Index: /azure_iot_hub_mbedtls/trunk/app_iothub_client/.cproject
===================================================================
--- /azure_iot_hub_mbedtls/trunk/app_iothub_client/.cproject	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/app_iothub_client/.cproject	(revision 398)
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1038496165">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1038496165" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings>
+					<externalSetting>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/app_iothub_client"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/app_iothub_client/Debug"/>
+						<entry flags="RESOLVED" kind="libraryFile" name="app_iothub_client" srcPrefixMapping="" srcRootPath=""/>
+					</externalSetting>
+				</externalSettings>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="com.renesas.cdt.managedbuild.core.toolchainInfo">
+				<option id="toolchain.id" value="RENESAS_GCC_RX"/>
+				<option id="toolchain.version" value="4.8.4.201803"/>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="GR-SAKURA Ethernet" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1038496165" name="Debug" parent="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib">
+					<folderInfo id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1038496165." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib.2005093931" name="GCC for Renesas RX" superClass="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib">
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.2035356596" name="Optimization Level" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel" useByScannerDiscovery="true"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections.400120804" name="Data sections (-fdata-sections)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.1109458604" name="Debug format" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.Default" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.992777735" name="Architecture" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture" useByScannerDiscovery="false" value="com.renesas.cdt.managedbuild.gcc.rx.architecture.v1" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability.895823890" name="Architecture Applicability" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability" useByScannerDiscovery="false" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName.980936999" name="DeviceName" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName" useByScannerDiscovery="false" value="R5F563NBDxFP" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand.26730345" name="DeviceCommand" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand" useByScannerDiscovery="false" value="R5F563NB" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.functionsections.862149100" name="Function sections (-ffunction-sections)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.64bitdouble.867017694" name="Make the double data type be 64 bits in size" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.64bitdouble" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize.484648443" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize" useByScannerDiscovery="false" value="100" valueType="string"/>
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.renesas.cdt.managedbuild.gcc.core.targetPlatform.1670958278" isAbstract="false" osList="all" superClass="com.renesas.cdt.managedbuild.gcc.core.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/app_iothub_client}/Debug" command="make" id="com.renesas.cdt.managedbuild.gcc.core.builder.1310913090" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="GCC for Renesas Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.managedbuild.gcc.core.builder"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen.34802174" name="Library Generator" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen">
+								<option id="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary.579614148" name="Select Library" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.selectLibrary.newLib" valueType="enumerated"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.rx.option.libraryType.372718212" name="Library type" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.libraryType" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType.preBuilt" valueType="enumerated"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.266362832" name="Compiler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.843400448" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" useByScannerDiscovery="false" valueType="includePath"/>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.1913348370" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler.434790663" name="Compiler CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.256343067" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" useByScannerDiscovery="false" valueType="includePath"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler.1578382899" name="Assembler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler">
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor.1492283696" name="Use preprocessor" superClass="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor" useByScannerDiscovery="false"/>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler.1558671019" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.linker.1454321544" name="Linker" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.linker">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.rx.option.linker.archives.archiveSearchDirectories.205349366" name="Standard archive search directories" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.linker.archives.archiveSearchDirectories" useByScannerDiscovery="false" valueType="stringList"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker.1168404647" name="Linker CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.rx.option.linker.cpp.archives.archiveSearchDirectories.763850240" name="Standard archive search directories" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.linker.cpp.archives.archiveSearchDirectories" useByScannerDiscovery="false" valueType="stringList"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy.1738401238" name="Objcopy" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver.475571967" name="Archiver" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="app_iothub_client.com.renesas.cdt.managedbuild.gcc.rx.ui.projectType.lib.1727033489" name="static ã©ã¤ãã©ãªã¼" projectType="com.renesas.cdt.managedbuild.gcc.rx.ui.projectType.lib"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<scannerConfigBuildInfo instanceId="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.release.lib.1258652772;com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.release.lib.1258652772.;com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.1230432769;com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.448336108">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1038496165;com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1038496165.;com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.266362832;com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.1913348370">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="DebugCitrus">
+			<resource resourceType="PROJECT" workspacePath="/app_iothub_client"/>
+		</configuration>
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/app_iothub_client"/>
+		</configuration>
+		<configuration configurationName="Release">
+			<resource resourceType="PROJECT" workspacePath="/app_iothub_client"/>
+		</configuration>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+</cproject>
Index: /azure_iot_hub_mbedtls/trunk/app_iothub_client/.project
===================================================================
--- /azure_iot_hub_mbedtls/trunk/app_iothub_client/.project	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/app_iothub_client/.project	(revision 398)
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>app_iothub_client</name>
+	<comment></comment>
+	<projects>
+		<project>asp3_dcre</project>
+		<project>azure_iothub</project>
+		<project>musl-1.1.18</project>
+		<project>ntshell</project>
+		<project>mbedtls-2.16.1</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: /azure_iot_hub_mbedtls/trunk/app_iothub_client/Debug/Makefile
===================================================================
--- /azure_iot_hub_mbedtls/trunk/app_iothub_client/Debug/Makefile	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/app_iothub_client/Debug/Makefile	(revision 398)
@@ -0,0 +1,653 @@
+#
+#  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-2016 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 735 2016-04-03 14:11:07Z ertl-hiro $
+# 
+
+#
+#  ターゲットの指定（Makefile.targetで上書きされるのを防ぐため）
+#
+all:
+
+#
+#  ターゲット略称の定義
+#
+TARGET = gr_sakura_gcc
+
+#
+#  プログラミング言語の定義
+#
+SRCLANG = c
+ifeq ($(SRCLANG),c)
+	LIBS = $(SRCDIR)/../musl-1.1.18/Debug/libmusl.a \
+		$(SRCDIR)/../mbedtls-2.16.1/Debug/libmbedtls.a \
+		$(SRCDIR)/../azure_iothub/Debug/libazure_iothub.a
+endif
+ifeq ($(SRCLANG),c++)
+	USE_CXX = true
+	CXXLIBS = -lstdc++ $(SRCDIR)/../musl-1.1.18/Debug/libmusl.a
+	CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ソースファイルのディレクトリの定義
+#
+SRCDIR = ../../asp3_dcre
+
+#
+#  オブジェクトファイル名の拡張子の設定
+#
+OBJEXT = elf
+
+#
+#  カーネルライブラリ（libkernel.a）のディレクトリ名
+#  （カーネルライブラリもmake対象にする時は，空に定義する）
+#
+KERNEL_LIB = ../../asp3_dcre/Debug
+
+#
+#  カーネルを関数単位でコンパイルするかどうかの定義
+#
+KERNEL_FUNCOBJS = 
+
+#
+#  TECSを外すかどうかの定義
+#
+OMIT_TECS = 
+
+#
+#  トレースログを取得するかどうかの定義
+#
+ENABLE_TRACE = 
+
+#
+#  開発ツール（コンパイラ等）のディレクトリの定義
+#
+DEVTOOLDIR = 
+
+#
+#  ユーティリティプログラムの名称
+#
+CFG = ruby -Eutf-8 $(SRCDIR)/cfg/cfg.rb
+TECSGEN = ruby -Eutf-8 $(SRCDIR)/tecsgen/tecsgen.rb
+
+#
+#  オブジェクトファイル名の定義
+#
+OBJNAME = app_iothub_client
+ifdef OBJEXT
+	OBJFILE = $(OBJNAME).$(OBJEXT)
+	CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+	OBJFILE = $(OBJNAME)
+	CFG1_OUT = cfg1_out
+endif
+
+#
+#  依存関係ファイルを置くディレクトリの定義
+#
+DEPDIR = deps
+
+#
+#  ターゲット依存部のディレクトリの定義
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ターゲット依存の定義のインクルード
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  TECS生成ファイルのディレクトリの定義
+#
+TECSGENDIR = ./gen
+ifndef OMIT_TECS
+	TECSGEN_TIMESTAMP = $(TECSGENDIR)/tecsgen.timestamp
+	INIT_TECS_COBJ = init_tecs.o
+endif
+
+#
+#  TECSが生成する定義のインクルード
+#
+ifndef OMIT_TECS
+	GEN_DIR = $(TECSGENDIR)
+	-include $(TECSGENDIR)/Makefile.tecsgen
+endif
+
+TINETDIR = tinet
+
+#
+#  mbedサービスの定義
+#
+
+include $(SRCDIR)/mbed/Makefile.mbed
+
+#
+#  共通コンパイルオプションの定義
+#
+COPTS := -g -std=gnu99 $(COPTS)
+ifndef OMIT_WARNING_ALL
+	COPTS := -Wall $(COPTS)
+endif
+ifndef OMIT_OPTIMIZATION
+	COPTS := -Og $(COPTS)
+endif
+ifdef OMIT_TECS
+	CDEFS := -DTOPPERS_OMIT_TECS $(CDEFS)
+endif
+CDEFS := $(CDEFS) -DDHCP4_CLI_CFG -DUSE_PING -DUSE_RESOLVER -DUSE_NETAPP_SUBR -DNOUSE_MPF_NET_BUF -DECHONET_USE_MALLOC -DHAVE_CONFIG_H -DWOLFSSL_USER_SETTINGS -DRamDisk=binary_______ntshell_src_rom_fs_bin_start
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR) \
+	-I$(SRCDIR)/../azure_iothub/c-utility/inc \
+	-I$(SRCDIR)/../azure_iothub/c-utility/pal/toppers \
+	-I$(SRCDIR)/../azure_iothub/iothub_client/inc \
+	-I$(SRCDIR)/../azure_iothub/iothub_client/inc/internal \
+	-I$(SRCDIR)/../azure_iothub/deps/parson \
+	-I$(SRCDIR)/../azure_iothub/certs \
+	-I$(SRCDIR)/../mbedtls-2.16.1/include \
+	$(INCLUDES)
+LDFLAGS := $(LDFLAGS) -L.
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+APPLDIRS := $(APPLDIRS) $(SRCDIR)/$(TINETDIR)/netapp
+APPL_COBJS := $(APPL_COBJS) ping.o ping6.o resolver.o dhcp4_cli.o netapp_subr.o ntp_cli.o net_misc.o
+APPLDIRS := $(APPLDIRS) ../../ntshell/fatfs ../../ntshell/ntshell ../../ntshell/ntshell/core ../../ntshell/ntshell/util ../../ntshell/src
+APPL_COBJS := $(APPL_COBJS) netcmd.o fdtable.o stdio_stub.o io_stub.o socket_stub.o ffarch.o diskio.o ff.o mmc_rspi.o ccsbcs.o ntshell.o text_editor.o text_history.o usrcmd.o vtrecv.o vtsend.o ntlibc.o ntstdio.o ntopt.o syscall.o
+
+#
+#  アプリケーションプログラムに関する定義
+#
+APPLNAME = app_iothub_client
+APPLDIRS := $(APPLDIRS) ../src ../../azure_iohub/c-utility/adapters
+APPL_CFG = main.cfg
+APPL_CDL = main.cdl
+
+APPL_DIRS := $(APPLDIRS) $(SRCDIR)/library
+APPL_ASMOBJS :=
+ifdef USE_CXX
+	APPL_CXXOBJS := main.o ntshell_main.o client.o
+	APPL_COBJS := $(APPL_COBJS)
+else
+	APPL_COBJS := $(APPL_COBJS) main.o ntshell_main.o client.o
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+APPL_BINOBJS := rom_fs.o
+APPL_CFLAGS := $(APPL_CFLAGS) -nostdinc
+ifdef APPLDIRS
+	INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIRS),-I$(dir))
+endif
+
+ifdef TINETDIR
+	#
+	#  ネットワークサービスの定義
+	#
+	NO_USE_TINET_LIBRARY = true
+
+	#  ネットワークインタフェースの選択、何れか一つ選択する。
+	NET_IF = ether
+
+	#  イーサネット・ディバイスドライバの選択
+	NET_DEV = if_rx62n
+
+	#  ネットワーク層の選択
+	#SUPPORT_INET6 = true
+	SUPPORT_INET4 = true
+
+	#  API に組込む機能の選択
+	#API_CFG_IP4MAPPED_ADDR = true
+
+	#  トランスポート層の選択
+	SUPPORT_TCP = true
+	SUPPORT_UDP = true
+
+	# IGMPを有効に設定
+	SUPPORT_IGMP = true
+
+	#
+	#  ネットワークサービスの Makefile のインクルード
+	#
+	include $(SRCDIR)/$(TINETDIR)/Makefile.tinet
+endif
+
+#
+#  システムサービスに関する定義
+#
+SYSSVC_DIRS := $(TECSGENDIR) $(SRCDIR)/tecs_kernel \
+				$(SYSSVC_DIRS) $(SRCDIR)/syssvc
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(INIT_TECS_COBJ) $(TECS_COBJS) $(SYSSVC_COBJS) \
+				 $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+INCLUDES := $(INCLUDES) -I$(TECSGENDIR) -I$(SRCDIR)/tecs_kernel -I../../musl-1.1.18/include
+
+#
+#  ターゲットファイル
+#
+.PHONY: all
+ifndef OMIT_TECS
+all: tecs | $(DEPDIR)
+#	@$(MAKE) check
+#	@$(MAKE) check $(OBJNAME).bin
+#	@$(MAKE) check $(OBJNAME).srec
+	@$(MAKE) check $(OBJNAME).mot
+else
+#all: check
+#all: check $(OBJNAME).bin
+#all: check $(OBJNAME).srec
+all: check $(OBJNAME).mot
+endif
+
+##### 以下は編集しないこと #####
+
+#
+#  コンフィギュレータに関する定義
+#
+ifndef TINETDIR
+  CFG_TRB := -T $(TARGETDIR)/target_kernel.trb
+  CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.def \
+			--symval-table $(SRCDIR)/kernel/kernel_sym.def $(CFG_TABS)
+else
+  CFG_TRB := -T $(TINET_ROOT)/tinet.trb:tcpip -T $(TARGETDIR)/target_kernel.trb:kernel
+  CFG_TABS := --api-table $(TINET_ROOT)/tcpip_api.def:tcpip \
+			--api-table $(SRCDIR)/kernel/kernel_api.def:kernel \
+			--symval-table $(TINET_ROOT)/tcpip_sym.def \
+			--symval-table $(SRCDIR)/kernel/kernel_sym.def $(CFG_TABS)
+endif
+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)
+CFG_CFLAGS := -DTOPPERS_CB_TYPE_ONLY $(CFG_CFLAGS)
+
+#
+#  カーネルに関する定義
+#
+#  KERNEL_ASMOBJS: カーネルライブラリに含める，ソースがアセンブリ言語の
+#				   オブジェクトファイル．
+#  KERNEL_COBJS: カーネルのライブラリに含める，ソースがC言語で，ソース
+#				 ファイルと1対1に対応するオブジェクトファイル．
+#  KERNEL_LCSRCS: カーネルのライブラリに含めるC言語のソースファイルで，
+#				  1つのソースファイルから複数のオブジェクトファイルを生
+#				  成するもの．
+#  KERNEL_LCOBJS: 上のソースファイルから生成されるオブジェクトファイル．
+#
+KERNEL_DIRS := $(KERNEL_DIRS) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+
+#
+#  カーネルのファイル構成の定義
+#
+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
+ifdef OMIT_OFFSET_H
+	OFFSET_H =
+else
+	OFFSET_H = offset.h
+endif
+ifndef TARGET_OFFSET_TRB
+	TARGET_OFFSET_TRB := $(TARGETDIR)/target_offset.trb
+endif
+ifndef TARGET_KERNEL_TRB
+	TARGET_KERNEL_TRB := $(TARGETDIR)/target_kernel.trb
+endif
+ifndef TARGET_CHECK_TRB
+	TARGET_CHECK_TRB := $(TARGETDIR)/target_check.trb
+endif
+ifndef TARGET_KERNEL_CFG
+	TARGET_KERNEL_CFG := $(TARGETDIR)/target_kernel.cfg
+endif
+ifndef TARGET_TCPIP_TRB
+	TARGET_TCPIP_TRB := $(SRCDIR)/$(TINETDIR)/tinet.trb
+endif
+
+#
+#  ソースファイルのあるディレクトリに関する定義
+#
+vpath %.c $(KERNEL_DIRS) $(SYSSVC_DIRS) $(APPL_DIRS)
+vpath %.S $(KERNEL_DIRS) $(SYSSVC_DIRS) $(APPL_DIRS)
+vpath %.cfg $(APPL_DIRS)
+vpath %.cdl $(APPL_DIRS)
+vpath %.bin $(APPL_DIRS)
+
+#
+#  コンパイルのための変数の定義
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS) $(HIDDEN_OBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS) $(APPL_BINOBJS)
+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
+
+#
+#  tecsgenからCプリプロセッサを呼び出す際のオプションの定義
+#
+TECS_CPP = $(CC) $(CDEFS) $(INCLUDES) $(SYSSVC_CFLAGS) -D TECSGEN -E
+
+#
+#  tecsgenの呼出し
+#
+.PHONY: tecs
+tecs $(TECSGEN_SRCS) $(TECS_HEADERS): $(TECSGEN_TIMESTAMP) ;
+$(TECSGEN_TIMESTAMP): $(APPL_CDL) $(TECS_IMPORTS)
+	$(TECSGEN) $< -R $(INCLUDES) --cpp "$(subst ", \", $(TECS_CPP))" -g $(TECSGENDIR)
+
+#
+#  カーネルのコンフィギュレーションファイルの生成
+#
+cfg1_out.c cfg1_out.db: cfg1_out.timestamp ;
+cfg1_out.timestamp: $(APPL_CFG) $(TECSGEN_TIMESTAMP)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) \
+						-M $(DEPDIR)/cfg1_out_c.d $(TARGET_KERNEL_CFG) $<
+
+$(CFG1_OUT): $(START_OBJS) cfg1_out.o $(CFG_DMY) $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(LDFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(CFG_DMY) $(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) cfg2_out.db: kernel_cfg.timestamp ;
+kernel_cfg.timestamp: cfg1_out.db cfg1_out.syms cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) $(CFG_TRB)
+
+#
+#  オフセットファイル（offset.h）の生成規則
+#
+$(OFFSET_H): offset.timestamp ;
+offset.timestamp: cfg1_out.db cfg1_out.syms cfg1_out.srec
+	$(CFG) --pass 2 -O --kernel asp $(INCLUDES) -T $(TARGET_OFFSET_TRB) \
+				--rom-symbol cfg1_out.syms --rom-image cfg1_out.srec
+
+#
+#  カーネルライブラリファイルの生成
+#
+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
+
+#
+#  特別な依存関係の定義
+#
+tBannerMain.o: $(filter-out tBannerMain.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  全体のリンク
+#
+$(OBJFILE): $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) $(OBJ_LDFLAGS) -o $(OBJFILE) -Wl,-Map=$(OBJNAME).map,--cref \
+			$(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
+
+$(OBJNAME).mot: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).mot
+
+#
+#  エラーチェック処理
+#
+.PHONY: check
+check: check.timestamp ;
+check.timestamp: cfg2_out.db $(OBJNAME).syms $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp -O $(INCLUDES) -T $(TARGET_CHECK_TRB) \
+				--rom-symbol $(OBJNAME).syms --rom-image $(OBJNAME).srec
+	@echo "configuration check passed"
+
+#
+#  コンパイル結果の消去
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(DEPDIR)/*.d $(CLEAN_FILES) check.timestamp
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS) cfg2_out.db
+	rm -f offset.timestamp $(OFFSET_H)
+	rm -f cfg1_out.syms cfg1_out.srec $(CFG1_OUT)
+	rm -f cfg1_out.timestamp cfg1_out.c cfg1_out.db
+	rm -rf $(TECSGENDIR)
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+
+.PHONY: cleankernel
+cleankernel:
+	rm -f $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f $(KERNEL_LIB_OBJS:%.o=$(DEPDIR)/%.d)
+
+.PHONY: realclean
+realclean: clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  コンフィギュレータが生成したファイルのコンパイルルールの定義
+#
+#  コンフィギュレータが生成したファイルは，共通のコンパイルオプション
+#  のみを付けてコンパイルする．
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c -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): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c -MD -MP -MF $(DEPDIR)/$*.d \
+									$(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_BINOBJS): %.o: %.bin
+	$(OBJCOPY) -B rx -I binary -O elf32-rx-le --rename-section .data=.rodata $< $*.o
+
+#
+#  デフォルトコンパイルルールを上書き
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(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 -MD -MP -MF $(DEPDIR)/$*.d $(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 -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $<
Index: /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/client.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/client.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/client.c	(revision 398)
@@ -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 <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"
+
+#ifdef _MSC_VER
+extern int sprintf_s(char* dst, size_t dstSizeInBytes, const char* format, ...);
+#endif // _MSC_VER
+
+#if 1//def MBED_BUILD_TIMESTAMP
+#define SET_TRUSTED_CERT_IN_SAMPLES
+#endif // MBED_BUILD_TIMESTAMP
+
+#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>"    */
+static const char* connectionString = "[device connection string]";
+
+
+static int callbackCounter;
+static bool g_continueRunning;
+static char msgText[1024];
+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;
+}
+
+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];
+	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
+	{
+		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 0
+			HTTP_PROXY_OPTIONS proxy_options;
+			proxy_options.host_address = "proxy.example.com";
+			proxy_options.port = 8080;
+			proxy_options.username = NULL;
+			proxy_options.password = NULL;
+			if (IoTHubClient_LL_SetOption(iotHubClientHandle, OPTION_HTTP_PROXY, &proxy_options) != IOTHUB_CLIENT_OK)
+			{
+				printf("failure to set option \"HTTP Proxy\"\r\n");
+			}
+
+			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
+			/* 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 = 0;
+				double temperature = 0;
+				double humidity = 0;
+				do
+				{
+					if ((iterator < MESSAGE_COUNT) && (iterator <= callbackCounter))
+					{
+						temperature = minTemperature + (rand() % 10);
+						humidity = minHumidity + (rand() % 20);
+						sprintf_s(msgText, sizeof(msgText), "{\"windSpeed\":%.2f,\"temperature\":%.2f,\"humidity\":%.2f}", avgWindSpeed + (rand() % 4 + 2), temperature, humidity);
+						if ((messages[iterator].messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)msgText, strlen(msgText))) == NULL)
+						{
+							(void)printf("ERROR: iotHubMessageHandle is NULL!\r\n");
+						}
+						else
+						{
+							MAP_HANDLE propMap;
+
+							messages[iterator].messageTrackingId = iterator;
+
+							propMap = IoTHubMessage_Properties(messages[iterator].messageHandle);
+							(void)sprintf_s(propText, sizeof(propText), temperature > 28 ? "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[iterator].messageHandle, "application/json");
+								(void)IoTHubMessage_SetContentEncodingSystemProperty(messages[iterator].messageHandle, "utf-8");
+							}
+
+							if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages[iterator].messageHandle, SendConfirmationCallback, &messages[iterator]) != 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", iterator);
+							}
+						}
+						iterator++;
+					}
+
+					IoTHubClient_LL_DoWork(iotHubClientHandle);
+					ThreadAPI_Sleep(1);
+
+					if (callbackCounter >= MESSAGE_COUNT)
+					{
+						printf("exit\n");
+						break;
+					}
+				} while (g_continueRunning);
+
+				(void)printf("iothub_client_sample_http 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);
+				}
+			}
+			IoTHubClient_LL_Destroy(iotHubClientHandle);
+		}
+		platform_deinit();
+	}
+}
+
+int iothub_client_main(int argc, char **argv)
+{
+	iothub_client_run(2);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/client.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/client.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/client.h	(revision 398)
@@ -0,0 +1,17 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#ifndef SENDEVENTASYNC_H
+#define SENDEVENTASYNC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    void iothub_client_sample_http_run(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SENDEVENTASYNC_H */
Index: /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.c	(revision 398)
@@ -0,0 +1,320 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2014-2019 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  サンプルプログラム(1)の本体
+ */
+
+#include "shellif.h"
+#include <kernel.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <setjmp.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "target_syssvc.h"
+#include "kernel_cfg.h"
+#include "main.h"
+#include <tinet_config.h>
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+#include <tinet_nic_defs.h>
+#include <tinet_cfg.h>
+#include <netinet/in_var.h>
+#include <net/ethernet.h>
+#include <net/if6_var.h>
+#include <net/net.h>
+#include <net/if_var.h>
+#include <netinet/udp_var.h>
+#include "netapp/dhcp4_cli.h"
+#include "ffarch.h"
+#include "ff.h"
+#include <stdio.h>
+#include "usrcmd.h"
+#include "fdtable.h"
+#include "gpio_api.h"
+#include "ntshell_main.h"
+#include "ntp_cli.h"
+#include "netcmd.h"
+
+ID ws_api_mailboxid = MAIN_DATAQUEUE;
+#ifndef NOUSE_MPF_NET_BUF
+ID ws_mempoolid = MPF_NET_BUF_256;
+#endif
+
+bool_t dhcp_enable = true;
+
+uint8_t mac_addr[6] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0x01};
+PRI main_task_priority = MAIN_PRIORITY + 1;
+
+static void netif_link_callback(T_IFNET *ether);
+extern int execute_command(int wait);
+
+enum main_state_t {
+	main_state_start,
+	main_state_idle,
+};
+
+struct main_t {
+	int timer;
+	enum main_state_t state;
+	SYSTIM prev, now;
+};
+struct main_t main_obj;
+
+static void main_initialize();
+static int main_get_timer();
+static void main_progress(int interval);
+static void main_timeout();
+
+extern int ntshell_exit;
+
+int uart_read(char *buf, int cnt, void *extobj)
+{
+	struct main_t *obj = (struct main_t *)extobj;
+	int result;
+	ER ret;
+	int timer;
+
+	obj->prev = obj->now;
+
+	/* タイマー取得 */
+	timer = main_get_timer();
+
+	/* 待ち */
+	ret = serial_trea_dat(SIO_PORTID, buf, cnt, timer);
+	if ((ret < 0) && (ret != E_OK) && (ret != E_TMOUT)) {
+		syslog(LOG_NOTICE, "tslp_tsk ret: %s %d", itron_strerror(ret), timer);
+		ntshell_exit = 1;
+		return -1;
+	}
+	result = (int)ret;
+
+	ret = get_tim(&obj->now);
+	if (ret != E_OK) {
+		syslog(LOG_NOTICE, "get_tim ret: %s", itron_strerror(ret));
+		ntshell_exit = 1;
+		return -1;
+	}
+
+			/* 時間経過 */
+	int elapse = obj->now - obj->prev;
+	main_progress(elapse);
+
+	/* タイムアウト処理 */
+	main_timeout();
+
+	return result;
+}
+
+int uart_write(const char *buf, int cnt, void *extobj)
+{
+	return serial_wri_dat(SIO_PORTID, buf, cnt);
+}
+
+ntshell_t ntshell;
+
+/*
+ * メインタスク
+ */
+void main_task(intptr_t exinf)
+{
+	main_initialize();
+
+	ntshell_init(&ntshell, uart_read, uart_write, cmd_execute, &main_obj);
+	ntshell_set_prompt(&ntshell, "NTShell>");
+	ntshell_execute(&ntshell);
+}
+
+int wolfSSL_Debugging_ON(void);
+
+/*
+ * 初期化
+ */
+static void main_initialize()
+{
+	ER ret;
+
+	//wolfSSL_Debugging_ON();
+
+	ntshell_task_init(SIO_PORTID);
+
+	main_obj.timer = TMO_FEVR;
+	main_obj.state = main_state_start;
+
+	gpio_t led_blue, led_green, led_red, sw;
+	gpio_init_out(&led_blue, LED_BLUE);
+	gpio_init_out(&led_green, LED_GREEN);
+	gpio_init_out(&led_red, LED_RED);
+	gpio_init_in(&sw, USER_BUTTON0);
+
+	bool_t exec = gpio_read(&sw) == 1;
+
+	gpio_write(&led_blue, 1);
+	gpio_write(&led_green, exec ? 1 : 0);
+	gpio_write(&led_red, 0);
+
+	if (!dhcp_enable) {
+		dhcp4c_rel_info();
+
+		in4_add_ifaddr(IPV4_ADDR_STAIC_LOCAL, IPV4_ADDR_STAIC_LOCAL_MASK);
+		uint8_t data[32], c;
+		int i, j;
+
+		for (i = 0, j = 0; i < sizeof(mac_addr); i++) {
+			c = mac_addr[i] >> 4;
+			data[j++] = (c < 10) ? ('0' + c) : ('A' - 10 + c);
+			c = mac_addr[i] & 0xF;
+			data[j++] = (c < 10) ? ('0' + c) : ('A' - 10 + c);
+			data[j++] = ':';
+		}
+		data[--j] = '\0';
+
+		syslog(LOG_NOTICE, "mac_addr %s %s", data, dhcp_enable ? "dhcp" : "static");
+	}
+
+	ether_set_link_callback(netif_link_callback);
+
+	/* 初期化 */
+	ffarch_init();
+
+	gpio_write(&led_green, 0);
+
+	ret = get_tim(&main_obj.now);
+	if (ret != E_OK) {
+		syslog(LOG_ERROR, "get_tim");
+		ext_tsk();
+		return;
+	}
+}
+
+/*
+ * タイマー取得
+ */
+static int main_get_timer()
+{
+	int timer = main_obj.timer;
+
+	return timer;
+}
+
+/*
+ * 時間経過
+ */
+static void main_progress(int interval)
+{
+	if (main_obj.timer != TMO_FEVR) {
+		main_obj.timer -= interval;
+		if (main_obj.timer < 0) {
+			main_obj.timer = 0;
+		}
+	}
+}
+
+/*
+ * タイムアウト処理
+ */
+static void main_timeout()
+{
+	//if (main_obj.timer == 0) {
+	//}
+}
+
+/* MACアドレスの設定時に呼ばれる */
+void mbed_mac_address(char *mac)
+{
+	memcpy(mac, mac_addr, 6);
+}
+
+static void netif_link_callback(T_IFNET *ether)
+{
+	uint8_t link_up = (ether->flags & IF_FLAG_LINK_UP) != 0;
+	uint8_t up = (ether->flags & IF_FLAG_UP) != 0;
+
+	if (dhcp_enable) {
+		if (!link_up)
+			dhcp4c_rel_info();
+		else if (!up)
+			dhcp4c_renew_info();
+	}
+	else {
+		up = link_up;
+	}
+
+	if (link_up && up)
+		ntp_cli_execute();
+
+	ntshell_change_netif_link(link_up, up);
+}
+
+int custom_rand_generate_seed(uint8_t* output, int32_t sz)
+{
+	SYSTIM now;
+	int32_t i;
+
+	get_tim(&now);
+	srand(now);
+
+	for (i = 0; i < sz; i++)
+		output[i] = rand();
+
+	return 0;
+}
+
+extern int iothub_client_main(int argc, char **argv);
+
+static const cmd_table_t cmdlist[] = {
+	{"cd", "change directory", usrcmd_cd },
+	{"ls", "list files", usrcmd_ls },
+	{"cp", "copy file", usrcmd_cp },
+	{"rm", "remove file", usrcmd_rm },
+	{"mv", "move file", usrcmd_mv },
+	{"mkdir", "Make directory", usrcmd_mkdir},
+	{"hexdump", "Hex dump", usrcmd_hexdump},
+	{"date", "print date and time", usrcmd_date},
+	{"ping", "ping", usrcmd_ping},
+	{"dhcpc", "DHCP Client rel/renew/info", usrcmd_dhcp4c},
+	{"dnsc", "DNS client", usrcmd_dnsc },
+	{"ntpc", "NTP client", usrcmd_ntpc },
+	{"iothub", "Asure IoT Hub Client", iothub_client_main},
+	{"info", "This is a description text string for info command.", usrcmd_info},
+	{"exit", "Exit Natural Tiny Shell", usrcmd_exit},
+};
+cmd_table_info_t cmd_table_info = { cmdlist, sizeof(cmdlist) / sizeof(cmdlist[0]) };
Index: /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.cdl	(revision 398)
@@ -0,0 +1,122 @@
+/*
+ *		サンプルプログラム(1)のコンポーネント記述ファイル
+ *
+ *  $Id$
+ */
+/*
+ *  カーネルオブジェクトの定義
+ */
+import(<kernel.cdl>);
+
+/*
+ *  ターゲット非依存のセルタイプの定義
+ */
+import("syssvc/tSerialPort.cdl");
+import("syssvc/tSerialAdapter.cdl");
+import("syssvc/tSysLog.cdl");
+import("syssvc/tSysLogAdapter.cdl");
+import("syssvc/tLogTask.cdl");
+import("syssvc/tBanner.cdl");
+
+/*
+ *  ターゲット依存部の取り込み
+ */
+import("ntshell.cdl");
+
+/*
+ *  「セルの組上げ記述」とは，"cell"で始まる行から，それに対応する"};"
+ *  の行までのことを言う．
+ */
+
+/*
+ *  システムログ機能の組上げ記述
+ *
+ *  システムログ機能を外す場合には，以下のセルの組上げ記述を削除し，コ
+ *  ンパイルオプションに-DTOPPERS_OMIT_SYSLOGを追加すればよい．ただし，
+ *  システムログタスクはシステムログ機能を使用するため，それも外すこと
+ *  が必要である．また，システムログ機能のアダプタも外さなければならな
+ *  い．tecsgenが警告メッセージを出すが，無視してよい．
+ */
+cell tSysLog SysLog {
+	logBufferSize = 32;					/* ログバッファのサイズ */
+	initLogMask = C_EXP("LOG_UPTO(LOG_NOTICE)");
+										/* ログバッファに記録すべき重要度 */
+	initLowMask = C_EXP("LOG_UPTO(LOG_EMERG)");
+									   	/* 低レベル出力すべき重要度 */
+	/* 低レベル出力との結合 */
+	cPutLog = PutLogTarget.ePutLog;
+};
+
+/*
+ *  C言語で記述されたアプリケーションから，TECSベースのシステムログ機能
+ *  を呼び出すためのアダプタの組上げ記述
+ *
+ *  システムログ機能のサービスコール（syslog関数とsyslog_0関数～syslog_5
+ *  関数以外のもの）ルをC言語で記述されたアプリケーションから呼び出さな
+ *  い場合には，以下のセルの組上げ記述を削除すればよい．
+ */
+cell tSysLogAdapter SysLogAdapter {
+	cSysLog = SysLog.eSysLog;
+};
+
+/*
+ *  シリアルインタフェースドライバの組上げ記述
+ *
+ *  シリアルインタフェースドライバを外す場合には，以下のセルの組上げ記
+ *  述を削除すればよい．ただし，システムログタスクはシリアルインタフェー
+ *  スドライバを使用するため，それも外すことが必要である．また，シリア
+ *  ルインタフェースドライバのアダプタも外さなければならない．
+ */
+cell tSerialPort SerialPort1 {
+	receiveBufferSize = 256;			/* 受信バッファのサイズ */
+	sendBufferSize    = 256;			/* 送信バッファのサイズ */
+
+	/* ターゲット依存部との結合 */
+	cSIOPort = SIOPortTarget1.eSIOPort;
+	eiSIOCBR <= SIOPortTarget1.ciSIOCBR;	/* コールバック */
+};
+
+/*
+ *  C言語で記述されたアプリケーションから，TECSベースのシリアルインタ
+ *  フェースドライバを呼び出すためのアダプタの組上げ記述
+ *
+ *  シリアルインタフェースドライバのサービスコールをC言語で記述されたア
+ *  プリケーションから呼び出さない場合には，以下のセルの組上げ記述を削
+ *  除すればよい．
+ */
+cell tSerialAdapter SerialAdapter {
+	cSerialPort[0] = SerialPort1.eSerialPort;
+};
+
+/*
+ *  システムログタスクの組上げ記述
+ *
+ *  システムログタスクを外す場合には，以下のセルの組上げ記述を削除すれ
+ *  ばよい．
+ */
+cell tLogTask LogTask {
+	priority  = 3;					/* システムログタスクの優先度 */
+	stackSize = LogTaskStackSize;	/* システムログタスクのスタックサイズ */
+
+	/* シリアルインタフェースドライバとの結合 */
+	cSerialPort        = SerialPort1.eSerialPort;
+	cnSerialPortManage = SerialPort1.enSerialPortManage;
+
+	/* システムログ機能との結合 */
+	cSysLog = SysLog.eSysLog;
+
+	/* 低レベル出力との結合 */
+	cPutLog = PutLogTarget.ePutLog;
+};
+
+/*
+ *  カーネル起動メッセージ出力の組上げ記述
+ *
+ *  カーネル起動メッセージの出力を外す場合には，以下のセルの組上げ記述
+ *  を削除すればよい．
+ */
+cell tBanner Banner {
+	/* 属性の設定 */
+	targetName      = BannerTargetName;
+	copyrightNotice = BannerCopyrightNotice;
+};
Index: /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.cfg	(revision 398)
@@ -0,0 +1,83 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  サンプルプログラム(1)のシステムコンフィギュレーションファイル
+ */
+#include "main.h"
+#include <tinet_config.h>
+#include <net/net_endian.h>
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+#include <tinet_nic_defs.h>
+#include <netinet/in_var.h>
+#include <net/ethernet.h>
+#include <net/if6_var.h>
+
+INCLUDE("tecsgen.cfg");
+
+INCLUDE("tinet/tinet_asp.cfg");
+INCLUDE("tinet_main.cfg");
+
+/* DHCP クライアント */
+#include "netapp/dhcp4_cli.h"
+//INCLUDE("netapp/dhcp4_cli_asp.cfg");
+INCLUDE("netapp/tinet_dhcp4_cli.cfg");
+
+/* DNSクライアント */
+#include "netapp/resolver.h"
+INCLUDE("netapp/resolver_asp.cfg");
+INCLUDE("netapp/tinet_resolver.cfg");
+
+/* NTPクライアント */
+#include "ntp_cli.h"
+//INCLUDE("ntp_cli.cfg");
+INCLUDE("tinet_ntp_cli.cfg");
+
+#include "net_misc.h"
+INCLUDE("net_misc.cfg");
+
+/* FatFs */
+INCLUDE("ffarch.cfg");
+
+/* mbed */
+INCLUDE("mbed_api.cfg");
+
+INCLUDE("ntshell_main.cfg");
+
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, MAIN_STACK_SIZE, NULL });
+CRE_DTQ(MAIN_DATAQUEUE, { TA_TFIFO, NUM_MAIN_DATAQUEUE, NULL });
Index: /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/main.h	(revision 398)
@@ -0,0 +1,74 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2014-2017 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+/*
+ *		サンプルプログラム(1)のヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include <kernel.h>
+
+#ifndef TOPPERS_CFG1_OUT
+#include "tinet_cfg.h"
+#endif
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY	5		/* メインタスクの優先度 */
+
+#define MAIN_STACK_SIZE		2048	/* メインタスクのスタック領域のサイズ */
+
+#define NUM_MAIN_DATAQUEUE	1	/* メインタスクで待ち受けているデータキューのサイズ */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+/* メインタスク */
+extern void main_task(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif	/* of #ifndef _MAIN_H_ */
Index: /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/tinet_app_config.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/tinet_app_config.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/app_iothub_client/src/tinet_app_config.h	(revision 398)
@@ -0,0 +1,659 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TINET_APP_CONFIG_H_
+#define _TINET_APP_CONFIG_H_
+
+/*
+ *  インターネットプロトコルファミリーのサポート
+ *
+ *    Makefile で指定しても良い
+ */
+
+/*#define SUPPORT_INET4		TCP/IP,IPv4		*/
+/*#define SUPPORT_INET6		TCP/IP,IPv6		*/
+/*#define SUPPORT_TCP		TCP			*/
+/*#define SUPPORT_UDP		UDP			*/
+
+/*データリンク層のネットワークインタフェースを選択する	*/
+/*いずれか一つだけ選択できる。				*/
+
+/*#define SUPPORT_PPP		PointtoPointProtocol	*/
+/*#define SUPPORT_LOOP		LocalLoopBack		*/
+/*#define SUPPORT_ETHER		Ethernet		*/
+
+/*#define SUPPORT_MIB		MIB(SNMP)		*/
+
+/*
+ *  TCP/IP に関する定義
+ */
+
+/* TCP に関する定義 */
+
+/*
+ *  TCP 通信端点の送受信ウィンドバッファの省コピー機能
+ *    注意: Makefile で指定している。
+ */
+/*#define TCP_CFG_RWBUF_CSAVE_ONLY*/
+			/* TCP 通信端点の受信ウィンドバッファの省コピー機能のみ有効にする。	*/
+/*#define TCP_CFG_RWBUF_CSAVE*/
+			/* TCP 通信端点の受信ウィンドバッファの省コピー機能を有効にする。	*/
+/*#define TCP_CFG_SWBUF_CSAVE_ONLY*/
+			/* TCP 通信端点の送信ウィンドバッファの省コピー機能のみ有効にする。	*/
+/*#define TCP_CFG_SWBUF_CSAVE*/
+			/* TCP 通信端点の送信ウィンドバッファの省コピー機能を有効にする。	*/
+
+/*
+ *  TCP 通信端点の受信ウィンドバッファの省コピー機能の、
+ *  受信ウィンドバッファキューの最大エントリ数。
+ *  ただし、正常に受信したセグメントも破棄するため、再送回数が増加する。
+ *  また、指定しないと制限しない。
+ */
+/*#define TCP_CFG_RWBUF_CSAVE_MAX_QUEUES	2*/
+
+/*
+ *  TCP 通信端点の送信ウィンドバッファの省コピー機能で、
+ *  送信ウィンドバッファに使用するネットワークバッファのサイズ。
+ */
+#define USE_TCP_MSS_SEG
+
+#ifdef USE_TCP_MSS_SEG
+
+#ifdef SUPPORT_INET6
+
+#define TCP_CFG_SWBUF_CSAVE_MAX_SIZE	(IF_HDR_SIZE + IPV6_MMTU)	/* 最大サイズ */
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+#define TCP_CFG_SWBUF_CSAVE_MAX_SIZE	(IF_HDR_SIZE + IP4_MSS)		/* 最大サイズ */
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#else	/* of #ifdef USE_TCP_MSS_SEG */
+
+#define TCP_CFG_SWBUF_CSAVE_MAX_SIZE	IF_PDU_SIZE			/* 最大サイズ */
+
+#endif	/* of #ifdef USE_TCP_MSS_SEG */
+
+#define TCP_CFG_SWBUF_CSAVE_MIN_SIZE	0				/* 最小サイズ */
+
+/*
+ *  TCP のノンブロッキングコール機能
+ */
+
+#ifdef UNDEF_TCP_CFG_NON_BLOCKING
+#undef TCP_CFG_NON_BLOCKING
+#endif
+
+/*
+ *  MAX_TCP_SND_SEG: 送信セグメントサイズの最大値
+ *
+ *    相手から MSS オプションでセグメントサイズを指定されても、
+ *    この値で、セグメントサイズを制限できる。
+ */
+
+#ifdef USE_TCP_MSS_SEG
+
+#ifdef MAX_TCP_SND_SEG
+#undef MAX_TCP_SND_SEG
+#endif
+
+#ifdef SUPPORT_INET6
+
+#define MAX_TCP_SND_SEG			TCP6_MSS
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+#define MAX_TCP_SND_SEG			TCP_MSS
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#endif	/* of #ifdef USE_TCP_MSS_SEG */
+
+/*
+ *  DEF_TCP_RCV_SEG: 受信セグメントサイズの規定値
+ */
+
+#ifdef USE_TCP_MSS_SEG
+
+#ifdef DEF_TCP_RCV_SEG
+#undef DEF_TCP_RCV_SEG
+#endif
+
+#ifdef SUPPORT_INET6
+
+#define DEF_TCP_RCV_SEG			TCP6_MSS
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+#define DEF_TCP_RCV_SEG			TCP_MSS
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#endif	/* of #ifdef USE_TCP_MSS_SEG */
+
+/*
+ *  タスクからの Time Wait 状態の TCP 通信端点分離機能
+ *
+ *  Time Wait 状態の TCP 通信端点のエントリ数を指定する。
+ *  指定しないか、0 を指定すると、
+ *  タスクから Time Wait 状態の TCP 通信端点を分離する機能は組込まない。
+ */
+#if !defined(SUPPORT_TCP)
+#define NUM_TCP_TW_CEP_ENTRY		0
+#elif defined(USE_TCP_MSS_SEG)
+#define NUM_TCP_TW_CEP_ENTRY		3
+#else
+#define NUM_TCP_TW_CEP_ENTRY		6
+#endif
+
+/*
+ *  TCP ヘッダのトレース出力機能
+ */
+//#define TCP_CFG_TRACE
+
+/*
+ *  トレース出力対象のリモートホストの IPv4 アドレス
+ *  IPV4_ADDRANY を指定すると、全てのホストを対象とする。
+ */
+#define TCP_CFG_TRACE_IPV4_RADDR	IPV4_ADDRANY
+
+/*
+ *  トレース出力対象のリモートホストのポート番号
+ *  TCP_PORTANY を指定すると、全てのポート番号を対象にする。
+ */
+#define TCP_CFG_TRACE_RPORTNO		TCP_PORTANY
+//#define TCP_CFG_TRACE_RPORTNO		UINT_C(7)
+
+/*
+ *  トレース出力対象のローカルホストのポート番号
+ *  TCP_PORTANY を指定すると、全てのポート番号を対象にする。
+ */
+#define TCP_CFG_TRACE_LPORTNO		TCP_PORTANY
+//#define TCP_CFG_TRACE_LPORTNO		UINT_C(7)
+
+/*
+ *  ITRON TCP/IP API、TCP の拡張機能
+ */
+#define TCP_CFG_EXTENTIONS
+
+/*
+ *  TCP_CFG_URG_OFFSET: 緊急データの最後のバイトのオフセット
+ *
+ *    -1: BSD の実装、緊急ポインタは、緊急データの最後のバイトの次のバイトを差す。
+ *     0: RFC1122 の規定、緊急ポインタは、緊急データの最後のバイトを差す。
+ */
+
+//#define TCP_CFG_URG_OFFSET	-1
+//#define TCP_CFG_URG_OFFSET	0
+
+/* UDP に関する定義 */
+
+/*
+ *  UDP のノンブロッキングコール機能
+ */
+
+#ifdef UNDEF_UDP_CFG_NON_BLOCKING
+#undef UDP_CFG_NON_BLOCKING
+#endif
+
+/*
+ *  ITRON TCP/IP API、UDP の拡張機能
+ */
+#define UDP_CFG_EXTENTIONS
+
+/* IPv6 に関する定義 */
+
+#ifdef SUPPORT_PPP
+
+#define NUM_IN6_STATIC_ROUTE_ENTRY	0
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	0
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_LOOP
+
+#define NUM_IN6_STATIC_ROUTE_ENTRY	0
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	0
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+#ifdef SUPPORT_ETHER
+
+#define NUM_IN6_STATIC_ROUTE_ENTRY	0
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	1
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+/* IPv4 に関する定義 */
+
+#ifdef SUPPORT_PPP
+
+#if 1
+#define IPV4_ADDR_LOCAL			MAKE_IPV4_ADDR(192,168,1,21)
+#else
+#define IPV4_ADDR_LOCAL			MAKE_IPV4_ADDR(0,0,0,0)		/* 相手に割り当ててもらう場合	*/
+#endif
+
+#if 1
+#define IPV4_ADDR_REMOTE		MAKE_IPV4_ADDR(192,168,1,31)
+#else
+#define IPV4_ADDR_REMOTE		MAKE_IPV4_ADDR(0,0,0,0)		/* 相手に割り当ててもらう場合	*/
+#endif
+
+#define NUM_IN4_STATIC_ROUTE_ENTRY	1
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	0
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_ETHER
+
+#define IPV4_ADDR_STAIC_LOCAL			MAKE_IPV4_ADDR(192,168,137,201)
+#define IPV4_ADDR_STAIC_LOCAL_MASK		MAKE_IPV4_ADDR(255,255,255,0)
+#define IPV4_ADDR_STAIC_DEFAULT_GW		MAKE_IPV4_ADDR(192,168,137,1)
+
+#ifdef DHCP4_CLI_CFG
+
+#define IPV4_ADDR_LOCAL			MAKE_IPV4_ADDR(0,0,0,0)
+#define IPV4_ADDR_LOCAL_MASK	MAKE_IPV4_ADDR(0,0,0,0)
+#define IPV4_ADDR_DEFAULT_GW	MAKE_IPV4_ADDR(0,0,0,0)
+
+#else	/* of #ifdef DHCP4_CLI_CFG */
+
+#define IPV4_ADDR_LOCAL			IPV4_ADDR_STAIC_LOCAL
+#define IPV4_ADDR_LOCAL_MASK	IPV4_ADDR_STAIC_LOCAL_MASK
+#define IPV4_ADDR_DEFAULT_GW	IPV4_ADDR_STAIC_DEFAULT_GW
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
+
+#define NUM_IN4_STATIC_ROUTE_ENTRY	3
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	1
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#ifdef SUPPORT_LOOP
+
+#define NUM_IN4_STATIC_ROUTE_ENTRY	1
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	0
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+/*
+ *  データリンク層 (ネットワークインタフェース) に関する定義
+ */
+
+/*
+ *  イーサネットに関する定義
+ */
+
+/*
+ *  PPP に関する定義
+ */
+
+#define HDLC_PORTID			1	/* HDLC(PPP)に用いるシリアルポート番号	*/
+
+/*#define PPP_IDLE_TIMEOUT		(180*NET_TIMER_HZ)*/
+					/* 切断までのアイドル時間、		*/
+					/* 切断しない場合はコメントアウトする。	*/
+
+/*#define PPP_CFG_MODEM			 モデム接続の場合はコメントを外す。	*/
+
+#define MODEM_CFG_INIT			"ATE1&D0&S0\\V0\\Q1S0=1"
+					/* モデム初期化文字列			*/
+					/* NTT DoComo モバイルアダプタ 96F 用	*/
+					/*   E1: エコーバックあり			*/
+					/*  &D0: ER信号無視			*/
+					/*  &S0: DR信号常時 ON			*/
+					/*  \V0: リザルトコード TYPE 1		*/
+					/*  \Q1: XON/XOFF フロー制御		*/
+					/* S0=1: 自動着信リング回数 = 1 回	*/
+
+#define MODEM_CFG_PHONE_NUMBER		"090-xxxx-9242"
+
+					/* 自構成情報の規定値			*/
+#define DEF_LCP_LOCAL_CFGS		(LCP_CFG_MRU|LCP_CFG_ACCM|LCP_CFG_MAGIC|\
+					 LCP_CFG_ACCOMP|LCP_CFG_PCOMP|LCP_CFG_PAP)
+
+					/* 相手に許す構成情報の規定値		*/
+#define DEF_LCP_REMOTE_CFGS		(LCP_CFG_MRU|LCP_CFG_ACCM|LCP_CFG_MAGIC|\
+					 LCP_CFG_ACCOMP|LCP_CFG_PCOMP|LCP_CFG_PAP)
+
+/*
+ *  認証に関する定義
+ */
+
+#define AUTH_CFG_CLIENT		   	/* 認証クライアントモードの時はコメントを外す。	*/
+#define AUTH_CFG_SERVER			/* 認証サーバモードの時はコメントを外す。		*/
+
+#define AUTH_LOCAL_USER			"h8"		/* 自ホストへのログイン認証ユーザ名	*/
+#define AUTH_LOCAL_PASSWD		"3048f"		/* 自ホストへのログイン認証パスワード	*/
+#define AUTH_REMOTE_USER		"pen3"		/* 相手へのログイン認証ユーザ名		*/
+#define AUTH_REMOTE_PASSWD		"600MHz"	/* 相手へのログイン認証パスワード		*/
+
+/*
+ *  ARP に関する定義
+ */
+
+/*#define ARP_CFG_CALLBACK_DUPLICATED*/	/* IP アドレス重複検出コールバック関数を	*/
+					/* 定義する場合はコメントを外す。		*/
+
+/*
+ *  ICMPv4/v6 に関する定義
+ */
+
+#ifdef USE_PING
+
+#define ICMP_CFG_CALLBACK_ECHO_REPLY	/* ICMP ECHO 応答を受信したとき呼出すコールバック関数を	*/
+					/* 定義する場合はコメントを外す。			*/
+
+#endif	/* of #ifdef USE_PING */
+
+/*
+ *  ネットワークバッファに関する定義
+ */
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  イーサネットの場合のネットワークバッファ数の割り当て
+ */
+
+/*
+ *  64 オクテット
+ *
+ *    IPv4 でのみ割り当てる。
+ *
+ *    IPv6 では、TCP 制御セグメント（CSEG、SDU なし）サイズの
+ *    ネットワークバッファ（IF + IPv6 + TCP = 74）以下の
+ *    ネットワークバッファは不要である。
+ */
+
+#ifdef NUM_MPF_NET_BUF_64
+#undef NUM_MPF_NET_BUF_64
+#endif
+
+#ifdef SUPPORT_INET4
+#define NUM_MPF_NET_BUF_64		4
+#else
+#define NUM_MPF_NET_BUF_64		0
+#endif
+
+/*
+ *  CSEG（IF + IP + TCP）
+ *
+ *    IPv6 でのみ割り当てる。
+ *
+ *    MBED Ethernet Controler のディバイスドライバ（if_mbed）の最低割当て長は、
+ *    イーサネットフレームの最短長である 60（CRC の 4 オクテットを除き、
+ *    更にアラインして 62）オクテットである。
+ *    従って、IPv4 では、CSEG サイズのネットワークバッファ
+ *   （IF + IPv4 + TCP = 54）は不要である。
+ */
+
+#ifdef NUM_MPF_NET_BUF_CSEG
+#undef NUM_MPF_NET_BUF_CSEG
+#endif
+
+#ifdef SUPPORT_INET6
+#define NUM_MPF_NET_BUF_CSEG		4
+#else
+#define NUM_MPF_NET_BUF_CSEG		0
+#endif
+
+/*
+ *  128 オクテット
+ *
+ *    IPv4 で、TCP MSS（IP MSS、IF + 576 オクテット）の
+ *    ネットワークバッファを割り当てる場合、
+ *    128 オクテットのネットワークバッファは割り当てない。
+ */
+
+#ifdef NUM_MPF_NET_BUF_128
+#undef NUM_MPF_NET_BUF_128
+#endif
+
+#if defined(USE_TCP_MSS_SEG)
+#define NUM_MPF_NET_BUF_128		0
+#else
+#define NUM_MPF_NET_BUF_128		2
+#endif
+
+/*
+ *  256 オクテット
+ *
+ *    IPv4 で、TCP MSS（IP MSS、IF + 576 オクテット）の
+ *    ネットワークバッファを割り当てる場合、
+ *    256 オクテットのネットワークバッファは割り当てない。
+ */
+
+#ifdef NUM_MPF_NET_BUF_256
+#undef NUM_MPF_NET_BUF_256
+#endif
+
+/*#if defined(USE_TCP_MSS_SEG)
+#define NUM_MPF_NET_BUF_256		0
+#else
+#define NUM_MPF_NET_BUF_256		2
+#endif*/
+#define NUM_MPF_NET_BUF_256		10
+
+/*
+ *  512 オクテット	
+ *
+ *    IPv4 で、TCP MSS（IP MSS、IF + 576 オクテット）の
+ *    ネットワークバッファを割り当てる場合、
+ *    512 オクテットのネットワークバッファは割り当てない。
+ */
+
+#ifdef NUM_MPF_NET_BUF_512
+#undef NUM_MPF_NET_BUF_512
+#endif
+
+#if defined(USE_TCP_MSS_SEG)
+#define NUM_MPF_NET_BUF_512		0
+#else
+#define NUM_MPF_NET_BUF_512		2
+#endif
+
+/*
+ *  TCP MSS（IP MSS、IF + 576 オクテット）
+ *
+ *   ・IPv4 でのみ割り当てる。
+ *   ・送受信ウィンドバッファの省コピー機能が有効で、
+ *     省コピー API を使用するときは、+1 割り当てる。
+ */
+
+#ifdef NUM_MPF_NET_BUF_IP_MSS
+#undef NUM_MPF_NET_BUF_IP_MSS
+#endif
+
+#if defined(SUPPORT_INET4) && defined(USE_TCP_MSS_SEG)
+
+#if (defined(TCP_CFG_RWBUF_CSAVE)      || defined(TCP_CFG_SWBUF_CSAVE) ||	\
+     defined(TCP_CFG_RWBUF_CSAVE_ONLY) || defined(TCP_CFG_SWBUF_CSAVE_ONLY)) && defined(USE_COPYSAVE_API)
+#define NUM_MPF_NET_BUF_IP_MSS		6
+#else
+#define NUM_MPF_NET_BUF_IP_MSS		4	/* IF + 576 オクテット	*/
+#endif
+
+#else	/* of #if defined(SUPPORT_INET4) && defined(USE_TCP_MSS_SEG) */
+
+#define NUM_MPF_NET_BUF_IP_MSS		0	/* IF + 576 オクテット	*/
+
+#endif	/* of #if defined(SUPPORT_INET4) && defined(USE_TCP_MSS_SEG) */
+
+/*
+ *  1024 オクテット	
+ *
+ *    TCP MSS のネットワークバッファを割り当てる場合、
+ *    1024 オクテットのネットワークバッファは割り当てない。
+ */
+
+#ifdef NUM_MPF_NET_BUF_1024
+#undef NUM_MPF_NET_BUF_1024
+#endif
+
+#if defined(USE_TCP_MSS_SEG)
+#define NUM_MPF_NET_BUF_1024		0	/* 1024 オクテット	*/
+#else
+#define NUM_MPF_NET_BUF_1024		2	/* 1024 オクテット	*/
+#endif
+
+/*
+ *  TCP MSS（IPV6 MMTU、IF + 1280 オクテット）
+ *
+ *   ・IPv6 でのみ割り当てる。
+ *   ・送受信ウィンドバッファの省コピー機能が有効で、
+ *     省コピー API を使用するときは、+1 割り当てる。
+ */
+
+#ifdef NUM_MPF_NET_BUF_IPV6_MMTU
+#undef NUM_MPF_NET_BUF_IPV6_MMTU
+#endif
+
+#if defined(SUPPORT_INET6) && (defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU))
+
+#if (defined(TCP_CFG_RWBUF_CSAVE)      || defined(TCP_CFG_SWBUF_CSAVE) ||	\
+     defined(TCP_CFG_RWBUF_CSAVE_ONLY) || defined(TCP_CFG_SWBUF_CSAVE_ONLY)) && defined(USE_COPYSAVE_API)
+#define NUM_MPF_NET_BUF_IPV6_MMTU	6	/* IF + 1280	*/
+#else
+#define NUM_MPF_NET_BUF_IPV6_MMTU	4	/* IF + 1280	*/
+#endif
+
+#else	/* of #if defined(SUPPORT_INET6) && (defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)) */
+
+#define NUM_MPF_NET_BUF_IPV6_MMTU	0	/* IF + 1280	*/
+
+#endif	/* of #if defined(SUPPORT_INET6) && (defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)) */
+
+/*
+ *  IF 最大 PDU サイズ
+ *
+ *   ・TCP MSS のネットワークバッファを割り当てる場合、
+ *     IF 最大 PDU サイズのネットワークバッファは割り当てない。
+ *   ・送受信ウィンドバッファの省コピー機能が有効で、
+ *     省コピー API を使用するときは、+1 割り当てる。
+ */
+
+#ifdef NUM_MPF_NET_BUF_IF_PDU
+#undef NUM_MPF_NET_BUF_IF_PDU
+#endif
+
+#ifdef USE_TCP_MSS_SEG
+
+#define NUM_MPF_NET_BUF_IF_PDU		0
+
+#else	/* of #ifdef USE_TCP_MSS_SEG */
+
+#if (defined(TCP_CFG_RWBUF_CSAVE) || defined(TCP_CFG_SWBUF_CSAVE)) && defined(USE_COPYSAVE_API)
+#define NUM_MPF_NET_BUF_IF_PDU		12
+#else
+#define NUM_MPF_NET_BUF_IF_PDU		10
+#endif
+
+#endif	/* of #ifdef USE_TCP_MSS_SEG */
+
+/*
+ *  65536 オクテット
+ *
+ *  ・NET_BUF_CFG_LONG_LEN を定義したときのみ割り当てる。
+ */
+
+#ifdef NET_BUF_CFG_LONG_LEN
+
+/* IPv6 用 */
+
+#ifdef NUM_MPF_NET_BUF6_65536
+#undef NUM_MPF_NET_BUF6_65536
+#endif
+
+#if defined(USE_TCP_MSS_SEG)
+#define NUM_MPF_NET_BUF6_65536	0
+#else
+#define NUM_MPF_NET_BUF6_65536	4
+#endif
+
+#else	/* of ifdef NET_BUF_CFG_LONG_LEN */
+
+#define NUM_MPF_NET_BUF6_65536	0
+
+#endif	/* of ifdef NET_BUF_CFG_LONG_LEN */
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+/*
+ *  DNS サーバに関する定義
+ */
+
+/* DNS サーバの IP アドレス */
+
+//#if !defined(DHCP6_CLI_CFG)
+
+#define IPV6_ADDR_DNS_INIT	\
+	{{{ UINT_C(0xfd), UINT_C(0x90), UINT_C(0xcc), UINT_C(0xe5), \
+	    UINT_C(0x25), UINT_C(0xf6), UINT_C(0xff), UINT_C(0x81), \
+	    UINT_C(0x02), UINT_C(0xa0), UINT_C(0x24), UINT_C(0xff), \
+	    UINT_C(0xfe), UINT_C(0x56), UINT_C(0xc5), UINT_C(0xd6) }}}
+
+//#endif	/* of #if !defined(DHCP6_CLI_CFG) */
+
+//#if !defined(DHCP4_CLI_CFG)
+#define IPV4_ADDR_DNS		MAKE_IPV4_ADDR(192,168,137,1)
+//#endif
+
+/* DOMAIN 名 */
+
+#if !(defined(DHCP4_CLI_CFG) || defined(DHCP6_CLI_CFG))
+#define RSLV_CFG_DNS_DOMAIN_NAME_STR	"jo.tomakomai-ct.ac.jp"
+#endif
+
+/*
+ *  DHCP クライアントに関する定義
+ */
+
+/* DHCPv6 の動作モードの設定 */
+
+#define DHCP6_CLI_CFG_MODE	DHCP6_CLI_CFG_STATELESS
+//#define DHCP6_CLI_CFG_MODE	DHCP6_CLI_CFG_STATEFULL
+
+#define ETHER_OUTPUT_PRIORITY	7	/* Ethernet 出力タスクの優先度		*/
+#define TCP_OUT_TASK_PRIORITY	6	/* TCP 出力タスクの優先度			*/
+#define NUM_DTQ_ETHER_OUTPUT	16	/* Ethernet 出力データキューサイズ	*/
+
+#endif /* _TINET_APP_CONFIG_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/.cproject
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/.cproject	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/.cproject	(revision 398)
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1141772740">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1141772740" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings>
+					<externalSetting>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/asp3_dcre"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/asp3_dcre/Debug"/>
+						<entry flags="RESOLVED" kind="libraryFile" name="asp3_dcre" srcPrefixMapping="" srcRootPath=""/>
+					</externalSetting>
+				</externalSettings>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="com.renesas.cdt.managedbuild.core.toolchainInfo">
+				<option id="toolchain.id" value="RENESAS_GCC_RX"/>
+				<option id="toolchain.version" value="4.8.4.201803"/>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="GR-SAKURA" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1141772740" name="Debug" parent="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib">
+					<folderInfo id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1141772740." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib.2015337568" name="GCC for Renesas RX" superClass="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib">
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.437023014" name="Optimization Level" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.debug" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections.1134325396" name="Data sections (-fdata-sections)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.78358819" name="Debug format" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.Default" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.590865234" name="Architecture" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture" useByScannerDiscovery="false" value="com.renesas.cdt.managedbuild.gcc.rx.architecture.v1" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability.1569090021" name="Architecture Applicability" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability" useByScannerDiscovery="false" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName.1692963898" name="DeviceName" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName" useByScannerDiscovery="false" value="R5F563NBDxFP" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand.2009531218" name="DeviceCommand" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand" useByScannerDiscovery="false" value="R5F563NB" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize.240222967" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize" useByScannerDiscovery="false" value="100" valueType="string"/>
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.renesas.cdt.managedbuild.gcc.core.targetPlatform.635282713" isAbstract="false" osList="all" superClass="com.renesas.cdt.managedbuild.gcc.core.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/asp3_dcre}/Debug" id="com.renesas.cdt.managedbuild.gcc.core.builder.1294414176" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="GCC for Renesas Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.managedbuild.gcc.core.builder"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen.946367481" name="Library Generator" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen">
+								<option id="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary.1170480133" name="Select Library" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.selectLibrary.newLib" valueType="enumerated"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.ctype.1151082078" name="ctype.h : Handles and checks characters" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.ctype" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.math.1236795275" name="math.h : Performs numeric calculations" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.math" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdio.37798219" name="stdio.h : Performs input/output handling" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdio" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdlib.504749247" name="stdlib.h : Performs C program standard processing" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdlib" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.string.393806246" name="string.h : Performs string operations" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.string" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType.1629400251" name="Library type" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType.preBuilt" valueType="enumerated"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.1111362713" name="Compiler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.2054745662" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" valueType="includePath"/>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.29581862" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler.1973101528" name="Compiler CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.76410091" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" valueType="includePath"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler.440090156" name="Assembler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler">
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor.149510249" name="Use preprocessor" superClass="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor" useByScannerDiscovery="false"/>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler.924423055" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.linker.666826710" name="Linker" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.linker"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker.1378229406" name="Linker CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy.1193107366" name="Objcopy" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver.279737131" name="Archiver" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+		<cconfiguration id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1141772740.1807945246">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1141772740.1807945246" moduleId="org.eclipse.cdt.core.settings" name="DebugCitrus">
+				<externalSettings>
+					<externalSetting>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/asp3_dcre"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/asp3_dcre/Debug"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/asp3_dcre/DebugCitrus"/>
+						<entry flags="RESOLVED" kind="libraryFile" name="asp3_dcre" srcPrefixMapping="" srcRootPath=""/>
+					</externalSetting>
+				</externalSettings>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="com.renesas.cdt.managedbuild.core.toolchainInfo">
+				<option id="toolchain.id" value="RENESAS_GCC_RX"/>
+				<option id="toolchain.version" value="4.8.4.201803"/>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="GR-CITRUS" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1141772740.1807945246" name="DebugCitrus" parent="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib">
+					<folderInfo id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1141772740.1807945246." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib.954299092" name="GCC for Renesas RX" superClass="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib">
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.52145852" name="Optimization Level" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.debug" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections.1744714466" name="Data sections (-fdata-sections)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.454116981" name="Debug format" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.Default" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.2025903549" name="Architecture" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture" useByScannerDiscovery="false" value="com.renesas.cdt.managedbuild.gcc.rx.architecture.v1" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability.1528028446" name="Architecture Applicability" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability" useByScannerDiscovery="false" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName.189078811" name="DeviceName" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName" useByScannerDiscovery="false" value="R5F5631FDxFP" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand.210295067" name="DeviceCommand" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand" useByScannerDiscovery="false" value="R5F5631F" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize.1083888317" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize" useByScannerDiscovery="false" value="100" valueType="string"/>
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.renesas.cdt.managedbuild.gcc.core.targetPlatform.570033485" isAbstract="false" osList="all" superClass="com.renesas.cdt.managedbuild.gcc.core.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/asp3_dcre}/DebugCitrus" id="com.renesas.cdt.managedbuild.gcc.core.builder.1961458105" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="GCC for Renesas Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.managedbuild.gcc.core.builder"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen.1465675052" name="Library Generator" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen">
+								<option id="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary.1037533987" name="Select Library" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.selectLibrary.newLib" valueType="enumerated"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.ctype.2142989377" name="ctype.h : Handles and checks characters" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.ctype" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.math.1166305813" name="math.h : Performs numeric calculations" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.math" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdio.2092784556" name="stdio.h : Performs input/output handling" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdio" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdlib.1959632906" name="stdlib.h : Performs C program standard processing" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdlib" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.string.625134910" name="string.h : Performs string operations" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.string" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType.1229104549" name="Library type" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType.preBuilt" valueType="enumerated"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.898625248" name="Compiler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.1239074055" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" valueType="includePath"/>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.1227214253" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler.357137743" name="Compiler CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.1091121156" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" valueType="includePath"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler.1313127858" name="Assembler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler">
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor.1462577396" name="Use preprocessor" superClass="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor" useByScannerDiscovery="false"/>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler.752901673" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.linker.556754216" name="Linker" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.linker"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker.522679427" name="Linker CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy.544937954" name="Objcopy" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver.1337586124" name="Archiver" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="asp3_dcre.com.renesas.cdt.managedbuild.gcc.rx.ui.projectType.lib.1653004172" name="static ã©ã¤ãã©ãªã¼" projectType="com.renesas.cdt.managedbuild.gcc.rx.ui.projectType.lib"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<scannerConfigBuildInfo instanceId="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1141772740;com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1141772740.;com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.1111362713;com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.29581862">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.release.lib.1759387786;com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.release.lib.1759387786.;com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.1831052993;com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.834580385">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="DebugCitrus"/>
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/asp3_dcre"/>
+		</configuration>
+		<configuration configurationName="Release">
+			<resource resourceType="PROJECT" workspacePath="/asp3_dcre"/>
+		</configuration>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+</cproject>
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/.project
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/.project	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/.project	(revision 398)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>asp3_dcre</name>
+	<comment></comment>
+	<projects>
+		<project>musl-1.1.18</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/Debug/Makefile
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/Debug/Makefile	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/Debug/Makefile	(revision 398)
@@ -0,0 +1,637 @@
+#
+#  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-2016 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 = gr_sakura_gcc
+
+#
+#  プログラミング言語の定義
+#
+SRCLANG = c
+ifeq ($(SRCLANG),c)
+	LIBS = $(SRCDIR)/../musl-1.1.18/Debug/libmusl.a
+endif
+ifeq ($(SRCLANG),c++)
+	USE_CXX = true
+	CXXLIBS = -lstdc++ $(SRCDIR)/../musl-1.1.18/Debug/libmusl.a
+	CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+#  ソースファイルのディレクトリの定義
+#
+SRCDIR = ..
+
+#
+#  オブジェクトファイル名の拡張子の設定
+#
+OBJEXT = elf
+
+#
+#  カーネルライブラリ（libkernel.a）のディレクトリ名
+#  （カーネルライブラリもmake対象にする時は，空に定義する）
+#
+KERNEL_LIB = 
+
+#
+#  カーネルを関数単位でコンパイルするかどうかの定義
+#
+KERNEL_FUNCOBJS = 
+
+#
+#  TECSを外すかどうかの定義
+#
+OMIT_TECS = 
+
+#
+#  トレースログを取得するかどうかの定義
+#
+ENABLE_TRACE = 
+
+#
+#  開発ツール（コンパイラ等）のディレクトリの定義
+#
+DEVTOOLDIR = 
+
+#
+#  ユーティリティプログラムの名称
+#
+CFG = ruby -Eutf-8 $(SRCDIR)/cfg/cfg.rb
+TECSGEN = ruby -Eutf-8 $(SRCDIR)/tecsgen/tecsgen.rb
+
+#
+#  オブジェクトファイル名の定義
+#
+OBJNAME = asp
+ifdef OBJEXT
+	OBJFILE = $(OBJNAME).$(OBJEXT)
+	CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+	OBJFILE = $(OBJNAME)
+	CFG1_OUT = cfg1_out
+endif
+
+#
+#  依存関係ファイルを置くディレクトリの定義
+#
+DEPDIR = deps
+
+#
+#  ターゲット依存部のディレクトリの定義
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ターゲット依存の定義のインクルード
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  TECS生成ファイルのディレクトリの定義
+#
+TECSGENDIR = ./gen
+ifndef OMIT_TECS
+	TECSGEN_TIMESTAMP = $(TECSGENDIR)/tecsgen.timestamp
+	INIT_TECS_COBJ = init_tecs.o
+endif
+
+#
+#  TECSが生成する定義のインクルード
+#
+ifndef OMIT_TECS
+	GEN_DIR = $(TECSGENDIR)
+	-include $(TECSGENDIR)/Makefile.tecsgen
+endif
+
+TINETDIR = 
+
+#
+#  mbedサービスの定義
+#
+
+include $(SRCDIR)/mbed/Makefile.mbed
+
+#
+#  共通コンパイルオプションの定義
+#
+COPTS := -g -std=gnu99 $(COPTS)
+ifndef OMIT_WARNING_ALL
+	COPTS := -Wall $(COPTS)
+endif
+ifndef OMIT_OPTIMIZATION
+	COPTS := -Og $(COPTS)
+endif
+ifdef OMIT_TECS
+	CDEFS := -DTOPPERS_OMIT_TECS $(CDEFS)
+endif
+CDEFS := $(CDEFS) 
+INCLUDES := -I. -I$(SRCDIR)/include $(INCLUDES) -I$(SRCDIR)
+LDFLAGS := $(LDFLAGS) -L.
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  アプリケーションプログラムに関する定義
+#
+APPLNAME = sample1
+APPLDIRS = $(SRCDIR)/sample
+APPL_CFG = sample1.cfg
+APPL_CDL = sample1.cdl
+
+APPL_DIRS := $(APPLDIRS) $(SRCDIR)/library
+APPL_ASMOBJS :=
+ifdef USE_CXX
+	APPL_CXXOBJS := sample1.o
+	APPL_COBJS :=
+else
+	APPL_COBJS := sample1.o
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+APPL_CFLAGS := $(APPL_CFLAGS) -nostdinc
+ifdef APPLDIRS
+	INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIRS),-I$(dir))
+endif
+
+ifdef TINETDIR
+	#
+	#  ネットワークサービスの定義
+	#
+	NO_USE_TINET_LIBRARY = true
+
+	#  ネットワークインタフェースの選択、何れか一つ選択する。
+	NET_IF = ether
+
+	#  イーサネット・ディバイスドライバの選択
+	NET_DEV = if_rx62n
+
+	#  ネットワーク層の選択
+	#SUPPORT_INET6 = true
+	SUPPORT_INET4 = true
+
+	#  API に組込む機能の選択
+	#API_CFG_IP4MAPPED_ADDR = true
+
+	#  トランスポート層の選択
+	SUPPORT_TCP = true
+	#SUPPORT_UDP = true
+
+	# IGMPを有効に設定
+	#SUPPORT_IGMP = true
+
+	#
+	#  ネットワークサービスの Makefile のインクルード
+	#
+	include $(SRCDIR)/$(TINETDIR)/Makefile.tinet
+endif
+
+#
+#  システムサービスに関する定義
+#
+SYSSVC_DIRS := $(TECSGENDIR) $(SRCDIR)/tecs_kernel \
+				$(SYSSVC_DIRS) $(SRCDIR)/syssvc
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(INIT_TECS_COBJ) $(TECS_COBJS) $(SYSSVC_COBJS) \
+				 $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+INCLUDES := $(INCLUDES) -I$(TECSGENDIR) -I$(SRCDIR)/tecs_kernel -I../../musl-1.1.18/include
+
+#
+#  ターゲットファイル
+#
+.PHONY: all
+ifndef OMIT_TECS
+all: tecs | $(DEPDIR)
+#	@$(MAKE) check
+#	@$(MAKE) check $(OBJNAME).bin
+#	@$(MAKE) check $(OBJNAME).srec
+	@$(MAKE) check $(OBJNAME).mot
+else
+#all: check
+#all: check $(OBJNAME).bin
+#all: check $(OBJNAME).srec
+all: check $(OBJNAME).mot
+endif
+
+##### 以下は編集しないこと #####
+
+#
+#  コンフィギュレータに関する定義
+#
+ifndef TINETDIR
+  CFG_TRB := -T $(TARGETDIR)/target_kernel.trb
+  CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.def \
+			--symval-table $(SRCDIR)/kernel/kernel_sym.def $(CFG_TABS)
+else
+  CFG_TRB := -T $(TINET_ROOT)/tinet.trb:tcpip -T $(TARGETDIR)/target_kernel.trb:kernel
+  CFG_TABS := --api-table $(TINET_ROOT)/tcpip_api.def:tcpip \
+			--api-table $(SRCDIR)/kernel/kernel_api.def:kernel \
+			--symval-table $(TINET_ROOT)/tcpip_sym.def \
+			--symval-table $(SRCDIR)/kernel/kernel_sym.def $(CFG_TABS)
+endif
+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)
+CFG_CFLAGS := -DTOPPERS_CB_TYPE_ONLY $(CFG_CFLAGS)
+
+#
+#  カーネルに関する定義
+#
+#  KERNEL_ASMOBJS: カーネルライブラリに含める，ソースがアセンブリ言語の
+#				   オブジェクトファイル．
+#  KERNEL_COBJS: カーネルのライブラリに含める，ソースがC言語で，ソース
+#				 ファイルと1対1に対応するオブジェクトファイル．
+#  KERNEL_LCSRCS: カーネルのライブラリに含めるC言語のソースファイルで，
+#				  1つのソースファイルから複数のオブジェクトファイルを生
+#				  成するもの．
+#  KERNEL_LCOBJS: 上のソースファイルから生成されるオブジェクトファイル．
+#
+KERNEL_DIRS := $(KERNEL_DIRS) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+
+#
+#  カーネルのファイル構成の定義
+#
+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
+ifdef OMIT_OFFSET_H
+	OFFSET_H =
+else
+	OFFSET_H = offset.h
+endif
+ifndef TARGET_OFFSET_TRB
+	TARGET_OFFSET_TRB := $(TARGETDIR)/target_offset.trb
+endif
+ifndef TARGET_KERNEL_TRB
+	TARGET_KERNEL_TRB := $(TARGETDIR)/target_kernel.trb
+endif
+ifndef TARGET_CHECK_TRB
+	TARGET_CHECK_TRB := $(TARGETDIR)/target_check.trb
+endif
+ifndef TARGET_KERNEL_CFG
+	TARGET_KERNEL_CFG := $(TARGETDIR)/target_kernel.cfg
+endif
+ifndef TARGET_TCPIP_TRB
+	TARGET_TCPIP_TRB := $(SRCDIR)/$(TINETDIR)/tinet.trb
+endif
+
+#
+#  ソースファイルのあるディレクトリに関する定義
+#
+vpath %.c $(KERNEL_DIRS) $(SYSSVC_DIRS) $(APPL_DIRS)
+vpath %.S $(KERNEL_DIRS) $(SYSSVC_DIRS) $(APPL_DIRS)
+vpath %.cfg $(APPL_DIRS)
+vpath %.cdl $(APPL_DIRS)
+vpath %.bin $(APPL_DIRS)
+
+#
+#  コンパイルのための変数の定義
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS) $(HIDDEN_OBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS) $(APPL_BINOBJS)
+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
+
+#
+#  tecsgenからCプリプロセッサを呼び出す際のオプションの定義
+#
+TECS_CPP = $(CC) $(CDEFS) $(INCLUDES) $(SYSSVC_CFLAGS) -D TECSGEN -E
+
+#
+#  tecsgenの呼出し
+#
+.PHONY: tecs
+tecs $(TECSGEN_SRCS) $(TECS_HEADERS): $(TECSGEN_TIMESTAMP) ;
+$(TECSGEN_TIMESTAMP): $(APPL_CDL) $(TECS_IMPORTS)
+	$(TECSGEN) $< -R $(INCLUDES) --cpp "$(subst ", \", $(TECS_CPP))" -g $(TECSGENDIR)
+
+#
+#  カーネルのコンフィギュレーションファイルの生成
+#
+cfg1_out.c cfg1_out.db: cfg1_out.timestamp ;
+cfg1_out.timestamp: $(APPL_CFG) $(TECSGEN_TIMESTAMP)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) \
+						-M $(DEPDIR)/cfg1_out_c.d $(TARGET_KERNEL_CFG) $<
+
+$(CFG1_OUT): $(START_OBJS) cfg1_out.o $(CFG_DMY) $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(LDFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(CFG_DMY) $(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) cfg2_out.db: kernel_cfg.timestamp ;
+kernel_cfg.timestamp: cfg1_out.db cfg1_out.syms cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) $(CFG_TRB)
+
+#
+#  オフセットファイル（offset.h）の生成規則
+#
+$(OFFSET_H): offset.timestamp ;
+offset.timestamp: cfg1_out.db cfg1_out.syms cfg1_out.srec
+	$(CFG) --pass 2 -O --kernel asp $(INCLUDES) -T $(TARGET_OFFSET_TRB) \
+				--rom-symbol cfg1_out.syms --rom-image cfg1_out.srec
+
+#
+#  カーネルライブラリファイルの生成
+#
+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
+
+#
+#  特別な依存関係の定義
+#
+tBannerMain.o: $(filter-out tBannerMain.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  全体のリンク
+#
+$(OBJFILE): $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) $(OBJ_LDFLAGS) -o $(OBJFILE) -Wl,-Map=$(OBJNAME).map,--cref \
+			$(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
+
+$(OBJNAME).mot: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).mot
+
+#
+#  エラーチェック処理
+#
+.PHONY: check
+check: check.timestamp ;
+check.timestamp: cfg2_out.db $(OBJNAME).syms $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp -O $(INCLUDES) -T $(TARGET_CHECK_TRB) \
+				--rom-symbol $(OBJNAME).syms --rom-image $(OBJNAME).srec
+	@echo "configuration check passed"
+
+#
+#  コンパイル結果の消去
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(DEPDIR)/*.d $(CLEAN_FILES) check.timestamp
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS) cfg2_out.db
+	rm -f offset.timestamp $(OFFSET_H)
+	rm -f cfg1_out.syms cfg1_out.srec $(CFG1_OUT)
+	rm -f cfg1_out.timestamp cfg1_out.c cfg1_out.db
+	rm -rf $(TECSGENDIR)
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+
+.PHONY: cleankernel
+cleankernel:
+	rm -f $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f $(KERNEL_LIB_OBJS:%.o=$(DEPDIR)/%.d)
+
+.PHONY: realclean
+realclean: clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  コンフィギュレータが生成したファイルのコンパイルルールの定義
+#
+#  コンフィギュレータが生成したファイルは，共通のコンパイルオプション
+#  のみを付けてコンパイルする．
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c -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): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c -MD -MP -MF $(DEPDIR)/$*.d \
+									$(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_BINOBJS): %.o: %.bin
+	$(OBJCOPY) -B rx -I binary -O elf32-rx-le --rename-section .data=.rodata $< $*.o
+
+#
+#  デフォルトコンパイルルールを上書き
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(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 -MD -MP -MF $(DEPDIR)/$*.d $(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 -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $<
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/MANIFEST
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/MANIFEST	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/MANIFEST	(revision 398)
@@ -0,0 +1,163 @@
+PACKAGE asp3
+VERSION 3.2.0
+
+configure.rb
+MANIFEST
+README.txt
+
+doc/asp_spec.txt
+doc/configurator.txt
+doc/design.txt
+doc/extension.txt
+doc/migration.txt
+doc/porting.txt
+doc/user.txt
+doc/version.txt
+
+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
+
+kernel/Makefile.kernel
+kernel/alarm.c
+kernel/alarm.h
+kernel/alarm.trb
+kernel/allfunc.h
+kernel/check.h
+kernel/cyclic.c
+kernel/cyclic.h
+kernel/cyclic.trb
+kernel/dataqueue.c
+kernel/dataqueue.h
+kernel/dataqueue.trb
+kernel/eventflag.c
+kernel/eventflag.h
+kernel/eventflag.trb
+kernel/exception.c
+kernel/exception.h
+kernel/exception.trb
+kernel/genoffset.trb
+kernel/interrupt.c
+kernel/interrupt.h
+kernel/interrupt.trb
+kernel/kernel.trb
+kernel/kernel_api.def
+kernel/kernel_check.trb
+kernel/kernel_impl.h
+kernel/kernel_int.h
+kernel/kernel_rename.def
+kernel/kernel_rename.h
+kernel/kernel_sym.def
+kernel/kernel_unrename.h
+kernel/mempfix.c
+kernel/mempfix.h
+kernel/mempfix.trb
+kernel/mutex.c
+kernel/mutex.h
+kernel/mutex.trb
+kernel/pridataq.c
+kernel/pridataq.h
+kernel/pridataq.trb
+kernel/semaphore.c
+kernel/semaphore.h
+kernel/semaphore.trb
+kernel/startup.c
+kernel/sys_manage.c
+kernel/task.c
+kernel/task.h
+kernel/task.trb
+kernel/task_manage.c
+kernel/task_refer.c
+kernel/task_sync.c
+kernel/task_term.c
+kernel/taskhook.c
+kernel/taskhook.h
+kernel/time_event.c
+kernel/time_event.h
+kernel/time_manage.c
+kernel/wait.c
+kernel/wait.h
+
+tecs_kernel/init_tecs.c
+tecs_kernel/kernel.cdl
+tecs_kernel/tAlarmNotifier.c
+tecs_kernel/tAlarmNotifier_inline.h
+tecs_kernel/tCpuExceptionHandler.c
+tecs_kernel/tCyclicNotifier.c
+tecs_kernel/tCyclicNotifier_inline.h
+tecs_kernel/tDataqueue_inline.h
+tecs_kernel/tEventflag_inline.h
+tecs_kernel/tFixedSizeMemoryPool_inline.h
+tecs_kernel/tISR.c
+tecs_kernel/tInitializeRoutine.c
+tecs_kernel/tInterruptHandler.c
+tecs_kernel/tInterruptRequest_inline.h
+tecs_kernel/tKernel_inline.h
+tecs_kernel/tMutex_inline.h
+tecs_kernel/tPriorityDataqueue_inline.h
+tecs_kernel/tSemaphore_inline.h
+tecs_kernel/tTask.c
+tecs_kernel/tTask_inline.h
+tecs_kernel/tTerminateRoutine.c
+tecs_kernel/tecs_kernel.h
+
+syssvc/histogram.h
+syssvc/serial.h
+syssvc/syslog.h
+syssvc/tHistogram.c
+syssvc/tHistogram.cdl
+syssvc/tHistogram.h
+syssvc/tHistogramAdapter.c
+syssvc/tHistogramAdapter.cdl
+syssvc/tBanner.cdl
+syssvc/tBannerMain.c
+syssvc/tLogTask.cdl
+syssvc/tLogTaskMain.c
+syssvc/tSerialAdapter.c
+syssvc/tSerialAdapter.cdl
+syssvc/tSerialPort.cdl
+syssvc/tSerialPortMain.c
+syssvc/tSysLog.c
+syssvc/tSysLog.cdl
+syssvc/tSysLogAdapter.c
+syssvc/tSysLogAdapter.cdl
+syssvc/tTestService.c
+syssvc/tTestService.cdl
+syssvc/tBuiltInTestAdaptor.c
+syssvc/test_svc.h
+
+library/log_output.c
+library/strerror.c
+library/t_perror.c
+library/vasyslog.c
+
+arch/gcc/tool_stddef.h
+
+arch/tracelog/trace_log.h
+arch/tracelog/tTraceLog.c
+arch/tracelog/tTraceLog.cdl
+
+utils/applyrename.rb
+utils/genrename.rb
+utils/gentest.rb
+utils/makerelease.rb
+
+sample/Makefile
+sample/sample1.c
+sample/sample1.cdl
+sample/sample1.cfg
+sample/sample1.h
+sample/tSample2.c
+sample/tSample2.cdl
+sample/tSample2.cfg
+sample/tSample2.h
+
+INCLUDE cfg/MANIFEST
+INCLUDE test/MANIFEST
+INCLUDE extension/MANIFEST
+INCLUDE target/dummy_gcc/MANIFEST
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/README.txt
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/README.txt	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/README.txt	(revision 398)
@@ -0,0 +1,53 @@
+
+	TOPPERS/ASP3 Kernel（Release 3.2）
+		Toyohashi Open Platform for Embedded Real-Time Systems/
+		Advanced Standard Profile Kernel
+
+TOPPERS/ASP3カーネル（TOPPERS/ASPカーネル Release 3.X．以下，ASP3カーネ
+ル）は，TOPPERS/ASPカーネルを拡張・改良したもので，TOPPERS第3世代カーネ
+ル（ITRON系）の基盤となるものとして開発したリアルタイムカーネルです．
+
+TOPPERS/ASPカーネルは，μITRON4.0仕様のスタンダードプロファイル準拠のリ
+アルタイムカーネルであるTOPPERS/JSPカーネルを拡張・改良する形で開発した
+ものです．
+
+【最初に読むべきドキュメント】
+
+ASP3カーネルの仕様概要がdoc/asp_spec.txtに，ユーザーズマニュアルが
+doc/user.txtにあります．また，従来のTOPPERSカーネルからASP3カーネルへ移
+行するための方法を記述したマイグレーションガイドがdoc/migration.txtにあ
+ります．ASP3カーネルを使用する場合には，まずはこれらのドキュメントをお
+読み下さい．
+
+【ファイルの閲覧にあたって】
+
+ASP3カーネルのドキュメント（プレーンテキストファイル）およびソースファ
+イルを読む際には，TABを4に設定してください．
+
+【利用条件】
+
+ASP3カーネルの利用条件は，各ファイルの先頭に表示されているTOPPERSライセ
+ンスです．TOPPERSライセンスに関するFAQが，以下のページにあります．
+
+	http://www.toppers.jp/faq/faq_ct12.html
+
+【質問・バグレポート・意見等の送付先】
+
+ASP3カーネルをより良いものにするためのご意見等を歓迎します．ASP3カーネ
+ルに関する質問やバグレポート，ご意見等は，TOPPERSプロジェクトの会員は
+TOPPERS開発者メーリングリスト（dev@toppers.jp）宛またはASP3カーネルのバ
+グトラッキングシステム（Trac）に，その他の方はTOPPERSユーザーズメーリン
+グリスト（users@toppers.jp）宛にお願いします．
+
+TOPPERSユーザーズメーリングリストへの登録方法については，以下のページに
+説明があります．
+
+	http://www.toppers.jp/community.html
+
+【ポーティングにあたって】
+
+ASP3カーネルを，TOPPERSプロジェクトからオープンソースにすることを前提に，
+未サポートのターゲットにポーティングされる場合には，あらかじめご相談く
+ださると幸いです．
+
+以上
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/gcc/tool_stddef.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/gcc/tool_stddef.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/gcc/tool_stddef.h	(revision 398)
@@ -0,0 +1,202 @@
+/*
+ *  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
+
+#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_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/Makefile.prc
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/Makefile.prc	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/Makefile.prc	(revision 398)
@@ -0,0 +1,43 @@
+#
+#		Makefileのプロセッサ依存部（M68040用）
+#
+
+#
+#  GNU開発環境のターゲットアーキテクチャの定義
+#
+GCC_TARGET = rx-elf
+
+#
+#  プロセッサ依存部ディレクトリ名の定義
+#
+PRCDIR = $(SRCDIR)/arch/$(PRC)_$(TOOL)
+
+#
+#  ツール依存部ディレクトリ名の定義 
+#
+TOOLDIR = $(SRCDIR)/arch/$(TOOL)
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(TOOLDIR) -I$(PRCDIR)
+COPTS := $(COPTS) -ffunction-sections -fno-function-cse -fsigned-char -fdata-sections -mlittle-endian-data -mcpu=rx600 -m64bit-doubles
+LDFLAGS := $(LDFLAGS) -flto
+
+#
+#  カーネルに関する定義
+#
+KERNEL_DIRS := $(KERNEL_DIRS) $(PRCDIR)
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS) prc_support.o prc_test.o
+KERNEL_COBJS := $(KERNEL_COBJS) prc_kernel_impl.o rx630_kernel_impl.o
+
+#
+#  コンフィギュレータ関係の変数の定義
+#
+CFG_TABS := $(CFG_TABS) --symval-table $(PRCDIR)/prc_sym.def
+CFG_ASMOBJS := $(CFG_ASMOBJS) kernel_cfg_asm.o
+
+#
+#  オフセットファイル生成のための定義
+#
+TARGET_OFFSET_TRB = $(PRCDIR)/prc_offset.trb
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_cfg1_out.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_cfg1_out.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_cfg1_out.h	(revision 398)
@@ -0,0 +1,47 @@
+/*
+ *		cfg1_out.cのリンクに必要なスタブの定義
+ */
+
+void sta_ker( void )
+{
+}
+
+void hardware_init_hook( void )
+{
+}
+
+void software_init_hook( void )
+{
+}
+
+const size_t	_kernel_istksz = 0;
+
+STK_T *const	_kernel_istk = NULL;
+
+/*
+ *  オフセットファイルを生成するための定義
+ */
+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 */
+	0U,						/* bpriority */
+	0U,						/* priority */
+	false,					/* acqeue */
+	false,					/* wupque */
+	true,					/* enatex */
+#ifdef TOPPERS_SUPPORT_OVRHDR
+	false,					/* staovr */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+	0U,						/* texptn */
+	NULL,					/* p_winifo */
+	NULL,			/* mutex_queue */
+#ifdef TOPPERS_SUPPORT_OVRHDR
+	0U,						/* leftotm */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+	{ NULL, NULL }			/* tskctxb */
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_check.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_check.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_check.trb	(revision 398)
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# 
+#		パス3の生成スクリプトのコア依存部（ARM用）
+# 
+#  $Id$
+#
+
+#
+#  ターゲット非依存部のインクルード
+#
+IncludeTrb("kernel/kernel_check.trb")
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_insn.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_insn.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_insn.h	(revision 398)
@@ -0,0 +1,164 @@
+/*
+ *  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,2006 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		プロセッサの特殊命令のインライン関数定義（RX630用）
+ */
+
+#ifndef	TOPPERS_PRC_INSN_H
+#define	TOPPERS_PRC_INSN_H
+
+#ifndef TOPPERS_MACRO_ONLY
+
+static uint32_t current_psw( void );
+static void set_psw( uint32_t psw );
+Inline uint32_t current_ipl( void );
+Inline void set_ipl( uint32_t ipl );
+static void disint( void );
+static void enaint( void );
+static uint16_t rev_endian_uint16( uint16_t data );
+static uint32_t rev_endian_uint32( uint32_t data );
+
+/*
+ *  Iフラグ, IPLを取得するためのマクロ定義
+ */
+#define PSW_I_MASK		( 0x00010000UL )
+#define PSW_IPL_MASK	( 0x0F000000UL )
+
+#else /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  Iフラグ, IPLを取得するためのマクロ定義
+ */
+#define PSW_I_MASK		( 0x00010000 )
+#define PSW_IPL_MASK	( 0x0F000000 )
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  プロセッサステータスレジスタ(PSW)の現在値の読出し
+ */
+static uint32_t
+current_psw( void )
+{
+	uint32_t psw;
+	Asm("mvfc	psw, %0" : "=r"(psw));
+	return psw;
+}
+
+
+/*
+ *  プロセッサステータスレジスタ(PSW)へ設定
+ */
+static void
+set_psw( uint32_t psw )
+{
+	Asm("mvtc %0, psw" :: "r"(psw));
+}
+
+
+/*
+ *  IPLの現在値の読出し
+ */
+Inline uint32_t
+current_ipl( void )
+{
+	return ( uint32_t )( current_psw() & PSW_IPL_MASK );
+}
+
+
+/*
+ *  IPLへ設定
+ */
+Inline void
+set_ipl( uint32_t ipl )
+{
+	set_psw( ( current_psw() & ( ~PSW_IPL_MASK ) ) | ipl );
+}
+
+
+/*
+ *  NMIを除くすべての割込みの禁止
+ */
+static void
+disint( void )
+{
+	Asm("clrpsw	i");
+}
+
+
+/*
+ *  NMIを除くすべての割込みの許可
+ */
+static void
+enaint( void )
+{
+	Asm("setpsw	i");
+}
+
+
+/*
+ *  エンディアン変換 16bit
+ */
+static uint16_t
+rev_endian_uint16( uint16_t data )
+{
+	Asm("revw %0, %1" : "=r"(data) : "r"(data));
+	return data;
+}
+
+/*
+ *  エンディアン変換 32bit
+ */
+static uint32_t
+rev_endian_uint32( uint32_t data )
+{
+	Asm("revl %0, %1" : "=r"(data) : "r"(data));
+	return data;
+}
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_PRC_INSN_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel.h	(revision 398)
@@ -0,0 +1,100 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		kernel.hのプロセッサ依存部（RX630用）
+ *
+ *  このインクルードファイルは，target_kernel.h（または，そこからインク
+ *  ルードされるファイル）のみからインクルードされる．他のファイルから
+ *  直接インクルードしてはならない．
+ */
+
+#ifndef TOPPERS_PRC_KERNEL_H
+#define TOPPERS_PRC_KERNEL_H
+
+/*
+ *  カーネル本体をコンパイルするためのマクロ定義
+ */
+//#define ALLFUNC
+
+
+/*
+ *  サポートする機能の定義
+ */
+#define TOPPERS_TARGET_SUPPORT_DIS_INT		/* dis_intをサポートする */
+#define TOPPERS_TARGET_SUPPORT_ENA_INT		/* ena_intをサポートする */
+#define TOPPERS_TARGET_SUPPORT_CLR_INT		/* clr_intをサポートする */
+#define TOPPERS_TARGET_SUPPORT_RAS_INT		/* ras_intをサポートする */
+#define TOPPERS_TARGET_SUPPORT_PRB_INT		/* prb_intをサポートする */
+
+/*
+ *  カーネル管理の割込み優先度の範囲
+ *
+ *  TMIN_INTPRIの定義を変更することで，どのレベルよりも高い割込み優先度
+ *  を持つものをカーネル管理外の割込みとするかを変更できる．
+ *
+ *  TMIN_INTPRIに設定できる値は，-15～-1の範囲である．例えばTMIN_INTPRI
+ *  を-14に設定すると，NMIに加えてレベル7の割込みがカーネル管理外となる．
+ *  TMIN_INTPRIを-15に設定すると，NMI以外にカーネル管理外の割込みを
+ *  設けないことになる．
+ */
+#ifndef TMIN_INTPRI
+#define TMIN_INTPRI		( -15 )		/* 割込み優先度の最小値（最高値）*/
+#endif /* TMIN_INTPRI */
+#define TMAX_INTPRI		( -1 )		/* 割込み優先度の最大値（最低値） */
+
+
+/*
+ *  割込み属性の定義
+ */
+#define	TA_POSEDGE		TA_EDGE			/* ポジティブエッジトリガ */
+#define	TA_NEGEDGE		UINT_C( 0x04 )	/* ネガティブエッジトリガ */
+#define	TA_BOTHEDGE		UINT_C( 0x08 )	/* 両エッジトリガ */
+
+#define	TA_LOWLEVEL		UINT_C( 0x10 )	/* Lレベル */
+
+
+/*
+ *  デフォルトの割込み/例外ハンドラの有無
+ */
+/*#define	OMIT_DEFAULT_INT_HANDLER*/
+/*#define	OMIT_DEFAULT_EXC_HANDLER*/
+
+
+#endif /* TOPPERS_PRC_KERNEL_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel.trb	(revision 398)
@@ -0,0 +1,348 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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の生成スクリプトのコア依存部（RX63x用）
+#
+
+# 
+#  割込み番号と割込みハンドラ番号の定義
+# 
+#  RX630では割込み番号と割込みハンドラ番号が1対1で対応する．
+# 
+$INTNO_VALID = [ 16, 21, 23, *(27..59), 62, *(64..79), 90, 91, 92, 93, 98, 102, *(106..112), 114, *(122..167), *(170..203), *(214..253) ]
+$INHNO_VALID = $INTNO_VALID
+
+# 
+#  例外番号の定義
+# 
+#  固定ベクタテーブルのベクタテーブルアドレスの小さい順番に例外番号を割振る．
+#  (予約領域も含む)
+# 
+
+$EXCNO_VALID = [ 20, 23, 25, 30 ]
+
+# 
+#  INT割込みの番号
+# 
+
+$INTNO_INT = [ *(64..79) ]
+
+# 
+#  割込み番号，割込みハンドラ番号，例外番号の範囲
+# 
+# (予約領域も含む)
+# 
+
+$INTNO_RANGE = [ *(0..255) ]
+$INHNO_RANGE = $INTNO_RANGE
+$EXCNO_RANGE = [ *(0..31)  ]
+
+# 
+#  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で使用できる割込み番号と割込み優先度
+# 
+
+$INTNO_CFGINT_VALID = $INHNO_VALID
+$INTPRI_CFGINT_VALID = [ *(-7..-1) ]
+
+
+# 
+#  ターゲット非依存部に含まれる標準の割込み管理機能/例外管理機能の初期化処理を使用する
+# 
+
+$OMIT_INITIALIZE_INTERRUPT = false
+$OMIT_INITIALIZE_EXCEPTION = false
+
+
+# 
+#  スタックサイズのチェック方法指定
+# 
+
+$CHECK_STKSZ_ALIGN = 4
+
+
+# 
+#  タスクスタックサイズの最小値
+# 
+#  タスク起動時に4byte,
+#  割込み入口処理にて48byte, CPU例外入口処理にて84byte,
+#  であるため, 最小値は88byteとする.
+# 
+
+$TARGET_MIN_STKSZ = 88
+
+# 
+#  定数定義
+# 
+
+$TA_POSEDGE = $TA_EDGE
+
+#
+#  ターゲット定義の割込み要求ライン属性
+#
+$TARGET_INTATR = $TA_POSEDGE|$TA_NEGEDGE|$TA_BOTHEDGE|$TA_LOWLEVEL
+
+# 
+# ターゲット依存の割込みハンドラ属性の定義
+# 
+
+$TARGET_INHATR = $TA_NONKERNEL
+
+
+# 
+# カーネル管理外割込みハンドラは固定させないため,
+# INTNO_FIX_KERNEL
+# INHNO_FIX_KERNEL
+# INHNO_FIX_NONKERNEL
+# INHNO_FIX_NONKERNEL
+# を定義しない.
+# 
+
+$USE_INHINIB_TABLE = true
+$USE_INTINIB_TABLE = true
+
+#
+#  標準テンプレートファイルのインクルード
+#
+IncludeTrb("kernel/kernel.trb")
+
+#
+#  割込み番号から割込み優先度及び属性を取り出すテーブル
+#
+$kernelCfgC.comment_header("Interrupt Level and Attribute Table")
+
+$kernelCfgC.add("const CFG_INT_INFO _kernel_cfg_int_table[#{$INTNO_RANGE.length}] = {")
+$INTNO_RANGE.each do |intnoVal|
+  if $cfgData[:CFG_INT].has_key?(intnoVal)
+    $kernelCfgC.append("\t{ #{-$cfgData[:CFG_INT][intnoVal][:intpri].val}, #{$cfgData[:CFG_INT][intnoVal][:intatr]} }")
+  else
+    $kernelCfgC.append("\t{  0, 0xFFFFFFFF }")
+  end
+  $kernelCfgC.append(",") if intnoVal < ($INTNO_RANGE.length - 1)
+  $kernelCfgC.add("\t/* #{sprintf("%02u", intnoVal)} */ ")
+end
+$kernelCfgC.add2("};")
+
+$kernelCfgAsm = GenFile.new("kernel_cfg_asm.S")
+
+#
+#  割込みベクタ及び割込みハンドラ定義
+#
+$kernelCfgAsm.add(<<EOS)
+;
+;  RX630アーキテクチャ依存出力ファイル
+;
+;  割込みベクタ及び割込みハンドラ定義
+;
+
+
+	.section P, CODE
+	.global	_kernel_interrupt
+	.global	__kernel_default_int_handler
+	.global	__kernel_default_exc_handler
+EOS
+
+$INHNO_RANGE.each do |inhnoVal|
+  if $cfgData[:DEF_INH].has_key?(inhnoVal)
+    $kernelCfgAsm.add(<<EOS)
+	.global	_#{$cfgData[:DEF_INH][inhnoVal][:inthdr]}
+	.global	__kernel_#{$cfgData[:DEF_INH][inhnoVal][:inthdr]}_#{inhnoVal}_entry
+__kernel_#{$cfgData[:DEF_INH][inhnoVal][:inthdr]}_#{inhnoVal}_entry:
+	pushm	r1-r5
+	mov.l	\##{inhnoVal}, r1
+	mov.l	\#_#{$cfgData[:DEF_INH][inhnoVal][:inthdr]}, r2
+	bra.a	_kernel_interrupt
+EOS
+    $kernelCfgAsm.add
+  end
+end
+
+$kernelCfgAsm.add(<<EOS)
+	.global	__kernel_default_int_handler_entry
+__kernel_default_int_handler_entry:
+	pushm	r1-r5
+	mov.l	\#0FFFFFFFFH, r1
+	mov.l	\#__kernel_default_int_handler, r2
+	bra.a	_kernel_interrupt
+
+	.global	__kernel_break_int_handler_entry
+__kernel_break_int_handler_entry:
+	rts
+EOS
+$kernelCfgAsm.add
+
+$kernelCfgAsm.add(<<EOS)
+	.global	_kernel_exception
+EOS
+
+$EXCNO_VALID.each do |excnoVal|
+  if $cfgData[:DEF_EXC].has_key?(excnoVal)
+    $kernelCfgAsm.add(<<EOS)
+	.global	_#{$cfgData[:DEF_EXC][excnoVal][:exchdr]}
+	.global	__kernel_#{$cfgData[:DEF_EXC][excnoVal][:exchdr]}_#{excnoVal}_entry
+__kernel_#{$cfgData[:DEF_EXC][excnoVal][:exchdr]}_#{excnoVal}_entry:
+	pushm	r1-r5
+	mov.l	\##{excnoVal}, r1
+	mov.l	\#_#{$cfgData[:DEF_EXC][excnoVal][:exchdr]}, r2
+	bra.a	_kernel_exception
+EOS
+    $kernelCfgAsm.add
+  end
+end
+
+$kernelCfgAsm.add(<<EOS)
+	.global	__kernel_default_exc_handler_entry
+__kernel_default_exc_handler_entry:
+	pushm	r1-r5
+	mov.l	\#0FFFFFFFFH, r1
+	mov.l	\#__kernel_default_exc_handler, r2
+	bra.a	_kernel_exception
+EOS
+$kernelCfgAsm.add
+
+$kernelCfgAsm.append(<<EOS)
+;
+;  可変ベクタテーブル
+;
+
+	.global	_start
+
+	.global	_vvector_table
+
+
+	.section .rvectors, ROMDATA
+
+_vvector_table:
+EOS
+
+$INHNO_RANGE.each do |inhnoVal|
+  if $cfgData[:DEF_INH].has_key?(inhnoVal)
+    $kernelCfgAsm.append("	.lword	__kernel_#{$cfgData[:DEF_INH][inhnoVal][:inthdr]}_#{inhnoVal}_entry")
+  elsif inhnoVal != 0
+    $kernelCfgAsm.append("	.lword	__kernel_default_int_handler_entry")
+  else
+    $kernelCfgAsm.append("	.lword	__kernel_break_int_handler_entry")
+  end
+  $kernelCfgAsm.add("		; #{sprintf("%02d", inhnoVal)} ")
+end
+
+$kernelCfgAsm.add2
+
+$kernelCfgAsm.append(<<EOS)
+;
+;  固定ベクタテーブル
+;
+
+	.global	_fvector_table
+
+	.section .fvectors, ROMDATA
+
+_fvector_table:
+	 .word	 0FFFFFFFFH 	 ; Endian Select Register (little)
+	 .space	 004H
+	 .word	 0FFFFFFFFH 	 ; OFS1
+	 .word	 0FFFFFFFFH 	 ; OFS0
+	 .space	 010H
+	 .word	 0FFFFFFFFH 	 ; 制御コード, IDコード1 - 3
+	 .word	 0FFFFFFFFH 	 ; IDコード4 - 7
+	 .word	 0FFFFFFFFH 	 ; IDコード8 - 11
+	 .word	 0FFFFFFFFH 	 ; IDコード12 - 15
+EOS
+(12..30).each do |excnoVal|
+  if $cfgData[:DEF_EXC].has_key?(excnoVal)
+    $kernelCfgAsm.append("	.word	 __kernel_#{$cfgData[:DEF_EXC][excnoVal][:exchdr]}_#{excnoVal}_entry")
+  elsif $EXCNO_VALID.include?(excnoVal)
+    $kernelCfgAsm.append("	.word	 __kernel_default_exc_handler_entry")
+  else
+    $kernelCfgAsm.append("	.word	 0")
+  end
+  $kernelCfgAsm.add("		; #{excnoVal} ")
+end
+
+$kernelCfgAsm.add("	.word	 _start		; 31:Reset")
+$kernelCfgAsm.add2(".end")
+
+#
+#  割込み要求ライン属性に関するターゲット依存のエラーチェック
+#
+$cfgData[:CFG_INT].each do |key, params|
+  # IRQ割込み番号かどうかをチェック
+  if $INTNO_INT.include?(key)
+    # TA_POSEDGEとTA_NEGEDGEが同時に設定されている場合
+    if (params[:intatr].val & ($TA_POSEDGE|$TA_NEGEDGE)) == $TA_POSEDGE|$TA_NEGEDGE
+      error_illegal_sym("E_RSATR", params, :intatr, :intno)
+    end
+    # TA_POSEDGEとTA_BOTHEDGEが同時に設定されている場合
+    if (params[:intatr].val & ($TA_POSEDGE|$TA_BOTHEDGE)) == $TA_POSEDGE|$TA_BOTHEDGE
+      error_illegal_sym("E_RSATR", params, :intatr, :intno)
+    end
+    # TA_NEGEDGEとTA_BOTHEDGEが同時に設定されている場合
+    if (params[:intatr].val & ($TA_NEGEDGE|$TA_BOTHEDGE)) == $TA_NEGEDGE|$TA_BOTHEDGE
+      error_illegal_sym("E_RSATR", params, :intatr, :intno)
+    end
+    # TA_POSEDGEとTA_NEGEDGEとTA_BOTHEDGEが同時に設定されている場合
+    if (params[:intatr].val & ($TA_POSEDGE|$TA_NEGEDGE|$TA_BOTHEDGE)) == $TA_POSEDGE|$TA_NEGEDGE|$TA_BOTHEDGE
+      error_illegal_sym("E_RSATR", params, :intatr, :intno)
+    end
+  else
+    # IRQ割込み以外の割込みに対して割込み属性が指定されている場合
+    if (params[:intatr].val & (~($TA_ENAINT|$TA_EDGE))) != 0
+      error_illegal_sym("E_RSATR", params, :intatr, :intno)
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel_impl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel_impl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel_impl.c	(revision 398)
@@ -0,0 +1,237 @@
+/*
+ *  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,2006 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		プロセッサ依存モジュール（RX630用）
+ */
+
+#include "kernel_impl.h"
+#include "sil.h"
+
+
+/*
+ *  割込み発生回数を保存する変数
+ */
+uint16_t	intnest;
+
+/*
+ *  CPUロックフラグ実現のための変数
+ */
+#if TIPM_LOCK != -15
+bool_t		lock_flag;		/* CPUロックフラグの値を保持する変数 */
+uint32_t	saved_ipl;		/* 割込み優先度レベルを保存する変数 */
+#endif	/* TIPM_LOCK != -15	*/
+
+
+/*
+ *  プロセッサ依存の初期化
+ */
+void
+prc_initialize( void )
+{
+	/*
+	 *  割込み発生回数の初期化
+	 *
+	 *  スタートアップは全割込みロック状態 & 非タスクコンテキスト
+	 *  にて動作するため, 非タスクコンテキストに偽装する.
+	 */
+	intnest = 1U;
+
+#if TIPM_LOCK != -15
+	/*
+	 *  CPUロックフラグ実現のための変数の初期化
+	 */
+	lock_flag = true;
+	saved_ipl = IPL_ENAALL;
+#endif	/* TIPM_LOCK != -15	*/
+}
+
+
+/*
+ *  プロセッサ依存の終了処理
+ */
+void
+prc_terminate( void )
+{
+	/*
+	 *  特に必要な処理はない
+	 */
+}
+
+
+/*
+ *  CPU例外の発生状況のログ出力
+ *
+ *  CPU例外ハンドラの中から，CPU例外情報ポインタ（p_excinf）を引数とし
+ *  て呼び出すことで，CPU例外の発生状況をシステムログに出力する．
+ */
+#ifdef SUPPORT_XLOG_SYS
+void
+xlog_sys( void *p_excinf )
+{
+	syslog(LOG_ERROR , "r1 = %u") , *((uint32_t*)((intptr_t)p_excinf + 14));
+	syslog(LOG_ERROR , "r2 = %u") , *((uint32_t*)((intptr_t)p_excinf + 15));
+	syslog(LOG_ERROR , "r3 = %u") , *((uint32_t*)((intptr_t)p_excinf + 16));
+	syslog(LOG_ERROR , "r4 = %u") , *((uint32_t*)((intptr_t)p_excinf + 17));
+	syslog(LOG_ERROR , "r5 = %u") , *((uint32_t*)((intptr_t)p_excinf + 18));
+	syslog(LOG_ERROR , "r6 = %u") , *((uint32_t*)((intptr_t)p_excinf + 1));
+	syslog(LOG_ERROR , "r7 = %u") , *((uint32_t*)((intptr_t)p_excinf + 2));
+	syslog(LOG_ERROR , "r8 = %u") , *((uint32_t*)((intptr_t)p_excinf + 3));
+	syslog(LOG_ERROR , "r9 = %u") , *((uint32_t*)((intptr_t)p_excinf + 4));
+	syslog(LOG_ERROR , "r10 = %u") , *((uint32_t*)((intptr_t)p_excinf + 5));
+	syslog(LOG_ERROR , "r11 = %u") , *((uint32_t*)((intptr_t)p_excinf + 6));
+	syslog(LOG_ERROR , "r12 = %u") , *((uint32_t*)((intptr_t)p_excinf + 7));
+	syslog(LOG_ERROR , "r13 = %u") , *((uint32_t*)((intptr_t)p_excinf + 8));
+	syslog(LOG_ERROR , "r14 = %u") , *((uint32_t*)((intptr_t)p_excinf + 12));
+	syslog(LOG_ERROR , "r15 = %u") , *((uint32_t*)((intptr_t)p_excinf + 13));
+	syslog(LOG_ERROR , "fpsw = %u") , *((uint32_t*)((intptr_t)p_excinf + 11));
+	syslog(LOG_ERROR , "acclo = %u") , *((uint32_t*)((intptr_t)p_excinf + 10));
+	syslog(LOG_ERROR , "acchi = %u") , *((uint32_t*)((intptr_t)p_excinf + 9));
+	syslog(LOG_ERROR , "pc = %x") , *((uint32_t*)((intptr_t)p_excinf + 19));
+	syslog(LOG_ERROR , "psw = %x") , *((uint32_t*)((intptr_t)p_excinf + 20));
+}
+#endif /* SUPPORT_XLOG_SYS */
+
+
+/*
+ *  割込み要求ラインの属性の設定
+ *
+ *  ASPカーネルでの利用を想定して，パラメータエラーはアサーションでチェッ
+ *  クしている．cfg_intサービスコールを設ける場合には，エラーを返すよう
+ *  にすべきであろう．
+ */
+void
+config_int( INTNO intno, ATR intatr, PRI intpri )
+{
+	uint8_t		irq_offset;
+	uint8_t		irq_val;
+
+	assert( VALID_INTNO_CFGINT(intno) );
+
+	assert( ( -15 <= intpri ) && ( intpri <= TMAX_INTPRI ) );
+#if TIPM_LOCK != -15
+	if( intatr == TA_NONKERNEL ){
+		assert( intpri < TMIN_INTPRI );
+ 	}
+	else{
+		assert( TMIN_INTPRI <= intpri ); 
+	}
+#endif
+
+	/*
+	 *  割込みのマスク
+	 *
+	 *  割込みを受け付けたまま，レベルトリガ／エッジトリガの設定や，割
+	 *  込み優先度の設定を行うのは危険なため，割込み属性にかかわらず，
+	 *  一旦マスクする．
+	 */
+	( void )disable_int( intno );
+
+	/*
+	 *  レベルトリガ/エッジトリガの設定
+	 *
+	 *  IRQのみサポートする
+	 */
+	if( INTNO_IRQ( intno ) != 0U ){
+		irq_offset = INTNO_IRQ_OFFSET( intno );
+
+		if( ( intatr & TA_POSEDGE ) != 0U ){
+			irq_val = IRQ_POSEDGE;
+		}
+		else if( ( intatr & TA_NEGEDGE ) != 0U ){
+			irq_val = IRQ_NEGEDGE;
+		}
+		else if( ( intatr & TA_BOTHEDGE ) != 0U ){
+			irq_val = IRQ_BOTHEDGE;
+		}
+		else if( ( intatr & TA_LOWLEVEL ) != 0U ){
+			irq_val = IRQ_LOWLEVEL;
+		}
+		else{
+			/*
+			 *  コンフィギュレータにてチェックしているため,
+			 *  ここへくることはありえない.
+			 */
+			irq_val = 0U;
+		}
+
+		sil_wrb_mem(irqcr_reg_addr[irq_offset], irq_val);
+	}
+
+	/*
+	 *  割込みレベルの設定
+	 *
+	 *  割込み番号に対応したIPR値を設定する.
+	 */
+	sil_wrb_mem(ipr_reg_addr[intno], cfg_int_table[intno].intpri);
+
+	/*
+	 *  割込みのマスク解除
+ 	 */
+	if( ( intatr & TA_ENAINT ) != 0U ){
+		( void )enable_int( intno );
+	}
+}
+
+
+#ifndef OMIT_DEFAULT_INT_HANDLER
+/*
+ *  未登録の割込みが発生した場合に呼び出される
+ */
+void
+default_int_handler( void )
+{
+	syslog(LOG_EMERG, "Unregistered Interrupt occurs.");
+}
+#endif /* OMIT_DEFAULT_INT_HANDLER */
+
+#ifndef OMIT_DEFAULT_EXC_HANDLER
+/*
+ *  未登録の例外が発生した場合に呼び出される
+ */
+void
+default_exc_handler( void )
+{
+	syslog(LOG_EMERG, "Unregistered Expevt error occurs.");
+}
+#endif /* OMIT_DEFAULT_EXC_HANDLER */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel_impl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel_impl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel_impl.h	(revision 398)
@@ -0,0 +1,697 @@
+/*
+ *  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,2006 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ *  Copyright (C) 2013      by Mitsuhiro Matsuura
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		プロセッサ依存モジュール（RX630用）
+ *
+ *  このインクルードファイルは，target_kernel_impl.h（または，そこからインク
+ *  ルードされるファイル）のみからインクルードされる．他のファイルから
+ *  直接インクルードしてはならない．
+ */
+
+#ifndef TOPPERS_PRC_CONFIG_H
+#define TOPPERS_PRC_CONFIG_H
+
+/*
+ *  プロセッサの特殊命令のインライン関数定義
+ */
+#include "prc_insn.h"
+#include "sil.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  非タスクコンテキスト用のスタック初期値
+ */
+
+#define TOPPERS_ISTKPT( istk, istksz ) (( STK_T * )(( char * )( istk ) + ( istksz )))
+
+/*
+ *  タスクコンテキストブロックの定義
+ */
+typedef struct task_context_block {
+	void	*sp;		/* スタックポインタ */
+	FP		pc;			/* プログラムカウンタ */
+} TSKCTXB;
+
+
+/*
+ *  割込み発生回数を保存する変数
+ */
+extern uint16_t intnest;
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  CPUロック状態での割込み優先度マスク
+ *
+ *  TIPM_LOCKは，CPUロック状態での割込み優先度マスク，すなわち，カーネ
+ *  ル管理外のものを除くすべての割込み要求をマスクする値に定義する．
+ *
+ *  TMIN_INTPRI変更することで管理外割込みの有無を決定する．
+ *  例えばTMIN_INTPRIを-14に設定すると，レベル15の割込みがカーネル管理外と
+ *  なる．TMIN_INTPRIを-15に設定すると，NMI以外にカーネル管理外の割込みを
+ *  設けないことになる（この場合には-15に設定することを推奨する）．
+ */
+#ifndef TIPM_LOCK
+#define TIPM_LOCK	TMIN_INTPRI
+#endif /* TIPM_LOCK */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  TOPPERS標準割込み処理モデルの実現
+ */
+/*
+ *  コンテキストの参照
+ *
+ *  RXでは，割込みの戻り先がタスクかどうかを判断するために intnest
+ *  を使用している．これを用いてコンテキストを判断する．
+ */
+Inline bool_t
+sense_context( void )
+{
+	/*  ネストカウンタ0より大なら非タスクコンテキスト  */
+	return ( intnest > 0U );
+}
+
+
+/*
+ *  CPUロックフラグ実現のための変数
+ *
+ *  これらの変数は，CPUロック状態の時のみ書き換えてよいものとする．
+ */
+#if TIPM_LOCK != -15
+extern bool_t	lock_flag;		/* CPUロックフラグの値を保持する変数 */
+extern uint32_t	saved_ipl;		/* 割込み優先度レベルを保存する変数 */
+#endif	/* TIPM_LOCK != -15	*/
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+
+/*
+ *  割込み優先度マスクの外部表現と内部表現の変換
+ *
+ *  RX630では，プロセッサステータスワードレジスタ（PSW）の下から
+ *  24～27ビット目の4ビットに割込み優先度レベル（IPL）が置かれている．
+ *  カーネル管理外割込みを実装する場合にIPLを使用した制御を行う．
+ *  カーネルは割込み優先度マスク（-1から連続した負の値）で管理されて
+ *  いるためIPLとの変換が必要となる．
+ */
+#define IPL_TO_IPM( ipl )	(-(( PRI )(( ipl ) >> 24U )))		/* IPLをIPMに	*/
+#define IPM_TO_IPL( ipm )	((( uint32_t )(-( ipm ))) << 24U )	/* IPMをIPLに	*/
+
+
+/*
+ *  CPUロック状態での割込み優先度マスクのIPL
+ */
+#define IPL_LOCK		( IPM_TO_IPL( TIPM_LOCK ) )
+
+/*
+ *  TIPM_ENAALL（割込み優先度マスク全解除）のIPL
+ */
+#define IPL_ENAALL		( IPM_TO_IPL( TIPM_ENAALL ) )
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  割込み要因毎のレベル & 属性定義テーブル
+ *  (テンプレートファイルによる出力)
+ */
+typedef struct cfg_int_info {
+	PRI		intpri;
+	ATR		intatr;
+} CFG_INT_INFO;
+
+extern const CFG_INT_INFO cfg_int_table[];
+
+
+/*
+ *  割込み番号の範囲の判定
+ *
+ *  割込み番号が有効な値か厳密にチェックするため,
+ *  コンフィギュレータ出力テーブルを参照する.
+ */
+#define VALID_INTNO( intno )	\
+ 				( cfg_int_table[( intno )].intpri > 0 )
+#define VALID_INTNO_DISINT( intno )	VALID_INTNO( intno )
+#define VALID_INTNO_CFGINT( intno )	VALID_INTNO( intno )
+
+/* cre_intで有効な割込み番号の指定  */
+#define VALID_INTNO_CREINT          VALID_INTNO_CFGINT((intno))
+
+/* cre_isrで有効な割込み番号の指定  */
+#define	VALID_INTNO_CREISR(intno)	VALID_INTNO_CFGINT((intno))
+
+
+/*
+ *  割込み制御レジスタ関連の定義
+ */
+#define	IRQ_POSEDGE			( 0x08U )
+#define	IRQ_NEGEDGE			( 0x04U )
+#define	IRQ_BOTHEDGE		( 0x0CU )
+#define	IRQ_LOWLEVEL		( 0x00U )
+
+
+/*
+ *  CPUロック状態への移行
+ *
+ *  IPM（ハードウェアの割込み優先度マスク）を，saved_iipmに保存し，カー
+ *  ネル管理外のものを除くすべての割込み要求をマスクする値（TIPM_LOCK）
+ *  に設定する．また，lock_flagをTRUEにする．
+ *
+ *  IPMが，最初からTIPM_LOCKと同じかそれより高い場合には，それを
+ *  saved_iipmに保存するのみで，TIPM_LOCKには設定しない．これは，モデル
+ *  上の割込み優先度マスクが，TIPM_LOCKと同じかそれより高いレベルに設定
+ *  されている状態にあたる．
+ *
+ *  この関数は，CPUロック状態（lock_flagがTRUEの状態）で呼ばれることは
+ *  ないものと想定している．
+ */
+Inline void
+lock_cpu( void )
+{
+#if TIPM_LOCK == -15
+	disint();
+#else	/* TIPM_LOCK == -15	*/
+	uint32_t	ipl;
+
+	/*
+	 *  current_ipl()の返り値を直接saved_iplに保存せず，一時変数ipl
+	 *  を用いているのは，current_ipl()を呼んだ直後に割込みが発生し，
+	 *  起動された割込み処理でsaved_iplが変更される可能性があるためで
+	 *  ある．
+	 */
+	ipl = current_ipl();
+	if( IPL_LOCK > ipl ){
+		set_ipl( IPL_LOCK );
+	}
+
+	saved_ipl = ipl;
+	lock_flag = true;
+#endif	/* TIPM_LOCK == -15	*/
+}
+
+#define lock_cpu_dsp()	lock_cpu()
+
+/*
+ *  CPUロック状態の解除
+ *
+ *  lock_flagをFALSEにし，IPM（ハードウェアの割込み優先度マスク）を，
+ *  saved_iipmに保存した値に戻す．
+ *
+ *  この関数は，CPUロック状態（lock_flagがtrueの状態）でのみ呼ばれるも
+ *  のと想定している．
+ */
+Inline void
+unlock_cpu( void )
+{
+#if TIPM_LOCK == -15
+	enaint();
+#else	/* TIPM_LOCK == -15	*/
+	lock_flag = false;
+	set_ipl( saved_ipl );
+#endif	/* TIPM_LOCK == -15	*/
+}
+
+#define unlock_cpu_dsp()	unlock_cpu()
+
+/*
+ *  CPUロック状態の参照
+ */
+Inline bool_t
+sense_lock( void )
+{
+#if TIPM_LOCK == -15
+	return (( bool_t )(( current_psw() & PSW_I_MASK) == 0 ));
+#else	/* TIPM_LOCK == -15	*/
+	return lock_flag;
+#endif	/* TIPM_LOCK == -15	*/
+}
+
+
+/*
+ *  割込み属性の設定のチェック
+ */
+Inline bool_t
+check_intno_cfg(INTNO intno)
+{
+	return(cfg_int_table[intno].intpri != 0U);
+}
+
+/*
+ * （モデル上の）割込み優先度マスクの設定
+ *
+ *  CPUロックフラグがクリアされている時は，ハードウェアの割込み優先度マ
+ *  スクを設定する．CPUロックフラグがセットされている時は，saved_iipm
+ *  を設定し，さらに，ハードウェアの割込み優先度マスクを，設定しようと
+ *  した（モデル上の）割込み優先度マスクとTIPM_LOCKの高い方に設定する．
+ */
+Inline void
+t_set_ipm( PRI intpri )
+{
+	uint32_t	ipl = IPM_TO_IPL( intpri );
+#if TIPM_LOCK == -15
+	set_ipl(ipl);
+#else	/* TIPM_LOCK == -15	*/
+	if( !lock_flag ){
+		set_ipl(ipl);
+	}
+	else {
+		saved_ipl = ipl;
+		set_ipl(ipl > IPL_LOCK ? ipl : IPL_LOCK);
+    }
+#endif	/* TIPM_LOCK == -15	*/
+}
+
+
+
+/*
+ * （モデル上の）割込み優先度マスクの参照
+ *
+ *  CPUロックフラグがクリアされている時はハードウェアの割込み優先度マ
+ *  スクを，セットされている時はsaved_iipmを参照する．
+ */
+Inline PRI
+t_get_ipm( void )
+{
+	uint32_t	ipl;
+#if TIPM_LOCK == -15
+	ipl = current_ipl();
+#else	/* TIPM_LOCK == -15	*/
+	if (!lock_flag) {
+		ipl = current_ipl();
+	}
+	else {
+		ipl = saved_ipl;
+	}
+#endif	/* TIPM_LOCK == -15	*/
+	return IPL_TO_IPM( ipl );
+}
+
+
+
+/*
+ *  割込み要求禁止フラグのセット
+ *
+ *  割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
+ *  フラグをセットしようとした場合には，FALSEを返す．
+ */
+Inline bool_t
+disable_int( INTNO intno )
+{
+	/*
+	 *  レベル定義が0である場合はCFG_INTされていない
+	 */
+	if( cfg_int_table[intno].intpri == 0 ){
+		return ( false );
+	}
+
+	sil_wrb_mem(ier_reg_addr[intno].addr,
+		sil_reb_mem(ier_reg_addr[intno].addr) & ~ier_reg_addr[intno].offset);
+
+	return ( true );
+}
+
+
+/*
+ *  割込み要求禁止フラグのクリア
+ *
+ *  割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
+ *  フラグをクリアしようとした場合には，FALSEを返す．
+ */
+Inline bool_t
+enable_int( INTNO intno )
+{
+	/*
+	 *  レベル定義が0である場合はCFG_INTされていない
+	 */
+	if( cfg_int_table[intno].intpri == 0 ){
+		return ( false );
+	}
+
+	sil_wrb_mem(ier_reg_addr[intno].addr,
+		sil_reb_mem(ier_reg_addr[intno].addr) | ier_reg_addr[intno].offset);
+
+	return ( true );
+}
+
+
+/*
+ *  割込み要求がクリアできる状態か？
+ */
+Inline bool_t
+check_intno_clear(INTNO intno)
+{
+	return(true);
+}
+
+/*
+ *  割込み要求のクリア
+ */
+Inline void
+clear_int( INTNO intno )
+{
+	sil_wrb_mem(IR_REG(intno), 0U);
+}
+
+
+/*
+ *  割込みが要求できる状態か？
+ */
+Inline bool_t
+check_intno_raise(INTNO intno)
+{
+	return(true);
+}
+
+/*
+ * 割込みの要求
+ * 注意：チップでサポートされていない操作
+ */
+Inline void
+raise_int( INTNO intno )
+{
+	*IR_REG(intno) = 1U;
+}
+
+/*
+ *  割込み要求のチェック
+ */
+Inline bool_t
+probe_int( INTNO intno )
+{
+	/*
+	 *  割込み要求レジスタは0 or 1でしかないため,
+	 *  そのままの値を返す.
+	 */
+	return sil_reb_mem(IR_REG(intno));
+}
+
+/*
+ *  割込み要求ラインの属性の設定
+ */
+extern void	config_int( INTNO intno, ATR intatr, PRI intpri );
+
+/*
+ *  割込みを受け付けるための遅延処理
+ */
+Inline void
+delay_for_interrupt(void)
+{
+}
+
+/*
+ *  最高優先順位タスクへのディスパッチ（prc_support.a30）
+ *
+ *  dispatchは，タスクコンテキストから呼び出されたサービスコール処理か
+ *  ら呼び出すべきもので，タスクコンテキスト・CPUロック状態・ディスパッ
+ *  チ許可状態・（モデル上の）割込み優先度マスク全解除状態で呼び出さな
+ *  ければならない．
+ */
+extern void	dispatch( void );
+
+/*
+ *  非タスクコンテキストからのディスパッチ要求
+ */
+#define request_dispatch()
+
+/*
+ *  ディスパッチャの動作開始（prc_support.a30）
+ *
+ *  start_dispatchは，カーネル起動時に呼び出すべきもので，すべての割込
+ *  みを禁止した状態（全割込みロック状態と同等の状態）で呼び出さなければ
+ *  ならない．
+ */
+extern void	start_dispatch( void ) NoReturn;
+
+/*
+ *  現在のコンテキストを捨ててディスパッチ（prc_support.a30）
+ *
+ *  exit_and_dispatchは，ext_tskから呼び出すべきもので，タスクコンテキ
+ *  スト・CPUロック状態・ディスパッチ許可状態・（モデル上の）割込み優先
+ *  度マスク全解除状態で呼び出さなければならない．
+ */
+#define _kernel_exit_and_dispatch();	\
+	_exit_and_dispatch();		\
+	ercd = E_SYS;
+
+extern void	_exit_and_dispatch( void ) NoReturn;
+
+/*
+ *  カーネルの終了処理の呼出し（prc_support.a30）
+ *
+ *  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 * )((( uint32_t ) ( p_tcb )->p_tinib->stk ) + 	\
+								( p_tcb )->p_tinib->stksz );							\
+		/* 起動番地の設定 */															\
+		( p_tcb )->tskctxb.pc = ( FP ) start_r;											\
+	}																					\
+}
+
+
+/*
+ *  calltexは使用しない
+ */
+#define OMIT_CALLTEX
+
+
+/*
+ *  割込みハンドラの設定
+ *
+ *  RX630はROMに割込みベクタを配置するため，本関数は空関数で実装する．
+ */
+Inline void
+define_inh( INHNO inhno, FP inthdr )
+{
+}
+
+/*
+ *  CPU例外ハンドラの設定
+ *
+ *  RX630はROMに例外ベクタを配置するため，本関数は空関数で実装する．
+ */
+Inline void
+define_exc( EXCNO excno, FP exchdr )
+{
+}
+
+/*
+ *  割込み/例外ハンドラの入口処理の生成マクロ
+ *
+ *  テンプレートファイルにより生成するため空マクロとする．
+ */
+#define HDR_ENTRY(hdr, intexc_num , tobejmp)
+
+/*
+ *  割込みハンドラの入口処理の生成マクロ
+ */
+#define _INT_ENTRY(inhno, inthdr)				_kernel_##inthdr##_##inhno##_entry
+#define INT_ENTRY(inhno, inthdr)				_INT_ENTRY(inhno , inthdr)
+
+#define _INTHDR_ENTRY(inhno, inhno_num ,inthdr)	\
+		extern void _kernel_##inthdr##_##inhno##_entry(void);
+#define INTHDR_ENTRY(inhno, inhno_num ,inthdr)	_INTHDR_ENTRY(inhno, inhno_num ,inthdr)
+
+
+/*
+ *  CPU例外ハンドラの入口処理の生成マクロ
+ */
+#define _EXC_ENTRY(excno , exchdr)					_kernel_##exchdr##_##excno##_entry
+#define EXC_ENTRY(excno , exchdr)					_EXC_ENTRY(excno , exchdr)
+
+#define _EXCHDR_ENTRY(excno , excno_num , exchdr)	\
+		extern void _kernel_##exchdr##_##excno##_entry(void);
+#define EXCHDR_ENTRY(excno , excno_num , exchdr)	_EXCHDR_ENTRY(excno , excno_num , exchdr)
+
+
+/*
+ *  CPU例外の発生した時のコンテキストの参照
+ *
+ *  CPU例外の発生した時のコンテキストが，タスクコンテキストの時にFALSE，
+ *  そうでない時にtrueを返す．
+ */
+Inline bool_t
+exc_sense_context( void *p_excinf )
+{
+	/* 
+	 *  ネストカウンタが1より大なら非タスクコンテキスト
+	 */
+	return( intnest > 1U );
+}
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  CPU例外情報 p_excinf から PSW の値を取得するためのオフセット値
+ *  EXCNO + ACC + FPSW + R1～R15 + PC
+ */
+#define EXC_GET_PSW_OFFSET	(4+8+4+60+4)
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  CPU例外の発生した時のIPLの参照
+ */
+Inline uint32_t
+exc_get_ipl(void *p_excinf)
+{
+	return((*((uint32_t *)((uintptr_t)p_excinf+EXC_GET_PSW_OFFSET)))
+			& PSW_IPL_MASK);
+}
+
+Inline bool_t
+exc_sense_i(void *p_excinf)
+{
+	return((*(((uint32_t *)((uintptr_t)p_excinf+EXC_GET_PSW_OFFSET)))
+			 & PSW_I_MASK) != 0u);
+}
+
+
+/*
+ *  CPU例外の発生した時のコンテキストと割込みのマスク状態の参照
+ *
+ *  CPU例外の発生した時のシステム状態が，カーネル実行中でなく，タスクコ
+ *  ンテキストであり，全割込みロック状態でなく，CPUロック状態でなく，（モ
+ *  デル上の）割込み優先度マスク全解除状態である時にtrue，そうでない時
+ *  にFALSEを返す（CPU例外がカーネル管理外の割込み処理中で発生した場合
+ *  にもFALSEを返す）．
+ *  
+ *  カーネル実行中でない→ (TIPM_LOCK== -15) Iフラグ == 1
+ *                         (else)           IPL < IPL_LOCK
+ *  タスクコンテキストである→intnest == 0
+ *  全割込みロックでない→ Iフラグ == 1
+ *  割込み優先度マスクが全解除→IPL == 0
+ *  
+ *  
+ */
+Inline bool_t
+exc_sense_intmask(void *p_excinf)
+{
+	return((!exc_sense_context(p_excinf))
+			&& exc_sense_i(p_excinf)
+			&& (exc_get_ipl(p_excinf) == IPL_ENAALL));
+}
+
+/*
+ *  CPU例外の発生した時のコンテキストと割込み／CPUロック状態の参照
+ *
+ *  CPU例外の発生した時のシステム状態が，カーネル実行中でなく，タスクコ
+ *  ンテキストであり，全割込みロック状態でなく，CPUロック状態でない時に
+ *  true，そうでない時にfalseを返す（CPU例外がカーネル管理外の割込み処
+ *  理中で発生した場合にもfalseを返す）．
+ *  
+ *  カーネル実行中でない→ (TIPM_LOCK== -15) Iフラグ == 1
+ *                         (else)           IPL < TIPM_LOCK
+ *  タスクコンテキストである→intnest < 1 
+ *  全割込みロックでない→ Iフラグ == 1
+ *  CPUロック状態でない→(TIPM_LOCK== -15) Iフラグ == 1
+ *                         (else)           IPL < TIPM_LOCK
+ */
+Inline bool_t
+exc_sense_unlock(void *p_excinf)
+{
+#if TIPM_LOCK == -15
+	return((!exc_sense_context(p_excinf))
+			&& exc_sense_i(p_excinf));
+#else
+	return((!exc_sense_context(p_excinf))
+			&& exc_sense_i(p_excinf)
+			&& exc_get_ipl(p_excinf) < IPL_LOCK);
+#endif
+}
+
+
+/*
+ *  プロセッサ依存の初期化
+ */
+extern void	prc_initialize( void );
+
+/*
+ *  プロセッサ依存の終了時処理
+ */
+extern void	prc_terminate( void );
+
+
+#ifndef OMIT_DEFAULT_INT_HANDLER
+/*
+ *  未登録の割込みが発生した場合に呼び出される
+ */
+void default_int_handler( void );
+#endif /* OMIT_DEFAULT_INT_HANDLER */
+
+#ifndef OMIT_DEFAULT_EXC_HANDLER
+/*
+ *  未登録の例外が発生した場合に呼び出される
+ */
+void default_exc_handler( void );
+#endif /* OMIT_DEFAULT_EXC_HANDLER */
+
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_PRC_CONFIG_H */
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_offset.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_offset.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_offset.trb	(revision 398)
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+#		オフセットファイル生成用Rubyテンプレート（ARM用）
+#
+#  $Id$
+#
+
+#
+#  ターゲット非依存部のインクルード
+#
+IncludeTrb("kernel/genoffset.trb")
+
+#
+#  フィールドのオフセットの定義の生成
+#
+GenerateDefine("TCB_p_tinib", $offsetof_TCB_p_tinib)
+GenerateDefine("TCB_sp", $offsetof_TCB_sp)
+GenerateDefine("TCB_pc", $offsetof_TCB_pc)
+GenerateDefine("TINIB_exinf", $offsetof_TINIB_exinf)
+GenerateDefine("TINIB_task", $offsetof_TINIB_task)
+GenerateDefine("TINIB_stksz", $offsetof_TINIB_stksz)
+GenerateDefine("TINIB_stk", $offsetof_TINIB_stk)
+GenerateDefineBit("TCB_enatex", $sizeof_TCB, "B")
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_rename.def
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_rename.def	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_rename.def	(revision 398)
@@ -0,0 +1,27 @@
+# prc_kernel_impl.c
+intnest
+lock_flag
+saved_ipl
+prc_initialize
+prc_terminate
+config_int
+default_int_handler
+default_exc_handler
+
+# prc_support.src
+dispatch
+start_dispatch
+exit_and_dispatch
+call_exit_kernel
+start_r
+interrupt
+exception
+
+# rx630_kernel_impl.c
+ipr_reg_addr
+ier_reg_addr
+ir_reg_addr
+irqcr_reg_addr
+
+# kernel_cfg.c
+cfg_int_table
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_rename.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_rename.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_rename.h	(revision 398)
@@ -0,0 +1,84 @@
+/* This file is generated from prc_rename.def by genrename. */
+
+#ifndef TOPPERS_PRC_RENAME_H
+#define TOPPERS_PRC_RENAME_H
+
+/*
+ *  prc_kernel_impl.c
+ */
+#define intnest						_kernel_intnest
+#define lock_flag					_kernel_lock_flag
+#define saved_ipl					_kernel_saved_ipl
+#define prc_initialize				_kernel_prc_initialize
+#define prc_terminate				_kernel_prc_terminate
+#define config_int					_kernel_config_int
+#define default_int_handler			_kernel_default_int_handler
+#define default_exc_handler			_kernel_default_exc_handler
+
+/*
+ *  prc_support.src
+ */
+#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
+#define start_r						_kernel_start_r
+#define interrupt					_kernel_interrupt
+#define exception					_kernel_exception
+
+/*
+ *  rx630_kernel_impl.c
+ */
+#define ipr_reg_addr				_kernel_ipr_reg_addr
+#define ier_reg_addr				_kernel_ier_reg_addr
+#define ir_reg_addr					_kernel_ir_reg_addr
+#define irqcr_reg_addr				_kernel_irqcr_reg_addr
+
+/*
+ *  kernel_cfg.c
+ */
+#define cfg_int_table				_kernel_cfg_int_table
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ *  prc_kernel_impl.c
+ */
+#define _intnest					__kernel_intnest
+#define _lock_flag					__kernel_lock_flag
+#define _saved_ipl					__kernel_saved_ipl
+#define _prc_initialize				__kernel_prc_initialize
+#define _prc_terminate				__kernel_prc_terminate
+#define _config_int					__kernel_config_int
+#define _default_int_handler		__kernel_default_int_handler
+#define _default_exc_handler		__kernel_default_exc_handler
+
+/*
+ *  prc_support.src
+ */
+#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
+#define _start_r					__kernel_start_r
+#define _interrupt					__kernel_interrupt
+#define _exception					__kernel_exception
+
+
+/*
+ *  rx630_kernel_impl.c
+ */
+#define _ipr_reg_addr				__kernel_ipr_reg_addr
+#define _ier_reg_addr				__kernel_ier_reg_addr
+#define _ir_reg_addr				__kernel_ir_reg_addr
+#define _irqcr_reg_addr				__kernel_irqcr_reg_addr
+
+/*
+ *  kernel_cfg.c
+ */
+#define _cfg_int_table				__kernel_cfg_int_table
+
+#endif /* TOPPERS_LABEL_ASM */
+
+
+#endif /* TOPPERS_PRC_RENAME_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_sil.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_sil.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_sil.h	(revision 398)
@@ -0,0 +1,294 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		sil.hのプロセッサ依存部（RX630用）
+ */
+
+#ifndef TOPPERS_PRC_SIL_H
+#define TOPPERS_PRC_SIL_H
+
+
+#ifndef TOPPERS_MACRO_ONLY
+#include "prc_insn.h"
+
+
+/*
+ *  全割込み禁止
+ */
+Inline uint32_t
+TOPPERS_disint( void )
+{
+	volatile uint32_t	TOPPERS_psw;
+
+	TOPPERS_psw = current_psw();
+	disint();
+
+	return( TOPPERS_psw );
+}
+
+
+/*
+ *  全割込み許可
+ */
+Inline void
+TOPPERS_enaint( uint32_t TOPPERS_psw )
+{
+	if( TOPPERS_psw & PSW_I_MASK ){
+		enaint();
+	}
+}
+
+
+/*
+ *  全割込みロック状態の制御
+ */
+#define SIL_PRE_LOC		uint32_t TOPPERS_i_psw;
+#define SIL_LOC_INT()	( ( void )( TOPPERS_i_psw = TOPPERS_disint() ) )
+#define SIL_UNL_INT()	( TOPPERS_enaint( TOPPERS_i_psw ) )
+
+
+/*
+ *  エンディアンの反転
+ *
+ *  本開発環境ではエンディアン変換命令が存在するため,
+ *  アーキテクチャ依存部にてマクロを上書きする.
+ */
+#define TOPPERS_SIL_REV_ENDIAN_UINT16( data )	\
+ 								rev_endian_uint16( data )
+#define TOPPERS_SIL_REV_ENDIAN_UINT32( data )	\
+ 								rev_endian_uint32( data )
+
+
+/*
+ *  微少時間待ち
+ */
+extern void sil_dly_nse( ulong_t dlytim ) throw();
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+
+/*
+ *  プロセッサのエンディアン
+ */
+#define SIL_ENDIAN_LITTLE			/* リトルエンディアン */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  メモリ空間アクセス関数
+ */
+#define TOPPERS_OMIT_SIL_ACCESS
+
+/*
+ *  8ビット単位の読出し／書込み
+ */
+#ifdef UINT8_MAX
+
+Inline uint8_t
+sil_reb_mem(const volatile uint8_t *mem)
+{
+	uint8_t	data;
+
+	data = *((const volatile uint8_t *) mem);
+	return(data);
+}
+
+Inline void
+sil_wrb_mem(volatile uint8_t *mem, uint8_t data)
+{
+	*((volatile uint8_t *) mem) = data;
+}
+
+#endif /* UINT8_MAX */
+
+/*
+ *  16ビット単位の読出し／書込み
+ */
+
+Inline uint16_t
+sil_reh_mem(const volatile uint16_t *mem)
+{
+	uint16_t	data;
+
+	data = *((const volatile uint16_t *) mem);
+	return(data);
+}
+
+Inline void
+sil_wrh_mem(volatile 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 volatile 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(volatile 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 volatile 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(volatile 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 volatile uint32_t *mem)
+{
+	uint32_t	data;
+
+	data = *((const volatile uint32_t *) mem);
+	return(data);
+}
+
+Inline void
+sil_wrw_mem(volatile 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 volatile 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(volatile 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 volatile 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(volatile 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_MACRO_ONLY */
+
+#endif /* TOPPERS_PRC_SIL_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_stddef.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_stddef.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_stddef.h	(revision 398)
@@ -0,0 +1,55 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		t_stddef.hのプロセッサ依存部（RX630用）
+ *
+ *  このインクルードファイルは，target_stddef.h（または，そこからインク
+ *  ルードされるファイル）のみからインクルードされる．他のファイルから
+ *  直接インクルードしてはならない．
+ */
+
+#ifndef TOPPERS_PRC_STDDEF_H
+#define TOPPERS_PRC_STDDEF_H
+
+/*
+ *  ターゲットを識別するためのマクロの定義
+ */
+#define TOPPERS_RX630				/* プロセッサ略称 */
+
+#endif /* TOPPERS_PRC_STDDEF_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_support.S
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_support.S	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_support.S	(revision 398)
@@ -0,0 +1,903 @@
+; 
+;   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) 2007      by Embedded and Real-Time Systems Laboratory
+;               Graduate School of Information Science, Nagoya Univ., JAPAN
+;   Copyright (C) 2010 by Witz Corporation, JAPAN
+;   Copyright (C) 2013      by Mitsuhiro Matsuura
+;   Copyright (C) 2017      by Cores Co., Ltd. Japan
+;  
+;   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+;   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+;   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+;   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+;       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+;       スコード中に含まれていること．
+;   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+;       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+;       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+;       の無保証規定を掲載すること．
+;   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+;       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+;       と．
+;     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+;         作権表示，この利用条件および下記の無保証規定を掲載すること．
+;     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+;         報告すること．
+;   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+;       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+;       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+;       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+;       免責すること．
+;  
+;   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+;   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+;   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+;   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+;   の責任を負わない．
+;  
+;  @(#) $Id$
+;
+
+;
+;  プロセッサ依存モジュール アセンブリ言語部（RX630用）
+;
+#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"
+
+;
+;  ディスパッチャおよび割込み(CPU例外)出入り口のルール:
+;	動作モードを以下のように定義する.
+;		ディスパッチャモード:
+;			CPUロック状態, 割込み優先度マスク全解除状態,
+;			タスクコンテキスト(intnest = 0), タスクスタック
+;		割込み(CPU例外)処理モード
+;			全割込みロック状態(PSWレジスタIビット = 0),
+;			割込み優先度マスク全解除でない状態(IPL != 0)
+;			割込みコンテキスト(intnest != 0), 割込みスタック
+;
+;	カーネル管理外割込みのサポート有無と, CPUロック状態, 割込み優先度
+;	マスク全解除状態の関係は以下の通りである.
+;		カーネル管理外割込み未サポート時:
+;			CPUロック状態(PSWレジスタIビット = 0)
+;			割込み優先度マスク全解除状態(IPL = 0)
+;		カーネル管理外割込みサポート時:
+;			CPUロック状態
+;				(PSWレジスタIビット = 0, IPL = IPL_LOCK, lock_flag = true)
+;			割込み優先度マスク全解除状態(saved_ipl = 0)
+;
+;	各構造体ポインタを以下のように各レジスタにアサインする.
+;		r15 = p_runtsk	ただしディスパッチャの各出口では無効
+;		r14 = *p_runtsk	dispatcher の中では p_runtsk 確定時に再取得する
+;	各入り口から最初に変数アクセスするときに上記レジスタに保存する.
+;
+;	構造体アライメントへの対応
+;		構造体アライメントが4Byte(アンパック)の場合:
+;			一般的なレジスタ相対アドレッシングが可能
+;				例:	mov.l	#__kernel_p_runtsk, r15
+;					mov.l  	r0, TCB_sp[r15]
+;		構造体アライメントが4Byteではない(パック)の場合:
+;			mov.lのようにロングサイズ指定の場合、相対値は4の倍数のみ有効
+;			このため, 一度対象アドレスを求めてからアクセスする必要がある
+;				例:	mov.l	#__kernel_p_runtsk, r15
+;					add		#TCB_sp, r15, r5
+;					mov.l  	r0, [r5]
+;		各オフセット値を判断し, 条件アセンブルによりコードを切り替える
+;
+
+;
+;  構造体アクセスのオフセット定義
+;
+#include "offset.h"
+
+;
+;  各種EQU定義(Hファイルの#define定義)
+;
+#include "target_kernel_impl.h"
+#include "prc_kernel_impl.h"
+
+	.global	__kernel_istkpt
+	
+	.global	__kernel_p_runtsk
+	.global	__kernel_p_schedtsk
+
+	.global	__kernel_dispatch
+	.global	__exit_and_dispatch
+	.global	__kernel_start_r
+	.global	__kernel_call_texrtn
+	.global	_kernel_interrupt
+	.global	_kernel_exception
+	.global	__kernel_intnest
+	.global	__kernel_call_exit_kernel
+	.global	__kernel_start_dispatch
+
+	.global	_ext_tsk
+	.global	__kernel_exit_kernel
+
+#if	TIPM_LOCK != -15
+	.global	__kernel_lock_flag
+	.global	__kernel_saved_ipl
+#endif
+
+	.global	__kernel_break_wait
+	.global	_sil_dly_nse
+
+#if LOG_INH_ENTER == 1
+	.global	_kernel_log_inh_enter
+#endif	/* LOG_INH_ENTER == 1 */
+#if LOG_INH_LEAVE == 1
+	.global	_kernel_log_inh_leave
+#endif	/* LOG_INH_LEAVE == 1 */
+#if LOG_EXC_ENTER == 1
+	.global	_kernel_log_exc_enter
+#endif	/* LOG_EXC_ENTER == 1 */
+#if LOG_EXC_LEAVE == 1
+	.global	_kernel_log_exc_leave
+#endif	/* LOG_EXC_LEAVE == 1 */
+#if LOG_DSP_ENTER == 1
+	.global	_kernel_log_dsp_enter
+#endif	/* LOG_DSP_ENTER == 1 */
+#if LOG_DSP_LEAVE == 1
+	.global	_kernel_log_dsp_leave
+#endif	/* LOG_DSP_LEAVE == 1 */
+
+#ifdef TOPPERS_SUPPORT_OVRHDR
+	.global	__kernel_ovrtimer_start
+	.global	__kernel_ovrtimer_stop
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+
+;
+;  TCB_sp への書込みマクロ
+;
+.macro	st_TCB_sp	src, tcb, tmp
+#if (TCB_sp % 4) == 0
+	mov.l	\src, TCB_sp[\tcb]
+#else
+	add		#TCB_sp, \tcb, \tmp
+	mov.l	\src, [\tmp]
+#endif
+.endm
+
+;
+;  TCB_sp からの読出しマクロ
+;
+.macro	ld_TCB_sp	dst, tcb, tmp
+#if (TCB_sp % 4) == 0
+	mov.l	TCB_sp[\tcb], \dst
+#else
+	add		#TCB_sp, \tcb, \tmp
+	mov.l	[tmp], \dst
+#endif
+.endm
+
+;
+;  TCB_pc への書込みマクロ
+;
+.macro	st_TCB_pc	src, tcb, tmp
+#if (TCB_pc % 4) == 0
+	mov.l	\src, TCB_pc[\tcb]
+#else
+	add		#TCB_pc, \tcb, \tmp
+	mov.l	\src, [\tmp]
+#endif
+.endm
+
+;
+;  TCB_pc からの読出しマクロ
+;
+.macro	ld_TCB_pc	dst, tcb, tmp
+#if (TCB_pc % 4) == 0
+	mov.l	TCB_pc[\tcb], \dst
+#else
+	add		#TCB_pc, \tcb, \tmp
+	mov.l	[\tmp], \dst
+#endif
+.endm
+
+;
+;  TCB_texptn からの読出しマクロ
+;
+.macro	ld_TCB_texptn	dst, tcb, tmp
+#if (TCB_texptn % 4) == 0
+	mov.l	TCB_texptn[\tcb], \dst
+#else
+	add		#TCB_texptn, \tcb, \tmp
+	mov.l	[\tmp], \dst
+#endif
+.endm
+
+;
+;  TCB_p_tinib からの読出しマクロ
+;
+.macro	ld_TCB_p_tinib	dst, tcb, tmp
+#if (TCB_p_tinib % 4) == 0
+	mov.l	TCB_p_tinib[\tcb], \dst
+#else
+	add		#TCB_p_tinib, \tcb, \tmp
+	mov.l	[\tmp], \dst
+#endif
+.endm
+
+;
+;  TINIB_exinf からの読出しマクロ
+;
+.macro	ld_TINIB_exinf	dst, tinib, tmp
+#if (TINIB_exinf % 4) == 0
+	mov.l	TINIB_exinf[\tinib], \dst
+#else
+	add		#TINIB_exinf, \tinib, \tmp
+	mov.l	[\tmp], \dst
+#endif
+.endm
+
+;
+;  TINIB_task からの読出しマクロ
+;
+.macro	ld_TINIB_task	dst, tinib, tmp
+#if (TINIB_task % 4) == 0
+	mov.l	TINIB_task[\tinib], \dst
+#else
+	add		#TINIB_task, \tinib, \tmp
+	mov.l	[\tmp], \dst
+#endif
+.endm
+
+
+	.section	P, CODE
+
+;
+;  APIからのタスクディスパッチャ入口
+;
+;  呼び出し条件:
+;	・ディスパッチャモード(ファイルヘッダ参照)
+;
+;  ここでは, コンテキストの退避と, 実行再開番地の設定をする.
+;
+__kernel_dispatch:
+#ifdef TOPPERS_SUPPORT_OVRHDR /* (6-5-3-1) */
+	mov.l	#255, r1					; r1にダミー割込み番号
+	bsr		__kernel_ovrtimer_stop
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+	pushm	r6-r13						; 非スクラッチレジスタ保存
+	mov.l	#__kernel_p_runtsk, r15
+	mov.l	[r15], r14
+	st_TCB_sp	r0, r14, r5				; スタックポインタをTCBに保存
+	st_TCB_pc	#dispatch_r, r14, r5	; 実行再開番地をTCBに保存
+	bra		dispatcher
+
+;
+;  APIへのタスクディスパッチャ出口
+;
+;  呼び出し条件:
+;	・ディスパッチャモード(ファイルヘッダ参照)
+;
+;  ここでは, タスク例外ハンドラ呼出しと, コンテキストの復帰をする.
+;
+dispatch_r:
+dispatch_r_rts:
+	popm 	r6-r13						; 非スクラッチレジスタ復帰
+#ifdef TOPPERS_SUPPORT_OVRHDR /* (6-5-3-2) */
+	bsr		__kernel_ovrtimer_start
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+	rts  	                        	; dispatch 呼び出し元へ戻る.
+
+;
+;  タスク起動処理(タスク先頭へのタスクディスパッチャ出口)
+;
+;  呼び出し条件:
+;	・ディスパッチャモード(ファイルヘッダ参照)
+;
+;  ここでは, CPUロック解除状態にし, タスクを起動する.
+;
+__kernel_start_r:
+#ifdef TOPPERS_SUPPORT_OVRHDR /* (6-5-6-1) */
+	push.l	r14
+	bsr		__kernel_ovrtimer_start
+	pop		r14
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+	mov.l 	#_ext_tsk, r5
+	push.l	r5							; 戻り番地をスタックに積む
+	ld_TCB_p_tinib	r5, r14, r4
+	ld_TINIB_exinf	r1, r5, r4			; 拡張情報を第一引数に設定
+	ld_TINIB_task	r5, r5, r4			; タスクの起動番地を取得
+.if	TIPM_LOCK == -15
+	setpsw	i							; 割込み許可(CPUロック解除状態)
+.else
+	mov.l	#__kernel_lock_flag, r4		; CPUロック解除状態へ
+	mov.l	#0, [r4]					; ここに来るときは必ず saved_ipl の
+	mvtc	#00010000H, psw				; 値は 0 のため, 直値を設定する.
+								; 全割込みロック解除状態( I = 1 )
+								; 割込み優先度マスク全解除状態( IPL = 0 )
+.endif
+	jmp		r5
+
+;
+;  カーネル起動からのタスクディスパッチャ入口
+;
+;  このルーチンは，カーネル起動時に，すべての割込みを禁止した状態
+; （割込みロック状態と同等）で呼び出される．また，割込みモード（非
+;  タスクコンテキストと同等）で呼び出されることを想定している．
+;
+;  呼び出し条件:
+;	・割込み(CPU例外)処理モード(ファイルヘッダ参照)
+;
+;  ここでは, ディスパッチャモードに変更する.
+;
+__kernel_start_dispatch:
+	mov.l	#__kernel_intnest, r5
+	mov.w	#0, [r5]					; タスクコンテキストに切換え
+#if	TIPM_LOCK != -15
+	mvtc	#(IPL_LOCK | 00010000H), psw	; 全割込みロック解除状態
+										; 割込み優先度マスク全解除でない状態
+#endif
+
+;
+; タスク終了(現在のコンテキストを捨てる)からのタスクディスパッチャ入口
+;
+;  呼び出し条件:
+;	・ディスパッチャモード(ファイルヘッダ参照)
+;
+;  ここでは, 何もすることはない.
+;  なお, p_runtsk のアドレス取得だけは行なう.
+;
+__exit_and_dispatch:
+	mov.l	#__kernel_p_runtsk, r15     
+.if	LOG_DSP_ENTER == 1
+	mov.l	[r15], r14
+.endif
+;
+; ディスパッチャ本体
+;
+;  呼び出し条件:
+;	・すべてのタスクのコンテキストは保存されている.
+;
+;  dispatcher 呼出時のスタック:
+;	・__kernel_dispatch からきた場合			: タスクスタック
+;	・exit_and_dispatch からきた場合: 
+;		exit_task からきた場合					: タスクスタック
+;		カーネル起動時(__kernel_start_dispatch)	: 割込みスタック
+;	・ret_int からきた場合						: タスクスタック
+;	・dispatcher_idle_loop からきた場合			: 割込みスタック
+;
+dispatcher:
+.if	LOG_DSP_ENTER == 1
+	push.l	r15
+	mov.l	r14, r1						; 引数(ディスパッチ元TCB)を設定
+	bsr		__kernel_log_dsp_enter
+	pop		r15
+.endif
+	mov.l	#__kernel_p_schedtsk, r5     
+	mov.l	[r5], [r15]					; p_schedtsk を p_runtsk に
+	mov.l	[r15], r14
+	cmp		#0, r14
+	bz		dispatcher_pre_idle			; schedtsk がなければアイドルループへ
+	ld_TCB_sp	r0, r14, r5				; タスクスタックポインタを復帰
+.if	LOG_DSP_LEAVE == 1
+	push.l	r14
+	mov.l	r14, r1						; 引数(ディスパッチ先TCB)を設定
+	bsr		__kernel_log_dsp_leave
+	pop		r14
+.endif
+	ld_TCB_pc	r5, r14, r4
+	jmp		r5					; 実行再開番地へジャンプ
+
+;
+;  schdedtskがNULLの場合はアイドルループに入る
+;  アイドルループは割込み処理モードで動作させる
+;
+;  ここで割込みモードに切り換えるのは，ここで発生する割込み処理に
+;  どのスタックを使うかという問題の解決と，割込みハンドラ内でのタ
+;  スクディスパッチの防止という2つの意味がある．
+;
+dispatcher_pre_idle:
+	mov.l	#__kernel_istkpt,r5
+	mov.l	[r5], r0					; 割込み用のスタックへ切替え
+	mov.l	#__kernel_intnest, r5
+	mov.w	#1, [r5]					; 非タスクコンテキストに切換え
+#if	TIPM_LOCK != -15
+	mov.l	#__kernel_lock_flag, r5		; CPUロック解除状態へ
+	mov.l	#0, [r5]
+	mvtc	#0, psw						; 優先度0の割込み処理中を偽装
+#endif
+
+dispatcher_idle_loop:
+	setpsw	i							; 全割込み許可
+	wait
+	clrpsw	i							; 全割込み禁止
+
+	mov.l	#__kernel_p_schedtsk, r4
+	mov.l	[r4], r4					; p_schedtsk -> r4
+	mov.l	#__kernel_p_runtsk, r5
+	mov.l	[r5], r5					; p_runtsk -> r5
+	cmp		r4, r5						; p_schedtsk と p_runtsk が同じでディスパッチ要求無しなら
+	beq		dispatcher_idle_loop		; アイドルループを繰り返す
+	mov.l	#0, [r5]					; reqflgがtrueならfalseにする
+	mov.l	#__kernel_intnest, r5
+	mov.w	#0, [r5]					; タスクコンテキストに切換え
+#if	TIPM_LOCK != -15
+	mov.l	#__kernel_lock_flag, r5		; CPUロック状態へ
+	mov.l	#1, [r5]
+	mov.l	#__kernel_saved_ipl, r5
+	mov.l	#0, [r5]
+	mvtc	#(IPL_LOCK | PSW_I_MASK), psw	; 全割込みロック解除状態
+										; 割込み優先度マスク全解除でない状態
+#endif
+	bra		dispatcher					; dispatcher へ戻る
+
+
+;
+; カーネルの終了処理の呼出し
+;
+; モードとスタックを非タスクコンテキスト用に切り替え．
+;
+	.global	__kernel_call_exit_kernel
+__kernel_call_exit_kernel:
+#if	TIPM_LOCK != -15
+	clrpsw	i							; 全割込み禁止
+	mov.l	#__kernel_lock_flag, r5		; CPUロック解除状態へ
+	mov.l	#0, [r5]
+#endif
+	mov.l	#__kernel_istkpt, r5
+	mov.l	[r5], r0					; 割込み用のスタックへ切替え
+	mov.l	#__kernel_intnest, r5
+	mov.w	#1, [r5]					; 非タスクコンテキストに切換え
+	bsr		__kernel_exit_kernel
+	bra		__kernel_call_exit_kernel
+
+
+;
+;  割込み(CPU例外)からのタスクディスパッチャ入口
+;
+;	呼出し条件:
+;	・全割込みロック状態(PSWレジスタIビット = 0)
+;	・割込み優先度マスク全解除でない状態(IPL != 0)
+;	・タスクコンテキスト(intnest=0)
+;	・使用スタックはタスクスタック
+;	・reqflg = true
+;
+;  ここでは, ディスパッチャモードに変更し, reqflgをOFFにしてから, 
+;  遅延ディスパッチの有無を判断する.
+;
+
+;
+;  ret_int先頭でスタックに積まれているPSWレジスタへのオフセット
+;  ACC + FPSW + R14--R15 + R1--R5 + PC
+;
+	.equ	RET_INT_GET_PSW_OFFSET,	(8+4+28+4)
+
+ret_int:
+.if	TIPM_LOCK == -15
+	mov.l	RET_INT_GET_PSW_OFFSET[r0], r5	; 割込み/CPU例外発生前のIPL値取得
+	and		#PSW_IPL_MASK, r5
+	mvtc	r5, psw						; 全割込みロック(CPUロック)状態
+										; 割込み/CPU例外発生前の割込み優先度
+.else
+	mov.l	#__kernel_lock_flag, r5		; CPUロック状態へ
+	mov.l	#1, [r5]
+	mov.l	RET_INT_GET_PSW_OFFSET[r0], r5	; 割込み/CPU例外発生前のIPL値取得
+	and		#PSW_IPL_MASK, r5
+	mov.l	#__kernel_saved_ipl, r4
+	mov.l	r5, [r4]
+	mvtc	#(IPL_LOCK | PSW_I_MASK), psw	; 全割込みロック解除状態
+										; 割込み優先度マスク全解除でない状態
+.endif
+	mov.l	#__kernel_p_runtsk, r15     
+	mov.l	[r15], r14
+	mov.l	#__kernel_p_schedtsk, r5
+	mov.l	[r5], r5
+	cmp		r5, r14						; p_schedtsk と p_runtsk が同じなら
+	beq  	ret_int_r_call_tex			; ret_int_r_call_tex へ
+	pushm	r6-r13						; 非スクラッチレジスタ保存
+	st_TCB_sp	r0, r14, r5				; スタックポインタをTCBに保存
+	st_TCB_pc	#ret_int_r, r14, r5		; 実行再開番地をTCBに保存
+	bra		dispatcher
+
+;
+;  割込み(CPU例外)へのタスクディスパッチャ出口
+;
+;  呼び出し条件:
+;	・ディスパッチャモード(ファイルヘッダ参照)
+;
+;  ここでは, タスク例外ハンドラ呼出しと, 割込み(CPU例外)処理モードへの
+;  変更と, コンテキストの復帰を行い, 割込み(CUP例外)発生元へ戻る.
+;
+__kernel_break_wait:					;タスクモニタ用ラベル
+ret_int_r:
+	popm 	r6-r13						; 非スクラッチレジスタ復帰
+ret_int_r_call_tex:
+#ifdef TOPPERS_SUPPORT_OVRHDR /* 6.6.1 & 6.7.1 */
+	push.l	r14
+	bsr		__kernel_ovrtimer_start
+	pop		r14
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ret_int_r_rte:
+#if	TIPM_LOCK != -15
+	clrpsw	i							; 全割込み禁止
+	mov.l	#__kernel_lock_flag, r5		; CPUロック解除状態へ
+	mov.l	#0, [r5]
+#endif
+	popm	r4-r5						; アキュムレータ復帰
+	mvtaclo	r5							; ACC最下位16bitは0で復帰
+	mvtachi	r4
+	popc	fpsw						; FPUステータスレジスタ復帰
+	popm	r14-r15						; レジスタ復帰
+	popm	r1-r5
+	rte									; 割込み前の処理に戻る
+
+
+;
+;  割込みの出入口処理(アセンブリ言語記述部分)
+;
+;  呼出し条件:
+;  ・割込み発生時のH/W処理により, PSWレジスタのIビット=0, IPLは受付け
+;    た割込みのIPL.
+;  ・スタックは多重割り込みなら割込みスタック, そうでなければ
+;    タスクスタック
+;  ・割込み発生時のH/W処理により,スタックに割込みからの復帰PCとPSWが
+;    保存されている.
+;  ・ベクタテーブルに登録された個別の入り口処理により, スタックに
+;    スクラッチレジスタ(R1-R5)が保存されている.
+;
+;  引数:
+;  ・r1:割込み要因番号
+;  ・r2:割込みハンドラのアドレス
+;
+;  レジスタがスタック上にどのように保存されているかを以下に示す.
+;  この図では上が低位, 下が高位のアドレスで, スタックは下から
+;  上方向に向かって積み上げられるものとする.
+;
+;	-------------------------
+;	|       ACC-HI(4byte)   |
+;	-------------------------(SP + 0)
+;	|       ACC-LO(4byte)   |
+;	-------------------------(SP + 4)
+;	|       FPSW(4byte)     |
+;	-------------------------(SP + 8)
+;	|       R14(4byte)      |
+;	-------------------------(SP + 12)
+;	|       R15(4byte)      |
+;	-------------------------(SP + 16)
+;	|       R1(4byte)       |
+;	-------------------------(SP + 20)
+;	|       R2(4byte)       |
+;	-------------------------(SP + 24)
+;	|       R3(4byte)       |
+;	-------------------------(SP + 28)
+;	|       R4(4byte)       |
+;	-------------------------(SP + 32)
+;	|       R5(4byte)       |
+;	-------------------------(SP + 36)
+;	|       PC(4byte)       |
+;	-------------------------(SP + 40)
+;	|       PSW(4byte)      |
+;	-------------------------(SP + 44)
+;
+;  ここでは, 割込み処理モードに変更してハンドラを実行する.
+;
+;  ハンドラからリターンした後は, 多重割込みでなく, かつ reqflg が
+;  TRUE になった時に，ret_int へ分岐(遅延ディスパッチ)する．
+;
+;  多重割込みかどうかは割込みネストカウンタの値で判定する.
+;  intnest != 0 ならば多重割込みであると判定する.
+;
+;  reqflg はCPUロック状態でチェックする. そうでないと，
+;  reqflg チェック後に起動された割込みハンドラ内で
+;  ディスパッチが要求された場合に，ディスパッチされない.
+;
+_kernel_interrupt:
+	pushm	r14-r15						; スクラッチレジスタを退避
+	pushc	fpsw						; FPUステータスレジスタ退避
+	mvfacmi	r5
+	shll	#16, r5						; ACC最下位16bitは0とする
+	mvfachi	r4
+	pushm	r4-r5						; アキュムレータ退避
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	add		#1, r4						; ネスト回数をインクリメント
+	mov.w	r4, [r5]
+	cmp		#1, r4						; 多重割り込みかどうか
+	bnz		interrupt_from_int			; 加算前が0でなければ多重割込み
+						; 初段の割込み
+#ifdef TOPPERS_SUPPORT_OVRHDR /* 6.6.1 */
+	pushm	r1-r5
+	bsr		__kernel_ovrtimer_stop		; r1に割込み番号
+	popm	r1-r5
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+	mov.l	r0, r3						; スタックポインタを取り出し
+	mov.l	#__kernel_istkpt, r5		; 割込み用のスタックへ切替える
+	mov.l	[r5], r0
+	push.l	r3							; タスクスタックを保持
+interrupt_from_int:		; 多重割込み
+	setpsw	i							; 割込み許可(CPUロック解除状態)
+
+.if	LOG_INH_LEAVE == 1
+	push.l	r1							; ログトレースの引数を保持
+.endif
+
+.if	LOG_INH_ENTER == 1
+	push.l	r2
+	bsr		__kernel_log_inh_enter		; ログトレース関数の呼出し
+							; 引数の割込み要因番号は既にr1に入っている
+	pop		r2
+.endif
+
+	jsr  	r2							; Cルーチン呼び出し
+
+.if	LOG_INH_LEAVE == 1
+	pop		r1							; 引数に割込み要因番号を設定
+	bsr		__kernel_log_inh_leave		; ログトレース関数の呼出し
+.endif
+
+	clrpsw	i							; 割込み禁止(CPUロック状態)
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	sub		#1, r4						; ネスト回数をデクリメント
+	mov.w	r4, [r5]
+	cmp		#0, r4						; 多重割り込みかどうか
+	bnz		interrupt_return			; 多重割り込みならリターン
+	; 初段の割込み
+	pop		r0							; タスクのスタックに戻す
+	mov.l	#__kernel_p_schedtsk, r4
+	mov.l	[r4], r4					; p_schedtsk -> r4
+	mov.l	#__kernel_p_runtsk, r5
+	mov.l	[r5], r5					; p_runtsk -> r5
+	cmp		r4, r5						; p_schedtsk と p_runtsk が異なりディスパッチ要求有りなら
+	bne		ret_int						; ret_int へジャンプ
+#ifdef TOPPERS_SUPPORT_OVRHDR /* 6.6.1 */
+	mov.l	#__kernel_p_runtsk, r5
+	mov.l	[r5], r4
+	cmp		#0, r4
+	beq		interrupt_return
+	bsr		__kernel_ovrtimer_start
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+interrupt_return:
+	popm	r4-r5						; アキュムレータ復帰
+	mvtaclo	r5							; ACC最下位16bitは0で復帰
+	mvtachi	r4
+	popc	fpsw						; FPUステータスレジスタ復帰
+	popm	r14-r15						; レジスタ復帰
+	popm	r1-r5
+	rte									; 割込み前の処理に戻る
+
+
+;
+;  CPU例外の出入口処理(アセンブリ言語記述部分)
+;
+;  呼出し条件:
+;  ・CPU例外発生時のH/W処理により, PSWレジスタのIビット=0, IPL=0.
+;  ・スタックは多重割り込みなら割込みスタック, そうでなければ
+;    タスクスタック
+;  ・CPU例外発生時のH/W処理により,スタックにCPU例外からの復帰PCと
+;    PSWが保存されている.
+;  ・ベクタテーブルに登録された個別の入り口処理により, スタックに
+;    スクラッチレジスタ(R1-R5)が保存されている.
+;
+;  引数:
+;  ・r1:CPU例外要因番号
+;  ・r2:CPU例外ハンドラのアドレス
+;
+;  レジスタがスタック上にどのように保存されているかを以下に示す.
+;  この図では上が低位, 下が高位のアドレスで, スタックは下から
+;  上方向に向かって積み上げられるものとする.
+;  なお, CPU例外要因番号とR6-R13はCPU例外ハンドラ内で情報を取得
+;  する目的で退避しており, 出口処理では保存内容を破棄すればよい.
+;
+;	-------------------------
+;	|    CPU例外要因番号    | <----- p_excinf
+;	------------------------- (intptr_t)(p_excinf + 0)
+;	|       R6(4byte)       |
+;	------------------------- (intptr_t)(p_excinf + 4)
+;	|       R7(4byte)       |
+;	------------------------- (intptr_t)(p_excinf + 8)
+;	|       R8(4byte)       |
+;	------------------------- (intptr_t)(p_excinf + 12)
+;	|       R9(4byte)       |
+;	------------------------- (intptr_t)(p_excinf + 16)
+;	|       R10(4byte)      |
+;	------------------------- (intptr_t)(p_excinf + 20)
+;	|       R11(4byte)      |
+;	------------------------- (intptr_t)(p_excinf + 24)
+;	|       R12(4byte)      |
+;	------------------------- (intptr_t)(p_excinf + 28)
+;	|       R13(4byte)      |
+;	------------------------- (intptr_t)(p_excinf + 32)
+;	|       ACC-HI(4byte)   |
+;	------------------------- (intptr_t)(p_excinf + 36)
+;	|       ACC-LO(4byte)   |
+;	------------------------- (intptr_t)(p_excinf + 40)
+;	|       FPSW(4byte)     |
+;	------------------------- (intptr_t)(p_excinf + 44)
+;	|       R14(4byte)      |
+;	------------------------- (intptr_t)(p_excinf + 48)
+;	|       R15(4byte)      |
+;	------------------------- (intptr_t)(p_excinf + 52)
+;	|       R1(4byte)       |
+;	------------------------- (intptr_t)(p_excinf + 56)
+;	|       R2(4byte)       |
+;	------------------------- (intptr_t)(p_excinf + 60)
+;	|       R3(4byte)       |
+;	------------------------- (intptr_t)(p_excinf + 64)
+;	|       R4(4byte)       |
+;	------------------------- (intptr_t)(p_excinf + 68)
+;	|       R5(4byte)       |
+;	------------------------- (intptr_t)(p_excinf + 72)
+;	|       PC(4byte)       |
+;	------------------------- (intptr_t)(p_excinf + 76)
+;	|       PSW(4byte)      |
+;	------------------------- (intptr_t)(p_excinf + 80)
+;
+;  ここでは, 割込み処理モードに変更してハンドラを実行する.
+;  CPU例外ハンドラに渡すVP型の変数 p_excinf としてISPの値渡す．
+;
+;  ハンドラからリターンした後は, 多重割込みでなく, かつ reqflg が
+;  TRUE になった時に，ret_int へ分岐(遅延ディスパッチ)する．
+;
+;  多重割込みかどうかは割込みネストカウンタの値で判定する.
+;  intnest != 0 ならば多重割込みであると判定する.
+;
+;  reqflg はCPUロック状態でチェックする. そうでないと，
+;  reqflg チェック後に起動された割込みハンドラ内で
+;  ディスパッチが要求された場合に，ディスパッチされない.
+;
+;
+;  CPU例外入口処理
+;
+;  ここでは, 割込み処理モードに変更してハンドラを実行する.
+;
+
+;
+;  CPU例外ハンドラ呼出し後に不要となるスタック情報のサイズ
+;  EXCNO + R6--R13
+;
+	.equ	EXCINF_REG_SIZE,	(4+32)
+
+_kernel_exception:
+	pushm	r14-r15						; スクラッチレジスタを退避
+	pushc	fpsw
+	mvfacmi	r5
+	shll	#16, r5						; ACC最下位16bitは0とする
+	mvfachi	r4
+	pushm	r4-r5						; アキュムレータ退避
+	pushm	r6-r13						; 非スクラッチレジスタ保存
+	push.l	r1							; CPU例外要因番号を保持
+	mov.l	r0, r3						; スタックポインタを取り出し
+	mov.l	EXC_GET_PSW_OFFSET[r3], r5
+	and		#PSW_I_MASK, r5
+	bz		exception_nonkernel			; 全割込み禁止(CPUロック)状態なら管理外
+#if	TIPM_LOCK != -15
+	mov.l	EXC_GET_PSW_OFFSET[r3], r5
+	and		#PSW_IPL_MASK, r5
+	cmp		#IPL_LOCK, r5
+	bgt	exception_nonkernel			; IPLがCPUロックレベル以上なら管理外
+#endif
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	add		#1, r4						; ネスト回数をインクリメント
+	mov.w	r4, [r5]
+	cmp		#1, r4						; 多重割り込みかどうか
+	bnz		exception_from_int			; 加算前が0でなければ多重割込み
+						; 初段の割込み
+#ifdef TOPPERS_SUPPORT_OVRHDR /* 6.7.1 */
+	pushm	r1-r5
+	mov.l	#255, r1					; r1にダミー割込み番号
+	bsr		__kernel_ovrtimer_stop
+	popm	r1-r5
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+	mov.l	#__kernel_istkpt, r5		; 割込み用のスタックへ切替える
+	mov.l	[r5], r0
+	push.l	r3							; タスクスタックを保持
+exception_from_int:		; 多重割込み
+	mov.l	EXC_GET_PSW_OFFSET[r3], r5
+	mvtc	r5, psw						; CPU例外発生前の状態に戻す
+#if	LOG_EXC_LEAVE == 1
+	push.l	r1							; ログトレースの引数を保持
+#endif
+
+#if	LOG_EXC_ENTER == 1
+	pushm	r2-r3
+	bsr		__kernel_log_exc_enter		; ログトレース関数の呼出し
+							; 引数の割込み要因番号は既にr1に入っている
+	popm	r2-r3
+#endif
+
+	mov.l	r3, r1						; 引数のp_excinfを設定
+	jsr  	r2							; Cルーチン呼び出し
+
+.if	LOG_EXC_LEAVE == 1
+	pop		r1							; 引数に割込み要因番号を設定
+	bsr		__kernel_log_exc_leave		; ログトレース関数の呼出し
+.endif
+
+	clrpsw	i							; ここからは必ず割込み禁止
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	sub		#1, r4						; ネスト回数をデクリメント
+	mov.w	r4, [r5]
+	cmp		#0, r4						; 多重割り込みかどうか
+	bnz		exception_return			; 多重割り込みならリターン
+	; 初段の割込み
+	pop		r0							; タスクのスタックに戻す
+	mov.l	#__kernel_p_schedtsk, r4
+	mov.l	[r4], r4					; p_schedtsk -> r4
+	mov.l	#__kernel_p_runtsk, r5
+	mov.l	[r5], r5					; p_runtsk -> r5
+	cmp		r4, r5						; p_schedtsk と p_runtsk が同じでディスパッチ要求無しか
+#ifndef TOPPERS_SUPPORT_OVRHDR /* 6.7.1 */
+	beq		exception_return			; なければリターン
+	add		#EXCINF_REG_SIZE, r0		; CPU例外情報の破棄
+	bra		ret_int						; あれば ret_int へジャンプ
+#else /* TOPPERS_SUPPORT_OVRHDR */
+	beq		exception_return_ovr		; なければリターン
+	add		#EXCINF_REG_SIZE, r0		; CPU例外情報の破棄
+	bra		ret_int						; あれば ret_int へジャンプ
+exception_return_ovr:
+	mov.l	#__kernel_p_runtsk, r5
+	mov.l	[r5], r4
+	cmp		#0, r4
+	beq		exception_return
+	bsr		__kernel_ovrtimer_start
+	bra		exception_return
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+
+exception_nonkernel:
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	add		#1, r4						; ネスト回数をインクリメント
+	mov.w	r4, [r5]
+	cmp		#1, r4						; 多重割り込みかどうか
+	bnz		exception_from_nonkernelint	; 加算前が0でなければ多重割込み
+						; 初段の割込み
+	mov.l	#__kernel_istkpt, r5		; 割込み用のスタックへ切替える
+	mov.l	[r5], r0
+	push.l	r3							; タスクスタックを保持
+exception_from_nonkernelint:	; 多重割込み
+	mov.l	EXC_GET_PSW_OFFSET[r3], r5
+	mvtc	r5, psw						; CPU例外発生前の状態に戻す
+
+	mov.l	r3, r1						; 引数のp_excinfを設定
+	jsr  	r2							; Cルーチン呼び出し
+
+	clrpsw	i							; ここからは必ず割込み禁止
+	mov.l	#__kernel_intnest, r5
+	mov.w	[r5], r4
+	sub		#1, r4						; ネスト回数をデクリメント
+	mov.w	r4, [r5]
+	cmp		#0, r4						; 多重割り込みかどうか
+	bnz		exception_return			; 多重割り込みならリターン
+	; 初段の割込み
+	pop		r0							; タスクのスタックに戻す
+
+exception_return:
+	add		#EXCINF_REG_SIZE, r0		; CPU例外情報の破棄
+	popm	r4-r5						; アキュムレータ復帰
+	mvtaclo	r5							; ACC最下位16bitは0で復帰
+	mvtachi	r4
+	popc	fpsw						; FPUステータスレジスタ復帰
+	popm	r14-r15						; レジスタ復帰
+	popm	r1-r5
+	rte									; 割込み前の処理に戻る
+
+
+;
+;  微少時間待ち
+;
+_sil_dly_nse:
+	mov.l	#SIL_DLY_TIM1, r5
+	sub		r5, r1
+	ble		sil_dly_nse_ret
+sil_dly_nse_loop:
+	mov.l	#SIL_DLY_TIM2, r5
+	sub		r5, r1
+	bgt		sil_dly_nse_loop
+sil_dly_nse_ret:
+	rts
+
+	.end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_sym.def
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_sym.def	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_sym.def	(revision 398)
@@ -0,0 +1,13 @@
+TA_EDGE
+TA_LOWLEVEL
+TA_BOTHEDGE
+TA_NEGEDGE
+TIPM_LOCK,,signed
+IPL_LOCK
+PSW_I_MASK
+PSW_IPL_MASK
+EXC_GET_PSW_OFFSET
+sizeof_TCB,sizeof(TCB)
+offsetof_TCB_p_tinib,"offsetof(TCB,p_tinib)"
+offsetof_TCB_sp,"offsetof(TCB,tskctxb.sp)"
+offsetof_TCB_pc,"offsetof(TCB,tskctxb.pc)"
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_syssvc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_syssvc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_syssvc.h	(revision 398)
@@ -0,0 +1,57 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ *  Copyright (C) 2013      by Mitsuhiro Matsuura
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		テストプログラムのターゲット依存定義（RX630用）
+ */
+
+#ifndef TOPPERS_PRC_SYSSVC_H
+#define TOPPERS_PRC_SYSSVC_H
+
+/*
+ *  起動メッセージにターゲット依存部の著作権表示を
+ *  追加するためのマクロ．
+ */
+#define PRC_COPYRIGHT										\
+	"Copyright (C) 2010 by Witz Corporation, JAPAN\n"		\
+	"Copyright (C) 2011 by Meika Sugimoto\n"				\
+	"Copyright (C) 2013 by Mitsuhiro Matsuura\n"
+
+#endif	/* TOPPERS_PRC_SYSSVC_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_test.S
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_test.S	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_test.S	(revision 398)
@@ -0,0 +1,58 @@
+;*
+;*  TOPPERS/ASP Kernel
+;*      Toyohashi Open Platform for Embedded Real-Time Systems/
+;*      Advanced Standard Profile Kernel
+;* 
+;*  Copyright (C) 2010 by Witz Corporation, JAPAN
+;* 
+;*  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+;*  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+;*  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+;*  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+;*      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+;*      スコード中に含まれていること．
+;*  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+;*      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+;*      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+;*      の無保証規定を掲載すること．
+;*  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+;*      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+;*      と．
+;*    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+;*        作権表示，この利用条件および下記の無保証規定を掲載すること．
+;*    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+;*        報告すること．
+;*  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+;*      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+;*      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+;*      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+;*      免責すること．
+;* 
+;*  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+;*  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+;*  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+;*  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+;*  の責任を負わない．
+;* 
+;*  @(#) $Id$
+;* 
+
+	.section	P, CODE
+
+	.global	_trigger_cpu_exception
+
+_trigger_cpu_exception:
+	;
+	;  CPU例外の発生
+	;
+	;  ゼロ割り算を行うことで, 浮動小数点例外を
+	;  発生させる.
+	;
+	mvtc	#00001000H, fpsw
+	mov.l	#1, r5
+	fdiv	#0, r5
+	mvtc	#00000000H, fpsw
+	rts
+
+	.end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_test.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_test.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_test.h	(revision 398)
@@ -0,0 +1,52 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		テストプログラムのターゲット依存定義（RX630用）
+ */
+
+#ifndef TOPPERS_PRC_TEST_H
+#define TOPPERS_PRC_TEST_H
+
+#define CPUEXC1					25		/* 浮動小数点例外 */
+#define RAISE_CPU_EXCEPTION		trigger_cpu_exception()
+
+extern void trigger_cpu_exception( void );
+
+#endif /* TOPPERS_PRC_TEST_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_unrename.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_unrename.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/prc_unrename.h	(revision 398)
@@ -0,0 +1,83 @@
+/* This file is generated from prc_rename.def by genrename. */
+
+#ifndef TOPPERS_PRC_RENAME_H
+#define TOPPERS_PRC_RENAME_H
+
+/*
+ *  prc_kernel_impl.c
+ */
+#undef intnest
+#undef lock_flag
+#undef saved_ipl
+#undef prc_initialize
+#undef prc_terminate
+#undef config_int
+#undef default_int_handler
+#undef default_exc_handler
+
+/*
+ *  prc_support.src
+ */
+#undef dispatch
+#undef start_dispatch
+#undef exit_and_dispatch
+#undef call_exit_kernel
+#undef start_r
+#undef interrupt
+#undef exception
+
+/*
+ *  rx630_kernel_impl.c
+ */
+#undef ipr_reg_addr
+#undef ier_reg_addr
+#undef ir_reg_addr
+#undef irqcr_reg_addr
+
+/*
+ *  kernel_cfg.c
+ */
+#undef cfg_int_table
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ *  prc_kernel_impl.c
+ */
+#undef _intnest
+#undef _lock_flag
+#undef _saved_ipl
+#undef _prc_initialize
+#undef _prc_terminate
+#undef _x_config_int
+#undef _default_int_handler
+#undef _default_exc_handler
+
+/*
+ *  prc_support.src
+ */
+#undef _dispatch
+#undef _start_dispatch
+#undef _exit_and_dispatch
+#undef _call_exit_kernel
+#undef _start_r
+#undef _interrupt
+#undef _exception
+
+/*
+ *  rx630_kernel_impl.c
+ */
+#undef _ipr_reg_addr
+#undef _ier_reg_addr
+#undef _ir_reg_addr
+#undef _irqcr_reg_addr
+
+/*
+ *  kernel_cfg.c
+ */
+#undef _cfg_int_table
+
+#endif /* TOPPERS_LABEL_ASM */
+
+
+#endif /* TOPPERS_PRC_RENAME_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/rx630.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/rx630.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/rx630.h	(revision 398)
@@ -0,0 +1,2012 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ *  Copyright (C) 2013      by Mitsuhiro Matsuura
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  RX630に依存する定義
+ */
+#ifndef TOPPERS_RX630_H
+#define TOPPERS_RX630_H
+
+#define __evenaccess
+
+/*
+ *  CPU例外ハンドラ番号の定義(固定ベクタテーブル)
+ *
+ *  番号の範囲は0 - 31
+ */
+#define INT_PRIVILEGED_INSTRUNCTION		20		/* 特権命令例外 */
+#define INT_UNDEF_INSTRUNCTION			23		/* 未定義命令例外 */
+#define INT_FLOATINGPOINT_INSTRUCTION	25		/* 浮動小数点例外 */
+#define INT_NMI							30		/* ノンマスカブル割り込み */
+#define INT_RESET						31		/* リセット */
+
+/*
+ *  割込み番号の定義(可変ベクタテーブル)
+ */
+#define INT_BUSERR			16
+#define INT_FCU_FCUERR		21
+#define INT_FCU_FRDYI		23
+#define INT_ICU_SWINT		27
+#define INT_CMT0_CMI		28
+#define INT_CMT1_CMI		29
+#define INT_CMT2_CMI		30
+#define INT_CMT3_CMI		31
+#define INT_ETH_EINT		32
+#define INT_USB0_D0FIFO0	33
+#define INT_USB0_D1FIFO0	34
+#define INT_USB0_USBI0		35
+#define INT_USB1_D0FIFO1	36
+#define INT_USB1_D1FIFO1	37
+#define INT_USB1_USBI1		38
+#define INT_RSPI0_SPRI0		39
+#define INT_RSPI0_SPTI0		40
+#define INT_RSPI0_SPII0		41
+#define INT_RSPI1_SPRI1		42
+#define INT_RSPI1_SPTI1		43
+#define INT_RSPI1_SPII1		44
+#define INT_RSPI2_SPRI2		45
+#define INT_RSPI2_SPTI2		46
+#define INT_RSPI2_SPII2		47
+#define INT_CAN0_RXF0		48
+#define INT_CAN0_TXF0		49
+#define INT_CAN0_RXM0		50
+#define INT_CAN0_TXM0		51
+#define INT_CAN1_RXF1		52
+#define INT_CAN1_TXF1		53
+#define INT_CAN1_RXM1		54
+#define INT_CAN1_TXM1		55
+#define INT_CAN2_RXF2		56
+#define INT_CAN2_TXF2		57
+#define INT_CAN2_RXM2		58
+#define INT_CAN2_TXM2		59
+#define INT_RTC_CUP			62
+#define INT_IRQ0			64
+#define INT_IRQ1			65
+#define INT_IRQ2			66
+#define INT_IRQ3			67
+#define INT_IRQ4			68
+#define INT_IRQ5			69
+#define INT_IRQ6			70
+#define INT_IRQ7			71
+#define INT_IRQ8			72
+#define INT_IRQ9			73
+#define INT_IRQ10			74
+#define INT_IRQ11			75
+#define INT_IRQ12			76
+#define INT_IRQ13			77
+#define INT_IRQ14			78
+#define INT_IRQ15			79
+#define INT_USB_USBR0		90
+#define INT_USB_USBR1		91
+#define INT_RTC_ALM			92
+#define INT_RTC_PRD			93
+#define INT_AD0_ADI0		98
+#define INT_S12AD_S12ADI0	102
+#define INT_ICU_GROUP0		106
+#define INT_ICU_GROUP1		107
+#define INT_ICU_GROUP2		108
+#define INT_ICU_GROUP3		109
+#define INT_ICU_GROUP4		110
+#define INT_ICU_GROUP5		111
+#define INT_ICU_GROUP6		112
+#define INT_ICU_GROUP12		114
+#define INT_SCI12_SCIX0		122
+#define INT_SCI12_SCIX1		123
+#define INT_SCI12_SCIX2		124
+#define INT_SCI12_SCIX3		125
+#define INT_TPU0_TGI0A		126
+#define INT_TPU0_TGI0B		127
+#define INT_TPU0_TGI0C		128
+#define INT_TPU0_TGI0D		129
+#define INT_TPU1_TGI0A		130
+#define INT_TPU1_TGI0B		131
+#define INT_TPU2_TGI0A		132
+#define INT_TPU2_TGI0B		133
+#define INT_TPU3_TGI0A		134
+#define INT_TPU3_TGI0B		135
+#define INT_TPU3_TGI0C		136
+#define INT_TPU3_TGI0D		137
+#define INT_TPU4_TGI0A		138
+#define INT_TPU4_TGI0B		139
+#define INT_TPU5_TGI0A		140
+#define INT_TPU5_TGI0B		141
+#define INT_MTU0_TGIA0		142
+#define INT_MTU0_TGIB0		143
+#define INT_MTU0_TGIC0		144
+#define INT_MTU0_TGID0		145
+#define INT_MTU0_TCIE0		146
+#define INT_MTU0_TCIF0		147
+#define INT_MTU1_TGIA1		148
+#define INT_MTU1_TGIB1		149
+#define INT_MTU2_TGIA2		150
+#define INT_MTU2_TGIB2		151
+#define INT_MTU3_TGIA3		152
+#define INT_MTU3_TGIB3		153
+#define INT_MTU3_TGIC3		154
+#define INT_MTU3_TGID3		155
+#define INT_MTU4_TGIA4		156
+#define INT_MTU4_TGIB4		157
+#define INT_MTU4_TGIC4		158
+#define INT_MTU4_TGID4		159
+#define INT_MTU4_TCIV4		160
+#define INT_MTU5_TGIU5		161
+#define INT_MTU5_TGIV5		162
+#define INT_MTU5_TGIW5		163
+#define INT_MTU5_TGI11A		164
+#define INT_MTU5_TGI11B		165
+#define INT_POE_OEI1		166
+#define INT_POE_OEI2		167
+#define INT_TMR0_CMI0A		170
+#define INT_TMR0_CMI0B		171
+#define INT_TMR0_OV0I		172
+#define INT_TMR1_CMI1A		173
+#define INT_TMR1_CMI1B		174
+#define INT_TMR1_OV1I		175
+#define INT_TMR2_CMI2A		176
+#define INT_TMR2_CMI2B		177
+#define INT_TMR2_OV2I		178
+#define INT_TMR3_CMI3A		179
+#define INT_TMR3_CMI3B		180
+#define INT_TMR3_OV3I		181
+#define INT_RIIC0_EEI		182
+#define INT_RIIC0_RXI		183
+#define INT_RIIC0_TXI		184
+#define INT_RIIC0_TEI		185
+#define INT_RIIC1_EEI		186
+#define INT_RIIC1_RXI		187
+#define INT_RIIC1_TXI		188
+#define INT_RIIC1_TEI		189
+#define INT_RIIC2_EEI		190
+#define INT_RIIC2_RXI		191
+#define INT_RIIC2_TXI		192
+#define INT_RIIC2_TEI		193
+#define INT_RIIC3_EEI		194
+#define INT_RIIC3_RXI		195
+#define INT_RIIC3_TXI		196
+#define INT_RIIC3_TEI		197
+#define INT_DMAC_DMAC0I		198
+#define INT_DMAC_DMAC1I		199
+#define INT_DMAC_DMAC2I		200
+#define INT_DMAC_DMAC3I		201
+#define INT_SCI0_RXI		214
+#define INT_SCI0_TXI		215
+#define INT_SCI0_TEI		216
+#define INT_SCI1_RXI		217
+#define INT_SCI1_TXI		218
+#define INT_SCI1_TEI		219
+#define INT_SCI2_RXI		220
+#define INT_SCI2_TXI		221
+#define INT_SCI2_TEI		222
+#define INT_SCI3_RXI		223
+#define INT_SCI3_TXI		224
+#define INT_SCI3_TEI		225
+#define INT_SCI4_RXI		226
+#define INT_SCI4_TXI		227
+#define INT_SCI4_TEI		228
+#define INT_SCI5_RXI		229
+#define INT_SCI5_TXI		230
+#define INT_SCI5_TEI		231
+#define INT_SCI6_RXI		232
+#define INT_SCI6_TXI		233
+#define INT_SCI6_TEI		234
+#define INT_SCI7_RXI		235
+#define INT_SCI7_TXI		236
+#define INT_SCI7_TEI		237
+#define INT_SCI8_RXI		238
+#define INT_SCI8_TXI		239
+#define INT_SCI8_TEI		240
+#define INT_SCI9_RXI		241
+#define INT_SCI9_TXI		242
+#define INT_SCI9_TEI		243
+#define INT_SCI10_RXI		244
+#define INT_SCI10_TXI		245
+#define INT_SCI10_TEI		246
+#define INT_SCI11_RXI		247
+#define INT_SCI11_TXI		248
+#define INT_SCI11_TEI		249
+#define INT_SCI12_RXI		250
+#define INT_SCI12_TXI		251
+#define INT_SCI12_TEI		252
+#define INT_IEB_IEBINT		253
+
+/*
+ *  各モジュールのレジスタ及び設定ビット情報
+ */
+
+#define SYSTEM_SYSCR0_ADDR		( ( volatile uint16_t __evenaccess * )0x00080006 )
+
+/*
+ * モジュールストップコントロールレジスタA（MSTPCRA）
+ */
+#define SYSTEM_MSTPCRA_ADDR			( ( volatile uint32_t __evenaccess * )0x00080010 )
+#define SYSTEM_MSTPCRA_MSTPA0_BIT	( 1UL << 0U )
+#define SYSTEM_MSTPCRA_MSTPA1_BIT	( 1UL << 1U )
+#define SYSTEM_MSTPCRA_MSTPA2_BIT	( 1UL << 2U )
+#define SYSTEM_MSTPCRA_MSTPA3_BIT	( 1UL << 3U )
+#define SYSTEM_MSTPCRA_MSTPA4_BIT	( 1UL << 4U )
+#define SYSTEM_MSTPCRA_MSTPA5_BIT	( 1UL << 5U )
+#define SYSTEM_MSTPCRA_MSTPA6_BIT	( 1UL << 6U )
+#define SYSTEM_MSTPCRA_MSTPA7_BIT	( 1UL << 7U )
+#define SYSTEM_MSTPCRA_MSTPA8_BIT	( 1UL << 8U )
+#define SYSTEM_MSTPCRA_MSTPA9_BIT	( 1UL << 9U )
+#define SYSTEM_MSTPCRA_MSTPA10_BIT	( 1UL << 10U )
+#define SYSTEM_MSTPCRA_MSTPA11_BIT	( 1UL << 11U )
+#define SYSTEM_MSTPCRA_MSTPA12_BIT	( 1UL << 12U )
+#define SYSTEM_MSTPCRA_MSTPA13_BIT	( 1UL << 13U )
+#define SYSTEM_MSTPCRA_MSTPA14_BIT	( 1UL << 14U )
+#define SYSTEM_MSTPCRA_MSTPA15_BIT	( 1UL << 15U )
+#define SYSTEM_MSTPCRA_MSTPA16_BIT	( 1UL << 16U )
+#define SYSTEM_MSTPCRA_MSTPA17_BIT	( 1UL << 17U )
+#define SYSTEM_MSTPCRA_MSTPA18_BIT	( 1UL << 18U )
+#define SYSTEM_MSTPCRA_MSTPA19_BIT	( 1UL << 19U )
+#define SYSTEM_MSTPCRA_MSTPA20_BIT	( 1UL << 20U )
+#define SYSTEM_MSTPCRA_MSTPA21_BIT	( 1UL << 21U )
+#define SYSTEM_MSTPCRA_MSTPA22_BIT	( 1UL << 22U )
+#define SYSTEM_MSTPCRA_MSTPA23_BIT	( 1UL << 23U )
+#define SYSTEM_MSTPCRA_MSTPA24_BIT	( 1UL << 24U )
+#define SYSTEM_MSTPCRA_MSTPA25_BIT	( 1UL << 25U )
+#define SYSTEM_MSTPCRA_MSTPA26_BIT	( 1UL << 26U )
+#define SYSTEM_MSTPCRA_MSTPA27_BIT	( 1UL << 27U )
+#define SYSTEM_MSTPCRA_MSTPA28_BIT	( 1UL << 28U )
+#define SYSTEM_MSTPCRA_MSTPA29_BIT	( 1UL << 29U )
+#define SYSTEM_MSTPCRA_MSTPA30_BIT	( 1UL << 30U )
+#define SYSTEM_MSTPCRA_MSTPA31_BIT	( 1UL << 31U )
+#define SYSTEM_MSTPCRA_ACSE_BIT		( 1UL << 31U)
+
+/*
+ * モジュールストップコントロールレジスタB（MSTPCRB）
+ */
+#define SYSTEM_MSTPCRB_ADDR			( ( volatile uint32_t __evenaccess * )0x00080014 )
+#define SYSTEM_MSTPCRB_MSTPB0_BIT	( 1UL << 0U )
+#define SYSTEM_MSTPCRB_MSTPB1_BIT	( 1UL << 1U )
+#define SYSTEM_MSTPCRB_MSTPB2_BIT	( 1UL << 2U )
+#define SYSTEM_MSTPCRB_MSTPB3_BIT	( 1UL << 3U )
+#define SYSTEM_MSTPCRB_MSTPB4_BIT	( 1UL << 4U )
+#define SYSTEM_MSTPCRB_MSTPB5_BIT	( 1UL << 5U )
+#define SYSTEM_MSTPCRB_MSTPB6_BIT	( 1UL << 6U )
+#define SYSTEM_MSTPCRB_MSTPB7_BIT	( 1UL << 7U )
+#define SYSTEM_MSTPCRB_MSTPB8_BIT	( 1UL << 8U )
+#define SYSTEM_MSTPCRB_MSTPB9_BIT	( 1UL << 9U )
+#define SYSTEM_MSTPCRB_MSTPB10_BIT	( 1UL << 10U )
+#define SYSTEM_MSTPCRB_MSTPB11_BIT	( 1UL << 11U )
+#define SYSTEM_MSTPCRB_MSTPB12_BIT	( 1UL << 12U )
+#define SYSTEM_MSTPCRB_MSTPB13_BIT	( 1UL << 13U )
+#define SYSTEM_MSTPCRB_MSTPB14_BIT	( 1UL << 14U )
+#define SYSTEM_MSTPCRB_MSTPB15_BIT	( 1UL << 15U )
+#define SYSTEM_MSTPCRB_MSTPB16_BIT	( 1UL << 16U )
+#define SYSTEM_MSTPCRB_MSTPB17_BIT	( 1UL << 17U )
+#define SYSTEM_MSTPCRB_MSTPB18_BIT	( 1UL << 18U )
+#define SYSTEM_MSTPCRB_MSTPB19_BIT	( 1UL << 19U )
+#define SYSTEM_MSTPCRB_MSTPB20_BIT	( 1UL << 20U )
+#define SYSTEM_MSTPCRB_MSTPB21_BIT	( 1UL << 21U )
+#define SYSTEM_MSTPCRB_MSTPB22_BIT	( 1UL << 22U )
+#define SYSTEM_MSTPCRB_MSTPB23_BIT	( 1UL << 23U )
+#define SYSTEM_MSTPCRB_MSTPB24_BIT	( 1UL << 24U )
+#define SYSTEM_MSTPCRB_MSTPB25_BIT	( 1UL << 25U )
+#define SYSTEM_MSTPCRB_MSTPB26_BIT	( 1UL << 26U )
+#define SYSTEM_MSTPCRB_MSTPB27_BIT	( 1UL << 27U )
+#define SYSTEM_MSTPCRB_MSTPB28_BIT	( 1UL << 28U )
+#define SYSTEM_MSTPCRB_MSTPB29_BIT	( 1UL << 29U )
+#define SYSTEM_MSTPCRB_MSTPB30_BIT	( 1UL << 30U )
+#define SYSTEM_MSTPCRB_MSTPB31_BIT	( 1UL << 31U )
+
+/*
+ * モジュールストップコントロールレジスタC（MSTPCRC）
+ */
+#define SYSTEM_MSTPCRC_ADDR			( ( volatile uint32_t __evenaccess * )0x00080018 )
+#define SYSTEM_MSTPCRC_MSTPC0_BIT	( 1UL << 0U )
+#define SYSTEM_MSTPCRC_MSTPC1_BIT	( 1UL << 1U )
+#define SYSTEM_MSTPCRC_MSTPC2_BIT	( 1UL << 2U )
+#define SYSTEM_MSTPCRC_MSTPC3_BIT	( 1UL << 3U )
+#define SYSTEM_MSTPCRC_MSTPC4_BIT	( 1UL << 4U )
+#define SYSTEM_MSTPCRC_MSTPC5_BIT	( 1UL << 5U )
+#define SYSTEM_MSTPCRC_MSTPC6_BIT	( 1UL << 6U )
+#define SYSTEM_MSTPCRC_MSTPC7_BIT	( 1UL << 7U )
+#define SYSTEM_MSTPCRC_MSTPC8_BIT	( 1UL << 8U )
+#define SYSTEM_MSTPCRC_MSTPC9_BIT	( 1UL << 9U )
+#define SYSTEM_MSTPCRC_MSTPC10_BIT	( 1UL << 10U )
+#define SYSTEM_MSTPCRC_MSTPC11_BIT	( 1UL << 11U )
+#define SYSTEM_MSTPCRC_MSTPC12_BIT	( 1UL << 12U )
+#define SYSTEM_MSTPCRC_MSTPC13_BIT	( 1UL << 13U )
+#define SYSTEM_MSTPCRC_MSTPC14_BIT	( 1UL << 14U )
+#define SYSTEM_MSTPCRC_MSTPC15_BIT	( 1UL << 15U )
+#define SYSTEM_MSTPCRC_MSTPC16_BIT	( 1UL << 16U )
+#define SYSTEM_MSTPCRC_MSTPC17_BIT	( 1UL << 17U )
+#define SYSTEM_MSTPCRC_MSTPC18_BIT	( 1UL << 18U )
+#define SYSTEM_MSTPCRC_MSTPC19_BIT	( 1UL << 19U )
+#define SYSTEM_MSTPCRC_MSTPC20_BIT	( 1UL << 20U )
+#define SYSTEM_MSTPCRC_MSTPC21_BIT	( 1UL << 21U )
+#define SYSTEM_MSTPCRC_MSTPC22_BIT	( 1UL << 22U )
+#define SYSTEM_MSTPCRC_MSTPC23_BIT	( 1UL << 23U )
+#define SYSTEM_MSTPCRC_MSTPC24_BIT	( 1UL << 24U )
+#define SYSTEM_MSTPCRC_MSTPC25_BIT	( 1UL << 25U )
+#define SYSTEM_MSTPCRC_MSTPC26_BIT	( 1UL << 26U )
+#define SYSTEM_MSTPCRC_MSTPC27_BIT	( 1UL << 27U )
+#define SYSTEM_MSTPCRC_MSTPC28_BIT	( 1UL << 28U )
+#define SYSTEM_MSTPCRC_MSTPC29_BIT	( 1UL << 29U )
+#define SYSTEM_MSTPCRC_MSTPC30_BIT	( 1UL << 30U )
+#define SYSTEM_MSTPCRC_MSTPC31_BIT	( 1UL << 31U )
+
+/*
+ * クロック発生回路
+ */
+#define SYSTEM_SCKCR_ADDR			( ( volatile uint32_t __evenaccess * )0x00080020 )
+#define SYSTEM_SCKCR2_ADDR		( ( volatile uint16_t __evenaccess * )0x00080024 )
+#define SYSTEM_SCKCR2_UCK_OFFSET	( 4U )
+#define SYSTEM_SCKCR2_UCK_MASK		( 0xFU << SYSTEM_SCKCR2_UCK_OFFSET )
+#define SYSTEM_SCKCR3_ADDR		( ( volatile uint16_t __evenaccess * )0x00080026 )
+#define SYSTEM_SCKCR3_CKSEL_OFFSET	( 8U )
+#define SYSTEM_SCKCR3_CKSEL_MASK	( 0x7U << SYSTEM_SCKCR3_CKSEL_OFFSET )
+#define SYSTEM_PLLCR_ADDR		( ( volatile uint16_t __evenaccess * )0x00080028 )
+#define SYSTEM_PLLCR_STC_OFFSET		( 8U )
+#define SYSTEM_PLLCR_STC_MASK		( 0x3FU << SYSTEM_PLLCR_STC_OFFSET )
+#define SYSTEM_PLLCR2_ADDR			( ( volatile uint8_t __evenaccess * )0x0008002A )
+#define SYSTEM_PLLCR2_PLLEN			( 1UL << 0U )
+#define SYSTEM_MOFCR_ADDR		( ( volatile uint8_t __evenaccess * )0x0008C293 )
+#define SYSTEM_MOFCR_MOFXIN		( 1UL << 0U )
+#define SYSTEM_MOSCCR_ADDR			( ( volatile uint8_t __evenaccess * )0x00080032 )
+#define SYSTEM_MOSCCR_MOSTP			( 1UL << 0U )
+
+/*
+ * プロテクトレジスタ
+ */
+#define SYSTEM_PRCR_ADDR		( ( volatile uint16_t __evenaccess * )0x000803FE )
+
+/*
+ * 割り込み要求レジスタ
+ */
+#define ICU_IR000_ADDR			( ( volatile uint8_t __evenaccess * )0x00087000 )
+#define ICU_IR001_ADDR			( ( volatile uint8_t __evenaccess * )0x00087001 )
+#define ICU_IR002_ADDR			( ( volatile uint8_t __evenaccess * )0x00087002 )
+#define ICU_IR003_ADDR			( ( volatile uint8_t __evenaccess * )0x00087003 )
+#define ICU_IR004_ADDR			( ( volatile uint8_t __evenaccess * )0x00087004 )
+#define ICU_IR005_ADDR			( ( volatile uint8_t __evenaccess * )0x00087005 )
+#define ICU_IR006_ADDR			( ( volatile uint8_t __evenaccess * )0x00087006 )
+#define ICU_IR007_ADDR			( ( volatile uint8_t __evenaccess * )0x00087007 )
+#define ICU_IR008_ADDR			( ( volatile uint8_t __evenaccess * )0x00087008 )
+#define ICU_IR009_ADDR			( ( volatile uint8_t __evenaccess * )0x00087009 )
+#define ICU_IR010_ADDR			( ( volatile uint8_t __evenaccess * )0x0008700A )
+#define ICU_IR011_ADDR			( ( volatile uint8_t __evenaccess * )0x0008700B )
+#define ICU_IR012_ADDR			( ( volatile uint8_t __evenaccess * )0x0008700C )
+#define ICU_IR013_ADDR			( ( volatile uint8_t __evenaccess * )0x0008700D )
+#define ICU_IR014_ADDR			( ( volatile uint8_t __evenaccess * )0x0008700E )
+#define ICU_IR015_ADDR			( ( volatile uint8_t __evenaccess * )0x0008700F )
+#define ICU_IR016_ADDR			( ( volatile uint8_t __evenaccess * )0x00087010 )
+#define ICU_IR017_ADDR			( ( volatile uint8_t __evenaccess * )0x00087011 )
+#define ICU_IR018_ADDR			( ( volatile uint8_t __evenaccess * )0x00087012 )
+#define ICU_IR019_ADDR			( ( volatile uint8_t __evenaccess * )0x00087013 )
+#define ICU_IR020_ADDR			( ( volatile uint8_t __evenaccess * )0x00087014 )
+#define ICU_IR021_ADDR			( ( volatile uint8_t __evenaccess * )0x00087015 )
+#define ICU_IR022_ADDR			( ( volatile uint8_t __evenaccess * )0x00087016 )
+#define ICU_IR023_ADDR			( ( volatile uint8_t __evenaccess * )0x00087017 )
+#define ICU_IR024_ADDR			( ( volatile uint8_t __evenaccess * )0x00087018 )
+#define ICU_IR025_ADDR			( ( volatile uint8_t __evenaccess * )0x00087019 )
+#define ICU_IR026_ADDR			( ( volatile uint8_t __evenaccess * )0x0008701A )
+#define ICU_IR027_ADDR			( ( volatile uint8_t __evenaccess * )0x0008701B )
+#define ICU_IR028_ADDR			( ( volatile uint8_t __evenaccess * )0x0008701C )
+#define ICU_IR029_ADDR			( ( volatile uint8_t __evenaccess * )0x0008701D )
+#define ICU_IR030_ADDR			( ( volatile uint8_t __evenaccess * )0x0008701E )
+#define ICU_IR031_ADDR			( ( volatile uint8_t __evenaccess * )0x0008701F )
+#define ICU_IR032_ADDR			( ( volatile uint8_t __evenaccess * )0x00087020 )
+#define ICU_IR033_ADDR			( ( volatile uint8_t __evenaccess * )0x00087021 )
+#define ICU_IR034_ADDR			( ( volatile uint8_t __evenaccess * )0x00087022 )
+#define ICU_IR035_ADDR			( ( volatile uint8_t __evenaccess * )0x00087023 )
+#define ICU_IR036_ADDR			( ( volatile uint8_t __evenaccess * )0x00087024 )
+#define ICU_IR037_ADDR			( ( volatile uint8_t __evenaccess * )0x00087025 )
+#define ICU_IR038_ADDR			( ( volatile uint8_t __evenaccess * )0x00087026 )
+#define ICU_IR039_ADDR			( ( volatile uint8_t __evenaccess * )0x00087027 )
+#define ICU_IR040_ADDR			( ( volatile uint8_t __evenaccess * )0x00087028 )
+#define ICU_IR041_ADDR			( ( volatile uint8_t __evenaccess * )0x00087029 )
+#define ICU_IR042_ADDR			( ( volatile uint8_t __evenaccess * )0x0008702A )
+#define ICU_IR043_ADDR			( ( volatile uint8_t __evenaccess * )0x0008702B )
+#define ICU_IR044_ADDR			( ( volatile uint8_t __evenaccess * )0x0008702C )
+#define ICU_IR045_ADDR			( ( volatile uint8_t __evenaccess * )0x0008702D )
+#define ICU_IR046_ADDR			( ( volatile uint8_t __evenaccess * )0x0008702E )
+#define ICU_IR047_ADDR			( ( volatile uint8_t __evenaccess * )0x0008702F )
+#define ICU_IR048_ADDR			( ( volatile uint8_t __evenaccess * )0x00087030 )
+#define ICU_IR049_ADDR			( ( volatile uint8_t __evenaccess * )0x00087031 )
+#define ICU_IR050_ADDR			( ( volatile uint8_t __evenaccess * )0x00087032 )
+#define ICU_IR051_ADDR			( ( volatile uint8_t __evenaccess * )0x00087033 )
+#define ICU_IR052_ADDR			( ( volatile uint8_t __evenaccess * )0x00087034 )
+#define ICU_IR053_ADDR			( ( volatile uint8_t __evenaccess * )0x00087035 )
+#define ICU_IR054_ADDR			( ( volatile uint8_t __evenaccess * )0x00087036 )
+#define ICU_IR055_ADDR			( ( volatile uint8_t __evenaccess * )0x00087037 )
+#define ICU_IR056_ADDR			( ( volatile uint8_t __evenaccess * )0x00087038 )
+#define ICU_IR057_ADDR			( ( volatile uint8_t __evenaccess * )0x00087039 )
+#define ICU_IR058_ADDR			( ( volatile uint8_t __evenaccess * )0x0008703A )
+#define ICU_IR059_ADDR			( ( volatile uint8_t __evenaccess * )0x0008703B )
+#define ICU_IR060_ADDR			( ( volatile uint8_t __evenaccess * )0x0008703C )
+#define ICU_IR061_ADDR			( ( volatile uint8_t __evenaccess * )0x0008703D )
+#define ICU_IR062_ADDR			( ( volatile uint8_t __evenaccess * )0x0008703E )
+#define ICU_IR063_ADDR			( ( volatile uint8_t __evenaccess * )0x0008703F )
+#define ICU_IR064_ADDR			( ( volatile uint8_t __evenaccess * )0x00087040 )
+#define ICU_IR065_ADDR			( ( volatile uint8_t __evenaccess * )0x00087041 )
+#define ICU_IR066_ADDR			( ( volatile uint8_t __evenaccess * )0x00087042 )
+#define ICU_IR067_ADDR			( ( volatile uint8_t __evenaccess * )0x00087043 )
+#define ICU_IR068_ADDR			( ( volatile uint8_t __evenaccess * )0x00087044 )
+#define ICU_IR069_ADDR			( ( volatile uint8_t __evenaccess * )0x00087045 )
+#define ICU_IR070_ADDR			( ( volatile uint8_t __evenaccess * )0x00087046 )
+#define ICU_IR071_ADDR			( ( volatile uint8_t __evenaccess * )0x00087047 )
+#define ICU_IR072_ADDR			( ( volatile uint8_t __evenaccess * )0x00087048 )
+#define ICU_IR073_ADDR			( ( volatile uint8_t __evenaccess * )0x00087049 )
+#define ICU_IR074_ADDR			( ( volatile uint8_t __evenaccess * )0x0008704A )
+#define ICU_IR075_ADDR			( ( volatile uint8_t __evenaccess * )0x0008704B )
+#define ICU_IR076_ADDR			( ( volatile uint8_t __evenaccess * )0x0008704C )
+#define ICU_IR077_ADDR			( ( volatile uint8_t __evenaccess * )0x0008704D )
+#define ICU_IR078_ADDR			( ( volatile uint8_t __evenaccess * )0x0008704E )
+#define ICU_IR079_ADDR			( ( volatile uint8_t __evenaccess * )0x0008704F )
+#define ICU_IR080_ADDR			( ( volatile uint8_t __evenaccess * )0x00087050 )
+#define ICU_IR081_ADDR			( ( volatile uint8_t __evenaccess * )0x00087051 )
+#define ICU_IR082_ADDR			( ( volatile uint8_t __evenaccess * )0x00087052 )
+#define ICU_IR083_ADDR			( ( volatile uint8_t __evenaccess * )0x00087053 )
+#define ICU_IR084_ADDR			( ( volatile uint8_t __evenaccess * )0x00087054 )
+#define ICU_IR085_ADDR			( ( volatile uint8_t __evenaccess * )0x00087055 )
+#define ICU_IR086_ADDR			( ( volatile uint8_t __evenaccess * )0x00087056 )
+#define ICU_IR087_ADDR			( ( volatile uint8_t __evenaccess * )0x00087057 )
+#define ICU_IR088_ADDR			( ( volatile uint8_t __evenaccess * )0x00087058 )
+#define ICU_IR089_ADDR			( ( volatile uint8_t __evenaccess * )0x00087059 )
+#define ICU_IR090_ADDR			( ( volatile uint8_t __evenaccess * )0x0008705A )
+#define ICU_IR091_ADDR			( ( volatile uint8_t __evenaccess * )0x0008705B )
+#define ICU_IR092_ADDR			( ( volatile uint8_t __evenaccess * )0x0008705C )
+#define ICU_IR093_ADDR			( ( volatile uint8_t __evenaccess * )0x0008705D )
+#define ICU_IR094_ADDR			( ( volatile uint8_t __evenaccess * )0x0008705E )
+#define ICU_IR095_ADDR			( ( volatile uint8_t __evenaccess * )0x0008705F )
+#define ICU_IR096_ADDR			( ( volatile uint8_t __evenaccess * )0x00087060 )
+#define ICU_IR097_ADDR			( ( volatile uint8_t __evenaccess * )0x00087061 )
+#define ICU_IR098_ADDR			( ( volatile uint8_t __evenaccess * )0x00087062 )
+#define ICU_IR099_ADDR			( ( volatile uint8_t __evenaccess * )0x00087063 )
+#define ICU_IR100_ADDR			( ( volatile uint8_t __evenaccess * )0x00087064 )
+#define ICU_IR101_ADDR			( ( volatile uint8_t __evenaccess * )0x00087065 )
+#define ICU_IR102_ADDR			( ( volatile uint8_t __evenaccess * )0x00087066 )
+#define ICU_IR103_ADDR			( ( volatile uint8_t __evenaccess * )0x00087067 )
+#define ICU_IR104_ADDR			( ( volatile uint8_t __evenaccess * )0x00087068 )
+#define ICU_IR105_ADDR			( ( volatile uint8_t __evenaccess * )0x00087069 )
+#define ICU_IR106_ADDR			( ( volatile uint8_t __evenaccess * )0x0008706A )
+#define ICU_IR107_ADDR			( ( volatile uint8_t __evenaccess * )0x0008706B )
+#define ICU_IR108_ADDR			( ( volatile uint8_t __evenaccess * )0x0008706C )
+#define ICU_IR109_ADDR			( ( volatile uint8_t __evenaccess * )0x0008706D )
+#define ICU_IR110_ADDR			( ( volatile uint8_t __evenaccess * )0x0008706E )
+#define ICU_IR111_ADDR			( ( volatile uint8_t __evenaccess * )0x0008706F )
+#define ICU_IR112_ADDR			( ( volatile uint8_t __evenaccess * )0x00087070 )
+#define ICU_IR113_ADDR			( ( volatile uint8_t __evenaccess * )0x00087071 )
+#define ICU_IR114_ADDR			( ( volatile uint8_t __evenaccess * )0x00087072 )
+#define ICU_IR115_ADDR			( ( volatile uint8_t __evenaccess * )0x00087073 )
+#define ICU_IR116_ADDR			( ( volatile uint8_t __evenaccess * )0x00087074 )
+#define ICU_IR117_ADDR			( ( volatile uint8_t __evenaccess * )0x00087075 )
+#define ICU_IR118_ADDR			( ( volatile uint8_t __evenaccess * )0x00087076 )
+#define ICU_IR119_ADDR			( ( volatile uint8_t __evenaccess * )0x00087077 )
+#define ICU_IR120_ADDR			( ( volatile uint8_t __evenaccess * )0x00087078 )
+#define ICU_IR121_ADDR			( ( volatile uint8_t __evenaccess * )0x00087079 )
+#define ICU_IR122_ADDR			( ( volatile uint8_t __evenaccess * )0x0008707A )
+#define ICU_IR123_ADDR			( ( volatile uint8_t __evenaccess * )0x0008707B )
+#define ICU_IR124_ADDR			( ( volatile uint8_t __evenaccess * )0x0008707C )
+#define ICU_IR125_ADDR			( ( volatile uint8_t __evenaccess * )0x0008707D )
+#define ICU_IR126_ADDR			( ( volatile uint8_t __evenaccess * )0x0008707E )
+#define ICU_IR127_ADDR			( ( volatile uint8_t __evenaccess * )0x0008707F )
+#define ICU_IR128_ADDR			( ( volatile uint8_t __evenaccess * )0x00087080 )
+#define ICU_IR129_ADDR			( ( volatile uint8_t __evenaccess * )0x00087081 )
+#define ICU_IR130_ADDR			( ( volatile uint8_t __evenaccess * )0x00087082 )
+#define ICU_IR131_ADDR			( ( volatile uint8_t __evenaccess * )0x00087083 )
+#define ICU_IR132_ADDR			( ( volatile uint8_t __evenaccess * )0x00087084 )
+#define ICU_IR133_ADDR			( ( volatile uint8_t __evenaccess * )0x00087085 )
+#define ICU_IR134_ADDR			( ( volatile uint8_t __evenaccess * )0x00087086 )
+#define ICU_IR135_ADDR			( ( volatile uint8_t __evenaccess * )0x00087087 )
+#define ICU_IR136_ADDR			( ( volatile uint8_t __evenaccess * )0x00087088 )
+#define ICU_IR137_ADDR			( ( volatile uint8_t __evenaccess * )0x00087089 )
+#define ICU_IR138_ADDR			( ( volatile uint8_t __evenaccess * )0x0008708A )
+#define ICU_IR139_ADDR			( ( volatile uint8_t __evenaccess * )0x0008708B )
+#define ICU_IR140_ADDR			( ( volatile uint8_t __evenaccess * )0x0008708C )
+#define ICU_IR141_ADDR			( ( volatile uint8_t __evenaccess * )0x0008708D )
+#define ICU_IR142_ADDR			( ( volatile uint8_t __evenaccess * )0x0008708E )
+#define ICU_IR143_ADDR			( ( volatile uint8_t __evenaccess * )0x0008708F )
+#define ICU_IR144_ADDR			( ( volatile uint8_t __evenaccess * )0x00087090 )
+#define ICU_IR145_ADDR			( ( volatile uint8_t __evenaccess * )0x00087091 )
+#define ICU_IR146_ADDR			( ( volatile uint8_t __evenaccess * )0x00087092 )
+#define ICU_IR147_ADDR			( ( volatile uint8_t __evenaccess * )0x00087093 )
+#define ICU_IR148_ADDR			( ( volatile uint8_t __evenaccess * )0x00087094 )
+#define ICU_IR149_ADDR			( ( volatile uint8_t __evenaccess * )0x00087095 )
+#define ICU_IR150_ADDR			( ( volatile uint8_t __evenaccess * )0x00087096 )
+#define ICU_IR151_ADDR			( ( volatile uint8_t __evenaccess * )0x00087097 )
+#define ICU_IR152_ADDR			( ( volatile uint8_t __evenaccess * )0x00087098 )
+#define ICU_IR153_ADDR			( ( volatile uint8_t __evenaccess * )0x00087099 )
+#define ICU_IR154_ADDR			( ( volatile uint8_t __evenaccess * )0x0008709A )
+#define ICU_IR155_ADDR			( ( volatile uint8_t __evenaccess * )0x0008709B )
+#define ICU_IR156_ADDR			( ( volatile uint8_t __evenaccess * )0x0008709C )
+#define ICU_IR157_ADDR			( ( volatile uint8_t __evenaccess * )0x0008709D )
+#define ICU_IR158_ADDR			( ( volatile uint8_t __evenaccess * )0x0008709E )
+#define ICU_IR159_ADDR			( ( volatile uint8_t __evenaccess * )0x0008709F )
+#define ICU_IR160_ADDR			( ( volatile uint8_t __evenaccess * )0x000870A0 )
+#define ICU_IR161_ADDR			( ( volatile uint8_t __evenaccess * )0x000870A1 )
+#define ICU_IR162_ADDR			( ( volatile uint8_t __evenaccess * )0x000870A2 )
+#define ICU_IR163_ADDR			( ( volatile uint8_t __evenaccess * )0x000870A3 )
+#define ICU_IR164_ADDR			( ( volatile uint8_t __evenaccess * )0x000870A4 )
+#define ICU_IR165_ADDR			( ( volatile uint8_t __evenaccess * )0x000870A5 )
+#define ICU_IR166_ADDR			( ( volatile uint8_t __evenaccess * )0x000870A6 )
+#define ICU_IR167_ADDR			( ( volatile uint8_t __evenaccess * )0x000870A7 )
+#define ICU_IR168_ADDR			( ( volatile uint8_t __evenaccess * )0x000870A8 )
+#define ICU_IR169_ADDR			( ( volatile uint8_t __evenaccess * )0x000870A9 )
+#define ICU_IR170_ADDR			( ( volatile uint8_t __evenaccess * )0x000870AA )
+#define ICU_IR171_ADDR			( ( volatile uint8_t __evenaccess * )0x000870AB )
+#define ICU_IR172_ADDR			( ( volatile uint8_t __evenaccess * )0x000870AC )
+#define ICU_IR173_ADDR			( ( volatile uint8_t __evenaccess * )0x000870AD )
+#define ICU_IR174_ADDR			( ( volatile uint8_t __evenaccess * )0x000870AE )
+#define ICU_IR175_ADDR			( ( volatile uint8_t __evenaccess * )0x000870AF )
+#define ICU_IR176_ADDR			( ( volatile uint8_t __evenaccess * )0x000870B0 )
+#define ICU_IR177_ADDR			( ( volatile uint8_t __evenaccess * )0x000870B1 )
+#define ICU_IR178_ADDR			( ( volatile uint8_t __evenaccess * )0x000870B2 )
+#define ICU_IR179_ADDR			( ( volatile uint8_t __evenaccess * )0x000870B3 )
+#define ICU_IR180_ADDR			( ( volatile uint8_t __evenaccess * )0x000870B4 )
+#define ICU_IR181_ADDR			( ( volatile uint8_t __evenaccess * )0x000870B5 )
+#define ICU_IR182_ADDR			( ( volatile uint8_t __evenaccess * )0x000870B6 )
+#define ICU_IR183_ADDR			( ( volatile uint8_t __evenaccess * )0x000870B7 )
+#define ICU_IR184_ADDR			( ( volatile uint8_t __evenaccess * )0x000870B8 )
+#define ICU_IR185_ADDR			( ( volatile uint8_t __evenaccess * )0x000870B9 )
+#define ICU_IR186_ADDR			( ( volatile uint8_t __evenaccess * )0x000870BA )
+#define ICU_IR187_ADDR			( ( volatile uint8_t __evenaccess * )0x000870BB )
+#define ICU_IR188_ADDR			( ( volatile uint8_t __evenaccess * )0x000870BC )
+#define ICU_IR189_ADDR			( ( volatile uint8_t __evenaccess * )0x000870BD )
+#define ICU_IR190_ADDR			( ( volatile uint8_t __evenaccess * )0x000870BE )
+#define ICU_IR191_ADDR			( ( volatile uint8_t __evenaccess * )0x000870BF )
+#define ICU_IR192_ADDR			( ( volatile uint8_t __evenaccess * )0x000870C0 )
+#define ICU_IR193_ADDR			( ( volatile uint8_t __evenaccess * )0x000870C1 )
+#define ICU_IR194_ADDR			( ( volatile uint8_t __evenaccess * )0x000870C2 )
+#define ICU_IR195_ADDR			( ( volatile uint8_t __evenaccess * )0x000870C3 )
+#define ICU_IR196_ADDR			( ( volatile uint8_t __evenaccess * )0x000870C4 )
+#define ICU_IR197_ADDR			( ( volatile uint8_t __evenaccess * )0x000870C5 )
+#define ICU_IR198_ADDR			( ( volatile uint8_t __evenaccess * )0x000870C6 )
+#define ICU_IR199_ADDR			( ( volatile uint8_t __evenaccess * )0x000870C7 )
+#define ICU_IR200_ADDR			( ( volatile uint8_t __evenaccess * )0x000870C8 )
+#define ICU_IR201_ADDR			( ( volatile uint8_t __evenaccess * )0x000870C9 )
+#define ICU_IR202_ADDR			( ( volatile uint8_t __evenaccess * )0x000870CA )
+#define ICU_IR203_ADDR			( ( volatile uint8_t __evenaccess * )0x000870CB )
+#define ICU_IR204_ADDR			( ( volatile uint8_t __evenaccess * )0x000870CC )
+#define ICU_IR205_ADDR			( ( volatile uint8_t __evenaccess * )0x000870CD )
+#define ICU_IR206_ADDR			( ( volatile uint8_t __evenaccess * )0x000870CE )
+#define ICU_IR207_ADDR			( ( volatile uint8_t __evenaccess * )0x000870CF )
+#define ICU_IR208_ADDR			( ( volatile uint8_t __evenaccess * )0x000870D0 )
+#define ICU_IR209_ADDR			( ( volatile uint8_t __evenaccess * )0x000870D1 )
+#define ICU_IR210_ADDR			( ( volatile uint8_t __evenaccess * )0x000870D2 )
+#define ICU_IR211_ADDR			( ( volatile uint8_t __evenaccess * )0x000870D3 )
+#define ICU_IR212_ADDR			( ( volatile uint8_t __evenaccess * )0x000870D4 )
+#define ICU_IR213_ADDR			( ( volatile uint8_t __evenaccess * )0x000870D5 )
+#define ICU_IR214_ADDR			( ( volatile uint8_t __evenaccess * )0x000870D6 )
+#define ICU_IR215_ADDR			( ( volatile uint8_t __evenaccess * )0x000870D7 )
+#define ICU_IR216_ADDR			( ( volatile uint8_t __evenaccess * )0x000870D8 )
+#define ICU_IR217_ADDR			( ( volatile uint8_t __evenaccess * )0x000870D9 )
+#define ICU_IR218_ADDR			( ( volatile uint8_t __evenaccess * )0x000870DA )
+#define ICU_IR219_ADDR			( ( volatile uint8_t __evenaccess * )0x000870DB )
+#define ICU_IR220_ADDR			( ( volatile uint8_t __evenaccess * )0x000870DC )
+#define ICU_IR221_ADDR			( ( volatile uint8_t __evenaccess * )0x000870DD )
+#define ICU_IR222_ADDR			( ( volatile uint8_t __evenaccess * )0x000870DE )
+#define ICU_IR223_ADDR			( ( volatile uint8_t __evenaccess * )0x000870DF )
+#define ICU_IR224_ADDR			( ( volatile uint8_t __evenaccess * )0x000870E0 )
+#define ICU_IR225_ADDR			( ( volatile uint8_t __evenaccess * )0x000870E1 )
+#define ICU_IR226_ADDR			( ( volatile uint8_t __evenaccess * )0x000870E2 )
+#define ICU_IR227_ADDR			( ( volatile uint8_t __evenaccess * )0x000870E3 )
+#define ICU_IR228_ADDR			( ( volatile uint8_t __evenaccess * )0x000870E4 )
+#define ICU_IR229_ADDR			( ( volatile uint8_t __evenaccess * )0x000870E5 )
+#define ICU_IR230_ADDR			( ( volatile uint8_t __evenaccess * )0x000870E6 )
+#define ICU_IR231_ADDR			( ( volatile uint8_t __evenaccess * )0x000870E7 )
+#define ICU_IR232_ADDR			( ( volatile uint8_t __evenaccess * )0x000870E8 )
+#define ICU_IR233_ADDR			( ( volatile uint8_t __evenaccess * )0x000870E9 )
+#define ICU_IR234_ADDR			( ( volatile uint8_t __evenaccess * )0x000870EA )
+#define ICU_IR235_ADDR			( ( volatile uint8_t __evenaccess * )0x000870EB )
+#define ICU_IR236_ADDR			( ( volatile uint8_t __evenaccess * )0x000870EC )
+#define ICU_IR237_ADDR			( ( volatile uint8_t __evenaccess * )0x000870ED )
+#define ICU_IR238_ADDR			( ( volatile uint8_t __evenaccess * )0x000870EE )
+#define ICU_IR239_ADDR			( ( volatile uint8_t __evenaccess * )0x000870EF )
+#define ICU_IR240_ADDR			( ( volatile uint8_t __evenaccess * )0x000870F0 )
+#define ICU_IR241_ADDR			( ( volatile uint8_t __evenaccess * )0x000870F1 )
+#define ICU_IR242_ADDR			( ( volatile uint8_t __evenaccess * )0x000870F2 )
+#define ICU_IR243_ADDR			( ( volatile uint8_t __evenaccess * )0x000870F3 )
+#define ICU_IR244_ADDR			( ( volatile uint8_t __evenaccess * )0x000870F4 )
+#define ICU_IR245_ADDR			( ( volatile uint8_t __evenaccess * )0x000870F5 )
+#define ICU_IR246_ADDR			( ( volatile uint8_t __evenaccess * )0x000870F6 )
+#define ICU_IR247_ADDR			( ( volatile uint8_t __evenaccess * )0x000870F7 )
+#define ICU_IR248_ADDR			( ( volatile uint8_t __evenaccess * )0x000870F8 )
+#define ICU_IR249_ADDR			( ( volatile uint8_t __evenaccess * )0x000870F9 )
+#define ICU_IR250_ADDR			( ( volatile uint8_t __evenaccess * )0x000870FA )
+#define ICU_IR251_ADDR			( ( volatile uint8_t __evenaccess * )0x000870FB )
+#define ICU_IR252_ADDR			( ( volatile uint8_t __evenaccess * )0x000870FC )
+#define ICU_IR253_ADDR			( ( volatile uint8_t __evenaccess * )0x000870FD )
+#define ICU_IR254_ADDR			( ( volatile uint8_t __evenaccess * )0x000870FE )
+#define ICU_IR255_ADDR			( ( volatile uint8_t __evenaccess * )0x000870FF )
+#define ICU_IR_BIT				( 1U << 0U )
+
+/*
+ * 割り込み要求先設定レジスタ
+ */
+#define ICU_ISELR000_ADDR		( ( volatile uint8_t __evenaccess * )0x00087100 )
+#define ICU_ISELR001_ADDR		( ( volatile uint8_t __evenaccess * )0x00087101 )
+#define ICU_ISELR002_ADDR		( ( volatile uint8_t __evenaccess * )0x00087102 )
+#define ICU_ISELR003_ADDR		( ( volatile uint8_t __evenaccess * )0x00087103 )
+#define ICU_ISELR004_ADDR		( ( volatile uint8_t __evenaccess * )0x00087104 )
+#define ICU_ISELR005_ADDR		( ( volatile uint8_t __evenaccess * )0x00087105 )
+#define ICU_ISELR006_ADDR		( ( volatile uint8_t __evenaccess * )0x00087106 )
+#define ICU_ISELR007_ADDR		( ( volatile uint8_t __evenaccess * )0x00087107 )
+#define ICU_ISELR008_ADDR		( ( volatile uint8_t __evenaccess * )0x00087108 )
+#define ICU_ISELR009_ADDR		( ( volatile uint8_t __evenaccess * )0x00087109 )
+#define ICU_ISELR010_ADDR		( ( volatile uint8_t __evenaccess * )0x0008710A )
+#define ICU_ISELR011_ADDR		( ( volatile uint8_t __evenaccess * )0x0008710B )
+#define ICU_ISELR012_ADDR		( ( volatile uint8_t __evenaccess * )0x0008710C )
+#define ICU_ISELR013_ADDR		( ( volatile uint8_t __evenaccess * )0x0008710D )
+#define ICU_ISELR014_ADDR		( ( volatile uint8_t __evenaccess * )0x0008710E )
+#define ICU_ISELR015_ADDR		( ( volatile uint8_t __evenaccess * )0x0008710F )
+#define ICU_ISELR016_ADDR		( ( volatile uint8_t __evenaccess * )0x00087110 )
+#define ICU_ISELR017_ADDR		( ( volatile uint8_t __evenaccess * )0x00087111 )
+#define ICU_ISELR018_ADDR		( ( volatile uint8_t __evenaccess * )0x00087112 )
+#define ICU_ISELR019_ADDR		( ( volatile uint8_t __evenaccess * )0x00087113 )
+#define ICU_ISELR020_ADDR		( ( volatile uint8_t __evenaccess * )0x00087114 )
+#define ICU_ISELR021_ADDR		( ( volatile uint8_t __evenaccess * )0x00087115 )
+#define ICU_ISELR022_ADDR		( ( volatile uint8_t __evenaccess * )0x00087116 )
+#define ICU_ISELR023_ADDR		( ( volatile uint8_t __evenaccess * )0x00087117 )
+#define ICU_ISELR024_ADDR		( ( volatile uint8_t __evenaccess * )0x00087118 )
+#define ICU_ISELR025_ADDR		( ( volatile uint8_t __evenaccess * )0x00087119 )
+#define ICU_ISELR026_ADDR		( ( volatile uint8_t __evenaccess * )0x0008711A )
+#define ICU_ISELR027_ADDR		( ( volatile uint8_t __evenaccess * )0x0008711B )
+#define ICU_ISELR028_ADDR		( ( volatile uint8_t __evenaccess * )0x0008711C )
+#define ICU_ISELR029_ADDR		( ( volatile uint8_t __evenaccess * )0x0008711D )
+#define ICU_ISELR030_ADDR		( ( volatile uint8_t __evenaccess * )0x0008711E )
+#define ICU_ISELR031_ADDR		( ( volatile uint8_t __evenaccess * )0x0008711F )
+#define ICU_ISELR032_ADDR		( ( volatile uint8_t __evenaccess * )0x00087120 )
+#define ICU_ISELR033_ADDR		( ( volatile uint8_t __evenaccess * )0x00087121 )
+#define ICU_ISELR034_ADDR		( ( volatile uint8_t __evenaccess * )0x00087122 )
+#define ICU_ISELR035_ADDR		( ( volatile uint8_t __evenaccess * )0x00087123 )
+#define ICU_ISELR036_ADDR		( ( volatile uint8_t __evenaccess * )0x00087124 )
+#define ICU_ISELR037_ADDR		( ( volatile uint8_t __evenaccess * )0x00087125 )
+#define ICU_ISELR038_ADDR		( ( volatile uint8_t __evenaccess * )0x00087126 )
+#define ICU_ISELR039_ADDR		( ( volatile uint8_t __evenaccess * )0x00087127 )
+#define ICU_ISELR040_ADDR		( ( volatile uint8_t __evenaccess * )0x00087128 )
+#define ICU_ISELR041_ADDR		( ( volatile uint8_t __evenaccess * )0x00087129 )
+#define ICU_ISELR042_ADDR		( ( volatile uint8_t __evenaccess * )0x0008712A )
+#define ICU_ISELR043_ADDR		( ( volatile uint8_t __evenaccess * )0x0008712B )
+#define ICU_ISELR044_ADDR		( ( volatile uint8_t __evenaccess * )0x0008712C )
+#define ICU_ISELR045_ADDR		( ( volatile uint8_t __evenaccess * )0x0008712D )
+#define ICU_ISELR046_ADDR		( ( volatile uint8_t __evenaccess * )0x0008712E )
+#define ICU_ISELR047_ADDR		( ( volatile uint8_t __evenaccess * )0x0008712F )
+#define ICU_ISELR048_ADDR		( ( volatile uint8_t __evenaccess * )0x00087130 )
+#define ICU_ISELR049_ADDR		( ( volatile uint8_t __evenaccess * )0x00087131 )
+#define ICU_ISELR050_ADDR		( ( volatile uint8_t __evenaccess * )0x00087132 )
+#define ICU_ISELR051_ADDR		( ( volatile uint8_t __evenaccess * )0x00087133 )
+#define ICU_ISELR052_ADDR		( ( volatile uint8_t __evenaccess * )0x00087134 )
+#define ICU_ISELR053_ADDR		( ( volatile uint8_t __evenaccess * )0x00087135 )
+#define ICU_ISELR054_ADDR		( ( volatile uint8_t __evenaccess * )0x00087136 )
+#define ICU_ISELR055_ADDR		( ( volatile uint8_t __evenaccess * )0x00087137 )
+#define ICU_ISELR056_ADDR		( ( volatile uint8_t __evenaccess * )0x00087138 )
+#define ICU_ISELR057_ADDR		( ( volatile uint8_t __evenaccess * )0x00087139 )
+#define ICU_ISELR058_ADDR		( ( volatile uint8_t __evenaccess * )0x0008713A )
+#define ICU_ISELR059_ADDR		( ( volatile uint8_t __evenaccess * )0x0008713B )
+#define ICU_ISELR060_ADDR		( ( volatile uint8_t __evenaccess * )0x0008713C )
+#define ICU_ISELR061_ADDR		( ( volatile uint8_t __evenaccess * )0x0008713D )
+#define ICU_ISELR062_ADDR		( ( volatile uint8_t __evenaccess * )0x0008713E )
+#define ICU_ISELR063_ADDR		( ( volatile uint8_t __evenaccess * )0x0008713F )
+#define ICU_ISELR064_ADDR		( ( volatile uint8_t __evenaccess * )0x00087140 )
+#define ICU_ISELR065_ADDR		( ( volatile uint8_t __evenaccess * )0x00087141 )
+#define ICU_ISELR066_ADDR		( ( volatile uint8_t __evenaccess * )0x00087142 )
+#define ICU_ISELR067_ADDR		( ( volatile uint8_t __evenaccess * )0x00087143 )
+#define ICU_ISELR068_ADDR		( ( volatile uint8_t __evenaccess * )0x00087144 )
+#define ICU_ISELR069_ADDR		( ( volatile uint8_t __evenaccess * )0x00087145 )
+#define ICU_ISELR070_ADDR		( ( volatile uint8_t __evenaccess * )0x00087146 )
+#define ICU_ISELR071_ADDR		( ( volatile uint8_t __evenaccess * )0x00087147 )
+#define ICU_ISELR072_ADDR		( ( volatile uint8_t __evenaccess * )0x00087148 )
+#define ICU_ISELR073_ADDR		( ( volatile uint8_t __evenaccess * )0x00087149 )
+#define ICU_ISELR074_ADDR		( ( volatile uint8_t __evenaccess * )0x0008714A )
+#define ICU_ISELR075_ADDR		( ( volatile uint8_t __evenaccess * )0x0008714B )
+#define ICU_ISELR076_ADDR		( ( volatile uint8_t __evenaccess * )0x0008714C )
+#define ICU_ISELR077_ADDR		( ( volatile uint8_t __evenaccess * )0x0008714D )
+#define ICU_ISELR078_ADDR		( ( volatile uint8_t __evenaccess * )0x0008714E )
+#define ICU_ISELR079_ADDR		( ( volatile uint8_t __evenaccess * )0x0008714F )
+#define ICU_ISELR080_ADDR		( ( volatile uint8_t __evenaccess * )0x00087150 )
+#define ICU_ISELR081_ADDR		( ( volatile uint8_t __evenaccess * )0x00087151 )
+#define ICU_ISELR082_ADDR		( ( volatile uint8_t __evenaccess * )0x00087152 )
+#define ICU_ISELR083_ADDR		( ( volatile uint8_t __evenaccess * )0x00087153 )
+#define ICU_ISELR084_ADDR		( ( volatile uint8_t __evenaccess * )0x00087154 )
+#define ICU_ISELR085_ADDR		( ( volatile uint8_t __evenaccess * )0x00087155 )
+#define ICU_ISELR086_ADDR		( ( volatile uint8_t __evenaccess * )0x00087156 )
+#define ICU_ISELR087_ADDR		( ( volatile uint8_t __evenaccess * )0x00087157 )
+#define ICU_ISELR088_ADDR		( ( volatile uint8_t __evenaccess * )0x00087158 )
+#define ICU_ISELR089_ADDR		( ( volatile uint8_t __evenaccess * )0x00087159 )
+#define ICU_ISELR090_ADDR		( ( volatile uint8_t __evenaccess * )0x0008715A )
+#define ICU_ISELR091_ADDR		( ( volatile uint8_t __evenaccess * )0x0008715B )
+#define ICU_ISELR092_ADDR		( ( volatile uint8_t __evenaccess * )0x0008715C )
+#define ICU_ISELR093_ADDR		( ( volatile uint8_t __evenaccess * )0x0008715D )
+#define ICU_ISELR094_ADDR		( ( volatile uint8_t __evenaccess * )0x0008715E )
+#define ICU_ISELR095_ADDR		( ( volatile uint8_t __evenaccess * )0x0008715F )
+#define ICU_ISELR096_ADDR		( ( volatile uint8_t __evenaccess * )0x00087160 )
+#define ICU_ISELR097_ADDR		( ( volatile uint8_t __evenaccess * )0x00087161 )
+#define ICU_ISELR098_ADDR		( ( volatile uint8_t __evenaccess * )0x00087162 )
+#define ICU_ISELR099_ADDR		( ( volatile uint8_t __evenaccess * )0x00087163 )
+#define ICU_ISELR100_ADDR		( ( volatile uint8_t __evenaccess * )0x00087164 )
+#define ICU_ISELR101_ADDR		( ( volatile uint8_t __evenaccess * )0x00087165 )
+#define ICU_ISELR102_ADDR		( ( volatile uint8_t __evenaccess * )0x00087166 )
+#define ICU_ISELR103_ADDR		( ( volatile uint8_t __evenaccess * )0x00087167 )
+#define ICU_ISELR104_ADDR		( ( volatile uint8_t __evenaccess * )0x00087168 )
+#define ICU_ISELR105_ADDR		( ( volatile uint8_t __evenaccess * )0x00087169 )
+#define ICU_ISELR106_ADDR		( ( volatile uint8_t __evenaccess * )0x0008716A )
+#define ICU_ISELR107_ADDR		( ( volatile uint8_t __evenaccess * )0x0008716B )
+#define ICU_ISELR108_ADDR		( ( volatile uint8_t __evenaccess * )0x0008716C )
+#define ICU_ISELR109_ADDR		( ( volatile uint8_t __evenaccess * )0x0008716D )
+#define ICU_ISELR110_ADDR		( ( volatile uint8_t __evenaccess * )0x0008716E )
+#define ICU_ISELR111_ADDR		( ( volatile uint8_t __evenaccess * )0x0008716F )
+#define ICU_ISELR112_ADDR		( ( volatile uint8_t __evenaccess * )0x00087170 )
+#define ICU_ISELR113_ADDR		( ( volatile uint8_t __evenaccess * )0x00087171 )
+#define ICU_ISELR114_ADDR		( ( volatile uint8_t __evenaccess * )0x00087172 )
+#define ICU_ISELR115_ADDR		( ( volatile uint8_t __evenaccess * )0x00087173 )
+#define ICU_ISELR116_ADDR		( ( volatile uint8_t __evenaccess * )0x00087174 )
+#define ICU_ISELR117_ADDR		( ( volatile uint8_t __evenaccess * )0x00087175 )
+#define ICU_ISELR118_ADDR		( ( volatile uint8_t __evenaccess * )0x00087176 )
+#define ICU_ISELR119_ADDR		( ( volatile uint8_t __evenaccess * )0x00087177 )
+#define ICU_ISELR120_ADDR		( ( volatile uint8_t __evenaccess * )0x00087178 )
+#define ICU_ISELR121_ADDR		( ( volatile uint8_t __evenaccess * )0x00087179 )
+#define ICU_ISELR122_ADDR		( ( volatile uint8_t __evenaccess * )0x0008717A )
+#define ICU_ISELR123_ADDR		( ( volatile uint8_t __evenaccess * )0x0008717B )
+#define ICU_ISELR124_ADDR		( ( volatile uint8_t __evenaccess * )0x0008717C )
+#define ICU_ISELR125_ADDR		( ( volatile uint8_t __evenaccess * )0x0008717D )
+#define ICU_ISELR126_ADDR		( ( volatile uint8_t __evenaccess * )0x0008717E )
+#define ICU_ISELR127_ADDR		( ( volatile uint8_t __evenaccess * )0x0008717F )
+#define ICU_ISELR128_ADDR		( ( volatile uint8_t __evenaccess * )0x00087180 )
+#define ICU_ISELR129_ADDR		( ( volatile uint8_t __evenaccess * )0x00087181 )
+#define ICU_ISELR130_ADDR		( ( volatile uint8_t __evenaccess * )0x00087182 )
+#define ICU_ISELR131_ADDR		( ( volatile uint8_t __evenaccess * )0x00087183 )
+#define ICU_ISELR132_ADDR		( ( volatile uint8_t __evenaccess * )0x00087184 )
+#define ICU_ISELR133_ADDR		( ( volatile uint8_t __evenaccess * )0x00087185 )
+#define ICU_ISELR134_ADDR		( ( volatile uint8_t __evenaccess * )0x00087186 )
+#define ICU_ISELR135_ADDR		( ( volatile uint8_t __evenaccess * )0x00087187 )
+#define ICU_ISELR136_ADDR		( ( volatile uint8_t __evenaccess * )0x00087188 )
+#define ICU_ISELR137_ADDR		( ( volatile uint8_t __evenaccess * )0x00087189 )
+#define ICU_ISELR138_ADDR		( ( volatile uint8_t __evenaccess * )0x0008718A )
+#define ICU_ISELR139_ADDR		( ( volatile uint8_t __evenaccess * )0x0008718B )
+#define ICU_ISELR140_ADDR		( ( volatile uint8_t __evenaccess * )0x0008718C )
+#define ICU_ISELR141_ADDR		( ( volatile uint8_t __evenaccess * )0x0008718D )
+#define ICU_ISELR142_ADDR		( ( volatile uint8_t __evenaccess * )0x0008718E )
+#define ICU_ISELR143_ADDR		( ( volatile uint8_t __evenaccess * )0x0008718F )
+#define ICU_ISELR144_ADDR		( ( volatile uint8_t __evenaccess * )0x00087190 )
+#define ICU_ISELR145_ADDR		( ( volatile uint8_t __evenaccess * )0x00087191 )
+#define ICU_ISELR146_ADDR		( ( volatile uint8_t __evenaccess * )0x00087192 )
+#define ICU_ISELR147_ADDR		( ( volatile uint8_t __evenaccess * )0x00087193 )
+#define ICU_ISELR148_ADDR		( ( volatile uint8_t __evenaccess * )0x00087194 )
+#define ICU_ISELR149_ADDR		( ( volatile uint8_t __evenaccess * )0x00087195 )
+#define ICU_ISELR150_ADDR		( ( volatile uint8_t __evenaccess * )0x00087196 )
+#define ICU_ISELR151_ADDR		( ( volatile uint8_t __evenaccess * )0x00087197 )
+#define ICU_ISELR152_ADDR		( ( volatile uint8_t __evenaccess * )0x00087198 )
+#define ICU_ISELR153_ADDR		( ( volatile uint8_t __evenaccess * )0x00087199 )
+#define ICU_ISELR154_ADDR		( ( volatile uint8_t __evenaccess * )0x0008719A )
+#define ICU_ISELR155_ADDR		( ( volatile uint8_t __evenaccess * )0x0008719B )
+#define ICU_ISELR156_ADDR		( ( volatile uint8_t __evenaccess * )0x0008719C )
+#define ICU_ISELR157_ADDR		( ( volatile uint8_t __evenaccess * )0x0008719D )
+#define ICU_ISELR158_ADDR		( ( volatile uint8_t __evenaccess * )0x0008719E )
+#define ICU_ISELR159_ADDR		( ( volatile uint8_t __evenaccess * )0x0008719F )
+#define ICU_ISELR160_ADDR		( ( volatile uint8_t __evenaccess * )0x000871A0 )
+#define ICU_ISELR161_ADDR		( ( volatile uint8_t __evenaccess * )0x000871A1 )
+#define ICU_ISELR162_ADDR		( ( volatile uint8_t __evenaccess * )0x000871A2 )
+#define ICU_ISELR163_ADDR		( ( volatile uint8_t __evenaccess * )0x000871A3 )
+#define ICU_ISELR164_ADDR		( ( volatile uint8_t __evenaccess * )0x000871A4 )
+#define ICU_ISELR165_ADDR		( ( volatile uint8_t __evenaccess * )0x000871A5 )
+#define ICU_ISELR166_ADDR		( ( volatile uint8_t __evenaccess * )0x000871A6 )
+#define ICU_ISELR167_ADDR		( ( volatile uint8_t __evenaccess * )0x000871A7 )
+#define ICU_ISELR168_ADDR		( ( volatile uint8_t __evenaccess * )0x000871A8 )
+#define ICU_ISELR169_ADDR		( ( volatile uint8_t __evenaccess * )0x000871A9 )
+#define ICU_ISELR170_ADDR		( ( volatile uint8_t __evenaccess * )0x000871AA )
+#define ICU_ISELR171_ADDR		( ( volatile uint8_t __evenaccess * )0x000871AB )
+#define ICU_ISELR172_ADDR		( ( volatile uint8_t __evenaccess * )0x000871AC )
+#define ICU_ISELR173_ADDR		( ( volatile uint8_t __evenaccess * )0x000871AD )
+#define ICU_ISELR174_ADDR		( ( volatile uint8_t __evenaccess * )0x000871AE )
+#define ICU_ISELR175_ADDR		( ( volatile uint8_t __evenaccess * )0x000871AF )
+#define ICU_ISELR176_ADDR		( ( volatile uint8_t __evenaccess * )0x000871B0 )
+#define ICU_ISELR177_ADDR		( ( volatile uint8_t __evenaccess * )0x000871B1 )
+#define ICU_ISELR178_ADDR		( ( volatile uint8_t __evenaccess * )0x000871B2 )
+#define ICU_ISELR179_ADDR		( ( volatile uint8_t __evenaccess * )0x000871B3 )
+#define ICU_ISELR180_ADDR		( ( volatile uint8_t __evenaccess * )0x000871B4 )
+#define ICU_ISELR181_ADDR		( ( volatile uint8_t __evenaccess * )0x000871B5 )
+#define ICU_ISELR182_ADDR		( ( volatile uint8_t __evenaccess * )0x000871B6 )
+#define ICU_ISELR183_ADDR		( ( volatile uint8_t __evenaccess * )0x000871B7 )
+#define ICU_ISELR184_ADDR		( ( volatile uint8_t __evenaccess * )0x000871B8 )
+#define ICU_ISELR185_ADDR		( ( volatile uint8_t __evenaccess * )0x000871B9 )
+#define ICU_ISELR186_ADDR		( ( volatile uint8_t __evenaccess * )0x000871BA )
+#define ICU_ISELR187_ADDR		( ( volatile uint8_t __evenaccess * )0x000871BB )
+#define ICU_ISELR188_ADDR		( ( volatile uint8_t __evenaccess * )0x000871BC )
+#define ICU_ISELR189_ADDR		( ( volatile uint8_t __evenaccess * )0x000871BD )
+#define ICU_ISELR190_ADDR		( ( volatile uint8_t __evenaccess * )0x000871BE )
+#define ICU_ISELR191_ADDR		( ( volatile uint8_t __evenaccess * )0x000871BF )
+#define ICU_ISELR192_ADDR		( ( volatile uint8_t __evenaccess * )0x000871C0 )
+#define ICU_ISELR193_ADDR		( ( volatile uint8_t __evenaccess * )0x000871C1 )
+#define ICU_ISELR194_ADDR		( ( volatile uint8_t __evenaccess * )0x000871C2 )
+#define ICU_ISELR195_ADDR		( ( volatile uint8_t __evenaccess * )0x000871C3 )
+#define ICU_ISELR196_ADDR		( ( volatile uint8_t __evenaccess * )0x000871C4 )
+#define ICU_ISELR197_ADDR		( ( volatile uint8_t __evenaccess * )0x000871C5 )
+#define ICU_ISELR198_ADDR		( ( volatile uint8_t __evenaccess * )0x000871C6 )
+#define ICU_ISELR199_ADDR		( ( volatile uint8_t __evenaccess * )0x000871C7 )
+#define ICU_ISELR200_ADDR		( ( volatile uint8_t __evenaccess * )0x000871C8 )
+#define ICU_ISELR201_ADDR		( ( volatile uint8_t __evenaccess * )0x000871C9 )
+#define ICU_ISELR202_ADDR		( ( volatile uint8_t __evenaccess * )0x000871CA )
+#define ICU_ISELR203_ADDR		( ( volatile uint8_t __evenaccess * )0x000871CB )
+#define ICU_ISELR204_ADDR		( ( volatile uint8_t __evenaccess * )0x000871CC )
+#define ICU_ISELR205_ADDR		( ( volatile uint8_t __evenaccess * )0x000871CD )
+#define ICU_ISELR206_ADDR		( ( volatile uint8_t __evenaccess * )0x000871CE )
+#define ICU_ISELR207_ADDR		( ( volatile uint8_t __evenaccess * )0x000871CF )
+#define ICU_ISELR208_ADDR		( ( volatile uint8_t __evenaccess * )0x000871D0 )
+#define ICU_ISELR209_ADDR		( ( volatile uint8_t __evenaccess * )0x000871D1 )
+#define ICU_ISELR210_ADDR		( ( volatile uint8_t __evenaccess * )0x000871D2 )
+#define ICU_ISELR211_ADDR		( ( volatile uint8_t __evenaccess * )0x000871D3 )
+#define ICU_ISELR212_ADDR		( ( volatile uint8_t __evenaccess * )0x000871D4 )
+#define ICU_ISELR213_ADDR		( ( volatile uint8_t __evenaccess * )0x000871D5 )
+#define ICU_ISELR214_ADDR		( ( volatile uint8_t __evenaccess * )0x000871D6 )
+#define ICU_ISELR215_ADDR		( ( volatile uint8_t __evenaccess * )0x000871D7 )
+#define ICU_ISELR216_ADDR		( ( volatile uint8_t __evenaccess * )0x000871D8 )
+#define ICU_ISELR217_ADDR		( ( volatile uint8_t __evenaccess * )0x000871D9 )
+#define ICU_ISELR218_ADDR		( ( volatile uint8_t __evenaccess * )0x000871DA )
+#define ICU_ISELR219_ADDR		( ( volatile uint8_t __evenaccess * )0x000871DB )
+#define ICU_ISELR220_ADDR		( ( volatile uint8_t __evenaccess * )0x000871DC )
+#define ICU_ISELR221_ADDR		( ( volatile uint8_t __evenaccess * )0x000871DD )
+#define ICU_ISELR222_ADDR		( ( volatile uint8_t __evenaccess * )0x000871DE )
+#define ICU_ISELR223_ADDR		( ( volatile uint8_t __evenaccess * )0x000871DF )
+#define ICU_ISELR224_ADDR		( ( volatile uint8_t __evenaccess * )0x000871E0 )
+#define ICU_ISELR225_ADDR		( ( volatile uint8_t __evenaccess * )0x000871E1 )
+#define ICU_ISELR226_ADDR		( ( volatile uint8_t __evenaccess * )0x000871E2 )
+#define ICU_ISELR227_ADDR		( ( volatile uint8_t __evenaccess * )0x000871E3 )
+#define ICU_ISELR228_ADDR		( ( volatile uint8_t __evenaccess * )0x000871E4 )
+#define ICU_ISELR229_ADDR		( ( volatile uint8_t __evenaccess * )0x000871E5 )
+#define ICU_ISELR230_ADDR		( ( volatile uint8_t __evenaccess * )0x000871E6 )
+#define ICU_ISELR231_ADDR		( ( volatile uint8_t __evenaccess * )0x000871E7 )
+#define ICU_ISELR232_ADDR		( ( volatile uint8_t __evenaccess * )0x000871E8 )
+#define ICU_ISELR233_ADDR		( ( volatile uint8_t __evenaccess * )0x000871E9 )
+#define ICU_ISELR234_ADDR		( ( volatile uint8_t __evenaccess * )0x000871EA )
+#define ICU_ISELR235_ADDR		( ( volatile uint8_t __evenaccess * )0x000871EB )
+#define ICU_ISELR236_ADDR		( ( volatile uint8_t __evenaccess * )0x000871EC )
+#define ICU_ISELR237_ADDR		( ( volatile uint8_t __evenaccess * )0x000871ED )
+#define ICU_ISELR238_ADDR		( ( volatile uint8_t __evenaccess * )0x000871EE )
+#define ICU_ISELR239_ADDR		( ( volatile uint8_t __evenaccess * )0x000871EF )
+#define ICU_ISELR240_ADDR		( ( volatile uint8_t __evenaccess * )0x000871F0 )
+#define ICU_ISELR241_ADDR		( ( volatile uint8_t __evenaccess * )0x000871F1 )
+#define ICU_ISELR242_ADDR		( ( volatile uint8_t __evenaccess * )0x000871F2 )
+#define ICU_ISELR243_ADDR		( ( volatile uint8_t __evenaccess * )0x000871F3 )
+#define ICU_ISELR244_ADDR		( ( volatile uint8_t __evenaccess * )0x000871F4 )
+#define ICU_ISELR245_ADDR		( ( volatile uint8_t __evenaccess * )0x000871F5 )
+#define ICU_ISELR246_ADDR		( ( volatile uint8_t __evenaccess * )0x000871F6 )
+#define ICU_ISELR247_ADDR		( ( volatile uint8_t __evenaccess * )0x000871F7 )
+#define ICU_ISELR248_ADDR		( ( volatile uint8_t __evenaccess * )0x000871F8 )
+#define ICU_ISELR249_ADDR		( ( volatile uint8_t __evenaccess * )0x000871F9 )
+#define ICU_ISELR250_ADDR		( ( volatile uint8_t __evenaccess * )0x000871FA )
+#define ICU_ISELR251_ADDR		( ( volatile uint8_t __evenaccess * )0x000871FB )
+#define ICU_ISELR252_ADDR		( ( volatile uint8_t __evenaccess * )0x000871FC )
+#define ICU_ISELR253_ADDR		( ( volatile uint8_t __evenaccess * )0x000871FD )
+#define ICU_ISELR254_ADDR		( ( volatile uint8_t __evenaccess * )0x000871FE )
+#define ICU_ISELR255_ADDR		( ( volatile uint8_t __evenaccess * )0x000871FF )
+#define ICU_ISEL_BIT			( 3U << 0U )
+
+/*
+ * 割り込み要求許可レジスタ
+ */
+#define ICU_IER02_ADDR			( ( volatile uint8_t __evenaccess * )0x00087202 )
+#define ICU_IER03_ADDR			( ( volatile uint8_t __evenaccess * )0x00087203 )
+#define ICU_IER04_ADDR			( ( volatile uint8_t __evenaccess * )0x00087204 )
+#define ICU_IER05_ADDR			( ( volatile uint8_t __evenaccess * )0x00087205 )
+#define ICU_IER06_ADDR			( ( volatile uint8_t __evenaccess * )0x00087206 )
+#define ICU_IER07_ADDR			( ( volatile uint8_t __evenaccess * )0x00087207 )
+#define ICU_IER08_ADDR			( ( volatile uint8_t __evenaccess * )0x00087208 )
+#define ICU_IER09_ADDR			( ( volatile uint8_t __evenaccess * )0x00087209 )
+#define ICU_IER0B_ADDR			( ( volatile uint8_t __evenaccess * )0x0008720B )
+#define ICU_IER0C_ADDR			( ( volatile uint8_t __evenaccess * )0x0008720C )
+#define ICU_IER0D_ADDR			( ( volatile uint8_t __evenaccess * )0x0008720D )
+#define ICU_IER0E_ADDR			( ( volatile uint8_t __evenaccess * )0x0008720E )
+#define ICU_IER0F_ADDR			( ( volatile uint8_t __evenaccess * )0x0008720F )
+#define ICU_IER10_ADDR			( ( volatile uint8_t __evenaccess * )0x00087210 )
+#define ICU_IER11_ADDR			( ( volatile uint8_t __evenaccess * )0x00087211 )
+#define ICU_IER12_ADDR			( ( volatile uint8_t __evenaccess * )0x00087212 )
+#define ICU_IER13_ADDR			( ( volatile uint8_t __evenaccess * )0x00087213 )
+#define ICU_IER14_ADDR			( ( volatile uint8_t __evenaccess * )0x00087214 )
+#define ICU_IER15_ADDR			( ( volatile uint8_t __evenaccess * )0x00087215 )
+#define ICU_IER16_ADDR			( ( volatile uint8_t __evenaccess * )0x00087216 )
+#define ICU_IER17_ADDR			( ( volatile uint8_t __evenaccess * )0x00087217 )
+#define ICU_IER18_ADDR			( ( volatile uint8_t __evenaccess * )0x00087218 )
+#define ICU_IER19_ADDR			( ( volatile uint8_t __evenaccess * )0x00087219 )
+#define ICU_IER1A_ADDR			( ( volatile uint8_t __evenaccess * )0x0008721A )
+#define ICU_IER1B_ADDR			( ( volatile uint8_t __evenaccess * )0x0008721B )
+#define ICU_IER1C_ADDR			( ( volatile uint8_t __evenaccess * )0x0008721C )
+#define ICU_IER1D_ADDR			( ( volatile uint8_t __evenaccess * )0x0008721D )
+#define ICU_IER1E_ADDR			( ( volatile uint8_t __evenaccess * )0x0008721E )
+#define ICU_IER1F_ADDR			( ( volatile uint8_t __evenaccess * )0x0008721F )
+#define ICU_IEN0_BIT			( 1U << 0U )
+#define ICU_IEN1_BIT			( 1U << 1U )
+#define ICU_IEN2_BIT			( 1U << 2U )
+#define ICU_IEN3_BIT			( 1U << 3U )
+#define ICU_IEN4_BIT			( 1U << 4U )
+#define ICU_IEN5_BIT			( 1U << 5U )
+#define ICU_IEN6_BIT			( 1U << 6U )
+#define ICU_IEN7_BIT			( 1U << 7U )
+
+/* 
+ * 割り込み要因プライオリティレジスタi(i=0～253)の設定
+ */
+#define ICU_IPR000_ADDR			( ( volatile uint8_t __evenaccess * )0x00087300 )
+#define ICU_IPR001_ADDR			( ( volatile uint8_t __evenaccess * )0x00087301 )
+#define ICU_IPR002_ADDR			( ( volatile uint8_t __evenaccess * )0x00087302 )
+#define ICU_IPR003_ADDR			( ( volatile uint8_t __evenaccess * )0x00087303 )
+#define ICU_IPR004_ADDR			( ( volatile uint8_t __evenaccess * )0x00087304 )
+#define ICU_IPR005_ADDR			( ( volatile uint8_t __evenaccess * )0x00087305 )
+#define ICU_IPR006_ADDR			( ( volatile uint8_t __evenaccess * )0x00087306 )
+#define ICU_IPR007_ADDR			( ( volatile uint8_t __evenaccess * )0x00087307 )
+#define ICU_IPR008_ADDR			( ( volatile uint8_t __evenaccess * )0x00087308 )
+#define ICU_IPR009_ADDR			( ( volatile uint8_t __evenaccess * )0x00087309 )
+#define ICU_IPR010_ADDR			( ( volatile uint8_t __evenaccess * )0x0008730A )
+#define ICU_IPR011_ADDR			( ( volatile uint8_t __evenaccess * )0x0008730B )
+#define ICU_IPR012_ADDR			( ( volatile uint8_t __evenaccess * )0x0008730C )
+#define ICU_IPR013_ADDR			( ( volatile uint8_t __evenaccess * )0x0008730D )
+#define ICU_IPR014_ADDR			( ( volatile uint8_t __evenaccess * )0x0008730E )
+#define ICU_IPR015_ADDR			( ( volatile uint8_t __evenaccess * )0x0008730F )
+#define ICU_IPR016_ADDR			( ( volatile uint8_t __evenaccess * )0x00087310 )
+#define ICU_IPR017_ADDR			( ( volatile uint8_t __evenaccess * )0x00087311 )
+#define ICU_IPR018_ADDR			( ( volatile uint8_t __evenaccess * )0x00087312 )
+#define ICU_IPR019_ADDR			( ( volatile uint8_t __evenaccess * )0x00087313 )
+#define ICU_IPR020_ADDR			( ( volatile uint8_t __evenaccess * )0x00087314 )
+#define ICU_IPR021_ADDR			( ( volatile uint8_t __evenaccess * )0x00087315 )
+#define ICU_IPR022_ADDR			( ( volatile uint8_t __evenaccess * )0x00087316 )
+#define ICU_IPR023_ADDR			( ( volatile uint8_t __evenaccess * )0x00087317 )
+#define ICU_IPR024_ADDR			( ( volatile uint8_t __evenaccess * )0x00087318 )
+#define ICU_IPR025_ADDR			( ( volatile uint8_t __evenaccess * )0x00087319 )
+#define ICU_IPR026_ADDR			( ( volatile uint8_t __evenaccess * )0x0008731A )
+#define ICU_IPR027_ADDR			( ( volatile uint8_t __evenaccess * )0x0008731B )
+#define ICU_IPR028_ADDR			( ( volatile uint8_t __evenaccess * )0x0008731C )
+#define ICU_IPR029_ADDR			( ( volatile uint8_t __evenaccess * )0x0008731D )
+#define ICU_IPR030_ADDR			( ( volatile uint8_t __evenaccess * )0x0008731E )
+#define ICU_IPR031_ADDR			( ( volatile uint8_t __evenaccess * )0x0008731F )
+#define ICU_IPR032_ADDR			( ( volatile uint8_t __evenaccess * )0x00087320 )
+#define ICU_IPR033_ADDR			( ( volatile uint8_t __evenaccess * )0x00087321 )
+#define ICU_IPR034_ADDR			( ( volatile uint8_t __evenaccess * )0x00087322 )
+#define ICU_IPR035_ADDR			( ( volatile uint8_t __evenaccess * )0x00087323 )
+#define ICU_IPR036_ADDR			( ( volatile uint8_t __evenaccess * )0x00087324 )
+#define ICU_IPR037_ADDR			( ( volatile uint8_t __evenaccess * )0x00087325 )
+#define ICU_IPR038_ADDR			( ( volatile uint8_t __evenaccess * )0x00087326 )
+#define ICU_IPR039_ADDR			( ( volatile uint8_t __evenaccess * )0x00087327 )
+#define ICU_IPR040_ADDR			( ( volatile uint8_t __evenaccess * )0x00087328 )
+#define ICU_IPR041_ADDR			( ( volatile uint8_t __evenaccess * )0x00087329 )
+#define ICU_IPR042_ADDR			( ( volatile uint8_t __evenaccess * )0x0008732A )
+#define ICU_IPR043_ADDR			( ( volatile uint8_t __evenaccess * )0x0008732B )
+#define ICU_IPR044_ADDR			( ( volatile uint8_t __evenaccess * )0x0008732C )
+#define ICU_IPR045_ADDR			( ( volatile uint8_t __evenaccess * )0x0008732D )
+#define ICU_IPR046_ADDR			( ( volatile uint8_t __evenaccess * )0x0008732E )
+#define ICU_IPR047_ADDR			( ( volatile uint8_t __evenaccess * )0x0008732F )
+#define ICU_IPR048_ADDR			( ( volatile uint8_t __evenaccess * )0x00087330 )
+#define ICU_IPR049_ADDR			( ( volatile uint8_t __evenaccess * )0x00087331 )
+#define ICU_IPR050_ADDR			( ( volatile uint8_t __evenaccess * )0x00087332 )
+#define ICU_IPR051_ADDR			( ( volatile uint8_t __evenaccess * )0x00087333 )
+#define ICU_IPR052_ADDR			( ( volatile uint8_t __evenaccess * )0x00087334 )
+#define ICU_IPR053_ADDR			( ( volatile uint8_t __evenaccess * )0x00087335 )
+#define ICU_IPR054_ADDR			( ( volatile uint8_t __evenaccess * )0x00087336 )
+#define ICU_IPR055_ADDR			( ( volatile uint8_t __evenaccess * )0x00087337 )
+#define ICU_IPR056_ADDR			( ( volatile uint8_t __evenaccess * )0x00087338 )
+#define ICU_IPR057_ADDR			( ( volatile uint8_t __evenaccess * )0x00087339 )
+#define ICU_IPR058_ADDR			( ( volatile uint8_t __evenaccess * )0x0008733A )
+#define ICU_IPR059_ADDR			( ( volatile uint8_t __evenaccess * )0x0008733B )
+#define ICU_IPR060_ADDR			( ( volatile uint8_t __evenaccess * )0x0008733C )
+#define ICU_IPR061_ADDR			( ( volatile uint8_t __evenaccess * )0x0008733D )
+#define ICU_IPR062_ADDR			( ( volatile uint8_t __evenaccess * )0x0008733E )
+#define ICU_IPR063_ADDR			( ( volatile uint8_t __evenaccess * )0x0008733F )
+#define ICU_IPR064_ADDR			( ( volatile uint8_t __evenaccess * )0x00087340 )
+#define ICU_IPR065_ADDR			( ( volatile uint8_t __evenaccess * )0x00087341 )
+#define ICU_IPR066_ADDR			( ( volatile uint8_t __evenaccess * )0x00087342 )
+#define ICU_IPR067_ADDR			( ( volatile uint8_t __evenaccess * )0x00087343 )
+#define ICU_IPR068_ADDR			( ( volatile uint8_t __evenaccess * )0x00087344 )
+#define ICU_IPR069_ADDR			( ( volatile uint8_t __evenaccess * )0x00087345 )
+#define ICU_IPR070_ADDR			( ( volatile uint8_t __evenaccess * )0x00087346 )
+#define ICU_IPR071_ADDR			( ( volatile uint8_t __evenaccess * )0x00087347 )
+#define ICU_IPR072_ADDR			( ( volatile uint8_t __evenaccess * )0x00087348 )
+#define ICU_IPR073_ADDR			( ( volatile uint8_t __evenaccess * )0x00087349 )
+#define ICU_IPR074_ADDR			( ( volatile uint8_t __evenaccess * )0x0008734A )
+#define ICU_IPR075_ADDR			( ( volatile uint8_t __evenaccess * )0x0008734B )
+#define ICU_IPR076_ADDR			( ( volatile uint8_t __evenaccess * )0x0008734C )
+#define ICU_IPR077_ADDR			( ( volatile uint8_t __evenaccess * )0x0008734D )
+#define ICU_IPR078_ADDR			( ( volatile uint8_t __evenaccess * )0x0008734E )
+#define ICU_IPR079_ADDR			( ( volatile uint8_t __evenaccess * )0x0008734F )
+#define ICU_IPR080_ADDR			( ( volatile uint8_t __evenaccess * )0x00087350 )
+#define ICU_IPR081_ADDR			( ( volatile uint8_t __evenaccess * )0x00087351 )
+#define ICU_IPR082_ADDR			( ( volatile uint8_t __evenaccess * )0x00087352 )
+#define ICU_IPR083_ADDR			( ( volatile uint8_t __evenaccess * )0x00087353 )
+#define ICU_IPR084_ADDR			( ( volatile uint8_t __evenaccess * )0x00087354 )
+#define ICU_IPR085_ADDR			( ( volatile uint8_t __evenaccess * )0x00087355 )
+#define ICU_IPR086_ADDR			( ( volatile uint8_t __evenaccess * )0x00087356 )
+#define ICU_IPR087_ADDR			( ( volatile uint8_t __evenaccess * )0x00087357 )
+#define ICU_IPR088_ADDR			( ( volatile uint8_t __evenaccess * )0x00087358 )
+#define ICU_IPR089_ADDR			( ( volatile uint8_t __evenaccess * )0x00087359 )
+#define ICU_IPR090_ADDR			( ( volatile uint8_t __evenaccess * )0x0008735A )
+#define ICU_IPR091_ADDR			( ( volatile uint8_t __evenaccess * )0x0008735B )
+#define ICU_IPR092_ADDR			( ( volatile uint8_t __evenaccess * )0x0008735C )
+#define ICU_IPR093_ADDR			( ( volatile uint8_t __evenaccess * )0x0008735D )
+#define ICU_IPR094_ADDR			( ( volatile uint8_t __evenaccess * )0x0008735E )
+#define ICU_IPR095_ADDR			( ( volatile uint8_t __evenaccess * )0x0008735F )
+#define ICU_IPR096_ADDR			( ( volatile uint8_t __evenaccess * )0x00087360 )
+#define ICU_IPR097_ADDR			( ( volatile uint8_t __evenaccess * )0x00087361 )
+#define ICU_IPR098_ADDR			( ( volatile uint8_t __evenaccess * )0x00087362 )
+#define ICU_IPR099_ADDR			( ( volatile uint8_t __evenaccess * )0x00087363 )
+#define ICU_IPR100_ADDR			( ( volatile uint8_t __evenaccess * )0x00087364 )
+#define ICU_IPR101_ADDR			( ( volatile uint8_t __evenaccess * )0x00087365 )
+#define ICU_IPR102_ADDR			( ( volatile uint8_t __evenaccess * )0x00087366 )
+#define ICU_IPR103_ADDR			( ( volatile uint8_t __evenaccess * )0x00087367 )
+#define ICU_IPR104_ADDR			( ( volatile uint8_t __evenaccess * )0x00087368 )
+#define ICU_IPR105_ADDR			( ( volatile uint8_t __evenaccess * )0x00087369 )
+#define ICU_IPR106_ADDR			( ( volatile uint8_t __evenaccess * )0x0008736A )
+#define ICU_IPR107_ADDR			( ( volatile uint8_t __evenaccess * )0x0008736B )
+#define ICU_IPR108_ADDR			( ( volatile uint8_t __evenaccess * )0x0008736C )
+#define ICU_IPR109_ADDR			( ( volatile uint8_t __evenaccess * )0x0008736D )
+#define ICU_IPR110_ADDR			( ( volatile uint8_t __evenaccess * )0x0008736E )
+#define ICU_IPR111_ADDR			( ( volatile uint8_t __evenaccess * )0x0008736F )
+#define ICU_IPR112_ADDR			( ( volatile uint8_t __evenaccess * )0x00087370 )
+#define ICU_IPR113_ADDR			( ( volatile uint8_t __evenaccess * )0x00087371 )
+#define ICU_IPR114_ADDR			( ( volatile uint8_t __evenaccess * )0x00087372 )
+#define ICU_IPR115_ADDR			( ( volatile uint8_t __evenaccess * )0x00087373 )
+#define ICU_IPR116_ADDR			( ( volatile uint8_t __evenaccess * )0x00087374 )
+#define ICU_IPR117_ADDR			( ( volatile uint8_t __evenaccess * )0x00087375 )
+#define ICU_IPR118_ADDR			( ( volatile uint8_t __evenaccess * )0x00087376 )
+#define ICU_IPR119_ADDR			( ( volatile uint8_t __evenaccess * )0x00087377 )
+#define ICU_IPR120_ADDR			( ( volatile uint8_t __evenaccess * )0x00087378 )
+#define ICU_IPR121_ADDR			( ( volatile uint8_t __evenaccess * )0x00087379 )
+#define ICU_IPR122_ADDR			( ( volatile uint8_t __evenaccess * )0x0008737A )
+#define ICU_IPR123_ADDR			( ( volatile uint8_t __evenaccess * )0x0008737B )
+#define ICU_IPR124_ADDR			( ( volatile uint8_t __evenaccess * )0x0008737C )
+#define ICU_IPR125_ADDR			( ( volatile uint8_t __evenaccess * )0x0008737D )
+#define ICU_IPR126_ADDR			( ( volatile uint8_t __evenaccess * )0x0008737E )
+#define ICU_IPR127_ADDR			( ( volatile uint8_t __evenaccess * )0x0008737F )
+#define ICU_IPR128_ADDR			( ( volatile uint8_t __evenaccess * )0x00087380 )
+#define ICU_IPR129_ADDR			( ( volatile uint8_t __evenaccess * )0x00087381 )
+#define ICU_IPR130_ADDR			( ( volatile uint8_t __evenaccess * )0x00087382 )
+#define ICU_IPR131_ADDR			( ( volatile uint8_t __evenaccess * )0x00087383 )
+#define ICU_IPR132_ADDR			( ( volatile uint8_t __evenaccess * )0x00087384 )
+#define ICU_IPR133_ADDR			( ( volatile uint8_t __evenaccess * )0x00087385 )
+#define ICU_IPR134_ADDR			( ( volatile uint8_t __evenaccess * )0x00087386 )
+#define ICU_IPR135_ADDR			( ( volatile uint8_t __evenaccess * )0x00087387 )
+#define ICU_IPR136_ADDR			( ( volatile uint8_t __evenaccess * )0x00087388 )
+#define ICU_IPR137_ADDR			( ( volatile uint8_t __evenaccess * )0x00087389 )
+#define ICU_IPR138_ADDR			( ( volatile uint8_t __evenaccess * )0x0008738A )
+#define ICU_IPR139_ADDR			( ( volatile uint8_t __evenaccess * )0x0008738B )
+#define ICU_IPR140_ADDR			( ( volatile uint8_t __evenaccess * )0x0008738C )
+#define ICU_IPR141_ADDR			( ( volatile uint8_t __evenaccess * )0x0008738D )
+#define ICU_IPR142_ADDR			( ( volatile uint8_t __evenaccess * )0x0008738E )
+#define ICU_IPR143_ADDR			( ( volatile uint8_t __evenaccess * )0x0008738F )
+#define ICU_IPR144_ADDR			( ( volatile uint8_t __evenaccess * )0x00087390 )
+#define ICU_IPR145_ADDR			( ( volatile uint8_t __evenaccess * )0x00087391 )
+#define ICU_IPR146_ADDR			( ( volatile uint8_t __evenaccess * )0x00087392 )
+#define ICU_IPR147_ADDR			( ( volatile uint8_t __evenaccess * )0x00087393 )
+#define ICU_IPR148_ADDR			( ( volatile uint8_t __evenaccess * )0x00087394 )
+#define ICU_IPR149_ADDR			( ( volatile uint8_t __evenaccess * )0x00087395 )
+#define ICU_IPR150_ADDR			( ( volatile uint8_t __evenaccess * )0x00087396 )
+#define ICU_IPR151_ADDR			( ( volatile uint8_t __evenaccess * )0x00087397 )
+#define ICU_IPR152_ADDR			( ( volatile uint8_t __evenaccess * )0x00087398 )
+#define ICU_IPR153_ADDR			( ( volatile uint8_t __evenaccess * )0x00087399 )
+#define ICU_IPR154_ADDR			( ( volatile uint8_t __evenaccess * )0x0008739A )
+#define ICU_IPR155_ADDR			( ( volatile uint8_t __evenaccess * )0x0008739B )
+#define ICU_IPR156_ADDR			( ( volatile uint8_t __evenaccess * )0x0008739C )
+#define ICU_IPR157_ADDR			( ( volatile uint8_t __evenaccess * )0x0008739D )
+#define ICU_IPR158_ADDR			( ( volatile uint8_t __evenaccess * )0x0008739E )
+#define ICU_IPR159_ADDR			( ( volatile uint8_t __evenaccess * )0x0008739F )
+#define ICU_IPR160_ADDR			( ( volatile uint8_t __evenaccess * )0x000873A0 )
+#define ICU_IPR161_ADDR			( ( volatile uint8_t __evenaccess * )0x000873A1 )
+#define ICU_IPR162_ADDR			( ( volatile uint8_t __evenaccess * )0x000873A2 )
+#define ICU_IPR163_ADDR			( ( volatile uint8_t __evenaccess * )0x000873A3 )
+#define ICU_IPR164_ADDR			( ( volatile uint8_t __evenaccess * )0x000873A4 )
+#define ICU_IPR165_ADDR			( ( volatile uint8_t __evenaccess * )0x000873A5 )
+#define ICU_IPR166_ADDR			( ( volatile uint8_t __evenaccess * )0x000873A6 )
+#define ICU_IPR167_ADDR			( ( volatile uint8_t __evenaccess * )0x000873A7 )
+#define ICU_IPR168_ADDR			( ( volatile uint8_t __evenaccess * )0x000873A8 )
+#define ICU_IPR169_ADDR			( ( volatile uint8_t __evenaccess * )0x000873A9 )
+#define ICU_IPR170_ADDR			( ( volatile uint8_t __evenaccess * )0x000873AA )
+#define ICU_IPR171_ADDR			( ( volatile uint8_t __evenaccess * )0x000873AB )
+#define ICU_IPR172_ADDR			( ( volatile uint8_t __evenaccess * )0x000873AC )
+#define ICU_IPR173_ADDR			( ( volatile uint8_t __evenaccess * )0x000873AD )
+#define ICU_IPR174_ADDR			( ( volatile uint8_t __evenaccess * )0x000873AE )
+#define ICU_IPR175_ADDR			( ( volatile uint8_t __evenaccess * )0x000873AF )
+#define ICU_IPR176_ADDR			( ( volatile uint8_t __evenaccess * )0x000873B0 )
+#define ICU_IPR177_ADDR			( ( volatile uint8_t __evenaccess * )0x000873B1 )
+#define ICU_IPR178_ADDR			( ( volatile uint8_t __evenaccess * )0x000873B2 )
+#define ICU_IPR179_ADDR			( ( volatile uint8_t __evenaccess * )0x000873B3 )
+#define ICU_IPR180_ADDR			( ( volatile uint8_t __evenaccess * )0x000873B4 )
+#define ICU_IPR181_ADDR			( ( volatile uint8_t __evenaccess * )0x000873B5 )
+#define ICU_IPR182_ADDR			( ( volatile uint8_t __evenaccess * )0x000873B6 )
+#define ICU_IPR183_ADDR			( ( volatile uint8_t __evenaccess * )0x000873B7 )
+#define ICU_IPR184_ADDR			( ( volatile uint8_t __evenaccess * )0x000873B8 )
+#define ICU_IPR185_ADDR			( ( volatile uint8_t __evenaccess * )0x000873B9 )
+#define ICU_IPR186_ADDR			( ( volatile uint8_t __evenaccess * )0x000873BA )
+#define ICU_IPR187_ADDR			( ( volatile uint8_t __evenaccess * )0x000873BB )
+#define ICU_IPR188_ADDR			( ( volatile uint8_t __evenaccess * )0x000873BC )
+#define ICU_IPR189_ADDR			( ( volatile uint8_t __evenaccess * )0x000873BD )
+#define ICU_IPR190_ADDR			( ( volatile uint8_t __evenaccess * )0x000873BE )
+#define ICU_IPR191_ADDR			( ( volatile uint8_t __evenaccess * )0x000873BF )
+#define ICU_IPR192_ADDR			( ( volatile uint8_t __evenaccess * )0x000873C0 )
+#define ICU_IPR193_ADDR			( ( volatile uint8_t __evenaccess * )0x000873C1 )
+#define ICU_IPR194_ADDR			( ( volatile uint8_t __evenaccess * )0x000873C2 )
+#define ICU_IPR195_ADDR			( ( volatile uint8_t __evenaccess * )0x000873C3 )
+#define ICU_IPR196_ADDR			( ( volatile uint8_t __evenaccess * )0x000873C4 )
+#define ICU_IPR197_ADDR			( ( volatile uint8_t __evenaccess * )0x000873C5 )
+#define ICU_IPR198_ADDR			( ( volatile uint8_t __evenaccess * )0x000873C6 )
+#define ICU_IPR199_ADDR			( ( volatile uint8_t __evenaccess * )0x000873C7 )
+#define ICU_IPR200_ADDR			( ( volatile uint8_t __evenaccess * )0x000873C8 )
+#define ICU_IPR201_ADDR			( ( volatile uint8_t __evenaccess * )0x000873C9 )
+#define ICU_IPR202_ADDR			( ( volatile uint8_t __evenaccess * )0x000873CA )
+#define ICU_IPR203_ADDR			( ( volatile uint8_t __evenaccess * )0x000873CB )
+#define ICU_IPR204_ADDR			( ( volatile uint8_t __evenaccess * )0x000873CC )
+#define ICU_IPR205_ADDR			( ( volatile uint8_t __evenaccess * )0x000873CD )
+#define ICU_IPR206_ADDR			( ( volatile uint8_t __evenaccess * )0x000873CE )
+#define ICU_IPR207_ADDR			( ( volatile uint8_t __evenaccess * )0x000873CF )
+#define ICU_IPR208_ADDR			( ( volatile uint8_t __evenaccess * )0x000873D0 )
+#define ICU_IPR209_ADDR			( ( volatile uint8_t __evenaccess * )0x000873D1 )
+#define ICU_IPR210_ADDR			( ( volatile uint8_t __evenaccess * )0x000873D2 )
+#define ICU_IPR211_ADDR			( ( volatile uint8_t __evenaccess * )0x000873D3 )
+#define ICU_IPR212_ADDR			( ( volatile uint8_t __evenaccess * )0x000873D4 )
+#define ICU_IPR213_ADDR			( ( volatile uint8_t __evenaccess * )0x000873D5 )
+#define ICU_IPR214_ADDR			( ( volatile uint8_t __evenaccess * )0x000873D6 )
+#define ICU_IPR215_ADDR			( ( volatile uint8_t __evenaccess * )0x000873D7 )
+#define ICU_IPR216_ADDR			( ( volatile uint8_t __evenaccess * )0x000873D8 )
+#define ICU_IPR217_ADDR			( ( volatile uint8_t __evenaccess * )0x000873D9 )
+#define ICU_IPR218_ADDR			( ( volatile uint8_t __evenaccess * )0x000873DA )
+#define ICU_IPR219_ADDR			( ( volatile uint8_t __evenaccess * )0x000873DB )
+#define ICU_IPR220_ADDR			( ( volatile uint8_t __evenaccess * )0x000873DC )
+#define ICU_IPR221_ADDR			( ( volatile uint8_t __evenaccess * )0x000873DD )
+#define ICU_IPR222_ADDR			( ( volatile uint8_t __evenaccess * )0x000873DE )
+#define ICU_IPR223_ADDR			( ( volatile uint8_t __evenaccess * )0x000873DF )
+#define ICU_IPR224_ADDR			( ( volatile uint8_t __evenaccess * )0x000873E0 )
+#define ICU_IPR225_ADDR			( ( volatile uint8_t __evenaccess * )0x000873E1 )
+#define ICU_IPR226_ADDR			( ( volatile uint8_t __evenaccess * )0x000873E2 )
+#define ICU_IPR227_ADDR			( ( volatile uint8_t __evenaccess * )0x000873E3 )
+#define ICU_IPR228_ADDR			( ( volatile uint8_t __evenaccess * )0x000873E4 )
+#define ICU_IPR229_ADDR			( ( volatile uint8_t __evenaccess * )0x000873E5 )
+#define ICU_IPR230_ADDR			( ( volatile uint8_t __evenaccess * )0x000873E6 )
+#define ICU_IPR231_ADDR			( ( volatile uint8_t __evenaccess * )0x000873E7 )
+#define ICU_IPR232_ADDR			( ( volatile uint8_t __evenaccess * )0x000873E8 )
+#define ICU_IPR233_ADDR			( ( volatile uint8_t __evenaccess * )0x000873E9 )
+#define ICU_IPR234_ADDR			( ( volatile uint8_t __evenaccess * )0x000873EA )
+#define ICU_IPR235_ADDR			( ( volatile uint8_t __evenaccess * )0x000873EB )
+#define ICU_IPR236_ADDR			( ( volatile uint8_t __evenaccess * )0x000873EC )
+#define ICU_IPR237_ADDR			( ( volatile uint8_t __evenaccess * )0x000873ED )
+#define ICU_IPR238_ADDR			( ( volatile uint8_t __evenaccess * )0x000873EE )
+#define ICU_IPR239_ADDR			( ( volatile uint8_t __evenaccess * )0x000873EF )
+#define ICU_IPR240_ADDR			( ( volatile uint8_t __evenaccess * )0x000873F0 )
+#define ICU_IPR241_ADDR			( ( volatile uint8_t __evenaccess * )0x000873F1 )
+#define ICU_IPR242_ADDR			( ( volatile uint8_t __evenaccess * )0x000873F2 )
+#define ICU_IPR243_ADDR			( ( volatile uint8_t __evenaccess * )0x000873F3 )
+#define ICU_IPR244_ADDR			( ( volatile uint8_t __evenaccess * )0x000873F4 )
+#define ICU_IPR245_ADDR			( ( volatile uint8_t __evenaccess * )0x000873F5 )
+#define ICU_IPR246_ADDR			( ( volatile uint8_t __evenaccess * )0x000873F6 )
+#define ICU_IPR247_ADDR			( ( volatile uint8_t __evenaccess * )0x000873F7 )
+#define ICU_IPR248_ADDR			( ( volatile uint8_t __evenaccess * )0x000873F8 )
+#define ICU_IPR249_ADDR			( ( volatile uint8_t __evenaccess * )0x000873F9 )
+#define ICU_IPR250_ADDR			( ( volatile uint8_t __evenaccess * )0x000873FA )
+#define ICU_IPR251_ADDR			( ( volatile uint8_t __evenaccess * )0x000873FB )
+#define ICU_IPR252_ADDR			( ( volatile uint8_t __evenaccess * )0x000873FC )
+#define ICU_IPR253_ADDR			( ( volatile uint8_t __evenaccess * )0x000873FD )
+#define ICU_IPR254_ADDR			( ( volatile uint8_t __evenaccess * )0x000873FE )
+#define ICU_IPR255_ADDR			( ( volatile uint8_t __evenaccess * )0x000873FF )
+#define ICU_IPR_OFFSET			( 0U )
+#define ICU_IPR_MASK			( 0xFU << ICU_IPR_OFFSET )
+
+/*
+ *  IRQコントロールレジスタ
+ */
+#define ICU_IRQ0_ADDR			( ( volatile uint8_t __evenaccess * )0x00087500 )
+#define ICU_IRQ1_ADDR			( ( volatile uint8_t __evenaccess * )0x00087501 )
+#define ICU_IRQ2_ADDR			( ( volatile uint8_t __evenaccess * )0x00087502 )
+#define ICU_IRQ3_ADDR			( ( volatile uint8_t __evenaccess * )0x00087503 )
+#define ICU_IRQ4_ADDR			( ( volatile uint8_t __evenaccess * )0x00087504 )
+#define ICU_IRQ5_ADDR			( ( volatile uint8_t __evenaccess * )0x00087505 )
+#define ICU_IRQ6_ADDR			( ( volatile uint8_t __evenaccess * )0x00087506 )
+#define ICU_IRQ7_ADDR			( ( volatile uint8_t __evenaccess * )0x00087507 )
+#define ICU_IRQ8_ADDR			( ( volatile uint8_t __evenaccess * )0x00087508 )
+#define ICU_IRQ9_ADDR			( ( volatile uint8_t __evenaccess * )0x00087509 )
+#define ICU_IRQ10_ADDR			( ( volatile uint8_t __evenaccess * )0x0008750A )
+#define ICU_IRQ11_ADDR			( ( volatile uint8_t __evenaccess * )0x0008750B )
+#define ICU_IRQ12_ADDR			( ( volatile uint8_t __evenaccess * )0x0008750C )
+#define ICU_IRQ13_ADDR			( ( volatile uint8_t __evenaccess * )0x0008750D )
+#define ICU_IRQ14_ADDR			( ( volatile uint8_t __evenaccess * )0x0008750E )
+#define ICU_IRQ15_ADDR			( ( volatile uint8_t __evenaccess * )0x0008750F )
+#define ICU_IRQMD_BIT			( 3U << 2U )
+
+
+/*
+ *  各チャンネルのレジスタ及び設定ビット情報
+ */
+#define CMT_CMSTR0_ADDR			( ( volatile uint16_t __evenaccess * )0x00088000 )
+#define CMT_CMSTR0_STR0_BIT		( 1U << 0U )
+#define CMT_CMSTR0_STR1_BIT		( 1U << 1U )
+#define CMT_CMSTR1_ADDR			( ( volatile uint16_t __evenaccess * )0x00088010 )
+#define CMT_CMSTR1_STR2_BIT		( 1U << 0U )
+#define CMT_CMSTR1_STR3_BIT		( 1U << 1U )
+#define CMT0_CMCR_ADDR			( ( volatile uint16_t __evenaccess * )0x00088002 )
+#define CMT0_CMCR_CKS_BIT		( 3U )
+#define CMT0_CMCR_CMIE_BIT		( 1U << 6U )
+#define CMT1_CMCR_ADDR			( ( volatile uint16_t __evenaccess * )0x00088008 )
+#define CMT1_CMCR_CKS_BIT		( 3U )
+#define CMT1_CMCR_CMIE_BIT		( 1U << 6U )
+#define CMT2_CMCR_ADDR			( ( volatile uint16_t __evenaccess * )0x00088012 )
+#define CMT2_CMCR_CKS_BIT		( 3U)
+#define CMT2_CMCR_CMIE_BIT		( 1U << 6U )
+#define CMT3_CMCR_ADDR			( ( volatile uint16_t __evenaccess * )0x00088018 )
+#define CMT3_CMCR_CKS_BIT		( 3U )
+#define CMT3_CMCR_CMIE_BIT		( 1U << 6U )
+#define CMT0_CMCNT_ADDR			( ( volatile uint16_t __evenaccess * )0x00088004 )
+#define CMT1_CMCNT_ADDR			( ( volatile uint16_t __evenaccess * )0x0008800A )
+#define CMT2_CMCNT_ADDR			( ( volatile uint16_t __evenaccess * )0x00088014 )
+#define CMT3_CMCNT_ADDR			( ( volatile uint16_t __evenaccess * )0x0008801A )
+#define CMT0_CMCOR_ADDR			( ( volatile uint16_t __evenaccess * )0x00088006 )
+#define CMT1_CMCOR_ADDR			( ( volatile uint16_t __evenaccess * )0x0008800C )
+#define CMT2_CMCOR_ADDR			( ( volatile uint16_t __evenaccess * )0x00088016 )
+#define CMT3_CMCOR_ADDR			( ( volatile uint16_t __evenaccess * )0x0008801C )
+
+#define SCI0_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A000 )
+#define SCI0_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A001 )
+#define SCI0_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A002 )
+#define SCI0_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A003 )
+#define SCI0_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A004 )
+#define SCI0_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A005 )
+#define SCI0_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A006 )
+#define SCI0_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A007 )
+#define SCI1_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A020 )
+#define SCI1_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A021 )
+#define SCI1_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A022 )
+#define SCI1_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A023 )
+#define SCI1_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A024 )
+#define SCI1_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A025 )
+#define SCI1_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A026 )
+#define SCI1_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A027 )
+#define SCI2_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A040 )
+#define SCI2_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A041 )
+#define SCI2_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A042 )
+#define SCI2_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A043 )
+#define SCI2_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A044 )
+#define SCI2_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A045 )
+#define SCI2_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A046 )
+#define SCI2_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A047 )
+#define SCI3_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A060 )
+#define SCI3_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A061 )
+#define SCI3_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A062 )
+#define SCI3_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A063 )
+#define SCI3_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A064 )
+#define SCI3_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A065 )
+#define SCI3_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A066 )
+#define SCI3_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A067 )
+#define SCI4_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A080 )
+#define SCI4_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A081 )
+#define SCI4_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A082 )
+#define SCI4_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A083 )
+#define SCI4_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A084 )
+#define SCI4_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A085 )
+#define SCI4_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A086 )
+#define SCI4_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A087 )
+#define SCI5_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0A0 )
+#define SCI5_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0A1 )
+#define SCI5_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0A2 )
+#define SCI5_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0A3 )
+#define SCI5_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0A4 )
+#define SCI5_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0A5 )
+#define SCI5_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0A6 )
+#define SCI5_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0A7 )
+#define SCI6_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0C0 )
+#define SCI6_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0C1 )
+#define SCI6_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0C2 )
+#define SCI6_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0C3 )
+#define SCI6_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0C4 )
+#define SCI6_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0C5 )
+#define SCI6_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0C6 )
+#define SCI6_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0C7 )
+#define SCI7_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0E0 )
+#define SCI7_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0E1 )
+#define SCI7_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0E2 )
+#define SCI7_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0E3 )
+#define SCI7_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0E4 )
+#define SCI7_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0E5 )
+#define SCI7_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0E6 )
+#define SCI7_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A0E7 )
+#define SCI8_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A100 )
+#define SCI8_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A101 )
+#define SCI8_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A102 )
+#define SCI8_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A103 )
+#define SCI8_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A104 )
+#define SCI8_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A105 )
+#define SCI8_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A106 )
+#define SCI8_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A107 )
+#define SCI9_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A120 )
+#define SCI9_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A121 )
+#define SCI9_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A122 )
+#define SCI9_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A123 )
+#define SCI9_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A124 )
+#define SCI9_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A125 )
+#define SCI9_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A126 )
+#define SCI9_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A127 )
+#define SCI10_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A140 )
+#define SCI10_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A141 )
+#define SCI10_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A142 )
+#define SCI10_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A143 )
+#define SCI10_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A144 )
+#define SCI10_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A145 )
+#define SCI10_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A146 )
+#define SCI10_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A147 )
+#define SCI11_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A160 )
+#define SCI11_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A161 )
+#define SCI11_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A162 )
+#define SCI11_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A163 )
+#define SCI11_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A164 )
+#define SCI11_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A165 )
+#define SCI11_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A166 )
+#define SCI11_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A167 )
+#define SCI12_SMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A300 )
+#define SCI12_BRR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A301 )
+#define SCI12_SCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A302 )
+#define SCI12_TDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A303 )
+#define SCI12_SSR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A304 )
+#define SCI12_RDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A305 )
+#define SCI12_SCMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A306 )
+#define SCI12_SEMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008A307 )
+#define SCI_SMR_CKS_BIT			( 3U << 0U )
+#define SCI_SMR_STOP_BIT		( 1U << 3U )
+#define SCI_SMR_PM_BIT			( 1U << 4U )
+#define SCI_SMR_PE_BIT			( 1U << 5U )
+#define SCI_SMR_CHR_BIT			( 1U << 6U )
+#define SCI_SMR_CM_BIT			( 1U << 7U )
+#define SCI_SCR_CKE_BIT			( 3U << 0U )
+#define SCI_SCR_TEIE_BIT		( 1U << 2U )
+#define SCI_SCR_RE_BIT			( 1U << 4U )
+#define SCI_SCR_TE_BIT			( 1U << 5U )
+#define SCI_SCR_RIE_BIT			( 1U << 6U )
+#define SCI_SCR_TIE_BIT			( 1U << 7U )
+#define SCI_SSR_TEND_BIT		( 1U << 2U )
+#define SCI_SSR_PER_BIT			( 1U << 3U )
+#define SCI_SSR_FER_BIT			( 1U << 4U )
+#define SCI_SSR_ORER_BIT		( 1U << 5U )
+#define SCI_SCMR_SMIF_BIT		( 1U << 0U )
+#define SCI_SCMR_SINV_BIT		( 1U << 2U )
+#define SCI_SCMR_SDIR_BIT		( 1U << 3U )
+#define SCI_SCMR_BCP2_BIT		( 1U << 7U )
+#define SCI_SEMR_ACS0_BIT		( 1U << 0U )
+#define SCI_SEMR_ABCS_BIT		( 1U << 4U )
+
+/*
+ *  I/Oポートのレジスタ及び設定ビット情報
+ */
+#define PORT0_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C000 )
+#define PORT1_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C001 )
+#define PORT2_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C002 )
+#define PORT3_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C003 )
+#define PORT4_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C004 )
+#define PORT5_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C005 )
+#define PORT6_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C006 )
+#define PORT7_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C007 )
+#define PORT8_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C008 )
+#define PORT9_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C009 )
+#define PORTA_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C00A )
+#define PORTB_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C00B )
+#define PORTC_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C00C )
+#define PORTD_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C00D )
+#define PORTE_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C00E )
+#define PORTF_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C00F )
+#define PORTG_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C010 )
+#define PORTJ_PDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C012 )
+#define PORT_PDR_B0_BIT			( 0x01U << 0U )
+#define PORT_PDR_B1_BIT			( 0x01U << 1U )
+#define PORT_PDR_B2_BIT			( 0x01U << 2U )
+#define PORT_PDR_B3_BIT			( 0x01U << 3U )
+#define PORT_PDR_B4_BIT			( 0x01U << 4U )
+#define PORT_PDR_B5_BIT			( 0x01U << 5U )
+#define PORT_PDR_B6_BIT			( 0x01U << 6U )
+#define PORT_PDR_B7_BIT			( 0x01U << 7U )
+#define PORT0_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C020 )
+#define PORT1_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C021 )
+#define PORT2_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C022 )
+#define PORT3_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C023 )
+#define PORT4_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C024 )
+#define PORT5_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C025 )
+#define PORT6_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C026 )
+#define PORT7_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C027 )
+#define PORT8_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C028 )
+#define PORT9_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C029 )
+#define PORTA_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C02A )
+#define PORTB_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C02B )
+#define PORTC_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C02C )
+#define PORTD_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C02D )
+#define PORTE_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C02E )
+#define PORTF_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C02F )
+#define PORTG_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C030 )
+#define PORTJ_PODR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C032 )
+#define PORT_PODR_B0_BIT		( 0x01U << 0U )
+#define PORT_PODR_B1_BIT		( 0x01U << 1U )
+#define PORT_PODR_B2_BIT		( 0x01U << 2U )
+#define PORT_PODR_B3_BIT		( 0x01U << 3U )
+#define PORT_PODR_B4_BIT		( 0x01U << 4U )
+#define PORT_PODR_B5_BIT		( 0x01U << 5U )
+#define PORT_PODR_B6_BIT		( 0x01U << 6U )
+#define PORT_PODR_B7_BIT		( 0x01U << 7U )
+#define PORT0_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C040 )
+#define PORT1_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C041 )
+#define PORT2_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C042 )
+#define PORT3_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C043 )
+#define PORT4_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C044 )
+#define PORT5_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C045 )
+#define PORT6_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C046 )
+#define PORT7_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C047 )
+#define PORT8_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C048 )
+#define PORT9_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C049 )
+#define PORTA_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C04A )
+#define PORTB_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C04B )
+#define PORTC_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C04C )
+#define PORTD_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C04D )
+#define PORTE_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C04E )
+#define PORTF_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C04F )
+#define PORTG_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C050 )
+#define PORTJ_PIDR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C052 )
+#define PORT_PIDR_B0_BIT		( 0x01U << 0U )
+#define PORT_PIDR_B1_BIT		( 0x01U << 1U )
+#define PORT_PIDR_B2_BIT		( 0x01U << 2U )
+#define PORT_PIDR_B3_BIT		( 0x01U << 3U )
+#define PORT_PIDR_B4_BIT		( 0x01U << 4U )
+#define PORT_PIDR_B5_BIT		( 0x01U << 5U )
+#define PORT_PIDR_B6_BIT		( 0x01U << 6U )
+#define PORT_PIDR_B7_BIT		( 0x01U << 7U )
+#define PORT0_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C060 )
+#define PORT1_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C061 )
+#define PORT2_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C062 )
+#define PORT3_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C063 )
+#define PORT4_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C064 )
+#define PORT5_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C065 )
+#define PORT6_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C066 )
+#define PORT7_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C067 )
+#define PORT8_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C068 )
+#define PORT9_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C069 )
+#define PORTA_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C06A )
+#define PORTB_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C06B )
+#define PORTC_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C06C )
+#define PORTD_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C06D )
+#define PORTE_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C06E )
+#define PORTF_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C06F )
+#define PORTG_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C070 )
+#define PORTJ_PMR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C072 )
+#define PORT_PMR_B0_BIT			( 0x01U << 0U )
+#define PORT_PMR_B1_BIT			( 0x01U << 1U )
+#define PORT_PMR_B2_BIT			( 0x01U << 2U )
+#define PORT_PMR_B3_BIT			( 0x01U << 3U )
+#define PORT_PMR_B4_BIT			( 0x01U << 4U )
+#define PORT_PMR_B5_BIT			( 0x01U << 5U )
+#define PORT_PMR_B6_BIT			( 0x01U << 6U )
+#define PORT_PMR_B7_BIT			( 0x01U << 7U )
+#define PORT0_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0C0 )
+#define PORT1_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0C1 )
+#define PORT2_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0C2 )
+#define PORT3_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0C3 )
+#define PORT4_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0C4 )
+#define PORT5_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0C5 )
+#define PORT6_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0C6 )
+#define PORT7_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0C7 )
+#define PORT8_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0C8 )
+#define PORT9_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0C9 )
+#define PORTA_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0CA )
+#define PORTB_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0CB )
+#define PORTC_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0CC )
+#define PORTD_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0CD )
+#define PORTE_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0CE )
+#define PORTF_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0CF )
+#define PORTG_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0D0 )
+#define PORTJ_PCR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0D2 )
+#define PORT_PCR_B0_BIT			( 0x01U << 0U )
+#define PORT_PCR_B1_BIT			( 0x01U << 1U )
+#define PORT_PCR_B2_BIT			( 0x01U << 2U )
+#define PORT_PCR_B3_BIT			( 0x01U << 3U )
+#define PORT_PCR_B4_BIT			( 0x01U << 4U )
+#define PORT_PCR_B5_BIT			( 0x01U << 5U )
+#define PORT_PCR_B6_BIT			( 0x01U << 6U )
+#define PORT_PCR_B7_BIT			( 0x01U << 7U )
+#define PORT0_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C080 )
+#define PORT1_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C082 )
+#define PORT2_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C084 )
+#define PORT3_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C086 )
+#define PORT4_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C088 )
+#define PORT5_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C08A )
+#define PORT6_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C08C )
+#define PORT7_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C08E )
+#define PORT8_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C090 )
+#define PORT9_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C092 )
+#define PORTA_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C094 )
+#define PORTB_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C096 )
+#define PORTC_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C098 )
+#define PORTD_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C09A )
+#define PORTE_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C09C )
+#define PORTF_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C09E )
+#define PORTG_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0A0 )
+#define PORTJ_ODR0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0A4 )
+#define PORT0_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C081 )
+#define PORT1_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C083 )
+#define PORT2_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C085 )
+#define PORT3_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C087 )
+#define PORT4_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C089 )
+#define PORT5_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C08B )
+#define PORT6_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C08D )
+#define PORT7_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C08F )
+#define PORT8_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C091 )
+#define PORT9_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C093 )
+#define PORTA_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C095 )
+#define PORTB_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C097 )
+#define PORTC_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C099 )
+#define PORTD_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C09B )
+#define PORTE_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C09D )
+#define PORTF_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C09F )
+#define PORTG_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0A1 )
+#define PORTJ_ODR1_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C0A5 )
+#define PORT_ODR_Pm0_OFFSET		( 0U )
+#define PORT_ODR_Pm0_MASK		( 0x3U << PORT_ODR_Pm0_OFFSET )
+#define PORT_ODR_Pm1_OFFSET		( 2U )
+#define PORT_ODR_Pm1_MASK		( 0x3U << PORT_ODR_Pm1_OFFSET )
+#define PORT_ODR_Pm2_OFFSET		( 4U )
+#define PORT_ODR_Pm2_MASK		( 0x3U << PORT_ODR_Pm2_OFFSET )
+#define PORT_ODR_Pm3_OFFSET		( 6U )
+#define PORT_ODR_Pm3_MASK		( 0x3U << PORT_ODR_Pm3_OFFSET )
+#define PORT_ODR_Pm4_OFFSET		( 0U )
+#define PORT_ODR_Pm4_MASK		( 0x3U << PORT_ODR_Pm4_OFFSET )
+#define PORT_ODR_Pm5_OFFSET		( 2U )
+#define PORT_ODR_Pm5_MASK		( 0x3U << PORT_ODR_Pm5_OFFSET )
+#define PORT_ODR_Pm6_OFFSET		( 4U )
+#define PORT_ODR_Pm6_MASK		( 0x3U << PORT_ODR_Pm6_OFFSET )
+#define PORT_ODR_Pm7_OFFSET		( 6U )
+#define PORT_ODR_Pm7_MASK		( 0x3U << PORT_ODR_Pm7_OFFSET )
+#define PORT_ODR_CMOS			( 0U )
+#define PORT_ODR_NCH_OPEN_DRAIN	( 1U )
+#define PORT_ODR_PCH_OPEN_DRAIN	( 2U )
+
+/*
+ *  マルチファンクションピンコントローラのレジスタ情報
+ */
+#define MPC_PFUSB0_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C114 )
+#define MPC_PFUSB0_PDHZS_BIT	( 0x01U << 2U )
+#define MPC_PFUSB0_PUPHZS_BIT	( 0x01U << 3U )
+#define MPC_PWPR_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C11F )
+#define MPC_PWPR_PFSWE			( 0x01U << 6U )
+#define MPC_PWPR_B0WI			( 0x01U << 7U )
+#define MPC_P00PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C140 )
+#define MPC_P01PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C141 )
+#define MPC_P02PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C142 )
+#define MPC_P03PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C143 )
+#define MPC_P04PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C144 )
+#define MPC_P05PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C145 )
+#define MPC_P06PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C146 )
+#define MPC_P07PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C147 )
+#define MPC_P10PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C148 )
+#define MPC_P11PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C149 )
+#define MPC_P12PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C14A )
+#define MPC_P13PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C14B )
+#define MPC_P14PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C14C )
+#define MPC_P15PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C14D )
+#define MPC_P16PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C14E )
+#define MPC_P17PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C14F )
+#define MPC_P20PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C150 )
+#define MPC_P21PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C151 )
+#define MPC_P22PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C152 )
+#define MPC_P23PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C153 )
+#define MPC_P24PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C154 )
+#define MPC_P25PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C155 )
+#define MPC_P26PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C156 )
+#define MPC_P27PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C157 )
+#define MPC_P30PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C158 )
+#define MPC_P31PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C159 )
+#define MPC_P32PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C15A )
+#define MPC_P33PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C15B )
+#define MPC_P34PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C15C )
+#define MPC_P35PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C15D )
+#define MPC_P36PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C15E )
+#define MPC_P37PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C15F )
+#define MPC_P40PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C160 )
+#define MPC_P41PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C161 )
+#define MPC_P42PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C162 )
+#define MPC_P43PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C163 )
+#define MPC_P44PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C164 )
+#define MPC_P45PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C165 )
+#define MPC_P46PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C166 )
+#define MPC_P47PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C167 )
+#define MPC_P50PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C168 )
+#define MPC_P51PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C169 )
+#define MPC_P52PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C16A )
+#define MPC_P53PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C16B )
+#define MPC_P54PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C16C )
+#define MPC_P55PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C16D )
+#define MPC_P56PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C16E )
+#define MPC_P57PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C16F )
+#define MPC_P60PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C170 )
+#define MPC_P61PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C171 )
+#define MPC_P62PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C172 )
+#define MPC_P63PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C173 )
+#define MPC_P64PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C174 )
+#define MPC_P65PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C175 )
+#define MPC_P66PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C176 )
+#define MPC_P67PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C177 )
+#define MPC_P70PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C178 )
+#define MPC_P71PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C179 )
+#define MPC_P72PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C17A )
+#define MPC_P73PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C17B )
+#define MPC_P74PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C17C )
+#define MPC_P75PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C17D )
+#define MPC_P76PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C17E )
+#define MPC_P77PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C17F )
+#define MPC_P80PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C180 )
+#define MPC_P81PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C181 )
+#define MPC_P82PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C182 )
+#define MPC_P83PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C183 )
+#define MPC_P84PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C184 )
+#define MPC_P85PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C185 )
+#define MPC_P86PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C186 )
+#define MPC_P87PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C187 )
+#define MPC_P90PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C188 )
+#define MPC_P91PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C189 )
+#define MPC_P92PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C18A )
+#define MPC_P93PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C18B )
+#define MPC_P94PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C18C )
+#define MPC_P95PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C18D )
+#define MPC_P96PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C18E )
+#define MPC_P97PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C18F )
+#define MPC_PA0PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C190 )
+#define MPC_PA1PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C191 )
+#define MPC_PA2PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C192 )
+#define MPC_PA3PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C193 )
+#define MPC_PA4PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C194 )
+#define MPC_PA5PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C195 )
+#define MPC_PA6PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C196 )
+#define MPC_PA7PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C197 )
+#define MPC_PB0PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C198 )
+#define MPC_PB1PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C199 )
+#define MPC_PB2PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C19A )
+#define MPC_PB3PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C19B )
+#define MPC_PB4PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C19C )
+#define MPC_PB5PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C19D )
+#define MPC_PB6PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C19E )
+#define MPC_PB7PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C19F )
+#define MPC_PC0PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1A0 )
+#define MPC_PC1PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1A1 )
+#define MPC_PC2PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1A2 )
+#define MPC_PC3PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1A3 )
+#define MPC_PC4PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1A4 )
+#define MPC_PC5PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1A5 )
+#define MPC_PC6PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1A6 )
+#define MPC_PC7PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1A7 )
+#define MPC_PD0PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1A8 )
+#define MPC_PD1PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1A9 )
+#define MPC_PD2PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1AA )
+#define MPC_PD3PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1AB )
+#define MPC_PD4PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1AC )
+#define MPC_PD5PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1AD )
+#define MPC_PD6PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1AE )
+#define MPC_PD7PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1AF )
+#define MPC_PE0PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1B0 )
+#define MPC_PE1PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1B1 )
+#define MPC_PE2PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1B2 )
+#define MPC_PE3PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1B3 )
+#define MPC_PE4PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1B4 )
+#define MPC_PE5PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1B5 )
+#define MPC_PE6PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1B6 )
+#define MPC_PE7PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1B7 )
+#define MPC_PF0PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1B8 )
+#define MPC_PF1PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1B9 )
+#define MPC_PF2PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1BA )
+#define MPC_PF3PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1BB )
+#define MPC_PF4PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1BC )
+#define MPC_PF5PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1BD )
+#define MPC_PF6PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1BE )
+#define MPC_PF7PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1BF )
+#define MPC_PJ3PFS_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C1D3 )
+
+/*
+ * リアルタイムクロック
+ */
+#define RTC_R64CNT_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C400 )
+#define RTC_RSECCNT_ADDR		( ( volatile uint8_t __evenaccess * )0x0008C402 )
+#define RTC_RMINCNT_ADDR		( ( volatile uint8_t __evenaccess * )0x0008C404 )
+#define RTC_RHRCNT_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C406 )
+#define RTC_RWKCNT_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C408 )
+#define RTC_RDAYCNT_ADDR		( ( volatile uint8_t __evenaccess * )0x0008C40A )
+#define RTC_RMONCNT_ADDR		( ( volatile uint8_t __evenaccess * )0x0008C40C )
+#define RTC_RYRCNT_ADDR			( ( volatile uint8_t __evenaccess * )0x0008C40E )
+
+/*
+ * 12 ビットA/D コンバータ
+ */
+#define S12AD_ADCSR_ADDR		( ( volatile uint8_t __evenaccess * )0x00089000 )
+#define S12AD_ADCSR_ADST_BIT	0x80
+#define S12AD_ADANS0_ADDR		( ( volatile uint16_t __evenaccess * )0x00089004 )
+#define S12AD_ADANS1_ADDR		( ( volatile uint16_t __evenaccess * )0x00089006 )
+#define S12AD_ADEXICR_ADDR		( ( volatile uint16_t __evenaccess * )0x00089012 )
+#define S12AD_ADDR0_ADDR		( ( volatile uint16_t __evenaccess * )0x00089020 )
+#define S12AD_ADDR1_ADDR		( ( volatile uint16_t __evenaccess * )0x00089022 )
+#define S12AD_ADDR2_ADDR		( ( volatile uint16_t __evenaccess * )0x00089024 )
+#define S12AD_ADDR3_ADDR		( ( volatile uint16_t __evenaccess * )0x00089026 )
+#define S12AD_ADDR4_ADDR		( ( volatile uint16_t __evenaccess * )0x00089028 )
+#define S12AD_ADDR5_ADDR		( ( volatile uint16_t __evenaccess * )0x0008902A )
+#define S12AD_ADDR6_ADDR		( ( volatile uint16_t __evenaccess * )0x0008902C )
+#define S12AD_ADDR7_ADDR		( ( volatile uint16_t __evenaccess * )0x0008902E )
+#define S12AD_ADDR8_ADDR		( ( volatile uint16_t __evenaccess * )0x00089030 )
+#define S12AD_ADDR9_ADDR		( ( volatile uint16_t __evenaccess * )0x00089032 )
+#define S12AD_ADDR10_ADDR		( ( volatile uint16_t __evenaccess * )0x00089034 )
+#define S12AD_ADDR11_ADDR		( ( volatile uint16_t __evenaccess * )0x00089036 )
+#define S12AD_ADDR12_ADDR		( ( volatile uint16_t __evenaccess * )0x00089038 )
+#define S12AD_ADDR13_ADDR		( ( volatile uint16_t __evenaccess * )0x0008903A )
+#define S12AD_ADDR14_ADDR		( ( volatile uint16_t __evenaccess * )0x0008903C )
+#define S12AD_ADDR15_ADDR		( ( volatile uint16_t __evenaccess * )0x0008903E )
+#define S12AD_ADDR16_ADDR		( ( volatile uint16_t __evenaccess * )0x00089040 )
+#define S12AD_ADDR17_ADDR		( ( volatile uint16_t __evenaccess * )0x00089042 )
+#define S12AD_ADDR18_ADDR		( ( volatile uint16_t __evenaccess * )0x00089044 )
+#define S12AD_ADDR19_ADDR		( ( volatile uint16_t __evenaccess * )0x00089046 )
+#define S12AD_ADDR20_ADDR		( ( volatile uint16_t __evenaccess * )0x00089048 )
+
+#define TPU0_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088110 )
+#define TPU1_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088120 )
+#define TPU2_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088130 )
+#define TPU3_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088140 )
+#define TPU4_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088150 )
+#define TPU5_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088160 )
+#define TPU6_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088180 )
+#define TPU7_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088190 )
+#define TPU8_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881A0 )
+#define TPU9_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881B0 )
+#define TPU10_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881C0 )
+#define TPU11_TCR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881D0 )
+#define TPU_TCR_TPSC_OFFSET		( 0U )
+#define TPU_TCR_TPSC_MASK		( 0x7U << TPU_TCR_TPSC_OFFSET )
+#define TPU_TCR_CKEG_OFFSET		( 3U )
+#define TPU_TCR_CKEG_MASK		( 0x3U << TPU_TCR_CKEG_OFFSET )
+#define TPU_TCR_CCLR_OFFSET		( 5U )
+#define TPU_TCR_CCLR_MASK		( 0x7U << TPU_TCR_CCLR_OFFSET )
+
+#define TPU0_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088111 )
+#define TPU1_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088121 )
+#define TPU2_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088131 )
+#define TPU3_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088141 )
+#define TPU4_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088151 )
+#define TPU5_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088161 )
+#define TPU6_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088181 )
+#define TPU7_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088191 )
+#define TPU8_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881A1 )
+#define TPU9_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881B1 )
+#define TPU10_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881C1 )
+#define TPU11_TMDR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881D1 )
+#define TPU_TMDR_MD_OFFSET		( 0U )
+#define TPU_TMDR_MD_MASK		( 0xFU << TPU_TMDR_MD_OFFSET )
+#define TPU_TMDR_BFA_BIT		( 0x10 )
+#define TPU_TMDR_BFB_BIT		( 0x20 )
+#define TPU_TMDR_ICSELB_BIT		( 0x40 )
+#define TPU_TMDR_ICSELD_BIT		( 0x80 )
+
+#define TPU0_TIOR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881C0 )
+#define TPU0_TIORH_ADDR			( ( volatile uint8_t __evenaccess * )0x00088112 )
+#define TPU0_TIORL_ADDR			( ( volatile uint8_t __evenaccess * )0x00088113 )
+#define TPU1_TIOR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088122 )
+#define TPU2_TIOR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088132 )
+#define TPU3_TIORH_ADDR			( ( volatile uint8_t __evenaccess * )0x00088142 )
+#define TPU3_TIORL_ADDR			( ( volatile uint8_t __evenaccess * )0x00088143 )
+#define TPU4_TIOR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088152 )
+#define TPU5_TIOR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088162 )
+#define TPU6_TIORH_ADDR			( ( volatile uint8_t __evenaccess * )0x00088182 )
+#define TPU6_TIORL_ADDR			( ( volatile uint8_t __evenaccess * )0x00088183 )
+#define TPU7_TIOR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088192 )
+#define TPU8_TIOR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881A2 )
+#define TPU9_TIORH_ADDR			( ( volatile uint8_t __evenaccess * )0x000881B2 )
+#define TPU9_TIORL_ADDR			( ( volatile uint8_t __evenaccess * )0x000881B3 )
+#define TPU10_TIOR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881C2 )
+#define TPU11_TIOR_ADDR			( ( volatile uint8_t __evenaccess * )0x000881D2 )
+#define TPU_TIOR_IOA_OFFSET	( 0U )
+#define TPU_TIOR_IOA_MASK		( 0xFU << TPU_TIOR_IOA_OFFSET )
+#define TPU_TIOR_IOB_OFFSET	( 4U )
+#define TPU_TIOR_IOB_MASK		( 0xFU << TPU_TIOR_IOB_OFFSET )
+#define TPU_TIORH_IOA_OFFSET	( 0U )
+#define TPU_TIORH_IOA_MASK		( 0xFU << TPU_TIORH_IOA_OFFSET )
+#define TPU_TIORH_IOB_OFFSET	( 4U )
+#define TPU_TIORH_IOB_MASK		( 0xFU << TPU_TIORH_IOB_OFFSET )
+#define TPU_TIORL_IOC_OFFSET	( 0U )
+#define TPU_TIORL_IOC_MASK		( 0xFU << TPU_TIORL_IOC_OFFSET )
+#define TPU_TIORL_IOD_OFFSET	( 4U )
+#define TPU_TIORL_IOD_MASK		( 0xFU << TPU_TIORL_IOD_OFFSET )
+
+#define TPU0_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x00088118 )
+#define TPU0_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x0008811A )
+#define TPU0_TGRC_ADDR			( ( volatile uint16_t __evenaccess * )0x0008811C )
+#define TPU0_TGRD_ADDR			( ( volatile uint16_t __evenaccess * )0x0008811E )
+#define TPU1_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x00088128 )
+#define TPU1_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x0008812A )
+#define TPU2_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x00088138 )
+#define TPU2_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x0008813A )
+#define TPU3_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x00088148 )
+#define TPU3_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x0008814A )
+#define TPU3_TGRC_ADDR			( ( volatile uint16_t __evenaccess * )0x0008814C )
+#define TPU3_TGRD_ADDR			( ( volatile uint16_t __evenaccess * )0x0008814E )
+#define TPU4_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x00088158 )
+#define TPU4_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x0008815A )
+#define TPU5_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x00088168 )
+#define TPU5_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x0008816A )
+#define TPU6_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x00088188 )
+#define TPU6_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x0008818A )
+#define TPU6_TGRC_ADDR			( ( volatile uint16_t __evenaccess * )0x0008818C )
+#define TPU6_TGRD_ADDR			( ( volatile uint16_t __evenaccess * )0x0008818E )
+#define TPU7_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x00088198 )
+#define TPU7_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x0008819A )
+#define TPU8_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x000881A8 )
+#define TPU8_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x000881AA )
+#define TPU9_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x000881B8 )
+#define TPU9_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x000881BA )
+#define TPU9_TGRC_ADDR			( ( volatile uint16_t __evenaccess * )0x000881BC )
+#define TPU9_TGRD_ADDR			( ( volatile uint16_t __evenaccess * )0x000881BE )
+#define TPU10_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x000881C8 )
+#define TPU10_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x000881CA )
+#define TPU11_TGRA_ADDR			( ( volatile uint16_t __evenaccess * )0x000881D8 )
+#define TPU11_TGRB_ADDR			( ( volatile uint16_t __evenaccess * )0x000881DA )
+
+#define TPUA_TSTR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088100 )
+#define TPUB_TSTR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088170 )
+#define TPU_TSTR_CST0_BIT		( 0x01U << 0U )
+#define TPU_TSTR_CST1_BIT		( 0x01U << 1U )
+#define TPU_TSTR_CST2_BIT		( 0x01U << 2U )
+#define TPU_TSTR_CST3_BIT		( 0x01U << 3U )
+#define TPU_TSTR_CST4_BIT		( 0x01U << 4U )
+#define TPU_TSTR_CST5_BIT		( 0x01U << 5U )
+
+#define TPUA_TSYR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088101 )
+#define TPUB_TSYR_ADDR			( ( volatile uint8_t __evenaccess * )0x00088171 )
+#define TPU_TSYR_SYNC0_BIT		( 0x01U << 0U )
+#define TPU_TSYR_SYNC1_BIT		( 0x01U << 1U )
+#define TPU_TSYR_SYNC2_BIT		( 0x01U << 2U )
+#define TPU_TSYR_SYNC3_BIT		( 0x01U << 3U )
+#define TPU_TSYR_SYNC4_BIT		( 0x01U << 4U )
+#define TPU_TSYR_SYNC5_BIT		( 0x01U << 5U )
+
+#define TPU0_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x00088114 )
+#define TPU1_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x00088124 )
+#define TPU2_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x00088134 )
+#define TPU3_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x00088144 )
+#define TPU4_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x00088154 )
+#define TPU5_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x00088164 )
+#define TPU6_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x00088184 )
+#define TPU7_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x00088194 )
+#define TPU8_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x000881A4 )
+#define TPU9_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x000881B4 )
+#define TPU10_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x000881C4 )
+#define TPU11_TIER_ADDR			( ( volatile uint8_t __evenaccess *)0x000881D4 )
+
+#define TPU0_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x00088116 )
+#define TPU1_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x00088126 )
+#define TPU2_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x00088136 )
+#define TPU3_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x00088146 )
+#define TPU4_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x00088156 )
+#define TPU5_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x00088166 )
+#define TPU6_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x00088186 )
+#define TPU7_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x00088196 )
+#define TPU8_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x000881A6 )
+#define TPU9_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x000881B6 )
+#define TPU10_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x000881C6 )
+#define TPU11_TCNT_ADDR			( ( volatile uint16_t __evenaccess *)0x000881D6 )
+
+/*
+ * RSPI
+ */
+#define RSPI0_SPCR_ADDR		( ( volatile uint8_t __evenaccess * )0x00088380 )
+#define RSPI1_SPCR_ADDR		( ( volatile uint8_t __evenaccess * )0x000883A0 )
+#define RSPI2_SPCR_ADDR		( ( volatile uint8_t __evenaccess * )0x000883C0 )
+#define RSPI_SPCR_SPMS_BIT	( 0x01U << 0U )
+#define RSPI_SPCR_TXMD_BIT	( 0x01U << 1U )
+#define RSPI_SPCR_MODFEN_BIT	( 0x01U << 2U )
+#define RSPI_SPCR_MSTR_BIT	( 0x01U << 3U )
+#define RSPI_SPCR_SPEIE_BIT	( 0x01U << 4U )
+#define RSPI_SPCR_SPTIE_BIT	( 0x01U << 5U )
+#define RSPI_SPCR_SPE_BIT	( 0x01U << 6U )
+#define RSPI_SPCR_SPRIE_BIT	( 0x01U << 7U )
+
+#define RSPI0_SSLP_ADDR		( ( volatile uint8_t __evenaccess * )0x00088381 )
+#define RSPI1_SSLP_ADDR		( ( volatile uint8_t __evenaccess * )0x000883A1 )
+#define RSPI2_SSLP_ADDR		( ( volatile uint8_t __evenaccess * )0x000883C1 )
+
+#define RSPI0_SPPCR_ADDR	( ( volatile uint8_t __evenaccess * )0x00088382 )
+#define RSPI1_SPPCR_ADDR	( ( volatile uint8_t __evenaccess * )0x000883A2 )
+#define RSPI2_SPPCR_ADDR	( ( volatile uint8_t __evenaccess * )0x000883C2 )
+
+#define RSPI0_SPSR_ADDR		( ( volatile uint8_t __evenaccess * )0x00088383 )
+#define RSPI1_SPSR_ADDR		( ( volatile uint8_t __evenaccess * )0x000883A3 )
+#define RSPI2_SPSR_ADDR		( ( volatile uint8_t __evenaccess * )0x000883C3 )
+
+#define RSPI0_SPDR_ADDR		( ( volatile uint32_t __evenaccess * )0x00088384 )
+#define RSPI1_SPDR_ADDR		( ( volatile uint32_t __evenaccess * )0x000883A4 )
+#define RSPI2_SPDR_ADDR		( ( volatile uint32_t __evenaccess * )0x000883C4 )
+
+#define RSPI0_SPSCR_ADDR	( ( volatile uint8_t __evenaccess * )0x00088388 )
+#define RSPI1_SPSCR_ADDR	( ( volatile uint8_t __evenaccess * )0x000883A8 )
+#define RSPI2_SPSCR_ADDR	( ( volatile uint8_t __evenaccess * )0x000883C8 )
+
+#define RSPI0_SPSSR_ADDR	( ( volatile uint8_t __evenaccess * )0x00088389 )
+#define RSPI1_SPSSR_ADDR	( ( volatile uint8_t __evenaccess * )0x000883A9 )
+#define RSPI2_SPSSR_ADDR	( ( volatile uint8_t __evenaccess * )0x000883C9 )
+
+#define RSPI0_SPBR_ADDR		( ( volatile uint8_t __evenaccess * )0x0008838A )
+#define RSPI1_SPBR_ADDR		( ( volatile uint8_t __evenaccess * )0x000883AA )
+#define RSPI2_SPBR_ADDR		( ( volatile uint8_t __evenaccess * )0x000883CA )
+
+#define RSPI0_SPDCR_ADDR	( ( volatile uint8_t __evenaccess * )0x0008838B )
+#define RSPI1_SPDCR_ADDR	( ( volatile uint8_t __evenaccess * )0x000883AB )
+#define RSPI2_SPDCR_ADDR	( ( volatile uint8_t __evenaccess * )0x000883CB )
+
+#define RSPI0_SPCKD_ADDR	( ( volatile uint8_t __evenaccess * )0x0008838C )
+#define RSPI1_SPCKD_ADDR	( ( volatile uint8_t __evenaccess * )0x000883AC )
+#define RSPI2_SPCKD_ADDR	( ( volatile uint8_t __evenaccess * )0x000883CC )
+
+#define RSPI0_SSLND_ADDR	( ( volatile uint8_t __evenaccess * )0x0008838D )
+#define RSPI1_SSLND_ADDR	( ( volatile uint8_t __evenaccess * )0x000883AD )
+#define RSPI2_SSLND_ADDR	( ( volatile uint8_t __evenaccess * )0x000883CD )
+
+#define RSPI0_SPND_ADDR		( ( volatile uint8_t __evenaccess * )0x0008838E )
+#define RSPI1_SPND_ADDR		( ( volatile uint8_t __evenaccess * )0x000883AE )
+#define RSPI2_SPND_ADDR		( ( volatile uint8_t __evenaccess * )0x000883CE )
+
+#define RSPI0_SPCR2_ADDR	( ( volatile uint8_t __evenaccess * )0x0008838F )
+#define RSPI1_SPCR2_ADDR	( ( volatile uint8_t __evenaccess * )0x000883AF )
+#define RSPI2_SPCR2_ADDR	( ( volatile uint8_t __evenaccess * )0x000883CF )
+
+#define RSPI0_SPCMD0_ADDR	( ( volatile uint16_t __evenaccess * )0x00088390 )
+#define RSPI0_SPCMD1_ADDR	( ( volatile uint16_t __evenaccess * )0x00088392 )
+#define RSPI0_SPCMD2_ADDR	( ( volatile uint16_t __evenaccess * )0x00088394 )
+#define RSPI0_SPCMD3_ADDR	( ( volatile uint16_t __evenaccess * )0x00088396 )
+#define RSPI0_SPCMD4_ADDR	( ( volatile uint16_t __evenaccess * )0x00088398 )
+#define RSPI0_SPCMD5_ADDR	( ( volatile uint16_t __evenaccess * )0x0008839A )
+#define RSPI0_SPCMD6_ADDR	( ( volatile uint16_t __evenaccess * )0x0008839C )
+#define RSPI0_SPCMD7_ADDR	( ( volatile uint16_t __evenaccess * )0x0008839E )
+#define RSPI1_SPCMD0_ADDR	( ( volatile uint16_t __evenaccess * )0x000883B0 )
+#define RSPI1_SPCMD1_ADDR	( ( volatile uint16_t __evenaccess * )0x000883B2 )
+#define RSPI1_SPCMD2_ADDR	( ( volatile uint16_t __evenaccess * )0x000883B4 )
+#define RSPI1_SPCMD3_ADDR	( ( volatile uint16_t __evenaccess * )0x000883B6 )
+#define RSPI1_SPCMD4_ADDR	( ( volatile uint16_t __evenaccess * )0x000883B8 )
+#define RSPI1_SPCMD5_ADDR	( ( volatile uint16_t __evenaccess * )0x000883BA )
+#define RSPI1_SPCMD6_ADDR	( ( volatile uint16_t __evenaccess * )0x000883BC )
+#define RSPI1_SPCMD7_ADDR	( ( volatile uint16_t __evenaccess * )0x000883BE )
+#define RSPI2_SPCMD0_ADDR	( ( volatile uint16_t __evenaccess * )0x000883D0 )
+#define RSPI2_SPCMD1_ADDR	( ( volatile uint16_t __evenaccess * )0x000883D2 )
+#define RSPI2_SPCMD2_ADDR	( ( volatile uint16_t __evenaccess * )0x000883D4 )
+#define RSPI2_SPCMD3_ADDR	( ( volatile uint16_t __evenaccess * )0x000883D6 )
+#define RSPI2_SPCMD4_ADDR	( ( volatile uint16_t __evenaccess * )0x000883D8 )
+#define RSPI2_SPCMD5_ADDR	( ( volatile uint16_t __evenaccess * )0x000883DA )
+#define RSPI2_SPCMD6_ADDR	( ( volatile uint16_t __evenaccess * )0x000883DC )
+#define RSPI2_SPCMD7_ADDR	( ( volatile uint16_t __evenaccess * )0x000883DE )
+#define RSPI_SPCMD_SPB_OFFSET	(8)
+#define RSPI_SPCMD_SPB_MASK (0xF << RSPI_SPCMD_SPB_OFFSET)
+
+/*
+ *  UART関連の定義
+ *
+ *  pdicのrx600/rx630_uart.cで使用する．
+ */
+/*
+ *  シリアルI/Oの個数
+ */
+#define TNUM_SIOP	( 2 )
+
+#endif	/* TOPPERS_RX630_H */
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/rx630_kernel_impl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/rx630_kernel_impl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/rx630_kernel_impl.c	(revision 398)
@@ -0,0 +1,595 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2010 by Witz Corporation, JAPAN
+ *  Copyright (C) 2013 by Mitsuhiro Matsuura
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		プロセッサ依存モジュール（RX630用）
+ */
+
+#include "kernel_impl.h"
+
+
+/*
+ *  割込み要因プライオリティレジスタアドレステーブル
+ */
+volatile uint8_t __evenaccess * const ipr_reg_addr[ INHNO_MAX ] = {
+	NULL,							/* No.0  予約 */
+	NULL,							/* No.1  予約 */
+	NULL,							/* No.2  予約 */
+	NULL,							/* No.3  予約 */
+	NULL,							/* No.4  予約 */
+	NULL,							/* No.5  予約 */
+	NULL,							/* No.6  予約 */
+	NULL,							/* No.7  予約 */
+	NULL,							/* No.8  予約 */
+	NULL,							/* No.9  予約 */
+	NULL,							/* No.10  予約 */
+	NULL,							/* No.11  予約 */
+	NULL,							/* No.12  予約 */
+	NULL,							/* No.13  予約 */
+	NULL,							/* No.14  予約 */
+	NULL,							/* No.15  予約 */
+	ICU_IPR000_ADDR,				/* No.16  バスエラー BUSERR */
+	NULL,							/* No.17  予約 */
+	NULL,							/* No.18  予約 */
+	NULL,							/* No.19  予約 */
+	NULL,							/* No.20  予約 */
+	ICU_IPR001_ADDR,				/* No.21  FCU FIFERR */
+	NULL,							/* No.22  予約 */
+	ICU_IPR002_ADDR,				/* No.23  FCU FRDYI */
+	NULL,							/* No.24  予約 */
+	NULL,							/* No.25  予約 */
+	NULL,							/* No.26  予約 */
+	ICU_IPR003_ADDR,				/* No.27  SWINT */
+	ICU_IPR004_ADDR,				/* No.28  CMTユニット0 CMT0 */
+	ICU_IPR005_ADDR,				/* No.29  CMTユニット0 CMT1 */
+	ICU_IPR006_ADDR,				/* No.30  CMTユニット1 CMT2 */
+	ICU_IPR007_ADDR,				/* No.31  CMTユニット1 CMT3 */
+	ICU_IPR032_ADDR,				/* No.32  ETHER */
+	ICU_IPR033_ADDR,				/* No.33  USB0 D0FIFO0 */
+	ICU_IPR034_ADDR,				/* No.34  USB0 D1FIFO0 */
+	ICU_IPR035_ADDR,				/* No.35  USB0 USBI0 */
+	ICU_IPR036_ADDR,				/* No.36  USB1 D0FIFO1 */
+	ICU_IPR037_ADDR,				/* No.37  USB1 D1FIFO1 */
+	ICU_IPR038_ADDR,				/* No.38  USB1 USBI1 */
+	ICU_IPR039_ADDR,				/* No.39  SPRI0 */
+	ICU_IPR039_ADDR,				/* No.40  SPTI0 */
+	ICU_IPR039_ADDR,				/* No.41  SPII0 */
+	ICU_IPR042_ADDR,				/* No.42  SPRI1 */
+	ICU_IPR042_ADDR,				/* No.43  SPTI1 */
+	ICU_IPR042_ADDR,				/* No.44  SPII1 */
+	ICU_IPR045_ADDR,				/* No.45  SPRI2 */
+	ICU_IPR045_ADDR,				/* No.46  SPTI2 */
+	ICU_IPR045_ADDR,				/* No.47  SPII2 */
+	ICU_IPR048_ADDR, 				/* No.48  CAN RXF0 */
+	ICU_IPR048_ADDR, 				/* No.49  CAN TXF0 */
+	ICU_IPR048_ADDR, 				/* No.50  CAN RXM0 */
+	ICU_IPR048_ADDR, 				/* No.51  CAN TXM0 */
+	ICU_IPR052_ADDR, 				/* No.52  CAN RXF1 */
+	ICU_IPR052_ADDR, 				/* No.53  CAN TXF1 */
+	ICU_IPR052_ADDR, 				/* No.54  CAN RXM1 */
+	ICU_IPR052_ADDR, 				/* No.55  CAN TXM1 */
+	ICU_IPR056_ADDR, 				/* No.56  CAN RXF2 */
+	ICU_IPR056_ADDR, 				/* No.57  CAN TXF2 */
+	ICU_IPR056_ADDR, 				/* No.58  CAN RXM2 */
+	ICU_IPR056_ADDR, 				/* No.59  CAN TXM2 */
+	NULL,							/* No.60  予約 */
+	NULL,							/* No.61  予約 */
+	ICU_IPR062_ADDR,			 	/* No.62  RTC PRD */
+	NULL,							/* No.63  予約 */
+	ICU_IPR064_ADDR,				/* No.64  外部端子 IRQ0 */
+	ICU_IPR065_ADDR,				/* No.65  外部端子 IRQ1 */
+	ICU_IPR066_ADDR,				/* No.66  外部端子 IRQ2 */
+	ICU_IPR067_ADDR,				/* No.67  外部端子 IRQ3 */
+	ICU_IPR068_ADDR,				/* No.68  外部端子 IRQ4 */
+	ICU_IPR069_ADDR,				/* No.69  外部端子 IRQ5 */
+	ICU_IPR070_ADDR,				/* No.70  外部端子 IRQ6 */
+	ICU_IPR071_ADDR,				/* No.71  外部端子 IRQ7 */
+	ICU_IPR072_ADDR,				/* No.72  外部端子 IRQ8 */
+	ICU_IPR073_ADDR,				/* No.73  外部端子 IRQ9 */
+	ICU_IPR074_ADDR,				/* No.74  外部端子 IRQ10 */
+	ICU_IPR075_ADDR,				/* No.75  外部端子 IRQ11 */
+	ICU_IPR076_ADDR,				/* No.76  外部端子 IRQ12 */
+	ICU_IPR077_ADDR,				/* No.77  外部端子 IRQ13 */
+	ICU_IPR078_ADDR,				/* No.78  外部端子 IRQ14 */
+	ICU_IPR079_ADDR,				/* No.79  外部端子 IRQ15 */
+	NULL,							/* No.80  予約 */
+	NULL,							/* No.81  予約 */
+	NULL,							/* No.82  予約 */
+	NULL,							/* No.83  予約 */
+	NULL,							/* No.84  予約 */
+	NULL,							/* No.85  予約 */
+	NULL,							/* No.86  予約 */
+	NULL,							/* No.87  予約 */
+	NULL,							/* No.88  予約 */
+	NULL,							/* No.89  予約 */
+	ICU_IPR090_ADDR, 				/* No.90  USBR0 */
+	ICU_IPR091_ADDR, 				/* No.91  USBR1 */
+	ICU_IPR092_ADDR,				/* No.92  RTC ALM */
+	ICU_IPR093_ADDR,				/* No.93  RTC PRD */
+	NULL,							/* No.94  予約 */
+	NULL,							/* No.95  予約 */
+	NULL,							/* No.96  予約 */
+	NULL,							/* No.97  予約 */
+	ICU_IPR098_ADDR,				/* No.98  AD ADI0 */
+	NULL,							/* No.99  予約 */
+	NULL,							/* No.100  予約 */
+	NULL,							/* No.101  予約 */
+	ICU_IPR102_ADDR,				/* No.102 S12AD S12ADIO */
+	NULL,							/* No.103  予約 */
+	NULL,							/* No.104  予約 */
+	NULL,							/* No.105  予約 */
+	ICU_IPR106_ADDR,				/* No.106 ICU GROUP0 */
+	ICU_IPR107_ADDR,				/* No.107 ICU GROUP1 */
+	ICU_IPR108_ADDR,				/* No.108 ICU GROUP2 */
+	ICU_IPR109_ADDR,				/* No.109 ICU GROUP3 */
+	ICU_IPR110_ADDR,				/* No.110 ICU GROUP4 */
+	ICU_IPR111_ADDR,				/* No.111 ICU GROUP5 */
+	ICU_IPR112_ADDR,				/* No.112 ICU GROUP6 */
+	NULL,							/* No.113  予約 */
+	ICU_IPR114_ADDR,				/* No.114 ICU GROUP12 */
+	NULL,							/* No.115  予約 */
+	NULL,							/* No.116  予約 */
+	NULL,							/* No.117  予約 */
+	NULL,							/* No.118  予約 */
+	NULL,							/* No.119  予約 */
+	NULL,							/* No.120  予約 */
+	NULL,							/* No.121  予約 */
+	ICU_IPR122_ADDR,				/* No.122 SCI12 SCIX0 */
+	ICU_IPR123_ADDR,				/* No.123 SCI12 SCIX1 */
+	ICU_IPR124_ADDR,				/* No.124 SCI12 SCIX2 */
+	ICU_IPR125_ADDR,				/* No.125 SCI12 SCIX3 */
+	ICU_IPR126_ADDR,				/* No.126 TPU0 TGI0A */
+	ICU_IPR126_ADDR,				/* No.127 TPU0 TGI0B */
+	ICU_IPR126_ADDR,				/* No.128 TPU0 TGI0C */
+	ICU_IPR126_ADDR,				/* No.129 TPU0 TGI0D */
+	ICU_IPR130_ADDR,				/* No.130 TPU1 TGI1A */
+	ICU_IPR130_ADDR,				/* No.131 TPU1 TGI1B */
+	ICU_IPR132_ADDR,				/* No.132 TPU2 TGI2A */
+	ICU_IPR132_ADDR,				/* No.133 TPU2 TGI2B */
+	ICU_IPR134_ADDR,				/* No.134 TPU3 TGI3A */
+	ICU_IPR134_ADDR,				/* No.135 TPU3 TGI3B */
+	ICU_IPR134_ADDR,				/* No.136 TPU3 TGI3C */
+	ICU_IPR134_ADDR,				/* No.137 TPU3 TGI3D */
+	ICU_IPR138_ADDR,				/* No.138 TPU4 TGI4A */
+	ICU_IPR138_ADDR,				/* No.139 TPU4 TGI4B */
+	ICU_IPR140_ADDR,				/* No.140 TPU5 TGI5A */
+	ICU_IPR140_ADDR,				/* No.141 TPU5 TGI5B */
+	ICU_IPR142_ADDR,				/* No.142 TPU6 TGI6A */
+	ICU_IPR142_ADDR,				/* No.143 TPU6 TGI6B */
+	ICU_IPR142_ADDR,				/* No.144 TPU6 TGI6C */
+	ICU_IPR142_ADDR,				/* No.145 TPU6 TGI6D */
+	ICU_IPR146_ADDR,				/* No.146 TGIE0 */
+	ICU_IPR146_ADDR,				/* No.147 TGIF0 */
+	ICU_IPR148_ADDR,				/* No.148 TPU7 TGI7A */
+	ICU_IPR148_ADDR,				/* No.149 TPU7 TGI7B */
+	ICU_IPR150_ADDR,				/* No.150 TPU8 TGI8A */
+	ICU_IPR150_ADDR,				/* No.151 TPU8 TGI8B */
+	ICU_IPR152_ADDR,				/* No.152 TPU9 TGI9A */
+	ICU_IPR152_ADDR,				/* No.153 TPU9 TGI9B */
+	ICU_IPR152_ADDR,				/* No.154 TPU9 TGI9C */
+	ICU_IPR152_ADDR,				/* No.155 TPU9 TGI9D */
+	ICU_IPR156_ADDR,				/* No.156 TPU10 TGI10A */
+	ICU_IPR156_ADDR,				/* No.157 TPU10 TGI10B */
+	ICU_IPR156_ADDR,				/* No.158 TGIC4 */
+	ICU_IPR156_ADDR,				/* No.159 TGID4 */
+	ICU_IPR160_ADDR,				/* No.160 TGIV4 */
+	ICU_IPR161_ADDR,				/* No.161 TGIU5 */
+	ICU_IPR162_ADDR,				/* No.162 TGIV5 */
+	ICU_IPR163_ADDR,				/* No.163 TGIW5 */
+	ICU_IPR164_ADDR,				/* No.164 TCI11A */
+	ICU_IPR165_ADDR,				/* No.165 TCI11B */
+	ICU_IPR167_ADDR,				/* No.166 POE OEI1 */
+	ICU_IPR167_ADDR,				/* No.167 POE OEI2 */
+	NULL,							/* No.168  予約 */
+	NULL,							/* No.169  予約 */
+	ICU_IPR170_ADDR,				/* No.170 TMR0 CMIA0 */
+	ICU_IPR170_ADDR,				/* No.171 TMR0 CMIB0 */
+	ICU_IPR170_ADDR,				/* No.172 TMR0 OVI0 */
+	ICU_IPR173_ADDR,				/* No.173 TMR1 CMIA1 */
+	ICU_IPR173_ADDR,				/* No.174 TMR1 CMIB1 */
+	ICU_IPR173_ADDR,				/* No.175 TMR1 OVI1 */
+	ICU_IPR176_ADDR,				/* No.176 TMR2 CMIA2 */
+	ICU_IPR176_ADDR,				/* No.177 TMR2 CMIB2 */
+	ICU_IPR176_ADDR,				/* No.178 TMR2 OVI2 */
+	ICU_IPR179_ADDR,				/* No.179 TMR3 CMIA3 */
+	ICU_IPR179_ADDR,				/* No.180 TMR3 CMIB3 */
+	ICU_IPR179_ADDR,				/* No.181 TMR3 OVI3 */
+	ICU_IPR182_ADDR,				/* No.182 RIIC0 EEI0 */
+	ICU_IPR183_ADDR,				/* No.183 RIIC0 RXI0 */
+	ICU_IPR184_ADDR,				/* No.184 RIIC0 TXI0 */
+	ICU_IPR185_ADDR,				/* No.185 RIIC0 TEI0 */
+	ICU_IPR186_ADDR,				/* No.186 RIIC0 EEI1 */
+	ICU_IPR187_ADDR,				/* No.187 RIIC0 RXI1 */
+	ICU_IPR188_ADDR,				/* No.188 RIIC0 TXI1 */
+	ICU_IPR189_ADDR,				/* No.189 RIIC0 TEI1 */
+	ICU_IPR190_ADDR,				/* No.190 RIIC0 EEI2 */
+	ICU_IPR191_ADDR,				/* No.191 RIIC0 RXI2 */
+	ICU_IPR192_ADDR,				/* No.192 RIIC0 TXI2 */
+	ICU_IPR193_ADDR,				/* No.193 RIIC0 TEI2 */
+	ICU_IPR194_ADDR,				/* No.194 RIIC0 EEI3 */
+	ICU_IPR195_ADDR,				/* No.195 RIIC0 RXI3 */
+	ICU_IPR196_ADDR,				/* No.196 RIIC0 TXI3 */
+	ICU_IPR197_ADDR,				/* No.197 RIIC0 TEI3 */
+	ICU_IPR198_ADDR,				/* No.198 DMAC DMTEND0 */
+	ICU_IPR199_ADDR,				/* No.199 DMAC DMTEND1 */
+	ICU_IPR200_ADDR,				/* No.200 DMAC DMTEND2 */
+	ICU_IPR201_ADDR,				/* No.201 DMAC DMTEND3 */
+	ICU_IPR202_ADDR,				/* No.202 EXDMAC EXDMACI0 */
+	ICU_IPR203_ADDR,				/* No.203 EXDMAC EXDMACI1 */
+	NULL,							/* No.204  予約 */
+	NULL,							/* No.205  予約 */
+	NULL,							/* No.206  予約 */
+	NULL,							/* No.207  予約 */
+	NULL,							/* No.208  予約 */
+	NULL,							/* No.209  予約 */
+	NULL,							/* No.210  予約 */
+	NULL,							/* No.211  予約 */
+	NULL,							/* No.212  予約 */
+	NULL,							/* No.213  予約 */
+	ICU_IPR214_ADDR,				/* No.214 SCI0 RXI0 */
+	ICU_IPR214_ADDR,				/* No.215 SCI0 TXI0 */
+	ICU_IPR214_ADDR,				/* No.216 SCI0 TEI0 */
+	ICU_IPR217_ADDR,				/* No.217 SCI1 RXI1 */
+	ICU_IPR217_ADDR,				/* No.218 SCI1 TXI1 */
+	ICU_IPR217_ADDR,				/* No.219 SCI1 TEI1 */
+	ICU_IPR220_ADDR,				/* No.220 SCI2 RXI2 */
+	ICU_IPR220_ADDR,				/* No.221 SCI2 TXI2 */
+	ICU_IPR220_ADDR,				/* No.222 SCI2 TEI2 */
+	ICU_IPR223_ADDR,				/* No.223 SCI3 RXI3 */
+	ICU_IPR223_ADDR,				/* No.224 SCI3 TXI3 */
+	ICU_IPR223_ADDR,				/* No.225 SCI3 TEI3 */
+	ICU_IPR226_ADDR,				/* No.226 SCI4 RXI4 */
+	ICU_IPR226_ADDR,				/* No.227 SCI4 TXI4 */
+	ICU_IPR226_ADDR,				/* No.228 SCI4 TEI4 */
+	ICU_IPR229_ADDR,				/* No.229 SCI5 RXI5 */
+	ICU_IPR229_ADDR,				/* No.230 SCI5 TXI5 */
+	ICU_IPR229_ADDR,				/* No.231 SCI5 TEI5 */
+	ICU_IPR232_ADDR,				/* No.232 SCI6 RXI6 */
+	ICU_IPR232_ADDR,				/* No.233 SCI6 TXI6 */
+	ICU_IPR232_ADDR,				/* No.234 SCI6 TEI6 */
+	ICU_IPR235_ADDR,				/* No.235 SCI7 RXI7 */
+	ICU_IPR235_ADDR,				/* No.236 SCI7 TXI7 */
+	ICU_IPR235_ADDR,				/* No.237 SCI7 TEI7 */
+	ICU_IPR238_ADDR,				/* No.238 SCI8 RXI8 */
+	ICU_IPR238_ADDR,				/* No.239 SCI8 TXI8 */
+	ICU_IPR238_ADDR,				/* No.240 SCI8 TEI8 */
+	ICU_IPR241_ADDR,				/* No.241 SCI9 RXI9 */
+	ICU_IPR241_ADDR,				/* No.242 SCI9 TXI9 */
+	ICU_IPR241_ADDR,				/* No.243 SCI9 TEI9 */
+	ICU_IPR244_ADDR,				/* No.244 SCI10 RXI10 */
+	ICU_IPR244_ADDR,				/* No.245 SCI10 TXI10 */
+	ICU_IPR244_ADDR,				/* No.246 SCI10 TEI10 */
+	ICU_IPR247_ADDR,				/* No.247 SCI11 RXI11 */
+	ICU_IPR247_ADDR,				/* No.248 SCI11 TXI11 */
+	ICU_IPR247_ADDR,				/* No.249 SCI11 TEI11 */
+	ICU_IPR250_ADDR,				/* No.250 SCI12 RXI12 */
+	ICU_IPR250_ADDR,				/* No.251 SCI12 TXI12 */
+	ICU_IPR250_ADDR,				/* No.252 SCI12 TEI12 */
+	ICU_IPR253_ADDR,				/* No.253 IEB IEBINT */
+	NULL,							/* No.254  予約 */
+	NULL,							/* No.255  予約 */
+};
+
+
+/*
+ *  割込み要求許可レジスタアドレステーブル
+ */
+const IER_INFO ier_reg_addr[ INHNO_MAX ] = {
+	{ NULL, INVALID_OFFSET },			/* No.0   予約 */
+	{ NULL, INVALID_OFFSET },			/* No.1   予約 */
+	{ NULL, INVALID_OFFSET },			/* No.2   予約 */
+	{ NULL, INVALID_OFFSET },			/* No.3   予約 */
+	{ NULL, INVALID_OFFSET },			/* No.4   予約 */
+	{ NULL, INVALID_OFFSET },			/* No.5   予約 */
+	{ NULL, INVALID_OFFSET },			/* No.6   予約 */
+	{ NULL, INVALID_OFFSET },			/* No.7   予約 */
+	{ NULL, INVALID_OFFSET },			/* No.8   予約 */
+	{ NULL, INVALID_OFFSET },			/* No.9   予約 */
+	{ NULL, INVALID_OFFSET },			/* No.10  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.11  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.12  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.13  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.14  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.15  予約 */
+	{ ICU_IER02_ADDR, ICU_IEN0_BIT },	/* No.16  バスエラー BUSERR */
+	{ NULL, INVALID_OFFSET },			/* No.17  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.18  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.19  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.20  予約 */
+	{ ICU_IER02_ADDR, ICU_IEN5_BIT },	/* No.21  FCU FIFERR */
+	{ NULL, INVALID_OFFSET },			/* No.22  予約 */
+	{ ICU_IER02_ADDR, ICU_IEN7_BIT },	/* No.23  FCU FRDYI */
+	{ NULL, INVALID_OFFSET },			/* No.24  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.25  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.26  予約 */
+	{ ICU_IER03_ADDR, ICU_IEN3_BIT },	/* No.27  SWINT */
+	{ ICU_IER03_ADDR, ICU_IEN4_BIT },	/* No.28  CMTユニット0 CMT0 */
+	{ ICU_IER03_ADDR, ICU_IEN5_BIT },	/* No.29  CMTユニット0 CMT1 */
+	{ ICU_IER03_ADDR, ICU_IEN6_BIT },	/* No.30  CMTユニット1 CMT2 */
+	{ ICU_IER03_ADDR, ICU_IEN7_BIT },	/* No.31  CMTユニット1 CMT3 */
+	{ ICU_IER04_ADDR, ICU_IEN0_BIT },	/* No.32  ETHER */
+	{ ICU_IER04_ADDR, ICU_IEN1_BIT },	/* No.33  USB0 D0FIFO0 */
+	{ ICU_IER04_ADDR, ICU_IEN2_BIT },	/* No.34  USB0 D1FIFO0 */
+	{ ICU_IER04_ADDR, ICU_IEN3_BIT },	/* No.35  USB0 USBI0 */
+	{ ICU_IER04_ADDR, ICU_IEN4_BIT },	/* No.36  USB1 D0FIFO1 */
+	{ ICU_IER04_ADDR, ICU_IEN5_BIT },	/* No.37  USB1 D1FIFO1 */
+	{ ICU_IER04_ADDR, ICU_IEN6_BIT },	/* No.38  USB1 USBI1 */
+	{ ICU_IER04_ADDR, ICU_IEN7_BIT },	/* No.39  RSPI0 SPRI0 */
+	{ ICU_IER05_ADDR, ICU_IEN0_BIT },	/* No.40  RSPI0 SPTI0 */
+	{ ICU_IER05_ADDR, ICU_IEN1_BIT },	/* No.41  RSPI0 SPII0 */
+	{ ICU_IER05_ADDR, ICU_IEN2_BIT },	/* No.42  RSPI1 SPRI1 */
+	{ ICU_IER05_ADDR, ICU_IEN3_BIT },	/* No.43  RSPI1 SPTI1 */
+	{ ICU_IER05_ADDR, ICU_IEN4_BIT },	/* No.44  RSPI1 SPII1 */
+	{ ICU_IER05_ADDR, ICU_IEN5_BIT },	/* No.45  RSPI2 SPRI2 */
+	{ ICU_IER05_ADDR, ICU_IEN6_BIT },	/* No.46  RSPI2 SPTI2 */
+	{ ICU_IER05_ADDR, ICU_IEN7_BIT },	/* No.47  RSPI2 SPII2 */
+	{ ICU_IER06_ADDR, ICU_IEN0_BIT },	/* No.48  CAN0 RXF0 */
+	{ ICU_IER06_ADDR, ICU_IEN1_BIT },	/* No.49  CAN0 TXF0 */
+	{ ICU_IER06_ADDR, ICU_IEN2_BIT },	/* No.50  CAN0 RXM0 */
+	{ ICU_IER06_ADDR, ICU_IEN3_BIT },	/* No.51  CAN0 TXM0 */
+	{ ICU_IER06_ADDR, ICU_IEN4_BIT },	/* No.52  CAN1 RXF1 */
+	{ ICU_IER06_ADDR, ICU_IEN5_BIT },	/* No.53  CAN1 TXF1 */
+	{ ICU_IER06_ADDR, ICU_IEN6_BIT },	/* No.54  CAN1 RXM1 */
+	{ ICU_IER06_ADDR, ICU_IEN7_BIT },	/* No.55  CAN1 TXM1 */
+	{ ICU_IER07_ADDR, ICU_IEN0_BIT },	/* No.56  CAN2 RXF2 */
+	{ ICU_IER07_ADDR, ICU_IEN1_BIT },	/* No.57  CAN2 TXF2 */
+	{ ICU_IER07_ADDR, ICU_IEN2_BIT },	/* No.58  CAN2 RXM2 */
+	{ ICU_IER07_ADDR, ICU_IEN3_BIT },	/* No.59  CAN2 TXM2 */
+	{ NULL, INVALID_OFFSET },			/* No.60  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.61  予約 */
+	{ ICU_IER07_ADDR, ICU_IEN6_BIT },	/* No.62  RTC PRD */
+	{ NULL, INVALID_OFFSET },			/* No.63  予約 */
+	{ ICU_IER08_ADDR, ICU_IEN0_BIT },	/* No.64  外部端子 IRQ0 */
+	{ ICU_IER08_ADDR, ICU_IEN1_BIT },	/* No.65  外部端子 IRQ1 */
+	{ ICU_IER08_ADDR, ICU_IEN2_BIT },	/* No.66  外部端子 IRQ2 */
+	{ ICU_IER08_ADDR, ICU_IEN3_BIT },	/* No.67  外部端子 IRQ3 */
+	{ ICU_IER08_ADDR, ICU_IEN4_BIT },	/* No.68  外部端子 IRQ4 */
+	{ ICU_IER08_ADDR, ICU_IEN5_BIT },	/* No.69  外部端子 IRQ5 */
+	{ ICU_IER08_ADDR, ICU_IEN6_BIT },	/* No.70  外部端子 IRQ6 */
+	{ ICU_IER08_ADDR, ICU_IEN7_BIT },	/* No.71  外部端子 IRQ7 */
+	{ ICU_IER09_ADDR, ICU_IEN0_BIT },	/* No.72  外部端子 IRQ8 */
+	{ ICU_IER09_ADDR, ICU_IEN1_BIT },	/* No.73  外部端子 IRQ9 */
+	{ ICU_IER09_ADDR, ICU_IEN2_BIT },	/* No.74  外部端子 IRQ10 */
+	{ ICU_IER09_ADDR, ICU_IEN3_BIT },	/* No.75  外部端子 IRQ11 */
+	{ ICU_IER09_ADDR, ICU_IEN4_BIT },	/* No.76  外部端子 IRQ12 */
+	{ ICU_IER09_ADDR, ICU_IEN5_BIT },	/* No.77  外部端子 IRQ13 */
+	{ ICU_IER09_ADDR, ICU_IEN6_BIT },	/* No.78  外部端子 IRQ14 */
+	{ ICU_IER09_ADDR, ICU_IEN7_BIT },	/* No.79  外部端子 IRQ15 */
+	{ NULL, INVALID_OFFSET },			/* No.80  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.81  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.82  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.83  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.84  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.85  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.86  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.87  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.88  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.89  予約 */
+	{ ICU_IER0B_ADDR, ICU_IEN2_BIT },	/* No.90  USBR0 */
+	{ ICU_IER0B_ADDR, ICU_IEN3_BIT },	/* No.91  USBR1 */
+	{ ICU_IER0B_ADDR, ICU_IEN4_BIT },	/* No.92  RTC ALM */
+	{ ICU_IER0B_ADDR, ICU_IEN5_BIT },	/* No.92  RTC PRD */
+	{ NULL, INVALID_OFFSET },			/* No.94  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.95  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.96  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.97  予約 */
+	{ ICU_IER0C_ADDR, ICU_IEN2_BIT },	/* No.98  AD0 ADI0 */
+	{ NULL, INVALID_OFFSET },			/* No.99  予約 */
+	{ NULL, INVALID_OFFSET },			/* No.100 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.101 予約 */
+	{ ICU_IER0C_ADDR, ICU_IEN6_BIT },	/* No.102 S12AD S12ADI00 */
+	{ NULL, INVALID_OFFSET },			/* No.103 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.104 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.105 予約 */
+	{ ICU_IER0D_ADDR, ICU_IEN2_BIT },	/* No.106 ICU GROUP0 */
+	{ ICU_IER0D_ADDR, ICU_IEN3_BIT },	/* No.107 ICU GROUP1 */
+	{ ICU_IER0D_ADDR, ICU_IEN4_BIT },	/* No.108 ICU GROUP2 */
+	{ ICU_IER0D_ADDR, ICU_IEN5_BIT },	/* No.109 ICU GROUP3 */
+	{ ICU_IER0D_ADDR, ICU_IEN6_BIT },	/* No.110 ICU GROUP4 */
+	{ ICU_IER0D_ADDR, ICU_IEN7_BIT },	/* No.111 ICU GROUP5 */
+	{ ICU_IER0E_ADDR, ICU_IEN0_BIT },	/* No.112 ICU GROUP6 */
+	{ NULL, INVALID_OFFSET },			/* No.113 予約 */
+	{ ICU_IER0E_ADDR, ICU_IEN1_BIT },	/* No.114 ICU GROUP12 */
+	{ NULL, INVALID_OFFSET },			/* No.115 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.116 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.117 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.118 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.119 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.120 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.121 予約 */
+	{ ICU_IER0F_ADDR, ICU_IEN2_BIT },	/* No.122 SCI12 SCIX0 */
+	{ ICU_IER0F_ADDR, ICU_IEN3_BIT },	/* No.123 SCI12 SCIX1 */
+	{ ICU_IER0F_ADDR, ICU_IEN4_BIT },	/* No.124 SCI12 SCIX2 */
+	{ ICU_IER0F_ADDR, ICU_IEN5_BIT },	/* No.125 SCI12 SCIX3 */
+	{ ICU_IER0F_ADDR, ICU_IEN6_BIT },	/* No.126 TPU0 TGI0A */
+	{ ICU_IER0F_ADDR, ICU_IEN7_BIT },	/* No.127 TPU0 TGI0B */
+	{ ICU_IER10_ADDR, ICU_IEN0_BIT },	/* No.128 TPU0 TGI0C */
+	{ ICU_IER10_ADDR, ICU_IEN1_BIT },	/* No.129 TPU0 TGI0D */
+	{ ICU_IER10_ADDR, ICU_IEN2_BIT },	/* No.130 TPU1 TGI1A */
+	{ ICU_IER10_ADDR, ICU_IEN3_BIT },	/* No.131 TPU1 TGI1B */
+	{ ICU_IER10_ADDR, ICU_IEN4_BIT },	/* No.132 TPU2 TGI2A */
+	{ ICU_IER10_ADDR, ICU_IEN5_BIT },	/* No.133 TPU2 TGI2B */
+	{ ICU_IER10_ADDR, ICU_IEN6_BIT },	/* No.134 TPU3 TGI3A */
+	{ ICU_IER10_ADDR, ICU_IEN7_BIT },	/* No.135 TPU3 TGI3B */
+	{ ICU_IER11_ADDR, ICU_IEN0_BIT },	/* No.136 TPU3 TGI3C */
+	{ ICU_IER11_ADDR, ICU_IEN1_BIT },	/* No.137 TPU3 TGI3D */
+	{ ICU_IER11_ADDR, ICU_IEN2_BIT },	/* No.138 TPU4 TGI4A */
+	{ ICU_IER11_ADDR, ICU_IEN3_BIT },	/* No.139 TPU4 TGI4B */
+	{ ICU_IER11_ADDR, ICU_IEN4_BIT },	/* No.140 TPU5 TGI5A */
+	{ ICU_IER11_ADDR, ICU_IEN5_BIT },	/* No.141 TPU5 TGI5B */
+	{ ICU_IER11_ADDR, ICU_IEN6_BIT },	/* No.142 TPU6 TGI6A */
+	{ ICU_IER11_ADDR, ICU_IEN7_BIT },	/* No.143 TPU6 TGI6B */
+	{ ICU_IER12_ADDR, ICU_IEN0_BIT },	/* No.144 TPU6 TGI6C */
+	{ ICU_IER12_ADDR, ICU_IEN1_BIT },	/* No.145 TPU6 TGI6D */
+	{ ICU_IER12_ADDR, ICU_IEN2_BIT },	/* No.146 TPU6 TGIE0 */
+	{ ICU_IER12_ADDR, ICU_IEN3_BIT },	/* No.147 TPU6 TGIF0 */
+	{ ICU_IER12_ADDR, ICU_IEN4_BIT },	/* No.148 TPU7 TGI7A */
+	{ ICU_IER12_ADDR, ICU_IEN5_BIT },	/* No.149 TPU7 TGI7B */
+	{ ICU_IER12_ADDR, ICU_IEN6_BIT },	/* No.150 TPU8 TGI8A */
+	{ ICU_IER12_ADDR, ICU_IEN7_BIT },	/* No.151 TPU8 TGI8B */
+	{ ICU_IER13_ADDR, ICU_IEN0_BIT },	/* No.152 TPU9 TGI9A */
+	{ ICU_IER13_ADDR, ICU_IEN1_BIT },	/* No.153 TPU9 TGI9B */
+	{ ICU_IER13_ADDR, ICU_IEN2_BIT },	/* No.154 TPU9 TGI9C */
+	{ ICU_IER13_ADDR, ICU_IEN3_BIT },	/* No.155 TPU9 TGI9D */
+	{ ICU_IER13_ADDR, ICU_IEN4_BIT },	/* No.156 TPU10 TGI10A */
+	{ ICU_IER13_ADDR, ICU_IEN5_BIT },	/* No.157 TPU10 TGI10B */
+	{ ICU_IER13_ADDR, ICU_IEN6_BIT },	/* No.158 TPU10 TGIC4 */
+	{ ICU_IER13_ADDR, ICU_IEN7_BIT },	/* No.159 TPU10 TGID4 */
+	{ ICU_IER14_ADDR, ICU_IEN0_BIT },	/* No.160 TPU10 TGIV4 */
+	{ ICU_IER14_ADDR, ICU_IEN1_BIT },	/* No.161 TPU11 TGIU5 */
+	{ ICU_IER14_ADDR, ICU_IEN2_BIT },	/* No.162 TPU11 TGIV5 */
+	{ ICU_IER14_ADDR, ICU_IEN3_BIT },	/* No.163 TPU11 TGIW5 */
+	{ ICU_IER14_ADDR, ICU_IEN4_BIT },	/* No.164 TPU11 TCI11A */
+	{ ICU_IER14_ADDR, ICU_IEN5_BIT },	/* No.165 TPU11 TCI11B */
+	{ ICU_IER14_ADDR, ICU_IEN6_BIT },	/* No.166 POE OEI1 */
+	{ ICU_IER14_ADDR, ICU_IEN7_BIT },	/* No.167 POE OEI2 */
+	{ NULL, INVALID_OFFSET },			/* No.168 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.169 予約 */
+	{ ICU_IER15_ADDR, ICU_IEN2_BIT },	/* No.170 TMR0 CMIA0 */
+	{ ICU_IER15_ADDR, ICU_IEN3_BIT },	/* No.171 TMR0 CMIB0 */
+	{ ICU_IER15_ADDR, ICU_IEN4_BIT },	/* No.172 TMR0 OVI0 */
+	{ ICU_IER15_ADDR, ICU_IEN5_BIT },	/* No.173 TMR1 CMIA1 */
+	{ ICU_IER15_ADDR, ICU_IEN6_BIT },	/* No.174 TMR1 CMIB1 */
+	{ ICU_IER15_ADDR, ICU_IEN7_BIT },	/* No.175 TMR1 OVI1 */
+	{ ICU_IER16_ADDR, ICU_IEN0_BIT },	/* No.176 TMR2 CMIA2 */
+	{ ICU_IER16_ADDR, ICU_IEN1_BIT },	/* No.177 TMR2 CMIB2 */
+	{ ICU_IER16_ADDR, ICU_IEN2_BIT },	/* No.178 TMR2 OVI2 */
+	{ ICU_IER16_ADDR, ICU_IEN3_BIT },	/* No.179 TMR3 CMIA3 */
+	{ ICU_IER16_ADDR, ICU_IEN4_BIT },	/* No.180 TMR3 CMIB3 */
+	{ ICU_IER16_ADDR, ICU_IEN5_BIT },	/* No.181 TMR3 OVI3 */
+	{ ICU_IER16_ADDR, ICU_IEN6_BIT },	/* No.182 RIIC0 EEI0 */
+	{ ICU_IER16_ADDR, ICU_IEN7_BIT },	/* No.183 RIIC0 RXI0 */
+	{ ICU_IER17_ADDR, ICU_IEN0_BIT },	/* No.184 RIIC0 TXI0 */
+	{ ICU_IER17_ADDR, ICU_IEN1_BIT },	/* No.185 RIIC0 TEI0 */
+	{ ICU_IER17_ADDR, ICU_IEN2_BIT },	/* No.186 RIIC0 EEI1 */
+	{ ICU_IER17_ADDR, ICU_IEN3_BIT },	/* No.187 RIIC0 RXI1 */
+	{ ICU_IER17_ADDR, ICU_IEN4_BIT },	/* No.188 RIIC0 TXI1 */
+	{ ICU_IER17_ADDR, ICU_IEN5_BIT },	/* No.189 RIIC0 TEI1 */
+	{ ICU_IER17_ADDR, ICU_IEN6_BIT },	/* No.190 RIIC0 EEI2 */
+	{ ICU_IER17_ADDR, ICU_IEN7_BIT },	/* No.191 RIIC0 RXI2 */
+	{ ICU_IER18_ADDR, ICU_IEN0_BIT },	/* No.192 RIIC0 TXI2 */
+	{ ICU_IER18_ADDR, ICU_IEN1_BIT },	/* No.193 RIIC0 TEI2 */
+	{ ICU_IER18_ADDR, ICU_IEN2_BIT },	/* No.194 RIIC0 EEI3 */
+	{ ICU_IER18_ADDR, ICU_IEN3_BIT },	/* No.195 RIIC0 RXI3 */
+	{ ICU_IER18_ADDR, ICU_IEN4_BIT },	/* No.196 RIIC0 TXI3 */
+	{ ICU_IER18_ADDR, ICU_IEN5_BIT },	/* No.197 RIIC0 TEI3 */
+	{ ICU_IER18_ADDR, ICU_IEN6_BIT },	/* No.198 DMAC DMAC0I */
+	{ ICU_IER18_ADDR, ICU_IEN7_BIT },	/* No.199 DMAC DMAC1I */
+	{ ICU_IER19_ADDR, ICU_IEN0_BIT },	/* No.200 DMAC DMAC2I */
+	{ ICU_IER19_ADDR, ICU_IEN1_BIT },	/* No.201 DMAC DMAC3I */
+	{ ICU_IER19_ADDR, ICU_IEN2_BIT },	/* No.202 EXDMAC EXDMAC0I */
+	{ ICU_IER19_ADDR, ICU_IEN3_BIT },	/* No.203 EXDMAC EXDMAC1I */
+	{ NULL, INVALID_OFFSET },			/* No.204 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.205 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.206 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.207 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.208 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.209 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.210 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.211 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.212 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.213 予約 */
+	{ ICU_IER1A_ADDR, ICU_IEN6_BIT },	/* No.214 SCI0 RXI0 */
+	{ ICU_IER1A_ADDR, ICU_IEN7_BIT },	/* No.215 SCI0 TXI0 */
+	{ ICU_IER1B_ADDR, ICU_IEN0_BIT },	/* No.216 SCI0 TEI0 */
+	{ ICU_IER1B_ADDR, ICU_IEN1_BIT },	/* No.217 SCI1 RXI1 */
+	{ ICU_IER1B_ADDR, ICU_IEN2_BIT },	/* No.228 SCI1 TXI1 */
+	{ ICU_IER1B_ADDR, ICU_IEN3_BIT },	/* No.229 SCI1 TEI1 */
+	{ ICU_IER1B_ADDR, ICU_IEN4_BIT },	/* No.220 SCI2 RXI2 */
+	{ ICU_IER1B_ADDR, ICU_IEN5_BIT },	/* No.221 SCI2 TXI2 */
+	{ ICU_IER1B_ADDR, ICU_IEN6_BIT },	/* No.222 SCI2 TEI2 */
+	{ ICU_IER1B_ADDR, ICU_IEN7_BIT },	/* No.223 SCI3 RXI3 */
+	{ ICU_IER1C_ADDR, ICU_IEN0_BIT },	/* No.224 SCI3 TXI3 */
+	{ ICU_IER1C_ADDR, ICU_IEN1_BIT },	/* No.225 SCI3 TEI3 */
+	{ ICU_IER1C_ADDR, ICU_IEN2_BIT },	/* No.226 SCI4 RXI4 */
+	{ ICU_IER1C_ADDR, ICU_IEN3_BIT },	/* No.227 SCI4 TXI4 */
+	{ ICU_IER1C_ADDR, ICU_IEN4_BIT },	/* No.228 SCI4 TEI4 */
+	{ ICU_IER1C_ADDR, ICU_IEN5_BIT },	/* No.229 SCI5 RXI5 */
+	{ ICU_IER1C_ADDR, ICU_IEN6_BIT },	/* No.230 SCI5 TXI5 */
+	{ ICU_IER1C_ADDR, ICU_IEN7_BIT },	/* No.231 SCI5 TEI5 */
+	{ ICU_IER1D_ADDR, ICU_IEN0_BIT },	/* No.232 SCI6 RXI6 */
+	{ ICU_IER1D_ADDR, ICU_IEN1_BIT },	/* No.233 SCI6 TXI6 */
+	{ ICU_IER1D_ADDR, ICU_IEN2_BIT },	/* No.234 SCI6 TEI6 */
+	{ ICU_IER1D_ADDR, ICU_IEN3_BIT },	/* No.235 SCI7 RXI7 */
+	{ ICU_IER1D_ADDR, ICU_IEN4_BIT },	/* No.236 SCI7 TXI7 */
+	{ ICU_IER1D_ADDR, ICU_IEN5_BIT },	/* No.237 SCI7 TEI7 */
+	{ ICU_IER1D_ADDR, ICU_IEN6_BIT },	/* No.238 SCI8 RXI8 */
+	{ ICU_IER1D_ADDR, ICU_IEN7_BIT },	/* No.239 SCI8 TXI8 */
+	{ ICU_IER1E_ADDR, ICU_IEN0_BIT },	/* No.240 SCI8 TEI8 */
+	{ ICU_IER1E_ADDR, ICU_IEN1_BIT },	/* No.241 SCI9 RXI9 */
+	{ ICU_IER1E_ADDR, ICU_IEN2_BIT },	/* No.242 SCI9 TXI9 */
+	{ ICU_IER1E_ADDR, ICU_IEN3_BIT },	/* No.243 SCI9 TEI9 */
+	{ ICU_IER1E_ADDR, ICU_IEN4_BIT },	/* No.244 SCI10 RXI10 */
+	{ ICU_IER1E_ADDR, ICU_IEN5_BIT },	/* No.245 SCI10 TXI10 */
+	{ ICU_IER1E_ADDR, ICU_IEN6_BIT },	/* No.246 SCI10 TEI10 */
+	{ ICU_IER1E_ADDR, ICU_IEN7_BIT },	/* No.247 SCI11 RXI11 */
+	{ ICU_IER1F_ADDR, ICU_IEN0_BIT },	/* No.248 SCI11 TXI11 */
+	{ ICU_IER1F_ADDR, ICU_IEN1_BIT },	/* No.249 SCI11 TEI11 */
+	{ ICU_IER1F_ADDR, ICU_IEN2_BIT },	/* No.250 SCI12 RXI12 */
+	{ ICU_IER1F_ADDR, ICU_IEN3_BIT },	/* No.251 SCI12 TXI12 */
+	{ ICU_IER1F_ADDR, ICU_IEN4_BIT },	/* No.252 SCI12 TEI12 */
+	{ ICU_IER1F_ADDR, ICU_IEN5_BIT },	/* No.253 IEB IEBINT */
+	{ NULL, INVALID_OFFSET },			/* No.254 予約 */
+	{ NULL, INVALID_OFFSET },			/* No.255 予約 */
+};
+
+
+/*
+ *  IRQコントロールレジスタアドレステーブル
+ */
+volatile uint8_t __evenaccess * const irqcr_reg_addr[ IRQ_MAX ] = {
+	ICU_IRQ0_ADDR,
+	ICU_IRQ1_ADDR,
+	ICU_IRQ2_ADDR,
+	ICU_IRQ3_ADDR,
+	ICU_IRQ4_ADDR,
+	ICU_IRQ5_ADDR,
+	ICU_IRQ6_ADDR,
+	ICU_IRQ7_ADDR,
+	ICU_IRQ8_ADDR,
+	ICU_IRQ9_ADDR,
+	ICU_IRQ10_ADDR,
+	ICU_IRQ11_ADDR,
+	ICU_IRQ12_ADDR,
+	ICU_IRQ13_ADDR,
+	ICU_IRQ14_ADDR,
+	ICU_IRQ15_ADDR,
+};
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/rx630_kernel_impl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/rx630_kernel_impl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/rx630_kernel_impl.h	(revision 398)
@@ -0,0 +1,105 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ *  Copyright (C) 2013      by Mitsuhiro Matsuura
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		プロセッサ依存モジュール（RX630用）
+ *
+ *  このインクルードファイルは，target_kernel_impl.h（または，そこからインク
+ *  ルードされるファイル）のみからインクルードされる．他のファイルから
+ *  直接インクルードしてはならない．
+ */
+
+
+#ifndef TOPPERS_RX630_CONFIG_H
+#define TOPPERS_RX630_CONFIG_H
+
+
+/*
+ *  割込み要因数
+ */
+#define	INHNO_MAX	UINT_C( 256 )
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  割込み制御用型定義
+ */
+typedef struct ier_info {
+	volatile uint8_t __evenaccess	*addr;
+			 uint8_t				offset;
+} IER_INFO;
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  割込み制御用定義
+ */
+#define	INVALID_OFFSET				( 0xFFU )
+#define	INTNO_IRQ( intno )			( ( 64U <= ( intno ) ) && ( ( intno ) <= 79U ) )
+#define	INTNO_IRQ_OFFSET( intno )	( ( intno ) - 64U )
+#define	IRQ_MAX						UINT_C( 16 )
+
+#define IR_TOP						(0x00087010)
+#define IR_REG( intno )				((volatile uint8_t __evenaccess * )(IR_TOP + (intno-16)))
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  割込み制御用テーブル
+ */
+
+/* 割込み要因プライオリティレジスタアドレス */
+extern volatile uint8_t __evenaccess * const ipr_reg_addr[];
+/* 割込み要求許可レジスタアドレス */
+extern const IER_INFO ier_reg_addr[];
+/* 割込み要求レジスタアドレス */
+extern volatile uint8_t __evenaccess * const ir_reg_addr[];
+/* IRQコントロールレジスタアドレス */
+extern volatile uint8_t __evenaccess * const irqcr_reg_addr[];
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  プロセッサ依存モジュール（RX630用）
+ */
+#include "prc_kernel_impl.h"
+
+#endif	/* TOPPERS_RX630_CONFIG_H */
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/scif.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/scif.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/scif.h	(revision 398)
@@ -0,0 +1,168 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2001-2011 by Industrial Technology Institute,
+ *                              Miyagi Prefectural Government, JAPAN
+ *  Copyright (C) 2007-2016 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2017      by Cores Co., Ltd. Japan
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  $Id$
+ */
+
+/*
+ *		FIFO内蔵シリアルコミュニケーションインタフェースに関する定義
+ */
+
+#ifndef TOPPERS_SCIF_H
+#define TOPPERS_SCIF_H
+
+/*
+ *  SCIレジスタのベース番地の定義
+ */
+#define SCI0_BASE	((uint32_t)(SCI0_SMR_ADDR))
+#define SCI1_BASE	((uint32_t)(SCI1_SMR_ADDR))
+#define SCI2_BASE	((uint32_t)(SCI2_SMR_ADDR))
+#define SCI3_BASE	((uint32_t)(SCI3_SMR_ADDR))
+#define SCI4_BASE	((uint32_t)(SCI4_SMR_ADDR))
+#define SCI5_BASE	((uint32_t)(SCI5_SMR_ADDR))
+#define SCI6_BASE	((uint32_t)(SCI6_SMR_ADDR))
+#define SCI7_BASE	((uint32_t)(SCI7_SMR_ADDR))
+#define SCI8_BASE	((uint32_t)(SCI8_SMR_ADDR))
+#define SCI9_BASE	((uint32_t)(SCI9_SMR_ADDR))
+#define SCI10_BASE	((uint32_t)(SCI10_SMR_ADDR))
+#define SCI11_BASE	((uint32_t)(SCI11_SMR_ADDR))
+/* SCI12は下記のSCI_NUMが使用できない */
+
+/* モジュールストップコントロールレジスタB bit */
+#define SCI_NUM(base)	(((intptr_t)base - SCI0_BASE) / 0x20)
+#define SCI_MSTPCRB_BIT(base)	(1 << (31 - SCI_NUM(base)))
+
+/* 指定可能なクロックソース */
+#define CLK_F1	UINT_C(0x00)
+#define CLK_F4	UINT_C(0x01)
+#define CLK_F16	UINT_C(0x02)
+#define CLK_F64	UINT_C(0x03)
+
+/* シリアルモードレジスタ（SMR） */
+#define CKS			UINT_C(0x03)
+#define MP			UINT_C(0x04)
+#define STOP		UINT_C(0x08)
+#define PM			UINT_C(0x10)
+#define PE			UINT_C(0x20)
+#define CHR			UINT_C(0x40)
+#define CM			UINT_C(0x80)
+#define ASYNC_7BIT	UINT_C(0x00)
+#define ASYNC_8BIT	UINT_C(0x40)
+
+/* シリアルコントロールレジスタ（SCR） */
+#define CKE			UINT_C(0x03)
+#define TEIE		UINT_C(0x04)
+#define RE			UINT_C(0x10)
+#define TE			UINT_C(0x20)
+#define RIE			UINT_C(0x40)
+#define TIE			UINT_C(0x80)
+
+/* シリアルステータスレジスタ（SSR） */
+#define TEND		UINT_C(0x04)
+#define PER			UINT_C(0x08)
+#define FER			UINT_C(0x10)
+#define ORER		UINT_C(0x20)
+
+/* スマートカードモードレジスタ（SCMR） */
+#define SMIF		UINT_C(0x01)
+#define SINV		UINT_C(0x04)
+#define SDIR		UINT_C(0x08)
+#define BCP2		UINT_C(0x80)
+
+/* シリアル拡張モードレジスタ（SEMR） */
+#define ACS0		UINT_C(0x01)
+#define ABCS		UINT_C(0x10)
+#define NFEN		UINT_C(0x20)
+
+/* I2C モードレジスタ1（SIMR1） */
+#define IICM		UINT_C(0x01)
+
+/* I2C モードレジスタ2（SIMR2） */
+#define IICINTM		UINT_C(0x01)
+#define IICCSC		UINT_C(0x02)
+#define IICACKT		UINT_C(0x20)
+
+/* I2C モードレジスタ3（SIMR2） */
+#define IICSTAREQ	UINT_C(0x01)
+#define IICRSTAREQ	UINT_C(0x02)
+#define IICSTPREQ	UINT_C(0x04)
+#define IICSTIF		UINT_C(0x08)
+
+/* I2C ステータスレジスタ（SISR） */
+#define IICACKR		UINT_C(0x01)
+
+/* SPI モードレジスタ（SPMR） */
+#define SSE			UINT_C(0x01)
+#define CTSE		UINT_C(0x02)
+#define MSS			UINT_C(0x04)
+#define CKPOL		UINT_C(0x40)
+#define CKPH 		UINT_C(0x80)
+
+#define SCI_SCR_FLG_ENABLE	(RE | TE)
+#define SCI_SMR_FLG_ENABLE	(STOP | PM | PE | CHR | CM)
+
+/*
+ *  SCIレジスタの番地の定義
+ */
+#define SCI_SMR(base)		((uint8_t *)((intptr_t)base + 0x00U))
+#define SCI_BRR(base)		((uint8_t *)((intptr_t)base + 0x01U))
+#define SCI_SCR(base)		((uint8_t *)((intptr_t)base + 0x02U))
+#define SCI_TDR(base)		((uint8_t *)((intptr_t)base + 0x03U))
+#define SCI_SSR(base)		((uint8_t *)((intptr_t)base + 0x04U))
+#define SCI_RDR(base)		((uint8_t *)((intptr_t)base + 0x05U))
+#define SCI_SCMR(base)		((uint8_t *)((intptr_t)base + 0x06U))
+#define SCI_SEMR(base)		((uint8_t *)((intptr_t)base + 0x07U))
+#define SCI_SNFR(base)		((uint8_t *)((intptr_t)base + 0x08U))
+#define SCI_SIMR1(base)		((uint8_t *)((intptr_t)base + 0x09U))
+#define SCI_SIMR2(base)		((uint8_t *)((intptr_t)base + 0x0AU))
+#define SCI_SIMR3(base)		((uint8_t *)((intptr_t)base + 0x0BU))
+#define SCI_SISR(base)		((uint8_t *)((intptr_t)base + 0x0CU))
+#define SCI_SPMR(base)		((uint8_t *)((intptr_t)base + 0x0DU))
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  コールバックルーチンの識別番号
+ */
+#define SIO_RDY_SND    (1U)        /* 送信可能コールバック */
+#define SIO_RDY_RCV    (2U)        /* 受信通知コールバック */
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_SCIF_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/sectrx.inc
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/sectrx.inc	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/sectrx.inc	(revision 398)
@@ -0,0 +1,130 @@
+;*
+;*  TOPPERS/ASP Kernel
+;*      Toyohashi Open Platform for Embedded Real-Time Systems/
+;*      Advanced Standard Profile Kernel
+;* 
+;*  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+;* 
+;*  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+;*  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+;*  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+;*  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+;*      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+;*      スコード中に含まれていること．
+;*  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+;*      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+;*      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+;*      の無保証規定を掲載すること．
+;*  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+;*      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+;*      と．
+;*    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+;*        作権表示，この利用条件および下記の無保証規定を掲載すること．
+;*    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+;*        報告すること．
+;*  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+;*      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+;*      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+;*      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+;*      免責すること．
+;* 
+;*  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+;*  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+;*  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+;*  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+;*  の責任を負わない．
+;* 
+;*  @(#) $Id$
+;* 
+
+;
+;  ターゲットシステム依存セクション定義ファイル(スターターキット用)
+;
+
+;
+;  セクションの定義
+;
+;  セクションのアドレス定義はHEW上の最適化リンカの
+;  オプションにて実施する.
+;
+
+	;
+	;  初期値有りデータ領域のセクション
+	;
+	;  00000000h - 00020000h
+	;
+	.section	D, ROMDATA
+	.section	D_2, ROMDATA, ALIGN = 2
+	.section	D_1, ROMDATA
+
+
+	;
+	;  初期値無しデータ領域のセクション
+	;
+	;  00000000h - 00020000h
+	;
+	.section	B, DATA, ALIGN = 4
+	.section	B_2, DATA, ALIGN = 2
+	.section	B_1, DATA
+	.section	W, ROMDATA,ALIGN = 4
+	.section	W_1, ROMDATA
+	.section	W_2, ROMDATA, ALIGN = 2
+
+
+	;
+	;  カーネルスタック領域のセクション
+	;
+	;  00000000h - 00020000h
+	;
+	;  以下.blkb命令で確保しているカーネルスタック領域のサイズを
+	;  変更する場合は, target_kernel_impl.hのDEFAULT_ISTKSZの値を, 同じ
+	;  値に変更すること.
+	;
+;	.section	SI, DATA, ALIGN = 4
+;	.global _DEFAULT_ISTACK
+;_DEFAULT_ISTACK:
+;	.blkb		DEFAULT_ISTKSZ
+;	.global DEFAULT_ISTACK_TOP
+;DEFAULT_ISTACK_TOP:
+
+	;
+	;  定数領域のセクション
+	;
+	;  00100000h - 00107FFFh
+	;
+	.section	C, ROMDATA, ALIGN = 4
+	.section	C_2, ROMDATA, ALIGN = 2
+	.section	C_1, ROMDATA
+
+	;
+	;  初期値有りデータ領域の初期値
+	;
+	;  00100000h - 00107FFFh
+	;
+	.section	R, DATA, ALIGN = 4
+	.section	R_2, DATA, ALIGN = 2
+	.section	R_1, DATA
+
+	;
+	;  可変ベクタテーブル領域のセクション
+	;
+	;  00100000h - 00107FFFh
+	;
+	.section	.fvectors, ROMDATA, ALIGN = 4
+	.global VVECTOR_TOP
+VVECTOR_TOP:
+
+	;
+	;  プログラム領域のセクション
+	;
+	;  FFE80000h - FFFFFF7Fh
+	;
+	.section	P, CODE
+
+	;
+	;  固定ベクタテーブル領域のセクション
+	;
+	;  FFFFFF80h - FFFFFFFFh
+	;
+	.section	FVECT, ROMDATA, ALIGN = 4
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/start.S
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/start.S	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/start.S	(revision 398)
@@ -0,0 +1,149 @@
+;*
+;*  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,2006 by Embedded and Real-Time Systems Laboratory
+;*              Graduate School of Information Science, Nagoya Univ., JAPAN
+;*  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+;* 
+;*  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+;*  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+;*  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+;*  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+;*      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+;*      スコード中に含まれていること．
+;*  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+;*      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+;*      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+;*      の無保証規定を掲載すること．
+;*  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+;*      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+;*      と．
+;*    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+;*        作権表示，この利用条件および下記の無保証規定を掲載すること．
+;*    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+;*        報告すること．
+;*  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+;*      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+;*      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+;*      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+;*      免責すること．
+;* 
+;*  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+;*  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+;*  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+;*  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+;*  の責任を負わない．
+;* 
+;*  @(#) $Id$
+;* 
+
+#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 "sectrx.inc"
+
+	;
+	;  メモリマップの定義(ターゲット依存部)
+	;
+
+.equ	DFLRE,				007FC440H		; DFLREレジスタ
+
+.equ	DB_BLOCK_ENABLE,	02D0FH
+
+;
+;  初期化ルーチン
+;
+	.section	P, CODE
+
+	.global	_start
+	.global	_sta_ker
+	.global	_software_init_hook
+	.global	_hardware_init_hook
+	.global	__kernel_istkpt
+	.global	_vvector_table
+
+_start:
+	;
+	;  電源投入後はレベル0, 全割込み禁止状態である.
+	;  カーネルでは高速割込みを使用しないため、BPC, BPSW及びFINTV
+	;  の初期化は行わない.
+	;
+
+	;
+	;  内蔵ROM（データフラッシュ）領域の設定
+	;
+	;  リセット後, データフラッシュ領域は読み出し禁止となっている
+	;  ため, 読み出し許可に設定する.
+	;
+	mov.l	#DFLRE, r5
+	mov.w	#DB_BLOCK_ENABLE, [R5]
+	
+	;
+	;  スタックポインタの設定
+	;
+	;  ユーザにて非タスクコンテキスト用スタック領域を用意した場合,
+	;  ユーザ領域を設定する.
+	;  kernel_cfg.cにて"_kernel_istkpt"の値を決定する.
+	;
+	mov.l	#__kernel_istkpt, r5
+	mov.l	[r5], r0			; 非タスクコンテキスト用スタック領域を設定
+
+	;
+	;  可変ベクタテーブルの設定
+	;
+	; mvtc	#VVECTOR_TOP, intb	; ベクタテーブルの設定
+	mvtc	#_vvector_table, intb	; ベクタテーブルの設定
+
+	;
+	;  ハードウェア固有の初期化ルーチンの呼出し
+	;
+	mov.l	#_hardware_init_hook, r5
+	cmp		#0, r5
+	beq.b	init_D
+	jsr		r5
+
+	;
+	;  初期値あり変数領域の初期化
+	;
+init_D:
+	mov.l	#(_edata - _data), r3
+	cmp		#0, r3
+	beq.b	clear_B						; サイズ0なら初期化必要なし
+	mov.l	#(_data), r1
+	mov.l	#(_mdata), r2
+	smovf
+
+	;
+	;  初期値なし変数領域の初期化
+	;
+clear_B:
+	mov.l	#0, r2
+	mov.l	#(_bss), r1
+	mov.l	#(_ebss - _bss) , r3
+	sstr.b
+
+	;
+	;  software_init_hook を呼出し（0 でない場合）
+	;
+	;  ソフトウェア環境（特にライブラリ）に依存して必要な初期化処理
+	;  がある場合は，software_init_hook という関数を用意すればよい.
+	;
+	mov.l	#_software_init_hook, r5
+	cmp		#0, r5
+	beq.b	kernel_link
+	jsr		r5
+
+	;
+	;  カーネルスタート
+	;
+kernel_link:
+	bra.a	__sta_ker					; --> __sta_ker()
+
+	.end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/tSCIF.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/tSCIF.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/tSCIF.c	(revision 398)
@@ -0,0 +1,301 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2006-2016 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2017      by Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		FIFO内蔵シリアルコミュニケーションインタフェース用 簡易SIOドライバ
+ */
+
+#include <sil.h>
+#include "tSCIF_tecsgen.h"
+#include "scif.h"
+#include "target_kernel_impl.h"
+
+/*
+ *  プリミティブな送信／受信関数
+ */
+
+/*
+ *  受信バッファに文字があるか？
+ */
+Inline bool_t
+scif_getready(CELLCB *p_cellcb)
+{
+	/*
+	 *  受信フラグがONのときのみ受信バッファから文字を取得する.
+	 *  これは, ポーリング受信に対応するためである.
+	 *  しかし, RX600シリーズでは受信フラグがないこと, システムサービス
+	 *  では受信割込みの中からしかデータを受信しに来ないことから, 常に
+	 *  受信バッファから文字を取得する.
+	 */
+	return true;
+}
+
+/*
+ *  送信バッファに空きがあるか？
+ */
+Inline bool_t
+scif_putready(CELLCB *p_cellcb)
+{
+	if((sil_reb_mem(SCI_SSR(ATTR_baseAddress)) & SCI_SSR_TEND_BIT) != 0){
+		return(true);
+	}
+	return(false);
+}
+
+/*
+ *  送信する文字の書込み
+ */
+Inline void
+scif_putchar(CELLCB *p_cellcb, char c)
+{
+	sil_wrb_mem(SCI_TDR(ATTR_baseAddress), c);
+}
+
+/*
+ *  シリアルI/Oポートのオープン
+ */
+void
+eSIOPort_open(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	uint_t	cnt, brr, clk;
+	volatile uint8_t i;
+
+	if (VAR_initialized) {
+		/*
+		 *  既に初期化している場合は、二重に初期化しない．
+		 */
+		return;
+	}
+
+	cnt = (FREQ_PCLK * 1000) / (16 * ATTR_baudRate);
+	if (cnt < 512)
+		clk = 0;
+	else if (cnt < 4 * 512)
+		clk = 1;
+	else if (cnt < 16 * 512)
+		clk = 2;
+	else if (cnt < 64 * 512)
+		clk = 3;
+	else
+		return;
+
+	brr = cnt / (1 << (2 * clk));
+	brr = (brr / 2) + (brr % 2) - 1;
+
+	/*
+	 *  SCIドライバの初期化ルーチン
+	 */
+
+	/*
+	 *  割り込み要求先レジスタの設定(ISELRi)
+	 *
+	 *  リセット値と同じ値を設定することになるため,
+	 *  処理は省略する.
+	 */
+
+	/*
+	 *  モジュールストップ機能の設定
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRB_ADDR,
+		sil_rew_mem(SYSTEM_MSTPCRB_ADDR) & ~SCI_MSTPCRB_BIT(ATTR_baseAddress));
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* 書込み禁止 */
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(ATTR_baseAddress), 0x00U);
+
+	/* クロック選択ビット(SMR.CKS[1:0]ビットを設定) */
+	sil_wrb_mem(SCI_SMR(ATTR_baseAddress),
+		(sil_reb_mem(SCI_SMR(ATTR_baseAddress)) & ~0x03) | clk);
+
+	/* SMRに送信／ 受信フォーマットを設定) */
+	sil_wrb_mem(SCI_SMR(ATTR_baseAddress),
+			sil_reb_mem(SCI_SMR(ATTR_baseAddress)) & (~SCI_SMR_FLG_ENABLE));
+
+	/* ビットレートを設定 */
+	sil_wrb_mem(SCI_BRR(ATTR_baseAddress), brr);
+
+	/* ビット期間(基本クロック16サイクルの期間が1ビット期間となる) */
+	for(i = 0; i < 16; i++) { }
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(ATTR_baseAddress),
+			(sil_reb_mem(SCI_SCR(ATTR_baseAddress)) | SCI_SCR_FLG_ENABLE));
+
+	VAR_initialized = true;
+}
+
+/*
+ *  シリアルI/Oポートのクローズ
+ */
+void
+eSIOPort_close(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	/*
+	 *  UART停止
+	 */
+	sil_wrb_mem(SCI_SCR(ATTR_baseAddress), 0x00U);
+}
+
+/*
+ *  シリアルI/Oポートへの文字送信
+ */
+bool_t
+eSIOPort_putChar(CELLIDX idx, char c)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	if (scif_putready(p_cellcb)){
+		scif_putchar(p_cellcb, c);
+		return(true);
+	}
+	return(false);
+}
+
+/*
+ *  シリアルI/Oポートからの文字受信
+ */
+int_t
+eSIOPort_getChar(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	uint8_t reg;
+	int_t c = -1;
+
+	/* オーバランエラーチェック */ /* ZZZ */
+	reg = sil_reb_mem(SCI_SSR(ATTR_baseAddress));
+	while((reg & SCI_SSR_ORER_BIT) != 0) {
+		sil_wrb_mem(SCI_SSR(ATTR_baseAddress), reg & ~SCI_SSR_ORER_BIT);
+		reg = sil_reb_mem(SCI_SSR(ATTR_baseAddress));
+	}
+
+	/*
+	 *  受信フラグがONのときのみ受信バッファから文字を取得する.
+	 *  これは, ポーリング受信に対応するためである.
+	 *  しかし, RX600シリーズでは受信フラグがないこと, システムサービス
+	 *  では受信割込みの中からしかデータを受信しに来ないことから, 常に
+	 *  受信バッファから文字を取得する.
+	 */
+	c = (int)(sil_reb_mem(SCI_RDR(ATTR_baseAddress)));
+
+	return c;
+}
+
+/*
+ *  シリアルI/Oポートからのコールバックの許可
+ */
+void
+eSIOPort_enableCBR(CELLIDX idx, uint_t cbrtn)
+{
+	CELLCB		*p_cellcb = GET_CELLCB(idx);
+
+	switch (cbrtn) {
+		case SIO_RDY_SND:
+			sil_wrb_mem(SCI_SCR(ATTR_baseAddress),
+				(sil_reb_mem(SCI_SCR(ATTR_baseAddress)) | SCI_SCR_TEIE_BIT));
+			break;
+		case SIO_RDY_RCV:
+			sil_wrb_mem(SCI_SCR(ATTR_baseAddress),
+				(sil_reb_mem(SCI_SCR(ATTR_baseAddress)) | SCI_SCR_RIE_BIT));
+			break;
+		default:
+			assert(1);
+			break;
+	}
+}
+
+/*
+ *  シリアルI/Oポートからのコールバックの禁止
+ */
+void
+eSIOPort_disableCBR(CELLIDX idx, uint_t cbrtn)
+{
+	CELLCB		*p_cellcb = GET_CELLCB(idx);
+
+	switch (cbrtn) {
+		case SIO_RDY_SND:
+			sil_wrb_mem(SCI_SCR(ATTR_baseAddress),
+				(sil_reb_mem(SCI_SCR(ATTR_baseAddress)) & (~SCI_SCR_TEIE_BIT)));
+			break;
+		case SIO_RDY_RCV:
+			sil_wrb_mem(SCI_SCR(ATTR_baseAddress),
+				(sil_reb_mem(SCI_SCR(ATTR_baseAddress)) & (~SCI_SCR_RIE_BIT)));
+			break;
+		default:
+			assert(1);
+			break;
+	}
+}
+
+/*
+ *  シリアルI/Oポートに対する受信割込み処理
+ */
+void
+eiRxISR_main(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	if (scif_getready(p_cellcb)) {
+		/*
+		 *  受信通知コールバックルーチンを呼び出す．
+		 */
+		ciSIOCBR_readyReceive();
+	}
+}
+
+/*
+ *  シリアルI/Oポートに対する送信割込み処理
+ */
+void
+eiTxISR_main(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	if (scif_putready(p_cellcb)) {
+		/*
+		 *  送信可能コールバックルーチンを呼び出す．
+		 */
+		ciSIOCBR_readySend();
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/tSCIF.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/tSCIF.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/rx630_gcc/tSCIF.cdl	(revision 398)
@@ -0,0 +1,71 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *		FIFO内蔵シリアルコミュニケーションインタフェース用 簡易SIOドラ
+ *		イバのコンポーネント記述
+ */
+
+/*
+ *  FIFO内蔵シリアルコミュニケーションインタフェースに関する定義のイン
+ *  ポート
+ */
+import_C("scif.h");
+
+/*
+ *  FIFO内蔵シリアルコミュニケーションインタフェース用 簡易SIOドライバ
+ *  のセルタイプ
+ */
+celltype tSCIF {
+	entry	sSIOPort	eSIOPort;
+	call	siSIOCBR	ciSIOCBR;
+
+	entry	siHandlerBody	eiRxISR;
+	entry	siHandlerBody	eiTxISR;
+
+	attr {
+		uintptr_t	baseAddress;	/* SCIFレジスタのベースアドレス */
+		uint32_t	baudRate;		/* ボーレートの設定値 */
+	};
+	var {
+		bool_t		initialized = false;	/* 初期化済み */
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/tracelog/tTraceLog.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/tracelog/tTraceLog.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/tracelog/tTraceLog.c	(revision 398)
@@ -0,0 +1,335 @@
+/*
+ *  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-2016 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 "tTraceLog_tecsgen.h"
+#include "kernel/kernel_impl.h"
+#include "kernel/task.h"
+#include "kernel/time_event.h"
+#include <sil.h>
+#include <log_output.h>
+#include "target_syssvc.h"
+
+/*
+ *  トレース時刻の取り出し
+ *
+ *  デフォルトでは，ログ時刻として，高分解能タイマのカウント値を用いて
+ *  いる．ターゲット依存で変更する場合には，SYSLOG_GET_LOGTIMに，ログ時
+ *  刻を取り出すマクロを定義する．
+ */
+#ifndef SYSLOG_GET_LOGTIM
+#define SYSLOG_GET_LOGTIM(p_logtim) \
+				(*(p_logtim) = target_hrt_get_current())
+#endif /* SYSLOG_GET_TIM */
+
+/*
+ *  トレースログの開始
+ */
+ER
+eTraceLog_start(MODE mode)
+{
+	if ((mode & TRACE_CLEAR) != 0U) {
+		VAR_count = 0U;
+		VAR_head = 0U;
+		VAR_tail = 0U;
+		mode &= ~TRACE_CLEAR;
+	}
+	VAR_mode = mode;
+	return(E_OK);
+}     
+
+/* 
+ *  トレースログの書込み
+ */
+ER
+eTraceLog_write(const TRACE *p_trace)
+{
+	SIL_PRE_LOC;
+
+	if ((VAR_mode & (TRACE_RINGBUF | TRACE_AUTOSTOP)) != 0U) {
+		SIL_LOC_INT();
+
+		/*
+		 *  トレース時刻の設定
+		 */
+		SYSLOG_GET_LOGTIM(&(((SYSLOG *) p_trace)->logtim));
+
+		/*
+		 *  トレースバッファに記録
+		 */
+		VAR_logBuffer[VAR_tail] = *p_trace;
+		VAR_tail++;
+		if (VAR_tail >= ATTR_logBufferSize) {
+			VAR_tail = 0U;
+		}
+		if (VAR_count < ATTR_logBufferSize) {
+			VAR_count++;
+			if (VAR_count >= ATTR_logBufferSize
+						&& (VAR_mode & TRACE_AUTOSTOP) != 0U) {
+				VAR_mode = TRACE_STOP;
+			}
+		}
+		else {
+			VAR_head = VAR_tail;
+		}
+
+		SIL_UNL_INT();
+	}
+	return(E_OK);
+}
+
+/*
+ *  トレースログの読出し
+ */
+ER
+eTraceLog_read(TRACE* p_trace)
+{
+	ER_UINT	ercd;
+	SIL_PRE_LOC;
+
+	SIL_LOC_INT();
+
+	/*
+	 *  トレースログバッファからの取出し
+	 */
+	if (VAR_count > 0U) {
+		*p_trace = VAR_logBuffer[VAR_head];
+		VAR_count--;
+		VAR_head++;
+		if (VAR_head >= ATTR_logBufferSize) {
+			VAR_head = 0U;
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+
+	SIL_UNL_INT();
+	return(ercd);
+}
+
+/*
+ *  アセンブリ言語で記述されるコードからトレースログを出力するための関
+ *  数
+ */
+
+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);
+}
+
+/* 
+ *  カーネル情報の取出し
+ */
+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;
+	if (TSTAT_DORMANT(tstat)) {
+		tstatstr = "DORMANT";
+	}
+	else {
+		if (TSTAT_SUSPENDED(tstat)) {
+			if (TSTAT_WAITING(tstat)) {
+				tstatstr = "WAITING-SUSPENDED";
+			}
+			else {
+				tstatstr = "SUSPENDED";
+			}
+		}
+		else if (TSTAT_WAITING(tstat)) {
+			tstatstr = "WAITING";
+		}
+		else {
+			tstatstr = "RUNNABLE";
+		}
+	}
+	return((intptr_t) tstatstr);
+}
+
+/* 
+ *  トレースログの表示
+ */
+static void
+trace_print(TRACE *p_trace, void (*putc)(char))
+{
+	intptr_t	traceinfo[TNUM_LOGPAR + 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->logpar[0]);
+		traceinfo[1] = get_tskstat(p_trace->logpar[1]);
+		tracemsg = "task %d becomes %s.";
+		break;
+	case LOG_TYPE_DSP|LOG_ENTER:
+		traceinfo[0] = get_tskid(p_trace->logpar[0]);
+		tracemsg = "dispatch from task %d.";
+		break;
+	case LOG_TYPE_DSP|LOG_LEAVE:
+		traceinfo[0] = get_tskid(p_trace->logpar[0]);
+		tracemsg = "dispatch to task %d.";
+		break;
+	case LOG_TYPE_COMMENT:
+		for (i = 1; i < TNUM_LOGPAR; i++) {
+			traceinfo[i-1] = p_trace->logpar[i];
+		}
+		tracemsg = (const char *)(p_trace->logpar[0]);
+		break;
+	case LOG_TYPE_ASSERT:
+		traceinfo[0] = p_trace->logpar[0];
+		traceinfo[1] = p_trace->logpar[1];
+		traceinfo[2] = p_trace->logpar[2];
+		tracemsg = "%s:%u: Assertion `%s' failed.";
+		break;
+	case LOG_TYPE_INH|LOG_ENTER:
+		traceinfo[0] = p_trace->logpar[0];
+		tracemsg = "interrupt IN: %d";
+		break;
+	case LOG_TYPE_INH|LOG_LEAVE:
+		traceinfo[0] = p_trace->logpar[0];
+		tracemsg = "interrupt OUT: %d";
+		break;
+	case LOG_TYPE_EXC|LOG_ENTER:
+		traceinfo[0] = p_trace->logpar[0];
+		tracemsg = "exception IN: %d";
+		break;
+	case LOG_TYPE_EXC|LOG_LEAVE:
+		traceinfo[0] = p_trace->logpar[0];
+		tracemsg = "exception OUT: %d";
+		break;
+	default:
+		traceinfo[0] = p_trace->logtype;
+		tracemsg = "unknown trace log type: %d.";
+		break;
+	}
+	syslog_printf(tracemsg, traceinfo, putc);
+	(*putc)('\n');
+}
+
+/*
+ *  低レベル出力の呼出し関数
+ */
+static void
+low_putchar(char c)
+{
+	cPutLog_putChar(c);
+}
+
+/* 
+ *  トレースログのダンプ
+ */
+void
+eTraceLog_dump(void)
+{
+	TRACE	trace;
+
+	while (trace_rea_log(&trace) >= 0) {
+		trace_print(&trace, low_putchar);
+	}
+}
+
+/*
+ *  トレースログのダンプ（受け口関数）
+ */
+void
+tTraceLog_eDump_main(uintptr_t exinf)
+{
+	eTraceLog_dump();
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/tracelog/tTraceLog.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/tracelog/tTraceLog.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/tracelog/tTraceLog.cdl	(revision 398)
@@ -0,0 +1,98 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *		トレースログ機能のコンポーネント記述ファイル
+ */
+
+/*
+ *  トレースログ出力に関する定義
+ */
+import_C("arch/tracelog/trace_log.h");
+
+/*
+ *  トレースログ機能のシグニチャ
+ */
+signature sTraceLog {
+	/*
+	 *  トレースログの開始
+	 */
+	ER		start([in] MODE mode);
+
+	/*
+	 *  トレースログの書込み
+	 */
+	ER		write([in] const TRACE *p_trace);
+
+	/*
+	 *  トレースログの読出し
+	 */
+	ER		read([out] TRACE *p_trace);
+
+	/*
+	 *  トレースログのダンプ
+	 */
+	void	dump(void);
+};
+
+/*
+ *  トレースログ機能のセルタイプ
+ */
+[singleton, active]
+celltype tTraceLog {
+	entry	sTraceLog		eTraceLog;
+	entry	sRoutineBody	eDump;		/* 終了処理ルーチンとの接続 */
+	call	sPutLog			cPutLog;	/* 低レベル出力との接続 */
+
+	attr {
+		uint_t	logBufferSize;			/* ログバッファサイズ */
+		MODE	initialMode = C_EXP("TRACE_STOP");
+										/* 初期化後のモード */
+	};
+	var {
+		[size_is(logBufferSize)] TRACE	*logBuffer;	/* ログバッファ */
+		uint_t	count = 0;				/* ログバッファ中のログの数 */
+		uint_t	head = 0;				/* 先頭のログの格納位置 */
+		uint_t	tail = 0;				/* 次のログの格納位置 */
+		MODE	mode = initialMode;		/* トレースモード */
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/tracelog/trace_log.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/tracelog/trace_log.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/arch/tracelog/trace_log.h	(revision 398)
@@ -0,0 +1,209 @@
+/*
+ *  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-2016 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_kernel_impl.hおよび
+ *  target_syssvc.hのみからインクルードされる．また，トレースログ機能の
+ *  初期化や記録の開始／停止，トレースログのダンプを行うプログラムから
+ *  インクルードすることを想定している．
+ */
+
+#ifndef TOPPERS_TRACE_CONFIG_H
+#define TOPPERS_TRACE_CONFIG_H
+
+/*
+ *  トレースログのデータ構造
+ *
+ *  システムログ機能のログ情報のデータ構造と同じものを用いる．
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+#include <t_syslog.h>
+typedef	SYSLOG	TRACE;
+
+#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
+
+/*
+ *  TECSで記述されたテストプログラム用のサービスを直接呼び出すための定義
+ *
+ *  C言語で記述されたアプリケーションから，TECSで記述されたトレースログ
+ *  機能を呼び出すためには，アダプタを用いるのが正当な方法であるが，ト
+ *  レースログ機能がシングルトンであることを利用して直接呼び出す．
+ */
+extern ER	tTraceLog_eTraceLog_start(MODE mode);
+extern ER	tTraceLog_eTraceLog_write(const TRACE *p_trace);
+extern ER	tTraceLog_eTraceLog_read(TRACE* p_trace);
+extern void	tTraceLog_eTraceLog_dump(void);
+
+/*
+ *  トレースログの開始
+ *
+ *  トレースログの記録を開始／停止する．引数により次の動作を行う．
+ *
+ *  TRACE_STOP：トレースを停止．
+ *  TRACE_RINGBUF：リングバッファモードでトレースを開始．
+ *  TRACE_AUTOSTOP：自動停止モードでトレースを開始．
+ *  TRACE_CLEAR：トレースログをクリア．
+ */
+Inline ER
+trace_sta_log(MODE mode)
+{
+	return(tTraceLog_eTraceLog_start(mode));
+}
+
+/*
+ *  トレースログの書込み
+ */
+Inline ER
+trace_wri_log(TRACE *p_trace)
+{
+	return(tTraceLog_eTraceLog_write(p_trace));
+}
+
+/*
+ *  トレースログの読出し
+ */
+Inline ER
+trace_rea_log(TRACE *p_trace)
+{
+	return(tTraceLog_eTraceLog_read(p_trace));
+}
+
+/*
+ *  トレースログを出力するためのライブラリ関数
+ */
+
+Inline void
+trace_write_0(uint_t type)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	(void) trace_wri_log(&trace);
+}
+
+Inline void
+trace_write_1(uint_t type, intptr_t arg1)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	trace.logpar[0] = arg1;
+	(void) trace_wri_log(&trace);
+}
+
+Inline void
+trace_write_2(uint_t type, intptr_t arg1, intptr_t arg2)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	trace.logpar[0] = arg1;
+	trace.logpar[1] = arg2;
+	(void) trace_wri_log(&trace);
+}
+
+Inline void
+trace_write_3(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3)
+{
+	TRACE	trace;
+
+	trace.logtype = type;
+	trace.logpar[0] = arg1;
+	trace.logpar[1] = arg2;
+	trace.logpar[2] = arg3;
+	(void) trace_wri_log(&trace);
+}
+														
+/*
+ *  トレースログを出力するためのマクロ
+ */
+
+#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))
+
+/* 
+ *  トレースログのダンプ
+ *
+ *  トレースログをダンプする．終了処理ルーチンとして登録することも想定
+ *  している．引数として，ダンプ先となる文字出力関数へのポインタを渡す．
+ *  ターゲット依存の低レベル文字出力を利用する場合には，target_putcを渡
+ *  す．
+ */
+Inline void
+trace_dump(void)
+{
+	tTraceLog_eTraceLog_dump();
+}
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  トレースログ方法の設定
+ */
+#define LOG_TSKSTAT(p_tcb)		trace_2(LOG_TYPE_TSKSTAT, p_tcb, p_tcb->tstat)
+
+#define LOG_TSYSLOG_ESYSLOG_WRITE_ENTER(priority, p_syslog) \
+								trace_wri_log((TRACE *) p_syslog)
+
+#endif /* TOPPERS_TRACE_CONFIG_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/GenFile.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/GenFile.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/GenFile.rb	(revision 398)
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+#
+#  TOPPERS Configurator by Ruby
+#
+#  Copyright (C) 2015,2016 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+#  Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#  Copyright (C) 2016 by APTJ Co., Ltd., JAPAN
+#
+#  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#      スコード中に含まれていること．
+#  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#      の無保証規定を掲載すること．
+#  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#      と．
+#    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#        作権表示，この利用条件および下記の無保証規定を掲載すること．
+#    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#        報告すること．
+#  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#      免責すること．
+#
+#  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#  の責任を負わない．
+#
+#  $Id$
+#
+
+#
+#		ファイル作成クラス
+#
+
+#
+# ファイルに書こうとした内容を変数に蓄積し，プログラムの終了時（output
+# メソッドが呼ばれた時）にファイルに出力する．既にファイルが存在し，差
+# 分がない場合は出力しない（タイムスタンプを更新しない）．
+#
+class GenFile
+  @@fileDataHash = {}
+
+  def initialize(fileName)
+    @selfFileName = fileName
+    if !@@fileDataHash.has_key?(fileName)
+      @@fileDataHash[@selfFileName] = ""
+    end
+  end
+
+  # ファイルデータの末尾に文字列を追加する
+  def append(code = "")
+    @@fileDataHash[@selfFileName] << code
+  end
+
+  # ファイルデータに1行追加する
+  def add(code = "")
+    @@fileDataHash[@selfFileName] << code << "\n"
+  end
+
+  # ファイルデータに1行追加する(改行2回)
+  def add2(code = "")
+    add(code + "\n")
+  end
+
+  # コメントヘッダを追加する
+  def comment_header(comment)
+    add("/*")
+    comment.split("\n").each do |sLine|
+      add(" *  " + sLine)
+    end
+    add2(" */")
+  end
+
+  # ファイルデータを表示する
+  def print()
+    puts(@@fileDataHash[@selfFileName])
+  end
+
+  # 全ファイルを出力する
+  def self.output()
+    @@fileDataHash.each do |fileName, fileData|
+      # 既にファイルが存在し，差分がない場合は出力しない
+      #（タイムスタンプを更新しない）
+      if File.exist?(fileName)
+        if fileData == File.read(fileName)
+          next
+        end
+      end
+      File.open(fileName, "w") do |file|
+        puts("[#{File.basename($0)}] Generated #{fileName}")
+        file.puts(fileData)
+      end
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/MANIFEST
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/MANIFEST	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/MANIFEST	(revision 398)
@@ -0,0 +1,8 @@
+MANIFEST
+cfg.rb
+pass1.rb
+pass2.rb
+GenFile.rb
+SRecord.rb
+
+doc/cfg_user.txt
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/SRecord.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/SRecord.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/SRecord.rb	(revision 398)
@@ -0,0 +1,172 @@
+# -*- coding: utf-8 -*-
+#
+#  TOPPERS Configurator by Ruby
+#
+#  Copyright (C) 2015,2016 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+#  Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#
+#  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#      スコード中に含まれていること．
+#  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#      の無保証規定を掲載すること．
+#  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#      と．
+#    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#        作権表示，この利用条件および下記の無保証規定を掲載すること．
+#    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#        報告すること．
+#  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#      免責すること．
+#
+#  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#  の責任を負わない．
+#
+#  $Id$
+#
+
+#
+#		Sレコードファイル処理クラス
+#
+
+#
+# Sレコードファイルを変数に読み込み，要求された番地のデータを返す．
+#
+# @sRecDataは，先頭番地をキーとし，そこからのデータ（ヘキサダンプ形式）
+# を値とブロックが格納されたハッシュである．連続するブロックは，1つのブ
+# ロックにまとめて格納するものとする（そうしないと，データの取出しやサー
+# チが面倒になる）．
+#
+class SRecord
+  def initialize(fileName)
+    @sRecData = {}
+    File.open(fileName) do |file|
+      prevAddress = 0
+      prevData = ""
+      file.each do |line|
+        # データレコードにより分岐
+        case line.slice(0, 2)
+        when "S1"
+          # データ長（アドレス分[2byte]+チェックサム分1byteを減算）
+          length = line.slice(2, 2).hex - 2 - 1
+
+          # アドレス（4文字=2byte）
+          address = line.slice(4, 4).hex
+
+          # データ（この時点では文字列で取っておく）
+          data = line.slice(8, length * 2)
+        when "S2"
+          # データ長（アドレス分[3byte]+チェックサム分1byteを減算）
+          length = line.slice(2, 2).hex - 3 - 1
+
+          # アドレス（6文字=3byte）
+          address = line.slice(4, 6).hex
+
+          # データ（この時点では文字列で取っておく）
+          data = line.slice(10, length * 2)
+        when "S3"
+          # データ長（アドレス分[4byte]+チェックサム分1byteを減算）
+          length = line.slice(2, 2).hex - 4 - 1
+
+          # アドレス（8文字=4byte）
+          address = line.slice(4, 8).hex
+
+          # データ（この時点では文字列で取っておく）
+          data = line.slice(12, length * 2)
+        else
+          address = nil
+        end
+
+        if !address.nil?
+          # データを格納する
+          if address == prevAddress + prevData.size / 2
+            prevData << data
+          else
+            set_data(prevAddress, prevData) if prevData.size > 0
+            prevAddress = address
+            prevData = data
+          end
+        end
+      end
+      set_data(prevAddress, prevData) if prevData.size > 0
+    end
+  end
+
+  # データ取得
+  def get_data(address, size)
+    endAddress = address + size
+    @sRecData.each do |block, blockData|
+      if (block <= address && endAddress <= block + blockData.size / 2)
+        offset = (address - block) * 2
+        return(blockData[offset, size * 2])
+      end
+    end
+    return(nil)
+  end
+
+  # データ書込み
+  def set_data(address, data)
+    endAddress = address + data.size / 2
+    @sRecData.each do |block, blockData|
+      nEndBlock = block + blockData.size / 2
+
+      if nEndBlock < address || endAddress < block
+        # 重なりがない
+      elsif address < block
+        # 新規データの方が先頭番地が小さい
+        # ここでは endAddress >= block が成立している
+        offset = (endAddress - block) * 2
+        data << blockData[offset..-1]
+        @sRecData.delete(block)
+      else
+        # 登録済みデータの方が先頭番地が小さいか同じ
+        offset = (address - block) * 2
+        address = block
+        blockData[offset, data.size] = data
+        data = blockData
+        @sRecData.delete(block)
+      end
+    end
+    @sRecData[address] = data
+  end
+
+  # 値としてのデータ取得
+  def get_value(address, size, signed)
+    targetData = get_data(address, size)
+    if targetData.nil?
+      return(nil)
+    else
+      if $endianLittle
+        # リトルエンディアンの場合，バイトオーダーを逆にする
+        reverseData = ""
+        # 後ろから2文字ずつ抜き出し，並び替える
+        while targetData.size > 0
+          reverseData << targetData[-2, 2]
+          targetData.slice!(-2, 2)
+        end
+        returnData = reverseData.hex
+      else
+        returnData = targetData.hex
+      end
+
+      # 負の数の処理
+      if signed && (returnData & (1 << (size * 8 - 1))) != 0
+        returnData -= (1 << (size * 8))
+      end
+      return(returnData)
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/cfg.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/cfg.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/cfg.rb	(revision 398)
@@ -0,0 +1,726 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+#
+#  TOPPERS Configurator by Ruby
+#
+#  Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#  Copyright (C) 2015,2016 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$
+#
+
+if $0 == __FILE__
+  TOOL_ROOT = File.expand_path(File.dirname(__FILE__)) + "/"
+  $LOAD_PATH.unshift(TOOL_ROOT)
+end
+
+require "pp"
+require "csv"
+require "optparse"
+require "pstore"
+require "GenFile.rb"
+require "SRecord.rb"
+
+#
+#  定数定義
+#
+# 共通
+VERSION = "1.2.2"
+
+# cfg1_out関係
+CFG1_PREFIX        = "TOPPERS_cfg_"
+CFG1_MAGIC_NUM     = "TOPPERS_magic_number"
+CFG1_SIZEOF_SIGNED = "TOPPERS_sizeof_signed_t"
+CFG1_OUT_C         = "cfg1_out.c"
+CFG1_OUT_DB        = "cfg1_out.db"
+CFG1_OUT_SREC      = "cfg1_out.srec"
+CFG1_OUT_SYMS      = "cfg1_out.syms"
+CFG1_OUT_TIMESTAMP = "cfg1_out.timestamp"
+CFG1_OUT_TARGET_H  = "target_cfg1_out.h"
+
+# cfg2_out関係
+CFG2_OUT_DB        = "cfg2_out.db"
+
+# cfg3_out関係
+CFG3_OUT_DB        = "cfg3_out.db"
+
+#
+#  エラー発生有無フラグ
+#
+$errorFlag = false
+
+#
+#  エラー／警告表示関数
+#
+# 一般的なエラー表示（処理を中断）
+def error_exit(message, location = "")
+  location += " " if location != ""
+  abort("#{location}error: #{message}")
+end
+
+# 一般的なエラー表示（処理を継続）
+def error(message, location = "")
+  location += " " if location != ""
+  STDERR.puts("#{location}error: #{message}")
+  $errorFlag = true
+end
+
+# 一般的な警告表示
+def warning(message, location = "")
+  location += " " if location != ""
+  STDERR.puts("#{location}warning: #{message}")
+end
+
+# システムコンフィギュレーションファイルの構文解析時のエラー
+$noParseError = 0
+def parse_error(cfgFile, message)
+  error(message, "#{cfgFile.getFileName()}:#{cfgFile.getLineNo}:")
+  if ($noParseError += 1) >= 10
+    abort("too many errors emitted, stopping now")
+  end
+end
+
+# システムコンフィギュレーションファイルの構文解析時の警告
+def parse_warning(cfgFile, message)
+  warning(message, "#{cfgFile.getFileName()}:#{cfgFile.getLineNo}:")
+end
+
+#
+#  静的API処理時のエラー／警告表示関数
+#
+# 静的API処理時のエラー／警告を短く記述できるように，メッセージ中の%ま
+# たは%%で始まる記述を以下のように展開する．
+#	%label → #{params[:label]}
+#	%%label → label `#{params[:label]}'
+#
+# エラー／警告メッセージの展開
+def expand_message(message, params)
+  result = message.dup
+  while /%%(\w+)\b/ =~ result
+    param = $1
+    paramVal = params[param.to_sym].to_s
+    result.sub!(/%%#{param}\b/, "#{param} `#{paramVal}'")
+  end
+  while /%(\w+)\b/ =~ result
+    param = $1
+    paramVal = params[param.to_sym].to_s
+    result.sub!(/%#{param}\b/, paramVal)
+  end
+  return(result)
+end
+
+# 静的API処理時のエラー
+def error_api(params, message)
+  error(expand_message(message, params), \
+			"#{params[:_file_]}:#{params[:_line_]}:")
+end
+
+# 静的API処理時の警告
+def warning_api(params, message)
+  warning(expand_message(message, params), \
+			"#{params[:_file_]}:#{params[:_line_]}:")
+end
+
+# 静的API処理時のエラー（エラーコード付き）
+def error_ercd(errorCode, params, message)
+  error_api(params, "#{errorCode}: #{message}")
+end
+
+# 静的API処理時の警告（エラーコード付き）
+def warning_ercd(errorCode, params, message)
+  warning_api(params, "#{errorCode}: #{message}")
+end
+
+# パラメータのエラー
+def error_wrong(errorCode, params, symbol, wrong)
+  error_ercd(errorCode, params, "%%#{symbol} is #{wrong} in %apiname")
+end
+
+def error_wrong_id(errorCode, params, symbol, objid, wrong)
+  error_ercd(errorCode, params, "%%#{symbol} is #{wrong} " \
+	             					"in %apiname of %#{objid}")
+end
+
+def error_wrong_sym(errorCode, params, symbol, symbol2, wrong)
+  error_ercd(errorCode, params, "%%#{symbol} is #{wrong} " \
+									"in %apiname of %%#{symbol2}")
+end
+
+# パラメータ不正のエラー
+def error_illegal(errorCode, params, symbol)
+  error_ercd(errorCode, params, "illegal %%#{symbol} in %apiname")
+end
+
+def error_illegal_id(errorCode, params, symbol, objid)
+  error_ercd(errorCode, params, "illegal %%#{symbol} " \
+	             					"in %apiname of %#{objid}")
+end
+
+def error_illegal_sym(errorCode, params, symbol, symbol2)
+  error_ercd(errorCode, params, "illegal %%#{symbol} " \
+									"in %apiname of %%#{symbol2}")
+end
+
+#
+#  Stringクラスの拡張（二重引用符で囲まれた文字列の作成／展開）
+#
+class String
+  #
+  #  二重引用符で囲まれた文字列の作成
+  #
+  def quote
+    result = ""
+    self.chars do |c|
+      case c
+      when "'"
+        result += "\\\'"
+      when "\""
+        result += "\\\""
+      when "\0"
+        result += "\\0"
+      when "\a"
+        result += "\\a"
+      when "\b"
+        result += "\\b"
+      when "\f"
+        result += "\\f"
+      when "\n"
+        result += "\\n"
+      when "\r"
+        result += "\\r"
+      when "\t"
+        result += "\\t"
+      when "\v"
+        result += "\\v"
+      when "\\"
+        result += "\\\\"
+      else
+        result += c
+      end
+    end
+    return("\"" + result + "\"")
+  end
+
+  #
+  #  二重引用符で囲まれた文字列の展開
+  #
+  def unquote
+    if /^\"(.*)\"$/m =~ self
+      str = $1
+      result = ""
+      while (/^(.*)\\(.*)$/m =~ str)
+        result += $1
+        str = $2
+        case str
+        when /^[aA](.*)$/m
+          result += "\a"
+          str = $1
+        when /^[bB](.*)$/m
+          result += "\b"
+          str = $1
+        when /^[fF](.*)$/m
+          result += "\f"
+          str = $1
+        when /^[nN](.*)$/m
+          result += "\n"
+          str = $1
+        when /^[rR](.*)$/m
+          result += "\r"
+          str = $1
+        when /^[tT](.*)$/m
+          result += "\t"
+          str = $1
+        when /^[vV](.*)$/m
+          result += "\v"
+          str = $1
+        when /^[xX]([0-9a-fA-F][0-9a-fA-F]?)(.*)$/m
+          result += $1.hex
+          str = $2
+        when /^([0-7][0-7]?[0-7]?)(.*)$/m
+          result += $1.oct
+          str = $2
+        when /^\\(.*)$/m
+          result += "\\"
+          str = $1
+        end
+      end
+      return(result + str)
+    else
+      return(self.dup)
+    end
+  end
+end
+
+#
+#  NumStrクラス（数値に文字列を付加したもの）の定義
+#
+class NumStr
+  def initialize(val, str = val.to_s)
+    @val = val
+    @str = str
+  end
+
+  # 数値情報を返す
+  def val
+    return @val
+  end
+  alias_method :to_i, :val
+
+  # 文字列情報を返す
+  def str
+    return @str
+  end
+  alias_method :to_s, :str
+
+  # 比較は数値情報で行う
+  def ==(other)
+    @val == other
+  end
+  def !=(other)
+    @val != other
+  end
+  def <=>(other)
+    @val <=> other
+  end
+
+  # ハッシュのキーとして使う時の比較も数値情報で行う
+  def eql?(other)
+    @val == other.val
+  end
+
+  # ハッシュ値の定義も上書きする
+  def hash
+    return @val.hash
+  end
+
+  # 数値クラスと演算できるようにする
+  def coerce(other)
+    if other.kind_of?(Numeric)
+      return other, @val
+    else
+      raise
+    end
+  end
+
+  # 二重引用符で囲まれた文字列の作成
+  def quote
+    str.quote
+  end
+
+  # 二重引用符で囲まれた文字列の展開
+  def unquote
+    str.unquote
+  end
+
+  # pp時の表示
+  def pretty_print(q)
+    q.text("[#{@val}(=0x#{@val.to_s(16)}),")
+    @str.pretty_print(q)
+    q.text("]")
+  end
+
+  # 未定義のメソッドは@valに送る
+  def method_missing(*method)
+    @val.send(*method)
+  end
+end
+
+#
+#  シンボルファイルの読み込み
+#
+#  以下のメソッドは，GNUのnmが生成するシンボルファイルに対応している．
+#  別のツールに対応する場合には，このメソッドを書き換えればよい．
+#
+def ReadSymbolFile(symbolFileName)
+  begin
+    symbolFile = File.open(symbolFileName)
+  rescue Errno::ENOENT, Errno::EACCES => ex
+    abort(ex.message)
+  end
+
+  symbolAddress = {}
+  symbolFile.each do |line|
+    # スペース区切りで分解
+    fields = line.split(/\s+/)
+
+    # 3列になっていない行は除外
+    if fields.size == 3
+      symbolAddress[fields[2]] = fields[0].hex
+    end
+  end
+  symbolFile.close
+  return(symbolAddress)
+end
+
+#
+#  値取得シンボルをグローバル変数として定義する
+#
+def DefineSymbolValue
+  $symbolValueTable.each do |symbolName, symbolData|
+    if symbolData.has_key?(:VALUE)
+      eval("$#{symbolName} = #{symbolData[:VALUE]}")
+    end
+  end
+end
+
+#
+#  インクルードパスからファイルを探す
+#
+def SearchFilePath(fileName)
+  if File.exist?(fileName)
+    # 指定したファイルパスに存在する
+    return fileName
+  elsif /^\./ =~ fileName
+    # 相対パスを指定していて見つからなかった場合，存在しないものとする
+    #（意図しないファイルが対象となることを防止）
+    return nil
+  else
+    # 各インクルードパスからファイル存在チェック
+    $includeDirectories.each do |includeDirectory|
+      path = includeDirectory + "/" + fileName
+      # 見つかったら相対パスを返す
+      if File.exist?(path)
+        return path
+      end
+    end
+    return nil
+  end
+end
+
+#
+#  指定した生成スクリプト（trbファイル）を検索してloadする
+#
+def IncludeTrb(fileName)
+  filePath = SearchFilePath(fileName)
+  if filePath.nil?
+    error_exit("`#{fileName}' not found")
+  else
+    load(filePath)
+  end
+end
+
+#
+#  パス3の処理
+#
+def Pass3
+  #
+  #  パス2から引き渡される情報をファイルから読み込む
+  #
+  db = PStore.new(CFG2_OUT_DB)
+  db.transaction(true) do
+    $apiDefinition = db[:apiDefinition]
+    $symbolValueTable = db[:symbolValueTable]
+    $cfgFileInfo = db[:cfgFileInfo]
+    $includeFiles = db[:includeFiles]
+    $cfgData = db[:cfgData]
+    $asmLabel = db[:asmLabel]
+    $endianLittle = db[:endianLittle]
+    $cfg2Data = db[:cfg2Data]
+  end
+  $cfg3Data = {}
+
+  #
+  #  値取得シンボルをグローバル変数として定義する
+  #
+  DefineSymbolValue()
+
+  #
+  #  生成スクリプト（trbファイル）を実行する
+  #
+  $trbFileNames.each do |trbFileName|
+    IncludeTrb(trbFileName)
+  end
+
+  #
+  #  パス4に引き渡す情報をファイルに生成
+  #
+  if $omitOutputDb.nil?
+    db = PStore.new(CFG3_OUT_DB)
+    db.transaction do
+      db[:apiDefinition] = $apiDefinition
+      db[:symbolValueTable] = $symbolValueTable
+      db[:cfgFileInfo] = $cfgFileInfo
+      db[:includeFiles] = $includeFiles
+      db[:cfgData] = $cfgData
+      db[:asmLabel] = $asmLabel
+      db[:endianLittle] = $endianLittle
+      db[:cfg3Data] = $cfg3Data
+    end
+  end
+end
+
+#
+#  パス4の処理
+#
+def Pass4
+  #
+  #  パス3から引き渡される情報をファイルから読み込む
+  #
+  db = PStore.new(CFG3_OUT_DB)
+  db.transaction(true) do
+    $apiDefinition = db[:apiDefinition]
+    $symbolValueTable = db[:symbolValueTable]
+    $cfgFileInfo = db[:cfgFileInfo]
+    $includeFiles = db[:includeFiles]
+    $cfgData = db[:cfgData]
+    $asmLabel = db[:asmLabel]
+    $endianLittle = db[:endianLittle]
+    $cfg3Data = db[:cfg3Data] || db[:cfg2Data]
+  end
+
+  #
+  #  値取得シンボルをグローバル変数として定義する
+  #
+  DefineSymbolValue()
+
+  #
+  #  生成スクリプト（trbファイル）を実行する
+  #
+  $trbFileNames.each do |trbFileName|
+    IncludeTrb(trbFileName)
+  end
+end
+
+#
+#  生成スクリプト（trbファイル）向けの関数
+#
+def SYMBOL(symbol)
+  if !$romSymbol.nil? && $romSymbol.has_key?($asmLabel + symbol)
+    return $romSymbol[$asmLabel + symbol]
+  else
+    return nil
+  end
+end
+
+def BCOPY(fromAddress, toAddress, size)
+  if !$romImage.nil?
+    copyData = $romImage.get_data(fromAddress, size)
+    if !copyData.nil?
+      $romImage.set_data(toAddress, copyData)
+    end
+  end
+end
+
+def BZERO(address, size)
+  if !$romImage.nil?
+    $romImage.set_data(address, "00" * size)
+  end
+end
+
+def PEEK(address, size, signed=false)
+  if !$romImage.nil?
+    return $romImage.get_value(address, size, signed)
+  else
+    return nil
+  end
+end
+
+#
+#  グローバル変数の初期化
+#
+$kernel = nil
+$pass = nil
+$includeDirectories = []
+$trbFileNames = []
+$apiTableFileNames = []
+$symvalTableFileNames = []
+$romImageFileName = nil
+$romSymbolFileName = nil
+$dependencyFileName = nil
+$idInputFileName = nil
+$idOutputFileName = nil
+
+#
+#  オプションの処理
+#
+OptionParser.new(banner="Usage: cfg.rb [options] CONFIG-FILE", 40) do |opt|
+  opt.version = VERSION
+  opt.on("-k KERNEL", "--kernel KERNEL", "kernel profile name") do |val|
+    $kernel = val
+  end
+  opt.on("-p NUM", "--pass NUM", "processing pass number") do |val|
+    $pass = val
+  end
+  opt.on("-I DIRECTORY", "--include-directory DIRECTORY",
+										 "include directory") do |val|
+    $includeDirectories.push(val)
+  end
+  opt.on("-T TRB-FILE", "--trb-file TRB-FILE",
+         "generation script (trb file)") do |val|
+    $trbFileNames.push(val)
+  end
+  opt.on("--api-table API-TABLE-FILE", "static API table file") do |val|
+    $apiTableFileNames.push(val)
+  end
+  opt.on("--symval-table SYMVAL-TABLE-FILE", "symbol-value table file") do |val|
+    $symvalTableFileNames.push(val)
+  end
+  opt.on("--rom-image SREC-FILE", "rom image file (s-record)") do |val|
+    $romImageFileName = val
+  end
+  opt.on("--rom-symbol SYMS-FILE", "rom symbol table file (nm)") do |val|
+    $romSymbolFileName = val
+  end
+  opt.on("--id-input-file ID-FILE", "ID input file") do |val|
+    $idInputFileName = val
+  end
+  opt.on("--id-output-file ID-FILE", "ID output file") do |val|
+    $idOutputFileName = val
+  end
+  opt.on("-M [DEPEND-FILE]", "--print-dependencies [DEPEND-FILE]",
+         "dependency file") do |val|
+    $dependencyFileName = val.nil? ? "" : val
+  end
+  opt.on("-O", "--omit-output-db", "omit DB file output") do
+    $omitOutputDb = true
+  end
+  opt.on("-v", "--version", "show version number") do
+    abort(opt.ver)
+  end
+  opt.on("-h", "--help", "show help (this)") do
+    abort(opt.help)
+  end
+  opt.parse!(ARGV)
+end
+$configFileNames = ARGV
+
+#
+#  オプションのチェック
+#
+if $pass.nil?
+  # パスの指定は必須
+  abort("`--pass' option is mandatory")
+elsif /^[1234]$/ !~ $pass
+  abort("pass number `#{$pass}' is not valid")
+end
+
+# パス1では，静的APIテーブルは必須
+if ($pass == "1" && $apiTableFileNames.empty?)
+  abort("`--api-table' option must be specified in pass 1")
+end
+
+# パス1以外では，生成スクリプト（trbファイル）が必須
+if ($pass != "1" && $trbFileNames.empty?)
+  abort("`--trb-file' must be specified except in pass 1")
+end
+
+#
+#  カーネルオプションの処理
+#
+case $kernel
+when /^hrp/
+	$supportDomain = true
+when /^fmp/
+	$supportClass = true
+end
+
+#
+#  ID番号入力ファイルの取り込み
+#
+$inputObjid = {}
+if !$idInputFileName.nil?
+  begin
+    idInputFile = File.open($idInputFileName)
+  rescue Errno::ENOENT, Errno::EACCES => ex
+    abort(ex.message)
+  end
+
+  idInputFile.each do |line|
+    ( objName, objidNumber ) = line.split(/\s+/)
+    $inputObjid[objName] = objidNumber.to_i
+  end
+
+  idInputFile.close
+end
+
+#
+#  指定されたシンボルファイルの読み込み
+#
+if !$romSymbolFileName.nil?
+  if File.exist?($romSymbolFileName)
+    $romSymbol = ReadSymbolFile($romSymbolFileName)
+  else
+    error_exit("`#{$romSymbolFileName}' not found")
+  end
+end
+
+#
+#  指定されたSレコードファイルの読み込み
+#
+if !$romImageFileName.nil?
+  if File.exist?($romImageFileName)
+    $romImage = SRecord.new($romImageFileName)
+  else
+    error_exit("`#{$romImageFileName}' not found")
+  end
+end
+
+#
+#  パスに従って各処理を実行
+#
+case $pass
+when "1"
+  load("pass1.rb")
+  Pass1()
+when "2"
+  load("pass2.rb")
+  Pass2()
+when "3"
+  Pass3()
+when "4"
+  Pass4()
+else
+  error_exit("invalid pass: #{$pass}")
+end
+
+# エラー発生時はabortする
+if $errorFlag
+  if ($0 == __FILE__)
+    abort()
+  else
+    # simplecov対応
+    raise()
+  end
+end
+
+#
+#  作成したすべてのファイルを出力する
+#
+GenFile.output
+
+# 
+#  タイムスタンプファイルの生成
+# 
+if !$timeStampFileName.nil?
+  File.open($timeStampFileName, "w").close
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/pass1.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/pass1.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/pass1.rb	(revision 398)
@@ -0,0 +1,951 @@
+# -*- coding: utf-8 -*-
+#
+#  TOPPERS Configurator by Ruby
+#
+#  Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#  Copyright (C) 2015-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$
+#
+
+#
+#		パス1の処理
+#
+
+#
+#  値取得シンボルテーブルへの固定登録
+#
+$symbolValueTable = {
+  "CHAR_BIT"  => { EXPR: "CHAR_BIT" },
+  "SCHAR_MAX" => { EXPR: "SCHAR_MAX", SIGNED: true },
+  "SCHAR_MIN" => { EXPR: "SCHAR_MIN", SIGNED: true },
+  "UCHAR_MAX" => { EXPR: "UCHAR_MAX" },
+  "CHAR_MAX"  => { EXPR: "CHAR_MAX",  SIGNED: true },
+  "CHAR_MIN"  => { EXPR: "CHAR_MIN",  SIGNED: true },
+  "SHRT_MAX"  => { EXPR: "SHRT_MAX",  SIGNED: true },
+  "SHRT_MIN"  => { EXPR: "SHRT_MIN",  SIGNED: true },
+  "USHRT_MAX" => { EXPR: "USHRT_MAX" },
+  "INT_MAX"   => { EXPR: "INT_MAX",   SIGNED: true },
+  "INT_MIN"   => { EXPR: "INT_MIN",   SIGNED: true },
+  "UINT_MAX"  => { EXPR: "UINT_MAX" },
+  "LONG_MAX"  => { EXPR: "LONG_MAX",  SIGNED: true },
+  "LONG_MIN"  => { EXPR: "LONG_MIN",  SIGNED: true },
+  "ULONG_MAX" => { EXPR: "ULONG_MAX" }
+}
+
+#
+#  静的APIテーブルへの固定登録
+#
+$apiDefinition = { "INCLUDE" =>
+  { :PARAM => [ { :NAME => :file, :STRING => true }]}}
+
+#
+#  静的APIテーブルの読み込み
+#
+def ReadApiTableFile
+  $apiTableFileNames.each do |apiTableFileName|
+    if /^(.+):(\w+)$/ =~ apiTableFileName
+      apiTableFileName = $1
+      apiPhase = $2.to_sym
+    end
+
+    if !File.exist?(apiTableFileName)
+      error_exit("`#{apiTableFileName}' not found")
+      next
+    end
+
+    apiFile = File.open(apiTableFileName)
+    apiFile.each do |line|
+      next if /^#/ =~ line			# コメントをスキップ
+
+      fields = line.split(/\s+/)	# フィールドに分解
+
+      apiName = fields.shift		# API名の取り出し
+      if /^(.+)\[(.+)\]$/ =~ apiName
+        apiName = $1
+        apiDef = { APINAME: apiName, API: $2 }
+      else
+        apiDef = { APINAME: apiName, API: apiName }
+      end
+      if !apiPhase.nil?
+        apiDef[:PHASE] = apiPhase
+      end
+
+      apiParams = []
+      fields.each do |param|
+        case param
+        when /^(\W*)(\w+)(\W*)$/
+          prefix = $1
+          name = $2
+          postfix = $3
+          apiParam = { :NAME => name }
+
+          case prefix
+          when "#"					# オブジェクト識別名（定義）
+            apiParam[:ID_DEF] = true
+          when "%"					# オブジェクト識別名（参照）
+            apiParam[:ID_REF] = true
+          when "."					# 符号無し整数定数式パラメータ
+            apiParam[:EXPTYPE] = "unsigned_t"
+          when "+"					# 符号付き整数定数式パラメータ
+            apiParam[:EXPTYPE] = "signed_t"
+            apiParam[:SIGNED] = true
+          when "&"					# 一般整数定数式パラメータ
+            # do nothing
+          when "$"					# 文字列定数式パラメータ
+            apiParam[:STRING] = true
+          else
+            error_exit("`#{param}' is invalid")
+          end
+
+          case postfix
+          when "*"					# キーを決めるパラメータ
+            apiDef[:KEYPAR] = name
+          when "?"					# オプションパラメータ
+            apiParam[:OPTIONAL] = true
+          when "\.\.\."				# リストパラメータ
+            apiParam[:LIST] = true
+          end
+        
+        when "{"					# {
+          apiParam = { :BRACE => "{" }
+        when "{?"					# {?
+          apiParam = { :BRACE => "{", :OPTBRACE => true }
+
+        when "}"					# }
+          apiParam = { :BRACE => "}" }
+
+        else
+          error_exit("`#{param}' is invalid")
+        end
+        apiParams.push(apiParam)
+      end
+      apiDef[:PARAM] = apiParams
+      $apiDefinition[apiName] = apiDef
+    end
+    apiFile.close
+  end
+end
+
+#
+#  値取得シンボルテーブルの読み込み
+#
+def ReadSymvalTable
+  $symvalTableFileNames.each do |symvalTableFileName|
+    if !File.exist?(symvalTableFileName)
+      error_exit("`#{symvalTableFileName}' not found")
+      next
+    end
+
+    symvalCsv = CSV.open(symvalTableFileName,
+						{ skip_blanks: true, skip_lines: /^#/ })
+    symvalCsv.each do |record|
+      # 変数名
+      if record[0].nil?
+        error_exit("invalid variable name in " \
+						"`#{symvalTableFileName}:#{symvalCsv.to_io.lineno}'")
+      end
+
+      symbol = {}
+      variable = record[0]
+
+      # 式
+      if record[1].nil? || record[1].empty?
+        symbol[:EXPR] = variable
+      else
+        symbol[:EXPR] = record[1]
+      end
+
+      # 式の型
+      if !record[2].nil? && !record[2].empty?
+        case record[2]
+        when /^[bB]/				# 真偽値
+          symbol[:BOOL] = true
+        when /^[uU]/				# 符号無し整数値
+          # 何も設定しない
+        else						# 符号付き整数値
+          symbol[:SIGNED] = true
+        end
+      end
+
+      # コンパイル条件
+      if !record[3].nil? && !record[3].empty?
+        symbol[:CONDITION] = record[3]
+      end
+
+      # 条件が成立しない時の式
+      if !record[4].nil? && !record[4].empty?
+        symbol[:ELSE_EXPR] = record[4]
+      end
+
+      $symbolValueTable[variable] = symbol
+    end
+    symvalCsv.close
+  end
+end
+
+#
+#  システムコンフィギュレーションファイルからの読み込みクラス
+#
+class ConfigFile
+  def initialize(fileName)
+    @cfgFileName = fileName
+    begin
+      @cfgFile = File.open(@cfgFileName)
+    rescue Errno::ENOENT, Errno::EACCES => ex
+      abort(ex.message)
+    end
+    @lineNo = 0
+    @withinComment = false
+  end
+
+  def close
+    @cfgFile.close
+  end
+
+  def getNextLine(withinApi)
+    line = @cfgFile.gets
+    return(nil) if line.nil?
+
+	line.encode!("UTF-16BE", "UTF-8",	# 不正なバイト列を除外する
+					:invalid => :replace,
+					:undef => :replace,
+					:replace => '?').encode!("UTF-8")
+    @lineNo += 1
+
+    line.chomp!
+    if @withinComment
+      case line
+      when /\*\//						# C言語スタイルのコメント終了
+        line.sub!(/^.*?\*\//, "")		# 最初の*/にマッチさせる */
+        @withinComment = false
+      else
+        line = ""
+      end
+    end
+    if !@withinComment
+      line.gsub!(/\/\*.*?\*\//, "")		# C言語スタイルのコメントの除去
+										# 最初の*/にマッチさせる */
+      case line
+      when /^\s*#/						# プリプロセッサディレクティブ
+        if withinApi
+          parse_error(self, \
+					"preprocessor directive must not be within static API")
+          line = ""
+        end
+      when /\/\*/						# C言語スタイルのコメント開始
+        line.sub!(/\/\*.*$/, "")
+        @withinComment = true
+      when /\/\//						# C++言語スタイルのコメント
+        line.sub!(/\/\/.*$/, "")
+      end
+    end
+    return(line)
+  end
+
+  def getFileName
+    return(@cfgFileName)
+  end
+
+  def getLineNo
+    return(@lineNo)
+  end
+end
+
+#
+#  システムコンフィギュレーションファイルのパーサークラス
+#
+class CfgParser
+  @@lastApiIndex = 0
+  @@currentDomain = nil
+  @@currentClass = nil
+  @@nestDC = []
+
+  def initialize
+    @line = ""
+    @skipComma = false						# 次が,であれば読み飛ばす
+  end
+
+  #
+  #  文字列末まで読む
+  #
+  def parseString(cfgFile)
+    string = ""
+    begin
+      case @line
+      when /^([^"]*\\\\)(.*)$/				# \\まで読む
+        string += $1
+        @line = $2
+      when /^([^"]*\\\")(.*)$/				# \"まで読む
+        string += $1
+        @line = $2
+      when /^([^"]*\")(.*)$/				# "まで読む
+        string += $1
+        @line = $2
+        return(string)
+      else									# 行末まで読む
+        string += @line + "\n"
+        @line = cfgFile.getNextLine(true)
+      end
+    end while (@line)
+    error_exit("unterminated string meets end-of-file")
+    return(string)
+  end
+
+  #
+  #  文字末まで読む
+  #
+  def parseChar(cfgFile)
+    string = ""
+    begin
+      case @line
+      when /^([^']*\\\\)(.*)$/				# \\まで読む
+        string += $1
+        @line = $2
+      when /^([^']*\\\')(.*)$/				# \'まで読む
+        string += $1
+        @line = $2
+      when /^([^']*\')(.*)$/				# 'まで読む
+        string += $1
+        @line = $2
+        return(string)
+      else									# 行末まで読む
+        string += @line + "\n"
+        @line = cfgFile.getNextLine(true)
+      end
+    end while (@line)
+    error_exit("unterminated string meets end-of-file")
+    return(string)
+  end
+
+  #
+  #  改行と空白文字を読み飛ばす
+  #
+  def skipSpace(cfgFile, withinApi)
+    loop do
+      return if @line.nil?						# ファイル末であればリターン
+      @line.lstrip!								# 先頭の空白を削除
+      return if @line != ""						# 空行でなければリターン
+      @line = cfgFile.getNextLine(withinApi)	# 次の行を読む
+    end
+  end
+
+  #
+  #  次の文字まで読み飛ばす
+  #
+  def skipToToken(cfgFile, withinApi=true)
+    skipSpace(cfgFile, withinApi)
+    if @line.nil?							# ファイル末であればエラー終了
+      error_exit("unexpexced end-of-file")
+    end
+  end
+
+  #
+  #  パラメータを1つ読む
+  #
+  # @lineの先頭からパラメータを1つ読んで，それを文字列で返す．読んだパ
+  # ラメータは，@lineからは削除する．パラメータの途中で行末に達した時は，
+  # cfgFileから次の行を取り出す．ファイル末に達した時は，nilを返す．
+  #
+  def parseParam(cfgFile)
+    param = ""								# 読んだ文字列
+    parenLevel = 0							# 括弧のネストレベル
+    skipComma = @skipComma
+    @skipComma = false
+
+    skipToToken(cfgFile)					# 次の文字まで読み飛ばす
+    begin
+      if parenLevel == 0
+        case @line
+        when /^(\s*,)(.*)$/					# ,
+          @line = $2
+          if param == "" && skipComma
+            skipComma = false
+            return(parseParam(cfgFile))		# 再帰呼び出し
+          else
+            return(param.strip)
+          end
+        when /^(\s*{)(.*)$/					# {
+          if param != ""
+            return(param.strip)
+          else
+            @line = $2
+            return("{")
+          end
+        when /^(\s*\()(.*)$/				# (
+          param += $1
+          @line = $2
+          parenLevel += 1
+        when /^(\s*([)}]))(.*)$/			# }か)
+          if param != ""
+            return(param.strip)
+          else
+            @line = $3
+            @skipComma = true if $2 == "}"
+            return($2)
+          end
+        when /^(\s*\")(.*)$/				# "
+          @line = $2
+          param += $1 + parseString(cfgFile)
+        when /^(\s*\')(.*)$/				# '
+          @line = $2
+          param += $1 + parseChar(cfgFile)
+        when /^(\s*[^,{}()"'\s]+)(.*)$/		# その他の文字列
+          param += $1
+          @line = $2
+        else								# 行末
+          param += " "
+          @line = cfgFile.getNextLine(true)
+        end
+      else
+        # 括弧内の処理
+        case @line
+        when /^(\s*\()(.*)$/				# "("
+          param += $1
+          @line = $2
+          parenLevel += 1
+        when /^(\s*\))(.*)$/				# ")"
+          param += $1
+          @line = $2
+          parenLevel -= 1
+        when /^(\s*\")(.*)$/				# "
+          @line = $2
+          param += $1 + parseString(cfgFile)
+        when /^(\s*\')(.*)$/				# '
+          @line = $2
+          param += $1 + parseChar(cfgFile)
+        when /^(\s*[^()"'\s]+)(.*)$/		# その他の文字列
+          param += $1
+          @line = $2
+        else								# 行末
+          param += " "
+          @line = cfgFile.getNextLine(true)
+        end
+      end
+    end while (@line)
+    return(param.strip)
+  end
+
+  def getParam(apiParam, param, cfgFile)
+    if param == ""
+      if !apiParam.has_key?(:OPTIONAL)
+        parse_error(cfgFile, "unexpected `,'")
+      end
+      return(param)
+    end
+
+    if apiParam.has_key?(:ID_DEF) || apiParam.has_key?(:ID_REF)
+      if (/^[A-Za-z_]\w*$/ !~ param)
+        parse_error(cfgFile, "`#{param}' is illegal object ID")
+      end
+      return(param)
+    end
+
+    if apiParam.has_key?(:STRING)
+      return(param.unquote)
+    else
+      return(param)
+    end
+  end
+
+  def parseApi(cfgFile, apiName)
+    # 静的APIの読み込み
+    staticApi = {}
+    tooFewParams = false
+    skipUntilBrace = 0
+
+    skipToToken(cfgFile)					# 次の文字まで読み飛ばす
+    if (/^\((.*)$/ =~ @line)
+      @line = $1
+
+      staticApi[:APINAME] = apiName
+      staticApi[:_FILE_] = cfgFile.getFileName
+      staticApi[:_LINE_] = cfgFile.getLineNo
+      apiDef = $apiDefinition[apiName]
+      param = parseParam(cfgFile)
+
+      apiDef[:PARAM].each do |apiParam|
+        return(staticApi) if param.nil?		# ファイル末であればリターン
+
+        if skipUntilBrace > 0
+          # API定義を}までスキップ中
+          if apiParam.has_key?(:BRACE)
+            case apiParam[:BRACE]
+            when "{"
+              skipUntilBrace += 1
+            when "}"
+              skipUntilBrace -= 1
+            end
+          end
+        elsif apiParam.has_key?(:OPTIONAL)
+          if /^([{})])$/ !~ param
+            store_param = getParam(apiParam, param, cfgFile)
+            if store_param != ""
+              staticApi[apiParam[:NAME]] = store_param
+            end
+            param = parseParam(cfgFile)
+          end
+        elsif apiParam.has_key?(:LIST)
+          staticApi[apiParam[:NAME]] = []
+          while /^([{})])$/ !~ param
+            staticApi[apiParam[:NAME]].push(getParam(apiParam, param, cfgFile))
+            param = parseParam(cfgFile)
+            break if param.nil?				# ファイル末の場合
+          end
+        elsif apiParam.has_key?(:OPTBRACE)
+          if param == apiParam[:BRACE]
+            param = parseParam(cfgFile)
+            break if param.nil?				# ファイル末の場合
+          else
+            if param == ""
+              param = parseParam(cfgFile)
+              break if param.nil?			# ファイル末の場合
+            elsif /^([})])$/ !~ param
+              parse_error(cfgFile, "`{...}' expected before #{param}")
+            end
+            skipUntilBrace += 1          	# API定義を}までスキップ
+          end
+        elsif !apiParam.has_key?(:BRACE)
+          if /^([{})])$/ !~ param
+            staticApi[apiParam[:NAME]] = getParam(apiParam, param, cfgFile)
+            param = parseParam(cfgFile)
+          elsif !tooFewParams
+            parse_error(cfgFile, "too few parameters before `#{$1}'")
+            tooFewParams = true
+          end
+        elsif param == apiParam[:BRACE]
+          param = parseParam(cfgFile)
+          tooFewParams = false
+        else
+          parse_error(cfgFile, "`#{apiParam[:BRACE]}' expected before #{param}")
+          # )かファイル末まで読み飛ばす
+          loop do
+            param = parseParam(cfgFile)
+            break if (param.nil? || param == ")")
+          end
+          break
+        end
+      end
+
+      # 期待されるパラメータをすべて読んだ後の処理
+      if param != ")"
+        begin
+          param = parseParam(cfgFile)
+          return(staticApi) if param.nil?	# ファイル末であればリターン
+        end while param != ")"
+        parse_error(cfgFile, "too many parameters before `)'")
+      end
+    else
+      parse_error(cfgFile, "syntax error: #{@line}")
+      @line = ""
+    end
+    return(staticApi)
+  end
+
+  def parseOpenBrace(cfgFile)
+    # {の読み込み
+    skipToToken(cfgFile)					# 次の文字まで読み飛ばす
+    if (/^\{(.*)$/ =~ @line)
+      @line = $1
+    else
+      parse_error(cfgFile, "`{' expected before #{@line}")
+    end
+  end
+
+  def parseFile(cfgFileName)
+    cfgFiles = [ ConfigFile.new(cfgFileName) ]
+    @line = ""
+    loop do
+      cfgFile = cfgFiles.last
+
+      skipSpace(cfgFile, false)				# 改行と空白文字を読み飛ばす
+      if @line.nil?
+        # ファイル末の処理
+        cfgFiles.pop.close
+        if cfgFiles.empty?
+          break								# パース処理終了
+        else
+          @line = ""						# 元のファイルに戻って続ける
+        end
+      elsif /^;(.*)$/ =~ @line
+        # ;は読み飛ばす
+        @line = $1
+      elsif /^#/ =~ @line
+        # プリプロセッサディレクティブを読む
+        case @line
+        when /^#include\b(.*)$/
+          $includeFiles.push($1.strip)
+        when /^#(ifdef|ifndef|if|endif|else|elif)\b/
+          directive = { :DIRECTIVE => @line.strip }
+          $cfgFileInfo.push(directive)
+        else
+          parse_error(cfgFile, "unknown preprocessor directive: #{@line}")
+        end
+        @line = ""
+      elsif (/^([A-Z_][A-Z0-9_]*)\b(.*)$/ =~ @line)
+        apiName = $1
+        @line = $2
+
+        case apiName
+        when "KERNEL_DOMAIN"
+          if $supportDomain.nil?
+            parse_warning(cfgFile, "`KERNEL_DOMAIN' is not supported")
+          end
+          if !@@currentDomain.nil?
+            parse_error(cfgFile, "`DOMAIN' must not be nested")
+          end
+          @@currentDomain = "TDOM_KERNEL"
+          parseOpenBrace(cfgFile)
+          @@nestDC.push("domain")
+        when "DOMAIN"
+          if $supportDomain.nil?
+            parse_warning(cfgFile, "`DOMAIN' is not supported")
+          end
+          if !@@currentDomain.nil?
+            parse_error(cfgFile, "`DOMAIN' must not be nested")
+          end
+          domid = parseParam(cfgFile).sub(/^\((.+)\)$/m, "\\1").strip
+          if (/^[A-Za-z_]\w*$/ !~ domid)
+            parse_error(cfgFile, "`#{domid}' is illegal domain ID")
+          else
+            if !$domainId.has_key?(domid)
+              if $inputObjid.has_key?(domid)
+                # ID番号入力ファイルに定義されていた場合
+                $domainId[domid] = $inputObjid[domid]
+                if $domainId[domid] > 32
+                  error_exit("domain ID for `#{domid}' is too large")
+                end
+              else
+                $domainId[domid] = nil
+              end
+            end
+            @@currentDomain = domid
+          end
+          parseOpenBrace(cfgFile)
+          @@nestDC.push("domain")
+        when "CLASS"
+          if $supportClass.nil?
+            parse_warning(cfgFile, "`CLASS' is not supported")
+          end
+          if !@@currentClass.nil?
+            parse_error(cfgFile, "`CLASS' must not be nested")
+          end
+          @@currentClass = parseParam(cfgFile).sub(/^\((.+)\)$/m, "\\1").strip
+          @@classFile = cfgFile.getFileName
+          @@classLine = cfgFile.getLineNo
+          parseOpenBrace(cfgFile)
+          @@nestDC.push("class")
+        else
+          if $apiDefinition.has_key?(apiName)
+            # 静的APIを1つ読む
+            staticApi = parseApi(cfgFile, apiName)
+            if staticApi.empty?
+              # ファイル末か文法エラー
+            elsif (staticApi[:APINAME] == "INCLUDE")
+              # INCLUDEの処理
+              includeFilePath = SearchFilePath(staticApi[:file])
+              if includeFilePath.nil?
+                parse_error(cfgFile, "`#{staticApi[:file]}' not found")
+              else
+                $dependencyFiles.push(includeFilePath)
+                cfgFiles.push(ConfigFile.new(includeFilePath))
+              end
+            else
+              # 静的APIの処理
+              if !@@currentDomain.nil?
+                staticApi[:DOMAIN] = @@currentDomain
+              end
+              if !@@currentClass.nil?
+                staticApi[:CLASS] = @@currentClass
+                staticApi[:CLASS_FILE_] = @@classFile
+                staticApi[:CLASS_LINE_] = @@classLine
+              end
+              staticApi[:INDEX] = (@@lastApiIndex += 1)
+              $cfgFileInfo.push(staticApi)
+            end
+          else
+            parse_error(cfgFile, "unknown static API: #{apiName}")
+          end
+        end
+      elsif (/^\}(.*)$/ =~ @line)
+        # }の処理
+        if @@nestDC.size > 0
+          case @@nestDC.pop
+          when "domain"
+            @@currentDomain = nil
+          when "class"
+            @@currentClass = nil
+          end
+        else
+          error_exit("unexpected `}'")
+        end
+        @line = $1
+      else
+        parse_error(cfgFile, "syntax error: #{@line}")
+        @line = ""
+      end
+    end
+  end
+end
+
+#
+#  cfg1_out.cの生成
+#
+module Cfg1OutC
+  #
+  #  静的APIのファイル名と行番号の出力
+  #
+  def self.OutLineNumber(cfgInfo)
+    @cfg1Out.add("#line #{cfgInfo[:_LINE_]} \"#{cfgInfo[:_FILE_].gsub('\\', '/')}\"")
+  end
+
+  #
+  #  クラス記述のファイル名と行番号の出力
+  #
+  def self.OutClassLineNumber(cfgInfo)
+    @cfg1Out.add("#line #{cfgInfo[:CLASS_LINE_]} \"#{cfgInfo[:CLASS_FILE_].gsub('\\', '/')}\"")
+  end
+
+  #
+  #  パラメータに関する定義の出力
+  #
+  def self.OutParamDef(param, index, apiParam, cfgInfo)
+    if apiParam.has_key?(:ID_DEF)
+      @cfg1Out.add("#define #{param}\t(<>)")
+    elsif apiParam.has_key?(:EXPTYPE)
+      OutLineNumber(cfgInfo)
+      @cfg1Out.add("const #{apiParam[:EXPTYPE]} #{CFG1_PREFIX}valueof_" \
+								"#{apiParam[:NAME]}_#{index} = " \
+								"(#{apiParam[:EXPTYPE]})(#{param});")
+    end
+  end
+
+  #
+  #  cfg1_out.cの生成（メインの処理）
+  #
+  def self.Generate
+    @cfg1Out = GenFile.new(CFG1_OUT_C)
+
+    @cfg1Out.append(<<EOS)
+/* #{CFG1_OUT_C} */
+#define TOPPERS_CFG1_OUT
+#include "kernel/kernel_int.h"
+EOS
+
+    # インクルードヘッダファイル
+    $includeFiles.each do |file|
+      @cfg1Out.add("#include #{file}")
+    end
+
+    @cfg1Out.add(<<EOS)
+
+#ifdef INT64_MAX
+  typedef int64_t signed_t;
+  typedef uint64_t unsigned_t;
+#else
+  typedef int32_t signed_t;
+  typedef uint32_t unsigned_t;
+#endif
+
+#include "#{CFG1_OUT_TARGET_H}"
+
+#if defined(SIL_ENDIAN_BIG) && defined(SIL_ENDIAN_LITTLE)
+#error Both SIL_ENDIAN_BIG and SIL_ENDIAN_LITTLE are defined.
+#endif
+#if !defined(SIL_ENDIAN_BIG) && !defined(SIL_ENDIAN_LITTLE)
+#error Neither SIL_ENDIAN_BIG nor SIL_ENDIAN_LITTLE is defined.
+#endif
+
+const uint32_t #{CFG1_MAGIC_NUM} = 0x12345678;
+const uint32_t #{CFG1_SIZEOF_SIGNED} = sizeof(signed_t);
+EOS
+
+    # 値取得シンボルの処理
+    $symbolValueTable.each do |symbolName, symbolData|
+      if symbolData.has_key?(:BOOL) || symbolData.has_key?(:SIGNED)
+        type = "signed_t"
+      else
+        type = "unsigned_t"
+      end
+      if symbolData.has_key?(:CONDITION)
+        @cfg1Out.add("#if #{symbolData[:CONDITION]}")
+      end
+      @cfg1Out.add("const #{type} #{CFG1_PREFIX}#{symbolName} = " \
+								"(#{type})(#{symbolData[:EXPR]});")
+      if symbolData.has_key?(:ELSE_EXPR)
+        @cfg1Out.add("#else")
+        @cfg1Out.add("const #{type} #{CFG1_PREFIX}#{symbolName} = " \
+								"(#{type})(#{symbolData[:ELSE_EXPR]});")
+      end
+      if symbolData.has_key?(:CONDITION)
+        @cfg1Out.add("#endif")
+      end
+    end
+    @cfg1Out.add
+
+    # ドメインIDの定義の生成
+    $domainId.each do |domainName, domainVal|
+      if domainVal > 0
+        @cfg1Out.add("#define #{domainName} #{domainVal}")
+      end
+    end
+    @cfg1Out.add
+
+    # 静的API／プリプロセッサディレクティブの処理
+    $cfgFileInfo.each do |cfgInfo|
+      if cfgInfo.has_key?(:DIRECTIVE)
+        @cfg1Out.add2(cfgInfo[:DIRECTIVE])
+      else
+        apiDef = $apiDefinition[cfgInfo[:APINAME]]
+        apiIndex = cfgInfo[:INDEX]
+        OutLineNumber(cfgInfo)
+        @cfg1Out.add("const unsigned_t #{CFG1_PREFIX}static_api_" \
+										"#{apiIndex} = #{apiIndex};")
+        apiDef[:PARAM].each do |apiParam|
+          next unless apiParam.has_key?(:NAME)
+          paramName = apiParam[:NAME]
+          next unless cfgInfo.has_key?(paramName)	# パラメータがない場合
+          paramData = cfgInfo[paramName]
+
+          if apiParam.has_key?(:LIST)
+            paramData.each.with_index(1) do |param, index|
+              OutParamDef(param, "#{apiIndex}_#{index}", apiParam, cfgInfo)
+            end
+          else
+            OutParamDef(paramData, "#{apiIndex}", apiParam, cfgInfo)
+          end
+        end
+        if cfgInfo.has_key?(:CLASS)
+          # クラスIDの取得のための処理
+          OutClassLineNumber(cfgInfo)
+          @cfg1Out.add("const signed_t #{CFG1_PREFIX}valueof_CLASS_" \
+                      "#{apiIndex} = (signed_t)(#{cfgInfo[:CLASS]});")
+        end
+        @cfg1Out.add
+      end
+    end
+  end
+end
+
+#
+#  パス1の処理
+#
+def Pass1
+  # 
+  #  タイムスタンプファイルの指定
+  # 
+  $timeStampFileName = CFG1_OUT_TIMESTAMP
+
+  #
+  #  静的APIテーブルの読み込み
+  #
+  ReadApiTableFile()
+
+  #
+  #  値取得シンボルテーブルの読み込み
+  #
+  ReadSymvalTable()
+
+  #
+  #  システムコンフィギュレーションファイルの読み込み
+  #
+  $cfgFileInfo = []
+  $dependencyFiles = $configFileNames.dup
+  $includeFiles = []
+  $domainId = { "TDOM_KERNEL" => -1, "TDOM_NONE" => -2 }
+  $configFileNames.each do |configFileName|
+    CfgParser.new.parseFile(configFileName)
+  end
+  abort if $errorFlag					# エラー発生時はabortする
+
+  #
+  #  ドメインIDの割当て処理
+  #
+  nextDomainId = 1
+  $domainId.each do |domainName, domainVal|
+    if domainVal.nil?
+      while $domainId.has_value?(nextDomainId)
+        nextDomainId += 1
+      end
+      $domainId[domainName] = nextDomainId
+      if nextDomainId > 32
+        error_exit("too large number of user domains")
+      end
+      nextDomainId += 1
+    end
+  end
+
+  #
+  #  cfg1_out.cの生成
+  #
+  Cfg1OutC::Generate()
+
+  #
+  #  依存関係の出力
+  #
+  if !$dependencyFileName.nil?
+    if $dependencyFileName == ""
+      depFile = STDOUT
+    else
+      begin
+        depFile = File.open($dependencyFileName, "w")
+      rescue Errno::ENOENT, Errno::EACCES => ex
+        abort(ex.message)
+      end
+    end
+
+    depFile.print("#{CFG1_OUT_TIMESTAMP}:")
+    $dependencyFiles.each do |fileName|
+      depFile.print(" #{fileName}")
+    end
+    depFile.puts("")
+
+    if $dependencyFileName != ""
+      depFile.close
+    end
+  end
+
+  #
+  #  パス2に引き渡す情報をファイルに生成
+  #
+  if $omitOutputDb.nil?
+    db = PStore.new(CFG1_OUT_DB)
+    db.transaction do
+      db[:apiDefinition] = $apiDefinition
+      db[:symbolValueTable] = $symbolValueTable
+      db[:cfgFileInfo] = $cfgFileInfo
+      db[:includeFiles] = $includeFiles
+      db[:domainId] = $domainId
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/pass2.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/pass2.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/cfg/pass2.rb	(revision 398)
@@ -0,0 +1,419 @@
+# -*- coding: utf-8 -*-
+#
+#  TOPPERS Configurator by Ruby
+#
+#  Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#  Copyright (C) 2015-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$
+#
+
+#
+#		パス2の処理
+#
+
+#
+#  パス1の生成物の読み込み
+#
+module Cfg1Out
+  #
+  #  Sレコードファイルからシンボルの値を取り出す
+  #
+  def self.GetSymbolValue(symbol, size, signed)
+    if @symbolAddress.has_key?(symbol)
+      return(@cfg1SRec.get_value(@symbolAddress[symbol], size, signed))
+    else
+      return(nil)
+    end
+  end
+
+  #
+  #  パス1の生成物の読み込み（メインの処理）
+  #
+  def self.Read
+    # cfg1_out.symsの読み込み
+    @symbolAddress = ReadSymbolFile(CFG1_OUT_SYMS)
+
+    # cfg1_out.srecの読み込み
+    begin
+      @cfg1SRec = SRecord.new(CFG1_OUT_SREC)
+    rescue Errno::ENOENT, Errno::EACCES => ex
+      abort(ex.message)
+    end
+
+    # マジックナンバーの取得
+    if @symbolAddress.has_key?(CFG1_MAGIC_NUM)
+      $asmLabel = ""
+      $cfg1_prefix = CFG1_PREFIX
+    elsif @symbolAddress.has_key?("_" + CFG1_MAGIC_NUM)
+      $asmLabel = "_"
+      $cfg1_prefix = "_" + CFG1_PREFIX
+    else
+      error_exit("`#{CFG1_MAGIC_NUM}' is not found in `#{CFG1_OUT_SYMS}'")
+    end
+
+    magicNumberData = @cfg1SRec.get_data(@symbolAddress \
+							[$asmLabel + CFG1_MAGIC_NUM], 4)
+    if (magicNumberData == "12345678")
+      $endianLittle = false
+    elsif (magicNumberData == "78563412")
+      $endianLittle = true
+    else
+      error_exit("`#{CFG1_MAGIC_NUM}' is invalid in `#{CFG1_OUT_SREC}'")
+    end
+
+    # 固定出力した変数の取得
+    $sizeOfSigned = GetSymbolValue($asmLabel + CFG1_SIZEOF_SIGNED, 4, false)
+
+    # 値取得シンボルの取得
+    $symbolValueTable.each do |symbolName, symbolData|
+      symbol = $cfg1_prefix + symbolName
+      if symbolData.has_key?(:BOOL)
+        value = GetSymbolValue(symbol, $sizeOfSigned, true)
+        if !value.nil?
+          # C言語の真偽値をRubyの真偽値に変換して取り込む
+          symbolData[:VALUE] = (value != 0)
+        end
+      else
+        value = GetSymbolValue(symbol, $sizeOfSigned, \
+										symbolData.has_key?(:SIGNED))
+        if !value.nil?
+          symbolData[:VALUE] = value
+        end
+      end
+    end
+
+    #
+    #  ハッシュの初期化
+    #
+    $cfgData = {}
+    @objidValues = {}
+    $apiDefinition.each do |apiName, apiDef|
+      if apiDef.has_key?(:API)
+        if !$cfgData.has_key?(apiDef[:API].to_sym)
+          $cfgData[apiDef[:API].to_sym] = {}
+        end
+      end
+      apiDef[:PARAM].each do |apiParam|
+        if apiParam.has_key?(:NAME) && apiParam.has_key?(:ID_DEF)
+          @objidValues[apiParam[:NAME]] = {}
+        end
+      end
+    end
+
+    #
+    #  ドメイン生成データをコンフィギュレーションデータ（$cfgData）に格納
+    #
+    $cfgData[:CRE_DOM] = {}
+    $domainId.each do |domainName, domainVal|
+      domid = NumStr.new(domainVal, domainName)
+      $cfgData[:CRE_DOM][domainVal] = { :domid => domid }
+    end
+
+    ReadPhase(nil)
+  end
+
+  #
+  #  パラメータの値を取り出す
+  #
+  def self.GetParamValue(paramName, param, apiIndex, index, apiParam, cfgInfo)
+    if apiParam.has_key?(:ID_DEF)				# オブジェクト識別名（定義）
+      value = @objidValues[paramName][param]
+    elsif apiParam.has_key?(:ID_REF)			# オブジェクト識別名（参照）
+      if @objidValues[paramName].has_key?(param)
+        value = @objidValues[paramName][param]
+      else
+        apiDef = $apiDefinition[cfgInfo[:APINAME]]
+        error("#{apiDef.has_key?(:KEYPAR) ? "E_NOEXS" : "E_ID"}: " \
+					"`#{param}' in #{cfgInfo[:APINAME]} is not defined", \
+					"#{cfgInfo[:_FILE_]}:#{cfgInfo[:_LINE_]}:")
+        value = nil
+      end
+    elsif apiParam.has_key?(:EXPTYPE)			# 整数定数式パラメータ
+      if apiIndex.nil?
+        if param.is_a?(NumStr)
+          return(param)
+        else
+          return(NumStr.new(param))
+        end
+      else
+        symbol = "#{$cfg1_prefix}valueof_#{paramName}_#{apiIndex}#{index}"
+        value = GetSymbolValue(symbol, $sizeOfSigned, \
+									apiParam.has_key?(:SIGNED))
+      end
+    else										# 一般定数式／文字列パラメータ
+      return(param)
+    end
+    return(NumStr.new(value, param))
+  end
+
+  #
+  #  指定したフェーズのためのパス1の生成物の読み込み
+  #
+  def self.ReadPhase(phase)
+    #
+    #  オブジェクトIDの割当て
+    #
+    # 割り当てたオブジェクトIDは，@objidValuesに保持する．@objidValuesは，
+    # 2重のハッシュ（ハッシュのハッシュ）である．
+    #
+    # 具体的には，@objidValuesは，オブジェクトIDのパラメータ名（例えば，セ
+    # マフォIDであれば"semid"．これを保持する変数名は，objidParamNameとす
+    # る）をキーとし，そのオブジェクトIDの割当て表（これを保持する変数名
+    # は，objidListとする）を値とするハッシュである．オブジェクトIDの割当
+    # て表は，オブジェクト名（これを保持する変数名は，objNameとする）をキー
+    # とし，そのID番号（これを保持する変数名は，objidNumberとする）を値と
+    # するハッシュである．
+    #
+    # 例えば，セマフォSEM1のID番号が1の場合には，次のように設定される．
+    #   @objidValues["semid"]["SEM1"] == 1
+    #
+
+    # ID番号割り当ての前処理
+    objidParamNameList = []
+    $cfgFileInfo.each do |cfgInfo|
+      # プリプロセッサディレクティブは読み飛ばす
+      next if cfgInfo.has_key?(:DIRECTIVE)
+
+      apiDef = $apiDefinition[cfgInfo[:APINAME]]
+      # 異なるフェーズの静的APIは読み飛ばす
+      next if apiDef[:PHASE] != phase
+
+      apiIndex = cfgInfo[:INDEX]
+      if !apiIndex.nil?
+        # シンボルファイルに静的APIのインデックスが存在しなければ読み飛
+        # ばす（ifdef等で消えた静的API）
+        symbol = "#{$cfg1_prefix}static_api_#{apiIndex}"
+        next unless @symbolAddress.has_key?(symbol)
+      end
+
+      apiDef[:PARAM].each do |apiParam|
+        if apiParam.has_key?(:NAME) && apiParam.has_key?(:ID_DEF)
+          objidParamName = apiParam[:NAME]
+          objName = cfgInfo[objidParamName]
+          if $inputObjid.has_key?(objName)
+            # ID番号入力ファイルに定義されていた場合
+            @objidValues[objidParamName][objName] = $inputObjid[objName]
+          else
+            @objidValues[objidParamName][objName] = nil
+          end
+          objidParamNameList.push(objidParamName)
+        end
+      end
+    end
+
+    # ID番号の割当て処理
+    objidParamNameList.each do |objidParamName|
+      objidList = @objidValues[objidParamName]
+
+      # 未使用のID番号のリスト（使用したものから消していく）
+      unusedObjidList = (1.upto(objidList.keys.size)).to_a
+
+      # 割り当て済みのID番号の処理
+      objidList.each do |objName, objidNumber|
+        if $inputObjid.has_key?(objName)
+          objidIndex = unusedObjidList.index($inputObjid[objName])
+          if objidIndex.nil?
+            # ID番号入力ファイルで指定された値が不正
+            error_exit("value of `#{objName}' in ID input file is illegal")
+          else
+            # 未使用のID番号のリストから削除
+            unusedObjidList.delete_at(objidIndex)
+          end
+        end
+      end
+
+      # ID番号の割当て
+      objidList.each do |objName, objidNumber|
+        if objidList[objName].nil?
+          # 以下で，@objidValuesを書き換えている
+          objidList[objName] = unusedObjidList.shift
+        end
+      end
+    end
+
+    #
+    #  静的APIデータをコンフィギュレーションデータ（$cfgData）に格納
+    #
+    $cfgFileInfo.each do |cfgInfo|
+      # プリプロセッサディレクティブは読み飛ばす
+      next if cfgInfo.has_key?(:DIRECTIVE)
+
+      apiDef = $apiDefinition[cfgInfo[:APINAME]]
+      # 異なるフェーズの静的APIは読み飛ばす
+      next if apiDef[:PHASE] != phase
+
+      apiSym = apiDef[:API].to_sym
+      apiIndex = cfgInfo[:INDEX]
+      if !apiIndex.nil?
+        # シンボルファイルに静的APIのインデックスが存在しなければ読み飛
+        # ばす（ifdef等で消えた静的API）
+        symbol = "#{$cfg1_prefix}static_api_#{apiIndex}"
+        next unless @symbolAddress.has_key?(symbol)
+      end
+
+      # パラメータの値をハッシュ形式に格納
+      params = {}
+      apiDef[:PARAM].each do |apiParam|
+        next unless apiParam.has_key?(:NAME)
+        paramName = apiParam[:NAME]
+        next unless cfgInfo.has_key?(paramName)		# パラメータがない場合
+        paramData = cfgInfo[paramName]
+
+        if apiParam.has_key?(:LIST)
+          params[paramName.to_sym] = []
+          paramData.each.with_index(1) do |param, index|
+            params[paramName.to_sym].push(GetParamValue(paramName, param, \
+								apiIndex, "_#{index}", apiParam, cfgInfo))
+          end
+        else
+          params[paramName.to_sym] = GetParamValue(paramName, paramData, \
+										apiIndex, "", apiParam, cfgInfo)
+        end
+      end
+
+      # ドメインIDを追加
+      if cfgInfo.has_key?(:DOMAIN)
+        domainName = cfgInfo[:DOMAIN]
+        params[:domain] = $domainId[domainName]
+      end
+
+      # クラスIDを追加
+      if cfgInfo.has_key?(:CLASS)
+        if apiIndex.nil?
+          params[:class] = cfgInfo[:CLASS]
+        else
+          symbol = "#{$cfg1_prefix}valueof_CLASS_#{apiIndex}"
+          value = GetSymbolValue(symbol, $sizeOfSigned, true)
+          params[:class] = NumStr.new(value, cfgInfo[:CLASS])
+        end
+      end
+
+      # API名，ファイル名，行番号を追加
+      params[:apiname] = cfgInfo[:APINAME]
+      params[:_file_] = cfgInfo[:_FILE_]
+      params[:_line_] = cfgInfo[:_LINE_]
+
+      # 登録キーを決定する
+      if apiDef.has_key?(:KEYPAR)
+        keyParam = params[apiDef[:KEYPAR].to_sym]
+        key = keyParam.val
+        if $cfgData[apiSym].has_key?(key)
+          # 登録キーの重複
+          error("E_OBJ: #{apiDef[:KEYPAR]} `#{keyParam}' " \
+								"is duplicated in #{cfgInfo[:APINAME]}",
+								"#{cfgInfo[:_FILE_]}:#{cfgInfo[:_LINE_]}:")
+        end
+      else
+        key = $cfgData[apiSym].count + 1
+      end
+      $cfgData[apiSym][key] = params
+    end
+  end
+
+  #
+  #  ID番号出力ファイルの生成
+  #
+  def self.OutputId(fileName)
+    idOutputFile = GenFile.new(fileName)
+    @objidValues.each do |objidParamName, objidList|
+      objidList.each do |objName, objidNumber|
+        idOutputFile.add("#{objName} #{objidNumber}")
+      end
+    end
+  end
+end
+
+#
+#  パス2の処理
+#
+def Pass2
+  #
+  #  パス1から引き渡される情報をファイルから読み込む
+  #
+  db = PStore.new(CFG1_OUT_DB)
+  db.transaction(true) do
+    $apiDefinition = db[:apiDefinition]
+    $symbolValueTable = db[:symbolValueTable]
+    $cfgFileInfo = db[:cfgFileInfo]
+    $includeFiles = db[:includeFiles]
+    $domainId = db[:domainId]
+  end
+  $cfg2Data = {}
+
+  #
+  #  パス1の生成物を読み込む
+  #
+  Cfg1Out.Read()
+  abort if $errorFlag					# エラー発生時はabortする
+
+  #
+  #  値取得シンボルをグローバル変数として定義する
+  #
+  DefineSymbolValue()
+
+  #
+  #  生成スクリプト（trbファイル）を実行する
+  #
+  $trbFileNames.each do |trbFileName|
+    if /^(.+):(\w+)$/ =~ trbFileName
+      trbFileName = $1
+      Cfg1Out.ReadPhase($2.to_sym)
+    end
+    IncludeTrb(trbFileName)
+  end
+
+  #
+  #  ID番号出力ファイルの生成
+  #
+  if !$idOutputFileName.nil?
+    Cfg1Out.OutputId($idOutputFileName)
+  end
+
+  #
+  #  パス3に引き渡す情報をファイルに生成
+  #
+  if $omitOutputDb.nil?
+    db = PStore.new(CFG2_OUT_DB)
+    db.transaction do
+      db[:apiDefinition] = $apiDefinition
+      db[:symbolValueTable] = $symbolValueTable
+      db[:cfgFileInfo] = $cfgFileInfo
+      db[:includeFiles] = $includeFiles
+      db[:cfgData] = $cfgData
+      db[:asmLabel] = $asmLabel
+      db[:endianLittle] = $endianLittle
+      db[:cfg2Data] = $cfg2Data
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/configure.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/configure.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/configure.rb	(revision 398)
@@ -0,0 +1,366 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+#
+#  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-2016 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$
+# 
+
+require "optparse"
+require "fileutils"
+require "shell"
+
+#  オプションの定義
+#
+#  -T <target>			ターゲット名（必須）
+#  -a <appldirs>		アプリケーションのディレクトリ名（複数指定可．デ
+#						フォルトはsampleディレクトリ）
+#  -A <applname>		アプリケーションプログラム名（デフォルトはsample1）
+#  -t					メインのオブジェクトファイルをリンク対象に含めない
+#  -c <cfgfile>			システムコンフィギュレーションファイル（.cfgファイ
+#						ル名）名
+#  -C <cdlflle>			コンポーネント記述ファイル（.cdlファイル）名
+#  -U <applobjs>		他のアプリケーションプログラムファイル
+#						（.oファイル名で指定．複数指定可）
+#  -S <syssvcobjs>		システムサービスのプログラムファイル
+#						（.oファイル名で指定．複数指定可）
+#  -L <kernel_lib>		カーネルライブラリ（libkernel.a）のディレクトリ名
+#						（省略した場合，カーネルライブラリもmakeする）
+#  -f					カーネルを関数単位でコンパイルするかどうかの指定
+#  -D <srcdir>			カーネルソースの置かれているディレクトリ
+#  -l <srclang>			プログラミング言語（現時点ではcとc++のみサポート）
+#  -m <tempmakefile>	Makefileのテンプレートのファイル名の指定（デフォル
+#						トはsampleディレクトリのMakefile）
+#  -d <depdir>			依存関係ファイルのディレクトリ名（デフォルトはdeps）
+#  -w					TECSを使用しない
+#  -r					トレースログ記録のサンプルコードを使用するかどうか
+#						の指定
+#  -V <devtooldir>		開発ツール（コンパイラ等）の置かれているディレクトリ
+#  -R <ruby>			rubyのパス名（明示的に指定する場合）
+#  -g <cfg>				コンフィギュレータ（cfg）のパス名
+#  -G <tecsgen>			TECSジェネレータ（tecsgen）のパス名
+#  -o <options>			コンパイルオプション（COPTSに追加）
+#  -O <options>			シンボル定義オプション（CDEFSに追加）
+#  -k <options>			リンカオプション（LDFLAGS等に追加）
+#  -e <tinetdir>		TINET のソースの置かれているディレクトリ
+#  -i <net_if>			ネットワークインタフェース（TINETが有効の場合は必須）
+#						ether、ppp、loop の何れかを指定する。
+#  -v <net_dev>			イーサネット・ディバイスドライバ
+#  						（ネットワークインタフェースに ether を指定した場合は必須）
+#  -n <net_proto>		ネットワーク層プロトコル（TINETが有効の場合は必須）
+#						inet6、inet4、inet6/inet4、inet6m、inet6m/inet4 の何れかを指定する。
+#  -s <trans_proto>		トランスポート層プロトコル（TINETが有効の場合は必須）
+#						tcp、udp、tcp/udp の何れかを指定する。
+
+#  使用例(1)
+#
+#  % ../configure.rb -T ct11mpcore_gcc -O "-DTOPPERS_USE_QEMU" \
+#					-A perf1 -a ../test -S "test_svc.o histogram.o"
+#
+#  使用例(2)
+#
+#  % ../configure.rb -T macosx_gcc -L .
+#	アプリケーションプログラムは，sample1になる．
+#
+#  使用例(3)
+#
+#  % ../configure.rb -T ct11mpcore_gcc -O "-DTOPPERS_USE_QEMU" -A tSample2 -t
+#	アプリケーションプログラムは，TECS版のサンプルプログラムになる．
+#
+#  使用例(4)
+#
+#  % ../configure.rb -T ct11mpcore_gcc PRC_NUM=4
+#	PRC_NUMを4に定義する．
+#
+#  使用例(5)
+#
+#  % ../configure.rb -T gr_sakura_gcc -A sample1n \
+#					-e tinet -i ether -v if_rx62n -n inet4 -s tcp -U sample1.o
+#	TINETを有効にする．
+
+#
+#  変数の初期化
+#
+$target = nil
+$appldirs = []
+$applobjs = []
+$syssvcobjs = []
+$kernel_lib = ""
+$kernel_funcobjs = ""
+$srclang = "c"
+$depdir = "deps"
+$omit_tecs = ""
+$enable_trace = ""
+$devtooldir = ""
+$ruby = "ruby"
+$copts = []
+$cdefs = []
+$ldflags = []
+
+#
+#  オプションの処理
+#
+OptionParser.new(nil, 22) do |opt|
+  opt.on("-T target",		"taget name (mandatory)") do |val|
+    $target = val
+  end
+  opt.on("-a appldirs",		"application directories") do |val|
+    $appldirs += val.split("\s+")
+  end
+  opt.on("-A applname",		"application program name") do |val|
+    $applname = val
+  end
+  opt.on("-t",				"TECS is used for application development") do |val|
+    $option_t = true
+  end
+  opt.on("-c cfgfile",		"system configuration file") do |val|
+    $cfgfile = val
+  end
+  opt.on("-C cdlfile",		"component description file") do |val|
+    $cdlfile = val
+  end
+  opt.on("-U applobjs",		"additional application object files") do |val|
+    $applobjs += val.split("\s+")
+  end
+  opt.on("-S syssvcobjs",	"system service object files") do |val|
+    $syssvcobjs += val.split("\s+")
+  end
+  opt.on("-L kernel_lib",	"directory of built kernel library") do |val|
+    $kernel_lib = val
+  end
+  opt.on("-f", "each function is complied separately in kernel") do |val|
+    $kernel_funcobjs = true
+  end
+  opt.on("-D srcdir",		"path of source code directory") do |val|
+    $srcdir = val
+  end
+  opt.on("-l srclang",		"programming language (C or C++)") do |val|
+    $srclang = val
+  end
+  opt.on("-m tempmakefile", "template file of Makefile") do |val|
+    $tempmakefile = val
+  end
+  opt.on("-d depdir",		"dependency relation file directory") do |val|
+    $depdir = val
+  end
+  opt.on("-w",				"TECS is not used at all") do |val|
+    $omit_tecs = true
+  end
+  opt.on("-r",				"use the sample code for trace log") do |val|
+    $enable_trace = true
+  end
+  opt.on("-V devtooldir",	"development tools directory") do |val|
+    $devtooldir = val
+  end
+  opt.on("-R ruby",			"path of ruby command") do |val|
+    $ruby = val
+  end
+  opt.on("-g cfg",			"path of configurator") do |val|
+    $cfg = val
+  end
+  opt.on("-G tecsgen",		"path of TECS generator") do |val|
+    $tecsgen = val
+  end
+  opt.on("-o options",		"compiler options") do |val|
+    $copts += val.split("\s+")
+  end
+  opt.on("-O options",		"symbol definition options") do |val|
+    $cdefs += val.split("\s+")
+  end
+  opt.on("-k options",		"linker options") do |val|
+    $ldflags += val.split("\s+")
+  end
+  opt.on("-e options",		"path of TINET directory") do |val|
+    $tinetdir = val
+  end
+  opt.on("-i options",		"network interface (ether or ppp or loop)") do |val|
+    $net_if = val
+  end
+  opt.on("-v options",		"ethernet device driver") do |val|
+    $net_dev = val
+  end
+  opt.on("-n options",		"network layer protocol (inet6 or inet4 or inet6/inet4 or inet6m or inet6m/inet4)") do |val|
+    $net_proto = val
+  end
+  opt.on("-s options",		"transeport layer protocol (tcp or udp or tcp/udp)") do |val|
+    $trans_proto = val
+  end
+  opt.parse!(ARGV)
+end
+
+#
+#  オブジェクトファイル名の拡張子を返す
+#
+def GetObjectExtension
+  if /cygwin/ =~ RUBY_PLATFORM
+    return("exe")
+  else
+    return("")
+  end
+end
+
+#
+#  変数のデフォルト値
+#
+if $appldirs.empty?
+  $appldirs.push("\$(SRCDIR)/sample")
+end
+$applname ||= "sample1"
+if $option_t.nil?
+  $applobjs.unshift($applname + ".o")
+end
+$cfgfile ||= $applname + ".cfg"
+$cdlfile ||= $applname + ".cdl"
+if $srcdir.nil?
+  # ソースディレクトリ名を取り出す
+  if /(.*)\/configure/ =~ $0
+    $srcdir = $1
+  else
+    $srcdir = Shell.new.cwd
+  end
+end
+if /^\// =~ $srcdir
+  $srcabsdir = $srcdir
+else
+  $srcabsdir = Shell.new.cwd + "/" + $srcdir
+end
+$tempmakefile ||= $srcdir + "/sample/Makefile"
+$cfg ||= $ruby + " \$(SRCDIR)/cfg/cfg.rb"
+$tecsgen ||= $ruby + " \$(SRCDIR)/tecsgen/tecsgen.rb"
+
+#
+#  -Tオプションとターゲット依存部ディレクトリの確認
+#
+if $target.nil?
+  puts("configure.rb: -T option is mandatory")
+elsif !File.directory?($srcdir + "/target/" + $target)
+  puts("configure.rb: #{$srcdir}/target/#{$target} not exist.")
+  $target = nil
+end
+
+if $target.nil?
+  puts("Installed targets are:")
+  Dir.glob($srcdir + "/target/[a-zA-Z0-9]*").each do |target|
+    target.sub!($srcdir + "/target/", "")
+    puts("\t" + target)
+  end
+  abort
+end
+
+#
+#  変数テーブルの作成
+#
+$vartable = Hash.new("")
+$vartable["TARGET"] = $target
+$vartable["APPLDIRS"] = $appldirs.join(" ")
+$vartable["APPLNAME"] = $applname
+$vartable["CFGFILE"] = $cfgfile
+$vartable["CDLFILE"] = $cdlfile
+$vartable["APPLOBJS"] = $applobjs.join(" ")
+$vartable["SYSSVCOBJS"] = $syssvcobjs.join(" ")
+$vartable["KERNEL_LIB"] = $kernel_lib
+$vartable["KERNEL_FUNCOBJS"] = $kernel_funcobjs
+$vartable["SRCDIR"] = $srcdir
+$vartable["SRCABSDIR"] = $srcabsdir
+$vartable["SRCLANG"] = $srclang
+$vartable["DEPDIR"] = $depdir
+$vartable["OMIT_TECS"] = $omit_tecs
+$vartable["ENABLE_TRACE"] = $enable_trace
+$vartable["DEVTOOLDIR"] = $devtooldir
+$vartable["RUBY"] = $ruby
+$vartable["CFG"] = $cfg
+$vartable["TECSGEN"] = $tecsgen
+$vartable["COPTS"] = $copts.join(" ")
+$vartable["CDEFS"] = $cdefs.join(" ")
+$vartable["LDFLAGS"] = $ldflags.join(" ")
+$vartable["OBJEXT"] = GetObjectExtension()
+$vartable["TINETDIR"] = $tinetdir
+$vartable["NET_IF"] = $net_if
+$vartable["NET_DEV"] = $net_dev
+$vartable["SUPPORT_INET6"] = ($net_proto == "inet6") || ($net_proto == "inet6/inet4") || ($net_proto == "inet6m") || ($net_proto == "inet6m/inet4")
+$vartable["SUPPORT_INET4"] = ($net_proto == "inet4") || ($net_proto == "inet6/inet4") || ($net_proto == "inet6m/inet4")
+$vartable["SUPPORT_TCP"] = ($trans_proto == "tcp") || ($net_proto == "tcp/udp")
+$vartable["SUPPORT_UDP"] = ($trans_proto == "udp") || ($net_proto == "tcp/udp")
+$vartable["API_CFG_IP4MAPPED_ADDR"] = ($net_proto == "inet6m") || ($net_proto == "inet6m/inet4")
+
+ARGV.each do |arg|
+  if /^([A-Za-z0-9_]+)\s*\=\s*(.*)$/ =~ arg
+    $vartable[$1] = $2
+  else
+    $vartable[arg] = true
+  end
+end
+
+#
+#  ファイルを変換する
+#
+def convert(inFileName, outFileName)
+  puts("Generating #{outFileName} from #{inFileName}.\n")
+  if (File.file?(outFileName))
+    puts("#{outFileName} exists.  Save as #{outFileName}.bak.\n")
+    FileUtils.move(outFileName, outFileName + ".bak")
+  end
+
+  begin
+    inFile = File.open(inFileName)
+    outFile = File.open(outFileName, "w")
+  rescue Errno::ENOENT, Errno::EACCES => ex
+    abort(ex.message)
+  end
+
+  inFile.each do |line|
+    line.chomp!
+    while line.sub!(/\@\(([A-Za-z0-9_]+)\)/) {|var| $vartable[$1]} do end
+    outFile.print(line,"\n")
+  end
+
+  inFile.close
+  outFile.close
+end
+
+#
+#  Makefileの生成
+#
+convert($tempmakefile, "Makefile")
+
+#
+#  依存関係ファイルのディレクトリの作成
+#
+if !File.directory?($depdir)
+  Dir.mkdir($depdir)
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/itron.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/itron.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/itron.h	(revision 398)
@@ -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-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$
+ */
+
+/*
+ *		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 size_t			SIZE;		/* メモリ領域のサイズを表す符号無し整数*/
+typedef	intptr_t		VP_INT;		/* ポインタまたは符号付き整数 */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  ITRON仕様共通定数
+ */
+#define	TRUE		true			/* 真 */
+#define	FALSE		false			/* 偽 */
+
+/*
+ *  強制待ち状態からの強制再開
+ */
+#define frsm_tsk(tskid)		rsm_tsk(tskid)
+
+/*
+ *  オブジェクト属性の定義
+ */
+#define TA_HLNG			UINT_C(0x00)	/* 高級言語用インタフェース */
+#define TA_TFIFO		UINT_C(0x00)	/* タスクの待ち行列をFIFO順に */
+#define TA_WSGL			UINT_C(0x00)	/* 待ちタスクは1つのみ */
+
+/*
+ *  ネスト回数の最大値
+ */
+#define TMAX_SUSCNT		UINT_C(1)		/* 強制待ち要求ネスト数の最大値 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_ITRON_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/kernel.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/kernel.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/kernel.h	(revision 398)
@@ -0,0 +1,694 @@
+/*
+ *  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-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$
+ */
+
+/*
+ *		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"
+
+/*
+ *  サポートする機能
+ */
+#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_CLR_INT
+#define TOPPERS_SUPPORT_CLR_INT			/* clr_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_CLR_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_RAS_INT
+#define TOPPERS_SUPPORT_RAS_INT			/* ras_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_RAS_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_PRB_INT
+#define TOPPERS_SUPPORT_PRB_INT			/* prb_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_PRB_INT */
+
+#define TOPPERS_SUPPORT_DYNAMIC_CRE		/* 動的生成機能拡張 */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  データ型の定義
+ */
+
+/*
+ *  ビットパターンやオブジェクト番号の型定義
+ */
+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	(*TMEHDR)(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 {
+	intptr_t	exinf;		/* タイムイベントハンドラの拡張情報 */
+	TMEHDR		tmehdr;		/* タイムイベントハンドラの先頭番地 */
+} T_NFY_HDR;
+
+typedef struct {
+	intptr_t	*p_var;		/* 変数の番地 */
+	intptr_t	value;		/* 設定する値 */
+} T_NFY_VAR;
+
+typedef struct {
+	intptr_t	*p_var;		/* 変数の番地 */
+} T_NFY_IVAR;
+
+typedef struct {
+	ID			tskid;		/* タスクID */
+} T_NFY_TSK;
+
+typedef struct {
+	ID			semid;		/* セマフォID */
+} T_NFY_SEM;
+
+typedef struct {
+	ID			flgid;		/* イベントフラグID */
+	FLGPTN		flgptn;		/* セットするビットパターン */
+} T_NFY_FLG;
+
+typedef struct {
+	ID			dtqid;		/* データキューID */
+	intptr_t	data;		/* 送信する値 */
+} T_NFY_DTQ;
+
+typedef struct {
+	intptr_t	*p_var;		/* 変数の番地 */
+} T_ENFY_VAR;
+
+typedef struct {
+	ID			dtqid;		/* データキューID */
+} T_ENFY_DTQ;
+
+typedef struct {
+	MODE	nfymode;			/* 通知処理モード */
+	union {						/* タイムイベントの通知に関する付随情報 */
+		T_NFY_HDR	handler;
+		T_NFY_VAR	setvar;		
+		T_NFY_IVAR	incvar;		
+		T_NFY_TSK	acttsk;
+		T_NFY_TSK	wuptsk;
+		T_NFY_SEM	sigsem;
+		T_NFY_FLG	setflg;
+		T_NFY_DTQ	snddtq;
+	} nfy;
+	union {						/* エラーの通知に関する付随情報 */
+		T_ENFY_VAR	setvar;
+		T_NFY_IVAR	incvar;		
+		T_NFY_TSK	acttsk;
+		T_NFY_TSK	wuptsk;
+		T_NFY_SEM	sigsem;
+		T_NFY_FLG	setflg;
+		T_ENFY_DTQ	snddtq;
+	} enfy;
+} T_NFYINFO;
+
+/*
+ *  パケット形式の定義
+ */
+typedef struct t_ctsk {
+	ATR			tskatr;		/* タスク属性 */
+	intptr_t	exinf;		/* タスクの拡張情報 */
+	TASK		task;		/* タスクのメインルーチンの先頭番地 */
+	PRI			itskpri;	/* タスクの起動時優先度 */
+	size_t		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;		/* 起床要求キューイング数 */
+	bool_t	raster;		/* タスク終了要求状態 */
+	bool_t	dister;		/* タスク終了禁止状態 */
+} T_RTSK;
+
+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_cmtx {
+	ATR		mtxatr;		/* ミューテックス属性 */
+	PRI		ceilpri;	/* ミューテックスの上限優先度 */
+} 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;		/* 周期通知属性 */
+	T_NFYINFO	nfyinfo;	/* 周期通知の通知方法 */
+	RELTIM		cyctim;		/* 周期通知の通知周期 */
+	RELTIM		cycphs;		/* 周期通知の通知位相 */
+} T_CCYC;
+
+typedef struct t_rcyc {
+	STAT	cycstat;	/* 周期通知の動作状態 */
+	RELTIM	lefttim;	/* 次回通知時刻までの相対時間 */
+} T_RCYC;
+
+typedef struct t_calm {
+	ATR			almatr;		/* アラーム通知属性 */
+	T_NFYINFO	nfyinfo;	/* アラーム通知の通知方法 */
+} 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_UINT	can_act(ID tskid) throw();
+extern ER		get_tst(ID tskid, STAT *p_tskstat) 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_UINT	can_wup(ID tskid) throw();
+extern ER		rel_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		ext_tsk(void) throw();
+extern ER		ras_ter(ID tskid) throw();
+extern ER		dis_ter(void) throw();
+extern ER		ena_ter(void) throw();
+extern bool_t	sns_ter(void) throw();
+extern ER		ter_tsk(ID tskid) 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		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		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		tsnd_dtq(ID dtqid, intptr_t data, TMO tmout) throw();
+extern ER		fsnd_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		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_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		set_tim(SYSTIM systim) throw();
+extern ER		get_tim(SYSTIM *p_systim) throw();
+extern ER		adj_tim(int32_t adjtim) throw();
+extern HRTCNT	fch_hrt(void) 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		stp_alm(ID almid) throw();
+extern ER		ref_alm(ID almid, T_RALM *pk_ralm) throw();
+
+/*
+ *  システム状態管理機能
+ */
+extern ER		rot_rdq(PRI tskpri) throw();
+extern ER		get_tid(ID *p_tskid) throw();
+extern ER		get_lod(PRI tskpri, uint_t *p_load) throw();
+extern ER		get_nth(PRI tskpri, uint_t nth, ID *p_tskid) throw();
+extern ER		loc_cpu(void) throw();
+extern ER		unl_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		clr_int(INTNO intno) throw();
+extern ER		ras_int(INTNO intno) throw();
+extern ER_BOOL	prb_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();
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ *  非タスクコンテキストから呼び出せるサービスコール
+ */
+#define iact_tsk(tskid)						act_tsk(tskid)
+#define iwup_tsk(tskid)						wup_tsk(tskid)
+#define irel_wai(tskid)						rel_wai(tskid)
+#define isns_ter()							sns_ter()
+#define isig_sem(semid)						sig_sem(semid)
+#define iset_flg(flgid, setptn)				set_flg(flgid, setptn)
+#define ipsnd_dtq(dtqid, data)				psnd_dtq(dtqid, data)
+#define ifsnd_dtq(dtqid, data)				fsnd_dtq(dtqid, data)
+#define ipsnd_pdq(pdqid, data, datapri)		psnd_pdq(pdqid, data, datapri)
+#define ifch_hrt()							fch_hrt()
+#define ista_alm(almid, almtim)				sta_alm(almid, almtim)
+#define istp_alm(almid)						stp_alm(almid)
+#define irot_rdq(tskpri)					rot_rdq(tskpri)
+#define iget_tid(p_tskid)					get_tid(p_tskid)
+#define iloc_cpu()							loc_cpu()
+#define iunl_cpu()							unl_cpu()
+#define isns_ctx()							sns_ctx()
+#define isns_loc()							sns_loc()
+#define isns_dsp()							sns_dsp()
+#define isns_dpn()							sns_dpn()
+#define isns_ker()							sns_ker()
+#define iext_ker()							ext_ker()
+#define idis_int(intno)						dis_int(intno)
+#define iena_int(intno)						ena_int(intno)
+#define iclr_int(intno)						clr_int(intno)
+#define iras_int(intno)						ras_int(intno)
+#define iprb_int(intno)						prb_int(intno)
+#define ixsns_dpn(p_excinf)					xsns_dpn(p_excinf)
+
+/*
+ *  オブジェクト属性の定義
+ */
+#define TA_ACT			UINT_C(0x01)	/* タスクを起動された状態で生成 */
+#define TA_NOACTQUE		UINT_C(0x02)	/* 起動要求をキューイングしない */
+
+#define TA_TPRI			UINT_C(0x01)	/* タスクの待ち行列を優先度順に */
+
+#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 TNFY_HANDLER	UINT_C(0x00)		/* タイムイベントハンドラの呼出し */
+#define TNFY_SETVAR		UINT_C(0x01)		/* 変数の設定 */
+#define TNFY_INCVAR		UINT_C(0x02)		/* 変数のインクリメント */
+#define TNFY_ACTTSK		UINT_C(0x03)		/* タスクの起動 */
+#define TNFY_WUPTSK		UINT_C(0x04)		/* タスクの起床 */
+#define TNFY_SIGSEM		UINT_C(0x05)		/* セマフォの資源の返却 */
+#define TNFY_SETFLG		UINT_C(0x06)		/* イベントフラグのセット */
+#define TNFY_SNDDTQ		UINT_C(0x07)		/* データキューへの送信 */
+
+#define TENFY_SETVAR	UINT_C(0x10)		/* 変数の設定 */
+#define TENFY_INCVAR	UINT_C(0x20)		/* 変数のインクリメント */
+#define TENFY_ACTTSK	UINT_C(0x30)		/* タスクの起動 */
+#define TENFY_WUPTSK	UINT_C(0x40)		/* タスクの起床 */
+#define TENFY_SIGSEM	UINT_C(0x50)		/* セマフォの返却 */
+#define TENFY_SETFLG	UINT_C(0x60)		/* イベントフラグのセット */
+#define TENFY_SNDDTQ	UINT_C(0x70)		/* データキューへの送信 */
+
+/*
+ *  オブジェクトの状態の定義
+ */
+#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_MTX			UINT_C(0x0080)	/* ミューテックスのロック待ち状態 */
+#define TTW_MPF			UINT_C(0x2000)	/* 固定長メモリブロックの獲得待ち */
+
+#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			/* 割込み優先度マスク全解除 */
+
+/*
+ *  構成定数とマクロ
+ */
+
+/*
+ *  優先度の範囲
+ */
+#define TMIN_TPRI		1			/* タスク優先度の最小値（最高値）*/
+#define TMAX_TPRI		16			/* タスク優先度の最大値（最低値）*/
+#define TMIN_DPRI		1			/* データ優先度の最小値（最高値）*/
+#define TMAX_DPRI		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(0xf631)	/* カーネル仕様のバージョン番号 */
+#define TKERNEL_PRVER	UINT_C(0x3020)	/* カーネルのバージョン番号 */
+
+/*
+ *  キューイング回数の最大値
+ */
+#define TMAX_ACTCNT		UINT_C(1)		/* 起動要求キューイング数の最大値 */
+#define TMAX_WUPCNT		UINT_C(1)		/* 起床要求キューイング数の最大値 */
+
+/*
+ *  ビットパターンのビット数
+ */
+#ifndef TBIT_FLGPTN					/* イベントフラグのビット数 */
+#define TBIT_FLGPTN		(sizeof(FLGPTN) * CHAR_BIT)
+#endif /* TBIT_FLGPTN */
+
+/*
+ *  システム時刻の調整できる範囲（単位：μ秒）
+ */
+#define TMIN_ADJTIM		-1000000		/* システム時刻の最小調整時間 */
+#define TMAX_ADJTIM		1000000			/* システム時刻の最大調整時間 */
+
+/*
+ *  メモリ領域確保のためのマクロ
+ *
+ *  以下の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_mbedtls/trunk/asp3_dcre/include/log_output.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/log_output.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/log_output.h	(revision 398)
@@ -0,0 +1,85 @@
+/*
+ *  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_stddef.h>
+#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_mbedtls/trunk/asp3_dcre/include/queue.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/queue.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/queue.h	(revision 398)
@@ -0,0 +1,164 @@
+/*
+ *  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
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+
+/*
+ *  キューのデータ構造の定義
+ */
+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_mbedtls/trunk/asp3_dcre/include/sil.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/sil.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/sil.h	(revision 398)
@@ -0,0 +1,284 @@
+/*
+ *  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_mbedtls/trunk/asp3_dcre/include/t_stddef.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/t_stddef.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/t_stddef.h	(revision 398)
@@ -0,0 +1,281 @@
+/*
+ *  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-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$
+ */
+
+/*
+ *		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_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	uint32_t		TMO;		/* タイムアウト指定 */
+typedef	uint32_t		RELTIM;		/* 相対時間［NGKI0550］*/
+#ifdef UINT64_MAX
+typedef	uint64_t		SYSTIM;		/* システム時刻［NGKI0548］*/
+#else /* UINT64_MAX */
+typedef	uint32_t		SYSTIM;		/* システム時刻［NGKI0548］*/
+#endif /* UINT64_MAX */
+typedef	uint32_t		PRCTIM;		/* プロセッサ時間［NGKI0573］*/
+typedef	uint32_t		HRTCNT;		/* 高分解能タイマのカウント値 */
+
+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_RASTER	(-53)		/* タスクの終了要求 */
+#define E_WBLK		(-57)		/* ノンブロッキング受付け */
+#define E_BOVR		(-58)		/* バッファオーバーフロー */
+#define E_COMM		(-65)		/* 通信エラー */
+
+/*
+ *  オブジェクト属性
+ */
+#define TA_NULL		UINT_C(0)	/* オブジェクト属性を指定しない */
+
+/*
+ *  タイムアウト指定
+ */
+#define TMO_POL		UINT_C(0)			/* ポーリング */
+#define TMO_FEVR	(UINT32_MAX)		/* 永久待ち */
+#define TMO_NBLK	(UINT32_MAX - 1)	/* ノンブロッキング */
+
+/*
+ *  アクセス許可パターン
+ */
+#define TACP_KERNEL	UINT_C(0)		/* カーネルドメインだけにアクセスを許可 */
+#define TACP_SHARED	(~UINT_C(0))	/* すべてのドメインからアクセスを許可 */
+
+/*
+ *  型に関する情報を取り出すためのマクロ
+ *
+ *  以下のALIGN_TYPEの定義は，アラインメントの単位が2の巾乗であることを
+ *  仮定している．
+ */
+#ifndef offsetof
+#define	offsetof(structure, field) \
+		((uintptr_t)(((char *) &(((structure *) 0)->field)) - ((char *) 0)))
+#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）に指定できる最大値［NGKI0551］
+ */
+#define TMAX_RELTIM		4000000000U				/* 66分40秒まで指定可 */
+
+#endif /* TOPPERS_T_STDDEF_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/t_stdlib.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/t_stdlib.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/t_stdlib.h	(revision 398)
@@ -0,0 +1,76 @@
+/*
+ *  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
+
+#include <t_stddef.h>
+
+/*
+ *  エラーメッセージ文字列を返す関数
+ *
+ *  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_mbedtls/trunk/asp3_dcre/include/t_syslog.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/t_syslog.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/include/t_syslog.h	(revision 398)
@@ -0,0 +1,342 @@
+/*
+ *  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_MACRO_ONLYを定義しておくことで，マクロ定義以外の記述を
+ *  除くことができる．
+ */
+
+#ifndef TOPPERS_T_SYSLOG_H
+#define TOPPERS_T_SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <t_stddef.h>
+
+/*
+ *  ログ情報の種別の定義
+ */
+#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_TSKSTAT	UINT_C(0x21)	/* タスク状態変化 */
+#define LOG_TYPE_DSP		UINT_C(0x31)	/* ディスパッチャ */
+#define LOG_TYPE_SVC		UINT_C(0x41)	/* サービスコール */
+
+#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
+
+/*
+ *  ログ情報のデータ構造
+ */
+
+#ifndef LOGTIM
+#define LOGTIM		HRTCNT			/* ログ時刻のデータ型 */
+#endif /* LOGTIM */
+
+#define TNUM_LOGPAR		6			/* ログパラメータの数 */
+
+#ifndef LOGPAR
+#define LOGPAR		intptr_t		/* ログパラメータのデータ型 */
+#define ULOGPAR		uintptr_t
+#endif /* LOGPAR */
+
+typedef struct {
+	uint_t	logtype;				/* ログ情報の種別 */
+	LOGTIM	logtim;					/* ログ時刻 */
+	LOGPAR	logpar[TNUM_LOGPAR];	/* ログパラメータ */
+} 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
+
+/*
+ *  ログ情報を出力するためのライブラリ関数
+ *
+ *  TECSで記述されたシステムログ機能を直接呼び出す．
+ */
+
+extern ER	tSysLog_eSysLog_write(uint_t prio, const SYSLOG *p_syslog) throw();
+
+Inline void
+_syslog_0(uint_t prio, uint_t type)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	(void) tSysLog_eSysLog_write(prio, &logbuf);
+}
+
+Inline void
+_syslog_1(uint_t prio, uint_t type, LOGPAR arg1)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.logpar[0] = arg1;
+	(void) tSysLog_eSysLog_write(prio, &logbuf);
+}
+
+Inline void
+_syslog_2(uint_t prio, uint_t type, LOGPAR arg1, LOGPAR arg2)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.logpar[0] = arg1;
+	logbuf.logpar[1] = arg2;
+	(void) tSysLog_eSysLog_write(prio, &logbuf);
+}
+
+Inline void
+_syslog_3(uint_t prio, uint_t type, LOGPAR arg1, LOGPAR arg2, LOGPAR arg3)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.logpar[0] = arg1;
+	logbuf.logpar[1] = arg2;
+	logbuf.logpar[2] = arg3;
+	(void) tSysLog_eSysLog_write(prio, &logbuf);
+}
+
+Inline void
+_syslog_4(uint_t prio, uint_t type, LOGPAR arg1, LOGPAR arg2,
+											LOGPAR arg3, LOGPAR arg4)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.logpar[0] = arg1;
+	logbuf.logpar[1] = arg2;
+	logbuf.logpar[2] = arg3;
+	logbuf.logpar[3] = arg4;
+	(void) tSysLog_eSysLog_write(prio, &logbuf);
+}
+
+Inline void
+_syslog_5(uint_t prio, uint_t type, LOGPAR arg1, LOGPAR arg2,
+								LOGPAR arg3, LOGPAR arg4, LOGPAR arg5)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.logpar[0] = arg1;
+	logbuf.logpar[1] = arg2;
+	logbuf.logpar[2] = arg3;
+	logbuf.logpar[3] = arg4;
+	logbuf.logpar[4] = arg5;
+	(void) tSysLog_eSysLog_write(prio, &logbuf);
+}
+
+Inline void
+_syslog_6(uint_t prio, uint_t type, LOGPAR arg1, LOGPAR arg2,
+					LOGPAR arg3, LOGPAR arg4, LOGPAR arg5, LOGPAR arg6)
+{
+	SYSLOG	logbuf;
+
+	logbuf.logtype = type;
+	logbuf.logpar[0] = arg1;
+	logbuf.logpar[1] = arg2;
+	logbuf.logpar[2] = arg3;
+	logbuf.logpar[3] = arg4;
+	logbuf.logpar[4] = arg5;
+	logbuf.logpar[5] = arg6;
+	(void) tSysLog_eSysLog_write(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, LOGPAR arg1)
+{
+}
+
+Inline void
+_syslog_2(uint_t prio, uint_t type, LOGPAR arg1, LOGPAR arg2)
+{
+}
+
+Inline void
+_syslog_3(uint_t prio, uint_t type, LOGPAR arg1, LOGPAR arg2, LOGPAR arg3)
+{
+}
+
+Inline void
+_syslog_4(uint_t prio, uint_t type, LOGPAR arg1, LOGPAR arg2,
+											LOGPAR arg3, LOGPAR arg4)
+{
+}
+
+Inline void
+_syslog_5(uint_t prio, uint_t type, LOGPAR arg1, LOGPAR arg2,
+								LOGPAR arg3, LOGPAR arg4, LOGPAR arg5)
+{
+}
+
+Inline void
+_syslog_6(uint_t prio, uint_t type, LOGPAR arg1, LOGPAR arg2,
+					LOGPAR arg3, LOGPAR arg4, LOGPAR arg5, LOGPAR arg6)
+{
+}
+
+Inline void
+syslog(uint_t prio, const char *format, ...)
+{
+}
+
+#endif /* TOPPERS_OMIT_SYSLOG */
+
+/*
+ *  ログ情報（コメント）を出力するためのマクロ
+ *
+ *  formatおよび後続の引数から作成したメッセージを，重大度prioでログ情
+ *  報として出力するためのマクロ．arg1～argnはLOGPAR型にキャストするた
+ *  め，LOGPAR型に型変換できる任意の型でよい．
+ */
+
+#define syslog_0(prio, format) \
+				_syslog_1(prio, LOG_TYPE_COMMENT, (LOGPAR)(format))
+
+#define syslog_1(prio, format, arg1) \
+				_syslog_2(prio, LOG_TYPE_COMMENT, (LOGPAR)(format), \
+														(LOGPAR)(arg1))
+
+#define syslog_2(prio, format, arg1, arg2) \
+				_syslog_3(prio, LOG_TYPE_COMMENT, (LOGPAR)(format), \
+										(LOGPAR)(arg1), (LOGPAR)(arg2))
+
+#define syslog_3(prio, format, arg1, arg2, arg3) \
+				_syslog_4(prio, LOG_TYPE_COMMENT, (LOGPAR)(format), \
+						(LOGPAR)(arg1), (LOGPAR)(arg2), (LOGPAR)(arg3))
+
+#define syslog_4(prio, format, arg1, arg2, arg3, arg4) \
+				_syslog_5(prio, LOG_TYPE_COMMENT, (LOGPAR)(format), \
+						(LOGPAR)(arg1), (LOGPAR)(arg2), (LOGPAR)(arg3), \
+														(LOGPAR)(arg4))
+
+#define syslog_5(prio, format, arg1, arg2, arg3, arg4, arg5) \
+				_syslog_6(prio, LOG_TYPE_COMMENT, (LOGPAR)(format), \
+						(LOGPAR)(arg1), (LOGPAR)(arg2), (LOGPAR)(arg3), \
+										(LOGPAR)(arg4), (LOGPAR)(arg5))
+
+/*
+ *  ログ情報（アサーションの失敗）を出力するためのマクロ
+ */
+#ifndef TOPPERS_assert_fail
+#define TOPPERS_assert_fail(exp, file, line) \
+				_syslog_3(LOG_EMERG, LOG_TYPE_ASSERT, (LOGPAR)(file), \
+										(LOGPAR)(line), (LOGPAR)(exp))
+#endif /* TOPPERS_assert_fail */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_T_SYSLOG_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/Makefile.kernel
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/Makefile.kernel	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/Makefile.kernel	(revision 398)
@@ -0,0 +1,142 @@
+#
+#  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-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$
+# 
+
+#
+#		カーネルのファイル構成の定義
+#
+
+#
+#  1つのソースファイルから複数のオブジェクトファイルを生成するように作
+#  成されたソースファイルのリスト
+#
+KERNEL_FCSRCS = startup.c task.c taskhook.c wait.c time_event.c \
+				task_manage.c task_refer.c task_sync.c task_term.c \
+				semaphore.c eventflag.c dataqueue.c pridataq.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 tskterm.o
+
+taskhook = mtxhook.o
+
+wait = waimake.o waicmp.o waitmo.o waitmook.o \
+		wobjwai.o wobjwaitmo.o iniwque.o
+
+time_event = tmeini.o tmeup.o tmedown.o tmecur.o tmeset.o \
+		tmereg.o tmeenq.o tmedeq.o tmechk.o tmeltim.o sigtim.o
+
+task_manage = acre_tsk.o del_tsk.o act_tsk.o can_act.o get_tst.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 can_wup.o \
+		rel_wai.o sus_tsk.o rsm_tsk.o dly_tsk.o
+
+task_term = ext_tsk.o ras_ter.o ena_ter.o dis_ter.o sns_ter.o ter_tsk.o
+
+semaphore = semini.o acre_sem.o del_sem.o sig_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 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 tsnd_dtq.o fsnd_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 tsnd_pdq.o \
+		rcv_pdq.o prcv_pdq.o trcv_pdq.o ini_pdq.o ref_pdq.o
+
+mutex = mtxini.o mtxchk.o mtxscan.o mtxdrop.o mtxacq.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 = set_tim.o get_tim.o adj_tim.o fch_hrt.o chknfy.o nfyhdr.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 stp_alm.o ref_alm.o almcal.o
+
+sys_manage = rot_rdq.o get_tid.o get_lod.o get_nth.o \
+		loc_cpu.o unl_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 clr_int.o ras_int.o prb_int.o chg_ipm.o get_ipm.o
+
+exception = excini.o xsns_dpn.o
+
+#
+#  生成されるオブジェクトファイルの依存関係の定義
+#
+$(startup) $(startup:.o=.s): startup.c
+$(task) $(task:.o=.s): task.c
+$(taskhook) $(taskhook:.o=.s): taskhook.c
+$(wait) $(wait:.o=.s): wait.c
+$(time_event) $(time_event:.o=.s): time_event.c
+$(task_manage) $(task_manage:.o=.s): task_manage.c
+$(task_refer) $(task_refer:.o=.s): task_refer.c
+$(task_sync) $(task_sync:.o=.s): task_sync.c
+$(task_term) $(task_term:.o=.s): task_term.c
+$(semaphore) $(semaphore:.o=.s): semaphore.c
+$(eventflag) $(eventflag:.o=.s): eventflag.c
+$(dataqueue) $(dataqueue:.o=.s): dataqueue.c
+$(pridataq) $(pridataq:.o=.s): pridataq.c
+$(mutex) $(mutex:.o=.s): mutex.c
+$(mempfix) $(mempfix:.o=.s): mempfix.c
+$(time_manage) $(time_manage:.o=.s): time_manage.c
+$(cyclic) $(cyclic:.o=.s): cyclic.c
+$(alarm) $(alarm:.o=.s): alarm.c
+$(sys_manage) $(sys_manage:.o=.s): sys_manage.c
+$(interrupt) $(interrupt:.o=.s): interrupt.c
+$(exception) $(exception:.o=.s): exception.c
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/alarm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/alarm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/alarm.c	(revision 398)
@@ -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-2016 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_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_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;
+		p_almcb->tmevtb.callback = (CBACK) call_alarm;
+		p_almcb->tmevtb.arg = (void *) p_almcb;
+	}
+	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);
+		p_almcb->tmevtb.callback = (CBACK) call_alarm;
+		p_almcb->tmevtb.arg = (void *) p_almcb;
+		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;
+	ATR			almatr;
+	T_NFYINFO	nfyinfo, *p_nfyinfo;
+	ER			ercd, rercd;
+
+	LOG_ACRE_ALM_ENTER(pk_calm);
+	CHECK_TSKCTX_UNL();
+
+	almatr = pk_calm->almatr;
+	nfyinfo = pk_calm->nfyinfo;
+
+	CHECK_RSATR(almatr, TA_NULL);
+	rercd = check_nfyinfo(&nfyinfo);
+	if (rercd != E_OK) {
+		ercd = rercd;
+		goto error_exit;
+	}
+
+	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 = almatr;
+		if (nfyinfo.nfymode == TNFY_HANDLER) {
+			p_alminib->exinf = nfyinfo.nfy.handler.exinf;
+			p_alminib->nfyhdr = (NFYHDR)(nfyinfo.nfy.handler.tmehdr);
+		}
+		else {
+			p_nfyinfo = &aalm_nfyinfo_table[p_alminib - aalminib_table];
+			*p_nfyinfo = nfyinfo;
+			p_alminib->exinf = (intptr_t) p_nfyinfo;
+			p_alminib->nfyhdr = notify_handler;
+		}
+		p_almcb->almsta = false;
+		ercd = ALMID(p_almcb);
+	}
+	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_ID(VALID_ALMID(almid));
+	p_almcb = get_almcb(almid);
+
+	lock_cpu();
+	if (p_almcb->p_alminib->almatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (almid <= tmax_salmid) {
+		ercd = E_OBJ;
+	}
+	else {
+		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;
+	}
+	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_UNL();
+	CHECK_ID(VALID_ALMID(almid));
+	CHECK_PAR(VALID_RELTIM(almtim));
+	p_almcb = get_almcb(almid);
+
+	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);
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_STA_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_sta_alm */
+
+/*
+ *  アラーム通知の動作停止
+ */
+#ifdef TOPPERS_stp_alm
+
+ER
+stp_alm(ID almid)
+{
+	ALMCB	*p_almcb;
+	ER		ercd;
+
+	LOG_STP_ALM_ENTER(almid);
+	CHECK_UNL();
+	CHECK_ID(VALID_ALMID(almid));
+	p_almcb = get_almcb(almid);
+
+	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;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_STP_ALM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_stp_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_ID(VALID_ALMID(almid));
+	p_almcb = get_almcb(almid);
+
+	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;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_REF_ALM_LEAVE(ercd, pk_ralm);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_alm */
+
+/*
+ *  アラーム通知起動ルーチン
+ */
+#ifdef TOPPERS_almcal
+
+void
+call_alarm(ALMCB *p_almcb)
+{
+	/*
+	 *  アラーム通知を停止状態にする．
+	 */
+	p_almcb->almsta = false;
+
+	/*
+	 *  通知ハンドラを，CPUロック解除状態で呼び出す．
+	 */
+	unlock_cpu();
+
+	LOG_ALM_ENTER(p_almcb);
+	(*(p_almcb->p_alminib->nfyhdr))(p_almcb->p_alminib->exinf);
+	LOG_ALM_LEAVE(p_almcb);
+
+	if (!sense_lock()) {
+		lock_cpu();
+	}
+}
+
+#endif /* TOPPERS_almcal */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/alarm.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/alarm.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/alarm.h	(revision 398)
@@ -0,0 +1,114 @@
+/*
+ *  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$
+ */
+
+/*
+ *		アラーム通知機能
+ */
+
+#ifndef TOPPERS_ALARM_H
+#define TOPPERS_ALARM_H
+
+#include "kernel_impl.h"
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ *  アラーム通知初期化ブロック
+ */
+typedef struct alarm_handler_initialization_block {
+	ATR			almatr;			/* アラーム通知属性 */
+	intptr_t	exinf;			/* 通知ハンドラの拡張情報 */
+	NFYHDR		nfyhdr;			/* 通知ハンドラの起動番地 */
+} 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 T_NFYINFO	aalm_nfyinfo_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_alarm(ALMCB *p_almcb);
+
+#endif /* TOPPERS_ALARM_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/alarm.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/alarm.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/alarm.trb	(revision 398)
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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$
+# 
+
+#
+#		アラーム通知機能の生成スクリプト
+#
+
+class AlarmObject < KernelObject
+  def initialize()
+    super("alm", "alarm")
+    @inibList["T_NFYINFO"] = "aalm_nfyinfo_table"
+  end
+
+  def prepare(key, params)
+    # almatrが無効の場合（E_RSATR）［NGKI2491］
+    #（TA_STA以外のビットがセットされている場合）
+    if (params[:almatr] & ~($TA_STA)) != 0
+      error_illegal_id("E_RSATR", params, :almatr, :almid)
+    end
+
+    # 通知情報の処理
+    params[:nfyhdr] = generateNotifyHandler(key, params, :almid)
+  end
+
+  def generateInib(key, params)
+    return("(#{params[:almatr]}), (intptr_t)(#{params[:par1]}), " \
+												"#{params[:nfyhdr]}")
+  end
+end
+
+#
+#  アラーム通知に関する情報の生成
+#
+$kernelCfgC.comment_header("Alarm Notification Functions")
+AlarmObject.new.generate()
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/allfunc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/allfunc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/allfunc.h	(revision 398)
@@ -0,0 +1,269 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  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$
+ */
+
+/*
+ *		すべての関数をコンパイルするための定義
+ */
+
+#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_tskterm
+
+/* taskhook.c */
+#define TOPPERS_mtxhook
+
+/* wait.c */
+#define TOPPERS_waimake
+#define TOPPERS_waicmp
+#define TOPPERS_waitmo
+#define TOPPERS_waitmook
+#define TOPPERS_wobjwai
+#define TOPPERS_wobjwaitmo
+#define TOPPERS_iniwque
+
+/* time_event.c */
+#define TOPPERS_tmeini
+#define TOPPERS_tmeup
+#define TOPPERS_tmedown
+#define TOPPERS_tmecur
+#define TOPPERS_tmeset
+#define TOPPERS_tmereg
+#define TOPPERS_tmeenq
+#define TOPPERS_tmedeq
+#define TOPPERS_tmechk
+#define TOPPERS_tmeltim
+#define TOPPERS_sigtim
+
+/* task_manage.c */
+#define TOPPERS_acre_tsk
+#define TOPPERS_del_tsk
+#define TOPPERS_act_tsk
+#define TOPPERS_can_act
+#define TOPPERS_get_tst
+#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_can_wup
+#define TOPPERS_rel_wai
+#define TOPPERS_sus_tsk
+#define TOPPERS_rsm_tsk
+#define TOPPERS_dly_tsk
+
+/* task_term.c */
+#define TOPPERS_ext_tsk
+#define TOPPERS_ras_ter
+#define TOPPERS_dis_ter
+#define TOPPERS_ena_ter
+#define TOPPERS_sns_ter
+#define TOPPERS_ter_tsk
+
+/* semaphore.c */
+#define TOPPERS_semini
+#define TOPPERS_acre_sem
+#define TOPPERS_del_sem
+#define TOPPERS_sig_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_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_tsnd_dtq
+#define TOPPERS_fsnd_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_tsnd_pdq
+#define TOPPERS_rcv_pdq
+#define TOPPERS_prcv_pdq
+#define TOPPERS_trcv_pdq
+#define TOPPERS_ini_pdq
+#define TOPPERS_ref_pdq
+
+/* mutex.c */
+#define TOPPERS_mtxini
+#define TOPPERS_mtxchk
+#define TOPPERS_mtxscan
+#define TOPPERS_mtxdrop
+#define TOPPERS_mtxacq
+#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_set_tim
+#define TOPPERS_get_tim
+#define TOPPERS_adj_tim
+#define TOPPERS_fch_hrt
+#define TOPPERS_chknfy
+#define TOPPERS_nfyhdr
+
+/* 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_stp_alm
+#define TOPPERS_ref_alm
+#define TOPPERS_almcal
+
+/* sys_manage.c */
+#define TOPPERS_rot_rdq
+#define TOPPERS_get_tid
+#define TOPPERS_get_lod
+#define TOPPERS_get_nth
+#define TOPPERS_loc_cpu
+#define TOPPERS_unl_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_clr_int
+#define TOPPERS_ras_int
+#define TOPPERS_prb_int
+#define TOPPERS_chg_ipm
+#define TOPPERS_get_ipm
+
+/* exception.c */
+#define TOPPERS_excini
+#define TOPPERS_xsns_dpn
+
+#endif /* TOPPERS_ALLFUNC_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/check.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/check.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/check.h	(revision 398)
@@ -0,0 +1,259 @@
+/*
+ *  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$
+ */
+
+/*
+ *		エラーチェック用マクロ
+ */
+
+#ifndef TOPPERS_CHECK_H
+#define TOPPERS_CHECK_H
+
+#include "kernel_impl.h"
+
+/*
+ *  オブジェクト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_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)
+
+/*
+ *  オブジェクト番号の範囲の判定
+ */
+#ifndef VALID_INTNO_DISINT
+#define VALID_INTNO_DISINT(intno)    VALID_INTNO(intno)
+#endif /* VALID_INTNO_DISINT */
+
+#ifndef VALID_INTNO_CREISR
+#define VALID_INTNO_CREISR(intno)    VALID_INTNO(intno)
+#endif /* VALID_INTNO_CREISR */
+
+/*
+ *  優先度の範囲の判定
+ */
+#define VALID_TPRI(tpri)	(TMIN_TPRI <= (tpri) && (tpri) <= TMAX_TPRI)
+
+#define VALID_DPRI(dpri)	(TMIN_DPRI <= (dpri) && (dpri) <= TMAX_DPRI)
+
+#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 */
+
+/*
+ *  相対時間の範囲の判定
+ */
+#define VALID_RELTIM(reltim)	((reltim) <= TMAX_RELTIM)
+
+/*
+ *  タイムアウト指定値の範囲の判定
+ */
+#define VALID_TMOUT(tmout)	((tmout) <= TMAX_RELTIM || (tmout) == TMO_FEVR \
+													|| (tmout) == TMO_POL)
+
+/*
+ *  アラインしているかの判定
+ */
+#define ALIGNED(val, align)		((((uintptr_t)(val)) & ((align) - 1U)) == 0U)
+
+#ifdef CHECK_STKSZ_ALIGN
+#define STKSZ_ALIGN(stksz)		ALIGNED(stksz, CHECK_STKSZ_ALIGN)
+#else /* CHECK_STKSZ_ALIGN */
+#define STKSZ_ALIGN(stksz)		true
+#endif /* CHECK_STKSZ_ALIGN */
+
+#ifdef CHECK_INTPTR_ALIGN
+#define INTPTR_ALIGN(p_var)		ALIGNED(p_var, CHECK_INTPTR_ALIGN)
+#else /* CHECK_INTPTR_ALIGN */
+#define INTPTR_ALIGN(p_var)		true
+#endif /* CHECK_INTPTR_ALIGN */
+
+#ifdef CHECK_FUNC_ALIGN
+#define FUNC_ALIGN(func)		ALIGNED(func, CHECK_FUNC_ALIGN)
+#else /* CHECK_FUNC_ALIGN */
+#define FUNC_ALIGN(func)		true
+#endif /* CHECK_FUNC_ALIGN */
+
+#ifdef CHECK_STACK_ALIGN
+#define STACK_ALIGN(stack)		ALIGNED(stack, CHECK_STACK_ALIGN)
+#else /* CHECK_STACK_ALIGN */
+#define STACK_ALIGN(stack)		true
+#endif /* CHECK_STACK_ALIGN */
+
+#ifdef CHECK_MPF_ALIGN
+#define MPF_ALIGN(mpf)			ALIGNED(mpf, CHECK_MPF_ALIGN)
+#else /* CHECK_MPF_ALIGN */
+#define MPF_ALIGN(mpf)			true
+#endif /* CHECK_MPF_ALIGN */
+
+#ifdef CHECK_MB_ALIGN
+#define MB_ALIGN(mb)			ALIGNED(mb, CHECK_MB_ALIGN)
+#else /* CHECK_MB_ALIGN */
+#define MB_ALIGN(mb)			true
+#endif /* CHECK_MB_ALIGN */
+
+/*
+ *  NULLでないことの判定
+ */
+#ifdef CHECK_INTPTR_NONNULL
+#define INTPTR_NONNULL(p_var)	((p_var) != NULL)
+#else /* CHECK_INTPTR_NONNULL */
+#define INTPTR_NONNULL(p_var)	true
+#endif /* CHECK_INTPTR_NONNULL */
+
+#ifdef CHECK_FUNC_NONNULL
+#define FUNC_NONNULL(func)		((func) != NULL)
+#else /* CHECK_FUNC_NONNULL */
+#define FUNC_NONNULL(func)		true
+#endif /* CHECK_FUNC_NONNULL */
+
+/*
+ *  呼出しコンテキストのチェック（E_CTX）
+ */
+#define CHECK_TSKCTX() do {									\
+	if (sense_context()) {									\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  CPUロック状態のチェック（E_CTX）
+ */
+#define CHECK_UNL() do {									\
+	if (sense_lock()) {										\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  呼出しコンテキストとCPUロック状態のチェック（E_CTX）
+ */
+#define CHECK_TSKCTX_UNL() do {								\
+	if (sense_context() || sense_lock()) {					\
+		ercd = E_CTX;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  ディスパッチ保留状態でないかのチェック（E_CTX）
+ */
+#define CHECK_DISPATCH() do {								\
+	if (sense_context() || 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)
+
+/*
+ *  オブジェクトIDのチェック（E_ID）
+ */
+#define CHECK_ID(exp) do {									\
+	if (!(exp)) {											\
+		ercd = E_ID;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  予約属性エラーのチェック（E_RSATR）
+ */
+#define CHECK_RSATR(atr, valid_atr) do {					\
+	if (((atr) & ~(valid_atr)) != 0U) {						\
+		ercd = E_RSATR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  パラメータエラーのチェック（E_PAR）
+ */
+#define CHECK_PAR(exp) do {									\
+	if (!(exp)) {											\
+		ercd = E_PAR;										\
+		goto error_exit;									\
+	}														\
+} while (false)
+
+/*
+ *  不正使用エラーのチェック（E_ILUSE）
+ */
+#define CHECK_ILUSE(exp) do {								\
+	if (!(exp)) {											\
+		ercd = E_ILUSE;										\
+		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_mbedtls/trunk/asp3_dcre/kernel/cyclic.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/cyclic.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/cyclic.c	(revision 398)
@@ -0,0 +1,428 @@
+/*
+ *  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-2016 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)]))
+
+#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]);
+		p_cyccb->tmevtb.callback = (CBACK) call_cyclic;
+		p_cyccb->tmevtb.arg = (void *) p_cyccb;
+		if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
+			/*
+			 *  初回の起動のためのタイムイベントを登録する［ASPD1035］
+			 *  ［ASPD1062］．
+			 */
+			p_cyccb->cycsta = true;
+			p_cyccb->tmevtb.evttim = (EVTTIM)(p_cyccb->p_cycinib->cycphs);
+			tmevtb_register(&(p_cyccb->tmevtb));
+		}
+		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);
+		p_cyccb->tmevtb.callback = (CBACK) call_cyclic;
+		p_cyccb->tmevtb.arg = (void *) p_cyccb;
+		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;
+	ATR			cycatr;
+	T_NFYINFO	nfyinfo, *p_nfyinfo;
+	RELTIM		cyctim;
+	RELTIM		cycphs;
+	ER			ercd, rercd;
+
+	LOG_ACRE_CYC_ENTER(pk_ccyc);
+	CHECK_TSKCTX_UNL();
+
+	cycatr = pk_ccyc->cycatr;
+	nfyinfo = pk_ccyc->nfyinfo;
+	cyctim = pk_ccyc->cyctim;
+	cycphs = pk_ccyc->cycphs;
+
+	CHECK_RSATR(cycatr, TA_STA);
+	rercd = check_nfyinfo(&nfyinfo);
+	if (rercd != E_OK) {
+		ercd = rercd;
+		goto error_exit;
+	}
+	CHECK_PAR(0 < cyctim && cyctim <= TMAX_RELTIM);
+	CHECK_PAR(0 <= cycphs && cycphs <= TMAX_RELTIM);
+
+	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 = cycatr;
+		if (nfyinfo.nfymode == TNFY_HANDLER) {
+			p_cycinib->exinf = nfyinfo.nfy.handler.exinf;
+			p_cycinib->nfyhdr = (NFYHDR)(nfyinfo.nfy.handler.tmehdr);
+		}
+		else {
+			p_nfyinfo = &acyc_nfyinfo_table[p_cycinib - acycinib_table];
+			*p_nfyinfo = nfyinfo;
+			p_cycinib->exinf = (intptr_t) p_nfyinfo;
+			p_cycinib->nfyhdr = notify_handler;
+		}
+		p_cycinib->cyctim = cyctim;
+		p_cycinib->cycphs = cycphs;
+
+		if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
+			p_cyccb->cycsta = true;
+			tmevtb_enqueue(&(p_cyccb->tmevtb), p_cyccb->p_cycinib->cycphs);
+		}
+		else {
+			p_cyccb->cycsta = false;
+		}
+		ercd = CYCID(p_cyccb);
+	}
+	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_ID(VALID_CYCID(cycid));
+	p_cyccb = get_cyccb(cycid);
+
+	lock_cpu();
+	if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (cycid <= tmax_scycid) {
+		ercd = E_OBJ;
+	}
+	else {
+		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;
+	}
+	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_ID(VALID_CYCID(cycid));
+	p_cyccb = get_cyccb(cycid);
+
+	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;
+		}
+		/*
+		 *  初回の起動のためのタイムイベントを登録する［ASPD1036］．
+		 */
+		tmevtb_enqueue(&(p_cyccb->tmevtb), p_cyccb->p_cycinib->cycphs);
+		ercd = E_OK;
+	}
+	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_ID(VALID_CYCID(cycid));
+	p_cyccb = get_cyccb(cycid);
+
+	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;
+	}
+	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_ID(VALID_CYCID(cycid));
+	p_cyccb = get_cyccb(cycid);
+
+	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;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_REF_CYC_LEAVE(ercd, pk_rcyc);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_cyc */
+
+/*
+ *  周期通知起動ルーチン
+ */
+#ifdef TOPPERS_cyccal
+
+void
+call_cyclic(CYCCB *p_cyccb)
+{
+	/*
+	 *  次回の起動のためのタイムイベントを登録する［ASPD1037］．
+	 */
+	p_cyccb->tmevtb.evttim += p_cyccb->p_cycinib->cyctim;	/*［ASPD1038］*/
+	tmevtb_register(&(p_cyccb->tmevtb));
+
+	/*
+	 *  通知ハンドラを，CPUロック解除状態で呼び出す．
+	 */
+	unlock_cpu();
+
+	LOG_CYC_ENTER(p_cyccb);
+	(*(p_cyccb->p_cycinib->nfyhdr))(p_cyccb->p_cycinib->exinf);
+	LOG_CYC_LEAVE(p_cyccb);
+
+	if (!sense_lock()) {
+		lock_cpu();
+	}
+}
+
+#endif /* TOPPERS_cyccal */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/cyclic.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/cyclic.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/cyclic.h	(revision 398)
@@ -0,0 +1,119 @@
+/*
+ *  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$
+ */
+
+/*
+ *		周期通知機能
+ */
+
+#ifndef TOPPERS_CYCLIC_H
+#define TOPPERS_CYCLIC_H
+
+#include "kernel_impl.h"
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ *  周期通知初期化ブロック
+ */
+typedef struct cyclic_handler_initialization_block {
+	ATR			cycatr;			/* 周期通知属性 */
+	intptr_t	exinf;			/* 通知ハンドラの拡張情報 */
+	NFYHDR		nfyhdr;			/* 通知ハンドラの起動番地 */
+	RELTIM		cyctim;			/* 周期通知の起動周期 */
+	RELTIM		cycphs;			/* 周期通知の起動位相 */
+} CYCINIB;
+
+/*
+ *  周期通知管理ブロック
+ *
+ *	次に周期通知を起動する時刻は，タイムイベントブロック（tmevtb）中の
+ *	タイムイベントの発生時刻（evttim）で保持する．
+ */
+typedef struct cyclic_handler_control_block {
+	const CYCINIB *p_cycinib;	/* 初期化ブロックへのポインタ */
+	bool_t		cycsta;			/* 周期通知の動作状態 */
+	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 T_NFYINFO	acyc_nfyinfo_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_cyclic(CYCCB *p_cyccb);
+
+#endif /* TOPPERS_CYCLIC_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/cyclic.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/cyclic.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/cyclic.trb	(revision 398)
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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$
+# 
+
+#
+#		周期通知機能の生成スクリプト
+#
+
+class CyclicObject < KernelObject
+  def initialize()
+    super("cyc", "cyclic")
+    @inibList["T_NFYINFO"] = "acyc_nfyinfo_table"
+  end
+
+  def prepare(key, params)
+    # cycatrが無効の場合（E_RSATR）［NGKI2383］
+    #（TA_STA以外のビットがセットされている場合）
+    if (params[:cycatr] & ~($TA_STA)) != 0
+      error_illegal_id("E_RSATR", params, :cycatr, :cycid)
+    end
+
+    # (0 < cyctim && cyctim <= TMAX_RELTIM)でない場合（E_PAR）［NGKI2397］
+    if !(0 < params[:cyctim] && params[:cyctim] <= $TMAX_RELTIM)
+      error_illegal_id("E_PAR", params, :cyctim, :cycid)
+    end
+
+    # (0 <= cycphs && cycphs <= TMAX_RELTIM)でない場合（E_PAR）［NGKI2399］
+    if !(0 <= params[:cycphs] && params[:cycphs] <= $TMAX_RELTIM)
+      error_illegal_id("E_PAR", params, :cycphs, :cycid)
+    end
+
+    # 通知情報の処理
+    params[:nfyhdr] = generateNotifyHandler(key, params, :cycid)
+  end
+
+  def generateInib(key, params)
+    return("(#{params[:cycatr]}), (intptr_t)(#{params[:par1]}), " \
+			"#{params[:nfyhdr]}, (#{params[:cyctim]}), (#{params[:cycphs]})")
+  end
+end
+
+#
+#  周期通知に関する情報の生成
+#
+$kernelCfgC.comment_header("Cyclic Notification Functions")
+CyclicObject.new.generate()
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/dataqueue.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/dataqueue.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/dataqueue.c	(revision 398)
@@ -0,0 +1,846 @@
+/*
+ *  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_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_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, p_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, p_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, p_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)
+{
+	TCB		*p_tcb;
+
+	if (!queue_empty(&(p_dtqcb->rwait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->rwait_queue));
+		((WINFO_RDTQ *)(p_tcb->p_winfo))->data = data;
+		wait_complete(p_tcb);
+		return(true);
+	}
+	else if (p_dtqcb->count < p_dtqcb->p_dtqinib->dtqcnt) {
+		enqueue_data(p_dtqcb, data);
+		return(true);
+	}
+	else {
+		return(false);
+	}
+}
+
+#endif /* TOPPERS_dtqsnd */
+
+/*
+ *  データキューへのデータ強制送信
+ */
+#ifdef TOPPERS_dtqfsnd
+
+void
+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_RDTQ *)(p_tcb->p_winfo))->data = data;
+		wait_complete(p_tcb);
+	}
+	else {
+		force_enqueue_data(p_dtqcb, data);
+	}
+}
+
+#endif /* TOPPERS_dtqfsnd */
+
+/*
+ *  データキューからのデータ受信
+ */
+#ifdef TOPPERS_dtqrcv
+
+bool_t
+receive_data(DTQCB *p_dtqcb, intptr_t *p_data)
+{
+	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_SDTQ *)(p_tcb->p_winfo))->data;
+			enqueue_data(p_dtqcb, data);
+			wait_complete(p_tcb);
+		}
+		return(true);
+	}
+	else if (!queue_empty(&(p_dtqcb->swait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->swait_queue));
+		*p_data = ((WINFO_SDTQ *)(p_tcb->p_winfo))->data;
+		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;
+	uint_t		dtqcnt;
+	DTQMB		*p_dtqmb;
+	ER			ercd;
+
+	LOG_ACRE_DTQ_ENTER(pk_cdtq);
+	CHECK_TSKCTX_UNL();
+
+	dtqatr = pk_cdtq->dtqatr;
+	dtqcnt = pk_cdtq->dtqcnt;
+	p_dtqmb = pk_cdtq->dtqmb;
+
+	CHECK_RSATR(dtqatr, TA_TPRI);
+
+	lock_cpu();
+	if (tnum_dtq == 0 || queue_empty(&free_dtqcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (dtqcnt != 0 && p_dtqmb == NULL) {
+			p_dtqmb = kernel_malloc(sizeof(DTQMB) * dtqcnt);
+			dtqatr |= TA_MBALLOC;
+		}
+		if (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 = 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);
+		}
+	}
+	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;
+	ER		ercd;
+
+	LOG_DEL_DTQ_ENTER(dtqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_PAR(VALID_DTQID(dtqid));
+	p_dtqcb = get_dtqcb(dtqid);
+
+	lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (dtqid <= tmax_sdtqid) {
+		ercd = E_OBJ;
+	}
+	else {
+		init_wait_queue(&(p_dtqcb->swait_queue));
+		init_wait_queue(&(p_dtqcb->rwait_queue));
+		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 (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_SDTQ winfo_sdtq;
+	ER		ercd;
+
+	LOG_SND_DTQ_ENTER(dtqid, data);
+	CHECK_DISPATCH();
+	CHECK_ID(VALID_DTQID(dtqid));
+	p_dtqcb = get_dtqcb(dtqid);
+
+	lock_cpu_dsp();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (send_data(p_dtqcb, data)) {
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		winfo_sdtq.data = data;
+		p_runtsk->tstat = TS_WAITING_SDTQ;
+		wobj_make_wait((WOBJCB *) p_dtqcb, (WINFO_WOBJ *) &winfo_sdtq);
+		dispatch();
+		ercd = winfo_sdtq.winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  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;
+	ER		ercd;
+
+	LOG_PSND_DTQ_ENTER(dtqid, data);
+	CHECK_UNL();
+	CHECK_ID(VALID_DTQID(dtqid));
+	p_dtqcb = get_dtqcb(dtqid);
+
+	lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (send_data(p_dtqcb, data)) {
+		if (p_runtsk != p_schedtsk) {
+			if (!sense_context()) {
+				dispatch();
+			}
+			else {
+				request_dispatch();
+			}
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_PSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_psnd_dtq */
+
+/*
+ *  データキューへの送信（タイムアウトあり）
+ */
+#ifdef TOPPERS_tsnd_dtq
+
+ER
+tsnd_dtq(ID dtqid, intptr_t data, TMO tmout)
+{
+	DTQCB	*p_dtqcb;
+	WINFO_SDTQ winfo_sdtq;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TSND_DTQ_ENTER(dtqid, data, tmout);
+	CHECK_DISPATCH();
+	CHECK_ID(VALID_DTQID(dtqid));
+	CHECK_PAR(VALID_TMOUT(tmout));
+	p_dtqcb = get_dtqcb(dtqid);
+
+	lock_cpu_dsp();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (send_data(p_dtqcb, data)) {
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		winfo_sdtq.data = data;
+		p_runtsk->tstat = TS_WAITING_SDTQ;
+		wobj_make_wait_tmout((WOBJCB *) p_dtqcb, (WINFO_WOBJ *) &winfo_sdtq,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_sdtq.winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  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_UNL();
+	CHECK_ID(VALID_DTQID(dtqid));
+	p_dtqcb = get_dtqcb(dtqid);
+
+	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 {
+		force_send_data(p_dtqcb, data);
+		if (p_runtsk != p_schedtsk) {
+			if (!sense_context()) {
+				dispatch();
+			}
+			else {
+				request_dispatch();
+			}
+		}
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_FSND_DTQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_fsnd_dtq */
+
+/*
+ *  データキューからの受信
+ */
+#ifdef TOPPERS_rcv_dtq
+
+ER
+rcv_dtq(ID dtqid, intptr_t *p_data)
+{
+	DTQCB	*p_dtqcb;
+	WINFO_RDTQ winfo_rdtq;
+	ER		ercd;
+
+	LOG_RCV_DTQ_ENTER(dtqid, p_data);
+	CHECK_DISPATCH();
+	CHECK_ID(VALID_DTQID(dtqid));
+	p_dtqcb = get_dtqcb(dtqid);
+
+	lock_cpu_dsp();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (receive_data(p_dtqcb, p_data)) {
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = TS_WAITING_RDTQ;
+		make_wait(&(winfo_rdtq.winfo));
+		queue_insert_prev(&(p_dtqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_rdtq.p_dtqcb = p_dtqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_rdtq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_rdtq.data;
+		}
+	}
+	unlock_cpu_dsp();
+
+  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;
+	ER		ercd;
+
+	LOG_PRCV_DTQ_ENTER(dtqid, p_data);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_DTQID(dtqid));
+	p_dtqcb = get_dtqcb(dtqid);
+
+	lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_data(p_dtqcb, p_data)) {
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	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_RDTQ winfo_rdtq;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout);
+	CHECK_DISPATCH();
+	CHECK_ID(VALID_DTQID(dtqid));
+	CHECK_PAR(VALID_TMOUT(tmout));
+	p_dtqcb = get_dtqcb(dtqid);
+
+	lock_cpu_dsp();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (receive_data(p_dtqcb, p_data)) {
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = TS_WAITING_RDTQ;
+		make_wait_tmout(&(winfo_rdtq.winfo), &tmevtb, tmout);
+		queue_insert_prev(&(p_dtqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_rdtq.p_dtqcb = p_dtqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_rdtq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_rdtq.data;
+		}
+	}
+	unlock_cpu_dsp();
+
+  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;
+	ER		ercd;
+    
+	LOG_INI_DTQ_ENTER(dtqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_DTQID(dtqid));
+	p_dtqcb = get_dtqcb(dtqid);
+
+	lock_cpu();
+	if (p_dtqcb->p_dtqinib->dtqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		init_wait_queue(&(p_dtqcb->swait_queue));
+		init_wait_queue(&(p_dtqcb->rwait_queue));
+		p_dtqcb->count = 0U;
+		p_dtqcb->head = 0U;
+		p_dtqcb->tail = 0U;
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_ID(VALID_DTQID(dtqid));
+	p_dtqcb = get_dtqcb(dtqid);
+
+	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;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_REF_DTQ_LEAVE(ercd, pk_rdtq);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_dtq */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/dataqueue.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/dataqueue.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/dataqueue.h	(revision 398)
@@ -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) 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_DATAQUEUE_H
+#define TOPPERS_DATAQUEUE_H
+
+#include "kernel_impl.h"
+#include <queue.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_send_waiting_information {
+	WINFO		winfo;			/* 標準の待ち情報ブロック */
+	DTQCB		*p_dtqcb;		/* 待っているデータキューの管理ブロック */
+	intptr_t	data;			/* 送信データ */
+} WINFO_SDTQ;
+
+typedef struct dataqueue_receive_waiting_information {
+	WINFO		winfo;			/* 標準の待ち情報ブロック */
+	DTQCB		*p_dtqcb;		/* 待っているデータキューの管理ブロック */
+	intptr_t	data;			/* 受信データ */
+} WINFO_RDTQ;
+
+/*
+ *  使用していないデータキュー管理ブロックのリスト
+ */
+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);
+
+/*
+ *  データキューへのデータ強制送信
+ */
+extern void	force_send_data(DTQCB *p_dtqcb, intptr_t data);
+
+/*
+ *  データキューからのデータ受信
+ */
+extern bool_t	receive_data(DTQCB *p_dtqcb, intptr_t *p_data);
+
+#endif /* TOPPERS_DATAQUEUE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/dataqueue.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/dataqueue.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/dataqueue.trb	(revision 398)
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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$
+# 
+
+#
+#		データキュー機能の生成スクリプト
+#
+
+class DataqueueObject < KernelObject
+  def initialize()
+    super("dtq", "dataqueue")
+  end
+
+  def prepare(key, params)
+    # パラメータが省略された時のデフォルト値の設定
+    params[:dtqmb] ||= "NULL"
+
+    # dtqatrが無効の場合（E_RSATR）［NGKI1669］
+    #（TA_TPRI以外のビットがセットされている場合）
+    if (params[:dtqatr] & ~($TA_TPRI)) != 0
+      error_illegal_id("E_RSATR", params, :dtqatr, :dtqid)
+    end
+
+    # dtqmbがNULLでない場合（E_NOSPT）［ASPS0132］
+    if params[:dtqmb] != "NULL"
+      error_illegal_id("E_NOSPT", params, :dtqmb, :dtqid)
+    end
+
+    # データキュー管理領域
+    if params[:dtqcnt] > 0
+      dtqmbName = "_kernel_dtqmb_#{params[:dtqid]}"
+      $kernelCfgC.add("static DTQMB #{dtqmbName}[#{params[:dtqcnt]}];")
+      params[:dtqinib_dtqmb] = dtqmbName
+    else
+      params[:dtqinib_dtqmb] = "NULL"
+    end
+  end
+
+  def generateInib(key, params)
+    return("(#{params[:dtqatr]}), (#{params[:dtqcnt]}), " \
+										"#{params[:dtqinib_dtqmb]}")
+  end
+end
+
+#
+#  データキューに関する情報の生成
+#
+$kernelCfgC.comment_header("Dataqueue Functions")
+DataqueueObject.new.generate()
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/eventflag.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/eventflag.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/eventflag.c	(revision 398)
@@ -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) 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 "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_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, p_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, p_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, p_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 */
+
+/*
+ *  イベントフラグの生成
+ *
+ *  pk_cflg->iflgptnは，エラーチェックをせず，一度しか参照しないため，
+ *  ローカル変数にコピーする必要がない（途中で書き換わっても支障がな
+ *  い）．
+ */
+#ifdef TOPPERS_acre_flg
+
+ER_UINT
+acre_flg(const T_CFLG *pk_cflg)
+{
+	FLGCB	*p_flgcb;
+	FLGINIB	*p_flginib;
+	ATR		flgatr;
+	ER		ercd;
+
+	LOG_ACRE_FLG_ENTER(pk_cflg);
+	CHECK_TSKCTX_UNL();
+
+	flgatr = pk_cflg->flgatr;
+
+	CHECK_RSATR(flgatr, TA_TPRI|TA_WMUL|TA_CLR);
+
+	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 = 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);
+	}
+	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;
+	ER		ercd;
+
+	LOG_DEL_FLG_ENTER(flgid);
+	CHECK_TSKCTX_UNL();
+	CHECK_PAR(VALID_FLGID(flgid));
+	p_flgcb = get_flgcb(flgid);
+
+	lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (flgid <= tmax_sflgid) {
+		ercd = E_OBJ;
+	}
+	else {
+		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 (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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;
+	ER		ercd;
+
+	LOG_SET_FLG_ENTER(flgid, setptn);
+	CHECK_UNL();
+	CHECK_ID(VALID_FLGID(flgid));
+	p_flgcb = get_flgcb(flgid);
+
+	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->waiptn))) {
+				queue_delete(&(p_tcb->task_queue));
+				wait_complete(p_tcb);
+				if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
+					break;
+				}
+			}
+		}
+		if (p_runtsk != p_schedtsk) {
+			if (!sense_context()) {
+				dispatch();
+			}
+			else {
+				request_dispatch();
+			}
+		}
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_SET_FLG_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_set_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_ID(VALID_FLGID(flgid));
+	p_flgcb = get_flgcb(flgid);
+
+	lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		p_flgcb->flgptn &= clrptn; 
+		ercd = E_OK;
+	}
+	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_ID(VALID_FLGID(flgid));
+	CHECK_PAR(waiptn != 0U);
+	CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+	p_flgcb = get_flgcb(flgid);
+
+	lock_cpu_dsp();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	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_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.waiptn;
+		}
+	}
+	unlock_cpu_dsp();
+
+  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_ID(VALID_FLGID(flgid));
+	CHECK_PAR(waiptn != 0U);
+	CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+	p_flgcb = get_flgcb(flgid);
+
+	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;
+	}
+	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_ID(VALID_FLGID(flgid));
+	CHECK_PAR(waiptn != 0U);
+	CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+	CHECK_PAR(VALID_TMOUT(tmout));
+	p_flgcb = get_flgcb(flgid);
+
+	lock_cpu_dsp();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	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_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.waiptn;
+		}
+	}
+	unlock_cpu_dsp();
+
+  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;
+	ER		ercd;
+    
+	LOG_INI_FLG_ENTER(flgid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_FLGID(flgid));
+	p_flgcb = get_flgcb(flgid);
+
+	lock_cpu();
+	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		init_wait_queue(&(p_flgcb->wait_queue));
+		p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_ID(VALID_FLGID(flgid));
+	p_flgcb = get_flgcb(flgid);
+
+	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;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_REF_FLG_LEAVE(ercd, pk_rflg);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_flg */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/eventflag.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/eventflag.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/eventflag.h	(revision 398)
@@ -0,0 +1,134 @@
+/*
+ *  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_EVENTFLAG_H
+#define TOPPERS_EVENTFLAG_H
+
+#include "kernel_impl.h"
+#include <queue.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つのフィールドが共通になっている．
+ *
+ *  waiptnには，待ち状態の間は待ちパターンを，待ち解除された後は待ち解
+ *  除時のパターンを入れる（1つのフィールドを2つの目的に兼用している）．
+ */
+typedef struct eventflag_waiting_information {
+	WINFO		winfo;			/* 標準の待ち情報ブロック */
+	FLGCB		*p_flgcb;		/* 待っているイベントフラグの管理ブロック */
+	FLGPTN		waiptn;			/* 待ちパターン／待ち解除時のパターン */
+	MODE		wfmode;			/* 待ちモード */
+} 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_mbedtls/trunk/asp3_dcre/kernel/eventflag.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/eventflag.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/eventflag.trb	(revision 398)
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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$
+# 
+
+#
+#		イベントフラグ機能の生成スクリプト
+#
+
+class EventflagObject < KernelObject
+  def initialize()
+    super("flg", "eventflag")
+  end
+
+  def prepare(key, params)
+    # flgatrが無効の場合（E_RSATR）［NGKI1562］
+    #（TA_TPRI，TA_WMUL，TA_CLR以外のビットがセットされている場合）
+    if (params[:flgatr] & ~($TA_TPRI|$TA_WMUL|$TA_CLR)) != 0
+      error_illegal_id("E_RSATR", params, :flgatr, :flgid)
+    end
+
+    # iflgptnがFLGPTNに格納できない場合（E_PAR）［NGKI3275］
+    if (params[:iflgptn] & ~((1 << $TBIT_FLGPTN) - 1)) != 0
+      error_wrong_id("E_PAR", params, :iflgptn, :flgid, "too large")
+    end
+  end
+
+  def generateInib(key, params)
+    return("(#{params[:flgatr]}), (#{params[:iflgptn]})")
+  end
+end
+
+#
+#  イベントフラグに関する情報の生成
+#
+$kernelCfgC.comment_header("Eventflag Functions")
+EventflagObject.new.generate()
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/exception.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/exception.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/exception.c	(revision 398)
@@ -0,0 +1,107 @@
+/*
+ *  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$
+ */
+
+/*
+ *		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 */
+
+/* 
+ *  CPU例外ハンドラ管理機能の初期化
+ */
+#ifdef TOPPERS_excini
+#ifndef OMIT_INITIALIZE_EXCEPTION
+
+void
+initialize_exception(void)
+{
+	uint_t			i;
+	const EXCINIB	*p_excinib;
+
+	for (i = 0; i < tnum_def_excno; i++) {
+		p_excinib = &(excinib_table[i]);
+		define_exc(p_excinib->excno, p_excinib->exc_entry);
+	}
+}
+
+#endif /* OMIT_INITIALIZE_EXCEPTION */
+#endif /* TOPPERS_excini */
+
+/*
+ *  CPU例外の発生したコンテキストの参照
+ */
+
+/*
+ *  CPU例外発生時のディスパッチ保留状態の参照
+ *
+ *  CPU例外ハンドラ中でenadspが変化することはないため，CPU例外が発生し
+ *  た時のenadspを保存しておく必要はない．
+ */
+#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) && enadsp
+								&& p_runtsk != NULL) ? false : true;
+	LOG_XSNS_DPN_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_xsns_dpn */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/exception.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/exception.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/exception.h	(revision 398)
@@ -0,0 +1,80 @@
+/*
+ *  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
+
+#include "kernel_impl.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_def_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_mbedtls/trunk/asp3_dcre/kernel/exception.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/exception.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/exception.trb	(revision 398)
@@ -0,0 +1,110 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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例外管理機能の生成スクリプト
+#
+
+#
+#  kernel_cfg.cの生成
+#
+$kernelCfgC.comment_header("CPU Exception Management Functions")
+
+#
+#  CPU例外ハンドラに関するエラーチェック
+#
+$cfgData[:DEF_EXC].each do |key, params|
+  # excnoがCPU例外ハンドラ番号として正しくない場合（E_PAR）［NGKI3134］
+  if $EXCNO_VALID.index(params[:excno]).nil?
+    error_illegal("E_PAR", params, :excno)
+  end
+
+  # excatrが無効の場合（E_RSATR）［NGKI3131］
+  #（TARGET_EXCATR以外のビットがセットされている場合）
+  if (params[:excatr] & ~($TARGET_EXCATR)) != 0
+    error_illegal_sym("E_RSATR", params, :excatr, :excno)
+  end
+end
+
+#
+#  CPU例外ハンドラのための標準的な初期化情報の生成
+#
+if !$OMIT_INITIALIZE_EXCEPTION
+  #
+  #  定義するCPU例外ハンドラの数
+  #
+  $kernelCfgC.add(<<EOS)
+#define TNUM_DEF_EXCNO	#{$cfgData[:DEF_EXC].size}
+const uint_t _kernel_tnum_def_excno = TNUM_DEF_EXCNO;
+EOS
+
+  if $cfgData[:DEF_EXC].size != 0
+    #
+    #  CPU例外ハンドラのエントリ
+    #
+    $cfgData[:DEF_EXC].each do |key, params|
+      $kernelCfgC.add("EXCHDR_ENTRY(#{params[:excno]}, " \
+						"#{params[:excno].val}, #{params[:exchdr]})")
+    end
+    $kernelCfgC.add("")
+
+    #
+    #  CPU例外ハンドラ初期化ブロック
+    #
+    $kernelCfgC.add("const EXCINIB _kernel_excinib_table[TNUM_DEF_EXCNO] = {")
+    $cfgData[:DEF_EXC].each_with_index do |(key, params), index|
+      $kernelCfgC.add(",") if index > 0
+      $kernelCfgC.append("\t{ (#{params[:excno]}), (#{params[:excatr]}), " \
+				"(FP)(EXC_ENTRY(#{params[:excno]}, #{params[:exchdr]})) }")
+    end
+    $kernelCfgC.add
+    $kernelCfgC.add2("};")
+  else
+    $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const EXCINIB, " \
+										"_kernel_excinib_table);")
+  end
+end
+
+#
+#  CPU例外管理機能初期化関数の追加
+#
+$initializeFunctions.push("_kernel_initialize_exception();")
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/genoffset.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/genoffset.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/genoffset.trb	(revision 398)
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+# 
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2011-2016 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$
+# 
+
+#
+#		オフセットファイル生成用の生成スクリプト
+#
+
+# 
+#  タイムスタンプファイルの指定
+# 
+$timeStampFileName = "offset.timestamp"
+
+# 
+#  offset.hの先頭部分の生成
+# 
+$offsetH = GenFile.new("offset.h")
+$offsetH.add2("/* offset.h */")
+
+# 
+#  #defineディレクティブの生成
+# 
+def GenerateDefine(symbol, value)
+  $offsetH.add("#define #{symbol}\t#{value}")
+end
+
+# 
+#  ビットのサーチ
+# 
+def SearchBit(val)
+  (0..7).each do |valBit|
+    if (val & 1) != 0
+      return valBit
+    end
+    val >>= 1
+  end
+end
+
+# 
+#  ビットフィールドのオフセットとビット位置の定義の生成
+# 
+def GenerateDefineBit(label, structSize, outputSize)
+  top = SYMBOL(label)
+  if top.nil?
+    error_exit("label `#{label}' not found")
+  else
+    val = 0
+    offset = 0
+    0.upto(structSize - 1).each do |i|
+      tmpVal = PEEK(top + i, 1)
+      if tmpVal != 0
+        val = tmpVal
+        offset = i
+        break
+      end
+    end
+
+    if val == 0
+      error_exit("bit not found in `#{label}'")
+    else
+      valBit = SearchBit(val)
+      case outputSize
+      when "W"
+        if $SIL_ENDIAN_BIG
+          valBit = valBit + 24 - ((offset & 0x03) << 3)
+        else
+          valBit = valBit + ((offset & 0x03) << 3)
+        end
+        offset &= ~0x03
+      when "H"
+        if $SIL_ENDIAN_BIG
+          valBit = valBit + 8 - ((offset & 0x01) << 3)
+        else
+          valBit = valBit + ((offset & 0x01) << 3)
+        end
+        offset &= ~0x01
+      end
+    end
+
+    $offsetH.add("#define #{label}\t#{offset}")
+    $offsetH.add("#define #{label}_bit\t#{valBit}")
+    $offsetH.add("#define #{label}_mask\t#{sprintf("0x%x", 1 << valBit)}")
+  end
+end
+
+# 
+#  バイト配置のチェック
+# 
+def magicCheck(size, check)
+  label = "MAGIC_#{size}"
+  top = SYMBOL(label)
+  if top.nil?
+    error_exit("label `#{label}' not found")
+  else
+    1.upto(size).each do |offset|
+      if $SIL_ENDIAN_BIG
+        val = PEEK(top + offset - 1, 1)
+      else
+        val = PEEK(top + size - offset, 1)
+      end
+      if val != check.at(offset - 1)
+        error_exit("value check of `#{label}' failed")
+      end
+    end
+  end
+end
+
+magicCheck(1, [ 0x12 ])
+magicCheck(2, [ 0x12, 0x34 ])
+magicCheck(4, [ 0x12, 0x34, 0x56, 0x78 ])
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/interrupt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/interrupt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/interrupt.c	(revision 398)
@@ -0,0 +1,678 @@
+/*
+ *  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 "interrupt.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ISR_ENTER
+#define LOG_ISR_ENTER(isrid)
+#endif /* LOG_ISR_ENTER */
+
+#ifndef LOG_ISR_LEAVE
+#define LOG_ISR_LEAVE(isrid)
+#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_CLR_INT_ENTER
+#define LOG_CLR_INT_ENTER(intno)
+#endif /* LOG_CLR_INT_ENTER */
+
+#ifndef LOG_CLR_INT_LEAVE
+#define LOG_CLR_INT_LEAVE(ercd)
+#endif /* LOG_CLR_INT_LEAVE */
+
+#ifndef LOG_RAS_INT_ENTER
+#define LOG_RAS_INT_ENTER(intno)
+#endif /* LOG_RAS_INT_ENTER */
+
+#ifndef LOG_RAS_INT_LEAVE
+#define LOG_RAS_INT_LEAVE(ercd)
+#endif /* LOG_RAS_INT_LEAVE */
+
+#ifndef LOG_PRB_INT_ENTER
+#define LOG_PRB_INT_ENTER(intno)
+#endif /* LOG_PRB_INT_ENTER */
+
+#ifndef LOG_PRB_INT_LEAVE
+#define LOG_PRB_INT_LEAVE(ercd)
+#endif /* LOG_PRB_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, p_intpri)
+#endif /* LOG_GET_IPM_LEAVE */
+
+/*
+ *  割込み番号の範囲の判定
+ */
+#ifndef VALID_INTNO_DISINT
+#define VALID_INTNO_DISINT(intno)	VALID_INTNO(intno)
+#endif /* VALID_INTNO_DISINT */
+
+#ifndef VALID_INTNO_CLRINT
+#define VALID_INTNO_CLRINT(intno)	VALID_INTNO(intno)
+#endif /* VALID_INTNO_CLRINT */
+
+#ifndef VALID_INTNO_RASINT
+#define VALID_INTNO_RASINT(intno)	VALID_INTNO(intno)
+#endif /* VALID_INTNO_RASINT */
+
+#ifndef VALID_INTNO_PRBINT
+#define VALID_INTNO_PRBINT(intno)	VALID_INTNO(intno)
+#endif /* VALID_INTNO_PRBINT */
+
+#ifndef VALID_INTNO_CREISR
+#define VALID_INTNO_CREISR(intno)	VALID_INTNO(intno)
+#endif /* VALID_INTNO_CREISR */
+
+/*
+ *  割込み優先度の範囲の判定
+ */
+#ifndef VALID_INTPRI_CHGIPM
+#define VALID_INTPRI_CHGIPM(intpri)	\
+					(TMIN_INTPRI <= (intpri) && (intpri) <= TIPM_ENAALL)
+#endif /* VALID_INTPRI_CHGIPM */
+
+/*
+ *  割込みサービスルーチンの数
+ */
+#define tnum_isr	((uint_t)(tmax_isrid - TMIN_ISRID + 1))
+#define tnum_sisr	((uint_t)(tmax_sisrid - TMIN_ISRID + 1))
+
+/*
+ *  割込みサービスルーチンIDから割込みサービスルーチン管理ブロックを取
+ *  り出すためのマクロ
+ */
+#define INDEX_ISR(isrid)	((uint_t)((isrid) - TMIN_ISRID))
+#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++) {
+		j = INDEX_ISR(isrorder_table[i]);
+		p_isrcb = &(isrcb_table[j]);
+		p_isrcb->p_isrinib = &(isrinib_table[j]);
+		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;
+	ISRCB	*p_isrcb;
+
+	for (p_queue = p_isr_queue->p_next; p_queue != p_isr_queue;
+											p_queue = p_queue->p_next) {
+		p_isrcb = (ISRCB *) p_queue;
+		LOG_ISR_ENTER(ISRID(p_isrcb));
+		(*(p_isrcb->p_isrinib->isr))(p_isrcb->p_isrinib->exinf);
+		LOG_ISR_LEAVE(ISRID(p_isrcb));
+
+		if (p_queue->p_next != p_isr_queue) {
+			/* ISRの呼出し前の状態に戻す */
+			if (sense_lock()) {
+				unlock_cpu();
+			}
+		}
+	}
+}
+
+#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);
+	}
+}
+
+/*
+ *  割込みサービスルーチンの生成
+ *
+ *  pk_cisr->exinfは，エラーチェックをせず，一度しか参照しないため，ロー
+ *  カル変数にコピーする必要がない（途中で書き換わっても支障がない）．
+ */
+#ifdef TOPPERS_acre_isr
+
+ER_UINT
+acre_isr(const T_CISR *pk_cisr)
+{
+	ISRCB		*p_isrcb;
+	ISRINIB		*p_isrinib;
+	QUEUE		*p_isr_queue;
+	ATR			isratr;
+	INTNO		intno;
+	ISR			isr;
+	PRI			isrpri;
+	ER			ercd;
+
+	LOG_ACRE_ISR_ENTER(pk_cisr);
+	CHECK_TSKCTX_UNL();
+
+	isratr = pk_cisr->isratr;
+	intno = pk_cisr->intno;
+	isr = pk_cisr->isr;
+	isrpri = pk_cisr->isrpri;
+
+	CHECK_RSATR(isratr, TARGET_ISRATR);
+	CHECK_PAR(VALID_INTNO_CREISR(intno));
+	CHECK_PAR(FUNC_ALIGN(isr));
+	CHECK_PAR(FUNC_NONNULL(isr));
+	CHECK_PAR(VALID_ISRPRI(isrpri));
+
+	p_isr_queue = search_isr_queue(intno);
+	CHECK_OBJ(p_isr_queue != NULL);
+
+	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 = isratr;
+		p_isrinib->exinf = pk_cisr->exinf;
+		p_isrinib->p_isr_queue = p_isr_queue;
+		p_isrinib->isr = isr;
+		p_isrinib->isrpri = isrpri;
+		enqueue_isr(p_isr_queue, p_isrcb);
+		ercd = ISRID(p_isrcb);
+	}
+	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_ID(VALID_ISRID(isrid));
+	p_isrcb = get_isrcb(isrid);
+
+	lock_cpu();
+	if (p_isrcb->p_isrinib->isratr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (isrid <= tmax_sisrid) {
+		ercd = E_OBJ;
+	}
+	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;
+	}
+	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_def_inhno; i++) {
+		p_inhinib = &(inhinib_table[i]);
+		define_inh(p_inhinib->inhno, p_inhinib->int_entry);
+	}
+	for (i = 0; i < tnum_cfg_intno; i++) {
+		p_intinib = &(intinib_table[i]);
+		config_int(p_intinib->intno, p_intinib->intatr, p_intinib->intpri);
+	}
+}
+
+#endif /* OMIT_INITIALIZE_INTERRUPT */
+#endif /* TOPPERS_intini */
+
+/*
+ *  割込みの禁止［NGKI3555］
+ */
+#ifdef TOPPERS_dis_int
+#ifdef TOPPERS_SUPPORT_DIS_INT					/*［NGKI3093］*/
+
+ER
+dis_int(INTNO intno)
+{
+	bool_t	locked;
+	ER		ercd;
+
+	LOG_DIS_INT_ENTER(intno);
+	CHECK_PAR(VALID_INTNO_DISINT(intno));		/*［NGKI3083］［NGKI3087］*/
+
+	locked = sense_lock();
+	if (!locked) {
+		lock_cpu();
+	}
+	if (check_intno_cfg(intno)) {
+		disable_int(intno);						/*［NGKI3086］*/
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;							/*［NGKI3085］*/
+	}
+	if (!locked) {
+		unlock_cpu();
+	}
+
+  error_exit:
+	LOG_DIS_INT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_DIS_INT */
+#endif /* TOPPERS_dis_int */
+
+/*
+ *  割込みの許可［NGKI3556］
+ */
+#ifdef TOPPERS_ena_int
+#ifdef TOPPERS_SUPPORT_ENA_INT					/*［NGKI3106］*/
+
+ER
+ena_int(INTNO intno)
+{
+	bool_t	locked;
+	ER		ercd;
+
+	LOG_ENA_INT_ENTER(intno);
+	CHECK_PAR(VALID_INTNO_DISINT(intno));		/*［NGKI3096］［NGKI3100］*/
+
+	locked = sense_lock();
+	if (!locked) {
+		lock_cpu();
+	}
+	if (check_intno_cfg(intno)) {
+		enable_int(intno);						/*［NGKI3099］*/
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;							/*［NGKI3098］*/
+	}
+	if (!locked) {
+		unlock_cpu();
+	}
+
+  error_exit:
+	LOG_ENA_INT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_ENA_INT */
+#endif /* TOPPERS_ena_int */
+
+/*
+ *  割込み要求のクリア［NGKI3920］
+ */
+#ifdef TOPPERS_clr_int
+#ifdef TOPPERS_SUPPORT_CLR_INT					/*［NGKI3927］*/
+
+ER
+clr_int(INTNO intno)
+{
+	bool_t	locked;
+	ER		ercd;
+
+	LOG_CLR_INT_ENTER(intno);
+	CHECK_PAR(VALID_INTNO_CLRINT(intno));		/*［NGKI3921］［NGKI3930］*/
+
+	locked = sense_lock();
+	if (!locked) {
+		lock_cpu();
+	}
+	if (check_intno_cfg(intno) && check_intno_clear(intno)) {
+		clear_int(intno);						/*［NGKI3924］*/
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;							/*［NGKI3923］［NGKI3929］*/
+	}
+	if (!locked) {
+		unlock_cpu();
+	}
+
+  error_exit:
+	LOG_CLR_INT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_CLR_INT */
+#endif /* TOPPERS_clr_int */
+
+/*
+ *  割込みの要求［NGKI3932］
+ */
+#ifdef TOPPERS_ras_int
+#ifdef TOPPERS_SUPPORT_RAS_INT					/*［NGKI3939］*/
+
+ER
+ras_int(INTNO intno)
+{
+	bool_t	locked;
+	ER		ercd;
+
+	LOG_RAS_INT_ENTER(intno);
+	CHECK_PAR(VALID_INTNO_RASINT(intno));		/*［NGKI3933］［NGKI3942］*/
+
+	locked = sense_lock();
+	if (!locked) {
+		lock_cpu();
+	}
+	if (check_intno_cfg(intno) && check_intno_raise(intno)) {
+		raise_int(intno);						/*［NGKI3936］*/
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_OBJ;							/*［NGKI3935］［NGKI3941］*/
+	}
+	if (!locked) {
+		unlock_cpu();
+	}
+
+  error_exit:
+	LOG_RAS_INT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_RAS_INT */
+#endif /* TOPPERS_ras_int */
+
+/*
+ *  割込み要求のチェック［NGKI3944］
+ */
+#ifdef TOPPERS_prb_int
+#ifdef TOPPERS_SUPPORT_PRB_INT					/*［NGKI3951］*/
+
+ER_BOOL
+prb_int(INTNO intno)
+{
+	bool_t	locked;
+	ER		ercd;
+
+	LOG_PRB_INT_ENTER(intno);
+	CHECK_PAR(VALID_INTNO_PRBINT(intno));		/*［NGKI3945］［NGKI3952］*/
+
+	locked = sense_lock();
+	if (!locked) {
+		lock_cpu();
+	}
+	if (check_intno_cfg(intno)) {
+		ercd = (ER_BOOL) probe_int(intno);		/*［NGKI3948］*/
+	}
+	else {
+		ercd = E_OBJ;							/*［NGKI3947］*/
+	}
+	if (!locked) {
+		unlock_cpu();
+	}
+
+  error_exit:
+	LOG_PRB_INT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_PRB_INT */
+#endif /* TOPPERS_prb_int */
+
+/*
+ *  割込み優先度マスクの変更［NGKI3107］
+ */
+#ifdef TOPPERS_chg_ipm
+
+ER
+chg_ipm(PRI intpri)
+{
+	ER		ercd;
+
+	LOG_CHG_IPM_ENTER(intpri);
+	CHECK_TSKCTX_UNL();							/*［NGKI3108］［NGKI3109］*/
+	CHECK_PAR(VALID_INTPRI_CHGIPM(intpri));		/*［NGKI3113］［NGKI3114］*/
+
+	lock_cpu();
+	t_set_ipm(intpri);							/*［NGKI3111］*/
+	if (intpri == TIPM_ENAALL && enadsp) {
+		dspflg = true;
+		p_schedtsk = search_schedtsk();
+		if (p_runtsk->raster && p_runtsk->enater) {
+			task_terminate(p_runtsk);
+			exit_and_dispatch();
+			ercd = E_SYS;
+		}
+		else {
+			if (p_runtsk != p_schedtsk) {
+				dispatch();
+			}
+			ercd = E_OK;
+		}
+	}
+	else {
+		dspflg = false;
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_CHG_IPM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_chg_ipm */
+
+/*
+ *  割込み優先度マスクの参照［NGKI3115］
+ */
+#ifdef TOPPERS_get_ipm
+
+ER
+get_ipm(PRI *p_intpri)
+{
+	ER		ercd;
+
+	LOG_GET_IPM_ENTER(p_intpri);
+	CHECK_TSKCTX_UNL();							/*［NGKI3116］［NGKI3117］*/
+
+	lock_cpu();
+	*p_intpri = t_get_ipm();					/*［NGKI3120］*/
+	ercd = E_OK;
+	unlock_cpu();
+
+  error_exit:
+	LOG_GET_IPM_LEAVE(ercd, p_intpri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_ipm */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/interrupt.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/interrupt.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/interrupt.h	(revision 398)
@@ -0,0 +1,189 @@
+/*
+ *  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-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$
+ */
+
+/*
+ *		割込み管理機能
+ */
+
+#ifndef TOPPERS_INTERRUPT_H
+#define TOPPERS_INTERRUPT_H
+
+#include "kernel_impl.h"
+#include <queue.h>
+
+/*
+ *  割込みサービスルーチン初期化ブロック
+ */
+typedef struct isr_initialization_block {
+	ATR			isratr;			/* 割込みサービスルーチン属性 */
+	intptr_t	exinf;			/* 割込みサービスルーチンの拡張情報 */
+	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）
+ */
+extern const ID	tmax_isrid;
+extern const ID	tmax_sisrid;
+
+/*
+ *  割込みサービスルーチン初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const ISRINIB	isrinib_table[];
+extern ISRINIB			aisrinib_table[];
+
+/*
+ *  割込みサービスルーチン生成順序テーブル（kernel_cfg.c）
+ */
+extern const ID	isrorder_table[];
+
+/*
+ *  割込みサービスルーチン管理ブロックのエリア（kernel_cfg.c）
+ */
+extern ISRCB	isrcb_table[];
+
+/*
+ *  割込みサービスルーチン管理ブロックから割込みサービスルーチンIDを取
+ *  り出すためのマクロ
+ */
+#define	ISRID(p_isrcb)	((ID)(((p_isrcb) - isrcb_table) + TMIN_ISRID))
+
+/*
+ *  割込みサービスルーチン機能の初期化
+ */
+extern void initialize_isr(void);
+
+/*
+ *  割込みサービスルーチンの呼出し
+ */
+extern void call_isr(QUEUE *p_isr_queue);
+
+#if !defined(OMIT_INITIALIZE_INTERRUPT) || defined(USE_INHINIB_TABLE)
+
+/*
+ *  割込みハンドラ初期化ブロック
+ */
+typedef struct interrupt_handler_initialization_block {
+	INHNO		inhno;			/* 割込みハンドラ番号 */
+	ATR			inhatr;			/* 割込みハンドラ属性 */
+	FP			int_entry;		/* 割込みハンドラの出入口処理の番地 */
+} INHINIB;
+
+/*
+ *  定義する割込みハンドラ番号の数（kernel_cfg.c）
+ */
+extern const uint_t	tnum_def_inhno;
+
+/*
+ *  割込みハンドラ初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const INHINIB	inhinib_table[];
+
+#endif /* !defined(OMIT_INITIALIZE_INTERRUPT) || defined(USE_INHINIB_TABLE) */
+
+#if !defined(OMIT_INITIALIZE_INTERRUPT) || defined(USE_INTINIB_TABLE)
+
+/*
+ *  割込み要求ライン初期化ブロック
+ */
+typedef struct interrupt_request_initialization_block {
+	INTNO		intno;			/* 割込み番号 */
+	ATR			intatr;			/* 割込み属性 */
+	PRI			intpri;			/* 割込み優先度 */
+} INTINIB;
+
+/*
+ *  設定する割込み要求ラインの数（kernel_cfg.c）
+ */
+extern const uint_t	tnum_cfg_intno;
+
+/*
+ *  割込み要求ライン初期化ブロックのエリア（kernel_cfg.c）
+ */
+extern const INTINIB	intinib_table[];
+
+#endif /* !defined(OMIT_INITIALIZE_INTERRUPT) || defined(USE_INTINIB_TABLE) */
+
+/*
+ *  割込み管理機能の初期化
+ */
+extern void	initialize_interrupt(void);
+
+#endif /* TOPPERS_INTERRUPT_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/interrupt.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/interrupt.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/interrupt.trb	(revision 398)
@@ -0,0 +1,430 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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の生成
+#
+$kernelCfgC.comment_header("Interrupt Management Functions")
+
+#
+#  CRE_ISRで使用できる割込み番号とそれに対応する割込みハンドラ番号のデ
+#  フォルト定義
+#
+if $INTNO_CREISR_VALID.nil?
+  $INTNO_CREISR_VALID = $INTNO_VALID
+end
+if $INHNO_CREISR_VALID.nil?
+  $INHNO_CREISR_VALID = $INHNO_VALID
+end
+
+#
+#  CFG_INTで使用できる割込み優先度のデフォルト定義
+# 
+if $INTPRI_CFGINT_VALID.nil?
+  $INTPRI_CFGINT_VALID = $TMIN_INTPRI.upto($TMAX_INTPRI).to_a
+end
+
+#
+#  割込み番号と割込みハンドラ番号の変換テーブルの作成
+#
+if $INTNO_CREISR_VALID.length != $INHNO_CREISR_VALID.length
+  error_exit("length of `INTNO_CREISR_VALID' is different from" \
+									" length of `INHNO_CREISR_VALID'")
+end
+$toInhnoVal = {}
+$toIntnoVal = {}
+inhno_creisr_valid = $INHNO_CREISR_VALID.dup
+$INTNO_CREISR_VALID.each do |intnoVal|
+  inhnoVal = inhno_creisr_valid.shift
+  $toInhnoVal[intnoVal] = inhnoVal
+  $toIntnoVal[inhnoVal] = intnoVal
+end
+
+#
+#  割込み要求ラインに関するエラーチェック
+#
+$cfgData[:CFG_INT].each do |key, params|
+  #	intnoが割込み番号として正しくない場合（E_PAR）［NGKI2972］
+  if $INTNO_VALID.index(params[:intno]).nil?
+    error_illegal("E_PAR", params, :intno)
+  end
+
+  #	intatrが無効の場合（E_RSATR）［NGKI2969］
+  #（TA_ENAINT，TA_EDGE，TARGET_INTATR以外のビットがセットされている場合）
+  if (params[:intatr] & ~($TA_ENAINT|$TA_EDGE|$TARGET_INTATR)) != 0
+    error_illegal_sym("E_RSATR", params, :intatr, :intno)
+  end
+
+  #	intpriがCFG_INTに対する割込み優先度として正しくない場合（E_PAR）
+  #	［NGKI2973］
+  if $INTPRI_CFGINT_VALID.index(params[:intpri]).nil?
+    error_illegal_sym("E_OBJ", params, :intpri, :intno)
+  end
+
+  # カーネル管理外に固定されているintnoに対して，intpriにTMIN_INTPRIよ
+  #	りも小さい値が指定されなかった場合（E_OBJ）［NGKI2983］
+  if !$INTNO_FIX_NONKERNEL.nil?
+    if !$INTNO_FIX_NONKERNEL.index(params[:intno]).nil?
+      if params[:intpri] >= $TMIN_INTPRI
+        error_ercd("E_OBJ", params, "%%intno must have higher priority " \
+											"than TMIN_INTPRI in %apiname")
+      end
+    end
+  end
+
+  #	カーネル管理に固定されているintnoに対して，intpriにTMIN_INTPRIより
+  #	も小さい値が指定された場合（E_OBJ）［NGKI2984］
+  if !$INTNO_FIX_KERNEL.nil?
+    if !$INTNO_FIX_KERNEL.index(params[:intno]).nil?
+      if params[:intpri] < $TMIN_INTPRI
+        error_ercd("E_OBJ", params, "%%intno must have lower or equal " \
+									"priority to TMIN_INTPRI in %apiname")
+      end
+    end
+  end
+end
+
+#
+#  割込みハンドラに関するエラーチェック
+#
+$cfgData[:DEF_INH].each do |key, params|
+  # inhnoが割込みハンドラ番号として正しくない場合（E_PAR）［NGKI3055］
+  if $INHNO_VALID.index(params[:inhno]).nil?
+    error_illegal("E_PAR", params, :inhno)
+  end
+
+  # inhatrが無効の場合（E_RSATR）［NGKI3052］
+  #（TARGET_INHATR以外のビットがセットされている場合）
+  if (params[:inhatr] & ~($TARGET_INHATR)) != 0
+    error_illegal_sym("E_RSATR", params, :inhatr, :inhno)
+  end
+
+  #	カーネル管理外に固定されているinhnoに対して，inhatrにTA_NONKERNELが
+  #	指定されていない場合（E_RSATR）［NGKI3067］
+  if !$INHNO_FIX_NONKERNEL.nil?
+    if !$INHNO_FIX_NONKERNEL.index(params[:inhno]).nil?
+      if (params[:inhatr] & $TA_NONKERNEL) == 0
+        error_ercd("E_RSATR", params, "%%inhno must be " \
+								"non-kernel interrupt in %apiname")
+      end
+    end
+  end
+
+  #	カーネル管理に固定されているinhnoに対して，inhatrにTA_NONKERNELが指
+  #	定されている場合（E_RSATR）［NGKI3068］
+  if !$INHNO_FIX_KERNEL.nil?
+    if !$INHNO_FIX_KERNEL.index(params[:inhno]).nil?
+      if (params[:inhatr] & $TA_NONKERNEL) != 0
+        error_ercd("E_RSATR", params, "%%inhno must not be " \
+								"non-kernel interrupt in %apiname")
+      end
+    end
+  end
+
+  if $toIntnoVal.has_key?(params[:inhno].val)
+    intnoVal = $toIntnoVal[params[:inhno].val]
+
+    # inhnoに対応するintnoに対するCFG_INTがない場合（E_OBJ）［NGKI3062］
+    if !$cfgData[:CFG_INT].has_key?(intnoVal)
+      error_ercd("E_OBJ", params, "intno `#{intnoVal}' corresponding to " \
+					"%%inhno in %apiname is not configured with CFG_INT")
+    else
+      intnoParams = $cfgData[:CFG_INT][intnoVal]
+      if (params[:inhatr] & $TA_NONKERNEL) == 0
+        # inhatrにTA_NONKERNELが指定されておらず，inhnoに対応するintno
+        # に対してCFG_INTで設定された割込み優先度がTMIN_INTPRIよりも小
+        # さい場合（E_OBJ）［NGKI3065］
+        if intnoParams[:intpri] < $TMIN_INTPRI
+          error_ercd("E_OBJ", params, "intpri `#{intnoParams[:intpri]}' " \
+				"configured for %%inhno must be lower or equal to TMIN_INTPRI")
+        end
+      else
+        # inhatrにTA_NONKERNELが指定されており，inhnoに対応するintnoに
+        # 対してCFG_INTで設定された割込み優先度がTMIN_INTPRI以上である
+        # 場合（E_OBJ）［NGKI3066］
+        if intnoParams[:intpri] >= $TMIN_INTPRI
+          error_ercd("E_OBJ", params, "intpri `#{intnoParams[:intpri]}' " \
+					"configured for %%inhno must be higher than TMIN_INTPRI")
+        end
+      end
+    end
+  end
+end
+
+#
+#  割込みサービスルーチン（ISR）に関するエラーチェック
+#
+$cfgData[:CRE_ISR].sort.each do |key, params|
+  #	isratrが無効の場合（E_RSATR）［NGKI2998］
+  #（TARGET_ISRATR以外のビットがセットされている場合）
+  if (params[:isratr] & ~($TARGET_ISRATR)) != 0
+    error_illegal("E_RSATR", params, "isratr")
+  end
+
+  #	intnoがCRE_ISRに対する割込み番号として正しくない場合（E_PAR）
+  #	［NGKI3003］
+  if $INTNO_CREISR_VALID.index(params[:intno]).nil?
+    error_illegal("E_PAR", params, "intno")
+  end
+
+  #	(TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合（E_PAR）
+  #	［NGKI3005］
+  if !($TMIN_ISRPRI <= params[:isrpri] && params[:isrpri] <= $TMAX_ISRPRI)
+    error_illegal("E_PAR", params, "isrpri")
+  end
+end
+
+$INTNO_CREISR_VALID.each do |intnoVal|
+  # 割込み番号intnoに対して登録されたISRのリストの作成
+  isrParamsList = []
+  $cfgData[:CRE_ISR].sort.each do |key, params|
+    if params[:intno] == intnoVal
+      isrParamsList.push(params)
+    end
+  end
+
+  #	割込み番号intnoに対して登録されたISRが存在する場合
+  if isrParamsList.size > 0
+    inhnoVal = $toInhnoVal[intnoVal]
+
+    # intnoに対応するinhnoに対してDEF_INHがある場合（E_OBJ）［NGKI3013］
+    if $cfgData[:DEF_INH].has_key?(inhnoVal)
+      inhnoParams = $cfgData[:DEF_INH][inhnoVal]
+      error_ercd("E_OBJ", isrParamsList[0], "%%intno in %apiname " \
+					"is duplicated with inhno #{inhnoParams[:inhno]}")
+    end
+
+    # intnoに対するCFG_INTがない場合（E_OBJ）［NGKI3012］
+    if !$cfgData[:CFG_INT].has_key?(intnoVal)
+      error_ercd("E_OBJ", isrParamsList[0], "%%intno in %apiname " \
+									"is not configured with CFG_INT")
+    else
+      intnoParams = $cfgData[:CFG_INT][intnoVal]
+
+      #	intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRIよりも
+      #	小さい場合（E_OBJ）［NGKI3014］
+      if intnoParams[:intpri] < $TMIN_INTPRI
+        error_ercd("E_OBJ", isrParamsList[0],
+						"intpri `#{intnoParams[:intpri]}' configured for " \
+						"%%intno with CFG_INT in higher than TMIN_INTPRI")
+      end
+    end
+  end
+end
+
+#
+#  割込みサービスルーチン（ISR）管理のデータ構造
+#
+intnoIsrList = []
+$INTNO_CREISR_VALID.each do |intnoVal|
+  inhnoVal = $toInhnoVal[intnoVal]
+  if $cfgData[:CFG_INT].has_key?(intnoVal) \
+							&& !$cfgData[:DEF_INH].has_key?(inhnoVal)
+    intnoIsrList.push(intnoVal)
+  end
+end
+
+intnoIsrList.sort!
+$isrQueueHeader = {}
+intnoIsrList.each_with_index do |intnoVal, index|
+  $isrQueueHeader[intnoVal] = "&(_kernel_isr_queue_table[#{index}])"
+end
+
+$kernelCfgC.add2("const uint_t _kernel_tnum_isr_queue = #{intnoIsrList.size};")
+
+if intnoIsrList.size > 0
+  $kernelCfgC.add("const ISR_ENTRY _kernel_isr_queue_list" \
+										"[#{intnoIsrList.size}] = {")
+  intnoIsrList.each_with_index do |intnoVal, index|
+    $kernelCfgC.add(",") if index > 0
+    $kernelCfgC.append("\t{ #{intnoVal}, #{$isrQueueHeader[intnoVal]} }")
+  end
+  $kernelCfgC.add
+  $kernelCfgC.add2("};")
+  $kernelCfgC.add2("QUEUE _kernel_isr_queue_table[#{intnoIsrList.size}];")
+else
+  $kernelCfgC.add("TOPPERS_EMPTY_LABEL(const ISR_ENTRY, " \
+											"_kernel_isr_queue_list);")
+  $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(QUEUE, _kernel_isr_queue_table);")
+end
+
+#
+#  割込みサービスルーチン（ISR）呼出しのための割込みハンドラ
+#
+intnoIsrList.each do |intnoVal|
+  inhnoVal = $toInhnoVal[intnoVal]
+
+  # 次のDEF_INHに相当するデータを生成
+  # DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
+  $cfgData[:DEF_INH][inhnoVal] = {
+    inhno: NumStr.new(inhnoVal),
+    inhatr: NumStr.new($TA_NULL, "TA_NULL"),
+    inthdr: "_kernel_inthdr_#{intnoVal}"
+  }
+
+  # 割込みサービスルーチン用の割込みハンドラ
+  $kernelCfgC.add("void")
+  $kernelCfgC.add("_kernel_inthdr_#{intnoVal}(void)")
+  $kernelCfgC.add("{")
+  $kernelCfgC.add("\t_kernel_call_isr(#{$isrQueueHeader[intnoVal]});");
+  $kernelCfgC.add2("}")
+end
+
+#
+#  割込みサービスルーチンに関する一般的な情報の生成
+#
+class IsrObject < KernelObject
+  def initialize()
+    super("isr", "isr")
+  end
+
+  def prepare(key, params)
+    # エラーチェックは実施済みなので，ここでの処理は不要
+  end
+
+  def generateInib(key, params)
+    return("(#{params[:isratr]}), (intptr_t)(#{params[:exinf]}), " \
+						"(#{$isrQueueHeader[params[:intno].val]}), " \
+						"(ISR)(#{params[:isr]}), (#{params[:isrpri]})")
+  end
+end
+IsrObject.new.generate()
+
+# 割込みサービスルーチン生成順序テーブルの生成
+if $cfgData[:CRE_ISR].size != 0
+  $kernelCfgC.add("const ID _kernel_isrorder_table[TNUM_SISRID] = { ")
+  $kernelCfgC.append("\t")
+  $cfgData[:CRE_ISR].each_with_index do |(key, params), index|
+    $kernelCfgC.append(", ") if index > 0
+    $kernelCfgC.append("#{params[:isrid]}")
+  end
+  $kernelCfgC.add
+  $kernelCfgC.add2("};")
+else
+  $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const ID, " \
+										"_kernel_isrorder_table);")
+end
+
+#
+#  割込みハンドラのための標準的な初期化情報の生成
+#
+if !$OMIT_INITIALIZE_INTERRUPT || $USE_INHINIB_TABLE
+  #
+  #  定義する割込みハンドラの数
+  #
+  $kernelCfgC.add(<<EOS)
+#define TNUM_DEF_INHNO	#{$cfgData[:DEF_INH].size}
+const uint_t _kernel_tnum_def_inhno = TNUM_DEF_INHNO;
+EOS
+
+  if $cfgData[:DEF_INH].size != 0
+    #
+    #  割込みハンドラのエントリ
+    #
+    $cfgData[:DEF_INH].each do |key, params|
+      if (params[:inhatr] & $TA_NONKERNEL) == 0
+        $kernelCfgC.add("INTHDR_ENTRY(#{params[:inhno]}, " \
+						"#{params[:inhno].val}, #{params[:inthdr]})")
+      end
+    end
+    $kernelCfgC.add("")
+
+    #
+    #  割込みハンドラ初期化ブロック
+    #
+    $kernelCfgC.add("const INHINIB _kernel_inhinib_table[TNUM_DEF_INHNO] = {")
+    $cfgData[:DEF_INH].each_with_index do |(key, params), index|
+      $kernelCfgC.add(",") if index > 0
+      if (params[:inhatr] & $TA_NONKERNEL) == 0
+        inthdr = "(FP)(INT_ENTRY(#{params[:inhno]}, #{params[:inthdr]}))"
+      else
+        inthdr = "(FP)(#{params[:inthdr]})"
+      end
+      $kernelCfgC.append("\t{ (#{params[:inhno]}), (#{params[:inhatr]}), " \
+															"#{inthdr} }")
+    end
+    $kernelCfgC.add
+    $kernelCfgC.add2("};")
+  else
+    $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INHINIB, " \
+										"_kernel_inhinib_table);")
+  end
+end
+
+#
+#  割込み要求ラインのための標準的な初期化情報の生成
+#
+if !$OMIT_INITIALIZE_INTERRUPT || $USE_INTINIB_TABLE
+  #
+  #  設定する割込み要求ラインの数
+  #
+  $kernelCfgC.add(<<EOS)
+#define TNUM_CFG_INTNO	#{$cfgData[:CFG_INT].size}
+const uint_t _kernel_tnum_cfg_intno = TNUM_CFG_INTNO;
+EOS
+
+  #
+  #  割込み要求ライン初期化ブロック
+  #
+  if $cfgData[:CFG_INT].size != 0
+    $kernelCfgC.add("const INTINIB _kernel_intinib_table[TNUM_CFG_INTNO] = {")
+    $cfgData[:CFG_INT].each_with_index do |(key, params), index|
+      $kernelCfgC.add(",") if index > 0
+      $kernelCfgC.append("\t{ (#{params[:intno]}), (#{params[:intatr]}), " \
+													"(#{params[:intpri]}) }")
+    end
+    $kernelCfgC.add
+    $kernelCfgC.add2("};")
+  else
+    $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const INTINIB, " \
+										"_kernel_intinib_table);")
+  end
+end
+
+#
+#  割込み管理機能初期化関数の追加
+#
+$initializeFunctions.push("_kernel_initialize_interrupt();")
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel.trb	(revision 398)
@@ -0,0 +1,540 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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の生成スクリプト
+#
+
+#
+#  タイムスタンプファイルの指定
+#
+$timeStampFileName = "kernel_cfg.timestamp"
+
+#
+#  kernel_cfg.hの先頭部分の生成
+#
+$kernelCfgH = GenFile.new("kernel_cfg.h")
+$kernelCfgH.add(<<EOS)
+/* kernel_cfg.h */
+#ifndef TOPPERS_KERNEL_CFG_H
+#define TOPPERS_KERNEL_CFG_H
+EOS
+
+#
+#  kernel_cfg.cの先頭部分の生成
+#
+$kernelCfgC = GenFile.new("kernel_cfg.c")
+$kernelCfgC.add(<<EOS)
+/* kernel_cfg.c */
+#include "kernel/kernel_int.h"
+#include "kernel_cfg.h"
+
+#if !(TKERNEL_PRID == 0x0007U && (TKERNEL_PRVER & 0xf000U) == 0x3000U)
+#error The kernel does not match this configuration file.
+#endif
+EOS
+
+#
+#  インクルードディレクティブ（#include）
+#
+$kernelCfgC.comment_header("Include Directives")
+$includeFiles.each do |file|
+  $kernelCfgC.add("#include #{file}")
+end
+$kernelCfgC.add()
+
+#
+#  スタック領域の確保関数
+#
+#  スタック領域の定義分と，スタック領域のサイズ記述を配列で返す．
+#
+unless defined? AllocStack()
+  def AllocStack(stack, size, section)
+    # 大きい方に丸めたサイズで確保する［NGKI1050］［NGKI3220］
+    $kernelCfgC.add("/*static*/ STK_T __attribute__((section(\"#{section}\"),aligned(16))) #{stack}[COUNT_STK_T(#{size})];")
+    return("ROUND_STK_T(#{size})")
+  end
+end
+
+#
+#  カーネルオブジェクトに関する情報の生成（仮想クラス）
+#
+class KernelObject
+  def initialize(obj, object, obj_s = obj)
+    @obj = obj
+    @OBJ = obj.tr("a-z", "A-Z")
+    @object = object
+    @obj_s = obj_s
+    @OBJ_S = obj_s.tr("a-z", "A-Z")
+    @objid = (obj + "id").to_sym
+    @api = "CRE_#{@OBJ}".to_sym
+    @inibList = { "#{@OBJ_S}INIB" => "a#{@obj_s}inib_table"}
+  end
+
+  def generate()
+    # AID_@OBJの処理
+    numAutoObjid = 0
+    $cfgData["AID_#{@OBJ}".to_sym].each do |key, params|
+      numAutoObjid += params["no#{@obj}".to_sym]
+    end
+    numObjid = $cfgData[@api].size + numAutoObjid
+
+    # kernel_cfg.hの生成
+    $kernelCfgH.add("#define TNUM_#{@OBJ}ID\t#{numObjid}")
+
+    # オブジェクトのID番号のマクロ定義の生成
+    $cfgData[@api].sort.each do |key, params|
+      $kernelCfgH.add("#define #{params[@objid]}\t#{params[@objid].val}")
+    end
+    $kernelCfgH.add()
+
+    # オブジェクトのID番号を保持する変数
+    if $USE_EXTERNAL_ID
+      $cfgData[@api].sort.each do |key, params|
+        $kernelCfgC.add("const ID #{params[@objid]}_id" \
+										" = #{params[@objid].val};")
+      end
+      $kernelCfgC.add()
+    end
+
+    # 静的に生成されたオブジェクトの数
+    $kernelCfgC.add("#define TNUM_S#{@OBJ}ID\t#{$cfgData[@api].size}")
+
+    # オブジェクトID番号の最大値
+    $kernelCfgC.add("const ID _kernel_tmax_#{@obj}id" \
+							" = (TMIN_#{@OBJ}ID + TNUM_#{@OBJ}ID - 1);")
+    $kernelCfgC.add2("const ID _kernel_tmax_s#{@obj}id" \
+							" = (TMIN_#{@OBJ}ID + TNUM_S#{@OBJ}ID - 1);")
+
+    # データ構造
+    if $cfgData[@api].size > 0
+      # 事前準備（エラーチェック，メモリ領域の生成）
+      $cfgData[@api].sort.each do |key, params|
+        prepare(key, params)
+      end
+
+      # オブジェクト全体に対して必要なメモリ領域の生成（オプション）
+      if respond_to?(:generateData)
+        generateData()
+      end
+
+      # オブジェクト初期化ブロックの生成
+      $kernelCfgC.add("const #{@OBJ_S}INIB _kernel_#{@obj_s}inib_table" \
+													"[TNUM_S#{@OBJ}ID] = {")
+      $cfgData[@api].sort.each_with_index do |(key, params), index|
+        $kernelCfgC.add(",") if index > 0
+        $kernelCfgC.append("\t{ " + generateInib(key, params) + " }")
+      end
+      $kernelCfgC.add
+      $kernelCfgC.add2("};")
+    else
+      $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(const #{@OBJ_S}INIB, " \
+										"_kernel_#{@obj_s}inib_table);")
+    end
+
+    # 動的生成オブジェクト用のオブジェクト初期化ブロック
+    @inibList.each do |type, array|
+      if numAutoObjid > 0
+        $kernelCfgC.add2("#{type} _kernel_#{array}[#{numAutoObjid}];")
+      else
+        $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(#{type}, _kernel_#{array});")
+      end
+    end
+
+    if numObjid > 0
+      # オブジェクト管理ブロックの生成
+      $kernelCfgC.add2("#{@OBJ_S}CB _kernel_#{@obj_s}cb_table" \
+													"[TNUM_#{@OBJ}ID];")
+
+      # オブジェクト初期化関数の追加
+      $initializeFunctions.push("_kernel_initialize_#{@object}();")
+    else
+      $kernelCfgC.add2("TOPPERS_EMPTY_LABEL(#{@OBJ_S}CB, " \
+										"_kernel_#{@obj_s}cb_table);")
+    end
+  end
+end
+
+#
+#  通知ハンドラの生成関数
+#
+def generateNotifyHandler(key, params, objid)
+  # パラメータを変数に格納
+  nfymode = params[:nfymode]
+  nfymode1 = nfymode & 0x0f
+  nfymode2 = nfymode & ~0x0f
+  par1 = params[:par1]
+  par2 = params[:par2]
+
+  # 通知処理のパラメータ数による補正処理
+  if nfymode == $TNFY_HANDLER || nfymode1 == $TNFY_SETVAR \
+								|| nfymode1 == $TNFY_SETFLG \
+								|| nfymode1 == $TNFY_SNDDTQ
+    # 通知処理のパラメータが2つの場合
+	numpar = 2
+	epar1 = params[:par3]
+	epar2 = params[:par4]
+  else
+    # 通知処理のパラメータが1つの場合
+    numpar = 1
+    epar1 = params[:par2]
+    epar2 = params[:par3]
+  end
+
+  # パラメータ数のチェック
+  if (numpar == 2 && par2.nil?) || (nfymode2 != 0 && epar1.nil?) \
+								|| (nfymode2 == $TENFY_SETFLG && epar2.nil?)
+    # パラメータが足りない場合
+    error_api(params, "too few parameters for nfymode `#{nfymode}' " \
+											"in %apiname of %#{objid}")
+  elsif (nfymode2 == 0 && !epar1.nil?) \
+					|| (nfymode2 != $TENFY_SETFLG && !epar2.nil?)
+    # パラメータが多すぎる場合
+    error_api(params, "too many parameters for nfymode `#{nfymode}' " \
+											"in %apiname of %#{objid}")
+  elsif nfymode == $TNFY_HANDLER
+    # タイムイベントハンドラの呼出し
+    funcname = "(NFYHDR)(#{par2})"
+  else
+    # 通知ハンドラの関数名
+    funcname = "_kernel_nfyhdr_#{params[objid]}"
+
+    # エラー通知のための変数のアドレスとオブジェクトIDを格納する
+    # 変数の生成（エラーチェックのために必要）
+    if nfymode2 == $TENFY_SETVAR || nfymode2 == $TENFY_INCVAR
+      $kernelCfgC.add2("intptr_t *const #{funcname}_p_evar =" \
+											" (intptr_t *)(#{epar1});")
+    elsif nfymode2 == $TENFY_ACTTSK || nfymode2 == $TENFY_WUPTSK
+      $kernelCfgC.add2("const ID #{funcname}_etskid = #{epar1};")
+    elsif nfymode2 == $TENFY_SIGSEM
+      $kernelCfgC.add2("const ID #{funcname}_esemid = #{epar1};")
+    elsif nfymode2 == $TENFY_SETFLG
+      $kernelCfgC.add2("const ID #{funcname}_eflgid = #{epar1};")
+    elsif nfymode2 == $TENFY_SNDDTQ
+      $kernelCfgC.add2("const ID #{funcname}_edtqid = #{epar1};")
+    end
+
+    # 関数の先頭部分の生成
+    $kernelCfgC.add("static void")
+    $kernelCfgC.add("#{funcname}(intptr_t exinf)")
+    $kernelCfgC.add("{")
+
+    if nfymode2 == 0
+      # エラー通知がない場合
+      errorCode = "(void) "
+    else
+      # エラー通知がある場合
+      $kernelCfgC.add2("\tER\tercd;")
+      errorCode = "ercd = "
+    end
+
+    # イベント通知処理の処理
+    if nfymode1 == $TNFY_SETVAR && nfymode2 == 0
+      # 変数の設定
+      $kernelCfgC.add("\t*((intptr_t *) exinf) = (#{par2});")
+    elsif nfymode1 == $TNFY_INCVAR && nfymode2 == 0
+      # 変数のインクリメント
+      $kernelCfgC.add("\t(void) loc_cpu();")
+      $kernelCfgC.add("\t*((intptr_t *) exinf) += 1;")
+      $kernelCfgC.add("\t(void) unl_cpu();")
+    elsif nfymode1 == $TNFY_ACTTSK
+      # タスクの起動
+      $kernelCfgC.add("\t#{errorCode}act_tsk((ID) exinf);")
+    elsif nfymode1 == $TNFY_WUPTSK
+      # タスクの起床
+      $kernelCfgC.add("\t#{errorCode}wup_tsk((ID) exinf);")
+    elsif nfymode1 == $TNFY_SIGSEM
+      # セマフォの返却
+      $kernelCfgC.add("\t#{errorCode}sig_sem((ID) exinf);")
+    elsif nfymode1 == $TNFY_SETFLG
+      # イベントフラグのセット
+      $kernelCfgC.add("\t#{errorCode}set_flg(((ID) exinf), #{par2});")
+    elsif nfymode1 == $TNFY_SNDDTQ
+      # データキューへの送信
+      $kernelCfgC.add("\t#{errorCode}psnd_dtq(((ID) exinf), #{par2});")
+    else
+      error_illegal_id("E_PAR", params, :nfymode, objid)
+    end
+			
+    if nfymode2 != 0
+      # エラー通知処理の処理
+      $kernelCfgC.add("\tif (ercd != E_OK) {")
+
+
+      if nfymode2 == $TENFY_SETVAR
+        # 変数の設定
+        $kernelCfgC.add("\t\t*#{funcname}_p_evar = (intptr_t) ercd;")
+      elsif nfymode2 == $TENFY_INCVAR
+        # 変数のインクリメント
+        $kernelCfgC.add("\t\t(void) loc_cpu();")
+        $kernelCfgC.add("\t\t*#{funcname}_p_evar += 1;")
+        $kernelCfgC.add("\t\t(void) unl_cpu();")
+      elsif nfymode2 == $TENFY_ACTTSK
+        # タスクの起動
+        $kernelCfgC.add("\t\t(void) act_tsk(#{funcname}_etskid);")
+      elsif nfymode2 == $TENFY_WUPTSK
+        # タスクの起床
+        $kernelCfgC.add("\t\t(void) wup_tsk(#{funcname}_etskid);")
+      elsif nfymode2 == $TENFY_SIGSEM
+        # セマフォの返却
+        $kernelCfgC.add("\t\t(void) sig_sem(#{funcname}_esemid);")
+      elsif nfymode2 == $TENFY_SETFLG
+        # イベントフラグのセット
+        $kernelCfgC.add("\t\t(void) set_flg(#{funcname}_eflgid, #{epar2});")
+      elsif nfymode2 == $TENFY_SNDDTQ
+        # データキューへの送信
+        $kernelCfgC.add("\t\t(void) psnd_dtq(#{funcname}_edtqid," \
+													" (intptr_t) ercd);")
+      else
+        error_illegal_id("E_PAR", params, :nfymode, objid)
+      end
+      $kernelCfgC.add("\t}")
+    end
+
+    # 関数の末尾部分の生成
+    $kernelCfgC.add2("}")
+  end
+  return(funcname)
+end
+
+#
+#  各機能モジュールのコンフィギュレーション
+#
+$initializeFunctions = []
+IncludeTrb("kernel/task.trb")
+IncludeTrb("kernel/semaphore.trb")
+IncludeTrb("kernel/eventflag.trb")
+IncludeTrb("kernel/dataqueue.trb")
+IncludeTrb("kernel/pridataq.trb")
+IncludeTrb("kernel/mutex.trb")
+IncludeTrb("kernel/mempfix.trb")
+IncludeTrb("kernel/cyclic.trb")
+IncludeTrb("kernel/alarm.trb")
+IncludeTrb("kernel/interrupt.trb")
+IncludeTrb("kernel/exception.trb")
+
+#
+#  非タスクコンテキスト用のスタック領域
+#
+$kernelCfgC.comment_header("Stack Area for Non-task Context")
+
+if $cfgData[:DEF_ICS].size == 0
+  # DEF_ICSがない場合のデフォルト値の設定
+  if $DEFAULT_ISTK.nil?
+    # スタック領域の自動割付け
+    istksz = AllocStack("_kernel_istack", "DEFAULT_ISTKSZ", "SI")
+    istk = "_kernel_istack"
+  else
+    istksz = "DEFAULT_ISTKSZ"
+    istk = "DEFAULT_ISTK"
+  end
+else
+  # 静的API「DEF_ICS」が複数ある（E_OBJ）［NGKI3216］
+  if $cfgData[:DEF_ICS].size > 1
+    error("E_OBJ: too many DEF_ICS")
+  end
+
+  # DEF_ICSがある場合の処理
+  params = $cfgData[:DEF_ICS][1]
+
+  # パラメータが省略された時のデフォルト値の設定
+  params[:istk] ||= "NULL"
+
+  # istkszがターゲット定義の最小値（TARGET_MIN_ISTKSZ，未定義の場合は1）
+  # よりも小さい場合（E_PAR）［NGKI3254］
+  if params[:istksz] < $TARGET_MIN_ISTKSZ
+    error_wrong("E_PAR", params, :istksz, "too small")
+  end
+
+  if params[:istk] == "NULL"
+    # スタック領域の自動割付け
+    istksz = AllocStack("_kernel_istack", params[:istksz], "SI")
+    istk = "_kernel_istack"
+  else
+    # istkszがスタック領域のサイズとして正しくない場合（E_PAR）［NGKI3222］
+    if (params[:istksz] & ($CHECK_STKSZ_ALIGN - 1)) != 0
+      error_wrong("E_PAR", params, :istksz, "not aligned")
+    end
+
+    istksz = "(#{params[:istksz]})"
+    istk = "(void *)(#{params[:istk]})"
+  end
+end
+
+$kernelCfgC.add(<<EOS)
+const size_t _kernel_istksz = #{istksz};
+STK_T *const _kernel_istk = #{istk};
+
+#ifdef TOPPERS_ISTKPT
+STK_T *const _kernel_istkpt = TOPPERS_ISTKPT(#{istk}, #{istksz});
+#endif /* TOPPERS_ISTKPT */
+EOS
+
+#
+#  カーネルが割り付けるメモリ領域
+#
+$kernelCfgC.comment_header("Memory Area Allocated by Kernel")
+
+if $cfgData[:DEF_KMM].size == 0
+  # DEF_KMMがない場合のデフォルト値の設定
+  kmmsz = "0"
+  kmm = "NULL"
+else
+  # 静的API「DEF_KMM」が複数ある（E_OBJ）
+  if ($cfgData[:DEF_KMM].size > 1)
+    error("E_OBJ: too many DEF_KMM")
+  end
+
+  # DEF_KMMがある場合の処理
+  params = $cfgData[:DEF_KMM][1]
+
+  # パラメータが省略された時のデフォルト値の設定
+  params[:kmm] ||= "NULL"
+
+  # kmmszが0の場合（E_PAR）
+  if params[:kmmsz] == 0
+    error_wrong("E_PAR", params, :kmmsz, "zero")
+  end
+
+  if params[:kmm] == "NULL"
+    # カーネルが割り付けるメモリ領域の自動割付け
+    $kernelCfgC.add("static MB_T _kernel_memory" \
+					"[TOPPERS_COUNT_SZ(#{params[:kmmsz]}, sizeof(MB_T))];")
+    kmmsz = "TOPPERS_ROUND_SZ(#{params[:kmmsz]}, sizeof(MB_T))"
+    kmm = "_kernel_memory"
+  else
+    # kmmszがカーネルが割り付けるメモリ領域のサイズとして正しくない場合
+    # （E_PAR）
+    if (params[:kmmsz] & ($CHECK_MB_ALIGN - 1)) != 0
+      error_wrong("E_PAR", params, :kmmsz, "not aligned")
+    end
+
+    kmmsz = "(#{params[:kmmsz]})"
+    kmm = "(void *)(#{params[:kmm]})"
+  end
+end
+
+$kernelCfgC.add(<<EOS)
+const size_t _kernel_kmmsz = #{kmmsz};
+MB_T *const _kernel_kmm = #{kmm};
+EOS
+
+#
+#  タイムイベント管理
+#
+$kernelCfgC.comment_header("Time Event Management")
+$kernelCfgC.add(<<EOS)
+TMEVTN   _kernel_tmevt_heap[1 + TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];
+EOS
+
+#
+#  各モジュールの初期化関数
+#
+$kernelCfgC.comment_header("Module Initialization Function")
+$kernelCfgC.append(<<EOS)
+void
+_kernel_initialize_object(void)
+{
+EOS
+$initializeFunctions.each do |func|
+  $kernelCfgC.add("\t#{func}")
+end
+$kernelCfgC.add2("}")
+
+#
+#  初期化ルーチン機能
+#
+$kernelCfgC.comment_header("Initialization Routine")
+
+# エラーチェック
+$cfgData[:ATT_INI].each do |key, params|
+  # iniatrが無効の場合（E_RSATR）［NGKI3241］
+  #（TA_NULLでない場合）
+  if (params[:iniatr] != $TA_NULL)
+    error_illegal_sym("E_RSATR", params, :iniatr, :inirtn)
+  end
+end
+
+# 初期化ルーチンの実行関数の生成
+$kernelCfgC.append(<<EOS)
+void
+_kernel_call_inirtn(void)
+{
+EOS
+$cfgData[:ATT_INI].each do |key, params|
+  $kernelCfgC.add("\t((INIRTN)(#{params[:inirtn]}))" \
+								"((intptr_t)(#{params[:exinf]}));")
+end
+$kernelCfgC.add2("}")
+
+#
+#  終了処理ルーチン機能
+#
+$kernelCfgC.comment_header("Termination Routine")
+
+# エラーチェック
+$cfgData[:ATT_TER].each do |key, params|
+  # teratrが無効の場合（E_RSATR）［NGKI3248］
+  #（TA_NULLでない場合）
+  if (params[:teratr] != $TA_NULL)
+    error_illegal_sym("E_RSATR", params, :teratr, :terrtn)
+  end
+end
+
+# 終了処理ルーチンの実行関数の生成
+$kernelCfgC.append(<<EOS)
+void
+_kernel_call_terrtn(void)
+{
+EOS
+$cfgData[:ATT_TER].reverse_each do |key, params|
+  $kernelCfgC.add("\t((TERRTN)(#{params[:terrtn]}))" \
+								"((intptr_t)(#{params[:exinf]}));")
+end
+$kernelCfgC.add2("}")
+
+#
+#  kernel_cfg.hの末尾部分の生成
+#
+$kernelCfgH.append(<<EOS)
+#endif /* TOPPERS_KERNEL_CFG_H */
+EOS
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_api.def
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_api.def	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_api.def	(revision 398)
@@ -0,0 +1,27 @@
+CRE_TSK #tskid* { .tskatr &exinf &task +itskpri .stksz &stk? }
+AID_TSK .notsk
+CRE_SEM #semid* { .sematr .isemcnt .maxsem }
+AID_SEM .nosem
+CRE_FLG #flgid* { .flgatr .iflgptn }
+AID_FLG .noflg
+CRE_DTQ #dtqid* { .dtqatr .dtqcnt &dtqmb? }
+AID_DTQ .nodtq
+CRE_PDQ #pdqid* { .pdqatr .pdqcnt +maxdpri &pdqmb? }
+AID_PDQ .nopdq
+CRE_MTX #mtxid* { .mtxatr +ceilpri? }
+AID_MTX .nomtx
+CRE_MPF #mpfid* { .mpfatr .blkcnt .blksz &mpf? &mpfmb? }
+AID_MPF .nompf
+CRE_CYC #cycid* { .cycatr { .nfymode &par1 &par2? &par3? &par4? } .cyctim .cycphs }
+AID_CYC .nocyc
+CRE_ALM #almid* { .almatr { .nfymode &par1 &par2? &par3? &par4? } }
+AID_ALM .noalm
+CFG_INT .intno* { .intatr +intpri }
+CRE_ISR #isrid* { .isratr &exinf .intno &isr +isrpri }
+AID_ISR .noisr
+DEF_INH .inhno* { .inhatr &inthdr }
+DEF_EXC .excno* { .excatr &exchdr }
+DEF_ICS { .istksz &istk? }
+DEF_KMM { .kmmsz &kmm? }
+ATT_INI { .iniatr &exinf &inirtn }
+ATT_TER { .teratr &exinf &terrtn }
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_check.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_check.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_check.trb	(revision 398)
@@ -0,0 +1,349 @@
+# -*- coding: utf-8 -*-
+# 
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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の生成スクリプト
+#
+
+# 
+#  タイムスタンプファイルの指定
+# 
+$timeStampFileName = "check.timestamp"
+
+#
+#  データセクションのLMAからVMAへのコピー
+#
+if !$lmaList.nil?
+  $lmaList.each do |lma|
+    startData = SYMBOL(lma[:START_DATA])
+    endData = SYMBOL(lma[:END_DATA])
+    startIdata = SYMBOL(lma[:START_IDATA])
+    if startData.nil?
+      error_exit("symbol `lma[:START_DATA]' not found")
+    elsif endData.nil?
+      error_exit("symbol `lma[:END_DATA]' not found")
+    elsif startIdata.nil?
+      error_exit("symbol `lma[:START_IDATA]' not found")
+    else
+      BCOPY(startIdata, startData, endData - startData)
+    end
+  end
+end
+
+#
+#  通知情報のチェック関数
+#
+$tmax_tskid = $TMIN_TSKID + $cfgData[:CRE_TSK].size - 1
+$tmax_semid = $TMIN_SEMID + $cfgData[:CRE_SEM].size - 1
+$tmax_flgid = $TMIN_FLGID + $cfgData[:CRE_FLG].size - 1
+$tmax_dtqid = $TMIN_DTQID + $cfgData[:CRE_DTQ].size - 1
+
+def checkNotifyHandler(key, params, objid, exinf, nfyhdr)
+  # パラメータを変数に格納
+  nfymode = params[:nfymode]
+  nfymode1 = nfymode & 0x0f
+  nfymode2 = nfymode & ~0x0f
+  par1 = params[:par1]
+  par2 = params[:par2]
+  funcname = "_kernel_nfyhdr_#{params[objid]}"
+
+  # 通知処理のパラメータ数による補正処理
+  if nfymode1 == $TNFY_SETVAR || nfymode1 == $TNFY_SETFLG \
+								|| nfymode1 == $TNFY_SNDDTQ
+    # 通知処理のパラメータが2つの場合
+    epar1 = params[:par3]
+    epar2 = params[:par4]
+  else
+    # 通知処理のパラメータが1つの場合
+    epar1 = params[:par2]
+    epar2 = params[:par3]
+  end
+
+  #	タイムイベントハンドラの先頭番地のチェック［NGKI3693］
+  if nfymode == $TNFY_HANDLER
+    tmehdr = nfyhdr
+    params1 = params.dup
+    params1[:tmehdr] = par2
+    if (tmehdr & ($CHECK_FUNC_ALIGN - 1)) != 0
+      error_wrong_id("E_PAR", params1, :tmehdr, objid, "not aligned")
+    end
+    if $CHECK_FUNC_NONNULL && tmehdr == 0
+      error_wrong_id("E_PAR", params1, :tmehdr, objid, "null")
+    end
+  end
+
+  #	イベント通知処理の変数の番地とオブジェクトIDのチェック
+  if nfymode1 == $TNFY_SETVAR || nfymode1 == $TNFY_INCVAR
+    # 変数の設定／インクリメントによるタイムイベントの通知
+	p_var = exinf
+    params1 = params.dup
+    params1[:p_var] = par1
+
+    # 変数の番地のチェック［NGKI3699］［NGKI3897］
+    if (p_var & ($CHECK_INTPTR_ALIGN - 1)) != 0
+      error_wrong_id("E_PAR", params1, :p_var, objid, "not aligned")
+    end
+    if $CHECK_INTPTR_NONNULL && p_var == 0
+      error_wrong_id("E_PAR", params1, :p_var, objid, "null")
+    end
+  elsif (nfymode1 == $TNFY_ACTTSK || nfymode1 == $TNFY_WUPTSK)
+    # タスクの起動／起床によるタイムイベントの通知
+    tskid = exinf
+    params1 = params.dup
+    params1[:tskid] = par1
+
+    # タスクIDのチェック［NGKI3704］
+    if !($TMIN_TSKID <= tskid && tskid <= $tmax_tskid)
+      error_illegal_id("E_ID", params1, :tskid, objid)
+    end
+  elsif nfymode1 == $TNFY_SIGSEM
+    # セマフォの資源の返却によるタイムイベントの通知
+    semid = exinf
+    params1 = params.dup
+    params1[:semid] = par1
+
+    # セマフォIDのチェック［NGKI3707］
+    if !($TMIN_SEMID <= semid && semid <= $tmax_semid)
+      error_illegal_id("E_ID", params1, :semid, objid)
+    end
+  elsif nfymode1 == $TNFY_SETFLG
+    # イベントフラグのセットによるタイムイベントの通知
+    flgid = exinf
+    params1 = params.dup
+    params1[:flgid] = par1
+
+    # イベントフラグIDのチェック［NGKI3710］
+    if !($TMIN_FLGID <= flgid && flgid <= $tmax_flgid)
+      error_illegal_id("E_ID", params1, :flgid, objid)
+    end
+  elsif nfymode1 == $TNFY_SNDDTQ
+    # データキューへの送信によるタイムイベントの通知
+    dtqid = exinf
+    params1 = params.dup
+    params1[:dtqid] = par1
+
+    # データキューIDのチェック［NGKI3713］
+    if !($TMIN_DTQID <= dtqid && dtqid <= $tmax_dtqid)
+      error_illegal_id("E_ID", params1, :dtqid, objid)
+    end
+  end
+
+  # エラー通知処理の変数の番地とオブジェクトIDのチェック
+  if (nfymode2 == $TENFY_SETVAR || nfymode2 == $TENFY_INCVAR)
+    # 変数の設定／インクリメントによるエラーの通知
+    p_var = PEEK(SYMBOL(funcname + "_p_evar"), $sizeof_intptr_t)
+    params1 = params.dup
+    params1[:p_var] = epar1
+
+    # 変数の番地のチェック［NGKI3701］［NGKI3897］
+    if (p_var & ($CHECK_INTPTR_ALIGN - 1)) != 0
+      error_wrong_id("E_PAR", params1, :p_var, objid, "not aligned")
+    end
+    if $CHECK_INTPTR_NONNULL && p_var == 0
+      error_wrong_id("E_PAR", params1, :p_var, objid, "null")
+    end
+  elsif nfymode2 == $TENFY_ACTTSK || nfymode2 == $TENFY_WUPTSK
+    # タスクの起動／起床によるエラーの通知
+    tskid = PEEK(SYMBOL(funcname + "_etskid"), $sizeof_ID)
+    params1 = params.dup
+    params1[:tskid] = epar1
+
+    # タスクIDのチェック［NGKI3704］
+    if !($TMIN_TSKID <= tskid && tskid <= $tmax_tskid)
+      error_illegal_id("E_ID", params1, :tskid, objid)
+    end
+  elsif nfymode2 == $TENFY_SIGSEM
+    # セマフォの資源の返却によるエラーの通知
+	semid = PEEK(SYMBOL(funcname + "_esemid"), $sizeof_ID)
+    params1 = params.dup
+    params1[:semid] = epar1
+
+    # セマフォIDのチェック［NGKI3707］
+    if !($TMIN_SEMID <= semid && semid <= $tmax_semid)
+      error_illegal_id("E_ID", params1, :semid, objid)
+    end
+  elsif nfymode2 == $TENFY_SETFLG
+    # イベントフラグのセットによるエラーの通知
+    flgid = PEEK(SYMBOL(funcname + "_eflgid"), $sizeof_ID)
+    params1 = params.dup
+    params1[:flgid] = epar1
+
+    # イベントフラグIDのチェック［NGKI3710］
+    if !($TMIN_FLGID <= flgid && flgid <= $tmax_flgid)
+      error_illegal_id("E_ID", params1, :flgid, objid)
+    end
+  elsif nfymode2 == $TENFY_SNDDTQ
+    # データキューへの送信によるエラーの通知
+    dtqid = PEEK(SYMBOL(funcname + "_edtqid"), $sizeof_ID)
+    params1 = params.dup
+    params1[:dtqid] = epar1
+
+    # データキューIDのチェック［NGKI3715］
+    if !($TMIN_DTQID <= dtqid && dtqid <= $tmax_dtqid)
+      error_illegal_id("E_ID", params1, :dtqid, objid)
+    end
+  end
+end
+
+# 
+#  タスクに関するチェック
+# 
+tinib = SYMBOL("_kernel_tinib_table")
+$cfgData[:CRE_TSK].sort.each do |key, params|
+  task = PEEK(tinib + $offsetof_TINIB_task, $sizeof_TASK)
+
+  # タスクの先頭番地のチェック［NGKI1033］
+  if (task & ($CHECK_FUNC_ALIGN - 1)) != 0
+    error_wrong_id("E_PAR", params, :task, :tskid, "not aligned")
+  end
+  if $CHECK_FUNC_NONNULL && task == 0
+    error_wrong_id("E_PAR", params, :task, :tskid, "null")
+  end
+
+  # タスクのスタック領域の先頭番地のチェック［NGKI1056］
+  if $USE_TSKINICTXB
+    stk = GetStackTskinictxb(key, params, tinib)
+  else
+    stk = PEEK(tinib + $offsetof_TINIB_stk, $sizeof_void_ptr)
+  end
+  if (stk & ($CHECK_STACK_ALIGN - 1)) != 0
+    error_wrong_id("E_PAR", params, :stk, :tskid, "not aligned")
+  end
+  if $CHECK_STACK_NONNULL && stk == 0
+    error_wrong_id("E_PAR", params, :stk, :tskid, "null")
+  end
+
+  tinib += $sizeof_TINIB
+end
+
+# 
+#  固定長メモリプールに関するチェック
+# 
+mpfinib = SYMBOL("_kernel_mpfinib_table")
+$cfgData[:CRE_MPF].sort.each do |key, params|
+  mpf = PEEK(mpfinib + $offsetof_MPFINIB_mpf, $sizeof_void_ptr)
+
+  # 固定長メモリプール領域の先頭番地のチェック［NGKI2249］
+  if (mpf & ($CHECK_MPF_ALIGN - 1)) != 0
+    error_wrong_id("E_PAR", params, :mpf, :mpfid, "not aligned")
+  end
+  if $CHECK_MPF_NONNULL && mpf == 0
+    error_wrong_id("E_PAR", params, :mpf, :mpfid, "null")
+  end
+
+  mpfinib += $sizeof_MPFINIB
+end
+
+# 
+#  周期通知に関するチェック
+# 
+cycinib = SYMBOL("_kernel_cycinib_table")
+$cfgData[:CRE_CYC].sort.each do |key, params|
+  exinf = PEEK(cycinib + $offsetof_CYCINIB_exinf, $sizeof_intptr_t)
+  nfyhdr = PEEK(cycinib + $offsetof_CYCINIB_nfyhdr, $sizeof_NFYHDR)
+
+  #	通知情報のチェック
+  checkNotifyHandler(key, params, :cycid, exinf, nfyhdr)
+
+  cycinib += $sizeof_CYCINIB
+end
+
+# 
+#  アラーム通知に関するチェック
+# 
+alminib = SYMBOL("_kernel_alminib_table")
+$cfgData[:CRE_ALM].sort.each do |key, params|
+  exinf = PEEK(alminib + $offsetof_ALMINIB_exinf, $sizeof_intptr_t)
+  nfyhdr = PEEK(alminib + $offsetof_ALMINIB_nfyhdr, $sizeof_NFYHDR)
+
+  #	通知情報のチェック
+  checkNotifyHandler(key, params, :almid, exinf, nfyhdr)
+
+  alminib += $sizeof_ALMINIB
+end
+
+#
+#  割込みサービスルーチンに関するチェック
+#
+isrinib = SYMBOL("_kernel_isrinib_table")
+$cfgData[:CRE_ISR].sort.each do |key, params|
+  isr = PEEK(isrinib + $offsetof_ISRINIB_isr, $sizeof_ISR)
+
+  # 割込みサービスルーチンの先頭番地のチェック［NGKI3004］
+  if (isr & ($CHECK_FUNC_ALIGN - 1)) != 0
+    error_wrong_id("E_PAR", params, :isr, :isrid, "not aligned")
+  end
+  if $CHECK_FUNC_NONNULL && isr == 0
+    error_wrong_id("E_PAR", params, :isr, :isrid, "null")
+  end
+
+  isrinib += $sizeof_ISRINIB
+end
+
+# 
+#  非タスクコンテキスト用のスタック領域に関するチェック
+# 
+istkAddr = SYMBOL("_kernel_istk")
+if !istkAddr.nil?
+  istk = PEEK(istkAddr, $sizeof_void_ptr)
+
+  # 非タスクコンテキスト用のスタック領域の先頭番地のチェック［NGKI3222］
+  if (istk & ($CHECK_STACK_ALIGN - 1)) != 0
+    error_wrong("E_PAR", $cfgData[:DEF_ICS][1], :istk, "not aligned")
+  end
+  if $CHECK_STACK_NONNULL && istk == 0
+    error_wrong("E_PAR", $cfgData[:DEF_ICS][1], :istk, "null")
+  end
+end
+
+# 
+#  カーネルが割り付けるメモリ領域に関するチェック
+# 
+kmmAddr = SYMBOL("_kernel_kmm")
+if !kmmAddr.nil?
+  kmm = PEEK(kmmAddr, $sizeof_void_ptr)
+
+  # カーネルが割り付けるメモリ領域の先頭番地のチェック
+  if (kmm & ($CHECK_MB_ALIGN - 1)) != 0
+    error_wrong("E_PAR", $cfgData[:DEF_KMM][1], :kmm, "not aligned")
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_impl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_impl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_impl.h	(revision 398)
@@ -0,0 +1,230 @@
+/*
+ *  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-2016 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>
+
+/*
+ *  ターゲット依存情報の定義
+ */
+#include "target_kernel_impl.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_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_DPRI		(TMAX_DPRI - TMIN_DPRI + 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
+
+/*
+ *  TECSの初期化（init_tecs.c）
+ */
+extern void initialize_tecs(void);
+
+/*
+ *  各モジュールの初期化（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_t	istksz;		/* スタック領域のサイズ（丸めた値） */
+extern STK_T *const	istk;		/* スタック領域の先頭番地 */
+#ifdef TOPPERS_ISTKPT
+extern STK_T *const	istkpt;		/* スタックポインタの初期値 */
+#endif /* TOPPERS_ISTKPT */
+
+/*
+ *  カーネルが割り付けるメモリ領域（kernel_cfg.c）
+ */
+extern const size_t	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_t size);
+extern void kernel_free(void *ptr);
+
+/*
+ *  通知ハンドラの型定義
+ */
+typedef void	(*NFYHDR)(intptr_t exinf);
+
+/*
+ *  通知方法のエラーチェック
+ */
+extern ER check_nfyinfo(const T_NFYINFO *p_nfyinfo);
+
+/*
+ *  通知ハンドラ
+ */
+extern void notify_handler(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_KERNEL_IMPL_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_int.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_int.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_int.h	(revision 398)
@@ -0,0 +1,83 @@
+/*
+ *  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-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$
+ */
+
+/*
+ *		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 "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_mbedtls/trunk/asp3_dcre/kernel/kernel_rename.def
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_rename.def	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_rename.def	(revision 398)
@@ -0,0 +1,198 @@
+# startup.c
+kerflg
+exit_kernel
+initialize_kmm
+kernel_malloc
+kernel_free
+
+# task.c
+p_runtsk
+p_schedtsk
+enadsp
+dspflg
+ready_queue
+ready_primap
+free_tcb
+initialize_task
+search_schedtsk
+make_runnable
+make_non_runnable
+make_dormant
+make_active
+change_priority
+rotate_ready_queue
+task_terminate
+
+# taskhook.c
+mtxhook_check_ceilpri
+mtxhook_scan_ceilmtx
+mtxhook_release_all
+
+# wait.c
+make_wait_tmout
+wait_complete
+wait_tmout
+wait_tmout_ok
+wobj_make_wait
+wobj_make_wait_tmout
+init_wait_queue
+
+# time_event.c
+boundary_evttim
+current_evttim
+current_hrtcnt
+monotonic_evttim
+systim_offset
+in_signal_time
+initialize_tmevt
+tmevt_up
+tmevt_down
+update_current_evttim
+set_hrt_event
+tmevtb_register
+tmevtb_enqueue
+tmevtb_dequeue
+check_adjtim
+tmevt_lefttim
+signal_time
+
+# semaphore.c
+free_semcb
+initialize_semaphore
+
+# eventflag.c
+free_flgcb
+initialize_eventflag
+check_flg_cond
+
+# dataqueue.c
+free_dtqcb
+initialize_dataqueue
+enqueue_data
+force_enqueue_data
+dequeue_data
+send_data
+force_send_data
+receive_data
+
+# pridataq.c
+free_pdqcb
+initialize_pridataq
+enqueue_pridata
+dequeue_pridata
+send_pridata
+receive_pridata
+
+# mutex.c
+free_mtxcb
+initialize_mutex
+mutex_check_ceilpri
+mutex_scan_ceilmtx
+mutex_drop_priority
+mutex_acquire
+mutex_release
+mutex_release_all
+
+# mempfix.c
+free_mpfcb
+initialize_mempfix
+get_mpf_block
+
+# time_manage.c
+check_nfyinfo
+notify_handler
+
+# cyclic.c
+free_cyccb
+initialize_cyclic
+call_cyclic
+
+# alarm.c
+free_almcb
+initialize_alarm
+call_alarm
+
+# interrupt.c
+free_isrcb
+initialize_isr
+call_isr
+initialize_interrupt
+
+# exception.c
+initialize_exception
+
+# kernel_cfg.c
+initialize_object
+call_inirtn
+call_terrtn
+tmax_tskid
+tmax_stskid
+tinib_table
+atinib_table
+torder_table
+tcb_table
+tmax_semid
+tmax_ssemid
+seminib_table
+aseminib_table
+semcb_table
+tmax_flgid
+tmax_sflgid
+flginib_table
+aflginib_table
+flgcb_table
+tmax_dtqid
+tmax_sdtqid
+dtqinib_table
+adtqinib_table
+dtqcb_table
+tmax_pdqid
+tmax_spdqid
+pdqinib_table
+apdqinib_table
+pdqcb_table
+tmax_mtxid
+tmax_smtxid
+mtxinib_table
+amtxinib_table
+mtxcb_table
+tmax_mpfid
+tmax_smpfid
+mpfinib_table
+ampfinib_table
+mpfcb_table
+tmax_cycid
+tmax_scycid
+cycinib_table
+acycinib_table
+acyc_nfyinfo_table
+cyccb_table
+tmax_almid
+tmax_salmid
+alminib_table
+aalminib_table
+aalm_nfyinfo_table
+almcb_table
+tnum_isr_queue
+isr_queue_list
+isr_queue_table
+tmax_isrid
+tmax_sisrid
+isrinib_table
+aisrinib_table
+isrorder_table
+isrcb_table
+tnum_def_inhno
+inhinib_table
+tnum_cfg_intno
+intinib_table
+tnum_def_excno
+excinib_table
+tmevt_heap
+istksz
+istk
+istkpt
+kmmsz
+kmm
+
+INCLUDE "target"
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_rename.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_rename.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_rename.h	(revision 398)
@@ -0,0 +1,240 @@
+/* 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 enadsp						_kernel_enadsp
+#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 task_terminate				_kernel_task_terminate
+
+/*
+ *  taskhook.c
+ */
+#define mtxhook_check_ceilpri		_kernel_mtxhook_check_ceilpri
+#define mtxhook_scan_ceilmtx		_kernel_mtxhook_scan_ceilmtx
+#define mtxhook_release_all			_kernel_mtxhook_release_all
+
+/*
+ *  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 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 boundary_evttim				_kernel_boundary_evttim
+#define current_evttim				_kernel_current_evttim
+#define current_hrtcnt				_kernel_current_hrtcnt
+#define monotonic_evttim			_kernel_monotonic_evttim
+#define systim_offset				_kernel_systim_offset
+#define in_signal_time				_kernel_in_signal_time
+#define initialize_tmevt			_kernel_initialize_tmevt
+#define tmevt_up					_kernel_tmevt_up
+#define tmevt_down					_kernel_tmevt_down
+#define update_current_evttim		_kernel_update_current_evttim
+#define set_hrt_event				_kernel_set_hrt_event
+#define tmevtb_register				_kernel_tmevtb_register
+#define tmevtb_enqueue				_kernel_tmevtb_enqueue
+#define tmevtb_dequeue				_kernel_tmevtb_dequeue
+#define check_adjtim				_kernel_check_adjtim
+#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
+
+/*
+ *  mutex.c
+ */
+#define free_mtxcb					_kernel_free_mtxcb
+#define initialize_mutex			_kernel_initialize_mutex
+#define mutex_check_ceilpri			_kernel_mutex_check_ceilpri
+#define mutex_scan_ceilmtx			_kernel_mutex_scan_ceilmtx
+#define mutex_drop_priority			_kernel_mutex_drop_priority
+#define mutex_acquire				_kernel_mutex_acquire
+#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
+
+/*
+ *  time_manage.c
+ */
+#define check_nfyinfo				_kernel_check_nfyinfo
+#define notify_handler				_kernel_notify_handler
+
+/*
+ *  cyclic.c
+ */
+#define free_cyccb					_kernel_free_cyccb
+#define initialize_cyclic			_kernel_initialize_cyclic
+#define call_cyclic					_kernel_call_cyclic
+
+/*
+ *  alarm.c
+ */
+#define free_almcb					_kernel_free_almcb
+#define initialize_alarm			_kernel_initialize_alarm
+#define call_alarm					_kernel_call_alarm
+
+/*
+ *  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 torder_table				_kernel_torder_table
+#define tcb_table					_kernel_tcb_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_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 acyc_nfyinfo_table			_kernel_acyc_nfyinfo_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 aalm_nfyinfo_table			_kernel_aalm_nfyinfo_table
+#define almcb_table					_kernel_almcb_table
+#define tnum_isr_queue				_kernel_tnum_isr_queue
+#define isr_queue_list				_kernel_isr_queue_list
+#define isr_queue_table				_kernel_isr_queue_table
+#define tmax_isrid					_kernel_tmax_isrid
+#define tmax_sisrid					_kernel_tmax_sisrid
+#define isrinib_table				_kernel_isrinib_table
+#define aisrinib_table				_kernel_aisrinib_table
+#define isrorder_table				_kernel_isrorder_table
+#define isrcb_table					_kernel_isrcb_table
+#define tnum_def_inhno				_kernel_tnum_def_inhno
+#define inhinib_table				_kernel_inhinib_table
+#define tnum_cfg_intno				_kernel_tnum_cfg_intno
+#define intinib_table				_kernel_intinib_table
+#define tnum_def_excno				_kernel_tnum_def_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
+
+
+#include "target_rename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_sym.def
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_sym.def	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_sym.def	(revision 398)
@@ -0,0 +1,150 @@
+USE_EXTERNAL_ID,true,bool,defined(USE_EXTERNAL_ID)
+SIL_ENDIAN_BIG,true,bool,defined(SIL_ENDIAN_BIG)
+SIL_ENDIAN_LITTLE,true,bool,defined(SIL_ENDIAN_LITTLE)
+TA_NULL
+TA_ACT
+TA_NOACTQUE
+TA_TPRI
+TA_WMUL
+TA_CLR
+TA_CEILING
+TA_STA
+TA_NONKERNEL
+TA_ENAINT
+TA_EDGE
+TNFY_HANDLER
+TNFY_SETVAR
+TNFY_INCVAR
+TNFY_ACTTSK
+TNFY_WUPTSK
+TNFY_SIGSEM
+TNFY_SETFLG
+TNFY_SNDDTQ
+TENFY_SETVAR
+TENFY_INCVAR
+TENFY_ACTTSK
+TENFY_WUPTSK
+TENFY_SIGSEM
+TENFY_SETFLG
+TENFY_SNDDTQ
+TMIN_TPRI,,signed
+TMAX_TPRI,,signed
+TMIN_DPRI,,signed
+TMAX_DPRI,,signed
+TMIN_ISRPRI,,signed
+TMAX_ISRPRI,,signed
+TBIT_FLGPTN
+TMAX_MAXSEM
+TMAX_RELTIM
+TMIN_INTPRI,,signed
+TMAX_INTPRI,,signed
+TMIN_TSKID,,signed
+TMIN_SEMID,,signed
+TMIN_FLGID,,signed
+TMIN_DTQID,,signed
+TMIN_PDQID,,signed
+TMIN_MTXID,,signed
+TMIN_MPFID,,signed
+TMIN_CYCID,,signed
+TMIN_ALMID,,signed
+USE_TSKINICTXB,true,bool,defined(USE_TSKINICTXB)
+OMIT_INITIALIZE_INTERRUPT,true,bool,defined(OMIT_INITIALIZE_INTERRUPT)
+USE_INHINIB_TABLE,true,bool,defined(USE_INHINIB_TABLE)
+USE_INTINIB_TABLE,true,bool,defined(USE_INTINIB_TABLE)
+OMIT_INITIALIZE_EXCEPTION,true,bool,defined(OMIT_INITIALIZE_EXCEPTION)
+DEFAULT_ISTK,,,defined(DEFAULT_ISTK)
+TARGET_TSKATR,,,defined(TARGET_TSKATR),0
+TARGET_INTATR,,,defined(TARGET_INTATR),0
+TARGET_INHATR,,,defined(TARGET_INHATR),0
+TARGET_ISRATR,,,defined(TARGET_ISRATR),0
+TARGET_EXCATR,,,defined(TARGET_EXCATR),0
+TARGET_MIN_STKSZ,,,defined(TARGET_MIN_STKSZ),1
+TARGET_MIN_ISTKSZ,,,defined(TARGET_MIN_ISTKSZ),1
+CHECK_STKSZ_ALIGN,,,defined(CHECK_STKSZ_ALIGN),1
+CHECK_INTPTR_ALIGN,,,defined(CHECK_INTPTR_ALIGN),1
+CHECK_INTPTR_NONNULL,true,bool,defined(CHECK_INTPTR_NONNULL)
+CHECK_FUNC_ALIGN,,,defined(CHECK_FUNC_ALIGN),1
+CHECK_FUNC_NONNULL,true,bool,defined(CHECK_FUNC_NONNULL)
+CHECK_STACK_ALIGN,,,defined(CHECK_STACK_ALIGN),1
+CHECK_STACK_NONNULL,true,bool,defined(CHECK_STACK_NONNULL)
+CHECK_MPF_ALIGN,,,defined(CHECK_MPF_ALIGN),1
+CHECK_MPF_NONNULL,true,bool,defined(CHECK_MPF_NONNULL)
+CHECK_MB_ALIGN,,,defined(CHECK_MB_ALIGN),1
+sizeof_void_ptr,sizeof(void*)
+sizeof_uint_t,sizeof(uint_t)
+sizeof_size_t,sizeof(size_t)
+sizeof_intptr_t,sizeof(intptr_t)
+sizeof_ID,sizeof(ID)
+sizeof_FP,sizeof(FP)
+sizeof_INTNO,sizeof(INTNO)
+sizeof_INHNO,sizeof(INHNO)
+sizeof_EXCNO,sizeof(EXCNO)
+sizeof_TASK,sizeof(TASK)
+sizeof_TMEHDR,sizeof(TMEHDR)
+sizeof_ISR,sizeof(ISR)
+sizeof_INTHDR,sizeof(INTHDR)
+sizeof_EXCHDR,sizeof(EXCHDR)
+sizeof_INIRTN,sizeof(INIRTN)
+sizeof_TERRTN,sizeof(TERRTN)
+sizeof_NFYHDR,sizeof(NFYHDR)
+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,"offsetof(TINIB,stksz)",,!defined(USE_TSKINICTXB)
+offsetof_TINIB_stk,"offsetof(TINIB,stk)",,!defined(USE_TSKINICTXB)
+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_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_nfyhdr,"offsetof(CYCINIB,nfyhdr)"
+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_nfyhdr,"offsetof(ALMINIB,nfyhdr)"
+sizeof_ISRINIB,sizeof(ISRINIB)
+offsetof_ISRINIB_isratr,"offsetof(ISRINIB,isratr)"
+offsetof_ISRINIB_exinf,"offsetof(ISRINIB,exinf)"
+offsetof_ISRINIB_p_isr_queue,"offsetof(ISRINIB,p_isr_queue)"
+offsetof_ISRINIB_isr,"offsetof(ISRINIB,isr)"
+offsetof_ISRINIB_isrpri,"offsetof(ISRINIB,isrpri)"
+sizeof_INHINIB,sizeof(INHINIB),,!defined(OMIT_INITIALIZE_INTERRUPT)
+offset_INHINIB_inhno,"offsetof(INHINIB,inhno)",,!defined(OMIT_INITIALIZE_INTERRUPT)
+offset_INHINIB_inhatr,"offsetof(INHINIB,inhatr)",,!defined(OMIT_INITIALIZE_INTERRUPT),,
+offset_INHINIB_int_entry,"offsetof(INHINIB,int_entry)",,!defined(OMIT_INITIALIZE_INTERRUPT),,
+sizeof_INTINIB,sizeof(INTINIB),,!defined(OMIT_INITIALIZE_INTERRUPT)
+offset_INTINIB_intno,"offsetof(INTINIB,intno)",,!defined(OMIT_INITIALIZE_INTERRUPT)
+offset_INTINIB_intatr,"offsetof(INTINIB,intatr)",,!defined(OMIT_INITIALIZE_INTERRUPT)
+offset_INTINIB_intpri,"offsetof(INTINIB,intpri)",,!defined(OMIT_INITIALIZE_INTERRUPT)
+sizeof_EXCINIB,sizeof(EXCINIB),,!defined(OMIT_INITIALIZE_EXCEPTION)
+offset_EXCINIB_excno,"offsetof(EXCINIB,excno)",,!defined(OMIT_INITIALIZE_EXCEPTION)
+offset_EXCINIB_excatr,"offsetof(EXCINIB,excatr)",,!defined(OMIT_INITIALIZE_EXCEPTION)
+offset_EXCINIB_exc_entry,"offsetof(EXCINIB,exc_entry)",,!defined(OMIT_INITIALIZE_EXCEPTION)
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_unrename.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_unrename.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/kernel_unrename.h	(revision 398)
@@ -0,0 +1,241 @@
+/* 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 enadsp
+#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 task_terminate
+
+/*
+ *  taskhook.c
+ */
+#undef mtxhook_check_ceilpri
+#undef mtxhook_scan_ceilmtx
+#undef mtxhook_release_all
+
+/*
+ *  wait.c
+ */
+#undef make_wait_tmout
+#undef wait_complete
+#undef wait_tmout
+#undef wait_tmout_ok
+#undef wobj_make_wait
+#undef wobj_make_wait_tmout
+#undef init_wait_queue
+
+/*
+ *  time_event.c
+ */
+#undef boundary_evttim
+#undef current_evttim
+#undef current_hrtcnt
+#undef monotonic_evttim
+#undef systim_offset
+#undef in_signal_time
+#undef initialize_tmevt
+#undef tmevt_up
+#undef tmevt_down
+#undef update_current_evttim
+#undef set_hrt_event
+#undef tmevtb_register
+#undef tmevtb_enqueue
+#undef tmevtb_dequeue
+#undef check_adjtim
+#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
+
+/*
+ *  mutex.c
+ */
+#undef free_mtxcb
+#undef initialize_mutex
+#undef mutex_check_ceilpri
+#undef mutex_scan_ceilmtx
+#undef mutex_drop_priority
+#undef mutex_acquire
+#undef mutex_release
+#undef mutex_release_all
+
+/*
+ *  mempfix.c
+ */
+#undef free_mpfcb
+#undef initialize_mempfix
+#undef get_mpf_block
+
+/*
+ *  time_manage.c
+ */
+#undef check_nfyinfo
+#undef notify_handler
+
+/*
+ *  cyclic.c
+ */
+#undef free_cyccb
+#undef initialize_cyclic
+#undef call_cyclic
+
+/*
+ *  alarm.c
+ */
+#undef free_almcb
+#undef initialize_alarm
+#undef call_alarm
+
+/*
+ *  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 torder_table
+#undef tcb_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_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 acyc_nfyinfo_table
+#undef cyccb_table
+#undef tmax_almid
+#undef tmax_salmid
+#undef alminib_table
+#undef aalminib_table
+#undef aalm_nfyinfo_table
+#undef almcb_table
+#undef tnum_isr_queue
+#undef isr_queue_list
+#undef isr_queue_table
+#undef tmax_isrid
+#undef tmax_sisrid
+#undef isrinib_table
+#undef aisrinib_table
+#undef isrorder_table
+#undef isrcb_table
+#undef tnum_def_inhno
+#undef inhinib_table
+#undef tnum_cfg_intno
+#undef intinib_table
+#undef tnum_def_excno
+#undef excinib_table
+#undef tmevt_heap
+#undef istksz
+#undef istk
+#undef istkpt
+#undef kmmsz
+#undef kmm
+
+
+#include "target_unrename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mempfix.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mempfix.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mempfix.c	(revision 398)
@@ -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) 2005-2016 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, p_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, p_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, p_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;
+	uint_t	blkcnt;
+	uint_t	blksz;
+	MPF_T	*mpf;
+	MPFMB	*p_mpfmb;
+	ER		ercd;
+
+	LOG_ACRE_MPF_ENTER(pk_cmpf);
+	CHECK_TSKCTX_UNL();
+
+	mpfatr = pk_cmpf->mpfatr;
+	blkcnt = pk_cmpf->blkcnt;
+	blksz = pk_cmpf->blksz;
+	mpf = pk_cmpf->mpf;
+	p_mpfmb = pk_cmpf->mpfmb;
+
+	CHECK_RSATR(mpfatr, TA_TPRI);
+	CHECK_PAR(blkcnt != 0);
+	CHECK_PAR(blksz != 0);
+	if (mpf != NULL) {
+		CHECK_PAR(MPF_ALIGN(mpf));
+	}
+	if (p_mpfmb != NULL) {
+		CHECK_PAR(MB_ALIGN(p_mpfmb));
+	}
+
+	lock_cpu();
+	if (tnum_mpf == 0 || queue_empty(&free_mpfcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (mpf == NULL) {
+			mpf = kernel_malloc(ROUND_MPF_T(blksz) * blkcnt);
+			mpfatr |= TA_MEMALLOC;
+		}
+		if (mpf == NULL) {
+			ercd = E_NOMEM;
+		}
+		else {
+			if (p_mpfmb == NULL) {
+				p_mpfmb = kernel_malloc(sizeof(MPFMB) * blkcnt);
+				mpfatr |= TA_MBALLOC;
+			}
+			if (p_mpfmb == NULL) {
+				if (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 = blkcnt;
+				p_mpfinib->blksz = ROUND_MPF_T(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);
+			}
+		}
+	}
+	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;
+	ER		ercd;
+
+	LOG_DEL_MPF_ENTER(mpfid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_MPFID(mpfid));
+	p_mpfcb = get_mpfcb(mpfid);
+
+	lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (mpfid <= tmax_smpfid) {
+		ercd = E_OBJ;
+	}
+	else {
+		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 (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_ID(VALID_MPFID(mpfid));
+	p_mpfcb = get_mpfcb(mpfid);
+
+	lock_cpu_dsp();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (p_mpfcb->fblkcnt > 0) {
+		get_mpf_block(p_mpfcb, p_blk);
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = TS_WAITING_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;
+		}
+	}
+	unlock_cpu_dsp();
+
+  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_ID(VALID_MPFID(mpfid));
+	p_mpfcb = get_mpfcb(mpfid);
+
+	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;
+	}
+	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_ID(VALID_MPFID(mpfid));
+	CHECK_PAR(VALID_TMOUT(tmout));
+	p_mpfcb = get_mpfcb(mpfid);
+
+	lock_cpu_dsp();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	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_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;
+		}
+	}
+	unlock_cpu_dsp();
+
+  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_t	blkoffset;
+	uint_t	blkidx;
+	TCB		*p_tcb;
+	ER		ercd;
+    
+	LOG_REL_MPF_ENTER(mpfid, blk);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_MPFID(mpfid));
+	p_mpfcb = get_mpfcb(mpfid);
+
+	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;
+			wait_complete(p_tcb);
+			if (p_runtsk != p_schedtsk) {
+				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;
+		}
+	}
+	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;
+	ER		ercd;
+    
+	LOG_INI_MPF_ENTER(mpfid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_MPFID(mpfid));
+	p_mpfcb = get_mpfcb(mpfid);
+
+	lock_cpu();
+	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		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 (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_ID(VALID_MPFID(mpfid));
+	p_mpfcb = get_mpfcb(mpfid);
+
+	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;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_REF_MPF_LEAVE(ercd, pk_rmpf);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_mpf */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mempfix.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mempfix.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mempfix.h	(revision 398)
@@ -0,0 +1,146 @@
+/*
+ *  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_MEMPFIX_H
+#define TOPPERS_MEMPFIX_H
+
+#include "kernel_impl.h"
+#include <queue.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_mbedtls/trunk/asp3_dcre/kernel/mempfix.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mempfix.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mempfix.trb	(revision 398)
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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$
+# 
+
+#
+#		固定長メモリプール機能の生成スクリプト
+#
+
+class MempfixObject < KernelObject
+  def initialize()
+    super("mpf", "mempfix")
+  end
+
+  def prepare(key, params)
+    # パラメータが省略された時のデフォルト値の設定
+    params[:mpf] ||= "NULL"
+    params[:mpfmb] ||= "NULL"
+
+    # mpfatrが無効の場合（E_RSATR）［NGKI2225］
+    #（TA_TPRI以外のビットがセットされている場合）
+    if (params[:mpfatr] & ~($TA_TPRI)) != 0
+      error_illegal_id("E_RSATR", params, :mpfatr, :mpfid)
+    end
+
+    # blkcntが0の場合（E_PAR）［NGKI2229］
+    if params[:blkcnt] == 0
+      error_illegal_id("E_PAR", params, :blkcnt, :mpfid)
+    end
+
+    # blkszが0の場合（E_PAR）［NGKI2230］
+    if params[:blksz] == 0
+      error_illegal_id("E_PAR", params, :blksz, :mpfid)
+    end
+
+    # 固定長メモリプール領域
+    if params[:mpf] == "NULL"
+      mpfName = "_kernel_mpf_#{params[:mpfid]}"
+      $kernelCfgC.add("static MPF_T #{mpfName}" \
+				"[#{params[:blkcnt]} * COUNT_MPF_T(#{params[:blksz]})];")
+      params[:mpfinib_mpf] = mpfName
+    else
+      params[:mpfinib_mpf] = "(void *)(#{params[:mpf]})"
+    end
+
+    # mpfmbがNULLでない場合（E_NOSPT）［ASPS0166］
+    if params[:mpfmb] != "NULL"
+      error_illegal_id("E_NOSPT", params, :mpfmb, :mpfid)
+    end
+
+    # 固定長メモリプール管理領域
+    mpfmbName = "_kernel_mpfmb_#{params[:mpfid]}"
+    $kernelCfgC.add("static MPFMB #{mpfmbName}[#{params[:blkcnt]}];")
+    params[:mpfinib_mpfmb] = mpfmbName
+  end
+
+  def generateInib(key, params)
+    return("(#{params[:mpfatr]}), (#{params[:blkcnt]}), " \
+			"ROUND_MPF_T(#{params[:blksz]}), #{params[:mpfinib_mpf]}, " \
+			"#{params[:mpfinib_mpfmb]}")
+  end
+end
+
+#
+#  固定長メモリプールに関する情報の生成
+#
+$kernelCfgC.comment_header("Fixed-sized Memorypool Functions")
+MempfixObject.new.generate()
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mutex.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mutex.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mutex.c	(revision 398)
@@ -0,0 +1,755 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2005-2016 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 "taskhook.h"
+#include "wait.h"
+#include "mutex.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACRE_MTX_ENTER
+#define LOG_ACRE_MTX_ENTER(pk_cmtx)
+#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)]))
+
+/*
+ *  ミューテックスのプロトコルを判断するマクロ
+ */
+#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_mtxini
+
+/*
+ *  使用していないミューテックス管理ブロックのリスト
+ */
+QUEUE	free_mtxcb;
+
+/* 
+ *  ミューテックス機能の初期化
+ */
+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)
+{
+	MTXCB	*p_mtxcb;
+
+	/*
+	 *  タスクがロックしている優先度上限ミューテックスの中で，上限優先
+	 *  度がbpriorityよりも低いものがあれば，falseを返す．
+	 */
+	p_mtxcb = p_tcb->p_lastmtx;
+	while (p_mtxcb != NULL) {
+		if (MTX_CEILING(p_mtxcb) && bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+			return(false);
+		}
+		p_mtxcb = p_mtxcb->p_prevmtx;
+	}
+
+	/*
+	 *  タスクが優先度上限ミューテックスのロックを待っている場合に，そ
+	 *  の上限優先度が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)
+{
+	MTXCB	*p_mtxcb;
+
+	p_mtxcb = p_tcb->p_lastmtx;
+	while (p_mtxcb != NULL) {
+		if (MTX_CEILING(p_mtxcb)) {
+			return(true);
+		}
+		p_mtxcb = p_mtxcb->p_prevmtx;
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_mtxscan */
+
+/* 
+ *  タスクの現在優先度の計算
+ *
+ *  p_tcbで指定されるタスクの現在優先度（に設定すべき値）を計算する．
+ */
+Inline uint_t
+mutex_calc_priority(TCB *p_tcb)
+{
+	uint_t	priority;
+	MTXCB	*p_mtxcb;
+
+	priority = p_tcb->bpriority;
+	p_mtxcb = p_tcb->p_lastmtx;
+	while (p_mtxcb != NULL) {
+		if (MTX_CEILING(p_mtxcb) && p_mtxcb->p_mtxinib->ceilpri < priority) {
+			priority = p_mtxcb->p_mtxinib->ceilpri;
+		}
+		p_mtxcb = p_mtxcb->p_prevmtx;
+	}
+	return(priority);
+}
+
+/*
+ *  ミューテックスを解放した場合の現在優先度変更処理
+ */
+#ifdef TOPPERS_mtxdrop
+
+void
+mutex_drop_priority(TCB *p_tcb, MTXCB *p_mtxcb)
+{
+	uint_t	newpri;
+
+	if (MTX_CEILING(p_mtxcb)
+					&& p_mtxcb->p_mtxinib->ceilpri == p_tcb->priority) {
+		newpri = mutex_calc_priority(p_tcb);
+		if (newpri != p_tcb->priority) {
+			change_priority(p_tcb, newpri, true);
+		}
+	}
+}
+
+#endif /* TOPPERS_mtxdrop */
+
+/*
+ *  ミューテックスのロック
+ */
+#ifdef TOPPERS_mtxacq
+
+void
+mutex_acquire(TCB *p_tcb, MTXCB *p_mtxcb)
+{
+	p_mtxcb->p_loctsk = p_tcb;
+	p_mtxcb->p_prevmtx = p_tcb->p_lastmtx;
+	p_tcb->p_lastmtx = p_mtxcb;
+	if (MTX_CEILING(p_mtxcb)
+					&& p_mtxcb->p_mtxinib->ceilpri < p_tcb->priority) {
+		change_priority(p_tcb, p_mtxcb->p_mtxinib->ceilpri, true);
+	}
+}
+
+#endif /* TOPPERS_mtxacq */
+
+/*
+ *  ミューテックスのロック解除
+ */
+#ifdef TOPPERS_mtxrel
+
+void
+mutex_release(MTXCB *p_mtxcb)
+{
+	TCB		*p_tcb;
+
+	if (queue_empty(&(p_mtxcb->wait_queue))) {
+		p_mtxcb->p_loctsk = NULL;
+	}
+	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;
+		p_mtxcb->p_prevmtx = p_tcb->p_lastmtx;
+		p_tcb->p_lastmtx = p_mtxcb;
+		if (MTX_CEILING(p_mtxcb)) {
+			if (p_mtxcb->p_mtxinib->ceilpri < p_tcb->priority) {
+				p_tcb->priority = p_mtxcb->p_mtxinib->ceilpri;
+			}
+		}
+		make_non_wait(p_tcb);
+	}
+}
+
+#endif /* TOPPERS_mtxrel */
+
+/*
+ *  タスクがロックしているすべてのミューテックスのロック解除
+ */
+#ifdef TOPPERS_mtxrela
+
+void
+mutex_release_all(TCB *p_tcb)
+{
+	MTXCB	*p_mtxcb;
+
+	while ((p_mtxcb = p_tcb->p_lastmtx) != NULL) {
+		p_tcb->p_lastmtx = p_mtxcb->p_prevmtx;
+		mutex_release(p_mtxcb);
+	}
+}
+
+#endif /* TOPPERS_mtxrela */
+
+/*
+ *  ミューテックスの生成［NGKI2022］
+ */
+#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();							/*［NGKI2023］［NGKI2024］*/
+
+	mtxatr = pk_cmtx->mtxatr;
+	ceilpri = pk_cmtx->ceilpri;
+
+	if (mtxatr == TA_CEILING) {
+		CHECK_PAR(VALID_TPRI(ceilpri));			/*［NGKI2037］*/
+	}
+	else {
+		CHECK_RSATR(mtxatr, TA_TPRI);			/*［NGKI2025］*/
+	}
+
+	lock_cpu();
+	if (tnum_mtx == 0 || queue_empty(&free_mtxcb)) {
+		ercd = E_NOID;							/*［NGKI2031］*/
+	}
+	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));
+		p_mtxcb->p_loctsk = NULL;				/*［NGKI2033］*/
+		ercd = MTXID(p_mtxcb);
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_MTX_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_mtx */
+
+/*
+ *  ミューテックスの削除［NGKI2056］
+ */
+#ifdef TOPPERS_del_mtx
+
+ER
+del_mtx(ID mtxid)
+{
+	MTXCB	*p_mtxcb, **pp_prevmtx;
+	MTXINIB	*p_mtxinib;
+	TCB		*p_loctsk;
+	ER		ercd;
+
+	LOG_DEL_MTX_ENTER(mtxid);
+	CHECK_TSKCTX_UNL();							/*［NGKI2057］［NGKI2058］*/
+	CHECK_ID(VALID_MTXID(mtxid));				/*［NGKI2059］*/
+	p_mtxcb = get_mtxcb(mtxid);
+
+	lock_cpu();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;							/*［NGKI2060］*/
+	}
+	else if (mtxid <= tmax_smtxid) {
+		ercd = E_OBJ;							/*［NGKI2062］*/
+	}
+	else {
+		init_wait_queue(&(p_mtxcb->wait_queue));	/*［NGKI2065］*/
+		p_loctsk = p_mtxcb->p_loctsk;
+		if (p_loctsk != NULL) {
+			/*
+			 *  p_loctskがロックしているミューテックスのリストから対象
+			 *  ミュークスを削除し，必要な場合にはp_loctskの現在優先度
+			 *  を変更する［NGKI2064］．
+			 */
+			pp_prevmtx = &(p_loctsk->p_lastmtx);
+			while (*pp_prevmtx != NULL) {
+				if (*pp_prevmtx == p_mtxcb) {
+					*pp_prevmtx = p_mtxcb->p_prevmtx;
+					break;
+				}
+				pp_prevmtx = &((*pp_prevmtx)->p_prevmtx);
+			}
+			mutex_drop_priority(p_loctsk, p_mtxcb);
+		}
+		p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib);
+		p_mtxinib->mtxatr = TA_NOEXS;						/*［NGKI2063］*/
+		queue_insert_prev(&free_mtxcb, &(p_mtxcb->wait_queue));
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_ID(VALID_MTXID(mtxid));
+	p_mtxcb = get_mtxcb(mtxid);
+
+	lock_cpu_dsp();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (MTX_CEILING(p_mtxcb)
+				&& p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+		ercd = E_ILUSE;
+	}
+	else if (p_mtxcb->p_loctsk == NULL) {
+		mutex_acquire(p_runtsk, p_mtxcb);
+		/*
+		 *  優先度上限ミューテックスをロックした場合，p_runtskの優先度
+		 *  が上がる可能性があるが，ディスパッチが必要になることはない．
+		 */
+		assert(p_runtsk == p_schedtsk);
+		ercd = E_OK;
+	}
+	else if (p_mtxcb->p_loctsk == p_runtsk) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_runtsk->tstat = TS_WAITING_MTX;
+		wobj_make_wait((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx);
+		dispatch();
+		ercd = winfo_mtx.winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  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_ID(VALID_MTXID(mtxid));
+	p_mtxcb = get_mtxcb(mtxid);
+
+	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) {
+		mutex_acquire(p_runtsk, p_mtxcb);
+		/*
+		 *  優先度上限ミューテックスをロックした場合，p_runtskの優先度
+		 *  が上がる可能性があるが，ディスパッチが必要になることはない．
+		 */
+		assert(p_runtsk == p_schedtsk);
+		ercd = E_OK;
+	}
+	else if (p_mtxcb->p_loctsk == p_runtsk) {
+		ercd = E_OBJ;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	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_ID(VALID_MTXID(mtxid));
+	CHECK_PAR(VALID_TMOUT(tmout));
+	p_mtxcb = get_mtxcb(mtxid);
+
+	lock_cpu_dsp();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (MTX_CEILING(p_mtxcb)
+				&& p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+		ercd = E_ILUSE;
+	}
+	else if (p_mtxcb->p_loctsk == NULL) {
+		mutex_acquire(p_runtsk, p_mtxcb);
+		/*
+		 *  優先度上限ミューテックスをロックした場合，p_runtskの優先度
+		 *  が上がる可能性があるが，ディスパッチが必要になることはない．
+		 */
+		assert(p_runtsk == p_schedtsk);
+		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_MTX;
+		wobj_make_wait_tmout((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_mtx.winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  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;
+	ER		ercd;
+    
+	LOG_UNL_MTX_ENTER(mtxid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_MTXID(mtxid));
+	p_mtxcb = get_mtxcb(mtxid);
+
+	lock_cpu();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_mtxcb != p_runtsk->p_lastmtx) {
+		ercd = E_OBJ;
+	}
+	else {
+		p_runtsk->p_lastmtx = p_mtxcb->p_prevmtx;
+		mutex_drop_priority(p_runtsk, p_mtxcb);
+		mutex_release(p_mtxcb);
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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, **pp_prevmtx;
+	TCB		*p_loctsk;
+	ER		ercd;
+    
+	LOG_INI_MTX_ENTER(mtxid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_MTXID(mtxid));
+	p_mtxcb = get_mtxcb(mtxid);
+
+	lock_cpu();
+	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		init_wait_queue(&(p_mtxcb->wait_queue));
+		p_loctsk = p_mtxcb->p_loctsk;
+		if (p_loctsk != NULL) {
+			p_mtxcb->p_loctsk = NULL;
+			pp_prevmtx = &(p_loctsk->p_lastmtx);
+			while (*pp_prevmtx != NULL) {
+				if (*pp_prevmtx == p_mtxcb) {
+					*pp_prevmtx = p_mtxcb->p_prevmtx;
+					break;
+				}
+				pp_prevmtx = &((*pp_prevmtx)->p_prevmtx);
+			}
+			mutex_drop_priority(p_loctsk, p_mtxcb);
+		}
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_ID(VALID_MTXID(mtxid));
+	p_mtxcb = get_mtxcb(mtxid);
+
+	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;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_REF_MTX_LEAVE(ercd, pk_rmtx);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_mtx */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mutex.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mutex.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mutex.h	(revision 398)
@@ -0,0 +1,180 @@
+/*
+ *  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$
+ */
+
+/*
+ *		ミューテックス機能
+ */
+
+#ifndef TOPPERS_MUTEX_H
+#define TOPPERS_MUTEX_H
+
+#include "kernel_impl.h"
+#include <queue.h>
+#include "wait.h"
+
+/*
+ *  ミューテックス初期化ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの初期化ブロックの共通部分
+ *  （WOBJINIB）を拡張（オブジェクト指向言語の継承に相当）したもので，
+ *  最初のフィールドが共通になっている．
+ */
+typedef struct mutex_initialization_block {
+	ATR			mtxatr;			/* ミューテックス属性 */
+	uint_t		ceilpri;		/* ミューテックスの上限優先度（内部表現）*/
+} MTXINIB;
+
+/*
+ *  ミューテックス管理ブロック
+ *
+ *  この構造体は，同期・通信オブジェクトの管理ブロックの共通部分（WOBJCB）
+ *  を拡張（オブジェクト指向言語の継承に相当）したもので，最初の2つの
+ *  フィールドが共通になっている．
+ */
+struct mutex_control_block {
+	QUEUE		wait_queue;		/* ミューテックス待ちキュー */
+	const MTXINIB *p_mtxinib;	/* 初期化ブロックへのポインタ */
+	TCB			*p_loctsk;		/* ミューテックスをロックしているタスク */
+	MTXCB		*p_prevmtx;		/* この前にロックしたミューテックス */
+};
+
+/*
+ *  ミューテックス待ち情報ブロックの定義
+ *
+ *  この構造体は，同期・通信オブジェクトの待ち情報ブロックの共通部分
+ *  （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	mutex_check_ceilpri(TCB *p_tcb, uint_t bpriority);
+
+/* 
+ *  優先度上限ミューテックスをロックしているかのチェック
+ *
+ *  p_tcbで指定されるタスクが優先度上限ミューテックスをロックしていれば
+ *  true，そうでなければfalseを返す．
+ */
+extern bool_t	mutex_scan_ceilmtx(TCB *p_tcb);
+
+/*
+ *  ミューテックスをロック解除した場合の現在優先度変更処理
+ *
+ *  p_tcbで指定されるタスクが，p_mtxcbで指定されるミューテックスをロッ
+ *  ク解除した際の現在優先度変更処理を行う．
+ */
+extern void	mutex_drop_priority(TCB *p_tcb, MTXCB *p_mtxcb);
+
+/*
+ *  ミューテックスのロック
+ *
+ *  p_tcbで指定されるタスクに，p_mtxcbで指定されるミューテックスをロッ
+ *  クさせる．
+ */
+extern void	mutex_acquire(TCB *p_tcb, MTXCB *p_mtxcb);
+
+/*
+ *  ミューテックスのロック解除
+ *
+ *  p_mtxcbで指定されるミューテックスをロック解除する．ロック解除した
+ *  ミューテックスに，ロック待ち状態のタスクがある場合には，そのタスク
+ *  にミューテックスをロックさせる．
+ */
+extern void	mutex_release(MTXCB *p_mtxcb);
+
+/*
+ *  タスクがロックしているすべてのミューテックスのロック解除
+ *
+ *  p_tcbで指定されるタスクに，それがロックしているすべてのミューテック
+ *  スをロック解除させる．ロック解除したミューテックスに，ロック待ち状
+ *  態のタスクがある場合には，そのタスクにミューテックスをロックさせる．
+ *
+ *  この関数は，タスクの終了時に使われるものであるため，p_tcbで指定され
+ *  るタスクの優先度を変更する処理は行わない．ただし，この関数の中で他
+ *  のタスクの優先度が変化し，実行すべきタスクが変わることがある．その
+ *  ため，この関数から戻った後に，ディスパッチが必要か判別して，必要な
+ *  場合にはディスパッチを行わなければならない．
+ */
+extern void	mutex_release_all(TCB *p_tcb);
+
+#endif /* TOPPERS_MUTEX_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mutex.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mutex.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/mutex.trb	(revision 398)
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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$
+# 
+
+#
+#		ミューテックス機能の生成スクリプト
+#
+
+class MutexObject < KernelObject
+  def initialize()
+    super("mtx", "mutex")
+  end
+
+  def prepare(key, params)
+    # mtxatrが無効の場合（E_RSATR）［NGKI2025］
+    # （TA_NULL，TA_TPRI，TA_CEILINGのいずれでもない場合）
+    if !(params[:mtxatr] == $TA_NULL || params[:mtxatr] == $TA_TPRI \
+										|| params[:mtxatr] == $TA_CEILING)
+      error_illegal_id("E_RSATR", params, :mtxatr, :mtxid)
+    end
+
+    if params[:mtxatr] == $TA_CEILING
+      # 優先度上限ミューテックスの場合
+      # ceilpriが未指定の場合はエラーとする
+      if params[:ceilpri].nil?
+        error_api(params, "ceilpri must be specified in %apiname of %mtxid")
+
+      # (TMIN_TPRI <= ceilpri && ceilpri <= TMAX_TPRI)でない場合（E_PAR）
+      # ［NGKI2037］
+      elsif !($TMIN_TPRI <= params[:ceilpri] && params[:ceilpri] <= $TMAX_TPRI)
+        error_illegal_id("E_PAR", params, :ceilpri, :mtxid)
+      end
+    else
+      # 優先度上限ミューテックスでない場合
+      # ceilpriが指定されている場合は警告メッセージを出す
+      if !params[:ceilpri].nil?
+        warning_api(params, "%%ceilpri is ignored in %apiname of %mtxid")
+      end
+      params[:ceilpri] = 0
+    end
+  end
+
+  def generateInib(key, params)
+    return("(#{params[:mtxatr]}), INT_PRIORITY(#{params[:ceilpri]})")
+  end
+end
+
+#
+#  ミューテックスに関する情報の生成
+#
+$kernelCfgC.comment_header("Mutex Functions")
+MutexObject.new.generate()
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/pridataq.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/pridataq.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/pridataq.c	(revision 398)
@@ -0,0 +1,801 @@
+/*
+ *  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-2016 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_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, p_data, p_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, p_data, p_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, p_data, p_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)
+{
+	TCB		*p_tcb;
+
+	if (!queue_empty(&(p_pdqcb->rwait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->rwait_queue));
+		((WINFO_RPDQ *)(p_tcb->p_winfo))->data = data;
+		((WINFO_RPDQ *)(p_tcb->p_winfo))->datapri = datapri;
+		wait_complete(p_tcb);
+		return(true);
+	}
+	else if (p_pdqcb->count < p_pdqcb->p_pdqinib->pdqcnt) {
+		enqueue_pridata(p_pdqcb, data, datapri);
+		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)
+{
+	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_SPDQ *)(p_tcb->p_winfo))->data;
+			datapri = ((WINFO_SPDQ *)(p_tcb->p_winfo))->datapri;
+			enqueue_pridata(p_pdqcb, data, datapri);
+			wait_complete(p_tcb);
+		}
+		return(true);
+	}
+	else if (!queue_empty(&(p_pdqcb->swait_queue))) {
+		p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->swait_queue));
+		*p_data = ((WINFO_SPDQ *)(p_tcb->p_winfo))->data;
+		*p_datapri = ((WINFO_SPDQ *)(p_tcb->p_winfo))->datapri;
+		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;
+	uint_t	pdqcnt;
+	PRI		maxdpri;
+	PDQMB	*p_pdqmb;
+	ER		ercd;
+
+	LOG_ACRE_PDQ_ENTER(pk_cpdq);
+	CHECK_TSKCTX_UNL();
+
+	pdqatr = pk_cpdq->pdqatr;
+	pdqcnt = pk_cpdq->pdqcnt;
+	maxdpri = pk_cpdq->maxdpri;
+	p_pdqmb = pk_cpdq->pdqmb;
+
+	CHECK_RSATR(pdqatr, TA_TPRI);
+	CHECK_PAR(VALID_DPRI(maxdpri));
+
+	lock_cpu();
+	if (tnum_pdq == 0 || queue_empty(&free_pdqcb)) {
+		ercd = E_NOID;
+	}
+	else {
+		if (pdqcnt != 0 && p_pdqmb == NULL) {
+			p_pdqmb = kernel_malloc(sizeof(PDQMB) * pdqcnt);
+			pdqatr |= TA_MBALLOC;
+		}
+		if (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 = pdqcnt;
+			p_pdqinib->maxdpri = 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);
+		}
+	}
+	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;
+	ER		ercd;
+
+	LOG_DEL_PDQ_ENTER(pdqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_PDQID(pdqid));
+	p_pdqcb = get_pdqcb(pdqid);
+
+	lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (pdqid <= tmax_spdqid) {
+		ercd = E_OBJ;
+	}
+	else {
+		init_wait_queue(&(p_pdqcb->swait_queue));
+		init_wait_queue(&(p_pdqcb->rwait_queue));
+		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 (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_SPDQ winfo_spdq;
+	ER		ercd;
+
+	LOG_SND_PDQ_ENTER(pdqid, data, datapri);
+	CHECK_DISPATCH();
+	CHECK_ID(VALID_PDQID(pdqid));
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	lock_cpu_dsp();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (datapri > p_pdqcb->p_pdqinib->maxdpri) {
+		ercd = E_PAR;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (send_pridata(p_pdqcb, data, datapri)) {
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		winfo_spdq.data = data;
+		winfo_spdq.datapri = datapri;
+		p_runtsk->tstat = TS_WAITING_SPDQ;
+		wobj_make_wait((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_spdq);
+		dispatch();
+		ercd = winfo_spdq.winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  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;
+	ER		ercd;
+
+	LOG_PSND_PDQ_ENTER(pdqid, data, datapri);
+	CHECK_UNL();
+	CHECK_ID(VALID_PDQID(pdqid));
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	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)) {
+		if (p_runtsk != p_schedtsk) {
+			if (!sense_context()) {
+				dispatch();
+			}
+			else {
+				request_dispatch();
+			}
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_PSND_PDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_psnd_pdq */
+
+/*
+ *  優先度データキューへの送信（タイムアウトあり）
+ */
+#ifdef TOPPERS_tsnd_pdq
+
+ER
+tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout)
+{
+	PDQCB	*p_pdqcb;
+	WINFO_SPDQ winfo_spdq;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout);
+	CHECK_DISPATCH();
+	CHECK_ID(VALID_PDQID(pdqid));
+	CHECK_PAR(VALID_TMOUT(tmout));
+	p_pdqcb = get_pdqcb(pdqid);
+	CHECK_PAR(TMIN_DPRI <= datapri);
+
+	lock_cpu_dsp();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (datapri > p_pdqcb->p_pdqinib->maxdpri) {
+		ercd = E_PAR;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (send_pridata(p_pdqcb, data, datapri)) {
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		winfo_spdq.data = data;
+		winfo_spdq.datapri = datapri;
+		p_runtsk->tstat = TS_WAITING_SPDQ;
+		wobj_make_wait_tmout((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_spdq,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_spdq.winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  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_RPDQ winfo_rpdq;
+	ER		ercd;
+
+	LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri);
+	CHECK_DISPATCH();
+	CHECK_ID(VALID_PDQID(pdqid));
+	p_pdqcb = get_pdqcb(pdqid);
+
+	lock_cpu_dsp();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (receive_pridata(p_pdqcb, p_data, p_datapri)) {
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = TS_WAITING_RPDQ;
+		make_wait(&(winfo_rpdq.winfo));
+		queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_rpdq.p_pdqcb = p_pdqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_rpdq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_rpdq.data;
+			*p_datapri = winfo_rpdq.datapri;
+		}
+	}
+	unlock_cpu_dsp();
+
+  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;
+	ER		ercd;
+
+	LOG_PRCV_PDQ_ENTER(pdqid, p_data, p_datapri);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_PDQID(pdqid));
+	p_pdqcb = get_pdqcb(pdqid);
+
+	lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (receive_pridata(p_pdqcb, p_data, p_datapri)) {
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_TMOUT;
+	}
+	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_RPDQ winfo_rpdq;
+	TMEVTB	tmevtb;
+	ER		ercd;
+
+	LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout);
+	CHECK_DISPATCH();
+	CHECK_ID(VALID_PDQID(pdqid));
+	CHECK_PAR(VALID_TMOUT(tmout));
+	p_pdqcb = get_pdqcb(pdqid);
+
+	lock_cpu_dsp();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (receive_pridata(p_pdqcb, p_data, p_datapri)) {
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (tmout == TMO_POL) {
+		ercd = E_TMOUT;
+	}
+	else {
+		p_runtsk->tstat = TS_WAITING_RPDQ;
+		make_wait_tmout(&(winfo_rpdq.winfo), &tmevtb, tmout);
+		queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
+		winfo_rpdq.p_pdqcb = p_pdqcb;
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo_rpdq.winfo.wercd;
+		if (ercd == E_OK) {
+			*p_data = winfo_rpdq.data;
+			*p_datapri = winfo_rpdq.datapri;
+		}
+	}
+	unlock_cpu_dsp();
+
+  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;
+	ER		ercd;
+    
+	LOG_INI_PDQ_ENTER(pdqid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_PDQID(pdqid));
+	p_pdqcb = get_pdqcb(pdqid);
+
+	lock_cpu();
+	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		init_wait_queue(&(p_pdqcb->swait_queue));
+		init_wait_queue(&(p_pdqcb->rwait_queue));
+		p_pdqcb->count = 0U;
+		p_pdqcb->p_head = NULL;
+		p_pdqcb->unused = 0U;
+		p_pdqcb->p_freelist = NULL;
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_ID(VALID_PDQID(pdqid));
+	p_pdqcb = get_pdqcb(pdqid);
+
+	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;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_REF_PDQ_LEAVE(ercd, pk_rpdq);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_pdq */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/pridataq.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/pridataq.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/pridataq.h	(revision 398)
@@ -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) 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_PRIDATAQ_H
+#define TOPPERS_PRIDATAQ_H
+
+#include "kernel_impl.h"
+#include <queue.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_send_waiting_information {
+	WINFO		winfo;			/* 標準の待ち情報ブロック */
+	PDQCB		*p_pdqcb;		/* 待っている優先度データキューの管理ブロック*/
+	intptr_t	data;			/* 送信データ */
+	PRI			datapri;		/* データ優先度 */
+} WINFO_SPDQ;
+
+typedef struct pridataq_receive_waiting_information {
+	WINFO		winfo;			/* 標準の待ち情報ブロック */
+	PDQCB		*p_pdqcb;		/* 待っている優先度データキューの管理ブロック*/
+	intptr_t	data;			/* 受信データ */
+	PRI			datapri;		/* データ優先度 */
+} WINFO_RPDQ;
+
+/*
+ *  使用していない優先度データキュー管理ブロックのリスト
+ */
+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);
+
+/*
+ *  優先度データキューからのデータ受信
+ */
+extern bool_t	receive_pridata(PDQCB *p_pdqcb, intptr_t *p_data,
+														PRI *p_datapri);
+
+#endif /* TOPPERS_PRIDATAQ_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/pridataq.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/pridataq.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/pridataq.trb	(revision 398)
@@ -0,0 +1,93 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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$
+# 
+
+#
+#		優先度データキュー機能の生成スクリプト
+#
+
+class PridataqObject < KernelObject
+  def initialize()
+    super("pdq", "pridataq")
+  end
+
+  def prepare(key, params)
+    # パラメータが省略された時のデフォルト値の設定
+    params[:pdqmb] ||= "NULL"
+
+    # pdqatrが無効の場合（E_RSATR）［NGKI1804］
+    #（TA_TPRI以外のビットがセットされている場合）
+    if (params[:pdqatr] & ~($TA_TPRI)) != 0
+      error_illegal_id("E_RSATR", params, :pdqatr, :pdqid)
+    end
+
+    # (TMIN_DPRI <= maxdpri && maxdpri <= TMAX_DPRI)でない場合（E_PAR）
+    # ［NGKI1819］
+    if !($TMIN_DPRI <= params[:maxdpri] && params[:maxdpri] <= $TMAX_DPRI)
+      error_illegal_id("E_PAR", params, :maxdpri, :pdqid)
+    end
+
+    # pdqmbがNULLでない場合（E_NOSPT）［ASPS0142］
+    if params[:pdqmb] != "NULL"
+      error_illegal_id("E_NOSPT", params, :pdqmb, :pdqid)
+    end
+
+    # 優先度データキュー管理領域
+    if params[:pdqcnt] > 0
+      pdqmbName = "_kernel_pdqmb_#{params[:pdqid]}"
+      $kernelCfgC.add("static PDQMB #{pdqmbName}[#{params[:pdqcnt]}];")
+      params[:pdqinib_pdqmb] = pdqmbName
+    else
+      params[:pdqinib_pdqmb] = "NULL"
+    end
+  end
+
+  def generateInib(key, params)
+    return("(#{params[:pdqatr]}), (#{params[:pdqcnt]}), " \
+				"(#{params[:maxdpri]}), #{params[:pdqinib_pdqmb]}")
+  end
+end
+
+#
+#  優先度データキューに関する情報の生成
+#
+$kernelCfgC.comment_header("Priority Dataqueue Functions")
+PridataqObject.new.generate()
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/semaphore.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/semaphore.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/semaphore.c	(revision 398)
@@ -0,0 +1,506 @@
+/*
+ *  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-2016 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_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;
+	ATR		sematr;
+	uint_t	isemcnt, maxsem;
+	ER		ercd;
+
+	LOG_ACRE_SEM_ENTER(pk_csem);
+	CHECK_TSKCTX_UNL();
+
+	sematr = pk_csem->sematr;
+	isemcnt = pk_csem->isemcnt;
+	maxsem = pk_csem->maxsem;
+
+	CHECK_RSATR(sematr, TA_TPRI);
+	CHECK_PAR(0 <= isemcnt && isemcnt <= maxsem);
+	CHECK_PAR(1 <= maxsem && maxsem <= TMAX_MAXSEM);
+
+	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 = sematr;
+		p_seminib->isemcnt = isemcnt;
+		p_seminib->maxsem = maxsem;
+
+		queue_initialize(&(p_semcb->wait_queue));
+		p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
+		ercd = SEMID(p_semcb);
+	}
+	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;
+	ER		ercd;
+
+	LOG_DEL_SEM_ENTER(semid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_SEMID(semid));
+	p_semcb = get_semcb(semid);
+
+	lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (semid <= tmax_ssemid) {
+		ercd = E_OBJ;
+	}
+	else {
+		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 (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_UNL();
+	CHECK_ID(VALID_SEMID(semid));
+	p_semcb = get_semcb(semid);
+
+	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));
+		wait_complete(p_tcb);
+		if (p_runtsk != p_schedtsk) {
+			if (!sense_context()) {
+				dispatch();
+			}
+			else {
+				request_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;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_SIG_SEM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_sig_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_ID(VALID_SEMID(semid));
+	p_semcb = get_semcb(semid);
+
+	lock_cpu_dsp();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (p_semcb->semcnt >= 1) {
+		p_semcb->semcnt -= 1;
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = TS_WAITING_SEM;
+		wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
+		dispatch();
+		ercd = winfo_sem.winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  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_ID(VALID_SEMID(semid));
+	p_semcb = get_semcb(semid);
+
+	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;
+	}
+	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_ID(VALID_SEMID(semid));
+	CHECK_PAR(VALID_TMOUT(tmout));
+	p_semcb = get_semcb(semid);
+
+	lock_cpu_dsp();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	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_SEM;
+		wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
+														&tmevtb, tmout);
+		dispatch();
+		ercd = winfo_sem.winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  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;
+	ER		ercd;
+    
+	LOG_INI_SEM_ENTER(semid);
+	CHECK_TSKCTX_UNL();
+	CHECK_ID(VALID_SEMID(semid));
+	p_semcb = get_semcb(semid);
+
+	lock_cpu();
+	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else {
+		init_wait_queue(&(p_semcb->wait_queue));
+		p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	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_ID(VALID_SEMID(semid));
+	p_semcb = get_semcb(semid);
+
+	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;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_REF_SEM_LEAVE(ercd, pk_rsem);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_sem */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/semaphore.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/semaphore.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/semaphore.h	(revision 398)
@@ -0,0 +1,124 @@
+/*
+ *  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-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_SEMAPHORE_H
+#define TOPPERS_SEMAPHORE_H
+
+#include "kernel_impl.h"
+#include <queue.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_mbedtls/trunk/asp3_dcre/kernel/semaphore.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/semaphore.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/semaphore.trb	(revision 398)
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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$
+# 
+
+#
+#		セマフォ機能の生成スクリプト
+#
+
+class SemaphoreObject < KernelObject
+  def initialize()
+    super("sem", "semaphore")
+  end
+
+  def prepare(key, params)
+    # sematrが無効の場合（E_RSATR）［NGKI1456］
+    #（TA_TPRI以外のビットがセットされている場合）
+    if (params[:sematr] & ~($TA_TPRI)) != 0
+      error_illegal_id("E_RSATR", params, :sematr, :semid)
+    end
+
+    # (1 <= maxsem && maxsem <= TMAX_MAXSEM)でない場合（E_PAR）［NGKI1468］
+    if !(1 <= params[:maxsem] && params[:maxsem] <= $TMAX_MAXSEM)
+      error_illegal_id("E_PAR", params, :maxsem, :semid)
+    end
+
+    # (0 <= isemcnt && isemcnt <= maxsem)でない場合（E_PAR）［NGKI1466］
+    if !(0 <= params[:isemcnt] && params[:isemcnt] <= params[:maxsem])
+      error_wrong_id("E_PAR", params, :isemcnt, :semid, "too large")
+    end
+  end
+
+  def generateInib(key, params)
+    return("(#{params[:sematr]}), (#{params[:isemcnt]}), (#{params[:maxsem]})")
+  end
+end
+
+#
+#  セマフォに関する情報の生成
+#
+$kernelCfgC.comment_header("Semaphore Functions")
+SemaphoreObject.new.generate()
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/startup.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/startup.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/startup.c	(revision 398)
@@ -0,0 +1,223 @@
+/*
+ *  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-2016 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)
+{
+	/*
+	 *  TECSの初期化
+	 */
+#ifndef TOPPERS_OMIT_TECS
+	initialize_tecs();
+#endif /* TOPPERS_OMIT_TECS */
+
+	/*
+	 *  ターゲット依存の初期化
+	 */
+	target_initialize();
+
+	/*
+	 *  各モジュールの初期化
+	 *
+	 *  タイムイベント管理モジュールは他のモジュールより先に初期化
+	 *  する必要がある．
+	 */
+	initialize_kmm();
+	initialize_tmevt();								/*［ASPD1061］*/
+	initialize_object();
+
+	/*
+	 *  初期化ルーチンの実行
+	 */ 
+	call_inirtn();
+
+	/*
+	 *  高分解能タイマの設定
+	 */
+	current_hrtcnt = target_hrt_get_current();		/*［ASPD1063］*/
+	set_hrt_event();								/*［ASPD1064］*/
+
+	/*
+	 *  カーネル動作の開始
+	 */
+	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_t 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_mbedtls/trunk/asp3_dcre/kernel/sys_manage.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/sys_manage.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/sys_manage.c	(revision 398)
@@ -0,0 +1,515 @@
+/*
+ *  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 "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_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, p_tskid)
+#endif /* LOG_GET_TID_LEAVE */
+
+#ifndef LOG_GET_LOD_ENTER
+#define LOG_GET_LOD_ENTER(tskpri, p_load)
+#endif /* LOG_GET_LOD_ENTER */
+
+#ifndef LOG_GET_LOD_LEAVE
+#define LOG_GET_LOD_LEAVE(ercd, p_load)
+#endif /* LOG_GET_LOD_LEAVE */
+
+#ifndef LOG_GET_NTH_ENTER
+#define LOG_GET_NTH_ENTER(tskpri, nth, p_tskid)
+#endif /* LOG_GET_NTH_ENTER */
+
+#ifndef LOG_GET_NTH_LEAVE
+#define LOG_GET_NTH_LEAVE(ercd, p_tskid)
+#endif /* LOG_GET_NTH_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_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_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 */
+
+/*
+ *  タスクの優先順位の回転［NGKI3548］
+ */
+#ifdef TOPPERS_rot_rdq
+
+ER
+rot_rdq(PRI tskpri)
+{
+	uint_t	pri;
+	ER		ercd;
+
+	LOG_ROT_RDQ_ENTER(tskpri);
+	CHECK_UNL();								/*［NGKI2684］*/
+	if (tskpri == TPRI_SELF && !sense_context()) {
+		pri = p_runtsk->bpriority;				/*［NGKI2689］*/
+	}
+	else {
+		CHECK_PAR(VALID_TPRI(tskpri));			/*［NGKI2685］*/
+		pri = INT_PRIORITY(tskpri);
+	}
+
+	lock_cpu();
+	rotate_ready_queue(&(ready_queue[pri]));
+	if (p_runtsk != p_schedtsk) {
+		if (!sense_context()) {
+			dispatch();
+		}
+		else {
+			request_dispatch();
+		}
+	}
+	ercd = E_OK;
+	unlock_cpu();
+
+  error_exit:
+	LOG_ROT_RDQ_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rot_rdq */
+
+/*
+ *  実行状態のタスクIDの参照［NGKI3550］
+ */
+#ifdef TOPPERS_get_tid
+
+ER
+get_tid(ID *p_tskid)
+{
+	ER		ercd;
+
+	LOG_GET_TID_ENTER(p_tskid);
+	CHECK_UNL();								/*［NGKI2707］*/
+
+	lock_cpu();
+	*p_tskid = (p_runtsk == NULL) ? TSK_NONE : TSKID(p_runtsk);
+	ercd = E_OK;
+	unlock_cpu();
+
+  error_exit:
+	LOG_GET_TID_LEAVE(ercd, p_tskid);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_tid */
+
+/*
+ *  実行できるタスクの数の参照［NGKI3623］
+ */
+#ifdef TOPPERS_get_lod
+
+ER
+get_lod(PRI tskpri, uint_t *p_load)
+{
+	uint_t	pri, load;
+	QUEUE	*p_queue, *p_entry;
+	ER		ercd;
+
+	LOG_GET_LOD_ENTER(p_tskid, p_load);
+	CHECK_TSKCTX_UNL();							/*［NGKI3624］［NGKI3625］*/
+	if (tskpri == TPRI_SELF) {
+		pri = p_runtsk->bpriority;				/*［NGKI3631］*/
+	}
+	else {
+		CHECK_PAR(VALID_TPRI(tskpri));			/*［NGKI3626］*/
+		pri = INT_PRIORITY(tskpri);
+	}
+	p_queue = &(ready_queue[pri]);
+
+	lock_cpu();
+	load = 0U;
+	for (p_entry = p_queue->p_next; p_entry != p_queue;
+										p_entry = p_entry->p_next) {
+		load += 1U;
+	}
+	*p_load = load;
+	ercd = E_OK;
+	unlock_cpu();
+
+  error_exit:
+	LOG_GET_LOD_LEAVE(ercd, p_load);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_lod */
+
+/*
+ *  指定した優先順位のタスクIDの参照［NGKI3641］
+ */
+#ifdef TOPPERS_get_nth
+
+ER
+get_nth(PRI tskpri, uint_t nth, ID *p_tskid)
+{
+	uint_t	pri;
+	QUEUE	*p_queue, *p_entry;
+	ID		tskid;
+	ER		ercd;
+
+	LOG_GET_NTH_ENTER(p_tskid, nth, p_tskid);
+	CHECK_TSKCTX_UNL();							/*［NGKI3642］［NGKI3643］*/
+	if (tskpri == TPRI_SELF) {
+		pri = p_runtsk->bpriority;				/*［NGKI3650］*/
+	}
+	else {
+		CHECK_PAR(VALID_TPRI(tskpri));			/*［NGKI3644］*/
+		pri = INT_PRIORITY(tskpri);
+	}
+	p_queue = &(ready_queue[pri]);
+
+	lock_cpu();
+	tskid = TSK_NONE;
+	for (p_entry = p_queue->p_next; p_entry != p_queue;
+										p_entry = p_entry->p_next) {
+		if (nth == 0U) {
+			tskid = TSKID((TCB *) p_entry);
+			break;
+		}
+		nth -= 1U;
+	}
+	*p_tskid = tskid;
+	ercd = E_OK;
+	unlock_cpu();
+
+  error_exit:
+	LOG_GET_NTH_LEAVE(ercd, p_tskid);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_nth */
+
+/*
+ *  CPUロック状態への遷移［NGKI3538］
+ */
+#ifdef TOPPERS_loc_cpu
+
+ER
+loc_cpu(void)
+{
+	ER		ercd;
+
+	LOG_LOC_CPU_ENTER();
+
+	if (!sense_lock()) {						/*［NGKI2731］*/
+		lock_cpu();								/*［NGKI2730］*/
+	}
+	ercd = E_OK;
+
+	LOG_LOC_CPU_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_loc_cpu */
+
+/*
+ *  CPUロック状態の解除［NGKI3539］
+ *
+ *  CPUロック中は，ディスパッチが必要となるサービスコールを呼び出すこ
+ *  とはできないため，CPUロック状態の解除時にディスパッチャを起動する
+ *  必要はない．
+ */
+#ifdef TOPPERS_unl_cpu
+
+ER
+unl_cpu(void)
+{
+	ER		ercd;
+
+	LOG_UNL_CPU_ENTER();
+
+	if (sense_lock()) {							/*［NGKI2738］*/
+		unlock_cpu();							/*［NGKI2737］*/
+	}
+	ercd = E_OK;
+
+	LOG_UNL_CPU_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_unl_cpu */
+
+/*
+ *  ディスパッチの禁止［NGKI2740］
+ */
+#ifdef TOPPERS_dis_dsp
+
+ER
+dis_dsp(void)
+{
+	ER		ercd;
+
+	LOG_DIS_DSP_ENTER();
+	CHECK_TSKCTX_UNL();							/*［NGKI2741］［NGKI2742］*/
+
+	lock_cpu();
+	enadsp = false;
+	dspflg = false;
+	ercd = E_OK;
+	unlock_cpu();
+
+  error_exit:
+	LOG_DIS_DSP_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_dis_dsp */
+
+/*
+ *  ディスパッチの許可［NGKI2746］
+ */
+#ifdef TOPPERS_ena_dsp
+
+ER
+ena_dsp(void)
+{
+	ER		ercd;
+
+	LOG_ENA_DSP_ENTER();
+	CHECK_TSKCTX_UNL();							/*［NGKI2747］［NGKI2748］*/
+
+	lock_cpu();
+	enadsp = true;
+	if (t_get_ipm() == TIPM_ENAALL) {
+		dspflg = true;
+		p_schedtsk = search_schedtsk();
+		if (p_runtsk->raster && p_runtsk->enater) {
+			task_terminate(p_runtsk);
+			exit_and_dispatch();
+			ercd = E_SYS;
+		}
+		else {
+			if (p_runtsk != p_schedtsk) {
+				dispatch();
+			}
+			ercd = E_OK;
+		}
+	}
+	else {
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_ENA_DSP_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ena_dsp */
+
+/*
+ *  コンテキストの参照［NGKI2752］
+ */
+#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ロック状態の参照［NGKI2754］
+ */
+#ifdef TOPPERS_sns_loc
+
+bool_t
+sns_loc(void)
+{
+	bool_t	state;
+
+	LOG_SNS_LOC_ENTER();
+	state = sense_lock() ? true : false;
+	LOG_SNS_LOC_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_loc */
+
+/*
+ *  ディスパッチ禁止状態の参照［NGKI2756］
+ */
+#ifdef TOPPERS_sns_dsp
+
+bool_t
+sns_dsp(void)
+{
+	bool_t	state;
+
+	LOG_SNS_DSP_ENTER();
+	state = !enadsp;
+	LOG_SNS_DSP_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_dsp */
+
+/*
+ *  ディスパッチ保留状態の参照［NGKI2758］
+ */
+#ifdef TOPPERS_sns_dpn
+
+bool_t
+sns_dpn(void)
+{
+	bool_t	state;
+
+	LOG_SNS_DPN_ENTER();
+	state = (sense_context() || sense_lock() || !dspflg) ? true : false;
+	LOG_SNS_DPN_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_dpn */
+
+/*
+ *  カーネル非動作状態の参照［NGKI2760］
+ */
+#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_mbedtls/trunk/asp3_dcre/kernel/task.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task.c	(revision 398)
@@ -0,0 +1,441 @@
+/*
+ *  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 "task.h"
+#include "taskhook.h"
+#include "wait.h"
+
+#ifdef TOPPERS_tskini
+
+/*
+ *  実行状態のタスク
+ */
+TCB		*p_runtsk;
+
+/*
+ *  実行すべきタスク
+ */
+TCB		*p_schedtsk;
+
+/*
+ *  ディスパッチ許可状態
+ */
+bool_t	enadsp;
+
+/*
+ *  タスクディスパッチ可能状態
+ */
+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;
+	enadsp = true;
+	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);
+		if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
+			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
+
+void
+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 (dspflg) {
+		if (p_schedtsk == (TCB *) NULL || pri < p_schedtsk->priority) {
+			p_schedtsk = p_tcb;
+		}
+	}
+}
+
+#endif /* TOPPERS_tskrun */
+
+/*
+ *  実行できる状態から他の状態への遷移
+ *
+ *  実行すべきタスクを更新するのは，p_tcbが実行すべきタスクであった場合
+ *  である．p_tcbと同じ優先度のタスクが他にある場合は，p_tcbの次のタス
+ *  クが実行すべきタスクになる．そうでない場合は，レディキューをサーチ
+ *  する必要がある．
+ */
+#ifdef TOPPERS_tsknrun
+
+void
+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) {
+			assert(dspflg);
+			p_schedtsk = primap_empty() ? (TCB *) NULL : search_schedtsk();
+		}
+	}
+	else {
+		if (p_schedtsk == p_tcb) {
+			assert(dspflg);
+			p_schedtsk = (TCB *)(p_queue->p_next);
+		}
+	}
+}
+
+#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->raster = false;
+	p_tcb->enater = true;
+	LOG_TSKSTAT(p_tcb);
+}
+
+#endif /* TOPPERS_tskdmt */
+
+/*
+ *  休止状態から実行できる状態への遷移
+ */
+#ifdef TOPPERS_tskact
+
+void
+make_active(TCB *p_tcb)
+{
+	activate_context(p_tcb);
+	p_tcb->tstat = TS_RUNNABLE;
+	LOG_TSKSTAT(p_tcb);
+	make_runnable(p_tcb);
+}
+
+#endif /* TOPPERS_tskact */
+
+/*
+ *  タスクの優先度の変更
+ *
+ *  タスクが実行できる状態の場合には，レディキューの中での位置を変更す
+ *  る．オブジェクトの待ちキューの中で待ち状態になっている場合には，待
+ *  ちキューの中での位置を変更する．
+ *
+ *  実行すべきタスクを更新するのは，(1) p_tcbが実行すべきタスクであって，
+ *  その優先度を下げた場合，(2) p_tcbが実行すべきタスクではなく，変更後
+ *  の優先度が実行すべきタスクの優先度よりも高い場合である．(1)の場合に
+ *  は，レディキューをサーチする必要がある．
+ */
+#ifdef TOPPERS_tskpri
+
+void
+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 (dspflg) {
+			if (p_schedtsk == p_tcb) {
+				if (newpri >= oldpri) {
+					p_schedtsk = search_schedtsk();
+				}
+			}
+			else {
+				if (mtxmode ? newpri <= p_schedtsk->priority
+							: newpri < p_schedtsk->priority) {
+					p_schedtsk = p_tcb;
+				}
+			}
+		}
+	}
+	else {
+		if (TSTAT_WAIT_WOBJCB(p_tcb->tstat)) {
+			/*
+			 *  タスクが，同期・通信オブジェクトの管理ブロックの共通部
+			 *  分（WOBJCB）の待ちキューにつながれている場合
+			 */
+			wobj_change_priority(((WINFO_WOBJ *)(p_tcb->p_winfo))->p_wobjcb,
+																	p_tcb);
+		}
+	}
+}
+
+#endif /* TOPPERS_tskpri */
+
+/*
+ *  レディキューの回転
+ *
+ *  実行すべきタスクを更新するのは，実行すべきタスクがタスクキューの末
+ *  尾に移動した場合である．
+ */
+#ifdef TOPPERS_tskrot
+
+void
+rotate_ready_queue(QUEUE *p_queue)
+{
+	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 (dspflg) {
+			if (p_schedtsk == (TCB *) p_entry) {
+				p_schedtsk = (TCB *)(p_queue->p_next);
+			}
+		}
+	}
+}
+
+#endif /* TOPPERS_tskrot */
+
+/*
+ *  タスクの終了処理
+ */
+#ifdef TOPPERS_tskterm
+
+void
+task_terminate(TCB *p_tcb)
+{
+	if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+		make_non_runnable(p_tcb);
+	}
+	else if (TSTAT_WAITING(p_tcb->tstat)) {
+		wait_dequeue_wobj(p_tcb);
+		wait_dequeue_tmevtb(p_tcb);
+	}
+	if (p_tcb->p_lastmtx != NULL) {
+		(*mtxhook_release_all)(p_tcb);
+	}
+	make_dormant(p_tcb);
+	if (p_tcb->actque) {
+		p_tcb->actque = false;
+		make_active(p_tcb);
+	}
+}
+
+#endif /* TOPPERS_tskterm */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task.h	(revision 398)
@@ -0,0 +1,440 @@
+/*
+ *  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$
+ */
+
+/*
+ *		タスク管理モジュール
+ */
+
+#ifndef TOPPERS_TASK_H
+#define TOPPERS_TASK_H
+
+#include "kernel_impl.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_WAITING_???で待ち
+ *  要因を表す．待ち要因（5ビットで表現される）の上位2ビットで，同期・
+ *  通信オブジェクトの待ちキューにつながっているかどうかを表す．同期・
+ *  通信オブジェクトの待ちキューにつながらないものは上位2ビットを00，同
+ *  期・通信オブジェクトの管理ブロックの共通部分（WOBJCB）の待ちキュー
+ *  につながるものは10または11，それ以外の待ちキューにつながるものは01
+ *  とする．
+ */
+#define TS_DORMANT		0x00U			/* 休止状態 */
+#define TS_RUNNABLE		0x01U			/* 実行できる状態 */
+#define TS_SUSPENDED	0x02U			/* 強制待ち状態 */
+
+#define TS_WAITING_SLP	(0x01U << 2)	/* 起床待ち */
+#define TS_WAITING_DLY	(0x02U << 2)	/* 時間経過待ち */
+#define TS_WAITING_RDTQ	(0x08U << 2)	/* データキューからの受信待ち */
+#define TS_WAITING_RPDQ	(0x09U << 2)	/* 優先度データキューからの受信待ち */
+#define TS_WAITING_SEM	(0x10U << 2)	/* セマフォ資源の獲得待ち */
+#define TS_WAITING_FLG	(0x11U << 2)	/* イベントフラグ待ち */
+#define TS_WAITING_SDTQ	(0x12U << 2)	/* データキューへの送信待ち */
+#define TS_WAITING_SPDQ	(0x13U << 2)	/* 優先度データキューへの送信待ち */
+#define TS_WAITING_MTX	(0x14U << 2)	/* ミューテックスのロック待ち */
+#define TS_WAITING_MPF	(0x15U << 2)	/* 固定長メモリブロックの獲得待ち */
+
+#define TS_WAITING_MASK	(0x1fU << 2)	/* 待ち状態の判別用マスク */
+
+/*
+ *  タスク状態判別マクロ
+ *
+ *  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_MASK) != 0U)
+#define TSTAT_SUSPENDED(tstat)	(((tstat) & TS_SUSPENDED) != 0U)
+
+/*
+ *  タスク待ち要因判別マクロ
+ *
+ *  TSTAT_WAIT_SLPはタスクが起床待ちであるかどうかを，TSTAT_WAIT_MTXは
+ *  タスクがミューテックス待ちであるかどうかを判別する．
+ *
+ *  また，TSTAT_WAIT_WOBJ はタスクが同期・通信オブジェクトに対する待ち
+ *  であるか（言い換えると，同期・通信オブジェクトの待ちキューにつなが
+ *  れているか）どうかを，TSTAT_WAIT_WOBJCBはタスクが同期・通信オブジェ
+ *  クトの管理ブロックの共通部分（WOBJCB）の待ちキューにつながれている
+ *  かどうかを判別する．
+ */
+#define TSTAT_WAIT_SLP(tstat)	(((tstat) & ~TS_SUSPENDED) == TS_WAITING_SLP)
+#define TSTAT_WAIT_MTX(tstat)	(((tstat) & ~TS_SUSPENDED) == TS_WAITING_MTX)
+
+#define TSTAT_WAIT_WOBJ(tstat)		(((tstat) & (0x18U << 2)) != 0U)
+#define TSTAT_WAIT_WOBJCB(tstat)	(((tstat) & (0x10U << 2)) != 0U)
+
+/*
+ *  待ち情報ブロック（WINFO）の定義
+ *
+ *  タスクが待ち状態の間は，TCBおよびそのp_winfoで指されるWINFOを次の
+ *  ように設定しなければならない．
+ *
+ *  (a) TCBのタスク状態を待ち状態（TS_WAITING_???）にする．
+ *
+ *  (b) タイムアウトを監視するために，タイムイベントブロックを登録する．
+ *  登録するタイムイベントブロックは，待ちに入るサービスコール処理関数
+ *  のローカル変数として確保し，それへのポインタをWINFOのp_tmevtbに記
+ *  憶する．タイムアウトの監視が必要ない場合（永久待ちの場合）には，
+ *  p_tmevtbをNULLにする．
+ *
+ *  同期・通信オブジェクトに対する待ち状態の場合には，標準のWINFOに
+ *  p_wobjcbフィールドを追加した構造体（WINFO_WOBJ，wait.hで定義）に，
+ *  待ち対象の同期・通信オブジェクトに依存して記憶することが必要な情報
+ *  のためのフィールドを追加した構造体（WINFO_???）を定義し，WINFOの代
+ *  わりに用いる．また，以下の(c)～(e)の設定を行う必要がある．同期・通
+ *  信オブジェクトに関係しない待ち（起床待ち，時間経過待ち）の場合には，
+ *  これらは必要ない．
+ *
+ *  (c) TCBを待ち対象の同期・通信オブジェクトの待ちキューにつなぐ．待
+ *  ちキューにつなぐために，task_queueを使う．
+ *
+ *  (d) 待ち対象の同期・通信オブジェクトの管理ブロックへのポインタを，
+ *  WINFO_WOBJのp_wobjcbに記憶する．
+ *
+ *  (e) 待ち対象の同期・通信オブジェクトに依存して記憶することが必要な
+ *  情報がある場合には，WINFO_???内のフィールドに記憶する．
+ *
+ *  待ち状態を解除する際には，待ち解除したタスクに対する返値をWINFOの
+ *  wercdに設定する．wercdが必要なのは待ち解除以降であるのに対して，
+ *  p_tmevtbは待ち解除後は必要ないため，メモリ節約のために共用体を使っ
+ *  ている．そのため，wercdへエラーコードを設定するのは，タイムイベント
+ *  ブロックを登録解除した後にしなければならない．
+ */
+typedef union waiting_information {
+	ER		wercd;			/* 待ち解除時のエラーコード */
+	TMEVTB	*p_tmevtb;		/* 待ち状態用のタイムイベントブロック */
+} WINFO;
+
+/*
+ *  ミューテックス管理ブロックの型の前方参照
+ */
+typedef struct mutex_control_block MTXCB;
+
+/*
+ *  タスク初期化ブロック
+ *
+ *  タスクに関する情報を，値が変わらないために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_t		stksz;			/* スタック領域のサイズ（丸めた値） */
+	void		*stk;			/* スタック領域の先頭番地 */
+#endif /* USE_TSKINICTXB */
+} TINIB;
+
+/*
+ *  タスク管理ブロック（TCB）
+ *
+ *  ASPカーネルでは，タスクの起動要求キューイング数の最大値（TMAX_ACTCNT）
+ *  と起床要求キューイング数の最大値（TMAX_WUPCNT）は1に固定されている
+ *  ため，キューイングされているかどうかの真偽値で表現することができる．
+ *  また，強制待ち要求ネスト数の最大値（TMAX_SUSCNT）が1に固定されてい
+ *  るので，強制待ち要求ネスト数（suscnt）は必要ない．
+ *
+ *  TCBのいくつかのフィールドは，特定のタスク状態でのみ有効な値を保持し，
+ *  それ以外の場合は値が保証されない（よって，参照してはならない）．各
+ *  フィールドが有効な値を保持する条件は次の通り．
+ *
+ *  ・初期化後は常に有効：
+ *  		p_tinib，tstat，actque
+ *  ・休止状態以外で有効（休止状態では初期値になっている）：
+ *  		bpriority，priority，wupque，raster，enater，p_lastmtx
+ *  ・待ち状態（二重待ち状態を含む）で有効：
+ *  		p_winfo
+ *  ・実行できる状態と同期・通信オブジェクトに対する待ち状態で有効：
+ *  		task_queue
+ *  ・実行可能状態，待ち状態，強制待ち状態，二重待ち状態で有効：
+ *  		tskctxb
+ */
+typedef struct task_control_block {
+	QUEUE			task_queue;		/* タスクキュー */
+	const TINIB		*p_tinib;		/* 初期化ブロックへのポインタ */
+
+#ifdef UINT8_MAX
+	uint8_t			tstat;			/* タスク状態（内部表現）*/
+	uint8_t			bpriority;		/* ベース優先度（内部表現）*/
+	uint8_t			priority;		/* 現在の優先度（内部表現）*/
+#else /* UINT8_MAX */
+	BIT_FIELD_UINT	tstat : 8;		/* タスク状態（内部表現）*/
+	BIT_FIELD_UINT	bpriority : 8;	/* ベース優先度（内部表現）*/
+	BIT_FIELD_UINT	priority : 8	/* 現在の優先度（内部表現）*/;
+#endif /* UINT8_MAX */
+	BIT_FIELD_BOOL	actque : 1;		/* 起動要求キューイング */
+	BIT_FIELD_BOOL	wupque : 1;		/* 起床要求キューイング */
+	BIT_FIELD_BOOL	raster : 1;		/* タスク終了要求状態 */
+	BIT_FIELD_BOOL	enater : 1;		/* タスク終了許可状態 */
+
+	WINFO			*p_winfo;		/* 待ち情報ブロックへのポインタ */
+	MTXCB			*p_lastmtx;		/* 最後にロックしたミューテックス */
+	TSKCTXB			tskctxb;		/* タスクコンテキストブロック */
+} TCB;
+
+/*
+ *  実行状態のタスク
+ *
+ *  実行状態のタスク（＝プロセッサがコンテキストを持っているタスク）の
+ *  TCBを指すポインタ．実行状態のタスクがない場合はNULLにする．
+ *
+ *  サービスコールの処理中で，自タスク（サービスコールを呼び出したタス
+ *  ク）に関する情報を参照する場合はp_runtskを使う．p_runtskを書き換え
+ *  るのは，ディスパッチャ（と初期化処理）のみである．
+ */
+extern TCB	*p_runtsk;
+
+/*
+ *  実行すべきタスク
+ *
+ *  実行すべきタスクのTCBを指すポインタ．実行できるタスクがない場合は
+ *  NULLにする．
+ *
+ *  p_runtskは，通常はp_schedtskと一致しているが，非タスクコンテキスト
+ *  実行中は，一致しているとは限らない．割込み優先度マスク全解除でない
+ *  状態の間とディスパッチ禁止状態の間（すなわち，dspflgがfalseである間）
+ *  は，p_schedtskを更新しない．
+ */
+extern TCB	*p_schedtsk;
+
+/*
+ *  ディスパッチ許可状態
+ *
+ *  ディスパッチ許可状態であることを示すフラグ．
+ */
+extern bool_t	enadsp;
+
+/*
+ *  タスクディスパッチ可能状態
+ *
+ *  割込み優先度マスク全解除状態であり，ディスパッチ許可状態である（ディ
+ *  スパッチ禁止状態でない）ことを示すフラグ．ディスパッチ保留状態でな
+ *  いことは，タスクコンテキスト実行中で，CPUロック状態でなく，dspflgが
+ *  trueであることで判別することができる．
+ */
+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)]))
+
+/*
+ *  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で指定されるタスクをレディキューに挿入する．レディキューに挿入
+ *  したタスクの優先度が，実行すべきタスクの優先度よりも高い場合は，実
+ *  行すべきタスクを更新する．
+ */
+extern void	make_runnable(TCB *p_tcb);
+
+/*
+ *  実行できる状態から他の状態への遷移
+ *
+ *  p_tcbで指定されるタスクをレディキューから削除する．p_tcbで指定した
+ *  タスクが実行すべきタスクであった場合には，実行すべきタスクを更新す
+ *  る．
+ */
+extern void	make_non_runnable(TCB *p_tcb);
+
+/*
+ *  休止状態への遷移
+ *
+ *  p_tcbで指定されるタスクの状態を休止状態とする．また，タスクの起動
+ *  時に初期化すべき変数の初期化と，タスク起動のためのコンテキストを設
+ *  定する．
+ */
+extern void	make_dormant(TCB *p_tcb);
+
+/*
+ *  休止状態から実行できる状態への遷移
+ *
+ *  p_tcbで指定されるタスクの状態を休止状態から実行できる状態とする．
+ */
+extern void	make_active(TCB *p_tcb);
+
+/*
+ *  タスクの優先度の変更
+ *
+ *  p_tcbで指定されるタスクの優先度をnewpri（内部表現）に変更する．また，
+ *  必要な場合には，実行すべきタスクを更新する．
+ *
+ *  p_tcbで指定されるタスクの優先順位は，優先度が同じタスクの中で，
+ *  mtxmodeがfalseの時は最低，mtxmodeがtrueの時は最高とする．
+ */
+extern void	change_priority(TCB *p_tcb, uint_t newpri, bool_t mtxmode);
+
+/*
+ *  レディキューの回転
+ *
+ *  レディキュー中の，p_queueで指定されるタスクキューを回転させる．また，
+ *  必要な場合には，実行すべきタスクを更新する．
+ */
+extern void	rotate_ready_queue(QUEUE *p_queue);
+
+/*
+ *  タスクの終了処理
+ *
+ *  p_tcbで指定されるタスクを終了させる処理を行う．タスクの起動要求キュー
+ *  イング数が0でない場合には，再度起動するための処理を行う．
+ */
+extern void	task_terminate(TCB *p_tcb);
+
+#endif /* TOPPERS_TASK_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task.trb	(revision 398)
@@ -0,0 +1,119 @@
+# -*- coding: utf-8 -*-
+#
+#   TOPPERS/ASP Kernel
+#       Toyohashi Open Platform for Embedded Real-Time Systems/
+#       Advanced Standard Profile Kernel
+# 
+#   Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
+#   Copyright (C) 2015,2016 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$
+# 
+
+#
+#		タスク管理モジュールの生成スクリプト
+#
+
+class TaskObject < KernelObject
+  def initialize()
+    super("tsk", "task", "t")
+  end
+
+  def prepare(key, params)
+    # パラメータが省略された時のデフォルト値の設定
+    params[:stk] ||= "NULL"
+
+    # tskatrが無効の場合（E_RSATR）［NGKI1028］
+    #（TA_ACT，TA_NOACTQUE，TARGET_TSKATR以外のビットがセットされている場合）
+    if (params[:tskatr] & ~($TA_ACT|$TA_NOACTQUE|$TARGET_TSKATR)) != 0
+      error_illegal_id("E_RSATR", params, :tskatr, :tskid)
+    end
+
+    # (TMIN_TPRI <= itskpri && itskpri <= TMAX_TPRI)でない場合［NGKI1034］
+    if !($TMIN_TPRI <= params[:itskpri] && params[:itskpri] <= $TMAX_TPRI)
+      error_illegal_id("E_PAR", params, :itskpri, :tskid)
+    end
+
+    # stkszがターゲット定義の最小値（TARGET_MIN_STKSZ，未定義の場合は1）
+    # よりも小さい場合［NGKI1042］
+    if params[:stksz] < $TARGET_MIN_STKSZ
+      error_wrong_id("E_PAR", params, :stksz, :tskid, "too small")
+    end
+
+    # スタック領域の設定［NGKI1041］
+    if params[:stk] == "NULL"
+      # スタック領域の生成［NGKI1049］
+      stkName = "_kernel_stack_#{params[:tskid]}"
+      params[:tinib_stksz] = AllocStack(stkName, params[:stksz], "SU")
+      params[:tinib_stk] = stkName
+    else
+      # stkszがスタック領域のサイズとして正しくない場合［NGKI1056］
+      if (params[:stksz] & ($CHECK_STKSZ_ALIGN - 1)) != 0
+        error_wrong_id("E_PAR", params, :stksz, :tskid, "not aligned")
+      end
+
+      params[:tinib_stksz] = params[:stksz]
+      params[:tinib_stk] = "(void *)(#{params[:stk]})"
+    end
+  end
+
+  def generateInib(key, params)
+    if $USE_TSKINICTXB
+      tskinictxb = GenerateTskinictxb(key, params)
+    else
+      tskinictxb = "#{params[:tinib_stksz]}, #{params[:tinib_stk]}"
+    end
+    return("(#{params[:tskatr]}), (intptr_t)(#{params[:exinf]}), " \
+			"(TASK)(#{params[:task]}), INT_PRIORITY(#{params[:itskpri]}), " \
+			+ tskinictxb + ", \"#{params[:task]}\"")
+  end
+end
+
+#
+#  タスク管理に関する情報の生成
+#
+$kernelCfgC.comment_header("Task Management Functions")
+if $cfgData[:CRE_TSK].size() == 0
+  error("no task is registered")
+end
+TaskObject.new.generate()
+
+# タスク生成順序テーブルの生成
+$kernelCfgC.add("const ID _kernel_torder_table[TNUM_STSKID] = { ")
+$kernelCfgC.append("\t")
+$cfgData[:CRE_TSK].each_with_index do |(key, params), index|
+  $kernelCfgC.append(", ") if index > 0
+  $kernelCfgC.append("#{params[:tskid]}")
+end
+$kernelCfgC.add
+$kernelCfgC.add2("};")
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_manage.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_manage.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_manage.c	(revision 398)
@@ -0,0 +1,529 @@
+/*
+ *  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 "taskhook.h"
+#include "wait.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_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_GET_TST_ENTER
+#define LOG_GET_TST_ENTER(tskid, p_tskstat)
+#endif /* LOG_GET_TST_ENTER */
+
+#ifndef LOG_GET_TST_LEAVE
+#define LOG_GET_TST_LEAVE(ercd, p_tskstat)
+#endif /* LOG_GET_TST_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, p_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, p_exinf)
+#endif /* LOG_GET_INF_LEAVE */
+
+/*
+ *  タスクの生成
+ *
+ *  pk_ctsk->exinfは，エラーチェックをせず，一度しか参照しないため，ロー
+ *  カル変数にコピーする必要がない（途中で書き換わっても支障がない）．
+ */
+#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;
+	TASK	task;
+	PRI		itskpri;
+	size_t	stksz;
+	STK_T	*stk;
+	ER		ercd;
+
+	LOG_ACRE_TSK_ENTER(pk_ctsk);
+	CHECK_TSKCTX_UNL();
+
+	tskatr = pk_ctsk->tskatr;
+	task = pk_ctsk->task;
+	itskpri = pk_ctsk->itskpri;
+	stksz = pk_ctsk->stksz;
+	stk = pk_ctsk->stk;
+
+	CHECK_RSATR(tskatr, TA_ACT|TA_NOACTQUE|TARGET_TSKATR);
+	CHECK_PAR(FUNC_ALIGN(task));
+	CHECK_PAR(FUNC_NONNULL(task));
+	CHECK_PAR(VALID_TPRI(itskpri));
+	CHECK_PAR(stksz >= TARGET_MIN_STKSZ);
+	if (stk != NULL) {
+		CHECK_PAR(STKSZ_ALIGN(stksz));
+		CHECK_PAR(STACK_ALIGN(stk));
+	}
+
+	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 = task;
+			p_tinib->ipriority = INT_PRIORITY(itskpri);
+#ifdef USE_TSKINICTXB
+			init_tskinictxb(&(p_tinib->tskinictxb), stksz, stk);
+#else /* USE_TSKINICTXB */
+			p_tinib->stksz = stksz;
+			p_tinib->stk = stk;
+#endif /* USE_TSKINICTXB */
+
+			p_tcb->actque = false;
+			make_dormant(p_tcb);
+			if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
+				make_active(p_tcb);
+				if (p_runtsk != p_schedtsk) {
+					dispatch();
+				}
+			}
+			ercd = TSKID(p_tcb);
+		}
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_ACRE_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_acre_tsk */
+
+/*
+ *  タスクの削除［NGKI1100］
+ */
+#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();							/*［NGKI1101］［NGKI1102］*/
+	CHECK_ID(VALID_TSKID(tskid));				/*［NGKI1103］*/
+	p_tcb = get_tcb(tskid);
+
+	lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;							/*［NGKI1104］*/
+	}
+	else if (tskid <= tmax_stskid || !TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;							/*［NGKI1106］［NGKI1107］*/
+	}
+	else {
+		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) {	/*［NGKI1109］*/
+			kernel_free(p_tinib->stk);
+		}
+#endif /* USE_TSKINICTXB */
+		p_tinib->tskatr = TA_NOEXS;				/*［NGKI1108］*/
+		queue_insert_prev(&free_tcb, &(p_tcb->task_queue));
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_DEL_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_del_tsk */
+
+/*
+ *  タスクの起動［NGKI3529］
+ */
+#ifdef TOPPERS_act_tsk
+
+ER
+act_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_ACT_TSK_ENTER(tskid);
+	CHECK_UNL();								/*［NGKI1114］*/
+	if (tskid == TSK_SELF && !sense_context()) {
+		p_tcb = p_runtsk;						/*［NGKI1121］*/
+	}
+	else {
+		CHECK_ID(VALID_TSKID(tskid));			/*［NGKI1115］*/
+		p_tcb = get_tcb(tskid);
+	}
+
+	lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;							/*［NGKI1116］*/
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		make_active(p_tcb);						/*［NGKI1118］*/
+		if (p_runtsk != p_schedtsk) {
+			if (!sense_context()) {
+				dispatch();
+			}
+			else {
+				request_dispatch();
+			}
+		}
+		ercd = E_OK;
+	}
+	else if ((p_tcb->p_tinib->tskatr & TA_NOACTQUE) != 0U || p_tcb->actque) {
+		ercd = E_QOVR;			   				/*［NGKI3528］*/
+	}
+	else {
+		p_tcb->actque = true;					/*［NGKI3527］*/
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_ACT_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_act_tsk */
+
+/*
+ *  タスク起動要求のキャンセル［NGKI1138］
+ */
+#ifdef TOPPERS_can_act
+
+ER_UINT
+can_act(ID tskid)
+{
+	TCB		*p_tcb;
+	ER_UINT	ercd;
+
+	LOG_CAN_ACT_ENTER(tskid);
+	CHECK_TSKCTX_UNL();							/*［NGKI1139］［NGKI1140］*/
+	if (tskid == TSK_SELF) {
+		p_tcb = p_runtsk;						/*［NGKI1146］*/
+	}
+	else {
+		CHECK_ID(VALID_TSKID(tskid));			/*［NGKI1141］*/
+		p_tcb = get_tcb(tskid);
+	}
+
+	lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;							/*［NGKI1142］*/
+	}
+	else {
+		ercd = p_tcb->actque ? 1 : 0;			/*［NGKI1144］*/
+		p_tcb->actque = false;					/*［NGKI1144］*/
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_CAN_ACT_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_can_act */
+
+/*
+ *  タスク状態の参照［NGKI3613］
+ */
+#ifdef TOPPERS_get_tst
+
+ER
+get_tst(ID tskid, STAT *p_tskstat)
+{
+	TCB		*p_tcb;
+	uint_t	tstat;
+	ER		ercd;
+
+	LOG_GET_TST_ENTER(tskid, p_tskstat);
+	CHECK_TSKCTX_UNL();							/*［NGKI3614］［NGKI3615］*/
+	if (tskid == TSK_SELF) {
+		p_tcb = p_runtsk;						/*［NGKI3621］*/
+	}
+	else {
+		CHECK_ID(VALID_TSKID(tskid));			/*［NGKI3616］*/
+		p_tcb = get_tcb(tskid);
+	}
+
+	lock_cpu();
+	tstat = p_tcb->tstat;
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;							/*［NGKI3617］*/
+	}
+	else {
+		if (TSTAT_DORMANT(tstat)) {				/*［NGKI3620］*/
+			*p_tskstat = TTS_DMT;
+		}
+		else if (TSTAT_SUSPENDED(tstat)) {
+			if (TSTAT_WAITING(tstat)) {
+				*p_tskstat = TTS_WAS;
+			}
+			else {
+				*p_tskstat = TTS_SUS;
+			}
+		}
+		else if (TSTAT_WAITING(tstat)) {
+			*p_tskstat = TTS_WAI;
+		}
+		else if (p_tcb == p_runtsk) {
+			*p_tskstat = TTS_RUN;
+		}
+		else {
+			*p_tskstat = TTS_RDY;
+		}
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_GET_TST_LEAVE(ercd, p_tskstat);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_tst */
+
+/*
+ *  タスクのベース優先度の変更［NGKI1183］
+ */
+#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();							/*［NGKI1184］［NGKI1185］*/
+	if (tskid == TSK_SELF) {
+		p_tcb = p_runtsk;						/*［NGKI1198］*/
+	}
+	else {
+		CHECK_ID(VALID_TSKID(tskid));			/*［NGKI1187］*/
+		p_tcb = get_tcb(tskid);
+	}
+	if (tskpri == TPRI_INI) {
+		newbpri = p_tcb->p_tinib->ipriority;	/*［NGKI1199］*/
+	}
+	else {
+		CHECK_PAR(VALID_TPRI(tskpri));			/*［NGKI1188］*/
+		newbpri = INT_PRIORITY(tskpri);
+	}
+
+	lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;							/*［NGKI1189］*/
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;							/*［NGKI1191］*/
+	}
+	else if ((p_tcb->p_lastmtx != NULL || TSTAT_WAIT_MTX(p_tcb->tstat))
+						&& !((*mtxhook_check_ceilpri)(p_tcb, newbpri))) {
+		ercd = E_ILUSE;							/*［NGKI1201］*/
+	}
+	else {
+		p_tcb->bpriority = newbpri;				/*［NGKI1192］*/
+		if (p_tcb->p_lastmtx == NULL || !((*mtxhook_scan_ceilmtx)(p_tcb))) {
+			change_priority(p_tcb, newbpri, false);		/*［NGKI1193］*/
+			if (p_runtsk != p_schedtsk) {
+				dispatch();
+			}									/*［NGKI1197］*/
+		}
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_CHG_PRI_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_chg_pri */
+
+/*
+ *  タスク優先度の参照［NGKI1202］
+ */
+#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();							/*［NGKI1203］［NGKI1204］*/
+	if (tskid == TSK_SELF) {
+		p_tcb = p_runtsk;						/*［NGKI1211］*/
+	}
+	else {
+		CHECK_ID(VALID_TSKID(tskid));			/*［NGKI1205］*/
+		p_tcb = get_tcb(tskid);
+	}
+
+	lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;							/*［NGKI1206］*/
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;							/*［NGKI1209］*/
+	}
+	else {
+		*p_tskpri = EXT_TSKPRI(p_tcb->priority);	/*［NGKI1210］*/
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_GET_PRI_LEAVE(ercd, p_tskpri);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_pri */
+
+/*
+ *  自タスクの拡張情報の参照［NGKI1212］
+ */
+#ifdef TOPPERS_get_inf
+
+ER
+get_inf(intptr_t *p_exinf)
+{
+	ER		ercd;
+
+	LOG_GET_INF_ENTER(p_exinf);
+	CHECK_TSKCTX_UNL();							/*［NGKI1213］［NGKI1214］*/
+
+	lock_cpu();
+	*p_exinf = p_runtsk->p_tinib->exinf;		/*［NGKI1216］*/
+	ercd = E_OK;
+	unlock_cpu();
+
+  error_exit:
+	LOG_GET_INF_LEAVE(ercd, p_exinf);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_inf */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_refer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_refer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_refer.c	(revision 398)
@@ -0,0 +1,224 @@
+/*
+ *  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 "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();
+	if (tskid == TSK_SELF) {
+		p_tcb = p_runtsk;
+	}
+	else {
+		CHECK_ID(VALID_TSKID(tskid));
+		p_tcb = get_tcb(tskid);
+	}
+
+	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) {
+				case TS_WAITING_SLP:
+					pk_rtsk->tskwait = TTW_SLP;
+					break;
+				case TS_WAITING_DLY:
+					pk_rtsk->tskwait = TTW_DLY;
+					break;
+				case TS_WAITING_SEM:
+					pk_rtsk->tskwait = TTW_SEM;
+					pk_rtsk->wobjid = SEMID(((WINFO_SEM *)(p_tcb->p_winfo))
+																->p_semcb);
+					break;
+				case TS_WAITING_FLG:
+					pk_rtsk->tskwait = TTW_FLG;
+					pk_rtsk->wobjid = FLGID(((WINFO_FLG *)(p_tcb->p_winfo))
+																->p_flgcb);
+					break;
+				case TS_WAITING_SDTQ:
+					pk_rtsk->tskwait = TTW_SDTQ;
+					pk_rtsk->wobjid = DTQID(((WINFO_SDTQ *)(p_tcb->p_winfo))
+																->p_dtqcb);
+					break;
+				case TS_WAITING_RDTQ:
+					pk_rtsk->tskwait = TTW_RDTQ;
+					pk_rtsk->wobjid = DTQID(((WINFO_RDTQ *)(p_tcb->p_winfo))
+																->p_dtqcb);
+					break;
+				case TS_WAITING_SPDQ:
+					pk_rtsk->tskwait = TTW_SPDQ;
+					pk_rtsk->wobjid = PDQID(((WINFO_SPDQ *)(p_tcb->p_winfo))
+																->p_pdqcb);
+					break;
+				case TS_WAITING_RPDQ:
+					pk_rtsk->tskwait = TTW_RPDQ;
+					pk_rtsk->wobjid = PDQID(((WINFO_RPDQ *)(p_tcb->p_winfo))
+																->p_pdqcb);
+					break;
+				case TS_WAITING_MTX:
+					pk_rtsk->tskwait = TTW_MTX;
+					pk_rtsk->wobjid = MTXID(((WINFO_MTX *)(p_tcb->p_winfo))
+																->p_mtxcb);
+					break;
+				case TS_WAITING_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->raster = p_tcb->raster;
+
+			/*
+			 *  タスク終了禁止状態の取出し
+			 */
+			pk_rtsk->dister = !(p_tcb->enater);
+		}
+
+		/*
+		 *  起動要求キューイング数の取出し
+		 */
+		pk_rtsk->actcnt = p_tcb->actque ? 1U : 0U;
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_REF_TSK_LEAVE(ercd, pk_rtsk);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ref_tsk */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_sync.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_sync.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_sync.c	(revision 398)
@@ -0,0 +1,501 @@
+/*
+ *  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 "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_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_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();
+
+	lock_cpu_dsp();
+	if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else if (p_runtsk->wupque) {
+		p_runtsk->wupque = false;
+		ercd = E_OK;
+	}
+	else {
+		p_runtsk->tstat = TS_WAITING_SLP;
+		make_wait(&winfo);
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  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_PAR(VALID_TMOUT(tmout));
+
+	lock_cpu_dsp();
+	if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else 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_SLP;
+		make_wait_tmout(&winfo, &tmevtb, tmout);
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  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_UNL();
+	if (tskid == TSK_SELF && !sense_context()) {
+		p_tcb = p_runtsk;
+	}
+	else {
+		CHECK_ID(VALID_TSKID(tskid));
+		p_tcb = get_tcb(tskid);
+	}
+
+	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)) {
+		wait_complete(p_tcb);
+		if (p_runtsk != p_schedtsk) {
+			if (!sense_context()) {
+				dispatch();
+			}
+			else {
+				request_dispatch();
+			}
+		}
+		ercd = E_OK;
+	}
+	else if (!(p_tcb->wupque)) {
+		p_tcb->wupque = true;
+		ercd = E_OK;
+	}
+	else {
+		ercd = E_QOVR;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_WUP_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_wup_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();
+	if (tskid == TSK_SELF) {
+		p_tcb = p_runtsk;
+	}
+	else {
+		CHECK_ID(VALID_TSKID(tskid));
+		p_tcb = get_tcb(tskid);
+	}
+
+	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;
+	}
+	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_UNL();
+	CHECK_ID(VALID_TSKID(tskid));
+	p_tcb = get_tcb(tskid);
+
+	lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;
+	}
+	else if (!TSTAT_WAITING(p_tcb->tstat)) {
+		ercd = E_OBJ;
+	}
+	else {
+		wait_dequeue_wobj(p_tcb);
+		wait_dequeue_tmevtb(p_tcb);
+		p_tcb->p_winfo->wercd = E_RLWAI;
+		make_non_wait(p_tcb);
+		if (p_runtsk != p_schedtsk) {
+			if (!sense_context()) {
+				dispatch();
+			}
+			else {
+				request_dispatch();
+			}
+		}
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_REL_WAI_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_rel_wai */
+
+/*
+ *  強制待ち状態への移行［NGKI1298］
+ */
+#ifdef TOPPERS_sus_tsk
+
+ER
+sus_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_SUS_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();							/*［NGKI1299］［NGKI1300］*/
+	if (tskid == TSK_SELF) {
+		p_tcb = p_runtsk;						/*［NGKI1310］*/
+	}
+	else {
+		CHECK_ID(VALID_TSKID(tskid));			/*［NGKI1302］*/
+		p_tcb = get_tcb(tskid);
+	}
+
+	lock_cpu();
+	if (p_tcb == p_runtsk && !dspflg) {			/*［NGKI1311］［NGKI3604］*/
+		ercd = E_CTX;
+	}
+	else if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;							/*［NGKI1303］*/
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;							/*［NGKI1305］*/
+	}
+	else if (p_tcb->raster) {
+		ercd = E_RASTER;						/*［NGKI3605］*/
+	}
+	else if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+		/*
+		 *  実行できる状態から強制待ち状態への遷移［NGKI1307］
+		 */
+		p_tcb->tstat = TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		make_non_runnable(p_tcb);
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else if (TSTAT_SUSPENDED(p_tcb->tstat)) {
+		ercd = E_QOVR;							/*［NGKI1306］*/
+	}
+	else {
+		/*
+		 *  待ち状態から二重待ち状態への遷移［NGKI1308］
+		 */
+		p_tcb->tstat |= TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		ercd = E_OK;
+	}
+	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_ID(VALID_TSKID(tskid));
+	p_tcb = get_tcb(tskid);
+
+	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);
+		make_runnable(p_tcb);
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		/*
+		 *  二重待ち状態から待ち状態への遷移
+		 */
+		p_tcb->tstat &= ~TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+		ercd = E_OK;
+	}
+	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(VALID_RELTIM(dlytim));
+
+	lock_cpu_dsp();
+	if (p_runtsk->raster) {
+		ercd = E_RASTER;
+	}
+	else {
+		p_runtsk->tstat = TS_WAITING_DLY;
+		make_non_runnable(p_runtsk);
+		p_runtsk->p_winfo = &winfo;
+		winfo.p_tmevtb = &tmevtb;
+		tmevtb.callback = (CBACK) wait_tmout_ok;
+		tmevtb.arg = (void *) p_runtsk;
+		tmevtb_enqueue(&tmevtb, dlytim);
+		LOG_TSKSTAT(p_runtsk);
+		dispatch();
+		ercd = winfo.wercd;
+	}
+	unlock_cpu_dsp();
+
+  error_exit:
+	LOG_DLY_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_dly_tsk */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_term.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_term.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/task_term.c	(revision 398)
@@ -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) 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"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#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_RAS_TER_ENTER
+#define LOG_RAS_TER_ENTER(tskid)
+#endif /* LOG_RAS_TER_ENTER */
+
+#ifndef LOG_RAS_TER_LEAVE
+#define LOG_RAS_TER_LEAVE(ercd)
+#endif /* LOG_RAS_TER_LEAVE */
+
+#ifndef LOG_DIS_TER_ENTER
+#define LOG_DIS_TER_ENTER()
+#endif /* LOG_DIS_TER_ENTER */
+
+#ifndef LOG_DIS_TER_LEAVE
+#define LOG_DIS_TER_LEAVE(ercd)
+#endif /* LOG_DIS_TER_LEAVE */
+
+#ifndef LOG_ENA_TER_ENTER
+#define LOG_ENA_TER_ENTER()
+#endif /* LOG_ENA_TER_ENTER */
+
+#ifndef LOG_ENA_TER_LEAVE
+#define LOG_ENA_TER_LEAVE(ercd)
+#endif /* LOG_ENA_TER_LEAVE */
+
+#ifndef LOG_SNS_TER_ENTER
+#define LOG_SNS_TER_ENTER()
+#endif /* LOG_SNS_TER_ENTER */
+
+#ifndef LOG_SNS_TER_LEAVE
+#define LOG_SNS_TER_LEAVE(state)
+#endif /* LOG_SNS_TER_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 */
+
+/*
+ *  自タスクの終了［NGKI1162］
+ */
+#ifdef TOPPERS_ext_tsk
+
+ER
+ext_tsk(void)
+{
+	PRI		intpri;
+	ER		ercd;
+
+	LOG_EXT_TSK_ENTER();
+	CHECK_TSKCTX();							/*［NGKI1164］*/
+
+	if (sense_lock()) {
+		/*
+		 *  CPUロック状態でext_tskが呼ばれた場合は，CPUロックを解除し
+		 *  てからタスクを終了する．実装上は，サービスコール内でのCPU
+		 *  ロックを省略すればよいだけ．［NGKI1168］
+		 */
+	}
+	else {
+		lock_cpu();
+	}
+
+	intpri = t_get_ipm();
+	if (!enadsp || intpri != TIPM_ENAALL) {
+		if (!enadsp) {
+			/*
+			 *  ディスパッチ禁止状態でext_tskが呼ばれた場合は，ディスパッ
+			 *  チ許可状態にしてからタスクを終了する．［NGKI1168］
+			 */
+			enadsp = true;
+		}
+		if (intpri != TIPM_ENAALL) {
+			/*
+			 *  割込み優先度マスク（IPM）がTIPM_ENAALL以外の状態で
+			 *  ext_tskが呼ばれた場合は，IPMをTIPM_ENAALLにしてからタス
+			 *  クを終了する．［NGKI1168］
+			 */
+			t_set_ipm(TIPM_ENAALL);
+		}
+		dspflg = true;
+		p_schedtsk = search_schedtsk();
+	}
+
+	task_terminate(p_runtsk);				/* ［NGKI3449］*/
+	exit_and_dispatch();					/* ［NGKI1169］*/
+	ercd = E_SYS;							/* ［NGKI1163］*/
+
+  error_exit:
+	LOG_EXT_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ext_tsk */
+
+/*
+ *  タスクの終了要求［NGKI3469］
+ */
+#ifdef TOPPERS_ras_ter
+
+ER
+ras_ter(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_RAS_TER_ENTER(tskid);
+	CHECK_TSKCTX_UNL();							/*［NGKI3470］［NGKI3471］*/
+	CHECK_ID(VALID_TSKID(tskid));				/*［NGKI3472］*/
+	p_tcb = get_tcb(tskid);
+	CHECK_ILUSE(p_tcb != p_runtsk);				/*［NGKI3475］*/
+
+	lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;							/*［NGKI3473］*/
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;							/*［NGKI3476］*/
+	}
+	else if (p_tcb->enater) {
+		task_terminate(p_tcb);					/*［NGKI3477］*/
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	else {
+		p_tcb->raster = true;					/*［NGKI3478］*/
+		if (!TSTAT_RUNNABLE(p_tcb->tstat)) {
+			if (TSTAT_WAITING(p_tcb->tstat)) {
+				wait_dequeue_wobj(p_tcb);		/*［NGKI3479］*/
+				wait_dequeue_tmevtb(p_tcb);
+				p_tcb->p_winfo->wercd = E_RASTER;	/*［NGKI3480］*/
+			}
+			p_tcb->tstat = TS_RUNNABLE;			/*［NGKI3606］*/
+			LOG_TSKSTAT(p_tcb);
+			make_runnable(p_tcb);
+			if (p_runtsk != p_schedtsk) {
+				dispatch();
+			}
+		}
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_RAS_TER_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ras_ter */
+
+/*
+ *  タスク終了の禁止［NGKI3482］
+ */
+#ifdef TOPPERS_dis_ter
+
+ER
+dis_ter(void)
+{
+	ER		ercd;
+
+	LOG_DIS_TER_ENTER();
+	CHECK_TSKCTX_UNL();							/*［NGKI3483］［NGKI3484］*/
+
+	lock_cpu();
+	p_runtsk->enater = false;					/*［NGKI3486］*/
+	ercd = E_OK;
+	unlock_cpu();
+
+  error_exit:
+	LOG_DIS_TER_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_dis_ter */
+
+/*
+ *  タスク終了の許可［NGKI3487］
+ */
+#ifdef TOPPERS_ena_ter
+
+ER
+ena_ter(void)
+{
+	ER		ercd;
+
+	LOG_ENA_TER_ENTER();
+	CHECK_TSKCTX_UNL();							/*［NGKI3488］［NGKI3489］*/
+
+	lock_cpu();
+	if (p_runtsk->raster && dspflg) {
+		task_terminate(p_runtsk);
+		exit_and_dispatch();
+		ercd = E_SYS;
+	}
+	else {
+		p_runtsk->enater = true;				/*［NGKI3491］*/
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_ENA_TER_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ena_ter */
+
+/*
+ *  タスク終了禁止状態の参照［NGKI3494］
+ */
+#ifdef TOPPERS_sns_ter
+
+bool_t
+sns_ter(void)
+{
+	bool_t	state;
+
+	LOG_SNS_TER_ENTER();
+	/*
+	 *  enaterを変更できるのは自タスクのみであるため，排他制御せずに読
+	 *  んでも問題ない．
+	 */
+	state = (p_runtsk != NULL && p_runtsk->enater) ? false : true;
+												/*［NGKI3495］［NGKI3496］*/
+	LOG_SNS_TER_LEAVE(state);
+	return(state);
+}
+
+#endif /* TOPPERS_sns_ter */
+
+/*
+ *  タスクの強制終了［NGKI1170］
+ */
+#ifdef TOPPERS_ter_tsk
+
+ER
+ter_tsk(ID tskid)
+{
+	TCB		*p_tcb;
+	ER		ercd;
+
+	LOG_TER_TSK_ENTER(tskid);
+	CHECK_TSKCTX_UNL();							/*［NGKI1171］［NGKI1172］*/
+	CHECK_ID(VALID_TSKID(tskid));				/*［NGKI1173］*/
+	p_tcb = get_tcb(tskid);
+	CHECK_ILUSE(p_tcb != p_runtsk);				/*［NGKI1176］*/
+
+	lock_cpu();
+	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
+		ercd = E_NOEXS;							/*［NGKI1174］*/
+	}
+	else if (TSTAT_DORMANT(p_tcb->tstat)) {
+		ercd = E_OBJ;							/*［NGKI1177］*/
+	}
+	else {
+		task_terminate(p_tcb);					/*［NGKI3450］*/
+		if (p_runtsk != p_schedtsk) {
+			dispatch();
+		}
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_TER_TSK_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_ter_tsk */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/taskhook.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/taskhook.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/taskhook.c	(revision 398)
@@ -0,0 +1,58 @@
+/*
+ *  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 "task.h"
+#include "taskhook.h"
+
+/*
+ *  ミューテックス機能のためのフックルーチン
+ */
+#ifdef TOPPERS_mtxhook
+
+bool_t	(*mtxhook_check_ceilpri)(TCB *p_tcb, uint_t bpriority) = NULL;
+bool_t	(*mtxhook_scan_ceilmtx)(TCB *p_tcb) = NULL;
+void	(*mtxhook_release_all)(TCB *p_tcb) = NULL;
+
+#endif /* TOPPERS_mtxhook */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/taskhook.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/taskhook.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/taskhook.h	(revision 398)
@@ -0,0 +1,58 @@
+/*
+ *  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$
+ */
+
+/*
+ *  タスク管理に関連するフックルーチン
+ */
+
+#ifndef TOPPERS_TASKHOOK_H
+#define TOPPERS_TASKHOOK_H
+
+#include "kernel_impl.h"
+#include "task.h"
+
+/*
+ *  ミューテックス機能のためのフックルーチン
+ */
+extern bool_t	(*mtxhook_check_ceilpri)(TCB *p_tcb, uint_t bpriority);
+extern bool_t	(*mtxhook_scan_ceilmtx)(TCB *p_tcb);
+extern void		(*mtxhook_release_all)(TCB *p_tcb);
+
+#endif /* TOPPERS_TASKHOOK_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/time_event.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/time_event.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/time_event.c	(revision 398)
@@ -0,0 +1,601 @@
+/*
+ *  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-2016 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"
+
+/*
+ *  TSTEP_HRTCNTの範囲チェック
+ */
+#if TSTEP_HRTCNT > 4000U
+#error TSTEP_HRTCNT is too large.
+#endif /* TSTEP_HRTCNT > 4000U */
+
+/*
+ *  HRTCNT_BOUNDの範囲チェック
+ */
+#if HRTCNT_BOUND >= 4294000000U
+#error HRTCNT_BOUND is too large.
+#endif /* HRTCNT_BOUND >= 4294000000U */
+
+#ifdef TCYC_HRTCNT
+#if HRTCNT_BOUND >= TCYC_HRTCNT
+#error HRTCNT_BOUND is too large.
+#endif /* HRTCNT_BOUND >= TCYC_HRTCNT */
+#endif /* TCYC_HRTCNT */
+
+/*
+ *  タイムイベントヒープ操作マクロ
+ */
+#define PARENT(p_tmevtn)	(tmevt_heap + (((p_tmevtn) - tmevt_heap) >> 1))
+													/* 親ノードを求める */
+#define LCHILD(p_tmevtn)	(tmevt_heap + (((p_tmevtn) - tmevt_heap) << 1))
+													/* 左の子ノードを求める */
+/*
+ *  タイムイベントヒープ中の先頭のノード
+ */
+#define p_top_tmevtn	(&(tmevt_heap[1]))
+#define top_evttim		(tmevt_heap[1].p_tmevtb->evttim)
+										/* 先頭のタイムイベントの発生時刻 */
+/*
+ *  タイムイベントヒープ中の最後のノード
+ */
+#define p_last_tmevtn	(tmevt_heap[0].p_last)
+
+/*
+ *  イベント時刻の前後関係の判定［ASPD1009］
+ *
+ *  イベント時刻は，boundary_evttimからの相対値で比較する．すなわち，
+ *  boundary_evttimを最も早い時刻，boundary_evttim-1が最も遅い時刻とみ
+ *  なして比較する．
+ */
+#define EVTTIM_ADVANCE(t)	((t) - boundary_evttim)
+#define EVTTIM_LT(t1, t2)	(EVTTIM_ADVANCE(t1) < EVTTIM_ADVANCE(t2))
+#define EVTTIM_LE(t1, t2)	(EVTTIM_ADVANCE(t1) <= EVTTIM_ADVANCE(t2))
+
+#ifdef TOPPERS_tmeini
+
+/*
+ *  境界イベント時刻［ASPD1008］
+ */
+EVTTIM	boundary_evttim;
+
+/*
+ *  最後に現在時刻を算出した時点でのイベント時刻［ASPD1012］
+ */
+EVTTIM	current_evttim;
+
+/*
+ *  最後に現在時刻を算出した時点での高分解能タイマのカウント値［ASPD1012］
+ */
+HRTCNT	current_hrtcnt;
+
+/*
+ *  最も進んでいた時のイベント時刻［ASPD1041］
+ */
+EVTTIM	monotonic_evttim;
+
+/*
+ *  システム時刻のオフセット［ASPD1043］
+ */
+SYSTIM	systim_offset;
+
+/*
+ *  高分解能タイマ割込みの処理中であることを示すフラグ［ASPD1032］
+ */
+bool_t	in_signal_time;
+
+/*
+ *  タイムイベント管理モジュールの初期化［ASPD1061］
+ */
+void
+initialize_tmevt(void)
+{
+	current_evttim = 0U;							/*［ASPD1047］*/
+	boundary_evttim = current_evttim - BOUNDARY_MARGIN;
+													/*［ASPD1048］*/
+	monotonic_evttim = 0U;							/*［ASPD1046］*/
+	systim_offset = 0U;								/*［ASPD1044］*/
+	in_signal_time = false;							/*［ASPD1033］*/
+	p_last_tmevtn = tmevt_heap;
+}
+
+#endif /* TOPPERS_tmeini */
+
+/*
+ *  タイムイベントの挿入位置を上向きに探索
+ *
+ *  時刻evttimに発生するタイムイベントを挿入するノードを空けるために，
+ *  ヒープの上に向かって空ノードを移動させる．移動前の空ノードの位置を
+ *  p_tmevtnに渡すと，移動後の空ノードの位置（すなわち挿入位置）を返す．
+ */
+#ifdef TOPPERS_tmeup
+
+TMEVTN *
+tmevt_up(TMEVTN *p_tmevtn, EVTTIM evttim)
+{
+	TMEVTN	*p_parent;
+
+	while (p_tmevtn > p_top_tmevtn) {
+		/*
+		 *  親ノードのイベント発生時刻の方が早い（または同じ）ならば，
+		 *  p_tmevtnが挿入位置なのでループを抜ける．
+		 */
+		p_parent = PARENT(p_tmevtn);
+		if (EVTTIM_LE(p_parent->p_tmevtb->evttim, evttim)) {
+			break;
+		}
+
+		/*
+		 *  親ノードをp_tmevtnの位置に移動させる．
+		 */
+		*p_tmevtn = *p_parent;
+		p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;
+
+		/*
+		 *  p_tmevtnを親ノードの位置に更新．
+		 */
+		p_tmevtn = p_parent;
+	}
+	return(p_tmevtn);
+}
+
+#endif /* TOPPERS_tmeup */
+
+/*
+ *  タイムイベントの挿入位置を下向きに探索
+ *
+ *  時刻evttimに発生するタイムイベントを挿入するノードを空けるために，
+ *  ヒープの下に向かって空ノードを移動させる．移動前の空ノードの位置を
+ *  p_tmevtnに渡すと，移動後の空ノードの位置（すなわち挿入位置）を返す．
+ */
+#ifdef TOPPERS_tmedown
+
+TMEVTN *
+tmevt_down(TMEVTN *p_tmevtn, EVTTIM evttim)
+{
+	TMEVTN	*p_child;
+
+	while ((p_child = LCHILD(p_tmevtn)) <= p_last_tmevtn) {
+		/*
+		 *  左右の子ノードのイベント発生時刻を比較し，早い方の子ノード
+		 *  の位置をp_childに設定する．以下の子ノードは，ここで選ばれた
+		 *  方の子ノードのこと．
+		 */
+		if (p_child + 1 <= p_last_tmevtn
+					&& EVTTIM_LT((p_child + 1)->p_tmevtb->evttim,
+											p_child->p_tmevtb->evttim)) {
+			p_child = p_child + 1;
+		}
+
+		/*
+		 *  子ノードのイベント発生時刻の方が遅い（または同じ）ならば，
+		 *  p_tmevtnが挿入位置なのでループを抜ける．
+		 */
+		if (EVTTIM_LE(evttim, p_child->p_tmevtb->evttim)) {
+			break;
+		}
+
+		/*
+		 *  子ノードをp_tmevtnの位置に移動させる．
+		 */
+		*p_tmevtn = *p_child;
+		p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;
+
+		/*
+		 *  p_tmevtnを子ノードの位置に更新．
+		 */
+		p_tmevtn = p_child;
+	}
+	return(p_tmevtn);
+}
+
+#endif /* TOPPERS_tmedown */
+
+/*
+ *  タイムイベントヒープへの追加
+ *
+ *  p_tmevtbで指定したタイムイベントブロックを，タイムイベントヒープに
+ *  追加する．
+ */
+Inline void
+tmevtb_insert(TMEVTB *p_tmevtb)
+{
+	TMEVTN	*p_tmevtn;
+
+	/*
+	 *  p_last_tmevtnをインクリメントし，そこから上に挿入位置を探す．
+	 */
+	p_tmevtn = tmevt_up(++p_last_tmevtn, p_tmevtb->evttim);
+
+	/*
+	 *  タイムイベントをp_tmevtnの位置に挿入する．
+	 */ 
+	p_tmevtn->p_tmevtb = p_tmevtb;
+	p_tmevtb->p_tmevtn = p_tmevtn;
+}
+
+/*
+ *  タイムイベントヒープからの削除
+ */
+Inline void
+tmevtb_delete(TMEVTB *p_tmevtb)
+{
+	TMEVTN	*p_tmevtn = p_tmevtb->p_tmevtn;
+	TMEVTN	*p_parent;
+	EVTTIM	event_evttim;
+
+	/*
+	 *  削除によりタイムイベントヒープが空になる場合は何もしない．
+	 */
+	if (--p_last_tmevtn < p_top_tmevtn) {
+		return;
+	}
+
+	/*
+	 *  削除したノードの位置に最後のノード（p_last_tmevtn + 1 の位置の
+	 *  ノード）を挿入し，それを適切な位置へ移動させる．実際には，最後
+	 *  のノードを実際に挿入するのではなく，削除したノードの位置が空ノー
+	 *  ドになるので，最後のノードを挿入すべき位置へ向けて空ノードを移
+	 *  動させる．
+	 *
+	 *  最後のノードのイベント発生時刻が，削除したノードの親ノードのイ
+	 *  ベント発生時刻より前の場合には，上に向かって挿入位置を探す．そ
+	 *  うでない場合には，下に向かって探す．
+	 */
+	event_evttim = (p_last_tmevtn + 1)->p_tmevtb->evttim;
+	if (p_tmevtn > p_top_tmevtn
+			&& EVTTIM_LT(event_evttim,
+						(p_parent = PARENT(p_tmevtn))->p_tmevtb->evttim)) {
+		/*
+		 *  親ノードをp_tmevtnの位置に移動させる．
+		 */
+		*p_tmevtn = *p_parent;
+		p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;
+
+		/*
+		 *  削除したノードの親ノードから上に向かって挿入位置を探す．
+		 */
+		p_tmevtn = tmevt_up(p_parent, event_evttim);
+	}
+	else {
+		/*
+		 *  削除したノードから下に向かって挿入位置を探す．
+		 */
+		p_tmevtn = tmevt_down(p_tmevtn, event_evttim);
+	}
+
+	/*
+	 *  最後のノードをp_tmevtnの位置に挿入する．
+	 */ 
+	*p_tmevtn = *(p_last_tmevtn + 1);
+	p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;
+}
+
+/*
+ *  タイムイベントヒープの先頭のノードの削除
+ */
+Inline TMEVTB *
+tmevtb_delete_top(void)
+{
+	TMEVTN	*p_tmevtn;
+	TMEVTB	*p_top_tmevtb = p_top_tmevtn->p_tmevtb;
+	EVTTIM	event_evttim;
+
+	/*
+	 *  削除によりタイムイベントヒープが空になる場合は何もしない．
+	 */
+	if (--p_last_tmevtn >= p_top_tmevtn) {
+		/*
+		 *  ルートノードに最後のノード（p_last_tmevtn + 1 の位置のノー
+		 *  ド）を挿入し，それを適切な位置へ移動させる．実際には，最後
+		 *  のノードを実際に挿入するのではなく，ルートノードが空ノード
+		 *  になるので，最後のノードを挿入すべき位置へ向けて空ノードを
+		 *  移動させる．
+		 */
+		event_evttim = (p_last_tmevtn + 1)->p_tmevtb->evttim;
+		p_tmevtn = tmevt_down(p_top_tmevtn, event_evttim);
+
+		/*
+		 *  最後のノードをp_tmevtnの位置に挿入する．
+		 */ 
+		*p_tmevtn = *(p_last_tmevtn + 1);
+		p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;
+	}
+	return(p_top_tmevtb);
+}
+
+/*
+ *  現在のイベント時刻の更新
+ */
+#ifdef TOPPERS_tmecur
+
+void
+update_current_evttim(void)
+{
+	HRTCNT	new_hrtcnt, hrtcnt_advance;
+	EVTTIM	previous_evttim;
+
+	new_hrtcnt = target_hrt_get_current();			/*［ASPD1013］*/
+	hrtcnt_advance = new_hrtcnt - current_hrtcnt;	/*［ASPD1014］*/
+#ifdef TCYC_HRTCNT
+	if (new_hrtcnt < current_hrtcnt) {
+		hrtcnt_advance += TCYC_HRTCNT;
+	}
+#endif /* TCYC_HRTCNT */
+
+	previous_evttim = current_evttim;
+	current_evttim += (EVTTIM) hrtcnt_advance;		/*［ASPD1015］*/
+	current_hrtcnt = new_hrtcnt;					/*［ASPD1016］*/
+	boundary_evttim = current_evttim - BOUNDARY_MARGIN;	/*［ASPD1011］*/
+
+	if (monotonic_evttim - previous_evttim < (EVTTIM) hrtcnt_advance) {
+#ifdef UINT64_MAX
+		if (current_evttim < monotonic_evttim) {
+			systim_offset += 1LLU << 32;			/*［ASPD1045］*/
+		}
+#endif /* UINT64_MAX */
+		monotonic_evttim = current_evttim;			/*［ASPD1042］*/
+	}
+}
+
+#endif /* TOPPERS_tmecur */
+
+/*
+ *  現在のイベント時刻を遅い方に丸めたイベント時刻の算出［ASPD1027］
+ *
+ *  現在のイベント時刻を更新した後に呼ぶことを想定している．
+ */
+Inline EVTTIM
+calc_current_evttim_ub(void)
+{
+	return(current_evttim + ((EVTTIM) TSTEP_HRTCNT));
+}
+
+/*
+ *  高分解能タイマ割込みの発生タイミングの設定
+ */
+#ifdef TOPPERS_tmeset
+
+void
+set_hrt_event(void)
+{
+	HRTCNT	hrtcnt;
+
+	if (p_last_tmevtn < p_top_tmevtn) {
+		target_hrt_set_event(HRTCNT_BOUND);			/*［ASPD1007］*/
+	}
+	else if (EVTTIM_LE(top_evttim, current_evttim)) {
+		target_hrt_raise_event();					/*［ASPD1017］*/
+	}
+	else {
+		hrtcnt = (HRTCNT)(top_evttim - current_evttim);
+		if (hrtcnt > HRTCNT_BOUND) {
+			target_hrt_set_event(HRTCNT_BOUND);		/*［ASPD1006］*/
+		}
+		else {
+			target_hrt_set_event(hrtcnt);			/*［ASPD1002］*/
+		}
+	}
+}
+
+#endif /* TOPPERS_tmeset */
+
+/*
+ *  タイムイベントブロックのヒープへの挿入
+ */
+#ifdef TOPPERS_tmereg
+
+void
+tmevtb_register(TMEVTB *p_tmevtb)
+{
+	tmevtb_insert(p_tmevtb);
+}
+
+#endif /* TOPPERS_tmereg */
+
+/*
+ *  相対時間指定によるタイムイベントの登録
+ *  
+ */
+#ifdef TOPPERS_tmeenq
+
+void
+tmevtb_enqueue(TMEVTB *p_tmevtb, RELTIM time)
+{
+	/*
+	 *  現在のイベント時刻とタイムイベントの発生時刻を求める［ASPD1026］．
+	 */
+	update_current_evttim();
+	p_tmevtb->evttim = calc_current_evttim_ub() + time;
+
+	/*
+	 *  タイムイベントブロックをヒープに挿入する［ASPD1030］．
+	 */
+	tmevtb_insert(p_tmevtb);
+
+	/*
+	 *  高分解能タイマ割込みの発生タイミングを設定する［ASPD1031］
+	 *  ［ASPD1034］．
+	 */
+	if (!in_signal_time && p_tmevtb->p_tmevtn == p_top_tmevtn) {
+		set_hrt_event();
+	}
+}
+
+#endif /* TOPPERS_tmeenq */
+
+/*
+ *  タイムイベントの登録解除
+ */
+#ifdef TOPPERS_tmedeq
+
+void
+tmevtb_dequeue(TMEVTB *p_tmevtb)
+{
+	TMEVTN	*p_tmevtn;
+
+	/*
+	 *  タイムイベントブロックをヒープから削除する［ASPD1039］．
+	 */
+	p_tmevtn = p_tmevtb->p_tmevtn;
+	tmevtb_delete(p_tmevtb);
+
+	/*
+	 *  高分解能タイマ割込みの発生タイミングを設定する［ASPD1040］．
+	 */
+	if (!in_signal_time && p_tmevtn == p_top_tmevtn) {
+		update_current_evttim();
+		set_hrt_event();
+	}
+}
+
+#endif /* TOPPERS_tmedeq */
+
+/*
+ *  システム時刻の調整時のエラーチェック
+ */
+#ifdef TOPPERS_tmechk
+
+bool_t
+check_adjtim(int_t adjtim)
+{
+	if (adjtim > 0) {
+		return(p_last_tmevtn >= p_top_tmevtn	/*［NGKI3588］*/
+					&& EVTTIM_LE(top_evttim, current_evttim - TMAX_ADJTIM));
+	}
+	else if (adjtim < 0) {						/*［NGKI3589］*/
+		return(monotonic_evttim - current_evttim >= -TMIN_ADJTIM);
+	}
+	return(false);
+}
+
+#endif /* TOPPERS_tmechk */
+
+/*
+ *  タイムイベントが発生するまでの時間の計算
+ */
+#ifdef TOPPERS_tmeltim
+
+RELTIM
+tmevt_lefttim(TMEVTB *p_tmevtb)
+{
+	EVTTIM	evttim, current_evttim_ub;
+
+	/*
+	 *  現在のイベント時刻を遅い方に丸めた時刻を求める［ASPD1050］．
+	 */
+	update_current_evttim();
+	current_evttim_ub = calc_current_evttim_ub();
+
+	/*
+	 *  タイムイベント発生までの相対時間を求める［ASPD1049］．
+	 */
+	evttim = p_tmevtb->evttim;
+	if (EVTTIM_LE(evttim, current_evttim_ub)) {
+		/*
+		 *  タイムイベントの発生時刻を過ぎている場合には0を返す［NGKI0552］．
+		 */
+		return(0U);
+	}
+	else {
+		return((RELTIM)(evttim - current_evttim_ub));
+	}
+}
+
+#endif /* TOPPERS_tmeltim */
+
+/*
+ *  高分解能タイマ割込みの処理
+ */
+#ifdef TOPPERS_sigtim
+
+void
+signal_time(void)
+{
+	TMEVTB	*p_tmevtb;
+	bool_t	callflag;
+
+	assert(sense_context());
+	assert(!sense_lock());
+
+	lock_cpu();
+	in_signal_time = true;							/*［ASPD1033］*/
+
+	do {
+		/*
+		 *  コールバック関数を呼び出さなければループを抜ける［ASPD1020］．
+		 */
+		callflag = false;
+
+		/*
+		 *  現在のイベント時刻を求める［ASPD1022］．
+		 */
+		update_current_evttim();
+
+		/*
+		 *  発生時刻がcurrent_evttim以前のタイムイベントがあれば，タイ
+		 *  ムイベントヒープから削除し，コールバック関数を呼び出す
+		 *  ［ASPD1018］［ASPD1019］．
+		 */
+		while (p_last_tmevtn >= p_top_tmevtn
+							&& EVTTIM_LE(top_evttim, current_evttim)) {
+			p_tmevtb = tmevtb_delete_top();
+			(*(p_tmevtb->callback))(p_tmevtb->arg);
+			callflag = true;
+		}
+	} while (callflag);								/*［ASPD1020］*/
+
+	/*
+	 *  高分解能タイマ割込みの発生タイミングを設定する［ASPD1025］．
+	 */
+	set_hrt_event();
+
+	in_signal_time = false;							/*［ASPD1033］*/
+	unlock_cpu();
+}
+
+#endif /* TOPPERS_sigtim */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/time_event.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/time_event.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/time_event.h	(revision 398)
@@ -0,0 +1,201 @@
+/*
+ *  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$
+ */
+
+/*
+ *		タイムイベント管理モジュール
+ */
+
+#ifndef TOPPERS_TIME_EVENT_H
+#define TOPPERS_TIME_EVENT_H
+
+#include "kernel_impl.h"
+#include "target_timer.h"
+
+/*
+ *  イベント時刻のデータ型の定義［ASPD1001］
+ *
+ *  タイムイベントヒープに登録するタイムイベントの発生時刻を表現するた
+ *  めのデータ型．オーバヘッド低減のために，32ビットで扱う．
+ */
+typedef uint32_t	EVTTIM;
+
+/*
+ *  タイムイベントヒープ中のノードのデータ型の前方参照
+ */
+typedef union time_event_node TMEVTN;
+
+/* 
+ *  タイムイベントブロックのデータ型の定義
+ */
+typedef void	(*CBACK)(void *);	/* コールバック関数の型 */
+
+typedef struct time_event_block {
+	EVTTIM	evttim;			/* タイムイベントの発生時刻 */
+	TMEVTN	*p_tmevtn;		/* タイムイベントヒープ中での位置 */
+	CBACK	callback;		/* コールバック関数 */
+	void	*arg;			/* コールバック関数へ渡す引数 */
+} TMEVTB;
+
+/*
+ *  タイムイベントヒープ中のノードのデータ型の定義
+ *
+ *  タイムイベントヒープの先頭のノード（tmevt_heap[0]）に，最後の使用領
+ *  域を指すポインタ（p_last）を格納し，それ以降をタイムイベントヒープ
+ *  として使用する．(tmevt_heap[0].p_last - tmevt_heap) が，タイムイベ
+ *  ントヒープに登録されているタイムイベントの数となる．
+ */
+union time_event_node {
+	TMEVTB	*p_tmevtb;		/* 対応するタイムイベントブロック */
+	TMEVTN	*p_last;		/* タイムイベントヒープの最後の使用領域 */
+};
+
+/*
+ *  タイムイベントヒープ（kernel_cfg.c）
+ */
+extern TMEVTN	tmevt_heap[];
+
+/*
+ *  境界イベント時刻［ASPD1008］
+ */
+extern EVTTIM	boundary_evttim;
+
+/*
+ *  現在のイベント時刻と境界イベント時刻の差［ASPD1010］
+ */
+#define BOUNDARY_MARGIN		(200000000U)
+
+/*
+ *  最後に現在時刻を算出した時点でのイベント時刻［ASPD1012］
+ */
+extern EVTTIM	current_evttim;
+
+/*
+ *  最後に現在時刻を算出した時点での高分解能タイマのカウント値［ASPD1012］
+ */
+extern HRTCNT	current_hrtcnt;
+
+/*
+ *  最も進んでいた時のイベント時刻［ASPD1041］
+ */
+extern EVTTIM	monotonic_evttim;
+
+/*
+ *  システム時刻のオフセット［ASPD1043］
+ *
+ *  get_timで参照するシステム時刻とmonotonic_evttimの差を保持する．
+ */
+extern SYSTIM	systim_offset;
+
+/*
+ *  高分解能タイマ割込みの処理中であることを示すフラグ［ASPD1032］
+ */
+extern bool_t	in_signal_time;
+
+/*
+ *  タイムイベント管理モジュールの初期化
+ */
+extern void	initialize_tmevt(void);
+
+/*
+ *  タイムイベントの挿入位置の探索
+ */
+extern TMEVTN	*tmevt_up(TMEVTN *p_tmevtn, EVTTIM evttim);
+extern TMEVTN	*tmevt_down(TMEVTN *p_tmevtn, EVTTIM evttim);
+
+/*
+ *  現在のイベント時刻の更新
+ *
+ *  current_evttimとcurrent_hrtcntを，現在の値に更新する．
+ */
+extern void		update_current_evttim(void);
+
+/*
+ *  高分解能タイマ割込みの発生タイミングの設定
+ *
+ *  現在のイベント時刻を取得した後に呼び出すことを想定している．
+ */
+extern void		set_hrt_event(void);
+
+/*
+ *  タイムイベントの登録
+ *
+ *  p_tmevtbで指定したタイムイベントブロックを登録する．タイムイベント
+ *  の発生時刻，コールバック関数，コールバック関数へ渡す引数は，
+ *  p_tmevtbが指すタイムイベントブロック中に設定しておく．
+ */
+extern void		tmevtb_register(TMEVTB *p_tmevtb);
+
+/*
+ *  相対時間指定によるタイムイベントの登録
+ *
+ *  timeで指定した相対時間が経過した後にコールバック関数が呼び出される
+ *  ように，p_tmevtbで指定したタイムイベントブロックを登録する．コール
+ *  バック関数，コールバック関数へ渡す引数は，p_tmevtbが指すタイムイベ
+ *  ントブロック中に設定しておく．
+ */
+extern void		tmevtb_enqueue(TMEVTB *p_tmevtb, RELTIM time);
+
+/*
+ *  タイムイベントの登録解除
+ */
+extern void		tmevtb_dequeue(TMEVTB *p_tmevtb);
+
+/*
+ *  システム時刻の調整時のエラーチェック
+ *
+ *  adjtimで指定された時間の分，システム時刻を調整してよいか判定する．
+ *  調整してはならない場合にtrue，そうでない場合にfalseを返す．現在のイ
+ *  ベント時刻を取得した後に呼び出すことを想定している．
+ */
+extern bool_t	check_adjtim(int_t adjtim);
+
+/*
+ *  タイムイベントが発生するまでの時間の計算
+ */
+extern RELTIM	tmevt_lefttim(TMEVTB *p_tmevtb);
+
+/*
+ *  高分解能タイマ割込みの処理
+ */
+extern void	signal_time(void);
+
+#endif /* TOPPERS_TIME_EVENT_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/time_manage.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/time_manage.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/time_manage.c	(revision 398)
@@ -0,0 +1,376 @@
+/*
+ *  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 "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "time_event.h"
+#include "target_timer.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_SET_TIM_ENTER
+#define LOG_SET_TIM_ENTER(systim)
+#endif /* LOG_SET_TIM_ENTER */
+
+#ifndef LOG_SET_TIM_LEAVE
+#define LOG_SET_TIM_LEAVE(ercd)
+#endif /* LOG_SET_TIM_LEAVE */
+
+#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, p_systim)
+#endif /* LOG_GET_TIM_LEAVE */
+
+#ifndef LOG_ADJ_TIM_ENTER
+#define LOG_ADJ_TIM_ENTER(adjtim)
+#endif /* LOG_ADJ_TIM_ENTER */
+
+#ifndef LOG_ADJ_TIM_LEAVE
+#define LOG_ADJ_TIM_LEAVE(ercd)
+#endif /* LOG_ADJ_TIM_LEAVE */
+
+#ifndef LOG_FCH_HRT_ENTER
+#define LOG_FCH_HRT_ENTER()
+#endif /* LOG_FCH_HRT_ENTER */
+
+#ifndef LOG_FCH_HRT_LEAVE
+#define LOG_FCH_HRT_LEAVE(hrtcnt)
+#endif /* LOG_FCH_HRT_LEAVE */
+
+/*
+ *  システム時刻の設定［NGKI3563］
+ */
+#ifdef TOPPERS_set_tim
+
+ER
+set_tim(SYSTIM systim)
+{
+	ER		ercd;
+
+	LOG_SET_TIM_ENTER(systim);
+	CHECK_TSKCTX_UNL();							/*［NGKI3564］［NGKI3565］*/
+
+	lock_cpu();
+	update_current_evttim();					/*［ASPD1059］*/
+	systim_offset = systim - monotonic_evttim;	/*［ASPD1060］*/
+	ercd = E_OK;
+	unlock_cpu();
+
+  error_exit:
+	LOG_SET_TIM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_set_tim */
+
+/*
+ *  システム時刻の参照［NGKI2349］
+ */
+#ifdef TOPPERS_get_tim
+
+ER
+get_tim(SYSTIM *p_systim)
+{
+	ER		ercd;
+
+	LOG_GET_TIM_ENTER(p_systim);
+	CHECK_TSKCTX_UNL();							/*［NGKI2350］［NGKI2351］*/
+
+	lock_cpu();
+	update_current_evttim();					/*［ASPD1057］*/
+	*p_systim = systim_offset + monotonic_evttim;	/*［ASPD1058］*/
+	ercd = E_OK;
+	unlock_cpu();
+
+  error_exit:
+	LOG_GET_TIM_LEAVE(ercd, p_systim);
+	return(ercd);
+}
+
+#endif /* TOPPERS_get_tim */
+
+/*
+ *  システム時刻の調整［NGKI3581］
+ */
+#ifdef TOPPERS_adj_tim
+
+ER
+adj_tim(int32_t adjtim)
+{
+	EVTTIM	previous_evttim;
+	ER		ercd;
+
+	LOG_ADJ_TIM_ENTER(adjtim);
+	CHECK_UNL();								/*［NGKI3583］*/
+	CHECK_PAR(TMIN_ADJTIM <= adjtim && adjtim <= TMAX_ADJTIM);
+												/*［NGKI3584］*/
+	lock_cpu();
+	update_current_evttim();					/*［ASPD1051］*/
+	if (check_adjtim(adjtim)) {					/*［ASPD1052］*/
+		ercd = E_OBJ;
+	}
+	else {
+		previous_evttim = current_evttim;
+		current_evttim += adjtim;				/*［ASPD1053］*/
+		boundary_evttim = current_evttim - BOUNDARY_MARGIN;	/*［ASPD1055］*/
+
+		if (adjtim > 0
+				&& monotonic_evttim - previous_evttim < (EVTTIM) adjtim) {
+#ifdef UINT64_MAX
+			if (current_evttim < monotonic_evttim) {
+				systim_offset += 1LLU << 32;
+			}
+#endif /* UINT64_MAX */
+			monotonic_evttim = current_evttim;	/*［ASPD1054］*/
+		}
+
+		set_hrt_event();						/*［ASPD1056］*/
+		ercd = E_OK;
+	}
+	unlock_cpu();
+
+  error_exit:
+	LOG_ADJ_TIM_LEAVE(ercd);
+	return(ercd);
+}
+
+#endif /* TOPPERS_adj_tim */
+
+/*
+ *  高分解能タイマの参照［NGKI3569］
+ *
+ *  任意の状態から呼び出せるようにするために，SILの全割込みロック状態の
+ *  制御機能を用いて，排他制御を実現している［NGKI3572］．
+ */
+#ifdef TOPPERS_fch_hrt
+
+HRTCNT
+fch_hrt(void)
+{
+	HRTCNT	hrtcnt;
+	SIL_PRE_LOC;
+
+	LOG_FCH_HRT_ENTER();
+
+	SIL_LOC_INT();
+	hrtcnt = target_hrt_get_current();			/*［NGKI3571］*/
+	SIL_UNL_INT();
+
+	LOG_FCH_HRT_LEAVE(hrtcnt);
+	return(hrtcnt);
+}
+
+#endif /* TOPPERS_fch_hrt */
+
+/*
+ *  通知方法のエラーチェック
+ */
+#ifdef TOPPERS_chknfy
+
+ER
+check_nfyinfo(const T_NFYINFO *p_nfyinfo)
+{
+	ER		ercd;
+
+	if (p_nfyinfo->nfymode == TNFY_HANDLER) {
+		CHECK_PAR(FUNC_ALIGN(p_nfyinfo->nfy.handler.tmehdr));
+		CHECK_PAR(FUNC_NONNULL(p_nfyinfo->nfy.handler.tmehdr));
+	}
+	else {
+		switch (p_nfyinfo->nfymode & 0x0fU) {
+		case TNFY_SETVAR:
+			CHECK_PAR((p_nfyinfo->nfymode & ~0x0fU) == 0);
+			CHECK_PAR(INTPTR_ALIGN(p_nfyinfo->nfy.setvar.p_var));
+			CHECK_PAR(INTPTR_NONNULL(p_nfyinfo->nfy.setvar.p_var));
+			break;
+		case TNFY_INCVAR:
+			CHECK_PAR((p_nfyinfo->nfymode & ~0x0fU) == 0);
+			CHECK_PAR(INTPTR_ALIGN(p_nfyinfo->nfy.incvar.p_var));
+			CHECK_PAR(INTPTR_NONNULL(p_nfyinfo->nfy.incvar.p_var));
+			break;
+		case TNFY_ACTTSK:
+			CHECK_ID(VALID_TSKID(p_nfyinfo->nfy.acttsk.tskid));
+			break;
+		case TNFY_WUPTSK:
+			CHECK_ID(VALID_TSKID(p_nfyinfo->nfy.wuptsk.tskid));
+			break;
+		case TNFY_SIGSEM:
+			CHECK_ID(VALID_SEMID(p_nfyinfo->nfy.sigsem.semid));
+			break;
+		case TNFY_SETFLG:
+			CHECK_ID(VALID_FLGID(p_nfyinfo->nfy.setflg.flgid));
+			break;
+		case TNFY_SNDDTQ:
+			CHECK_ID(VALID_DTQID(p_nfyinfo->nfy.snddtq.dtqid));
+			break;
+		default:
+			CHECK_PAR(false);
+			break;
+		}
+		switch (p_nfyinfo->nfymode & ~0x0fU) {
+		case 0:
+			break;
+		case TENFY_SETVAR:
+			CHECK_PAR(INTPTR_ALIGN(p_nfyinfo->enfy.setvar.p_var));
+			CHECK_PAR(INTPTR_NONNULL(p_nfyinfo->enfy.setvar.p_var));
+			break;
+		case TENFY_INCVAR:
+			CHECK_PAR(INTPTR_ALIGN(p_nfyinfo->enfy.incvar.p_var));
+			CHECK_PAR(INTPTR_NONNULL(p_nfyinfo->enfy.incvar.p_var));
+			break;
+		case TENFY_ACTTSK:
+			CHECK_ID(VALID_TSKID(p_nfyinfo->enfy.acttsk.tskid));
+			break;
+		case TENFY_WUPTSK:
+			CHECK_ID(VALID_TSKID(p_nfyinfo->enfy.wuptsk.tskid));
+			break;
+		case TENFY_SIGSEM:
+			CHECK_ID(VALID_SEMID(p_nfyinfo->enfy.sigsem.semid));
+			break;
+		case TENFY_SETFLG:
+			CHECK_ID(VALID_FLGID(p_nfyinfo->enfy.setflg.flgid));
+			break;
+		case TENFY_SNDDTQ:
+			CHECK_ID(VALID_DTQID(p_nfyinfo->enfy.snddtq.dtqid));
+			break;
+		default:
+			CHECK_PAR(false);
+			break;
+		}
+	}
+	ercd = E_OK;
+
+  error_exit:
+	return(ercd);
+}
+
+#endif /* TOPPERS_chknfy */
+
+/*
+ *  通知ハンドラ
+ */
+#ifdef TOPPERS_nfyhdr
+
+void
+notify_handler(intptr_t exinf)
+{
+	T_NFYINFO	*p_nfyinfo = (T_NFYINFO *) exinf;
+	ER			ercd;
+
+	switch (p_nfyinfo->nfymode & 0x0fU) {
+	case TNFY_SETVAR:
+		*(p_nfyinfo->nfy.setvar.p_var) = p_nfyinfo->nfy.setvar.value;
+		ercd = E_OK;
+		break;
+	case TNFY_INCVAR:
+		(void) loc_cpu();
+		*(p_nfyinfo->nfy.incvar.p_var) += 1;
+		(void) unl_cpu();
+		ercd = E_OK;
+		break;
+	case TNFY_ACTTSK:
+		ercd = act_tsk(p_nfyinfo->nfy.acttsk.tskid);
+		break;
+	case TNFY_WUPTSK:
+		ercd = wup_tsk(p_nfyinfo->nfy.wuptsk.tskid);
+		break;
+	case TNFY_SIGSEM:
+		ercd = sig_sem(p_nfyinfo->nfy.sigsem.semid);
+		break;
+	case TNFY_SETFLG:
+		ercd = set_flg(p_nfyinfo->nfy.setflg.flgid,
+							p_nfyinfo->nfy.setflg.flgptn);
+		break;
+	case TNFY_SNDDTQ:
+		ercd = psnd_dtq(p_nfyinfo->nfy.snddtq.dtqid,
+							p_nfyinfo->nfy.snddtq.data);
+		break;
+	default:
+		ercd = E_SYS;
+		break;
+	}
+
+	if (ercd != E_OK) {
+		switch (p_nfyinfo->nfymode & ~0x0fU) {
+		case TENFY_SETVAR:
+			*(p_nfyinfo->enfy.setvar.p_var) = (intptr_t) ercd;
+			break;
+		case TENFY_INCVAR:
+			(void) loc_cpu();
+			*(p_nfyinfo->enfy.incvar.p_var) += 1;
+			(void) unl_cpu();
+			break;
+		case TENFY_ACTTSK:
+			(void) act_tsk(p_nfyinfo->enfy.acttsk.tskid);
+			break;
+		case TENFY_WUPTSK:
+			(void) wup_tsk(p_nfyinfo->enfy.wuptsk.tskid);
+			break;
+		case TENFY_SIGSEM:
+			(void) sig_sem(p_nfyinfo->enfy.sigsem.semid);
+			break;
+		case TENFY_SETFLG:
+			(void) set_flg(p_nfyinfo->enfy.setflg.flgid,
+							p_nfyinfo->enfy.setflg.flgptn);
+			break;
+		case TENFY_SNDDTQ:
+			(void) psnd_dtq(p_nfyinfo->enfy.snddtq.dtqid, (intptr_t) ercd);
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+#endif /* TOPPERS_nfyhdr */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/wait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/wait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/wait.c	(revision 398)
@@ -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-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 "kernel_impl.h"
+#include "wait.h"
+
+/*
+ *  待ち状態への遷移（タイムアウト指定）
+ */
+#ifdef TOPPERS_waimake
+
+void
+make_wait_tmout(WINFO *p_winfo, TMEVTB *p_tmevtb, TMO tmout)
+{
+	make_non_runnable(p_runtsk);
+	p_runtsk->p_winfo = p_winfo;
+	if (tmout == TMO_FEVR) {
+		p_winfo->p_tmevtb = NULL;
+	}
+	else {
+		assert(tmout <= TMAX_RELTIM);
+		p_winfo->p_tmevtb = p_tmevtb;
+		p_tmevtb->callback = (CBACK) wait_tmout;
+		p_tmevtb->arg = (void *) p_runtsk;
+		tmevtb_enqueue(p_tmevtb, (RELTIM) tmout);
+	}
+}
+
+#endif /* TOPPERS_waimake */
+
+/*
+ *  待ち解除
+ */
+#ifdef TOPPERS_waicmp
+
+void
+wait_complete(TCB *p_tcb)
+{
+	wait_dequeue_tmevtb(p_tcb);
+	p_tcb->p_winfo->wercd = E_OK;
+	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;
+	make_non_wait(p_tcb);
+	if (p_runtsk != p_schedtsk) {
+		request_dispatch();
+	}
+
+	/*
+	 *  ここで優先度の高い割込みを受け付ける．
+	 */
+	unlock_cpu();
+	delay_for_interrupt();
+	lock_cpu();
+}
+
+#endif /* TOPPERS_waitmo */
+#ifdef TOPPERS_waitmook
+
+void
+wait_tmout_ok(TCB *p_tcb)
+{
+	p_tcb->p_winfo->wercd = E_OK;
+	make_non_wait(p_tcb);
+	if (p_runtsk != p_schedtsk) {
+		request_dispatch();
+	}
+
+	/*
+	 *  ここで優先度の高い割込みを受け付ける．
+	 */
+	unlock_cpu();
+	delay_for_interrupt();
+	lock_cpu();
+}
+
+#endif /* TOPPERS_waitmook */
+
+/*
+ *  実行中のタスクの同期・通信オブジェクトの待ちキューへの挿入
+ *
+ *  実行中のタスクを，同期・通信オブジェクトの待ちキューへ挿入する．オ
+ *  ブジェクトの属性に応じて，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
+
+void
+init_wait_queue(QUEUE *p_wait_queue)
+{
+	TCB		*p_tcb;
+
+	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;
+		make_non_wait(p_tcb);
+	}
+}
+
+#endif /* TOPPERS_iniwque */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/wait.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/wait.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/kernel/wait.h	(revision 398)
@@ -0,0 +1,275 @@
+/*
+ *  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-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_WAIT_H
+#define TOPPERS_WAIT_H
+
+#include "kernel_impl.h"
+#include <queue.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)
+{
+	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で指定されるタスクを，待ち解除するようタスク状態を更新する．
+ *  待ち解除するタスクが実行できる状態になる場合は，レディキューにつな
+ *  ぐ．
+ */
+Inline void
+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);
+		make_runnable(p_tcb);
+	}
+	else {
+		/*
+		 *  二重待ち状態から強制待ち状態への遷移
+		 */
+		p_tcb->tstat = TS_SUSPENDED;
+		LOG_TSKSTAT(p_tcb);
+	}
+}
+
+/*
+ *  オブジェクト待ちキューからの削除
+ *
+ *  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とする．待ちキュー
+ *  からの削除は行わない．
+ */
+extern void	wait_complete(TCB *p_tcb);
+
+/*
+ *  タイムアウトに伴う待ち解除
+ *
+ *  p_tcbで指定されるタスクが，待ちキューにつながれていれば待ちキュー
+ *  から削除し，タスク状態を更新する．また，待ち解除したタスクからの返
+ *  値を，wait_tmoutではE_TMOUT，wait_tmout_okではE_OKとする．
+ *
+ *  wait_tmout_okは，dly_tskで使うためのもので，待ちキューから削除する
+ *  処理を行わない．
+ *
+ *  いずれの関数も，タイムイベントのコールバック関数として用いるための
+ *  もので，割込みハンドラから呼び出されることを想定している．
+ */
+extern void	wait_tmout(TCB *p_tcb);
+extern void	wait_tmout_ok(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とする．
+ */
+extern void	init_wait_queue(QUEUE *p_wait_queue);
+
+#endif /* TOPPERS_WAIT_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/log_output.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/log_output.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/log_output.c	(revision 398)
@@ -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-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 <t_stddef.h>
+#include <t_syslog.h>
+#include <log_output.h>
+
+/*
+ *  数値を文字列に変換
+ */
+#define CONVERT_BUFLEN	((sizeof(ULOGPAR) * CHAR_BIT + 2) / 3)
+										/* ULOGPAR型の数値の最大文字数 */
+static void
+convert(ULOGPAR 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 LOGPAR *p_args, void (*putc)(char))
+{
+	char		c;
+	uint_t		width;
+	bool_t		padzero;
+	LOGPAR	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 == 't' || c == 'T') {
+			c = *format++;
+		}
+		switch (c) {
+		case 'd':
+			val = (LOGPAR)(*p_args++);
+			if (val >= 0) {
+				convert((ULOGPAR) val, 10U, raddec,
+											width, false, padzero, putc);
+			}
+			else {
+				convert((ULOGPAR)(-val), 10U, raddec,
+											width, true, padzero, putc);
+			}
+			break;
+		case 'u':
+			val = (LOGPAR)(*p_args++);
+			convert((ULOGPAR) val, 10U, raddec, width, false, padzero, putc);
+			break;
+		case 'x':
+		case 'p':
+			val = (LOGPAR)(*p_args++);
+			convert((ULOGPAR) val, 16U, radhex, width, false, padzero, putc);
+			break;
+		case 'X':
+			val = (LOGPAR)(*p_args++);
+			convert((ULOGPAR) val, 16U, radHEX, width, false, padzero, putc);
+			break;
+		case 'c':
+			(*putc)((char)(LOGPAR)(*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->logpar[0]),
+								&(p_syslog->logpar[1]), putc);
+		break;
+	case LOG_TYPE_ASSERT:
+		syslog_printf("%s:%u: Assertion `%s' failed.",
+								&(p_syslog->logpar[0]), putc);
+		break;
+	default:
+		/*
+		 *  他の種別のログ情報には対応していない．
+		 */
+		break;
+	}
+}
+
+/*
+ *  ログ情報喪失メッセージの出力
+ */
+void
+syslog_lostmsg(uint_t lostlog, void (*putc)(char))
+{
+	LOGPAR	lostinfo[1];
+
+	lostinfo[0] = (LOGPAR) lostlog;
+	syslog_printf("%d messages are lost.", lostinfo, putc);
+	(*putc)('\n');
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/strerror.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/strerror.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/strerror.c	(revision 398)
@@ -0,0 +1,115 @@
+/*
+ *  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-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 <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_RASTER:
+		return("E_RASTER");
+
+	case E_WBLK:
+		return("E_WBLK");
+	case E_BOVR:
+		return("E_BOVR");
+
+	case E_COMM:
+		return("E_COMM");
+
+	default:
+		return("unknown error");
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/t_perror.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/t_perror.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/t_perror.c	(revision 398)
@@ -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_mbedtls/trunk/asp3_dcre/library/vasyslog.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/vasyslog.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/library/vasyslog.c	(revision 398)
@@ -0,0 +1,115 @@
+/*
+ *  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-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 <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	sz;
+	char	c;
+
+	logbuf.logtype = LOG_TYPE_COMMENT;
+	logbuf.logpar[0] = (LOGPAR) format;
+	i = 1U;
+	va_start(ap, format);
+
+	while ((c = *format++) != '\0' && i < TNUM_LOGPAR) {
+		if (c != '%') {
+			continue;
+		}
+
+		sz = '\0';
+		c = *format++;
+		while ('0' <= c && c <= '9') {
+			c = *format++;
+		}
+		if (c == 'l' || c == 't' || c == 'T') {
+			sz = c;
+			c = *format++;
+		}
+		switch (c) {
+		case 'd':
+			logbuf.logpar[i++] = (sz == 'l') ? (LOGPAR) va_arg(ap, long_t)
+							   : (sz == 't') ? (LOGPAR) va_arg(ap, int32_t)
+							   : (sz == 'T') ? (LOGPAR) va_arg(ap, SYSTIM)
+							   : (LOGPAR) va_arg(ap, int_t);
+			break;
+		case 'u':
+		case 'x':
+		case 'X':
+			logbuf.logpar[i++] = (sz == 'l') ? (LOGPAR) va_arg(ap, ulong_t)
+							   : (sz == 't') ? (LOGPAR) va_arg(ap, uint32_t)
+							   : (sz == 'T') ? (LOGPAR) va_arg(ap, SYSTIM)
+							   : (LOGPAR) va_arg(ap, uint_t);
+			break;
+		case 'p':
+			logbuf.logpar[i++] = (LOGPAR) va_arg(ap, void *);
+			break;
+		case 'c':
+			logbuf.logpar[i++] = (LOGPAR) va_arg(ap, int);
+			break;
+		case 's':
+			logbuf.logpar[i++] = (LOGPAR) va_arg(ap, const char *);
+			break;
+		case '\0':
+			format--;
+			break;
+		default:
+			break;
+		}
+	}
+	va_end(ap);
+	(void) tSysLog_eSysLog_write(prio, &logbuf);
+}
+
+#endif /* TOPPERS_OMIT_SYSLOG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/Makefile.mbed
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/Makefile.mbed	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/Makefile.mbed	(revision 398)
@@ -0,0 +1,36 @@
+#
+#		Makefile のmbed（RZ/A1用）
+#
+#  $Id$
+# 
+
+#
+#  mbedディレクトリ名の定義
+#
+MBEDDIR = $(SRCDIR)/mbed
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES)\
+	-I$(MBEDDIR)\
+	-I$(MBEDDIR)/hal\
+	-I$(MBEDDIR)/platform\
+	-I$(MBEDDIR)/target
+COPTS := $(COPTS)
+LDFLAGS := $(LDFLAGS)
+CDEFS := $(CDEFS)
+
+#
+#  システムサービスに関する定義
+#
+SYSSVC_DIRS := $(SYSSVC_DIRS)\
+	$(MBEDDIR)/hal\
+	$(MBEDDIR)/target
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+#START_OBJS = 
+SYSSVC_COBJS := $(SYSSVC_COBJS)\
+	mbed_api.o mbed_lp_ticker_api.o mbed_gpio.o mbed_pinmap_common.o\
+	mbed_us_ticker_api.o mbed_ticker_api.o
+#CFG_DMY := 
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/analogin_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/analogin_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/analogin_api.h	(revision 398)
@@ -0,0 +1,71 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_ANALOGIN_API_H
+#define MBED_ANALOGIN_API_H
+
+#include "device.h"
+
+#if DEVICE_ANALOGIN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Analogin hal structure. analogin_s is declared in the target's hal
+ */
+typedef struct analogin_s analogin_t;
+
+/**
+ * \defgroup hal_analogin Analogin hal functions
+ * @{
+ */
+
+/** Initialize the analogin peripheral
+ *
+ * Configures the pin used by analogin.
+ * @param obj The analogin object to initialize
+ * @param pin The analogin pin name
+ */
+void analogin_init(analogin_t *obj, PinName pin);
+
+/** Read the input voltage, represented as a float in the range [0.0, 1.0]
+ *
+ * @param obj The analogin object
+ * @return A floating value representing the current input voltage
+ */
+float analogin_read(analogin_t *obj);
+
+/** Read the value from analogin pin, represented as an unsigned 16bit value
+ *
+ * @param obj The analogin object
+ * @return An unsigned 16bit value representing the current input voltage
+ */
+uint16_t analogin_read_u16(analogin_t *obj);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/analogout_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/analogout_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/analogout_api.h	(revision 398)
@@ -0,0 +1,93 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_ANALOGOUT_API_H
+#define MBED_ANALOGOUT_API_H
+
+#include "device.h"
+
+#if DEVICE_ANALOGOUT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Analogout hal structure. dac_s is declared in the target's hal
+ */
+typedef struct dac_s dac_t;
+
+/**
+ * \defgroup hal_analogout Analogout hal functions
+ * @{
+ */
+
+/** Initialize the analogout peripheral
+ *
+ * Configures the pin used by analogout.
+ * @param obj The analogout object to initialize
+ * @param pin The analogout pin name
+ */
+void analogout_init(dac_t *obj, PinName pin);
+
+/** Release the analogout object
+ *
+ * Note: This is not currently used in the mbed-drivers
+ * @param obj The analogout object
+ */
+void analogout_free(dac_t *obj);
+
+/** Set the output voltage, specified as a percentage (float)
+ *
+ * @param obj The analogin object
+ * @param value The floating-point output voltage to be set
+ */
+void analogout_write(dac_t *obj, float value);
+
+/** Set the output voltage, specified as unsigned 16-bit
+ *
+ * @param obj The analogin object
+ * @param value The unsigned 16-bit output voltage to be set
+ */
+void analogout_write_u16(dac_t *obj, uint16_t value);
+
+/** Read the current voltage value on the pin
+ *
+ * @param obj The analogin object
+ * @return A floating-point value representing the current voltage on the pin,
+ *     measured as a percentage
+ */
+float analogout_read(dac_t *obj);
+
+/** Read the current voltage value on the pin, as a normalized unsigned 16bit value
+ *
+ * @param obj The analogin object
+ * @return An unsigned 16-bit value representing the current voltage on the pin
+ */
+uint16_t analogout_read_u16(dac_t *obj);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/buffer.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/buffer.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/buffer.h	(revision 398)
@@ -0,0 +1,35 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2014-2015 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.
+ */
+#ifndef MBED_BUFFER_H
+#define MBED_BUFFER_H
+
+#include <stddef.h>
+
+/** Generic buffer structure
+ */
+typedef struct buffer_s {
+    void    *buffer; /**< the pointer to a buffer */
+    size_t   length; /**< the buffer length */
+    size_t   pos;    /**< actual buffer position */
+    uint8_t  width;  /**< The buffer unit width (8, 16, 32, 64), used for proper *buffer casting */
+} buffer_t;
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/can_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/can_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/can_api.h	(revision 398)
@@ -0,0 +1,85 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2016 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.
+ */
+#ifndef MBED_CAN_API_H
+#define MBED_CAN_API_H
+
+#include "device.h"
+
+#if DEVICE_CAN
+
+#include "PinNames.h"
+#include "PeripheralNames.h"
+#include "hal/can_helper.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    IRQ_RX,
+    IRQ_TX,
+    IRQ_ERROR,
+    IRQ_OVERRUN,
+    IRQ_WAKEUP,
+    IRQ_PASSIVE,
+    IRQ_ARB,
+    IRQ_BUS,
+    IRQ_READY
+} CanIrqType;
+
+
+typedef enum {
+    MODE_RESET,
+    MODE_NORMAL,
+    MODE_SILENT,
+    MODE_TEST_LOCAL,
+    MODE_TEST_GLOBAL,
+    MODE_TEST_SILENT
+} CanMode;
+
+typedef void (*can_irq_handler)(uint32_t id, CanIrqType type);
+
+typedef struct can_s can_t;
+
+void          can_init     (can_t *obj, PinName rd, PinName td);
+void          can_free     (can_t *obj);
+int           can_frequency(can_t *obj, int hz);
+
+void          can_irq_init (can_t *obj, can_irq_handler handler, uint32_t id);
+void          can_irq_free (can_t *obj);
+void          can_irq_set  (can_t *obj, CanIrqType irq, uint32_t enable);
+
+int           can_write    (can_t *obj, CAN_Message, int cc);
+int           can_read     (can_t *obj, CAN_Message *msg, int handle);
+int           can_mode     (can_t *obj, CanMode mode);
+int           can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle);
+void          can_reset    (can_t *obj);
+unsigned char can_rderror  (can_t *obj);
+unsigned char can_tderror  (can_t *obj);
+void          can_monitor  (can_t *obj, int silent);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif    // MBED_CAN_API_H
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/can_helper.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/can_helper.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/can_helper.h	(revision 398)
@@ -0,0 +1,58 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_CAN_HELPER_H
+#define MBED_CAN_HELPER_H
+
+#if DEVICE_CAN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum CANFormat {
+    CANStandard = 0,
+    CANExtended = 1,
+    CANAny = 2
+};
+typedef enum CANFormat CANFormat;
+
+enum CANType {
+    CANData   = 0,
+    CANRemote = 1
+};
+typedef enum CANType CANType;
+
+struct CAN_Message {
+    unsigned int   id;                 // 29 bit identifier
+    unsigned char  data[8];            // Data field
+    unsigned char  len;                // Length of data field in bytes
+    CANFormat      format;             // 0 - STANDARD, 1- EXTENDED IDENTIFIER
+    CANType        type;               // 0 - DATA FRAME, 1 - REMOTE FRAME
+};
+typedef struct CAN_Message CAN_Message;
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+
+#endif // MBED_CAN_HELPER_H
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/dma_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/dma_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/dma_api.h	(revision 398)
@@ -0,0 +1,50 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2014-2015 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.
+ */
+#ifndef MBED_DMA_API_H
+#define MBED_DMA_API_H
+
+#include <stdint.h>
+
+#define DMA_ERROR_OUT_OF_CHANNELS (-1)
+
+typedef enum {
+    DMA_USAGE_NEVER,
+    DMA_USAGE_OPPORTUNISTIC,
+    DMA_USAGE_ALWAYS,
+    DMA_USAGE_TEMPORARY_ALLOCATED,
+    DMA_USAGE_ALLOCATED
+} DMAUsage;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void dma_init(void);
+
+int dma_channel_allocate(uint32_t capabilities);
+
+int dma_channel_free(int channelid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/ethernet_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/ethernet_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/ethernet_api.h	(revision 398)
@@ -0,0 +1,72 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_ETHERNET_API_H
+#define MBED_ETHERNET_API_H
+
+#include "device.h"
+
+#if DEVICE_ETHERNET
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Descriptor info */
+#define NUM_OF_TX_DESCRIPTOR    (4)
+#define NUM_OF_RX_DESCRIPTOR    (4)
+
+// Connection constants
+
+int ethernet_init(void);
+void ethernet_free(void);
+
+// write size bytes from data to ethernet buffer
+// return num bytes written
+// or -1 if size is too big
+int ethernet_write(const char *data, int size);
+
+// send ethernet write buffer, returning the packet size sent
+int ethernet_send(void);
+
+// recieve from ethernet buffer, returning packet size, or 0 if no packet
+int ethernet_receive(void);
+
+// read size bytes in to data, return actual num bytes read (0..size)
+// if data == NULL, throw the bytes away
+int ethernet_read(char *data, int size);
+
+// get the ethernet address
+void ethernet_address(char *mac);
+
+// see if the link is up
+int ethernet_link(void);
+
+// force link settings
+void ethernet_set_link(int speed, int duplex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/gpio_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/gpio_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/gpio_api.h	(revision 398)
@@ -0,0 +1,133 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_GPIO_API_H
+#define MBED_GPIO_API_H
+
+#include <stdint.h>
+#include "device.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup hal_gpio GPIO HAL functions
+ * @{
+ */
+
+/** Set the given pin as GPIO
+ *
+ * @param pin The pin to be set as GPIO
+ * @return The GPIO port mask for this pin
+ **/
+uint32_t gpio_set(PinName pin);
+/* Checks if gpio object is connected (pin was not initialized with NC)
+ * @param pin The pin to be set as GPIO
+ * @return 0 if port is initialized with NC
+ **/
+int gpio_is_connected(const gpio_t *obj);
+
+/** Initialize the GPIO pin
+ *
+ * @param obj The GPIO object to initialize
+ * @param pin The GPIO pin to initialize
+ */
+void gpio_init(gpio_t *obj, PinName pin);
+
+/** Set the input pin mode
+ *
+ * @param obj  The GPIO object
+ * @param mode The pin mode to be set
+ */
+void gpio_mode(gpio_t *obj, PinMode mode);
+
+/** Set the pin direction
+ *
+ * @param obj       The GPIO object
+ * @param direction The pin direction to be set
+ */
+void gpio_dir(gpio_t *obj, PinDirection direction);
+
+/** Set the output value
+ *
+ * @param obj   The GPIO object
+ * @param value The value to be set
+ */
+void gpio_write(gpio_t *obj, int value);
+
+/** Read the input value
+ *
+ * @param obj The GPIO object
+ * @return An integer value 1 or 0
+ */
+int gpio_read(gpio_t *obj);
+
+// the following functions are generic and implemented in the common gpio.c file
+// TODO: fix, will be moved to the common gpio header file
+
+/** Init the input pin and set mode to PullDefault
+ *
+ * @param obj The GPIO object
+ * @param pin The pin name
+ */
+void gpio_init_in(gpio_t* gpio, PinName pin);
+
+/** Init the input pin and set the mode
+ *
+ * @param obj  The GPIO object
+ * @param pin  The pin name
+ * @param mode The pin mode to be set
+ */
+void gpio_init_in_ex(gpio_t* gpio, PinName pin, PinMode mode);
+
+/** Init the output pin as an output, with predefined output value 0
+ *
+ * @param obj The GPIO object
+ * @param pin The pin name
+ * @return An integer value 1 or 0
+ */
+void gpio_init_out(gpio_t* gpio, PinName pin);
+
+/** Init the pin as an output and set the output value
+ *
+ * @param obj   The GPIO object
+ * @param pin   The pin name
+ * @param value The value to be set
+ */
+void gpio_init_out_ex(gpio_t* gpio, PinName pin, int value);
+
+/** Init the pin to be in/out
+ *
+ * @param obj       The GPIO object
+ * @param pin       The pin name
+ * @param direction The pin direction to be set
+ * @param mode      The pin mode to be set
+ * @param value     The value to be set for an output pin
+ */
+void gpio_init_inout(gpio_t* gpio, PinName pin, PinDirection direction, PinMode mode, int value);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/gpio_irq_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/gpio_irq_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/gpio_irq_api.h	(revision 398)
@@ -0,0 +1,97 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_GPIO_IRQ_API_H
+#define MBED_GPIO_IRQ_API_H
+
+#include "device.h"
+
+#if DEVICE_INTERRUPTIN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** GPIO IRQ events
+ */
+typedef enum {
+    IRQ_NONE,
+    IRQ_RISE,
+    IRQ_FALL
+} gpio_irq_event;
+
+/** GPIO IRQ HAL structure. gpio_irq_s is declared in the target's HAL
+ */
+typedef struct gpio_irq_s gpio_irq_t;
+
+typedef void (*gpio_irq_handler)(uint32_t id, gpio_irq_event event);
+
+/**
+ * \defgroup hal_gpioirq GPIO IRQ HAL functions
+ * @{
+ */
+
+/** Initialize the GPIO IRQ pin
+ *
+ * @param obj     The GPIO object to initialize
+ * @param pin     The GPIO pin name
+ * @param handler The handler to be attached to GPIO IRQ
+ * @param id      The object ID (id != 0, 0 is reserved)
+ * @return -1 if pin is NC, 0 otherwise
+ */
+int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id);
+
+/** Release the GPIO IRQ PIN
+ *
+ * @param obj The gpio object
+ */
+void gpio_irq_free(gpio_irq_t *obj);
+
+/** Enable/disable pin IRQ event
+ *
+ * @param obj    The GPIO object
+ * @param event  The GPIO IRQ event
+ * @param enable The enable flag
+ */
+void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable);
+
+/** Enable GPIO IRQ
+ *
+ * This is target dependent, as it might enable the entire port or just a pin
+ * @param obj The GPIO object
+ */
+void gpio_irq_enable(gpio_irq_t *obj);
+
+/** Disable GPIO IRQ
+ *
+ * This is target dependent, as it might disable the entire port or just a pin
+ * @param obj The GPIO object
+ */
+void gpio_irq_disable(gpio_irq_t *obj);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/i2c_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/i2c_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/i2c_api.h	(revision 398)
@@ -0,0 +1,248 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 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.
+ */
+#ifndef MBED_I2C_API_H
+#define MBED_I2C_API_H
+
+#include "device.h"
+#include "hal/buffer.h"
+
+#if DEVICE_I2C_ASYNCH
+#include "hal/dma_api.h"
+#endif
+
+#if DEVICE_I2C
+
+/**
+ * @defgroup hal_I2CEvents I2C Events Macros
+ *
+ * @{
+ */
+#define I2C_EVENT_ERROR               (1 << 1)
+#define I2C_EVENT_ERROR_NO_SLAVE      (1 << 2)
+#define I2C_EVENT_TRANSFER_COMPLETE   (1 << 3)
+#define I2C_EVENT_TRANSFER_EARLY_NACK (1 << 4)
+#define I2C_EVENT_ALL                 (I2C_EVENT_ERROR |  I2C_EVENT_TRANSFER_COMPLETE | I2C_EVENT_ERROR_NO_SLAVE | I2C_EVENT_TRANSFER_EARLY_NACK)
+
+/**@}*/
+
+#if DEVICE_I2C_ASYNCH
+/** Asynch I2C HAL structure
+ */
+typedef struct {
+    struct i2c_s    i2c;     /**< Target specific I2C structure */
+    struct buffer_s tx_buff; /**< Tx buffer */
+    struct buffer_s rx_buff; /**< Rx buffer */
+} i2c_t;
+
+#else
+/** Non-asynch I2C HAL structure
+ */
+typedef struct i2c_s i2c_t;
+
+#endif
+
+enum {
+  I2C_ERROR_NO_SLAVE = -1,
+  I2C_ERROR_BUS_BUSY = -2
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup hal_GeneralI2C I2C Configuration Functions
+ * @{
+ */
+
+/** Initialize the I2C peripheral. It sets the default parameters for I2C
+ *  peripheral, and configures its specifieds pins.
+ *  
+ *  @param obj  The I2C object
+ *  @param sda  The sda pin
+ *  @param scl  The scl pin
+ */
+void i2c_init(i2c_t *obj, PinName sda, PinName scl);
+
+/** Configure the I2C frequency
+ *
+ *  @param obj The I2C object
+ *  @param hz  Frequency in Hz
+ */
+void i2c_frequency(i2c_t *obj, int hz);
+
+/** Send START command
+ *
+ *  @param obj The I2C object
+ */
+int  i2c_start(i2c_t *obj);
+
+/** Send STOP command
+ *
+ *  @param obj The I2C object
+ */
+int  i2c_stop(i2c_t *obj);
+
+/** Blocking reading data
+ *
+ *  @param obj     The I2C object
+ *  @param address 7-bit address (last bit is 1)
+ *  @param data    The buffer for receiving
+ *  @param length  Number of bytes to read
+ *  @param stop    Stop to be generated after the transfer is done
+ *  @return Number of read bytes
+ */
+int i2c_read(i2c_t *obj, int address, char *data, int length, int stop);
+
+/** Blocking sending data
+ *
+ *  @param obj     The I2C object
+ *  @param address 7-bit address (last bit is 0)
+ *  @param data    The buffer for sending
+ *  @param length  Number of bytes to write
+ *  @param stop    Stop to be generated after the transfer is done
+ *  @return 
+ *      zero or non-zero - Number of written bytes
+ *      negative - I2C_ERROR_XXX status
+ */
+int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop);
+
+/** Reset I2C peripheral. TODO: The action here. Most of the implementation sends stop()
+ *
+ *  @param obj The I2C object
+ */
+void i2c_reset(i2c_t *obj);
+
+/** Read one byte
+ *
+ *  @param obj The I2C object
+ *  @param last Acknoledge
+ *  @return The read byte
+ */
+int i2c_byte_read(i2c_t *obj, int last);
+
+/** Write one byte
+ *
+ *  @param obj The I2C object
+ *  @param data Byte to be written
+ *  @return 0 if NAK was received, 1 if ACK was received, 2 for timeout.
+ */
+int i2c_byte_write(i2c_t *obj, int data);
+
+/**@}*/
+
+#if DEVICE_I2CSLAVE
+
+/**
+ * \defgroup SynchI2C Synchronous I2C Hardware Abstraction Layer for slave
+ * @{
+ */
+
+/** Configure I2C as slave or master.
+ *  @param obj The I2C object
+ *  @return non-zero if a value is available
+ */
+void i2c_slave_mode(i2c_t *obj, int enable_slave);
+
+/** Check to see if the I2C slave has been addressed.
+ *  @param obj The I2C object
+ *  @return The status - 1 - read addresses, 2 - write to all slaves,
+ *         3 write addressed, 0 - the slave has not been addressed
+ */
+int  i2c_slave_receive(i2c_t *obj);
+
+/** Configure I2C as slave or master.
+ *  @param obj The I2C object
+ *  @return non-zero if a value is available
+ */
+int  i2c_slave_read(i2c_t *obj, char *data, int length);
+
+/** Configure I2C as slave or master.
+ *  @param obj The I2C object
+ *  @return non-zero if a value is available
+ */
+int  i2c_slave_write(i2c_t *obj, const char *data, int length);
+
+/** Configure I2C address.
+ *  @param obj     The I2C object
+ *  @param idx     Currently not used
+ *  @param address The address to be set
+ *  @param mask    Currently not used
+ */
+void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask);
+
+#endif
+
+/**@}*/
+
+#if DEVICE_I2C_ASYNCH
+
+/**
+ * \defgroup hal_AsynchI2C Asynchronous I2C Hardware Abstraction Layer
+ * @{
+ */
+
+/** Start I2C asynchronous transfer
+ *
+ *  @param obj       The I2C object
+ *  @param tx        The transmit buffer
+ *  @param tx_length The number of bytes to transmit
+ *  @param rx        The receive buffer
+ *  @param rx_length The number of bytes to receive
+ *  @param address   The address to be set - 7bit or 9bit
+ *  @param stop      If true, stop will be generated after the transfer is done
+ *  @param handler   The I2C IRQ handler to be set
+ *  @param hint      DMA hint usage
+ */
+void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint);
+
+/** The asynchronous IRQ handler
+ *
+ *  @param obj The I2C object which holds the transfer information
+ *  @return Event flags if a transfer termination condition was met, otherwise return 0.
+ */
+uint32_t i2c_irq_handler_asynch(i2c_t *obj);
+
+/** Attempts to determine if the I2C peripheral is already in use
+ *
+ *  @param obj The I2C object
+ *  @return Non-zero if the I2C module is active or zero if it is not
+ */
+uint8_t i2c_active(i2c_t *obj);
+
+/** Abort asynchronous transfer
+ *
+ *  This function does not perform any check - that should happen in upper layers.
+ *  @param obj The I2C object
+ */
+void i2c_abort_asynch(i2c_t *obj);
+
+#endif
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/lp_ticker_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/lp_ticker_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/lp_ticker_api.h	(revision 398)
@@ -0,0 +1,87 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 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.
+ */
+#ifndef MBED_LPTICKER_API_H
+#define MBED_LPTICKER_API_H
+
+#include "device.h"
+
+#if DEVICE_LOWPOWERTIMER
+
+#include "hal/ticker_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup hal_LpTicker Low Power Ticker Functions
+ * @{
+ */
+
+/** Get low power ticker's data
+ *
+ * @return The low power ticker data
+ */
+const ticker_data_t* get_lp_ticker_data(void);
+
+/** The wrapper for ticker_irq_handler, to pass lp ticker's data
+ *
+ */
+void lp_ticker_irq_handler(void);
+
+/* HAL lp ticker */
+
+/** Initialize the low power ticker
+ *
+ */
+void lp_ticker_init(void);
+
+/** Read the current counter
+ *
+ * @return The current timer's counter value in microseconds
+ */
+uint32_t lp_ticker_read(void);
+
+/** Set interrupt for specified timestamp
+ *
+ * @param timestamp The time in microseconds to be set
+ */
+void lp_ticker_set_interrupt(timestamp_t timestamp);
+
+/** Disable low power ticker interrupt
+ *
+ */
+void lp_ticker_disable_interrupt(void);
+
+/** Clear the low power ticker interrupt
+ *
+ */
+void lp_ticker_clear_interrupt(void);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_gpio.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_gpio.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_gpio.c	(revision 398)
@@ -0,0 +1,61 @@
+/* mbed Microcontroller 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.
+ */
+#include "hal/gpio_api.h"
+
+static inline void _gpio_init_in(gpio_t* gpio, PinName pin, PinMode mode)
+{
+    gpio_init(gpio, pin);
+    if (pin != NC) {
+        gpio_dir(gpio, PIN_INPUT);
+        gpio_mode(gpio, mode);
+    }
+}
+
+static inline void _gpio_init_out(gpio_t* gpio, PinName pin, PinMode mode, int value)
+{
+    gpio_init(gpio, pin);
+    if (pin != NC) {
+        gpio_write(gpio, value);
+        gpio_dir(gpio, PIN_OUTPUT);
+        gpio_mode(gpio, mode);
+    }
+}
+
+void gpio_init_in(gpio_t* gpio, PinName pin) {
+    gpio_init_in_ex(gpio, pin, PullDefault);
+}
+
+void gpio_init_in_ex(gpio_t* gpio, PinName pin, PinMode mode) {
+    _gpio_init_in(gpio, pin, mode);
+}
+
+void gpio_init_out(gpio_t* gpio, PinName pin) {
+    gpio_init_out_ex(gpio, pin, 0);
+}
+
+void gpio_init_out_ex(gpio_t* gpio, PinName pin, int value) {
+    _gpio_init_out(gpio, pin, PullNone, value);
+}
+
+void gpio_init_inout(gpio_t* gpio, PinName pin, PinDirection direction, PinMode mode, int value) {
+    if (direction == PIN_INPUT) {
+        _gpio_init_in(gpio, pin, mode);
+        if (pin != NC)
+            gpio_write(gpio, value); // we prepare the value in case it is switched later
+    } else {
+        _gpio_init_out(gpio, pin, mode, value);
+    }
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_lp_ticker_api.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_lp_ticker_api.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_lp_ticker_api.c	(revision 398)
@@ -0,0 +1,45 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 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.
+ */
+#include "hal/lp_ticker_api.h"
+
+#if DEVICE_LOWPOWERTIMER
+
+static ticker_event_queue_t events;
+
+static const ticker_interface_t lp_interface = {
+    .init = lp_ticker_init,
+    .read = lp_ticker_read,
+    .disable_interrupt = lp_ticker_disable_interrupt,
+    .clear_interrupt = lp_ticker_clear_interrupt,
+    .set_interrupt = lp_ticker_set_interrupt,
+};
+
+static const ticker_data_t lp_data = {
+    .interface = &lp_interface,
+    .queue = &events,
+};
+
+const ticker_data_t* get_lp_ticker_data(void)
+{
+    return &lp_data;
+}
+
+void lp_ticker_irq_handler(void)
+{
+    ticker_irq_handler(&lp_data);
+}
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_pinmap_common.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_pinmap_common.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_pinmap_common.c	(revision 398)
@@ -0,0 +1,89 @@
+/* mbed Microcontroller 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.
+ */
+#include "hal/pinmap.h"
+#include "platform/mbed_error.h"
+
+void pinmap_pinout(PinName pin, const PinMap *map) {
+    if (pin == NC)
+        return;
+
+    while (map->pin != NC) {
+        if (map->pin == pin) {
+            pin_function(pin, map->function);
+
+            pin_mode(pin, PullNone);
+            return;
+        }
+        map++;
+    }
+    error("could not pinout");
+}
+
+uint32_t pinmap_merge(uint32_t a, uint32_t b) {
+    // both are the same (inc both NC)
+    if (a == b)
+        return a;
+
+    // one (or both) is not connected
+    if (a == (uint32_t)NC)
+        return b;
+    if (b == (uint32_t)NC)
+        return a;
+
+    // mis-match error case
+    error("pinmap mis-match");
+    return (uint32_t)NC;
+}
+
+uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map) {
+    while (map->pin != NC) {
+        if (map->pin == pin)
+            return map->peripheral;
+        map++;
+    }
+    return (uint32_t)NC;
+}
+
+uint32_t pinmap_peripheral(PinName pin, const PinMap* map) {
+    uint32_t peripheral = (uint32_t)NC;
+
+    if (pin == (PinName)NC)
+        return (uint32_t)NC;
+    peripheral = pinmap_find_peripheral(pin, map);
+    if ((uint32_t)NC == peripheral) // no mapping available
+        error("pinmap not found for peripheral");
+    return peripheral;
+}
+
+uint32_t pinmap_find_function(PinName pin, const PinMap* map) {
+    while (map->pin != NC) {
+        if (map->pin == pin)
+            return map->function;
+        map++;
+    }
+    return (uint32_t)NC;
+}
+
+uint32_t pinmap_function(PinName pin, const PinMap* map) {
+    uint32_t function = (uint32_t)NC;
+
+    if (pin == (PinName)NC)
+        return (uint32_t)NC;
+    function = pinmap_find_function(pin, map);
+    if ((uint32_t)NC == function) // no mapping available
+        error("pinmap not found for function");
+    return function;
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_ticker_api.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_ticker_api.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_ticker_api.c	(revision 398)
@@ -0,0 +1,137 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 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.
+ */
+#include <stddef.h>
+#include "hal/ticker_api.h"
+#include "platform/mbed_critical.h"
+
+void ticker_set_handler(const ticker_data_t *const data, ticker_event_handler handler) {
+    data->interface->init();
+
+    data->queue->event_handler = handler;
+}
+
+void ticker_irq_handler(const ticker_data_t *const data) {
+    data->interface->clear_interrupt();
+
+    /* Go through all the pending TimerEvents */
+    while (1) {
+        if (data->queue->head == NULL) {
+            // There are no more TimerEvents left, so disable matches.
+            data->interface->disable_interrupt();
+            return;
+        }
+
+        if ((int)(data->queue->head->timestamp - data->interface->read()) <= 0) {
+            // This event was in the past:
+            //      point to the following one and execute its handler
+            ticker_event_t *p = data->queue->head;
+            data->queue->head = data->queue->head->next;
+            if (data->queue->event_handler != NULL) {
+                (*data->queue->event_handler)(p->id); // NOTE: the handler can set new events
+            }
+            /* Note: We continue back to examining the head because calling the
+             * event handler may have altered the chain of pending events. */
+        } else {
+            // This event and the following ones in the list are in the future:
+            //      set it as next interrupt and return
+            data->interface->set_interrupt(data->queue->head->timestamp);
+            return;
+        }
+    }
+}
+
+void ticker_insert_event(const ticker_data_t *const data, ticker_event_t *obj, timestamp_t timestamp, uint32_t id) {
+    /* disable interrupts for the duration of the function */
+    core_util_critical_section_enter();
+
+    // initialise our data
+    obj->timestamp = timestamp;
+    obj->id = id;
+
+    /* Go through the list until we either reach the end, or find
+       an element this should come before (which is possibly the
+       head). */
+    ticker_event_t *prev = NULL, *p = data->queue->head;
+    while (p != NULL) {
+        /* check if we come before p */
+        if ((int)(timestamp - p->timestamp) < 0) {
+            break;
+        }
+        /* go to the next element */
+        prev = p;
+        p = p->next;
+    }
+    
+    /* if we're at the end p will be NULL, which is correct */
+    obj->next = p;
+
+    /* if prev is NULL we're at the head */
+    if (prev == NULL) {
+        data->queue->head = obj;
+        data->interface->set_interrupt(timestamp);
+    } else {
+        prev->next = obj;
+    }
+
+    core_util_critical_section_exit();
+}
+
+void ticker_remove_event(const ticker_data_t *const data, ticker_event_t *obj) {
+    core_util_critical_section_enter();
+
+    // remove this object from the list
+    if (data->queue->head == obj) {
+        // first in the list, so just drop me
+        data->queue->head = obj->next;
+        if (data->queue->head == NULL) {
+            data->interface->disable_interrupt();
+        } else {
+            data->interface->set_interrupt(data->queue->head->timestamp);
+        }
+    } else {
+        // find the object before me, then drop me
+        ticker_event_t* p = data->queue->head;
+        while (p != NULL) {
+            if (p->next == obj) {
+                p->next = obj->next;
+                break;
+            }
+            p = p->next;
+        }
+    }
+
+    core_util_critical_section_exit();
+}
+
+timestamp_t ticker_read(const ticker_data_t *const data)
+{
+    return data->interface->read();
+}
+
+int ticker_get_next_timestamp(const ticker_data_t *const data, timestamp_t *timestamp)
+{
+    int ret = 0;
+
+    /* if head is NULL, there are no pending events */
+    core_util_critical_section_enter();
+    if (data->queue->head != NULL) {
+        *timestamp = data->queue->head->timestamp;
+        ret = 1;
+    }
+    core_util_critical_section_exit();
+
+    return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_us_ticker_api.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_us_ticker_api.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/mbed_us_ticker_api.c	(revision 398)
@@ -0,0 +1,41 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 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.
+ */
+#include "hal/us_ticker_api.h"
+
+static ticker_event_queue_t events;
+
+static const ticker_interface_t us_interface = {
+    .init = us_ticker_init,
+    .read = us_ticker_read,
+    .disable_interrupt = us_ticker_disable_interrupt,
+    .clear_interrupt = us_ticker_clear_interrupt,
+    .set_interrupt = us_ticker_set_interrupt,
+};
+
+static const ticker_data_t us_data = {
+    .interface = &us_interface,
+    .queue = &events,
+};
+
+const ticker_data_t* get_us_ticker_data(void)
+{
+    return &us_data;
+}
+
+void us_ticker_irq_handler(void)
+{
+    ticker_irq_handler(&us_data);
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/pinmap.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/pinmap.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/pinmap.h	(revision 398)
@@ -0,0 +1,50 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_PINMAP_H
+#define MBED_PINMAP_H
+
+#include "PinNames.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    PinName pin;
+    int peripheral;
+    int function;
+} PinMap;
+
+void pin_function(PinName pin, int function);
+void pin_mode    (PinName pin, PinMode mode);
+
+uint32_t pinmap_peripheral(PinName pin, const PinMap* map);
+uint32_t pinmap_function(PinName pin, const PinMap* map);
+uint32_t pinmap_merge     (uint32_t a, uint32_t b);
+void     pinmap_pinout    (PinName pin, const PinMap *map);
+uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map);
+uint32_t pinmap_find_function(PinName pin, const PinMap* map);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/port_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/port_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/port_api.h	(revision 398)
@@ -0,0 +1,93 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_PORTMAP_H
+#define MBED_PORTMAP_H
+
+#include "device.h"
+
+#if DEVICE_PORTIN || DEVICE_PORTOUT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Port HAL structure. port_s is declared in the target's HAL
+ */
+typedef struct port_s port_t;
+
+/**
+ * \defgroup hal_port Port HAL functions
+ * @{
+ */
+
+/** Get the pin name from the port's pin number
+ *
+ * @param port  The port name
+ * @param pin_n The pin number within the specified port
+ * @return The pin name for the port's pin number
+ */
+PinName port_pin(PortName port, int pin_n);
+
+/** Initilize the port
+ *
+ * @param obj  The port object to initialize
+ * @param port The port name
+ * @param mask The bitmask to identify which bits in the port should be included (0 - ignore)
+ * @param dir  The port direction
+ */
+void port_init(port_t *obj, PortName port, int mask, PinDirection dir);
+
+/** Set the input port mode
+ *
+ * @param obj  The port object
+ * @param mode THe port mode to be set
+ */
+void port_mode(port_t *obj, PinMode mode);
+
+/** Set port direction (in/out)
+ *
+ * @param obj The port object
+ * @param dir The port direction to be set
+ */
+void port_dir(port_t *obj, PinDirection dir);
+
+/** Write value to the port
+ *
+ * @param obj   The port object
+ * @param value The value to be set
+ */
+void port_write(port_t *obj, int value);
+
+/** Read the current value on the port
+ *
+ * @param obj The port object
+ * @return An integer with each bit corresponding to an associated port pin setting
+ */
+int port_read(port_t *obj);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/pwmout_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/pwmout_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/pwmout_api.h	(revision 398)
@@ -0,0 +1,120 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_PWMOUT_API_H
+#define MBED_PWMOUT_API_H
+
+#include "device.h"
+
+#if DEVICE_PWMOUT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Pwmout hal structure. pwmout_s is declared in the target's hal
+ */
+typedef struct pwmout_s pwmout_t;
+
+/**
+ * \defgroup hal_pwmout Pwmout hal functions
+ * @{
+ */
+
+/** Initialize the pwm out peripheral and configure the pin
+ *
+ * @param obj The pwmout object to initialize
+ * @param pin The pwmout pin to initialize
+ */
+void pwmout_init(pwmout_t *obj, PinName pin);
+
+/** Deinitialize the pwmout object
+ *
+ * @param obj The pwmout object
+ */
+void pwmout_free(pwmout_t *obj);
+
+/** Set the output duty-cycle in range <0.0f, 1.0f>
+ *
+ * Value 0.0f represents 0 percentage, 1.0f represents 100 percent.
+ * @param obj     The pwmout object
+ * @param percent The floating-point percentage number
+ */
+void pwmout_write(pwmout_t *obj, float percent);
+
+/** Read the current float-point output duty-cycle
+ *
+ * @param obj The pwmout object
+ * @return A floating-point output duty-cycle
+ */
+float pwmout_read(pwmout_t *obj);
+
+/** Set the PWM period specified in seconds, keeping the duty cycle the same
+ *
+ * Periods smaller than microseconds (the lowest resolution) are set to zero.
+ * @param obj     The pwmout object
+ * @param seconds The floating-point seconds period
+ */
+void pwmout_period(pwmout_t *obj, float seconds);
+
+/** Set the PWM period specified in miliseconds, keeping the duty cycle the same
+ *
+ * @param obj The pwmout object
+ * @param ms  The milisecond period
+ */
+void pwmout_period_ms(pwmout_t *obj, int ms);
+
+/** Set the PWM period specified in microseconds, keeping the duty cycle the same
+ *
+ * @param obj The pwmout object
+ * @param us  The microsecond period
+ */
+void pwmout_period_us(pwmout_t *obj, int us);
+
+/** Set the PWM pulsewidth specified in seconds, keeping the period the same.
+ *
+ * @param obj     The pwmout object
+ * @param seconds The floating-point pulsewidth in seconds
+ */
+void pwmout_pulsewidth(pwmout_t *obj, float seconds);
+
+/** Set the PWM pulsewidth specified in miliseconds, keeping the period the same.
+ *
+ * @param obj The pwmout object
+ * @param ms  The floating-point pulsewidth in miliseconds
+ */
+void pwmout_pulsewidth_ms(pwmout_t *obj, int ms);
+
+/** Set the PWM pulsewidth specified in microseconds, keeping the period the same.
+ *
+ * @param obj The pwmout object
+ * @param us  The floating-point pulsewidth in microseconds
+ */
+void pwmout_pulsewidth_us(pwmout_t *obj, int us);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/rtc_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/rtc_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/rtc_api.h	(revision 398)
@@ -0,0 +1,77 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_RTC_API_H
+#define MBED_RTC_API_H
+
+#include "device.h"
+
+#if DEVICE_RTC
+
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup hal_rtc RTC hal functions
+ * @{
+ */
+
+/** Initialize the RTC peripheral
+ *
+ */
+void rtc_init(void);
+
+/** Deinitialize RTC
+ *
+ * TODO: The function is not used by rtc api in mbed-drivers.
+ */
+void rtc_free(void);
+
+/** Get the RTC enable status
+ *
+ * @retval 0 disabled
+ * @retval 1 enabled
+ */
+int rtc_isenabled(void);
+
+/** Get the current time from the RTC peripheral
+ *
+ * @return The current time
+ */
+time_t rtc_read(void);
+
+/** Set the current time to the RTC peripheral
+ *
+ * @param t The current time to be set
+ */
+void rtc_write(time_t t);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/serial_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/serial_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/serial_api.h	(revision 398)
@@ -0,0 +1,307 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_SERIAL_API_H
+#define MBED_SERIAL_API_H
+
+#include "device.h"
+#include "hal/buffer.h"
+#include "hal/dma_api.h"
+
+#if DEVICE_SERIAL
+
+#define SERIAL_EVENT_TX_SHIFT (2)
+#define SERIAL_EVENT_RX_SHIFT (8)
+
+#define SERIAL_EVENT_TX_MASK (0x00FC)
+#define SERIAL_EVENT_RX_MASK (0x3F00)
+
+#define SERIAL_EVENT_ERROR (1 << 1)
+
+/**
+ * @defgroup SerialTXEvents Serial TX Events Macros
+ *
+ * @{
+ */
+#define SERIAL_EVENT_TX_COMPLETE (1 << (SERIAL_EVENT_TX_SHIFT + 0))
+#define SERIAL_EVENT_TX_ALL      (SERIAL_EVENT_TX_COMPLETE)
+/**@}*/
+
+/**
+ * @defgroup SerialRXEvents Serial RX Events Macros
+ *
+ * @{
+ */
+#define SERIAL_EVENT_RX_COMPLETE        (1 << (SERIAL_EVENT_RX_SHIFT + 0))
+#define SERIAL_EVENT_RX_OVERRUN_ERROR   (1 << (SERIAL_EVENT_RX_SHIFT + 1))
+#define SERIAL_EVENT_RX_FRAMING_ERROR   (1 << (SERIAL_EVENT_RX_SHIFT + 2))
+#define SERIAL_EVENT_RX_PARITY_ERROR    (1 << (SERIAL_EVENT_RX_SHIFT + 3))
+#define SERIAL_EVENT_RX_OVERFLOW        (1 << (SERIAL_EVENT_RX_SHIFT + 4))
+#define SERIAL_EVENT_RX_CHARACTER_MATCH (1 << (SERIAL_EVENT_RX_SHIFT + 5))
+#define SERIAL_EVENT_RX_ALL             (SERIAL_EVENT_RX_OVERFLOW | SERIAL_EVENT_RX_PARITY_ERROR | \
+                                         SERIAL_EVENT_RX_FRAMING_ERROR | SERIAL_EVENT_RX_OVERRUN_ERROR | \
+                                         SERIAL_EVENT_RX_COMPLETE | SERIAL_EVENT_RX_CHARACTER_MATCH)
+/**@}*/
+
+#define SERIAL_RESERVED_CHAR_MATCH (255)
+
+typedef enum {
+    ParityNone = 0,
+    ParityOdd = 1,
+    ParityEven = 2,
+    ParityForced1 = 3,
+    ParityForced0 = 4
+} SerialParity;
+
+typedef enum {
+    RxIrq,
+    TxIrq
+} SerialIrq;
+
+typedef enum {
+    FlowControlNone,
+    FlowControlRTS,
+    FlowControlCTS,
+    FlowControlRTSCTS
+} FlowControl;
+
+typedef void (*uart_irq_handler)(uint32_t id, SerialIrq event);
+
+#if DEVICE_SERIAL_ASYNCH
+/** Asynch serial HAL structure
+ */
+typedef struct {
+    struct serial_s serial;  /**< Target specific serial structure */
+    struct buffer_s tx_buff; /**< TX buffer */
+    struct buffer_s rx_buff; /**< RX buffer */
+    uint8_t char_match;      /**< Character to be matched */
+    uint8_t char_found;      /**< State of the matched character */
+} serial_t;
+
+#else
+/** Non-asynch serial HAL structure
+ */
+typedef struct serial_s serial_t;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup hal_GeneralSerial Serial Configuration Functions
+ * @{
+ */
+
+/** Initialize the serial peripheral. It sets the default parameters for serial
+ *  peripheral, and configures its specifieds pins.
+ *
+ * @param obj The serial object
+ * @param tx  The TX pin name
+ * @param rx  The RX pin name
+ */
+void serial_init(serial_t *obj, PinName tx, PinName rx);
+
+/** Release the serial peripheral, not currently invoked. It requires further
+ *  resource management.
+ *
+ * @param obj The serial object
+ */
+void serial_free(serial_t *obj);
+
+/** Configure the baud rate
+ *
+ * @param obj      The serial object
+ * @param baudrate The baud rate to be configured
+ */
+void serial_baud(serial_t *obj, int baudrate);
+
+/** Configure the format. Set the number of bits, parity and the number of stop bits
+ *
+ * @param obj       The serial object
+ * @param data_bits The number of data bits
+ * @param parity    The parity
+ * @param stop_bits The number of stop bits
+ */
+void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits);
+
+/** The serial interrupt handler registration
+ *
+ * @param obj     The serial object
+ * @param handler The interrupt handler which will be invoked when the interrupt fires
+ * @param id      The SerialBase object
+ */
+void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id);
+
+/** Configure serial interrupt. This function is used for word-approach
+ *
+ * @param obj    The serial object
+ * @param irq    The serial IRQ type (RX or TX)
+ * @param enable Set to non-zero to enable events, or zero to disable them
+ */
+void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable);
+
+/** Get character. This is a blocking call, waiting for a character
+ *
+ * @param obj The serial object
+ */
+int  serial_getc(serial_t *obj);
+
+/** Send a character. This is a blocking call, waiting for a peripheral to be available
+ *  for writing
+ *
+ * @param obj The serial object
+ * @param c   The character to be sent
+ */
+void serial_putc(serial_t *obj, int c);
+
+/** Check if the serial peripheral is readable
+ *
+ * @param obj The serial object
+ * @return Non-zero value if a character can be read, 0 if nothing to read
+ */
+int  serial_readable(serial_t *obj);
+
+/** Check if the serial peripheral is writable
+ *
+ * @param obj The serial object
+ * @return Non-zero value if a character can be written, 0 otherwise.
+ */
+int  serial_writable(serial_t *obj);
+
+/** Clear the serial peripheral
+ *
+ * @param obj The serial object
+ */
+void serial_clear(serial_t *obj);
+
+/** Set the break
+ *
+ * @param obj The serial object
+ */
+void serial_break_set(serial_t *obj);
+
+/** Clear the break
+ *
+ * @param obj The serial object
+ */
+void serial_break_clear(serial_t *obj);
+
+/** Configure the TX pin for UART function.
+ *
+ * @param tx The pin name used for TX
+ */
+void serial_pinout_tx(PinName tx);
+
+/** Configure the serial for the flow control. It sets flow control in the hardware
+ *  if a serial peripheral supports it, otherwise software emulation is used.
+ *
+ * @param obj    The serial object
+ * @param type   The type of the flow control. Look at the available FlowControl types.
+ * @param rxflow The TX pin name
+ * @param txflow The RX pin name
+ */
+void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow);
+
+#if DEVICE_SERIAL_ASYNCH
+
+/**@}*/
+
+/**
+ * \defgroup hal_AsynchSerial Asynchronous Serial Hardware Abstraction Layer
+ * @{
+ */
+
+/** Begin asynchronous TX transfer. The used buffer is specified in the serial object,
+ *  tx_buff
+ *
+ * @param obj       The serial object
+ * @param tx        The transmit buffer
+ * @param tx_length The number of bytes to transmit
+ * @param tx_width  Deprecated argument
+ * @param handler   The serial handler
+ * @param event     The logical OR of events to be registered
+ * @param hint      A suggestion for how to use DMA with this transfer
+ * @return Returns number of data transfered, otherwise returns 0
+ */
+int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint);
+
+/** Begin asynchronous RX transfer (enable interrupt for data collecting)
+ *  The used buffer is specified in the serial object - rx_buff
+ *
+ * @param obj        The serial object
+ * @param rx         The receive buffer
+ * @param rx_length  The number of bytes to receive
+ * @param rx_width   Deprecated argument
+ * @param handler    The serial handler
+ * @param event      The logical OR of events to be registered
+ * @param handler    The serial handler
+ * @param char_match A character in range 0-254 to be matched
+ * @param hint       A suggestion for how to use DMA with this transfer
+ */
+void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_width, uint32_t handler, uint32_t event, uint8_t char_match, DMAUsage hint);
+
+/** Attempts to determine if the serial peripheral is already in use for TX
+ *
+ * @param obj The serial object
+ * @return Non-zero if the RX transaction is ongoing, 0 otherwise
+ */
+uint8_t serial_tx_active(serial_t *obj);
+
+/** Attempts to determine if the serial peripheral is already in use for RX
+ *
+ * @param obj The serial object
+ * @return Non-zero if the RX transaction is ongoing, 0 otherwise
+ */
+uint8_t serial_rx_active(serial_t *obj);
+
+/** The asynchronous TX and RX handler.
+ *
+ * @param obj The serial object
+ * @return Returns event flags if an RX transfer termination condition was met; otherwise returns 0
+ */
+int serial_irq_handler_asynch(serial_t *obj);
+
+/** Abort the ongoing TX transaction. It disables the enabled interupt for TX and
+ *  flushes the TX hardware buffer if TX FIFO is used
+ *
+ * @param obj The serial object
+ */
+void serial_tx_abort_asynch(serial_t *obj);
+
+/** Abort the ongoing RX transaction. It disables the enabled interrupt for RX and
+ *  flushes the RX hardware buffer if RX FIFO is used
+ *
+ * @param obj The serial object
+ */
+void serial_rx_abort_asynch(serial_t *obj);
+
+/**@}*/
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/sleep_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/sleep_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/sleep_api.h	(revision 398)
@@ -0,0 +1,69 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_SLEEP_API_H
+#define MBED_SLEEP_API_H
+
+#include "device.h"
+
+#if DEVICE_SLEEP
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Send the microcontroller to sleep
+ *
+ * The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the
+ * system clock to the core is stopped until a reset or an interrupt occurs. This eliminates
+ * dynamic power used by the processor, memory systems and buses. The processor, peripheral and
+ * memory state are maintained, and the peripherals continue to work and can generate interrupts.
+ *
+ * The processor can be woken up by any internal peripheral interrupt or external pin interrupt.
+ *
+ * @note
+ *  The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
+ * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
+ * able to access the LocalFileSystem
+ */
+void hal_sleep(void);
+
+/** Send the microcontroller to deep sleep
+ *
+ * This processor is setup ready for deep sleep, and sent to sleep using __WFI(). This mode
+ * has the same sleep features as sleep plus it powers down peripherals and clocks. All state
+ * is still maintained.
+ *
+ * The processor can only be woken up by an external interrupt on a pin or a watchdog timer.
+ *
+ * @note
+ *  The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored.
+ * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be
+ * able to access the LocalFileSystem
+ */
+void hal_deepsleep(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/spi_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/spi_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/spi_api.h	(revision 398)
@@ -0,0 +1,238 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller 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.
+ */
+#ifndef MBED_SPI_API_H
+#define MBED_SPI_API_H
+
+#include "device.h"
+#include "hal/dma_api.h"
+#include "hal/buffer.h"
+
+#if DEVICE_SPI
+
+#define SPI_EVENT_ERROR       (1 << 1)
+#define SPI_EVENT_COMPLETE    (1 << 2)
+#define SPI_EVENT_RX_OVERFLOW (1 << 3)
+#define SPI_EVENT_ALL         (SPI_EVENT_ERROR | SPI_EVENT_COMPLETE | SPI_EVENT_RX_OVERFLOW)
+
+#define SPI_EVENT_INTERNAL_TRANSFER_COMPLETE (1 << 30) // Internal flag to report that an event occurred
+
+#define SPI_FILL_WORD         (0xFFFF)
+#define SPI_FILL_CHAR         (0xFF)
+
+#if DEVICE_SPI_ASYNCH
+/** Asynch SPI HAL structure
+ */
+typedef struct {
+    struct spi_s spi;        /**< Target specific SPI structure */
+    struct buffer_s tx_buff; /**< Tx buffer */
+    struct buffer_s rx_buff; /**< Rx buffer */
+} spi_t;
+
+#else
+/** Non-asynch SPI HAL structure
+ */
+typedef struct spi_s spi_t;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup hal_GeneralSPI SPI Configuration Functions
+ * @{
+ */
+
+/** Initialize the SPI peripheral
+ *
+ * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
+ * @param[out] obj  The SPI object to initialize
+ * @param[in]  mosi The pin to use for MOSI
+ * @param[in]  miso The pin to use for MISO
+ * @param[in]  sclk The pin to use for SCLK
+ * @param[in]  ssel The pin to use for SSEL
+ */
+void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel);
+
+/** Release a SPI object
+ *
+ * TODO: spi_free is currently unimplemented
+ * This will require reference counting at the C++ level to be safe
+ *
+ * Return the pins owned by the SPI object to their reset state
+ * Disable the SPI peripheral
+ * Disable the SPI clock
+ * @param[in] obj The SPI object to deinitialize
+ */
+void spi_free(spi_t *obj);
+
+/** Configure the SPI format
+ *
+ * Set the number of bits per frame, configure clock polarity and phase, shift order and master/slave mode.
+ * The default bit order is MSB.
+ * @param[in,out] obj   The SPI object to configure
+ * @param[in]     bits  The number of bits per frame
+ * @param[in]     mode  The SPI mode (clock polarity, phase, and shift direction)
+ * @param[in]     slave Zero for master mode or non-zero for slave mode
+ */
+void spi_format(spi_t *obj, int bits, int mode, int slave);
+
+/** Set the SPI baud rate
+ *
+ * Actual frequency may differ from the desired frequency due to available dividers and bus clock
+ * Configures the SPI peripheral's baud rate
+ * @param[in,out] obj The SPI object to configure
+ * @param[in]     hz  The baud rate in Hz
+ */
+void spi_frequency(spi_t *obj, int hz);
+
+/**@}*/
+/**
+ * \defgroup SynchSPI Synchronous SPI Hardware Abstraction Layer
+ * @{
+ */
+
+/** Write a byte out in master mode and receive a value
+ *
+ * @param[in] obj   The SPI peripheral to use for sending
+ * @param[in] value The value to send
+ * @return Returns the value received during send
+ */
+int  spi_master_write(spi_t *obj, int value);
+
+/** Write a block out in master mode and receive a value
+ *
+ *  The total number of bytes sent and received will be the maximum of
+ *  tx_length and rx_length. The bytes written will be padded with the
+ *  value 0xff.
+ *
+ * @param[in] obj        The SPI peripheral to use for sending
+ * @param[in] tx_buffer  Pointer to the byte-array of data to write to the device
+ * @param[in] tx_length  Number of bytes to write, may be zero
+ * @param[in] rx_buffer  Pointer to the byte-array of data to read from the device
+ * @param[in] rx_length  Number of bytes to read, may be zero
+ * @param[in] write_fill Default data transmitted while performing a read
+ * @returns
+ *      The number of bytes written and read from the device. This is
+ *      maximum of tx_length and rx_length.
+ */
+int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, char write_fill);
+
+/** Check if a value is available to read
+ *
+ * @param[in] obj The SPI peripheral to check
+ * @return non-zero if a value is available
+ */
+int  spi_slave_receive(spi_t *obj);
+
+/** Get a received value out of the SPI receive buffer in slave mode
+ *
+ * Blocks until a value is available
+ * @param[in] obj The SPI peripheral to read
+ * @return The value received
+ */
+int  spi_slave_read(spi_t *obj);
+
+/** Write a value to the SPI peripheral in slave mode
+ *
+ * Blocks until the SPI peripheral can be written to
+ * @param[in] obj   The SPI peripheral to write
+ * @param[in] value The value to write
+ */
+void spi_slave_write(spi_t *obj, int value);
+
+/** Checks if the specified SPI peripheral is in use
+ *
+ * @param[in] obj The SPI peripheral to check
+ * @return non-zero if the peripheral is currently transmitting
+ */
+int  spi_busy(spi_t *obj);
+
+/** Get the module number
+ *
+ * @param[in] obj The SPI peripheral to check
+ * @return The module number
+ */
+uint8_t spi_get_module(spi_t *obj);
+
+/**@}*/
+
+#if DEVICE_SPI_ASYNCH
+/**
+ * \defgroup AsynchSPI Asynchronous SPI Hardware Abstraction Layer
+ * @{
+ */
+
+/** Begin the SPI transfer. Buffer pointers and lengths are specified in tx_buff and rx_buff
+ *
+ * @param[in] obj       The SPI object that holds the transfer information
+ * @param[in] tx        The transmit buffer
+ * @param[in] tx_length The number of bytes to transmit
+ * @param[in] rx        The receive buffer
+ * @param[in] rx_length The number of bytes to receive
+ * @param[in] bit_width The bit width of buffer words
+ * @param[in] event     The logical OR of events to be registered
+ * @param[in] handler   SPI interrupt handler
+ * @param[in] hint      A suggestion for how to use DMA with this transfer
+ */
+void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint);
+
+/** The asynchronous IRQ handler
+ *
+ * Reads the received values out of the RX FIFO, writes values into the TX FIFO and checks for transfer termination
+ * conditions, such as buffer overflows or transfer complete.
+ * @param[in] obj     The SPI object that holds the transfer information
+ * @return Event flags if a transfer termination condition was met; otherwise 0.
+ */
+uint32_t spi_irq_handler_asynch(spi_t *obj);
+
+/** Attempts to determine if the SPI peripheral is already in use
+ *
+ * If a temporary DMA channel has been allocated, peripheral is in use.
+ * If a permanent DMA channel has been allocated, check if the DMA channel is in use.  If not, proceed as though no DMA
+ * channel were allocated.
+ * If no DMA channel is allocated, check whether tx and rx buffers have been assigned.  For each assigned buffer, check
+ * if the corresponding buffer position is less than the buffer length.  If buffers do not indicate activity, check if
+ * there are any bytes in the FIFOs.
+ * @param[in] obj The SPI object to check for activity
+ * @return Non-zero if the SPI port is active or zero if it is not.
+ */
+uint8_t spi_active(spi_t *obj);
+
+/** Abort an SPI transfer
+ *
+ * @param obj The SPI peripheral to stop
+ */
+void spi_abort_asynch(spi_t *obj);
+
+
+#endif
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // SPI_DEVICE
+
+#endif // MBED_SPI_API_H
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/ticker_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/ticker_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/ticker_api.h	(revision 398)
@@ -0,0 +1,121 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 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.
+ */
+#ifndef MBED_TICKER_API_H
+#define MBED_TICKER_API_H
+
+#include <stdint.h>
+#include "device.h"
+
+typedef uint32_t timestamp_t;
+
+/** Ticker's event structure
+ */
+typedef struct ticker_event_s {
+    timestamp_t            timestamp; /**< Event's timestamp */
+    uint32_t               id;        /**< TimerEvent object */
+    struct ticker_event_s *next;      /**< Next event in the queue */
+} ticker_event_t;
+
+typedef void (*ticker_event_handler)(uint32_t id);
+
+/** Ticker's interface structure - required API for a ticker
+ */
+typedef struct {
+    void (*init)(void);                           /**< Init function */
+    uint32_t (*read)(void);                       /**< Read function */
+    void (*disable_interrupt)(void);              /**< Disable interrupt function */
+    void (*clear_interrupt)(void);                /**< Clear interrupt function */
+    void (*set_interrupt)(timestamp_t timestamp); /**< Set interrupt function */
+} ticker_interface_t;
+
+/** Ticker's event queue structure
+ */
+typedef struct {
+    ticker_event_handler event_handler; /**< Event handler */
+    ticker_event_t *head;               /**< A pointer to head */
+} ticker_event_queue_t;
+
+/** Ticker's data structure
+ */
+typedef struct {
+    const ticker_interface_t *interface; /**< Ticker's interface */
+    ticker_event_queue_t *queue;         /**< Ticker's event queue */
+} ticker_data_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup hal_ticker Ticker HAL functions
+ * @{
+ */
+
+/** Initialize a ticker and set the event handler
+ *
+ * @param data    The ticker's data
+ * @param handler A handler to be set
+ */
+void ticker_set_handler(const ticker_data_t *const data, ticker_event_handler handler);
+
+/** IRQ handler that goes through the events to trigger overdue events.
+ *
+ * @param data    The ticker's data
+ */
+void ticker_irq_handler(const ticker_data_t *const data);
+
+/** Remove an event from the queue
+ *
+ * @param data The ticker's data
+ * @param obj  The event object to be removed from the queue
+ */
+void ticker_remove_event(const ticker_data_t *const data, ticker_event_t *obj);
+
+/** Insert an event to the queue
+ *
+ * @param data      The ticker's data
+ * @param obj       The event object to be inserted to the queue
+ * @param timestamp The event's timestamp
+ * @param id        The event object
+ */
+void ticker_insert_event(const ticker_data_t *const data, ticker_event_t *obj, timestamp_t timestamp, uint32_t id);
+
+/** Read the current ticker's timestamp
+ *
+ * @param data The ticker's data
+ * @return The current timestamp
+ */
+timestamp_t ticker_read(const ticker_data_t *const data);
+
+/** Read the next event's timestamp
+ *
+ * @param data The ticker's data
+ * @return 1 if timestamp is pending event, 0 if there's no event pending
+ */
+int ticker_get_next_timestamp(const ticker_data_t *const data, timestamp_t *timestamp);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/us_ticker_api.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/us_ticker_api.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/hal/us_ticker_api.h	(revision 398)
@@ -0,0 +1,83 @@
+
+/** \addtogroup hal */
+/** @{*/
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 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.
+ */
+#ifndef MBED_US_TICKER_API_H
+#define MBED_US_TICKER_API_H
+
+#include <stdint.h>
+#include "hal/ticker_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup hal_UsTicker Microseconds Ticker Functions
+ * @{
+ */
+
+/** Get ticker's data
+ *
+ * @return The low power ticker data
+ */
+const ticker_data_t* get_us_ticker_data(void);
+
+
+/** The wrapper for ticker_irq_handler, to pass us ticker's data
+ *
+ */
+void us_ticker_irq_handler(void);
+
+/* HAL us ticker */
+
+/** Initialize the ticker
+ *
+ */
+void us_ticker_init(void);
+
+/** Read the current counter
+ *
+ * @return The current timer's counter value in microseconds
+ */
+uint32_t us_ticker_read(void);
+
+/** Set interrupt for specified timestamp
+ *
+ * @param timestamp The time in microseconds to be set
+ */
+void us_ticker_set_interrupt(timestamp_t timestamp);
+
+/** Disable us ticker interrupt
+ *
+ */
+void us_ticker_disable_interrupt(void);
+
+/** Clear us ticker interrupt
+ *
+ */
+void us_ticker_clear_interrupt(void);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @}*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/platform/mbed_critical.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/platform/mbed_critical.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/platform/mbed_critical.h	(revision 398)
@@ -0,0 +1,17 @@
+#ifndef MBED_CRITICAL_H
+#define MBED_CRITICAL_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void core_util_critical_section_enter(void);
+void core_util_critical_section_exit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/platform/mbed_error.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/platform/mbed_error.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/platform/mbed_error.h	(revision 398)
@@ -0,0 +1,16 @@
+#ifndef MBED_ERROR_H
+#define MBED_ERROR_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void error(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/tMbedSerial.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/tMbedSerial.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/tMbedSerial.c	(revision 398)
@@ -0,0 +1,204 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2006-2016 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$
+ */
+
+/*
+ *		FIFO内蔵シリアルコミュニケーションインタフェース用 簡易SIOドライバ
+ */
+
+#include <sil.h>
+#include "tMbedSerial_tecsgen.h"
+#include "serial_api.h"
+
+static void mbed_serial_irq_handler(uint32_t id, SerialIrq event);
+
+/*
+ *  シリアルI/Oポートのオープン
+ */
+void
+eSIOPort_open(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	serial_t *obj = &p_cellcb->serial;
+	uint_t	brr;
+
+	if (VAR_initialized) {
+		/*
+		 *  既に初期化している場合は、二重に初期化しない．
+		 */
+		return;
+	}
+
+	serial_init(obj, ATTR_tx, ATTR_rx);
+	serial_baud(obj, ATTR_baudRate);
+	serial_format(obj, 8, ParityNone, 1);
+
+	serial_irq_handler(obj, mbed_serial_irq_handler, idx);
+
+	VAR_initialized = true;
+}
+
+/*
+ *  シリアルI/Oポートのクローズ
+ */
+void
+eSIOPort_close(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	serial_t *obj = &p_cellcb->serial;
+
+	serial_free(obj);
+}
+
+/*
+ *  シリアルI/Oポートへの文字送信
+ */
+bool_t
+eSIOPort_putChar(CELLIDX idx, char c)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	serial_t *obj = &p_cellcb->serial;
+
+	if (serial_writable(obj)){
+		serial_putc(obj, c);
+		return(true);
+	}
+	return(false);
+}
+
+/*
+ *  シリアルI/Oポートからの文字受信
+ */
+int_t
+eSIOPort_getChar(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	serial_t *obj = &p_cellcb->serial;
+	char	c;
+
+	if (serial_readable(obj)) {
+		return serial_getc(obj);
+	}
+	return(-1);
+}
+
+/*
+ *  シリアルI/Oポートからのコールバックの許可
+ */
+void
+eSIOPort_enableCBR(CELLIDX idx, uint_t cbrtn)
+{
+	CELLCB		*p_cellcb = GET_CELLCB(idx);
+	serial_t *obj = &p_cellcb->serial;
+
+	switch (cbrtn) {
+	case SIOSendReady:
+		serial_irq_set(obj, TxIrq, true);
+		break;
+	case SIOReceiveReady:
+		serial_irq_set(obj, RxIrq, true);
+		break;
+	}
+}
+
+/*
+ *  シリアルI/Oポートからのコールバックの禁止
+ */
+void
+eSIOPort_disableCBR(CELLIDX idx, uint_t cbrtn)
+{
+	CELLCB		*p_cellcb = GET_CELLCB(idx);
+	serial_t *obj = &p_cellcb->serial;
+
+	switch (cbrtn) {
+	case SIOSendReady:
+		serial_irq_set(obj, TxIrq, false);
+		break;
+	case SIOReceiveReady:
+		serial_irq_set(obj, RxIrq, false);
+		break;
+	}
+}
+
+/*
+ *  シリアルI/Oポートに対する受信割込み処理
+ */
+void
+eiRxISR_main(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	serial_t *obj = &p_cellcb->serial;
+
+	if (serial_readable(obj)) {
+		/*
+		 *  受信通知コールバックルーチンを呼び出す．
+		 */
+		ciSIOCBR_readyReceive();
+	}
+}
+
+/*
+ *  シリアルI/Oポートに対する送信割込み処理
+ */
+void
+eiTxISR_main(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	serial_t *obj = &p_cellcb->serial;
+
+	if (serial_writable(obj)) {
+		/*
+		 *  送信可能コールバックルーチンを呼び出す．
+		 */
+		ciSIOCBR_readySend();
+	}
+}
+
+void
+mbed_serial_irq_handler(uint32_t id, SerialIrq event)
+{
+	switch (event) {
+	case TxIrq:
+		eiTxISR_main(id);
+		break;
+	case RxIrq:
+		eiRxISR_main(id);
+		break;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/tMbedSerial.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/tMbedSerial.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/tMbedSerial.cdl	(revision 398)
@@ -0,0 +1,70 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *		FIFO内蔵シリアルコミュニケーションインタフェース用 簡易SIOドラ
+ *		イバのコンポーネント記述
+ */
+
+/*
+ *  FIFO内蔵シリアルコミュニケーションインタフェースに関する定義のイン
+ *  ポート
+ */
+import_C("serial_api.h");
+
+/*
+ *  FIFO内蔵シリアルコミュニケーションインタフェース用 簡易SIOドライバ
+ *  のセルタイプ
+ */
+celltype tMbedSerial {
+	entry	sSIOPort	eSIOPort;
+	call	siSIOCBR	ciSIOCBR;
+
+	attr {
+		int32_t tx;
+		int32_t rx;
+		uint32_t	baudRate;		/* ボーレートの設定値 */
+	};
+	var {
+		bool_t		initialized = false;	/* 初期化済み */
+		serial_t	serial;
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/target/device.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/target/device.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/target/device.h	(revision 398)
@@ -0,0 +1,128 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2014-2018 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+#ifndef _MBED_API_H_
+#define _MBED_API_H_
+
+#include <time.h>
+#include "PinNames.h"
+
+#define DEVICE_ANALOGIN		1
+#define DEVICE_ANALOGOUT	1
+#define DEVICE_PWMOUT		1
+#define DEVICE_SERIAL		1
+#define DEVICE_SPI			1
+#define DEVICE_I2C			1
+#define DEVICE_RTC			1
+#define DEVICE_SLEEP		1
+
+void mbed_api_init(void);
+
+void wait_ms(int ms);
+uint32_t us_ticker_read(void);
+
+typedef struct gpio_s {
+	PinName  pin;
+	PinDirection dir;
+	PinMode mode;
+} gpio_t;
+
+typedef struct analogin_s {
+	PinName pin;
+} analogin_t;
+
+typedef struct dac_s {
+	PinName pin;
+} dac_t;
+
+typedef struct pwmout_s {
+	PinName pin;
+} pwmout_t;
+
+void arduino_tick();
+
+typedef struct serial_s {
+	void *base_address;
+	int rxi_intno;
+	int tei_intno;
+} serial_t;
+
+typedef struct i2c_s {
+	void *base_address;
+	int rxi_intno;
+	int txi_intno;
+	int tei_intno;
+	unsigned char rxdata[16];
+} i2c_t;
+
+#define SPI_FILL_CHAR         (0xFF)
+
+typedef struct spi_s {
+	void *base_address;
+	int rxi_intno;
+	int txi_intno;
+	int tei_intno;
+} spi_t;
+
+void sci0_rxi_handler(void);
+void sci0_txi_handler(void);
+void sci0_tei_handler(void);
+
+void sci1_rxi_handler(void);
+void sci1_txi_handler(void);
+void sci1_tei_handler(void);
+
+void sci2_rxi_handler(void);
+void sci2_txi_handler(void);
+void sci2_tei_handler(void);
+
+void sci3_rxi_handler(void);
+void sci3_txi_handler(void);
+void sci3_tei_handler(void);
+
+void sci4_rxi_handler(void);
+void sci4_txi_handler(void);
+void sci4_tei_handler(void);
+
+void sci5_rxi_handler(void);
+void sci5_txi_handler(void);
+void sci5_tei_handler(void);
+
+void sci6_rxi_handler(void);
+void sci6_txi_handler(void);
+void sci6_tei_handler(void);
+
+#endif /* _MBED_API_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/target/mbed_api.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/target/mbed_api.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/target/mbed_api.c	(revision 398)
@@ -0,0 +1,2017 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ *
+ *  Copyright (C) 2014-2018 Cores Co., Ltd. Japan
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+#include <stdint.h>
+#include <time.h>
+#include <gpio_api.h>
+#include <ticker_api.h>
+#include <serial_api.h>
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "rx630.h"
+#include "target_stddef.h"
+#include "target_kernel_impl.h"
+#include "scif.h"
+
+ /* PWM出力(490Hz) */
+#define TPU_BASE_COUNTER	(48000000 / 4 / 490)
+
+void mbed_api_init()
+{
+}
+
+void error(const char *text)
+{
+	syslog(LOG_ERROR, text);
+}
+
+void core_util_critical_section_enter(void)
+{
+
+}
+
+void core_util_critical_section_exit(void)
+{
+
+}
+
+void wait_ms(int ms)
+{
+	dly_tsk(ms * 1000);
+}
+
+void us_ticker_init(void)
+{
+}
+
+void us_ticker_set_interrupt(timestamp_t timestamp)
+{
+}
+
+void us_ticker_disable_interrupt(void)
+{
+}
+
+void us_ticker_clear_interrupt(void)
+{
+}
+
+uint32_t us_ticker_read(void)
+{
+	SYSTIM result;
+	get_tim(&result);
+	return result;
+}
+
+void gpio_init(gpio_t *obj, PinName pin)
+{
+	obj->pin = pin;
+	obj->dir = PIN_INPUT;
+	obj->mode = PullDefault;
+}
+
+
+static bool_t pin_function_table[8] = {
+	true, true, true, true, true, true, true, true
+};
+
+static ER change_pin_function(int pin, bool_t gpio)
+{
+	ER result = E_PAR;
+
+	if ((pin < 0) || (pin >= 8))
+		return E_PAR;
+
+	if (pin_function_table[pin] == gpio)
+		return E_OK;
+
+	/* 汎用入出力ポートに設定 */
+	switch (pin) {
+	case D0:
+		/* P21 */
+		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B1_BIT);
+		break;
+	case D1:
+		/* P20 */
+		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B0_BIT);
+		break;
+	case D2:
+		/* P22 */
+		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B2_BIT);
+		break;
+	case D3:
+		/* P23 */
+		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B3_BIT);
+		break;
+	case D4:
+		/* P24 */
+		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B4_BIT);
+		break;
+	case D5:
+		/* P25 */
+		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B5_BIT);
+		break;
+	case D6:
+		/* P32 */
+		sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) & ~PORT_PMR_B2_BIT);
+		break;
+	case D7:
+		/* P33 */
+		sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) & ~PORT_PMR_B3_BIT);
+		break;
+	default:
+		break;
+	}
+
+	/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+	/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+	switch (pin) {
+		/* P21/TIOCA3 */
+	case D0:
+		if (gpio) {
+			/* P21端子機能制御レジスタ P21とする */
+			sil_wrb_mem(MPC_P21PFS_ADDR, 0x00);
+		}
+		else {
+			/* P21端子機能制御レジスタ TIOCA3とする */
+			sil_wrb_mem(MPC_P21PFS_ADDR, 0x03);
+		}
+		result = E_OK;
+		break;
+		/* P20/TIOCB3 */
+	case D1:
+		if (gpio) {
+			/* P20端子機能制御レジスタ P20とする */
+			sil_wrb_mem(MPC_P20PFS_ADDR, 0x00);
+		}
+		else {
+			/* P20端子機能制御レジスタ TIOCB3とする */
+			sil_wrb_mem(MPC_P20PFS_ADDR, 0x03);
+		}
+		result = E_OK;
+		break;
+		/* P22/TIOCC3 */
+	case D2:
+		if (gpio) {
+			/* P22端子機能制御レジスタ P22とする */
+			sil_wrb_mem(MPC_P22PFS_ADDR, 0x00);
+		}
+		else {
+			/* P22端子機能制御レジスタ TIOCC3とする */
+			sil_wrb_mem(MPC_P22PFS_ADDR, 0x03);
+		}
+		result = E_OK;
+		break;
+		/* P23/TIOCD3 */
+	case D3:
+		if (gpio) {
+			/* P23端子機能制御レジスタ P23とする */
+			sil_wrb_mem(MPC_P23PFS_ADDR, 0x00);
+		}
+		else {
+			/* P23端子機能制御レジスタ TIOCD3とする */
+			sil_wrb_mem(MPC_P23PFS_ADDR, 0x03);
+		}
+		result = E_OK;
+		break;
+		/* P24/TIOCB4 */
+	case D4:
+		if (gpio) {
+			/* P24端子機能制御レジスタ P24とする */
+			sil_wrb_mem(MPC_P24PFS_ADDR, 0x00);
+		}
+		else {
+			/* P24端子機能制御レジスタ TIOCB4とする */
+			sil_wrb_mem(MPC_P24PFS_ADDR, 0x03);
+		}
+		result = E_OK;
+		break;
+		/* P25/TIOCA4 */
+	case D5:
+		if (gpio) {
+			/* P25端子機能制御レジスタ P25とする */
+			sil_wrb_mem(MPC_P25PFS_ADDR, 0x00);
+		}
+		else {
+			/* P25端子機能制御レジスタ TIOCA4とする */
+			sil_wrb_mem(MPC_P25PFS_ADDR, 0x03);
+		}
+		result = E_OK;
+		break;
+		/* P32/TIOCC0 */
+	case D6:
+		if (gpio) {
+			/* P32端子機能制御レジスタ P32とする */
+			sil_wrb_mem(MPC_P32PFS_ADDR, 0x00);
+		}
+		else {
+			/* P32端子機能制御レジスタ TIOCC0とする */
+			sil_wrb_mem(MPC_P32PFS_ADDR, 0x03);
+		}
+		result = E_OK;
+		break;
+		/* P33/TIOCD0 */
+	case D7:
+		if (gpio) {
+			/* P33端子機能制御レジスタ P33とする */
+			sil_wrb_mem(MPC_P33PFS_ADDR, 0x00);
+		}
+		else {
+			/* P33端子機能制御レジスタ TIOCD0とする */
+			sil_wrb_mem(MPC_P33PFS_ADDR, 0x03);
+		}
+		result = E_OK;
+		break;
+	default:
+		break;
+	}
+
+	/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+
+	/* 機能ポートに設定 */
+	if (!gpio) {
+		switch (pin) {
+			/* P21/TIOCA3 */
+		case D0:
+			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B1_BIT);
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B1_BIT);
+			break;
+			/* P20/TIOCB3 */
+		case D1:
+			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B0_BIT);
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B0_BIT);
+			break;
+			/* P22/TIOCC3 */
+		case D2:
+			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B2_BIT);
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B2_BIT);
+			break;
+			/* P23/TIOCD3 */
+		case D3:
+			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B3_BIT);
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B3_BIT);
+			break;
+			/* P24/TIOCB4 */
+		case D4:
+			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B4_BIT);
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B4_BIT);
+			break;
+			/* P25/TIOCA4 */
+		case D5:
+			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B5_BIT);
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B5_BIT);
+			break;
+			/* P32/TIOCC0 */
+		case D6:
+			sil_wrb_mem(PORT3_PDR_ADDR, sil_reb_mem(PORT3_PDR_ADDR) | PORT_PDR_B2_BIT);
+			sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) | PORT_PMR_B2_BIT);
+			break;
+			/* P33/TIOCD0 */
+		case D7:
+			sil_wrb_mem(PORT3_PDR_ADDR, sil_reb_mem(PORT3_PDR_ADDR) | PORT_PDR_B3_BIT);
+			sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) | PORT_PMR_B3_BIT);
+			break;
+		default:
+			break;
+		}
+	}
+
+	pin_function_table[pin] = gpio;
+
+	return result;
+}
+
+static void change_pin_mode(gpio_t *obj)
+{
+	volatile __evenaccess uint8_t *pdr; int bit;
+
+	switch (obj->pin) {
+	case D0:
+		/* P21 */
+		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B1_BIT;
+		break;
+	case D1:
+		/* P20 */
+		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B0_BIT;
+		break;
+	case D2:
+		/* P22 */
+		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B2_BIT;
+		break;
+	case D3:
+		/* P23 */
+		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B3_BIT;
+		break;
+	case D4:
+		/* P24 */
+		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B4_BIT;
+		break;
+	case D5:
+		/* P25 */
+		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B5_BIT;
+		break;
+	case D6:
+		/* P32 */
+		pdr = PORT3_PDR_ADDR; bit = PORT_PDR_B2_BIT;
+		break;
+	case D7:
+		/* P33 */
+		pdr = PORT3_PDR_ADDR; bit = PORT_PDR_B3_BIT;
+		break;
+	case D8:
+		/* PC2 */
+		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B2_BIT;
+		break;
+	case D9:
+		/* PC3 */
+		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B3_BIT;
+		break;
+	case D10:
+		/* PC4 */
+		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B4_BIT;
+		break;
+	case D11:
+		/* PC6 */
+		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B6_BIT;
+		break;
+	case D12:
+		/* PC7 */
+		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B7_BIT;
+		break;
+	case D13:
+		/* PC5 */
+		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B5_BIT;
+		break;
+	default:
+		return;
+	}
+
+	volatile __evenaccess uint8_t *pcr = pdr + (PORT0_PCR_ADDR - PORT0_PDR_ADDR);
+
+	switch (obj->dir) {
+	case PIN_INPUT:
+		sil_wrb_mem(pdr, sil_reb_mem(pdr) & ~bit);
+		break;
+	case PIN_OUTPUT:
+		sil_wrb_mem(pdr, sil_reb_mem(pdr) | bit);
+		break;
+	default:
+		break;
+	}
+
+	switch (obj->mode) {
+	case PullUp:
+		sil_wrb_mem(pcr, sil_reb_mem(pcr) | bit);
+		break;
+	default:
+		sil_wrb_mem(pcr, sil_reb_mem(pcr) & ~bit);
+		break;
+	}
+}
+
+void gpio_mode(gpio_t *obj, PinMode mode)
+{
+	/* 汎用入出力ポートに設定 */
+	change_pin_function(obj->pin, true);
+
+	obj->mode = mode;
+
+	change_pin_mode(obj);
+}
+
+void gpio_dir(gpio_t *obj, PinDirection direction)
+{
+	/* 汎用入出力ポートに設定 */
+	change_pin_function(obj->pin, true);
+
+	obj->dir = direction;
+
+	change_pin_mode(obj);
+}
+
+void gpio_write(gpio_t *obj, int value)
+{
+	volatile __evenaccess uint8_t *podr;
+	int bit;
+
+	switch (obj->pin) {
+	case D0:
+		/* P21 */
+		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B1_BIT;
+		break;
+	case D1:
+		/* P20 */
+		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B0_BIT;
+		break;
+	case D2:
+		/* P22 */
+		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B2_BIT;
+		break;
+	case D3:
+		/* P23 */
+		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B3_BIT;
+		break;
+	case D4:
+		/* P24 */
+		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B4_BIT;
+		break;
+	case D5:
+		/* P25 */
+		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B5_BIT;
+		break;
+	case D6:
+		/* P32 */
+		podr = PORT3_PODR_ADDR; bit = PORT_PODR_B2_BIT;
+		break;
+	case D7:
+		/* P33 */
+		podr = PORT3_PODR_ADDR; bit = PORT_PODR_B3_BIT;
+		break;
+	case D8:
+		/* PC2 */
+		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B2_BIT;
+		break;
+	case D9:
+		/* PC3 */
+		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B3_BIT;
+		break;
+	case D10:
+		/* PC4 */
+		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B4_BIT;
+		break;
+	case D11:
+		/* PC6 */
+		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B6_BIT;
+		break;
+	case D12:
+		/* PC7 */
+		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B7_BIT;
+		break;
+	case D13:
+		/* PC5 */
+		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B5_BIT;
+		break;
+	default:
+		return;
+	}
+
+	switch (value) {
+	case 0:
+		sil_wrb_mem(podr, sil_reb_mem(podr) & ~bit);
+		break;
+	case 1:
+		sil_wrb_mem(podr, sil_reb_mem(podr) | bit);
+		break;
+	}
+}
+
+int gpio_read(gpio_t *obj)
+{
+	volatile __evenaccess uint8_t *pidr;
+	int bit;
+
+	switch (obj->pin) {
+	case D0:
+		/* P21 */
+		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B1_BIT;
+		break;
+	case D1:
+		/* P20 */
+		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B0_BIT;
+		break;
+	case D2:
+		/* P22 */
+		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B2_BIT;
+		break;
+	case D3:
+		/* P23 */
+		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B3_BIT;
+		break;
+	case D4:
+		/* P24 */
+		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B4_BIT;
+		break;
+	case D5:
+		/* P25 */
+		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B5_BIT;
+		break;
+	case D6:
+		/* P32 */
+		pidr = PORT3_PIDR_ADDR; bit = PORT_PIDR_B2_BIT;
+		break;
+	case D7:
+		/* P33 */
+		pidr = PORT3_PIDR_ADDR; bit = PORT_PIDR_B3_BIT;
+		break;
+	case D8:
+		/* PC2 */
+		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B2_BIT;
+		break;
+	case D9:
+		/* PC3 */
+		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B3_BIT;
+		break;
+	case D10:
+		/* PC4 */
+		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B4_BIT;
+		break;
+	case D11:
+		/* PC6 */
+		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B6_BIT;
+		break;
+	case D12:
+		/* PC7 */
+		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B7_BIT;
+		break;
+	case D13:
+		/* PC5 */
+		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B5_BIT;
+		break;
+	default:
+		return 0;
+	}
+
+	if ((sil_reb_mem(pidr) & bit) != 0) {
+		return 1;
+	}
+	else {
+		return 0;
+	}
+}
+
+void pin_function(PinName pin, int function)
+{
+}
+
+void pin_mode(PinName pin, PinMode mode)
+{
+
+}
+
+#define arduino_ad_table_count 64
+static uint16_t arduino_ad_table[8][arduino_ad_table_count];
+static int arduino_ad_pos = 0;
+static uint32_t arduino_ad_avelage[8];
+
+void analogin_init(analogin_t *obj, PinName pin)
+{
+	/*
+	* モジュールストップ機能の設定(S12AD)
+	*/
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRA_ADDR,
+		sil_rew_mem(SYSTEM_MSTPCRA_ADDR) & ~SYSTEM_MSTPCRA_MSTPA17_BIT);
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* 書込み禁止 */
+
+	/* 12bitADC初期化 */
+	sil_wrh_mem(S12AD_ADEXICR_ADDR, 0x0000);	/* 温度センサ出力、内部基準電圧非選択 */
+	sil_wrh_mem(S12AD_ADANS0_ADDR, 0x00FF);		/* 変換ポートAN000～AN007選択、AN008～AN015非選択 */
+	sil_wrh_mem(S12AD_ADANS1_ADDR, 0x0000);		/* 変換ポートAN016～AN020非選択 */
+}
+
+uint16_t analogin_read_u16(analogin_t *obj)
+{
+	uint16_t result = 0;
+
+	switch (obj->pin) {
+	case A0:
+		/* *value = sil_reh_mem(S12AD_ADDR0_ADDR); */
+		result = (arduino_ad_avelage[0] / (arduino_ad_table_count));
+		break;
+	case A1:
+		/* *value = sil_reh_mem(S12AD_ADDR1_ADDR); */
+		result = (arduino_ad_avelage[1] / (arduino_ad_table_count));
+		break;
+	case A2:
+		/* *value = sil_reh_mem(S12AD_ADDR2_ADDR); */
+		result = (arduino_ad_avelage[2] / (arduino_ad_table_count));
+		break;
+	case A3:
+		/* *value = sil_reh_mem(S12AD_ADDR3_ADDR); */
+		result = (arduino_ad_avelage[3] / (arduino_ad_table_count));
+		break;
+	case A4:
+		/* *value = sil_reh_mem(S12AD_ADDR4_ADDR); */
+		result = (arduino_ad_avelage[4] / (arduino_ad_table_count));
+		break;
+	case A5:
+		/* *value = sil_reh_mem(S12AD_ADDR5_ADDR); */
+		result = (arduino_ad_avelage[5] / (arduino_ad_table_count));
+		break;
+	case A6:
+		/* *value = sil_reh_mem(S12AD_ADDR6_ADDR); */
+		result = (arduino_ad_avelage[6] / (arduino_ad_table_count));
+		break;
+	case A7:
+		/* *value = sil_reh_mem(S12AD_ADDR7_ADDR); */
+		result = (arduino_ad_avelage[7] / (arduino_ad_table_count));
+		break;
+	default:
+		return 0;
+	}
+
+	return 65535 - ((result << 4) | (result >> 8));
+}
+
+void arduino_tick()
+{
+	static volatile __evenaccess uint16_t *const regs[8] = {
+		S12AD_ADDR0_ADDR,
+		S12AD_ADDR1_ADDR,
+		S12AD_ADDR2_ADDR,
+		S12AD_ADDR3_ADDR,
+		S12AD_ADDR4_ADDR,
+		S12AD_ADDR5_ADDR,
+		S12AD_ADDR6_ADDR,
+		S12AD_ADDR7_ADDR
+	};
+	uint16_t ad_value;
+	int i;
+
+	/* ADCの変換結果取得 */
+	if ((sil_reb_mem(S12AD_ADCSR_ADDR) & S12AD_ADCSR_ADST_BIT) == 0) {
+		for (i = 0; i < 8; i++) {
+			arduino_ad_avelage[i] -= arduino_ad_table[i][arduino_ad_pos];
+			ad_value = sil_reh_mem(regs[i]);
+			arduino_ad_table[i][arduino_ad_pos] = ad_value;
+			arduino_ad_avelage[i] += ad_value;
+		}
+
+		arduino_ad_pos++;
+		if (arduino_ad_pos >= arduino_ad_table_count) {
+			arduino_ad_pos = 0;
+		}
+
+		/* 変換開始（シングルスキャンモード） */
+		sil_wrb_mem(S12AD_ADCSR_ADDR, S12AD_ADCSR_ADST_BIT);
+	}
+}
+
+void analogout_init(dac_t *obj, PinName pin)
+{
+}
+
+void analogout_write_u16(dac_t *obj, uint16_t value)
+{
+}
+
+void pwmout_init(pwmout_t* obj, PinName pin)
+{
+	/* PWM出力(490Hz) */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRA_ADDR,
+		sil_rew_mem(SYSTEM_MSTPCRA_ADDR) & ~SYSTEM_MSTPCRA_MSTPA13_BIT); /* TPU0～TPU5 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* 書込み禁止 */
+
+	/* カウンタクロックの選択、カウンタクリア要因の選択 */
+	sil_wrb_mem(TPU0_TCR_ADDR, (1 << TPU_TCR_TPSC_OFFSET) | (1 << TPU_TCR_CKEG_OFFSET)
+		| (1 << TPU_TCR_CCLR_OFFSET));
+	sil_wrb_mem(TPU3_TCR_ADDR, (1 << TPU_TCR_TPSC_OFFSET) | (1 << TPU_TCR_CKEG_OFFSET)
+		| (3 << TPU_TCR_CCLR_OFFSET));
+	sil_wrb_mem(TPU4_TCR_ADDR, (1 << TPU_TCR_TPSC_OFFSET) | (1 << TPU_TCR_CKEG_OFFSET)
+		| (3 << TPU_TCR_CCLR_OFFSET));
+	/* 波形出力レベルの選択 */
+	sil_wrb_mem(TPU0_TIORL_ADDR, (5 << TPU_TIORL_IOC_OFFSET) | (5 << TPU_TIORL_IOD_OFFSET));
+	sil_wrb_mem(TPU3_TIORH_ADDR, (5 << TPU_TIORH_IOA_OFFSET) | (5 << TPU_TIORH_IOB_OFFSET));
+	sil_wrb_mem(TPU3_TIORL_ADDR, (5 << TPU_TIORL_IOC_OFFSET) | (5 << TPU_TIORL_IOD_OFFSET));
+	sil_wrb_mem(TPU4_TIOR_ADDR, (5 << TPU_TIOR_IOA_OFFSET) | (5 << TPU_TIOR_IOB_OFFSET));
+	/* TGRyの設定 */
+	sil_wrh_mem(TPU0_TGRA_ADDR, TPU_BASE_COUNTER);
+	sil_wrh_mem(TPU0_TGRC_ADDR, 0);
+	sil_wrh_mem(TPU0_TGRD_ADDR, 0);
+	sil_wrh_mem(TPU3_TGRA_ADDR, 0);
+	sil_wrh_mem(TPU3_TGRB_ADDR, 0);
+	sil_wrh_mem(TPU3_TGRC_ADDR, 0);
+	sil_wrh_mem(TPU3_TGRD_ADDR, 0);
+	sil_wrh_mem(TPU4_TGRA_ADDR, 0);
+	sil_wrh_mem(TPU4_TGRB_ADDR, 0);
+	/* PWMモード2の設定 */
+	sil_wrb_mem(TPU0_TMDR_ADDR, 3);
+	sil_wrb_mem(TPU3_TMDR_ADDR, 3);
+	sil_wrb_mem(TPU4_TMDR_ADDR, 3);
+	/* 同期動作設定 */
+	sil_wrb_mem(TPUA_TSYR_ADDR, TPU_TSYR_SYNC0_BIT | TPU_TSYR_SYNC3_BIT | TPU_TSYR_SYNC4_BIT);
+	/* カウント動作開始 */
+	sil_wrb_mem(TPUA_TSTR_ADDR, TPU_TSTR_CST0_BIT | TPU_TSTR_CST3_BIT | TPU_TSTR_CST4_BIT);
+}
+
+void pwmout_free(pwmout_t* obj)
+{
+	/* カウント動作終了 */
+	sil_wrb_mem(TPUA_TSTR_ADDR, 0);
+}
+
+void pwmout_period_us(pwmout_t* obj, int us)
+{
+}
+
+void pwmout_pulsewidth_us(pwmout_t* obj, int us)
+{
+}
+
+typedef enum {
+	sciSerial,
+	sciI2C,
+	sciSPIM,
+	sciSPIS,
+} sci_mode_t;
+
+void sci_enable(void *base_address, sci_mode_t mode)
+{
+	/*
+	 *  モジュールストップ機能の設定
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRB_ADDR,
+		sil_rew_mem(SYSTEM_MSTPCRB_ADDR) & ~SCI_MSTPCRB_BIT(base_address));
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* 書込み禁止 */
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(base_address), 0x00U);
+
+	switch ((uint32_t)base_address) {
+	/* TXD/SDA/MOSI:P20, RXD/SCL/MISO:P21, SCK:P22 */
+	case SCI0_BASE:
+		switch (mode) {
+		case sciSerial:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT2_PODR_ADDR,
+				sil_reb_mem(PORT2_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B1_BIT);
+			/* TX出力/RX入力ポート設定 */
+			sil_wrb_mem(PORT2_PDR_ADDR, (sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B0_BIT) & ~PORT_PDR_B1_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT2_PCR_ADDR, sil_reb_mem(PORT2_PCR_ADDR) & ~(PORT_PCR_B0_BIT | PORT_PCR_B1_BIT));
+			/* RX CMOS */
+			sil_wrb_mem(PORT2_ODR0_ADDR,
+				(sil_reb_mem(PORT2_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm1_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm1_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B1_BIT);
+			break;
+		case sciI2C:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT2_PODR_ADDR,
+				sil_reb_mem(PORT2_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B1_BIT);
+			/* SCL,SDA 出力ポート設定 */
+			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B0_BIT | PORT_PDR_B1_BIT);
+			/* プルアップ有効 */
+			sil_wrb_mem(PORT2_PCR_ADDR, sil_reb_mem(PORT2_PCR_ADDR) | PORT_PCR_B0_BIT | PORT_PCR_B1_BIT);
+			/* Nチャネルオープンドレイン */
+			sil_wrb_mem(PORT2_ODR0_ADDR,
+				(sil_reb_mem(PORT2_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm1_MASK))
+				| (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm1_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B1_BIT);
+			break;
+		case sciSPIM:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT2_PODR_ADDR,
+				sil_reb_mem(PORT2_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B1_BIT | PORT_PODR_B2_BIT);
+			/* MOSI出力/MISO入力/SCK入出力ポート設定 */
+			sil_wrb_mem(PORT2_PDR_ADDR, (sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B0_BIT | PORT_PDR_B2_BIT) & ~PORT_PDR_B1_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT2_PCR_ADDR, sil_reb_mem(PORT2_PCR_ADDR) & ~(PORT_PCR_B0_BIT | PORT_PCR_B1_BIT | PORT_PCR_B2_BIT));
+			/* MISO CMOS */
+			sil_wrb_mem(PORT2_ODR0_ADDR,
+				(sil_reb_mem(PORT2_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm1_MASK | PORT_ODR_Pm2_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm1_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm2_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B1_BIT | PORT_PMR_B2_BIT);
+			break;
+		}
+		/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+		/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+		/* P20端子機能制御レジスタ TXD0/SMOSI0/SSDA0とする */
+		sil_wrb_mem(MPC_P20PFS_ADDR, 0x0A);
+		/* P21端子機能制御レジスタ RXD0/SMISO0/SSCL0とする */
+		sil_wrb_mem(MPC_P21PFS_ADDR, 0x0A);
+		if (mode == sciSPIM) {
+			/* P22端子機能制御レジスタ SCK0とする */
+			sil_wrb_mem(MPC_P22PFS_ADDR, 0x0A);
+		}
+
+		/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+		break;
+	/* TXD/SDA/MOSI:P50, RXD/SCL/MISO:P52, SCK:P51 */
+	case SCI2_BASE:
+		switch (mode) {
+		case sciSerial:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT5_PODR_ADDR,
+				sil_reb_mem(PORT5_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B2_BIT);
+			/* TX出力/RX入力ポート設定 */
+			sil_wrb_mem(PORT5_PDR_ADDR, (sil_reb_mem(PORT5_PDR_ADDR) | PORT_PDR_B0_BIT) & ~PORT_PDR_B2_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT5_PCR_ADDR, sil_reb_mem(PORT5_PCR_ADDR) & ~(PORT_PCR_B0_BIT | PORT_PCR_B2_BIT));
+			/* RX CMOS */
+			sil_wrb_mem(PORT5_ODR0_ADDR,
+				(sil_reb_mem(PORT5_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm2_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm2_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT5_PMR_ADDR, sil_reb_mem(PORT5_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B2_BIT);
+			break;
+		case sciI2C:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT5_PODR_ADDR,
+				sil_reb_mem(PORT5_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B2_BIT);
+			/* SCL,SDA 出力ポート設定 */
+			sil_wrb_mem(PORT5_PDR_ADDR, sil_reb_mem(PORT5_PDR_ADDR) | PORT_PDR_B0_BIT | PORT_PDR_B2_BIT);
+			/* プルアップ有効 */
+			sil_wrb_mem(PORT5_PCR_ADDR, sil_reb_mem(PORT5_PCR_ADDR) | PORT_PCR_B0_BIT | PORT_PCR_B2_BIT);
+			/* Nチャネルオープンドレイン */
+			sil_wrb_mem(PORT5_ODR0_ADDR,
+				(sil_reb_mem(PORT5_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm2_MASK))
+				| (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm2_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT5_PMR_ADDR, sil_reb_mem(PORT5_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B2_BIT);
+			break;
+		case sciSPIM:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT5_PODR_ADDR,
+				sil_reb_mem(PORT5_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B1_BIT | PORT_PODR_B2_BIT);
+			/* MOSI出力/MISO入力/SCK入出力ポート設定 */
+			sil_wrb_mem(PORT5_PDR_ADDR, (sil_reb_mem(PORT5_PDR_ADDR) | PORT_PDR_B0_BIT | PORT_PDR_B1_BIT) & ~PORT_PDR_B2_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT5_PCR_ADDR, sil_reb_mem(PORT5_PCR_ADDR) & ~(PORT_PCR_B0_BIT | PORT_PCR_B1_BIT | PORT_PCR_B2_BIT));
+			/* MISO CMOS */
+			sil_wrb_mem(PORT5_ODR0_ADDR,
+				(sil_reb_mem(PORT5_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm1_MASK | PORT_ODR_Pm2_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm1_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm2_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT5_PMR_ADDR, sil_reb_mem(PORT5_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B1_BIT | PORT_PMR_B1_BIT | PORT_PMR_B2_BIT);
+			break;
+		}
+		/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+		/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+		/* P50端子機能制御レジスタ SSDA2とする */
+		sil_wrb_mem(MPC_P50PFS_ADDR, 0x0A);
+		/* P52端子機能制御レジスタ SSCL2とする */
+		sil_wrb_mem(MPC_P52PFS_ADDR, 0x0A);
+		if (mode == sciSPIM) {
+			/* P51端子機能制御レジスタ SCK2とする */
+			sil_wrb_mem(MPC_P51PFS_ADDR, 0x0A);
+		}
+
+		/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+		break;
+	/* TXD/SDA/MOSI:P23, RXD/SCL/MISO:P25, SCK:P24 */
+	case SCI3_BASE:
+		switch (mode) {
+		case sciSerial:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT2_PODR_ADDR,
+				sil_reb_mem(PORT2_PODR_ADDR) | PORT_PODR_B3_BIT | PORT_PODR_B5_BIT);
+			/* TX出力/RX入力ポート設定 */
+			sil_wrb_mem(PORT2_PDR_ADDR, (sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B3_BIT) & ~PORT_PDR_B5_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT2_PCR_ADDR, sil_reb_mem(PORT2_PCR_ADDR) & ~(PORT_PCR_B3_BIT | PORT_PCR_B5_BIT));
+			/* RX CMOS */
+			sil_wrb_mem(PORT2_ODR0_ADDR,
+				(sil_reb_mem(PORT2_ODR0_ADDR) & ~(PORT_ODR_Pm3_MASK | PORT_ODR_Pm5_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm3_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm5_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B3_BIT | PORT_PMR_B5_BIT);
+			break;
+		case sciI2C:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT2_PODR_ADDR,
+				sil_reb_mem(PORT2_PODR_ADDR) | PORT_PODR_B3_BIT | PORT_PODR_B5_BIT);
+			/* SCL,SDA 出力ポート設定 */
+			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B3_BIT | PORT_PDR_B5_BIT);
+			/* プルアップ有効 */
+			sil_wrb_mem(PORT2_PCR_ADDR, sil_reb_mem(PORT2_PCR_ADDR) | PORT_PCR_B3_BIT | PORT_PCR_B5_BIT);
+			/* Nチャネルオープンドレイン */
+			sil_wrb_mem(PORT2_ODR0_ADDR,
+				(sil_reb_mem(PORT2_ODR0_ADDR) & ~(PORT_ODR_Pm3_MASK | PORT_ODR_Pm5_MASK))
+				| (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm3_OFFSET) | (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm5_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B3_BIT | PORT_PMR_B5_BIT);
+			break;
+		case sciSPIM:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT2_PODR_ADDR,
+				sil_reb_mem(PORT2_PODR_ADDR) | PORT_PODR_B3_BIT | PORT_PODR_B4_BIT | PORT_PODR_B5_BIT);
+			/* MOSI出力/MISO入力/SCK入出力ポート設定 */
+			sil_wrb_mem(PORT2_PDR_ADDR, (sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B3_BIT | PORT_PDR_B4_BIT) & ~PORT_PDR_B5_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT2_PCR_ADDR, sil_reb_mem(PORT2_PCR_ADDR) & ~(PORT_PCR_B3_BIT | PORT_PCR_B4_BIT | PORT_PCR_B5_BIT));
+			/* MISO CMOS */
+			sil_wrb_mem(PORT2_ODR0_ADDR,
+				(sil_reb_mem(PORT2_ODR0_ADDR) & ~(PORT_ODR_Pm3_MASK | PORT_ODR_Pm4_MASK | PORT_ODR_Pm5_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm3_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm4_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm5_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B3_BIT | PORT_PMR_B4_BIT | PORT_PMR_B4_BIT | PORT_PMR_B5_BIT);
+			break;
+		}
+		/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+		/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+		/* P23端子機能制御レジスタ SSDA2とする */
+		sil_wrb_mem(MPC_P23PFS_ADDR, 0x0A);
+		/* P25端子機能制御レジスタ SSCL2とする */
+		sil_wrb_mem(MPC_P25PFS_ADDR, 0x0A);
+		if (mode == sciSPIM) {
+			/* P24端子機能制御レジスタ SCK2とする */
+			sil_wrb_mem(MPC_P24PFS_ADDR, 0x0A);
+		}
+
+		/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+		break;
+	/* TXD/SDA/MOSI:P32, RXD/SCL/MISO:P33, SCK:P34 */
+	case SCI6_BASE:
+		switch (mode) {
+		case sciSerial:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT3_PODR_ADDR,
+				sil_reb_mem(PORT3_PODR_ADDR) | PORT_PODR_B2_BIT | PORT_PODR_B3_BIT);
+			/* TX出力/RX入力ポート設定 */
+			sil_wrb_mem(PORT3_PDR_ADDR, (sil_reb_mem(PORT3_PDR_ADDR) | PORT_PDR_B2_BIT) & ~PORT_PDR_B3_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT3_PCR_ADDR, sil_reb_mem(PORT3_PCR_ADDR) & ~(PORT_PCR_B2_BIT | PORT_PCR_B3_BIT));
+			/* RX CMOS */
+			sil_wrb_mem(PORT3_ODR0_ADDR,
+				(sil_reb_mem(PORT3_ODR0_ADDR) & ~(PORT_ODR_Pm2_MASK | PORT_ODR_Pm3_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm2_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm3_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) | PORT_PMR_B2_BIT | PORT_PMR_B3_BIT);
+			break;
+		case sciI2C:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT3_PODR_ADDR,
+				sil_reb_mem(PORT3_PODR_ADDR) | PORT_PODR_B2_BIT | PORT_PODR_B3_BIT);
+			/* SCL,SDA 出力ポート設定 */
+			sil_wrb_mem(PORT3_PDR_ADDR, sil_reb_mem(PORT3_PDR_ADDR) | PORT_PDR_B2_BIT | PORT_PDR_B3_BIT);
+			/* プルアップ有効 */
+			sil_wrb_mem(PORT3_PCR_ADDR, sil_reb_mem(PORT3_PCR_ADDR) | PORT_PCR_B2_BIT | PORT_PCR_B3_BIT);
+			/* Nチャネルオープンドレイン */
+			sil_wrb_mem(PORT3_ODR0_ADDR,
+				(sil_reb_mem(PORT3_ODR0_ADDR) & ~(PORT_ODR_Pm2_MASK | PORT_ODR_Pm3_MASK))
+				| (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm2_OFFSET) | (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm3_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) | PORT_PMR_B2_BIT | PORT_PMR_B3_BIT);
+			break;
+		case sciSPIM:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT3_PODR_ADDR,
+				sil_reb_mem(PORT3_PODR_ADDR) | PORT_PODR_B2_BIT | PORT_PODR_B3_BIT | PORT_PODR_B4_BIT);
+			/* MOSI出力/MISO入力/SCK入出力ポート設定 */
+			sil_wrb_mem(PORT3_PDR_ADDR, (sil_reb_mem(PORT3_PDR_ADDR) | PORT_PDR_B2_BIT | PORT_PDR_B4_BIT) & ~PORT_PDR_B3_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT3_PCR_ADDR, sil_reb_mem(PORT3_PCR_ADDR) & ~(PORT_PCR_B2_BIT | PORT_PCR_B3_BIT | PORT_PCR_B4_BIT));
+			/* MISO CMOS */
+			sil_wrb_mem(PORT3_ODR0_ADDR,
+				(sil_reb_mem(PORT3_ODR0_ADDR) & ~(PORT_ODR_Pm2_MASK | PORT_ODR_Pm3_MASK | PORT_ODR_Pm4_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm2_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm3_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm4_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) | PORT_PMR_B2_BIT | PORT_PMR_B3_BIT | PORT_PMR_B4_BIT);
+			break;
+		}
+
+		/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+		/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+		/* P32端子機能制御レジスタ TXD6/SMOSI6/SSDA6とする */
+		sil_wrb_mem(MPC_P32PFS_ADDR, 0x0A);
+		/* P33端子機能制御レジスタ RXD6/SMISO6/SSCL6とする */
+		sil_wrb_mem(MPC_P33PFS_ADDR, 0x0A);
+		if (mode == sciSPIM) {
+			/* P34端子機能制御レジスタ SCK6とする */
+			sil_wrb_mem(MPC_P34PFS_ADDR, 0x0A);
+		}
+
+		/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+		break;
+	/* TXD/SDA/MOSI:PC7, RXD/SCL/MISO:PC6, SCK:PC5 */
+	case SCI8_BASE:
+		switch (mode) {
+		case sciSerial:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORTC_PODR_ADDR,
+				sil_reb_mem(PORTC_PODR_ADDR) | PORT_PODR_B6_BIT | PORT_PODR_B7_BIT);
+			/* TX出力/RX入力ポート設定 */
+			sil_wrb_mem(PORTC_PDR_ADDR, (sil_reb_mem(PORTC_PDR_ADDR) | PORT_PDR_B6_BIT) & ~PORT_PDR_B7_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORTC_PCR_ADDR, sil_reb_mem(PORTC_PCR_ADDR) & ~(PORT_PCR_B6_BIT | PORT_PCR_B7_BIT));
+			/* RX CMOS */
+			sil_wrb_mem(PORTC_ODR0_ADDR,
+				(sil_reb_mem(PORTC_ODR0_ADDR) & ~(PORT_ODR_Pm6_MASK | PORT_ODR_Pm7_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm6_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm7_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORTC_PMR_ADDR, sil_reb_mem(PORTC_PMR_ADDR) | PORT_PMR_B6_BIT | PORT_PMR_B7_BIT);
+			break;
+		case sciI2C:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORTC_PODR_ADDR,
+				sil_reb_mem(PORTC_PODR_ADDR) | PORT_PODR_B6_BIT | PORT_PODR_B7_BIT);
+			/* SCL,SDA 出力ポート設定 */
+			sil_wrb_mem(PORTC_PDR_ADDR, sil_reb_mem(PORTC_PDR_ADDR) | PORT_PDR_B6_BIT | PORT_PDR_B7_BIT);
+			/* プルアップ有効 */
+			sil_wrb_mem(PORTC_PCR_ADDR, sil_reb_mem(PORTC_PCR_ADDR) | PORT_PCR_B6_BIT | PORT_PCR_B7_BIT);
+			/* Nチャネルオープンドレイン */
+			sil_wrb_mem(PORTC_ODR0_ADDR,
+				(sil_reb_mem(PORTC_ODR0_ADDR) & ~(PORT_ODR_Pm6_MASK | PORT_ODR_Pm7_MASK))
+				| (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm6_OFFSET) | (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm7_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORTC_PMR_ADDR, sil_reb_mem(PORTC_PMR_ADDR) | PORT_PMR_B6_BIT | PORT_PMR_B7_BIT);
+			break;
+		case sciSPIM:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORTC_PODR_ADDR,
+				sil_reb_mem(PORTC_PODR_ADDR) | PORT_PODR_B7_BIT | PORT_PODR_B6_BIT | PORT_PODR_B5_BIT);
+			/* MOSI出力/MISO入力/SCK入出力ポート設定 */
+			sil_wrb_mem(PORTC_PDR_ADDR, (sil_reb_mem(PORTC_PDR_ADDR) | PORT_PDR_B5_BIT | PORT_PDR_B7_BIT) & ~PORT_PDR_B6_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORTC_PCR_ADDR, sil_reb_mem(PORTC_PCR_ADDR) & ~(PORT_PCR_B5_BIT | PORT_PCR_B7_BIT | PORT_PCR_B6_BIT));
+			/* MISO CMOS */
+			sil_wrb_mem(PORTC_ODR0_ADDR,
+				(sil_reb_mem(PORTC_ODR0_ADDR) & ~(PORT_ODR_Pm5_MASK | PORT_ODR_Pm6_MASK | PORT_ODR_Pm7_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm5_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm6_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm7_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORTC_PMR_ADDR, sil_reb_mem(PORTC_PMR_ADDR) | PORT_PMR_B5_BIT | PORT_PMR_B6_BIT | PORT_PMR_B7_BIT);
+			break;
+		}
+
+		/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+		/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+		/* PC7端子機能制御レジスタ TXD8/SMOSI8/SSDA8とする */
+		sil_wrb_mem(MPC_PC7PFS_ADDR, 0x0A);
+		/* PC6端子機能制御レジスタ RXD8/SMISO8/SSCL8とする */
+		sil_wrb_mem(MPC_PC6PFS_ADDR, 0x0A);
+		if (mode == sciSPIM) {
+			/* PC5端子機能制御レジスタ SCK8とする */
+			sil_wrb_mem(MPC_PC5PFS_ADDR, 0x0A);
+		}
+
+		/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+		break;
+	}
+}
+
+void sci_disable(void *base_address)
+{
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(base_address), 0x00U);
+
+	/*
+	 *  モジュールストップ機能の設定
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRB_ADDR,
+		sil_rew_mem(SYSTEM_MSTPCRB_ADDR) | SCI_MSTPCRB_BIT(base_address));
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* 書込み禁止 */
+}
+
+void sci_set_frequency(void *base_address, int hz)
+{
+	uint_t	cnt, brr, clk;
+
+	cnt = (FREQ_PCLK * 1000) / (16 * hz);
+	if (cnt < 512)
+		clk = 0;
+	else if (cnt < 4 * 512)
+		clk = 1;
+	else if (cnt < 16 * 512)
+		clk = 2;
+	else if (cnt < 64 * 512)
+		clk = 3;
+	else
+		return;
+
+	brr = cnt / (1 << (2 * clk));
+	brr = (brr / 2) + (brr % 2) - 1;
+
+	/* SMRに送信／ 受信フォーマットを設定 */
+	/* クロック選択ビット(SMR.CKS[1:0]ビットを設定)、それ以外のビットを“0”に設定 */
+	sil_wrb_mem(SCI_SMR(base_address), clk);
+
+	/* ビットレートを設定 */
+	sil_wrb_mem(SCI_BRR(base_address), brr);
+}
+
+void serial_init(serial_t *obj, PinName tx, PinName rx)
+{
+#ifdef TOPPERS_GRCITRUS
+	if ((rx == D1) && (tx == D0)) {
+		obj->base_address = (void *)SCI0_BASE;
+		obj->rxi_intno = INT_SCI0_RXI;
+		obj->tei_intno = INT_SCI0_TEI;
+	}
+	else if ((rx == D6) && (tx == D5)) {
+		obj->base_address = (void *)SCI2_BASE;
+		obj->rxi_intno = INT_SCI2_RXI;
+		obj->tei_intno = INT_SCI2_TEI;
+	}
+	else if ((rx == D8) && (tx == D7)) {
+		obj->base_address = (void *)SCI6_BASE;
+		obj->rxi_intno = INT_SCI6_RXI;
+		obj->tei_intno = INT_SCI6_TEI;
+	}
+	else if ((rx == D11) && (tx == D12)) {
+		obj->base_address = (void *)SCI8_BASE;
+		obj->rxi_intno = INT_SCI8_RXI;
+		obj->tei_intno = INT_SCI8_TEI;
+	}
+	else {
+		obj->base_address = NULL;
+		return;
+	}
+#else
+	if ((rx == D0) && (tx == D1)) {
+		obj->base_address = (void *)SCI0_BASE;
+		obj->rxi_intno = INT_SCI0_RXI;
+		obj->tei_intno = INT_SCI0_TEI;
+	}
+	else if ((rx == D6) && (tx == D7)) {
+		obj->base_address = (void *)SCI6_BASE;
+		obj->rxi_intno = INT_SCI6_RXI;
+		obj->tei_intno = INT_SCI6_TEI;
+	}
+	else if ((rx == D11) && (tx == D12)) {
+		obj->base_address = (void *)SCI8_BASE;
+		obj->rxi_intno = INT_SCI8_RXI;
+		obj->tei_intno = INT_SCI8_TEI;
+}
+	else {
+		obj->base_address = NULL;
+		return;
+	}
+#endif // TOPPERS_GRCITRUS
+	dis_int(obj->rxi_intno);
+	dis_int(obj->tei_intno);
+
+	/* SCI有効 */
+	sci_enable(obj->base_address, sciSerial);
+
+	/* SIMR1.IICMビットを“0”に設定 */
+	sil_wrb_mem(SCI_SIMR1(obj->base_address),
+		sil_reb_mem(SCI_SIMR1(obj->base_address)) & ~IICM);
+
+	/* SPMR.CKPH, CKPOLビットを“0”に設定 */
+	sil_wrb_mem(SCI_SPMR(obj->base_address),
+		sil_reb_mem(SCI_SPMR(obj->base_address)) & ~(CKPH | CKPOL));
+
+	sci_set_frequency(obj->base_address, /*9600*/115200);
+
+	/* SCMRレジスタはSDIRビットを“0”、SINVビットを“0”、SMIFビットを“0”に設定 */
+	sil_wrb_mem(SCI_SCMR(obj->base_address),
+		(sil_reb_mem(SCI_SCMR(obj->base_address)) & ~(SINV | SMIF | SDIR)));
+
+	/* SMRに送信／ 受信フォーマットを設定 */
+	serial_format(obj, 8, ParityNone, 1);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) | RE | TE));
+
+	ena_int(obj->rxi_intno);
+	ena_int(obj->tei_intno);
+}
+
+void serial_free(serial_t *obj)
+{
+	dis_int(obj->rxi_intno);
+	dis_int(obj->tei_intno);
+
+	/* SCI無効 */
+	sci_disable(obj->base_address);
+
+	obj->base_address = NULL;
+}
+
+void serial_baud(serial_t *obj, int baudrate)
+{
+	uint8_t scr = sil_reb_mem(SCI_SCR(obj->base_address));
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), 0x00U);
+
+	sci_set_frequency(obj->base_address, baudrate);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), scr);
+}
+
+void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
+{
+	uint8_t smr = sil_reb_mem(SCI_SMR(obj->base_address));
+
+	smr &= ~(PE | PM | CHR | STOP);
+
+	switch (parity) {
+	case ParityNone:
+		break;
+	case ParityOdd:
+		smr |= PE | PM;
+		break;
+	case ParityEven:
+		smr |= PE;
+		break;
+	default:
+		break;
+	}
+
+	switch (data_bits) {
+	case 7:
+		smr |= CHR;
+		break;
+	case 8:
+		break;
+	default:
+		break;
+	}
+
+	switch (stop_bits) {
+	case 1:
+		break;
+	case 2:
+		smr |= STOP;
+		break;
+	default:
+		break;
+	}
+
+	sil_wrb_mem(SCI_SMR(obj->base_address), smr);
+}
+
+int serial_getc(serial_t *obj)
+{
+	uint8_t ssr;
+	int c;
+
+	for (;;) {
+		/* SSR.ORER, PER, FERフラグをリード */
+		ssr = sil_reb_mem(SCI_SSR(obj->base_address));
+
+		/* 受信エラーが発生したとき */
+		if ((ssr & (ORER | PER | FER)) != 0) {
+			/* オーバランエラー */
+			if ((ssr & ORER) != 0) {
+				/* RDRレジスタをリード */
+				c = (int)sil_reb_mem(SCI_RDR(obj->base_address));
+			}
+			/* フレーミングエラー */
+			if ((ssr & FER) != 0) {
+			}
+			/* パリティエラー */
+			if ((ssr & PER) != 0) {
+			}
+		}
+
+		/* SSR.ORER, PER, FERフラグを“0”に設定 */
+		sil_wrb_mem(SCI_SSR(obj->base_address), ssr & ~(ORER | PER | FER));
+
+		/* SSR.ORER, PER, FERフラグをリード */
+		ssr = sil_reb_mem(SCI_SSR(obj->base_address));
+
+		/* RXI割り込み */
+		if (serial_readable(obj)) {
+			clear_int(obj->rxi_intno);
+			break;
+		}
+
+		dly_tsk(10);
+	}
+
+	/* RDRレジスタをリード */
+	c = (int)sil_reb_mem(SCI_RDR(obj->base_address));
+
+	return c;
+}
+
+void serial_putc(serial_t *obj, int c)
+{
+	while (!serial_writable(obj))
+		dly_tsk(10);
+
+	sil_wrb_mem(SCI_TDR(obj->base_address), (char)c);
+
+	clear_int(obj->tei_intno);
+}
+
+int serial_readable(serial_t *obj)
+{
+	//return probe_int(obj->rxi_intno);
+	return true;
+}
+
+int serial_writable(serial_t *obj)
+{
+	//return probe_int(obj->tei_intno);
+	return (sil_reb_mem(SCI_SSR(obj->base_address)) & TEND) != 0U;
+}
+
+void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
+{
+	switch (irq) {
+	case RxIrq:
+		if (enable) {
+			sil_wrb_mem(SCI_SCR(obj->base_address),
+				(sil_reb_mem(SCI_SCR(obj->base_address)) | RIE));
+		}
+		else {
+			sil_wrb_mem(SCI_SCR(obj->base_address),
+				(sil_reb_mem(SCI_SCR(obj->base_address)) & (~RIE)));
+		}
+		break;
+	case TxIrq:
+		if (enable) {
+			sil_wrb_mem(SCI_SCR(obj->base_address),
+				(sil_reb_mem(SCI_SCR(obj->base_address)) | TEIE));
+		}
+		else {
+			sil_wrb_mem(SCI_SCR(obj->base_address),
+				(sil_reb_mem(SCI_SCR(obj->base_address)) & (~TEIE)));
+		}
+		break;
+	}
+}
+
+struct uart_irq_info_t {
+	uart_irq_handler handler;
+	uint32_t id;
+};
+
+struct uart_irq_info_t sci_irq_info[7];
+
+void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
+{
+	int no = SCI_NUM(obj->base_address);
+	bool_t lock = sense_lock();
+
+	if (!lock)
+		loc_cpu();
+
+	sci_irq_info[no].handler = handler;
+	sci_irq_info[no].id = id;
+
+	if (!lock)
+		unl_cpu();
+}
+
+void i2c_init(i2c_t *obj, PinName sda, PinName scl)
+{
+	if ((sda == I2C_SDA) && (scl == I2C_SCL)) {
+#ifdef TOPPERS_GRCITRUS
+		obj->base_address = (void *)SCI6_BASE;
+		obj->rxi_intno = INT_SCI6_RXI;
+		obj->txi_intno = INT_SCI6_TXI;
+		obj->tei_intno = INT_SCI6_TEI;
+#else
+		obj->base_address = (void *)SCI2_BASE;
+		obj->rxi_intno = INT_SCI2_RXI;
+		obj->txi_intno = INT_SCI2_TXI;
+		obj->tei_intno = INT_SCI2_TEI;
+#endif
+	}
+	else {
+		obj->base_address = NULL;
+		return;
+	}
+
+	/* SCI有効 */
+	sci_enable(obj->base_address, sciI2C);
+
+	/* SIMR3.IICSDAS[1:0](b5-b4), IICSCLS[1:0](b7-b6)ビットを“11b”に設定 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address), 0xF0U);
+
+	sci_set_frequency(obj->base_address, 100000);
+
+	/* SCMRレジスタはSDIRビットを“1”、SINVビットを“0”、SMIFビットを“0”に設定 */
+	sil_wrb_mem(SCI_SCMR(obj->base_address),
+		(sil_reb_mem(SCI_SCMR(obj->base_address)) & ~(SINV | SMIF)) | SDIR);
+
+	/* SEMR、SNFR、SIMR1、SIMR2、SPMRレジスタに値を設定 */
+	/* SEMRレジスタは、NFENビットを設定 */
+	sil_wrb_mem(SCI_SEMR(obj->base_address), NFEN);
+
+	/* SNFRレジスタは、NFCS[2:0]ビットを設定*/
+	sil_wrb_mem(SCI_SNFR(obj->base_address), 1);
+
+	/* SIMR1レジスタは、IICMビットを“1”に設定し、IICDL[4:0]ビ	ットを設定 */
+	sil_wrb_mem(SCI_SIMR1(obj->base_address), IICM | (3 << 3));
+
+	/* SIMR2レジスタは、IICACKT、IICCSCビットを“1”に設定し、IICINTMビットを設定 */
+	sil_wrb_mem(SCI_SIMR2(obj->base_address), IICACKT | IICCSC | IICINTM);
+
+	/* SPMRレジスタは、全ビット“0”に設定 */
+	sil_wrb_mem(SCI_SPMR(obj->base_address), 0);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) | RE | TE));
+}
+
+void i2c_frequency(i2c_t *obj, int hz)
+{
+	uint8_t scr = sil_reb_mem(SCI_SCR(obj->base_address));
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), 0x00U);
+
+	sci_set_frequency(obj->base_address, hz);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), scr);
+}
+
+int i2c_start(i2c_t *obj)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	/* SIMR3.IICSTAREQビットを“1”に設定すると同時に、
+	 * SIMR3.IICSCLS[1:0],IICSDAS[1:0]ビットを“01b”に設定 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address), IICSTAREQ | (1 << 4) | (1 << 6));
+
+	return 0;
+}
+
+int i2c_restart(i2c_t *obj)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	sil_wrb_mem(SCI_SIMR3(obj->base_address), IICRSTAREQ | (1 << 4) | (1 << 6));
+
+	return 0;
+}
+
+int i2c_stop(i2c_t *obj)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	/* SIMR3.IICSTPREQビットを“1”に設定すると同時に、
+	 * SIMR3.IICSCLS[1:0],IICSDAS[1:0]ビットを“01b”に設定 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address), IICSTPREQ | (1 << 4) | (1 << 6));
+
+	return 0;
+}
+
+int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	/* 送信割り込み要求を禁止 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) & ~(RIE)) | TEIE | TIE);
+
+	/* 開始条件の生成 */
+	i2c_start(obj);
+
+	/* STI(TEI)割り込み発生確認 */
+	while (!probe_int(obj->tei_intno))
+		dly_tsk(2);
+	clear_int(obj->tei_intno);
+
+	/* SIMR3.IICSTIFフラグを“0”に設定し、 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address),
+		sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~IICSTIF);
+	/* SIMR3.IICSCLS[1:0], IICSDAS[1:0]ビットを“00b”に設定 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address),
+		sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~((3 << 4) | (3 << 6)));
+
+	/* TDRレジスタにスレーブアドレス、R/Wビットをライト */
+	sil_wrb_mem(SCI_TDR(obj->base_address), address | 1);
+
+	/* TXI割り込み発生確認 */
+	while (!probe_int(obj->txi_intno))
+		dly_tsk(10);
+	clear_int(obj->txi_intno);
+
+	/* スレーブデバイスからのACKを確認 */
+	if ((sil_reb_mem(SCI_SISR(obj->base_address)) & IICACKR) == 0) {
+		/* SIMR2.IICACKTビットを“0”に設定 */
+		sil_wrb_mem(SCI_SIMR2(obj->base_address), sil_reb_mem(SCI_SIMR2(obj->base_address)) & ~IICACKT);
+		/* SCR.RIEビットを“1”に設定 */
+		sil_wrb_mem(SCI_SCR(obj->base_address), sil_reb_mem(SCI_SCR(obj->base_address)) | RIE);
+
+		for (int i = 0; i < length; i++) {
+			/* 次データが最終 */
+			if (i == length - 1) {
+				/* SIMR2.IICACKTビットを“1”に設定 */
+				sil_wrb_mem(SCI_SIMR2(obj->base_address), sil_reb_mem(SCI_SIMR2(obj->base_address)) | IICACKT);
+			}
+
+			/* TDRレジスタにダミーデータ“FFh”をライト */
+			sil_wrb_mem(SCI_TDR(obj->base_address), 0xFF);
+
+			/* RXI割り込み発生確認 */
+			while (!probe_int(obj->rxi_intno))
+				dly_tsk(10);
+			clear_int(obj->rxi_intno);
+
+			/* RDRレジスタの受信データをリード */
+			*data = sil_reb_mem(SCI_RDR(obj->base_address));
+			data++;
+
+			/* TXI割り込み発生確認 */
+			while (!probe_int(obj->txi_intno))
+				dly_tsk(10);
+			clear_int(obj->txi_intno);
+		}
+	}
+
+	if (stop) {
+		/* 停止条件の生成 */
+		i2c_stop(obj);
+
+		/* STI(TEI)割り込み発生確認 */
+		while (!probe_int(obj->tei_intno))
+			dly_tsk(2);
+		clear_int(obj->tei_intno);
+
+		/* SIMR3.IICSTIFフラグを“0”に設定し、*/
+		sil_wrb_mem(SCI_SIMR3(obj->base_address),
+			sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~IICSTIF);
+		/* SIMR3.IICSCLS[1:0], IICSDAS[1:0]ビットを“11b”に設定 */
+		sil_wrb_mem(SCI_SIMR3(obj->base_address),
+			sil_reb_mem(SCI_SIMR3(obj->base_address)) | ((3 << 4) | (3 << 6)));
+	}
+
+	return length;
+}
+
+int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	/* 受信割り込み要求を禁止 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) & ~(RIE)) | TEIE | TIE);
+
+	/* 開始条件の生成 */
+	i2c_start(obj);
+
+	/* STI(TEI)割り込み発生確認 */
+	while (!probe_int(obj->tei_intno))
+		dly_tsk(2);
+	clear_int(obj->tei_intno);
+
+	/* SIMR3.IICSTIFフラグを“0”に設定し、 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address),
+		sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~IICSTIF);
+	/* SIMR3.IICSCLS[1:0], IICSDAS[1:0]ビットを“00b”に設定 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address),
+		sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~((3 << 4) | (3 << 6)));
+
+	/* TDRレジスタにスレーブアドレス、R/Wビットをライト */
+	sil_wrb_mem(SCI_TDR(obj->base_address), address);
+
+	/* TXI割り込み発生確認 */
+	while (!probe_int(obj->txi_intno))
+		dly_tsk(10);
+	clear_int(obj->txi_intno);
+
+	/* スレーブデバイスからのACKを確認 */
+	if ((sil_reb_mem(SCI_SISR(obj->base_address)) & IICACKR) == 0) {
+
+		for (int i = 0; i < length; i++) {
+			/* TDRレジスタにスレーブアドレス、R/Wビットをライト */
+			sil_wrb_mem(SCI_TDR(obj->base_address), *data);
+			data++;
+
+			/* TXI割り込み発生確認 */
+			while (!probe_int(obj->txi_intno))
+				dly_tsk(10);
+			clear_int(obj->txi_intno);
+		}
+	}
+
+	if (stop) {
+		/* 停止条件の生成 */
+		i2c_stop(obj);
+
+		/* STI(TEI)割り込み発生確認 */
+		while (!probe_int(obj->tei_intno))
+			dly_tsk(2);
+		clear_int(obj->tei_intno);
+
+		/* SIMR3.IICSTIFフラグを“0”に設定し、*/
+		sil_wrb_mem(SCI_SIMR3(obj->base_address),
+			sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~IICSTIF);
+		/* SIMR3.IICSCLS[1:0], IICSDAS[1:0]ビットを“11b”に設定 */
+		sil_wrb_mem(SCI_SIMR3(obj->base_address),
+			sil_reb_mem(SCI_SIMR3(obj->base_address)) | ((3 << 4) | (3 << 6)));
+	}
+
+	return length;
+}
+
+int i2c_byte_read(i2c_t *obj, int last)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	return 0;
+}
+
+int i2c_byte_write(i2c_t *obj, int data)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	return 0;
+}
+
+void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
+{
+	if ((mosi == D11) && (miso == D12) && (sclk == D13) && ((ssel == D10) || (ssel == NC))) {
+		obj->base_address = (void *)SCI8_BASE;
+		obj->txi_intno = INT_SCI8_TXI;
+		obj->rxi_intno = INT_SCI8_RXI;
+		obj->tei_intno = INT_SCI8_TEI;
+	}
+	else if ((mosi == D3) && (miso == D6) && (sclk == D4) && (ssel == NC)) {
+		obj->base_address = (void *)SCI3_BASE;
+		obj->txi_intno = INT_SCI3_TXI;
+		obj->rxi_intno = INT_SCI3_RXI;
+		obj->tei_intno = INT_SCI3_TEI;
+	}
+	else {
+		obj->base_address = NULL;
+		return;
+	}
+
+	/* SCI有効 */
+	sci_enable(obj->base_address, (ssel != NC) ? sciSPIS : sciSPIM);
+
+	/* SIMR1.IICMビットを“0”に設定 */
+	sil_wrb_mem(SCI_SIMR1(obj->base_address),
+		sil_reb_mem(SCI_SIMR1(obj->base_address)) & ~IICM);
+
+	if (ssel == NC) {
+		/* SPMR.SSE, CTSE, MSS, MFF, CKPH, CKPOLビットを“0”に設定 */
+		sil_wrb_mem(SCI_SPMR(obj->base_address), 0);
+	}
+	else {
+		/* SPMR, CTSE, MSS, MFF, CKPH, CKPOLビットを“0”に設定 */
+		/* SPMR.SSEビットを“1”に設定 */
+		sil_wrb_mem(SCI_SPMR(obj->base_address), SSE);
+	}
+
+	/* SCMRレジスタはSDIRビットを“0”、SINVビットを“0”、SMIFビットを“0”に設定 */
+	sil_wrb_mem(SCI_SCMR(obj->base_address),
+		(sil_reb_mem(SCI_SCMR(obj->base_address)) & ~(SMIF | SDIR)) | SINV);
+
+	/* SMRに送信／ 受信フォーマットをクロック同期式モードで動作で設定 */
+	sil_wrb_mem(SCI_SMR(obj->base_address), CM);
+
+	sci_set_frequency(obj->base_address, 1000000);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) | RE | TE));
+}
+
+void spi_free(spi_t *obj)
+{
+	/* SCI無効 */
+	sci_disable(obj->base_address);
+
+	obj->base_address = NULL;
+}
+
+void spi_format(spi_t *obj, int bits, int mode, int slave)
+{
+	int polarity = (mode & 0x2) ? 1 : 0;
+	int phase = (mode & 0x1) ? 1 : 0;
+	uint8_t spmr;
+
+	if ((bits != 8) || (mode < 0) || (mode > 3)) {
+		return;
+	}
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), 0x00U);
+
+	spmr = sil_reb_mem(SCI_SPMR(obj->base_address));
+
+	/* クロック極性反転あり/なし */
+	if (polarity)
+		spmr |= CKPOL;
+	else
+		spmr &= ~CKPOL;
+
+	/* クロック位相反転あり/なし */
+	if (phase)
+		spmr |= CKPH;
+	else
+		spmr &= ~CKPH;
+
+	if (slave) {
+		/* SCKn端子はクロック入力として使用 */
+		sil_wrb_mem(SCI_SCR(obj->base_address), 
+			(sil_reb_mem(SCI_SCR(obj->base_address)) & ~CKE) | 2);
+
+		/* SPMR.MSSビットを“1”に設定 */
+		sil_wrb_mem(SCI_SPMR(obj->base_address), spmr | MSS);
+	}
+	else {
+		/* SCKn端子はクロック出力として使用 */
+		sil_wrb_mem(SCI_SCR(obj->base_address),
+			sil_reb_mem(SCI_SCR(obj->base_address)) & ~CKE);
+
+		/* SPMR.MSSビットを“0”に設定 */
+		sil_wrb_mem(SCI_SPMR(obj->base_address), spmr & ~MSS);
+	}
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) | RE | TE));
+}
+
+void spi_frequency(spi_t *obj, int hz)
+{
+	uint8_t scr = sil_reb_mem(SCI_SCR(obj->base_address));
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), 0x00U);
+
+	sci_set_frequency(obj->base_address, hz);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), scr);
+}
+
+int spi_master_write(spi_t *obj, int value)
+{
+	/* TXI割り込み発生確認 */
+	while (!probe_int(obj->txi_intno))
+		;
+
+	/* 送信データをライト */
+	sil_wrb_mem(SCI_TDR(obj->base_address), (char)value);
+
+	do {
+		uint8_t ssr = sil_reb_mem(SCI_SSR(obj->base_address));
+		if ((ssr & ORER) != 0) {
+			ssr &= ~ORER;
+			sil_wrb_mem(SCI_SSR(obj->base_address), ssr);
+			return -1;
+		}
+	}
+	/* RXI割り込み発生確認 */
+	while (!probe_int(obj->rxi_intno));
+
+	/* 受信データをリード */
+	return sil_reb_mem(SCI_RDR(obj->base_address));
+}
+
+int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
+	char *rx_buffer, int rx_length, char write_fill)
+{
+	int total = (tx_length > rx_length) ? tx_length : rx_length;
+
+	for (int i = 0; i < total; i++) {
+		char out = (i < tx_length) ? tx_buffer[i] : write_fill;
+		char in = spi_master_write(obj, out);
+		if (i < rx_length) {
+			rx_buffer[i] = in;
+		}
+	}
+
+	return total;
+}
+
+uint8_t DecToBcd(uint8_t value)
+{
+	return ((value / 10) << 4) | (value % 10);
+}
+
+uint8_t BcdToDec(uint8_t value)
+{
+	return (10 * (value >> 4)) | (value & 0x0F);
+}
+
+void rtc_init(void)
+{
+}
+
+void rtc_free(void)
+{
+}
+
+int rtc_isenabled(void)
+{
+	return 1;
+}
+
+long long __tm_to_secs(const struct tm *tm);
+int __secs_to_tm(long long t, struct tm *tm);
+
+time_t rtc_read(void)
+{
+	struct tm tm = { 0 };
+	tm.tm_year = 2000 - 1900 + BcdToDec(sil_reb_mem((uint8_t *)RTC_RYRCNT_ADDR));
+	tm.tm_mon = BcdToDec(sil_reb_mem((uint8_t *)RTC_RMONCNT_ADDR)) - 1;
+	tm.tm_mday = BcdToDec(sil_reb_mem((uint8_t *)RTC_RDAYCNT_ADDR));
+	tm.tm_hour = BcdToDec(sil_reb_mem((uint8_t *)RTC_RHRCNT_ADDR));
+	tm.tm_min = BcdToDec(sil_reb_mem((uint8_t *)RTC_RMINCNT_ADDR));
+	tm.tm_sec = BcdToDec(sil_reb_mem((uint8_t *)RTC_RSECCNT_ADDR));
+	return __tm_to_secs(&tm);
+}
+
+void rtc_write(time_t t)
+{
+	struct tm tm;
+
+	__secs_to_tm(t, &tm);
+	sil_wrb_mem((uint8_t *)RTC_RYRCNT_ADDR, DecToBcd(tm.tm_year + 1900 - 2000));
+	sil_wrb_mem((uint8_t *)RTC_RMONCNT_ADDR, DecToBcd(tm.tm_mon + 1));
+	sil_wrb_mem((uint8_t *)RTC_RDAYCNT_ADDR, DecToBcd(tm.tm_mday));
+	sil_wrb_mem((uint8_t *)RTC_RHRCNT_ADDR, DecToBcd(tm.tm_hour));
+	sil_wrb_mem((uint8_t *)RTC_RMINCNT_ADDR, DecToBcd(tm.tm_min));
+	sil_wrb_mem((uint8_t *)RTC_RSECCNT_ADDR, DecToBcd(tm.tm_sec));
+}
+
+void sci_rxi_handler(uint32_t no)
+{
+	struct uart_irq_info_t *info = &sci_irq_info[no];
+	if (info->handler == NULL)
+		return;
+
+	info->handler(info->id, RxIrq);
+}
+
+void sci_txi_handler(uint32_t no)
+{
+/*	struct uart_irq_info_t *info = &sci_irq_info[no];
+	if (info->handler == NULL)
+		return;
+
+	info->handler(info->id, TxIrq);*/
+}
+
+void sci_tei_handler(int no)
+{
+	struct uart_irq_info_t *info = &sci_irq_info[no];
+	if (info->handler == NULL)
+		return;
+
+	info->handler(info->id, TxIrq);
+}
+
+void sci0_rxi_handler(void)
+{
+	sci_rxi_handler(0);
+}
+
+void sci0_txi_handler(void)
+{
+	sci_txi_handler(0);
+}
+
+void sci0_tei_handler(void)
+{
+	sci_tei_handler(0);
+}
+
+void sci1_rxi_handler(void)
+{
+	sci_rxi_handler(1);
+}
+
+void sci1_txi_handler(void)
+{
+	sci_txi_handler(1);
+}
+
+void sci1_tei_handler(void)
+{
+	sci_tei_handler(1);
+}
+
+void sci2_rxi_handler(void)
+{
+	sci_rxi_handler(2);
+}
+
+void sci2_txi_handler(void)
+{
+	sci_txi_handler(2);
+}
+
+void sci2_tei_handler(void)
+{
+	sci_tei_handler(2);
+}
+
+void sci3_rxi_handler(void)
+{
+	sci_rxi_handler(3);
+}
+
+void sci3_txi_handler(void)
+{
+	sci_txi_handler(3);
+}
+
+void sci3_tei_handler(void)
+{
+	sci_tei_handler(3);
+}
+
+void sci4_rxi_handler(void)
+{
+	sci_rxi_handler(4);
+}
+
+void sci4_txi_handler(void)
+{
+	sci_txi_handler(4);
+}
+
+void sci4_tei_handler(void)
+{
+	sci_tei_handler(4);
+}
+
+void sci5_rxi_handler(void)
+{
+	sci_rxi_handler(5);
+}
+
+void sci5_txi_handler(void)
+{
+	sci_txi_handler(5);
+}
+
+void sci5_tei_handler(void)
+{
+	sci_tei_handler(5);
+}
+
+void sci6_rxi_handler(void)
+{
+	sci_rxi_handler(6);
+}
+
+void sci6_txi_handler(void)
+{
+	sci_txi_handler(6);
+}
+
+void sci6_tei_handler(void)
+{
+	sci_tei_handler(6);
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/target/mbed_api.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/target/mbed_api.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/mbed/target/mbed_api.cfg	(revision 398)
@@ -0,0 +1,120 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2018 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  gpio_apiのシステムコンフィギュレーションファイル
+ */
+#include "shellif.h"
+#include "gpio_api.h"
+
+/* CSI0 */
+
+DEF_INH(INT_SCI0_RXI, { TA_HLNG, sci0_rxi_handler });
+CFG_INT(INT_SCI0_RXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI0_TXI, { TA_HLNG, sci0_txi_handler });
+CFG_INT(INT_SCI0_TXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI0_TEI, { TA_HLNG, sci0_tei_handler });
+CFG_INT(INT_SCI0_TEI, { TA_NULL, -1 });
+
+/* CSI1 */
+
+DEF_INH(INT_SCI1_RXI, { TA_HLNG, sci1_rxi_handler });
+CFG_INT(INT_SCI1_RXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI1_TXI, { TA_HLNG, sci1_txi_handler });
+CFG_INT(INT_SCI1_TXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI1_TEI, { TA_HLNG, sci1_tei_handler });
+CFG_INT(INT_SCI1_TEI, { TA_NULL, -1 });
+
+/* CSI2 */
+
+DEF_INH(INT_SCI2_RXI, { TA_HLNG, sci2_rxi_handler });
+CFG_INT(INT_SCI2_RXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI2_TXI, { TA_HLNG, sci2_txi_handler });
+CFG_INT(INT_SCI2_TXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI2_TEI, { TA_HLNG, sci2_tei_handler });
+CFG_INT(INT_SCI2_TEI, { TA_NULL, -1 });
+
+/* CSI3 */
+
+DEF_INH(INT_SCI3_RXI, { TA_HLNG, sci3_rxi_handler });
+CFG_INT(INT_SCI3_RXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI3_TXI, { TA_HLNG, sci3_txi_handler });
+CFG_INT(INT_SCI3_TXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI3_TEI, { TA_HLNG, sci3_tei_handler });
+CFG_INT(INT_SCI3_TEI, { TA_NULL, -1 });
+
+/* CSI4 */
+
+DEF_INH(INT_SCI4_RXI, { TA_HLNG, sci4_rxi_handler });
+CFG_INT(INT_SCI4_RXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI4_TXI, { TA_HLNG, sci4_txi_handler });
+CFG_INT(INT_SCI4_TXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI4_TEI, { TA_HLNG, sci4_tei_handler });
+CFG_INT(INT_SCI4_TEI, { TA_NULL, -1 });
+
+/* CSI5 */
+
+DEF_INH(INT_SCI5_RXI, { TA_HLNG, sci5_rxi_handler });
+CFG_INT(INT_SCI5_RXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI5_TXI, { TA_HLNG, sci5_txi_handler });
+CFG_INT(INT_SCI5_TXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI5_TEI, { TA_HLNG, sci5_tei_handler });
+CFG_INT(INT_SCI5_TEI, { TA_NULL, -1 });
+
+/* CSI6 */
+
+DEF_INH(INT_SCI6_RXI, { TA_HLNG, sci6_rxi_handler });
+CFG_INT(INT_SCI6_RXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI6_TXI, { TA_HLNG, sci6_txi_handler });
+CFG_INT(INT_SCI6_TXI, { TA_NULL, -1 });
+
+DEF_INH(INT_SCI6_TEI, { TA_HLNG, sci6_tei_handler });
+CFG_INT(INT_SCI6_TEI, { TA_NULL, -1 });
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/Makefile
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/Makefile	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/Makefile	(revision 398)
@@ -0,0 +1,611 @@
+#
+#  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-2016 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)
+
+#
+#  カーネルライブラリ（libkernel.a）のディレクトリ名
+#  （カーネルライブラリもmake対象にする時は，空に定義する）
+#
+KERNEL_LIB = @(KERNEL_LIB)
+
+#
+#  カーネルを関数単位でコンパイルするかどうかの定義
+#
+KERNEL_FUNCOBJS = @(KERNEL_FUNCOBJS)
+
+#
+#  TECSを外すかどうかの定義
+#
+OMIT_TECS = @(OMIT_TECS)
+
+#
+#  トレースログを取得するかどうかの定義
+#
+ENABLE_TRACE = @(ENABLE_TRACE)
+
+#
+#  開発ツール（コンパイラ等）のディレクトリの定義
+#
+DEVTOOLDIR = @(DEVTOOLDIR)
+
+#
+#  ユーティリティプログラムの名称
+#
+CFG = @(CFG)
+TECSGEN = @(TECSGEN)
+
+#
+#  オブジェクトファイル名の定義
+#
+OBJNAME = asp
+ifdef OBJEXT
+	OBJFILE = $(OBJNAME).$(OBJEXT)
+	CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+	OBJFILE = $(OBJNAME)
+	CFG1_OUT = cfg1_out
+endif
+
+#
+#  依存関係ファイルを置くディレクトリの定義
+#
+DEPDIR = @(DEPDIR)
+
+#
+#  ターゲット依存部のディレクトリの定義
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+#  ターゲット依存の定義のインクルード
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+#  TECS生成ファイルのディレクトリの定義
+#
+TECSGENDIR = ./gen
+ifndef OMIT_TECS
+	TECSGEN_TIMESTAMP = $(TECSGENDIR)/tecsgen.timestamp
+	INIT_TECS_COBJ = init_tecs.o
+endif
+
+#
+#  TECSが生成する定義のインクルード
+#
+ifndef OMIT_TECS
+	GEN_DIR = $(TECSGENDIR)
+	-include $(TECSGENDIR)/Makefile.tecsgen
+endif
+
+#
+#  共通コンパイルオプションの定義
+#
+COPTS := -g @(COPTS) $(COPTS)
+ifndef OMIT_WARNING_ALL
+	COPTS := -Wall $(COPTS)
+endif
+ifndef OMIT_OPTIMIZATION
+	COPTS := -O2 $(COPTS)
+endif
+ifdef OMIT_TECS
+	CDEFS := -DTOPPERS_OMIT_TECS $(CDEFS)
+endif
+CDEFS := $(CDEFS) @(CDEFS)
+INCLUDES := -I. -I$(SRCDIR)/include $(INCLUDES) -I$(SRCDIR)
+LDFLAGS := $(LDFLAGS) @(LDFLAGS)
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+#  アプリケーションプログラムに関する定義
+#
+APPLNAME = @(APPLNAME)
+APPLDIRS = @(APPLDIRS)
+APPL_CFG = @(CFGFILE)
+APPL_CDL = @(CDLFILE)
+
+APPL_DIRS := $(APPLDIRS) $(SRCDIR)/library
+APPL_ASMOBJS :=
+ifdef USE_CXX
+	APPL_CXXOBJS := @(APPLOBJS)
+	APPL_COBJS :=
+else
+	APPL_COBJS := @(APPLOBJS)
+endif
+APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
+APPL_CFLAGS := $(APPL_CFLAGS)
+ifdef APPLDIRS
+	INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIRS),-I$(dir))
+endif
+
+#
+#  ネットワークサービスの定義
+#
+
+NO_USE_TINET_LIBRARY = true
+
+#  ネットワークインタフェースの選択、何れか一つ選択する。
+
+NET_IF = ether
+
+#  イーサネット・ディバイスドライバの選択
+
+NET_DEV = if_mbed
+
+#  ネットワーク層の選択
+
+#SUPPORT_INET6 = true
+SUPPORT_INET4 = true
+
+#  API に組込む機能の選択
+
+#API_CFG_IP4MAPPED_ADDR = true
+
+#  トランスポート層の選択
+
+SUPPORT_TCP = true
+#SUPPORT_UDP = true
+
+#
+#  システムサービスの Makefile のインクルード
+#
+include $(SRCDIR)/tinet/Makefile.tinet
+
+#
+#  システムサービスに関する定義
+#
+SYSSVC_DIRS := $(TECSGENDIR) $(SRCDIR)/tecs_kernel \
+				$(SYSSVC_DIRS) $(SRCDIR)/syssvc
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(INIT_TECS_COBJ) $(TECS_COBJS) $(SYSSVC_COBJS) \
+				@(SYSSVCOBJS) $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+INCLUDES := $(INCLUDES) -I$(TECSGENDIR) -I$(SRCDIR)/tecs_kernel
+
+#
+#  ターゲットファイル
+#
+.PHONY: all
+ifndef OMIT_TECS
+all: tecs | $(DEPDIR)
+#	@$(MAKE) check
+	@$(MAKE) check $(OBJNAME).bin
+#	@$(MAKE) check $(OBJNAME).srec
+else
+#all: check
+all: check $(OBJNAME).bin
+#all: check $(OBJNAME).srec
+endif
+
+##### 以下は編集しないこと #####
+
+#
+#  コンフィギュレータに関する定義
+#
+CFG_TABS := --api-table $(SRCDIR)/tinet/tcpip_api.def:tcpip \
+			--api-table $(SRCDIR)/kernel/kernel_api.def:kernel \
+			--symval-table $(SRCDIR)/tinet/tcpip_sym.def \
+			--symval-table $(SRCDIR)/kernel/kernel_sym.def $(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)
+CFG_CFLAGS := -DTOPPERS_CB_TYPE_ONLY $(CFG_CFLAGS)
+
+#
+#  カーネルに関する定義
+#
+#  KERNEL_ASMOBJS: カーネルライブラリに含める，ソースがアセンブリ言語の
+#				   オブジェクトファイル．
+#  KERNEL_COBJS: カーネルのライブラリに含める，ソースがC言語で，ソース
+#				 ファイルと1対1に対応するオブジェクトファイル．
+#  KERNEL_LCSRCS: カーネルのライブラリに含めるC言語のソースファイルで，
+#				  1つのソースファイルから複数のオブジェクトファイルを生
+#				  成するもの．
+#  KERNEL_LCOBJS: 上のソースファイルから生成されるオブジェクトファイル．
+#
+KERNEL_DIRS := $(KERNEL_DIRS) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+
+#
+#  カーネルのファイル構成の定義
+#
+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
+ifdef OMIT_OFFSET_H
+	OFFSET_H =
+else
+	OFFSET_H = offset.h
+endif
+ifndef TARGET_OFFSET_TRB
+	TARGET_OFFSET_TRB := $(TARGETDIR)/target_offset.trb
+endif
+ifndef TARGET_KERNEL_TRB
+	TARGET_KERNEL_TRB := $(TARGETDIR)/target_kernel.trb
+endif
+ifndef TARGET_CHECK_TRB
+	TARGET_CHECK_TRB := $(TARGETDIR)/target_check.trb
+endif
+ifndef TARGET_KERNEL_CFG
+	TARGET_KERNEL_CFG := $(TARGETDIR)/target_kernel.cfg
+endif
+ifndef TARGET_TCPIP_TRB
+	TARGET_TCPIP_TRB := $(SRCDIR)/$(TINETDIR)/tinet.trb
+endif
+
+#
+#  ソースファイルのあるディレクトリに関する定義
+#
+vpath %.c $(KERNEL_DIRS) $(SYSSVC_DIRS) $(APPL_DIRS)
+vpath %.S $(KERNEL_DIRS) $(SYSSVC_DIRS) $(APPL_DIRS)
+vpath %.cfg $(APPL_DIRS)
+vpath %.cdl $(APPL_DIRS)
+
+#
+#  コンパイルのための変数の定義
+#
+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)
+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) -Wl,-T,$(LDSCRIPT)
+endif
+
+#
+#  tecsgenからCプリプロセッサを呼び出す際のオプションの定義
+#
+TECS_CPP = $(CC) $(CDEFS) $(INCLUDES) $(SYSSVC_CFLAGS) -D TECSGEN -E
+
+#
+#  tecsgenの呼出し
+#
+.PHONY: tecs
+tecs $(TECSGEN_SRCS) $(TECS_HEADERS): $(TECSGEN_TIMESTAMP) ;
+$(TECSGEN_TIMESTAMP): $(APPL_CDL) $(TECS_IMPORTS)
+	$(TECSGEN) $< -R $(INCLUDES) --cpp "$(subst ", \", $(TECS_CPP))" -g $(TECSGENDIR)
+
+#
+#  カーネルのコンフィギュレーションファイルの生成
+#
+cfg1_out.c cfg1_out.db: cfg1_out.timestamp ;
+cfg1_out.timestamp: $(APPL_CFG) $(TECSGEN_TIMESTAMP)
+	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) \
+						-M $(DEPDIR)/cfg1_out_c.d $(TARGET_KERNEL_CFG) $<
+
+$(CFG1_OUT): $(START_OBJS) cfg1_out.o $(CFG_DMY) $(END_OBJS) $(HIDDEN_OBJS)
+	$(LINK) $(CFLAGS) $(LDFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+						$(START_OBJS) cfg1_out.o $(CFG_DMY) $(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) cfg2_out.db: kernel_cfg.timestamp ;
+kernel_cfg.timestamp: cfg1_out.db cfg1_out.syms cfg1_out.srec
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) -T $(TARGET_TCPIP_TRB):tcpip -T $(TARGET_KERNEL_TRB):kernel
+
+#
+#  オフセットファイル（offset.h）の生成規則
+#
+$(OFFSET_H): offset.timestamp ;
+offset.timestamp: cfg1_out.db cfg1_out.syms cfg1_out.srec
+	$(CFG) --pass 2 -O --kernel asp $(INCLUDES) -T $(TARGET_OFFSET_TRB) \
+				--rom-symbol cfg1_out.syms --rom-image cfg1_out.srec
+
+#
+#  カーネルライブラリファイルの生成
+#
+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
+
+#
+#  特別な依存関係の定義
+#
+tBannerMain.o: $(filter-out tBannerMain.o,$(ALL_OBJS)) $(LIBS_DEP)
+
+#
+#  全体のリンク
+#
+$(OBJFILE): $(ALL_OBJS) $(LIBS_DEP)
+	$(LINK) $(CFLAGS) $(LDFLAGS) $(OBJ_LDFLAGS) -o $(OBJFILE) \
+			$(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+			$(ALL_LIBS) $(END_OBJS)
+
+#
+#  依存関係フォルダの作成
+#
+$(DEPDIR):
+	mkdir $@
+
+#
+#  シンボルファイルの生成
+#
+$(OBJNAME).syms: $(OBJFILE)
+	$(NM) -n $(OBJFILE) > $(OBJNAME).syms
+
+#
+#  バイナリファイルの生成
+#
+$(OBJNAME).bin: $(OBJFILE)
+	$(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+
+#
+#  Sレコードファイルの生成
+#
+$(OBJNAME).srec: $(OBJFILE)
+	$(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+#  エラーチェック処理
+#
+.PHONY: check
+check: check.timestamp ;
+check.timestamp: cfg2_out.db $(OBJNAME).syms $(OBJNAME).srec
+	$(CFG) --pass 3 --kernel asp -O $(INCLUDES) -T $(TARGET_CHECK_TRB) \
+				--rom-symbol $(OBJNAME).syms --rom-image $(OBJNAME).srec
+	@echo "configuration check passed"
+
+#
+#  コンパイル結果の消去
+#
+.PHONY: clean
+clean:
+	rm -f \#* *~ *.o $(DEPDIR)/*.d $(CLEAN_FILES) check.timestamp
+	rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+	rm -f kernel_cfg.timestamp $(CFG2_OUT_SRCS) cfg2_out.db
+	rm -f offset.timestamp $(OFFSET_H)
+	rm -f cfg1_out.syms cfg1_out.srec $(CFG1_OUT)
+	rm -f cfg1_out.timestamp cfg1_out.c cfg1_out.db
+	rm -rf $(TECSGENDIR)
+ifndef KERNEL_LIB
+	rm -f libkernel.a
+endif
+
+.PHONY: cleankernel
+cleankernel:
+	rm -f $(OFFSET_H) $(KERNEL_LIB_OBJS)
+	rm -f $(KERNEL_LIB_OBJS:%.o=$(DEPDIR)/%.d)
+
+.PHONY: realclean
+realclean: clean
+	rm -f $(REALCLEAN_FILES)
+
+#
+#  コンフィギュレータが生成したファイルのコンパイルルールの定義
+#
+#  コンフィギュレータが生成したファイルは，共通のコンパイルオプション
+#  のみを付けてコンパイルする．
+#
+ALL_CFG_COBJS = $(CFG_COBJS) cfg1_out.o
+ALL_CFG_ASMOBJS = $(CFG_ASMOBJS)
+
+$(ALL_CFG_COBJS): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(CFG_CFLAGS) $<
+
+$(ALL_CFG_ASMOBJS): %.o: %.S
+	$(CC) -c -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
+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): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+	$(CC) -DTOPPERS_$(*F) -o $@ -c -MD -MP -MF $(DEPDIR)/$*.d \
+									$(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+	$(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+	$(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+	$(CXX) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+	$(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+#  デフォルトコンパイルルールを上書き
+#
+%.o: %.c
+	@echo "*** Default compile rules should not be used."
+	$(CC) -c -MD -MP -MF $(DEPDIR)/$*.d $(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 -MD -MP -MF $(DEPDIR)/$*.d $(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 -MD -MP -MF $(DEPDIR)/$*.d $(CFLAGS) $<
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.c	(revision 398)
@@ -0,0 +1,561 @@
+/*
+ *  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-2016 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' : 対象タスクにras_terにより終了要求する．
+ *  'y' : 対象タスクにdis_terを呼び出させ，タスク終了を禁止する．
+ *  'Y' : 対象タスクにena_terを呼び出させ，タスク終了を許可する．
+ *  'r' : 3つの優先度（HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY）のレ
+ *        ディキューを回転させる．
+ *  'c' : 周期ハンドラを動作開始させる．
+ *  'C' : 周期ハンドラを動作停止させる．
+ *  'b' : アラームハンドラを5秒後に起動するよう動作開始させる．
+ *  'B' : アラームハンドラを動作停止させる．
+ *  'z' : 対象タスクにCPU例外を発生させる（タスクを終了させる）．
+ *  'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる（プログラムを
+ *        終了する）．
+ *  '@' : タスク3をacre_tskにより生成する．
+ *  '!' : 対象タスクをdel_tskにより削除する．
+ *  '$' : アラームハンドラをacre_almにより生成する．
+ *  '#' : アラームハンドラをdel_almにより削除する．
+ *  'V' : fch_hrtで高分解能タイマを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;		/* タスク内でのループ回数 */
+
+/*
+ *  並行実行されるタスク
+ */
+void task(intptr_t exinf)
+{
+	volatile ulong_t	i;
+	int_t		n = 0;
+	int_t		tskno = (int_t) exinf;
+	const char	*graph[] = { "|", "  +", "    *" };
+	char		c;
+
+	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(10000000)", tskno);
+			SVC_PERROR(tslp_tsk(10000000));
+			break;
+		case 'd':
+			syslog(LOG_INFO, "#%d#dly_tsk(10000000)", tskno);
+			SVC_PERROR(dly_tsk(10000000));
+			break;
+		case 'y':
+			syslog(LOG_INFO, "#%d#dis_ter()", tskno);
+			SVC_PERROR(dis_ter());
+			break;
+		case 'Y':
+			syslog(LOG_INFO, "#%d#ena_ter()", tskno);
+			SVC_PERROR(ena_ter());
+			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;
+		}
+	}
+}
+
+/*
+ *  割込みハンドラ
+ */
+#ifdef INTNO1
+
+void intno1_isr(intptr_t exinf)
+{
+	intno1_clear();
+	SVC_PERROR(rot_rdq(HIGH_PRIORITY));
+	SVC_PERROR(rot_rdq(MID_PRIORITY));
+	SVC_PERROR(rot_rdq(LOW_PRIORITY));
+}
+
+#endif /* INTNO1 */
+
+/*
+ *  CPU例外ハンドラ
+ */
+ID	cpuexc_tskid;		/* CPU例外を起こしたタスクのID */
+
+#ifdef CPUEXC1
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	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 xsns_dpn = %d",
+								sns_loc(), sns_dsp(), xsns_dpn(p_excinf));
+
+	if (xsns_dpn(p_excinf)) {
+		syslog(LOG_NOTICE, "Sample program ends with exception.");
+		SVC_PERROR(ext_ker());
+		assert(0);
+	}
+
+#ifdef PREPARE_RETURN_CPUEXC
+	PREPARE_RETURN_CPUEXC;
+	SVC_PERROR(get_tid(&cpuexc_tskid));
+	SVC_PERROR(act_tsk(EXC_TASK));
+#else /* PREPARE_RETURN_CPUEXC */
+	syslog(LOG_NOTICE, "Sample program ends with exception.");
+	SVC_PERROR(ext_ker());
+	assert(0);
+#endif /* PREPARE_RETURN_CPUEXC */
+}
+
+#endif /* CPUEXC1 */
+
+/*
+ *  周期ハンドラ
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
+ */
+void cyclic_handler(intptr_t exinf)
+{
+	SVC_PERROR(rot_rdq(HIGH_PRIORITY));
+	SVC_PERROR(rot_rdq(MID_PRIORITY));
+	SVC_PERROR(rot_rdq(LOW_PRIORITY));
+}
+
+/*
+ *  アラームハンドラ
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
+ */
+void alarm_handler(intptr_t exinf)
+{
+	SVC_PERROR(rot_rdq(HIGH_PRIORITY));
+	SVC_PERROR(rot_rdq(MID_PRIORITY));
+	SVC_PERROR(rot_rdq(LOW_PRIORITY));
+}
+
+/*
+ *  例外処理タスク
+ */
+void exc_task(intptr_t exinf)
+{
+	SVC_PERROR(ras_ter(cpuexc_tskid));
+}
+
+/*
+ *  メインタスク
+ */
+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 */
+	HRTCNT	hrtcnt1, hrtcnt2;
+	T_CTSK	ctsk;
+	ID		TASK3 = -1;
+	T_CALM	calm;
+	ID		ALMHDR1 = -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回目の測定結果
+	 * を使う．
+	 */
+#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 * 400LU / (ulong_t)(stime2 - stime1) * 1000LU;
+
+#endif /* TASK_LOOP */
+
+	/*
+ 	 *  タスクの起動
+	 */
+	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_ter(%d)", tskno);
+			SVC_PERROR(ras_ter(tskid));
+			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, 5000000)");
+			SVC_PERROR(sta_alm(ALMHDR1, 5000000));
+			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));
+			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 '$':
+			calm.almatr = TA_NULL;
+			calm.nfyinfo.nfymode = TNFY_HANDLER;
+			calm.nfyinfo.nfy.handler.exinf = (intptr_t) 0;
+			calm.nfyinfo.nfy.handler.tmehdr = (TMEHDR) alarm_handler;
+			SVC_PERROR(ALMHDR1 = acre_alm(&calm));
+			syslog(LOG_NOTICE, "alarm handler is created with almid = %d.",
+														(int_t) ALMHDR1);
+			break;
+		case '#':
+			syslog(LOG_INFO, "#del_alm(1)");
+			SVC_PERROR(del_alm(ALMHDR1));
+			break;
+
+		case 'V':
+			hrtcnt1 = fch_hrt();
+			hrtcnt2 = fch_hrt();
+			syslog(LOG_NOTICE, "hrtcnt1 = %tu, hrtcnt2 = %tu",
+										hrtcnt1, hrtcnt2);
+			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_mbedtls/trunk/asp3_dcre/sample/sample1.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.cdl	(revision 398)
@@ -0,0 +1,122 @@
+/*
+ *		サンプルプログラム(1)のコンポーネント記述ファイル
+ *
+ *  $Id$
+ */
+/*
+ *  カーネルオブジェクトの定義
+ */
+import(<kernel.cdl>);
+
+/*
+ *  ターゲット非依存のセルタイプの定義
+ */
+import("syssvc/tSerialPort.cdl");
+import("syssvc/tSerialAdapter.cdl");
+import("syssvc/tSysLog.cdl");
+import("syssvc/tSysLogAdapter.cdl");
+import("syssvc/tLogTask.cdl");
+import("syssvc/tBanner.cdl");
+
+/*
+ *  ターゲット依存部の取り込み
+ */
+import("target.cdl");
+
+/*
+ *  「セルの組上げ記述」とは，"cell"で始まる行から，それに対応する"};"
+ *  の行までのことを言う．
+ */
+
+/*
+ *  システムログ機能の組上げ記述
+ *
+ *  システムログ機能を外す場合には，以下のセルの組上げ記述を削除し，コ
+ *  ンパイルオプションに-DTOPPERS_OMIT_SYSLOGを追加すればよい．ただし，
+ *  システムログタスクはシステムログ機能を使用するため，それも外すこと
+ *  が必要である．また，システムログ機能のアダプタも外さなければならな
+ *  い．tecsgenが警告メッセージを出すが，無視してよい．
+ */
+cell tSysLog SysLog {
+	logBufferSize = 32;					/* ログバッファのサイズ */
+	initLogMask = C_EXP("LOG_UPTO(LOG_NOTICE)");
+										/* ログバッファに記録すべき重要度 */
+	initLowMask = C_EXP("LOG_UPTO(LOG_EMERG)");
+									   	/* 低レベル出力すべき重要度 */
+	/* 低レベル出力との結合 */
+	cPutLog = PutLogTarget.ePutLog;
+};
+
+/*
+ *  C言語で記述されたアプリケーションから，TECSベースのシステムログ機能
+ *  を呼び出すためのアダプタの組上げ記述
+ *
+ *  システムログ機能のサービスコール（syslog関数とsyslog_0関数～syslog_5
+ *  関数以外のもの）ルをC言語で記述されたアプリケーションから呼び出さな
+ *  い場合には，以下のセルの組上げ記述を削除すればよい．
+ */
+cell tSysLogAdapter SysLogAdapter {
+	cSysLog = SysLog.eSysLog;
+};
+
+/*
+ *  シリアルインタフェースドライバの組上げ記述
+ *
+ *  シリアルインタフェースドライバを外す場合には，以下のセルの組上げ記
+ *  述を削除すればよい．ただし，システムログタスクはシリアルインタフェー
+ *  スドライバを使用するため，それも外すことが必要である．また，シリア
+ *  ルインタフェースドライバのアダプタも外さなければならない．
+ */
+cell tSerialPort SerialPort1 {
+	receiveBufferSize = 256;			/* 受信バッファのサイズ */
+	sendBufferSize    = 256;			/* 送信バッファのサイズ */
+
+	/* ターゲット依存部との結合 */
+	cSIOPort = SIOPortTarget1.eSIOPort;
+	eiSIOCBR <= SIOPortTarget1.ciSIOCBR;	/* コールバック */
+};
+
+/*
+ *  C言語で記述されたアプリケーションから，TECSベースのシリアルインタ
+ *  フェースドライバを呼び出すためのアダプタの組上げ記述
+ *
+ *  シリアルインタフェースドライバのサービスコールをC言語で記述されたア
+ *  プリケーションから呼び出さない場合には，以下のセルの組上げ記述を削
+ *  除すればよい．
+ */
+cell tSerialAdapter SerialAdapter {
+	cSerialPort[0] = SerialPort1.eSerialPort;
+};
+
+/*
+ *  システムログタスクの組上げ記述
+ *
+ *  システムログタスクを外す場合には，以下のセルの組上げ記述を削除すれ
+ *  ばよい．
+ */
+cell tLogTask LogTask {
+	priority  = 3;					/* システムログタスクの優先度 */
+	stackSize = LogTaskStackSize;	/* システムログタスクのスタックサイズ */
+
+	/* シリアルインタフェースドライバとの結合 */
+	cSerialPort        = SerialPort1.eSerialPort;
+	cnSerialPortManage = SerialPort1.enSerialPortManage;
+
+	/* システムログ機能との結合 */
+	cSysLog = SysLog.eSysLog;
+
+	/* 低レベル出力との結合 */
+	cPutLog = PutLogTarget.ePutLog;
+};
+
+/*
+ *  カーネル起動メッセージ出力の組上げ記述
+ *
+ *  カーネル起動メッセージの出力を外す場合には，以下のセルの組上げ記述
+ *  を削除すればよい．
+ */
+cell tBanner Banner {
+	/* 属性の設定 */
+	targetName      = BannerTargetName;
+	copyrightNotice = BannerCopyrightNotice;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.cfg	(revision 398)
@@ -0,0 +1,23 @@
+/*
+ *		サンプルプログラム(1)のシステムコンフィギュレーションファイル
+ *
+ *  $Id$
+ */
+INCLUDE("tecsgen.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 });
+CRE_TSK(EXC_TASK, { TA_NULL, 0, exc_task, EXC_PRIORITY, STACK_SIZE, NULL });
+AID_TSK(3);
+CRE_CYC(CYCHDR1, { TA_NULL, { TNFY_HANDLER, 0, cyclic_handler }, 2000000, 0 });
+AID_ALM(1);
+#ifdef INTNO1
+CFG_INT(INTNO1, { INTNO1_INTATR, INTNO1_INTPRI });
+CRE_ISR(INTNO1_ISR, { TA_NULL, 0, INTNO1, intno1_isr, 1 });
+#endif /* INTNO1 */
+#ifdef CPUEXC1
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
+#endif /* CPUEXC1 */
+DEF_KMM({ KMM_SIZE, NULL });
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/sample1.h	(revision 398)
@@ -0,0 +1,103 @@
+/*
+ *  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-2016 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 <kernel.h>
+
+/*
+ *  ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define EXC_PRIORITY	1		/* 例外処理タスクの優先度 */
+#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 exc_task(intptr_t exinf);
+#ifdef INTNO1
+extern void intno1_isr(intptr_t exinf);
+#endif /* INTNO1 */
+#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_mbedtls/trunk/asp3_dcre/sample/tSample2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.c	(revision 398)
@@ -0,0 +1,643 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ *
+ *  Copyright (C) 2015-2016 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015-2016 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' : 対象タスクをcTask_activateにより起動する．
+ *  'A' : 対象タスクに対する起動要求をcTask_cancelActivateによりキャンセルする．
+ *  'e' : 対象タスクにexitTaskを呼び出させ，終了させる．
+ *  't' : 対象タスクをcTask_terminateにより強制終了する．
+ *  '>' : 対象タスクの優先度をHIGH_PRIORITYにする．
+ *  '=' : 対象タスクの優先度をMID_PRIORITYにする．
+ *  '<' : 対象タスクの優先度をLOW_PRIORITYにする．
+ *  'G' : 対象タスクの優先度をcTask_getPriorityで読み出す．
+ *  's' : 対象タスクにsleepを呼び出させ，起床待ちにさせる．
+ *  'S' : 対象タスクにsleepTimeout10秒)を呼び出させ，起床待ちにさせる．
+ *  'w' : 対象タスクをcTask_wakeupにより起床する．
+ *  'W' : 対象タスクに対する起床要求をcTask_cancelWakeupによりキャンセルする．
+ *  'l' : 対象タスクをcTask_releaseWaitにより強制的に待ち解除にする．
+ *  'u' : 対象タスクをcTask_suspendにより強制待ち状態にする．
+ *  'm' : 対象タスクの強制待ち状態をcTask_resumeにより解除する．
+ *  'd' : 対象タスクにdelay(10秒)を呼び出させ，時間経過待ちにさせる．
+ *  'x' : 対象タスクにraiseTerminateにより終了要求する．
+ *  'y' : 対象タスクにdisableTerminateを呼び出させ，タスク終了を禁止する．
+ *  'Y' : 対象タスクにenableTerminateを呼び出させ，タスク終了を許可する．
+ *  'r' : 3つの優先度（HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY）のレ
+ *        ディキューを回転させる．
+ *  'c' : 周期ハンドラを動作開始させる．
+ *  'C' : 周期ハンドラを動作停止させる．
+ *  'b' : アラームハンドラを5秒後に起動するよう動作開始させる．
+ *  'B' : アラームハンドラを動作停止させる．
+ *  'z' : 対象タスクにCPU例外を発生させる（タスクを終了させる）．
+ *  'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる（プログラムを
+ *        終了する）．
+ *  'V' : fetchHighResolutionTimerで高分解能タイマを2回読む．
+ *  'v' : 発行したシステムコールを表示する（デフォルト）．
+ *  'q' : 発行したシステムコールを表示しない．
+ * 呼び口関数 #_TCPF_#
+ * require port: signature:sKernel context:task
+ *   ER             getExtendedInformation( intptr_t* p_exinf );
+ *   ER             sleep( );
+ *   ER             sleepTimeout( TMO timeout );
+ *   ER             delay( RELTIM delayTime );
+ *   ER             exit( );
+ *   ER             disableTerminate( );
+ *   ER             enableTerminate( );
+ *   bool_t         senseTerminate( );
+ *   ER             setTime( SYSTIM systemTime );
+ *   ER             getTime( SYSTIM* p_systemTime );
+ *   ER             adjustTime( int32_t adjustTime );
+ *   HRTCNT         fetchHighResolutionTimer( );
+ *   ER             rotateReadyQueue( PRI taskPriority );
+ *   ER             getTaskId( ID* p_taskId );
+ *   ER             getLoad( PRI taskPriority, uint_t* p_load );
+ *   ER             getNthTask( PRI taskPriority, uint_t nth, ID* p_taskID );
+ *   ER             lockCpu( );
+ *   ER             unlockCpu( );
+ *   ER             disableDispatch( );
+ *   ER             enableDispatch( );
+ *   bool_t         senseContext( );
+ *   bool_t         senseLock( );
+ *   bool_t         senseDispatch( );
+ *   bool_t         senseDispatchPendingState( );
+ *   bool_t         senseKernel( );
+ *   ER             exitKernel( );
+ *   ER             changeInterruptPriorityMask( PRI interruptPriority );
+ *   ER             getInterruptPriorityMask( PRI* p_interruptPriority );
+ * require port: signature:siKernel context:non-task
+ *   HRTCNT         ciKernel_fetchHighResolutionTimer( );
+ *   ER             ciKernel_rotateReadyQueue( PRI taskPriority );
+ *   ER             ciKernel_getTaskId( ID* p_taskId );
+ *   ER             ciKernel_lockCpu( );
+ *   ER             ciKernel_unlockCpu( );
+ *   bool_t         ciKernel_senseContext( );
+ *   bool_t         ciKernel_senseLock( );
+ *   bool_t         ciKernel_senseDispatch( );
+ *   bool_t         ciKernel_senseDispatchPendingState( );
+ *   bool_t         ciKernel_senseKernel( );
+ *   ER             ciKernel_exitKernel( );
+ *   bool_t         ciKernel_exceptionSenseDispatchPendingState( const void* p_exceptionInformation );
+ * call port: cTask signature: sTask context:task
+ *   ER             cTask_activate( subscript );
+ *   ER_UINT        cTask_cancelActivate( subscript );
+ *   ER             cTask_getTaskState( subscript, STAT* p_tskstat );
+ *   ER             cTask_changePriority( subscript, PRI priority );
+ *   ER             cTask_getPriority( subscript, PRI* p_priority );
+ *   ER             cTask_refer( subscript, T_RTSK* pk_taskStatus );
+ *   ER             cTask_wakeup( subscript );
+ *   ER_UINT        cTask_cancelWakeup( subscript );
+ *   ER             cTask_releaseWait( subscript );
+ *   ER             cTask_suspend( subscript );
+ *   ER             cTask_resume( subscript );
+ *   ER             cTask_raiseTerminate( subscript );
+ *   ER             cTask_terminate( subscript );
+ *       subscript:  0...(NCP_cTask-1)
+ * call port: cExceptionTask signature: sTask context:task
+ *   ER             cExceptionTask_activate( );
+ *   ER_UINT        cExceptionTask_cancelActivate( );
+ *   ER             cExceptionTask_getTaskState( STAT* p_tskstat );
+ *   ER             cExceptionTask_changePriority( PRI priority );
+ *   ER             cExceptionTask_getPriority( PRI* p_priority );
+ *   ER             cExceptionTask_refer( T_RTSK* pk_taskStatus );
+ *   ER             cExceptionTask_wakeup( );
+ *   ER_UINT        cExceptionTask_cancelWakeup( );
+ *   ER             cExceptionTask_releaseWait( );
+ *   ER             cExceptionTask_suspend( );
+ *   ER             cExceptionTask_resume( );
+ *   ER             cExceptionTask_raiseTerminate( );
+ *   ER             cExceptionTask_terminate( );
+ * call port: cCyclic signature: sCyclic context:task
+ *   ER             cCyclic_start( );
+ *   ER             cCyclic_stop( );
+ *   ER             cCyclic_refer( T_RCYC* pk_cyclicHandlerStatus );
+ * call port: cAlarm signature: sAlarm context:task
+ *   ER             cAlarm_start( RELTIM alarmTime );
+ *   ER             cAlarm_stop( );
+ *   ER             cAlarm_refer( T_RALM* pk_alarmStatus );
+ * call port: cSerialPort signature: sSerialPort context:task optional:true
+ *   bool_t     is_cSerialPort_joined()                     check if joined
+ *   ER             cSerialPort_open( );
+ *   ER             cSerialPort_close( );
+ *   ER_UINT        cSerialPort_read( char* buffer, uint_t length );
+ *   ER_UINT        cSerialPort_write( const char* buffer, uint_t length );
+ *   ER             cSerialPort_control( uint_t ioControl );
+ *   ER             cSerialPort_refer( T_SERIAL_RPOR* pk_rpor );
+ * call port: cSysLog signature: sSysLog context:task
+ *   ER             cSysLog_write( uint_t priority, const SYSLOG* p_syslog );
+ *   ER_UINT        cSysLog_read( SYSLOG* p_syslog );
+ *   ER             cSysLog_mask( uint_t logMask, uint_t lowMask );
+ *   ER             cSysLog_refer( T_SYSLOG_RLOG* pk_rlog );
+ *   ER             cSysLog_flush( );
+ * #[</PREAMBLE>]# */  
+
+#include "tSample2_tecsgen.h"
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "kernel_cfg.h"
+#include "tSample2.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;		/* タスク内でのループ回数 */
+
+/*
+ *  並行実行されるタスク
+ */
+void eSampleTask_main(int_t subscript)
+{
+	volatile ulong_t	i;
+	int_t		n = 0;
+	int_t		tskno = subscript + 1; 
+	const char	*graph[] = { "|", "  +", "    *" };
+	char		c;
+
+	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#exit()", tskno);
+			SVC_PERROR(exit());
+			assert(0);
+		case 's':
+			syslog(LOG_INFO, "#%d#sleep()", tskno);
+			SVC_PERROR(sleep());
+			break;
+		case 'S':
+			syslog(LOG_INFO, "#%d#sleepTimeout(10000)", tskno);
+			SVC_PERROR(sleepTimeout(10000));
+			break;
+		case 'd':
+			syslog(LOG_INFO, "#%d#delay(10000)", tskno);
+			SVC_PERROR(delay(10000));
+			break;
+		case 'y':
+			syslog(LOG_INFO, "#%d#disableTerminate()", tskno);
+			SVC_PERROR(disableTerminate());
+			break;
+		case 'Y':
+			syslog(LOG_INFO, "#%d#enableTerminate()", tskno);
+			SVC_PERROR(enableTerminate());
+			break;
+#ifdef CPUEXC1
+		case 'z':
+			syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+			RAISE_CPU_EXCEPTION;
+			break;
+		case 'Z':
+			SVC_PERROR(lockCpu());
+			syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+			RAISE_CPU_EXCEPTION;
+			SVC_PERROR(unlockCpu());
+			break;
+#endif /* CPUEXC1 */
+		default:
+			break;
+		}
+	}
+}
+
+/*
+ *  CPU例外ハンドラ
+ */
+
+ID	cpuexc_tskid;		/* CPU例外を起こしたタスクのID */
+
+#ifdef CPUEXC1
+
+void
+cpuexc_handler(void *p_excinf)
+{
+	
+	syslog(LOG_NOTICE, "CPU exception handler (p_excinf = %08p).", p_excinf);
+	if (ciKernel_senseContext() != true) {
+		syslog(LOG_WARNING,
+					"ciKernel_senseContext() is not true in CPU exception handler.");
+	}
+	if (ciKernel_senseDispatchPendingState() != true) {
+		syslog(LOG_WARNING,
+					"ciKernel_senseDispatchPendingState() is not true in CPU exception handler.");
+	}
+	syslog(LOG_INFO, "ciKernel_senseLock() = %d ciKernel_senseDispatch() = %d ciKernel_exceptionSenseDispatchPendingState() = %d",
+		   ciKernel_senseLock(), ciKernel_senseDispatch(), ciKernel_exceptionSenseDispatchPendingState(p_excinf));
+
+	if (ciKernel_exceptionSenseDispatchPendingState(p_excinf)) {
+		syslog(LOG_NOTICE, "Sample program ends with exception.");
+		SVC_PERROR(ciKernel_senseKernel());
+		assert(0);
+	}
+
+#ifdef PREPARE_RETURN_CPUEXC
+	PREPARE_RETURN_CPUEXC;
+	SVC_PERROR(ciKernel_getTaskId(&cpuexc_tskid));
+	cExceptionTask_activate();
+#else /* PREPARE_RETURN_CPUEXC */
+	syslog(LOG_NOTICE, "Sample program ends with exception.");
+	SVC_PERROR(ciKernel_exitKernel());
+	assert(0);
+#endif /* PREPARE_RETURN_CPUEXC */
+}
+
+#endif /* CPUEXC1 */
+
+/*
+ *  周期ハンドラ
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
+ */
+/* #[<ENTRY_FUNC>]# eiCyclicHandler_main
+ * name:         eiCyclicHandler_main
+ * global_name:  tSample2_eiCyclicHandler_main
+ * oneway:       
+ * #[/ENTRY_FUNC>]# */
+void
+eiCyclicHandler_main()
+{
+	SVC_PERROR(ciKernel_rotateReadyQueue(HIGH_PRIORITY));
+	SVC_PERROR(ciKernel_rotateReadyQueue(MID_PRIORITY));
+	SVC_PERROR(ciKernel_rotateReadyQueue(LOW_PRIORITY));
+}
+
+/*
+ *  アラームハンドラ
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
+ */
+/* #[<ENTRY_FUNC>]# eiAlarmHandler_main
+ * name:         eiAlarmHandler_main
+ * global_name:  tSample2_eiAlarmHandler_main
+ * oneway:       
+ * #[/ENTRY_FUNC>]# */
+void
+eiAlarmHandler_main()
+{
+	SVC_PERROR(ciKernel_rotateReadyQueue(HIGH_PRIORITY));
+	SVC_PERROR(ciKernel_rotateReadyQueue(MID_PRIORITY));
+	SVC_PERROR(ciKernel_rotateReadyQueue(LOW_PRIORITY));
+}
+/*
+ *  例外処理タスク
+ */
+/* #[<ENTRY_FUNC>]# eExceptionTask_main
+ * name:         eExceptionTask_main
+ * global_name:  tSample2_eExceptionTask_main
+ * oneway:       
+ * #[/ENTRY_FUNC>]# */
+void eExceptionTask_main()
+{
+	SVC_PERROR(ras_ter(cpuexc_tskid));
+}
+/*
+ *  メインタスク
+ */
+/* 属性の設定 *//* #[<ENTRY_FUNC>]# eMainTask_main
+ * name:         eMainTask_main
+ * global_name:  tSample2_eMainTask_main
+ * oneway:       
+ * #[/ENTRY_FUNC>]# */
+void
+eMainTask_main()
+{
+	char	c;
+	volatile ulong_t	i;
+	ulong_t j;
+	int_t	tskno = 1;
+	ER_UINT	ercd;
+	PRI		tskpri;
+	SYSTIM	stime1, stime2;
+	HRTCNT	hrtcnt1, hrtcnt2;
+
+	if (is_cSerialPort_joined()) {
+		SVC_PERROR(cSysLog_mask(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_ERROR)));
+	} else {
+		/*
+		 *  シリアル出力ができない場合、ログメッセージを全て
+		 *  低レベル出力により出力する。
+		 */
+		SVC_PERROR(cSysLog_mask(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_DEBUG)));
+	}
+	syslog(LOG_NOTICE, "Sample program starts.");
+
+	/*
+	 *  シリアルポートの初期化
+	 *
+	 *  システムログタスクと同じシリアルポートを使う場合など，シリアル
+	 *  ポートがオープン済みの場合にはここでE_OBJエラーになるが，支障は
+	 *  ない．
+	 */
+
+	if (is_cSerialPort_joined()) {
+		ercd = cSerialPort_open();
+		if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+			syslog(LOG_ERROR, "%s (%d) reported by `cSerialPort_open'.",
+										itron_strerror(ercd), SERCD(ercd));
+		}
+		SVC_PERROR(cSerialPort_control(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回目の測定結果
+	 * を使う．
+	 */
+#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 * 400LU / (ulong_t)(stime2 - stime1) * 1000LU;
+
+#endif /* TASK_LOOP */
+
+	/*
+ 	 *  タスクの起動
+	 */
+
+	SVC_PERROR(cTask_activate( 1 ));
+	SVC_PERROR(cTask_activate( 2 ));
+	SVC_PERROR(cTask_activate( 3 ));
+
+	/*
+ 	 *  メインループ
+	 */
+	if (is_cSerialPort_joined()) {
+		do {
+			SVC_PERROR(cSerialPort_read(&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;
+				break;
+			case '2':
+				tskno = 2;
+				break;
+			case '3':
+				tskno = 3;
+				break;
+			case 'a':
+				syslog(LOG_INFO, "#cTask_activate(%d)", tskno);
+				SVC_PERROR(cTask_activate(tskno));
+				break;
+			case 'A':
+				syslog(LOG_INFO, "#cTask_cancelActivate(%d)", tskno);
+				SVC_PERROR(cTask_cancelActivate(tskno));
+
+				if (ercd >= 0) {
+					syslog(LOG_NOTICE, "cTask_cancelActivate(%d) returns %d", tskno, ercd);
+				}
+				break;
+			case 't':
+				syslog(LOG_INFO, "#cTask_terminate(%d)", tskno);
+				SVC_PERROR(cTask_terminate(tskno));
+				break;
+			case '>':
+				syslog(LOG_INFO, "#cTask_changePriority(%d, HIGH_PRIORITY)", tskno);
+				SVC_PERROR(cTask_changePriority(tskno, HIGH_PRIORITY));
+				break;
+			case '=':
+				syslog(LOG_INFO, "#cTask_changePriority(%d, MID_PRIORITY)", tskno);
+				SVC_PERROR(cTask_changePriority(tskno, MID_PRIORITY));
+				break;
+			case '<':
+				syslog(LOG_INFO, "#(cTask_changePriority(%d, LOW_PRIORITY)", tskno);
+				SVC_PERROR(cTask_changePriority(tskno, LOW_PRIORITY));
+				break;
+			case 'G':
+				syslog(LOG_INFO, "#cTask_getPriority(%d, &tskpri)", tskno);
+				SVC_PERROR(ercd = cTask_getPriority(tskno, &tskpri));
+				if (ercd >= 0) {
+					syslog(LOG_NOTICE, "priority of task %d is %d", tskno, tskpri);
+				}
+				break;
+			case 'w':
+				syslog(LOG_INFO, "#cTask_wakeup(%d)", tskno);
+				SVC_PERROR(cTask_wakeup(tskno));
+				break;
+			case 'W':
+				syslog(LOG_INFO, "#cTask_cancelWakeup(%d)", tskno);
+				SVC_PERROR(ercd = cTask_cancelWakeup(tskno));
+				if (ercd >= 0) {
+					syslog(LOG_NOTICE, "cTask_cancelWakeup(%d) returns %d", tskno, ercd);
+				}
+				break;
+			case 'l':
+				syslog(LOG_INFO, "#cTask_releaseWait(%d)", tskno);
+				SVC_PERROR(cTask_releaseWait(tskno));
+				break;
+			case 'u':
+				syslog(LOG_INFO, "#cTask_suspend(%d)", tskno);
+				SVC_PERROR(cTask_suspend(tskno));
+				break;
+			case 'm':
+				syslog(LOG_INFO, "#cTask_resume(%d)", tskno);
+				SVC_PERROR(cTask_resume(tskno));
+				break;
+			case 'x':
+				syslog(LOG_INFO, "#cTask_raiseTerminate(%d)", tskno);
+				SVC_PERROR(cTask_raiseTerminate(tskno));
+				break;
+			case 'X':
+				syslog(LOG_INFO, "#cTask_raiseTerminate(%d)", tskno);
+				SVC_PERROR(cTask_raiseTerminate(tskno));
+				break;
+			case 'r':
+				syslog(LOG_INFO, "#rotateReadyQueue(three priorities)");
+				SVC_PERROR(rotateReadyQueue(HIGH_PRIORITY));
+				SVC_PERROR(rotateReadyQueue(MID_PRIORITY));
+				SVC_PERROR(rotateReadyQueue(LOW_PRIORITY));
+				break;
+			case 'c':
+				syslog(LOG_INFO, "#cCyclic_start(1)");
+				SVC_PERROR(cCyclic_start());
+				break;
+			case 'C':
+				syslog(LOG_INFO, "#cCyclic_stop(1)");
+				SVC_PERROR(cCyclic_stop());
+				break;
+			case 'b':
+				syslog(LOG_INFO, "#cAlarm_start(1, 5000000)");
+				SVC_PERROR(cAlarm_start(5000000));
+				break;
+			case 'B':
+				syslog(LOG_INFO, "#cAlarm_stop()(1)");
+				SVC_PERROR(cAlarm_stop());
+				break;
+			case 'V':
+				hrtcnt1 = fetchHighResolutionTimer();
+				hrtcnt2 = fetchHighResolutionTimer();
+				syslog(LOG_NOTICE, "hrtcnt1 = %tu, hrtcnt2 = %tu",
+											hrtcnt1, hrtcnt2);
+				break;
+			case 'v':
+				SVC_PERROR(cSysLog_mask(LOG_UPTO(LOG_INFO),
+											LOG_UPTO(LOG_EMERG)));
+				break;
+			case 'q':
+				SVC_PERROR(cSysLog_mask(LOG_UPTO(LOG_NOTICE),
+											LOG_UPTO(LOG_EMERG)));
+				break;
+#ifdef BIT_KERNEL
+			case ' ':
+				SVC_PERROR(lockCpu());
+				{
+					extern ER	bit_kernel(void);
+
+					SVC_PERROR(ercd = bit_kernel());
+					if (ercd >= 0) {
+						syslog(LOG_NOTICE, "bit_kernel passed.");
+					}
+				}
+				SVC_PERROR(unlockCpu());
+				break;
+#endif /* BIT_KERNEL */
+
+			default:
+				break;
+			}
+		} while (c != '\003' && c != 'Q');
+	} else {
+		syslog(LOG_NOTICE, "cSerialPort of tSample2 is not joined.");
+		syslog(LOG_NOTICE, "Sample program will halt after 40 seconds.");
+		for (j = 0; j < 100; j++) {
+			for (i = 0; i < task_loop; i++);
+		}
+	}
+
+	syslog(LOG_NOTICE, "Sample program ends.");
+	SVC_PERROR(ciKernel_exitKernel());
+	assert(0);
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.cdl	(revision 398)
@@ -0,0 +1,200 @@
+/*
+ *		サンプルプログラム(2)のコンポーネント記述ファイル
+ *
+ *  $Id$
+ */
+/*
+ *  カーネルオブジェクトの定義
+ */
+import("kernel.cdl");
+
+/*
+ *  ターゲット非依存のセルタイプの定義
+ */
+import("syssvc/tSerialPort.cdl");
+import("syssvc/tSysLog.cdl");
+import("syssvc/tLogTask.cdl");
+import("syssvc/tBanner.cdl");
+
+/*
+ *  ターゲット依存部の取り込み
+ */
+import("target.cdl");
+
+/*
+ *  「セルの組上げ記述」とは，"cell"で始まる行から，それに対応する"};"
+ *  の行までのことを言う．
+ */
+
+/*
+ *  システムログ機能の組上げ記述
+ *
+ *  システムログ機能を外す場合には，以下のセルの組上げ記述を削除し，コ
+ *  ンパイルオプションに-DTOPPERS_OMIT_SYSLOGを追加すればよい．ただし，
+ *  システムログタスクはシステムログ機能を使用するため，それも外すこと
+ *  が必要である．また，システムログ機能のアダプタも外さなければならな
+ *  い．tecsgenが警告メッセージを出すが，無視してよい．
+ */
+cell tSysLog SysLog {
+	logBufferSize = 32;					/* ログバッファのサイズ */
+	initLogMask = C_EXP("LOG_UPTO(LOG_NOTICE)");
+										/* ログバッファに記録すべき重要度 */
+	initLowMask = C_EXP("LOG_UPTO(LOG_EMERG)");
+									   	/* 低レベル出力すべき重要度 */
+
+	/* 低レベル出力との結合 */
+	cPutLog = PutLogTarget.ePutLog;
+};
+
+/*
+ *  シリアルインタフェースドライバの組上げ記述
+ *
+ *  シリアルインタフェースドライバを外す場合には，以下のセルの組上げ記
+ *  述を削除すればよい．ただし，システムログタスクはシリアルインタフェー
+ *  スドライバを使用するため，それも外すことが必要である．また，シリア
+ *  ルインタフェースドライバのアダプタも外さなければならない．
+ */
+cell tSerialPort SerialPort1 {
+	receiveBufferSize = 256;			/* 受信バッファのサイズ */
+	sendBufferSize    = 256;			/* 送信バッファのサイズ */
+
+	/* ターゲット依存部との結合 */
+	cSIOPort = SIOPortTarget1.eSIOPort;
+	eiSIOCBR <= SIOPortTarget1.ciSIOCBR;	/* コールバック */
+};
+
+/*
+ *  システムログタスクの組上げ記述
+ *
+ *  システムログタスクを外す場合には，以下のセルの組上げ記述を削除すれ
+ *  ばよい．
+ */
+cell tLogTask LogTask {
+	priority  = 3;					/* システムログタスクの優先度 */
+	stackSize = LogTaskStackSize;	/* システムログタスクのスタックサイズ */
+
+	/* シリアルインタフェースドライバとの結合 */
+	cSerialPort        = SerialPort1.eSerialPort;
+	cnSerialPortManage = SerialPort1.enSerialPortManage;
+
+	/* システムログ機能との結合 */
+	cSysLog = SysLog.eSysLog;
+
+	/* 低レベル出力との結合 */
+	cPutLog = PutLogTarget.ePutLog;
+};
+
+/*
+ *  カーネル起動メッセージ出力の組上げ記述
+ *
+ *  カーネル起動メッセージの出力を外す場合には，以下のセルの組上げ記述
+ *  を削除すればよい．
+ */
+cell tBanner Banner {
+	/* 属性の設定 */
+	targetName      = BannerTargetName;
+	copyrightNotice = BannerCopyrightNotice;
+};
+
+/*
+ *  サンプルプログラムの定義
+ */
+[singleton]
+celltype tSample2 {
+	require tKernel.eKernel;			/* 呼び口名なし（例：delay）*/
+	/*require cKernel = tKernel.eKernel;/* 呼び口名あり（例：cKernel_delay）*/
+	require ciKernel = tKernel.eiKernel;/* 呼び口名あり（例：ciKernel_）*/
+
+	call sTask		    cTask[4];		/* タスク操作 */
+	call sTask 			cExceptionTask;
+	call sCyclic        cCyclic;
+	call sAlarm         cAlarm;
+
+	[optional] call sSerialPort	cSerialPort;/* シリアルドライバとの接続 */
+	call sSysLog		cSysLog;		/* システムログ機能との接続 */
+	
+	entry sTaskBody		eMainTask;	  	/* Mainタスク */
+	entry sTaskBody		eSampleTask[3];	/* 並行実行されるタスク */
+	entry sTaskBody		eExceptionTask;	/* 例外処理タスク */
+	
+	entry siHandlerBody eiCyclicHandler;/* 周期ハンドラ*/
+	entry siHandlerBody eiAlarmHandler; /* アラームハンドラ */
+};
+
+/*
+ *  組み上げ記述
+ */
+
+/* Sample2のプロトタイプ宣言 */
+cell tSample2 Sample2;
+
+cell tKernel ASPKernel{
+};
+
+cell tTask MainTask {
+	/* 呼び口の結合 */
+	cTaskBody = Sample2.eMainTask;
+	/* 属性の設定 */
+	attribute = C_EXP("TA_ACT");
+	priority = C_EXP("MAIN_PRIORITY");
+	stackSize = C_EXP("STACK_SIZE");
+};
+
+cell tTask Task1 {
+	/* 呼び口の結合 */
+	cTaskBody = Sample2.eSampleTask[0];
+	  /* 属性の設定 */
+	priority = C_EXP("MID_PRIORITY");
+	stackSize = C_EXP("STACK_SIZE");
+};
+
+cell tTask Task2 {
+	/* 呼び口の結合 */
+	cTaskBody = Sample2.eSampleTask[1];
+	/* 属性の設定 */
+	priority = C_EXP("MID_PRIORITY");
+	stackSize = C_EXP("STACK_SIZE");
+};
+
+cell tTask Task3 {
+	/* 呼び口の結合 */
+	cTaskBody = Sample2.eSampleTask[2];
+	/* 属性の設定 */
+	priority = C_EXP("MID_PRIORITY");
+	stackSize = C_EXP("STACK_SIZE");
+};
+
+cell tTask ExceptionTask {
+	/* 呼び口の結合 */
+	cTaskBody = Sample2.eExceptionTask;
+	/* 属性の設定 */
+	priority = C_EXP("EXC_PRIORITY");
+	stackSize = C_EXP("STACK_SIZE");
+};
+
+cell tCyclicHandler CyclicHandler {
+	/* 呼び口の結合 */
+	ciHandlerBody = Sample2.eiCyclicHandler;
+	/* 属性の設定 */
+	cycleTime = 2000000;
+};
+
+cell tAlarmHandler AlarmHandler {
+	ciHandlerBody = Sample2.eiAlarmHandler;
+};
+
+cell tSample2 Sample2 {
+	/* 呼び口の結合 */
+	cTask[ 0 ] = MainTask.eTask;
+	cTask[ 1 ] = Task1.eTask;
+	cTask[ 2 ] = Task2.eTask;
+	cTask[ 3 ] = Task3.eTask;
+
+	cExceptionTask = ExceptionTask.eTask;
+
+	cCyclic = CyclicHandler.eCyclic;
+	cAlarm  = AlarmHandler.eAlarm;
+
+	cSerialPort = SerialPort1.eSerialPort;
+	cSysLog = SysLog.eSysLog;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.cfg	(revision 398)
@@ -0,0 +1,12 @@
+/*
+ *		サンプルプログラム(2)のシステムコンフィギュレーションファイル
+ *
+ *  $Id$
+ */
+INCLUDE("gen/tecsgen.cfg");
+
+#include "tSample2.h"
+
+#ifdef CPUEXC1
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
+#endif /* CPUEXC1 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/sample/tSample2.h	(revision 398)
@@ -0,0 +1,87 @@
+/*
+ *  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-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 EXC_PRIORITY	1		/* 例外処理タスクの優先度 */
+#define MAIN_PRIORITY	5		/* メインタスクの優先度 */
+								/* HIGH_PRIORITYより高くすること */
+
+#define HIGH_PRIORITY	9		/* 並列に実行されるタスクの優先度 */
+#define MID_PRIORITY	10
+#define LOW_PRIORITY	11
+
+/*
+ *  ターゲットに依存する可能性のある定数の定義
+ */
+
+#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	cyclic_handler(intptr_t exinf);
+extern void	alarm_handler(intptr_t exinf);
+extern void	cpuexc_handler(void *p_excinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/histogram.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/histogram.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/histogram.h	(revision 398)
@@ -0,0 +1,77 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2016 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
+
+#include <t_stddef.h>
+
+/*
+ *  実行時間分布計測の初期化
+ */
+extern void	init_hist(ID histid);
+
+/*
+ *  実行時間計測の開始
+ */
+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_mbedtls/trunk/asp3_dcre/syssvc/musl_adapter.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/musl_adapter.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/musl_adapter.c	(revision 398)
@@ -0,0 +1,308 @@
+/*
+ *  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 <kernel.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <target_kernel_impl.h>
+#include "syssvc/musl_adapter.h"
+#include "kernel_cfg.h"
+
+#ifndef _MSC_VER
+void _start_c(const char * const*args);
+
+void
+_sta_ker()
+{
+	static const char *const args[] = {
+		(char *)1,
+		"asp3",
+		0,
+		// envp
+		"TZ=JST-9",
+		0,
+		// auxv
+		0
+	};
+	_start_c(args);
+}
+
+void *tid_address;
+
+__attribute__((weak))
+long SYS_set_tid_address(long a) {
+	tid_address = (void *)a;
+	return 0;
+}
+
+__attribute__((weak))
+int SYS_gettid()
+{
+	ID tskid;
+	ER ret;
+
+	ret = get_tid(&tskid);
+	if (ret != E_OK)
+		return -ENOSYS;
+
+	return tskid;
+}
+
+__attribute__((weak))
+int SYS_getpid()
+{
+	return 1;
+}
+
+__attribute__((weak))
+int SYS_tkill(int tid, int sig)
+{
+	ER ret;
+
+	ret = ter_tsk(tid);
+	if (ret != E_OK)
+		return -ENOSYS;
+
+	return 0;
+}
+
+sigset_t g_sigmask;
+
+__attribute__((weak))
+long SYS_rt_sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
+{
+	if (old != NULL)
+		memcpy(old, &g_sigmask, sizeof(sigset_t));
+
+	switch (how) {
+	case SIG_BLOCK:
+		for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
+			g_sigmask.__bits[i] |= set->__bits[i];
+		}
+		break;
+	case SIG_UNBLOCK:
+		for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
+			g_sigmask.__bits[i] &= ~set->__bits[i];
+		}
+		break;
+	case SIG_SETMASK:
+		memcpy(&g_sigmask, set, sizeof(sigset_t));
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+__attribute__((weak))
+void SYS_exit_group()
+{
+	ext_ker();
+}
+
+__attribute__((weak))
+void SYS_exit()
+{
+	ext_ker();
+}
+
+__attribute__((weak))
+int SYS_open(const char *path, int flags, void *arg)
+{
+	return -ENOSYS;
+}
+
+__attribute__((weak))
+long SYS_poll()
+{
+	return -ENOSYS;
+}
+
+__attribute__((weak))
+long SYS_brk(long a) {
+	return (long)shell_brk((void *)a);
+}
+
+__attribute__((weak))
+long SYS_mmap2(long a, long b, long c, long d, long e, long f, long g) {
+	return (int)shell_mmap2((void *)a, (size_t)b, (int)c, (int)d, (int)e, ((off_t)f << 32) | (off_t)g);
+}
+
+__attribute__((weak))
+long SYS_mprotect(long a, long b, long c) {
+	return shell_mprotect((void *)a, (size_t)b, (int)c);
+}
+
+uint32_t __sync_add_and_fetch_4(uint32_t *count, uint32_t value)
+{
+	uint32_t result;
+	bool_t lock = sense_lock();
+
+	if (!lock)
+		loc_cpu();
+
+	result = *count;
+	result += value;
+	*count = result;
+
+	if (!lock)
+		unl_cpu();
+
+	return result;
+}
+
+uint32_t __sync_sub_and_fetch_4(uint32_t *count, uint32_t value)
+{
+	uint32_t result;
+	bool_t lock = sense_lock();
+
+	if (!lock)
+		loc_cpu();
+
+	result = *count;
+	result -= value;
+	*count = result;
+
+	if (!lock)
+		unl_cpu();
+
+	return result;
+}
+
+#endif
+
+#ifndef _MSC_VER
+extern uint32_t _HeapBase;
+extern uint32_t _HeapLimit;
+#else
+uint8_t _HeapBase[16 * 4096];
+#define _HeapLimit _HeapBase[sizeof(_HeapBase)]
+#endif
+
+void *shell_brk(void *addr)
+{
+	if (addr == 0) {
+		return (void *)(&_HeapBase);
+	}
+	if ((addr >= (void *)&_HeapBase) && (addr < (void *)&_HeapLimit)) {
+		return addr;
+	}
+	return (void *)-1;
+}
+
+void *shell_mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset)
+{
+	if (fd != -1)
+		return (void *)-EINVAL;
+
+	if ((length >= 0) && (length <= sizeof(&_HeapBase))) {
+		return &_HeapBase;
+	}
+	return (void *)-1;
+}
+
+int shell_mprotect(void *addr, size_t len, int prot)
+{
+	//if ((addr >= (void *)&_HeapBase) && (addr + len < (void *)&_HeapLimit)) {
+	return 0;
+//}
+//return -1;
+}
+
+#include "syssvc/tlsf/tlsf.h"
+
+static tlsf_t sys_tlsf;
+static pool_t sys_pool;
+
+void sys_malloc_init(intptr_t exinf)
+{
+	sys_tlsf = tlsf_create(&_HeapBase);
+	if (sys_tlsf == NULL)
+		return;
+
+	sys_pool = tlsf_add_pool(sys_tlsf, ((uint8_t *)&_HeapBase) + tlsf_size(), ((intptr_t)&_HeapLimit - (intptr_t)&_HeapBase) - tlsf_size());
+}
+
+void sys_malloc_fini(intptr_t exinf)
+{
+	tlsf_destroy(sys_tlsf);
+}
+
+void *malloc(size_t size)
+{
+	void *result;
+	wai_sem(SEM_MALLOC);
+	result = tlsf_malloc(sys_tlsf, size);
+	sig_sem(SEM_MALLOC);
+	if (result == NULL)
+		tlsf_check_pool(sys_pool);
+	return result;
+}
+
+void *calloc(size_t size, size_t count)
+{
+	void *result;
+	wai_sem(SEM_MALLOC);
+	result = tlsf_malloc(sys_tlsf, count * size);
+	sig_sem(SEM_MALLOC);
+	if (result != NULL)
+		memset(result, 0, count * size);
+	else
+		tlsf_check_pool(sys_pool);
+	return result;
+}
+
+void *realloc(void *ptr, size_t size)
+{
+	void *result;
+	wai_sem(SEM_MALLOC);
+	result = tlsf_realloc(sys_tlsf, ptr, size);
+	sig_sem(SEM_MALLOC);
+	if (result == NULL)
+		tlsf_check_pool(sys_pool);
+	return result;
+}
+
+void free(void *ptr)
+{
+	wai_sem(SEM_MALLOC);
+	tlsf_free(sys_tlsf, ptr);
+	sig_sem(SEM_MALLOC);
+}
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/musl_adapter.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/musl_adapter.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/musl_adapter.cfg	(revision 398)
@@ -0,0 +1,41 @@
+/*
+ *  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 "syssvc/musl_adapter.h"
+
+ATT_INI({ TA_NULL, 0, sys_malloc_init });
+CRE_SEM(SEM_MALLOC, { TA_TPRI, 1, 1 });
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/musl_adapter.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/musl_adapter.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/musl_adapter.h	(revision 398)
@@ -0,0 +1,53 @@
+/*
+ *  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$
+ */
+
+#ifndef MUSL_ADAPTER_H
+#define MUSL_ADAPTER_H
+
+#include <stdio.h>
+
+extern void *shell_brk(void *addr);
+
+extern void *shell_mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset);
+
+extern int shell_mprotect(void *addr, size_t len, int prot);
+
+extern void sys_malloc_init(intptr_t exinf);
+
+extern void sys_malloc_fini(intptr_t exinf);
+
+#endif /* MUSL_ADAPTER_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/serial.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/serial.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/serial.h	(revision 398)
@@ -0,0 +1,107 @@
+/*
+ *  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-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$
+ */
+
+/*
+ *		シリアルインタフェースドライバ
+ */
+
+#ifndef TOPPERS_SERIAL_H
+#define TOPPERS_SERIAL_H
+
+#include <kernel.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ *  シリアルインタフェースドライバの用いるパケット
+ */
+typedef struct {
+	uint_t		reacnt;			/* 受信バッファ中の文字数 */
+	uint_t		wricnt;			/* 送信バッファ中の文字数 */
+} T_SERIAL_RPOR;
+
+#ifdef TOPPERS_OMIT_TECS
+/*
+ *  シリアルインタフェースドライバの初期化ルーチン
+ */
+extern void		serial_initialize(intptr_t exinf) throw();
+
+/*
+ *  シリアルインタフェースドライバからの未送信文字の取出し
+ */
+extern bool_t	serial_get_chr(ID portid, char *p_c) throw();
+#endif
+
+/*
+ *  シリアルインタフェースドライバのサービスコール
+ */
+extern ER		serial_opn_por(ID portid) throw();
+extern ER		serial_cls_por(ID portid) throw();
+extern ER_UINT	serial_trea_dat(ID portid, char *buf, uint_t len, TMO tmout) 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();
+
+Inline ER_UINT	serial_rea_dat(ID portid, char *buf, uint_t len)
+{
+	return serial_trea_dat(portid, buf, len, TMO_FEVR);
+}
+
+/*
+ *  シリアルインタフェースドライバの動作制御用のための定数
+ *
+ *  以下の定数は，ビット毎に論理和をとって用いる．
+ */
+#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_mbedtls/trunk/asp3_dcre/syssvc/siofd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/siofd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/siofd.c	(revision 398)
@@ -0,0 +1,110 @@
+/*
+ *  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 <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include "target_serial.h"
+#include "siofd.h"
+#include "serial_api.h"
+
+extern serial_t log_serial;
+
+__attribute__((weak))
+int siofd_open(const char *path, int flags, ...)
+{
+	return -1;
+}
+
+__attribute__((weak))
+int siofd_close(int fd)
+{
+	return -1;
+}
+
+__attribute__((weak))
+ssize_t siofd_read(int fd, void *data, size_t len)
+{
+	char *pos, *end;
+
+	if (fd != STDIN_FILENO)
+		return -1;
+
+	for (pos = (char *)data, *end = &pos[len]; pos < end; pos++) {
+		*pos = serial_getc(&log_serial);
+	}
+
+	return pos - (char *)data;
+}
+
+__attribute__((weak))
+ssize_t siofd_write(int fd, const void *data, size_t len)
+{
+	const char *pos, *end;
+
+	if (fd != STDOUT_FILENO)
+		return -1;
+
+	for (pos = (const char *)data, end = &pos[len]; pos < end; pos++) {
+		serial_putc(&log_serial, *pos);
+	}
+
+	return pos - (char *)data;
+}
+
+__attribute__((weak))
+int siofd_tcsetattr(int fd, int act, const struct termios *tio)
+{
+	return 0;
+}
+
+__attribute__((weak))
+int siofd_tcgetattr(int fd, struct termios *tio)
+{
+	return 0;
+}
+
+__attribute__((weak))
+int siofd_fcntl(int fd, int cmd, ...)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/siofd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/siofd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/siofd.h	(revision 398)
@@ -0,0 +1,55 @@
+/*
+ *  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$
+ */
+
+/*
+ *	シリアルインタフェースドライバのファイルディスクリプタ実装部
+ */
+
+int siofd_open(const char *path, int flags, ...);
+
+int siofd_close(int fd);
+
+ssize_t siofd_read(int fd, void *data, size_t len);
+
+ssize_t siofd_write(int fd, const void *data, size_t len);
+
+int siofd_tcsetattr(int fd, int act, const struct termios *tio);
+
+int siofd_tcgetattr(int fd, struct termios *tio);
+
+int siofd_fcntl(int fd, int cmd, ...);
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/syslog.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/syslog.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/syslog.h	(revision 398)
@@ -0,0 +1,100 @@
+/*
+ *  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$
+ */
+
+/*
+ *		システムログ機能
+ */
+
+#ifndef TOPPERS_SYSLOG_H
+#define TOPPERS_SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+
+#ifdef TOPPERS_OMIT_TECS
+/*
+ *  ログバッファのサイズ
+ */
+#ifndef TCNT_SYSLOG_BUFFER
+#define TCNT_SYSLOG_BUFFER	32		/* ログバッファのサイズ */
+#endif /* TCNT_SYSLOG_BUFFER */
+
+/*
+ *  システムログ機能の初期化
+ */
+extern void	syslog_initialize(intptr_t exinf) throw();
+#endif
+
+/*
+ *  ログ情報の出力
+ */
+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();
+
+/*
+ *  低レベル出力によるすべてのログ情報の出力
+ */
+extern ER	syslog_fls_log(void) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_SYSLOG_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tBanner.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tBanner.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tBanner.cdl	(revision 398)
@@ -0,0 +1,74 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2016 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$
+ */
+
+/*
+ *  カーネル起動メッセージ出力の本体のセルタイプ
+ */
+[singleton]
+celltype tBannerMain {
+	entry	sRoutineBody	eBannerInitialize;
+
+	attr {
+		char	*targetName;			/* ターゲット名 */
+		char	*copyrightNotice;		/* 著作権表示 */
+	};
+};
+
+/*
+ *  カーネル起動メッセージ出力（複合コンポーネント）のセルタイプ
+ */
+[singleton,active]
+composite tBanner {
+	attr {
+		char	*targetName;			/* ターゲット名 */
+		char	*copyrightNotice;		/* 著作権表示 */
+	};
+
+	cell tBannerMain BannerMain {
+		/* 属性の継承 */
+		targetName      = composite.targetName;
+		copyrightNotice = composite.copyrightNotice;
+	};
+
+	cell tInitializeRoutine InitializeRoutine {
+		/* 呼び口 */
+		cInitializeRoutineBody = BannerMain.eBannerInitialize;
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tBannerMain.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tBannerMain.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tBannerMain.c	(revision 398)
@@ -0,0 +1,74 @@
+/*
+ *  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-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 "tBannerMain_tecsgen.h"
+#include <t_syslog.h>
+
+/*
+ *  カーネル起動メッセージ
+ */
+static const char banner[] = "\n"
+"TOPPERS/ASP3 Kernel Release %d.%X.%d for %s"
+" (" __DATE__ ", " __TIME__ ")\n"
+"Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory\n"
+"                            Toyohashi Univ. of Technology, JAPAN\n"
+"Copyright (C) 2004-2017 by Embedded and Real-Time Systems Laboratory\n"
+"            Graduate School of Information Science, Nagoya Univ., JAPAN\n"
+"%s";
+
+/*
+ *  カーネル起動メッセージの出力（受け口関数）
+ */
+void
+eBannerInitialize_main(intptr_t exinf)
+{
+	syslog_5(LOG_NOTICE, banner,
+				(TKERNEL_PRVER >> 12) & 0x0fU,
+				(TKERNEL_PRVER >> 4) & 0xffU,
+				TKERNEL_PRVER & 0x0fU,
+				ATTR_targetName,
+				ATTR_copyrightNotice);
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tBuiltInTestAdaptor.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tBuiltInTestAdaptor.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tBuiltInTestAdaptor.c	(revision 398)
@@ -0,0 +1,59 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2016 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 "tBuiltInTestAdaptor_tecsgen.h"
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+
+/*
+ *  自己診断サービスのディスクリプタの取得
+ */
+ER
+eGetBuiltInTestDescriptor_getDescriptor(Descriptor(sBuiltInTest) *p_desc,
+																	int_t i)
+{
+	*p_desc = cBuiltInTest_refer_to_descriptor(i);
+	return(E_OK);
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogram.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogram.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogram.c	(revision 398)
@@ -0,0 +1,127 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2016 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 "tHistogram_tecsgen.h"
+#define syslog_write	cSysLog_write
+#include <t_syslog.h>
+#include <log_output.h>
+
+/* 
+ *  実行時間分布計測の初期化（受け口関数）
+ */
+void
+eHistogram_initialize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	uint_t	i;
+
+	for (i = 0; i <= ATTR_maxTime; i++) {
+		VAR_histarea[i] = 0U;
+	}
+	VAR_over = 0U;
+	VAR_under = 0U;
+}
+
+/*
+ *  実行時間計測の開始（受け口関数）
+ */
+void
+eHistogram_beginMeasure(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	HIST_BM_HOOK();
+	HIST_GET_TIM(&VAR_begin_time);
+}
+
+/*
+ *  実行時間計測の終了（受け口関数）
+ */
+void
+eHistogram_endMeasure(CELLIDX idx)
+{
+	CELLCB		*p_cellcb = GET_CELLCB(idx);
+	histtim_t	end_time, timediff;
+	uint_t		val;
+
+	HIST_GET_TIM(&end_time);
+
+	timediff = end_time - VAR_begin_time;
+#ifdef HISTTIM_CYCLE
+	if (end_time < VAR_begin_time) {
+		timediff += HISTTIM_CYCLE;
+	}
+#endif /* HISTTIM_CYCLE */
+	val = HIST_CONV_TIM(timediff);
+	if (val <= ATTR_maxTime) {
+		VAR_histarea[val]++;
+	}
+	else if (val <= ((uint_t) INT_MAX)) {
+		VAR_over++;
+	}
+	else {
+		VAR_under++;
+	}
+}
+
+/*
+ *  実行時間分布計測の表示（受け口関数）
+ */
+void
+eHistogram_print(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	uint_t	i;
+
+	for (i = 0; i <= ATTR_maxTime; i++) {
+		if (VAR_histarea[i] > 0) {
+			syslog_2(LOG_NOTICE, "%d : %d", i, VAR_histarea[i]);
+		}
+	}
+	if (VAR_over > 0) {
+		syslog_2(LOG_NOTICE, "> %d : %d", ATTR_maxTime, VAR_over);
+	}
+	if (VAR_under > 0) {
+		syslog_1(LOG_NOTICE, "> INT_MAX : %d", VAR_under);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogram.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogram.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogram.cdl	(revision 398)
@@ -0,0 +1,87 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2016 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$
+ */
+
+/*
+ *		実行時間分布集計サービスのコンポーネント記述ファイル
+ */
+
+import_C("syssvc/tHistogram.h");
+
+/*
+ *  実行時間分布集計サービスのシグニチャ
+ */
+signature sHistogram {
+	/*
+	 *  実行時間分布計測の初期化
+   	 */
+	void	initialize(void);
+
+	/*
+	 *  実行時間計測の開始
+	 */
+	void	beginMeasure(void);
+
+	/*
+	 *  実行時間計測の終了
+	 */
+	void	endMeasure(void);
+
+	/*
+	 *  実行時間分布計測の表示
+	 */
+	void	print(void);
+};
+
+/*
+ *  実行時間分布集計サービスのセルタイプ
+ */
+celltype tHistogram {
+	entry	sHistogram		eHistogram;
+
+	attr {
+		uint_t		maxTime = 1000;		/* 分布を記録する最大時間 */
+	};
+	var {
+		[size_is(maxTime + 1)] uint_t	*histarea;
+										/* 分布を記録するメモリ領域 */
+		histtim_t	begin_time;			/* 計測開始時刻 */
+		uint_t		over;				/* 最大時間を超えた度数 */
+		uint_t		under;				/* 時間の逆転が疑われる度数 */
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogram.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogram.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogram.h	(revision 398)
@@ -0,0 +1,77 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2006-2016 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_THISTOGRAM_H
+#define TOPPERS_THISTOGRAM_H
+
+#include "target_syssvc.h"
+
+/*
+ *  ターゲット依存部で設定変更するためのマクロ
+ */
+#ifndef HISTTIM						/* 実行時間計測用の時刻のデータ型 */
+#define HISTTIM					HRTCNT
+
+#ifdef TCYC_HRTCNT					/* 実行時間計測用の時刻の周期 */
+#define HISTTIM_CYCLE			TCYC_HRTCNT
+#endif /* TCYC_HRTCNT */
+#endif /* HISTTIM */
+
+#ifndef HIST_GET_TIM				/* 実行時間計測用の現在時刻の取得 */
+#define HIST_GET_TIM(p_time)	(*(p_time) = fch_hrt())
+#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 HISTTIM	histtim_t;
+
+#endif /* TOPPERS_THISTOGRAM_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogramAdapter.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogramAdapter.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogramAdapter.c	(revision 398)
@@ -0,0 +1,87 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2016 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$
+ */
+
+/*
+ *		C言語で記述されたアプリケーションから，TECSベースの実行時間分布
+ *		集計サービスを呼び出すためのアダプタ
+ */
+
+#include "tHistogramAdapter_tecsgen.h"
+#include "histogram.h"
+
+/*
+ *  実行時間分布計測の初期化（サービスコール）
+ */
+void
+init_hist(ID histid)
+{
+	assert(1 <= histid && histid <= N_CP_cHistogram);
+	return(cHistogram_initialize(histid - 1));
+}
+
+/*
+ *  実行時間計測の開始
+ */
+void
+begin_measure(ID histid)
+{
+	assert(1 <= histid && histid <= N_CP_cHistogram);
+	return(cHistogram_beginMeasure(histid - 1));
+}
+
+/*
+ *  実行時間計測の終了
+ */
+void
+end_measure(ID histid)
+{
+	assert(1 <= histid && histid <= N_CP_cHistogram);
+	return(cHistogram_endMeasure(histid - 1));
+}
+
+/*
+ *  実行時間分布計測の表示
+ */
+void
+print_hist(ID histid)
+{
+	assert(1 <= histid && histid <= N_CP_cHistogram);
+	return(cHistogram_print(histid - 1));
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogramAdapter.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogramAdapter.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tHistogramAdapter.cdl	(revision 398)
@@ -0,0 +1,10 @@
+/*
+ *		C言語で記述されたアプリケーションから，TECSベースの実行時間分布
+ *		集計サービスを呼び出すためのアダプタ用セルタイプの定義
+ * 
+ *  $Id$
+ */
+[singleton, active]
+celltype tHistogramAdapter {
+	call	sHistogram		cHistogram[];
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tLogTask.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tLogTask.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tLogTask.cdl	(revision 398)
@@ -0,0 +1,125 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *		システムログタスクのコンポーネント記述ファイル
+ */
+
+/*
+ *  システムログタスクのシグニチャ
+ */
+signature sLogTask {
+	ER		flush([in] uint_t count);
+};
+
+/*
+ *  システムログタスクの本体のセルタイプ
+ */
+[singleton]
+celltype tLogTaskMain {
+	entry	sTaskBody		eLogTaskBody;
+	entry	sRoutineBody	eLogTaskTerminate;
+	entry	sLogTask		eLogTask;
+
+	call	sSerialPort		cSerialPort;	/* シリアルドライバとの接続 */
+	call	snSerialPortManage	cnSerialPortManage;
+											/* シリアルドライバ管理との接続 */
+	call	sSysLog			cSysLog;		/* システムログ機能との接続 */
+	call	sPutLog			cPutLog;		/* 低レベル出力との接続 */
+
+	attr {
+		RELTIM	interval;				/* システムログタスクの動作間隔 */
+		RELTIM	flushWait;				/* フラッシュ待ちの単位時間 */
+	};
+};
+
+/*
+ *  システムログタスク（複合コンポーネント）のセルタイプ
+ */
+[singleton, active]
+composite tLogTask {
+	entry	sLogTask	eLogTask;		/* システムログタスク操作 */
+	
+	call	sSerialPort	cSerialPort;	/* シリアルドライバとの接続 */
+	call	snSerialPortManage	cnSerialPortManage;
+										/* シリアルドライバ管理との接続 */
+	call	sSysLog		cSysLog;		/* システムログ機能との接続 */
+	call	sPutLog		cPutLog;		/* 低レベル出力との接続 */
+
+	attr {
+		[omit] ATR		attribute = C_EXP("TA_ACT");	/* タスク属性 */
+		[omit] PRI  	priority;		/* タスクの初期優先度 */
+		[omit] size_t 	stackSize;		/* タスクのスタックサイズ */
+		RELTIM		interval = 10000;	/* システムログタスクの動作間隔 */
+		RELTIM		flushWait = 1000;	/* フラッシュ待ちの単位時間 */
+	};
+
+	cell tLogTaskMain LogTaskMain {
+		/* 呼び口の結合 */
+		cSerialPort        => composite.cSerialPort;
+		cnSerialPortManage => composite.cnSerialPortManage;
+		cSysLog            => composite.cSysLog;
+		cPutLog            => composite.cPutLog;
+
+		/* 属性の継承 */
+		interval  = composite.interval;
+		flushWait = composite.flushWait;
+	};
+
+	cell tTask Task {
+		/* 呼び口の結合 */
+		cTaskBody = LogTaskMain.eLogTaskBody;
+
+		/* 属性の継承 */
+		attribute = composite.attribute;
+		priority  = composite.priority;
+		stackSize = composite.stackSize;
+	};
+
+	cell tTerminateRoutine TerminateRoutine {
+		/* 呼び口 */
+		cTerminateRoutineBody = LogTaskMain.eLogTaskTerminate;
+	};
+
+	/* 受け口の結合 */
+	composite.eLogTask => LogTaskMain.eLogTask;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tLogTaskMain.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tLogTaskMain.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tLogTaskMain.c	(revision 398)
@@ -0,0 +1,196 @@
+/*
+ *  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-2016 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 "tLogTaskMain_tecsgen.h"
+#include <t_syslog.h>
+#include <log_output.h>
+
+/*
+ *  シリアルインタフェースへの1文字出力
+ */
+static void
+logtask_putc(char c)
+{
+	cSerialPort_write(&c, 1);
+}
+
+/*
+ *  低レベル出力への1文字出力
+ */
+static void
+target_fput_log(char c)
+{
+	cPutLog_putChar(c);
+}
+
+/*
+ *  システムログ出力の待ち合わせ（受け口関数）
+ */
+ER
+eLogTask_flush(uint_t count)
+{
+	T_SYSLOG_RLOG	rlog;
+	T_SERIAL_RPOR	rpor;
+	ER				ercd, rercd;
+
+	if (sns_dpn()) {
+		ercd = E_CTX;
+	}
+	else {
+		for (;;) {
+			if (cSysLog_refer(&rlog) < 0) {
+				ercd = E_SYS;
+				goto error_exit;
+			}
+			if (rlog.count <= count) {
+				if (count == 0U) {
+					/*
+					 *  countが0の場合には，シリアルバッファが空かを確
+					 *  認する．
+					 */
+					if (cSerialPort_refer(&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;
+				}
+			}
+
+			/*
+			 *  フラッシュ待ちの単位時間（ATTR_flushWaitμ秒）待つ．
+			 */
+			rercd = dly_tsk(ATTR_flushWait);
+			if (rercd < 0) {
+				ercd = (rercd == E_RLWAI) ? rercd : E_SYS;
+				goto error_exit;
+			}
+		}
+	}
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  システムログタスクの本体（受け口関数）
+ */
+void
+eLogTaskBody_main(void)
+{
+	SYSLOG	syslog;
+	uint_t	lost;
+	ER_UINT	rercd;
+
+	cSerialPort_open();
+	syslog_0(LOG_NOTICE, "System logging task is started.");
+
+	for (;;) {
+		lost = 0U;
+		while ((rercd = cSysLog_read(&syslog)) >= 0) {
+			lost += (uint_t) rercd;
+			if (lost > 0U) {
+				syslog_lostmsg(lost, logtask_putc);
+				lost = 0U;
+			}
+			syslog_print(&syslog, logtask_putc);
+			logtask_putc('\n');
+		}
+		if (lost > 0U) {
+			syslog_lostmsg(lost, logtask_putc);
+		}
+		dly_tsk(ATTR_interval);
+	}
+}
+
+/*
+ *  システムログタスクの終了処理（受け口関数）
+ */
+void
+eLogTaskTerminate_main(intptr_t exinf)
+{
+	char	c;
+	SYSLOG	syslog;
+	bool_t	msgflg = false;
+	ER_UINT	rercd;
+
+	/*
+	 *  シリアルインタフェースドライバの送信バッファに蓄積されたデータ
+	 *  を，低レベル出力機能を用いて出力する．
+	 */
+	while (cnSerialPortManage_getChar(&c)) {
+		target_fput_log(c);
+	}
+
+	/*
+	 *  ログバッファに記録されたログ情報を，低レベル出力機能を用いて出
+	 *  力する．
+	 */
+	while ((rercd = cSysLog_read(&syslog)) >= 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 (syslog.logtype >= LOG_TYPE_COMMENT) {
+			syslog_print(&syslog, target_fput_log);
+			target_fput_log('\n');
+		}
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tPutLogSIOPort.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tPutLogSIOPort.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tPutLogSIOPort.c	(revision 398)
@@ -0,0 +1,70 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2007-2018 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$
+ */
+
+/*
+ *		SIOドライバによるシステムログの低レベル出力
+ */
+
+#include "tPutLogSIOPort_tecsgen.h"
+
+/*
+ *  システムログの低レベル出力のための初期化
+ *
+ *  初期化ルーチンを呼び出すより前に初期化するために，カーネルのターゲッ
+ *  ト依存部から直接呼び出すための関数．
+ */
+void
+tPutLogSIOPort_initialize(void)
+{
+	cSIOPort_open();
+}
+
+/*
+ *  システムログの低レベル出力のための文字出力（受け口関数）
+ *
+ *  SIOポートに文字が送信できるまでポーリングする．
+ */
+void
+ePutLog_putChar(char c)
+{
+	if(c == '\n'){
+		while (!cSIOPort_putChar('\r'));
+	}
+	while (!cSIOPort_putChar(c));
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tPutLogSIOPort.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tPutLogSIOPort.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tPutLogSIOPort.cdl	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015-2018 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$
+ */
+
+/*
+ *		SIOドライバによるシステムログの低レベル出力のコンポーネント記述
+ *		ファイル
+ */
+
+/*
+ *  システムログの低レベル出力のセルタイプ
+ */
+[singleton]
+celltype tPutLogSIOPort {
+	entry	sPutLog		ePutLog;
+	call	sSIOPort	cSIOPort;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialAdapter.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialAdapter.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialAdapter.c	(revision 398)
@@ -0,0 +1,143 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *		C言語で記述されたアプリケーションから，TECSベースのシリアルイン
+ *		タフェースドライバを呼び出すためのアダプタ
+ */
+
+#include "tSerialAdapter_tecsgen.h"
+#include "serial.h"
+
+/*
+ *  シリアルポートのオープン（サービスコール）
+ */
+ER
+serial_opn_por(ID portid)
+{
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= N_CP_cSerialPort)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	return(cSerialPort_open(portid - 1));
+}
+
+/*
+ *  シリアルポートのクローズ（サービスコール）
+ */
+ER
+serial_cls_por(ID portid)
+{
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= N_CP_cSerialPort)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	return(cSerialPort_close(portid - 1));
+}
+
+/*
+ *  シリアルポートからの文字列受信（サービスコール）
+ */
+ER_UINT
+serial_trea_dat(ID portid, char *buf, uint_t len, TMO tmout)
+{
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= N_CP_cSerialPort)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	return(cSerialPort_read(portid - 1, buf, len, tmout));
+}
+
+/*
+ *  シリアルポートへの文字列送信（サービスコール）
+ */
+ER_UINT
+serial_wri_dat(ID portid, const char *buf, uint_t len)
+{
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= N_CP_cSerialPort)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	return(cSerialPort_write(portid - 1, buf, len));
+}
+
+/*
+ *  シリアルポートの制御（サービスコール）
+ */
+ER
+serial_ctl_por(ID portid, uint_t ioctl)
+{
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= N_CP_cSerialPort)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	return(cSerialPort_control(portid - 1, ioctl));
+}
+
+/*
+ *  シリアルポート状態の参照（サービスコール）
+ */
+ER
+serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor)
+{
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!(1 <= portid && portid <= N_CP_cSerialPort)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	return(cSerialPort_refer(portid - 1, pk_rpor));
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialAdapter.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialAdapter.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialAdapter.cdl	(revision 398)
@@ -0,0 +1,10 @@
+/*
+ *		C言語で記述されたアプリケーションから，TECSベースのシリアルイン
+ *		タフェースドライバを呼び出すためのアダプタ用セルタイプの定義
+ * 
+ *  $Id$
+ */
+[singleton, active]
+celltype tSerialAdapter {
+	call	sSerialPort		cSerialPort[];
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialPort.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialPort.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialPort.cdl	(revision 398)
@@ -0,0 +1,191 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *		シリアルインタフェースドライバのコンポーネント記述ファイル
+ */
+
+/*
+ *  シリアルインタフェースドライバをTECSを用いずに呼び出すためにも必要
+ *  な定義の取込み
+ */
+import_C("syssvc/serial.h");
+
+/*
+ *  シリアルインタフェースドライバのシグニチャ
+ */
+signature sSerialPort {
+	ER		open(void);
+	ER		close(void);
+	ER_UINT	read([out,size_is(length)] char *buffer, [in] uint_t length, [in] TMO tmout);
+	ER_UINT	write([in,size_is(length)] const char *buffer, [in] uint_t length);
+	ER		control([in] uint_t ioControl);
+	ER		refer([out] T_SERIAL_RPOR *pk_rpor);
+};
+
+/*
+ *  シリアルインタフェースドライバのターゲット依存部が提供する関数
+ */
+signature sSIOPort {
+	void	open(void);
+	void	close(void);
+	bool_t	putChar([in] char c);
+	int_t	getChar(void);
+	void	enableCBR([in] uint_t cbrtn);
+	void	disableCBR([in] uint_t cbrtn);
+};
+
+/*
+ *  コールバックルーチンの識別番号（cbrtnパラメータに用いる）
+ */
+const uint_t SIOSendReady = 1;		/* 送信可能コールバック */
+const uint_t SIOReceiveReady = 2;	/* 受信通知コールバック */
+
+/*
+ *  ターゲット依存部からのコールバック
+ */
+[callback]
+signature siSIOCBR {
+	void	readySend(void);
+	void	readyReceive(void);
+};
+
+/*
+ *  シリアルインタフェースドライバ管理用のシグニチャ（終了処理ルーチン
+ *  からの使用を想定）
+ */
+signature snSerialPortManage {
+	bool_t	getChar([out] char *p_char);
+};
+
+/*
+ *  シリアルポートの制御部のセルタイプ
+ */
+celltype tSerialPortMain {
+	entry	sSerialPort			eSerialPort;
+	entry	snSerialPortManage	enSerialPortManage;
+
+	call	sSIOPort	cSIOPort;			/* 簡易SIOドライバとの接続 */
+	entry	siSIOCBR	eiSIOCBR;
+	
+	call	sSemaphore	cSendSemaphore;		/* 送信用セマフォとの接続 */
+	call	siSemaphore	ciSendSemaphore;
+	call	sSemaphore	cReceiveSemaphore;	/* 受信用セマフォとの接続 */
+	call	siSemaphore	ciReceiveSemaphore;
+	
+	attr {
+		uint_t	receiveBufferSize = 256;	/* 受信バッファサイズ */
+		uint_t	sendBufferSize = 256;		/* 送信バッファサイズ */
+	};
+	var {
+		bool_t	openFlag = C_EXP("false");	/* オープン済みフラグ */
+		bool_t	errorFlag;					/* エラーフラグ */
+		uint_t	ioControl;					/* 動作制御の設定値 */
+
+		[size_is(receiveBufferSize)] char *receiveBuffer;	/* 受信バッファ */
+		uint_t	receiveReadPointer;			/* 受信バッファ読出しポインタ */
+		uint_t	receiveWritePointer;		/* 受信バッファ書込みポインタ */
+		uint_t	receiveCount;				/* 受信バッファ中の文字数 */
+		char  	receiveFlowControl;			/* 送るべきSTART/STOP */
+		bool_t	receiveStopped;				/* STOPを送った状態か？ */
+
+		[size_is(sendBufferSize)] char *sendBuffer;		/* 送信バッファ */
+		uint_t	sendReadPointer;			/* 送信バッファ読出しポインタ */
+		uint_t	sendWritePointer;			/* 送信バッファ書込みポインタ */
+		uint_t	sendCount;					/* 送信バッファ中の文字数 */
+		bool_t	sendStopped;				/* STOPを受け取った状態か？ */
+	};
+};
+
+/*
+ *  シリアルポートドライバ（複合セル）のセルタイプ
+ *
+ *  シリアルポートの制御部と，それが使用する2つのセマフォ（受信用と送
+ *  信用）を複合化して，1つのコンポーネントとしている．
+ */
+composite tSerialPort {
+	entry	sSerialPort			eSerialPort;
+	entry	snSerialPortManage	enSerialPortManage;
+
+	call	sSIOPort		cSIOPort;		/* 簡易SIOドライバとの接続 */
+	entry	siSIOCBR		eiSIOCBR;
+	
+	attr {
+		uint_t	receiveBufferSize = 256;	/* 受信バッファサイズ */
+		uint_t	sendBufferSize = 256;		/* 送信バッファサイズ */
+	};
+
+	/* 受信用のセマフォ */
+	cell tSemaphore ReceiveSemaphore {
+		attribute = C_EXP("TA_NULL");
+		initialCount = 0;
+		maxCount =1;
+	};
+
+	/* 送信用のセマフォ */
+	cell tSemaphore SendSemaphore {
+		attribute = C_EXP("TA_NULL");
+		initialCount = 1;
+		maxCount =1;
+	};
+
+	/* シリアルポートの制御部 */
+	cell tSerialPortMain SerialPortMain {
+		/* セマフォとの結合 */
+		cReceiveSemaphore  = ReceiveSemaphore.eSemaphore;
+		ciReceiveSemaphore = ReceiveSemaphore.eiSemaphore;
+		cSendSemaphore     = SendSemaphore.eSemaphore;
+		ciSendSemaphore    = SendSemaphore.eiSemaphore;
+
+		/* 呼び口のエクスポート */
+		cSIOPort          => composite.cSIOPort;
+
+		/* 属性の継承 */
+		receiveBufferSize = composite.receiveBufferSize;
+		sendBufferSize    = composite.sendBufferSize;
+	};
+
+	/* 受け口のエクスポート */
+	composite.eSerialPort        => SerialPortMain.eSerialPort;
+	composite.enSerialPortManage => SerialPortMain.enSerialPortManage;
+	composite.eiSIOCBR           => SerialPortMain.eiSIOCBR;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialPortMain.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialPortMain.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSerialPortMain.c	(revision 398)
@@ -0,0 +1,646 @@
+/*
+ *  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-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 <kernel.h>
+#include "tSerialPortMain_tecsgen.h"
+#include <t_syslog.h>
+
+/*
+ *  フロー制御に関連する定数とマクロ
+ */
+#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を送る基準文字数 */
+
+/*
+ *  ポインタのインクリメント
+ */
+#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(CELLCB *p_cellcb)
+{
+	VAR_errorFlag = true;
+	return(E_SYS);
+}
+
+/*
+ *  待ちに入るサービスコールからのエラーの変換
+ */
+static ER
+gen_ercd_wait(ER rercd, CELLCB *p_cellcb)
+{
+	switch (MERCD(rercd)) {
+	case E_RLWAI:
+	case E_DLT:
+	case E_RASTER:
+		return(rercd);
+	default:
+		VAR_errorFlag = true;
+		return(E_SYS);
+	}
+}
+
+/*
+ *  シリアルポートのオープン（受け口関数）
+ */
+ER
+eSerialPort_open(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	ER		ercd;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!VALID_IDX(idx)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+	p_cellcb = GET_CELLCB(idx);
+
+	SVC(dis_dsp(), gen_ercd_sys(p_cellcb));
+	if (VAR_openFlag) {				/* オープン済みかのチェック */
+		ercd = E_OBJ;
+	}
+	else {
+		/*
+		 *  変数の初期化
+		 */
+		VAR_ioControl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
+
+		VAR_receiveReadPointer = 0U;
+		VAR_receiveWritePointer = 0U;
+		VAR_receiveCount = 0U;
+		VAR_receiveFlowControl = '\0';
+		VAR_receiveStopped = false;
+
+		VAR_sendReadPointer = 0U;
+		VAR_sendWritePointer = 0U;
+		VAR_sendCount = 0U;
+		VAR_sendStopped = false;
+
+		/*
+		 *  これ以降，割込みを禁止する．
+		 */
+		if (loc_cpu() < 0) {
+			ercd = E_SYS;
+			goto error_exit_enadsp;
+		}
+
+		/*
+		 *  ハードウェア依存のオープン処理
+		 */
+		cSIOPort_open();
+
+		/*
+		 *  受信通知コールバックを許可する．
+		 */
+		cSIOPort_enableCBR(SIOReceiveReady);
+		VAR_openFlag = true;
+		VAR_errorFlag = false;
+
+		if (unl_cpu() < 0) {
+			VAR_errorFlag = true;
+			ercd = E_SYS;
+			goto error_exit_enadsp;
+		}
+		ercd = E_OK;
+	}
+
+  error_exit_enadsp:
+	SVC(ena_dsp(), gen_ercd_sys(p_cellcb));
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  シリアルポートのクローズ（受け口関数）
+ */
+ER
+eSerialPort_close(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	ER		ercd;
+	bool_t	eflag = false;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!VALID_IDX(idx)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+	p_cellcb = GET_CELLCB(idx);
+
+	SVC(dis_dsp(), gen_ercd_sys(p_cellcb));
+	if (!VAR_openFlag) {			/* オープン済みかのチェック */
+		ercd = E_OBJ;
+	}
+	else {
+		/*
+		 *  ハードウェア依存のクローズ処理
+		 */
+		if (loc_cpu() < 0) {
+			eflag = true;
+		}
+		cSIOPort_close();
+		VAR_openFlag = false;
+		if (unl_cpu() < 0) {
+			eflag = true;
+		}
+
+		/*
+		 *  セマフォの初期化
+		 */
+		if (cSendSemaphore_initialize() < 0) {
+			eflag = true;
+		}
+		if (cReceiveSemaphore_initialize() < 0) {
+			eflag = true;
+		}
+
+		/*
+		 *  エラーコードの設定
+		 */
+		if (eflag) {
+			ercd = gen_ercd_sys(p_cellcb);
+		}
+		else {
+			ercd = E_OK;
+		}
+	}
+	SVC(ena_dsp(), gen_ercd_sys(p_cellcb));
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  シリアルポートへの文字送信
+ *
+ *  p_cellcbで指定されるSIOポートに対して，文字cを送信する．文字を送信
+ *  レジスタにいれた場合にはtrueを返す．そうでない場合には，送信レジス
+ *  タが空いたことを通知するコールバック関数を許可し，falseを返す．この
+ *  関数は，CPUロック状態で呼び出される．
+ */
+Inline bool_t
+serialPort_sendChar(CELLCB *p_cellcb, char c)
+{
+	if (cSIOPort_putChar(c)) {
+		return(true);
+	}
+	else {
+		cSIOPort_enableCBR(SIOSendReady);
+		return(false);
+	}
+}
+
+/*
+ *  シリアルポートへの1文字送信
+ */
+static ER_BOOL
+serialPort_writeChar(CELLCB *p_cellcb, char c)
+{
+	bool_t	buffer_full;
+	ER		ercd, rercd;
+
+	/*
+	 *  LFの前にCRを送信する．
+	 */
+	if (c == '\n' && (VAR_ioControl & IOCTL_CRLF) != 0U) {
+		/*
+		 *  以下のコードは再帰呼出しになっているが，引数cが'\n'の場合に
+		 *  引数cを'\r'として呼び出すことから，この再帰呼出しは2回目の
+		 *  呼び出しで必ず止まる．
+		 */
+		SVC(rercd = serialPort_writeChar(p_cellcb, '\r'), rercd);
+		if ((bool_t) rercd) {
+			SVC(rercd = cSendSemaphore_wait(),
+										gen_ercd_wait(rercd, p_cellcb));
+		}
+	}
+
+	SVC(loc_cpu(), gen_ercd_sys(p_cellcb));
+	if (VAR_sendCount == 0U && !VAR_sendStopped
+								&& serialPort_sendChar(p_cellcb, c)) {
+		/*
+		 *  SIOの送信レジスタに文字を入れることに成功した場合．
+		 */
+		buffer_full = false;
+	}
+	else {
+		/*
+		 *  送信バッファに文字を入れる．
+		 */
+		VAR_sendBuffer[VAR_sendWritePointer] = c;
+		INC_PTR(VAR_sendWritePointer, ATTR_sendBufferSize);
+		VAR_sendCount++;
+		buffer_full = (VAR_sendCount == ATTR_sendBufferSize);
+	}
+
+	SVC(unl_cpu(), gen_ercd_sys(p_cellcb));
+	ercd = (ER_BOOL) buffer_full;
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  シリアルポートへの文字列送信（受け口関数）
+ */
+ER_UINT
+eSerialPort_write(CELLIDX idx, const char *buffer, uint_t length)
+{
+	CELLCB	*p_cellcb;
+	bool_t	buffer_full;
+	uint_t	wricnt = 0U;
+	ER		ercd, rercd;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!VALID_IDX(idx)) {			/* ポート番号のチェック */
+		return(E_ID);
+	}
+
+	p_cellcb = GET_CELLCB(idx);
+	if (!VAR_openFlag) {			/* オープン済みかのチェック */
+		return(E_OBJ);
+	}
+	if (VAR_errorFlag) {			/* エラー状態かのチェック */
+		return(E_SYS);
+	}
+
+	buffer_full = true;				/* ループの1回めはwai_semする */
+	while (wricnt < length) {
+		if (buffer_full) {
+			SVC(rercd = cSendSemaphore_wait(),
+										gen_ercd_wait(rercd, p_cellcb));
+		}
+		SVC(rercd = serialPort_writeChar(p_cellcb, *buffer++), rercd);
+		wricnt++;
+		buffer_full = (bool_t) rercd;
+	}
+	if (!buffer_full) {
+		SVC(cSendSemaphore_signal(), gen_ercd_sys(p_cellcb));
+	}
+	ercd = E_OK;
+
+  error_exit:
+	return(wricnt > 0U ? (ER_UINT) wricnt : ercd);
+}
+
+/*
+ *  シリアルポートからの1文字受信
+ */
+static bool_t
+serialPort_readChar(CELLCB *p_cellcb, char *p_c)
+{
+	bool_t	buffer_empty;
+	ER		ercd;
+
+	SVC(loc_cpu(), gen_ercd_sys(p_cellcb));
+
+	/*
+	 *  受信バッファから文字を取り出す．
+	 */
+	*p_c = VAR_receiveBuffer[VAR_receiveReadPointer];
+	INC_PTR(VAR_receiveReadPointer, ATTR_receiveBufferSize);
+	VAR_receiveCount--;
+	buffer_empty = (VAR_receiveCount == 0U);
+
+	/*
+	 *  STARTを送信する．
+	 */
+	if (VAR_receiveStopped && VAR_receiveCount
+								<= BUFCNT_START(ATTR_receiveBufferSize)) {
+		if (!serialPort_sendChar(p_cellcb, FC_START)) {
+			VAR_receiveFlowControl = FC_START;
+		}
+		VAR_receiveStopped = false;
+	}
+
+	SVC(unl_cpu(), gen_ercd_sys(p_cellcb));
+	ercd = (ER_BOOL) buffer_empty;
+
+  error_exit:
+	return(ercd);
+}
+
+/*
+ *  シリアルポートからの文字列受信（受け口関数）
+ */
+ER_UINT
+eSerialPort_read(CELLIDX idx, char *buffer, uint_t length, TMO tmout)
+{
+	CELLCB	*p_cellcb;
+	bool_t	buffer_empty;
+	uint_t	reacnt = 0U;
+	char	c = '\0';		/* コンパイラの警告を抑止するために初期化する */
+	ER		ercd, rercd;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!VALID_IDX(idx)) {			/* ポート番号のチェック */
+		return(E_ID);
+	}
+
+	p_cellcb = GET_CELLCB(idx);
+	if (!VAR_openFlag) {			/* オープン済みかのチェック */
+		return(E_OBJ);
+	}
+	if (VAR_errorFlag) {			/* エラー状態かのチェック */
+		return(E_SYS);
+	}
+
+	buffer_empty = true;			/* ループの1回めはwai_semする */
+	while (reacnt < length) {
+		if (buffer_empty) {
+			rercd = cReceiveSemaphore_waitTimeout(tmout);
+			if (rercd == E_TMOUT)
+				return E_TMOUT;
+			if (rercd < 0) {
+				gen_ercd_wait(rercd, p_cellcb);
+				ercd = rercd;
+				goto error_exit;
+			}
+		}
+		SVC(rercd = serialPort_readChar(p_cellcb, &c), rercd);
+		*buffer++ = c;
+		reacnt++;
+		buffer_empty = (bool_t) rercd;
+
+		/*
+		 *  エコーバック処理．
+		 */
+		if ((VAR_ioControl & IOCTL_ECHO) != 0U) {
+			SVC(rercd = cSendSemaphore_wait(),
+										gen_ercd_wait(rercd, p_cellcb));
+			SVC(rercd = serialPort_writeChar(p_cellcb, c), rercd);
+			if (!((bool_t) rercd)) {
+				SVC(cSendSemaphore_signal(), gen_ercd_sys(p_cellcb));
+			}
+		}
+	}
+	if (!buffer_empty) {
+		SVC(cReceiveSemaphore_signal(), gen_ercd_sys(p_cellcb));
+	}
+	ercd = E_OK;
+
+  error_exit:
+	return(reacnt > 0U ? (ER_UINT) reacnt : ercd);
+}
+
+/*
+ *  シリアルポートの制御（受け口関数）
+ */
+ER
+eSerialPort_control(CELLIDX idx, uint_t ioctl)
+{
+	CELLCB	*p_cellcb;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!VALID_IDX(idx)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	p_cellcb = GET_CELLCB(idx);
+	if (!VAR_openFlag) {			/* オープン済みかのチェック */
+		return(E_OBJ);
+	}
+	if (VAR_errorFlag) {			/* エラー状態かのチェック */
+		return(E_SYS);
+	}
+
+	VAR_ioControl = ioctl;
+	return(E_OK);
+}
+
+/*
+ *  シリアルポート状態の参照（受け口関数）
+ */
+ER
+eSerialPort_refer(CELLIDX idx, T_SERIAL_RPOR* pk_rpor)
+{
+	CELLCB	*p_cellcb;
+
+	if (sns_dpn()) {				/* コンテキストのチェック */
+		return(E_CTX);
+	}
+	if (!VALID_IDX(idx)) {
+		return(E_ID);				/* ポート番号のチェック */
+	}
+
+	p_cellcb = GET_CELLCB(idx);
+	if (!VAR_openFlag) {			/* オープン済みかのチェック */
+		return(E_OBJ);
+	}
+	if (VAR_errorFlag) {			/* エラー状態かのチェック */
+		return(E_SYS);
+	}
+
+	pk_rpor->reacnt = VAR_receiveCount;
+	pk_rpor->wricnt = VAR_sendCount;
+	return(E_OK);
+}
+
+/*
+ *  シリアルポートからの送信可能コールバック（受け口関数）
+ */
+void
+eiSIOCBR_readySend(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+
+	assert(VALID_IDX(idx));
+	p_cellcb = GET_CELLCB(idx);
+	if (VAR_receiveFlowControl != '\0') {
+		/*
+		 *  START/STOP を送信する．
+		 */
+		(void) cSIOPort_putChar(VAR_receiveFlowControl);
+		VAR_receiveFlowControl = '\0';
+	}
+	else if (!VAR_sendStopped && VAR_sendCount > 0U) {
+		/*
+		 *  送信バッファ中から文字を取り出して送信する．
+		 */
+		(void) cSIOPort_putChar(VAR_sendBuffer[VAR_sendReadPointer]);
+		INC_PTR(VAR_sendReadPointer, ATTR_sendBufferSize);
+		if (VAR_sendCount == ATTR_sendBufferSize) {
+			if (ciSendSemaphore_signal() < 0) {
+				VAR_errorFlag = true;
+			}
+		}
+		VAR_sendCount--;
+	}
+	else {
+		/*
+		 *  送信すべき文字がない場合は，送信可能コールバックを禁止する．
+		 */
+		cSIOPort_disableCBR(SIOSendReady);
+	}
+}
+
+/*
+ *  シリアルポートからの受信通知コールバック（受け口関数）
+ */
+void
+eiSIOCBR_readyReceive(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	char	c;
+
+	assert(VALID_IDX(idx));
+	p_cellcb = GET_CELLCB(idx);
+	c = (char) cSIOPort_getChar();
+	if ((VAR_ioControl & IOCTL_FCSND) != 0U && c == FC_STOP) {
+		/*
+		 *  送信を一時停止する．送信中の文字はそのまま送信する．
+		 */
+		VAR_sendStopped = true;
+	}
+	else if (VAR_sendStopped && (c == FC_START
+				|| (VAR_ioControl & IOCTL_FCANY) != 0U)) {
+		/*
+		 *  送信を再開する．
+		 */
+		VAR_sendStopped = false;
+		if (VAR_sendCount > 0U) {
+			c = VAR_sendBuffer[VAR_sendReadPointer];
+			if (serialPort_sendChar(p_cellcb, c)) {
+				INC_PTR(VAR_sendReadPointer, ATTR_sendBufferSize);
+				if (VAR_sendCount == ATTR_sendBufferSize) {
+					if (ciSendSemaphore_signal() < 0) {
+						VAR_errorFlag = true;
+					}
+				}
+				VAR_sendCount--;
+			}
+		}
+	}
+	else if ((VAR_ioControl & IOCTL_FCSND) != 0U && c == FC_START) {
+		/*
+		 *  送信に対してフロー制御している場合，START は捨てる．
+		 */
+	}
+	else if (VAR_receiveCount == ATTR_receiveBufferSize) {
+		/*
+		 *  バッファフルの場合，受信した文字を捨てる．
+		 */
+	}
+	else {
+		/*
+		 *  受信した文字を受信バッファに入れる．
+		 */
+		VAR_receiveBuffer[VAR_receiveWritePointer] = c;
+		INC_PTR(VAR_receiveWritePointer, ATTR_receiveBufferSize);
+		if (VAR_receiveCount == 0U) {
+			if (ciReceiveSemaphore_signal() < 0) {
+				VAR_errorFlag = true;
+			}
+		}
+		VAR_receiveCount++;
+
+		/*
+		 *  STOPを送信する．
+		 */
+		if ((VAR_ioControl & IOCTL_FCRCV) != 0U && !VAR_receiveStopped
+				&& VAR_receiveCount >= BUFCNT_STOP(ATTR_receiveBufferSize)) {
+			if (!serialPort_sendChar(p_cellcb, FC_STOP)) {
+				VAR_receiveFlowControl = FC_STOP;
+			}
+			VAR_receiveStopped = true;
+		}
+	}
+}
+
+/*
+ *  シリアルインタフェースドライバからの未送信文字の取出し
+ */
+bool_t
+enSerialPortManage_getChar(CELLIDX idx, char *p_c)
+{
+	CELLCB	*p_cellcb;
+
+	if (VALID_IDX(idx)) {						/* ポート番号のチェック */
+		p_cellcb = GET_CELLCB(idx);
+		if (VAR_openFlag) {						/* オープン済みかのチェック */
+			if (VAR_sendCount > 0U) {
+				*p_c = VAR_sendBuffer[VAR_sendReadPointer];
+				INC_PTR(VAR_sendReadPointer, ATTR_sendBufferSize);
+				VAR_sendCount--;
+				return(true);
+			}
+		}
+	}
+	return(false);
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLog.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLog.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLog.c	(revision 398)
@@ -0,0 +1,225 @@
+/*
+ *  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-2016 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>
+#include "tSysLog_tecsgen.h"
+#undef TOPPERS_OMIT_SYSLOG
+#include <t_syslog.h>
+#include <log_output.h>
+#include "target_syssvc.h"
+
+/*
+ *  トレースログマクロのデフォルト定義
+ *
+ *  システムログに出力されたログ情報をトレースログにも記録できるように，
+ *  eSyslog_writeの入口にトレースログマクロを置く．
+ */
+#ifndef LOG_TSYSLOG_ESYSLOG_WRITE_ENTER
+#define LOG_TSYSLOG_ESYSLOG_WRITE_ENTER(priority, p_syslog)
+#endif /* LOG_TSYSLOG_ESYSLOG_WRITE_ENTER */
+
+/*
+ *  ログ時刻の取り出し
+ *
+ *  デフォルトでは，ログ時刻として，高分解能タイマのカウント値を用いて
+ *  いる．ターゲット依存で変更する場合には，SYSLOG_GET_LOGTIMに，ログ時
+ *  刻を取り出すマクロを定義する．
+ */
+#ifndef SYSLOG_GET_LOGTIM
+#define target_hrt_get_current		_kernel_target_hrt_get_current
+#include "target_timer.h"
+#define SYSLOG_GET_LOGTIM(p_logtim) \
+				(*(p_logtim) = _kernel_target_hrt_get_current())
+#endif /* SYSLOG_GET_LOGTIM */
+
+/*
+ *  低レベル出力の呼出し関数
+ */
+static void
+low_putchar(char c)
+{
+	cPutLog_putChar(c);
+}
+
+/*
+ *  ログ情報の出力（受け口関数）
+ *
+ *  CPUロック状態や実行コンテキストによらず動作できるように実装してある．
+ */
+ER
+eSysLog_write(uint_t priority, const SYSLOG *p_syslog)
+{
+	SIL_PRE_LOC;
+
+	LOG_TSYSLOG_ESYSLOG_WRITE_ENTER(priority, p_syslog);
+	SIL_LOC_INT();
+
+	/*
+	 *  ログ時刻の設定
+	 */
+	SYSLOG_GET_LOGTIM(&(((SYSLOG *) p_syslog)->logtim));
+
+	/*
+	 *  ログバッファに記録
+	 */
+	if ((VAR_logMask & LOG_MASK(priority)) != 0U) {
+		VAR_logBuffer[VAR_tail] = *p_syslog;
+		VAR_tail++;
+		if (VAR_tail >= ATTR_logBufferSize) {
+			VAR_tail = 0U;
+		}
+		if (VAR_count < ATTR_logBufferSize) {
+			VAR_count++;
+		}
+		else {
+			VAR_head = VAR_tail;
+			VAR_lost++;
+		}
+	}
+
+	/*
+	 *  低レベル出力
+	 */
+	if ((VAR_lowMask & LOG_MASK(priority)) != 0U) {
+		syslog_print(p_syslog, low_putchar);
+		low_putchar('\n');
+	}
+
+	SIL_UNL_INT();
+	return(E_OK);
+}
+
+/*
+ *  ログバッファからの読出し（受け口関数）
+ *
+ *  CPUロック状態や実行コンテキストによらず動作できるように実装してある．
+ */
+ER_UINT
+eSysLog_read(SYSLOG *p_syslog)
+{
+	ER_UINT	ercd;
+	SIL_PRE_LOC;
+
+	SIL_LOC_INT();
+
+	/*
+	 *  ログバッファからの取出し
+	 */
+	if (VAR_count > 0U) {
+		*p_syslog = VAR_logBuffer[VAR_head];
+		VAR_count--;
+		VAR_head++;
+		if (VAR_head >= ATTR_logBufferSize) {
+			VAR_head = 0U;
+		}
+		ercd = (ER_UINT) VAR_lost;
+		VAR_lost = 0U;
+	}
+	else {
+		ercd = E_OBJ;
+	}
+
+	SIL_UNL_INT();
+	return(ercd);
+}
+
+/* 
+ *  出力すべきログ情報の重要度の設定（受け口関数）
+ */
+ER
+eSysLog_mask(uint_t logMask, uint_t lowMask)
+{
+	SIL_PRE_LOC;
+
+	SIL_LOC_INT();
+	VAR_logMask = logMask;
+	VAR_lowMask = lowMask;
+	SIL_UNL_INT();
+	return(E_OK);
+}
+
+/*
+ *  ログバッファの状態参照（受け口関数）
+ */
+ER_UINT
+eSysLog_refer(T_SYSLOG_RLOG *pk_rlog)
+{
+	SIL_PRE_LOC;
+
+	SIL_LOC_INT();
+	pk_rlog->count = VAR_count;
+	pk_rlog->lost = VAR_lost;
+	pk_rlog->logmask = VAR_logMask;
+	pk_rlog->lowmask = VAR_lowMask;
+	SIL_UNL_INT();
+	return(E_OK);
+}
+
+/* 
+ *  低レベル出力によるすべてのログ情報の出力（受け口関数）
+ */
+ER
+eSysLog_flush(void)
+{
+	SYSLOG	logbuf;
+	ER_UINT	rercd;
+	SIL_PRE_LOC;
+
+	SIL_LOC_INT();
+
+	while ((rercd = eSysLog_read(&logbuf)) >= 0) {
+		if (rercd > 0) {
+			syslog_lostmsg((uint_t) rercd, low_putchar);
+		}
+		if (logbuf.logtype >= LOG_TYPE_COMMENT) {
+			syslog_print(&logbuf, low_putchar);
+			low_putchar('\n');
+		}
+	}
+
+	SIL_UNL_INT();
+	return(E_OK);
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLog.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLog.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLog.cdl	(revision 398)
@@ -0,0 +1,113 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *		システムログ機能のコンポーネント記述ファイル
+ */
+
+/*
+ *  システムログ出力に関する定義
+ */
+import_C("t_syslog.h");
+
+/*
+ *  低レベル出力のシグニチャ
+ */
+signature sPutLog {
+	void	putChar([in] char c);
+};
+
+/*
+ *  システムログ機能のシグニチャ
+ */
+signature sSysLog {
+	/*
+	 *  ログ情報の出力
+	 */
+	ER		write([in] uint_t priority, [in] const SYSLOG *p_syslog);
+
+	/*
+	 *  ログバッファからのログ情報の読出し
+	 */
+	ER_UINT	read([out] SYSLOG *p_syslog);
+
+	/*
+	 *  出力すべきログ情報の重要度の設定
+	 */
+	ER		mask([in] uint_t logMask, [in] uint_t lowMask);
+
+	/*
+	 *  低レベル出力によるすべてのログ情報の出力
+	 */
+	ER		refer([out] T_SYSLOG_RLOG *pk_rlog);
+
+	/*
+	 *  低レベル出力によるすべてのログ情報の出力
+	 */
+	ER		flush(void);
+};
+
+/*
+ *  システムログ機能のセルタイプ
+ */
+[singleton]
+celltype tSysLog {
+	entry	sSysLog		eSysLog;
+	call	sPutLog		cPutLog;		/* 低レベル出力との接続 */
+
+	attr {
+		uint_t	logBufferSize;			/* ログバッファサイズ */
+		uint_t	initLogMask = C_EXP("LOG_UPTO(LOG_DEBUG)");
+										/* ログバッファに記録すべき重要度 */
+		uint_t	initLowMask = C_EXP("LOG_UPTO(LOG_EMERG)");
+									   	/* 低レベル出力すべき重要度 */
+	};
+	var {
+		[size_is(logBufferSize)] SYSLOG	*logBuffer;	/* ログバッファ */
+		uint_t	count = 0;				/* ログバッファ中のログの数 */
+		uint_t	head = 0;				/* 先頭のログの格納位置 */
+		uint_t	tail = 0;				/* 次のログの格納位置 */
+		uint_t	lost = 0;				/* 失われたログの数 */
+		uint_t	logMask = initLogMask;	/* ログバッファに記録すべき重要度 */
+		uint_t	lowMask = initLowMask;	/* 低レベル出力すべき重要度 */
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLogAdapter.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLogAdapter.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLogAdapter.c	(revision 398)
@@ -0,0 +1,92 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *		C言語で記述されたアプリケーションから，TECSベースのシステムログ
+ *		機能を呼び出すためのアダプタ
+ */
+
+#include "tSysLogAdapter_tecsgen.h"
+#include "syslog.h"
+
+/*
+ *  ログ情報の出力
+ */
+ER
+syslog_wri_log(uint_t prio, const SYSLOG *p_syslog)
+{
+	return(cSysLog_write(prio, p_syslog));
+}
+
+/*
+ *  ログバッファからのログ情報の読出し
+ */
+ER_UINT
+syslog_rea_log(SYSLOG *p_syslog)
+{
+	return(cSysLog_read(p_syslog));
+}
+
+/*
+ *  出力すべきログ情報の重要度の設定
+ */
+ER
+syslog_msk_log(uint_t logmask, uint_t lowmask)
+{
+	return(cSysLog_mask(logmask, lowmask));
+}
+
+/*
+ *  ログバッファの状態参照
+ */
+ER
+syslog_ref_log(T_SYSLOG_RLOG *pk_rlog)
+{
+	return(cSysLog_refer(pk_rlog));
+}
+
+/*
+ *  低レベル出力によるすべてのログ情報の出力
+ */
+ER
+syslog_fls_log(void)
+{
+	return(cSysLog_flush());
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLogAdapter.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLogAdapter.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tSysLogAdapter.cdl	(revision 398)
@@ -0,0 +1,10 @@
+/*
+ *		C言語で記述されたアプリケーションから，TECSベースのシステムログ
+ *		機能を呼び出すためのアダプタ用セルタイプの定義
+ *
+ *  $Id$
+ */
+[singleton, active]
+celltype tSysLogAdapter {
+	call	sSysLog		cSysLog;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tTestService.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tTestService.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tTestService.c	(revision 398)
@@ -0,0 +1,179 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2016 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 "tTestService_tecsgen.h"
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+
+/*
+ *  テストプログラムの開始（受け口関数）
+ */
+void
+eTestService_start(const char *progname)
+{
+	syslog_1(LOG_NOTICE, "Test program: %s", progname);
+	VAR_check_count = 0U;
+}
+
+/*
+ *	自己診断関数の設定
+ */
+void
+eTestService_setBuiltInTest(Descriptor(sBuiltInTest) desc)
+{
+	cBuiltInTest_set_descriptor(desc);
+}
+
+/*
+ *	テストプログラムの終了
+ */
+static void
+test_finish(void)
+{
+	SIL_PRE_LOC;
+
+	SIL_LOC_INT();
+	(void) cSysLog_flush();
+	(void) ext_ker();
+
+	/* ここへ来ることはないはず */
+	SIL_UNL_INT();
+}
+
+/*
+ *	チェックポイント（受け口関数）
+ */
+void
+eTestService_checkPoint(uint_t count)
+{
+	bool_t	errorflag = false;
+	ER		rercd;
+	SIL_PRE_LOC;
+
+	/*
+	 *  割込みロック状態に
+	 */
+	SIL_LOC_INT();
+
+	/*
+	 *  シーケンスチェック
+	 */
+	if (++VAR_check_count == count) {
+		syslog_1(LOG_NOTICE, "Check point %d passed.", count);
+	}
+	else {
+		syslog_1(LOG_ERROR, "## Unexpected check point %d.\007", count);
+		errorflag = true;
+	}
+
+	/*
+	 *  カーネルの内部状態の検査
+	 */
+	if (is_cBuiltInTest_joined()) {
+		rercd = cBuiltInTest_builtInTest();
+		if (rercd < 0) {
+			syslog_2(LOG_ERROR, "## Internal inconsistency detected (%s, %d)."
+								"\007", itron_strerror(rercd), SERCD(rercd));
+			errorflag = true;
+		}
+	}
+
+	/*
+	 *  エラーが検出された場合は，テストプログラムを終了する．
+	 */
+	if (errorflag) {
+		test_finish();
+	}
+
+	/*
+	 *  割込みロック状態を解除
+	 */
+	SIL_UNL_INT();
+}
+
+/*
+ *	完了チェックポイント（受け口関数）
+ */
+void
+eTestService_finishPoint(uint_t count)
+{
+	if (count > 0U) {
+		eTestService_checkPoint(count);
+		syslog_0(LOG_NOTICE, "All check points passed.");
+	}
+	test_finish();
+}
+
+/*
+ *	条件チェックのエラー処理（受け口関数）
+ */
+void
+eTestService_assertError(const char *expr, const char *file, int_t line)
+{
+	syslog_3(LOG_ERROR, "## Assertion `%s' failed at %s:%u.\007",
+												expr, file, line);
+	test_finish();
+}
+
+/*
+ *	エラーコードチェックのエラー処理（受け口関数）
+ */
+void
+eTestService_serviceError(ER ercd, const char *file, int_t line)
+{
+	syslog_3(LOG_ERROR, "## Unexpected error %s detected at %s:%u.\007",
+										itron_strerror(ercd), file, line);
+	test_finish();
+}
+
+/*
+ *	エラーコードチェックのエラー処理（受け口関数）
+ */
+ER
+eTestService_getInterruptPriorityMask(PRI *p_ipm)
+{
+	return(get_ipm(p_ipm));
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tTestService.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tTestService.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tTestService.cdl	(revision 398)
@@ -0,0 +1,106 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2016 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$
+ */
+
+/*
+ *		テストプログラム用サービスのコンポーネント記述ファイル
+ */
+
+/*
+ *  自己診断サービスのシグニチャ
+ */
+signature sBuiltInTest {
+	ER		builtInTest(void);
+};
+
+/*
+ *  テストプログラム用サービスのシグニチャ
+ *
+ *  setBuiltInTestは，TECSの中では動的結合を使って実現すべきであるが，
+ *  C言語のアプリケーションから呼び出しやすくするために，TECSの作法違
+ *  反のコードとなっている．
+ *
+ *  getInterruptPriorityMaskは，そのままカーネルを呼び出すだけの関数で
+ *  ある．保護機能対応でないカーネルではそのままカーネルを呼べば良いが，
+ *  保護機能対応カーネルではカーネルを直接呼び出せるとは限らないので，
+ *  テストプログラム用サービス（カーネルドメインで動作することを想定）
+ *  として用意している．
+ */
+signature sTestService {
+	void	start([in, string] const char *progname);
+	void	setBuiltInTest([in] Descriptor(sBuiltInTest) desc);
+	void	checkPoint([in] uint_t count);
+	void	finishPoint([in] uint_t count);
+	void	assertError([in, string] const char *expr,
+							[in, string] const char *file, [in] int_t line);
+	void	serviceError([in] ER ercd,
+							[in, string] const char *file, [in] int_t line);
+	ER		getInterruptPriorityMask([out] PRI *p_ipm);
+};
+
+/*
+ *  テストプログラム用サービスのセルタイプ
+ */
+[singleton, active]
+celltype tTestService {
+	entry						sTestService	eTestService;
+	[dynamic, optional] call	sBuiltInTest	cBuiltInTest;
+	call						sSysLog			cSysLog;
+
+	var {
+		uint_t		check_count;	/* 最後に通過したチェックポイント */
+	};
+};
+
+/*
+ *  自己診断サービスのディスクリプタを取得するシグニチャ
+ */
+signature sGetBuiltInTestDescriptor {
+	ER		getDescriptor([out] Descriptor(sBuiltInTest) *p_desc,
+														[in] int_t i);
+};
+
+/*
+ *  自己診断サービスのディスクリプタを取得するセルタイプ
+ */
+[singleton, active]
+celltype tBuiltInTestAdaptor {
+	[ref_desc] call	sBuiltInTest				cBuiltInTest[];
+	entry			sGetBuiltInTestDescriptor	eGetBuiltInTestDescriptor;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/test_svc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/test_svc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/test_svc.h	(revision 398)
@@ -0,0 +1,189 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2005-2016 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_SVC_H
+#define TOPPERS_TEST_SVC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <kernel.h>
+#include "target_test.h"
+
+/*
+ *  TECSで記述されたテストプログラム用のサービスを直接呼び出すための定義
+ *
+ *  C言語で記述されたアプリケーションから，TECSで記述されたテストプログ
+ *  ラム用のサービスを呼び出すためには，アダプタを用いるのが正当な方法
+ *  であるが，テストプログラム用のサービスがシングルトンであることを利
+ *  用して直接呼び出す．
+ */
+extern void	tTestService_eTestService_start(const char *progname);
+extern void	tTestService_eTestService_setBuiltInTest(void *desc);
+extern void	tTestService_eTestService_checkPoint(uint_t count);
+extern void	tTestService_eTestService_finishPoint(uint_t count);
+extern void	tTestService_eTestService_assertError(const char *expr,
+											const char *file, int_t line);
+extern void	tTestService_eTestService_serviceError(ER ercd,
+											const char *file, int_t line);
+extern ER	tTestService_eTestService_getInterruptPriorityMask(PRI *p_ipm);
+
+/*
+ *  テストプログラムの開始
+ */
+Inline void
+test_start(const char *progname)
+{
+	tTestService_eTestService_start(progname);
+}
+
+/*
+ *	自己診断関数の設定
+ */
+Inline void
+set_bit_service(void *bit_service)
+{
+	tTestService_eTestService_setBuiltInTest(bit_service);
+}
+
+/*
+ *	チェックポイント
+ */
+Inline void
+check_point(uint_t count)
+{
+	tTestService_eTestService_checkPoint(count);
+}
+
+/*
+ *	完了チェックポイント
+ */
+Inline void
+check_finish(uint_t count)
+{
+	tTestService_eTestService_finishPoint(count);
+}
+
+/*
+ *	条件チェック
+ */
+Inline void
+check_assert_error(const char *expr, const char *file, int_t line)
+{
+	tTestService_eTestService_assertError(expr, file, line);
+}
+
+#define check_assert(exp) \
+	((void)(!(exp) ? (check_assert_error(#exp, __FILE__, __LINE__), 0) : 0))
+
+/*
+ *	エラーコードチェック
+ */
+Inline void
+check_ercd_error(ER ercd, const char *file, int_t line)
+{
+	tTestService_eTestService_serviceError(ercd, file, line);
+}
+
+#define check_ercd(ercd, expected_ercd) \
+	((void)((ercd) != (expected_ercd) ? \
+					(check_ercd_error(ercd, __FILE__, __LINE__), 0) : 0))
+
+/*
+ *	システム状態のチェック
+ */
+#define check_state(ctx, loc, dsp, dpn, ter) do {	\
+	check_assert(sns_ctx() == ctx);					\
+	check_assert(sns_loc() == loc);					\
+	check_assert(sns_dsp() == dsp);					\
+	check_assert(sns_dpn() == dpn);					\
+	check_assert(sns_ter() == ter);					\
+} while (false);
+
+/*
+ *	割込み優先度マスクのチェック
+ */
+#define check_ipm(ipm) do {												\
+	PRI		intpri;														\
+	ER		ercd;														\
+																		\
+	ercd = tTestService_eTestService_getInterruptPriorityMask(&intpri);	\
+	check_ercd(ercd, E_OK);												\
+	check_assert(intpri == ipm);										\
+} while (false);
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ *  TECSで記述された自己診断サービスを直接呼び出すための定義
+ *
+ *  C言語で記述されたアプリケーションから，TECSで記述された自己診断サー
+ *  ビスを呼び出すためには，アダプタを用いるのが正当な方法であるが，自
+ *  己診断サービスがシングルトンであることを利用して直接呼び出す．
+ */
+extern ER	tBuiltInTestAdaptor_eGetBuiltInTestDescriptor_getDescriptor
+												(void **p_desc, int_t i);
+
+Inline void *
+get_bit_kernel(void)
+{
+	void	*desc;
+
+	tBuiltInTestAdaptor_eGetBuiltInTestDescriptor_getDescriptor(&desc, 0);
+	return(desc);
+}
+
+Inline void *
+get_bit_mutex(void)
+{
+	void	*desc;
+
+	tBuiltInTestAdaptor_eGetBuiltInTestDescriptor_getDescriptor(&desc, 1);
+	return(desc);
+}
+
+#endif /* TOPPERS_TEST_SVC_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tlsf/README.md
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tlsf/README.md	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tlsf/README.md	(revision 398)
@@ -0,0 +1,92 @@
+# tlsf
+Two-Level Segregated Fit memory allocator implementation.
+Written by Matthew Conte (matt@baisoku.org).
+Released under the BSD license.
+
+Features
+--------
+  * O(1) cost for malloc, free, realloc, memalign
+  * Extremely low overhead per allocation (4 bytes)
+  * Low overhead per TLSF management of pools (~3kB)
+  * Low fragmentation
+  * Compiles to only a few kB of code and data
+  * Support for adding and removing memory pool regions on the fly
+
+Caveats
+-------
+  * Currently, assumes architecture can make 4-byte aligned accesses
+  * Not designed to be thread safe; the user must provide this
+
+Notes
+-----
+This code was based on the TLSF 1.4 spec and documentation found at:
+
+	http://www.gii.upv.es/tlsf/main/docs
+
+It also leverages the TLSF 2.0 improvement to shrink the per-block overhead from 8 to 4 bytes.
+
+History
+-------
+2016/04/10 - v3.1
+  * Code moved to github
+  * tlsfbits.h rolled into tlsf.c
+  * License changed to BSD
+
+2014/02/08 - v3.0
+  * This version is based on improvements from 3DInteractive GmbH
+  * Interface changed to allow more than one memory pool
+  * Separated pool handling from control structure (adding, removing, debugging)
+  * Control structure and pools can still be constructed in the same memory block
+  * Memory blocks for control structure and pools are checked for alignment
+  * Added functions to retrieve control structure size, alignment size, min and max block size, overhead of pool structure, and overhead of a single allocation
+  * Minimal Pool size is tlsf_block_size_min() + tlsf_pool_overhead()
+  * Pool must be empty when it is removed, in order to allow O(1) removal
+
+2011/10/20 - v2.0
+  * 64-bit support
+  * More compiler intrinsics for ffs/fls
+  * ffs/fls verification during TLSF creation in debug builds
+
+2008/04/04 - v1.9
+  * Add tlsf_heap_check, a heap integrity check
+  * Support a predefined tlsf_assert macro
+  * Fix realloc case where block should shrink; if adjacent block is in use, execution would go down the slow path
+
+2007/02/08 - v1.8
+  * Fix for unnecessary reallocation in tlsf_realloc
+
+2007/02/03 - v1.7
+  * tlsf_heap_walk takes a callback
+  * tlsf_realloc now returns NULL on failure
+  * tlsf_memalign optimization for 4-byte alignment
+  * Usage of size_t where appropriate
+
+2006/11/21 - v1.6
+  * ffs/fls broken out into tlsfbits.h
+  * tlsf_overhead queries per-pool overhead
+
+2006/11/07 - v1.5
+  * Smart realloc implementation
+  * Smart memalign implementation
+
+2006/10/11 - v1.4
+  * Add some ffs/fls implementations
+  * Minor code footprint reduction
+
+2006/09/14 - v1.3
+  * Profiling indicates heavy use of blocks of size 1-128, so implement small block handling
+  * Reduce pool overhead by about 1kb
+  * Reduce minimum block size from 32 to 12 bytes
+  * Realloc bug fix
+
+2006/09/09 - v1.2
+  * Add tlsf_block_size
+  * Static assertion mechanism for invariants
+  * Minor bugfixes 
+
+2006/09/01 - v1.1
+  * Add tlsf_realloc
+  * Add tlsf_walk_heap
+
+2006/08/25 - v1.0
+  * First release
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tlsf/tlsf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tlsf/tlsf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tlsf/tlsf.c	(revision 398)
@@ -0,0 +1,1253 @@
+#include <assert.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <t_syslog.h>
+
+#include "tlsf.h"
+
+#undef _MSC_VER
+
+#if defined(__cplusplus)
+#define tlsf_decl inline
+#else
+#define tlsf_decl static
+#endif
+
+/*
+** Architecture-specific bit manipulation routines.
+**
+** TLSF achieves O(1) cost for malloc and free operations by limiting
+** the search for a free block to a free list of guaranteed size
+** adequate to fulfill the request, combined with efficient free list
+** queries using bitmasks and architecture-specific bit-manipulation
+** routines.
+**
+** Most modern processors provide instructions to count leading zeroes
+** in a word, find the lowest and highest set bit, etc. These
+** specific implementations will be used when available, falling back
+** to a reasonably efficient generic implementation.
+**
+** NOTE: TLSF spec relies on ffs/fls returning value 0..31.
+** ffs/fls return 1-32 by default, returning 0 for error.
+*/
+
+/*
+** Detect whether or not we are building for a 32- or 64-bit (LP/LLP)
+** architecture. There is no reliable portable method at compile-time.
+*/
+#if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) \
+	|| defined (_WIN64) || defined (__LP64__) || defined (__LLP64__)
+#define TLSF_64BIT
+#endif
+
+/*
+** gcc 3.4 and above have builtin support, specialized for architecture.
+** Some compilers masquerade as gcc; patchlevel test filters them out.
+*/
+#if defined (__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
+	&& defined (__GNUC_PATCHLEVEL__)
+
+#if defined (__SNC__)
+/* SNC for Playstation 3. */
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+	const unsigned int reverse = word & (~word + 1);
+	const int bit = 32 - __builtin_clz(reverse);
+	return bit - 1;
+}
+
+#else
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+	return __builtin_ffs(word) - 1;
+}
+
+#endif
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+	const int bit = word ? 32 - __builtin_clz(word) : 0;
+	return bit - 1;
+}
+
+#elif defined (_MSC_VER) && (_MSC_VER >= 1400) && (defined (_M_IX86) || defined (_M_X64))
+/* Microsoft Visual C++ support on x86/X64 architectures. */
+
+#include <intrin.h>
+
+#pragma intrinsic(_BitScanReverse)
+#pragma intrinsic(_BitScanForward)
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+	unsigned long index;
+	return _BitScanReverse(&index, word) ? index : -1;
+}
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+	unsigned long index;
+	return _BitScanForward(&index, word) ? index : -1;
+}
+
+#elif defined (_MSC_VER) && defined (_M_PPC)
+/* Microsoft Visual C++ support on PowerPC architectures. */
+
+#include <ppcintrinsics.h>
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+	const int bit = 32 - _CountLeadingZeros(word);
+	return bit - 1;
+}
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+	const unsigned int reverse = word & (~word + 1);
+	const int bit = 32 - _CountLeadingZeros(reverse);
+	return bit - 1;
+}
+
+#elif defined (__ARMCC_VERSION)
+/* RealView Compilation Tools for ARM */
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+	const unsigned int reverse = word & (~word + 1);
+	const int bit = 32 - __clz(reverse);
+	return bit - 1;
+}
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+	const int bit = word ? 32 - __clz(word) : 0;
+	return bit - 1;
+}
+
+#elif defined (__ghs__)
+/* Green Hills support for PowerPC */
+
+#include <ppc_ghs.h>
+
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+	const unsigned int reverse = word & (~word + 1);
+	const int bit = 32 - __CLZ32(reverse);
+	return bit - 1;
+}
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+	const int bit = word ? 32 - __CLZ32(word) : 0;
+	return bit - 1;
+}
+
+#else
+/* Fall back to generic implementation. */
+
+tlsf_decl int tlsf_fls_generic(unsigned int word)
+{
+	int bit = 32;
+
+	if (!word) bit -= 1;
+	if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; }
+	if (!(word & 0xff000000)) { word <<= 8; bit -= 8; }
+	if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; }
+	if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; }
+	if (!(word & 0x80000000)) { word <<= 1; bit -= 1; }
+
+	return bit;
+}
+
+/* Implement ffs in terms of fls. */
+tlsf_decl int tlsf_ffs(unsigned int word)
+{
+	return tlsf_fls_generic(word & (~word + 1)) - 1;
+}
+
+tlsf_decl int tlsf_fls(unsigned int word)
+{
+	return tlsf_fls_generic(word) - 1;
+}
+
+#endif
+
+/* Possibly 64-bit version of tlsf_fls. */
+#if defined (TLSF_64BIT)
+tlsf_decl int tlsf_fls_sizet(size_t size)
+{
+	int high = (int)(size >> 32);
+	int bits = 0;
+	if (high)
+	{
+		bits = 32 + tlsf_fls(high);
+	}
+	else
+	{
+		bits = tlsf_fls((int)size & 0xffffffff);
+
+	}
+	return bits;
+}
+#else
+#define tlsf_fls_sizet tlsf_fls
+#endif
+
+#undef tlsf_decl
+
+/*
+** Constants.
+*/
+
+/* Public constants: may be modified. */
+enum tlsf_public
+{
+	/* log2 of number of linear subdivisions of block sizes. Larger
+	** values require more memory in the control structure. Values of
+	** 4 or 5 are typical.
+	*/
+	SL_INDEX_COUNT_LOG2 = 5,
+};
+
+/* Private constants: do not modify. */
+enum tlsf_private
+{
+#if defined (TLSF_64BIT)
+	/* All allocation sizes and addresses are aligned to 8 bytes. */
+	ALIGN_SIZE_LOG2 = 3,
+#else
+	/* All allocation sizes and addresses are aligned to 4 bytes. */
+	ALIGN_SIZE_LOG2 = 2,
+#endif
+	ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2),
+
+	/*
+	** We support allocations of sizes up to (1 << FL_INDEX_MAX) bits.
+	** However, because we linearly subdivide the second-level lists, and
+	** our minimum size granularity is 4 bytes, it doesn't make sense to
+	** create first-level lists for sizes smaller than SL_INDEX_COUNT * 4,
+	** or (1 << (SL_INDEX_COUNT_LOG2 + 2)) bytes, as there we will be
+	** trying to split size ranges into more slots than we have available.
+	** Instead, we calculate the minimum threshold size, and place all
+	** blocks below that size into the 0th first-level list.
+	*/
+
+#if defined (TLSF_64BIT)
+	/*
+	** TODO: We can increase this to support larger sizes, at the expense
+	** of more overhead in the TLSF structure.
+	*/
+	FL_INDEX_MAX = 32,
+#else
+	FL_INDEX_MAX = 30,
+#endif
+	SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2),
+	FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2),
+	FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1),
+
+	SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT),
+};
+
+/*
+** Cast and min/max macros.
+*/
+
+#define tlsf_cast(t, exp)	((t) (exp))
+#define tlsf_min(a, b)		((a) < (b) ? (a) : (b))
+#define tlsf_max(a, b)		((a) > (b) ? (a) : (b))
+
+/*
+** Set assert macro, if it has not been provided by the user.
+*/
+#if !defined (tlsf_assert)
+#define tlsf_assert assert
+#endif
+
+/*
+** Static assertion mechanism.
+*/
+
+#define _tlsf_glue2(x, y) x ## y
+#define _tlsf_glue(x, y) _tlsf_glue2(x, y)
+#define tlsf_static_assert(exp) \
+	typedef char _tlsf_glue(static_assert, __LINE__) [(exp) ? 1 : -1]
+
+/* This code has been tested on 32- and 64-bit (LP/LLP) architectures. */
+tlsf_static_assert(sizeof(int) * CHAR_BIT == 32);
+tlsf_static_assert(sizeof(size_t) * CHAR_BIT >= 32);
+tlsf_static_assert(sizeof(size_t) * CHAR_BIT <= 64);
+
+/* SL_INDEX_COUNT must be <= number of bits in sl_bitmap's storage type. */
+tlsf_static_assert(sizeof(unsigned int) * CHAR_BIT >= SL_INDEX_COUNT);
+
+/* Ensure we've properly tuned our sizes. */
+tlsf_static_assert(ALIGN_SIZE == SMALL_BLOCK_SIZE / SL_INDEX_COUNT);
+
+/*
+** Data structures and associated constants.
+*/
+
+/*
+** Block header structure.
+**
+** There are several implementation subtleties involved:
+** - The prev_phys_block field is only valid if the previous block is free.
+** - The prev_phys_block field is actually stored at the end of the
+**   previous block. It appears at the beginning of this structure only to
+**   simplify the implementation.
+** - The next_free / prev_free fields are only valid if the block is free.
+*/
+typedef struct block_header_t
+{
+	/* Points to the previous physical block. */
+	struct block_header_t* prev_phys_block;
+
+	/* The size of this block, excluding the block header. */
+	size_t size;
+
+	/* Next and previous free blocks. */
+	struct block_header_t* next_free;
+	struct block_header_t* prev_free;
+} block_header_t;
+
+/*
+** Since block sizes are always at least a multiple of 4, the two least
+** significant bits of the size field are used to store the block status:
+** - bit 0: whether block is busy or free
+** - bit 1: whether previous block is busy or free
+*/
+static const size_t block_header_free_bit = 1 << 0;
+static const size_t block_header_prev_free_bit = 1 << 1;
+
+/*
+** The size of the block header exposed to used blocks is the size field.
+** The prev_phys_block field is stored *inside* the previous free block.
+*/
+static const size_t block_header_overhead = sizeof(size_t);
+
+/* User data starts directly after the size field in a used block. */
+static const size_t block_start_offset =
+	offsetof(block_header_t, size) + sizeof(size_t);
+
+/*
+** A free block must be large enough to store its header minus the size of
+** the prev_phys_block field, and no larger than the number of addressable
+** bits for FL_INDEX.
+*/
+static const size_t block_size_min = 
+	sizeof(block_header_t) - sizeof(block_header_t*);
+static const size_t block_size_max = tlsf_cast(size_t, 1) << FL_INDEX_MAX;
+
+
+/* The TLSF control structure. */
+typedef struct control_t
+{
+	/* Empty lists point at this block to indicate they are free. */
+	block_header_t block_null;
+
+	/* Bitmaps for free lists. */
+	unsigned int fl_bitmap;
+	unsigned int sl_bitmap[FL_INDEX_COUNT];
+
+	/* Head of free lists. */
+	block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT];
+} control_t;
+
+/* A type used for casting when doing pointer arithmetic. */
+typedef ptrdiff_t tlsfptr_t;
+
+/*
+** block_header_t member functions.
+*/
+
+static size_t block_size(const block_header_t* block)
+{
+	return block->size & ~(block_header_free_bit | block_header_prev_free_bit);
+}
+
+static void block_set_size(block_header_t* block, size_t size)
+{
+	const size_t oldsize = block->size;
+	block->size = size | (oldsize & (block_header_free_bit | block_header_prev_free_bit));
+}
+
+static int block_is_last(const block_header_t* block)
+{
+	return block_size(block) == 0;
+}
+
+static int block_is_free(const block_header_t* block)
+{
+	return tlsf_cast(int, block->size & block_header_free_bit);
+}
+
+static void block_set_free(block_header_t* block)
+{
+	block->size |= block_header_free_bit;
+}
+
+static void block_set_used(block_header_t* block)
+{
+	block->size &= ~block_header_free_bit;
+}
+
+static int block_is_prev_free(const block_header_t* block)
+{
+	return tlsf_cast(int, block->size & block_header_prev_free_bit);
+}
+
+static void block_set_prev_free(block_header_t* block)
+{
+	block->size |= block_header_prev_free_bit;
+}
+
+static void block_set_prev_used(block_header_t* block)
+{
+	block->size &= ~block_header_prev_free_bit;
+}
+
+static block_header_t* block_from_ptr(const void* ptr)
+{
+	return tlsf_cast(block_header_t*,
+		tlsf_cast(unsigned char*, ptr) - block_start_offset);
+}
+
+static void* block_to_ptr(const block_header_t* block)
+{
+	return tlsf_cast(void*,
+		tlsf_cast(unsigned char*, block) + block_start_offset);
+}
+
+/* Return location of next block after block of given size. */
+static block_header_t* offset_to_block(const void* ptr, size_t size)
+{
+	return tlsf_cast(block_header_t*, tlsf_cast(tlsfptr_t, ptr) + size);
+}
+
+/* Return location of previous block. */
+static block_header_t* block_prev(const block_header_t* block)
+{
+	tlsf_assert(block_is_prev_free(block) && "previous block must be free");
+	return block->prev_phys_block;
+}
+
+/* Return location of next existing block. */
+static block_header_t* block_next(const block_header_t* block)
+{
+	block_header_t* next = offset_to_block(block_to_ptr(block),
+		block_size(block) - block_header_overhead);
+	tlsf_assert(!block_is_last(block));
+	return next;
+}
+
+/* Link a new block with its physical neighbor, return the neighbor. */
+static block_header_t* block_link_next(block_header_t* block)
+{
+	block_header_t* next = block_next(block);
+	next->prev_phys_block = block;
+	return next;
+}
+
+static void block_mark_as_free(block_header_t* block)
+{
+	/* Link the block to the next block, first. */
+	block_header_t* next = block_link_next(block);
+	block_set_prev_free(next);
+	block_set_free(block);
+}
+
+static void block_mark_as_used(block_header_t* block)
+{
+	block_header_t* next = block_next(block);
+	block_set_prev_used(next);
+	block_set_used(block);
+}
+
+static size_t align_up(size_t x, size_t align)
+{
+	tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two");
+	return (x + (align - 1)) & ~(align - 1);
+}
+
+static size_t align_down(size_t x, size_t align)
+{
+	tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two");
+	return x - (x & (align - 1));
+}
+
+static void* align_ptr(const void* ptr, size_t align)
+{
+	const tlsfptr_t aligned =
+		(tlsf_cast(tlsfptr_t, ptr) + (align - 1)) & ~(align - 1);
+	tlsf_assert(0 == (align & (align - 1)) && "must align to a power of two");
+	return tlsf_cast(void*, aligned);
+}
+
+/*
+** Adjust an allocation size to be aligned to word size, and no smaller
+** than internal minimum.
+*/
+static size_t adjust_request_size(size_t size, size_t align)
+{
+	size_t adjust = 0;
+	if (size && size < block_size_max)
+	{
+		const size_t aligned = align_up(size, align);
+		adjust = tlsf_max(aligned, block_size_min);
+	}
+	return adjust;
+}
+
+/*
+** TLSF utility functions. In most cases, these are direct translations of
+** the documentation found in the white paper.
+*/
+
+static void mapping_insert(size_t size, int* fli, int* sli)
+{
+	int fl, sl;
+	if (size < SMALL_BLOCK_SIZE)
+	{
+		/* Store small blocks in first list. */
+		fl = 0;
+		sl = tlsf_cast(int, size) / (SMALL_BLOCK_SIZE / SL_INDEX_COUNT);
+	}
+	else
+	{
+		fl = tlsf_fls_sizet(size);
+		sl = tlsf_cast(int, size >> (fl - SL_INDEX_COUNT_LOG2)) ^ (1 << SL_INDEX_COUNT_LOG2);
+		fl -= (FL_INDEX_SHIFT - 1);
+	}
+	*fli = fl;
+	*sli = sl;
+}
+
+/* This version rounds up to the next block size (for allocations) */
+static void mapping_search(size_t size, int* fli, int* sli)
+{
+	if (size >= SMALL_BLOCK_SIZE)
+	{
+		const size_t round = (1 << (tlsf_fls_sizet(size) - SL_INDEX_COUNT_LOG2)) - 1;
+		size += round;
+	}
+	mapping_insert(size, fli, sli);
+}
+
+static block_header_t* search_suitable_block(control_t* control, int* fli, int* sli)
+{
+	int fl = *fli;
+	int sl = *sli;
+
+	/*
+	** First, search for a block in the list associated with the given
+	** fl/sl index.
+	*/
+	unsigned int sl_map = control->sl_bitmap[fl] & (~0U << sl);
+	if (!sl_map)
+	{
+		/* No block exists. Search in the next largest first-level list. */
+		const unsigned int fl_map = control->fl_bitmap & (~0U << (fl + 1));
+		if (!fl_map)
+		{
+			/* No free blocks available, memory has been exhausted. */
+			return 0;
+		}
+
+		fl = tlsf_ffs(fl_map);
+		*fli = fl;
+		sl_map = control->sl_bitmap[fl];
+	}
+	tlsf_assert(sl_map && "internal error - second level bitmap is null");
+	sl = tlsf_ffs(sl_map);
+	*sli = sl;
+
+	/* Return the first block in the free list. */
+	return control->blocks[fl][sl];
+}
+
+/* Remove a free block from the free list.*/
+static void remove_free_block(control_t* control, block_header_t* block, int fl, int sl)
+{
+	block_header_t* prev = block->prev_free;
+	block_header_t* next = block->next_free;
+	tlsf_assert(prev && "prev_free field can not be null");
+	tlsf_assert(next && "next_free field can not be null");
+	next->prev_free = prev;
+	prev->next_free = next;
+
+	/* If this block is the head of the free list, set new head. */
+	if (control->blocks[fl][sl] == block)
+	{
+		control->blocks[fl][sl] = next;
+
+		/* If the new head is null, clear the bitmap. */
+		if (next == &control->block_null)
+		{
+			control->sl_bitmap[fl] &= ~(1 << sl);
+
+			/* If the second bitmap is now empty, clear the fl bitmap. */
+			if (!control->sl_bitmap[fl])
+			{
+				control->fl_bitmap &= ~(1 << fl);
+			}
+		}
+	}
+}
+
+/* Insert a free block into the free block list. */
+static void insert_free_block(control_t* control, block_header_t* block, int fl, int sl)
+{
+	block_header_t* current = control->blocks[fl][sl];
+	tlsf_assert(current && "free list cannot have a null entry");
+	tlsf_assert(block && "cannot insert a null entry into the free list");
+	block->next_free = current;
+	block->prev_free = &control->block_null;
+	current->prev_free = block;
+
+	tlsf_assert(block_to_ptr(block) == align_ptr(block_to_ptr(block), ALIGN_SIZE)
+		&& "block not aligned properly");
+	/*
+	** Insert the new block at the head of the list, and mark the first-
+	** and second-level bitmaps appropriately.
+	*/
+	control->blocks[fl][sl] = block;
+	control->fl_bitmap |= (1 << fl);
+	control->sl_bitmap[fl] |= (1 << sl);
+}
+
+/* Remove a given block from the free list. */
+static void block_remove(control_t* control, block_header_t* block)
+{
+	int fl, sl;
+	mapping_insert(block_size(block), &fl, &sl);
+	remove_free_block(control, block, fl, sl);
+}
+
+/* Insert a given block into the free list. */
+static void block_insert(control_t* control, block_header_t* block)
+{
+	int fl, sl;
+	mapping_insert(block_size(block), &fl, &sl);
+	insert_free_block(control, block, fl, sl);
+}
+
+static int block_can_split(block_header_t* block, size_t size)
+{
+	return block_size(block) >= sizeof(block_header_t) + size;
+}
+
+/* Split a block into two, the second of which is free. */
+static block_header_t* block_split(block_header_t* block, size_t size)
+{
+	/* Calculate the amount of space left in the remaining block. */
+	block_header_t* remaining =
+		offset_to_block(block_to_ptr(block), size - block_header_overhead);
+
+	const size_t remain_size = block_size(block) - (size + block_header_overhead);
+
+	tlsf_assert(block_to_ptr(remaining) == align_ptr(block_to_ptr(remaining), ALIGN_SIZE)
+		&& "remaining block not aligned properly");
+
+	tlsf_assert(block_size(block) == remain_size + size + block_header_overhead);
+	block_set_size(remaining, remain_size);
+	tlsf_assert(block_size(remaining) >= block_size_min && "block split with invalid size");
+
+	block_set_size(block, size);
+	block_mark_as_free(remaining);
+
+	return remaining;
+}
+
+/* Absorb a free block's storage into an adjacent previous free block. */
+static block_header_t* block_absorb(block_header_t* prev, block_header_t* block)
+{
+	tlsf_assert(!block_is_last(prev) && "previous block can't be last");
+	/* Note: Leaves flags untouched. */
+	prev->size += block_size(block) + block_header_overhead;
+	block_link_next(prev);
+	return prev;
+}
+
+/* Merge a just-freed block with an adjacent previous free block. */
+static block_header_t* block_merge_prev(control_t* control, block_header_t* block)
+{
+	if (block_is_prev_free(block))
+	{
+		block_header_t* prev = block_prev(block);
+		tlsf_assert(prev && "prev physical block can't be null");
+		tlsf_assert(block_is_free(prev) && "prev block is not free though marked as such");
+		block_remove(control, prev);
+		block = block_absorb(prev, block);
+	}
+
+	return block;
+}
+
+/* Merge a just-freed block with an adjacent free block. */
+static block_header_t* block_merge_next(control_t* control, block_header_t* block)
+{
+	block_header_t* next = block_next(block);
+	tlsf_assert(next && "next physical block can't be null");
+
+	if (block_is_free(next))
+	{
+		tlsf_assert(!block_is_last(block) && "previous block can't be last");
+		block_remove(control, next);
+		block = block_absorb(block, next);
+	}
+
+	return block;
+}
+
+/* Trim any trailing block space off the end of a block, return to pool. */
+static void block_trim_free(control_t* control, block_header_t* block, size_t size)
+{
+	tlsf_assert(block_is_free(block) && "block must be free");
+	if (block_can_split(block, size))
+	{
+		block_header_t* remaining_block = block_split(block, size);
+		block_link_next(block);
+		block_set_prev_free(remaining_block);
+		block_insert(control, remaining_block);
+	}
+}
+
+/* Trim any trailing block space off the end of a used block, return to pool. */
+static void block_trim_used(control_t* control, block_header_t* block, size_t size)
+{
+	tlsf_assert(!block_is_free(block) && "block must be used");
+	if (block_can_split(block, size))
+	{
+		/* If the next block is free, we must coalesce. */
+		block_header_t* remaining_block = block_split(block, size);
+		block_set_prev_used(remaining_block);
+
+		remaining_block = block_merge_next(control, remaining_block);
+		block_insert(control, remaining_block);
+	}
+}
+
+static block_header_t* block_trim_free_leading(control_t* control, block_header_t* block, size_t size)
+{
+	block_header_t* remaining_block = block;
+	if (block_can_split(block, size))
+	{
+		/* We want the 2nd block. */
+		remaining_block = block_split(block, size - block_header_overhead);
+		block_set_prev_free(remaining_block);
+
+		block_link_next(block);
+		block_insert(control, block);
+	}
+
+	return remaining_block;
+}
+
+static block_header_t* block_locate_free(control_t* control, size_t size)
+{
+	int fl = 0, sl = 0;
+	block_header_t* block = 0;
+
+	if (size)
+	{
+		mapping_search(size, &fl, &sl);
+		block = search_suitable_block(control, &fl, &sl);
+	}
+
+	if (block)
+	{
+		tlsf_assert(block_size(block) >= size);
+		remove_free_block(control, block, fl, sl);
+	}
+
+	return block;
+}
+
+static void* block_prepare_used(control_t* control, block_header_t* block, size_t size)
+{
+	void* p = 0;
+	if (block)
+	{
+		tlsf_assert(size && "size must be non-zero");
+		block_trim_free(control, block, size);
+		block_mark_as_used(block);
+		p = block_to_ptr(block);
+	}
+	return p;
+}
+
+/* Clear structure and point all empty lists at the null block. */
+static void control_construct(control_t* control)
+{
+	int i, j;
+
+	control->block_null.next_free = &control->block_null;
+	control->block_null.prev_free = &control->block_null;
+
+	control->fl_bitmap = 0;
+	for (i = 0; i < FL_INDEX_COUNT; ++i)
+	{
+		control->sl_bitmap[i] = 0;
+		for (j = 0; j < SL_INDEX_COUNT; ++j)
+		{
+			control->blocks[i][j] = &control->block_null;
+		}
+	}
+}
+
+/*
+** Debugging utilities.
+*/
+
+typedef struct integrity_t
+{
+	int prev_status;
+	int status;
+} integrity_t;
+
+#define tlsf_insist(x) { tlsf_assert(x); if (!(x)) { status--; } }
+
+static void integrity_walker(void* ptr, size_t size, int used, void* user)
+{
+	block_header_t* block = block_from_ptr(ptr);
+	integrity_t* integ = tlsf_cast(integrity_t*, user);
+	const int this_prev_status = block_is_prev_free(block) ? 1 : 0;
+	const int this_status = block_is_free(block) ? 1 : 0;
+	const size_t this_block_size = block_size(block);
+
+	int status = 0;
+	(void)used;
+	tlsf_insist(integ->prev_status == this_prev_status && "prev status incorrect");
+	tlsf_insist(size == this_block_size && "block size incorrect");
+
+	integ->prev_status = this_status;
+	integ->status += status;
+}
+
+int tlsf_check(tlsf_t tlsf)
+{
+	int i, j;
+
+	control_t* control = tlsf_cast(control_t*, tlsf);
+	int status = 0;
+
+	/* Check that the free lists and bitmaps are accurate. */
+	for (i = 0; i < FL_INDEX_COUNT; ++i)
+	{
+		for (j = 0; j < SL_INDEX_COUNT; ++j)
+		{
+			const int fl_map = control->fl_bitmap & (1 << i);
+			const int sl_list = control->sl_bitmap[i];
+			const int sl_map = sl_list & (1 << j);
+			const block_header_t* block = control->blocks[i][j];
+
+			/* Check that first- and second-level lists agree. */
+			if (!fl_map)
+			{
+				tlsf_insist(!sl_map && "second-level map must be null");
+			}
+
+			if (!sl_map)
+			{
+				tlsf_insist(block == &control->block_null && "block list must be null");
+				continue;
+			}
+
+			/* Check that there is at least one free block. */
+			tlsf_insist(sl_list && "no free blocks in second-level map");
+			tlsf_insist(block != &control->block_null && "block should not be null");
+
+			while (block != &control->block_null)
+			{
+				int fli, sli;
+				tlsf_insist(block_is_free(block) && "block should be free");
+				tlsf_insist(!block_is_prev_free(block) && "blocks should have coalesced");
+				tlsf_insist(!block_is_free(block_next(block)) && "blocks should have coalesced");
+				tlsf_insist(block_is_prev_free(block_next(block)) && "block should be free");
+				tlsf_insist(block_size(block) >= block_size_min && "block not minimum size");
+
+				mapping_insert(block_size(block), &fli, &sli);
+				tlsf_insist(fli == i && sli == j && "block size indexed in wrong list");
+				block = block->next_free;
+			}
+		}
+	}
+
+	return status;
+}
+
+#undef tlsf_insist
+
+static void default_walker(void* ptr, size_t size, int used, void* user)
+{
+	(void)user;
+	syslog(LOG_NOTICE, "\t%p %s size: %x (%p)", ptr, used ? "used" : "free", (unsigned int)size, block_from_ptr(ptr));
+}
+
+void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user)
+{
+	tlsf_walker pool_walker = walker ? walker : default_walker;
+	block_header_t* block =
+		offset_to_block(pool, -(int)block_header_overhead);
+
+	while (block && !block_is_last(block))
+	{
+		pool_walker(
+			block_to_ptr(block),
+			block_size(block),
+			!block_is_free(block),
+			user);
+		block = block_next(block);
+	}
+}
+
+size_t tlsf_block_size(void* ptr)
+{
+	size_t size = 0;
+	if (ptr)
+	{
+		const block_header_t* block = block_from_ptr(ptr);
+		size = block_size(block);
+	}
+	return size;
+}
+
+int tlsf_check_pool(pool_t pool)
+{
+	/* Check that the blocks are physically correct. */
+	integrity_t integ = { 0, 0 };
+	tlsf_walk_pool(pool, integrity_walker, &integ);
+
+	return integ.status;
+}
+
+/*
+** Size of the TLSF structures in a given memory block passed to
+** tlsf_create, equal to the size of a control_t
+*/
+size_t tlsf_size(void)
+{
+	return sizeof(control_t);
+}
+
+size_t tlsf_align_size(void)
+{
+	return ALIGN_SIZE;
+}
+
+size_t tlsf_block_size_min(void)
+{
+	return block_size_min;
+}
+
+size_t tlsf_block_size_max(void)
+{
+	return block_size_max;
+}
+
+/*
+** Overhead of the TLSF structures in a given memory block passed to
+** tlsf_add_pool, equal to the overhead of a free block and the
+** sentinel block.
+*/
+size_t tlsf_pool_overhead(void)
+{
+	return 2 * block_header_overhead;
+}
+
+size_t tlsf_alloc_overhead(void)
+{
+	return block_header_overhead;
+}
+
+pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
+{
+	block_header_t* block;
+	block_header_t* next;
+
+	const size_t pool_overhead = tlsf_pool_overhead();
+	const size_t pool_bytes = align_down(bytes - pool_overhead, ALIGN_SIZE);
+
+	if (((ptrdiff_t)mem % ALIGN_SIZE) != 0)
+	{
+		syslog(LOG_NOTICE, "tlsf_add_pool: Memory must be aligned by %u bytes.",
+			(unsigned int)ALIGN_SIZE);
+		return 0;
+	}
+
+	if (pool_bytes < block_size_min || pool_bytes > block_size_max)
+	{
+#if defined (TLSF_64BIT)
+		syslog(LOG_NOTICE, "tlsf_add_pool: Memory size must be between 0x%x and 0x%x00 bytes.", 
+			(unsigned int)(pool_overhead + block_size_min),
+			(unsigned int)((pool_overhead + block_size_max) / 256));
+#else
+		syslog(LOG_NOTICE, "tlsf_add_pool: Memory size must be between %u and %u bytes.", 
+			(unsigned int)(pool_overhead + block_size_min),
+			(unsigned int)(pool_overhead + block_size_max));
+#endif
+		return 0;
+	}
+
+	/*
+	** Create the main free block. Offset the start of the block slightly
+	** so that the prev_phys_block field falls outside of the pool -
+	** it will never be used.
+	*/
+	block = offset_to_block(mem, -(tlsfptr_t)block_header_overhead);
+	block_set_size(block, pool_bytes);
+	block_set_free(block);
+	block_set_prev_used(block);
+	block_insert(tlsf_cast(control_t*, tlsf), block);
+
+	/* Split the block to create a zero-size sentinel block. */
+	next = block_link_next(block);
+	block_set_size(next, 0);
+	block_set_used(next);
+	block_set_prev_free(next);
+
+	return mem;
+}
+
+void tlsf_remove_pool(tlsf_t tlsf, pool_t pool)
+{
+	control_t* control = tlsf_cast(control_t*, tlsf);
+	block_header_t* block = offset_to_block(pool, -(int)block_header_overhead);
+
+	int fl = 0, sl = 0;
+
+	tlsf_assert(block_is_free(block) && "block should be free");
+	tlsf_assert(!block_is_free(block_next(block)) && "next block should not be free");
+	tlsf_assert(block_size(block_next(block)) == 0 && "next block size should be zero");
+
+	mapping_insert(block_size(block), &fl, &sl);
+	remove_free_block(control, block, fl, sl);
+}
+
+/*
+** TLSF main interface.
+*/
+
+#if _DEBUG
+int test_ffs_fls()
+{
+	/* Verify ffs/fls work properly. */
+	int rv = 0;
+	rv += (tlsf_ffs(0) == -1) ? 0 : 0x1;
+	rv += (tlsf_fls(0) == -1) ? 0 : 0x2;
+	rv += (tlsf_ffs(1) == 0) ? 0 : 0x4;
+	rv += (tlsf_fls(1) == 0) ? 0 : 0x8;
+	rv += (tlsf_ffs(0x80000000) == 31) ? 0 : 0x10;
+	rv += (tlsf_ffs(0x80008000) == 15) ? 0 : 0x20;
+	rv += (tlsf_fls(0x80000008) == 31) ? 0 : 0x40;
+	rv += (tlsf_fls(0x7FFFFFFF) == 30) ? 0 : 0x80;
+
+#if defined (TLSF_64BIT)
+	rv += (tlsf_fls_sizet(0x80000000) == 31) ? 0 : 0x100;
+	rv += (tlsf_fls_sizet(0x100000000) == 32) ? 0 : 0x200;
+	rv += (tlsf_fls_sizet(0xffffffffffffffff) == 63) ? 0 : 0x400;
+#endif
+
+	if (rv)
+	{
+		syslog(LOG_NOTICE, "test_ffs_fls: %x ffs/fls tests failed.", rv);
+	}
+	return rv;
+}
+#endif
+
+tlsf_t tlsf_create(void* mem)
+{
+#if _DEBUG
+	if (test_ffs_fls())
+	{
+		return 0;
+	}
+#endif
+
+	if (((tlsfptr_t)mem % ALIGN_SIZE) != 0)
+	{
+		syslog(LOG_NOTICE, "tlsf_create: Memory must be aligned to %u bytes.",
+			(unsigned int)ALIGN_SIZE);
+		return 0;
+	}
+
+	control_construct(tlsf_cast(control_t*, mem));
+
+	return tlsf_cast(tlsf_t, mem);
+}
+
+tlsf_t tlsf_create_with_pool(void* mem, size_t bytes)
+{
+	tlsf_t tlsf = tlsf_create(mem);
+	tlsf_add_pool(tlsf, (char*)mem + tlsf_size(), bytes - tlsf_size());
+	return tlsf;
+}
+
+void tlsf_destroy(tlsf_t tlsf)
+{
+	/* Nothing to do. */
+	(void)tlsf;
+}
+
+pool_t tlsf_get_pool(tlsf_t tlsf)
+{
+	return tlsf_cast(pool_t, (char*)tlsf + tlsf_size());
+}
+
+void* tlsf_malloc(tlsf_t tlsf, size_t size)
+{
+	control_t* control = tlsf_cast(control_t*, tlsf);
+	const size_t adjust = adjust_request_size(size, ALIGN_SIZE);
+	block_header_t* block = block_locate_free(control, adjust);
+	return block_prepare_used(control, block, adjust);
+}
+
+void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t size)
+{
+	control_t* control = tlsf_cast(control_t*, tlsf);
+	const size_t adjust = adjust_request_size(size, ALIGN_SIZE);
+
+	/*
+	** We must allocate an additional minimum block size bytes so that if
+	** our free block will leave an alignment gap which is smaller, we can
+	** trim a leading free block and release it back to the pool. We must
+	** do this because the previous physical block is in use, therefore
+	** the prev_phys_block field is not valid, and we can't simply adjust
+	** the size of that block.
+	*/
+	const size_t gap_minimum = sizeof(block_header_t);
+	const size_t size_with_gap = adjust_request_size(adjust + align + gap_minimum, align);
+
+	/*
+	** If alignment is less than or equals base alignment, we're done.
+	** If we requested 0 bytes, return null, as tlsf_malloc(0) does.
+	*/
+	const size_t aligned_size = (adjust && align > ALIGN_SIZE) ? size_with_gap : adjust;
+
+	block_header_t* block = block_locate_free(control, aligned_size);
+
+	/* This can't be a static assert. */
+	tlsf_assert(sizeof(block_header_t) == block_size_min + block_header_overhead);
+
+	if (block)
+	{
+		void* ptr = block_to_ptr(block);
+		void* aligned = align_ptr(ptr, align);
+		size_t gap = tlsf_cast(size_t,
+			tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr));
+
+		/* If gap size is too small, offset to next aligned boundary. */
+		if (gap && gap < gap_minimum)
+		{
+			const size_t gap_remain = gap_minimum - gap;
+			const size_t offset = tlsf_max(gap_remain, align);
+			const void* next_aligned = tlsf_cast(void*,
+				tlsf_cast(tlsfptr_t, aligned) + offset);
+
+			aligned = align_ptr(next_aligned, align);
+			gap = tlsf_cast(size_t,
+				tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr));
+		}
+
+		if (gap)
+		{
+			tlsf_assert(gap >= gap_minimum && "gap size too small");
+			block = block_trim_free_leading(control, block, gap);
+		}
+	}
+
+	return block_prepare_used(control, block, adjust);
+}
+
+void tlsf_free(tlsf_t tlsf, void* ptr)
+{
+	/* Don't attempt to free a NULL pointer. */
+	if (ptr)
+	{
+		control_t* control = tlsf_cast(control_t*, tlsf);
+		block_header_t* block = block_from_ptr(ptr);
+		tlsf_assert(!block_is_free(block) && "block already marked as free");
+		block_mark_as_free(block);
+		block = block_merge_prev(control, block);
+		block = block_merge_next(control, block);
+		block_insert(control, block);
+	}
+}
+
+/*
+** The TLSF block information provides us with enough information to
+** provide a reasonably intelligent implementation of realloc, growing or
+** shrinking the currently allocated block as required.
+**
+** This routine handles the somewhat esoteric edge cases of realloc:
+** - a non-zero size with a null pointer will behave like malloc
+** - a zero size with a non-null pointer will behave like free
+** - a request that cannot be satisfied will leave the original buffer
+**   untouched
+** - an extended buffer size will leave the newly-allocated area with
+**   contents undefined
+*/
+void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size)
+{
+	control_t* control = tlsf_cast(control_t*, tlsf);
+	void* p = 0;
+
+	/* Zero-size requests are treated as free. */
+	if (ptr && size == 0)
+	{
+		tlsf_free(tlsf, ptr);
+	}
+	/* Requests with NULL pointers are treated as malloc. */
+	else if (!ptr)
+	{
+		p = tlsf_malloc(tlsf, size);
+	}
+	else
+	{
+		block_header_t* block = block_from_ptr(ptr);
+		block_header_t* next = block_next(block);
+
+		const size_t cursize = block_size(block);
+		const size_t combined = cursize + block_size(next) + block_header_overhead;
+		const size_t adjust = adjust_request_size(size, ALIGN_SIZE);
+
+		tlsf_assert(!block_is_free(block) && "block already marked as free");
+
+		/*
+		** If the next block is used, or when combined with the current
+		** block, does not offer enough space, we must reallocate and copy.
+		*/
+		if (adjust > cursize && (!block_is_free(next) || adjust > combined))
+		{
+			p = tlsf_malloc(tlsf, size);
+			if (p)
+			{
+				const size_t minsize = tlsf_min(cursize, size);
+				memcpy(p, ptr, minsize);
+				tlsf_free(tlsf, ptr);
+			}
+		}
+		else
+		{
+			/* Do we need to expand to the next block? */
+			if (adjust > cursize)
+			{
+				block_merge_next(control, block);
+				block_mark_as_used(block);
+			}
+
+			/* Trim the resulting block and return the original pointer. */
+			block_trim_used(control, block, adjust);
+			p = ptr;
+		}
+	}
+
+	return p;
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tlsf/tlsf.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tlsf/tlsf.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/syssvc/tlsf/tlsf.h	(revision 398)
@@ -0,0 +1,90 @@
+#ifndef INCLUDED_tlsf
+#define INCLUDED_tlsf
+
+/*
+** Two Level Segregated Fit memory allocator, version 3.1.
+** Written by Matthew Conte
+**	http://tlsf.baisoku.org
+**
+** Based on the original documentation by Miguel Masmano:
+**	http://www.gii.upv.es/tlsf/main/docs
+**
+** This implementation was written to the specification
+** of the document, therefore no GPL restrictions apply.
+** 
+** Copyright (c) 2006-2016, Matthew Conte
+** 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 name of the copyright holder nor the
+**       names of its contributors may be used to endorse or promote products
+**       derived from this software without specific prior written permission.
+** 
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL MATTHEW CONTE BE LIABLE FOR ANY
+** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (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 <stddef.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* tlsf_t: a TLSF structure. Can contain 1 to N pools. */
+/* pool_t: a block of memory that TLSF can manage. */
+typedef void* tlsf_t;
+typedef void* pool_t;
+
+/* Create/destroy a memory pool. */
+tlsf_t tlsf_create(void* mem);
+tlsf_t tlsf_create_with_pool(void* mem, size_t bytes);
+void tlsf_destroy(tlsf_t tlsf);
+pool_t tlsf_get_pool(tlsf_t tlsf);
+
+/* Add/remove memory pools. */
+pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes);
+void tlsf_remove_pool(tlsf_t tlsf, pool_t pool);
+
+/* malloc/memalign/realloc/free replacements. */
+void* tlsf_malloc(tlsf_t tlsf, size_t bytes);
+void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t bytes);
+void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size);
+void tlsf_free(tlsf_t tlsf, void* ptr);
+
+/* Returns internal block size, not original request size */
+size_t tlsf_block_size(void* ptr);
+
+/* Overheads/limits of internal structures. */
+size_t tlsf_size(void);
+size_t tlsf_align_size(void);
+size_t tlsf_block_size_min(void);
+size_t tlsf_block_size_max(void);
+size_t tlsf_pool_overhead(void);
+size_t tlsf_alloc_overhead(void);
+
+/* Debugging. */
+typedef void (*tlsf_walker)(void* ptr, size_t size, int used, void* user);
+void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user);
+/* Returns nonzero if any internal consistency check fails. */
+int tlsf_check(tlsf_t tlsf);
+int tlsf_check_pool(pool_t pool);
+
+#if defined(__cplusplus)
+};
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/MANIFEST
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/MANIFEST	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/MANIFEST	(revision 398)
@@ -0,0 +1,34 @@
+PACKAGE asp_target_rsk_rx_hew
+
+E_PACKAGE
+MANIFEST
+asm_config.cfg
+gr_sakura.h
+sectrx.inc
+target.tf
+target_asm_config.tf
+target_ccrx_echonet.tf
+target_cfg1_out.h
+target_check.tf
+target_kernel_impl.c
+target_kernel_impl.h
+target_sym.def
+target_kernel.h
+target_offset.tf
+target_rename.def
+target_rename.h
+target_serial.c
+target_serial.cfg
+target_serial.h
+target_sil.h
+target_stddef.h
+target_support.src
+target_syssvc.h
+target_test.h
+target_timer.c
+target_timer.cfg
+target_timer.h
+target_unrename.h
+tinet_target_config.c
+tinet_target_config.h
+tinet_target_defs.h
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/Makefile.target
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/Makefile.target	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/Makefile.target	(revision 398)
@@ -0,0 +1,84 @@
+#
+#		Makefileのターゲット依存部（GR-SAKURA用）
+#
+
+#
+#  ボード名，プロセッサ名，開発環境名の定義
+#
+BOARD = gr_sakura
+PRC = rx630
+TOOL = gcc
+
+#
+#  コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(TARGETDIR) -I$(SRCDIR)/mbed
+
+#
+#  カーネルに関する定義
+#
+KERNEL_DIRS := $(KERNEL_DIRS) $(TARGETDIR)
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS) target_kernel_impl.o target_support.o target_timer.o
+
+#
+#  システムサービスに関する定義
+#
+SYSSVC_DIRS := $(SYSSVC_DIRS) $(SRCDIR)/mbed $(SRCDIR)/syssvc/tlsf
+SYSSVC_COBJS := $(SYSSVC_COBJS) musl_adapter.o tlsf.o
+
+#
+#  コンフィギュレータ関係の変数の定義
+#
+CFG_TABS := $(CFG_TABS) --symval-table $(TARGETDIR)/target_sym.def
+
+#
+#  トレースログ記録のサンプルコードに関する定義
+#
+ifeq ($(ENABLE_TRACE),true)
+	COPTS := $(COPTS) -DTOPPERS_ENABLE_TRACE
+	SYSSVC_DIRS := $(SYSSVC_DIRS) $(SRCDIR)/arch/tracelog
+endif
+
+#
+#  各セグメントの開始アドレスの定義
+#
+#TEXT_START_ADDRESS = 00010000
+#DATA_START_ADDRESS = 00100000
+
+#
+#  リンカスクリプトの定義
+#
+LDSCRIPT = $(TARGETDIR)/gr_sakura.ld
+
+#
+#  スタートアップモジュールに関する定義
+#
+#  m68kelf.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) $(MAKEDEP_OPTS) \
+		-O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+LDFLAGS := -nostdlib $(LDFLAGS)
+CFG1_OUT_LDFLAGS := -nostdlib $(CFG1_OUT_LDFLAGS)
+LIBS := $(LIBS) -lgcc
+CFG2_OUT_SRCS := $(CFG2_OUT_SRCS) kernel_cfg_asm.S
+
+#
+#  依存関係の定義
+#
+cfg1_out.c: $(TARGETDIR)/target_sym.def
+kernel_cfg.timestamp: $(TARGETDIR)/target_kernel.trb
+$(OBJFILE): $(TARGETDIR)/target_check.trb
+
+#
+#  プロセッサ依存部のインクルード
+#
+include $(SRCDIR)/arch/$(PRC)_$(TOOL)/Makefile.prc
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/Makefile.tinet
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/Makefile.tinet	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/Makefile.tinet	(revision 398)
@@ -0,0 +1,41 @@
+#
+#   TINET (TCP/IP Protocol Stack)
+#  
+#   Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+#                    Tomakomai National College of Technology, JAPAN
+# 
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次の条件を満たすこと．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+# 
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#  
+#   @(#) $Id$
+#
+
+#
+#  Makefile.tinet のシステム依存部分（GR-SAKURA用）
+
+ifeq ($(NET_IF),ether)
+
+	TINET_COBJS := $(TINET_COBJS) tinet_target_config.o
+
+endif
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/PinNames.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/PinNames.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/PinNames.h	(revision 398)
@@ -0,0 +1,74 @@
+#ifndef MBED_PINNAMES_H
+#define MBED_PINNAMES_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+	P20, P21, P22, P23, P24, P25, P32, P33, PC2, PC3, PC4, PC5, PC6, PC7,
+	P50, P52, PA0, PA1, PA2, PA6, PA7,
+	AN0, AN1, AN2, AN3, AN4, AN5, AN6, AN7,
+
+	D0 = P21,
+	D1 = P20,
+	D2 = P22,
+	D3 = P23,
+	D4 = P24,
+	D5 = P25,
+	D6 = P32,
+	D7 = P33,
+	D8 = PC2,
+	D9 = PC3,
+	D10 = PC4,
+	D11 = PC6,
+	D12 = PC7,
+	D13 = PC5,
+
+	A0 = AN0,
+	A1 = AN1,
+	A2 = AN2,
+	A3 = AN3,
+	A4 = AN4,
+	A5 = AN5,
+	A6 = AN6,
+	A7 = AN7,
+
+	I2C_SCL = P52,
+	I2C_SDA = P50,
+
+	PIN_LED0 = PA0,
+	PIN_LED1 = PA1,
+	PIN_LED2 = PA2,
+	PIN_LED3 = PA6,
+	PIN_SW = PA7,
+
+	NC = (int)0xFFFFFFFF
+} PinName;
+
+#define LED_RED			PIN_LED0
+#define LED_GREEN		PIN_LED1
+#define LED_BLUE		PIN_LED2
+#define LED_USER		PIN_LED3
+#define USER_BUTTON0	PIN_SW
+
+typedef enum {
+	PIN_INPUT,
+	PIN_OUTPUT
+} PinDirection;
+
+typedef enum {
+	PullUp = 2,
+	PullDown = 3,
+	PullNone = 0,
+	OpenDrain = 4,
+	PullDefault = PullNone
+} PinMode;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/gr_sakura.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/gr_sakura.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/gr_sakura.h	(revision 398)
@@ -0,0 +1,81 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* GR-SAKURA用ヘッダファル */
+
+#ifndef	TOPPERS_GRSAKURA_H
+#define	TOPPERS_GRSAKURA_H
+
+
+/*
+ *  MCU依存情報の読み込み
+ */
+#include "rx630.h"
+
+/*
+ *  クロック設定
+ */
+
+/*
+ *  システムクロックICLK(kHz)
+ *
+ *  CPU，DTC，DMACA，ETHERC，EDMAC，ROM，RAM用
+ *  
+ */
+#define FREQ_ICLK  (96000U)
+
+/*
+ *  クロックPCLK(kHz)
+ *
+ *  タイマ，シリアルなど周辺モジュール用
+ */
+#define FREQ_PCLK  (48000U)
+
+/*
+ *  ボーレート設定
+ */
+#define UART_BAUDRATE		115200
+
+/*
+ *  クロックソース
+ */
+#define UART_CLKSRC			CLK_F1
+
+#endif	/* TOPPERS_GRSAKURA_H */
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/gr_sakura.ld
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/gr_sakura.ld	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/gr_sakura.ld	(revision 398)
@@ -0,0 +1,147 @@
+MEMORY
+{
+	RAM : ORIGIN = 0x0, LENGTH = 131072
+	ROM : ORIGIN = 0xFFF00000, LENGTH = 1048576
+}
+
+SECTIONS
+{
+	.fvectors 0xFFFFFF80 : AT (0xFFFFFF80)
+	{
+		KEEP(*(.fvectors))
+	} > ROM
+	.text 0xFFF00000 : AT (0xFFF00000)
+	{
+		*(.text)
+		*(.text.*)
+		*(P)
+		etext = .;
+	} > ROM
+	.rvectors : 
+	{
+		_rvectors_start = .;
+		KEEP(*(.rvectors))
+		_rvectors_end = .;
+	} > ROM
+	.init : 
+	{
+		*(.init)
+		__preinit_array_start = .;
+		*(.preinit_array)
+		__preinit_array_end = .;
+		__init_array_start = (. + 3) & ~ 3;
+		*(.init_array)
+		*(SORT(.init_array.*))
+		__init_array_end = .;
+		__fini_array_start = .;
+		*(.fini_array)
+		*(SORT(.fini_array.*))
+		__fini_array_end = .;
+	} > ROM
+	.fini : 
+	{
+		*(.fini)
+	} > ROM
+	.got : 
+	{
+		*(.got)
+		*(.got.plt)
+	} > ROM
+	.rodata : 
+	{
+		_brodata = .;
+		*(.rodata)
+		*(.rodata.*)
+		*(C_1)
+		*(C_2)
+		*(C)
+		_mrb_preset_const_start = .;
+		*(.mrb_preset_const)
+		_mrb_preset_const_end = .;
+		_erodata = .;
+	} > ROM
+	.eh_frame_hdr : 
+	{
+		*(.eh_frame_hdr)
+	} > ROM
+	.eh_frame : 
+	{
+		*(.eh_frame)
+	} > ROM
+	.jcr : 
+	{
+		*(.jcr)
+	} > ROM
+	.tors : 
+	{
+		__CTOR_LIST__ = .;
+		. = ALIGN(2);
+		___ctors = .;
+		*(.ctors)
+		___ctors_end = .;
+		__CTOR_END__ = .;
+		__DTOR_LIST__ = .;
+		___dtors = .;
+		*(.dtors)
+		___dtors_end = .;
+		__DTOR_END__ = .;
+		. = ALIGN(2);
+		_mdata = .;
+	} > ROM
+	.istack 0x00000 (NOLOAD) : AT (0x00000)
+	{
+		*(SI)
+		_istack = .;
+	} > RAM
+	.ustack 0x00400 (NOLOAD) : AT (0x00400)
+	{
+		_heap_stop = .;
+		*(SU)
+		_ustack = .;
+	} > RAM
+	.gcc_exc :
+	{
+		*(.gcc_exc)
+	} > RAM
+	.data : AT (_mdata)
+	{
+		_data = .;
+		*(.data)
+		*(.data.*)
+		. = ALIGN(4);
+		*(D)
+		*(D_1)
+		. = ALIGN(2);
+		*(D_2)
+		_mrb_preset_data_start = .;
+		*(.mrb_preset_data)
+		_mrb_preset_data_end = .;
+		_edata = .;
+	} > RAM
+	.bss : 
+	{
+		_bss = .;
+		*(.bss)
+		*(.bss.**)
+		*(COMMON)
+		. = ALIGN(4);
+		*(B)
+		*(B_1)
+		. = ALIGN(2);
+		*(B_2)
+		_ebss = .;
+		. = ALIGN(4);
+		_end = .;
+	} > RAM
+	.eth_memory (NOLOAD) : 
+	{
+		. = ALIGN(32);
+		KEEP(*(ETH_MEMORY))
+	} > RAM
+	.heap (NOLOAD) :
+	{
+		*(.heap*)
+		__HeapBase = .;
+	} > RAM
+	__HeapLimit = ORIGIN(RAM) + LENGTH(RAM);
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/sectrx.inc
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/sectrx.inc	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/sectrx.inc	(revision 398)
@@ -0,0 +1,130 @@
+;*
+;*  TOPPERS/ASP Kernel
+;*      Toyohashi Open Platform for Embedded Real-Time Systems/
+;*      Advanced Standard Profile Kernel
+;* 
+;*  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+;* 
+;*  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+;*  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+;*  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+;*  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+;*      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+;*      スコード中に含まれていること．
+;*  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+;*      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+;*      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+;*      の無保証規定を掲載すること．
+;*  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+;*      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+;*      と．
+;*    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+;*        作権表示，この利用条件および下記の無保証規定を掲載すること．
+;*    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+;*        報告すること．
+;*  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+;*      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+;*      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+;*      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+;*      免責すること．
+;* 
+;*  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+;*  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+;*  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+;*  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+;*  の責任を負わない．
+;* 
+;*  @(#) $Id$
+;* 
+
+;
+;  ターゲットシステム依存セクション定義ファイル(スターターキット用)
+;
+
+;
+;  セクションの定義
+;
+;  セクションのアドレス定義はHEW上の最適化リンカの
+;  オプションにて実施する.
+;
+
+	;
+	;  初期値有りデータ領域のセクション
+	;
+	;  00000000h - 00020000h
+	;
+	.section	D, ROMDATA
+	.section	D_2, ROMDATA, ALIGN = 2
+	.section	D_1, ROMDATA
+
+
+	;
+	;  初期値無しデータ領域のセクション
+	;
+	;  00000000h - 00020000h
+	;
+	.section	B, DATA, ALIGN = 4
+	.section	B_2, DATA, ALIGN = 2
+	.section	B_1, DATA
+	.section	W, ROMDATA,ALIGN = 4
+	.section	W_1, ROMDATA
+	.section	W_2, ROMDATA, ALIGN = 2
+
+
+	;
+	;  カーネルスタック領域のセクション
+	;
+	;  00000000h - 00020000h
+	;
+	;  以下.blkb命令で確保しているカーネルスタック領域のサイズを
+	;  変更する場合は, target_kernel_impl.hのDEFAULT_ISTKSZの値を, 同じ
+	;  値に変更すること.
+	;
+;	.section	SI, DATA, ALIGN = 4
+;	.global _DEFAULT_ISTACK
+;_DEFAULT_ISTACK:
+;	.blkb		DEFAULT_ISTKSZ
+;	.global DEFAULT_ISTACK_TOP
+;DEFAULT_ISTACK_TOP:
+
+	;
+	;  定数領域のセクション
+	;
+	;  00100000h - 00107FFFh
+	;
+	.section	C, ROMDATA, ALIGN = 4
+	.section	C_2, ROMDATA, ALIGN = 2
+	.section	C_1, ROMDATA
+
+	;
+	;  初期値有りデータ領域の初期値
+	;
+	;  00100000h - 00107FFFh
+	;
+	.section	R, DATA, ALIGN = 4
+	.section	R_2, DATA, ALIGN = 2
+	.section	R_1, DATA
+
+	;
+	;  可変ベクタテーブル領域のセクション
+	;
+	;  00100000h - 00107FFFh
+	;
+	.section	.fvectors, ROMDATA, ALIGN = 4
+	.global VVECTOR_TOP
+VVECTOR_TOP:
+
+	;
+	;  プログラム領域のセクション
+	;
+	;  FFE80000h - FFFFFF7Fh
+	;
+	.section	P, CODE
+
+	;
+	;  固定ベクタテーブル領域のセクション
+	;
+	;  FFFFFF80h - FFFFFFFFh
+	;
+	.section	FVECT, ROMDATA, ALIGN = 4
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tPutLogGRSakura.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tPutLogGRSakura.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tPutLogGRSakura.c	(revision 398)
@@ -0,0 +1,71 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2007-2016 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 "tPutLogGRSakura_tecsgen.h"
+
+/*
+ *  システムログの低レベル出力のための初期化
+ *
+ *  初期化ルーチンを呼び出すより前に初期化するために，カーネルのターゲッ
+ *  ト依存部から直接呼び出すための関数．
+ */
+void
+tPutLogGRSakura_initialize(void)
+{
+	cSIOPort_open();
+}
+
+/*
+ *  システムログの低レベル出力のための文字出力（受け口関数）
+ *
+ *  SIOポートに文字が送信できるまでポーリングする．
+ */
+void
+ePutLog_putChar(char c)
+{
+	if(c == '\n'){
+		while(!cSIOPort_putChar('\r'));
+	}
+	while(!cSIOPort_putChar(c));
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tPutLogGRSakura.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tPutLogGRSakura.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tPutLogGRSakura.cdl	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *		システムログの低レベル出力のコンポーネント記述
+ */
+
+/*
+ *  システムログの低レベル出力のセルタイプ
+ */
+[singleton]
+celltype tPutLogGRSakura {
+	entry	sPutLog		ePutLog;
+	call	sSIOPort	cSIOPort;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tSIOPortGRSakura.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tSIOPortGRSakura.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tSIOPortGRSakura.cdl	(revision 398)
@@ -0,0 +1,180 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2017      by Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  $Id$
+ */
+
+/*
+ *		シリアルインタフェースドライバのターゲット依存部（GR-SAKURA用）
+ *		のコンポーネント記述
+ */
+
+/*
+ *  GR-SAKURAとRX631/RX63Nに関する定義
+ */
+import_C("gr_sakura.h");
+import_C("device.h");
+
+/*
+ *  FIFO内蔵シリアルコミュニケーションインタフェース用 簡易SIOドライバ
+ */
+import("tMbedSerial.cdl");
+
+/*
+ *  シリアルインタフェースドライバのターゲット依存部の本体（シリアルイ
+ *  ンタフェースドライバとSIOドライバを接続する部分）のセルタイプ
+ */
+celltype tSIOPortGRSakuraMain {
+	/*
+	 *  シリアルインタフェースドライバとの結合
+	 */
+	[inline] entry		sSIOPort	eSIOPort;
+	[optional] call		siSIOCBR	ciSIOCBR;
+
+	/*
+	 *  SIOドライバとの結合
+	 */
+	call			sSIOPort	cSIOPort;
+	[inline] entry	siSIOCBR	eiSIOCBR;
+};
+
+/*
+ *  シリアルインタフェースドライバのターゲット依存部（複合コンポーネン
+ *  ト）のセルタイプ
+ */
+composite tSIOPortGRSakura {
+	/*
+	 *  シリアルインタフェースドライバとの結合
+	 */
+	entry				sSIOPort	eSIOPort;
+	[optional] call		siSIOCBR	ciSIOCBR;
+
+	/*
+	 *  属性の定義
+	 */
+	attr {
+		int32_t tx;								/* 送信Pin */
+		int32_t rx;								/* 受信Pin */
+		uint32_t	baudRate = 115200;			/* ボーレートの設定値 */
+	};
+
+	/*
+	 *  SIOドライバ
+	 */
+	cell tMbedSerial MbedSerial {
+		tx          = composite.tx;
+		rx          = composite.rx;
+		baudRate    = composite.baudRate;
+		ciSIOCBR    = SIOPortMain.eiSIOCBR;
+	};
+
+	/*
+	 *  シリアルインタフェースドライバのターゲット依存部の本体
+	 */
+	cell tSIOPortGRSakuraMain SIOPortMain {
+		ciSIOCBR            => composite.ciSIOCBR;
+		cSIOPort            = MbedSerial.eSIOPort;
+	};
+	composite.eSIOPort => SIOPortMain.eSIOPort;
+};
+
+/*
+ *  シリアルインタフェースドライバのターゲット依存部のプロトタイプ
+ *
+ *  サンプルプログラムが使うポートが，SIOPortTarget1に固定されているた
+ *  め，ポート1とポート3を入れ換えている．具体的には，SIOPortTarget1は
+ *  MbedSerialのチャネル2（チャネル番号は0から始まるので，ポート3のこと）に，
+ *  SIOPortTarget3はMbedSerialのチャネル0につながっている．
+ */
+[prototype]
+cell tSIOPortGRSakura SIOPortTarget1 {
+	/* 属性の設定 */
+	tx = C_EXP("P20");		/* PIN_IO1 */
+	rx = C_EXP("P21");		/* PIN_IO0 */
+};
+
+[prototype]
+cell tSIOPortGRSakura SIOPortTarget2 {
+	/* 属性の設定 */
+	tx = C_EXP("P32");		/* PIN_IO6 */
+	rx = C_EXP("P33");		/* PIN_IO7 */
+};
+
+[prototype]
+cell tSIOPortGRSakura SIOPortTarget3 {
+	/* 属性の設定 */
+	tx = C_EXP("P50");		/* PIN_IO24 */
+	rx = C_EXP("P52");		/* PIN_IO26 */
+};
+
+[prototype]
+cell tSIOPortGRSakura SIOPortTarget4 {
+	/* 属性の設定 */
+	tx = C_EXP("P23");		/* PIN_IO3 */
+	rx = C_EXP("P25");		/* PIN_IO5 */
+};
+
+[prototype]
+cell tSIOPortGRSakura SIOPortTarget5 {
+	/* 属性の設定 */
+	tx = C_EXP("PC3");		/* PIN_IO9 */
+	rx = C_EXP("PC2");		/* PIN_IO8 */
+};
+
+[prototype]
+cell tSIOPortGRSakura SIOPortTarget6 {
+	/* 属性の設定 */
+	tx = C_EXP("PC7");		/* PIN_IO12 */
+	rx = C_EXP("PC6");		/* PIN_IO11 */
+};
+
+[prototype]
+cell tSIOPortGRSakura SIOPortTarget7 {
+	/* 属性の設定 */
+	tx = C_EXP("P26");		/* PIN_IO58 */
+	rx = C_EXP("P30");		/* PIN_IO60 */
+};
+
+[prototype]
+cell tSIOPortGRSakura SIOPortTarget8 {
+	/* 属性の設定 */
+	tx = NULL;
+	rx = NULL;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tSIOPortGRSakuraMain_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tSIOPortGRSakuraMain_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tSIOPortGRSakuraMain_inline.h	(revision 398)
@@ -0,0 +1,143 @@
+/*
+ *  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-2016 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$
+ */
+
+/*
+ *		シリアルインタフェースドライバのターゲット依存部（GR-SAKURA用）
+ */
+
+/*
+ *  SIOポートのオープン
+ */
+Inline void
+eSIOPort_open(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	/*
+	 *  デバイス依存のオープン処理
+	 */
+	cSIOPort_open();
+}
+
+/*
+ *  SIOポートのクローズ
+ */
+Inline void
+eSIOPort_close(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	/*
+	 *  デバイス依存のクローズ処理
+	 */
+	cSIOPort_close();
+}
+
+/*
+ *  SIOポートへの文字送信
+ */
+Inline bool_t
+eSIOPort_putChar(CELLIDX idx, char c)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	return(cSIOPort_putChar(c));
+}
+
+/*
+ *  SIOポートからの文字受信
+ */
+Inline int_t
+eSIOPort_getChar(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	return(cSIOPort_getChar());
+}
+
+/*
+ *  SIOポートからのコールバックの許可
+ */
+Inline void
+eSIOPort_enableCBR(CELLIDX idx, uint_t cbrtn)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	cSIOPort_enableCBR(cbrtn);
+}
+
+/*
+ *  SIOポートからのコールバックの禁止
+ */
+Inline void
+eSIOPort_disableCBR(CELLIDX idx, uint_t cbrtn)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	cSIOPort_disableCBR(cbrtn);
+}
+
+/*
+ *  SIOポートからの送信可能コールバック
+ */
+Inline void
+eiSIOCBR_readySend(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	if (is_ciSIOCBR_joined()) {
+		ciSIOCBR_readySend();
+	}
+}
+
+/*
+ *  SIOポートからの受信通知コールバック
+ */
+Inline void
+eiSIOCBR_readyReceive(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	
+	if (is_ciSIOCBR_joined()) {
+		ciSIOCBR_readyReceive();
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target.cdl	(revision 398)
@@ -0,0 +1,77 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *  タスクのスタックサイズのデフォルト
+ */
+const size_t DefaultTaskStackSize = 1024;		/* スタックサイズ（1KB）*/
+
+/*
+ *  システムログタスクのスタックサイズの定義
+ */
+const size_t LogTaskStackSize = DefaultTaskStackSize;
+
+/*
+ *  カーネル起動メッセージに関する定義
+ */
+const char *const BannerTargetName = "GR-SAKURA";		/* ターゲット名 */
+const char *const BannerCopyrightNotice = "";			/* 著作権表示 */
+
+/*
+ *  ターゲット依存のセルタイプの定義
+ */
+import("syssvc/tPutLogSIOPort.cdl");
+import("tSIOPortGRSakura.cdl");
+
+/*
+ *  シリアルインタフェースドライバのターゲット依存部の組み上げ記述
+ */
+cell tSIOPortGRSakura SIOPortTarget1 {
+};
+
+/*
+ *  低レベル出力の組み上げ記述
+ */
+cell tPutLogSIOPort PutLogTarget {
+	/* SIOドライバとの結合 */
+	cSIOPort = SIOPortTarget1.eSIOPort;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_cfg1_out.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_cfg1_out.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_cfg1_out.h	(revision 398)
@@ -0,0 +1,6 @@
+/*
+ *		cfg1_out.cのリンクに必要なスタブの定義
+ */
+
+#include "prc_cfg1_out.h"
+#include "sil.h"
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_check.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_check.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_check.trb	(revision 398)
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+#
+#		パス3の生成スクリプトのターゲット依存部（GR-SAKURA用）
+#
+
+#
+#  生成スクリプトのプロセッサ依存部
+#
+IncludeTrb("prc_check.trb")
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel.cfg	(revision 398)
@@ -0,0 +1,7 @@
+/*
+ *		カーネル実装のコンフィギュレーションファイル
+ *
+ *  $Id$
+ */
+INCLUDE("target_timer.cfg")
+INCLUDE("syssvc/musl_adapter.cfg")
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel.h	(revision 398)
@@ -0,0 +1,78 @@
+/*
+ *  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-2004 by Naoki Saito
+ *             Nagoya Municipal Industrial Research Institute, JAPAN
+ *  Copyright (C) 2003-2004 by Platform Development Center
+ *                                          RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  カーネルのターゲット依存定義（GR-SAKURA用）
+ */
+
+/*
+ *  このインクルードファイルは，kernel.hでインクルードされる．他のファ
+ *  イルから直接インクルードすることはない．このファイルをインクルード
+ *  する前に，t_stddef.hがインクルードされるので，それらに依存してもよ
+ *  い．
+ */
+
+#ifndef TOPPERS_TARGET_KERNEL_H
+#define TOPPERS_TARGET_KERNEL_H
+
+
+/*
+ *  プロセッサで共通な定義
+ */
+#include "prc_kernel.h"
+
+/*
+ *  サポートする機能の定義
+ */
+#define	TOPPERS_TARGET_SUPPORT_GET_UTM		/* get_utmをサポートする */
+//#define TOPPERS_TARGET_SUPPORT_OVRHDR		/* オーバランハンドラ */
+
+/*
+ *  タイムティックの定義
+ */
+#define	TIC_NUME		( 1U )		/* タイムティックの周期の分子 */
+#define	TIC_DENO		( 1U )		/* タイムティックの周期の分母 */
+
+#endif /* TOPPERS_TARGET_KERNEL_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel.trb	(revision 398)
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+#
+#		パス2の生成スクリプトのターゲット依存部（GR-SAKURA用）
+#
+
+#
+#  生成スクリプトのプロセッサ依存部
+#
+IncludeTrb("prc_kernel.trb")
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel_impl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel_impl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel_impl.c	(revision 398)
@@ -0,0 +1,158 @@
+/*
+ *  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-2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ *  Copyright (C) 2013      by Mitsuhiro Matsuura
+ *  Copyright (C) 2017      by Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	ターゲットシステム依存モジュール（GR-SAKURA用）
+ */
+
+#include "kernel_impl.h"
+#include <sil.h>
+#include "gr_sakura.h"
+#include "syssvc/serial.h"
+#ifdef TOPPERS_OMIT_TECS
+#include "serial_api.h"
+#include "target_syssvc.h"
+#endif
+
+#ifdef TOPPERS_OMIT_TECS
+serial_t log_serial;
+#endif
+
+/*
+ *  ターゲットシステム依存 初期化ルーチン
+ */
+void
+target_initialize( void )
+{
+	/*
+	 *  プロセッサ依存の初期化
+	 */
+	prc_initialize();
+
+	/* IOポート初期化 */
+	/* P25を出力ポートにする */
+	sil_wrb_mem(PORT2_PDR_ADDR, 
+		sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B5_BIT);
+	/* PA0, PA1, PA2, PA6を出力ポートにする */
+	sil_wrb_mem(PORTA_PDR_ADDR,
+		sil_reb_mem(PORTA_PDR_ADDR) | PORT_PDR_B0_BIT | PORT_PDR_B1_BIT | PORT_PDR_B2_BIT | PORT_PDR_B6_BIT);
+	/* PA7を入力ポートにする */
+	sil_wrb_mem(PORTA_PDR_ADDR,
+		sil_reb_mem(PORTA_PDR_ADDR) & ~PORT_PDR_B7_BIT);
+
+#ifdef TOPPERS_OMIT_TECS
+	/*
+	 *  シリアルポートの設定
+	 */
+	serial_init(&log_serial, STDIO_UART_TX, STDIO_UART_RX);
+	serial_baud(&log_serial, UART_BAUDRATE);
+	serial_format(&log_serial, 8, ParityNone, 1);
+#endif
+
+	/* ポートP40～P47を周辺機器に */
+	sil_wrb_mem(PORT4_PMR_ADDR, 0xFF);
+
+	/* ポートP40～P47を入力ポートにする */
+	sil_wrb_mem(PORT4_PDR_ADDR, 0x00);
+
+	/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+	/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+	/* P21端子機能制御レジスタ RXD0とする */
+	sil_wrb_mem(MPC_P21PFS_ADDR, 0x0a);
+	/* P20端子機能制御レジスタ TXD0とする */
+	sil_wrb_mem(MPC_P20PFS_ADDR, 0x0a);
+
+	/* P40端子機能制御レジスタ アナログ入力AN000とする */
+	sil_wrb_mem(MPC_P40PFS_ADDR, 0x80);
+	/* P41端子機能制御レジスタ アナログ入力AN001とする */
+	sil_wrb_mem(MPC_P41PFS_ADDR, 0x80);
+	/* P42端子機能制御レジスタ アナログ入力AN002とする */
+	sil_wrb_mem(MPC_P42PFS_ADDR, 0x80);
+	/* P43端子機能制御レジスタ アナログ入力AN003とする */
+	sil_wrb_mem(MPC_P43PFS_ADDR, 0x80);
+	/* P44端子機能制御レジスタ アナログ入力AN004とする */
+	sil_wrb_mem(MPC_P44PFS_ADDR, 0x80);
+	/* P45端子機能制御レジスタ アナログ入力AN005とする */
+	sil_wrb_mem(MPC_P45PFS_ADDR, 0x80);
+	/* P46端子機能制御レジスタ アナログ入力AN006とする */
+	sil_wrb_mem(MPC_P46PFS_ADDR, 0x80);
+	/* P47端子機能制御レジスタ アナログ入力AN007とする */
+	sil_wrb_mem(MPC_P47PFS_ADDR, 0x80);
+
+	/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+}
+
+
+/*
+ *  ターゲットシステムの終了ルーチン
+ */
+void
+target_exit( void )
+{
+	/*
+	 *	プロセッサ依存の終了処理
+	 */
+	prc_terminate();
+
+	while ( 1 );
+}
+#ifdef TOPPERS_OMIT_TECS
+/*
+ *  システムログの低レベル出力のための文字出力
+ */
+void
+target_fput_log(char c)
+{
+	if (c == '\n') {
+		serial_putc(&log_serial, '\r');
+	}
+
+	serial_putc(&log_serial, c);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel_impl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel_impl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_kernel_impl.h	(revision 398)
@@ -0,0 +1,128 @@
+/*
+ *  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-2007 by Embedded and Real-Time Systems Laboratory
+ *              Graduate School of Information Science, Nagoya Univ., JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		ターゲット依存モジュール（GR-SAKURA用）
+ *
+ *  カーネルのターゲット依存部のインクルードファイル．kernel_impl.hのター
+ *  ゲット依存部の位置付けとなる．
+ */
+
+#ifndef TOPPERS_TARGET_CONFIG_H
+#define TOPPERS_TARGET_CONFIG_H
+
+/*
+ *  ターゲットシステムのハードウェア資源の定義
+ */
+#include "gr_sakura.h"
+
+
+/*
+ *  デフォルトの非タスクコンテキスト用のスタック領域の定義
+ *
+ *  スタックサイズを変更する場合は, sectrx.incの_DEFAULT_ISTACK
+ *  ラベルの位置にある.blkb命令のサイズと, 以下DEFAULT_ISTKSZの
+ *  サイズを合わせて同じ値に変更すること.
+ */
+#define DEFAULT_ISTKSZ		( 0x400 )
+
+
+/*
+ *  ターゲット依存の文字出力に使用するポートの定義  
+ */
+#define TARGET_PUTC_PORTID	( 1 )
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  ターゲットシステム依存の初期化
+ */
+extern void	target_initialize( void );
+
+/*
+ *  ターゲットシステムの終了
+ *
+ *  システムを終了する時に使う．
+ */
+extern void	target_exit( void )	NoReturn;
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+
+/*
+ *  プロセッサ依存モジュール（RX630用）
+ */
+#include "rx630_kernel_impl.h"
+
+/*
+ *  トレースログに関する設定
+ */
+#define TCNT_TRACE_BUFFER	( 32 )
+
+/*
+ *  トレースログ出力する箇所の選択
+ *    ログ出力する箇所を1で定義
+ *    ログ出力しない箇所を0で定義
+ */
+#ifdef TOPPERS_ENABLE_TRACE
+#define LOG_DSP_ENTER(dspno)
+#define LOG_DSP_LEAVE(dspno)
+#define LOG_INH_ENTER(inhno)
+#define LOG_INH_LEAVE(inhno)
+#define LOG_EXC_ENTER(excno)
+#define LOG_EXC_LEAVE(excno)
+#else
+#undef LOG_DSP_ENTER
+#undef LOG_DSP_LEAVE
+#undef LOG_INH_ENTER
+#undef LOG_INH_LEAVE
+#undef LOG_EXC_ENTER
+#undef LOG_EXC_LEAVE
+#endif
+
+#ifdef TOPPERS_ENABLE_TRACE
+#include "arch/tracelog/trace_log.h"
+#endif /* TOPPERS_ENABLE_TRACE */
+
+#endif /* TOPPERS_TARGET_CONFIG_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_rename.def
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_rename.def	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_rename.def	(revision 398)
@@ -0,0 +1,13 @@
+# target_kernel_impl.c
+target_initialize
+target_exit
+
+#trace_config.c
+log_dsp_enter
+log_dsp_leave
+log_inh_enter
+log_inh_leave
+log_exc_enter
+log_exc_leave
+
+INCLUDE "rx_rxc/prc"
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_rename.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_rename.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_rename.h	(revision 398)
@@ -0,0 +1,49 @@
+/* This file is generated from target_rename.def by genrename. */
+
+#ifndef TOPPERS_TARGET_RENAME_H
+#define TOPPERS_TARGET_RENAME_H
+
+/*
+ *  target_kernel_impl.c
+ */
+#define target_initialize			_kernel_target_initialize
+#define target_exit					_kernel_target_exit
+
+/*
+ *  trace_config.c
+ */
+#define log_dsp_enter				_kernel_log_dsp_enter
+#define log_dsp_leave				_kernel_log_dsp_leave
+#define log_inh_enter				_kernel_log_inh_enter
+#define log_inh_leave				_kernel_log_inh_leave
+#define log_exc_enter				_kernel_log_exc_enter
+#define log_exc_leave				_kernel_log_exc_leave
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ *  target_kernel_impl.c
+ */
+#define _board_id					__kernel_board_id
+#define _board_addr					__kernel_board_addr
+#define _target_initialize			__kernel_target_initialize
+#define _target_exit				__kernel_target_exit
+#define _config_int					__kernel_config_int
+
+/*
+ *  trace_config.c
+ */
+#define _log_dsp_enter				__kernel_log_dsp_enter
+#define _log_dsp_leave				__kernel_log_dsp_leave
+#define _log_inh_enter				__kernel_log_inh_enter
+#define _log_inh_leave				__kernel_log_inh_leave
+#define _log_exc_enter				__kernel_log_exc_enter
+#define _log_exc_leave				__kernel_log_exc_leave
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "prc_rename.h"
+
+#endif /* TOPPERS_TARGET_RENAME_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_serial.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_serial.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_serial.c	(revision 398)
@@ -0,0 +1,318 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2006-2018 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$
+ */
+
+/*
+ *		シリアルインタフェースドライバのターゲット依存部（GR-SAKURA用）
+ */
+
+#include "gr_sakura.h"
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include "target_serial.h"
+#include "syssvc/siofd.h"
+
+/*
+ *  SIOポート初期化ブロックの定義
+ */
+typedef struct sio_port_initialization_block {
+	char		*path;			/* ファイルのパス名 */
+} SIOPINIB;
+
+/*
+ *  SIOポート管理ブロックの定義
+ */
+struct sio_port_control_block {
+	const SIOPINIB *p_siopinib;	/* SIOポート初期化ブロック */
+	intptr_t	exinf;			/* 拡張情報 */
+	bool_t		opened;		/* オープン済みフラグ */
+	struct termios saved_term;	/* 元の端末制御情報 */
+
+	int_t		read_fd;		/* 読出し用ファイルディスクリプタ */
+	bool_t		rcv_flag;		/* 受信文字バッファ有効フラグ */
+	char		rcv_buf;		/* 受信文字バッファ */
+	bool_t		rcv_rdy;		/* 受信通知コールバック許可フラグ */
+
+	int_t		write_fd;		/* 書込み用ファイルディスクリプタ */
+	bool_t		snd_flag;		/* 送信文字バッファ有効フラグ */
+	char		snd_buf;		/* 送信文字バッファ */
+	bool_t		snd_rdy;		/* 送信通知コールバック許可フラグ */
+};
+
+/*
+ *  SIOポート初期化ブロック
+ */
+const SIOPINIB siopinib_table[TNUM_SIOP] = {
+	{ NULL }
+};
+
+/*
+ *  SIOポート管理ブロックのエリア
+ */
+SIOPCB	siopcb_table[TNUM_SIOP];
+
+/*
+ *  SIOポートIDから管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_SIOP(siopid)	((uint_t)((siopid) - 1))
+#define get_siopcb(siopid)	(&(siopcb_table[INDEX_SIOP(siopid)]))
+
+/*
+ *  SIOドライバの初期化
+ */
+void
+sio_initialize(intptr_t exinf)
+{
+	SIOPCB	*p_siopcb;
+	uint_t	i;
+
+	/*
+	 *  SIOポート管理ブロックの初期化
+	 */
+	for (i = 0; i < TNUM_SIOP; i++) {
+		p_siopcb = &(siopcb_table[i]);
+		p_siopcb->p_siopinib = &(siopinib_table[i]);
+		p_siopcb->opened = false;
+	}
+}
+
+/*
+ *  SIOドライバの終了処理
+ */
+void
+sio_terminate(intptr_t exinf)
+{
+	uint_t	i;
+
+	/*
+	 *  オープンされているSIOポートのクローズ
+	 */
+	for (i = 0; i < TNUM_SIOP; i++) {
+		sio_cls_por(&(siopcb_table[i]));
+	}
+}
+
+/*
+ *  SIOポートのオープン
+ */
+SIOPCB *
+sio_opn_por(ID siopid, intptr_t exinf)
+{
+	SIOPCB			*p_siopcb;
+	const SIOPINIB	*p_siopinib;
+	int_t			fd;
+	struct termios	term;
+
+	p_siopcb = get_siopcb(siopid);
+	p_siopinib = p_siopcb->p_siopinib;
+
+	if (!(p_siopcb->opened)) {
+		if (p_siopinib->path != NULL) {
+			fd = siofd_open(p_siopinib->path, O_RDWR, 0777);
+			assert(fd >= 0);
+			p_siopcb->read_fd = fd;
+			p_siopcb->write_fd = fd;
+		}
+		else {
+			fd = STDIN_FILENO;					/* 標準入出力を使う */
+			p_siopcb->read_fd = STDIN_FILENO;
+			p_siopcb->write_fd = STDOUT_FILENO;
+		}
+		siofd_fcntl(fd, F_SETOWN, getpid());
+		siofd_fcntl(fd, F_SETFL, (O_NONBLOCK | O_ASYNC));
+
+		siofd_tcgetattr(fd, &(p_siopcb->saved_term));
+		term = p_siopcb->saved_term;
+		term.c_lflag &= ~(ECHO | ICANON);
+		siofd_tcsetattr(fd, TCSAFLUSH, &term);
+
+		p_siopcb->exinf = exinf;
+		p_siopcb->rcv_flag = false;
+		p_siopcb->rcv_rdy = false;
+		p_siopcb->snd_flag = false;
+		p_siopcb->snd_rdy = false;
+		p_siopcb->opened = true;
+	}
+	return(p_siopcb);
+}
+
+/*
+ *  SIOポートのクローズ
+ */
+void
+sio_cls_por(SIOPCB *p_siopcb)
+{
+	int_t	fd;
+
+	if (p_siopcb->opened) {
+		fd = p_siopcb->read_fd;
+		siofd_tcsetattr(fd, TCSAFLUSH, &(p_siopcb->saved_term));
+		siofd_fcntl(fd, F_SETFL, 0);
+
+		if (p_siopcb->p_siopinib->path != NULL) {
+			siofd_close(p_siopcb->read_fd);
+		}
+
+		p_siopcb->opened = false;
+	}
+}
+
+/*
+ *  SIOの割込みサービスルーチン
+ */
+bool_t
+sio_isr_snd(ID siopid)
+{
+	SIOPCB	*p_siopcb = get_siopcb(siopid);
+	int_t	n;
+
+	if (p_siopcb->snd_flag) {
+		if ((n = siofd_write(p_siopcb->write_fd, &(p_siopcb->snd_buf), 1)) > 0) {
+			p_siopcb->snd_flag = false;
+			if (p_siopcb->snd_rdy) {
+				sio_irdy_snd(p_siopcb->exinf);
+				return p_siopcb->snd_rdy;
+			}
+		}
+	}
+
+	return false;
+}
+
+/*
+ *  SIOの割込みサービスルーチン
+ */
+bool_t
+sio_isr_rcv(ID siopid, char c)
+{
+	SIOPCB	*p_siopcb = get_siopcb(siopid);
+
+	if (!p_siopcb->rcv_flag) {
+		p_siopcb->rcv_buf = c;
+		p_siopcb->rcv_flag = true;
+		if (p_siopcb->rcv_rdy) {
+			sio_irdy_rcv(p_siopcb->exinf);
+			return p_siopcb->rcv_rdy;
+		}
+	}
+
+	return false;
+}
+
+/*
+ *  SIOポートへの文字送信
+ */
+bool_t
+sio_snd_chr(SIOPCB *p_siopcb, char c)
+{
+	int_t	n;
+
+	if (!p_siopcb->snd_flag) {
+		if ((n = siofd_write(p_siopcb->write_fd, &c, 1)) > 0) {
+			return(true);
+		}
+		else {
+			assert(n < 0 && errno == EAGAIN);
+			p_siopcb->snd_flag = true;
+			p_siopcb->snd_buf = c;
+			return(true);
+		}
+	}
+	else {
+		return(false);
+	}
+}
+
+/*
+ *  SIOポートからの文字受信
+ */
+int_t
+sio_rcv_chr(SIOPCB *p_siopcb)
+{
+	char	c;
+	int_t	n;
+
+	if (p_siopcb->rcv_flag) {
+		p_siopcb->rcv_flag = false;
+		return((int_t)(uint8_t)(p_siopcb->rcv_buf));
+	}
+	else if ((n = siofd_read(p_siopcb->read_fd, &c, 1)) > 0) {
+		return((int_t)(uint8_t) c);
+	}
+	else {
+		assert(n < 0 && errno == EAGAIN);
+		return(-1);
+	}
+}
+
+/*
+ *  SIOポートからのコールバックの許可
+ */
+void
+sio_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
+{
+	switch (cbrtn) {
+	case SIO_RDY_SND:
+		p_siopcb->snd_rdy = true;
+		break;
+	case SIO_RDY_RCV:
+		p_siopcb->rcv_rdy = true;
+		break;
+	}
+}
+
+/*
+ *  SIOポートからのコールバックの禁止
+ */
+void
+sio_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
+{
+	switch (cbrtn) {
+	case SIO_RDY_SND:
+		p_siopcb->snd_rdy = false;
+		break;
+	case SIO_RDY_RCV:
+		p_siopcb->rcv_rdy = false;
+		break;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_serial.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_serial.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_serial.cfg	(revision 398)
@@ -0,0 +1,9 @@
+/*
+ *	SIOドライバ（GR-SAKURA用）のコンフィギュレーションファイル
+ */
+
+#include <target_serial.h>
+//INCLUDE("unix_sigio.cfg");
+ATT_INI({ TA_NULL, 0, sio_initialize });
+ATT_TER({ TA_NULL, 0, sio_terminate });
+//CRE_ISR( ISR_SIO, { TA_NULL, 0, INTNO_SIGIO, sio_isr, ISRPRI_SIO });
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_serial.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_serial.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_serial.h	(revision 398)
@@ -0,0 +1,135 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2006-2018 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$
+ */
+
+/*
+ *		シリアルインタフェースドライバのターゲット依存部（GR-SAKURA用）
+ */
+
+#ifndef TOPPERS_TARGET_SERIAL_H
+#define TOPPERS_TARGET_SERIAL_H
+
+#include "gr_sakura.h"
+#include <t_stddef.h>
+
+/*
+ *  SIOポート数の定義
+ */
+//#define TNUM_SIOP		1		/* サポートするSIOポートの数 */
+
+/*
+ *  SIO割込みを登録するための定義
+ */
+#define ISRPRI_SIO		1		/* SIOの割込みサービスルーチンのISR優先度 */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  SIOポート管理ブロックの定義
+ */
+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);
+
+/*
+ *  SIOドライバの終了処理
+ */
+extern void		sio_terminate(intptr_t exinf);
+
+/*
+ *  SIOポートのオープン
+ */
+extern SIOPCB	*sio_opn_por(ID siopid, intptr_t exinf);
+
+/*
+ *  SIOポートのクローズ
+ */
+extern void		sio_cls_por(SIOPCB *p_siopcb);
+
+/*
+ *  SIOの割込みサービスルーチン
+ */
+extern bool_t	sio_isr_snd(ID siopid);
+
+/*
+ *  SIOの割込みサービスルーチン
+ */
+extern bool_t	sio_isr_rcv(ID siopid, char c);
+
+/*
+ *  SIOポートへの文字送信
+ */
+extern bool_t	sio_snd_chr(SIOPCB *siopcb, char c);
+
+/*
+ *  SIOポートからの文字受信
+ */
+extern int_t	sio_rcv_chr(SIOPCB *siopcb);
+
+/*
+ *  SIOポートからのコールバックの許可
+ */
+extern void		sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn);
+
+/*
+ *  SIOポートからのコールバックの禁止
+ */
+extern void		sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn);
+
+/*
+ *  SIOポートからの送信可能コールバック
+ */
+extern void		sio_irdy_snd(intptr_t exinf);
+
+/*
+ *  SIOポートからの受信通知コールバック
+ */
+extern void		sio_irdy_rcv(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_TARGET_SERIAL_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_sil.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_sil.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_sil.h	(revision 398)
@@ -0,0 +1,62 @@
+/*
+ *  TOPPERS Software
+ *      Toyohashi Open Platform for Embedded Real-Time Systems
+ * 
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		sil.hのターゲット依存部（GR-SAKURA用）
+ *
+ *  このインクルードファイルは，sil.hの先頭でインクルードされる．他のファ
+ *  イルからは直接インクルードすることはない．このファイルをインクルー
+ *  ドする前に，t_stddef.hがインクルードされるので，それらに依存しても
+ *  よい．
+ */
+
+#ifndef TOPPERS_TARGET_SIL_H
+#define TOPPERS_TARGET_SIL_H
+
+/*
+ *  微少時間待ちのための定義
+ */
+#define SIL_DLY_TIM1     69
+#define SIL_DLY_TIM2     50
+
+/*
+ *  プロセッサで共通な定義
+ */
+#include "prc_sil.h"
+
+#endif /* TOPPERS_TARGET_SIL_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_stddef.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_stddef.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_stddef.h	(revision 398)
@@ -0,0 +1,94 @@
+/*
+ *  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) 2003-2004 by Naoki Saito
+ *             Nagoya Municipal Industrial Research Institute, JAPAN
+ *  Copyright (C) 2003-2004 by Platform Development Center
+ *                                          RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  t_stddef.hのターゲット依存部（GR-SAKURA用）
+ *
+ *  このインクルードファイルは，t_stddef.hの先頭でインクルードされる．
+ *  他のファイルからは直接インクルードすることはない．他のインクルード
+ *  ファイルに先立って処理されるため，他のインクルードファイルに依存し
+ *  てはならない．
+ */
+
+#ifndef TOPPERS_TARGET_STDDEF_H
+#define TOPPERS_TARGET_STDDEF_H
+
+/*
+ *  ターゲットを識別するためのマクロの定義
+ */
+#define TOPPERS_GRSAKURA			/* システム略称 */
+
+
+/*
+ *  開発環境で共通な定義
+ */
+#ifndef TOPPERS_MACRO_ONLY
+#include <stdint.h>
+#endif /* TOPPERS_MACRO_ONLY */
+
+#include "tool_stddef.h"
+
+
+/*
+ *  プロセッサで共通な定義
+ */
+#include "prc_stddef.h"
+
+/*
+ *  アサーションの失敗時の実行中断処理
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+#ifndef _MSC_VER
+Inline void
+TOPPERS_assert_abort( void )
+{
+}
+#else
+void TOPPERS_assert_abort(void);
+#endif
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_TARGET_STDDEF_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_support.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_support.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_support.c	(revision 398)
@@ -0,0 +1,125 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	ターゲットシステム依存モジュール（GR-SAKURA用）
+ */
+
+#include "kernel_impl.h"
+#include <sil.h>
+
+void hardware_init_hook()
+{
+	/*
+	 * 動作モード設定
+	 *
+	 * 動作モードはボード上の端子によって決定されるため,
+	 * ここでは特別設定しない.
+	 * ただし, リトルエンディアン/シングルチップモード
+	 * であることを前提とする.
+	 *
+	 * またリセット後, 内蔵ROM：有効, 内蔵RAM：有効, 外部バス：無効
+	 * である.
+	 */
+
+	/*
+	 * クロック設定
+	 *
+	 * 入力：12MHz
+	 * PLL回路：12 x 8 = 96MHz
+	 * システムクロック：96MHz
+	 * 周辺モジュールクロック：48MHz
+	 * 外部バスクロック：96MHz
+	 * とする.
+	 */
+	sil_wrb_mem(PORT3_PDR_ADDR,
+		sil_reb_mem(PORT3_PDR_ADDR) & ~PORT_PDR_B6_BIT);
+	sil_wrb_mem(PORT3_PDR_ADDR,
+		sil_reb_mem(PORT3_PDR_ADDR) & ~PORT_PDR_B7_BIT);
+	sil_wrb_mem(PORT3_PMR_ADDR,
+		sil_reb_mem(PORT3_PMR_ADDR) & ~PORT_PDR_B6_BIT);
+	sil_wrb_mem(PORT3_PMR_ADDR,
+		sil_reb_mem(PORT3_PMR_ADDR) & ~PORT_PDR_B7_BIT);
+
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xa503);
+
+	/* メインクロック発振器強制発振 */
+	while((sil_reb_mem(SYSTEM_MOFCR_ADDR) & SYSTEM_MOFCR_MOFXIN) == 0)
+		sil_wrb_mem(SYSTEM_MOFCR_ADDR,
+			sil_reb_mem(SYSTEM_MOFCR_ADDR) | SYSTEM_MOFCR_MOFXIN);
+
+	/* メインクロック発振器動作 */
+	while((sil_reb_mem(SYSTEM_MOSCCR_ADDR) & SYSTEM_MOSCCR_MOSTP) != 0)
+		sil_wrb_mem(SYSTEM_MOSCCR_ADDR,
+			sil_reb_mem(SYSTEM_MOSCCR_ADDR) & ~SYSTEM_MOSCCR_MOSTP);
+
+	sil_wrh_mem(SYSTEM_PLLCR_ADDR,
+		(sil_reh_mem(SYSTEM_PLLCR_ADDR) & ~SYSTEM_PLLCR_STC_MASK)
+		| (0x0f << SYSTEM_PLLCR_STC_OFFSET));
+
+	sil_wrb_mem(SYSTEM_PLLCR2_ADDR,
+		sil_reb_mem(SYSTEM_PLLCR2_ADDR) & ~SYSTEM_PLLCR2_PLLEN);
+
+	sil_wrw_mem(SYSTEM_SCKCR_ADDR, 0x21021211);
+
+	sil_wrh_mem(SYSTEM_SCKCR2_ADDR, 0x0033);
+
+	/* PLL回路選択 */
+	sil_wrh_mem(SYSTEM_SCKCR3_ADDR,
+		(sil_reh_mem(SYSTEM_SCKCR3_ADDR) & ~SYSTEM_SCKCR3_CKSEL_MASK)
+		| (4 << SYSTEM_SCKCR3_CKSEL_OFFSET));
+
+	/*
+	 * モジュールストップ
+	 *
+	 * リセット後, 動作している内蔵周辺モジュールはDMAC, DTC,
+	 * 内蔵RAMのみである.
+	 * それ以外の内蔵周辺モジュールに関しては使用する側で
+	 * 設定すること.
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xa500);
+}
+
+void software_init_hook()
+{
+	/*
+	 * 本コンパイラではweak definitionの機能が無いため,
+	 * 特に必要な処理はないが, 必ず呼び出すこととする.
+	 */
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_sym.def
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_sym.def	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_sym.def	(revision 398)
@@ -0,0 +1,4 @@
+SIL_DLY_TIM1
+SIL_DLY_TIM2
+INTATR_TIMER0
+INTATR_TIMER1
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_syssvc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_syssvc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_syssvc.h	(revision 398)
@@ -0,0 +1,126 @@
+/*
+ *  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-2004 by Naoki Saito
+ *             Nagoya Municipal Industrial Research Institute, JAPAN
+ *  Copyright (C) 2003-2004 by Platform Development Center
+ *                                          RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		システムサービスのターゲット依存部（GR-SAKURA用）
+ *
+ *  システムサービスのターゲット依存部のインクルードファイル．このファ
+ *  イルの内容は，コンポーネント記述ファイルに記述され，このファイルは
+ *  無くなる見込み．
+ */
+
+#ifndef TOPPERS_TARGET_SYSSVC_H
+#define TOPPERS_TARGET_SYSSVC_H
+
+
+/*
+ *  プロセッサ依存の定義
+ */
+#include "prc_syssvc.h"
+
+/*
+ *  トレースログに関する設定
+ */
+#ifdef TOPPERS_ENABLE_TRACE
+#include "arch/tracelog/trace_log.h"
+#endif /* TOPPERS_ENABLE_TRACE */
+
+
+/*
+ *  ボード依存情報の読み込み
+ */
+#include "gr_sakura.h"
+
+
+/*
+ *  起動メッセージのターゲットシステム名
+ */
+#define	TARGET_NAME	"GR-SAKURA"
+
+#ifdef TOPPERS_OMIT_TECS
+/*
+ *  システムログの低レベル出力のための文字出力
+ *
+ *  ターゲット依存の方法で，文字cを表示/出力/保存する．
+ */
+extern void	target_fput_log( char c );
+#endif
+
+/*
+ *  起動メッセージにターゲット依存部の著作権表示を
+ *  追加するためのマクロ．
+ */
+#ifdef PRC_COPYRIGHT
+#define TARGET_COPYRIGHT	PRC_COPYRIGHT
+#endif /* PRC_COPYRIGHT */
+
+
+/*
+ *  シリアルポート数の定義
+ */
+#define TNUM_PORT			UINT_C( 2 )
+
+/*
+ *  使用するシリアルポートID
+ */
+#define SIO_PORTID			UINT_C( 1 )
+
+#define LOGTASK_PORTID		SIO_PORTID
+
+#define STACK_SIZE			(512)
+
+/*
+ *  使用するシリアルポートのPinName
+ */
+#define STDIO_UART_TX P20
+#define STDIO_UART_RX P21
+
+/*
+ *  システムログタスク関連の定数の定義
+ *
+ *  デフォルト値の通り．
+ */
+
+#endif /* TOPPERS_TARGET_SYSSVC_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_test.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_test.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_test.h	(revision 398)
@@ -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) 2003-2004 by Naoki Saito
+ *             Nagoya Municipal Industrial Research Institute, JAPAN
+ *  Copyright (C) 2003-2004 by Platform Development Center
+ *                                          RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		テストプログラムのターゲット依存定義（GR-SAKURA用）
+ */
+
+#ifndef TOPPERS_TARGET_TEST_H
+#define TOPPERS_TARGET_TEST_H
+
+/*
+ *  プロセッサで共通な定義
+ */
+#include "prc_test.h"
+
+/*
+ *  タスクで使用するシリアルポートID
+ */
+#define	TASK_PORTID		( 1 )
+
+
+#endif /* TOPPERS_TARGET_TEST_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_timer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_timer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_timer.c	(revision 398)
@@ -0,0 +1,684 @@
+/*
+ *  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-2004 by Naoki Saito
+ *             Nagoya Municipal Industrial Research Institute, JAPAN
+ *  Copyright (C) 2003-2004 by Platform Development Center
+ *                                          RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ *  Copyright (C) 2013      by Mitsuhiro Matsuura
+ *  Copyright (C) 2017      by Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		タイマドライバ（GR-SAKURA用）
+ */
+
+#include "kernel_impl.h"
+#include "time_event.h"
+#include <sil.h>
+#include "target_timer.h"
+#ifdef TOPPERS_SUPPORT_OVRHDR
+#include "overrun.h"
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+
+/*
+ * 上位タイマソフトカウンタ
+ */
+static uint16_t elapse_upper_timer = 0;
+
+/*
+ * 上下位タイマ設定カウンタ
+ */
+static uint16_t timer_upper_set_count = 0, timer_lower_set_count = 0;
+
+#ifdef TOPPERS_SUPPORT_OVRHDR
+
+/* オーバラン上下位タイマ設定カウンタ */
+static uint16_t timer_ovr_upper_set_count = 0, timer_ovr_lower_set_count = 0;
+
+/* オーバランタイマ実行中フラグ */
+static bool_t timer_ovr_running_flg = false;
+
+/* オーバランタイマ開始時HRTタイマ値 */
+static HRTCNT timer_ovr_hrt_backup;
+
+/* オーバランタイマ設定時間 */
+static PRCTIM timer_ovr_ovrtim_backup;
+
+/*
+ *  オーバランタイマ割込み要求のクリア
+ */
+Inline void
+target_ovrtimer_int_clear()
+{
+	clear_int(INTNO_TIMER2);
+}
+
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+
+/*
+ *  タイマの初期化処理
+ */
+void
+target_timer_initialize(intptr_t exinf)
+{
+	/*
+	 * モジュールストップ機能の設定  CMTユニット0 解除
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRA_ADDR,
+			sil_rew_mem(SYSTEM_MSTPCRA_ADDR) & ~SYSTEM_MSTPCRA_MSTPA15_BIT);
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xA500);	/* 書込み禁止 */
+
+	/* 
+	 * タイマ停止 
+	 */
+	sil_wrh_mem(CMT_CMSTR0_ADDR,
+			sil_reh_mem(CMT_CMSTR0_ADDR) & ~(CMT_CMSTR0_STR0_BIT | CMT_CMSTR0_STR1_BIT));
+	
+	/*
+ 	 * カウントアップに用いられるクロック設定
+	 * PCLK/8を選択
+	 */
+	sil_wrh_mem(CMT0_CMCR_ADDR, CMT_PCLK_DIV_8);
+	sil_wrh_mem(CMT1_CMCR_ADDR, CMT_PCLK_DIV_8);
+
+	/* 
+	 * コンペアマッチタイマカウンタ設定
+	 */
+	sil_wrh_mem(CMT0_CMCNT_ADDR, 0U);
+	sil_wrh_mem(CMT1_CMCNT_ADDR, 0U);
+
+	/* 
+	 * コンペアマッチタイマ周期設定
+	 */
+	sil_wrh_mem(CMT0_CMCOR_ADDR, 0); /* lower */
+	sil_wrh_mem(CMT1_CMCOR_ADDR, CMCOR_PERIOD - 1); /* upper */
+	elapse_upper_timer = 0;
+
+	/*
+	 * コンペアマッチタイマ割り込み要求先設定レジスタ（28,29）
+	 */
+	sil_wrb_mem(ICU_ISELR028_ADDR, ICU_ISEL_CPU);
+	sil_wrb_mem(ICU_ISELR029_ADDR, ICU_ISEL_CPU);
+
+	/*
+	 *  タイマ動作開始前の割込み要求をクリア
+	 */
+	clear_int(INTNO_TIMER0);
+	clear_int(INTNO_TIMER1);
+
+	/* 
+	 * コンペアマッチタイマ割り込みを許可
+	 */
+//	sil_wrh_mem(CMT0_CMCR_ADDR,
+//			sil_reh_mem(CMT0_CMCR_ADDR) | CMT0_CMCR_CMIE_BIT); /* lower */
+	sil_wrh_mem(CMT1_CMCR_ADDR,
+			sil_reh_mem(CMT1_CMCR_ADDR) | CMT1_CMCR_CMIE_BIT); /* upper */
+
+	/* 
+	 * タイマ動作開始
+	 */
+//	sil_wrh_mem(CMT_CMSTR0_ADDR,
+//			sil_reh_mem(CMT_CMSTR0_ADDR) | CMT_CMSTR0_STR0_BIT); /* lower */
+	sil_wrh_mem(CMT_CMSTR0_ADDR,
+			sil_reh_mem(CMT_CMSTR0_ADDR) | CMT_CMSTR0_STR1_BIT); /* upper */
+}
+
+/*
+ *  タイマの停止処理
+ */
+void
+target_timer_terminate(intptr_t exinf)
+{
+	/* 
+	 * タイマ停止  lower, upper
+	 */
+	sil_wrh_mem(CMT_CMSTR0_ADDR,
+			sil_reh_mem(CMT_CMSTR0_ADDR) & ~(CMT_CMSTR0_STR0_BIT | CMT_CMSTR0_STR1_BIT));
+
+	/*
+	 * タイマ割り込み禁止　lower,upper
+	 */
+	sil_wrh_mem(CMT0_CMCR_ADDR,
+			sil_reh_mem(CMT0_CMCR_ADDR) & ~CMT0_CMCR_CMIE_BIT);
+	sil_wrh_mem(CMT1_CMCR_ADDR,
+			sil_reh_mem(CMT1_CMCR_ADDR) & ~CMT1_CMCR_CMIE_BIT);
+
+	/*
+	 *  タイマ割込み要求をクリア
+	 */
+	clear_int(INTNO_TIMER0);
+	clear_int(INTNO_TIMER1);
+
+	/*
+	 * モジュールストップ機能の設定  CMTユニット0 停止
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRA_ADDR,
+			sil_rew_mem(SYSTEM_MSTPCRA_ADDR) | SYSTEM_MSTPCRA_MSTPA15_BIT);
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xA500);	/* 書込み禁止 */
+}
+
+/*
+ *  下位タイマ割込みハンドラ(CMT0)
+ */
+void target_lower_timer_handler(void)
+{
+	/*
+	 * タイマ停止
+	 */
+	sil_wrh_mem(CMT_CMSTR0_ADDR,
+		sil_reh_mem(CMT_CMSTR0_ADDR) & ~CMT_CMSTR0_STR0_BIT);
+
+	/*
+	 * タイマ割り込み禁止
+	 */
+	sil_wrh_mem(CMT0_CMCR_ADDR,
+			sil_reh_mem(CMT0_CMCR_ADDR) & ~CMT0_CMCR_CMIE_BIT);
+
+	/*
+	 * 割り込み要因クリア
+	 */
+	clear_int(INTNO_TIMER0);
+
+	/*
+	 * カウント設定クリア
+	 */
+	timer_lower_set_count = 0;
+
+	/*
+	 * タイマ割り込み処理
+	 */
+	signal_time();
+}
+
+/*
+ *  上位タイマ割込みハンドラ(CMT1)
+ */
+void target_upper_timer_handler(void)
+{
+	/*
+	 * 上位タイマソフトカウンタ更新
+	 */
+	elapse_upper_timer++;
+
+	/*
+	 * 上位タイマ設定値更新
+	 */
+	if(timer_upper_set_count > 0) {
+		timer_upper_set_count--;
+	}
+
+	/*
+	 * 上位タイママッチ処理
+	 */
+	if(timer_upper_set_count == 0){
+		if(timer_lower_set_count > 0){
+			/*
+			 * 下位タイマ設定、開始
+			 */
+			sil_wrh_mem(CMT0_CMCOR_ADDR, timer_lower_set_count);
+			clear_int(INTNO_TIMER0);
+			sil_wrh_mem(CMT0_CMCR_ADDR,
+					sil_reh_mem(CMT0_CMCR_ADDR) | CMT0_CMCR_CMIE_BIT);
+			sil_wrh_mem(CMT_CMSTR0_ADDR,
+					sil_reh_mem(CMT_CMSTR0_ADDR) | CMT_CMSTR0_STR0_BIT);
+		}
+		else{
+			/*
+			 * 下位タイマ割り込み強制起動
+			 */
+			target_hrt_raise_event();
+		}
+	}
+
+#ifdef TOPPERS_SUPPORT_OVRHDR
+	if(timer_ovr_running_flg == true) {
+		/*
+		 * オーバラン上位タイマ設定値更新
+		 */
+		if(timer_ovr_upper_set_count > 0) {
+			timer_ovr_upper_set_count--;
+		}
+
+		/*
+		 * オーバラン上位タイママッチ処理
+		 */
+		if(timer_ovr_upper_set_count == 0) {
+			if(timer_ovr_lower_set_count > 0){
+				/*
+				 * オーバラン下位タイマ設定、開始
+				 */
+				sil_wrh_mem(CMT2_CMCNT_ADDR, 0U);
+				sil_wrh_mem(CMT2_CMCOR_ADDR, timer_ovr_lower_set_count);
+				target_ovrtimer_int_clear();
+				sil_wrh_mem(CMT2_CMCR_ADDR,
+						sil_reh_mem(CMT2_CMCR_ADDR) | CMT2_CMCR_CMIE_BIT);
+				sil_wrh_mem(CMT_CMSTR1_ADDR,
+						sil_reh_mem(CMT_CMSTR1_ADDR) | CMT_CMSTR1_STR2_BIT);
+			}
+			else {
+				/*
+				 * オーバラン下位タイマ割り込み強制起動
+				 */
+				target_ovrtimer_raise_event();
+			}
+		}
+	}
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+}
+
+/*
+ *  高分解能タイマへの割込みタイミングの設定
+ */
+void
+target_hrt_set_event(HRTCNT hrtcnt)
+{
+	uint32_t current_timer_count_work;
+	uint32_t total_timer_count;
+
+	/*
+	 * 時間 -> タイマカウンタ 変換
+	 */
+	total_timer_count = hrtcnt * USEC_CONVERT_VALUE;
+	timer_upper_set_count = total_timer_count / CMCOR_PERIOD;
+	timer_lower_set_count = total_timer_count % CMCOR_PERIOD;
+
+	/*
+	 * 上位タイマカウンタ現在値で調整
+	 */
+	current_timer_count_work = timer_lower_set_count + sil_reh_mem(CMT1_CMCNT_ADDR);
+	if(current_timer_count_work >= CMCOR_PERIOD) {
+		timer_upper_set_count++;
+		timer_lower_set_count = current_timer_count_work - CMCOR_PERIOD;
+	}
+
+	/*
+	 * 下位タイマ設定
+	 */
+	if(timer_upper_set_count == 0 && timer_lower_set_count > 0) {
+		/*
+		 * コンペアマッチタイマカウンタ設定
+		 */
+		sil_wrh_mem(CMT0_CMCNT_ADDR, 0U);
+
+		/*
+		 * 割り込み要因クリア
+		 */
+		clear_int(INTNO_TIMER0);
+
+		/*
+		 * コンペアマッチタイマ周期設定
+		 */
+		sil_wrh_mem(CMT0_CMCOR_ADDR, timer_lower_set_count);
+
+		/*
+		 *  タイマ割り込み許可
+		 */
+		sil_wrh_mem(CMT0_CMCR_ADDR,
+				sil_reh_mem(CMT0_CMCR_ADDR) | CMT0_CMCR_CMIE_BIT);
+
+		/*
+		 * タイマ開始
+		 */
+		sil_wrh_mem(CMT_CMSTR0_ADDR,
+				sil_reh_mem(CMT_CMSTR0_ADDR) | CMT_CMSTR0_STR0_BIT);
+	}
+}
+
+/*
+ *  高分解能タイマ割込みの要求
+ */
+void
+target_hrt_raise_event(void)
+{
+	/*
+	 * 下位タイマ強制割り込み起動
+	 * 注意：停止するまで割り込みが繰り返し発生する
+	 */
+	sil_wrh_mem(CMT0_CMCNT_ADDR, 0U);	/* カウンタ初期化	*/
+	clear_int(INTNO_TIMER0);			/* 要求クリア		*/
+	sil_wrh_mem(CMT0_CMCOR_ADDR, 0U);	/* マッチ周期設定	*/
+	sil_wrh_mem(CMT0_CMCR_ADDR,			/* 割り込み許可	*/
+			sil_reh_mem(CMT0_CMCR_ADDR) | CMT0_CMCR_CMIE_BIT);
+	sil_wrh_mem(CMT_CMSTR0_ADDR,		/* タイマ起動		*/
+			sil_reh_mem(CMT_CMSTR0_ADDR) | CMT_CMSTR0_STR0_BIT);
+}
+
+/*
+ * 高分解能タイマの現在のカウント値の読出し　内部処理
+ */
+HRTCNT target_hrt_get_current_convert(void)
+{
+	uint16_t local_cnt, local_eut;
+	HRTCNT time;
+
+	local_eut = elapse_upper_timer;
+	local_cnt = sil_reh_mem(CMT1_CMCNT_ADDR);
+
+	/*
+	 * 上位タイマ コンペアマッチチェック
+	 */
+	if (probe_int(INTNO_TIMER1)) {
+		if (local_cnt < 0x8000)
+			local_eut += 1;
+	}
+
+	time = (((HRTCNT)local_eut * CMCOR_PERIOD) + (HRTCNT)local_cnt) / USEC_CONVERT_VALUE;
+#ifdef _MSC_VER
+	// シミュレーションではタイマーが戻らないよう調整
+	if (time < current_hrtcnt)
+		time = current_hrtcnt + ((HRTCNT)local_cnt / USEC_CONVERT_VALUE);
+#endif
+	return time;
+}
+
+/*
+ *  オーバランタイマドライバ
+ */
+#ifdef TOPPERS_SUPPORT_OVRHDR
+
+/*
+ *  オーバランタイマの初期化処理
+ */
+void
+target_ovrtimer_initialize(intptr_t exinf)
+{
+	/*
+	 * モジュールストップ機能の設定  CMTユニット1 解除
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRA_ADDR,
+			sil_rew_mem(SYSTEM_MSTPCRA_ADDR) & ~SYSTEM_MSTPCRA_MSTPA14_BIT);
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xA500);	/* 書込み禁止 */
+
+	/*
+	 * タイマ停止 CMT2
+	 */
+	sil_wrh_mem(CMT_CMSTR1_ADDR,
+			sil_reh_mem(CMT_CMSTR1_ADDR) & ~CMT_CMSTR1_STR2_BIT);
+
+	/*
+ 	 * カウントアップに用いられるクロック設定 CMT2
+	 * PCLK/8を選択
+	 */
+	sil_wrh_mem(CMT2_CMCR_ADDR, CMT_PCLK_DIV_8);
+
+	/*
+	 * コンペアマッチタイマカウンタ設定 CMT2
+	 */
+	sil_wrh_mem(CMT2_CMCNT_ADDR, 0U);
+
+	/*
+	 * コンペアマッチタイマ周期設定 CMT2
+	 */
+	sil_wrh_mem(CMT2_CMCOR_ADDR, 0U);
+
+	/*
+	 * コンペアマッチタイマ割り込み要求先設定レジスタ（30）
+	 */
+	sil_wrb_mem(ICU_ISELR030_ADDR, ICU_ISEL_CPU);
+
+	/*
+	 *  タイマ動作開始前の割込み要求をクリア
+	 */
+	target_ovrtimer_int_clear();
+}
+
+void
+target_ovrtimer_start(PRCTIM ovrtim)
+{
+	uint32_t current_timer_count_work;
+	uint32_t total_timer_count;
+
+	/*
+	 * 時間 -> タイマカウンタ 変換
+	 */
+	total_timer_count = ovrtim * USEC_CONVERT_VALUE;
+	timer_ovr_upper_set_count = total_timer_count / CMCOR_PERIOD;
+	timer_ovr_lower_set_count = total_timer_count % CMCOR_PERIOD;
+
+	/*
+	 * 高分解能上位タイマカウンタ現在値で調整
+	 */
+	timer_ovr_ovrtim_backup = ovrtim;
+	timer_ovr_hrt_backup = target_hrt_get_current();
+	current_timer_count_work = timer_ovr_lower_set_count + sil_reh_mem(CMT1_CMCNT_ADDR);
+	if(current_timer_count_work >= CMCOR_PERIOD) {
+		timer_ovr_upper_set_count++;
+		timer_ovr_lower_set_count = current_timer_count_work - CMCOR_PERIOD;
+	}
+
+	/*
+	 * オーバランタイマ動作中フラグ
+	 */
+	timer_ovr_running_flg = true;
+
+	/*
+	 * 下位タイマ設定
+	 */
+	if(timer_ovr_upper_set_count == 0) {
+		if(timer_ovr_lower_set_count == 0) {
+			target_ovrtimer_raise_event();
+		}
+		else {
+			/*
+			 * コンペアマッチタイマカウンタクリア CMT2
+			 */
+			sil_wrh_mem(CMT2_CMCNT_ADDR, 0U);
+
+			/*
+			 * コンペアマッチタイマ周期設定 CMT2
+			 */
+			sil_wrh_mem(CMT2_CMCOR_ADDR, timer_ovr_lower_set_count);
+
+			/*
+			 *  タイマ動作開始前の割込み要求をクリア
+			 */
+			target_ovrtimer_int_clear();
+
+			/*
+			 * コンペアマッチタイマ割り込みを許可 CMT2
+			 */
+			sil_wrh_mem(CMT2_CMCR_ADDR,
+					sil_reh_mem(CMT2_CMCR_ADDR) | CMT2_CMCR_CMIE_BIT);
+
+			/*
+			 * タイマ動作開始 CMT2
+			 */
+			sil_wrh_mem(CMT_CMSTR1_ADDR,
+					sil_reh_mem(CMT_CMSTR1_ADDR) | CMT_CMSTR1_STR2_BIT);
+		}
+	}
+}
+
+/*
+ *  オーバランタイマの停止処理
+ */
+void
+target_ovrtimer_terminate(intptr_t exinf)
+{
+	/*
+	 * タイマ停止
+	 */
+	sil_wrh_mem(CMT_CMSTR1_ADDR,
+			sil_reh_mem(CMT_CMSTR1_ADDR) & ~CMT_CMSTR1_STR2_BIT);
+
+	/*
+	 * タイマ割り込み禁止
+	 */
+	sil_wrh_mem(CMT2_CMCR_ADDR,
+			sil_reh_mem(CMT2_CMCR_ADDR) & ~CMT2_CMCR_CMIE_BIT);
+
+	/*
+	 *  タイマ割込み要求をクリア
+	 */
+	target_ovrtimer_int_clear();
+
+	/*
+	 * オーバランタイマ動作中フラグ
+	 */
+	timer_ovr_running_flg = false;
+
+	/*
+	 * モジュールストップ機能の設定  CMTユニット0 停止
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRA_ADDR,
+			sil_rew_mem(SYSTEM_MSTPCRA_ADDR) | SYSTEM_MSTPCRA_MSTPA14_BIT);
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xA500);	/* 書込み禁止 */
+}
+
+/*
+ *  オーバランタイマの停止
+ */
+PRCTIM
+target_ovrtimer_stop(uint_t int_num)
+{
+	uint32_t	cnt;
+
+	/*
+	 * タイマ停止
+	 */
+	sil_wrh_mem(CMT_CMSTR1_ADDR,
+			sil_reh_mem(CMT_CMSTR1_ADDR) & ~CMT_CMSTR1_STR2_BIT);
+
+	/*
+	 * オーバランタイマ動作中フラグ
+	 */
+	timer_ovr_running_flg = false;
+
+	if(int_num == INTNO_TIMER2) {
+		/*
+		 *  オーバラン割込みの場合
+		 */
+		target_ovrtimer_int_clear();
+		return(0U);
+	}
+	else {
+		HRTCNT timer_ovr_hrt_current = target_hrt_get_current();
+		if((timer_ovr_hrt_current < timer_ovr_hrt_backup) && (int_num == INTNO_OVR_BASE_TIMER)) {
+			timer_ovr_hrt_current += (CMCOR_PERIOD / USEC_CONVERT_VALUE);
+		}
+
+		cnt = timer_ovr_ovrtim_backup - (timer_ovr_hrt_current - timer_ovr_hrt_backup);
+		if(timer_ovr_hrt_current < timer_ovr_hrt_backup) {
+			cnt += TCYC_HRTCNT;
+		}
+
+		if(cnt > timer_ovr_ovrtim_backup) { /* 設定時間を過ぎた */
+			cnt = 0;
+		}
+		return (PRCTIM)cnt;
+	}
+}
+
+/*
+ *  オーバランタイマの現在値の読出し
+ */
+PRCTIM
+target_ovrtimer_get_current(void)
+{
+	uint32_t	cnt;
+
+	if (probe_int(INTNO_TIMER2)) {
+		/*
+		 *  割込み要求が発生している場合
+		 */
+		return(0U);
+	}
+	else {
+		HRTCNT timer_ovr_hrt_current = target_hrt_get_current();
+		cnt = timer_ovr_ovrtim_backup - (timer_ovr_hrt_current - timer_ovr_hrt_backup);
+		if(timer_ovr_hrt_current < timer_ovr_hrt_backup) {
+			cnt += TCYC_HRTCNT;
+		}
+
+		if(cnt > timer_ovr_ovrtim_backup) { /* 設定時間を過ぎた */
+			cnt = 0;
+		}
+		return (PRCTIM)cnt;
+	}
+}
+
+/*
+ *  高分解能タイマ割込みの要求
+ */
+void
+target_ovrtimer_raise_event(void)
+{
+	/*
+	 * オーバラン下位タイマ強制割り込み起動
+	 * 注意：停止するまで割り込みが繰り返し発生する
+	 */
+	sil_wrh_mem(CMT2_CMCNT_ADDR, 0U);	/* カウンタ初期化	*/
+	clear_int(INTNO_TIMER2);			/* 要求クリア		*/
+	sil_wrh_mem(CMT2_CMCOR_ADDR, 0U);	/* マッチ周期設定	*/
+	sil_wrh_mem(CMT2_CMCR_ADDR,			/* 割り込み許可	*/
+			sil_reh_mem(CMT2_CMCR_ADDR) | CMT2_CMCR_CMIE_BIT);
+	sil_wrh_mem(CMT_CMSTR1_ADDR,		/* タイマ起動		*/
+			sil_reh_mem(CMT_CMSTR1_ADDR) | CMT_CMSTR1_STR2_BIT);
+}
+
+/*
+ *  オーバランタイマ割込みハンドラ
+ *
+ *  このルーチンに来るまでに，target_ovrtimer_stopが呼ばれているため，
+ *  OSタイマを停止する必要はない．
+ */
+void
+target_ovrtimer_handler(void)
+{
+	/*
+	 * タイマ割り込み禁止
+	 */
+	sil_wrh_mem(CMT2_CMCR_ADDR,
+			sil_reh_mem(CMT2_CMCR_ADDR) & ~CMT2_CMCR_CMIE_BIT);
+
+	/*
+	 * 上下位タイマカウンタクリア
+	 */
+	timer_ovr_upper_set_count = 0;
+	timer_ovr_lower_set_count = 0;
+
+	call_ovrhdr();	/* オーバランハンドラの起動処理 */
+}
+
+#endif /* TOPPERS_SUPPORT_OVRHDR */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_timer.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_timer.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_timer.cfg	(revision 398)
@@ -0,0 +1,22 @@
+/*
+ *  タイマドライバ（GR-SAKURA用）のコンフィギュレーションファイル
+ */
+
+#include "target_timer.h"
+
+ATT_INI({ TA_NULL, 0, target_timer_initialize });
+ATT_TER({ TA_NULL, 0, target_timer_terminate });
+DEF_INH(INHNO_TIMER0, { TA_NULL, target_lower_timer_handler });
+CFG_INT(INTNO_TIMER0, { INTATR_TIMER0, INTPRI_TIMER0 });
+DEF_INH(INHNO_TIMER1, { TA_NULL, target_upper_timer_handler });
+CFG_INT(INTNO_TIMER1, { INTATR_TIMER1, INTPRI_TIMER1 });
+
+/*
+ *  オーバランハンドラ用タイマドライバ（RX630用）のコンフィギュレーションファイル
+ */
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ATT_INI({ TA_NULL, 0, target_ovrtimer_initialize });
+ATT_TER({ TA_NULL, 0, target_ovrtimer_terminate }); 
+DEF_INH(INHNO_TIMER2, { TA_NULL, target_ovrtimer_handler });
+CFG_INT(INTNO_TIMER2, { INTATR_TIMER2, INTPRI_TIMER2 });
+#endif /* TOPPERS_SUPPORT_OVRHDR */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_timer.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_timer.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_timer.h	(revision 398)
@@ -0,0 +1,277 @@
+/*
+ *  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-2004 by Naoki Saito
+ *             Nagoya Municipal Industrial Research Institute, JAPAN
+ *  Copyright (C) 2003-2004 by Platform Development Center
+ *                                          RICOH COMPANY,LTD. JAPAN
+ *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
+ *  Copyright (C) 2013      by Mitsuhiro Matsuura
+ *  Copyright (C) 2017      by Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *		タイマドライバ（GR-SAKURA用）
+ */
+ 
+#ifndef TOPPERS_TARGET_TIMER_H
+#define TOPPERS_TARGET_TIMER_H
+
+#include "gr_sakura.h"
+#include "rx630_kernel_impl.h"
+#include "target_syssvc.h"
+
+/*
+ *  タイマ割込みハンドラ登録のための定数
+ */
+#define INHNO_TIMER0	INT_CMT0_CMI				/* 割込みハンドラ番号 */
+#define INTNO_TIMER0	INT_CMT0_CMI				/* 割込み番号 */
+#define INTPRI_TIMER0	-5							/* 割込み優先度 */
+#define INTATR_TIMER0	(TA_ENAINT | TA_EDGE)		/* 割込み属性 */
+
+#define INHNO_TIMER1	INT_CMT1_CMI				/* 割込みハンドラ番号 */
+#define INTNO_TIMER1	INT_CMT1_CMI				/* 割込み番号 */
+#define INTPRI_TIMER1	-5							/* 割込み優先度 */
+#define INTATR_TIMER1	(TA_ENAINT | TA_EDGE)		/* 割込み属性 */
+
+/*
+ *  オーバランタイマ割込みハンドラ登録のための定数
+ */
+#define INHNO_TIMER2	INT_CMT2_CMI				/* 割込みハンドラ番号 */
+#define INTNO_TIMER2	INT_CMT2_CMI				/* 割込み番号 */
+#define INTPRI_TIMER2	-5							/* 割込み優先度 */
+#define INTATR_TIMER2	(TA_ENAINT | TA_EDGE)		/* 割込み属性 */
+#define INTNO_OVR_BASE_TIMER	INTNO_TIMER1		/* 基本タイマに使うタイマ割込み番号 */
+#define INTNO_DUMMY_TIMER		255					/* ダミータイマ割込み番号 */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  タイマ値の内部表現の型
+ */
+typedef uint16_t	CLOCK;
+
+/*
+ *  タイマ値の内部表現とミリ秒単位との変換
+ *
+ *  1msのタイマー割り込みを使用するのでそのクロックを定義する．
+ */
+#define TIMER_CLOCK				(FREQ_PCLK / 8U)		/* PCLK/最低分周比8 = 6MHz */
+#define TO_CLOCK(nume, deno)	((CLOCK)(TIMER_CLOCK * (nume) / (deno)))
+#define	TO_USEC(clock)			((SYSUTM)((clock) * 1000U / TIMER_CLOCK))
+
+/*
+ *  コンペアマッチタイマコンスタントレジスタ（CMCOR）
+ *
+ *  コンペアマッチ周期
+ *  周辺モジュールクロック（PCLK）48MHzを8分周するので，
+ *  6カウント = 1us : max 10922.667us
+ */
+#define CMCOR_PERIOD	(0x10000U)
+
+/*
+ * カウント < - > マイクロ秒 変換値
+ * 48MHz / 8 / 1000
+ */
+#define USEC_CONVERT_VALUE	6U
+
+/*
+ *  高分解能タイマのタイマ周期
+ *
+ *  2^32 / 6
+ */
+#define TCYC_HRTCNT		715827882U	/* (0x100000000 / 6) = 715827882.667usec */
+
+/*
+ *  高分解能タイマのカウント値の進み幅
+ */
+#define TSTEP_HRTCNT	1U
+
+/*
+ *  性能評価用システム時刻を取り出す際の処理時間の見積り値（単位は内部表現）
+ */
+#define	GET_TOLERANCE	(100U)	/* 処理遅れの見積り値（単位は内部表現）*/
+#define	BEFORE_IREQ(clock) \
+		((clock) >= (TO_CLOCK(TIC_NUME, TIC_DENO) - GET_TOLERANCE))
+
+/*
+ *  コンペアマッチタイマコントロールレジスタの設定値
+ */
+/*
+ *  クロック選択ビット
+ *
+ *  bit7は予約領域であり, 書込みは1固定
+ */
+#define CMT_PCLK_DIV_8			(0x0080U)
+#define CMT_PCLK_DIV_32			(0x0081U)
+#define CMT_PCLK_DIV_128		(0x0082U)
+#define CMT_PCLK_DIV_512		(0x0083U)
+
+/*
+ * コンペアマッチタイマ割り込み要求先設定レジスタi（ISELRi）（i= 割り込みベクタ番号）
+ */
+#define ICU_ISEL_CPU			(0x00U)
+
+/*
+ *  タイマの起動処理
+ *
+ *  タイマを初期化し，周期的なタイマ割込み要求を発生させる．
+ */
+extern void	target_timer_initialize(intptr_t exinf);
+
+/*
+ *  タイマの停止処理
+ *
+ *  タイマの動作を停止させる．
+ */
+extern void	target_timer_terminate(intptr_t exinf);
+
+/*
+ *  タイマレジスタ値の読み出し
+ */
+Inline uint16_t rx630_cmt_getcount(void)
+{
+	return sil_reh_mem((uint16_t *)CMT0_CMCNT_ADDR);
+}
+
+/*
+ *  タイマレジスタ値の書き込み
+ */
+Inline void rx630_cmt_setcount(uint16_t count)
+{
+	sil_wrh_mem(CMT0_CMCNT_ADDR, count);
+}
+
+/*
+ *  タイマの現在値の読出し
+ */
+Inline CLOCK
+target_timer_get_current(void)
+{
+	/* アップカウントのためタイマレジスタ値をそのまま返す	*/
+	return (rx630_cmt_getcount());
+}
+
+/*
+ *  タイマ割込み要求のチェック
+ */
+Inline bool_t
+target_timer_probe_int(void)
+{
+	return(probe_int(INTNO_TIMER0));
+}
+
+/*
+ *  タイマ割込みハンドラ
+ */
+extern void	target_lower_timer_handler(void);
+extern void	target_upper_timer_handler(void);
+
+/*
+ *  割込みタイミングに指定する最大値
+ */
+#define HRTCNT_BOUND	100000002U
+
+/*
+ *  高分解能タイマへの割込みタイミングの設定
+ *
+ *  高分解能タイマを，hrtcntで指定した値カウントアップしたら割込みを発
+ *  生させるように設定する．
+ */
+extern void target_hrt_set_event(HRTCNT hrtcnt);
+
+/*
+ *  高分解能タイマ割込みの要求
+ */
+extern  void target_hrt_raise_event(void);
+
+/*
+ *  高分解能タイマの現在のカウント値の読出し　内部処理
+ */
+extern HRTCNT target_hrt_get_current_convert(void);
+
+/*
+ *  高分解能タイマの現在のカウント値の読出し
+ */
+Inline HRTCNT
+target_hrt_get_current(void)
+{
+	return (target_hrt_get_current_convert());
+}
+
+#ifdef TOPPERS_SUPPORT_OVRHDR
+
+/*
+ *  オーバランタイマの初期化処理
+ */
+extern void target_ovrtimer_initialize(intptr_t exinf);
+
+/*
+ *  オーバランタイマの停止処理
+ */
+extern void target_ovrtimer_terminate(intptr_t exinf);
+
+/*
+ *  オーバランタイマの動作開始
+ */
+extern void target_ovrtimer_start(PRCTIM ovrtim);
+
+/*
+ *  オーバランタイマの停止
+ */
+extern PRCTIM target_ovrtimer_stop(uint_t int_num);
+
+/*
+ *  オーバランタイマの現在値の読出し
+ */
+extern PRCTIM target_ovrtimer_get_current(void);
+
+/*
+ *  オーバランタイマの割込みの要求
+ */
+extern  void target_ovrtimer_raise_event(void);
+
+/*
+ *  オーバランタイマ割込みハンドラ
+ */
+extern void	target_ovrtimer_handler(void);
+
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_TARGET_TIMER_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_unrename.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_unrename.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/target_unrename.h	(revision 398)
@@ -0,0 +1,46 @@
+/* This file is generated from target_rename.def by genrename. */
+
+#ifndef TOPPERS_TARGET_UNRENAME_H
+#define TOPPERS_TARGET_UNRENAME_H
+
+/*
+ *  target_kernel_impl.c
+ */
+#undef target_initialize
+#undef target_exit
+
+/*
+ *  trace_config.c
+ */
+#undef log_dsp_enter
+#undef log_dsp_leave
+#undef log_inh_enter
+#undef log_inh_leave
+#undef log_exc_enter
+#undef log_exc_leave
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ *  target_kernel_impl.c
+ */
+#undef _target_initialize
+#undef _target_exit
+
+/*
+ *  trace_config.c
+ */
+#undef _log_dsp_enter
+#undef _log_dsp_leave
+#undef _log_inh_enter
+#undef _log_inh_leave
+#undef _log_exc_enter
+#undef _log_exc_leave
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "prc_unrename.h"
+
+#endif /* TOPPERS_TARGET_UNRENAME_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tinet_target_config.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tinet_target_config.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tinet_target_config.c	(revision 398)
@@ -0,0 +1,114 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ターゲット依存モジュール（RX63N用）
+ */
+
+#include <sil.h>
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+#include <rx630.h>
+
+#if defined(SUPPORT_ETHER)
+
+/*
+ *  rx62n_bus_init -- ターゲット依存部のバスの初期化
+ */
+
+void
+rx62n_bus_init (void)
+{
+	/* イーサネット・コントローラの動作を許可 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRB_ADDR,
+		sil_rew_mem(SYSTEM_MSTPCRB_ADDR) & ~SYSTEM_MSTPCRB_MSTPB15_BIT);
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, 0xA500);	/* 書込み禁止 */
+
+	/* EtherNET有効 */
+	/* PA3～5 RMII_MDIO, RMII_MDC, RMII_LINKSTA */
+	sil_wrb_mem(PORTA_PMR_ADDR,
+		sil_reb_mem(PORTA_PMR_ADDR) | (1 << 3) | (1 << 4) | (1 << 5));
+	/* PB0～7 RXD1, RXD0, REF50CK, RX-ER, TXD-EN, TXD0, TXD1, CRS */
+	sil_wrb_mem(PORTB_PMR_ADDR,
+		sil_reb_mem(PORTB_PMR_ADDR) | 0xFF);
+
+	/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+	/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+	/* PA3をET_MDIOとする */
+	sil_wrb_mem(MPC_PA3PFS_ADDR, 0x11); 
+	/* PA4をET_MDCとする */
+	sil_wrb_mem(MPC_PA4PFS_ADDR, 0x11); 
+	/* PA5をET_LINKSTAとする */
+	sil_wrb_mem(MPC_PA5PFS_ADDR, 0x11); 
+
+	/* PB0をRXD1とする */
+	sil_wrb_mem(MPC_PB0PFS_ADDR, 0x12);
+	/* PB1をRXD0とする */
+	sil_wrb_mem(MPC_PB1PFS_ADDR, 0x12);
+	/* PB2をREF50CKとする */
+	sil_wrb_mem(MPC_PB2PFS_ADDR, 0x12);
+	/* PB3をRX-ERとする */
+	sil_wrb_mem(MPC_PB3PFS_ADDR, 0x12);
+	/* PB4をTXD-ENとする */
+	sil_wrb_mem(MPC_PB4PFS_ADDR, 0x12);
+	/* PB5をTXD0とする */
+	sil_wrb_mem(MPC_PB5PFS_ADDR, 0x12);
+	/* PB6をTXD1とする */
+	sil_wrb_mem(MPC_PB6PFS_ADDR, 0x12);
+	/* PB7をCRSとする */
+	sil_wrb_mem(MPC_PB7PFS_ADDR, 0x12);
+
+	/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+	sil_wrb_mem(MPC_PWPR_ADDR , 0x80);
+}
+
+/*
+ *  rx62n_inter_init -- ターゲット依存部の割込みの初期化
+ */
+
+void
+rx62n_inter_init (void)
+{
+}
+
+#endif	/* of #if defined(SUPPORT_ETHER) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tinet_target_config.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tinet_target_config.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tinet_target_config.h	(revision 398)
@@ -0,0 +1,535 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TINET_TARGET_CONFIG_H_
+#define _TINET_TARGET_CONFIG_H_
+
+/*
+ *  TCP/IP に関する定義
+ */
+
+/* TCP に関する定義 */
+
+/*
+ *  MAX_TCP_SND_SEG: 送信セグメントサイズの最大値
+ *
+ *    相手から MSS オプションでセグメントサイズを指定されても、
+ *    この値で、セグメントサイズを制限できる。
+ */
+
+#ifndef MAX_TCP_SND_SEG
+#define MAX_TCP_SND_SEG		(IF_MTU - (IP_HDR_SIZE + TCP_HDR_SIZE))
+#endif	/* of #ifndef MAX_TCP_SND_SEG */
+
+/*
+ *  DEF_TCP_RCV_SEG: 受信セグメントサイズの規定値
+ */
+
+#ifndef DEF_TCP_RCV_SEG
+#define DEF_TCP_RCV_SEG		(IF_MTU - (IP_HDR_SIZE + TCP_HDR_SIZE))
+#endif	/* of #ifndef DEF_TCP_RCV_SEG */
+
+/* 
+ *  セグメントの順番を入れ替えるときに新たにネットワークバッファを割当てて、
+ *  データをコピーするサイズのしきい値
+ */
+#define MAX_TCP_REALLOC_SIZE	1024	
+
+#define TCP_CFG_OPT_MSS		/* コネクション開設時に、セグメントサイズオプションをつけて送信する。*/
+#define TCP_CFG_DELAY_ACK	/* ACK を遅らせるときはコメントを外す。			*/
+#define TCP_CFG_ALWAYS_KEEP	/* 常にキープアライブする時はコメントを外す。		*/
+
+/* UDP に関する定義 */
+
+#define UDP_CFG_IN_CHECKSUM	/* UDP の入力チェックサムを行う場合はコメントを外す。	*/
+#define UDP_CFG_OUT_CHECKSUM	/* UDP の出力チェックサムを行う場合はコメントを外す。	*/
+
+/* ICMPv4/v6 に関する定義 */
+
+#define ICMP_REPLY_ERROR		/* ICMP エラーメッセージを送信する場合はコメントを外す。*/
+
+/* IPv4 に関する定義 */
+
+//#define IP4_CFG_FRAGMENT		/* データグラムの分割・再構成行う場合はコメントを外す。	*/
+#define NUM_IP4_FRAG_QUEUE	2	/* データグラム再構成キューサイズ			*/
+#define IP4_CFG_FRAG_REASSM_SIZE	4096	/* IPv4 再構成バッファサイズ			*/
+
+/* IPv6 に関する定義 */
+
+#define NUM_IP6_DAD_COUNT	1	/* 重複アドレス検出で送信する近隣要請の回数、		*/
+					/*  0 を指定すると、重複アドレス検出を行わない。	*/
+#define NUM_ND6_CACHE_ENTRY	10	/* 近隣キャッシュのエントリ数			*/
+
+/*
+ *  IPv6 用ホストキャッシュのエントリ数。
+ *  0 を指定するとIPv6 用ホストキャッシュを組込まない。
+ */
+#define NUM_IN6_HOSTCACHE_ENTRY	4
+
+#ifdef SUPPORT_ETHER
+
+#define IP6_CFG_AUTO_LINKLOCAL		/* リンクローカルアドレスの自動設定を行う場合はコメントを外す。*/
+
+/*
+ *  ディフォルトルータリストに関する定義
+ */
+
+/*
+ *  ディフォルトルータリストのエントリ数。
+ *  最大値は 16、0 を指定するとルータ通知を受信しない。
+ */
+#define NUM_ND6_DEF_RTR_ENTRY		4
+
+/*
+ *  プレフィックスリストに関する定義。
+ *  最大値は 16。
+ */
+#define NUM_ND6_PREFIX_ENTRY		4	/*  プレフィックスリストのエントリ数			*/
+
+/*
+ *  起動時のルータ要請出力回数。
+ *  0 を指定するとルータ要請を出力しない。
+ */
+#define NUM_ND6_RTR_SOL_RETRY	3	
+
+#define IP6_CFG_FRAGMENT		/* データグラムの分割・再構成行う場合はコメントを外す。	*/
+#define NUM_IP6_FRAG_QUEUE	2	/* データグラム再構成キューサイズ			*/
+#define IP6_CFG_FRAG_REASSM_SIZE	4096	/* IPv6 再構成バッファサイズ			*/
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+/*
+ *  データリンク層 (ネットワークインタフェース) に関する定義
+ */
+
+/*
+ *  PPP、モデムに関する定義
+ */
+
+#define MODEM_CFG_DIAL		"ATD"	/* ダイアルコマンド文字列			*/
+#define MODEM_CFG_RETRY_CNT	3	/* ダイアルリトライ回数			*/
+#define MODEM_CFG_RETRY_WAIT	10000	/* ダイアルリトライまでの待ち時間 [ms]	*/
+
+/*
+ *  PPP、HDLC に関する定義
+ */
+
+#define DEF_LOCAL_ACCM		ULONG_C(0x000a0000)	/* 自分の ACCM、XON と XOFF のみ変換	*/
+#define DEF_REMOTE_ACCM		ULONG_C(0xffffffff)	/* 相手の ACCM、初期値は全て変換		*/
+
+/*
+ *  PPP、LCP に関する定義
+ */
+
+#define LCP_CFG_MRU		UINT_C(0x0001)	/* MRU					*/
+#define LCP_CFG_ACCM		UINT_C(0x0002)	/* ACCM					*/
+#define LCP_CFG_MAGIC		UINT_C(0x0004)	/* マジック番号				*/
+#define LCP_CFG_PCOMP		UINT_C(0x0008)	/* プロトコル部圧縮機能			*/
+#define LCP_CFG_ACCOMP		UINT_C(0x0010)	/* アドレス・制御部圧縮			*/
+#define LCP_CFG_PAP		UINT_C(0x0020)	/* PAP					*/
+/*#define LCP_CFG_CHAP		UINT_C(0x0040)	   CHAP は実装予定			*/
+
+#ifdef LCP_CFG_MAGIC
+
+#define LCP_ECHO_INTERVAL	(20*NET_TIMER_HZ)	/* インターバル時間		*/
+#define LCP_ECHO_FAILS		9			/* 失敗閾値			*/
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+/*
+ *  PPP、PAP に関する定義
+ */
+
+#define DEF_PAP_TIMEOUT		(3*NET_TIMER_HZ)
+#define DEF_PAP_REQTIME		(30*NET_TIMER_HZ)	/* タイムアウト処理を行うときはコメントを外す。*/
+#define MAX_PAP_REXMT		10			/* 認証要求の最大再送回数	*/
+
+/*
+ *  RX63N Ethernet Controler に関する定義
+ */
+
+#define NUM_IF_RX62N_TXBUF		2	/* 送信バッファ数			*/
+#define NUM_IF_RX62N_RXBUF		2	/* 受信バッファ数			*/
+#define IF_RX62N_BUF_PAGE_SIZE	1518	/* バッファサイズ */
+
+#define TMO_IF_RX62N_GET_NET_BUF	1000	/* [us]、受信用 net_buf 獲得タイムアウト	*/
+					/* [s]、 送信タイムアウト			*/
+#define TMO_IF_RX62N_XMIT		(2*IF_TIMER_HZ)
+
+/*#define IF_RX62N_CFG_ACCEPT_ALL		 マルチキャスト、エラーフレームも受信するときはコメントを外す。*/
+
+/*
+ *  Bluetooth USB PAN に関する定義
+ */
+
+#define NUM_IF_BTUSB_TXBUF		2	/* 送信バッファ数			*/
+#define NUM_IF_BTUSB_RXBUF		2	/* 受信バッファ数			*/
+#define IF_BTUSB_BUF_PAGE_SIZE	1518	/* バッファサイズ */
+
+#define TMO_IF_BTUSB_GET_NET_BUF	1	/* [ms]、受信用 net_buf 獲得タイムアウト	*/
+					/* [s]、 送信タイムアウト			*/
+#define TMO_IF_BTUSB_XMIT		(2*IF_TIMER_HZ)
+
+/*
+ *  イーサネット出力時に、NIC で net_buf を開放する場合に指定する。
+ *
+ *  注意: 以下の指定は、指定例であり、if_rx62n では、
+ *        開放しないので、以下のコメントを外してはならない。
+ */
+
+/*#define ETHER_NIC_CFG_RELEASE_NET_BUF*/
+
+/*
+ *  RX63N Ethernet Controller に関する定義
+ */
+
+#define RX63N_BASE_ADDRESS		ULONG_C(0x00200000)	/* NIC のレジスタベースアドレス */
+
+#define INHNO_IF_RX62N_TRX	INT_ETH_EINT	/* パケット送受信 */
+#define INTNO_IF_RX62N_TRX	INT_ETH_EINT	/* パケット送受信 */
+#define INTATR_IF_RX62N_TRX	(TA_NULL)	/* 割込み属性	*/
+#define INTPRI_IF_RX62N_TRX	(-1)		/* 割込み優先度	*/
+
+/*
+ *  ARP に関する定義
+ */
+
+#define NUM_ARP_ENTRY		10			/* ARP キャッシュエントリ数	*/
+
+/*
+ *  DHCP に関する定義
+ *
+ *    ・注意: TINET は、DHCP を実装していない。応用プログラムで、
+ *            DHCP メッセージを受信するための定義である。
+ *            また、現在は IPv4 のみ有効である。
+ */
+
+#define DHCP_CFG					 /* DHCP を処理する場合はコメントを外す。*/
+
+/*
+ *  Ethernet に関する定義
+ */
+
+/*#define ETHER_CFG_ACCEPT_ALL		 マルチキャスト、エラーフレームも受信するときはコメントを外す。	*/
+/*#define ETHER_CFG_UNEXP_WARNING	 非サポートフレームの警告を表示するときはコメントを外す。		*/
+/*#define ETHER_CFG_802_WARNING		 IEEE 802.3 フレームの警告を表示するときはコメントを外す。		*/
+/*#define ETHER_CFG_MCAST_WARNING	 マルチキャストの警告を表示するときはコメントを外す。		*/
+#define ETHER_CFG_MULTICAST			/* マルチキャストを送受信 */
+
+/*
+ *  アドレスリストに関する定義。
+ */
+#define NUM_IN6_IFADDR_ENTRY		5	/*  インタフェースのアドレスリストのエントリ数		*/
+
+/*
+ *  汎用ネットワークに関する定義
+ */
+
+/*
+ *  ネットワークバッファに関する定義
+ */
+
+/* ネットワークバッファ数 */
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  PPP では、受信用の ネットワークバッファは PDU (1502) サイズを常に
+ *  割り当てなければならないので PDU サイズを多めに確保する。
+ */
+
+#ifndef NUM_MPF_NET_BUF_CSEG
+#define NUM_MPF_NET_BUF_CSEG	2	/* IF + IP + TCP、2 以上*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_CSEG */
+
+#ifndef NUM_MPF_NET_BUF_64
+#define NUM_MPF_NET_BUF_64	0	/* 64 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_64 */
+
+#ifndef NUM_MPF_NET_BUF_128
+#define NUM_MPF_NET_BUF_128	0	/* 128 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_128 */
+
+#ifndef NUM_MPF_NET_BUF_256
+#define NUM_MPF_NET_BUF_256	0	/* 256 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_256 */
+
+#ifndef NUM_MPF_NET_BUF_512
+#define NUM_MPF_NET_BUF_512	0	/* 512 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_512 */
+
+#ifndef NUM_MPF_NET_BUF_1024
+#define NUM_MPF_NET_BUF_1024	0	/* 1024 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_1024 */
+
+#ifndef NUM_MPF_NET_BUF_IF_PDU
+#define NUM_MPF_NET_BUF_IF_PDU	2	/* IF 最大 PDU サイズ	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_IF_PDU */
+
+#ifndef NUM_MPF_NET_BUF4_REASSM
+
+#if defined(SUPPORT_INET4) && defined(IP4_CFG_FRAGMENT)
+#define NUM_MPF_NET_BUF4_REASSM	2	/* IPv4 再構成バッファサイズ	*/
+#else
+#define NUM_MPF_NET_BUF4_REASSM	0	/* IPv4 再構成バッファサイズ	*/
+#endif
+
+#endif	/* of #ifndef NUM_MPF_NET_BUF4_REASSM */
+
+#ifndef NUM_MPF_NET_BUF6_REASSM
+
+#if defined(SUPPORT_INET6) && defined(IP6_CFG_FRAGMENT)
+#define NUM_MPF_NET_BUF6_REASSM	2	/* IPv6 再構成バッファサイズ	*/
+#else
+#define NUM_MPF_NET_BUF6_REASSM	0	/* IPv6 再構成バッファサイズ	*/
+#endif
+
+#endif	/* of #ifndef NUM_MPF_NET_BUF6_REASSM */
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  イーサネットの場合のネットワークバッファ数の割り当て
+ */
+
+/*
+ *  注意!!
+ *
+ *  RX63N Ethernet Controler のディバイスドライバ（if_rx62n）の最低割当て長は
+ *  60（アラインして 62）オクテットのため IF + IP +TCP よりは
+ *  64 オクテットのネットワークバッファの方が最適である。
+ */
+
+#ifndef NUM_MPF_NET_BUF_CSEG
+#define NUM_MPF_NET_BUF_CSEG	0	/* IF + IP + TCP	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_CSEG */
+
+#ifndef NUM_MPF_NET_BUF_64
+#define NUM_MPF_NET_BUF_64	2	/* 64 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_64 */
+
+#ifndef NUM_MPF_NET_BUF_128
+#define NUM_MPF_NET_BUF_128	0	/* 128 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_128 */
+
+#ifndef NUM_MPF_NET_BUF_256
+#define NUM_MPF_NET_BUF_256	0	/* 256 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_256 */
+
+#ifndef NUM_MPF_NET_BUF_512
+#define NUM_MPF_NET_BUF_512	0	/* 512 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_512 */
+
+#if defined(SUPPORT_INET4)
+
+#ifndef NUM_MPF_NET_BUF_IP_MSS
+#define NUM_MPF_NET_BUF_IP_MSS	0	/* IF + 576 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_IP_MSS */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#ifndef NUM_MPF_NET_BUF_1024
+#define NUM_MPF_NET_BUF_1024	0	/* 1024 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_1024 */
+
+#if defined(SUPPORT_INET6)
+
+#ifndef NUM_MPF_NET_BUF_IPV6_MMTU
+#define NUM_MPF_NET_BUF_IPV6_MMTU	0	/* IF + 1280	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_IPV6_MMTU */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#ifndef NUM_MPF_NET_BUF_IF_PDU
+#define NUM_MPF_NET_BUF_IF_PDU	4	/* IF 最大 PDU サイズ	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_IF_PDU */
+
+#ifndef NUM_MPF_NET_BUF4_REASSM
+
+#if defined(SUPPORT_INET4) && defined(IP4_CFG_FRAGMENT)
+#define NUM_MPF_NET_BUF4_REASSM	2	/* IPv4 再構成バッファサイズ	*/
+#else
+#define NUM_MPF_NET_BUF4_REASSM	0	/* IPv4 再構成バッファサイズ	*/
+#endif
+
+#endif	/* of #ifndef NUM_MPF_NET_BUF4_REASSM */
+
+#ifndef NUM_MPF_NET_BUF6_REASSM
+
+#if defined(SUPPORT_INET6) && defined(IP6_CFG_FRAGMENT)
+#define NUM_MPF_NET_BUF6_REASSM	2	/* IPv6 再構成バッファサイズ	*/
+#else
+#define NUM_MPF_NET_BUF6_REASSM	0	/* IPv6 再構成バッファサイズ	*/
+#endif
+
+#endif	/* of #ifndef NUM_MPF_NET_BUF6_REASSM */
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#ifdef SUPPORT_LOOP
+
+#ifndef NUM_MPF_NET_BUF_CSEG
+#define NUM_MPF_NET_BUF_CSEG	2	/* IF + IP + TCP	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_CSEG */
+
+#ifndef NUM_MPF_NET_BUF_64
+#define NUM_MPF_NET_BUF_64	0	/* 64 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_64 */
+
+#ifndef NUM_MPF_NET_BUF_128
+#define NUM_MPF_NET_BUF_128	0	/* 128 オクテット、2 以上	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_128 */
+
+#ifndef NUM_MPF_NET_BUF_256
+#define NUM_MPF_NET_BUF_256	0	/* 256 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_256 */
+
+#ifndef NUM_MPF_NET_BUF_512
+#define NUM_MPF_NET_BUF_512	0	/* 512 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_512 */
+
+#ifndef NUM_MPF_NET_BUF_1024
+#define NUM_MPF_NET_BUF_1024	0	/* 1024 オクテット	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_1024 */
+
+#ifndef NUM_MPF_NET_BUF_IF_PDU
+#define NUM_MPF_NET_BUF_IF_PDU	4	/* IF 最大 PDU サイズ	*/
+#endif	/* of #ifndef NUM_MPF_NET_BUF_IF_PDU */
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+/*
+ *  ネットワーク統計情報の計測
+ *
+ *  ネットワーク統計情報の計測を行う場合は、tinet/include/net/net.h
+ *  で定義されているプロトコル識別フラグを指定する。
+ */
+
+#if 1
+
+#ifdef SUPPORT_INET6
+
+#ifdef SUPPORT_INET4
+
+#define NET_COUNT_ENABLE	(0			\
+				| PROTO_FLG_PPP_HDLC	\
+				| PROTO_FLG_PPP_PAP	\
+				| PROTO_FLG_PPP_LCP	\
+				| PROTO_FLG_PPP_IPCP	\
+				| PROTO_FLG_PPP		\
+				| PROTO_FLG_LOOP	\
+				| PROTO_FLG_ETHER_NIC	\
+				| PROTO_FLG_ETHER	\
+				| PROTO_FLG_IP6		\
+				| PROTO_FLG_ICMP6	\
+				| PROTO_FLG_ND6		\
+				| PROTO_FLG_ARP		\
+				| PROTO_FLG_IP4		\
+				| PROTO_FLG_ICMP4	\
+				| PROTO_FLG_TCP		\
+				| PROTO_FLG_UDP		\
+				| PROTO_FLG_NET_BUF	\
+				)
+
+#else	/* of #ifdef SUPPORT_INET4 */
+
+#define NET_COUNT_ENABLE	(0			\
+				| PROTO_FLG_PPP_HDLC	\
+				| PROTO_FLG_PPP_PAP	\
+				| PROTO_FLG_PPP_LCP	\
+				| PROTO_FLG_PPP_IPCP	\
+				| PROTO_FLG_PPP		\
+				| PROTO_FLG_LOOP	\
+				| PROTO_FLG_ETHER_NIC	\
+				| PROTO_FLG_ETHER	\
+				| PROTO_FLG_IP6		\
+				| PROTO_FLG_ICMP6	\
+				| PROTO_FLG_ND6		\
+				| PROTO_FLG_TCP		\
+				| PROTO_FLG_UDP		\
+				| PROTO_FLG_NET_BUF	\
+				)
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+#define NET_COUNT_ENABLE	(0			\
+				| PROTO_FLG_PPP_HDLC	\
+				| PROTO_FLG_PPP_PAP	\
+				| PROTO_FLG_PPP_LCP	\
+				| PROTO_FLG_PPP_IPCP	\
+				| PROTO_FLG_PPP		\
+				| PROTO_FLG_LOOP	\
+				| PROTO_FLG_ETHER_NIC	\
+				| PROTO_FLG_ETHER	\
+				| PROTO_FLG_ARP		\
+				| PROTO_FLG_IP4		\
+				| PROTO_FLG_ICMP4	\
+				| PROTO_FLG_TCP		\
+				| PROTO_FLG_UDP		\
+				| PROTO_FLG_NET_BUF	\
+				)
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#else	/* of #if 0 */
+
+#define NET_COUNT_ENABLE	(0			\
+				)
+
+#endif	/* of #if 0 */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ *  関数
+ */
+
+extern void rx62n_bus_init (void);
+extern void rx62n_inter_init (void);
+
+#endif	/* of #ifndef TOPPERS_MACRO_ONLY */
+
+#endif /* _TINET_TARGET_CONFIG_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tinet_target_defs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tinet_target_defs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/target/gr_sakura_gcc/tinet_target_defs.h	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TINET_TARGET_DEFS_H_
+#define _TINET_TARGET_DEFS_H_
+
+/*
+ *  ネットワークに関する定義
+ */
+
+/*
+ *  CPU のアライメントに関する定義
+ *
+ *  4 オクテット単位で、アラインする必要がある場合は 4 を指定する。
+ */
+
+#define CPU_NET_ALIGN		2
+
+#endif /* _TINET_TARGET_DEFS_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/init_tecs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/init_tecs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/init_tecs.c	(revision 398)
@@ -0,0 +1,13 @@
+/*
+ *		TECSの初期化処理
+ *
+ *  $Id$
+ */
+
+#include "global_tecsgen.h"
+
+void
+initialize_tecs(void)
+{
+	INITIALIZE_TECS();
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/kernel.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/kernel.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/kernel.cdl	(revision 398)
@@ -0,0 +1,800 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015,2016 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015-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$
+ */
+
+/*
+ *		TOPPERS/ASPカーネルオブジェクト コンポーネント記述ファイル
+ */
+
+/*
+ *  カーネルオブジェクトのコンポーネント化のためのヘッダファイル
+ */
+import_C("tecs_kernel.h");
+
+/*
+ *  カーネル操作のシグニチャ（タスクコンテキスト用）
+ */
+signature sKernel {
+	ER		getExtendedInformation([out] intptr_t *p_exinf);
+
+	ER		sleep(void);
+	ER		sleepTimeout([in] TMO timeout);
+	ER		delay([in] RELTIM delayTime);
+
+	ER		exit(void);
+	ER		disableTerminate(void);
+	ER		enableTerminate(void);
+	bool_t	senseTerminate(void);
+
+	ER		setTime([in] SYSTIM systemTime);
+	ER		getTime([out] SYSTIM *p_systemTime);
+	ER		adjustTime([in] int32_t adjustTime);
+	HRTCNT	fetchHighResolutionTimer(void);
+
+	ER		rotateReadyQueue([in] PRI taskPriority);
+	ER		getTaskId([out] ID *p_taskId);
+	ER		getLoad([in] PRI taskPriority, [out] uint_t *p_load);
+	ER		getNthTask([in] PRI taskPriority, [in] uint_t nth,
+												[out] ID *p_taskID);
+	ER		lockCpu(void);
+	ER		unlockCpu(void);
+	ER		disableDispatch(void);
+	ER		enableDispatch(void);
+	bool_t	senseContext(void);
+	bool_t	senseLock(void);
+	bool_t	senseDispatch(void);
+	bool_t	senseDispatchPendingState(void);
+	bool_t	senseKernel(void);
+	ER		exitKernel(void);
+
+	ER		changeInterruptPriorityMask([in] PRI interruptPriority);
+	ER		getInterruptPriorityMask([out] PRI *p_interruptPriority);
+};
+
+/*
+ *  カーネル操作のシグニチャ（非タスクコンテキスト用）
+ */
+[context("non-task")]
+signature siKernel {
+	HRTCNT	fetchHighResolutionTimer(void);
+
+	ER		rotateReadyQueue([in] PRI taskPriority);
+	ER		getTaskId([out]ID *p_taskId);
+	ER		lockCpu(void);
+	ER		unlockCpu(void);
+	bool_t	senseContext(void);
+	bool_t	senseLock(void);
+	bool_t	senseDispatch(void);
+	bool_t	senseDispatchPendingState(void);
+	bool_t	senseKernel(void);
+	ER		exitKernel(void);
+
+	/* CPU例外ハンドラ中で使用する */
+	bool_t	exceptionSenseDispatchPendingState
+						([in] const void *p_exceptionInformation);
+};
+
+/*
+ *  カーネルのセルタイプ
+ */
+[singleton]
+celltype tKernel {
+	[inline] entry	sKernel		eKernel;
+	[inline] entry	siKernel	eiKernel;
+};
+
+/*
+ *  タイムイベント通知を受け取るためのシグネチャ
+ */
+[context("non-task")]
+signature siNotificationHandler {
+};
+
+/*
+ *  タスク本体のシグニチャ
+ */
+signature sTaskBody {
+	void	main(void);
+};
+
+/*
+ *  タスク操作のシグニチャ（タスクコンテキスト用）
+ */
+signature sTask {
+	ER		activate(void);
+	ER_UINT	cancelActivate(void);
+	ER		getTaskState([out] STAT *p_tskstat);
+	ER		changePriority([in] PRI priority);
+	ER		getPriority([out] PRI *p_priority);
+	ER		refer([out] T_RTSK *pk_taskStatus);
+
+	ER		wakeup(void);
+	ER_UINT	cancelWakeup(void);
+	ER		releaseWait(void);
+	ER		suspend(void);
+	ER		resume(void);
+
+	ER		raiseTerminate(void);
+	ER		terminate(void);
+};
+
+/*
+ *  タスク操作のシグニチャ（非タスクコンテキスト用）
+ */
+[context("non-task")]
+signature siTask {
+	ER		activate(void);
+	ER		wakeup(void);
+	ER		releaseWait(void);
+};
+
+/*
+ *  タスクのセルタイプ
+ */
+[active]
+celltype tTask {
+	[inline] entry	sTask	eTask;
+	[inline] entry	siTask	eiTask;
+	call	sTaskBody	cTaskBody;
+
+	[inline] entry	siNotificationHandler	eiActivateNotificationHandler;
+	[inline] entry	siNotificationHandler	eiWakeUpNotificationHandler;
+
+	attr {
+		ID				id = C_EXP("TSKID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] PRI		priority;
+		[omit] size_t	stackSize;
+	};
+
+	factory {
+		write("tecsgen.cfg",
+				"CRE_TSK(%s, { %s, $cbp$, tTask_start, %s, %s, NULL });",
+									id, attribute, priority, stackSize);
+	};
+	FACTORY {
+		write("tecsgen.cfg", "#include \"$ct$_tecsgen.h\"");
+		write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
+	};
+};
+
+/*
+ *  セマフォ操作のシグニチャ（タスクコンテキスト用）
+ */
+signature sSemaphore {
+	ER		signal(void);
+	ER		wait(void);
+	ER		waitPolling(void);
+	ER		waitTimeout([in] TMO timeout);
+	ER		initialize(void);
+	ER		refer([out] T_RSEM *pk_semaphoreStatus);
+};
+
+/*
+ *  セマフォ操作のシグニチャ（非タスクコンテキスト用）
+ */
+[context("non-task")]
+signature siSemaphore {
+	ER		signal(void);
+};
+
+/*
+ *  セマフォのセルタイプ
+ */
+celltype tSemaphore {
+	[inline] entry	sSemaphore	eSemaphore;
+	[inline] entry	siSemaphore	eiSemaphore;
+
+	[inline] entry	siNotificationHandler	eiNotificationHandler;
+
+	attr {
+		ID				id = C_EXP("SEMID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] uint_t	initialCount;
+		[omit] uint_t	maxCount = 1;
+	};
+
+	factory {
+		write("tecsgen.cfg", "CRE_SEM(%s, { %s, %s, %s });",
+								id, attribute, initialCount, maxCount);
+	};
+	FACTORY {
+		write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
+	};
+};
+
+/*
+ *  イベントフラグ操作のシグニチャ（タスクコンテキスト用）
+ */
+signature sEventflag {
+	ER		set([in] FLGPTN setPattern);
+	ER		clear([in] FLGPTN clearPattern);
+	ER		wait([in] FLGPTN waitPattern, [in] MODE waitMode,
+											[out] FLGPTN *p_flagPattern);
+	ER		waitPolling([in] FLGPTN waitPattern, [in] MODE waitMode,
+											[out] FLGPTN *p_flagPattern);
+	ER		waitTimeout([in] FLGPTN waitPattern, [in] MODE waitMode,
+							[out] FLGPTN *p_flagPattern, [in] TMO timeout);
+	ER		initialize(void);
+	ER		refer([out] T_RFLG *pk_eventflagStatus);
+};
+
+/*
+ *  イベントフラグ操作のシグニチャ（非タスクコンテキスト用）
+ */
+[context("non-task")]
+signature siEventflag {
+	ER		set([in] FLGPTN setPattern);
+};
+
+/*
+ *  イベントフラグのセルタイプ
+ */
+celltype tEventflag {
+	[inline] entry	sEventflag	eEventflag;
+	[inline] entry	siEventflag	eiEventflag;
+
+	[inline] entry	siNotificationHandler	eiNotificationHandler;
+
+	attr {
+		ID				id = C_EXP("FLGID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] FLGPTN	flagPattern;
+	};
+
+	factory {
+		write("tecsgen.cfg", "CRE_FLG(%s, { %s, %s });",
+									id, attribute, flagPattern);
+	};
+	FACTORY {
+		write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
+	};
+};
+
+/*
+ *  データキュー操作のシグニチャ（タスクコンテキスト用）
+ */
+signature sDataqueue {
+	ER 		send([in] intptr_t data);
+	ER 		sendPolling([in] intptr_t data);
+	ER 		sendTimeout([in] intptr_t data, [in] TMO timeout);
+	ER 		sendForce([in] intptr_t data);
+	ER 		receive([out] intptr_t *p_data);
+	ER 		receivePolling([out] intptr_t *p_Data);
+	ER 		receiveTimeout([out] intptr_t *p_data, [in] TMO timeout);
+	ER 		initialize(void);
+	ER 		refer([out] T_RDTQ *pk_dataqueueStatus);
+};
+
+/*
+ *  データキュー操作のシグニチャ（非タスクコンテキスト用）
+ */
+[context("non-task")]
+signature siDataqueue {
+	ER		sendPolling([in] intptr_t data);
+	ER		sendForce([in] intptr_t data);
+};
+
+/*
+ *  データキューのセルタイプ
+ */
+celltype tDataqueue {
+	[inline] entry	sDataqueue	eDataqueue;
+	[inline] entry	siDataqueue	eiDataqueue;
+
+	[inline] entry	siNotificationHandler	eiNotificationHandler;
+
+	attr {
+		ID				id = C_EXP("DTQID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] uint_t	dataCount = 1;
+		[omit] void		*dataqueueManagementBuffer = C_EXP("NULL");
+	};
+
+	factory {
+		write("tecsgen.cfg", "CRE_DTQ(%s, { %s, %s, %s });",
+						id, attribute, dataCount, dataqueueManagementBuffer);
+	};
+	FACTORY {
+		write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
+	};
+};
+
+/*
+ *  優先度データキュー操作のシグニチャ（タスクコンテキスト用）
+ */
+signature sPriorityDataqueue {
+	ER 		send([in] intptr_t data, [in] PRI dataPriority);
+	ER 		sendPolling([in] intptr_t data, [in] PRI dataPriority);
+	ER 		sendTimeout([in] intptr_t data, [in] PRI dataPriority,
+													[in] TMO timeout);
+	ER 		receive([out] intptr_t *p_data, [out] PRI *p_dataPriority);
+	ER 		receivePolling([out] intptr_t *p_data, [out] PRI *p_dataPriority);
+ 	ER 		receiveTimeout([out] intptr_t *p_data, [out] PRI *p_dataPriority,
+													[in] TMO timeout);
+	ER 		initialize(void);
+	ER 		refer([out] T_RPDQ *pk_priorityDataqueueStatus);
+};
+
+/*
+ *  優先度データキュー操作のシグニチャ（非タスクコンテキスト用）
+ */
+[context("non-task")]
+signature siPriorityDataqueue {
+	ER		sendPolling([in] intptr_t data, [in] PRI dataPriority);
+};
+
+/*
+ *  優先度データキューのセルタイプ
+ */
+celltype tPriorityDataqueue {
+	[inline] entry	sPriorityDataqueue	ePriorityDataqueue;
+	[inline] entry	siPriorityDataqueue	eiPriorityDataqueue;
+
+	attr {
+		ID				id = C_EXP("PDTQID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] uint_t	dataCount = 1;
+		[omit] PRI		maxDataPriority;
+		[omit] void		*priorityDataqueueManagementBuffer = C_EXP("NULL");
+	};
+
+	factory {
+		write("tecsgen.cfg", "CRE_PDQ(%s, { %s, %s, %s, %s});",
+								id, attribute, dataCount, maxDataPriority,
+								priorityDataqueueManagementBuffer);
+	};
+	FACTORY {
+		write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
+	};
+};
+
+/*
+ *  ミューテックス操作のシグニチャ（タスクコンテキスト用）
+ */
+signature sMutex {
+	ER		lock(void);
+	ER		lockPolling(void);
+	ER		lockTimeout([in] TMO timeout);
+	ER		unlock(void);
+	ER		initialize(void);
+	ER		refer([out] T_RSEM *pk_mutexStatus);
+};
+
+/*
+ *  ミューテックスのセルタイプ
+ */
+celltype tMutex {
+	[inline] entry	sMutex	eMutex;
+
+	attr {
+		ID				id = C_EXP("MTXID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] PRI		ceilingPriority;
+	};
+
+	factory {
+		write("tecsgen.cfg", "CRE_MTX(%s, { %s, %s });",
+								id, attribute, ceilingPriority);
+	};
+	FACTORY {
+		write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
+	};
+};
+
+/*
+ *  固定長メモリメモリプール操作のシグニチャ（タスクコンテキスト用）
+ */
+[deviate]
+signature sFixedSizeMemoryPool {
+	ER 		get([out] void **p_block);
+	ER 		getPolling([out] void **p_block);
+	ER 		getTimeout([out] void **p_block, [in] TMO timeout);
+	ER 		release([in] const void *block);
+	ER 		initialize(void);
+	ER 		refer([out] T_RMPF *pk_fixedSizeMemoryPoolStatus);
+};
+
+/*
+ *  固定長メモリプールのセルタイプ
+ */
+celltype tFixedSizeMemoryPool {
+	[inline] entry	sFixedSizeMemoryPool	eFixedSizeMemoryPool;
+
+	attr {
+		ID				id = C_EXP("MPFID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] uint_t	blockCount;
+		[omit] uint_t	blockSize;
+		[omit] MPF_T	*memoryPool = C_EXP("NULL");
+		[omit] void 	*memoryPoolManagementBuffer = C_EXP("NULL");
+	};
+
+	factory {
+		write("tecsgen.cfg", "CRE_MPF(%s, {%s, %s, %s, %s, %s});",
+								id, attribute, blockCount, blockSize,
+								memoryPool, memoryPoolManagementBuffer);
+	};
+	FACTORY {
+		write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
+	};
+};
+
+/*
+ *  ハンドラ本体のシグニチャ
+ */
+[context("non-task")]
+signature siHandlerBody {
+	void	main(void);
+};
+
+/*
+ *  タイムイベントハンドラを指定するためのセルタイプ
+ */
+celltype tTimeEventHandler {
+	entry		siNotificationHandler	eiNotificationHandler;
+	[omit] call	siHandlerBody			ciHandlerBody;
+
+	FACTORY {
+		write("tecsgen.cfg", "#include \"$ct$_tecsgen.h\"");
+	};
+};
+
+/*
+ *  周期通知を操作するためのシグニチャ（タスクコンテキスト用）
+ */
+signature sCyclic {
+	ER		start(void);
+	ER		stop(void);
+	ER		refer([out]T_RCYC *pk_cyclicHandlerStatus);
+};
+
+/*
+ *  周期通知のセルタイプ
+ */
+[active, generate(NotifierPlugin,
+	"factory=\"CRE_CYC({{id}}, { {{attribute}}, { {{_handler_params_}} }, "
+	"{{cycleTime}}, {{cyclePhase}} });\", output_file=tecsgen.cfg")]
+celltype tCyclicNotifier {
+	[inline] entry	sCyclic		eCyclic;
+
+	call			siNotificationHandler	ciNotificationHandler;
+	[optional] call siNotificationHandler	ciErrorNotificationHandler;
+
+	attr {
+		ID				id = C_EXP("ALMID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] bool_t	ignoreErrors = false;
+		[omit] RELTIM	cycleTime;
+		[omit] RELTIM	cyclePhase = 0;
+
+		/* 変数の設定による通知（TNFY_SETVAR）*/
+		[omit] intptr_t *setVariableAddress = 0;
+		[omit] intptr_t setVariableValue = 0;
+
+		/* 変数のインクリメントによる通知（TNFY_INCVAR）*/
+		[omit] intptr_t *incrementedVariableAddress = 0;
+
+		/* イベントフラグのセットによる通知（TNFY_SETFLG）*/
+		[omit] FLGPTN flagPattern = 0;
+
+		/* データキューへの送信による通知（TNFY_SNDDTQ）*/
+		[omit] intptr_t dataqueueSentValue = 0;
+
+		/* 変数の設定によるエラー通知（TENFY_SETVAR）*/
+		[omit] intptr_t *setVariableAddressForError = 0;
+
+		/* 変数のインクリメントによるエラー通知（TENFY_INCVAR）*/
+		[omit] intptr_t *incrementedVariableAddressForError = 0;
+
+		/* イベントフラグのセットによるエラー通知（TENFY_SETFLG）*/
+		[omit] FLGPTN flagPatternForError = 0;
+	};
+
+	FACTORY {
+		write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
+	};
+};
+
+/*
+ *  周期通知にユーザーハンドラを指定するための複合セルタイプ
+ */
+[active]
+composite tCyclicHandler {
+	entry		sCyclic			eCyclic;
+	[omit] call	siHandlerBody	ciHandlerBody;
+
+	attr {
+		ID				id = C_EXP("ALMID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] RELTIM	cycleTime;
+		[omit] RELTIM	cyclePhase = 0;
+	};
+
+	cell tCyclicNotifier CyclicNotifier {
+		id = composite.id;
+		attribute = composite.attribute;
+		ciNotificationHandler = TimeEventHandler.eiNotificationHandler;
+		cycleTime = composite.cycleTime;
+		cyclePhase = composite.cyclePhase;
+	};
+
+	cell tTimeEventHandler TimeEventHandler {
+		ciHandlerBody => composite.ciHandlerBody;
+	};
+
+	eCyclic => CyclicNotifier.eCyclic;
+};
+
+/*
+ *  アラーム通知を操作するためのシグニチャ（タスクコンテキスト用）
+ */
+signature sAlarm {
+	ER		start([in] RELTIM alarmTime);
+	ER		stop(void);
+	ER		refer([out]T_RALM *pk_alarmStatus);
+};
+
+/*
+ *  アラーム通知を操作するためのシグニチャ（非タスクコンテキスト用）
+ */
+[context("non-task")]
+signature siAlarm {
+	ER		start([in] RELTIM alarmTime);
+	ER		stop(void);
+};
+
+/*
+ *  アラーム通知のセルタイプ
+ */
+[active, generate(NotifierPlugin,
+	"factory=\"CRE_ALM({{id}}, { {{attribute}}, {{{_handler_params_}}} });\", "
+	"output_file=tecsgen.cfg")]
+celltype tAlarmNotifier {
+	[inline] entry	sAlarm		eAlarm;
+	[inline] entry	siAlarm		eiAlarm;
+
+	call			siNotificationHandler	ciNotificationHandler;
+	[optional] call	siNotificationHandler	ciErrorNotificationHandler;
+
+	attr {
+		ID				id = C_EXP("ALMID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] bool_t	ignoreErrors = false;
+
+		/* 変数の設定による通知（TNFY_SETVAR）*/
+		[omit] intptr_t *setVariableAddress = 0;
+		[omit] intptr_t setVariableValue = 0;
+
+		/* 変数のインクリメントによる通知（TNFY_INCVAR）*/
+		[omit] intptr_t *incrementedVariableAddress = 0;
+
+		/* イベントフラグのセットによる通知（TNFY_SETFLG）*/
+		[omit] FLGPTN flagPattern = 0;
+
+		/* データキューへの送信による通知（TNFY_SNDDTQ）*/
+		[omit] intptr_t dataqueueSentValue = 0;
+
+		/* 変数の設定によるエラー通知（TENFY_SETVAR）*/
+		[omit] intptr_t *setVariableAddressForError = 0;
+
+		/* 変数のインクリメントによるエラー通知（TENFY_INCVAR）*/
+		[omit] intptr_t *incrementedVariableAddressForError = 0;
+
+		/* イベントフラグのセットによるエラー通知（TENFY_SETFLG）*/
+		[omit] FLGPTN flagPatternForError = 0;
+	};
+
+	FACTORY {
+		write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
+	};
+};
+
+/*
+ *  アラーム通知にユーザーハンドラを指定するための複合セルタイプ
+ */
+[active]
+composite tAlarmHandler {
+	entry		sAlarm			eAlarm;
+	entry		siAlarm			eiAlarm;
+	[omit] call	siHandlerBody	ciHandlerBody;
+
+	attr {
+		ID			id = C_EXP("ALMID_$id$");
+		[omit] ATR	attribute = C_EXP("TA_NULL");
+	};
+
+	cell tAlarmNotifier AlarmNotifier {
+		id = composite.id;
+		attribute = composite.attribute;
+		ciNotificationHandler = TimeEventHandler.eiNotificationHandler;
+	};
+
+	cell tTimeEventHandler TimeEventHandler {
+		ciHandlerBody => composite.ciHandlerBody;
+	};
+
+	eAlarm => AlarmNotifier.eAlarm;
+	eiAlarm => AlarmNotifier.eiAlarm;
+};
+
+/*
+ *  割込み要求ライン操作のシグニチャ（タスクコンテキスト用）
+ */
+signature sInterruptRequest {
+	ER		disable(void);
+	ER		enable(void);
+	ER		clear(void);
+	ER		raise(void);
+	ER_BOOL	probe(void);
+};
+
+/*
+ *  割込み要求ラインのセルタイプ
+ */
+celltype tInterruptRequest {
+	[inline] entry	sInterruptRequest	eInterruptRequest;
+
+	attr {
+		INTNO			interruptNumber;
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] PRI		interruptPriority;
+	};
+
+	factory {
+		write("tecsgen.cfg", "CFG_INT(%s, { %s, %s });",
+							interruptNumber, attribute, interruptPriority);
+	};
+};
+
+/*
+ *  割込みサービスルーチンのセルタイプ
+ */
+[active]
+celltype tISR {
+	call	siHandlerBody	ciISRBody;
+
+	attr {
+		ID				id = C_EXP("ISRID_$id$");
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+		[omit] INTNO	interruptNumber;
+		[omit] PRI		isrPriority = 1;
+	};
+
+	factory {
+		write("tecsgen.cfg", "CRE_ISR(%s, { %s, $cbp$, %s, tISR_start, %s });",
+								id, attribute, interruptNumber, isrPriority);
+	};
+	FACTORY {
+		write("tecsgen.cfg", "#include \"$ct$_tecsgen.h\"");
+		write("$ct$_factory.h", "#include \"kernel_cfg.h\"");
+	};
+};
+
+/*
+ *  割込みハンドラのセルタイプ
+ */
+[active]
+celltype tInterruptHandler {
+	call	siHandlerBody	ciInterruptHandlerBody;
+
+	attr {
+		INHNO			interruptHandlerNumber;
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+	};
+
+	factory {
+		write("tecsgen.cfg",
+				"DEF_INH(%s, { %s, tInterruptHandler_start });", attribute);
+	};
+	FACTORY {
+		write("tecsgen.cfg", "#include \"$ct$_tecsgen.h\"");
+	};
+};
+
+/*
+ *  CPU例外ハンドラのセルタイプ
+ */
+[active]
+celltype tCpuExceptionHandler {
+	call	siHandlerBody	ciCpuExceptionHandlerBody;
+
+	attr {
+		EXCNO			cpuExceptionHandlerNumber;
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+	};
+
+	factory {
+		write("tecsgen.cfg",
+				"DEF_EXC(%s, { %s, tCpuExceptionHandler_start });", attribute);
+	};
+	FACTORY {
+		write("tecsgen.cfg", "#include \"$ct$_tecsgen.h\"");
+	};
+};
+
+/*
+ *  初期化／終了処理ルーチン本体のシグニチャ
+ */
+signature sRoutineBody {
+	void	main(void);
+};
+
+/*
+ *  初期化ルーチンのセルタイプ
+ */
+[active]
+celltype tInitializeRoutine {
+	call	sRoutineBody	cInitializeRoutineBody;
+
+	attr {
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+	};
+
+	factory {
+		write("tecsgen.cfg",
+				"ATT_INI({ %s, $cbp$, tInitializeRoutine_start });",
+															attribute);
+	};
+	FACTORY {
+		write("tecsgen.cfg", "#include \"$ct$_tecsgen.h\"");
+	};
+};
+
+/*
+ *  終了処理ルーチンのセルタイプ
+ */
+[active]
+celltype tTerminateRoutine {
+	call	sRoutineBody	cTerminateRoutineBody;
+
+	attr {
+		[omit] ATR		attribute = C_EXP("TA_NULL");
+	};
+
+	factory {
+		write("tecsgen.cfg",
+				"ATT_TER({ %s, $cbp$, tTerminateRoutine_start });", attribute);
+	};
+	FACTORY {
+		write("tecsgen.cfg", "#include \"$ct$_tecsgen.h\"");
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tAlarmNotifier.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tAlarmNotifier.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tAlarmNotifier.c	(revision 398)
@@ -0,0 +1,43 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#include "tAlarmNotifier_tecsgen.h"
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tAlarmNotifier_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tAlarmNotifier_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tAlarmNotifier_inline.h	(revision 398)
@@ -0,0 +1,96 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#ifndef TOPPERS_TALARMHANDLER_INLINE_H
+#define TOPPERS_TALARMHANDLER_INLINE_H
+
+/*
+ *  アラーム通知の動作開始
+ */
+Inline ER
+eAlarm_start(CELLIDX idx, RELTIM alarmTime)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(sta_alm(ATTR_id, alarmTime));
+}
+
+/*
+ *  アラーム通知の動作停止
+ */
+Inline ER
+eAlarm_stop(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(stp_alm(ATTR_id));
+}
+
+/*
+ *  アラーム通知の状態参照
+ */
+Inline ER
+eAlarm_refer(CELLIDX idx, T_RALM* pk_alarmStatus)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ref_alm(ATTR_id, pk_alarmStatus));
+}
+
+/*
+ *  アラーム通知の動作開始（非タスクコンテキスト用）
+ */
+Inline ER
+eiAlarm_start(CELLIDX idx, RELTIM alarmTime)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ista_alm(ATTR_id, alarmTime));
+}
+
+/*
+ *  アラーム通知の動作停止（非タスクコンテキスト用）
+ */
+Inline ER
+eiAlarm_stop(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(istp_alm(ATTR_id));
+}
+
+#endif /* TOPPERS_TALARMHANDLER_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tCpuExceptionHandler.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tCpuExceptionHandler.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tCpuExceptionHandler.c	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#include "tCpuExceptionHandler_tecsgen.h"
+
+/*
+ *  割込みハンドラ本体の呼出し
+ */
+void
+tCpuExceptionHandler_start(intptr_t exinf)
+{
+	CELLCB	*p_cellcb = (CELLCB *) exinf;
+
+	ciCpuExceptionHandlerBody_main();
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tCyclicNotifier.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tCyclicNotifier.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tCyclicNotifier.c	(revision 398)
@@ -0,0 +1,43 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#include "tCyclicNotifier_tecsgen.h"
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tCyclicNotifier_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tCyclicNotifier_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tCyclicNotifier_inline.h	(revision 398)
@@ -0,0 +1,76 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#ifndef TOPPERS_TCYCLICHANDLER_INLINE_H
+#define TOPPERS_TCYCLICHANDLER_INLINE_H
+
+/*
+ *  周期通知の動作開始
+ */
+Inline ER
+eCyclic_start(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(sta_cyc(ATTR_id));
+}
+
+/*
+ *  周期通知の動作停止
+ */
+Inline ER
+eCyclic_stop(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(stp_cyc(ATTR_id));
+}
+
+/*
+ *  周期通知の状態参照
+ */
+Inline ER
+eCyclic_refer(CELLIDX idx, T_RCYC* pk_cyclicHandlerStatus)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ref_cyc(ATTR_id, pk_cyclicHandlerStatus));
+}
+
+#endif /* TOPPERS_TCYCLICHANDLER_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tDataqueue_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tDataqueue_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tDataqueue_inline.h	(revision 398)
@@ -0,0 +1,156 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#ifndef TOPPERS_TDATAQUEUE_INLINE_H
+#define TOPPERS_TDATAQUEUE_INLINE_H
+
+/*
+ *  データキューへの送信
+ */
+Inline ER
+eDataqueue_send(CELLIDX idx, intptr_t data)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(snd_dtq(ATTR_id, data));
+}
+
+/*
+ *  データキューへの送信（ポーリング）
+ */
+Inline ER
+eDataqueue_sendPolling(CELLIDX idx, intptr_t data)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(psnd_dtq(ATTR_id, data));
+}
+
+/*
+ *  データキューへの送信（タイムアウトあり）
+ */
+Inline ER
+eDataqueue_sendTimeout(CELLIDX idx, intptr_t data, TMO timeout)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(tsnd_dtq(ATTR_id, data, timeout));
+}
+
+/*
+ *  データキューへの強制送信
+ */
+Inline ER
+eDataqueue_sendForce(CELLIDX idx, intptr_t data)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(fsnd_dtq(ATTR_id, data));
+}
+
+/*
+ *  データキューからの受信
+ */
+Inline ER
+eDataqueue_receive(CELLIDX idx, intptr_t* p_data)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(rcv_dtq(ATTR_id, p_data));
+}
+
+/*
+ *  データキューからの受信（ポーリング）
+ */
+Inline ER
+eDataqueue_receivePolling(CELLIDX idx, intptr_t* p_data)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(prcv_dtq(ATTR_id, p_data));
+}
+
+/*
+ *  データキューからの受信（タイムアウトあり）
+ */
+Inline ER
+eDataqueue_receiveTimeout(CELLIDX idx, intptr_t* p_data, TMO timeout)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(trcv_dtq(ATTR_id, p_data, timeout));
+}
+
+/*
+ *  データキューの再初期化
+ */
+Inline ER
+eDataqueue_initialize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ini_dtq(ATTR_id));
+}
+
+/*
+ *  データキューの状態参照
+ */
+Inline ER
+eDataqueue_refer(CELLIDX idx, T_RDTQ* pk_dataqueueStatus)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ref_dtq(ATTR_id, pk_dataqueueStatus));
+}
+
+/*
+ *  データキューへの送信（ポーリング，非タスクコンテキスト用）
+ */
+Inline ER
+eiDataqueue_sendPolling(CELLIDX idx, intptr_t data)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(psnd_dtq(ATTR_id, data));
+}
+
+/*
+ *  データキューへの強制送信（非タスクコンテキスト用）
+ */
+Inline ER
+eiDataqueue_sendForce(CELLIDX idx, intptr_t data)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(fsnd_dtq(ATTR_id,  data));
+}
+
+#endif /* TOPPERS_TDATAQUEUE_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tEventflag_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tEventflag_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tEventflag_inline.h	(revision 398)
@@ -0,0 +1,130 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#ifndef TOPPERS_TEVENTFLAG_INLINE_H
+#define TOPPERS_TEVENTFLAG_INLINE_H
+
+/*
+ *  イベントフラグのセット
+ */
+Inline ER
+eEventflag_set(CELLIDX idx, FLGPTN setPattern)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(set_flg(ATTR_id, setPattern));
+}
+
+/*
+ *  イベントフラグのクリア
+ */
+Inline ER
+eEventflag_clear(CELLIDX idx, FLGPTN clearPattern)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(clr_flg(ATTR_id, clearPattern));
+}
+
+/*
+ *  イベントフラグ待ち
+ */
+Inline ER
+eEventflag_wait(CELLIDX idx, FLGPTN waitPattern,
+							MODE waitFlagMode, FLGPTN* p_flagPattern)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(wai_flg(ATTR_id, waitPattern, waitFlagMode, p_flagPattern));
+}
+
+/*
+ *  イベントフラグ待ち（ポーリング）
+ */
+Inline ER
+eEventflag_waitPolling(CELLIDX idx, FLGPTN waitPattern,
+							MODE waitFlagMode, FLGPTN* p_flagPattern)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(pol_flg(ATTR_id, waitPattern, waitFlagMode, p_flagPattern));
+}
+
+/*
+ *  イベントフラグ待ち（タイムアウトあり）
+ */
+Inline ER
+eEventflag_waitTimeout(CELLIDX idx, FLGPTN waitPattern,
+				MODE waitFlagMode, FLGPTN* p_flagPattern, TMO timeout)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(twai_flg(ATTR_id, waitPattern, waitFlagMode,
+											p_flagPattern, timeout));
+}
+
+/*
+ *  イベントフラグの再初期化
+ */
+Inline ER
+eEventflag_initialize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ini_flg(ATTR_id));
+}
+
+/*
+ *  イベントフラグの状態参照
+ */
+Inline ER
+eEventflag_refer(CELLIDX idx, T_RFLG* pk_eventflagStatus)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ref_flg(ATTR_id, pk_eventflagStatus));
+}
+
+/*
+ *  イベントフラグのセット（非タスクコンテキスト用）
+ */
+Inline ER
+eiEventflag_set(CELLIDX idx, FLGPTN setPattern)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(set_flg(ATTR_id, setPattern));
+}
+
+#endif /* TOPPERS_TEVENTFLAG_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tFixedSizeMemoryPool_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tFixedSizeMemoryPool_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tFixedSizeMemoryPool_inline.h	(revision 398)
@@ -0,0 +1,106 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#ifndef TOPPERS_TFIXEDSIZEMEMORYPOOL_INLINE_H
+#define TOPPERS_TFIXEDSIZEMEMORYPOOL_INLINE_H
+
+/*
+ *  固定長メモリブロックの獲得
+ */
+Inline ER
+eFixedSizeMemoryPool_get(CELLIDX idx, void **p_block)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(get_mpf( ATTR_id, p_block));
+}
+
+/*
+ *  固定長メモリブロックの獲得（ポーリング）
+ */
+Inline ER
+eFixedSizeMemoryPool_getPolling(CELLIDX idx, void **p_block)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(pget_mpf(ATTR_id, p_block));
+}
+
+/*
+ *  固定長メモリブロックの獲得（タイムアウトあり）
+ */
+Inline ER
+eFixedSizeMemoryPool_getTimeout(CELLIDX idx, void **p_block, TMO timeout)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(tget_mpf(ATTR_id, p_block, timeout));
+}
+
+/*
+ *  固定長メモリブロックの返却
+ */
+Inline ER
+eFixedSizeMemoryPool_release(CELLIDX idx, const void *block)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(rel_mpf(ATTR_id, (void *) block));
+}
+
+/*
+ *  固定長メモリプールの再初期化
+ */
+Inline ER
+eFixedSizeMemoryPool_initialize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ini_mpf(ATTR_id));
+}
+
+/*
+ *  固定長メモリプールの状態参照
+ */
+Inline ER
+eFixedSizeMemoryPool_refer(CELLIDX idx, T_RMPF *pk_fixedSizeMemoryPoolStatus)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ref_mpf(ATTR_id, pk_memoryPoolFixedSizeStatus));
+}
+
+#endif /* TOPPERS_TFIXEDSIZEMEMORYPOOL_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tISR.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tISR.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tISR.c	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#include "tISR_tecsgen.h"
+
+/*
+ *  割込みサービルルーチン本体の呼出し
+ */
+void
+tISR_start(intptr_t exinf)
+{
+	CELLCB	*p_cellcb = (CELLCB *) exinf;
+
+	ciISRBody_main();
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tInitializeRoutine.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tInitializeRoutine.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tInitializeRoutine.c	(revision 398)
@@ -0,0 +1,53 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#include "tInitializeRoutine_tecsgen.h"
+
+/*
+ *  初期化ルーチン本体の呼出し
+ */
+void  tInitializeRoutine_start(intptr_t exinf)
+{
+	CELLCB	*p_cellcb = (CELLCB *) exinf;
+
+	cInitializeRoutineBody_main();
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tInterruptHandler.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tInterruptHandler.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tInterruptHandler.c	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#include "tInterruptHandler_tecsgen.h"
+
+/*
+ *  割込みハンドラ本体の呼出し
+ */
+void
+tInterruptHandler_start(intptr_t exinf)
+{
+	CELLCB	*p_cellcb = (CELLCB *) exinf;
+
+	ciInterruptHandlerBody_main();
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tInterruptRequest_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tInterruptRequest_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tInterruptRequest_inline.h	(revision 398)
@@ -0,0 +1,96 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015-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$  
+ */
+
+#ifndef TOPPERS_TINTERRUPTREQUEST_INLINE_H
+#define TOPPERS_TINTERRUPTREQUEST_INLINE_H
+
+/*
+ *  割込みの禁止
+ */
+Inline ER
+eInterruptRequest_disable(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(dis_int(ATTR_interruptNumber));
+}
+
+/*
+ *  割込みの許可
+ */
+Inline ER
+eInterruptRequest_enable(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ena_int(ATTR_interruptNumber));
+}
+
+/*
+ *  割込み要求のクリア
+ */
+Inline ER
+eInterruptRequest_clear(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(clr_int(ATTR_interruptNumber));
+}
+
+/*
+ *  割込みの要求
+ */
+Inline ER
+eInterruptRequest_raise(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ras_int(ATTR_interruptNumber));
+}
+
+/*
+ *  割込み要求のチェック
+ */
+Inline ER_BOOL
+eInterruptRequest_probe(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(prb_int(ATTR_interruptNumber));
+}
+
+#endif /* TOPPERS_TINTERRUPTREQUEST_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tKernel_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tKernel_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tKernel_inline.h	(revision 398)
@@ -0,0 +1,405 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#ifndef TOPPERS_TKERNEL_INLINE_H
+#define TOPPERS_TKERNEL_INLINE_H
+
+/*
+ *  自タスクの拡張情報の参照
+ */
+Inline ER
+eKernel_getExtendedInformation(intptr_t* p_exinf)
+{
+	return(get_inf(p_exinf));
+}
+
+/*
+ *  起床待ち
+ */
+Inline ER
+eKernel_sleep(void)
+{
+	return(slp_tsk());
+}
+
+/*
+ *  起床待ち（タイムアウトあり）
+ */
+Inline ER
+eKernel_sleepTimeout(TMO timeout)
+{
+	return(tslp_tsk(timeout));
+}
+
+/*
+ *  自タスクの遅延
+ */
+Inline ER
+eKernel_delay(RELTIM delayTime)
+{
+	return(dly_tsk(delayTime));
+}
+
+/*
+ *  自タスクの終了
+ */
+Inline ER
+eKernel_exit(void)
+{
+	return(ext_tsk());
+}
+
+/*
+ *  タスク終了の禁止
+ */
+Inline ER
+eKernel_disableTerminate(void)
+{
+	return(dis_ter());
+}
+
+/*
+ *  タスク終了の許可
+ */
+Inline ER
+eKernel_enableTerminate(void)
+{
+	return(ena_ter());
+}
+
+/*
+ *  タスク終了禁止状態の参照
+ */
+Inline bool_t
+eKernel_senseTerminate(void)
+{
+	return(sns_ter());
+}
+
+/*
+ *  システム時刻の設定
+ */
+Inline ER
+eKernel_setTime(SYSTIM systemTime)
+{
+	return(set_tim(systemTime));
+}
+
+/*
+ *  システム時刻の参照
+ */
+Inline ER
+eKernel_getTime(SYSTIM* p_systemTime)
+{
+	return(get_tim(p_systemTime));
+}
+
+/*
+ *  システム時刻の調整
+ */
+Inline ER
+eKernel_adjustTime(int32_t adjustTime)
+{
+	return(adj_tim(adjustTime));
+}
+
+/*
+ *  高分解能タイマの参照
+ */
+Inline HRTCNT
+eKernel_fetchHighResolutionTimer(void)
+{
+	return(fch_hrt());
+}
+
+/*
+ *  タスクの優先順位の回転
+ */
+Inline ER
+eKernel_rotateReadyQueue(PRI taskPriority)
+{
+	return(rot_rdq(taskPriority));
+}
+
+/*
+ *  実行状態のタスクIDの参照
+ */
+Inline ER
+eKernel_getTaskId(ID *p_taskId)
+{
+	return(get_tid(p_taskId));
+}
+
+/*
+ *  実行できるタスクの数の参照
+ */
+Inline ER
+eKernel_getLoad(PRI taskPriority, uint_t* p_load)
+{
+	return(get_lod(taskPriority, p_load));
+}
+
+/*
+ *  指定した優先順位のタスクIDの参照
+ */
+Inline ER
+eKernel_getNthTask(PRI taskPriority, uint_t nth, ID* p_taskID)
+{
+	return (get_nth(taskPriority, nth, p_taskID));
+}
+/*
+ *  CPUロック状態への遷移
+ */
+Inline ER
+eKernel_lockCpu()
+{
+	return(loc_cpu());
+}
+
+/*
+ *  CPUロック状態の解除
+ */
+Inline ER
+eKernel_unlockCpu()
+{
+	return(unl_cpu());
+}
+
+/*
+ *  ディスパッチの禁止
+ */
+Inline ER
+eKernel_disableDispatch()
+{
+	return(dis_dsp());
+}
+
+/*
+ *  ディスパッチの許可
+ */
+Inline ER
+eKernel_enableDispatch()
+{
+	return(ena_dsp());
+}
+
+/*
+ *  コンテキストの参照
+ */
+Inline bool_t
+eKernel_senseContext()
+{
+	return(sns_ctx());
+}
+
+/*
+ *  CPUロック状態の参照
+ */
+Inline bool_t
+eKernel_senseLock()
+{
+	return(sns_loc());
+}
+
+/*
+ *  ディスパッチ禁止状態の参照
+ */
+Inline bool_t
+eKernel_senseDispatch()
+{
+	return(sns_dsp());
+}
+
+/*
+ *  ディスパッチ保留状態の参照
+ */
+Inline bool_t
+eKernel_senseDispatchPendingState()
+{
+	return(sns_dpn());
+}
+
+/*
+ *  カーネル非動作状態の参照
+ */
+Inline bool_t
+eKernel_senseKernel()
+{
+	return(sns_ker());
+}
+
+/*
+ *  カーネルの終了
+ */
+Inline ER
+eKernel_exitKernel()
+{
+	return(ext_ker());
+}
+
+/*
+ *  割込み優先度マスクの変更
+ */
+Inline ER
+eKernel_changeInterruptPriorityMask(PRI interruptPriority)
+{
+	return(chg_ipm(interruptPriority));
+}
+
+/*
+ *  割込み優先度マスクの参照
+ */
+Inline ER
+eKernel_getInterruptPriorityMask(PRI* p_interruptPriority)
+{
+	return(get_ipm(p_interruptPriority));
+}
+
+/*
+ *  高分解能タイマの参照（非タスクコンテキスト用）
+ */
+Inline HRTCNT
+eiKernel_fetchHighResolutionTimer(void)
+{
+	return(fch_hrt());
+}
+
+/*
+ *  タスクの優先順位の回転（非タスクコンテキスト用）
+ */
+Inline ER
+eiKernel_rotateReadyQueue(PRI taskPriority)
+{
+	return(rot_rdq(taskPriority));
+}
+
+/*
+ *  実行状態のタスクIDの参照（非タスクコンテキスト用）
+ */
+Inline ER
+eiKernel_getTaskId(ID* p_taskId)
+{
+	return(get_tid(p_taskId));
+}
+
+/*
+ *  CPUロック状態への遷移（非タスクコンテキスト用）
+ */
+Inline ER
+eiKernel_lockCpu()
+{
+	return(loc_cpu());
+}
+
+/*
+ *  CPUロック状態の解除（非タスクコンテキスト用）
+ */
+Inline ER
+eiKernel_unlockCpu()
+{
+	return(unl_cpu());
+}
+
+/*
+ *  コンテキストの参照（非タスクコンテキスト用）
+ */
+Inline bool_t
+eiKernel_senseContext()
+{
+	return(sns_ctx());
+}
+
+/*
+ *  CPUロック状態の参照（非タスクコンテキスト用）
+ */
+Inline bool_t
+eiKernel_senseLock()
+{
+	return(sns_loc());
+}
+
+/*
+ *  ディスパッチ禁止状態の参照（非タスクコンテキスト用）
+ */
+Inline bool_t
+eiKernel_senseDispatch()
+{
+	return(sns_dsp());
+}
+
+/*
+ *  ディスパッチ保留状態の参照（非タスクコンテキスト用）
+ */
+Inline bool_t
+eiKernel_senseDispatchPendingState()
+{
+	return(sns_dpn());
+}
+
+/*
+ *  カーネル非動作状態の参照（非タスクコンテキスト用）
+ */
+Inline bool_t
+eiKernel_senseKernel()
+{
+	return(sns_ker());
+}
+
+/*
+ *  カーネルの終了（非タスクコンテキスト用）
+ */
+Inline ER
+eiKernel_exitKernel()
+{
+	return(ext_ker());
+}
+
+/*
+ *  CPU例外発生時のディスパッチ保留状態の参照
+ */
+Inline bool_t
+eiKernel_exceptionSenseDispatchPendingState(const void *p_exceptionInformation)
+{
+	return(xsns_dpn((void *) p_exceptionInformation));
+}
+
+#endif /* TOPPERS_TKERNEL_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tMutex_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tMutex_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tMutex_inline.h	(revision 398)
@@ -0,0 +1,106 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#ifndef TOPPERS_TMUTEX_INLINE_H
+#define TOPPERS_TMUTEX_INLINE_H
+
+/*
+ *  ミューテックスのロック
+ */
+Inline ER
+eMutex_lock(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(loc_mtx(ATTR_id));
+}
+
+/*
+ *  ミューテックスのロック（ポーリング）
+ */
+Inline ER
+eMutex_lockPolling(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ploc_mtx(ATTR_id));
+}
+
+/*
+ *  ミューテックスのロック（タイムアウトあり）
+ */
+Inline ER
+eMutex_lockTimeout(CELLIDX idx, TMO timeout)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ploc_mtx(ATTR_id, timeout));
+}
+
+/*
+ *  ミューテックスのロック解除
+ */
+Inline ER
+eMutex_unlock(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(unl_mtx(ATTR_id));
+}
+
+/*
+ *  ミューテックスの再初期化
+ */
+Inline ER
+eMutex_initialize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ini_mtx(ATTR_id));
+}
+
+/*
+ *  ミューテックスの状態参照
+ */
+Inline ER
+eMutex_refer(CELLIDX idx, T_RMTX *pk_mutexStatus)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ref_mtx(ATTR_id, pk_mutexStatus));
+}
+
+#endif /* TOPPERS_TMUTEX_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tPriorityDataqueue_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tPriorityDataqueue_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tPriorityDataqueue_inline.h	(revision 398)
@@ -0,0 +1,139 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#ifndef TOPPERS_TPRIORITYDATAQUEUE_INLINE_H
+#define TOPPERS_TPRIORITYDATAQUEUE_INLINE_H
+
+/*
+ *  優先度データキューへの送信
+ */
+Inline ER
+ePriorityDataqueue_send(CELLIDX idx, intptr_t data, PRI dataPriority)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(snd_pdq(ATTR_id, data, dataPriority));
+}
+
+/*
+ *  優先度データキューへの送信（ポーリング）
+ */
+Inline ER
+ePriorityDataqueue_sendPolling(CELLIDX idx, intptr_t data, PRI dataPriority)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(psnd_pdq(ATTR_id, data, dataPriority));
+}
+
+/*
+ *  優先度データキューへの送信（タイムアウトあり）
+ */
+Inline ER
+ePriorityDataqueue_sendTimeout(CELLIDX idx, intptr_t data,
+									PRI dataPriority, TMO timeout)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(tsnd_pdq(ATTR_id, data, dataPriority, timeout));
+}
+
+/*
+ *  優先度データキューからの受信
+ */
+Inline ER
+ePriorityDataqueue_receive(CELLIDX idx, intptr_t *p_data, PRI *p_dataPriority)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(rcv_pdq(ATTR_id, p_data, p_dataPriority));
+}
+
+/*
+ *  優先度データキューからの受信（ポーリング）
+ */
+Inline ER
+ePriorityDataqueue_receivePolling(CELLIDX idx, intptr_t *p_data,
+														PRI *p_dataPriority)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(prcv_pdq(ATTR_id, p_data, p_dataPriority));
+}
+
+/*
+ *  優先度データキューからの受信（タイムアウトあり）
+ */
+Inline ER
+ePriorityDataqueue_receiveTimeout(CELLIDX idx, intptr_t *p_data,
+											PRI *p_dataPriority, TMO timeout)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(trcv_pdq(ATTR_id, p_data, p_dataPriority, timeout));
+}
+
+/*
+ *  優先度データキューの再初期化
+ */
+Inline ER
+ePriorityDataqueue_initialize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ini_pdq(ATTR_id));
+}
+
+/*
+ *  優先度データキューの状態参照
+ */
+Inline ER
+ePriorityDataqueue_refer(CELLIDX idx, T_RPDQ* pk_priorityDataqueueStatus)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ref_pdq(ATTR_id, pk_priorityDataqueueStatus));
+}
+
+/*
+ *  優先度データキューへの送信（ポーリング，非タスクコンテキスト用）
+ */
+Inline ER
+eiPriorityDataqueue_sendPolling(CELLIDX idx, intptr_t data, PRI dataPriority)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(psnd_pdq(ATTR_id, data, dataPriority));
+}
+
+#endif /* TOPPERS_TPRIORITYDATAQUEUE_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tSemaphore_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tSemaphore_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tSemaphore_inline.h	(revision 398)
@@ -0,0 +1,116 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#ifndef TOPPERS_TSEMAPHORE_INLINE_H
+#define TOPPERS_TSEMAPHORE_INLINE_H
+
+/*
+ *  セマフォ資源の返却
+ */
+Inline ER
+eSemaphore_signal(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(sig_sem(ATTR_id));
+}
+
+/*
+ *  セマフォ資源の獲得
+ */
+Inline ER
+eSemaphore_wait(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(wai_sem(ATTR_id));
+}
+
+/*
+ *  セマフォ資源の獲得（ポーリング）
+ */
+Inline ER
+eSemaphore_waitPolling(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(pol_sem(ATTR_id));
+}
+
+/*
+ *  セマフォ資源の獲得（タイムアウトあり）
+ */
+Inline ER
+eSemaphore_waitTimeout(CELLIDX idx, TMO timeout)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(twai_sem(ATTR_id, timeout));
+}
+
+/*
+ *  セマフォの再初期化
+ */
+Inline ER
+eSemaphore_initialize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ini_sem(ATTR_id));
+}
+
+/*
+ *  セマフォの状態参照
+ */
+Inline ER
+eSemaphore_refer(CELLIDX idx, T_RSEM *pk_semaphoreStatus)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ref_sem(ATTR_id, pk_semaphoreStatus));
+}
+
+/*
+ *  セマフォ資源の返却（非タスクコンテキスト用）
+ */
+Inline ER
+eiSemaphore_signal(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(sig_sem(ATTR_id));
+}
+
+#endif /* TOPPERS_TSEMAPHORE_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tTask.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tTask.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tTask.c	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#include "tTask_tecsgen.h"
+
+/*
+ *  タスク本体の呼出し
+ */
+void
+tTask_start(intptr_t exinf)
+{
+	CELLCB	*p_cellcb = (CELLCB *) exinf;
+
+	cTaskBody_main();
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tTask_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tTask_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tTask_inline.h	(revision 398)
@@ -0,0 +1,206 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#ifndef TOPPERS_TTASK_INLINE_H
+#define TOPPERS_TTASK_INLINE_H
+
+/*
+ *  タスクの起動
+ */
+Inline ER
+eTask_activate(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(act_tsk(ATTR_id));
+}
+
+/*
+ *  タスク起動要求のキャンセル
+ */
+Inline ER_UINT
+eTask_cancelActivate(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(can_act(ATTR_id));
+}
+
+/*
+ *  タスク状態の参照
+ */
+Inline ER
+eTask_getTaskState(CELLIDX idx, STAT *p_tskstat)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(get_tst(ATTR_id, p_tskstat));
+}
+
+/*
+ *  タスクのベース優先度の変更
+ */
+Inline ER
+eTask_changePriority(CELLIDX idx, PRI priority)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(chg_pri(ATTR_id, priority));
+}
+
+/*
+ *  タスク優先度の参照
+ */
+Inline ER
+eTask_getPriority(CELLIDX idx, PRI *p_priority)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(get_pri(ATTR_id, p_priority));
+}
+
+/*
+ *  タスクの状態参照
+ */
+Inline ER
+eTask_refer(CELLIDX idx, T_RTSK *pk_taskStatus)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ref_tsk(ATTR_id, pk_taskStatus));
+}
+
+/*
+ *  タスクの起床
+ */
+Inline ER
+eTask_wakeup(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(wup_tsk(ATTR_id));
+}
+
+/*
+ *  タスク起床要求のキャンセル
+ */
+Inline ER_UINT
+eTask_cancelWakeup(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(can_wup(ATTR_id));
+}
+
+/*
+ *  待ち状態の強制解除
+ */
+Inline ER
+eTask_releaseWait(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(rel_wai(ATTR_id));
+}
+
+/*
+ *  強制待ち状態への移行
+ */
+Inline ER
+eTask_suspend(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(sus_tsk(ATTR_id));
+}
+
+/*
+ *  強制待ち状態からの再開
+ */
+Inline ER
+eTask_resume(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(rsm_tsk(ATTR_id));
+}
+
+/*
+ *  タスクの終了要求［NGKI3469］
+ */
+Inline ER
+eTask_raiseTerminate(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ras_ter(ATTR_id));
+}
+
+/*
+ *  タスクの強制終了
+ */
+Inline ER
+eTask_terminate(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(ter_tsk(ATTR_id));
+}
+
+/*
+ *  タスクの起動（非タスクコンテキスト用）
+ */
+Inline ER
+eiTask_activate(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(act_tsk(ATTR_id));
+}
+
+/*
+ *  タスクの起床（非タスクコンテキスト用）
+ */
+Inline ER
+eiTask_wakeup(CELLIDX idx)
+{
+	CELLCB	*p_cellcb= GET_CELLCB(idx);
+	return(iwup_tsk(ATTR_id));
+}
+
+/*
+ *  待ち状態の強制解除（非タスクコンテキスト用）
+ */
+Inline ER
+eiTask_releaseWait(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	return(irel_wai(ATTR_id));
+}
+
+#endif /* TOPPERS_TTASK_INLINE_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tTerminateRoutine.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tTerminateRoutine.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tTerminateRoutine.c	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  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$
+ */
+
+#include "tTerminateRoutine_tecsgen.h"
+
+/*
+ *  終了処理ルーチン本体の呼出し
+ */
+
+void  tTerminateRoutine_start(intptr_t exinf)
+{
+	CELLCB	*p_cellcb = (CELLCB *) exinf;
+
+	cTerminateRoutineBody_main();
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tecs_kernel.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tecs_kernel.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecs_kernel/tecs_kernel.h	(revision 398)
@@ -0,0 +1,58 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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>
+
+extern void	tTask_start(intptr_t exinf);
+
+extern void tTimeEventHandler_start(intptr_t exinf);
+
+extern void tISR_start(intptr_t exinf);
+extern void tInterruptHandler_start(void);
+extern void tCpuExceptionHandler_start(void *p_excinf);
+
+extern void tInitializeRoutine_start(intptr_t exinf);
+extern void tTerminateRoutine_start(intptr_t exinf);
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/MANIFEST_for_asp3
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/MANIFEST_for_asp3	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/MANIFEST_for_asp3	(revision 398)
@@ -0,0 +1,106 @@
+MANIFEST_for_asp3
+
+tecsgen
+tecsgen.rb
+tecsmerge
+tecsmerge.rb
+
+tecslib/version.rb
+
+tecslib/core/C_parser.tab.rb
+tecslib/core/C_parser.y.rb
+tecslib/core/bnf.tab.rb
+tecslib/core/bnf.y.rb
+tecslib/core/componentobj.rb
+tecslib/core/ctypes.rb
+tecslib/core/expression.rb
+tecslib/core/gen_xml.rb
+tecslib/core/generate.rb
+tecslib/core/location.rb
+tecslib/core/messages.rb
+tecslib/core/optimize.rb
+tecslib/core/plugin.rb
+tecslib/core/pluginModule.rb
+tecslib/core/syntaxobj.rb
+tecslib/core/tecs_lang.rb
+tecslib/core/tecsgen.rb
+tecslib/core/tecsinfo.rb
+tecslib/core/tool_info.rb
+tecslib/core/types.rb
+tecslib/core/unjoin_plugin.rb
+tecslib/core/value.rb
+
+tecslib/messages/messages_console_en_US.rb
+tecslib/messages/messages_console_ja_JP.rb
+tecslib/messages/messages_file_en_US.rb
+tecslib/messages/messages_file_ja_JP.rb
+
+tecslib/plugin/C2TECSBridgePlugin.rb
+tecslib/plugin/CellPlugin.rb
+tecslib/plugin/CelltypePlugin.rb
+tecslib/plugin/CompositePlugin.rb
+tecslib/plugin/DomainPlugin.rb
+tecslib/plugin/Mruby2CBridgePlugin.rb
+tecslib/plugin/MrubyBridgePlugin.rb
+tecslib/plugin/MultiPlugin.rb
+tecslib/plugin/NotifierPlugin.rb
+tecslib/plugin/RPCPlugin.rb
+tecslib/plugin/SignaturePlugin.rb
+tecslib/plugin/TECS2CBridgePlugin.rb
+tecslib/plugin/ThroughPlugin.rb
+tecslib/plugin/TracePlugin.rb
+tecslib/plugin/lib/GenParamCopy.rb
+tecslib/plugin/lib/GenTransparentMarshaler.rb
+
+tecs/tecs.h
+tecs/tecs.xsd
+
+tecs/mruby/TECSPointer.h
+tecs/mruby/TECSStruct.h
+tecs/mruby/mruby.cdl
+tecs/mruby/mrubyInitializer.cdl
+tecs/mruby/mrubyPointers.cdl
+tecs/mruby/mrubyVMs.cdl
+tecs/mruby/nMruby_tBoolPointer.c
+tecs/mruby/nMruby_tCharPointer.c
+tecs/mruby/nMruby_tDouble64Pointer.c
+tecs/mruby/nMruby_tFloat32Pointer.c
+tecs/mruby/nMruby_tInt16Pointer.c
+tecs/mruby/nMruby_tInt32Pointer.c
+tecs/mruby/nMruby_tInt64Pointer.c
+tecs/mruby/nMruby_tInt8Pointer.c
+tecs/mruby/nMruby_tIntPointer.c
+tecs/mruby/nMruby_tLongPointer.c
+tecs/mruby/nMruby_tMruby.c
+tecs/mruby/nMruby_tSCharPointer.c
+tecs/mruby/nMruby_tShortPointer.c
+tecs/mruby/nMruby_tTECSInitializer.c
+tecs/mruby/nMruby_tUCharPointer.c
+tecs/mruby/nMruby_tUInt16Pointer.c
+tecs/mruby/nMruby_tUInt32Pointer.c
+tecs/mruby/nMruby_tUInt64Pointer.c
+tecs/mruby/nMruby_tUInt8Pointer.c
+tecs/mruby/nMruby_tUIntPointer.c
+tecs/mruby/nMruby_tULongPointer.c
+tecs/mruby/nMruby_tUShortPointer.c
+tecs/mruby/tMruby.cdl
+tecs/mruby/tecs_mruby.h
+
+tecs/posix/posix.cdl
+
+tecs/rpc/PPAllocator.cdl
+tecs/rpc/RPCTask.cdl
+tecs/rpc/TDR.cdl
+tecs/rpc/rpc.cdl
+tecs/rpc/rpc_string.h
+tecs/rpc/sChannel.cdl
+tecs/rpc/sRPCErrorHandler.cdl
+tecs/rpc/tDataqueueAdaptor_inline.h
+tecs/rpc/tDataqueueOWChannel.cdl
+tecs/rpc/tPPAllocator.c
+tecs/rpc/tRPCDedicatedTaskMain.c
+tecs/rpc/tTDR_inline.h
+tecs/rpc/tecs_rpc.h
+tecs/rpc/tMessageBufferCEP.cdl
+tecs/rpc/tMessageBufferCEP_inline.h
+tecs/rpc/tMessageBufferChannel.cdl
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/MANIFEST_tecsgen_body
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/MANIFEST_tecsgen_body	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/MANIFEST_tecsgen_body	(revision 398)
@@ -0,0 +1,207 @@
+MANIFEST_tecsgen_body
+
+Makefile
+tecscde
+tecscde.rb
+tecsgen
+tecsgen.rb
+tecsgen_rcov.rb
+tecsmerge
+tecsmerge.rb
+cdelib/Makefile
+cdelib/cell_plugin_dialog.rb
+cdelib/cell_plugin_dialog_ui_definition.rb
+cdelib/palette.rb
+cdelib/saveload.rb
+cdelib/tcontrol.rb
+cdelib/tmodel.rb
+cdelib/tview.rb
+cdelib/version.rb
+tecs/TECSInfo/TECSInfo.cdl
+tecs/TECSInfo/TECSInfoAccessor.cdl
+tecs/TECSInfo/nTECSInfo_tArrayTypeInfo.c
+tecs/TECSInfo/nTECSInfo_tBoolTypeInfo.c
+tecs/TECSInfo/nTECSInfo_tCallInfo.c
+tecs/TECSInfo/nTECSInfo_tCellInfo.c
+tecs/TECSInfo/nTECSInfo_tCelltypeInfo.c
+tecs/TECSInfo/nTECSInfo_tDefinedTypeInfo.c
+tecs/TECSInfo/nTECSInfo_tDescriptorTypeInfo.c
+tecs/TECSInfo/nTECSInfo_tEntryInfo.c
+tecs/TECSInfo/nTECSInfo_tFloatTypeInfo.c
+tecs/TECSInfo/nTECSInfo_tFunctionInfo.c
+tecs/TECSInfo/nTECSInfo_tIntTypeInfo.c
+tecs/TECSInfo/nTECSInfo_tNamespaceInfo.c
+tecs/TECSInfo/nTECSInfo_tParamInfo.c
+tecs/TECSInfo/nTECSInfo_tPtrTypeInfo.c
+tecs/TECSInfo/nTECSInfo_tRawEntryDescriptorInfo.c
+tecs/TECSInfo/nTECSInfo_tRegionInfo.c
+tecs/TECSInfo/nTECSInfo_tSignatureInfo.c
+tecs/TECSInfo/nTECSInfo_tStructTypeInfo.c
+tecs/TECSInfo/nTECSInfo_tTECSInfoAccessor.c
+tecs/TECSInfo/nTECSInfo_tTECSInfoSub.c
+tecs/TECSInfo/nTECSInfo_tTECSInfo_inline.h
+tecs/TECSInfo/nTECSInfo_tTypeInfo.c
+tecs/TECSInfo/nTECSInfo_tVarDeclInfo.c
+tecs/TECSInfo/nTECSInfo_tVoidTypeInfo.c
+tecs/TECSInfo/tTECSInfoAccessor.c
+tecs/TLSFMalloc/README-TLSF.txt
+tecs/TLSFMalloc/tTLSFMalloc.cdl
+tecs/TLSFMalloc/tTLSFMalloc_inline.h
+tecs/mruby/README-mruby.txt
+tecs/mruby/TECSPointer.h
+tecs/mruby/TECSStruct.h
+tecs/mruby/mruby.cdl
+tecs/mruby/mrubyBridge.txt
+tecs/mruby/mrubyInitializer.cdl
+tecs/mruby/mrubyPointers.cdl
+tecs/mruby/mrubyTECSPointer.txt
+tecs/mruby/mrubyTECSStruct.txt
+tecs/mruby/mrubyVMs.cdl
+tecs/mruby/nMruby_tBoolPointer.c
+tecs/mruby/nMruby_tCharPointer.c
+tecs/mruby/nMruby_tDouble64Pointer.c
+tecs/mruby/nMruby_tFloat32Pointer.c
+tecs/mruby/nMruby_tInt16Pointer.c
+tecs/mruby/nMruby_tInt32Pointer.c
+tecs/mruby/nMruby_tInt64Pointer.c
+tecs/mruby/nMruby_tInt8Pointer.c
+tecs/mruby/nMruby_tIntPointer.c
+tecs/mruby/nMruby_tLongPointer.c
+tecs/mruby/nMruby_tMruby.c
+tecs/mruby/nMruby_tMrubyCyclicTaskBody.c
+tecs/mruby/nMruby_tMrubyProc.c
+tecs/mruby/nMruby_tMrubyTaskBody.c
+tecs/mruby/nMruby_tMrubyVM.c
+tecs/mruby/nMruby_tSCharPointer.c
+tecs/mruby/nMruby_tShortPointer.c
+tecs/mruby/nMruby_tTECSInitializer.c
+tecs/mruby/nMruby_tUCharPointer.c
+tecs/mruby/nMruby_tUInt16Pointer.c
+tecs/mruby/nMruby_tUInt32Pointer.c
+tecs/mruby/nMruby_tUInt64Pointer.c
+tecs/mruby/nMruby_tUInt8Pointer.c
+tecs/mruby/nMruby_tUIntPointer.c
+tecs/mruby/nMruby_tULongPointer.c
+tecs/mruby/nMruby_tUShortPointer.c
+tecs/mruby/sMruby.cdl
+tecs/mruby/tMruby.cdl
+tecs/mruby/tecs_mruby.h
+tecs/posix/posix.cdl
+tecs/rpc/PPAllocator.cdl
+tecs/rpc/RPCTask.cdl
+tecs/rpc/TDR.cdl
+tecs/rpc/rpc.cdl
+tecs/rpc/rpc_string.h
+tecs/rpc/sChannel.cdl
+tecs/rpc/sRPCErrorHandler.cdl
+tecs/rpc/tDataqueueAdaptor_inline.h
+tecs/rpc/tDataqueueOWChannel.cdl
+tecs/rpc/tMessageBufferCEP.cdl
+tecs/rpc/tMessageBufferCEP_inline.h
+tecs/rpc/tMessageBufferChannel.cdl
+tecs/rpc/tNBOTDR_inline.h
+tecs/rpc/tPPAllocator.c
+tecs/rpc/tRPCDedicatedTaskMain.c
+tecs/rpc/tRPCDedicatedTaskMainWithOpener.c
+tecs/rpc/tRPCSharedChannelMan.c
+tecs/rpc/tRPCSharedTaskMain.c
+tecs/rpc/tRPCSharedTaskMainWithOpener.c
+tecs/rpc/tSocketChannel.cdl
+tecs/rpc/tSocketClient.c
+tecs/rpc/tSocketServer.c
+tecs/rpc/tTDR_inline.h
+tecs/rpc/tTINETChannel.cdl
+tecs/rpc/tTINETClient.c
+tecs/rpc/tTINETServer.c
+tecs/rpc/tecs_rpc.h
+tecs/sMalloc.cdl
+tecs/tecs.h
+tecs/tecs.xsd
+tecslib/core/C_parser.tab.rb
+tecslib/core/C_parser.y.rb
+tecslib/core/bnf.tab.rb
+tecslib/core/bnf.y.rb
+tecslib/core/componentobj.rb
+tecslib/core/ctypes.rb
+tecslib/core/expression.rb
+tecslib/core/gen_xml.rb
+tecslib/core/generate.rb
+tecslib/core/location.rb
+tecslib/core/messages.rb
+tecslib/core/optimize.rb
+tecslib/core/plugin.rb
+tecslib/core/pluginModule.rb
+tecslib/core/syntaxobj.rb
+tecslib/core/tecs_lang.rb
+tecslib/core/tecsgen.rb
+tecslib/core/tecsinfo.rb
+tecslib/core/tool_info.rb
+tecslib/core/types.rb
+tecslib/core/unjoin_plugin.rb
+tecslib/core/value.rb
+tecslib/messages/messages_console_en_US.rb
+tecslib/messages/messages_console_ja_JP.rb
+tecslib/messages/messages_file_en_US.rb
+tecslib/messages/messages_file_ja_JP.rb
+tecslib/plugin/ATK1AlarmPlugin.rb
+tecslib/plugin/ATK1DelayTaskPlugin.rb
+tecslib/plugin/ATK1EventPlugin.rb
+tecslib/plugin/ATK1ISRPlugin.rb
+tecslib/plugin/ATK1KernelPlugin.rb
+tecslib/plugin/ATK1ResourcePlugin.rb
+tecslib/plugin/ATK1TaskPlugin.rb
+tecslib/plugin/C2TECSBridgePlugin.rb
+tecslib/plugin/CellPlugin.rb
+tecslib/plugin/CelltypePlugin.rb
+tecslib/plugin/CompositePlugin.rb
+tecslib/plugin/DomainPlugin.rb
+tecslib/plugin/HRP2AlarmHandlerPlugin.rb
+tecslib/plugin/HRP2Cache.rb
+tecslib/plugin/HRP2CyclicHandlerPlugin.rb
+tecslib/plugin/HRP2DataqueuePlugin.rb
+tecslib/plugin/HRP2EventflagPlugin.rb
+tecslib/plugin/HRP2FixedSizeMemoryPoolPlugin.rb
+tecslib/plugin/HRP2HandlerPlugin.rb
+tecslib/plugin/HRP2KernelObjectPlugin.rb
+tecslib/plugin/HRP2ObjectPlugin.rb
+tecslib/plugin/HRP2Plugin.rb
+tecslib/plugin/HRP2PostHook.rb
+tecslib/plugin/HRP2PriorityDataqueuePlugin.rb
+tecslib/plugin/HRP2RPCPlugin.rb
+tecslib/plugin/HRP2SVCPlugin.rb
+tecslib/plugin/HRP2SemaphorePlugin.rb
+tecslib/plugin/HRP2TaskPlugin.rb
+tecslib/plugin/HRPHandlerPlugin.rb
+tecslib/plugin/HRPKernelObjectManager.rb
+tecslib/plugin/HRPKernelObjectPlugin.rb
+tecslib/plugin/HRPObjectPlugin.rb
+tecslib/plugin/HRPPlugin.rb
+tecslib/plugin/HRPRPCPlugin.rb
+tecslib/plugin/HRPSVCPlugin.rb
+tecslib/plugin/HRPTaskPlugin.rb
+tecslib/plugin/Mruby2CBridgePlugin.rb
+tecslib/plugin/MrubyBridgeCellPlugin.rb
+tecslib/plugin/MrubyBridgeCelltypePlugin.rb
+tecslib/plugin/MrubyBridgeCompositePlugin.rb
+tecslib/plugin/MrubyBridgePlugin.rb
+tecslib/plugin/MrubyBridgeSignaturePlugin.rb
+tecslib/plugin/MultiPlugin.rb
+tecslib/plugin/NotifierPlugin.rb
+tecslib/plugin/OpaqueMarshalerPlugin.rb
+tecslib/plugin/OpaqueRPCPlugin.rb
+tecslib/plugin/RPCPlugin.rb
+tecslib/plugin/RepeatCellPlugin.rb
+tecslib/plugin/RepeatJoinPlugin.rb
+tecslib/plugin/SharedOpaqueRPCPlugin.rb
+tecslib/plugin/SharedRPCPlugin.rb
+tecslib/plugin/SignaturePlugin.rb
+tecslib/plugin/TECS2CBridgePlugin.rb
+tecslib/plugin/TECSInfoPlugin.rb
+tecslib/plugin/ThroughPlugin.rb
+tecslib/plugin/TracePlugin.rb
+tecslib/plugin/lib/GenHRP2Marshaler.rb
+tecslib/plugin/lib/GenOpaqueMarshaler.rb
+tecslib/plugin/lib/GenParamCopy.rb
+tecslib/plugin/lib/GenTransparentMarshaler.rb
+tecslib/plugin/lib/MrubyBridgeCelltypePluginModule.rb
+tecslib/version.rb
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/Makefile
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/Makefile	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/Makefile	(revision 398)
@@ -0,0 +1,138 @@
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2013 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+LIB_PATH= tecslib/core
+PLUGIN_PATH= tecslib/plugin
+GEN_SRC =   tecsgen.rb\
+  $(LIB_PATH)/bnf.tab.rb\
+  $(LIB_PATH)/bnf.y.rb\
+  $(LIB_PATH)/componentobj.rb\
+  $(LIB_PATH)/ctypes.rb\
+  $(LIB_PATH)/C_parser.tab.rb\
+  $(LIB_PATH)/C_parser.y.rb\
+  $(LIB_PATH)/expression.rb\
+  $(LIB_PATH)/generate.rb\
+  $(LIB_PATH)/messages.rb\
+  $(LIB_PATH)/optimize.rb\
+  $(LIB_PATH)/pluginModule.rb\
+  $(LIB_PATH)/syntaxobj.rb\
+  $(LIB_PATH)/types.rb\
+  $(LIB_PATH)/value.rb\
+  tecslib/version.rb
+
+PLUGIN_SRC = \
+  $(PLUGIN_PATH)/CellPlugin.rb\
+  $(PLUGIN_PATH)/CelltypePlugin.rb\
+  $(PLUGIN_PATH)/lib/GenTransparentMarshaler.rb\
+  $(PLUGIN_PATH)/lib/GenOpaqueMarshaler.rb\
+  $(PLUGIN_PATH)/lib/GenParamCopy.rb\
+  $(PLUGIN_PATH)/OpaqueRPCPlugin.rb\
+  $(PLUGIN_PATH)/RPCPlugin.rb\
+  $(PLUGIN_PATH)/SharedRPCPlugin.rb\
+  $(PLUGIN_PATH)/SignaturePlugin.rb\
+  $(PLUGIN_PATH)/ThroughPlugin.rb\
+  $(PLUGIN_PATH)/TracePlugin.rb
+
+
+BNF = $(LIB_PATH)/bnf.y.rb
+GEN_TAB =  $(LIB_PATH)/bnf.tab.rb
+GEN_TAB_DEB =  $(LIB_PATH)/bnf-deb.tab.rb
+C_PARSER = $(LIB_PATH)/C_parser.y.rb
+C_TAB = $(LIB_PATH)/C_parser.tab.rb
+EXERB_EXE = tecsgen.exe
+
+all: generator
+
+debug : yydebug
+
+generator : $(GEN_TAB) $(GEN_SRC) $(PLUGIN_SRC) $(C_TAB)
+
+clean : clean2
+	rm -f $(GEN_TAB) $(GEN_TAB_DEB) $(C_TAB)
+
+clean2 :
+	rm -f $(LIB_PATH)/bnf.output $(LIB_PATH)/C_parser.output
+	rm -rf rdoc
+
+real_clean : clean
+	rm -f $(EXERB_EXE)
+
+$(GEN_TAB) : $(BNF)
+	racc -O -v $(BNF)
+
+$(C_TAB) : $(C_PARSER)
+	racc -O -v $(C_PARSER)
+
+yydebug : $(GEN_TAB_DEB)
+
+$(GEN_TAB_DEB) : $(BNF) $(GEN_SRC) $(PLUGIN_SRC)
+	racc -v -g -o $(GEN_TAB_DEB) $(BNF)	# yydebug を有効にする
+
+print_error :	# エラーメッセージを拾い出す
+	grep -e "Generator\.error" -e cdl_error $(LIB_PATH)/*.rb \
+		| grep -v bnf.tab.rb \
+		| sed -e "s/\s*Generator\.error(//" -e "s/\s*cdl_error[0-9]*(//" -e "s/).*$$//"
+
+print_error2 :	# エラーメッセージを拾い出す
+	grep '[^A-Z][A-VXYZ][0-9][0-9][0-9][0-9]' $(LIB_PATH)/*.rb \
+		| grep -v bnf.tab.rb \
+		| grep -v '^Makefile' \
+		| sed -e "s/.*\([A-Z][0-9][0-9][0-9][0-9].*\)/\1/" \
+		| sed -e 's/\(.*\)".*/\1/'
+
+print_warning : # ウォーニングメッセージを拾い出す
+	grep -e 'Generator\.warning' -e cdl_warning $(LIB_PATH)/*.rb \
+		| grep -v bnf.tab.rb \
+		| sed -e "s/\s*Generator\.warning(/  /" -e "s/).*$$//"
+
+print_expr_token :
+	# Expression に含まれるトークンを拾い出す
+	# OP_... より後ろは式とは関係ないトークン
+	grep ':[A-Z]' bnf.y.rb | sed -e 's/.*\(:[A-Z]\w*\).*/\1/'
+
+print_mikan : # 設計未完部分を拾い出す
+	grep mikan $(LIB_PATH)/*.rb 
+
+print_def :
+	grep -e '^ *def' -e '^ *class' $(LIB_PATH)/*.rb | grep -v bnf.tab.rb
+
+print_class :
+	grep '^ *class' $(LIB_PATH)/*.rb | grep -v bnf.tab.rb
+
+rdoc :
+	rdoc --charset euc --op rdoc $(GEN_SRC) $(PLUGIN_SRC)
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/in_exerb.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/in_exerb.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/in_exerb.rb	(revision 398)
@@ -0,0 +1,114 @@
+# coding: utf-8
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2015 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# exerb 版で最初に読みこまれるファイル
+# このファイルから generate.rb が読みこまれる
+
+$IN_EXERB=true
+
+# この変数は exerb 版のみ
+$path = ENV[ 'PATH' ]
+
+#=== cygwin のパスを Windows パスに変換
+# cygpath コマンドを探して、見つかれば変換する
+# 変換できなかった、または変換後のパスが見つからない場合、default を返す
+def cygpath( path, default = nil )
+  if ! $IN_EXERB then
+    return default
+  end
+  if File.exist? path then
+    return default
+  end
+
+  found = false
+  $path.split( ";" ).each{ |path2|
+    cygpath_path = "#{path2}\\cygpath.exe"
+    if File.exist?( cygpath_path )  then
+      path3 = nil
+      dbgPrint "in_exerb: cygpath: found\n"
+      IO.popen( "cygpath -m #{path}", "r"){ |io|
+        path3 = io.gets.chomp!
+      }
+      dbgPrint "in_exerb: cygpath: '#{path}' => '#{path3}'\n"
+      # File.stat( path3.to_s )
+
+      if File.exist?( path3 )
+        dbgPrint "in_exerb: cygpath: '#{path3}' found\n"
+        return path3
+      else
+        break
+      end
+    end
+  }
+  dbgPrint "cygpath '#{path}' not found\n"
+  return default
+end
+
+# gcc のパスを設定する
+#  cygwin のあるバージョンでは gcc は gcc-3.exe または gcc-4.exe へのシンボリックリンクとなっている
+#  exerb 版ではシンボリックリンクを辿れないため gcc の exe を探す
+#  cygwin のリンクは、システム属性が付けられ、コマンドプロンプト上では dir /A:S を指定しないと表示されない
+#  (cygwin のバージョンで実装が異なるかもしれない)
+#  ファイルの先頭2バイトを読出し PE フォーマットのマジックに一致するか調べる
+$gcc = "gcc"
+$path.split( ";" ).each{ |path|
+  found = false
+  [ "gcc.exe", "gcc-3.exe", "gcc-4.exe" ].each{ |gcc|
+    gcc_path = "#{path}\\#{gcc}"
+    if File.exist?( gcc_path )  then
+      begin
+        magic = File.read( gcc_path, 2 )
+        if magic == "MZ"                  # マジックをチェック
+          $gcc = gcc
+          found = true
+          break
+        end
+      rescue
+        # magic の読出しに失敗。無視
+      end
+    end
+  }
+  break if found
+}
+
+# cpp コマンドを設定する
+$cpp = "#{$gcc} -E -D TECSGEN"
+
+# exerb 版 TECS ジェネレータの実行を開始
+require "tecsgen.rb"
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/TECSInfo.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/TECSInfo.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/TECSInfo.cdl	(revision 398)
@@ -0,0 +1,618 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+import_C( "t_stddef.h" );
+
+/* Constants of Kinds */
+const int8_t TECSTypeKind_BoolType    = 1;
+const int8_t TECSTypeKind_IntType     = 2;
+const int8_t TECSTypeKind_FloatType   = 3;
+const int8_t TECSTypeKind_PtrType     = 4;
+const int8_t TECSTypeKind_ArrayType   = 5;
+const int8_t TECSTypeKind_DefinedType = 6;
+const int8_t TECSTypeKind_StructType  = 7;
+const int8_t TECSTypeKind_EnumType    = 8;
+const int8_t TECSTypeKind_VoidType    = 9;
+const int8_t TECSTypeKind_DescriptorType = 10;
+
+/* Parameter Direction */
+const int8_t PARAM_DIR_IN         = 1;
+const int8_t PARAM_DIR_OUT        = 2;
+const int8_t PARAM_DIR_INOUT      = 3;
+const int8_t PARAM_DIR_SEND       = 4;
+const int8_t PARAM_DIR_RECEIVE    = 5;
+
+/* VarDecl declType */
+const int8_t DECLTYPE_STMEMBER    = 1;  /* Struct Member */
+const int8_t DECLTYPE_ATTR        = 2;
+const int8_t DECLTYPE_VAR         = 3;
+
+/* VarDecl place info */
+const int8_t VARDECL_PLACE_STRUCT = 1;
+const int8_t VARDECL_PLACE_NON    = 2;
+const int8_t VARDECL_PLACE_CB     = 3;
+const int8_t VARDECL_PLACE_INIB   = 4;
+
+/* CallInfo place info */
+const int8_t CALL_PLACE_NON       = 1;
+const int8_t CALL_PLACE_INIB_DES  = 2;
+const int8_t CALL_PLACE_CB_DES    = 3;
+const int8_t CALL_PLACE_INIB_IDX  = 4;
+const int8_t CALL_PLACE_CB_IDX    = 5;
+
+namespace nTECSInfo {
+
+    /*******   SIGNATURES   *******/
+
+    /* Type Information of attr, var, param, return */
+    signature sTypeInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1] = NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        uint32_t   getSize(void);    // size of the value in bytes
+        int8_t     getKind(void);    // see Constants of Kinds
+        uint32_t   getNType(void);
+           // kind == ARRAY の場合サイズ、POINTER, TYPEDEF の場合1、それ以外は0
+        ER     getTypeInfo( [out]Descriptor(sTypeInfo) *desc );
+           // kind == POINTER, TYPEDEF の場合、desc に有効な値を返す
+        uint32_t   getNMember(void);
+           // STRUCT の場合メンバー数
+        ER     getMemberInfo( [in]uint32_t ith, [out]Descriptor(sVarDeclInfo) *desc );
+           // kind == STRUCT の場合、desc に有効な値を返す
+           // ith はメンバーの添数 0<=ith<*num
+           // ith が範囲外の場合 E_NORES を返す
+//        void   getSignatureInfo( [out]Descriptor(sSignatureInfo) *desc );
+//           // kind == DESCRIPTOR の場合、desc に有効な値を返す
+    };
+
+    /* ATTR, VAR, struct member Information */
+    signature sVarDeclInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1] = NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        void       getLocationInfo(  [out]uint32_t *offset,
+                                     [out]int8_t   *place );            // VARDECL_PLACE_*
+        void       getTypeInfo( [out]Descriptor( sTypeInfo ) *desc );
+        void       getSizeIsExpr( [out,string(max_len)]char_t *expr_str, [in]int32_t max_len );
+          // size_is 計算式を文字列で返す. size_is 未指定の場合 *expr_str = NULL が返される
+        ER         getSizeIs( [out]uint32_t *size, [in]const void *p_cb);
+          // p_cb を与えると、size を返す (size_is 指定がない場合，E_NOSPT を返す)
+    };
+
+    /* PARAM Information */
+    signature sParamInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1] = NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        ER         getTypeInfo( [out]Descriptor(sTypeInfo) *desc);
+        ER         getDir( [out]int8_t *dir );
+    };
+
+    /* FUNCTION Information */
+    signature sFunctionInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1] = NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        void       getReturnTypeInfo( [out]Descriptor( sTypeInfo ) *desc );
+        uint32_t   getNParam(void);
+        ER         getParamInfo( [in]uint32_t ith, [out]Descriptor(sParamInfo) *param );
+           // 0 <= ith < *num
+           // ith が範囲外の場合 E_NORES を返す
+    };
+
+    /* SIGNATURE Information */
+    signature sSignatureInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1] = NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        uint32_t   getNFunction(void);
+        ER         getFunctionInfo( [in]uint32_t ith, [out]Descriptor( sFunctionInfo ) *desc );
+           // 0 <= ith < *num
+           // ith が範囲外の場合 E_NORES を返す
+    };
+
+    /* CALL Information */
+    signature sCallInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1]= NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        void       getSignatureInfo( [out]Descriptor( sSignatureInfo ) *desc );
+        uint32_t   getArraySize(void);
+        void       getSpecifierInfo( [out]bool_t   *b_optional,
+                                     [out]bool_t   *b_dynamic,
+                                     [out]bool_t   *b_ref_desc,
+                                     [out]bool_t   *b_omit );
+        void       getInternalInfo(  [out]bool_t   *b_allocator_port,
+                                     [out]bool_t   *b_require_port );
+        void       getLocationInfo(  [out]uint32_t *offset,             // CALL_PLACE_*
+                                     [out]int8_t   *place );            // CALL_PLACE_*
+        void       getOptimizeInfo(  [out]bool_t   *b_VMT_useless,      // VMT (関数テーブル) 不要最適化 (関数直接呼出し)
+                                     [out]bool_t   *b_skelton_useless,  // スケルトン関数不要 (
+                                     [out]bool_t   *b_cell_unique );    // 単一のセル
+    };
+
+    /* ENTRY Information */
+    signature sEntryInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1]=NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        void       getSignatureInfo( [out]Descriptor( sSignatureInfo ) *desc );
+        uint32_t   getArraySize(void);
+        bool_t     isInline(void);
+    };
+
+    /* CELLTYPE Information */
+    signature sCelltypeInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1]=NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        uint32_t   getNAttr(void);
+        ER         getAttrInfo( [in]uint32_t ith, [out]Descriptor(sVarDeclInfo)*desc );
+        uint32_t   getNVar(void);
+        ER         getVarInfo( [in]uint32_t ith,  [out]Descriptor(sVarDeclInfo)*desc );
+           // ith が範囲外の場合 E_NORES を返す
+        uint32_t   getNCall(void);
+        ER         getCallInfo( [in]uint32_t ith, [out]Descriptor(sCallInfo)*desc );
+           // ith が範囲外の場合 E_NORES を返す
+        uint32_t   getNEntry(void);
+        ER         getEntryInfo( [in]uint32_t ith, [out]Descriptor(sEntryInfo)*desc );
+           // ith が範囲外の場合 E_NORES を返す
+        bool_t     isSingleton(void);
+        bool_t     isIDX_is_ID(void);
+        uint32_t   sizeOfCB(void);
+        uint32_t   sizeOfINIB(void);
+    };
+
+    /* CELL Information */
+    [deviate]
+    signature sCellInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1]=NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        uint32_t   getNRawEntryDescriptorInfo( void );
+        ER         getRawEntryDescriptorInfo( [in]int_t index, [out]Descriptor(sRawEntryDescriptorInfo) *desc );
+           // index は、受け口を指定 (CelltypeInfo の cEntryInfo の序数に一致する)
+        void       getCelltypeInfo( [out]Descriptor( sCelltypeInfo ) *desc );
+        void       getCBP( [out]void **cbp );      // out: 逸脱
+        void       getINIBP( [out]void **inibp );  // out: 逸脱
+    };
+
+    [deviate]
+    signature sRawEntryDescriptorInfo {
+        uint16_t   getNRawEntryDescriptorInfo( void );         // 受け口配列の場合、要素数を返す。非配列の場合 1。
+        ER         getRawDescriptor( [in]int_t ith, [out]void **rawDesc );
+                        // ith が配列範囲外の場合、E_NOEXS を返す
+    };
+
+    /* NAMESPACE Information */
+    signature sNamespaceInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1]=NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        uint32_t   getNNamespace(void);
+        ER         getNamespaceInfo( [in]uint32_t ith, [out]Descriptor(sNamespaceInfo) *des );
+           // ith が範囲外の場合 E_NORES を返す
+        uint32_t   getNSignature(void);
+        ER         getSignatureInfo( [in]uint32_t ith, [out]Descriptor(sSignatureInfo) *des );
+           // ith が範囲外の場合 E_NORES を返す
+        uint32_t   getNCelltype(void);
+        ER     getCelltypeInfo( [in]uint32_t ith,  [out]Descriptor(sCelltypeInfo) *des );
+           // ith が範囲外の場合 E_NORES を返す
+    };
+
+    /* REGION Information */
+    signature sRegionInfo {
+        ER         getName( [out,string(max_len)]char_t *name, [in]int_t max_len );
+           // 長さが max_len を超えた場合は E_NOMEM を返す.
+           // (max_len-1) 文字コピーする。name[max_len-1]=NULL
+        uint16_t   getNameLength(void);
+           //  終端文字 (NULL) を含む長さ (strlen と仕様が異なることに注意)
+        uint32_t   getNCell(void);
+        ER         getCellInfo( [in]uint32_t ith,    [out]Descriptor(sCellInfo) *des );
+           // ith が範囲外の場合 E_NORES を返す
+        uint32_t   getNRegion(void);
+        ER         getRegionInfo( [in]uint32_t ith,  [out]Descriptor(sRegionInfo) *des );
+           // ith が範囲外の場合 E_NORES を返す
+    };
+
+    /* TECS Information */
+    signature sTECSInfo {
+        ER     findNamespace([in,string]const char_t *namespace_path, [out]Descriptor( sNamespaceInfo )*nsDesc);
+        ER     findRegion(   [in,string]const char_t *namespace_path, [out]Descriptor( sRegionInfo )*regionDesc);
+        ER     findSignature([in,string]const char_t *namespace_path, [out]Descriptor( sSignatureInfo )*signatureDesc);
+        ER     findCelltype( [in,string]const char_t *namespace_path, [out]Descriptor( sCelltypeInfo )*celltypeDesc);
+        ER     findCell(     [in,string]const char_t *namespace_path, [out]Descriptor( sCellInfo )*cellDesc);
+        ER     findRawEntryDescriptor(
+                             [in,string]const char_t *namespace_path,
+                             [in]             int_t  ith,
+                             [out]Descriptor( sRawEntryDescriptorInfo )*rawEntryDescDesc,
+                             [out]Descriptor( sEntryInfo )*entryDesc);
+        ER     findRawEntryDescriptor_unsafe(           // このメソッドは、非配列の場合のみしようできる
+                             [in,string]const char_t *namespace_path,
+                             [out]void **rawDesc );
+    };
+
+    /*******   CELLTYPES   *******/
+
+    /*
+     * tTECSInfo セルタイプのセルは、ユーザーが設置する．
+     *
+     * このセルから、tTECSInfoSub への結合は、プラグインにより自動的に
+     * 行われるため、ユーザーは、このセルを設置するだけでよい．
+     * (プロトタイプを用いていないのは、このセルを任意のリージョンに置
+     * くことを想定してのもの)
+     */
+    [singleton,
+     generate( TECSInfoPlugin, "" )]
+    celltype tTECSInfo {
+        [inline]
+            entry sTECSInfo eTECSInfo;
+        call  sTECSInfo cTECSInfo;
+        FACTORY{
+            write( "global_tecsgen.h", "#define setRawEntryDescriptor( callDesc, callPortSignature, rawEntryDesc )   (callDesc).vdes = (struct tag_ ## callPortSignature ## _VDES *) rawEntryDesc" );
+        };
+    };
+
+    /*
+     * tTECSInfoSub セルタイプのセルは、プラグインにより自動生成される．
+     * プラグインは、生成を行う前にエラーが発生している場合、セルを生成しない．
+     * (TECSInfoSub セルが未定義のエラーも出ることになる。不完全な状態
+     * で生成しようとすると、Ruby 例外を発生する可能性があるため、生成
+     * しない)
+     */
+    [singleton]
+    celltype tTECSInfoSub {
+        entry sTECSInfo eTECSInfo;
+        [ref_desc]
+            call sNamespaceInfo cNamespaceInfo;   // root namespace
+        [ref_desc]
+            call sRegionInfo    cRegionInfo;      // root region
+        // 内部処理用の呼び口 (何度も使いまわすので、使う直前に(再)設定すること）
+        [dynamic,optional]
+            call sNamespaceInfo cNamespaceInfoTemp;
+        [dynamic,optional]
+            call sRegionInfo    cRegionInfoTemp;
+        [dynamic,optional]
+            call sSignatureInfo cSignatureInfoTemp;
+        [dynamic,optional]
+            call sCelltypeInfo  cCelltypeInfoTemp;
+        [dynamic,optional]
+            call sCellInfo      cCellInfoTemp;
+        [dynamic,optional]
+            call sEntryInfo     cEntryInfoTemp;
+        [dynamic,optional]
+            call sRawEntryDescriptorInfo cRawEntryDescriptorInfoTemp;
+
+        attr {
+            int32_t name_len = 256;
+            int32_t path_len = 1024;
+        };
+        var {
+            [size_is(name_len)]
+                char_t  *name1;
+            [size_is(name_len)]
+                char_t  *name2;
+            [size_is(path_len)]
+                char_t  *path;
+        };
+    };
+
+    celltype tNamespaceInfo {
+        attr {
+            char *name;
+        };
+
+        entry sNamespaceInfo eNamespaceInfo;
+        [ref_desc,optional]
+            call  sSignatureInfo cSignatureInfo[];
+        [ref_desc,optional]
+            call  sCelltypeInfo  cCelltypeInfo[];
+        [ref_desc,optional]
+            call  sNamespaceInfo cNamespaceInfo[];
+    };
+
+    /* SIGNATURE information */
+    celltype tSignatureInfo{
+        attr {
+            char *name;
+        };
+
+        entry sSignatureInfo   eSignatureInfo;
+        [ref_desc,optional]
+            call sFunctionInfo cFunctionInfo[];
+    };
+    celltype tFunctionInfo {
+        attr {
+            char_t *name;
+            bool_t  bOneway;
+        };
+        entry sFunctionInfo eFunctionInfo;
+        [ref_desc,optional]
+            call sParamInfo cParamInfo[];
+        [ref_desc]
+            call sTypeInfo  cReturnTypeInfo;
+    };
+    celltype tParamInfo {
+        attr {
+            char_t *name;
+            int8_t dir;
+            char_t *sizeIsExpr;
+            char_t *countIsExpr;
+            char_t *stringExpr;
+        };
+        entry sParamInfo eParamInfo;
+        [ref_desc]
+            call sTypeInfo cTypeInfo;
+    };
+
+    /* CELLTYPE information */
+    celltype tCelltypeInfo{
+        attr {
+            char_t   *name;
+            bool_t   b_singleton;
+            bool_t   b_IDX_is_ID_act;
+            uint32_t sizeOfCB;         // size in bytes, 0 if not exist
+            uint32_t sizeOfINIB;       // size in bytes, 0 if not exist
+            uint32_t n_cellInLinkUnit; // CellInLinkUnit == 0 の時 セルタイプコードは、リンクされていない
+            uint32_t n_cellInSystem;   // すべてのリンクユニットを含めたセルの個数．
+                                       // この数が 0になるものは、CelltypeInfo は省略される．
+        };
+        [ref_desc,optional]
+            call  sEntryInfo   cEntryInfo[];
+        [ref_desc,optional]
+            call  sCallInfo    cCallInfo[];
+        [ref_desc,optional]
+            call  sVarDeclInfo cAttrInfo[];
+        [ref_desc,optional]
+            call  sVarDeclInfo cVarInfo[];
+
+        entry sCelltypeInfo    eCelltypeInfo;
+    };
+    celltype tCallInfo {
+        attr {
+            char_t   *name;
+            uint32_t offset;
+            uint32_t array_size;
+            bool_t   b_optional;
+            bool_t   b_omit;
+            bool_t   b_dynamic;
+            bool_t   b_ref_desc;
+            bool_t   b_allocator_port;
+            bool_t   b_require_port;
+            int8_t   place;
+            bool_t   b_VMT_useless;        // VMT (関数テーブル) 不要最適化 (関数直接呼出し)
+            bool_t   b_skelton_useless;    // スケルトン関数不要 (
+            bool_t   b_cell_unique;        // 単一のセル
+        };
+        entry sCallInfo eCallInfo;
+        [ref_desc]
+            call sSignatureInfo cSignatureInfo;
+        FACTORY {
+            write( "$ct_global$_factory.h", "#include \"include_all_signature_header.h\"" );
+        };
+    };
+    celltype tEntryInfo {
+        attr {
+            char_t *name;
+            bool_t b_inline;
+            uint32_t array_size;
+        };
+        entry sEntryInfo eEntryInfo;
+        [ref_desc]
+            call sSignatureInfo cSignatureInfo;
+        FACTORY {
+            write( "$ct_global$_factory.h", "#include \"include_all_signature_header.h\"" );
+        };
+    };
+    /* Variable Declarator (attr, var, struct member) */
+    celltype tVarDeclInfo {
+        attr {
+            char_t   *name;
+            char_t   *sizeIsExpr;
+            int8_t   declType;        /* valid when attr, var */
+            int8_t   place;
+            uint32_t offset;
+        };
+        entry sVarDeclInfo eVarDeclInfo;
+        [ref_desc]
+            call sTypeInfo cTypeInfo;
+    };
+
+    /* REGION & CELL information */
+    celltype tRegionInfo {
+        attr {
+            char *name;
+        };
+
+        entry sRegionInfo eRegionInfo;
+        [ref_desc,optional]
+            call  sCellInfo   cCellInfo[];
+        [ref_desc,optional]
+            call  sRegionInfo cRegionInfo[];
+    };
+    celltype tCellInfo {
+        attr {
+            char_t *name;
+            void   *cbp;
+            void   *inibp;
+        };
+        [ref_desc]
+            call  sCelltypeInfo cCelltypeInfo;
+        [ref_desc,optional]
+            call  sRawEntryDescriptorInfo cRawEntryDescriptor[];
+        entry sCellInfo eCellInfo;
+    };
+    celltype tRawEntryDescriptorInfo {
+        attr {
+            int_t size;   // 非配列の場合 0
+            [size_is(size)]
+                void  **rawEntryDescriptor;
+        };
+        entry sRawEntryDescriptorInfo eRawEntryDescriptor;
+        // [ref_desc]
+        //    call  sEntryInfo             cEntryInfo;
+    };
+
+    /* celltypes of TYPEs */
+    celltype tVoidTypeInfo {
+        attr {
+            char_t   *name;
+            int8_t   typeKind;
+            uint32_t size;     /* bytes */
+            bool_t   b_const;
+            bool_t   b_volatile;
+        };
+        entry sTypeInfo eTypeInfo;
+    };
+    celltype tBoolTypeInfo {
+        attr {
+            char_t   *name;
+            int8_t   typeKind;
+            uint32_t size;     /* bytes */
+            bool_t   b_const;
+            bool_t   b_volatile;
+        };
+        entry sTypeInfo eTypeInfo;
+    };
+    celltype tIntTypeInfo {
+        attr {
+            char_t   *name;
+            int8_t   typeKind;
+            uint32_t size;     /* bytes */
+            bool_t   b_const;
+            bool_t   b_volatile;
+        };
+        entry sTypeInfo eTypeInfo;
+    };
+    celltype tFloatTypeInfo {
+        attr {
+            char_t   *name;
+            int8_t   typeKind;
+            uint32_t size;     /* bytes */
+            bool_t   b_const;
+            bool_t   b_volatile;
+        };
+        entry sTypeInfo eTypeInfo;
+    };
+    celltype tStructTypeInfo {
+        attr {
+            char_t   *name;
+            int8_t   typeKind;
+            uint32_t size;     /* bytes */
+            bool_t   b_const;
+            bool_t   b_volatile;
+        };
+        entry sTypeInfo eTypeInfo;
+        [ref_desc]
+            call sVarDeclInfo cVarDeclInfo[];
+    };
+    celltype tPtrTypeInfo {
+        attr {
+            char_t   *name;
+            int8_t   typeKind;
+            uint32_t size;     /* bytes */
+            bool_t   b_const;
+            bool_t   b_volatile;
+        };
+        entry sTypeInfo eTypeInfo;
+        [ref_desc]
+            call sTypeInfo cTypeInfo;
+        FACTORY {
+            write( "$ct_global$_factory.h", "#include \"include_all_signature_header.h\"" );
+        };
+    };
+    celltype tArrayTypeInfo {
+        attr {
+            char_t   *name;
+            int8_t   typeKind;
+            uint32_t size;     /* bytes */
+            bool_t   b_const;
+            bool_t   b_volatile;
+        };
+        entry sTypeInfo eTypeInfo;
+        [ref_desc]
+            call sTypeInfo cTypeInfo;
+        FACTORY {
+            write( "$ct_global$_factory.h", "#include \"include_all_signature_header.h\"" );
+        };
+    };
+    celltype tDefinedTypeInfo {
+        attr {
+            char_t   *name;
+            int8_t   typeKind;
+            uint32_t size;     /* bytes */
+            bool_t   b_const;
+            bool_t   b_volatile;
+        };
+        entry sTypeInfo eTypeInfo;
+        [ref_desc]
+            call sTypeInfo cTypeInfo;
+    };
+    celltype tDescriptorTypeInfo {
+        attr {
+            char_t   *name;
+            int8_t   typeKind;
+            uint32_t size;     /* bytes */
+            bool_t   b_const;
+            bool_t   b_volatile;
+        };
+        entry sTypeInfo eTypeInfo;
+        [ref_desc]
+            call sSignatureInfo cSignatureInfo;
+        FACTORY {
+            write( "$ct_global$_factory.h", "#include \"include_all_signature_header.h\"" );
+        };
+    };
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/TECSInfoAccessor.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/TECSInfoAccessor.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/TECSInfoAccessor.cdl	(revision 398)
@@ -0,0 +1,164 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+// mruby からアクセスできるようなシグニチャにした、アクセス用セルタイプの定義
+// つまり、シグニチャから Descriptor 型をなくし、名前を指定して動的結合させるセルタイプを用意する
+
+import( <TECSInfo.cdl> );
+
+//namespace nTECSInfo {
+    signature sAccessor{
+        ER   selectNamespaceInfoByName( [in,string]const char_t *namespacePath );
+        ER   selectCelltypeInfoByName(  [in,string]const char_t *namespacePath );
+        ER   selectSignatureInfoByName( [in,string]const char_t *namespacePath );
+        ER   selectRegionInfoByName(    [in,string]const char_t *regionPath );
+        ER   selectCellInfoByName(      [in,string]const char_t *cellPath );
+
+        // namespace
+        ER   getSelectedNamespaceInfo( [out,string(max_len)]char_t *name, [in]int_t max_len, [out]int_t *num_namespace, [out]int_t *num_celltype, [out]int_t *num_signature );
+        ER   selectCelltypeInfo( [in]int_t ith );
+        ER   selectSignatureInfo( [in]int_t ith );
+
+        // celltype
+        ER   getSelectedCelltypeInfo( [out,string(max_len)]char_t *name, [in]int_t max_len,
+                                      [out]int_t *num_attr, [out]int_t *num_var, [out]int_t *num_call, [out]int_t *num_entry );
+        ER   selectCallInfo( [in]int_t ith );
+        ER   selectEntryInfo( [in]int_t ith );
+        ER   selectAttrInfo( [in]int_t ith );
+        ER   selectVarInfo( [in]int_t ith );
+
+        // attr
+        ER   getSelectedAttrInfo( [out,string(max_len)]char_t *name, [in]int_t max_len );
+        ER   getSizeIsExprOfAttr( [out,string(max_len)]char_t *expr_str, [in]int32_t max_len );
+        ER   selectTypeInfoOfAttr(void);
+
+        // var
+        ER   getSelectedVarInfo( [out,string(max_len)]char_t *name, [in]int_t max_len );
+        ER   getSizeIsExprOfVar( [out,string(max_len)]char_t *expr_str, [in]int32_t max_len );
+        ER   selectTypeInfoOfVar(void);
+
+        // call
+        ER   getSelectedCallInfo( [out,string(max_len)]char_t *name, [in]int_t max_len, [out]int_t *array_size );
+        ER   selectSignatureOfCall(void);
+        ER   getSelectedCallSpecifierInfo( [out]bool_t   *b_optional,  [out]bool_t   *b_dynamic,
+                                           [out]bool_t   *b_ref_desc,  [out]bool_t   *b_omit );
+        ER   getSelectedCallInternalInfo(  [out]bool_t   *b_allocator_port, [out]bool_t   *b_require_port );
+        ER   getSelectedCallLocationInfo(  [out]uint32_t *offset,             // offset in CALL_PLACE_*
+                                           [out]int8_t   *place );            // CALL_PLACE_*
+        ER   getSelectedCallOptimizeInfo(  [out]bool_t   *b_VMT_useless,      // VMT (関数テーブル) 不要最適化 (関数直接呼出し)
+                                           [out]bool_t   *b_skelton_useless,  // スケルトン関数不要 (
+                                           [out]bool_t   *b_cell_unique );    // 単一のセル
+
+        // entry
+        ER   getSelectedEntryInfo( [out,string(max_len)]char_t *name, [in]int_t max_len, [out]int_t *array_size );
+        ER   selectSignatureOfEntry(void);
+        ER   getSelectedEntryInlineInfo([out]bool_t *b_inline);
+
+        // signature
+        ER   getSelectedSignatureInfo( [out,string(max_len)]char_t *name, [in]int_t max_len, [out]int_t *num_function );
+        ER   selectFunctionInfoByIndex( [in]int_t ith );
+
+        // function
+        ER   getSelectedFunctionInfo( [out,string(max_len)]char_t *name, [in]int_t max_len, [out]int_t *num_args );
+        ER   selectTypeInfoOfReturn(void);
+
+        // parameter of function
+        ER   getSelectedParamInfo( [out,string(max_len)]char_t *name, [in]int_t max_len, [out]int8_t *dir );
+        ER   selectParamInfo( [in]int_t ith );
+        ER   selectTypeInfoOfParam(void);
+
+        // type of function return and parameter, celltype attr and var
+        ER   getSelectedTypeInfo( [out,string(max_len)]char_t *name, [in]int_t max_len, [out]int8_t *kind );
+        ER   selectTypeInfoOfType(void);
+
+        // region
+        ER   getSelectedRegionInfo( [out,string(max_len)]char_t *name, [in]int_t max_len, [out]int_t *num_cell );
+        ER   selectCellInfo( [in]int_t ith );
+
+        // cell
+        ER   getSelectedCellInfo( [out,string(max_len)]char_t *name, [in]int_t max_len);
+        ER   selectCelltypeInfoOfCell(void); // 選択中セルのセルタイプを選択 (セルタイプの関数を使用できる)
+        ER   getAttrValueInStr([out,string(max_len)]char_t *buf, [in]int_t max_len);  // 事前に、セル、セルタイプ、属性を選択しておくこと．cTypeInfo が変更される
+        ER   getAttrSizeIsValue(void);       // 事前に、セル、セルタイプ、属性を選択しておくこと．cTypeInfo が変更される
+        ER   getVarValueInStr([out,string(max_len)]char_t *buf, [in]int_t max_len);   // 事前に、セル、セルタイプ、変数を選択しておくこと．cTypeInfo が変更される
+        ER   getVarSizeIsValue(void);        // 事前に、セル、セルタイプ、変数を選択しておくこと．cTypeInfo が変更される
+    };
+
+    celltype tTECSInfoAccessor {
+
+        entry sAccessor eSelector;
+
+        call  nTECSInfo::sTECSInfo cTECSInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sNamespaceInfo cNSInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sCelltypeInfo  cCelltypeInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sSignatureInfo cSignatureInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sFunctionInfo  cFunctionInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sParamInfo     cParamInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sCallInfo      cCallInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sEntryInfo     cEntryInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sVarDeclInfo   cAttrInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sVarDeclInfo   cVarInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sTypeInfo      cTypeInfo;
+
+        [dynamic,optional]
+            call  nTECSInfo::sRegionInfo    cRegionInfo;
+        [dynamic,optional]
+            call  nTECSInfo::sCellInfo      cCellInfo;
+
+        attr{
+            int16_t NAME_LEN = 256;
+        };
+        var{
+            [size_is(NAME_LEN)]
+                char_t  *name;
+            [size_is(NAME_LEN)]
+                char_t  *name2;
+            int8_t      *selectedCbp;
+            int8_t      *selectedInibp;
+        };
+    };
+//};
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tArrayTypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tArrayTypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tArrayTypeInfo.c	(revision 398)
@@ -0,0 +1,253 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * typeKind         int8_t           ATTR_typeKind   
+ * size             uint32_t         ATTR_size       
+ * b_const          bool_t           ATTR_b_const    
+ * b_volatile       bool_t           ATTR_b_volatile 
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cTypeInfo signature: nTECSInfo_sTypeInfo context:task
+ *   ER             cTypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cTypeInfo_getNameLength( );
+ *   uint32_t       cTypeInfo_getSize( );
+ *   int8_t         cTypeInfo_getKind( );
+ *   uint32_t       cTypeInfo_getNType( );
+ *   ER             cTypeInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   uint32_t       cTypeInfo_getNMember( );
+ *   ER             cTypeInfo_getMemberInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_ref_desc()      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tArrayTypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTypeInfo
+ * entry port: eTypeInfo
+ * signature:  nTECSInfo_sTypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getName
+ * name:         eTypeInfo_getName
+ * global_name:  nTECSInfo_tArrayTypeInfo_eTypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNameLength
+ * name:         eTypeInfo_getNameLength
+ * global_name:  nTECSInfo_tArrayTypeInfo_eTypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eTypeInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getSize
+ * name:         eTypeInfo_getSize
+ * global_name:  nTECSInfo_tArrayTypeInfo_eTypeInfo_getSize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getSize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return ATTR_size;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getKind
+ * name:         eTypeInfo_getKind
+ * global_name:  nTECSInfo_tArrayTypeInfo_eTypeInfo_getKind
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+int8_t
+eTypeInfo_getKind(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return TECSTypeKind_ArrayType;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNType
+ * name:         eTypeInfo_getNType
+ * global_name:  nTECSInfo_tArrayTypeInfo_eTypeInfo_getNType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNType(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return ATTR_size / cTypeInfo_getSize();  /* 配列要素数 = サイズ / 要素サイズ */
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getTypeInfo
+ * name:         eTypeInfo_getTypeInfo
+ * global_name:  nTECSInfo_tArrayTypeInfo_eTypeInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+  ER      ercd = E_OK;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  *desc = cTypeInfo_refer_to_descriptor();
+  return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNMember
+ * name:         eTypeInfo_getNMember
+ * global_name:  nTECSInfo_tArrayTypeInfo_eTypeInfo_getNMember
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNMember(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getMemberInfo
+ * name:         eTypeInfo_getMemberInfo
+ * global_name:  nTECSInfo_tArrayTypeInfo_eTypeInfo_getMemberInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getMemberInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tBoolTypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tBoolTypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tBoolTypeInfo.c	(revision 398)
@@ -0,0 +1,237 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * typeKind         int8_t           ATTR_typeKind   
+ * size             uint32_t         ATTR_size       
+ * b_const          bool_t           ATTR_b_const    
+ * b_volatile       bool_t           ATTR_b_volatile 
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tBoolTypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTypeInfo
+ * entry port: eTypeInfo
+ * signature:  nTECSInfo_sTypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getName
+ * name:         eTypeInfo_getName
+ * global_name:  nTECSInfo_tBoolTypeInfo_eTypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNameLength
+ * name:         eTypeInfo_getNameLength
+ * global_name:  nTECSInfo_tBoolTypeInfo_eTypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eTypeInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getSize
+ * name:         eTypeInfo_getSize
+ * global_name:  nTECSInfo_tBoolTypeInfo_eTypeInfo_getSize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getSize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return ATTR_size;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getKind
+ * name:         eTypeInfo_getKind
+ * global_name:  nTECSInfo_tBoolTypeInfo_eTypeInfo_getKind
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+int8_t
+eTypeInfo_getKind(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return TECSTypeKind_ArrayType;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNType
+ * name:         eTypeInfo_getNType
+ * global_name:  nTECSInfo_tBoolTypeInfo_eTypeInfo_getNType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNType(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return 0;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getTypeInfo
+ * name:         eTypeInfo_getTypeInfo
+ * global_name:  nTECSInfo_tBoolTypeInfo_eTypeInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return E_NOEXS;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNMember
+ * name:         eTypeInfo_getNMember
+ * global_name:  nTECSInfo_tBoolTypeInfo_eTypeInfo_getNMember
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNMember(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getMemberInfo
+ * name:         eTypeInfo_getMemberInfo
+ * global_name:  nTECSInfo_tBoolTypeInfo_eTypeInfo_getMemberInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getMemberInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tCallInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tCallInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tCallInfo.c	(revision 398)
@@ -0,0 +1,260 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * offset           uint32_t         ATTR_offset     
+ * array_size       uint32_t         ATTR_array_size 
+ * b_optional       bool_t           ATTR_b_optional 
+ * b_omit           bool_t           ATTR_b_omit     
+ * b_dynamic        bool_t           ATTR_b_dynamic  
+ * b_ref_desc       bool_t           ATTR_b_ref_desc 
+ * b_allocator_port bool_t           ATTR_b_allocator_port
+ * b_require_port   bool_t           ATTR_b_require_port
+ * place            int8_t           ATTR_place      
+ * b_VMT_useless    bool_t           ATTR_b_VMT_useless
+ * b_skelton_useless bool_t           ATTR_b_skelton_useless
+ * b_cell_unique    bool_t           ATTR_b_cell_unique
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cSignatureInfo signature: nTECSInfo_sSignatureInfo context:task
+ *   ER             cSignatureInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cSignatureInfo_getNameLength( );
+ *   uint32_t       cSignatureInfo_getNFunction( );
+ *   ER             cSignatureInfo_getFunctionInfo( uint32_t ith, Descriptor( nTECSInfo_sFunctionInfo )* desc );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sSignatureInfo ) cSignatureInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sSignatureInfo ) cSignatureInfo_ref_desc()      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tCallInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eCallInfo
+ * entry port: eCallInfo
+ * signature:  nTECSInfo_sCallInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eCallInfo_getName
+ * name:         eCallInfo_getName
+ * global_name:  nTECSInfo_tCallInfo_eCallInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eCallInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eCallInfo_getNameLength
+ * name:         eCallInfo_getNameLength
+ * global_name:  nTECSInfo_tCallInfo_eCallInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eCallInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eCallInfo_getSignatureInfo
+ * name:         eCallInfo_getSignatureInfo
+ * global_name:  nTECSInfo_tCallInfo_eCallInfo_getSignatureInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eCallInfo_getSignatureInfo(CELLIDX idx, Descriptor( nTECSInfo_sSignatureInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *desc = cSignatureInfo_refer_to_descriptor();
+}
+
+/* #[<ENTRY_FUNC>]# eCallInfo_getArraySize
+ * name:         eCallInfo_getArraySize
+ * global_name:  nTECSInfo_tCallInfo_eCallInfo_getArraySize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eCallInfo_getArraySize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return ATTR_array_size;
+}
+
+/* #[<ENTRY_FUNC>]# eCallInfo_getSpecifierInfo
+ * name:         eCallInfo_getSpecifierInfo
+ * global_name:  nTECSInfo_tCallInfo_eCallInfo_getSpecifierInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eCallInfo_getSpecifierInfo(CELLIDX idx, bool_t* b_optional, bool_t* b_dynamic, bool_t* b_ref_desc, bool_t* b_omit)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  *b_optional = ATTR_b_optional;
+  *b_dynamic  = ATTR_b_dynamic;
+  *b_ref_desc = ATTR_b_ref_desc;
+  *b_omit     = ATTR_b_omit;
+}
+
+/* #[<ENTRY_FUNC>]# eCallInfo_getInternalInfo
+ * name:         eCallInfo_getInternalInfo
+ * global_name:  nTECSInfo_tCallInfo_eCallInfo_getInternalInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eCallInfo_getInternalInfo(CELLIDX idx, bool_t* b_allocator_port, bool_t* b_require_port)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  *b_allocator_port = ATTR_b_allocator_port;
+  *b_require_port   = ATTR_b_require_port;
+}
+
+/* #[<ENTRY_FUNC>]# eCallInfo_getLocationInfo
+ * name:         eCallInfo_getLocationInfo
+ * global_name:  nTECSInfo_tCallInfo_eCallInfo_getLocationInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eCallInfo_getLocationInfo(CELLIDX idx, uint32_t* offset, int8_t* place)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  *offset = ATTR_offset;
+  *place  = ATTR_place;
+}
+
+/* #[<ENTRY_FUNC>]# eCallInfo_getOptimizeInfo
+ * name:         eCallInfo_getOptimizeInfo
+ * global_name:  nTECSInfo_tCallInfo_eCallInfo_getOptimizeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eCallInfo_getOptimizeInfo(CELLIDX idx, bool_t* b_VMT_useless, bool_t* b_skelton_useless, bool_t* b_cell_unique)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  *b_VMT_useless     = ATTR_b_VMT_useless;
+  *b_skelton_useless = ATTR_b_skelton_useless;
+  *b_cell_unique     = ATTR_b_cell_unique;
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tCellInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tCellInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tCellInfo.c	(revision 398)
@@ -0,0 +1,251 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * cbp              void*            ATTR_cbp        
+ * inibp            void*            ATTR_inibp      
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cCelltypeInfo signature: nTECSInfo_sCelltypeInfo context:task
+ *   ER             cCelltypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cCelltypeInfo_getNameLength( );
+ *   uint32_t       cCelltypeInfo_getNAttr( );
+ *   ER             cCelltypeInfo_getAttrInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNVar( );
+ *   ER             cCelltypeInfo_getVarInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNCall( );
+ *   ER             cCelltypeInfo_getCallInfo( uint32_t ith, Descriptor( nTECSInfo_sCallInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNEntry( );
+ *   ER             cCelltypeInfo_getEntryInfo( uint32_t ith, Descriptor( nTECSInfo_sEntryInfo )* desc );
+ *   bool_t         cCelltypeInfo_isSingleton( );
+ *   bool_t         cCelltypeInfo_isIDX_is_ID( );
+ *   uint32_t       cCelltypeInfo_sizeOfCB( );
+ *   uint32_t       cCelltypeInfo_sizeOfINIB( );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sCelltypeInfo ) cCelltypeInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sCelltypeInfo ) cCelltypeInfo_ref_desc()      (same as above; abbreviated version);
+ * call port: cRawEntryDescriptor signature: nTECSInfo_sRawEntryDescriptorInfo context:task optional:true
+ *   bool_t     is_cRawEntryDescriptor_joined(int subscript)        check if joined
+ *   uint16_t       cRawEntryDescriptor_getNRawEntryDescriptorInfo( subscript );
+ *   ER             cRawEntryDescriptor_getRawDescriptor( subscript, const char_t* signatureName, int_t ith, void** rawDesc );
+ *       subscript:  0...(NCP_cRawEntryDescriptor-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sRawEntryDescriptorInfo ) cRawEntryDescriptor_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sRawEntryDescriptorInfo ) cRawEntryDescriptor_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tCellInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eCellInfo
+ * entry port: eCellInfo
+ * signature:  nTECSInfo_sCellInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eCellInfo_getName
+ * name:         eCellInfo_getName
+ * global_name:  nTECSInfo_tCellInfo_eCellInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eCellInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eCellInfo_getNameLength
+ * name:         eCellInfo_getNameLength
+ * global_name:  nTECSInfo_tCellInfo_eCellInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eCellInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eCellInfo_getNRawEntryDescriptorInfo
+ * name:         eCellInfo_getNRawEntryDescriptorInfo
+ * global_name:  nTECSInfo_tCellInfo_eCellInfo_getNRawEntryDescriptorInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eCellInfo_getNRawEntryDescriptorInfo(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return NCP_cRawEntryDescriptor;
+}
+
+/* #[<ENTRY_FUNC>]# eCellInfo_getRawEntryDescriptorInfo
+ * name:         eCellInfo_getRawEntryDescriptorInfo
+ * global_name:  nTECSInfo_tCellInfo_eCellInfo_getRawEntryDescriptorInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eCellInfo_getRawEntryDescriptorInfo(CELLIDX idx, int_t index, Descriptor( nTECSInfo_sRawEntryDescriptorInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+  ER      ercd = E_OK;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( 0 <= index && index < NCP_cRawEntryDescriptor ){
+      if( is_cRawEntryDescriptor_joined( index ) )
+          *desc = cRawEntryDescriptor_refer_to_descriptor( index );
+      else
+          ercd = E_NOEXS;
+  }
+  else
+      ercd = E_ID;
+
+  return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eCellInfo_getCelltypeInfo
+ * name:         eCellInfo_getCelltypeInfo
+ * global_name:  nTECSInfo_tCellInfo_eCellInfo_getCelltypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eCellInfo_getCelltypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sCelltypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *desc = cCelltypeInfo_refer_to_descriptor();
+}
+
+/* #[<ENTRY_FUNC>]# eCellInfo_getCBP
+ * name:         eCellInfo_getCBP
+ * global_name:  nTECSInfo_tCellInfo_eCellInfo_getCBP
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eCellInfo_getCBP(CELLIDX idx, void** cbp)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *cbp = ATTR_cbp;
+}
+
+/* #[<ENTRY_FUNC>]# eCellInfo_getINIBP
+ * name:         eCellInfo_getINIBP
+ * global_name:  nTECSInfo_tCellInfo_eCellInfo_getINIBP
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eCellInfo_getINIBP(CELLIDX idx, void** inibp)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *inibp = ATTR_inibp;
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tCelltypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tCelltypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tCelltypeInfo.c	(revision 398)
@@ -0,0 +1,446 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * b_singleton      bool_t           ATTR_b_singleton
+ * b_IDX_is_ID_act  bool_t           ATTR_b_IDX_is_ID_act
+ * sizeOfCB         uint32_t         ATTR_sizeOfCB   
+ * sizeOfINIB       uint32_t         ATTR_sizeOfINIB 
+ * n_cellInLinkUnit uint32_t         ATTR_n_cellInLinkUnit
+ * n_cellInSystem   uint32_t         ATTR_n_cellInSystem
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cEntryInfo signature: nTECSInfo_sEntryInfo context:task optional:true
+ *   bool_t     is_cEntryInfo_joined(int subscript)        check if joined
+ *   ER             cEntryInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cEntryInfo_getNameLength( subscript );
+ *   void           cEntryInfo_getSignatureInfo( subscript, Descriptor( nTECSInfo_sSignatureInfo )* desc );
+ *   uint32_t       cEntryInfo_getArraySize( subscript );
+ *   bool_t         cEntryInfo_isInline( subscript );
+ *       subscript:  0...(NCP_cEntryInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sEntryInfo ) cEntryInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sEntryInfo ) cEntryInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ * call port: cCallInfo signature: nTECSInfo_sCallInfo context:task optional:true
+ *   bool_t     is_cCallInfo_joined(int subscript)        check if joined
+ *   ER             cCallInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cCallInfo_getNameLength( subscript );
+ *   void           cCallInfo_getSignatureInfo( subscript, Descriptor( nTECSInfo_sSignatureInfo )* desc );
+ *   uint32_t       cCallInfo_getArraySize( subscript );
+ *   void           cCallInfo_getSpecifierInfo( subscript, bool_t* b_optional, bool_t* b_dynamic, bool_t* b_ref_desc, bool_t* b_omit );
+ *   void           cCallInfo_getInternalInfo( subscript, bool_t* b_allocator_port, bool_t* b_require_port );
+ *   void           cCallInfo_getLocationInfo( subscript, uint32_t* offset, int8_t* place );
+ *   void           cCallInfo_getOptimizeInfo( subscript, bool_t* b_VMT_useless, bool_t* b_skelton_useless, bool_t* b_cell_unique );
+ *       subscript:  0...(NCP_cCallInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sCallInfo ) cCallInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sCallInfo ) cCallInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ * call port: cAttrInfo signature: nTECSInfo_sVarDeclInfo context:task optional:true
+ *   bool_t     is_cAttrInfo_joined(int subscript)        check if joined
+ *   ER             cAttrInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cAttrInfo_getNameLength( subscript );
+ *   uint32_t       cAttrInfo_getOffset( subscript );
+ *   void           cAttrInfo_getTypeInfo( subscript, Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   void           cAttrInfo_getSizeIsExpr( subscript, char_t* expr_str, int32_t max_len );
+ *   ER             cAttrInfo_getSizeIs( subscript, uint32_t* size, const void* p_cb );
+ *       subscript:  0...(NCP_cAttrInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sVarDeclInfo ) cAttrInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sVarDeclInfo ) cAttrInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ * call port: cVarInfo signature: nTECSInfo_sVarDeclInfo context:task optional:true
+ *   bool_t     is_cVarInfo_joined(int subscript)        check if joined
+ *   ER             cVarInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cVarInfo_getNameLength( subscript );
+ *   uint32_t       cVarInfo_getOffset( subscript );
+ *   void           cVarInfo_getTypeInfo( subscript, Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   void           cVarInfo_getSizeIsExpr( subscript, char_t* expr_str, int32_t max_len );
+ *   ER             cVarInfo_getSizeIs( subscript, uint32_t* size, const void* p_cb );
+ *       subscript:  0...(NCP_cVarInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sVarDeclInfo ) cVarInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sVarDeclInfo ) cVarInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tCelltypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eCelltypeInfo
+ * entry port: eCelltypeInfo
+ * signature:  nTECSInfo_sCelltypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_getName
+ * name:         eCelltypeInfo_getName
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eCelltypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+    ER		ercd = E_OK;
+    CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        return(E_ID);
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    name[ max_len - 1 ] = '\0';
+    strncpy( name, ATTR_name, max_len );
+    if( name[ max_len - 1 ] ){
+        name[ max_len - 1 ] = '\0';
+        ercd = E_NOMEM;
+    }
+
+    return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_getNameLength
+ * name:         eCelltypeInfo_getNameLength
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eCelltypeInfo_getNameLength(CELLIDX idx)
+{
+    CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_getNAttr
+ * name:         eCelltypeInfo_getNAttr
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_getNAttr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eCelltypeInfo_getNAttr(CELLIDX idx)
+{
+    CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    return NCP_cAttrInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_getAttrInfo
+ * name:         eCelltypeInfo_getAttrInfo
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_getAttrInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eCelltypeInfo_getAttrInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+    CELLCB	*p_cellcb;
+    ER      ercd = E_OK;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    if( 0 <= ith && ith < NCP_cAttrInfo ){
+        if( is_cAttrInfo_joined( ith ) )
+            *desc = cAttrInfo_refer_to_descriptor( ith );
+        else
+            ercd = E_NOEXS;
+    }
+    else
+        ercd = E_ID;
+    return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_getNVar
+ * name:         eCelltypeInfo_getNVar
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_getNVar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eCelltypeInfo_getNVar(CELLIDX idx)
+{
+    CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    return NCP_cVarInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_getVarInfo
+ * name:         eCelltypeInfo_getVarInfo
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_getVarInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eCelltypeInfo_getVarInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+    CELLCB	*p_cellcb;
+    ER      ercd = E_OK;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    if( 0 <= ith &&  ith < NCP_cVarInfo ){
+        if( is_cVarInfo_joined( ith ) )
+            *desc = cVarInfo_refer_to_descriptor( ith );
+        else
+            ercd = E_NOEXS;
+    }
+    else
+        ercd = E_ID;
+    return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_getNCall
+ * name:         eCelltypeInfo_getNCall
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_getNCall
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eCelltypeInfo_getNCall(CELLIDX idx)
+{
+    CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    return NCP_cCallInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_getCallInfo
+ * name:         eCelltypeInfo_getCallInfo
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_getCallInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eCelltypeInfo_getCallInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sCallInfo )* desc)
+{
+    CELLCB	*p_cellcb;
+    ER      ercd = E_OK;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    if( 0 <= ith && ith < NCP_cCallInfo ){
+        if( is_cCallInfo_joined( ith ) )
+            *desc = cCallInfo_refer_to_descriptor( ith );
+        else
+            ercd = E_NOEXS;
+    }
+    else
+        ercd = E_ID;
+
+    return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_getNEntry
+ * name:         eCelltypeInfo_getNEntry
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_getNEntry
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eCelltypeInfo_getNEntry(CELLIDX idx)
+{
+    CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    return NCP_cEntryInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_getEntryInfo
+ * name:         eCelltypeInfo_getEntryInfo
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_getEntryInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eCelltypeInfo_getEntryInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sEntryInfo )* desc)
+{
+    CELLCB	*p_cellcb;
+    ER      ercd = E_OK;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    if( 0 <= ith && ith < NCP_cEntryInfo ){
+        if( is_cEntryInfo_joined( ith ) )
+            *desc = cEntryInfo_refer_to_descriptor( ith );
+        else
+            ercd = E_NOEXS;
+    }
+    else
+        ercd = E_ID;
+
+    return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_isSingleton
+ * name:         eCelltypeInfo_isSingleton
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_isSingleton
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+bool_t
+eCelltypeInfo_isSingleton(CELLIDX idx)
+{
+    CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    return ATTR_b_singleton;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_isIDX_is_ID
+ * name:         eCelltypeInfo_isIDX_is_ID
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_isIDX_is_ID
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+bool_t
+eCelltypeInfo_isIDX_is_ID(CELLIDX idx)
+{
+    CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* Write error processing code here */
+    } /* end if VALID_IDX(idx) */
+
+    /* Put statements here #_TEFB_# */
+    return ATTR_b_IDX_is_ID_act;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_sizeOfCB
+ * name:         eCelltypeInfo_sizeOfCB
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_sizeOfCB
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eCelltypeInfo_sizeOfCB(CELLIDX idx)
+{
+    CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* エラー処理コードをここに記述します */
+    } /* end if VALID_IDX(idx) */
+
+    /* ここに処理本体を記述します #_TEFB_# */
+    return ATTR_sizeOfCB;
+}
+
+/* #[<ENTRY_FUNC>]# eCelltypeInfo_sizeOfINIB
+ * name:         eCelltypeInfo_sizeOfINIB
+ * global_name:  nTECSInfo_tCelltypeInfo_eCelltypeInfo_sizeOfINIB
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eCelltypeInfo_sizeOfINIB(CELLIDX idx)
+{
+    CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+        p_cellcb = GET_CELLCB(idx);
+    }
+    else {
+        /* エラー処理コードをここに記述します */
+    } /* end if VALID_IDX(idx) */
+
+    /* ここに処理本体を記述します #_TEFB_# */
+    return ATTR_sizeOfINIB;
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tDefinedTypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tDefinedTypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tDefinedTypeInfo.c	(revision 398)
@@ -0,0 +1,255 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * typeKind         int8_t           ATTR_typeKind   
+ * size             uint32_t         ATTR_size       
+ * b_const          bool_t           ATTR_b_const    
+ * b_volatile       bool_t           ATTR_b_volatile 
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cTypeInfo signature: nTECSInfo_sTypeInfo context:task
+ *   ER             cTypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cTypeInfo_getNameLength( );
+ *   uint32_t       cTypeInfo_getSize( );
+ *   int8_t         cTypeInfo_getKind( );
+ *   uint32_t       cTypeInfo_getNType( );
+ *   ER             cTypeInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   uint32_t       cTypeInfo_getNMember( );
+ *   ER             cTypeInfo_getMemberInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_ref_desc()      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tDefinedTypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTypeInfo
+ * entry port: eTypeInfo
+ * signature:  nTECSInfo_sTypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getName
+ * name:         eTypeInfo_getName
+ * global_name:  nTECSInfo_tDefinedTypeInfo_eTypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNameLength
+ * name:         eTypeInfo_getNameLength
+ * global_name:  nTECSInfo_tDefinedTypeInfo_eTypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eTypeInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getSize
+ * name:         eTypeInfo_getSize
+ * global_name:  nTECSInfo_tDefinedTypeInfo_eTypeInfo_getSize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getSize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return cTypeInfo_getSize();
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getKind
+ * name:         eTypeInfo_getKind
+ * global_name:  nTECSInfo_tDefinedTypeInfo_eTypeInfo_getKind
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+int8_t
+eTypeInfo_getKind(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return TECSTypeKind_DefinedType;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNType
+ * name:         eTypeInfo_getNType
+ * global_name:  nTECSInfo_tDefinedTypeInfo_eTypeInfo_getNType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNType(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return 1;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getTypeInfo
+ * name:         eTypeInfo_getTypeInfo
+ * global_name:  nTECSInfo_tDefinedTypeInfo_eTypeInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  /*
+   * ith == 0 is valid, others are invalid.
+   * but this function always returns valid value
+   */
+  *desc = cTypeInfo_refer_to_descriptor();
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNMember
+ * name:         eTypeInfo_getNMember
+ * global_name:  nTECSInfo_tDefinedTypeInfo_eTypeInfo_getNMember
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNMember(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getMemberInfo
+ * name:         eTypeInfo_getMemberInfo
+ * global_name:  nTECSInfo_tDefinedTypeInfo_eTypeInfo_getMemberInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getMemberInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tDescriptorTypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tDescriptorTypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tDescriptorTypeInfo.c	(revision 398)
@@ -0,0 +1,247 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * typeKind         int8_t           ATTR_typeKind   
+ * size             uint32_t         ATTR_size       
+ * b_const          bool_t           ATTR_b_const    
+ * b_volatile       bool_t           ATTR_b_volatile 
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cSignatureInfo signature: nTECSInfo_sSignatureInfo context:task
+ *   ER             cSignatureInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cSignatureInfo_getNameLength( );
+ *   uint32_t       cSignatureInfo_getNFunction( );
+ *   ER             cSignatureInfo_getFunctionInfo( uint32_t ith, Descriptor( nTECSInfo_sFunctionInfo )* desc );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sSignatureInfo ) cSignatureInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sSignatureInfo ) cSignatureInfo_ref_desc()      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tDescriptorTypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTypeInfo
+ * entry port: eTypeInfo
+ * signature:  nTECSInfo_sTypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getName
+ * name:         eTypeInfo_getName
+ * global_name:  nTECSInfo_tDescriptorTypeInfo_eTypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNameLength
+ * name:         eTypeInfo_getNameLength
+ * global_name:  nTECSInfo_tDescriptorTypeInfo_eTypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eTypeInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getSize
+ * name:         eTypeInfo_getSize
+ * global_name:  nTECSInfo_tDescriptorTypeInfo_eTypeInfo_getSize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getSize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return ATTR_size;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getKind
+ * name:         eTypeInfo_getKind
+ * global_name:  nTECSInfo_tDescriptorTypeInfo_eTypeInfo_getKind
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+int8_t
+eTypeInfo_getKind(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return TECSTypeKind_DescriptorType;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNType
+ * name:         eTypeInfo_getNType
+ * global_name:  nTECSInfo_tDescriptorTypeInfo_eTypeInfo_getNType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNType(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return 0;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getTypeInfo
+ * name:         eTypeInfo_getTypeInfo
+ * global_name:  nTECSInfo_tDescriptorTypeInfo_eTypeInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return E_NOEXS;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNMember
+ * name:         eTypeInfo_getNMember
+ * global_name:  nTECSInfo_tDescriptorTypeInfo_eTypeInfo_getNMember
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNMember(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getMemberInfo
+ * name:         eTypeInfo_getMemberInfo
+ * global_name:  nTECSInfo_tDescriptorTypeInfo_eTypeInfo_getMemberInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getMemberInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tEntryInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tEntryInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tEntryInfo.c	(revision 398)
@@ -0,0 +1,183 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * b_inline         bool_t           ATTR_b_inline   
+ * array_size       uint32_t         ATTR_array_size 
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cSignatureInfo signature: nTECSInfo_sSignatureInfo context:task
+ *   ER             cSignatureInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cSignatureInfo_getNameLength( );
+ *   uint32_t       cSignatureInfo_getNFunction( );
+ *   ER             cSignatureInfo_getFunctionInfo( uint32_t ith, Descriptor( nTECSInfo_sFunctionInfo )* desc );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sSignatureInfo ) cSignatureInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sSignatureInfo ) cSignatureInfo_ref_desc()      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tEntryInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eEntryInfo
+ * entry port: eEntryInfo
+ * signature:  nTECSInfo_sEntryInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eEntryInfo_getName
+ * name:         eEntryInfo_getName
+ * global_name:  nTECSInfo_tEntryInfo_eEntryInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eEntryInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eEntryInfo_getNameLength
+ * name:         eEntryInfo_getNameLength
+ * global_name:  nTECSInfo_tEntryInfo_eEntryInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eEntryInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eEntryInfo_getSignatureInfo
+ * name:         eEntryInfo_getSignatureInfo
+ * global_name:  nTECSInfo_tEntryInfo_eEntryInfo_getSignatureInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eEntryInfo_getSignatureInfo(CELLIDX idx, Descriptor( nTECSInfo_sSignatureInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *desc = cSignatureInfo_refer_to_descriptor();
+}
+
+/* #[<ENTRY_FUNC>]# eEntryInfo_getArraySize
+ * name:         eEntryInfo_getArraySize
+ * global_name:  nTECSInfo_tEntryInfo_eEntryInfo_getArraySize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eEntryInfo_getArraySize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return ATTR_array_size;
+}
+
+/* #[<ENTRY_FUNC>]# eEntryInfo_isInline
+ * name:         eEntryInfo_isInline
+ * global_name:  nTECSInfo_tEntryInfo_eEntryInfo_isInline
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+bool_t
+eEntryInfo_isInline(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return ATTR_b_inline;
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tFloatTypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tFloatTypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tFloatTypeInfo.c	(revision 398)
@@ -0,0 +1,237 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * typeKind         int8_t           ATTR_typeKind   
+ * size             uint32_t         ATTR_size       
+ * b_const          bool_t           ATTR_b_const    
+ * b_volatile       bool_t           ATTR_b_volatile 
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tFloatTypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTypeInfo
+ * entry port: eTypeInfo
+ * signature:  nTECSInfo_sTypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getName
+ * name:         eTypeInfo_getName
+ * global_name:  nTECSInfo_tFloatTypeInfo_eTypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNameLength
+ * name:         eTypeInfo_getNameLength
+ * global_name:  nTECSInfo_tFloatTypeInfo_eTypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eTypeInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getSize
+ * name:         eTypeInfo_getSize
+ * global_name:  nTECSInfo_tFloatTypeInfo_eTypeInfo_getSize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getSize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return ATTR_size;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getKind
+ * name:         eTypeInfo_getKind
+ * global_name:  nTECSInfo_tFloatTypeInfo_eTypeInfo_getKind
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+int8_t
+eTypeInfo_getKind(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return TECSTypeKind_FloatType;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNType
+ * name:         eTypeInfo_getNType
+ * global_name:  nTECSInfo_tFloatTypeInfo_eTypeInfo_getNType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNType(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return 0;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getTypeInfo
+ * name:         eTypeInfo_getTypeInfo
+ * global_name:  nTECSInfo_tFloatTypeInfo_eTypeInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return E_NOEXS;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNMember
+ * name:         eTypeInfo_getNMember
+ * global_name:  nTECSInfo_tFloatTypeInfo_eTypeInfo_getNMember
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNMember(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getMemberInfo
+ * name:         eTypeInfo_getMemberInfo
+ * global_name:  nTECSInfo_tFloatTypeInfo_eTypeInfo_getMemberInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getMemberInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tFunctionInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tFunctionInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tFunctionInfo.c	(revision 398)
@@ -0,0 +1,200 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * bOneway          bool_t           ATTR_bOneway    
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cParamInfo signature: nTECSInfo_sParamInfo context:task optional:true
+ *   bool_t     is_cParamInfo_joined(int subscript)        check if joined
+ *   ER             cParamInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cParamInfo_getNameLength( subscript );
+ *   ER             cParamInfo_getTypeInfo( subscript, Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *       subscript:  0...(NCP_cParamInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sParamInfo ) cParamInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sParamInfo ) cParamInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ * call port: cReturnTypeInfo signature: nTECSInfo_sTypeInfo context:task
+ *   ER             cReturnTypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cReturnTypeInfo_getNameLength( );
+ *   uint32_t       cReturnTypeInfo_getSize( );
+ *   int8_t         cReturnTypeInfo_getKind( );
+ *   uint32_t       cReturnTypeInfo_getNType( );
+ *   ER             cReturnTypeInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   uint32_t       cReturnTypeInfo_getNMember( );
+ *   ER             cReturnTypeInfo_getMemberInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sTypeInfo ) cReturnTypeInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sTypeInfo ) cReturnTypeInfo_ref_desc()      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tFunctionInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eFunctionInfo
+ * entry port: eFunctionInfo
+ * signature:  nTECSInfo_sFunctionInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eFunctionInfo_getName
+ * name:         eFunctionInfo_getName
+ * global_name:  nTECSInfo_tFunctionInfo_eFunctionInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eFunctionInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eFunctionInfo_getNameLength
+ * name:         eFunctionInfo_getNameLength
+ * global_name:  nTECSInfo_tFunctionInfo_eFunctionInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eFunctionInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eFunctionInfo_getReturnTypeInfo
+ * name:         eFunctionInfo_getReturnTypeInfo
+ * global_name:  nTECSInfo_tFunctionInfo_eFunctionInfo_getReturnTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eFunctionInfo_getReturnTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *desc = cReturnTypeInfo_refer_to_descriptor();
+}
+
+/* #[<ENTRY_FUNC>]# eFunctionInfo_getNParam
+ * name:         eFunctionInfo_getNParam
+ * global_name:  nTECSInfo_tFunctionInfo_eFunctionInfo_getNParam
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eFunctionInfo_getNParam(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return NCP_cParamInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eFunctionInfo_getParamInfo
+ * name:         eFunctionInfo_getParamInfo
+ * global_name:  nTECSInfo_tFunctionInfo_eFunctionInfo_getParamInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eFunctionInfo_getParamInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sParamInfo )* param)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  if( ith >= NCP_cParamInfo )
+      ercd = E_NOEXS;
+  else
+      *param = cParamInfo_refer_to_descriptor( ith );
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tIntTypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tIntTypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tIntTypeInfo.c	(revision 398)
@@ -0,0 +1,237 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * typeKind         int8_t           ATTR_typeKind   
+ * size             uint32_t         ATTR_size       
+ * b_const          bool_t           ATTR_b_const    
+ * b_volatile       bool_t           ATTR_b_volatile 
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tIntTypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTypeInfo
+ * entry port: eTypeInfo
+ * signature:  nTECSInfo_sTypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getName
+ * name:         eTypeInfo_getName
+ * global_name:  nTECSInfo_tIntTypeInfo_eTypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNameLength
+ * name:         eTypeInfo_getNameLength
+ * global_name:  nTECSInfo_tIntTypeInfo_eTypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eTypeInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getSize
+ * name:         eTypeInfo_getSize
+ * global_name:  nTECSInfo_tIntTypeInfo_eTypeInfo_getSize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getSize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return ATTR_size;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getKind
+ * name:         eTypeInfo_getKind
+ * global_name:  nTECSInfo_tIntTypeInfo_eTypeInfo_getKind
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+int8_t
+eTypeInfo_getKind(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return TECSTypeKind_IntType;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNType
+ * name:         eTypeInfo_getNType
+ * global_name:  nTECSInfo_tIntTypeInfo_eTypeInfo_getNType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNType(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return 0;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getTypeInfo
+ * name:         eTypeInfo_getTypeInfo
+ * global_name:  nTECSInfo_tIntTypeInfo_eTypeInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return E_NOEXS;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNMember
+ * name:         eTypeInfo_getNMember
+ * global_name:  nTECSInfo_tIntTypeInfo_eTypeInfo_getNMember
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNMember(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getMemberInfo
+ * name:         eTypeInfo_getMemberInfo
+ * global_name:  nTECSInfo_tIntTypeInfo_eTypeInfo_getMemberInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getMemberInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tNamespaceInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tNamespaceInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tNamespaceInfo.c	(revision 398)
@@ -0,0 +1,277 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char*            ATTR_name       
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cSignatureInfo signature: nTECSInfo_sSignatureInfo context:task optional:true
+ *   bool_t     is_cSignatureInfo_joined(int subscript)        check if joined
+ *   ER             cSignatureInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cSignatureInfo_getNameLength( subscript );
+ *   uint32_t       cSignatureInfo_getNFunction( subscript );
+ *   ER             cSignatureInfo_getFunctionInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sFunctionInfo )* desc );
+ *       subscript:  0...(NCP_cSignatureInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sSignatureInfo ) cSignatureInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sSignatureInfo ) cSignatureInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ * call port: cCelltypeInfo signature: nTECSInfo_sCelltypeInfo context:task optional:true
+ *   bool_t     is_cCelltypeInfo_joined(int subscript)        check if joined
+ *   ER             cCelltypeInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cCelltypeInfo_getNameLength( subscript );
+ *   uint32_t       cCelltypeInfo_getNAttr( subscript );
+ *   ER             cCelltypeInfo_getAttrInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNVar( subscript );
+ *   ER             cCelltypeInfo_getVarInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNCall( subscript );
+ *   ER             cCelltypeInfo_getCallInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sCallInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNEntry( subscript );
+ *   ER             cCelltypeInfo_getEntryInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sEntryInfo )* desc );
+ *   bool_t         cCelltypeInfo_isSingleton( subscript );
+ *   bool_t         cCelltypeInfo_isIDX_is_ID( subscript );
+ *   uint32_t       cCelltypeInfo_sizeOfCB( subscript );
+ *   uint32_t       cCelltypeInfo_sizeOfINIB( subscript );
+ *       subscript:  0...(NCP_cCelltypeInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sCelltypeInfo ) cCelltypeInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sCelltypeInfo ) cCelltypeInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ * call port: cNamespaceInfo signature: nTECSInfo_sNamespaceInfo context:task optional:true
+ *   bool_t     is_cNamespaceInfo_joined(int subscript)        check if joined
+ *   ER             cNamespaceInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cNamespaceInfo_getNameLength( subscript );
+ *   uint32_t       cNamespaceInfo_getNNamespace( subscript );
+ *   ER             cNamespaceInfo_getNamespaceInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sNamespaceInfo )* des );
+ *   uint32_t       cNamespaceInfo_getNSignature( subscript );
+ *   ER             cNamespaceInfo_getSignatureInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sSignatureInfo )* des );
+ *   uint32_t       cNamespaceInfo_getNCelltype( subscript );
+ *   ER             cNamespaceInfo_getCelltypeInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sCelltypeInfo )* des );
+ *       subscript:  0...(NCP_cNamespaceInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sNamespaceInfo ) cNamespaceInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sNamespaceInfo ) cNamespaceInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tNamespaceInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eNamespaceInfo
+ * entry port: eNamespaceInfo
+ * signature:  nTECSInfo_sNamespaceInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eNamespaceInfo_getName
+ * name:         eNamespaceInfo_getName
+ * global_name:  nTECSInfo_tNamespaceInfo_eNamespaceInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eNamespaceInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eNamespaceInfo_getNameLength
+ * name:         eNamespaceInfo_getNameLength
+ * global_name:  nTECSInfo_tNamespaceInfo_eNamespaceInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eNamespaceInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eNamespaceInfo_getNNamespace
+ * name:         eNamespaceInfo_getNNamespace
+ * global_name:  nTECSInfo_tNamespaceInfo_eNamespaceInfo_getNNamespace
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eNamespaceInfo_getNNamespace(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return NCP_cNamespaceInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eNamespaceInfo_getNamespaceInfo
+ * name:         eNamespaceInfo_getNamespaceInfo
+ * global_name:  nTECSInfo_tNamespaceInfo_eNamespaceInfo_getNamespaceInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eNamespaceInfo_getNamespaceInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sNamespaceInfo )* des)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *des = cNamespaceInfo_refer_to_descriptor( ith );
+}
+
+/* #[<ENTRY_FUNC>]# eNamespaceInfo_getNSignature
+ * name:         eNamespaceInfo_getNSignature
+ * global_name:  nTECSInfo_tNamespaceInfo_eNamespaceInfo_getNSignature
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eNamespaceInfo_getNSignature(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return NCP_cSignatureInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eNamespaceInfo_getSignatureInfo
+ * name:         eNamespaceInfo_getSignatureInfo
+ * global_name:  nTECSInfo_tNamespaceInfo_eNamespaceInfo_getSignatureInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eNamespaceInfo_getSignatureInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sSignatureInfo )* des)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	*des = cSignatureInfo_refer_to_descriptor( ith );
+}
+
+/* #[<ENTRY_FUNC>]# eNamespaceInfo_getNCelltype
+ * name:         eNamespaceInfo_getNCelltype
+ * global_name:  nTECSInfo_tNamespaceInfo_eNamespaceInfo_getNCelltype
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eNamespaceInfo_getNCelltype(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return NCP_cCelltypeInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eNamespaceInfo_getCelltypeInfo
+ * name:         eNamespaceInfo_getCelltypeInfo
+ * global_name:  nTECSInfo_tNamespaceInfo_eNamespaceInfo_getCelltypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eNamespaceInfo_getCelltypeInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sCelltypeInfo )* des)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	*des = cCelltypeInfo_refer_to_descriptor( ith );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tParamInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tParamInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tParamInfo.c	(revision 398)
@@ -0,0 +1,174 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * dir              int8_t           ATTR_dir        
+ * sizeIsExpr       char_t*          ATTR_sizeIsExpr 
+ * countIsExpr      char_t*          ATTR_countIsExpr
+ * stringExpr       char_t*          ATTR_stringExpr 
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cTypeInfo signature: nTECSInfo_sTypeInfo context:task
+ *   ER             cTypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cTypeInfo_getNameLength( );
+ *   uint32_t       cTypeInfo_getSize( );
+ *   int8_t         cTypeInfo_getKind( );
+ *   uint32_t       cTypeInfo_getNType( );
+ *   ER             cTypeInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   uint32_t       cTypeInfo_getNMember( );
+ *   ER             cTypeInfo_getMemberInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_ref_desc()      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tParamInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eParamInfo
+ * entry port: eParamInfo
+ * signature:  nTECSInfo_sParamInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eParamInfo_getName
+ * name:         eParamInfo_getName
+ * global_name:  nTECSInfo_tParamInfo_eParamInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eParamInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eParamInfo_getNameLength
+ * name:         eParamInfo_getNameLength
+ * global_name:  nTECSInfo_tParamInfo_eParamInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eParamInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eParamInfo_getTypeInfo
+ * name:         eParamInfo_getTypeInfo
+ * global_name:  nTECSInfo_tParamInfo_eParamInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eParamInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *desc = cTypeInfo_refer_to_descriptor();
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eParamInfo_getDir
+ * name:         eParamInfo_getDir
+ * global_name:  nTECSInfo_tParamInfo_eParamInfo_getDir
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eParamInfo_getDir(CELLIDX idx, int8_t *dir)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *dir = ATTR_dir;
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tPtrTypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tPtrTypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tPtrTypeInfo.c	(revision 398)
@@ -0,0 +1,251 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * typeKind         int8_t           ATTR_typeKind   
+ * size             uint32_t         ATTR_size       
+ * b_const          bool_t           ATTR_b_const    
+ * b_volatile       bool_t           ATTR_b_volatile 
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cTypeInfo signature: nTECSInfo_sTypeInfo context:task
+ *   ER             cTypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cTypeInfo_getNameLength( );
+ *   uint32_t       cTypeInfo_getSize( );
+ *   int8_t         cTypeInfo_getKind( );
+ *   uint32_t       cTypeInfo_getNType( );
+ *   ER             cTypeInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   uint32_t       cTypeInfo_getNMember( );
+ *   ER             cTypeInfo_getMemberInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_ref_desc()      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tPtrTypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTypeInfo
+ * entry port: eTypeInfo
+ * signature:  nTECSInfo_sTypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getName
+ * name:         eTypeInfo_getName
+ * global_name:  nTECSInfo_tPtrTypeInfo_eTypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNameLength
+ * name:         eTypeInfo_getNameLength
+ * global_name:  nTECSInfo_tPtrTypeInfo_eTypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eTypeInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getSize
+ * name:         eTypeInfo_getSize
+ * global_name:  nTECSInfo_tPtrTypeInfo_eTypeInfo_getSize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getSize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return ATTR_size;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getKind
+ * name:         eTypeInfo_getKind
+ * global_name:  nTECSInfo_tPtrTypeInfo_eTypeInfo_getKind
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+int8_t
+eTypeInfo_getKind(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return TECSTypeKind_PtrType;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNType
+ * name:         eTypeInfo_getNType
+ * global_name:  nTECSInfo_tPtrTypeInfo_eTypeInfo_getNType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNType(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return 1;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getTypeInfo
+ * name:         eTypeInfo_getTypeInfo
+ * global_name:  nTECSInfo_tPtrTypeInfo_eTypeInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  *desc = cTypeInfo_refer_to_descriptor();
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNMember
+ * name:         eTypeInfo_getNMember
+ * global_name:  nTECSInfo_tPtrTypeInfo_eTypeInfo_getNMember
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNMember(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getMemberInfo
+ * name:         eTypeInfo_getMemberInfo
+ * global_name:  nTECSInfo_tPtrTypeInfo_eTypeInfo_getMemberInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getMemberInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tRawEntryDescriptorInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tRawEntryDescriptorInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tRawEntryDescriptorInfo.c	(revision 398)
@@ -0,0 +1,75 @@
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * size             int_t            ATTR_size       
+ * rawEntryDescriptor void**           ATTR_rawEntryDescriptor
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nTECSInfo_tRawEntryDescriptorInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eRawEntryDescriptor
+ * entry port: eRawEntryDescriptor
+ * signature:  nTECSInfo_sRawEntryDescriptorInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eRawEntryDescriptor_getNRawEntryDescriptorInfo
+ * name:         eRawEntryDescriptor_getNRawEntryDescriptorInfo
+ * global_name:  nTECSInfo_tRawEntryDescriptorInfo_eRawEntryDescriptor_getNRawEntryDescriptorInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eRawEntryDescriptor_getNRawEntryDescriptorInfo(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eRawEntryDescriptor_getRawDescriptor
+ * name:         eRawEntryDescriptor_getRawDescriptor
+ * global_name:  nTECSInfo_tRawEntryDescriptorInfo_eRawEntryDescriptor_getRawDescriptor
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eRawEntryDescriptor_getRawDescriptor(CELLIDX idx, int_t ith, void** rawDesc)
+{
+	CELLCB	*p_cellcb;
+  ER      ercd = E_OK;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( 0 <= ith && ith < ATTR_size ){
+      *rawDesc = ATTR_rawEntryDescriptor[ ith ];
+  }
+  else {
+      ercd = E_ID;
+  }
+  return ercd;
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tRegionInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tRegionInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tRegionInfo.c	(revision 398)
@@ -0,0 +1,216 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char*            ATTR_name       
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cCellInfo signature: nTECSInfo_sCellInfo context:task optional:true
+ *   bool_t     is_cCellInfo_joined(int subscript)        check if joined
+ *   ER             cCellInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cCellInfo_getNameLength( subscript );
+ *   void           cCellInfo_getCelltypeInfo( subscript, Descriptor( nTECSInfo_sCelltypeInfo )* desc );
+ *   void           cCellInfo_getCBP( subscript, void** cbp );
+ *   void           cCellInfo_getINIBP( subscript, void** inibp );
+ *       subscript:  0...(NCP_cCellInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sCellInfo ) cCellInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sCellInfo ) cCellInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ * call port: cRegionInfo signature: nTECSInfo_sRegionInfo context:task optional:true
+ *   bool_t     is_cRegionInfo_joined(int subscript)        check if joined
+ *   ER             cRegionInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cRegionInfo_getNameLength( subscript );
+ *   uint32_t       cRegionInfo_getNCell( subscript );
+ *   ER             cRegionInfo_getCellInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sCellInfo )* des );
+ *   uint32_t       cRegionInfo_getNRegion( subscript );
+ *   ER             cRegionInfo_getRegionInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sRegionInfo )* des );
+ *       subscript:  0...(NCP_cRegionInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sRegionInfo ) cRegionInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sRegionInfo ) cRegionInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tRegionInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eRegionInfo
+ * entry port: eRegionInfo
+ * signature:  nTECSInfo_sRegionInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eRegionInfo_getName
+ * name:         eRegionInfo_getName
+ * global_name:  nTECSInfo_tRegionInfo_eRegionInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eRegionInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eRegionInfo_getNameLength
+ * name:         eRegionInfo_getNameLength
+ * global_name:  nTECSInfo_tRegionInfo_eRegionInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eRegionInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eRegionInfo_getNCell
+ * name:         eRegionInfo_getNCell
+ * global_name:  nTECSInfo_tRegionInfo_eRegionInfo_getNCell
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eRegionInfo_getNCell(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return NCP_cCellInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eRegionInfo_getCellInfo
+ * name:         eRegionInfo_getCellInfo
+ * global_name:  nTECSInfo_tRegionInfo_eRegionInfo_getCellInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eRegionInfo_getCellInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sCellInfo )* des)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *des = cCellInfo_refer_to_descriptor( ith );
+}
+
+/* #[<ENTRY_FUNC>]# eRegionInfo_getNRegion
+ * name:         eRegionInfo_getNRegion
+ * global_name:  nTECSInfo_tRegionInfo_eRegionInfo_getNRegion
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eRegionInfo_getNRegion(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return NCP_cRegionInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eRegionInfo_getRegionInfo
+ * name:         eRegionInfo_getRegionInfo
+ * global_name:  nTECSInfo_tRegionInfo_eRegionInfo_getRegionInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eRegionInfo_getRegionInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sRegionInfo )* des)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *des = cRegionInfo_refer_to_descriptor( ith );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tSignatureInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tSignatureInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tSignatureInfo.c	(revision 398)
@@ -0,0 +1,165 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char*            ATTR_name       
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cFunctionInfo signature: nTECSInfo_sFunctionInfo context:task optional:true
+ *   bool_t     is_cFunctionInfo_joined(int subscript)        check if joined
+ *   ER             cFunctionInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cFunctionInfo_getNameLength( subscript );
+ *   void           cFunctionInfo_getReturnTypeInfo( subscript, Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   uint32_t       cFunctionInfo_getNParam( subscript );
+ *   ER             cFunctionInfo_getParamInfo( subscript, uint32_t ith, Descriptor( nTECSInfo_sParamInfo )* param );
+ *       subscript:  0...(NCP_cFunctionInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sFunctionInfo ) cFunctionInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sFunctionInfo ) cFunctionInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tSignatureInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eSignatureInfo
+ * entry port: eSignatureInfo
+ * signature:  nTECSInfo_sSignatureInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eSignatureInfo_getName
+ * name:         eSignatureInfo_getName
+ * global_name:  nTECSInfo_tSignatureInfo_eSignatureInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSignatureInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSignatureInfo_getNameLength
+ * name:         eSignatureInfo_getNameLength
+ * global_name:  nTECSInfo_tSignatureInfo_eSignatureInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eSignatureInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+      /* 終端文字 (NULL) を含む */
+}
+
+/* #[<ENTRY_FUNC>]# eSignatureInfo_getNFunction
+ * name:         eSignatureInfo_getNFunction
+ * global_name:  nTECSInfo_tSignatureInfo_eSignatureInfo_getNFunction
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eSignatureInfo_getNFunction(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return NCP_cFunctionInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eSignatureInfo_getFunctionInfo
+ * name:         eSignatureInfo_getFunctionInfo
+ * global_name:  nTECSInfo_tSignatureInfo_eSignatureInfo_getFunctionInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSignatureInfo_getFunctionInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sFunctionInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  *desc = cFunctionInfo_ref_desc( ith );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tStructTypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tStructTypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tStructTypeInfo.c	(revision 398)
@@ -0,0 +1,255 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * typeKind         int8_t           ATTR_typeKind   
+ * size             uint32_t         ATTR_size       
+ * b_const          bool_t           ATTR_b_const    
+ * b_volatile       bool_t           ATTR_b_volatile 
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cVarDeclInfo signature: nTECSInfo_sVarDeclInfo context:task
+ *   ER             cVarDeclInfo_getName( subscript, char_t* name, int_t max_len );
+ *   uint16_t       cVarDeclInfo_getNameLength( subscript );
+ *   uint32_t       cVarDeclInfo_getOffset( subscript );
+ *   void           cVarDeclInfo_getTypeInfo( subscript, Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   void           cVarDeclInfo_getSizeIsExpr( subscript, char_t* expr_str, int32_t max_len );
+ *   ER             cVarDeclInfo_getSizeIs( subscript, uint32_t* size, const void* p_cb );
+ *       subscript:  0...(NCP_cVarDeclInfo-1)
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sVarDeclInfo ) cVarDeclInfo_refer_to_descriptor( int_t subscript );
+ *      Descriptor( nTECSInfo_sVarDeclInfo ) cVarDeclInfo_ref_desc( int_t subscript )      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tStructTypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTypeInfo
+ * entry port: eTypeInfo
+ * signature:  nTECSInfo_sTypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getName
+ * name:         eTypeInfo_getName
+ * global_name:  nTECSInfo_tStructTypeInfo_eTypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNameLength
+ * name:         eTypeInfo_getNameLength
+ * global_name:  nTECSInfo_tStructTypeInfo_eTypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eTypeInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+      /* 終端文字 (NULL) を含む */
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getSize
+ * name:         eTypeInfo_getSize
+ * global_name:  nTECSInfo_tStructTypeInfo_eTypeInfo_getSize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getSize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return ATTR_size;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getKind
+ * name:         eTypeInfo_getKind
+ * global_name:  nTECSInfo_tStructTypeInfo_eTypeInfo_getKind
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+int8_t
+eTypeInfo_getKind(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return TECSTypeKind_StructType;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNType
+ * name:         eTypeInfo_getNType
+ * global_name:  nTECSInfo_tStructTypeInfo_eTypeInfo_getNType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNType(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return NCP_cVarDeclInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getTypeInfo
+ * name:         eTypeInfo_getTypeInfo
+ * global_name:  nTECSInfo_tStructTypeInfo_eTypeInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  // *desc = cTypeInfo_refer_to_descriptor( ith );
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNMember
+ * name:         eTypeInfo_getNMember
+ * global_name:  nTECSInfo_tStructTypeInfo_eTypeInfo_getNMember
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNMember(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return NCP_cVarDeclInfo;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getMemberInfo
+ * name:         eTypeInfo_getMemberInfo
+ * global_name:  nTECSInfo_tStructTypeInfo_eTypeInfo_getMemberInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getMemberInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( ith >= NCP_cVarDeclInfo )
+      ercd = E_NOEXS;
+  else
+      *desc = cVarDeclInfo_refer_to_descriptor( ith );
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTECSInfoAccessor.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTECSInfoAccessor.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTECSInfoAccessor.c	(revision 398)
@@ -0,0 +1,1130 @@
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * NAME_LEN         int16_t          ATTR_NAME_LEN   
+ * name             char_t*          VAR_name        
+ * name2            char_t*          VAR_name2       
+ * selectedCbp      int8_t*          VAR_selectedCbp 
+ * selectedInibp    int8_t*          VAR_selectedInibp
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cTECSInfo signature: nTECSInfo_sTECSInfo context:task
+ *   ER             cTECSInfo_findNamespace( const char_t* namespace_path, Descriptor( nTECSInfo_sNamespaceInfo )* NSdesc );
+ *   ER             cTECSInfo_findRegion( const char_t* namespace_path, Descriptor( nTECSInfo_sRegionInfo )* RGNdesc );
+ *   ER             cTECSInfo_findSignature( const char_t* namespace_path, Descriptor( nTECSInfo_sSignatureInfo )* SIGdesc );
+ *   ER             cTECSInfo_findCelltype( const char_t* namespace_path, Descriptor( nTECSInfo_sCelltypeInfo )* CTdesc );
+ *   ER             cTECSInfo_findCell( const char_t* namespace_path, Descriptor( nTECSInfo_sCellInfo )* CELLdesc );
+ * call port: cNSInfo signature: nTECSInfo_sNamespaceInfo context:task optional:true
+ *   bool_t     is_cNSInfo_joined()                     check if joined
+ *   ER             cNSInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cNSInfo_getNameLength( );
+ *   uint32_t       cNSInfo_getNNamespace( );
+ *   ER             cNSInfo_getNamespaceInfo( uint32_t ith, Descriptor( nTECSInfo_sNamespaceInfo )* des );
+ *   uint32_t       cNSInfo_getNSignature( );
+ *   ER             cNSInfo_getSignatureInfo( uint32_t ith, Descriptor( nTECSInfo_sSignatureInfo )* des );
+ *   uint32_t       cNSInfo_getNCelltype( );
+ *   ER             cNSInfo_getCelltypeInfo( uint32_t ith, Descriptor( nTECSInfo_sCelltypeInfo )* des );
+ *   [dynamic, optional]
+ *      void           cNSInfo_set_descriptor( Descriptor( nTECSInfo_sNamespaceInfo ) desc );
+ *      void           cNSInfo_unjoin(  );
+ * call port: cCelltypeInfo signature: nTECSInfo_sCelltypeInfo context:task optional:true
+ *   bool_t     is_cCelltypeInfo_joined()                     check if joined
+ *   ER             cCelltypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cCelltypeInfo_getNameLength( );
+ *   uint32_t       cCelltypeInfo_getNAttr( );
+ *   ER             cCelltypeInfo_getAttrInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNVar( );
+ *   ER             cCelltypeInfo_getVarInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNCall( );
+ *   ER             cCelltypeInfo_getCallInfo( uint32_t ith, Descriptor( nTECSInfo_sCallInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNEntry( );
+ *   ER             cCelltypeInfo_getEntryInfo( uint32_t ith, Descriptor( nTECSInfo_sEntryInfo )* desc );
+ *   bool_t         cCelltypeInfo_isSingleton( );
+ *   bool_t         cCelltypeInfo_isIDX_is_ID( );
+ *   uint32_t       cCelltypeInfo_sizeOfCB( );
+ *   uint32_t       cCelltypeInfo_sizeOfINIB( );
+ *   [dynamic, optional]
+ *      void           cCelltypeInfo_set_descriptor( Descriptor( nTECSInfo_sCelltypeInfo ) desc );
+ *      void           cCelltypeInfo_unjoin(  );
+ * call port: cAttrInfo signature: nTECSInfo_sVarDeclInfo context:task optional:true
+ *   bool_t     is_cAttrInfo_joined()                     check if joined
+ *   ER             cAttrInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cAttrInfo_getNameLength( );
+ *   uint32_t       cAttrInfo_getOffset( );
+ *   void           cAttrInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   void           cAttrInfo_getSizeIsExpr( char_t* expr_str, int32_t max_len );
+ *   ER             cAttrInfo_getSizeIs( uint32_t* size, const void* p_cb );
+ *   [dynamic, optional]
+ *      void           cAttrInfo_set_descriptor( Descriptor( nTECSInfo_sVarDeclInfo ) desc );
+ *      void           cAttrInfo_unjoin(  );
+ * call port: cVarInfo signature: nTECSInfo_sVarDeclInfo context:task optional:true
+ *   bool_t     is_cVarInfo_joined()                     check if joined
+ *   ER             cVarInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cVarInfo_getNameLength( );
+ *   uint32_t       cVarInfo_getOffset( );
+ *   void           cVarInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   void           cVarInfo_getSizeIsExpr( char_t* expr_str, int32_t max_len );
+ *   ER             cVarInfo_getSizeIs( uint32_t* size, const void* p_cb );
+ *   [dynamic, optional]
+ *      void           cVarInfo_set_descriptor( Descriptor( nTECSInfo_sVarDeclInfo ) desc );
+ *      void           cVarInfo_unjoin(  );
+ * call port: cTypeInfo signature: nTECSInfo_sTypeInfo context:task optional:true
+ *   bool_t     is_cTypeInfo_joined()                     check if joined
+ *   ER             cTypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cTypeInfo_getNameLength( );
+ *   uint32_t       cTypeInfo_getSize( );
+ *   int8_t         cTypeInfo_getKind( );
+ *   uint32_t       cTypeInfo_getNType( );
+ *   ER             cTypeInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   uint32_t       cTypeInfo_getNMember( );
+ *   ER             cTypeInfo_getMemberInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   [dynamic, optional]
+ *      void           cTypeInfo_set_descriptor( Descriptor( nTECSInfo_sTypeInfo ) desc );
+ *      void           cTypeInfo_unjoin(  );
+ * call port: cRegionInfo signature: nTECSInfo_sRegionInfo context:task optional:true
+ *   bool_t     is_cRegionInfo_joined()                     check if joined
+ *   ER             cRegionInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cRegionInfo_getNameLength( );
+ *   uint32_t       cRegionInfo_getNCell( );
+ *   ER             cRegionInfo_getCellInfo( uint32_t ith, Descriptor( nTECSInfo_sCellInfo )* des );
+ *   uint32_t       cRegionInfo_getNRegion( );
+ *   ER             cRegionInfo_getRegionInfo( uint32_t ith, Descriptor( nTECSInfo_sRegionInfo )* des );
+ *   [dynamic, optional]
+ *      void           cRegionInfo_set_descriptor( Descriptor( nTECSInfo_sRegionInfo ) desc );
+ *      void           cRegionInfo_unjoin(  );
+ * call port: cCellInfo signature: nTECSInfo_sCellInfo context:task optional:true
+ *   bool_t     is_cCellInfo_joined()                     check if joined
+ *   ER             cCellInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cCellInfo_getNameLength( );
+ *   void           cCellInfo_getCelltypeInfo( Descriptor( nTECSInfo_sCelltypeInfo )* desc );
+ *   void           cCellInfo_getCBP( void** cbp );
+ *   void           cCellInfo_getINIBP( void** inibp );
+ *   [dynamic, optional]
+ *      void           cCellInfo_set_descriptor( Descriptor( nTECSInfo_sCellInfo ) desc );
+ *      void           cCellInfo_unjoin(  );
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tTECSInfoAccessor_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eSelector
+ * entry port: eSelector
+ * signature:  nTECSInfo_sAccessor
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eSelector_selectNamespaceInfoByName
+ * name:         eSelector_selectNamespaceInfoByName
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectNamespaceInfoByName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectNamespaceInfoByName(CELLIDX idx, const char_t* namespacePath)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sNamespaceInfo ) NSdesc;
+    if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+  /* ここに処理本体を記述します #_TEFB_# */
+  ercd = cTECSInfo_findNamespace( namespacePath, &NSdesc );
+  if( ercd == E_OK ){
+      cNSInfo_set_descriptor( NSdesc );
+  }
+  else{
+      cNSInfo_unjoin();
+  }
+
+  return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCelltypeInfoByName
+ * name:         eSelector_selectCelltypeInfoByName
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectCelltypeInfoByName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCelltypeInfoByName(CELLIDX idx, const char_t* namespacePath)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sCelltypeInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  ercd = cTECSInfo_findCelltype( namespacePath, &desc );
+  if( ercd == E_OK ){
+      cCelltypeInfo_set_descriptor( desc );
+  }
+  else{
+      cCelltypeInfo_unjoin();
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectSignatureInfoByName
+ * name:         eSelector_selectSignatureInfoByName
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectSignatureInfoByName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectSignatureInfoByName(CELLIDX idx, const char_t* namespacePath)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectRegionInfoByName
+ * name:         eSelector_selectRegionInfoByName
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectRegionInfoByName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectRegionInfoByName(CELLIDX idx, const char_t* regionPath)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCellInfoByName
+ * name:         eSelector_selectCellInfoByName
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectCellInfoByName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCellInfoByName(CELLIDX idx, const char_t* cellPath)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedNamespaceInfo
+ * name:         eSelector_getSelectedNamespaceInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedNamespaceInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedNamespaceInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* num_celltype, int_t* num_signature)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCelltypeInfo
+ * name:         eSelector_selectCelltypeInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectCelltypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCelltypeInfo(CELLIDX idx, int_t i)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectSignatureInfo
+ * name:         eSelector_selectSignatureInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectSignatureInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectSignatureInfo(CELLIDX idx, int_t i)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCelltypeInfo
+ * name:         eSelector_getSelectedCelltypeInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedCelltypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCelltypeInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* num_attr, int_t* num_var, int_t* num_call, int_t* num_entry)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCallInfo
+ * name:         eSelector_selectCallInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectCallInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCallInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectEntryInfo
+ * name:         eSelector_selectEntryInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectEntryInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectEntryInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectAttrInfo
+ * name:         eSelector_selectAttrInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectAttrInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectAttrInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectVarInfo
+ * name:         eSelector_selectVarInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectVarInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectVarInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedAttrInfo
+ * name:         eSelector_getSelectedAttrInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedAttrInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedAttrInfo(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSizeIsExprOfAttr
+ * name:         eSelector_getSizeIsExprOfAttr
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSizeIsExprOfAttr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eSelector_getSizeIsExprOfAttr(CELLIDX idx, char_t* expr_str, int32_t max_len)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectTypeInfoOfAttr
+ * name:         eSelector_selectTypeInfoOfAttr
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectTypeInfoOfAttr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectTypeInfoOfAttr(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedVarInfo
+ * name:         eSelector_getSelectedVarInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedVarInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedVarInfo(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSizeIsExprOfVar
+ * name:         eSelector_getSizeIsExprOfVar
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSizeIsExprOfVar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eSelector_getSizeIsExprOfVar(CELLIDX idx, char_t* expr_str, int32_t max_len)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectTypeInfoOfVar
+ * name:         eSelector_selectTypeInfoOfVar
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectTypeInfoOfVar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectTypeInfoOfVar(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCallInfo
+ * name:         eSelector_getSelectedCallInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedCallInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCallInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* array_size)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectSignatureOfCall
+ * name:         eSelector_selectSignatureOfCall
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectSignatureOfCall
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectSignatureOfCall(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCallSpecifierInfo
+ * name:         eSelector_getSelectedCallSpecifierInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedCallSpecifierInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCallSpecifierInfo(CELLIDX idx, bool_t* b_optional, bool_t* b_dynamic, bool_t* b_ref_desc, bool_t* b_omit)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCallInternalInfo
+ * name:         eSelector_getSelectedCallInternalInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedCallInternalInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCallInternalInfo(CELLIDX idx, bool_t* b_allocator_port, bool_t* b_require_port)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCallLocationInfo
+ * name:         eSelector_getSelectedCallLocationInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedCallLocationInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCallLocationInfo(CELLIDX idx, uint32_t* offset, int8_t* place)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCallOptimizeInfo
+ * name:         eSelector_getSelectedCallOptimizeInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedCallOptimizeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCallOptimizeInfo(CELLIDX idx, bool_t* b_VMT_useless, bool_t* b_skelton_useless, bool_t* b_cell_unique)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedEntryInfo
+ * name:         eSelector_getSelectedEntryInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedEntryInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedEntryInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* array_size)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectSignatureOfEntry
+ * name:         eSelector_selectSignatureOfEntry
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectSignatureOfEntry
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectSignatureOfEntry(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedEntryInlineInfo
+ * name:         eSelector_getSelectedEntryInlineInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedEntryInlineInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedEntryInlineInfo(CELLIDX idx, bool_t* b_inline)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedSignatureInfo
+ * name:         eSelector_getSelectedSignatureInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedSignatureInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedSignatureInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* num_function)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selecFunctionInfoByIndex
+ * name:         eSelector_selecFunctionInfoByIndex
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selecFunctionInfoByIndex
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selecFunctionInfoByIndex(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedFunctionInfo
+ * name:         eSelector_getSelectedFunctionInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedFunctionInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedFunctionInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* num_args)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectTypeInfoOfReturn
+ * name:         eSelector_selectTypeInfoOfReturn
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectTypeInfoOfReturn
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectTypeInfoOfReturn(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedParamInfo
+ * name:         eSelector_getSelectedParamInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedParamInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedParamInfo(CELLIDX idx, char_t* name, int_t max_len, int8_t* dir)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectParamInfo
+ * name:         eSelector_selectParamInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectParamInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectParamInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectTypeInfoOfParam
+ * name:         eSelector_selectTypeInfoOfParam
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectTypeInfoOfParam
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectTypeInfoOfParam(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedTypeInfo
+ * name:         eSelector_getSelectedTypeInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedTypeInfo(CELLIDX idx, char_t* name, int_t max_len, int8_t* kind)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectTypeInfoOfType
+ * name:         eSelector_selectTypeInfoOfType
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectTypeInfoOfType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectTypeInfoOfType(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedRegionInfo
+ * name:         eSelector_getSelectedRegionInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelectedRegionInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedRegionInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* num_cell)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCellInfo
+ * name:         eSelector_selectCellInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectCellInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCellInfo(CELLIDX idx, int_t i)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelecteCellInfo
+ * name:         eSelector_getSelecteCellInfo
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getSelecteCellInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelecteCellInfo(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCelltypeInfoOfCell
+ * name:         eSelector_selectCelltypeInfoOfCell
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_selectCelltypeInfoOfCell
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCelltypeInfoOfCell(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getAttrValue
+ * name:         eSelector_getAttrValue
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getAttrValue
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getAttrValue(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getAttrSizeIsValue
+ * name:         eSelector_getAttrSizeIsValue
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getAttrSizeIsValue
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getAttrSizeIsValue(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getVarValue
+ * name:         eSelector_getVarValue
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getVarValue
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getVarValue(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getVarSizeIsValue
+ * name:         eSelector_getVarSizeIsValue
+ * global_name:  nTECSInfo_tTECSInfoAccessor_eSelector_getVarSizeIsValue
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getVarSizeIsValue(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTECSInfoSub.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTECSInfoSub.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTECSInfoSub.c	(revision 398)
@@ -0,0 +1,526 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name_len         int32_t          ATTR_name_len   
+ * path_len         int32_t          ATTR_path_len   
+ * name1            char_t*          VAR_name1       
+ * name2            char_t*          VAR_name2       
+ * path             char_t*          VAR_path        
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cNamespaceInfo signature: nTECSInfo_sNamespaceInfo context:task
+ *   ER             cNamespaceInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cNamespaceInfo_getNameLength( );
+ *   uint32_t       cNamespaceInfo_getNNamespace( );
+ *   ER             cNamespaceInfo_getNamespaceInfo( uint32_t ith, Descriptor( nTECSInfo_sNamespaceInfo )* des );
+ *   uint32_t       cNamespaceInfo_getNSignature( );
+ *   ER             cNamespaceInfo_getSignatureInfo( uint32_t ith, Descriptor( nTECSInfo_sSignatureInfo )* des );
+ *   uint32_t       cNamespaceInfo_getNCelltype( );
+ *   ER             cNamespaceInfo_getCelltypeInfo( uint32_t ith, Descriptor( nTECSInfo_sCelltypeInfo )* des );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sNamespaceInfo ) cNamespaceInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sNamespaceInfo ) cNamespaceInfo_ref_desc()      (same as above; abbreviated version);
+ * call port: cRegionInfo signature: nTECSInfo_sRegionInfo context:task
+ *   ER             cRegionInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cRegionInfo_getNameLength( );
+ *   uint32_t       cRegionInfo_getNCell( );
+ *   ER             cRegionInfo_getCellInfo( uint32_t ith, Descriptor( nTECSInfo_sCellInfo )* des );
+ *   uint32_t       cRegionInfo_getNRegion( );
+ *   ER             cRegionInfo_getRegionInfo( uint32_t ith, Descriptor( nTECSInfo_sRegionInfo )* des );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sRegionInfo ) cRegionInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sRegionInfo ) cRegionInfo_ref_desc()      (same as above; abbreviated version);
+ * call port: cNamespaceInfoTemp signature: nTECSInfo_sNamespaceInfo context:task optional:true
+ *   bool_t     is_cNamespaceInfoTemp_joined()                     check if joined
+ *   ER             cNamespaceInfoTemp_getName( char_t* name, int_t max_len );
+ *   uint16_t       cNamespaceInfoTemp_getNameLength( );
+ *   uint32_t       cNamespaceInfoTemp_getNNamespace( );
+ *   ER             cNamespaceInfoTemp_getNamespaceInfo( uint32_t ith, Descriptor( nTECSInfo_sNamespaceInfo )* des );
+ *   uint32_t       cNamespaceInfoTemp_getNSignature( );
+ *   ER             cNamespaceInfoTemp_getSignatureInfo( uint32_t ith, Descriptor( nTECSInfo_sSignatureInfo )* des );
+ *   uint32_t       cNamespaceInfoTemp_getNCelltype( );
+ *   ER             cNamespaceInfoTemp_getCelltypeInfo( uint32_t ith, Descriptor( nTECSInfo_sCelltypeInfo )* des );
+ *   [dynamic, optional]
+ *      void           cNamespaceInfoTemp_set_descriptor( Descriptor( nTECSInfo_sNamespaceInfo ) desc );
+ *      void           cNamespaceInfoTemp_unjoin(  );
+ * call port: cRegionInfoTemp signature: nTECSInfo_sRegionInfo context:task optional:true
+ *   bool_t     is_cRegionInfoTemp_joined()                     check if joined
+ *   ER             cRegionInfoTemp_getName( char_t* name, int_t max_len );
+ *   uint16_t       cRegionInfoTemp_getNameLength( );
+ *   uint32_t       cRegionInfoTemp_getNCell( );
+ *   ER             cRegionInfoTemp_getCellInfo( uint32_t ith, Descriptor( nTECSInfo_sCellInfo )* des );
+ *   uint32_t       cRegionInfoTemp_getNRegion( );
+ *   ER             cRegionInfoTemp_getRegionInfo( uint32_t ith, Descriptor( nTECSInfo_sRegionInfo )* des );
+ *   [dynamic, optional]
+ *      void           cRegionInfoTemp_set_descriptor( Descriptor( nTECSInfo_sRegionInfo ) desc );
+ *      void           cRegionInfoTemp_unjoin(  );
+ * call port: cCelltypeInfoTemp signature: nTECSInfo_sCelltypeInfo context:task optional:true
+ *   bool_t     is_cCelltypeInfoTemp_joined()                     check if joined
+ *   ER             cCelltypeInfoTemp_getName( char_t* name, int_t max_len );
+ *   uint16_t       cCelltypeInfoTemp_getNameLength( );
+ *   uint32_t       cCelltypeInfoTemp_getNAttr( );
+ *   ER             cCelltypeInfoTemp_getAttrInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   uint32_t       cCelltypeInfoTemp_getNVar( );
+ *   ER             cCelltypeInfoTemp_getVarInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   uint32_t       cCelltypeInfoTemp_getNCall( );
+ *   ER             cCelltypeInfoTemp_getCallInfo( uint32_t ith, Descriptor( nTECSInfo_sCallInfo )* desc );
+ *   uint32_t       cCelltypeInfoTemp_getNEntry( );
+ *   ER             cCelltypeInfoTemp_getEntryInfo( uint32_t ith, Descriptor( nTECSInfo_sEntryInfo )* desc );
+ *   bool_t         cCelltypeInfoTemp_isSingleton( );
+ *   bool_t         cCelltypeInfoTemp_isIDX_is_ID( );
+ *   uint32_t       cCelltypeInfoTemp_sizeOfCB( );
+ *   uint32_t       cCelltypeInfoTemp_sizeOfINIB( );
+ *   [dynamic, optional]
+ *      void           cCelltypeInfoTemp_set_descriptor( Descriptor( nTECSInfo_sCelltypeInfo ) desc );
+ *      void           cCelltypeInfoTemp_unjoin(  );
+ * call port: cCellInfoTemp signature: nTECSInfo_sCellInfo context:task optional:true
+ *   bool_t     is_cCellInfoTemp_joined()                     check if joined
+ *   ER             cCellInfoTemp_getName( char_t* name, int_t max_len );
+ *   uint16_t       cCellInfoTemp_getNameLength( );
+ *   uint32_t       cCellInfoTemp_getNRawEntryDescriptorInfo( );
+ *   ER             cCellInfoTemp_getRawEntryDescriptorInfo( int_t index, Descriptor( nTECSInfo_sRawEntryDescriptorInfo )* desc );
+ *   void           cCellInfoTemp_getCelltypeInfo( Descriptor( nTECSInfo_sCelltypeInfo )* desc );
+ *   void           cCellInfoTemp_getCBP( void** cbp );
+ *   void           cCellInfoTemp_getINIBP( void** inibp );
+ *   [dynamic, optional]
+ *      void           cCellInfoTemp_set_descriptor( Descriptor( nTECSInfo_sCellInfo ) desc );
+ *      void           cCellInfoTemp_unjoin(  );
+ * call port: cEntryInfoTemp signature: nTECSInfo_sEntryInfo context:task optional:true
+ *   bool_t     is_cEntryInfoTemp_joined()                     check if joined
+ *   ER             cEntryInfoTemp_getName( char_t* name, int_t max_len );
+ *   uint16_t       cEntryInfoTemp_getNameLength( );
+ *   void           cEntryInfoTemp_getSignatureInfo( Descriptor( nTECSInfo_sSignatureInfo )* desc );
+ *   uint32_t       cEntryInfoTemp_getArraySize( );
+ *   bool_t         cEntryInfoTemp_isInline( );
+ *   [dynamic, optional]
+ *      void           cEntryInfoTemp_set_descriptor( Descriptor( nTECSInfo_sEntryInfo ) desc );
+ *      void           cEntryInfoTemp_unjoin(  );
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tTECSInfoSub_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+static ER
+separate_basename( const char_t **namespace_path, char_t **basename );
+
+
+/*
+ * VAR_name1 … 引数として渡されたものをコピーする。ただし、途中の '::' を '\0' に書き換えることはある。
+ * VAR_name2 … 都度上書きして使用する
+ */
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTECSInfo
+ * entry port: eTECSInfo
+ * signature:  nTECSInfo_sTECSInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findNamespace
+ * name:         eTECSInfo_findNamespace
+ * global_name:  nTECSInfo_tTECSInfoSub_eTECSInfo_findNamespace
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTECSInfo_findNamespace(const char_t* namespace_path, Descriptor( nTECSInfo_sNamespaceInfo )* nsDesc)
+{
+    const char_t  *p = namespace_path;
+    char_t  *p2;
+    Descriptor( nTECSInfo_sNamespaceInfo ) desc, desc2;
+    int     i;
+    int     n;
+
+    if( p[ 0 ] == ':' && p[ 1 ] == ':' ){
+        p += 2;
+    }
+    desc = cNamespaceInfo_refer_to_descriptor(); // root name space
+    while( *p != '\0' ){
+        p2 = VAR_name1;
+        for( i = 0; i < ATTR_name_len; i++ ){
+            if( *p == '\0' ||  *p == ':' ){
+                *p2 = '\0';
+                break;
+            }
+            *p2++ = *p++;
+        }
+        if( i == ATTR_name_len )
+            return E_NORES;
+
+        desc2 = desc;
+        cNamespaceInfoTemp_set_descriptor( desc2 );
+        n = cNamespaceInfoTemp_getNNamespace( );
+        for( i = 0; i < n; i++ ){
+            cNamespaceInfoTemp_set_descriptor( desc2 );
+            cNamespaceInfoTemp_getNamespaceInfo( i, &desc );
+            cNamespaceInfoTemp_set_descriptor( desc );
+            cNamespaceInfoTemp_getName( VAR_name2, ATTR_name_len );
+            if( strcmp( VAR_name1, VAR_name2 ) == 0 )
+                break;
+        }
+        if( i == n )
+            return E_NOID;
+
+        if( p[ 0 ] == ':' ){
+            if( p[ 1 ] == ':' )
+                p += 2;
+            else
+                return E_OBJ;
+        }
+    }
+    *nsDesc = desc;
+    return E_OK;
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findRegion
+ * name:         eTECSInfo_findRegion
+ * global_name:  nTECSInfo_tTECSInfoSub_eTECSInfo_findRegion
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTECSInfo_findRegion(const char_t* namespace_path, Descriptor( nTECSInfo_sRegionInfo )* regionDesc)
+{
+    const char_t  *p = namespace_path;
+    char_t  *p2;
+    Descriptor( nTECSInfo_sRegionInfo ) desc, desc2;
+    int     i;
+    int     n;
+
+    if( p[ 0 ] == ':' && p[ 1 ] == ':' ){
+        p += 2;
+    }
+    desc = cRegionInfo_refer_to_descriptor();
+    while( *p != '\0' ){
+        p2 = VAR_name1;
+        for( i = 0; i < ATTR_name_len; i++ ){
+            if( *p == '\0' ||  *p == ':' ){
+                *p2 = '\0';
+                break;
+            }
+            *p2++ = *p++;
+        }
+        if( i == ATTR_name_len )
+            return E_NORES;
+
+        desc2 = desc;
+        cRegionInfoTemp_set_descriptor( desc2 );
+        n = cRegionInfoTemp_getNRegion( );
+        for( i = 0; i < n; i++ ){
+            // syslog_3( LOG_NOTICE, "tTECSInfo.eTECSInfo.findRegion 2 %s i=%d n=%d", VAR_name1, i, n );
+            cRegionInfoTemp_set_descriptor( desc2 );
+            cRegionInfoTemp_getRegionInfo( i, &desc );
+            cRegionInfoTemp_set_descriptor( desc );
+            cRegionInfoTemp_getName( VAR_name2, ATTR_name_len );
+            if( strcmp( VAR_name1, VAR_name2 ) == 0 )
+                break;
+        }
+        if( i == n )
+            return E_NOID;
+
+        if( p[ 0 ] == ':' ){
+            if( p[ 1 ] == ':' )
+                p += 2;
+            else
+                return E_OBJ;
+        }
+    }
+    *regionDesc = desc;
+    return E_OK;
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findSignature
+ * name:         eTECSInfo_findSignature
+ * global_name:  nTECSInfo_tTECSInfoSub_eTECSInfo_findSignature
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTECSInfo_findSignature(const char_t* namespace_path, Descriptor( nTECSInfo_sSignatureInfo )* signatureDesc)
+{
+    Descriptor( nTECSInfo_sNamespaceInfo ) nsDesc;
+    Descriptor( nTECSInfo_sSignatureInfo ) desc;
+    ER        ercd;
+    char_t    *pname;
+    int       i, n;
+
+    ercd = separate_basename( &namespace_path, &pname );
+    if( ercd != E_OK )
+        return ercd;
+
+    ercd = eTECSInfo_findNamespace( namespace_path, &nsDesc);
+    if( ercd != E_OK )
+        return ercd;
+
+    // syslog_0( LOG_NOTICE, "tTECSInfo.eTECSInfo.findCell 4" );
+    cNamespaceInfoTemp_set_descriptor( nsDesc );
+    n = cNamespaceInfoTemp_getNSignature( );
+    for( i = 0; i < n; i++ ){
+        cNamespaceInfoTemp_getSignatureInfo( i, &desc );
+        cSignatureInfoTemp_set_descriptor( desc );
+        cSignatureInfoTemp_getName( VAR_name1, ATTR_name_len );
+        if( strcmp( pname, VAR_name1 ) == 0 )
+            break;
+    }
+    // syslog_0( LOG_NOTICE, "tTECSInfo.eTECSInfo.findCell 5" );
+    if( i == n )
+        return E_NOEXS;
+
+    *signatureDesc = desc;
+    return E_OK;
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findCelltype
+ * name:         eTECSInfo_findCelltype
+ * global_name:  nTECSInfo_tTECSInfoSub_eTECSInfo_findCelltype
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTECSInfo_findCelltype(const char_t* namespace_path, Descriptor( nTECSInfo_sCelltypeInfo )* celltypeDesc)
+{
+  return E_NOSPT;
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findCell
+ * name:         eTECSInfo_findCell
+ * global_name:  nTECSInfo_tTECSInfoSub_eTECSInfo_findCell
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTECSInfo_findCell(const char_t* namespace_path, Descriptor( nTECSInfo_sCellInfo )* cellDesc)
+{
+    char_t  *p, *pname;
+    Descriptor( nTECSInfo_sRegionInfo ) RegionDesc;
+    Descriptor( nTECSInfo_sCellInfo )   desc;
+    int     i, n, len;
+    ER      ercd;
+
+#if 0
+    // syslog_0( LOG_NOTICE, "tTECSInfo.eTECSInfo.findCell 1" );
+    len = strnlen( namespace_path, ATTR_path_len );
+    if( len >= ATTR_path_len ){
+        return E_NOMEM;
+    }
+    if( VAR_path != namespace_path )     // findRawEntryDescriptorInfo から呼ばれた時、VAR_path に入っているのでコピー不要
+        strcpy( VAR_path, namespace_path );
+    p = &VAR_path[ len - 1 ];
+    while( p > VAR_path ){
+        if( *p == ':' )
+            break;
+        p--;
+    }
+    if( *p == ':' ){
+        p--;
+        if( p < VAR_path || *p != ':' )
+            return E_PAR;    // :: ではなく、: であった
+        if( p == VAR_path ){
+            namespace_path = "::";
+        }
+        else{
+            *p = '\0';
+            namespace_path = VAR_path;
+        }
+        pname = &p[2];
+    }
+    else{
+        namespace_path = "::";
+        pname = VAR_path;
+    }
+#endif
+    ercd = separate_basename( &namespace_path, &pname );
+    if( ercd != E_OK )
+        return ercd;
+
+    // syslog_2( LOG_NOTICE, "tTECSInfo.eTECSInfo.findCell 2 %s %s", namespace_path, pname );
+    
+    // syslog_0( LOG_NOTICE, "tTECSInfo.eTECSInfo.findCell 3" );
+    ercd = eTECSInfo_findRegion( namespace_path, &RegionDesc);
+    if( ercd != E_OK )
+        return ercd;
+
+    // syslog_0( LOG_NOTICE, "tTECSInfo.eTECSInfo.findCell 4" );
+    cRegionInfoTemp_set_descriptor( RegionDesc );
+    n = cRegionInfoTemp_getNCell( );
+    for( i = 0; i < n; i++ ){
+        cRegionInfoTemp_getCellInfo( i, &desc );
+        cCellInfoTemp_set_descriptor( desc );
+        cCellInfoTemp_getName( VAR_name1, ATTR_name_len );
+        if( strcmp( pname, VAR_name1 ) == 0 )
+            break;
+    }
+    // syslog_0( LOG_NOTICE, "tTECSInfo.eTECSInfo.findCell 5" );
+    if( i == n )
+        return E_NOEXS;
+
+    *cellDesc = desc;
+    return E_OK;
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findRawEntryDescriptor
+ * name:         eTECSInfo_findRawEntryDescriptor
+ * global_name:  nTECSInfo_tTECSInfoSub_eTECSInfo_findRawEntryDescriptor
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTECSInfo_findRawEntryDescriptor(const char_t* namespace_path, int_t ith, Descriptor( nTECSInfo_sRawEntryDescriptorInfo )* rawEntryDescDesc, Descriptor( nTECSInfo_sEntryInfo )* entryDesc)
+{
+    int_t  len;
+    Descriptor( nTECSInfo_sCelltypeInfo )  celltypeDesc;
+    Descriptor( nTECSInfo_sCellInfo )      cellDesc;
+    Descriptor( nTECSInfo_sEntryInfo )     entDesc;
+    char_t *p;
+    int_t  i, n;
+    ER     ercd;
+
+    len = strnlen( namespace_path, ATTR_path_len );
+    if( len >= ATTR_path_len ){
+        return E_NOMEM;
+    }
+    strcpy( VAR_path, namespace_path );
+    p = &VAR_path[len-1];
+    while( *p != '.' && p != &VAR_path[0] )
+        p--;
+    if( *p != '.' )
+        return E_PAR;    // '.' が見つからない
+    *p = '\0';
+    ercd = eTECSInfo_findCell( VAR_path, &cellDesc);
+    if( ercd != E_OK )
+        return ercd;
+    cCellInfoTemp_set_descriptor( cellDesc );
+    cCellInfoTemp_getCelltypeInfo( &celltypeDesc  );
+    cCelltypeInfoTemp_set_descriptor( celltypeDesc );
+    n = cCelltypeInfoTemp_getNEntry();
+    p += 1;
+    //syslog_1( LOG_NOTICE, "tTECSInfo.eTECSInfo.findRawEntryDescriptor 4 n_entry=%d", n );
+    // dly_tsk( 10000 );
+    for( i = 0; i < n; i++ ){
+        ercd = cCelltypeInfoTemp_getEntryInfo( i, &entDesc ); // エラーはみない
+        //syslog_2( LOG_NOTICE, "tTECSInfo.eTECSInfo.findRawEntryDescriptor 5 ercd=%d entDesc=%x", ercd, entDesc.vdes );
+        cEntryInfoTemp_set_descriptor( entDesc );
+        ercd = cEntryInfoTemp_getName( VAR_name1, ATTR_name_len );
+        //dly_tsk( 5 );
+        //syslog_4( LOG_NOTICE, "tTECSInfo.eTECSInfo.findRawEntryDescriptor 6 ercd=%d entDesc=%x nm=%s p=%s", ercd, entDesc.vdes, VAR_name1, p );
+        //dly_tsk( 5 );
+        if( ercd != E_OK )
+            return ercd;
+        if( strcmp( VAR_name1, p ) == 0 )
+            break;
+    }
+    if( i != n ){
+        cCellInfoTemp_getRawEntryDescriptorInfo( ith, rawEntryDescDesc );
+        *entryDesc = entDesc;
+    }
+    else{
+        ercd = E_NOEXS;
+    }
+    return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findRawEntryDescriptor_unsafe
+ * name:         eTECSInfo_findRawEntryDescriptor_unsafe
+ * global_name:  nTECSInfo_tTECSInfoSub_eTECSInfo_findRawEntryDescriptor_unsafe
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTECSInfo_findRawEntryDescriptor_unsafe(const char_t* namespace_path, void** rawDesc)
+{
+    ER   ercd;
+    Descriptor( nTECSInfo_sRawEntryDescriptorInfo ) rawEntryDescDesc;
+    Descriptor( nTECSInfo_sEntryInfo ) entryDesc;
+    ercd = eTECSInfo_findRawEntryDescriptor(namespace_path, 0, &rawEntryDescDesc, &entryDesc);
+    if( ercd != E_OK )
+        return ercd;
+    cRawEntryDescriptorInfoTemp_set_descriptor( rawEntryDescDesc );
+    ercd = cRawEntryDescriptorInfoTemp_getRawDescriptor( 0, rawDesc );
+    return ercd;
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
+
+/*
+ * namespace_path を VAR_path へコピーし、ディレクトリパス部とオブジェクト名部に分割する
+ * namespace_path  "::namespace::subnamespace::object_name"
+ * VAR_path        "::namespace::subnamespace\0:object_name"   一番右の '::' を '\0:' に置き換える
+ * basename        "object_name" へのポインタを返す
+ */
+static ER
+separate_basename( const char_t **namespace_path, char_t **basename )
+{
+    int     i, len;
+    char_t  *p;
+    static const char_t *root_namespacepath = "::";
+
+    len = strnlen( *namespace_path, ATTR_path_len );
+    if( len >= ATTR_path_len ){
+        return E_NOMEM;
+    }
+    if( VAR_path != *namespace_path )     // findRawEntryDescriptorInfo から呼ばれた時、VAR_path に入っているのでコピー不要
+        strcpy( VAR_path, *namespace_path );
+    p = &VAR_path[ len - 1 ];
+    while( p > VAR_path ){
+        if( *p == ':' )
+            break;
+        p--;
+    }
+    if( *p == ':' ){
+        p--;
+        if( p < VAR_path || *p != ':' )
+            return E_PAR;    // :: ではなく、: であった
+        if( p == VAR_path ){
+            *namespace_path = root_namespacepath;
+        }
+        else{
+            *p = '\0';
+            *namespace_path = VAR_path;
+        }
+        *basename = &p[2];
+    }
+    else{
+        *namespace_path = root_namespacepath;
+        *basename = VAR_path;
+    }
+    return  E_OK;
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTECSInfo_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTECSInfo_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTECSInfo_inline.h	(revision 398)
@@ -0,0 +1,149 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef nTECSInfo_tTECSInfo__INLINE_H
+#define nTECSInfo_tTECSInfo__INLINE_H
+
+/*
+ * This file was automatically generated by tecsgen.
+ * Move and rename like below before editing,
+ *   gen/tTECSInfo_inline_template.h => src/tTECSInfo_inline.h
+ * to avoid to be overwritten by tecsgen.
+ */
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cTECSInfo signature: nTECSInfo_sTECSInfo context:task
+ *   ER             cTECSInfo_findNamespace( const char_t* namespace_path, Descriptor( nTECSInfo_sNamespaceInfo )* nsDesc );
+ *   ER             cTECSInfo_findRegion( const char_t* namespace_path, Descriptor( nTECSInfo_sRegionInfo )* regionDesc );
+ *   ER             cTECSInfo_findSignature( const char_t* namespace_path, Descriptor( nTECSInfo_sSignatureInfo )* signatureDesc );
+ *   ER             cTECSInfo_findCelltype( const char_t* namespace_path, Descriptor( nTECSInfo_sCelltypeInfo )* celltypeDesc );
+ *   ER             cTECSInfo_findCell( const char_t* namespace_path, Descriptor( nTECSInfo_sCellInfo )* cellDesc );
+ *   ER             cTECSInfo_findRawEntryDescriptor( const char_t* namespace_path, Descriptor( nTECSInfo_sRawEntryDescriptorInfo )* rawEntryDescDesc, Descriptor( nTECSInfo_sEntryInfo )* entryDesc );
+ *   ER             cTECSInfo_findRawEntryDescriptor_unsafe( const char_t* namespace_path, void** rawDesc );
+ *
+ * #[</PREAMBLE>]# */
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTECSInfo
+ * entry port: eTECSInfo
+ * signature:  nTECSInfo_sTECSInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findNamespace
+ * name:         eTECSInfo_findNamespace
+ * global_name:  nTECSInfo_tTECSInfo_eTECSInfo_findNamespace
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTECSInfo_findNamespace(const char_t* namespace_path, Descriptor( nTECSInfo_sNamespaceInfo )* nsDesc)
+{
+    return cTECSInfo_findNamespace( namespace_path, nsDesc );
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findRegion
+ * name:         eTECSInfo_findRegion
+ * global_name:  nTECSInfo_tTECSInfo_eTECSInfo_findRegion
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTECSInfo_findRegion(const char_t* namespace_path, Descriptor( nTECSInfo_sRegionInfo )* regionDesc)
+{
+    return cTECSInfo_findRegion( namespace_path, regionDesc );
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findSignature
+ * name:         eTECSInfo_findSignature
+ * global_name:  nTECSInfo_tTECSInfo_eTECSInfo_findSignature
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTECSInfo_findSignature(const char_t* namespace_path, Descriptor( nTECSInfo_sSignatureInfo )* signatureDesc)
+{
+    return cTECSInfo_findSignature( namespace_path, signatureDesc );
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findCelltype
+ * name:         eTECSInfo_findCelltype
+ * global_name:  nTECSInfo_tTECSInfo_eTECSInfo_findCelltype
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTECSInfo_findCelltype(const char_t* namespace_path, Descriptor( nTECSInfo_sCelltypeInfo )* celltypeDesc)
+{
+  return cTECSInfo_findCelltype( namespace_path, celltypeDesc );
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findCell
+ * name:         eTECSInfo_findCell
+ * global_name:  nTECSInfo_tTECSInfo_eTECSInfo_findCell
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTECSInfo_findCell(const char_t* namespace_path, Descriptor( nTECSInfo_sCellInfo )* cellDesc)
+{
+  return cTECSInfo_findCell( namespace_path, cellDesc );
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findRawEntryDescriptor
+ * name:         eTECSInfo_findRawEntryDescriptor
+ * global_name:  nTECSInfo_tTECSInfo_eTECSInfo_findRawEntryDescriptor
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTECSInfo_findRawEntryDescriptor(const char_t* namespace_path, int_t ith, Descriptor( nTECSInfo_sRawEntryDescriptorInfo )* rawEntryDescDesc, Descriptor( nTECSInfo_sEntryInfo )* entryDesc)
+{
+    return cTECSInfo_findRawEntryDescriptor(namespace_path, ith, rawEntryDescDesc, entryDesc);
+}
+
+/* #[<ENTRY_FUNC>]# eTECSInfo_findRawEntryDescriptor_unsafe
+ * name:         eTECSInfo_findRawEntryDescriptor_unsafe
+ * global_name:  nTECSInfo_tTECSInfo_eTECSInfo_findRawEntryDescriptor_unsafe
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTECSInfo_findRawEntryDescriptor_unsafe(const char_t* namespace_path, void** rawDesc)
+{
+    return cTECSInfo_findRawEntryDescriptor_unsafe(namespace_path, rawDesc);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
+
+#endif /* nTECSInfo_tTECSInfo_INLINEH */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tTypeInfo.c	(revision 398)
@@ -0,0 +1,202 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * typeKind         int8_t           ATTR_typeKind   
+ * bitSize          int32_t          ATTR_bitSize    
+ * b_const          bool_t           ATTR_b_const    
+ * b_volatile       bool_t           ATTR_b_volatile 
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cTypeInfo signature: nTECSInfo_sTypeInfo context:task optional:true
+ *   bool_t     is_cTypeInfo_joined()                     check if joined
+ *   ER             cTypeInfo_getName( char_t* name, int_t max_len );
+ *   void           cTypeInfo_getNameLength( uint16_t* len );
+ *   void           cTypeInfo_getSize( uint32_t* size );
+ *   void           cTypeInfo_getKind( int8_t* kind );
+ *   void           cTypeInfo_getNType( int32_t* num );
+ *   void           cTypeInfo_getTypeInfo( int32_t ith, Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_ref_desc()      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tTypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTypeInfo
+ * entry port: eTypeInfo
+ * signature:  nTECSInfo_sTypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getName
+ * name:         eTypeInfo_getName
+ * global_name:  nTECSInfo_tTypeInfo_eTypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNameLength
+ * name:         eTypeInfo_getNameLength
+ * global_name:  nTECSInfo_tTypeInfo_eTypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eTypeInfo_getNameLength(CELLIDX idx, uint16_t* len)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getSize
+ * name:         eTypeInfo_getSize
+ * global_name:  nTECSInfo_tTypeInfo_eTypeInfo_getSize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eTypeInfo_getSize(CELLIDX idx, uint32_t* size)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getKind
+ * name:         eTypeInfo_getKind
+ * global_name:  nTECSInfo_tTypeInfo_eTypeInfo_getKind
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eTypeInfo_getKind(CELLIDX idx, int8_t* kind)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNType
+ * name:         eTypeInfo_getNType
+ * global_name:  nTECSInfo_tTypeInfo_eTypeInfo_getNType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eTypeInfo_getNType(CELLIDX idx, int32_t* num)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getTypeInfo
+ * name:         eTypeInfo_getTypeInfo
+ * global_name:  nTECSInfo_tTypeInfo_eTypeInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eTypeInfo_getTypeInfo(CELLIDX idx, int32_t ith, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tVarDeclInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tVarDeclInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tVarDeclInfo.c	(revision 398)
@@ -0,0 +1,213 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * sizeIsExpr       char_t*          ATTR_sizeIsExpr 
+ * declType         int8_t           ATTR_declType   
+ * place            int8_t           ATTR_place      
+ * offset           uint32_t         ATTR_offset     
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cTypeInfo signature: nTECSInfo_sTypeInfo context:task
+ *   ER             cTypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cTypeInfo_getNameLength( );
+ *   uint32_t       cTypeInfo_getSize( );
+ *   int8_t         cTypeInfo_getKind( );
+ *   uint32_t       cTypeInfo_getNType( );
+ *   ER             cTypeInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   uint32_t       cTypeInfo_getNMember( );
+ *   ER             cTypeInfo_getMemberInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   [ref_desc]
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_refer_to_descriptor();
+ *      Descriptor( nTECSInfo_sTypeInfo ) cTypeInfo_ref_desc()      (same as above; abbreviated version);
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tVarDeclInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eVarDeclInfo
+ * entry port: eVarDeclInfo
+ * signature:  nTECSInfo_sVarDeclInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eVarDeclInfo_getName
+ * name:         eVarDeclInfo_getName
+ * global_name:  nTECSInfo_tVarDeclInfo_eVarDeclInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eVarDeclInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eVarDeclInfo_getNameLength
+ * name:         eVarDeclInfo_getNameLength
+ * global_name:  nTECSInfo_tVarDeclInfo_eVarDeclInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eVarDeclInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eVarDeclInfo_getLocationInfo
+ * name:         eVarDeclInfo_getLocationInfo
+ * global_name:  nTECSInfo_tVarDeclInfo_eVarDeclInfo_getLocationInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eVarDeclInfo_getLocationInfo(CELLIDX idx, uint32_t* offset, int8_t* place)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  *offset = ATTR_offset;
+  *place  = ATTR_place;
+}
+
+/* #[<ENTRY_FUNC>]# eVarDeclInfo_getTypeInfo
+ * name:         eVarDeclInfo_getTypeInfo
+ * global_name:  nTECSInfo_tVarDeclInfo_eVarDeclInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eVarDeclInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  *desc = cTypeInfo_refer_to_descriptor();
+}
+
+/* #[<ENTRY_FUNC>]# eVarDeclInfo_getSizeIsExpr
+ * name:         eVarDeclInfo_getSizeIsExpr
+ * global_name:  nTECSInfo_tVarDeclInfo_eVarDeclInfo_getSizeIsExpr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eVarDeclInfo_getSizeIsExpr(CELLIDX idx, char_t* expr_str, int32_t max_len)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  strncpy( expr_str, ATTR_sizeIsExpr, max_len - 1 );
+  expr_str[ max_len - 1 ] = '\0';
+}
+
+/* #[<ENTRY_FUNC>]# eVarDeclInfo_getSizeIs
+ * name:         eVarDeclInfo_getSizeIs
+ * global_name:  nTECSInfo_tVarDeclInfo_eVarDeclInfo_getSizeIs
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eVarDeclInfo_getSizeIs(CELLIDX idx, uint32_t* size, const void* p_cb)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  ercd = E_NOSPT;
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tVoidTypeInfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tVoidTypeInfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/nTECSInfo_tVoidTypeInfo.c	(revision 398)
@@ -0,0 +1,237 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * name             char_t*          ATTR_name       
+ * typeKind         int8_t           ATTR_typeKind   
+ * size             uint32_t         ATTR_size       
+ * b_const          bool_t           ATTR_b_const    
+ * b_volatile       bool_t           ATTR_b_volatile 
+ *
+ * #[</PREAMBLE>]# */
+
+/* Put prototype declaration and/or variale definition here #_PAC_# */
+#include <string.h>
+#include "nTECSInfo_tVoidTypeInfo_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* entry port function #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTypeInfo
+ * entry port: eTypeInfo
+ * signature:  nTECSInfo_sTypeInfo
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getName
+ * name:         eTypeInfo_getName
+ * global_name:  nTECSInfo_tVoidTypeInfo_eTypeInfo_getName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getName(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	name[ max_len - 1 ] = '\0';
+	strncpy( name, ATTR_name, max_len );
+  if( name[ max_len - 1 ] ){
+      name[ max_len - 1 ] = '\0';
+      ercd = E_NOMEM;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNameLength
+ * name:         eTypeInfo_getNameLength
+ * global_name:  nTECSInfo_tVoidTypeInfo_eTypeInfo_getNameLength
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint16_t
+eTypeInfo_getNameLength(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	return strlen( ATTR_name ) + 1;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getSize
+ * name:         eTypeInfo_getSize
+ * global_name:  nTECSInfo_tVoidTypeInfo_eTypeInfo_getSize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getSize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return ATTR_size;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getKind
+ * name:         eTypeInfo_getKind
+ * global_name:  nTECSInfo_tVoidTypeInfo_eTypeInfo_getKind
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+int8_t
+eTypeInfo_getKind(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return ATTR_typeKind;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNType
+ * name:         eTypeInfo_getNType
+ * global_name:  nTECSInfo_tVoidTypeInfo_eTypeInfo_getNType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNType(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return 0;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getTypeInfo
+ * name:         eTypeInfo_getTypeInfo
+ * global_name:  nTECSInfo_tVoidTypeInfo_eTypeInfo_getTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getTypeInfo(CELLIDX idx, Descriptor( nTECSInfo_sTypeInfo )* desc)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* Write error processing code here */
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+  return E_NOEXS;
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getNMember
+ * name:         eTypeInfo_getNMember
+ * global_name:  nTECSInfo_tVoidTypeInfo_eTypeInfo_getNMember
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+uint32_t
+eTypeInfo_getNMember(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+}
+
+/* #[<ENTRY_FUNC>]# eTypeInfo_getMemberInfo
+ * name:         eTypeInfo_getMemberInfo
+ * global_name:  nTECSInfo_tVoidTypeInfo_eTypeInfo_getMemberInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eTypeInfo_getMemberInfo(CELLIDX idx, uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/tTECSInfoAccessor.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/tTECSInfoAccessor.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TECSInfo/tTECSInfoAccessor.c	(revision 398)
@@ -0,0 +1,1613 @@
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * NAME_LEN         int16_t          ATTR_NAME_LEN   
+ * name             char_t*          VAR_name        
+ * name2            char_t*          VAR_name2       
+ * selectedCbp      int8_t*          VAR_selectedCbp 
+ * selectedInibp    int8_t*          VAR_selectedInibp
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cTECSInfo signature: nTECSInfo_sTECSInfo context:task
+ *   ER             cTECSInfo_findNamespace( const char_t* namespace_path, Descriptor( nTECSInfo_sNamespaceInfo )* NSdesc );
+ *   ER             cTECSInfo_findRegion( const char_t* namespace_path, Descriptor( nTECSInfo_sRegionInfo )* RGNdesc );
+ *   ER             cTECSInfo_findSignature( const char_t* namespace_path, Descriptor( nTECSInfo_sSignatureInfo )* SIGdesc );
+ *   ER             cTECSInfo_findCelltype( const char_t* namespace_path, Descriptor( nTECSInfo_sCelltypeInfo )* CTdesc );
+ *   ER             cTECSInfo_findCell( const char_t* namespace_path, Descriptor( nTECSInfo_sCellInfo )* CELLdesc );
+ * call port: cNSInfo signature: nTECSInfo_sNamespaceInfo context:task optional:true
+ *   bool_t     is_cNSInfo_joined()                     check if joined
+ *   ER             cNSInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cNSInfo_getNameLength( );
+ *   uint32_t       cNSInfo_getNNamespace( );
+ *   ER             cNSInfo_getNamespaceInfo( uint32_t ith, Descriptor( nTECSInfo_sNamespaceInfo )* des );
+ *   uint32_t       cNSInfo_getNSignature( );
+ *   ER             cNSInfo_getSignatureInfo( uint32_t ith, Descriptor( nTECSInfo_sSignatureInfo )* des );
+ *   uint32_t       cNSInfo_getNCelltype( );
+ *   ER             cNSInfo_getCelltypeInfo( uint32_t ith, Descriptor( nTECSInfo_sCelltypeInfo )* des );
+ *   [dynamic, optional]
+ *      void           cNSInfo_set_descriptor( Descriptor( nTECSInfo_sNamespaceInfo ) desc );
+ *      void           cNSInfo_unjoin(  );
+ * call port: cCelltypeInfo signature: nTECSInfo_sCelltypeInfo context:task optional:true
+ *   bool_t     is_cCelltypeInfo_joined()                     check if joined
+ *   ER             cCelltypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cCelltypeInfo_getNameLength( );
+ *   uint32_t       cCelltypeInfo_getNAttr( );
+ *   ER             cCelltypeInfo_getAttrInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNVar( );
+ *   ER             cCelltypeInfo_getVarInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNCall( );
+ *   ER             cCelltypeInfo_getCallInfo( uint32_t ith, Descriptor( nTECSInfo_sCallInfo )* desc );
+ *   uint32_t       cCelltypeInfo_getNEntry( );
+ *   ER             cCelltypeInfo_getEntryInfo( uint32_t ith, Descriptor( nTECSInfo_sEntryInfo )* desc );
+ *   bool_t         cCelltypeInfo_isSingleton( );
+ *   bool_t         cCelltypeInfo_isIDX_is_ID( );
+ *   uint32_t       cCelltypeInfo_sizeOfCB( );
+ *   uint32_t       cCelltypeInfo_sizeOfINIB( );
+ *   [dynamic, optional]
+ *      void           cCelltypeInfo_set_descriptor( Descriptor( nTECSInfo_sCelltypeInfo ) desc );
+ *      void           cCelltypeInfo_unjoin(  );
+ * call port: cSignatureInfo signature: nTECSInfo_sSignatureInfo context:task optional:true
+ *   bool_t     is_cSignatureInfo_joined()                     check if joined
+ *   ER             cSignatureInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cSignatureInfo_getNameLength( );
+ *   uint32_t       cSignatureInfo_getNFunction( );
+ *   ER             cSignatureInfo_getFunctionInfo( uint32_t ith, Descriptor( nTECSInfo_sFunctionInfo )* desc );
+ *   [dynamic, optional]
+ *      void           cSignatureInfo_set_descriptor( Descriptor( nTECSInfo_sSignatureInfo ) desc );
+ *      void           cSignatureInfo_unjoin(  );
+ * call port: cFunctionInfo signature: nTECSInfo_sFunctionInfo context:task optional:true
+ *   bool_t     is_cFunctionInfo_joined()                     check if joined
+ *   ER             cFunctionInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cFunctionInfo_getNameLength( );
+ *   void           cFunctionInfo_getReturnTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   uint32_t       cFunctionInfo_getNParam( );
+ *   ER             cFunctionInfo_getParamInfo( uint32_t ith, Descriptor( nTECSInfo_sParamInfo )* param );
+ *   [dynamic, optional]
+ *      void           cFunctionInfo_set_descriptor( Descriptor( nTECSInfo_sFunctionInfo ) desc );
+ *      void           cFunctionInfo_unjoin(  );
+ * call port: cParamInfo signature: nTECSInfo_sParamInfo context:task optional:true
+ *   bool_t     is_cParamInfo_joined()                     check if joined
+ *   ER             cParamInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cParamInfo_getNameLength( );
+ *   ER             cParamInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   ER             cParamInfo_getDir( int8_t* dir );
+ *   [dynamic, optional]
+ *      void           cParamInfo_set_descriptor( Descriptor( nTECSInfo_sParamInfo ) desc );
+ *      void           cParamInfo_unjoin(  );
+ * call port: cCallInfo signature: nTECSInfo_sCallInfo context:task optional:true
+ *   bool_t     is_cCallInfo_joined()                     check if joined
+ *   ER             cCallInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cCallInfo_getNameLength( );
+ *   void           cCallInfo_getSignatureInfo( Descriptor( nTECSInfo_sSignatureInfo )* desc );
+ *   uint32_t       cCallInfo_getArraySize( );
+ *   void           cCallInfo_getSpecifierInfo( bool_t* b_optional, bool_t* b_dynamic, bool_t* b_ref_desc, bool_t* b_omit );
+ *   void           cCallInfo_getInternalInfo( bool_t* b_allocator_port, bool_t* b_require_port );
+ *   void           cCallInfo_getLocationInfo( uint32_t* offset, int8_t* place );
+ *   void           cCallInfo_getOptimizeInfo( bool_t* b_VMT_useless, bool_t* b_skelton_useless, bool_t* b_cell_unique );
+ *   [dynamic, optional]
+ *      void           cCallInfo_set_descriptor( Descriptor( nTECSInfo_sCallInfo ) desc );
+ *      void           cCallInfo_unjoin(  );
+ * call port: cEntryInfo signature: nTECSInfo_sEntryInfo context:task optional:true
+ *   bool_t     is_cEntryInfo_joined()                     check if joined
+ *   ER             cEntryInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cEntryInfo_getNameLength( );
+ *   void           cEntryInfo_getSignatureInfo( Descriptor( nTECSInfo_sSignatureInfo )* desc );
+ *   uint32_t       cEntryInfo_getArraySize( );
+ *   bool_t         cEntryInfo_isInline( );
+ *   [dynamic, optional]
+ *      void           cEntryInfo_set_descriptor( Descriptor( nTECSInfo_sEntryInfo ) desc );
+ *      void           cEntryInfo_unjoin(  );
+ * call port: cAttrInfo signature: nTECSInfo_sVarDeclInfo context:task optional:true
+ *   bool_t     is_cAttrInfo_joined()                     check if joined
+ *   ER             cAttrInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cAttrInfo_getNameLength( );
+ *   void           cAttrInfo_getLocationInfo( uint32_t* offset, int8_t* place );
+ *   void           cAttrInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   void           cAttrInfo_getSizeIsExpr( char_t* expr_str, int32_t max_len );
+ *   ER             cAttrInfo_getSizeIs( uint32_t* size, const void* p_cb );
+ *   [dynamic, optional]
+ *      void           cAttrInfo_set_descriptor( Descriptor( nTECSInfo_sVarDeclInfo ) desc );
+ *      void           cAttrInfo_unjoin(  );
+ * call port: cVarInfo signature: nTECSInfo_sVarDeclInfo context:task optional:true
+ *   bool_t     is_cVarInfo_joined()                     check if joined
+ *   ER             cVarInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cVarInfo_getNameLength( );
+ *   void           cVarInfo_getLocationInfo( uint32_t* offset, int8_t* place );
+ *   void           cVarInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   void           cVarInfo_getSizeIsExpr( char_t* expr_str, int32_t max_len );
+ *   ER             cVarInfo_getSizeIs( uint32_t* size, const void* p_cb );
+ *   [dynamic, optional]
+ *      void           cVarInfo_set_descriptor( Descriptor( nTECSInfo_sVarDeclInfo ) desc );
+ *      void           cVarInfo_unjoin(  );
+ * call port: cTypeInfo signature: nTECSInfo_sTypeInfo context:task optional:true
+ *   bool_t     is_cTypeInfo_joined()                     check if joined
+ *   ER             cTypeInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cTypeInfo_getNameLength( );
+ *   uint32_t       cTypeInfo_getSize( );
+ *   int8_t         cTypeInfo_getKind( );
+ *   uint32_t       cTypeInfo_getNType( );
+ *   ER             cTypeInfo_getTypeInfo( Descriptor( nTECSInfo_sTypeInfo )* desc );
+ *   uint32_t       cTypeInfo_getNMember( );
+ *   ER             cTypeInfo_getMemberInfo( uint32_t ith, Descriptor( nTECSInfo_sVarDeclInfo )* desc );
+ *   [dynamic, optional]
+ *      void           cTypeInfo_set_descriptor( Descriptor( nTECSInfo_sTypeInfo ) desc );
+ *      void           cTypeInfo_unjoin(  );
+ * call port: cRegionInfo signature: nTECSInfo_sRegionInfo context:task optional:true
+ *   bool_t     is_cRegionInfo_joined()                     check if joined
+ *   ER             cRegionInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cRegionInfo_getNameLength( );
+ *   uint32_t       cRegionInfo_getNCell( );
+ *   ER             cRegionInfo_getCellInfo( uint32_t ith, Descriptor( nTECSInfo_sCellInfo )* des );
+ *   uint32_t       cRegionInfo_getNRegion( );
+ *   ER             cRegionInfo_getRegionInfo( uint32_t ith, Descriptor( nTECSInfo_sRegionInfo )* des );
+ *   [dynamic, optional]
+ *      void           cRegionInfo_set_descriptor( Descriptor( nTECSInfo_sRegionInfo ) desc );
+ *      void           cRegionInfo_unjoin(  );
+ * call port: cCellInfo signature: nTECSInfo_sCellInfo context:task optional:true
+ *   bool_t     is_cCellInfo_joined()                     check if joined
+ *   ER             cCellInfo_getName( char_t* name, int_t max_len );
+ *   uint16_t       cCellInfo_getNameLength( );
+ *   void           cCellInfo_getCelltypeInfo( Descriptor( nTECSInfo_sCelltypeInfo )* desc );
+ *   void           cCellInfo_getCBP( void** cbp );
+ *   void           cCellInfo_getINIBP( void** inibp );
+ *   [dynamic, optional]
+ *      void           cCellInfo_set_descriptor( Descriptor( nTECSInfo_sCellInfo ) desc );
+ *      void           cCellInfo_unjoin(  );
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "tTECSInfoAccessor_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+static void
+getSelectedTypeValue( CELLCB *p_cellcb, void *ptr, char_t *buf, int_t max_len );
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eSelector
+ * entry port: eSelector
+ * signature:  sAccessor
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eSelector_selectNamespaceInfoByName
+ * name:         eSelector_selectNamespaceInfoByName
+ * global_name:  tTECSInfoAccessor_eSelector_selectNamespaceInfoByName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectNamespaceInfoByName(CELLIDX idx, const char_t* namespacePath)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sNamespaceInfo ) NSdesc;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  ercd = cTECSInfo_findNamespace( namespacePath, &NSdesc );
+  if( ercd == E_OK ){
+      cNSInfo_set_descriptor( NSdesc );
+  }
+  else {
+      cNSInfo_unjoin(  );
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCelltypeInfoByName
+ * name:         eSelector_selectCelltypeInfoByName
+ * global_name:  tTECSInfoAccessor_eSelector_selectCelltypeInfoByName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCelltypeInfoByName(CELLIDX idx, const char_t* namespacePath)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sCelltypeInfo ) CTdesc;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  ercd = cTECSInfo_findCelltype( namespacePath, &CTdesc );
+  if( ercd == E_OK ){
+      cCelltypeInfo_set_descriptor( CTdesc );
+  }
+  else {
+      cCelltypeInfo_unjoin(  );
+  }
+  
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectSignatureInfoByName
+ * name:         eSelector_selectSignatureInfoByName
+ * global_name:  tTECSInfoAccessor_eSelector_selectSignatureInfoByName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectSignatureInfoByName(CELLIDX idx, const char_t* namespacePath)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sSignatureInfo ) SIGdesc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  ercd = cTECSInfo_findSignature( namespacePath, &SIGdesc );
+  if( ercd == E_OK ){
+      cSignatureInfo_set_descriptor( SIGdesc );
+  }
+  else {
+      cSignatureInfo_unjoin(  );
+  }
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectRegionInfoByName
+ * name:         eSelector_selectRegionInfoByName
+ * global_name:  tTECSInfoAccessor_eSelector_selectRegionInfoByName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectRegionInfoByName(CELLIDX idx, const char_t* regionPath)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sRegionInfo ) RGNdesc;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  ercd = cTECSInfo_findRegion( regionPath, &RGNdesc );
+  if( ercd == E_OK ){
+      cRegionInfo_set_descriptor( RGNdesc );
+  }
+  else {
+      cRegionInfo_unjoin(  );
+  }
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCellInfoByName
+ * name:         eSelector_selectCellInfoByName
+ * global_name:  tTECSInfoAccessor_eSelector_selectCellInfoByName
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCellInfoByName(CELLIDX idx, const char_t* cellPath)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sCellInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  ercd = cTECSInfo_findCell( cellPath, &desc );
+  if( ercd == E_OK ){
+      cCellInfo_set_descriptor( desc );
+  }
+  else {
+      cCellInfo_unjoin(  );
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedNamespaceInfo
+ * name:         eSelector_getSelectedNamespaceInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedNamespaceInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedNamespaceInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* num_namespace, int_t* num_celltype, int_t* num_signature)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cNSInfo_joined() ){
+      cNSInfo_getName( name, max_len );
+      *num_namespace = cNSInfo_getNNamespace( );
+      *num_signature = cNSInfo_getNSignature( );
+      *num_celltype  = cNSInfo_getNCelltype( );
+  }
+  else {
+      ercd = E_OBJ;      // cNSInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCelltypeInfo
+ * name:         eSelector_selectCelltypeInfo
+ * global_name:  tTECSInfoAccessor_eSelector_selectCelltypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCelltypeInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sCelltypeInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  cCelltypeInfo_unjoin(  );
+  if( is_cNSInfo_joined() ){
+      if( 0 <= ith && ith < cNSInfo_getNCelltype() ){
+          cNSInfo_getCelltypeInfo( ith, &desc );
+          cCelltypeInfo_set_descriptor( desc );
+      }
+      else{
+          ercd = E_PAR;  // index out of range
+      }
+  }
+  else{
+      ercd = E_OBJ;      // cNSInfo not joined
+  }
+
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectSignatureInfo
+ * name:         eSelector_selectSignatureInfo
+ * global_name:  tTECSInfoAccessor_eSelector_selectSignatureInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectSignatureInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sSignatureInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  cSignatureInfo_unjoin(  );
+  if( is_cNSInfo_joined() ){
+      if( 0 <= ith && ith < cNSInfo_getNSignature( ) ){
+          cNSInfo_getSignatureInfo( ith, &desc );
+          cSignatureInfo_set_descriptor( desc );
+      }
+      else{
+          ercd = E_PAR;  // index out of range
+      }
+  }
+  else{
+      ercd = E_OBJ;      // cNSInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCelltypeInfo
+ * name:         eSelector_getSelectedCelltypeInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedCelltypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCelltypeInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* num_attr, int_t* num_var, int_t* num_call, int_t* num_entry)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cCelltypeInfo_joined() ){
+      cCelltypeInfo_getName( name, max_len );
+      *num_attr  = cCelltypeInfo_getNAttr( );
+      *num_var   = cCelltypeInfo_getNVar( );
+      *num_call  = cCelltypeInfo_getNCall( );
+      *num_entry = cCelltypeInfo_getNEntry( );
+  }
+  else {
+      ercd = E_OBJ;      // cCelltypeInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCallInfo
+ * name:         eSelector_selectCallInfo
+ * global_name:  tTECSInfoAccessor_eSelector_selectCallInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCallInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sCallInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  cCallInfo_unjoin(  );
+  if( is_cCelltypeInfo_joined() ){
+      if( 0 <= ith && ith < cCelltypeInfo_getNCall( ) ){
+          cCelltypeInfo_getCallInfo( ith, &desc );
+          cCallInfo_set_descriptor( desc );
+      }
+      else{
+          ercd = E_PAR;  // index out of range
+      }
+  }
+  else{
+      ercd = E_OBJ;      // cCelltypeInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectEntryInfo
+ * name:         eSelector_selectEntryInfo
+ * global_name:  tTECSInfoAccessor_eSelector_selectEntryInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectEntryInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sEntryInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  cEntryInfo_unjoin(  );
+  if( is_cCelltypeInfo_joined() ){
+      if( 0 <= ith && ith < cCelltypeInfo_getNEntry( ) ){
+          cCelltypeInfo_getEntryInfo( ith, &desc );
+          cEntryInfo_set_descriptor( desc );
+      }
+      else{
+          ercd = E_PAR;  // index out of range
+      }
+  }
+  else{
+      ercd = E_OBJ;      // cCelltypeInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectAttrInfo
+ * name:         eSelector_selectAttrInfo
+ * global_name:  tTECSInfoAccessor_eSelector_selectAttrInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectAttrInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sVarDeclInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  cAttrInfo_unjoin(  );
+  if( is_cCelltypeInfo_joined() ){
+      if( 0 <= ith && ith < cCelltypeInfo_getNAttr( ) ){
+          cCelltypeInfo_getAttrInfo( ith, &desc );
+          cAttrInfo_set_descriptor( desc );
+      }
+      else{
+          ercd = E_PAR;  // index out of range
+      }
+  }
+  else{
+      ercd = E_OBJ;      // cCelltypeInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectVarInfo
+ * name:         eSelector_selectVarInfo
+ * global_name:  tTECSInfoAccessor_eSelector_selectVarInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectVarInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sVarDeclInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  cVarInfo_unjoin(  );
+  if( is_cCelltypeInfo_joined() ){
+      if( 0 <= ith && ith < cCelltypeInfo_getNVar( ) ){
+          cCelltypeInfo_getVarInfo( ith, &desc );
+          cVarInfo_set_descriptor( desc );
+      }
+      else{
+          ercd = E_PAR;  // index out of range
+      }
+  }
+  else{
+      ercd = E_OBJ;      // cCelltypeInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedAttrInfo
+ * name:         eSelector_getSelectedAttrInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedAttrInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedAttrInfo(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cAttrInfo_joined() ){
+      cAttrInfo_getName( name, max_len );
+  }
+  else{
+      ercd = E_OBJ;      // cAttrInfo not joined
+  }
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSizeIsExprOfAttr
+ * name:         eSelector_getSizeIsExprOfAttr
+ * global_name:  tTECSInfoAccessor_eSelector_getSizeIsExprOfAttr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSizeIsExprOfAttr(CELLIDX idx, char_t* expr_str, int32_t max_len)
+{
+	CELLCB	*p_cellcb;
+  ER     ercd = E_OK;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cAttrInfo_joined() ){
+      cAttrInfo_getSizeIsExpr( expr_str, max_len );
+  }
+  else{
+      ercd = E_OBJ;      // cAttrInfo not joined
+  }
+  return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectTypeInfoOfAttr
+ * name:         eSelector_selectTypeInfoOfAttr
+ * global_name:  tTECSInfoAccessor_eSelector_selectTypeInfoOfAttr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectTypeInfoOfAttr(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sTypeInfo ) desc;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cAttrInfo_joined() ){
+      cAttrInfo_getTypeInfo( &desc );
+      cTypeInfo_set_descriptor( desc );
+  }
+  else{
+      ercd = E_OBJ;      // cAttrInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedVarInfo
+ * name:         eSelector_getSelectedVarInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedVarInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedVarInfo(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cVarInfo_joined() ){
+      cVarInfo_getName( name, max_len );
+  }
+  else{
+      ercd = E_OBJ;      // cVarInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSizeIsExprOfVar
+ * name:         eSelector_getSizeIsExprOfVar
+ * global_name:  tTECSInfoAccessor_eSelector_getSizeIsExprOfVar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSizeIsExprOfVar(CELLIDX idx, char_t* expr_str, int32_t max_len)
+{
+	CELLCB	*p_cellcb;
+  ER     ercd = E_OK;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  printf( "eSelector_getSizeIsExprOfVar not supported\n" );
+
+  return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectTypeInfoOfVar
+ * name:         eSelector_selectTypeInfoOfVar
+ * global_name:  tTECSInfoAccessor_eSelector_selectTypeInfoOfVar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectTypeInfoOfVar(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sTypeInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cVarInfo_joined() ){
+      cVarInfo_getTypeInfo( &desc );
+      cTypeInfo_set_descriptor( desc );
+  }
+  else{
+      ercd = E_OBJ;      // cVarInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCallInfo
+ * name:         eSelector_getSelectedCallInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedCallInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCallInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* array_size)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+    if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cCallInfo_joined() ){
+      cCallInfo_getName( name, max_len );
+      *array_size = cCallInfo_getArraySize();
+  }
+  else{
+      ercd = E_OBJ;      // cCallInfo not joined
+  }
+  return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectSignatureOfCall
+ * name:         eSelector_selectSignatureOfCall
+ * global_name:  tTECSInfoAccessor_eSelector_selectSignatureOfCall
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectSignatureOfCall(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sSignatureInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cCallInfo_joined() ){
+      cCallInfo_getSignatureInfo( &desc );
+      cSignatureInfo_set_descriptor( desc );
+  }
+  else {
+      ercd = E_OBJ;      // cCallInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCallSpecifierInfo
+ * name:         eSelector_getSelectedCallSpecifierInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedCallSpecifierInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCallSpecifierInfo(CELLIDX idx, bool_t* b_optional, bool_t* b_dynamic, bool_t* b_ref_desc, bool_t* b_omit)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cCallInfo_joined() ){
+      cCallInfo_getSpecifierInfo( b_optional, b_dynamic, b_ref_desc, b_omit );
+  }
+  else {
+      ercd = E_OBJ;      // cCallInfo not joined
+  }
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCallInternalInfo
+ * name:         eSelector_getSelectedCallInternalInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedCallInternalInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCallInternalInfo(CELLIDX idx, bool_t* b_allocator_port, bool_t* b_require_port)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cCallInfo_joined() ){
+      cCallInfo_getInternalInfo( b_allocator_port, b_require_port );
+  }
+  else {
+      ercd = E_OBJ;      // cCallInfo not joined
+  }
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCallLocationInfo
+ * name:         eSelector_getSelectedCallLocationInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedCallLocationInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCallLocationInfo(CELLIDX idx, uint32_t* offset, int8_t* place)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cCallInfo_joined() ){
+      cCallInfo_getLocationInfo( offset, place );
+  }
+  else {
+      ercd = E_OBJ;      // cCallInfo not joined
+  }
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCallOptimizeInfo
+ * name:         eSelector_getSelectedCallOptimizeInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedCallOptimizeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCallOptimizeInfo(CELLIDX idx, bool_t* b_VMT_useless, bool_t* b_skelton_useless, bool_t* b_cell_unique)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cCallInfo_joined() ){
+      cCallInfo_getOptimizeInfo( b_VMT_useless, b_skelton_useless, b_cell_unique );
+  }
+  else {
+      ercd = E_OBJ;      // cCallInfo not joined
+  }
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedEntryInfo
+ * name:         eSelector_getSelectedEntryInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedEntryInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedEntryInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* array_size)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cEntryInfo_joined() ){
+      cEntryInfo_getName( name, max_len );
+      *array_size = cEntryInfo_getArraySize();
+  }
+  else{
+      ercd = E_OBJ;      // cEntryInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectSignatureOfEntry
+ * name:         eSelector_selectSignatureOfEntry
+ * global_name:  tTECSInfoAccessor_eSelector_selectSignatureOfEntry
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectSignatureOfEntry(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sSignatureInfo ) desc;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cEntryInfo_joined() ){
+      cEntryInfo_getSignatureInfo( &desc );
+      cSignatureInfo_set_descriptor( desc );
+  }
+  else {
+      ercd = E_OBJ;      // cEntryInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedEntryInlineInfo
+ * name:         eSelector_getSelectedEntryInlineInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedEntryInlineInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedEntryInlineInfo(CELLIDX idx, bool_t* b_inline)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cEntryInfo_joined() ){
+      *b_inline = cEntryInfo_isInline( );
+  }
+  else {
+      ercd = E_OBJ;      // cEntryInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedSignatureInfo
+ * name:         eSelector_getSelectedSignatureInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedSignatureInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedSignatureInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* num_function)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cSignatureInfo_joined() ){
+      cSignatureInfo_getName( name, max_len );
+      *num_function = cSignatureInfo_getNFunction( );
+  }
+  else {
+      ercd = E_OBJ;      // cSignatureInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectFunctionInfoByIndex
+ * name:         eSelector_selectFunctionInfoByIndex
+ * global_name:  tTECSInfoAccessor_eSelector_selectFunctionInfoByIndex
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectFunctionInfoByIndex(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sFunctionInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cSignatureInfo_joined() ){
+      if( 0 <= ith && ith < cSignatureInfo_getNFunction( ) ){
+          cSignatureInfo_getFunctionInfo( ith, &desc );
+          cFunctionInfo_set_descriptor( desc );
+      }
+      else {
+      }
+  }
+  else {
+      ercd = E_OBJ;      // cSignatureInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedFunctionInfo
+ * name:         eSelector_getSelectedFunctionInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedFunctionInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedFunctionInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* num_args)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cFunctionInfo_joined() ){
+      cFunctionInfo_getName( name, max_len );
+      *num_args = cFunctionInfo_getNParam( );
+  }
+  else {
+      ercd = E_OBJ;      // cFunctionInfo not joined
+  }
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectTypeInfoOfReturn
+ * name:         eSelector_selectTypeInfoOfReturn
+ * global_name:  tTECSInfoAccessor_eSelector_selectTypeInfoOfReturn
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectTypeInfoOfReturn(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sTypeInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cFunctionInfo_joined() ){
+      cFunctionInfo_getReturnTypeInfo( &desc );
+      cTypeInfo_set_descriptor( desc );
+  }
+  else {
+      ercd = E_OBJ;      // cFunctionInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedParamInfo
+ * name:         eSelector_getSelectedParamInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedParamInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedParamInfo(CELLIDX idx, char_t* name, int_t max_len, int8_t* dir)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cParamInfo_joined() ){
+      cParamInfo_getName( name, max_len );
+      cParamInfo_getDir( dir );
+  }
+  else {
+      ercd = E_OBJ;      // cParamInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectParamInfo
+ * name:         eSelector_selectParamInfo
+ * global_name:  tTECSInfoAccessor_eSelector_selectParamInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectParamInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sParamInfo ) desc;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cFunctionInfo_joined() ){
+      if( 0 <= ith && ith < cFunctionInfo_getNParam() ){
+          cFunctionInfo_getParamInfo( ith, &desc );
+          cParamInfo_set_descriptor( desc );
+      }
+      else{
+          ercd = E_PAR;  // index out of range
+      }
+  }
+  else {
+      ercd = E_OBJ;      // cFunctionInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectTypeInfoOfParam
+ * name:         eSelector_selectTypeInfoOfParam
+ * global_name:  tTECSInfoAccessor_eSelector_selectTypeInfoOfParam
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectTypeInfoOfParam(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sTypeInfo ) desc;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cParamInfo_joined() ){
+      cParamInfo_getTypeInfo( &desc );
+      cTypeInfo_set_descriptor( desc );
+  }
+  else {
+      ercd = E_OBJ;      // cFunctionInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedTypeInfo
+ * name:         eSelector_getSelectedTypeInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedTypeInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedTypeInfo(CELLIDX idx, char_t* name, int_t max_len, int8_t* kind)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cTypeInfo_joined() ){
+      cTypeInfo_getName( name, max_len );
+      *kind = cTypeInfo_getKind( );
+  }
+  else {
+      ercd = E_OBJ;      // cTypeInfo not joined
+  }
+  return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectTypeInfoOfType
+ * name:         eSelector_selectTypeInfoOfType
+ * global_name:  tTECSInfoAccessor_eSelector_selectTypeInfoOfType
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectTypeInfoOfType(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sTypeInfo ) desc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cTypeInfo_joined() ){
+      cTypeInfo_getTypeInfo( &desc );
+      cTypeInfo_set_descriptor( desc );
+  }
+  else {
+      ercd = E_OBJ;      // cTypeInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedRegionInfo
+ * name:         eSelector_getSelectedRegionInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedRegionInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedRegionInfo(CELLIDX idx, char_t* name, int_t max_len, int_t* num_cell)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cRegionInfo_joined() ){
+      cRegionInfo_getName( name, max_len );
+      *num_cell = cRegionInfo_getNCell();
+  }
+  else {
+      ercd = E_OBJ;      // cNSInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCellInfo
+ * name:         eSelector_selectCellInfo
+ * global_name:  tTECSInfoAccessor_eSelector_selectCellInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCellInfo(CELLIDX idx, int_t ith)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sCellInfo ) desc;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cRegionInfo_joined() ){
+      if( 0 <= ith && ith < cRegionInfo_getNCell() ){
+          cRegionInfo_getCellInfo( ith, &desc );
+          cCellInfo_set_descriptor( desc );
+      }
+      else {
+          ercd = E_PAR;
+      }
+  }
+  else {
+      ercd = E_OBJ;      // cNSInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getSelectedCellInfo
+ * name:         eSelector_getSelectedCellInfo
+ * global_name:  tTECSInfoAccessor_eSelector_getSelectedCellInfo
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getSelectedCellInfo(CELLIDX idx, char_t* name, int_t max_len)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cCellInfo_joined() ){
+      cCellInfo_getName( name, max_len );
+  }
+  else {
+      ercd = E_OBJ;      // cNSInfo not joined
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_selectCelltypeInfoOfCell
+ * name:         eSelector_selectCelltypeInfoOfCell
+ * global_name:  tTECSInfoAccessor_eSelector_selectCelltypeInfoOfCell
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_selectCelltypeInfoOfCell(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+  Descriptor( nTECSInfo_sCelltypeInfo ) desc;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cCellInfo_joined() ){
+      cCellInfo_getCelltypeInfo( &desc );
+      cCelltypeInfo_set_descriptor( desc );
+  }
+  else {
+      ercd = E_OBJ;      // cNSInfo not joined
+  }
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getAttrValueInStr
+ * name:         eSelector_getAttrValueInStr
+ * global_name:  tTECSInfoAccessor_eSelector_getAttrValueInStr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getAttrValueInStr(CELLIDX idx, char_t* buf, int_t max_len)
+{
+	ER		  ercd = E_OK;
+	CELLCB	*p_cellcb;
+  uint32_t offset;
+  void     *base, *ptr;
+  int8_t   place;
+
+  Descriptor( nTECSInfo_sCelltypeInfo ) CTdesc;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( is_cCellInfo_joined() && is_cAttrInfo_joined() ){
+      cCellInfo_getCelltypeInfo( &CTdesc );
+      cCelltypeInfo_set_descriptor( CTdesc );
+      printf( "eSelector_getAttrValueInStr not supported\n" );
+      cAttrInfo_getLocationInfo( &offset, &place );
+      switch( place ){
+      case VARDECL_PLACE_CB:
+          cCellInfo_getCBP( &base );
+          break;
+      case VARDECL_PLACE_INIB:
+          cCellInfo_getINIBP( &base );
+          break;
+      default:
+          base = (void *)0;
+      };
+      if( base ){
+          ptr = base + offset;
+          eSelector_selectTypeInfoOfAttr(idx);
+          getSelectedTypeValue( p_cellcb, ptr, buf, max_len );
+      }
+      else {
+          strncpy( buf, "(OMITTED)", max_len );
+      }
+  }
+  else{
+      ercd = E_OBJ;
+  }
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getAttrSizeIsValue
+ * name:         eSelector_getAttrSizeIsValue
+ * global_name:  tTECSInfoAccessor_eSelector_getAttrSizeIsValue
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getAttrSizeIsValue(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  printf( "eSelector_getAttrSizeIsValue not supported\n" );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getVarValueInStr
+ * name:         eSelector_getVarValueInStr
+ * global_name:  tTECSInfoAccessor_eSelector_getVarValueInStr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getVarValueInStr(CELLIDX idx, char_t* buf, int_t max_len)
+{
+	ER        ercd = E_OK;
+	CELLCB    *p_cellcb;
+  int8_t    place;
+  void      *base, *ptr;
+  uint32_t  offset;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  cVarInfo_getLocationInfo( &offset, &place );
+  switch( place ){
+  case VARDECL_PLACE_CB:
+      cCellInfo_getCBP( &base );
+      break;
+  case VARDECL_PLACE_INIB:
+      cCellInfo_getINIBP( &base );
+      break;
+  default:
+      base = (void *)0;
+  };
+  if( base ){
+      ptr = base + offset;
+      eSelector_selectTypeInfoOfVar(idx);
+      getSelectedTypeValue( p_cellcb, ptr, buf, max_len );
+  }
+  else {
+      strncpy( buf, "(OMITTED)", max_len );
+  }
+  printf( "eSelector_getVarValueInStr not supported\n" );
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSelector_getVarSizeIsValue
+ * name:         eSelector_getVarSizeIsValue
+ * global_name:  tTECSInfoAccessor_eSelector_getVarSizeIsValue
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSelector_getVarSizeIsValue(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  printf( "eSelector_getVarSizeIsValue not supported\n" );
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
+
+static void
+getSelectedTypeValue( CELLCB *p_cellcb, void *ptr, char_t *buf, int_t max_len )
+{
+    switch( cTypeInfo_getKind() ){
+    case TECSTypeKind_BoolType:
+        snprintf( buf, max_len, "%d", *(bool_t *)ptr );
+        break;
+    case TECSTypeKind_IntType:
+        switch( cTypeInfo_getSize() ){
+        case 8:
+            snprintf( buf, max_len, "%d", *(int8_t *)ptr );
+            break;
+        case 16:
+            snprintf( buf, max_len, "%d", *(int16_t *)ptr );
+            break;
+        case 32:
+            snprintf( buf, max_len, "%d", *(int32_t *)ptr );
+            break;
+        case 64:
+            snprintf( buf, max_len, "%lld", *(int64_t *)ptr );
+            break;
+        default:
+            snprintf( buf, max_len, "unknown int size(%d)", cTypeInfo_getSize() );
+        };
+    case TECSTypeKind_FloatType:
+        switch( cTypeInfo_getSize() ){
+        case 32:
+            snprintf( buf, max_len, "%g", *(float32_t *)ptr );
+            break;
+        case 64:
+            snprintf( buf, max_len, "%g", *(double64_t *)ptr );
+            break;
+        default:
+            snprintf( buf, max_len, "unknown double size(%d)", cTypeInfo_getSize() );
+        };
+    case TECSTypeKind_PtrType:
+        snprintf( buf, max_len, "%X", *(double64_t *)ptr );
+        break;
+    case TECSTypeKind_ArrayType:        break;
+    case TECSTypeKind_DefinedType:      break;
+    case TECSTypeKind_StructType:       break;
+    case TECSTypeKind_EnumType:         break;
+    case TECSTypeKind_VoidType:         break;
+    case TECSTypeKind_DescriptorType:   break;
+    default:                            break;
+    };
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TLSFMalloc/README-TLSF.txt
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TLSFMalloc/README-TLSF.txt	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TLSFMalloc/README-TLSF.txt	(revision 398)
@@ -0,0 +1,23 @@
+TLSF Malloc アロケータ
+                                          2017.4.15
+                                          大山
+1.概要
+
+TLSF は効率よく、フラグメントが起きにくいアロケータです。 OS 非依存に
+実装されているため、組込みシステムへの応用に適しています。この実装では
+排他制御を行っていません。複数のタスクで共用するには、排他制御を行う必
+要があります。
+
+2. 実装について
+
+1) TLSF アロケータの本体は、TECS ジェネレータパッケージには含まれていません。
+以下に公開されている TLSF を入手する必要があります。
+これは GPL/LGPL ライセンスで公開されています。
+  http://www.gii.upv.es/tlsf/main/docs
+
+2) TLSF には、別に実装され MIT ライセンスで公開されているものもあります。
+API が若干異なるため、tTLSFMalloc_inline.h を少し修正する必要があります。
+  https://github.com/mattconte/tlsf
+
+3) ETロボコン用パッケージ
+mruby-on-ev3rt+tecs_package (ev3rt) には、1) の TLSF が含まれています。
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TLSFMalloc/tTLSFMalloc.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TLSFMalloc/tTLSFMalloc.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TLSFMalloc/tTLSFMalloc.cdl	(revision 398)
@@ -0,0 +1,56 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+import( <sMalloc.cdl> );
+
+celltype tTLSFMalloc {
+    [inline]
+        entry  sMalloc  eMalloc;
+    attr {
+        /* memory pool size in bytes */
+        size_t  memoryPoolSize;
+    };
+    var {
+        /*
+         * メモリプール
+         *
+         * size_is の引数に関する補足説明
+         *  pool の型が uint64_t のため sizeof uint64_t (8) で割っている
+         *  memoryPoolSize が 8 の倍数でない場合、メモリ領域が不足しないよう +7 を加算してから除する
+         */
+        [size_is( (memoryPoolSize+7) / 8 )]
+            uint64_t   *pool;
+    };
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TLSFMalloc/tTLSFMalloc_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TLSFMalloc/tTLSFMalloc_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/TLSFMalloc/tTLSFMalloc_inline.h	(revision 398)
@@ -0,0 +1,152 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef tTLSFMalloc__INLINE_H
+#define tTLSFMalloc__INLINE_H
+
+#include "tlsf.h"
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * memoryPoolSize   size_t           ATTR_memoryPoolSize
+ * pool             uint64_t*        VAR_pool        
+ *
+ * #[</PREAMBLE>]# */
+
+/* #[<ENTRY_PORT>]# eMalloc
+ * entry port: eMalloc
+ * signature:  sMalloc
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eMalloc_initializeMemoryPool
+ * name:         eMalloc_initializeMemoryPool
+ * global_name:  tTLSFMalloc_eMalloc_initializeMemoryPool
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline int
+eMalloc_initializeMemoryPool(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+	} /* end if VALID_IDX(idx) */
+
+  return init_memory_pool(ATTR_memoryPoolSize, VAR_pool);
+}
+
+/* #[<ENTRY_FUNC>]# eMalloc_calloc
+ * name:         eMalloc_calloc
+ * global_name:  tTLSFMalloc_eMalloc_calloc
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline void*
+eMalloc_calloc(CELLIDX idx, size_t nelem, size_t elem_size)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+	} /* end if VALID_IDX(idx) */
+
+  return calloc_ex( nelem, elem_size, VAR_pool);
+}
+
+/* #[<ENTRY_FUNC>]# eMalloc_malloc
+ * name:         eMalloc_malloc
+ * global_name:  tTLSFMalloc_eMalloc_malloc
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline void*
+eMalloc_malloc(CELLIDX idx, size_t size)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+	} /* end if VALID_IDX(idx) */
+
+  return malloc_ex(size, VAR_pool);
+
+}
+
+/* #[<ENTRY_FUNC>]# eMalloc_realloc
+ * name:         eMalloc_realloc
+ * global_name:  tTLSFMalloc_eMalloc_realloc
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline void*
+eMalloc_realloc(CELLIDX idx, const void* ptr, size_t new_size)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+	} /* end if VALID_IDX(idx) */
+
+  return realloc_ex((void *)ptr, new_size, VAR_pool);
+}
+
+/* #[<ENTRY_FUNC>]# eMalloc_free
+ * name:         eMalloc_free
+ * global_name:  tTLSFMalloc_eMalloc_free
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline void
+eMalloc_free(CELLIDX idx, const void* ptr)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+	} /* end if VALID_IDX(idx) */
+
+  return free_ex((void *)ptr, VAR_pool);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
+
+#endif /* tTLSFMalloc_INLINEH */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/README-mruby.txt
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/README-mruby.txt	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/README-mruby.txt	(revision 398)
@@ -0,0 +1,62 @@
+mruby
+                                              2017.4.17  新規
+                                              2017.11.4  
+                                              大山 博司
+
+■概要
+
+mruby ディレクトリには、組込み用 mruby VM のセルタイプ、および
+MrubyBridgePlugin に対応したモジュールが含まれます．
+
+mruby V1.2.0 に対応しています．V1.1.0 でもビルドすることは可能です．
+
+ここには mruby の本体は含まれません．以下からダウンロードする必要があります．
+   http://forum.mruby.org/
+
+■TECS ジェネレータ V1.5 での変更
+
+tMruby.cdl (パス：tecsgen/tecs/mruby/tMruby.cdl) を新設した．
+以下を可能にするために tMruby を composite に分解した．
+ * mruby スクリプトの周期タスク実行
+ * VM ごとに異なる TLSF アロケータコンポーネントを使用
+
+tMruby.cdl では tMruby (ネームスペースパス：nMruby::tMruby) の実装を
+新しくした他、周期タスク実行用の tMrubyCyclic (同：nMruby::tMrubyCyclic)
+を新設した．tMruby を分解した、tMrubyVM セルタイプと、そのシグニチャ
+sMruby (sMruby.cdl内) も新設した．
+
+tMruby.cdl に置き換え可能だが、以下の点でビルド用 Makefile の変更が必要．
+ * TLSF ヘッダ tTLSFMalloc_inline.h へのパスを追加
+ * TLSF のオブジェクトの追加 (mruby+TECS on EV3 には実装済み)
+
+また、以下の点に留意する必要がある．
+ * TLSF は、VM ごとに 1MB を割り付ける 
+
+このため、十分な空きメモリが必要である．
+このサイズは VM セルの定義で変更可能 (属性 memoryPoolSize)．
+
+■ コンポーネント概要
+
+tMruby.cdl: (TECS ジェネレータ V1.5.0 以降)
+ celltype  tMrubyVM
+    VM を実装するためのセルタイプ．メモリアロケータ TLSFMalloc を含ま
+    ない. 受け口 eMrubyVM のシグニチャは sMruby．
+
+ composite tMruby
+    受け口 eMrubyBody のシグニチャを sTaskBody とする．tTLSFMalloc も
+    組み入れ.
+
+ composite tMrubyCyclic
+    受け口 eMrubyBody のシグニチャを sTaskBody とする．tTLSFMalloc も
+    組み入れ.
+    周期タスク起床を前提としている．
+    一回目の呼出しでは mrb_open し、ブリッジセルを登録後、mrb_run を呼
+    び出してスクリプト実行を行う．スクリプト終了後に mrb_close は呼び
+    出されない．
+    二回目以降の呼出しでは mrb_run のみ呼び出される．
+    終了処理 mrb_close を呼びだす手段は提供していない．突然電源が切ら
+    れることを前提としている． (少なくとも最初の実装では)．
+
+sMruby.cdl：
+ signature sMruby
+   初期化、実行、終了処理に分解したシグニチャ
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/TECSPointer.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/TECSPointer.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/TECSPointer.h	(revision 398)
@@ -0,0 +1,585 @@
+/*
+ *  mruby => TECS brige
+ *  
+ *   Copyright (C) 2008-2012 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$ 
+ */
+
+#ifndef TECSPointer_h__
+#define TECSPointer_h__
+
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#ifndef CHAR_T_DEFINED
+typedef	int		bool_t;
+typedef	char	char_t;
+typedef	double	double64_t;
+typedef	float	float32_t;
+#endif /* CHAR_T_DEFINED */
+
+////  define Pointer classes ////
+#define POINTER_BODY( Type, TYPE )										\
+																		\
+	struct Type ## PointerBody {										\
+		uint32_t	length;												\
+		TYPE 		buf[ /* length */ ];								\
+	};
+
+
+// struct TypePointerBody
+POINTER_BODY( Bool,  bool_t )		/* struct BoolPointerBody */
+POINTER_BODY( Double64, double64_t )/* struct Double64PointerBody */
+POINTER_BODY( Float32, float32_t )	/* struct Float32PointerBody */
+
+POINTER_BODY( Int8,  int8_t )		/* struct Int8PointerBody */
+POINTER_BODY( Int16, int16_t )		/* struct Int16PointerBody */
+POINTER_BODY( Int32, int32_t )		/* struct Int32PointerBody */
+POINTER_BODY( Int64, int64_t )		/* struct Int64PointerBody */
+POINTER_BODY( Char,  char_t )		/* struct CharPointerBody */
+POINTER_BODY( Int,   int )			/* struct IntPointerBody */
+POINTER_BODY( Short, short )		/* struct ShortPointerBody */
+POINTER_BODY( Long,  long )			/* struct LongPointerBody */
+
+POINTER_BODY( UInt8,  uint8_t )		/* struct UInt8PointerBody */
+POINTER_BODY( UInt16, uint16_t )	/* struct UInt16PointerBody */
+POINTER_BODY( UInt32, uint32_t )	/* struct UInt32PointerBody */
+POINTER_BODY( UInt64, uint64_t )	/* struct UInt64PointerBody */
+POINTER_BODY( UChar,  uint8_t )		/* struct UCharPointerBody */
+POINTER_BODY( UInt,   unsigned int )	/* struct UIntPointerBody */
+POINTER_BODY( UShort, unsigned short )	/* struct UShortPointerBody */
+POINTER_BODY( ULong,  unsigned long )	/* struct ULongPointerBody */
+
+POINTER_BODY( SChar,  char_t )		/* struct SCharPointerBody */
+
+// ■ TECS_NO_VAL_CHECK を define すると、値チェックを省略する
+#ifndef TECS_NO_VAL_CHECK
+#define	VALCHECK_INT(Type, TYPE, type )									\
+	/*  check before assigning mrb_int val to intN_t */					\
+	static inline void													\
+	VALCHECK_ ## Type( mrb_state *mrb, mrb_int val )					\
+	{																	\
+		if( sizeof( mrb_int ) > sizeof( type ) ){						\
+			if( val > TYPE ## _MAX || val < TYPE ## _MIN ) 				\
+				mrb_raise(mrb, E_ARGUMENT_ERROR, "too large or too small for "  #type "_t"); \
+		}																\
+	}
+#define	VALCHECK_MRB_INT(Type, TYPE, type )								\
+	/*  check before assigning val (intN_t) to mrb_int */				\
+	static inline void													\
+	VALCHECK_MRB_ ## Type( mrb_state *mrb, type val )					\
+	{																	\
+		if( sizeof( type ) > sizeof( mrb_int ) ){						\
+			if( val > TYPE ## _MAX				\
+				|| val < TYPE ## _MIN )		\
+				/* '=' unecessary for negative value	*/				\
+				/* ignore warning on int32_t */							\
+				mrb_raise(mrb, E_ARGUMENT_ERROR, "too large or too small for mrb_int"); \
+		}																\
+	}
+
+#define	VALCHECK_UINT(Type, TYPE, type )								\
+	/*  check before assigning mrb_int val to intN_t */					\
+	static inline void													\
+	VALCHECK_ ## Type( mrb_state *mrb, mrb_int  val )					\
+	{																	\
+		if( sizeof( mrb_int ) > sizeof( type ) ){						\
+			if( val > TYPE ## _MAX || val < 0 ) 						\
+				mrb_raise(mrb, E_ARGUMENT_ERROR, "too large or too small for "  #type "_t"); \
+		}																\
+	}
+#define	VALCHECK_MRB_UINT(Type, TYPE, type )							\
+	/*  check before assigning val (intN_t) to mrb_int */				\
+	static inline void													\
+	VALCHECK_MRB_ ## Type( mrb_state *mrb, type val )					\
+	{																	\
+		if( sizeof( type ) > sizeof( mrb_int ) ){						\
+      if( val > TYPE ## _MAX )                        \
+				/* '=' unecessary for negative value	*/				\
+				/* ignore warning on int32_t */							\
+				mrb_raise(mrb, E_ARGUMENT_ERROR, "too large or too small for mrb_int"); \
+		}																\
+	}
+#else // TECS_NO_VAL_CHECK
+
+#define	VALCHECK_INT(Type, TYPE, type )
+#define	VALCHECK_UINT(Type, TYPE, type )
+
+#endif // TECS_NO_VAL_CHECK
+
+// define VALCHECK function
+#define VALCHECK_Bool( mrb, val )
+#define	VALCHECK_MRB_Bool( mrb, val )
+
+VALCHECK_INT( Int8, INT8, int8_t )
+VALCHECK_MRB_INT( Int8, INT8, int8_t )
+VALCHECK_INT( Int16, INT16, int16_t )
+VALCHECK_MRB_INT( Int16, INT16, int16_t )
+VALCHECK_UINT( UInt8, UINT8, uint8_t )
+#define	VALCHECK_MRB_UInt8(mrb,val)
+VALCHECK_UINT( UInt16, UINT16, uint16_t )
+#define	VALCHECK_MRB_UInt16(mrb,val)
+VALCHECK_INT( Int32, INT32, int32_t )
+#define VALCHECK_MRB_Int32(mrb,val)
+VALCHECK_UINT( UInt32, UINT32, uint32_t )
+#define VALCHECK_MRB_UInt32(mrb,val)
+
+VALCHECK_INT( Int64, INT64, int64_t )
+VALCHECK_UINT( UInt64, UINT64, uint64_t )
+#ifndef mrb_int_IS_int64
+	 // ■ int 32 bit を仮定している. 64 bit であれば mrb_int_IS_64 を define する
+VALCHECK_MRB_INT( Int64, INT64, int64_t )
+VALCHECK_MRB_UINT( UInt64, UINT64, uint64_t )
+#else
+#define VALCHECK_MRB_Int64(mrb,val)      // 範囲チェックが無意味であるため、警告が出るのを回避する
+#define VALCHECK_MRB_UInt64(mrb,val)      // 範囲チェックが無意味であるため、警告が出るのを回避する
+#endif
+
+#ifndef TECS_NO_VAL_CHECK
+	 // ■ char_t は unsigned とみなす
+static inline void
+VALCHECK_Char( mrb_state *mrb, mrb_int  val )
+{
+	if( val > 0xff || val < 0 )	
+		mrb_raise(mrb, E_ARGUMENT_ERROR, "too large or too small for char_t");
+}
+#define	VALCHECK_MRB_Char( mrb, val )
+
+VALCHECK_INT( Short, SHRT, short )
+#define	VALCHECK_MRB_Short( mrb, val )
+
+VALCHECK_INT( Int, INT, int )
+#define	VALCHECK_MRB_Int( mrb, val )
+
+VALCHECK_INT( Long, LONG, long )
+#define	VALCHECK_MRB_Long( mrb, val )
+
+VALCHECK_INT( SChar, SCHAR, signed char )
+#define	VALCHECK_MRB_SChar( mrb, val )
+
+VALCHECK_UINT( UChar, UCHAR, unsigned char )
+#define	VALCHECK_MRB_UChar( mrb, val )
+
+VALCHECK_UINT( UInt, UINT, unsigned int )
+#define	VALCHECK_MRB_UInt( mrb, val )
+
+VALCHECK_UINT( UShort, USHRT, unsigned short )
+#define	VALCHECK_MRB_UShort( mrb, val )
+
+VALCHECK_UINT( ULong, ULONG, unsigned long )
+#define	VALCHECK_MRB_ULong( mrb, val )
+
+#else // TECS_NO_VAL_CHECK
+
+#define VALCHECK_Char( mrb, val )
+#define	VALCHECK_MRB_Char( mrb, val )
+#define VALCHECK_Int( mrb, val )
+#define	VALCHECK_MRB_Int( mrb, val )
+#define	VALCHECK_Short( mrb, val )
+#define	VALCHECK_MRB_Short( mrb, val )
+#define	VALCHECK_Long( mrb, val )
+#define	VALCHECK_MRB_Long( mrb, val )
+#define	VALCHECK_SChar( mrb, val )
+#define	VALCHECK_MRB_SChar( mrb, val )
+#define	VALCHECK_UChar( mrb, val )
+#define	VALCHECK_MRB_UChar( mrb, val )
+#define	VALCHECK_UInt( mrb, val )
+#define	VALCHECK_MRB_UInt( mrb, val )
+#define	VALCHECK_UShort( mrb, val )
+#define	VALCHECK_MRB_UShort( mrb, val )
+#define	VALCHECK_ULong( mrb, val )
+#define	VALCHECK_MRB_ULong( mrb, val )
+
+#endif // TECS_NO_VAL_CHECK
+
+#define CHECK_AND_GET_POINTER( Type, type )								\
+	type *CheckAndGet ## Type ## Pointer( mrb_state *mrb, mrb_value value, int32_t len ) \
+	{																	\
+		if( mrb_type(value) != MRB_TT_DATA								\
+			|| DATA_TYPE( value ) == 0									\
+			|| strcmp( DATA_TYPE( value )->struct_name,  "TECS::" #Type "Pointer" ) ) \
+			mrb_raise(mrb, E_TYPE_ERROR, "not PointerType or unexpected PointerType"); \
+		if( len != -1 && ((struct Type ## PointerBody *)DATA_PTR( value ))->length < len ) \
+			mrb_raise(mrb, E_ARGUMENT_ERROR, "size_is too short");		\
+		return ((struct Type##PointerBody*)(DATA_PTR(value)))->buf;		\
+	}																	\
+																		\
+	type *CheckAndGet ## Type ## PointerNullable( mrb_state *mrb, mrb_value value, int32_t len ) \
+	{																	\
+		if( mrb_nil_p(value) )											\
+			return NULL;												\
+		return CheckAndGet ## Type ## Pointer( mrb, value, len );		\
+	}
+
+
+/*
+ * CHECK_AND_GET_CHAR_POINTER & CHECK_AND_GET_CHAR_POINTER_MOD are used 
+ * in case that the macro TECS_Use_MrbString_for_CharPointer is defined.
+ * This does not work as str_modify is static funcion.
+ */
+#define CHECK_AND_GET_CHAR_POINTER( Type, type )								\
+	type *CheckAndGet ## Type ## Pointer( mrb_state *mrb, mrb_value value, int32_t len ) \
+	{																	\
+		if( mrb_type(value) != MRB_TT_STRING )							\
+			mrb_raise(mrb, E_TYPE_ERROR, "not String Type");			\
+		if( len != -1 && RSTRING_LEN(value) < len )						\
+			mrb_raise(mrb, E_ARGUMENT_ERROR, "size_is too short");		\
+		return RSTRING_PTR(value);										\
+	}																	\
+																		\
+	type *CheckAndGet ## Type ## PointerNullable( mrb_state *mrb, mrb_value value, int32_t len ) \
+	{																	\
+		if( mrb_nil_p(value) )											\
+			return NULL;												\
+		return CheckAndGet ## Type ## Pointer( mrb, value, len );		\
+	}
+
+#define CHECK_AND_GET_CHAR_POINTER_MOD( Type, type )					\
+	type *CheckAndGet ## Type ## PointerMod( mrb_state *mrb, mrb_value value, int32_t len ) \
+	{																	\
+		char *ptr;														\
+		if( mrb_type(value) != MRB_TT_STRING )							\
+			mrb_raise(mrb, E_TYPE_ERROR, "not String Type");			\
+		str_modify(mrb,RSTRING(value));									\
+		if( len == -1 || RSTRING_LEN(value) < len )						\
+			mrb_raise(mrb, E_ARGUMENT_ERROR, "size_is too short");		\
+		ptr = RSTRING_PTR(value);										\
+		ptr[len] = '\0';												\
+		return (type *)ptr;												\
+	}																	\
+																		\
+	type *CheckAndGet ## Type ## PointerModNullable( mrb_state *mrb, mrb_value value, int32_t len ) \
+	{																	\
+		if( mrb_nil_p(value) )											\
+			return NULL;												\
+		return CheckAndGet ## Type ## Pointer( mrb, value, len );		\
+	}
+
+#define CHECK_AND_GET_POINTER_PROTO( Type, type )						\
+	type *CheckAndGet ## Type ## Pointer( mrb_state *mrb, mrb_value value, int32_t len ); \
+	type *CheckAndGet ## Type ## PointerNullable( mrb_state *mrb, mrb_value value, int32_t len )
+#define CHECK_AND_GET_POINTER_MOD_PROTO( Type, type )					\
+	type *CheckAndGet ## Type ## PointerMod( mrb_state *mrb, mrb_value value, int32_t len ); \
+	type *CheckAndGet ## Type ## PointerModNullable( mrb_state *mrb, mrb_value value, int32_t len )
+
+CHECK_AND_GET_POINTER_PROTO( Bool,  bool_t );		/* Bool pointer */
+CHECK_AND_GET_POINTER_PROTO( Double64, double64_t );/* Double64 pointer */
+CHECK_AND_GET_POINTER_PROTO( Float32, float32_t );	/* Float32 pointer */
+
+CHECK_AND_GET_POINTER_PROTO( Int8,  int8_t );		/* Int8 pointer */
+CHECK_AND_GET_POINTER_PROTO( Int16, int16_t );		/* Int16 pointer */
+CHECK_AND_GET_POINTER_PROTO( Int32, int32_t );		/* Int32 pointer */
+CHECK_AND_GET_POINTER_PROTO( Int64, int64_t );		/* Int64 pointer */
+CHECK_AND_GET_POINTER_PROTO( Int,   int );			/* Int pointer */
+CHECK_AND_GET_POINTER_PROTO( Short, short );		/* Short pointer */
+CHECK_AND_GET_POINTER_PROTO( Long,  long );			/* Long pointer */
+
+CHECK_AND_GET_POINTER_PROTO( UInt8,  uint8_t );		/* UInt8 pointer */
+CHECK_AND_GET_POINTER_PROTO( UInt16, uint16_t );	/* UInt16 pointer */
+CHECK_AND_GET_POINTER_PROTO( UInt32, uint32_t );	/* UInt32 pointer */
+CHECK_AND_GET_POINTER_PROTO( UInt64, uint64_t );	/* UInt64 pointer */
+CHECK_AND_GET_POINTER_PROTO( UInt,   unsigned int );/* UInt pointer */
+CHECK_AND_GET_POINTER_PROTO( UShort, unsigned short );	/* UShort pointer */
+CHECK_AND_GET_POINTER_PROTO( ULong,  unsigned long );	/* ULong pointer */
+
+#ifndef TECS_Use_MrbString_for_CharPointer
+CHECK_AND_GET_POINTER_PROTO( Char,  char_t );		/* Char pointer */
+CHECK_AND_GET_POINTER_PROTO( SChar,  char_t );		/* SChar pointer */
+//CHECK_AND_GET_POINTER_PROTO( SChar,  schar_t );		/* SChar pointer */
+CHECK_AND_GET_POINTER_PROTO( UChar,  uint8_t );		/* UChar pointer */
+//CHECK_AND_GET_POINTER_PROTO( UChar,  uchar_t );		/* UChar pointer */
+#define CheckAndGetCharPointerMod	CheckAndGetCharPointer
+#define CheckAndGetSCharPointerMod	CheckAndGetSCharPointer
+#define CheckAndGetUCharPointerMod	CheckAndGetUCharPointer
+#define CheckAndGetCharPointerModNullable	CheckAndGetCharPointerNullable
+#define CheckAndGetSCharPointerModNullable	CheckAndGetSCharPointerNullable
+#define CheckAndGetUCharPointerModNullable	CheckAndGetUCharPointerNullable
+#else
+CHECK_AND_GET_POINTER_PROTO( Char,  char_t );		/* Char pointer */
+CHECK_AND_GET_POINTER_PROTO( SChar,  char_t );		/* SChar pointer */
+CHECK_AND_GET_POINTER_PROTO( UChar,  uint8_t );		/* UChar pointer */
+CHECK_AND_GET_POINTER_MOD_PROTO( Char,  char_t );	/* Char pointer */
+CHECK_AND_GET_POINTER_MOD_PROTO( SChar,  char_t );	/* SChar pointer */
+CHECK_AND_GET_POINTER_MOD_PROTO( UChar,  uint8_t );	/* UChar pointer */
+#endif /* TECS_Use_MrbString_for_CharPointer */
+
+#define GET_SET_BOOL( Type, TYPE )										\
+	static mrb_value													\
+	Type ## Pointer_aget(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self );		\
+		mrb_int	subscript;												\
+		TYPE	val;													\
+																		\
+		mrb_get_args(mrb, "i", &subscript );							\
+		if( subscript < 0 || subscript >= pointerBody->length )			\
+			mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (get)"); \
+		val = pointerBody->buf[ subscript ];							\
+		VALCHECK_MRB_ ## Type( mrb, val );								\
+		return val ? mrb_true_value() : mrb_false_value();				\
+	}																	\
+																		\
+	static mrb_value													\
+	Type ## Pointer_aset(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self ); 	\
+		mrb_int	subscript;												\
+		mrb_value	val;													\
+																		\
+		mrb_get_args(mrb, "io", &subscript, &val );						\
+																		\
+		if( subscript < 0 || subscript >= pointerBody->length )			\
+			mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (set)"); \
+		pointerBody->buf[ subscript ] = mrb_test( val );				\
+																		\
+		return self;													\
+	}																	\
+																		\
+	static mrb_value													\
+	Type ## Pointer_get_val(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self );		\
+		TYPE	val;													\
+																		\
+		val = *pointerBody->buf;										\
+		VALCHECK_MRB_ ## Type( mrb, val );								\
+		return val ? mrb_true_value() : mrb_false_value();				\
+	}																	\
+																		\
+	static mrb_value													\
+	Type ## Pointer_set_val(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self ); 	\
+		mrb_value	val;												\
+																		\
+		mrb_get_args(mrb, "o", &val );									\
+																		\
+		*pointerBody->buf = mrb_test( val );							\
+		return self;													\
+	}
+
+#define GET_SET_CHAR( Type, TYPE )		GET_SET_INT( Type, TYPE )
+#define GET_SET_INT( Type, TYPE )										\
+	static mrb_value													\
+	Type ## Pointer_aget(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self );		\
+		mrb_int	subscript;												\
+		TYPE	val;													\
+																		\
+		mrb_get_args(mrb, "i", &subscript );							\
+		if( subscript < 0 || subscript >= pointerBody->length )			\
+			mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (get)"); \
+		val = pointerBody->buf[ subscript ];							\
+		VALCHECK_MRB_ ## Type( mrb, val );								\
+		return mrb_fixnum_value( val );									\
+	}																	\
+																		\
+	static mrb_value													\
+	Type ## Pointer_aset(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self ); 	\
+		mrb_int	subscript;												\
+		mrb_int	val;													\
+																		\
+		mrb_get_args(mrb, "ii", &subscript, &val );						\
+																		\
+		if( subscript < 0 || subscript >= pointerBody->length )			\
+			mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (set)"); \
+		VALCHECK_ ## Type ( mrb, val );									\
+		pointerBody->buf[ subscript ] = val;							\
+																		\
+		return self;													\
+	}																	\
+																		\
+	static mrb_value													\
+	Type ## Pointer_get_val(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self );		\
+		TYPE	val;													\
+																		\
+		val = *pointerBody->buf;										\
+		VALCHECK_MRB_ ## Type( mrb, val );								\
+		return mrb_fixnum_value( val );									\
+	}																	\
+																		\
+	static mrb_value													\
+	Type ## Pointer_set_val(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self ); 	\
+		mrb_int	val;													\
+																		\
+		mrb_get_args(mrb, "i", &val );									\
+																		\
+		VALCHECK_ ## Type ( mrb, val );									\
+		*pointerBody->buf = val;										\
+																		\
+		return self;													\
+	}
+
+#define GET_SET_FLOAT( Type, TYPE )										\
+	static mrb_value													\
+	Type ## Pointer_aget(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self );		\
+		mrb_int	subscript;												\
+																		\
+		mrb_get_args(mrb, "i", &subscript );							\
+		if( subscript < 0 || subscript >= pointerBody->length )			\
+			mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (get)"); \
+		return mrb_float_value( mrb, pointerBody->buf[ subscript ] );   \
+	}																	\
+																		\
+	static mrb_value													\
+	Type ## Pointer_aset(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self ); 	\
+		mrb_int	subscript;												\
+		mrb_float	val;												\
+																		\
+		mrb_get_args(mrb, "if", &subscript, &val );						\
+																		\
+		if( subscript < 0 || subscript >= pointerBody->length )			\
+			mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (set)"); \
+		pointerBody->buf[ subscript ] = val;							\
+																		\
+		return self;													\
+	}																	\
+																		\
+	static mrb_value													\
+	Type ## Pointer_get_val(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self );		\
+																		\
+		return mrb_float_value( mrb, *pointerBody->buf );               \
+	}																	\
+																		\
+	static mrb_value													\
+	Type ## Pointer_set_val(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self ); 	\
+		mrb_float	val;												\
+																		\
+		mrb_get_args(mrb, "f", &val );									\
+																		\
+		*pointerBody->buf = val;										\
+																		\
+		return self;													\
+	}
+
+////  define Pointer classes ////
+#define POINTER_CLASS( Type, TYPE )										\
+																		\
+	static void															\
+	Type ## PointerBody_free( mrb_state *mrb, void *p )					\
+	{																	\
+		(void)mrb_free( mrb, p );										\
+	}																	\
+																		\
+	struct mrb_data_type Type ## PointerBody_mrb_data_type =			\
+		{																\
+			"TECS::" #Type "Pointer",									\
+			Type ## PointerBody_free									\
+		};																\
+																		\
+	static mrb_value													\
+	Type ## Pointer_initialize( mrb_state *mrb, mrb_value self)			\
+	{																	\
+		mrb_int	length;													\
+		struct Type ## PointerBody *pointerBody;						\
+																		\
+		mrb_get_args(mrb, "i", &length );								\
+		if( length < 0 )												\
+			mrb_raise(mrb, E_INDEX_ERROR, "negative length");			\
+		DATA_TYPE( self ) = &Type ## PointerBody_mrb_data_type;			\
+		pointerBody = (struct Type ## PointerBody *)mrb_malloc(mrb, sizeof(struct Type ## PointerBody) + length * sizeof( TYPE ) ); \
+		pointerBody->length = length;									\
+		DATA_PTR( self ) = (void *)pointerBody;							\
+						 												\
+		return self;													\
+	}																	\
+																		\
+	static mrb_value													\
+	Type ## Pointer_size(mrb_state *mrb, mrb_value self)				\
+	{																	\
+		struct Type ## PointerBody *pointerBody = DATA_PTR( self );		\
+																		\
+		return mrb_fixnum_value( pointerBody->length );					\
+	}																	\
+																		\
+	struct RClass *														\
+	tecs_init_## Type ## Pointer(mrb_state *mrb, struct RClass *TECS)	\
+	{																	\
+		struct RClass *a;												\
+																		\
+		a = mrb_define_class_under(mrb, TECS, #Type "Pointer", mrb->object_class); \
+		MRB_SET_INSTANCE_TT(a, MRB_TT_DATA);							\
+																		\
+		mrb_define_method(mrb, a, "initialize",      Type ## Pointer_initialize,   MRB_ARGS_REQ(1)); \
+		mrb_define_method(mrb, a, "[]",              Type ## Pointer_aget,         MRB_ARGS_REQ(1)); \
+		mrb_define_method(mrb, a, "value",           Type ## Pointer_get_val,      MRB_ARGS_NONE()); \
+		mrb_define_method(mrb, a, "[]=",             Type ## Pointer_aset,         MRB_ARGS_REQ(2)); \
+		mrb_define_method(mrb, a, "value=",          Type ## Pointer_set_val,      MRB_ARGS_REQ(1)); \
+		mrb_define_method(mrb, a, "size",            Type ## Pointer_size,         MRB_ARGS_NONE()); \
+		mrb_define_method(mrb, a, "length",          Type ## Pointer_size,         MRB_ARGS_NONE()); \
+		return	a;														\
+	}
+
+static inline mrb_value
+CharPointer_to_s( mrb_state *mrb, mrb_value self )
+{
+	struct CharPointerBody *pointerBody = DATA_PTR( self );
+	return mrb_str_new( mrb, pointerBody->buf, strnlen( pointerBody->buf, pointerBody->length ) );
+}
+
+static inline mrb_value
+CharPointer_from_s( mrb_state *mrb, mrb_value self )
+{
+	mrb_value str;
+	struct CharPointerBody *pointerBody = DATA_PTR( self );
+
+	mrb_get_args(mrb, "o", &str );
+	if( mrb_type( str ) != MRB_TT_STRING ){
+		mrb_raise(mrb, E_ARGUMENT_ERROR, "Not String");
+	}
+
+	strncpy( pointerBody->buf, RSTRING_PTR(str), pointerBody->length );
+	return self;
+}
+
+/* Initialize TECSPointer classes */
+void	init_TECSPointer( mrb_state *mrb, struct RClass *TECS );
+
+#endif /* TECSPointer_h__ */
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/TECSStruct.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/TECSStruct.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/TECSStruct.h	(revision 398)
@@ -0,0 +1,141 @@
+/*
+ *  mruby => TECS brige
+ *  
+ *   Copyright (C) 2008-2012 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$ 
+ */
+
+#ifndef TECSStruct_h__
+#define TECSStruct_h__
+
+#define MEMBER_GET_SET_INT( TAG, MEMBER, Type, TYPE )					\
+	static mrb_value													\
+	Struct_ ## TAG ## _ ## MEMBER ## _aget(mrb_state *mrb, mrb_value self)	\
+	{																	\
+		struct TAG *st = DATA_PTR( self );								\
+		TYPE ## _t	val;												\
+																		\
+		val = st->MEMBER;												\
+		VALCHECK_MRB_ ## Type( mrb, val );								\
+		return mrb_fixnum_value( val );									\
+	}																	\
+																		\
+	static mrb_value													\
+	Struct_ ## TAG ## _ ## MEMBER ## _aset(mrb_state *mrb, mrb_value self)	\
+	{																	\
+		struct TAG *st = DATA_PTR( self );								\
+		mrb_int	val;													\
+																		\
+		mrb_get_args(mrb, "i", &val );									\
+																		\
+		VALCHECK_ ## Type ( mrb, val );									\
+		st->MEMBER = val;												\
+																		\
+		return self;													\
+	}
+
+#define MEMBER_GET_SET_FLOAT( TAG, MEMBER )								\
+	static mrb_value													\
+	Struct_ ## TAG ## _ ## MEMBER ## _aget(mrb_state *mrb, mrb_value self)	\
+	{																	\
+		struct TAG *st = DATA_PTR( self );								\
+																		\
+		return mrb_float_value( mrb, st->MEMBER );                      \
+	}																	\
+																		\
+	static mrb_value													\
+	Struct_ ## TAG ## _ ## MEMBER ## _aset(mrb_state *mrb, mrb_value self)	\
+	{																	\
+		struct TAG *st = DATA_PTR( self );								\
+		mrb_float	val;												\
+																		\
+		mrb_get_args(mrb, "f", &val );									\
+																		\
+		st->MEMBER = val;												\
+																		\
+		return self;													\
+	}
+
+////  define Struct class ////
+#define STRUCT_CLASS( TAG )												\
+																		\
+	static void															\
+	Struct ## TAG ## Body_free( mrb_state *mrb, void *p )				\
+	{																	\
+		(void)mrb_free( mrb, p );										\
+	}																	\
+																		\
+	struct mrb_data_type Struct ## TAG ## Body_mrb_data_type =			\
+		{																\
+			"TECS::Struct" #TAG,										\
+			Struct ## TAG ## Body_free									\
+		};																\
+																		\
+	static mrb_value													\
+	Struct_ ## TAG ## _initialize( mrb_state *mrb, mrb_value self)		\
+	{																	\
+																		\
+		DATA_TYPE( self ) = &Struct ## TAG ## Body_mrb_data_type;		\
+		DATA_PTR( self ) = mrb_malloc(mrb, sizeof(struct TAG)); 		\
+						 												\
+		return self;													\
+	}
+
+#define  STRUCT_INIT_BEGIN( TAG )										\
+	struct RClass *														\
+	tecs_init_Struct_## TAG(mrb_state *mrb, struct RClass *TECS)		\
+	{																	\
+		struct RClass *a;												\
+																		\
+		a = mrb_define_class_under(mrb, TECS, "Struct" #TAG, mrb->object_class); \
+		MRB_SET_INSTANCE_TT(a, MRB_TT_DATA);							\
+																		\
+		mrb_define_method(mrb, a, "initialize", Struct_ ## TAG ## _initialize,            MRB_ARGS_NONE());
+
+#define  STRUCT_INIT_MEMBER( TAG, MEMBER )								\
+		mrb_define_method(mrb, a, #MEMBER,      Struct_ ## TAG ## _ ## MEMBER ## _aget,   MRB_ARGS_NONE()); \
+		mrb_define_method(mrb, a, #MEMBER "=",  Struct_ ## TAG ## _ ## MEMBER ## _aset,   MRB_ARGS_REQ(1));
+
+
+#define  STRUCT_INIT_END( TAG )											\
+	}
+
+#define CHECK_STRUCT( tag, value )										\
+	do {																\
+		if( mrb_type(value) != MRB_TT_DATA								\
+			|| DATA_TYPE( value ) == 0									\
+			|| strcmp( DATA_TYPE( value )->struct_name, "TECS::Struct" #tag ) ) \
+			mrb_raise(mrb, E_TYPE_ERROR, "not Struct or tag mismatch"); \
+	}while(0)
+
+#endif /* TECSStruct_h__ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mruby.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mruby.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mruby.cdl	(revision 398)
@@ -0,0 +1,40 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+import_C( "tecs_mruby.h" );
+
+import( <mrubyInitializer.cdl> );
+import( <mrubyPointers.cdl> );
+import( <mrubyVMs.cdl> );
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyBridge.txt
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyBridge.txt	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyBridge.txt	(revision 398)
@@ -0,0 +1,366 @@
+MrubyBridgePlugin に関するメモ
+										2012年11月 7日　初版作成
+										2013年 5月26日　見直し
+                                                        大山　博司
+
+【概要】
+
+MrubyBridgePlugin は、TECS CDL の signature 記述に基づき、mruby と TECS 
+コンポーネントをブリッジする、mruby の C 言語実装クラスであり TECS のセ
+ルタイプとなるコンポーネントを生成する、TECS のシグニチャプラグインであ
+る。
+
+【構造】
+
+         +--------------------------+              +-------------------+
+         |     (ブリッジセル)         |              |    (目的セル)      |
+         |                          |              |                   |
+mruby    | nMruby::tsSignatureBridge|  sSignature  |  tTargetCelltype  |
+ - - - > |       BridgeCell         |--------------|>   TargetCell     |
+         |                          |cTECS    eTest|                   |
+         | mruby クラス：            |              |                   |
+         |  TECS::TSignatureBridge  |              |                   |
+         +--------------------------+              +-------------------+
+
+MrubyBridgePlugin は、mruby から TECS へブリッジをするセルタイプを生成
+する。mruby=>TECS をブリッジするセルは、そのセルタイプのセルとして、プ
+ラグインの利用者が CDL 内に設置し、mruby から操作したいセル、すなわち
+目的セルに結合する。
+
+このセルタイプは、mruby のクラスの定義を行い、ブリッジセルを mruby の
+インスタンスとして取り扱えるようにし、mruby のインスタンスメソッドの呼
+び出しに応じて、目的セルの受け口関数を呼び出す働きを持つ。
+
+【簡単な使用例】
+
+簡単な使用例は、SimpleSample.cdl および SimpleSample.rb にある。
+MrubyBrigePlugin はシグニチャプラグインであり、シグニチャプラグインの
+使用方法を理解していれば、これらのソースファイルのコメントを参照するこ
+とで、MrubyBrigePlugin の大よその使い方は理解できるはずである。
+以下の方法で、ビルドおよび実行できる。
+
+   % make                             # mruby 本体のビルド (.a を作成)
+   % cd MrubyBridge                   # MrubyBridge へ移動
+   % make                             # ビルド
+   % ./mruby-Sample SimpleSample.rb   # 実行
+
+【Makefile の構成】
+
+tecsgen により生成される gen/Makefile.templ に対し、以下の変更を加える必要があ
+る。
+
+・gen/Makefile.temp は、一つ上のディレクトリへ Makefile という名前で置
+  けば、cygwin などの POSIX 環境で試験実行する場合には、無調整で使用で
+  きるように生成される(ただし gnu make を使用する)
+・tSysLog を使う場合、リロケータブルオブジェクトを追加 (下行参照)
+   OTHER_OBJS = $(_TECS_OBJ_DIR)vasyslog.o
+
+【データ型】
+
+MrubyBridgePlugin は、以下の TECS の型を扱うことができる (制限される)。
+この制限は、MrubyBridgePlugin を適用しようとするシグニチャに対するものであり、
+それ以外へ制限がおよぶものではない。
+
+ スカラー型			bool_t, char_t, intN_t, double64_t, float32_t
+									(N=8,16,32,64)
+					int, short, long, char (TECS 非推奨の型)
+
+ ポインタ型			bool_t*, char_t*, intN_t*, double64_t*, float32_t*
+					int*, short*, long*, char*
+					構造体型へのポインタ（構造体型と同じ制限あり）
+
+                    これらは、ポインタの指している先の値を扱うためのも
+                    のである。ポインタ値(アドレス)を渡したい場合には、
+                    これらを使用できない。代わりに intptr_t, uintptr_t 
+                    を使用する。
+
+ 					size_is, string 指定子あり/なしのいずれも扱える。
+					ただし構造体型へのポインタに size_is 指定されたも
+					のは扱えない。(仕様書に明言されていないが構造体ポ
+					インタの string は、元々サポートされない)
+
+					string の長さ指定がない場合、in 引数に対してのみ用
+					いることができる。
+
+ 構造体型			メンバは、スカラー型でなくてはならない
+
+ typedef型          上記のスカラー型、構造体型、ポインタ型の typedef 
+                    された型を扱うことができる。元の型として扱われる。
+					このためポインタ型や構造体型の場合、元の型名により
+					これらを扱うための mruby クラスを指定する。
+
+【対応する mruby の型(クラス)】
+
+  bool_t			true または false。
+					mruby で false と見なされるもの(false または nil) 
+					を C の false として扱う。mruby で false と見なさ
+					れないものを C の true として扱う。整数値 0 は、
+					mruby では false とは見なされない。
+  char_t			FIXNUM  (値は 0..255)		
+  schar_t			FIXNUM  (値は -128..127)		
+  uchar_t			FIXNUM  (値は 0..255)		
+  intN_t			FIXNUM
+  uintN_t			FIXNUM
+  double64_t		FLOAT (mruby の FLOAT が double か float かは実装
+                          による)
+  float32_t			FLOAT
+  int				FIXNUM
+  short				FIXNUM
+  long				FIXNUM
+  char				FIXNUM  (char_t と同じ)
+
+・TECS 専用のクラスを用いるもの
+
+  bool_t*			TECS::BoolPointer
+  char_t*			TECS::CharPointer
+  uchar_t*			TECS::UCharPointer
+  schar_t*			TECS::SCharPointer
+  intN_t*			TECS::IntNPointer   N:8,16,32,64
+  uintN_t*			TECS::UIntNPointer  N:8,16,32,64
+  float32_t*		TECS::Float32Pointer
+  double64_t*		TECS::Double64Pointer
+  int*				TECS::IntPointer
+  short*			TECS::ShortPointer
+  long*				TECS::LongPointer
+  char*				TECS::CharPointer  (char_t* と同じ)
+
+  struct TAG		TECS:TECSStructTAG
+  struct TAG*		TECS:TECSStructTAG
+                    TAG の部分は、構造体のタグ名に置き換える。関数への
+                    引数として、構造体を渡すか、構造体へのポインタを渡
+                    すかは、プラグインが自動で判定する。TAG 名を付けて
+                    いない構造体を扱うことはできない。typedef した名前
+                    で構造体を扱うことはできない。
+
+・その他
+
+  void * は扱えない
+  intptr_t は、通常 stdint.h で typedef されているが、元の型として扱う
+
+プラグイン引数として ignoreUnsigned=true を指定すると、無符号整数型へ
+のポインタ型を有符号整数型のポインタ型として扱う（値の範囲チェックを含
+む）。ポインタを扱うクラスのメモリ使用量を抑えること、有符号、無符号の
+使い分けをルーズにすることができる。
+
+ビルド時のオプション (C 言語のマクロ定義) TECS_NO_VAL_CHECK を指定する
+ことで、値の範囲チェックを行わないようにすることができる。
+
+【関数名】
+
+・関数名に関数する制限
+
+  関数名 initialize は ruby で既定のメソッド名と重複するため、initialize_cell
+ に置換される。
+
+  initialize と initialize_cell の両方が signature 内に存在する場合、エラーと
+  なる。エラーを解消するには、少なくとも一方の名前を変更する必要がある。
+
+【戻り値】
+
+戻り値で扱えるのは、以下の型に限られる。
+
+   void, bool_t, char_t, intN_t, float32_t, double64_t
+   int, short, long, char
+   元の型が、これらである typedef された型
+
+【引数】
+
+・順序の通り対応する mruby の型（クラス）の値を引数として渡す
+・指定可能な基本指定子  in, inout, out  (send/receive は不可)
+・例外の発生
+  ・整数の値が、引数の型の範囲を超えている場合、例外を発生する。
+    無符号型の場合、負の値を取ることはできない。ただし、mrb_int と同じ
+    またはそれ以上のサイズの場合には、負の値が指定されても例外とはしな
+    い。さもないと最上位ビットが 1 の値を入力できないため。
+    char_t (char) は無符号と見なされる。
+    なお uintptr_t に 0x80000000 にを渡す際に RangeError 例外が発生す
+    るが、これは mruby によるものであり、TECS による制限ではない
+  ・ポインタ型や構造体型に対応する mruby の型(クラス) と一致しない
+  ・size_is, string のサイズが小さい
+
+【参考】
+
+ TECSPointer.txt
+
+  以下の mruby クラス、すなわち TECS のポインタ値を扱うためのクラスに
+  ついての説明。
+　これらのクラスは必要に応じて生成される。引数として使用されていないク
+  ラスは生成されない。
+
+  TECS::Int8Pointer,   TECS::Int16Pointer,   TECS::Int32Pointer
+  TECS::Int64Pointer,  TECS::UInt64Pointer
+  TECS::UInt8Pointer,  TECS::UInt16Pointer,  TECS::UInt32Pointer
+  TECS::CharPointer,   TECS::SCharPointer,   TECS::UCharPointer
+  TECS::IntPointer,    TECS::ShortPointer,   TECS::LongPointer
+  TECS::UIntPointer,   TECS::UShortPointer,  TECS::ULongPointer
+  TECS::BoolPointer,   TECS::Float32Pointer, TECS::Double64Pointer
+
+ TECSStruct.txt
+
+  以下の mruby クラス、すなわち TECS の構造体（ポインタ）値を扱うため
+  のクラスについての説明。
+
+  TECS::StructTAG
+
+【TECS CDLによる記述】
+
+ ブリッジプラグインにより、ブリッジセルタイプが自動生成される。
+ ブリッジセルは、CDL に記述して設置する必要がある
+
+・ブリッジプラグインの呼出し
+
+mruby=>TECS ブリッジプラグインは、シグニチャプラグインである。CDL 上の以下のよ
+うな記述により、mruby=>TECS ブリッジプラグインを呼び出す。
+
+  ex)
+    generate( MrubyBridgePlugin, sSignature, "" );
+
+ シグニチャ sSignature は、この記述よりも前に定義されていなくてはならない。
+ この generate の記述により、次のようなブリッジセルタイプが生成される。
+
+generate の第3引数は、プラグイン引数（オプション）である。
+
+  ignoreUnsigned   true を指定すると無符号整数へのポインタ型に有符号のポ
+                   インタクラスを使用する（メモリを節約できる）
+                   デフォルトは false である。
+  include          ブリッジに含める関数を指定する。exclude と同時指定不可。
+  exclude          ブリッジに含める関数を指定する。include と同時指定不可。
+
+  ex)
+    generate( MrubyBridgePlugin, sSignature, "exclude=fun99" );
+
+多くの関数を指定する場合、以下のように、分割した文字列の連接として師定
+することができます。
+
+  ex)
+    generate( MrubyBridgePlugin, sSignature,
+        "ignoreUnsigned=true, "
+        "include='func1,func2', "
+        "include='func3,func4', "
+     );
+
+・ブリッジセルタイプ
+
+ ブリッジセルタイプは、ネームスペース nMruby の下に作られる。ブリッジ
+セルタイプの名前は、シグニチャ名に 't' を前置きしたものである。以下は、
+ブリッジプラグインにより自動生成されるセルタイプのコードの例である。シ
+グニチャ sSignature に対するブリッジセルタイプ名は tsSignature であり、
+呼び口cTECS を持つ。
+
+  ex) 自動生成される CDL コード（内部で生成され、解釈される）
+
+   namespace nMruby {
+     celltype SSignature{
+       call sSignature cTECS;
+     };
+   };
+
+・ブリッジセルの設置
+
+ ブリッジセルは、ブリッジセルタイプのセルとして生成する。ブリッジセル
+ の設置は CDL の記述者が行うものである。ブリッジセルの呼び口 cTECS を 
+ mRuby から呼び出したいセルへ結合する。
+
+  ex) ブリッジセルを設置する CDL 記述
+
+   cell nMruby::tsSignature BridgeCell {
+     cTECS = Cell.eEnt;
+   };
+
+  ex) ブリッジセルを設置する CDL 記述(VM 名指定あり)
+
+   cell nMruby::tsSignature BridgeCell {
+     cTECS = Cell.eEnt;
+	 VMname = "VM2";
+   };
+
+  VMname は mruby VM のセルの名前の指定である。VMname を指定しない場合、
+  "VM" が仮定される。VMname は、実際には、VM_TECSInitializer などのよ
+  うに、ブリッジを登録するセルの、セル名に用いられる。tecsgen 実行時に
+  以下のようなメッセージが出力される。受け口 
+  VM_TECSInitializer.eInitialize へ VM の初期化用呼び口から結合する。
+
+   MrubyBridgePlugin: join your VMs cInitialize to VM_TECSInitializer.eInitialize
+
+【mruby コード】
+
+ ブリッジプラグインが適用されたシグニチャに対応する mruby クラスが生成
+ される。これをブリッジクラスと呼ぶ。
+ ブリッジクラスを通してセルの受け口関数を呼び出すことができる。
+
+・ブリッジクラス
+
+ ブリッジクラスは、モジュール TECS の下に作成される。ブリッジクラスの
+ 名前は、シグニチャ名に 'T' を前置きしたものとなる。
+
+ ex)  TECS::TsSignature
+
+・ブリッジのインスタンス
+
+  ブリッジクラスにて、ブリッジセル名を引数として new することで、ブリッ
+  ジクラスのインスタンスが生成される。ブリッジクラスのインスタンスのこ
+  とを、短かくブリッジのインスンタンスとも呼ぶ。ブリッジのインスタンス
+  は、ブリッジセルへのポインタ情報を保持するだけである。同一のブリッジ
+  のインスタンスは何度でも生成することができる。
+
+ ex)  brdige = TECS::TsSignature.new( "CellName" )
+
+【残課題】
+
+[済] 整数型の unsigned の扱い
+   キャストをしているので、コンパイルは警告なく通る。
+   値の範囲チェックと整合していない。
+   以下を新たに設けるか。
+   UInt8Pointer, UInt16Pointer, UInt32Pointer, UInt64Pointer
+   UIntPointer, UShortPointer, ULongPointer, UCharPointer, SCharPointer, 
+
+[済] 値の範囲のチェック
+   TECSPointer, TECSStruct では整数値を設定する際に、範囲チェックがある。
+   メソッドへの直接の引数はチェックされない。
+
+[済] 現状の so としての実装はおかしい
+   静的に mruby の本体が結合されている。
+
+[済] ポインタ型を扱うクラスが多すぎる
+   使用するクラスだけロードされ、初期化される仕組みが欲しい。
+
+・以下の方法でブリッジを割り付けているが、
+    bridge = TsSample.new( "SimpleBridge" )
+　以下のように、定数として扱うことができる方がスマートである。
+    bridge = TECS::SimpleBridge
+  (現状の方が、ブリッジのセルタイプがわかる点が優れている)
+  ⇒ もし定数として扱うとして、割付けを C で行うか ruby コードで行うか
+     の違いでしかない。以下にあるラッパークラスにより定数の初期化を行
+     えばよい。
+  ⇒ 定数として扱うと、オブジェクトが最初から最後まで消えないという問
+     題がある(それでも少量であるが)
+
+・上記に関連して、VM が異なる場合に、他の VM に割り付けたブリッジ名が
+  見えてしまう。アクセス制限が十分でない。
+  ブリッジ名のアクセス制限を実現するには、VM を識別する情報が必要にな
+  る。mrb_state に p_cellcb を加える方法、mrb_state自身で区別する方法
+  が考えられる。要検討。
+  なお、セルタイプ単位でのアクセス制 限はできている(てきていないのは、
+  同じセルタイプで複数のブリッジセルがある場合に、ブリッジ名のアクセス
+  制限)。
+
+・typedef された型名でアクセスできると便利である
+  TECSPointer や TECSStruct のクラスに対する alias により、別名として
+  アクセスできるとよい。
+   ⇒ とりあえず、MrubyBridgePlugin のメッセージとしてわかるようにした。
+
+・send/receive への対応
+  mruby と共通のアロケータを指定可能とする (アロケータコンバータプラグインを新規に設けては?)
+
+・構造体メンバーの型制限の緩和
+   strign or size_is 指定された char* など
+
+・ruby らしいプログラムから mruby ⇒ TECS ブリッジのクラスへの自動変換するラッパークラスの生成
+  (ruby's Array => TECS::Pointer, ruby's Struct => TECS::StructTAG)
+
+[済]ブリッジクラスの new でセルが見つからなかった場合、ruby 例外を発生させる。
+  これを free する段階で SEGV が発生するため DATA_SET を早めに行うように変更。
+  なお、各メソッドの関数で DATA_PTR が null かどうかをチェックしないが、
+  例外が発生したことにより不完全なブリッジは変数に記憶されない（はず）
+  ため、問題ない。
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyInitializer.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyInitializer.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyInitializer.cdl	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+namespace nMruby{
+
+	signature sInitializeBridge {
+		void initializeBridge( [in]const mrb_state *mrb );
+	};
+
+	signature sInitializeTECSBridge {
+		void initializeBridge( [inout]mrb_state *mrb, [inout]struct RClass *TECS );
+	};
+
+	// tTECSInitializer creates classes under "TECS" module in mruby VM
+	celltype tTECSInitializer {
+		entry sInitializeBridge eInitialize;
+		call  sInitializeTECSBridge cInitialize[];
+		var{
+			struct RClass *TECS = 0;
+		};
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyPointers.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyPointers.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyPointers.cdl	(revision 398)
@@ -0,0 +1,70 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+// Pointer celltypes
+
+namespace nMruby {
+	// Pointer to Bool
+	[singleton]celltype tBoolPointer	 {	entry  sInitializeTECSBridge eInitialize; };
+
+	// Pointer to Chars
+	[singleton]celltype tCharPointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tSCharPointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tUCharPointer	 {	entry  sInitializeTECSBridge eInitialize; };
+
+	// Pointer to Signed Integers
+	[singleton]celltype tInt8Pointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tInt16Pointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tInt32Pointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tInt64Pointer	 {	entry  sInitializeTECSBridge eInitialize; };
+
+	// Pointer to Unsigned Integers
+	[singleton]celltype tUInt8Pointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tUInt16Pointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tUInt32Pointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tUInt64Pointer	 {	entry  sInitializeTECSBridge eInitialize; };
+
+	// Pointer to Floating types
+	[singleton]celltype tFloat32Pointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tDouble64Pointer	 {	entry  sInitializeTECSBridge eInitialize; };
+
+	// Pointer to Integers (unrecommended)
+	[singleton]celltype tIntPointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tShortPointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tLongPointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tUIntPointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tUShortPointer	 {	entry  sInitializeTECSBridge eInitialize; };
+	[singleton]celltype tULongPointer	 {	entry  sInitializeTECSBridge eInitialize; };
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyTECSPointer.txt
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyTECSPointer.txt	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyTECSPointer.txt	(revision 398)
@@ -0,0 +1,106 @@
+TECS::Int8Pointer       TECS::UInt8Pointer
+TECS::Int16Pointer      TECS::UInt16Pointer
+TECS::Int32Pointer      TECS::UInt32Pointer
+TECS::Int64Pointer      TECS::UInt64Pointer
+TECS::CharPointer       TECS::SCharPointer      TECS::UCharPointer
+TECS::IntPointer	    TECS::UIntPointer
+TECS::ShortPointer	    TECS::UShortPointer
+TECS::LongPointer       TECS::ULongPointer
+TECS::BoolPointer
+TECS::Float32Pointer
+TECS::Double64Pointer
+
+TECS のポインタ型の整数データ、浮動小数点データ、文字データを扱うため
+の記憶域を扱います。これらのクラスは、シグニチャで使用されているものを 
+MrubyBridgePlugin プラグインが自動判別して生成します。
+
+ポインタ値そのものを渡すには intptr_t 型として渡すのが妥当です。
+
+C 言語の型とは、以下のように対応します。
+
+   int8_t                 TECS::Int8Pointer
+   int16_t                TECS::Int16Pointer
+   int32_t                TECS::Int32Pointer
+   int64_t                TECS::Int64Pointer
+   char_t                 TECS::CharPointer
+   schar_t                TECS::SCharPointer
+   uchar_t                TECS::UCharPointer
+   uint8_t                TECS::UInt8Pointer
+   uint16_t               TECS::UInt16Pointer
+   uint32_t               TECS::UInt32Pointer
+   uint64_t               TECS::UInt64Pointer
+   bool_t                 TECS::BoolPointer
+   float32_t              TECS::Float32Pointer
+   double64_t             TECS::Double64Pointer
+
+ 非推奨の型
+   char                   TECS::CharPointer
+   int                    TECS::IntPointer
+   short                  TECS::ShortPointer
+   long                   TECS::LongPointer
+   signed char            TECS::SCharPointer
+   unsigned char          TECS::UCharPointer
+   unsigned int           TECS::UIntPointer
+   unsigned short         TECS::UShortPointer
+   unsigned long          TECS::ULongPointer
+   float                  TECS::Float32Pointer
+   double                 TECS::Double64Pointer
+
+char, signed char, unsgined char は char_t, schar_t, uchar_t と見なされます。
+
+【備考】
+ターゲット環境において char, singed char, unsigned char のサイズが 1 バイトでは無い場合には、相違が生じる。
+
+== スーパークラス ==
+
+Object
+
+== クラスメソッド ==
+
+new( size )
+
+  size の大きさを持つ記憶域を指すポインタを生成して返します。
+  size の単位は、要素の個数です。
+
+== メソッド ==
+
+self[ nth ]
+
+  nth 番目の要素を返します。nth は 0..(length-1) の整数です。
+  '=' の左辺では、nth 番目の要素を右辺の値に置き換えます。
+
+  nth に整数または浮動小数以外を渡した場合、例外が発生します。
+
+self[ nth ] = val
+
+  整数型のポインタの場合、値の範囲がチェックされます。
+  val の値が範囲を超える場合、例外が発生します。
+
+value
+
+  ポインタの指す先の値を取り出します。
+  self[0] と同じです。
+
+value = val
+
+  ポインタの指す先に値を設定します。
+  self[0] = val と同じです。
+
+length
+size
+
+  ポインタが指す要素の個数を返します。
+
+to_s
+
+  CharPointer クラスでのみ使用できます。
+  mruby の String クラスのインスタンスに変換して返します。
+
+from_s
+
+  CharPointer クラスでのみ使用できます。
+  mruby の文字列から CharPointer の指す記憶域に文字列をコピーします。
+  
+  new の際に確保された記憶域が用いられます。記憶域の大きさが文字列よりも短い場合には、記憶域の大きさに収まるようにコピーされます。
+  記憶域よりも文字列が長い場合、記憶域の末尾に終端文字 '\0' は置かれません。
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyTECSStruct.txt
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyTECSStruct.txt	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyTECSStruct.txt	(revision 398)
@@ -0,0 +1,24 @@
+TECS::StructTAG
+
+  C 言語の構造体を扱うためのクラスであり、signature に現れる構造体に合わせて MrubyBridgePlugin により生成されます。
+  TAG の部分は、構造体のタグ名に置き換えます。
+
+== スーパークラス ==
+
+Object
+
+== クラスメソッド ==
+
+new()
+
+== メソッド ==
+
+MEMBER
+
+  構造体メンバの値を読み出します。
+  MEMBER はメンバ名に置き換えます。
+
+MEMBER = val
+
+  構造体メンバの値を書き込みます。
+  MEMBER はメンバ名に置き換えます。
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyVMs.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyVMs.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/mrubyVMs.cdl	(revision 398)
@@ -0,0 +1,53 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+import( <posix.cdl> );
+
+/*
+ * POSIX 環境用の VM
+ * mrbgems の mrbgems/mruby-bin-mruby/tools/mruby/mruby.c を参考に作成したもの
+ */
+namespace nMruby{
+	[active]
+	celltype tMrubyProc {
+	    entry nPosix::sMain eMain;
+
+		[optional]
+			call sInitializeBridge cInit;
+		var {
+			mrb_state *mrb;
+		};
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tBoolPointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tBoolPointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tBoolPointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tBoolPointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_BOOL( Bool, bool_t )
+POINTER_CLASS( Bool, bool_t )
+CHECK_AND_GET_POINTER( Bool, bool_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tBoolPointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_BoolPointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tCharPointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tCharPointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tCharPointer.c	(revision 398)
@@ -0,0 +1,85 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tCharPointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( Char, char_t )
+POINTER_CLASS( Char, char_t )
+#ifndef  TECS_Use_MrbString_for_CharPointer
+CHECK_AND_GET_POINTER( Char, char_t )
+#else
+CHECK_AND_GET_CHAR_POINTER( Char, char_t )
+CHECK_AND_GET_CHAR_POINTER_MOD( Char, char_t )
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tCharPointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	struct  RClass *c;
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	c = tecs_init_CharPointer( mrb, TECS );
+	mrb_define_method(mrb, c, "to_s", CharPointer_to_s, MRB_ARGS_NONE());
+	mrb_define_method(mrb, c, "from_s", CharPointer_from_s, MRB_ARGS_REQ(1));
+
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tDouble64Pointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tDouble64Pointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tDouble64Pointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tDouble64Pointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_FLOAT( Double64, double64_t )
+POINTER_CLASS( Double64, double64_t )
+CHECK_AND_GET_POINTER( Double64, double64_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tDouble64Pointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_Double64Pointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tFloat32Pointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tFloat32Pointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tFloat32Pointer.c	(revision 398)
@@ -0,0 +1,76 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tFloat32Pointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_FLOAT( Float32, float32_t )
+POINTER_CLASS( Float32, float32_t )
+CHECK_AND_GET_POINTER( Float32, float32_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tFloat32Pointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_Float32Pointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt16Pointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt16Pointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt16Pointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tInt16Pointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( Int16, int16_t )
+POINTER_CLASS( Int16, int16_t )
+CHECK_AND_GET_POINTER( Int16, int16_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tInt16Pointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_Int16Pointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt32Pointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt32Pointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt32Pointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tInt32Pointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( Int32, int32_t )
+POINTER_CLASS( Int32, int32_t )
+CHECK_AND_GET_POINTER( Int32, int32_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tInt32Pointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_Int32Pointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt64Pointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt64Pointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt64Pointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (C) 2012 by Ubiquitous Computing and Networking Laboratory
+ *                Ritsumeikan Univ., JAPAN
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tInt64Pointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( Int64, int64_t )
+POINTER_CLASS( Int64, int64_t )
+CHECK_AND_GET_POINTER( Int64, int64_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tInt64Pointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_Int64Pointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt8Pointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt8Pointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tInt8Pointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tInt8Pointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( Int8, int8_t )
+POINTER_CLASS( Int8, int8_t )
+CHECK_AND_GET_POINTER( Int8, int8_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tInt8Pointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_Int8Pointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tIntPointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tIntPointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tIntPointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tIntPointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( Int, int )
+POINTER_CLASS( Int, int )
+CHECK_AND_GET_POINTER( Int, int )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tIntPointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_IntPointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tLongPointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tLongPointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tLongPointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tLongPointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( Long, long )
+POINTER_CLASS( Long, long )
+CHECK_AND_GET_POINTER( Long, long )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tLongPointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_LongPointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMruby.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMruby.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMruby.c	(revision 398)
@@ -0,0 +1,228 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ * 呼び口関数 #_TCPF_#
+ * call port : cSerialPort  signature: sSerialPort context: task
+ *   ER             cSerialPort_open( );
+ *   ER             cSerialPort_close( );
+ *   ER_UINT        cSerialPort_read( char_t* buffer, uint_t length );
+ *   ER_UINT        cSerialPort_write( const char_t* buffer, uint_t length );
+ *   ER             cSerialPort_control( uint_t ioControl );
+ *   ER             cSerialPort_refer( T_SERIAL_RPOR* pk_rpor );
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tMruby_tecsgen.h"
+#include <string.h>
+
+#include <mruby.h>
+#include <mruby/proc.h>
+#include <mruby/data.h>
+#include <mruby/compile.h>
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+#define MEM_SIZE 1024*1024 // 1MB
+//#define VM_EVAL
+//#define MALLOC_EVAL
+
+#include <t_syslog.h>
+
+void mrb_init_mrb(CELLCB *p_cellcb, mrb_state *mrb);
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eMrubyBody
+ * entry port: eMrubyBody
+ * signature:  sMrubyBody
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eMrubyBody_main
+ * name:         eMrubyBody_main
+ * global_name:  nMruby_tMruby_eMrubyBody_main
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eMrubyBody_main(CELLIDX idx)
+{
+#ifdef VM_EVAL
+  SYSUTM tstart, tend;
+#endif
+  
+  CELLCB	*p_cellcb;
+  mrb_state *mrb;
+  
+  if (VALID_IDX(idx)) {
+    p_cellcb = GET_CELLCB(idx);
+  }
+#ifdef VM_EVAL
+  get_utm(&tstart);
+#endif
+
+  /* new interpreter instance */
+  mrb = mrb_open();
+  if (mrb == NULL) {
+    syslog(LOG_EMERG, "Invalid mrb_state, exiting test driver");
+//    cSerialPort_write("Invalid mrb_state, exiting test driver\n", 39);
+    return;
+  }
+
+#ifdef VM_EVAL
+  get_utm(&tend);
+  syslog(LOG_EMERG, "mrb_open time = %d micro sec", tend - tstart);
+#endif
+  if(is_cInit_joined()){
+    // TECS Bridge
+    cInit_initializeBridge( mrb );
+  }
+  mrb_init_mrb(p_cellcb, mrb);
+	syslog(LOG_EMERG, "end of mruby program");
+#ifdef VM_EVAL
+  get_utm(&tstart);
+#endif
+  mrb_close(mrb);
+#ifdef VM_EVAL
+  get_utm(&tend);
+  syslog(LOG_EMERG, "mrb_close time = %d micro sec", tend - tstart);
+#endif
+}
+
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
+
+void
+mrb_init_mrb(CELLCB	*p_cellcb, mrb_state *mrb)
+{
+  mrb_irep *irep = mrb_read_irep(mrb, ATTR_irep);
+  
+  mrb_run(mrb, mrb_proc_new(mrb, irep), mrb_top_self(mrb));
+  if (mrb->exc) {
+    mrb_p(mrb, mrb_obj_value(mrb->exc));
+    exit(0);
+  }
+}
+
+/*
+extern void debug_print(char * str);
+extern void debug_print_address(char * str, int address);
+extern void debug_print_int(char * str, int data);
+#include <errno.h>
+void *
+_sbrk(size_t incr)
+{
+  // TODO: 正しいヒープサイズを指定すること (EV3はRAM 64MB)
+  extern char __heap_start;
+  static uint32_t cs3_heap_end = &__heap_start + MEM_SIZE; // ヒープの最後アドレス
+  static char *heap_end = &__heap_start;
+  char *prev_heap_end;
+  uint16_t incr2;
+  
+  char str[20];
+  
+#ifdef MALLOC_EVAL
+  syslog(LOG_EMERG, "heap_start = %x", &__heap_start);
+#endif
+
+  prev_heap_end = heap_end;
+  incr2 = (uint16_t)incr;
+  
+  if (heap_end + incr2 > cs3_heap_end) {
+    errno = ENOMEM;
+    return (void *)-1;
+  }
+  heap_end += incr2;
+
+#ifdef MALLOC_EVAL
+  syslog(LOG_EMERG, "heap_end = %x", heap_end);
+#endif
+
+#ifdef DEBUG_MALLOC	
+  debug_print_int("incr",incr);
+  debug_print_address("prev_heap_end",(int) prev_heap_end);
+  dly_tsk(50);
+#endif
+  return (void *) prev_heap_end;
+}
+*/
+extern intptr_t bt_snd_chr(intptr_t c);
+extern intptr_t uart_snd_chr(intptr_t c) ;
+extern void initialize_lcd_dri();
+#define UART1	(*(volatile struct st_uart *)0x01D0C000)
+size_t fwrite(const void *buf, size_t size, size_t n, FILE *fp){
+  intptr_t intp;
+  char *cp;
+  cp = (char*)buf;
+  /* シリアルポートが結合されている場合のみ呼び出す
+  if(is_cSerialPort_joined()){
+    //cSerialPort_write(buf, size);
+   
+  }*/
+    
+  for(int i = 0;i < size; i++){
+    intp = *cp++;
+    if (intp == '\n') {
+	    bt_snd_chr('\r');
+	    while(!uart_send(&UART1, '\r'));
+    } 
+	bt_snd_chr(intp);
+    while(!uart_send(&UART1, intp));
+
+  }
+    return size;
+};
+
+#ifndef EV3_SOUND
+void _write(){}
+void _close(){}
+void _lseek(){}
+void _read(){}
+//void _fstat(){}
+//void _isatty(){}
+#endif
+
+//void _exit(){}
+//void _getpid(){}
+//void _kill(){}
+void _gettimeofday(){}
+void _fini(){}
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyCyclicTaskBody.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyCyclicTaskBody.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyCyclicTaskBody.c	(revision 398)
@@ -0,0 +1,90 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cMrubyVM signature: nMruby_sMrubyVM context:task
+ *   bool_t         cMrubyVM_initialize( );
+ *   bool_t         cMrubyVM_run( );
+ *   void           cMrubyVM_funcall( const char_t* name );
+ *   void           cMrubyVM_finalize( );
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tMrubyCyclicTaskBody_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eMrubyBody
+ * entry port: eMrubyBody
+ * signature:  sTaskBody
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eMrubyBody_main
+ * name:         eMrubyBody_main
+ * global_name:  nMruby_tMrubyCyclicTaskBody_eMrubyBody_main
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eMrubyBody_main(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( ! VAR_b_init ){
+      cMrubyVM_initialize( );
+      VAR_b_init = true;
+  }
+  cMrubyVM_run( );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyProc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyProc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyProc.c	(revision 398)
@@ -0,0 +1,171 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * 以前の nMruby_tMrubyProc.c は、mruby の本体に含まれていた 
+ *    mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
+ * をベースに TECS のコードを足していたが、TOPPERS ライセンスと異なるため
+ * 新たに書き下ろした。（小さなコードのため、概ね似たようなものになるが。
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mruby.h"
+#include "mruby/string.h"
+#include "mruby/array.h"
+#include "mruby/compile.h"
+#include "mruby/dump.h"
+#include "mruby/variable.h"
+
+/* #[<PREAMBLE>]#
+ * Don't edit the comments between #[<...>]# and #[</...>]#
+ * These comment are used by tecsmerege when merging.
+ *
+ * attr access macro #_CAAM_#
+ * mrb              mrb_state*       VAR_mrb         
+ *
+ * call port function #_TCPF_#
+ * call port: cInit signature: nMruby_sInitializeBridge context:task optional:true
+ *   bool_t     is_cInit_joined()                     check if joined
+ *   void           cInit_initializeBridge( const mrb_state* mrb );
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tMrubyProc_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eMain
+ * entry port: eMain
+ * signature:  nPosix_sMain
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eMain_main
+ * name:         eMain_main
+ * global_name:  nMruby_tMrubyProc_eMain_main
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+int
+eMain_main(CELLIDX idx, int argc, const char** argv)
+{
+	CELLCB	*p_cellcb;
+  mrb_state *mrb;
+  mrbc_context* context;
+  if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+      return -1;
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if (argc != 2) {
+      printf("usage: %s script.rb\n", argv[0]);
+      goto error_return;
+  }
+  mrb = mrb_open();
+  if( mrb == 0 ){
+      printf("%s: mrb_open() failed\n", argv[0]);
+      goto error_return;
+  }
+  context = mrbc_context_new(mrb);
+  if (context == 0) {
+      printf("%s: mrbc_context_new() failed\n", argv[0]);
+      goto error_close;
+  }
+
+  /*--------   ARGV   ----------*/
+  {
+      mrb_value ARGV = mrb_ary_new_capa(mrb, argc);
+      int  i;
+      for (i = 0; i < argc; i++) {
+          mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, argv[i]));
+      }
+      mrb_define_global_const(mrb, "ARGV", ARGV);
+  }
+  /*--------   $0   ----------*/
+  {
+      mrb_sym zero_sym = mrb_intern_lit(mrb, "$0");
+      mrbc_filename(mrb, context, argv[0]);
+      mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, argv[0]));
+  }
+
+  /* ------- register TECS bridge classes -------*/
+  if (is_cInit_joined()) {
+      cInit_initializeBridge(mrb);
+  }
+
+  /*--------  load .rb file -------*/
+  {
+      FILE *file = fopen(argv[1], "r");
+      if (file == NULL) {
+          printf("file not found: %s\n", argv[1]);
+          goto error_free;
+      }
+
+      mrb_value val = mrb_load_file_cxt(mrb, file, context);
+      if (mrb->exc) {
+          if(! mrb_undef_p(val)){
+              mrb_print_error(mrb);
+          }
+      }
+  }
+
+  /*---------- success case --------*/
+  mrbc_context_free(mrb, context);
+  mrb_close( mrb );
+  return 0;
+
+  /*---------- error case ----------*/
+error_free:
+  mrbc_context_free(mrb, context);
+error_close:
+  mrb_close( mrb );
+error_return:
+
+  return -1;
+}
+
+/* #[<POSTAMBLE>]#
+ *   Put non-entry functions below.
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyProc_1_0.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyProc_1_0.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyProc_1_0.c	(revision 398)
@@ -0,0 +1,304 @@
+/*
+ * This file comes from mruby. (renamed from tools/mruby/mruby.c)
+ * This file is distributed under ruby's license. (not under TOPPERS license)
+ *   see https://github.com/mruby/mruby
+ * A little modification is done to to call initializer registering TECS components.
+ *
+ * このファイルは、mruby のものです。
+ * mruby のライセンスのもとで、配布されます。(TOPPERS ライセンスではありません)
+ *  参照：  https://github.com/mruby/mruby
+ * TECS コンポーネントを登録する初期化子を呼ぶため、少しの修正がなされています。
+ */
+
+#include "nMruby_tMrubyProc_tecsgen.h"
+
+#include "mruby.h"
+#include "mruby/proc.h"
+#include "mruby/array.h"
+#include "mruby/string.h"
+#include "mruby/compile.h"
+#include "mruby/dump.h"
+#include "mruby/variable.h"
+#include <stdio.h>
+#include <string.h>
+
+#ifndef ENABLE_STDIO
+static void
+p(mrb_state *mrb, mrb_value obj)
+{
+  obj = mrb_funcall(mrb, obj, "inspect", 0);
+  fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout);
+  putc('\n', stdout);
+}
+#else
+#define p(mrb,obj) mrb_p(mrb,obj)
+#endif
+
+void mrb_show_version(mrb_state *);
+void mrb_show_copyright(mrb_state *);
+
+struct _args {
+  FILE *rfp;
+  char* cmdline;
+  int fname        : 1;
+  int mrbfile      : 1;
+  int check_syntax : 1;
+  int verbose      : 1;
+  int argc;
+  char** argv;
+};
+
+static void
+usage(const char *name)
+{
+  static const char *const usage_msg[] = {
+  "switches:",
+  "-b           load and execute RiteBinary (mrb) file",
+  "-c           check syntax only",
+  "-e 'command' one line of script",
+  "-v           print version number, then run in verbose mode",
+  "--verbose    run in verbose mode",
+  "--version    print the version",
+  "--copyright  print the copyright",
+  NULL
+  };
+  const char *const *p = usage_msg;
+
+  printf("Usage: %s [switches] programfile\n", name);
+  while(*p)
+  printf("  %s\n", *p++);
+}
+
+static int
+parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
+{
+  char **origargv = argv;
+  static const struct _args args_zero = { 0 };
+
+  *args = args_zero;
+
+  for (argc--,argv++; argc > 0; argc--,argv++) {
+    char *item;
+    if (argv[0][0] != '-') break;
+
+    if (strlen(*argv) <= 1) {
+      argc--; argv++;
+      args->rfp = stdin;
+      break;
+    }
+
+    item = argv[0] + 1;
+    switch (*item++) {
+    case 'b':
+      args->mrbfile = 1;
+      break;
+    case 'c':
+      args->check_syntax = 1;
+      break;
+    case 'e':
+      if (item[0]) {
+        goto append_cmdline;
+      }
+      else if (argc > 1) {
+        argc--; argv++;
+        item = argv[0];
+append_cmdline:
+        if (!args->cmdline) {
+          char *buf;
+
+          buf = (char *)mrb_malloc(mrb, strlen(item)+1);
+          strcpy(buf, item);
+          args->cmdline = buf;
+        }
+        else {
+          args->cmdline = (char *)mrb_realloc(mrb, args->cmdline, strlen(args->cmdline)+strlen(item)+2);
+          strcat(args->cmdline, "\n");
+          strcat(args->cmdline, item);
+        }
+      }
+      else {
+        printf("%s: No code specified for -e\n", *origargv);
+        return 0;
+      }
+      break;
+    case 'v':
+      mrb_show_version(mrb);
+      args->verbose = 1;
+      break;
+    case '-':
+      if (strcmp((*argv) + 2, "version") == 0) {
+        mrb_show_version(mrb);
+        exit(0);
+      }
+      else if (strcmp((*argv) + 2, "verbose") == 0) {
+        args->verbose = 1;
+        break;
+      }
+      else if (strcmp((*argv) + 2, "copyright") == 0) {
+        mrb_show_copyright(mrb);
+        exit(0);
+      }
+      else return -3;
+      return 0;
+    default:
+      return -4;
+    }
+  }
+
+  if (args->rfp == NULL && args->cmdline == NULL) {
+    if (*argv == NULL) args->rfp = stdin;
+    else {
+      args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
+      if (args->rfp == NULL) {
+        printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
+        return 0;
+      }
+      args->fname = 1;
+      args->cmdline = argv[0];
+      argc--; argv++;
+    }
+  }
+  args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1));
+  memcpy(args->argv, argv, (argc+1) * sizeof(char*));
+  args->argc = argc;
+
+  return 0;
+}
+
+static void
+cleanup(mrb_state *mrb, struct _args *args)
+{
+  if (args->rfp && args->rfp != stdin)
+    fclose(args->rfp);
+  if (args->cmdline && !args->fname)
+    mrb_free(mrb, args->cmdline);
+  if (args->argv)
+    mrb_free(mrb, args->argv);
+  mrb_close(mrb);
+}
+
+static void
+showcallinfo(mrb_state *mrb)
+{
+  mrb_callinfo *ci;
+  mrb_int ciidx;
+  const char *filename, *method, *sep;
+  int i, line;
+
+  printf("trace:\n");
+  ciidx = mrb_fixnum(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "ciidx")));
+  if (ciidx >= mrb->ciend - mrb->cibase)
+    ciidx = 10; /* ciidx is broken... */
+
+  for (i = ciidx; i >= 0; i--) {
+    ci = &mrb->cibase[i];
+    filename = "(unknown)";
+    line = -1;
+
+    if (MRB_PROC_CFUNC_P(ci->proc)) {
+      continue;
+    }
+    else {
+      mrb_irep *irep = ci->proc->body.irep;
+      if (irep->filename != NULL)
+        filename = irep->filename;
+      if (irep->lines != NULL && i+1 <= ciidx) {
+        mrb_code *pc = mrb->cibase[i+1].pc;
+        if (irep->iseq <= pc && pc < irep->iseq + irep->ilen) {
+          line = irep->lines[pc - irep->iseq - 1];
+        }
+      }
+    }
+    if (ci->target_class == ci->proc->target_class)
+      sep = ".";
+    else
+      sep = "#";
+
+    method = mrb_sym2name(mrb, ci->mid);
+    printf("\t[%d] %s:%d%s%s%s%s\n",
+    	   i, filename, line,
+	   method ? ":in " : "",
+	   method ? mrb_class_name(mrb, ci->proc->target_class) : "",
+	   method ? sep : "",
+	   method ? method : "");
+  }
+}
+
+int
+eMain_main( CELLIDX idx, int argc, const char **argv)
+{
+  CELLCB   *p_cellcb = GET_CELLCB( idx );
+  mrb_state *mrb = mrb_open();
+  int n = -1;
+  int i;
+  struct _args args;
+  mrb_value ARGV;
+
+  cInit_initializeBridge( mrb );
+
+  if (mrb == NULL) {
+    fprintf(stderr, "Invalid mrb_state, exiting mruby\n");
+    return EXIT_FAILURE;
+  }
+
+  n = parse_args(mrb, argc, (char **)argv, &args);
+  if (n < 0 || (args.cmdline == NULL && args.rfp == NULL)) {
+    cleanup(mrb, &args);
+    usage(argv[0]);
+    return n;
+  }
+
+  ARGV = mrb_ary_new_capa(mrb, args.argc);
+  for (i = 0; i < args.argc; i++) {
+    mrb_ary_push(mrb, ARGV, mrb_str_new(mrb, args.argv[i], strlen(args.argv[i])));
+  }
+  mrb_define_global_const(mrb, "ARGV", ARGV);
+
+  if (args.mrbfile) {
+    n = mrb_load_irep(mrb, args.rfp);
+    if (n < 0) {
+      fprintf(stderr, "failed to load mrb file: %s\n", args.cmdline);
+    }
+    else if (!args.check_syntax) {
+      mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
+      n = 0;
+      if (mrb->exc) {
+        showcallinfo(mrb);
+        p(mrb, mrb_obj_value(mrb->exc));
+        n = -1;
+      }
+    }
+  }
+  else {
+    mrbc_context *c = mrbc_context_new(mrb);
+    mrb_value v;
+
+    if (args.verbose)
+      c->dump_result = 1;
+    if (args.check_syntax)
+      c->no_exec = 1;
+
+    if (args.rfp) {
+      mrbc_filename(mrb, c, args.cmdline ? args.cmdline : "-");
+      v = mrb_load_file_cxt(mrb, args.rfp, c);
+    }
+    else {
+      mrbc_filename(mrb, c, "-e");
+      v = mrb_load_string_cxt(mrb, args.cmdline, c);
+    }
+    mrbc_context_free(mrb, c);
+    if (mrb->exc) {
+      if (!mrb_undef_p(v)) {
+        showcallinfo(mrb);
+        p(mrb, mrb_obj_value(mrb->exc));
+      }
+      n = -1;
+    }
+    else if (args.check_syntax) {
+      printf("Syntax OK\n");
+    }
+  }
+  cleanup(mrb, &args);
+
+  return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyTaskBody.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyTaskBody.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyTaskBody.c	(revision 398)
@@ -0,0 +1,88 @@
+/*
+ *   Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cMrubyVM signature: nMruby_sMrubyVM context:task
+ *   bool_t         cMrubyVM_initialize( );
+ *   bool_t         cMrubyVM_run( );
+ *   void           cMrubyVM_finalize( );
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tMrubyTaskBody_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eMrubyBody
+ * entry port: eMrubyBody
+ * signature:  sTaskBody
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eMrubyBody_main
+ * name:         eMrubyBody_main
+ * global_name:  nMruby_tMrubyTaskBody_eMrubyBody_main
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eMrubyBody_main(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( cMrubyVM_initialize( ) ){
+    cMrubyVM_run( );
+    cMrubyVM_finalize( );
+  }
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyVM.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyVM.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tMrubyVM.c	(revision 398)
@@ -0,0 +1,236 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * irep             uint8_t*         ATTR_irep       
+ * var_irep         mrb_irep*        VAR_var_irep    
+ * mrb              mrb_state*       VAR_mrb         
+ * rproc            struct RProc*    VAR_rproc       
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cInit signature: nMruby_sInitializeBridge context:task optional:true
+ *   bool_t     is_cInit_joined()                     check if joined
+ *   void           cInit_initializeBridge( const mrb_state* mrb );
+ * call port: cMalloc signature: sMalloc context:task
+ *   int            cMalloc_initializeMemoryPool( );
+ *   void*          cMalloc_calloc( size_t nelem, size_t elem_size );
+ *   void*          cMalloc_malloc( size_t size );
+ *   void*          cMalloc_realloc( const void* ptr, size_t new_size );
+ *   void           cMalloc_free( const void* ptr );
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tMrubyVM_tecsgen.h"
+#include <string.h>
+
+#include <mruby.h>
+#include <mruby/proc.h>
+#include <mruby/data.h>
+#include <mruby/compile.h>
+#include "t_syslog.h"
+
+MRB_API mrb_state* mrb_open_TECS( CELLCB *p_cellcb);
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eMrubyVM
+ * entry port: eMrubyVM
+ * signature:  nMruby_sMrubyVM
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eMrubyVM_initialize
+ * name:         eMrubyVM_initialize
+ * global_name:  nMruby_tMrubyVM_eMrubyVM_initialize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+bool_t
+eMrubyVM_initialize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+    return false;
+	} /* end if VALID_IDX(idx) */
+
+  cMalloc_initializeMemoryPool();
+	/* ここに処理本体を記述します #_TEFB_# */
+  /* new interpreter instance */
+  //VAR_mrb = mrb_open();
+  VAR_mrb = mrb_open_TECS(p_cellcb);
+  if (VAR_mrb == NULL) {
+    syslog(LOG_EMERG, "Invalid mrb_state, exiting test driver");
+//    cSerialPort_write("Invalid mrb_state, exiting test driver\n", 39);
+    return false;
+  }
+
+  if(is_cInit_joined()){
+    // TECS Bridge
+    cInit_initializeBridge( VAR_mrb );
+  }
+  VAR_var_irep = mrb_read_irep(VAR_mrb, ATTR_irep);
+  VAR_rproc = mrb_proc_new(VAR_mrb, VAR_var_irep);
+  return true;
+}
+
+/* #[<ENTRY_FUNC>]# eMrubyVM_run
+ * name:         eMrubyVM_run
+ * global_name:  nMruby_tMrubyVM_eMrubyVM_run
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+bool_t
+eMrubyVM_run(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  mrb_run(VAR_mrb, VAR_rproc, mrb_top_self(VAR_mrb));
+  if (VAR_mrb->exc) {
+    mrb_p(VAR_mrb, mrb_obj_value(VAR_mrb->exc));
+    return false;
+  }
+  return true;
+}
+
+/* #[<ENTRY_FUNC>]# eMrubyVM_funcall
+ * name:         eMrubyVM_funcall
+ * global_name:  nMruby_tMrubyVM_eMrubyVM_funcall
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eMrubyVM_funcall(CELLIDX idx, const char_t* name)
+{
+	CELLCB	*p_cellcb;
+  mrb_int  argc;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  argc = 0;
+  (void)mrb_funcall(VAR_mrb, mrb_top_self(VAR_mrb), name, argc );
+}
+
+/* #[<ENTRY_FUNC>]# eMrubyVM_finalize
+ * name:         eMrubyVM_finalize
+ * global_name:  nMruby_tMrubyVM_eMrubyVM_finalize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eMrubyVM_finalize(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	syslog(LOG_EMERG, "end of mruby program");
+  mrb_close(VAR_mrb);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
+
+#include "tlsf.h"
+void*
+mrb_TECS_allocf(mrb_state *mrb, void *p, size_t size, void *ud)
+{
+	CELLCB	*p_cellcb= (CELLCB *)ud;
+  if (size == 0) {
+      cMalloc_free(p);
+      //tlsf_free(p);
+      return NULL;
+  }
+  else if (p){
+      //return tlsf_realloc(p,size);
+      return cMalloc_realloc(p, size);
+  }
+  else {
+      //return tlsf_malloc(size);
+      return cMalloc_malloc(size);
+  }
+}
+
+// p_cellcb は VM のもの
+// VM セルタイプに、呼び口 call sMalloc cMalloc; を設ける
+// mrb_TECS_allocf を参照
+MRB_API mrb_state*
+mrb_open_TECS( CELLCB *p_cellcb)
+{
+    return mrb_open_allocf(mrb_TECS_allocf, (void *)p_cellcb);
+};
+
+/*** ダミー関数 ***/
+#ifndef EV3_SOUND
+void _write(){}
+void _close(){}
+void _lseek(){}
+void _read(){}
+//void _fstat(){}
+//void _isatty(){}
+#endif
+
+//void _exit(){}
+//void _getpid(){}
+//void _kill(){}
+void _gettimeofday(){}
+void _fini(){}
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tSCharPointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tSCharPointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tSCharPointer.c	(revision 398)
@@ -0,0 +1,87 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tSCharPointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+//GET_SET_INT( SChar, schar_t )
+//POINTER_CLASS( SChar, schar_t )
+GET_SET_INT( SChar, char_t )
+POINTER_CLASS( SChar, char_t )
+#ifndef  TECS_Use_MrbString_for_CharPointer
+//CHECK_AND_GET_POINTER( SChar, schar_t )
+CHECK_AND_GET_POINTER( SChar, char_t )
+#else
+CHECK_AND_GET_CHAR_POINTER( SChar, schar_t )
+CHECK_AND_GET_CHAR_POINTER_MOD( SChar, schar_t )
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tSCharPointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	struct RClass *c;
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	c=tecs_init_SCharPointer( mrb, TECS );
+	mrb_define_method(mrb, c, "to_s", CharPointer_to_s, MRB_ARGS_NONE());
+	mrb_define_method(mrb, c, "from_s", CharPointer_from_s, MRB_ARGS_REQ(1));
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tShortPointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tShortPointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tShortPointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tShortPointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( Short, short )
+POINTER_CLASS( Short, short )
+CHECK_AND_GET_POINTER( Short, short )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tShortPointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_ShortPointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tTECSInitializer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tTECSInitializer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tTECSInitializer.c	(revision 398)
@@ -0,0 +1,95 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * TECS             struct RClass *  VAR_TECS        
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port : cInitialize  signature: nMruby_sInitializeTECSBridge context: task
+ *   void           cInitialize_initializeBridge( subscript, const mrb_state* mrb, const struct RClass * TECS );
+ *       subscript:  0...(NCP_cInitialize-1)
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tTECSInitializer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tTECSInitializer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(CELLIDX idx, const mrb_state* mrb)
+{
+	CELLCB	*p_cellcb;
+	int      i;
+	struct RClass *TECS;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	TECS = mrb_define_module( (mrb_state *)mrb, "TECS" );
+	// mrb: const mrb_state * => mrb_state *
+    VAR_TECS = TECS;
+
+	for( i = 0; i < NCP_cInitialize; i++ )
+		cInitialize_initializeBridge( i, (mrb_state*)mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUCharPointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUCharPointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUCharPointer.c	(revision 398)
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tUCharPointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( UChar, uchar_t )
+POINTER_CLASS( UChar, uchar_t )
+#ifndef  TECS_Use_MrbString_for_CharPointer
+CHECK_AND_GET_POINTER( UChar, uchar_t )
+#else
+CHECK_AND_GET_CHAR_POINTER( UChar, uchar_t )
+CHECK_AND_GET_CHAR_POINTER_MOD( UChar, uchar_t )
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tUCharPointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	struct RClass *c;
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	c=tecs_init_UCharPointer( mrb, TECS );
+	mrb_define_method(mrb, c, "to_s", CharPointer_to_s, MRB_ARGS_NONE());
+	mrb_define_method(mrb, c, "from_s", CharPointer_from_s, MRB_ARGS_REQ(1));
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt16Pointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt16Pointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt16Pointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tUInt16Pointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( UInt16, uint16_t )
+POINTER_CLASS( UInt16, uint16_t )
+CHECK_AND_GET_POINTER( UInt16, uint16_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tUInt16Pointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_UInt16Pointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt32Pointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt32Pointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt32Pointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tUInt32Pointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( UInt32, uint32_t )
+POINTER_CLASS( UInt32, uint32_t )
+CHECK_AND_GET_POINTER( UInt32, uint32_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tUInt32Pointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_UInt32Pointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt64Pointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt64Pointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt64Pointer.c	(revision 398)
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tUInt64Pointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( UInt64, uint64_t )
+POINTER_CLASS( UInt64, uint64_t )
+CHECK_AND_GET_POINTER( UInt64, uint64_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tUInt64Pointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_UInt64Pointer( mrb, TECS );
+
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt8Pointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt8Pointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUInt8Pointer.c	(revision 398)
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tUInt8Pointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( UInt8, uint8_t )
+POINTER_CLASS( UInt8, uint8_t )
+CHECK_AND_GET_POINTER( UInt8, uint8_t )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tUInt8Pointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_UInt8Pointer( mrb, TECS );
+
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUIntPointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUIntPointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUIntPointer.c	(revision 398)
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tUIntPointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( UInt, unsigned int )
+POINTER_CLASS( UInt, unsigned int )
+CHECK_AND_GET_POINTER( UInt, unsigned int )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tUIntPointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_UIntPointer( mrb, TECS );
+
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tULongPointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tULongPointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tULongPointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tULongPointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( ULong, unsigned long )
+POINTER_CLASS( ULong, unsigned long )
+CHECK_AND_GET_POINTER( ULong, unsigned long )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tULongPointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_ULongPointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUShortPointer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUShortPointer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/nMruby_tUShortPointer.c	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+#include "nMruby_tUShortPointer_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+GET_SET_INT( UShort, unsigned short )
+POINTER_CLASS( UShort, unsigned short )
+CHECK_AND_GET_POINTER( UShort, unsigned short )
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eInitialize
+ * entry port: eInitialize
+ * signature:  nMruby_sInitializeTECSBridge
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eInitialize_initializeBridge
+ * name:         eInitialize_initializeBridge
+ * global_name:  nMruby_tUShortPointer_eInitialize_initializeBridge
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eInitialize_initializeBridge(mrb_state* mrb, struct RClass * TECS)
+{
+	/* ここに処理本体を記述します #_TEFB_# */
+	(void)tecs_init_UShortPointer( mrb, TECS );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/sMruby.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/sMruby.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/sMruby.cdl	(revision 398)
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (C) 2012 by Ubiquitous Computing and Networking Laboratory
+ *                Ritsumeikan Univ., JAPAN
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+namespace nMruby{
+  signature sMrubyVM {
+    /*
+     * 初期化する (以下まで完了する)
+     *   mrb_open
+     *   VM_TECSInitializer  (TECS ブリッジの初期化)
+     *   mrb_read_irep       (バイトコードの登録)
+     */
+    bool_t initialize(void);
+
+    /*
+     * 実行する
+     * RETURN
+     *   true  未処置の例外がない
+     *   false 未処置の例外がある
+     *  initialize が false を返した場合、run, finalize を呼び出してはならない
+     */
+    bool_t run(void);
+
+    /*
+     * 関数を呼びだす
+     */
+    void funcall( [in,string]const char_t *name );
+
+    /*
+     * 終期化する
+     *  run が false を返した場合でも呼びだすこと
+     */
+    void finalize(void);
+
+  };
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/tMruby.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/tMruby.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/tMruby.cdl	(revision 398)
@@ -0,0 +1,148 @@
+/*
+ *  Copyright (C) 2012 by Ubiquitous Computing and Networking Laboratory
+ *                Ritsumeikan Univ., JAPAN
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+//import(<syssvc/tSerialPort.cdl>);
+//import(<kernel.cdl>);
+
+import(<mruby.cdl>);
+import(<sMruby.cdl>);
+import(<tTLSFMalloc.cdl>);
+
+namespace nMruby{
+
+/*** mruby VM ***/
+  celltype tMrubyVM{
+    entry sMrubyVM eMrubyVM;
+    attr{
+      [omit]char_t *mrubyFile;
+      const uint8_t *irep=C_EXP("$cell_global$_irep");
+    };
+    var{
+      mrb_irep      *var_irep;
+      mrb_state     *mrb;
+      struct RProc  *rproc;
+    };
+
+    /* MrubyBridgePlugin の生成する VM_TECSInitializeer.eInitialize へ結合する */
+    [optional]  call sInitializeBridge cInit;
+    /*
+     * アロケータ 
+     *  他と共有しないのであれば、このアロケータは排他制御される必要はない
+     */
+    call sMalloc cMalloc;
+
+    FACTORY{
+      write("Makefile.tecsgen", "clean_mrb_c :");
+      write("Makefile.tecsgen", "	rm -f $(MRB_C)"); 
+    };
+    factory{
+      write("Makefile.tecsgen", "POST_TECSGEN_TARGET := $(POST_TECSGEN_TARGET) $cell_global$_mrb.c");
+      write("Makefile.tecsgen", "$cell_global$_mrb.c : %s tecs.timestamp Makefile", mrubyFile);
+      write("Makefile.tecsgen", "	$(MRBC) -B$cell_global$_irep -o$cell_global$_mrb.c %s", mrubyFile);
+      write("Makefile.tecsgen", "TECS_COBJS := $(TECS_COBJS) $cell_global$_mrb.o");
+      write("Makefile.tecsgen", "MRB_C := $(MRB_C) $cell_global$_mrb.c");
+      write("$ct_global$_factory.h","extern const uint8_t $cell_global$_irep[];");
+    };
+  };
+
+/*** Standard Task Versoin  ***/
+  /*
+   * tMruby　の eMrubyBody.main が、繰り返し起床されることは想定されていません。
+   */
+  celltype tMrubyTaskBody{
+    entry sTaskBody eMrubyBody;
+    call  sMrubyVM  cMrubyVM;
+  };
+  composite tMruby{
+    entry sTaskBody eMrubyBody;
+    [optional]  call sInitializeBridge cInit;
+    attr{
+      [omit]char_t *mrubyFile;
+      size_t memoryPoolSize = 1024 * 1024;    /** 1MB default **/
+      /* note: this requires enough memory */
+      /* please pay attention to memory layout */
+    };
+
+    /** **/
+    cell tMrubyVM MrubyVM{
+      mrubyFile = composite.mrubyFile;
+      cInit => composite.cInit;
+      cMalloc = TLSFMalloc.eMalloc;
+    };
+    cell tMrubyTaskBody MrubyTaskBody {
+      cMrubyVM = MrubyVM.eMrubyVM;
+    };
+    cell tTLSFMalloc TLSFMalloc {
+      memoryPoolSize = composite.memoryPoolSize;
+    };
+    composite.eMrubyBody => MrubyTaskBody.eMrubyBody;
+  };
+
+/*** Cyclic Task Versoin  ***/
+  /*
+   * tMrubyCyclic の eMrubyBody.main が繰り返し呼び出されることが想定されています。
+   * この実装では mrb_close は呼び出されません (終了は、突然電源が切れることを想定)
+   */
+  celltype tMrubyCyclicTaskBody{
+    entry sTaskBody eMrubyBody;
+    call  sMrubyVM  cMrubyVM;
+    var {
+        bool_t  b_init;
+    };
+  };
+  composite tMrubyCyclic{
+    entry sTaskBody eMrubyBody;
+    [optional]  call sInitializeBridge cInit;
+    attr{
+      [omit]char_t *mrubyFile;
+      size_t memoryPoolSize = 1024 * 1024;    /** 1MB default **/
+      /* note: this requires enough memory */
+      /* please pay attention to memory layout */
+    };
+
+    /** **/
+    cell tMrubyVM MrubyVM{
+      mrubyFile = composite.mrubyFile;
+      cInit => composite.cInit;
+      cMalloc = TLSFMalloc.eMalloc;
+    };
+    cell tMrubyCyclicTaskBody MrubyTaskBody {
+      cMrubyVM = MrubyVM.eMrubyVM;
+    };
+    cell tTLSFMalloc TLSFMalloc {
+      memoryPoolSize = composite.memoryPoolSize;
+    };
+    composite.eMrubyBody => MrubyTaskBody.eMrubyBody;
+  };
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/tecs_mruby.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/tecs_mruby.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/mruby/tecs_mruby.h	(revision 398)
@@ -0,0 +1,78 @@
+/*
+ *  Copyright (C) 2008-2019 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+#ifndef tecs_mruby_h__
+#define tecs_mruby_h__
+
+#ifndef TECSGEN
+
+// tecsgen doesn't include actual mruby.h
+#include "mruby.h"
+#include "mruby/class.h"
+#include "mruby/data.h"
+#include "mruby/string.h"
+#include "mruby/irep.h"
+#include "mruby/dump.h"
+#include "mruby/proc.h"
+
+#include "TECSPointer.h"
+#include "TECSStruct.h"
+
+
+#else /* TECSGEN */
+
+/*
+ * fake definition because tecsgen cannot accept actual mruby.h in case of below.
+ *   types:   long long, long long int
+ *   special keyword __attribute__(x), __extension__
+ */
+typedef int mrb_state;
+typedef int mrb_irep;
+typedef int mrb_context;
+struct  RClass {uint32_t gcnext;};  // actual definition: struct RBasic *gcnext
+struct  RProc  {uint32_t gcnext;};  // actual definition: struct RBasic *gcnext
+
+typedef int CELLCB;
+
+#define GET_SET_BOOL( Type, type )
+#define GET_SET_CHAR( Type, type )
+#define GET_SET_INT( Type, type )
+#define GET_SET_FLOAT( Type, type )
+#define POINTER_CLASS( Type, type )
+#define CHECK_AND_GET_POINTER( Type, type )
+
+#endif /* TECSGEN */
+
+#endif /* tecs_mruby_h__ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/posix/posix.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/posix/posix.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/posix/posix.cdl	(revision 398)
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (C) 2008-2017 by TOPPERS Project
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+
+namespace nPosix {
+	signature sMain{
+		int  main( [in]int argc, [in,size_is(argc),string]const char **argv );
+	};
+};
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/PPAllocator.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/PPAllocator.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/PPAllocator.cdl	(revision 398)
@@ -0,0 +1,87 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/*
+ * PPAlloc: Push Pop Allocator
+ *
+ * allocate した逆順で deallocate しなくてはならない
+ * deallocate は、まとめて行うことができる
+ * 例えば最初に allocate された領域を deallocate すると、すべての allocate された領域を deallocate したことになる
+ * 排他制御していないため単一のタスクに割付けて使用する
+ */
+
+[deviate]   // alloc が逸脱になる
+signature sPPAllocator {
+	/*
+	 * size で指定された大きさのメモリ領域をアロケートする
+	 * メモリ領域が確保された場合 *ptr にメモリ領域のアドレスを格納して E_OK を返す
+	 * 十分な空き領域がない場合 E_NOMEM を返す
+	 */
+	ER  alloc( [in]uint32_t size, [out]void **ptr );
+	/*
+	 * メモリをデアロケートする
+	 * alloc で獲得したポインタを引き数 ptr に指定する
+	 * alloc で獲得したメモリ領域を alloc したのとは逆順に dealloc しなくてはならない
+	 * すべてを dealloc するには、最初に alloc されたメモリ領域を dealloc することで行うことができる
+	 * alloc し獲得したメモリ領域をすべて dealloc する前に、再び alloc することはできる
+	 * その場合でも、dealloc していないメモリ領域を alloc したのとは逆順に dealloc しなくてはならない
+	 *
+	 * ptr の値が buf <= ptr < buf+allocated_size を満たすかどうか検査される
+	 * ptr の値が不正の場合 E_PAR を返す
+	 */
+	ER  dealloc( [in]const void *ptr );
+
+    /*
+	 * PPAllocator セルの割付け済みメモリをすべて解放する
+	 * この関数は必ず成功する
+	 */
+    ER  dealloc_all(void);
+};
+
+celltype tPPAllocator {
+	entry  sPPAllocator ePPAllocator;
+	attr {
+		uint32_t   heapSize;
+	};
+	var {
+		[size_is(heapSize)]
+			int8_t  *buf;
+		uint32_t   allocatedSize;
+	};
+};
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/RPCTask.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/RPCTask.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/RPCTask.cdl	(revision 398)
@@ -0,0 +1,119 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/*
+ * unmarshaler の main のシグニチャ
+ */
+signature sUnmarshalerMain {
+	ER	main(void);
+};
+
+///////////////// 専有チャンネル用の定義 ////////////////
+/*
+ * CELLTYPE: 専有チャンネル用のタスクメイン
+ */
+celltype tRPCDedicatedTaskMain {			// Transparent RPC で用いる
+	entry	sTaskBody			eMain;
+	call	sUnmarshalerMain	cMain;
+};
+
+celltype tRPCDedicatedTaskMainWithOpener {	// Opaque RPC で用いる
+	entry	sTaskBody				eMain;
+	call	sUnmarshalerMain		cMain;
+	call	sServerChannelOpener	cOpener;
+	attr {
+		RELTIM	initialDelay = 0;	// sec
+		RELTIM	reopenDelay = 1;	// sec
+	};
+	require tKernel.eKernel;
+};
+
+///////////////// 共有チャンネル用の定義 ////////////////
+/*
+ * CONST: 共有チャンネルヘッダのマジック
+ */
+const uint16_t RPC_CHANNEL_MAN_SOP_MAGIC   = (0x3141);  // Beginning of using shared channel
+const uint16_t RPC_CHANNEL_MAN_EOP_MAGIC   = (0x2718);  // End of using shared channel
+
+/*
+ * CELLTYPE: 共有チャンネルマネージャ
+ * REM:      呼び元側に置くチャンネルマネージャ
+ *           eSemaphore が呼び出されたときチャンネルをロックするとともに、
+ *           チャンネル番号を送出する
+ */
+celltype tRPCSharedChannelMan {
+	entry	sSemaphore	eSemaphore[];
+	call	sSemaphore	cSemaphore;
+	call	sTDR		cClientSideTDR;
+};
+
+
+/*
+ * CELLTYPE: 共有チャンネル用のタスクメイン
+ * REM:      呼び先側に置くタスク
+ *           チャンネル番号を取り出し、チャンネル番号の cTaskBody を呼び出す
+ */
+celltype tRPCSharedTaskMain {
+	entry	sTaskBody	eMain;
+
+	call	sUnmarshalerMain	cUnmarshalAndCallFunction[];
+	call	sTDR		cServerSideTDR;
+
+	require	tSysLog.eSysLog;
+
+	var {
+		int16_t	channelNo;	/* 配列添数 + 1 */
+	};
+};
+
+celltype tRPCSharedTaskMainWithOpener {	// Opaque RPC で用いる
+	entry	sTaskBody			eMain;
+	call	sUnmarshalerMain	cUnmarshalAndCallFunction[];
+	call	sTDR				cServerSideTDR;
+	call	sServerChannelOpener cOpener;
+	require	tSysLog.eSysLog;
+	require tKernel.eKernel;
+
+	attr {
+		RELTIM	initialDelay = 0;	// sec
+		RELTIM	reopenDelay = 1;	// sec
+	};
+	var {
+		int16_t	channelNo;	/* 配列添数 + 1 */
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/TDR.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/TDR.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/TDR.cdl	(revision 398)
@@ -0,0 +1,169 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+import_C( "tecs_rpc.h" );
+
+// Straight Order TDR
+const uint32_t TDR_SOP_MAGIC1   = (0x672A);  // Client to Server
+const uint32_t TDR_SOP_MAGIC2   = (0x561E);  // Server to Client
+const uint32_t TDR_EOP_MAGIC1   = (0x5A3C);  // 返信を待つ (同期呼出し)
+const uint32_t TDR_EOP_MAGIC2   = (0x6D5E);  // 返信を待たない(非同期呼出しまたはリターン)
+
+// Straight Order TDR for SharedChannel
+const uint32_t TDR_SHSOP_MAGIC1   = (0x98D5);  // Client to Server
+const uint32_t TDR_SHSOP_MAGIC2   = (0xA9E1);  // Server to Client
+const uint32_t TDR_SHEOP_MAGIC1   = (0xB5C3);  // 返信を待つ (同期呼出し)
+const uint32_t TDR_SHEOP_MAGIC2   = (0x92A1);  // 返信を待たない(非同期呼出しまたはリターン)
+
+/*
+ * TDR: TECS Data Representation layer
+ */
+[deviate]         /* get_intptr が逸脱になる */
+signature sTDR {  /* TECS Data Representation */
+
+	/* 制御関数 */
+
+	/* チャンネルのリセット */
+	ER	reset( void );	/* 通信チャンネルのリセット */
+						/* 途中でエラーが発生し、送信または受信を続行できなかったときはリセットする */
+						/* 一方がリセットをかけると、他方は RESET エラーを返す */
+						/* 確認できないときは、このチャネルは放棄するしかない */
+
+	/* マジックコードの送受信 */
+	ER	sendSOP( [in]bool_t b_client );     /* StartOfPacket magic を送信 */
+	ER	receiveSOP( [in]bool_t b_client );  /* StartOfPacket magic を受信 */
+						 /* b_client: クライアント側なら true, サーバー側なら false */
+
+	ER	sendEOP( [in]bool_t b_continue );   /* EndOfPacket magic を送信（パケットの掃きだしも行う） */
+	ER	receiveEOP( [in]bool_t b_continue );/* EndOfPacket magic を受信 */
+                        /* b_continue: 同期呼び出しのクライアント側なら true,
+                           非同期呼び出しのクライアント側またはサーバー側なら false */
+
+	/* データ送受信関数 */
+
+	/* 整数型 (推奨) */
+	ER	putInt8( [in]int8_t in ); 
+	ER	putInt16( [in]int16_t in ); 
+	ER	putInt32( [in]int32_t in ); 
+	ER	putInt64( [in]int64_t in ); 
+	ER	putInt128( [in]int128_t in ); 
+  
+	ER	getInt8( [out]int8_t *out );
+	ER	getInt16( [out]int16_t *out );
+	ER	getInt32( [out]int32_t *out );
+	ER	getInt64( [out]int64_t *out );
+	ER	getInt128( [out]int128_t *out );
+
+	/* 無符号整数型 (推奨) */
+	ER	putUInt8( [in]uint8_t in ); 
+	ER	putUInt16( [in]uint16_t in ); 
+	ER	putUInt32( [in]uint32_t in ); 
+	ER	putUInt64( [in]uint64_t in ); 
+	ER	putUInt128( [in]uint128_t in ); 
+  
+	ER	getUInt8( [out]uint8_t *out );
+	ER	getUInt16( [out]uint16_t *out );
+	ER	getUInt32( [out]uint32_t *out );
+	ER	getUInt64( [out]uint64_t *out );
+	ER	getUInt128( [out]uint128_t *out );
+
+	/* 文字型（推奨、8bit） */
+	ER	putChar( [in]char_t in ); 
+	ER	getChar( [out]char_t *out ); 
+
+	/* Bool 型 */
+	ER	putBool( [in]bool_t in ); 
+	ER	getBool( [out]bool_t *out ); 
+
+	/* 浮動小数型 */
+	ER	putFloat32( [in]float32_t in );
+	ER	putDouble64( [in]double64_t in );
+	ER	getFloat32( [out]float32_t *out );
+	ER	getDouble64( [out]double64_t *out );
+
+
+	/* 非推奨の型(有符号) */
+	ER	putSChar( [in]schar_t in );
+	ER	putShort( [in]short_t in ); 
+	ER	putInt( [in]int_t in ); 
+	ER	putLong( [in]long_t in ); 
+
+	ER	getSChar( [out]schar_t *out ); 
+	ER	getShort( [out]short_t *out ); 
+	ER	getInt( [out]int_t *out ); 
+	ER	getLong( [out]long_t *out ); 
+
+
+	/* 非推奨の型(無符号) */
+	ER	putUChar( [in]uchar_t in ); 
+	ER	putUShort( [in]ushort_t in ); 
+	ER	putUInt( [in]uint_t in ); 
+	ER	putULong( [in]ulong_t in ); 
+
+	ER	getUChar( [out]unsigned char *out ); 
+	ER	getUShort( [out]ushort_t *out ); 
+	ER	getUInt( [out]uint_t *out ); 
+	ER	getULong( [out]ulong_t *out ); 
+
+	ER	putIntptr( [in]const intptr_t ptr );
+	ER	getIntptr( [out]intptr_t *ptr );
+};
+
+// Straight Byte Order TECS Data Representation (Data are always sent in native endian)
+celltype tTDR {
+	call	sChannel	cChannel;
+	[inline]
+		entry	sTDR	eTDR;
+
+	var {
+		TMO	tmo = C_EXP( "TMO_FEVR" );
+	};
+	require tSysLog.eSysLog;
+};
+
+// Network Byte Order (Big-endian) TECS Data Representation (Data are always sent in big-endian)
+celltype tNBOTDR {
+	call	sChannel	cChannel;
+	[inline]
+		entry	sTDR	eTDR;
+
+	var {
+		TMO	tmo = C_EXP( "TMO_FEVR" );
+	};
+	require tSysLog.eSysLog;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/rpc.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/rpc.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/rpc.cdl	(revision 398)
@@ -0,0 +1,59 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/*
+ * TECS RPC に関する定義
+ */
+
+/* チャンネル シグニチャ */
+import( <sChannel.cdl> );
+
+/* TDR シグニチャ & セルタイプ */
+import( <TDR.cdl> );
+
+/* チャンネルセルタイプ */
+/* チャンネルセルタイプは、必要なものを各アプリケーションで import する */
+// import( <tDataqueueOWChannel.cdl> );
+// import( <tSocketChannel.cdl> );
+// import( <tTINETChannel.cdl> );
+
+/* タスク セルタイプ */
+import( <RPCTask.cdl> );
+import( <PPAllocator.cdl> );
+
+import( <sRPCErrorHandler.cdl> );
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/rpc_string.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/rpc_string.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/rpc_string.h	(revision 398)
@@ -0,0 +1,155 @@
+/*
+ *
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+#ifndef RPC_STRING_H
+#define RPC_STRING_H
+
+#include <string.h>
+
+/* GenParamCopy.rb で生成する STRLEN, STRNLEN 関数の定義 */
+/* 現状では short, int, long, int128_t をサポートしない */
+
+#define   STRLEN8( str )    strlen( (char *)str )
+
+/*
+ * STRNLEN
+ *  marshaler, unmarshaler は strnlen を使う．
+ *  バッファオーバーランへの耐性を明確にするため．
+ *  しかし、strnlen は ANSI-C 標準のライブラリ関数ではないため、実装されていないケースがある
+ *  GNU (Linux), VC++ では使用できるが、MacOS では使用できない
+ *  （他の組込み用 OS での実装状況も不明）
+ *  小さな関数ですむので inline 関数として実装しておく
+ */
+
+#ifndef USE_STRNLEN_LIB
+#define   STRNLEN8( str, n )    strnlen( (char *)str, n )
+
+#else
+
+Inline size_t
+#define   STRNLEN8( str, n )    STRNLEN8_( (uint8_t *)str, n )
+STRNLEN8_(const uint8_t *s, size_t maxlen)
+{
+    size_t  i;
+    for( i = 0; i < maxlen; i++ )
+        if( *s++ == 0 )
+            break;
+
+    return  i;
+}
+
+#endif
+
+#define	STRLEN16( s )			STRLEN16_( (uint16_t *)s )
+#define	STRLEN32( s )			STRLEN32_( (uint32_t *)s )
+#define	STRLEN64( s )			STRLEN64_( (uint64_t *)s )
+
+#define	STRNLEN16( s, maxlen )	STRLEN16_( (uint16_t *)s, maxlen )
+#define	STRNLEN32( s, maxlen )	STRLEN32_( (uint32_t *)s, maxlen )
+#define	STRNLEN64( s, maxlen )	STRLEN64_( (uint64_t *)s, maxlen )
+
+/** STRLENnn_ nn:16,32,64**/
+Inline size_t
+STRLEN16_(const uint16_t *s )
+{
+    size_t  i;
+    for( i = 0; ; i++ )
+        if( *s++ == 0 )
+            break;
+
+    return  i;
+}
+
+Inline size_t
+STRLEN32_(const uint32_t *s )
+{
+    size_t  i;
+    for( i = 0; ; i++ )
+        if( *s++ == 0 )
+            break;
+
+    return  i;
+}
+
+Inline size_t
+STRLEN64_(const uint64_t *s )
+{
+    size_t  i;
+    for( i = 0; ; i++ )
+        if( *s++ == 0 )
+            break;
+
+    return  i;
+}
+
+/** STRNLENnn_ nn:16,32,64**/
+Inline size_t
+STRNLEN16_(const uint16_t *s, size_t maxlen)
+{
+    size_t  i;
+    for( i = 0; i < maxlen; i++ )
+        if( *s++ == 0 )
+            break;
+
+    return  i;
+}
+
+Inline size_t
+STRNLEN32_(const uint32_t *s, size_t maxlen)
+{
+    size_t  i;
+    for( i = 0; i < maxlen; i++ )
+        if( *s++ == 0 )
+            break;
+
+    return  i;
+}
+
+Inline size_t
+STRNLEN64_(const uint64_t *s, size_t maxlen)
+{
+    size_t  i;
+    for( i = 0; i < maxlen; i++ )
+        if( *s++ == 0 )
+            break;
+
+    return  i;
+}
+
+
+#endif /* RPC_STRING_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/sChannel.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/sChannel.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/sChannel.cdl	(revision 398)
@@ -0,0 +1,67 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+signature	sServerChannelOpener {
+	ER		open( void );
+	ER		close( void );
+};
+
+signature	sChannel {
+	/* 送る */
+	ER		send( [in,size_is(size)] const int8_t  *buf, [in]int16_t  size, [in]TMO tmo );
+	/* 送信終わりの掃き出し（パケットの終わりで一回だけ呼出す */
+	ER		flush( [in]TMO tmo );       /* バッファリングしている場合の掃きだし */
+
+	/* 受け取る */
+	ER_UINT	receive( [out,size_is(size)] int8_t  *buf, [in]int16_t  size, [in]TMO tmo );
+
+	/* パケットの終わりまで受信した (flush の逆)。終わりに達していない場合 E_ILUSE */
+	ER		end_receive( void );
+
+	/* リセット */
+	ER		reset( void );       /* チャンネルをリセット */
+};
+
+/*
+ * size に uint16_t ではなく int16_t を用いるのは、下位層が ER_INT を返す場合を想定したもの．
+ *
+ * sChannel は TECS RPC の TDR の下位層である通信チャンネルとのインタフェースである．
+ * 通信チャンネルは、高水準 I/O のように、バッファリングされることを想定する．
+ * TDR からは、int8_t, int16_t, int32_t, int64_t, (int128_t), float32_t, double64_t bool_t, char_t のような基本型(無符号を含む)が渡される。
+ * 配列や構造体の場合であっても要素ごとに渡される。
+ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/sRPCErrorHandler.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/sRPCErrorHandler.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/sRPCErrorHandler.cdl	(revision 398)
@@ -0,0 +1,74 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+
+/* client side state */
+const	int16_t	RPCSTATE_CLIENT_GET_SEM		= 1;
+const	int16_t	RPCSTATE_CLIENT_SEND_SOP	= 2;
+const	int16_t	RPCSTATE_CLIENT_SEND_BODY	= 3;
+const	int16_t	RPCSTATE_CLIENT_SEND_EOP	= 4;
+const	int16_t	RPCSTATE_CLIENT_EXEC		= 5;
+const	int16_t	RPCSTATE_CLIENT_RECV_SOP	= 6;
+const	int16_t	RPCSTATE_CLIENT_RECV_BODY	= 7;
+const	int16_t	RPCSTATE_CLIENT_RECV_EOP	= 8;
+const	int16_t	RPCSTATE_CLIENT_RELEASE_SEM	= 9;
+
+/* server side state */
+const	int16_t	RPCSTATE_SERVER_GET_SEM		= 11;
+const	int16_t	RPCSTATE_SERVER_RECV_SOP	= 12;
+const	int16_t	RPCSTATE_SERVER_RECV_BODY	= 13;
+const	int16_t	RPCSTATE_SERVER_RECV_EOP	= 14;
+const	int16_t	RPCSTATE_SERVER_EXEC		= 15;
+const	int16_t	RPCSTATE_SERVER_SEND_SOP	= 16;
+const	int16_t	RPCSTATE_SERVER_SEND_BODY	= 17;
+const	int16_t	RPCSTATE_SERVER_SEND_EOP	= 18;
+const	int16_t	RPCSTATE_SERVER_RELEASE_SEM	= 19;
+
+/* error hadler */
+signature sRPCErrorHandler {
+	ER	errorOccured( [in]int16_t func_id, [in]ER er, [in]int16_t state );
+};
+
+/*
+ * 呼び元側では state が RPCSTATE_CLIENT_EXEC と等しいか大きい場合、
+ * 呼び先側では state が RPCSTATE_SERVER_EXEC と等しいか大きい場合、
+ * 呼び先関数の呼び出しには成功している。
+ *
+ * RPCErrorHandler が呼び出された時点で、send/receive 引数の解放は終わっている。
+ * このため、RPCErrorHandler の中で処理を打ち切っても(タスクの再起動などを行っても)、それらによるメモリリークが起きない。
+ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tDataqueueAdaptor_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tDataqueueAdaptor_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tDataqueueAdaptor_inline.h	(revision 398)
@@ -0,0 +1,221 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * #[</PREAMBLE>]# */
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eChannel
+ * entry port: eChannel
+ * signature:  sChannel
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eChannel_open
+ * name:         eChannel_open
+ * global_name:  tDataqueueAdaptor_eChannel_open
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eChannel_open(CELLIDX idx, const int8_t* arg, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eChannel_close
+ * name:         eChannel_close
+ * global_name:  tDataqueueAdaptor_eChannel_close
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eChannel_close(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eChannel_reset
+ * name:         eChannel_reset
+ * global_name:  tDataqueueAdaptor_eChannel_reset
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eChannel_reset(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	cEventflag_clear( 0 );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eChannel_send
+ * name:         eChannel_send
+ * global_name:  tDataqueueAdaptor_eChannel_send
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eChannel_send(CELLIDX idx, const int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	int     i;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	ercd = 0;
+	for( i = 0; i < size; i++ )
+		ercd |= cDataqueue_send( (intptr_t)((uint8_t)buf[ i ]) );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eChannel_flush
+ * name:         eChannel_flush
+ * global_name:  tDataqueueAdaptor_eChannel_flush
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eChannel_flush(CELLIDX idx, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eChannel_receive
+ * name:         eChannel_receive
+ * global_name:  tDataqueueAdaptor_eChannel_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER_UINT
+eChannel_receive(CELLIDX idx, int8_t* buf, int16_t size, TMO tmo)
+{
+	ER_UINT ercd = E_OK;
+	CELLCB	*p_cellcb;
+	intptr_t data;
+	int     i;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	/* printf( "DQA: receive(%d) ", size ); */
+	for( i = 0; i < size; i++ ){
+		ercd = cDataqueue_receive( &data );
+		buf[i] = (int8_t)data;
+		if( ercd != E_OK )
+			break;
+	}
+	if( ercd != E_OK )
+		return(ercd);
+	else
+		return i;
+}
+
+/* #[<ENTRY_FUNC>]# eChannel_end_receive
+ * name:         eChannel_end_receive
+ * global_name:  tDataqueueAdaptor_eChannel_end_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eChannel_end_receive(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tDataqueueOWChannel.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tDataqueueOWChannel.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tDataqueueOWChannel.cdl	(revision 398)
@@ -0,0 +1,80 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+
+/*
+ *celltype::tDataqueueAdaptor
+ */
+celltype tDataqueueAdaptor {
+	[inline]
+		entry sChannel   eChannel;
+	call  sDataqueue cDataqueue;
+	call  sEventflag cEventflag;
+};
+
+/*
+ *composite::tDataqueueOWChannel
+ */
+composite tDataqueueOWChannel {
+	entry sTDR       eTDR;
+	entry sDataqueue eDataqueue;
+	entry sEventflag eEventflag;
+	attr {
+		// Queue のデフォルトのサイズ
+		uint_t	queueSize = 64;
+	};
+
+	cell  tDataqueue Dataqueue{
+		count = composite.queueSize;
+
+	};
+	cell  tEventflag Eventflag{
+		flagPattern = 0;
+	};
+	cell  tDataqueueAdaptor DataqueueAdaptor{
+		cDataqueue = Dataqueue.eDataqueue;
+		cEventflag = Eventflag.eEventflag;
+	};
+	cell  tTDR TDR {
+		cChannel = DataqueueAdaptor.eChannel;
+	};
+
+	composite.eTDR       => TDR.eTDR;
+	composite.eDataqueue => Dataqueue.eDataqueue;
+	composite.eEventflag => Eventflag.eEventflag;
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tMessageBufferCEP.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tMessageBufferCEP.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tMessageBufferCEP.cdl	(revision 398)
@@ -0,0 +1,67 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+const uint16_t DEFAULT_MESSAGE_BUFFER_SIZE = 64;
+
+celltype tMessageBufferCEP {
+    [inline]
+        entry sChannel eChannel;
+    call  sMessageBuffer cMessageBuffer0;   /* Client(send) --> Server(receive) */
+    call  sMessageBuffer cMessageBuffer1;   /* Server(send) --> Client(receive) */
+
+    attr {
+        uint16_t  buf_size = DEFAULT_MESSAGE_BUFFER_SIZE;
+        /* この値は maxMessageSize に合わせる。小さいと、バッファオーバーランになる */
+    };
+    var {
+        /*
+         * OpaqueMarshalerPlugin の生成するマーシャラは、受信したいサイズ以上の領域を確保しない．
+         * 一方、tMessageBuffer は、最大 maxMessageSize 読み出しうる．
+         * 受信する側は、必ず maxMessageSize を用意しておく必要がある．
+         * このため、いったんバッファへ受け取ってコピーする必要がある．
+         */
+        [size_is(buf_size)]
+            int8_t *read_buf;
+        uint16_t   read_count;
+        uint16_t   n_read_buf_filled;
+
+        [size_is(buf_size)]
+            int8_t *write_buf;
+        uint16_t   write_count;
+    };
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tMessageBufferCEP_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tMessageBufferCEP_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tMessageBufferCEP_inline.h	(revision 398)
@@ -0,0 +1,203 @@
+#ifndef tMessageBufferCEP__INLINE_H
+#define tMessageBufferCEP__INLINE_H
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cMessageBuffer0 signature: sMessageBuffer context:task
+ *   ER             cMessageBuffer0_send( const uint8_t* message, uint32_t size );
+ *   ER             cMessageBuffer0_sendPolling( const uint8_t* message, uint32_t size );
+ *   ER             cMessageBuffer0_sendTimeout( const uint8_t* message, uint32_t size, TMO timeout );
+ *   ER_UINT        cMessageBuffer0_receive( uint8_t* message );
+ *   ER_UINT        cMessageBuffer0_receivePolling( uint8_t* message );
+ *   ER_UINT        cMessageBuffer0_receiveTimeout( uint8_t* message, TMO timeout );
+ *   ER             cMessageBuffer0_initialize( );
+ *   ER             cMessageBuffer0_refer( T_RMBF* pk_messageBufferStatus );
+ * call port: cMessageBuffer1 signature: sMessageBuffer context:task
+ *   ER             cMessageBuffer1_send( const uint8_t* message, uint32_t size );
+ *   ER             cMessageBuffer1_sendPolling( const uint8_t* message, uint32_t size );
+ *   ER             cMessageBuffer1_sendTimeout( const uint8_t* message, uint32_t size, TMO timeout );
+ *   ER_UINT        cMessageBuffer1_receive( uint8_t* message );
+ *   ER_UINT        cMessageBuffer1_receivePolling( uint8_t* message );
+ *   ER_UINT        cMessageBuffer1_receiveTimeout( uint8_t* message, TMO timeout );
+ *   ER             cMessageBuffer1_initialize( );
+ *   ER             cMessageBuffer1_refer( T_RMBF* pk_messageBufferStatus );
+ *
+ * #[</PREAMBLE>]# */
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eChannel
+ * entry port: eChannel
+ * signature:  sChannel
+2 * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eChannel_send
+ * name:         eChannel_send
+ * global_name:  tMessageBufferCEP_eChannel_send
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eChannel_send(CELLIDX idx, const int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+  int16_t write_count;
+    CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( size < 0 )
+      return E_PAR;
+  else if( size == 0 )
+      return E_OK;
+
+  write_count = 0;
+  while( write_count < size ){
+      VAR_write_buf[ VAR_write_count++ ] = buf[ write_count++ ];
+      if( VAR_write_count >= ATTR_buf_size ){
+          ercd = eChannel_flush( idx, tmo);
+          if( ercd != E_OK ){
+              break;
+          }
+      }
+  }
+
+  // syslog( LOG_INFO, "eChannel_send ercd=%d", ercd );
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eChannel_flush
+ * name:         eChannel_flush
+ * global_name:  tMessageBufferCEP_eChannel_flush
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eChannel_flush(CELLIDX idx, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  /* flush しなくても、いつも送られる */
+  if( VAR_write_count > 0 ){
+      ercd = cMessageBuffer0_sendTimeout( (const uint8_t *)VAR_write_buf, VAR_write_count, tmo );
+  }
+  // syslog( LOG_INFO, "eChannel_flush ercd=%d count=%d", ercd, VAR_write_count );
+  VAR_write_count = 0;
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eChannel_receive
+ * name:         eChannel_receive
+ * global_name:  tMessageBufferCEP_eChannel_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER_UINT
+eChannel_receive(CELLIDX idx, int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		   ercd = E_OK;
+	CELLCB	 *p_cellcb;
+  int16_t  count = 0;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  if( size == 0 )
+      return 0;
+
+  while( count < size ){
+      if( VAR_n_read_buf_filled == 0 ){
+          ercd = cMessageBuffer1_receiveTimeout( (uint8_t *)VAR_read_buf, tmo );
+          if( ercd < 0  )
+              break;
+          VAR_n_read_buf_filled = ercd;
+      }
+      while( count < size && VAR_read_count < VAR_n_read_buf_filled ){
+          buf[ count ] = VAR_read_buf[ VAR_read_count ];
+          count++;
+          VAR_read_count++;
+      }
+      if( VAR_read_count >= VAR_n_read_buf_filled ){
+          VAR_n_read_buf_filled = 0;
+          VAR_read_count = 0;
+      }
+      ercd = count;
+  }
+  // syslog( LOG_INFO, "eChannel_receive ercd=%d", ercd );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eChannel_end_receive
+ * name:         eChannel_end_receive
+ * global_name:  tMessageBufferCEP_eChannel_end_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eChannel_end_receive(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eChannel_reset
+ * name:         eChannel_reset
+ * global_name:  tMessageBufferCEP_eChannel_reset
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eChannel_reset(CELLIDX idx)
+{
+  ER		ercd0 = E_OK, ercd1 = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+  ercd0 = cMessageBuffer0_initialize( );
+  ercd1 = cMessageBuffer1_initialize( );
+
+	return(ercd1 != E_OK ? ercd1 : ercd0);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
+
+#endif /* tMessageBufferCEP_INLINEH */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tMessageBufferChannel.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tMessageBufferChannel.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tMessageBufferChannel.cdl	(revision 398)
@@ -0,0 +1,73 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 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$
+ */
+
+composite tMessagebufferChannel {
+    //entry sTDR       eTDR;
+    entry sEventflag eEventflag;
+    entry sSemaphore eSemaphore;
+    entry sMessageBuffer eMessageBuffer;
+
+    attr {
+        // Queue のデフォルトのサイズ
+        uint32_t	bufferSize = 256;
+    };
+
+    cell  tMessageBuffer Messagebuffer{
+        maxMessageSize = 128;
+        bufferSize = composite.bufferSize;
+    };
+    cell  tEventflag Eventflag{
+        flagPattern = 0;
+    };
+    cell tSemaphore Semaphore{
+        attribute = C_EXP("TA_NULL");
+        initialCount = 0;
+    };
+
+    //cell  tTDR TDR {
+    //	cChannel = MessagebufferAdaptor.eChannel;
+    //};
+
+    //composite.eTDR       => TDR.eTDR;
+    composite.eEventflag => Eventflag.eEventflag;
+    composite.eSemaphore => Semaphore.eSemaphore;
+    composite.eMessageBuffer => Messagebuffer.eMessageBuffer;
+
+};
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tNBOTDR_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tNBOTDR_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tNBOTDR_inline.h	(revision 398)
@@ -0,0 +1,1647 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * tmo              TMO              VAR_tmo         
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port: cChannel signature: sChannel context:task 
+ *   ER             cChannel_send( const int8_t* buf, int16_t size, TMO tmo );
+ *   ER             cChannel_flush( TMO tmo );
+ *   ER_UINT        cChannel_receive( int8_t* buf, int16_t size, TMO tmo );
+ *   ER             cChannel_end_receive( );
+ *   ER             cChannel_reset( );
+ * require port: signature:sSysLog context:task
+ *   ER             write( uint_t prio, const SYSLOG* p_syslog );
+ *   ER_UINT        read( SYSLOG* p_syslog );
+ *   ER             mask( uint_t logmask, uint_t lowmask );
+ *   ER             refer( T_SYSLOG_RLOG* pk_rlog );
+ *
+ * #[</PREAMBLE>]# */
+
+/*
+ * marhaler, unmarshaler が使用する STRLEN 関数を定義する
+ *  marshaler, unmarshaler は必ず TDR は に結合されるため
+ */
+#include	"rpc_string.h"
+
+/*
+ * Network Byte Order TECS Data Representation
+ *
+ *  NBOTDR is one of sTDR implementation and is default TDR for OpaqueRPC.
+ *  NBOTDR always sends and receives data in Big Endian (Network Byte Order).
+ *  So NBOTDR is useful with distributed hybrid systems.
+ */
+
+/*
+ * Macro Symbols:
+ * 1) endian
+ *  NBOTDR_BIGENDIAN
+ *  NBOTDR_LITTLEENDIAN
+ *   if these macros are not specified, endian is automatically decided.
+ * 2) size of each type in bits.
+ *  NBOTDR_LONG_BIT (32)
+ *  NBOTDR_SHORT_BIT (16)
+ *  NBOTDR_INT_BIT (32)
+ *  NBOTDR_INTPTR_BIT (32)
+ *   default value in parenthesises
+ *   normally use default value
+ */
+
+/*
+ * 無調整型だが、いくらか暫定的な実装になっている
+ * ・ntohX(), htonX() は int64_t 型に定義されている (32bitならオーバヘッド大)
+ * ・int128_t, uint128_t は tecs.h で typedef された型である
+ * ・BIGENDIAN 判定は動的になっている (恐らく最適化で定数判定にされることはない)
+ */
+
+#if defined( NBOTDR_BIGENDIAN )
+#define	IS_BIGENDIAN()	(1)
+# if defined( NBOTDR_LITTLEENDIAN )
+#   error  "Don't specify both NBOTDR_LITTLEENDIAN and NBOTDR_BIGENDIAN"
+# endif
+#elif defined( NBOTDR_LITTLEENDIAN )
+#define	IS_BIGENDIAN()	(0)
+#else
+/* BIGENDIAN かどうか自動判定 */
+static const uint16_t	endian_check = 0xff00;
+#define	IS_BIGENDIAN()	(*(uint8_t *)&endian_check)
+#warning "it is better to specify -D NBOTDR_BIGENDIAN or -D NBOTDR_LITTLEENDIAN"
+#endif
+
+#if ! defined( NBOTDR_LONG_BIT )
+#define	NBOTDR_LONG_BIT	32
+#endif
+#if NBOTDR_LONG_BIT == 32
+#  define  NTOHL( d, sz )	ntoh32( d )
+#  define  HTONL( d, sz )	hton32( d )
+typedef		int32_t		TDR_LONG;
+typedef		uint32_t	TDR_ULONG;
+#elif NBOTDR_LONG_BIT == 64
+#  define  NTOHL( d, sz )	ntoh64( d )
+#  define  HTONL( d, sz )	hton64( d )
+typedef		int64_t		TDR_LONG;
+typedef		uint64_t	TDR_ULONG;
+#elif NBOTDR_LONG_BIT == 128
+#  define  NTOHL( d, sz )	ntoh128( d )
+#  define  HTONL( d, sz )	hton128( d )
+typedef		int128_t	TDR_LONG;
+typedef		uint128_t	TDR_ULONG;
+#elif ! defined( NBOTDR_LONG_BIT )
+#  define  NTOHL	ntohX
+#  define  HTONL	htonX
+#  warning "it is better to specify -D NBOTDR_LONG_BIT=N  N: 32, 64, 128"
+#else
+#  error  "NBOTDR_LONG_BIT must be 32, 64 or 128"
+#endif
+
+#if ! defined( NBOTDR_SHORT_BIT )
+#define	NBOTDR_SHORT_BIT	16
+#endif
+#if NBOTDR_SHORT_BIT == 16
+#  define  NTOHS( d, sz )	ntoh16( d )
+#  define  HTONS( d, sz )	hton16( d )
+typedef		int16_t		TDR_SHORT;
+typedef		uint16_t	TDR_USHORT;
+#elif NBOTDR_SHORT_BIT == 32
+#  define  NTOHS( d, sz )	ntoh32( d )
+#  define  HTONS( d, sz )	hton32( d )
+typedef		int32_t		TDR_SHORT;
+typedef		uint32_t	TDR_USHORT;
+#elif NBOTDR_SHORT_BIT == 64
+#  define  NTOHS( d, sz )	ntoh64( d )
+#  define  HTONS( d, sz )	hton64( d )
+typedef		int64_t		TDR_SHORT;
+typedef		uint64_t	TDR_USHORT;
+#elif ! defined( NBOTDR_SHORT_BIT )
+#  define  NTOHS( d, sz )	ntohX( d, sz )
+#  define  HTONS( d, sz )	htonX( d, sz )
+#  warning "it is better to specify -D NBOTDR_SHORT_BIT=N  N: 16, 32, 64"
+#else
+#  error  "NBOTDR_SHORT_BIT must be 16, 32 or 64"
+#endif
+
+#if ! defined( NBOTDR_INT_BIT )
+#define	NBOTDR_INT_BIT	32
+#endif
+#if NBOTDR_INT_BIT == 16
+#  define  NTOHI( d, sz )	ntoh16( d )
+#  define  HTONI( d, sz )	hton16( d )
+typedef		int16_t		TDR_INT;
+typedef		uint16_t	TDR_UINT;
+#elif NBOTDR_INT_BIT == 32
+#  define  NTOHI( d, sz )	ntoh32( d )
+#  define  HTONI( d, sz )	hton32( d )
+typedef		int32_t		TDR_INT;
+typedef		uint32_t	TDR_UINT;
+#elif NBOTDR_INT_BIT == 64
+#  define  NTOHI( d, sz )	ntoh64( d )
+#  define  HTONI( d, sz )	hton64( d )
+typedef		int64_t		TDR_INT;
+typedef		uint64_t	TDR_UINT;
+#elif NBOTDR_INT_BIT == 128
+#  define  NTOHI( d, sz )	ntoh128( d )
+#  define  HTONI( d, sz )	hton128( d )
+typedef		int128_t	TDR_INT;
+typedef		uint128_t	TDR_UINT;
+#elif ! defined( NBOTDR_INT_BIT )
+#  define  NTOHI( d, sz )	ntohX( d, sz )
+#  define  HTONI( d, sz )	htonX( d, sz )
+#  warning "it is better to specify -D NBOTDR_INT_BIT=N  N: 16, 32, 64, 128"
+#else
+#  error  "NBOTDR_INT_BIT must be 16, 32, 64 or 128"
+#endif
+
+#if ! defined( NBOTDR_INTPTR_BIT )
+#define	NBOTDR_INTPTR_BIT	32
+#endif
+#if NBOTDR_INTPTR_BIT == 16
+#  define  NTOHIP( d, sz )	ntoh16( d )
+#  define  HTONIP( d, sz )	hton16( d )
+typedef		int16_t		TDR_INTPTR;
+#elif NBOTDR_INTPTR_BIT == 32
+#  define  NTOHIP( d, sz )	ntoh32( d )
+#  define  HTONIP( d, sz )	hton32( d )
+typedef		int32_t		TDR_INTPTR;
+#elif NBOTDR_INTPTR_BIT == 64
+#  define  NTOHIP( d, sz )	ntoh64( d )
+#  define  HTONIP( d, sz )	hton64( d )
+typedef		int64_t		TDR_INTPTR;
+#elif NBOTDR_INTPTR_BIT == 128
+#  define  NTOHIP( d, sz )	ntoh128( d )
+#  define  HTONIP( d, sz )	hton128( d )
+typedef		int128_t	TDR_INTPTR;
+#elif ! defined( NBOTDR_INTPTR_BIT )
+#  define  NTOHIP( d, sz )		ntohX( d, sz )
+#  define  HTONIP( d, sz )		htonX( d, sz )
+#  warning "it is better to specify -D NBOTDR_INTPTR_BIT=N  N: 16, 32, 64, 128"
+#else
+#  error  "NBOTDR_INTPTR_BIT must be 16, 32, 64 or 128 "
+#endif
+
+Inline int16_t
+hton16( int16_t d )
+{
+	if( IS_BIGENDIAN() )
+		return d;		// big endian
+	else{
+		union  {
+			int8_t	by[2];
+			int16_t	d;
+		} d0, d1;
+		// syslog( LOG_INFO, "### little endian ###" );
+		d0.d = d;
+		d1.by[0] = d0.by[1];
+		d1.by[1] = d0.by[0];
+		return d1.d;
+	}
+}
+
+Inline int32_t
+hton32( int32_t d )
+{
+	if( IS_BIGENDIAN() )
+		return d;
+	else{
+		union  {
+			int8_t	by[4];
+			int32_t	d;
+		} d0, d1;
+		d0.d = d;
+		d1.by[0] = d0.by[3];
+		d1.by[1] = d0.by[2];
+		d1.by[2] = d0.by[1];
+		d1.by[3] = d0.by[0];
+		return d1.d;
+	}
+}
+
+Inline int64_t
+hton64( int64_t d )
+{
+	if( IS_BIGENDIAN() )
+		return d;
+	else{
+		union  {
+			int8_t	by[8];
+			int64_t	d;
+		} d0, d1;
+		d0.d = d;
+		d1.by[0] = d0.by[7];
+		d1.by[1] = d0.by[6];
+		d1.by[2] = d0.by[5];
+		d1.by[3] = d0.by[4];
+		d1.by[4] = d0.by[3];
+		d1.by[5] = d0.by[2];
+		d1.by[6] = d0.by[1];
+		d1.by[7] = d0.by[0];
+		return d1.d;
+	}
+}
+
+Inline int128_t
+hton128( int128_t d )
+{
+	if( IS_BIGENDIAN() )
+		return d;
+	else{
+		/* この実装は tecs.h で typedef した int128_t に適合 */
+		int128_t d1;
+		d1.hi = hton64( d.lo );
+		d1.lo = hton64( d.hi );
+		return	d1;
+	}
+}
+
+Inline int16_t
+ntoh16( int16_t d )
+{
+	if( IS_BIGENDIAN() )
+		return d;
+	else{
+		union  {
+			int8_t	by[2];
+			int16_t	d;
+		} d0, d1;
+		d0.d = d;
+		d1.by[0] = d0.by[1];
+		d1.by[1] = d0.by[0];
+		return d1.d;
+	}
+}
+
+Inline int32_t
+ntoh32( int32_t d )
+{
+	if( IS_BIGENDIAN() )
+		return d;
+	else{
+		union  {
+			int8_t	by[4];
+			int32_t	d;
+		} d0, d1;
+		d0.d = d;
+		d1.by[0] = d0.by[3];
+		d1.by[1] = d0.by[2];
+		d1.by[2] = d0.by[1];
+		d1.by[3] = d0.by[0];
+		return d1.d;
+	}
+}
+
+Inline int64_t
+ntoh64( int64_t d )
+{
+	if( IS_BIGENDIAN() )
+		return d;
+	else{
+		union  {
+			int8_t	by[8];
+			int64_t	d;
+		} d0, d1;
+		d0.d = d;
+		d1.by[0] = d0.by[7];
+		d1.by[1] = d0.by[6];
+		d1.by[2] = d0.by[5];
+		d1.by[3] = d0.by[4];
+		d1.by[4] = d0.by[3];
+		d1.by[5] = d0.by[2];
+		d1.by[6] = d0.by[1];
+		d1.by[7] = d0.by[0];
+		return d1.d;
+	}
+}
+
+/*** unsigned 用の関数 (128 bit 版のみ用意) ***/
+Inline int128_t
+ntoh128( int128_t d )
+{
+	if( IS_BIGENDIAN() )
+		return d;
+	else{
+		/* この実装は tecs.h で typedef した int128_t に適合 */
+		int128_t d1;
+		d1.hi = ntoh64( d.lo );
+		d1.lo = ntoh64( d.hi );
+		return	d1;
+	}
+}
+
+Inline uint128_t
+hton128u( uint128_t d )
+{
+	if( IS_BIGENDIAN() )
+		return d;
+	else{
+		/* この実装は tecs.h で typedef した int128_t に適合 */
+		uint128_t d1;
+		d1.hi = hton64( d.lo );
+		d1.lo = hton64( d.hi );
+		return	d1;
+	}
+}
+
+Inline uint128_t
+ntoh128u( uint128_t d )
+{
+	if( IS_BIGENDIAN() )
+		return d;
+	else{
+		/* この実装は tecs.h で typedef した int128_t に適合 */
+		uint128_t d1;
+		d1.hi = ntoh64( d.lo );
+		d1.lo = ntoh64( d.hi );
+		return	d1;
+	}
+}
+
+/************************************************
+ *  htonX, ntohX は 16, 32, 64 にのみ対応できる *
+ ************************************************/
+Inline int64_t
+htonX( int64_t d, int_t sz )
+{
+	switch( sz ){
+	case	2:	return	hton16( d );
+	case	4:	return	hton32( d );
+	case	8:	return	hton64( d );
+	default:	return	0;			// # mikan
+	};
+}
+
+Inline int64_t
+ntohX( int64_t d, int_t sz )
+{
+	switch( sz ){
+	case	2:	return	ntoh16( d );
+	case	4:	return	ntoh32( d );
+	case	8:	return	ntoh64( d );
+	default:	return	0;			// # mikan
+	};
+}
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTDR
+ * entry port: eTDR
+ * signature:  sTDR
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTDR_reset
+ * name:         eTDR_reset
+ * global_name:  tNBOTDR_eTDR_reset
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_reset(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	syslog( LOG_INFO, "TDR: resetting channel" );
+	ercd = cChannel_reset();
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_sendSOP
+ * name:         eTDR_sendSOP
+ * global_name:  tNBOTDR_eTDR_sendSOP
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_sendSOP(CELLIDX idx, bool_t b_client )
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	uint16_t sopMagic;
+	uint8_t	val;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+#ifdef RPC_DEBUG
+	syslog(LOG_INFO, "eTDR_sendSOP(b_client=%d)", b_client);
+#endif
+    if( b_client )
+		sopMagic = TDR_SOP_MAGIC1;
+	else
+		sopMagic = TDR_SOP_MAGIC2;
+
+	/*
+	 * SOP パケットの送信
+	 * パケットシーケンスが多少崩れても回復できるように、バイト単位で送る
+	 * 上位バイト、下位バイトの順に送る
+	 */
+
+	val = (uint8_t)(sopMagic>>8);
+	ercd = eTDR_putUInt8( idx, val );		/* 上位8ビット */
+	if( ercd != E_OK )
+		return	ercd;
+
+	val = (uint8_t)(sopMagic&0xff);			/* 下位8ビット */
+	ercd = eTDR_putUInt8( idx, val );
+
+	return	ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_receiveSOP
+ * name:         eTDR_receiveSOP
+ * global_name:  tNBOTDR_eTDR_receiveSOP
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_receiveSOP(CELLIDX idx, bool_t b_client )
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	uint16_t sopMagic;
+	uint8_t val;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+#ifdef RPC_DEBUG
+	syslog(LOG_INFO, "eTDR_receiveSOP(b_client=%d)", b_client);
+#endif
+
+    if( b_client )
+		sopMagic = TDR_SOP_MAGIC2;
+	else
+		sopMagic = TDR_SOP_MAGIC1;
+
+	if( (ercd=eTDR_getUInt8( idx, &val )) != E_OK )
+		;
+	else if( val != (uint8_t)(sopMagic>>8) ){
+		ercd = E_MAGIC;
+	}
+	else if((ercd=eTDR_getUInt8( idx, &val )) != E_OK )
+		;
+	else if( val != (uint8_t)sopMagic ){
+		ercd = E_MAGIC;
+	}
+
+	if( ercd != E_OK )
+		syslog( LOG_INFO, "receiveSOP: ERCD=%d", ercd );
+
+	return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_sendEOP
+ * name:         eTDR_sendEOP
+ * global_name:  tNBOTDR_eTDR_sendEOP
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_sendEOP(CELLIDX idx, bool_t b_continue )
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	uint16_t magic;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+#ifdef RPC_DEBUG
+	syslog(LOG_INFO, "eTDR_sendEOP(b_continue=%d)", b_continue);
+#endif
+
+	if( b_continue )
+		magic = TDR_EOP_MAGIC1;
+	else
+		magic = TDR_EOP_MAGIC2;
+
+	/* EOP magic の送信 */
+	if( (ercd = eTDR_putUInt16( idx, magic )) != E_OK )
+		return ercd;
+
+	return cChannel_flush(VAR_tmo);
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_receiveEOP
+ * name:         eTDR_receiveEOP
+ * global_name:  tNBOTDR_eTDR_receiveEOP
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_receiveEOP(CELLIDX idx, bool_t b_continue)
+{
+	ER		ercd = E_OK, er2;
+	CELLCB	*p_cellcb;
+	uint16_t magic;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+#ifdef RPC_DEBUG
+	syslog(LOG_INFO, "eTDR_receiveEOP(b_continue=%d)",b_continue);
+#endif
+/* mikan cChannel EOF get_* */
+/* mikan magic EOF */
+
+	if( (ercd=eTDR_getUInt16( idx, &magic )) == E_OK ){
+		if( (b_continue && magic == TDR_EOP_MAGIC1) || (!b_continue && magic == TDR_EOP_MAGIC2) ){
+		} else {
+			ercd = E_MAGIC;
+		}
+	}
+	er2 = cChannel_end_receive();
+	return ercd != E_OK ? ercd : er2;
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt8
+ * name:         eTDR_putInt8
+ * global_name:  tNBOTDR_eTDR_putInt8
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt8(CELLIDX idx, int8_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt16
+ * name:         eTDR_putInt16
+ * global_name:  tNBOTDR_eTDR_putInt16
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt16(CELLIDX idx, int16_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	in = hton16( in );
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt32
+ * name:         eTDR_putInt32
+ * global_name:  tNBOTDR_eTDR_putInt32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt32(CELLIDX idx, int32_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	in = hton32( in );
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt64
+ * name:         eTDR_putInt64
+ * global_name:  tNBOTDR_eTDR_putInt64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt64(CELLIDX idx, int64_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	in = hton64( in );
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt128
+ * name:         eTDR_putInt128
+ * global_name:  tNBOTDR_eTDR_putInt128
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt128(CELLIDX idx, int128_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	in = hton128( in );
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt8
+ * name:         eTDR_getInt8
+ * global_name:  tNBOTDR_eTDR_getInt8
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt8(CELLIDX idx, int8_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	 *p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt16
+ * name:         eTDR_getInt16
+ * global_name:  tNBOTDR_eTDR_getInt16
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt16(CELLIDX idx, int16_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	*out = ntoh16( *out );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt32
+ * name:         eTDR_getInt32
+ * global_name:  tNBOTDR_eTDR_getInt32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt32(CELLIDX idx, int32_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	*out = ntoh32( *out );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt64
+ * name:         eTDR_getInt64
+ * global_name:  tNBOTDR_eTDR_getInt64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt64(CELLIDX idx, int64_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	*out = ntoh64( *out );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt128
+ * name:         eTDR_getInt128
+ * global_name:  tNBOTDR_eTDR_getInt128
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt128(CELLIDX idx, int128_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	*out = ntoh128( *out );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt8
+ * name:         eTDR_putUInt8
+ * global_name:  tNBOTDR_eTDR_putUInt8
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt8(CELLIDX idx, uint8_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt16
+ * name:         eTDR_putUInt16
+ * global_name:  tNBOTDR_eTDR_putUInt16
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt16(CELLIDX idx, uint16_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	in = hton16( in );
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt32
+ * name:         eTDR_putUInt32
+ * global_name:  tNBOTDR_eTDR_putUInt32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt32(CELLIDX idx, uint32_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	in = hton32( in );
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt64
+ * name:         eTDR_putUInt64
+ * global_name:  tNBOTDR_eTDR_putUInt64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt64(CELLIDX idx, uint64_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	in = hton64( in );
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt128
+ * name:         eTDR_putUInt128
+ * global_name:  tNBOTDR_eTDR_putUInt128
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt128(CELLIDX idx, uint128_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	in = hton128u( in );
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt8
+ * name:         eTDR_getUInt8
+ * global_name:  tNBOTDR_eTDR_getUInt8
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt8(CELLIDX idx, uint8_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt16
+ * name:         eTDR_getUInt16
+ * global_name:  tNBOTDR_eTDR_getUInt16
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt16(CELLIDX idx, uint16_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	*out = ntoh16( *out );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt32
+ * name:         eTDR_getUInt32
+ * global_name:  tNBOTDR_eTDR_getUInt32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt32(CELLIDX idx, uint32_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	*out = ntoh32( *out );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt64
+ * name:         eTDR_getUInt64
+ * global_name:  tNBOTDR_eTDR_getUInt64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt64(CELLIDX idx, uint64_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	*out = ntoh64( *out );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt128
+ * name:         eTDR_getUInt128
+ * global_name:  tNBOTDR_eTDR_getUInt128
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt128(CELLIDX idx, uint128_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	*out = ntoh128u( *out );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putChar
+ * name:         eTDR_putChar
+ * global_name:  tNBOTDR_eTDR_putChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putChar(CELLIDX idx, char_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getChar
+ * name:         eTDR_getChar
+ * global_name:  tNBOTDR_eTDR_getChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getChar(CELLIDX idx, char_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putBool
+ * name:         eTDR_putBool
+ * global_name:  tNBOTDR_eTDR_putBool
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putBool(CELLIDX idx, bool_t in)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	eTDR_putUInt8(idx, (uint8_t)(in != 0) );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getBool
+ * name:         eTDR_getBool
+ * global_name:  tNBOTDR_eTDR_getBool
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getBool(CELLIDX idx, bool_t* out)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	uint8_t	val;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	ercd = eTDR_getUInt8(idx, &val );
+	if( ercd != E_OK )
+		return ercd;
+	*out = (val != 0);
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putFloat32
+ * name:         eTDR_putFloat32
+ * global_name:  tNBOTDR_eTDR_putFloat32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putFloat32(CELLIDX idx, float32_t in)
+{
+	CELLCB	*p_cellcb;
+    int32_t val;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	val = hton32( *(int32_t*)&in );
+	return cChannel_send( (int8_t *)&val, (int16_t)sizeof( val ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putDouble64
+ * name:         eTDR_putDouble64
+ * global_name:  tNBOTDR_eTDR_putDouble64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putDouble64(CELLIDX idx, double64_t in)
+{
+    int64_t val;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+    val = *(int64_t *)&in;
+	val = hton64( val );
+	return cChannel_send( (int8_t *)&val, (int16_t)sizeof( val ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getFloat32
+ * name:         eTDR_getFloat32
+ * global_name:  tNBOTDR_eTDR_getFloat32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getFloat32(CELLIDX idx, float32_t* out)
+{
+	ER_UINT		er_sz = E_OK;
+    int32_t   val;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)&val, (int16_t)sizeof( val ), VAR_tmo );
+	val = ntoh32( val );
+    *out = *(float32_t *)&val;
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getDouble64
+ * name:         eTDR_getDouble64
+ * global_name:  tNBOTDR_eTDR_getDouble64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getDouble64(CELLIDX idx, double64_t* out)
+{
+	ER_UINT		er_sz = E_OK;
+    int64_t     val;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)&val, (int16_t)sizeof( val ), VAR_tmo );
+	val = ntoh64( val );
+    *out = *(double64_t *)&val;
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putSChar
+ * name:         eTDR_putSChar
+ * global_name:  tNBOTDR_eTDR_putSChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putSChar(CELLIDX idx, signed char in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putShort
+ * name:         eTDR_putShort
+ * global_name:  tNBOTDR_eTDR_putShort
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putShort(CELLIDX idx, short_t in)
+{
+	CELLCB	*p_cellcb;
+	TDR_SHORT	IN = in;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	IN = HTONS( IN, sizeof IN );
+	return cChannel_send( (int8_t *)&IN, (int16_t)sizeof( IN ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt
+ * name:         eTDR_putInt
+ * global_name:  tNBOTDR_eTDR_putInt
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt(CELLIDX idx, int_t in)
+{
+	CELLCB	*p_cellcb;
+	TDR_INT	IN = in;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	IN = HTONI( IN, sizeof IN );
+	return cChannel_send( (int8_t *)&IN, (int16_t)sizeof( IN ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putLong
+ * name:         eTDR_putLong
+ * global_name:  tNBOTDR_eTDR_putLong
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putLong(CELLIDX idx, long_t in)
+{
+	CELLCB	*p_cellcb;
+	TDR_LONG	IN = in;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	IN = HTONL( IN, sizeof IN );
+	return cChannel_send( (int8_t *)&IN, (int16_t)sizeof( IN ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getSChar
+ * name:         eTDR_getSChar
+ * global_name:  tNBOTDR_eTDR_getSChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getSChar(CELLIDX idx, signed char* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getShort
+ * name:         eTDR_getShort
+ * global_name:  tNBOTDR_eTDR_getShort
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getShort(CELLIDX idx, short* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	TDR_SHORT	OUT;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)&OUT, (int16_t)sizeof( OUT ), VAR_tmo );
+	*out = NTOHS( OUT, sizeof OUT );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( OUT ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt
+ * name:         eTDR_getInt
+ * global_name:  tNBOTDR_eTDR_getInt
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt(CELLIDX idx, int_t* out)
+{
+	ER_UINT		 er_sz;
+	CELLCB		*p_cellcb;
+	TDR_INT	OUT;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)&OUT, (int16_t)sizeof( OUT ), VAR_tmo );
+	*out = NTOHI( OUT, sizeof OUT );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( OUT ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getLong
+ * name:         eTDR_getLong
+ * global_name:  tNBOTDR_eTDR_getLong
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getLong(CELLIDX idx, long_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	TDR_LONG	OUT;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)&OUT, (int16_t)sizeof( OUT ), VAR_tmo );
+	*out = NTOHL( OUT, sizeof OUT );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( OUT ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUChar
+ * name:         eTDR_putUChar
+ * global_name:  tNBOTDR_eTDR_putUChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUChar(CELLIDX idx, unsigned char in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUShort
+ * name:         eTDR_putUShort
+ * global_name:  tNBOTDR_eTDR_putUShort
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUShort(CELLIDX idx, ushort_t in)
+{
+	CELLCB	*p_cellcb;
+	TDR_USHORT	IN = in;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	IN = HTONS( IN, sizeof IN );
+	return cChannel_send( (int8_t *)&IN, (int16_t)sizeof( IN ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt
+ * name:         eTDR_putUInt
+ * global_name:  tNBOTDR_eTDR_putUInt
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt(CELLIDX idx, uint_t in)
+{
+	CELLCB		*p_cellcb;
+	TDR_UINT	IN = in;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	IN = HTONI( IN, sizeof IN );
+	return cChannel_send( (int8_t *)&IN, (int16_t)sizeof( IN ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putULong
+ * name:         eTDR_putULong
+ * global_name:  tNBOTDR_eTDR_putULong
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putULong(CELLIDX idx, ulong_t in)
+{
+	CELLCB	*p_cellcb;
+	TDR_ULONG	IN = in;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	IN = HTONL( IN, sizeof IN );
+	return cChannel_send( (int8_t *)&IN, (int16_t)sizeof( IN ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUChar
+ * name:         eTDR_getUChar
+ * global_name:  tNBOTDR_eTDR_getUChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUChar(CELLIDX idx, unsigned char* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUShort
+ * name:         eTDR_getUShort
+ * global_name:  tNBOTDR_eTDR_getUShort
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUShort(CELLIDX idx, unsigned short* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	TDR_USHORT	OUT;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)&OUT, (int16_t)sizeof( OUT ), VAR_tmo );
+	*out = NTOHS( OUT, sizeof OUT );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( OUT ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt
+ * name:         eTDR_getUInt
+ * global_name:  tNBOTDR_eTDR_getUInt
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt(CELLIDX idx, uint_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	TDR_UINT	OUT;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)&OUT, (int16_t)sizeof( OUT ), VAR_tmo );
+	*out = NTOHI( OUT, sizeof OUT );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( OUT ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getULong
+ * name:         eTDR_getULong
+ * global_name:  tNBOTDR_eTDR_getULong
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getULong(CELLIDX idx, ulong_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	TDR_ULONG	OUT;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)&OUT, (int16_t)sizeof( OUT ), VAR_tmo );
+	*out = NTOHL( OUT, sizeof OUT );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( OUT ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putIntptr
+ * name:         eTDR_putIntptr
+ * global_name:  tNBOTDR_eTDR_putIntptr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putIntptr(CELLIDX idx, const intptr_t ptr)
+{
+	CELLCB	*p_cellcb;
+	TDR_INTPTR	IN = ptr;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	IN = HTONIP( IN, sizeof IN );
+	return cChannel_send( (int8_t *)&IN, (int16_t)sizeof( IN ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getIntptr
+ * name:         eTDR_getIntptr
+ * global_name:  tNBOTDR_eTDR_getIntptr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getIntptr(CELLIDX idx, intptr_t* ptr)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	TDR_INTPTR	OUT;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)&OUT, (int16_t)sizeof( OUT ), VAR_tmo );
+	*ptr = NTOHIP( OUT, sizeof OUT );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( OUT ) ? E_OK : E_BOVR );
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tPPAllocator.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tPPAllocator.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tPPAllocator.c	(revision 398)
@@ -0,0 +1,146 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * heap_size        uint32_t         ATTR_heap_size  
+ * buf              int8_t*          VAR_buf         
+ * allocated_size   uint32_t         VAR_allocated_size
+ *
+ * #[</PREAMBLE>]# */
+
+#include "tPPAllocator_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# ePPAllocator
+ * entry port: ePPAllocator
+ * signature:  sPPAllocator
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# ePPAllocator_alloc
+ * name:         ePPAllocator_alloc
+ * global_name:  tPPAllocator_ePPAllocator_alloc
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+ePPAllocator_alloc(CELLIDX idx, uint32_t size, void** ptr)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	if( size + VAR_allocatedSize > ATTR_heapSize ){
+		ercd = E_NOMEM;
+	}
+	else {
+		*ptr = (void *)(VAR_buf+VAR_allocatedSize);
+		VAR_allocatedSize += size;
+	}
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# ePPAllocator_dealloc
+ * name:         ePPAllocator_dealloc
+ * global_name:  tPPAllocator_ePPAllocator_dealloc
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+ePPAllocator_dealloc(CELLIDX idx, const void* ptr)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	if( (uintptr_t)ptr < (uintptr_t)VAR_buf || (uintptr_t)ptr >= (uintptr_t)(VAR_buf+VAR_allocatedSize) ){
+		ercd = E_PAR;
+	}
+	else {
+		VAR_allocatedSize = (uintptr_t)ptr - (uintptr_t)VAR_buf;
+	}
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# ePPAllocator_dealloc_all
+ * name:         ePPAllocator_dealloc_all
+ * global_name:  tPPAllocator_ePPAllocator_dealloc_all
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+ePPAllocator_dealloc_all(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	VAR_allocatedSize = 0;
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCDedicatedTaskMain.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCDedicatedTaskMain.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCDedicatedTaskMain.c	(revision 398)
@@ -0,0 +1,86 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port : cMain  signature: sTaskBody context: task
+ *   void           cMain_main( );
+ *
+ * #[</PREAMBLE>]# */
+
+#include "tRPCDedicatedTaskMain_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eMain
+ * entry port: eMain
+ * signature:  sTaskBody
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eMain_main
+ * name:         eMain_main
+ * global_name:  tRPCDedicatedTaskMain_eMain_main
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eMain_main(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	while( cMain_main() == E_OK ){
+	}
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCDedicatedTaskMainWithOpener.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCDedicatedTaskMainWithOpener.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCDedicatedTaskMainWithOpener.c	(revision 398)
@@ -0,0 +1,99 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port : cMain  signature: sTaskBody context: task
+ *   void           cMain_main( );
+ *
+ * #[</PREAMBLE>]# */
+
+#include "tRPCDedicatedTaskMainWithOpener_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eMain
+ * entry port: eMain
+ * signature:  sTaskBody
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eMain_main
+ * name:         eMain_main
+ * global_name:  tRPCDedicatedTaskMain_eMain_main
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eMain_main(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	ER		er;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	while(1){
+#ifdef RPC_DEBUG
+		syslog(LOG_INFO, "begin RPC unmarshaler task" );
+		syslog(LOG_INFO, "Opening RPC server channel" );
+#endif
+		delay( ATTR_initialDelay );
+		er = cOpener_open();
+		syslog(LOG_INFO, "opened" );
+		while( cMain_main() == E_OK ){
+		}
+		delay( ATTR_reopenDelay );
+		er = cOpener_close();
+	}
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCSharedChannelMan.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCSharedChannelMan.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCSharedChannelMan.c	(revision 398)
@@ -0,0 +1,254 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port : cSemaphore  signature: sSemaphore context: task
+ *   ER             cSemaphore_signal( );
+ *   ER             cSemaphore_wait( );
+ *   ER             cSemaphore_waitPolling( );
+ *   ER             cSemaphore_waitTimeout( TMO timeout );
+ *   ER             cSemaphore_initialize( );
+ *   ER             cSemaphore_refer( T_RSEM* pk_semaphore_status );
+ * call port : cClientSideTDR  signature: sTDR context: task
+ *   ER             cClientSideTDR_open( const int8_t* arg, int16_t size, TMO tmo );
+ *   ER             cClientSideTDR_close( );
+ *   ER             cClientSideTDR_reset( );
+ *   ER             cClientSideTDR_sop( int_t no );
+ *   ER             cClientSideTDR_is_sop( int_t no );
+ *   ER             cClientSideTDR_eop( int_t no );
+ *   ER             cClientSideTDR_is_eop( int_t no );
+ *   ER             cClientSideTDR_set_tmo( TMO tmo );
+ *   ER             cClientSideTDR_put_int8( int8_t in );
+ *   ER             cClientSideTDR_put_int16( int16_t in );
+ *   ER             cClientSideTDR_put_int32( int32_t in );
+ *   ER             cClientSideTDR_put_int64( int64_t in );
+ *   ER             cClientSideTDR_put_int128( int128_t in );
+ *   ER             cClientSideTDR_get_int8( int8_t* out );
+ *   ER             cClientSideTDR_get_int16( int16_t* out );
+ *   ER             cClientSideTDR_get_int32( int32_t* out );
+ *   ER             cClientSideTDR_get_int64( int64_t* out );
+ *   ER             cClientSideTDR_get_int128( int128_t* out );
+ *   ER             cClientSideTDR_put_char( char_t in );
+ *   ER             cClientSideTDR_put_short( short in );
+ *   ER             cClientSideTDR_put_int( int_t in );
+ *   ER             cClientSideTDR_put_long( long_t in );
+ *   ER             cClientSideTDR_get_char( char_t* out );
+ *   ER             cClientSideTDR_get_short( short* out );
+ *   ER             cClientSideTDR_get_int( int_t* out );
+ *   ER             cClientSideTDR_get_long( long_t* out );
+ *   ER             cClientSideTDR_put_intptr( const void* ptr );
+ *   ER             cClientSideTDR_get_intptr( void** ptr );
+ *
+ * #[</PREAMBLE>]# */
+
+#include "tRPCSharedChannelMan_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eSemaphore
+ * entry port: eSemaphore
+ * signature:  sSemaphore
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eSemaphore_signal
+ * name:         eSemaphore_signal
+ * global_name:  tRPCSharedTaskMain_eSemaphore_signal
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSemaphore_signal(CELLIDX idx, int_t subscript)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	cClientSideTDR_putInt16( RPC_CHANNEL_MAN_EOP_MAGIC );
+	ercd = cSemaphore_signal();
+	// syslog( LOG_INFO, "tRPCSharedTaskMain: cSemaphore_signal" );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSemaphore_wait
+ * name:         eSemaphore_wait
+ * global_name:  tRPCSharedTaskMain_eSemaphore_wait
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSemaphore_wait(CELLIDX idx, int_t subscript)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	ercd = cSemaphore_wait();
+	if( ercd == E_OK ){
+		// syslog( LOG_INFO, "tRPCSharedTaskMain: cSemaphore_wait" );
+
+		cClientSideTDR_putInt16( RPC_CHANNEL_MAN_SOP_MAGIC );
+		cClientSideTDR_putInt16( subscript );
+	}
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSemaphore_waitPolling
+ * name:         eSemaphore_waitPolling
+ * global_name:  tRPCSharedTaskMain_eSemaphore_waitPolling
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSemaphore_waitPolling(CELLIDX idx, int_t subscript)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	ercd = cSemaphore_waitPolling();
+	if( ercd == E_OK ){
+		cClientSideTDR_putInt16( RPC_CHANNEL_MAN_SOP_MAGIC );
+		cClientSideTDR_putInt16( subscript );
+	}
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSemaphore_waitTimeout
+ * name:         eSemaphore_waitTimeout
+ * global_name:  tRPCSharedTaskMain_eSemaphore_waitTimeout
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSemaphore_waitTimeout(CELLIDX idx, int_t subscript, TMO timeout)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	ercd = cSemaphore_waitTimeout(timeout);
+	if( ercd == E_OK ){
+		// syslog( LOG_INFO, "tRPCSharedTaskMain: cSemaphore_waitTimeout" );
+
+		cClientSideTDR_putInt16( RPC_CHANNEL_MAN_SOP_MAGIC );
+		cClientSideTDR_putInt16( subscript );
+	}
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSemaphore_initialize
+ * name:         eSemaphore_initialize
+ * global_name:  tRPCSharedTaskMain_eSemaphore_initialize
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSemaphore_initialize(CELLIDX idx, int_t subscript)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eSemaphore_refer
+ * name:         eSemaphore_refer
+ * global_name:  tRPCSharedTaskMain_eSemaphore_refer
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eSemaphore_refer(CELLIDX idx, int_t subscript, T_RSEM* pk_semaphore_status)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCSharedTaskMain.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCSharedTaskMain.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCSharedTaskMain.c	(revision 398)
@@ -0,0 +1,160 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * channelNo        int16_t          VAR_channelNo   
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port : cUnmarshalAndCallFunction  signature: sTaskBody context: task
+ *   void           cUnmarshalAndCallFunction_main( subscript );
+ * call port : cServerSideTDR  signature: sTDR context: task
+ *   ER             cServerSideTDR_reset( );
+ *   ER             cServerSideTDR_sendSOP( bool_t b_client );
+ *   ER             cServerSideTDR_receiveSOP( bool_t b_client );
+ *   ER             cServerSideTDR_sendEOP( bool_t b_continue );
+ *   ER             cServerSideTDR_receiveEOP( bool_t b_continue );
+ *   ER             cServerSideTDR_putInt8( int8_t in );
+ *   ER             cServerSideTDR_putInt16( int16_t in );
+ *   ER             cServerSideTDR_putInt32( int32_t in );
+ *   ER             cServerSideTDR_putInt64( int64_t in );
+ *   ER             cServerSideTDR_putInt128( int128_t in );
+ *   ER             cServerSideTDR_getInt8( int8_t* out );
+ *   ER             cServerSideTDR_getInt16( int16_t* out );
+ *   ER             cServerSideTDR_getInt32( int32_t* out );
+ *   ER             cServerSideTDR_getInt64( int64_t* out );
+ *   ER             cServerSideTDR_getInt128( int128_t* out );
+ *   ER             cServerSideTDR_putFloat32( float32_t in );
+ *   ER             cServerSideTDR_putDouble64( double64_t in );
+ *   ER             cServerSideTDR_getFloat32( float32_t* out );
+ *   ER             cServerSideTDR_getDouble64( double64_t* out );
+ *   ER             cServerSideTDR_putChar( char_t in );
+ *   ER             cServerSideTDR_putShort( short in );
+ *   ER             cServerSideTDR_putInt( int_t in );
+ *   ER             cServerSideTDR_putLong( long_t in );
+ *   ER             cServerSideTDR_getChar( char_t* out );
+ *   ER             cServerSideTDR_getShort( short* out );
+ *   ER             cServerSideTDR_getInt( int_t* out );
+ *   ER             cServerSideTDR_getLong( long_t* out );
+ *   ER             cServerSideTDR_putIntptr( const intptr_t ptr );
+ *   ER             cServerSideTDR_getIntptr( intptr_t* ptr );
+ * require port : signature: sSysLog context: task
+ *   ER             write( uint_t prio, const SYSLOG* p_syslog );
+ *   ER_UINT        read( SYSLOG* p_syslog );
+ *   ER             mask( uint_t logmask, uint_t lowmask );
+ *   ER             refer( T_SYSLOG_RLOG* pk_rlog );
+ *
+ * #[</PREAMBLE>]# */
+
+#include "tRPCSharedTaskMain_tecsgen.h"
+#include "t_syslog.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eMain
+ * entry port: eMain
+ * signature:  sTaskBody
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eMain_main
+ * name:         eMain_main
+ * global_name:  tRPCSharedTaskMain_eMain_main
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eMain_main(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	syslog( LOG_INFO, "Shared RPC server task started." );
+	while(1){
+		int16_t magic;
+		ER      er;
+
+		er = cServerSideTDR_getInt16( &magic );
+		if( er != E_OK ){
+			syslog( LOG_INFO, "err: getInt16 for SOP_MAGIC(%X)", er );
+			continue;
+		}
+		if( magic != RPC_CHANNEL_MAN_SOP_MAGIC ){
+			syslog( LOG_INFO, "illegal SOP magic(%X): retrying", (uint16_t)magic );
+			continue;
+		}
+		er = cServerSideTDR_getInt16( &VAR_channelNo );
+		if( er != E_OK ){
+			syslog( LOG_INFO, "err: getInt16 for channelNo(%X)", er );
+			continue;
+		}
+		if( VAR_channelNo < 0 || VAR_channelNo >= N_CP_cUnmarshalAndCallFunction(p_cellcb) ){
+			syslog( LOG_INFO, "illegal channel number(%X): retrying", (uint16_t)VAR_channelNo );
+			continue;
+		}
+		syslog( LOG_INFO, "Shared Channel: servicing channel No. %d", VAR_channelNo );
+		
+		cUnmarshalAndCallFunction_main( VAR_channelNo );
+
+		er = cServerSideTDR_getInt16( &magic );
+		if( er != E_OK ){
+			syslog( LOG_INFO, "err: getInt16 for EOP_MAGIC(%X)", er );
+			continue;
+		}
+		if( magic != RPC_CHANNEL_MAN_EOP_MAGIC ){
+			syslog( LOG_INFO, "illegal EOP magic(%X): retrying", (uint16_t)magic );
+			continue;
+		}
+	}
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCSharedTaskMainWithOpener.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCSharedTaskMainWithOpener.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tRPCSharedTaskMainWithOpener.c	(revision 398)
@@ -0,0 +1,190 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/*
+ * このファイルは tecsgen によりテンプレートとして自動生成されました
+ * このファイルを編集して使用することが意図されていますが
+ * tecsgen の再実行により上書きされてしまうため、通常
+ *   gen/tRPCSharedTaskMainWithOpener_template.c => src/tRPCSharedTaskMainWithOpener.c
+ * のように名前, フォルダを変更してから修正します
+ */
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * initialDelay     RELTIM           ATTR_initialDelay
+ * reopenDelay      RELTIM           ATTR_reopenDelay
+ * channelNo        int16_t          VAR_channelNo   
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port : cUnmarshalAndCallFunction  signature: sTaskBody context: task
+ *   void           cUnmarshalAndCallFunction_main( subscript );
+ * call port : cServerSideTDR  signature: sTDR context: task
+ *   ER             cServerSideTDR_reset( );
+ *   ER             cServerSideTDR_sendSOP( bool_t b_client );
+ *   ER             cServerSideTDR_receiveSOP( bool_t b_client );
+ *   ER             cServerSideTDR_sendEOP( bool_t b_continue );
+ *   ER             cServerSideTDR_receiveEOP( bool_t b_continue );
+ *   ER             cServerSideTDR_putInt8( int8_t in );
+ *   ER             cServerSideTDR_putInt16( int16_t in );
+ *   ER             cServerSideTDR_putInt32( int32_t in );
+ *   ER             cServerSideTDR_putInt64( int64_t in );
+ *   ER             cServerSideTDR_putInt128( int128_t in );
+ *   ER             cServerSideTDR_getInt8( int8_t* out );
+ *   ER             cServerSideTDR_getInt16( int16_t* out );
+ *   ER             cServerSideTDR_getInt32( int32_t* out );
+ *   ER             cServerSideTDR_getInt64( int64_t* out );
+ *   ER             cServerSideTDR_getInt128( int128_t* out );
+ *   ER             cServerSideTDR_putFloat32( float32_t in );
+ *   ER             cServerSideTDR_putDouble64( double64_t in );
+ *   ER             cServerSideTDR_getFloat32( float32_t* out );
+ *   ER             cServerSideTDR_getDouble64( double64_t* out );
+ *   ER             cServerSideTDR_putChar( char_t in );
+ *   ER             cServerSideTDR_putShort( short in );
+ *   ER             cServerSideTDR_putInt( int_t in );
+ *   ER             cServerSideTDR_putLong( long_t in );
+ *   ER             cServerSideTDR_getChar( char_t* out );
+ *   ER             cServerSideTDR_getShort( short* out );
+ *   ER             cServerSideTDR_getInt( int_t* out );
+ *   ER             cServerSideTDR_getLong( long_t* out );
+ *   ER             cServerSideTDR_putIntptr( const intptr_t ptr );
+ *   ER             cServerSideTDR_getIntptr( intptr_t* ptr );
+ * call port : cOpener  signature: sServerChannelOpener context: task
+ *   ER             cOpener_open( );
+ *   ER             cOpener_close( );
+ * require port : signature: sSysLog context: task
+ *   ER             write( uint_t prio, const SYSLOG* p_syslog );
+ *   ER_UINT        read( SYSLOG* p_syslog );
+ *   ER             mask( uint_t logmask, uint_t lowmask );
+ *   ER             refer( T_SYSLOG_RLOG* pk_rlog );
+ * require port : signature: sKernel context: task
+ *   ER             delay( RELTIM delay_time );
+ *   ER             exitTask( );
+ *   ER             getTime( SYSTIM* p_system_time );
+ *   ER             getMicroTime( SYSUTM* p_system_micro_time );
+ *   ER             exitKernel( );
+ *
+ * #[</PREAMBLE>]# */
+
+/* プロトタイプ宣言や変数の定義をここに書きます */
+#include "tRPCSharedTaskMainWithOpener_tecsgen.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eMain
+ * entry port: eMain
+ * signature:  sTaskBody
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eMain_main
+ * name:         eMain_main
+ * global_name:  tRPCSharedTaskMainWithOpener_eMain_main
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+void
+eMain_main(CELLIDX idx)
+{
+	CELLCB	*p_cellcb;
+	ER		er;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		/* エラー処理コードをここに記述します */
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	delay( ATTR_initialDelay );
+	/* ここに処理本体を記述します #_TEFB_# */
+	while(1){
+#ifdef RPC_DEBUG
+		syslog(LOG_INFO, "begin RPC unmarshaler task" );
+		syslog(LOG_INFO, "Opening RPC server channel" );
+#endif
+
+		er = cOpener_open();
+		syslog(LOG_INFO, "opened" );
+		while(1){
+			int16_t magic;
+
+			er = cServerSideTDR_getInt16( &magic );
+			if( er != E_OK ){
+				syslog( LOG_INFO, "err: getInt16 for SOP_MAGIC(%X)", er );
+				continue;
+			}
+			if( magic != RPC_CHANNEL_MAN_SOP_MAGIC ){
+				syslog( LOG_INFO, "illegal SOP magic(%X): retrying", (uint16_t)magic );
+				continue;
+			}
+			er = cServerSideTDR_getInt16( &VAR_channelNo );
+			if( er != E_OK ){
+				syslog( LOG_INFO, "err: getInt16 for channelNo(%X)", er );
+				continue;
+			}
+			if( VAR_channelNo < 0 || VAR_channelNo >= N_CP_cUnmarshalAndCallFunction(p_cellcb) ){
+				syslog( LOG_INFO, "illegal channel number(%X): retrying", (uint16_t)VAR_channelNo );
+				continue;
+			}
+			syslog( LOG_INFO, "Shared Channel: servicing channel No. %d", VAR_channelNo );
+		
+			cUnmarshalAndCallFunction_main( VAR_channelNo );
+
+			er = cServerSideTDR_getInt16( &magic );
+			if( er != E_OK ){
+				syslog( LOG_INFO, "err: getInt16 for EOP_MAGIC(%X)", er );
+				continue;
+			}
+			if( magic != RPC_CHANNEL_MAN_EOP_MAGIC ){
+				syslog( LOG_INFO, "illegal EOP magic(%X): retrying", (uint16_t)magic );
+				continue;
+			}
+		}
+		er = cOpener_close();
+		delay( ATTR_reopenDelay );
+	}
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tSocketChannel.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tSocketChannel.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tSocketChannel.cdl	(revision 398)
@@ -0,0 +1,69 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+const	uint16_t	SOCKET_DEFAULT_PORT_NO  = 8931;
+
+signature sSocketClientOpener {
+	ER		open( [in,string]const char_t *serverAddr, [in]uint16_t portNo, [in]TMO tmo );
+	ER		simpleOpen( [in]TMO tmo );      // attr の設定に従って開く
+	ER		close( [in]TMO tmo );
+};
+
+celltype tSocketClient {
+	entry	sChannel			eC0;
+	entry	sSocketClientOpener	eOpener;
+	attr {
+		// simpleOpen で用いられるアドレスおよびポート番号
+		int16_t	portNo = SOCKET_DEFAULT_PORT_NO;
+		char_t  *serverAddr = "127.0.0.1";       // Loop back address
+	};
+	var {
+		int_t	sd;
+	};
+};
+
+celltype tSocketServer {
+	entry	sChannel				eC1;
+	entry	sServerChannelOpener	eOpener;
+	attr {
+		int16_t	portNo = SOCKET_DEFAULT_PORT_NO;
+	};
+	var {
+		int_t    sd;
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tSocketClient.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tSocketClient.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tSocketClient.c	(revision 398)
@@ -0,0 +1,350 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * Don't edit the comments between #[<...>]# and #[</...>]#
+ * These comment are used by tecsmerege when merging.
+ *
+ * attr access macro #_CAAM_#
+ * portNo           int16_t          ATTR_portNo    
+ * serverAddr       char_t*          ATTR_serverAddr
+ * sd               int_t            VAR_sd          
+ *
+ * #[</PREAMBLE>]# */
+
+#include "tSocketClient_tecsgen.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include "errno2ER.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* 正常終了 */
+#define	E_ID	(-18)	/* 不正ID番号 */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eC0
+ * entry port: eC0
+ * signature:  sChannel
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eC0_send
+ * name:         eC0_send
+ * global_name:  tSocketClient_eC0_send
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC0_send(CELLIDX idx, const int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	ssize_t sz;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+	// mikan BUG  buf の位置を更新していない
+	while(size>0){
+		if((sz=write( VAR_sd, buf, (ssize_t)size )) < 0 ){
+#ifdef RPC_DEBUG
+			perror( "eC0_send" );
+			syslog( LOG_INFO, "eC0_send: sd %d, writing %d bytes, ercd=%d", VAR_sd, size, ercd );
+#endif
+			ercd = errno2ER( errno );
+			break;
+		}
+		else{
+			size -= sz;
+		}
+	}
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC0_flush
+ * name:         eC0_flush
+ * global_name:  tSocketClient_eC0_flush
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC0_flush(CELLIDX idx, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+	/* write はバッファリングなしなので flush しない */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC0_receive
+ * name:         eC0_receive
+ * global_name:  tSocketClient_eC0_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER_UINT
+eC0_receive(CELLIDX idx, int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	ssize_t  sz;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+	sz = read( VAR_sd, buf, (ssize_t)size );
+	ercd = errno2ER( errno );
+#ifdef DEBUG
+	{
+		int i;
+		for( i = 0; i < sz; i++ ){
+			printf( "%02X ", (unsigned char)buf[i] );
+			if( i % 8 == 7 )
+				putchar( '\n' );
+		}
+		putchar( '\n' );
+	}
+#endif
+	/* mikan 一発で全て読めると仮定 */
+	if( sz >= 0 )
+		ercd = sz;
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC0_end_receive
+ * name:         eC0_end_receive
+ * global_name:  tSocketClient_eC0_end_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC0_end_receive(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC0_reset
+ * name:         eC0_reset
+ * global_name:  tSocketClient_eC0_reset
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC0_reset(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_PORT>]# eOpener
+ * entry port: eOpener
+ * signature:  sSocketClientOpener
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eOpener_open
+ * name:         eOpener_open
+ * global_name:  tSocketClient_eOpener_open
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eOpener_open(CELLIDX idx, const char_t* serverAddr, uint16_t portNo, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	int		soc;
+	struct sockaddr_in addr={AF_INET};
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	soc=socket(AF_INET, SOCK_STREAM, 0);
+	if(soc<0){
+		ercd = errno2ER( errno );
+		syslog( LOG_INFO, "SocketClient: socket failed");
+		return ercd;
+	}
+
+#if 0
+/* ノンブロックに変更 */
+	int flag=fcntl(soc, F_GETFL, 0);
+	if(flag<0) perror("fcntl(GET) error");
+	if(fcntl(soc, F_SETFL, flag|O_NONBLOCK)<0) perror("fcntl(NONBLOCK) error");
+#endif /* 0 */
+
+	puts( "connecting" );
+	inet_aton( serverAddr, &addr.sin_addr );
+	addr.sin_port=htons(portNo);
+	if(connect(soc, (struct sockaddr*)&addr, sizeof(addr))<0){
+		ercd = errno2ER( errno );
+		close( soc );
+		printf( "connect fail errno=%d, ercd=%d\n", errno, ercd );
+		syslog( LOG_INFO, "SocketClient: connect" );
+		return ercd;
+	}
+	VAR_sd = soc;
+
+#if 0
+	if(errno!=EINPROGRESS)
+		perror("connect error");
+	//EINPROGRESS:コネクション要求は始まったが、まだ完了していない
+
+	fd_set rmask,wmask;FD_ZERO(&rmask);FD_SET(soc,&rmask);wmask=rmask;
+	struct timeval tv={ タイムアウト時間[秒],[μ秒] };
+	int rc=select(soc+1, &rmask, &wmask, NULL, &tv);
+	if(rc<0) perror("connect-select error");
+	if(rc==0){ タイムアウト処理 }
+	if(rc==2){ //読み書きが同時に出来る場合
+#if Solaris
+		int val;
+		socklen_t len=sizeof(val);
+		if(getsockopt(soc,SOL_SOCKET,SO_ERROR, &val,&len)>=0) {
+#elif Linux
+			struct sockaddr_in name;
+			socklen_t len=sizeof(name);
+			if(getpeername(soc,(struct sockaddr*)&name,&len)>=0) {
+#endif
+				// 既にデータが来ている
+			}else{
+				// コネクト失敗
+			}
+		}
+	}
+//フラグを元に戻す
+	if(fcntl(soc, F_SETFL, flag)<0) perror("fcntl(END) error");
+#endif /* 0 */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eOpener_simpleOpen
+ * name:         eOpener_simpleOpen
+ * global_name:  tSocketClient_eOpener_simpleOpen
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eOpener_simpleOpen(CELLIDX idx, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+
+	/* Put statements here #_TEFB_# */
+	ercd = eOpener_open(idx, ATTR_serverAddr, ATTR_portNo, tmo);
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eOpener_close
+ * name:         eOpener_close
+ * global_name:  tSocketClient_eOpener_close
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eOpener_close(CELLIDX idx, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	close( VAR_sd );       /* mikan エラー処理 */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   Put non-entry functions below.
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tSocketServer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tSocketServer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tSocketServer.c	(revision 398)
@@ -0,0 +1,303 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * portNo           int16_t          ATTR_portNo    
+ * sd               int_t            VAR_sd          
+ *
+ * #[</PREAMBLE>]# */
+
+#include "tSocketServer_tecsgen.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include "errno2ER.h"
+
+#ifndef E_OK
+#define	E_OK	0		/* 正常終了 */
+#define	E_ID	(-18)	/* 不正ID番号 */
+#endif
+
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eC1
+ * entry port: eC1
+ * signature:  sChannel
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eC1_send
+ * name:         eC1_send
+ * global_name:  tSocketServer_eC1_send
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC1_send(CELLIDX idx, const int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	int     sz;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+#ifdef DEBUG
+	syslog( LOG_INFO, "tSocketServer: send" );
+	{
+		int i;
+		for( i = 0; i < size; i++ ){
+			printf( "%02X ", (unsigned char)buf[i] );
+			if( i % 8 == 7 )
+				putchar( '\n' );
+		}
+		putchar( '\n' );
+	}
+#endif
+	while(size>0){
+		if((sz=write( VAR_sd, buf, (size_t)size )) < 0 ){
+			ercd = errno2ER( errno );
+			break;
+		}
+		else{
+			size -= sz;
+		}
+	}
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC1_flush
+ * name:         eC1_flush
+ * global_name:  tSocketServer_eC1_flush
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC1_flush(CELLIDX idx, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC1_receive
+ * name:         eC1_receive
+ * global_name:  tSocketServer_eC1_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER_UINT
+eC1_receive(CELLIDX idx, int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+	ER_UINT sz;
+	CELLCB	*p_cellcb;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+	if( (sz=read( VAR_sd, buf, (size_t)size )) < 0 )
+		ercd = errno2ER( errno );
+	else
+		ercd = sz;
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC1_end_receive
+ * name:         eC1_end_receive
+ * global_name:  tSocketServer_eC1_end_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC1_end_receive(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC1_reset
+ * name:         eC1_reset
+ * global_name:  tSocketServer_eC1_reset
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC1_reset(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+	syslog( LOG_INFO, "tSocketServer: reset" );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_PORT>]# eOpener
+ * entry port: eOpener
+ * signature:  sServerChannelOpener
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eOpener_open
+ * name:         eOpener_open
+ * global_name:  tSocketServer_eOpener_open
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eOpener_open(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	int		ssoc, soc;
+	struct sockaddr_in addr={ AF_INET };
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	syslog( LOG_INFO, "tSocketServer: open" );
+
+	ssoc=socket(AF_INET,SOCK_STREAM,0);
+	if(ssoc<0){
+		ercd = errno2ER( errno );
+		syslog( LOG_INFO, "tSocketServer: socket failed" );
+		return ercd;
+	}
+
+	addr.sin_port = htons(ATTR_portNo);
+	addr.sin_addr.s_addr = INADDR_ANY;
+	if(bind(ssoc,(struct sockaddr*)&addr,sizeof(addr))<0){
+		ercd = errno2ER( errno );
+		syslog( LOG_INFO, "tSocketServer: bind failed" );
+		return ercd;
+	}
+
+	if(listen(ssoc, 1 )<0){
+		ercd = errno2ER( errno );
+		syslog( LOG_INFO, "tSocketServer: listen failed" );
+		return ercd;
+	}
+
+    soc=accept(ssoc, NULL, NULL);
+    if(soc<0){
+		ercd = errno2ER( errno );
+		syslog( LOG_INFO, "tSocketServer: accept failed" );
+		return ercd;
+	}
+	syslog( LOG_INFO, "tSocketServer: accepted" );
+
+	close( ssoc );
+	VAR_sd = soc;
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eOpener_close
+ * name:         eOpener_close
+ * global_name:  tSocketServer_eOpener_close
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eOpener_close(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	syslog( LOG_INFO, "tSocketServer: close" );
+	if( close( VAR_sd ) < 0 )
+		ercd = errno2ER( errno );
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTDR_inline.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTDR_inline.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTDR_inline.h	(revision 398)
@@ -0,0 +1,1278 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * tmo              TMO              VAR_tmo         
+ *
+ * #[</PREAMBLE>]# */
+
+/*
+ * marhaler, unmarshaler が使用する STRLEN 関数を定義する
+ *  marshaler, unmarshaler は必ず TDR は に結合されるため
+ */
+#include	"rpc_string.h"
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eTDR
+ * entry port: eTDR
+ * signature:  sTDR
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eTDR_reset
+ * name:         eTDR_reset
+ * global_name:  tTDR_eTDR_reset
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_reset(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	syslog( LOG_INFO, "TDR: resetting channel" );
+	ercd = cChannel_reset();
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_sendSOP
+ * name:         eTDR_sendSOP
+ * global_name:  tTDR_eTDR_sendSOP
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_sendSOP(CELLIDX idx, bool_t b_client )
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	const uint16_t *p_sopMagic;
+	const uint16_t SOP_MAGIC1 = TDR_SOP_MAGIC1;
+	const uint16_t SOP_MAGIC2 = TDR_SOP_MAGIC2;
+	uint8_t		   val;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+#ifdef RPC_DEBUG
+	syslog(LOG_INFO, "eTDR_sendSOP(b_client=%d)", b_client);
+#endif
+    if( b_client )
+		p_sopMagic = &SOP_MAGIC1;
+	else
+		p_sopMagic = &SOP_MAGIC2;
+
+	/*
+	 * SOP パケットの送信
+	 * パケットシーケンスが多少崩れても回復できるように、バイト単位で送る
+	 * 下位アドレス、上位アドレスの順に送る
+	 */
+
+	val = (uint8_t)(*((uint8_t *)p_sopMagic));
+	ercd = eTDR_putUInt8( idx, val );
+	// syslog( LOG_INFO, "sendSOP:1 %02X", val );
+	if( ercd != E_OK )
+		return	ercd;
+	val = (uint8_t)*(((uint8_t *)p_sopMagic)+1);
+	ercd = eTDR_putUInt8( idx, val );
+	// syslog( LOG_INFO, "sendSOP:2 %02X", val );
+
+	return	ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_receiveSOP
+ * name:         eTDR_receiveSOP
+ * global_name:  tTDR_eTDR_receiveSOP
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_receiveSOP(CELLIDX idx, bool_t b_client)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	const uint16_t SOP_MAGIC1 = TDR_SOP_MAGIC1;
+	const uint16_t SOP_MAGIC2 = TDR_SOP_MAGIC2;
+	const uint16_t *p_sopMagic;
+	uint16_t magic;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+#ifdef RPC_DEBUG
+	syslog(LOG_INFO, "eTDR_receiveSOP(b_client=%d)", b_client);
+#endif
+
+  if( b_client )
+		p_sopMagic = &SOP_MAGIC2;
+	else
+		p_sopMagic = &SOP_MAGIC1;
+
+	if( (ercd=eTDR_getUInt8( idx, (uint8_t *)&magic )) != E_OK )
+		;
+	else if( (uint8_t)magic != (uint8_t)(*((uint8_t *)p_sopMagic)) ){
+		// syslog( LOG_INFO, "receiveSOP:1 %02X expecting=%02X", (uint8_t)magic, (int8_t)(*((int8_t *)p_sopMagic)) );
+		ercd = E_MAGIC;
+	}
+	else if((ercd=eTDR_getUInt8( idx, ((uint8_t *)&magic)+1 )) != E_OK )
+		;
+	else if( magic != *p_sopMagic){
+		// syslog( LOG_INFO, "receiveSOP:2 %04X expecting=%04X", magic, *p_sopMagic );
+		ercd = E_MAGIC;
+	}
+
+	if( ercd != E_OK )
+		syslog( LOG_INFO, "receiveSOP: ERCD=%d", ercd );
+
+	return ercd;
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_sendEOP
+ * name:         eTDR_sendEOP
+ * global_name:  tTDR_eTDR_sendEOP
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_sendEOP(CELLIDX idx, bool_t b_continue )
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	uint16_t magic;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+#ifdef RPC_DEBUG
+	syslog(LOG_INFO, "eTDR_sendEOP(b_continue=%d)", b_continue);
+#endif
+
+	if( b_continue )
+		magic = TDR_EOP_MAGIC1;
+	else
+		magic = TDR_EOP_MAGIC2;
+
+	/* EOP magic の送信 */
+	if( (ercd = eTDR_putInt16( idx, (int16_t)magic )) != E_OK )
+		return ercd;
+
+	return cChannel_flush(VAR_tmo);
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_receiveEOP
+ * name:         eTDR_receiveEOP
+ * global_name:  tTDR_eTDR_receiveEOP
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_receiveEOP(CELLIDX idx, bool_t b_continue)
+{
+	ER		ercd = E_OK, er2;
+	CELLCB	*p_cellcb;
+	uint16_t magic;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+#ifdef RPC_DEBUG
+	syslog(LOG_INFO, "eTDR_receiveEOP(b_continue=%d)",b_continue);
+#endif
+/* mikan cChannel EOF get_* */
+/* mikan magic EOF */
+
+	if( (ercd=eTDR_getInt16( idx, (int16_t *)&magic )) == E_OK ){
+		if( (b_continue && magic == TDR_EOP_MAGIC1) || (!b_continue && magic == TDR_EOP_MAGIC2) ){
+		} else {
+			ercd = E_MAGIC;
+		}
+	}
+	er2 = cChannel_end_receive();
+	return ercd != E_OK ? ercd : er2;
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt8
+ * name:         eTDR_putInt8
+ * global_name:  tTDR_eTDR_putInt8
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt8(CELLIDX idx, int8_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt16
+ * name:         eTDR_putInt16
+ * global_name:  tTDR_eTDR_putInt16
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt16(CELLIDX idx, int16_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt32
+ * name:         eTDR_putInt32
+ * global_name:  tTDR_eTDR_putInt32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt32(CELLIDX idx, int32_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt64
+ * name:         eTDR_putInt64
+ * global_name:  tTDR_eTDR_putInt64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt64(CELLIDX idx, int64_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt128
+ * name:         eTDR_putInt128
+ * global_name:  tTDR_eTDR_putInt128
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt128(CELLIDX idx, int128_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt8
+ * name:         eTDR_getInt8
+ * global_name:  tTDR_eTDR_getInt8
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt8(CELLIDX idx, int8_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	 *p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt16
+ * name:         eTDR_getInt16
+ * global_name:  tTDR_eTDR_getInt16
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt16(CELLIDX idx, int16_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt32
+ * name:         eTDR_getInt32
+ * global_name:  tTDR_eTDR_getInt32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt32(CELLIDX idx, int32_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt64
+ * name:         eTDR_getInt64
+ * global_name:  tTDR_eTDR_getInt64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt64(CELLIDX idx, int64_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt128
+ * name:         eTDR_getInt128
+ * global_name:  tTDR_eTDR_getInt128
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt128(CELLIDX idx, int128_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt8
+ * name:         eTDR_putUInt8
+ * global_name:  tTDR_eTDR_putUInt8
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt8(CELLIDX idx, uint8_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt16
+ * name:         eTDR_putUInt16
+ * global_name:  tTDR_eTDR_putUInt16
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt16(CELLIDX idx, uint16_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt32
+ * name:         eTDR_putUInt32
+ * global_name:  tTDR_eTDR_putUInt32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt32(CELLIDX idx, uint32_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt64
+ * name:         eTDR_putUInt64
+ * global_name:  tTDR_eTDR_putUInt64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt64(CELLIDX idx, uint64_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt128
+ * name:         eTDR_putUInt128
+ * global_name:  tTDR_eTDR_putUInt128
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt128(CELLIDX idx, uint128_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt8
+ * name:         eTDR_getUInt8
+ * global_name:  tTDR_eTDR_getUInt8
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt8(CELLIDX idx, uint8_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt16
+ * name:         eTDR_getUInt16
+ * global_name:  tTDR_eTDR_getUInt16
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt16(CELLIDX idx, uint16_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt32
+ * name:         eTDR_getUInt32
+ * global_name:  tTDR_eTDR_getUInt32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt32(CELLIDX idx, uint32_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt64
+ * name:         eTDR_getUInt64
+ * global_name:  tTDR_eTDR_getUInt64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt64(CELLIDX idx, uint64_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt128
+ * name:         eTDR_getUInt128
+ * global_name:  tTDR_eTDR_getUInt128
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt128(CELLIDX idx, uint128_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putBool
+ * name:         eTDR_putBool
+ * global_name:  tNBOTDR_eTDR_putBool
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putBool(CELLIDX idx, bool_t in)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	eTDR_putUInt8(idx, (uint8_t)(in != 0) );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getBool
+ * name:         eTDR_getBool
+ * global_name:  tNBOTDR_eTDR_getBool
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getBool(CELLIDX idx, bool_t* out)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	uint8_t	val = 0;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	ercd = eTDR_getUInt8(idx, &val );
+	if( ercd != E_OK )
+		return ercd;
+	*out = (val != 0);
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putFloat32
+ * name:         eTDR_putFloat32
+ * global_name:  tTDR_eTDR_putFloat32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putFloat32(CELLIDX idx, float32_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putDouble64
+ * name:         eTDR_putDouble64
+ * global_name:  tTDR_eTDR_putDouble64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putDouble64(CELLIDX idx, double64_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getFloat32
+ * name:         eTDR_getFloat32
+ * global_name:  tTDR_eTDR_getFloat32
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getFloat32(CELLIDX idx, float32_t* out)
+{
+	ER_UINT		er_sz = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getDouble64
+ * name:         eTDR_getDouble64
+ * global_name:  tTDR_eTDR_getDouble64
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getDouble64(CELLIDX idx, double64_t* out)
+{
+	ER_UINT		er_sz = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putChar
+ * name:         eTDR_putChar
+ * global_name:  tTDR_eTDR_putChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putChar(CELLIDX idx, char_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getChar
+ * name:         eTDR_getChar
+ * global_name:  tTDR_eTDR_getChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getChar(CELLIDX idx, char_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putSChar
+ * name:         eTDR_putSChar
+ * global_name:  tTDR_eTDR_putSChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putSChar(CELLIDX idx, signed char in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putShort
+ * name:         eTDR_putShort
+ * global_name:  tTDR_eTDR_putShort
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putShort(CELLIDX idx, short_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putInt
+ * name:         eTDR_putInt
+ * global_name:  tTDR_eTDR_putInt
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putInt(CELLIDX idx, int_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putLong
+ * name:         eTDR_putLong
+ * global_name:  tTDR_eTDR_putLong
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putLong(CELLIDX idx, long_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getSChar
+ * name:         eTDR_getSChar
+ * global_name:  tTDR_eTDR_getSChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getSChar(CELLIDX idx, signed char* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getShort
+ * name:         eTDR_getShort
+ * global_name:  tTDR_eTDR_getShort
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getShort(CELLIDX idx, short* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getInt
+ * name:         eTDR_getInt
+ * global_name:  tTDR_eTDR_getInt
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getInt(CELLIDX idx, int_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getLong
+ * name:         eTDR_getLong
+ * global_name:  tTDR_eTDR_getLong
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getLong(CELLIDX idx, long_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUChar
+ * name:         eTDR_putUChar
+ * global_name:  tTDR_eTDR_putUChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUChar(CELLIDX idx, unsigned char in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUShort
+ * name:         eTDR_putUShort
+ * global_name:  tTDR_eTDR_putUShort
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUShort(CELLIDX idx, ushort_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putUInt
+ * name:         eTDR_putUInt
+ * global_name:  tTDR_eTDR_putUInt
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putUInt(CELLIDX idx, uint_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putULong
+ * name:         eTDR_putULong
+ * global_name:  tTDR_eTDR_putULong
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putULong(CELLIDX idx, ulong_t in)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&in, (int16_t)sizeof( in ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUChar
+ * name:         eTDR_getUChar
+ * global_name:  tTDR_eTDR_getUChar
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUChar(CELLIDX idx, unsigned char* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUShort
+ * name:         eTDR_getUShort
+ * global_name:  tTDR_eTDR_getUShort
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUShort(CELLIDX idx, unsigned short* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getUInt
+ * name:         eTDR_getUInt
+ * global_name:  tTDR_eTDR_getUInt
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getUInt(CELLIDX idx, uint_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getULong
+ * name:         eTDR_getULong
+ * global_name:  tTDR_eTDR_getULong
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getULong(CELLIDX idx, ulong_t* out)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	} /* end if VALID_IDX(idx) */
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)out, (int16_t)sizeof( *out ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *out ) ? E_OK : E_BOVR );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_putIntptr
+ * name:         eTDR_putIntptr
+ * global_name:  tTDR_eTDR_putIntptr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_putIntptr(CELLIDX idx, const intptr_t ptr)
+{
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	return cChannel_send( (int8_t *)&ptr, (int16_t)sizeof( ptr ), VAR_tmo );
+}
+
+/* #[<ENTRY_FUNC>]# eTDR_getIntptr
+ * name:         eTDR_getIntptr
+ * global_name:  tTDR_eTDR_getIntptr
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+Inline ER
+eTDR_getIntptr(CELLIDX idx, intptr_t* ptr)
+{
+	ER_UINT	 er_sz;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+  (void)p_cellcb;   // to avoid unused warning
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	er_sz = cChannel_receive( (int8_t *)ptr, (int16_t)sizeof( *ptr ), VAR_tmo );
+	return  er_sz < 0 ? er_sz : ( er_sz == sizeof( *ptr ) ? E_OK : E_BOVR );
+}
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTINETChannel.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTINETChannel.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTINETChannel.cdl	(revision 398)
@@ -0,0 +1,110 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+import_C( "netinet/in.h" );
+
+const	uint16_t	TINETIPV4_DEFAULT_PORT_NO  = 8931;
+
+signature sTINETClientOpenerIPV4 {
+	ER		open( [in]const T_IPV4EP *clientAddr, [in]TMO tmo );
+	ER		close( [in]TMO tmo );
+};
+
+signature sIPV4AcceptCheck {
+	bool_t	check( [in]const T_IPV4EP *clientAddr );
+};
+
+celltype tTINETClient {
+	entry	sChannel				eC0;
+	entry	sTINETClientOpenerIPV4	eOpener;
+	attr {
+		ID				cep_id = C_EXP( "$id$_CEPID" );
+		[omit]
+			uint16_t	recv_buf_size = C_EXP( "TCP_MSS" );
+		[omit]
+			uint16_t	send_buf_size = C_EXP( "TCP_MSS" );
+	};
+	FACTORY {
+		write( "$ct$_factory.h", "#include \"netinet/tcp.h\"\n" );
+		write( "$ct$_tecsgen.h", "#include \"tinet_cfg.h\"\n" );
+		write( "tinet_tecsgen.cfg", "#include \"$ct$_factory.h\"\n" );
+	};
+	factory {
+		write( "$ct$_factory.h", "int8_t $id$_recv_buf[%s];\n", recv_buf_size );
+		write( "$ct$_factory.h", "int8_t $id$_send_buf[%s];\n", send_buf_size );
+		write( "tinet_tecsgen.cfg", "TCP_CRE_CEP ($id$_CEPID, {\n"
+								"	0,\n"
+								"	$id$_send_buf,\n"
+								"	%s,\n"
+								"	$id$_recv_buf,\n"
+								"	%s,\n"
+								"	NULL \n"
+								"	} );\n",
+			   send_buf_size, recv_buf_size );
+	};
+};
+
+celltype tTINETServer {
+
+	entry	sChannel				eC1;
+	entry	sServerChannelOpener	eOpener;
+	[optional]
+		call  sIPV4AcceptCheck  cCheck;
+	attr {
+		ID				cep_id = C_EXP( "$id$_CEPID" );
+		ID				rep_id = C_EXP( "$id$_REPID" );
+		[omit]
+			int16_t		portNo  = TINETIPV4_DEFAULT_PORT_NO;
+		[omit]
+			uint16_t	recv_buf_size = C_EXP( "TCP_MSS" );
+		[omit]
+			uint16_t	send_buf_size = C_EXP( "TCP_MSS" );
+	};
+	FACTORY {
+		write( "$ct$_factory.h", "#include \"netinet/tcp.h\"\n" );
+		write( "$ct$_tecsgen.h", "#include \"tinet_cfg.h\"\n" );
+		write( "tinet_tecsgen.cfg", "#include \"$ct$_factory.h\"\n" );
+	};
+	factory {
+		write( "$ct$_factory.h", "int8_t $id$_recv_buf[%s];\n", recv_buf_size );
+		write( "$ct$_factory.h", "int8_t $id$_send_buf[%s];\n", send_buf_size );
+		write( "tinet_tecsgen.cfg", "TCP_CRE_REP ($id$_REPID,	{ 0, { IPV4_ADDRANY, %s } } );\n", portNo );
+		write( "tinet_tecsgen.cfg", "TCP_CRE_CEP ($id$_CEPID, {0, $id$_send_buf, %s, $id$_recv_buf, %s, NULL } );\n",
+				   send_buf_size, recv_buf_size );
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTINETClient.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTINETClient.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTINETClient.c	(revision 398)
@@ -0,0 +1,264 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * cep_id           ID               ATTR_cep_id     
+ *
+ * #[</PREAMBLE>]# */
+
+#include "tTINETClient_tecsgen.h"
+#include "tTINETClient_factory.h"
+
+#include <string.h>
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+#include <netinet/tcp.h>
+
+#ifndef E_OK
+#define	E_OK	0		/* 正常終了 */
+#define	E_ID	(-18)	/* 不正ID番号 */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eC0
+ * entry port: eC0
+ * signature:  sChannel
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eC0_send
+ * name:         eC0_send
+ * global_name:  tTINETClient_eC0_send
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC0_send(CELLIDX idx, const int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	int     sz;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+#ifdef DEBUG
+	syslog( LOG_INFO, "tTINETServer: send" );
+	{
+		int i;
+		for( i = 0; i < size; i++ ){
+			printf( "%02X ", (unsigned char)buf[i] );
+			if( i % 8 == 7 )
+				putchar( '\n' );
+		}
+		putchar( '\n' );
+	}
+#endif
+	while(size>0){
+		if((sz=tcp_snd_dat( ATTR_cep_id, (intptr_t *)buf, (size_t)size, tmo )) < 0 ){
+			ercd = sz;
+			break;
+		}
+		else{
+			size -= sz;
+		}
+	}
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC0_flush
+ * name:         eC0_flush
+ * global_name:  tTINETClient_eC0_flush
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC0_flush(CELLIDX idx, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+	/* write はバッファリングなしなので flush しない */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC0_receive
+ * name:         eC0_receive
+ * global_name:  tTINETClient_eC0_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER_UINT
+eC0_receive(CELLIDX idx, int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+	ercd = tcp_rcv_dat( ATTR_cep_id, buf, (size_t)size, tmo );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC0_end_receive
+ * name:         eC0_end_receive
+ * global_name:  tTINETClient_eC0_end_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC0_end_receive(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC0_reset
+ * name:         eC0_reset
+ * global_name:  tTINETClient_eC0_reset
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC0_reset(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_PORT>]# eOpener
+ * entry port: eOpener
+ * signature:  sTINETClientOpenerIPV4
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eOpener_open
+ * name:         eOpener_open
+ * global_name:  tTINETClient_eOpener_open
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eOpener_open(CELLIDX idx, const T_IPV4EP* clientAddr, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	puts("opening");
+	ercd=tcp_con_cep(ATTR_cep_id, NADR, clientAddr, tmo);
+	if(ercd<0){
+		puts("failed");
+		syslog( LOG_INFO, "TINETClient: connect failed");
+	}
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eOpener_close
+ * name:         eOpener_close
+ * global_name:  tTINETClient_eOpener_close
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eOpener_close(CELLIDX idx, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	ercd = tcp_cls_cep( ATTR_cep_id, 0 );       /* mikan エラー処理 */
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTINETServer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTINETServer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tTINETServer.c	(revision 398)
@@ -0,0 +1,275 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+ *
+ * 属性アクセスマクロ #_CAAM_#
+ * cep_id           ID               ATTR_cep_id     
+ * rep_id           ID               ATTR_rep_id     
+ *
+ * 呼び口関数 #_TCPF_#
+ * call port : cCheck  signature: sIPV4AcceptCheck context: task
+ *   bool_t         cCheck_check( const T_IPV4EP* clientAddr );
+ *
+ * #[</PREAMBLE>]# */
+
+#include "tTINETServer_tecsgen.h"
+#include "tTINETServer_factory.h"
+
+#include <string.h>
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+#include <netinet/tcp.h>
+
+
+#ifndef E_OK
+#define	E_OK	0		/* 正常終了 */
+#define	E_ID	(-18)	/* 不正ID番号 */
+#endif
+
+/* 受け口関数 #_TEPF_# */
+/* #[<ENTRY_PORT>]# eC1
+ * entry port: eC1
+ * signature:  sChannel
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eC1_send
+ * name:         eC1_send
+ * global_name:  tTINETServer_eC1_send
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC1_send(CELLIDX idx, const int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	int     sz;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+#ifdef DEBUG
+	syslog( LOG_INFO, "tTINETServer: send" );
+	{
+		int i;
+		for( i = 0; i < size; i++ ){
+			printf( "%02X ", (unsigned char)buf[i] );
+			if( i % 8 == 7 )
+				putchar( '\n' );
+		}
+		putchar( '\n' );
+	}
+#endif
+	while(size>0){
+		if((sz=tcp_snd_dat( ATTR_cep_id, buf, (size_t)size, tmo )) < 0 ){
+			ercd = sz;
+			break;
+		}
+		else{
+			size -= sz;
+		}
+	}
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC1_flush
+ * name:         eC1_flush
+ * global_name:  tTINETServer_eC1_flush
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC1_flush(CELLIDX idx, TMO tmo)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC1_receive
+ * name:         eC1_receive
+ * global_name:  tTINETServer_eC1_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER_UINT
+eC1_receive(CELLIDX idx, int8_t* buf, int16_t size, TMO tmo)
+{
+	ER		ercd = E_OK;
+	ER_UINT sz;
+	CELLCB	*p_cellcb;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+	ercd = tcp_rcv_dat( ATTR_cep_id, buf, (size_t)size, tmo );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC1_end_receive
+ * name:         eC1_end_receive
+ * global_name:  tTINETServer_eC1_end_receive
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC1_end_receive(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eC1_reset
+ * name:         eC1_reset
+ * global_name:  tTINETServer_eC1_reset
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eC1_reset(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します */
+	syslog( LOG_INFO, "tTINETServer: reset" );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_PORT>]# eOpener
+ * entry port: eOpener
+ * signature:  sServerChannelOpener
+ * context:    task
+ * #[</ENTRY_PORT>]# */
+
+/* #[<ENTRY_FUNC>]# eOpener_open
+ * name:         eOpener_open
+ * global_name:  tTINETServer_eOpener_open
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eOpener_open(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	T_IPV4EP		dst;
+
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	syslog( LOG_INFO, "tTINETServer: open" );
+	if( (ercd=tcp_acp_cep(ATTR_cep_id, ATTR_rep_id, &dst, TMO_FEVR)) != E_OK ){
+		syslog( LOG_INFO, "tTINETServer: accept failed" );
+		return ercd;
+	}
+
+	syslog( LOG_INFO, "tTINETServer: accepted" );
+
+	return(ercd);
+}
+
+/* #[<ENTRY_FUNC>]# eOpener_close
+ * name:         eOpener_close
+ * global_name:  tTINETServer_eOpener_close
+ * oneway:       false
+ * #[</ENTRY_FUNC>]# */
+ER
+eOpener_close(CELLIDX idx)
+{
+	ER		ercd = E_OK;
+	CELLCB	*p_cellcb;
+	if (VALID_IDX(idx)) {
+		p_cellcb = GET_CELLCB(idx);
+	}
+	else {
+		return(E_ID);
+	}
+
+	/* ここに処理本体を記述します #_TEFB_# */
+	syslog( LOG_INFO, "tTINETServer: close" );
+	ercd = tcp_cls_cep( ATTR_cep_id, TMO_FEVR );
+
+	return(ercd);
+}
+
+/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tecs_rpc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tecs_rpc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/rpc/tecs_rpc.h	(revision 398)
@@ -0,0 +1,65 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+#ifndef  tecs_rpc_h__
+#define  tecs_rpc_h__
+
+#include "tecs.h"
+
+#ifndef E_RPC
+
+#define E_RPC    (-68)
+
+/* minor error code */
+#define E_RESET  (-101)
+#define E_MAGIC  (-102)
+
+#endif /* E_RPC */
+
+
+/*
+ * marshaler, unmarshaler 内の状態値を設定するマクロ
+ * val は sRPCErrorHandler.cdl で定義する
+ */
+#if ! defined( NO_NEED_RPC_STATE ) && ! defined( NO_NEED_RPC_ERROR_HANDLER )
+#define SET_RPC_STATE( state, val )		(state)=(val)
+#else
+#define SET_RPC_STATE( state, val )
+#endif /* NO_NEED_RPC_STATE */
+
+#endif /* tecs_rpc_h__ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/sMalloc.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/sMalloc.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/sMalloc.cdl	(revision 398)
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (C) 2012 by Ubiquitous Computing and Networking Laboratory
+ *                Ritsumeikan Univ., JAPAN
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+import_C( "t_stddef.h" );
+
+[deviate]
+signature sMalloc {
+    int    initializeMemoryPool(void);
+    void   *calloc( [in]size_t nelem, [in]size_t elem_size );
+    void   *malloc( [in]size_t size );
+    void   *realloc( [in]const void *ptr, [in]size_t new_size );
+    void   free( [in]const void *ptr );
+};
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/tecs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/tecs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/tecs.h	(revision 398)
@@ -0,0 +1,64 @@
+/*
+ *  TECS Generator
+ *      Generator for TOPPERS Embedded Component System
+ *  
+ *   Copyright (C) 2008-2013 by TOPPERS Project
+ *--
+ *   上記著作権者は，以下の(1)(4)の条件を満たす場合に限り，本ソフトウェ
+ *   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *       スコード中に含まれていること．
+ *   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *       の無保証規定を掲載すること．
+ *   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *       と．
+ *     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *         作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *         報告すること．
+ *   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *       免責すること．
+ *  
+ *   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *   の責任を負わない．
+ *  
+ *   $Id$
+ */
+
+#ifndef  tecs_h__
+#define  tecs_h__
+
+#include "t_stddef.h"
+
+#ifndef INT128_DEFINED
+#define INT128_DEFINED
+typedef struct tag_int128_t { int64_t  hi; int64_t  lo; } int128_t;
+typedef struct tag_uint128_t { int64_t  hi; int64_t  lo; } uint128_t;
+#endif /* end INT128_T_DEFINED */
+
+#ifndef SHORT_T_DEFINED
+#define SHORT_T_DEFINED
+typedef short short_t;
+typedef unsigned short ushort_t;
+#endif /* end SHORT_T_DEFINED */
+
+#ifndef CHAR_T_DEFINED				/* t_stddef.h ASP 1.7.0 以前では重複する */
+#define CHAR_T_DEFINED
+typedef char  char_t;				/* signed, unsigned 未定 */
+#endif /* end CHAR_T_DEFINED */
+
+typedef signed char		schar_t;	/* signed */
+typedef unsigned char	uchar_t;	/* unsigned */
+
+#endif /* end tecs_h__ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/tecs.xsd
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/tecs.xsd	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecs/tecs.xsd	(revision 398)
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsd:schema
+    xmlns="http://www.toppers.jp/tecs.html"
+    targetNamespace="http://www.toppers.jp/tecs.html"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
+
+  <!-- 1st element -->
+  <xsd:element name="GUI_Tool">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element minOccurs="0" maxOccurs="unbounded" ref="import" />
+          <xsd:element minOccurs="0" maxOccurs="unbounded" ref="namespace" />
+          <xsd:element minOccurs="0" maxOccurs="unbounded" ref="signature" />
+          <xsd:element minOccurs="0" maxOccurs="unbounded" ref="celltype"  />
+          <xsd:element minOccurs="0" maxOccurs="unbounded" ref="cell" />
+          <xsd:element minOccurs="0" maxOccurs="unbounded" ref="region" />
+        </xsd:choice>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <!--
+    * All elements MUST BE TOP LEVEL to assign global name.
+	* In XML file, all names are treated as global name.
+    * Note: inner elements have local name.
+	 -->
+
+  <!-- elements of statement -->
+  <xsd:element name="import"    type="importType" />
+  <xsd:element name="signature" type="signatureType" />
+  <xsd:element name="celltype"  type="celltypeType" />
+  <xsd:element name="cell"      type="cellType" />
+  <xsd:element name="namespace" type="namespaceType" />
+  <xsd:element name="region"    type="regionType" />
+
+  <!-- elements of name, type, expression(rhs, initializer, subscript)  -->
+  <xsd:element name="name"      type="xsd:string" />
+  <xsd:element name="signame"   type="xsd:string" />
+  <xsd:element name="rettype"   type="xsd:string" />
+  <xsd:element name="type"      type="xsd:string" />
+  <xsd:element name="subscript" type="xsd:string" />
+  <xsd:element name="rhs"       type="xsd:string" />
+  <xsd:element name="initializer" type="xsd:string" />
+  <xsd:element name="choiceElement" type="xsd:string" />
+  <xsd:element name="composite" />                       <!-- treat composite as celltype with 'composite' specifier -->
+  <xsd:element name="singleton" />
+  <xsd:element name="active" />
+
+  <!-- elements for signature -->
+  <xsd:element name="param">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="name"/>
+        <xsd:element ref="type"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:element name="func">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="name"/>
+        <xsd:element ref="rettype" />
+        <xsd:element minOccurs="0" maxOccurs="unbounded" ref="param" />
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <!-- elements for celltype -->
+  <xsd:element name="attr">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="name"/>
+        <xsd:element ref="type" />
+        <xsd:element minOccurs="0" ref="initializer" />
+        <xsd:element minOccurs="0" maxOccurs="1" ref="choice" />
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:element name="choice">
+    <xsd:complexType>
+      <xsd:sequence>
+      <xsd:element minOccurs="1" maxOccurs="unbounded" ref="choiceElement"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:element name="call">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="name"/>
+        <xsd:element ref="signame" />
+        <xsd:element minOccurs="0" ref="subscript" />
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:element name="entry">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="name"/>
+        <xsd:element ref="signame" />
+        <xsd:element minOccurs="0" ref="subscript" />
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <!-- elements for cell -->
+  <xsd:element name="attr_join">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="name"/>
+        <xsd:element ref="rhs" />
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:element name="call_join">
+    <xsd:complexType>
+     <xsd:sequence>
+        <xsd:element ref="name"/>
+        <xsd:element minOccurs="0" ref="subscript" />
+        <xsd:element ref="rhs" />
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+
+  <!-- ***** complex types ***** -->
+  <xsd:complexType name="signatureType">
+    <xsd:sequence>
+      <xsd:element ref="name"/>
+      <xsd:element minOccurs="1" maxOccurs="unbounded" ref="func" />
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="celltypeType">
+    <xsd:sequence>
+      <xsd:choice maxOccurs="unbounded">
+        <xsd:element ref="name"/>
+        <xsd:element maxOccurs="1" ref="composite" />
+        <xsd:element maxOccurs="1" ref="singleton" />
+        <xsd:element maxOccurs="1" ref="active" />
+        <xsd:element maxOccurs="unbounded" ref="attr" />
+        <xsd:element maxOccurs="unbounded" ref="call" />
+        <xsd:element maxOccurs="unbounded" ref="entry" />
+      </xsd:choice>
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="cellType">
+    <xsd:sequence>
+      <xsd:choice maxOccurs="unbounded">
+        <xsd:element ref="name"/>
+        <xsd:element maxOccurs="unbounded" ref="attr_join" />
+        <xsd:element maxOccurs="unbounded" ref="call_join" />
+      </xsd:choice>
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="namespaceType">
+    <xsd:sequence maxOccurs="unbounded" >
+      <xsd:element ref="name"/>
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="signature" />
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="celltype" />
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="namespace" />
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="regionType">
+    <xsd:sequence maxOccurs="unbounded" >
+      <xsd:element ref="name"/>
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="cell" />
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="import" />  <!-- inner: cell, region only -->
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="region" />
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="importType">
+  	<xsd:sequence>
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="import" />
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="signature" />
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="celltype"  />
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="cell" />
+      <xsd:element minOccurs="0" maxOccurs="unbounded" ref="region" />
+    </xsd:sequence>
+    <xsd:attribute name="path" type="xsd:string" use="required" />
+  </xsd:complexType>
+
+</xsd:schema>
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen	(revision 398)
@@ -0,0 +1,58 @@
+#! /bin/sh
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2013 by TOPPERS Project
+#
+#   ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#   ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#   å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#   (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#       æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#       ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#   (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#       ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#       è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#       ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#   (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#       ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#       ã¨ï¼
+#     (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#         ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#     (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+#         å ±åãããã¨ï¼
+#   (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#       å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#       ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#       ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#       å
+è²¬ãããã¨ï¼
+#  
+#   æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#   ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#   ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#   ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#   ã®è²¬ä»»ãè² ããªãï¼
+#  
+#   $Id$
+
+#ruby -w $TECSPATH/../tecsgen/tecsgen.rb "$@"
+tecsgen.rb "$@"
+exit $?
+
+# ç´æ¥ tecsgen.rb ãå¼åºãã±ã¼ã¹ãããããããããã®ã¹ã¯ãªããã§å¦çãè¡ãã¹ãã§ãªã
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen.rb	(revision 398)
@@ -0,0 +1,624 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2019 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#= tecsgen  : TECS のジェネレータ
+#
+#Authors::    石川　拓也(HRP2Plugin)
+#Authors::    原　　拓(動的結合仕様)
+#Authors::    河田　智明(NotifierPlugin)
+#Authors::    高田　広章(ASP3 への TECS 組込み)
+#Authors::    高木　信尚(ランタイムヘッダ)
+#Authors::    成瀬　有美(TECS flow 実装)
+#Authors::    鵜飼　敬幸(ATK1Plugin)
+#Authors::    大山　博司(ジェネレータ実装, RPCPlugin, TracePlugin, MrubyBridgePlugin)
+#Authors::    山本　将也(ジェネレータ初期プロトタイプ実装)
+#Authors::    小南　靖雄(テストコードの一部)
+#Authors::    安積　卓也(ASP+TECS, EV3RT+TECS, mruby on TECS等実装)
+#  Authors list is in i-ro-ha order.
+#Version::   see version.rb
+$Copyright = "Copyright(c) 2008-2019, TOPPERS project. All rights reserved."
+$License   = "TOPPERS License"
+
+# This doesn't work as expected in exerb version (Ruby 1.8.7?)
+$tecsgen_base_path = File.dirname( File.expand_path __FILE__ )
+
+
+###
+#= Array  initializer の '{', '}' で囲まれた場合
+# mikan AggregateInitializer など、クラスを変更すべきである
+class Array
+  #=== CDL の文字列を生成する
+  def to_CDL_str
+    str = '{ '
+    delim = ''
+    self.each{ |v|
+      str += delim + v.to_CDL_str
+      delim = ', '
+    }
+    str += ' }'
+    return str
+  end
+
+  def show_tree( indent )
+    indent.times{ print "  " }
+    print( "Array\n" )
+    self.each{ |m|
+      m.show_tree( indent+1 )
+    }
+  end
+end
+
+#=== RUBY ライブラリをロードする
+#
+# -L, $RUBYLIB, システム(/usr/lib/rub..など) の順にサーチが行われる
+# exerb 対応のため、上記パスにファイルが見つからない場合 require を実行してみる
+#
+# プラグインの場合は b_fatal = false を指定。ファイルがなくてもエラー出力後、処理続行
+# b_fatal = false の場合 tecslib/core がサーチパスに追加される
+#RETURN::Bool   : true=成功、 false=失敗   失敗した場合、Generator.error は呼び元で出力する
+def require_tecsgen_lib( fname, b_fatal = true )
+  dbgPrint( "require_lib: #{fname}\n")
+  set_kcode $KCODE_TECSGEN
+  begin  
+    b_require = false
+    b_exception = false
+
+    # -L 、 $RUBYLIB で指定されたパスおよびシステムのパスからサーチ
+    #   exerb では $LOAD_PATH は ["."] のみ入っているようだ
+    ($library_path+$LOAD_PATH).each{ |path|
+      [ "", "tecslib/plugin/" ].each { |lp|
+        lib = File.expand_path( path ) + '/' + lp + fname
+        
+        if File.exist? lib then  # ファイル存否と他のエラーを区別するため存在確認をする
+          begin
+            require( lib )
+            b_require = true
+          rescue Exception => evar
+            b_exception = true
+            print_exception( evar )
+          end
+          break
+        end
+      }
+      if b_require then
+        break
+      end
+    }
+
+    if b_require == false && b_exception == false then
+      # exerb 対応 "." をサーチパスの最初に加える
+      #   "tecslib/" は RPCPlugin.rb, TracePlugin.rb のために用意してある
+      #   RPCPlugin.rb, TracePlugin.rb が tecslib 下でなければ不要になるが、このようにしておく
+      ["","tecslib/plugin/"].each{ |lp|
+        path = lp + fname
+        begin
+          require path
+          return true
+        rescue LoadError => e
+          # p "LoadError to load #{fname}"
+          # 2015.12.18 exerb 版でプラグインのロードでエラーが出るので、無視する. おそらく昔からエラーは出ていた
+          # print_exception( e )
+        rescue Exception => e
+          b_exception = true
+          # 文法エラーなどが発生
+          print_exception( e )
+          break
+        end
+      }
+    end
+
+    if b_require == false then
+      # 見つからなかった
+      if b_exception == false then
+        STDERR << "tecsgen: Fail to load #{fname}. Check $RUBYLIB environment variable or -L option\n"
+      end
+      # tecsgen を構成するファイルの場合は中止する
+      if b_fatal then
+        STDERR << "tecsgen: Exit because of unrecoverble error\n"
+        exit 1
+      end
+      return false
+    end
+    return true
+  ensure
+    # $KCODE を CDL の文字コードに戻しておく
+    set_kcode $KCODE_CDL
+  end
+end
+
+#=== 例外の表示
+#evar:: Exception
+def print_exception( evar )
+# もしスタックトレースが出るまでい時間がかかるようならば、次をコメントアウトしてみるべし
+  print "*** Begin Ruby exception message ***\n"
+  puts( evar.to_s )
+
+  if $debug then
+    puts "#### stack trace ####"
+    pp evar.backtrace
+  end
+  print "*** End Ruby exception message ***\n"
+end
+
+def dbgPrint( str )
+  if $debug then
+    print str
+  end
+end
+
+def dbgPrintf( *param )
+  if $debug then
+    printf *param
+  end
+end
+
+#=== エラーおよび警告のレポート
+def print_report
+  msg = nil
+
+  if Generator.get_n_error != 0 then
+    msg = "#{Generator.get_n_error} error"
+    msg = "#{msg}s" if Generator.get_n_error >= 2
+  end
+
+  if Generator.get_n_warning != 0 then
+    msg = "#{msg}  " if msg
+    msg = "#{msg}#{Generator.get_n_warning} warning"
+    msg = "#{msg}s" if Generator.get_n_warning >= 2
+  end
+
+  puts msg if msg
+end
+
+#=== $KCODE を設定
+def set_kcode kcode
+  if ! $b_no_kcode then
+    $KCODE = kcode
+  end
+end
+#----- class TECSGEN -------#
+class TECSGEN
+
+  @@current_tecsgen = nil
+
+  def self.init( addtional_option_parser = nil )
+    initialize_global_var
+    analyze_option addtional_option_parser
+    load_modules
+    if ! $TECSFLOW then
+      setup
+    end
+        
+    dbgPrint  "tecspath: #{$tecsgen_base_path}, __FILE__=#{__FILE__}\n"
+    dbgPrint  "ARGV(remained): #{ARGV}, argments=#{$arguments}\n"
+  end
+
+  #----- initialize -------#
+  def initialize
+    @cell_list = nil
+    @cell_list2 = nil
+    @celltype_list = nil
+    @root_namespace = nil
+
+    #--- obsolete ---#   replaced to TOOL_INFO
+    @cell_location_list = []
+    @join_location_list = []
+  end
+
+  def run1
+    @@current_tecsgen = self
+
+    syntax_analisys ARGV
+    semantics_analisys_1
+    semantics_analisys_2
+
+    @celltype_list = Celltype.get_celltype_list
+    @cell_list = Cell.get_cell_list
+    @cell_list2 = Cell.get_cell_list2
+
+    @@current_tecsgen = nil
+  end
+
+  def run2
+    @@current_tecsgen = self
+
+    optimize_and_generate
+    finalize
+
+    @@current_tecsgen = nil
+  end
+
+  #-----  initialize_global_var -----#
+  def self.initialize_global_var
+
+    require 'optparse'
+    #2.0 require 'runit/assert.rb'
+    require 'kconv'
+    $b_no_kcode = RUBY_VERSION >= "1.9.0" ? true : false
+	       # Use Ruby 1.9 M17N code (use Ruby 1.8 code if false).
+    if ! $b_no_kcode then
+      require 'jcode'
+    end
+    require 'pp'
+    # include RUNIT::Assert
+
+    ### グローバル変数定義 ###
+
+    # コマンドライン引数　 (Makefile.templ へ出力)
+    $arguments = ""
+    ARGV.each { |a| $arguments += " " + a }
+
+    $unopt     = false     # bool:   disable optimizing both call and entry port
+    $unopt_entry= false    # bool:   disable optimizing entry port
+    $gen_base  = "gen"     # string: folder path to place generated files
+    $gen       = $gen_base # string: folder path to place generated files
+    $generate_all_template = false   # bool:   generarete template files for all celltypes (if non cell exist or system celltypes)
+    $generate_no_template = false    # bool:   generarete no template file (neither celltype code nor Makefile)
+    $idx_is_id = false     # bool:   all components are idx_is_id
+    $unique_id = false     # bool:   assign unique id to each cell (otherwise begin from 1 for each celltype)
+    $debug     = false     # bool:   tecsgen debug message
+    $dryrun    = false     # bool:   dryrun mode: syntax is checked, but not generate any files
+    $show_tree = false     # bool:   show parsing tree
+    $verbose   = false     # bool:   verbose mode: show some messages
+    $yydebug   = false     # bool:   yydebug: parser debug mode (need bnf-deb.tab.rb)
+    $run_dir   = Dir.pwd   # string: tecsgen/tecscde start up directory
+    $base_dir  = {  }      # string=>bool: base dir for import_path (key:base_dir, val:actually used or specified directly)
+    $import_path = [ "." ] # string array : import/import_C path
+    $import_path_opt = []  # [String]
+    $library_path = [ $tecsgen_base_path ] # string array : path to dir where tecsgen.rb placed
+    $define    = [ ]       # string array : define
+    $ram_initializer = false # bool: generate ram initializer
+    $region_list = {}      #string array : region path which is generated
+    $generating_region = nil # Region:  Region to optimisze & generate code   # コマンドラインオプションではない
+		 #           Cell#is_generate? にて参照される
+    $unit_test = false     # bool:   unit test verification
+    $kcode     = nil       # nil | String: Kanji code type "euc"|"sjis"|"none"|"utf8"
+    $force_overwrite = false # bool:  force overwrite all files if file contents not differ
+    $no_banner = false     # bool:   not print banner
+    $print_version = false # bool:   print version
+    $target    = "tecs"    # String: target name, ARGV[0] から再設定する（"tecs" は仮のターゲット)
+    $no_default_import_path = false  # bool: no default import path
+    $c_suffix  = "c"       # suffix for C progorams (for C++ source)
+    $h_suffix  = "h"       # suffix for C progoram headers (for C++ source)
+
+    if ENV['TECSGEN_DEFAULT_RAM'] then
+      rom_ram_defalult = "ram"
+    else
+      rom_ram_defalult = "rom"
+    end
+    if rom_ram_defalult == "rom" then
+      $rom       = true      # bool:   ROM support : generate CB separately
+    else
+      $rom       = false     # bool:   ROM support : generate CB separately
+    end
+    $b_cpp_specified = false
+    if $cpp == nil then
+      $cpp       = "gcc -E -DTECSGEN"
+    end
+    if ENV[ 'TECS_CPP' ]then
+      $cpp = ENV[ 'TECS_CPP' ]
+      $b_cpp_specified = true
+    end
+    if ENV[ 'TECSPATH' ] then
+      $tecspath = ENV[ 'TECSPATH' ]
+    else
+      $tecspath = "#{$tecsgen_base_path}/tecs"
+    end
+
+    # # 文字コードの設定
+    if $IN_EXERB then
+      # KCODE_CDL, $KCONV_CDL を仮に設定する (tecs_lang.rb ですぐに再設定される)
+      $KCODE_CDL = "SJIS"          # string: "EUC" | "SJIS" | "NONE" | "UTF8"
+      $KCONV_CDL = Kconv::SJIS     # const: NONE には ASCII を対応させる
+    else
+      $KCODE_CDL = "EUC"           # string: "EUC" | "SJIS" | "NONE" | "UTF8"
+      $KCONV_CDL = Kconv::EUC      # const: NONE には ASCII を対応させる
+    end
+    # $KCODE_TECSGEN, $KCONV_TECSGEN を仮に設定する (tecs_lang.rb ですぐに再設定される)
+    $KCODE_TECSGEN = "UTF8"      # string: "EUC"  このファイルの文字コード（オプションではなく定数）
+    $KCONV_TECSGEN = Kconv::UTF8 # const: 
+    set_kcode( $KCODE_TECSGEN )  # このファイルの文字コードを設定
+
+  end # initialize_global_var
+
+  def self.analyze_option( additional_option_parser )
+
+    ###  tecsgen コマンドオプション解析  ###
+    ARGV.options {|parser|
+      parser.banner = "Usage: tecsgen [options] files"
+      parser.on('-D', '--define=def', 'define cpp symbol for import_C') { |define|
+        $define << define
+      }
+      parser.on('-G', '--generate-region=path', 'generate region') { |path|
+        if path =~ /^::/ then
+          gen_path = path
+        else
+          gen_path = "::" + path
+        end
+        $region_list[ gen_path ] = true
+      }
+      parser.on('-I', '--import-path=path', 'imoprt/import_C path') { |path|
+        $import_path << path
+        $import_path_opt << path
+      }
+      parser.on('-L', '--library-path=path', 'path to dir where tecsgen.rb (obsolete, unnecessary to specify -L, those passes are gotten from tecsgen.rb') { |path|
+        $library_path << path
+      }
+      parser.on('-R', '--RAM-initializer',   'generate RAM initializer. INITIALIZE_TECS() must be called before running any TECS code.' ){
+        $ram_initializer = true
+      }
+      parser.on('-U', '--unoptimize', 'unoptimize') {
+        $unopt = true
+      }
+      parser.on('--unoptimize-entry', 'unoptimize entry port') {
+        $unopt_entry = true
+      }
+      parser.on('-c', '--cpp=cpp_cmd', 'C pre-processor command used import_C (default: gcc -E -DTECSGEN), you can also specify by environment variable TECS_CPP' ){
+        |arg|
+        $cpp = arg
+        $b_cpp_specified = true
+      }
+      parser.on('-d', '--dryrun',      'dryrun' ){
+        $dryrun = true
+      }
+      parser.on('-f', '--force-overwrite', 'force overwrite all files') {
+        $force_overwrite = true
+      }
+      parser.on('-g', '--gen=dir',     'generate dir') { |dir|
+        $gen = $gen_base = dir
+      }
+      parser.on('-i', '--idx_is_id',   'set idx_is_id to all celltypes') {
+        $idx_is_id = true
+      }
+      #  parser.on('-k', '--kcode=code',  'set kanji code: euc|sjis|none|utf8, none is default') { |code|
+      parser.on('-k', '--kcode=code',  "set kanji code: euc|sjis|none|utf8") { |code|
+        $kcode = code
+      }
+      #  old_mode は V1.0.C.22 で廃止
+      #  parser.on('-o', '--old-mode',    'old mode' ){
+      #    $old_mode = true
+      #  }
+      parser.on('-r', '--ram',     'RAM only' ){
+        $rom = false
+      }
+      parser.on('-s', '--show-tree',   'show parsing tree' ){
+        $show_tree = true
+      }
+      parser.on('-t', '--generator-debug', 'generator debug' ){
+        $debug = true
+        $verbose = true
+      }
+      parser.on('-u', '--unique-id', 'assign unique id for each cell' ){
+        $unique_id = true
+      }
+      parser.on('-v', '--verbose',     'verbose mode' ){
+        $verbose = true
+      }
+      parser.on('-y', '--yydebug',     'yydebug' ){
+        $yydebug = true
+      }
+      parser.on( '--no-banner', 'not display banner') {
+        $no_banner = true
+      }
+      parser.on( '--version', 'print version') {
+        $print_version = true
+      }
+      parser.on( '--unit-test', 'unit verification (test tecsgen itself)') {
+        $unit_test = true
+      }
+      parser.on( '--generate-all-template', 'generate all celltypes\' templates') {
+        $generate_all_template = true
+      }
+      parser.on( '--generate-no-template',  'generate no template') {
+        $generate_no_template = true
+      }
+      parser.on( '--no-default-import-path', 'no default import path' ){
+        $no_default_import_path = true
+      }
+      parser.on( '--c-suffix=c', 'C program suffix (default: c)' ){
+        | suffix |
+        $c_suffix = suffix
+      }
+      parser.on( '--h-suffix=h', 'C program header suffix (default: h)' ){
+        | suffix |
+        $h_suffix = suffix
+      }
+      #  parser.on(  '--include_path_opt_format',  'cpp include path option format, default: "-I %s"' ){
+      #  }
+      parser.version = #{$version}
+      parser.release = nil
+      if additional_option_parser
+        additional_option_parser.call( parser )
+      end
+      parser.parse!
+    }
+
+    if ARGV.empty? && ! $print_version && ! $unit_test && ! $TECSFLOW
+      ARGV.options{|parser|
+        puts parser.help
+        exit 1
+      }
+    end
+
+  end # analyze_option
+
+  def self.load_modules
+    ### tecsgen モジュールのロード ####
+    # -L でパス指定可能としたため、ここからロードを開始する
+
+    #  tecsgen バージョンファイルのロード
+    # これを実行するまで tecsgen のバージョンを表示できない
+    # このファイルを誤って読み込むと、異なるバージョン名を表示してしまう
+    require_tecsgen_lib 'tecslib/version.rb'
+    if $title then
+      STDERR << "#{$title} version #{$tool_version} (tecsgen version #{$version})  #{$Copyright}\n"
+    elsif ! $no_banner || $print_version
+      STDERR << "tecsgen  version #{$version}  #{$Copyright}\n"
+    end
+    if $verbose then
+      STDERR << "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}]\n"
+    end
+    if $print_version && ARGV.empty? && ! $TECSFLOW
+      exit
+    end
+
+    # 文字コード決定のため最初に読みこむ
+    require_tecsgen_lib 'tecslib/core/tecs_lang.rb'
+
+    unless $yydebug then
+      require_tecsgen_lib 'tecslib/core/bnf.tab.rb'
+    else
+      require_tecsgen_lib 'tecslib/core/bnf-deb.tab.rb'
+    end
+
+    # syntaxobj.rb には Node が定義されているので、早い段階で require 
+    require_tecsgen_lib 'tecslib/core/syntaxobj.rb'
+    require_tecsgen_lib 'tecslib/core/pluginModule.rb'
+    require_tecsgen_lib 'tecslib/core/plugin.rb'
+    require_tecsgen_lib 'tecslib/core/messages.rb'
+    require_tecsgen_lib 'tecslib/core/types.rb'
+    require_tecsgen_lib 'tecslib/core/value.rb'
+    require_tecsgen_lib 'tecslib/core/componentobj.rb'
+    require_tecsgen_lib 'tecslib/core/expression.rb'
+    require_tecsgen_lib 'tecslib/core/optimize.rb'
+    require_tecsgen_lib 'tecslib/core/tecsgen.rb'
+    require_tecsgen_lib 'tecslib/core/generate.rb'
+    require_tecsgen_lib 'tecslib/core/gen_xml.rb'
+    require_tecsgen_lib 'tecslib/core/tool_info.rb'
+    require_tecsgen_lib 'tecslib/core/tecsinfo.rb'
+    require_tecsgen_lib 'tecslib/core/unjoin_plugin.rb'
+    require_tecsgen_lib 'tecslib/plugin/CelltypePlugin.rb'
+    require_tecsgen_lib 'tecslib/plugin/CompositePlugin.rb'
+    require_tecsgen_lib 'tecslib/plugin/CellPlugin.rb'
+    require_tecsgen_lib 'tecslib/plugin/SignaturePlugin.rb'
+    require_tecsgen_lib 'tecslib/plugin/ThroughPlugin.rb'
+    require_tecsgen_lib 'tecslib/plugin/DomainPlugin.rb'
+    require_tecsgen_lib 'tecslib/plugin/MultiPlugin.rb'
+
+    # C 言語パーサ
+    require_tecsgen_lib 'tecslib/core/C_parser.tab.rb'
+    require_tecsgen_lib 'tecslib/core/ctypes.rb'
+
+    if $unit_test then
+      exit 1
+    end
+
+  end # load_modules
+
+  def self.setup
+    # $import_path, $tecspath を調整
+    TECSGEN.adjust_exerb_path
+
+    # $import_path に環境変数 $TECSGEN およびその直下を追加
+    if $no_default_import_path == false then
+      # $TECSGEN および、その直下のディレクトリをパスに追加
+      if $tecspath != "." then
+        TECSGEN.add_import_path $tecspath
+        dir = nil
+        begin
+          Dir.foreach( $tecspath ){ |f|
+            if f != "." && f != ".." && File.directory?( $tecspath + '/' + f ) then
+              TECSGEN.add_import_path( $tecspath + '/' + f )
+            end
+          }
+        rescue
+          # 無視
+        end
+      end
+    end
+
+    # デフォルト設定
+    TECSGEN.set_default_config
+
+    # $target の設定
+    $target = ARGV[0]
+    pos = $target.rindex( /[:\\\/]/ )
+    if pos then
+      $target = $target[pos+1..-1]  # ディレクトリ区切りを除いた文字列
+    end
+    pos = $target.rindex( /\./ )
+    if pos then
+      $target = $target[0..pos-1]   # 拡張子を取り除いた文字列
+    end
+
+    # gen ディレクトリの作成
+    begin
+      if ! File.directory?( $gen_base ) then
+        Dir.mkdir( $gen_base )
+      end
+    rescue
+      print( "Cannot mkdir #{$gen_base}. If the path has hierarchy, please create directory by manual.\n" )
+      exit 1
+    end
+  end # setup
+
+  #=== TECSGEN#get_celltype_list
+  def get_celltype_list
+    @celltype_list
+  end
+
+  #=== TECSGEN#get_cell_list
+  def get_cell_list
+    @cell_list
+  end
+
+  def get_root_namespace
+    @root_namespace
+  end
+end # TECSGEN
+
+# 複数のジェネレータインスタンスを生成することは、可能だが、以下の問題がある
+#  クラス変数のリセットを確実に行う必要がある
+
+if $TECSCDE != true && $TECSFLOW != true then
+  begin
+    TECSGEN.init
+    tecsgen = TECSGEN.new
+    tecsgen.run1
+    tecsgen.run2
+    tecsgen.dump_tecsgen_rbdmp
+  rescue => evar
+    print_exception( evar )
+    STDERR << "tecsgen: exit because of unrecoverble error.\n"
+    STDERR << "   please retry after resolve early error.\n"
+    STDERR << "   if no error has occured, please report to TOPPERS TECS WG (users@toppers.jp or com-wg@toppers.jp).\n"
+    exit 1
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen_rcov
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen_rcov	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen_rcov	(revision 398)
@@ -0,0 +1,13 @@
+#! /bin/sh
+# å¼æ°ã¯ "$@" ã¨ãã¦ãªãã¨ãå
+ã®å¼æ°ã« "--cpp=gcc-3 -E -DTECS" ã®ãããª '"' ã§å²ã¾ãããã®ãæå¾
+ããã¨ããã«æ±ããªã
+# --aggregate ã®å¼æ°ã¯ test/Makefile ã¨ä¸è´ãããå¿
+è¦ããã
+# rcov å®è¡æ pretty.rb ã§ ruby ä¾å¤çºçãããTrac #601 åç
+§ã
+
+do="rcov -t --no-html --aggregate $TECSPATH/../test/coverage.data $TECSPATH/../tecsgen/tecsgen.rb --"
+echo $do "$@"
+$do "$@"
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen_rcov.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen_rcov.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsgen_rcov.rb	(revision 398)
@@ -0,0 +1,64 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2016 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# カバレッジを取るための tecsgen コマンド
+# SimpleCov を使用するため、ruby V1.9 以降が必要
+#
+# Usage: tecsgen_rcov.rb [options] CDL-file.cdl
+#
+
+$:.unshift(File.dirname(__FILE__))
+
+require 'simplecov'
+SimpleCov.command_name "tecsgen#{Time.now.to_f}"
+SimpleCov.root File.dirname( File.expand_path __FILE__ )
+SimpleCov.at_exit do
+  SimpleCov.result.format!
+end
+SimpleCov.start
+# SimpleCov.start do
+#    # add_filter "//"
+# end
+
+print "simplecov begin\n"
+
+require 'tecsgen'
+
+print "simplecov end\n"
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.tab.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.tab.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.tab.rb	(revision 398)
@@ -0,0 +1,2608 @@
+#
+# DO NOT MODIFY!!!!
+# This file is automatically generated by Racc 1.4.9
+# from Racc grammer file "".
+#
+
+require 'racc/parser.rb'
+class C_parser < Racc::Parser
+
+module_eval(<<'...end C_parser.y.rb/module_eval...', 'C_parser.y.rb', 784)
+
+	RESERVED = {
+		# keyword
+		'typedef' => :TYPEDEF,
+		'struct' => :STRUCT,
+		'union' => :UNION,
+		'sizeof' => :SIZEOF,
+		'throw' => :THROW,
+
+		# specifier
+		# types
+		'void'    => :VOID,
+		'char'    => :CHAR,
+		'short'   => :SHORT,
+
+		'volatile'=> :VOLATILE,
+		'restrict'=> :RESTRICT,
+		'const'   => :CONST,
+		'extern'   => :EXTERN,
+
+		'long'    => :LONG,
+		'float'   => :FLOAT,
+		'double'  => :DOUBLE,
+		'signed'  => :SIGNED,
+		'unsigned'=> :UNSIGNED,
+
+		'int'     => :INT,
+		'enum'    => :ENUM,
+
+		'if'      => :IF,
+		'else'    => :ELSE,
+		'while'   => :WHILE,
+		'do'      => :DO,
+		'for'     => :FOR,
+		'switch'  => :SWITCH,
+		'case'    => :CASE,
+		'default' => :DEFAULT,
+		'goto'    => :GOTO,
+		'continue' => :CONTINUE,
+		'break'   => :BREAK,
+		'return'  => :RETURN,
+		'__inline__'  => :__INLINE__,
+		'inline'  => :INLINE,
+		'__inline'  => :__INLINE,
+		'Inline'  => :CINLINE,        # inline starting with Capital letter
+		'static'  => :STATIC,
+		'register' => :REGISTER,
+		'auto'    => :AUTO,
+		'__extension__'    => :EXTENSION,
+		'__asm__' => :_ASM,
+		'asm' =>     :_ASM
+
+	}
+
+	@@generator_nest = -1
+	@@generator_stack = []
+	@@current_locale = []
+
+	def finalize
+
+		# mikan Namespace.pop
+		Celltype.pop
+		Cell.pop
+		CompositeCelltype.pop
+		Region.pop
+
+	end
+
+	def set_plugin( plugin )
+		@plugin = plugin
+	end
+
+	def self.get_plugin
+		@@generator_stack[@@generator_nest].get_plugin
+	end
+
+	def get_plugin
+		@plugin
+	end
+
+	def parse(files)
+
+		# mikan Namespace.push
+		Celltype.push
+		Cell.push
+		CompositeCelltype.push
+		Region.push
+
+		@@generator_nest += 1
+		@@generator_stack[@@generator_nest] = self
+		@b_no_type_name = false
+
+	begin
+
+		@q = []
+		comment = false
+#		b_asm   = false
+
+		# euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策
+		TECS_LANG::set_kcode_binary
+
+		# 800U, 0xffLL など (整数リテラルに共通の修飾子)
+		integer_qualifier = "([Uu][Ll][Ll]|[Uu][Ll]|[Uu]|[Ll][Ll]|[Ll])?"
+
+		files.each {|file|
+			lineno = 1
+		begin
+#2.0		IO.foreach(file) {|line|
+			TECSIO.foreach(file) {|line|
+			col = 1
+			line.rstrip!
+
+			until line.empty?
+
+				if comment
+					case line
+					# コメント終了
+					when /\A\*\//
+						comment = false
+					when /\A./
+						;
+					end
+				else
+					case line
+					# 空白、プリプロセスディレクティブ
+					when /\A\s+/
+						;
+					# 識別子
+					when /\A[a-zA-Z_]\w*/
+						word = $&
+						@q << [RESERVED[word] || :IDENTIFIER, Token.new(word.intern, file, lineno, col)]
+					# 16 進数定数
+					when /\A0x[0-9A-Fa-f]+#{integer_qualifier}/
+						@q << [:HEX_CONSTANT, Token.new($&, file, lineno, col)]
+					# 8 進数定数
+					when /\A0[0-7]+#{integer_qualifier}/
+						@q << [:OCTAL_CONSTANT, Token.new($&, file, lineno, col)]
+					# 浮動小数定数
+					when /\A[0-9]+\.([0-9]*)?([Ee][+-]?[0-9]+)?/
+						@q << [:FLOATING_CONSTANT, Token.new($&, file, lineno, col)]
+					# 整数定数
+					when /\A\d+#{integer_qualifier}/
+					# when /\A\d+/
+						@q << [:INTEGER_CONSTANT, Token.new($&.to_i, file, lineno, col)]
+					# 文字
+					when /\A'(?:[^'\\]|\\.)'/
+						@q << [:CHARACTER_LITERAL, Token.new($&, file, lineno, col)]
+					# 文字列
+#					"#include  #include #include \"../systask/logtask.cfg\"       最後の " 忘れ)で無限ループ
+#					when /\A"(?:[^"\\]+|\\.)*"/
+					when /\A"(?:[^"\\]|\\.)*"/   # これはうまく行くようだ
+						@q << [:STRING_LITERAL, Token.new($&, file, lineno, col)]
+					# 行コメント
+					when /\A\/\/.*$/
+						# 読み飛ばすだけ
+					# コメント開始
+					when /\A\/\*/
+						comment = true
+					when /\A>>=/, /\A<<=/, /\A>>/,  /\A<</
+						@q << [$&, Token.new($&, file, lineno, col)]
+					when /\A\+=/, /\A\-=/, /\A\*=/, /\A\/=/, /\A%=/, /\A&=/, /\A\|=/, /\A\^=/
+						@q << [$&, Token.new($&, file, lineno, col)]
+					when /\A::/, /\A==/, /\A!=/, /\A>=/, /\A<=/, /\A\->/, /\A\+\+/, /\A\-\-/
+						@q << [$&, Token.new($&, file, lineno, col)]
+					when /\A\|\|/, /\A\&\&/
+						@q << [$&, Token.new($&, file, lineno, col)]
+					when /\A./
+						@q << [$&, Token.new($&, file, lineno, col)]
+					else
+						raise
+					end
+				end
+
+				line = $'
+				col += $&.length
+			end
+
+			lineno += 1
+		}
+
+		rescue => evar
+			Generator.error( "B1002 while open or reading \'$1\'" , file )
+			print_exception( evar )
+		end
+	}
+
+	# 終了の印
+	@q << nil
+
+	@yydebug = true
+	do_parse
+
+		ensure
+			@@generator_nest -= 1
+			TECS_LANG::reset_kcode
+		end
+
+	end
+
+
+	def next_token
+		token = @q.shift
+
+		if token then
+			@@current_locale[@@generator_nest] = token[1].locale
+
+			case token[1].val
+			when ";", ":", ",", "(", ")", "{", "}"
+			set_no_type_name false
+			when ".", "->"
+			set_no_type_name true
+			end
+
+			# TYPE_NAME トークンへ置き換え
+			if @b_no_type_name == false
+				if token[0] == :IDENTIFIER && Namespace.is_typename?( token[1].val ) then
+					token[0] = :TYPE_NAME
+					locale = @@current_locale[@@generator_nest]
+#print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}: type_name'\n" )
+				end
+			end
+
+			if $debug then     # 070107 token 無効時ここを通さないようした (through 対応 -d の時に例外発生) 
+				locale = @@current_locale[@@generator_nest]
+				if token then
+					print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}'\n" )
+				else
+					print( "#{locale[0]}: line #{locale[1]} : EOF\n" )
+				end
+			end
+		end
+
+		token
+	end
+
+	def on_error(t, v, vstack)
+		if v == "$" then
+			Generator.error( "B1003 Unexpected EOF"  )
+		else
+			Generator.error( "B1004 syntax error near \'$1\'" , v.val )
+		end
+
+	end
+
+	def self.current_locale
+		@@current_locale[ @@generator_nest ]
+	end
+
+	@@n_error = 0
+	@@n_warning = 0
+	@@n_info = 0
+
+	# このメソッドは構文解析、意味解析からのみ呼出し可（コード生成でエラー発生は不適切）
+	def self.error( msg )
+		@@n_error += 1
+		locale = @@current_locale[ @@generator_nest ]
+
+		if locale then
+			Console.puts "#{locale[0]}:#{locale[1]}: error: #{msg}"
+		else
+			Console.puts "error: #{msg}"
+		end
+	end
+
+	# このメソッドは構文解析、意味解析からのみ呼出し可（コード生成でウォーニング発生は不適切）
+	def self.warning( msg )
+		@@n_warning += 1
+		locale = @@current_locale[ @@generator_nest ]
+		Console.puts "#{locale[0]}:#{locale[1]}: warning: #{msg}"
+	end
+
+	# このメソッドは構文解析、意味解析からのみ呼出し可
+	def self.info( msg )
+		@@n_info += 1
+		locale = @@current_locale[ @@generator_nest ]
+		Console.puts "#{locale[0]}:#{locale[1]}: info: #{msg}"
+	end
+
+	def self.get_n_error
+		@@n_error
+	end
+
+	def self.get_n_warning
+		@@n_warning
+	end
+
+	def self.get_nest
+		@@generator_nest
+	end
+
+	def set_no_type_name b_no_type_name
+		locale = @@current_locale[ @@generator_nest ]
+#print "b_no_type_name=#{b_no_type_name} #{locale[0]}: line #{locale[1]}\n"
+		@b_no_type_name = b_no_type_name
+	end
+
+...end C_parser.y.rb/module_eval...
+##### State transition tables begin ###
+
+clist = [
+'111,112,113,114,115,117,294,118,56,298,55,163,54,123,124,82,54,262,122',
+'125,126,127,128,129,130,111,112,113,114,115,117,217,118,271,391,101',
+'163,91,123,124,82,271,271,122,125,126,127,128,129,130,56,70,171,72,82',
+'69,397,71,80,32,33,34,224,309,271,223,216,226,84,227,228,229,84,392',
+'101,325,272,171,298,312,80,164,165,172,393,173,174,175,176,177,178,179',
+'180,149,181,101,218,79,308,369,388,32,33,34,265,266,164,165,172,73,173',
+'174,175,176,177,178,179,180,149,181,111,112,113,114,115,117,384,118',
+'32,33,34,163,78,123,124,82,440,402,122,125,126,127,128,129,130,55,219',
+'271,271,383,101,54,332,248,325,387,55,298,249,250,56,382,54,111,112',
+'113,114,115,117,56,118,56,171,331,163,395,123,124,82,276,210,122,125',
+'126,127,128,129,130,420,55,378,210,248,377,396,54,330,249,250,393,92',
+'164,165,172,56,173,174,175,176,177,178,179,180,149,181,171,9,10,11,12',
+'13,14,15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,355,356',
+'213,164,165,172,204,173,174,175,176,177,178,179,180,149,181,111,112',
+'113,114,115,117,404,118,93,378,203,163,377,123,124,82,193,271,122,125',
+'126,127,128,129,130,111,112,113,114,115,117,290,118,101,86,55,163,85',
+'123,124,82,54,291,122,125,126,127,128,129,130,56,357,171,13,14,15,16',
+'17,18,19,20,21,22,26,28,30,31,32,33,34,248,86,322,438,85,249,250,171',
+'434,435,370,164,165,172,271,173,174,175,176,177,178,179,180,149,181',
+'259,260,261,321,255,256,257,258,315,316,262,164,165,172,271,173,174',
+'175,176,177,178,179,180,149,181,111,112,113,114,115,117,403,118,317',
+'318,263,163,264,123,124,82,320,271,122,125,126,127,128,129,130,13,14',
+'15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,437,111,112,113,114,115',
+'117,360,118,400,171,271,163,368,123,124,82,166,103,122,125,126,127,128',
+'129,130,102,55,255,256,257,258,310,54,255,256,257,258,405,164,165,172',
+'56,173,174,175,176,177,178,179,180,149,181,171,9,10,11,12,13,14,15,16',
+'17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,259,260,301,164,165',
+'172,300,173,174,175,176,177,178,179,180,149,181,111,112,113,114,115',
+'117,408,118,253,254,292,163,409,123,124,82,253,254,122,125,126,127,128',
+'129,130,111,112,113,114,115,117,410,118,253,254,55,163,289,123,124,82',
+'54,288,122,125,126,127,128,129,130,56,415,171,13,14,15,16,17,18,19,20',
+'21,22,26,28,30,31,32,33,34,253,254,253,254,251,252,261,171,211,212,285',
+'164,165,172,284,173,174,175,176,177,178,179,180,149,181,237,238,239',
+'240,241,242,243,244,245,246,247,164,165,172,283,173,174,175,176,177',
+'178,179,180,149,181,111,112,113,114,115,117,282,118,251,252,389,163',
+'389,123,124,82,251,252,122,125,126,127,128,129,130,111,112,113,114,115',
+'117,101,118,67,82,55,163,64,123,124,82,54,63,122,125,126,127,128,129',
+'130,56,55,171,55,55,294,280,54,298,54,54,54,279,430,431,432,56,433,56',
+'56,56,365,436,278,263,275,264,171,273,270,48,164,165,172,444,173,174',
+'175,176,177,178,179,180,149,181,269,3,,,,,,,,,,164,165,172,,173,174',
+'175,176,177,178,179,180,149,181,111,112,113,114,115,117,,118,,,,163',
+',123,124,82,,,122,125,126,127,128,129,130,111,112,113,114,115,117,,118',
+',,,148,,123,124,,,,122,125,126,127,128,129,130,,,171,111,112,113,114',
+'115,117,,118,,,,148,,123,124,,,,122,125,126,127,128,129,130,,,,164,165',
+'172,,173,174,175,176,177,178,179,180,149,181,,,,,,,111,112,113,114,115',
+'117,,118,,411,,148,,123,124,,,149,122,125,126,127,128,129,130,,,,111',
+'112,113,114,115,117,,118,,,,148,,123,124,,,149,122,125,126,127,128,129',
+'130,111,112,113,114,115,117,,118,,,,148,,123,124,,,,122,125,126,127',
+'128,129,130,,,171,,,,,,,,,,,,,149,,111,112,113,114,115,117,,118,,,171',
+'148,,123,124,,,,122,125,126,127,128,129,130,,149,,,,,,,,111,112,113',
+'114,115,117,,118,,,,148,,123,124,146,398,149,122,125,126,127,128,129',
+'130,111,112,113,114,115,117,,118,,,,148,,123,124,,,,122,125,126,127',
+'128,129,130,111,112,113,114,115,117,,118,,149,,148,,123,124,389,,,122',
+'125,126,127,128,129,130,,,,147,,,111,112,113,114,115,117,,118,,,,148',
+'149,123,124,,,,122,125,126,127,128,129,130,111,112,113,114,115,117,',
+'118,,379,,148,149,123,124,,,,122,125,126,127,128,129,130,,,,,,,,,,,',
+',149,,,,,111,112,113,114,115,117,,118,,,,148,,123,124,,,,122,125,126',
+'127,128,129,130,,149,,,,,,,,,,,,,,,,,,,,,,,,,149,171,9,10,11,12,13,14',
+'15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,111,112,113',
+'114,115,117,,118,,,,148,,123,124,149,,,122,125,126,127,128,129,130,111',
+'112,113,114,115,117,,118,,,,148,,123,124,146,,,122,125,126,127,128,129',
+'130,111,112,113,114,115,117,,118,,,,148,,123,124,,,,122,125,126,127',
+'128,129,130,,111,112,113,114,115,117,,118,,,,148,,123,124,,,149,122',
+'125,126,127,128,129,130,,,147,,,111,112,113,114,115,117,,118,,,,148',
+'149,123,124,,,,122,125,126,127,128,129,130,111,112,113,114,115,117,',
+'118,,,,148,149,123,124,,,,122,125,126,127,128,129,130,,111,112,113,114',
+'115,117,,118,,,,148,149,123,124,,,,122,125,126,127,128,129,130,111,112',
+'113,114,115,117,,118,,,,148,,123,124,146,,149,122,125,126,127,128,129',
+'130,111,112,113,114,115,117,427,118,,,,148,,123,124,,,149,122,125,126',
+'127,128,129,130,,111,112,113,114,115,117,,118,,,,148,,123,124,,,149',
+'122,125,126,127,128,129,130,,,147,,,111,112,113,114,115,117,,118,,185',
+',148,149,123,124,,,,122,125,126,127,128,129,130,111,112,113,114,115',
+'117,,118,,,,148,149,123,124,,,,122,125,126,127,128,129,130,,111,112',
+'113,114,115,117,,118,,,,148,149,123,124,,,,122,125,126,127,128,129,130',
+'111,112,113,114,115,117,,118,,,,148,,123,124,,,149,122,125,126,127,128',
+'129,130,111,112,113,114,115,117,,118,,,,148,,123,124,,,149,122,125,126',
+'127,128,129,130,,111,112,113,114,115,117,,118,,,,148,,123,124,,,149',
+'122,125,126,127,128,129,130,111,112,113,114,115,117,,118,,,,148,,123',
+'124,,,149,122,125,126,127,128,129,130,111,112,113,114,115,117,,118,',
+',,148,,123,124,,,149,122,125,126,127,128,129,130,,111,112,113,114,115',
+'117,,118,,,,148,,123,124,,,149,122,125,126,127,128,129,130,111,112,113',
+'114,115,117,,118,,,,148,,123,124,,,149,122,125,126,127,128,129,130,111',
+'112,113,114,115,117,,118,,,,148,,123,124,,,149,122,125,126,127,128,129',
+'130,,111,112,113,114,115,117,,118,,,,148,,123,124,,,149,122,125,126',
+'127,128,129,130,111,112,113,114,115,117,,118,,,,148,,123,124,,,149,122',
+'125,126,127,128,129,130,111,112,113,114,115,117,,118,,,,148,,123,124',
+',,149,122,125,126,127,128,129,130,,111,112,113,114,115,117,,118,,,,148',
+',123,124,,,149,122,125,126,127,128,129,130,111,112,113,114,115,117,',
+'118,,,,148,,123,124,,,149,122,125,126,127,128,129,130,111,112,113,114',
+'115,117,,118,,,,148,,123,124,146,,149,122,125,126,127,128,129,130,,111',
+'112,113,114,115,117,,118,,,,148,,123,124,,,149,122,125,126,127,128,129',
+'130,,,,,,,,,,,,,,,,,,149,,,,,,,,,,147,,,111,112,113,114,115,117,,118',
+',,,148,149,123,124,,,,122,125,126,127,128,129,130,,111,112,113,114,115',
+'117,,118,,,,148,149,123,124,,,,122,125,126,127,128,129,130,,,,,,,13',
+'14,15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,,,111,112,113,114,115',
+'117,,118,,,,148,,123,124,,,149,122,125,126,127,128,129,130,,111,112',
+'113,114,115,231,,118,,,,148,,123,124,,,149,122,125,126,127,128,129,130',
+'111,112,113,114,115,233,,118,,,,148,,123,124,,,,122,125,126,127,128',
+'129,130,111,112,113,114,115,233,,118,,,,148,,123,124,,,149,122,125,126',
+'127,128,129,130,,,,,,,,,,,,,111,112,113,114,115,117,149,118,,,,148,',
+'123,124,,,,122,125,126,127,128,129,130,111,112,113,114,115,117,149,118',
+',,,148,,123,124,,,,122,125,126,127,128,129,130,,,,,,,149,13,14,15,16',
+'17,18,19,20,21,22,26,28,30,31,32,33,34,,,111,112,113,114,115,117,,118',
+',,,148,,123,124,,,149,122,125,126,127,128,129,130,111,112,113,114,115',
+'117,327,118,,,,148,,123,124,,,149,122,125,126,127,128,129,130,,,,,,',
+',13,14,15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,,,111,112,113,114',
+'115,117,,118,,,,148,,123,124,,,149,122,125,126,127,128,129,130,111,112',
+'113,114,115,117,,118,,,,148,,123,124,,,149,122,125,126,127,128,129,130',
+'111,112,113,114,115,117,,118,,,,148,,123,124,,,,122,125,126,127,128',
+'129,130,,111,112,113,114,115,117,429,118,,,,148,,123,124,,,149,122,125',
+'126,127,128,129,130,,287,,,,111,112,113,114,115,117,,118,,,,148,149',
+'123,124,146,442,,122,125,126,127,128,129,130,111,112,113,114,115,117',
+',118,,,,148,149,123,124,,,,122,125,126,127,128,129,130,,111,112,113',
+'114,115,117,,118,,,,148,149,123,124,,,,122,125,126,127,128,129,130,',
+',147,,,,,,,,,,,,,,46,149,,,,,,,,,,,,,,,,,,,,,,,,,149,,,46,,,,,,,,,,',
+',,,,,,,,,,,,149,45,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,30',
+'31,32,33,34,35,36,37,38,,,47,45,9,10,11,12,13,14,15,16,17,18,19,20,21',
+'22,26,28,30,31,32,33,34,35,36,37,38,,41,47,294,375,,298,,,54,,,,,,,',
+',56,,,,,,,,,,325,375,,298,,,,,,,,,,,,56,,,,,,,,9,10,11,12,13,14,15,16',
+'17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,9,10,11,12,13,14',
+'15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,188,,,,,192',
+',,,,,,,,,,,,,,,,,,,413,,,,,,,,,,,,,,,,,,,,,,9,10,11,12,13,14,15,16,17',
+'18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,9,10,11,12,13,14,15',
+'16,17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,371,9,10,11,12',
+'13,14,15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,,,,,',
+'205,,,,,,,,,,,,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,30,31',
+'32,33,34,35,36,37,38,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28',
+'30,31,32,33,34,35,36,37,38,307,,,,,,,,,,,,,,,,,,,,,,,,,381,,,,,,,,,',
+',,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,35,36',
+'37,38,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,30,31,32,33,34',
+'35,36,37,38,302,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,30,31',
+'32,33,34,35,36,37,38,,,,,,,,,,,,9,10,11,12,13,14,15,16,17,18,19,20,21',
+'22,26,28,30,31,32,33,34,35,36,37,38,9,10,11,12,13,14,15,16,17,18,19',
+'20,21,22,26,28,30,31,32,33,34,35,36,37,38,9,10,11,12,13,14,15,16,17',
+'18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,9,10,11,12,13,14,15',
+'16,17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,9,10,11,12,13',
+'14,15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,9,10,11',
+'12,13,14,15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37,38,9',
+'10,11,12,13,14,15,16,17,18,19,20,21,22,26,28,30,31,32,33,34,35,36,37',
+'38' ]
+        racc_action_table = arr = ::Array.new(3198, nil)
+        idx = 0
+        clist.each do |str|
+          str.split(',', -1).each do |i|
+            arr[idx] = i.to_i unless i.empty?
+            idx += 1
+          end
+        end
+
+clist = [
+'440,440,440,440,440,440,293,440,56,293,52,440,293,440,440,440,52,139',
+'440,440,440,440,440,440,440,438,438,438,438,438,438,106,438,354,326',
+'103,438,65,438,438,438,151,326,438,438,438,438,438,438,438,88,29,440',
+'31,51,29,354,31,109,56,56,56,120,207,286,120,106,120,293,120,120,120',
+'52,328,212,324,151,438,324,212,51,440,440,440,328,440,440,440,440,440',
+'440,440,440,440,440,318,110,49,207,286,318,88,88,88,142,142,438,438',
+'438,31,438,438,438,438,438,438,438,438,438,438,436,436,436,436,436,436',
+'304,436,120,120,120,436,49,436,436,436,428,362,436,436,436,436,436,436',
+'436,98,116,428,362,304,316,98,227,340,222,316,309,222,340,340,98,304',
+'309,167,167,167,167,167,167,222,167,309,436,226,167,333,167,167,167',
+'167,98,167,167,167,167,167,167,167,394,4,297,309,339,297,334,4,225,339',
+'339,394,66,436,436,436,4,436,436,436,436,436,436,436,436,436,436,167',
+'167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167',
+'167,167,167,167,167,167,167,167,267,267,101,167,167,167,95,167,167,167',
+'167,167,167,167,167,167,167,429,429,429,429,429,429,364,429,68,373,94',
+'429,373,429,429,429,87,364,429,429,429,429,429,429,429,427,427,427,427',
+'427,427,187,427,71,83,217,427,83,427,427,427,217,187,427,427,427,427',
+'427,427,427,217,269,429,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75',
+'75,75,133,53,221,426,53,133,133,427,418,418,291,429,429,429,426,429',
+'429,429,429,429,429,429,429,429,429,137,137,350,220,136,136,136,136',
+'214,214,351,427,427,427,220,427,427,427,427,427,427,427,427,427,427',
+'175,175,175,175,175,175,363,175,215,215,352,175,353,175,175,175,218',
+'363,175,175,175,175,175,175,175,76,76,76,76,76,76,76,76,76,76,76,76',
+'76,76,76,76,76,425,82,82,82,82,82,82,274,82,357,175,425,82,283,82,82',
+'82,82,73,82,82,82,82,82,82,82,72,201,347,347,347,347,209,201,348,348',
+'348,348,365,175,175,175,201,175,175,175,175,175,175,175,175,175,175',
+'82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82',
+'82,82,82,349,349,198,82,82,82,197,82,82,82,82,82,82,82,82,82,82,273',
+'273,273,273,273,273,371,273,135,135,189,273,374,273,273,273,346,346',
+'273,273,273,273,273,273,273,404,404,404,404,404,404,376,404,345,345',
+'79,404,186,404,404,404,79,184,404,404,404,404,404,404,404,79,380,273',
+'47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,344,344,343,343,342',
+'342,138,404,99,99,179,273,273,273,178,273,273,273,273,273,273,273,273',
+'273,273,131,131,131,131,131,131,131,131,131,131,131,404,404,404,177',
+'404,404,404,404,404,404,404,404,404,404,402,402,402,402,402,402,176',
+'402,341,341,395,402,396,402,402,402,134,134,402,402,402,402,402,402',
+'402,275,275,275,275,275,275,102,275,27,403,77,275,25,275,275,275,77',
+'23,275,275,275,275,275,275,275,77,55,402,152,384,191,174,55,191,152',
+'384,191,173,408,412,414,55,416,152,384,191,281,422,172,140,165,141,275',
+'163,149,3,402,402,402,437,402,402,402,402,402,402,402,402,402,402,147',
+'1,,,,,,,,,,275,275,275,,275,275,275,275,275,275,275,275,275,275,360',
+'360,360,360,360,360,,360,,,,360,,360,360,360,,,360,360,360,360,360,360',
+'360,249,249,249,249,249,249,,249,,,,249,,249,249,,,,249,249,249,249',
+'249,249,249,,,360,383,383,383,383,383,383,,383,,,,383,,383,383,,,,383',
+'383,383,383,383,383,383,,,,360,360,360,,360,360,360,360,360,360,360',
+'360,360,360,,,,,,,377,377,377,377,377,377,,377,,377,,377,,377,377,,',
+'249,377,377,377,377,377,377,377,,,,367,367,367,367,367,367,,367,,,,367',
+',367,367,,,383,367,367,367,367,367,367,367,366,366,366,366,366,366,',
+'366,,,,366,,366,366,,,,366,366,366,366,366,366,366,,,367,,,,,,,,,,,',
+',377,,393,393,393,393,393,393,,393,,,366,393,,393,393,,,,393,393,393',
+'393,393,393,393,,367,,,,,,,,356,356,356,356,356,356,,356,,,,356,,356',
+'356,356,356,366,356,356,356,356,356,356,356,330,330,330,330,330,330',
+',330,,,,330,,330,330,,,,330,330,330,330,330,330,330,322,322,322,322',
+'322,322,,322,,393,,322,,322,322,322,,,322,322,322,322,322,322,322,,',
+',356,,,310,310,310,310,310,310,,310,,,,310,356,310,310,,,,310,310,310',
+'310,310,310,310,298,298,298,298,298,298,,298,,298,,298,330,298,298,',
+',,298,298,298,298,298,298,298,,,,,,,,,,,,,322,,,,,282,282,282,282,282',
+'282,,282,,,,282,,282,282,,,,282,282,282,282,282,282,282,,310,,,,,,,',
+',,,,,,,,,,,,,,,,,298,282,282,282,282,282,282,282,282,282,282,282,282',
+'282,282,282,282,282,282,282,282,282,282,282,282,282,282,280,280,280',
+'280,280,280,,280,,,,280,,280,280,282,,,280,280,280,280,280,280,280,146',
+'146,146,146,146,146,,146,,,,146,,146,146,146,,,146,146,146,146,146,146',
+'146,278,278,278,278,278,278,,278,,,,278,,278,278,,,,278,278,278,278',
+'278,278,278,,397,397,397,397,397,397,,397,,,,397,,397,397,,,280,397',
+'397,397,397,397,397,397,,,146,,,405,405,405,405,405,405,,405,,,,405',
+'146,405,405,,,,405,405,405,405,405,405,405,271,271,271,271,271,271,',
+'271,,,,271,278,271,271,,,,271,271,271,271,271,271,271,,266,266,266,266',
+'266,266,,266,,,,266,397,266,266,,,,266,266,266,266,266,266,266,80,80',
+'80,80,80,80,,80,,,,80,,80,80,80,,405,80,80,80,80,80,80,80,406,406,406',
+'406,406,406,406,406,,,,406,,406,406,,,271,406,406,406,406,406,406,406',
+',265,265,265,265,265,265,,265,,,,265,,265,265,,,266,265,265,265,265',
+'265,265,265,,,80,,,85,85,85,85,85,85,,85,,85,,85,80,85,85,,,,85,85,85',
+'85,85,85,85,264,264,264,264,264,264,,264,,,,264,406,264,264,,,,264,264',
+'264,264,264,264,264,,263,263,263,263,263,263,,263,,,,263,265,263,263',
+',,,263,263,263,263,263,263,263,262,262,262,262,262,262,,262,,,,262,',
+'262,262,,,85,262,262,262,262,262,262,262,261,261,261,261,261,261,,261',
+',,,261,,261,261,,,264,261,261,261,261,261,261,261,,260,260,260,260,260',
+'260,,260,,,,260,,260,260,,,263,260,260,260,260,260,260,260,259,259,259',
+'259,259,259,,259,,,,259,,259,259,,,262,259,259,259,259,259,259,259,258',
+'258,258,258,258,258,,258,,,,258,,258,258,,,261,258,258,258,258,258,258',
+'258,,257,257,257,257,257,257,,257,,,,257,,257,257,,,260,257,257,257',
+'257,257,257,257,256,256,256,256,256,256,,256,,,,256,,256,256,,,259,256',
+'256,256,256,256,256,256,255,255,255,255,255,255,,255,,,,255,,255,255',
+',,258,255,255,255,255,255,255,255,,254,254,254,254,254,254,,254,,,,254',
+',254,254,,,257,254,254,254,254,254,254,254,253,253,253,253,253,253,',
+'253,,,,253,,253,253,,,256,253,253,253,253,253,253,253,252,252,252,252',
+'252,252,,252,,,,252,,252,252,,,255,252,252,252,252,252,252,252,,251',
+'251,251,251,251,251,,251,,,,251,,251,251,,,254,251,251,251,251,251,251',
+'251,250,250,250,250,250,250,,250,,,,250,,250,250,,,253,250,250,250,250',
+'250,250,250,389,389,389,389,389,389,,389,,,,389,,389,389,389,,252,389',
+'389,389,389,389,389,389,,248,248,248,248,248,248,,248,,,,248,,248,248',
+',,251,248,248,248,248,248,248,248,,,,,,,,,,,,,,,,,,250,,,,,,,,,,389',
+',,117,117,117,117,117,117,,117,,,,117,389,117,117,,,,117,117,117,117',
+'117,117,117,,236,236,236,236,236,236,,236,,,,236,248,236,236,,,,236',
+'236,236,236,236,236,236,,,,,,,117,117,117,117,117,117,117,117,117,117',
+'117,117,117,117,117,117,117,,,121,121,121,121,121,121,,121,,,,121,,121',
+'121,,,117,121,121,121,121,121,121,121,,122,122,122,122,122,122,,122',
+',,,122,,122,122,,,236,122,122,122,122,122,122,122,123,123,123,123,123',
+'123,,123,,,,123,,123,123,,,,123,123,123,123,123,123,123,124,124,124',
+'124,124,124,,124,,,,124,,124,124,,,121,124,124,124,124,124,124,124,',
+',,,,,,,,,,,233,233,233,233,233,233,122,233,,,,233,,233,233,,,,233,233',
+'233,233,233,233,233,223,223,223,223,223,223,123,223,,,,223,,223,223',
+',,,223,223,223,223,223,223,223,,,,,,,124,233,233,233,233,233,233,233',
+'233,233,233,233,233,233,233,233,233,233,,,231,231,231,231,231,231,,231',
+',,,231,,231,231,,,233,231,231,231,231,231,231,231,224,224,224,224,224',
+'224,224,224,,,,224,,224,224,,,223,224,224,224,224,224,224,224,,,,,,',
+',231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231',
+',,213,213,213,213,213,213,,213,,,,213,,213,213,,,231,213,213,213,213',
+'213,213,213,210,210,210,210,210,210,,210,,,,210,,210,210,,,224,210,210',
+'210,210,210,210,210,180,180,180,180,180,180,,180,,,,180,,180,180,,,',
+'180,180,180,180,180,180,180,,407,407,407,407,407,407,407,407,,,,407',
+',407,407,,,213,407,407,407,407,407,407,407,,180,,,,435,435,435,435,435',
+'435,,435,,,,435,210,435,435,435,435,,435,435,435,435,435,435,435,164',
+'164,164,164,164,164,,164,,,,164,180,164,164,,,,164,164,164,164,164,164',
+'164,,279,279,279,279,279,279,,279,,,,279,407,279,279,,,,279,279,279',
+'279,279,279,279,,,435,,,,,,,,,,,,,,41,435,,,,,,,,,,,,,,,,,,,,,,,,,164',
+',,2,,,,,,,,,,,,,,,,,,,,,,,279,41,41,41,41,41,41,41,41,41,41,41,41,41',
+'41,41,41,41,41,41,41,41,41,41,41,41,41,,,41,2,2,2,2,2,2,2,2,2,2,2,2',
+'2,2,2,2,2,2,2,2,2,2,2,2,2,2,,2,2,294,294,,294,,,294,,,,,,,,,294,,,,',
+',,,,,325,325,,325,,,,,,,,,,,,325,,,,,,,,294,294,294,294,294,294,294',
+'294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294',
+'294,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325',
+'325,325,325,325,325,325,325,325,325,86,,,,,86,,,,,,,,,,,,,,,,,,,,378',
+',,,,,,,,,,,,,,,,,,,,,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86',
+'86,86,86,86,86,86,86,86,86,378,378,378,378,378,378,378,378,378,378,378',
+'378,378,378,378,378,378,378,378,378,378,378,378,378,378,292,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,,,,,,96,,,,,,,,,,,,292,292',
+'292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292',
+'292,292,292,292,292,292,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96',
+'96,96,96,96,96,96,96,96,96,96,202,,,,,,,,,,,,,,,,,,,,,,,,,299,,,,,,',
+',,,,,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202',
+'202,202,202,202,202,202,202,202,202,299,299,299,299,299,299,299,299',
+'299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299',
+'199,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92',
+'92,92,92,,,,,,,,,,,,199,199,199,199,199,199,199,199,199,199,199,199',
+'199,199,199,199,199,199,199,199,199,199,199,199,199,8,8,8,8,8,8,8,8',
+'8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,196,196,196,196,196,196,196,196,196',
+'196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,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,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,93,93,93,93,93,93,93,93,93,93,93,93,93,93',
+'93,93,93,93,93,93,93,93,93,93,93,69,69,69,69,69,69,69,69,69,69,69,69',
+'69,69,69,69,69,69,69,69,69,69,69,69,69' ]
+        racc_action_check = arr = ::Array.new(3198, nil)
+        idx = 0
+        clist.each do |str|
+          str.split(',', -1).each do |i|
+            arr[idx] = i.to_i unless i.empty?
+            idx += 1
+          end
+        end
+
+racc_action_pointer = [
+   nil,   732,  2528,   716,   182,  3068,  3043,  2752,  2993,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   624,   nil,   619,   nil,   656,   nil,    38,
+   nil,    40,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,  2499,   nil,   nil,   nil,   nil,   nil,   510,   nil,    78,
+   nil,    37,     3,   322,   nil,   680,   -14,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,    20,   183,   nil,   249,  3118,
+   nil,   278,   429,   421,   nil,   252,   344,   664,   nil,   544,
+  1392,   nil,   419,   285,   nil,  1473,  2701,   266,    28,   nil,
+   nil,   nil,  2932,  3093,   214,   193,  2819,   nil,   138,   576,
+   nil,   200,   654,    22,   nil,   nil,    12,   nil,   nil,    15,
+     1,   nil,   nil,   nil,   nil,   nil,   137,  1959,   nil,   nil,
+    55,  2035,  2061,  2086,  2111,   nil,   nil,   nil,   nil,   nil,
+   nil,   568,   nil,   306,   629,   495,   326,   318,   571,   -20,
+   672,   673,    64,   nil,   nil,   nil,  1235,   724,   nil,   702,
+   nil,    22,   682,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   672,  2431,   669,   nil,   161,   nil,   nil,
+   nil,   nil,   702,   691,   685,   376,   635,   612,   546,   542,
+  2350,   nil,   nil,   nil,   547,   nil,   545,   281,   nil,   507,
+   nil,   684,   nil,   nil,   nil,   nil,  3018,   451,   447,  2968,
+   nil,   440,  2881,   nil,   nil,   nil,   nil,    44,   nil,   410,
+  2325,   nil,    61,  2300,   343,   368,   nil,   286,   381,   nil,
+   348,   322,   147,  2173,  2249,   189,   160,   139,   nil,   nil,
+   nil,  2224,   nil,  2148,   nil,   nil,  1985,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,  1904,   779,
+  1853,  1828,  1802,  1777,  1752,  1726,  1701,  1676,  1650,  1625,
+  1600,  1574,  1549,  1524,  1498,  1443,  1367,   223,   nil,   300,
+   nil,  1341,   nil,   514,   385,   659,   nil,   nil,  1260,  2457,
+  1210,   619,  1132,   379,   nil,   nil,    45,   nil,   nil,   nil,
+   nil,   325,  2794,    -1,  2604,   nil,   nil,   183,  1090,  2906,
+   nil,   nil,   nil,   nil,   107,   nil,   nil,   nil,   nil,   149,
+  1065,   nil,   nil,   nil,   nil,   nil,   137,   nil,    82,   nil,
+   nil,   nil,  1034,   nil,    68,  2629,    23,   nil,    65,   nil,
+  1009,   nil,   nil,   167,   186,   nil,   nil,   nil,   nil,   170,
+   131,   621,   567,   559,   557,   520,   503,   417,   423,   464,
+   334,   326,   350,   351,    14,   nil,   984,   421,   nil,   nil,
+   754,   nil,   129,   376,   256,   451,   908,   883,   nil,   nil,
+   nil,   510,   nil,   260,   520,   nil,   539,   855,  2726,   nil,
+   556,   nil,   nil,   807,   683,   nil,   nil,   nil,   nil,  1878,
+   nil,   nil,   nil,   950,   180,   629,   631,  1286,   nil,   nil,
+   nil,   nil,   634,   653,   539,  1316,  1417,  2376,   687,   nil,
+   nil,   nil,   689,   nil,   693,   nil,   649,   nil,   318,   nil,
+   nil,   nil,   622,   nil,   nil,   412,   323,   281,   128,   256,
+   nil,   nil,   nil,   nil,   nil,  2406,   118,   666,    23,   nil,
+    -2,   nil,   nil,   nil,   nil,   nil,   nil ]
+
+racc_action_default = [
+  -215,  -269,    -1,  -269,  -269,   -86,   -88,   -90,   -92,   -98,
+   -99,  -100,  -101,  -102,  -103,  -104,  -105,  -106,  -107,  -108,
+  -109,  -110,  -111,  -112,  -113,  -114,  -115,  -118,  -121,  -269,
+  -139,  -269,  -163,  -164,  -165,  -166,  -167,  -168,  -169,  -216,
+  -217,  -269,  -219,  -220,  -223,  -224,  -225,  -269,   447,  -269,
+   -94,   -96,  -269,  -171,  -173,  -269,  -180,   -87,  -112,  -114,
+   -89,   -91,   -93,  -222,  -221,  -120,  -269,  -124,  -138,  -269,
+  -142,  -269,  -155,  -158,  -218,  -130,  -132,  -269,   -85,  -269,
+  -269,  -229,  -269,  -170,  -172,  -269,  -269,  -269,  -181,  -182,
+  -184,  -116,  -269,  -269,  -112,  -113,  -269,  -140,  -269,  -269,
+  -159,  -161,  -269,  -269,  -129,  -131,  -269,  -227,   -95,   -96,
+    -2,    -3,    -4,    -5,    -6,    -7,    -8,  -269,   -10,   -12,
+   -25,  -269,  -269,  -269,  -269,   -31,   -32,   -33,   -34,   -35,
+   -36,   -37,   -39,   -43,   -46,   -49,   -54,   -57,   -59,   -61,
+   -63,   -65,   -67,   -69,   -97,  -209,  -269,  -269,  -265,  -269,
+   -82,  -269,  -269,  -230,  -231,  -232,  -233,  -234,  -235,  -236,
+  -237,  -238,  -239,  -265,  -269,  -269,  -243,  -269,  -245,  -247,
+  -248,  -249,  -269,  -269,  -269,  -269,  -269,  -269,  -269,  -269,
+  -269,  -268,   -37,   -84,  -269,  -176,  -269,  -269,  -179,  -186,
+  -188,  -192,  -193,  -174,  -183,  -185,  -269,  -112,  -113,  -269,
+  -122,  -269,  -269,  -145,  -144,  -137,  -141,  -269,  -146,  -148,
+  -269,  -151,  -269,  -269,  -269,  -269,  -226,  -269,  -269,   -11,
+  -269,  -269,  -195,  -269,  -269,  -269,  -269,  -269,   -19,   -20,
+   -26,  -269,   -27,  -269,   -29,   -30,  -269,   -71,   -72,   -73,
+   -74,   -75,   -76,   -77,   -78,   -79,   -80,   -81,  -269,  -269,
+  -269,  -269,  -269,  -269,  -269,  -269,  -269,  -269,  -269,  -269,
+  -269,  -269,  -269,  -269,  -269,  -269,  -269,  -269,  -213,  -269,
+  -266,  -269,  -250,  -269,  -269,  -269,  -244,  -246,  -269,  -269,
+  -269,  -269,  -269,  -269,  -261,  -262,  -269,  -263,  -175,  -177,
+  -178,  -269,  -269,  -197,  -269,  -190,  -191,  -198,  -269,  -269,
+  -128,  -127,  -119,  -123,  -269,  -133,  -135,  -136,  -143,  -269,
+  -269,  -149,  -153,  -160,  -162,  -152,  -269,  -156,  -269,  -228,
+  -267,    -9,  -269,  -196,  -197,  -269,  -269,   -14,  -269,   -23,
+  -269,   -17,   -18,  -269,  -269,   -70,   -40,   -41,   -42,   -44,
+   -45,   -47,   -48,   -50,   -51,   -52,   -53,   -55,   -56,   -58,
+   -60,   -62,   -64,   -66,  -269,  -210,  -269,  -269,   -83,  -240,
+  -269,  -242,  -269,  -269,  -269,  -269,  -269,  -269,  -260,  -264,
+  -194,  -269,  -189,  -199,  -269,  -205,  -269,  -269,  -269,  -201,
+  -269,  -117,  -125,  -269,  -269,  -147,  -150,  -154,  -157,  -269,
+   -38,   -13,   -15,  -269,  -269,   -28,  -269,  -269,  -211,  -214,
+  -212,  -241,  -269,  -269,  -269,  -269,  -269,  -269,  -269,  -200,
+  -206,  -203,  -269,  -207,  -269,  -202,  -269,  -134,  -269,   -24,
+   -16,   -68,  -251,  -253,  -254,  -269,  -269,  -269,  -269,  -269,
+  -187,  -204,  -208,  -126,   -21,  -269,  -269,  -269,  -269,  -256,
+  -269,  -258,   -22,  -252,  -255,  -257,  -259 ]
+
+racc_goto_table = [
+    51,   144,   145,    81,   183,   182,   184,   281,   186,    23,
+   267,    95,   208,    83,   206,   305,   303,   313,   328,   169,
+    25,     4,   199,   230,    57,    60,    61,    62,    75,    89,
+    40,    99,   168,   221,   198,    95,   296,    77,    95,   220,
+   373,   182,   232,   234,   235,    65,    96,   207,    23,    76,
+   304,   366,   343,   344,   345,   346,    75,    75,    90,    25,
+     4,   194,   214,   215,    66,   104,   105,   323,   145,    74,
+   202,   373,   196,   107,    68,   109,    94,    76,    76,   347,
+   348,   339,   340,   183,   182,   274,   341,   342,    98,   108,
+   195,   236,   187,    88,   209,   372,   353,   352,    75,   197,
+    94,   152,   286,    94,   169,   359,    39,   361,   351,   106,
+   350,   201,    98,   349,     2,    98,   303,   277,   167,    76,
+   206,   313,   225,   313,   394,     1,   299,   nil,   nil,   183,
+   182,   311,   183,   182,   314,   406,   407,   nil,   198,   nil,
+   nil,   198,   nil,   nil,    95,   326,   329,   333,   109,   334,
+   336,   337,   338,   220,   nil,   220,   nil,   nil,   335,   nil,
+   nil,   nil,   nil,   nil,   293,   nil,   nil,   nil,   182,   182,
+   182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
+   182,   182,   182,   182,   182,   182,   152,   295,   354,   nil,
+   nil,   nil,   401,   358,   nil,   324,   nil,   306,   417,   nil,
+   362,   363,   364,   197,   nil,   nil,   197,   nil,   nil,    94,
+   nil,   nil,    75,   319,    75,   201,   nil,   nil,   201,   367,
+   380,    98,   nil,   385,   390,   nil,   nil,   nil,   nil,   183,
+   182,   386,   nil,    76,   422,    76,   424,   nil,   nil,   nil,
+   nil,   198,   182,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   329,   418,    83,   nil,   nil,   nil,   nil,   439,
+   nil,   441,   nil,   nil,   nil,   nil,   nil,   293,   443,   nil,
+   445,   nil,   446,   nil,   nil,   nil,   nil,   399,   145,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   324,   412,
+   414,   152,   183,   182,   416,   209,   197,   nil,   nil,   nil,
+   nil,   145,   nil,   nil,   nil,   419,   421,   182,   201,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   425,   426,   428,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   423,   399,   145,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   306 ]
+
+racc_goto_check = [
+    36,    37,    12,    72,    26,    13,    28,    73,    60,    38,
+    11,    39,    55,    59,    53,    49,    46,    57,     8,    29,
+    40,    30,    43,    15,    30,    30,    30,    30,    33,    58,
+    68,    56,    84,    10,    39,    39,    65,    48,    39,     6,
+    66,    13,    13,    13,    13,    42,    52,    54,    38,     9,
+    47,    75,    18,    18,    18,    18,    33,    33,     9,    40,
+    30,    58,    56,    56,    45,    48,    48,    65,    12,    68,
+    52,    66,    44,    36,    51,    36,    38,     9,     9,    19,
+    19,    16,    16,    26,    13,    28,    17,    17,    30,    35,
+     9,    27,    61,    62,    36,    64,    24,    23,    33,    38,
+    38,    30,     6,    38,    29,    73,    67,    73,    22,    71,
+    21,    30,    30,    20,     2,    30,    46,    84,    83,     9,
+    53,    57,     9,    57,     8,     1,    43,   nil,   nil,    26,
+    13,    28,    26,    13,    28,    75,    75,   nil,    39,   nil,
+   nil,    39,   nil,   nil,    39,     6,    12,    10,    36,    10,
+    15,    15,    15,     6,   nil,     6,   nil,   nil,    12,   nil,
+   nil,   nil,   nil,   nil,    58,   nil,   nil,   nil,    13,    13,
+    13,    13,    13,    13,    13,    13,    13,    13,    13,    13,
+    13,    13,    13,    13,    13,    13,    30,    36,     6,   nil,
+   nil,   nil,    73,    12,   nil,    58,   nil,    36,    49,   nil,
+     6,     6,     6,    38,   nil,   nil,    38,   nil,   nil,    38,
+   nil,   nil,    33,    36,    33,    30,   nil,   nil,    30,    29,
+    12,    30,   nil,    55,    15,   nil,   nil,   nil,   nil,    26,
+    13,    28,   nil,     9,    73,     9,    73,   nil,   nil,   nil,
+   nil,    39,    13,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,    12,    11,    59,   nil,   nil,   nil,   nil,    73,
+   nil,    73,   nil,   nil,   nil,   nil,   nil,    58,    73,   nil,
+    73,   nil,    73,   nil,   nil,   nil,   nil,    37,    12,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,    58,    12,
+    60,    30,    26,    13,    28,    36,    38,   nil,   nil,   nil,
+   nil,    12,   nil,   nil,   nil,    12,    26,    13,    30,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,     6,     6,     6,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,    72,    37,    12,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+    36 ]
+
+racc_goto_pointer = [
+   nil,   125,   114,   nil,   nil,   nil,   -78,   nil,  -206,     2,
+   -84,  -136,   -78,   -80,   nil,   -98,  -170,  -167,  -203,  -180,
+  -148,  -152,  -155,  -167,  -169,   nil,   -81,   -40,   -79,   -63,
+    19,   nil,   nil,   -19,   nil,    10,    -4,   -79,     7,   -58,
+    18,   nil,    18,   -70,   -19,    37,  -183,  -151,   -10,  -186,
+   nil,    45,   -23,   -82,   -51,   -86,   -40,  -195,   -27,   -39,
+   -78,     6,    37,   nil,  -197,  -155,  -253,   104,    28,   nil,
+   nil,    32,   -48,  -168,   nil,  -231,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,    36,   -50 ]
+
+racc_goto_default = [
+   nil,   nil,   nil,   119,   110,   116,   151,   120,   nil,     7,
+   nil,   nil,   150,   131,   121,   132,   133,   134,   135,   136,
+   137,   138,   139,   140,   141,   142,   143,   nil,   nil,    44,
+   191,    49,     5,     6,     8,    50,    87,   268,    58,    24,
+    59,    27,   nil,   nil,   nil,   nil,   200,   nil,   222,   nil,
+    29,   nil,   nil,    97,   nil,   nil,   nil,   100,    52,    53,
+   376,   nil,   nil,   189,   190,   374,   297,   nil,   nil,    42,
+    43,   nil,   154,   170,   153,   155,   156,   157,   158,   159,
+   160,   161,   162,   nil,   nil ]
+
+racc_reduce_table = [
+  0, 0, :racc_error,
+  1, 98, :_reduce_none,
+  1, 100, :_reduce_2,
+  1, 100, :_reduce_3,
+  1, 100, :_reduce_4,
+  1, 100, :_reduce_5,
+  1, 100, :_reduce_6,
+  1, 100, :_reduce_7,
+  1, 100, :_reduce_8,
+  3, 100, :_reduce_9,
+  1, 102, :_reduce_10,
+  2, 102, :_reduce_11,
+  1, 104, :_reduce_none,
+  4, 104, :_reduce_13,
+  3, 104, :_reduce_none,
+  4, 104, :_reduce_none,
+  5, 104, :_reduce_none,
+  3, 104, :_reduce_17,
+  3, 104, :_reduce_18,
+  2, 104, :_reduce_19,
+  2, 104, :_reduce_20,
+  6, 104, :_reduce_none,
+  7, 104, :_reduce_none,
+  1, 105, :_reduce_none,
+  3, 105, :_reduce_none,
+  1, 110, :_reduce_none,
+  2, 110, :_reduce_26,
+  2, 110, :_reduce_27,
+  4, 110, :_reduce_28,
+  2, 110, :_reduce_29,
+  2, 110, :_reduce_30,
+  1, 111, :_reduce_31,
+  1, 111, :_reduce_32,
+  1, 111, :_reduce_33,
+  1, 111, :_reduce_34,
+  1, 111, :_reduce_35,
+  1, 111, :_reduce_36,
+  1, 112, :_reduce_none,
+  4, 112, :_reduce_38,
+  1, 113, :_reduce_none,
+  3, 113, :_reduce_40,
+  3, 113, :_reduce_41,
+  3, 113, :_reduce_42,
+  1, 114, :_reduce_none,
+  3, 114, :_reduce_44,
+  3, 114, :_reduce_45,
+  1, 115, :_reduce_none,
+  3, 115, :_reduce_47,
+  3, 115, :_reduce_48,
+  1, 116, :_reduce_none,
+  3, 116, :_reduce_50,
+  3, 116, :_reduce_51,
+  3, 116, :_reduce_52,
+  3, 116, :_reduce_53,
+  1, 117, :_reduce_none,
+  3, 117, :_reduce_55,
+  3, 117, :_reduce_56,
+  1, 118, :_reduce_none,
+  3, 118, :_reduce_58,
+  1, 119, :_reduce_none,
+  3, 119, :_reduce_60,
+  1, 120, :_reduce_none,
+  3, 120, :_reduce_62,
+  1, 121, :_reduce_none,
+  3, 121, :_reduce_64,
+  1, 122, :_reduce_none,
+  3, 122, :_reduce_66,
+  1, 123, :_reduce_none,
+  5, 123, :_reduce_68,
+  1, 109, :_reduce_none,
+  3, 109, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 124, :_reduce_none,
+  1, 103, :_reduce_82,
+  3, 103, :_reduce_83,
+  1, 125, :_reduce_84,
+  3, 126, :_reduce_none,
+  1, 127, :_reduce_86,
+  2, 127, :_reduce_87,
+  1, 127, :_reduce_none,
+  2, 127, :_reduce_89,
+  1, 127, :_reduce_90,
+  2, 127, :_reduce_91,
+  1, 127, :_reduce_none,
+  2, 127, :_reduce_none,
+  1, 128, :_reduce_94,
+  3, 128, :_reduce_95,
+  1, 132, :_reduce_none,
+  3, 132, :_reduce_97,
+  1, 129, :_reduce_none,
+  1, 129, :_reduce_none,
+  1, 129, :_reduce_none,
+  1, 129, :_reduce_none,
+  1, 130, :_reduce_102,
+  1, 130, :_reduce_103,
+  1, 130, :_reduce_104,
+  1, 130, :_reduce_105,
+  1, 130, :_reduce_106,
+  1, 130, :_reduce_107,
+  1, 130, :_reduce_108,
+  1, 130, :_reduce_109,
+  1, 130, :_reduce_110,
+  1, 130, :_reduce_111,
+  1, 130, :_reduce_112,
+  1, 130, :_reduce_113,
+  1, 130, :_reduce_114,
+  1, 130, :_reduce_115,
+  0, 141, :_reduce_116,
+  6, 135, :_reduce_117,
+  0, 142, :_reduce_118,
+  5, 135, :_reduce_119,
+  2, 135, :_reduce_120,
+  1, 138, :_reduce_121,
+  1, 140, :_reduce_none,
+  2, 140, :_reduce_none,
+  1, 139, :_reduce_124,
+  3, 143, :_reduce_125,
+  5, 143, :_reduce_126,
+  2, 143, :_reduce_none,
+  2, 143, :_reduce_none,
+  2, 145, :_reduce_129,
+  1, 145, :_reduce_none,
+  2, 145, :_reduce_131,
+  1, 145, :_reduce_132,
+  1, 144, :_reduce_133,
+  3, 144, :_reduce_134,
+  1, 146, :_reduce_none,
+  5, 136, :_reduce_none,
+  4, 136, :_reduce_none,
+  2, 136, :_reduce_none,
+  1, 147, :_reduce_139,
+  1, 149, :_reduce_none,
+  2, 149, :_reduce_none,
+  1, 148, :_reduce_none,
+  3, 150, :_reduce_none,
+  2, 150, :_reduce_none,
+  2, 150, :_reduce_none,
+  1, 151, :_reduce_none,
+  3, 151, :_reduce_none,
+  1, 152, :_reduce_none,
+  2, 152, :_reduce_none,
+  3, 152, :_reduce_none,
+  4, 137, :_reduce_none,
+  5, 137, :_reduce_none,
+  5, 137, :_reduce_none,
+  6, 137, :_reduce_none,
+  2, 137, :_reduce_none,
+  5, 137, :_reduce_none,
+  6, 137, :_reduce_none,
+  2, 137, :_reduce_none,
+  1, 153, :_reduce_none,
+  3, 153, :_reduce_none,
+  1, 154, :_reduce_none,
+  3, 154, :_reduce_none,
+  1, 106, :_reduce_163,
+  1, 106, :_reduce_none,
+  1, 106, :_reduce_165,
+  1, 131, :_reduce_none,
+  1, 131, :_reduce_none,
+  1, 131, :_reduce_none,
+  1, 131, :_reduce_none,
+  2, 133, :_reduce_170,
+  1, 133, :_reduce_none,
+  2, 133, :_reduce_172,
+  1, 156, :_reduce_173,
+  3, 156, :_reduce_174,
+  4, 156, :_reduce_175,
+  3, 156, :_reduce_176,
+  4, 156, :_reduce_177,
+  4, 156, :_reduce_none,
+  3, 156, :_reduce_179,
+  1, 155, :_reduce_180,
+  2, 155, :_reduce_181,
+  2, 155, :_reduce_182,
+  3, 155, :_reduce_183,
+  1, 159, :_reduce_none,
+  2, 159, :_reduce_none,
+  1, 157, :_reduce_none,
+  5, 157, :_reduce_none,
+  1, 160, :_reduce_none,
+  3, 160, :_reduce_none,
+  2, 161, :_reduce_none,
+  2, 161, :_reduce_none,
+  1, 161, :_reduce_none,
+  1, 158, :_reduce_none,
+  3, 158, :_reduce_none,
+  1, 107, :_reduce_none,
+  2, 107, :_reduce_none,
+  1, 162, :_reduce_none,
+  1, 162, :_reduce_none,
+  2, 162, :_reduce_none,
+  3, 163, :_reduce_none,
+  2, 163, :_reduce_none,
+  3, 163, :_reduce_none,
+  3, 163, :_reduce_none,
+  4, 163, :_reduce_none,
+  2, 163, :_reduce_205,
+  3, 163, :_reduce_none,
+  3, 163, :_reduce_207,
+  4, 163, :_reduce_none,
+  1, 134, :_reduce_209,
+  3, 134, :_reduce_210,
+  4, 134, :_reduce_211,
+  4, 134, :_reduce_212,
+  1, 108, :_reduce_213,
+  3, 108, :_reduce_214,
+  0, 99, :_reduce_none,
+  2, 99, :_reduce_none,
+  1, 164, :_reduce_none,
+  2, 164, :_reduce_none,
+  1, 165, :_reduce_none,
+  1, 165, :_reduce_none,
+  2, 165, :_reduce_none,
+  2, 165, :_reduce_none,
+  1, 165, :_reduce_none,
+  1, 165, :_reduce_none,
+  1, 165, :_reduce_none,
+  4, 166, :_reduce_226,
+  1, 168, :_reduce_227,
+  3, 168, :_reduce_228,
+  3, 167, :_reduce_none,
+  1, 170, :_reduce_none,
+  1, 170, :_reduce_none,
+  1, 170, :_reduce_none,
+  1, 170, :_reduce_none,
+  1, 170, :_reduce_none,
+  1, 170, :_reduce_none,
+  1, 170, :_reduce_none,
+  1, 170, :_reduce_none,
+  1, 170, :_reduce_none,
+  1, 170, :_reduce_none,
+  3, 171, :_reduce_none,
+  4, 171, :_reduce_none,
+  3, 171, :_reduce_none,
+  2, 169, :_reduce_none,
+  3, 169, :_reduce_none,
+  1, 180, :_reduce_none,
+  2, 180, :_reduce_none,
+  1, 181, :_reduce_none,
+  1, 181, :_reduce_none,
+  1, 172, :_reduce_none,
+  2, 172, :_reduce_none,
+  5, 173, :_reduce_none,
+  7, 173, :_reduce_none,
+  5, 177, :_reduce_none,
+  5, 174, :_reduce_none,
+  7, 175, :_reduce_none,
+  6, 176, :_reduce_none,
+  7, 176, :_reduce_none,
+  6, 176, :_reduce_none,
+  7, 176, :_reduce_none,
+  3, 178, :_reduce_none,
+  2, 178, :_reduce_none,
+  2, 178, :_reduce_none,
+  2, 178, :_reduce_none,
+  3, 178, :_reduce_none,
+  1, 101, :_reduce_265,
+  2, 101, :_reduce_266,
+  3, 101, :_reduce_267,
+  1, 179, :_reduce_268 ]
+
+racc_reduce_n = 269
+
+racc_shift_n = 447
+
+racc_token_table = {
+  false => 0,
+  :error => 1,
+  :INTEGER_CONSTANT => 2,
+  :FLOATING_CONSTANT => 3,
+  :OCTAL_CONSTANT => 4,
+  :HEX_CONSTANT => 5,
+  :CHARACTER_LITERAL => 6,
+  "(" => 7,
+  ")" => 8,
+  :STRING_LITERAL => 9,
+  "[" => 10,
+  "]" => 11,
+  "." => 12,
+  :IDENTIFIER => 13,
+  "->" => 14,
+  "++" => 15,
+  "--" => 16,
+  "{" => 17,
+  "}" => 18,
+  "," => 19,
+  :SIZEOF => 20,
+  "&" => 21,
+  "*" => 22,
+  "+" => 23,
+  "-" => 24,
+  "~" => 25,
+  "!" => 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,
+  "|=" => 52,
+  "^=" => 53,
+  ";" => 54,
+  :EXTERN => 55,
+  :STATIC => 56,
+  :AUTO => 57,
+  :REGISTER => 58,
+  :VOID => 59,
+  :CHAR => 60,
+  :SHORT => 61,
+  :INT => 62,
+  :LONG => 63,
+  :FLOAT => 64,
+  :DOUBLE => 65,
+  :SIGNED => 66,
+  :UNSIGNED => 67,
+  :BOOL => 68,
+  :TYPE_NAME => 69,
+  :STRUCT => 70,
+  :UNION => 71,
+  :ENUM => 72,
+  :CONST => 73,
+  :RESTRICT => 74,
+  :VOLATILE => 75,
+  :__INLINE__ => 76,
+  :INLINE => 77,
+  :__INLINE => 78,
+  :CINLINE => 79,
+  :C_EXP => 80,
+  :EXTENSION => 81,
+  :TYPEDEF => 82,
+  :CASE => 83,
+  :DEFAULT => 84,
+  :IF => 85,
+  :ELSE => 86,
+  :SWITCH => 87,
+  :WHILE => 88,
+  :DO => 89,
+  :FOR => 90,
+  :GOTO => 91,
+  :CONTINUE => 92,
+  :BREAK => 93,
+  :RETURN => 94,
+  "::" => 95,
+  :_ASM => 96 }
+
+racc_nt_base = 97
+
+racc_use_result_var = true
+
+Racc_arg = [
+  racc_action_table,
+  racc_action_check,
+  racc_action_default,
+  racc_action_pointer,
+  racc_goto_table,
+  racc_goto_check,
+  racc_goto_default,
+  racc_goto_pointer,
+  racc_nt_base,
+  racc_reduce_table,
+  racc_token_table,
+  racc_shift_n,
+  racc_reduce_n,
+  racc_use_result_var ]
+
+Racc_token_to_s_table = [
+  "$end",
+  "error",
+  "INTEGER_CONSTANT",
+  "FLOATING_CONSTANT",
+  "OCTAL_CONSTANT",
+  "HEX_CONSTANT",
+  "CHARACTER_LITERAL",
+  "\"(\"",
+  "\")\"",
+  "STRING_LITERAL",
+  "\"[\"",
+  "\"]\"",
+  "\".\"",
+  "IDENTIFIER",
+  "\"->\"",
+  "\"++\"",
+  "\"--\"",
+  "\"{\"",
+  "\"}\"",
+  "\",\"",
+  "SIZEOF",
+  "\"&\"",
+  "\"*\"",
+  "\"+\"",
+  "\"-\"",
+  "\"~\"",
+  "\"!\"",
+  "\"/\"",
+  "\"%\"",
+  "\"<<\"",
+  "\">>\"",
+  "\"<\"",
+  "\">\"",
+  "\"<=\"",
+  "\">=\"",
+  "\"==\"",
+  "\"!=\"",
+  "\"^\"",
+  "\"|\"",
+  "\"&&\"",
+  "\"||\"",
+  "\"?\"",
+  "\":\"",
+  "\"=\"",
+  "\"+=\"",
+  "\"-=\"",
+  "\"*=\"",
+  "\"/=\"",
+  "\"%=\"",
+  "\"<<=\"",
+  "\">>=\"",
+  "\"&=\"",
+  "\"|=\"",
+  "\"^=\"",
+  "\";\"",
+  "EXTERN",
+  "STATIC",
+  "AUTO",
+  "REGISTER",
+  "VOID",
+  "CHAR",
+  "SHORT",
+  "INT",
+  "LONG",
+  "FLOAT",
+  "DOUBLE",
+  "SIGNED",
+  "UNSIGNED",
+  "BOOL",
+  "TYPE_NAME",
+  "STRUCT",
+  "UNION",
+  "ENUM",
+  "CONST",
+  "RESTRICT",
+  "VOLATILE",
+  "__INLINE__",
+  "INLINE",
+  "__INLINE",
+  "CINLINE",
+  "C_EXP",
+  "EXTENSION",
+  "TYPEDEF",
+  "CASE",
+  "DEFAULT",
+  "IF",
+  "ELSE",
+  "SWITCH",
+  "WHILE",
+  "DO",
+  "FOR",
+  "GOTO",
+  "CONTINUE",
+  "BREAK",
+  "RETURN",
+  "\"::\"",
+  "_ASM",
+  "$start",
+  "all",
+  "C_parser",
+  "primary_expression",
+  "namespace_identifier",
+  "string_literal_list",
+  "expression",
+  "postfix_expression",
+  "argument_expression_list",
+  "type_qualifier",
+  "type_name",
+  "initializer_list",
+  "assignment_expression",
+  "unary_expression",
+  "unary_operator",
+  "cast_expression",
+  "multiplicative_expression",
+  "additive_expression",
+  "shift_expression",
+  "relational_expression",
+  "equality_expression",
+  "and_expression",
+  "exclusive_or_expression",
+  "inclusive_or_expression",
+  "logical_and_expression",
+  "logical_or_expression",
+  "conditional_expression",
+  "assignment_operator",
+  "constant_expression",
+  "declaration",
+  "declaration_specifiers",
+  "init_declarator_list",
+  "storage_class_specifier",
+  "type_specifier",
+  "function_specifier",
+  "init_declarator",
+  "declarator",
+  "initializer",
+  "struct_specifier",
+  "union_specifier",
+  "enum_specifier",
+  "struct_term",
+  "struct_tag",
+  "struct_declaration_list",
+  "@1",
+  "@2",
+  "struct_declaration",
+  "struct_declarator_list",
+  "specifier_qualifier_list",
+  "struct_declarator",
+  "union_term",
+  "union_tag",
+  "union_declaration_list",
+  "union_declaration",
+  "union_declarator_list",
+  "union_declarator",
+  "enumerator_list",
+  "enumerator",
+  "pointer",
+  "direct_declarator",
+  "parameter_type_list",
+  "identifier_list",
+  "type_qualifier_list",
+  "parameter_list",
+  "parameter_declaration",
+  "abstract_declarator",
+  "direct_abstract_declarator",
+  "extension_statement",
+  "cdl_statement",
+  "typedef",
+  "func_def",
+  "declarator_list",
+  "compound_statement",
+  "statement",
+  "labeled_statement",
+  "expression_statement",
+  "ifstatement",
+  "whilestatement",
+  "dowhilestatement",
+  "forstatement",
+  "switchstatement",
+  "jump_statement",
+  "asm_statement",
+  "block_item_list",
+  "block_item" ]
+
+Racc_debug_parser = false
+
+##### State transition tables end #####
+
+# reduce 0 omitted
+
+# reduce 1 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 57)
+  def _reduce_2(val, _values, result)
+     result = [ :IDENTIFIER, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 65)
+  def _reduce_3(val, _values, result)
+     result = [ :INTEGER_CONSTANT, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 67)
+  def _reduce_4(val, _values, result)
+     result = [ :FLOATING_CONSTANT, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 69)
+  def _reduce_5(val, _values, result)
+     result = [ :OCTAL_CONSTANT, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 71)
+  def _reduce_6(val, _values, result)
+     result = [ :HEX_CONSTANT, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 73)
+  def _reduce_7(val, _values, result)
+     result = [ :CHARACTER_LITERAL, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 75)
+  def _reduce_8(val, _values, result)
+     result = [ :STRING_LITERAL_LIST, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 77)
+  def _reduce_9(val, _values, result)
+     result = [ :PARENTHESES, val[1].get_elements ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 81)
+  def _reduce_10(val, _values, result)
+     result = [val[0]] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 83)
+  def _reduce_11(val, _values, result)
+     result << val[1] 
+    result
+  end
+.,.,
+
+# reduce 12 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 89)
+  def _reduce_13(val, _values, result)
+     result = [ :OP_SUBSC, val[0], val[2] ] 
+    result
+  end
+.,.,
+
+# reduce 14 omitted
+
+# reduce 15 omitted
+
+# reduce 16 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 94)
+  def _reduce_17(val, _values, result)
+     result = [ :OP_DOT, val[0], val[2] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 96)
+  def _reduce_18(val, _values, result)
+     result = [ :OP_REF, val[0], val[2] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 97)
+  def _reduce_19(val, _values, result)
+     result = val[0] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 98)
+  def _reduce_20(val, _values, result)
+     result = val[0] 
+    result
+  end
+.,.,
+
+# reduce 21 omitted
+
+# reduce 22 omitted
+
+# reduce 23 omitted
+
+# reduce 24 omitted
+
+# reduce 25 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 111)
+  def _reduce_26(val, _values, result)
+     result = [ val[0], val[1] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 113)
+  def _reduce_27(val, _values, result)
+     result = [ :OP_SIZEOF_EXPR, val[1] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 115)
+  def _reduce_28(val, _values, result)
+     result = [ :OP_SIZEOF_TYPE, val[1] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 116)
+  def _reduce_29(val, _values, result)
+     result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 117)
+  def _reduce_30(val, _values, result)
+     result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 120)
+  def _reduce_31(val, _values, result)
+     result = :OP_U_AMP 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 121)
+  def _reduce_32(val, _values, result)
+     result = :OP_U_ASTER 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 122)
+  def _reduce_33(val, _values, result)
+     result = :OP_U_PLUS 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 123)
+  def _reduce_34(val, _values, result)
+     result = :OP_U_MINUS 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 124)
+  def _reduce_35(val, _values, result)
+     result = :OP_U_TILDE 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 125)
+  def _reduce_36(val, _values, result)
+     result = :OP_U_EXCLAM 
+    result
+  end
+.,.,
+
+# reduce 37 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 130)
+  def _reduce_38(val, _values, result)
+      result = [ :CAST, val[1], val[3] ] 
+    result
+  end
+.,.,
+
+# reduce 39 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 135)
+  def _reduce_40(val, _values, result)
+     result = [ :OP_MULT, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 137)
+  def _reduce_41(val, _values, result)
+     result = [ :OP_DIV, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 139)
+  def _reduce_42(val, _values, result)
+     result = [ :OP_REMAIN, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 43 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 144)
+  def _reduce_44(val, _values, result)
+     result = [ :OP_ADD, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 146)
+  def _reduce_45(val, _values, result)
+     result = [ :OP_SUB, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 46 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 151)
+  def _reduce_47(val, _values, result)
+     result = [ :OP_LSFT, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 153)
+  def _reduce_48(val, _values, result)
+     result = [ :OP_RSFT, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 49 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 158)
+  def _reduce_50(val, _values, result)
+     result = [ :OP_LT, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 160)
+  def _reduce_51(val, _values, result)
+     result = [ :OP_GT, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 162)
+  def _reduce_52(val, _values, result)
+     result = [ :OP_LE, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 164)
+  def _reduce_53(val, _values, result)
+     result = [ :OP_GE, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 54 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 169)
+  def _reduce_55(val, _values, result)
+     result = [ :OP_EQ, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 171)
+  def _reduce_56(val, _values, result)
+     result = [ :OP_NE, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 57 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 176)
+  def _reduce_58(val, _values, result)
+     result = [ :OP_AND, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 59 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 181)
+  def _reduce_60(val, _values, result)
+     result = [ :OP_EOR, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 61 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 186)
+  def _reduce_62(val, _values, result)
+     result = [ :OP_OR, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 63 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 191)
+  def _reduce_64(val, _values, result)
+     result = [ :OP_LAND, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 65 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 196)
+  def _reduce_66(val, _values, result)
+     result = [ :OP_LOR, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 67 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 201)
+  def _reduce_68(val, _values, result)
+     result = [ :OP_CEX, val[0], val[2].get_elements, val[4] ]  
+    result
+  end
+.,.,
+
+# reduce 69 omitted
+
+# reduce 70 omitted
+
+# reduce 71 omitted
+
+# reduce 72 omitted
+
+# reduce 73 omitted
+
+# reduce 74 omitted
+
+# reduce 75 omitted
+
+# reduce 76 omitted
+
+# reduce 77 omitted
+
+# reduce 78 omitted
+
+# reduce 79 omitted
+
+# reduce 80 omitted
+
+# reduce 81 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 223)
+  def _reduce_82(val, _values, result)
+    			result = Expression.new( val[0] )
+			# result.print
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 228)
+  def _reduce_83(val, _values, result)
+    			result = Expression.new( val[2] )    # ',' の後ろを採用
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 234)
+  def _reduce_84(val, _values, result)
+    			result = Expression.new( val[0] )
+			# result.print
+#			res = result.eval_const( nil )
+
+			# if res then
+			#   puts "val: #{res}"
+			# else
+			#   puts "val: nil"
+			# end
+		
+    result
+  end
+.,.,
+
+# reduce 85 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 261)
+  def _reduce_86(val, _values, result)
+    			result = CIntType.new( -3 )    # storage class は無視
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 265)
+  def _reduce_87(val, _values, result)
+    			result = val[1]                # storage class は無視
+		
+    result
+  end
+.,.,
+
+# reduce 88 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 270)
+  def _reduce_89(val, _values, result)
+    			result = val[1].merge val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 274)
+  def _reduce_90(val, _values, result)
+    			result = CIntType.new( -3 )
+			result.set_qualifier val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 279)
+  def _reduce_91(val, _values, result)
+    			val[1].set_qualifier val[0]
+						result = val[1]
+		
+    result
+  end
+.,.,
+
+# reduce 92 omitted
+
+# reduce 93 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 287)
+  def _reduce_94(val, _values, result)
+     result = [val[0]] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 289)
+  def _reduce_95(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+# reduce 96 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 294)
+  def _reduce_97(val, _values, result)
+     val[0].set_initializer( val[2] ) 
+    result
+  end
+.,.,
+
+# reduce 98 omitted
+
+# reduce 99 omitted
+
+# reduce 100 omitted
+
+# reduce 101 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 304)
+  def _reduce_102(val, _values, result)
+     set_no_type_name true; result = CVoidType.new 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 306)
+  def _reduce_103(val, _values, result)
+     set_no_type_name true; result = CIntType.new(-11 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 308)
+  def _reduce_104(val, _values, result)
+     set_no_type_name true; result = CIntType.new( -2 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 310)
+  def _reduce_105(val, _values, result)
+     set_no_type_name true; result = CIntType.new( -3 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 312)
+  def _reduce_106(val, _values, result)
+     set_no_type_name true; result = CIntType.new( -4 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 314)
+  def _reduce_107(val, _values, result)
+     set_no_type_name true; result = CFloatType.new(-32) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 316)
+  def _reduce_108(val, _values, result)
+     set_no_type_name true; result = CFloatType.new(-64) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 319)
+  def _reduce_109(val, _values, result)
+    			set_no_type_name true
+			result = CIntType.new( -3 )
+			result.set_sign :SIGNED
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 325)
+  def _reduce_110(val, _values, result)
+    			set_no_type_name true
+			result = CIntType.new( -3 )
+			result.set_sign :UNSIGNED
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 330)
+  def _reduce_111(val, _values, result)
+     set_no_type_name true; result = CBoolType.new 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 332)
+  def _reduce_112(val, _values, result)
+     set_no_type_name true; result = val[0] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 334)
+  def _reduce_113(val, _values, result)
+     set_no_type_name true; result = CVoidType.new 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 336)
+  def _reduce_114(val, _values, result)
+     set_no_type_name true; result = CVoidType.new 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 338)
+  def _reduce_115(val, _values, result)
+     set_no_type_name true; result = CDefinedType.new( val[0].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 344)
+  def _reduce_116(val, _values, result)
+     StructType.set_define( true )  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 347)
+  def _reduce_117(val, _values, result)
+    			StructType.end_of_parse
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 353)
+  def _reduce_118(val, _values, result)
+    			result = CStructType.new()
+			StructType.set_define( true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 358)
+  def _reduce_119(val, _values, result)
+    			StructType.end_of_parse
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 364)
+  def _reduce_120(val, _values, result)
+    			StructType.set_define( false )
+			StructType.end_of_parse
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 370)
+  def _reduce_121(val, _values, result)
+     set_no_type_name true 
+    result
+  end
+.,.,
+
+# reduce 122 omitted
+
+# reduce 123 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 379)
+  def _reduce_124(val, _values, result)
+    			result = CStructType.new( val[0].val )
+			set_no_type_name true
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 388)
+  def _reduce_125(val, _values, result)
+    			val[1].each { |i|	# i: Decl
+				i.set_type( val[0] )
+				i.set_kind( :MEMBER )
+				i.check
+				CStructType.new_member( i )
+			}
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 399)
+  def _reduce_126(val, _values, result)
+    			val[1].each { |i|	# i: Decl
+				i.set_type( val[0] )
+				i.set_kind( :MEMBER )
+				i.check
+				CStructType.new_member( i )
+			}
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+# reduce 127 omitted
+
+# reduce 128 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 417)
+  def _reduce_129(val, _values, result)
+    			result = val[1].merge val[0]
+		
+    result
+  end
+.,.,
+
+# reduce 130 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 422)
+  def _reduce_131(val, _values, result)
+    			val[1].set_qualifier val[0]
+						result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 427)
+  def _reduce_132(val, _values, result)
+    			result = CIntType.new( -3 )
+			result.set_qualifier val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 433)
+  def _reduce_133(val, _values, result)
+     result = [ val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 435)
+  def _reduce_134(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+# reduce 135 omitted
+
+# reduce 136 omitted
+
+# reduce 137 omitted
+
+# reduce 138 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 452)
+  def _reduce_139(val, _values, result)
+     set_no_type_name true 
+    result
+  end
+.,.,
+
+# reduce 140 omitted
+
+# reduce 141 omitted
+
+# reduce 142 omitted
+
+# reduce 143 omitted
+
+# reduce 144 omitted
+
+# reduce 145 omitted
+
+# reduce 146 omitted
+
+# reduce 147 omitted
+
+# reduce 148 omitted
+
+# reduce 149 omitted
+
+# reduce 150 omitted
+
+# reduce 151 omitted
+
+# reduce 152 omitted
+
+# reduce 153 omitted
+
+# reduce 154 omitted
+
+# reduce 155 omitted
+
+# reduce 156 omitted
+
+# reduce 157 omitted
+
+# reduce 158 omitted
+
+# reduce 159 omitted
+
+# reduce 160 omitted
+
+# reduce 161 omitted
+
+# reduce 162 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 495)
+  def _reduce_163(val, _values, result)
+     result = :CONST 
+    result
+  end
+.,.,
+
+# reduce 164 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 498)
+  def _reduce_165(val, _values, result)
+     result = :VOLATILE 
+    result
+  end
+.,.,
+
+# reduce 166 omitted
+
+# reduce 167 omitted
+
+# reduce 168 omitted
+
+# reduce 169 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 509)
+  def _reduce_170(val, _values, result)
+    			val[1].set_type( val[0] )
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+# reduce 171 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 515)
+  def _reduce_172(val, _values, result)
+    			result = Decl.new( val[1].val )
+			result.set_type( val[0] )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 521)
+  def _reduce_173(val, _values, result)
+     result = Decl.new( val[0].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 523)
+  def _reduce_174(val, _values, result)
+     result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 526)
+  def _reduce_175(val, _values, result)
+    			val[0].set_type( CArrayType.new( val[2] ) )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 531)
+  def _reduce_176(val, _values, result)
+    			val[0].set_type( CArrayType.new )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 536)
+  def _reduce_177(val, _values, result)
+    		# 	Generator.warning( "W6001 need 'void' for no parameter"  )
+			val[0].set_type( CFuncType.new )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+# reduce 178 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 543)
+  def _reduce_179(val, _values, result)
+    		# 	Generator.warning( "W6002 need 'void' for no parameter"  )
+			val[0].set_type( CFuncType.new )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 550)
+  def _reduce_180(val, _values, result)
+     result = CPtrType.new 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 553)
+  def _reduce_181(val, _values, result)
+    			result = CPtrType.new
+			result.set_qualifier( val[1] )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 558)
+  def _reduce_182(val, _values, result)
+    			val[1].set_type(CPtrType.new)
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 563)
+  def _reduce_183(val, _values, result)
+    			ptrtype = CPtrType.new
+			ptrtype.set_qualifier( val[1] )
+			val[2].set_type( ptrtype )
+			result = val[2]
+		
+    result
+  end
+.,.,
+
+# reduce 184 omitted
+
+# reduce 185 omitted
+
+# reduce 186 omitted
+
+# reduce 187 omitted
+
+# reduce 188 omitted
+
+# reduce 189 omitted
+
+# reduce 190 omitted
+
+# reduce 191 omitted
+
+# reduce 192 omitted
+
+# reduce 193 omitted
+
+# reduce 194 omitted
+
+# reduce 195 omitted
+
+# reduce 196 omitted
+
+# reduce 197 omitted
+
+# reduce 198 omitted
+
+# reduce 199 omitted
+
+# reduce 200 omitted
+
+# reduce 201 omitted
+
+# reduce 202 omitted
+
+# reduce 203 omitted
+
+# reduce 204 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 630)
+  def _reduce_205(val, _values, result)
+    			Generator.warning( "W6003 need 'void' for no parameter"  )
+		
+    result
+  end
+.,.,
+
+# reduce 206 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 635)
+  def _reduce_207(val, _values, result)
+    			Generator.warning( "W6004 need 'void' for no parameter"  )
+		
+    result
+  end
+.,.,
+
+# reduce 208 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 642)
+  def _reduce_209(val, _values, result)
+     result = val[0] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 644)
+  def _reduce_210(val, _values, result)
+     result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 646)
+  def _reduce_211(val, _values, result)
+     result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 648)
+  def _reduce_212(val, _values, result)
+     result = C_EXP.new( val[2] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 653)
+  def _reduce_213(val, _values, result)
+    			result = [ val[0] ]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 657)
+  def _reduce_214(val, _values, result)
+    			val[0] << val[2]
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+# reduce 215 omitted
+
+# reduce 216 omitted
+
+# reduce 217 omitted
+
+# reduce 218 omitted
+
+# reduce 219 omitted
+
+# reduce 220 omitted
+
+# reduce 221 omitted
+
+# reduce 222 omitted
+
+# reduce 223 omitted
+
+# reduce 224 omitted
+
+# reduce 225 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 685)
+  def _reduce_226(val, _values, result)
+    			val[2].each{ |i|
+			   i.set_kind( :TYPEDEF )
+			}
+			Typedef.new_decl_list( val[1], val[2] )
+                        # val[1].show_tree 0
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 694)
+  def _reduce_227(val, _values, result)
+     result = [ val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 696)
+  def _reduce_228(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+# reduce 229 omitted
+
+# reduce 230 omitted
+
+# reduce 231 omitted
+
+# reduce 232 omitted
+
+# reduce 233 omitted
+
+# reduce 234 omitted
+
+# reduce 235 omitted
+
+# reduce 236 omitted
+
+# reduce 237 omitted
+
+# reduce 238 omitted
+
+# reduce 239 omitted
+
+# reduce 240 omitted
+
+# reduce 241 omitted
+
+# reduce 242 omitted
+
+# reduce 243 omitted
+
+# reduce 244 omitted
+
+# reduce 245 omitted
+
+# reduce 246 omitted
+
+# reduce 247 omitted
+
+# reduce 248 omitted
+
+# reduce 249 omitted
+
+# reduce 250 omitted
+
+# reduce 251 omitted
+
+# reduce 252 omitted
+
+# reduce 253 omitted
+
+# reduce 254 omitted
+
+# reduce 255 omitted
+
+# reduce 256 omitted
+
+# reduce 257 omitted
+
+# reduce 258 omitted
+
+# reduce 259 omitted
+
+# reduce 260 omitted
+
+# reduce 261 omitted
+
+# reduce 262 omitted
+
+# reduce 263 omitted
+
+# reduce 264 omitted
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 761)
+  def _reduce_265(val, _values, result)
+     result = NamespacePath.new( val[0].val, false ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 762)
+  def _reduce_266(val, _values, result)
+     result = NamespacePath.new( val[1].val, true ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 764)
+  def _reduce_267(val, _values, result)
+     result = val[0].append!( val[2].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'C_parser.y.rb', 768)
+  def _reduce_268(val, _values, result)
+    		while true
+			# ';' が表れるまで、トークンを読み飛ばす。
+			# gcc の構文拡張に対応すべきだが、単純な実装として、';' まで読み飛ばす。
+			# トークン単位で読み飛ばしているので、文字列やコメント内の ';' は対象にならない。
+			token = next_token
+			if token[1].val == ";"
+				break
+			end
+			# p "skip: #{token[1].val}" 
+		end
+		
+    result
+  end
+.,.,
+
+def _reduce_none(val, _values, result)
+  val[0]
+end
+
+end   # class C_parser
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.y.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.y.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/C_parser.y.rb	(revision 398)
@@ -0,0 +1,1081 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)〜(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+class C_parser
+rule
+# トップレベルの構文要素は C_parser
+all: C_parser
+
+# Expr
+##########################  式  ##########################
+# K&Rの文法(プログラミング言語C 第2版 付録)と一部異なる
+# argument_expression_list(関数引数), assignment_expression(代入)がない
+# 式の result は、すべて配列で第一要素が識別シンボル、第二要素以下が引数
+#
+# 2019/3/28 長島 下記のC99の構文に近づくよう変更
+#（読めないヘッダーファイルがあったため）
+# http://www.quut.com/c/ANSI-C-grammar-y-1999.html
+# 元々のコメントと合わなくなっています
+
+primary_expression
+		: namespace_identifier
+		{ result = [ :IDENTIFIER, val[0] ] }     #1ok
+#        : IDENTIFIER	# mikan namespace への対応
+#		{ result = [ :IDENTIFIER, val[0] ] }
+#        | TRUE
+#		{ result = [ :BOOL_CONSTANT, true ] }
+#        | FALSE
+#		{ result = [ :BOOL_CONSTANT, false ] }
+		| INTEGER_CONSTANT
+		{ result = [ :INTEGER_CONSTANT, val[0] ] }
+		| FLOATING_CONSTANT
+		{ result = [ :FLOATING_CONSTANT, val[0] ] }
+		| OCTAL_CONSTANT
+		{ result = [ :OCTAL_CONSTANT, val[0] ] }
+		| HEX_CONSTANT
+		{ result = [ :HEX_CONSTANT, val[0] ] }
+		| CHARACTER_LITERAL
+		{ result = [ :CHARACTER_LITERAL, val[0] ] }
+		| string_literal_list
+		{ result = [ :STRING_LITERAL_LIST, val[0] ] }
+		| '(' expression ')'
+		{ result = [ :PARENTHESES, val[1].get_elements ] }
+
+string_literal_list
+		: STRING_LITERAL
+		{ result = [val[0]] }
+		| string_literal_list STRING_LITERAL
+		{ result << val[1] }
+
+# 関数呼び出しと後置インクリメント、デクリメント演算子がない
+postfix_expression
+		: primary_expression
+		| postfix_expression '[' expression ']'
+		{ result = [ :OP_SUBSC, val[0], val[2] ] }
+		| postfix_expression '(' ')'
+		| postfix_expression '(' argument_expression_list ')'
+		| postfix_expression type_qualifier '(' argument_expression_list ')'    # intended __asm volatile ( "   MNEMONIC  OPERAND" );
+		| postfix_expression '.' IDENTIFIER
+		{ result = [ :OP_DOT, val[0], val[2] ] }
+		| postfix_expression '->' IDENTIFIER
+		{ result = [ :OP_REF, val[0], val[2] ] }
+		| postfix_expression '++'	{ result = val[0] }   # ++, -- は無視する
+		| postfix_expression '--'	{ result = val[0] }
+		| '(' type_name ')' '{' initializer_list '}'
+		| '(' type_name ')' '{' initializer_list ',' '}'
+
+argument_expression_list
+		: assignment_expression
+		| argument_expression_list ',' assignment_expression
+
+
+# 前置インクリメント、デクリメント演算子がない
+unary_expression
+		: postfix_expression
+		| unary_operator cast_expression
+		{ result = [ val[0], val[1] ] }
+		| SIZEOF unary_expression
+		{ result = [ :OP_SIZEOF_EXPR, val[1] ] }
+		| SIZEOF '(' type_name ')'
+		{ result = [ :OP_SIZEOF_TYPE, val[1] ] }
+		| '++' unary_expression			{ result = val[1] }   # ++, -- は無視する
+		| '--' unary_expression			{ result = val[1] }
+
+unary_operator
+		: '&'	{ result = :OP_U_AMP }
+		| '*'	{ result = :OP_U_ASTER }
+		| '+'	{ result = :OP_U_PLUS }
+		| '-'	{ result = :OP_U_MINUS }
+		| '~'	{ result = :OP_U_TILDE }
+		| '!'	{ result = :OP_U_EXCLAM }
+
+cast_expression
+		: unary_expression
+		| '(' type_name ')' cast_expression
+		{  result = [ :CAST, val[1], val[3] ] }
+
+multiplicative_expression
+		: cast_expression
+		| multiplicative_expression '*' cast_expression
+		{ result = [ :OP_MULT, val[0], val[2] ]  }
+		| multiplicative_expression '/' cast_expression
+		{ result = [ :OP_DIV, val[0], val[2] ]  }
+		| multiplicative_expression '%' cast_expression
+		{ result = [ :OP_REMAIN, val[0], val[2] ]  }
+
+additive_expression
+		: multiplicative_expression
+		| additive_expression '+' multiplicative_expression
+		{ result = [ :OP_ADD, val[0], val[2] ]  }
+		| additive_expression '-' multiplicative_expression
+		{ result = [ :OP_SUB, val[0], val[2] ]  }
+
+shift_expression
+		: additive_expression
+		| shift_expression '<<' additive_expression
+		{ result = [ :OP_LSFT, val[0], val[2] ]  }
+		| shift_expression '>>' additive_expression
+		{ result = [ :OP_RSFT, val[0], val[2] ]  }
+
+relational_expression
+		: shift_expression
+		| relational_expression '<' shift_expression
+		{ result = [ :OP_LT, val[0], val[2] ]  }
+		| relational_expression '>' shift_expression
+		{ result = [ :OP_GT, val[0], val[2] ]  }
+		| relational_expression '<=' shift_expression
+		{ result = [ :OP_LE, val[0], val[2] ]  }
+		| relational_expression '>=' shift_expression
+		{ result = [ :OP_GE, val[0], val[2] ]  }
+
+equality_expression
+		: relational_expression
+		| equality_expression '==' relational_expression
+		{ result = [ :OP_EQ, val[0], val[2] ]  }
+		| equality_expression '!=' relational_expression
+		{ result = [ :OP_NE, val[0], val[2] ]  }
+
+and_expression
+		: equality_expression
+		| and_expression '&' equality_expression
+		{ result = [ :OP_AND, val[0], val[2] ]  }
+
+exclusive_or_expression
+		: and_expression
+		| exclusive_or_expression '^' and_expression
+		{ result = [ :OP_EOR, val[0], val[2] ]  }
+
+inclusive_or_expression
+		: exclusive_or_expression
+		| inclusive_or_expression '|' exclusive_or_expression
+		{ result = [ :OP_OR, val[0], val[2] ]  }
+
+logical_and_expression
+		: inclusive_or_expression
+		| logical_and_expression '&&' inclusive_or_expression
+		{ result = [ :OP_LAND, val[0], val[2] ]  }
+
+logical_or_expression
+		: logical_and_expression
+		| logical_or_expression '||' logical_and_expression
+		{ result = [ :OP_LOR, val[0], val[2] ]  }
+
+conditional_expression
+		: logical_or_expression
+		| logical_or_expression '?' expression ':' conditional_expression
+		{ result = [ :OP_CEX, val[0], val[2].get_elements, val[4] ]  }
+
+assignment_expression
+		: conditional_expression
+		| unary_expression assignment_operator assignment_expression
+
+assignment_operator
+		: '='
+		| '+='
+		| '-='
+		| '*='
+		| '/='
+		| '%='
+		| '<<='
+		| '>>='
+		| '&='
+		| '|='
+		| '^='
+
+expression
+		: assignment_expression
+		{
+			result = Expression.new( val[0] )
+			# result.print
+		}
+		| expression ',' assignment_expression
+		{
+			result = Expression.new( val[2] )    # ',' の後ろを採用
+		}
+
+constant_expression
+		: conditional_expression
+		{
+			result = Expression.new( val[0] )
+			# result.print
+#			res = result.eval_const( nil )
+
+			# if res then
+			#   puts "val: #{res}"
+			# else
+			#   puts "val: nil"
+			# end
+		}
+
+# Types
+##########################  宣言  ##########################
+# 宣言もK&Rと一部異なる
+
+# declarationはセルの属性で使われる
+# K&Rとの違い: storage classが指定できない、型が省略できない
+declaration
+		: declaration_specifiers init_declarator_list ';'
+#        : specifier_qualifier_list init_declarator_list ';'
+
+# declaration_specifiersは関数のパラメータで使われるが、
+# specifier_qualifier_listで十分かもしれない
+
+declaration_specifiers
+		: storage_class_specifier
+		{
+			result = CIntType.new( -3 )    # storage class は無視
+		}
+		| storage_class_specifier declaration_specifiers
+		{
+			result = val[1]                # storage class は無視
+		}
+		| type_specifier
+		| type_specifier declaration_specifiers
+		{
+			result = val[1].merge val[0]
+		}
+		| type_qualifier
+		{
+			result = CIntType.new( -3 )
+			result.set_qualifier val[0]
+		}
+		| type_qualifier declaration_specifiers
+		{
+			val[1].set_qualifier val[0]
+						result = val[1]
+		}
+		| function_specifier
+		| function_specifier declaration_specifiers
+
+init_declarator_list
+		: init_declarator
+		{ result = [val[0]] }
+		| init_declarator_list ',' init_declarator
+		{ result << val[2] }
+
+init_declarator
+		: declarator
+		| declarator '=' initializer
+		{ val[0].set_initializer( val[2] ) }
+
+storage_class_specifier
+		: EXTERN
+		| STATIC
+		| AUTO
+		| REGISTER
+
+type_specifier
+		: VOID
+		{ set_no_type_name true; result = CVoidType.new }
+		| CHAR
+		{ set_no_type_name true; result = CIntType.new(-11 ) }
+		| SHORT
+		{ set_no_type_name true; result = CIntType.new( -2 ) }
+		| INT
+		{ set_no_type_name true; result = CIntType.new( -3 ) }
+		| LONG
+		{ set_no_type_name true; result = CIntType.new( -4 ) }
+		| FLOAT
+		{ set_no_type_name true; result = CFloatType.new(-32) }
+		| DOUBLE
+		{ set_no_type_name true; result = CFloatType.new(-64) }
+		| SIGNED
+		{
+			set_no_type_name true
+			result = CIntType.new( -3 )
+			result.set_sign :SIGNED
+		}
+		| UNSIGNED
+		{
+			set_no_type_name true
+			result = CIntType.new( -3 )
+			result.set_sign :UNSIGNED
+		}
+		| BOOL
+		{ set_no_type_name true; result = CBoolType.new }
+		| struct_specifier
+		{ set_no_type_name true; result = val[0] } # set_no_type_name true は struct_tag でも呼ばれる
+		| union_specifier
+		{ set_no_type_name true; result = CVoidType.new }  # void が宣言されたとする
+		| enum_specifier
+		{ set_no_type_name true; result = CVoidType.new }  # void が宣言されたとする
+		| TYPE_NAME
+		{ set_no_type_name true; result = CDefinedType.new( val[0].val ) }
+
+# mikan K&Rのstruct_or_union_specifierに相当するが、unionは使えない, bit field にも対応しない
+struct_specifier		# mikan
+#        : STRUCT struct_tag '{'
+		: struct_term struct_tag '{'
+		{ StructType.set_define( true )  }
+		struct_declaration_list '}'
+		{
+			StructType.end_of_parse
+			result = val[1]
+		}
+#        | STRUCT
+		| struct_term
+		{
+			result = CStructType.new()
+			StructType.set_define( true )
+		}
+		'{' struct_declaration_list '}'
+		{
+			StructType.end_of_parse
+			result = val[1]
+		}
+#        | STRUCT struct_tag   # mikan struct_tag は namespace 対応が必要
+		| struct_term struct_tag   # mikan struct_tag は namespace 対応が必要
+		{
+			StructType.set_define( false )
+			StructType.end_of_parse
+			result = val[1]
+		}
+
+struct_term
+		: STRUCT { set_no_type_name true }
+
+struct_declaration_list
+		: struct_declaration
+		| struct_declaration_list struct_declaration
+
+struct_tag:
+		IDENTIFIER
+		{
+			result = CStructType.new( val[0].val )
+			set_no_type_name true
+		}
+
+# ポインタ修飾子を追加
+struct_declaration
+		: declaration_specifiers struct_declarator_list ';'
+#        :                                specifier_qualifier_list struct_declarator_list ';'
+		{
+			val[1].each { |i|	# i: Decl
+				i.set_type( val[0] )
+				i.set_kind( :MEMBER )
+				i.check
+				CStructType.new_member( i )
+			}
+			result = val[1]
+		}
+		# ビットフィールドを読み飛ばし
+		| declaration_specifiers struct_declarator_list ':' constant_expression ';'
+		{
+			val[1].each { |i|	# i: Decl
+				i.set_type( val[0] )
+				i.set_kind( :MEMBER )
+				i.check
+				CStructType.new_member( i )
+			}
+			result = val[1]
+		}
+		| union_specifier ';'                       # 無名
+		| struct_specifier ';'                       # 無名
+
+
+
+# K&Rのspecifier_qualifier_listと同じ
+# 名前がまぎらわしかったのでtype_を付けた
+specifier_qualifier_list
+		: type_specifier specifier_qualifier_list
+		{
+			result = val[1].merge val[0]
+		}
+		| type_specifier
+		| type_qualifier specifier_qualifier_list
+		{
+			val[1].set_qualifier val[0]
+						result = val[1]
+		}
+		| type_qualifier
+		{
+			result = CIntType.new( -3 )
+			result.set_qualifier val[0]
+		}
+
+struct_declarator_list
+		: struct_declarator
+		{ result = [ val[0] ] }
+		| struct_declarator_list ',' struct_declarator
+		{ result << val[2] }
+
+# ビットフィールドは使えない
+struct_declarator
+		: declarator
+#		| ':' constant_expression
+#		| declarator ':' constant_expression
+
+union_specifier
+#        : UNION union_tag '{' union_declaration_list '}'
+#        | UNION '{' union_declaration_list '}'
+#        | UNION union_tag   # mikan struct_tag は namespace 対応が必要
+		: union_term union_tag '{' union_declaration_list '}'
+		| union_term '{' union_declaration_list '}'
+		| union_term union_tag   # mikan struct_tag は namespace 対応が必要
+
+union_term
+		: UNION { set_no_type_name true }
+
+union_declaration_list
+		: union_declaration
+		| union_declaration_list union_declaration
+
+union_tag:
+	IDENTIFIER
+
+union_declaration
+		: declaration_specifiers union_declarator_list ';'
+		| union_specifier ';'                       # 無名
+		| struct_specifier ';'                      # 無名
+
+union_declarator_list
+		: union_declarator
+		| union_declarator_list ',' union_declarator
+
+union_declarator
+		: declarator
+		| ':' constant_expression
+		| declarator ':' constant_expression
+
+enum_specifier
+		: ENUM '{' enumerator_list '}'
+		| ENUM IDENTIFIER '{' enumerator_list '}'
+		| ENUM '{' enumerator_list ',' '}'
+		| ENUM IDENTIFIER '{' enumerator_list ',' '}'
+		| ENUM IDENTIFIER
+		| ENUM TYPE_NAME '{' enumerator_list '}'
+		| ENUM TYPE_NAME '{' enumerator_list ',' '}'
+		| ENUM TYPE_NAME
+
+enumerator_list
+		: enumerator
+		| enumerator_list ',' enumerator
+
+enumerator
+		: IDENTIFIER
+		| IDENTIFIER '=' constant_expression
+
+type_qualifier
+		: CONST
+		{ result = :CONST }
+		| RESTRICT
+		| VOLATILE
+		{ result = :VOLATILE }
+
+function_specifier
+		: __INLINE__
+		| INLINE
+		| __INLINE
+		| CINLINE
+
+declarator
+		: pointer direct_declarator
+		{
+			val[1].set_type( val[0] )
+			result = val[1]
+		}
+		| direct_declarator
+		| pointer TYPE_NAME     # 関数ポインタの typedef が二重定義の場合
+		{
+			result = Decl.new( val[1].val )
+			result.set_type( val[0] )
+		}
+
+direct_declarator		# mikan
+		: IDENTIFIER
+		{ result = Decl.new( val[0].val ) }
+		| '(' declarator ')'
+		{ result = val[1] }
+		| direct_declarator '[' constant_expression ']'
+		{
+			val[0].set_type( CArrayType.new( val[2] ) )
+			result = val[0]
+		}
+		| direct_declarator '[' ']'
+		{
+			val[0].set_type( CArrayType.new )
+			result = val[0]
+		}
+		| direct_declarator '(' parameter_type_list ')'
+		{
+		# 	Generator.warning( "W6001 need 'void' for no parameter"  )
+			val[0].set_type( CFuncType.new )
+			result = val[0]
+		}
+		| direct_declarator '(' identifier_list ')'  # これは何のために必要？ 060211
+		| direct_declarator '(' ')'
+		{
+		# 	Generator.warning( "W6002 need 'void' for no parameter"  )
+			val[0].set_type( CFuncType.new )
+			result = val[0]
+		}
+
+pointer
+		: '*'
+		{ result = CPtrType.new }
+		| '*' type_qualifier_list
+		{
+			result = CPtrType.new
+			result.set_qualifier( val[1] )
+		}
+		| '*' pointer
+		{
+			val[1].set_type(CPtrType.new)
+			result = val[1]
+		}
+		| '*' type_qualifier_list pointer
+		{
+			ptrtype = CPtrType.new
+			ptrtype.set_qualifier( val[1] )
+			val[2].set_type( ptrtype )
+			result = val[2]
+		}
+
+type_qualifier_list
+		: type_qualifier
+		| type_qualifier_list type_qualifier
+
+parameter_type_list
+		: parameter_list
+		| parameter_list ',' '.' '.' '.'
+		# mikan 可変長パラメータ,  ... の間のスペースが許される（手抜き）
+
+parameter_list
+		: parameter_declaration
+#		{ result = ParamList.new( val[0] ) }
+		| parameter_list ',' parameter_declaration
+#		{
+#			val[0].add_param( val[2] )
+#			# result = val[0] 不要
+#		}
+
+
+# パラメータ修飾子を追加
+parameter_declaration
+		: declaration_specifiers declarator
+#		{
+#			decl = ParamDecl.new( val[1], val[0], [] )
+#			val[1].set_kind( :PARAMETER )
+#			result = decl
+#		}
+
+	# 以下はエラーとする
+#        | declaration_specifiers	# 仮引数なしは、とりあえず扱わない 060210
+#		{
+#			unless val[0].kind_of?( VoidType ) then
+#				Generator.error( "B1001 need parameter name"  )
+#			end
+#			result = nil
+#		}
+		| declaration_specifiers abstract_declarator	# 仮引数なし
+		| declaration_specifiers						# 仮引数なし
+
+
+identifier_list       # 060211  不用になった
+        : IDENTIFIER
+        | identifier_list ',' IDENTIFIER
+
+type_name
+		: specifier_qualifier_list
+		| specifier_qualifier_list abstract_declarator
+
+abstract_declarator		# mikan
+		: pointer
+		| direct_abstract_declarator
+		| pointer direct_abstract_declarator
+
+direct_abstract_declarator
+		: '(' abstract_declarator ')'
+		| '[' ']'
+		| '[' assignment_expression ']'
+		| direct_abstract_declarator '[' ']'
+		| direct_abstract_declarator '[' assignment_expression ']'
+		| '(' ')'
+		{
+			Generator.warning( "W6003 need 'void' for no parameter"  )
+		}
+		| '(' parameter_type_list ')'
+		| direct_abstract_declarator '(' ')'
+		{
+			Generator.warning( "W6004 need 'void' for no parameter"  )
+		}
+		| direct_abstract_declarator '(' parameter_type_list ')'
+
+# assignment_expressionをconstant_expressionに変更
+initializer			# mikan
+		: assignment_expression
+		{ result = val[0] }
+		| '{' initializer_list '}'
+		{ result = val[1] }
+		| '{' initializer_list ',' '}'
+		{ result = val[1] }
+		| C_EXP '(' STRING_LITERAL ')'
+		{ result = C_EXP.new( val[2] ) }
+
+initializer_list
+		: initializer
+		{
+			result = [ val[0] ]
+		}
+		| initializer_list ',' initializer
+		{
+			val[0] << val[2]
+			result = val[0]
+		}
+
+
+##########################  ここからはCDL独自  ##########################
+
+#トップレベルの構文規則
+C_parser
+		:
+		| C_parser extension_statement
+
+extension_statement
+		: cdl_statement
+		| EXTENSION cdl_statement
+
+cdl_statement
+		: typedef
+		| func_def
+		| enum_specifier ';'
+		| struct_specifier ';'
+		| declaration
+		| ';'
+		| error   # エラー回復ポイント
+
+typedef
+        : TYPEDEF specifier_qualifier_list declarator_list ';'
+		{
+			val[2].each{ |i|
+			   i.set_kind( :TYPEDEF )
+			}
+			Typedef.new_decl_list( val[1], val[2] )
+                        # val[1].show_tree 0
+		}
+
+declarator_list
+		: declarator
+		{ result = [ val[0] ] }
+		| declarator_list ',' declarator
+		{ result << val[2] }
+
+func_def
+		: declaration_specifiers declarator compound_statement
+
+statement
+		: labeled_statement
+		| compound_statement
+		| expression_statement
+		| ifstatement
+		| whilestatement
+		| dowhilestatement
+		| forstatement
+		| switchstatement
+		| jump_statement
+		| asm_statement
+
+labeled_statement
+		: IDENTIFIER ':' statement
+		| CASE constant_expression ':' statement
+		| DEFAULT ':' statement
+
+compound_statement
+		: '{' '}'
+		| '{' block_item_list '}'
+
+block_item_list
+		: block_item
+		| block_item_list block_item
+
+block_item
+		: declaration
+		| statement
+
+expression_statement
+		: ';'
+		| expression ';'
+
+ifstatement
+		: IF '(' expression ')' statement
+		| IF '(' expression ')' statement ELSE statement
+
+switchstatement
+		: SWITCH '(' expression ')' compound_statement
+
+whilestatement
+		: WHILE '(' expression ')' statement
+
+dowhilestatement
+		: DO statement WHILE '(' expression ')' ';'
+
+forstatement
+		: FOR '(' expression_statement expression_statement ')' statement
+		| FOR '(' expression_statement expression_statement expression ')' statement
+		| FOR '(' declaration expression_statement ')' statement
+		| FOR '(' declaration expression_statement expression ')' statement
+
+jump_statement
+		: GOTO IDENTIFIER ';'
+		| CONTINUE ';'
+		| BREAK ';'
+		| RETURN ';'
+		| RETURN expression ';'
+
+namespace_identifier
+		: IDENTIFIER		{ result = NamespacePath.new( val[0].val, false ) }
+		| '::' IDENTIFIER	{ result = NamespacePath.new( val[1].val, true ) }
+		| namespace_identifier '::' IDENTIFIER
+		{ result = val[0].append!( val[2].val ) }
+
+asm_statement
+		: _ASM {
+		while true
+			# ';' が表れるまで、トークンを読み飛ばす。
+			# gcc の構文拡張に対応すべきだが、単純な実装として、';' まで読み飛ばす。
+			# トークン単位で読み飛ばしているので、文字列やコメント内の ';' は対象にならない。
+			token = next_token
+			if token[1].val == ";"
+				break
+			end
+			# p "skip: #{token[1].val}" 
+		end
+		}
+
+end
+
+---- inner
+
+	RESERVED = {
+		# keyword
+		'typedef' => :TYPEDEF,
+		'struct' => :STRUCT,
+		'union' => :UNION,
+		'sizeof' => :SIZEOF,
+		'throw' => :THROW,
+
+		# specifier
+		# types
+		'void'    => :VOID,
+		'char'    => :CHAR,
+		'short'   => :SHORT,
+
+		'volatile'=> :VOLATILE,
+		'restrict'=> :RESTRICT,
+		'const'   => :CONST,
+		'extern'   => :EXTERN,
+
+		'long'    => :LONG,
+		'float'   => :FLOAT,
+		'double'  => :DOUBLE,
+		'signed'  => :SIGNED,
+		'unsigned'=> :UNSIGNED,
+
+		'int'     => :INT,
+		'enum'    => :ENUM,
+
+		'if'      => :IF,
+		'else'    => :ELSE,
+		'while'   => :WHILE,
+		'do'      => :DO,
+		'for'     => :FOR,
+		'switch'  => :SWITCH,
+		'case'    => :CASE,
+		'default' => :DEFAULT,
+		'goto'    => :GOTO,
+		'continue' => :CONTINUE,
+		'break'   => :BREAK,
+		'return'  => :RETURN,
+		'__inline__'  => :__INLINE__,
+		'inline'  => :INLINE,
+		'__inline'  => :__INLINE,
+		'Inline'  => :CINLINE,        # inline starting with Capital letter
+		'static'  => :STATIC,
+		'register' => :REGISTER,
+		'auto'    => :AUTO,
+		'__extension__'    => :EXTENSION,
+		'__asm__' => :_ASM,
+		'asm' =>     :_ASM
+
+	}
+
+	@@generator_nest = -1
+	@@generator_stack = []
+	@@current_locale = []
+
+	def finalize
+
+		# mikan Namespace.pop
+		Celltype.pop
+		Cell.pop
+		CompositeCelltype.pop
+		Region.pop
+
+	end
+
+	def set_plugin( plugin )
+		@plugin = plugin
+	end
+
+	def self.get_plugin
+		@@generator_stack[@@generator_nest].get_plugin
+	end
+
+	def get_plugin
+		@plugin
+	end
+
+	def parse(files)
+
+		# mikan Namespace.push
+		Celltype.push
+		Cell.push
+		CompositeCelltype.push
+		Region.push
+
+		@@generator_nest += 1
+		@@generator_stack[@@generator_nest] = self
+		@b_no_type_name = false
+
+	begin
+
+		@q = []
+		comment = false
+#		b_asm   = false
+
+		# euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策
+		TECS_LANG::set_kcode_binary
+
+		# 800U, 0xffLL など (整数リテラルに共通の修飾子)
+		integer_qualifier = "([Uu][Ll][Ll]|[Uu][Ll]|[Uu]|[Ll][Ll]|[Ll])?"
+
+		files.each {|file|
+			lineno = 1
+		begin
+#2.0		IO.foreach(file) {|line|
+			TECSIO.foreach(file) {|line|
+			col = 1
+			line.rstrip!
+
+			until line.empty?
+
+				if comment
+					case line
+					# コメント終了
+					when /\A\*\//
+						comment = false
+					when /\A./
+						;
+					end
+				else
+					case line
+					# 空白、プリプロセスディレクティブ
+					when /\A\s+/
+						;
+					# 識別子
+					when /\A[a-zA-Z_]\w*/
+						word = $&
+						@q << [RESERVED[word] || :IDENTIFIER, Token.new(word.intern, file, lineno, col)]
+					# 16 進数定数
+					when /\A0x[0-9A-Fa-f]+#{integer_qualifier}/
+						@q << [:HEX_CONSTANT, Token.new($&, file, lineno, col)]
+					# 8 進数定数
+					when /\A0[0-7]+#{integer_qualifier}/
+						@q << [:OCTAL_CONSTANT, Token.new($&, file, lineno, col)]
+					# 浮動小数定数
+					when /\A[0-9]+\.([0-9]*)?([Ee][+-]?[0-9]+)?/
+						@q << [:FLOATING_CONSTANT, Token.new($&, file, lineno, col)]
+					# 整数定数
+					when /\A\d+#{integer_qualifier}/
+					# when /\A\d+/
+						@q << [:INTEGER_CONSTANT, Token.new($&.to_i, file, lineno, col)]
+					# 文字
+					when /\A'(?:[^'\\]|\\.)'/
+						@q << [:CHARACTER_LITERAL, Token.new($&, file, lineno, col)]
+					# 文字列
+#					"#include  #include #include \"../systask/logtask.cfg\"       最後の " 忘れ)で無限ループ
+#					when /\A"(?:[^"\\]+|\\.)*"/
+					when /\A"(?:[^"\\]|\\.)*"/   # これはうまく行くようだ
+						@q << [:STRING_LITERAL, Token.new($&, file, lineno, col)]
+					# 行コメント
+					when /\A\/\/.*$/
+						# 読み飛ばすだけ
+					# コメント開始
+					when /\A\/\*/
+						comment = true
+					when /\A>>=/, /\A<<=/, /\A>>/,  /\A<</
+						@q << [$&, Token.new($&, file, lineno, col)]
+					when /\A\+=/, /\A\-=/, /\A\*=/, /\A\/=/, /\A%=/, /\A&=/, /\A\|=/, /\A\^=/
+						@q << [$&, Token.new($&, file, lineno, col)]
+					when /\A::/, /\A==/, /\A!=/, /\A>=/, /\A<=/, /\A\->/, /\A\+\+/, /\A\-\-/
+						@q << [$&, Token.new($&, file, lineno, col)]
+					when /\A\|\|/, /\A\&\&/
+						@q << [$&, Token.new($&, file, lineno, col)]
+					when /\A./
+						@q << [$&, Token.new($&, file, lineno, col)]
+					else
+						raise
+					end
+				end
+
+				line = $'
+				col += $&.length
+			end
+
+			lineno += 1
+		}
+
+		rescue => evar
+			Generator.error( "B1002 while open or reading \'$1\'" , file )
+			print_exception( evar )
+		end
+	}
+
+	# 終了の印
+	@q << nil
+
+	@yydebug = true
+	do_parse
+
+	ensure
+		@@generator_nest -= 1
+		TECS_LANG::reset_kcode
+	end
+
+	end
+
+
+	def next_token
+		token = @q.shift
+
+		if token then
+			@@current_locale[@@generator_nest] = token[1].locale
+
+			case token[1].val
+			when ";", ":", ",", "(", ")", "{", "}"
+			set_no_type_name false
+			when ".", "->"
+			set_no_type_name true
+			end
+
+			# TYPE_NAME トークンへ置き換え
+			if @b_no_type_name == false
+				if token[0] == :IDENTIFIER && Namespace.is_typename?( token[1].val ) then
+					token[0] = :TYPE_NAME
+					locale = @@current_locale[@@generator_nest]
+#print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}: type_name'\n" )
+				end
+			end
+
+			if $debug then     # 070107 token 無効時ここを通さないようした (through 対応 -d の時に例外発生) 
+				locale = @@current_locale[@@generator_nest]
+				if token then
+					print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}'\n" )
+				else
+					print( "#{locale[0]}: line #{locale[1]} : EOF\n" )
+				end
+			end
+		end
+
+		token
+	end
+
+	def on_error(t, v, vstack)
+		if v == "$" then
+			Generator.error( "B1003 Unexpected EOF"  )
+		else
+			Generator.error( "B1004 syntax error near \'$1\'" , v.val )
+		end
+
+	end
+
+	def self.current_locale
+		@@current_locale[ @@generator_nest ]
+	end
+
+	@@n_error = 0
+	@@n_warning = 0
+	@@n_info = 0
+
+	# このメソッドは構文解析、意味解析からのみ呼出し可（コード生成でエラー発生は不適切）
+	def self.error( msg )
+		@@n_error += 1
+		locale = @@current_locale[ @@generator_nest ]
+
+		if locale then
+			Console.puts "#{locale[0]}:#{locale[1]}: error: #{msg}"
+		else
+			Console.puts "error: #{msg}"
+		end
+	end
+
+	# このメソッドは構文解析、意味解析からのみ呼出し可（コード生成でウォーニング発生は不適切）
+	def self.warning( msg )
+		@@n_warning += 1
+		locale = @@current_locale[ @@generator_nest ]
+		Console.puts "#{locale[0]}:#{locale[1]}: warning: #{msg}"
+	end
+
+	# このメソッドは構文解析、意味解析からのみ呼出し可
+	def self.info( msg )
+		@@n_info += 1
+		locale = @@current_locale[ @@generator_nest ]
+		Console.puts "#{locale[0]}:#{locale[1]}: info: #{msg}"
+	end
+
+	def self.get_n_error
+		@@n_error
+	end
+
+	def self.get_n_warning
+		@@n_warning
+	end
+
+	def self.get_nest
+		@@generator_nest
+	end
+
+	def set_no_type_name b_no_type_name
+		locale = @@current_locale[ @@generator_nest ]
+#print "b_no_type_name=#{b_no_type_name} #{locale[0]}: line #{locale[1]}\n"
+		@b_no_type_name = b_no_type_name
+	end
+
+---- footer
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/bnf.tab.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/bnf.tab.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/bnf.tab.rb	(revision 398)
@@ -0,0 +1,5206 @@
+#
+# DO NOT MODIFY!!!!
+# This file is automatically generated by Racc 1.4.14
+# from Racc grammer file "".
+#
+
+require 'racc/parser.rb'
+class Generator < Racc::Parser
+
+module_eval(<<'...end bnf.y.rb/module_eval...', 'bnf.y.rb', 1534)
+
+  RESERVED = {
+    # keyword
+    'namespace' => :NAMESPACE,
+    'signature' => :SIGNATURE,
+    'celltype' => :CELLTYPE,
+    'cell' => :CELL,
+    'attr' => :ATTRIBUTE,
+    'var' => :VAR,
+    'call' => :CALL,
+    'entry' => :ENTRY,
+    'composite' => :COMPOSITE,
+    'require' => :REQUIRE,
+    'factory' => :FACTORY,
+    'FACTORY' => :CTFACTORY,
+    'typedef' => :TYPEDEF,
+    'struct' => :STRUCT,
+    'region' => :REGION,
+    'import' => :IMPORT,
+    'import_C' => :IMPORT_C,
+    'generate' => :GENERATE,
+    '__tool_info__' => :TOOL_INFO,
+
+    # types
+    'void'    => :VOID,
+
+    'volatile'=> :VOLATILE,
+    'const'   => :CONST,
+
+    'signed'  => :SIGNED,
+    'unsigned'=> :UNSIGNED,
+
+    'int8_t'    => :INT8_T,
+    'int16_t'   => :INT16_T,
+    'int32_t'   => :INT32_T,
+    'int64_t'   => :INT64_T,
+    'int128_t'  => :INT128_T,
+    'uint8_t'   => :UINT8_T,
+    'uint16_t'  => :UINT16_T,
+    'uint32_t'  => :UINT32_T,
+    'uint64_t'  => :UINT64_T,
+    'uint128_t' => :UINT128_T,
+
+    'float32_t'   => :FLOAT32_T,
+    'double64_t'  => :DOUBLE64_T,
+    'bool_t'      => :BOOL_T,
+    'char_t'  => :CHAR_T,
+    'schar_t'  => :SCHAR_T,
+    'uchar_t'  => :UCHAR_T,
+
+    # unrecommened types
+    'int'     => :INT,
+#   'intptr'  => :INTPTR,
+    'short'   => :SHORT,
+    'long'    => :LONG,
+
+    # obsolete types
+    'char'    => :CHAR,
+#    'int8'    => :INT8,
+#    'int16'   => :INT16,
+#    'int32'   => :INT32,
+#    'int64'   => :INT64,
+#    'int128'  => :INT128,
+#    'float'   => :FLOAT,
+#    'double'  => :DOUBLE,
+#    'bool'    => :BOOL,
+
+    'enum'    => :ENUM,
+    'enum8'   => :ENUM8,
+    'enum16'  => :ENUM16,
+    'enum32'  => :ENUM32,
+    'enum64'  => :ENUM64,
+
+    'true'    => :TRUE,
+    'false'   => :FALSE,
+
+    'C_EXP'   => :C_EXP,
+
+    'Descriptor'   => :DESCRIPTOR,
+
+    # location information for TECSCDE
+    '__location_information__' => :__LOCATION_INFORMATION__,
+    '__cell__' => :__CELL__,
+    '__join__' => :__JOIN__,
+  }
+
+  # 指定子 '[]' 内でのみ使用できるキーワード
+  RESERVED2 = {
+    # specifier
+    'id' => :ID,
+
+    # signature
+    'callback' => :CALLBACK,
+    'context' => :CONTEXT,
+    'deviate' => :DEVIATE,
+
+    # celltype
+    'singleton' => :SINGLETON,
+    'idx_is_id' => :IDX_IS_ID,
+    'active' => :ACTIVE,
+
+    # port (entry)
+    'inline' => :INLINE,
+    'ref_desc' => :REF_DESC,   # call も可
+
+    # port (call)
+    'optional' => :OPTIONAL,
+    'dynamic' => :DYNAMIC,
+
+    # port (call), attribute
+    'omit' => :OMIT,
+
+    # attribute
+    'choice' => :CHOICE,
+
+    # cell
+    'allocator' => :ALLOCATOR,
+    'prototype' => :PROTOTYPE,
+    'restrict'  => :RESTRICT,
+
+    # FuncType
+    'oneway' => :ONEWAY,
+
+    # parameter (basic)
+    'in' => :IN,
+    'out' => :OUT,
+    'inout' => :INOUT,
+    'send' => :SEND,
+    'receive' => :RECEIVE,
+
+    # parameter 
+    'size_is' => :SIZE_IS,
+    'count_is' => :COUNT_IS,
+    'string' => :STRING,
+    'nullable' => :NULLABLE,
+
+    'through' => :THROUGH,
+    'in_through' => :IN_THROUGH,
+    'out_through' => :OUT_THROUGH,
+    'to_through' => :TO_THROUGH,
+
+    'node' => :NODE,
+    'linkunit' => :LINKUNIT ,
+    'domain' => :DOMAIN,
+    'class' => :CLASS,
+  }
+
+  # 再帰的なパーサのためのスタック
+  @@generator_nest = -1
+  @@generator_stack = []
+  @@current_locale = []
+
+  # import_C 中である
+  @@import_C = false
+
+  # すべての構文解析が完了した
+  @@b_end_all_parse = false
+
+  # tag なし struct
+  @@no_struct_tag_num = 0
+
+  def self.parse( file_name, plugin = nil, b_reuse = false )
+    # パーサインスタンスを生成(別パーサで読み込む)
+    parser = Generator.new
+
+    # plugin から import されている場合の plugin 設定
+    parser.set_plugin plugin
+
+    # reuse フラグを設定
+    parser.set_reuse b_reuse
+
+    # cdl をパース
+    parser.parse( [file_name] )
+
+    # 終期化　パーサスタックを戻す
+    parser.finalize
+  end
+
+  def finalize
+
+    # mikan Namespace.pop
+    Namespace.pop
+    Signature.pop
+    Celltype.pop
+    Cell.pop
+    CompositeCelltype.pop
+  end
+
+  def set_plugin( plugin )
+    @plugin = plugin
+  end
+
+  def self.get_plugin
+    if @@generator_stack[@@generator_nest] then
+      # tecsgen 引数の cdl が import される場合は nil
+      return @@generator_stack[@@generator_nest].get_plugin
+    else
+      return nil
+    end
+  end
+
+  def get_plugin
+    @plugin
+  end
+
+  def set_reuse( b_reuse )
+    @b_reuse = b_reuse
+  end
+
+  def self.is_reuse?
+    if @@generator_stack[@@generator_nest] then
+      # tecsgen 引数の cdl が import される場合は nil
+      return @@generator_stack[@@generator_nest].is_reuse?
+    else
+      return false
+    end
+  end
+
+  def is_reuse?
+    @b_reuse
+  end
+
+  def parse(files)
+
+    # mikan Namespace.push
+    Namespace.push
+    Signature.push
+    Celltype.push
+    Cell.push
+    CompositeCelltype.push
+
+    @@generator_nest += 1
+    @@generator_stack[@@generator_nest] = self
+    @in_specifier = false
+
+    begin
+
+      @q = []
+      b_in_comment = false
+      b_in_string = false
+
+      # euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策
+      TECS_LANG::set_kcode_binary
+
+      files.each {|file|
+        lineno = 1
+        begin
+          string = ""
+#2.0          IO.foreach(file) {|line|
+          TECSIO.foreach(file) {|line|
+            col = 1
+#            line.rstrip!         改行含む文字列を扱うようになったので、ここで空白を取り除けなくなった
+
+            until line.empty?
+
+              if b_in_comment
+                case line
+                  # コメント終了
+                when /\A\*\//
+                  b_in_comment = false
+                when /\A./
+                  ;
+                when /\s+/     # line.rstrip! を止めたため \n などの空白文字とまっちするルールが必要になった
+                  ;
+                end
+              elsif b_in_string
+                if line =~ /\A(?:[^"\\]|\\.)*"/
+                  string = "#{string}#{$&}"
+                  @q <<  [:STRING_LITERAL, Token.new(string, file, lineno, col)]
+                  b_in_string = false
+                elsif line =~ /\A.*\\\n/     # 改行 \n は '.' にマッチしない
+                  string += $&
+                elsif line =~ /\A.*\n/     # 改行 \n は '.' にマッチしない
+                  string += line
+                  # この位置では error メソッドは使えない (token 読出し前)
+                  puts "#{file}:#{lineno}:#{col}: error: string literal has newline without escape"
+                  @@n_error += 1
+                end
+              else
+                case line
+                # 空白、プリプロセスディレクティブ
+                when /\A\s+/
+                  ;
+                # 識別子
+                when /\A[a-zA-Z_]\w*/
+                  word = $&
+                  @q << [RESERVED[word] || :IDENTIFIER, Token.new(word.intern, file, lineno, col)]
+                # 16 進数定数
+                when /\A0x[0-9A-Fa-f]+/
+                  @q << [:HEX_CONSTANT, Token.new($&, file, lineno, col)]
+                # 8 進数定数
+                when /\A0[0-7]+/
+                  @q << [:OCTAL_CONSTANT, Token.new($&, file, lineno, col)]
+                # 浮動小数定数
+                when /\A[0-9]+\.([0-9]*)?([Ee][+-]?[0-9]+)?/
+                  @q << [:FLOATING_CONSTANT, Token.new($&, file, lineno, col)]
+                # 整数定数
+                when /\A\d+/
+                  @q << [:INTEGER_CONSTANT, Token.new($&.to_i, file, lineno, col)]
+                # 文字定数
+                when /\A'(?:[^'\\]|\\.)'/
+                  @q << [:CHARACTER_LITERAL, Token.new($&, file, lineno, col)]
+                # 文字列
+#                "#include  #include #include \"../systask/logtask.cfg\"       最後の " 忘れ)で無限ループ
+#                when /\A"(?:[^"\\]+|\\.)*"/
+                when /\A"(?:[^"\\]|\\.)*"/   # これはうまく行くようだ
+                  @q << [:STRING_LITERAL, Token.new($&, file, lineno, col)]
+                # 文字列 (改行あり)
+                when /\A"(?:[^"\\]|\\.)*\\\n$/
+                  string = $&
+                  b_in_string = true
+                # 文字列 (改行あり, escape なし)
+                when /\A("(?:[^"\\]|\e\.)*)\n$/
+                  string = $1 + "\\\n"
+                  b_in_string = true
+                  # この位置では error メソッドは使えない (token 読出し前) # mikan cdl_error ではない
+                  puts "#{file}:#{lineno}:#{col}: error: string literal has newline without escape"
+                  @@n_error += 1
+                # 山括弧で囲まれた文字列
+                # when /\A<[0-9A-Za-z_\. \/]+>/   # AB: angle bracke
+                when /\A<(?:[^>\\]|\\.)*>/   # これはうまく行くようだ
+                  @q << [:AB_STRING_LITERAL, Token.new($&, file, lineno, col)]
+                # 行コメント
+                when /\A\/\/.*$/
+                  # 読み飛ばすだけ
+                # コメント開始
+                when /\A\/\*/
+                  b_in_comment = true
+                # '>>', '<<' など
+                when /\A>>/, /\A<</, /\A==/, /\A!=/, /\A\&\&/, /\A\|\|/
+                  @q << [$&, Token.new($&, file, lineno, col)]
+                when /\A::/, /\A=>/, /\A<=/, /\A>=/
+                  @q << [$&, Token.new($&, file, lineno, col)]
+                # '(', ')' など一文字の記号、または未知の記号
+                when /\A./
+                  @q << [$&, Token.new($&, file, lineno, col)]
+                else
+                  raise
+                end
+              end
+
+              line = $'
+              col += $&.length
+            end
+
+            lineno += 1
+          }
+
+        rescue => evar
+          Generator.error( "G1014 while open or reading \'$1\'" , file )
+          if $debug then
+            p puts( evar )
+            pp $@
+          end
+        end
+      }
+
+      # 終了の印
+      @q << nil
+
+      @yydebug = true
+      do_parse
+
+    ensure
+      @@generator_nest -= 1
+      TECS_LANG::reset_kcode
+    end
+
+  end
+
+  def next_token
+    token = @q.shift
+
+    if token then
+      @@current_locale[@@generator_nest] = token[1].locale
+
+      if token[0] == :IDENTIFIER then
+        # TYPE_NAME トークンへ置換え
+        if Namespace.is_typename?( token[1].val ) then
+          token[0] = :TYPE_NAME
+        elsif @in_specifier && RESERVED2[ token[1].val.to_s ] then
+          # 指定子キーワード（ '[', ']' 内でのみ有効)
+          token[0] = RESERVED2[ token[1].val.to_s ]
+        end
+      end
+
+      if $debug then     # 070107 token 無効時ここを通さないようした (through 対応 -d の時に例外発生) 
+        locale = @@current_locale[@@generator_nest]
+        if token then
+          print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}'\n" )
+        else
+          print( "#{locale[0]}: line #{locale[1]} : EOF\n" )
+        end
+      end
+    else
+      token = [ false, false ]
+    end
+
+    token
+  end
+
+  def on_error(t, v, vstack)
+    # p t, token_to_str(t), vstack
+    if token_to_str(t) == "$end" then
+      Generator.error( "G1015 Unexpected EOF"  )
+    else
+      Generator.error( "G1016 syntax error near \'$1\'" , v.val )
+    end
+  end
+
+  def self.current_locale
+    @@current_locale[ @@generator_nest ]
+  end
+
+  @@n_error = 0
+  @@n_warning = 0
+  @@n_info = 0
+
+  # このメソッドは構文解析、意味解析からのみ呼出し可（コード生成でエラー発生は不適切）
+  def self.error( msg, *arg )
+    locale = nil
+    self.error2( locale, msg, *arg )
+  end
+
+  def self.error2( locale, msg, *arg )
+    @@n_error += 1
+
+    msg = TECSMsg.get_error_message( msg )
+    # $1, $2, ... を arg で置換
+    count = 1
+    arg.each{ |a|
+      str = TECSIO.str_code_convert( msg, a.to_s )
+      msg.sub!( /\$#{count}/, str )
+      count += 1
+    }
+
+    # import_C の中でのエラー？
+    if @@import_C then
+      C_parser.error( msg )
+    else
+
+      # Node の記憶する 位置 (locale) を使用した場合、変更以前に比べ、
+      # 問題発生箇所と異なる位置にエラーが出るため、構文解析中のエラー
+      # は、解析中の位置を出力する．(new_XXX で owner が子要素のチェッ
+      # クをすると owner の行番号が出てしまう点で、ずれが生じている)
+
+      if @@b_end_all_parse == false || locale == nil then
+        locale = @@current_locale[ @@generator_nest ]
+      end
+      if locale then
+        Console.puts "#{locale[0]}:#{locale[1]}:#{locale[2]}: error: #{msg}"
+      else
+        Console.puts "error: #{msg}"
+      end
+    end
+  end
+
+  # このメソッドは構文解析、意味解析からのみ呼出し可（コード生成でウォーニング発生は不適切）
+  def self.warning( msg, *arg )
+    locale = nil
+    self.warning2( locale, msg, *arg )
+  end
+
+  def self.warning2( locale, msg, *arg )
+    @@n_warning += 1
+
+    msg = TECSMsg.get_warning_message( msg )
+    # $1, $2, ... を arg で置換
+    count = 1
+    arg.each{ |a|
+      str = TECSIO.str_code_convert( msg, a.to_s )
+      msg.sub!( /\$#{count}/, str )
+      count += 1
+    }
+
+    # import_C の中でのウォーニング？
+    if @@import_C then
+      C_parser.warning( msg )
+    else
+      if @@b_end_all_parse == false || locale == nil then
+        locale = @@current_locale[ @@generator_nest ]
+      end
+      if locale then
+        Console.puts "#{locale[0]}:#{locale[1]}:#{locale[2]}: warning: #{msg}"
+      else
+        Console.puts "warning: #{msg}"
+      end
+    end
+  end
+
+  # このメソッドは構文解析、意味解析からのみ呼出し可
+  def self.info( msg, *arg )
+    locale = nil
+    self.info2( locale, msg, *arg )
+  end
+
+  def self.info2( locale, msg, *arg )
+    @@n_info += 1
+
+    msg = TECSMsg.get_info_message( msg )
+    # $1, $2, ... を arg で置換
+    count = 1
+    arg.each{ |a|
+      str = TECSIO.str_code_convert( msg, a.to_s )
+      msg.sub!( /\$#{count}/, str )
+      count += 1
+    }
+
+    # import_C の中でのウォーニング？
+    if @@import_C then
+      C_parser.info( msg )
+    else
+      if @@b_end_all_parse == false || locale == nil then
+        locale = @@current_locale[ @@generator_nest ]
+      end
+      if locale then
+        Console.puts "#{locale[0]}:#{locale[1]}:#{locale[2]}: info: #{msg}"
+      else
+        Console.puts "info: #{msg}"
+      end
+    end
+  end
+
+  def self.get_n_error
+    @@n_error
+  end
+
+  def self.get_n_warning
+    @@n_warning
+  end
+
+  def self.get_n_info
+    @@n_info
+  end
+
+  def self.get_nest
+    @@generator_nest
+  end
+
+  def self.parsing_C?
+    @@import_C
+  end
+
+  #===  '[' specifier 始め
+  def set_in_specifier
+    # p "set_in_specifier"
+    @in_specifier = true
+  end
+
+  #=== ']' specifier 終わり
+  def unset_in_specifier
+    # p "unset_in_specifier"
+    @in_specifier = false
+  end
+
+  # statement_specifier は構文解釈途中で参照したいため
+  @@statement_specifier_stack = []
+  def self.add_statement_specifier( ss )
+    if( @@statement_specifier_stack[ @@generator_nest ] == nil )then
+      @@statement_specifier_stack[ @@generator_nest ] = [ ss ]
+    else
+      @@statement_specifier_stack[ @@generator_nest ] << ss
+    end
+  end
+
+
+  def self.get_statement_specifier
+    spec_list = @@statement_specifier_stack[ @@generator_nest ]
+    @@statement_specifier_stack[ @@generator_nest ] = nil
+    return spec_list
+  end
+
+  #=== すべての構文解析が完了したことを報告
+  def self.end_all_parse
+    @@b_end_all_parse = true
+  end
+
+...end bnf.y.rb/module_eval...
+##### State transition tables begin ###
+
+clist = [
+'66,575,328,559,538,815,78,330,869,328,78,78,78,409,199,200,201,202,203',
+'204,205,207,846,208,678,135,897,135,647,212,213,214,215,216,217,218',
+'249,679,177,872,870,408,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24',
+'25,26,27,28,29,30,31,32,33,34,35,38,465,189,693,333,334,42,43,44,45',
+'46,47,48,49,896,88,644,406,666,761,711,87,135,871,135,135,135,135,189',
+'66,189,189,70,68,69,135,71,72,328,73,78,74,304,305,324,860,901,189,407',
+'136,325,136,327,189,75,75,75,76,77,77,77,135,874,178,189,189,189,79',
+'875,101,80,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28',
+'29,30,31,32,33,34,35,38,78,364,365,256,899,42,43,44,45,46,47,48,49,189',
+'189,189,136,66,136,136,136,136,878,135,135,89,100,78,78,136,328,70,68',
+'69,399,71,72,135,73,877,74,304,305,324,135,446,135,478,868,325,479,327',
+'867,879,75,136,76,89,77,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24',
+'25,26,27,28,29,30,31,32,33,34,35,38,450,48,49,314,838,42,43,44,45,46',
+'47,48,49,135,135,839,135,66,304,305,306,135,307,308,310,311,691,838',
+'78,136,136,70,68,69,313,71,72,275,73,880,74,78,180,136,816,304,305,324',
+'78,881,136,136,136,325,75,327,76,690,77,5,6,7,10,13,14,15,16,17,18,19',
+'20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,38,835,426,403,282,697',
+'42,43,44,45,46,47,48,49,163,817,163,620,288,277,136,136,432,136,180',
+'504,78,150,136,654,149,720,70,68,69,283,71,72,403,73,402,74,520,636',
+'162,199,200,201,202,203,204,205,207,328,208,75,503,76,135,77,212,213',
+'214,215,216,217,218,304,305,306,859,307,308,310,311,199,200,201,202',
+'203,204,205,207,889,208,635,648,883,135,637,212,213,214,215,216,217',
+'218,884,858,681,199,200,201,202,203,204,205,207,341,208,342,888,343',
+'135,234,212,213,214,215,216,217,218,199,200,201,202,203,204,205,207',
+'682,208,885,668,235,135,661,212,213,214,215,216,217,218,88,789,790,691',
+'256,400,87,136,150,890,89,149,199,200,201,202,203,204,205,207,667,208',
+'891,660,163,135,776,212,213,214,215,216,217,218,794,255,401,136,199',
+'200,201,202,203,204,205,207,892,208,719,415,850,135,162,212,213,214',
+'215,216,217,218,887,898,136,902,886,582,721,903,581,833,199,200,201',
+'202,203,204,205,207,720,208,414,851,904,135,136,212,213,214,215,216',
+'217,218,199,200,201,202,203,204,205,207,832,208,722,698,826,135,906',
+'212,213,214,215,216,217,218,163,163,88,478,136,907,479,582,87,908,581',
+'607,89,163,3,163,88,910,827,699,699,81,87,352,353,234,89,797,170,770',
+'136,199,200,201,202,203,204,205,207,796,208,547,587,564,135,235,212',
+'213,214,215,216,217,218,90,199,200,201,202,203,204,205,207,136,208,394',
+'395,396,135,91,212,213,214,215,216,217,218,199,200,201,202,203,204,205',
+'207,136,208,394,395,396,135,92,212,213,214,215,216,217,218,199,200,201',
+'202,203,204,205,207,163,208,350,351,96,135,124,212,213,214,215,216,217',
+'218,594,336,125,199,200,201,202,203,204,205,207,126,208,130,510,132',
+'135,136,212,213,214,215,216,217,218,134,199,200,201,202,203,204,205',
+'207,140,208,352,353,142,135,136,212,213,214,215,216,217,218,199,200',
+'201,202,203,204,205,207,143,208,404,336,144,135,136,212,213,214,215',
+'216,217,218,199,200,201,202,203,204,205,207,147,208,358,359,155,135',
+'136,212,213,214,215,216,217,218,350,351,156,199,200,201,202,203,204',
+'205,207,159,208,350,351,160,135,136,212,213,214,215,216,217,218,164',
+'199,200,201,202,203,204,205,207,165,208,358,359,166,135,136,212,213',
+'214,215,216,217,218,199,200,201,202,203,204,205,207,167,208,630,437',
+'168,135,136,212,213,214,215,216,217,218,352,353,234,747,518,171,631',
+'287,288,436,438,439,440,441,136,347,629,172,347,173,348,349,235,348',
+'349,199,200,201,202,203,204,205,207,174,208,352,353,175,135,136,212',
+'213,214,215,216,217,218,176,199,200,201,202,203,204,205,207,180,208',
+'184,772,185,135,136,212,213,214,215,216,217,218,199,200,201,202,203',
+'204,205,207,454,208,145,146,186,135,136,212,213,214,215,216,217,218',
+'347,187,234,517,518,348,349,456,457,458,455,199,200,201,202,203,204',
+'205,207,454,208,188,235,189,135,191,212,213,214,215,216,217,218,354',
+'355,356,357,787,788,136,456,457,458,455,354,355,356,357,199,200,201',
+'202,203,204,205,207,437,208,382,383,384,135,136,212,213,214,215,216',
+'217,218,377,378,379,380,381,385,436,438,439,440,441,304,305,306,136',
+'307,308,310,311,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27',
+'28,29,30,31,32,33,34,35,38,136,354,355,356,357,42,43,44,45,46,47,48',
+'49,199,200,201,202,203,204,205,207,192,208,352,353,193,135,196,212,213',
+'214,215,216,217,218,247,89,136,199,200,201,202,203,204,205,207,257,208',
+'159,264,208,135,270,212,213,214,215,216,217,218,199,200,201,202,203',
+'204,205,207,180,208,272,279,280,135,281,212,213,214,215,216,217,218',
+'234,284,285,286,289,290,199,200,201,202,203,204,205,207,312,208,335',
+'189,336,135,235,212,213,214,215,216,217,218,360,199,200,201,202,203',
+'204,205,207,136,208,361,670,362,135,363,212,213,214,215,216,217,218',
+'199,200,201,202,203,204,205,207,368,208,369,136,371,135,372,212,213',
+'214,215,216,217,218,159,199,200,201,202,203,204,205,207,405,208,136',
+'587,410,135,142,212,213,214,215,216,217,218,412,413,199,200,201,202',
+'203,204,205,207,416,208,417,418,419,135,136,212,213,214,215,216,217',
+'218,420,199,200,201,202,203,204,205,207,421,208,444,445,448,135,136',
+'212,213,214,215,216,217,218,199,200,201,202,203,204,205,207,459,208',
+'462,772,463,135,136,212,213,214,215,216,217,218,470,88,234,88,382,383',
+'384,87,472,87,473,89,474,89,481,136,377,378,379,380,381,385,235,482',
+'208,199,200,201,202,203,204,205,207,511,208,512,513,514,135,136,212',
+'213,214,215,216,217,218,515,199,200,201,202,203,204,205,207,521,208',
+'522,523,264,135,136,212,213,214,215,216,217,218,199,200,201,202,203',
+'204,205,207,525,208,270,528,529,135,136,212,213,214,215,216,217,218',
+'199,200,201,202,203,204,205,207,208,208,532,208,208,135,180,212,213',
+'214,215,216,217,218,536,537,540,199,200,201,202,203,204,205,207,541',
+'208,542,544,545,135,136,212,213,214,215,216,217,218,737,738,740,741',
+'548,189,270,558,562,196,739,737,738,740,741,136,565,189,743,742,196',
+'739,234,592,569,88,88,571,88,743,742,87,87,88,87,89,89,136,89,87,328',
+'574,235,89,196,199,200,201,202,203,204,205,207,589,208,590,700,360,135',
+'136,212,213,214,215,216,217,218,361,362,472,199,200,201,202,203,204',
+'205,207,363,208,472,591,607,135,136,212,213,214,215,216,217,218,199',
+'200,201,202,203,204,205,207,608,208,611,336,612,135,614,212,213,214',
+'215,216,217,218,199,200,201,202,203,204,205,207,615,208,616,617,618',
+'135,208,212,213,214,215,216,217,218,621,737,738,740,741,163,625,88,88',
+'641,196,739,785,87,87,136,643,89,89,743,742,625,662,663,669,674,199',
+'200,201,202,203,204,205,207,675,208,676,680,683,135,136,212,213,214',
+'215,216,217,218,199,200,201,202,203,204,205,207,685,208,686,687,688',
+'135,136,212,213,214,215,216,217,218,472,104,105,106,107,108,109,110',
+'111,112,113,114,689,189,136,692,208,695,704,5,6,7,10,13,14,15,16,17',
+'18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,38,163,706,707',
+'708,163,42,43,44,45,46,47,48,49,710,712,136,117,118,119,120,121,122',
+'123,199,200,201,202,203,204,205,207,713,208,714,715,718,135,136,212',
+'213,214,215,216,217,218,199,200,201,202,203,204,205,207,723,208,726',
+'571,75,135,729,212,213,214,215,216,217,218,199,200,201,202,203,204,205',
+'207,730,208,196,744,745,135,748,212,213,214,215,216,217,218,199,200',
+'201,202,203,204,205,207,749,208,752,753,754,135,756,212,213,214,215',
+'216,217,218,625,759,760,764,199,200,201,202,203,204,205,207,767,208',
+'771,779,780,135,136,212,213,214,215,216,217,218,199,200,201,202,203',
+'204,205,207,782,208,783,791,793,135,136,212,213,214,215,216,217,218',
+'199,200,201,202,203,204,205,207,189,208,795,798,799,135,136,212,213',
+'214,215,216,217,218,199,200,201,202,203,204,205,207,800,208,803,804',
+'805,135,136,212,213,214,215,216,217,218,806,654,718,180,199,200,201',
+'202,203,204,205,207,811,208,812,813,814,135,136,212,213,214,215,216',
+'217,218,199,200,201,202,203,204,205,207,726,208,823,828,831,135,136',
+'212,213,214,215,216,217,218,199,200,201,202,203,204,205,207,836,208',
+'840,841,-386,135,136,212,213,214,215,216,217,218,199,200,201,202,203',
+'204,205,207,842,208,843,237,844,135,136,212,213,214,215,216,217,218',
+'848,803,208,854,199,200,201,202,203,204,205,207,857,208,862,863,865',
+'135,136,212,213,214,215,216,217,218,199,200,201,202,203,204,205,207',
+',208,,,,135,136,212,213,214,215,216,217,218,199,200,201,202,203,204',
+'205,207,,208,,,,135,136,212,213,214,215,216,217,218,199,200,201,202',
+'203,204,205,207,,208,,,,135,136,212,213,214,215,216,217,218,88,,,,,',
+'87,,,88,89,737,738,740,741,87,,,136,89,196,739,,,,234,,,,743,742,117',
+'118,119,120,121,122,123,,,136,,,,,235,,,199,200,201,202,203,204,205',
+'207,,208,,,,135,136,212,213,214,215,216,217,218,199,200,201,202,203',
+'204,205,207,,208,472,,,135,136,212,213,214,215,216,217,218,199,200,201',
+'202,203,204,205,345,,208,,,,135,,212,213,214,215,216,217,218,199,200',
+'201,202,203,204,205,207,,208,,,,135,,212,213,214,215,216,217,218,,,',
+'104,105,106,107,108,109,110,111,112,113,114,,,,,136,,,,,,,104,105,106',
+'107,108,109,110,111,112,113,114,,,,,136,117,118,119,120,121,122,123',
+',,,478,585,,584,,,,,,,89,136,117,118,119,120,121,122,123,20,21,22,23',
+'24,25,26,27,28,29,30,31,32,33,136,5,6,7,10,13,14,15,16,17,18,19,20,21',
+'22,23,24,25,26,27,28,29,30,31,32,33,34,35,38,672,,78,,,42,43,44,45,46',
+'47,48,49,,,,,,,,,,,,,,,,,,,,,5,6,7,10,13,14,15,16,17,18,19,20,21,22',
+'23,24,25,26,27,28,29,30,31,32,33,34,35,38,241,,78,,,42,43,44,45,46,47',
+'48,49,,,,,,,,,,,,,,,,,,,,,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23',
+'24,25,26,27,28,29,30,31,32,33,34,35,38,78,,,,,42,43,44,45,46,47,48,49',
+',,,,,,,,,,,,,,,,,,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26',
+'27,28,29,30,31,32,33,34,35,38,78,,,,,42,43,44,45,46,47,48,49,506,,,',
+',,,,,,,,,,,,,,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27',
+'28,29,30,31,32,33,34,35,38,78,428,,,,42,43,44,45,46,47,48,49,,,,,,,',
+',,,,,,,,,,,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28',
+'29,30,31,32,33,34,35,38,78,,,,,42,43,44,45,46,47,48,49,,,,,,,,,,,,,',
+',,,,,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30',
+'31,32,33,34,35,38,78,,,,,42,43,44,45,46,47,48,49,,,,,,,,,,,,,,,,,,,5',
+'6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33',
+'34,35,38,78,632,,,,42,43,44,45,46,47,48,49,,,,,,,,,,,,,,,,,,,5,6,7,10',
+'13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35',
+'38,78,638,,,,42,43,44,45,46,47,48,49,,,,,,,,,,,,,,,,,,,5,6,7,10,13,14',
+'15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,38,128',
+'658,,,,42,43,44,45,46,47,48,49,,,,,,,,,,,,,,,,,,,5,6,7,10,13,14,15,16',
+'17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,38,78,,,,,42',
+'43,44,45,46,47,48,49,,,,,,,,,,,,,,,,,,,5,6,7,10,13,14,15,16,17,18,19',
+'20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,38,78,516,,,,42,43,44',
+'45,46,47,48,49,,,,,,,,,,,,,,,,,,,5,6,7,10,13,14,15,16,17,18,19,20,21',
+'22,23,24,25,26,27,28,29,30,31,32,33,34,35,38,78,,,,,42,43,44,45,46,47',
+'48,49,,,,,,,,,,,,,,,,,,,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24',
+'25,26,27,28,29,30,31,32,33,34,35,38,78,387,,,,42,43,44,45,46,47,48,49',
+',,,,,,,,,,,,,,,,,,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26',
+'27,28,29,30,31,32,33,34,35,38,78,,,,,42,43,44,45,46,47,48,49,,,,,,,',
+',,,,,,,,,,,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28',
+'29,30,31,32,33,34,35,38,,,,,,42,43,44,45,46,47,48,49,5,6,7,10,13,14',
+'15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,38,,',
+',,,42,43,44,45,46,47,48,49,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23',
+'24,25,26,27,28,29,30,31,32,33,34,35,38,,,,,,42,43,44,45,46,47,48,49',
+'5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32',
+'33,34,35,38,,,,,,42,43,44,45,46,47,48,49,5,6,7,10,13,14,15,16,17,18',
+'19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,38,,,,,,42,43,44',
+'45,46,47,48,49,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27',
+'28,29,30,31,32,33,34,35,38,,,,,,42,43,44,45,46,47,48,49,5,6,7,10,13',
+'14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,38',
+',,,,,42,43,44,45,46,47,48,49,5,6,7,10,13,14,15,16,17,18,19,20,21,22',
+'23,24,25,26,27,28,29,30,31,32,33,34,35,38,,,,,,42,43,44,45,46,47,48',
+'49,5,6,7,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31',
+'32,33,34,35,38,,,,,,42,43,44,45,46,47' ]
+        racc_action_table = arr = ::Array.new(3593, nil)
+        idx = 0
+        clist.each do |str|
+          str.split(',', -1).each do |i|
+            arr[idx] = i.to_i unless i.empty?
+            idx += 1
+          end
+        end
+
+clist = [
+'2,469,843,447,422,777,192,194,852,192,329,2,613,269,515,515,515,515',
+'515,515,515,515,824,515,596,325,893,515,560,515,515,515,515,515,515',
+'515,154,597,125,856,853,269,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2',
+'2,2,2,2,2,2,2,2,329,422,613,194,194,2,2,2,2,2,2,2,2,893,85,560,267,576',
+'703,642,85,721,855,631,558,528,511,447,161,777,469,2,2,2,92,2,2,563',
+'2,161,2,192,192,192,843,895,824,267,325,192,515,192,596,329,2,613,2',
+'329,2,613,75,860,125,856,154,597,2,861,41,2,161,161,161,161,161,161',
+'161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161',
+'161,161,161,161,161,187,230,230,258,895,161,161,161,161,161,161,161',
+'161,576,703,642,721,185,631,558,528,511,866,691,303,89,41,315,185,92',
+'315,161,161,161,258,161,161,333,161,863,161,563,563,563,286,308,782',
+'340,851,563,340,563,851,866,161,75,161,340,161,185,185,185,185,185,185',
+'185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185',
+'185,185,185,185,185,315,89,89,190,869,185,185,185,185,185,185,185,185',
+'839,470,812,692,291,187,187,187,512,187,187,187,187,609,812,291,691',
+'303,185,185,185,190,185,185,171,185,872,185,778,171,333,778,315,315',
+'315,294,873,286,308,782,315,185,315,185,609,185,291,291,291,291,291',
+'291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291',
+'291,291,291,291,291,291,808,291,625,176,625,291,291,291,291,291,291',
+'291,291,392,778,573,539,539,172,839,470,294,692,172,366,561,86,512,561',
+'86,808,291,291,291,176,291,291,264,291,264,291,392,553,573,720,720,720',
+'720,720,720,720,720,874,720,291,366,291,720,291,720,720,720,720,720',
+'720,720,294,294,294,841,294,294,294,294,902,902,902,902,902,902,902',
+'902,880,902,553,561,876,902,553,902,902,902,902,902,902,902,877,841',
+'599,889,889,889,889,889,889,889,889,210,889,210,880,210,889,720,889',
+'889,889,889,889,889,889,521,521,521,521,521,521,521,521,599,521,878',
+'577,720,521,568,521,521,521,521,521,521,521,430,743,743,751,157,262',
+'430,720,148,881,430,148,522,522,522,522,522,522,522,522,577,522,882',
+'568,102,522,720,522,522,522,522,522,522,522,751,157,262,902,523,523',
+'523,523,523,523,523,523,883,523,653,278,834,523,102,523,523,523,523',
+'523,523,523,879,894,889,897,879,580,653,898,580,801,234,234,234,234',
+'234,234,234,234,653,234,278,834,901,234,521,234,234,234,234,234,234',
+'234,166,166,166,166,166,166,166,166,801,166,657,626,784,166,904,166',
+'166,166,166,166,166,166,115,716,518,476,522,905,476,477,518,906,477',
+'756,518,434,1,452,127,909,784,657,626,3,127,494,494,234,127,756,115',
+'716,523,479,479,479,479,479,479,479,479,756,479,434,479,452,479,234',
+'479,479,479,479,479,479,479,8,358,358,358,358,358,358,358,358,234,358',
+'520,520,520,358,9,358,358,358,358,358,358,358,363,363,363,363,363,363',
+'363,363,166,363,254,254,254,363,16,363,363,363,363,363,363,363,360,360',
+'360,360,360,360,360,360,375,360,222,222,38,360,68,360,360,360,360,360',
+'360,360,505,505,69,361,361,361,361,361,361,361,361,70,361,72,375,73',
+'361,479,361,361,361,361,361,361,361,74,682,682,682,682,682,682,682,682',
+'76,682,223,223,77,682,358,682,682,682,682,682,682,682,862,862,862,862',
+'862,862,862,862,79,862,265,265,80,862,363,862,862,862,862,862,862,862',
+'362,362,362,362,362,362,362,362,84,362,225,225,94,362,360,362,362,362',
+'362,362,362,362,489,489,95,797,797,797,797,797,797,797,797,100,797,490',
+'490,101,797,361,797,797,797,797,797,797,797,104,811,811,811,811,811',
+'811,811,811,106,811,497,497,108,811,682,811,811,811,811,811,811,811',
+'838,838,838,838,838,838,838,838,110,838,549,297,114,838,862,838,838',
+'838,838,838,838,838,491,491,797,684,684,117,549,181,181,297,297,297',
+'297,297,362,487,549,118,221,119,487,487,797,221,221,796,796,796,796',
+'796,796,796,796,122,796,492,492,123,796,797,796,796,796,796,796,796',
+'796,124,835,835,835,835,835,835,835,835,126,835,128,835,129,835,811',
+'835,835,835,835,835,835,835,514,514,514,514,514,514,514,514,318,514',
+'82,82,131,514,838,514,514,514,514,514,514,514,488,133,796,389,389,488',
+'488,318,318,318,318,823,823,823,823,823,823,823,823,564,823,136,796',
+'137,823,138,823,823,823,823,823,823,823,495,495,495,495,742,742,796',
+'564,564,564,564,224,224,224,224,207,207,207,207,207,207,207,207,547',
+'207,510,510,510,207,835,207,207,207,207,207,207,207,510,510,510,510',
+'510,510,547,547,547,547,547,546,546,546,514,546,546,546,546,207,207',
+'207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207',
+'207,207,207,207,207,207,207,207,207,823,496,496,496,496,207,207,207',
+'207,207,207,207,207,748,748,748,748,748,748,748,748,139,748,493,493',
+'141,748,144,748,748,748,748,748,748,748,151,152,207,859,859,859,859',
+'859,859,859,859,159,859,160,164,165,859,167,859,859,859,859,859,859',
+'859,575,575,575,575,575,575,575,575,168,575,169,173,174,575,175,575',
+'575,575,575,575,575,575,748,177,178,179,183,184,257,257,257,257,257',
+'257,257,257,189,257,195,198,206,257,748,257,257,257,257,257,257,257',
+'226,581,581,581,581,581,581,581,581,748,581,227,581,228,581,229,581',
+'581,581,581,581,581,581,729,729,729,729,729,729,729,729,235,729,236',
+'859,240,729,242,729,729,729,729,729,729,729,256,584,584,584,584,584',
+'584,584,584,266,584,575,584,271,584,272,584,584,584,584,584,584,584',
+'274,276,147,147,147,147,147,147,147,147,280,147,281,282,283,147,257',
+'147,147,147,147,147,147,147,284,591,591,591,591,591,591,591,591,285',
+'591,306,307,309,591,581,591,591,591,591,591,591,591,719,719,719,719',
+'719,719,719,719,324,719,326,719,327,719,729,719,719,719,719,719,719',
+'719,334,288,147,602,246,246,246,288,335,602,337,288,338,602,342,584',
+'246,246,246,246,246,246,147,343,368,714,714,714,714,714,714,714,714',
+'380,714,381,382,383,714,147,714,714,714,714,714,714,714,384,710,710',
+'710,710,710,710,710,710,394,710,395,396,401,710,591,710,710,710,710',
+'710,710,710,706,706,706,706,706,706,706,706,402,706,407,408,409,706',
+'719,706,706,706,706,706,706,706,504,504,504,504,504,504,504,504,410',
+'504,411,412,413,504,414,504,504,504,504,504,504,504,416,419,425,365',
+'365,365,365,365,365,365,365,426,365,428,431,432,365,714,365,365,365',
+'365,365,365,365,827,827,827,827,437,442,443,446,450,827,827,783,783',
+'783,783,710,454,460,827,827,783,783,504,504,461,4,696,462,373,783,783',
+'4,696,146,373,4,696,706,373,146,463,465,504,146,472,630,630,630,630',
+'630,630,630,630,480,630,483,630,498,630,504,630,630,630,630,630,630',
+'630,499,500,827,364,364,364,364,364,364,364,364,501,364,783,502,525',
+'364,365,364,364,364,364,364,364,364,908,908,908,908,908,908,908,908',
+'526,908,529,530,531,908,533,908,908,908,908,908,908,908,341,341,341',
+'341,341,341,341,341,534,341,535,536,537,341,538,341,341,341,341,341',
+'341,341,543,739,739,739,739,544,548,88,424,557,739,739,739,88,424,630',
+'559,88,424,739,739,565,570,572,578,583,347,347,347,347,347,347,347,347',
+'586,347,588,598,600,347,364,347,347,347,347,347,347,347,345,345,345',
+'345,345,345,345,345,604,345,605,606,607,345,908,345,345,345,345,345',
+'345,345,739,162,162,162,162,162,162,162,162,162,162,162,608,610,341',
+'611,616,619,632,345,345,345,345,345,345,345,345,345,345,345,345,345',
+'345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,634,636',
+'637,638,640,345,345,345,345,345,345,345,345,641,643,347,260,260,260',
+'260,260,260,260,348,348,348,348,348,348,348,348,644,348,646,648,651',
+'348,345,348,348,348,348,348,348,348,349,349,349,349,349,349,349,349',
+'658,349,662,663,664,349,665,349,349,349,349,349,349,349,350,350,350',
+'350,350,350,350,350,666,350,668,671,673,350,688,350,350,350,350,350',
+'350,350,351,351,351,351,351,351,351,351,689,351,693,694,695,351,697',
+'351,351,351,351,351,351,351,699,700,701,707,352,352,352,352,352,352',
+'352,352,711,352,718,725,727,352,348,352,352,352,352,352,352,352,353',
+'353,353,353,353,353,353,353,730,353,731,746,749,353,349,353,353,353',
+'353,353,353,353,354,354,354,354,354,354,354,354,750,354,755,760,761',
+'354,350,354,354,354,354,354,354,354,355,355,355,355,355,355,355,355',
+'763,355,764,766,767,355,351,355,355,355,355,355,355,355,768,769,770',
+'771,356,356,356,356,356,356,356,356,772,356,773,775,776,356,352,356',
+'356,356,356,356,356,356,357,357,357,357,357,357,357,357,780,357,781',
+'793,799,357,353,357,357,357,357,357,357,357,359,359,359,359,359,359',
+'359,359,810,359,814,815,816,359,354,359,359,359,359,359,359,359,149',
+'149,149,149,149,149,149,149,817,149,821,149,822,149,355,149,149,149',
+'149,149,149,149,828,833,836,837,474,474,474,474,474,474,474,474,840',
+'474,845,846,850,474,356,474,474,474,474,474,474,474,290,290,290,290',
+'290,290,290,290,,290,,,,290,357,290,290,290,290,290,290,290,848,848',
+'848,848,848,848,848,848,,848,,,,848,359,848,848,848,848,848,848,848',
+'806,806,806,806,806,806,806,806,,806,,,,806,149,806,806,806,806,806',
+'806,806,245,,,,,,245,,,253,245,669,669,669,669,253,,,474,253,669,669',
+',,,848,,,,669,669,170,170,170,170,170,170,170,,,290,,,,,848,,,403,403',
+'403,403,403,403,403,403,,403,,,,403,848,403,403,403,403,403,403,403',
+'513,513,513,513,513,513,513,513,,513,669,,,513,806,513,513,513,513,513',
+'513,513,212,212,212,212,212,212,212,212,,212,,,,212,,212,212,212,212',
+'212,212,212,211,211,211,211,211,211,211,211,,211,,,,211,,211,211,211',
+'211,211,211,211,,,,464,464,464,464,464,464,464,464,464,464,464,,,,,403',
+',,,,,,54,54,54,54,54,54,54,54,54,54,54,,,,,513,464,464,464,464,464,464',
+'464,,,,478,478,,478,,,,,,,478,212,54,54,54,54,54,54,54,36,36,36,36,36',
+'36,36,36,36,36,36,36,36,36,211,478,478,478,478,478,478,478,478,478,478',
+'478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478',
+'478,582,,582,,,478,478,478,478,478,478,478,478,,,,,,,,,,,,,,,,,,,,,582',
+'582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582',
+'582,582,582,582,582,582,582,582,582,582,150,,150,,,582,582,582,582,582',
+'582,582,582,,,,,,,,,,,,,,,,,,,,,150,150,150,150,150,150,150,150,150',
+'150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150',
+'150,150,372,,,,,150,150,150,150,150,150,150,150,,,,,,,,,,,,,,,,,,,372',
+'372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372',
+'372,372,372,372,372,372,372,372,372,372,293,,,,,372,372,372,372,372',
+'372,372,372,372,,,,,,,,,,,,,,,,,,293,293,293,293,293,293,293,293,293',
+'293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293',
+'293,293,444,293,,,,293,293,293,293,293,293,293,293,,,,,,,,,,,,,,,,,',
+',444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444',
+'444,444,444,444,444,444,444,444,444,444,444,445,,,,,444,444,444,444',
+'444,444,444,444,,,,,,,,,,,,,,,,,,,445,445,445,445,445,445,445,445,445',
+'445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445',
+'445,445,550,,,,,445,445,445,445,445,445,445,445,,,,,,,,,,,,,,,,,,,550',
+'550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550',
+'550,550,550,550,550,550,550,550,550,550,554,550,,,,550,550,550,550,550',
+'550,550,550,,,,,,,,,,,,,,,,,,,554,554,554,554,554,554,554,554,554,554',
+'554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554',
+'554,566,554,,,,554,554,554,554,554,554,554,554,,,,,,,,,,,,,,,,,,,566',
+'566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566',
+'566,566,566,566,566,566,566,566,566,566,71,566,,,,566,566,566,566,566',
+'566,566,566,,,,,,,,,,,,,,,,,,,71,71,71,71,71,71,71,71,71,71,71,71,71',
+'71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,386,,,,,71,71,71,71,71',
+'71,71,71,,,,,,,,,,,,,,,,,,,386,386,386,386,386,386,386,386,386,386,386',
+'386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386',
+'459,386,,,,386,386,386,386,386,386,386,386,,,,,,,,,,,,,,,,,,,459,459',
+'459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459',
+'459,459,459,459,459,459,459,459,459,251,,,,,459,459,459,459,459,459',
+'459,459,,,,,,,,,,,,,,,,,,,251,251,251,251,251,251,251,251,251,251,251',
+'251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251',
+'250,251,,,,251,251,251,251,251,251,251,251,,,,,,,,,,,,,,,,,,,250,250',
+'250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250',
+'250,250,250,250,250,250,250,250,250,156,,,,,250,250,250,250,250,250',
+'250,250,,,,,,,,,,,,,,,,,,,156,156,156,156,156,156,156,156,156,156,156',
+'156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156',
+',,,,,156,156,156,156,156,156,156,156,622,622,622,622,622,622,622,622',
+'622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622,622',
+'622,622,622,,,,,,622,622,622,622,622,622,622,622,40,40,40,40,40,40,40',
+'40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,,,,,',
+'40,40,40,40,40,40,40,40,705,705,705,705,705,705,705,705,705,705,705',
+'705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705',
+',,,,,705,705,705,705,705,705,705,705,244,244,244,244,244,244,244,244',
+'244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244',
+'244,244,244,,,,,,244,244,244,244,244,244,244,244,519,519,519,519,519',
+'519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519',
+'519,519,519,519,519,519,,,,,,519,519,519,519,519,519,519,519,709,709',
+'709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709',
+'709,709,709,709,709,709,709,709,709,,,,,,709,709,709,709,709,709,709',
+'709,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289',
+'289,289,289,289,289,289,289,289,289,289,289,289,,,,,,289,289,289,289',
+'289,289,289,289,239,239,239,239,239,239,239,239,239,239,239,239,239',
+'239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,,,,,,239',
+'239,239,239,239,239' ]
+        racc_action_check = arr = ::Array.new(3593, nil)
+        idx = 0
+        clist.each do |str|
+          str.split(',', -1).each do |i|
+            arr[idx] = i.to_i unless i.empty?
+            idx += 1
+          end
+        end
+
+racc_action_pointer = [
+   nil,   613,    -1,   620,  1492,   nil,   nil,   nil,   612,   627,
+   nil,   nil,   nil,   nil,   nil,   nil,   680,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,  2268,   nil,   694,   nil,
+  3265,   123,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,  2185,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   702,   712,
+   721,  2888,   717,   719,   729,   115,   738,   742,   nil,   704,
+   770,   nil,   921,   nil,   755,    75,   359,   nil,  1610,   174,
+   nil,   nil,    89,   nil,   730,   742,   nil,   nil,   nil,   nil,
+   807,   755,   496,   nil,   827,   nil,   836,   nil,   840,   nil,
+   858,   nil,   nil,   nil,   862,   586,   nil,   877,   889,   891,
+   nil,   nil,   905,   909,   917,    27,   922,   606,   866,   870,
+   nil,   892,   nil,   903,   nil,   nil,   979,   888,   983,  1040,
+   nil,  1044,   nil,   nil,  1106,   nil,  1500,  1268,   484,  2000,
+  2416,  1115,  1107,   nil,    26,   nil,  3183,   448,   nil,  1094,
+  1123,    97,  1591,   nil,  1124,  1129,   575,  1127,  1143,  1031,
+  2017,   282,   350,  1146,  1147,  1149,   335,  1163,  1164,  1134,
+   nil,   848,   nil,  1163,  1168,   184,   nil,   156,   nil,  1171,
+   218,   nil,    -6,   nil,   -65,  1178,   nil,   nil,  1081,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,  1179,  1019,   nil,   nil,
+   437,  2228,  2206,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   880,   687,   729,   989,   767,  1182,  1177,  1178,  1179,
+   132,   nil,   nil,   nil,   553,  1222,  1220,   nil,   nil,  3511,
+  1225,   nil,  1196,   nil,  3347,  2107,  1268,   nil,   nil,   nil,
+  3124,  3065,   nil,  2116,   612,   nil,  1230,  1176,   130,   nil,
+  1615,   nil,   480,   nil,   367,   767,  1244,    76,   nil,    -1,
+   nil,  1217,  1245,   nil,  1227,   nil,  1228,   nil,   524,   nil,
+  1237,  1270,  1241,  1271,  1252,  1261,   197,   nil,  1329,  3470,
+  2048,   271,   nil,  2534,   291,   nil,   nil,   778,   nil,   nil,
+   nil,   nil,   nil,   177,   nil,   nil,  1232,  1233,   198,  1234,
+   nil,   nil,   nil,   nil,   nil,   183,   nil,   nil,   867,   nil,
+   nil,   nil,   nil,   nil,  1252,    10,  1197,  1313,   nil,    -2,
+   nil,   nil,   nil,   190,  1328,  1274,   nil,  1337,  1339,   nil,
+   206,  1588,  1336,  1345,   nil,  1658,   nil,  1636,  1750,  1772,
+  1794,  1816,  1842,  1864,  1886,  1908,  1934,  1956,   651,  1978,
+   695,   720,   787,   673,  1544,  1452,   325,   nil,  1350,   nil,
+   nil,   nil,  2475,  1495,   nil,   692,   nil,   nil,   nil,   nil,
+  1361,  1363,  1364,  1365,  1375,   nil,  2947,   nil,   nil,   936,
+   nil,   nil,   342,   nil,  1384,  1386,  1387,   nil,   nil,   nil,
+   nil,  1382,  1400,  2162,   nil,   nil,   nil,  1402,  1347,  1404,
+  1426,  1368,  1429,  1430,  1428,   nil,  1440,   nil,   nil,  1442,
+   nil,   nil,   -37,   nil,  1611,  1443,  1422,   nil,  1424,   nil,
+   476,  1355,  1426,   nil,   599,   nil,   nil,  1471,   nil,   nil,
+   nil,   nil,  1373,  1467,  2593,  2652,  1441,   -11,   nil,   nil,
+  1444,   nil,   601,   nil,  1483,   nil,   nil,   nil,   nil,  3006,
+  1385,  1485,  1488,  1501,  2163,  1477,   nil,   nil,   nil,    -8,
+   254,   nil,  1509,   nil,  2026,   nil,   593,   597,  2294,   628,
+  1516,   nil,   nil,  1521,   nil,   nil,   nil,   877,   954,   791,
+   804,   855,   890,  1087,   596,   978,  1063,   815,  1515,  1509,
+  1509,  1518,  1518,   nil,  1427,   709,   nil,   nil,   nil,   nil,
+   958,    81,   261,  2184,   949,    12,   nil,   nil,   592,  3388,
+   590,   461,   495,   521,   nil,  1544,  1563,   nil,    80,  1536,
+  1568,  1570,   nil,  1572,  1588,  1559,  1591,  1562,  1593,   318,
+   nil,   nil,   nil,  1572,  1604,   nil,   937,   937,  1603,   857,
+  2711,   nil,   nil,   310,  2770,   nil,   nil,  1547,    79,  1613,
+    13,   355,   nil,    92,   900,  1618,  2829,   nil,   437,   nil,
+  1620,   nil,  1507,   344,   nil,  1148,    73,   433,  1597,   nil,
+   541,  1199,  2355,  1627,  1244,   nil,  1636,   nil,  1635,   nil,
+   nil,  1291,   nil,   nil,   nil,   nil,    14,    27,  1639,   430,
+  1640,   nil,  1331,   nil,  1658,  1660,  1661,  1657,  1680,   240,
+  1587,  1626,   nil,     0,   nil,   nil,  1687,   nil,   nil,  1689,
+   nil,   nil,  3224,   nil,   nil,   332,   578,   nil,   nil,   nil,
+  1519,    78,  1660,   nil,  1716,   nil,  1721,  1689,  1692,   nil,
+  1720,  1733,    75,  1703,  1720,   nil,  1753,   nil,  1723,   nil,
+   nil,  1638,   nil,   521,   nil,   nil,   nil,   577,  1742,   nil,
+   nil,   nil,  1769,  1770,  1661,  1747,  1789,   nil,  1795,  2125,
+   nil,  1794,   nil,  1798,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   743,   nil,   844,   nil,   nil,   nil,  1768,  1811,
+   nil,   176,   256,  1788,  1819,  1790,  1493,  1817,   nil,  1825,
+  1801,  1829,   nil,    74,   nil,  3306,  1405,  1772,   nil,  3429,
+  1383,  1837,   nil,   nil,  1360,   nil,   587,   nil,  1845,  1313,
+   384,    76,   nil,   nil,   nil,  1815,   nil,  1842,   nil,  1221,
+  1746,  1837,   nil,   nil,   nil,   nil,   nil,   nil,   nil,  1611,
+   nil,   nil,  1006,   482,   nil,   nil,  1867,   nil,  1101,  1864,
+  1788,   447,   nil,   nil,   nil,  1858,   596,   nil,   nil,   nil,
+  1859,  1885,   nil,  1908,  1909,   nil,  1911,  1882,  1891,  1918,
+  1808,  1920,  1902,  1933,   nil,  1907,  1934,    -9,   284,   nil,
+  1951,  1927,   199,  1485,   576,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,  1954,   nil,   nil,   904,   812,   nil,  1930,
+   nil,   513,   nil,   nil,   nil,   nil,  2092,   nil,   330,   nil,
+  1947,   835,   240,   nil,  1975,  1976,  1864,  1970,   nil,   nil,
+   nil,  1884,  1974,   982,     8,   nil,   nil,  1474,  1982,   nil,
+   nil,   nil,   nil,  2014,   525,   927,  2015,  1987,   857,   253,
+  1996,   399,   nil,   -13,   nil,  1997,  2024,   nil,  2070,   nil,
+  2000,   205,    -5,    30,   nil,    52,    25,   nil,   nil,  1126,
+   117,    97,   765,   197,   nil,   nil,   180,   nil,   nil,   217,
+   nil,   nil,   279,   291,   379,   nil,   418,   367,   433,   534,
+   412,   454,   467,   460,   nil,   nil,   nil,   nil,   nil,   439,
+   nil,   nil,   nil,    11,   533,   100,   nil,   539,   512,   nil,
+   nil,   558,   414,   nil,   576,   594,   567,   nil,  1566,   606,
+   nil ]
+
+racc_action_default = [
+  -195,  -442,    -1,  -442,  -442,   -69,   -70,   -71,   -72,   -73,
+   -74,   -75,   -76,   -77,   -78,   -79,  -442,   -81,   -82,   -83,
+   -84,   -85,   -86,   -87,   -88,   -89,   -90,   -91,   -92,   -93,
+   -94,   -95,   -96,   -97,   -98,   -99,  -442,  -101,  -104,  -118,
+  -442,  -442,  -126,  -127,  -128,  -129,  -130,  -131,  -136,  -137,
+  -192,  -193,  -194,  -196,  -442,  -198,  -199,  -200,  -201,  -202,
+  -203,  -204,  -207,  -208,  -209,  -210,  -211,  -235,  -442,  -442,
+  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -408,  -442,
+  -442,   911,  -442,   -65,   -67,  -442,  -139,  -140,  -442,  -146,
+  -206,  -205,  -442,  -100,  -106,  -442,  -109,   -72,   -73,  -119,
+  -442,  -125,  -442,  -212,  -442,  -215,  -442,  -217,  -442,  -219,
+  -442,  -221,  -222,  -223,  -442,  -442,  -389,  -442,  -442,  -442,
+  -397,  -398,  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -442,
+  -248,  -442,  -255,  -442,  -261,  -251,  -442,  -328,  -442,  -442,
+  -351,  -442,  -401,  -413,  -442,   -62,  -442,  -442,  -138,  -442,
+  -442,  -442,  -147,  -148,  -442,  -102,  -442,  -442,  -132,  -134,
+  -442,  -442,  -442,  -409,  -442,  -442,  -442,  -442,  -442,  -442,
+  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -442,
+  -338,  -442,  -245,  -442,  -243,  -442,  -256,  -442,  -252,  -442,
+  -442,  -329,  -442,  -402,  -442,  -442,  -435,   -66,    -2,    -3,
+    -4,    -5,    -6,    -7,    -8,    -9,   -10,  -442,   -12,   -14,
+   -18,  -442,  -442,   -22,   -23,   -24,   -25,   -26,   -27,   -28,
+   -30,   -34,   -37,   -40,   -45,   -48,   -50,   -52,   -54,   -56,
+   -58,   -61,   -68,  -186,  -442,  -442,  -442,  -143,   -63,  -442,
+  -442,  -145,  -150,  -152,  -442,  -156,  -442,  -141,  -149,   -80,
+  -442,  -442,  -107,  -442,  -442,  -123,  -442,  -442,  -442,  -197,
+  -442,  -213,  -442,  -225,  -442,  -442,  -442,  -442,  -229,  -442,
+  -292,  -442,  -442,  -390,  -442,  -392,  -442,  -394,  -442,  -407,
+  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -241,  -442,  -442,
+  -442,  -442,  -249,  -442,  -442,  -262,  -264,  -442,  -266,  -267,
+  -268,  -269,  -270,  -442,  -289,  -290,  -442,  -442,  -442,  -442,
+  -314,  -315,  -253,  -325,  -327,  -442,  -352,  -354,  -442,  -356,
+  -357,  -358,  -359,  -367,  -442,  -442,  -442,  -442,  -384,  -442,
+  -410,  -411,  -412,  -442,  -442,  -442,   -13,  -442,  -442,   -60,
+  -172,  -442,  -442,  -442,   -19,  -442,   -20,  -442,  -442,  -442,
+  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -442,
+  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -190,  -442,  -142,
+   -64,  -144,  -442,  -157,  -155,  -442,  -159,  -161,  -162,  -163,
+  -442,  -442,  -166,  -442,  -442,  -171,  -442,  -105,  -108,  -442,
+  -120,  -122,  -442,  -112,  -114,  -442,  -442,  -133,  -135,  -124,
+  -214,  -442,  -442,  -442,  -216,  -218,  -220,  -442,  -442,  -442,
+  -442,  -442,  -442,  -442,  -442,  -396,  -442,  -400,  -236,  -442,
+  -238,  -239,  -442,  -246,  -442,  -442,  -442,  -250,  -442,  -257,
+  -442,  -442,  -442,  -263,  -442,  -271,  -273,  -442,  -275,  -276,
+  -277,  -278,  -291,  -442,  -442,  -442,  -251,  -442,  -316,  -330,
+  -442,  -353,  -442,  -360,  -442,  -363,  -364,  -365,  -366,  -442,
+  -374,  -442,  -442,  -442,  -442,  -442,  -403,  -404,  -405,  -442,
+  -442,  -421,  -442,   -11,  -442,  -173,  -174,  -175,  -442,  -442,
+  -442,   -16,   -17,  -442,   -31,   -32,   -33,   -35,   -36,   -38,
+   -39,   -41,   -42,   -43,   -44,   -46,   -47,   -49,   -51,   -53,
+   -55,   -57,  -442,  -187,  -442,  -442,  -151,  -153,  -154,  -158,
+  -442,  -442,  -442,  -442,  -442,  -442,  -103,  -110,  -442,  -442,
+  -442,  -442,  -442,  -442,  -226,  -442,  -442,  -230,  -442,  -442,
+  -339,  -442,  -402,  -442,  -442,  -442,  -442,  -442,  -442,  -442,
+  -244,  -247,  -254,  -442,  -442,  -260,  -442,  -442,  -442,  -442,
+  -442,  -295,  -297,  -442,  -442,  -306,  -308,  -442,  -442,  -442,
+  -442,  -442,  -350,  -442,  -442,  -442,  -442,  -369,  -442,  -375,
+  -442,  -385,  -442,  -442,  -388,  -442,  -442,  -442,  -442,   -29,
+  -176,  -442,  -442,  -442,  -408,  -182,  -442,  -178,  -442,   -15,
+   -21,  -442,  -188,  -191,  -189,  -160,  -442,  -442,  -442,  -442,
+  -442,  -121,  -442,  -113,  -442,  -442,  -442,  -442,  -442,  -442,
+  -233,  -442,  -224,  -442,  -391,  -393,  -442,  -399,  -237,  -442,
+  -242,  -258,  -442,  -265,  -272,  -442,  -442,  -279,  -280,  -285,
+  -442,  -442,  -442,  -296,  -442,  -299,  -442,  -442,  -442,  -307,
+  -442,  -442,  -442,  -442,  -442,  -317,  -442,  -320,  -442,  -331,
+  -332,  -442,  -334,  -442,  -344,  -355,  -361,  -442,  -442,  -370,
+  -371,  -373,  -442,  -442,  -442,  -442,  -442,  -422,  -442,  -442,
+  -180,  -442,  -184,  -442,  -177,  -183,  -179,   -59,  -164,  -165,
+  -167,  -168,  -442,  -170,  -442,  -115,  -116,  -117,  -442,  -442,
+  -231,  -442,  -442,  -442,  -442,  -442,  -442,  -442,  -274,  -442,
+  -442,  -442,  -293,  -442,  -294,  -442,  -442,  -442,  -305,  -442,
+  -442,  -442,  -311,  -313,  -442,  -326,  -442,  -336,  -442,  -442,
+  -442,  -442,  -362,  -368,  -376,  -442,  -386,  -442,  -406,  -442,
+  -442,  -442,  -423,  -425,  -426,  -427,  -428,  -429,  -430,  -442,
+  -436,  -437,  -442,  -442,  -181,  -185,  -442,  -111,  -442,  -442,
+  -234,  -442,  -387,  -395,  -240,  -442,  -442,  -281,  -282,  -286,
+  -442,  -442,  -298,  -442,  -442,  -309,  -442,  -442,  -442,  -442,
+  -442,  -442,  -442,  -442,  -349,  -442,  -442,  -442,  -442,  -382,
+  -442,  -442,  -442,  -442,  -442,  -432,  -433,  -438,  -439,  -440,
+  -441,  -169,  -227,  -442,  -232,  -259,  -442,  -442,  -287,  -442,
+  -300,  -442,  -303,  -304,  -310,  -312,  -442,  -333,  -442,  -335,
+  -442,  -442,  -442,  -342,  -442,  -442,  -344,  -442,  -377,  -378,
+  -379,  -442,  -442,  -442,  -442,  -424,  -431,  -442,  -442,  -283,
+  -284,  -288,  -301,  -442,  -442,  -442,  -442,  -442,  -442,  -442,
+  -442,  -442,  -372,  -442,  -383,  -442,  -442,  -434,  -442,  -302,
+  -442,  -442,  -442,  -442,  -340,  -442,  -442,  -343,  -345,  -442,
+  -442,  -442,  -442,  -442,  -228,  -318,  -442,  -321,  -323,  -442,
+  -337,  -341,  -442,  -442,  -442,  -381,  -442,  -442,  -442,  -442,
+  -442,  -442,  -442,  -442,  -420,  -319,  -322,  -324,  -347,  -442,
+  -346,  -380,  -416,  -442,  -442,  -442,  -418,  -442,  -442,  -414,
+  -415,  -442,  -442,  -348,  -442,  -442,  -442,  -419,  -442,  -442,
+  -417 ]
+
+racc_goto_table = [
+    54,   137,   232,    84,   236,   265,   263,   161,   179,   195,
+   339,   152,   240,   572,   238,   102,   153,    99,   154,   323,
+   169,   266,   389,   329,   531,   468,   533,   534,   467,   393,
+     9,   181,   425,   435,    50,   376,   453,   344,   268,   570,
+     8,   552,   556,   649,   650,   609,   141,   732,   127,    83,
+   271,   388,   251,   274,   276,   338,   552,   475,   316,   717,
+   773,   725,   295,   555,   157,   551,   802,   626,   491,   492,
+   493,   494,   239,   487,   488,   495,   496,   489,   490,   248,
+   567,   452,   566,   480,   657,   461,   568,   151,   778,   367,
+   724,   819,   273,   339,   278,   194,   331,   332,   895,   900,
+   893,   471,   577,   370,     1,   784,     2,   502,   238,   346,
+   497,   498,   398,   499,   500,   501,    82,   786,   373,    93,
+    94,   250,    95,   392,   258,   601,   182,   397,   148,   507,
+   375,   580,   366,   253,    51,   849,    52,   259,   261,   262,
+   267,   549,   323,   183,   339,    84,   386,   552,   339,   129,
+   291,   556,   619,   131,   254,   293,   429,   133,   294,   260,
+   623,   825,   434,   552,   757,   443,   239,   701,   339,   433,
+   550,   633,   639,   484,   485,   486,   852,   821,   809,   822,
+   634,   451,   801,    54,   340,   297,   388,   659,   554,     9,
+   318,   197,   640,   483,   560,   583,   645,   646,   866,     8,
+   138,   190,   561,   449,   716,   847,   807,   808,   505,   751,
+   139,   315,   422,     9,   655,   nil,   nil,   292,   nil,   nil,
+   nil,   nil,   nil,     8,   nil,   nil,   nil,   253,   253,   442,
+   694,   nil,   nil,   nil,   447,   nil,   238,   nil,   nil,   nil,
+   727,   411,   nil,   524,   374,   nil,   nil,   nil,   254,   254,
+   530,   460,   530,   530,   nil,   598,   599,   600,   526,   469,
+   818,   820,   nil,   604,   605,   606,   424,   476,   nil,   nil,
+   430,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   527,   nil,
+   509,   nil,   656,   624,   nil,   nil,   nil,   423,   nil,    54,
+   nil,   431,   297,   nil,   239,   603,   535,   519,   nil,   595,
+   579,   nil,   762,   nil,   nil,   nil,   765,   nil,   nil,   468,
+   nil,   nil,   467,   318,   nil,   nil,   339,   339,   339,     9,
+   nil,   nil,   340,   427,   339,   339,   339,   464,   539,     8,
+   nil,   nil,   nil,   nil,   588,   nil,   nil,   578,   nil,   546,
+   586,   nil,   238,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   563,   nil,   593,
+   728,   nil,   613,   253,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   684,   508,   nil,   nil,   nil,   nil,   nil,   530,   nil,
+   nil,   nil,   nil,   nil,   254,   nil,   nil,   nil,   nil,   nil,
+   323,   nil,   nil,   861,   677,   nil,   576,   nil,   nil,   nil,
+   239,   nil,   nil,   nil,   nil,   476,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   182,   882,   573,   nil,   nil,   nil,   543,
+   665,   nil,   nil,   nil,   nil,   nil,   671,   596,   597,   588,
+   nil,   nil,   553,   557,   673,   nil,   238,   nil,   763,   622,
+   853,   nil,   766,   nil,   610,   nil,   530,   553,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   664,   nil,
+   nil,   nil,   nil,   nil,   642,   702,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   602,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   239,   nil,   nil,   nil,   nil,   339,
+   nil,   nil,   nil,   339,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   731,   nil,   nil,   nil,   746,   nil,   705,
+   nil,   758,   nil,   nil,   nil,   709,   nil,   nil,   553,   nil,
+   nil,   nil,   557,   837,   nil,   nil,   nil,   703,   nil,   651,
+   nil,   nil,   nil,   nil,   553,   nil,   nil,   nil,   nil,   768,
+   nil,   nil,   nil,   nil,   774,   775,   nil,   nil,   nil,   nil,
+   855,   nil,   nil,   nil,   781,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   696,
+   nil,   873,   nil,   792,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   464,   nil,   nil,   339,   nil,   nil,   750,   610,   nil,
+   nil,   769,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   894,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   339,   nil,   nil,   nil,   nil,   nil,   777,   nil,   nil,
+   nil,   829,   830,   810,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   834,   339,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   530,   nil,   845,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   774,   nil,   339,   nil,   nil,   755,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   864,   nil,   nil,   nil,   nil,   824,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   876,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   905,   nil,   nil,
+   nil,   nil,   nil,   909,   nil,   856,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   651 ]
+
+racc_goto_check = [
+    45,     4,    32,    31,    23,     5,    85,    47,    83,   167,
+    22,    29,    55,   153,    28,    68,    53,    25,     4,   101,
+    47,    23,    44,   157,    84,    74,    84,    84,    76,    48,
+    34,    89,     6,   106,    64,    60,   145,    10,    86,   154,
+    33,    24,    24,   129,   130,    88,   156,   170,    25,    30,
+    83,    43,    40,    83,    83,    11,    24,    61,   138,   133,
+   135,   152,    98,   118,    51,   113,   116,   107,    14,    14,
+    14,    14,    29,    12,    12,    15,    15,    13,    13,    53,
+   113,   140,   146,     6,   107,   147,   148,    31,   149,    32,
+   150,   151,   158,    22,   159,   161,   162,   163,   164,   165,
+   166,   168,   169,    28,     1,   173,     2,     6,    28,     8,
+    16,    17,    23,    18,    19,    20,    26,   170,    27,    37,
+    39,    41,    42,    46,    51,    49,    31,    52,    54,    57,
+    59,    62,    63,    25,    65,   116,    66,    67,    80,    81,
+    82,    87,   101,    90,    22,    31,    40,    24,    22,    91,
+    92,    24,    84,    93,    45,    94,    95,    96,    97,    45,
+    99,   170,   100,    24,   108,   110,    29,   111,    22,    98,
+   112,   113,   118,    10,    10,    10,   135,   152,   133,   152,
+   114,   138,   115,    45,    25,    45,    43,   113,   117,    34,
+    45,    30,   119,    11,   121,    61,   122,   123,   124,    33,
+   125,   126,   127,   128,   131,   170,   132,   134,     5,    88,
+   136,   137,     4,    34,   139,   nil,   nil,    64,   nil,   nil,
+   nil,   nil,   nil,    33,   nil,   nil,   nil,    25,    25,     4,
+    84,   nil,   nil,   nil,     4,   nil,    28,   nil,   nil,   nil,
+   154,   156,   nil,    85,    31,   nil,   nil,   nil,    45,    45,
+     5,     4,     5,     5,   nil,     6,     6,     6,    23,     4,
+   129,   130,   nil,     6,     6,     6,    25,    53,   nil,   nil,
+    25,   nil,   nil,   nil,   nil,   nil,   nil,   nil,    86,   nil,
+    47,   nil,   145,   106,   nil,   nil,   nil,    31,   nil,    45,
+   nil,    45,    45,   nil,    29,    48,    83,    47,   nil,    60,
+    10,   nil,    24,   nil,   nil,   nil,    24,   nil,   nil,    74,
+   nil,   nil,    76,    45,   nil,   nil,    22,    22,    22,    34,
+   nil,   nil,    25,    64,    22,    22,    22,    45,    89,    33,
+   nil,   nil,   nil,   nil,    23,   nil,   nil,   167,   nil,    47,
+    55,   nil,    28,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,    47,   nil,    32,
+    74,   nil,   157,    25,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,    44,    31,   nil,   nil,   nil,   nil,   nil,     5,   nil,
+   nil,   nil,   nil,   nil,    45,   nil,   nil,   nil,   nil,   nil,
+   101,   nil,   nil,   153,    22,   nil,     4,   nil,   nil,   nil,
+    29,   nil,   nil,   nil,   nil,    53,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,    31,   153,    68,   nil,   nil,   nil,    31,
+    23,   nil,   nil,   nil,   nil,   nil,    23,     4,     4,    23,
+   nil,   nil,    45,    45,    55,   nil,    28,   nil,     6,    47,
+    84,   nil,     6,   nil,     4,   nil,     5,    45,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,    47,   nil,
+   nil,   nil,   nil,   nil,     4,    23,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,    25,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,    29,   nil,   nil,   nil,   nil,    22,
+   nil,   nil,   nil,    22,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   167,   nil,   nil,   nil,    23,   nil,    47,
+   nil,    85,   nil,   nil,   nil,    47,   nil,   nil,    45,   nil,
+   nil,   nil,    45,     6,   nil,   nil,   nil,     4,   nil,    45,
+   nil,   nil,   nil,   nil,    45,   nil,   nil,   nil,   nil,    23,
+   nil,   nil,   nil,   nil,    23,    32,   nil,   nil,   nil,   nil,
+     6,   nil,   nil,   nil,    23,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,    25,
+   nil,     6,   nil,    32,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,    45,   nil,   nil,    22,   nil,   nil,     4,     4,   nil,
+   nil,    47,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,     6,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,    22,   nil,   nil,   nil,   nil,   nil,     4,   nil,   nil,
+   nil,    32,    32,    83,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,    23,    22,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,     5,   nil,    23,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+    23,   nil,    22,   nil,   nil,    31,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,    32,   nil,   nil,   nil,   nil,     4,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,    23,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,    23,   nil,   nil,
+   nil,   nil,   nil,    23,   nil,     4,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,    45 ]
+
+racc_goto_pointer = [
+   nil,   104,   106,   nil,   -74,  -160,  -258,   nil,  -103,   nil,
+  -174,  -152,  -277,  -275,  -286,  -283,  -250,  -250,  -249,  -249,
+  -249,   nil,  -197,  -145,  -403,   -23,   112,  -126,  -136,   -78,
+    45,    -1,  -145,    38,    28,   nil,   nil,    83,   nil,    82,
+  -104,   -34,    84,  -200,  -231,    -2,  -131,   -95,  -225,  -393,
+   nil,   -36,  -129,   -73,    43,  -138,   nil,  -243,   nil,  -116,
+  -211,  -283,  -345,  -102,    32,   132,   134,   -24,   -39,   nil,
+   nil,   nil,   nil,   nil,  -304,   nil,  -301,   nil,   nil,   nil,
+   -24,   -25,   -27,  -118,  -386,  -158,  -129,  -302,  -483,   -96,
+    15,    77,   -35,    80,   -31,  -137,    83,   -29,  -125,  -386,
+  -135,  -173,   nil,   nil,   nil,   nil,  -264,  -481,  -535,   nil,
+  -138,  -463,  -274,  -379,  -373,  -582,  -698,  -257,  -382,  -365,
+   nil,  -254,  -364,  -363,  -653,   125,    63,  -247,  -110,  -518,
+  -517,  -447,  -563,  -592,  -562,  -659,   134,    19,  -134,  -349,
+  -237,   nil,   nil,   nil,   nil,  -282,  -377,  -240,  -375,  -636,
+  -570,  -687,  -601,  -450,  -423,   nil,   -31,  -170,   -78,   -79,
+   nil,   -48,   -98,   -97,  -794,  -796,  -784,  -135,  -234,  -370,
+  -622,   nil,   nil,  -634 ]
+
+racc_goto_default = [
+   nil,   nil,   nil,   209,   198,   206,   337,   210,   219,   211,
+   220,   nil,   221,   222,   223,   224,   225,   226,   227,   228,
+   229,   230,   231,   233,    67,     4,   nil,   245,    39,    40,
+   nil,   391,   nil,    97,    98,    11,    12,    37,    36,   nil,
+   nil,   nil,   nil,   252,   nil,   246,   nil,   nil,   nil,   390,
+    41,   nil,   158,    85,    86,   nil,   242,   243,   244,   nil,
+   nil,   nil,   477,   nil,   nil,   nil,   nil,    53,   nil,    55,
+    56,    57,    58,    59,    60,    61,    62,    63,    64,    65,
+   103,   nil,   nil,   nil,   nil,   628,   nil,   269,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   296,
+   nil,   298,   299,   300,   301,   302,   nil,   nil,   627,   303,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   309,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   652,   nil,   653,   nil,   nil,   nil,   nil,   317,
+   nil,   319,   320,   321,   322,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   326,   nil,   115,   nil,   nil,   116,   nil,
+   466,   nil,   nil,   nil,   nil,   nil,   nil,   733,   735,   nil,
+   nil,   734,   736,   nil ]
+
+racc_reduce_table = [
+  0, 0, :racc_error,
+  1, 142, :_reduce_none,
+  1, 144, :_reduce_2,
+  1, 144, :_reduce_3,
+  1, 144, :_reduce_4,
+  1, 144, :_reduce_5,
+  1, 144, :_reduce_6,
+  1, 144, :_reduce_7,
+  1, 144, :_reduce_8,
+  1, 144, :_reduce_9,
+  1, 144, :_reduce_10,
+  3, 144, :_reduce_11,
+  1, 146, :_reduce_none,
+  2, 146, :_reduce_13,
+  1, 148, :_reduce_none,
+  4, 148, :_reduce_15,
+  3, 148, :_reduce_16,
+  3, 148, :_reduce_17,
+  1, 149, :_reduce_none,
+  2, 149, :_reduce_19,
+  2, 149, :_reduce_20,
+  4, 149, :_reduce_21,
+  1, 150, :_reduce_22,
+  1, 150, :_reduce_23,
+  1, 150, :_reduce_24,
+  1, 150, :_reduce_25,
+  1, 150, :_reduce_26,
+  1, 150, :_reduce_27,
+  1, 151, :_reduce_none,
+  4, 151, :_reduce_29,
+  1, 153, :_reduce_none,
+  3, 153, :_reduce_31,
+  3, 153, :_reduce_32,
+  3, 153, :_reduce_33,
+  1, 154, :_reduce_none,
+  3, 154, :_reduce_35,
+  3, 154, :_reduce_36,
+  1, 155, :_reduce_none,
+  3, 155, :_reduce_38,
+  3, 155, :_reduce_39,
+  1, 156, :_reduce_none,
+  3, 156, :_reduce_41,
+  3, 156, :_reduce_42,
+  3, 156, :_reduce_43,
+  3, 156, :_reduce_44,
+  1, 157, :_reduce_none,
+  3, 157, :_reduce_46,
+  3, 157, :_reduce_47,
+  1, 158, :_reduce_none,
+  3, 158, :_reduce_49,
+  1, 159, :_reduce_none,
+  3, 159, :_reduce_51,
+  1, 160, :_reduce_none,
+  3, 160, :_reduce_53,
+  1, 161, :_reduce_none,
+  3, 161, :_reduce_55,
+  1, 162, :_reduce_none,
+  3, 162, :_reduce_57,
+  1, 163, :_reduce_none,
+  5, 163, :_reduce_59,
+  1, 147, :_reduce_60,
+  1, 164, :_reduce_61,
+  3, 165, :_reduce_62,
+  1, 168, :_reduce_none,
+  2, 168, :_reduce_64,
+  1, 167, :_reduce_65,
+  3, 167, :_reduce_66,
+  1, 171, :_reduce_none,
+  3, 171, :_reduce_68,
+  1, 169, :_reduce_69,
+  1, 169, :_reduce_70,
+  1, 169, :_reduce_71,
+  1, 169, :_reduce_none,
+  1, 169, :_reduce_none,
+  1, 169, :_reduce_74,
+  1, 169, :_reduce_none,
+  1, 169, :_reduce_none,
+  1, 169, :_reduce_77,
+  1, 169, :_reduce_78,
+  1, 169, :_reduce_79,
+  4, 169, :_reduce_80,
+  1, 177, :_reduce_81,
+  1, 177, :_reduce_82,
+  1, 177, :_reduce_83,
+  1, 178, :_reduce_84,
+  1, 178, :_reduce_85,
+  1, 178, :_reduce_86,
+  1, 178, :_reduce_87,
+  1, 178, :_reduce_88,
+  1, 178, :_reduce_89,
+  1, 178, :_reduce_90,
+  1, 178, :_reduce_91,
+  1, 178, :_reduce_92,
+  1, 178, :_reduce_93,
+  1, 178, :_reduce_94,
+  1, 178, :_reduce_95,
+  1, 178, :_reduce_96,
+  1, 178, :_reduce_97,
+  1, 179, :_reduce_98,
+  1, 179, :_reduce_99,
+  2, 176, :_reduce_100,
+  1, 176, :_reduce_none,
+  0, 182, :_reduce_102,
+  6, 174, :_reduce_103,
+  0, 183, :_reduce_104,
+  5, 174, :_reduce_105,
+  2, 174, :_reduce_106,
+  1, 181, :_reduce_none,
+  2, 181, :_reduce_none,
+  1, 180, :_reduce_109,
+  3, 184, :_reduce_110,
+  6, 184, :_reduce_111,
+  1, 187, :_reduce_112,
+  3, 187, :_reduce_113,
+  1, 189, :_reduce_114,
+  4, 189, :_reduce_115,
+  4, 189, :_reduce_116,
+  4, 189, :_reduce_117,
+  1, 166, :_reduce_none,
+  2, 166, :_reduce_119,
+  1, 185, :_reduce_120,
+  3, 185, :_reduce_121,
+  1, 190, :_reduce_none,
+  4, 175, :_reduce_none,
+  5, 175, :_reduce_none,
+  2, 175, :_reduce_none,
+  1, 191, :_reduce_126,
+  1, 191, :_reduce_127,
+  1, 191, :_reduce_128,
+  1, 191, :_reduce_129,
+  1, 191, :_reduce_130,
+  1, 191, :_reduce_131,
+  1, 192, :_reduce_none,
+  3, 192, :_reduce_none,
+  1, 193, :_reduce_none,
+  3, 193, :_reduce_none,
+  1, 170, :_reduce_136,
+  1, 170, :_reduce_137,
+  2, 172, :_reduce_138,
+  1, 172, :_reduce_none,
+  1, 195, :_reduce_140,
+  3, 195, :_reduce_141,
+  4, 195, :_reduce_142,
+  3, 195, :_reduce_143,
+  4, 195, :_reduce_144,
+  3, 195, :_reduce_145,
+  1, 194, :_reduce_146,
+  2, 194, :_reduce_147,
+  2, 194, :_reduce_148,
+  3, 194, :_reduce_149,
+  1, 196, :_reduce_none,
+  3, 196, :_reduce_none,
+  1, 197, :_reduce_152,
+  3, 197, :_reduce_153,
+  3, 198, :_reduce_154,
+  2, 198, :_reduce_155,
+  1, 198, :_reduce_156,
+  2, 198, :_reduce_157,
+  3, 199, :_reduce_158,
+  1, 200, :_reduce_159,
+  3, 200, :_reduce_160,
+  1, 201, :_reduce_161,
+  1, 201, :_reduce_162,
+  1, 201, :_reduce_163,
+  4, 201, :_reduce_164,
+  4, 201, :_reduce_165,
+  1, 201, :_reduce_166,
+  4, 201, :_reduce_167,
+  4, 201, :_reduce_168,
+  6, 201, :_reduce_169,
+  4, 201, :_reduce_170,
+  1, 201, :_reduce_171,
+  1, 152, :_reduce_none,
+  2, 152, :_reduce_173,
+  1, 202, :_reduce_none,
+  1, 202, :_reduce_none,
+  2, 202, :_reduce_none,
+  3, 203, :_reduce_177,
+  2, 203, :_reduce_178,
+  3, 203, :_reduce_179,
+  3, 203, :_reduce_180,
+  4, 203, :_reduce_181,
+  2, 203, :_reduce_182,
+  3, 203, :_reduce_none,
+  3, 203, :_reduce_184,
+  4, 203, :_reduce_185,
+  1, 173, :_reduce_186,
+  3, 173, :_reduce_187,
+  4, 173, :_reduce_188,
+  4, 173, :_reduce_189,
+  1, 204, :_reduce_190,
+  3, 204, :_reduce_191,
+  2, 143, :_reduce_none,
+  2, 143, :_reduce_none,
+  2, 143, :_reduce_none,
+  0, 143, :_reduce_none,
+  1, 205, :_reduce_none,
+  4, 205, :_reduce_197,
+  1, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  2, 208, :_reduce_none,
+  2, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  1, 208, :_reduce_none,
+  1, 209, :_reduce_212,
+  3, 209, :_reduce_213,
+  4, 221, :_reduce_214,
+  1, 221, :_reduce_215,
+  4, 221, :_reduce_216,
+  1, 221, :_reduce_217,
+  4, 221, :_reduce_218,
+  1, 221, :_reduce_219,
+  4, 221, :_reduce_220,
+  1, 221, :_reduce_221,
+  1, 221, :_reduce_222,
+  1, 221, :_reduce_223,
+  6, 221, :_reduce_224,
+  1, 222, :_reduce_225,
+  3, 222, :_reduce_226,
+  7, 226, :_reduce_227,
+  10, 226, :_reduce_228,
+  1, 223, :_reduce_229,
+  3, 223, :_reduce_230,
+  5, 227, :_reduce_231,
+  7, 227, :_reduce_232,
+  1, 229, :_reduce_233,
+  3, 229, :_reduce_234,
+  1, 211, :_reduce_235,
+  5, 219, :_reduce_236,
+  7, 219, :_reduce_237,
+  5, 218, :_reduce_238,
+  5, 218, :_reduce_239,
+  9, 220, :_reduce_240,
+  4, 210, :_reduce_241,
+  7, 210, :_reduce_242,
+  1, 231, :_reduce_none,
+  4, 231, :_reduce_none,
+  1, 230, :_reduce_245,
+  3, 230, :_reduce_246,
+  6, 212, :_reduce_247,
+  1, 232, :_reduce_248,
+  1, 233, :_reduce_none,
+  2, 233, :_reduce_none,
+  1, 145, :_reduce_251,
+  2, 145, :_reduce_252,
+  3, 145, :_reduce_253,
+  6, 213, :_reduce_254,
+  1, 234, :_reduce_255,
+  0, 235, :_reduce_256,
+  2, 235, :_reduce_257,
+  3, 236, :_reduce_258,
+  6, 236, :_reduce_259,
+  6, 214, :_reduce_260,
+  1, 237, :_reduce_261,
+  1, 238, :_reduce_none,
+  2, 238, :_reduce_none,
+  1, 239, :_reduce_264,
+  4, 239, :_reduce_265,
+  1, 240, :_reduce_none,
+  1, 240, :_reduce_none,
+  1, 240, :_reduce_none,
+  1, 240, :_reduce_none,
+  1, 240, :_reduce_none,
+  1, 241, :_reduce_271,
+  3, 241, :_reduce_272,
+  1, 247, :_reduce_273,
+  4, 247, :_reduce_274,
+  1, 247, :_reduce_275,
+  1, 247, :_reduce_276,
+  1, 247, :_reduce_277,
+  1, 247, :_reduce_278,
+  1, 248, :_reduce_279,
+  1, 248, :_reduce_280,
+  3, 248, :_reduce_281,
+  3, 248, :_reduce_282,
+  5, 249, :_reduce_283,
+  5, 249, :_reduce_284,
+  4, 242, :_reduce_285,
+  6, 242, :_reduce_286,
+  7, 242, :_reduce_287,
+  8, 242, :_reduce_288,
+  1, 250, :_reduce_289,
+  1, 250, :_reduce_290,
+  1, 251, :_reduce_291,
+  1, 228, :_reduce_none,
+  1, 252, :_reduce_none,
+  5, 243, :_reduce_294,
+  1, 253, :_reduce_295,
+  2, 253, :_reduce_296,
+  1, 254, :_reduce_297,
+  4, 254, :_reduce_298,
+  1, 255, :_reduce_299,
+  4, 255, :_reduce_300,
+  5, 255, :_reduce_301,
+  3, 256, :_reduce_302,
+  1, 256, :_reduce_303,
+  1, 257, :_reduce_none,
+  5, 244, :_reduce_305,
+  1, 258, :_reduce_306,
+  2, 258, :_reduce_307,
+  1, 259, :_reduce_308,
+  4, 259, :_reduce_309,
+  4, 260, :_reduce_310,
+  5, 245, :_reduce_311,
+  7, 245, :_reduce_312,
+  5, 246, :_reduce_none,
+  1, 261, :_reduce_314,
+  1, 261, :_reduce_315,
+  0, 262, :_reduce_none,
+  2, 262, :_reduce_none,
+  7, 263, :_reduce_318,
+  9, 263, :_reduce_319,
+  1, 264, :_reduce_none,
+  1, 265, :_reduce_321,
+  3, 265, :_reduce_322,
+  1, 265, :_reduce_323,
+  3, 265, :_reduce_324,
+  0, 269, :_reduce_325,
+  8, 215, :_reduce_326,
+  4, 215, :_reduce_327,
+  1, 266, :_reduce_328,
+  1, 267, :_reduce_329,
+  0, 268, :_reduce_none,
+  2, 268, :_reduce_none,
+  2, 268, :_reduce_none,
+  4, 270, :_reduce_333,
+  1, 270, :_reduce_334,
+  3, 272, :_reduce_335,
+  1, 272, :_reduce_336,
+  6, 274, :_reduce_337,
+  1, 224, :_reduce_338,
+  1, 225, :_reduce_none,
+  6, 273, :_reduce_340,
+  7, 273, :_reduce_341,
+  4, 273, :_reduce_342,
+  6, 273, :_reduce_343,
+  1, 275, :_reduce_none,
+  6, 271, :_reduce_345,
+  9, 271, :_reduce_346,
+  9, 271, :_reduce_347,
+  12, 271, :_reduce_348,
+  1, 276, :_reduce_none,
+  6, 216, :_reduce_350,
+  1, 277, :_reduce_351,
+  1, 278, :_reduce_none,
+  2, 278, :_reduce_none,
+  1, 279, :_reduce_354,
+  4, 279, :_reduce_355,
+  1, 280, :_reduce_none,
+  1, 280, :_reduce_none,
+  1, 280, :_reduce_none,
+  1, 280, :_reduce_none,
+  1, 281, :_reduce_360,
+  3, 281, :_reduce_361,
+  4, 286, :_reduce_362,
+  1, 286, :_reduce_363,
+  1, 286, :_reduce_364,
+  1, 286, :_reduce_365,
+  1, 286, :_reduce_366,
+  1, 282, :_reduce_367,
+  5, 283, :_reduce_368,
+  1, 287, :_reduce_369,
+  2, 287, :_reduce_370,
+  0, 291, :_reduce_371,
+  8, 284, :_reduce_372,
+  4, 284, :_reduce_373,
+  1, 288, :_reduce_374,
+  1, 289, :_reduce_375,
+  0, 290, :_reduce_none,
+  2, 290, :_reduce_none,
+  2, 290, :_reduce_none,
+  2, 290, :_reduce_none,
+  6, 292, :_reduce_380,
+  4, 292, :_reduce_381,
+  6, 285, :_reduce_382,
+  8, 285, :_reduce_383,
+  1, 294, :_reduce_none,
+  1, 295, :_reduce_none,
+  1, 293, :_reduce_none,
+  9, 217, :_reduce_387,
+  6, 217, :_reduce_388,
+  1, 296, :_reduce_none,
+  3, 296, :_reduce_none,
+  6, 299, :_reduce_391,
+  3, 299, :_reduce_392,
+  6, 299, :_reduce_393,
+  3, 299, :_reduce_394,
+  8, 299, :_reduce_395,
+  4, 299, :_reduce_396,
+  1, 299, :_reduce_397,
+  1, 299, :_reduce_398,
+  6, 299, :_reduce_399,
+  4, 299, :_reduce_400,
+  1, 297, :_reduce_401,
+  0, 298, :_reduce_none,
+  2, 298, :_reduce_none,
+  2, 298, :_reduce_none,
+  1, 301, :_reduce_none,
+  4, 301, :_reduce_406,
+  1, 300, :_reduce_407,
+  1, 186, :_reduce_408,
+  1, 188, :_reduce_409,
+  4, 206, :_reduce_none,
+  2, 302, :_reduce_none,
+  2, 302, :_reduce_none,
+  0, 302, :_reduce_none,
+  14, 303, :_reduce_414,
+  2, 305, :_reduce_415,
+  0, 305, :_reduce_416,
+  6, 306, :_reduce_417,
+  13, 304, :_reduce_418,
+  5, 307, :_reduce_419,
+  0, 307, :_reduce_420,
+  5, 207, :_reduce_421,
+  3, 309, :_reduce_422,
+  3, 310, :_reduce_423,
+  5, 310, :_reduce_424,
+  1, 311, :_reduce_none,
+  1, 311, :_reduce_none,
+  1, 311, :_reduce_none,
+  1, 311, :_reduce_none,
+  1, 311, :_reduce_429,
+  1, 311, :_reduce_430,
+  3, 313, :_reduce_431,
+  2, 313, :_reduce_432,
+  1, 314, :_reduce_433,
+  3, 314, :_reduce_434,
+  1, 308, :_reduce_435,
+  1, 312, :_reduce_436,
+  1, 312, :_reduce_437,
+  2, 312, :_reduce_438,
+  2, 312, :_reduce_439,
+  2, 312, :_reduce_440,
+  2, 312, :_reduce_441 ]
+
+racc_reduce_n = 442
+
+racc_shift_n = 911
+
+racc_token_table = {
+  false => 0,
+  :error => 1,
+  :TRUE => 2,
+  :FALSE => 3,
+  :INTEGER_CONSTANT => 4,
+  :FLOATING_CONSTANT => 5,
+  :OCTAL_CONSTANT => 6,
+  :HEX_CONSTANT => 7,
+  :CHARACTER_LITERAL => 8,
+  "(" => 9,
+  ")" => 10,
+  :STRING_LITERAL => 11,
+  "[" => 12,
+  "]" => 13,
+  "." => 14,
+  :IDENTIFIER => 15,
+  "->" => 16,
+  :SIZEOF => 17,
+  "&" => 18,
+  "*" => 19,
+  "+" => 20,
+  "-" => 21,
+  "~" => 22,
+  "!" => 23,
+  "/" => 24,
+  "%" => 25,
+  "<<" => 26,
+  ">>" => 27,
+  "<" => 28,
+  ">" => 29,
+  "<=" => 30,
+  ">=" => 31,
+  "==" => 32,
+  "!=" => 33,
+  "^" => 34,
+  "|" => 35,
+  "&&" => 36,
+  "||" => 37,
+  "?" => 38,
+  ":" => 39,
+  ";" => 40,
+  "," => 41,
+  "=" => 42,
+  :VOID => 43,
+  :FLOAT32_T => 44,
+  :DOUBLE64_T => 45,
+  :TYPE_NAME => 46,
+  :BOOL_T => 47,
+  :FLOAT => 48,
+  :DOUBLE => 49,
+  :DESCRIPTOR => 50,
+  :CHAR_T => 51,
+  :SCHAR_T => 52,
+  :UCHAR_T => 53,
+  :CHAR => 54,
+  :SHORT => 55,
+  :INT => 56,
+  :LONG => 57,
+  :INT8_T => 58,
+  :INT16_T => 59,
+  :INT32_T => 60,
+  :INT64_T => 61,
+  :INT128_T => 62,
+  :UINT8_T => 63,
+  :UINT16_T => 64,
+  :UINT32_T => 65,
+  :UINT64_T => 66,
+  :UINT128_T => 67,
+  :SIGNED => 68,
+  :UNSIGNED => 69,
+  :STRUCT => 70,
+  "{" => 71,
+  "}" => 72,
+  :STRING => 73,
+  :SIZE_IS => 74,
+  :COUNT_IS => 75,
+  :ENUM => 76,
+  :ENUM8 => 77,
+  :ENUM16 => 78,
+  :ENUM32 => 79,
+  :ENUM64 => 80,
+  :ENUM128 => 81,
+  :CONST => 82,
+  :VOLATILE => 83,
+  "..." => 84,
+  :IN => 85,
+  :OUT => 86,
+  :INOUT => 87,
+  :SEND => 88,
+  :RECEIVE => 89,
+  :NULLABLE => 90,
+  :C_EXP => 91,
+  :ALLOCATOR => 92,
+  :CALLBACK => 93,
+  :CONTEXT => 94,
+  :DEVIATE => 95,
+  :ID => 96,
+  :PROTOTYPE => 97,
+  :RESTRICT => 98,
+  :SINGLETON => 99,
+  :IDX_IS_ID => 100,
+  :ACTIVE => 101,
+  :GENERATE => 102,
+  :IMPORT_C => 103,
+  :IMPORT => 104,
+  :AB_STRING_LITERAL => 105,
+  :TYPEDEF => 106,
+  :NAMESPACE => 107,
+  "::" => 108,
+  :SIGNATURE => 109,
+  :ONEWAY => 110,
+  :CELLTYPE => 111,
+  :INLINE => 112,
+  :OPTIONAL => 113,
+  :REF_DESC => 114,
+  :DYNAMIC => 115,
+  :OMIT => 116,
+  :CALL => 117,
+  :ENTRY => 118,
+  :ATTRIBUTE => 119,
+  :CHOICE => 120,
+  :VAR => 121,
+  :REQUIRE => 122,
+  :FACTORY => 123,
+  :CTFACTORY => 124,
+  :CELL => 125,
+  :THROUGH => 126,
+  :COMPOSITE => 127,
+  "=>" => 128,
+  :REGION => 129,
+  :IN_THROUGH => 130,
+  :OUT_THROUGH => 131,
+  :TO_THROUGH => 132,
+  :NODE => 133,
+  :LINKUNIT => 134,
+  :DOMAIN => 135,
+  :CLASS => 136,
+  :__LOCATION_INFORMATION__ => 137,
+  :__CELL__ => 138,
+  :__JOIN__ => 139,
+  :TOOL_INFO => 140 }
+
+racc_nt_base = 141
+
+racc_use_result_var = true
+
+Racc_arg = [
+  racc_action_table,
+  racc_action_check,
+  racc_action_default,
+  racc_action_pointer,
+  racc_goto_table,
+  racc_goto_check,
+  racc_goto_default,
+  racc_goto_pointer,
+  racc_nt_base,
+  racc_reduce_table,
+  racc_token_table,
+  racc_shift_n,
+  racc_reduce_n,
+  racc_use_result_var ]
+
+Racc_token_to_s_table = [
+  "$end",
+  "error",
+  "TRUE",
+  "FALSE",
+  "INTEGER_CONSTANT",
+  "FLOATING_CONSTANT",
+  "OCTAL_CONSTANT",
+  "HEX_CONSTANT",
+  "CHARACTER_LITERAL",
+  "\"(\"",
+  "\")\"",
+  "STRING_LITERAL",
+  "\"[\"",
+  "\"]\"",
+  "\".\"",
+  "IDENTIFIER",
+  "\"->\"",
+  "SIZEOF",
+  "\"&\"",
+  "\"*\"",
+  "\"+\"",
+  "\"-\"",
+  "\"~\"",
+  "\"!\"",
+  "\"/\"",
+  "\"%\"",
+  "\"<<\"",
+  "\">>\"",
+  "\"<\"",
+  "\">\"",
+  "\"<=\"",
+  "\">=\"",
+  "\"==\"",
+  "\"!=\"",
+  "\"^\"",
+  "\"|\"",
+  "\"&&\"",
+  "\"||\"",
+  "\"?\"",
+  "\":\"",
+  "\";\"",
+  "\",\"",
+  "\"=\"",
+  "VOID",
+  "FLOAT32_T",
+  "DOUBLE64_T",
+  "TYPE_NAME",
+  "BOOL_T",
+  "FLOAT",
+  "DOUBLE",
+  "DESCRIPTOR",
+  "CHAR_T",
+  "SCHAR_T",
+  "UCHAR_T",
+  "CHAR",
+  "SHORT",
+  "INT",
+  "LONG",
+  "INT8_T",
+  "INT16_T",
+  "INT32_T",
+  "INT64_T",
+  "INT128_T",
+  "UINT8_T",
+  "UINT16_T",
+  "UINT32_T",
+  "UINT64_T",
+  "UINT128_T",
+  "SIGNED",
+  "UNSIGNED",
+  "STRUCT",
+  "\"{\"",
+  "\"}\"",
+  "STRING",
+  "SIZE_IS",
+  "COUNT_IS",
+  "ENUM",
+  "ENUM8",
+  "ENUM16",
+  "ENUM32",
+  "ENUM64",
+  "ENUM128",
+  "CONST",
+  "VOLATILE",
+  "\"...\"",
+  "IN",
+  "OUT",
+  "INOUT",
+  "SEND",
+  "RECEIVE",
+  "NULLABLE",
+  "C_EXP",
+  "ALLOCATOR",
+  "CALLBACK",
+  "CONTEXT",
+  "DEVIATE",
+  "ID",
+  "PROTOTYPE",
+  "RESTRICT",
+  "SINGLETON",
+  "IDX_IS_ID",
+  "ACTIVE",
+  "GENERATE",
+  "IMPORT_C",
+  "IMPORT",
+  "AB_STRING_LITERAL",
+  "TYPEDEF",
+  "NAMESPACE",
+  "\"::\"",
+  "SIGNATURE",
+  "ONEWAY",
+  "CELLTYPE",
+  "INLINE",
+  "OPTIONAL",
+  "REF_DESC",
+  "DYNAMIC",
+  "OMIT",
+  "CALL",
+  "ENTRY",
+  "ATTRIBUTE",
+  "CHOICE",
+  "VAR",
+  "REQUIRE",
+  "FACTORY",
+  "CTFACTORY",
+  "CELL",
+  "THROUGH",
+  "COMPOSITE",
+  "\"=>\"",
+  "REGION",
+  "IN_THROUGH",
+  "OUT_THROUGH",
+  "TO_THROUGH",
+  "NODE",
+  "LINKUNIT",
+  "DOMAIN",
+  "CLASS",
+  "__LOCATION_INFORMATION__",
+  "__CELL__",
+  "__JOIN__",
+  "TOOL_INFO",
+  "$start",
+  "all",
+  "component_description",
+  "primary_expression",
+  "namespace_identifier",
+  "string_literal_list",
+  "expression",
+  "postfix_expression",
+  "unary_expression",
+  "unary_operator",
+  "cast_expression",
+  "type_name",
+  "multiplicative_expression",
+  "additive_expression",
+  "shift_expression",
+  "relational_expression",
+  "equality_expression",
+  "and_expression",
+  "exclusive_or_expression",
+  "inclusive_or_expression",
+  "logical_and_expression",
+  "logical_or_expression",
+  "conditional_expression",
+  "constant_expression",
+  "declaration",
+  "type_specifier_qualifier_list",
+  "init_declarator_list",
+  "declaration_specifiers",
+  "type_specifier",
+  "type_qualifier",
+  "init_declarator",
+  "declarator",
+  "initializer",
+  "struct_specifier",
+  "enum_specifier",
+  "sign_int_type",
+  "char_type",
+  "int_type",
+  "sign",
+  "struct_tag",
+  "struct_declaration_list",
+  "@1",
+  "@2",
+  "struct_declaration",
+  "struct_declarator_list",
+  "spec_L",
+  "pointer_specifier_list",
+  "spec_R",
+  "pointer_specifier",
+  "struct_declarator",
+  "enum_type",
+  "enumerator_list",
+  "enumerator",
+  "pointer",
+  "direct_declarator",
+  "parameter_type_list",
+  "parameter_list",
+  "parameter_declaration",
+  "parameter_specifier_list_bracket",
+  "parameter_specifier_list",
+  "parameter_specifier",
+  "abstract_declarator",
+  "direct_abstract_declarator",
+  "initializer_list",
+  "specified_statement",
+  "location_information",
+  "tool_info",
+  "statement",
+  "statement_specifier_list",
+  "typedef",
+  "const_statement",
+  "namespace",
+  "signature",
+  "celltype",
+  "cell",
+  "composite_celltype",
+  "region",
+  "import",
+  "import_C",
+  "generate_statement",
+  "statement_specifier",
+  "alloc_list",
+  "restrict_list",
+  "plugin_name",
+  "plugin_arg",
+  "alloc",
+  "restrict",
+  "port_name",
+  "region_name_list",
+  "declarator_list",
+  "typedef_specifier",
+  "namespace_name",
+  "statement_list",
+  "signature_name",
+  "function_head_list",
+  "function_head",
+  "celltype_name",
+  "celltype_statement_list",
+  "specified_celltype_statement",
+  "celltype_statement",
+  "celltype_statement_specifier_list",
+  "port",
+  "attribute",
+  "var",
+  "require",
+  "factory",
+  "celltype_statement_specifier",
+  "alloc_list2",
+  "alloc2",
+  "port_type",
+  "namespace_signature_name",
+  "array_size",
+  "attribute_declaration_list",
+  "attribute_declaration",
+  "attribute_specifier",
+  "choice_list",
+  "choice_element",
+  "var_declaration_list",
+  "var_declaration",
+  "var_specifier",
+  "factory_head",
+  "factory_function_list",
+  "factory_function",
+  "factory_function_name",
+  "arg_list",
+  "namespace_celltype_name",
+  "cell_name",
+  "join_list",
+  "@3",
+  "specified_join",
+  "reverse_join",
+  "join_specifier_list",
+  "join",
+  "join_specifier",
+  "cae_name",
+  "array_index",
+  "composite_celltype_name",
+  "composite_celltype_statement_list",
+  "specified_composite_celltype_statement",
+  "composite_celltype_statement",
+  "composite_celltype_statement_specifier_list",
+  "composite_port",
+  "composite_attribute",
+  "internal_cell",
+  "export_join",
+  "composite_celltype_statement_specifier",
+  "composite_attribute_declaration_list",
+  "internal_namespace_celltype_name",
+  "internal_cell_name",
+  "internal_join_list",
+  "@4",
+  "external_join",
+  "internal_cell_elem_name",
+  "export_name",
+  "internal_ref_cell_name",
+  "region_specifier_list",
+  "region_name",
+  "region_statement",
+  "region_specifier",
+  "namespace_region_name",
+  "region_cell",
+  "cell_location_join_location_list",
+  "cell_location",
+  "join_location",
+  "port_location_list",
+  "port_location",
+  "bar_list",
+  "JSON_string",
+  "JSON_object",
+  "JSON_property_list",
+  "JSON_value",
+  "JSON_number",
+  "JSON_array",
+  "JSON_array_list" ]
+
+Racc_debug_parser = false
+
+##### State transition tables end #####
+
+# reduce 0 omitted
+
+# reduce 1 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 52)
+  def _reduce_2(val, _values, result)
+     result = [ :IDENTIFIER, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 54)
+  def _reduce_3(val, _values, result)
+     result = [ :BOOL_CONSTANT, true ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 56)
+  def _reduce_4(val, _values, result)
+     result = [ :BOOL_CONSTANT, false ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 58)
+  def _reduce_5(val, _values, result)
+     result = [ :INTEGER_CONSTANT, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 60)
+  def _reduce_6(val, _values, result)
+     result = [ :FLOATING_CONSTANT, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 62)
+  def _reduce_7(val, _values, result)
+     result = [ :OCTAL_CONSTANT, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 64)
+  def _reduce_8(val, _values, result)
+     result = [ :HEX_CONSTANT, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 66)
+  def _reduce_9(val, _values, result)
+     result = [ :CHARACTER_LITERAL, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 68)
+  def _reduce_10(val, _values, result)
+     result = [ :STRING_LITERAL_LIST, val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 70)
+  def _reduce_11(val, _values, result)
+     result = [ :PARENTHESES, val[1].get_elements ] 
+    result
+  end
+.,.,
+
+# reduce 12 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 76)
+  def _reduce_13(val, _values, result)
+    			# 連接した文字列を1つの文字列にまとめる
+			str = "\"" + val[0].val.gsub( /\"(.*)\"/, "\\1" ) + val[1].val.gsub( /\"(.*)\"/, "\\1" ) + "\""
+			result = Token.new( str, val[0].file, val[0].lineno, val[0].col )
+		
+    result
+  end
+.,.,
+
+# reduce 14 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 85)
+  def _reduce_15(val, _values, result)
+     result = [ :OP_SUBSC, val[0], val[2] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 87)
+  def _reduce_16(val, _values, result)
+     result = [ :OP_DOT, val[0], val[2] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 89)
+  def _reduce_17(val, _values, result)
+     result = [ :OP_REF, val[0], val[2] ] 
+    result
+  end
+.,.,
+
+# reduce 18 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 95)
+  def _reduce_19(val, _values, result)
+     result = [ val[0], val[1] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 97)
+  def _reduce_20(val, _values, result)
+     result = [ :OP_SIZEOF_EXPR, val[1] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 99)
+  def _reduce_21(val, _values, result)
+     result = [ :OP_SIZEOF_TYPE, val[1] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 102)
+  def _reduce_22(val, _values, result)
+     result = :OP_U_AMP 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 103)
+  def _reduce_23(val, _values, result)
+     result = :OP_U_ASTER 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 104)
+  def _reduce_24(val, _values, result)
+     result = :OP_U_PLUS 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 105)
+  def _reduce_25(val, _values, result)
+     result = :OP_U_MINUS 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 106)
+  def _reduce_26(val, _values, result)
+     result = :OP_U_TILDE 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 107)
+  def _reduce_27(val, _values, result)
+     result = :OP_U_EXCLAM 
+    result
+  end
+.,.,
+
+# reduce 28 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 112)
+  def _reduce_29(val, _values, result)
+      result = [ :CAST, val[1], val[3] ] 
+    result
+  end
+.,.,
+
+# reduce 30 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 117)
+  def _reduce_31(val, _values, result)
+     result = [ :OP_MULT, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 119)
+  def _reduce_32(val, _values, result)
+     result = [ :OP_DIV, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 121)
+  def _reduce_33(val, _values, result)
+     result = [ :OP_REMAIN, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 34 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 126)
+  def _reduce_35(val, _values, result)
+     result = [ :OP_ADD, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 128)
+  def _reduce_36(val, _values, result)
+     result = [ :OP_SUB, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 37 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 133)
+  def _reduce_38(val, _values, result)
+     result = [ :OP_LSFT, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 135)
+  def _reduce_39(val, _values, result)
+     result = [ :OP_RSFT, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 40 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 140)
+  def _reduce_41(val, _values, result)
+     result = [ :OP_LT, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 142)
+  def _reduce_42(val, _values, result)
+     result = [ :OP_GT, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 144)
+  def _reduce_43(val, _values, result)
+     result = [ :OP_LE, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 146)
+  def _reduce_44(val, _values, result)
+     result = [ :OP_GE, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 45 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 151)
+  def _reduce_46(val, _values, result)
+     result = [ :OP_EQ, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 153)
+  def _reduce_47(val, _values, result)
+     result = [ :OP_NE, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 48 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 158)
+  def _reduce_49(val, _values, result)
+     result = [ :OP_AND, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 50 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 163)
+  def _reduce_51(val, _values, result)
+     result = [ :OP_EOR, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 52 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 168)
+  def _reduce_53(val, _values, result)
+     result = [ :OP_OR, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 54 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 173)
+  def _reduce_55(val, _values, result)
+     result = [ :OP_LAND, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 56 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 178)
+  def _reduce_57(val, _values, result)
+     result = [ :OP_LOR, val[0], val[2] ]  
+    result
+  end
+.,.,
+
+# reduce 58 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 183)
+  def _reduce_59(val, _values, result)
+     result = [ :OP_CEX, val[0], val[2].get_elements, val[4] ]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 190)
+  def _reduce_60(val, _values, result)
+    			result = Expression.new( val[0] )
+			# result.print
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 197)
+  def _reduce_61(val, _values, result)
+    			result = Expression.new( val[0] )
+			# result.print
+
+			# res = result.eval_const( nil )
+			# if res then
+			#   puts "val: #{res}"
+			# else
+			#   puts "val: nil"
+			# end
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 219)
+  def _reduce_62(val, _values, result)
+    			val[1].each { |i|	# i: Decl
+				i.set_type( val[0] )
+			}
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+# reduce 63 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 235)
+  def _reduce_64(val, _values, result)
+    			val[1].set_qualifier( val[0] )
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 241)
+  def _reduce_65(val, _values, result)
+     result = [val[0]] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 243)
+  def _reduce_66(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+# reduce 67 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 248)
+  def _reduce_68(val, _values, result)
+     val[0].set_initializer( val[2] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 254)
+  def _reduce_69(val, _values, result)
+     result = VoidType.new 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 255)
+  def _reduce_70(val, _values, result)
+     result = FloatType.new(32) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 256)
+  def _reduce_71(val, _values, result)
+     result = FloatType.new(64) 
+    result
+  end
+.,.,
+
+# reduce 72 omitted
+
+# reduce 73 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 259)
+  def _reduce_74(val, _values, result)
+     result = DefinedType.new( val[0].val ) 
+    result
+  end
+.,.,
+
+# reduce 75 omitted
+
+# reduce 76 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 263)
+  def _reduce_77(val, _values, result)
+     result = BoolType.new 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 269)
+  def _reduce_78(val, _values, result)
+    			Generator.warning( "W5002 float: obsolete type. use float32_t"  )
+			result = FloatType.new(32)
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 273)
+  def _reduce_79(val, _values, result)
+    			Generator.warning( "W5003 double: obsolete type. use double64_t"  )
+			result = FloatType.new(64)
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 276)
+  def _reduce_80(val, _values, result)
+              # namespace_identifier: signature name
+			result = DescriptorType.new( val[2] )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 281)
+  def _reduce_81(val, _values, result)
+     result = IntType.new( -1 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 284)
+  def _reduce_82(val, _values, result)
+    			result = IntType.new( -1 )
+			result.set_sign( :SIGNED, true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 289)
+  def _reduce_83(val, _values, result)
+    			result = IntType.new( -1 )
+			result.set_sign( :UNSIGNED, true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 295)
+  def _reduce_84(val, _values, result)
+    			# Generator.warning( "W5004 char: obsolete type. use char_t"  )
+			result = IntType.new( -11 )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 298)
+  def _reduce_85(val, _values, result)
+     result = IntType.new( -2 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 299)
+  def _reduce_86(val, _values, result)
+     result = IntType.new( -3 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 300)
+  def _reduce_87(val, _values, result)
+     result = IntType.new( -4 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 324)
+  def _reduce_88(val, _values, result)
+     result = IntType.new( 8 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 325)
+  def _reduce_89(val, _values, result)
+     result = IntType.new( 16 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 326)
+  def _reduce_90(val, _values, result)
+     result = IntType.new( 32 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 327)
+  def _reduce_91(val, _values, result)
+     result = IntType.new( 64 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 328)
+  def _reduce_92(val, _values, result)
+     result = IntType.new( 128 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 331)
+  def _reduce_93(val, _values, result)
+    			result = IntType.new( 8 )
+			result.set_sign( :UNSIGNED, true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 336)
+  def _reduce_94(val, _values, result)
+    			result = IntType.new( 16 )
+			result.set_sign( :UNSIGNED, true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 341)
+  def _reduce_95(val, _values, result)
+    			result = IntType.new( 32 )
+			result.set_sign( :UNSIGNED, true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 346)
+  def _reduce_96(val, _values, result)
+    			result = IntType.new( 64 )
+			result.set_sign( :UNSIGNED, true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 351)
+  def _reduce_97(val, _values, result)
+    			result = IntType.new( 128 )
+			result.set_sign( :UNSIGNED, true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 356)
+  def _reduce_98(val, _values, result)
+     result = :SIGNED 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 357)
+  def _reduce_99(val, _values, result)
+     result = :UNSIGNED 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 363)
+  def _reduce_100(val, _values, result)
+    			val[1].set_sign( val[0] )
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+# reduce 101 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 371)
+  def _reduce_102(val, _values, result)
+     StructType.set_define( true )  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 374)
+  def _reduce_103(val, _values, result)
+    			StructType.end_of_parse
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 379)
+  def _reduce_104(val, _values, result)
+    			# tag が無い場合、内部名を与える
+			result = StructType.new( :"TAG__#{@@no_struct_tag_num}__" )
+			@@no_struct_tag_num += 1
+			StructType.set_define( true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 386)
+  def _reduce_105(val, _values, result)
+    			StructType.end_of_parse
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 391)
+  def _reduce_106(val, _values, result)
+    			StructType.set_define( false )
+			StructType.end_of_parse
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+# reduce 107 omitted
+
+# reduce 108 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 402)
+  def _reduce_109(val, _values, result)
+     result = StructType.new( val[0].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 408)
+  def _reduce_110(val, _values, result)
+    			val[1].each { |i|	# i: Decl
+				i.set_type( val[0] )
+				i.set_kind( :MEMBER )
+				i.check
+				StructType.new_member( i )
+			}
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 418)
+  def _reduce_111(val, _values, result)
+    			val[4].each { |i|	# i: Decl
+				i.set_type( val[3] )
+				i.set_kind( :MEMBER )
+  				i.set_specifier_list val[1]
+				i.check
+				StructType.new_member( i )
+			}
+			result = val[4]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 429)
+  def _reduce_112(val, _values, result)
+     result = [ val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 430)
+  def _reduce_113(val, _values, result)
+     result <<  val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 433)
+  def _reduce_114(val, _values, result)
+     result = [:STRING,-1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 434)
+  def _reduce_115(val, _values, result)
+     result = [:STRING,val[2]] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 435)
+  def _reduce_116(val, _values, result)
+     result = [:SIZE_IS,val[2]] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 436)
+  def _reduce_117(val, _values, result)
+     result = [:COUNT_IS,val[2]] 
+    result
+  end
+.,.,
+
+# reduce 118 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 447)
+  def _reduce_119(val, _values, result)
+    			val[1].set_qualifier( val[0] )
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 456)
+  def _reduce_120(val, _values, result)
+     result = [ val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 458)
+  def _reduce_121(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+# reduce 122 omitted
+
+# reduce 123 omitted
+
+# reduce 124 omitted
+
+# reduce 125 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 471)
+  def _reduce_126(val, _values, result)
+     result = EnumType.new( -1 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 472)
+  def _reduce_127(val, _values, result)
+     result = EnumType.new( 8 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 473)
+  def _reduce_128(val, _values, result)
+     result = EnumType.new( 16 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 474)
+  def _reduce_129(val, _values, result)
+     result = EnumType.new( 32 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 475)
+  def _reduce_130(val, _values, result)
+     result = EnumType.new( 64 ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 476)
+  def _reduce_131(val, _values, result)
+     result = EnumType.new( 128 ) 
+    result
+  end
+.,.,
+
+# reduce 132 omitted
+
+# reduce 133 omitted
+
+# reduce 134 omitted
+
+# reduce 135 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 487)
+  def _reduce_136(val, _values, result)
+     result = :CONST 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 488)
+  def _reduce_137(val, _values, result)
+     result = :VOLATILE 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 493)
+  def _reduce_138(val, _values, result)
+    			val[1].set_type( val[0] )
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+# reduce 139 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 500)
+  def _reduce_140(val, _values, result)
+     result = Decl.new( val[0].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 502)
+  def _reduce_141(val, _values, result)
+     result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 505)
+  def _reduce_142(val, _values, result)
+    			val[0].set_type( ArrayType.new( val[2] ) )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 510)
+  def _reduce_143(val, _values, result)
+    			val[0].set_type( ArrayType.new )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 515)
+  def _reduce_144(val, _values, result)
+    			val[0].set_type( FuncType.new( val[2] ) )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 521)
+  def _reduce_145(val, _values, result)
+    			Generator.warning( "W5010 need 'void' for no parameter"  )
+			val[0].set_type( FuncType.new )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 528)
+  def _reduce_146(val, _values, result)
+     result = PtrType.new 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 531)
+  def _reduce_147(val, _values, result)
+    			result = PtrType.new
+			result.set_qualifier( val[1] )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 536)
+  def _reduce_148(val, _values, result)
+    			val[1].set_type(PtrType.new)
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 541)
+  def _reduce_149(val, _values, result)
+    			ptrtype = PtrType.new
+			ptrtype.set_qualifier( val[1] )
+			val[2].set_type( ptrtype )
+			result = val[2]
+		
+    result
+  end
+.,.,
+
+# reduce 150 omitted
+
+# reduce 151 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 555)
+  def _reduce_152(val, _values, result)
+     result = ParamList.new( val[0] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 558)
+  def _reduce_153(val, _values, result)
+    			val[0].add_param( val[2] )
+			# result = val[0] 不要
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 568)
+  def _reduce_154(val, _values, result)
+    			val[2].set_kind( :PARAMETER )
+			paramdecl = ParamDecl.new( val[2], val[1], val[0] )
+			val[2].check
+			result = paramdecl
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 577)
+  def _reduce_155(val, _values, result)
+    			Generator.error( "G1001 need specifier for \'$1\'" , val[1].get_name )
+			result = nil
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 582)
+  def _reduce_156(val, _values, result)
+    			unless val[0].instance_of?( VoidType ) then
+				Generator.error( "G1002 need parameter name"  )
+			end
+			result = nil
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 590)
+  def _reduce_157(val, _values, result)
+    			unless val[1].instance_of?( VoidType ) then
+				Generator.error( "G1003 need parameter name"  )
+			end
+			result = nil
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 597)
+  def _reduce_158(val, _values, result)
+     result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 601)
+  def _reduce_159(val, _values, result)
+     result = val[0] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 603)
+  def _reduce_160(val, _values, result)
+     result = result + val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 606)
+  def _reduce_161(val, _values, result)
+     result = [ [:IN]  ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 607)
+  def _reduce_162(val, _values, result)
+     result = [ [:OUT] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 608)
+  def _reduce_163(val, _values, result)
+     result = [ [:INOUT] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 609)
+  def _reduce_164(val, _values, result)
+     result = [ [:SEND,   val[2]] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 610)
+  def _reduce_165(val, _values, result)
+     result = [ [:RECEIVE,val[2]] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 611)
+  def _reduce_166(val, _values, result)
+     result = [ [:STRING,nil] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 612)
+  def _reduce_167(val, _values, result)
+     result = [ [:STRING,  val[2]] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 613)
+  def _reduce_168(val, _values, result)
+     result = [ [:SIZE_IS, val[2]] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 616)
+  def _reduce_169(val, _values, result)
+    			result = [ [:SIZE_IS,val[2]], [:MAX_IS, val[4]] ]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 618)
+  def _reduce_170(val, _values, result)
+     result = [ [:COUNT_IS,val[2]] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 619)
+  def _reduce_171(val, _values, result)
+     result = [ [:NULLABLE] ] 
+    result
+  end
+.,.,
+
+# reduce 172 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 625)
+  def _reduce_173(val, _values, result)
+    			if val[1] then
+				val[1].set_type( val[0] )
+				result = val[1]
+			else
+				# エラー：仮で val[0] を返す
+				result = val[0]
+			end
+		
+    result
+  end
+.,.,
+
+# reduce 174 omitted
+
+# reduce 175 omitted
+
+# reduce 176 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 642)
+  def _reduce_177(val, _values, result)
+     result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 645)
+  def _reduce_178(val, _values, result)
+    			Generator.error( "G1004 impossible array type"  )
+			result = nil
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 650)
+  def _reduce_179(val, _values, result)
+    			Generator.error( "G1005 impossible array type"  )
+			result = nil
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 655)
+  def _reduce_180(val, _values, result)
+    			Generator.error( "G1006 impossible array type"  )
+			result = nil
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 660)
+  def _reduce_181(val, _values, result)
+    			Generator.error( "G1007 impossible array type"  )
+			result = nil
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 665)
+  def _reduce_182(val, _values, result)
+    			Generator.error( "G1008 impossible function type"  )
+			result = nil
+		
+    result
+  end
+.,.,
+
+# reduce 183 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 671)
+  def _reduce_184(val, _values, result)
+    			Generator.warning( "W5011 need 'void' for no parameter"  )
+			val[0].set_type( FuncType.new )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 677)
+  def _reduce_185(val, _values, result)
+    			val[0].set_type( FuncType.new( val[2] ) )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 684)
+  def _reduce_186(val, _values, result)
+     result = val[0] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 686)
+  def _reduce_187(val, _values, result)
+     result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 688)
+  def _reduce_188(val, _values, result)
+     result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 691)
+  def _reduce_189(val, _values, result)
+     result = C_EXP.new( val[2] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 696)
+  def _reduce_190(val, _values, result)
+    			result = [ val[0] ]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 700)
+  def _reduce_191(val, _values, result)
+    			val[0] << val[2]
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+# reduce 192 omitted
+
+# reduce 193 omitted
+
+# reduce 194 omitted
+
+# reduce 195 omitted
+
+# reduce 196 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 719)
+  def _reduce_197(val, _values, result)
+    			obj = val[3]
+			if obj.kind_of?( Cell ) || obj.kind_of?( Signature ) || obj.kind_of?( Celltype ) || obj.kind_of?( CompositeCelltype )then
+                                # cell, signature 以外は、指定子を置けない
+			else
+              Generator.get_statement_specifier   # クリア
+              Generator.error( "G1009 unexpected specifier"  )
+			end
+		
+    result
+  end
+.,.,
+
+# reduce 198 omitted
+
+# reduce 199 omitted
+
+# reduce 200 omitted
+
+# reduce 201 omitted
+
+# reduce 202 omitted
+
+# reduce 203 omitted
+
+# reduce 204 omitted
+
+# reduce 205 omitted
+
+# reduce 206 omitted
+
+# reduce 207 omitted
+
+# reduce 208 omitted
+
+# reduce 209 omitted
+
+# reduce 210 omitted
+
+# reduce 211 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 748)
+  def _reduce_212(val, _values, result)
+     Generator.add_statement_specifier val[0]	
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 750)
+  def _reduce_213(val, _values, result)
+     Generator.add_statement_specifier val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 754)
+  def _reduce_214(val, _values, result)
+     result = [ :ALLOCATOR, val[2] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 756)
+  def _reduce_215(val, _values, result)
+     result = [ :CALLBACK ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 758)
+  def _reduce_216(val, _values, result)
+     result = [ :CONTEXT, val[2].val ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 760)
+  def _reduce_217(val, _values, result)
+     result = [ :DEVIATE ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 762)
+  def _reduce_218(val, _values, result)
+     result = [ :ID, val[2] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 764)
+  def _reduce_219(val, _values, result)
+     result = [ :PROTOTYPE ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 766)
+  def _reduce_220(val, _values, result)
+     result = [ :RESTRICT, val[2] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 767)
+  def _reduce_221(val, _values, result)
+     result = [:SINGLETON] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 768)
+  def _reduce_222(val, _values, result)
+     result = [:IDX_IS_ID] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 769)
+  def _reduce_223(val, _values, result)
+     result = [:ACTIVE] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 771)
+  def _reduce_224(val, _values, result)
+     result = [:GENERATE, val[2].val, val[4].val] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 774)
+  def _reduce_225(val, _values, result)
+     result = [ val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 775)
+  def _reduce_226(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 779)
+  def _reduce_227(val, _values, result)
+      result = [ :NORMAL_ALLOC, val[0], nil, val[2], val[4], val[6] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 781)
+  def _reduce_228(val, _values, result)
+      result = [ :NORMAL_ALLOC, val[0], val[2], val[5], val[7], val[9] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 790)
+  def _reduce_229(val, _values, result)
+    	result = [val[0]]		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 792)
+  def _reduce_230(val, _values, result)
+    	result << val[2]		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 796)
+  def _reduce_231(val, _values, result)
+    	result = [ val[0].val, nil, val[3] ]		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 798)
+  def _reduce_232(val, _values, result)
+    	result = [ val[0].val, val[2].val, val[5] ]		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 802)
+  def _reduce_233(val, _values, result)
+    	result = [val[0]]		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 804)
+  def _reduce_234(val, _values, result)
+    	result << val[2]		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 809)
+  def _reduce_235(val, _values, result)
+    			val[0].each { |decl|
+				decl.set_kind( :CONSTANT )
+				Namespace.new_const_decl( decl )
+				decl.check
+			}
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 819)
+  def _reduce_236(val, _values, result)
+    			@@import_C = true
+			Import_C.new( val[2] )
+			@@import_C = false
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 825)
+  def _reduce_237(val, _values, result)
+    			@@import_C = true
+			Import_C.new( val[2], val[4] )
+			@@import_C = false
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 832)
+  def _reduce_238(val, _values, result)
+     Import.new( val[2] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 834)
+  def _reduce_239(val, _values, result)
+     Import.new( val[2], true ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 839)
+  def _reduce_240(val, _values, result)
+     Generate.new( val[2].val, val[4], val[6] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 844)
+  def _reduce_241(val, _values, result)
+    			val[2].each{ |i|       # i:Decl
+				i.set_kind( :TYPEDEF )
+    		}
+			Typedef.new_decl_list( val[1], val[2] )
+			val[2].each{ |i|       # i:Decl
+				i.check
+			}
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 854)
+  def _reduce_242(val, _values, result)
+    			val[5].each{ |i|       # i:Decl
+				i.set_kind( :TYPEDEF )
+			}
+			Typedef.new_decl_list( val[4], val[5] )
+			val[5].each{ |i|       # i:Decl
+				i.check
+			}
+		
+    result
+  end
+.,.,
+
+# reduce 243 omitted
+
+# reduce 244 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 871)
+  def _reduce_245(val, _values, result)
+     result = [ val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 873)
+  def _reduce_246(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 877)
+  def _reduce_247(val, _values, result)
+    val[1].end_of_parse
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 881)
+  def _reduce_248(val, _values, result)
+    result = Namespace.new(val[0].val)
+    result
+  end
+.,.,
+
+# reduce 249 omitted
+
+# reduce 250 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 889)
+  def _reduce_251(val, _values, result)
+     result = NamespacePath.new( val[0].val, false ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 890)
+  def _reduce_252(val, _values, result)
+     result = NamespacePath.new( val[1].val, true ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 892)
+  def _reduce_253(val, _values, result)
+     result = val[0].append!( val[2].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 897)
+  def _reduce_254(val, _values, result)
+     result = val[1].end_of_parse( val[3] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 901)
+  def _reduce_255(val, _values, result)
+    result = Signature.new( val[0].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 907)
+  def _reduce_256(val, _values, result)
+     result = NamedList.new( nil, "function" ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 909)
+  def _reduce_257(val, _values, result)
+     result = val[0].add_item( val[1] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 914)
+  def _reduce_258(val, _values, result)
+    			# val[1]: Decl
+			if val[1].is_function? then
+				result = FuncHead.new( val[1], val[0], false )
+				val[1].set_kind :FUNCHEAD
+				val[1].check
+			else
+				# mikan 関数の配列も以下のメッセージになる
+				Generator.error( "G1010 Not function"  )
+				result = nil
+			end
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 927)
+  def _reduce_259(val, _values, result)
+    			if val[4].is_function? then
+				result = FuncHead.new( val[4], val[3], true )
+			else
+				Generator.error( "G1011 Not function"  )
+				result = nil
+			end
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 940)
+  def _reduce_260(val, _values, result)
+    			val[1].end_of_parse
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 946)
+  def _reduce_261(val, _values, result)
+     result = Celltype.new(val[0].val) 
+    result
+  end
+.,.,
+
+# reduce 262 omitted
+
+# reduce 263 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 955)
+  def _reduce_264(val, _values, result)
+    			if val[0].kind_of? Port then
+				Celltype.new_port( val[0] )
+			end
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 961)
+  def _reduce_265(val, _values, result)
+    			if val[3].kind_of? Port then
+				val[3].set_specifier val[1]  # 設定順序あり
+				Celltype.new_port( val[3] )
+			else
+				# Port 以外では指定子はエラー
+				Generator.error( "G1012 $1 : cannot put specifier here" , val[1] )
+			end
+		
+    result
+  end
+.,.,
+
+# reduce 266 omitted
+
+# reduce 267 omitted
+
+# reduce 268 omitted
+
+# reduce 269 omitted
+
+# reduce 270 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 980)
+  def _reduce_271(val, _values, result)
+     result = [ val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 982)
+  def _reduce_272(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 985)
+  def _reduce_273(val, _values, result)
+     result = [ :INLINE ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 986)
+  def _reduce_274(val, _values, result)
+     result = [ :ALLOCATOR, val[2] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 987)
+  def _reduce_275(val, _values, result)
+     result = [ :OPTIONAL ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 988)
+  def _reduce_276(val, _values, result)
+     result = [ :REF_DESC ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 989)
+  def _reduce_277(val, _values, result)
+     result = [ :DYNAMIC ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 990)
+  def _reduce_278(val, _values, result)
+     result = [ :OMIT ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 993)
+  def _reduce_279(val, _values, result)
+     result = [ val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 994)
+  def _reduce_280(val, _values, result)
+     result = [ val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 995)
+  def _reduce_281(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 996)
+  def _reduce_282(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1000)
+  def _reduce_283(val, _values, result)
+      result = [ :INTERNAL_ALLOC, val[0].val, val[2].val, val[4] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1002)
+  def _reduce_284(val, _values, result)
+      result = [ :RELAY_ALLOC, val[0].val, val[2].val, val[4] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1008)
+  def _reduce_285(val, _values, result)
+     result = Port.new( val[2].val, val[1], val[0] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1010)
+  def _reduce_286(val, _values, result)
+     result = Port.new( val[2].val, val[1], val[0], "[]" ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1012)
+  def _reduce_287(val, _values, result)
+     result = Port.new(val[2].val, val[1], val[0], val[4]) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1014)
+  def _reduce_288(val, _values, result)
+     result = Port.new( val[2].val, val[1], val[0], nil, val[4], val[ 6 ].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1017)
+  def _reduce_289(val, _values, result)
+     result = :CALL 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1018)
+  def _reduce_290(val, _values, result)
+     result = :ENTRY 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1022)
+  def _reduce_291(val, _values, result)
+     result = val[0] 
+    result
+  end
+.,.,
+
+# reduce 292 omitted
+
+# reduce 293 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1034)
+  def _reduce_294(val, _values, result)
+     result = nil 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1038)
+  def _reduce_295(val, _values, result)
+     Celltype.new_attribute( val[0] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1040)
+  def _reduce_296(val, _values, result)
+     Celltype.new_attribute( val[1] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1046)
+  def _reduce_297(val, _values, result)
+    			val[0].each{ |i|       # i:Decl
+				i.set_kind( :ATTRIBUTE )
+				i.check
+			}
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1054)
+  def _reduce_298(val, _values, result)
+    			val[3].each{ |i|       # i:Decl
+				i.set_kind( :ATTRIBUTE )   # 設定順序あり
+				i.set_specifier_list( [val[1]] )
+				i.check
+			}
+			result = val[3]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1063)
+  def _reduce_299(val, _values, result)
+     result = [:OMIT] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1064)
+  def _reduce_300(val, _values, result)
+     result = [:SIZE_IS,val[2]] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1065)
+  def _reduce_301(val, _values, result)
+      result = [:CHOICE,val[3]] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1068)
+  def _reduce_302(val, _values, result)
+      result << val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1069)
+  def _reduce_303(val, _values, result)
+      result = [ val[0] ] 
+    result
+  end
+.,.,
+
+# reduce 304 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1077)
+  def _reduce_305(val, _values, result)
+     result = nil 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1081)
+  def _reduce_306(val, _values, result)
+     Celltype.new_var( val[0] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1083)
+  def _reduce_307(val, _values, result)
+     Celltype.new_var( val[1] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1088)
+  def _reduce_308(val, _values, result)
+    			val[0].each{ |i|       # i:Decl
+				i.set_kind( :VAR )
+				i.check
+			}
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1095)
+  def _reduce_309(val, _values, result)
+    			val[3].each{ |i|       # i:Decl
+				i.set_kind( :VAR )   # 設定順序あり
+				i.set_specifier_list( [val[1]] )
+				i.check
+			}
+			result = val[3]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1104)
+  def _reduce_310(val, _values, result)
+     result = [:SIZE_IS,val[2]] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1110)
+  def _reduce_311(val, _values, result)
+    			Celltype.new_require( val[1], val[3] )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1114)
+  def _reduce_312(val, _values, result)
+    			Celltype.new_require( val[3], val[5], val[1].val )
+		
+    result
+  end
+.,.,
+
+# reduce 313 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1122)
+  def _reduce_314(val, _values, result)
+     Factory.set_f_celltype( false ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1123)
+  def _reduce_315(val, _values, result)
+     Factory.set_f_celltype( true ) 
+    result
+  end
+.,.,
+
+# reduce 316 omitted
+
+# reduce 317 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1131)
+  def _reduce_318(val, _values, result)
+     Factory.new( val[0].val, val[2], val[4], nil    ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1133)
+  def _reduce_319(val, _values, result)
+     Factory.new( val[0].val, val[2], val[4], val[6] ) 
+    result
+  end
+.,.,
+
+# reduce 320 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1140)
+  def _reduce_321(val, _values, result)
+     result = [ [ :IDENTIFIER, val[0].val ] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1142)
+  def _reduce_322(val, _values, result)
+     result << [ :IDENTIFIER, val[2].val ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1144)
+  def _reduce_323(val, _values, result)
+     result = [ [ :STRING_LITERAL, val[0].val ] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1146)
+  def _reduce_324(val, _values, result)
+     result << [ :STRING_LITERAL, val[2].val ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1151)
+  def _reduce_325(val, _values, result)
+     Cell.new_def 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1153)
+  def _reduce_326(val, _values, result)
+     result = Cell.end_of_parse true 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1155)
+  def _reduce_327(val, _values, result)
+     result = Cell.end_of_parse false 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1159)
+  def _reduce_328(val, _values, result)
+     result = Cell.new(val[0]) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1163)
+  def _reduce_329(val, _values, result)
+     result = Cell.set_name(val[0].val) 
+    result
+  end
+.,.,
+
+# reduce 330 omitted
+
+# reduce 331 omitted
+
+# reduce 332 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1172)
+  def _reduce_333(val, _values, result)
+     val[3].set_specifier_list( val[1] )  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1174)
+  def _reduce_334(val, _values, result)
+     val[0].set_specifier_list( [] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1178)
+  def _reduce_335(val, _values, result)
+     result << val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1180)
+  def _reduce_336(val, _values, result)
+     result = [val[0]] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1184)
+  def _reduce_337(val, _values, result)
+     result = [ :THROUGH, val[2], val[4] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1187)
+  def _reduce_338(val, _values, result)
+     result = val[0] 
+    result
+  end
+.,.,
+
+# reduce 339 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1201)
+  def _reduce_340(val, _values, result)
+    			result = Join.new( val[0].val,  -1, val[4] )
+			Cell.new_join( result, true )
+		 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1206)
+  def _reduce_341(val, _values, result)
+    			result = Join.new( val[0].val, val[2], val[5] )
+			Cell.new_join( result, true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1211)
+  def _reduce_342(val, _values, result)
+    			result = Join.new( val[0].val, nil, val[2] )
+			Cell.new_join( result, true )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1216)
+  def _reduce_343(val, _values, result)
+    			result = Join.new( val[0].val, nil, [ :COMPOSITE, val[4] ] )
+			Cell.new_join( result, true )
+		
+    result
+  end
+.,.,
+
+# reduce 344 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1227)
+  def _reduce_345(val, _values, result)
+    			rj = ReverseJoin.new( val[0].val, nil, val[2], val[4].val )
+			Cell.new_reverse_join( rj )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1233)
+  def _reduce_346(val, _values, result)
+    			rj = ReverseJoin.new( val[0].val, nil, val[2], val[4].val, val[6] )
+			Cell.new_reverse_join( rj )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1239)
+  def _reduce_347(val, _values, result)
+    			rj = ReverseJoin.new( val[0].val, val[2], val[5], val[7].val )
+			Cell.new_reverse_join( rj )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1245)
+  def _reduce_348(val, _values, result)
+    			rj = ReverseJoin.new( val[0].val, val[2], val[5], val[7].val, val[9] )
+			Cell.new_reverse_join( rj )
+		
+    result
+  end
+.,.,
+
+# reduce 349 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1257)
+  def _reduce_350(val, _values, result)
+    			CompositeCelltype.end_of_parse
+			result = val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1263)
+  def _reduce_351(val, _values, result)
+     result = CompositeCelltype.new(val[0].val) 
+    result
+  end
+.,.,
+
+# reduce 352 omitted
+
+# reduce 353 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1272)
+  def _reduce_354(val, _values, result)
+    			if val[0].kind_of?( Port ) then
+				CompositeCelltype.new_port( val[0] )   # 遅延して登録
+			end
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1278)
+  def _reduce_355(val, _values, result)
+    			if val[3].kind_of?( Port ) then
+				# port 以外 val[3] に有効な値が入っていないので、以下のメソッドを適用できない
+				# 現状 port, cell 以外は指定子を受け付けない
+				# （しかし将来他の文も指定子を受け付ける可能性があるので、この位置に記述する）
+				val[3].set_specifier( Generator.get_statement_specifier )
+				CompositeCelltype.new_port( val[3] )   # 遅延して登録 (set_specifier 後)
+			elsif val[3].kind_of?( Cell ) then
+				# Cell.end_of_parse にて設定
+			else
+              Generator.get_statement_specifier   # クリア
+              Generator.error( "G1013 unexpected specifier"  )
+			end
+		
+    result
+  end
+.,.,
+
+# reduce 356 omitted
+
+# reduce 357 omitted
+
+# reduce 358 omitted
+
+# reduce 359 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1302)
+  def _reduce_360(val, _values, result)
+    			Generator.add_statement_specifier val[0]
+			result = [ val[0] ]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1307)
+  def _reduce_361(val, _values, result)
+    			Generator.add_statement_specifier val[2]
+			result = val[0] << val[2]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1312)
+  def _reduce_362(val, _values, result)
+     result = [ :ALLOCATOR, val[2] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1313)
+  def _reduce_363(val, _values, result)
+     result = [ :OMIT ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1314)
+  def _reduce_364(val, _values, result)
+     result = [ :OPTIONAL ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1315)
+  def _reduce_365(val, _values, result)
+     result = [ :REF_DESC ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1316)
+  def _reduce_366(val, _values, result)
+     result = [ :DYNAMIC ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1321)
+  def _reduce_367(val, _values, result)
+    			# CompositeCelltype.new_port( val[0] )
+			result = val[0]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1328)
+  def _reduce_368(val, _values, result)
+     result = nil 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1332)
+  def _reduce_369(val, _values, result)
+     CompositeCelltype.new_attribute( val[0] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1334)
+  def _reduce_370(val, _values, result)
+     CompositeCelltype.new_attribute( val[1] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1339)
+  def _reduce_371(val, _values, result)
+     Cell.new_def 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1341)
+  def _reduce_372(val, _values, result)
+     result = Cell.end_of_parse true 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1343)
+  def _reduce_373(val, _values, result)
+     result = Cell.end_of_parse false 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1348)
+  def _reduce_374(val, _values, result)
+     Cell.new(val[0],true) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1352)
+  def _reduce_375(val, _values, result)
+     Cell.set_name(val[0].val) 
+    result
+  end
+.,.,
+
+# reduce 376 omitted
+
+# reduce 377 omitted
+
+# reduce 378 omitted
+
+# reduce 379 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1363)
+  def _reduce_380(val, _values, result)
+    	Cell.external_join( val[0].val, val[4].val, true )	
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1365)
+  def _reduce_381(val, _values, result)
+    	Cell.external_join( val[0].val, val[2].val, false )	
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1372)
+  def _reduce_382(val, _values, result)
+    			CompositeCelltype.new_join( val[0].val,
+						val[2].val, val[4].val, :ENTRY )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1377)
+  def _reduce_383(val, _values, result)
+    			CompositeCelltype.new_join( val[2].val,
+						val[4].val, val[6].val, :ENTRY )
+		
+    result
+  end
+.,.,
+
+# reduce 384 omitted
+
+# reduce 385 omitted
+
+# reduce 386 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1393)
+  def _reduce_387(val, _values, result)
+     Region.end_of_parse 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1395)
+  def _reduce_388(val, _values, result)
+     Region.end_of_parse 
+    result
+  end
+.,.,
+
+# reduce 389 omitted
+
+# reduce 390 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1404)
+  def _reduce_391(val, _values, result)
+     Region.new_in_through( val[2].val, val[4].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1406)
+  def _reduce_392(val, _values, result)
+     Region.new_in_through 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1408)
+  def _reduce_393(val, _values, result)
+     Region.new_out_through( val[2].val, val[4].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1410)
+  def _reduce_394(val, _values, result)
+     Region.new_out_through() 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1412)
+  def _reduce_395(val, _values, result)
+     Region.new_to_through( val[2], val[4].val, val[6].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1414)
+  def _reduce_396(val, _values, result)
+     Region.new_to_through( val[2], nil, nil ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1416)
+  def _reduce_397(val, _values, result)
+     Region.set_type( :NODE ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1418)
+  def _reduce_398(val, _values, result)
+     Region.set_type( :LINKUNIT ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1420)
+  def _reduce_399(val, _values, result)
+     Region.set_domain( val[2].val, val[4] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1422)
+  def _reduce_400(val, _values, result)
+     Region.set_type( :CLASS, val[2].val ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1426)
+  def _reduce_401(val, _values, result)
+     result = Region.new( val[0].val ) 
+    result
+  end
+.,.,
+
+# reduce 402 omitted
+
+# reduce 403 omitted
+
+# reduce 404 omitted
+
+# reduce 405 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1437)
+  def _reduce_406(val, _values, result)
+    			obj = val[3]
+			if obj.kind_of?( Cell ) then
+			else
+              Generator.get_statement_specifier   # クリア
+              Generator.error( "G9999 unexpected specifier"  )
+			end
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1459)
+  def _reduce_407(val, _values, result)
+     result = [ val[0].val ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1464)
+  def _reduce_408(val, _values, result)
+     set_in_specifier 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1466)
+  def _reduce_409(val, _values, result)
+     unset_in_specifier 
+    result
+  end
+.,.,
+
+# reduce 410 omitted
+
+# reduce 411 omitted
+
+# reduce 412 omitted
+
+# reduce 413 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1480)
+  def _reduce_414(val, _values, result)
+    			TECSGEN::Cell_location.new( val[1], val[3], val[5], val[7], val[9], val[12] )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1486)
+  def _reduce_415(val, _values, result)
+    			result = val[0] << val[1]
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1489)
+  def _reduce_416(val, _values, result)
+     result = [] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1493)
+  def _reduce_417(val, _values, result)
+     result = [ val[0], val[2], val[3] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1498)
+  def _reduce_418(val, _values, result)
+                TECSGEN::Join_location.new( val[2], val[4], val[6], val[8], val[11] )
+		
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1504)
+  def _reduce_419(val, _values, result)
+                result = val[0] << [ val[1], val[3] ]
+          
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1506)
+  def _reduce_420(val, _values, result)
+     result = [] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1510)
+  def _reduce_421(val, _values, result)
+     TOOL_INFO.new( val[2].to_sym, val[4] ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1511)
+  def _reduce_422(val, _values, result)
+      result = val[1] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1512)
+  def _reduce_423(val, _values, result)
+     result = { val[0].to_sym => val[2] } 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1514)
+  def _reduce_424(val, _values, result)
+     val[0][ val[2].to_sym ] = val[4] 
+    result
+  end
+.,.,
+
+# reduce 425 omitted
+
+# reduce 426 omitted
+
+# reduce 427 omitted
+
+# reduce 428 omitted
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1516)
+  def _reduce_429(val, _values, result)
+     result=val[0].val 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1516)
+  def _reduce_430(val, _values, result)
+     result=val[0].val 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1517)
+  def _reduce_431(val, _values, result)
+     result = val[1]  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1518)
+  def _reduce_432(val, _values, result)
+     result = []  
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1519)
+  def _reduce_433(val, _values, result)
+     result = [ val[0] ] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1520)
+  def _reduce_434(val, _values, result)
+     val[0] << val[2] 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1521)
+  def _reduce_435(val, _values, result)
+     result = val[0].val.gsub!( /\"(.*)\"/, "\\1" ) 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1522)
+  def _reduce_436(val, _values, result)
+     result = val[0].val.to_i 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1523)
+  def _reduce_437(val, _values, result)
+     result = val[0].val.to_f 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1524)
+  def _reduce_438(val, _values, result)
+     result = - val[0].val.to_i 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1525)
+  def _reduce_439(val, _values, result)
+     result = - val[0].val.to_f 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1526)
+  def _reduce_440(val, _values, result)
+     result = val[0].val.to_i 
+    result
+  end
+.,.,
+
+module_eval(<<'.,.,', 'bnf.y.rb', 1527)
+  def _reduce_441(val, _values, result)
+     result = val[0].val.to_f 
+    result
+  end
+.,.,
+
+def _reduce_none(val, _values, result)
+  val[0]
+end
+
+end   # class Generator
+
+
+
+# ファイル => INCLUDE("header")の配列
+Include = Hash.new {|hash, key| hash[key] = []}
+
+
+class Token
+
+  attr_accessor :val, :file, :lineno, :col
+
+  def initialize(val, file, lineno, col)
+    @val = val
+    @file = file
+    @lineno = lineno
+    @col = col
+
+  end
+
+  def to_s
+    @val.to_s
+  end
+
+  def to_sym
+    @val.to_sym
+  end
+
+  def get_name
+    @val
+  end
+
+  def locale
+    [@file, @lineno, @col]
+  end
+
+  def eql?(other)
+    if other.is_a? Symbol
+      @val == other
+    elsif other.is_a? Token
+      @val == other.val
+    elsif other.is_a? String
+      @val.to_s == other
+    else
+      raise ArgumentError
+    end
+  end
+
+  alias == eql?
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    print "#{@val}\n"
+  end
+
+end
+
+#= TECSIO
+#  Ruby2.0(1.9) 対応に伴い導入したクラス
+#  SJIS 以外では、ASCII-8BIT として入力する
+class TECSIO
+  def self.foreach(file) # ブロック引数 { |line| }
+    pr = Proc.new   # このメソッドのブロック引数を pr に代入
+    if $b_no_kcode then
+	  msg = "E".encode $Ruby19_File_Encode
+      if( $Ruby19_File_Encode == "Shift_JIS" )
+
+        # Shift JIS は、いったん Windows-31J として読み込ませ、Shift_JIS に変換させる．
+        # コメント等に含まれる SJIS に不適切な文字コードは '?' または REPLACEMENT CHARACTER に変換される．
+        # EUC や UTF-8 で記述された CDL が混在していても、Ruby 例外が発生することなく処理を進めることができる．
+        # 文字コード指定が SJIS であって、文字列リテラルの中に、文字コードがSJIS 以外の非 ASCII が含まれている場合、
+        # Ruby 1.8 の tecsgen では文字コード指定に影響なく処理されたものが、Ruby 1.9 以降では '?' に置き換わる可能性がある．
+
+        mode = "r:Windows-31J"
+      else
+        mode = "r:#{$Ruby19_File_Encode}"
+      end
+      # mode = "r"
+    else
+	  msg = "E"
+      mode = "r"
+    end
+
+    f = File.open( file, mode )
+    begin
+      f.each{ |line|
+        # dbgPrint line
+        line = str_code_convert( msg, line )
+        pr.call( line )
+      }
+    ensure
+      f.close
+    end
+  end
+
+  #=== 文字コードが相違する場合一致させる
+  # msg と str の文字コードが相違する場合、str を msg の文字コードに変換する
+  # 変換不可の文字コードは '?' (utf-8 の場合 U+FFFD (REPLACEMENT CHARACTER )) に変換
+  #
+  # このメソッドは、エラーメッセージ出力でも使用されていることに注意．
+  #
+  #msg_enc::Encode | String
+  def self.str_code_convert( msg, str )
+    if $b_no_kcode == false then
+      return str                          # Ruby V1.8 まで
+    end
+    if msg.encoding != str.encoding then
+      option = { :invalid => :replace, :undef => :replace }   # 例外を発生させず、'?' に変換する(utf-8 は 0xfffd)
+      # return str.encode( msg.encoding, option )
+      str = str.encode( "utf-8", option )
+      return str.encode( msg.encoding, option )
+    else
+      return str
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/bnf.y.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/bnf.y.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/bnf.y.rb	(revision 398)
@@ -0,0 +1,2225 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+class Generator
+rule
+# トップレベルの構文要素はcomponent_description
+all: component_description
+
+# Expr
+##########################  式  ##########################
+# K&Rの文法(プログラミング言語C 第2版 付録)と一部異なる
+# argument_expression_list(関数引数), assignment_expression(代入)がない
+# 式の result は、すべて配列で第一要素が識別シンボル、第二要素以下が引数
+
+primary_expression
+        : namespace_identifier
+		{ result = [ :IDENTIFIER, val[0] ] }     #1ok
+        | TRUE
+		{ result = [ :BOOL_CONSTANT, true ] }
+        | FALSE
+		{ result = [ :BOOL_CONSTANT, false ] }
+        | INTEGER_CONSTANT
+		{ result = [ :INTEGER_CONSTANT, val[0] ] }
+        | FLOATING_CONSTANT
+		{ result = [ :FLOATING_CONSTANT, val[0] ] }
+        | OCTAL_CONSTANT
+		{ result = [ :OCTAL_CONSTANT, val[0] ] }
+        | HEX_CONSTANT
+		{ result = [ :HEX_CONSTANT, val[0] ] }
+        | CHARACTER_LITERAL
+		{ result = [ :CHARACTER_LITERAL, val[0] ] }
+        | string_literal_list
+		{ result = [ :STRING_LITERAL_LIST, val[0] ] }
+        | '(' expression ')'
+		{ result = [ :PARENTHESES, val[1].get_elements ] }
+
+string_literal_list
+        : STRING_LITERAL
+        | string_literal_list STRING_LITERAL
+		{
+			# 連接した文字列を1つの文字列にまとめる
+			str = "\"" + val[0].val.gsub( /\"(.*)\"/, "\\1" ) + val[1].val.gsub( /\"(.*)\"/, "\\1" ) + "\""
+			result = Token.new( str, val[0].file, val[0].lineno, val[0].col )
+		}
+
+# 関数呼び出しと後置インクリメント、デクリメント演算子がない
+postfix_expression
+        : primary_expression
+        | postfix_expression '[' expression ']'
+		{ result = [ :OP_SUBSC, val[0], val[2] ] }
+        | postfix_expression '.' IDENTIFIER
+		{ result = [ :OP_DOT, val[0], val[2] ] }
+        | postfix_expression '->' IDENTIFIER
+		{ result = [ :OP_REF, val[0], val[2] ] }
+
+# 前置インクリメント、デクリメント演算子がない
+unary_expression
+        : postfix_expression
+        | unary_operator cast_expression
+		{ result = [ val[0], val[1] ] }
+        | SIZEOF unary_expression
+		{ result = [ :OP_SIZEOF_EXPR, val[1] ] }
+        | SIZEOF '(' type_name ')'
+		{ result = [ :OP_SIZEOF_TYPE, val[1] ] }
+
+unary_operator
+        : '&'	{ result = :OP_U_AMP }
+        | '*'	{ result = :OP_U_ASTER }
+        | '+'	{ result = :OP_U_PLUS }
+        | '-'	{ result = :OP_U_MINUS }
+        | '~'	{ result = :OP_U_TILDE }
+        | '!'	{ result = :OP_U_EXCLAM }
+
+cast_expression
+        : unary_expression
+        | '(' type_name ')' cast_expression
+		{  result = [ :CAST, val[1], val[3] ] }
+
+multiplicative_expression
+        : cast_expression
+        | multiplicative_expression '*' cast_expression
+		{ result = [ :OP_MULT, val[0], val[2] ]  }
+        | multiplicative_expression '/' cast_expression
+		{ result = [ :OP_DIV, val[0], val[2] ]  }
+        | multiplicative_expression '%' cast_expression
+		{ result = [ :OP_REMAIN, val[0], val[2] ]  }
+
+additive_expression
+        : multiplicative_expression
+        | additive_expression '+' multiplicative_expression
+		{ result = [ :OP_ADD, val[0], val[2] ]  }
+        | additive_expression '-' multiplicative_expression
+		{ result = [ :OP_SUB, val[0], val[2] ]  }
+
+shift_expression
+        : additive_expression
+        | shift_expression '<<' additive_expression
+		{ result = [ :OP_LSFT, val[0], val[2] ]  }
+        | shift_expression '>>' additive_expression
+		{ result = [ :OP_RSFT, val[0], val[2] ]  }
+
+relational_expression
+        : shift_expression
+        | relational_expression '<' shift_expression
+		{ result = [ :OP_LT, val[0], val[2] ]  }
+        | relational_expression '>' shift_expression
+		{ result = [ :OP_GT, val[0], val[2] ]  }
+        | relational_expression '<=' shift_expression
+		{ result = [ :OP_LE, val[0], val[2] ]  }
+        | relational_expression '>=' shift_expression
+		{ result = [ :OP_GE, val[0], val[2] ]  }
+
+equality_expression
+        : relational_expression
+        | equality_expression '==' relational_expression
+		{ result = [ :OP_EQ, val[0], val[2] ]  }
+        | equality_expression '!=' relational_expression
+		{ result = [ :OP_NE, val[0], val[2] ]  }
+
+and_expression
+        : equality_expression
+        | and_expression '&' equality_expression
+		{ result = [ :OP_AND, val[0], val[2] ]  }
+
+exclusive_or_expression
+        : and_expression
+        | exclusive_or_expression '^' and_expression
+		{ result = [ :OP_EOR, val[0], val[2] ]  }
+
+inclusive_or_expression
+        : exclusive_or_expression
+        | inclusive_or_expression '|' exclusive_or_expression
+		{ result = [ :OP_OR, val[0], val[2] ]  }
+
+logical_and_expression
+        : inclusive_or_expression
+        | logical_and_expression '&&' inclusive_or_expression
+		{ result = [ :OP_LAND, val[0], val[2] ]  }
+
+logical_or_expression
+        : logical_and_expression
+        | logical_or_expression '||' logical_and_expression
+		{ result = [ :OP_LOR, val[0], val[2] ]  }
+
+conditional_expression
+        : logical_or_expression
+        | logical_or_expression '?' expression ':' conditional_expression
+		{ result = [ :OP_CEX, val[0], val[2].get_elements, val[4] ]  }
+
+
+# コンマ演算子が使えない
+expression
+        : conditional_expression
+		{
+			result = Expression.new( val[0] )
+			# result.print
+		}
+
+constant_expression
+        : conditional_expression
+		{
+			result = Expression.new( val[0] )
+			# result.print
+
+			# res = result.eval_const( nil )
+			# if res then
+			#   puts "val: #{res}"
+			# else
+			#   puts "val: nil"
+			# end
+		}
+
+
+
+# Types
+##########################  宣言  ##########################
+# 宣言もK&Rと一部異なる
+
+# declarationはセルの属性で使われる
+# K&Rとの違い: storage classが指定できない、型が省略できない
+declaration
+        : type_specifier_qualifier_list init_declarator_list ';'
+		{
+			val[1].each { |i|	# i: Decl
+				i.set_type( val[0] )
+			}
+			result = val[1]
+		}
+
+# declaration_specifiersは関数のパラメータで使われるが、
+# type_specifier_qualifier_listで十分かもしれない
+# Oyama
+# const, volatile は単独で型にならないので変形
+# const と volatile が同居することはないので、繰返し指定できないようにした
+# type_specifier も繰返し指定できる必要はない (singed など単独で型にはならない)
+declaration_specifiers
+        : type_specifier
+        | type_qualifier type_specifier
+		{
+			val[1].set_qualifier( val[0] )
+			result = val[1]
+		}
+
+init_declarator_list
+        : init_declarator
+		{ result = [val[0]] }
+        | init_declarator_list ',' init_declarator
+		{ result << val[2] }
+
+init_declarator
+        : declarator
+        | declarator '=' initializer
+		{ val[0].set_initializer( val[2] ) }
+
+# INT8から下はK&Rにない
+# Oyama
+# signed, unsigned は単独で型にならないので、構文要素として分離
+type_specifier
+        : VOID	{ result = VoidType.new }
+        | FLOAT32_T	{ result = FloatType.new(32) }
+        | DOUBLE64_T	{ result = FloatType.new(64) }
+        | struct_specifier
+        | enum_specifier
+        | TYPE_NAME	{ result = DefinedType.new( val[0].val ) }
+#        | IDENTIFIER	{ result = DefinedType.new( val[0].val ) }   # reduce/reduce conflict が起こってしまう
+        | sign_int_type
+        | char_type
+        | BOOL_T	{ result = BoolType.new }
+#        | BOOL	{
+#			Generator.warning( "W5001 bool: obsolete type. use bool_t"  )
+#			result = BoolType.new
+#		}
+        | FLOAT	{
+			Generator.warning( "W5002 float: obsolete type. use float32_t"  )
+			result = FloatType.new(32)
+		}
+        | DOUBLE {
+			Generator.warning( "W5003 double: obsolete type. use double64_t"  )
+			result = FloatType.new(64)
+		}
+        | DESCRIPTOR '(' namespace_identifier ')' {          # namespace_identifier: signature name
+			result = DescriptorType.new( val[2] )
+		}
+
+char_type
+        : CHAR_T	{ result = IntType.new( -1 ) }
+        | SCHAR_T
+		{
+			result = IntType.new( -1 )
+			result.set_sign( :SIGNED, true )
+		}
+        | UCHAR_T
+		{
+			result = IntType.new( -1 )
+			result.set_sign( :UNSIGNED, true )
+		}
+
+int_type
+        : CHAR	{
+			# Generator.warning( "W5004 char: obsolete type. use char_t"  )
+			result = IntType.new( -11 )
+		}
+        | SHORT	{ result = IntType.new( -2 ) }
+        | INT		{ result = IntType.new( -3 ) }
+        | LONG	{ result = IntType.new( -4 ) }
+#        | INTPTR	{ result = IntType.new( -5 ) }
+#        | INT8	{
+#			Generator.warning( "W5005 int8: obsolete. use int8_t"  )
+#			result = IntType.new(  8 )
+#		}
+#        | INT16	{
+#			Generator.warning( "W5006 int16: obsolete. use int16_t"  )
+#			result = IntType.new( 16 )
+#		}
+#        | INT32	{
+#			Generator.warning( "W5007 int32: obsolete. use int32_t"  )
+#			result = IntType.new( 32 )
+#		}
+#        | INT64
+#		{
+#			Generator.warning( "W5008 int64: obsolete. use int64_t"  )
+#			result = IntType.new( 64 )
+#		}
+#        | INT128
+#		{
+#			Generator.warning( "W5009 int64: obsolete. use int64_t"  )
+#			result = IntType.new( 128 )
+#		}
+        | INT8_T	{ result = IntType.new( 8 ) }
+        | INT16_T	{ result = IntType.new( 16 ) }
+        | INT32_T	{ result = IntType.new( 32 ) }
+        | INT64_T	{ result = IntType.new( 64 ) }
+        | INT128_T	{ result = IntType.new( 128 ) }
+        | UINT8_T
+		{
+			result = IntType.new( 8 )
+			result.set_sign( :UNSIGNED, true )
+		}
+        | UINT16_T
+		{
+			result = IntType.new( 16 )
+			result.set_sign( :UNSIGNED, true )
+		}
+        | UINT32_T
+		{
+			result = IntType.new( 32 )
+			result.set_sign( :UNSIGNED, true )
+		}
+        | UINT64_T
+		{
+			result = IntType.new( 64 )
+			result.set_sign( :UNSIGNED, true )
+		}
+        | UINT128_T
+		{
+			result = IntType.new( 128 )
+			result.set_sign( :UNSIGNED, true )
+		}
+
+sign    # TECS では signed, unsigned 単独では型にできない
+        : SIGNED	{ result = :SIGNED }
+        | UNSIGNED	{ result = :UNSIGNED }
+
+# result[0] :CHAR などのトークン、result[1] :CONST, :VOLATILE など
+sign_int_type
+        : sign int_type
+		{
+			val[1].set_sign( val[0] )
+			result = val[1]
+		}
+        | int_type
+
+# K&Rのstruct_or_union_specifierに相当するが、unionは使えない
+struct_specifier		# mikan
+        : STRUCT struct_tag '{'
+		{ StructType.set_define( true )  }
+	   struct_declaration_list '}'
+		{
+			StructType.end_of_parse
+			result = val[1]
+		}
+        | STRUCT
+		{
+			# tag が無い場合、内部名を与える
+			result = StructType.new( :"TAG__#{@@no_struct_tag_num}__" )
+			@@no_struct_tag_num += 1
+			StructType.set_define( true )
+		}
+	   '{' struct_declaration_list '}'
+		{
+			StructType.end_of_parse
+			result = val[1]
+		}
+        | STRUCT struct_tag   # mikan struct_tag は namespace 対応が必要
+		{
+			StructType.set_define( false )
+			StructType.end_of_parse
+			result = val[1]
+		}
+
+struct_declaration_list
+        : struct_declaration
+        | struct_declaration_list struct_declaration
+
+struct_tag:
+	IDENTIFIER
+		{ result = StructType.new( val[0].val ) }
+
+# ポインタ修飾子を追加
+struct_declaration
+        :                                type_specifier_qualifier_list struct_declarator_list ';'
+		{
+			val[1].each { |i|	# i: Decl
+				i.set_type( val[0] )
+				i.set_kind( :MEMBER )
+				i.check
+				StructType.new_member( i )
+			}
+			result = val[1]
+		}
+        | spec_L pointer_specifier_list spec_R type_specifier_qualifier_list struct_declarator_list ';'
+		{
+			val[4].each { |i|	# i: Decl
+				i.set_type( val[3] )
+				i.set_kind( :MEMBER )
+  				i.set_specifier_list val[1]
+				i.check
+				StructType.new_member( i )
+			}
+			result = val[4]
+		}
+
+pointer_specifier_list
+        : pointer_specifier                               { result = [ val[0] ] }
+        | pointer_specifier_list ',' pointer_specifier    { result <<  val[2] }
+
+pointer_specifier
+        : STRING				{ result = [:STRING,-1] }
+        | STRING   '(' expression ')'	{ result = [:STRING,val[2]] }
+        | SIZE_IS  '(' expression ')'	{ result = [:SIZE_IS,val[2]] }
+        | COUNT_IS '(' expression ')'	{ result = [:COUNT_IS,val[2]] }
+
+
+# K&Rのspecifier_qualifier_listと同じ
+# 名前がまぎらわしかったのでtype_を付けた
+type_specifier_qualifier_list
+# Oyama type_specifier を繰り返して指定することはなくなった (sign_int_type としたため）
+#        : type_specifier type_specifier_qualifier_list
+        : type_specifier
+        | type_qualifier type_specifier_qualifier_list
+		{
+			val[1].set_qualifier( val[0] )
+			result = val[1]
+		}
+# mikan Oyama type_qualifier だけでは型指定にならない : 構文エラーとするより、意味エラーとした方が親切
+#        | type_qualifier
+
+
+struct_declarator_list
+        : struct_declarator
+		{ result = [ val[0] ] }
+        | struct_declarator_list ',' struct_declarator
+		{ result << val[2] }
+
+# ビットフィールドは使えない
+struct_declarator
+        : declarator
+
+# enumの種類を追加
+enum_specifier		# mikan
+        : enum_type            '{' enumerator_list '}'
+        | enum_type IDENTIFIER '{' enumerator_list '}'
+        | enum_type IDENTIFIER
+
+enum_type
+        : ENUM	{ result = EnumType.new( -1 ) }
+        | ENUM8	{ result = EnumType.new( 8 ) }
+        | ENUM16	{ result = EnumType.new( 16 ) }
+        | ENUM32	{ result = EnumType.new( 32 ) }
+        | ENUM64	{ result = EnumType.new( 64 ) }
+        | ENUM128	{ result = EnumType.new( 128 ) }
+
+enumerator_list
+        : enumerator
+        | enumerator_list ',' enumerator
+
+enumerator
+        : IDENTIFIER
+        | IDENTIFIER '=' constant_expression
+
+type_qualifier
+        : CONST	{ result = :CONST }
+        | VOLATILE	{ result = :VOLATILE }
+
+declarator
+        : pointer direct_declarator
+		{
+			val[1].set_type( val[0] )
+			result = val[1]
+		}
+        | direct_declarator
+
+direct_declarator		# mikan
+        : IDENTIFIER
+		{ result = Decl.new( val[0].val ) }
+        | '(' declarator ')'
+		{ result = val[1] }
+        | direct_declarator '[' constant_expression ']'
+		{
+			val[0].set_type( ArrayType.new( val[2] ) )
+			result = val[0]
+		}
+        | direct_declarator '[' ']'
+		{
+			val[0].set_type( ArrayType.new )
+			result = val[0]
+		}
+        | direct_declarator '(' parameter_type_list ')'
+		{
+			val[0].set_type( FuncType.new( val[2] ) )
+			result = val[0]
+		}
+#        | direct_declarator '(' identifier_list ')'  # これは何のために必要？ 060211
+        | direct_declarator '(' ')'
+		{
+			Generator.warning( "W5010 need 'void' for no parameter"  )
+			val[0].set_type( FuncType.new )
+			result = val[0]
+		}
+
+pointer
+        : '*'
+		{ result = PtrType.new }
+        | '*' type_qualifier
+		{
+			result = PtrType.new
+			result.set_qualifier( val[1] )
+		}
+        | '*' pointer
+		{
+			val[1].set_type(PtrType.new)
+			result = val[1]
+		}
+        | '*' type_qualifier pointer
+		{
+			ptrtype = PtrType.new
+			ptrtype.set_qualifier( val[1] )
+			val[2].set_type( ptrtype )
+			result = val[2]
+		}
+
+
+parameter_type_list
+        : parameter_list
+        | parameter_list ',' '...'
+		# mikan 可変長パラメータ
+
+parameter_list
+        : parameter_declaration
+		{ result = ParamList.new( val[0] ) }
+        | parameter_list ',' parameter_declaration
+		{
+			val[0].add_param( val[2] )
+			# result = val[0] 不要
+		}
+
+
+# パラメータ修飾子を追加
+parameter_declaration
+#        : spec_L parameter_specifier_list spec_R declaration_specifiers declarator
+        : parameter_specifier_list_bracket declaration_specifiers  declarator
+		{
+			val[2].set_kind( :PARAMETER )
+			paramdecl = ParamDecl.new( val[2], val[1], val[0] )
+			val[2].check
+			result = paramdecl
+		}
+
+	# 以下はエラーとする
+        | declaration_specifiers declarator # parameter_specifier なしは扱わない
+		{
+			Generator.error( "G1001 need specifier for \'$1\'" , val[1].get_name )
+			result = nil
+		}
+        | declaration_specifiers	# 仮引数なしは、とりあえず扱わない 060210
+		{
+			unless val[0].instance_of?( VoidType ) then
+				Generator.error( "G1002 need parameter name"  )
+			end
+			result = nil
+		}
+#        | '[' parameter_specifier_list ']' declaration_specifiers # 同 060210
+        | parameter_specifier_list_bracket declaration_specifiers # 同 060210
+		{
+			unless val[1].instance_of?( VoidType ) then
+				Generator.error( "G1003 need parameter name"  )
+			end
+			result = nil
+		}
+
+parameter_specifier_list_bracket
+        :  spec_L parameter_specifier_list spec_R { result = val[1] }
+#        :  '[' parameter_specifier_list  ']'  { result = val[1] }
+
+parameter_specifier_list
+        : parameter_specifier	{ result = val[0] }
+        | parameter_specifier_list ',' parameter_specifier
+		{ result = result + val[2] }
+
+parameter_specifier
+        : IN					{ result = [ [:IN]  ] }
+        | OUT					{ result = [ [:OUT] ] }
+        | INOUT					{ result = [ [:INOUT] ] }
+        | SEND     '(' namespace_identifier ')'	{ result = [ [:SEND,   val[2]] ] }   #1ok allocator
+        | RECEIVE  '(' namespace_identifier ')'	{ result = [ [:RECEIVE,val[2]] ] }   #1ok allocator
+        | STRING				{ result = [ [:STRING,nil] ] }
+        | STRING   '(' expression ')'	{ result = [ [:STRING,  val[2]] ] }
+        | SIZE_IS  '(' expression ')'	{ result = [ [:SIZE_IS, val[2]] ] }
+        | SIZE_IS  '(' expression ',' constant_expression ')'
+		{
+			result = [ [:SIZE_IS,val[2]], [:MAX_IS, val[4]] ]
+		}
+        | COUNT_IS '(' expression ')'	{ result = [ [:COUNT_IS,val[2]] ] }
+        | NULLABLE		{ result = [ [:NULLABLE] ] }
+
+type_name
+        : type_specifier_qualifier_list
+        | type_specifier_qualifier_list abstract_declarator
+		{
+			if val[1] then
+				val[1].set_type( val[0] )
+				result = val[1]
+			else
+				# エラー：仮で val[0] を返す
+				result = val[0]
+			end
+		}
+		# mikan abstract_declarator が pointer 以外ではうまく動かない、とりあえず '*' CAST のみ救った
+
+abstract_declarator		# mikan
+        : pointer
+        | direct_abstract_declarator
+        | pointer direct_abstract_declarator
+
+direct_abstract_declarator
+        : '(' abstract_declarator ')'
+		{ result = val[1] }  # 関数ポインタ型を救う
+        | '[' ']'
+		{
+			Generator.error( "G1004 impossible array type"  )
+			result = nil
+		}
+        | '[' constant_expression ']'
+		{
+			Generator.error( "G1005 impossible array type"  )
+			result = nil
+		}
+        | direct_abstract_declarator '[' ']'
+		{
+			Generator.error( "G1006 impossible array type"  )
+			result = nil
+		}
+        | direct_abstract_declarator '[' constant_expression ']'
+		{
+			Generator.error( "G1007 impossible array type"  )
+			result = nil
+		}
+        | '(' ')'
+		{
+			Generator.error( "G1008 impossible function type"  )
+			result = nil
+		}
+        | '(' parameter_type_list ')'
+        | direct_abstract_declarator '(' ')'
+		{
+			Generator.warning( "W5011 need 'void' for no parameter"  )
+			val[0].set_type( FuncType.new )
+			result = val[0]
+		}
+        | direct_abstract_declarator '(' parameter_type_list ')'
+		{
+			val[0].set_type( FuncType.new( val[2] ) )
+			result = val[0]
+		}
+
+# assignment_expressionをconstant_expressionに変更
+initializer			# mikan
+        : constant_expression
+		{ result = val[0] }
+        | '{' initializer_list '}'
+		{ result = val[1] }
+        | '{' initializer_list ',' '}'
+		{ result = val[1] }
+#        | C_EXP '(' STRING_LITERAL ')'
+        | C_EXP '(' string_literal_list ')'
+		{ result = C_EXP.new( val[2] ) }
+
+initializer_list
+        : initializer
+		{
+			result = [ val[0] ]
+		}
+        | initializer_list ',' initializer
+		{
+			val[0] << val[2]
+			result = val[0]
+		}
+
+
+##########################  ここからはCDL独自  ##########################
+
+#トップレベルの構文規則
+#コンポーネント記述
+component_description
+        : component_description specified_statement
+        | component_description location_information
+        | component_description tool_info
+        | 
+
+specified_statement
+        : statement
+        | spec_L statement_specifier_list spec_R statement
+		{
+			obj = val[3]
+			if obj.kind_of?( Cell ) || obj.kind_of?( Signature ) || obj.kind_of?( Celltype ) || obj.kind_of?( CompositeCelltype )then
+                                # cell, signature 以外は、指定子を置けない
+			else
+              Generator.get_statement_specifier   # クリア
+              Generator.error( "G1009 unexpected specifier"  )
+			end
+		}
+		# これと同じ記述が composite_celltype にもある
+
+statement
+        : typedef
+        | const_statement
+        | namespace
+        | signature
+        | celltype
+        | cell
+        | composite_celltype
+        | enum_specifier ';'
+        | struct_specifier ';'
+        | region
+        | import
+        | import_C
+        | generate_statement
+        | error   # エラー回復ポイント
+
+	
+statement_specifier_list
+        : statement_specifier
+		{ Generator.add_statement_specifier val[0]	}
+        | statement_specifier_list ',' statement_specifier
+		{ Generator.add_statement_specifier val[2] }
+
+statement_specifier
+        : ALLOCATOR '(' alloc_list ')'                       # cell
+		{ result = [ :ALLOCATOR, val[2] ] }
+        | CALLBACK                                           # signature
+		{ result = [ :CALLBACK ] }
+        | CONTEXT '(' string_literal_list ')'                # signature
+		{ result = [ :CONTEXT, val[2].val ] }
+        | DEVIATE                                            # signature
+		{ result = [ :DEVIATE ] }
+        | ID '(' constant_expression ')'                     # cell
+		{ result = [ :ID, val[2] ] }
+        | PROTOTYPE                                          # cell
+		{ result = [ :PROTOTYPE ] }
+        | RESTRICT  '(' restrict_list ')'                    # cell
+		{ result = [ :RESTRICT, val[2] ] }
+        | SINGLETON  { result = [:SINGLETON] }               # celltype, composite
+        | IDX_IS_ID  { result = [:IDX_IS_ID] }               # celltype, composite (composite: no-effective)
+        | ACTIVE     { result = [:ACTIVE] }                  # celltype, composite
+        | GENERATE '(' plugin_name ',' plugin_arg  ')'       # celltype, cell
+		{ result = [:GENERATE, val[2].val, val[4].val] }
+
+alloc_list
+        : alloc			{ result = [ val[0] ] }
+        | alloc_list ',' alloc	{ result << val[2] }
+
+alloc
+        : IDENTIFIER '.' IDENTIFIER '.' IDENTIFIER '=' initializer
+		{  result = [ :NORMAL_ALLOC, val[0], nil, val[2], val[4], val[6] ] }
+        | IDENTIFIER '[' constant_expression ']' '.' IDENTIFIER '.' IDENTIFIER '=' initializer
+		{  result = [ :NORMAL_ALLOC, val[0], val[2], val[5], val[7], val[9] ] }
+# mikan 将来的な拡張 ('*' でまとめて指定可能とする)
+#        | IDENTIFIER '.' IDENTIFIER '.' '*'        '=' initializer
+#		{  result = [ val[0], val[ ], val[ ], val[ ] ] }
+#        | IDENTIFIER '.' '*' '.' '*'               '=' initializer
+#		{  result = [ val[0], val[ ], val[ ], val[ ] ] }
+
+restrict_list
+        : restrict
+		{	result = [val[0]]		}
+        | restrict_list ',' restrict
+		{	result << val[2]		}
+
+restrict
+        : port_name '=' '{' region_name_list '}'
+		{	result = [ val[0].val, nil, val[3] ]		}
+        | port_name '.' IDENTIFIER '=' '{' region_name_list '}'
+		{	result = [ val[0].val, val[2].val, val[5] ]		}
+
+region_name_list
+        : namespace_identifier
+		{	result = [val[0]]		}
+        | region_name_list ',' namespace_identifier
+		{	result << val[2]		}
+
+const_statement
+        : declaration   # 定数定義
+		{
+			val[0].each { |decl|
+				decl.set_kind( :CONSTANT )
+				Namespace.new_const_decl( decl )
+				decl.check
+			}
+		}
+
+import_C
+        : IMPORT_C '(' STRING_LITERAL ')' ';'
+		{
+			@@import_C = true
+			Import_C.new( val[2] )
+			@@import_C = false
+		}
+        | IMPORT_C '(' STRING_LITERAL ',' STRING_LITERAL ')' ';'
+		{
+			@@import_C = true
+			Import_C.new( val[2], val[4] )
+			@@import_C = false
+		}
+
+import
+        : IMPORT '(' STRING_LITERAL ')' ';'
+		{ Import.new( val[2] ) }
+        | IMPORT '(' AB_STRING_LITERAL ')' ';'
+		{ Import.new( val[2], true ) }
+
+generate_statement
+#        : GENERATE '(' plugin_name ',' namespace_identifier ',' STRING_LITERAL ')' ';'  #1ok signature plugin
+        : GENERATE '(' plugin_name ',' namespace_identifier ',' plugin_arg ')' ';'  #1ok signature plugin
+		{ Generate.new( val[2].val, val[4], val[6] ) }
+
+typedef
+        : TYPEDEF type_specifier_qualifier_list declarator_list ';'
+		{
+			val[2].each{ |i|       # i:Decl
+				i.set_kind( :TYPEDEF )
+    		}
+			Typedef.new_decl_list( val[1], val[2] )
+			val[2].each{ |i|       # i:Decl
+				i.check
+			}
+		}
+        | TYPEDEF '[' typedef_specifier ']' type_specifier_qualifier_list declarator_list ';'
+		{
+			val[5].each{ |i|       # i:Decl
+				i.set_kind( :TYPEDEF )
+			}
+			Typedef.new_decl_list( val[4], val[5] )
+			val[5].each{ |i|       # i:Decl
+				i.check
+			}
+		}
+		# mikan   typedef_specifier 未処置
+
+
+typedef_specifier
+        : STRING
+        | STRING '(' expression ')'
+
+declarator_list
+        : declarator
+		{ result = [ val[0] ] }
+        | declarator_list ',' declarator
+		{ result << val[2] }
+
+namespace
+        : NAMESPACE namespace_name '{' statement_list '}' ';'
+		{val[1].end_of_parse}
+
+namespace_name
+        : IDENTIFIER
+		{result = Namespace.new(val[0].val)}
+		# namespace インスタンスに statement を記憶させるためここで生成
+
+statement_list
+        : specified_statement
+        | statement_list specified_statement
+
+namespace_identifier
+        : IDENTIFIER		{ result = NamespacePath.new( val[0].val, false ) }
+        | '::' IDENTIFIER	{ result = NamespacePath.new( val[1].val, true ) }
+        | namespace_identifier '::' IDENTIFIER
+		{ result = val[0].append!( val[2].val ) }
+
+#シグニチャ
+signature
+        : SIGNATURE signature_name '{' function_head_list '}' ';'
+		{ result = val[1].end_of_parse( val[3] ) }
+
+signature_name
+        : IDENTIFIER
+		{result = Signature.new( val[0].val ) }
+
+function_head_list     # result:  function_head の配列
+#        : function_head
+#		{ result = NamedList.new( val[0], "function" ) }
+        :
+		{ result = NamedList.new( nil, "function" ) }
+        | function_head_list function_head
+		{ result = val[0].add_item( val[1] ) }
+
+function_head
+        :               type_specifier_qualifier_list declarator ';'
+		{
+			# val[1]: Decl
+			if val[1].is_function? then
+				result = FuncHead.new( val[1], val[0], false )
+				val[1].set_kind :FUNCHEAD
+				val[1].check
+			else
+				# mikan 関数の配列も以下のメッセージになる
+				Generator.error( "G1010 Not function"  )
+				result = nil
+			end
+		}
+        | spec_L ONEWAY spec_R type_specifier_qualifier_list declarator ';'
+		{
+			if val[4].is_function? then
+				result = FuncHead.new( val[4], val[3], true )
+			else
+				Generator.error( "G1011 Not function"  )
+				result = nil
+			end
+		}
+
+
+#セルタイプ
+celltype
+        : CELLTYPE celltype_name '{' celltype_statement_list '}' ';'
+		{
+			val[1].end_of_parse
+			result = val[1]
+		}
+
+celltype_name
+        : IDENTIFIER
+		{ result = Celltype.new(val[0].val) }
+
+celltype_statement_list
+        : specified_celltype_statement
+        | celltype_statement_list specified_celltype_statement
+
+specified_celltype_statement
+        : celltype_statement
+		{
+			if val[0].kind_of? Port then
+				Celltype.new_port( val[0] )
+			end
+		}
+        | spec_L celltype_statement_specifier_list spec_R celltype_statement
+		{
+			if val[3].kind_of? Port then
+				val[3].set_specifier val[1]  # 設定順序あり
+				Celltype.new_port( val[3] )
+			else
+				# Port 以外では指定子はエラー
+				Generator.error( "G1012 $1 : cannot put specifier here" , val[1] )
+			end
+		}
+
+celltype_statement
+        : port
+        | attribute
+        | var
+        | require
+        | factory
+#        | error       # エラー回復ポイント  (#513 無限ループに陥るケースがあるので、ここでのエラー回復は取りやめ)
+
+celltype_statement_specifier_list
+        : celltype_statement_specifier
+		{ result = [ val[0] ] }
+        | celltype_statement_specifier_list ',' celltype_statement_specifier
+		{ result << val[2] }
+
+celltype_statement_specifier
+        : INLINE { result = [ :INLINE ] }
+        | ALLOCATOR '(' alloc_list2 ')'    { result = [ :ALLOCATOR, val[2] ] }
+        | OPTIONAL { result = [ :OPTIONAL ] }
+        | REF_DESC { result = [ :REF_DESC ] }
+        | DYNAMIC { result = [ :DYNAMIC ] }
+        | OMIT { result = [ :OMIT ] }
+
+alloc_list2
+        : alloc2			{ result = [ val[0] ] }    # 受け口のアロケータ指定
+        | alloc				{ result = [ val[0] ] }    # 内部セルのアロケータ指定
+        | alloc_list2 ',' alloc2	{ result << val[2] }
+        | alloc_list2 ',' alloc		{ result << val[2] }
+
+alloc2
+        : IDENTIFIER '.' IDENTIFIER '=' initializer    # 内部アロケータ (デバドラ向きアロケータ)指定
+		{  result = [ :INTERNAL_ALLOC, val[0].val, val[2].val, val[4] ] }
+        | IDENTIFIER '.' IDENTIFIER '<=' initializer   # 多段リレーモデル向きアロケータ指定
+		{  result = [ :RELAY_ALLOC, val[0].val, val[2].val, val[4] ] }
+
+
+#呼び口、受け口
+port
+        : port_type namespace_signature_name port_name ';'
+		{ result = Port.new( val[2].val, val[1], val[0] ) }
+        | port_type namespace_signature_name port_name '[' ']' ';'
+		{ result = Port.new( val[2].val, val[1], val[0], "[]" ) }
+        | port_type namespace_signature_name port_name '[' array_size ']' ';'
+		{ result = Port.new(val[2].val, val[1], val[0], val[4]) }
+        | port_type namespace_signature_name port_name '<=' namespace_identifier '.' IDENTIFIER ';'    #1ok reverse require
+		{ result = Port.new( val[2].val, val[1], val[0], nil, val[4], val[ 6 ].val ) }
+
+port_type
+        : CALL	{ result = :CALL }
+        | ENTRY	{ result = :ENTRY }
+
+namespace_signature_name
+        : namespace_identifier  #1ok
+		{ result = val[0] }
+
+port_name
+        : IDENTIFIER
+
+array_size
+        : constant_expression
+
+
+#属性
+attribute
+        : ATTRIBUTE '{' attribute_declaration_list '}' ';'
+		{ result = nil }
+
+attribute_declaration_list
+        : attribute_declaration
+		{ Celltype.new_attribute( val[0] ) }
+        | attribute_declaration_list attribute_declaration
+		{ Celltype.new_attribute( val[1] ) }
+
+
+attribute_declaration
+        :                             declaration
+		{
+			val[0].each{ |i|       # i:Decl
+				i.set_kind( :ATTRIBUTE )
+				i.check
+			}
+			result = val[0]
+		}
+        | spec_L attribute_specifier spec_R declaration
+		{
+			val[3].each{ |i|       # i:Decl
+				i.set_kind( :ATTRIBUTE )   # 設定順序あり
+				i.set_specifier_list( [val[1]] )
+				i.check
+			}
+			result = val[3]
+		}
+
+attribute_specifier
+        : OMIT     { result = [:OMIT] }
+        | SIZE_IS  '(' expression ')'	{ result = [:SIZE_IS,val[2]] }
+        | CHOICE '=' '{' choice_list '}' {  result = [:CHOICE,val[3]] }
+
+choice_list
+        : choice_list ',' choice_element {  result << val[2] }
+        | choice_element                 {  result = [ val[0] ] }
+
+choice_element
+        : STRING_LITERAL
+
+#内部変数
+var
+        : VAR '{' var_declaration_list '}' ';'
+		{ result = nil }
+
+var_declaration_list
+        : var_declaration
+   		{ Celltype.new_var( val[0] ) }
+        | var_declaration_list var_declaration
+   		{ Celltype.new_var( val[1] ) }
+
+var_declaration
+        : declaration
+		{
+			val[0].each{ |i|       # i:Decl
+				i.set_kind( :VAR )
+				i.check
+			}
+		}
+        | spec_L var_specifier spec_R declaration
+		{
+			val[3].each{ |i|       # i:Decl
+				i.set_kind( :VAR )   # 設定順序あり
+				i.set_specifier_list( [val[1]] )
+				i.check
+			}
+			result = val[3]
+		}
+
+var_specifier
+        : SIZE_IS  '(' expression ')'	{ result = [:SIZE_IS,val[2]] }
+
+# リクワイア
+require
+        : REQUIRE namespace_identifier '.' IDENTIFIER';'                            # mikan namespace #1
+		{
+			Celltype.new_require( val[1], val[3] )
+		}
+        | REQUIRE IDENTIFIER '=' namespace_identifier '.' IDENTIFIER';'             #1
+		{
+			Celltype.new_require( val[3], val[5], val[1].val )
+		}
+
+#ファクトリ
+factory
+        : factory_head '{' factory_function_list '}' ';'
+
+factory_head
+        : FACTORY     { Factory.set_f_celltype( false ) }
+        | CTFACTORY   { Factory.set_f_celltype( true ) }
+
+factory_function_list
+        :                                         # 空
+        | factory_function_list factory_function
+
+factory_function
+        : factory_function_name '(' constant_expression ',' constant_expression  ')' ';'
+		{ Factory.new( val[0].val, val[2], val[4], nil    ) }
+        | factory_function_name '(' constant_expression ',' constant_expression ',' arg_list ')' ';'
+		{ Factory.new( val[0].val, val[2], val[4], val[6] ) }
+
+factory_function_name
+        : IDENTIFIER
+
+arg_list     # factory の write 関数の第三引数以降
+        : IDENTIFIER
+		{ result = [ [ :IDENTIFIER, val[0].val ] ] }
+        | arg_list ',' IDENTIFIER
+		{ result << [ :IDENTIFIER, val[2].val ] }
+        | STRING_LITERAL
+		{ result = [ [ :STRING_LITERAL, val[0].val ] ] }
+        | arg_list ',' STRING_LITERAL
+		{ result << [ :STRING_LITERAL, val[2].val ] }
+
+#セル生成
+cell
+        : CELL namespace_celltype_name cell_name '{'
+		{ Cell.new_def }
+          join_list '}' ';'
+		{ result = Cell.end_of_parse true }
+        | CELL namespace_celltype_name cell_name ';'   # oyama プロトタイプ宣言
+			{ result = Cell.end_of_parse false }
+
+namespace_celltype_name
+        : namespace_identifier
+		{ result = Cell.new(val[0]) }
+
+cell_name
+        : IDENTIFIER
+		{ result = Cell.set_name(val[0].val) }
+
+join_list
+        :   # 空行  061007
+        | join_list specified_join
+        | join_list reverse_join
+
+specified_join
+        :  spec_L join_specifier_list spec_R join
+		{ val[3].set_specifier_list( val[1] )  }
+	|  join
+		{ val[0].set_specifier_list( [] ) }
+
+join_specifier_list
+        : join_specifier_list ',' join_specifier
+		{ result << val[2] }
+        | join_specifier
+		{ result = [val[0]] }
+
+join_specifier
+        : THROUGH '(' plugin_name ',' plugin_arg ')'
+		{ result = [ :THROUGH, val[2], val[4] ] }
+
+plugin_name
+        : IDENTIFIER   { result = val[0] }
+
+plugin_arg
+        : string_literal_list
+
+join
+#        : cae_name                     '=' expression ';'
+#		{
+#			result = Join.new( val[0].val, nil, val[2] )
+#			Cell.new_join( result, true )
+#		}
+#        | cae_name '[' ']'             '=' expression ';'
+        : cae_name '[' ']'             '=' expression ';'
+		{
+			result = Join.new( val[0].val,  -1, val[4] )
+			Cell.new_join( result, true )
+		 }
+        | cae_name '[' array_index ']' '=' expression ';'
+		{
+			result = Join.new( val[0].val, val[2], val[5] )
+			Cell.new_join( result, true )
+		}
+        | cae_name '=' initializer ';'     # 初期化子： '{', '}' も可
+		{
+			result = Join.new( val[0].val, nil, val[2] )
+			Cell.new_join( result, true )
+		}
+        | cae_name '=' COMPOSITE '.' IDENTIFIER ';'
+		{
+			result = Join.new( val[0].val, nil, [ :COMPOSITE, val[4] ] )
+			Cell.new_join( result, true )
+		}
+
+cae_name #  cae: callport, attribute, entryport
+        : IDENTIFIER
+
+reverse_join
+        # non-array <= non-array
+        : cae_name '<=' namespace_identifier '.' IDENTIFIER ';'
+		{
+			rj = ReverseJoin.new( val[0].val, nil, val[2], val[4].val )
+			Cell.new_reverse_join( rj )
+		}
+        # non-array <= array
+        | cae_name '<=' namespace_identifier '.' IDENTIFIER '[' expression ']' ';'
+		{
+			rj = ReverseJoin.new( val[0].val, nil, val[2], val[4].val, val[6] )
+			Cell.new_reverse_join( rj )
+		}
+        # array <= non-array
+        | cae_name '[' array_index ']' '<=' namespace_identifier '.' IDENTIFIER ';'
+		{
+			rj = ReverseJoin.new( val[0].val, val[2], val[5], val[7].val )
+			Cell.new_reverse_join( rj )
+		}
+        # array <= array
+        | cae_name '[' array_index ']' '<=' namespace_identifier '.' IDENTIFIER '[' expression ']' ';'
+		{
+			rj = ReverseJoin.new( val[0].val, val[2], val[5], val[7].val, val[9] )
+			Cell.new_reverse_join( rj )
+		}
+
+
+array_index
+        : constant_expression
+
+#複合種
+composite_celltype
+        : COMPOSITE composite_celltype_name '{' composite_celltype_statement_list '}' ';'
+		{
+			CompositeCelltype.end_of_parse
+			result = val[1]
+		}
+
+composite_celltype_name
+        : IDENTIFIER
+		{ result = CompositeCelltype.new(val[0].val) }
+
+composite_celltype_statement_list
+        : specified_composite_celltype_statement
+        | composite_celltype_statement_list specified_composite_celltype_statement
+
+specified_composite_celltype_statement
+        : composite_celltype_statement
+		{
+			if val[0].kind_of?( Port ) then
+				CompositeCelltype.new_port( val[0] )   # 遅延して登録
+			end
+		}
+        | spec_L composite_celltype_statement_specifier_list spec_R composite_celltype_statement
+		{
+			if val[3].kind_of?( Port ) then
+				# port 以外 val[3] に有効な値が入っていないので、以下のメソッドを適用できない
+				# 現状 port, cell 以外は指定子を受け付けない
+				# （しかし将来他の文も指定子を受け付ける可能性があるので、この位置に記述する）
+				val[3].set_specifier( Generator.get_statement_specifier )
+				CompositeCelltype.new_port( val[3] )   # 遅延して登録 (set_specifier 後)
+			elsif val[3].kind_of?( Cell ) then
+				# Cell.end_of_parse にて設定
+			else
+              Generator.get_statement_specifier   # クリア
+              Generator.error( "G1013 unexpected specifier"  )
+			end
+		}
+
+composite_celltype_statement
+        : composite_port
+        | composite_attribute
+        | internal_cell
+        | export_join
+#        | error       # エラー回復ポイント  (#513 無限ループに陥るケースがあるので、ここでのエラー回復は取りやめ)
+
+composite_celltype_statement_specifier_list
+        : composite_celltype_statement_specifier
+		{
+			Generator.add_statement_specifier val[0]
+			result = [ val[0] ]
+		}
+        | composite_celltype_statement_specifier_list ',' composite_celltype_statement_specifier
+		{
+			Generator.add_statement_specifier val[2]
+			result = val[0] << val[2]
+		}
+
+composite_celltype_statement_specifier
+        : ALLOCATOR '(' alloc_list2 ')'		{ result = [ :ALLOCATOR, val[2] ] }
+        | OMIT	{ result = [ :OMIT ] }
+        | OPTIONAL	{ result = [ :OPTIONAL ] }
+        | REF_DESC	{ result = [ :REF_DESC ] }
+        | DYNAMIC	{ result = [ :DYNAMIC ] }
+
+composite_port
+        : port
+		{
+			# CompositeCelltype.new_port( val[0] )
+			result = val[0]
+		}
+
+#属性
+composite_attribute
+        : ATTRIBUTE '{' composite_attribute_declaration_list '}' ';'
+		{ result = nil }
+
+composite_attribute_declaration_list
+        : attribute_declaration
+		{ CompositeCelltype.new_attribute( val[0] ) }
+        | composite_attribute_declaration_list attribute_declaration
+		{ CompositeCelltype.new_attribute( val[1] ) }
+
+internal_cell
+        : CELL internal_namespace_celltype_name
+             internal_cell_name '{'
+		{ Cell.new_def }
+             internal_join_list '}' ';'
+		{ result = Cell.end_of_parse true }
+        | CELL internal_namespace_celltype_name	internal_cell_name ';'
+		{ result = Cell.end_of_parse false }
+
+
+internal_namespace_celltype_name
+        : namespace_identifier
+		{ Cell.new(val[0],true) }
+
+internal_cell_name
+        : IDENTIFIER
+		{ Cell.set_name(val[0].val) }
+
+
+internal_join_list
+        :   # 空行  061007
+        | internal_join_list specified_join
+        | internal_join_list external_join
+        | internal_join_list reverse_join
+
+external_join  # cell 内に記述する呼び口の外部結合
+        : internal_cell_elem_name '=>' COMPOSITE '.' export_name ';'
+		{	Cell.external_join( val[0].val, val[4].val, true )	}
+        | internal_cell_elem_name '=>' export_name ';'
+		{	Cell.external_join( val[0].val, val[2].val, false )	}
+        # 以前の文法では、呼び口側も cell の外に記述していた
+        # その時の実装を
+
+export_join    # cell 外に記述する受け口の外部結合
+        : export_name '=>' internal_ref_cell_name '.' internal_cell_elem_name ';'
+		{
+			CompositeCelltype.new_join( val[0].val,
+						val[2].val, val[4].val, :ENTRY )
+		}
+        | COMPOSITE '.' export_name '=>' internal_ref_cell_name '.' internal_cell_elem_name ';'
+		{
+			CompositeCelltype.new_join( val[2].val,
+						val[4].val, val[6].val, :ENTRY )
+		}
+
+export_name
+        : IDENTIFIER
+
+internal_ref_cell_name
+        : IDENTIFIER
+
+internal_cell_elem_name
+        : IDENTIFIER
+
+# リージョン
+region
+        : spec_L region_specifier_list spec_R REGION region_name '{'  region_statement '}' ';'
+		{ Region.end_of_parse }
+        |                  REGION region_name '{'  region_statement '}' ';'
+		{ Region.end_of_parse }
+
+
+region_specifier_list
+        : region_specifier
+        | region_specifier_list ',' region_specifier
+
+region_specifier
+        : IN_THROUGH '(' plugin_name ',' plugin_arg ')'
+		{ Region.new_in_through( val[2].val, val[4].val ) }
+        | IN_THROUGH '(' ')'   # in 許可
+		{ Region.new_in_through }
+        | OUT_THROUGH '(' plugin_name ',' plugin_arg ')'
+		{ Region.new_out_through( val[2].val, val[4].val ) }
+        | OUT_THROUGH '(' ')'  # out 許可
+		{ Region.new_out_through() }
+        | TO_THROUGH '(' namespace_region_name ',' plugin_name ',' plugin_arg ')'
+		{ Region.new_to_through( val[2], val[4].val, val[6].val ) }
+        | TO_THROUGH '('namespace_region_name ')'  # to 許可
+		{ Region.new_to_through( val[2], nil, nil ) }
+        | NODE
+		{ Region.set_type( :NODE ) }
+        | LINKUNIT
+		{ Region.set_type( :LINKUNIT ) }
+        | DOMAIN '(' IDENTIFIER ',' STRING_LITERAL ')'
+		{ Region.set_domain( val[2].val, val[4] ) }
+        | CLASS '(' IDENTIFIER ')'
+		{ Region.set_type( :CLASS, val[2].val ) }
+
+region_name
+        : IDENTIFIER
+		{ result = Region.new( val[0].val ) }
+
+region_statement
+        :
+        | region_statement region_cell
+        | region_statement region
+
+region_cell
+        : cell
+        | spec_L statement_specifier_list spec_R cell
+		{
+			obj = val[3]
+			if obj.kind_of?( Cell ) then
+			else
+              Generator.get_statement_specifier   # クリア
+              Generator.error( "G9999 unexpected specifier"  )
+			end
+		}
+#        | spec_L region_cell_specifier_list spec_R cell
+
+# region_cell_specifier_list
+#         : region_cell_specifier
+# 		{ Generator.add_statement_specifier val[0] }
+#         | region_cell_specifier_list region_cell_specifier
+# 		{ Generator.add_statement_specifier val[2] }
+
+# region_cell_specifier
+#         : ALLOCATOR '(' alloc_list ')'
+# 		{ result = [ :ALLOCATOR, val[2] ] }
+
+
+namespace_region_name
+         : :IDENTIFIER
+		{ result = [ val[0].val ] }  # mikan 配列である必要はない
+#        : namespace_identifier
+
+# 指定子の括弧 (in, out などのキーワード切り替えのため分離)
+spec_L
+        : '['  { set_in_specifier }
+spec_R
+        : ']'  { unset_in_specifier }
+
+# location information
+location_information
+        :  __LOCATION_INFORMATION__ '{'  cell_location_join_location_list '}'
+
+cell_location_join_location_list
+        : cell_location_join_location_list cell_location
+        | cell_location_join_location_list join_location
+        |
+
+cell_location
+        : __CELL__ namespace_identifier '(' constant_expression ',' constant_expression ','  constant_expression ','  constant_expression ')' '{' port_location_list '}'
+		{
+			TECSGEN::Cell_location.new( val[1], val[3], val[5], val[7], val[9], val[12] )
+		}
+
+port_location_list
+        : port_location_list port_location
+		{
+			result = val[0] << val[1]
+		}
+        |
+		{ result = [] }
+
+port_location
+        : IDENTIFIER '(' IDENTIFIER ',' constant_expression ')'
+		{ result = [ val[0], val[2], val[3] ] }
+
+join_location    # mikan port array
+        : __JOIN__ '(' namespace_identifier '.' IDENTIFIER '=>' namespace_identifier '.' IDENTIFIER ')'  '{' bar_list '}'
+		{
+            TECSGEN::Join_location.new( val[2], val[4], val[6], val[8], val[11] )
+		}
+
+bar_list
+        : bar_list IDENTIFIER '(' constant_expression ')'
+          {
+            result = val[0] << [ val[1], val[3] ]
+          }
+        | { result = [] }
+
+
+#  JSON object
+tool_info        : TOOL_INFO '(' JSON_string ')' JSON_object { TOOL_INFO.new( val[2].to_sym, val[4] ) }
+JSON_object      : '{' JSON_property_list   '}'              {  result = val[1] }
+JSON_property_list : JSON_string ':' JSON_value              { result = { val[0].to_sym => val[2] } }
+                 | JSON_property_list ',' JSON_string ':' JSON_value
+                                                             { val[0][ val[2].to_sym ] = val[4] }
+JSON_value       : JSON_string | JSON_number | JSON_object | JSON_array
+                 | TRUE { result=val[0].val } | FALSE  { result=val[0].val } # JSON_NULL # null not suppoted
+JSON_array       : '[' JSON_array_list ']'                   { result = val[1]  }
+                 | '['  ']'                                  { result = []  }
+JSON_array_list  : JSON_value                                { result = [ val[0] ] }
+                 | JSON_array_list ',' JSON_value            { val[0] << val[2] }
+JSON_string      : STRING_LITERAL                            { result = val[0].val.gsub!( /\"(.*)\"/, "\\1" ) }
+JSON_number      : INTEGER_CONSTANT                          { result = val[0].val.to_i }
+                 | FLOATING_CONSTANT                         { result = val[0].val.to_f }
+                 | '-' INTEGER_CONSTANT                      { result = - val[0].val.to_i }
+                 | '-' FLOATING_CONSTANT                     { result = - val[0].val.to_f }
+                 | '+' INTEGER_CONSTANT                      { result = val[0].val.to_i }
+                 | '+' FLOATING_CONSTANT                     { result = val[0].val.to_f }
+
+
+end
+
+---- inner
+
+  RESERVED = {
+    # keyword
+    'namespace' => :NAMESPACE,
+    'signature' => :SIGNATURE,
+    'celltype' => :CELLTYPE,
+    'cell' => :CELL,
+    'attr' => :ATTRIBUTE,
+    'var' => :VAR,
+    'call' => :CALL,
+    'entry' => :ENTRY,
+    'composite' => :COMPOSITE,
+    'require' => :REQUIRE,
+    'factory' => :FACTORY,
+    'FACTORY' => :CTFACTORY,
+    'typedef' => :TYPEDEF,
+    'struct' => :STRUCT,
+    'region' => :REGION,
+    'import' => :IMPORT,
+    'import_C' => :IMPORT_C,
+    'generate' => :GENERATE,
+    '__tool_info__' => :TOOL_INFO,
+
+    # types
+    'void'    => :VOID,
+
+    'volatile'=> :VOLATILE,
+    'const'   => :CONST,
+
+    'signed'  => :SIGNED,
+    'unsigned'=> :UNSIGNED,
+
+    'int8_t'    => :INT8_T,
+    'int16_t'   => :INT16_T,
+    'int32_t'   => :INT32_T,
+    'int64_t'   => :INT64_T,
+    'int128_t'  => :INT128_T,
+    'uint8_t'   => :UINT8_T,
+    'uint16_t'  => :UINT16_T,
+    'uint32_t'  => :UINT32_T,
+    'uint64_t'  => :UINT64_T,
+    'uint128_t' => :UINT128_T,
+
+    'float32_t'   => :FLOAT32_T,
+    'double64_t'  => :DOUBLE64_T,
+    'bool_t'      => :BOOL_T,
+    'char_t'  => :CHAR_T,
+    'schar_t'  => :SCHAR_T,
+    'uchar_t'  => :UCHAR_T,
+
+    # unrecommened types
+    'int'     => :INT,
+#   'intptr'  => :INTPTR,
+    'short'   => :SHORT,
+    'long'    => :LONG,
+
+    # obsolete types
+    'char'    => :CHAR,
+#    'int8'    => :INT8,
+#    'int16'   => :INT16,
+#    'int32'   => :INT32,
+#    'int64'   => :INT64,
+#    'int128'  => :INT128,
+#    'float'   => :FLOAT,
+#    'double'  => :DOUBLE,
+#    'bool'    => :BOOL,
+
+    'enum'    => :ENUM,
+    'enum8'   => :ENUM8,
+    'enum16'  => :ENUM16,
+    'enum32'  => :ENUM32,
+    'enum64'  => :ENUM64,
+
+    'true'    => :TRUE,
+    'false'   => :FALSE,
+
+    'C_EXP'   => :C_EXP,
+
+    'Descriptor'   => :DESCRIPTOR,
+
+    # location information for TECSCDE
+    '__location_information__' => :__LOCATION_INFORMATION__,
+    '__cell__' => :__CELL__,
+    '__join__' => :__JOIN__,
+  }
+
+  # 指定子 '[]' 内でのみ使用できるキーワード
+  RESERVED2 = {
+    # specifier
+    'id' => :ID,
+
+    # signature
+    'callback' => :CALLBACK,
+    'context' => :CONTEXT,
+    'deviate' => :DEVIATE,
+
+    # celltype
+    'singleton' => :SINGLETON,
+    'idx_is_id' => :IDX_IS_ID,
+    'active' => :ACTIVE,
+
+    # port (entry)
+    'inline' => :INLINE,
+    'ref_desc' => :REF_DESC,   # call も可
+
+    # port (call)
+    'optional' => :OPTIONAL,
+    'dynamic' => :DYNAMIC,
+
+    # port (call), attribute
+    'omit' => :OMIT,
+
+    # attribute
+    'choice' => :CHOICE,
+
+    # cell
+    'allocator' => :ALLOCATOR,
+    'prototype' => :PROTOTYPE,
+    'restrict'  => :RESTRICT,
+
+    # FuncType
+    'oneway' => :ONEWAY,
+
+    # parameter (basic)
+    'in' => :IN,
+    'out' => :OUT,
+    'inout' => :INOUT,
+    'send' => :SEND,
+    'receive' => :RECEIVE,
+
+    # parameter 
+    'size_is' => :SIZE_IS,
+    'count_is' => :COUNT_IS,
+    'string' => :STRING,
+    'nullable' => :NULLABLE,
+
+    'through' => :THROUGH,
+    'in_through' => :IN_THROUGH,
+    'out_through' => :OUT_THROUGH,
+    'to_through' => :TO_THROUGH,
+
+    'node' => :NODE,
+    'linkunit' => :LINKUNIT ,
+    'domain' => :DOMAIN,
+    'class' => :CLASS,
+  }
+
+  # 再帰的なパーサのためのスタック
+  @@generator_nest = -1
+  @@generator_stack = []
+  @@current_locale = []
+
+  # import_C 中である
+  @@import_C = false
+
+  # すべての構文解析が完了した
+  @@b_end_all_parse = false
+
+  # tag なし struct
+  @@no_struct_tag_num = 0
+
+  def self.parse( file_name, plugin = nil, b_reuse = false )
+    # パーサインスタンスを生成(別パーサで読み込む)
+    parser = Generator.new
+
+    # plugin から import されている場合の plugin 設定
+    parser.set_plugin plugin
+
+    # reuse フラグを設定
+    parser.set_reuse b_reuse
+
+    # cdl をパース
+    parser.parse( [file_name] )
+
+    # 終期化　パーサスタックを戻す
+    parser.finalize
+  end
+
+  def finalize
+
+    # mikan Namespace.pop
+    Namespace.pop
+    Signature.pop
+    Celltype.pop
+    Cell.pop
+    CompositeCelltype.pop
+  end
+
+  def set_plugin( plugin )
+    @plugin = plugin
+  end
+
+  def self.get_plugin
+    if @@generator_stack[@@generator_nest] then
+      # tecsgen 引数の cdl が import される場合は nil
+      return @@generator_stack[@@generator_nest].get_plugin
+    else
+      return nil
+    end
+  end
+
+  def get_plugin
+    @plugin
+  end
+
+  def set_reuse( b_reuse )
+    @b_reuse = b_reuse
+  end
+
+  def self.is_reuse?
+    if @@generator_stack[@@generator_nest] then
+      # tecsgen 引数の cdl が import される場合は nil
+      return @@generator_stack[@@generator_nest].is_reuse?
+    else
+      return false
+    end
+  end
+
+  def is_reuse?
+    @b_reuse
+  end
+
+  def parse(files)
+
+    # mikan Namespace.push
+    Namespace.push
+    Signature.push
+    Celltype.push
+    Cell.push
+    CompositeCelltype.push
+
+    @@generator_nest += 1
+    @@generator_stack[@@generator_nest] = self
+    @in_specifier = false
+
+    begin
+
+      @q = []
+      b_in_comment = false
+      b_in_string = false
+
+      # euc のコメントを utf8 として扱うと、コメントの終わりを誤る問題の対策
+      TECS_LANG::set_kcode_binary
+
+      files.each {|file|
+        lineno = 1
+        begin
+          string = ""
+#2.0          IO.foreach(file) {|line|
+          TECSIO.foreach(file) {|line|
+            col = 1
+#            line.rstrip!         改行含む文字列を扱うようになったので、ここで空白を取り除けなくなった
+
+            until line.empty?
+
+              if b_in_comment
+                case line
+                  # コメント終了
+                when /\A\*\//
+                  b_in_comment = false
+                when /\A./
+                  ;
+                when /\s+/     # line.rstrip! を止めたため \n などの空白文字とまっちするルールが必要になった
+                  ;
+                end
+              elsif b_in_string
+                if line =~ /\A(?:[^"\\]|\\.)*"/
+                  string = "#{string}#{$&}"
+                  @q <<  [:STRING_LITERAL, Token.new(string, file, lineno, col)]
+                  b_in_string = false
+                elsif line =~ /\A.*\\\n/     # 改行 \n は '.' にマッチしない
+                  string += $&
+                elsif line =~ /\A.*\n/     # 改行 \n は '.' にマッチしない
+                  string += line
+                  # この位置では error メソッドは使えない (token 読出し前)
+                  puts "#{file}:#{lineno}:#{col}: error: string literal has newline without escape"
+                  @@n_error += 1
+                end
+              else
+                case line
+                # 空白、プリプロセスディレクティブ
+                when /\A\s+/
+                  ;
+                # 識別子
+                when /\A[a-zA-Z_]\w*/
+                  word = $&
+                  @q << [RESERVED[word] || :IDENTIFIER, Token.new(word.intern, file, lineno, col)]
+                # 16 進数定数
+                when /\A0x[0-9A-Fa-f]+/
+                  @q << [:HEX_CONSTANT, Token.new($&, file, lineno, col)]
+                # 8 進数定数
+                when /\A0[0-7]+/
+                  @q << [:OCTAL_CONSTANT, Token.new($&, file, lineno, col)]
+                # 浮動小数定数
+                when /\A[0-9]+\.([0-9]*)?([Ee][+-]?[0-9]+)?/
+                  @q << [:FLOATING_CONSTANT, Token.new($&, file, lineno, col)]
+                # 整数定数
+                when /\A\d+/
+                  @q << [:INTEGER_CONSTANT, Token.new($&.to_i, file, lineno, col)]
+                # 文字定数
+                when /\A'(?:[^'\\]|\\.)'/
+                  @q << [:CHARACTER_LITERAL, Token.new($&, file, lineno, col)]
+                # 文字列
+#                "#include  #include #include \"../systask/logtask.cfg\"       最後の " 忘れ)で無限ループ
+#                when /\A"(?:[^"\\]+|\\.)*"/
+                when /\A"(?:[^"\\]|\\.)*"/   # これはうまく行くようだ
+                  @q << [:STRING_LITERAL, Token.new($&, file, lineno, col)]
+                # 文字列 (改行あり)
+                when /\A"(?:[^"\\]|\\.)*\\\n$/
+                  string = $&
+                  b_in_string = true
+                # 文字列 (改行あり, escape なし)
+                when /\A("(?:[^"\\]|\e\.)*)\n$/
+                  string = $1 + "\\\n"
+                  b_in_string = true
+                  # この位置では error メソッドは使えない (token 読出し前) # mikan cdl_error ではない
+                  puts "#{file}:#{lineno}:#{col}: error: string literal has newline without escape"
+                  @@n_error += 1
+                # 山括弧で囲まれた文字列
+                # when /\A<[0-9A-Za-z_\. \/]+>/   # AB: angle bracke
+                when /\A<(?:[^>\\]|\\.)*>/   # これはうまく行くようだ
+                  @q << [:AB_STRING_LITERAL, Token.new($&, file, lineno, col)]
+                # 行コメント
+                when /\A\/\/.*$/
+                  # 読み飛ばすだけ
+                # コメント開始
+                when /\A\/\*/
+                  b_in_comment = true
+                # '>>', '<<' など
+                when /\A>>/, /\A<</, /\A==/, /\A!=/, /\A\&\&/, /\A\|\|/
+                  @q << [$&, Token.new($&, file, lineno, col)]
+                when /\A::/, /\A=>/, /\A<=/, /\A>=/
+                  @q << [$&, Token.new($&, file, lineno, col)]
+                # '(', ')' など一文字の記号、または未知の記号
+                when /\A./
+                  @q << [$&, Token.new($&, file, lineno, col)]
+                else
+                  raise
+                end
+              end
+
+              line = $'
+              col += $&.length
+            end
+
+            lineno += 1
+          }
+
+        rescue => evar
+          Generator.error( "G1014 while open or reading \'$1\'" , file )
+          if $debug then
+            p puts( evar )
+            pp $@
+          end
+        end
+      }
+
+      # 終了の印
+      @q << nil
+
+      @yydebug = true
+      do_parse
+
+    ensure
+      @@generator_nest -= 1
+      TECS_LANG::reset_kcode
+    end
+
+  end
+
+  def next_token
+    token = @q.shift
+
+    if token then
+      @@current_locale[@@generator_nest] = token[1].locale
+
+      if token[0] == :IDENTIFIER then
+        # TYPE_NAME トークンへ置換え
+        if Namespace.is_typename?( token[1].val ) then
+          token[0] = :TYPE_NAME
+        elsif @in_specifier && RESERVED2[ token[1].val.to_s ] then
+          # 指定子キーワード（ '[', ']' 内でのみ有効)
+          token[0] = RESERVED2[ token[1].val.to_s ]
+        end
+      end
+
+      if $debug then     # 070107 token 無効時ここを通さないようした (through 対応 -d の時に例外発生) 
+        locale = @@current_locale[@@generator_nest]
+        if token then
+          print( "#{locale[0]}: line #{locale[1]} : #{token[0]} '#{token[1].val}'\n" )
+        else
+          print( "#{locale[0]}: line #{locale[1]} : EOF\n" )
+        end
+      end
+    else
+      token = [ false, false ]
+    end
+
+    token
+  end
+
+  def on_error(t, v, vstack)
+    # p t, token_to_str(t), vstack
+    if token_to_str(t) == "$end" then
+      Generator.error( "G1015 Unexpected EOF"  )
+    else
+      Generator.error( "G1016 syntax error near \'$1\'" , v.val )
+    end
+  end
+
+  def self.current_locale
+    @@current_locale[ @@generator_nest ]
+  end
+
+  @@n_error = 0
+  @@n_warning = 0
+  @@n_info = 0
+
+  # このメソッドは構文解析、意味解析からのみ呼出し可（コード生成でエラー発生は不適切）
+  def self.error( msg, *arg )
+    locale = nil
+    self.error2( locale, msg, *arg )
+  end
+
+  def self.error2( locale, msg, *arg )
+    @@n_error += 1
+
+    msg = TECSMsg.get_error_message( msg )
+    # $1, $2, ... を arg で置換
+    count = 1
+    arg.each{ |a|
+      str = TECSIO.str_code_convert( msg, a.to_s )
+      msg.sub!( /\$#{count}/, str )
+      count += 1
+    }
+
+    # import_C の中でのエラー？
+    if @@import_C then
+      C_parser.error( msg )
+    else
+
+      # Node の記憶する 位置 (locale) を使用した場合、変更以前に比べ、
+      # 問題発生箇所と異なる位置にエラーが出るため、構文解析中のエラー
+      # は、解析中の位置を出力する．(new_XXX で owner が子要素のチェッ
+      # クをすると owner の行番号が出てしまう点で、ずれが生じている)
+
+      if @@b_end_all_parse == false || locale == nil then
+        locale = @@current_locale[ @@generator_nest ]
+      end
+      if locale then
+        Console.puts "#{locale[0]}:#{locale[1]}:#{locale[2]}: error: #{msg}"
+      else
+        Console.puts "error: #{msg}"
+      end
+    end
+  end
+
+  # このメソッドは構文解析、意味解析からのみ呼出し可（コード生成でウォーニング発生は不適切）
+  def self.warning( msg, *arg )
+    locale = nil
+    self.warning2( locale, msg, *arg )
+  end
+
+  def self.warning2( locale, msg, *arg )
+    @@n_warning += 1
+
+    msg = TECSMsg.get_warning_message( msg )
+    # $1, $2, ... を arg で置換
+    count = 1
+    arg.each{ |a|
+      str = TECSIO.str_code_convert( msg, a.to_s )
+      msg.sub!( /\$#{count}/, str )
+      count += 1
+    }
+
+    # import_C の中でのウォーニング？
+    if @@import_C then
+      C_parser.warning( msg )
+    else
+      if @@b_end_all_parse == false || locale == nil then
+        locale = @@current_locale[ @@generator_nest ]
+      end
+      if locale then
+        Console.puts "#{locale[0]}:#{locale[1]}:#{locale[2]}: warning: #{msg}"
+      else
+        Console.puts "warning: #{msg}"
+      end
+    end
+  end
+
+  # このメソッドは構文解析、意味解析からのみ呼出し可
+  def self.info( msg, *arg )
+    locale = nil
+    self.info2( locale, msg, *arg )
+  end
+
+  def self.info2( locale, msg, *arg )
+    @@n_info += 1
+
+    msg = TECSMsg.get_info_message( msg )
+    # $1, $2, ... を arg で置換
+    count = 1
+    arg.each{ |a|
+      str = TECSIO.str_code_convert( msg, a.to_s )
+      msg.sub!( /\$#{count}/, str )
+      count += 1
+    }
+
+    # import_C の中でのウォーニング？
+    if @@import_C then
+      C_parser.info( msg )
+    else
+      if @@b_end_all_parse == false || locale == nil then
+        locale = @@current_locale[ @@generator_nest ]
+      end
+      if locale then
+        Console.puts "#{locale[0]}:#{locale[1]}:#{locale[2]}: info: #{msg}"
+      else
+        Console.puts "info: #{msg}"
+      end
+    end
+  end
+
+  def self.get_n_error
+    @@n_error
+  end
+
+  def self.get_n_warning
+    @@n_warning
+  end
+
+  def self.get_n_info
+    @@n_info
+  end
+
+  def self.get_nest
+    @@generator_nest
+  end
+
+  def self.parsing_C?
+    @@import_C
+  end
+
+  #===  '[' specifier 始め
+  def set_in_specifier
+    # p "set_in_specifier"
+    @in_specifier = true
+  end
+
+  #=== ']' specifier 終わり
+  def unset_in_specifier
+    # p "unset_in_specifier"
+    @in_specifier = false
+  end
+
+  # statement_specifier は構文解釈途中で参照したいため
+  @@statement_specifier_stack = []
+  def self.add_statement_specifier( ss )
+    if( @@statement_specifier_stack[ @@generator_nest ] == nil )then
+      @@statement_specifier_stack[ @@generator_nest ] = [ ss ]
+    else
+      @@statement_specifier_stack[ @@generator_nest ] << ss
+    end
+  end
+
+
+  def self.get_statement_specifier
+    spec_list = @@statement_specifier_stack[ @@generator_nest ]
+    @@statement_specifier_stack[ @@generator_nest ] = nil
+    return spec_list
+  end
+
+  #=== すべての構文解析が完了したことを報告
+  def self.end_all_parse
+    @@b_end_all_parse = true
+  end
+
+---- footer
+
+
+# ファイル => INCLUDE("header")の配列
+Include = Hash.new {|hash, key| hash[key] = []}
+
+
+class Token
+
+  attr_accessor :val, :file, :lineno, :col
+
+  def initialize(val, file, lineno, col)
+    @val = val
+    @file = file
+    @lineno = lineno
+    @col = col
+
+  end
+
+  def to_s
+    @val.to_s
+  end
+
+  def to_sym
+    @val.to_sym
+  end
+
+  def get_name
+    @val
+  end
+
+  def locale
+    [@file, @lineno, @col]
+  end
+
+  def eql?(other)
+    if other.is_a? Symbol
+      @val == other
+    elsif other.is_a? Token
+      @val == other.val
+    elsif other.is_a? String
+      @val.to_s == other
+    else
+      raise ArgumentError
+    end
+  end
+
+  alias == eql?
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    print "#{@val}\n"
+  end
+
+end
+
+#= TECSIO
+#  Ruby2.0(1.9) 対応に伴い導入したクラス
+#  SJIS 以外では、ASCII-8BIT として入力する
+class TECSIO
+  def self.foreach(file) # ブロック引数 { |line| }
+    pr = Proc.new   # このメソッドのブロック引数を pr に代入
+    if $b_no_kcode then
+	  msg = "E".encode $Ruby19_File_Encode
+      if( $Ruby19_File_Encode == "Shift_JIS" )
+
+        # Shift JIS は、いったん Windows-31J として読み込ませ、Shift_JIS に変換させる．
+        # コメント等に含まれる SJIS に不適切な文字コードは '?' または REPLACEMENT CHARACTER に変換される．
+        # EUC や UTF-8 で記述された CDL が混在していても、Ruby 例外が発生することなく処理を進めることができる．
+        # 文字コード指定が SJIS であって、文字列リテラルの中に、文字コードがSJIS 以外の非 ASCII が含まれている場合、
+        # Ruby 1.8 の tecsgen では文字コード指定に影響なく処理されたものが、Ruby 1.9 以降では '?' に置き換わる可能性がある．
+
+        mode = "r:Windows-31J"
+      else
+        mode = "r:#{$Ruby19_File_Encode}"
+      end
+      # mode = "r"
+    else
+	  msg = "E"
+      mode = "r"
+    end
+
+    f = File.open( file, mode )
+    begin
+      f.each{ |line|
+        # dbgPrint line
+        line = str_code_convert( msg, line )
+        pr.call( line )
+      }
+    ensure
+      f.close
+    end
+  end
+
+  #=== 文字コードが相違する場合一致させる
+  # msg と str の文字コードが相違する場合、str を msg の文字コードに変換する
+  # 変換不可の文字コードは '?' (utf-8 の場合 U+FFFD (REPLACEMENT CHARACTER )) に変換
+  #
+  # このメソッドは、エラーメッセージ出力でも使用されていることに注意．
+  #
+  #msg_enc::Encode | String
+  def self.str_code_convert( msg, str )
+    if $b_no_kcode == false then
+      return str                          # Ruby V1.8 まで
+    end
+    if msg.encoding != str.encoding then
+      option = { :invalid => :replace, :undef => :replace }   # 例外を発生させず、'?' に変換する(utf-8 は 0xfffd)
+      # return str.encode( msg.encoding, option )
+      str = str.encode( "utf-8", option )
+      return str.encode( msg.encoding, option )
+    else
+      return str
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/componentobj.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/componentobj.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/componentobj.rb	(revision 398)
@@ -0,0 +1,7991 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2019 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# STAGE:
+# このメンテナンス状況はよろしくない
+#  B    bnf.y.rb から呼出される
+#  P    parse 段階で呼出される（bnf.y.rb から直接呼出されるわけではないが、構文木生成を行う）
+#  S    P の中から呼出されるが、構文木生成するわけではなく意味チェックする
+#  G    コード生成（この段階で、構文木は完全である．不完全ならエラーで打ちきられている）
+#                                                   factory の第一引数 "format" の後ろの引数
+
+# mikan 以下は ruby の mix in で実現できるかもしれない
+# Nestable を継承した場合、クラス変数は Nestable のものが共有される（別にしたかった）
+# class Nestable
+#   @@nest_stack_index = -1
+#   @@nest_stack = []
+#   @@current_object = nil
+# 
+#   def self.push
+#     @@nest_stack_index += 1
+#     @@nest_stack[ @nest_stack_index ] = @@current_object
+#     @@current_object = nil
+#   end
+# 
+#   def pop
+#     @@current_object = @@nest_stack[ @@nest_stack_index ]
+#     @nest_stack_index -= 1
+#     if @@nest_stack_index < -1 then
+#       raise TooManyRestore
+#     end
+#   end
+# end
+#
+
+class Signature < NSBDNode  # < Nestable
+#  @name:: Symbol
+#  @global_name:: Symbol
+#  @function_head_list:: NamedList : FuncHead のインスタンスが要素
+#  @func_name_to_id::  {String}  :  関数名を添字とする配列で id を記憶する．id は signature の出現順番 (1から始まる)
+#  @context:: string : コンテキスト名
+#  @b_callback:: bool: callback : コールバック用のシグニチャ
+#  @b_deviate:: bool: deviate : 逸脱（pointer level mismatch を出さない）
+#  @b_checked_as_allocator_signature:: bool:  アロケータシグニチャとしてチェック済み
+#  @b_empty:: Bool: 空(関数が一つもない状態)
+#  @descriptor_list:: nil | { Signature => ParamDecl }  最後の ParamDecl しか記憶しないことに注意
+#  @generate:: [ Symbol, String, Plugin ]  = [ PluginName, option, Plugin ] Plugin は生成後に追加される
+
+  include PluginModule
+
+  @@nest_stack_index = -1
+  @@nest_stack = []
+  @@current_object = nil
+
+  def self.push
+    @@nest_stack_index += 1
+    @@nest_stack[ @@nest_stack_index ] = @@current_object
+    @@current_object = nil
+  end
+
+  def self.pop
+    @@current_object = @@nest_stack[ @@nest_stack_index ]
+    @@nest_stack_index -= 1
+    if @@nest_stack_index < -1 then
+      raise "TooManyRestore"
+    end
+  end
+
+  # STAGE: P
+  # このメソッドは parse 中のみ呼び出される
+  def self.get_current
+    @@current_object
+  end
+
+  #
+  # STAGE: B
+  def initialize( name )
+    super()
+    @name = name
+    Namespace.new_signature( self )
+    set_namespace_path # @NamespacePath の設定
+    if "#{Namespace.get_global_name}" == "" then
+      @global_name = @name
+    else
+      @global_name = :"#{Namespace.get_global_name}_#{@name}"
+    end
+
+    @func_name_to_id = {}
+    @context = nil
+    @b_callback = false
+    @b_deviate = false
+    @b_empty = false
+    @b_checked_as_allocator_signature = false
+    @descriptor_list = nil
+    @generate = nil
+    @@current_object = self
+    set_specifier_list( Generator.get_statement_specifier )
+  end
+
+  #
+  # STAGE: B
+  def end_of_parse( function_head_list )
+    @function_head_list = function_head_list
+
+    # id を割付ける
+    id = 1
+    function_head_list.get_items.each{ |f|
+      @func_name_to_id[ f.get_name ] = id
+      f.set_owner self
+      id += 1
+    }
+    if id == 1 then
+      @b_empty = true
+    end
+
+    # set_descriptor_list ##
+
+    if @generate then
+      signature_plugin
+    end
+
+    @@current_object = nil
+
+    return self
+  end
+
+  #=== Signature# signature の指定子を設定
+  # STAGE: B
+  #spec_list::      [ [ :CONTEXT,  String ], ... ]
+  #                     s[0]        s[1]
+  def set_specifier_list( spec_list )
+    return if spec_list == nil  # 空ならば何もしない
+
+    spec_list.each { |s|
+      case s[0]     # statement_specifier
+      when :CALLBACK
+        @b_callback = true
+      when :CONTEXT         # [context("non-task")] etc
+        if @context then
+          cdl_error( "S1001 context specifier duplicate"  )
+        end
+        # @context = s[1].gsub( /\A\"(.*)\"$/, "\\1" )
+        @context = CDLString.remove_dquote s[1]
+        case @context
+        when "non-task", "task", "any"
+        else
+          cdl_warning( "W1001 \'$1\': unknown context type. usually specifiy task, non-task or any" , @context )
+        end
+      when :DEVIATE
+        @b_deviate = true
+      when :GENERATE
+        if @generate then
+          cdl_error( "S9999 generate specifier duplicate"  )
+        end
+        @generate = [ s[1], s[2] ] # [ PluginName, "option" ]
+      else
+        cdl_error( "S1002 \'$1\': unknown specifier for signature" , s[0] )
+      end
+    }
+  end
+
+  def get_name
+    @name
+  end
+
+  def get_global_name
+    @global_name
+  end
+
+  def get_function_head_array
+    if @function_head_list then
+      return @function_head_list.get_items
+    else
+      return nil
+    end
+  end
+
+  def get_function_head( func_name )
+    return @function_head_list.get_item( func_name.to_sym )
+  end
+
+  #=== Signature# 関数名から signature 内の id を得る
+  def get_id_from_func_name func_name
+    @func_name_to_id[ func_name ]
+  end
+
+  #=== Signature# context を得る
+  # context 文字列を返す "task", "non-task", "any"
+  # 未指定時のデフォルトとして task を返す
+  def get_context
+    if @context then
+      return @context
+    else
+      return "task"
+    end
+  end
+
+  #=== Signature# signaure のすべての関数のすべてのパラメータをたどる
+  #block:: ブロックを引数に取る
+  # ブロックは2つの引数を受け取る  Decl, ParamDecl     ( Decl: 関数ヘッダ )
+  # Port クラスにも each_param がある（同じ働き）
+  def each_param # ブロック引数 { |func_decl, param_decl| }
+    fha = get_function_head_array                       # 呼び口または受け口のシグニチャの関数配列
+    return if fha == nil                                # nil なら文法エラーで有効値が設定されなかった
+
+    pr = Proc.new   # このメソッドのブロック引数を pr に代入
+    fha.each{ |fh|  # fh: FuncHead                      # 関数配列中の各関数頭部
+      fd = fh.get_declarator                            # fd: Decl  (関数頭部からDeclarotorを得る)
+      if fd.is_function? then                           # fd が関数でなければ、すでにエラー
+        fd.get_type.get_paramlist.get_items.each{ |par| # すべてのパラメータについて
+          pr.call( fd, par )
+        }
+      end
+    }
+  end
+
+  #=== Signature# 正当なアロケータ シグニチャかテストする
+  # alloc, dealloc 関数を持つかどうか、第一引き数がそれぞれ、整数、ポインタ、第二引き数が、ポインタへのポインタ、なし
+  def is_allocator?
+
+    # 一回だけチェックする
+    if @b_checked_as_allocator_signature == true then
+      return true
+    end
+    @b_checked_as_allocator_signature = true
+
+    fha = get_function_head_array                       # 呼び口または受け口のシグニチャの関数配列
+    if fha == nil then                                  # nil なら文法エラーで有効値が設定されなかった
+      return false
+    end
+
+    found_alloc = false; found_dealloc = false
+    fha.each{ |fh|  # fh: FuncHead                      # 関数配列中の各関数頭部
+      fd = fh.get_declarator                            # fd: Decl  (関数頭部からDeclarotorを得る)
+      if fd.is_function? then                           # fd が関数でなければ、すでにエラー
+        func_name = fd.get_name.to_sym 
+        if func_name == :alloc then
+          found_alloc = true
+          params = fd.get_type.get_paramlist.get_items
+          if params then
+            if ! params[0].instance_of?( ParamDecl ) ||
+                ! params[0].get_type.get_original_type.kind_of?( IntType ) ||
+                params[0].get_direction != :IN then
+              # 第一引数が int 型でない
+              if ! params[0].instance_of?( ParamDecl ) ||
+                  ! params[0].get_type.kind_of?( PtrType ) ||
+                  ! params[0].get_type.get_type.kind_of?( PtrType ) ||
+                  params[0].get_type.get_type.get_type.kind_of?( PtrType ) ||
+                  params[0].get_direction != :OUT then
+                # 第一引数がポインタ型でもない
+                cdl_error3( @locale, "S1003 $1: \'alloc\' 1st parameter neither [in] integer type nor [out] double pointer type", @name )
+              end
+            elsif ! params[1].instance_of?( ParamDecl ) ||
+                ! params[1].get_type.kind_of?( PtrType ) ||
+                ! params[1].get_type.get_type.kind_of?( PtrType ) ||
+                params[1].get_type.get_type.get_type.kind_of?( PtrType ) ||
+                params[0].get_direction != :IN then
+              # (第一引数が整数で) 第二引数がポインタでない
+              cdl_error3( @locale, "S1004 $1: \'alloc\' 2nd parameter not [in] double pointer" , @name )
+            end
+          else
+            cdl_error3( @locale, "S1005 $1: \'alloc\' has no parameter, unsuitable for allocator signature" , @name )
+          end
+        elsif func_name == :dealloc then
+          found_dealloc = true
+          params = fd.get_type.get_paramlist.get_items
+          if params then
+            if ! params[0].instance_of?( ParamDecl ) ||
+                ! params[0].get_type.kind_of?( PtrType ) ||
+                params[0].get_type.get_type.kind_of?( PtrType ) ||
+                params[0].get_direction != :IN then
+              cdl_error3( @locale, "S1006 $1: \'dealloc\' 1st parameter not [in] pointer type" , @name )
+#            elsif params[1] != nil then    # 第二引き数はチェックしない
+#              cdl_error3( @locale, "S1007 Error message is changed to empty" )
+#                 cdl_error3( @locale, "S1007 $1: \'dealloc\' cannot has 2nd parameter" , @name )
+            end
+          else
+            cdl_error3( @locale, "S1008 $1: \'dealloc\' has no parameter, unsuitable for allocator signature" , @name )
+          end
+        end
+        if found_alloc && found_dealloc then
+          return true
+        end
+      end
+    }
+    if ! found_alloc then
+      cdl_error3( @locale, "S1009 $1: \'alloc\' function not found, unsuitable for allocator signature" , @name )
+    end
+    if ! found_dealloc then
+      cdl_error3( @locale, "S1010 $1: \'dealloc\' function not found, unsuitable for allocator signature" , @name )
+    end
+    return false
+  end
+
+  #=== Signature# シグニチャプラグイン (generate 指定子)
+  def signature_plugin
+    plugin_name = @generate[0]
+    option = @generate[1]
+    apply_plugin( plugin_name, option )
+  end
+
+  #== Signature#apply_plugin
+  def apply_plugin plugin_name, option
+    if is_empty? then
+      cdl_warning( "S9999 $1 is empty. cannot apply signature plugin. ignored" , @name )
+      return
+    end
+
+    plClass = load_plugin( plugin_name, SignaturePlugin )
+    return if plClass == nil
+    if $verbose then
+      print "new through: plugin_object = #{plClass.class.name}.new( #{@name}, #{option} )\n"
+    end
+
+    begin
+      plugin_object = plClass.new( self, option )
+      plugin_object.set_locale @locale
+    rescue Exception => evar
+      cdl_error( "S1150 $1: fail to new" , plugin_name )
+      print_exception( evar )
+    end
+    generate_and_parse plugin_object
+end
+
+  #== Signature# 引数で参照されている Descriptor 型のリストを
+  #RETURN:: Hash { Signature => ParamDecl }:  複数の ParamDecl から参照されている場合、最後のものしか返さない
+  def get_descriptor_list
+    @descriptor_list
+  end
+
+  @@set_descriptor_list = {}
+  def self.set_descriptor_list
+    Namespace.get_root.travers_all_signature{ |sig|
+      if @@set_descriptor_list[ sig ] == nil then
+        @@set_descriptor_list[ sig ] = true
+        sig.set_descriptor_list
+      end
+    }
+  end
+
+  #== Signature# 引数で参照されている Descriptor 型のリストを作成する
+  def set_descriptor_list
+    desc_list = { }
+    # p "has_desc #{@name}"
+    fha = get_function_head_array                       # 呼び口または受け口のシグニチャの関数配列
+    if fha == nil then                                  # nil の場合、自己参照によるケースと仮定
+      @descriptor_list = desc_list
+      return desc_list
+    end
+    fha.each{ |fh|
+      fd = fh.get_declarator                            # fd: Decl  (関数頭部からDeclarotorを得る)
+      if fd.is_function? then                           # fd が関数でなければ、すでにエラー
+        params = fd.get_type.get_paramlist.get_items
+        if params then
+          params.each{ |param|
+            t = param.get_type.get_original_type
+            while( t.kind_of? PtrType )
+              t = t.get_referto
+            end
+            # p "has_desc #{param.get_name} #{t}"
+            if t.kind_of? DescriptorType then
+              desc_list[ t.get_signature ] = param
+              # p self.get_name, t.get_signature.get_name
+              if t.get_signature == self then
+               # cdl_error( "S9999 Descriptor argument '$1' is the same signature as this parameter '$2' included", @name, param.get_name )
+              end
+              dir = param.get_direction
+              if dir != :IN && dir != :OUT && dir != :INOUT then
+                cdl_error( "S9999 Descriptor argument '$1' cannot be specified for $2 parameter", param.get_name, dir.to_s.downcase )
+              end
+            end
+          }
+        end
+      end
+    }
+    @descriptor_list = desc_list
+  end
+
+  #=== Signature# 引数に Descriptor があるか？
+  def has_descriptor?
+    if get_descriptor_list == nil then
+      # end_of_parse が呼び出される前に has_descriptor? が呼び出された
+      # 呼び出し元は DescriptorType#initialize
+      # この場合、同じシグニチャ内の引数が Descriptor 型である
+      return true
+    elsif get_descriptor_list.length > 0 then
+      return true
+    else
+      return false
+    end
+  end
+
+  #=== Signature# コールバックか？
+  # 指定子 callback が指定されていれば true 
+  def is_callback?
+    @b_callback
+  end
+
+  #=== Signature# 逸脱か？
+  # 指定子 deviate が指定されていれば true 
+  def is_deviate?
+    @b_deviate
+  end
+
+  #=== Signature# 空か？
+  def is_empty?
+    @b_empty
+  end
+
+  #=== Signature# Push Pop Allocator が必要か？
+  # Transparent RPC の場合 oneway かつ in の配列(size_is, count_is, string のいずれかで修飾）がある
+  def need_PPAllocator?( b_opaque = false )
+    fha = get_function_head_array                       # 呼び口または受け口のシグニチャの関数配列
+    fha.each{ |fh|
+      fd = fh.get_declarator
+      if fd.get_type.need_PPAllocator?( b_opaque ) then
+        # p "#{fd.get_name} need_PPAllocator: true"
+        @b_need_PPAllocator = true
+        return true
+      end
+      # p "#{fd.get_name} need_PPAllocator: false"
+    }
+    return false
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "Signature: name: #{@name} context: #{@context} deviate : #{@b_deviate} PPAllocator: #{@b_PPAllocator} #{self}"
+    (indent+1).times { print "  " }
+    puts "namespace_path: #{@NamespacePath}"
+    (indent+1).times { print "  " }
+    puts "function head list:"
+    @function_head_list.show_tree( indent + 2 )
+  end
+
+end
+
+module CelltypePluginModule
+  #=== Celltype# セルタイププラグイン (generate 指定子)
+  def celltype_plugin
+    plugin_name = @generate[0]
+    option = @generate[1]
+    @generate[2] = apply_plugin( plugin_name, option )
+  end
+
+  #=== Celltype# セルタイププラグインをこのセルタイプに適用
+  def apply_plugin( plugin_name, option )
+
+    # plClass = load_plugin( plugin_name, CelltypePlugin )
+    if kind_of? Celltype then
+      plugin_class = CelltypePlugin
+    elsif kind_of? CompositeCelltype then
+      plugin_class = CompositePlugin
+    else
+      raise "unknown class #{self.class.name}"
+    end
+    
+    plClass = load_plugin( plugin_name, plugin_class )
+    return if plClass == nil
+    if $verbose then
+      print "new celltype plugin: plugin_object = #{plClass.class.name}.new( #{@name}, #{option} )\n"
+    end
+
+    begin
+      plugin_object = plClass.new( self, option )
+      @generate_list << [ plugin_name, option, plugin_object ]
+      plugin_object.set_locale @locale
+      generate_and_parse plugin_object
+    rescue Exception => evar
+      cdl_error( "S1023 $1: fail to new" , plugin_name )
+      print_exception( evar )
+    end
+
+    # 既に存在するセルに new_cell を適用
+    @cell_list.each{ |cell|
+      apply_plugin_cell plugin_object, cell
+    }
+
+    return plugin_object
+  end
+
+  def apply_plugin_cell plugin, cell
+    begin
+      plugin.new_cell cell
+    rescue Exception => evar
+      cdl_error( "S1037 $1: celltype plugin fail to new_cell" , plugin.class.name )
+      print_exception( evar )
+    end
+  end
+
+  def celltype_plugin_new_cell cell
+    @generate_list.each{ |generate|
+      celltype_plugin = generate[2]
+      begin
+        celltype_plugin.new_cell cell
+      rescue Exception => evar
+        cdl_error( "S1037 $1: celltype plugin fail to new_cell" , celltype_plugin.class.name )
+        print_exception( evar )
+      end
+    }
+  end
+end #CelltypePluginModule
+
+class Celltype < NSBDNode # < Nestable
+# @name:: Symbol
+# @global_name:: Symbol
+# @name_list:: NamedList item: Decl (attribute, var), Port
+# @port:: Port[]
+# @attribute:: Decl[]
+# @var:: Decl[]
+# @require:: [[cp_name,Celltype|Cell,Port],...]
+# @factory_list::   Factory[]
+# @ct_factory_list::    Factory[] :    celltype factory
+# @cell_list:: Cell[] : 定義のみ (V1.0.0.2 以降)
+# @ordered_cell_list:: Cell[] : ID 順に順序付けされたセルリスト、最適化以降有効 (リンク単位ごとに生成されなおす)
+# @singleton:: bool
+# @idx_is_id:: bool
+# @idx_is_id_act:: bool: actual value
+# @b_need_ptab:: bool: true if having cells in multi-domain
+# @active:: bool
+# @b_reuse:: bool :  reuse 指定されて import された(template 不要)
+# @generate:: [ Symbol, String, Plugin ]  = [ PluginName, option, Plugin ] Plugin は生成後に追加される
+# @generate_list:: [ [ Symbol, String, Plugin ], ... ]   generate 文で追加された generate
+#
+# @n_attribute_ro:: int >= 0    none specified
+# @n_attribute_rw:: int >= 0    # of [rw] specified attributes (obsolete)
+# @n_attribute_omit : int >= 0  # of [omit] specified attributes
+# @n_var:: int >= 0
+# @n_var_size_is:: int >= 0     # of [size_is] specified vars # mikan count_is
+# @n_var_omit:: int >= 0        # of [omit] specified vars # mikan var の omit は有？
+# @n_var_init:: int >= 0        # of vars with initializer
+# @n_call_port:: int >= 0       # dynamic ports are included
+# @n_call_port_array:: int >= 0  # dynamic ports are included
+# @n_call_port_omitted_in_CB:: int >= 0   最適化で省略される呼び口
+# @n_call_port_dynamic:: int >= 0  #
+# @n_call_port_array_dynamic:: int >= 0
+# @n_call_port_ref_desc:: int >= 0  #
+# @n_call_port_array_ref_desc:: int >= 0
+# @n_entry_port:: int >= 0
+# @n_entry_port_array:: int >= 0
+# @n_entry_port_inline:: int >= 0
+# @n_cell_gen:: int >= 0  生成するセルの数．コード生成の頭で算出する．意味解析段階では参照不可
+# @id_base:: Integer : cell の ID の最小値(最大値は @id_base + @n_cell)
+#
+# @b_cp_optimized:: bool : 呼び口最適化実施
+# @plugin:: PluginObject      このセルタイプがプラグインにより生成された CDL から生成された場合に有効。
+#                              generate の指定は @generate にプラグインが保持される
+#
+# @included_header:: Hash :  include されたヘッダファイル
+# @domain_roots::Hash { DomainTypeName(Symbol) => [ Region ] }  ドメインタイプ名と Region の配列 (optimize.rb で設定)
+#                                               ルートリージョンはドメイン名が　nil
+
+  include PluginModule
+  include CelltypePluginModule
+  
+  @@nest_stack_index = -1
+  @@nest_stack = []
+  @@current_object = nil
+  @@celltype_list = []
+
+  def self.push
+    @@nest_stack_index += 1
+    @@nest_stack[ @@nest_stack_index ] = @@current_object
+    @@current_object = nil
+  end
+
+  def self.pop
+    @@current_object = @@nest_stack[ @@nest_stack_index ]
+    @@nest_stack_index -= 1
+    if @@nest_stack_index < -1 then
+      raise "TooManyRestore"
+    end
+  end
+
+  def initialize( name )
+    super()
+    @@current_object = self
+    @name = name
+    if "#{Namespace.get_global_name}" != "" then
+      @global_name = :"#{Namespace.get_global_name}_#{@name}"
+    else
+      @global_name = name
+    end
+
+    @name_list = NamedList.new( nil, "symbol in celltype #{name}" )
+    @port = []
+    @attribute = []
+    @var = []
+    @require = []
+    @factory_list = []
+    @ct_factory_list = []
+    @cell_list = []
+    @singleton = false
+    @active = false
+    @generate = nil
+    @generate_list = []
+
+    @n_attribute_ro = 0
+    @n_attribute_rw = 0
+    @n_attribute_omit = 0
+    @n_var = 0
+    @n_var_omit = 0
+    @n_var_size_is = 0
+    @n_var_init = 0
+    @n_call_port = 0
+    @n_call_port_array = 0
+    @n_call_port_omitted_in_CB = 0
+    @n_call_port_dynamic = 0
+    @n_call_port_array_dynamic = 0
+    @n_call_port_ref_desc = 0
+    @n_call_port_array_ref_desc = 0
+    @n_entry_port = 0
+    @n_entry_port_array = 0
+    @n_entry_port_array_ns = 0
+    @n_entry_port_inline = 0
+    @n_cell_gen = 0
+
+    @b_cp_optimized = false
+
+    @plugin = Generator.get_plugin
+      # plugin の場合 PluginObject が返される
+    # 元の Generator から呼出された Generator の中でパースおよび意味チェックされている
+
+    # if @plugin then
+    #  # plugin 生成されるセルタイプは再利用ではない   #833 不具合修正
+    #  @b_reuse = false
+    # else
+      @b_reuse = Generator.is_reuse?
+    # end
+
+    if $idx_is_id then
+      @idx_is_id = true
+      @idx_is_id_act = true
+      @b_need_ptab = true
+    else
+      @idx_is_id = false
+      @idx_is_id_act = false
+      @b_need_ptab = false
+    end
+
+    Namespace.new_celltype( self )
+    set_namespace_path # @NamespacePath の設定
+    set_specifier_list( Generator.get_statement_specifier )
+
+    @included_header = {}
+    @domain_roots = {}
+    @@celltype_list << self
+  end
+
+  def get_name
+    @name
+  end
+
+  #== Celltype#ドメインルートを返す
+  # @domain_roots の説明を参照
+  def get_domain_roots
+    @domain_roots
+  end
+
+  # Celltype# end_of_parse
+  def end_of_parse
+    # 属性・変数のチェック
+    check_attribute
+
+    # アロケータ呼び口を内部生成
+    generate_allocator_port
+
+    # リレーアロケータ、内部アロケータの設定
+    @port.each { |p|
+      p.set_allocator_instance
+    }
+
+    if @n_entry_port == 0 && @active == false && @factory_list.length == 0 &&
+        ( @singleton && @ct_factory_list.length == 0 || ! @singleton )then
+      cdl_warning( "W1002 $1: non-active celltype has no entry port & factory" , @name )
+    end
+
+    if @generate then
+      celltype_plugin
+    end
+
+    # check_dynamic_join ##
+
+    @@current_object = nil
+  end
+
+  def self.new_port( port )
+    @@current_object.new_port( port )
+  end
+
+  def new_port( port )
+    port.set_owner self
+    @port << port
+    @name_list.add_item( port )
+    if port.get_port_type == :CALL then
+      @n_call_port += 1
+      @n_call_port_array += 1 if port.get_array_size != nil
+      if port.is_dynamic? then
+        @n_call_port_dynamic += 1
+        @n_call_port_array_dynamic += 1 if port.get_array_size != nil
+      end
+      if port.is_ref_desc? then
+        @n_call_port_ref_desc += 1
+        @n_call_port_array_ref_desc += 1 if port.get_array_size != nil
+      end
+    else
+      @n_entry_port += 1
+      @n_entry_port_array += 1 if port.get_array_size != nil
+      @n_entry_port_array_ns += 1 if port.get_array_size == "[]"
+      @n_entry_port_inline += 1 if port.is_inline?
+    end
+    port.set_celltype self
+  end
+
+  def get_port_list
+    @port
+  end
+
+  def self.new_attribute( attribute )
+    @@current_object.new_attribute( attribute )
+  end
+
+  #=== Celltype# new_attribute for Celltype
+  #attribute:: [Decl]
+  def new_attribute( attribute )
+    @attribute += attribute
+    attribute.each { |a|
+      a.set_owner self
+      @name_list.add_item( a )
+      if( a.is_omit? )then
+        @n_attribute_omit += 1
+      elsif( a.is_rw? )then
+        @n_attribute_rw += 1
+      else
+        @n_attribute_ro += 1
+      end
+      if a.get_initializer then
+        # 登録後にチェックしても問題ない（attr を参照できないので、自己参照しない）
+        a.get_type.check_init( @locale, a.get_identifier, a.get_initializer, :ATTRIBUTE )
+      end
+    }
+  end
+
+  #=== Celltype# celltype の attribute/var のチェック
+  # STAGE:  S
+  #
+  # このメソッドは celltype のパースが完了した時点で呼出される．
+  def check_attribute
+    # attribute の size_is 指定が妥当かチェック
+    (@attribute+@var).each{ |a|
+      if a.get_size_is then
+        if ! a.get_type.kind_of?( PtrType ) then
+          # size_is がポインタ型以外に指定された
+          cdl_error( "S1011 $1: size_is specified for non-pointer type" , a.get_identifier )
+        else
+
+          # 参照する変数が存在し、計算可能な型かチェックする
+          size = a.get_size_is.eval_const( @name_list )  # C_EXP の可能性あり
+          init = a.get_initializer
+          if init then
+            if ! init.instance_of?( Array ) then
+              # 初期化子が配列ではない
+              cdl_error( "S1012 $1: unsuitable initializer, need array initializer" , a.get_identifier )
+            elsif size.kind_of?( Integer ) && size < init.length then
+              # size_is 指定された個数よりも初期化子の配列要素が多い
+              cdl_error( "S1013 $1: too many initializer, $2 for $3" , a.get_identifier, init.length, size )
+            # elsif a.get_size_is.eval_const( nil ) == nil  # C_EXP の可能性あり
+            end
+
+          end
+        end
+      else
+        if a.get_type.kind_of?( PtrType ) then
+          if a.get_initializer.instance_of?( Array ) ||
+              ( a.get_initializer.instance_of?( Expression ) &&
+                a.get_initializer.eval_const2(@name_list).instance_of?( Array ) ) then
+            # size_is 指定されていないポインタが Array で初期化されていたら、エラー
+            cdl_error( "S1159 $1: non-size_is pointer cannot be initialized with array initializer" , a.get_identifier )
+          end
+        end
+      end
+    }
+  end
+
+  def get_attribute_list
+    @attribute
+  end
+
+  #=== Celltype# アロケータ呼び口を生成
+  #    send, receive 引数のアロケータを呼出すための呼び口を生成
+  def generate_allocator_port
+    @port.each { |port|
+      # ポートのすべてのパラメータを辿る
+      port.each_param { |port, fd, par|
+        case par.get_direction                        # 引数の方向指定子 (in, out, inout, send, receive )
+        when :SEND, :RECEIVE
+          if par.get_allocator then
+            cp_name = :"#{port.get_name}_#{fd.get_name}_#{par.get_name}"     # アロケータ呼び口の名前
+            #           ポート名          関数名         パラメータ名
+            # alloc_sig_path = [ par.get_allocator.get_name ]  # mikan Namespace アロケータ呼び口のシグニチャ #1
+            alloc_sig_path = par.get_allocator.get_namespace_path
+            array_size = port.get_array_size            # 呼び口または受け口配列のサイズ
+            created_port = Port.new( cp_name, alloc_sig_path, :CALL, array_size ) # 呼び口を生成
+            created_port.set_allocator_port( port, fd, par )
+            if port.is_optional? then
+              created_port.set_optional
+            end
+            if port.is_omit? then
+              created_port.set_omit
+            end
+            new_port( created_port )                    # セルタイプに新しい呼び口を追加
+          # else
+          #  already error "not found or not signature" in class ParamDecl
+          end
+        end
+      }
+    }
+  end
+
+  def get_name_list
+    @name_list
+  end
+
+  def self.new_var( var )
+    @@current_object.new_var( var )
+  end
+
+  #=== Celltype# 新しい内部変数
+  #var:: [Decl]
+  def new_var( var )
+    @var += var
+    var.each { |i|     # i: Decl
+      i.set_owner self
+      if i.is_omit? then
+        @n_var_omit += 1
+      else
+        @n_var += 1
+      end
+      @name_list.add_item( i )
+
+      # size_is 指定された配列? mikan  count_is
+      if i.get_size_is then
+        @n_var_size_is += 1
+      end
+
+      if i.get_initializer then
+        i.get_type.check_init( @locale, i.get_identifier, i.get_initializer, :VAR, @name_list )
+        @n_var_init += 1
+      end
+    }
+  end
+
+  def get_var_list
+    @var
+  end
+
+  #=== Celltype# celltype の指定子を設定
+  def set_specifier_list( spec_list )
+    return if spec_list == nil
+
+    spec_list.each { |s|
+      case s[0]
+      when :SINGLETON
+        @singleton = true
+      when :IDX_IS_ID
+        @idx_is_id = true
+        @idx_is_id_act = true
+        @b_need_ptab = true
+      when :ACTIVE
+        @active = true
+      when :GENERATE
+        if @generate then
+          cdl_error( "S1014 generate specifier duplicate"  )
+        end
+        @generate = [ s[1], s[2] ] # [ PluginName, "option" ]
+      else
+        cdl_error( "S1015 $1 cannot be specified for composite" , s[0] )
+      end
+    }
+    if @singleton then
+      @idx_is_id_act = false
+      @b_need_ptab = false
+    end
+  end
+
+  #
+  def self.new_require( ct_or_cell_nsp, ep_name, cp_name = nil )
+    @@current_object.new_require( ct_or_cell_nsp, ep_name.to_sym, cp_name )
+  end
+
+  def new_require( ct_or_cell_nsp, ep_name, cp_name )
+    # Require: set_owner するものがない
+    obj = Namespace.find( ct_or_cell_nsp )    #1
+    if obj.instance_of? Celltype then
+      # Celltype 名で指定
+      ct = obj
+    elsif obj.instance_of? Cell then
+      # Cell 名で指定
+      ct = obj.get_celltype
+    elsif obj == nil then
+      cdl_error( "S1016 $1 not found" , ct_or_cell_nsp.get_path_str )
+      return
+    else
+      cdl_error( "S1017 $1 : neither celltype nor cell" , ct_or_cell_nsp.get_path_str )
+      return
+    end
+
+    if( ! ct.is_singleton? ) then
+      # シングルトンではない
+      cdl_error( "S1018 $1 : not singleton cell" , obj.get_name )
+    end
+
+    # 受け口を探す
+    obj2 = ct.find( ep_name )
+    if( ( ! obj2.instance_of? Port ) || obj2.get_port_type != :ENTRY ) then
+      cdl_error( "S1019 \'$1\' : not entry port" , ep_name )
+      return
+    elsif obj2.get_array_size then
+      cdl_error( "S1020 \'$1\' : required port cannot be array" , ep_name )
+      return
+    end
+
+    if obj2.get_signature == nil then
+      # signature が未定義：既にエラー
+      return
+    end
+
+    require_call_port_prefix = :_require_call_port
+    if cp_name == nil then
+      # 関数名重複チェック
+      @require.each{ |req|
+        unless req[0].to_s =~ /^#{require_call_port_prefix}/ then
+          next     # 名前ありの require は関数名重複チェックしない
+        end
+        port = req[2]
+        if port.get_signature == obj2.get_signature then
+          # 同じ signature （すべて同じ関数名を持つ）個別に出すのではなく、まとめてエラーとする
+          cdl_error( "S1021 $1 : require cannot have same signature with \'$2\'" , obj2.get_name, port.get_name )
+          next
+        end
+        port.get_signature.get_function_head_array.each{ |f|
+          # mikan ここは、namedList からの検索にならないの？（効率が悪い）
+          obj2.get_signature.get_function_head_array.each{ |f2|
+            if( f.get_name == f2.get_name ) then
+              cdl_error( "S1022 $1.$2 : \'$3\' conflict function name in $4.$5" , obj.get_name, obj2.get_name, f.get_name, req[1].get_name, req[2].get_name )
+            end
+          }
+        }
+      }
+    end
+
+    if cp_name == nil then
+      b_has_name = false
+      cp_name = :"#{require_call_port_prefix}_#{ct.get_name}_#{obj2.get_name}"
+    else
+      b_has_name = true
+    end
+    # require を追加
+    @require << [ cp_name, obj, obj2 ]  # [ lhs:cp_name, rhs:Celltype, rhs:Port ]
+
+    # require port を追加 (呼び口として追加する。ただし require をセットしておく)
+    port = Port.new( cp_name, obj2.get_signature.get_namespace_path, :CALL )
+    port.set_require( b_has_name )
+    self.new_port port
+  end
+
+  def self.new_factory( factory )
+    @@current_object.new_factory( factory )
+  end
+
+  def new_factory( factory )
+    factory.set_owner self
+    if factory.get_f_celltype then
+      @ct_factory_list << factory
+    else
+      @factory_list << factory
+    end
+
+    factory.check_arg( self )
+
+  end
+
+  @@dynamic_join_checked_list = {}
+  def self.check_dynamic_join
+    Namespace.get_root.travers_all_celltype{ |ct|
+      if @@dynamic_join_checked_list[ ct ] == nil then
+        @@dynamic_join_checked_list[ ct ] = true
+        ct.check_dynamic_join
+      end
+    }
+  end
+
+  #=== Celltype#dynamic の適合性チェック
+  def check_dynamic_join
+    return if ! $verbose
+    @port.each{ |port|
+      signature = port.get_signature
+      next if signature == nil   # すでにエラー
+      if port.is_dynamic? then
+        dbgPrint( "[DYNAMIC] checking dynamic port: #{@global_name}.#{port.get_name}\n" )
+        # print( "[DYNAMIC] checking dynamic port: #{@global_name}.#{port.get_name}\n" )
+        next if find_ref_desc_port signature
+        next if find_descriptor_param signature, :DYNAMIC
+        cdl_warning( 'W9999 $1 cannot get information for dynamic port $2', @name, port.get_name )
+      elsif port.is_ref_desc? then
+        dbgPrint( "[DYNAMIC] checking ref_desc port: #{@global_name}.#{port.get_name}\n" )
+        # print( "[DYNAMIC] checking ref_desc port: #{@global_name}.#{port.get_name}\n" )
+        next if find_dynamic_port signature
+        next if find_descriptor_param signature, :REF_DESC
+        cdl_warning( 'W9999 $1 cannot put information from ref_desc port $2', @name, port.get_name )
+      elsif port.get_signature then
+        if port.get_signature.has_descriptor? then
+          port.get_signature.get_descriptor_list.each{ |signature, param|
+            dbgPrint( "[DYNAMIC] checking Descriptor parameter: #{@global_name}.#{port.get_name} ... #{param.get_name}\n" )
+            # print( "[DYNAMIC] checking Descriptor parameter: #{@global_name}.#{port.get_name} ... #{param.get_name}\n" )
+            if port.get_port_type == :CALL then
+              if param.get_direction == :IN
+                next if find_ref_desc_port signature
+                next if find_descriptor_param signature, :DYNAMIC
+              elsif param.get_direction == :OUT
+                next if find_dynamic_port signature
+                next if find_descriptor_param signature, :REF_DESC
+              end
+            else  # :ENTRY
+              if param.get_direction == :IN
+                next if find_dynamic_port signature
+                next if find_descriptor_param signature, :REF_DESC
+              elsif param.get_direction == :OUT
+                next if find_ref_desc_port signature
+                next if find_descriptor_param signature, :DYNAMIC
+              end
+            end
+            cdl_warning( 'W9999 "$1" cannot handle Descriptor "$2" information for port "$3"', @name, param.get_name, port.get_name )
+          }
+        end
+      end
+    }
+  end
+
+  def find_dynamic_port signature
+    dbgPrint "[DYNAMIC] find_dynamic_port signature=#{signature.get_name}"
+    @port.each{ |port|
+      dbgPrint "[DYNAMIC] port=#{port.get_name} signature=#{port.get_signature.get_name} dynamic=#{port.is_dynamic?}"
+      return port if port.is_dynamic? && port.get_signature == signature
+    }
+    return nil
+  end
+  def find_ref_desc_port signature
+    if signature == nil then  # すでにエラー
+      return nil
+    end
+    dbgPrint "[DYNAMIC] find_ref_desc_port signature=#{signature.get_name}"
+    @port.each{ |port|
+      dbgPrint "[DYNAMIC] port=#{port.get_name} signature=#{port.get_signature.get_name} ref_desc=#{port.is_ref_desc?}"
+      return port if port.is_ref_desc? && port.get_signature == signature
+    }
+    return nil
+  end
+  #=== Celltype#ディスクリプタ型でシグニチャが一致し dyn_ref に対応づく引数を探す
+  #dyn_ref::Symbol: :DYNAMIC=ディスクリプタを得る手段となる引数を探す．:REF_DESC=渡す手段となる引数を探す
+  def find_descriptor_param signature, dyn_ref
+    param_list = []
+    @port.each{ |port|
+      port.each_param{ |port, func, param|
+        type = param.get_type
+        while type.kind_of? PtrType
+          type = type.get_type
+        end
+        dbgPrint( "[DYNAMIC] dyn_ref=#{dyn_ref} port_type=#{port.get_port_type} dir=#{param.get_direction} paramName=#{param.get_name} paramType=#{type.class}\n" )
+        # print( "[DYNAMIC] dyn_ref=#{dyn_ref} port_type=#{port.get_port_type} dir=#{param.get_direction} paramName=#{param.get_name} paramType=#{type.class}\n" )
+        if type.kind_of? DescriptorType then
+          if type.get_signature == signature then
+            dir = param.get_direction
+            if dir == :INOUT then
+              dbgPrint( "[DYNAMIC] found INOUT Descriptor parameter: #{@global_name}.#{port.get_name} ... #{param.get_name}\n" )
+              # print( "[DYNAMIC] found INOUT Descriptor parameter: #{@global_name}.#{port.get_name} ... #{param.get_name}\n" )
+              return param
+            elsif dyn_ref == :DYNAMIC then
+              if dir == :IN && port.get_port_type == :ENTRY ||
+                 dir == :OUT && port.get_port_type == :CALL then
+                dbgPrint( "[DYNAMIC] found INBOUND Descriptor parameter: #{@global_name}.#{port.get_name} ... #{param.get_name}\n" )
+                # print( "[DYNAMIC] found INBOUND Descriptor parameter: #{@global_name}.#{port.get_name} ... #{param.get_name}\n" )
+                return param
+              end
+            elsif dyn_ref == :REF_DESC
+              if dir == :IN && port.get_port_type == :CALL ||
+                 dir == :OUT && port.get_port_type == :ENTRY then
+                dbgPrint( "[DYNAMIC] found OUTBOUND Descriptor parameter: #{@global_name}.#{port.get_name} ... #{param.get_name}\n" )
+                # print( "[DYNAMIC] found OUTBOUND Descriptor parameter: #{@global_name}.#{port.get_name} ... #{param.get_name}\n" )
+                return param
+              end
+            else
+              raise "unknown ref_desc"
+            end
+          end
+        end
+      }
+    }
+    return nil
+  end
+
+  #=== Celltype# celltype に新しい cell を追加
+  #cell:: Cell
+  # 新しいセルをセルタイプに追加．
+  # セルの構文解釈の最後でこのメソドを呼出される．
+  # シングルトンセルが同じ linkunit に複数ないかチェック
+  def new_cell( cell )
+    dbgPrint "Celltype#new_cell( #{cell.get_name} )\n"
+    # Celltype では Cell の set_owner しない
+    # シングルトンで、プロトタイプ宣言でない場合、コード生成対象リージョンの場合
+    if @singleton  then
+      @cell_list.each{ |c|
+        if c.get_region.get_link_root == cell.get_region.get_link_root then
+          cdl_error( "S1024 $1: multiple cell for singleton celltype" , @name )
+        end
+      }
+    end
+    @cell_list << cell
+
+    # プラグインにより生成されたセルタイプか ?
+    if @plugin then
+      @plugin.new_cell cell
+    end
+
+    # セルタイププラグインの適用
+    celltype_plugin_new_cell cell
+  end
+
+  #=== Celltype# セルタイプは INIB を持つか？
+  # セルタイプが INIB を持つかどうかを判定する
+  # $rom == false のとき:  INIB を持たない． （すべては CB に置かれる）
+  # $rom == true のとき、INIB に置かれるものが一つでも存在すれば INIB を持つ
+  #   INIB に置かれるものは
+  #     attribute (omit のものは除く．現仕様では rw のものはない)
+  #     size_is を伴う var
+  #     呼び口（ただし、最適化で不要となるものは除く）
+  def has_INIB?
+
+    result = $rom &&
+             (@n_attribute_ro > 0 ||
+              @n_var_size_is > 0 ||
+              ( @n_call_port - @n_call_port_omitted_in_CB - (@n_call_port_dynamic-@n_call_port_array_dynamic) ) > 0 ||
+              $ram_initializer && @n_call_port_dynamic > 0 ||
+              @n_entry_port_array_ns > 0)
+    # print "name=#{@name} n_attribute_ro=#{@n_attribute_ro}  n_var_size_is=#{@n_var_size_is} n_call_port=#{@n_call_port} n_call_port_omitted_in_CB=#{@n_call_port_omitted_in_CB} n_call_port_dynamic=#{@n_call_port_dynamic} n_call_port_array_dynamic=#{@n_call_port_array_dynamic} n_entry_port_array_ns=#{@n_entry_port_array_ns} has_INIB?=#{result}\n"
+
+    return result
+  end
+
+  #=== Celltype# セルタイプは CB を持つか？
+  # $rom == true のとき、いかのものが置かれる．それらの一つでも存在すれば CB を持つ
+  #   size_is が指定されていない var
+  #   rw 指定された attribute (現仕様では存在しない)
+  # $rom == false のとき、いかのものが置かれる．それらの一つでも存在すれば CB を持つ
+  #   attribute
+  #   var
+  #   呼び口（ただし、最適化で不要となるものは除く）
+  def has_CB?
+    if $rom then
+      return @n_attribute_rw > 0 || (@n_var-@n_var_size_is) > 0 || (@n_call_port_dynamic - @n_call_port_array_dynamic) > 0
+      # return @n_attribute_rw > 0 || @n_var > 0
+    else
+      return @n_attribute_rw > 0 || @n_attribute_ro > 0 || @n_var > 0 || (@n_call_port-@n_call_port_omitted_in_CB) > 0 || @n_entry_port_array_ns > 0
+    end
+  end
+
+  #=== Celltype# SET_CB_INIB_POINTER, INITIALIZE_CB が必要か
+  def need_CB_initializer?
+    @n_var_init > 0 || has_CB? || ( @n_call_port_dynamic && $ram_initializer )
+  end
+
+  #=== Celltype# 逆require の結合を生成する
+  def create_reverse_require_join cell
+    @port.each{ |p|
+      p.create_reverse_require_join cell
+    }
+  end
+
+  #=== Celltype# singleton セルを得る
+  #region:: Region   : singleton を探す Region
+  # 距離が最も近いものを返す
+  # mikan 本当は region の範囲の singleton を探す必要がある
+  def get_singleton_cell region
+    cell = nil
+    dist = 999999999 # mikan 制限値（これは十分すぎるほどデカイが）
+    # require: celltype で指定
+    @cell_list.each{ |c|
+      # 到達可能で最も近いセルを探す（複数の singleton があるかもしれない）
+      d = region.distance( c.get_region )
+      #debug
+      dbgPrint "distance #{d} from #{region.get_name} to #{c.get_name} in #{c.get_region.get_name}\n"
+      # print "DOMAIN: distance #{d} from #{region.get_name} to #{c.get_name} in #{c.get_region.get_name}\n"
+      if d != nil then
+        if d < dist then
+          cell = c
+          dist = d
+        end
+      end
+    }
+    return cell
+  end
+
+  def find( name )
+    @name_list.get_item( name )
+  end
+
+  #=== Celltype# セルタイププラグインを得る
+  def get_celltype_plugin
+    if @generate then
+      return @generate[2]
+    end
+  end
+
+  def get_global_name
+    @global_name
+  end
+
+  def is_singleton?
+    @singleton
+  end
+
+  def is_active?
+    @active
+  end
+
+  def idx_is_id_act?
+    @idx_is_id_act
+  end
+
+  def multi_domain?
+    @b_need_ptab
+  end
+
+  #=== Celltype# アクティブではないか
+  # このメソッドでは active の他に factory (singleton においては FACTORYを含む)がなければ inactive とする
+  def is_inactive?
+    if @active == false && @factory_list.length == 0 &&
+        ( @singleton && @ct_factory_list.length == 0 || ! @singleton )then
+      return true
+    end
+    return false
+  end
+
+  def get_id_base
+    @id_base
+  end
+
+  def get_plugin
+    @plugin
+  end
+
+  def get_require
+    @require
+  end
+
+  #=== Celltype# コード生成する必要があるか判定
+  # セルの個数が 0 ならセルタイプコードは生成不要
+  def need_generate?
+    @n_cell_gen > 0
+  end
+
+  #=== Celltype# require 呼び口の結合を行う
+  # STAGE: S
+  # セルタイプの require 呼び口について、結合を行う
+  # セルが生成されないかチェックを行う
+  def set_require_join
+    @require.each{ |req|
+      cp_name = req[0]
+      cell_or_ct = req[1]
+      port = req[2]
+      @cell_list.each{ |c|
+        c.set_require_join( cp_name, cell_or_ct, port )
+      }
+    }
+  end
+
+  def get_cell_list
+    @cell_list
+  end
+
+  #=== Celltype# inline 受け口しかないか？
+  # 受け口が無い場合、すべての受け口が inline とはしない
+  def is_all_entry_inline?
+    @n_entry_port == @n_entry_port_inline && @n_entry_port > 0
+  end
+
+  #=== Celltype.get_celltype_list
+  def self.get_celltype_list
+    @@celltype_list
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "Celltype: name=#{@name} global_name=#{@global_name}"  
+    (indent+1).times { print "  " }
+    puts "active=#{@active}, singleton=#{@singleton}, idx_is_id=#{@idx_is_id} plugin=#{@plugin.class} reuse=#{@b_reuse}"
+    (indent+1).times { print "  " }
+    puts "namespace_path: #{@NamespacePath}"
+    (indent+1).times { print "  " }
+    puts "port:"
+    @port.each { |i| i.show_tree( indent + 2 ) }
+    (indent+1).times { print "  " }
+    puts "attribute:"
+    @attribute.each { |i| i.show_tree( indent + 2 ) }
+    (indent+1).times { print "  " }
+    puts "var:"
+    @var.each { |i| i.show_tree( indent + 2 ) }
+#    (indent+1).times { print "  " }
+#    puts "require:"   mikan
+#    @require.each { |i| i.show_tree( indent + 2 ) }
+    (indent+1).times { print "  " }
+    puts "factory:"
+    @factory_list.each { |i| i.show_tree( indent + 2 ) }
+    (indent+1).times { print "  " }
+    puts "@n_attribute_ro #{@n_attribute_ro}"
+    (indent+1).times { print "  " }
+    puts "@n_attribute_rw #{@n_attribute_rw}"
+# @n_attribute_omit : int >= 0  # of [omit] specified cells
+# @n_var:: int >= 0
+# @n_var_size_is:: int >= 0     # of [size_is] specified cells # mikan count_is
+# @n_var_omit:: int >= 0        # of [omit] specified  cells # mikan var の omit は有？
+# @n_call_port:: int >= 0
+# @n_call_port_array:: int >= 0
+# @n_call_port_omitted_in_CB:: int >= 0   最適化で省略される呼び口
+# @n_entry_port:: int >= 0
+# @n_entry_port_array:: int >= 0
+    (indent+1).times { print "  " }
+    puts "@n_entry_port_inline #{@n_entry_port_inline}"
+# @n_cell:: int >= 0  コード生成の頭で算出する．意味解析段階では参照不可
+# @id_base:: Integer : cell の ID の最小値(最大値は @id_base + @n_cell)
+
+  end
+end
+
+class Cell < NSBDNode # < Nestable
+# @name:: Symbol : composite celltype の内側のインスタンスでは外のセル
+# @global_name:: Symbol : C で使える名前（namespace を含む）
+# @local_name:: str : cell celltype name { ... } の name
+# @celltype:: Celltype | CompositeCelltype
+# @join_list:: NamedList
+# @reverse_join_list:: NamedList
+# @b_defined:: definition flag (false if only prototype )
+# @b_prototype:: bool:  prototype specified in current parsing cell. (@b_defined is used to determine whether definition done)
+# @b_duplicate:: bool:  definition duplicate
+# @b_checked::   bool:  set_definition_join が済んでいる場合 true
+# @require_joined_list:: {cp_name=>true}:  set_require_join が済んでいる呼び口は true
+# @f_ref:: refercenced from others
+# @entry_array_max_subscript:: { @port=>Integer } : 受け口配列の配列添数の最大値（添数無し受け口配列対応）
+# @plugin::     Plugin: avialble if cell is generated by plugin generated cdl code.
+# @referenced_port_list:: { Port => Integer } : 受け口の参照数
+#                                               すべての意味解析(through, composite展開)が終わった後に設定する
+#                                               逆require ポートに対して複数の結合がないかチェックする
+# @generate:: [ Symbol, String, Plugin ]  = [ PluginName, option, Plugin ] Plugin は生成後に追加される
+# @b_post_code_generated:: Bool: true if generated in tmp_plugin_post_code.cdl
+#
+# composite のためインスタンス変数
+# @in_composite:: bool : true if in composite celltype
+# @compositecelltypejoin_list:: NamedList : item= CompositeCelltypeJoin ( if @in_composite )
+# @f_cloned:: bool : true if cloned (instantiate of composite consist cell)
+# @my_clone:: Cell : Composite cell で in_composite = true の場合のみ有効（直前の clone を一時記憶）
+# @cell_list:: Cell[local_name] : Composite cell で clone した後のリスト cell_list
+# @cell_list2:: [ Cell ] : Composite cell で clone した後のリスト cell_list
+#                          @cell_list2 は composite 内での出現順  
+#
+# region のためのインスタンス変数
+# @region:: Region (属するregion)
+#
+# allocator のためのインスタンス変数
+# @alloc_list::  [ [ NORMAL_ALLOC, ep_name, func_name, param_name, expr ], ... ]
+#   受け口側のアロケータへの結合を記憶。以下のメソッドで追加される
+#      set_specifier … cell 定義時にアロケータ指定されている場合
+#      create_relay_allocator_join … リレーアロケータの場合
+#
+# ID のためのインスタンス変数（optimize.rb にて設定）
+# @id:: Integer : コード生成直前に設定  (プロトタイプ宣言の場合は -1 のまま放置)
+# @id_specified::Integer : 指定された id
+# @restrict_list::{ entry_name => { func_name, [ region_path_str, ... ] } }
+# @restrict_list2::{ entry_name => { func_name, [ domain_root_region, ... ] } }
+# @b_restrict_referenced::Bool: restrict_list が参照れた
+
+=begin
+# Cell クラスは、以下のものを扱う
+# 1)普通のセル
+# 2)composite セルタイプのセル
+# 3)composite セルタイプの内側のセル (@in_composite)   # composite の内側の composite セルタイプのセルもある
+#
+# 2) は CellOfComposite クラスとして分けたほうがよいかもしれない
+#    expand (composite セルの展開) は CellOfComposite にのみ必要なメソッドである
+#    get_real_cell, get_real_port など @celltype.instance_of?( CompositeCelltype ) の判定がなくすっきりする
+#    ただ、分離しても、メンテナンスすべき範囲が切り離されてしまい、忘れやすくなる問題とのトレードオフかも
+#
+# 3) は CellInCompoiste クラスとして分けたほうがよいかもしれない
+#    @in_composite で判定している処理を切り離せる (上記 2) よりも分離は容易ではない)
+#    clone_for_composite は CellInCompoiste にのみ必要なメソッドである
+#    ただし、clone 後に Cell, CellOfComposite に変化する必要があるので、clone ではなく new する実装に変更する必要がある
+#
+=end
+
+  include PluginModule
+
+  @@nest_stack_index = -1
+  @@nest_stack = []
+  @@current_object = nil
+
+  # 定義されたすべてのセル（出現順. namespace に影響されない）
+  @@cell_list = []     # composite の内部のセルを含まない
+  @@cell_list2 = []    # composite の内部のセルを含む (元のセルを含む)
+                       # 意味解析後 make_cell_list2 にて設定される
+
+  def self.push
+    @@nest_stack_index += 1
+    @@nest_stack[ @@nest_stack_index ] = @@current_object
+    @@current_object = nil
+  end
+
+  def self.pop
+    @@current_object = @@nest_stack[ @@nest_stack_index ]
+    @@nest_stack_index -= 1
+    if @@nest_stack_index < -1 then
+      raise "TooManyRestore"
+    end
+  end
+
+  def initialize( ct_path, in_composite = false )
+    super()
+    @region = Region.get_current
+
+    # celltype のplugin/存在をチェック
+    object = Namespace.find( ct_path )    #1
+    if object == nil then
+      # mikan celltype の名前が不完全 "::ct1ct2" になる
+      cdl_error( "S1027 \'$1\' celltype not found" , ct_path.get_path_str )
+    elsif ! object.instance_of?( Celltype ) && ! object.instance_of?( CompositeCelltype ) then
+      # mikan celltype の名前が不完全
+      cdl_error( "S1028 \'$1\' not celltype" , ct_path.get_path_str )
+    else
+      @celltype = object
+    end
+
+    @in_composite = in_composite
+    if @in_composite then
+      @compositecelltypejoin_list = NamedList.new( nil, "in cell '#{@name}'" )
+      @plugin = nil
+    else
+      @compositecelltypejoin_list = nil
+      @plugin = Generator.get_plugin
+    end
+
+    @@current_object = self
+    @b_defined = false
+    @b_prototype = false
+    @f_ref     = false
+    @f_cloned  = false
+    @alloc_list = []
+    @id = -1
+    @id_specified = nil
+    @b_duplicate = false
+    @b_checked = false
+    @require_joined_list = {}
+    @entry_array_max_subscript = {}
+    @referenced_port_list = {}
+    @restrict_list = {}
+    @restrict_list2 = {}
+    @b_restrict_referenced = false
+    @b_post_code_generated = false
+
+    @cell_list = {}
+    @cell_list2 = []
+  end
+
+  def self.set_name( name )
+    @@current_object.set_name( name )
+  end
+
+  def set_name( name )
+
+    @name = name
+    @local_name = name
+    if "#{Namespace.get_global_name}" != "" then
+      @global_name = :"#{Namespace.get_global_name}_#{name}"
+    else
+      @global_name = name
+    end
+
+    # この時点ではプロトタイプか、定義か分らないが、自己参照のために登録
+    # set_f_def で再度登録しなおす
+    # Celltype への登録は、end_of_parse で行う
+    if @in_composite then
+      cell_prev = CompositeCelltype.find( name )
+      if cell_prev == nil then
+        CompositeCelltype.new_cell_in_composite( self )
+      end
+    else
+      # cell_prev = Namespace.find( [ name ] )   # 親まで捜しにいく
+      cell_prev = Namespace.get_current.find( name )
+      if cell_prev == nil then
+        Namespace.new_cell( self )
+        set_namespace_path # @NamespacePath の設定
+      end
+    end
+
+    if cell_prev then
+      if ! cell_prev.instance_of?( Cell ) then
+        cdl_error( "S1029 $1 mismatch with previous one" , name )
+        # celltype が一致しているか ?
+      elsif get_celltype != cell_prev.get_celltype then
+        cdl_error( "S1030 $1: celltype mismatch with previous one" , name )
+      else
+        # region が一致しているか?
+        if ! cell_prev.get_region.equal? get_region then
+          cdl_error( "S1031 $1 region \'$2\' mismatch  with previous one \'$3\'" , name, @region.get_name, cell_prev.get_region.get_name )
+        end
+
+        @@current_object = cell_prev
+        # この時点では、まだプロトタイプ宣言か定義か分らない
+        # 以前が定義であって、今回も定義の場合、重複エラーである
+      end
+    end
+
+    @join_list = NamedList.new( nil, "in cell '#{@name}'" )
+    @reverse_join_list = nil
+
+    # debug
+    dbgPrint "Cell new_cell: #{@global_name} #{@in_composite} #{self}\n"
+
+    # 内部アロケータを @alloc_list に追加
+    if @celltype.instance_of? CompositeCelltype then
+      @celltype.get_internal_allocator_list.each{ |cell, cp_internal_name, port_name, fd_name, par_name, ext_alloc_ent|
+        nsp = NamespacePath.new( @name, false )
+        rhs = Expression.new( [:OP_DOT, [:IDENTIFIER, nsp], Token.new( ext_alloc_ent.to_s.to_sym, nil, nil, nil ) ] )  #1 構文解析段階なので locale 不要
+
+        @alloc_list << [:NORMAL_ALLOC,port_name,nil,fd_name,par_name,rhs]
+# print "add alloc_list: #{port_name}.#{fd_name}.#{par_name}=#{rhs.to_s}\n"
+      }
+    end
+  end
+
+  #=== Cell# cell の定義
+  # 本体(join)の定義の直前に呼び出される
+  def self.new_def
+    @@current_object.new_def
+  end
+
+  #=== Cell# cell の定義
+  # 本体(join)の定義の直前に呼び出される
+  # このメソッドは cell tCelltype Cell { };  '{', '}' の部分がある場合に呼出される
+  def new_def
+    set_specifier_list( Generator.get_statement_specifier )
+
+    # prototype 指定子ないか
+    if ! @b_prototype then
+      # 二重定義のチェック
+      if @b_defined == true then
+        cdl_error( "S1032 $1: duplicate cell" , @name )
+        dbgPrint "previous: #{@prev_locale[0]}: line #{@prev_locale[1]} '#{@name}' defined here\n"
+
+        # セルの重複定義エラーの処置
+        # 前の定義は捨てる
+        @join_list = NamedList.new( nil, "in cell '#{@name}'" )
+      end
+
+      @b_defined = true
+      @prev_locale = @locale
+    end
+  end
+
+  def self.new_join( join, b_regular = false )
+    @@current_object.new_join( join, b_regular )
+  end
+
+  #===  Cell# 新しい結合をチェック
+  # STAGE:   P
+  #
+  #join::  Join : 新しい結合
+  #b_regular:: bool : 通常の場所 (bnf.y.rb)からならば true, それ以外(allocator, require) では false
+  def new_join( join, b_regular = false )
+    join.set_owner self
+
+    # composite の新文法対応．
+    # composite の中のセルで、attribute の定義である場合
+    # cell 内の attr_ext = composite.attr; 構文を処理
+    if @in_composite then
+      if @celltype then
+        if @celltype.find(join.get_name).instance_of?( Decl ) then # mikan a::b で指定されていたものがエラーにならないかも
+          rhs = join.get_rhs
+          if rhs.instance_of? Expression then
+            ele = rhs.get_elements
+            if( ele[0]==:IDENTIFIER )then    #  attr = attr_ext （右辺単項）か？ #1
+              if( CompositeCelltype.has_attribute?(ele[1].get_name ) )then    # mikan a::b.ePort がエラーにならないかも
+                ident = ele[1].get_name   # 右辺は attribute．
+              else
+                # 右辺は attribute にないのであれば、定数のはず
+                # 定数は下へ渡す (cell の join にする)
+                ident = nil
+              end
+            else
+              if join.get_rhs.eval_const2(nil) == nil then   # 定数式ではないか？
+                # 右辺が、単一のシンボルでない場合、現状は扱えない
+                cdl_error( "S1033 rhs expression is not supported. Only attribute is permitted on current version."  )
+                return
+              else
+                # 定数は下へ渡す (cell の join にする)
+                ident = nil
+              end
+            end
+
+            if ident then
+              # attr = attr; のような参照はエラー (a = composite.a とする必要がある)
+              if @celltype.find( ident ) then
+                cdl_error( "S1034 $1 : cannot refer to $2\'s attribute here. Use \'composite.$3\' to refer to composite celltype\'s" , ident, @celltype.get_name, ident )
+              end
+            end
+          elsif rhs.instance_of? Array then
+            if rhs[0] == :COMPOSITE then   # 右辺は composite.attr の形式
+              ident = rhs[1].to_sym
+            else
+              ident = nil    # 右辺は { 10, -10 } の形式
+            end
+          else
+            ident = nil      # 右辺は C_EXP の形式
+          end
+
+          # ident が見つかった（右辺は単一の ident）
+          if ident then
+            # composite の旧文法の構文処理へ渡す．セル外の attr_ext = Cell.attr; 構文の処理に渡す
+            #                        export_name, internal_cell_name, internal_cell_elem_name
+            decl = CompositeCelltype.new_join( ident, @name, join.get_name, :ATTRIBUTE )  # mikan a::b.ePort がエラーにならないかも
+            if ! decl.instance_of? Decl then
+              return
+            end
+            ini = decl.get_initializer
+            if ini == nil then
+              return
+            end
+            # 以下の旧文法実装に渡す．
+            # 旧文法では cell に初期値を与えることで、composite で属性の初期値を指定することができた
+            # attribute で指定された初期値を cell の属性として処理させる
+            join.change_rhs( ini )
+          else
+            # ident がない．定数式
+          end
+        else
+          # celltype の属性として、この join の名前がない
+          # 以下の join.set_definition の中でエラーとなる
+        end
+      else
+        return    # celltype がない．すでにエラー
+      end
+    elsif join.get_rhs.instance_of? Array then
+      rhs = join.get_rhs
+      if rhs[0] == :COMPOSITE then
+        # composite の中でないのに attr = composite.attr が使われた
+        cdl_error( "S1035 composite : cannot specify out of composite celltype definition"  )
+        return
+      end
+    end
+
+    # 以下 composite 文法変更前からある処理
+
+    # 既に左辺が同じ名前の初期化が存在するか？
+    j = @join_list.get_item( join.get_name )   # mikan NamespacePath がパスを持っている
+    if j.instance_of? Join then    # mikan ここでは j が Join or Nil 以外は、ないはず
+
+      # debug
+      dbgPrint "add_array_member: #{@name} port: #{j.get_port_name} rhs: #{j.get_rhs}, #{join.get_port_name} #{join.get_rhs}\n"
+      # 呼び口配列（であると仮定して）要素を追加
+      j.add_array_member join
+
+    else
+      dbgPrint "new_join: cell=#{@name} add_item=#{join.get_name}\n"
+      # join
+      @join_list.add_item( join )
+    end
+
+    # if get_owner then   # error S1030 発生時 get_owner が見つからなくて例外になる
+    #   dbgPrint "Cell#new_join: #{get_owner.get_name}.#{@name}\n"
+    # else
+    #   dbgPrint "Cell#new_join: \"owner not fund\".#{@name}\n"
+    # end
+    if ! @in_composite then
+     if join.get_cell
+       dbgPrint "new_join: #{@name} #{@region.get_name} => #{join.get_cell.get_name} #{join.get_cell.get_region.get_path_string}\n"
+     end
+#     p "region: generate? #{@region.is_generate?}"
+    end
+
+  end
+
+  #=== Cell.新しい逆結合
+  def self.new_reverse_join( reverse_join )
+    @@current_object.new_reverse_join( reverse_join )
+  end
+
+  #=== Cell#新しい逆結合
+  def new_reverse_join( reverse_join )
+    dbgPrint( "new_reverse_join name=#{reverse_join.get_name}\n")
+    b_cb = false
+    if @celltype then
+      ep_name = reverse_join.get_name
+      port = @celltype.find ep_name
+      if port && port.get_signature
+        if port.get_signature.is_callback? then
+          b_cb = true
+        end
+      end
+    end
+    if ! @b_prototype && ! b_cb then
+      cdl_error( "S9999 '$1': reverse join can be used in prototype cell, or with callback signature", @name )
+    end
+    if @reverse_join_list == nil then
+#      @reverse_join_list = NamedList.new( reverse_join, "in cell '#{@name}'" )
+      @reverse_join_list = [ reverse_join ]
+    else
+#      @reverse_join_list.add_item( reverse_join )
+      @reverse_join_list << reverse_join
+    end
+  end
+
+  #=== Cell#逆結合から結合を生成
+  # STAGE: S
+  def create_reverse_join
+    if @b_checked then
+      return
+    end
+
+    if @reverse_join_list then
+#      @reverse_join_list.get_items.each{ |rj|
+      @reverse_join_list.each{ |rj|
+        # 逆結合の情報を得る
+        ep_name = rj.get_name
+        ep_subscript, cp_cell_nsp, cp_name, cp_subscript = rj.get_rhs_cell_and_port
+
+        # 呼び口側のセルと、そのセルタイプ
+        if ! @in_composite then
+          cell = Namespace.find cp_cell_nsp
+        else
+          cell = CompositeCelltype.find cp_cell_nsp.to_s.to_sym
+        end
+
+        if ! cell.instance_of? Cell then
+          cdl_error( "S9999 '$1': not cell for reverse join", cp_cell_nsp.get_path_str )
+          next
+        end
+        ct = cell.get_celltype
+        if ct == nil then
+          next
+        end
+
+        if ! @in_composite then
+          ep_cell_nsp = get_namespace_path
+          ep_cell_nsp_str = ep_cell_nsp.get_path_str
+        else
+          ep_cell_nsp = NamespacePath.new @name, false
+          ep_cell_nsp_str = @name
+        end
+        ep_subscript_val = ep_subscript ? ep_subscript.eval_const( nil ) : nil
+        rhs = Expression.create_cell_join_expression( ep_cell_nsp, ep_subscript_val, ep_name, rj.get_locale )
+        join = Join.new( cp_name, cp_subscript, rhs, rj.get_locale )
+        cell.new_join( join )
+        # join.set_definition( ct.find(join.get_name) )
+        if cp_subscript then
+          ss_str = "[#{cp_subscript}]"
+        else
+          ss_str = ""
+        end
+        dbgPrint "create_reverse_join: #{cell.get_name}.#{cp_name}#{ss_str} => #{ep_cell_nsp_str}.#{ep_name}\n"
+      }
+    end
+  end
+
+  def self.external_join( internal_cell_elem_name, export_name, b_composite )
+    @@current_object.external_join( internal_cell_elem_name, export_name, b_composite )
+  end
+
+  #=== Cell# cell 内に記述する呼び口の外部結合
+  # internal_cell_elem_name:: string : 呼び口名
+  # export_name:: string: composite の外部に公開する呼び口名
+  #  呼び口を外部結合する．
+  #  このメソッドは、composite の中の cell でしか呼ばれない．
+  def external_join( internal_cell_elem_name, export_name, b_composite )
+
+    # cCall => composite.cCall; ではないか？
+    if( b_composite == false )then
+      # cCall => cCall; のような場合
+      if @celltype.find( export_name ) then
+        cdl_error( "S1036 $1 : cannot refer to $2\'s here. Use \'composite.$3\' to refer to composite celltype\'s" , export_name, @celltype.get_name, export_name )
+      end
+    end
+    # composite の旧文法における、cell 外の cCall = Cell.cCall; の構文処理に渡す
+    CompositeCelltype.new_join( export_name, @name,  internal_cell_elem_name, :CALL )
+  end
+
+  def self.end_of_parse f_def
+    cell = @@current_object
+    cell.end_of_parse f_def
+    @@current_object = nil
+    return cell
+  end
+
+  def end_of_parse f_def
+    if @b_prototype then  # prototype 指定子あったか?
+      f_def = false       # プロトタイプ宣言とする
+      @b_prototype = false
+    end
+    if f_def == false then
+      # cell tCelltype Cell; の形式の場合
+      # f_def == true の場合 new_def で、呼出される
+      set_specifier_list( Generator.get_statement_specifier )
+    end
+    if TECSGEN.post_coded?
+      @b_post_code_generated = true
+    end
+    set_f_def f_def
+
+    if @generate then
+      cell_plugin
+    end
+  end
+
+  #=== Cell# プロトタイプ宣言(false)か定義(true)かを設定
+  #    このメソッドは構文解釈の最後に呼出される
+  #f_def::     bool     false if prototype, true if definition
+  def set_f_def f_def
+    if ! f_def then
+      return
+    end
+
+    if ! @in_composite then
+      # if @celltype.instance_of? Celltype then
+      if @celltype then  # composite でも呼びだす, エラー時 nil
+        @celltype.new_cell self
+      end
+      @@cell_list << self
+    end
+  end
+
+  def set_f_ref
+    dbgPrint "set_f_ref: #{@global_name}\n"
+    @f_ref = true
+
+    # composite の内部セルを参照されたことにする
+    # 今のところ問題ないが、未参照であるべきものまで参照されたことになる
+    if @cell_list then
+      @cell_list.each{ |cn,cell|
+        cell.set_f_ref
+      }
+    end
+  end
+
+  #=== Cell# cell の指定子を設定
+  # STAGE:  B
+  #
+  #    bnf.y.rb の statement_specifiler_list
+  #spec_list::      [ :ALLOCATOR, [ [ :NORMAL_ALLOC, ep_name, subscript, func_name, param_name, expr ], ... ] ]
+  #                     s[0]      s[1]   a[0]        a[1]       a[2]        a[3]     a[4]       a[5]
+  #    セルに指定されたアロケータ指定子
+  #    a[1] の subscript はこのメソッドの中で Expression から Integer に評価される
+  #    受け口側に生成されるアロケータ呼び口の結合を内部生成する
+  #    呼び口側は Port の create_allocator_join にて生成
+  #    リレーアロケータの場合 create_relay_allocator_join にて生成す
+  def set_specifier_list( spec_list )
+    return if spec_list == nil  # 空ならば何もしない
+
+    dbgPrint( "set_spec_list: #{@name}\n" )
+    b_generate = false   # generate が指定された
+
+    spec_list.each{ |s|
+      case s[0]             # statement_specifier
+      when :ALLOCATOR       # [allocator(ePort.func.param=allocCell.eA,ePort.func2.param=allocCell.eA)]
+        s[1].each { |a|     # alloc_list : allocator の内部の ',' で区切られた部分の配列
+          cp_name = :"#{a[0+1]}_#{a[2+1]}_#{a[3+1]}"    # アロケータ呼び口の名前：'=' の左辺を '.' に変えて '_' で連結
+          # p "#{a[0]} #{a[0+1]} #{a[2+1]} #{a[3+1]} #{cp_name}"
+          if a[1+1] then
+            subscript = a[1+1].eval_const nil
+            a[1+1] = subscript
+          else
+            subscript = nil
+          end
+          # アロケータ呼び口の結合を生成
+          join = Join.new( cp_name, subscript, a[4+1] )   # 構文解析段階なので locale 不要
+          dbgPrint( "new allocator join #{cp_name} #{subscript} #{a[4+1]}\n" )
+          Cell.new_join( join )
+          @alloc_list << a 
+        }
+      when :ID          # [id(0)]
+        if ! s[1].instance_of? Expression then
+          cdl_error( "S1160 $1 must be constant for id", s[1].to_s )
+        else
+          id = s[1].eval_const nil
+          if id == nil || Integer(id) != id then
+            cdl_error( "S1161 $1 must be constant for id", s[1].to_s )
+          elsif id == 0 then
+            cdl_error( "S1162 $1: id cannot be 0", s[1].to_s )
+          else
+            @id_specified = id
+          end
+        end
+      when :GENERATE      # [generate(CellPlugin,"option")]
+        if @generate then
+          cdl_error( "S1163 generate specifier duplicate"  )
+        end
+        @generate = [ s[1], s[2] ] # [ PluginName, "option" ]
+        b_generate = true
+      when :PROTOTYPE     # [prototype]
+        @b_prototype = true
+      when :RESTRICT      # [restrict]
+        s[1].each{ |re|
+          add_restrict re[0], re[1], re[2]
+        }
+      else
+          cdl_error( "S1039 \'$1\': unknown specifier for cell" , s[0] )
+      end
+    }
+    if @b_prototype then
+      if b_generate then
+         cdl_error( "S9999 '$1': generate and prototype specified simultaneously" , @name )
+      end
+      if @b_defined then
+         cdl_error( "S9999 '$1': prototype specified after definition" , @name )
+      end
+    end
+  end
+
+  def get_allocator_list
+
+    # 意味チェック(set_definition)されていない？
+    # relay アロケータの場合、セルの意味チェックが行われていないと、@alloc_list が完成しない
+    if @b_checked == false then
+      set_definition_join
+    end
+    @alloc_list
+  end
+
+  def get_specified_id
+    @id_specified
+  end
+
+  #=== id 指定子の値を設定
+  # このメソッドは、プラグインで cell の生成順序を制御したい場合のために設けた
+  # 通常の id 指定子では使っていない
+  def set_specified_id id
+    if Integer( id ) != id || id <= 0 then
+      cdl_error( "S1164 '$1' set_specified_id: id not positive integer '$2'", @name, id )
+    elsif @id_specified then
+      cdl_error( "S1165 '$1' set_specified_id: id duplicate", @name )
+    else
+      @id_specified = id
+    end
+  end
+
+  #=== Cell# セルプラグイン (generate 指定子)
+  def cell_plugin
+    plugin_name = @generate[0]
+    option = @generate[1]
+    @generate[2] = apply_plugin plugin_name, option
+  end
+
+  def apply_plugin plugin_name, option
+    if ! @b_defined then
+      cdl_error( "S9999 plugin cannot apply to prototype cell '$1'", @name )
+    end
+
+    plClass = load_plugin( plugin_name, CellPlugin )
+    # return if plClass == nil # 従来と仕様が変わるので、継続する
+    if $verbose then
+      print "new cell plugin: plugin_object = #{plClass.class.name}.new( #{@name}, #{option} )\n"
+    end
+
+    begin
+      plugin_object = plClass.new( self, option )
+      plugin_object.set_locale @locale
+      generate_and_parse plugin_object
+    rescue Exception => evar
+      cdl_error( "S1166 $1: fail to new", plugin_name )
+      print_exception( evar )
+    end
+    return  plugin_object
+  end
+
+  def add_compositecelltypejoin join
+    @compositecelltypejoin_list.add_item join
+  end
+
+  #=== Cell# cell を composite セルタイプのセル用に clone する
+  #name::        string : 親 cell の名前  (cell tComposite cell1 での cell1)
+  #global_name:: string : 親 cell の global_name 
+  #join_array::  Join[] : composite の cell の join で、この cell に対応するもの
+  #ct_name::     string : 親セルのセルタイプ名
+  #region::      Region : 元のセルが属する region
+  #このメソッドは CompositeCelltype の expand から呼出される
+  def clone_for_composite( name, global_name, namespacePath, join_array, ct_name, region, plugin, locale )
+
+    # debug
+    dbgPrint "  CLONING Cell#clone_for_composite : cloning: #{@name} #{global_name}  b_defined=#{@b_defined} #{self}=>#{@my_clone} \n"
+    dbgPrint "              my_name=#{@name} name=#{name} owner class=#{@owner.class.name}\n"
+
+    @my_clone = self.clone
+
+    # clone したセルの内部に持つ名前情報を調整する
+    @my_clone.set_cloned( name, global_name, namespacePath, join_array, ct_name, region, plugin, locale )
+
+    # @celltype == nil は以前にセルタイプ未定義エラー
+    if @b_defined == true && @celltype != nil then
+      if @celltype.instance_of?( Celltype ) then
+        # celltype に登録（コード生成の対象となる）
+        @celltype.new_cell( @my_clone )
+      end
+    end
+
+    return @my_clone
+  end
+
+  #=== Cell# clone されたセルの内部に持つ名前情報を調整する
+  #name::        string : 親 cell の名前  (cell tComposite cell1 での cell1)
+  #global_name:: string : 親 cell の global_name
+  #join_array::  Join[] : composite の cell の join で、この cell に対応するもの
+  #parent_ct_name:: string : 親セルのセルタイプ名（composite セルタイプ）
+  #  このメソッドはすぐ上の clone_for_composite から呼出され、clone されたセルを整える
+  def set_cloned( name, global_name, namespacePath, join_array, parent_ct_name, region, plugin, locale )
+
+    # debug
+    dbgPrint "cell.set_cloned : global_name: #{global_name}  name: #{name}  @name: #{@name}\n"
+    dbgPrint "set_cloned:  entry_array_max_subscript.len=#{@entry_array_max_subscript.length}\n"
+    @global_name = :"#{global_name}_#{@name}"
+    @name = :"#{name}_#{@name}"
+    @NamespacePath = namespacePath.change_name @name
+    @region = region
+    @plugin = plugin
+    @locale = locale
+
+    @in_composite = false
+    @b_checked = false
+    @f_cloned = true
+
+    # Namespace.new_cell( self )  # mikan namespace 対応
+    region.new_cell( self )  # mikan  namespace に cell を置けないことを仮定
+
+    # join_list : NamedList の clone を作る
+    if @celltype then
+      dbgPrint "set_cloned: #{@celltype.get_name} #{@name} #{region.get_name}\n"
+    end
+    @join_list = @join_list.clone_for_composite( parent_ct_name, name, locale )
+    @referenced_port_list = {}
+
+    @alloc_list = []
+    @require_joined_list = {}
+    @entry_array_max_subscript = @entry_array_max_subscript.dup
+    @cell_list = {}
+    @cell_list2 = []
+
+    # このセルのグローバル名を与える
+    # C_EXP の$id$ 置換はこのセルの名前になる
+    join_array.each { |j|
+      @join_list.change_item j
+    }
+  end
+
+  #=== clone されたセルが composite の場合、内部セルを展開する
+  #self:: clone されたセルでなければならない
+  def expand_inner
+    if ! @f_cloned then
+      raise "expnad_inner: not cloned cell"
+    end
+
+    # clone しようとするセルが composit セルタイプ？
+    if @celltype.instance_of?( CompositeCelltype ) then
+      # composite cell を再帰的に展開
+      @cell_list, @cell_list2 = @celltype.expand( @name, @global_name, @NamespacePath, @join_list, @region, @plugin, @locale )
+    end
+  end
+
+  #=== Cell# clone された cell の join_list の右辺の変更
+  #  呼び口の右辺の cell を他の clone された cell に置換え
+  def change_rhs_port cloned_cell_list
+
+    # debug
+    dbgPrint "=====   Cell#change_rhs_port: name=#{@name}   =====\n"
+
+    @join_list.get_items.each { |j|
+      j.change_rhs_port( cloned_cell_list, @celltype )
+    }
+  end
+
+  def get_f_def
+    @b_defined
+  end
+
+  def get_f_ref
+    if @f_ref then
+      return true
+    else
+      return false
+    end
+  end
+
+  def get_name
+    @name
+  end
+
+  def get_local_name
+    @local_name
+  end
+
+  def get_global_name
+    @global_name
+  end
+
+  def get_region
+    @region
+  end
+
+  def self.get_current
+    @@current_object
+  end
+
+  #=== Cell# 生成されるセルか？
+  # 最適化、コード生成中に、対象となる region に属する場合 true を返す
+  def is_generate?
+    if $generating_region == nil then
+      # 構文解釈、意味解析段階で呼ばれると例外発生
+      raise "is_generate? called before optimizing"
+    end
+
+    # print "Cell#is_generate?: #{@name} #{@region.get_name} #{$generating_region.get_name}\n"
+    if $generating_region == @region.get_link_root then
+      return true
+    else
+      return false
+    end
+  end
+
+  #=== Cell# composite 内部の複製されたセルか？
+  # composite 定義の内部のセル (@in_composite = true) ではない
+  def is_cloned?
+    @f_cloned
+  end
+
+  #=== Cell# composite 内部のセルか？
+  def is_in_composite?
+    @in_composite
+  end
+
+  #=== Cell# composite のセルか？
+  def is_of_composite?
+    if @celltype.kind_of? CompositeCelltype
+      return true
+    else
+      return false
+    end
+  end
+
+  #=== Cell# tmp_plugin_post_code.cdl で生成されたセルか？
+  def post_code_generated?
+    @b_post_code_generated
+  end
+
+  # composite cell の port に対応する内部の cell の port の名前（リンク時に必要な名前）
+  def get_real_global_name port_name
+    if @celltype.instance_of?( CompositeCelltype ) then
+
+      # debug
+      dbgPrint "get_real_global_name: cell name: #{@name} #{@local_name} #{@global_name} #{port_name}\n"
+      @cell_list.each{ |n,c|
+        dbgPrint "   name: #{n}\n"
+        dbgPrint " get_name: #{c.get_name} local_name: #{c.get_local_name}\n"  if c
+        dbgPrint "\n\n"
+      }
+
+      cj = @celltype.find_export( port_name )
+
+      # debug
+      dbgPrint " composite join name: #{cj.get_name}  cell: #{cj.get_cell_name}  cell elem: #{cj.get_cell_elem_name}\n"
+
+      name = @cell_list[ "#{cj.get_cell_name}" ].get_real_global_name( cj.get_cell_elem_name )
+      return name
+
+    else
+      # debug
+      dbgPrint "  get_real_global_name: cell name: #{@global_name}\n"
+
+      return @global_name
+    end
+  end
+
+  #=== Cell# セルの受け口 port_name に対する実際のセル名、受け口名を '_' で連結
+  #    namespace 名 + '_' + セル名 + '_' + 受け口名   （このセルが composite ならば展開後のセル名、受け口名）
+  def get_real_global_port_name port_name
+
+    # composite か？
+    if @celltype.instance_of?( CompositeCelltype ) then
+
+      # debug
+      dbgPrint "get_real_global_port_name: cell name: #{@name} #{@local_name} #{@global_name} #{port_name}\n"
+      @cell_list.each{ |n,c|
+        dbgPrint "   name: #{n}\n"
+        dbgPrint " get_name: #{c.get_name} local_name: #{c.get_local_name}\n"  if c
+        dbgPrint "\n"
+      }
+
+      # セルタイプ内で port_name の CompositeCelltypeJoin を探す（コード生成段階では必ず見つかる）
+      cj = @celltype.find_export( port_name )
+
+      # debug
+      dbgPrint "   composite join name: #{cj.get_name}  cell: #{cj.get_cell_name}  cell elem: #{cj.get_cell_elem_name}\n"
+
+      # composite の内部のセルに対し再帰的に get_real_global_port_name を適用
+      name = @cell_list[ "#{cj.get_cell_name}" ].get_real_global_port_name( cj.get_cell_elem_name )
+      return name
+
+    else
+      # debug
+      dbgPrint "get_real_global_port_name:  cell name: #{@global_name}\n"
+
+      return "#{@global_name}_#{port_name}"
+    end
+  end
+
+  #=== Cell# PORT (celltype の定義) を得る
+  def get_real_port( port_name )
+
+    # composite か？
+    if @celltype.instance_of?( CompositeCelltype ) then
+
+      # セルタイプ内で port_name の CompositeCelltypeJoin を探す（コード生成段階では必ず見つかる）
+      cj = @celltype.find_export( port_name )
+
+      # composite の内部のセルに対し再帰的に get_real_port を適用
+      port = @cell_list[ "#{cj.get_cell_name}" ].get_real_port( cj.get_cell_elem_name )
+      return port
+    else
+
+      return @celltype.find( port_name )
+    end
+  end
+
+  #=== Cell# cell を得る
+  #    composite でなければ自分自身を返す
+  def get_real_cell( port_name )
+
+    # composite か？
+    if @celltype.instance_of?( CompositeCelltype ) then
+
+      # セルタイプ内で port_name の CompositeCelltypeJoin を探す（コード生成段階では必ず見つかる）
+      # print "get_real_cell: cell=#{@name} port=#{port_name}\n"
+      # pp @cell_list
+      cj = @celltype.find_export( port_name )
+
+      # composite の内部のセルに対し再帰的に get_real_port を適用
+      cell = @cell_list[ "#{cj.get_cell_name}" ].get_real_cell( cj.get_cell_elem_name )
+      return cell
+    else
+
+      return self
+    end
+  end
+
+  #=== Cell#get_real_celltype
+  #
+  def get_real_celltype( port_name )
+    if @celltype.instance_of?( CompositeCelltype ) then
+      return @celltype.get_real_celltype port_name
+    else
+      return @celltype
+    end
+  end
+
+  #=== Cell# 受け口のport の参照カウントをアップする
+  #port_name:: Symbol  : ポート名
+  def port_referenced port
+    if @referenced_port_list[ port ] then
+      @referenced_port_list[ port ] += 1
+    else
+      @referenced_port_list[ port ] = 1
+    end
+
+    # composite か？
+    if @celltype.instance_of?( CompositeCelltype ) then
+
+      # セルタイプ内で port_name の CompositeCelltypeJoin を探す（コード生成段階では必ず見つかる）
+      cj = @celltype.find_export( port.get_name )
+
+      dbgPrint " port_referenced: #{@celltype.get_name} #{@name} cj=#{cj&&(cj.get_name)||"nil"}\n"
+
+      if cj then  # 既にエラー
+        # composite の内部のセルに対し再帰的に get_real_port を適用
+        cell = @cell_list[ "#{cj.get_cell_name}" ]
+        if cell && cell.get_celltype then
+          cell.port_referenced( cell.get_celltype.find( cj.get_cell_elem_name ) )
+        end
+      end
+    end
+  end
+
+  def get_internal_port_name port_name
+    if @celltype.instance_of?( CompositeCelltype ) then
+      cj = @celltype.find_export( port_name )
+#      return "#{@name}_#{cj.get_cell.get_internal_port_name cj.get_cell_elem_name}"
+      return cj.get_cell.get_internal_port_name( cj.get_cell_elem_name )
+    else
+
+      # debug
+      dbgPrint "  get_global_port_name: cell port: #{@global_name}_#{port_name}\n"
+
+      return "#{@global_name}_#{port_name}"
+    end
+  end
+
+  #Cell#属性の初期値を得る
+  #attr_name::Symbol  必ず初期化されていないと Ruby 例外となる
+  def get_attr_initializer attr_name
+    val = @join_list.get_item( attr_name )
+    if val == nil then
+      val = (@celltype.find  attr_name).get_initializer
+    else
+      val = val.get_rhs
+    end
+    return val
+  end
+
+  def get_celltype
+    @celltype
+  end
+
+  def get_join_list
+    @join_list
+  end
+
+  def set_id id
+    @id = id
+  end
+
+  def get_id
+    @id
+  end
+
+  def get_plugin
+    @plugin
+  end
+
+  def get_cell_list2
+    list = []
+    @cell_list2.each{ |cell|
+      list << cell
+      list += cell.get_cell_list2
+    }
+    return list
+  end
+
+  #=== Cell# 受け口配列の添数の最大値を設定
+  def set_entry_port_max_subscript( port, num )
+    dbgPrint( "set_entry_port_max_subscript: #{@name}.#{port.get_name}: #{num}\n" )
+    subscript = @entry_array_max_subscript[port]
+
+    if subscript == nil || num > subscript then
+      @entry_array_max_subscript[port] = num
+      set_entry_inner_port_max_subscript( port, num )
+    end
+  end
+
+  #=== Cell# composite の内側セルの受け口配列の添数の最大値を設定
+  def set_entry_inner_port_max_subscript( port, num )
+    if @cell_list == nil then
+      return    # プロトタイプ宣言しかされていなくて、内側セルが展開されていない　or composite 展開前
+    end
+
+    # composite の内側のセルに伝播
+    if @celltype.instance_of? CompositeCelltype then
+      dbgPrint "set_entry_inner_port_max_subscript #{@name} #{@port} #{num} cell_list.len=#{@cell_list.length}\n"
+      # @cell_list.each{ |c, p| print c, p, '\n' }
+
+      cj = @celltype.find_export port.get_name
+      if cj && @cell_list[ cj.get_cell_name.to_s ] then
+        inner_cell = @cell_list[ cj.get_cell_name.to_s ]
+        ct = inner_cell.get_celltype
+        if ct then
+          inner_port = ct.find( cj.get_cell_elem_name )
+          inner_cell.set_entry_port_max_subscript( inner_port, num )
+        end
+      end
+    end
+  end
+
+  #=== Cell# 受け口配列の添数の最大値を返す
+  # 長さは +1 する
+  # 1つもない場合は -1 を返す
+  def get_entry_port_max_subscript( port )
+    subscript = @entry_array_max_subscript[port]
+    if subscript == nil then
+      subscript = -1
+    end
+    return subscript
+  end
+
+  #=== Cell# リレーアロケータの結合を生成
+  # STAGE: S
+  # 呼び口側の結合を元に受け口側の結合を生成
+  def create_relay_allocator_join
+
+    # celltype がなければチェックしない（既にエラー）
+    return if @celltype == nil
+
+    # relay allocator を生成
+    @celltype.get_port_list.each { |p|
+      ail = p.get_allocator_instance
+      if ail then
+        dbgPrint "create_relay_allocator_join: #{@name}, #{p.get_name}\n"
+        if p.get_array_size then
+          # mikan relay allocator が array に対応できてもよいのでは？
+          cdl_error( "S1040 array not supported for relay allocator"  )
+          next
+        end
+        ail.each{ |name,ai2|
+          # ai2 = [ :INTERNAL_ALLOC|:RELAY_ALLOC, func_name, param_name, rhs_cp_name, rhs_func_name, rhs_param_name ]
+          if ai2[0] == :RELAY_ALLOC then
+            dbgPrint "create_relay_allocator_join: #{@name}, #{name}\n"
+            # 呼び口側の結合を取り出す
+            ja = @join_list.get_item( :"#{ai2[3]}_#{ai2[4]}_#{ai2[5]}" )
+            if ja == nil then
+              # 見つからない場合
+              found = false
+              
+              # composite 内で外部に結合されているか
+              if @in_composite then
+                @compositecelltypejoin_list.get_items.each { |cj|
+                  dbgPrint( "create relay_allocator in_composite\n" )
+                  dbgPrint("    #{cj.get_cell_name} #{@name} #{cj.get_cell_elem_name} #{ai2[3]}_#{ai2[4]}_#{ai2[5]}\n")
+                  if cj.get_cell_name == @name &&
+                      cj.get_cell_elem_name == :"#{ai2[3]}_#{ai2[4]}_#{ai2[5]}" then
+                    found = true
+                    dbgPrint "create_relay_allocator: found #{cj.get_cell_elem_name}\n"
+                    break
+                  end
+                }
+              end
+
+              if found == false then
+                cdl_error( "S1041 \'$1_$2_$3\': not joined. cannot create internal join for relay allocator" , ai2[3], ai2[4], ai2[5] )
+                print( "      In cell #{get_name}\n" )
+                # join が未結合であることのエラーは二度でる (S1043)
+              end
+              next    # 打ち切る
+            end
+
+            b_export = false
+            # composite 内のセルでエクスポートされているかチェック
+            #  mikan エクスポート側と、こちら側で、リレー先が一致するかチェックが必要
+            if @compositecelltypejoin_list then
+              # export されているか調べる
+              @compositecelltypejoin_list.get_items.each{ |cj|
+                # 属性名と composite の export する名前は一致するか
+                if p.get_name == cj.get_cell_elem_name then
+                  print "export : #{p.get_name}\n"
+                  b_export = true    # 属性は export されているので、とりあえず未初期化とはしない
+                  break
+                end
+              }
+              # 
+            end
+
+            # mikan 配列
+            am = nil
+            if am then
+              am.each{ |ja2|
+                rhs = ja2.get_rhs
+                subscript = ja2.get_subscript
+                if b_export == false then
+                  # CompositeCelltype の場合、内側のセルで生成させる
+                  join = Join.new( :"#{p.get_name}_#{ai2[1]}_#{ai2[2]}", subscript, rhs, @loacle )
+                  # p ( "#{p.get_name}_#{ai2[1]}_#{ai2[2]}", subscript, rhs )
+                  new_join( join )
+                  join.set_definition( @celltype.find(join.get_name) )
+                  # mikan relay mismatch チェックができていない（下方を参照）
+                end
+                @alloc_list << [ :NORMAL_ALLOC, p.get_name, subscript, ai2[1], ai2[2], rhs ]
+              }
+            else
+              if b_export == false then
+                # CompositeCelltype の場合、内側のセルで生成させる
+                join = Join.new( :"#{p.get_name}_#{ai2[1]}_#{ai2[2]}", nil, ja.get_rhs, @locale )
+                new_join( join )
+                join.set_definition( @celltype.find(join.get_name) )
+                if @celltype.instance_of? CompositeCelltype then
+                  jr = @join_list.get_item( :"#{ai2[3]}_#{ai2[4]}_#{ai2[5]}" )
+                  if jr.get_rhs_cell2 != join.get_rhs_cell2 || jr.get_rhs_port2 != join.get_rhs_port2 then
+                    cdl_error( "S1167 \'$1\': relay mismatch \'$2\'",
+                                      "#{p.get_name}_#{ai2[1]}_#{ai2[2]}",
+                                      "#{ai2[3]}_#{ai2[4]}_#{ai2[5]}" )
+                    # 本当は composite の呼び口と受け口の間で行うべきだが、内部で多段接続されている場合
+                  else
+                    dbgPrint "relay success:  #{p.get_name}_#{ai2[1]}_#{ai2[2]}=>#{ai2[3]}_#{ai2[4]}_#{ai2[5]} #{jr.get_rhs_cell2.get_name}.#{jr.get_rhs_port2} \n"
+                  end
+                end
+              end
+              @alloc_list << [ :NORMAL_ALLOC, p.get_name, nil, ai2[1], ai2[2], ja.get_rhs ]
+            end
+            dbgPrint "create_relay_allocator_join: #{p.get_name}_#{ai2[1]}_#{ai2[2]} #{ai2[3]}_#{ai2[4]}_#{ai2[5]}\n"
+          end
+        }
+      end
+    }
+  end
+
+  #=== Cell# @@cell_list2 を作る
+  # @@cell_list2 は、出現順に composite 内を含むセルのリスト
+  def self.make_cell_list2
+    @@cell_list.each{ |c|
+      @@cell_list2 << c
+      @@cell_list2 += c.get_cell_list2
+    }
+  end
+
+  #=== Cell# @@cell_list2 を得る
+  # composite 内を含む (compositeも含む)
+  # 意味解析後に作成される
+  def self.get_cell_list2
+    @@cell_list2
+  end
+
+  #=== Cell# @@cell_list を得る
+  #composite の中を含まない
+  def self.get_cell_list
+    @@cell_list
+  end
+
+  #=== Cell# reverse_join を生成する
+  def self.create_reverse_join
+    @@cell_list.each{ |c|
+      ct = c.get_celltype
+      # if c.is_generate? then
+      if ct then
+        c.create_reverse_join
+      end
+      # end
+    }
+  end
+
+  #=== Cell# reverse_require_join を生成する
+  def self.create_reverse_require_join
+    @@cell_list2.each{ |c|
+      ct = c.get_celltype
+      # if c.is_generate? then
+        if ct then
+          # self への呼び口側の結合を生成
+          ct.create_reverse_require_join c
+        end
+      # end
+    }
+  end
+
+  #=== Cell# 受け口のport の参照カウントを設定する
+  # self は呼び元のセル
+  # 呼び先セルの受け口の参照カウントをアップする
+  def set_port_reference_count
+    @join_list.get_items.each { |j|
+      if j.get_definition.instance_of? Port then
+        am = j.get_array_member2
+        if am then             # 呼び口配列
+          am.each { |j2|
+            next if j2 == nil    # optional で一部が欠落しているケース
+            cell = j2.get_rhs_cell2
+            next if cell == nil     # 右辺が見つからなかった．既にエラー
+            port = cell.get_celltype.find( j2.get_rhs_port2 )
+            dbgPrint( "set_port_reference_count: #{@name}.#{j2.get_name} => #{cell.get_name}.#{port.get_name}\n")
+            cell.port_referenced port
+          }
+        else
+          cell = j.get_rhs_cell2
+          next if cell == nil || cell.get_celltype == nil     # 右辺が見つからなかった．既にエラー
+          port = cell.get_celltype.find( j.get_rhs_port2 )
+          if port == nil then
+            dbgPrint "set_port_ref: #{@name}.#{j.get_name} = #{cell.get_name}.#{j.get_rhs_port2}\n"
+            # through プラグインで生成されたセルの受け口が見つからないケース (のハズ)
+            cdl_error( "entry '$1' not found in '$2' refered from $3.$4", j.get_rhs_port2, cell.get_name, @name, j.get_name )
+            next
+          end
+          dbgPrint( "set_port_reference_count: #{@name}.#{j.get_name} => #{cell.get_name}.#{port.get_name}\n")
+          cell.port_referenced port
+        end
+      end
+    }
+  end
+
+  #=== Cell# 結合(Join)のチェック
+  #     Join は呼び口の結合または attribute の初期化
+  #
+  #  mikan このメソッドは、以下の４つのチェックからなるが、分割したほうがより適切な長さのメソッドになる
+  #  ・リレーアロケータの生成 => create_relay_allocator_join
+  #  ・未結合の呼び口のチェック
+  #  ・ポインタ型が配列で初期化される場合のチェック
+  #  ・未初期化の属性のチェック
+  def check_join
+
+    # celltype がなければチェックしない（既にエラー）
+    return if @celltype == nil
+    return if @b_defined == false
+    return if @f_cloned == true    # 内部セルについては、composite の定義時にチェックされている
+
+    # debug
+    # if @compositecelltypejoin_list then
+    #   p "check_join"
+    #   @compositecelltypejoin_list.get_items.each { |cj| p "#{cj.get_name} #{cj.get_name.object_id}" }
+    # end
+
+    # 未結合の呼び口のチェック
+    @celltype.get_port_list.each { |p|
+
+      # 呼び口でなければ、チェックしない
+      next if p.get_port_type != :CALL
+
+      # debug
+      dbgPrint "check_join: #{@name} #{get_celltype.get_name} #{p.get_name}\n"
+
+      # 結合リストの中から呼び口名に一致するものを取りだす
+      j = @join_list.get_item( p.get_name )
+
+      if j == nil then
+        # 未結合の呼び口
+
+        # composite celltype の内部の場合、composite celltype が export する呼び口に結合されているか探す
+        found = false
+        if @in_composite then
+          # composite celltype の export するものすべてから探す
+          # （export するものの右辺値から探すために get_item ではダメ）
+          @compositecelltypejoin_list.get_items.each{ |cj|
+            # 呼び口名と composite の export する名前は一致するか
+            if p.get_name == cj.get_cell_elem_name then
+              found = true
+            end
+          }
+        end
+
+        # 呼び口配列の場合 optional で全ての要素が初期化されない場合に、ここへ来る
+        if ! found && ! p.is_require? && ! p.is_optional? then
+          if ! p.is_allocator_port? then
+            cdl_error( "S1042 call port \'$1\' not initialized in cell \'$2\'" , p.get_name, @name )
+          else
+            cdl_error( "S1043 call port \'$1\' not initialized in cell \'$2\'. this call port is created by tecsgen. check allocator specifier" , p.get_name, @name )
+          end
+        end
+      elsif p.get_array_size.kind_of? Integer then
+        # 添数あり呼び口配列の場合、すべての添数要素が初期化されているかチェックする
+
+        am = j.get_array_member2
+        if( am )then
+          # join は配列
+
+          # 呼び口配列定義での配列の大きさ
+          length = p.get_array_size
+
+          # 配列の大きさが呼び口配列定義と結合定義で一致するか？
+          if am.length != length then
+            if ! p.is_optional? || am.length >= length then
+              # optional の場合、要素数が少なすぎるのは OK
+              cdl_error( "S1044 $1: array initializer too many or few, $2 for $3" , p.get_name, am.length, length )
+            end
+
+            # am の要素に nil を追加しておく (#_CPA_# のコード生成時、この配列要素数分生成)
+            i = am.length
+            while i < length
+              am << nil
+              i += 1
+            end
+          end
+
+#          # 配列要素の抜けがないかチェック
+#          if am.length < length then  # 満たない場合既にエラーだが要素のある範囲でチェック
+#            length = am.length
+#          end
+          i = 0
+          while( i < length )
+            if am[i] == nil then
+              if ! p.is_optional? then
+                cdl_error( "S1045 $1[$2]: not initialized" , p.get_name, i )
+              end
+            else
+              # 生成されないリージョンへの結合かチェック
+              if ! @in_composite then
+                am[i].check_region2
+              end
+            end
+            i += 1
+          end
+
+        # else
+        # join が非配列であれば、既にエラー
+        end
+      elsif j.get_array_member then
+        # 添数なし呼び口配列の場合
+        am = j.get_array_member2
+        length = am.length
+        i = 0
+        while i < length
+          if am[i] == nil then
+            if ! p.is_optional? then
+              cdl_error( "S1046 $1[$2]: not initialized" , p.get_name, i )
+            end
+          end
+          i += 1
+        end
+
+        # 生成されないリージョンへの結合かチェック
+        if ! @in_composite then
+          am.each { |join|
+            if join then
+              join.check_region2
+            end
+          }
+        end
+      else
+        # 呼び口［配列」でない場合
+
+        # 生成されないリージョンへの結合かチェック
+        if ! @in_composite then
+          j.check_region2
+        end
+
+      end # j != nil
+    }
+
+    # ポインタ型が配列で初期化される場合のチェック
+    (@celltype.get_attribute_list+@celltype.get_var_list).each { |a|
+      if a.get_size_is then
+
+        if a.instance_of? CompositeCelltypeJoin then
+          # 既にエラーになっている
+          # cdl_error( "S1047 size_is pointer cannot be exposed for composite attribute"  )
+          next
+        end
+
+        if( ! a.get_type.kind_of?( PtrType ) ) then
+          cdl_error( "S1048 $1: size_is specified for non-pointer type" , a.get_name )
+        else
+          size = a.get_size_is.eval_const( @join_list, @celltype.get_name_list )
+          a.get_type.set_scs( a.get_size_is, nil, nil, nil, false )
+          if( ! size.kind_of? Integer )then               # C_EXP の可能性あり
+            # mikan 多分ここでのエラー発生は不要、eval_const の中で変数が存在しない、型が不適切などのエラーになるはず
+            cdl_error( "S1049 $1: size_is arg not constant" , a.get_name )
+          else
+            j = @join_list.get_item( a.get_identifier )
+            if j then
+              ini = j.get_rhs
+              if ini then
+                if ! ini.instance_of?( Array ) then
+                  cdl_error( "S1050 unsuitable initializer, need array initializer"  )
+                elsif size < ini.length then
+                  cdl_error( "S1051 too many initializer for array, $1 for $2" , ini.length, size )
+                else
+                  # a.get_type.set_scs( a.get_size_is, nil, nil )
+                end
+              end
+            else
+              # size_is 引数がセルで指定されていて、初期化子がセルタイプで指定されているケースのチェック
+              ini = a.get_initializer
+              if ini.instance_of? Expression
+                ini = ini.eval_const( @celltype.get_name_list )
+              end
+              if ini.instance_of? Array then
+                if( ini.length > size )then
+                  cdl_error( "S1168 too many initializer for array, $1 for $2", ini.length, size )
+                end
+              end
+            end
+          end
+        end
+      else
+        if ! a.instance_of? CompositeCelltypeJoin then
+          # composite は size_is 指定できない
+          if a.get_type.kind_of?( PtrType ) then
+            j = @join_list.get_item( a.get_identifier )
+            if j && j.get_rhs.instance_of?( Array ) then
+              ## size_is 指定されていないポインタが Array で初期化されていたら、エラーとする
+              cdl_error( "S1169 $1: non-size_is pointer cannot be initialized with array initializer" , a.get_identifier )
+            end
+          end
+        end
+      end
+    }
+
+    # 未初期化の属性をチェック
+    @celltype.get_attribute_list.each { |a|
+      b_init = false
+      # self.show_tree 1
+      if a.get_initializer then                               # セルタイプで初期化されている
+        b_init = true
+        # @in_composite で export されている場合には、この初期値は使われない
+        # export されている、いないに関わらず、初期化されていることが保証される
+      elsif @join_list.get_item( a.get_name ) then            # セルで初期化されている
+        b_init = true
+      elsif @in_composite && @compositecelltypejoin_list then
+        # 属性が export されているか調べる。export されていれば未初期化とはしない
+        # mikan リニアサーチ
+        @compositecelltypejoin_list.get_items.each{ |cj|
+          # 属性名と composite の export する名前は一致するか
+          if a.get_name.to_sym == cj.get_cell_elem_name.to_sym then
+            b_init = true    # 属性は export されているので、とりあえず未初期化とはしない
+          end
+        }
+        if b_init then
+          # size_is の引数がマッチするかチェックする
+          # 内部セルの size_is をエクスポートする size_is とマッチするかチェックする
+          # 内部セルとエクスポートで名前を変えている可能性があるので、内部セルの size_is の名前を変換した上でチェックする
+          if a.get_size_is then
+            ### p "attr: get_size_is"
+            cj = @compositecelltypejoin_list.get_item a.get_name.to_sym
+            if cj.get_port_decl.instance_of? Decl then
+              ### p "attr: get_size_is 2"
+              # cj_size_is は、外部公開される attr の size_is
+              cj_size_is = cj.get_port_decl.get_size_is
+              if cj_size_is == nil then
+                cdl_error( "S1170 \'$1\' has size_is but export attr \'$2\' doesn't have", a.get_name, cj.get_name )
+              end
+              exprs = a.get_size_is.to_s
+              ### p "exprs : ", exprs
+              remain = exprs
+              inner_to_export = {}
+			  ### exprs に含まれる識別子を抜き出し、対応する export される名前を探す
+              while remain != "" && remain != nil
+                ### p "remain ", remain
+                remain =~ /([^\w]*)([_A-Za-z][\w\d]*)/   # 変数名文字列を取り出す 
+				if $2 == nil then
+						break
+				end
+                arg_name = $2.to_sym
+                remain = $'
+                ### p exprs, $1, $2, $'
+                # size_is に含まれる変数は、composite で export されているか
+                cj2 = nil
+                @compositecelltypejoin_list.get_items.each{ |cj2t|
+                  if cj2t.get_cell_elem_name == arg_name then
+                    cj2 = cj2t
+                  end
+                }
+                if cj2 == nil then
+                  cdl_error( "S1171 \'$1\' size_is argument of \'$2\' not exported", a.get_name, cj.get_name )
+                  next
+                end
+                if cj2.get_port_decl.instance_of? Decl then
+                   decl2 = cj2.get_port_decl
+                   # 内部の名前と外部の名前の対応関係を記憶
+                   inner_to_export[arg_name] = decl2.get_name
+                # else cj2 は Port (既にエラー)
+                end
+              end
+              # 内部の名前を外部の名前で置換
+              inner_to_export.each{ |arg_name, exp_name|
+                ### p "changing #{arg_name}=>#{exp_name}"
+                # exprs.gsub!( Regexp.new("#{arg_name}[^0-9A-Za-z_]"), exp_name.to_s )
+                exprs.gsub!( Regexp.new("#{arg_name}(\\W)"), exp_name.to_s+"\\1" )  # 文字列末尾にないケース
+                exprs.gsub!( Regexp.new("#{arg_name}\\Z"), exp_name.to_s )          # 文字列末尾にあるケース
+              }
+              ### p "changed: #{exprs} #{cj_size_is.to_s}"
+              if exprs != cj_size_is.to_s then
+                cdl_error( "S1172 \'$1\' size_is argument mismatch with exporting one \'$2\'", a.get_name, cj.get_name )
+              end
+            # else cj は Port (既にエラー)
+            end
+          end
+        end    
+      end
+
+      if b_init == false then
+          cdl_error( "S1052 attribute \'$1\' not initialized in cell \'$2\'" , a.get_name, @name )
+      end
+   
+    }
+  end
+
+  #=== Cell# 逆 require をチェックする
+  # 逆 require 指定された受け口に複数の結合がないかチェックする
+  # composite の内部セル (f_cloned=true) もチェックする
+  def check_reverse_require
+    # celltype がなければチェックしない（既にエラー）
+    return if @celltype == nil
+    return if @b_defined == false
+
+    # p "check reverse require   #{@name}"
+    # 逆require 指定された受け口に複数の結合がないかチェック
+    @referenced_port_list.each{ |port,count|
+      # p port.class, count
+      # p port.get_name, port.get_port_type, port.get_signature.get_name
+      if port.is_reverse_required? && count > 1 then
+        cdl_warning( "W1009 $1: fixed join entry port has multi join", port.get_name )
+      end
+    }
+  end
+
+  #=== Cell# require 呼び口の結合を行う
+  # STAGE: S
+  #cp_name:: Symbol           : 呼び口名
+  #cell_or_t:: Celltype|Cell  : celltype の require の右辺で指定されたセルタイプまたはセル
+  #port::  Port               : celltype の Port オブジェクト
+  def set_require_join( cp_name, cell_or_ct, port )
+
+    # set_require_join は2度呼び出される
+    # 2度目は post コードを生成した後       #####  いったん見合わせ（重複エラーを見逃す）
+    # if @require_joined_list[ cp_name ] then
+    #   return
+    # else
+    #   @require_joined_list[ cp_name ] = true
+    # end
+
+    dbgPrint "set_require_join: #{@name}.#{cp_name} = #{cell_or_ct.get_name}.#{port.get_name}\n"
+
+    if cell_or_ct.instance_of? Celltype then
+      # print "DOMAIN: not considered\n"
+      cell = cell_or_ct.get_singleton_cell @region
+      if cell == nil then
+        cdl_error( "S1025 not found reachable cell for require \'$1\' in celltype \'$2\'" , port.get_name, cell_or_ct.get_name )
+        return
+      end
+    else
+      # require: cell で指定
+      cell = cell_or_ct
+      if @region.distance( cell.get_region ) == nil then
+        cdl_error( "S1026 required cell \'$1\' not reachable" , cell.get_name )
+      end
+    end
+
+    if @join_list.get_item( cp_name ) then
+      cdl_warning( "W1003 $1 : require call port overridden in $2" , cp_name, @name )
+    else
+      # require の join を生成(呼び口の結合)
+#      rhs = Expression.new( [ :OP_DOT, [ :IDENTIFIER, Token.new( cell.get_name, nil, nil, nil ) ],
+      nsp = NamespacePath.new( cell.get_name, false, cell.get_namespace )
+      nsp.set_locale @locale
+      rhs = Expression.new( [ :OP_DOT, [ :IDENTIFIER, nsp ],
+                              Token.new( port.get_name, nil, nil, nil ) ], @locale )   #1
+      join = Join.new( cp_name, nil, rhs, @locale )
+      self.new_join( join )
+
+      join.set_definition( @celltype.find(join.get_name) )
+    end
+  end
+
+  #=== Cell# Join の definition の設定とチェック
+  # STAGE: S
+  def set_definition_join
+    return if @celltype == nil    # 既にエラー：打ち切る
+    return if @b_defined == false # プロトタイプ宣言のみ
+    return if @b_checked == true  # 既に設定（チェック）済み
+
+    dbgPrint "set_definition_join in #{@name}\n"
+
+    # relay allocator をたどって再入しないよう、先頭で @b_checked を true にする
+    @b_checked = true
+
+    if ! @f_cloned then
+      check_restrict_list
+      
+      # compoiste セルのクローンされたものは、set_definition 不要
+      # 元の join は既に definition されている
+      # 元のセルにおいて、代入チェックされているので、二重にチェック(through適用)されてしまう
+      @join_list.get_items.each{ |join|
+        dbgPrint " set_definition_join: checking #{@name}.#{join.get_name}\n"
+        if join.get_array_member then
+          port = @celltype.find(join.get_name)
+          join.get_array_member2.each { |am|
+            if am == nil then   # 未結合の場合、エラーチェックは check_join
+              if port && ! port.is_optional? then
+                # テスト用にエラーメッセージ出力
+                # cdl_error( "TEMPORAL set_definition_join: uninitialized array member"  )
+              end
+              next
+            end
+            am.set_definition( port )
+          }
+        else
+          dbgPrint "set_definition_join: #{@name}.#{join.get_name} celltype=#{@celltype.get_name}\n"
+          join.set_definition( @celltype.find(join.get_name) )
+        end
+      }
+    end
+
+    # リレー join は through プラグイン生成後にしかできない
+    # through 後に結合先が入れ替えられる 
+    create_relay_allocator_join
+
+    # composite セルの展開
+    if ! @in_composite && ! @f_cloned && @celltype.instance_of?( CompositeCelltype ) then
+      # composite セルタイプ内の composite は展開しない
+      # compoiste セル展開中の composite は展開しない (CompositeCelltype::expand 内で再帰的に expnad)
+      expand
+    end
+  end
+
+  #=== Cell# composite セルの展開
+  # このセルが composite セルタイプ
+  def expand
+
+    #debug
+    dbgPrint "=====    expanding   #{@name}     =====\n"
+
+    # composite celltype の cell を展開
+    @cell_list, @cell_list2 = @celltype.expand( @name, @global_name, @NamespacePath, @join_list, @region, @plugin, @locale )
+
+    # プロトタイプが参照されている場合、子も参照されていることにする
+    if @f_ref then
+      dbgPrint "expand: set_f_ref\n"
+      set_f_ref
+    end
+  end
+
+  #=== Cell#内部セルの受け口添数最大値を設定
+  def set_max_entry_port_inner_cell
+    if @cell_list == nil then
+      return
+    end
+
+    dbgPrint "set_max_entry_port_inner_cell name=#{@name} entry_array_max_subscript.len=#{@entry_array_max_subscript.length}\n"
+
+    # プロトタイプ宣言で設定されていたものを反映する
+    @entry_array_max_subscript.each{ |port,name|
+      dbgPrint "set_entry_inner_port_max_subscript( #{port}, #{name} )\n"
+      set_entry_inner_port_max_subscript( port, name )
+    }
+  end
+
+  #=== Cell#restrict を追加
+  def add_restrict( entry_name, func_name, region_name_list )
+    if @restrict_list[ entry_name ] == nil then
+      @restrict_list[ entry_name ] = {}
+      @restrict_list2[ entry_name ] = {}
+    end
+    if @restrict_list[ entry_name ][ func_name ] == nil then
+      @restrict_list[ entry_name ][ func_name ] = []
+      @restrict_list2[ entry_name ][ func_name ] = []
+    end
+    region_name_list.each { |rp|
+      @restrict_list[ entry_name ][ func_name ] << rp
+      # p "Class: " + rp.to_s
+      obj = Namespace.find rp
+      if ( obj.kind_of? Region ) then
+        @restrict_list2[ entry_name ][ func_name ] << obj.get_domain_root
+      else
+        cdl_error( "S9999 $1 not found or not region", rp.to_s )
+      end
+    }
+  end
+
+  #=== Cell#check_restrict_list
+  def check_restrict_list
+    # p "check_restrict_list"
+    @restrict_list.each{ |entry_name, func_hash|
+      func_hash.each{ |func_name, region_list|
+        region_list.each{ |rp|
+          obj = Namespace.find rp
+          if ( obj.kind_of? Region ) then
+            if obj.get_domain_root != @region.get_domain_root then
+            else
+              cdl_info( "I9999 $1: restrict calling domain to $2, which is same domain as the cell locates", @name, rp.to_s )
+              # restrict を同じドメインを指定してもよいこととする (HRP3)
+              # KernelDoamin 内のセルに対し、KernelDomain に restrict している場合、
+              # 無所属経由で結合されているが、KernelDomain から呼出すことを想定した許可
+            end
+          else
+            cdl_error( "S9999 $1 not region", rp.to_s )
+          end
+        }
+      }
+    }
+  end
+
+  #=== Cell#callable?
+  def callable?( callee_cell, entry_name, func_name )
+    # p "callable? #{@name}"
+    res = callee_cell.callable_from?( entry_name, func_name, self )
+    dbgPrint "callable? #{callee_cell.get_namespace_path}.#{entry_name}.#{func_name} from #{@NamespacePath} is #{res}\n"
+    return res
+  end
+
+  #=== Cell#callable_from? (private)
+  def callable_from?( entry_name, func_name, caller_cell )
+    @b_restrict_referenced = true
+    if @restrict_list.length == 0 then
+      return true
+    end
+
+    dr = caller_cell.get_region.get_domain_root
+    if @restrict_list[entry_name] then
+      if @restrict_list[entry_name][func_name] then
+        @restrict_list2[entry_name][func_name].each{ |region|
+          if dr == region then
+            return true
+          end
+        }
+      elsif @restrict_list[entry_name][nil] then
+        @restrict_list2[entry_name][nil].each{ |region|
+          if dr == region then
+            return true
+          end
+        }
+      else
+        return false
+      end
+    else
+      return false
+    end
+  end
+
+  #=== Cell#get_callable_regions( entry_name, func_name )
+  # func_name=nil の場合、entry_name の可否をチェック数る
+  # nil が返る場合、制限されていないことを意味する
+  def get_restricted_regions( entry_name, func_name )
+    # p "get_restricted_regions #{@name}"
+    @b_restrict_referenced = true
+    if @restrict_list[entry_name] then
+      if @restrict_list[entry_name][func_name] then
+        return @restrict_list2[entry_name][func_name]
+      else
+        return @restrict_list2[entry_name][nil]
+      end
+    end
+    return nil
+  end
+
+  #=== Cell#has_ineffective_restrict_specifier
+  # restrict 指定子が指定されていて、参照されていない場合 true
+  # 参照は、HRPSVCPlugin のみ
+  def has_ineffective_restrict_specifier
+    if @restrict_list.length != 0 && @b_restrict_referenced == false then
+      return true
+    else
+      return false
+    end
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "Cell: name: #{@name} in_composite: #{@in_composite} def: #{@b_defined} ref: #{@f_ref} cloned: #{@f_cloned}"
+    (indent+1).times { print "  " }
+    puts "Cell locale: #{@name}@#{@locale[0]}##{@locale[1]}"
+    (indent+1).times { print "  " }
+    puts "id: #{@id}  global_name: #{@global_name}  region: #{@region.get_name} plugin: #{@plugin.class.name} #{self}"
+    (indent+1).times { print "  " }
+    puts "namespace_path: #{@NamespacePath}"
+
+    if @celltype then
+      (indent+1).times { print "  " }
+      puts "celltype: #{@celltype.get_name}"
+    end
+    @join_list.show_tree( indent + 1 )
+    @entry_array_max_subscript.each{ |port, num|
+      (indent+1).times { print "  " }
+      puts "entry array #{port.get_name}: max subscript=#{num}"
+    }
+    if @cell_list then   # ここで @cell_list が nil なのは Bug
+      (indent+1).times { print "  " }
+      puts "cloned cell list:"
+      @cell_list.each { |n,c|
+        (indent+2).times { print "  " }
+        puts "inner cell : #{n} = #{c.get_name}"
+      }
+    end
+    if @compositecelltypejoin_list then
+      @compositecelltypejoin_list.get_items.each{ |cj|
+        cj.show_tree( indent+1 )
+      }
+    end
+    if @alloc_list.length > 0 then
+      (indent+1).times { print "  " }
+      puts "allocator list: "
+      @alloc_list.each { |a|
+        cp_name = :"#{a[0+1]}_#{a[2+1]}_#{a[3+1]}"
+        if a[1+1] then
+          # subscript = "[#{a[1+1].eval_const nil}]"
+          subscript = "[#{a[1+1]}]"
+        else
+          subscript = ""
+        end
+        # アロケータ呼び口の結合を生成
+        (indent+2).times { print "  " }
+        puts "#{cp_name}#{subscript} = #{a[4+1]}"
+      }
+    end
+    @referenced_port_list.each{ |port,count|
+      (indent+1).times { print "  " }
+      puts( "#{port.get_name} : #{count} times referenced" )
+    }
+  end
+
+end
+
+class CompositeCelltype < NSBDNode # < Nestable
+# @name:: str
+# @global_name:: str
+# @cell_list_in_composite:: NamedList   Cell
+# @cell_list::Array :: [ Cell ] : cell of CompositeCelltype's cell
+# @export_name_list:: NamedList : CompositeCelltypeJoin
+# @port_list:: CompositeCelltypeJoin[]
+# @attr_list:: CompositeCelltypeJoin[]
+# @b_singleton:: bool : 'singleton' specified
+# @b_active:: bool : 'active' specified
+# @real_singleton:: bool : has singleton cell in this composite celltype
+# @real_active:: bool : has active cell in this composite celltype
+# @name_list:: NamedList item: Decl (attribute), Port エクスポート定義
+# @internal_allocator_list:: [ [cell, internal_cp_name, port_name, func_name, param_name, ext_alloc_ent], ... ]
+# @generate:: [ Symbol, String, Plugin ]  = [ PluginName, option, Plugin ] Plugin は生成後に追加される
+# @generate_list:: [ [ Symbol, String, Plugin ], ... ]   generate 文で追加された generate
+
+  @@nest_stack_index = -1
+  @@nest_stack = []
+  @@current_object = nil
+
+  include CelltypePluginModule
+  include PluginModule
+
+  def self.push
+    @@nest_stack_index += 1
+    @@nest_stack[ @@nest_stack_index ] = @@current_object
+    @@current_object = nil
+  end
+
+  def self.pop
+    @@current_object = @@nest_stack[ @@nest_stack_index ]
+    @@nest_stack_index -= 1
+    if @@nest_stack_index < -1 then
+      raise "TooManyRestore"
+    end
+  end
+
+  def initialize( name )
+    super()
+    @name = name
+    @cell_list_in_composite = NamedList.new( nil, "in composite celltype #{name}" )
+    @cell_list = []
+    @export_name_list = NamedList.new( nil, "export in composite celltype #{name}" )
+    @name_list = NamedList.new( nil, "in composite celltype #{name}" )
+    @@current_object = self
+
+    @b_singleton = false
+    @real_singleton = nil
+    @b_active = false
+    @real_active = nil
+    if "#{Namespace.get_global_name}" == "" then
+      @global_name = @name
+    else
+      @global_name = :"#{Namespace.get_global_name}_#{@name}"
+    end
+
+    Namespace.new_compositecelltype( self )
+    set_namespace_path # @NamespacePath の設定
+
+    @port_list = []
+    @attr_list = []
+    @internal_allocator_list = []
+    @generate_list = []
+    set_specifier_list( Generator.get_statement_specifier )
+  end
+
+  def self.end_of_parse
+    @@current_object.end_of_parse
+    @@current_object = nil
+  end
+
+  # CompositeCelltype#end_of_parse
+  def end_of_parse
+    # singleton に関するチェック
+    if @b_singleton && @real_singleton == nil then
+      cdl_warning( "W1004 $1 : specified singleton but has no singleton in this celltype" , @name )
+    elsif ! @b_singleton && @real_singleton != nil then
+      if ! @b_singleton then
+        cdl_error( "S1053 $1 must be singleton. inner cell \'$2\' is singleton" , @name, @real_singleton.get_name )
+      end
+    end
+
+    # active に関するチェック
+    if @b_active && @real_active == nil then
+      cdl_error( "S1054 $1 : specified active but has no active in this celltype" , @name )
+    elsif ! @b_active && @real_active != nil then
+      cdl_error( "S1055 $1 must be active. inner cell \'$2\' is active" , @name, @real_active.get_name )
+    end
+
+    # @allocator_instance を設定する
+    @name_list.get_items.each{ |n|
+      if n.instance_of? Port then
+        n.set_allocator_instance
+      end
+    }
+
+    # リレーアロケータの entry 側
+    @port_list.each{ |p|
+      if p.get_port_type == :ENTRY then
+        if p.get_allocator_instance == nil then
+          next
+        end
+
+        p.get_allocator_instance.each{ |name,ai|
+          if ai[0] == :RELAY_ALLOC then
+            self.new_join( :"#{p.get_name}_#{ai[4]}_#{ai[5]}", p.get_cell_name, :"#{p.get_cell_elem_name}_#{ai[4]}_#{ai[5]}", :CALL )
+          end
+        }
+      end
+    }
+    # mikan relay が正しく抜けているかチェックされていない
+
+    # callback 結合
+    @cell_list_in_composite.get_items.each{ |c|
+      ct = c.get_celltype
+      if ct then
+        c.create_reverse_join
+      end
+    }
+
+    # 意味解析
+    @cell_list_in_composite.get_items.each{ |c|
+      c.set_definition_join
+    }
+
+    # cell の未結合の呼び口がないかチェック
+    @cell_list_in_composite.get_items.each{ |c|
+      c.check_join
+      c.check_reverse_require
+    }
+
+    # 呼び口の結合について、export と内部結合の両方がないかチェック
+    # リレーアロケータ、内部アロケータの設定
+    @port_list.each{ |p|
+      p.check_dup_init
+    }
+
+    # すべてのエクスポート定義に対応した呼び口、受け口、属性が存在するかチェック
+    @name_list.get_items.each{ |n|
+      if( @export_name_list.get_item( n.get_name ) == nil )then
+        cdl_error( "S1056 $1 : cannot export, nothing designated" , n.get_name )
+      end
+    }
+
+    # 内部アロケータを設定する
+    @internal_allocator_list.each{ |cell, cp_internal_name, port_name, fd_name, par_name, ext_alloc_ent|
+      res = ext_alloc_ent.get_allocator_rhs_elements( :INTERNAL_ALLOC )
+      ep_name = res[0]
+      cj = @export_name_list.get_item( ep_name )
+      internal_alloc_name_from_port_def = cj.get_cell_name
+      internal_alloc_ep_name_from_port_def = cj.get_cell_elem_name
+
+      # puts "internal_allocator #{cell.get_name} #{cp_internal_name} #{port_name}.#{fd_name}.#{par_name}"
+      cell.get_allocator_list.each{ |a|
+        # puts "allocator_list of #{cell.get_name} #{a[0]} #{a[1]}.#{a[2]}.#{a[3]}.#{a[4]} #{a[5].to_s}"
+        if cp_internal_name == :"#{a[1]}_#{a[3]}_#{a[4]}" then
+          dbgPrint "internal_allocator {cp_internal_name} #{a[1]}_#{a[3]}_#{a[4]}\n"
+          dbgPrint "internal_allocator: #{a[5]}, #{internal_alloc_name_from_port_def}.#{internal_alloc_ep_name_from_port_def}\n"
+          if a[5].to_s != "#{internal_alloc_name_from_port_def}.#{internal_alloc_ep_name_from_port_def}" then
+            cdl_error( "S1173 $1: allocator mismatch from $2's allocator", "#{port_name}.#{fd_name}.#{par_name}", cell.get_name  )
+          end
+        end
+      }
+    }
+
+    # composite プラグイン
+    if @generate then
+      celltype_plugin
+    end
+  end
+
+ ### CompositeCelltype#new_cell_in_composite
+  def self.new_cell_in_composite( cell )
+    @@current_object.new_cell_in_composite( cell )
+
+  end
+
+  def new_cell_in_composite( cell )
+    cell.set_owner self  # Cell (in_omposite)
+    @cell_list_in_composite.add_item( cell )
+    if cell.get_celltype then    # nil ならば、すでにセルタイプなしエラー
+      if cell.get_celltype.is_singleton? then
+        @real_singleton = cell
+      end
+      if cell.get_celltype.is_active? then
+        @real_active = cell
+      end
+    end
+  end
+
+ ### join
+  def self.new_join( export_name, internal_cell_name,
+			 internal_cell_elem_name, type )
+    @@current_object.new_join( export_name, internal_cell_name,
+					 internal_cell_elem_name, type )
+    
+  end
+
+ ### CompositeCelltype#new_cell
+  def new_cell cell
+    @cell_list << cell
+
+    # セルタイププラグインの適用
+    celltype_plugin_new_cell cell
+  end
+
+  #=== CompositeCelltype# CompositeCelltypeJoin を作成
+  # STAGE: B
+  #export_name:: Symbol : 外部に公開する名前
+  #internal_cell_name:: Symbol : 内部セル名
+  #internal_cell_elem_name:: Symbol : 内部セルの要素名（呼び口名、受け口名、属性名のいずれか）
+  #type::  :CALL, :ENTRY, :ATTRIBUTE のいずれか（構文要素としてあるべきもの）
+  #RETURN:: Decl | Port : エクスポート定義
+  # new_join は
+  #   cCall => composite.cCall;     (セル内)
+  #   attr = composite.attr;        (セル内)
+  #   composite.eEnt => cell2.eEnt; (セル外)
+  # の構文要素の出現に対して呼び出される
+  def new_join( export_name, internal_cell_name,
+		 internal_cell_elem_name, type )
+
+    dbgPrint "new_join: #{export_name} #{internal_cell_name} #{internal_cell_elem_name}\n"
+
+    cell = @cell_list_in_composite.get_item( internal_cell_name )
+    if cell == nil then
+      cdl_error( "S1057 $1 not found in $2" , internal_cell_name, @name )
+      return
+    end
+
+    celltype = cell.get_celltype
+    return if celltype == nil	# celltype == nil ならすでにエラー
+
+    # 内部セルのセルタイプから対応要素を探す
+    # このメソッドは、構文上、呼び口、受け口、属性が記述できる箇所から呼出される
+    # 構文上の呼出し位置（記述位置）と、要素が対応したものかチェック
+    obj = celltype.find( internal_cell_elem_name )
+    if obj.instance_of?( Decl ) then
+      if obj.get_kind == :VAR then
+        cdl_error( "S1058 \'$1\' : cannot export var" , internal_cell_elem_name )
+        return
+      elsif type != :ATTRIBUTE then
+        cdl_error( "S1059 \'$1\' : exporting attribute. write in cell or use \'=\' to export attribute" , export_name )
+        # return 次のエラーを避けるために処理続行し、付け加えてみる
+      end
+    elsif obj.instance_of?( Port ) then
+      if obj.get_port_type != type then
+        cdl_error( "S1060 \'$1\' : port type mismatch. $2 type is allowed here." , export_name, type )
+        # return 次のエラーを避けるために処理続行し、付け加えてみる
+      end
+    else
+      cdl_error( "S1061 \'$1\' : not defined" , internal_cell_elem_name )
+      dbgPrint "S1061 CompositeCelltypeJoin#new_join: #{export_name} => #{internal_cell_name}.#{internal_cell_elem_name} #{type}\n"
+      return
+    end
+
+    # エクスポート定義と一致するかどうかチェック
+    obj2 = @name_list.get_item( export_name )
+    if( obj2 == nil )then
+      cdl_error( "S1062 $1 has no export definition" , export_name )
+    elsif obj2.instance_of?( Decl ) then
+      if( ! obj.instance_of? Decl )then
+        cdl_error( "S1063 $1 is port but previously defined as an attribute" , export_name )
+      elsif ! obj.get_type.equal? obj2.get_type then
+        cdl_error( "S1064 $1 : type \'$2$3\' mismatch with pprevious definition\'$4$5\'" , export_name, obj.get_type.get_type_str, obj.get_type.get_type_str_post, obj2.get_type.get_type_str, obj2.get_type.get_type_str_post )
+      end
+    elsif obj2.instance_of?( Port ) then
+      if( obj.instance_of? Port )then
+        if( obj.get_port_type != obj2.get_port_type )then
+          cdl_error( "S1065 $1 : port type $2 mismatch with previous definition $3" , export_name, obj.get_port_type, obj2.get_port_type )
+        elsif obj.get_signature != obj2.get_signature then
+          if obj.get_signature != nil && obj2.get_signature != nil then
+            # nil ならば既にエラーなので報告しない
+            cdl_error( "S1066 $1 : signature \'$2\' mismatch with previous definition \'$3\'" , export_name, obj.get_signature.get_name, obj2.get_signature.get_name )
+          end
+        elsif obj.get_array_size != obj2.get_array_size then
+          cdl_error( "S1067 $1 : array size mismatch with previous definition" , export_name )
+        elsif obj.is_optional? != obj2.is_optional? then
+          cdl_error( "S1068 $1 : optional specifier mismatch with previous definition" , export_name )
+        elsif obj.is_omit? != obj2.is_omit? then
+          cdl_error( "S9999 $1 : omit specifier mismatch with previous definition" , export_name )
+        elsif obj.is_dynamic? != obj2.is_dynamic? then
+          cdl_error( "S9999 $1 : dynamic specifier mismatch with previous definition" , export_name )
+        elsif obj.is_ref_desc? != obj2.is_ref_desc? then
+          cdl_error( "S9999 $1 : ref_desc specifier mismatch with previous definition" , export_name )
+        end
+      else
+        cdl_error( "S1069 $1 is an attribute but previously defined as a port" , export_name )
+      end
+    end
+
+    join = CompositeCelltypeJoin.new( export_name, internal_cell_name,
+				 internal_cell_elem_name, cell, obj2 )
+    join.set_owner self   # CompositeCelltypeJoin
+    cell.add_compositecelltypejoin join
+
+    # debug
+    dbgPrint "compositecelltype join: add #{cell.get_name} #{export_name} = #{internal_cell_name}.#{internal_cell_elem_name}\n"
+
+    if obj.instance_of?( Decl ) then
+      # attribute
+#      # 内部から外部へ複数の結合がないかチェック
+#      found = false
+#      @attr_list.each{ |a|
+#        if a.get_name == join.get_name then
+#          found = true
+#          break
+#        end
+#      }
+#      if found == false then
+        @attr_list << join
+#      end
+    else
+      # call/entry port
+#      # 内部から外部へ複数の結合がないかチェック
+#      found = false
+#      @port_list.each{ |port|
+#        if port.get_name == join.get_name then
+#          found = true
+#          break
+#        end
+#      }
+#      if found == false then
+        @port_list << join
+#      end
+    end
+
+    # join を @export_name_list に登録（重複チェックとともに，後で行われる CompositeCelltypeJoin の clone に備える）
+    if obj.instance_of?( Decl ) && @export_name_list.get_item( export_name ) then
+      # 既に存在する。追加しない。新仕様では、@export_name_list に同じ名前が含まれることがある。
+    elsif obj.instance_of?( Port ) && obj.get_port_type == :CALL && @export_name_list.get_item( export_name ) then
+      # 既に存在する。追加しない。新仕様では、@export_name_list に同じ名前が含まれることがある。
+    else
+      @export_name_list.add_item( join )
+    end
+
+    # export するポートに含まれる send/receive パラメータのアロケータ(allocator)呼び口をセルと結合
+    if obj2.instance_of? Port then
+      obj2.each_param{ |port, fd, par|
+        case par.get_direction                        # 引数の方向指定子 (in, out, inout, send, receive )
+        when :SEND, :RECEIVE
+          cp_name = :"#{port.get_name}_#{fd.get_name}_#{par.get_name}"     # アロケータ呼び口の名前
+          #            ポート名         関数名         パラメータ名
+          cp_internal_name = :"#{internal_cell_elem_name}_#{fd.get_name}_#{par.get_name}"
+
+          # リレーアロケータ or 内部アロケータ指定がなされている場合、アロケータ呼び口を追加しない
+          # この時点では get_allocator_instance では得られないため tmp を得る
+          if port.get_allocator_instance_tmp then
+            found = false
+            port.get_allocator_instance_tmp.each { |s|
+              if s[1] == fd.get_name && s[2] == par.get_name then
+                found = true
+
+                if s[0] == :INTERNAL_ALLOC then
+                  # 内部アロケータの場合    # mikan これは内部のセルに直結する。外部のポートに改めるべき
+                  @internal_allocator_list << [ cell, cp_internal_name, port.get_name, fd.get_name, par.get_name, s[3] ]
+                end
+              end
+            }
+            if found == true
+              next
+            end
+          end
+
+          # 外部アロケータの場合
+          new_join( cp_name, internal_cell_name, cp_internal_name, :CALL )
+        end
+      }
+    end
+
+    # エクスポート定義を返す
+    return obj2
+  end
+
+  def self.has_attribute? attr
+    @@current_object.has_attribute? attr
+  end
+
+  def has_attribute? attr
+    @name_list.get_item( attr ) != nil
+  end
+
+  def self.new_port port
+    @@current_object.new_port port
+  end
+
+  #=== CompositeCelltype# new_port
+  def new_port port
+    port.set_owner self   # Port (CompositeCelltype)
+    dbgPrint "new_port: #{@owner.get_name}.#{port.get_name}\n"
+    @name_list.add_item port
+
+    # export するポートに含まれる send/receive パラメータのアロケータ呼び口の export を生成してポートに追加
+    # この時点では内部アロケータかどうか判断できないので、とりあえず生成しておく
+    port.each_param { |port, fd, par|
+      case par.get_direction                        # 引数の方向指定子 (in, out, inout, send, receive )
+      when :SEND, :RECEIVE
+        #### リレーアロケータ or 内部アロケータ指定がなされている場合、アロケータ呼び口を追加しない
+        # 内部アロケータ指定がなされている場合、アロケータ呼び口を追加しない
+        # この時点では get_allocator_instance では得られないため tmp を得る
+        if port.get_allocator_instance_tmp then
+          found = false
+          port.get_allocator_instance_tmp.each { |s|
+            if s[0] == :INTERNAL_ALLOC && s[1] == fd.get_name && s[2] == par.get_name then
+              found = true
+              break
+            end
+          }
+          if found == true
+            next
+          end
+        end
+
+        if par.get_allocator then
+          cp_name = :"#{port.get_name}_#{fd.get_name}_#{par.get_name}"     # アロケータ呼び口の名前
+          #           ポート名          関数名         パラメータ名
+          alloc_sig_path = [ par.get_allocator.get_name ]  # mikan Namespace アロケータ呼び口のシグニチャ
+          array_size = port.get_array_size            # 呼び口または受け口配列のサイズ
+          created_port = Port.new( cp_name, alloc_sig_path, :CALL, array_size ) # 呼び口を生成
+          created_port.set_allocator_port( port, fd, par )
+          if port.is_omit? then
+            created_port.set_omit
+          end
+          new_port( created_port )           # セルタイプに新しい呼び口を追加
+        # else
+        #   already error
+        end
+      end
+    }
+  end
+
+  def self.new_attribute attr
+    @@current_object.new_attribute attr
+  end
+
+  #=== CompositeCelltype# new_attribute for CompositeCelltype
+  #attribute:: [Decl]
+  def new_attribute( attribute )
+    attribute.each { |a|
+      a.set_owner self   # Decl (CompositeCelltype)
+      # V1.1.0.10 composite の attr の size_is は可となった
+      # if a.get_size_is then
+      #  cdl_error( "S1070 $1: size_is pointer cannot be exposed for composite attribute" , a.get_name )
+      # end
+      @name_list.add_item( a )
+      if a.get_initializer then
+        a.get_type.check_init( @locale, a.get_identifier, a.get_initializer, :ATTRIBUTE )
+      end
+    }
+  end
+
+  #=== CompositeCelltype# 逆require の結合を生成する
+  def create_reverse_require_join cell
+    @name_list.get_items.each{ |n|
+      if n.instance_of? Port then
+        n.create_reverse_require_join cell
+      end
+    }
+  end
+
+  # false : if not in celltype definition, nil : if not found in celltype
+  def self.find( name )
+    if @@current_object == nil then
+      return false
+    end
+    @@current_object.find name
+  end
+
+  def find name
+    dbgPrint "CompositeCelltype: find in composite: #{name}\n"
+    cell = @cell_list_in_composite.get_item( name )
+    return cell if cell
+
+    dbgPrint "CompositeCelltype: #{name}, #{@name_list.get_item( name )}\n"
+    return @name_list.get_item( name )
+
+    # 従来仕様
+#    cj = @export_name_list.get_item( name )
+#p "#{name}, #{cj.get_port_decl}"
+#    if cj then
+#      return cj.get_port_decl
+#    else
+#      return nil
+#    end
+  end
+
+  #=== CompositeCelltype# export する CompositeCelltypeJoin を得る
+  #name:: string:
+  # attribute の場合、同じ名前に対し複数存在する可能性があるが、最初のものしか返さない
+  def find_export name
+    return @export_name_list.get_item( name )
+  end
+
+  #=== CompositeCelltype# composite celltype の cell を展開
+  #name:: string: Composite cell の名前
+  #global_name:: string: Composite cell の global name (C 言語名)
+  #join_list:: NamedList : Composite cell に対する Join の NamedList
+  #RETURN:
+  # [ { name => cell }, [ cell, ... ] ]
+  #  戻り値 前は 名前⇒cloneされた内部セル、後ろは composite の出現順のリスト
+  def expand( name, global_name, namespacePath, join_list, region, plugin, locale )
+
+    # debug
+    dbgPrint "expand composite: #{@name} name: #{name}  global_name: #{global_name}\njoin_list:\n"
+    join_list.get_items.each{ |j|
+      dbgPrint "   #{j.get_name} #{j}\n"
+    }
+  
+    # 展開で clone されたセルのリスト、右辺は Cell (composite の場合 composite な cell の clone)
+    clone_cell_list = {}
+    clone_cell_list2 = []
+    clone_cell_list3 = {}
+
+    #  composite 内部のすべての cell について
+    @cell_list_in_composite.get_items.each { |c|
+
+      # debug
+      dbgPrint "expand : cell #{c.get_name}\n"
+
+      # Join の配列
+      ja = []
+
+      # CompositeCelltype が export する呼び口、受け口、属性のリストについて
+      # @export_name_list.get_items.each{ |cj|	# cj: CompositeCelltypeJoin
+      # 新仕様では、@export_name_list に入っていない attr がありうる
+      (@port_list+@attr_list).each{ |cj|	# cj: CompositeCelltypeJoin
+
+        # debug
+        dbgPrint "        cj : #{cj.get_name}\n"
+
+        # CompositeCelltypeJoin (export) の対象セルか？
+        if cj.match?( c ) then
+
+          # 対象セル内の CompositeCelltype の export する Join (attribute または call port)
+          j = join_list.get_item( cj.get_name )
+
+          # debug
+          if j then
+            dbgPrint "  REWRITE_EX parent cell: #{name} child cell: #{c.get_name}:  parent's export port: #{cj.get_name}  join: #{j.get_name}=>#{j.get_rhs.to_s}\n"
+          else
+            dbgPrint "expand : parent cell: #{name} child cell: #{c.get_name}:  parent's export port: #{cj.get_name}  join: nil\n"
+          end
+
+          if j then
+            # 呼び口、属性の場合
+            #  ComositeCell 用のもの(j) を対象セル用に clone (@through_list もコピーされる)
+            # p "expand: cloning Join #{j.get_name} #{@name} #{name}"
+            jc = j.clone_for_composite( @name, name, locale )
+                                        # celltype_name, cell_name
+
+            # debug
+            # p "cn #{jc.get_name} #{cj.get_cell_elem_name}"
+
+            # 対象セルの呼び口または属性の名前に変更
+            jc.change_name( cj.get_cell_elem_name )
+
+            # 対象セルに対する Join の配列
+            ja << jc
+          end
+
+          # debug
+          dbgPrint "\n"
+        end
+      }
+
+      # debug
+      dbgPrint "expand : clone #{name}_#{c.get_name}\n"
+
+      # セルの clone を生成
+#      clone_cell_list[ "#{name}_#{c.get_name}" ] =  c.clone_for_composite( name, global_name, ja )
+      c2 =  c.clone_for_composite( name, global_name, namespacePath, ja, @name, region, plugin, locale )
+      clone_cell_list[ "#{c.get_local_name}" ] = c2
+      clone_cell_list2 << c2
+      clone_cell_list3[ c ] = c2
+
+    }
+
+    clone_cell_list.each { |nm,c|
+      dbgPrint "  cloned: #{nm} = #{c.get_global_name}\n"
+      # join の owner を clone されたセルに変更する V1.1.0.25
+      c.get_join_list.get_items.each{ |j|
+        j.set_cloned( clone_cell_list[ "#{c.get_local_name}" ] )
+      }
+      dbgPrint "change_rhs_port: inner cell #{c.get_name}\n"
+      c.change_rhs_port clone_cell_list3
+    }
+    clone_cell_list2.each { |c|
+      c.expand_inner
+    }
+    return [ clone_cell_list, clone_cell_list2 ]
+  end
+
+  #=== CompositeCelltype 指定子リストの設定
+  def set_specifier_list( spec_list )
+    return if spec_list == nil
+
+    spec_list.each { |s|
+      case s[0]
+      when :SINGLETON
+        @b_singleton = true
+      when :IDX_IS_ID
+        cdl_warning( "W1005 $1 : idx_is_id is ineffective for composite celltype" , @name )
+      when :ACTIVE
+        @b_active = true
+      when :GENERATE
+        if @generate then
+          cdl_error( "S9999 generate specifier duplicate"  )
+        end
+        @generate = [ s[1], s[2] ] # [ PluginName, "option" ]
+      else
+        cdl_error( "S1071 $1 cannot be specified for composite" , s[0] )
+      end
+    }
+  end
+
+  def get_name
+    @name
+  end
+
+  def get_global_name
+    @global_name
+  end
+
+  def get_port_list
+    @port_list
+  end
+
+  def get_attribute_list
+    @attr_list
+  end
+
+  def get_var_list
+    []   # 空の配列を返す
+  end
+
+  def get_internal_allocator_list
+    @internal_allocator_list
+  end
+
+  #== CompositeCelltype#get_real_celltype
+  # port_name に接続されている内部のセルタイプを得る
+  def get_real_celltype( port_name )
+    cj = find_export port_name
+    inner_celltype = cj.get_cell.get_celltype
+    if inner_celltype.instance_of? CompositeCelltype then
+      return inner_celltype.get_real_celltype
+    else
+      return inner_celltype
+    end
+  end
+
+  #== CompositeCelltype# generate 指定子の情報
+  # CompositeCelltype には generate が指定できないので nil を返す
+  # Celltype::@generate を参照のこと
+  def get_celltype_plugin
+    nil
+  end
+
+  def is_singleton?
+    @b_singleton
+  end
+
+  def is_active?
+    @b_active
+  end
+
+  #=== CompositeCelltype# アクティブではない
+  # active ではないに加え、全ての内部セルのセルタイプが inactive の場合に inactive
+  # （内部のセルが active または factory を持っている）
+  def is_inactive?
+    if @b_active == false then
+      @cell_list_in_composite.get_items.each{ |c|
+        if c.get_celltype && c.get_celltype.is_inactive? == false then
+          # c.get_celltype == nil の場合はセルタイプ未定義ですでにエラー
+          return false
+        end
+      }
+      return true
+    else
+      return false
+    end
+  end
+
+  def get_id_base
+    raise "get_id_base"
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "CompositeCelltype: name: #{@name}"
+    (indent+1).times { print "  " }
+    puts "active: #{@b_active}, singleton: #{@b_singleton}"
+    @cell_list_in_composite.show_tree( indent + 1 )
+    (indent+1).times { print "  " }
+    puts "name_list"
+    @name_list.show_tree( indent + 2 )
+    (indent+1).times { print "  " }
+    puts "export_name_list"
+    @export_name_list.show_tree( indent + 2 )
+    if @internal_allocator_list.length > 0 then
+      (indent+1).times { print "  " }
+      puts "internal_allocator_list:"
+      @internal_allocator_list.each{  |a|
+        (indent+1).times { print "  " }
+        puts "  #{a[0].get_name} #{a[1]} #{a[2]} #{a[3]} #{a[4]}"
+      }
+    end
+  end
+
+end
+
+
+
+#== 構文要素：口を表すクラス（セルタイプの呼び口、受け口）
+class Port < BDNode
+# @name::  str
+# @signature:: Signature
+# @port_type::  :CALL, :ENTRY
+# @array_size:: nil: not array, "[]": sizeless, Integer: sized array
+# @reverse_require_cell_path:: NamespacePath :     逆require呼び元セル  mikan namespace (呼び口のみ指定可能)
+# @reverse_require_callport_name:: Symbol:  逆require呼び元セルの呼び口名
+#
+# set_allocator_port によって設定される．設定された場合、このポートはアロケータポートである。
+# @allocator_port:: Port : この呼び口ができる元となった呼び口または受け口
+# @allocator_func_decl:: Decl : この呼び口ができる元となった呼び口または受け口の関数
+# @allocator_param_decl:: ParamDecl : この呼び口ができる元となった呼び口または受け口のパラメータ
+#
+# set_specifier によって設定される(
+# @allocator_instance:: Hash : {"func_param" => [ :RELAY_ALLOC, func_name, param_name, rhs_cp_name, rhs_func_name, rhs_param_name ]}
+#                                               [:INTERNAL_ALLOC, func_name, param_name, rhs_ep_name ]
+# @allocator_instance_tmp:: Hash : {"func_param" => [:INTERNAL_ALLOC|:RELAY_ALLOC,  IDENTIFIER, IDENTIFIER, expression ],..}
+#                                                                                    function    parameter   rhs
+#
+# @b_require:: bool : require により生成された call port の場合 true
+# @b_has_name:: bool : require : 名前ありのリクワイア呼び口
+# @b_inline:: bool : entry port のみ
+# @b_omit:: bool : omit 指定子が指定された (call port のみ)
+# @b_optional:: bool : call port のみ
+# @b_ref_desc:: bool :  ref_desc キーワードが指定された
+# @b_dynamic:: bool :  dynamic キーワードが指定された (呼び口のみ)
+#
+# optimize::
+# @celltype:: 属するセルタイプ
+#
+# :CALL の場合の最適化
+# @b_VMT_useless:: bool                     # VMT 関数テーブルを使用しない
+# @b_skelton_useless:: bool                 # スケルトン関数不要   (true の時、受け口関数を呼出す)
+# @b_cell_unique:: bool                     # 呼び先は唯一のセル
+# @only_callee_port:: Port                  # 唯一の呼び先ポート
+# @only_callee_cell:: Cell                  # 唯一の呼び先セル (@b_PEPDES_in_CB_useless = true の時有効)
+#
+# :ENTRY の場合の最適化（呼び口最適化と同じ変数名を使用）
+# @b_VMT_useless:: bool                     # VMT 関数テーブルが不要
+# @b_skelton_useless:: bool                 # スケルトン関数不要
+
+  def initialize( name, sig_path, port_type, array_size = nil, reverse_require_cell_path = nil, reverse_require_entry_port_name = nil )
+    super()
+    @name = name
+    @port_type = port_type
+
+    if array_size == "[]" then
+#      if port_type == :ENTRY then
+#        cdl_error( "S1072 $1: entry port: sizeless array not supported in current version" , name )
+#      end
+      @array_size = array_size
+    elsif array_size then
+      if array_size.kind_of? Expression then
+        @array_size = array_size.eval_const(nil)
+      else
+        @array_size = array_size   # これはアロケータ呼び口の場合（元の呼び口で既に評価済み）
+      end
+      if @array_size == nil then
+        cdl_error( "S1073 Not constant expression $1" , array_size.to_s )
+      end
+
+      #if Integer( @array_size ) != @array_size || @array_size <= 0 then
+      if ! @array_size.kind_of? Integer then
+        cdl_error( "S1074 Not Integer $1" , array_size.to_s )
+      end
+
+    end
+
+    object = Namespace.find( sig_path )    #1
+    if object == nil then
+      # mikan signature の名前が不完全
+      cdl_error( "S1075 \'$1\' signature not found" , sig_path )
+    elsif ! object.instance_of?( Signature ) then
+      # mikan signature の名前が不完全
+      cdl_error( "S1076 \'$1\' not signature" , sig_path )
+    else
+      @signature = object
+
+    end
+
+    # 逆require
+    @reverse_require_cell_path       = nil
+    @reverse_require_entry_port_name = nil
+    if reverse_require_cell_path then
+      if port_type == :CALL then
+        cdl_error( "S1152 $1 call port cannot have fixed join", @name )
+      else
+        @reverse_require_cell_path       = reverse_require_cell_path
+        @reverse_require_entry_port_name = reverse_require_entry_port_name
+
+        # 受け口配列か？
+        if array_size then
+          cdl_error( "S1153 $1: cannot be entry port array for fixed join port", @name )
+        end
+
+        # 呼び口のセルタイプを探す
+        ct_or_cell = Namespace.find( @reverse_require_cell_path )  #1
+        if ct_or_cell.instance_of? Cell then
+          ct = ct_or_cell.get_celltype
+        elsif ct_or_cell.instance_of? Celltype then
+          ct = ct_or_cell
+          if ! ct.is_singleton? then
+            cdl_error( "S1154 $1: must be singleton celltype for fixed join", @reverse_require_cell_path.to_s )
+          end
+        else
+          ct = nil
+          cdl_error( "S1155 $1: not celltype or not found", @reverse_require_cell_path.get_path_str)
+        end
+
+        if ct == nil then
+          return    # 既にエラー
+        end
+
+        # 添え字なしの呼び口配列か？
+        port = ct.find( @reverse_require_entry_port_name )
+        if port == nil || port.get_port_type != :CALL
+          cdl_error( "S1156 $1: not call port or not found", @reverse_require_entry_port_name )
+        else
+          if port.get_array_size != "[]" then
+            cdl_error( "S1157 $1: sized array or not array", @reverse_require_entry_port_name )
+          end
+        end
+
+      end
+    end
+
+    @b_require = false
+    @b_has_name = false
+    @b_inline = false
+    @b_optional = false
+    @b_omit = false
+    @b_ref_desc = false
+    @b_dynamic = false
+    reset_optimize
+  end
+
+  #=== Port#最適化に関する変数をリセットする
+  # Region ごとに最適化のやりなおしをするため、リセットする
+  def reset_optimize
+    if @port_type == :CALL then
+      # call port optimize
+      @b_VMT_useless = false                     # VMT 不要 (true の時 VMT を介することなく呼出す)
+      @b_skelton_useless = false                 # スケルトン関数不要   (true の時、受け口関数を呼出す)
+      @b_cell_unique = false                     # 唯一の呼び先セル
+      @only_callee_port = nil                    # 唯一の呼び先ポート
+      @only_callee_cell = nil                    # 唯一の呼び先セル
+    else
+      # entry port optimize
+      if $unopt || $unopt_entry then
+        # 最適化なし
+        @b_VMT_useless = false                     # VMT 不要 (true の時 VMT を介することなく呼出す)
+        @b_skelton_useless = false                 # スケルトン関数不要   (true の時、受け口関数を呼出す)
+      else
+        # 最適化あり
+        @b_VMT_useless = true                      # VMT 不要 (true の時 VMT を介することなく呼出す)
+        @b_skelton_useless = true                  # スケルトン関数不要   (true の時、受け口関数を呼出す)
+      end
+    end
+end
+
+  def set_celltype celltype
+    @celltype = celltype
+  end
+
+  def get_name
+    @name
+  end
+
+  def get_port_type
+    @port_type
+  end
+
+  def get_signature
+    @signature
+  end
+
+  def get_array_size
+    @array_size
+  end
+
+  def get_celltype
+    @celltype
+  end
+
+  #=== Port# アロケータポートの設定
+  #port:: Port : send/receive のあった呼び口または受け口
+  #fd:: Decl : 関数の declarator
+  #par:: ParamDecl : send/receive のあった引数
+  # この呼び口が生成されるもとになった呼び口または受け口の情報を設定
+  def set_allocator_port( port, fd, par )
+    @allocator_port = port
+    @allocator_func_decl = fd
+    @allocator_param_decl = par
+  end
+
+  def is_allocator_port?
+    @allocator_port != nil
+  end
+
+  def get_allocator_port
+    @allocator_port
+  end
+
+  def get_allocator_func_decl
+    @allocator_func_decl
+  end
+
+  def get_allocator_param_decl
+    @allocator_param_decl
+  end
+
+  def set_require( b_has_name )
+    @b_require = true
+    @b_has_name = b_has_name
+  end
+
+  def is_require?
+    @b_require
+  end
+
+  #=== Port# require 呼び口が名前を持つ？
+  # require 限定
+  def has_name?
+    @b_has_name
+  end
+
+  def is_optional?
+    @b_optional
+  end
+
+  def set_optional
+    @b_optional = true
+  end
+
+  #=== Port# omit 指定されている?
+  def is_omit?
+    @b_omit || ( @signature && @signature.is_empty? )
+  end
+
+  def set_omit
+    @b_omit = true
+  end
+
+  def set_VMT_useless                     # VMT 関数テーブルを使用しない
+   @b_VMT_useless = true
+  end
+
+  def set_skelton_useless                 # スケルトン関数不要   (true の時、受け口関数を呼出す)
+    @b_skelton_useless = true
+  end
+
+  def set_cell_unique                     # 呼び先セルは一つだけ
+    @b_cell_unique = true
+  end
+
+  #=== Port# 呼び口/受け口の指定子の設定
+  # inline, allocator の指定
+  def set_specifier spec_list
+    spec_list.each { |s|
+      case s[0]
+      when :INLINE
+        if @port_type == :CALL then
+          cdl_error( "S1077 inline: cannot be specified for call port"  )
+          next
+        end
+        @b_inline = true
+      when :OMIT
+        if @port_type == :ENTRY then
+          cdl_error( "S9999 omit: cannot be specified for entry port"  )
+          next
+        end
+        @b_omit = true
+      when :OPTIONAL
+        if @port_type == :ENTRY then
+          cdl_error( "S1078 optional: cannot be specified for entry port"  )
+          next
+        end
+        @b_optional = true
+      when :REF_DESC
+        if @port_type == :ENTRY then
+          cdl_error( "S9999 ref_desc: cannnot be specified for entry port" )
+          next
+        end
+        @b_ref_desc = true
+      when :DYNAMIC
+        if @port_type == :ENTRY then
+          cdl_error( "S9999 dynamic: cannnot be specified for entry port" )
+          next
+        end
+        @b_dynamic = true
+      when :ALLOCATOR
+        if @port_type == :CALL then
+          cdl_error( "S1079 allocator: cannot be specified for call port"  )
+        end
+        if @allocator_instance_tmp then
+          cdl_error( "S1080 duplicate allocator specifier"  )
+          next
+        end
+        @allocator_instance_tmp = s[1]
+      else
+        raise "unknown specifier #{s[0]}"
+      end
+    }
+    if ( @b_dynamic || @b_ref_desc ) then
+      if @b_dynamic then
+        dyn_ref = "dynamic"
+      else
+        dyn_ref = "ref_desc"
+      end
+      if @b_omit then     # is_omit? は is_empty? も含んでいるので使えない
+        cdl_error( "S9999 omit cannot be specified with $1", dyn_ref  )
+      elsif @signature && @signature.is_empty? then
+        cdl_error( "S9999 $1 cannot be specified for empty signature", dyn_ref  )
+      elsif @signature && @signature.has_descriptor? then
+        # cdl_error( "S9999 $1 port '$2' cannot have Descriptor in its signature", dyn_ref, @name )
+      end
+
+    elsif @b_dynamic && @b_ref_desc then
+      cdl_error( "S9999 both dynamic & ref_desc cannot be specified simultaneously"  )
+    end
+  end
+
+  #=== Port# リレーアロケータ、内部アロケータのインスタンスを設定
+  # 呼び口の前方参照可能なように、セルタイプの解釈の最後で行う
+  def set_allocator_instance
+    if @allocator_instance_tmp == nil then
+      return
+    end
+
+    @allocator_instance = {}
+    @allocator_instance_tmp.each { |ai|
+      direction = nil
+      alloc_type = ai[0]
+      # ai = [ :INTERNAL_ALLOC|:RELAY_ALLOC, func_name, param_name, rhs ]
+      case alloc_type
+      when :INTERNAL_ALLOC
+        if ! @owner.instance_of? CompositeCelltype then # ミスを防ぐために composite でなければとした
+          cdl_error( "S1081 self allocator not supported yet"  )   # mikan これはサポートされているはず。要調査 12/1/15
+          next
+        end
+        # OK
+      when :RELAY_ALLOC
+        # OK
+      when :NORMAL_ALLOC
+        # ここへ来るのは composite の受け口で右辺が "eEnt.func.param" 形式で指定されていた場合
+        cdl_error( "S1174 $1 not suitable for lhs, suitable lhs: 'func.param'", "#{ai[1]}.#{ai[3]}.#{ai[4]}" )
+        next
+      else
+        raise "Unknown allocator type #{ai[1]}"
+      end
+
+      # '=' 左辺(func_name,param_name)は実在するか?
+      if @signature then       # signature = nil なら既にエラー
+        fh = @signature.get_function_head( ai[1] )
+        if fh == nil then
+          cdl_error( "S1082 function \'$1\' not found in signature" , ai[1] )
+          next
+        end
+        decl = fh.get_declarator
+        if ! decl.is_function? then
+          next   # 既にエラー
+        end
+        paramdecl = decl.get_type.get_paramlist.find( ai[2] )
+        if paramdecl == nil then
+          cdl_error( "S1083 \'$1\' not found in function \'$2\'" , ai[2], ai[1] )
+          next
+        end
+        case paramdecl.get_direction
+        when :SEND, :RECEIVE
+          # OK
+          direction = paramdecl.get_direction
+        else
+          cdl_error( "S1084 \'$1\' in function \'$2\' is not send or receive" , ai[2], ai[1] )
+          next
+        end
+      end
+
+      # 重複指定がないか?
+      if @allocator_instance[ "#{@name}_#{ai[1]}_#{ai[2]}" ] then
+        cdl_error( "S1085 duplicate allocator specifier for \'$1_$2\'" , ai[1], ai[2] )
+      end
+
+      # 右辺のチェック
+      case alloc_type
+      when :INTERNAL_ALLOC
+
+        ele = ai[3].get_elements
+        if( ele[0] != :IDENTIFIER )then
+          cdl_error( "S1086 $1: rhs not in 'allocator_entry_port' form", ai[3].to_s )
+          next
+        end
+
+        ep_name = ele[1]   # アロケータ受け口名
+        ep = @owner.find ep_name.get_path[0]  # mikan "a::b"
+        if ep == nil || ! ep.instance_of?( Port ) || ep.get_port_type != :ENTRY || ! ep.get_signature.is_allocator? then
+          cdl_error( "S1175 $1 not found or not allocator entry port for $2" , ep_name, ai[1] )
+        end
+        # 右辺チェック終わり
+        # ai2 = [ :INTERNAL_ALLOC, func_name, param_name, rhs_ep_name ]
+        ai2 = [ ai[0], ai[1], ai[2], ep_name ]
+
+      when :RELAY_ALLOC
+        ele = ai[3].get_elements
+        if( ele[0] != :OP_DOT ||
+            ele[1][0] != :OP_DOT || ele[1][1][0] != :IDENTIFIER || ! ele[1][1][1].is_name_only? ||
+            ! ele[1][2].instance_of?( Token ) || ! ele[2].instance_of?( Token ) )then   #1
+          # [ :OP_DOT, [ :OP_DOT, [ :IDENTIFIER,  name_space_path ],  Token(1) ],  Token(2) ]
+          #    ele[0]    ele[1][0]  ele[1][1][0]  ele[1][1][1]        ele[1][2]    ele[2]
+          #      name_space_path.Token(1).Token(2) === call_port.func.param
+          #  mikan Expression#analyze_cell_join_expression の変種を作成して置き換えるべき
+
+          cdl_error( "S1176 rhs not in 'call_port.func.param' form for for $1_$2" , ai[1], ai[2] )   # S1086
+          next
+        end
+        func_name = ele[1][2]; cp_name = ele[1][1][1].get_name; param_name = ele[2].to_sym
+        cp = @owner.find cp_name    # リレーする先の呼び口
+        if cp then
+# mikan cp が呼び口であることのチェック（属性の場合もある）
+# mikan 受け口から受け口へのリレーへの対応 (呼び口から呼び口へのリレーはありえない)  <=== 文法にかかわる事項（呼び口側でアロケータが決定される）
+          sig = cp.get_signature
+          if sig && @signature then
+            fh = @signature.get_function_head( func_name )
+            if fh == nil then
+              cdl_error( "S1087 function \'$1\' not found in signature \'$2\'" , func_name, sig.get_name )
+              next
+            end
+            decl = fh.get_declarator
+            if ! decl.is_function? then
+              next   # 既にエラー
+            end
+            paramdecl = decl.get_type.get_paramlist.find( param_name )
+            if paramdecl == nil then
+              cdl_error( "S1088 \'$1\' not found in function \'$2\'" , param_name, func_name )
+              next
+            end
+            case paramdecl.get_direction
+            when :SEND, :RECEIVE
+              # OK
+              if alloc_type == :RELAY_ALLOC && direction != paramdecl.get_direction then
+                cdl_error( "S1089 relay allocator send/receive mismatch between $1.$2 and $3_$4.$5" , ai[1], ai[2], cp_name, func_name, param_name )
+              end
+            else
+              cdl_error( "S1090 \'$1\' in function \'$2\' is not send or receive" , param_name, func_name )
+              next
+            end
+
+            # else
+            # sig == nil ならば既にエラー
+          end
+        else
+          if @celltype then
+            ct_name = @celltype.get_name
+          else
+            ct_name = "(None)"
+          end
+          cdl_error( "S1091 call port \'$1\' not found in celltype $2" , cp_name, ct_name )
+          next
+        end
+        # 右辺チェック終わり
+        # ai2 = [ :RELAY_ALLOC, func_name, param_name, rhs_cp_name, rhs_func_name, rhs_param_name ]
+        ai2 = [ ai[0], ai[1], ai[2], cp_name, func_name, param_name ]
+      end # case alloc_type
+
+      @allocator_instance[ "#{@name}_#{ai[1]}_#{ai[2]}" ] = ai2
+    }
+  end
+
+  def is_inline?
+    @b_inline
+  end
+
+  def is_VMT_useless?                     # VMT 関数テーブルを使用しない
+    if @port_type == :ENTRY && $unopt_entry == true then
+      # プラグインから $unopt_entry を設定するケースのため
+      # ここで読み出すときに、false を返す (reset_optimize での設定変更は速すぎる)
+      return false
+    else
+      return @b_VMT_useless
+    end
+  end
+
+  def is_skelton_useless?                 # スケルトン関数不要   (true の時、受け口関数を呼出す)
+    if @port_type == :ENTRY && $unopt_entry == true then
+      # プラグインから $unopt_entry を設定するケースのため
+      # ここで読み出すときに、false を返す (reset_optimize での設定変更は速すぎる)
+      return false
+    else
+      return @b_skelton_useless
+    end
+  end
+
+  def is_cell_unique?                     # 呼び先のセルは一つ？
+    @b_cell_unique
+  end
+
+  #=== Port# 受け口最適化の設定
+  # この受け口を参照する呼び口が VMT, skelton を必要としているかどうかを設定
+  # 一つでも呼び口が必要としている（すなわち b_*_useless が false）場合は、
+  # この受け口の最適化を false とする
+  def set_entry_VMT_skelton_useless( b_VMT_useless, b_skelton_useless )
+    if ! b_VMT_useless then
+      @b_VMT_useless = false
+    end
+    if ! b_skelton_useless then
+      @b_skelton_useless = false
+    end
+  end
+
+  #=== Port# 唯一の結合先を設定
+  # 最適化で使用
+  #  b_VMT_useless == true || b_skelton_useless == true の時に設定される
+  #  optional の場合 callee_cell, callee_port が nil となる
+  def set_only_callee( callee_port, callee_cell )
+    @only_callee_port = callee_port
+    @only_callee_cell = callee_cell
+  end
+
+  #=== Port# 唯一の結合先ポートを返す(compositeの場合実セル)
+  # optional 呼び口で未結合の場合 nil を返す
+  def get_real_callee_port
+    if @only_callee_cell then
+      return @only_callee_cell.get_real_port( @only_callee_port.get_name )
+    end
+  end
+
+  #=== Port# 唯一の結合先セルを返す(compositeの場合実セル)
+  # optional 呼び口で未結合の場合 nil を返す
+  def get_real_callee_cell
+    if @only_callee_cell then
+      return @only_callee_cell.get_real_cell( @only_callee_port.get_name )
+    end
+  end
+
+  def get_allocator_instance
+    return @allocator_instance
+  end
+
+  def get_allocator_instance_tmp
+    return @allocator_instance_tmp
+  end
+
+  #=== Port# 逆require の結合を生成する
+  # STAGE: S
+  def create_reverse_require_join cell
+    if @reverse_require_cell_path == nil then
+      return
+    end
+
+    # 呼び元セルを探す
+    ct_or_cell = Namespace.find( @reverse_require_cell_path )   # mikan namespace    #1
+    if ct_or_cell.instance_of? Cell then
+      cell2 = ct_or_cell
+      ct = cell2.get_celltype
+      if ct == nil then
+        return    # 既にエラー
+      end
+    elsif ct_or_cell.instance_of? Celltype then
+      cell2 = ct_or_cell.get_singleton_cell( cell.get_region )
+      if cell2 == nil then
+        cdl_error( "S1158 $1: singleton cell not found for fixed join", ct_or_cell.get_name )
+        return
+      end
+      ct = ct_or_cell
+    else
+      # 既にエラー：無視
+      return
+    end
+
+    # 結合を生成する
+    dbgPrint "create_reverse_require_join #{cell2.get_name}.#{@reverse_require_entry_port_name}[] = #{cell.get_name}.#{@name}"
+    nsp = NamespacePath.new( cell.get_name, false, cell.get_namespace )
+#    rhs = Expression.new( [ :OP_DOT, [ :IDENTIFIER, Token.new( cell.get_name, nil, nil, nil ) ],
+    rhs = Expression.new( [ :OP_DOT, [ :IDENTIFIER, nsp ],
+                            Token.new( @name, nil, nil, nil ) ], cell.get_locale )   #1
+    join = Join.new( @reverse_require_entry_port_name, -1, rhs, cell.get_locale )
+    cell2.new_join( join )
+    join.set_definition( ct.find(join.get_name) )
+
+  end
+
+  #=== Port# signature のすべての関数のすべてのパラメータをたどる
+  #block:: ブロックを引数として取る(ruby の文法で書かない)
+  #  ブロックは3つの引数を受け取る(Port, Decl,      ParamDecl)    Decl: 関数ヘッダ
+  # Signature クラスにも each_param がある（同じ働き）
+  def each_param # ブロック引数{  |port, func_decl, param_decl| }
+    return if @signature == nil                         # signature 未定義（既にエラー）
+    fha = @signature.get_function_head_array            # 呼び口または受け口のシグニチャの関数配列
+    return if fha == nil                                # nil なら文法エラーで有効値が設定されなかった
+
+    pr = Proc.new   # このメソッドのブロック引数を pr に代入
+    port = self
+    fha.each{ |fh|  # fh: FuncHead                      # 関数配列中の各関数頭部
+      fd = fh.get_declarator                            # fd: Decl  (関数頭部からDeclarotorを得る)
+      if fd.is_function? then                           # fd が関数でなければ、すでにエラー
+        fd.get_type.get_paramlist.get_items.each{ |par| # すべてのパラメータについて
+          pr.call( port, fd, par )
+        }
+      end
+    }
+  end
+
+  #=== Port# 逆require指定されている？
+  def is_reverse_required?
+    @reverse_require_cell_path != nil
+  end
+
+  #=== Port# is_dynamic?
+  def is_dynamic?
+    @b_dynamic
+  end
+
+  #=== Port# is_ref_desc?
+  def is_ref_desc?
+    @b_ref_desc
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "Port: name:#{@name} port_type:#{@port_type} require:#{@b_require} inline:#{@b_inline} omit:#{@b_omit} optional:#{@b_optional} ref_desc:#{@b_ref_desc} dynamic:#{@b_dynamic}"
+    (indent+1).times { print "  " }
+    if @signature then
+      puts "signature: #{@signature.get_name} #{@signature}"
+    else
+      puts "signature: NOT defined"
+    end
+    if @array_size == "[]" then
+      (indent+1).times { print "  " }
+      puts "array_size: not specified"
+    elsif @array_size then
+      (indent+1).times { print "  " }
+      puts "array_size: #{@array_size}"
+    end
+    if @allocator_instance then
+      (indent+1).times { print "  " }
+      puts "allocator instance:"
+      @allocator_instance.each { |b,a|
+        (indent+2).times { print "  " }
+        puts "#{a[0]} #{a[1]} #{b} "
+        # a[3].show_tree( indent+3 )
+      }
+    end
+    (indent+1).times { print "  " }
+    if @port_type == :CALL then
+      puts "VMT_useless : #{@b_VMT_useless}  skelton_useless : #{@b_skelton_useless}  cell_unique : #{@b_cell_unique}"
+    else
+      puts "VMT_useless : #{@b_VMT_useless}  skelton_useless : #{@b_skelton_useless}"
+    end
+  end
+
+end
+
+#== Namespace
+#
+# root namespace だけ、Region クラスのインスタンスとして生成される
+# root namespace は、root region を兼ねるため
+#
+# @cell_list は Region の場合にのみ持つ (mikan @cell_list 関連は Region に移すべき)
+#
+class Namespace < NSBDNode
+# @name::  Symbol     # root の場合 "::" (String)
+# @global_name:: str
+# @name_list:: NamedList   Signature,Celltype,CompositeCelltype,Cell,Typedef,Namespace
+# @struct_tag_list:: NamedList : StructType
+# @namespace_list:: Namespace[] : Region は Namespace の子クラスであり、含まれる
+# @signature_list:: Sginature[]
+# @celltype_list:: Celltype[]
+# @compositecelltype_list:: CompositeCelltype[]
+# @cell_list:: Cell[]
+# @typedef_list:: Typedef[]
+# @decl_list:: ( Typedef | StructType | EnumType )[]   依存関係がある場合に備えて、順番どおりに配列に格納 mikan enum
+# @const_decl_list:: Decl[]
+# @cache_n_cells:: Integer :  get_n_cells の結果をキャッシュする
+# @cache_generating_region:: Region :  get_n_cells の結果をキャッシュするしているリージョン
+
+  # mikan namespace の push, pop
+
+  # namespace 階層用のスタック
+  @@namespace_stack = []      # @@namespace_stack[0] = "::" (generator.rb)
+  @@namespace_sp = -1
+
+  # Generator ネスト用のスタック (namespace 階層用のスタックを対比する)
+  @@nest_stack_index = -1
+  @@nest_stack = []
+
+  @@root_namespace = nil
+
+  # Generator ネスト用スタックの push, pop (クラスメソッド)
+  def self.push
+    dbgPrint "push Namespace\n"
+    @@nest_stack_index += 1
+    @@nest_stack[ @@nest_stack_index ] = [ @@namespace_stack, @@namespace_sp ]
+    if @@root_namespace then
+      @@namespace_sp = 0
+      @@namespace_stack[ @@namespace_sp ] = @@root_namespace
+    end
+  end
+
+  def self.pop
+    dbgPrint "pop Namespace\n"
+    @@namespace_stack, @@namespace_sp = @@nest_stack[ @@nest_stack_index ]
+    @@nest_stack_index -= 1
+    if @@nest_stack_index < -1 then
+      raise "TooManyRestore"
+    end
+  end
+
+  # namespace 階層用スタックの push, pop (インスタンスメソッド)
+  def push ns
+    @@namespace_sp += 1
+    @@namespace_stack[ @@namespace_sp ] = self
+    dbgPrint "Namespace.PUSH #{@@namespace_sp} #{@name}\n"
+  end
+
+  def pop
+    dbgPrint "Namespace.POP #{@@namespace_sp} #{@name}\n"
+    @@namespace_sp -= 1
+    if @@namespace_sp < 0 then
+      raise "StackUnderflow"
+    end
+  end
+
+  def initialize( name )
+
+    super()
+    @name = name
+
+    if( name == "::" )then
+      if( @@root_namespace != nil )then
+        # root は一回のみ生成できる
+        raise "try to re-create root namespace"
+      end
+      @@root_namespace = self
+      @NamespacePath = NamespacePath.new( name, true )
+    else
+      ns = @@namespace_stack[ @@namespace_sp ].find( name )
+      if ns.kind_of? Namespace then
+        dbgPrint "namespace: re-appear #{@name}\n"
+        # 登録済み namespace の再登録
+        ns.push ns
+        return
+      elsif ns then
+        cdl_error( "S1151 $1: not namespace", @name )
+        prev_locale = ns.get_locale
+        puts "previous: #{prev_locale[0]}: line #{prev_locale[1]} \'#{name}\' defined here"
+      end
+      dbgPrint "namespace: 1st-appear #{@name}\n"
+    end
+
+    if @@namespace_sp >= 0 then   # root は除外
+      @@namespace_stack[@@namespace_sp].new_namespace( self )
+    end
+    push self
+
+    @global_name = Namespace.get_global_name    # stack 登録後取る
+    @name_list = NamedList.new( nil, "symbol in namespace '#{@name}'" )
+    @struct_tag_list = NamedList.new( nil, "struct tag" )
+
+    @namespace_list = []
+    @signature_list = []
+    @celltype_list = []
+    @compositecelltype_list = []
+    @cell_list = []
+    @typedef_list = []
+    @decl_list = []
+    @const_decl_list = []
+    @cache_n_cells = nil
+    @cache_generating_region = nil
+    if @NamespacePath == nil then
+      # root namespace の場合は設定済 (親 namespace が見つからず例外になる)
+      set_namespace_path # @NamespacePath の設定
+    end
+  end
+
+  def end_of_parse
+    pop
+  end
+
+  def get_name
+    @name
+  end
+
+  #=== Namespace:: global_name を得る
+  # parse 中のみこのメソッドは使える
+  # STAGE: P
+  def self.get_global_name    # parse 中有効
+    if @@namespace_sp <= 0 then
+      return ""
+    end
+
+    path = @@namespace_stack[1].get_name.to_s
+    i = 2
+    while i <= @@namespace_sp
+      path = path+"_"+@@namespace_stack[i].get_name.to_s
+      i += 1
+    end
+
+    path
+  end
+
+  def get_global_name
+    @global_name
+  end
+
+  #=== Namespace#セルの個数を得る
+  # 子 region が linkunit, node 指定されていれば、含めない（別のリンク単位）
+  # プロトタイプ宣言のもののみの個数を含めない
+  # mikan namespace 下に cell を置けない仕様になると、このメソッドは Region のものでよい
+  # mikan 上記の場合 instance_of? Namespace の条件判定は不要となる
+  def get_n_cells
+    if @cache_generating_region == $generating_region then
+      # このメソッドは繰り返し呼び出されるため、結果をキャッシュする
+      return @cache_n_cells
+    end
+
+    count = 0
+    @cell_list.each{ |c|
+      # 定義かプロトタイプ宣言だけかは、new_cell の段階で判断できないため、カウントしなおす
+      if c.get_f_def == true then
+        # print "get_n_cells: cell: #{c.get_name}\n"
+        count += 1
+      end
+    }
+
+    @namespace_list.each{ |ns|
+      if ns.instance_of? Namespace then
+        count += ns.get_n_cells
+      else
+        # ns は Region である
+        rt = ns.get_region_type
+        # print "get_n_cells: region: #{ns.get_name}: #{rt}\n"
+        if rt == :NODE || rt == :LINKUNIT then
+          # 別の linkunit なので加算しない
+        else
+          count += ns.get_n_cells
+        end
+      end
+    }
+
+    @cache_generating_region = $generating_region
+    @cache_n_cells = count
+    return count
+  end
+
+  #=== Namespace.find : in_path で示されるオブジェクトを探す
+  #in_path:: NamespacePath
+  #in_path:: Array : 古い形式
+  #  path [ "::", "ns1", "ns2" ]   absolute
+  #  path [ "ns1", "ns2" ]         relative
+  def self.find( in_path )
+
+    if in_path.instance_of? Array then
+      # raise "Namespace.find: old fashion"
+
+      path = in_path
+      length = path.length
+      return self.find_one( path[0] ) if length == 1
+
+      name = path[0]
+      if name == "::" then
+        i = 1
+        name = path[i]   # 構文的に必ず存在
+        object = @@root_namespace.find( name )  # root
+      else
+        # 相対パス
+        i = 0
+        object = @@namespace_stack[@@namespace_sp].find_one( name ) # crrent
+      end
+
+    elsif in_path.instance_of? NamespacePath then
+      path = in_path.get_path
+      length = path.length
+
+      if length == 0 then
+        if in_path.is_absolute? then
+          return @@root_namespace
+        else
+          raise "path length 0, not absolute"
+        end
+      end
+
+      i = 0
+      name = path[0]
+      if in_path.is_absolute? then
+        object = @@root_namespace.find( name )  # root
+      else
+        bns = in_path.get_base_namespace
+        object = bns.find_one( name )           # crrent
+      end
+    else
+      raise "unexpected path"
+    end
+
+    i += 1
+    while i < length
+
+      unless object.kind_of?( Namespace ) then
+        # クラスメソッド内で cdl_error を呼び出すことはできない
+        # また、前方参照対応後、正確な行番号が出ない問題も生じる
+        # cdl_error( "S1092 \'$1\' not namespace" , name )
+        # このメソッドから nil が帰った場合 "not found" が出るので、ここでは出さない
+        return nil
+      end
+
+      object = object.find( path[i] )
+      i += 1
+    end
+
+    return object
+  end
+
+
+  def find( name )
+    @name_list.get_item(name)
+  end
+
+  #=== Namespace# namespace から探す。見つからなければ親 namespace から探す
+  def self.find_one( name )
+    return @@namespace_stack[@@namespace_sp].find_one( name )
+  end
+
+  def find_one( name )
+
+    object = find( name )
+    # これは出すぎ
+    # dbgPrint "in '#{@name}' find '#{name}' object #{object ? object.class : "Not found"}\n"
+
+    if object != nil then
+      return object
+    elsif @name != "::" then
+      return @owner.find_one( name )
+    else
+      return nil
+    end
+  end
+
+  def self.get_current
+    @@namespace_stack[@@namespace_sp]
+  end
+
+  def self.find_tag( name )
+    # mikan tag : namespace の path に対応しない
+    # namespace の中にあっても、root namespace にあるものと見なされる
+    # よって カレント namespace から根に向かって探す
+    i = @@namespace_sp
+    while i >= 0
+      res = @@namespace_stack[i].find_tag( name )
+      if res then
+        return res
+      end
+      i -= 1
+    end
+  end
+
+  def find_tag( name )
+    @struct_tag_list.get_item( name )
+  end
+
+ ### namespace
+  def self.new_namespace( namespace )
+    @@namespace_stack[@@namespace_sp].new_namespace( namespace )
+  end
+
+  def new_namespace( namespace )
+    dbgPrint "new_namespace: #{@name}:#{self} #{namespace.get_name}:#{namespace} \n"
+    namespace.set_owner self   # Namespace (Namespace)
+
+    @name_list.add_item( namespace )
+    @namespace_list << namespace
+  end
+
+ ### signature
+  def self.new_signature( signature )
+    @@namespace_stack[@@namespace_sp].new_signature( signature )
+  end
+
+  def new_signature( signature )
+    signature.set_owner self   # Signature (Namespace)
+    @name_list.add_item( signature )
+    @signature_list << signature
+  end
+
+ ### celltype
+  def self.new_celltype( celltype )
+    @@namespace_stack[@@namespace_sp].new_celltype( celltype )
+  end
+
+  def new_celltype( celltype )
+    celltype.set_owner self   # Celltype (Namespace)
+    @name_list.add_item( celltype )
+    @celltype_list << celltype
+  end
+
+ ### compositecelltype
+  def self.new_compositecelltype( compositecelltype )
+    @@namespace_stack[@@namespace_sp].new_compositecelltype( compositecelltype )
+  end
+
+  def new_compositecelltype( compositecelltype )
+    compositecelltype.set_owner self   # CompositeCelltype (Namespace)
+    @name_list.add_item( compositecelltype )
+    @compositecelltype_list << compositecelltype
+  end
+
+ ### cell (Namespace)
+  def self.new_cell( cell )
+    @@namespace_stack[@@namespace_sp].new_cell( cell )
+  end
+
+  def new_cell( cell )
+    dbgPrint "Namespace.new_cell: #{@NamespacePath.get_path_str}::#{cell.get_name}\n"
+    if ! is_root? && ! ( instance_of? Region ) then
+      cdl_error( "S9999 '$1' cell cannot be placed under namespace", cell.get_name )
+    end
+    cell.set_owner self   # Cell (Namespace)
+    @name_list.add_item( cell )
+    @cell_list << cell
+  end
+
+  #=== Namespace# 参照されているが、未定義のセルを探す
+  # プロトタイプ宣言だけで定義されていないケースをエラーとする
+  # 受動の未結合セルについて警告する
+  def check_ref_but_undef
+    @cell_list.each { |c|
+      if ! c.get_f_def then   # Namespace の @cell_list にはプロトタイプが含まれるケースあり
+        if c.get_f_ref then
+          c.cdl_error( "S1093 $1 : undefined cell" , c.get_namespace_path.get_path_str )
+        elsif $verbose then
+          c.cdl_warning( "W1006 $1 : only prototype, unused and undefined cell" , c.get_namespace_path.get_path_str )
+        end
+      else
+        dbgPrint "check_ref_but_undef: #{c.get_global_name}\n"
+        ct = c.get_celltype
+        # if c.get_f_ref == false && c.is_generate? && ct && ct.is_inactive? then
+        if c.get_f_ref == false && ct && ct.is_inactive? then
+          c.cdl_warning( "W1007 $1 : non-active cell has no entry join and no factory" , c.get_namespace_path.get_path_str )
+        end
+        if c.has_ineffective_restrict_specifier then
+          c.cdl_warning( "W9999: $1 has ineffective restrict specifier", c.get_namespace_path.get_path_str )
+        end
+      end
+    }
+    @namespace_list.each { |n|
+      n.check_ref_but_undef
+    }
+  end
+
+  #=== Namespace# セルの受け口の参照カウントを設定する
+  def set_port_reference_count
+    @cell_list.each { |c|
+      c.set_port_reference_count
+    }
+    @namespace_list.each { |n|
+      n.set_port_reference_count
+    }
+  end
+
+ ### struct
+  def self.new_structtype( struct )
+    @@namespace_stack[@@namespace_sp].new_structtype( struct )
+  end
+
+  def new_structtype( struct )
+    # struct.set_owner self   # StructType (Namespace) # StructType は BDNode ではない
+    dup = @struct_tag_list.get_item(struct.get_name)
+    if dup != nil then
+      if struct.same? dup then
+        # 同じものが typedef された
+        # p "#{struct.get_name}"
+        return
+      end
+    end
+
+    @struct_tag_list.add_item( struct )
+    @decl_list << struct
+  end
+
+ ### typedef
+  def self.new_typedef( typedef )
+    @@namespace_stack[@@namespace_sp].new_typedef( typedef )
+  end
+
+  def new_typedef( typedef )
+    typedef.set_owner self   # TypeDef (Namespace)
+    dup = @name_list.get_item(typedef.get_name)
+    if dup != nil then
+      typedef_type = typedef.get_declarator.get_type.get_original_type
+      dup_type = dup.get_declarator.get_type.get_original_type
+      # print "typedef: #{typedef.get_name} = #{typedef_type.get_type_str} #{typedef_type.get_type_str_post}\n"
+      if typedef_type.get_type_str == dup_type.get_type_str &&
+          typedef_type.get_type_str_post == dup_type.get_type_str_post then
+        # 同じものが typedef された
+        # ここへ来るのは C で関数ポインタを typedef しているケース
+        # 以下のように二重に定義されている場合は type_specifier_qualifier_list として扱われる
+        #    typedef long LONG; 
+        #    typedef long LONG;
+        # bnf.y.rb では declarator に TYPE_NAME を許さないので、ここへ来ることはない
+        # p "#{typedef.get_declarator.get_type.get_type_str} #{typedef.get_name} #{typedef.get_declarator.get_type.get_type_str_post}"
+        return
+      end
+      # p "prev: #{dup.get_declarator.get_type.get_type_str}#{dup.get_declarator.get_type.get_type_str_post} current:#{typedef.get_declarator.get_type.get_type_str} #{typedef.get_declarator.get_type.get_type_str_post}"
+    end
+
+    # p "typedef: #{typedef.get_name}  #{typedef.get_declarator.get_type.get_original_type.get_type_str}#{typedef.get_declarator.get_type.get_original_type.get_type_str_post}"
+    # typedef.show_tree 0
+
+    @name_list.add_item( typedef )
+    @typedef_list << typedef
+    @decl_list << typedef
+  end
+
+  def self.is_typename?( str )
+    i = @@namespace_sp
+    while i >= 0
+      if @@namespace_stack[i].is_typename?( str ) then
+        return true
+      end
+      i -= 1
+    end
+    false
+  end
+
+  def is_typename?( str )
+    if @name_list.get_item( str ).instance_of?( Typedef ) then
+      true
+    else
+      false
+    end
+  end
+
+ ### const_decl
+  def self.new_const_decl( decl )
+    @@namespace_stack[@@namespace_sp].new_const_decl( decl )
+  end
+
+  def new_const_decl( decl )
+    decl.set_owner self   # Decl (Namespace:const)
+    if ! decl.is_const? then			# const 修飾さていること
+      if decl.is_type?( PtrType ) then
+        cdl_error( "S1094 $1: pointer is not constant. check \'const\'" , decl.get_name )
+      else
+        cdl_error( "S1095 $1: not constant" , decl.get_name )
+      end
+    elsif ! decl.is_type?( IntType ) && ! decl.is_type?( FloatType ) &&
+        ! decl.is_type?( BoolType ) && ! decl.is_type?( PtrType ) then
+                                            # IntType, FloatType であること
+      cdl_error( "S1096 $1: should be int, float, bool or pointer type" , decl.get_name )
+    elsif decl.get_initializer == nil then   # 初期値を持つこと
+      cdl_error( "S1097 $1: has no initializer" , decl.get_name )
+#    elsif decl.get_initializer.eval_const(nil) == nil then  #eval_const は check_init で呼出されるので二重チェック
+#                                            # mikan 初期値が型に対し適切であること
+#      cdl_error( "S1098 $1: has unsuitable initializer" , decl.get_name )
+    else
+      decl.get_type.check_init( @locale, decl.get_name, decl.get_initializer, :CONSTANT )
+      @name_list.add_item( decl )
+      @const_decl_list << decl
+    end
+
+  end
+
+ ### region
+  # def self.new_region( region )
+  #   @@namespace_stack[@@namespace_sp].new_region( region )
+  # end
+# 
+  # def new_region( region )
+  #   region.set_owner self   # Rgion (Namespace)
+  #   @name_list.add_item( region )
+  # end
+
+ ###
+
+  #=== Namespace# すべてのセルの require ポートを設定
+  # STAGE: S
+  def set_require_join
+    @celltype_list.each{ |ct|
+      ct.set_require_join
+    }
+    # すべての namespace について require ポートをセット
+    @namespace_list.each{ |ns|
+      ns.set_require_join
+    }
+  end
+
+  #=== Namespace# Join への definition の設定とチェック
+  # セルタイプに属するすべてのセルに対して実施
+  def set_definition_join
+    # celltype のコードを生成
+    @cell_list.each { |c|
+      dbgPrint "set_definition_join #{c.get_name}\n"
+      c.set_definition_join
+    }
+    @namespace_list.each{ |ns|
+      ns.set_definition_join
+    }
+  end
+
+  #=== Namespace# set_max_entry_port_inner_cell
+  # セルタイプに属するすべてのセルに対して実施
+  def set_max_entry_port_inner_cell
+    # celltype のコードを生成
+    @cell_list.each { |c|
+      c.set_max_entry_port_inner_cell
+    }
+    @namespace_list.each{ |ns|
+      ns.set_max_entry_port_inner_cell
+    }
+  end
+
+  #=== Namespace# セルの結合をチェックする
+  def check_join
+    @cell_list.each { |c|
+      dbgPrint "check_join #{c.get_name}\n"
+      c.check_join
+      c.check_reverse_require
+    }
+    @namespace_list.each{ |ns|
+      ns.check_join
+    }
+  end
+
+  #== Namespace# ルートか?
+  # ルートネームスペース と ルートリージョンは同じ
+  def is_root?
+    @name == "::"
+  end
+
+  #== Namespace# ルートを得る
+  # ルートリージョンとルートネームスペースは同じオブジェクト
+  def self.get_root
+    @@root_namespace
+  end
+
+  #== Namespace (Region) に属するセルのリスト
+  def get_cell_list
+    @cell_list
+  end
+
+  #== Namespace (Region)# 子リージョンのリスト
+  #
+  # リージョンは Namespace クラスで namespace として記憶されている
+  def get_region_list
+    @namespace_list
+  end
+  
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "#{self.class}: name: #{@name} path: #{get_namespace_path.get_path_str}"
+    @struct_tag_list.show_tree( indent + 1 )
+    @name_list.show_tree( indent + 1 )
+  end
+
+end
+
+
+class Join < BDNode
+# @name:: string
+# @subscript:: nil: not array, -1: subscript not specified, >=0: array_subscript
+# @rhs:: Expression | initializer ( array of Expression | initializer (Expression | C_EXP) )
+# @definition:: Port, Decl(attribute or var)
+#
+# available if definition is Port
+# @cell_name:: string : 右辺のセルの名前
+# @cell:: Cell  : 右辺のセル
+# @celltype:: Celltype : 右辺のセルタイプ
+# @port_name:: string : 右辺の受け口名
+# @port:: Port : 右辺の受け口
+# @array_member:: rhs array : available only for first appear in the same name
+# @array_member2:: Join array : available only for first appear in the same name
+# @rhs_subscript:: nil : not array, >=0: 右辺の添数
+#
+
+# @through_list::  @cp_through_list + @region_through_list
+#  以下の構造を持つ（@cp_through_list の構造は共通）
+# @cp_through_list::  呼び口に指定された through
+#   [ [plugin_name, cell_name, plugin_arg], [plugin_name2, cell_name2, plugin_arg], ... ]
+# @region_through_list::  region に指定された through
+#   [ [plugin_name, cell_name, plugin_arg, region], [plugin_name2, cell_name2, plugin_arg, region2], ... ]
+#
+# @through_generated_list:: [Plugin_class object, ...]: @through_list に対応
+# @region_through_generated_list:: [Plugin_class object, ...]: @region_through_list に対応
+#
+
+  include PluginModule
+
+  #=== Join# 初期化
+  #name:: string: 名前（属性名、呼び口名）
+  #subscript:: Nil=非配列, -1="[]", N="[N]"
+  #rhs:: Expression: 右辺の式
+  def initialize( name, subscript, rhs, locale = nil )
+    # dbgPrint "Join#new: #{name}, #{subscript} #{rhs.eval_const(nil)}\n"
+    dbgPrint "Join#new: #{name}, #{subscript}\n"
+
+    super()
+    if locale then
+      @locale = locale
+    end
+
+    @name = name
+    if subscript.instance_of?( Expression ) then
+       #mikan 配列添数が整数であることを未チェック
+       @subscript = subscript.eval_const(nil)
+       if @subscript == nil then
+         cdl_error( "S1099 array subscript not constant"  )
+       end
+    else
+       @subscript = subscript
+    end
+
+    @rhs = rhs
+    @definition = nil
+
+    # 配列要素を設定
+    # 本当は、初出の要素のみ設定するのが適当
+    # new_join で add_array_member の中で初出要素の array_member に対し設定する
+    if @subscript == -1 then
+      @array_member  = [self]
+      @array_member2 = [self]
+    elsif @subscript != nil then
+      @array_member = []
+      @array_member2 = []
+      @array_member[@subscript]  = self
+      @array_member2[@subscript] = self
+    end
+
+    @through_list = []
+    @cp_through_list = []
+    @region_through_list = []
+    @through_generated_list = []
+    @region_through_generated_list = []
+  end
+
+  #===  Join# 左辺に対応する celltype の定義を設定するとともにチェックする
+  # STAGE:   S
+  #
+  #     代入可能かチェックする
+  #definition:: Decl (attribute,varの時) または Port (callの時) または nil (definition が見つからなかった時)
+
+  def set_definition( definition )
+
+    dbgPrint "set_definition: #{@owner.get_name}.#{@name} = #{definition.class}\n"
+
+    # 二重チェックの防止
+    if @definition then
+      # set_definition を個別に行うケースで、二重に行われる可能性がある（異常ではない）
+      # 二重に set_definition が実行されると through が二重に適用されてしまう
+      # cdl_warning( "W9999 $1, internal error: set_definition duplicate", @name )
+      return
+    end
+
+    @definition = definition
+
+    # mikan 左辺値、右辺値の型チェックなど
+    if @definition.instance_of?( Decl ) then
+      check_var_init
+    elsif @definition.instance_of?( Port ) then
+      check_call_port_init
+      if @definition.get_port_type == :CALL then   # :ENTRY ならエラー。無視しない
+        check_and_gen_through
+        create_allocator_join  # through プラグイン生成した後でないと、挿入前のセルのアロケータを結合してしまう
+      end
+    elsif @definition == nil then
+      cdl_error( "S1117 \'$1\' not in celltype", @name )
+    else
+      raise "UnknownToken"
+    end
+  end
+
+  #=== Join# 変数の初期化チェック
+  def check_var_init
+    # attribute, var の場合
+    if @definition.get_kind == :ATTRIBUTE then
+#        check_cell_cb_init( definition.get_type, @rhs )
+      # 右辺で初期化可能かチェック
+      @definition.get_type.check_init( @locale, @definition.get_identifier, @rhs, :ATTRIBUTE )
+    elsif @definition.get_kind == :VAR then
+      # var は初期化できない
+      cdl_error( "S1100 $1: cannot initialize var" , @name )
+    else
+      # Bug trap
+      raise "UnknownDeclKind"
+    end
+  end
+
+  #=== Join# 呼び口の初期化チェック
+  def check_call_port_init
+    ### Port
+
+    # 左辺は受け口か（受け口を初期化しようとしている）？
+    if @definition.get_port_type == :ENTRY then
+      cdl_error( "S1101 \'$1\' cannot initialize entry port" , @name )
+      return
+    end
+
+#      # 配列添数の整合性チェック
+#      # 呼び口の定義で、非配列なら添数なし、添数なし配列なら添数なし、添数あり配列なら添数あり
+    as = @definition.get_array_size
+    if ( @subscript == nil && as != nil ) then
+      cdl_error( "S1102 $1: must specify array subscript here" , @name )
+    elsif ( @subscript != nil && as == nil ) then
+      cdl_error( "S1103 $1: cannot specify array subscript here" , @name )
+    end
+#    if @subscript == nil then
+#      if as != nil then
+#        cdl_error( "S1103 $1: need array subscript" , @name )
+#      end
+#    elsif @subscript == -1 then
+#      if as != "[]" then
+#        cdl_error( "S1104 $1: need array subscript number. ex. \'[0]\'" , @name )
+#      end
+#    else # @subscript >0
+#      if as == nil then
+#        cdl_error( "S1105 $1: cannot specify array subscript here" , @name )
+#      elsif as == "[]" then
+#        cdl_error( "S1106 $1: cannot specify array subscript number. use \'[]\'" , @name )
+#      end
+#    end
+
+    # mikan Expression の get_type で型導出させる方がスマート
+    # mikan '=' の左辺が配列かどうか未チェック
+    #(1) '=' の右辺は "Cell.ePort" の形式か？
+    #     演算子は "."  かつ "." の左辺が :IDENTIFIER
+    #     "." の右辺はチェック不要 (synatax 的に :IDENTIFIER)
+    #(2) "Cell" は存在するか？（名前が一致するものはあるか）
+    #(3) "Cell" は cell か？
+    #(4) "Cell" の celltype は有効か？ (無効なら既にエラー）
+    #(5) "ePort" は "Cell" の celltype 内に存在するか？
+    #(6) "ePort" は entry port か？
+    #(7) signature は一致するか
+
+    # 右辺がない（以前の段階でエラー）
+    return unless @rhs
+
+    # cCall = composite.cCall; のチェック．この形式は属性用
+    # 呼び口を export するには cCall => composite.cCall; の形式を用いる
+    if @rhs.instance_of?( Array ) == true && @rhs[0] == :COMPOSITE then
+      cdl_error( "S1107 to export port, use \'cCall => composite.cCall\'"  )
+      return
+    elsif ! @rhs.instance_of?( Expression ) then
+      raise "Unknown bug. specify -t to find problem in source"
+    end
+
+    # 右辺の Expression の要素を取り出す
+    ret = @rhs.analyze_cell_join_expression
+    if ret == nil then   #1
+      cdl_error( "S1108 $1: rhs not \'Cell.ePort\' form" , @name )
+      return
+    end
+
+    nsp, @rhs_subscript, @port_name = ret[0], ret[1], ret[2]
+    @cell_name = nsp.get_name     # mikan ns::cellname の形式の考慮
+
+    # composite の定義の中なら object は結合先 cell か、見つからなければ nil が返る
+    # composite の定義外なら false が返る
+    object = CompositeCelltype.find( @cell_name )
+    if object == false then
+#     mikan 左辺が namespace に対応していないため。 path にして find
+      # p nsp.get_path_str, nsp.get_path
+      object = Namespace.find( nsp )    #1
+      in_composite = false
+    else
+      if nsp.get_path.length != 1 then
+        cdl_error( "$1 cannot have path", nsp.get_path_str )
+      end
+      in_composite = true
+    end
+
+    if object == nil then                                             # (2)
+      cdl_error( "S1109 \'$1\' not found" , nsp.to_s )
+    elsif ! object.instance_of?( Cell ) then                          # (3)
+      cdl_error( "S1110 \'$1\' not cell" , nsp.to_s )
+    else
+      dbgPrint "set_definition: set_f_ref #{@owner.get_name}.#{@name} => #{object.get_name}\n"
+      object.set_f_ref
+
+      # 右辺のセルのセルタイプ
+      celltype = object.get_celltype
+
+      if celltype then                                                # (4)
+        object2 = celltype.find( @port_name )
+        if object2 == nil then                                        # (5)
+          cdl_error( "S1111 \'$1\' not found" , @port_name )
+        elsif ! object2.instance_of? Port \
+             || object2.get_port_type != :ENTRY then                  # (6)
+          cdl_error( "S1112 \'$1\' not entry port" , @port_name )
+        elsif @definition.get_signature != object2.get_signature then # (7)
+          cdl_error( "S1113 \'$1\' signature mismatch" , @port_name )
+        elsif object2.get_array_size then
+          # 受け口配列
+
+          unless @rhs_subscript then
+            # 右辺に添数指定がなかった
+            cdl_error( "S1114 \'$1\' should be array" , @port_name )
+          else
+
+            as = object2.get_array_size
+            if( as.kind_of?( Integer ) && as <= @rhs_subscript )then
+              # 受け口配列の大きさに対し、右辺の添数が同じか大きい
+              cdl_error( "S1115 $1[$2]: subscript out of range (< $3)" , @port_name, @rhs_subscript, as )
+            else
+              dbgPrint "Join OK #{@owner.get_name}.#{@name}[#{@rhs_subscript}] = #{object.get_name}.#{@port_name} #{self}\n"
+              @cell = object
+              @celltype = celltype
+              @port = object2
+              # 右辺のセルの受け口 object2 を参照済みにする
+              # object2: Port, @definition: Port
+              @cell.set_entry_port_max_subscript( @port, @rhs_subscript )
+            end
+
+            # debug
+            dbgPrint "Join set_definition: rhs: #{@cell}  #{@cell.get_name if @cell}\n"
+
+          end
+        elsif @rhs_subscript then
+          # 受け口配列でないのに右辺で添数指定されている
+          cdl_error( "S1116 \'$1\' entry port is not array" , @port_name )
+        else
+          dbgPrint "Join OK #{@owner.get_name}.#{@name} = #{object.get_name}.#{@port_name} #{self}\n"
+          @cell = object
+          @port = object2
+          @celltype = celltype
+
+          # 右辺のセル object の受け口 object2 を参照済みにする
+          # object2: Port, @definition: Port
+
+          # debug
+          # p "rhs:  #{@cell}  #{@cell.get_name}"
+        end  # end of port (object2) チェック
+
+        #else
+        #  celltype == nil (すでにエラー)
+      end  # end of celltyep チェック
+
+
+      check_region( object )
+
+    end  # end of cell (object) チェック
+
+  end
+
+  #=== Join# アロケータの結合を生成
+  # STAGE: S
+  #cell::  呼び口の結合先のセル
+  #
+  # ここでは呼び口側に生成されるアロケータ呼び口の結合を生成
+  # 受け口側は Cell の set_specifier_list で生成
+  #  a[*] の内容は Cell の set_specifier_list を参照
+  def create_allocator_join
+
+    cell = get_rhs_cell2   # 右辺のセルを得る
+    port = get_rhs_port2
+
+    if( cell && cell.get_allocator_list ) then      # cell == nil なら既にエラー
+
+      dbgPrint "create_allocator_join: #{@owner.get_name}.#{@name}=>#{cell ? cell.get_name : "nil"}\n"
+
+      cell.get_allocator_list.each { |a|
+
+        if( a[0+1] == port && a[1+1] == @rhs_subscript )then
+          # 名前の一致するものの結合を生成する
+          # 過不足は、別途チェックされる
+          cp_name = :"#{@name}_#{a[2+1]}_#{a[3+1]}"
+          # p "creating allocator join #{cp_name} #{@subscript} #{a[1+1]}"
+          join = Join.new( cp_name, @subscript, a[4+1], @locale )
+
+          #debug
+          dbgPrint "create_allocator_join: #{@owner.get_name}.#{cp_name} [#{@subscript}] #{@name}\n"
+          @owner.new_join join
+        else
+          dbgPrint "create_allocator_join:3 not #{@owner.get_name}.#{a[0+1]} #{@name}\n"
+        end
+      }
+    end
+  end
+
+  #=== Join# リージョン間の結合をチェック
+  # リージョン間の through による @region_through_list の作成
+  # 実際の生成は check_and_gen_through で行う
+  # mikan Cell#distance とRegion へたどり着くまでための処理に共通部分が多い
+  def check_region( object )
+
+    #debug
+    dbgPrint "check_region #{@owner.get_name}.#{@name} => #{object.get_name}\n"
+    # print "DOMAIN: check_region #{@owner.get_name}.#{@name} => #{object.get_name}\n"
+
+    # プラグインで生成されたなかでは生成しない
+    # さもないとプラグイン生成されたものとの間で、無限に生成される
+##    if Generator.get_nest >= 1 then
+##    if Generator.get_plugin then     # mikan これは必要？ (意味解析段階での実行になるので不適切)
+    if @owner.get_plugin.kind_of?( ThroughPlugin ) then
+      # プラグイン生成されたセルの場合、結合チェックのみ
+      return
+    end
+
+    # region のチェック
+    r1 = @owner.get_region      # 呼び口セルの region
+    r2 = object.get_region      # 受け口セルの region
+
+    if ! r1.equal? r2 then      # 同一 region なら呼出し可能
+
+      f1 = r1.get_family_line
+      len1 = f1.length
+      f2 = r2.get_family_line
+      len2 = f2.length
+
+      # 不一致になるところ（兄弟）を探す
+      i = 1  # i = 0 は :RootRegion なので必ず一致
+      while( i < len1 && i < len2 )
+        if( f1[i] != f2[i] )then
+          break
+        end
+        i += 1
+      end
+
+      sibling_level = i     # 兄弟となるレベル、もしくはどちらか一方が終わったレベル
+
+      dbgPrint "sibling_level: #{i}\n"
+      dbgPrint "from: #{f1[i].get_name}\n" if f1[i]
+      dbgPrint "to: #{f2[i].get_name}\n" if f2[i]
+
+      if f1[sibling_level] && f2[sibling_level] then
+        b_to_through = true
+      else
+        b_to_through = false
+      end
+
+
+      # 呼び側について呼び元のレベルから兄弟レベルまで（out_through をチェックおよび挿入）
+      i = len1 -1
+      if b_to_through then
+        end_level = sibling_level
+      else
+        end_level = sibling_level - 1
+      end
+      while i > end_level
+      # while i > sibling_level
+      # while i >= sibling_level
+        dbgPrint "going out from #{f1[i].get_name} level=#{i}\n"
+        region_count = f1[i].next_out_through_count
+        out_through_list = f1[i].get_out_through_list   # [ plugin_name, plugin_arg ]
+        domain = f1[i].get_domain_type
+        if domain then
+          domain_through = f1[i].get_domain_type.add_through_plugin( self, f1[i], f1[i-1], :OUT_THROUGH )
+          if domain_through == nil then
+            cdl_error( "S9999 $1: going out from regin '$2' not permitted by domain '$3'" , @name, f1[i].get_name, f1[i].get_domain_type.get_name )
+          end
+        elsif out_through_list.length == 0 then
+          cdl_error( "S1118 $1: going out from region \'$2\' not permitted" , @name, f1[i].get_name )
+        end
+
+        out_through_list.each { |ol|
+          if ol[0] then    # plugin_name が指定されていなければ登録しない
+            plugin_arg = CDLString.remove_dquote ol[1]
+            through = [ ol[0], :"Join_out_through_", plugin_arg, f1[i], f1[i-1], :OUT_THROUGH, region_count]
+            @region_through_list << through
+          end
+        }
+        if domain_through && domain_through.length > 0 then
+          through = [ domain_through[0], :"Join_domain_out_through_", domain_through[1], f1[i], f1[i-1], :OUT_THROUGH, region_count ]
+          @region_through_list << through
+        end
+        i -= 1
+      end
+
+      # 兄弟レベルにおいて（to_through をチェックおよび挿入）
+      if f1[sibling_level] && f2[sibling_level] then
+        dbgPrint "going from #{f1[sibling_level].get_name} to #{f2[sibling_level].get_name}\n"
+        found = 0
+        region_count = f1[i].next_to_through_count( f2[sibling_level].get_name )   # to_through の region カウント
+        f1[sibling_level].get_to_through_list.each { |t|
+          if t[0][0] == f2[sibling_level].get_name then   # region 名が一致するか ?
+            if t[1] then    # plugin_name が指定されていなければ登録しない
+              plugin_arg = CDLString.remove_dquote t[2]
+              through = [ t[1], :"Join_to_through__", plugin_arg, f1[sibling_level], f2[sibling_level], :TO_THROUGH, region_count ]
+              @region_through_list << through
+            end
+            found = 1
+          end
+        }
+        domain = f1[sibling_level].get_domain_type
+        if domain then
+          domain_through = f1[sibling_level].get_domain_type.add_through_plugin( self, f1[sibling_level], f2[sibling_level], :TO_THROUGH )
+          if domain_through == nil then
+            cdl_error( "S9999 $1: going from regin '$2' not permitted by domain'$3'" , @name, f1[sibling_level].get_name, f2[sibling_level].get_domain_type.get_name )
+          end
+          if domain_through && domain_through.length > 0 then
+            through = [ domain_through[0], :"Join_domain_to_through_", domain_through[1], f1[sibling_level], f2[sibling_level], :TO_THROUGH, region_count ]
+            @region_through_list << through
+          end
+        elsif found == 0 then
+          cdl_error( "S1119 $1: going from region \'$2\' to \'$3\' not permitted" , @name, f1[sibling_level].get_name, f2[sibling_level].get_name )
+        end
+      end
+
+      # 受け側について兄弟レベルから受け側のレベルまで（in_through をチェックおよび挿入）
+      if b_to_through then
+        i = sibling_level + 1      # to_through を経た場合、最初の in_through は適用しない
+      else
+        i = sibling_level
+      end
+      while i < len2
+        dbgPrint "going in to #{f2[i].get_name} level=#{i}\n"
+        region_count = f2[i].next_in_through_count
+        in_through_list = f2[i].get_in_through_list   # [ plugin_name, plugin_arg ]
+        domain = f2[i].get_domain_type
+        if domain then
+          domain_through = f2[i].get_domain_type.add_through_plugin( self, f2[i-1], f2[i], :IN_THROUGH )
+          if domain_through == nil then
+            cdl_error( "S9999 $1: going in from regin '$2' to '$3' not permitted by domain '$4'",
+                        @name, f2[i-1].get_name, f2[i].get_name, f2[i].get_domain_type.get_name )
+          end
+          if domain_through && domain_through.length > 0 then
+            through = [ domain_through[0], :"Join_domain_in_through_", domain_through[1], f2[i-1], f2[i], :IN_THROUGH, region_count ]
+            @region_through_list << through
+          end
+        elsif in_through_list.length == 0 then
+          cdl_error( "S1120 $1: going in to region \'$2\' not permitted" , @name, f2[i].get_name )
+        end
+        in_through_list.each { |il|
+          if il[0] then    # plugin_name が指定されていなければ登録しない
+            plugin_arg = CDLString.remove_dquote il[1]
+            through = [ il[0], :"Join_in_through_", plugin_arg, f2[i-1], f2[i],:IN_THROUGH, region_count ]
+            @region_through_list << through
+          end
+        }
+        i += 1
+      end
+
+    end
+  end
+
+
+  #=== Join# 生成しないリージョンへの結合かチェック
+  # 右辺のセルが、生成されないリージョンにあればエラー
+  # 右辺は、プラグイン生成されたセルがあれば、それを対象とする
+  def check_region2
+    lhs_cell = @owner
+
+    # 生成しないリージョンのセルへの結合か？
+    # if join.get_cell && ! join.get_cell.is_generate? then
+    # if get_rhs_cell && ! get_rhs_cell.is_generate? then # composite セルがプロタイプ宣言の場合例外
+    # print "Link root: (caller #{@owner.get_name}) '#{@owner.get_region.get_link_root.get_name}'"
+    # print " #{@owner.get_region.get_link_root == get_rhs_region.get_link_root ? "==" : "!="} "
+    # print "'#{get_rhs_region.get_link_root.get_name}'  (callee #{@cell_name})\n"
+
+    if get_rhs_region then
+      dbgPrint "check_region2 #{lhs_cell.get_name} => #{get_rhs_region.get_path_string}#{@rhs.to_s}\n"
+
+      # if get_rhs_region.is_generate? != true then  #3
+      if @owner.get_region.get_link_root != get_rhs_region.get_link_root then
+        cdl_error( "S1121 \'$1\' in region \'$2\' cannot be directly joined $3 in  $4" , lhs_cell.get_name, lhs_cell.get_region.get_namespace_path.get_path_str, @rhs.to_s, get_rhs_region.get_namespace_path.get_path_str )
+      end
+    else
+      # rhs のセルが存在しなかった (既にエラー)
+    end
+  end
+
+  def get_definition
+    @definition
+  end
+
+  #=== Join# specifier を設定
+  # STAGE: B
+  # set_specifier_list は、join の解析の最後で呼び出される
+  # through 指定子を設定
+  #  check_and_gen_through を呼出して、through 生成
+  def set_specifier_list( specifier_list )
+
+    specifier_list.each { |s|
+      case s[0]
+      when :THROUGH
+        # set plugin_name
+        plugin_name = s[1].to_s
+        plugin_name[0] = "#{plugin_name[/^./].upcase}"     # 先頭文字を大文字に : ruby のクラス名の制約
+
+        # set cell_name
+        cell_name = :"#{s[1].to_s}_"
+
+        # set plugin_arg
+        plugin_arg = CDLString.remove_dquote s[2].to_s
+        # plugin_arg = s[2].to_s.gsub( /\A"(.*)/, '\1' )   # 前後の "" を取り除く
+        # plugin_arg.sub!( /(.*)"\z/, '\1' )
+
+        @cp_through_list << [ plugin_name, cell_name, plugin_arg ]
+      end
+    }
+
+  end
+
+  #=== Join# through のチェックと生成
+  # new_join の中の check_region で region 間の through が @region_through に設定される
+  # set_specifier で呼び口の結合で指定された through が @cp_through 設定される
+  # その後、このメソッドが呼ばれる
+  def check_and_gen_through
+
+    dbgPrint "check_and_gen_through #{@owner.get_name}.#{@name}\n"
+
+    if ! @definition.instance_of? Port then
+      cdl_error( "S1123 $1 : not port: \'through\' can be specified only for port" , @name )
+      return
+    end
+    if @cp_through_list.length > 0 then
+      # is_empty? must check before is_omit?
+      if @definition.get_signature && @definition.get_signature.is_empty? then
+        cdl_warning( "W9999 'through' is specified for empty signature, ignored"  )
+        return
+      elsif @definition.is_omit? then
+        cdl_warning( "W9999 'through' is specified for omitted port, ignored"  )
+        return
+      end
+    end
+
+    @through_list = @cp_through_list + @region_through_list
+      # 後から @cp_through_list と @region_through_list に分けたため、このような実装になった
+
+    if @through_list then           # nil when the join is not Port
+      len = @through_list.length    # through が連接している数
+    else
+      len = 0
+    end
+    cp_len = @cp_through_list.length
+
+    if @owner.is_in_composite? && len > 0 then
+      cdl_error( "S1177 cannot specify 'through' in composite in current version" )
+      return
+    end
+
+    # 連続した through について、受け口側から順にセルを生成し解釈する
+    i = len - 1
+    while i >= 0
+
+      through = @through_list[ i ]
+      plugin_name           = through[ 0 ]
+      generating_cell_name  = through[ 1 ]
+      plugin_arg            = through[ 2 ]
+
+      if i != len - 1 then
+
+        begin
+          next_cell_nsp       = @through_generated_list[ i + 1 ].get_cell_namespace_path
+          next_port_name      = @through_generated_list[ i + 1 ].get_through_entry_port_name
+          next_port_subscript = @through_generated_list[ i + 1 ].get_through_entry_port_subscript
+        rescue Exception => evar
+          cdl_error( "S1124 $1: plugin function failed: \'get_through_entry_port_name\'" , plugin_name )
+          print_exception( evar )
+          i -= 1
+          next
+        end
+
+        next_cell = Namespace.find( next_cell_nsp )    #1
+        if next_cell == nil then
+          # p "next_cell_path: #{next_cell_nsp.get_path_str}"
+          cdl_error( "S1125 $1: not generated cell \'$2\'" , @through_generated_list[ i + 1 ].class, next_cell_nsp.get_path_str )
+          return
+        end
+
+      else
+        # 最後のセルの場合、次のセルの名前、ポート名
+        next_cell      = @cell
+        next_port_name = @port_name
+        next_port_subscript = @rhs_subscript
+
+        if next_cell == nil then
+          # 結合先がない
+          return
+        end
+      end
+
+      if i >= cp_len then
+        # region_through_list 部分
+        # region から @cell_name.@port_name への through がないか探す
+        # rp = @through_list[i][3].find_cell_port_through_plugin( @cell_name, @port_name ) #762
+        rp = @through_list[i][3].find_cell_port_through_plugin( @cell.get_global_name, @port_name, @rhs_subscript )
+           # @through_list[i] と @region_through_list[i-cp_len] は同じ
+        # 共用しないようにするには、見つからなかったことにすればよい
+        # rp = nil
+      else
+        # region 以外のものは共有しない
+        # 呼び口側に指定されているし、plugin_arg が異なるかもしれない
+        rp = nil
+      end
+
+      if rp == nil then
+        plClass = load_plugin( plugin_name, ThroughPlugin )
+        if( plClass ) then
+          gen_through_cell_code_and_parse( plugin_name, i, next_cell, next_port_name, next_port_subscript, plClass )
+        end
+      else
+        # 見つかったものを共用する
+        @through_generated_list[ i ] = rp
+      end
+
+      if i >= cp_len then
+        # @through_generated_list のうち @region_through_listに対応する部分
+        @region_through_generated_list[ i - cp_len ] = @through_generated_list[ i ]
+        if rp == nil then
+          # 生成したものを region(@through_list[i][3]) のリストに追加
+          # @through_list[i][3].add_cell_port_through_plugin( @cell_name, @port_name, @through_generated_list[i] ) #762
+          @through_list[i][3].add_cell_port_through_plugin( @cell.get_global_name, @port_name, @rhs_subscript, @through_generated_list[i] )
+        end
+      end
+
+      if i == 0 then
+        # 最も呼び口側のセルは、CDL 上の結合がないため、参照されたことにならない
+        # mikan namespace 対応
+        # cell = Namespace.find( [ @through_generated_list[0].get_cell_name] )    #1
+        if @through_generated_list[0] == nil then
+          return  # plugin_object の生成に失敗している
+        end
+        cell = Namespace.find( @through_generated_list[0].get_cell_namespace_path )    #1
+        if cell.instance_of? Cell then
+          cell.set_f_ref
+        end
+      end
+
+      i -= 1
+    end
+
+  end
+
+  @@through_count = { }
+  def get_through_count name
+    sym = name.to_sym
+    if @@through_count[ sym ] then
+      @@through_count[ sym ] += 1
+    else
+      @@through_count[ sym ] = 0
+    end
+    return @@through_count[ sym ]
+  end
+
+  #=== Join# through プラグインを呼び出して CDL 生成させるとともに、import する
+  def gen_through_cell_code_and_parse( plugin_name, i, next_cell, next_port_name, next_port_subscript, plClass )
+
+    through = @through_list[ i ]
+    plugin_name           = through[ 0 ]
+    generating_cell_name  = :"#{through[ 1 ]}_#{get_through_count through[ 1 ]}"
+    plugin_arg            = through[ 2 ]
+    if through[ 3 ] then
+      # region 間の through の場合
+      @@start_region      = through[ 3 ]
+      if next_cell.get_region.equal? @@start_region then
+        @@end_region      = @@start_region
+      else
+        @@end_region      = through[ 4 ]
+      end
+      @@through_type      = through[ 5 ]
+      @@region_count      = through[ 6 ]
+    else
+      # 呼び口の through の場合
+      @@start_region      = @owner.get_region    # 呼び口側セルの region
+      @@end_region        = next_cell.get_region # 次のセルの region
+      @@through_type      = :THROUGH             # 呼び口の through 指定
+      @@region_count      = 0
+    end
+    @@plugin_creating_join = self
+    caller_cell = @owner
+
+    begin
+      plugin_object = plClass.new( generating_cell_name.to_sym, plugin_arg.to_s,
+                                   next_cell, next_port_name.to_sym, next_port_subscript,
+                                   @definition.get_signature, @celltype, caller_cell )
+      plugin_object.set_locale @locale
+    rescue Exception => evar
+      cdl_error( "S1126 $1: fail to new" , plugin_name )
+      if @celltype && @definition.get_signature && caller_cell && next_cell then
+        print "signature: #{@definition.get_signature.get_name} from: #{caller_cell.get_name} to: #{next_cell.get_name} of celltype: #{@celltype.get_name}\n"
+      end
+      print_exception( evar )
+      return 
+    end
+
+    @through_generated_list[ i ] = plugin_object
+
+    # Region に関する情報を設定
+    # 後から追加したので、new の引数外で設定
+    # plugin_object.set_through_info( start_region, end_region, through_type )
+
+    generate_and_parse plugin_object
+  end
+
+  #プラグインへの引数で渡さないものを、一時的に記憶しておく
+  # プラグインの initialize の中でコールバックして設定する
+  @@plugin_creating_join = nil
+  @@start_region = nil
+  @@end_region = nil
+  @@through_type = nil
+  @@region_count = nil
+
+  #=== Join# ThroughPlugin の追加情報を設定する
+  # このメソッドは ThroughPlugin#initialize から呼び出される
+  # plugin_object を生成する際の引数では不足する情報を追加する
+  def self.set_through_info plugin_object
+    plugin_object.set_through_info( @@start_region, @@end_region, @@through_type,
+                                    @@plugin_creating_join,
+                                    @@plugin_creating_join.get_cell,
+                                    @@region_count )
+  end
+
+  def get_name
+    @name
+  end
+
+  #=== Join#配列添数を得る
+  # @subscript の説明を参照のこと
+  def get_subscript
+    @subscript
+  end
+
+  def get_cell_name         # 受け口セル名
+    @cell_name
+  end
+
+  def get_celltype
+    @celltype
+  end
+
+  def get_cell
+    @cell
+  end
+
+  #=== Join# 右辺の実セルを得る
+  #    実セルとは through で挿入されたもの、composite の内部など実際に結合される先
+  #    このメソッドは　get_rhs_port と対になっている
+  #    このメソッドは、意味解析段階では呼び出してはならない (対象セルの意味解析が済む前には正しい結果を返さない)
+  def get_rhs_cell
+    # through 指定あり？
+    if @through_list[0] then
+      # mikan through で生成したものが root namespace 限定
+      if @through_generated_list[0] then
+        # cell = Namespace.find( [ "::", @through_generated_list[0].get_cell_name.to_sym ] )    #1
+        cell = Namespace.find( @through_generated_list[0].get_cell_namespace_path )    #1
+        # cell が nil になるのはプラグインの get_cell_namespace_path が正しくないか、
+        # プラグイン生成コードがエラーになっている。
+        # できの悪いプラグインが多ければ、cell == nil をはじいた方がよい。
+        return cell.get_real_cell( @through_generated_list[0].get_through_entry_port_name )
+      else
+        return nil            # generate に失敗している
+      end
+    elsif @cell then
+      return @cell.get_real_cell( @port_name )
+    else
+      # 右辺が未定義の場合 @cell は nil (既にエラー)
+      return nil
+    end
+  end
+
+  #=== Join# 右辺のセルを得る
+  # 右辺のセルを得る。ただし、composite 展開されていない
+  # composite 展開されたものを得るには get_rhs_cell を使う
+  # プロトタイプ宣言しかされていない場合には、こちらしか使えない
+  # このメソッドは get_rhs_port2 と対になっている
+  def get_rhs_cell2
+    # through 指定あり？
+    if @through_list[0] then
+      # mikan through で生成したものが root namespace 限定
+      # cell = Namespace.find( [ "::", @through_generated_list[0].get_cell_name ] )
+      if @through_generated_list[0] then
+        # cell = Namespace.find( [ @through_generated_list[0].get_cell_name ] )    #1
+        cell = Namespace.find( @through_generated_list[0].get_cell_namespace_path )    #1
+      else
+        cell = @cell            # generate に失敗している
+      end
+    else
+      cell = @cell
+    end
+
+    return cell
+  end
+
+  #=== Join# 右辺のセルを得る
+  # through は適用しないが、composite は展開した後のセル
+  # (意味解析が終わっていないと、composite 展開が終わっていない)
+  # このメソッドは get_rhs_port3 と対になっている
+  def get_rhs_cell3
+    if @cell then
+      return @cell.get_real_cell( @port_name )
+    end
+  end
+
+  #=== Join# 右辺のセルのリージョンを得る
+  # 右辺が未定義の場合、nil を返す
+  # composite の場合、実セルではなく composite cell の region を返す(composite はすべて同じ region に属する)
+  # composite の cell がプロトタイプ宣言されているとき get_rhs_cell/get_real_cell は ruby の例外となる
+  def get_rhs_region
+    # through 指定あり？
+    if @through_list[0] then
+      if @through_generated_list[0] then
+        # mikan through で生成したものが root namespace 限定
+        # cell = Namespace.find( [ "::", @through_generated_list[0].get_cell_name.to_sym ] )    #1
+        cell = Namespace.find( @through_generated_list[0].get_cell_namespace_path )    #1
+        if cell then
+          return cell.get_region
+        end
+      else
+        return nil       # generate に失敗している
+      end
+    elsif @cell then
+      return @cell.get_region
+    end
+    # 右辺が未定義の場合 @cell は nil (既にエラー)
+    return nil
+  end
+
+  def get_cell_global_name  # 受け口セル名（コンポジットなら展開した内側のセル）
+
+    # debug
+    dbgPrint "cell get_cell_global_name:  #{@cell_name}\n"
+    # @cell.show_tree( 1 )
+
+    if @cell then
+      return @cell.get_real_global_name( @port_name )
+    else
+      return "NonDefinedCell?"
+    end
+
+  end
+
+  #===  Join# 結合の右辺の受け口の名前
+  #     namespace 名 + '_' + セル名 + '_' + 受け口名   （このセルが composite ならば展開後のセル名、受け口名）
+  #subscript:: Integer  呼び口配列の時添数 または nil 呼び口配列でない時
+  def get_port_global_name( subscript = nil )  # 受け口名（コンポジットなら展開した内側のセル）
+
+    # debug
+    dbgPrint "Cell get_port_global_name:  #{@cell_name}\n"
+
+    # through 指定あり？
+    if @through_list[0] then
+
+      # mikan through で生成したものが root namespace 限定
+      # cell = Namespace.find( [ "::", @through_generated_list[0].get_cell_name.to_sym ] )    #1
+      cell = Namespace.find( @through_generated_list[0].get_cell_namespace_path )    #1
+
+      # through で挿入されたセルで、実際に接続されるセル（compositeの場合内部の)の受け口の C 言語名前
+      return cell.get_real_global_port_name( @through_generated_list[0].get_through_entry_port_name )
+    else
+
+      # 実際に接続されるセルの受け口の C 言語名前
+      if @cell then
+        return @cell.get_real_global_port_name( @port_name )
+      else
+        return "UndefinedCellsPort?"
+      end
+
+    end
+
+  end
+
+  def get_port_name
+    @port_name
+  end
+
+  def get_rhs
+    @rhs
+  end
+
+  # 末尾数字1 : CDL で指定された、右辺のセルを返す
+  def get_rhs_cell1   # get_cell と同じ
+    @cell
+  end
+  def get_rhs_port1   # get_port_name 同じ
+    @port_name
+  end
+  def get_rhs_subscript1
+    @rhs_subscript
+  end
+
+  #=== Join# 右辺のポートを得る
+  #    右辺が composite の場合は、内部の繋がるセルのポート, through の場合は挿入されたセルのポート
+  #    このメソッドは get_rhs_cell と対になっている
+  def get_rhs_port
+    # through 指定あり？
+    if @through_list[0] then
+      # through で生成されたセルを探す
+      cell = Namespace.find( @through_generated_list[0].get_cell_namespace_path )    #1
+      # cell のプラグインで生成されたポート名のポートを探す (composite なら内部の繋がるポート)
+      return cell.get_real_port( @through_generated_list[0].get_through_entry_port_name )
+    else
+      # ポートを返す(composite なら内部の繋がるポートを返す)
+      return @cell.get_real_port( @port_name )
+    end
+  end
+
+  #=== Join# 右辺の配列添数を得る
+  #    右辺が through の場合は挿入されたセルの添数
+  #    右辺が composite の場合は、内部の繋がるセルのポートの添数 (composite では変わらない)
+  #    このメソッドは get_rhs_cell,  と対になっている
+  def get_rhs_subscript
+    if @through_list[0] then
+      return @through_generated_list[0].get_through_entry_port_subscript
+    else
+      return @rhs_subscript
+    end
+  end
+
+  #=== Join# 右辺のポートを得る
+  # 右辺のポートを得る。
+  # これはプロトタイプ宣言しかされていない場合には、こちらしか使えない
+  def get_rhs_port2
+    # through 指定あり？
+    if @through_list[0] then
+      if @through_generated_list[0] then
+        port = @through_generated_list[0].get_through_entry_port_name.to_sym
+      else
+        port = @port_name    # generate に失敗している
+      end
+    else
+      port = @port_name
+    end
+
+    return port
+  end
+
+  #=== Join# 右辺のポートを得る
+  # through は適用しないが、composite は展開した後のセルの対応するポート
+  def get_rhs_port3
+    if @cell then
+      return @cell.get_real_port( @port_name )
+    end
+  end
+
+  #=== Join# 呼び口配列の2番目以降の要素を追加する
+  #     一番最初に定義された配列要素が全要素の初期値の配列を持つ
+  #     このメソッドは非配列の場合も呼出される（join 重複エラーの場合）
+  #join2:: Join  呼び口配列要素の Join
+  def add_array_member join2
+
+    # subscript2: join2 の左辺添数
+    subscript2 = join2.get_subscript
+
+    if @subscript == nil then		# not array : initialize duplicate
+      # 非配列の場合、join が重複している
+      cdl_error( "S1127 \'$1\' duplicate", @name )
+      # print "add_array_member2: #{@owner.get_name}\n"
+
+    elsif @subscript >= 0 then
+      # 添数指定ありの場合
+      if( subscript2 == nil || subscript2 < 0 ) then
+        # join2 左辺は非配列または添数なし
+        # 配列が不一致
+        cdl_error( "S1128 \'$1\' inconsistent array definition", @name )
+      elsif @array_member[subscript2] != nil then
+        # 同じ添数が既に定義済み
+        cdl_error( "S1129 \'$1\' redefinition of subscript $2" ,@name, subscript2 )
+      else
+        # 添数の位置に要素を追加
+        @array_member[subscript2] = join2.get_rhs
+        @array_member2[subscript2] = join2
+#        p "0:#{join2.get_rhs}"
+      end
+
+    else
+      # 添数指定なしの場合
+      if( subscript2 == nil || subscript2 >= 0 ) then
+        # join2 左辺は非配列または添数有
+        # 配列が不一致
+        cdl_error( "S1130 \'R1\' inconsistent array definition", @name )
+      end
+
+      # 添数なし配列の場合、配列要素を追加
+      @array_member  << join2.get_rhs
+      @array_member2 << join2
+    end
+  end
+
+  def get_array_member
+    @array_member
+  end
+
+  def get_array_member2
+    @array_member2
+  end
+
+  def change_name name
+    # debug
+    dbgPrint "change_name: #{@name} to #{name}\n"
+
+    @name = name
+
+    if @array_member2 then
+      i = 0
+      while i < @array_member2.length
+        if @array_member2[i] != self && @array_member[i] != nil then
+          # @array_member2[i] が nil になるのは optional の時と、
+          # Join の initialize で無駄に @array_member2 が設定されている場合
+          # 無駄に設定されているものについては、再帰的に呼び出す必要はない（clone_for_composite では対策している）
+          @array_member2[i].change_name( name )
+        end
+        i += 1
+      end
+    end
+  end
+
+  # composite cell を展開したセルの結合を clone したセルの名前に変更
+  def change_rhs_port( clone_cell_list, celltype )
+    dbgPrint "change_rhs_port: name=#{@name}\n"
+
+    # debug
+    if $debug then
+#    if @name == :cCallB then
+      # dbgPrint "change_rhs name: #{@name}  cell_name: #{@cell_name} #{@cell} #{self}\n"
+      print "============\n"
+      print "CHANGE_RHS change_rhs name: #{@owner.get_name}.#{@name}  rhs cell_name: #{@cell_name} #{@cell} #{self}\n"
+
+      clone_cell_list.each{ |cell, ce|
+        # dbgPrint "=== change_rhs:  #{cell.get_name}=#{cell} : #{ce.get_name}\n"
+        print "   CHANGE_RHS  change_rhs:  #{cell.get_name}=#{cell} : #{ce.get_name}\n"
+      }
+      print "============\n"
+    end
+
+    c = clone_cell_list[@cell]
+    return if c == nil
+
+    # debug
+    dbgPrint "  REWRITE cell_name:  #{@owner.get_name}   #{@cell_name} => #{c.get_global_name}, #{c.get_name}\n"
+
+    # @rhs の内容を調整しておく（この内容は、subscript を除いて、後から使われていない）
+    elements = @rhs.get_elements
+    if elements[0] == :OP_SUBSC then  # 右辺：受け口配列？
+      elements  = elements[1]
+    end
+
+    # 右辺が　cell.ePort の形式でない
+    if elements[0] != :OP_DOT || elements[1][0] != :IDENTIFIER then   #1
+      return
+    else
+      # セル名を composite 内部の名前から、外部の名前に入れ替える
+      # elements[1][1] = Token.new( c.get_name, nil, nil, nil )
+      elements[1][1] = NamespacePath.new( c.get_name, false, c.get_namespace )
+    end
+
+    @cell_name = c.get_name
+    @cell = c
+    # @definition = nil          # @definition が有効： チェック済み（とは、しない）
+
+    if @array_member2 then
+
+      # debug
+      dbgPrint "array_member2.len : #{@array_member.length}\n"
+
+      i = 0
+      while i < @array_member2.length
+        # @array_member2[i] が nil になるのは optional の時と、
+        # Join の initialize で無駄に @array_member2 が設定されている場合
+        # 無駄に設定されているものについては、再帰的に呼び出す必要はない（clone_for_composite では対策している）
+        if @array_member2[i] != self && @array_member[i] != nil then
+          dbgPrint "change_rhs array_member #{i}: #{@name}  #{@cell_name}\n"
+          @array_member2[i].change_rhs_port( clone_cell_list, celltype )
+        end
+        i += 1
+      end
+    end
+
+  end
+
+  #=== Join# composite セル用にクローン
+  #cell_global_name:: string : 親セルのグローバル名
+  # 右辺の C_EXP に含まれる $id$, $cell$, $ct$ を置換
+  # ここで置換するのは composite の attribute の C_EXP を composite セルタイプおよびセル名に置換するため
+  # （内部セルの C_EXP もここで置換される）
+  # @through_list などもコピーされるので、これが呼び出される前に確定する必要がある
+  def clone_for_composite( ct_name, cell_name, locale, b_need_recursive = true )
+    # debug
+    dbgPrint "=====  clone_for_composite: #{@name} #{@cell_name} #{self}   =====\n"
+    cl = self.clone
+
+    if @array_member2 && b_need_recursive then
+      cl.clone_array_member( ct_name, cell_name, self, locale )
+    end
+
+    rhs = CDLInitializer.clone_for_composite( @rhs, ct_name, cell_name, locale )
+    cl.change_rhs rhs
+
+    # debug
+    dbgPrint "join cloned : #{cl}\n"
+    return cl
+  end
+
+  def clone_array_member( ct_name, cell_name, prev, locale )
+    # 配列のコピーを作る
+    am  = @array_member.clone
+    am2 = @array_member2.clone
+
+    # 配列要素のコピーを作る
+    i = 0
+    while i < am2.length
+      if @array_member2[i] == prev then
+        # 自分自身である（ので、呼出すと無限再帰呼出しとなる）
+        am2[i] = self
+        am[i] = am2[i].get_rhs
+      elsif @array_member2[i] then
+#        am2[i] = @array_member2[i].clone_for_composite( ct_name, cell_name, locale, false )
+        am2[i] = @array_member2[i].clone_for_composite( ct_name, cell_name, locale, true )
+        am[i] = am2[i].get_rhs
+      else
+        # 以前のエラーで array_member2[i] は nil になっている
+      end
+
+      # debug
+      dbgPrint "clone_array_member: #{@name} subsript=#{i} #{am2[i]} #{@array_member2[i]}\n"
+
+      i += 1
+    end
+
+    # i = 0 は、ここで自分自身を設定
+    # am2[0] = self
+
+    @array_member  = am
+    @array_member2 = am2
+
+  end
+
+  #=== Join# rhs を入れ換える
+  #rhs:: Expression | initializer
+  # 右辺を入れ換える．
+  # このメソッドは、composite で cell の属性の初期値を attribute の値で置き換えるのに使われる
+  # このメソッドは composite 内の cell の属性の初期値が定数ではなく式になった場合、不要になる
+  def change_rhs rhs
+    @rhs = rhs
+  end
+
+  #=== Join# clone された join の owner を変更
+  def set_cloned( owner )
+    dbgPrint "Join#set_cloned: #{@name}  prev owner: #{@owner.get_name} new owner: #{owner.get_name}\n"
+    @owner = owner
+    if @array_member2 then
+      @array_member2.each{ |join|
+        dbgPrint "Joinarray#set_cloned: #{@name}  prev owner: #{join.get_owner.get_name} new owner: #{owner.get_name}\n"
+        join.set_owner owner
+      }
+    end
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "Join: name: #{@name} owner: #{@owner.get_name} id: #{self}"
+    if @subscript == nil then
+    elsif @subscript >= 0 then
+      (indent+1).times { print "  " }
+      puts "subscript: #{@subscript}"
+    else
+      (indent+1).times { print "  " }
+      puts "subscript: not specified"
+    end
+    (indent+1).times { print "  " }
+    puts "rhs: "
+    if @rhs.instance_of?( Array )then
+      @rhs.each{ |i|
+        if i.instance_of?( Array )then
+          i.each{ |j|
+            j.show_tree( indent + 3 )
+          }
+        elsif i.instance_of? Symbol then
+          (indent+2).times { print "  " }
+          print i
+          print "\n"
+        else
+          i.show_tree( indent + 2 )
+        end
+      }
+    else
+      @rhs.show_tree( indent + 2 )
+      (indent+1).times { print "  " }
+      if @definition then
+        puts "definition:"
+        @definition.show_tree( indent + 2 )
+      else
+        puts "definition: not found"
+      end
+    end
+    if @definition.instance_of?( Port ) then
+      (indent+2).times { print "  " }
+      if @cell then
+        puts "cell: #{@cell_name} #{@cell}  port: #{@port_name}  cell_global_name: #{@cell.get_global_name}"
+      else
+        puts "cell: #{@cell_name} port: #{@port_name}  (cell not found)"
+      end
+    end
+    if @through_list then
+      i = 0
+      @through_list.each { |t|
+        (indent+2).times { print "  " }
+        puts "through: plugin name :  '#{t[0]}' arg : '#{t[2]}'"
+        if @through_generated_list[i] then
+          @through_generated_list[i].show_tree( indent+3 )
+        end
+        i += 1
+      }
+    end
+    if @array_member2 then
+      (indent+1).times { print "  " }
+      puts "array member:"
+      i = 0
+      @array_member2.each { |j|
+        if j then
+          (indent+2).times { print "  " }
+          puts "[#{i}]: #{j.get_name}  id: #{j} owner=#{j.get_owner.get_name}"
+          j.get_rhs.show_tree(indent+3)
+#          (indent+3).times { print "  " }
+#          puts "cell global name: #{j.get_cell_global_name}"
+#          puts "cell global name: #{j.get_rhs_cell.get_global_name}"
+#          (indent+3).times { print "  " }
+#          puts "port global name: #{j.get_port_global_name}"
+#          puts "port global name: #{j.get_rhs_port.get_name}"
+        else
+          (indent+2).times { print "  " }
+          puts "[#{i}]: [optional]  id: #{j}"
+        end
+        i += 1
+      }
+    end
+  end
+
+end
+
+#== 逆結合
+class ReverseJoin < BDNode
+#@ep_name:: Symbol
+#@ep_subscript:: Expression or nil
+#@cell_nsp: NamespacePath
+#@cp_name:: Symbol
+#@cp_subscript:: Expression or nil
+  def initialize( ep_name, ep_subscript, cell_nsp, cp_name, cp_subscript = nil )
+    super()
+    @ep_name = ep_name
+    @ep_subscript = ep_subscript
+    @cell_nsp = cell_nsp
+    @cp_name = cp_name
+    @cp_subscript = cp_subscript
+  end
+
+  def get_name
+    @ep_name
+  end
+
+  def get_rhs_cell_and_port
+    [ @ep_subscript, @cell_nsp, @cp_name, @cp_subscript ]
+  end
+end
+
+# CLASS: CompositeCelltype 用の Join
+# REM:   CompositeCelltype が export するもの
+class CompositeCelltypeJoin < BDNode
+# @export_name:: string     :  CompositeCelltype が export する名前（呼び口、受け口、属性）
+# @internal_cell_name:: string : CompositeCelltype 内部のセルの名前
+# @internal_cell_elem_name:: string : CompositeCelltype 内部のセルの呼び口、受け口、属性の名前
+# @cell : Cell : Cell::  internal cell  : CompositeCelltyep 内部のセル（in_compositeセル）
+# @port_decl:: Port | Decl
+# @b_pseudo: bool : 
+
+  def initialize( export_name, internal_cell_name,
+		 internal_cell_elem_name, cell, port_decl )
+    super()
+    @export_name = export_name
+    @internal_cell_name = internal_cell_name
+    @internal_cell_elem_name = internal_cell_elem_name
+    @cell = cell
+    @port_decl = port_decl
+
+  end
+
+  #=== CompositeCelltypeJoin# CompositeCelltypeJoin の対象セルか？
+  #cell::  Cell 対象かどうかチェックするセル
+  #
+  #     CompositeCelltypeJoin と cell の名前が一致するかチェックする
+  #     port_decl が指定された場合は、現状使われていない
+  def match?( cell, port_decl = nil )
+
+    #debug
+    if port_decl
+      dbgPrint(  "match?"  )
+      dbgPrintf( "  @cell:      %-20s      %08x\n", @cell.get_name, @cell.object_id )
+      dbgPrintf( "  @port_decl: %-20s      %08x\n", @port_decl.get_name, @port_decl.object_id )
+      dbgPrintf( "  cell:       %-20s      %08x\n", cell.get_name, cell.object_id )
+      dbgPrintf( "  port_decl:  %-20s      %08x\n", port_decl.get_name, port_decl.object_id )
+      dbgPrint(  "  cell_name: #{cell.get_name.class}=#{cell.get_name} cell_elem_name: #{port_decl.get_name.class}=#{port_decl.get_name}\n" )
+      dbgPrint(  "  @cell_name: #{@cell.get_name.class}=#{@cell.get_name} cell_elem_name: #{@port_decl.get_name.class}=#{@port_decl.get_name}\n" )
+
+    end
+
+#    if @cell.equal?( cell ) && ( port_decl == nil || @port_decl.equal?( port_decl ) ) then
+    # なぜ port_decl が一致しなければならなかったか忘れた。
+    # recursive_composite で名前の一致に変更   060917
+    if((@cell.get_name == cell.get_name) && (port_decl == nil || @port_decl.get_name == port_decl.get_name))then
+      true
+    else
+      false
+    end
+  end
+
+  def check_dup_init
+    return if get_port_type != :CALL
+
+    if @cell.get_join_list.get_item @internal_cell_elem_name then
+      cdl_error( "S1131 \'$1.$2\' has duplicate initializer" , @internal_cell_name, @internal_cell_elem_name )
+    end
+  end
+
+  def get_name
+    @export_name
+  end
+
+  def get_cell_name
+    @internal_cell_name
+  end
+
+  def get_cell
+    @cell
+  end
+
+  def get_cell_elem_name
+    @internal_cell_elem_name
+  end
+
+  # @port_decl が Port の場合のみ呼び出してよい
+  def get_port_type
+    if @port_decl then
+      @port_decl.get_port_type
+    end
+  end
+
+  def get_port_decl
+    @port_decl
+  end
+
+  #=== CompositeCelltypeJoin#get_allocator_instance
+  def get_allocator_instance
+    if @port_decl.instance_of? Port then
+      return @port_decl.get_allocator_instance
+    elsif @port_decl
+      raise "CompositeCelltypeJoin#get_allocator_instance: not port"
+    else
+      return nil
+    end
+  end
+
+  # @port_decl が Port の場合のみ呼び出してよい
+  def is_require?
+    if @port_decl then
+      @port_decl.is_require?
+    end
+  end
+
+  # @port_decl が Port の場合のみ呼び出してよい
+  def is_allocator_port?
+    if @port_decl then
+      @port_decl.is_allocator_port?
+    end
+  end
+
+  # @port_decl が Port の場合のみ呼び出してよい
+  def is_optional?
+    if @port_decl then
+      @port_decl.is_optional?
+    end
+  end
+
+  #=== CompositeCelltypeJoin# 右辺が Decl ならば初期化子（式）を返す
+  # このメソッドは Cell の check_join から初期値チェックのために呼び出される
+  def get_initializer
+    if @port_decl.instance_of? Decl then
+      @port_decl.get_initializer
+    end
+  end
+
+  def get_size_is
+    if @port_decl.instance_of? Decl then
+      @port_decl.get_size_is
+    end
+  end
+
+  #=== CompositeCelltypeJoin# 配列サイズを得る
+  #RETURN:: nil: not array, "[]": 大きさ指定なし, Integer: 大きさ指定あり
+  def get_array_size
+    @port_decl.get_array_size
+  end
+
+  #=== CompositeCelltypeJoin# signature を得る
+  # @port_decl が Port の時のみ呼び出してもよい
+  def get_signature
+    @port_decl.get_signature
+  end
+
+  #=== CompositeCelltypeJoin# get_type
+  def get_type
+    if @port_decl.instance_of? Decl
+      @port_decl.get_type
+    end
+  end
+
+  #=== CompositeCelltypeJoin# get_initializer
+  def get_initializer
+    if @port_decl.instance_of? Decl
+      @port_decl.get_initializer
+    end
+  end
+
+  #=== CompositeCelltypeJoin# get_choice_list
+  def get_choice_list
+    if @port_decl.instance_of? Decl
+      @port_decl.get_choice_list
+    end
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "CompositeCelltypeJoin: export_name: #{@export_name} #{self}"
+    (indent+1).times { print "  " }
+    puts "internal_cell_name: #{@internal_cell_name}"
+    (indent+1).times { print "  " }
+    puts "internal_cell_elem_name: #{@internal_cell_elem_name}"
+    if @port_decl then
+      @port_decl.show_tree( indent + 1 )
+    end
+  end
+end
+
+class Factory < BDNode
+# @name:: string
+# @file_name:: string
+# @format:: string
+# @arg_list:: Expression の elements と同じ形式 [ [:IDENTIFIER, String], ... ]
+# @f_celltype:: bool : true: celltype factory, false: cell factory
+
+  @@f_celltype = false
+
+  def initialize( name, file_name, format, arg_list )
+    super()
+    @f_celltype = @@f_celltype
+
+    case name
+    when :write
+      # write 関数
+      @name = name
+
+      # write 関数の第一引数：出力先ファイル名
+        # 式を評価する（通常単一の文字列であるから、単一の文字列が返される）
+      @file_name = file_name.eval_const(nil).val  # file_name : Expression
+      if ! @file_name.instance_of?( String ) then
+        # 文字列定数ではなかった
+        cdl_error( "S1132 $1: 1st parameter is not string(file name)" , @name )
+        @file_name = nil
+      end
+
+      # write 関数の第二引数：フォーマット文字列
+      @format    = format.eval_const(nil).val     # format : Expression
+        # 式を評価する（通常単一の文字列であるから、単一の文字列が返される）
+      if ! @format.instance_of?( String ) then
+        # 文字列定数ではなかった
+        cdl_error( "S1133 $1: 2nd parameter is not string(fromat)" , @name )
+        @format = nil
+      end
+
+      # 第三引数以降を引数リストとする mikan 引数のチェック
+      @arg_list = arg_list
+
+    else
+      cdl_error( "S1134 $1: unknown factory function" , name )
+    end
+    Celltype.new_factory( self )
+  end
+
+  def check_arg( celltype )
+    if ! @arg_list then
+      return
+    end
+
+    if @f_celltype then
+      cdl_error( "S1135 celltype factory can\'t have parameter(s)"  )
+      return
+    end
+
+    @arg_list.each{ |elements|
+
+      case elements[0]
+      when :IDENTIFIER  #1
+        obj = celltype.find( elements[1] )
+        if obj == nil then
+          cdl_error( "S1136 \'$1\': not found" , elements[1] )
+        elsif ! obj.instance_of?( Decl ) || obj.get_kind != :ATTRIBUTE then
+          cdl_error( "S1137 \'$1\': not attribute" , elements[1] )
+        end
+      when :STRING_LITERAL
+      else
+        cdl_error( "S1138 internal error Factory.check_arg()"  )
+      end
+
+    }
+  end
+
+  def self.set_f_celltype( f_celltype )
+    @@f_celltype = f_celltype
+  end
+
+  def get_f_celltype
+    @f_celltype
+  end
+
+  def get_name
+    @name
+  end
+
+  def get_file_name
+    @file_name
+  end
+
+  def get_format
+    @format
+  end
+
+  def get_arg_list
+    @arg_list
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "Factory: name: #{@name}"
+    if @arg_list then
+      (indent+1).times { print "  " }
+      puts "argument(s):"
+      @arg_list.each { |l|
+        (indent+2).times { print "  " }
+        print "\"#{l}\"\n"
+      }
+    end
+  end
+end
+
+#== DomainType
+#
+# region の domain を記憶するクラス
+class DomainType < Node
+#@name::Symbol : ドメインタイプの名前 ex) HRP2
+#@region::Region
+#@plugin_name::Symbol : ex) HRP2Plugin
+#@option::String : ex) "trusted", "nontrusted"
+#@plugin::DomainPlugin の子クラス
+
+  include PluginModule
+
+  # ドメインに属する region の Hash
+  # domain 指定が一度も行われない場合、このリストは空である
+  # ルートリージョンは option = "OutOfDomain" で登録される (domain 指定が無ければ登録されない)
+  @@domain_regions = { }  # { :domain_type => [ region, ... ] }
+
+  def initialize( region, name, option )
+    super()
+    @name = name
+    @plugin_name = (name.to_s + "Plugin").to_sym
+    plClass = load_plugin( @plugin_name, DomainPlugin )
+    @region = region
+    @option = option
+
+    if @@domain_regions[ name ] then
+      if ! @@domain_regions[ name ].include?( region ) then
+        @@domain_regions[ name ] << region
+      end
+    else
+      @@domain_regions[ name ] = [ region ]
+    end
+  end
+
+  def create_domain_plugin
+    if ! @plugin then
+      pluginClass = Object.const_get @plugin_name
+      return if pluginClass == nil
+      @plugin = pluginClass.new( @region, @name, @option )
+      @plugin.set_locale @locale
+    end
+  end
+
+  def add_through_plugin( join, from_region, to_region, through_type )
+    # print( "DOMAIN: add_through_plugin: from=#{from_region.get_name}#{join.get_owner.get_name}.#{join.get_name} to=#{to_region}#{join.get_cell.get_name}.#{join.get_port_name} through_type=#{through_type}\n" )
+    return @plugin.add_through_plugin( join, from_region, to_region, through_type )
+  end
+
+  def joinable?( from_region, to_region, through_type )
+    # print( "DOMAIN: joinable? from_region=#{from_region.get_name} to_region=#{to_region} through_type=#{through_type}\n" )
+    return @plugin.joinable?( from_region, to_region, through_type )
+  end
+
+  def get_name
+    @name
+  end
+
+  #== DomainType リージョンの Hash を得る
+  # @@domain_regions の説明参照
+  def self.get_domain_regions
+    return @@domain_regions
+  end
+
+  def get_regions
+    return @@domain_regions[ @name ]
+  end
+
+  def get_option
+    @option
+  end
+
+  #== DomainType#ドメイン種別を得る
+  #return::Symbol :kernel, :user, :OutOfDomain
+  def get_kind
+    @plugin.get_kind
+  end
+
+  def show_tree( indent )
+    (indent+1).times { print( "  " ) }
+    puts "domain: name=#{@name} plugin=#{@plugin_name} option=#{@option}"
+  end
+end
+
+#== Region クラス
+# 
+# Region は Namespace を継承している
+# root region は特殊で、root namespace と同じである
+#
+# cell は region に属する
+# region に属する cell のリストは Namespace クラスのインスタンス変数として記憶される
+#
+class Region < Namespace
+# @name:: string
+# @in_through_list:: [ [ plugin_name, plugin_arg ], ... ] : plungin_name = nil の時 in 禁止
+# @out_through_list:: [ [ plugin_name, plugin_arg ], ... ] : plungin_name = nil の時 out 禁止
+# @to_through_list:: [ [ dst_region, plugin_name, plugin_arg ], ... ]
+# @cell_port_throug_plugin_list:: { "#{cell_name}.#{port_name}" => through_generated_list の要素 }
+#    この region から cell_name.port_name への through プラグインで生成されたオブジェクト
+# @region_type::Symbol : :NODE, :LINKUNIT, :DOMAIN, :CLASS
+# @region_type_param::Symbol : domain, class の名前. node, linkunit では nil
+# @link_root:: Region : linkUnit の根っことなる region (node, linkunit が指定された region)
+# @family_line:: [ @region_root, ...,@region_me ]  家系
+# @in_through_count:: Integer :  n 番目の in_through 結合 (n>=0)
+# @out_through_count:: Integer : n 番目の out_through 結合 (n>=0)
+# @to_through_count:: { :RegionName => Integer }: RegionName への n 番目の to_through 結合 (n>=0)
+# @domain_type::DomainType : domain 指定されていない場合、nil
+# @domain_root::Region : domain 指定されていなる Region (root の場合 nil)
+
+  @@in_through_list  = []
+  @@out_through_list = []
+  @@to_through_list  = []
+  @@region_type = nil
+  @@region_type_param = nil
+  @@domain_name = nil
+  @@domain_option = nil    # Token が入る
+
+  @@link_roots = []
+
+  def initialize( name )
+    # mikan name の Namespace 修飾
+    # object = Namespace.find( [ name ] )   # 親まで捜しにいく
+    if name != "::" then
+      object = Namespace.get_current.find( name )    #1
+    else
+      # root リージョン
+      object = nil
+      @@region_type = :NODE
+    end
+
+    @in_through_list    = @@in_through_list
+    @out_through_list   = @@out_through_list
+    @to_through_list    = @@to_through_list
+    @region_type        = @@region_type
+    @region_type_param  = @@region_type_param
+
+    if @@domain_name then
+      dbgPrint "Region=#{name} domain_type=#{@@domain_name} option=#{@@domain_option}\n"
+      domain_option = CDLString.remove_dquote @@domain_option.to_s
+      @domain_type = DomainType.new( self, @@domain_name, domain_option )
+      @@domain_name       = nil
+      @@domain_option     = nil
+    else
+      @domain_type = nil
+    end
+
+    @@in_through_list   = []
+    @@out_through_list  = []
+    @@to_through_list   = []
+    @@region_type       = nil
+    @@region_type_param = nil
+
+    @in_through_count = -1
+    @out_through_count = -1
+    @to_through_count = {}
+
+    super( name )
+    if object then
+
+      if object.instance_of?( Region ) then
+        dbgPrint "Region.new: re-appear #{@name}\n"
+
+        # # Region path が前回出現と一致するか？
+        # if @@region_stack[ @@region_stack_sp - 1 ] then
+        #   my_path = @@region_stack[ @@region_stack_sp - 1 ].get_path_string.to_s + "." + @name.to_s
+        # else
+        #   my_path = @name.to_s
+        # end
+        # if my_path != object.get_path_string then
+        #   cdl_error( "S1139 $1: region path mismatch. previous path: $2" , my_path, object.get_path_string )
+        # end
+
+        # 再出現
+        # @@region_stack[@@region_stack_sp] = object
+
+        # 再出現時に specifier が指定されているか？
+        if( @in_through_list.length != 0 || @out_through_list.length != 0 || @to_through_list.length != 0 ||
+            @region_type != nil || @domain_type != nil )then
+          cdl_error( "S1140 $1: region specifier must place at first appearence" , name )
+        end
+        return
+
+      else
+        # エラー用ダミー定義
+
+        # 異なる同名のオブジェクトが定義済み
+        cdl_error( "S1141 $1 duplication, previous one : $2" , name, object.class )
+        # @@region_stack[@@region_stack_sp] = self    # エラー時暫定 region
+      end
+    else
+      # 初出現
+      dbgPrint "Region.new: #{@name}\n"
+      set_region_family_line
+
+      if @region_type == :NODE || @region_type == :LINKUNIT then
+        dbgPrint "new LinkRoot: #{@name}\n"
+        @@link_roots << self
+      end
+    end
+
+    @cell_port_throug_plugin_list = {}
+
+# p @name
+# p @in_through_list
+# p @out_through_list
+# p @to_through_list
+
+  end
+
+  def self.end_of_parse
+    Namespace.get_current.create_domain_plugin
+    Namespace.get_current.end_of_parse
+  end
+
+  def self.new_in_through( plugin_name = nil, plugin_arg = nil )
+    @@in_through_list << [ plugin_name, plugin_arg ]
+  end
+
+  def self.new_out_through( plugin_name = nil, plugin_arg = nil )
+    @@out_through_list << [ plugin_name, plugin_arg ]
+  end
+
+  def self.new_to_through( dst_region, plugin_name, plugin_arg )
+    # p "New to_through #{dst_region}"
+    @@to_through_list  << [ dst_region, plugin_name, plugin_arg ]
+  end
+
+  def self.set_type( type, param = nil )
+    if @@region_type then
+      Generator.error( "S1178 $1 region type specifier duplicate, previous $2", type, @@region_type )
+    end
+    @@region_type = type
+    @@region_type_param = param
+  end
+
+  def self.set_domain( name, option )
+    if @@domain_name then
+      Generator.error( "S9999 $1 domain specifier duplicate, previous $2", type, @@region_type )
+    end
+    @@domain_name = name
+    @@domain_option = option
+  end
+
+  #== Region ルートリージョンを得る
+  # ルートリージョンは、ルートネームスペースと同じである
+  def self.get_root
+    Namespace.get_root
+  end
+
+  def set_region_family_line
+
+    dbgPrint  "set_region_family_line: Region: #{@name}  \n"
+    # root namespace (root region) の region type は :NODE
+    if @name == "::" then
+      @region_type = :NODE
+    end
+
+    if @region_type == :NODE || @region_type == :LINKUNIT then
+      @link_root = self
+    else
+      @link_root = @owner.get_link_root
+    end
+
+    if @domain_type != nil || @owner == nil then
+      @domain_root = self
+    else
+      @domain_root = @owner.get_domain_root
+    end
+
+    if @domain_type then
+      # ルートリージョンが最初から @domain_type 設定されることはないの
+      # で @owner == nil を調べる必要はない
+      @owner.set_domain_type @domain_type
+    end
+
+    if @owner then
+      @family_line = ( @owner.get_family_line.dup ) << self
+    else
+      @family_line = [ self ]    # root region
+    end
+
+=begin
+    @family_line = []
+    @link_root = nil
+
+    # @family_line を作成する
+    # @link_root もみつける
+    # (上位にたどっていって Region で node または linkunit のいずれか先に見つかったものが @link_root となる)
+    # root namespace は Region かつ node なので必ず @link_root は見つかる
+    # mikan: self が node, linkUnit の場合、ここで期待したとおりに設定されないため、Region#initialize で再設定
+    obj = self
+    while 1
+      if obj.instance_of? Region then
+        @family_line << obj
+        if @link_root == nil then
+          if obj.get_region_type == :NODE || obj.get_region_type == :LINKUNIT then
+            @link_root = obj
+          end
+        end
+      else
+        # さもなければ Namespace
+        # namespace の下に region がある場合
+      end
+
+      # root namespace にたどり着けば終り
+      break if obj.get_name == "::"
+
+      obj = obj.get_owner
+    end
+    # print "#{@name}: linkRoot: #{@link_root.get_name}  (this can be wrong if #{@name} is node or linkunit, and corret later\n"
+    @family_line.reverse!
+=end
+
+  end
+
+  #== Region#ドメインを設定する
+  def set_domain_type domain_type
+    if @region_type == :NODE then
+      if @domain_type then
+        if @domain_type.get_name != domain_type.get_name then
+          cdl_error( "S9999 '$1' node root cannot belong to both $2 and $3", @name, @domain_type.get_name, domain_type.get_name )
+        end
+      else
+        @domain_type = DomainType.new( self, domain_type.get_name, "OutOfDomain" )
+        @domain_type.create_domain_plugin
+      end
+    elsif @domain_type == nil then
+      @owner.set_domain_type domain_type
+    end
+  end
+
+  def self.get_link_roots
+    @@link_roots
+  end
+
+  def get_family_line
+    @family_line
+  end
+
+  def get_in_through_list
+    @in_through_list
+  end
+
+  def get_out_through_list
+    @out_through_list
+  end
+
+  def get_to_through_list
+    @to_through_list
+  end
+
+  def get_link_root
+    @link_root
+  end
+
+  def get_domain_type
+    @domain_type
+  end
+
+  #== Region# domain の根っことなる region を得る
+  # Region のインスタンスを返す
+  # domain 指定子があれば、そのリージョンがドメインルートである
+  # なければ、親リージョンのドメインルートとする
+  def get_domain_root
+    @domain_root
+  end
+
+  def get_path_string
+    pstring = ""
+    delim = ""
+    @family_line.each{ |p|
+      pstring = "#{pstring}#{delim}#{p.get_name}"
+      delim = "."
+    }
+    dbgPrint "get_path_string: #{pstring}\n"
+    pstring
+  end
+
+  def get_region_type
+    @region_type
+  end
+
+  def get_name
+    @name
+  end
+
+  #== Region# ルートリージョン
+  # ルートリージョンは、namespace のルートと同じインスタンス
+  def selfget_root
+    Namespace.get_root
+  end
+
+  def next_in_through_count
+    @in_through_count += 1
+  end
+
+  def next_out_through_count
+    @out_through_count += 1
+  end
+
+  def next_to_through_count( symRegionName )
+    if @to_through_count[ symRegionName ] == nil then
+      @to_through_count[ symRegionName ] = 0
+    else
+      @to_through_count[ symRegionName ] += 1
+    end
+  end
+
+  #=== Region# 構文解析中の region を得る
+  # 構文解析中 Namespace (あるいは子クラスの Region) の上位をたどって Region を見つける
+  # cell が namespace 下におくことができなければ、ループをまわす必要はない
+  def self.get_current
+    # @@region_stack[@@region_stack_sp]
+    region = Namespace.get_current
+    while 1
+      if region.instance_of? Region
+        break
+      end
+      region = region.get_owner
+    end
+    return region
+  end
+
+  #=== Region# through プラグインで、この region から cell_name.port_name へのプラグインオブジェクトを登録
+  # mikan namesppace 対応 (cell_name)
+  def add_cell_port_through_plugin( cell_name, port_name, subscript, through_plugin_object )
+    if subscript then
+      subscript = '[' + subscript.to_s + ']'
+    end
+    @cell_port_throug_plugin_list[ "#{cell_name}.#{port_name}#{subscript}" ] = through_plugin_object
+  end
+
+  def find_cell_port_through_plugin( cell_name, port_name, subscript )
+    if subscript then
+      subscript = '[' + subscript.to_s + ']'
+    end
+    return @cell_port_throug_plugin_list[ "#{cell_name}.#{port_name}#{subscript}" ]
+  end
+
+  def create_domain_plugin
+    if @domain_type then
+      @domain_type.create_domain_plugin
+    end
+  end
+
+  #=== Region# to_region への距離（unreachable な場合 nil)
+  # mikan Cell#check_region とRegion へたどり着くまでための処理に共通性が高い
+  # region#distance は require で用いられる
+  def distance( to_region )
+
+    r1 = self                   # 出発 region
+    r2 = to_region              # 目的 region
+    dist = 0
+
+    if ! r1.equal? r2 then      # 同一 region なら呼出し可能
+
+      # mikan namespace 対応
+      f1 = r1.get_family_line
+      len1 = f1.length
+      f2 = r2.get_family_line
+      len2 = f2.length
+
+      # 不一致になるところ（兄弟）を探す
+      i = 1  # i = 0 は :RootRegion なので必ず一致
+      while( i < len1 && i < len2 )
+        if( f1[i] != f2[i] )then
+          break
+        end
+        i += 1
+      end
+
+      sibling_level = i     # 兄弟となるレベル、もしくはどちらか一方が終わったレベル
+
+      # p "sibling_level: #{i}"
+      # p "from: #{f1[i].get_name}" if f1[i]
+      # p "to: #{f2[i].get_name}" if f2[i]
+
+      # 呼び側について呼び元のレベルから兄弟レベルまで（out_through をチェックおよび挿入）
+      i = len1 -1
+      while i >= sibling_level
+        dbgPrint "going out from #{f1[i].get_name} level=#{i}\n"
+        # print "DOMAIN: going out from #{f1[i].get_name} level=#{i}\n"
+        domain = f1[i].get_domain_type
+        domain_ok = false
+        if domain then
+          if ! f1[i].get_domain_type.joinable?( f1[i], f1[i-1], :OUT_THROUGH ) then
+            return nil
+          end
+          domain_ok = true
+        end
+        if ! domain_ok then
+          out_through_list = f1[i].get_out_through_list   # [ plugin_name, plugin_arg ]
+          if out_through_list.length == 0 then
+            return nil
+          end
+        end
+        i -= 1
+        dist += 1
+      end
+
+      # 兄弟レベルにおいて（to_through をチェックおよび挿入）
+      if f1[sibling_level] && f2[sibling_level] then
+        dbgPrint "going from #{f1[sibling_level].get_name} to #{f2[sibling_level].get_name}\n"
+        # print "DOMAIN: going from #{f1[sibling_level].get_name} to #{f2[sibling_level].get_name}\n"
+        domain = f1[sibling_level].get_domain_type
+        domain_ok = false
+        if domain then
+          if ! f1[i].get_domain_type.joinable?( f1[i], f1[i-1], :TO_THROUGH ) then
+            return nil
+          end
+          domain_ok = true
+        end
+        if ! domain_ok then
+          found = 0
+          f1[sibling_level].get_to_through_list.each { |t|
+            if t[0][0] == f2[sibling_level].get_name then   # region 名が一致するか ?
+              found = 1
+            end
+          }
+          if found == 0 then
+            return nil
+          end
+        end
+        dist += 1
+      end
+
+      # 受け側について兄弟レベルから受け側のレベルまで（in_through をチェックおよび挿入）
+      i = sibling_level
+      while i < len2
+        dbgPrint "going in to #{f2[i].get_name} level=#{i}\n"
+        # print "DOMAIN: going in to #{f2[i].get_name} level=#{i}\n"
+        domain = f2[i].get_domain_type
+        domain_ok = false
+        if domain then
+          if ! f2[i].get_domain_type.joinable?( f2[i-1], f2[i], :IN_THROUGH ) then
+            return nil
+          end
+          domain_ok = true
+        end
+        if ! domain_ok then
+          in_through_list = f2[i].get_in_through_list   # [ plugin_name, plugin_arg ]
+          if in_through_list.length == 0 then
+            return nil
+          end
+        end
+        i += 1
+        dist += 1
+      end
+    end
+
+    dbgPrint "dsitance=#{dist} from #{r1.get_name} to #{r2.get_name}\n"
+
+    return dist
+  end
+
+  def show_tree( indent )
+    super
+    (indent+1).times { print( "  " ) }
+    puts "path: #{get_path_string}"
+    (indent+1).times { print( "  " ) }
+    puts "namespace: #{@namespace ? @namespace.get_name : "nil"}  owner: #{@owner.class}.#{@owner ? @owner.get_name : "nil"}"
+    if @domain
+      @domain.show_tree( indent+1 )
+    end
+  end
+end
+
+#== Importable class
+# this module is included by Import_C and Import
+module Importable
+#@last_base_dir::String
+
+  #=== Importable#find_file
+  #file::String : file name to find
+  #return::String | Nil: path to file or nil if not found
+  #find file in 
+  def find_file file
+    $import_path.each{ |path|
+      if path == "."
+        pt = file
+      else
+        pt = "#{path}/#{file}"
+      end
+      if File.exist?( pt )
+        if ! $base_dir[ Dir.pwd ]
+          $base_dir[ Dir.pwd ] = true
+        end
+        if $verbose then
+          print "#{file} is found in #{path}\n"
+        end
+        @last_base_dir = nil
+        dbgPrint "base_dir=. while searching #{file}\n"
+        return pt
+      end
+    }
+
+    $base_dir.each_key{ |bd|
+      $import_path.each{ |path|
+#        if path =~ /\A\// || path =~ /\A[a-zA-Z]:/
+          pt = "#{path}/#{file}"
+#        else
+#          pt = "#{bd}/#{path}/#{file}"
+#        end
+        begin
+          Dir.chdir $run_dir
+          Dir.chdir bd
+          if File.exist?( pt )
+            if $verbose then
+              print "#{file} is found in #{bd}/#{path}\n"
+            end
+            @last_base_dir = bd
+            dbgPrint "base_dir=#{bd} while searching #{file}\n"
+            $base_dir[ bd ] = true
+            return pt
+          end
+        rescue
+        end
+      }
+    }
+    @last_base_dir = nil
+    dbgPrint "base_dir=. while searching #{file}\n"
+    return nil
+  end
+
+  def get_base_dir
+    return @last_base_dir
+    $base_dir.each{ |bd, flag|
+      if flag == true
+        return bd
+      end
+    }
+    return nil
+  end
+end
+
+class Import_C < Node
+
+  # ヘッダの名前文字列のリスト
+  @@header_list = {}
+  @@header_list2 = []
+  @@define_list = {}
+
+  include Importable
+
+  #=== Import_C# import_C の生成（ヘッダファイルを取込む）
+  #header:: Token : import_C の第一引数文字列リテラルトークン
+  #define:: Token : import_C の第二引数文字列リテラルトークン
+  def initialize( header, define = nil )
+    super()
+    # ヘッダファイル名文字列から前後の "" を取り除く
+    # header = header.to_s.gsub( /\A"(.*)"\z/, '\1' )
+    header = CDLString.remove_dquote header.to_s
+
+    if define then
+      # 前後の "" を取り除く
+      # def_opt = define.to_s.gsub( /\A"(.*)/, '\1' )
+      # def_opt.sub!( /(.*)"\z/, '\1' )
+      def_opt = CDLString.remove_dquote define.to_s
+
+      # "," を -D に置き換え
+      def_opt = def_opt.gsub( /,/, " -D " )
+
+      # 先頭に -D を挿入 # mikan 不適切な define 入力があった場合、CPP 時にエラー
+      def_opt = def_opt.gsub( /^/, "-D " )
+
+    end
+
+    # コマンドライン指定された DEFINE 
+    $define.each{ |define|
+      if $IN_EXERB then
+        q = ""
+      else
+        if define =~ /'/ then
+          q = '"'
+        else
+          q = "'"
+        end
+      end
+      def_opt = "#{def_opt} -D #{q}#{define}#{q}"
+    }
+
+    header_path = find_file header
+
+=begin
+    include_opt = ""
+    found = false
+    header_path = ""
+    $import_path.each{ |path|
+      include_opt = "#{include_opt} -I #{path}"
+      if found == false then
+        begin
+          # ファイルの stat を取ってみる(なければ例外発生)
+          File.stat( "#{path}/#{header}" )
+
+          # cdl を見つかったファイルパスに再設定
+          header_path = "#{path}/#{header}"
+          found = true
+        rescue => evar
+          found = false
+          # print_exception( evar )
+        end
+      end
+    }
+
+    if found == false then
+=end
+    if header_path == nil then
+      cdl_error( "S1142 $1 not found in search path" , header )
+      return
+    end
+
+    include_opt = ""
+    if get_base_dir then
+      base = get_base_dir + "/"
+    else
+      base = ""
+    end
+    $import_path.each{ |path|
+      include_opt = "#{include_opt} -I #{base}#{path}"
+    }
+
+    # 読込み済み？
+    if( @@header_list[ header ] ) then
+      # 第二引数 define が以前と異なる
+      if @@define_list[ header ].to_s != define.to_s then
+        cdl_error( "S1143 import_C: arg2: mismatch with previous one"  )
+      end
+      # いずれにせよ読み込まない
+      return
+    end
+
+    # ヘッダのリストを記録
+    @@header_list[ header ] = header_path
+    @@header_list2 << header
+    @@define_list[ header ] = define
+
+    if $verbose then
+      print "import_C header=#{header_path}, define=#{define}\n"
+    end
+
+    begin
+      tmp_C = "#{$gen}/tmp_C_src.c"
+      file = File.open( tmp_C, "w" )
+    rescue => evar
+      cdl_error( "S1144 $1: temporary C source: open error" , tmp_C )
+      print_exception( evar )
+    end
+
+    begin
+      print_defines file
+
+      file.print( "#include \"#{header}\"\n" )
+    rescue => evar
+      cdl_error( "S1145 $1: temporary C source: writing error" , tmp_C )
+      print_exception( evar )
+    ensure
+      file.close
+    end
+
+    # CPP 出力用 tmp ファイル名
+    tmp_header = header.gsub( /\//, "_" )
+    tmp_header = "#{$gen}/tmp_#{tmp_header}"
+
+    # CPP コマンドラインを作成
+    cmd = "#{$cpp} #{def_opt} #{include_opt} #{tmp_C}"
+
+    begin
+      if( $verbose )then
+        puts "CPP: #{cmd}"
+      end
+
+      # プリプロセッサコマンドを pipe として開く
+          # cmd は cygwin/Linux では bash(sh) 経由で実行される
+          # Exerb 版では cmd.exe 経由で実行される
+          # この差は引き数の (), $, % などシェルの特別な文字の評価に現れるので注意
+          cpp = IO.popen( cmd, "r:ASCII-8BIT" )
+      begin
+        tmp_file = nil
+        tmp_file = File.open( tmp_header, "w:ASCII-8BIT" )
+        cpp.each { |line|
+          line = line.gsub( /^#(.*)$/, '/* \1 */' )
+          tmp_file.puts( line )
+        }
+      rescue => evar
+        cdl_error( "S1146 $1: error occured while CPP" , header )
+        print_exception( evar )
+      ensure
+        tmp_file.close if tmp_file    # mikan File.open に失敗した時 tmp_file == nil は保証されている ?
+        cpp.close
+      end
+    rescue => evar
+      cdl_error( "S1147 $1: popen for CPP failed" , header )
+      print_exception( evar )
+    end
+
+    # C 言語のパーサインスタンスを生成
+    c_parser = C_parser.new
+
+    # tmp_header をパース
+    c_parser.parse( [tmp_header] )
+
+    # 終期化　パーサスタックを戻す
+    c_parser.finalize
+
+  end
+
+  def print_defines file
+    if ! $b_no_gcc_extension_support then
+      
+    file.print <<EOT
+
+#ifndef TECS_NO_GCC_EXTENSION_SUPPORT
+
+/*
+ * these extension can be eliminated also by spefcifying option
+ * --no-gcc-extension-support for tecsgen.
+ */
+#ifdef __GNUC__
+
+#ifndef __attribute__
+#define __attribute__(x)
+#endif
+
+#ifndef __extension__
+#define __extension__
+#endif
+
+#ifndef __builtin_va_list
+#define __builtin_va_list va_list
+#endif
+
+#ifndef __asm__
+#define __asm__(x)
+#endif
+
+#ifndef restrict
+#define restrict
+#endif
+
+#endif /* ifdef __GNUC__ */
+#endif /* TECS_NO_GCC_EXTENSION_SUPPORT */
+EOT
+    end
+
+    file.print <<EOT
+
+/* va_list is not supported in C_parser.y.rb */
+typedef struct { int dummy; } va_list;
+
+EOT
+  end
+
+  def self.get_header_list
+    @@header_list
+  end
+  def self.get_header_list2
+    @@header_list2
+  end
+
+end
+
+class Import < Node
+# @b_reuse::bool:       再利用．セルタイプの template 生成不要
+# @b_reuse_real::bool:  実際に再利用
+# @cdl::      string:   import する CDL
+# @cdl_path:: string:   CDL のパス
+# @b_imported:: bool:   import された(コマンドライン指定されていない)
+
+  include Importable
+
+  # ヘッダの名前文字列のリスト  添字：expand したパス、値：Import
+  @@import_list = {}
+
+  @@nest_stack_index = -1
+  @@nest_stack = []
+  @@current_object = nil
+
+  def self.push object
+    @@nest_stack_index += 1
+    @@nest_stack[ @@nest_stack_index ] = @@current_object
+    @@current_object = object
+  end
+
+  def self.pop
+    @@current_object = @@nest_stack[ @@nest_stack_index ]
+    @@nest_stack_index -= 1
+    if @@nest_stack_index < -1 then
+      raise "TooManyRestore"
+    end
+  end
+
+  #=== Import# import を行う
+  #cdl::      string   cdl へのパス．"" で囲まれていることを仮定
+  #b_reuse::  bool     true: template を生成しない
+  def initialize( cdl, b_reuse = false, b_imported = true )
+    Import.push self
+    @b_imported = b_imported
+    super()
+    @@current_import = self
+    # ヘッダファイル名文字列から前後の "", <> を取り除くn
+    @cdl = cdl.to_s.gsub( /\A["<](.*)[">]\z/, '\1' )
+
+    # サーチパスから探す
+    found = false
+    @cdl_path = ""
+
+    @b_reuse = b_reuse
+    @b_reuse_real = @b_reuse || Generator.is_reuse?
+
+    if( Generator.get_plugin ) &&( File.exist? "#{$gen}/#{@cdl}" ) then
+      @cdl_path = "#{$gen}/#{@cdl}"
+      found = true
+    else
+      path = find_file @cdl
+      if path then
+        found = true
+        @cdl_path = path
+      end
+    end
+
+    if found == false then
+      cdl_error( "S1148 $1 not found in search path" , @cdl )
+      return
+    end
+
+    # 読込み済みなら、読込まない
+    prev = @@import_list[ File.expand_path( @cdl_path ) ]
+    if( prev ) then
+      if prev.is_reuse_real? != @b_reuse_real then
+        cdl_warning( "W1008 $1: reuse designation mismatch with previous import" , @cdl )
+      end
+      return
+    end
+
+    # import リストを記録
+    @@import_list[ File.expand_path( @cdl_path ) ] = self
+
+    # plugin から import されている場合
+    plugin = Generator.get_plugin
+
+    # パーサインスタンスを生成(別パーサで読み込む)
+    parser = Generator.new
+
+    # plugin から import されている場合の plugin 設定
+    parser.set_plugin plugin
+
+    # reuse フラグを設定
+    parser.set_reuse @b_reuse_real
+
+    # cdl をパース
+    parser.parse( [@cdl_path] )
+
+    # 終期化　パーサスタックを戻す
+    parser.finalize
+    Import.pop
+  end
+
+  def self.get_list
+    @@import_list
+  end
+
+  def get_cdl_path
+    @cdl_path
+  end
+
+  def is_reuse_real?
+    @b_reuse_real
+  end
+
+  def self.get_current
+    @@current_object
+  end
+
+  def is_imported?
+    @b_imported
+  end
+
+  #=== cdl の名前を返す
+  # 引数で指定されている cdl 名。一部パスを含む可能性がある
+  def get_cdl_name
+    @cdl
+  end
+end
+
+#== generate: signature, celltype, cell へのプラグインのロードと適用
+class Generate < Node
+#@plugin_name:: Symbol
+#@object_nsp:: NamespacePath
+#@option::         String '"', '"' で囲まれている
+#@plugin_object:: Plugin
+
+  include PluginModule
+
+  def initialize( plugin_name, object_nsp, option )
+    super()
+    @plugin_name = plugin_name
+    @object_nsp = object_nsp
+    option = option.to_s    # option は Token
+    @option = option
+    @plugin_object = nil
+
+    dbgPrint "generate: #{plugin_name} #{object_nsp.to_s} option=#{option}\n"
+
+    object = Namespace.find( object_nsp )
+    if object.kind_of?( Signature ) ||
+       object.kind_of?( Celltype ) ||
+       object.kind_of?( CompositeCelltype ) ||
+       object.kind_of?( Cell )then
+      @plugin_object = object.apply_plugin( @plugin_name, @option )
+    elsif object then
+      # V1.5.0 以前の仕様では、signature のみ可能だった
+#      cdl_error( "S1149 $1 not signature" , signature_nsp )
+      cdl_error( "S9999 generate: '$1' neither signature, celltype nor cell", object_nsp )
+      return
+    else
+      cdl_error( "S9999 generate: '$1' not found", object_nsp )
+    end
+  end
+end
+
+#== 名前空間パス
+class NamespacePath < Node
+#@b_absolute::Bool
+#@path::[ Symbol,... ]
+#@namespace::Namespace:  @b_absolute == false のとき、基点となる namespace
+
+  #=== NamespacePath# initialize
+  #ident::Symbol           最初の名前, ただし "::" のみの場合は String
+  #b_absolute:Bool         "::" で始まっている場合 true
+  #namespace::Namespace    b_absolute = false かつ、構文解釈段階以外で呼び出す場合は、必ず指定すること 
+  def initialize( ident, b_absolute, namespace = nil )
+    super()
+
+    if ident == "::" then   # RootNamespace
+      @path = []
+      @b_absolute = true
+    else
+      @path = [ ident ]
+      @b_absolute = b_absolute
+    end
+
+    if namespace then
+      @namespace = namespace
+      if b_absolute == true then
+        raise "NamespacePath#initialize: naamespace specified for absolute path"
+      end
+    else
+      if b_absolute == false then
+        @namespace = Namespace.get_current
+      else
+        @namespace = nil
+      end
+    end
+  end
+
+  #=== NamespacePath# append する
+  #RETURN self
+  # このメソッドは、元の NamespacePath オブジェクトを変形して返す
+  def append!( ident )
+    @path << ident
+    return self
+  end
+  #=== NamespacePath# append する
+  # このメソッドは、元の NamespacePath オブジェクトを変形しない
+  #RETURN:: 複製した NamespacePath
+  def append( ident )
+    cl = self.clone
+    cl.set_clone
+    cl.append!( ident )
+    return cl
+  end
+
+  def set_clone
+    @path = @path.clone
+  end
+
+  def get_name
+    @path[ @path.length - 1 ]
+  end
+
+  #=== NamespacePath#クローンを作成して名前を変更する
+  def change_name name
+    cl = self.clone
+    cl.set_clone
+    cl.change_name_no_clone name
+    return cl
+  end
+  alias :change_name_clone :change_name
+
+  #=== NamespacePath#名前を変更する
+  # このインスタンスを参照するすべてに影響を与えることに注意
+  def change_name_no_clone name
+    @path[ @path.length - 1 ] = name
+    nil
+  end
+
+  #=== NamespacePath:: path 文字列を得る
+  # CDL 用の path 文字列を生成
+  def to_s
+    get_path_str
+  end
+  def get_path_str
+    first = true
+    if @b_absolute then
+      path = "::"
+    else
+      path = ""
+    end
+    @path.each{ |n|
+      if first then
+        path = "#{path}#{n}"
+        first = false
+      else
+        path += "::#{n}"
+      end
+    }
+    return path
+  end
+
+  def is_absolute?
+    @b_absolute
+  end
+  def is_name_only?
+    @path.length == 1 && @b_absolute == false
+  end
+
+  #=== NamespacePath:: パスの配列を返す
+  # is_absolute? true の場合、ルートからのパス
+  #              false の場合、base_namespace からの相対
+  # ルート namespace の場合、長さ０の配列を返す
+  #
+  def get_path
+    @path
+  end
+
+  #=== NamespacePath#フルパスの配列を返す
+  # 返された配列を書き換えてはならない
+  def get_full_path
+    if @b_absolute then
+      return @path
+    else
+      return @namespace.get_namespace_path.get_full_path.clone + @path
+    end
+  end
+
+  #=== NamespacePath:: 相対パスのベースとなる namespace
+  # is_absolute? == false の時のみ有効な値を返す (true なら nil)
+  def get_base_namespace
+    @namespace
+  end
+
+  #=== NamespacePath:: C 言語グローバル名を得る
+  def get_global_name
+    if @b_absolute then
+      global_name = ""
+    else
+      global_name = @namespace.get_global_name
+    end
+
+    @path.each{ |n|
+      if global_name != "" then
+        global_name = "#{global_name}_#{n}"
+      else
+        global_name = n.to_s
+      end
+    }
+    global_name
+  end
+
+  #=== NamespacePath:: 分解して NamespacePath インスタンスを生成する
+  #path_str:: String       : namespace または region のパス ex) "::path::A" , "::", "ident"
+  #b_force_absolute:: Bool : "::" で始まっていない場合でも絶対パスに扱う
+  #
+  # NamespacePath は通常構文解析されて作成される
+  # このメソッドは、オプションなどで指定される文字列を分解して NamespacePath を生成するのに用いる
+  # チェックはゆるい。不適切なパス指定は、不適切な NamespacePath が生成される
+  def self.analyze( path_str, b_force_absolute = false )
+
+    if path_str == "::" then
+      return self.new( "::", true )
+    end
+
+    pa = path_str.split( "::" )
+    if pa[0] == "" then
+      pa.shift
+      b_absolute = true
+    else
+      if b_force_absolute then
+        b_absolute = true
+      else
+        b_absolute = false
+      end
+    end
+
+    if pa[0] then
+      nsp = self.new( pa[0].to_sym, b_absolute )
+    else
+      nsp = self.new( "::", b_absolute )
+    end
+    pa.shift
+
+    pa.each{ |a|
+      if a then
+        nsp.append! a.to_sym
+      else
+        nsp.append! "::"
+      end
+    }
+
+    return nsp
+  end
+
+end
+
+# 以下単体テストコード
+if $unit_test then
+  root_namespace = Namespace.new("::")
+
+  puts( "===== Unit Test: NamespacePath ===== (componentobj.rb)")
+  a = NamespacePath.new( :"ABC", true )
+  printf( "Path: %-10s global_name: %s\n", a.get_path_str, a.get_global_name )
+
+  a.append( :"DEF" )
+  printf( "Path: %-10s global_name: %s\n", a.get_path_str, a.get_global_name )
+
+  a = NamespacePath.new( :"abc", false )
+  printf( "Path: %-10s global_name: %s\n", a.get_path_str, a.get_global_name )
+
+  a.append( :"def" )
+  printf( "Path: %-10s global_name: %s\n", a.get_path_str, a.get_global_name )
+
+  puts ""
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/ctypes.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/ctypes.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/ctypes.rb	(revision 398)
@@ -0,0 +1,244 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# CType は C_parser で定義される型を扱う CIntType, CFloatType などに include するもの
+# CIntType は IntType を継承するなど、C の型では TECS の型を継承する
+module CType
+
+  #=== 構文要素 type_specifier が複数指定されている場合に merge する
+  # merge は const(CIntType) unsigned(CIntTtype), long(CIntType), などと他の型をマージする
+  # const, unsigned, long などは、単体で int (CIntType) 型になりうる
+  #
+  # mikan C の文法を厳密にはチェックしていない  long struct 等もできてしまう
+  def merge another
+
+    # p "self: #{self.class} kind_of( IntType ): #{self.kind_of?( IntType )}  another: #{another.class}"
+
+    # signed, unsigned が Symbol として来る事は無くなった
+    # if another.instance_of? Symbol then
+    #   # ここで Symbol は :SIGNED, :UNSIGNED のいずれか
+    # 
+    #   # CIntType か？
+    #   if self.instance_of? CIntType then
+    #     self.set_sign another
+    #     return self
+    #   else
+    #     cdl_error( "C1001 $1: mismatch, suitable for int types" , another )
+    #     return self
+    #   end
+    # elsif self.instance_of?( CIntType ) && another.instance_of?( CIntType )then
+    if self.instance_of?( CIntType ) && another.instance_of?( CIntType )then
+      if another.get_bit_size != -3 then
+        if @bit_size == -4 && another.get_bit_size == -4 then
+          @bit_size = -5  # long long
+        else
+          # self は int 型、another の bit_size が (int 以外であれば)そちらにする
+          # mikan 上記以外で 両方 -3 でなければ、本来エラー
+          @bit_size = another.get_bit_size
+        end
+      end
+
+      if another.get_sign then
+        # another で sign が指定されていれば、そちらのものを採用する mikan 矛盾のチェック
+        @sign = another.get_sign
+      end
+
+#      if another.get_qualifier then
+#        # another で qualifier が指定されていれば、そちらのものを採用する mikan 矛盾のチェック
+#        @qualifier = another.get_qualifier
+#      end
+      if another.is_const? then
+        @b_const = true
+      end
+      if another.is_volatile? then
+        @b_volatile = true
+      end
+
+      return self
+    elsif self.instance_of?( CIntType ) then
+      return another.merge self
+    elsif self.instance_of?( CDefinedType ) then
+      # mikan unsigned などとの merge の不正検出
+      if another.is_const? then
+        @b_const = true
+      end
+      if another.is_volatile? then
+        @b_volatile = true
+      end
+
+#      if self.get_type.get_type_str == another.get_type_str &&
+#          self.get_type.get_type_str_post == another.get_type_str_post
+#        # p "typedef #{another.get_type_str} #{self.get_type_str}#{another.get_type_str_post} ;"
+#      else
+#        cdl_error( "C1002 $1 not compatible with previous one $2" , self.get_type_str, another.get_type_str )
+#      end
+      return self
+    elsif self.instance_of?( CStructType ) then
+      if another.is_const? then
+        @b_const = true
+      end
+      if another.is_volatile? then
+        @b_volatile = true
+      end
+      return self
+    elsif self.instance_of?( CFloatType ) then
+      # mikan long double
+      #   TECS には long double を表現する手段がない (double80_t を定義すればよいか?)
+#      cdl_warning( "C1003 $1 & $2 incompatible (\'long double\' is not supported.). Treated as $3." , self.class, another.class, self.class )
+#      cdl_warning( "W9999 $1 & $2 incompatible (\'long double\' is not supported.). Treated as $3." , self.get_type_str, another.get_type_str, self.get_type_str )
+      self.to_long      
+      return self
+    else
+      raise "merge: unknown type"
+    end
+  end
+
+  #=== qualifier を設定する
+  #     元の Type クラスでは矛盾チェックしない（TECSの本来の文法では重複指定できないため）
+  def set_qualifier( qual )
+
+    if @qualifier then
+      cdl_error( "C1004 $1: qualifier redefined. previous one: $2" , qual, @qualifier )
+    end
+    super( qual )
+  end
+
+end
+
+class CDefinedType < DefinedType
+
+  include CType
+
+  def initialize( type_name )
+    super( type_name )
+  end
+end
+
+class CVoidType < VoidType
+
+  include CType
+
+end
+
+class CBoolType < BoolType
+
+  include CType
+
+end
+
+class CIntType < IntType
+
+  include CType
+
+  def initialize( bit_size )
+    #p super.class   mikan super.class が Symbol だ、なぜ？
+    super( bit_size )
+  end
+
+  def set_sign( sign, b_uint = false )
+    super( sign, b_uint )
+    # p "CInt: set_sign: #{get_type_str} #{sign}"
+  end
+end
+
+class CFloatType < FloatType
+
+  include CType
+
+  def initialize( bit_size )
+    super
+  end
+
+  def to_long
+    if @bit_size != -64 then
+      cdl_warning( "W9999 long specified for $1" , get_type_str )
+    else
+      @bit_size = -128  # @bit_size = -128 : long double
+    end
+  end
+end
+
+class CEnumType < EnumType # mikan
+
+  include CType
+
+  def initialize( bit_size )
+    super( bit_size )
+  end
+
+end
+
+class CStructType < StructType
+
+  include CType
+
+
+  def initialize( tag = nil )
+    super( tag )
+  end
+end
+
+class CFuncType < FuncType
+
+  include CType
+
+  def initialize( paramlist = nil )
+    super( paramlist )
+  end
+
+end
+
+class CArrayType < ArrayType
+
+  include CType
+
+  def initialize( subscript = nil )
+    super( subscript )
+  end
+end
+
+class CPtrType < PtrType
+
+  include CType
+
+  def initialize( referto = nil )
+    super( referto )
+  end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/expression.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/expression.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/expression.rb	(revision 398)
@@ -0,0 +1,1037 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+class Expression < Node
+#  @elements   # array
+
+  def initialize( elements, locale = nil )
+    super()
+    if locale then
+      @locale = locale
+    end
+
+    @elements = elements
+  end
+
+  def print
+    # puts "expr: #{@elements}"
+    puts "expr_string: #{to_s}"
+  end
+
+  #=== Expression# to_s
+  # C 言語ソース向きの文字列を生成 (globa_name)
+  def to_s
+    elements_to_s( @elements )
+  end
+
+  #=== Expression# to_str
+  # C 言語ソース向きの文字列を生成 (globa_name)
+  def to_str( name_list, pre, post )
+    elements_to_s( @elements, name_list, pre, post )
+  end
+
+  #=== Expression#to_CDL_str
+  # CDL 表現の文字列を生成
+  def to_CDL_str
+    return to_s
+  end
+
+  #=== 定数式として評価する(トライしてみる)
+  #
+  # このメソッドは、定数式を評価する
+  # ・attribute, var の初期化子
+  # ・size_is, count_is 引数
+  # ・配列の添数
+  #
+  # name_list(NamedList|Nil): 式から参照可能なリスト．
+  # NamedList の要素は  size_is, count_is の引数評価の場合 ParamDecl (関数仮引数)
+  #
+  # name_list2(NamedList|Nil) : NamedList の要素は Decl (attribute, var) である．省略時 nil
+  # 
+  # RETURN: 評価した定数．評価できなかった場合は nil を返す
+  #
+  # 型は get_type で、評価する（定数として求められないときに使用できる）
+  # Array を返すのは attr{ int *a = {1, 2, 3}; int *b = a; }; の b の右辺を評価した場合
+
+  def eval_const( name_list, name_list2 = nil )
+    val = elements_eval_const( @elements, name_list, name_list2, 0 )
+    if val.kind_of? IntegerVal then
+      return val.to_i
+    elsif val.kind_of? FloatVal then
+      return val.to_f
+    elsif val.kind_of? BoolVal then
+      return val.to_i
+    elsif val.kind_of? PointerVal then
+      return val.to_i           # mikan エラー V1008 が発生してしまう
+      # elsif val.kind_of? EnumVal then
+      # enum mikan
+    else
+      # C_EXP, Array または nil ：そのまま返す
+      return val
+    end
+  end
+
+  #=== 定数式として評価する2(トライしてみる)
+  #
+  # IntegerVal, FloatVal をそのまま返す（eval_const では Integer, Float に変換）
+  def eval_const2( name_list, name_list2 = nil, nest = 0 )
+    val = elements_eval_const( @elements, name_list, name_list2, nest )
+  end
+
+  #=== 式の型を評価する
+  #
+  # eval_const で値が得られない場合、型を導出可能であれば型を得る
+  # param を含んだ式は定数値を求められないが、型を得ることはできる
+  # 未定義変数を含んだ型は、得ることができない (ダミー型定義が返る)
+  def get_type( namedList )        # 名前空間の NamedList を指定
+    elements_get_type( @elements, namedList )
+  end
+
+  def check_dir_for_param( namedList, dir, spec )
+    elements_check_dir_for_param( @elements, namedList, dir, spec )
+  end
+
+  def get_elements
+    @elements
+  end
+
+  def show_tree( indent )
+    # mikan override してしまった print を呼出す方法がわからないのでこうした
+    str = ""
+    indent.times { str += "  " }
+    puts "#{str}#{to_s}"
+  end
+
+## private
+
+  #=== 式を文字列に変換
+  #name_list:: attribute (Celltype::@attribute_list), struct の @member_list を仮定している
+  def elements_to_s( elements, name_list = nil, pre = nil, post = nil )
+    if elements.instance_of? Token then
+      return elements.to_s    # OP_DOT, OP_REF の右辺
+    end
+
+    case elements[0]
+    when :IDENTIFIER
+      nsp = elements[1]
+      # if nsp.is_name_only? && name_list && name_list.get_item( nsp.get_name ) then
+      if nsp.is_name_only? && name_list && name_list.get_item( nsp.get_name ) then
+        return "#{pre}#{nsp.get_name}#{post}"
+      else
+        # return  elements[1].get_global_name
+        return nsp.get_path_str
+      end
+    when :INTEGER_CONSTANT, :FLOATING_CONSTANT, :OCTAL_CONSTANT, :HEX_CONSTANT, :CHARACTER_LITERAL, :STRING_LITERAL_LIST, :BOOL_CONSTANT
+      return  elements[1].to_s
+    when :PARENTHESES
+      return "(#{elements_to_s(elements[1],name_list,pre,post)})"
+    when :OP_SUBSC
+      return "#{elements_to_s(elements[1],name_list,pre,post)}[#{elements[2].to_s}]"
+    when :OP_DOT
+      return "#{elements_to_s(elements[1],name_list,pre,post)}.#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_REF
+      return "#{elements_to_s(elements[1],name_list,pre,post)}->#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_SIZEOF_EXPR
+      return "sizeof(#{elements_to_s(elements[1],name_list,pre,post)})"
+    when :OP_SIZEOF_TYPE
+      return "sizeof(#{elements[1]}) mikan"
+    when :OP_U_AMP
+      return "&#{elements_to_s(elements[1],name_list,pre,post)}"
+    when :OP_U_ASTER
+      return "*#{elements_to_s(elements[1],name_list,pre,post)}"
+    when :OP_U_PLUS
+      return "+#{elements_to_s(elements[1],name_list,pre,post)}"
+    when :OP_U_MINUS
+      return "-#{elements_to_s(elements[1],name_list,pre,post)}"
+    when :OP_U_TILDE
+      return "~#{elements_to_s(elements[1],name_list,pre,post)}"
+    when :OP_U_EXCLAM
+      return "!#{elements_to_s(elements[1],name_list,pre,post)}"
+    when :CAST
+      return "(#{elements[1].get_type_str})#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_MULT
+      return "#{elements_to_s(elements[1],name_list,pre,post)}*#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_DIV
+      return "#{elements_to_s(elements[1],name_list,pre,post)}/#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_REMAIN
+      return "#{elements_to_s(elements[1],name_list,pre,post)}%#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_ADD
+      return "#{elements_to_s(elements[1],name_list,pre,post)}+#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_SUB
+      return "#{elements_to_s(elements[1],name_list,pre,post)}-#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_LSFT
+      return "#{elements_to_s(elements[1],name_list,pre,post)}<<#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_RSFT
+      return "#{elements_to_s(elements[1],name_list,pre,post)}>>#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_LT
+      return "#{elements_to_s(elements[1],name_list,pre,post)}<#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_GT
+      return "#{elements_to_s(elements[1],name_list,pre,post)}>#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_LE
+      return "#{elements_to_s(elements[1],name_list,pre,post)}<=#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_GE
+      return "#{elements_to_s(elements[1],name_list,pre,post)}>=#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_EQ
+      return "#{elements_to_s(elements[1],name_list,pre,post)}==#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_NE
+      return "#{elements_to_s(elements[1],name_list,pre,post)}!=#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_AND
+      return "#{elements_to_s(elements[1],name_list,pre,post)}&#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_EOR
+      return "#{elements_to_s(elements[1],name_list,pre,post)}^#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_OR
+      return "#{elements_to_s(elements[1],name_list,pre,post)}|#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_LAND
+      return "#{elements_to_s(elements[1],name_list,pre,post)}&&#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_LOR
+      return "#{elements_to_s(elements[1],name_list,pre,post)}||#{elements_to_s(elements[2],name_list,pre,post)}"
+    when :OP_CEX
+      return "#{elements_to_s(elements[1],name_list,pre,post)}?#{elements_to_s(elements[2],name_list,pre,post)}:#{elements_to_s(elements[3],name_list,pre,post)}"
+    else
+      raise "Unknown expression element: #{elemets[0]}. try -t and please report"
+    end
+    return ""
+  end
+
+  #=== Expression# 逆ポーランド文字列化
+  #param_list:: ParamlList  関数の引数リスト
+  def get_rpn( param_list = nil, name_list2 = nil )
+    return elements_rpn( @elements, param_list, name_list2 )
+  end
+
+  #=== Expression# 逆ポーランド文字列化 (private)
+  #name_list:: ParamlList  関数の引数リスト
+  def elements_rpn( elements, name_list = nil, name_list2 = nil )
+    if elements.instance_of? Token then
+      print "rpn: #{elements.to_s}\n"
+      return elements.to_s    # OP_DOT, OP_REF の右辺
+    end
+
+    case elements[0]
+    when :IDENTIFIER
+      nsp = elements[1]
+      #if nsp.is_name_only? && name_list && name_list.find( nsp.get_name ) then
+      if nsp.is_name_only? then
+        count = 0
+        # p "search: #{nsp.get_name}"
+        name_list.get_items.each{ |nm,val|
+          # p "    : #{nm.get_name} #{nsp.get_name.class} #{nm.get_name.class}"
+          if nsp.get_name == nm.get_name then
+            return " $#{count}"
+          end
+          count += 1
+        }
+        raise "not found parameter"
+      else
+        # return  elements[1].get_global_name
+        raise "not unexpected parameter"
+      end
+    when :INTEGER_CONSTANT, :FLOATING_CONSTANT, :OCTAL_CONSTANT, :HEX_CONSTANT, :CHARACTER_LITERAL, :STRING_LITERAL_LIST, :BOOL_CONSTANT
+      return elements[1].to_s
+    when :PARENTHESES
+      return elements_rpn( elements[1], name_list, name_list2 )
+    when :OP_SUBSC
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[1], "", name_list, name_list2 ) + " []"
+    when :OP_DOT
+      return elements_rpn( elements[1], name_list, name_list2 ) + " ."
+    when :OP_REF
+      return elements_rpn( elements[1], name_list, name_list2 ) + " ->"
+    when :OP_SIZEOF_EXPR
+      return elements_rpn( elements[1], name_list, name_list2 ) + " #s"
+    when :OP_SIZEOF_TYPE
+      return elements_rpn( elements[1], name_list, name_list2 ) + " #S"
+    when :OP_U_AMP
+      return elements_rpn( elements[1], name_list, name_list2 ) + " #&"
+    when :OP_U_ASTER
+      return elements_rpn( elements[1], name_list, name_list2 ) + " #*"
+    when :OP_U_PLUS
+      return elements_rpn( elements[1], name_list, name_list2 ) + " #+"
+    when :OP_U_MINUS
+      return elements_rpn( elements[1], name_list, name_list2 ) + " #-"
+    when :OP_U_TILDE
+      return elements_rpn( elements[1], name_list, name_list2 ) + " #~"
+    when :OP_U_EXCLAM
+      return elements_rpn( elements[1], name_list, name_list2 ) + " #!"
+    when :CAST
+      return elements_rpn( elements[1], name_list, name_list2 ) + " #(" + elements_rpn( elements[2], "", name_list, name_list2 ) + ")"
+    when :OP_MULT
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " *"
+    when :OP_DIV
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " /"
+    when :OP_REMAIN
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " %"
+    when :OP_ADD
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " +"
+    when :OP_SUB
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " -"
+    when :OP_LSFT
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " <<"
+    when :OP_RSFT
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " >>"
+    when :OP_LT
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " <"
+    when :OP_GT
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " >"
+    when :OP_LE
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " <="
+    when :OP_GE
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " >="
+    when :OP_EQ
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " =="
+    when :OP_NE
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " !="
+    when :OP_AND
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " &"
+    when :OP_EOR
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " ^"
+    when :OP_OR
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " |"
+    when :OP_LAND
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " &&"
+    when :OP_LOR
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " + elements_rpn( elements[2], "", name_list, name_list2 ) + " ||"
+    when :OP_CEX
+      return elements_rpn( elements[1], name_list, name_list2 ) + " " +
+             elements_rpn( elements[2], name_list, name_list2 ) + " " +
+             elements_rpn( elements[3], name_list, name_list2 ) + " ?:"
+    else
+      raise "Unknown expression element: #{elemets[0]}. try -t and please report"
+    end
+    return ""
+  end
+
+  # 定数式(elements)を評価する
+  #
+  # このメソッドは Expression クラスのメソッドである必要はない（関数化できる）
+  #
+  # elements は式の要素
+  #
+  # name_list, name_list2 は eval_const を参照
+  #
+  # RETURN: 評価した定数、評価できなかった場合は nil を返す
+
+  MAX_NEST_LEVEL = 64    # 簡易のループ検出（参照のネストを 64 まで許可する）
+  def elements_eval_const( elements, name_list, name_list2 = nil, nest = nil )
+
+    case elements[0]
+    when :IDENTIFIER
+      nsp = elements[1]
+
+      # #809 の修正しかけ (別の問題が解決しきれていない)
+      # nest += 1     # 参照がループになっていないかのチェック
+      #               # mikan 本当にループしているかどうかではなく、単純に多数の参照を繰り返していることで判定している
+      # if nest > MAX_NEST_LEVEL then
+      #   cdl_error( "E9999: '$1' too many reference (maybe loop) max=$1" , nsp.to_s, MAX_NEST_LEVEL )
+      #   return
+      # end
+      if nsp.is_name_only? then
+        if name_list then
+          object = name_list.get_item( nsp.get_name )
+        end
+
+        if object == nil && name_list2 then
+          object = name_list2.get_item( nsp.get_name )
+        end
+      end
+
+      # 見つからなければ定数定義から探す
+      if object == nil then
+        object = Namespace.find( nsp )# mikan namespace の対応 #1
+      end
+
+# この実装は、もう少し整理されるべき
+# これが呼出されるのは、以下の場合
+#   ・attribute, var の右辺式の評価
+#   ・size_is 引数の評価：関数パラメータの場合とattribute, var の場合がある
+# 以下のエラーチェックでは、これらがごっちゃになって誤りを検出しようとしている
+
+      # IDENTIFIER は見つからなかった？
+      if object == nil then
+        cdl_error( "E1001 $1: not found" , nsp.get_path_str )
+        # raise  "E1001"  # bug trap
+        return nil
+      elsif object.instance_of?( Join ) then
+        # Join の場合： cell の中の attribute, var, call のどれかが見つかった
+        # Decl (attribute, var) でない？
+        if ! object.get_definition.instance_of?( Decl ) then
+          cdl_error( "E1002 $1: not constant (port)" , nsp.get_path_str )
+          return nil
+        end
+        return object.get_rhs.eval_const2( name_list, name_list2, nest )
+      elsif ! object.instance_of?( Decl ) then
+        # Decl でない場合： 定数でもない
+        if ( ! object.instance_of?( ParamDecl ) ) then
+                                                      # mikan paramdecl は無視する
+                                                      # ParamList から呼ばれたとき
+          cdl_error( "E1003 $1: not constant" , nsp.get_path_str )
+        else
+          # ParamDecl
+          object.referenced
+        end
+        return nil
+      else # Decl
+        object.referenced
+        if object.get_initializer == nil then
+          # 初期化子の存在しない変数   # mikan ここへくるのは、通常ありえないはず（未検証）
+          return IntegerVal.new( 0 )
+        else
+          # Decl の右辺の評価
+          # mikan size_is 引数に現れる変数の型が適切かのチェックする
+          if object.get_initializer.instance_of?( Expression ) || object.get_initializer.instance_of?( C_EXP ) then
+            return object.get_initializer.eval_const2( name_list, name_list2, nest )
+          else
+            # Array の場合
+            return object.get_initializer
+          end
+        end
+      end
+    when :BOOL_CONSTANT
+      if( elements[1].instance_of?( TrueClass ) )then
+        return BoolVal.new( true )
+      elsif( elements[1].instance_of?( FalseClass ) )then
+        return  BoolVal.new( false )
+      else
+        throw( "BOOL constant error" )
+      end
+    when :INTEGER_CONSTANT
+      return IntegerVal.new( elements[1].val )
+    when :FLOATING_CONSTANT
+      return FloatVal.new( elements[1].val )
+    when :OCTAL_CONSTANT
+      return IntegerVal.new( elements[1].val.oct, elements[1].val )
+    when :HEX_CONSTANT
+      return IntegerVal.new( elements[1].val.hex, elements[1].val )
+    when :CHARACTER_LITERAL
+      str =  elements[1].val.gsub(/'/, "" )
+#2.0      if str.jlength == 1
+      if $b_no_kcode then
+        len = str.length
+      else
+        len = str.jlength
+      end
+      if len == 1 then
+        sum = 0
+        str.each_byte { |b| sum = sum * 256 + b }
+        return IntegerVal.new( sum, elements[1].val )
+      else
+#2.0        if str[0] == 92 then
+        if str[0] == 92 || str[0] == "\\" then
+          case str[1]
+#2.0          when 48 # '0'
+          when 48, "0" # '0'
+            return IntegerVal.new( 0, elements[1].val )
+#2.0          when 110 # 'n'
+          when 110, "n" # 'n'
+            return IntegerVal.new( 10, elements[1].val )
+#2.0          when 114 # 'r'
+          when 114, "r" # 'r'
+            return IntegerVal.new( 13, elements[1].val )
+#2.0          when 116 # 't'
+          when 116, "t" # 't'
+            return IntegerVal.new( 15, elements[1].val )
+#2.0          when 92 # '\\'
+          when 92, '\\' # '\\'
+            return IntegerVal.new( 92, elements[1].val )
+          end
+        end
+      end
+#2.0      printf( "c=%c\n", str[1] )
+      printf( "len=%d c=%c\n", len, str[1] )
+      raise Error
+
+    when :STRING_LITERAL_LIST
+      return  StringVal.new( elements[1] )
+    when :PARENTHESES
+      return elements_eval_const( elements[1], name_list, name_list2, nest );
+    when :OP_SUBSC
+      cdl_error( "E1004 cannot evaluate \'[]\' operator"  )
+      return nil
+    when :OP_DOT
+      cdl_error( "E1005 cannot evaluate \'.\' operator"  )
+      return nil
+    when :OP_REF
+      cdl_error( "E1006 cannot evaluate \'->\' operator"  )
+      return nil
+    when :OP_SIZEOF_EXPR
+      if Generator.parsing_C? then
+        cdl_info( "I9999 cannot evaluate \'sizeof\' operator. this might causes later error."  )
+      else
+        cdl_error( "E1007 cannot evaluate \'sizeof\' operator"  )
+      end
+      return nil
+    when :OP_SIZEOF_TYPE
+      if Generator.parsing_C? then
+        cdl_info( "I9999 cannot evaluate \'sizeof\' operator. this might causes later error."  )
+      else
+        cdl_error( "E1008 cannot evaluate \'sizeof\' operator"  )
+      end
+      return nil
+    when :OP_U_AMP
+      cdl_error( "E1009 cannot evaluate \'&\' operator"  )
+      return nil
+    when :OP_U_ASTER
+      # cdl_error( "E1010 cannot evaluate \'*\' operator"  )
+      val = elements_eval_const(elements[1], name_list, name_list2, nest)
+      return nil if ! evaluable?( val )
+      return val
+    when :OP_U_PLUS
+      val = elements_eval_const(elements[1], name_list, name_list2, nest)
+      return nil if ! evaluable?( val )
+      if val.respond_to?( "+@" ) then
+        return + val
+      else
+        cdl_error( "E1011 cannot evaluate unary + for $1" , val.class )
+        return nil
+      end
+    when :OP_U_MINUS
+      val = elements_eval_const(elements[1], name_list, name_list2, nest)
+      return nil if ! evaluable?( val )
+      if val.respond_to?( "-@" ) then
+        return - val
+      else
+        return nil
+      end
+    when :OP_U_TILDE
+      val = elements_eval_const(elements[1], name_list, name_list2, nest)
+      return nil if ! evaluable?( val )
+# p "val.respond_to?( \"-@\" )=#{val.respond_to?( "-@" )} #{val.class}"
+# p "val.respond_to?( \"~@\" )=#{val.respond_to?( "~@" )}"
+#2.0      if val.respond_to?( "~@" ) then  # Ruby 1.9, 2.0 preview 版では例外が発生してしまう
+      if val.kind_of? IntegerVal then
+        return ~ val
+      else
+        return nil
+      end
+    when :OP_U_EXCLAM
+      val = elements_eval_const(elements[1], name_list, name_list2, nest)
+      return nil if ! evaluable?( val )
+      val = val.cast( BoolType.new )
+      if val.respond_to?( "not" ) then
+        return val.not
+      else
+        return nil
+      end
+      return nil
+    when :CAST
+      val = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if val == nil
+      return nil if ! evaluable?( val )
+      return val.cast( elements[1] )
+    when :OP_MULT
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs * rhs
+    when :OP_DIV
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs / rhs
+    when :OP_REMAIN
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs % rhs
+    when :OP_ADD
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs + rhs
+    when :OP_SUB
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs - rhs
+    when :OP_LSFT
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs << rhs
+    when :OP_RSFT
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs >> rhs
+    when :OP_LT
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs < rhs
+    when :OP_GT
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs > rhs
+    when :OP_LE
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs <= rhs
+    when :OP_GE
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs >= rhs
+    when :OP_EQ
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs.eq( rhs )
+    when :OP_NE
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs.neq( rhs )
+    when :OP_AND
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs & rhs
+    when :OP_EOR
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs ^ rhs
+    when :OP_OR
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs | rhs
+    when :OP_LAND
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs.lAND( rhs )
+    when :OP_LOR
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      # return nil if( rhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, lhs )
+      return lhs.lOR( rhs )
+    when :OP_CEX
+      lhs = elements_eval_const(elements[1], name_list, name_list2, nest)
+      mhs = elements_eval_const(elements[2], name_list, name_list2, nest)
+      rhs = elements_eval_const(elements[3], name_list, name_list2, nest)
+      # return nil if( rhs == nil || mhs == nil || lhs == nil )
+      return nil if ! evaluable?( rhs, mhs, lhs )
+      if lhs.cast( BoolType.new ).val then
+          return mhs
+      else
+          return rhs
+      end
+    end
+    return nil
+  end
+
+  def elements_get_type( elements, namedList )
+    type = elements_get_type_sub( elements, namedList )
+    # 返された方が DefinedType の場合 元の型を返す
+    if type.kind_of?( DefinedType ) then
+      type = type.get_type
+    end
+    return type
+  end
+
+  def elements_get_type_sub( elements, namedList )
+    case elements[0]
+    when :IDENTIFIER
+      nsp = elements[1]
+      if nsp.is_name_only? then
+        paramdecl = namedList.get_item( nsp.get_name )
+      else
+        paramdecl = nil
+      end
+      unless paramdecl then
+        cdl_error( "E1012 $1: not found in parameter list" , nsp.get_path_str )
+        return IntType.new(32)        # dummy result
+      end
+      return paramdecl.get_type
+# mikan get_type
+#    when :INTEGER_CONSTANT
+#    when :FLOATING_CONSTANT
+#    when :OCTAL_CONSTANT
+#    when :HEX_CONSTANT
+#    when :CHARACTER_LITERAL
+#    when :STRING_LITERAL_LIST
+#    when :PARENTHESES
+#    when :OP_SUBSC
+#    when :OP_DOT
+#    when :OP_REF
+#    when :OP_SIZEOF_EXPR
+#    when :OP_SIZEOF_TYPE
+#    when :OP_U_AMP
+    when :OP_U_ASTER
+      type = elements_get_type( elements[1], namedList )
+      unless type.kind_of?( PtrType ) then
+        cdl_error( "E1013 \'*\': operand is not pointer value"  )
+        return IntType.new( 8 )    # IntType を返しておく
+      end
+      return type.get_referto
+
+    when :OP_U_PLUS, :OP_U_MINUS
+      # mikan operand が適切な型かチェックしていない
+      return elements_get_type( elements[1], namedList )
+
+    when :OP_ADD, :OP_SUB, :OP_MULT, :OP_DIV, :OP_REMAIN
+      # mikan operand が適切な型かチェックしていない＆左辺の型を採用している
+      return elements_get_type( elements[1], namedList )
+
+    when :OP_U_TILDE
+      # mikan operand が整数かチェックしていない
+      return elements_get_type( elements[1], namedList )
+    when :OP_AND, :OP_EOR, :OP_OR, :OP_LSFT, :OP_RSFT
+      # mikan operand が整数かチェックしていない
+      return BoolType.new
+    when :OP_U_EXCLAM
+      # mikan operand が整数かチェックしていない
+      return BoolType.new
+
+    when :OP_LT, :OP_GT, :OP_LE, :OP_GE, :OP_EQ, :OP_NE, :OP_LAND, :OP_LOR, :OP_CEX, :CAST
+      cdl_error( "E1014 $1: elements_get_type: sorry not supported" , elements[0] )
+    end
+
+    return nil
+  end
+
+  # 式が size_is, count_is, string の引数である場合の方向のチェック
+  def elements_check_dir_for_param( elements, namedList, dir, spec )
+   # dir ： 元の引数の方向
+   # direct: size_is などの引数の変数の方向
+
+    case elements[0]
+    when :IDENTIFIER
+      nsp = elements[1]
+      if nsp.is_name_only? then
+        paramdecl = namedList.get_item( nsp.get_name )
+      else
+        paramdecl = nil
+      end
+
+      return unless paramdecl      # if nil already error in element_get_type
+
+      direct = paramdecl.get_direction
+      judge = false
+      case spec
+      when "size_is", "string"
+        case dir
+        when :IN, :OUT, :INOUT, :SEND
+          judge = true if ( direct == :IN || direct == :INOUT )
+          req_direct = "in or inout"
+        when :RECEIVE
+          judge = true if ( direct == :OUT || direct == :INOUT )
+          req_direct = "out or inout"
+        end
+
+      when "count_is"
+        case dir
+        when :IN, :SEND
+          judge = true if ( direct == :IN || direct == :INOUT )
+          req_direct = "in or inout"
+        when :OUT, :RECEIVE     # mikan out で count_is のみ指定されている場合 in でなくてはならない
+          judge = true if ( direct == :OUT || direct == :INOUT )
+          req_direct = "out or inout"
+        when :INOUT
+          judge = true if ( direct == :INOUT )
+          req_direct = "inout"
+        end
+      end
+
+      if judge == false then
+        cdl_error( "E1015 \'$1\': direction mismatch for $2, $3 required" , nsp.get_path_str, spec, req_direct )
+      end
+
+    when :INTEGER_CONSTANT, :FLOATING_CONSTANT, :OCTAL_CONSTANT, :HEX_CONSTANT, :CHARACTER_LITERAL, :STRING_LITERAL_LIST
+      return true
+
+    # 単項演算子
+    when :OP_U_ASTER, :OP_SIZEOF_EXPR, :OP_SIZEOF_TYPE, :OP_U_PLUS, :OP_U_MINUS, :OP_U_TILDE, :OP_U_EXCLAM, :CAST, :OP_U_AMP, :PARENTHESES,
+      elements_check_dir_for_param( elements[1], namedList, dir, spec )
+
+    # 2項演算子
+    when :OP_SUBSC, :OP_DOT, :OP_REF, :OP_MULT, :OP_DIV, :OP_REMAIN, :OP_ADD, :OP_SUB, :OP_LSFT, :OP_RSFT, :OP_LT, :OP_GT, :OP_LE, :OP_GE, :OP_EQ, :OP_NE, :OP_AND, :OP_EOR, :OP_OR, :OP_LAND, :OP_LOR
+      return elements_check_dir_for_param( elements[1], namedList, dir, spec ) && elements_check_dir_for_param( elements[2], namedList, dir, spec )
+
+    # 3項演算子
+    when :OP_CEX
+      return elements_check_dir_for_param( elements[1], namedList, dir, spec ) && elements_check_dir_for_param( elements[2], namedList, dir, spec ) && elements_check_dir_for_param( elements[3], namedList, dir, spec )
+
+    else
+      cdl_error( "E1016 $1: elements_check_dir_for_param: sorry not supported" , elements[0] )
+    end
+
+  end
+
+  #Express# get_allocator_rhs_elem
+  #alloc_type::Symbol  :NORMAL_ALLOC|:INTERNAL_ALLOC|:RELAY_ALLOC
+  #式がアロケータ指定子の右辺として妥当かチェックし、正しければ分解した値を返す
+  #return:
+  #  :NORMAL_ALLOC      [ cell_nsp, ep_name ]               # rhs = cell_nsp.ep_name    ex) Alloc.eAlloc
+  #  :INTERNAL_ALLOC    [ ep_name ]                         # rhs = ep_name             ex) eAlloc
+  #  :RELAY_ALLOC       [ cp_name, func_name, param_name ]  # rhs = cp_name.func_name.param_name
+  def get_allocator_rhs_elements( alloc_type )
+    ele = @elements
+    case alloc_type 
+    when :NORMAL_ALLOC
+      if ele[0] != :OP_DOT || ele[1][0] != :IDENTIFIER then   #1
+        cdl_error( "E1017 $1: rhs not \'Cell.ePort\' form" , ele[0].to_s )
+        return nil
+      end
+      cell_nsp  = elements[1][1]
+      port_name = elements[2].val
+      return [ cell_nsp, port_name ]
+    when :INTERNAL_ALLOC
+      if( ele[0] == :IDENTIFIER )then
+        if ele[1].is_name_only? then
+          return [ ele[1].get_path[0] ]  # mikan a::b
+        else
+          cdl_error( "E1018 $1: namespace cannot be specified", ele[1].to_s )
+        end
+      else
+        cdl_error( "E1019 $1: rhs not in 'allocator_entry_port' form", ele[1].to_s )
+      end
+    when :RELAY_ALLOC
+      if( ele[0] != :OP_DOT ||
+          ele[1][0] != :OP_DOT || ele[1][1][0] != :IDENTIFIER || ! ele[1][1][1].is_name_only? ||
+          ! ele[1][2].instance_of?( Token ) || ! ele[2].instance_of?( Token ) )then   #1
+        cdl_error( "E1020 rhs not in 'call_port.func.param' form ($1)" , ele[0].to_s )   # S1086
+      end
+      func_name = ele[1][2]; cp_name = ele[1][1][1].get_name; param_name = ele[2].to_sym
+      return [ cp_name, func_name, param_name ]
+    end
+    return  nil
+  end
+
+  #Expression#Expression のクローンを作成する
+  def clone_for_composite
+    cl = self.clone
+    elements = clone_elements @elements
+    cl.set_elements elements
+    return cl
+  end
+
+  #Expression#elements のクローンを作成
+  #elements::Array
+  # このメソッドは、Array のディープコピーを行う
+  def clone_elements elements
+    elements = elements.clone
+    elements.map!{ |ele|
+      if ele.instance_of? Array
+        clone_elements ele
+      else
+        ele
+      end
+    }
+    return elements
+  end
+
+  def set_elements elements
+    @elements = elements
+  end
+
+  #=== Expression#セル結合の式を解析する
+  # Cell.eEntry  => [ :OP_DOT, [ :IDENTIFIER, token ], token ]
+  # Cell.eEntry[expression] => [ :OP_SUBSC, [ :OP_DOT, [ :IDENTIFIER, token ], token ], expression ]
+  # Return: [ NamespacePath(cell_name), Integer(subscript) or nil, Token(port_name)]
+  def analyze_cell_join_expression
+    # 右辺の Expression の要素を取り出す
+    elements = @elements
+    if elements[0] == :OP_SUBSC then  # 右辺：受け口配列？
+      # elements = [ :OP_SUBSC, [ :OP_DOT, [ :IDENTIFIER, token ], token ], expression ]
+      subscript = elements[2].eval_const(nil)  # 受け口配列の添数
+      elements  = elements[1]          # mikan 配列だった場合
+    else
+      subscript = nil
+    end
+
+    # elements = [ :OP_DOT, [ :IDENTIFIER, token ], token ]
+    if elements[0] != :OP_DOT || elements[1][0] != :IDENTIFIER then   #1
+      return nil
+    end
+
+    nsp = elements[1][1]         # NamespacePath
+    port_name = elements[2].val
+
+    return [ nsp, subscript, port_name]
+  end
+
+  #=== Expression# セルへの結合の式を生成する
+  #nsp:: NamespacePath
+  #subscript:: Integer
+  #port_name:: Symbol
+  # analyze_cell_join_expression と対になっている
+  def self.create_cell_join_expression( nsp, subscript, port_name, locale = nil )
+    if ! port_name.instance_of?( Symbol ) then
+      raise "port_name: not Symbol"
+    end
+
+    if subscript then
+      elements = [ :OP_SUBSC, [ :OP_DOT, [ :IDENTIFIER, nsp ],
+                                Token.new( port_name, nil, nil, nil ) ],
+                   Expression.create_integer_constant( subscript, @locale ) ]
+    else
+      elements = [ :OP_DOT, [ :IDENTIFIER, nsp ], Token.new( port_name, nil, nil, nil ) ]
+    end
+    return Expression.new( elements, locale )
+  end
+
+  #=== Expression#整数定数の式を生成する
+  #val:: Integer : 値： 整数
+  def self.create_integer_constant( val, locale = nil )
+    if val != Integer( val ) || val < 0 then
+      raise "create_integer_constant: not integer or negative: #{val}"
+    end
+    Expression.new( [ :INTEGER_CONSTANT, Token.new( val, nil, nil, nil ) ], locale )
+  end
+
+  #=== Expression#単一の識別子の式を解析する
+  # Identifier  => [ :IDENTIFIER, token ]
+  # Return: NamespacePath(Identifier)
+  def analyze_single_identifier
+    # 右辺の Expression の要素を取り出す
+    elements = @elements
+    if elements[0] == :IDENTIFIER
+      return elements[1]
+    else
+      return nil
+    end
+  end
+
+  #=== Expression#
+  #nsp:: NamespacePath :  参照するもの識別子
+  def self.create_single_identifier( nsp, locale )
+    if ! nsp.instance_of?( NamespacePath ) then
+      raise "create_single_identifier: not NamespacePath: #{nsp.to_s}"
+    end
+    Expression.new( [ :IDENTIFIER, nsp ] )
+  end
+
+  #=== 評価可能かチェックする
+  #*v:: 可変個引数（任意の型）
+  # すべてが BaseVal の子クラス（値）であれば、評価可能と判断する
+  def evaluable?( *v )
+    v.each{ |val|
+      if ! val.kind_of?( BaseVal ) then
+        return false
+      end
+    }
+    return true
+  end
+
+  private :elements_to_s, :elements_eval_const,  :elements_get_type
+
+end
+
+
+class C_EXP < Node
+# @c_exp_string : string
+
+  #c_exp_string::String
+  #b_renew::Bool  : true なら C_EXP の clone 作成（エスケープ処理等をしない）
+  def initialize( c_exp_string, b_renew = false )
+    if b_renew then
+      @c_exp_string = c_exp_string
+    else
+      # 前後の " を取り除く
+      # str = c_exp_string.to_s.sub( /^\"(.*)\"$/, "\\1" )
+      str = CDLString.remove_dquote c_exp_string.to_s
+      @c_exp_string = CDLString.escape str
+    end
+  end
+
+  #=== composite 用に C_EXP を clone する
+  #ct_name::
+  #cell_name::
+  # composite の attribute に現れる C_EXP を文字列置換して生成しなおす．
+  # この文字列置換は、意味解釈段階で行う．
+  # 他の C_EXP の文字列置換は、コード生成段階で行う．
+  def clone_for_composite( ct_name, cell_name, locale )
+    dbgPrint "C_EXP: #{ct_name} #{cell_name} #{@c_exp_string}\n"
+
+    @locale = locale
+    str = @c_exp_string.gsub( /(^|[^\$])\$ct\$/, "\\1#{ct_name}" )
+    str = str.          gsub( /(^|[^\$])\$cell\$/, "\\1#{cell_name}" )
+    str = str.          gsub( /(^|[^\$])\$id\$/, "\\1#{ct_name}_#{cell_name}" )
+    return C_EXP.new( str, true )
+  end
+
+  def get_c_exp_string
+    @c_exp_string
+  end
+
+  #=== C_EXP を評価する
+  # C_EXP の引き数文字列を返す
+  # 本来 C_EXP は eval_const する対象ではないが、便宜上 eval_const で対応
+  def eval_const( name_list, name_list2 = nil )
+     return self
+  end
+  def eval_const2( name_list, name_list2 = nil, nest = nil )
+     return self
+  end
+
+  def to_s
+    @c_exp_string
+  end
+
+  def to_CDL_str
+    return "C_EXP( \"#{to_s}\" )"
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "C_EXP: #{@c_exp_string}"
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/gen_xml.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/gen_xml.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/gen_xml.rb	(revision 398)
@@ -0,0 +1,377 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+XML_INDENT = "    "
+
+class Namespace
+  def self.gen_XML root_namespace
+    begin
+      file_name = $gen_base + "/" + $target + ".xml"
+      dbgPrint "generating XML file:#{file_name}\n"
+      file = AppFile.open( file_name )
+
+      file.print <<EOT
+<?xml version="1.0" encoding="UTF-8"?>
+<GUI_Tool xmlns="http://www.toppers.jp/tecs.html">
+EOT
+      root_namespace.gen_XML file, 1
+
+      file.print <<EOT
+</GUI_Tool>
+EOT
+
+      file.close
+    rescue => evar
+      Generator.error( "T2001 fail to create XML file $1", file_name)
+      print_exception( evar )
+    end
+  end
+
+  def gen_XML( file, nest )
+    # signature のコードを生成
+    @signature_list.each { |s|
+      s.gen_XML file, nest
+    }
+
+    # celltype のコードを生成
+    @celltype_list.each { |t|
+      t.gen_XML( file, nest )
+    }
+
+    # composite のコードを生成
+    @compositecelltype_list.each { |t|
+      t.gen_XML( file, nest )
+    }
+
+    # cell のコードを生成
+    @cell_list.each { |t|
+      t.gen_XML( file, nest )
+    }
+
+    # サブネームスペースのコードを生成
+    @namespace_list.each { |n|
+      kind = n.instance_of?( Namespace ) ? "namespace" : "region"
+      file.print <<EOT
+#{XML_INDENT * nest}<#{kind}>
+#{XML_INDENT * (nest+1)}<name> #{n.get_name} </name>
+EOT
+      n.gen_XML( file, nest + 1 )
+      file.print <<EOT
+#{XML_INDENT * nest}</#{kind}>
+EOT
+    }
+  end
+end
+
+class Signature
+  def gen_XML file, nest
+    indent = XML_INDENT * nest
+    if is_imported? then
+      file.print <<EOT
+#{indent}<import path='#{@import.get_cdl_name}'>
+EOT
+      nest += 1
+      indent = XML_INDENT * nest
+    end
+
+    file.print <<EOT
+#{indent}<signature>
+#{indent}#{XML_INDENT}<name> #{@name} </name>
+EOT
+    @function_head_list.get_items.each{ |fh|
+      file.print <<EOT
+#{indent}#{XML_INDENT}<func>
+#{indent}#{XML_INDENT}#{XML_INDENT}<name> #{fh.get_name} </name>
+#{indent}#{XML_INDENT}#{XML_INDENT}<rettype> #{fh.get_return_type.get_type_str}#{fh.get_return_type.get_type_str_post} </rettype>
+EOT
+      fh.get_paramlist.get_items.each{ |pd|
+        file.print <<EOT
+#{indent}#{XML_INDENT}#{XML_INDENT}<param>
+#{indent}#{XML_INDENT}#{XML_INDENT}#{XML_INDENT}<name> #{pd.get_name} </name>
+#{indent}#{XML_INDENT}#{XML_INDENT}#{XML_INDENT}<type> #{pd.get_type.get_type_str}#{pd.get_type.get_type_str_post} </type>
+#{indent}#{XML_INDENT}#{XML_INDENT}</param>
+EOT
+      }
+      file.print <<EOT
+#{indent}#{XML_INDENT}</func>
+EOT
+    }
+    file.print <<EOT
+#{indent}</signature>
+EOT
+    if is_imported? then
+      nest -= 1
+      indent = XML_INDENT * nest
+      file.print <<EOT
+#{indent}</import>
+EOT
+    end
+  end
+end
+
+class Celltype
+  def gen_XML file, nest
+    indent = XML_INDENT * nest
+    if is_imported? then
+      file.print <<EOT
+#{indent}<import path='#{@import.get_cdl_name}'>
+EOT
+      nest += 1
+      indent = XML_INDENT * nest
+    end
+
+    file.print <<EOT
+#{indent}<celltype>
+#{indent}#{XML_INDENT}<name> #{@name} </name>
+EOT
+    if @active then
+      file.print <<EOT
+#{indent}#{XML_INDENT}<active />
+EOT
+    end
+    if @singleton then
+      file.print <<EOT
+#{indent}#{XML_INDENT}<singleton />
+EOT
+    end
+
+    @attribute.each{ |attr|
+      file.print <<EOT
+#{indent}#{XML_INDENT}<attr>
+#{indent}#{XML_INDENT}#{XML_INDENT}<name> #{attr.get_name} </name>
+#{indent}#{XML_INDENT}#{XML_INDENT}<type> #{attr.get_type.get_type_str}#{attr.get_type.get_type_str_post} </type>
+EOT
+      if attr.get_initializer then
+        file.print <<EOT
+#{indent}#{XML_INDENT}#{XML_INDENT}<initializer> #{attr.get_initializer.to_CDL_str} </initializer>
+EOT
+      end
+
+      if attr.get_choice_list then
+        file.print <<EOT
+#{indent}#{XML_INDENT}#{XML_INDENT}<choice>
+EOT
+
+        attr.get_choice_list.each { |choiceElement|
+          file.print <<EOT
+#{indent}#{XML_INDENT}#{XML_INDENT}#{XML_INDENT}<choiceElement>#{choiceElement}</choiceElement>
+EOT
+        }
+
+        file.print <<EOT
+#{indent}#{XML_INDENT}#{XML_INDENT}</choice>
+EOT
+      end
+
+      file.print <<EOT
+#{indent}#{XML_INDENT}</attr>
+EOT
+    }
+    @port.each{ |port|
+      port_type = port.get_port_type == :CALL ? "call" : "entry"
+      file.print <<EOT
+#{indent}#{XML_INDENT}<#{port_type}>
+#{indent}#{XML_INDENT}#{XML_INDENT}<name> #{port.get_name} </name>
+#{indent}#{XML_INDENT}#{XML_INDENT}<signame> #{port.get_signature.get_name} </signame>
+EOT
+      if port.get_array_size then
+        file.print <<EOT
+#{indent}#{XML_INDENT}#{XML_INDENT}<subscript> #{port.get_array_size} </subscript>
+EOT
+      end
+      file.print <<EOT
+#{indent}#{XML_INDENT}</#{port_type}>
+EOT
+    }
+    file.print <<EOT
+#{indent}</celltype>
+EOT
+    if is_imported? then
+      nest -= 1
+      indent = XML_INDENT * nest
+      file.print <<EOT
+#{indent}</import>
+EOT
+    end
+  end
+
+end
+
+#
+# Celltype と共用可能なはずだが、以下の点の変更が必要
+#  @active ⇒ @b_active
+#  @singleton ⇒ @b_singleton
+#  @attribute ⇒ @name_list (Decl)
+#  @port ⇒ @name_list (Port)
+class CompositeCelltype
+  def gen_XML file, nest
+    indent = XML_INDENT * nest
+    if is_imported? then
+      file.print <<EOT
+#{indent}<import path='#{@import.get_cdl_name}'>
+EOT
+      nest += 1
+      indent = XML_INDENT * nest
+    end
+
+    file.print <<EOT
+#{indent}<celltype>
+#{indent}#{XML_INDENT}<name> #{@name} </name>
+EOT
+    file.print <<EOT
+#{indent}#{XML_INDENT}<composite />
+EOT
+
+    if @b_active then
+      file.print <<EOT
+#{indent}#{XML_INDENT}<active />
+EOT
+    end
+    if @b_singleton then
+      file.print <<EOT
+#{indent}#{XML_INDENT}<singleton />
+EOT
+    end
+
+    @name_list.get_items.each{ |attr|
+      if ! attr.instance_of? Decl then
+        next
+      end
+      file.print <<EOT
+#{indent}#{XML_INDENT}<attr>
+#{indent}#{XML_INDENT}#{XML_INDENT}<name> #{attr.get_name} </name>
+#{indent}#{XML_INDENT}#{XML_INDENT}<type> #{attr.get_type.get_type_str}#{attr.get_type.get_type_str_post} </type>
+EOT
+      if attr.get_initializer then
+        file.print <<EOT
+#{indent}#{XML_INDENT}#{XML_INDENT}<initializer> #{attr.get_initializer.to_CDL_str} </initializer>
+EOT
+      end
+      file.print <<EOT
+#{indent}#{XML_INDENT}</attr>
+EOT
+    }
+    @name_list.get_items.each{ |port|
+      if ! port.instance_of? Port then
+        next
+      end
+      port_type = port.get_port_type == :CALL ? "call" : "entry"
+      file.print <<EOT
+#{indent}#{XML_INDENT}<#{port_type}>
+#{indent}#{XML_INDENT}#{XML_INDENT}<name> #{port.get_name} </name>
+#{indent}#{XML_INDENT}#{XML_INDENT}<signame> #{port.get_signature.get_name} </signame>
+EOT
+      if port.get_array_size then
+        file.print <<EOT
+#{indent}#{XML_INDENT}#{XML_INDENT}<subscript> #{port.get_array_size} </subscript>
+EOT
+      end
+      file.print <<EOT
+#{indent}#{XML_INDENT}</#{port_type}>
+EOT
+    }
+    file.print <<EOT
+#{indent}</celltype>
+EOT
+    if is_imported? then
+      nest -= 1
+      indent = XML_INDENT * nest
+      file.print <<EOT
+#{indent}</import>
+EOT
+    end
+  end
+
+end
+
+class Cell
+  def gen_XML file, nest
+    indent = XML_INDENT * nest
+
+    if is_imported? then
+      file.print <<EOT
+#{indent}<import path='#{@import.get_cdl_name}'>
+EOT
+      nest += 1
+      indent = XML_INDENT * nest
+    end
+
+    file.print <<EOT
+#{indent}<cell>
+#{indent}#{XML_INDENT}<name> #{@name} </name>
+EOT
+    @join_list.get_items.each{ |join|
+      if join.get_definition.kind_of? Port then
+        kind = "call_join"
+      elsif join.get_definition.kind_of? Decl then
+        kind = "attr_join"
+      else
+        raise "Unknown"
+      end
+      if join.get_array_member2 then
+        join.get_array_member2.each { |j2|
+          file.print <<EOT
+#{indent}#{XML_INDENT}<#{kind}>
+#{indent}#{XML_INDENT}#{XML_INDENT}<name> #{join.get_name} </name>
+#{indent}#{XML_INDENT}#{XML_INDENT}<subscript> #{join.get_subscript} </subscript>
+#{indent}#{XML_INDENT}#{XML_INDENT}<rhs> #{join.get_rhs.to_CDL_str} </rhs>
+#{indent}#{XML_INDENT}</#{kind}>
+EOT
+        }
+      else
+        file.print <<EOT
+#{indent}#{XML_INDENT}<#{kind}>
+#{indent}#{XML_INDENT}#{XML_INDENT}<name> #{join.get_name} </name>
+#{indent}#{XML_INDENT}#{XML_INDENT}<rhs> #{join.get_rhs.to_CDL_str} </rhs>
+#{indent}#{XML_INDENT}</#{kind}>
+EOT
+      end
+    }
+    file.print <<EOT
+#{indent}</cell>
+EOT
+    if is_imported? then
+      nest -= 1
+      indent = XML_INDENT * nest
+      file.print <<EOT
+#{indent}</import>
+EOT
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/generate.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/generate.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/generate.rb	(revision 398)
@@ -0,0 +1,5304 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2019 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+def ifdef_macro_only f
+  f.print <<EOT
+#ifndef TOPPERS_MACRO_ONLY
+
+EOT
+end
+
+def ifndef_macro_only f
+  f.print <<EOT
+#ifndef TOPPERS_MACRO_ONLY
+
+EOT
+end
+
+def endif_macro_only f
+  f.print <<EOT
+#endif /* TOPPERS_MACRO_ONLY */
+
+EOT
+end
+
+def ifndef_cb_type_only f
+  f.print <<EOT
+#ifndef TOPPERS_CB_TYPE_ONLY
+
+EOT
+end
+
+def ifdef_cb_type_only f
+  f.print <<EOT
+#ifdef TOPPERS_CB_TYPE_ONLY
+
+EOT
+end
+
+def endif_cb_type_only f
+  f.print <<EOT
+#endif /* TOPPERS_CB_TYPE_ONLY */
+
+EOT
+end
+
+def begin_extern_C f
+  f.print  <<EOT
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+EOT
+end
+
+def end_extern_C f
+  f.print  <<EOT
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+EOT
+end
+
+def print_note( f, b_complete = true )
+  if b_complete
+    f.print "/*\n"
+  else
+    f.print " *\n"
+  end
+  f.print TECSMsg.get( :note )
+  if b_complete
+    f.print " */\n"
+  else
+    f.print " *\n"
+  end
+end
+
+def print_Makefile_note f
+  f.print TECSMsg.get( :Makefile_note )
+end
+
+
+def print_indent( f, n )
+  f.print "    " * n
+end
+
+# celltype_private.h を生成
+
+class Namespace
+  @@domain_gen_factory_list = nil
+  def generate
+
+    begin
+      # root namespace ならば makefile を出力する(全セルタイプに関わるものだけ)
+      # 先に出力する
+      if @name == "::" then
+
+        gen_makefile_template
+        gen_makefile_tecsgen
+        if $generating_region.get_n_cells == 0 then
+          dbgPrint "only makefile_template #{@name}\n"
+          return
+        end
+        if instance_of? Region then
+          @@domain_gen_factory_list = {}   # create hash
+        end
+      end
+
+      dbgPrint "generating region: #{$generating_region.get_name} namespace=#{@name} gen_dir=#{$gen}\n"
+      # global_tecsgen.h (typedef, struct, const) の生成
+      gen_global_header
+
+      if ( instance_of? Region ) && get_domain_type != nil then
+        # p "*******************  domain_type: #{get_domain_type.get_name}  ****************"
+        domain_type = get_domain_type
+        if @@domain_gen_factory_list[ domain_type ] == nil then
+          @@domain_gen_factory_list[ domain_type ] = self
+          domain_type.gen_factory
+        end
+      end
+      
+      # signature のコードを生成
+      @signature_list.each { |s|
+        s.generate
+      }
+
+      # celltype のコードを生成
+      @celltype_list.each { |t|
+        t.generate
+      }
+
+      # サブネームスペースのコードを生成
+      @namespace_list.each { |n|
+        n.generate
+      }
+
+    rescue => evar
+      # もしスタックトレースが出るまでい時間がかかるようならば、次をコメントアウトしてみるべし
+      cdl_error( "H1001 tecsgen: fatal internal error during code generation"  )
+      print_exception( evar )
+    end
+  end
+
+  def generate_post
+
+    if $generating_region.get_n_cells == 0 then
+      return
+    end
+
+    begin
+      # global_tecsgen.h (typedef, struct, const) の終わりのガードコード生成
+      gen_global_header_post
+
+      # signature のコードを生成
+      @signature_list.each { |s|
+        s.generate_post
+      }
+
+      # celltype のコードを生成
+      @celltype_list.each { |t|
+        t.generate_post
+      }
+
+      # サブネームスペースのコードを生成
+      @namespace_list.each { |n|
+        n.generate_post
+      }
+
+    rescue => evar
+      cdl_error( "H1002 tecsgen: fatal internal error during post code generation"  )
+      print_exception( evar )
+    end
+  end
+
+###  
+  def gen_global_header
+
+    # global_tecs.h の生成
+    f = AppFile.open( "#{$gen}/global_tecsgen.#{$h_suffix}" )
+
+    if @name == "::" then
+      print_note f
+
+      # ガードコードを出力
+      f.print <<EOT
+#ifndef GLOBAL_TECSGEN_H
+#define GLOBAL_TECSGEN_H
+
+EOT
+
+      # import_C で指定されたヘッダファイルの #include を出力
+      if Import_C.get_header_list2.length > 0 then
+        # ヘッダ include の出力
+        f.printf TECSMsg.get( :IMP_comment ), "#_IMP_#"
+        Import_C.get_header_list2.each{ |h|
+          f.printf( "#include \"#{h}\"\n" )
+        }
+        f.printf( "/**/\n\n" )
+      end
+
+      ifndef_macro_only f
+    end
+
+    # typedef, struct, enum を生成
+    @decl_list.each { |d|
+
+      # d は Typedef, StructType, EnumType のいずれか
+      if d.instance_of?( Typedef ) then
+
+        # Typedef の場合、declarator の @type が　CType でないか
+        if ! d.get_declarator.get_type.kind_of?( CType ) then
+          d.gen_gh f
+        end
+      elsif ! d.kind_of?( CType ) then
+
+        # CType ではない (StructType または EnumType)
+        d.gen_gh f
+#     else
+#       ここに該当するのは CStructType, CEnumType
+      end
+    }
+
+    if @name == "::" then
+
+      if $ram_initializer then
+        # Proc to judge the necessity of CB initializer
+        b_inline_only_or_proc = Proc.new{ |ct|
+          # print ct.get_name, ": ",  ct.need_CB_initializer?, "\n"
+          ct.need_CB_initializer?
+        }
+        gen_celltype_names( f, "extern void ", "_CB_initialize();\n", true, b_inline_only_or_proc )
+        gen_celltype_names( f, "extern void ", "_CB_initialize();\n", false, b_inline_only_or_proc )
+        f.print "\n#define INITIALIZE_TECS() \\\n"
+        gen_celltype_names( f, "\t", "_CB_initialize();\\\n", true, b_inline_only_or_proc )
+        gen_celltype_names( f, "\t", "_CB_initialize();\\\n", false, b_inline_only_or_proc )
+        f.print( "/* INITIALIZE_TECS terminator */\n\n" )
+      else
+        f.print "\n#define INITIALIZE_TECS() \n"
+      end
+      f.print "#define INITIALZE_TECSGEN() INITIALIZE_TECS()  /* for backward compatibility */\n\n"
+
+      f.print( "/* Descriptor for dynamic join */\n" )
+      f.print( "#define Descriptor( signature_global_name )  DynDesc__ ## signature_global_name\n" )
+      f.print( "#define is_descriptor_unjoined( desc )  ((desc).vdes==NULL)\n\n" )
+      endif_macro_only f
+    end
+
+    # const を生成  mikan
+    @const_decl_list.each { |d|
+      f.printf( "#define %-14s ((%s%s)%s)\n", d.get_global_name,
+                d.get_type.get_type_str, d.get_type.get_type_str_post,
+                d.get_initializer.eval_const2(nil) )
+    }
+
+    f.close
+
+  end
+
+  def gen_global_header_post
+
+    # global_tecs.h を開く
+    f = AppFile.open( "#{$gen}/global_tecsgen.#{$h_suffix}" )
+
+    if @name == "::" then
+      f.print <<EOT
+
+#endif /* GLOBAL_TECSGEN_H */
+EOT
+    end
+
+    f.close
+
+  end
+
+  #=== Makefile.tecsgen, Makefile.templ の出力
+  # 全セルタイプ名を出力する部分を出力
+  #    （本メソッドは root namespace に対して呼出す）
+  #     個々のセルタイプのメークルールは Celltype クラスで出力
+  def gen_makefile
+    gen_makefile_template
+    gen_makefile_tecsgen
+  end
+
+  def gen_makefile_template
+
+    return if $generate_no_template
+
+    ### Makefile.templ の生成
+    f = AppFile.open( "#{$gen}/Makefile.templ" )
+
+    print_Makefile_note f
+
+    # Makefile の変数の出力
+    f.printf TECSMsg.get( :MVAR_comment ), "#_MVAR_#"
+    f.printf "# fixed variable (unchangeable by config or plugin)\n"
+
+    # TARGET の出力 (第一引数 $target に region 名および .exe を付加)
+    target = $target
+    if $generating_region != @@root_namespace then
+      # 子 region のリンクターゲットの場合
+      target += "-#{$generating_region.get_global_name}"
+    end
+    f.print "TARGET_BASE = #{target}\n"
+
+    if $generating_region == @@root_namespace then
+      f.print "BASE_DIR = .\n"
+      vpath_lead = ""
+    else
+      f.print "BASE_DIR = ..\n"
+      vpath_lead = "../"
+    end
+
+    f.print "GEN_DIR = $(BASE_DIR)/#{$gen}\n"
+
+    f.print "INCLUDES ="
+    search_path = $import_path + TECSGEN::Makefile.get_search_path
+    search_path.each{ |path|
+      if TECSGEN.is_absolute_path? path then
+        f.print( TECSGEN.subst_tecspath " -I #{path}" )
+      else
+        f.print " -I $(BASE_DIR)/#{path}"
+      end
+    }
+    f.print " -I $(GEN_DIR)\n"
+    f.print "DEFINES ="
+    $define.each{ |define| f.print " -D #{define}" }
+    f.print "\n\n"
+    f.printf "# end of fixed variable (unchangeable by config or plugin)\n"
+
+
+    vpath_add = ""
+    search_path.each{ |path|
+      if path != "." then
+        if TECSGEN.is_absolute_path? path then
+          vpath_add += " " + TECSGEN.subst_tecspath( path )
+        else
+          vpath_add += " " + vpath_lead + path
+        end
+      end
+    }
+    objs_add = ""
+    TECSGEN::Makefile.get_objs.each{ |obj| objs_add += " " + obj }
+    ld_flag_add = TECSGEN::Makefile.get_ldflags
+    var_add = ""
+    TECSGEN::Makefile.get_vars.each{ |var|
+      var_add += "#" + TECSGEN::Makefile.get_var_comment( var ) + "\n"
+      a = TECSGEN::Makefile.get_var_val( var ).to_s
+      b = var.to_s
+      c = var_add.to_s
+      var_add += var.to_s + " =" + " " + TECSGEN::Makefile.get_var_val( var ).to_s + "\n\n"
+    }
+    pre_tecsgen_target = ""
+    TECSGEN::Makefile.get_pre_tecsgen_target{ |target| pre_tecsgen_target += " " + target }
+    post_tecsgen_target = ""
+    TECSGEN::Makefile.get_post_tecsgen_target{ |target| post_tecsgen_target += " " + target }
+
+#
+# LD = gcc
+# LDFLAGS =#{ld_flag_add}
+# SRC_DIR = $(BASE_DIR)/src
+# _TECS_OBJ_DIR = $(GEN_DIR)/
+# #   _TECS_OBJ_DIR   # should end with '/'
+
+    f.print <<EOT
+#{var_add}
+
+# Pre-tecsgen target
+PRE_TECSGEN_TARGET =#{pre_tecsgen_target}
+
+# Post-tecsgen target
+POST_TECSGEN_TARGET =#{post_tecsgen_target}
+
+# vpath for C sources and headers
+vpath %.#{$c_suffix} $(SRC_DIR) $(GEN_DIR) #{vpath_add}
+vpath %.#{$h_suffix} $(SRC_DIR) $(GEN_DIR) #{vpath_add}
+
+# Other objects (out of tecsgen)
+OTHER_OBJS =#{objs_add}                      # Add objects out of tecs care.
+# OTHER_OBJS = $(_TECS_OBJ_DIR)vasyslog.o
+EOT
+
+    # make ルールの出力
+    f.printf( TECSMsg.get( :MRUL_comment), "#_MRUL_#" )
+
+    f.print <<EOT
+allall: tecs
+\tmake all     # in order to include generated Makefile.tecsgen & Makefile.depend
+
+EOT
+
+    if $generating_region.get_n_cells != 0 then
+      all_target = "$(TARGET)"
+    else
+      all_target = ""
+    end
+
+    if $generating_region == @@root_namespace then
+      if Region.get_link_roots.length > 1 then
+        all_target += " sub_regions"
+      end
+      timestamp = " $(TIMESTAMP)"
+    else
+      timestamp = ""
+    end
+
+    f.print "all : #{all_target}\n\n"
+    f.printf TECSMsg.get( :MDEP_comment ), "#_MDEP_#"
+    f.print "-include $(GEN_DIR)/Makefile.tecsgen\n"
+    if $generating_region.get_n_cells != 0 then
+      # Makefile.depend の include
+      f.print "-include $(GEN_DIR)/Makefile.depend\n\n"
+
+      f.print "$(TARGET) :#{timestamp} $(CELLTYPE_COBJS) $(TECSGEN_COBJS) $(PLUGIN_COBJS) $(OTHER_OBJS)\n"
+      f.print "	$(LD) -o $(TARGET) $(TECSGEN_COBJS) $(CELLTYPE_COBJS) $(PLUGIN_COBJS) $(OTHER_OBJS) $(LDFLAGS)\n\n"
+    end
+
+    if Region.get_link_roots.length > 1 && $generating_region == @@root_namespace then
+      f.print "\nsub_regions:$(TIMESTAMP)\n"
+      Region.get_link_roots.each {|region|
+        if region.get_global_name != "" then  # Root region: この Makefile 自身
+          f.print "\tcd #{region.get_global_name}; make all\n"
+        end
+      }
+      f.print "\n"
+    end
+
+    # clean: ターゲット
+    f.print "clean :\n"
+    if $generating_region == @@root_namespace then
+      Region.get_link_roots.each {|region|
+        if region.get_global_name != "" then  # Root region: この Makefile 自身
+          f.print "\tcd #{region.get_global_name}; make clean\n"
+        end
+      }
+    end
+	  f.print "	rm -f $(CELLTYPE_COBJS) $(TECSGEN_COBJS) $(PLUGIN_COBJS) $(OTHER_OBJS) $(TARGET) #{timestamp}\n"
+    if $generating_region == @@root_namespace then
+      f.print "	rm -rf $(GEN_DIR)\n"
+    end
+    f.print "\n"
+
+    # tecs: ターゲット
+    if $generating_region == @@root_namespace then
+      f.print "tecs : $(PRE_TECSGEN_TARGET) $(TIMESTAMP) $(POST_TECSGEN_TARGET)\n\n"
+      f.print "$(TIMESTAMP) : $(TECS_IMPORTS)\n"
+      f.print "	$(TECSGEN) #{TECSGEN.subst_tecspath( $arguments, true )}\n\n"
+      # f.print "	touch $(TIMESTAMP)\n\n"
+    else
+      f.print "tecs:\n"
+      f.print "\t@echo \"run 'make tecs' in root region\"\n\n"
+    end
+
+    # tecsflow:, tcflow ターゲット
+    if $generating_region.get_n_cells != 0 || $generating_region == @@root_namespace then
+      f.print "#####  TECSFlow targets  #####\n"
+    end
+
+    if Region.get_link_roots.length > 1 && $generating_region == @@root_namespace then
+      tecsflow_target = "tecsflow_sub"
+      if $generating_region.get_n_cells > 0 then
+        f.print "tecsflow: tecs tecsflow_sub\n"
+      else
+        f.print "tecsflow:\n"
+      end
+      Region.get_link_roots.each {|region|
+        if region.get_n_cells > 0 then
+          f.print "\tcd #{region.get_global_name}; make tecsflow\n"
+        end
+      }
+      f.print "\n"
+    else
+      tecsflow_target = "tecsflow"
+    end
+
+    if $generating_region.get_n_cells != 0 then
+      f.print "#{tecsflow_target} : $(GEN_DIR)/tecsgen.rbdmp tcflow\n"
+      f.print "\ttecsflow -g $(GEN_DIR)\n\n"
+      f.print "tecsflow_u : $(GEN_DIR)/tecsgen.rbdmp tcflow\n"
+      f.print "\ttecsflow -g $(GEN_DIR) -U\n\n"
+      f.print "$(GEN_DIR)/tecsgen.rbdmp : tecs\n\n"
+      f.print "tcflow : tecs\n"
+      f.print "\tmake tcflow_exec\n\n"
+      f.print "tcflow_exec : $(GEN_DIR)/tcflow.rbdmp\n"
+      f.print "$(GEN_DIR)/tcflow.rbdmp : $(CELLTYPE_SRCS) $(PLUGIN_CELLTYPE_SRCS)\n"
+      f.print "\ttcflow -g $(GEN_DIR) -c '$(CC) -E -DTECSFLOW -DTECSGEN $(CFLAGS) -I ./' $^\n"
+    end
+
+    if $generating_region.get_n_cells != 0 || $generating_region == @@root_namespace then
+      f.print "#####  end TECSFlow targets  #####\n\n"
+    end
+
+    # generic %.o : %.c
+    f.print "# generic target for objs\n"
+    f.print "$(_TECS_OBJ_DIR)%.o : %.#{$c_suffix}\n"
+    f.print "	$(CC) -c $(CFLAGS) -o $@ $<\n\n"
+
+    lines = TECSGEN::Makefile.get_lines
+    if lines.length > 0 then
+      f.print( "# additional lines\n" )
+      lines.each{ |line|
+        f.print  line, "\n"
+      }
+      f.print( "# end additional lines\n\n" )
+    end
+
+    f.close
+  end
+
+  def gen_makefile_tecsgen
+    ### Makefile.tecsgen の生成
+    f = AppFile.open( "#{$gen}/Makefile.tecsgen" )
+
+    f.print <<EOT
+# generated automatically by tecsgen.
+# This file is not intended to modify.
+#
+# Makefile variables below are defined.
+#  TECS_IMPORT_CDLS          .cdl files improted by import statement
+#  SIGNATURE_HEADERS         .h files of signature
+#  CELLTYPE_TECSGEN_HEADERS  .h files of celltype
+#  CELLTYPE_FACTORY_HEADERS  .h files of celltype's factory
+#  TECS_HEADERS              summary of .h files above
+#  TECS_INLINE_HEADERS       .h files of celltype inline header
+#  PLUGIN_INLINE_HEADERS     .h files of plugin generated inline header
+#
+#  TECS_COBJS                .o files of TECS
+#                            = $(TECSGEN_COBJS)+$(PLUGIN_COBJS)+$(CELLTYPE_COBJS)
+#                            = $(TECS_KERNEL_COBJS)+$(TECS_KERNEL_COBJS)+$(TECS_OUTOFDOMAIN_COBJS)
+#                            = $(TECSGEN_domain_COBJS)+$(PLUGIN_domain_COBJS)+$(CELLTYPE_domain_COBJS) for each domain
+#
+#  TECSGEN_COBJS             .o files of celltype_tecsgen.c
+#  CELLTYPE_COBJS            .o files of celltype.c (celltype code)
+#  PLUGIN_COBJS              .o files of plugin generated .c files
+#
+#  TECSGEN_SRCS              .c files of celltype_tecsgen.c
+#  CELLTYPE_SRCS             .c files of celltype.c (celltype code)
+#  PLUGIN_SRCS               .c files of plugin generated
+#  PLUGIN_CELLTYPE_SRCS      .c files of plugin generated celltype.c (celltype code)
+#  PLUGIN_TECSGEN_SRCS       .c files of plugin generated celltype_tecsgen.c
+#
+# Variables for domain
+#  TECS_DOMAINS             domain names
+#  TECS_KERNEL_COBJS        .o files of kernel domain (tecsgen, celltype, plugin)
+#  TECS_USER_COBJS          .o files of user domain (tecsgen, celltype, plugin)
+#  TECS_OUTOFDOMAIN_COBJS   .o files of OutOfDomain (tecsgen, celltype, plugin)
+#  TECSGEN_domain_COBJS     .o files of celltype_tecsgen.c files for each domain
+#  PLUGIN_domain_COBJS      .o files of plugin generated .c files for each domain
+#  CELLTYPE_domain_COBJS    .o files of celltype.c files for each domain
+#  TECSGEN_domain_SRCS      .c files of celltype_domain_tecsgen.c
+#  PLUGIN_domain_SRCS       .c files of plugin generated .c files for each domain
+#  CELLTYPE_domain_SRCS     .c files of celltype.c files for each domain
+
+EOT
+
+    f.print( "TECS_IMPORT_CDLS =" )
+    Import.get_list.each{ |cdl_expand_path, import|
+      path = import.get_cdl_path
+      if TECSGEN.is_absolute_path? path then
+        path = TECSGEN.subst_tecspath path
+      end
+      f.print " "
+      f.print( path )
+    }
+    f.print( "\n" )
+    f.print( "TECS_IMPORT_HEADERS =" )
+    Import_C.get_header_list.each{ |header,path|
+      if TECSGEN.is_absolute_path? path then
+        path = TECSGEN.subst_tecspath path
+      end
+      f.print " "
+      f.print path
+    }
+    f.print "\n"
+    f.print "TECS_IMPORTS = $(TECS_IMPORT_CDLS) $(TECS_IMPORT_HEADERS)\n\n"
+
+    f.print "SIGNATURE_HEADERS = \\\n"
+    if $generating_region.get_n_cells != 0 then
+      @signature_list.each{ |s|
+        f.print "\t$(GEN_DIR)/#{s.get_global_name}_tecsgen.#{$h_suffix} \\\n"
+      }
+    end
+    f.print "# SIGNATURE_HEADERS terminator\n\n"
+
+    b_inline_only_or_proc = Proc.new { |ct|  true    }
+    f.print "CELLTYPE_TECSGEN_HEADERS = \\\n"
+    gen_celltype_names( f, "\t$(GEN_DIR)/", "_tecsgen.h \\\n", true, b_inline_only_or_proc )
+    gen_celltype_names( f, "\t$(GEN_DIR)/", "_tecsgen.h \\\n", false, b_inline_only_or_proc )
+    f.print "# CELLTYPE_TECSGEN_HEADERS terminator\n\n"
+    f.print "CELLTYPE_FACTORY_HEADERS = \\\n"
+    gen_celltype_names( f, "\t$(GEN_DIR)/", "_factory.h \\\n", true, b_inline_only_or_proc )
+    gen_celltype_names( f, "\t$(GEN_DIR)/", "_factory.h \\\n", false, b_inline_only_or_proc )
+    f.print "# CELLTYPE_FACTORY_HEADERS terminator\n\n"
+    f.print "# TECS_HEADERS:  headers generated by tecsgen\n"
+    f.print "TECS_HEADERS = $(SIGNATURE_HEADERS) $(CELLTYPE_TECSGEN_HEADERS) $(CELLTYPE_FACTORY_HEADERS)\n\n"
+    b_inline_only_or_proc = true
+    f.print "TECS_INLINE_HEADERS = \\\n"
+    gen_celltype_names( f, "\t", "_tecsgen.h \\\n", false, b_inline_only_or_proc )
+    f.print "# TECS_INLINE_HEADERS terminator\n\n"
+    f.print "PLUGIN_INLINE_HEADERS = \\\n"
+    gen_celltype_names( f, "\t", "_tecsgen.h \\\n", true, b_inline_only_or_proc )
+    f.print "# PLUGIN_INLINE_HEADERS terminator\n\n"
+
+    ### set domain variables ###
+    domain_type = nil
+    domain_regions = nil
+    DomainType.get_domain_regions.each{ |dt, regions|
+      # domain_type は一つのノードには、一つしかないので、このループは、必ず一回しか回らない
+        ###   mikan 複数のノードがあり、異なる domain_type が指定される可能性はある
+      domain_regions = regions
+      domain_type = dt
+    }
+    if domain_regions == nil then
+      # in case no 'domain' specified at region
+      domain_regions = [ Region.get_root ]
+    end
+
+    hasDomainProc = Proc.new{
+      if domain_regions.length > 1 || domain_regions[0] != Region.get_root then
+        true
+      else
+        false
+      end
+    }
+    decideDomainNameProc = Proc.new { |region|
+      if region.is_root? then
+        if hasDomainProc.call then
+          dn = "_Root_"
+        else
+          dn = ""
+        end
+      else
+        dn = "_#{region.get_namespace_path.get_global_name}"
+      end
+    }
+
+    f.print( "# TECS_COBJS: all objects of TECS, include both user written code and tecsgen automatically generated code\n" )
+    f.print( "TECS_COBJS = $(TECSGEN_COBJS) $(PLUGIN_COBJS) $(CELLTYPE_COBJS)\n\n" )
+
+    ### in case domain is used ###
+    if hasDomainProc.call then
+
+      f.print( "# TECS_DOMAINS: list of domain names (names of 'domain' spacified region)\n" )
+      f.print( "TECS_DOMAINS = " )
+      domain_regions.each{ |r|
+        if r.get_domain_type.get_option != "OutOfDomain" then
+          f.print( " #{r.get_namespace_path.get_global_name}" )
+        end
+      }
+      f.print( "\n\n" )
+
+      f.print( "# TECS_KERNEL_COBJS: objects belong to kernel domain\n" )
+      f.print( "TECS_KERNEL_COBJS = \\\n" )
+      domain_regions.each{ |r|
+        if r.get_domain_type.get_kind == :kernel then
+          f.print( "	$(TECSGEN#{decideDomainNameProc.call r}_COBJS) \\\n" )
+          f.print( "	$(PLUGIN#{decideDomainNameProc.call r}_COBJS) \\\n" )
+          f.print( "	$(CELLTYPE#{decideDomainNameProc.call r}_COBJS) \\\n" )
+        end
+      }
+      f.print( "# TECS_KERNEL_COBJS terminator\n\n" )
+
+      f.print( "# TECS_USER_COBJS: objects belong to user domain\n" )
+      f.print( "TECS_USER_COBJS = \\\n" )
+      domain_regions.each{ |r|
+        if r.get_domain_type.get_kind == :user then
+          f.print( "	$(TECSGEN#{decideDomainNameProc.call r}_COBJS) \\\n" )
+          f.print( "	$(PLUGIN#{decideDomainNameProc.call r}_COBJS) \\\n" )
+          f.print( "	$(CELLTYPE#{decideDomainNameProc.call r}_COBJS) \\\n" )
+        end
+      }
+      f.print( "# TECS_USER_COBJS terminator\n\n" )
+
+      f.print( "# TECS_OUTOFDOMAIN_COBJS: objects belong to OutOfDomain\n" )
+      f.print( "TECS_OUTOFDOMAIN_COBJS = \\\n" )
+      domain_regions.each{ |r|
+        if r.get_domain_type.get_kind == :OutOfDomain then
+          f.print( "	$(TECSGEN#{decideDomainNameProc.call r}_COBJS) \\\n" )
+          f.print( "	$(PLUGIN#{decideDomainNameProc.call r}_COBJS) \\\n" )
+          f.print( "	$(CELLTYPE#{decideDomainNameProc.call r}_COBJS) \\\n" )
+        end
+      }
+      f.print( "# TECS_OUTOFDOMAIN_COBJS terminator\n\n" )
+      
+      f.print( "# TECSGEN_COBJS: objects from sources which are automatically generated by tecsgen\n" )
+      f.print( "TECSGEN_COBJS = \\\n" )
+      domain_regions.each{ |r|
+        f.print( "	$(TECSGEN#{decideDomainNameProc.call r}_COBJS) \\\n" )
+      }
+      f.print( "# TECSGEN_COBJS terminator\n\n" )
+
+      f.print( "# PLUGIN_COBJS: objects from sources which are automatically generated by plugin(s)\n" )
+      f.print( "PLUGIN_COBJS = \\\n" )
+      domain_regions.each{ |r|
+        f.print( "	$(PLUGIN#{decideDomainNameProc.call r}_COBJS) \\\n" )
+      }
+      f.print( "# PLUGIN_COBJS terminator\n\n" )
+
+      f.print( "CELLTYPE_COBJS = \\\n" )
+      domain_regions.each{ |r|
+        f.print( "	$(CELLTYPE#{decideDomainNameProc.call r}_COBJS) \\\n" )
+      }
+      f.print( "# CELLTYPE_COBJS terminator\n\n" )
+
+      f.print( "TECSGEN_SRCS = \\\n" )
+      domain_regions.each{ |r|
+        f.print( "	$(TECSGEN#{decideDomainNameProc.call r}_SRCS) \\\n" )
+      }
+      f.print( "# TECSGEN_SRCS terminator\n\n" )
+
+      f.print( "PLUGIN_SRCS = \\\n" )
+      domain_regions.each{ |r|
+        f.print( "	$(PLUGIN#{decideDomainNameProc.call r}_SRCS) \\\n" )
+      }
+      f.print( "# PLUGIN#_SRCS terminator\n\n" )
+    end
+
+    ###
+    f.print( "# TECSGEN_COBJS: objects from sources which are automatically generated by tecsgen\n" )
+    domain_regions.each{ |r|
+      nsp = decideDomainNameProc.call( r )
+      f.print( "TECSGEN#{nsp}_COBJS = \\\n" )
+      gen_celltype_names_domain( f, "	$(_TECS_OBJ_DIR)", "_tecsgen.o \\\n", domain_type, r, false )
+      f.print( "# TECSGEN#{nsp}_COBJS terminator\n\n" )
+    }
+
+    f.print( "# PLUGIN_COBJS: objects from sources which are automatically generated by plugin(s)\n" )
+    domain_regions.each{ |r|
+      nsp = decideDomainNameProc.call( r )
+      f.print( "PLUGIN#{nsp}_COBJS = \\\n" )
+      gen_celltype_names_domain( f, "	$(_TECS_OBJ_DIR)", "_tecsgen.o \\\n", domain_type, r, true )
+      gen_celltype_names_domain2( f, "	$(_TECS_OBJ_DIR)", ".o \\\n", domain_type, r, true, false )
+      f.print( "# PLUGIN#{nsp}_COBJS terminator\n\n" )
+    }
+
+    f.print( "# CELLTYPE_COBJS: objects of celltype code written by user\n" )
+    domain_regions.each{ |r|
+      nsp = decideDomainNameProc.call( r )
+      f.print( "CELLTYPE#{nsp}_COBJS = \\\n" )
+      gen_celltype_names_domain2( f, "	$(_TECS_OBJ_DIR)", ".o \\\n", domain_type, r, false, false )
+      f.print( "# CELLTYPE#{nsp}_COBJS terminator\n\n" )
+    }
+
+    f.print( "# TECSGEN_SRCS: sources automatically generated by tecsgen\n" )
+    domain_regions.each{ |r|
+      nsp = decideDomainNameProc.call( r )
+      f.print( "TECSGEN#{nsp}_SRCS = \\\n" )
+      gen_celltype_names_domain( f, "	$(GEN_DIR)/", "_tecsgen.#{$c_suffix} \\\n", domain_type, r, false )
+      f.print( "# TECSGEN#{nsp}_SRCS terminator\n\n" )
+    }
+
+    f.print( "# PLUGIN_SRCS: sources automatically generated by plugin\n" )
+    f.print( "PLUGIN_CELLTYPE_SRCS = \\\n" )
+    domain_regions.each{ |r|
+      nsp = decideDomainNameProc.call( r )
+      f.print( "  $(PLUGIN#{nsp}_CELLTYPE_SRCS)\\\n" )
+    }
+    f.print( "# PLUGIN_CELLTYPE_SRCS terminator\n\n" )
+    f.print( "PLUGIN_TECSGEN_SRCS = \\\n" )
+    domain_regions.each{ |r|
+      nsp = decideDomainNameProc.call( r )
+      f.print( "  $(PLUGIN#{nsp}_TECSGEN_SRCS)\\\n" )
+    }
+    f.print( "# PLUGIN_TECSGEN_SRCS terminator\n\n" )
+    domain_regions.each{ |r|
+      nsp = decideDomainNameProc.call( r )
+      f.print( "PLUGIN#{nsp}_SRCS = $(PLUGIN#{nsp}_CELLTYPE_SRCS) $(PLUGIN#{nsp}_TECSGEN_SRCS)\n\n" )
+      f.print( "PLUGIN#{nsp}_CELLTYPE_SRCS = \\\n" )
+      gen_celltype_names_domain2( f, "", ".#{$c_suffix} \\\n", domain_type, r, true, false )
+      f.print( "# PLUGIN#{nsp}_CELLTYPE_SRCS terminator\n\n" )
+      nsp = decideDomainNameProc.call( r )
+      f.print( "PLUGIN#{nsp}_TECSGEN_SRCS = \\\n" )
+      gen_celltype_names_domain( f, "", "_tecsgen.#{$c_suffix} \\\n", domain_type, r, true )
+      f.print( "# PLUGIN#{nsp}_TECSGEN_SRCS terminator\n\n" )
+    }
+
+    f.print( "# CELLTYPE_SRCS: sources of celltype code written by user\n" )
+     f.print( "CELLTYPE_SRCS = \\\n" )
+     gen_celltype_names( f, "	", ".#{$c_suffix} \\\n", false, false )
+      f.print( "# CELLTYPE_SRCS terminator\n\n" )
+    f.close
+
+  end
+
+  #=== すべてのセルタイプの名前を出力
+  #f::       FILE:   出力先ファイル
+  #prepend:: string: 前置文字列
+  #append::  string: 後置文字列
+  #b_plguin::  bool:   plugin により生成されたセルタイプを出力
+  ##b_inline_only::  bool:   true ならば inline の entry port のみのセルタイプを含める
+  #b_inline_only_or_proc::  bool|Proc:   true ならば inline の entry port のみ、かつインアクティブなセルタイプを含める
+  #                                      Proc ならば Proc を実行した結果 true ならば含める
+  #  namespace "::" から呼出される
+  def gen_celltype_names( f, prepend, append, b_plugin, b_inline_only_or_proc = true )
+    dbgPrint "gen_celltype_names #{@name}\n"
+
+    @celltype_list.each { |ct|
+      next if ! ct.need_generate?
+#      next if b_inline_only == false && ct.is_all_entry_inline?
+      next if b_inline_only_or_proc == false && ct.is_all_entry_inline? && ! ct.is_active?
+      # print "Proc:", b_inline_only_or_proc.kind_of?( Proc ), b_inline_only_or_proc.class, "\n"
+      next if b_inline_only_or_proc.kind_of?( Proc ) && ( b_inline_only_or_proc.call( ct ) == false )
+      if ( b_plugin && ct.get_plugin ) || ( ! b_plugin && ! ct.get_plugin ) then
+        f.print " #{prepend}#{ct.get_global_name}#{append}"
+      end
+    }
+    @namespace_list.each { |ns|
+      ns.gen_celltype_names( f, prepend, append, b_plugin, b_inline_only_or_proc )
+    }
+
+  end
+
+  #=== すべてのセルタイプの名前を出力
+  #region:: Region:
+  # gen_celltype_names とgen_celltype_names_domain の相違：
+  #   region を domain_roots に含む場合、出力する．
+  #   または、region を含まないが、domain_roots が複数かつルートリージョンの場合、出力する．
+  # それ以外は、gen_celltype_names の説明を参照
+  def gen_celltype_names_domain( f, prepend, append, domain_type, region, b_plugin, b_inline_only = true )
+    dbgPrint "gen_celltype_names #{@name}\n"
+
+    @celltype_list.each { |ct|
+      next if ! ct.need_generate?
+#      next if b_inline_only == false && ct.is_all_entry_inline?
+      next if b_inline_only == false && ct.is_all_entry_inline? && ! ct.is_active?
+      if ( b_plugin && ct.get_plugin ) || ( ! b_plugin && ! ct.get_plugin ) then
+        regions = ct.get_domain_roots[ domain_type ]
+        if regions.include?( region ) then
+          # p "BBB celltype:#{ct.get_name} domain:#{domain_type} append:#{append}"
+          if region.is_root? then
+            nsp = ""
+          else
+            nsp = "_#{region.get_namespace_path.get_global_name}"
+          end
+          f.print " #{prepend}#{ct.get_global_name}#{nsp}#{append}"
+        elsif region.is_root? then
+          # the case of domain_roots >= 2 && no cell in root region
+          if regions.length > 1 then
+            f.print " #{prepend}#{ct.get_global_name}#{append}"
+          end
+        end
+      end
+    }
+    @namespace_list.each { |ns|
+      ns.gen_celltype_names_domain( f, prepend, append, domain_type, region, b_plugin, b_inline_only )
+    }
+  end
+  #== Namespace#すべてのセルタイプの名前を出力
+  # セルタイプコードのための名前出力
+  # gen_celltype_names_domain と gen_celltype_names_domain2 の相違
+  # ・どれか一つのリージョンにしか出さない
+  #     domain_roots が1つだけで、指定リージョンを含む
+  #     domain_roots が2つ以上で、指定リージョンがルートリージョン 
+  # ・ドメイン名を付加しない
+  def gen_celltype_names_domain2( f, prepend, append, domain_type, region, b_plugin, b_inline_only = true )
+    dbgPrint "gen_celltype_names #{@name}\n"
+
+    @celltype_list.each { |ct|
+      next if ! ct.need_generate?
+#      next if b_inline_only == false && ct.is_all_entry_inline?
+      next if b_inline_only == false && ct.is_all_entry_inline? && ! ct.is_active?
+      if ( b_plugin && ct.get_plugin ) || ( ! b_plugin && ! ct.get_plugin ) then
+        # p "BBB celltype:#{ct.get_name} domain:#{domain_type} append:#{append}"
+        regions = ct.get_domain_roots[ domain_type ]
+        if regions.include?( region ) && regions.length == 1 then
+          f.print " #{prepend}#{ct.get_global_name}#{append}"
+        elsif region.is_root? then
+          # the case of domain_roots >= 2 && no cell in root region
+          if regions.length > 1 then
+            f.print " #{prepend}#{ct.get_global_name}#{append}"
+          end
+        end
+      end
+    }
+    @namespace_list.each { |ns|
+      ns.gen_celltype_names_domain2( f, prepend, append, domain_type, region, b_plugin, b_inline_only )
+    }
+  end
+
+  #=== Namespace#すべてのシグニチャをたどる
+  def travers_all_signature # ブロック引数 { |signature|  }
+    proc = Proc.new    # このメソッドのブロック引数
+    @signature_list.each{ |sig|
+      proc.call sig
+    }
+    @namespace_list.each{ |ns|
+      ns.travers_all_signature_proc proc
+    }
+  end
+  def travers_all_signature_proc proc
+    @signature_list.each{ |sig|
+      proc.call sig
+    }
+    @namespace_list.each{ |ns|
+      ns.travers_all_signature_proc proc
+    }
+  end
+
+  #=== Namespace#すべてのセルタイプをたどる
+  def travers_all_celltype # ブロック引数 { |celltype|  }
+    proc = Proc.new    # このメソッドのブロック引数
+    @celltype_list.each{ |ct|
+      proc.call ct
+    }
+    @namespace_list.each{ |ns|
+      ns.travers_all_celltype_proc proc
+    }
+  end
+  def travers_all_celltype_proc proc
+    @celltype_list.each{ |ct|
+      proc.call ct
+    }
+    @namespace_list.each{ |ns|
+      ns.travers_all_celltype_proc proc
+    }
+  end
+end
+
+class Typedef
+  def gen_gh f
+
+#    print "Typedef.gen_gh\n"
+#    show_tree 1
+
+    f.printf( "typedef %-14s %s%s;\n",
+		"#{@declarator.get_type.get_type_str}",
+		"#{@declarator.get_name}",
+		"#{@declarator.get_type.get_type_str_post}")
+  end
+end
+
+class StructType < Type
+  def gen_gh f
+
+#    print "StructType.gen_gh\n"
+#    show_tree 1
+
+    if ! @b_define then
+      return
+    end
+
+    f.print "struct #{@tag} {\n"
+
+    @members_decl.get_items.each{ |i|
+      f.printf( "                %-14s %s%s;\n", "#{i.get_type.get_type_str}", "#{i.get_name}", "#{i.get_type.get_type_str_post}" )
+    }
+
+    f.print "};\n"
+
+  end
+end
+
+class Signature
+
+  def generate
+    generate_signature_header
+  end
+
+  def generate_post
+    generate_signature_header_post
+  end
+
+  def generate_signature_header
+    f = AppFile.open("#{$gen}/#{@global_name}_tecsgen.#{$h_suffix}")
+
+    print_note f
+    gen_sh_guard f
+    gen_sh_info f
+    gen_sh_include f
+
+    ifndef_macro_only f
+    gen_sh_func_tab f
+    endif_macro_only f
+    gen_sh_func_id f
+
+    f.close
+  end
+
+  def generate_signature_header_post
+    f = AppFile.open("#{$gen}/#{@global_name}_tecsgen.#{$h_suffix}")
+    gen_sh_endif f
+    f.close
+  end
+
+
+#####  signature header
+
+  def gen_sh_guard f
+    f.print("#ifndef #{@global_name}_TECSGEN_H\n")
+    f.print("#define #{@global_name}_TECSGEN_H\n\n")
+  end
+
+  def gen_sh_info f
+    f.print <<EOT
+/*
+ * signature   :  #{@name}
+ * global name :  #{@global_name}
+ * context     :  #{get_context}
+ */
+
+EOT
+  end
+
+  def gen_sh_include f
+    dl = get_descriptor_list
+    if dl.length > 0 then
+      f.printf TECSMsg.get(:SDI_comment), "#_SDI_#"
+      dl.each{ |dt,param|
+        f.print <<EOT
+/* pre-typedef incomplete-type to avoid error in case of mutual or cyclic reference */
+#ifndef Descriptor_of_#{dt.get_global_name}_Defined
+#define  Descriptor_of_#{dt.get_global_name}_Defined
+typedef struct { struct tag_#{dt.get_global_name}_VDES *vdes; } Descriptor( #{dt.get_global_name} );
+#endif
+EOT
+#        f.print "#include \"#{dt.get_global_name}_tecsgen.#{$h_suffix}\"\n"
+      }
+      f.print "\n"
+    end
+
+  end
+
+  def gen_sh_func_tab f
+
+    # シグニチャディスクリプタの出力
+    f.printf TECSMsg.get(:SD_comment), "#_SD_#"
+    f.print "struct tag_#{@global_name}_VDES {\n"
+    f.print "    struct tag_#{@global_name}_VMT *VMT;\n"
+    f.print "};\n\n"
+
+    # シグニチャ関数テーブルの出力
+    f.printf TECSMsg.get(:SFT_comment), "#_SFT_#"
+    f.print( "struct tag_#{@global_name}_VMT {\n" )
+    get_function_head_array.each{ |fun|
+      f.print "    "
+      functype = fun.get_declarator.get_type
+      f.printf( "%-14s", functype.get_type_str )
+
+      f.print( " (*#{fun.get_name}__T)(" )
+      f.print( " const struct tag_#{@global_name}_VDES *edp" ) unless @singleton
+
+      if functype.get_paramlist then
+        items = functype.get_paramlist.get_items
+        len = items.length
+      else
+        # ここで nil になるのは、引数なしの時に void がなかった場合
+        items = []
+        len = 0
+      end
+
+      i = 0
+      items.each{ |param|
+        f.print ", "
+        f.print( param.get_type.get_type_str )
+        f.print( " " )
+        f.print( param.get_name )
+        f.print( param.get_type.get_type_str_post )
+        i += 1
+      }
+      f.print " );\n"
+    }
+    if get_function_head_array.length == 0 then
+      f.print( "    void   (*dummy__)(void);\n" )
+    end
+
+    f.print "};\n\n"
+    f.printf TECSMsg.get(:SDES_comment), "#_SDES_#"
+    f.print <<EOT
+#ifndef Descriptor_of_#{@global_name}_Defined
+#define  Descriptor_of_#{@global_name}_Defined
+typedef struct { struct tag_#{@global_name}_VDES *vdes; } Descriptor( #{@global_name} );
+#endif
+EOT
+  end
+
+  #=== Signature# 関数の ID の define を出力
+  def gen_sh_func_id f
+    f.print "/* function id */\n"
+    get_function_head_array.each{ |fun|
+      f.printf( "#define\tFUNCID_%-31s (%d)\n", "#{@global_name}_#{fun.get_name}".upcase, get_id_from_func_name( fun.get_name ) )
+    }
+    f.print "\n"
+  end
+
+  def gen_sh_endif f
+    f.print("#endif /* #{@global_name}_TECSGEN_H */\n")
+  end
+
+end
+
+class Celltype
+
+  def generate
+
+    if need_generate?    # セルのないセルタイプは生成しない
+
+      generate_private_header
+      generate_factory_header
+      generate_cell_code
+      generate_template_code
+      generate_inline_template_code
+      generate_celltype_factory_code
+      generate_cell_factory_code
+      generate_makefile
+
+    elsif $generate_all_template   # テンプレートコード生成オプション
+
+      generate_template_code
+      generate_inline_template_code
+
+      # generate_makefile_template は Makefile に追記するものだから、呼び出さない
+
+    end
+
+  end
+
+  def generate_post
+    return if ! need_generate?    # セルのないセルタイプは生成しない
+
+    generate_private_header_post
+    generate_factory_header_post
+  end
+
+  def generate_private_header
+
+    f = AppFile.open("#{$gen}/#{@global_name}_tecsgen.#{$h_suffix}")
+
+    print_note f
+
+    gen_ph_guard f
+    gen_ph_info f
+    gen_ph_include f
+    #
+    ifndef_macro_only f
+    begin_extern_C f
+    gen_ph_cell_cb_type f
+    gen_ph_INIB_as_CB f
+    gen_ph_extern_cell f          # セルタイプグルコード以外は参照しない
+    gen_ph_typedef_idx f          # mikan 参照するものができていない
+    gen_ph_ep_fun_prototype f
+    end_extern_C f
+    endif_macro_only f
+	#
+    gen_ph_include_cb_type f
+
+    if @n_entry_port_inline == 0 then
+      # inline がなければ CB_TYPE_ONLY とする
+      # inline ありの場合、いったん define しておいて、後ですべて undef する
+      ifndef_cb_type_only f
+    end
+
+    gen_ph_base f
+    gen_ph_valid_idx f
+    gen_ph_n_cp f                 if @n_call_port_array > 0
+    gen_ph_n_ep f                 if @n_entry_port_array > 0
+    gen_ph_test_optional_call_port f
+    gen_ph_get_cellcb f
+    gen_ph_attr_access f          if @n_attribute_rw > 0 || @n_attribute_ro > 0 || @n_var > 0
+    f.print "#ifndef TECSFLOW\n"
+    gen_ph_cp_fun_macro f, false  if @n_call_port > 0
+    f.print "#else  /* TECSFLOW */\n"
+    gen_ph_cp_fun_macro f, true   if @n_call_port > 0
+    f.print "#endif /* TECSFLOW */\n"
+#    gen_ph_abstract_ep_des_type f
+
+    if @n_entry_port_inline == 0 then
+      endif_cb_type_only f
+    end
+
+    ifndef_macro_only f
+    begin_extern_C f
+#    gen_ph_cell_cb_type f
+#    gen_ph_INIB_as_CB f
+#    gen_ph_extern_cell f          # セルタイプグルコード以外は参照しない
+    # gen_ph_typedef_idx f          # mikan 参照するものができていない
+#    gen_ph_ep_fun_prototype f
+    gen_ph_ep_skel_prototype f
+
+    #--- CB_TYPE_ONLY の場合、ref_desc, set_desc 関数は含めない (マクロ参照するため)
+    if @n_entry_port_inline == 0 then
+      ifndef_cb_type_only f
+    end
+    gen_ph_ref_desc_func f
+    gen_ph_set_desc_func f
+    if @n_entry_port_inline == 0 then
+      endif_cb_type_only f
+    end
+    end_extern_C f
+    endif_macro_only f
+
+    # 短縮形などのマクロ出力
+    if @n_entry_port_inline == 0 then
+      ifndef_cb_type_only f
+    end
+    gen_ph_valid_idx_abbrev f
+    gen_ph_get_cellcb_abbrev f
+    gen_ph_attr_access_abbrev f   if @n_attribute_rw > 0 || @n_attribute_ro > 0 || @n_var > 0
+    gen_ph_cp_fun_macro_abbrev f  if @n_call_port > 0
+    gen_ph_ref_desc_macro_abbrev f
+    gen_ph_set_desc_macro_abbrev f
+    gen_ph_test_optional_call_port_abbrev f
+    gen_ph_ep_fun_macro f         if @n_entry_port > 0
+    gen_ph_foreach_cell f         # FOREACH マクロの出力
+    gen_ph_cb_initialize_macro f   # CB 初期化マクロの出力．消費しないので ram_initializer フラグに関わらず出力
+    gen_ph_dealloc_code f, ""
+    gen_ph_dealloc_code f, "_RESET"
+    if @n_entry_port_inline == 0 then
+      endif_cb_type_only f
+    end
+
+    f.close
+  end
+
+  def generate_private_header_post
+
+    f = AppFile.open("#{$gen}/#{@global_name}_tecsgen.#{$h_suffix}")
+
+    ifndef_macro_only f
+    gen_ph_inline f
+    endif_macro_only f
+
+    if @n_entry_port_inline > 0 then
+      ifdef_cb_type_only f
+      f.printf TECSMsg.get( :UDF_comment ), "#_UDF_#"
+      f.print "#undef VALID_IDX\n"
+      f.print "#undef GET_CELLCB\n"
+      f.print "#undef CELLCB\n"
+      f.print "#undef CELLIDX\n"
+      f.print "#undef #{@name}_IDX\n"
+
+      f.print "#undef FOREACH_CELL\n"
+      f.print "#undef END_FOREACH_CELL\n"
+      f.print "#undef INITIALIZE_CB\n"
+      f.print "#undef SET_CB_INIB_POINTER\n"
+
+      @attribute.each { |a|
+        f.print( "#undef ATTR_#{a.get_name}\n" )
+        f.print( "#undef #{@global_name}_ATTR_#{a.get_name}\n" )
+        f.print( "#undef #{@global_name}_GET_#{a.get_name}\n" )
+      }
+      @var.each { |v|
+        f.print( "#undef VAR_#{v.get_name}\n" )
+        f.print( "#undef VAR_#{v.get_name}\n" )
+        f.print( "#undef #{@global_name}_VAR_#{v.get_name}\n" )
+        f.print( "#undef #{@global_name}_GET_#{v.get_name}\n" )
+        f.print( "#undef #{@global_name}_SET_#{v.get_name}\n" )
+      }
+      @port.each { |p|
+        next if p.get_port_type != :CALL
+
+        # is_...joined は omit するケースでも出力されるため、omit を検査する前に出力
+        if p.is_optional? then
+          f.print( "#undef is_#{p.get_name}_joined\n" )
+        end
+
+        next if p.is_omit?
+
+        p.get_signature.get_function_head_array.each{ |fun|
+          f.print( "#undef #{@global_name}_#{p.get_name}_#{fun.get_name}\n" )
+          if ! p.is_require? || p.has_name? then
+            f.print( "#undef #{p.get_name}_#{fun.get_name}\n" )
+          else
+            f.print( "#undef #{fun.get_name}\n" )
+          end
+        }
+        if p.is_dynamic? then
+          f.print( "#undef #{p.get_name}_set_descriptor\n" )
+          if p.is_optional? then
+            f.print( "#undef #{p.get_name}_unjoin\n" )
+          end
+        elsif p.is_ref_desc? then
+          f.print( "#undef #{p.get_name}_refer_to_descriptor\n" )
+          f.print( "#undef #{p.get_name}_ref_desc\n" )
+        end
+      }
+      @port.each { |p|
+        next if p.get_port_type != :ENTRY
+        next if p.is_omit?
+        p.get_signature.get_function_head_array.each{ |fun|
+          f.print( "#undef #{p.get_name}_#{fun.get_name}\n" )
+        }
+      }
+
+      gen_ph_dealloc_code( f, "", true )
+      gen_ph_dealloc_code( f, "_RESET", true )
+
+      endif_cb_type_only f
+    end
+
+    gen_ph_endif f
+
+    f.close
+  end
+
+  #=== CELLTYPE_tecsgen.c を生成
+  def generate_cell_code
+    fs = { }
+    f = nil
+    @domain_roots.each{ |domain_type_name, regions|
+      regions.each{ |r|
+        if r.is_root? then
+          nsp = ""
+        else
+          nsp = "_#{r.get_namespace_path.get_global_name}"
+        end
+        # p "celltype:#{@name} dn:#{domain_type_name} nsp:#{nsp}"
+        fs[r] = AppFile.open("#{$gen}/#{@global_name}#{nsp}_tecsgen.#{$c_suffix}")
+        if r.is_root? then
+          f = fs[r]
+        end
+      }
+    }
+
+    # in case that domain_roots does not include root region
+    if f == nil then
+      regions = nil
+      @domain_roots.each{ |domain_type_name, regions_|
+        regions = regions_   # domain_type_name is unique
+      }
+      if regions.length > 1 then 
+        # if domain_roots.length >= 2 && no cell in root region
+        # shared code are placed in root region
+        f = AppFile.open("#{$gen}/#{@global_name}_tecsgen.#{$c_suffix}")
+      else
+        # shared code are placed in unique region
+        f = fs[ regions[0] ]
+      end
+    end
+
+    # すべての _tecsgen.c に出力
+    print_note f
+    gen_cell_private_header f
+    gen_cell_factory_header f
+    gen_cell_ep_des_type f
+
+    # すべての _tecsgen.c に出力
+    fs.each{ |r,f2|
+      if f == f2 then
+        next
+      end
+      print_note f2
+      gen_cell_private_header f2
+      gen_cell_factory_header f2
+      gen_cell_ep_des_type f2
+    }
+
+    # 一つの _tecsgen.c に出力
+    gen_cell_skel_fun f
+    gen_cell_fun_table f
+    gen_cell_var_init f
+
+    # セルごとに _tecsgen.c に出力
+    gen_cell_ep_vdes fs
+    gen_cell_ep_vdes_array fs
+    gen_cell_cb_out_init fs         # INITIALIZE_CB で参照されるため ram_initializer=false でも消せない
+    gen_cell_cb fs
+    gen_cell_extern_mt fs
+    gen_cell_ep_des fs
+
+    # 一つの _tecsgen.c に出力
+    gen_cell_cb_tab f
+    if $ram_initializer then
+      gen_cell_cb_initialize_code f
+    end
+
+    fs.each{ |r,f2|
+      f2.close
+      if f == f2 then
+        f = nil
+      end
+    }
+    if f then
+      f.close
+    end
+
+  end
+
+#####  celltype header
+
+  def gen_ph_guard( f, post = "TECSGEN" )
+    f.print("#ifndef #{@global_name}_#{post}_H\n")
+    f.print("#define #{@global_name}_#{post}_H\n\n")
+  end
+
+  def gen_ph_info f
+
+    yn_multi_domain = "no"
+    yn_multi_domain = "yes" if multi_domain?
+    yn_idx_is_id = "no"
+    yn_idx_is_id = "yes"  if @idx_is_id
+    yn_idx_is_id_act = "no"
+    yn_idx_is_id_act = "yes"  if @idx_is_id_act
+    yn_singleton = "no"
+    yn_singleton = "yes"  if @singleton
+    yn_rom       = "no"
+    yn_rom       = "yes"  if $rom
+    yn_has_CB    = "no"
+    yn_has_CB    = "yes"  if has_CB?
+    yn_has_INIB  = "no"
+    yn_has_INIB  = "yes"  if has_INIB?
+    yn_cb_init   = "no"
+    yn_cb_init   = "yes"  if need_CB_initializer?
+    # @singleton = false    # mikan singleton  060827
+
+    f.print <<EOT
+/*
+ * celltype          :  #{@name}
+ * global name       :  #{@global_name}
+ * multi-domain      :  #{yn_multi_domain}
+ * idx_is_id(actual) :  #{yn_idx_is_id}(#{yn_idx_is_id_act})
+ * singleton         :  #{yn_singleton}
+ * has_CB            :  #{yn_has_CB}
+ * has_INIB          :  #{yn_has_INIB}
+ * rom               :  #{yn_rom}
+ * CB initializer    :  #{yn_cb_init}
+ */
+
+EOT
+  end
+
+  def gen_ph_include f
+    # ランタイムヘッダの include
+#    f.printf TECSMsg.get( :IRTH_comment), "#_IRTH_#"
+#    f.print "#include \"tecs.#{$h_suffix}\"\n\n"
+
+    # グローバルヘッダの include
+    f.printf TECSMsg.get( :IGH_comment ), "#_IGH_#"
+    f.print "#include \"global_tecsgen.#{$h_suffix}\"\n\n"
+
+    # シグニチャヘッダの include
+    f.printf TECSMsg.get( :ISH_comment ), "#_ISH_#"
+    @port.each { |p|
+      next if p.is_omit?
+      hname = "#{p.get_signature.get_global_name}_tecsgen.#{$h_suffix}".to_sym
+      if header_included?( hname ) == false then
+        f.print "#include \"#{hname}\"\n"
+      end
+    }
+    f.print "\n"
+  end
+
+  def gen_ph_include_cb_type f
+
+    if ! @b_cp_optimized then
+      return
+    end
+
+    # 最適化のため参照するセルタイプの CB 型の定義を取込む
+    # _CB_TYPE_ONLY を定義した上で include する
+    f.printf( TECSMsg.get( :ICT_comment ), "#_ICT_#" )
+
+    f.print( "#ifndef  TOPPERS_CB_TYPE_ONLY\n" )
+    f.print( "#define  #{@global_name}_CB_TYPE_ONLY\n" )
+    f.print( "#define TOPPERS_CB_TYPE_ONLY\n" )
+    f.print( "#endif  /* TOPPERS_CB_TYPE_ONLY */\n" )
+
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      next if p.is_omit?
+
+      if p.is_skelton_useless? || p.is_cell_unique? || p.is_VMT_useless? then
+        # 最適化コード (optimize) # スケルトン不要など
+        p2 = p.get_real_callee_port
+        if p2 then
+          ct = p2.get_celltype
+          hname = "#{ct.get_global_name}_tecsgen.#{$h_suffix}".to_sym
+          if header_included?( hname ) == false then
+            f.print( "#include \"#{hname}\"\n" )
+          end
+        # else
+          # optional で未結合
+        end
+      end
+
+    }
+    f.print( "#ifdef  #{@global_name}_CB_TYPE_ONLY\n" )
+    f.print( "#undef TOPPERS_CB_TYPE_ONLY\n" )
+    f.print( "#endif /* #{@global_name}_CB_TYPE_ONLY */\n" )
+
+#    @port.each { |p|
+#      next if p.get_port_type != :CALL
+#      if p.is_skelton_useless? || p.is_cell_unique? || p.is_VMT_useless? then
+#        # 最適化コード (optimize) # スケルトン不要など
+#        p2 = p.get_real_callee_port
+#        ct = p2.get_celltype
+#        ct.gen_ph_typedef_idx f
+#        ct.gen_ph_INIB_as_CB f
+#        ct.gen_ph_extern_cell f
+#        f.print "\n"
+#      end
+#    }
+
+  end
+
+
+  def gen_ph_base f
+    return if @singleton
+
+    # ID の基数および個数の define を出力
+    f.printf("#define %-20s %10s  /* %s #_NIDB_# */\n", "#{@global_name}_ID_BASE", "(#{@id_base})", TECSMsg.get(:NIDB_comment))
+    f.printf("#define %-20s %10s  /* %s  #_NCEL_# */\n\n", "#{@global_name}_N_CELL", "(#{@n_cell_gen})", TECSMsg.get(:NCEL_comment))
+  end
+
+  def gen_ph_valid_idx f
+    return if @singleton
+
+    # mikan  最適化
+    # IDX 正当性チェックマクロの出力
+    f.printf( TECSMsg.get( :CVI_comment ), "#_CVI_#" )
+    if @idx_is_id_act then
+      f.print("#define #{@global_name}_VALID_IDX(IDX) (#{@global_name}_ID_BASE <= (IDX) && (IDX) < #{@global_name}_ID_BASE+#{@global_name}_N_CELL)\n\n")
+    else
+      f.print("#define #{@global_name}_VALID_IDX(IDX) (1)\n\n")
+    end
+
+  end
+
+  def gen_ph_valid_idx_abbrev f
+    return if @singleton
+
+    # IDX 正当性チェックマクロ（短縮形）の出力
+    f.printf( TECSMsg.get( :CVIA_comment ), "#_CVIA_#")
+    f.print("#define VALID_IDX(IDX)  #{@global_name}_VALID_IDX(IDX)\n\n")
+
+  end
+
+  #=== 呼び口配列の大きさを得るマクロの出力
+  #
+  #セルタイプヘッダへ呼び口の個数を出力
+  def gen_ph_n_cp f
+
+    b_comment = false
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      next if p.is_omit?
+      next if p.get_array_size == nil
+
+      if ! b_comment then
+        f.printf( TECSMsg.get( :NCPA_comment ), "#_NCPA_#" )
+        b_comment = true
+      end
+
+      if p.get_array_size != "[]" then       # 固定長配列
+        f.print( "#define N_CP_#{p.get_name}    (#{p.get_array_size})\n" )
+        f.print( "#define NCP_#{p.get_name}     (#{p.get_array_size})\n" )
+      else                                   # 可変長配列
+        if @singleton then
+          if has_INIB? then
+            inib = "INIB"
+          else
+            inib = "CB"
+          end
+          f.print( "#define N_CP_#{p.get_name}  (#{@global_name}_SINGLE_CELL_#{inib}.n_#{p.get_name})\n" )
+          f.print( "#define NCP_#{p.get_name}   (#{@global_name}_SINGLE_CELL_#{inib}.n_#{p.get_name})\n" )
+          # mikan singleton ならば、固定長化できる
+        else
+          if has_CB? && has_INIB? then
+            inib = "->_inib"
+          else
+            inib = ""
+          end
+          f.print( "#define N_CP_#{p.get_name}(p_that)  ((p_that)#{inib}->n_#{p.get_name})\n" )
+          f.print( "#define NCP_#{p.get_name}           (N_CP_#{p.get_name}(p_cellcb))\n" )
+        end
+      end
+    }
+  end
+
+  #=== 受け口配列の大きさを得るマクロの出力
+  #
+  #セルタイプヘッダへ受け口の個数を出力
+  def gen_ph_n_ep f
+
+    b_comment = false
+    @port.each { |p|
+      next if p.get_port_type != :ENTRY
+      # next if p.is_omit?                       # 受け口配列の個数は省略しない
+      next if p.get_array_size == nil
+
+      if ! b_comment then
+        f.printf( TECSMsg.get( :NEPA_comment ), "#_NEPA_#" )
+        b_comment = true
+      end
+
+      if p.get_array_size != "[]" then       # 固定長配列
+        f.print( "#define NEP_#{p.get_name}     (#{p.get_array_size})\n" )
+      else                                   # 可変長配列
+        if @singleton then
+          if has_INIB? then
+            inib = "INIB"
+          else
+            inib = "CB"
+          end
+          f.print( "#define NEP_#{p.get_name}   (#{@global_name}_SINGLE_CELL_#{inib}.n_#{p.get_name})\n" )
+          # mikan singleton ならば、固定長化できる
+        else
+          if has_CB? && has_INIB? then
+            inib = "->_inib"
+          else
+            inib = ""
+          end
+          f.print( "#define NEP_#{p.get_name}           ((p_cellcb)#{inib}->n_#{p.get_name})\n" )
+        end
+      end
+    }
+  end
+
+  #=== optional な呼び口が結合されているかテストするコードの生成
+  def gen_ph_test_optional_call_port f
+    b_comment = false
+
+    if @singleton then
+      if has_INIB? then
+        inib = "INIB"
+      else
+        inib = "CB"
+      end
+    else
+      if has_CB? && has_INIB? then
+        inib = "->_inib"
+      else
+        inib = ""
+      end
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      next if ! p.is_optional?
+      # next if p.is_omit?  # omit でも test コードは生成する
+
+      if b_comment == false then
+        f.printf( TECSMsg.get( :TOCP_comment ), "#_TOCP_#" )
+        b_comment = true
+      end
+
+      if @singleton then
+        param = ""
+        delim = ""
+      else
+        param = "p_that"
+        delim = ","
+      end
+      if p.get_array_size != nil then
+        param = param + delim + "subscript"
+      end
+      f.print( "#define #{@global_name}_is_#{p.get_name}_joined(#{param}) \\\n" )
+
+      if p.is_omit? then
+        f.print( "   omit  is_#{p.get_name}_joined\n" )
+        next
+      end
+
+      # 関数名の出力(標準：受け口ディスクリプタから VMT の関数名、最適化：受け口関数 or 受け口ディスクリプタ)
+      # mikan  全部つながっているかどうかで (1) を判定する
+      if ! p.is_VMT_useless? then
+        if p.is_dynamic? then
+          if @singleton then
+            inib_tmp = "CB"
+          else
+            inib_tmp = ""
+          end
+        else
+          inib_tmp = inib
+        end
+
+        # 標準コード
+        if p.get_array_size == nil then
+          if @singleton then
+            f.print( "\t  (#{@global_name}_SINGLE_CELL_#{inib_tmp}.#{p.get_name}!=0)\n" )
+          else
+            f.print( "\t  ((p_that)#{inib_tmp}->#{p.get_name}!=0)\n" )
+          end
+        else
+          # 配列の場合
+          if @singleton then
+            f.print( "\t  ((#{@global_name}_SINGLE_CELL_#{inib_tmp}.#{p.get_name}!=0) \\\n" )
+            f.print( "\t  &&(#{@global_name}_SINGLE_CELL_#{inib_tmp}.#{p.get_name}[subscript]!=0))\n" )
+          else
+            f.print( "\t  (((p_that)#{inib_tmp}->#{p.get_name}!=0)\\\n" )
+            f.print( "\t  &&((p_that)#{inib_tmp}->#{p.get_name}[subscript]!=0))\n" )
+          end
+        end
+      else
+        # 最適化コード (optimize) # VMT 不要（配列要素すべて同じ）
+        p2 = p.get_real_callee_port
+        if p2 then
+          ct = p2.get_celltype
+          if p.is_skelton_useless? then
+            # 受け口関数を直接呼出す
+            f.print( "\t  (1)\n" )
+          else
+            # 受け口スケルトン関数を直接呼出す
+            f.print( "\t  (1)\n" )
+          end
+        else
+          # optional で未結合
+          f.print( "\t  (0)    /* not joined */\n" )
+        end
+      end
+    }
+  end
+
+  #=== optional な呼び口が結合されているかテストするコードの生成（短縮形）
+  def gen_ph_test_optional_call_port_abbrev f
+    b_comment = false
+
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      next if ! p.is_optional?
+      # next if p.is_omit?  # omit でも test コードは生成する
+
+      if b_comment == false then
+        f.printf( TECSMsg.get( :TOCPA_comment ), "#_TOCPA_#" )
+        b_comment = true
+      end
+
+      if @singleton then
+        param = ""
+        delim = ""
+      else
+        param = "p_cellcb"
+        delim = ","
+      end
+
+      if p.get_array_size == nil then
+        subscript = ""
+      else
+        subscript = "subscript"
+        param = param + delim + subscript
+      end
+      f.print( "#define is_#{p.get_name}_joined(#{subscript})\\\n\t\t#{@global_name}_is_#{p.get_name}_joined(#{param})\n" )
+    }
+  end
+
+  #=== CELLCB へのポインタを得るマクロを出力
+  #   セルタイプヘッダへ出力
+  def gen_ph_get_cellcb f
+    f.printf( TECSMsg.get( :GCB_comment ), "#_GCB_#" )
+    if ( ! has_CB? && ! has_INIB? ) || @singleton then
+      f.print( "#define #{@global_name}_GET_CELLCB(idx) ((void *)0)\n" )
+    elsif @idx_is_id_act then   # mikan 単一のセルの場合の最適化, idx_is_id でない場合
+      f.print( "#define #{@global_name}_GET_CELLCB(idx) (#{@global_name}_CB_ptab[(idx) - #{@global_name}_ID_BASE])\n" )
+    else
+      f.print( "#define #{@global_name}_GET_CELLCB(idx) (idx)\n" )
+    end
+  end
+
+  #=== CELLCB へのポインタを得るマクロ（短縮形）を出力
+  #  セルタイプヘッダへ出力
+  def gen_ph_get_cellcb_abbrev f
+    f.printf( TECSMsg.get( :GCBA_comment ), "#_GCBA_#" )
+    f.print("#define GET_CELLCB(idx)  #{@global_name}_GET_CELLCB(idx)\n\n")
+
+    f.printf( TECSMsg.get( :CCT_comment ), "#_CCT_#" )
+    f.print( "#define CELLCB\t#{@global_name}_CB\n\n" )
+
+    f.printf( TECSMsg.get( :CTIXA_comment ), "#_CTIXA_#" )
+    f.print( "#define CELLIDX\t#{@global_name}_IDX\n\n" )
+
+    if @name != @global_name then
+      f.print( "#define #{@name}_IDX  #{@global_name}_IDX\n" )
+    end
+  end
+
+  #===  attribute, var をアクセスするマクロを出力
+  #    セルタイプヘッダへ出力
+  def gen_ph_attr_access f
+    if @n_attribute_rw > 0 || @n_attribute_ro > 0 then
+      f.printf( TECSMsg.get( :AAM_comment ), "#_AAM_#" )
+    end
+
+    @attribute.each { |a|
+
+      next if a.is_omit?
+
+      # mikan const_value の場合
+      f.print( "#define " )
+      if @singleton then
+        if has_INIB? then
+          inib = "INIB"
+        else
+          inib = "CB"
+        end
+        f.printf( "%-20s", "#{@global_name}_ATTR_#{a.get_name}" )
+        f.print( "\t(#{@global_name}_SINGLE_CELL_#{inib}.#{a.get_name})\n" )
+        # mikan ここでは cell ではなく celltype の名前
+      else
+        if ! a.is_rw? && has_CB? && has_INIB? then
+          inib = "->_inib"
+        else
+          inib = ""
+        end
+        f.printf( "%-20s", "#{@global_name}_ATTR_#{a.get_name}( p_that )" )
+        f.print( "\t((p_that)#{inib}->#{a.get_name})\n" )
+      end
+    }
+    f.print( "\n" )
+
+    @attribute.each { |a|
+
+      next if a.is_omit?
+
+      if @singleton then
+        if has_INIB? then
+          inib = "INIB"
+        else
+          inib = "CB"
+        end
+      else
+        if ! a.is_rw? && has_CB? && has_INIB? then
+          inib = "->_inib"
+        else
+          inib = ""
+        end
+      end
+
+      # mikan const_value の場合
+      f.print( "#define " )
+      if @singleton then
+        f.printf( "%-20s", "#{@global_name}_GET_#{a.get_name}()" )
+        f.print( "\t(#{@global_name}_SINGLE_CELL_#{inib}.#{a.get_name})\n" )
+        # mikan ここでは cell ではなく celltype の名前
+      else
+        f.printf( "%-20s", "#{@global_name}_GET_#{a.get_name}(p_that)" )
+        f.print( "\t((p_that)#{inib}->#{a.get_name})\n" )
+      end
+
+      if a.is_rw? then
+        f.print( "#define " )
+        if @singleton then
+          f.printf( "%-20s", "#{@global_name}_SET_#{a.get_name}(val)" )
+          f.print( "\t(#{@global_name}_SINGLE_CELL_#{inib}.#{a.get_name} = (val))\n" )
+          # mikan ここでは cell ではなく celltype の名前
+        else
+          f.printf( "%-20s", "#{@global_name}_SET_#{a.get_name}(p_that,val)" )
+          f.print( "\t((p_that)#{inib}->#{a.get_name}=(val))\n" )
+        end
+      end
+
+    }
+    f.print( "\n" )
+
+    if @n_var > 0 then
+      f.printf( TECSMsg.get( :VAM_comment ), "#_VAM_#" )
+    end
+
+    @var.each { |v|
+
+      next if v.is_omit?
+
+      if @singleton then
+        if v.get_size_is && has_INIB? then
+          inib = "INIB"
+        else
+          inib = "CB"
+        end
+      else
+        if v.get_size_is && has_CB? && has_INIB? then
+          inib = "->_inib"
+        else
+          inib = ""
+        end
+      end
+
+      # mikan const_value の場合
+      f.print( "#define " )
+      if @singleton then
+        f.printf( "%-20s", "#{@global_name}_VAR_#{v.get_name}" )
+        f.print( "\t(#{@global_name}_SINGLE_CELL_#{inib}.#{v.get_name})\n" )
+        # mikan ここでは cell ではなく celltype の名前
+      else
+        f.printf( "%-20s", "#{@global_name}_VAR_#{v.get_name}(p_that)" )
+        f.print( "\t((p_that)#{inib}->#{v.get_name})\n" )
+      end
+    }
+    f.print( "\n" )
+    @var.each { |v|
+
+      next if v.is_omit?
+
+      # mikan const_value の場合
+      f.print( "#define " )
+      if @singleton then
+        f.printf( "%-20s", "#{@global_name}_GET_#{v.get_name}()" )
+        f.print( "\t(#{@global_name}_SINGLE_CELL_CB.#{v.get_name})\n" )
+        # mikan ここでは cell ではなく celltype の名前
+      else
+        f.printf( "%-20s", "#{@global_name}_GET_#{v.get_name}(p_that)" )
+        f.print( "\t((p_that)->#{v.get_name})\n" )
+      end
+
+      f.print( "#define " )
+      if @singleton then
+        f.printf( "%-20s", "#{@global_name}_SET_#{v.get_name}(val)" )
+        f.print( "\t(#{@global_name}_SINGLE_CELL_CB.#{v.get_name}=(val))\n" )
+        # mikan ここでは cell ではなく celltype の名前
+      else
+        f.printf( "%-20s", "#{@global_name}_SET_#{v.get_name}(p_that,val)" )
+        f.print( "\t((p_that)->#{v.get_name}=(val))\n" )
+      end
+    }
+    f.print( "\n" )
+
+  end
+
+  #===  attribute/var アクセスマクロ（短縮形）コードの生成
+  def gen_ph_attr_access_abbrev f
+    if @n_attribute_rw > 0 || @n_attribute_ro > 0 then
+      f.printf( TECSMsg.get( :AAMA_comment ), "#_AAMA_#" )
+    end
+
+    @attribute.each { |a|
+      next if a.is_omit?
+
+      # mikan const_value の場合
+      f.print( "#define " )
+      f.printf( "%-20s", "ATTR_#{a.get_name}" )
+      f.print( " #{@global_name}_ATTR_#{a.get_name}" )
+      if ! @singleton then
+        f.print( "( p_cellcb )" )
+      end
+      f.print "\n"
+    }
+    f.print( "\n" )
+
+    if @n_var > 0 then
+      f.printf( TECSMsg.get( :VAMA_comment ), "#_VAMA_#" )
+    end
+
+    @var.each { |v|
+      next if v.is_omit?
+
+      # mikan const_value の場合
+      f.print( "#define " )
+      f.printf( "%-20s", "VAR_#{v.get_name}" )
+      f.print( " #{@global_name}_VAR_#{v.get_name}" )
+      if ! @singleton then
+        f.print( "( p_cellcb )" )
+      end
+      f.print( "\n" )
+    }
+    f.print( "\n" )
+
+  end
+
+  def gen_ph_cp_fun_macro f, b_flow
+    if @n_call_port >0 && b_flow == false then
+      f.printf( TECSMsg.get( :CPM_comment ) , "#_CPM_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      next if p.is_omit?
+
+      p.get_signature.get_function_head_array.each{ |fun|
+        if @singleton then
+          if has_INIB? then
+            inib = "INIB"
+          else
+            inib = "CB"
+          end
+          if p.is_dynamic? && p.get_array_size == nil then
+            # dynamic call port (not array)
+            inib = "CB"
+          end
+        else
+          if has_CB? && has_INIB? then
+            inib = "->_inib"
+          else
+            inib = ""
+          end
+          if p.is_dynamic? && p.get_array_size == nil then
+            # dynamic call port (not array)
+            inib = ""
+          end
+        end
+
+        f.print( "#define #{@global_name}_#{p.get_name}_#{fun.get_name}(" )
+        ft = fun.get_declarator.get_type
+        delim = ""
+
+        if ! @singleton then
+          f.print( "#{delim} p_that" )
+          delim = ","
+        end
+
+        if p.get_array_size then
+          f.print( "#{delim} subscript" )
+          delim = ","
+        end
+
+        ft.get_paramlist.get_items.each{ |param|
+          f.print( "#{delim} #{param.get_name}" )
+          delim = ","
+        }
+        f.print( " ) \\\n" )
+
+        subsc = ""
+        subsc = "[subscript]" if p.get_array_size
+        delim = ""
+
+        # 関数名の出力(標準：受け口ディスクリプタから VMT の関数名、最適化：受け口関数 or 受け口ディスクリプタ)
+        if b_flow then
+          f.print( "\t  (p_that)->#{p.get_name}#{subsc}.#{fun.get_name}__T( \\\n" )
+        elsif ! p.is_VMT_useless? then
+          # 標準コード
+          if @singleton then
+            f.print( "\t  #{@global_name}_SINGLE_CELL_#{inib}.#{p.get_name}" )
+          else
+            f.print( "\t  (p_that)#{inib}->#{p.get_name}" )
+          end
+          f.print( "#{subsc}->VMT->#{fun.get_name}__T( \\\n" )
+        else
+          # 最適化コード (optimize) # VMT 不要
+          p2 = p.get_real_callee_port
+          if p2 then
+            ct = p2.get_celltype
+            if p.is_skelton_useless? then
+              # 受け口関数を直接呼出す
+              f.print( "\t  #{ct.get_global_name}_#{p2.get_name}_#{fun.get_name}( \\\n" )
+            else
+              # 受け口スケルトン関数を直接呼出す
+              f.print( "\t  #{ct.get_global_name}_#{p2.get_name}_#{fun.get_name}_skel( \\\n" )
+              # print "skelton: #{@name} #{ct.get_global_name}_#{p2.get_name}\n"
+            end
+          else
+            # optional で未結合
+            f.print( "\t  ((#{fun.get_declarator.get_type.get_type.get_type_str} (*)()" )
+            f.print( "#{fun.get_declarator.get_type.get_type.get_type_str_post})0)()\n" )
+            f.print( "\t  /* optional no entry port joined */\n" )
+            if ! p.is_optional? then
+              raise "unjoined but not optional celltype: #{@name} #{p.get_name}"
+            end
+          end
+        end
+
+        b_join = true    # optional で結合していない場合 false
+
+        # 受け口情報の出力(標準：受け口ディスクリプタ、最適化：IDX など)
+        if b_flow then
+        elsif ! p.is_skelton_useless? && ! p.is_cell_unique? then
+          # 標準コード
+          if @singleton then
+            f.print( "\t  #{@global_name}_SINGLE_CELL_#{inib}.#{p.get_name}#{subsc}" )
+            delim = ","
+          else
+            f.print( "\t   (p_that)#{inib}->#{p.get_name}#{subsc}" )
+            delim = ","
+          end
+        else
+          # 最適化コード (optimize) # スケルトン不要
+          c2 = p.get_real_callee_cell               # 唯一のセル(でない場合もある、複数セルがある場合)
+          p2 = p.get_real_callee_port               # 唯一のポート(でない場合は、ない)
+          if p2 then
+            ct = p2.get_celltype                    # 呼び先のセルタイプ
+            if ! ct.is_singleton? then
+              if ct.has_CB? || ct.has_INIB? then
+                if p.is_cell_unique? then
+                  name_array = ct.get_name_array( c2 )
+                  f.print( "\t   #{name_array[7]}" )
+                else
+                  # CELLCB IDX を渡す (標準コードと同じだが、扱う型は異なる)
+                  # p.is_skelton_useless? == true/false ともに同じ
+                  f.print( "\t   (p_that)#{inib}->#{p.get_name}#{subsc}" )
+                end
+              else
+                f.print( "\t   (#{ct.get_global_name}_IDX)0" )
+              end
+              delim = ","
+            else
+              f.print( "\t   " )
+            end
+          else
+            # optional で未結合
+            b_join = false
+          end
+        end
+
+        if b_join then
+          ft.get_paramlist.get_items.each{ |param|
+            f.print( "#{delim} (#{param.get_name})" )
+            delim = ","
+          }
+          f.print( " )\n" )
+        end
+      }
+    }
+    f.print( "\n" )
+  end
+
+  #=== ref_desc 指定された呼び口に対するディスクリプタ参照関数の生成
+  def gen_ph_ref_desc_func f
+    if @n_call_port_ref_desc >0 then
+      f.printf( TECSMsg.get( :CRD_comment ), "#_CRD_#" )
+    end
+
+    if has_CB? && has_INIB? then
+      inib = "->_inib"
+    else
+      inib = ""
+    end
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      next if ! p.is_ref_desc?
+
+      if @singleton then
+        p_that = ""
+        p_cellcb = ""
+        delim = ""
+        if has_INIB? then
+          cb = "#{@global_name}_SINGLE_CELL_INIB."
+        else
+          cb = "#{@global_name}_SINGLE_CELL_CB."
+        end
+      else
+        p_that = "#{@global_name}_CB  *p_that"
+        p_cellcb = "    #{@global_name}_CB *p_cellcb = p_that;\n"
+        delim = ", "
+        cb = "p_cellcb#{inib}->"
+      end
+
+      if p.get_array_size
+        array = "#{delim}int_t  i "
+        array2 = "[ i ]"
+        assert = "    assert( 0 <= i && i < NCP_#{p.get_name} );\n"
+      else
+        array = ""
+        array2 = ""
+        assert = ""
+      end
+      f.print <<EOT
+/* [ref_desc] #{p.get_name} */
+Inline Descriptor( #{p.get_signature.get_global_name} )
+#{@global_name}_#{p.get_name}_refer_to_descriptor( #{p_that}#{array} )
+{
+    Descriptor( #{p.get_signature.get_global_name} )  des;
+#{p_cellcb}    /* cast is ncecessary for removing 'const'  */
+#{assert}    des.vdes = (struct tag_#{p.get_signature.get_global_name}_VDES *)#{cb}#{p.get_name}#{array2};
+    return des;
+}
+
+EOT
+    }
+  end
+
+  #=== dynamic 指定された呼び口に対するディスクリプタ設定関数の生成
+  def gen_ph_set_desc_func f
+    if @n_call_port_dynamic >0 then
+      f.printf( TECSMsg.get( :SDF_comment ), "#_SDF_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      next if ! p.is_dynamic?
+      if has_CB? && has_INIB? && p.get_array_size then
+        inib = "->_inib"
+      else
+        inib = ""
+      end
+      if @singleton then
+        # p "main== #{@global_name} #{p.get_name} #{p.get_array_size}"
+        p_that = ""
+        p_that2 = ""
+        p_cellcb = ""
+        if p.get_array_size && $rom then
+          cb = "#{@global_name}_SINGLE_CELL_INIB."
+        else
+          cb = "#{@global_name}_SINGLE_CELL_CB."
+        end
+      else
+        p_that = "#{@global_name}_CB  *p_that, "
+        p_that2 = "#{@global_name}_CB  *p_that "
+        p_cellcb = "    #{@global_name}_CB *p_cellcb = p_that;\n"
+        cb = "(p_cellcb)->#{inib}"
+      end
+
+      if p.get_array_size then
+        array = "int_t  i, "
+        array2 = "[ i ]"
+        array3 = " int_t  i "
+        assert2 = "    assert( 0 <= i && i < NCP_#{p.get_name} );\n"
+      else
+        array = ""
+        array2 = ""
+        array3 = ""
+        assert2 = ""
+      end
+      f.print <<EOT
+/* [dynamic] #{p.get_name} */
+Inline void
+#{@global_name}_#{p.get_name}_set_descriptor( #{p_that}#{array}Descriptor( #{p.get_signature.get_global_name} ) des )
+{
+#{p_cellcb}    assert( des.vdes != NULL );
+#{assert2}    #{cb}#{p.get_name}#{array2} = des.vdes;
+}
+
+EOT
+
+      if p.is_optional? then
+        if p_that2 != "" && array3 != "" then
+          delim = ", "
+        else
+          delim = ""
+        end
+        f.print <<EOT
+/* [dynamic,optional] #{p.get_name} */
+Inline void
+#{@global_name}_#{p.get_name}_unjoin( #{p_that2}#{delim}#{array3} )
+{
+#{p_cellcb}    #{cb}#{p.get_name}#{array2} = NULL;
+}
+
+EOT
+      end
+    }
+  end
+
+  #=== send/receive で受け取ったメモリ領域を dealloc するマクロコード
+  #f:: File
+  #b_undef:: bool : true = #undef コードの生成,  false = #define コードの生成
+  def  gen_ph_dealloc_code( f, append_name, b_undef = false )
+    b_msg = false
+    @port.each{ |p|
+      next if p.is_omit?
+
+      p.each_param{ |port, fd, par|
+        case par.get_direction                        # 引数の方向指定子 (in, out, inout, send, receive )
+        when :SEND
+          # next if port.get_port_type == :CALL
+          type = par.get_declarator.get_type
+          pre = "("
+          post = ")"
+        when :RECEIVE
+          # next if port.get_port_type == :ENTRY
+          type = par.get_declarator.get_type.get_type
+#          pre = "(*"
+#          post = ")"
+          pre = "("
+          post = ")"
+        else
+          next
+        end
+
+        #                      ポート名         関数名         パラメータ名
+        dealloc_func_name = "#{port.get_name}_#{fd.get_name}_#{par.get_name}_dealloc"
+        dealloc_macro_name = dealloc_func_name.upcase
+        name = par.get_name
+
+        if b_undef == false
+          if (type.get_size || type.get_count) && type.get_type.has_pointer?
+            count_str = "count__"
+            count_str2 = ", count__"
+          else
+            count_str = nil
+            count_str2 = nil
+          end
+          if ! b_msg
+            f.print "\n"
+            f.printf TECSMsg.get( :DAL_comment ), "#_DAL_#  #{append_name}"
+            b_msg = true
+          end
+          f.print "#define #{dealloc_macro_name}#{append_name}(#{name}#{count_str2})"
+          if append_name == "_RESET" then
+            gen_dealloc_code_for_type( f, type, dealloc_func_name, pre, name, post, 0, true, count_str )
+          else
+            gen_dealloc_code_for_type( f, type, dealloc_func_name, pre, name, post, 0, false, count_str )
+          end
+          f.print "\n"
+        else
+          f.print "#undef #{dealloc_macro_name}#{append_name}\n"
+        end
+      }
+    }
+  end
+
+  def gen_ph_cp_fun_macro_abbrev f
+    if @n_call_port >0 then
+      f.printf( TECSMsg.get( :CPMA_comment ), "#_CPMA_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      # next if p.is_omit?  呼び出すとエラーを起こすコードを生成
+
+      p.get_signature.get_function_head_array.each{ |fun|
+        if p.is_VMT_useless? && ! @singleton then
+          dummy_p_cell_access_pre = "((void)p_cellcb, "
+          dummy_p_cell_access_post = ")"
+        else
+          dummy_p_cell_access_pre = ""
+          dummy_p_cell_access_post = ""
+        end
+ 
+        if ! p.is_require? || p.has_name? then
+          f.print( "#define #{p.get_name}_#{fun.get_name}(" )
+        else
+          f.print( "#define #{fun.get_name}(" )
+        end
+        ft = fun.get_declarator.get_type
+        delim = ""
+
+#        if ! @singleton then
+#          f.print( "#{delim} p_that" )
+#          delim = ","
+#        end
+
+        if p.get_array_size then
+          f.print( "#{delim} subscript" )
+          delim = ","
+        end
+
+        ft.get_paramlist.get_items.each{ |param|
+          f.print( "#{delim} #{param.get_name}" )
+          delim = ","
+        }
+        f.print( " ) \\\n" )
+
+        if p.is_omit? then
+          f.print( "          #{dummy_p_cell_access_pre}omitted #{p.get_name}_#{fun.get_name}(" )
+        else
+          f.print( "          #{dummy_p_cell_access_pre}#{@global_name}_#{p.get_name}_#{fun.get_name}(" )
+        end
+        ft = fun.get_declarator.get_type
+        delim = ""
+
+        if ! @singleton then
+          f.print( "#{delim} p_cellcb" )
+          delim = ","
+        end
+
+        if p.get_array_size then
+          f.print( "#{delim} subscript" )
+          delim = ","
+        end
+
+        ft.get_paramlist.get_items.each{ |param|
+          f.print( "#{delim} #{param.get_name}" )
+          delim = ","
+        }
+        f.print( " )#{dummy_p_cell_access_post}\n" )
+      }
+    }
+    f.print( "\n" )
+  end
+
+  def gen_ph_ref_desc_macro_abbrev f
+    if @n_call_port_ref_desc >0 then
+      f.printf( TECSMsg.get( :CRDA_comment ), "#_CRDA_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      next if ! p.is_ref_desc?
+
+      if @singleton then
+        p_cellcb = ""
+        delim = ""
+      else
+        p_cellcb = "p_cellcb"
+        delim = ", "
+      end
+
+      if p.get_array_size then
+        array = " i "
+        array2 = "#{delim}i"
+      else
+        array = ""
+        array2 = ""
+      end
+
+      f.printf( "#define %s_refer_to_descriptor(#{array})\\\n          %s_refer_to_descriptor( #{p_cellcb}#{array2} )\n",
+                "#{p.get_name}",
+                "#{@global_name}_#{p.get_name}" )
+      f.printf( "#define %s_ref_desc(#{array})\\\n          %s_refer_to_descriptor(#{array})\n",   
+                "#{p.get_name}",
+                "#{p.get_name}" )
+    }
+    f.print( "\n" )
+  end
+
+  def gen_ph_set_desc_macro_abbrev f
+    if @n_call_port_dynamic >0 then
+      f.printf( TECSMsg.get( :SDMA_comment ), "#_SDMA_#" )
+    end
+
+    if @singleton then
+      p_cellcb = ""
+      delim = ""
+    else
+      p_cellcb = "p_cellcb"
+      delim = ", "
+    end
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      next if ! p.is_dynamic?
+
+      if p.get_array_size then
+        subsc = "i, "
+        subsc2 = "i"
+        subsc3 = delim + subsc2
+      else
+        subsc = ""
+        subsc2 = ""
+        subsc3 = ""
+      end
+      f.printf( "#define %s_set_descriptor( #{subsc}desc )\\\n          %s_set_descriptor( #{p_cellcb}#{delim}#{subsc}desc )\n",
+                "#{p.get_name}",
+                "#{@global_name}_#{p.get_name}" )
+      f.printf( "#define %s_unjoin( #{subsc2} )\\\n          %s_unjoin( #{p_cellcb}#{subsc3} )\n",
+                "#{p.get_name}",
+                "#{@global_name}_#{p.get_name}" )
+    }
+    f.print( "\n" )
+  end
+
+  def gen_ph_ep_fun_macro f
+    if @n_entry_port >0 then
+      f.printf( TECSMsg.get( :EPM_comment ), "#_EPM_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :ENTRY
+      next if p.is_omit?
+
+      p.get_signature.get_function_head_array.each{ |fun|
+        f.printf( "#define %-16s %s\n",
+                  "#{p.get_name}_#{fun.get_name}",
+                  "#{@global_name}_#{p.get_name}_#{fun.get_name}" )
+      }
+    }
+    f.print( "\n" )
+
+  end
+
+  def gen_ph_typedef_idx f
+    f.printf( TECSMsg.get( :CTIX_comment ), "#_CTIX_#" )
+    if @idx_is_id_act then
+      f.print( "typedef ID #{@global_name}_IDX;\n" )
+    else
+      if has_CB? then
+        f.print( "typedef struct tag_#{@global_name}_CB *#{@global_name}_IDX;\n" )
+      elsif has_INIB? then
+        f.print( "typedef const struct tag_#{@global_name}_INIB *#{@global_name}_IDX;\n" )
+      else
+        f.print( "typedef int   #{@global_name}_IDX;\n" )
+      end
+    end
+
+  end
+
+  def gen_ph_idx_type f
+    if @idx_is_id_act then
+      f.print( "ID" )
+    else
+      if has_CB? then
+        f.print( "struct tag_#{@global_name}_CB *" )
+      elsif has_INIB? then
+        # f.print( "struct tag_#{@global_name}_INIB *" )  # const を出力していない
+        f.print( "const struct tag_#{@global_name}_INIB *" )
+      else
+        f.print( "int" )
+      end
+    end
+
+  end
+
+  def gen_ph_ep_fun_prototype f
+    if @n_entry_port >0 then
+      f.printf( TECSMsg.get( :EPP_comment ), "#_EPP_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :ENTRY
+      next if p.is_omit?
+
+      f.print( "/* #{p.get_signature.get_global_name} */\n" )
+
+      p.get_signature.get_function_head_array.each{ |fun|
+        if p.is_inline? then
+          f.print( "Inline " )
+        end
+        functype = fun.get_declarator.get_type
+        f.printf( "%-12s", functype.get_type_str )
+
+        f.print( " #{@global_name}_#{p.get_name}_#{fun.get_name}(" )
+        if @singleton then
+           delim = ""
+        else
+          f.print( "#{@global_name}_IDX idx" )
+          delim = ","
+        end
+
+        if p.get_array_size then
+          f.print( "#{delim} int_t subscript" )     # mikan singleton 時の ',' の始末
+          delim = ","
+        end
+
+        if functype.get_paramlist then
+          items = functype.get_paramlist.get_items
+          len = items.length
+        else
+          # ここで nil になるのは、引数なしの時に void がなかった場合
+          items = []
+          len = 0
+        end
+        i = 0
+        items.each{ |param|
+          f.print "#{delim} "
+          delim = ","
+          f.print( param.get_type.get_type_str )
+          f.print( " " )
+          f.print( param.get_name )
+          f.print( param.get_type.get_type_str_post )
+          i += 1
+        }
+        f.print( ");\n" )
+
+      }
+    }
+  end
+
+  def gen_ph_ep_skel_prototype f
+    # 受け口スケルトン関数のプロトタイプ宣言を出力
+    if @n_entry_port >0 then
+      f.printf( TECSMsg.get( :EPSP_comment ), "#_EPSP_#" )
+    end
+    @port.each { |p|
+      next if p.get_port_type != :ENTRY
+      next if p.is_omit?
+#      if p.is_skelton_useless? || ! p.is_VMT_useless? then    # 受け口最適化
+      if p.is_skelton_useless? then    # 受け口最適化
+#        f.print( "/* #{p.get_name} : omitted by entry port optimize */\n" )
+        next
+      end
+
+      f.print( "/* #{p.get_name} */\n" )
+
+      p.get_signature.get_function_head_array.each{ |fun|
+        functype = fun.get_declarator.get_type
+        f.printf "%-14s", functype.get_type_str
+
+        f.print " #{@global_name}_#{p.get_name}_#{fun.get_name}_skel("
+        f.print " const struct tag_#{p.get_signature.get_global_name}_VDES *epd"
+        delim = ","
+
+        if functype.get_paramlist then
+          items = functype.get_paramlist.get_items
+          len = items.length
+        else
+          # ここで nil になるのは、引数なしの時に void がなかった場合
+          items = []
+          len = 0
+        end
+        i = 0
+        items.each{ |param|
+          f.print "#{delim} "
+          delim = ","
+          f.print param.get_type.get_type_str
+          f.print " "
+          f.print param.get_name
+          f.print param.get_type.get_type_str_post
+          i += 1
+        }
+        f.print ");\n"
+      }
+    }
+    f.print( "\n" )
+  end
+
+  def gen_ph_cell_cb_type f
+
+    if ( $rom )then
+      # 定数部は ROM, 変数部は RAM
+
+      if has_INIB? then
+
+        f.printf( TECSMsg.get( :CIP_comment ), "#_CIP_#" )
+        f.print( "typedef const struct tag_#{@global_name}_INIB {\n" )
+
+        gen_cell_cb_type_port( f, :INIB )
+        gen_cell_cb_type_attribute( f, :INIB )
+
+        f.print( "}  #{@global_name}_INIB;\n" )
+
+      end
+
+      if has_CB? then
+        f.printf( TECSMsg.get( :CCTPA_comment ), "#_CCTPA_#" )
+        f.print( "typedef struct tag_#{@global_name}_CB {\n" )
+        if has_INIB? then
+          f.print "    #{@global_name}_INIB  *_inib;\n"
+        end
+        gen_cell_cb_type_port( f, :CB_DYNAMIC )
+        gen_cell_cb_type_attribute( f, :CB )
+        gen_cell_cb_type_var f
+        f.print( "}  #{@global_name}_CB;\n" )
+      end
+
+      if ! has_CB? && ! has_INIB? then
+        f.printf( TECSMsg.get( :CCDP_comment ), "#_CCDP_#" )
+        f.print( "typedef struct tag_#{@global_name}_CB {\n" )
+        f.print( "    int  dummy;\n" )
+        f.print( "} #{@global_name}_CB;\n" )
+     end
+
+    else
+      # 全て RAM
+      f.printf( TECSMsg.get( :CCTPO_comment ), "#_CCTPO_#" )
+
+      f.print( "typedef struct tag_#{@global_name}_CB {\n" )
+
+      gen_cell_cb_type_port( f, :CB )
+      gen_cell_cb_type_attribute( f, :CB )
+      gen_cell_cb_type_var f
+
+      f.print( "}  #{@global_name}_CB;\n" )
+    end
+  end
+
+
+  #===   attribute の型宣言出力
+  #inib_cb::  :INIB または :CB
+  def gen_cell_cb_type_attribute( f, inib_cb )
+    if inib_cb == :INIB && @n_attribute_ro > 0 then
+      f.print "    /* attribute(RO) #_ATO_# */ \n"
+    elsif inib_cb == :CB then
+      if $rom then
+        if @n_attribute_rw > 0 then
+          f.print "    /* attribute(RW) #_ATW_# */ \n"
+        end
+      else
+        if @n_attribute_rw > 0 || @n_attribute_ro > 0 then
+          f.print "    /* attribute #_AT_# */ \n"
+        end
+      end
+    end
+
+    @attribute.each{ |a|
+      next if a.is_omit?
+      next if inib_cb == :INIB && a.is_rw?
+      next if has_INIB? && inib_cb == :CB && ! a.is_rw?
+
+      if a.get_type.kind_of?( PtrType ) && ! a.get_type.is_const? && a.get_size_is then
+        const_str = "const "
+      else
+        const_str = ""
+      end
+      f.print "    "
+      f.printf( "#{const_str}%-14s", a.get_type.get_type_str )
+      f.print " #{a.get_name}#{a.get_type.get_type_str_post};\n"
+    }
+    @var.each { |v|
+      next if v.is_omit?
+      next if v.get_size_is == nil
+      next if $rom && inib_cb == :CB      # size_is 指定されたものは INIB にのみ出力する
+
+      f.print "    "
+      f.printf( "%-14s", v.get_type.get_type_str )
+      f.print " #{v.get_name}#{v.get_type.get_type_str_post};\n"
+    }
+  end
+
+  def gen_cell_cb_type_var f
+    # 変数の出力
+    if @n_var > 0 then
+      f.print "    /* var #_VA_# */ \n"
+    end
+
+    @var.each{ |v|
+
+      next if v.is_omit?
+      next if v.get_size_is != nil    # size_is 指定された var は attribute へ出力する
+
+      f.print "    "
+      f.printf( "%-14s", v.get_type.get_type_str )
+      f.print " #{v.get_name}#{v.get_type.get_type_str_post};\n"
+    }
+  end
+
+  def gen_cell_cb_type_port( f, inib_cb )
+    gen_cell_cb_type_call_port( f, inib_cb )
+    gen_cell_cb_type_entry_port( f, inib_cb )
+  end
+
+  def gen_cell_cb_type_call_port( f, inib_cb )
+    # 呼び口
+    if @n_call_port >0 then
+      f.print "    /* call port #_TCP_# */\n"
+    end
+
+    @port.each{ |p|
+      next if p.get_port_type != :CALL
+      next if p.is_omit?
+      next if inib_cb == :INIB && p.is_dynamic? && p.get_array_size == nil && ! $ram_initializer
+      next if inib_cb == :CB_DYNAMIC && ( ! p.is_dynamic? || p.get_array_size != nil )
+      # bprint "cb_type #{inib_cb} #{p.get_name} dynamic=#{p.is_dynamic?}\n"
+
+      ptr = p.get_array_size ? '*' : ''
+
+      if ! p.is_cell_unique? then
+        const = p.is_dynamic?  ? '' : 'const'
+        if inib_cb == :INIB && p.is_dynamic? && p.get_array_size == nil && $ram_initializer then
+          init = '_init_'
+          const2 = 'const'
+        else
+          init = ''
+          const2 = 'const'
+        end
+
+        if ! p.is_skelton_useless? then
+          # 標準形
+          if inib_cb == :INIB && p.is_dynamic? && p.get_array_size != nil && $ram_initializer then
+            f.print( "    struct tag_#{p.get_signature.get_global_name}_VDES #{ptr}#{const2}*#{p.get_name;}_init_;\n" )
+          end
+          f.print( "    struct tag_#{p.get_signature.get_global_name}_VDES #{ptr}#{const}*#{p.get_name;}#{init};\n" )
+#          f.print( "    struct tag_#{p.get_signature.get_global_name}_VDES #{ptr}*#{p.get_name;};\n" )
+          if p.get_array_size == "[]" then
+            f.print( "    int_t n_#{p.get_name};\n" )
+          end
+        else
+          # 最適化 skelton 関数を呼出さない(受け口関数を直接呼出す)
+          # 呼び先セルタイプの CB の IDX 型
+          if p.get_real_callee_cell then
+            f.print( "    " )
+            p.get_real_callee_cell.get_celltype.gen_ph_idx_type f
+            f.print( " #{ptr}#{p.get_name;};\n" )
+            # 相互参照に備えて、typedef した型を使わない
+            # f.print( "    #{p.get_real_callee_cell.get_celltype.get_global_name}_IDX #{ptr}#{p.get_name;};\n" )
+            if p.get_array_size == "[]" then
+              f.print( "    int_t n_#{p.get_name};\n" )
+            end
+          #else
+          #  optional で未結合
+          end
+        end
+      # else
+        # 最適化 一つしかセルがない場合、受け口ディスクリプタまたは受け側の IDX は呼び口関数マクロに埋め込まれる
+      end
+    }
+  end
+
+  #=== Celltype#受け口配列添数を記憶する変数の定義
+  def gen_cell_cb_type_entry_port( f, inib_cb )
+    # 呼び口
+    if @n_entry_port >0 then
+      f.print "    /* call port #_NEP_# */ \n"
+    end
+
+    @port.each{ |p|
+      # next if p.is_omit?                       # 受け口配列の個数は省略しない
+      if p.get_port_type == :ENTRY && p.get_array_size == "[]"
+        f.print( "    int_t n_#{p.get_name};\n" )
+      end
+    }
+  end
+
+  def gen_ph_extern_cell f
+    if @singleton then
+      f.printf( TECSMsg.get( :SCP_comment ),  "#_SCP_#" )
+      if has_CB? then
+        f.print "extern  #{@global_name}_CB  #{@global_name}_SINGLE_CELL_CB;\n"
+      end
+      if has_INIB? then
+        f.print "extern  #{@global_name}_INIB  #{@global_name}_SINGLE_CELL_INIB;\n"
+      end
+      f.print "\n"
+    elsif @b_need_ptab then
+      f.printf( TECSMsg.get( :SCP_comment ),  "#_MCPP_#" )
+      if has_CB? then
+        f.print "extern #{@global_name}_CB  *const #{@global_name}_CB_ptab[];\n"
+        @ordered_cell_list.each{ |c|
+          if c.is_generate? then                           # 生成対象か？
+            name_array = get_name_array c
+            f.print "extern #{@global_name}_CB  #{name_array[4]};\n"
+          end
+        }
+      elsif has_INIB?
+        f.print "extern #{@global_name}_INIB  *const #{@global_name}_INIB_ptab[];\n"
+        @ordered_cell_list.each{ |c|
+          if c.is_generate? then                           # 生成対象か？
+            name_array = get_name_array c
+            f.print "extern #{@global_name}_INIB  #{name_array[11]};\n"
+          end
+        }
+      end
+    else
+      f.printf( TECSMsg.get( :SCP_comment ),  "#_MCPB_#" )
+      if has_CB? then
+        f.print "extern #{@global_name}_CB  #{@global_name}_CB_tab[];\n"
+      elsif has_INIB?
+        f.print "extern #{@global_name}_INIB  #{@global_name}_INIB_tab[];\n"
+      end
+    end
+  end
+
+  def gen_ph_INIB_as_CB f
+    # ここは、手抜きである。本来なら INIB を出力すべき
+    if ! has_CB? && has_INIB? then
+      f.printf( TECSMsg.get( :DCI_comment ),  "#_DCI_#" )
+      if @singleton then
+        f.print "#define #{@global_name}_SINGLE_CELL_CB   #{@global_name}_SINGLE_CELL_INIB\n"
+      elsif @b_need_ptab then
+        f.print "#define #{@global_name}_CB_ptab           #{@global_name}_INIB_ptab\n"
+      else
+        f.print "#define #{@global_name}_CB_tab           #{@global_name}_INIB_tab\n"
+      end
+      f.print "#define #{@global_name}_CB               #{@global_name}_INIB\n"
+      f.print "#define tag_#{@global_name}_CB           tag_#{@global_name}_INIB\n"
+      f.print "\n"
+    end
+
+  end
+
+  #===  イテレータコード (FOREACH_CELL)の生成
+  #      singleton では出力しない
+  def gen_ph_foreach_cell f
+
+    return if @singleton
+
+    if has_CB? || has_INIB? then
+
+      if need_CB_initializer?
+        necessity = ""
+      else
+        necessity = "//"
+      end
+
+      f.printf( TECSMsg.get( :FEC_comment ), "#_FEC_#" )
+
+      if @b_need_ptab then
+        amp = ''
+        tab = 'ptab'
+      else
+        amp = '&'
+        tab = 'tab'
+      end
+      f.print <<EOT
+#define FOREACH_CELL(i,p_cb)   \\
+    for( (i) = 0; (i) < #{@global_name}_N_CELL; (i)++ ){ \\
+       #{necessity}(p_cb) = #{amp}#{@global_name}_CB_#{tab}[i];
+
+#define END_FOREACH_CELL   }
+
+EOT
+    else
+      f.printf( TECSMsg.get( :NFEC_comment ), "#_NFEC_#" )
+      f.print <<EOT
+#define FOREACH_CELL(i,p_cb)   \\
+    for((i)=0;(i)<0;(i)++){
+
+#define END_FOREACH_CELL   }
+
+EOT
+    end
+  end
+
+
+  #===  変数var初期化コード
+  #
+  def gen_ph_cb_initialize_macro f
+
+    f.printf( TECSMsg.get( :CIM_comment ), "#_CIM_#" )
+
+    @var.each { |v|
+      init = v.get_initializer
+      if init.instance_of? Array then
+        type = v.get_type
+        if( type.kind_of? PtrType )then
+          # PtrType は ArrayType にすり替える
+
+          # 初期化子の要素数とする (後は 0 である)
+          t2 = ArrayType.new( Expression.create_integer_constant( init.length, nil ) )
+          t2.set_type( type.get_type )
+          type = t2
+        end
+        f.print "extern const #{type.get_type_str} #{@global_name}_#{v.get_name}_VAR_INIT#{type.get_type_str_post};\n"
+      end
+    }
+    if @singleton then
+      arg = "()"
+      p_that = ""
+      that = "#{@global_name}_SINGLE_CELL_CB."
+    else
+      arg = "(p_that)"
+      p_that = "(p_that)"
+      that = "(p_that)->"
+    end
+
+    if @n_cell_gen > 0 && need_CB_initializer? then
+      b_var_init = false
+      f.print "#define INITIALIZE_CB#{arg}"
+      @var.each { |v|
+        init = v.get_initializer
+        next if init == nil
+
+        b_var_init = true
+        type = v.get_type.get_original_type
+        f.print "\\\n"
+#        print v.get_name, type.class, "\n"
+#        if init.instance_of? Array || type.kind_of?( StructType ) then
+        if init.instance_of? Array then
+          if(type.kind_of?( ArrayType ) || type.kind_of?( PtrType ))then
+            pre = "&"
+            post = "[0]"
+          elsif type.kind_of? StructType then
+            pre = "&"
+            post = ""
+#          elsif type.kind_of? PtrType then
+#            pre = ""
+#            post = ""
+          end
+          f.print "\tmemcpy((void*)#{pre}#{@global_name}_VAR_#{v.get_name}#{p_that}#{post}, "
+          f.print "(void*)#{pre}#{@global_name}_#{v.get_name}_VAR_INIT#{post}, sizeof(#{@global_name}_#{v.get_name}_VAR_INIT));"
+        elsif init.instance_of? C_EXP then
+          f.print "\t#{that}#{v.get_name} = #{init.get_c_exp_string};"
+        else
+          pre = "#{get_global_name}_ATTR_"
+          if @singleton then
+            post = ""
+          else
+            post = "#{p_that}"
+          end
+          f.print "\t#{that}#{v.get_name} = #{init.to_str( @name_list, pre, post )};"
+        end
+      }
+
+      # dynamic call port の初期化コード
+      b_dyn_port = false
+      @port.each{ |p|
+        next if p.get_port_type != :CALL
+        if p.is_dynamic? && $ram_initializer then
+          if p.get_array_size == nil then
+            f.print "\\\n\t#{that}#{p.get_name} = #{that}_inib->#{p.get_name}_init_;"
+          else
+            if @singleton || p.get_array_size != "[]" then
+              p_that = ""
+            else
+              p_that = "(p_that)"
+            end
+            if @singleton then
+              that = "#{@global_name}_SINGLE_CELL_INIB."
+            else
+              that = "(p_that)->"
+            end
+            if has_CB? then
+              init = '_init->'
+            else
+              init = ''
+            end
+            f.printf( "\\\n%-80s\\\n", '     {' )
+            f.printf( "%-80s\\\n", '        int_t   j;' )
+            f.printf( "%-80s\\\n", "        for( j = 0; j < N_CP_#{p.get_name}#{p_that}; j++ ){" )
+            f.printf( "%-80s\\\n", "            #{that}#{p.get_name}[j] = #{that}#{init}#{p.get_name}_init_[j];" )
+            f.printf( "%-80s\\\n", '        }' )
+            f.printf( "%-80s", '       }' )
+          end
+          b_dyn_port = true
+        end
+      }
+      if b_dyn_port then
+        f.print( "\n" )
+      end
+      
+      if b_var_init == false && b_dyn_port == false && ! @singleton then
+        f.print "\t(void)(p_that);"
+      end
+      f.print "\n"
+
+      f.print "#define SET_CB_INIB_POINTER(i,p_that)\\\n"
+      if has_CB? && has_INIB? then
+        if @singleton then
+          f.print "\t#{that}_inib = &#{@global_name}_SINGLE_CELL_INIB;\n\n"
+        elsif @b_need_ptab then
+          f.print "\t#{that}_inib = #{@global_name}_INIB_ptab[(i)];\n\n"
+        else
+          f.print "\t#{that}_inib = &#{@global_name}_INIB_tab[(i)];\n\n"
+        end
+      else
+        f.print "\t/* empty */\n"
+      end
+
+    # else
+    #   セルが一つもなければ出力しない
+    end
+
+  end
+
+
+  def gen_ph_inline f
+    # inline ポートが一つでもあれば、inline.h の include
+    if @n_entry_port_inline > 0 then
+      f.printf( TECSMsg.get( :INL_comment ), "#_INL_#" )
+      f.print( "#include \"#{@global_name}_inline.#{$h_suffix}\"\n\n" )
+    end
+  end
+
+  def gen_ph_endif( f, post = "TECSGEN" )
+    f.print("#endif /* #{@global_name}_#{post}H */\n")
+  end
+
+
+##### celltype factory header
+  def generate_factory_header
+
+    f = AppFile.open("#{$gen}/#{@global_name}_factory.#{$h_suffix}")
+    f.print("#ifndef #{@name}_FACTORY_H\n")
+    f.print("#define #{@name}_FACTORY_H\n")
+    f.close
+  end
+
+  def generate_factory_header_post
+
+    f = AppFile.open("#{$gen}/#{@global_name}_factory.#{$h_suffix}")
+
+    plugin_obj = get_celltype_plugin
+    if plugin_obj
+      plugin_obj.gen_factory f
+    end
+
+    f.print("#endif /* #{@name}_FACTORY_H */\n")
+    f.close
+  end
+
+
+#####  celltype glue code
+  def gen_cell_private_header f
+    f.print "#include \"#{@global_name}_tecsgen.#{$h_suffix}\"\n"
+  end
+
+  def gen_cell_factory_header f
+    f.print "#include \"#{@global_name}_factory.#{$h_suffix}\"\n\n"
+  end
+
+  def gen_cell_ep_des_type f
+    if @n_entry_port > 0 then
+      f.printf( TECSMsg.get( :EDT_comment ), "#_EDT_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :ENTRY
+      next if p.is_omit?
+      if p.is_skelton_useless?    # 受け口最適化
+        f.print( "/* #{p.get_name} : omitted by entry port optimize */\n\n" )
+        next
+      end
+
+      f.print( "/* #{p.get_name} */\n" )
+      f.print( "struct tag_#{@global_name}_#{p.get_name}_DES {\n" )
+      f.print( "    const struct tag_#{p.get_signature.get_global_name}_VMT *vmt;\n" )
+      if has_CB? || has_INIB? then
+        f.print( "    #{@name}_IDX  idx;\n" )
+      else
+        # CB も INIB も存在しない (ので、idx として整数で初期化しておく)
+        f.print( "    int           idx;\n" )
+      end
+      if p.get_array_size then
+        f.print( "    int_t  subscript;\n" )
+      end
+      f.print( "};\n\n" )
+    }
+  end
+
+  def gen_cell_skel_fun f
+    if @n_entry_port >0 then
+      f.printf( TECSMsg.get( :EPSF_comment ), "#_EPSF_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :ENTRY
+      next if p.is_omit?
+      if p.is_skelton_useless? then    # 受け口最適化
+        f.print( "/* #{p.get_name} : omitted by entry port optimize */\n" )
+        next
+      end
+
+      f.print( "/* #{p.get_name} */\n" )
+
+      p.get_signature.get_function_head_array.each{ |fun|
+        functype = fun.get_declarator.get_type
+        f.printf "%-14s", functype.get_type_str
+
+        f.print " #{@global_name}_#{p.get_name}_#{fun.get_name}_skel("
+        f.print " const struct tag_#{p.get_signature.get_global_name}_VDES *epd"
+        delim = ","
+
+        if functype.get_paramlist then
+          items = functype.get_paramlist.get_items
+          len = items.length
+        else
+          # ここで nil になるのは、引数なしの時に void がなかった場合
+          items = []
+          len = 0
+        end
+        i = 0
+        items.each{ |param|
+          f.print "#{delim} "
+          delim = ","
+          f.print param.get_type.get_type_str
+          f.print " "
+          f.print param.get_name
+          f.print param.get_type.get_type_str_post
+          i += 1
+        }
+        f.print ")\n"
+
+        f.print "{\n"
+        if ( ! @singleton || p.get_array_size != nil ) then
+          f.print "    struct tag_#{@global_name}_#{p.get_name}_DES *lepd\n"
+          f.print "        = (struct tag_#{@global_name}_#{p.get_name}_DES *)epd;\n"
+        end
+
+        if functype.get_type_str == "void" then # mikan "void" の typedef に未対応
+          f.print "    "
+        else
+          f.print "    return "
+        end
+
+        f.print "#{@global_name}_#{p.get_name}_#{fun.get_name}("
+        if @singleton then
+          delim = ""
+        else
+          f.print " lepd->idx"
+          delim = ","
+        end
+
+        if p.get_array_size then
+          f.print "#{delim} lepd->subscript"
+          delim = ","
+        end
+
+        items.each{ |param|
+          f.print "#{delim} "
+          delim = ","
+          f.print param.get_name
+          i += 1
+        }
+        f.print " );\n"
+
+        f.print "}\n"
+      }
+    }
+    if @n_entry_port >0 then
+      f.print( "\n" )
+    end
+  end
+
+  def gen_cell_fun_table f
+    if @n_entry_port >0 then
+      f.printf( TECSMsg.get( :EPSFT_comment ), "#_EPSFT_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :ENTRY
+      next if p.is_omit?
+      if p.is_VMT_useless? then    # 受け口最適化
+        f.print "/* #{p.get_name} : omitted by entry port optimize */\n"
+        next
+      end
+
+      f.print "/* #{p.get_name} */\n"
+
+      # f.print "static const struct tag_#{p.get_signature.get_global_name}_VMT"
+      f.print "const struct tag_#{p.get_signature.get_global_name}_VMT"
+      f.print " #{@global_name}_#{p.get_name}_MT_ = {\n"
+
+      p.get_signature.get_function_head_array.each{ |fun|
+        f.print "    #{@global_name}_#{p.get_name}_#{fun.get_name}_skel,\n"
+      }
+
+      f.print "};\n"
+    }
+    f.print "\n"
+
+  end
+
+  def gen_cell_ep_vdes fs
+    if @n_cell_gen  >0 then
+      fs.each{ |r,f| f.printf( TECSMsg.get( :CPEPD_comment ), "#_CPEPD_#" ) }
+    end
+
+    # このセルタイプのすべてのセルについて
+    @ordered_cell_list.each{ |c|
+      if c.is_generate? then                           # 生成対象か？
+
+        f = fs[ c.get_region.get_domain_root ]
+
+        # 結合のリスト (NamedList)
+        jl = c.get_join_list
+
+        # 全ての結合リストについて
+        jl.get_items.each{ |j|
+
+          # 左辺の定義を得る
+          definition = j.get_definition
+
+          # 呼び口ではない？　（属性）
+          next unless definition.instance_of? Port
+
+          port = find j.get_name # celltype の Port (こちらに最適化情報がある)
+          # port = definition    # definition は composite の Port が得られることがある
+          next if port.is_cell_unique?
+          next if port.is_omit?
+
+          # 配列要素を得る（受け口配列でなければ nil が返る）
+          am = j.get_array_member2
+
+          # 呼び口配列か?
+          if am  then
+            i = 0
+            while( i < am.length )
+              j = am[i]
+              if j then
+                if am[i].get_rhs_cell.get_celltype == self then
+                  # 同じセルタイプへ結合している場合(VDES では type conflict になる)
+                  p = am[i].get_rhs_port
+                  des_type = "const struct tag_#{@global_name}_#{p.get_name}_DES"
+                else
+                  des_type = "struct tag_#{definition.get_signature.get_global_name}_VDES"
+                end
+
+                # 右辺は受け口配列か？
+                if j.get_rhs_subscript then
+
+                  # 受け口の配列添数
+                  subscript = j.get_rhs_subscript
+
+                  f.printf( "extern %s %s%d;\n",
+                            des_type,
+                            "#{j.get_port_global_name(i)}_des",
+                            subscript)
+                else
+                  f.printf( "extern %s %s;\n",
+                            des_type,
+                            "#{j.get_port_global_name(i)}_des")
+                end
+              #else if j == nil
+              #  optioanl で配列要素が初期化されていない
+              end
+              i += 1
+            end
+          else
+            dbgPrint "me=#{@name} callee=#{j.get_rhs_cell.get_celltype.get_name} #{j.get_cell.get_celltype.get_name} \n"
+            if j.get_rhs_cell.get_celltype == self then
+              # 同じセルタイプへ結合している場合(VDES では type conflict になる)
+              p = j.get_rhs_port
+              des_type = "const struct tag_#{@global_name}_#{p.get_name}_DES"
+            else
+              des_type = "struct tag_#{definition.get_signature.get_global_name}_VDES"
+            end
+
+            if j.get_rhs_subscript then
+              # 受け口配列
+              subscript = j.get_rhs_subscript
+              f.printf( "extern %s %s%d;\n",
+                        des_type,
+                        "#{j.get_port_global_name}_des",
+                        subscript)
+            else
+              f.printf( "extern %s %s;\n",
+                        des_type,
+                        "#{j.get_port_global_name}_des" )
+            end
+          end
+          # mikan   cell の namespace 未対応、Join で Cell オブジェクトを引当ておく必要あり
+        }
+
+        f.print "\n"
+      end
+    }
+  end
+
+  def gen_cell_ep_vdes_array fs
+    if @n_cell_gen >0 then
+      fs.each{ |r, f| f.printf( TECSMsg.get( :CPA_comment ), "#_CPA_#" ) }  # mikan 呼び口配列が無い場合も出てしまう
+    end
+
+    @ordered_cell_list.each{ |c|
+      if c.is_generate? then
+        f = fs[ c.get_region.get_domain_root ]
+
+        jl = c.get_join_list
+        # ループを回す変数を jl から @port に変更
+        # dynamic, optional 
+#        jl.get_items.each{ |j|
+        @port.each { |port|
+          next if port.get_port_type != :CALL
+          dbgPrint( "gen_cell_ep_vdes_array: #{c.get_name}.#{port.get_name}\n" )
+
+#          definition = j.get_definition
+#          next unless definition.instance_of? Port
+          j = jl.get_item( port.get_name )
+
+          # port = definition    # definition は composite の Port が得られることがある
+          # port = find j.get_name # celltype の Port (こちらに最適化情報がある)
+          next if port.is_cell_unique?
+          next if port.is_omit?
+
+          b_array = false
+          am = nil
+          if j then
+            am = j.get_array_member2
+            if am then
+              b_array = true
+            end
+          else
+            if port.get_array_size == "[]" then
+              # this case is dynamic optional and nothing joined
+              next
+            elsif port.get_array_size then
+              b_array = true
+            end
+          end
+          if b_array  then
+#          if am then
+            # 左辺は配列
+            const = ( port.is_dynamic? && ! $ram_initializer ) ? '' : 'const '
+            init = ( port.is_dynamic? && $ram_initializer ) ? '_init_' : ''
+
+            if ! port.is_skelton_useless? then
+              f.printf( "struct %s * #{const}%s_%s[] = {\n",
+                        "tag_#{port.get_signature.get_global_name}_VDES",
+                        "#{c.get_global_name}",
+                        "#{port.get_name}" + init )
+            else
+
+#              スケルトン関数不要最適化の場合、この配列は参照されない
+              # mikan このケースがテストされていない
+              f.printf( "#{const}%s_IDX  %s_%s[] = {\n",
+#                        "#{j.get_celltype.get_global_name}",   # 右辺 composite に対応できない
+                        "#{j.get_rhs_cell.get_celltype.get_global_name}",
+                        "#{c.get_global_name}",
+                        "#{j.get_name}" )
+            end
+            if port.get_array_size == "[]" then
+              length = am.length
+            else
+              length = port.get_array_size
+            end
+            # am.each { |j|
+            i = 0
+            while i < length
+              if am == nil then
+                f.print( "    0,\n" )
+                i += 1
+                next
+              end
+              j = am[i]
+              i += 1
+
+              if j then
+                # 同一セルタイプの結合の場合、VDES 型へのキャストが必要
+                if j.get_rhs_cell.get_celltype == self then
+                  definition = j.get_definition
+                  des_type_cast = "(struct tag_#{definition.get_signature.get_global_name}_VDES *)"
+                else
+                  des_type_cast = ""
+                end
+
+                
+                if j.get_rhs_subscript then
+                  # 右辺配列の場合(最適化はない)
+                  subscript = j.get_rhs_subscript
+                  f.printf( "    %s%d,\n",
+                            "#{des_type_cast}&#{j.get_port_global_name}_des",
+                            subscript)
+                  # p "1: #{j.get_port_global_name}_des"
+                  # p "2: #{j.get_cell_global_name}_#{j.get_port_name}_des"
+
+                else
+                  # 右辺非配列の場合 */
+                  if ! port.is_skelton_useless? then
+                    f.printf( "    %s,\n",
+                              "#{des_type_cast}&#{j.get_port_global_name}_des" )
+                  else
+                    cell = j.get_rhs_cell
+                    name_array = cell.get_celltype.get_name_array( cell )
+                    f.printf( "    #{name_array[7]},\n" )
+                  end
+                end
+              else
+                # optional で呼び口配列要素が初期化されていない
+                f.printf( "    0,\n" )
+              end
+            # }
+            end
+            # mikan   cell の namespace 未対応、Join で Cell オブジェクトを引当ておく必要あり
+            f.print "};\n"
+            # dynamic の呼び口配列
+            if port.is_dynamic? && $ram_initializer then
+              f.printf( "struct %s * %s_%s[ #{length} ];\n",
+                        "tag_#{port.get_signature.get_global_name}_VDES",
+                        "#{c.get_global_name}",
+                        "#{port.get_name}" )
+            end
+          end
+        }
+
+        f.print "\n"
+      end
+    }
+  end
+
+  #=== CB を初期化するプログラムの生成
+  def gen_cell_cb_initialize_code f
+    if ! need_CB_initializer?
+      return
+    end
+    f.printf( TECSMsg.get( :CIC_comment ), "#_CIC_#" )
+    f.print <<EOT
+void
+#{@global_name}_CB_initialize()
+{
+EOT
+    if @singleton then
+      f.print <<EOT
+    SET_CB_INIB_POINTER(i,p_cb)
+    INITIALIZE_CB()
+EOT
+    else
+      f.print <<EOT
+    #{@global_name}_CB	*p_cb;
+    int		i;
+    FOREACH_CELL(i,p_cb)
+        SET_CB_INIB_POINTER(i,p_cb)
+        INITIALIZE_CB(p_cb)
+    END_FOREACH_CELL
+EOT
+    end
+
+    f.print <<EOT
+}
+EOT
+  end
+
+  # === CB/INIB の外で初期化される変数の出力
+  def gen_cell_cb_out_init fs
+
+    # セルがなければ、出力しない
+    if @n_cell_gen == 0 then
+      return
+    end
+
+    fs.each{ |r, f| f.printf( TECSMsg.get( :AVAI_comment ), "#_AVAI_#" ) }
+
+    # attribute, var のポインタ型の参照する配列を生成
+    @ordered_cell_list.each{ |c|
+      next if  ! c.is_generate?
+
+      f = fs[ c.get_region.get_domain_root ]
+      name_array = get_name_array( c )
+
+      ct = c.get_celltype
+      jl = c.get_join_list
+
+      # attribute, var のポインタ変数が配列により初期化される場合の、配列を出力
+      av_list = ct.get_attribute_list + ct.get_var_list
+      if av_list.length != 0 then
+        av_list.each{ |a|    # a: Decl
+          j = jl.get_item( a.get_identifier )
+          if j then
+            init = j.get_rhs
+          else
+            init = a.get_initializer
+          end
+
+          if( a.is_type?( PtrType ) && ( (init && init.instance_of?( Array )) || init == nil ) )then
+            ptr_type = a.get_type
+            size = ptr_type.get_size
+
+            if size then
+              # 式を評価する(attribute, var に含まれる変数を参照可能)
+              sz = size.eval_const( c.get_join_list, c.get_celltype.get_name_list )
+              # 式を生成しなおす (変数を含まない形にする)  不完全な形で Token を生成 (エラー発生しないから)
+              size = Expression.new( [:INTEGER_CONSTANT, Token.new(sz, nil, 0, 0)] )
+              array_type = ArrayType.new( size )
+              type = a.get_type.get_referto
+              if ! type.is_const? && a.get_kind == :ATTRIBUTE then
+                type.set_qualifier :CONST
+              end
+              array_type.set_type( type )
+              if a.get_kind == :ATTRIBUTE then
+                f.print "const "
+              end
+              f.printf( "#{a.get_type.get_referto.get_type_str} #{name_array[3]}_#{a.get_identifier}_INIT[%d]#{a.get_type.get_referto.get_type_str_post}", sz )
+								# name_array[3]: cell_CB_INIT
+              if !( $ram_initializer && a.get_kind == :VAR ) then
+                # -R (ram initializer 使用) の場合 var は初期化コードを出力しない
+                if( init )then
+                  str = " = #{gen_cell_cb_init( f, c, name_array, array_type, init, a.get_identifier, 1, true )}"
+                  str = str.sub( /\}$/, "};\n" )
+                else
+                  str = ";\n"
+                end
+                f.print( str )
+              else
+                f.print( ";\n" )
+              end
+            end
+          end
+        }
+      end
+    }
+  end
+
+  #=== var の初期値の ROM 部への
+  def gen_cell_var_init f
+    # var の{ }で囲まれた初期値指定があるか調べる
+    n_init = 0
+    @var.each { |v|
+      init = v.get_initializer
+      if init && init.instance_of?( Array ) then
+        n_init += 1
+      end
+    }
+
+    if n_init > 0 then
+      f.printf( TECSMsg.get( :AVI_comment ), "#_AVI_#" )
+      @var.each { |v|
+        init = v.get_initializer
+        if init && init.instance_of?( Array ) then
+          type = v.get_type
+          org_type = v.get_type.get_original_type
+
+          if( org_type.kind_of? PtrType )then
+            # PtrType は ArrayType にすり替える
+
+            # 初期化子の要素数だけとする（後は 0)
+            t2 = ArrayType.new( Expression.create_integer_constant( init.length, nil ) )
+            t2.set_type( type.get_type )
+            type = t2
+            org_type = t2
+          end
+
+          c = @ordered_cell_list[0]   # 仮の cell (実際には使われない)
+          name_array = get_name_array( c )
+          # f.print "const #{type0.get_type_str}\t#{@global_name}_#{v.get_name}_VAR_INIT#{type0.get_type_str_post} = "
+          f.print "const #{type.get_type_str}\t#{@global_name}_#{v.get_name}_VAR_INIT#{type.get_type_str_post} = "
+          if org_type.kind_of? StructType then
+            # celltype の default の初期値あり
+            str = gen_cell_cb_init( f, c, name_array, type, init, v.get_identifier, 1, true )
+          elsif( org_type.kind_of?( PtrType ) || org_type.kind_of?( ArrayType ) ) then
+            str = "{ "
+            type = org_type.get_type
+            # mikan ポインタではなく、配列型としないと、ポインタ変数の領域の分、損する
+            init.each { |i|
+              str += gen_cell_cb_init( f, c, name_array, type, i, v.get_identifier, 1, true )
+              str += ", "
+            }
+            str += "}"
+          else
+            p type.class
+            raise "Unknown Type"
+          end
+          f.print str
+          f.print ";\n"
+        end
+      }
+      f.print "\n"
+    end
+
+  end
+
+  def gen_cell_cb fs
+    if has_INIB? then
+      if @n_cell_gen > 0 then
+        fs.each{ |r, f| f.printf( TECSMsg.get( :INIB_comment ), "#_INIB_#" ) }
+      end
+      if @singleton then
+        fs.each{ |r, f| f.print "#{@global_name}_INIB #{@global_name}_SINGLE_CELL_INIB = \n" }
+        indent = 0
+      elsif ! @b_need_ptab then
+        fs.each{ |r, f| f.print "#{@global_name}_INIB #{@global_name}_INIB_tab[] = {\n" }
+        indent = 1
+      else
+        indent = 0
+      end
+
+      @ordered_cell_list.each{ |c|
+        next if ! c.is_generate?
+
+        f = fs[ c.get_region.get_domain_root ]
+
+        name_array = get_name_array( c )
+
+        unless @singleton then
+          print_indent( f, indent )
+          f.print "/* cell: #{name_array[2]}:  #{name_array[1]} id=#{c.get_id} */\n"
+			    # name_array[2]: cell_CB_name
+        end
+
+        print_indent( f, indent )
+        if @b_need_ptab then
+          f.print "const #{@global_name}_INIB #{name_array[5]} = "
+        end
+        f.print "{\n"
+
+        gen_cell_cb_port( c, indent, f, name_array, :INIB )
+        gen_cell_cb_attribute( c, indent, f, name_array, :INIB )
+
+        unless @singleton then
+          # 1 つの cell INIB の終わり
+          if @b_need_ptab then
+            f.print( "};\n\n" )
+          else
+            f.print( "    },\n" )
+          end
+        end
+      }
+      if ! @b_need_ptab then
+        fs.each{ |r, f| f.print( "};\n\n" ) }
+      end
+    end  # has_INIB?
+
+    if has_CB? then
+      if @n_cell_gen >0 then
+        fs.each{ |r, f| f.printf( TECSMsg.get( :CB_comment ),  "#_CB_#" ) }
+      end
+
+      # RAM initializer を使用しない、または ROM 化しない
+      if $ram_initializer == false || $rom == false then
+        if @singleton then
+          fs.each{ |r, f| f.print "struct tag_#{@global_name}_CB #{@global_name}_SINGLE_CELL_CB = \n" }
+          indent = 0
+        elsif ! @b_need_ptab then
+          fs.each{ |r, f| f.print "struct tag_#{@global_name}_CB #{@global_name}_CB_tab[] = {\n" }
+          indent = 1
+        else
+          indent = 0
+        end
+
+        @ordered_cell_list.each{ |c|
+          next if ! c.is_generate?
+
+          f = fs[ c.get_region.get_domain_root ]
+
+          name_array = get_name_array( c )
+
+          unless @singleton then
+            print_indent( f, indent )
+            f.print "/* cell: #{name_array[2]}:  #{name_array[1]} id=#{c.get_id} */\n"
+            # name_array[2]: cell_CB_name
+          end
+
+          print_indent( f, indent )
+          if @b_need_ptab then
+            f.print "#{@global_name}_CB #{name_array[2]} = "
+          end
+          f.print "{\n"
+
+          if has_INIB? then
+            print_indent( f, indent + 1 )
+            f.printf( "&%-39s /* _inib */\n", "#{name_array[5]}," )
+          end
+
+          #if ! has_INIB? then
+          if $rom == false then
+            gen_cell_cb_port( c, indent, f, name_array, :CB_ALL )
+          else
+            gen_cell_cb_port( c, indent, f, name_array, :CB_DYNAMIC )
+          end
+
+          gen_cell_cb_attribute( c, indent, f, name_array, :CB )
+          gen_cell_cb_var( c, indent, f, name_array )
+
+          unless @singleton then
+            # 1 つの cell CB の終わり
+            if @b_need_ptab then
+              f.print( "};\n\n" )
+            else
+              f.print( "    },\n" )
+            end
+          end
+        }
+        if ! @b_need_ptab then
+          fs.each{ |r, f| f.print( "};\n\n" ) }
+        end
+      else
+        if @singleton then
+          fs.each{ |r, f| f.print "struct tag_#{@global_name}_CB #{@global_name}_SINGLE_CELL_CB;\n" }
+          indent = 0
+        elsif @b_need_ptab then
+          @ordered_cell_list.each{ |c|
+            next if ! c.is_generate?
+
+            f = fs[ c.get_region.get_domain_root ]
+
+            name_array = get_name_array( c )
+            f.print "/* cell: #{name_array[2]}:  #{name_array[1]} id=#{c.get_id} */\n"
+            f.print "#{@global_name}_CB #{name_array[2]} = {};\n"
+          }
+        else
+          fs.each{ |r, f| f.print "struct tag_#{@global_name}_CB #{@global_name}_CB_tab[#{@n_cell_gen}];\n" }
+        end
+      end
+    end  # has_CB?
+  end
+
+  def gen_cell_cb_tab f
+    indent = 0
+    if @b_need_ptab then
+      if has_INIB? && ( $ram_initializer || ! has_CB? ) then
+        f.print "/* ID to INIB table #_INTAB_# */\n"
+        @ordered_cell_list.each{ |c|
+          if c.is_generate? && ( c.get_region.get_domain_root != Region.get_root ) then # 生成対象かつ、ルート以外か
+            name_array = get_name_array( c )
+            print_indent( f, indent + 1 )
+            f.print "extern #{@global_name}_INIB  #{name_array[5]};\n"
+          end
+        }
+
+        f.print "#{@global_name}_INIB *const #{@global_name}_INIB_ptab[] ={\n"
+        @ordered_cell_list.each{ |c|
+          if c.is_generate? then                           # 生成対象か？
+            name_array = get_name_array( c )
+            print_indent( f, indent + 1 )
+            f.print "&#{name_array[5]},\n"
+          end
+        }
+        f.print "};\n"
+      end
+      if has_CB? then
+        f.print "/* ID to CB table #_CBTAB_# */\n"
+        @ordered_cell_list.each{ |c|
+          if c.is_generate? && ( c.get_region.get_domain_root != Region.get_root ) then # 生成対象かつ、ルート以外か
+            name_array = get_name_array( c )
+            print_indent( f, indent + 1 )
+            f.print "extern #{@global_name}_CB  #{name_array[2]};\n"
+          end
+        }
+
+        f.print "#{@global_name}_CB *const #{@global_name}_CB_ptab[] ={\n"
+        @ordered_cell_list.each{ |c|
+          if c.is_generate? then                           # 生成対象か？
+            name_array = get_name_array( c )
+            print_indent( f, indent + 1 )
+            f.print "&#{name_array[2]},\n"
+          end
+        }
+        f.print "};\n"
+      end
+    end
+  end
+
+
+  #=== name_array を生成
+  # IN:   cell  : Cell
+  #       index : CB, INIB 配列の添数
+  # RETURN: name_array
+  #   name_array[0] = @name           # celltype name
+  #   name_array[1] = cell.get_name   # cell name
+  #   name_array[2] = cell_CB_name    # cell_CB_name
+  #   name_array[3] = cell_CB_INIT    # cell_CB_INIT # CB の外側で初期化が必要な配列の名前
+  #   name_array[4] = cell_CB_proto   # CB name for prototype
+  #   name_array[5] = cell_INIB       # INIB name
+  #   name_array[6] = cell_ID         # ID
+  #   name_array[7] = cell_IDX        # IDX
+  #   name_array[8] = cell_CBP        # CB pointer
+  #   name_array[9] = @global_name    # celltype global name
+  #   name_array[10] = cell.get_global_name # cell global name
+  #   name_array[11] = cell_INIB_proto #INIB name for proto type
+  
+  def get_name_array( cell )
+
+    if @singleton then
+      cell_CB_name = "#{@global_name}_SINGLE_CELL_CB"
+      cell_CB_INIT = cell_CB_name
+      cell_CB_proto = "#{@global_name}_SINGLE_CELL_CB"
+      cell_INIB_name = "#{@global_name}_SINGLE_CELL_INIB"
+      cell_INIB_proto = cell_INIB_name
+      cell_ID = 0
+    else
+      if ! @b_need_ptab then
+        index = cell.get_id - cell.get_celltype.get_id_base
+        cell_CB_name = "#{@global_name}_CB_tab[#{index}]"
+        cell_CB_INIT = "#{@global_name}_#{cell.get_name}_CB"
+        cell_CB_proto = "#{@global_name}_CB_tab[]"
+        cell_INIB_name = "#{@global_name}_INIB_tab[#{index}]"
+        cell_INIB_proto = "#{@global_name}_INIB_tab[]"
+      else
+        cell_CB_name = "#{cell.get_global_name}_CB"
+        cell_CB_INIT = cell_CB_name
+        cell_CB_proto = cell_CB_name
+        cell_INIB_name = "#{cell.get_global_name}_INIB"
+        cell_INIB_proto = cell_INIB_name
+      end
+      cell_ID = cell.get_id
+    end
+
+    if has_CB? then
+      cell_CBP = "&#{cell_CB_name}"
+    elsif has_INIB? then
+      cell_CBP = "&#{cell_INIB_name}"
+    else
+      cell_CBP = "NULL"    # CB も INIB もなければ NULL に置換
+    end
+
+    if @idx_is_id_act then
+      cell_IDX = cell_ID
+    else
+      cell_IDX = cell_CBP
+    end
+
+    name_array = []
+    name_array[0] = @name           # celltype name
+    name_array[1] = cell.get_name   # cell name
+    name_array[2] = cell_CB_name    # cell_CB_name
+    name_array[3] = cell_CB_INIT    # cell_CB_INIT
+    name_array[4] = cell_CB_proto   # CB name for prototype
+    name_array[5] = cell_INIB_name  # cell INIB name
+    name_array[6] = cell_ID         # cell ID
+    name_array[7] = cell_IDX        # cell IDX
+    name_array[8] = cell_CBP        # cell CBP
+    name_array[9] = @global_name    # celltype global name
+    name_array[10] = cell.get_global_name # cell global name
+    name_array[11] = cell_INIB_proto # INIB name for prototype
+
+    return name_array
+  end
+
+  #=== attribute と size_is 指定された var (ポインタ)の初期化データを出力
+  #
+  # ROM 化サポートの有無、および出力対象が CB か INIB かにより出力される内容が異なる
+  def gen_cell_cb_attribute( cell, indent, f, name_array, cb_inib )
+    ct = self
+    jl = cell.get_join_list
+
+    if cb_inib == :INIB then
+      return if @n_attribute_ro == 0 && @n_var_size_is == 0
+      print_indent( f, indent + 1 )
+      f.print "/* attribute(RO) */ \n"
+    elsif $rom then  # && cb_inib == CB
+      # CB で rw と var
+      return if @n_attribute_rw == 0
+      print_indent( f, indent + 1 )
+      f.print "/* attribute(RW) */ \n"
+    else  # cb_inib == CB && $rom == false
+      # CB に全部
+      return if @n_attribute_rw == 0 && @n_attribute_ro == 0 && @n_var_size_is == 0
+      print_indent( f, indent + 1 )
+      f.print "/* attribute */ \n"
+    end
+
+    attribute = ct.get_attribute_list
+    attribute.each{ |a|              # a: Decl
+      next if a.is_omit?
+      if cb_inib == :INIB && a.is_rw? == true then
+        # $rom == true でしか、ここへ来ない
+        next
+      elsif cb_inib == :CB && $rom && ! a.is_rw? then
+        next
+      end
+
+      j = jl.get_item( a.get_identifier )
+      if j then
+        # cell の初期値指定あり
+        gen_cell_cb_init( f, cell, name_array, a.get_type, j.get_rhs, a.get_identifier, indent + 1 )
+      elsif a.get_initializer then
+        # celltype の default の初期値あり
+        gen_cell_cb_init( f, cell, name_array, a.get_type, a.get_initializer, a.get_identifier, indent + 1 )
+      else
+        # 初期値未指定
+        gen_cell_cb_init( f, cell, name_array, a.get_type, nil, a.get_identifier, indent + 1 )
+      end
+    }
+    @var.each{ |v|
+      next if v.is_omit?
+      next if v.get_size_is == nil   # size_is 指定がある場合 attribute の一部として出力
+
+      if v.get_initializer && $ram_initializer == false then
+        gen_cell_cb_init( f, cell, name_array, v.get_type, v.get_initializer, v.get_identifier, indent + 1 )
+      else
+        # 初期値未指定 または RAM initializer 使用
+        gen_cell_cb_init( f, cell, name_array, v.get_type, nil, v.get_identifier, indent + 1 )
+      end
+    }
+  end
+
+  #=== var の初期化データを出力
+  def gen_cell_cb_var( cell, indent, f, name_array )
+    jl = cell.get_join_list
+    var = get_var_list
+    if @n_var - @n_var_size_is > 0 then
+      print_indent( f, indent + 1 )
+      f.print "/* var */ \n"
+      var.each{ |v|
+
+        next if v.is_omit?
+        next if v.get_size_is      # size_is 指定がある場合 attribute の一部として出力
+
+        if v.get_initializer && $ram_initializer == false then
+          gen_cell_cb_init( f, cell, name_array, v.get_type, v.get_initializer, v.get_identifier, indent + 1 )
+        else
+          # 初期値未指定 または RAM initializer 使用
+          gen_cell_cb_init( f, cell, name_array, v.get_type, nil, v.get_identifier, indent + 1 )
+        end
+      }
+    end
+  end
+
+  #inib_cb::Symbol: :INIB, :CB_ALL, :CB_DYNAMIC
+  def gen_cell_cb_port( cell, indent, f, name_array, inib_cb = :INIB )
+    gen_cell_cb_call_port( cell, indent, f, name_array, inib_cb )
+    gen_cell_cb_entry_port( cell, indent, f, name_array )
+  end
+
+  #=== 呼び口の初期化コードの生成
+  def gen_cell_cb_call_port( cell, indent, f, name_array, inib_cb )
+    jl = cell.get_join_list
+
+    port = get_port_list
+    if inib_cb == :INIB && ( @n_call_port - @n_call_port_omitted_in_CB -
+                             ( $ram_initializer ? 0 : (@n_call_port_dynamic-@n_call_port_array_dynamic) )  > 0 ) ||
+       inib_cb == :CB_ALL && @n_call_port > 0 ||
+       inib_cb == :CB_DYNAMIC && (@n_call_port_dynamic - @n_call_port_array_dynamic) > 0 then
+      print_indent( f, indent + 1 )
+      f.print "/* call port (#{inib_cb}) #_CP_# */ \n"
+      port.each{ |p|
+        next if p.get_port_type != :CALL
+        next if p.is_omit?
+        next if p.is_cell_unique?        # 最適化（単一セルで呼び口マクロに埋め込まれる）
+        next if inib_cb == :INIB && p.is_dynamic? && p.get_array_size == nil && ! $ram_initializer
+        next if inib_cb == :CB_DYNAMIC && ( ! p.is_dynamic? || p.get_array_size != nil )
+
+        j = jl.get_item( p.get_name )
+        print_indent( f, indent + 1 )
+
+        # debug
+        if j == nil then
+          dbgPrint "cell_cb_call_port: #{p.get_name} array size=#{p.get_array_size}\n"
+          # optional 呼び口
+          # cdl_error( "H1003 internal error: cell \'$1\' port \'$2\': initializer not found\n" , cell.get_name, p.get_name )
+          # exit( 1 )
+          if p.get_array_size then
+            if p.is_dynamic? then
+              if inib_cb == :INIB then
+                if  $ram_initializer then
+                  f.printf( "%-40s /* #_CCP7_# _init_ */\n",  "#{cell.get_global_name}_#{p.get_name}_init_," )
+                  print_indent( f, indent + 1 )
+                end
+                f.printf( "%-40s /* #_CCP7B_# */\n",  "#{cell.get_global_name}_#{p.get_name}," )
+              elsif $rom == false then
+                f.printf( "%-40s /* #_CCP8_# */\n",  "#{cell.get_global_name}_#{p.get_name}," )
+              end
+            else
+              f.printf( "%-40s /* #_CCP9_# */\n",  "0," )
+            end
+            if p.get_array_size == "[]" then
+              # 添数省略の呼び口配列
+              print_indent( f, indent + 1 )
+              f.printf( "%-40s /* %s #_CCP6_# */\n", "0,", "length of #{p.get_name} (n_#{p.get_name})" )
+            end
+          else
+            f.printf( "%-40s /* #_CCP5_# */\n",  "0," )
+          end
+          next
+        end
+
+        am = j.get_array_member2
+        if am then
+          # 呼び口配列の場合
+          if inib_cb == :INIB && p.is_dynamic? && p.get_array_size != nil && $ram_initializer then
+            f.printf( "%-40s /* #_CCP3_# _init_ */\n",  "#{cell.get_global_name}_#{j.get_name}_init_," )
+            print_indent( f, indent + 1 )
+          end
+          f.printf( "%-40s /* #_CCP3B_# */\n",  "#{cell.get_global_name}_#{j.get_name}," )
+          if p.get_array_size == "[]" then
+            # 添数省略の呼び口配列
+            print_indent( f, indent + 1 )
+            f.printf( "%-40s /* %s #_CCP4_# */\n", "#{am.length},", "length of #{p.get_name} (n_#{p.get_name})" )
+          end
+        else
+          # 同一セルタイプの結合の場合、VDES 型へのキャストが必要
+          #print "CCP0/CCP1 #{p.get_name}, #{j.get_rhs_cell.get_celltype.get_name}, #{@name}\n"
+          if j.get_rhs_cell.get_celltype == self then
+            definition = j.get_definition
+            des_type_cast = "(struct tag_#{definition.get_signature.get_global_name}_VDES *)"
+          else
+            des_type_cast = ""
+          end
+
+          init = ( p.is_dynamic? && inib_cb == :INIB ) ? "_init_" : ""
+
+          if j.get_rhs_subscript then
+            # 受け口配列の場合
+            subscript = j.get_rhs_subscript
+            f.printf( "%-40s /* %s #_CCP0_# */\n",
+                      # "&#{j.get_cell_global_name}_#{j.get_port_name}_des#{subscript},",
+                      "#{des_type_cast}&#{j.get_port_global_name}_des#{subscript},",
+                      p.get_name.to_s + init )
+          else
+            # 呼び口配列でも、受け口配列でもない
+            if ! p.is_skelton_useless? then
+              f.printf( "%-40s /* %s #_CCP1_# */\n",
+                        "#{des_type_cast}&#{j.get_port_global_name}_des,",
+                        p.get_name.to_s + init )
+            else
+              # スケルトン不要最適化（CB (INIB) へのポインタを埋め込む）
+              c = j.get_rhs_cell                    # 呼び先セル
+              ct = c.get_celltype                   # 呼び先セルタイプ
+              name_array = ct.get_name_array( c )   # 呼び先セルタイプで name_array を得る
+              if ct.has_INIB? || ct.has_CB? then
+                f.printf( "%-40s /* %s #_CCP2_# */\n", "#{name_array[7]},", p.get_name )
+              else
+                # 呼び先は CB も INIB も持たない（NULL に初期化）
+                f.printf( "%-40s /* %s #_CCP2B_# */\n", "0,", p.get_name )
+              end
+            end
+          end
+        end
+
+      }
+      end
+  end
+
+  #=== 受け口の初期化コードの生成
+  def gen_cell_cb_entry_port( cell, indent, f, name_array )
+    jl = cell.get_join_list
+
+    port = get_port_list
+    if @n_entry_port != 0 then
+      print_indent( f, indent + 1 )
+      f.print "/* entry port #_EP_# */ \n"
+      @port.each{ |p|
+        # next if p.is_omit?  # 受け口配列の個数は省略しない
+        if p.get_port_type == :ENTRY && p.get_array_size == "[]"
+          print_indent( f, indent + 1 )
+          f.printf( "%-40s /*  #_EEP_# */\n", "#{cell.get_entry_port_max_subscript( p )+1}," )
+        end
+      }
+    end
+  end
+
+  #=== セルの attribute の初期値を出力
+  #
+  #f_get_str:: true の場合、文字列を返す、false の場合、ファイル f に出力する．
+  # 文字列を返すとき、末尾に ',' は含まれない．
+  # ファイルへ出力するとき、末尾に ',' が出力される．構造体要素、配列要素の初期値を出力すると ',' が二重に出力される．
+  # ただし現状では、ファイルへ出力することはない
+  #
+  def gen_cell_cb_init( f, cell, name_array, type, init, identifier, indent, f_get_str = false )
+
+    cell_CB_name = name_array[2]
+    cell_CB_INIT = name_array[3]
+
+    while type.kind_of?( DefinedType )
+      type = type.get_type
+    end
+
+    if ( init == nil ) then
+
+      if f_get_str then
+        # 初期値未指定
+        if type.kind_of?( BoolType ) then
+          str = "false"   # formerly tecs_false
+        elsif type.kind_of?( IntType ) then
+          str = "0"
+        elsif type.kind_of?( FloatType ) then
+          str = "0.0"
+        elsif type.kind_of?( EnumType ) then
+          str = "0"
+        elsif type.kind_of?( ArrayType ) then
+          str = "{}"
+        elsif type.kind_of?( StructType ) then
+          str = "{}"
+        elsif type.kind_of?( PtrType ) then
+          if type.get_size then
+            str = "#{cell_CB_INIT}_#{identifier}_INIT"
+          else
+            str = "0"
+          end
+        else
+          raise "UnknownType"
+        end
+        return str
+      else
+        # 初期値未指定
+        if type.kind_of?( BoolType ) then
+          f.print "    " * indent
+          f.printf( "%-40s /* %s */\n", "false,", identifier )   # formerly tecs_false
+        elsif type.kind_of?( IntType ) then
+          f.print "    " * indent
+          f.printf( "%-40s /* %s */\n", "0,", identifier )
+        elsif type.kind_of?( FloatType ) then
+          f.print "    " * indent
+          f.printf( "%-40s /* %s */\n", "0.0,", identifier )
+        elsif type.kind_of?( EnumType ) then
+          f.print "    " * indent
+          f.printf( "%-40s /* %s */\n", "0,", identifier )
+        elsif type.kind_of?( ArrayType ) then
+          f.print "    " * indent
+          f.printf( "%-40s /* %s */\n", "{},", identifier )
+        elsif type.kind_of?( StructType ) then
+          f.print "    " * indent
+          f.printf( "%-40s /* %s */\n", "{},", identifier )
+        elsif type.kind_of?( PtrType ) then
+          if type.get_size then
+            f.print "    " * indent
+            f.printf( "%-40s /* %s */\n", "#{cell_CB_INIT}_#{identifier}_INIT,", identifier )
+          else
+            f.print "    " * indent
+            f.printf( "%-40s /* %s */\n", "0,", identifier )
+          end
+        else
+          raise "UnknownType"
+        end
+      end
+      return
+    end    
+
+    # このメソッドは Celltype のものである必要は無い（上に続くのでここに置く）
+    # 初期値指定あり
+    if type.kind_of?( BoolType ) then
+      if init.instance_of?( C_EXP ) then
+        init_str = subst_name( init.get_c_exp_string, name_array )
+      else
+        init_str = init.eval_const2(cell.get_join_list,@name_list)
+      end
+
+      if f_get_str then
+        return "#{init_str}"
+      else
+        f.print "    " * indent
+        f.printf( "%-40s /* %s */\n", "#{init_str},", identifier )
+      end
+#      if f_get_str then
+#        return "#{init.eval_const2(nil)}"
+#      else
+#        f.print "    " * indent
+#        f.printf( "%-40s /* %s */\n", "#{init.eval_const2(nil)},", identifier )
+#      end
+    elsif type.kind_of?( IntType ) then
+      if init.instance_of?( C_EXP ) then
+        init_str = subst_name( init.get_c_exp_string, name_array )
+      else
+        init_str = init.eval_const2(cell.get_join_list,@name_list)
+      end
+
+      if f_get_str then
+        return "#{init_str}"
+      else
+        f.print "    " * indent
+        f.printf( "%-40s /* %s */\n", "#{init_str},", identifier )
+      end
+    elsif type.kind_of?( FloatType ) then
+      # mikan C_EXP for FloatType
+      if f_get_str then
+        return "#{init.eval_const2(cell.get_join_list,@name_list)}"
+      else
+        f.print "    " * indent
+        f.printf( "%-40s /* %s */\n", "#{init.eval_const2(cell.get_join_list,@name_list)},", identifier )
+      end
+    elsif type.kind_of?( EnumType ) then
+      # mikan C_EXP for EnumType
+      if f_get_str then
+        return "#{init.eval_const2(cell.get_join_list,@name_list)}"
+      else
+        f.print "    " * indent
+        f.printf( "%-40s /* %s */\n", "#{init.eval_const2(cell.get_join_list,@name_list)},", identifier )
+      end
+    elsif type.kind_of?( ArrayType ) then
+      if type.get_subscript
+        len = type.get_subscript.eval_const(cell.get_join_list,@name_list)
+      else
+        len = init.length
+      end
+
+      at = type.get_type
+      i = 0
+      if f_get_str then
+        str = "{ " 
+      else
+        f.print "    " * indent
+        f.print( "{\n" )
+      end
+
+      len.times {
+        next if ! init[i]        # mikan この処置は適切？
+        if f_get_str then
+          str += gen_cell_cb_init( f, cell, name_array, at, init[i], "#{identifier}[#{i}]", indent + 1, f_get_str )
+          str += ', '
+        else
+          gen_cell_cb_init( f, cell, name_array, at, init[i], "#{identifier}[#{i}]", indent + 1, f_get_str )
+        end
+        i += 1
+      }
+
+      if f_get_str then
+         str += "}"
+      else
+        f.print "    " * indent
+        f.print( "},\n" )
+      end
+
+    elsif type.kind_of?( StructType ) then
+      i = 0
+      decls = type.get_members_decl.get_items
+      if f_get_str then
+        str = "{ "
+      else
+        f.print "    " * indent
+        f.print( "{                                        /* #{identifier} */\n" )
+      end
+
+      decls.each{ |d|
+        # p "#{d.get_identifier}: #{init}"
+        next if ! init[i]
+
+        if f_get_str then
+          str += gen_cell_cb_init( f, cell, name_array, d.get_type, init[i], d.get_identifier, indent + 1, f_get_str )
+          str += ', '
+        else
+          gen_cell_cb_init( f, cell, name_array, d.get_type, init[i], d.get_identifier, indent + 1, f_get_str )
+        end
+        i += 1
+      }
+      if f_get_str then
+        str += "}"
+      else
+        f.print "    " * indent
+        f.print( "},\n" )
+      end
+
+    elsif type.kind_of?( PtrType ) then
+
+      if init.instance_of?( Array ) then
+        if f_get_str then
+          return "#{cell_CB_INIT}_#{identifier}_INIT"
+        else
+          f.print "    " * indent
+          f.printf( "%-40s /* %s */\n", "#{cell_CB_INIT}_#{identifier}_INIT,", identifier )
+        end
+      elsif init.instance_of?( C_EXP ) then
+        init_str = subst_name( init.get_c_exp_string, name_array )
+
+        if f_get_str then
+          return "#{init_str}"
+        else
+          f.print "    " * indent
+          f.printf( "%-40s /* %s */\n", "#{init_str},", identifier )
+        end
+
+      else
+        if f_get_str then
+          return "#{init.eval_const2(cell.get_join_list,@name_list)}"
+        else
+          f.print "    " * indent
+# p init.eval_const2(cell.get_join_list,@name_list).class
+# p init.eval_const2(cell.get_join_list,@name_list)
+# p identifier
+          f.printf( "%-40s /* %s */\n", "#{init.eval_const2(cell.get_join_list,@name_list)},", identifier )
+
+        end
+      end
+    else
+      raise "UnknownType"
+    end
+  end
+
+  #== 関数テーブルの外部参照
+  def gen_cell_extern_mt fs
+    fs.each{ |r, f|
+      if ! r.is_root? then
+        @port.each{ |p|
+          next if p.is_omit?
+          if p.get_port_type == :ENTRY && ! p.is_VMT_useless? then
+            f.print "extern const struct tag_#{p.get_signature.get_global_name}_VMT"
+            f.print " #{@global_name}_#{p.get_name}_MT_;\n"
+          end
+        }
+      end
+    }
+  end
+
+  #=== 受け口ディスクリプタの定義を生成
+  def gen_cell_ep_des fs
+    if @n_cell_gen >0 then
+      fs.each{ |r, f|        f.printf( TECSMsg.get( :EPD_comment ),  "#_EPD_#" ) }
+    end
+
+    index = 0
+    @ordered_cell_list.each{ |c|
+
+      next if ! c.is_generate?
+
+      f = fs[ c.get_region.get_domain_root ]
+
+      ct = c.get_celltype     # ct = self でも同じ
+      jl = c.get_join_list
+      name_array = get_name_array( c )
+
+      port = ct.get_port_list
+      if port.length != 0 then
+        port.each{ |p|
+          next if p.get_port_type != :ENTRY
+          next if p.is_omit?
+          if p.is_skelton_useless?       # 受け口最適化n ep_opt
+            f.print( "/* #{p.get_name} : omitted by entry port optimize */\n" )
+            next
+          end
+
+          len = p.get_array_size
+          if len == "[]" then
+            len = c.get_entry_port_max_subscript(p) + 1
+          end
+
+          if len != nil then
+            # 受け口配列の場合
+            i = 0
+            while i < len
+              f.print "extern const struct tag_#{@global_name}_#{p.get_name}_DES"
+              f.print " #{c.get_global_name}_#{p.get_name}_des#{i};\n"
+              f.print "const struct tag_#{@global_name}_#{p.get_name}_DES"
+              # f.print " #{c.get_name}_#{p.get_name}_des#{i} = {\n"
+              f.print " #{c.get_global_name}_#{p.get_name}_des#{i} = {\n"
+              if p.is_VMT_useless? then
+                f.print "    0,\n"
+              else
+                f.print "    &#{@global_name}_#{p.get_name}_MT_,\n"
+              end
+              if( @idx_is_id_act )then
+                f.print "    #{c.get_id},           /* ID */\n"
+              else
+                if has_CB? then
+                  # if @singleton then
+                  #   f.print "    &#{@global_name}_SINGLE_CELL_CB,        /* CB 1 */\n"
+                  # else
+                  #   # f.print "    &#{@global_name}_#{c.get_name}_CB,\n"
+                  #   f.print "    &#{@global_name}_CB_tab[#{index}],      /* CB 2 */\n"
+                  # end
+                  f.print "    #{name_array[8]},      /* CB 1 */\n"
+                elsif has_INIB? then
+                  # if @singleton then
+                  #   f.print "    &#{@global_name}_SINGLE_CELL_INIB,      /* INIB 1 */\n"
+                  # else
+                  #   f.print "    &#{@global_name}_INIB_tab[#{index}],    /* INIB 2 */\n"
+                  # end
+                  f.print "    &#{name_array[5]},      /* INIB 1 */\n"
+                else
+                  f.print "    0,\n"
+                end
+              end
+              f.print "    #{i}\n"
+              f.print "};\n"
+              i += 1
+            end
+          else
+            f.print "extern const struct tag_#{@global_name}_#{p.get_name}_DES"
+            f.print " #{c.get_global_name}_#{p.get_name}_des;\n"
+            f.print "const struct tag_#{@global_name}_#{p.get_name}_DES"
+            # f.print " #{c.get_name}_#{p.get_name}_des = {\n"
+            f.print " #{c.get_global_name}_#{p.get_name}_des = {\n"
+            if p.is_VMT_useless? then
+              f.print "    0,\n"
+            else
+              f.print "    &#{@global_name}_#{p.get_name}_MT_,\n"
+            end
+            if @idx_is_id_act then
+              f.print "    #{c.get_id},     /* ID */\n"
+            else
+              if has_CB? then
+                # if @singleton then
+                #   f.print "    &#{@global_name}_SINGLE_CELL_CB,       /* CB 3 */\n"
+                # else
+                #   f.print "    &#{@global_name}_CB_tab[#{index}],     /* CB 4 */\n"
+                #   # f.print "    &#{@global_name}_#{c.get_name}_CB,\n"
+                # end
+                f.print "    #{name_array[8]},      /* CB 3 */\n"
+              elsif has_INIB? then
+                # if @singleton then
+                #   f.print "    &#{@global_name}_SINGLE_CELL_INIB,     /* INIB 3 */\n"
+                # else
+                #   # f.print "    &#{@global_name}_INIB_tab[#{index}],   /* INIB 4 */\n"
+                # end
+                f.print "    &#{name_array[5]},      /* INIB 3 */\n"
+              else
+                f.print "    0,\n"
+              end
+            end
+            f.print "};\n"
+          end
+        }
+      end
+      index += 1
+    }
+  end
+
+  def generate_template_code
+
+    return if is_all_entry_inline?
+    return if @b_reuse && ! $generate_all_template
+    if ! ( @plugin && @plugin.gen_ep_func? ) then
+      return if $generate_no_template     # $generate_all_template より優先される
+
+      # 参考として出力するテンプレートファイルであることを示すために "_templ" を付加する
+      fname = "#{$gen}/#{@global_name}_templ.#{$c_suffix}"
+    else
+      # Plugin により生成されたセルタイプについては、原則的にテンプレートではなく、
+      # 修正不要なセルタイプの実装コードを生成する．
+      # このため、ファイル名に _temp を付加しない
+      fname = "#{$gen}/#{@global_name}.#{$c_suffix}"
+    end
+
+    f = AppFile.open(fname)
+
+    unless ( @plugin && @plugin.gen_ep_func? ) then
+      f.printf( TECSMsg.get( :template_note ), @name, @name )
+    else
+      print_note( f, true )
+    end
+
+    f.print TECSMsg.get( :preamble_note )
+    gen_template_attr_access f
+    gen_template_cp_fun f
+    # gen_template_types f     # 0805503 追加してみたが、やっぱりやめる
+    f.print( " *\n * #[</PREAMBLE>]# */\n\n" )
+    f.printf TECSMsg.get( :PAC_comment ), "#_PAC_#"
+
+    gen_template_private_header f
+    if ( @plugin ) then
+      # このメソッドの引数は plugin.rb の説明を見よ
+      @plugin.gen_preamble( f, @singleton, @name, @global_name )
+    end
+
+    gen_template_ep_fun f
+
+    f.print TECSMsg.get( :postamble_note )
+
+    if ( @plugin ) then
+      # このメソッドの引数は plugin.rb の説明を見よ
+      @plugin.gen_postamble( f, @singleton, @name, @global_name )
+    end
+
+    f.close
+  end
+
+#####  celltype template
+
+  def gen_template_private_header f
+    f.print "#include \"#{@global_name}_tecsgen.#{$h_suffix}\"\n\n"
+    f.print <<EOT
+#ifndef E_OK
+#define	E_OK	0		/* success */
+#define	E_ID	(-18)	/* illegal ID */
+#endif
+
+EOT
+  end
+
+  def gen_template_attr_access f
+
+    if @n_attribute_rw > 0 || @n_attribute_ro > 0 || @n_var > 0 then
+      f.printf( TECSMsg.get( :CAAM_comment ), "#_CAAM_#" )
+    end
+
+    @attribute.each { |a|
+
+      next if a.is_omit?
+
+      f.printf( " * %-16s %-16s %-16s\n", a.get_name, "#{a.get_type.get_type_str} #{a.get_type.get_type_str_post}", "ATTR_#{a.get_name}" )
+
+    }
+
+    @var.each { |v|
+
+      next if v.is_omit?
+
+      f.printf( " * %-16s %-16s %-16s\n", v.get_name, "#{v.get_type.get_type_str} #{v.get_type.get_type_str_post}", "VAR_#{v.get_name}" )
+    }
+
+  end
+
+  def gen_template_types f
+    f.printf( TECSMsg.get( :TYP_comment ), "#_TYP_#", "#{@global_name}_CB", "#{@name}_IDX" )
+  end
+
+  def gen_template_cp_fun f
+    if @n_call_port >0 then
+      f.print " *\n"
+      f.printf( TECSMsg.get( :TCPF_comment ), "#_TCPF_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      # next if p.is_omit?
+
+      sig_name = p.get_signature.get_global_name
+      con_tmp = p.get_signature.get_context
+      if con_tmp then
+        context = " context:#{con_tmp}"
+      else
+        context = ""
+      end
+
+      if p.is_optional? then
+        optional = " optional:true"
+        if p.get_array_size
+          is_join = " *   bool_t     is_#{p.get_name}_joined(int subscript)        check if joined\n"
+        else
+          is_join = " *   bool_t     is_#{p.get_name}_joined()                     check if joined\n"
+        end
+      else
+        optional = ""
+        is_join = ""
+      end
+
+      if p.is_omit? then
+        omit = " omit:true"
+      else
+        omit = ""
+      end
+
+      if p.is_allocator_port? then
+        f.print " * allocator port for #{p.get_port_type.to_s.downcase} port:#{p.get_allocator_port.get_name} func:#{p.get_allocator_func_decl.get_name} param: #{p.get_allocator_param_decl.get_name}\n"
+      elsif ! p.is_require? then
+        f.print " * call port: #{p.get_name} signature: #{sig_name}#{context}#{optional}#{omit}\n#{is_join}"
+      else
+        f.print " * require port: signature:#{sig_name}#{context}\n"
+      end
+
+      p.get_signature.get_function_head_array.each{ |fun|
+        
+        ft = fun.get_declarator.get_type
+
+        f.printf( " *   %-14s ", ft.get_type.get_type_str )
+        if ! p.is_require? || p.has_name? then
+          f.print( "#{p.get_name}_#{fun.get_name}(" )
+        else
+          f.print( "#{fun.get_name}(" )
+        end
+        delim = ""
+
+#        if ! @singleton then
+#          f.print( "#{delim} p_that" )
+#          delim = ","
+#        end
+
+        if p.get_array_size then
+          f.print( "#{delim} subscript" )
+          delim = ","
+        end
+
+        ft.get_paramlist.get_items.each{ |param|
+          # p "type_str: #{param.get_type.get_type_str}"
+          f.print( "#{delim} #{param.get_type.get_type_str}" )
+          f.print( " #{param.get_name}#{param.get_type.get_type_str_post}" )
+          delim = ","
+	}
+        f.print( " );\n" )
+
+#        subsc = ""
+#        subsc = "[subscript]" if p.get_array_size
+#
+#        if @singleton then
+#          f.print( " *        #{@global_name}_#{p.get_name}" )
+#        else
+#          f.print( " *        (p_that)->#{p.get_name}" )
+#        end
+#        f.print( "#{subsc}->VMT->#{fun.get_name}(" )
+#        f.print( " (p_that)->#{p.get_name}#{subsc}" )
+#        ft.get_paramlist.get_items.each{ |param|
+#          f.print( ", (#{param.get_name})" )
+#        }
+#        f.print( " )\n" )
+
+      }
+
+      if p.get_array_size then
+        f.print " *       subscript:  0...(NCP_#{p.get_name}-1)\n"
+      end
+
+      if p.is_ref_desc? then
+        subsc = p.get_array_size ? ' int_t subscript ' : ''
+        f.print " *   [ref_desc]\n"
+        f.printf( " *      %-14s %s;\n",
+                  "Descriptor( #{p.get_signature.get_global_name} )", 
+                  "#{p.get_name}_refer_to_descriptor(#{subsc})" )
+        f.printf( " *      %-14s %s;\n",
+                  "Descriptor( #{p.get_signature.get_global_name} )", 
+                  "#{p.get_name}_ref_desc(#{subsc})      (same as above; abbreviated version)" )
+      end
+      if p.is_dynamic? then
+        subsc = p.get_array_size ? 'int_t subscript, ' : ''
+        subsc2 = p.get_array_size ? ' int_t subscript' : ''
+        if p.is_optional? then
+          f.print " *   [dynamic, optional]\n"
+        else
+          f.print " *   [dynamic]\n"
+        end
+        f.printf( " *      %-14s %s;\n",
+                  "void",
+                  "#{p.get_name}_set_descriptor( #{subsc}Descriptor( #{p.get_signature.get_global_name} ) desc )" )
+        if p.is_optional? then
+          f.printf( " *      %-14s %s;\n",
+                    "void",
+                    "#{p.get_name}_unjoin( #{subsc2} )" )
+        end
+      end
+    }
+
+  end
+
+  def gen_template_ep_fun( f, b_inline = false )
+
+    if @n_entry_port >0 then
+      f.printf( TECSMsg.get( :TEPF_comment ), "#_TEPF_#" )
+    end
+
+    @port.each { |p|
+      next if p.get_port_type != :ENTRY
+      next if p.is_omit?
+      next if b_inline && ! p.is_inline?  # inline ポート
+      next if ! b_inline && p.is_inline?  # 非 inline ポート
+
+      inline_prefix = ""
+      nCELLIDX = "CELLIDX"
+      nCELLCB = "CELLCB"
+      nVALID_IDX = "VALID_IDX"
+      nGET_CELLCB = "GET_CELLCB"
+
+      f.print <<EOT
+/* #[<ENTRY_PORT>]# #{p.get_name}
+ * entry port: #{p.get_name}
+ * signature:  #{p.get_signature.get_global_name}
+ * context:    #{p.get_signature.get_context}
+EOT
+
+      if p.get_array_size != nil then
+        f.print <<EOT
+ * entry port array size:  NEP_#{p.get_name}
+EOT
+      end
+
+      f.print <<EOT
+ * #[</ENTRY_PORT>]# */
+
+EOT
+
+      p.get_signature.get_function_head_array.each{ |fun|
+        f.print <<EOT
+/* #[<ENTRY_FUNC>]# #{p.get_name}_#{fun.get_name}
+ * name:         #{p.get_name}_#{fun.get_name}
+ * global_name:  #{@global_name}_#{p.get_name}_#{fun.get_name}
+ * oneway:       #{fun.is_oneway?}
+ * #[</ENTRY_FUNC>]# */
+EOT
+
+        if b_inline then
+          f.print "Inline "
+        end
+        functype = fun.get_declarator.get_type
+        f.printf "%s\n", functype.get_type_str
+        f.print "#{inline_prefix}#{p.get_name}_#{fun.get_name}("
+        if @singleton then
+          delim = ""
+        else
+          f.print "#{nCELLIDX} idx"
+          delim = ", "
+        end
+
+        if p.get_array_size then
+          f.print "#{delim}int_t subscript"
+          delim = ", "
+        end
+
+        if functype.get_paramlist then
+          items = functype.get_paramlist.get_items
+          len = items.length
+        else
+          # ここで nil になるのは、引数なしの時に void がなかった場合
+          items = []
+          len = 0
+        end
+
+        i = 0
+        items.each{ |param|
+          f.print "#{delim}"
+          delim = ", "
+          f.print param.get_type.get_type_str
+          # p "type_str2: #{param.get_type.get_type_str}"
+          f.print " "
+          f.print param.get_name
+          f.print param.get_type.get_type_str_post
+          i += 1
+        }
+        f.print ")\n"
+
+        f.print "{\n"
+
+        if ( @plugin && @plugin.gen_ep_func? ) then
+          # このメソッドの引数は plugin.rb の説明を見よ
+          @plugin.gen_ep_func_body( f, @singleton, @name, @global_name, p.get_signature.get_global_name, p.get_name, fun.get_name, "#{@global_name}_#{p.get_name}_#{fun.get_name}", functype, items )
+
+        else
+          if ! @singleton then
+            if functype.get_type.kind_of?( DefinedType ) && ( functype.get_type.get_type_str == "ER" || functype.get_type.get_type_str == "ER_UINT" ) then
+              if ! fun.is_oneway? then
+                f.print "	ER\t\tercd = E_OK;\n"
+                er_cd = "return(E_ID);"
+                ret_cd = "return(ercd);"
+              else
+                er_cd = "#{TECSMsg.get(:oneway_ercd_note)}\n		return(E_OK);"
+                ret_cd = "#{TECSMsg.get(:oneway_ercd_note)}\n	return(E_OK);"
+              end
+            else
+              er_cd = "#{TECSMsg.get(:ercd_note)}"
+              ret_cd = nil
+            end
+            f.print <<EOT
+	#{nCELLCB}	*p_cellcb;
+	if (#{nVALID_IDX}(idx)) {
+		p_cellcb = #{nGET_CELLCB}(idx);
+	}
+	else {
+		#{er_cd}
+	} /* end if #{nVALID_IDX}(idx) */
+
+EOT
+            f.printf( TECSMsg.get( :TEFB_comment ), "#_TEFB_#" )
+            f.printf( "\n" )
+
+            if ret_cd then
+              f.print "	#{ret_cd}\n"
+            end
+          else
+          end # ! @singleton
+        end # @plugin
+
+        f.print "}\n\n"
+      }
+    }
+  end
+
+  def generate_inline_template_code
+    return if @n_entry_port_inline == 0
+    return if @b_reuse && ! $generate_all_template
+    if ! ( @plugin && @plugin.gen_ep_func? ) then
+      return if @b_reuse && ! $generate_all_template
+      return if $generate_no_template     # $generate_all_template より優先される
+
+      # 参考として出力するテンプレートファイルであることを示すために "_templ" を付加する
+      fname = "#{$gen}/#{@global_name}_inline_templ.#{$h_suffix}"
+    else
+      # Plugin により生成されたセルタイプについては、原則的にテンプレートではなく、
+      # 修正不要なセルタイプの実装コードを生成する．
+      # このため、ファイル名に _temp を付加しない
+      fname = "#{$gen}/#{@global_name}_inline.#{$h_suffix}"
+    end
+    f = AppFile.open(fname)
+
+    gen_ph_guard f, "_INLINE"
+
+    unless ( @plugin && @plugin.gen_ep_func? ) then
+      f.printf( TECSMsg.get( :inline_template_note ), @name, @name )
+    else
+      print_note( f, true )
+    end
+
+    f.print TECSMsg.get( :preamble_note )
+    gen_template_attr_access f
+    gen_template_cp_fun f
+    f.print( " *\n * #[</PREAMBLE>]# */\n\n" )
+
+    gen_template_ep_fun( f, true )
+
+    f.print TECSMsg.get( :postamble_note )
+
+    if ( @plugin ) then
+      # このメソッドの引数は plugin.rb の説明を見よ
+      @plugin.gen_postamble( f, @singleton, @name, @global_name )
+    end
+
+    f.print "\n"
+    gen_ph_endif f, "INLINE"
+    f.close
+  end
+
+
+##### generate tecsgen.cfg
+
+  def generate_celltype_factory_code
+
+    @ct_factory_list.each { |fa|
+      if fa.get_name == :write then
+
+        # 前後の " を取り除く
+        # file_name = fa.get_file_name.sub( /^\"(.*)\"$/, "\\1" )
+        file_name = CDLString.remove_dquote fa.get_file_name
+        format = CDLString.remove_dquote fa.get_format
+        # format    = fa.get_format.sub( /^\"(.*)/, "\\1" )        # 前の " を取り除く
+        # format    = format.sub( /(.*)\"\z/, "\\1" )              # 後の " を取り除く
+        format    = format.gsub( /\\\n/, "\n" )                  # \\\n => \n
+
+
+        # mikan 以下は subst_name で置換するように変更すべき
+        file_name = file_name.gsub( /(^|[^\$])\$ct\$/, "\\1#{@name}" )   # $ct$ をセルタイプ名に置換
+        file_name = file_name.gsub( /(^|[^\$])\$ct_global\$/, "\\1#{@global_name}" )   # $ct$ をセルタイプ名に置換
+        format    = format.gsub( /(^|[^\$])\$ct\$/, "\\1#{@name}" )   # $ct$ をセルタイプ名に置換
+        format    = format.gsub( /(^|[^\$])\$ct_global\$/, "\\1#{@global_name}" )   # $ct$ をセルタイプ名に置換
+        format    = format.gsub( /\$\$/, "\$" )                # $$ を $ に置換
+
+        if file_name[0] != ?/ then
+          file_name = "#{$gen}/#{file_name}"
+        end
+
+        begin
+          cfg_file = AppFile.open( file_name )
+          if $debug then
+            print "'#{@name}' : celltype factory format: "
+            puts( format )
+          end
+          # format 中の \n, \r, \t, \f と \" などを置換
+          fmt = CDLString.escape format
+          cfg_file.print( fmt )
+          cfg_file.puts( "\n" )
+          cfg_file.close()
+        rescue => evar
+          cdl_error( "H1004 \'$1\' : write error while writing factory (specify -t to get more info)" , file_name )
+          print_exception( evar )
+        end
+      end
+    }
+  end
+
+  def generate_cell_factory_code
+
+    @ordered_cell_list.each{ |c|
+
+      # cell のプロトタイプ宣言なら無視
+      next if ! c.is_generate?
+
+      name_array = get_name_array( c )
+
+      @factory_list.each { |fa|
+
+        if fa.get_name == :write then
+
+          # 前後の " を取り除く
+          # file_name = fa.get_file_name.sub( /^\"(.*)\"$/, "\\1" )
+          file_name = CDLString.remove_dquote fa.get_file_name
+          file_name = subst_name( file_name, name_array )
+          # format    = fa.get_format.sub( /^\"(.*)\"$/, "\\1" )        # 前後の "" を取り除く
+          format    = CDLString.remove_dquote fa.get_format
+          # format    = fa.get_format.sub( /^\"(.*)/, "\\1" )        # 前の " を取り除く
+          # format    = format.sub( /(.*)\"\z/, "\\1" )              # 後の " を取り除く
+          format    = format.gsub( /\\\n/, "\n" )                  # \\\n => \n
+
+          format    = subst_name( format, name_array )
+
+          arg_list  = fa.get_arg_list
+
+          if file_name[0] != ?/ then
+            file_name = "#{$gen}/#{file_name}"
+          end
+
+          na = []     # シンボルを attribute の値に置き換えた後の引数
+          if arg_list then
+            arg_list.each { |a|
+              case a[0]
+              when :STRING_LITERAL   # 文字列定数
+                # s = a[1].sub( /^\"(.*)\"$/, "\\1" )            # 前後の "" を取り除く
+                s = CDLString.remove_dquote a[1]
+                s = subst_name( s, name_array )
+                # s = subst_name( a[1], name_array )
+
+                na << s
+              when :IDENTIFIER
+                param_name = a[1]    # 識別子（属性の名前）
+                attr = self.find( param_name )
+                init = attr.get_initializer      # celltype で指定された初期値
+
+                # cell の join のリストから名前を探す
+                j = c.get_join_list.get_item( param_name )
+                if j then    # param_name の cell のジョインがあるか
+                  init = j.get_rhs                    # cell で指定された初期値を優先
+                end
+
+                str = gen_cell_cb_init( nil, c,    name_array, attr.get_type, init, attr.get_identifier, 0,   true )
+                                      # file,cell, name_array, type,          init, identifier,       indent, f_get_str
+
+                # str = str.sub( /^\"(.*)\"$/, "\\1" )            # 前後の "" を取り除く mikan ここで置換でよい？
+                str = CDLString.remove_dquote str
+                na << str
+              end
+            }
+          end
+
+          begin
+            cfg_file = AppFile.open( file_name )
+
+            if $debug then
+              print "'#{c.get_name}' : factory format: "
+              print( format )
+              print( " arg: " )
+              na.each { |n| print "'#{n}' " }
+              print( "\n" )
+            end
+
+            # format 中の \n, \r, \t, \f と \" などを置換
+            fmt = CDLString.escape format
+            cfg_file.printf( fmt, *na )
+            cfg_file.puts( "\n" )
+            cfg_file.close()
+          rescue => evar
+            cdl_error( "H1005 \'$1\' : write error while writing factory (specify -t to get more info)" , file_name )
+            print_exception( evar )
+          end
+        end
+      }
+    }
+
+  end
+
+  def generate_makefile
+    generate_makefile_template
+    generate_makefile_depend
+  end
+
+  def generate_makefile_template
+
+    return if $generate_no_template
+
+    # Makefile.templ の生成（追記）
+
+    f = AppFile.open( "#{$gen}/Makefile.templ" )
+    f.print <<EOT
+$(_TECS_OBJ_DIR)#{@global_name}.o : #{@global_name}.#{$c_suffix}
+	$(CC) -c $(CFLAGS) -o $@ $<
+ 
+EOT
+# この生成規則は2点で意味がない
+#  ・$(GEN_DIR) に .o を生成するルールがない
+#  ・テンプレートコードをそのままビルドするのは紛らわしい
+# # Celltype: #{@name}
+# $(GEN_DIR)/#{@global_name}_tecsgen.o : $(GEN_DIR)/#{@global_name}_tecsgen.#{$c_suffix}
+# 	$(CC) -c $(CFLAGS) -o $@ $<
+# 
+# $(GEN_DIR)/#{@global_name}_templ.o : $(GEN_DIR)/#{@global_name}_templ.#{$c_suffix}
+# 	$(CC) -c $(CFLAGS) -o $@ $<
+# 
+
+    f.close
+
+  end
+
+  def generate_makefile_depend
+
+    headers = [ "$(GEN_DIR)/#{@global_name}_tecsgen.#{$h_suffix}", "$(GEN_DIR)/#{@global_name}_factory.#{$h_suffix}", "$(GEN_DIR)/global_tecsgen.#{$h_suffix}" ]
+
+    # inline 受け口を持つか？
+    if @n_entry_port_inline > 0 then
+      headers << "#{@global_name}_inline.#{$h_suffix}"
+    end
+
+    # 呼び口または受け口のシグニチャのヘッダ
+    @port.each { |p|
+      next if p.is_omit?
+      headers << "$(GEN_DIR)/#{p.get_signature.get_global_name}_tecsgen.#{$h_suffix}"
+    }
+
+    headers += get_depend_header_list
+    headers.sort!
+    headers.uniq!
+    headers = headers.join " "
+
+    f = AppFile.open( "#{$gen}/Makefile.depend" )
+
+#    print_Makefile_note f
+
+    f.print <<EOT
+# Celltype: #{@name}  #_MDEP_#
+$(_TECS_OBJ_DIR)#{@global_name}_tecsgen.o : #{@global_name}_tecsgen.#{$c_suffix} #{headers}
+$(_TECS_OBJ_DIR)#{@global_name}_templ.o : #{@global_name}_templ.#{$c_suffix} #{headers}
+$(_TECS_OBJ_DIR)#{@global_name}.o : #{@global_name}.#{$c_suffix} #{headers}
+
+EOT
+    f.close
+  end
+
+  #=== decl 用の dealloc コードを生成
+  #b_reset:: Bool:  リセット用の dealloc コードの生成 (NULL ポインタの場合 dealloc しない)
+  # mikan string 修飾されたポインタの先にポインタが来ないと仮定。ポインタ型を持つ構造体の可能性を排除していない
+  # このメソッドでは、行を出力する直前に " \\\n" を出力し、行末で改行文字を出力しない
+  def gen_dealloc_code_for_type( f, type, dealloc_func_name, pre, name, post, level, b_reset, count_str = nil )
+    type = type.get_original_type
+    indent = "	" + "  " * (level+1)
+    if ! type.has_pointer?
+      return
+    elsif type.kind_of?( ArrayType ) then
+      if type.get_type.has_pointer?
+        loop_str = "i#{level}__"
+        count_str = "#{type.get_subscript.eval_const(nil)}"
+        f.print " \\\n"
+        f.print "#{indent}{ int_t  #{loop_str};"
+        f.print " \\\n"
+        f.print "#{indent}  for( #{loop_str} = 0; #{loop_str} < #{count_str}; #{loop_str}++ ){ "
+        
+        gen_dealloc_code_for_type( f, type.get_type, dealloc_func_name, pre, name, "#{post}[#{loop_str}]", level+2, b_reset )
+
+        f.print " \\\n"
+        f.print "#{indent}  }"
+        f.print " \\\n"
+        f.print "#{indent}}"
+      end
+    elsif type.kind_of?( StructType ) then
+      members_decl = type.get_members_decl
+      members_decl.get_items.each { |md|
+        pre2 = pre + name.to_s + post + "."
+        name2 = md.get_name
+        post2 = ""
+        type2 = md.get_type.get_original_type
+        if type2.kind_of? PtrType then   # mikan typedef された型
+          if type2.get_count then
+            count_str = type2.get_count.to_str( members_decl, pre2, post2 )
+          elsif type2.get_size then
+            count_str = type2.get_size.to_str( members_decl, pre2, post2 )
+          else
+            count_str = nil
+          end
+        else
+            count_str = nil
+        end
+        gen_dealloc_code_for_type( f, md.get_type, dealloc_func_name, pre2, name2, post2, level, b_reset, count_str )
+      }
+
+    elsif type.kind_of?( PtrType ) then
+
+      if b_reset || type.is_nullable? then
+        nullable = ""
+        if( !b_reset && type.is_nullable? )then
+          nullable = "\t/* nullable */"
+        end
+        level2 = level + 1
+        indent2 = indent + "  "
+        f.print " \\\n"
+        f.print "#{indent}if( #{pre}#{name}#{post} ){#{nullable}"
+      else
+        level2 = level
+        indent2 = indent
+      end
+
+      if type.get_type.has_pointer?
+        if count_str then
+          loop_str = "i#{level}__"
+          f.print " \\\n"
+          f.print "#{indent2}{ int_t  #{loop_str};"
+          f.print " \\\n"
+          f.print "#{indent2}  for( #{loop_str} = 0; #{loop_str} < #{count_str}; #{loop_str}++ ){ "
+
+          gen_dealloc_code_for_type( f, type.get_type, dealloc_func_name, pre, name, "#{post}[#{loop_str}]", level2+2, b_reset )
+
+          f.print " \\\n"
+          f.print "#{indent2}  }"
+          f.print " \\\n"
+          f.print "#{indent2}}"
+        else
+          gen_dealloc_code_for_type( f, type.get_type, dealloc_func_name, "(*#{pre}", name, "#{post})", level2, b_reset )
+        end
+      end
+      f.print " \\\n"
+      f.print "#{indent2}#{dealloc_func_name}( #{pre}#{name}#{post} ); "
+
+      if b_reset || type.is_nullable? then
+        f.print " \\\n"
+        f.print "#{indent}}"
+      end
+    else
+      raise "UnknownType"
+    end
+  end
+
+  def get_depend_header_list
+    get_depend_header_list_( [] )
+  end
+
+  def get_depend_header_list_( celltype_list )
+    headers = []
+
+    if celltype_list.include? self then
+      return headers
+    else
+      celltype_list << self
+    end
+
+    # 呼び口の結合先のセルタイプのヘッダ（最適化の場合のみ）
+    # 結合先の受け口が inline の場合、inline ヘッダも
+    @port.each { |p|
+      next if p.get_port_type != :CALL
+      next if p.is_omit?
+
+      if p.is_skelton_useless? || p.is_cell_unique? || p.is_VMT_useless? then
+        # 最適化コード (optimize) # スケルトン不要など
+        p2 = p.get_real_callee_port
+        if p2 then
+          ct = p2.get_celltype
+          headers << " $(GEN_DIR)/#{ct.get_global_name}_tecsgen.#{$h_suffix}"
+          if p2.is_inline? then
+            headers << " #{ct.get_global_name}_inline.#{$h_suffix}"
+          end
+          headers += ct.get_depend_header_list_( celltype_list )
+        #else
+        #  optional で未結合  
+        end
+      end
+    }
+    return headers
+  end
+
+
+  #=== $id$, $ct$, $cb$, $idx$ 置換
+  #
+  #  str に以下の置換を行う
+  #-   $ct$ ⇒ セルタイプ名(ct)
+  #-   $cell$ ⇒ セル名(cell)   cell が nil ならば以下の置換は行われない
+  #-   $cb$ ⇒ CB の C 言語名(cb)
+  #-   $cbp$ ⇒ CB へのポインタ(cbp)
+  #-   $cb_proto$ ⇒ CB の C 言語名プロトタイプ宣言用(cb_proto)
+  #-   $id$ ⇒ $ct$_$cell_global$    # ct_cell  before or same V1.5.2
+  #-   $idx$ ⇒ idx
+  #-   $ID$ ⇒ id (整数の番号)
+  #-   $ct_global$ ⇒ セルタイプ名(ct)
+  #-   $cell_global$ ⇒ セル名(cell)
+  #-   $$   ⇒ $
+  def subst_name( str, name_array )
+    ct   = name_array[0]    # celltype name
+    cell = name_array[1]    # cell name
+    cb   = name_array[2]    # cell CB name
+    cb_init = name_array[3] # cell CB INIT, これは置換に使われない
+    cb_proto = name_array[4] # cell CB name for prototype
+    id   = name_array[6]    # cell ID
+    idx  = name_array[7]    # cell CB name for prototype
+    cbp  = name_array[8]    # cell CB pointer
+    ct_global = name_array[9]    # cell CB pointer
+    cell_global  = name_array[10]    # cell CB pointer
+
+    str = str.gsub( /(^|[^\$])\$ct\$/, "\\1#{ct}" )
+    str = str.gsub( /(^|[^\$])\$ct_global\$/, "\\1#{ct_global}" )
+    if cell then
+      str = str.gsub( /(^|[^\$])\$cell\$/, "\\1#{cell}" )
+      str = str.gsub( /(^|[^\$])\$cb\$/, "\\1#{cb}" )
+      # str = str.gsub( /(^|[^\$])\$id\$/, "\\1#{ct}_#{cell}" )
+      str = str.gsub( /(^|[^\$])\$id\$/, "\\1#{ct}_#{cell_global}" )
+      str = str.gsub( /(^|[^\$])\$cb_proto\$/, "\\1#{cb_proto}" )
+      str = str.gsub( /(^|[^\$])\$ID\$/, "\\1#{id}" )
+      str = str.gsub( /(^|[^\$])\$idx\$/, "\\1#{idx}" )
+      str = str.gsub( /(^|[^\$])\$cbp\$/, "\\1#{cbp}" )
+      str = str.gsub( /(^|[^\$])\$cell_global\$/, "\\1#{cell_global}" )
+    end
+    str = str.gsub( /\$\$/, "\$" )                       # $$ を $ に置換
+
+    return str
+  end
+
+end
+
+# Appendable File（追記可能ファイル）
+class AppFile
+  # 開いたファイルのリスト
+  @@file_name_list = {}
+
+  def self.open( name )
+    if $force_overwrite
+      real_name = name
+    else
+      real_name = name+".tmp"
+    end
+
+#2.0
+    if $b_no_kcode then 
+      mode = ":" + $Ruby19_File_Encode
+    else
+      mode = ""
+    end
+
+    # 既に開いているか？
+    if @@file_name_list[ name ] then
+#2.0
+      mode = "a" + mode
+      # 追記モードで開く
+      file = File.open( real_name, mode )
+    else
+#2.0
+      mode = "w" + mode
+      # 新規モードで開く（既にあれば、サイズを０にする）
+      file = File.open( real_name, mode )
+      @@file_name_list[ name ] = true
+    end
+    # File クラスのオブジェクトを返す
+    return file
+  end
+
+  def self.update
+    if $force_overwrite
+      return
+    end
+
+    @@file_name_list.each{ |name,boo|
+      b_identical = false
+      if File.readable? name
+        old_lines = File.readlines name
+        new_lines = File.readlines name + ".tmp"
+        if old_lines.length == new_lines.length then
+          i = 0
+          len = old_lines.length
+          while i < len
+            if old_lines[i] != new_lines[i]
+              break
+            end
+            i += 1
+          end
+          if i == len
+            b_identical = true
+          end
+        end
+      end
+      if b_identical == false then
+        if $verbose then
+          print "#{name} updated\n"
+          print "renaming '#{name}.tmp' => '#{name}'\n"
+        end
+        File.rename name+".tmp", name
+      else
+        if $verbose then
+          print "#{name} not updated\n"
+        end
+        File.delete name+".tmp"
+      end
+    }
+  end
+end
+
+class MemFile
+  def initialize
+    @string = ""
+  end
+  def print str
+    @string += str
+  end
+  def get_string
+    @string
+  end
+end
+
+class Region
+
+  def gen_region_str_pre f
+    nest = 1
+    while nest < @family_line.length
+      f.print "  " * ( nest-1 )
+      f.print "region #{@family_line[ nest ].get_name}{\n"
+      nest += 1
+    end
+    return nest - 1
+  end
+
+  def gen_region_str_post f
+    nest = @family_line.length - 1
+    while nest >= 1
+      f.print "  " * ( nest-1 )
+      f.print "};\n"
+      nest -= 1
+    end
+    return nest - 1
+  end
+end
+
+class DomainType < Node
+  def gen_factory
+    # p "DomainType: gen_factory"
+    @plugin.gen_factory
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/location.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/location.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/location.rb	(revision 398)
@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+class TECSGEN
+
+  #------ manupulate location information --------#
+  def self.new_cell_location cell_location
+    @@current_tecsgen.new_cell_location cell_location
+  end
+  def new_cell_location cell_location
+    @cell_location_list << cell_location
+  end
+  def get_cell_location_list
+    @cell_location_list
+  end
+
+  def self.new_join_location join_location
+    @@current_tecsgen.new_join_location join_location
+  end
+  def new_join_location join_location
+    @join_location_list << join_location
+  end
+  def get_join_location_list
+    @join_location_list
+  end
+
+#==  Cell_location
+  # tecscde の位置情報
+  class  Cell_location
+
+    #=== Join_location#initialize
+    #cell_nspath::NamespacePath
+    #x,y,w,h::Expression
+    #port_location_list::[ [Symbol(ep_or_cp_name), Symbol(edge_name), Expression(offset)], ... ]
+    #ep_name::Symbol
+    def initialize( cell_nspath, x, y, w, h, port_location_list )
+      # p "Cell_location: #{cell_nspath}, #{x}, #{y}, #{w}, #{h}, #{port_location_list}"
+      @cell_nspath = cell_nspath
+      @x = x.eval_const nil
+      @y = y.eval_const nil
+      @w = w.eval_const nil
+      @h = h.eval_const nil
+      @port_location_list = port_location_list
+
+      TECSGEN.new_cell_location self
+    end
+
+    def get_location
+      [ @cell_nspath, @x, @y, @w, @h, @port_location_list ]
+    end
+
+  end # Cell_location
+
+  #==  Join_location
+  # tecscde の位置情報
+  class  Join_location
+    @@join_location_list = []
+
+    #=== Join_location#initialize
+    #cp_cell_nspath::NamespacePath
+    #cp_name::Symbol
+    #ep_cell_nspath::NamespacePath
+    #ep_name::Symbol
+    #bar_list::[[Symbol (VBar or HBar), Expression(position mm)], ....]
+    def initialize( cp_cell_nspath, cp_name, ep_cell_path, ep_name, bar_list )
+      # p "Join_location  #{cp_cell_nspath}, #{cp_name}, #{ep_cell_path}, #{ep_name} #{bar_list}"
+      @cp_cell_nspath = cp_cell_nspath
+      @cp_name = cp_name
+      @ep_cell_path = ep_cell_path
+      @ep_name = ep_name
+      @bar_list = bar_list
+
+      TECSGEN.new_join_location self
+    end
+
+    def get_location
+      [@cp_cell_nspath, @cp_name, @ep_cell_path, @ep_name, @bar_list]
+    end
+
+  end # Join_location
+
+end # TECSGEN
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/messages.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/messages.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/messages.rb	(revision 398)
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== TECS の生成する各国語化必要な文字列
+# 現状、エラーメッセージは英語のみ
+# 生成ファイルのコメントとして出力される文字列
+class TECSMsg
+
+  #=== TECSMsg#生成するヘッダやテンプレートなどに含めるコメントの取得
+  # CDL の文字コードに合わせて、文字コード変換を行う
+  def self.get( msg )
+    str = @@comment[ msg ]
+#2.0    if $KCONV_TECSGEN == $KCONV_CDL
+    if $KCONV_TECSGEN == $KCONV_CDL || $KCONV_CDL == Kconv::BINARY then
+      return str
+    else
+      return str.kconv( $KCONV_CDL, $KCONV_TECSGEN )
+    end
+  end
+
+ #=== TECSMsg#ローカライズされたエラーメッセージを得る
+ #body::String   : "S0001 error message body"  の形式
+ # S0001 の部分が使用される
+ # Generator.error2 から呼び出される
+ def self.get_error_message( body )
+   body =~ /^[A-Z0-9]+/    # エラー番号を取り出す
+   num = $&
+   if num then
+     msg = @@error_message[ num.to_sym ]
+   else
+     msg = nil
+   end
+   if msg == nil then
+     m = body
+   else
+     m = num + " " + msg
+   end
+   return m
+ end
+
+ #=== TECSMsg#ローカライズされたウォーニングメッセージを得る
+ # Generator.warning2 から呼び出される
+ def self.get_warning_message( body )
+   body =~ /^[A-Z0-9]+/    # ウォーニング番号を取り出す
+   num = $&
+   msg = @@warning_message[ num.to_sym ]
+   if msg == nil then
+     m = body
+   else
+     m = num + " " + msg
+   end
+   return m
+ end
+
+ #=== TECSMsg#ローカライズされた情報メッセージを得る
+ # Generator.info2 から呼び出される
+ def self.get_info_message( body )
+   body =~ /^[A-Z0-9]+/    # 情報番号を取り出す
+   num = $&
+   msg = @@info_message[ num.to_sym ]
+   if msg == nil then
+     m = body
+   else
+     m = num + " " + msg
+   end
+   return m
+ end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/optimize.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/optimize.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/optimize.rb	(revision 398)
@@ -0,0 +1,466 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+=begin
+This file includes the processes between semantics analysis and code generation.
+Optimize is one of them.
+Other processes are setting ID for each cell and setting domain information
+
+このファイルには、意味解析からコード生成の間で行うべき処理が含まれる．
+最適化もその一つである．
+その他に、セル毎の ID 付け、ドメインわけを行う．
+コード生成対象となるセルを対象に処理を行うものが含まれる．
+=end
+
+class Namespace
+
+  #===  各セルに ID （整数値）を割付ける
+  def set_cell_id_and_domain
+    # celltype の各セルに ID を割付ける
+    @celltype_list.each { |t|
+      t.set_cell_id_and_domain
+    }
+
+    # サブネームスペースの各セルに ID を割付ける
+    @namespace_list.each { |n|
+      n.set_cell_id_and_domain
+    }
+  end
+
+  def optimize
+    # celltype の最適化
+    @celltype_list.each { |t|
+      t.optimize
+    }
+
+    # サブネームスペースの最適化
+    @namespace_list.each { |n|
+      n.optimize
+    }
+  end
+
+  def reset_optimize
+    # celltype の最適化
+    @celltype_list.each { |t|
+      t.reset_optimize
+    }
+
+    # サブネームスペースの最適化
+    @namespace_list.each { |n|
+      n.reset_optimize
+    }
+  end
+end
+
+class Celltype
+
+  ID_BASE = 1               # reset_optimize でリセットする
+  @@ID_BASE = ID_BASE
+
+  def set_cell_id_and_domain
+    set_cell_id
+    set_domain
+  end
+
+  #=== 各セルに ID （整数値）を割付ける
+  def set_cell_id
+
+    if $verbose then
+      print( "=== id for the cells of celltype #{get_namespace_path.to_s} ===\n" ) 
+    end
+
+    if $unique_id then
+      @id_base = @@ID_BASE   # id をシステム全体で連番にする
+    else
+      @id_base = 1           # base を常に 1 から始める
+    end
+
+    id_specified_cells = []
+    no_id_specified_cells = []
+
+    # プロトタイプを除いた数を求める
+    @cell_list.each{ |c|
+      if c.is_generate? then
+        # c.set_id( @id_base + @n_cell_gen )
+        id = c.get_specified_id
+        if id then
+          id_specified_cells << c
+        else
+          no_id_specified_cells << c
+        end
+        
+        # p "#{c.get_name} #{@id_base+@n_cell_gen}"
+        @@ID_BASE     += 1
+        @n_cell_gen   += 1
+      end
+    }
+
+    @ordered_cell_list = []   # id = 1 が添数 0 に格納される
+    # ID 指定されているセルに id 番号を与える
+    id_specified_cells.each{ |c|
+      id = c.get_specified_id
+      if id > 0 then
+        if id >= @n_cell_gen then
+          cdl_error( "S3001 $1: id too large $2 (max=$3)", c.get_name, id, @n_cell_gen )
+          next
+        end
+      else
+        if - id >= @n_cell_gen then
+          cdl_error( "S3002 $1: id too large $2 (max=$3)", c.get_name, id, @n_cell_gen )
+          next
+        end
+        id = @n_cell_gen + id + 1
+      end
+
+      if @ordered_cell_list[ id - 1 ] then
+        cdl_error( "S3003 $1: id number '$2' conflict with $3", c.get_name, id, @ordered_cell_list[ id - 1 ].get_name )
+      end
+      @ordered_cell_list[ id - 1 ] = c
+      # 通し番号とする場合のため @id_base を加える
+      c.set_id( @id_base - 1 + id )
+      if $verbose then
+        print( "#{c.get_name}: id=#{c.get_id}  specified id=#{c.get_specified_id}\n" )
+      end
+    }
+
+    # ID 指定されていないセルに id 番号を与える
+    i = 0
+    no_id_specified_cells.each{ |c|
+      while( @ordered_cell_list[i] != nil )
+        i += 1
+      end
+      @ordered_cell_list[ i ] = c
+      c.set_id( @id_base + i )
+      if $verbose then
+        print( "#{c.get_name}: id=#{c.get_id}\n" )
+      end
+    }
+    if @n_cell_gen >0 && i >= @n_cell_gen then
+      raise "id over id=#{i} N=#{@n_cell_gen}"
+    end
+  end
+
+  def set_domain
+    domain_cells = {}
+    @cell_list.each{ |c|
+      if c.is_generate? then
+        dr = c.get_region.get_domain_root
+        if dr.get_domain_type then
+          dn = dr.get_domain_type.get_name
+        else
+          dn = nil
+        end
+        if @domain_roots[ dn ] then
+          @domain_roots[ dn ] << dr
+        else
+          @domain_roots[ dn ] = [ dr ]
+        end
+        if domain_cells[ dr ]  then
+          domain_cells[ dr ] << c
+        else
+          domain_cells[ dr ] = [ c ]
+        end
+      end
+    }
+
+    @domain_roots.each{ |dn, drs|
+      drs.uniq!
+      if $verbose && dn then
+        print "[domain] celltype=#{@name} domainType=#{dn} domainRootRegions={"
+        delim = ""
+        drs.each{ |r|
+          print delim, r.get_name
+          delim = ", "
+        }
+        print "}\n"
+        drs.each{ |r|
+          print "[domain] celltype=#{@name} domainRootRegion=#{r.get_name} domainType=#{dn} domainKind=#{r.get_domain_root.get_domain_type.get_kind} domainCells={"
+          delim = ""
+          domain_cells[r].each{ |c|
+            print delim, c.get_name
+            delim = ", "
+          }
+          print "}\n"
+        }
+      end
+    }
+    if @domain_roots.length > 1 then
+      p @domain_roots
+      raise "ambigous DomainType"
+    end
+
+    @domain_roots.each{ |dn, regions|
+      # domain_type は一つのノードに一つしかないので、一つの要素を無条件で取り出す
+      if regions.length > 1 then
+        if $verbose then
+          cdl_info( "I9999 celltype '$1' has cells in multi-domain.\n", @name )
+        end
+        # if @idx_is_id == false then
+        #   cdl_info( "I9999 celltype '$1' forcely set idx_is_id\n", @name )
+        # end
+        @b_need_ptab = true
+        # @idx_is_id_act = true
+      end
+    }
+  end
+
+  def optimize
+
+    # port の参照するセルタイプの数、セルの数を求める
+    if $verbose then
+      print "=== optimizing celltype #{get_namespace_path.to_s} ===\n"
+    end
+
+    optimize_call
+    if $unopt_entry == false then
+      optimize_entry
+    end
+  end
+
+  #=== Celltype#呼び口最適化
+  def optimize_call
+    @port.each{ |port|
+      next if port.get_port_type != :CALL
+      if port.is_omit? then
+        # 呼び口最適化実施
+        @b_cp_optimized = true
+        @n_call_port_omitted_in_CB += 1               # CB で省略する呼び口
+        port.set_skelton_useless                      # スケルトン関数不要最適化
+        port.set_VMT_useless                          # VMT 不要最適化 (直接受け口関数を呼出す)
+        if $verbose then
+          print "optimized by omit: port: #{port.get_name} : o\n"
+        end
+        next
+      elsif port.is_dynamic? then
+        if $verbose then
+          print "unoptimized by dynamic: port: #{port.get_name}\n"
+        end
+        next
+      elsif port.is_ref_desc? then
+        if $verbose then
+          print "unoptimized by ref_desc: port: #{port.get_name}\n"
+        end
+        next
+      end
+
+      if $verbose then
+        print "optimizing port : #{port.get_name}\n"
+      end
+
+      port_cells = []    # 呼び先セル
+      port_ports = []    # 呼び先のポート
+
+      # セルの参照するセルを集める（ポートも一緒に集める）
+      @cell_list.each{ |cell|
+
+        if ! cell.is_generate? then
+          next
+        end
+
+        jl = cell.get_join_list
+        j = jl.get_item( port.get_name )
+
+        if j then
+          if j.get_array_member2 then
+            # 呼び口配列の場合、全部の結合先を集める
+            j.get_array_member2.each { |j2|
+              if j2 then
+                port_cells << j2.get_rhs_cell
+                port_ports << j2.get_rhs_port   # 右辺のポート
+              else
+                # optional で、ある添数のみ初期化されていない（すべて初期化されない場合は、下）
+                port_cells << nil
+                port_ports << nil
+              end
+            }
+          else
+            # 全ての結合先を集める
+            port_cells << j.get_rhs_cell
+            port_ports << j.get_rhs_port   # 右辺のポート
+          end
+        else
+          # optional で初期化されていない（nil を要素に加えておく）
+          port_cells << nil
+          port_ports << nil   # 右辺のポート
+        end
+      }
+
+      # 重複要素を取り除く
+      port_cells.uniq!
+      port_ports.uniq!
+
+      # 呼び口の呼び先が一つのポートだけか？
+      if port_ports.length == 1 then
+
+        # 呼び口配列が可変長の場合、最適化しない
+             # mikan 呼び口配列要素数マクロ不具合暫定対策
+             # より望ましい修正は、受け口へのポインタは省略するが、配列個数は出力する(#_CP_#, #_TCP_#)
+             # さらに配列個数が定数化できるのであれば、定数マクロを出力 (#_NCPA_#)
+        next if port.get_array_size == "[]"
+
+        # 呼び口最適化実施
+        @b_cp_optimized = true
+
+        # 呼び先が一つのセルだけか？
+        if port_cells.length == 1 then
+
+          # 呼び口は optional で初期化されていない、または受け口は配列ではないか？
+          if port_ports[0] == nil || port_ports[0].get_array_size == nil then
+
+            @n_call_port_omitted_in_CB += 1               # CB で省略する呼び口
+            port.set_cell_unique                          # セル一つだけ最適化
+            port.set_skelton_useless                      # スケルトン関数不要最適化
+            port.set_VMT_useless                          # VMT 不要最適化 (直接受け口関数を呼出す)
+
+            if $verbose then
+              print "cell_unique, VMT_useless & skelton_useless optimize\n"
+            end
+          else
+            port.set_VMT_useless                          # VMT 不要最適化 (スケルトン関数を呼出す)
+
+            if $verbose then
+              print "VMT_useless optimize\n"
+            end
+          end
+
+        else  # 呼び先が複数のセル（単一のポート）
+
+          # 呼び口は optional で初期化されていない、または受け口は配列ではないか？
+          if port_ports[0] == nil || port_ports[0].get_array_size == nil then
+            if ! @singleton then
+              port.set_skelton_useless                    # スケルトン関数不要最適化
+              port.set_VMT_useless                        # VMT 不要最適化 (スケルトン関数 or 受け口関数を呼出す)
+
+              if $verbose then
+                print "VMT_useless & skelton useless optimize\n"
+              end
+            else
+              port.set_VMT_useless                           # VMT 不要最適化 (スケルトン関数 or 受け口関数を呼出す)
+
+              if $verbose then
+                print "VMT_useless optimize\n"
+              end
+            end
+          end
+        end
+
+        port.set_only_callee( port_ports[0], port_cells[0] )
+           # set_cell_unique でない場合 cell は意味がない
+
+      end
+
+      # debug
+      dbgPrint "#{port.get_name} : # of cells : #{port_cells.length}  # of ports : #{port_ports.length}\n"
+    }
+  end
+
+  #=== Celltype#受け口最適化
+  # optimize_entry は、呼び口最適化の結果を使用している
+  def optimize_entry
+    # 受け口最適化の設定
+    @port.each{ |port|
+      next if port.get_port_type != :CALL
+
+      # 呼び口側の最適化状態
+      b_VMT_useless     = port.is_VMT_useless?
+      b_skelton_useless = port.is_skelton_useless?
+
+      # セルの参照するセルを集める（ポートも一緒に集める）
+      @cell_list.each{ |cell|
+
+        if ! cell.is_generate? then
+          next
+        end
+
+        jl = cell.get_join_list
+        j = jl.get_item( port.get_name )
+
+        if j then    # optional で結合されていない場合 nil
+          if j.get_array_member2 then
+            # 呼び口配列
+            j.get_array_member2.each { |j2|
+              if j2 then
+                port2 = j2.get_rhs_port   # 右辺のポート
+                # 受け口側の最適化可能性を設定
+                port2.set_entry_VMT_skelton_useless( b_VMT_useless, b_skelton_useless )
+              #else
+              #  optional で呼び口配列要素が初期化されていない
+              end
+            }
+          else
+            port2 = j.get_rhs_port      # 右辺のポート
+            # 受け口側の最適化可能性を設定
+            port2.set_entry_VMT_skelton_useless( b_VMT_useless, b_skelton_useless )
+          end
+        end
+      }
+    }
+  end
+
+  #Celltype# リセットする
+  def reset_optimize
+    @@ID_BASE = ID_BASE      # 本当は一回だけでよい
+    @id_base = 1             # set_cell_id でリセットされるので不要
+
+    @b_cp_optimized = false  # 呼び口最適化
+    @n_call_port_omitted_in_CB = 0 # 呼び口最適化により不生成となったポートの数
+    @n_cell_gen = 0          # 生成セル個数
+    @port.each{ |p|
+      p.reset_optimize
+    }
+    @included_header = {}
+    @domain_roots = {}
+  end
+
+  #Celltype# ヘッダは include されているか
+  #hname::Symbol : ヘッダ名
+  #RETURN:: bool_t: false インクルードされていない、true インクルードされている
+  # #_ISH_#, #_ICT_# でヘッダが取り込まれているかチェックする
+  # false が返った場合、hname は登録されて、次回の呼び出しでは true が返る
+  def header_included?( hname )
+    if @included_header[ hname ] == nil then
+      @included_header[ hname ] = true
+      return false
+    else
+      return true
+    end
+  end
+end
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/plugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/plugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/plugin.rb	(revision 398)
@@ -0,0 +1,337 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== Plugin クラス
+# ThroughPlugin, SignaturePlugin, CelltypePlugin に include する
+class Plugin < Node
+#@error_backlog:: [msg1, msg2, ... ]   @locale が設定される前に発生したエラー
+
+  PluginArgProc = {
+    "silent"  => Proc.new { |obj,rhs| obj.set_silent rhs },
+  }
+
+  def initialize
+    super
+    @b_silent = false
+    @locale = nil       # set_locale が呼び出されるまで nil となる
+    @error_backlog = []
+  end
+
+  #=== Plugin#cdl_error
+  # set_locale が呼び出されるまで @error_backlog に保存し保留する
+  def cdl_error *arg
+    if @locale then
+      Generator.error2( @locale, *arg )
+    else
+      @error_backlog << arg
+    end
+  end
+
+  #=== locale を設定する
+  # Node は initialize で locale を設定するが、plugin は parse とは
+  # 異なるタイミング new されるため、locale を再設定する
+  # このメソッドを2度呼び出すと @error_backlog のエラーが2度出力されてしまう
+  def set_locale locale
+    @locale = locale
+    @error_backlog.each { |arg|
+      Generator.error2( locale, *arg )
+    }
+  end
+
+### 構文解釈 または 意味解析段階で呼び出されるメソッド ###
+# generate 指定子の場合、構文解釈次第(end_of_parseで)呼び出される
+# generate 文の場合、出現次第呼び出される
+  ### 意味解析段階で呼び出されるメソッド ### <<< コメント誤り (V1.4.2)
+  #===  CDL ファイルの生成
+  #      typedef, signature, celltype, cell のコードを生成
+  #      重複して生成してはならない
+  #      すでに生成されている場合は出力しないこと。
+  #      もしくは同名の import により、重複を避けること。
+  #file::        FILE       生成するファイル
+  def gen_cdl_file file
+  end
+
+
+### コード生段階で呼び出されるメソッド ###
+  #=== プラグインは gen_ep_func を提供するか
+  # gen_ep_func 定義   ⇒ テンプレートではない、セルタイプコード(tCelltype.c)を生成 
+  # gen_ep_func 未定義 ⇒ テンプレート(tCelltype_templ.c)を生成
+  def gen_ep_func?
+    self.class.method_defined?( :gen_ep_func_body )
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     プラグインの場合、変更する必要のないセルタイプコードを生成する
+  #     このメソッドが未定義であれば、プラグインはセルタイプコードを生成しない (通常通りテンプレートを生成する)
+  #      gen_cdl_file の中で生成されたセルタイプに対して呼び出される
+  #file::           FILE        出力先ファイル (tCelltype.c)
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+#  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+#  end
+
+  #===  受け口関数の preamble (C言語)を生成する
+  #     必要なら preamble 部に出力する
+  #      gen_cdl_file の中でで生成されたセルタイプに対して呼び出される
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  def gen_preamble( file, b_singleton, ct_name, global_ct_name )
+    # デフォルトでは何も出力しない
+  end
+
+  #===  受け口関数の postamble (C言語)を生成する
+  #     必要なら postamble 部に出力する
+  #      gen_cdl_file の中で生成されたセルタイプに対して呼び出される
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  def gen_postamble( file, b_singleton, ct_name, global_ct_name )
+    # デフォルトでは何も出力しない
+  end
+
+  #=== gen_cdl_file の中で生成されたセルタイプに新しいセルが生成された
+  # どのセルタイプかは cell.get_celltype で分かる
+  #
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  def new_cell cell
+    # デフォルトでは何もしない
+  end
+
+### プラグイン引数の解釈 ###
+  def parse_plugin_arg
+    arg = @plugin_arg_str.dup
+
+    # 改行を消す
+    arg.gsub!( /\\\n/, "" )
+
+    while arg != ""
+
+      # 前の空白読み飛ばす
+      arg.sub!( /\A\s*(?:\\\n)*\s*(.*)/, '\1')
+
+      #  識別子取得
+      if arg =~ /\A[a-zA-Z_]\w*/ then
+        ident = $~.to_s    # 
+        arg = $'
+      else
+        cdl_error( "P1001 plugin arg: cannot find identifier in $1" , arg )
+        return
+      end
+      
+      # 前の空白読み飛ばす
+      arg.sub!( /\A\s*(?:\\\n)*\s*(.*)/, '\1')
+
+      if arg =~ /=/ then
+        arg = $'
+      else
+        cdl_error( "P1002 plugin arg: expecting \'=\' not \'$1\'" , arg )
+        return
+      end
+
+      # 前の空白読み飛ばす
+      arg.sub!( /\A\s*(?:\\\n)*\s*(.*)/, '\1')
+
+      # 右辺文字列
+      if arg =~ /\A\\"(.*?)\\"\s*,/ then      # \"  \" で囲まれている場合
+        rhs = $1
+        remain = $'
+      elsif arg =~ /\A%(.*?)%\s*,/ then      # %   % で囲まれている場合
+        rhs = $1
+        remain = $'
+      elsif arg =~ /\A!(.*?)!\s*,/ then    # $   $ で囲まれている場合
+        rhs = $1
+        remain = $'
+      elsif arg =~ /\A'(.*?)'\s*,/ then    # $   $ で囲まれている場合
+        rhs = $1
+        remain = $'
+      elsif  arg =~ /\A\\"(.*?)\\"\s*,/ then  # || にも [,$] にもできなかった
+        rhs = $1
+        remain = $'
+      # elsif arg =~ /\A(.*?)\s*$/ then
+      elsif arg =~ /\A\\"(.*?)\\"\s*\z/ then      # \"  \" で囲まれている場合
+        rhs = $1
+        remain = $'
+      elsif arg =~ /\A%(.*?)%\s*\z/ then      # %   % で囲まれている場合
+        rhs = $1
+        remain = $'
+      elsif arg =~ /\A!(.*?)!\s*\z/ then    # $   $ で囲まれている場合
+        rhs = $1
+        remain = $'
+      elsif arg =~ /\A'(.*?)'\s*\z/ then    # $   $ で囲まれている場合
+        rhs = $1
+        remain = $'
+      elsif  arg =~ /\A\\"(.*?)\\"\s*\z/ then  # || にも [,$] にもできなかった
+        rhs = $1
+        remain = $'
+      elsif arg =~ /\A(.*?),/ then
+        rhs = $1
+        remain = $'
+        # 前の空白読み飛ばす
+        rhs.sub!( /\A\s*(.*)\s*\z/, '\1')
+      elsif arg =~ /\A(.*?)\s*\z/ then
+        rhs = $1
+        remain = $'
+      else
+        cdl_error( "P1003 plugin arg: unexpected $1" , arg )
+        return
+      end
+
+      # 0文字の文字列を to_sym すると例外発生するので空白文字とする
+      if rhs == "" then
+        rhs = " "
+      end
+
+      arg = remain         # arg の残りの部分
+      arg.sub!( /\A\s*(?:\\\n)*\s*(.*)/, '\1')      # 前の空白読み飛ばす
+
+      # \ を外す
+      rhs = rhs.gsub( /\\(.)/, "\\1" )   # ここで $' が変わることに注意！
+      # print "parse_plugin_arg:  #{ident} #{rhs}\n"
+      @plugin_arg_list[ ident ] = rhs
+
+      check_plugin_arg( ident, rhs )
+    end
+    # @plugin_arg_list.each{|i,r|  print "ident: #{i}  rhs: #{r}\n" }
+  end
+
+  #=== プラグイン引数をチェックする
+  # @plugin_arg_check_proc_tab に従ってプラグイン引数をチェックすする
+  # 古い用法：子クラスでオーバーライドし、引数識別子が正しいかチェックする
+  #ident:: string: 引数識別子
+  #rhs:: string: 右辺文字列
+  def check_plugin_arg( ident, rhs )
+
+    dbgPrint "check_plugin_arg: #{ident} #{rhs.to_str}\n"
+    proc = nil
+    if @plugin_arg_check_proc_tab  then
+      proc = @plugin_arg_check_proc_tab[ident.to_s]
+    end
+    if proc == nil then
+      proc = PluginArgProc[ ident.to_s ]
+    end
+    if proc.instance_of? Proc then
+      dbgPrint "calling: #{self.class.name}.#{proc.to_s}\n"
+      proc.call( self, rhs )
+    else
+      params = ""
+      delim = ""
+      @plugin_arg_check_proc_tab.each{ |j,p|
+        params = "#{params}#{delim}#{j}"
+        delim = ", "
+      }
+      cdl_error( "P1004 $1: unknown plugin argument\'s identifier\n  $2 are acceptible for RPCPlugin." , ident, params )
+    end
+  end
+
+  #=== プラグインのメッセージ出力
+  def print_msg( msg )
+    if @b_silent == true then
+      return
+    end
+    print msg
+  end
+
+  #=== プラグイン引数 silent
+  def set_silent rhs
+    if rhs == "true" || rhs == nil then
+      @b_silent = true
+    end
+  end
+end
+
+#== 出力文字列を utf-8 から出力ファイルに convert する
+# tecsgen のソースコードは utf-8 で記述されている
+# これを、出力ファイルの文字コードに変換して出力する
+#
+# generate.rb で出力するものは message.rb で変換している
+# generate.rb で出力するものは APPFile クラスを使用している
+# mikan: CFile で出力したものに factory で追記できない (cdl ファイルの場合、追記できても意味がない)
+class CFile
+  def self.open( path, mode )
+    CFile.new( path, mode )
+  end
+
+  def initialize( path, mode )
+    if $b_no_kcode then 
+      mode += ":" + $Ruby19_File_Encode
+    end
+    @file = File.open( path, mode )
+  end
+
+  def print str
+    if $b_no_kcode && $KCONV_CONSOLE == Kconv::BINARY then 
+      @file.print( str )
+    else
+      @file.print( str.kconv( $KCONV_CDL, $KCONV_TECSGEN ) )
+    end
+  end
+
+  def puts str
+    if $b_no_kcode && $KCONV_CONSOLE == Kconv::BINARY then 
+      @file.print( str )
+    else
+      @file.print( str.kconv( $KCONV_CDL, $KCONV_TECSGEN ) )
+    end
+    @file.print( "\n" )
+  end
+
+  def printf( format, *arg )
+    if $b_no_kcode && $KCONV_CONSOLE == Kconv::BINARY then 
+      @file.print( sprintf( format, *arg ) )
+    else
+      @file.print( sprintf( format, *arg ).kconv( $KCONV_CDL, $KCONV_TECSGEN ) )
+    end
+  end
+
+  def close
+    @file.close
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/pluginModule.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/pluginModule.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/pluginModule.rb	(revision 398)
@@ -0,0 +1,167 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== プラグインをロードする側のモジュール
+# @@loaded_plugin_list:: {Symbol=>Integer}
+module PluginModule
+
+  @@loaded_plugin_list = {}
+
+  #=== プラグインをロードする
+  # return:: PluginClass
+  # V1.4.1 まで return:: true : 成功、 false : 失敗
+  #
+  # #{plugin_name}.rb をロードし、plugin_name クラスのオブジェクトを生成する．
+  # plugin_name が MultiPlugin の場合、get_plugin により、superClass のプラグインオブジェクトをロードする．
+  #
+  # すでにロードされているものは、重複してロードしない
+  # load 時の例外はこのメソッドの中でキャッチされて false が返される
+  def load_plugin( plugin_name, superClass )
+
+    dbgPrint "PluginModule: load_plugin: #{plugin_name}\n"
+    begin
+      unless @@loaded_plugin_list[ plugin_name.to_sym ] then
+        @@loaded_plugin_list[ plugin_name.to_sym ] = 0
+        if ( $verbose ) then
+          print( "load '#{plugin_name}.rb'\n" )
+        end
+        # "#{plugin_name}.rb" をロード（システム用ではないので、fatal エラーにしない）
+        if require_tecsgen_lib( "#{plugin_name}.rb", false ) == false then
+          cdl_error( "P2001 $1.rb : fail to load plugin" , plugin_name )
+          return nil
+        end
+      end
+
+      plClass = Object.const_get plugin_name
+      if ( plClass <= superClass ) then       # plClass inherits superClass
+        return plClass
+      elsif (plClass <= MultiPlugin) then     # plClass inherits MultiPlugin
+        dbgPrint "pluginClass=#{plClass}\n"
+        plugin_object = plClass.get_plugin superClass
+        dbgPrint "pluginClass=#{plugin_object}\n"
+        if plugin_object == nil then
+          cdl_error( "P9999 '$1': MultiPlugin not support '$2'", plugin_name, superClass.name )
+        end
+        @@loaded_plugin_list[ plugin_name.to_sym ] = :MultiPlugin
+        return plugin_object
+      else
+        cdl_error( "P2002 $1: not kind of $2" ,  plugin_name, superClass.name )
+        return nil
+      end
+    rescue Exception => evar
+      if $debug then
+        p evar.class
+        pp evar.backtrace
+      end
+      cdl_error( "P2003 $1: load failed" , plugin_name )
+      return nil
+    end
+    # ここへは来ない
+    return nil
+  end
+
+  #=== プラグインの gen_cdl_file を呼びして cdl ファイルを生成させ、解釈を行う
+  def generate_and_parse plugin_object
+    if plugin_object == nil     # プラグインのロードに失敗している（既にエラー）
+      return
+    end
+    plugin_name = plugin_object.class.name.to_sym
+    if @@loaded_plugin_list[ plugin_name ] == :MultiPlugin then
+      p "#{plugin_name}: MultiPlugin"
+      return
+    elsif @@loaded_plugin_list[ plugin_name ] == nil then
+      #raise "#{plugin_name} might have different name "
+      ## プラグインのファイル名と、プラグインのクラス名が相違する場合
+      #MultiPlugin の get_plugin で返されたケースでは nil になっている
+      @@loaded_plugin_list[ plugin_name ] = 0
+    end
+    count = @@loaded_plugin_list[ plugin_name ]
+    @@loaded_plugin_list[ plugin_name ] += 1
+    tmp_file_name = "#{$gen}/tmp_#{plugin_name}_#{count}.cdl"
+
+    begin
+      tmp_file = CFile.open( tmp_file_name, "w" )
+    rescue Exception => evar
+      cdl_error( "P2004 $1: open error \'$2\'" , plugin_name, tmp_file_name )
+      print_exception( evar )
+    end
+    dbgPrint "generate_and_parse: #{plugin_object.class}: gen_cdl_file\n"
+    begin
+      plugin_object.gen_cdl_file( tmp_file )
+    rescue Exception => evar
+      cdl_error( "P2005 $1: plugin error in gen_through_cell_code " , plugin_name )
+      print_exception( evar )
+    end
+    begin
+      tmp_file.close
+    rescue Exception => evar
+      cdl_error( "P2006 $1: close error \'$2\'" , plugin_name, tmp_file_name )
+      print_exception( evar )
+    end
+
+    generator = Generator.new
+    generator.set_plugin( plugin_object )
+    generator.parse( [ tmp_file_name ] )
+    generator.finalize
+  end
+
+  #=== プラグインが CDL の POST コードを生成
+  # tmp_plugin_post_code.cdl への出力
+  def self.gen_plugin_post_code file
+    dbgPrint "PluginModule #{@@loaded_plugin_list}\n"
+    @@loaded_plugin_list.each{ |plugin_name,count|
+      if count == :MultiPlugin then
+        next
+      end
+      dbgPrint "PluginModule: #{plugin_name}\n"
+      eval_str = "#{plugin_name}.gen_post_code( file )"
+      if $verbose then
+        print "gen_plugin_post_code: #{eval_str}\n"
+      end
+      begin
+        eval( eval_str )
+      rescue Exception => evar
+        Generator.error( "P2007 $1: fail to generate post code" , plugin_name )
+
+        print_exception( evar )
+      end
+    }
+  end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/syntaxobj.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/syntaxobj.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/syntaxobj.rb	(revision 398)
@@ -0,0 +1,1251 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# mikan ruby の symbol と文字列の使い分けがどうしてもうまくいかないことが時々あるので name.to_sym を入れることにした
+
+#== Node
+#
+# Node の直接の子クラス： C_EXP, Type, BaseVal, BDNode(ほとんどのものは BDNode の子クラス)
+# Node に (BDNodeにも) 入らないもの: Token, Import, Import_C, Generate
+#
+# owner を持たないものが Node となる
+# エラーは、cdl_error を通じて報告する (意味解析が構文解析後に行われる場合には、行番号が正しく出力できる
+# 
+
+class Node
+#@locale::    [@file, @lineno, @col]
+
+  def initialize
+    @locale = Generator.current_locale
+  end
+
+  #=== エラーを出力する
+  def cdl_error( message, *arg )
+    Generator.error2( @locale, message, *arg )
+  end
+
+  #=== エラーを出力する
+  #locale:: Array(locale info) : 構文解析中は無視される
+  def cdl_error2( locale, message, *arg )
+    Generator.error2( locale, message, *arg )
+  end
+
+  #=== エラーを出力する
+  #locale:: Array(locale info)
+  # 構文解析中 cdl_error2 では locale が無視されるため、別に locale を出力する
+  def cdl_error3( locale, message, *arg )
+    Generator.error(  message, *arg )
+    Console.puts "check: #{locale[0]}: line #{locale[1]} for above error"
+  end
+
+  #=== ウォーニング出力する
+  def cdl_warning( message, *arg )
+    Generator.warning2( @locale, message, *arg )
+  end
+
+  #=== ウォーニング出力する
+  def cdl_warning2( locale, message, *arg )
+    Generator.warning2( locale, message, *arg )
+  end
+
+  #=== 情報を表示する
+  def cdl_info( message, *arg )
+    Generator.info2( @locale, message, *arg )
+  end
+
+  #=== 情報を表示する
+  def cdl_info2( locale, message, *arg )
+    Generator.info2( locale, message, *arg )
+  end
+
+  def get_locale
+    @locale
+  end
+
+  def set_locale locale
+    @locale = locale
+  end
+
+  def locale_str
+    "locale=( #{@locale[0]}, #{@locale[1]} )"
+  end
+end
+
+#== 双方向 Node (Bi Direction Node)
+#
+#  Node の子クラス
+#  owner Node から参照されているもの (owner へのリンクも取り出せる)
+#
+#  get_owner で得られるもの
+#    FuncHead => Signature
+#    Decl => Namespace(const), Typedef(typedef),
+#            Celltype, CompositeCelltype(attr,var)
+#            Struct(member), ParamDecl(parameter), FuncHead(funchead)
+#    Signature, Celltype, CompositeCelltype, Typedef => Namespace
+#,   Namespace => Namespace, Generator.class (root Namespace の場合)
+#    Cell => Region, CompositeCelltype(in_composite)
+#    Port => Celltype, Composite
+#    Factory => Celltype
+#    Join => Cell
+#    CompositeCelltypeJoin => CompositeCelltype
+#    Region => Region, 
+#    ParamDecl => ParamList
+#    ParamList => FuncHead
+#    Expression => Namespace
+#    大半のものは new_* メソッドで owner Node に伝達される
+#    そのメソッドが呼び出されたときに owner Node が記録される
+#    new_* がないもの：
+#            Decl(parameter), ParamDecl, ParamList, FuncHead, Expression 
+#
+#    Expression は、owner Node となるものが多くあるが、改造が困難であるため
+#    Expression が定義されたときの Namespace を owner Node とする
+#    StructType は Type の一種なので owner を持たない
+#
+class BDNode < Node
+#@owner::Node
+#@NamespacePath:: NamespacePath
+#@Generator::
+#@import::Import :  
+
+  def initialize
+    super
+    @owner = nil
+    @NamespacePath = nil
+    @import = Import.get_current
+
+  end
+
+  #=== owner を設定する
+  def set_owner owner
+    dbgPrint "set_owner: #{owner.class.name}\n"
+    @owner = owner
+  end
+
+  #=== owner を得る
+  # class の説明を参照
+  def get_owner
+    if @owner == nil
+      raise "Node have no owner #{self.class.name} #{get_name}"
+    end
+    @owner
+  end
+end
+
+#== Namespace 名を持つ BDNode
+# Namespace(Region), Signature, Celltype, CompositeCelltype, Cell
+class NSBDNode < BDNode
+
+  def initialize
+    super
+  end
+
+  #=== 属する namespace を得る
+  # owner を namespace にたどり着くまで上にたどる
+  def get_namespace
+    if @owner.kind_of? Namespace
+      return @owner
+    elsif @owner != nil then
+      return @owner.get_namespace
+    else
+      # @owner == nil なら "::"
+      if @name != "::" then
+        raise "non-root namespace has no owner #{self.class.name}##{@name} #{self}"
+      end
+      return nil
+    end
+  end
+
+  def set_namespace_path
+    ns = get_namespace
+    if ns then
+      @NamespacePath = ns.get_namespace_path.append( get_name )
+    else
+      raise "get_namespace_path: no namespace found"
+    end
+  end
+
+  #=== NamespacePath を得る
+  def get_namespace_path
+    return @NamespacePath
+  end
+
+  def is_imported?
+    if @import then
+      return @import.is_imported?
+    else
+      return false    # mikan: 仮 @import が nil になるケースが追求できていない
+    end
+  end
+end
+
+class NamedList
+#  @names:: {} of items
+#  @items:: [] of items : item の CLASS は get_name メソッドを持つこと get_name の戻り値は Symbol でなくてはならない
+#                         NamedList を clone_for_composite する場合は、item にもメソッドが必要
+#  @type:: string	エラーメッセージ
+
+  def initialize( item, type )
+    @names = {}
+    @items = []
+    @type = type
+    add_item( item )
+  end
+
+  #=== 要素を加える
+  # parse した時点で加えること(場所を記憶する)
+  def add_item( item )
+
+    if item then
+      assert_name item
+      name = item.get_name
+      prev = @names[name]
+      if prev then
+        Generator.error( "S2001 \'$1\' duplicate $2" , name, @type )
+        prev_locale = prev.get_locale
+        puts "previous: #{prev_locale[0]}: line #{prev_locale[1]} \'#{name}\' defined here"
+        return self
+      end
+
+      @names[name]=item
+      @items << item
+    end
+
+    return self
+  end
+
+  def change_item( item )
+    assert_name item
+    name = item.get_name
+
+    prev_one = @names[name]
+    @names[name]=item
+
+    @items = @items - [ prev_one ]
+    @items << item
+  end
+
+  def del_item( item )
+    assert_name item
+    name = item.get_name
+    @names.delete name
+
+    @items = @items - [ item ]
+  end
+
+  def get_item( name )
+    if ! name.kind_of? Symbol
+      print "get_item: '#{name}', items are below\n"
+      @names.each{ |nm,item|
+        p nm
+      }
+      raise "get_item: #{name}: not Symbol"
+    end
+    if name then
+      return @names[name.to_sym]
+    else
+      return nil
+    end
+  end
+
+  def get_items
+    return @items
+  end
+
+  #=== composite cell を clone した時に要素(JOIN) の clone する
+  #
+  # mikan このメソッドは Join に特化されているので NamedList から分離すべき
+  def clone_for_composite( ct_name, cell_name, locale )
+    cl = self.clone
+    cl.set_cloned( ct_name, cell_name, locale )
+    return cl
+  end
+
+  #=== clone された NamedList インスタンスの参照するもの(item)を clone
+  #
+  # mikan このメソッドは Join に特化されているので NamedList から分離すべき
+  def set_cloned( ct_name, cell_name, locale )
+    items = []
+    names = {}
+    @items.each { |i|
+      dbgPrint "NamedList clone #{ct_name}, #{cell_name}, #{i.get_name}\n"
+
+      cl = i.clone_for_composite( ct_name, cell_name, locale )
+      names[cl.get_name] = cl
+      items << cl
+    }
+    @items = items
+    @names = names
+  end
+
+  def assert_name item
+    if ! item.get_name.kind_of? Symbol
+      raise "Not symbol for NamedList item"
+    end
+  end
+
+  def show_tree( indent )
+    @items.each { |i|
+      i.show_tree( indent )
+    }
+  end
+
+end
+
+class Typedef < BDNode
+# @declarator:: Decl
+
+  def self.new_decl_list( type_spec_qual_list, decl_list )
+    decl_list.each { |decl|
+       Typedef.new( type_spec_qual_list, decl )
+    }
+  end
+
+  def initialize( type_spec_qual_list, decl )
+    super()
+    decl.set_type( type_spec_qual_list )
+    @declarator = decl
+    decl.set_owner self    # Decl(Typedef)
+
+    Namespace.new_typedef( self )
+  end
+
+  def get_name
+    @declarator.get_name
+  end
+
+  def get_declarator
+    @declarator
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "Typedef: #{locale_str}"
+    @declarator.show_tree( indent + 1 )
+  end
+end
+
+#== 関数頭部
+# signature に登録される関数
+class FuncHead <BDNode
+#  @declarator:: Decl
+
+  def initialize( declarator, type, b_oneway )
+    super()
+    declarator.set_type( type )
+    @declarator = declarator
+    @declarator.set_owner self  # Decl (FuncHead)
+
+    if @declarator.get_type.kind_of?( FuncType ) then
+      if b_oneway then
+        @declarator.get_type.set_oneway( b_oneway )
+      end
+    end
+    @declarator.get_type.check_struct_tag :FUNCHEAD
+
+    # check if return type is pointer
+    if declarator.get_type.kind_of? FuncType then
+      if declarator.get_type.get_type.get_original_type.kind_of?( PtrType ) &&
+          Signature.get_current.is_deviate? == false then
+        cdl_warning( "W3004 $1 pointer type has returned. specify deviate or stop return pointer" , @declarator.get_identifier )
+      end
+    end
+  end
+
+  def get_name
+    @declarator.get_name
+  end
+
+  def get_declarator
+    @declarator
+  end
+
+  def is_oneway?
+    if @declarator.is_function? then
+      return @declarator.get_type.is_oneway?
+    end
+    return false
+  end
+
+  def is_function?
+    @declarator.is_function?
+  end
+
+  #=== FuncHead# 関数の名前を返す
+  def get_name
+    return @declarator.get_name
+  end
+
+  #=== FuncHead# 関数の戻り値の型を返す
+  # types.rb に定義されている型
+  # 関数ヘッダの定義として不完全な場合 nil を返す
+  def get_return_type
+    if is_function? then
+      return @declarator.get_type.get_type
+    end
+  end
+
+  #=== FuncHead# 関数の引数のリストを返す
+  # ParamList を返す
+  # 関数ヘッダの定義として不完全な場合 nil を返す
+  def get_paramlist
+    if is_function? then
+      return @declarator.get_type.get_paramlist
+    end
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "FuncHead: #{locale_str}"
+    @declarator.show_tree( indent + 1 )
+  end
+end
+
+#=== 宣言
+# @kind で示される各種の宣言
+class Decl < BDNode
+
+# @identifer:: String
+# @global_name:: String | nil : String(@kind=TYPEDEF||:CONSTANT), nil(@kind=その他)
+#                set_kind にて設定される
+# @type:: ArrayType, FuncType, PtrType, IntType, StructType
+#         VoidType, FloatType, DefinedType, BoolType
+# @initializer:: constant_expression, mikan { initlist }
+# @kind:: :VAR, :ATTRIBUTE, :PARAMETER, :TYPEDEF, :CONSTANT, :MEMBER, :FUNCHEAD(signatureの関数定義)
+# @b_referenced:: bool
+#
+# 以下は、@kind が :VAR, :ATTRIBUTE のときに有効
+# @rw:: bool     # 古い文法では attr に指定可能だった（消すには generate の修正も必要）
+# @omit:: bool
+# @choice_list:: [String]  attr 初期値の選択肢
+# 以下は、@kind が :VAR, :ATTRIBUTE, :MEMBER のときに有効
+# @size_is:: Expression or nil unless specified
+# 以下は、@kind が :MEMBER のときに有効
+# @count_is:: Expression or nil unless specified
+#             attr, var の場合、count_is は指定できない
+# @string:: Expression, -1 (length not specified) or nil (not specified)
+#
+# mikan  ParamDecl だけ別に設けたが、MemberDecl, AttrDecl なども分けるべきか(？)
+
+  def initialize( identifier )
+    super()
+    @identifier = identifier
+    @rw = false
+    @omit = false
+    @size_is = nil
+    @count_is = nil
+    @string  = nil
+    @choice_list  = nil
+    @b_referenced  = false
+  end
+
+  def set_initializer( initializer )
+    @initializer = initializer
+  end
+
+  def get_initializer
+    @initializer
+  end
+
+  def is_function?
+    if @type.class == FuncType then
+      return true
+    else
+      return false
+    end
+  end
+
+  #== Decl の意味的誤りをチェックする
+  def check
+    # return nil if @type == nil
+
+    # 構造体タグチェック（ポインタ型から構造体が参照されている場合は、タグの存在をチェックしない）
+    @type.check_struct_tag @kind
+
+    # 型のチェックを行う
+    res = @type.check
+    if res then
+      cdl_error( "S2002 $1: $2" , @identifier, res )
+    end
+
+    # 不要の初期化子をチェックする
+    if @initializer then
+      case @kind
+      when :PARAMETER, :TYPEDEF, :MEMBER, :FUNCHEAD
+        cdl_error( "S2003 $1: $2 cannot have initializer" , @identifier, @kind.to_s.downcase )
+      when :VAR, :ATTRIBUTE, :CONSTANT
+        # p @initializer  ここでは代入可能かどうか、チェックしない
+        # :VAR, :ATTRIBUTE, :CONSTANT はそれぞれでチェックする
+        # return @type.check_init( @identifier, @initializer, @kind )
+      else
+        raise "unknown kind in Delc::check"
+      end
+    end
+
+    if( @type.kind_of? ArrayType ) && ( @type.get_subscript == nil ) && ( @omit == false ) then
+      if @kind == :ATTRIBUTE then
+        cdl_error( "S2004 $1: array subscript must be specified or omit" , @identifier )
+      elsif @kind == :VAR || @kind == :MEMBER then
+        cdl_error( "S2005 $1: array subscript must be specified" , @identifier )
+      end
+    end
+
+    return nil
+  end
+
+  #== ポインタレベルを得る
+  # 戻り値：
+  #   非ポインタ変数   = 0
+  #   ポインタ変数     = 1
+  #   二重ポインタ変数 = 2
+  def get_ptr_level
+    level = 0
+    type = @type
+    while 1
+      if type.kind_of?( PtrType ) then
+        level += 1
+        type = type.get_referto
+#      elsif type.kind_of?( ArrayType ) then  # 添数なし配列はポインタとみなす
+#        if type.get_subscript == nil then
+#          level += 1
+#          type = type.get_type
+#        else
+#          break
+#        end
+        # mikan ポインタの添数あり配列のポインタレベルは０でよい？
+      elsif type.kind_of?( DefinedType ) then
+        type = type.get_type
+        # p "DefinedType: #{type} #{type.class}"
+      else
+        break
+      end
+    end
+    return level
+  end
+
+  def get_name
+    @identifier
+  end
+
+  def get_global_name
+    @global_name
+  end
+
+  def set_type( type )
+    unless @type then
+      @type = type
+    else
+      @type.set_type( type )             # 葉に設定
+    end
+  end
+
+  def get_type
+    @type
+  end
+
+  def get_identifier
+    @identifier
+  end
+
+  # STAGE: B
+  def set_kind( kind )
+    @kind = kind
+    case kind
+    when :TYPEDEF, :CONSTANT
+      if Namespace.get_global_name.to_s == "" then
+        @global_name = @identifier
+      else
+        @global_name = :"#{Namespace.get_global_name}_#{@identifier}"
+      end
+    else
+      @global_name = nil
+    end
+  end
+
+  def get_kind
+    @kind
+  end
+
+  def set_specifier_list( spec_list )
+    spec_list.each{  |spec|
+      case spec[0]
+      when :RW
+        @rw = true
+      when :OMIT
+        @omit = true
+      when :SIZE_IS
+        @size_is = spec[1]
+      when :COUNT_IS
+        @count_is = spec[1]
+      when :STRING
+        @string = spec[1]
+      when :CHOICE
+        @choice_list = spec[1]
+      else
+        raise "Unknown specifier #{spec[0]}"
+      end
+    }
+
+    if @size_is || @count_is || @string
+        @type.set_scs( @size_is, @count_is, @string, nil, false )
+    end
+  end
+
+  def is_rw?
+    @rw
+  end
+
+  def is_omit?
+    @omit
+  end
+
+  def get_size_is
+    @size_is
+  end
+
+  def get_count_is
+    @count_is
+  end
+
+  def get_string
+    @string
+  end
+
+  def get_choice_list
+    @choice_list
+  end
+
+  def referenced
+    @b_referenced = true
+  end
+
+  def is_referenced?
+    @b_referenced
+  end
+
+  def is_type?( type )
+    t = @type
+    while 1
+      if t.kind_of?( type ) then
+        return true
+      elsif t.kind_of?( DefinedType ) then
+        t = t.get_type
+      else
+        return false
+      end
+    end
+  end
+
+  def is_const?
+    type = @type
+    while 1
+      if type.is_const? then
+        return true
+      elsif type.kind_of?( DefinedType ) then
+        type = type.get_type
+      else
+        return false
+      end
+    end
+  end
+
+  #=== Decl# print_flowinfo
+  def print_flowinfo file
+    if @kind == :VAR then
+      file.write "#{@identifier} "
+    end
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "Declarator: name: #{@identifier} kind: #{@kind} global_name: #{@global_name} #{locale_str}"
+    (indent+1).times { print "  " }
+    puts "type:"
+    @type.show_tree( indent + 2 )
+    if @initializer then
+      (indent+1).times { print "  " }
+      puts "initializer:"
+      @initializer.show_tree( indent + 2 )
+    else
+      (indent+1).times { print "  " }
+      puts "initializer: no"
+    end
+    (indent+1).times { print "  " }
+    puts "size_is: #{@size_is.to_s}, count_is: #{@count_is.to_s}, string: #{@string.to_s} referenced: #{@b_referenced} "
+   
+  end
+
+end
+
+# 関数パラメータの宣言
+class ParamDecl < BDNode
+
+# @declarator:: Decl:  Token, ArrayType, FuncType, PtrType
+# @direction:: :IN, :OUT, :INOUT, :SEND, :RECEIVE
+# @size:: Expr   (size_is 引数)
+# @count:: Expr   (count_is 引数)
+# @max:: Expr (size_is の第二引数)
+# @b_nullable:: Bool : nullable 
+# @string:: Expr or -1(if size not specified) （string 引数）
+# @allocator:: Signature of allocator
+# @b_ref:: bool : size_is, count_is, string_is 引数として参照されている
+#
+# 1. 関数型でないこと
+# 2. ２次元以上の配列であって最も内側以外の添数があること
+# 3. in, out, ..., size_is, count_is, ... の重複指定がないこと
+# 4. ポインタレベルが適切なこと
+
+  def initialize( declarator, specifier, param_specifier )
+    super()
+    @declarator = declarator
+    @declarator.set_owner self  # Decl (ParamDecl)
+    @declarator.set_type( specifier )
+    @param_specifier = param_specifier
+    @b_ref = false
+    @b_nullable = false
+
+    if @declarator.is_function? then		# (1)
+      cdl_error( "S2006 \'$1\' function" , get_name )
+      return
+    end
+
+    res = @declarator.check
+    if res then					# (2)
+      cdl_error( "S2007 \'$1\' $2" , get_name, res )
+      return
+    end
+
+    @param_specifier.each { |i|
+      case i[0]                                     # (3)
+      when :IN, :OUT, :INOUT, :SEND, :RECEIVE
+        if @direction == nil then
+          @direction = i[0]
+        elsif i[0] == @direction then
+          cdl_warning( "W3001 $1: duplicate" , i[0] )
+          next
+        else
+          cdl_error( "S2008 $1: inconsitent with previous one" , i[0] )
+          next
+        end
+
+        case i[0]
+        when :SEND, :RECEIVE
+          @allocator = Namespace.find( i[1] )   #1
+          if ! @allocator.instance_of?( Signature ) then
+            cdl_error( "S2009 $1: not found or not signature" , i[1] )
+            next
+          elsif ! @allocator.is_allocator? then
+            # cdl_error( "S2010 $1: not allocator signature" , i[1] )
+          end
+        end
+
+      when :SIZE_IS
+        if @size then
+          cdl_error( "S2011 size_is duplicate"  )
+        else
+          @size = i[1]
+        end
+      when :COUNT_IS
+        if @count then
+          cdl_error( "S2012 count_is duplicate"  )
+        else
+          @count = i[1]
+        end
+      when :STRING
+        if @string then
+          cdl_error( "S2013 string duplicate"  )
+        elsif i[1] then
+          @string = i[1]
+        else
+          @string = -1
+        end
+      when :MAX_IS
+        # max_is は、内部的なもの bnf.y.rb 参照
+        # size_is で重複チェックされる
+        @max = i[1]
+      when :NULLABLE
+        # if ! @declarator.get_type.kind_of?( PtrType ) then
+        #  cdl_error( "S2026 '$1' nullable specified for non-pointer type", @declarator.get_name )
+        # else
+          @b_nullable = true
+        # end
+      end
+
+    }
+
+    if @direction == nil then
+      cdl_error( "S2014 No direction specified. [in/out/inout/send/receive]"  )
+    end
+
+    if ( @direction == :OUT || @direction == :INOUT ) && @string == -1 then
+      cdl_warning( "W3002 $1: this string might cause buffer over run" , get_name )
+    end
+
+    # mikan ポインタの配列（添数有）のレベルが０
+    ptr_level = @declarator.get_ptr_level
+
+    # p "ptr_level: #{@declarator.get_identifier} #{ptr_level}"
+    # p @declarator
+
+    #----  set req_level, min_level & max_level  ----#
+    if !(@size||@count||@string) then	    # (4)
+      req_level = 1
+    elsif (@size||@count)&&@string then
+      req_level = 2
+    else
+      req_level = 1
+    end
+
+    if @direction == :RECEIVE then
+      req_level += 1
+    end
+    min_level = req_level
+    max_level = req_level
+
+    # IN without pointer specifier can be non-pointer type
+    if @direction == :IN && !(@size||@count||@string) then
+      min_level = 0
+    end
+
+    # if size_is specified and pointer refer to struct, max_level increase
+    if @size then
+      type = @declarator.get_type.get_original_type
+      while type.kind_of? PtrType
+        type = type.get_referto.get_original_type
+      end
+      if type.kind_of? StructType then
+        max_level += 1
+      end
+    end
+    #----  end req_level & max_level    ----#
+
+    # p "req_level: #{req_level} ptr_level: #{ptr_level}"
+    #if ptr_level < req_level && ! ( @direction == :IN && req_level == 1 && ptr_level == 0) then
+    if ptr_level < min_level then
+      cdl_error( "S2014 $1 need pointer or more pointer" , @declarator.get_identifier )
+    elsif ptr_level > max_level then
+      # note: 構文解析段階で実行のため get_current 可
+      if Signature.get_current == nil || Signature.get_current.is_deviate? == false then
+        cdl_warning( "W3003 $1 pointer level mismatch" , @declarator.get_identifier )
+      end
+    end
+
+    type = @declarator.get_type
+    while type.kind_of?( DefinedType )
+      type = type.get_original_type
+    end
+
+    if ptr_level > 0 then
+      # size_is, count_is, string をセット
+      if @direction == :RECEIVE && ptr_level > 1 then
+        type.get_type.set_scs( @size, @count, @string, @max, @b_nullable )
+      else
+        type.set_scs( @size, @count, @string, @max, @b_nullable )
+      end
+
+#p ptr_level
+#type.show_tree 1
+
+      # ポインタが指している先のデータ型を得る
+      i = 0
+      t2 = type
+      while i < ptr_level
+        t2 = t2.get_referto
+        while t2.kind_of?( DefinedType )
+          t2 = t2.get_original_type
+        end
+        i += 1
+      end
+
+# p @declarator.get_name
+# t2.show_tree 1
+# p t2.is_const?
+
+      # const 修飾が適切かチェック
+      if @direction == :IN then
+        if ! t2.is_const? then
+          cdl_error( "S2015 '$1' must be const for \'in\' parameter $2" , get_name, type.class )
+        end
+      else
+        if t2.is_const? then
+          cdl_error( "S2016 '$1' can not be const for $2 parameter" , get_name, @direction )
+        end
+      end
+    else
+      # 非ポインタタイプ
+      if @size != nil || @count != nil || @string != nil || @max != nil || @b_nullable then
+        type.set_scs( @size, @count, @string, @max, @b_nullable )
+      end
+    end
+
+#    if ptr_level > 0 && @direction == :IN then
+#      if type.is_const != :CONST
+#    end
+
+    # p self
+
+  end
+
+  def check_struct_tag kind
+    @declarator.get_type.check_struct_tag :PARAMETER
+  end
+
+  def get_name
+    @declarator.get_name
+  end
+
+  def get_size
+    @size
+  end
+
+  def get_count
+    @count
+  end
+
+  def get_string
+    @string
+  end
+
+  def get_max
+    @max
+  end
+
+  def clear_max
+    # p "clear_max: #{@declarator.get_name} #{@max.to_s}"
+    @max = nil
+    @declarator.get_type.clear_max
+  end
+
+  def is_nullable?
+    @b_nullable
+  end
+
+  def get_type
+    @declarator.get_type
+  end
+
+  def get_direction
+    @direction
+  end
+
+  def get_declarator
+    @declarator
+  end
+
+  def get_allocator
+    @allocator
+  end
+
+  def referenced
+    @b_ref = true
+  end
+
+  def is_referenced?
+    @b_ref
+  end
+
+  #=== PPAllocator が必要か
+  # Transparent RPC の場合 in で size_is, count_is, string のいずれかが指定されている場合 oneway では PPAllocator が必要
+  # Transparent PC で oneway かどうかは、ここでは判断しないので別途判断が必要
+  # Opaque RPC の場合 size_is, count_is, string のいずれかが指定されている場合、PPAllocator が必要
+  def need_PPAllocator?( b_opaque = false )
+    if ! b_opaque then
+#      if @direction == :IN && ( @size || @count || @string ) then
+      if @direction == :IN && @declarator.get_type.get_original_type.kind_of?( PtrType ) then
+        return true
+      end
+    else
+      if (@direction == :IN || @direction == :OUT || @direction == :INOUT ) &&
+          @declarator.get_type.get_original_type.kind_of?( PtrType ) then
+        return true
+      end
+    end
+    return false
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "ParamDecl: direction: #{@direction} #{locale_str}"
+    @declarator.show_tree( indent + 1 )
+    if @size then
+      (indent+1).times { print "  " }
+      puts "size:"
+      @size.show_tree( indent + 2 )
+    end
+    if @count then
+      (indent+1).times { print "  " }
+      puts "count:"
+      @count.show_tree( indent + 2 )
+    end
+    if @string then
+      (indent+1).times { print "  " }
+      puts "string:"
+      if @string == -1 then
+       (indent+2).times { print "  " }
+        puts "size is not specified"
+      else
+        @string.show_tree( indent + 2 )
+      end
+    end
+    if @allocator then
+      (indent+1).times { print "  " }
+      puts "allocator: signature: #{@allocator.get_name}"
+    end    
+  end
+end
+
+# 関数パラメータリスト
+class ParamList < BDNode
+# @param_list:: NamedList : item: ParamDecl
+
+  def initialize( paramdecl )
+    super()
+    @param_list = NamedList.new( paramdecl, "parameter" )
+    @param_list.get_items.each { |paramdecl|
+      paramdecl.set_owner self   # ParamDecl
+    }
+  end
+
+  def add_param( paramdecl )
+    return if paramdecl == nil    # 既にエラー
+
+    @param_list.add_item( paramdecl )
+    paramdecl.set_owner self   # ParamDecl
+  end
+
+  def get_items
+    @param_list.get_items
+  end
+
+  #=== size_is, count_is, string の引数の式をチェック
+  # 変数は前方参照可能なため、関数頭部の構文解釈が終わった後にチェックする
+  def check_param
+    @param_list.get_items.each { |i|
+      next if i == nil                      # i == nil : エラー時
+
+      if i.get_type.class == VoidType then
+        # 単一の void 型はここにはこない
+        cdl_error( "S2027 '$1' parameter cannot be void type", i.get_name )
+      end
+
+      size = i.get_size			# Expression
+      if size then
+        val = size.eval_const( @param_list )
+        if val == nil then			# 定数式でないか？
+          # mikan 変数を含む式：単一の変数のみ OK
+          type = size.get_type( @param_list )
+          unless type.kind_of?( IntType ) then
+            cdl_error( "S2017 size_is argument is not integer type"  )
+          else
+            size.check_dir_for_param( @param_list, i.get_direction, "size_is" )
+          end
+        else
+          if val != Integer( val ) then
+            cdl_error( "S2018 \'$1\' size_is parameter not integer" , i.get_declarator.get_identifier )
+          elsif val <= 0 then
+            cdl_error( "S2019 \'$1\' size_is parameter negative or zero" , i.get_declarator.get_identifier )
+          end
+        end
+      end
+
+      max = i.get_max
+      if max then
+        val2 = max.eval_const( @param_list )
+        if val2 == nil then
+          cdl_error( "S2028 '$1' max (size_is 2nd parameter) not constant", i.get_name )
+        elsif val2 != Integer( val2 ) || val2 <= 0 then
+          cdl_error( "S2029 '$1' max (size_is 2nd parameter) negative or zero, or not integer", i.get_name )
+        end
+      end
+
+      if val != nil && val2 != nil then
+        if val < val2 then
+          cdl_warning( "W3005 '$1' size_is always lower than max. max is ignored", i.get_name )
+          i.clear_max
+        else
+          cdl_error( "S2030 '$1' both size_is and max are const. size_is larger than max", i.get_name )
+        end
+      end
+
+      count = i.get_count			# Expression
+      if count then
+        val = count.eval_const( @param_list )
+        if val == nil then			# 定数式でないか？
+          # mikan 変数を含む式：単一の変数のみ OK
+          type = count.get_type( @param_list )
+          unless type.kind_of?( IntType ) then
+            cdl_error( "S2020 count_is argument is not integer type"  )
+          else
+            count.check_dir_for_param( @param_list, i.get_direction, "count_is" )
+          end
+        else
+          if val != Integer( val ) then
+            cdl_error( "S2021 \'$1\' count_is parameter not integer" , i.get_declarator.get_identifier )
+          elsif val <= 0 then
+            cdl_error( "S2022 \'$1\' count_is parameter negative or zero" , i.get_declarator.get_identifier )
+          end
+        end
+      end
+
+      string = i.get_string			# Expression
+      if string != -1 && string then
+        val = string.eval_const( @param_list )
+        if val == nil then			# 定数式でないか？
+          # mikan 変数を含む式：単一の変数のみ OK
+          type = string.get_type( @param_list )
+          unless type.kind_of?( IntType ) then
+            cdl_error( "S2023 string argument is not integer type"  )
+          else
+            string.check_dir_for_param( @param_list, i.get_direction, "string" )
+          end
+        else
+          if val != Integer( val ) then
+            cdl_error( "S2024 \'$1\' string parameter not integer" , i.get_declarator.get_identifier )
+          elsif val <= 0 then
+            cdl_error( "S2025 \'$1\' string parameter negative or zero" , i.get_declarator.get_identifier )
+          end
+        end
+      end
+    }
+  end
+
+  def check_struct_tag kind
+    @param_list.get_items.each{ |p|
+      p.check_struct_tag kind
+    }
+  end
+
+  #=== Push Pop Allocator が必要か？
+  # Transparent RPC の場合 (oneway かつ) in の配列(size_is, count_is, string のいずれかで修飾）がある
+  def need_PPAllocator?( b_opaque = false )
+    @param_list.get_items.each { |i|
+      if i.need_PPAllocator?( b_opaque ) then
+        return true
+      end
+    }
+    false
+  end
+
+  def find( name )
+    @param_list.get_item( name )
+  end
+
+  #== ParamList# 文字列化
+  #b_name:: Bool: パラメータ名を含める
+  def to_str( b_name )
+    str = "("
+    delim = ""
+    @param_list.get_items.each{ |paramdecl|
+      decl = paramdecl.get_declarator
+      str += delim + decl.get_type
+      if b_name then
+        str += " " + decl.get_name
+      end
+      str += decl.get_type_post
+      delim = ", "
+    }
+    str += ")"
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "ParamList: #{locale_str}"
+    @param_list.show_tree( indent + 1 )
+  end
+end
+
+#== CDL の文字列リテラルを扱うためのクラス
+# CDL の文字列リテラルそのものではない
+class CDLString
+  # エスケープ文字を変換
+  def self.escape str
+    str = str.dup
+    str.gsub!( /\\a/, "\x07" )
+    str.gsub!( /\\b/, "\x08" )
+    str.gsub!( /\\f/, "\x0c" )
+    str.gsub!( /\\n/, "\x0a" )
+    str.gsub!( /\\r/, "\x0d" )
+    str.gsub!( /\\t/, "\x08" )
+    str.gsub!( /\\v/, "\x0b" )
+    str.gsub!( /(\\[Xx][0-9A-Fa-f]{1,2})/, '{printf \"\\1\"}' )
+    str.gsub!( /(\\[0-7]{1,3})/, '{printf \"\\1\"}' )
+    str.gsub!( /\\(.)/, "\\1" )   # mikan 未定義のエスケープシーケンスを変換してしまう (gcc V3.4.4 では警告が出される)
+    return str
+  end
+
+  #=== CDLString#前後の " を取り除く
+  def self.remove_dquote str
+    s = str.sub( /\A"/, "" )
+    s.sub!( /"\z/, "" )
+    return s
+  end
+end
+
+#== CDL の初期化子を扱うためのクラス
+# CDL の初期化子そのものではない
+class CDLInitializer
+  #=== 初期化子のクローン
+  # 初期化子は Expression, C_EXP, Array のいずれか
+  def self.clone_for_composite( rhs, ct_name, cell_name, locale )
+    if rhs.instance_of? C_EXP then
+      # C_EXP の clone を作るとともに置換
+      rhs = rhs.clone_for_composite( ct_name, cell_name, locale )
+    elsif rhs.instance_of? Expression then
+      rhs = rhs.clone_for_composite
+    elsif rhs.instance_of? Array then
+      rhs = clone_for_compoiste_array( rhs, ct_name, cell_name, locale )
+    else
+      raise "unknown rhs for join"
+    end
+    return rhs
+  end
+
+  #=== 初期化子（配列）のクローン
+  # 要素は clone_for_composite を持つものだけ
+  def self.clone_for_compoiste_array( array, ct_name, cell_name, locale )
+    # "compoiste.identifier" の場合 (CDL としては誤り)
+    if array[0] == :COMPOSITE then
+      return array.clone
+    end
+
+    new_array = array.map{ |m|
+      clone_for_composite( m, ct_name, cell_name, locale )
+    }
+    return new_array
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tecs_lang.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tecs_lang.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tecs_lang.rb	(revision 398)
@@ -0,0 +1,351 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== 言語に関する変数を設定
+# メッセージファイルの読み込みも行う (読み込みに失敗した場合、デフォルトの文字コードに変更する)
+class TECS_LANG
+  # ハッシュのタグは case insensitive のため、大文字の文字列とする
+  CHARSET_ALIAS = {
+    "UJIS" => :eucJP,
+    "UTF-8" => :utf8,
+    "EUCJP" => :eucJP,   # 以下 case insensitive にするため
+    "SJIS" => :sjis,
+    "UTF8" => :utf8,
+    "ISO8859-1" => :"iso8859-1"
+  }
+  LANG_ALIAS = {
+    "C" => :en_US,
+    "EN_US" => :en_US,   # 以下 case insensitive にするため
+    "JA_JP" => :ja_JP
+  }
+  SUITABLE_CHARSET = {
+    :ja_JP => [ :eucJP, :sjis, :utf8 ],
+    :en_US => [ :"iso8859-1", :utf8, nil ]
+  }
+
+  #=== LANG のパース
+  #lang::String  "ja_JP.eucJP@cjknarrow", "C" など
+  #RETURN:: [ :ja_JP, :eucJP, :cjknarrow ]
+  def self.parse_lang( lang )
+    lang =~ /([^\.@]*)(\.([^@]*))?(@(.*))?/
+
+    lang_terri = $1.to_sym if $1 != nil && $1 != ""
+    # set_kcode_binary により、C.UTF-8 のみを特別扱いする必要がなくなった
+    # if lang_terri == :C then    # LANG=C.* は、すべて 1 byte 文字コードとして扱う
+    #  codeset = nil
+    #  modifier = nil
+    # else
+      codeset = $3.to_sym if $3 != nil && $3 != ""
+      modifier = $5.to_sym if $5 != nil && $5 != ""
+    # end
+    [ lang_terri, codeset, modifier ]
+  end
+
+  #=== lang, charset の別明解決および妥当性のチェック
+  #lang::Symbol    : :en_US, :ja_JP など
+  #charset::Symbol : :eucJP, :utf8 など
+  #RETURN:
+  #  [ lang, charset, result ]::　　result = false の場合 lang, charset は不適切
+  def self.resolve_alias_and_check( lang, charset )
+    if LANG_ALIAS[ lang.to_s.upcase ] then
+      ln = LANG_ALIAS[ lang.to_s.upcase ]
+    else
+      ln = lang
+    end
+
+    if CHARSET_ALIAS[ charset.to_s.upcase ] then
+      cs = CHARSET_ALIAS[ charset.to_s.upcase ]
+    else
+      cs = charset
+    end
+
+    if SUITABLE_CHARSET[ ln ] == nil || SUITABLE_CHARSET[ ln ].index( cs ) == nil
+      res = false
+    else
+      res = true
+    end
+
+    # p ln, cs, res
+    [ ln, cs, res ]
+  end
+
+  #=== codepage を取り出す
+  #codepage は3～5桁の整数として仮定
+  def self.get_win_codepage
+    cmd_pipe = IO.popen('cmd /c chcp','r')
+    cmd_pipe.read =~ /([0-9]{3,5})/
+    cp = $1
+    cmd_pipe.close
+    return cp
+  end
+
+  #=== codepage から LANG の設定文字列に変換
+  def self.codepage_to_lang cp
+    if cp == "932" then
+      "ja_JP.sjis"
+    else
+      "en_US"
+    end
+  end
+
+  #=== 言語、文字コードに関する変数を設定
+  # 以下の順にチェックされ、一番最後に設定された値が採用される
+  #   ・デフォルト
+  #   ・codepage  (exerb 版で TERM 未設定または TERM=cygwin の場合のみ)
+  #   ・LANG 環境変数
+  #   ・TECSGEN_LANG 環境変数
+  #   ・TECSGEN_FILE_LANG 環境変数 (ファイルの文字コードのみ)
+  #   ・-k オプション (ファイルの文字コードのみ)
+  def self.set_lang_var
+
+    if $IN_EXERB && ( ENV[ 'TERM' ] == nil || ENV[ 'TERM' ] == "cygwin" ) then
+      # exerb 版で端末 cygwin の時は codepage のみを見る
+      cp = get_win_codepage
+      lang = codepage_to_lang cp
+      $LANG_FILE, $CHARSET_FILE, *dum = self.parse_lang( lang )
+      $LANG_CONSOLE = $LANG_FILE
+      $CHARSET_CONSOLE = $CHARSET_FILE
+
+    elsif ENV[ 'LANG' ]then
+      # 非 exerb 版では LANG 環境変数を見る
+      # cygwin console では codepage に従って出力した方が平和なため
+
+      $LANG_FILE, $CHARSET_FILE, *dum = self.parse_lang( ENV[ 'LANG' ] )
+      $LANG_CONSOLE = $LANG_FILE
+      $CHARSET_CONSOLE = $CHARSET_FILE
+    end
+
+    if ENV[ 'TECSGEN_LANG' ]then
+      $LANG_FILE, $CHARSET_FILE, *dum = self.parse_lang( ENV[ 'TECSGEN_LANG' ] )
+      $LANG_CONSOLE = $LANG_FILE
+      $CHARSET_CONSOLE = $CHARSET_FILE
+    end
+
+    if ENV[ 'TECSGEN_FILE_LANG' ]then
+      $LANG_FILE, $CHARSET_FILE, *dum = self.parse_lang( ENV[ 'TECSGEN_FILE_LANG' ] )
+    end
+
+    self.set_lang_by_option
+  end
+
+  #=== -k オプションからファイル用の言語、文字コード変数を設定
+  def self.set_lang_by_option
+    if $kcode == nil
+      return
+    end
+
+    code = $kcode
+    found = false
+    res = $CODE_TYPE_ARRAY.index( code )
+    if res == nil then
+      print "-k: illegal kcode type #{code}. (#{$CODE_TYPE_ARRAY.join(", ")})\n"
+      exit 1
+    end
+
+    case $kcode
+    when "euc"
+      $CHARSET_FILE = :eucJP
+      $LANG_FILE = :ja_JP
+    when "sjis"
+      $CHARSET_FILE = :sjis
+      $LANG_FILE = :ja_JP
+    when "utf8"
+      $CHARSET_FILE = :utf8
+      $LANG_FILE = :ja_JP
+    when "none"
+      $CHARSET_FILE = nil
+      $LANG_FILE = "en_US"
+    end
+  end
+
+  #=== Kconv クラス用の変数を設定
+  # 言語情報から Kconv に関する変数を設定
+  def self.set_kconv_var
+
+    # 文字コードの設定
+    case $CHARSET_FILE           # string: "EUC" | "SJIS" | "NONE" | "UTF8"
+    when :eucJP
+      $KCODE_CDL = "EUC"
+      $KCONV_CDL = Kconv::EUC
+      $Ruby19_File_Encode = "ASCII-8BIT"
+    when :sjis
+      $KCODE_CDL = "SJIS"
+      $KCONV_CDL = Kconv::SJIS
+      $Ruby19_File_Encode = "Shift_JIS"
+    when :utf8
+      $KCODE_CDL = "UTF8"
+      $KCONV_CDL = Kconv::UTF8
+      $Ruby19_File_Encode = "ASCII-8BIT"
+    else
+      $KCODE_CDL = "BINARY"
+      $KCONV_CDL = Kconv::BINARY
+      $Ruby19_File_Encode = "ASCII-8BIT"
+    end
+
+    case $CHARSET_CONSOLE
+    when :eucJP
+      $KCODE_CONSOLE = "EUC"
+      $KCONV_CONSOLE = Kconv::EUC
+    when :sjis
+      $KCODE_CONSOLE = "SJIS"
+      $KCONV_CONSOLE = Kconv::SJIS
+    when :utf8
+      $KCODE_CONSOLE = "UTF8"
+      $KCONV_CONSOLE = Kconv::UTF8
+    else
+      $KCODE_CONSOLE = "BINARY"
+      $KCONV_CONSOLE = Kconv::BINARY
+    end
+
+    $KCODE_TECSGEN = "UTF8"      # string: "EUC"  このファイルの文字コード（オプションではなく定数）
+    $KCONV_TECSGEN = Kconv::UTF8 # const: 
+    set_kcode $KCODE_TECSGEN     # このファイルの文字コードを設定
+  end
+
+  #=== 一時的に KCODE を BINARY に変更する
+  # EUC を UTF8 で読み込んだ場合に文字区切りを誤る問題の対応
+  # コメントの読み飛ばしを誤る点が問題
+  # ただし、SJIS の場合は、エスケープ文字の問題があるため、変更しない
+  def self.set_kcode_binary
+
+    #2.0
+    if $b_no_kcode then
+      return
+    end
+
+    $KCODE_BACK = $KCODE
+    if $KCODE != "SJIS" then
+      set_kcode "BINARY"
+    end
+  end
+
+  #=== 一時的なあ KCODE の変更を元に戻す
+  def self.reset_kcode
+    set_kcode $KCODE_BACK
+  end
+
+  #####
+  # $LANG_FILE        言語 (C は en_US に変換される)
+  # $LANG_CONSOLE     言語 (C は en_US に変換される)
+  # $CHARSET_FILE     ファイルの文字コード
+  # $CHARSET_CONSOLE  コンソール文字コード
+
+  # デフォルトの設定（正規化済みのこと）
+  $LANG_FILE_DEFAULT  = :en_US
+  $CHARSET_FILE_DEFAULT = nil
+  $LANG_CONSOLE_DEFAULT = :en_US
+  $CHARSET_CONSOLE_DEFAULT = nil
+
+  $LANG_FILE = $LANG_FILE_DEFAULT
+  $CHARSET_FILE = $CHARSET_FILE_DEFAULT
+  $LANG_CONSOLE = $LANG_CONSOLE_DEFAULT
+  $CHARSET_CONSOLE = $CHARSET_CONSOLE_DEFAULT
+
+  # -k で指定可能なコード
+  $CODE_TYPE_ARRAY = [ "euc", "sjis", "none", "utf8" ]
+
+  # 言語を決定する
+  self.set_lang_var
+
+  # 言語、コードのチェックと正規化
+  lang_file, charset_file, res =
+    self.resolve_alias_and_check( $LANG_FILE, $CHARSET_FILE )
+  if res == false then
+    # lang_file, charset_file = lang_file_default, charset_file_default
+    lang_file, charset_file = $LANG_FILE_DEFAULT, $CHARSET_FILE_DEFAULT
+  end
+  lang_console, charset_console, res =
+    self.resolve_alias_and_check( $LANG_CONSOLE, $CHARSET_CONSOLE )
+  if res == false then
+    # lang_console, charset_console = lang_console_default, charset_console_default
+    lang_console, charset_console = $LANG_CONSOLE_DEFAULT, $CHARSET_CONSOLE_DEFAULT
+  end
+
+  # メッセージモジュールをロード
+  if require_tecsgen_lib( "tecslib/messages/messages_console_#{lang_console}.rb", false ) == false then
+    require_tecsgen_lib( "tecslib/messages/messages_console_#{$LANG_CONSOLE_DEFAULT}.rb" )
+    $LANG_CONSOLE, $CHARSET_CONSOLE = $LANG_CONSOLE_DEFAULT, $CHARSET_CONSOLE_DEFAULT
+  else
+    $LANG_CONSOLE, $CHARSET_CONSOLE = lang_console, charset_console
+  end
+  if require_tecsgen_lib( "tecslib/messages/messages_file_#{lang_file}.rb", false ) == false then
+    require_tecsgen_lib( "tecslib/messages/messages_file_#{$LANG_FILE_DEFAULT}.rb" )
+    $LANG_FILE, $CHARSET_FILE = $LANG_FILE_DEFAULT, $CHARSET_FILE_DEFAULT
+  else
+    $LANG_FILE, $CHARSET_FILE = lang_file, charset_file
+  end
+
+  # Kconv クラスのための変数を設定
+  self.set_kconv_var 
+
+  dbgPrint "LANG_FILE=#{$LANG_FILE}.#{$CHARSET_FILE}, LANG_CONSOLE=#{$LANG_CONSOLE}.#{$CHARSET_CONSOLE}\n"
+  dbgPrint "KCODE_CDL=#{$KCODE_CDL}(#{$KCONV_CDL}) KCODE_CONSOLE=#{$KCODE_CONSOLE}(#{$KCONV_CONSOLE})\n"
+  dbgPrint "Ruby19_File_Encode=#{$Ruby19_File_Encode}\n"
+
+  #=== 単体テスト実行
+  if $unit_test then
+    print "unit test: set_lang_var\n"
+    require "kconv"
+    self.set_lang_var
+    print "#{$LANG_FILE} #{$LANG_CONSOLE}\n"
+    print "#{$CHARSET_FILE} #{$CHARSET_CONSOLE}\n"
+
+    $LANG_FILE, $CHARSET_FILE, res = self.resolve_alias_and_check( $LANG_FILE, $CHARSET_FILE )
+    print "#{$LANG_FILE} #{$CHARSET_FILE}, #{res}\n"
+  end
+end
+
+#= Console クラス
+# 文字コードを変換する
+class Console
+  def self.print str
+    if $b_no_kcode && $KCONV_CONSOLE == Kconv::BINARY then 
+      STDOUT.print str
+    else
+      STDOUT.print str.kconv( $KCONV_CONSOLE, $KCONV_TECSGEN )
+    end
+  end
+  def self.puts str
+    if $b_no_kcode && $KCONV_CONSOLE == Kconv::BINARY then 
+      STDOUT.puts str
+    else
+      STDOUT.puts str.kconv( $KCONV_CONSOLE, $KCONV_TECSGEN )
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tecsgen.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tecsgen.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tecsgen.rb	(revision 398)
@@ -0,0 +1,523 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+
+class TECSGEN
+
+  @@b_post_coded = false     # ポストコード生成開始後 true
+
+  #=== import パス (-I) を末尾に追加
+  # 既に登録済みであれば、追加しない
+  def self.add_import_path path
+    if $import_path.index( path ) == nil then
+      dbgPrint "add_import_path: '#{path}'\n"
+      $import_path << path
+    end
+  end
+
+  #=== EXEB 版のパスの調整
+  # 環境変数 TECSPATH が cygwin スタイルだと、exerb 版では扱えない
+  # $import_path と $TECSPATH を調整する
+  def self.adjust_exerb_path
+    if $IN_EXERB then
+      new_tecspath = cygpath( $tecspath, $tecspath )
+      pattern = /\A#{$tecspath}/
+      paths = []
+      $import_path.each{ |path|
+        # cygpath は '..' を簡約してしまうので、new_tecspath で置換する
+        # paths << cygpath( path, path )
+        paths << path.sub( pattern, new_tecspath )
+      }
+      $import_path = paths
+      $tecspath = new_tecspath
+    else
+      return
+    end
+  end
+
+  #=== $(TECSPATH) への置換
+  #path::String   : ENV[ 'TECSPATH' ] に一致する部分があれば、 "$(TECSPATH)" に置換
+  #b_global::Bool : true なら gsub で置換。false なら sub で置換
+  def self.subst_tecspath( path, b_global = false )
+    tp = $tecspath.dup
+    tp.gsub!( /\\/, "\\\\\\\\" )
+    pattern = /#{tp}/
+      substr = "$(TECSPATH)"
+    if b_global then
+      str =  path.gsub( pattern, substr )
+    else
+      str = path.sub( pattern, substr )
+    end
+    dbgPrint "subst_tecspath #{path}, #{str}\n"
+    return str
+  end
+
+  #=== path は絶対パスか?
+  #path:: String   :
+  # '/' または '$' で始まる場合、絶対パスと判定する
+  def self.is_absolute_path?( path )
+    pa = path[0..0]; pa2 = path[0..1]
+    if pa == '/' || pa == '$' || pa2 =~ /[A-Za-z]:/ then
+      res = true
+    else
+      res = false
+    end
+    dbgPrint "is_absolute( #{path} ) = #{res}  #{path[0]}\n"
+    return res
+  end
+
+  #=== tecsgen のデフォルトを設定
+  def self.set_default_config
+    Makefile::set_default_config
+  end
+
+  ###
+  #== Makefile.templ の出力内容を追加、変更するための操作
+  module Makefile
+    # 固定されている変数(add_var で変更できない)
+    @@fixed_vars = { :INCLUDES => nil, :DEFINES => nil, :TARGET_BASE => nil, :BASE_DIR => nil }
+    @@config_mode = false
+
+    @@vars = { }
+    @@vars_default = { }
+    @@var_comments = { }
+
+    @@objs = []
+    @@ldflags = ""
+    @@search_path = []
+    @@pre_tecsgen_target = []
+    @@post_tecsgen_target = []
+    @@lines = []
+
+    #=== OTHER_OBJS に追加する
+    def self.add_obj obj
+      @@objs << obj
+    end
+    #=== 追加する変数
+    # プラグインからは、デフォルト値を変更できる
+    # config により
+    def self.add_var( var, val, comment = nil )
+      if @@fixed_vars[ var ]
+        raise "fixed var '#{var}' cannot be changed"
+      end
+      if @@config_mode then
+        @@vars_default[ var.to_sym ] = val
+        @@var_comments_default[ var.to_sym ] = comment
+      else
+        @@vars[ var.to_sym ] = val
+        @@var_comments[ var.to_sym ] = comment
+      end
+    end
+    #=== LDFLAGS に追加する
+    def self.add_ldflag ldflag
+      @@ldflags += " " + ldflag
+    end
+    #=== サーチパスを追加する
+    # CFLAGS, vpath に追加する
+    def self.add_search_path path
+      @@search_path << path
+    end
+    #=== PRE_TECSGEN_TARGET に追加する
+    # PRE_TECSGEN_TARGET に target を追加する
+    def self.add_pre_tecsgen_target target
+      @@pre_tecsgen_target << pre_tecsgen_target
+    end
+    #=== POST_TECSGEN_TARGET に追加する
+    # POST_TECSGEN_TARGET に target を追加する
+    def self.add_post_tecsgen_target target
+      @@post_tecsgen_target << pre_tecsgen_target
+    end
+    #=== 追加する変数
+    def self.add_line( line )
+      @@lines << line.to_s + "\n"
+    end
+
+    def self.get_objs  # Array を返す
+      return @@objs.uniq
+    end
+    def self.get_vars  # Array を返す
+      if RUBY_VERSION >= '1.9' then
+        return (@@vars.keys + @@vars_default.keys).sort.uniq
+      else
+        # V1.8 では、Symbol の sort ができないので、一旦 String に置換する
+        return (@@vars.keys + @@vars_default.keys).map{|s| s.to_s }.sort.uniq.map!{|s| s.to_sym }
+      end
+    end
+    def self.get_var_val( var )
+      return @@vars[ var ] ? @@vars[ var ] : @@vars_default[ var ]
+    end
+    def self.get_var_comment( var )
+      return @@var_comments[ var ]
+    end
+    def self.get_ldflags  # String を返す
+      return @@ldflags
+    end
+    def self.get_search_path  # Array を返す
+      return @@search_path.uniq
+    end
+    def self.get_pre_tecsgen_target  # Array を返す
+      return @@pre_tecsgen_target.uniq
+    end
+    def self.get_post_tecsgen_target  # Array を返す
+      return @@post_tecsgen_target.uniq
+    end
+    def self.get_lines  # 付加する行を得る
+      return @@lines.uniq
+    end
+
+    #=== TECSGEN のデフォルト設定を行う
+    # Makefile 
+    # @@fixed_vars で定義されている変数は、変更できず、定数定義されている
+    def self.set_default_config
+      add_var( "TARGET", "$(TARGET_BASE).exe", "default target name"  )
+      add_var( "TECSGEN", "tecsgen", "default TECS generator"  )
+      add_var( "TIMESTAMP", "$(GEN_DIR)/tecsgen.timestamp", "Time Stamp"  )
+      add_var( "CC", "gcc", "default C Compiler"  )
+      add_var( "CFLAGS", '$(INCLUDES) $(DEFINES) -D  "Inline=static inline"', "default C Compiler options"  )
+      add_var( "LD", "gcc", "default Liknker"  )
+      add_var( "LDFLAGS", @@ldflags, "default Liknker Options"  )
+      add_var( "SRC_DIR", "$(BASE_DIR)/src", "default source directory" )
+      add_var( "_TECS_OBJ_DIR", "$(GEN_DIR)/", "default relocatable object (.o) directory" )
+    end
+  end
+
+  def self.get_argv
+    ARGV
+  end
+
+  #------ TECSGEN CDL analyze and generate ------#
+
+  def syntax_analisys argv
+    # ルート namespace (region) を生成
+    @root_namespace = Region.new("::")
+
+    ####  構文解析 (post コードを除く) ####
+    # すべての cdl を import する
+    argv.each{ |f|
+      dbgPrint( "## Import: #{f}\n")
+      Import.new( f, false, false )
+    }
+
+    # すべての構文解釈が完了したことの報告
+    #   実際には、後からプラグインの生成する CDL のパースが行われる
+    #   エラー行数の決定方法の変更のために行う
+    Generator.end_all_parse
+    dbgPrint( "## End all parse (except Post Code)\n")
+  end # syntax_analisys
+
+  #=== TECSGEN#semantics_analisys_1
+  # semantics check. only cells here
+  # other objects (signature, celltype, typedef, etc ) are checked while syntax analisys
+  def semantics_analisys_1
+    ####  意味解析１ (post コードを除く) ####
+    dbgPrint( "## Creating reverse join \n")
+    Cell.create_reverse_join
+
+    DescriptorType.check_signature
+    Signature.set_descriptor_list
+    Celltype.check_dynamic_join
+
+    #0 set_definition_join は2回呼び出される（1回目）
+    dbgPrint( "## Checking all join\n")
+    @root_namespace.set_definition_join
+    # @root_namespace.set_require_join                   ### いったん見合わせ。重複エラーを見逃す
+    # through プラグインで生成されたセルにも require も生成できる (set_definition_join の後ろで実施)
+
+    ####  post コードの生成と構文解析 ####
+    @@b_post_coded = true     # ポストコード生成開始後 true
+    # 引数がなければ、プラグインのポストコードを出力しない
+    if ARGV.length > 0 then
+      dbgPrint( "## Generating Post Code\n")
+      # プラグインのポストコードの出力と import
+      tmp_file_name = "#{$gen}/tmp_plugin_post_code.cdl"
+      file = nil
+      begin
+        file = CFile.open( tmp_file_name, "w" )
+      rescue
+        Generator.error( "G9999 fail to create #{tmp_file_name}" )
+      end
+
+      if file then
+        # through プラグインのポストコード生成
+        PluginModule.gen_plugin_post_code file
+
+        begin
+          file.close
+        rescue
+          Generator.error( "G9999 fail to close #{tmp_file_name}" )
+        end
+        dbgPrint( "## Import Post Code\n")
+        Import.new( "#{tmp_file_name}" )
+      end
+    end
+
+    ####  意味解析１ (post コード) ####
+    dbgPrint( "## Creating reverse join (for post code) \n")
+    Cell.create_reverse_join
+
+    # Join の定義の設定とチェック
+    #0 # 前方参照対応
+    #0 set_definition_join は2回呼び出される（2回目）  post_code で生成された
+    dbgPrint( "## Checking all join (for cells generated by Post Code\n")
+    @root_namespace.set_definition_join
+    @root_namespace.set_max_entry_port_inner_cell
+
+    dbgPrint( "## Set require join\n")
+    @root_namespace.set_require_join   # mikan post の前にも
+    # ポストコードで生成されたセルの require のjoin を生成
+    # mikan require で through が適用されて、ポストコードが必要となっても出力されない
+  end # semantics_analisys_1
+
+  def semantics_analisys_2
+    ####  意味解析２ ####
+    Cell.make_cell_list2
+    dbgPrint( "## Set fixed join\n")
+    Cell.create_reverse_require_join
+    # create_reverse_require_join は set_detinition_join に埋め込むことができない
+        # namespace に依存しない出現順で行う
+        # mikan through プラグインが適用されポストコードに影響を与える場合が考慮できていない
+        # mikan post code に影響のあるものであれば、早くに reverse_require_join の結合が必要
+    dbgPrint( "## Setting port reference count\n")
+    @root_namespace.set_port_reference_count
+
+    dbgPrint( "## Checking all join\n")
+    @root_namespace.check_join
+
+    # mikan プラグインで生成されたコンポーネントの set_def_and_check_join
+
+    dbgPrint( "## Checking referenced but undefined cell\n")
+    @root_namespace.check_ref_but_undef
+  end  #  semantics_analisys_2
+
+  def optimize_and_generate
+    #### Region link root ごとにオプティマイズおよび生成 ####
+    Region.get_link_roots.each { |region|
+
+      n_cells = region.get_n_cells
+
+      dbgPrint "#{region.get_name} has #{n_cells} cells\n"
+      if $verbose
+        print "=====================================\n"
+        print "=== Region.path_str: #{region.get_namespace_path.get_path_str}\n"
+        print "=====================================\n"
+      else
+        dbgPrint "Region.path_str: #{region.get_namespace_path.get_path_str}\n"
+      end
+
+      if $region_list.length > 0 then
+        if $region_list[ region.get_namespace_path.get_path_str ] then
+          $region_list[ region.get_namespace_path.get_path_str ] = false
+        else
+          next
+        end
+      end
+
+      # セルが一つもなければ生成しない
+      # セルの生成がない場合
+      if region.get_n_cells == 0 then
+        if $region_list.length > 0 then
+          Generator.warning( "W9999 $1: specified to generate but has no cell", region.get_name )
+        end
+        if region != @root_namespace then
+          next
+        end
+      end
+
+      $generating_region = region
+      if Region.get_link_roots.length > 1 then
+        if region.get_name == "::" then
+          $gen = $gen_base
+        else
+          $gen = $gen_base + "/" + region.get_global_name.to_s
+          begin
+            if ! File.directory?( $gen ) then
+              Dir.mkdir( $gen )
+            end
+          rescue
+            print( "Cannot mkdir #{$gen}\n" )
+            exit 1
+          end
+        end
+      else
+        $gen = $gen_base
+      end
+
+      dbgPrint( "## Unset optimize variables\n")
+      @root_namespace.reset_optimize   # 最適化をリセットする
+
+      if Generator.get_n_error == 0 then
+        # エラーが発生していたら、設定しない
+        dbgPrint( "## Set cell id\n")
+        @root_namespace.set_cell_id_and_domain      # セルの ID とドメイン情報を設定（linkunit 毎に0からつける）
+
+        # エラーが発生していたら、最適化は実施しない
+        if ! $unopt then
+          dbgPrint( "## Optimizing: Link Region=#{@root_namespace.get_name}\n")
+          @root_namespace.optimize
+        end
+      end
+
+      if $show_tree then
+        # エラーが発生していても表示（エラー発生時は最適化されていないので注意）
+        print "##### show_tree LinkRegion=#{region.get_name} #####\n"
+        @root_namespace.show_tree(0)
+        print "##### END       LinkRegion=#{region.get_name} #####\n\n"
+      end
+
+      # 構文解釈、意味解析でエラー発生していたら、コード生成をしない
+      if Generator.get_n_error != 0 then
+        print_report
+        exit 1
+      end
+
+      #### コード生成 ####
+      begin
+        dbgPrint( "## Generating: Link Region=#{@root_namespace.get_name}\n")
+        @root_namespace.generate
+        dbgPrint( "## Generating Post: Link Region=#{@root_namespace.get_name}\n")
+        @root_namespace.generate_post
+      rescue
+        # 通常ここへは来ない (generate, generate_post で処置される)
+        Generator.error( "G9999 fail to generate" )
+      end
+    }
+  end # optimize_and_generate
+
+  def finalize
+    dbgPrint( "## Generating XML\n")
+    # Region.gen_xml @root_namespace
+    ## 
+    # Namespace.gen_XML  @root_namespace
+
+    $region_list.each{ |region_path_str, val|
+      if val == true then
+        Generator.warning( "W9999 $1: not link root, -G ignored", region_path_str )
+      end
+    }
+
+    # update する
+    # APPFile で生成されたファイルは、もし変化があれば、ここで更新する
+    # コード生成段階でエラーが発生すれば、更新しない
+    # CFile で生成されたものは、更新されている
+    if Generator.get_n_error == 0 then
+      begin
+        AppFile.update
+      rescue => evar
+        Generator.error( "G9999 Fail to update. (error occurred while renaming generated files)" )
+        print_exception( evar )
+      end
+    end
+
+    print_report
+    if Generator.get_n_error != 0 then
+      STDERR.print "error occurred while generating. some file can be corrupt in #{$gen_base}\n"
+      exit 1
+    end
+
+    open( "#{$gen_base}/tecsgen.timestamp", "w" ){|io|}
+  end # finalize
+
+  def dump_tecsgen_rbdmp
+    dbgPrint "dump_tecsgen_rbdmp 0:\n"
+    #### unjoin_plugin 後に行う必要があるため、コード生成後にダンプを行う
+    #### Region link root ごとにオプティマイズしてダンプ ####
+    Namespace.get_root.unjoin_plugin
+    Namespace.get_root.find_plugin 0, []
+
+    Region.get_link_roots.each { |region|
+      dbgPrint "dump_tecsgen_rbdmp 1: Region.path_str: #{region.get_namespace_path.get_path_str}\n"
+
+      n_cells = region.get_n_cells
+
+      if $region_list.length > 0 then
+        if $region_list[ region.get_namespace_path.get_path_str ] == false then
+          $region_list[ region.get_namespace_path.get_path_str ] = true
+        else
+          next
+        end
+      end
+
+      dbgPrint "dump_tecsgen_rbdmp 2: Region.path_str: #{region.get_namespace_path.get_path_str}\n"
+      # セルが一つもなければ生成しない
+      # セルの生成がない場合
+      if region.get_n_cells == 0 then
+        # if $region_list.length > 0 then
+        #   Generator.warning( "W9999 $1: specified to generate but has no cell", region.get_name )
+        # end
+        if region != @root_namespace then
+          next
+        end
+      end
+
+      dbgPrint "dump_tecsgen_rbdmp 3: Region.path_str: #{region.get_namespace_path.get_path_str}\n"
+      $generating_region = region
+      if Region.get_link_roots.length > 1 then
+        if region.get_name == "::" then
+          $gen = $gen_base
+        else
+          $gen = $gen_base + "/" + region.get_global_name.to_s
+        end
+      else
+        $gen = $gen_base
+      end
+
+      dbgPrint "dump_tecsgen_rbdmp 4: Region.path_str: #{region.get_namespace_path.get_path_str}\n"
+      dbgPrint( "## Unset optimize variables\n")
+      @root_namespace.reset_optimize   # 最適化をリセットする
+
+      #  if Generator.get_n_error == 0 then
+      #   # エラーが発生していたら、ここへは来ない
+         dbgPrint( "## Set cell id\n")
+        @root_namespace.set_cell_id_and_domain      # セルの ID とドメイン情報を設定（linkunit 毎に0からつける）
+
+        # エラーが発生していたら、最適化は実施しない
+        if ! $unopt then
+          dbgPrint( "## Optimizing: Link Region=#{@root_namespace.get_name}\n")
+          @root_namespace.optimize
+        end
+      # end
+      dbgPrint "dump_tecsgen_rbdmp final: Region.path_str: #{region.get_namespace_path.get_path_str}\n"
+      File.write( "#{$gen}/tecsgen.rbdmp", Marshal.dump(Namespace.get_root) )
+    }
+  end
+  
+  def self.post_coded?
+    @@b_post_coded
+  end
+end # class TECSGEN
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tecsinfo.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tecsinfo.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tecsinfo.rb	(revision 398)
@@ -0,0 +1,862 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2017-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# TECS 情報セルの生成
+module TECSInfo
+  # region は Link root のこと
+  def self.print_info f, region
+    # p "region: "+ region.get_name.to_s
+    nest = region.gen_region_str_pre f
+    indent0 = "    " * nest
+    indent = "    " * ( nest + 1 )
+    f.print <<EOT
+#{indent0}region rTECSInfo {
+EOT
+    Type.reset_print_info
+
+    # mikan 全部生成するのではなく、region 下のセルのセルタイプと、そこから参照されるシグニチャ、セルタイプに限定して出力すべき
+    # しかし、意味解析後に出力するため、これは容易ではない．最適化とコード生成は、リンクルートごとに行われる．
+    Namespace.print_info f, indent
+    region.get_link_root.print_info f, indent
+
+    f.print "\n#{indent}/*** TYPE information cell ***/\n"
+    Type.print_info_post f, indent
+
+    f.print "\n#{indent}/*** TECS information cell ***/\n"
+    f.print <<EOT
+#{indent}cell nTECSInfo::tTECSInfoSub TECSInfoSub {
+#{indent}    cNamespaceInfo = _RootNamespaceInfo.eNamespaceInfo;
+#{indent}    cRegionInfo    = _LinkRootRegionInfo.eRegionInfo;
+#{indent}} /* TECSInfoSub */;
+#{indent0}}; /* rTECSInfo */
+EOT
+    region.gen_region_str_post f
+  end
+end
+
+class Namespace
+  # RootRegion と LinkRegion は同じ Region クラスのオブジェクトである
+  # 子ネームスペースは Namespace クラスの、子リージョンは Region クラスのオブジェクトである
+  # これは、意味解析段階で呼び出されるため、リンクユニットごとに出しわけることができない
+  # 出しわけるには、2パスにする必要がある
+  def print_info_ns_sub f, indent
+    if @name == "::" then
+      name = "_Root"
+    else
+      name = @global_name
+    end
+    f.print "\n#{indent}/*** #{get_namespace_path} namespace information cell ***/\n"
+    f.print <<EOT
+#{indent}cell nTECSInfo::tNamespaceInfo #{name}NamespaceInfo{
+#{indent}    name = "#{@name}";
+EOT
+    if @signature_list.length > 0 then
+      f.print "\n#{indent}    /* SIGNATURE info */\n"
+    end
+    @signature_list.each{ |sig|
+      f.print <<EOT
+#{indent}    cSignatureInfo[] = #{sig.get_global_name}SignatureInfo.eSignatureInfo;
+EOT
+    }
+    if @celltype_list.length > 0 then
+      f.print "\n#{indent}    /* CELLTYPE info */\n"
+    end
+    @celltype_list.each{ |ct|
+      if ct.get_cell_list.length > 0 then
+        f.print <<EOT
+#{indent}    cCelltypeInfo[] = #{ct.get_global_name}CelltypeInfo.eCelltypeInfo;
+EOT
+      end
+    }
+    if @namespace_list.length > 0 then
+      f.print "\n#{indent}    /* NAMESPACE info */\n"
+    end
+    @namespace_list.each{ |ns|
+      if ns.instance_of? Namespace then
+        f.print <<EOT
+#{indent}    cNamespaceInfo[] = #{ns.get_global_name}NamespaceInfo.eNamespaceInfo;
+EOT
+      end
+    }
+    f.print <<EOT
+#{indent}};   /* cell nTECSInfo::tNamespaceInfo #{name}NamespaceInfo */
+EOT
+  end
+
+  def print_info_ns f, indent
+    # p "print_info: #{self.get_global_name}"
+    print_info_ns_sub f, indent
+    @signature_list.each { |sig|
+      sig.print_info f, indent
+    }
+    @celltype_list.each { |ct|
+      if ct.get_cell_list.length > 0 then
+        ct.print_info f, indent
+      end
+    }
+    @namespace_list.each { |ns|
+      if ns.instance_of? Namespace then   # region を含めない
+        ns.print_info_ns f, indent
+      end
+    }
+  end
+
+  def self.print_info( f, indent )
+    @@root_namespace.print_info_ns f, indent
+  end
+
+  #=== Namespace# 構造体メンバーのオフセット定義
+  def print_struct_define f
+    f.print "\n/***** Offset of members of structures  *****/\n"
+    @struct_tag_list.get_items.each{ |tag, sttype|
+      # print "sttype: #{tag.get_name} #{sttype}\n"
+      tag.get_members_decl.get_items.each{ |decl|
+        f.printf "#define OFFSET_OF_%-30s  (%s)\n",
+                 "#{tag.get_ID_str}_#{decl.get_name}",
+                 "(uint32_t)(intptr_t)&(((#{tag.get_type_str}#{tag.get_type_str_post}*)0)->#{decl.get_name})"
+        f.printf "#define PLACE_OF_%-30s  (%s)\n",
+                 "#{tag.get_ID_str}_#{decl.get_name}",
+                 "VARDECL_PLACE_STRUCT"
+      }
+    }
+  end
+
+  def print_celltype_define_offset f
+    @celltype_list.each { |ct|
+      if ct.get_cell_list.length > 0 then
+        ct.print_define_offset f
+      end
+    }
+    @namespace_list.each { |ns|
+      if ns.instance_of? Namespace then   # region を含めない
+        ns.print_celltype_define_offset f
+      end
+    }
+  end
+
+  def print_celltype_define f
+    @celltype_list.each { |ct|
+      if ct.get_cell_list.length > 0 then
+        ct.print_celltype_define f
+      end
+    }
+    @namespace_list.each { |ns|
+      if ns.instance_of? Namespace then   # region を含めない
+        ns.print_celltype_define f
+      end
+    }
+  end
+
+  def print_call_define f
+    @celltype_list.each { |ct|
+      if ct.get_cell_list.length > 0 then
+        ct.print_call_define f
+      end
+    }
+    @namespace_list.each { |ns|
+      if ns.instance_of? Namespace then   # region を含めない
+        ns.print_call_define f
+      end
+    }
+  end
+
+  def print_entry_define f
+    @celltype_list.each { |ct|
+      if ct.get_cell_list.length > 0 then
+        ct.print_entry_define f
+      end
+    }
+    @namespace_list.each { |ns|
+      if ns.instance_of? Namespace then   # region を含めない
+        ns.print_entry_define f
+      end
+    }
+  end
+end
+
+class Region
+  def print_info_region_sub f, indent
+    if get_link_root == self then
+      name = "_LinkRoot"
+    else
+      name = @global_name
+    end
+    # p "region:#{get_name}"
+    f.print "\n#{indent}/*** #{get_namespace_path} region information cell ***/\n"
+    f.print <<EOT
+#{indent}cell nTECSInfo::tRegionInfo #{name}RegionInfo{
+#{indent}    name = "#{@name}";
+EOT
+    @cell_list.each{ |cell|
+        # print "cell class="+cell.get_celltype.class.name+", " + cell.get_celltype.get_name.to_s + " 1\n"
+      if ! cell.exclude_info? then
+        # print "cell class="+cell.get_celltype.class.name+", " + cell.get_celltype.get_name.to_s + " 2\n"
+        f.print "#{indent}    cCellInfo[] = #{cell.get_global_name}CellInfo.eCellInfo;\n"
+      end
+    }
+    @namespace_list.each { |region|
+      if region.instance_of? Region then
+        f.print "#{indent}    cRegionInfo[] = #{region.get_global_name}RegionInfo.eRegionInfo;\n"
+       end
+    }
+    f.print "#{indent}};\n"
+    @cell_list.each{ |cell|
+      if ! cell.exclude_info? then
+        cell.print_info f, indent
+      end
+    }
+  end
+
+  def print_info_region( f, indent )
+    self.print_info_region_sub f, indent
+    @namespace_list.each { |region|
+      if region.instance_of? Region then
+        region.print_info_region f, indent
+      end
+    }
+  end
+  
+  def print_info( f, indent )
+    #p "print_info: #{self.get_global_name}"
+    self.print_info_region f, indent
+  end
+
+  def self.print_cell_define f
+    region.get_link_root.print_cell_define f
+    region.get_link_root.get_region{ |region|
+      if region.instance_of? Region then
+        region.print_cell_define_offset f
+      end
+
+    }
+  end
+
+  def print_cell_define f
+    ct_list = {}
+    @cell_list.each{ |cell|
+      next if cell.exclude_info_factory?
+      ct_list[ cell.get_celltype ] = true
+    }
+    f.print "#define TOPPERS_CB_TYPE_ONLY\n"
+    ct_list.each{ |ct, val|
+      f.print "#include \"#{ct.get_global_name}_tecsgen.h\"\n"
+    }
+    f.print "\n"
+    @cell_list.each{ |cell|
+      next if cell.exclude_info_factory?
+      name_array = cell.get_celltype.get_name_array cell
+      if cell.get_celltype.has_CB?
+        cb = "(void*)#{name_array[8]}"
+        cb_proto = "extern #{cell.get_celltype.get_global_name}_CB #{name_array[4]};\n"
+      else
+        cb = "0"
+        cb_proto = ""
+      end
+      if cell.get_celltype.has_INIB?
+        inib = "(void*)&#{name_array[5]}"
+        inib_proto = "extern #{cell.get_celltype.get_global_name}_INIB #{name_array[11]};\n"
+      else
+        inib = "0"
+        inib_proto = ""
+      end
+      if ! cell.exclude_info_factory? then
+        f.print <<EOT
+#{cb_proto}#define  #{cell.get_global_name}__CBP   #{cb}
+#{inib_proto}#define  #{cell.get_global_name}__INIBP #{inib}
+EOT
+      end
+    }
+    @namespace_list.each { |region|
+      if region.instance_of? Region then
+        region.print_cell_define f
+      end
+    }
+  end
+
+  def print_entry_descriptor_define f
+    @cell_list.each{ |cell|
+      next if cell.exclude_info_factory?
+
+      signatures = {}
+      cell.get_celltype.get_port_list.each{ |port|
+        next if port.get_port_type != :ENTRY
+
+        if signatures[ port.get_signature ] == nil then
+          f.print "#include \"#{port.get_signature.get_global_name}_tecsgen.h\"\n"
+        end
+        if cell.get_celltype.get_global_name == :nTECSInfo_tRawEntryDescriptorInfo then
+          f.print "const struct tag_#{cell.get_celltype.get_global_name}_#{port.get_name}_DES "
+          f.print "#{cell.get_global_name}_#{port.get_name}_des;\n"
+        else
+          f.print "extern struct tag_#{port.get_signature.get_global_name}_VDES "
+          f.print "#{cell.get_global_name}_#{port.get_name}_des;\n"
+        end
+      }
+    }
+    @namespace_list.each { |region|
+      if region.instance_of? Region then
+        region.print_entry_descriptor_define f
+      end
+    }
+  end
+end
+
+class Celltype
+  def print_info f, indent
+    f.print <<EOT
+#{indent}cell nTECSInfo::tCelltypeInfo #{@global_name}CelltypeInfo {
+#{indent}    name             = "#{@name}";
+#{indent}    b_singleton      = #{@singleton};
+#{indent}    b_IDX_is_ID_act  = C_EXP( "#{@global_name}__IDX_is_ID_act" );
+#{indent}    sizeOfCB         = C_EXP( "#{@global_name}__sizeOfCB" );
+#{indent}    sizeOfINIB       = C_EXP( "#{@global_name}__sizeOfINIB" );
+#{indent}    n_cellInLinkUnit = C_EXP( "#{@global_name}__NCELLINLINKUNIT" );
+#{indent}    n_cellInSystem   = #{@cell_list.length};
+EOT
+    @port.each{ |port|
+      if port.get_port_type == :ENTRY then
+        f.print <<EOT
+#{indent}    cEntryInfo[]    = #{@global_name}_#{port.get_name}EntryInfo.eEntryInfo;
+EOT
+      end
+    }
+    @port.each{ |port|
+      if port.get_port_type == :CALL then
+        f.print <<EOT
+#{indent}    cCallInfo[]     = #{@global_name}_#{port.get_name}CallInfo.eCallInfo;
+EOT
+      end
+    }
+    @attribute.each{ |decl|
+      f.print <<EOT
+#{indent}    cAttrInfo[]     = #{@global_name}_#{decl.get_name}VarDeclInfo.eVarDeclInfo;
+EOT
+    }
+    @var.each{ |decl|
+      f.print <<EOT
+#{indent}    cVarInfo[]      = #{@global_name}_#{decl.get_name}VarDeclInfo.eVarDeclInfo;
+EOT
+    }
+    f.print <<EOT
+#{indent}};
+EOT
+    @port.each{ |port|
+      if port.get_port_type == :ENTRY then
+        port.print_info f, @global_name, indent
+      end
+    }
+    @port.each{ |port|
+      if port.get_port_type == :CALL then
+        port.print_info f, @global_name, indent
+      end
+    }
+    @attribute.each{ |decl|
+      decl.print_info f, @global_name, indent, :DECLTYPE_ATTR
+    }
+    @var.each{ |decl|
+      decl.print_info f, @global_name, indent, :DECLTYPE_VAR
+    }
+  end
+
+  def print_define_offset f
+    # intptr_t に一回キャストするのは 64bit 版を考量してのこと．しかし 32bit としているので 4GB を超える構造体等は扱えない
+    if @n_cell_gen > 0 then
+      f.print <<EOT
+
+#include "#{@global_name}_tecsgen.h"
+EOT
+      @attribute.each{ |decl|
+        if has_INIB? then
+          inib_cb = "INIB"
+        else
+          inib_cb = "CB"
+        end
+        if ! decl.is_omit? then
+          offset = "(uint32_t)(intptr_t)&(((#{@global_name}_#{inib_cb}*)0)->#{decl.get_name})"
+          place = inib_cb
+        else
+          offset = "0xffffffff"
+          place = "NON"
+        end
+        f.printf "#define OFFSET_OF_%-30s  (%s)\n", "#{@global_name}_#{decl.get_name}", offset
+        f.printf "#define PLACE_OF_%-30s  VARDECL_PLACE_%s\n", "#{@global_name}_#{decl.get_name}", place
+      }
+      @var.each{ |decl|
+        if decl.get_size_is && has_INIB? then
+          inib_cb = "INIB"
+        else
+          inib_cb = "CB"
+        end
+        place = inib_cb
+        f.printf "#define OFFSET_OF_%-30s  (%s)\n", "#{@global_name}_#{decl.get_name}", "(uint32_t)(intptr_t)&(((#{@global_name}_#{inib_cb}*)0)->#{decl.get_name})"
+        f.printf "#define PLACE_OF_%-30s  VARDECL_PLACE_%s\n", "#{@global_name}_#{decl.get_name}", place
+      }
+    else
+      f.print <<EOT
+
+// #include "#{@global_name}_tecsgen.h"   // no cell exist
+EOT
+      # 生成されないセルタイプ
+      @attribute.each{ |decl|
+        f.printf "#define OFFSET_OF_%-30s  (%s)\n", "#{@global_name}_#{decl.get_name}", "0xffffffff"
+        f.printf "#define PLACE_OF_%-30s   VARDECL_PLACE_NON\n", "#{@global_name}_#{decl.get_name}"
+      }
+      @var.each{ |decl|
+        f.printf "#define OFFSET_OF_%-30s  (%s)\n", "#{@global_name}_#{decl.get_name}", "0xffffffff"
+        f.printf "#define PLACE_OF_%-30s   VARDECL_PLACE_NON\n", "#{@global_name}_#{decl.get_name}"
+      }
+    end
+  end
+
+  def print_celltype_define f
+    if has_INIB? then
+      size_INIB = "(sizeof(#{@global_name}_INIB))"
+    else
+      size_INIB = "(0)"
+    end
+    if has_CB? then
+      size_CB = "(sizeof(#{@global_name}_CB))"
+    else
+      size_CB   = "(0)"
+    end
+
+    if @n_cell_gen > 0 then
+      f.printf "\n#include \"#{@global_name}_tecsgen.h\"\n"
+      f.printf "#define %-50s (#{@idx_is_id_act})\n",     "#{@global_name}__IDX_is_ID_act"
+      f.printf "#define %-50s (#{size_CB})\n",            "#{@global_name}__sizeOfCB"
+      f.printf "#define %-50s (#{size_INIB})\n",          "#{@global_name}__sizeOfINIB"
+      f.printf "#define %-30s (%d)\n", "#{@global_name}__NCELLINLINKUNIT", @n_cell_gen
+    else
+      f.printf "#define %-50s (false)\n",                 "#{@global_name}__IDX_is_ID_act"
+      f.printf "#define %-50s (0)\n",                     "#{@global_name}__sizeOfCB"
+      f.printf "#define %-50s (0)\n",                     "#{@global_name}__sizeOfINIB"
+      f.printf "#define %-30s (%d)\n", "#{@global_name}__NCELLINLINKUNIT", @n_cell_gen
+    end
+  end
+
+  def print_call_define f
+    if @n_cell_gen > 0 then
+      f.print <<EOT
+
+#include "#{@global_name}_tecsgen.h"
+EOT
+    else
+      f.print <<EOT
+
+// #include "#{@global_name}_tecsgen.h"   // no cell exist
+EOT
+    end
+    @port.each{ |port|
+      next if port.get_port_type == :ENTRY
+      if port.is_omit? || ( port.is_VMT_useless? && port.is_cell_unique? ) || @n_cell_gen == 0 then
+        place = "CALL_PLACE_NON"
+      elsif port.is_dynamic?
+        if port.get_array_size then
+          place = "CALL_PLACE_INIB_DES"
+        else
+          place = "CALL_PLACE_CB_DES"
+        end
+      elsif ! has_INIB? then
+        if port.is_VMT_useless? then
+          place = "CALL_PLACE_CB_IDX"
+        else
+          place = "CALL_PLACE_CB_DES"
+        end
+      else
+        if port.is_VMT_useless? then
+          place = "CALL_PLACE_INIB_IDX"
+        else
+          place = "CALL_PLACE_INIB_DES"
+        end
+      end
+      if ( port.is_VMT_useless? && port.is_cell_unique? ) || port.is_omit? || @n_cell_gen == 0 then
+        offset = "0xffffffff"
+      else
+        if port.is_dynamic? || ! has_INIB? then
+          cb_inib = "CB"
+        else
+          cb_inib = "INIB"
+        end
+        offset = "(uint32_t)(intptr_t)&((#{@global_name}_#{cb_inib}*)0)->#{port.get_name}"
+      end
+      array_size = port.get_array_size
+      if array_size == "[]" then
+        array_size = "0xffffffff"
+      elsif array_size == nil then
+        array_size = "0"
+      end
+
+      f.printf "#define %-50s (#{offset})\n",                   "#{@global_name}_#{port.get_name}__offset"
+      f.printf "#define %-50s (#{array_size})\n",               "#{@global_name}_#{port.get_name}__array_size"
+      f.printf "#define %-50s (#{place})\n",                    "#{@global_name}_#{port.get_name}__place"
+      f.printf "#define %-50s (#{port.is_VMT_useless?})\n",     "#{@global_name}_#{port.get_name}__b_VMT_useless"
+      f.printf "#define %-50s (#{port.is_skelton_useless?})\n", "#{@global_name}_#{port.get_name}__b_skelton_useless"
+      f.printf "#define %-50s (#{port.is_cell_unique?})\n",     "#{@global_name}_#{port.get_name}__b_cell_unique"
+    }
+  end
+
+  def print_entry_define f
+    @port.each{ |port|
+      next if port.get_port_type == :CALL
+      array_size = port.get_array_size
+      if array_size == "[]" then
+        array_size = "0xffffffff"
+      elsif array_size == nil then
+        array_size = "0"
+      end
+
+      f.printf "#define %-50s (#{array_size})\n",               "#{@global_name}_#{port.get_name}__array_size"
+    }
+  end
+end
+
+class Port
+  def print_info f, ct_global, indent
+    return if @signature == nil     # signature not found error in cdl
+    if @port_type == :ENTRY then
+      f.print <<EOT
+#{indent}cell nTECSInfo::tEntryInfo #{ct_global}_#{@name}EntryInfo{
+#{indent}    name            = "#{@name}";
+#{indent}    cSignatureInfo  = #{@signature.get_global_name}SignatureInfo.eSignatureInfo;
+#{indent}    b_inline        = #{@b_inline};
+#{indent}    array_size      = C_EXP( "#{ct_global}_#{@name}__array_size" );
+#{indent}};
+EOT
+    else
+      f.print <<EOT
+#{indent}cell nTECSInfo::tCallInfo #{ct_global}_#{@name}CallInfo{
+#{indent}    name            = "#{@name}";
+#{indent}    cSignatureInfo  = #{@signature.get_global_name}SignatureInfo.eSignatureInfo;
+#{indent}    offset            = C_EXP( "#{ct_global}_#{@name}__offset" );
+#{indent}    array_size        = C_EXP( "#{ct_global}_#{@name}__array_size" );
+#{indent}    b_optional        = #{@b_optional};
+#{indent}    b_omit            = #{@b_omit};
+#{indent}    b_dynamic         = #{@b_dynamic};
+#{indent}    b_ref_desc        = #{@b_ref_desc};
+#{indent}    b_allocator_port  = #{@allocator_port!=nil ? true : false};
+#{indent}    b_require_port    = #{@b_require};
+#{indent}    place             = C_EXP( "#{ct_global}_#{@name}__place" );
+#{indent}    b_VMT_useless     = C_EXP( "#{ct_global}_#{@name}__b_VMT_useless" );
+#{indent}    b_skelton_useless = C_EXP( "#{ct_global}_#{@name}__b_skelton_useless" );
+#{indent}    b_cell_unique     = C_EXP( "#{ct_global}_#{@name}__b_cell_unique" );
+
+#{indent}};
+EOT
+    end
+  end
+end
+
+class Cell
+  def print_info f, indent
+    if exclude_info? then
+      return
+    end
+    f.print <<EOT
+
+#{indent}/*** #{@global_name} cell information ****/
+#{indent}cell nTECSInfo::tCellInfo #{@global_name}CellInfo {
+#{indent}    name            = "#{@name}";
+#{indent}    cbp             = C_EXP( \"#{@global_name}__CBP\" );
+#{indent}    inibp           = C_EXP( \"#{@global_name}__INIBP\" );
+#{indent}    cCelltypeInfo   = #{@celltype.get_global_name}CelltypeInfo.eCelltypeInfo;
+EOT
+    @celltype.get_port_list.each{ |port|
+      next if port.get_port_type != :ENTRY
+
+      f.print <<EOT
+#{indent}    cRawEntryDescriptor[] = #{@global_name}_#{port.get_name}RawEntryDescriptorInfo.eRawEntryDescriptor;
+EOT
+    }
+    f.print "#{indent}};\n"
+
+    # RawEntryDescriptorInfo cells
+    @celltype.get_port_list.each{ |port|
+      next if port.get_port_type != :ENTRY
+
+      size = port.get_array_size
+      if size == nil then
+        size = 1
+      elsif size == "[]" then
+        size = @entry_array_max_subscript[ port ]
+      end
+      if ! port.is_omit? then
+        red = "C_EXP( \"&#{@global_name}_#{port.get_name}_des\" )"
+      else
+        red = "(void *)0"
+      end
+      # mikan 受け口配列
+      f.print <<EOT
+#{indent}cell nTECSInfo::tRawEntryDescriptorInfo #{@global_name}_#{port.get_name}RawEntryDescriptorInfo {
+#{indent}   size = #{size};
+#{indent}   rawEntryDescriptor = { #{red} };
+EOT
+#  #{indent}   cEntryInfo = #{@celltype.get_global_name}_#{port.get_name}EntryInfo.eEntryInfo;
+      f.print "#{indent}};\n"
+    }
+  end
+
+  def exclude_info?
+    # print "exclude_info?: name=" + get_name.to_s
+    if @celltype == nil ||
+       is_of_composite? ||
+       @celltype.get_global_name == :nTECSInfo_tTECSInfoSub ||
+       post_code_generated? ||
+       @b_defined == false then
+      # print ": true celltype_is_of_composite=#{is_of_composite?} celltype_name=#{@celltype.get_global_name} celltype.need_generate=#{@celltype.need_generate?}\n"
+      return true
+    else
+      # print ": false\n"
+      return false
+    end
+  end
+
+  def exclude_info_factory?
+    # print "exclude_info_factory?: name=" + get_name.to_s
+    if @celltype == nil ||
+       is_of_composite? ||
+       @celltype.get_global_name == :nTECSInfo_tTECSInfoSub ||
+       ! @celltype.need_generate? then
+      # print ": true celltype_is_of_composite=#{is_of_composite?} celltype_name=#{@celltype.get_global_name} celltype.need_generate=#{@celltype.need_generate?}\n"
+      return true
+    else
+      # print ": false\n"
+      return false
+    end
+  end
+end
+
+class Signature
+  def print_info f, indent
+    f.print <<EOT
+
+#{indent}/*** #{@global_name} signature information ****/
+#{indent}cell nTECSInfo::tSignatureInfo #{@global_name}SignatureInfo {
+#{indent}    name            = "#{@name}";
+EOT
+    @function_head_list.get_items.each{ |fh|
+      f.print <<EOT
+#{indent}    cFunctionInfo[] = #{@global_name}_#{fh.get_name}FunctionInfo.eFunctionInfo;
+EOT
+    }
+    f.print <<EOT
+#{indent}};
+EOT
+    @function_head_list.get_items.each{ |fh|
+      fh.print_info f, indent
+    }
+  end
+end
+
+class FuncHead
+  def print_info f, indent
+    sig_name = @owner.get_global_name
+    func_name = get_name
+    f.print <<EOT
+#{indent}cell nTECSInfo::tFunctionInfo #{sig_name}_#{func_name}FunctionInfo {
+#{indent}    name            = "#{get_name}";
+#{indent}    bOneway         = #{is_oneway?};
+EOT
+    get_paramlist.get_items.each{ |param|
+      f.print <<EOT
+#{indent}    cParamInfo[]    = #{sig_name}_#{func_name}_#{param.get_name}ParamInfo.eParamInfo;
+EOT
+    }
+    f.print <<EOT
+#{indent}    cReturnTypeInfo = #{get_return_type.get_ID_str}TypeInfo.eTypeInfo;
+#{indent}};
+EOT
+    get_paramlist.get_items.each{ |param|
+      dbgPrint "param_list #{sig_name}, #{func_name}, #{param.get_name}\n"
+      param.print_info f, sig_name, func_name, get_paramlist, indent
+    }
+    get_return_type.print_info f, indent
+  end
+end
+
+class ParamDecl
+  def print_info f, signature_global_name, func_name, paramdecl_list, indent
+    if @size then
+      size = "\"#{@size.get_rpn( paramdecl_list )}\""
+    else
+      size = "(char_t*)0";
+    end
+    if @count then
+      count = "\"#{@count.get_rpn( paramdecl_list )}\""
+    else
+      count = "(char_t*)0";
+    end
+    if @string then
+      if @string == -1 then
+        string = '""'
+      else
+        string =  "\"#{@string.get_rpn( paramdecl_list )}\""
+      end
+    else
+      string = "(char_t*)0";
+    end
+    f.print <<EOT
+#{indent}cell nTECSInfo::tParamInfo #{signature_global_name}_#{func_name}_#{get_name}ParamInfo {
+#{indent}    name            = "#{get_name}";
+#{indent}    dir             = PARAM_DIR_#{@direction};
+#{indent}    sizeIsExpr      = #{size};
+#{indent}    countIsExpr     = #{count};
+#{indent}    stringExpr      = #{string};
+#{indent}    cTypeInfo       = #{get_type.get_ID_str}TypeInfo.eTypeInfo;
+#{indent}};
+EOT
+    get_type.print_info f, indent
+  end
+end
+
+class Decl
+  def print_info f, parent_ID_str, indent, decl_type
+    if @size_is then
+      size = "\"mikan\"";
+    else
+      size = "(char_t*)0";
+    end
+    f.print <<EOT
+#{indent}cell nTECSInfo::tVarDeclInfo #{parent_ID_str}_#{get_name}VarDeclInfo {
+#{indent}    name            = "#{get_name}";
+#{indent}    sizeIsExpr      = #{size};
+#{indent}    declType        = #{decl_type};
+#{indent}    offset          = C_EXP( "OFFSET_OF_#{parent_ID_str}_#{get_name}" );
+#{indent}    place           = C_EXP( "PLACE_OF_#{parent_ID_str}_#{get_name}" );
+#{indent}    cTypeInfo       = #{get_type.get_ID_str}TypeInfo.eTypeInfo;
+#{indent}};
+EOT
+    get_type.print_info f, indent
+  end
+end
+
+class Type
+  @@typeinfo_printed = {}
+
+  def self.reset_print_info
+    @@typeinfo_printed = {}
+  end
+
+  def print_info f, indent
+    # Type の info は、最後にまとめて出力するので、ここでは記録するだけ
+    if @@typeinfo_printed[ get_ID_str ] then
+      return
+    end
+    # p "ID Str: #{get_ID_str}"
+    @@typeinfo_printed[ get_ID_str ] = self
+    if self.kind_of? PtrType then
+      get_referto.print_info f, indent
+    elsif self.kind_of? ArrayType then
+      get_type.print_info f, indent
+    elsif self.kind_of? DefinedType then
+      get_type.print_info f, indent
+    elsif self.kind_of? StructType then
+      get_members_decl.get_items.each{ |decl|
+        decl.print_info f, get_ID_str, indent, :DECLTYPE_STMEMBER
+      }
+    end
+  end
+
+  def self.print_info_post f, indent
+    @@typeinfo_printed.each{ |nm, type|
+      type.print_info_post f, indent
+    }
+  end
+
+  def print_info_post f, indent
+    if self.class.superclass == Type then     # 親クラスが Type の場合 types.rb のクラス
+      type_name = self.class.name
+    else
+      type_name = self.class.superclass.name  # ctypes.rb のクラス (親クラスが types.rb のクラス)
+    end
+    # p "type: #{type_name}, #{self.class.name}"
+
+    # p "class=#{self.class.name} size=#{bit_size}"
+    f.print <<EOT
+#{indent}cell nTECSInfo::t#{type_name}Info #{get_ID_str}TypeInfo{
+#{indent}    name           = "#{get_type_str}#{get_type_str_post}";
+#{indent}    typeKind       = TECSTypeKind_#{type_name};
+#{indent}    size           = C_EXP( "sizeof(#{get_type_str}#{get_type_str_post})" );
+#{indent}    b_const        = #{is_const?};
+#{indent}    b_volatile     = #{is_volatile?};
+EOT
+    if self.kind_of? PtrType then
+      f.print "#{indent}    cTypeInfo        = #{get_referto.get_ID_str}TypeInfo.eTypeInfo;\n"
+    elsif self.kind_of? ArrayType then
+      f.print "#{indent}    cTypeInfo        = #{get_type.get_ID_str}TypeInfo.eTypeInfo;\n"
+    elsif self.kind_of? DefinedType then
+      f.print "#{indent}    cTypeInfo        = #{get_type.get_ID_str}TypeInfo.eTypeInfo;\n"
+    elsif self.kind_of? StructType then
+      get_members_decl.get_items.each{ |decl|
+        f.print "#{indent}    cVarDeclInfo[] = #{get_ID_str}_#{decl.get_name}VarDeclInfo.eVarDeclInfo;\n"
+      }
+    elsif self.kind_of? DescriptorType then
+      f.print "#{indent}    cSignatureInfo   = #{get_signature.get_global_name}SignatureInfo.eSignatureInfo;\n"
+    end
+    
+    f.print <<EOT
+#{indent}};
+EOT
+  end
+
+  #=== Type# 型文字列の識別子化
+  #型文字列に含まれる識別子として用いることのできない文字を用いることのできる文字列に置き換える
+  # 空白 => __
+  # * => _Ptr_
+  # [] => _Array_
+  # Descriptor() => Descriptor_of_
+  def get_ID_str
+    # puts "get_ID_str: #{self.class.name}"
+    if kind_of? PtrType then
+      str = get_referto.get_ID_str + "_Ptr_"
+    elsif kind_of? ArrayType then
+      str = get_type.get_ID_str + "_Array" + get_subscript.eval_const( nil ).to_s + "_"
+    elsif kind_of? StructType then
+      str = "struct #{@tag}"
+    elsif kind_of? DescriptorType then
+      str = "Descriptor_of_" + get_signature.get_global_name.to_s
+    else
+      str = get_type_str + get_type_str_post
+    end
+    # p "before: #{str}"
+    str.gsub!( / /, "__" )
+    # p "after: #{str}"
+    return str
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tool_info.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tool_info.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/tool_info.rb	(revision 398)
@@ -0,0 +1,348 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#= TOOL_INFO class
+# The syntax of the contents of __tool_info__ is same as JSON.
+# Home made schema is used to validate the contents of __tool_info__.
+# the schema is not defiened well. see saveload.rb for example of the schema.
+# 
+class TOOL_INFO
+
+  # tool_info 
+  @@tool_info = { }
+
+  # tool_info schema for tecsgen
+  @@TECSGEN_schema = {
+    :tecsgen        => {   # require
+      :base_dir       => [ :string ],             # dir where the cde created initially
+      :direct_import  => [ :string ],             # .cdl (sometimes .cde) specified in argments
+      :import_path    => [ :string ],             # -I of tecsgen
+      :define_macro   => [ :string ],             # -D of tecsgen
+      :tecscde_version=> :string,                 # TECSCDE version
+      :cde_format_version=> :string,              # CDE format version
+      :save_date      => :string,                 # last save date & time
+    },
+    :__tecsgen      => {   # optioanl
+      :cpp            => :string                  # -c or TECS_CPP environment variable
+    }
+  }
+
+  def initialize( name, val )
+    @@tool_info[name] = val
+
+    # __tool_info__( "tecsgen" ): validate & reflect immediately
+    p "tool_info: tecsgen #{name}"
+    if name == :tecsgen then
+      set_tecsgen_tool_info
+    end
+  end
+
+  def self.get_tool_info name
+    @@tool_info[ name ]
+  end
+
+  #=== TOOL_INFO#set_tecsgen_tool_info
+  # __tool_info__( "tecsgen" )
+  def set_tecsgen_tool_info
+    validator = TOOL_INFO::VALIDATOR.new( :tecsgen, @@TECSGEN_schema )
+    if validator.validate || $b_force_apply_tool_info
+      info = TOOL_INFO.get_tool_info( :tecsgen )
+      (info[ :base_dir ]).each{ |bd|
+        if ! $base_dir.include? bd
+          $base_dir[ bd ] = true
+        end
+      }
+
+      info[ :import_path ].each{ |path|
+        if ! $import_path.include?( path )
+          $import_path << path
+        end
+      }
+
+      info[ :define_macro ].each{ |define|
+        if ! $define.include?( define )
+          $define << define
+        end
+      }
+      if info[ :cpp ]
+        if ! $b_cpp_specified
+          $cpp = info[ :cpp ]
+          $b_cpp_specified = true
+        end
+      end
+
+      info[ :direct_import ] && info[ :direct_import ].each{ |import|
+        Import.new( import, false, false )
+      }
+    end
+  end
+
+  #== simple JSON validator
+  # this validator use simple schema.
+  # array length cannot be checked.
+  # you have to check array length in your code, if necessary.
+  class VALIDATOR
+
+    #@b_ok::Bool
+
+    def error( msg )
+      STDERR.print( "__tool_info__: " + msg )
+      @b_ok = false
+    end
+
+    def initialize name, schema
+      @name = name
+      @schema = schema
+      @b_ok = true
+    end
+
+    #=== VALIDATOR#validate
+    def validate
+      info = TOOL_INFO.get_tool_info @name
+      if info == nil
+        error( "\"#{@name}\" not found\n" )
+        return @b_ok
+      end
+      validate_object info, @name, @name
+      return @b_ok
+    end
+
+    def validate_object( object, require_type, path )
+      obj_type = @schema[ require_type ]
+      dbgPrint "validate_object: #{path}  object=#{obj_type[ :type ]}  required=#{object[:type]}\n"
+
+      obj_type.each{ |name, val_type|
+        val = object[name]
+        path2 = path.to_s + "." + name.to_s
+        if val == nil
+          error( "#{path}: required property not found '#{name}'\n" )
+          next
+        end
+        if val_type.kind_of? Array
+          validate_array_member val, val_type, path2
+        else
+          validate_types val, val_type, path2
+        end
+      }
+
+      optional = @schema[ ("__" + require_type.to_s).to_sym ]
+      if optional
+        dbgPrint "#{require_type.to_s} has optional\n"
+
+        optional.each{ |name, val_type|
+          val = object[name]
+          path2 = path.to_s + "." + name.to_s
+          if val == nil
+            # no need to occur error
+            # error( "#{path}: required property not found '#{name}'\n" )
+            next
+          end
+          if val_type.kind_of? Array
+            validate_array_member val, val_type, path2
+          else
+            validate_types val, val_type, path2
+          end
+        }
+      end
+
+    end
+
+    def validate_array_member array, val_types, path
+      if ! array.kind_of? Array
+        error( "#{path2}: array required as value\n" )
+        return
+      end
+      index=0
+      array.each{ |member|
+        type = get_object_type member
+        i = val_types.find_index type
+        if i == nil
+          if type == :integer
+            i = val_types.find_index :number
+          end
+        end
+        if i == nil
+          error( "#{path}: array member type mismatch, #{type} for #{val_types}\n" )
+          next
+        end
+        val_type = val_types[ i ]
+        validate_types member, val_type, (path.to_s + '[' + index.to_s + '].')
+        index += 1
+      }
+    end
+
+    #=== TOOL_INFO::VALIDATOR#validate_types
+    #obj::Object (Integer, Floating, String, Hash)
+    #val_type::Symbol : required object type
+    def validate_types obj, val_type, path
+      type = get_object_type obj
+      case val_type
+      when :integer
+        if type == :integer
+          return
+        end
+      when :number
+        if type == :integer || type == :number
+          return
+        end
+      when :string
+        if type == :string
+          return
+        end
+        # when :nil   # mikan
+        # when :bool  # mikan
+      else # object or fixed string
+        if val_type.kind_of? String
+          # val is specified by String
+          if type == :string
+            if obj == val_type
+              return
+            end
+          end
+        else
+          if type.to_sym == val_type
+            validate_object( obj, val_type, path + val_type.to_s )
+            return
+          end
+        end
+      end
+      error( "#{path}: type mismatch, #{type} for #{val_type}\n" )
+    end
+
+    def get_object_type obj
+# p "#{obj.class} #{obj.to_s}"
+      if obj.kind_of? Integer
+        return :integer
+      elsif obj.kind_of? Float
+        return :number
+      elsif obj.kind_of? String
+        return :string
+      elsif obj.kind_of? Hash
+        return obj[ :type ].to_sym
+      end
+      return nil
+    end
+  end
+
+end
+
+
+#---------- obsolete -------#
+
+#--- TOOL_INFO replaced location information ---#
+
+class TECSGEN
+
+  #------ manupulate location information --------#
+  def self.new_cell_location cell_location
+    @@current_tecsgen.new_cell_location cell_location
+  end
+  def new_cell_location cell_location
+    @cell_location_list << cell_location
+  end
+  def get_cell_location_list
+    @cell_location_list
+  end
+
+  def self.new_join_location join_location
+    @@current_tecsgen.new_join_location join_location
+  end
+  def new_join_location join_location
+    @join_location_list << join_location
+  end
+  def get_join_location_list
+    @join_location_list
+  end
+
+#==  Cell_location
+  # tecscde の位置情報
+  class  Cell_location
+
+    #=== Join_location#initialize
+    #cell_nspath::NamespacePath
+    #x,y,w,h::Expression
+    #port_location_list::[ [Symbol(ep_or_cp_name), Symbol(edge_name), Expression(offset)], ... ]
+    #ep_name::Symbol
+    def initialize( cell_nspath, x, y, w, h, port_location_list )
+      # p "Cell_location: #{cell_nspath}, #{x}, #{y}, #{w}, #{h}, #{port_location_list}"
+      @cell_nspath = cell_nspath
+      @x = x.eval_const nil
+      @y = y.eval_const nil
+      @w = w.eval_const nil
+      @h = h.eval_const nil
+      @port_location_list = port_location_list
+
+      TECSGEN.new_cell_location self
+    end
+
+    def get_location
+      [ @cell_nspath, @x, @y, @w, @h, @port_location_list ]
+    end
+
+  end # Cell_location
+
+  #==  Join_location
+  # tecscde の位置情報
+  class  Join_location
+    @@join_location_list = []
+
+    #=== Join_location#initialize
+    #cp_cell_nspath::NamespacePath
+    #cp_name::Symbol
+    #ep_cell_nspath::NamespacePath
+    #ep_name::Symbol
+    #bar_list::[[Symbol (VBar or HBar), Expression(position mm)], ....]
+    def initialize( cp_cell_nspath, cp_name, ep_cell_path, ep_name, bar_list )
+      # p "Join_location  #{cp_cell_nspath}, #{cp_name}, #{ep_cell_path}, #{ep_name} #{bar_list}"
+      @cp_cell_nspath = cp_cell_nspath
+      @cp_name = cp_name
+      @ep_cell_path = ep_cell_path
+      @ep_name = ep_name
+      @bar_list = bar_list
+
+      TECSGEN.new_join_location self
+    end
+
+    def get_location
+      [@cp_cell_nspath, @cp_name, @ep_cell_path, @ep_name, @bar_list]
+    end
+
+  end # Join_location
+
+end # TECSGEN
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/types.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/types.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/types.rb	(revision 398)
@@ -0,0 +1,1633 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--  
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#= HasType: @type を内部に持つ型のためのモジュール
+#  @b_cloned::Bool  : true if @type is cloned
+#
+# このモジュールは DefinedType, PtrType, ArrayType に include される
+# 本当は typedef された時の Decl の要素のみ clone すればよいのだが、get_type, get_original_type で
+# 取り出されたとき、set_scs, set_qualifier されたときに無条件で clone する (無駄にメモリを使用する)
+# ただし、clone するのは一回のみである (二回 clone すると別の型を参照してしまう)
+#
+# initialize で clone しても、共有されているときに clone されない
+#
+module HasType
+  def initHasType
+    @b_cloned = false
+  end
+
+  #=== HasType# @type をクローンする
+  def clone_type
+#    if @b_cloned == false then
+      @type = @type.clone
+      @b_cloned = true
+#    end
+  end
+end
+
+class Type < Node
+# @b_const    : bool
+# @b_volatile : bool
+
+  def initialize
+    super
+  end
+
+  def set_qualifier( qualifier )
+    case qualifier
+    when :CONST
+#      if @b_const then
+#        cdl_error( "T1001 const duplicate"  )
+#      end
+      @b_const = true
+    when :VOLATILE
+#      if @b_volatile then
+#        cdl_error( "T1002 volatile duplicate"  )
+#      end
+      @b_volatile = true
+    else
+      raise "Unknown qualifier #{qualifier}"
+    end
+  end
+
+  def is_const?
+    if @b_const then
+      return true
+    else
+      return false
+    end
+  end
+
+  def is_volatile?
+    if @b_volatile then
+      return true
+    else
+      return false
+    end
+  end
+
+  def is_void?
+    if self.kind_of? DefinedType then
+      return @type.is_void?
+    elsif self.kind_of? VoidType then
+      return true
+    else
+      return false
+    end
+  end
+
+  #=== size_is, count_is, string を設定
+  # 派生クラスでオーバーライドする（デフォルトではエラー）
+  def set_scs( size, count, string, max = nil, b_nullable = false )
+    str = ""
+    delim = ""
+    if size then
+      str = "size_is"
+      delim = ", "
+    end
+    if count then
+      str = "#{str}#{delim}count_is"
+      delim = ", "
+    end
+    if string then
+      str = "#{str}#{delim}string"
+      delim = ", "
+    end
+    if b_nullable then
+      str = "#{str}#{delim}nullable"
+      delim = ", "
+    end
+    cdl_error( "T1003 $1: unsuitable specifier for $2" , str, self.class )
+  end
+
+  def clear_max
+    raise "clear_max called: #{self.class}"
+  end
+
+  def get_type_str
+    str = ""
+    if @b_const then
+      str = "#{str}const "
+    end
+    if @b_volatile then
+      str = "#{str}volatile "
+    end
+    return str
+  end
+
+  #=== 型をチェック
+  #    正当な型定義かどうか、チェックする
+  def check
+    # 型に誤りがあれば、エラー文字列を返す
+  end
+
+  #=== struct の tag をチェック
+  #    正当な型定義かどうか、チェックする
+  #kind:: Decl の @kind を参照
+  def check_struct_tag kind
+    # tag が存在しなければエラーを出力する
+    # 配列型では、要素の型を再帰的にチェック
+    # ポインタ型では、指す先の tag チェックはしない
+    # 関数型ではパラメータリストのすべてについて行う
+  end
+
+  #===  初期化可能かチェック
+  #     attribute など初期化可能かチェックする（型に対し正当な初期化子が与えられているか）
+  #ident::        string                被代入変数命
+  #initialize::   Expression, Array of initializer or C_EXP
+  #               代入値、C_EXP が与えられるのは IntType の場合のみ
+  #kind::         symbol (:ATTRIBUTE, :VAR, :CONSTNAT )
+  #attribute::    NameList              kind == :VAR のとき参照できる attribute
+  #
+  #     locale を第一引数として取るのは、以下の理由による。
+  #     このメソッドは、変数への代入が行われる「行」に対して呼び出されるが、
+  #     Type クラスのインスタンスは、変数が定義された「行」を記憶している。
+  #
+  # STAGE: S
+  def check_init( locale, ident, initializer, kind, attribute = nil )
+    #
+  end
+
+  #=== const_val を指定の型にキャストする
+  # 派生クラスでオーバーライドしていないとエラー
+  def cast( const_val )
+    cdl_error( "T1004 cannot cast to $1" , self.class )
+  end
+
+  #=== 型が一致するかのチェック
+  # 型名の字面でチェック．
+  # typedef された型も字面で一致を見るため、元の型が同じでも型名が異なれば不一致となる
+  def equal? type2
+    return ( get_type_str == type2.get_type_str ) && ( get_type_str_post == type2.get_type_str_post )
+  end
+
+  #=== bit size を得る
+  # IntType, FloatType 以外は0
+  def get_bit_size
+    return 0
+  end
+
+  #=== 元の型を得る
+  # typedef された型の場合、その元の型を返す.
+  # それ以外は、自分自身を返す．
+  # (DefinedType では本メソッドがオーバーライドされる)
+  def get_original_type
+    return self
+  end
+
+  #=== 内部にポインタ型を持つ
+  # ポインタ型、またはポインタ型メンバを持つ構造体、または要素がポインタ型を持つ配列
+  def has_pointer?
+    false
+  end
+
+  #=== size_is, count_is, string 指定されたポインタを持つか
+  # size_is, count_is, string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれをを要素に持つ配列
+  def has_sized_pointer?
+    false
+  end
+  
+  #=== 長さ指定のない string を持つ
+  # なさ指定のない string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれを要素に持つ配列
+  def has_unsized_string?
+    false
+  end
+
+  def show_tree indent
+    indent.times { print "  " }
+    puts "const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
+    indent.times { print "  " }
+    puts "has_pointer=#{has_pointer?} has_sized_pointer=#{has_sized_pointer?} has_unsized_string=#{has_unsized_string?}"
+  end
+end
+
+class DefinedType < Type
+#  @type_name::string
+#  @typedef::Typedef
+#  @type:: kind_of Type
+
+  include HasType
+
+  def initialize( type_name )
+    super()
+    @type_name = type_name
+
+    # mikan type_name が path になっていないため暫定
+    @typedef = Namespace.find( [ type_name ] )  #1
+
+#    if @type.class != Typedef then
+#      raise NotTypedef
+    #    end
+    if @typedef == nil then
+      cdl_error( "T1005 \'$1\' not defined" , type_name )
+    elsif @typedef.class != Typedef then
+      cdl_error( "T1006 \'$1\' not type name. expecting type name here" , type_name )
+    end
+    @type = @typedef.get_declarator.get_type
+    initHasType
+  end
+
+  def get_type
+    clone_type
+    return @type
+  end
+
+  def get_type_str
+    "#{super}#{@type_name}"
+  end
+
+  def get_type_str_post
+    ""
+  end
+
+  def get_size
+    return @type.get_size
+  end
+
+  def is_nullable?
+    return @type.is_nullable?
+  end
+
+  #=== qualifier(const, volatile) の設定
+  def set_qualifier( qualifier )
+    clone_type
+    @type.set_qualifier( qualifier )
+    super
+  end
+
+  def set_scs( size, count, string, max = nil, b_nullable = false )
+    clone_type
+    @type.set_scs( size, count, string, max, b_nullable )
+  end
+
+  def clear_max
+    @type.clear_max
+  end
+
+  def get_original_type
+    clone_type
+    return @type.get_original_type
+  end
+
+  def check	# 意味的誤りがあれば、文字列を返す
+    nil    # typedef の段階で意味チェックされている
+  end
+
+  def check_init( locale, ident, initializer, kind, attribute = nil )
+    get_type.check_init( locale, ident, initializer, kind, attribute )
+  end
+
+  #=== 内部にポインタ型を持つ
+  # ポインタ型、またはポインタ型メンバを持つ構造体、または要素がポインタ型を持つ配列
+  def has_pointer?
+    @type.has_pointer?
+  end
+
+  #=== size_is, count_is, string 指定されたポインタを持つか
+  # size_is, count_is, string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれをを要素に持つ配列
+  def has_sized_pointer?
+    @type.has_sized_pointer?
+  end
+  
+  #=== 長さ指定のない string を持つ
+  # なさ指定のない string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれを要素に持つ配列
+  def has_unsized_string?
+    @type.has_unsized_string?
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    if @typedef == nil then
+      puts "DefinedType: #{@type_name} is missing, const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
+    else
+      puts "DefinedType: #{@type_name}, const=#{@b_const} volatile=#{@b_volatile}"
+    end
+    super( indent + 1 )
+    @typedef.show_tree( indent + 1 )
+    @type.show_tree( indent + 1 )
+  end
+end
+
+class VoidType < Type
+
+  def check	# 意味的誤りがあれば、文字列を返す
+    nil
+  end
+
+  def check_init( locale, ident, initializer, kind, attribute = nil )
+    cdl_error2( locale, "T1007 $1: void type variable cannot have initializer" , ident )
+  end
+
+  def get_type_str
+    "#{super}void"
+  end
+
+  def get_type_str_post
+    ""
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "VoidType #{locale_str}"
+    super( indent + 1 )
+  end
+end
+
+class BoolType < Type
+
+  def check	# 意味的誤りがあれば、文字列を返す
+    nil
+  end
+
+  def get_type_str
+    "#{super}bool_t"
+  end
+
+  def get_type_str_post
+    ""
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "BoolType #{locale_str}"
+    super( indent + 1 )
+  end
+end
+
+class IntType < Type
+#  @bit_size::		-11: char, -1: char_t, -2: short, -3: int, -4: long, -5: long long
+#			8, 16, 32, 64, 128
+#  @sign::		:SIGNED, :UNSIGNED, nil
+
+  def initialize( bit_size )
+    super()
+    @bit_size = bit_size
+    @sign = nil
+  end
+
+  def set_sign( sign, b_uint = false )
+    if @sign then
+      if @sign != sign then
+        cdl_error( "T1008 ambigous signed or unsigned"   )
+      end
+    elsif b_uint == false && @bit_size > 0 then
+      if sign == :SIGNED then
+        cdl_warning( "W2001 signed int$1_t: obsolete. use int$2_t" , @bit_size, @bit_size )
+      else
+        cdl_warning( "W2002 unsinged int$1_t: obsolete. use uint$2_t" , @bit_size, @bit_size )
+      end
+    end
+
+    @sign = sign
+
+    if @sign != :SIGNED && @sign != :UNSIGNED then
+      raise "set_sign: unknown sign: #{@sign}"
+    end
+  end
+
+  def check	# 意味的誤りがあれば、文字列を返す
+    nil
+  end
+
+  def check_init( locale, ident, initializer, kind, attribute = nil )
+    val = initializer  # C_EXP, Array
+    if val.instance_of?( Expression ) then
+      val = val.eval_const2( nil, attribute )
+      # 評価の結果 C_EXP や Array となる可能性がある
+    end
+
+    if val.instance_of? Token then    # StringVal 導入により、もはや Token は来ないはず
+      # val が Token の場合 == の右辺が String だとエラーを起こす (#198)
+      cdl_error2( locale, "T1009 $1: $2: not integer" , ident, val )
+      return
+    elsif val.is_a? C_EXP then
+      # #192 var が attribute を参照し、attribute の右辺が C_EXP の場合
+      # const の右辺が C_EXP の場合も
+      return
+    elsif val.kind_of? FloatVal then
+      cdl_error2( locale, "T1011 $1: need cast to assign float to integer" , ident )
+      return
+    elsif val.instance_of? Array then
+      cdl_error2( locale, "T1017 $1: unsuitable initializer for scalar type" , ident )
+      return
+    elsif val == nil then
+      cdl_error2( locale, "T1010 $1: initializer is not constant" , ident )
+      return
+    end
+
+    if ! val.kind_of? IntegerVal then
+      cdl_error2( locale, "T1012 $1: $2: not integer" , ident, val )
+      return
+    end
+
+    val = val.to_i
+    max = get_max
+    min = get_min
+    dbgPrint "sign=#{@sign} ident=#{ident} val=#{val} max=#{max} min=#{min}\n"
+
+    if max != nil then
+      if val > max then
+        if @sign == :SIGNED || @sign == nil then
+          cdl_error2( locale, "T1013 $1: too large (max=$2)" , ident, max )
+        else
+          cdl_error2( locale, "T1016 $1: too large (max=$2)" , ident, max )
+        end
+      end
+    end
+
+    if min != nil then
+      if val < min
+        if @sign == :SIGNED || @sign == nil then
+          cdl_error2( locale, "T1014 $1: too large negative value (min=$2)" , ident, min )
+        else
+          cdl_error2( locale, "T1015 $1: negative value for unsigned" , ident )
+        end
+      end
+    end
+  end
+
+  #=== IntType# 最大値、最小値をチェックしてクリップする
+  # キャスト演算を行う
+  #in_val:: IntegerVal, FloatVal:  この型にキャストする値
+  #from_type:: Symbol:  :IntType, :FloatType  IntType の場合はビット数でクリップ、FloatType の場合は最大値でクリップ
+  def check_and_clip( in_val, from_type = :IntType )
+    bit_size = get_bit_size
+    if bit_size == -1 then
+      bit_size = 8
+    end
+    val = in_val.to_i
+    if get_max && val > get_max then
+      if from_type == :IntType then
+        rval = ((1 << bit_size)-1) & val   # bit 数でクリップ
+      else
+        rval = get_max                         # 最大値でクリップ (FloatType)
+      end
+      cdl_warning( "W2003 $1: too large to cast to $2, clipped($3)" , in_val, get_type_str, rval )
+    elsif get_min && val < get_min then
+      if from_type == :IntType then
+        rval = ((1 << bit_size)-1) & val
+      else
+        rval = get_min
+      end
+      if @sign == :SIGNED || @sign == nil then
+        cdl_warning( "W2004 $1: too small to cast to $2, clipped($3)" , in_val, get_type_str, rval )
+      else    # @sign == :UNSIGNED || @sign == nil (char の場合)
+        cdl_warning( "W2005 $1: negative value for unsigned: convert to $2" , in_val, rval )
+      end
+    else
+      rval = val
+    end
+    return rval
+  end
+
+  def get_min
+    if @sign == :SIGNED || @sign == nil then
+      if @bit_size == -1 then
+        bit_sz = 8   # char_t は、有符号に扱う
+      else
+        bit_sz = @bit_size
+      end
+      case bit_sz
+      when 8, 16, 32, 64, 128
+        return  - ( 1 << ( bit_sz - 1 ))
+      else # -1, -2, -3, -4, -5, -11
+        return nil
+      end
+    else   # @sign == :UNSIGNED
+      return 0
+    end
+  end
+
+  def get_max
+    if @bit_size == -1 then
+      if @sign == nil then
+        return 255   # char_t は、無符号に扱う
+      else
+        bit_sz = 8
+      end
+    else
+      bit_sz = @bit_size
+    end
+    if @sign == :SIGNED || @sign == nil then
+      case bit_sz
+      when 8, 16, 32, 64, 128
+        return ( 1 << ( bit_sz - 1 )) -1
+      else # -1, -2, -3, -4, -5, -11
+        return nil
+      end
+    else   # @sign == :UNSIGNED
+      case bit_sz
+      when 8, 16, 32, 64, 128
+        return ( 1 << bit_sz ) - 1
+      else # -2, -3, -4, -5, -11
+        return nil
+      end
+    end
+  end
+
+  #=== IntType# C 言語における型名（修飾子付き）
+  def get_type_str
+    str = super
+
+    # NEW_MODE
+    case @sign
+    when :SIGNED
+      sign = ""
+      signL = "signed "
+    when :UNSIGNED
+      sign = "u"
+      signL = "unsigned "
+    else
+      sign = ""
+      signL = ""
+    end
+
+    # p "get_type_str: sign:#{@sign} signL=#{signL}"
+
+    case @bit_size
+    when -1      # char_t 型
+      if @sign == :SIGNED then
+        sign = "s"
+      end
+      str = "#{str}#{sign}char_t"
+    when -11     # char 型(obsolete)
+      str = "#{str}#{signL}char"
+    when -2      # short 型
+      str = "#{str}#{signL}short"
+    when -3      # int 型
+      str = "#{str}#{signL}int"
+    when -4      # long 型
+      str = "#{str}#{signL}long"
+    when -5      # long long 型
+      str = "#{str}#{signL}long long"
+    when 8, 16, 32, 64, 128     # int16, int32, int64, int128 型
+      str = "#{str}#{sign}int#{@bit_size}_t"
+    end
+
+    return str
+  end
+
+  #=== IntType# C 言語における型名（後置文字列）
+  def get_type_str_post
+    ""
+  end
+
+  #=== IntType#bit_size を得る
+  #    返される値は @bit_size の仕様を参照
+  def get_bit_size
+    return @bit_size
+  end
+
+  #=== IntType# sign を得る
+  # @sign の説明を参照
+  def get_sign
+    @sign
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "IntType bit_size=#{@bit_size} sign=#{@sign} const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
+    super( indent + 1 )
+  end
+end
+
+class FloatType < Type
+#  @bit_size::         32, 64, (80), -32, -64, -128
+
+  def initialize( bit_size )
+    super()
+    @bit_size = bit_size
+  end
+
+  def check	# 意味的誤りがあれば、文字列を返す
+    nil
+  end
+
+  # mikan Float 型の C_EXP 対応 (generate.rb にも変更必要)
+  def check_init( locale, ident, initializer, kind, attribute = nil )
+    # 型に対する初期値に誤りがあれば、エラー文字列を返す
+    val = initializer
+    if val.instance_of?( Expression ) then
+      val = val.eval_const2( nil, attribute )
+      # 評価の結果 C_EXP や Array となる可能性がある
+    end
+
+    if val.instance_of? Token then
+      # val が Token の場合 == の右辺が String だとエラーを起こす
+      cdl_error2( locale, "T1018 $1: $2: not number" , ident, val )
+      return
+    elsif val.instance_of? Array then
+      cdl_error2( locale, "T1020 $1: unsuitable initializer for scalar type" , ident )
+      return
+    elsif val.instance_of? C_EXP then
+      return
+    elsif val == nil then
+      cdl_error2( locale, "T1019 $1: initializer is not constant" , ident )
+      return
+    elsif ! val.kind_of?( IntegerVal ) && ! val.kind_of?( FloatVal ) then
+      cdl_error2( locale, "T1037 $1: not number" , ident )
+      return
+    end
+    # else
+    #   cdl_error2( locale, "T1020 $1: unsuitable initializer for scalar type" , ident )
+    #   return
+    # end
+    return
+  end
+
+  def get_type_str
+    str = super
+
+    case @bit_size
+    when 32
+      str = "#{str}float32_t"
+    when 64
+      str = "#{str}double64_t"
+    when -32
+      str = "#{str}float"
+    when -64
+      str = "#{str}double"
+    when -128
+      str = "#{str}long double"
+    end
+    return str
+  end
+
+  def get_type_str_post
+    ""
+  end
+
+  def get_bit_size
+    @bit_size
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "FloatType bit_size=#{@bit_size} qualifier=#{@qualifier} #{locale_str}"
+    super( indent + 1 )
+  end
+end
+
+class EnumType < Type # mikan
+#  @bit_size::		-1: enum
+#			8, 16, 32, 64, 128
+#  @element::		[]
+#  @element_val::	[]
+
+  def initialize( bit_size )
+    super()
+    @bit_size = bit_size
+  end
+
+  def check
+   # mikan enum check
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "EnumType bit_size=#{@bit_size} qualifier=#{@qualifier} #{locale_str}"
+    super( indent + 1 )
+    # mikan element
+  end
+end
+
+class StructType < Type
+#  @tag::
+#  @b_define::  true if define, false if refer
+#  @members_decl:: NamedList
+#  @definition:: StructType
+#  @b_has_pointer_member:: bool : メンバにポインタ型がある
+#  @b_has_sized_pointer_member:: bool : メンバにポインタ型がある
+#  @b_has_unsized_string_member:: bool : メンバにポインタ型がある
+#  @b_hasTag:: bool : タグがある
+#  @member_types_symbol:: Symbol : tag が無い時のみ設定 (それ以外では nil)
+
+  @@structtype_current_stack = []
+  @@structtype_current_sp = -1
+
+  # tag なし struct
+  @@no_struct_tag_num = 0
+  @@no_tag_struct_list = {}
+
+  def initialize( tag = nil )
+    super()
+    @tag = tag
+    if tag then
+      @b_hasTag = true
+    else
+      @b_hasTag = false
+    end
+    @@structtype_current_sp += 1
+    @@structtype_current_stack[@@structtype_current_sp] = self
+    @b_has_pointer_member = false
+    @b_has_sized_pointer_member = false
+    @b_has_unsized_string_member = false
+    @member_types_symbol = nil
+  end
+
+  def self.set_define( b_define )
+    @@structtype_current_stack[@@structtype_current_sp].set_define( b_define )
+  end
+
+  def set_define( b_define )
+    @b_define = b_define
+    if @b_define then
+      @members_decl = NamedList.new( nil, "in struct #{@tag}" )
+      # if @tag then    登録タイミングを終わりに変更 V1.0.2.19
+      #  Namespace.new_structtype( self )
+      # end
+    else
+      @definition = Namespace.find_tag( @tag )
+      # check_struct_tag に移す V1.0.2.19
+      # if @definition == nil then
+      #  cdl_error( "T1021 \'$1\': struct not defined" , @tag )
+      # end
+    end
+  end
+
+  def self.new_member( member_decl )
+    @@structtype_current_stack[@@structtype_current_sp].new_member( member_decl )
+  end
+
+  def new_member( member_decl )
+    member_decl.set_owner self   # Decl (StructType)
+    @members_decl.add_item( member_decl )
+    if member_decl.get_type.has_pointer?
+      @b_has_pointer_member = true
+    end
+    if member_decl.get_type.has_sized_pointer?
+      @b_has_sized_pointer_member = true
+    end
+    if member_decl.get_type.has_unsized_string?
+      @b_has_unsized_string_member = true
+    end
+  end
+
+  def check	# 意味的誤りがあれば、文字列を返す
+    nil
+  end
+
+  #=== 構造体のタグをチェック
+  #  declarator の時点でチェックする
+  #kind:: Decl の @kind を参照
+  def check_struct_tag kind
+    if @tag == nil
+      return
+    end
+
+    st = Namespace.find_tag( @tag )
+    if st == nil then
+      cdl_error( "T1022 struct $1: not defined" , @tag )
+    end
+  end
+
+  # mikan Float 型の C_EXP 対応 (generate.rb にも変更必要)
+  def check_init( locale, ident, initializer, kind, attribute = nil )
+
+    st = Namespace.find_tag( @tag )
+    if st == nil then
+      cdl_error2( locale, "T1023 struct $1: not defined" , @tag )
+      return
+    end
+
+    # 初期化子が式の場合、型（タグ）が一致するかチェック
+    if initializer.instance_of?( Expression ) then
+      t = initializer.get_type( attribute )
+      # print "Check init #{t.class} #{t.get_name}\n"
+      if ! t.kind_of?( StructType ) then
+        if t then
+          str = t.get_type_str
+        else
+          str = "unknown"
+        end
+        cdl_error2( locale, "T1038 $1: initializer type mismatch. '$2' & '$3'" , ident, get_type_str, str )
+      elsif @tag != t.get_name then
+        cdl_error2( locale, "T1039 $1: struct tag mismatch $2 and $3" , ident, @tag, t.get_name )
+      end
+      initializer = initializer.eval_const( attribute )
+    end
+
+    if initializer.instance_of?( Array ) then
+      i = 0
+      st.get_members_decl.get_items.each { |d|
+        if initializer[i] then
+          d.get_type.check_init( locale, "#{ident}.#{d.get_identifier}", initializer[i], kind )
+        end
+        i += 1
+      }
+    else
+      cdl_error2( locale, "T1024 $1: unsuitable initializer for struct" , ident )
+    end
+  end
+
+  def self.end_of_parse()
+    @@structtype_current_stack[@@structtype_current_sp].end_of_parse
+    @@structtype_current_sp -= 1
+  end
+
+  def end_of_parse()
+    if @members_decl == nil   # @b_define = false またはメンバーのない構造体（エラー）
+      return
+    end
+    @members_decl.get_items.each{ |md|
+      size = md.get_size_is
+      if size then
+        val = size.eval_const( @members_decl )
+        if val == nil then
+          type = size.get_type( @members_decl )
+          if ! type.kind_of?( IntType ) then
+            cdl_error( "T1025 size_is argument is not integer type"  )
+          end
+        end
+      end
+      count = md.get_count_is
+      if count then
+        val = count.eval_const( @members_decl )
+        if val == nil then
+          type = count.get_type( @members_decl )
+          if ! type.kind_of?( IntType ) then
+            cdl_error( "T1026 count_is argument is not integer type"  )
+          end
+        end
+      end
+      string = md.get_string
+      if string == -1 then
+        # 長さ指定なし
+      elsif string then
+        val = string.eval_const( @members_decl )
+        if val == nil then
+          type = string.get_type( @members_decl )
+          if ! type.kind_of?( IntType ) then
+            cdl_error( "T1027 string argument is not integer type"  )
+          end
+        end
+      end
+    }
+
+    if @tag == nil then
+      @member_types_symbol = get_member_types_symbol
+      # print "member_types_symbol = #{get_member_types_symbol}\n"
+      if @@no_tag_struct_list[ @member_types_symbol ] then
+        @tag = @@no_tag_struct_list[ @member_types_symbol ]
+      else
+        @tag = :"TAG_#{@@no_struct_tag_num}_TECS_internal__"
+	    @@no_struct_tag_num += 1
+        @@no_tag_struct_list[ @member_types_symbol ] = @tag
+        Namespace.new_structtype( self )
+      end
+    else
+      if @b_define then
+        Namespace.new_structtype( self )
+      end
+    end
+  end
+
+  def get_name
+    @tag
+  end
+
+  def get_type_str      # mikan struct get_type_str
+    str = super
+
+    if @b_hasTag then
+      # typedef struct tag StructType; の形式の場合
+      # struct の本体は、別に生成される
+      return "#{str}struct #{@tag}"
+
+    else
+      # typedef struct { int a; } StructType; の形式の場合
+      str += "struct {"
+      @members_decl.get_items.each{ |i|
+        str += sprintf( "%s %s%s;", "#{i.get_type.get_type_str}", "#{i.get_name}", "#{i.get_type.get_type_str_post}" )
+      }
+      str += "} "
+
+      return str
+
+    end
+  end
+
+  def get_type_str_post
+    ""
+  end
+
+  def get_members_decl
+    return @members_decl if @members_decl
+
+    st = Namespace.find_tag( @tag )
+    if st then
+      return st.get_members_decl
+    end
+
+    return nil
+  end
+
+  def has_pointer?
+    if @definition
+      return @definition.has_pointer?
+    else
+      return @b_has_pointer_member
+    end
+  end
+
+  def has_sized_pointer?
+    if @definition
+      return @definition.has_sized_pointer?
+    else
+      return @b_has_sized_pointer_member
+    end
+  end
+  
+  def has_unsized_string?
+    if @definition
+      return @definition.has_unsized_string?
+    else
+      return @b_has_unsized_string_member
+    end
+  end
+
+  #=== 同じ構造体かどうかチェックする
+  # tag のチェックは行わない
+  # すべてのメンバの名前と型が一致することを確認する
+  def same? another
+    md = another.get_members_decl
+    if @members_decl == nil || md == nil
+      return false
+    end
+
+    md1 = @members_decl.get_items
+    md2 = md.get_items
+    if( md1.length != md2.length )
+      return false
+    end
+
+    i = 0
+    while i < md1.length
+      if md1[i].get_name != md2[i].get_name ||
+          md1[i].get_type.get_type_str != md2[i].get_type.get_type_str ||
+          md1[i].get_type.get_type_str_post != md2[i].get_type.get_type_str_post
+        return false
+      end
+      i += 1
+    end
+
+    return true
+  end
+  
+  def get_member_types_symbol
+    mts = ''
+    @members_decl.get_items.each { |member|
+      mts += member.get_type.get_type_str + member.get_type.get_type_str_post + ';'
+    }
+    return mts.to_sym
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "StructType tag: #{@tag} qualifier=#{@qualifier} has_pointer=#{@b_has_pointer_member} #{locale_str}"
+    super( indent + 1 )
+    if @b_define then
+      @members_decl.show_tree( indent + 1 )
+    end
+  end
+end
+
+class FuncType < Type
+#  @paramlist::  ParamList
+#  @type:: return type : PtrType, ArrayType, FuncType, IntType, FloatType, ...
+#  @b_oneway:: bool: true, false
+#  @has_in:: bool :  has [in] parameter
+#  @has_inout:: bool : has [inout] parameter
+#  @has_out:: bool : has [out] parameter
+#  @has_send:: bool : has [send] parameter
+#  @has_receive:: bool : has [receive] parameter
+
+  def initialize( paramlist = nil )
+    super()
+
+    @has_in = false
+    @has_inout = false
+    @has_out = false
+    @has_send = false
+    @has_receive = false
+
+    @paramlist = paramlist
+    @b_oneway = false
+    if paramlist then
+      paramlist.check_param
+    else
+      @paramlist = ParamList.new( nil )
+    end
+    @paramlist.set_owner self  # ParamList
+    @paramlist.get_items.each{ |p|
+      case p.get_direction
+      when :IN
+        @has_in = true
+      when :INOUT
+        @has_inout = true
+      when :OUT
+        @has_out = true
+      when :SEND
+        @has_send = true
+      when :RECEIVE
+        @has_receive = true
+      else
+        raise "unkown direction"
+      end
+    }
+
+  end
+
+  def check	# 意味的誤りがあれば、文字列を返す
+    if @type.class == ArrayType then	# 配列を返す関数
+      return "function returning array"
+    elsif @type.class == FuncType then	# 関数を返す関数
+      return "function returning function"
+    end
+    return @type.check   # 関数の return する型のチェック
+
+    # パラメータの型のチェックは ParamList#check_param で行う
+  end
+
+  def check_struct_tag kind
+    @type.check_struct_tag kind
+    # ParamDecl でもチェックされるので、ここではチェックしない
+    # @paramlist.check_struct_tag kind
+  end
+
+  def check_init( locale, ident, initializer, kind, attribute = nil )
+    cdl_error2( locale, "T1028 $1: cannot initialize function pointer" , ident )
+    return
+  end
+
+  def set_type( type )
+    unless @type then
+      @type = type
+    else
+      @type.set_type( type )
+    end
+  end
+
+  #=== return type を返す
+  #
+  # return type を返す
+  # get_return_type とすべきだった
+  def get_type
+    @type
+  end
+
+  def get_type_str
+    return @type.get_type_str
+  end
+
+  def get_type_str_post
+    # 型だけを返す (仮引数の名前を含めない)
+    @paramlist.to_str( false )
+  end
+
+  def get_paramlist
+    @paramlist
+  end
+
+  def set_oneway( b_oneway )
+    @b_oneway = b_oneway
+
+    if ( ( @type.get_type_str != "ER" && @type.get_type_str != "void" ) || @type.get_type_str_post != "" ) then
+      cdl_error( "T1029 oneway function cannot return type \'$1$2\', \'void\' or \'ER\' is permitted" , @type.get_type_str, @type.get_type_str_post )
+    end
+
+    if @paramlist then
+      @paramlist.get_items.each{ |p|
+        if p.get_direction != :IN && p.get_direction != :SEND then
+          cdl_error( "T1030 oneway function cannot have $1 parameter for \'$2\'" , p.get_direction, p.get_name )
+        end
+      }
+    end
+  end
+
+  def is_oneway?
+    @b_oneway
+  end
+
+  #=== Push Pop Allocator が必要か？
+  # Transparent RPC の場合 oneway かつ in の配列(size_is, count_is, string のいずれかで修飾）がある
+  def need_PPAllocator?( b_opaque = false )
+    if @b_oneway || b_opaque then
+      return @paramlist.need_PPAllocator?( b_opaque )
+    else
+      return false
+    end
+  end
+
+  #=== パラメータが in, inout, out, send, receive を持つか
+  def has_in?
+    @has_in
+  end
+  def has_inout?
+    @has_inout
+  end
+  def has_out?
+    @has_out
+  end
+  def has_send?
+    @has_send
+  end
+  def has_receive?
+    @has_receive
+  end
+
+  #=== 入力方向のパラメータを持つか
+  def has_inward?
+    @has_in || @has_inout || @has_send
+  end
+  #=== 出力方向のパラメータを持つか
+  def has_outward?
+    @has_inout || @has_out || @has_receive
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    if @b_oneway then
+      puts "FunctType:  oneway=true #{locale_str}"
+    else
+      puts "FunctType:  oneway=false #{locale_str}"
+    end
+    super( indent + 1 )
+    if @paramlist then
+      @paramlist.show_tree( indent + 1 )
+    end
+    (indent+1).times { print "  " }
+    puts "return type:"
+    @type.show_tree( indent + 2 )
+  end
+end
+
+class ArrayType < Type
+#  @type:: element type :  ArrayType, FuncType, IntType, FloatType, ...
+#  @subscript:: Expression, nil if '[]'
+
+  include HasType
+
+  def initialize( subscript = nil )
+    super()
+    @subscript = subscript
+    initHasType
+  end
+
+  def set_type( type )
+    unless @type then
+      @type = type
+    else
+      @type.set_type( type )
+    end
+  end
+
+  #=== Array#qualifier(const, volatile) の設定
+  def set_qualifier( qualifier )
+    clone_type
+    @type.set_qualifier( qualifier )
+    super
+  end
+
+  # 配列要素が const なら const
+  def is_const?
+    @type.is_const?
+  end
+
+  # 配列要素が volatile なら volatile
+  def is_volatile?
+    @type.is_volatile?
+  end
+
+  def get_type
+    @type
+  end
+
+  def get_subscript
+    @subscript
+  end
+
+  def get_type_str
+    return "#{@type.get_type_str}"
+  end
+
+  def get_type_str_post
+    if @subscript
+      "[#{@subscript.eval_const(nil)}]#{@type.get_type_str_post}"
+    else
+      "[]#{@type.get_type_str_post}"
+    end
+    # "[#{@subscript.to_s}]#{@type.get_type_str_post}"
+  end
+
+  def check	# 意味的誤りがあれば、文字列を返す
+    if @type.class == FuncType then		# 関数の配列
+      return "array of function"
+    elsif @type.class == ArrayType then	# 添数なし配列の配列
+      unless @type.get_subscript then
+        return "subscript not specified"
+      end
+    end
+
+    return @type.check    # 配列要素の型をチェック
+  end
+
+  def check_struct_tag kind
+    @type.check_struct_tag kind
+  end
+
+  def check_init( locale, ident, initializer, kind, attribute = nil )
+    if ( initializer.instance_of?( Array ) ) then
+      # 要素数が指定されている場合、初期化要素数をチェック
+      if @subscript then
+        n_sub = @subscript.eval_const( nil )
+        if n_sub then
+          if initializer.length > n_sub then
+            cdl_error2( locale, "T9999 $1: too many initializer, $2 for $3" , ident, initializer.length, n_sub )
+          end
+        end
+      end
+      index = 0
+      initializer.each{ |i|
+        @type.check_init( locale, "#{ident}[#{index}]", i, kind, attribute = nil )
+        index += 1
+      }
+    else
+      cdl_error2( locale, "T1031 $1: unsuitable initializer for array" , ident )
+    end
+  end
+
+  def has_pointer?
+    @type.has_pointer?
+  end
+
+  def has_sized_pointer?
+    @type.has_sized_pointer?
+  end
+
+  def has_unsized_string?
+    @type.has_unsized_string?
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "ArrayType: #{locale_str}"
+    super( indent + 1 )
+    (indent+1).times { print "  " }
+    puts "type:"
+    @type.show_tree( indent + 2 )
+    (indent+1).times { print "  " }
+    puts "subscript:"
+    if @subscript then
+      @subscript.show_tree( indent + 2 )
+    else
+      (indent+2).times { print "  " }
+      puts "no subscript"
+    end
+  end
+end
+
+class PtrType < Type
+#  @type:: refer to : PtrType, FuncType, ArrayType, IntType, FloatType, ...
+#  @size:: Expr, or nil if not specified
+#  @count:: Expr, or nil if not specified
+#  @string:: Expr or -1(if size not specified) （string 引数）, or nil if not specified
+
+  include HasType
+
+  def initialize( referto = nil )
+    super()
+    @type   = referto
+    @size   = nil
+    @count  = nil
+    @string = nil
+    initHasType
+  end
+
+  def set_type( type )
+    unless @type then
+      @type = type
+    else
+      @type.set_type( type )	# 枝先の type を設定
+    end
+  end
+
+  def get_type_str
+    if @type.kind_of?( ArrayType ) || @type.kind_of?( FuncType ) then
+      parenthes = "("
+    else
+      parenthes = ""
+    end
+    return "#{@type.get_type_str}#{parenthes}*"
+  end
+
+  def get_type_str_post
+    if @type.kind_of?( ArrayType ) || @type.kind_of?( FuncType ) then
+      parenthes = ")"
+    else
+      parenthes = ""
+    end
+    "#{parenthes}#{@type.get_type_str_post}"
+  end
+
+  def check	# 意味的誤りがあれば、文字列を返す
+    return nil if @type == nil
+    @type.check
+  end
+
+  def check_struct_tag kind
+    if kind != :MEMBER  # 構造体メンバーの場合、ポインタの先の構造体タグをチェックしない
+      @type.check_struct_tag kind
+    end
+  end
+
+  def check_init( locale, ident, initializer, kind, attribute = nil )
+    if ( initializer.instance_of?( Expression ) ) then
+      val = initializer.eval_const2( nil, attribute )
+      if val.kind_of? PointerVal then
+        type = val.get_type  # PtrType
+        t1 = self
+        t2 = type
+        while( t1.kind_of?( PtrType ) && t2.kind_of?( PtrType ) )
+          t1 = t1.get_type
+          t2 = t2.get_type
+          if ( t1.class == t2.class ) && ( t1.get_bit_size == t2.get_bit_size ) then
+          elsif ( t1.kind_of?( CDefinedType) || t2.kind_of?( CDefinedType ) )&& t1.get_type_str == t2.get_type_str && t1.get_type_str_post && t2.get_type_str_post then
+            # int8_t などが、一方は .h に定義されているケース
+          else
+            cdl_error2( locale, "T1032 $1: incompatible pointer type" , ident )
+            break
+          end
+        end
+      elsif val.kind_of? IntegerVal then
+        if val.to_i != 0 then
+          cdl_error2( locale, "T1033 $1: need cast to assign integer to pointer" , ident )
+        end
+      elsif val.kind_of? StringVal then
+        # 文字列定数
+        # mikan L"wide string"
+        if @type.get_bit_size != -1 && @type.get_bit_size != -11 then  # -1: char_t
+          cdl_error2( locale, "T1034 $1: unsuitable string constant" , ident )
+        end
+      elsif ( val.instance_of?( Array ) ) then
+        i = 0
+        val.each { |ini|
+          @type.check_init( locale, "#{ident}[#{i}]", ini, kind, attribute = nil )
+          i += 1
+        }
+      elsif val.instance_of?( C_EXP ) then
+
+      else
+        cdl_error2( locale, "T1035 $1: unsuitable initializer for pointer" , ident )
+      end
+    elsif ( initializer.instance_of?( Array ) ) then
+      if @size == nil && @count == nil then
+        cdl_error2( locale, "T9999 $1: non-size_is pointer cannot have array initializer", ident )
+      end
+
+      i = 0
+      initializer.each { |ini|
+        @type.check_init( locale, "#{ident}[#{i}]", ini, kind, attribute = nil )
+        i += 1
+      }
+    elsif( initializer.instance_of?( C_EXP ) ) then
+
+    else
+      cdl_error2( locale, "T1036 $1: unsuitable initializer for pointer" , ident )
+    end
+  end
+
+  def get_referto
+    clone_type
+    @type
+  end
+
+  def set_scs( size, count, string, max, b_nullable )
+    @size = size
+    @count = count
+    @max = max
+    @b_nullable = b_nullable
+
+    # string は最も左側の ptr に作用する
+    if @type.kind_of?( PtrType ) then
+      # ptr_level が 2 以上であることは ParamDecl#initializer でチェックされる
+      clone_type
+      @type.set_scs( nil, nil, string, nil, false )
+    elsif @type.kind_of?( VoidType ) && ( size || count || string ) then
+      str = ""
+      if size then
+        str = "size_is"
+      end
+      if count then
+        if str then
+          str += ", "
+        end
+        str += "count_is"
+      end
+      if string then
+        if str then
+          str += ", "
+        end
+        str += "string"
+      end
+
+      cdl_error( "T1040 $1 specified for void pointer type", str )
+    else
+      @string = string
+    end
+
+    if (@size != nil) && (@b_nullable != false) then
+      cdl_error( "T9999 size_is & nullable cannot be specified simultaneously. If size is zero, pointer must be null")
+    end
+  end
+
+  def clear_max
+    @max = nil
+  end
+
+  def get_size
+    @size
+  end
+
+  def get_count
+    @count
+  end
+
+  def get_string
+    @string
+  end
+
+  #=== PtrType# size_is の最大値
+  def get_max
+    @max
+  end
+
+  def is_nullable?
+    return @b_nullable
+  end
+
+  def get_type
+    clone_type
+    @type
+  end
+
+  def has_pointer?
+    true
+  end
+
+  def has_sized_pointer?
+    @size != nil || @count != nil || @string.instance_of?( Expression ) || @type.has_sized_pointer?
+  end
+
+  def has_unsized_string?
+    @string == -1 || @type.has_unsized_string?
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "PtrType: qualifier=#{@qualifier}, nullable=#{@b_nullable} #{locale_str}"
+    super( indent + 1 )
+    (indent+1).times { print "  " }
+    if @size then
+      print "size=#{@size.to_s}, "
+    else
+      print "size=nil, "
+    end
+    if @max then
+      print "max=#{@size.to_s}, "
+    else
+      print "max=nil, "
+    end
+    if @count then
+      print "count=#{@count.to_s}, "
+    else
+      print "count=nil, "
+    end
+    if @string then
+      if @string.instance_of?( Expression ) then
+        print "string=#{@string.to_s}\n"
+      else
+        print "string=yes\n"
+      end
+    else
+      print "string=nil\n"
+    end
+
+    (indent+1).times { print "  " }
+    puts "type:"
+    @type.show_tree( indent + 2 )
+  end
+
+end
+
+#==  DescriptorType クラス
+# 動的結合で渡すデスクリプタ型
+class DescriptorType < Type
+  # @sinagure_nsp::NamespacePath
+
+  @@descriptors = {}
+
+  def initialize( signature_nsp )
+    @signature_nsp = signature_nsp
+    # check_signature ##
+    @@descriptors[ self ] = false
+  end
+
+  def get_type_str
+    "Descriptor( #{@signature_nsp.get_global_name} )"
+  end
+
+  def get_type_str_post
+    ""
+  end
+
+  def set_qualifier( qualifier )
+    cdl_error( "T9999 '$1' cannot be specified for Descriptor", qualfier.to_s )
+  end
+
+  def check
+  end
+
+  def check_init( locale, ident, initializer, kind, attribute = nil )
+    case kind
+    when :PARAMETER
+      # 引数は初期化できない
+    else
+      cdl_error2( locale, "T9999 Descriptor cannot be used for $1", kind)
+    end
+  end
+
+  def self.check_signature
+    @@descriptors.each{ |desc, val|
+      if val != true then
+        desc.check_signature
+        @@descriptors[ desc ] = true
+      end
+    }
+  end
+  
+  def check_signature
+    # p "Desc #{@signature_nsp.to_s}"
+    obj = Namespace.find @signature_nsp
+    if ! obj.kind_of? Signature then
+      cdl_error( "T9999 '$1': not signature or not found", @signature_nsp.to_s )
+    else
+      if obj.has_descriptor? then
+       # cdl_error( "T9999 '$1': has Descriptor in function parameter", @signature_nsp.to_s )
+      end
+      # @signature_nsp = obj.get_namespace_path
+    end
+  end
+
+  #== DescriptorType#
+  def get_signature
+    Namespace.find @signature_nsp
+  end
+end
+
+# 以下単体テストコード
+if $unit_test then
+  puts( "===== Unit Test: IntType ===== (types.rb)")
+  sizes = [ 8, 16, 32, 64 ]
+  sizes.each{ |n|
+    int = IntType.new n
+    printf( "%8s  max: %d  min:%d\n", "int#{n}_t", int.get_max, int.get_min )
+  }
+  puts ""
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/unjoin_plugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/unjoin_plugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/unjoin_plugin.rb	(revision 398)
@@ -0,0 +1,218 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2019 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# Marshal.dump で不都合な事項への対策
+# Proc は _dump_data が定義されていないため、定義する．
+# plugin 関係は、tecsflow に Plugin クラスが存在しないため、消しておく．
+
+# Proc は、Marshal.dump することができないため _dump_data を定義
+class Proc
+  def _dump_data
+    nil
+  end
+end
+
+class Object
+  @@visited = {}
+  @@n_visited = 0
+  @@n_found = 0
+  @@n_plugin_proxy = 0
+
+  # do nothing now. this function is used to find remained Proxy object.
+    def find_plugin level, object_list
+
+    # find_plugin_1 level, object_list
+    # print "find_plugin: n_visted=", @@n_visited, " (len=", @@visited.length, ")  found=", @@n_found, "  proxy=", @@n_plugin_proxy, "\n"
+  end
+
+  def find_plugin_1 level, object_list
+    if @@visited[ self ] then
+      return
+    end
+    @@visited[ self ] = true
+    @@n_visited += 1
+
+    if kind_of? Expression then
+      # print   # Expression では print が別に定義されている
+      get_elements.each{|ele|
+        ele.find_plugin_1 level+1, object_list
+      }
+      return
+    end
+
+    if level > 100 then    # 100 is enough now, 50 is too small
+      print "reached max level: "
+      if respond_to? :get_name then
+        print "#{get_name}(#{self.class.name})\n"
+      else
+        print "(#{self.class.name})\n"
+      end
+      return
+    end
+
+    object_list.push self                 ##### ここから return 不可
+
+    if (kind_of? Plugin) || (kind_of? HRPSVCPlugin) then
+      @@n_found += 1
+      print "Plugin found: #{self.class.name}\n"
+      object_list.each{ |obj|
+        if obj.respond_to? :get_name then
+          print "#{obj.get_name}(#{obj.class.name}), "
+        else
+          print "(#{obj.class.name}), "
+        end
+      }
+      print "\n"
+    elsif kind_of? Join::ThroughPluginProxy then
+      @@n_plugin_proxy += 1
+    end
+
+    level += 1
+    if kind_of? Array then
+      each{ |val|
+        val.find_plugin_1 level, object_list
+      }
+    elsif kind_of? Hash then
+      each{ |key, val|
+        key.find_plugin_1 level, object_list
+        val.find_plugin_1 level, object_list
+      }
+    else
+      instance_variables.each{|iv|
+        iv_val = instance_variable_get iv
+        iv_val.find_plugin_1 level, object_list
+      }
+    end
+    object_list.pop                       ##### ここまで return 不可
+  end
+end
+
+class Namespace
+  def unjoin_plugin
+    @signature_list.each{ |sig| sig.unjoin_plugin }
+    @celltype_list.each{ |ct| ct.unjoin_plugin }
+    @cell_list.each{ |cell| cell.unjoin_plugin }
+    @namespace_list.each{ |ns| ns.unjoin_plugin}
+  end
+end
+
+class Region < Namespace
+  def unjoin_plugin
+    if @domain_type then
+      @domain_type.unjoin_plugin
+    end
+    @cell_port_throug_plugin_list.each{ |key, po|
+      proxy = Join::ThroughPluginProxy.new po.get_cell_namespace_path, po.get_through_entry_port_name, po.get_through_entry_port_subscript
+      @cell_port_throug_plugin_list[ key ] = proxy
+    }
+    super
+  end
+end
+
+class DomainType < Node
+  def unjoin_plugin
+    @plugin = nil
+  end
+end
+
+class Signature < NSBDNode
+  def unjoin_plugin
+    @generate = nil
+  end
+end
+
+class Celltype < NSBDNode
+  def unjoin_plugin
+    @generate = nil
+    @generate_list = []
+    @plugin = nil
+  end
+end
+
+class Cell < NSBDNode
+  def unjoin_plugin
+    @generate = nil
+    @plugin   = nil
+    @join_list.get_items.each{ |j| j.unjoin_plugin }
+  end
+end
+
+class Join < BDNode
+  class ThroughPluginProxy
+    def initialize namespace_path, entry_port_name, entry_port_subscript
+      @namespace_path = namespace_path
+      @entry_port_name = entry_port_name
+      @entry_port_subscript = entry_port_subscript
+    end 
+    def get_cell_namespace_path
+      @namespace_path
+    end
+    def get_through_entry_port_name
+      @entry_port_name
+    end
+    def get_through_entry_port_subscript
+      @entry_port_subscript
+    end
+  end 
+
+  def unjoin_plugin
+    # @thourhg_generated_list is refered in get_rhs_cell, get_rhs_port
+    @through_generated_list.map!{|po| # po: plugin object
+      ThroughPluginProxy.new po.get_cell_namespace_path, po.get_through_entry_port_name, po.get_through_entry_port_subscript
+    }
+    @region_through_generated_list.map!{|po| # po: plugin object
+      ThroughPluginProxy.new po.get_cell_namespace_path, po.get_through_entry_port_name, po.get_through_entry_port_subscript
+    }
+    if @array_member2 then
+      @array_member2.each{ |j| 
+        if j then
+          j.unjoin_plugin2
+        end
+      }
+    end
+  end
+  def unjoin_plugin2
+    @through_generated_list.map!{|po| # po: plugin object
+      ThroughPluginProxy.new po.get_cell_namespace_path, po.get_through_entry_port_name, po.get_through_entry_port_subscript
+    }
+    @region_through_generated_list.map!{|po| # po: plugin object
+      ThroughPluginProxy.new po.get_cell_namespace_path, po.get_through_entry_port_name, po.get_through_entry_port_subscript
+    }
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/value.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/value.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/core/value.rb	(revision 398)
@@ -0,0 +1,579 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#= BaseVal 整数、浮動小数などの値を扱うクラスの基底クラス
+#
+# TECS の CDL で扱う値は、以下に分類される
+# ・整数
+# ・浮動小数
+# ・文字列
+# ・ブール値
+# 集成型（構造体、配列）と C_EXP はここでは扱わない
+#
+# このクラスで定義済みの演算子は、エラーとなる
+# 型により演算可能な場合、演算子をオーバーライドする
+#
+class BaseVal < Node
+  def ~@
+    unsupport "~"
+  end
+  def -@
+    unsupport "unary -"
+  end
+  def +@
+    unsupport "unary +"
+  end
+  def not # ! val
+    unsupport "!"
+  end
+
+  def * val
+    unsupport "*"
+  end
+  def / val
+    unsupport "/"
+  end
+  def % val
+    unsupport "%"
+  end
+  def + val
+    unsupport "+"
+  end
+  def - val
+    unsupport "-"
+  end
+  def << val
+    unsupport "<<"
+  end
+  def >> val
+    unsupport ">>"
+  end
+  def > val
+    unsupport ">"
+  end
+  def < val
+    unsupport "<"
+  end
+  def >= val
+    unsupport ">="
+  end
+  def <= val
+    unsupport "<="
+  end
+  def eq val # == val
+    unsupport "=="
+  end
+  def neq val # != val
+    unsupport "!="
+  end
+  def & val
+    unsupport "&"
+  end
+  def ^ val
+    unsupport "^"
+  end
+  def | val
+    unsupport "|"
+  end
+  def lAND val  # && val
+    unsupport "&&"
+  end
+  def lOR val   # || val
+    unsupport "||"
+  end
+  def cast( type )
+    unsupport "CAST"
+  end
+
+  def unsupport op
+    cdl_error( "V1001 $1: unable for $2" , op, self.class )
+  end
+
+  def to_s
+    raise "to_s not overridden"
+  end
+
+  def to_b
+    cdl_error( "V1002 $1: cannot cast to bool (implicitly)" , self.class )
+    false
+  end
+  def to_i
+    cdl_error( "V1003 $1: cannot cast to integer (implicitly)" , self.class )
+    1
+  end
+  def to_f
+    cdl_error( "V1004 $1: cannot cast to float (implicitly)" , self.class )
+    1.0
+  end
+end
+
+#= Pointer 値 (IntegerVal の Pointer 版)
+#
+# ポインタ値は、CDL で直接生成されることはない
+# 整数値のキャスト演算により生成される
+class PointerVal < BaseVal
+#@int_val:: IntegerVal: IntegerVal でなくてはならない
+#@ptr_type:: PtrType: ポインタの指す先の型
+
+  def initialize( int_val, ptr_type )
+    super()
+    @int_val = int_val
+    @ptr_type = ptr_type
+  end
+
+  #=== ポインタの指す先の型を得る
+  # PointerVal 専用のメソッド
+  def get_type
+    @ptr_type
+  end
+
+  def cast type
+    t = type.get_original_type   # typedef の元を得る
+    if t.kind_of? IntType then
+      val = t.check_and_clip( @int_val, :IntType )
+      return IntegerVal.new( val )
+    elsif t.kind_of? FloatType then
+      cdl_error( "V1005 Cannot cast pointer to float"  )
+      return FloatVal.new( @int_val )
+    elsif t.kind_of? PtrType then
+      return PointerVal.new( @int_val, type )
+    else
+      cdl_error( "V1006 pointer value cannot cast to $1" , type.class )
+      return nil
+    end
+  end
+
+  def to_s
+    "(#{@ptr_type.get_type_str}#{@ptr_type.get_type_str_post})#{sprintf("0x%X", @int_val)}"
+  end
+
+  def to_b
+    cdl_error( "V1007 convert pointer value to bool"  )
+    false
+  end
+  def to_i
+    cdl_error( "V1008 convert pointer value to integer without cast"  )
+    @val.to_i
+  end
+end
+
+#= IntegerVal: 整数値を扱うクラス
+class IntegerVal < BaseVal
+#@val:: Integer: value
+#@str:: string: literal
+#@sign:: Symbol: :SIGNED | :UNSIGNED
+#@size:: Symbol: :NORMAL | :SHORT | :LONG | :LONGLONG
+
+  def initialize( val, str = nil, sign = :SIGNED, size = :NORMAL )
+    super()
+    @val = val.to_i
+    @str = str
+    @sign = sign
+    @size = size
+  end
+
+  def ~@
+    IntegerVal.new( ~ @val )
+  end
+  def -@
+    IntegerVal.new( - @val )
+  end
+  def +@
+    self
+  end
+  def not # !
+      BoolVal.new( self.to_b )
+  end
+
+  def * val
+    if val.kind_of? FloatVal then
+      return FloatVal.new( @val.to_f * val.to_f )
+    else
+      return IntegerVal.new( @val * val.to_i )
+    end
+  end
+  def / val
+    if val.kind_of? FloatVal then
+      v2 = val.to_f   # to_f を2回評価しない
+      if v2 == 0.0 then
+        cdl_error( "V1009 / : divieded by zero"  )
+        return FloatVal.new( 1.0 )
+      end
+      return FloatVal.new( @val.to_f / v2 )
+    else
+      v2 = val.to_i   # to_i を2回評価しない
+      if v2 == 0 then
+        cdl_error( "V1010 / : divieded by zero"  )
+        return IntegerVal.new( 1 )
+      end
+      return IntegerVal.new( @val / v2 )
+    end
+  end
+  def % val
+    if val.kind_of? FloatVal then
+      v2 = val.to_f   # to_f を2回評価しない
+      if v2 == 0.0 then
+        cdl_error( "V1011 % : divieded by zero"  )
+        return FloatVal.new( 1.0 )
+      end
+      return FloatVal.new( @val.to_f % v2 )
+    else
+      v2 = val.to_i   # to_i を2回評価しない
+      if v2 == 0 then
+        cdl_error( "V1012 % : divieded by zero"  )
+        return IntegerVal.new( 1 )
+      end
+      return IntegerVal.new( @val % v2 )
+    end
+  end
+  def + val
+    if val.kind_of? FloatVal then
+      return FloatVal.new( @val.to_f + val.to_f )
+    else
+      return IntegerVal.new( @val + val.to_i )
+    end
+  end
+  def - val
+    if val.kind_of? FloatVal then
+      return FloatVal.new( @val.to_f - val.to_f )
+    else
+      return IntegerVal.new( @val - val.to_i )
+    end
+  end
+  def << val
+    return IntegerVal.new( @val << val.to_i )
+  end
+  def >> val
+    return IntegerVal.new( @val >> val.to_i )
+  end
+  def > val
+    if val.kind_of? FloatVal then
+      return BoolVal.new( @val.to_f > val.to_f )
+    else
+      return BoolVal.new( @val > val.to_i )
+    end
+  end
+  def < val
+    if val.kind_of? FloatVal then
+      return BoolVal.new( @val.to_f < val.to_f )
+    else
+      return BoolVal.new( @val < val.to_i )
+    end
+  end
+  def >= val
+    if val.kind_of? FloatVal then
+      return BoolVal.new( @val.to_f >= val.to_f )
+    else
+      return BoolVal.new( @val >= val.to_i )
+    end
+  end
+  def <= val
+    if val.kind_of? FloatVal then
+      return BoolVal.new( @val.to_f <= val.to_f )
+    else
+      return BoolVal.new( @val <= val.to_i )
+    end
+  end
+  def eq val # == val
+    if val.kind_of? FloatVal then
+      return BoolVal.new( @val.to_f == val.to_f )
+    else
+      return BoolVal.new( @val == val.to_i )
+    end
+  end
+  def neq val # != val
+    if val.kind_of? FloatVal then
+      return BoolVal.new( @val.to_f != val.to_f )
+    else
+      return BoolVal.new( @val != val.to_i )
+    end
+  end
+  def & val
+    IntegerVal.new( @val & val.to_i )
+  end
+  def ^ val
+    IntegerVal.new( @val ^ val.to_i )
+  end
+  def | val
+    IntegerVal.new( @val | val.to_i )
+  end
+  def lAND val  # && val
+    BoolVal.new( self.to_b && val.to_b )
+  end
+  def lOR val   # || val
+    BoolVal.new( self.to_b || val.to_b )
+  end
+  def cast( type )
+    t = type.get_original_type   # typedef の元を得る
+    if t.kind_of? IntType then
+      val = t.check_and_clip( @val, :IntType )
+      return IntegerVal.new( val )
+    elsif t.kind_of? FloatType then
+      return FloatVal.new( @val )
+    elsif t.kind_of? PtrType then
+      return PointerVal.new( @val, type )
+    elsif t.kind_of? BoolType then
+      return BoolVal.new( @val.to_b )
+    else
+      cdl_error( "V1013 integer value cannot cast to $1" , type.class )
+      return nil
+    end
+  end
+
+  def to_s
+    if @str then
+      @str
+    else
+      @val.to_s
+    end
+  end
+  def to_b
+    @val != 0
+  end
+  def to_i
+    @val
+  end
+  def to_f
+    @val.to_f
+  end
+end
+
+#= BoolVal: bool 値を扱うクラス
+class BoolVal < BaseVal
+#@val:: bool: true, false
+
+  def initialize( val )
+    super()
+    if val == true || val == false
+      @val = val
+    elsif val.to_i != 0
+      @val = true
+    else
+      @val = false
+    end
+    # raise "No boolean val" if val != true && val != false
+  end
+
+  def not # ! val
+      BoolVal.new( ! @val )
+  end
+  def eq val # == val
+    if val.kind_of? BoolVal then
+      return BoolVal.new( self.to_i == val.to_i )
+    else
+      cdl_error( "V1014 comparing bool value with \'$1\'" , val.class )
+      return BoolVal.new( false )
+    end
+  end
+  def neq val # != val
+    if val.kind_of? BoolVal then
+      return BoolVal.new( self.to_i != val.to_i )
+    else
+      cdl_error( "V1015 comparing bool value with \'$1\'" , val.class )
+      return BoolVal.new( false )
+    end
+  end
+  def lAND val  # && val
+    BoolVal.new( self.to_b && val.to_b )
+  end
+  def lOR val   # || val
+    BoolVal.new( self.to_b || val.to_b )
+  end
+  def cast( type )
+    t = type.get_original_type   # typedef の元を得る
+    if @val then
+      val = 1
+    else
+      val = 0
+    end
+    if t.kind_of? IntType then
+      return IntegerVal.new( val )
+    elsif t.kind_of? FloatType then
+      return FloatVal.new( val )
+    elsif t.kind_of? BoolType then
+      return self
+    else
+      cdl_error( "V1016 bool value cannot cast to $1" , type.class )
+      return nil
+    end
+  end
+
+  def to_s
+    if @val
+      return "true"
+    else
+      return "false"
+    end
+  end
+  def to_b
+    @val
+  end
+  def to_i
+    return 0 if @val == false
+    return 1
+  end
+  def to_f
+    return 0.0 if @val == false
+    return 1.0
+  end
+
+  attr_reader :val
+end
+
+#= FloatVal: 実数値を扱うクラス
+class FloatVal < BaseVal
+#@val:: Float
+  def initialize( val )
+    super()
+    @val = val.to_f
+  end
+
+  def -@
+    FloatVal.new( - @val )
+  end
+  def +@
+    self
+  end
+  def * val
+    FloatVal.new( @val * val.to_f )
+  end
+  def / val
+    v2 = val.to_f   # to_f を2回評価しない
+    if v2 == 0.0 then
+      cdl_error( "V1017 / : divieded by zero"  )
+      return FloatVal.new( 1.0 )
+    end
+    return FloatVal.new( @val.to_f / v2 )
+  end
+  def % val
+    v2 = val.to_f   # to_f を2回評価しない
+    if v2 == 0.0 then
+      cdl_error( "V1018 % : divieded by zero"  )
+      return FloatVal.new( 1.0 )
+    end
+    return FloatVal.new( @val.to_f % v2 )
+  end
+  def + val
+    FloatVal.new( @val + val.to_f )
+  end
+  def - val
+    FloatVal.new( @val - val.to_f )
+  end
+  def > val
+    BoolVal.new( @val > val.to_f )
+  end
+  def < val
+    BoolVal.new( @val < val.to_f )
+  end
+  def >= val
+    BoolVal.new( @val >= val.to_f )
+  end
+  def <= val
+    BoolVal.new( @val <= val.to_f )
+  end
+  def eq val # == val
+    BoolVal.new( @val == val.to_f )
+  end
+  def neq val # != val
+    BoolVal.new( @val != val.to_f )
+  end
+  def cast( type )
+    t = type.get_original_type   # typedef の元を得る
+    if t.kind_of? IntType then
+      val = t.check_and_clip( @val, :FloatType )
+      return IntegerVal.new( val )
+    elsif t.kind_of? FloatType then
+      return self
+    else
+      cdl_error( "V1019 floating value cannot cast to $1" , type )
+      return self
+    end
+  end
+
+  def to_b
+    cdl_error( "V1020 convert floating value to bool without cast"  )
+    @val.to_i
+  end
+  def to_i
+    cdl_error( "V1021 convert floating value to integer without cast"  )
+    @val.to_i
+  end
+  def to_s
+    @val.to_s
+  end
+  def to_f
+    @val
+  end
+end
+
+#= 文字列リテラルを扱うクラス
+class StringVal < BaseVal
+#@str:: Token:
+#@specifier:: Symbol: :WIDE, :NORMAL
+
+  def initialize( str, spec = :NORMAL )
+    super()
+    @str = str
+    @specifier = spec   # mikan L"str" wide 文字列未対応
+  end
+
+  #===
+  #
+  # string の cast はできない mikan ポインタ型への cast はできるべき
+  def cast type
+    t = type.get_original_type   # typedef の元を得る
+    if t.kind_of? IntType then
+      cdl_error( "V1022 string cannot cast to integer"  )
+    elsif t.kind_of? FloatType then
+      cdl_error( "V1023 string cannot cast to float"  )
+    elsif t.kind_of? PtrType then
+      cdl_error( "V1024 string cannot cast to pointer"  )
+    else
+      cdl_error( "V1025 string cannot cast to $1" , type )
+    end
+  end
+    
+  def to_s
+    @str.to_s
+  end
+
+  def val
+    @str.to_s   # Token で扱われていた名残 (val を取り出す)
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_console_en_US.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_console_en_US.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_console_en_US.rb	(revision 398)
@@ -0,0 +1,1174 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+
+# Console Messages for en_US 
+class TECSMsg
+
+###
+# エラーメッセージ
+@@error_message = {}
+
+### C_parser.y.rb
+# B1001 need parameter name"
+@@error_message[ :"B1001" ] = "need parameter name"
+
+# B1002 while open or reading \'$1\'"
+@@error_message[ :"B1002" ] = "while open or reading \'$1\'"
+
+# B1003 Unexpected EOF"
+@@error_message[ :"B1003" ] = "Unexpected EOF"
+
+# B1004 syntax error near \'$1\'"
+@@error_message[ :"B1004" ] = "syntax error near \'$1\'"
+
+### ctypes.rb
+# C1001 $1: mismatch, suitable for integer types"
+@@error_message[ :"C1001" ] = "$1: mismatch, suitable for integer types"
+
+# C1002 $1 not compatible with previous one $2"
+@@error_message[ :"C1002" ] = "$1 not compatible with previous one $2"
+
+# C1003 $1 & $2 incompatible  (\'long double\' not support)"
+@@error_message[ :"C1003" ] = "$1 & $2 incompatible  (\'long double\' not support)"
+
+# C1004 $1: qualifier respecified. previous one: $2"
+@@error_message[ :"C1004" ] = "$1: qualifier respecified. previous one: $2"
+
+### expression.rb
+# E1001 $1: not found"
+@@error_message[ :"E1001" ] = "$1: not found"
+
+# E1002 $1: not constant (port)"
+@@error_message[ :"E1002" ] = "$1: not constant (port)"
+
+# E1003 $1: not constant"
+@@error_message[ :"E1003" ] = "$1: not constant"
+
+# E1004 cannot evaluate \'[]\' operator"
+@@error_message[ :"E1004" ] = "cannot evaluate \'[]\' operator"
+
+# E1005 cannot evaluate \'.\' operator"
+@@error_message[ :"E1005" ] = "cannot evaluate \'.\' operator"
+
+# E1006 cannot evaluate \'->\' operator"
+@@error_message[ :"E1006" ] = "cannot evaluate \'->\' operator"
+
+# E1007 cannot evaluate \'sizeof\' operator"
+@@error_message[ :"E1007" ] = "cannot evaluate \'sizeof\' operator"
+
+# E1008 cannot evaluate \'sizeof\' operator"
+@@error_message[ :"E1008" ] = "cannot evaluate \'sizeof\' operator"
+
+# E1009 cannot evaluate \'&\' operator"
+@@error_message[ :"E1009" ] = "cannot evaluate \'&\' operator"
+
+# E1010 cannot evaluate \'*\' operator"
+@@error_message[ :"E1010" ] = "cannot evaluate \'*\' operator"
+
+# E1011 cannot evaluate unary + for $1"
+@@error_message[ :"E1011" ] = "cannot evaluate unary + for $1"
+
+# E1012 $1: not found in parameter list"
+@@error_message[ :"E1012" ] = "$1: not found in parameter list"
+
+# E1013 \'*\': operand is not pointer value"
+@@error_message[ :"E1013" ] = "\'*\': operand is not pointer value"
+
+# E1014 $1: elements_get_type: sorry not supported"
+@@error_message[ :"E1014" ] = "$1: elements_get_type: sorry not supported"
+
+# E1015 \'$1\': direction mismatch for $2, $3 required"
+@@error_message[ :"E1015" ] = "\'$1\': direction mismatch for $2, $3 required"
+
+# E1016 $1: elements_check_dir_for_param: sorry not supported"
+@@error_message[ :"E1016" ] = "$1: elements_check_dir_for_param: sorry not supported"
+
+# E1017 $1: rhs not \'Cell.ePort\' form"
+@@error_message[ :"E1017" ] = "$1: rhs not \'Cell.ePort\' form"
+
+# E1018 $1: namespace cannot be specified"
+@@error_message[ :"E1018" ] = "$1: namespace cannot be specified"
+
+# E1019 $1: rhs not in 'allocator_entry_port' form"
+@@error_message[ :"E1019" ] = "$1: rhs not in 'allocator_entry_port' form"
+
+# E1020 rhs not in 'call_port.func.param' form for $1_$2"
+@@error_message[ :"E1020" ] = "rhs not in 'call_port.func.param' form for $1_$2"
+
+### bnf.y.rb
+# G1001 need specifier for \'$1\'"
+@@error_message[ :"G1001" ] = "need specifier for \'$1\'"
+
+# G1002 need parameter name"
+@@error_message[ :"G1002" ] = "need parameter name"
+
+# G1003 need parameter name"
+@@error_message[ :"G1003" ] = "need parameter name"
+
+# G1004 impossible array type 0"
+@@error_message[ :"G1004" ] = "impossible array type 0"
+
+# G1005 impossible array type 1"
+@@error_message[ :"G1005" ] = "impossible array type 1"
+
+# G1006 impossible array type 2"
+@@error_message[ :"G1006" ] = "impossible array type 2"
+
+# G1007 impossible array type 3"
+@@error_message[ :"G1007" ] = "impossible array type 3"
+
+# G1008 impossible function type"
+@@error_message[ :"G1008" ] = "impossible function type"
+
+# G1009 unexpected specifier"
+@@error_message[ :"G1009" ] = "unexpected specifier"
+
+# G1010 Not function"
+@@error_message[ :"G1010" ] = "Not function"
+
+# G1011 Not function"
+@@error_message[ :"G1011" ] = "Not function"
+
+# G1012 $1 : cannot put specifier here"
+@@error_message[ :"G1012" ] = "$1 : cannot put specifier here"
+
+# G1013 unexpected specifier"
+@@error_message[ :"G1013" ] = "unexpected specifier"
+
+# G1014 while open or reading \'$1\'"
+@@error_message[ :"G1014" ] = "while open or reading \'$1\'"
+
+# G1015 Unexpected EOF"
+@@error_message[ :"G1015" ] = "Unexpected EOF"
+
+# G1016 syntax error near \'$1\'"
+@@error_message[ :"G1016" ] = "syntax error near \'$1\'"
+
+### plugin.rb
+# P1001 plugin arg: cannot find identifier in $1"
+@@error_message[ :"P1001" ] = "plugin arg: cannot find identifier in $1"
+
+# P1002 plugin arg: expecting \'=\' not \'$1\'"
+@@error_message[ :"P1002" ] = "plugin arg: expecting \'=\' not \'$1\'"
+
+# P1003 plugin arg: unexpected $1"
+@@error_message[ :"P1003" ] = "plugin arg: unexpected $1"
+
+# P1004 $1: unknown plugin argument\'s identifier\n  $2 are acceptable for RPCPlugin."
+@@error_message[ :"P1004" ] = "$1: unknown plugin argument\'s identifier\n  $2 are acceptable for RPCPlugin."
+
+### pluginModule.rb
+# P2001 $1.rb : fail to load plugin"
+@@error_message[ :"P2001" ] = "$1.rb : fail to load plugin"
+
+# P2002 $1: not kind of $2"
+@@error_message[ :"P2002" ] = "$1: not kind of $2"
+
+# P2003 $1: load failed"
+@@error_message[ :"P2003" ] = "$1: load failed"
+
+# P2004 $1: open error \'$2\'"
+@@error_message[ :"P2004" ] = "$1: open error \'$2\'"
+
+# P2005 $1: plugin error in gen_through_cell_code "
+@@error_message[ :"P2005" ] = "$1: plugin error in gen_through_cell_code "
+
+# P2006 $1: close error \'$2\'"
+@@error_message[ :"P2006" ] = "$1: close error \'$2\'"
+
+# P2007 $1: fail to generate post code"
+@@error_message[ :"P2007" ] = "$1: fail to generate post code"
+
+### componentobj.rb
+# S1001 context specifier duplicate"
+@@error_message[ :"S1001" ] = "context specifier duplicate"
+
+# S1002 \'$1\': unknown specifier for signature"
+@@error_message[ :"S1002" ] = "\'$1\': unknown specifier for signature"
+
+# S1003 $1: \'alloc\' 1st parameter neither [in] integer type nor [out] double pointer type
+@@error_message[ :"S1003" ] = "$1: \'alloc\' 1st parameter neither [in] integer type nor [out] double pointer type"
+
+# S1004 $1: \'alloc\' 2nd parameter not [in] double pointer"
+@@error_message[ :"S1004" ] = "$1: \'alloc\' 2nd parameter not [in] double pointer"
+
+# S1005 $1: \'alloc\' has no parameter, unsuitable for allocator signature"
+@@error_message[ :"S1005" ] = "$1: \'alloc\' has no parameter, unsuitable for allocator signature"
+
+# S1006 $1: \'dealloc\' 1st parameter not [in] pointer type"
+@@error_message[ :"S1006" ] = "$1: \'dealloc\' 1st parameter not [in] pointer type"
+
+# S1007 "
+     # S1007 $1: \'dealloc\' cannot has 2nd parameter"
+# @@error_message[ :"S1007" ] = "$1: \'dealloc\' cannot has 2nd parameter"
+
+# S1008 $1: \'dealloc\' has no parameter, unsuitable for allocator signature"
+@@error_message[ :"S1008" ] = "$1: \'dealloc\' has no parameter, unsuitable for allocator signature"
+
+# S1009 $1: \'alloc\' function not found, unsuitable for allocator signature"
+@@error_message[ :"S1009" ] = "$1: \'alloc\' function not found, unsuitable for allocator signature"
+
+# S1010 $1: \'dealloc\' function not found, unsuitable for allocator signature"
+@@error_message[ :"S1010" ] = "$1: \'dealloc\' function not found, unsuitable for allocator signature"
+
+# S1011 $1: size_is specified for non-pointer type"
+@@error_message[ :"S1011" ] = "$1: size_is specified for non-pointer type"
+
+# S1012 $1: unsuitable initializer, need array initializer"
+@@error_message[ :"S1012" ] = "$1: unsuitable initializer, need array initializer"
+
+# S1013 $1: too many initializer, $2 for $3"
+@@error_message[ :"S1013" ] = "$1: too many initializer, $2 for $3"
+
+# S1014 generate specifier duplicate"
+@@error_message[ :"S1014" ] = "generate specifier duplicate"
+
+# S1015 $1 cannot be specified for composite"
+@@error_message[ :"S1015" ] = "$1 cannot be specified for composite"
+
+# S1016 $1 not found"
+@@error_message[ :"S1016" ] = "$1 not found"
+
+# S1017 $1 : neither celltype nor cell"
+@@error_message[ :"S1017" ] = "$1 : neither celltype nor cell"
+
+# S1018 $1 : not singleton cell"
+@@error_message[ :"S1018" ] = "$1 : not singleton cell"
+
+# S1019 \'$1\' : not entry port"
+@@error_message[ :"S1019" ] = "\'$1\' : not entry port"
+
+# S1020 \'$1\' : required port cannot be array"
+@@error_message[ :"S1020" ] = "\'$1\' : required port cannot be array"
+
+# S1021 $1 : require cannot have same signature with \'$2\'"
+@@error_message[ :"S1021" ] = "$1 : require cannot have same signature with \'$2\'"
+
+# S1022 $1.$2 : \'$3\' conflict function name in $4.$5"
+@@error_message[ :"S1022" ] = "$1.$2 : \'$3\' conflict function name in $4.$5"
+
+# S1023 $1: fail to new"
+@@error_message[ :"S1023" ] = "$1: fail to new"
+
+# S1024 $1: multiple cell for singleton celltype"
+@@error_message[ :"S1024" ] = "$1: multiple cell for singleton celltype"
+
+# S1025 not found reachable cell for require \'$1\' in celltype \'$2\'"
+@@error_message[ :"S1025" ] = "not found reachable cell for require \'$1\' in celltype \'$2\'"
+
+# S1026 required cell \'$1\' not reachable"
+@@error_message[ :"S1026" ] = "required cell \'$1\' not reachable"
+
+# S1027 \'$1\' celltype not found"
+@@error_message[ :"S1027" ] = "\'$1\' celltype not found"
+
+# S1028 \'$1\' not celltype"
+@@error_message[ :"S1028" ] = "\'$1\' not celltype"
+
+# S1029 $1 mismatch with previous one"
+@@error_message[ :"S1029" ] = "$1 mismatch with previous one"
+
+# S1030 $1: celltype mismatch with previous one"
+@@error_message[ :"S1030" ] = "$1: celltype mismatch with previous one"
+
+# S1031 $1 region \'$2\' mismatch  with previous one \'$3\'"
+@@error_message[ :"S1031" ] = "$1 region \'$2\' mismatch  with previous one \'$3\'"
+
+# S1032 $1: duplicate cell"
+@@error_message[ :"S1032" ] = "$1: duplicate cell"
+
+# S1033 rhs expression is not supported. Only attribute is permitted on current version."
+@@error_message[ :"S1033" ] = "rhs expression is not supported. Only attribute is permitted on current version."
+
+# S1034 $1 : cannot refer to $2\'s attribute here. Use \'composite.$3\' to refer to composite celltype\'s"
+@@error_message[ :"S1034" ] = "$1 : cannot refer to $2\'s attribute here. Use \'composite.$3\' to refer to composite celltype\'s"
+
+# S1035 composite : cannot specify out of composite celltype definition"
+@@error_message[ :"S1035" ] = "composite : cannot specify out of composite celltype definition"
+
+# S1036 $1 : cannot refer to $2\'s here. Use \'composite.$3\' to refer to composite celltype\'s"
+@@error_message[ :"S1036" ] = "$1 : cannot refer to $2\'s here. Use \'composite.$3\' to refer to composite celltype\'s"
+
+# S1037 $1: celltype plugin fail to new_cell"
+@@error_message[ :"S1037" ] = "$1: celltype plugin fail to new_cell"
+
+# S1038 $1.$2: self allocator not supported for array entry port"
+@@error_message[ :"S1038" ] = "$1.$2: self allocator not supported for array entry port"
+
+# S1039 \'$1\': unknown specifier for cell"
+@@error_message[ :"S1039" ] = "\'$1\': unknown specifier for cell"
+
+# S1040 array not supported for relay allocator"
+@@error_message[ :"S1040" ] = "array not supported for relay allocator"
+
+# S1041 \'$1_$2_$3\': not joined. cannot create internal join for relay allocator"
+@@error_message[ :"S1041" ] = "\'$1_$2_$3\': not joined. cannot create internal join for relay allocator"
+
+# S1042 call port \'$1\' not initialized in cell \'$2\'"
+@@error_message[ :"S1042" ] = "call port \'$1\' not initialized in cell \'$2\'"
+
+# S1043 call port \'$1\' not initialized in cell \'$2\'. this call port is created by tecsgen. check allocator specifier"
+@@error_message[ :"S1043" ] = "call port \'$1\' not initialized in cell \'$2\'. this call port is created by tecsgen. check allocator specifier"
+
+# S1044 $1: array initializer too many or few, $2 for $3"
+@@error_message[ :"S1044" ] = "$1: array initializer too many or few, $2 for $3"
+
+# S1045 $1[$2]: not initialized"
+@@error_message[ :"S1045" ] = "$1[$2]: not initialized"
+
+# S1046 $1[$2]: not initialized"
+@@error_message[ :"S1046" ] = "$1[$2]: not initialized"
+
+# S1047 size_is pointer cannot be exposed for composite attribute"
+@@error_message[ :"S1047" ] = "size_is pointer cannot be exposed for composite attribute"
+
+# S1048 $1: size_is specified for non-pointer type"
+@@error_message[ :"S1048" ] = "$1: size_is specified for non-pointer type"
+
+# S1049 $1: size_is arg not constant"
+@@error_message[ :"S1049" ] = "$1: size_is arg not constant"
+
+# S1050 unsuitable initializer, need array initializer"
+@@error_message[ :"S1050" ] = "unsuitable initializer, need array initializer"
+
+# S1051 too many initializer for array, $1 for $2"
+@@error_message[ :"S1051" ] = "too many initializer for array, $1 for $2"
+
+# S1052 attribute \'$1\' not initialized in cell \'$2\'"
+@@error_message[ :"S1052" ] = "attribute \'$1\' not initialized in cell \'$2\'"
+
+# S1053 $1 must be singleton. inner cell \'$2\' is singleton"
+@@error_message[ :"S1053" ] = "$1 must be singleton. inner cell \'$2\' is singleton"
+
+# S1054 $1 : specified active but has no active in this celltype"
+@@error_message[ :"S1054" ] = "$1 : specified active but has no active in this celltype"
+
+# S1055 $1 must be active. inner cell \'$2\' is active"
+@@error_message[ :"S1055" ] = "$1 must be active. inner cell \'$2\' is active"
+
+# S1056 $1 : cannot export, nothing designated"
+@@error_message[ :"S1056" ] = "$1 : cannot export, nothing designated"
+
+# S1057 $1 not found in $2"
+@@error_message[ :"S1057" ] = "$1 not found in $2"
+
+# S1058 \'$1\' : cannot export var"
+@@error_message[ :"S1058" ] = "\'$1\' : cannot export var"
+
+# S1059 \'$1\' : exporting attribute. write in cell or use \'=\' to export attribute"
+@@error_message[ :"S1059" ] = "\'$1\' : exporting attribute. write in cell or use \'=\' to export attribute"
+
+# S1060 \'$1\' : port type mismatch. $2 type is allowed here."
+@@error_message[ :"S1060" ] = "\'$1\' : port type mismatch. $2 type is allowed here."
+
+# S1061 \'$1\' : not defined"
+@@error_message[ :"S1061" ] = "\'$1\' : not defined"
+
+# S1062 $1 has no export definition"
+@@error_message[ :"S1062" ] = "$1 has no export definition"
+
+# S1063 $1 is port but previously defined as an attribute"
+@@error_message[ :"S1063" ] = "$1 is port but previously defined as an attribute"
+
+# S1064 $1 : type \'$2$3\' mismatch with pprevious definition\'$4$5\'"
+@@error_message[ :"S1064" ] = "$1 : type \'$2$3\' mismatch with pprevious definition\'$4$5\'"
+
+# S1065 $1 : port type $2 mismatch with previous definition $3"
+@@error_message[ :"S1065" ] = "$1 : port type $2 mismatch with previous definition $3"
+
+# S1066 $1 : signature \'$2\' mismatch with previous definition \'$3\'"
+@@error_message[ :"S1066" ] = "$1 : signature \'$2\' mismatch with previous definition \'$3\'"
+
+# S1067 $1 : array size mismatch with previous definition"
+@@error_message[ :"S1067" ] = "$1 : array size mismatch with previous definition"
+
+# S1068 $1 : optional specifier mismatch with previous definition"
+@@error_message[ :"S1068" ] = "$1 : optional specifier mismatch with previous definition"
+
+# S1069 $1 is an attribute but previously defined as a port"
+@@error_message[ :"S1069" ] = "$1 is an attribute but previously defined as a port"
+
+# S1070 $1: size_is pointer cannot be exposed for composite attribute"
+@@error_message[ :"S1070" ] = "$1: size_is pointer cannot be exposed for composite attribute"
+
+# S1071 $1 cannot be specified for composite"
+@@error_message[ :"S1071" ] = "$1 cannot be specified for composite"
+
+# S1072 $1: entry port: sizeless array not supported in current version"
+@@error_message[ :"S1072" ] = "$1: entry port: sizeless array not supported in current version"
+
+# S1073 Not constant expression $1"
+@@error_message[ :"S1073" ] = "Not constant expression $1"
+
+# S1074 Not Integer $1"
+@@error_message[ :"S1074" ] = "Not Integer $1"
+
+# S1075 \'$1\' signature not found"
+@@error_message[ :"S1075" ] = "\'$1\' signature not found"
+
+# S1076 \'$1\' not signature"
+@@error_message[ :"S1076" ] = "\'$1\' not signature"
+
+# S1077 inline: cannot be specified for call port"
+@@error_message[ :"S1077" ] = "inline: cannot be specified for call port"
+
+# S1078 optional: cannot be specified for entry port"
+@@error_message[ :"S1078" ] = "optional: cannot be specified for entry port"
+
+# S1079 allocator: cannot be specified for call port"
+@@error_message[ :"S1079" ] = "allocator: cannot be specified for call port"
+
+# S1080 duplicate allocator specifier"
+@@error_message[ :"S1080" ] = "duplicate allocator specifier"
+
+# S1081 self allocator not supported yet"
+@@error_message[ :"S1081" ] = "self allocator not supported yet"
+
+# S1082 function \'$1\' not found in signature"
+@@error_message[ :"S1082" ] = "function \'$1\' not found in signature"
+
+# S1083 \'$1\' not found in function \'$2\'"
+@@error_message[ :"S1083" ] = "\'$1\' not found in function \'$2\'"
+
+# S1084 \'$1\' in function \'$2\' is not send or receive"
+@@error_message[ :"S1084" ] = "\'$1\' in function \'$2\' is not send or receive"
+
+# S1085 duplicate allocator specifier for \'$1_$2\'"
+@@error_message[ :"S1085" ] = "duplicate allocator specifier for \'$1_$2\'"
+
+# S1086 rhs not call_port.func.param for $1_$2"
+@@error_message[ :"S1086" ] = "rhs not call_port.func.param for $1_$2"
+
+# S1087 function \'$1\' not found in signature \'$2\'"
+@@error_message[ :"S1087" ] = "function \'$1\' not found in signature \'$2\'"
+
+# S1088 \'$1\' not found in function \'$2\'"
+@@error_message[ :"S1088" ] = "\'$1\' not found in function \'$2\'"
+
+# S1089 relay allocator send/receive mismatch between $1.$2 and $3_$4.$5"
+@@error_message[ :"S1089" ] = "relay allocator send/receive mismatch between $1.$2 and $3_$4.$5"
+
+# S1090 \'$1\' in function \'$2\' is not send or receive"
+@@error_message[ :"S1090" ] = "\'$1\' in function \'$2\' is not send or receive"
+
+# S1091 call port \'$1\' not found in celltype $2"
+@@error_message[ :"S1091" ] = "call port \'$1\' not found in celltype $2"
+
+# S1092 \'$1\' not namespace"
+@@error_message[ :"S1092" ] = "\'$1\' not namespace"
+
+# S1093 $1 : undefined cell"
+@@error_message[ :"S1093" ] = "$1 : undefined cell"
+
+# S1094 $1: pointer is not constant. check \'const\'"
+@@error_message[ :"S1094" ] = "$1: pointer is not constant. check \'const\'"
+
+# S1095 $1: not constant"
+@@error_message[ :"S1095" ] = "$1: not constant"
+
+# S1096 $1: should be int, float, bool or pointer type"
+@@error_message[ :"S1096" ] = "$1: should be int, float, bool or pointer type"
+
+# S1097 $1: has no initializer"
+@@error_message[ :"S1097" ] = "$1: has no initializer"
+
+# S1098 $1: has unsuitable initializer"
+@@error_message[ :"S1098" ] = "$1: has unsuitable initializer"
+
+# S1099 array subscript not constant"
+@@error_message[ :"S1099" ] = "array subscript not constant"
+
+# S1100 $1: cannot initialize var"
+@@error_message[ :"S1100" ] = "$1: cannot initialize var"
+
+# S1101 \'$1\' cannot initialize entry port"
+@@error_message[ :"S1101" ] = "\'$1\' cannot initialize entry port"
+
+# S1102 $1: must specify array subscript here"
+@@error_message[ :"S1102" ] = "$1: must specify array subscript here"
+
+# S1103 $1: need array subscript"
+@@error_message[ :"S1103" ] = "$1: need array subscript"
+
+# S1104 $1: need array subscript number. ex. \'[0]\'"
+@@error_message[ :"S1104" ] = "$1: need array subscript number. ex. \'[0]\'"
+
+# S1105 $1: cannot specify array subscript here"
+@@error_message[ :"S1105" ] = "$1: cannot specify array subscript here"
+
+# S1106 $1: cannot specify array subscript number. use \'[]\'"
+@@error_message[ :"S1106" ] = "$1: cannot specify array subscript number. use \'[]\'"
+
+# S1107 to export port, use \'cCall => composite.cCall\'"
+@@error_message[ :"S1107" ] = "to export port, use \'cCall => composite.cCall\'"
+
+# S1108 $1: rhs not \'Cell.ePort\' form"
+@@error_message[ :"S1108" ] = "$1: rhs not \'Cell.ePort\' form"
+
+# S1109 \'$1\' not found"
+@@error_message[ :"S1109" ] = "\'$1\' not found"
+
+# S1110 \'$1\' not cell"
+@@error_message[ :"S1110" ] = "\'$1\' not cell"
+
+# S1111 \'$1\' not found"
+@@error_message[ :"S1111" ] = "\'$1\' not found"
+
+# S1112 \'$1\' not entry port"
+@@error_message[ :"S1112" ] = "\'$1\' not entry port"
+
+# S1113 \'$1\' signature mismatch"
+@@error_message[ :"S1113" ] = "\'$1\' signature mismatch"
+
+# S1114 \'$1\' should be array"
+@@error_message[ :"S1114" ] = "\'$1\' should be array"
+
+# S1115 $1[$2]: subscript out of range (< $3)"
+@@error_message[ :"S1115" ] = "$1[$2]: subscript out of range (< $3)"
+
+# S1116 \'$1\' entry port is not array"
+@@error_message[ :"S1116" ] = "\'$1\' entry port is not array"
+
+# S1117 \'$1\' not in celltype"
+@@error_message[ :"S1117" ] = "\'$1\' not in celltype"
+
+# S1118 $1: going out from region \'$2\' not permitted"
+@@error_message[ :"S1118" ] = "$1: going out from region \'$2\' not permitted"
+
+# S1119 $1: going from region \'$2\' to \'$3\' not permitted"
+@@error_message[ :"S1119" ] = "$1: going from region \'$2\' to \'$3\' not permitted"
+
+# S1120 $1: going in to region \'$2\' not permitted"
+@@error_message[ :"S1120" ] = "$1: going in to region \'$2\' not permitted"
+
+# S1121 \'$1\' in region \'$2\' cannot be directly joined $3 in  $4"
+@@error_message[ :"S1121" ] = "\'$1\' in region \'$2\' cannot be directly joined $3 in  $4"
+
+# S1122 $1 : not port: \'through\' can be specified only for port"
+@@error_message[ :"S1122" ] = "$1 : not port: \'through\' can be specified only for port"
+
+# S1123 $1 : not port: \'through\' can be specified only for port"
+@@error_message[ :"S1123" ] = "$1 : not port: \'through\' can be specified only for port"
+
+# S1124 $1: plugin function failed: \'get_through_entry_port_name\'"
+@@error_message[ :"S1124" ] = "$1: plugin function failed: \'get_through_entry_port_name\'"
+
+# S1125 $1: not generated cell \'$2\'"
+@@error_message[ :"S1125" ] = "$1: not generated cell \'$2\'"
+
+# S1126 $1: fail to new"
+@@error_message[ :"S1126" ] = "$1: fail to new"
+
+# S1127 \'$1\' duplicate"
+@@error_message[ :"S1127" ] = "\'$1\' duplicate"
+
+# S1128 \'$1\' inconsistent array definition"
+@@error_message[ :"S1128" ] = "\'$1\' inconsistent array definition"
+
+# S1129 \'$1\' redefinition of subscript $1"
+@@error_message[ :"S1129" ] = "\'$1\' redefinition of subscript $1"
+
+# S1130 \'$1\' inconsistent array definition"
+@@error_message[ :"S1130" ] = "\'$1\' inconsistent array definition"
+
+# S1131 \'$1.$2\' has duplicate initializer"
+@@error_message[ :"S1131" ] = "\'$1.$2\' has duplicate initializer"
+
+# S1132 $1: 1st parameter is not string(file name)"
+@@error_message[ :"S1132" ] = "$1: 1st parameter is not string(file name)"
+
+# S1133 $1: 2nd parameter is not string(fromat)"
+@@error_message[ :"S1133" ] = "$1: 2nd parameter is not string(fromat)"
+
+# S1134 $1: unknown factory function"
+@@error_message[ :"S1134" ] = "$1: unknown factory function"
+
+# S1135 celltype factory can\'t have parameter(s)"
+@@error_message[ :"S1135" ] = "celltype factory can\'t have parameter(s)"
+
+# S1136 \'$1\': not found"
+@@error_message[ :"S1136" ] = "\'$1\': not found"
+
+# S1137 \'$1\': not attribute"
+@@error_message[ :"S1137" ] = "\'$1\': not attribute"
+
+# S1138 internal error Factory.check_arg()"
+@@error_message[ :"S1138" ] = "internal error Factory.check_arg()"
+
+# S1139 $1: region path mismatch. previous path: $2"
+@@error_message[ :"S1139" ] = "$1: region path mismatch. previous path: $2"
+
+# S1140 $1: region specifier must place at first appearence"
+@@error_message[ :"S1140" ] = "$1: region specifier must place at first appearence"
+
+# S1141 $1 duplication, previous one : $2"
+@@error_message[ :"S1141" ] = "$1 duplication, previous one : $2"
+
+# S1142 $1 not found in search path"
+@@error_message[ :"S1142" ] = "$1 not found in search path"
+
+# S1143 import_C: arg2: mismatch with previous one"
+@@error_message[ :"S1143" ] = "import_C: arg2: mismatch with previous one"
+
+# S1144 $1: temporary C source: open error"
+@@error_message[ :"S1144" ] = "$1: temporary C source: open error"
+
+# S1145 $1: temporary C source: writing error"
+@@error_message[ :"S1145" ] = "$1: temporary C source: writing error"
+
+# S1146 $1: error occured while CPP"
+@@error_message[ :"S1146" ] = "$1: error occured while CPP"
+
+# S1147 $1: popen for CPP failed"
+@@error_message[ :"S1147" ] = "$1: popen for CPP failed"
+
+# S1148 $1 not found in search path"
+@@error_message[ :"S1148" ] = "$1 not found in search path"
+
+# S1149 $1 not signature"
+@@error_message[ :"S1149" ] = "$1 not signature"
+
+# S1150 $1: fail to new"
+@@error_message[ :"S1150" ] = "$1: fail to new"
+
+# S1151 $1: not namespace"
+@@error_message[ :"S1151" ] = "$1: not namespace"
+
+# S1152 $1: call port cannot have fixed join"
+@@error_message[ :"S1152" ] = "$1: call port cannot have fixed join"
+
+# "S1153 $1: cannot be entry port array for fixed join port"
+@@error_message[ :"S1153" ] = "$1: cannot be entry port array for fixed join port"
+
+# "S1154 $1: must be singleton celltype for fixed join"
+@@error_message[ :"S1154" ] = "$1: must be singleton celltype for fixed join"
+
+# "S1155 $1: not celltype or not found"
+@@error_message[ :"S1155" ] = "$1: not celltype or not found"
+
+# "S1156 $1: not call port or not found"
+@@error_message[ :"S1156" ] = "$1: not call port or not found"
+
+# "S1157 $1: sized array or not array"
+@@error_message[ :"S1157" ] = "$1: sized array or not array"
+
+# "S1158 $1: singleton cell not found for fixed join"
+@@error_message[ :"S1158" ] = "$1: singleton cell not found for fixed join"
+
+# S1159 $1: non-size_is pointer cannot be initialized with array initializer"
+@@error_message[ :"S1159" ] = "$1: non-size_is pointer cannot be initialized with array initializer"
+
+# S1160 $1 must be constant for id"
+@@error_message[ :"S1160" ] = "$1 must be constant for id"
+
+# S1161 $1 must be constant for id"
+@@error_message[ :"S1161" ] = "$1 must be constant for id"
+
+# S1162 $1: id cannot be 0"
+@@error_message[ :"S1162" ] = "$1: id cannot be 0"
+
+# S1163 generate specifier duplicate"
+@@error_message[ :"S1163" ] = "generate specifier duplicate"
+
+# S1164 '$1' set_specified_id: id not positive integer '$2'"
+@@error_message[ :"S1164" ] = "'$1' set_specified_id: id not positive integer '$2'"
+
+# S1165 '$1' set_specified_id: id duplicate"
+@@error_message[ :"S1165" ] = "'$1' set_specified_id: id duplicate"
+
+# S1166 $1: fail to new"
+@@error_message[ :"S1166" ] = "$1: fail to new"
+
+# S1167 \'$1\': relay mismatch \'$2\'"
+@@error_message[ :"S1167" ] = "\'$1\': relay mismatch \'$2\'"
+
+# S1168 too many initializer for array, $1 for $2"
+@@error_message[ :"S1168" ] = "too many initializer for array, $1 for $2"
+
+# S1169 $1: non-size_is pointer cannot be initialized with array initializer"
+@@error_message[ :"S1169" ] = "$1: non-size_is pointer cannot be initialized with array initializer"
+
+# S1170 \'$1\' has size_is but export attr \'$2\' doesn't have"
+@@error_message[ :"S1170" ] = "\'$1\' has size_is but export attr \'$2\' doesn't have"
+
+# S1171 \'$1\' size_is argument of \'$2\' not exported"
+@@error_message[ :"S1171" ] = "\'$1\' size_is argument of \'$2\' not exported"
+
+# S1172 \'$1\' size_is argument mismatch with exporting one \'$2\'"
+@@error_message[ :"S1172" ] = "\'$1\' size_is argument mismatch with exporting one \'$2\'"
+
+# S1173 $1: allocator mismatch from $2's allocator"
+@@error_message[ :"S1173" ] = "$1: allocator mismatch from $2's allocator"
+
+# S1174 $1 not suitable for lhs, suitable lhs: 'func.param'"
+@@error_message[ :"S1174" ] = "$1 not suitable for lhs, suitable lhs: 'func.param'"
+
+# S1175 $1 not found or not allocator entry port for $2"
+@@error_message[ :"S1175" ] = "$1 not found or not allocator entry port for $2"
+
+# S1176 rhs not in 'call_port.func.param' form for $1_$2"
+@@error_message[ :"S1176" ] = "rhs not in 'call_port.func.param' form for $1_$2"
+
+# S1177 cannot specify 'through' in composite in current version"
+@@error_message[ :"S1177" ] = "cannot specify 'through' in composite in current version"
+
+# S1178 $1 region type specifier duplicate, previous $2"
+@@error_message[ :"S1178" ] = "$1 region type specifier duplicate, previous $2"
+
+### syntaxobj.rb
+# S2001 \'$1\' duplicate $2"
+@@error_message[ :"S2001" ] = "\'$1\' duplicate $2"
+
+# S2002 $1: $2"
+@@error_message[ :"S2002" ] = "$1: $2"
+
+# S2003 $1: $2 cannot have initializer"
+@@error_message[ :"S2003" ] = "$1: $2 cannot have initializer"
+
+# S2004 $1: array subscript must be specified or omit"
+@@error_message[ :"S2004" ] = "$1: array subscript must be specified or omit"
+
+# S2005 $1: array subscript must be specified"
+@@error_message[ :"S2005" ] = "$1: array subscript must be specified"
+
+# S2006 \'$1\' function"
+@@error_message[ :"S2006" ] = "\'$1\' function"
+
+# S2007 \'$1\' $2"
+@@error_message[ :"S2007" ] = "\'$1\' $2"
+
+# S2008 $1: inconsitent with previous one"
+@@error_message[ :"S2008" ] = "$1: inconsitent with previous one"
+
+# S2009 $1: not found or not signature"
+@@error_message[ :"S2009" ] = "$1: not found or not signature"
+
+# S2010 $1: not allocator signature"
+@@error_message[ :"S2010" ] = "$1: not allocator signature"
+
+# S2011 size_is duplicate"
+@@error_message[ :"S2011" ] = "size_is duplicate"
+
+# S2012 count_is duplicate"
+@@error_message[ :"S2012" ] = "count_is duplicate"
+
+# S2013 string duplicate"
+@@error_message[ :"S2013" ] = "string duplicate"
+
+# S2014 $1 need pointer or more pointer"
+@@error_message[ :"S2014" ] = "$1 need pointer or more pointer"
+
+# S2015 $1 must be const for \'in\' parameter $2"
+@@error_message[ :"S2015" ] = "'$1' must be const for \'in\' parameter $2"
+
+# S2016 $1 can not be const for $2 parameter"
+@@error_message[ :"S2016" ] = "'$1' can not be const for $2 parameter"
+
+# S2017 size_is argument is not integer type"
+@@error_message[ :"S2017" ] = "size_is argument is not integer type"
+
+# S2018 \'$1\' size_is parameter not integer"
+@@error_message[ :"S2018" ] = "\'$1\' size_is parameter not integer"
+
+# S2019 \'$1\' size_is parameter negative or zero"
+@@error_message[ :"S2019" ] = "\'$1\' size_is parameter negative or zero"
+
+# S2020 count_is argument is not integer type"
+@@error_message[ :"S2020" ] = "count_is argument is not integer type"
+
+# S2021 \'$1\' count_is parameter not integer"
+@@error_message[ :"S2021" ] = "\'$1\' count_is parameter not integer"
+
+# S2022 \'$1\' count_is parameter negative or zero"
+@@error_message[ :"S2022" ] = "\'$1\' count_is parameter negative or zero"
+
+# S2023 string argument is not integer type"
+@@error_message[ :"S2023" ] = "string argument is not integer type"
+
+# S2024 \'$1\' string parameter not integer"
+@@error_message[ :"S2024" ] = "\'$1\' string parameter not integer"
+
+# S2025 \'$1\' string parameter negative or zero"
+@@error_message[ :"S2025" ] = "\'$1\' string parameter negative or zero"
+
+# S2026 '$1' nullable specified for non-pointer type"
+@@error_message[ :"S2026" ] = "'$1' nullable specified for non-pointer type"
+
+# S2027 '$1' parameter cannot be void type"
+@@error_message[ :"S2027" ] = "'$1' parameter cannot be void type"
+
+# S2028 '$1' max (size_is 2nd parameter) not constant"
+@@error_message[ :"S2028" ] = "'$1' max (size_is 2nd parameter) not constant"
+
+# S2029 '$1' max (size_is 2nd parameter) negative or zero, or not integer"
+@@error_message[ :"S2029" ] = "'$1' max (size_is 2nd parameter) negative or zero, or not integer"
+
+# S2030 '$1' both size_is and max are const. size_is larger than max"
+@@error_message[ :"S2030" ] = "'$1' both size_is and max are const. size_is larger than max"
+
+### optimize.rb
+# S3001 $1: id too large $2 (max=$3)"
+@@error_message[ :"S3001" ] = "$1: id too large $2 (max=$3)"
+
+# S3002 $1: id too large $2 (max=$3)"
+@@error_message[ :"S3002" ] = "$1: id too large $2 (max=$3)"
+
+# S3003 $1: id number '$2' conflict with $3"
+@@error_message[ :"S3003" ] = "$1: id number '$2' conflict with $3"
+
+### types.rb
+# T1001 const duplicate"
+@@error_message[ :"T1001" ] = "const duplicate"
+
+# T1002 volatile duplicate"
+@@error_message[ :"T1002" ] = "volatile duplicate"
+
+# T1003 $1: unsuitable specifier for $2"
+@@error_message[ :"T1003" ] = "$1: unsuitable specifier for $2"
+
+# T1004 cannot cast to $1"
+@@error_message[ :"T1004" ] = "cannot cast to $1"
+
+# T1005 \'$1\' not defined"
+@@error_message[ :"T1005" ] = "\'$1\' not defined"
+
+# T1006 \'$1\' not type name. expecting type name here"
+@@error_message[ :"T1006" ] = "\'$1\' not type name. expecting type name here"
+
+# T1007 $1: void type variable cannot have initializer"
+@@error_message[ :"T1007" ] = "$1: void type variable cannot have initializer"
+
+# T1008 ambigous signed or unsigned"
+@@error_message[ :"T1008" ] = "ambigous signed or unsigned"
+
+# T1009 $1: $2: not integer"
+@@error_message[ :"T1009" ] = "$1: $2: not integer"
+
+# T1010 $1: initializer is not constant"
+@@error_message[ :"T1010" ] = "$1: initializer is not constant"
+
+# T1011 $1: need cast to assign float to integer"
+@@error_message[ :"T1011" ] = "$1: need cast to assign float to integer"
+
+# T1012 $1: $2: not integer"
+@@error_message[ :"T1012" ] = "$1: $2: not integer"
+
+# T1013 $1: too large (max=$2)"
+@@error_message[ :"T1013" ] = "$1: too large (max=$2)"
+
+# T1014 $1: too large negative value (min=-$2)"
+@@error_message[ :"T1014" ] = "$1: too large negative value (min=-$2)"
+
+# T1015 $1: negative value for unsigned"
+@@error_message[ :"T1015" ] = "$1: negative value for unsigned"
+
+# T1016 $1: too large (max=$2)"
+@@error_message[ :"T1016" ] = "$1: too large (max=$2)"
+
+# T1017 $1: unsuitable initializer for scalar type"
+@@error_message[ :"T1017" ] = "$1: unsuitable initializer for scalar type"
+
+# T1018 $1: $2: not number"
+@@error_message[ :"T1018" ] = "$1: $2: not number"
+
+# T1019 $1: initializer is not constant"
+@@error_message[ :"T1019" ] = "$1: initializer is not constant"
+
+# T1020 $1: unsuitable initializer for scalar type"
+@@error_message[ :"T1020" ] = "$1: unsuitable initializer for scalar type"
+
+# T1021 \'$1\': struct not defined"
+@@error_message[ :"T1021" ] = "\'$1\': struct not defined"
+
+# T1022 struct $1: not defined"
+@@error_message[ :"T1022" ] = "struct $1: not defined"
+
+# T1023 struct $1: not defined"
+@@error_message[ :"T1023" ] = "struct $1: not defined"
+
+# T1024 $1: unsuitable initializer for struct"
+@@error_message[ :"T1024" ] = "$1: unsuitable initializer for struct"
+
+# T1025 size_is argument is not integer type"
+@@error_message[ :"T1025" ] = "size_is argument is not integer type"
+
+# T1026 count_is argument is not integer type"
+@@error_message[ :"T1026" ] = "count_is argument is not integer type"
+
+# T1027 string argument is not integer type"
+@@error_message[ :"T1027" ] = "string argument is not integer type"
+
+# T1028 $1: cannot initialize function pointer"
+@@error_message[ :"T1028" ] = "$1: cannot initialize function pointer"
+
+# T1029 oneway function cannot return type \'$1$2\', \'void\' or \'ER\' is permitted"
+@@error_message[ :"T1029" ] = "oneway function cannot return type \'$1$2\', \'void\' or \'ER\' is permitted"
+
+# T1030 oneway function cannot have $1 parameter for \'$2\'"
+@@error_message[ :"T1030" ] = "oneway function cannot have $1 parameter for \'$2\'"
+
+# T1031 $1: unsuitable initializer for array"
+@@error_message[ :"T1031" ] = "$1: unsuitable initializer for array"
+
+# T1032 $1: incompatible pointer type"
+@@error_message[ :"T1032" ] = "$1: incompatible pointer type"
+
+# T1033 $1: need cast to assign integer to pointer"
+@@error_message[ :"T1033" ] = "$1: need cast to assign integer to pointer"
+
+# T1034 $1: unsuitable string constant"
+@@error_message[ :"T1034" ] = "$1: unsuitable string constant"
+
+# T1035 $1: unsuitable initializer for pointer"
+@@error_message[ :"T1035" ] = "$1: unsuitable initializer for pointer"
+
+# T1036 $1: unsuitable initializer for pointer"
+@@error_message[ :"T1036" ] = "$1: unsuitable initializer for pointer"
+
+# T1037 $1: not number"
+@@error_message[ :"T1037" ] = "$1: not number"
+
+# T1038 $1: initializer type mismatch. '$2' & '$3'"
+@@error_message[ :"T1038" ] = "$1: initializer type mismatch. '$2' & '$3'"
+
+# T1039 $1: struct tag mismatch $2 and $3"
+@@error_message[ :"T1039" ] = "$1: struct tag mismatch $2 and $3"
+
+# T1040 $1 specified for void pointer type"
+@@error_message[ :"T1040" ] = "$1 specified for void pointer type"
+
+### gen_xml.rb
+# T2001 fail to create XML file $1"
+@@error_message[ :"T2001" ] = "fail to create XML file $1"
+
+# TEMPORAL set_definition_join: uninitialized array member"
+@@error_message[ :"TEMPORAL" ] = "set_definition_join: uninitialized array member"
+
+# V1001 $1: unable for $2"
+@@error_message[ :"V1001" ] = "$1: unable for $2"
+
+# V1002 $1: cannot cast to bool (implicitly)"
+@@error_message[ :"V1002" ] = "$1: cannot cast to bool (implicitly)"
+
+# V1003 $1: cannot cast to integer (implicitly)"
+@@error_message[ :"V1003" ] = "$1: cannot cast to integer (implicitly)"
+
+# V1004 $1: cannot cast to float (implicitly)"
+@@error_message[ :"V1004" ] = "$1: cannot cast to float (implicitly)"
+
+# V1005 Cannot cast pointer to float"
+@@error_message[ :"V1005" ] = "Cannot cast pointer to float"
+
+# V1006 pointer value cannot cast to $1"
+@@error_message[ :"V1006" ] = "pointer value cannot cast to $1"
+
+# V1007 convert pointer value to bool"
+@@error_message[ :"V1007" ] = "convert pointer value to bool"
+
+# V1008 convert pointer value to integer without cast"
+@@error_message[ :"V1008" ] = "convert pointer value to integer without cast"
+
+# V1009 / : divieded by zero"
+@@error_message[ :"V1009" ] = "/ : divieded by zero"
+
+# V1010 / : divieded by zero"
+@@error_message[ :"V1010" ] = "/ : divieded by zero"
+
+# V1011 % : divieded by zero"
+@@error_message[ :"V1011" ] = "% : divieded by zero"
+
+# V1012 % : divieded by zero"
+@@error_message[ :"V1012" ] = "% : divieded by zero"
+
+# V1013 integer value cannot cast to $1"
+@@error_message[ :"V1013" ] = "integer value cannot cast to $1"
+
+# V1014 comparing bool value with \'$1\'"
+@@error_message[ :"V1014" ] = "comparing bool value with \'$1\'"
+
+# V1015 comparing bool value with \'$1\'"
+@@error_message[ :"V1015" ] = "comparing bool value with \'$1\'"
+
+# V1016 bool value cannot cast to $1"
+@@error_message[ :"V1016" ] = "bool value cannot cast to $1"
+
+# V1017 / : divieded by zero"
+@@error_message[ :"V1017" ] = "/ : divieded by zero"
+
+# V1018 % : divieded by zero"
+@@error_message[ :"V1018" ] = "% : divieded by zero"
+
+# V1019 floating value cannot cast to $1"
+@@error_message[ :"V1019" ] = "floating value cannot cast to $1"
+
+# V1020 convert floating value to bool without cast"
+@@error_message[ :"V1020" ] = "convert floating value to bool without cast"
+
+# V1021 convert floating value to integer without cast"
+@@error_message[ :"V1021" ] = "convert floating value to integer without cast"
+
+# V1022 string cannot cast to integer"
+@@error_message[ :"V1022" ] = "string cannot cast to integer"
+
+# V1023 string cannot cast to float"
+@@error_message[ :"V1023" ] = "string cannot cast to float"
+
+# V1024 string cannot cast to pointer"
+@@error_message[ :"V1024" ] = "string cannot cast to pointer"
+
+# V1025 string cannot cast to $1"
+@@error_message[ :"V1025" ] = "string cannot cast to $1"
+
+###
+# warning メッセージ
+@@warning_message = {}
+
+### componentobj.rb
+# W1001 \'$1\': unknown context type. usually specifiy task, non-task or any"
+@@warning_message[ :"W1001" ] = "\'$1\': unknown context type. usually specifiy task, non-task or any"
+
+# W1002 $1: non-active celltype has no entry port & factory"
+@@warning_message[ :"W1002" ] = "$1: non-active celltype has no entry port & factory"
+
+# W1003 $1 : require call port overridden in $2"
+@@warning_message[ :"W1003" ] = "$1 : require call port overridden in $2"
+
+# W1004 $1 : specified singleton but has no singleton in this celltype"
+@@warning_message[ :"W1004" ] = "$1 : specified singleton but has no singleton in this celltype"
+
+# W1005 $1 : idx_is_id is ineffective for composite celltype"
+@@warning_message[ :"W1005" ] = "$1 : idx_is_id is ineffective for composite celltype"
+
+# W1006 $1 : only prototype, unused and undefined cell"
+@@warning_message[ :"W1006" ] = "$1 : only prototype, unused and undefined cell"
+
+# W1007 $1 : non-active cell has no entry join and no factory"
+@@warning_message[ :"W1007" ] = "$1 : non-active cell has no entry join and no factory"
+
+# W1008 $1: reuse designation mismatch with previous import"
+@@warning_message[ :"W1008" ] = "$1: reuse designation mismatch with previous import"
+
+# "W1009 $1: fixed join entry port has multi join"
+@@warning_message[ :"W1009" ] = "$1: fixed join entry port has multi join"
+
+### types.rb
+# W2001 signed int$1_t: obsolete. use int$2_t"
+@@warning_message[ :"W2001" ] = "signed int$1_t: obsolete. use int$2_t"
+
+# W2002 unsinged int$1_t: obsolete. use uint$2_t"
+@@warning_message[ :"W2002" ] = "unsinged int$1_t: obsolete. use uint$2_t"
+
+# W2003 $1: too large to cast to $2, clipped($3)"
+@@warning_message[ :"W2003" ] = "$1: too large to cast to $2, clipped($3)"
+
+# W2004 $1: too small to cast to $2, clipped($3)"
+@@warning_message[ :"W2004" ] = "$1: too small to cast to $2, clipped($3)"
+
+# W2005 $1: negative value for unsigned: convert to $2"
+@@warning_message[ :"W2005" ] = "$1: negative value for unsigned: convert to $2"
+
+### syntaxobj.rb
+# W3001 $1: duplicate"
+@@warning_message[ :"W3001" ] = "$1: duplicate"
+
+# W3002 $1: this string might cause buffer over run"
+@@warning_message[ :"W3002" ] = "$1: this string might cause buffer over run"
+
+# W3003 $1 pointer level mismatch"
+@@warning_message[ :"W3003" ] = "$1 pointer level mismatch"
+
+# W3004 $1 pointer type has returned. specify deviate or stop return pointer"
+@@error_message[ :"W3004" ] = "$1 pointer type has returned. specify deviate or stop return pointer"
+
+# W3005 '$1' size_is always lower than max. max is ignored"
+@@error_message[ :"W3005" ] = "'$1' size_is always lower than max. max is ignored"
+
+### bnf.y.rb
+# W5001 bool: obsolete type. use bool_t"
+@@warning_message[ :"W5001" ] = "bool: obsolete type. use bool_t"
+
+# W5002 float: obsolete type. use float32_t"
+@@warning_message[ :"W5002" ] = "float: obsolete type. use float32_t"
+
+# W5003 double: obsolete type. use double64_t"
+@@warning_message[ :"W5003" ] = "double: obsolete type. use double64_t"
+
+# W5004 char: obsolete type. use char_t"
+@@warning_message[ :"W5004" ] = "char: obsolete type. use char_t"
+
+# W5005 int8: obsolete. use int8_t"
+@@warning_message[ :"W5005" ] = "int8: obsolete. use int8_t"
+
+# W5006 int16: obsolete. use int16_t"
+@@warning_message[ :"W5006" ] = "int16: obsolete. use int16_t"
+
+# W5007 int32: obsolete. use int32_t"
+@@warning_message[ :"W5007" ] = "int32: obsolete. use int32_t"
+
+# W5008 int64: obsolete. use int64_t"
+@@warning_message[ :"W5008" ] = "int64: obsolete. use int64_t"
+
+# W5009 int64: obsolete. use int64_t"
+@@warning_message[ :"W5009" ] = "int64: obsolete. use int64_t"
+
+# W5010 need 'void' for no parameter"
+@@warning_message[ :"W5010" ] = "need 'void' for no parameter"
+
+# W5011 need 'void' for no parameter"
+@@warning_message[ :"W5011" ] = "need 'void' for no parameter"
+
+### C_parser.y.rb
+# W6001 need 'void' for no parameter"
+@@warning_message[ :"W6001" ] = "need 'void' for no parameter"
+
+# W6002 need 'void' for no parameter"
+@@warning_message[ :"W6002" ] = "need 'void' for no parameter"
+
+# W6003 need 'void' for no parameter"
+@@warning_message[ :"W6003" ] = "need 'void' for no parameter"
+
+# W6004 need 'void' for no parameter"
+@@warning_message[ :"W6004" ] = "need 'void' for no parameter"
+
+###
+# info メッセージ
+@@info_message = {}
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_console_ja_JP.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_console_ja_JP.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_console_ja_JP.rb	(revision 398)
@@ -0,0 +1,1174 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+
+# Console Messages for ja_JP
+class TECSMsg
+
+###
+# エラーメッセージ
+@@error_message = {}
+
+### C_parser.y.rb
+# B1001 need parameter name"
+@@error_message[ :"B1001" ] = "パラメータ名が必要です" 
+
+# B1002 while open or reading \'$1\'"
+@@error_message[ :"B1002" ] = "\'$1\' のオープンまたは読み込みに失敗しました" 
+
+# B1003 Unexpected EOF"
+@@error_message[ :"B1003" ] = "予期しない EOF です"
+
+# B1004 syntax error near \'$1\'"
+@@error_message[ :"B1004" ] = "\'$1\' 付近の構文エラーです"
+
+### ctypes.rb
+# C1001 $1: mismatch, suitable for integer types"
+@@error_message[ :"C1001" ] = "$1: 整合していません, それは整数型に適しています"
+
+# C1002 $1 not compatible with previous one $2"
+@@error_message[ :"C1002" ] = "$1 はそれ以前のものである $2 と両立しません"
+
+# C1003 $1 & $2 incompatible  (\'long double\' not support)"
+@@error_message[ :"C1003" ] = "$1 及び $2 は両立しません (\'long double\' は未サポート)"
+
+# C1004 $1: qualifier respecified. previous one: $2"
+@@error_message[ :"C1004" ] = "$1: 修飾子が再度指定されました. その前の修飾子: $2"
+
+### expression.rb
+# E1001 $1: not found"
+@@error_message[ :"E1001" ] = "$1: 見つかりません"
+
+# E1002 $1: not constant (port)"
+@@error_message[ :"E1002" ] = "$1: 定数ではありません (port)"
+
+# E1003 $1: not constant"
+@@error_message[ :"E1003" ] = "$1: 定数ではありません"
+
+# E1004 cannot evaluate \'[]\' operator"
+@@error_message[ :"E1004" ] = "\'[]\' 演算子を評価できません"
+
+# E1005 cannot evaluate \'.\' operator"
+@@error_message[ :"E1005" ] = "\'.\' 演算子を評価できません"
+
+# E1006 cannot evaluate \'->\' operator"
+@@error_message[ :"E1006" ] = "\'->\' 演算子を評価できません"
+
+# E1007 cannot evaluate \'sizeof\' operator"
+@@error_message[ :"E1007" ] = "\'sizeof\' 演算子を評価できません"
+
+# E1008 cannot evaluate \'sizeof\' operator"
+@@error_message[ :"E1008" ] = "\'sizeof\' 演算子を評価できません"
+
+# E1009 cannot evaluate \'&\' operator"
+@@error_message[ :"E1009" ] = "\'&\' 演算子を評価できません"
+
+# E1010 cannot evaluate \'*\' operator"
+@@error_message[ :"E1010" ] = "\'*\' 演算子を評価できません"
+
+# E1011 cannot evaluate unary + for $1"
+@@error_message[ :"E1011" ] = "$1 に対する単項の + を評価できません"
+
+# E1012 $1: not found in parameter list"
+@@error_message[ :"E1012" ] = "$1: パラメータリストの中に見つかりません"
+
+# E1013 \'*\': operand is not pointer value"
+@@error_message[ :"E1013" ] = "\'*\': オペランドはポインタ値ではありません"
+
+# E1014 $1: elements_get_type: sorry not supported"
+@@error_message[ :"E1014" ] = "$1: elements_get_type: 申し訳ありません．サポートされていません"
+
+# E1015 \'$1\': direction mismatch for $2, $3 required"
+@@error_message[ :"E1015" ] = "\'$1\': $2 に対する方向が整合していません．$3 が必要です"
+
+# E1016 $1: elements_check_dir_for_param: sorry not supported"
+@@error_message[ :"E1016" ] = "$1: elements_check_dir_for_param: 申し訳ありません．サポートされていません"
+
+# E1017 $1: rhs not \'Cell.ePort\' form"
+@@error_message[ :"E1017" ] = "$1: 右辺が \'Cell.ePort\' 形式ではありません"
+
+# E1018 $1: namespace cannot be specified"
+@@error_message[ :"E1018" ] = "$1: namespace を指定できません"
+
+# E1019 $1: rhs not in 'allocator_entry_port' form"
+@@error_message[ :"E1019" ] = "$1: 右辺が 'allocator_entry_port' 形式ではありません"
+
+# E1020 rhs not in 'call_port.func.param' form for $1_$2"
+@@error_message[ :"E1020" ] = "右辺が 'call_port.func.param' 形式でありません ($1_$2)"
+
+### bnf.y.rb
+# G1001 need specifier for \'$1\'"
+@@error_message[ :"G1001" ] = "\'$1\' に対する指定子が必要です"
+
+# G1002 need parameter name"
+@@error_message[ :"G1002" ] = "パラメータ名が必要です"
+
+# G1003 need parameter name"
+@@error_message[ :"G1003" ] = "パラメータ名が必要です"
+
+# G1004 impossible array type 0"
+@@error_message[ :"G1004" ] = "あり得ない配列型 0 です"
+
+# G1005 impossible array type 1"
+@@error_message[ :"G1005" ] = "あり得ない配列型 1 です"
+
+# G1006 impossible array type 2"
+@@error_message[ :"G1006" ] = "あり得ない配列型 2 です"
+
+# G1007 impossible array type 3"
+@@error_message[ :"G1007" ] = "あり得ない配列型 3 です"
+
+# G1008 impossible function type"
+@@error_message[ :"G1008" ] = "あり得ない関数型です"
+
+# G1009 unexpected specifier"
+@@error_message[ :"G1009" ] = "予期しない指定子です"
+
+# G1010 Not function"
+@@error_message[ :"G1010" ] = "関数ではありません"
+
+# G1011 Not function"
+@@error_message[ :"G1011" ] = "関数ではありません"
+
+# G1012 $1 : cannot put specifier here"
+@@error_message[ :"G1012" ] = "$1 : ここに指定子を置くことはできません"
+
+# G1013 unexpected specifier"
+@@error_message[ :"G1013" ] = "予期しない指定子です"
+
+# G1014 while open or reading \'$1\'"
+@@error_message[ :"G1014" ] = "\'$1\' のオープンまたは読み込みに失敗しました"
+
+# G1015 Unexpected EOF"
+@@error_message[ :"G1015" ] = "予期しない EOF です"
+
+# G1016 syntax error near \'$1\'"
+@@error_message[ :"G1016" ] = "\'$1\' 付近の構文エラーです"
+
+### plugin.rb
+# P1001 plugin arg: cannot find identifier in $1"
+@@error_message[ :"P1001" ] = "plugin arg: $1 の中に識別子を見つけることができません"
+
+# P1002 plugin arg: expecting \'=\' not \'$1\'"
+@@error_message[ :"P1002" ] = "plugin arg: \'$1\' ではなく \'=\' が必要です"
+
+# P1003 plugin arg: unexpected $1"
+@@error_message[ :"P1003" ] = "plugin arg: 予期しない $1 です"
+
+# P1004 $1: unknown plugin argument\'s identifier\n  $2 are acceptable for RPCPlugin."
+@@error_message[ :"P1004" ] = "$1: 不明なプラグイン引数の識別子\n  $2 が RPC プラグインに対して受け入れ可能です"
+
+### pluginModule.rb
+# P2001 $1.rb : fail to load plugin"
+@@error_message[ :"P2001" ] = "$1.rb : プラグインの読み込みに失敗しました"
+
+# P2002 $1: not kind of $2"
+@@error_message[ :"P2002" ] = "$1: $2 の一種ではありません"
+
+# P2003 $1: load failed"
+@@error_message[ :"P2003" ] = "$1: 読み込みに失敗しました"
+
+# P2004 $1: open error \'$2\'"
+@@error_message[ :"P2004" ] = "$1: オープンエラー \'$2\' が発生しました"
+
+# P2005 $1: plugin error in gen_through_cell_code "
+@@error_message[ :"P2005" ] = "$1: gen_through_cell_code 内のプラグインエラーが発生しました"
+
+# P2006 $1: close error \'$2\'"
+@@error_message[ :"P2006" ] = "$1: \'$2\' のクローズエラーが発生しました"
+
+# P2007 $1: fail to generate post code"
+@@error_message[ :"P2007" ] = "$1: ポストコードの生成に失敗しました"
+
+### componentobj.rb
+# S1001 context specifier duplicate"
+@@error_message[ :"S1001" ] = "コンテキスト指定子が重複しています"
+
+# S1002 \'$1\': unknown specifier for signature"
+@@error_message[ :"S1002" ] = "\'$1\': シグニチャに対する不明な指定子です"
+
+# S1003 $1: \'alloc\' 1st parameter neither [in] integer type nor [out] double pointer type
+@@error_message[ :"S1003" ] = "$1: \'alloc\' 関数の第1パラメータが in の整数型でも out の二重ポインタ型でもありません．"
+
+# S1004 $1: \'alloc\' 2nd parameter not [in] double pointer"
+@@error_message[ :"S1004" ] = "$1: \'alloc\' 関数の第2パラメータが in のポインタへのポインタではありません．"
+
+# S1005 $1: \'alloc\' has no parameter, unsuitable for allocator signature"
+@@error_message[ :"S1005" ] = "$1: \'alloc\' 関数がパラメータを持っていません．アロケータシグニチャに対して不適当です．"
+
+# S1006 $1: \'dealloc\' 1st parameter not [in] pointer type"
+@@error_message[ :"S1006" ] = "$1: \'dealloc\' 関数の第1パラメータが in のポインタ型ではありません．"
+
+# S1007 "
+     # S1007 $1: \'dealloc\' cannot has 2nd parameter"
+# @@error_message[ :"S1007" ] = "$1: \'dealloc\' 関数は第2パラメータを持つことができません．"
+
+# S1008 $1: \'dealloc\' has no parameter, unsuitable for allocator signature"
+@@error_message[ :"S1008" ] = "$1: \'dealloc\' 関数がパラメータを持っていません．アロケータシグニチャに対して不適当です．"
+
+# S1009 $1: \'alloc\' function not found, unsuitable for allocator signature"
+@@error_message[ :"S1009" ] = "$1: \'alloc\' 関数が見つかりません．アロケータシグニチャに対して不適当です．"
+
+# S1010 $1: \'dealloc\' function not found, unsuitable for allocator signature"
+@@error_message[ :"S1010" ] = "$1: \'dealloc\' 関数が見つかりません．アロケータシグニチャに対して不適当です．"
+
+# S1011 $1: size_is specified for non-pointer type"
+@@error_message[ :"S1011" ] = "$1: 非ポインタ型に対して size_is が指定されました"
+
+# S1012 $1: unsuitable initializer, need array initializer"
+@@error_message[ :"S1012" ] = "$1: 不適当な初期化子です．配列の初期化子が必要です．"
+
+# S1013 $1: too many initializer, $2 for $3"
+@@error_message[ :"S1013" ] = "$1: 初期化子が多すぎます．$3 とするところを $2 としました．"
+
+# S1014 generate specifier duplicate"
+@@error_message[ :"S1014" ] = "generate 指定子が重複しました．"
+
+# S1015 $1 cannot be specified for composite"
+@@error_message[ :"S1015" ] = "$1 は複合セルに対して指定できません．"
+
+# S1016 $1 not found"
+@@error_message[ :"S1016" ] = "$1 が見つかりません"
+
+# S1017 $1 : neither celltype nor cell"
+@@error_message[ :"S1017" ] = "$1 : セルタイプでもセルでもありません"
+
+# S1018 $1 : not singleton cell"
+@@error_message[ :"S1018" ] = "$1 : シングルトンセルではありません"
+
+# S1019 \'$1\' : not entry port"
+@@error_message[ :"S1019" ] = "\'$1\' : 受け口ではありません"
+
+# S1020 \'$1\' : required port cannot be array"
+@@error_message[ :"S1020" ] = "\'$1\' : 要求された口(port)は配列に出来ません．"
+
+# S1021 $1 : require cannot have same signature with \'$2\'"
+@@error_message[ :"S1021" ] = "$1 : リクワイアは \'$2\' と同じシグニチャを持つことが出来ません．"
+
+# S1022 $1.$2 : \'$3\' conflict function name in $4.$5"
+@@error_message[ :"S1022" ] = "$1.$2 : \'$3\' は $4.$5 における関数名と衝突しています．"
+
+# S1023 $1: fail to new"
+@@error_message[ :"S1023" ] = "$1: new に失敗しました．"
+
+# S1024 $1: multiple cell for singleton celltype"
+@@error_message[ :"S1024" ] = "$1: シングルトンセルタイプに対し複数のセルが存在します．"
+
+# S1025 not found reachable cell for require \'$1\' in celltype \'$2\'"
+@@error_message[ :"S1025" ] = "セルタイプ \'$2\' 内のリクワイア \'$1\' へ到達可能なセルが見つかりません．"
+
+# S1026 required cell \'$1\' not reachable"
+@@error_message[ :"S1026" ] = "必要とされるセル \'$1\' は到達可能ではありません．"
+
+# S1027 \'$1\' celltype not found"
+@@error_message[ :"S1027" ] = "セルタイプ \'$1\' が見つかりません"
+
+# S1028 \'$1\' not celltype"
+@@error_message[ :"S1028" ] = "\'$1\' はセルタイプではありません"
+
+# S1029 $1 mismatch with previous one"
+@@error_message[ :"S1029" ] = "$1 がそれ以前のものと整合していません"
+
+# S1030 $1: celltype mismatch with previous one"
+@@error_message[ :"S1030" ] = "$1: セルタイプがそれ以前のものと整合していません"
+
+# S1031 $1 region \'$2\' mismatch  with previous one \'$3\'"
+@@error_message[ :"S1031" ] = "セル $1 のリージョン \'$2\' はそれ以前のリージョン \'$3\' と整合していません．"
+
+# S1032 $1: duplicate cell"
+@@error_message[ :"S1032" ] = "$1: セルが重複しています"
+
+# S1033 rhs expression is not supported. Only attribute is permitted on current version."
+@@error_message[ :"S1033" ] = "右辺式はサポートされていません．属性のみが現在のバージョンで使用できます．"
+
+# S1034 $1 : cannot refer to $2\'s attribute here. Use \'composite.$3\' to refer to composite celltype\'s"
+@@error_message[ :"S1034" ] = "$1 : ここでは $2 の属性を参照できません. 複合セルタイプの属性を参照するため \'composite.$3\' をお使いください．"
+
+# S1035 composite : cannot specify out of composite celltype definition"
+@@error_message[ :"S1035" ] = "composite : 複合セルタイプ定義の外側では指定できません．"
+
+# S1036 $1 : cannot refer to $2\'s here. Use \'composite.$3\' to refer to composite celltype\'s"
+@@error_message[ :"S1036" ] = "$1 : ここでは$2のものを参照できません．複合セルタイプのものを参照するため \'composite.$3\' をお使いください．"
+
+# S1037 $1: celltype plugin fail to new_cell"
+@@error_message[ :"S1037" ] = "$1: セルタイププラグインが new_cell に失敗しました．"
+
+# S1038 $1.$2: self allocator not supported for array entry port"
+@@error_message[ :"S1038" ] = "$1.$2: セルフアロケータは受け口配列に対してサポートされていません．"
+
+# S1039 \'$1\': unknown specifier for cell"
+@@error_message[ :"S1039" ] = "\'$1\': セルに対する不明な指定子です．"
+
+# S1040 array not supported for relay allocator"
+@@error_message[ :"S1040" ] = "配列はリレーアロケータに対してサポートされていません．"
+
+# S1041 \'$1_$2_$3\': not joined. cannot create internal join for relay allocator"
+@@error_message[ :"S1041" ] = "\'$1_$2_$3\': 結合されません. リレーアロケータに対して内部結合を生成できません．"
+
+# S1042 call port \'$1\' not initialized in cell \'$2\'"
+@@error_message[ :"S1042" ] = "呼び口 \'$1\' はセル \'$2\' の中で初期化されません．"
+
+# S1043 call port \'$1\' not initialized in cell \'$2\'. this call port is created by tecsgen. check allocator specifier"
+@@error_message[ :"S1043" ] = "呼び口 \'$1\' はセル \'$2\' の中で初期化されません．この呼び口は tecsgen により生成されます．アロケータ指定子を確認してください．"
+
+# S1044 $1: array initializer too many or few, $2 for $3"
+@@error_message[ :"S1044" ] = "$1: 配列の初期化子が多すぎるかまたは少なすぎます．$3 とするところを $2 にしました．"
+
+# S1045 $1[$2]: not initialized"
+@@error_message[ :"S1045" ] = "$1[$2]: 初期化されません．"
+
+# S1046 $1[$2]: not initialized"
+@@error_message[ :"S1046" ] = "$1[$2]: 初期化されません"
+
+# S1047 size_is pointer cannot be exposed for composite attribute"
+@@error_message[ :"S1047" ] = "size_is を指定されたポインタ変数は，複合セルタイプの属性名に関しては，外部へ公開することができません．"
+
+# S1048 $1: size_is specified for non-pointer type"
+@@error_message[ :"S1048" ] = "$1: size_is が非ポインタ型に対して指定されました．"
+
+# S1049 $1: size_is arg not constant"
+@@error_message[ :"S1049" ] = "$1: size_is 引数が定数ではありません．"
+
+# S1050 unsuitable initializer, need array initializer"
+@@error_message[ :"S1050" ] = "不適当な初期化子です．配列の初期化子が必要です．"
+
+# S1051 too many initializer for array, $1 for $2"
+@@error_message[ :"S1051" ] = "配列に対する初期化子が多すぎます．$2 とするところを $1 にしました．"
+
+# S1052 attribute \'$1\' not initialized in cell \'$2\'"
+@@error_message[ :"S1052" ] = "属性 \'$1\' はセル \'$2\' の中で初期化されません．"
+
+# S1053 $1 must be singleton. inner cell \'$2\' is singleton"
+@@error_message[ :"S1053" ] = "$1 はシングルトンである必要があります．内部セル \'$2\' はシングルトンです．"
+
+# S1054 $1 : specified active but has no active in this celltype"
+@@error_message[ :"S1054" ] = "$1 : アクティブに指定されましたが，このセルタイプの中にはアクティブなセルがありません．"
+
+# S1055 $1 must be active. inner cell \'$2\' is active"
+@@error_message[ :"S1055" ] = "$1 は active である必要があります. 内部セル \'$2\' がアクティブです．"
+
+# S1056 $1 : cannot export, nothing designated"
+@@error_message[ :"S1056" ] = "$1 : 外部に公開することができません．何も指定されていません．"
+
+# S1057 $1 not found in $2"
+@@error_message[ :"S1057" ] = "$1 が $2 の中に見つかりません．"
+
+# S1058 \'$1\' : cannot export var"
+@@error_message[ :"S1058" ] = "\'$1\' : 変数を外部に公開することができません．"
+
+# S1059 \'$1\' : exporting attribute. write in cell or use \'=\' to export attribute"
+@@error_message[ :"S1059" ] = "\'$1\' : 属性を公開しています. セルの中に記述するかまたは属性の公開のために \'=\' を使って下さい．"
+
+# S1060 \'$1\' : port type mismatch. $2 type is allowed here."
+@@error_message[ :"S1060" ] = "\'$1\' : 口(port)の型が整合していません. ここでは $2 型が使用できます．"
+
+# S1061 \'$1\' : not defined"
+@@error_message[ :"S1061" ] = "\'$1\' : 定義されていません．"
+
+# S1062 $1 has no export definition"
+@@error_message[ :"S1062" ] = "$1 には外部定義がありません．"
+
+# S1063 $1 is port but previously defined as an attribute"
+@@error_message[ :"S1063" ] = "$1 は口(port)ですがそれより前に属性として定義されました．"
+
+# S1064 $1 : type \'$2$3\' mismatch with pprevious definition\'$4$5\'"
+@@error_message[ :"S1064" ] = "$1 : 型 \'$2$3\' はそれ以前の定義 \'$4$5\' と整合してません．"
+
+# S1065 $1 : port type $2 mismatch with previous definition $3"
+@@error_message[ :"S1065" ] = "$1 : 口(port)型 $2 はそれ以前の定義 $3 と整合していません．"
+
+# S1066 $1 : signature \'$2\' mismatch with previous definition \'$3\'"
+@@error_message[ :"S1066" ] = "$1 : シグニチャ \'$2\' はそれ以前の定義 \'$3\' と整合していません．"
+
+# S1067 $1 : array size mismatch with previous definition"
+@@error_message[ :"S1067" ] = "$1 : 配列のサイズがそれ以前の定義と整合していません．"
+
+# S1068 $1 : optional specifier mismatch with previous definition"
+@@error_message[ :"S1068" ] = "$1 : オプショナルな指定子がそれ以前の定義と整合していません．"
+
+# S1069 $1 is an attribute but previously defined as a port"
+@@error_message[ :"S1069" ] = "$1 は属性ですがそれより前に口(port)として定義されました．"
+
+# S1070 $1: size_is pointer cannot be exposed for composite attribute"
+@@error_message[ :"S1070" ] = "$1: size_is を指定されたポインタ変数は，複合セルタイプの属性名に関しては，公開することができません．"
+
+# S1071 $1 cannot be specified for composite"
+@@error_message[ :"S1071" ] = "$1 は複合セルに対して指定できません．"
+
+# S1072 $1: entry port: sizeless array not supported in current version"
+@@error_message[ :"S1072" ] = "$1: 受け口: 現在の版ではサイズ未指定の配列はサポートされていません．"
+
+# S1073 Not constant expression $1"
+@@error_message[ :"S1073" ] = "$1 は定数式ではありません．"
+
+# S1074 Not Integer $1"
+@@error_message[ :"S1074" ] = "$1 は整数ではありません"
+
+# S1075 \'$1\' signature not found"
+@@error_message[ :"S1075" ] = "\'$1\' シグニチャが見つかりません．"
+
+# S1076 \'$1\' not signature"
+@@error_message[ :"S1076" ] = "\'$1\' はシグニチャではありません．"
+
+# S1077 inline: cannot be specified for call port"
+@@error_message[ :"S1077" ] = "inline: 呼び口に対して指定できません．"
+
+# S1078 optional: cannot be specified for entry port"
+@@error_message[ :"S1078" ] = "optional: 受け口に対して指定できません．"
+
+# S1079 allocator: cannot be specified for call port"
+@@error_message[ :"S1079" ] = "allocator: 呼び口に対して指定できません．"
+
+# S1080 duplicate allocator specifier"
+@@error_message[ :"S1080" ] = "アロケータ指定子が重複しています．"
+
+# S1081 self allocator not supported yet"
+@@error_message[ :"S1081" ] = "セルフアロケータはまだサポートされていません"
+
+# S1082 function \'$1\' not found in signature"
+@@error_message[ :"S1082" ] = "関数 \'$1\' がシグニチャで見つかりません"
+
+# S1083 \'$1\' not found in function \'$2\'"
+@@error_message[ :"S1083" ] = "\'$1\' が関数 \'$2\' で見つかりません"
+
+# S1084 \'$1\' in function \'$2\' is not send or receive"
+@@error_message[ :"S1084" ] = "\'$2\' 内の \'$1\' が基本指定子 send または receive ではありません．"
+
+# S1085 duplicate allocator specifier for \'$1_$2\'"
+@@error_message[ :"S1085" ] = "\'$1_$2\' に対する重複したアロケータ指定子です．"
+
+# S1086 rhs not call_port.func.param for $1_$2"
+@@error_message[ :"S1086" ] = "$1_$2 に対して not call_port.func.param の形式ではありません．"
+
+# S1087 function \'$1\' not found in signature \'$2\'"
+@@error_message[ :"S1087" ] = "関数 \'$1\' がシグニチャ \'$2\' の中に見つかりません．"
+
+# S1088 \'$1\' not found in function \'$2\'"
+@@error_message[ :"S1088" ] = "\'$1\' が関数 \'$2\' の中に見つかりません．"
+
+# S1089 relay allocator send/receive mismatch between $1.$2 and $3_$4.$5"
+@@error_message[ :"S1089" ] = "リレーアロケータ send/receive は $1.$2 及び $3_$4.$5 の間で整合していません．"
+
+# S1090 \'$1\' in function \'$2\' is not send or receive"
+@@error_message[ :"S1090" ] = "関数 \'$2\' 内の \'$1\' が send または receive ではありません．"
+
+# S1091 call port \'$1\' not found in celltype $2"
+@@error_message[ :"S1091" ] = "呼び口 \'$1\' がセルタイプ $2 の中に見つかりません．"
+
+# S1092 \'$1\' not namespace"
+@@error_message[ :"S1092" ] = "\'$1\' はネームスペースではありません．"
+
+# S1093 $1 : undefined cell"
+@@error_message[ :"S1093" ] = "$1 : 未定義のセルです"
+
+# S1094 $1: pointer is not constant. check \'const\'"
+@@error_message[ :"S1094" ] = "$1: ポインタが定数ではありません．\'const\' を確認してください"
+
+# S1095 $1: not constant"
+@@error_message[ :"S1095" ] = "$1: 定数ではありません"
+
+# S1096 $1: should be int, float, bool or pointer type"
+@@error_message[ :"S1096" ] = "$1: int, float, bool またはポインタ型である必要があります"
+
+# S1097 $1: has no initializer"
+@@error_message[ :"S1097" ] = "$1: 初期化子を持っていません"
+
+# S1098 $1: has unsuitable initializer"
+@@error_message[ :"S1098" ] = "$1: 不適当な初期化子があります．"
+
+# S1099 array subscript not constant"
+@@error_message[ :"S1099" ] = "配列添数が定数ではありません．"
+
+# S1100 $1: cannot initialize var"
+@@error_message[ :"S1100" ] = "$1: 変数を初期化できません．"
+
+# S1101 \'$1\' cannot initialize entry port"
+@@error_message[ :"S1101" ] = "\'$1\' 受け口を初期化できません．"
+
+# S1102 $1: must specify array subscript here"
+@@error_message[ :"S1102" ] = "$1: ここでは配列添数を指定する必要があります．"
+
+# S1103 $1: need array subscript"
+@@error_message[ :"S1103" ] = "$1: 配列添数が必要です．"
+
+# S1104 $1: need array subscript number. ex. \'[0]\'"
+@@error_message[ :"S1104" ] = "$1: 配列添数の数値が必要です．(例) \'[0]\'"
+
+# S1105 $1: cannot specify array subscript here"
+@@error_message[ :"S1105" ] = "$1: ここでは配列添数を指定することができません．"
+
+# S1106 $1: cannot specify array subscript number. use \'[]\'"
+@@error_message[ :"S1106" ] = "$1: 配列添数の数値を指定することが出来ません．\'[]\' をお使いください．"
+
+# S1107 to export port, use \'cCall => composite.cCall\'"
+@@error_message[ :"S1107" ] = "口(port)を外部に公開するため, \'cCall => composite.cCall\' をお使いください．"
+
+# S1108 $1: rhs not \'Cell.ePort\' form"
+@@error_message[ :"S1108" ] = "$1: 右辺が \'Cell.ePort\' の形式ではありません．"
+
+# S1109 \'$1\' not found"
+@@error_message[ :"S1109" ] = "\'$1\' が見つかりません．"
+
+# S1110 \'$1\' not cell"
+@@error_message[ :"S1110" ] = "\'$1\' セルではありません．"
+
+# S1111 \'$1\' not found"
+@@error_message[ :"S1111" ] = "\'$1\' が見つかりません．"
+
+# S1112 \'$1\' not entry port"
+@@error_message[ :"S1112" ] = "\'$1\' 受け口ではありません．"
+
+# S1113 \'$1\' signature mismatch"
+@@error_message[ :"S1113" ] = "\'$1\' シグニチャが整合していません．"
+
+# S1114 \'$1\' should be array"
+@@error_message[ :"S1114" ] = "\'$1\' 配列である必要があります．"
+
+# S1115 $1[$2]: subscript out of range (< $3)"
+@@error_message[ :"S1115" ] = "$1[$2]: 配列の添数が範囲外の値です．(< $3)"
+
+# S1116 \'$1\' entry port is not array"
+@@error_message[ :"S1116" ] = "\'$1\' 受け口が配列ではありません．"
+
+# S1117 \'$1\' not in celltype"
+@@error_message[ :"S1117" ] = "\'$1\' はセルタイプ内にありません．"
+
+# S1118 $1: going out from region \'$2\' not permitted"
+@@error_message[ :"S1118" ] = "$1: リージョン $2 から out することができません．"
+
+# S1119 $1: going from region \'$2\' to \'$3\' not permitted"
+@@error_message[ :"S1119" ] = "$1: リージョン $2 からリージョン $3へ結合できません．"
+
+# S1120 $1: going in to region \'$2\' not permitted"
+@@error_message[ :"S1120" ] = "$1: リージョン \'$2\' へ in することができません．"
+
+# S1121 \'$1\' in region \'$2\' cannot be directly joined $3 in  $4"
+@@error_message[ :"S1121" ] = "リージョン \'$2\' 内の \'$1\' は直接 $4 内の $3 に結合できません．"
+
+# S1122 $1 : not port: \'through\' can be specified only for port"
+@@error_message[ :"S1122" ] = "$1 :口(port) ではありません: \'through\' は口(port)に対してのみ指定できます．"
+
+# S1123 $1 : not port: \'through\' can be specified only for port"
+@@error_message[ :"S1123" ] = "$1 :口(port) ではありません: \'through\' は口(port)に対してのみ指定できます．"
+
+# S1124 $1: plugin function failed: \'get_through_entry_port_name\'"
+@@error_message[ :"S1124" ] = "$1: プラグイン関数が失敗しました．: \'get_through_entry_port_name\'"
+
+# S1125 $1: not generated cell \'$2\'"
+@@error_message[ :"S1125" ] = "$1: 生成されたセル \'$2\' ではありません．"
+
+# S1126 $1: fail to new"
+@@error_message[ :"S1126" ] = "$1: new に失敗しました．"
+
+# S1127 \'$1\' duplicate"
+@@error_message[ :"S1127" ] = "\'$1\' が重複しています．"
+
+# S1128 \'$1\' inconsistent array definition"
+@@error_message[ :"S1128" ] = "\'$1\' は一貫しない配列定義です．"
+
+# S1129 \'$1\' redefinition of subscript $1"
+@@error_message[ :"S1129" ] = "\'$1\' は配列添数 $1 の再定義です．"
+
+# S1130 \'$1\' inconsistent array definition"
+@@error_message[ :"S1130" ] = "\'$1\' は一貫しない配列定義です．"
+
+# S1131 \'$1.$2\' has duplicate initializer"
+@@error_message[ :"S1131" ] = "\'$1.$2\' には重複した初期化子があります．"
+
+# S1132 $1: 1st parameter is not string(file name)"
+@@error_message[ :"S1132" ] = "$1: 第1パラメータが string(ファイル名) ではありません．"
+
+# S1133 $1: 2nd parameter is not string(fromat)"
+@@error_message[ :"S1133" ] = "$1: 第2パラメータが string(ファイル名) ではありません．"
+
+# S1134 $1: unknown factory function"
+@@error_message[ :"S1134" ] = "$1: 不明なファクトリ関数です．"
+
+# S1135 celltype factory can\'t have parameter(s)"
+@@error_message[ :"S1135" ] = "セルタイプファクトリはパラメータを持つことができません．"
+
+# S1136 \'$1\': not found"
+@@error_message[ :"S1136" ] = "\'$1\': 見つかりません．"
+
+# S1137 \'$1\': not attribute"
+@@error_message[ :"S1137" ] = "\'$1\': 属性ではありません．"
+
+# S1138 internal error Factory.check_arg()"
+@@error_message[ :"S1138" ] = "Factory.check_arg() の内部エラーです．"
+
+# S1139 $1: region path mismatch. previous path: $2"
+@@error_message[ :"S1139" ] = "$1: リージョンパスが整合していません．以前のパス: $2"
+
+# S1140 $1: region specifier must place at first appearence"
+@@error_message[ :"S1140" ] = "$1: リージョン指定子は最初に配置する必要があります．"
+
+# S1141 $1 duplication, previous one : $2"
+@@error_message[ :"S1141" ] = "$1 が重複しています, 以前の値 : $2"
+
+# S1142 $1 not found in search path"
+@@error_message[ :"S1142" ] = "$1 が検索パスの中に見つかりません．"
+
+# S1143 import_C: arg2: mismatch with previous one"
+@@error_message[ :"S1143" ] = "import_C: arg2: 以前のものと整合していません．"
+
+# S1144 $1: temporary C source: open error"
+@@error_message[ :"S1144" ] = "$1: 一時的な C ソース: オープンエラーです．"
+
+# S1145 $1: temporary C source: writing error"
+@@error_message[ :"S1145" ] = "$1: 一時的な C ソース: 書込みエラーです．"
+
+# S1146 $1: error occured while CPP"
+@@error_message[ :"S1146" ] = "$1: CPP 実行中にエラーが発生しました．"
+
+# S1147 $1: popen for CPP failed"
+@@error_message[ :"S1147" ] = "$1: CPPに対する popen が失敗しました．"
+
+# S1148 $1 not found in search path"
+@@error_message[ :"S1148" ] = "$1 が検索パスの中に見つかりません．"
+
+# S1149 $1 not signature"
+@@error_message[ :"S1149" ] = "$1 シグニチャではありません．"
+
+# S1150 $1: fail to new"
+@@error_message[ :"S1150" ] = "$1: new に失敗しました．"
+
+# S1151 $1: not namespace"
+@@error_message[ :"S1151" ] = "$1: ネームスペースではありません．"
+
+# S1152 $1: call port cannot have fixed join"
+@@error_message[ :"S1152" ] = "$1: 呼び口は固定結合を持つことができません．"
+
+# "S1153 $1: cannot be entry port array for fixed join port"
+@@error_message[ :"S1153" ] = "$1: 固定結合の口に対する受け口配列はあり得ません．"
+
+# "S1154 $1: must be singleton celltype for fixed join"
+@@error_message[ :"S1154" ] = "$1: 固定結合に対するシングルトンセルタイプである必要があります．"
+
+# "S1155 $1: not celltype or not found"
+@@error_message[ :"S1155" ] = "$1: セルタイプではないかまたは見つかりません．"
+
+# "S1156 $1: not call port or not found"
+@@error_message[ :"S1156" ] = "$1: 呼び口ではないかまたは見つかりません．"
+
+# "S1157 $1: sized array or not array"
+@@error_message[ :"S1157" ] = "$1: サイズ指定された配列かまたは配列ではありません．"
+
+# "S1158 $1: singleton cell not found for fixed join"
+@@error_message[ :"S1158" ] = "$1: シングルトンセルが固定結合に対して見つかりません．"
+
+# S1159 $1: non-size_is pointer cannot be initialized with array initializer"
+@@error_message[ :"S1159" ] = "$1: size_is 指定されていないポインタは、配列初期化子で初期化できません"
+
+# S1160 $1 must be constant for id"
+@@error_message[ :"S1160" ] = "$1 id は定数でなければなりません"
+
+# S1161 $1 must be constant for id"
+@@error_message[ :"S1161" ] = "$1 id は定数でなければなりません"
+
+# S1162 $1: id cannot be 0"
+@@error_message[ :"S1162" ] = "$1: id に 0 を指定できません"
+
+# S1163 generate specifier duplicate"
+@@error_message[ :"S1163" ] = "generate 指定子が重複しています"
+
+# S1164 '$1' set_specified_id: id not positive integer '$2'"
+@@error_message[ :"S1164" ] = "'$1' id が正整数でありません '$2'"
+
+# S1165 '$1' set_specified_id: id duplicate"
+@@error_message[ :"S1165" ] = "'$1' id 指定子が重複しています"
+
+# S1166 $1: fail to new"
+@@error_message[ :"S1166" ] = "$1: プラグインの生成に失敗しました"
+
+# S1167 \'$1\': relay mismatch \'$2\'"
+@@error_message[ :"S1167" ] = "\'$1\': リレーにマッチしません \'$2\'"
+
+# S1168 too many initializer for array, $1 for $2"
+@@error_message[ :"S1168" ] = "配列初期化子が多すぎます $1 for $2"
+
+# S1169 $1: non-size_is pointer cannot be initialized with array initializer"
+@@error_message[ :"S1169" ] = "$1: size_is 指定されていないポインタに配列初期化子を指定できません"
+
+# S1170 \'$1\' has size_is but export attr \'$2\' doesn't have"
+@@error_message[ :"S1170" ] = "\'$1\' に size_is 指定されていますがエクスポートする \'$2\' に指定されていません"
+
+# S1171 \'$1\' size_is argument of \'$2\' not exported"
+@@error_message[ :"S1171" ] = "\'$1\' \'$2\' size_is 引数がエクスポートされていません"
+
+# S1172 \'$1\' size_is argument mismatch with exporting one \'$2\'"
+@@error_message[ :"S1172" ] = "\'$1\' size_is 引数がエクスポートされている \'$2\' と一致しません"
+
+# S1173 $1: allocator mismatch from $2's allocator"
+@@error_message[ :"S1173" ] = "$1: アロケータが $2' のアロケータと一致しません"
+
+# S1174 $1 not suitable for lhs, suitable lhs: 'func.param'"
+@@error_message[ :"S1174" ] = "$1 左辺が不適切です。適切な左辺は 'func.param' の形式です"
+
+# S1175 $1 not found or not allocator entry port for $2"
+@@error_message[ :"S1175" ] = "$1  $2 のアロケータ受け口が見当たらないか、アロケータ受け口ではありません"
+
+# S1176 rhs not in 'call_port.func.param' form for $1_$2"
+@@error_message[ :"S1176" ] = "右辺が 'call_port.func.param' 形式でありません ($1_$2)"
+
+# S1177 cannot specify 'through' in composite in current version"
+@@error_message[ :"S1177" ] = "現在のバージョンでは、コンポジットセルに 'through'を指定できません"
+
+# S1178 $1 region type specifier duplicate, previous $2"
+@@error_message[ :"S1178" ] = "$1 リージョンタイプ指定子が重複しています。以前は $2 でした"
+
+### syntaxobj.rb
+# S2001 \'$1\' duplicate $2"
+@@error_message[ :"S2001" ] = "\'$1\': 重複しています ($2)"
+
+# S2002 $1: $2"
+@@error_message[ :"S2002" ] = "$1: $2"
+
+# S2003 $1: $2 cannot have initializer"
+@@error_message[ :"S2003" ] = "$1: $2 は初期化子をもつことができません．"
+
+# S2004 $1: array subscript must be specified or omit"
+@@error_message[ :"S2004" ] = "$1: 配列添数は指定されるかまたは省略される必要があります．"
+
+# S2005 $1: array subscript must be specified"
+@@error_message[ :"S2005" ] = "$1: 配列添数は指定される必要があります．"
+
+# S2006 \'$1\' function"
+@@error_message[ :"S2006" ] = "\'$1\' 関数です．"
+
+# S2007 \'$1\' $2"
+@@error_message[ :"S2007" ] = "\'$1\' $2"
+
+# S2008 $1: inconsitent with previous one"
+@@error_message[ :"S2008" ] = "$1: 以前のものと一貫していません．"
+
+# S2009 $1: not found or not signature"
+@@error_message[ :"S2009" ] = "$1: 見つからないかまたはシグニチャではありません．"
+
+# S2010 $1: not allocator signature"
+@@error_message[ :"S2010" ] = "$1: アロケータシグニチャではありません．"
+
+# S2011 size_is duplicate"
+@@error_message[ :"S2011" ] = "size_is が重複しています．"
+
+# S2012 count_is duplicate"
+@@error_message[ :"S2012" ] = "count_is が重複しています．"
+
+# S2013 string duplicate"
+@@error_message[ :"S2013" ] = "string が重複しています．"
+
+# S2014 $1 need pointer or more pointer"
+@@error_message[ :"S2014" ] = "$1 は一つ以上のポインタが必要です．"
+
+# S2015 $1 must be const for \'in\' parameter $2"
+@@error_message[ :"S2015" ] = "'$1' は \'in\' パラメータ $2 に対して定数である必要があります．"
+
+# S2016 $1 can not be const for $2 parameter"
+@@error_message[ :"S2016" ] = "'$1' は $2 パラメータに対して定数指定できません． "
+
+# S2017 size_is argument is not integer type"
+@@error_message[ :"S2017" ] = "size_is 引数が整数型ではありません．"
+
+# S2018 \'$1\' size_is parameter not integer"
+@@error_message[ :"S2018" ] = "\'$1\' size_is パラメータは整数ではありません．"
+
+# S2019 \'$1\' size_is parameter negative or zero"
+@@error_message[ :"S2019" ] = "\'$1\' size_is パラメータが負数またはゼロです．"
+
+# S2020 count_is argument is not integer type"
+@@error_message[ :"S2020" ] = "count_is 引数は整数型ではありません．"
+
+# S2021 \'$1\' count_is parameter not integer"
+@@error_message[ :"S2021" ] = "\'$1\' count_is パラメータは整数型ではありません．"
+
+# S2022 \'$1\' count_is parameter negative or zero"
+@@error_message[ :"S2022" ] = "\'$1\' count_is パラメータは負数またはゼロです．"
+
+# S2023 string argument is not integer type"
+@@error_message[ :"S2023" ] = "string 引数は整数型ではありません．"
+
+# S2024 \'$1\' string parameter not integer"
+@@error_message[ :"S2024" ] = "\'$1\' string パラメータは整数型ではありません．"
+
+# S2025 \'$1\' string parameter negative or zero"
+@@error_message[ :"S2025" ] = "\'$1\' string パラメータは負数またはゼロです．"
+
+# S2026 '$1' nullable specified for non-pointer type"
+@@error_message[ :"S2026" ] = "'$1' ポインタ型以外に nullable が指定されました"
+
+# S2027 '$1' parameter cannot be void type"
+@@error_message[ :"S2027" ] = "'$1' 引数を void 型にできません"
+
+# S2028 '$1' max (size_is 2nd parameter) not constant"
+@@error_message[ :"S2028" ] = "'$1' max (size_is の第二引数)が定数でありません"
+
+# S2029 '$1' max (size_is 2nd parameter) negative or zero, or not integer"
+@@error_message[ :"S2029" ] = "'$1' max (size_is の第二引数) が負、ゼロまたは整数ではありません"
+
+# S2030 '$1' both size_is and max are const. size_is larger than max"
+@@error_message[ :"S2030" ] = "'$1' size_is max の両方が定数で. size_is の方が max を超えています"
+
+### optimize.rb
+# S3001 $1: id too large $2 (max=$3)"
+@@error_message[ :"S3001" ] = "$1: id に $2 は大きすぎます (最大値は$3)"
+
+# S3002 $1: id too large $2 (max=$3)"
+@@error_message[ :"S3002" ] = "$1: id too large $2 (max=$3)"
+
+# S3003 $1: id number '$2' conflict with $3"
+@@error_message[ :"S3003" ] = "$1: id 番号 '$2' は $3 と衝突しています"
+
+### types.rb
+# T1001 const duplicate"
+@@error_message[ :"T1001" ] = "const が重複しています．"
+
+# T1002 volatile duplicate"
+@@error_message[ :"T1002" ] = "volatile が重複しています．"
+
+# T1003 $1: unsuitable specifier for $2"
+@@error_message[ :"T1003" ] = "$1: $2 に対する不適切な指定子です．"
+
+# T1004 cannot cast to $1"
+@@error_message[ :"T1004" ] = "$1 へキャストできません．"
+
+# T1005 \'$1\' not defined"
+@@error_message[ :"T1005" ] = "\'$1\' は定義されていません．"
+
+# T1006 \'$1\' not type name. expecting type name here"
+@@error_message[ :"T1006" ] = "\'$1\' は型名ではありません．ここは型名が必要です．"
+
+# T1007 $1: void type variable cannot have initializer"
+@@error_message[ :"T1007" ] = "$1: void 型変数は初期化子をもつことができません．"
+
+# T1008 ambigous signed or unsigned"
+@@error_message[ :"T1008" ] = "符号付きであるかまたは符号無しであるかが曖昧です．"
+
+# T1009 $1: $2: not integer"
+@@error_message[ :"T1009" ] = "$1: $2: 整数ではありません．"
+
+# T1010 $1: initializer is not constant"
+@@error_message[ :"T1010" ] = "$1: 初期化子は定数ではありません．"
+
+# T1011 $1: need cast to assign float to integer"
+@@error_message[ :"T1011" ] = "$1: 浮動小数点型から整数型へ割り当てのためにキャストが必要です．"
+
+# T1012 $1: $2: not integer"
+@@error_message[ :"T1012" ] = "$1: $2: 整数ではありません．"
+
+# T1013 $1: too large (max=$2)"
+@@error_message[ :"T1013" ] = "$1: 値が大きすぎます (max=$2)"
+
+# T1014 $1: too large negative value (min=-$2)"
+@@error_message[ :"T1014" ] = "$1: 負数の絶対値が大きすぎます．(min=-$2)"
+
+# T1015 $1: negative value for unsigned"
+@@error_message[ :"T1015" ] = "$1: 符号無し整数型に対し負数値が使用されています．"
+
+# T1016 $1: too large (max=$2)"
+@@error_message[ :"T1016" ] = "$1: 値が大きすぎます．(max=$2)"
+
+# T1017 $1: unsuitable initializer for scalar type"
+@@error_message[ :"T1017" ] = "$1: スカラー型に対する不適当な初期化子です．"
+
+# T1018 $1: $2: not number"
+@@error_message[ :"T1018" ] = "$1: $2: 数値ではありません．"
+
+# T1019 $1: initializer is not constant"
+@@error_message[ :"T1019" ] = "$1: 初期化子は定数ではありません．"
+
+# T1020 $1: unsuitable initializer for scalar type"
+@@error_message[ :"T1020" ] = "$1: スカラー型に対する不適当な初期化子です．"
+
+# T1021 \'$1\': struct not defined"
+@@error_message[ :"T1021" ] = "\'$1\': 構造体が定義されていません．"
+
+# T1022 struct $1: not defined"
+@@error_message[ :"T1022" ] = "構造体 $1: 定義されていません．"
+
+# T1023 struct $1: not defined"
+@@error_message[ :"T1023" ] = "構造体 $1: 定義されていません．"
+
+# T1024 $1: unsuitable initializer for struct"
+@@error_message[ :"T1024" ] = "$1: 構造体に対する不適当な初期化子です．"
+
+# T1025 size_is argument is not integer type"
+@@error_message[ :"T1025" ] = "size_is 引数 は整数型ではありません．"
+
+# T1026 count_is argument is not integer type"
+@@error_message[ :"T1026" ] = "count_is 引数 は整数型ではありません．"
+
+# T1027 string argument is not integer type"
+@@error_message[ :"T1027" ] = "string 引数は整数型ではありません．"
+
+# T1028 $1: cannot initialize function pointer"
+@@error_message[ :"T1028" ] = "$1: 関数ポインタを初期化することはできません．"
+
+# T1029 oneway function cannot return type \'$1$2\', \'void\' or \'ER\' is permitted"
+@@error_message[ :"T1029" ] = "一方向関数は型 \'$1$2\' を返すことができません．\'void\' または \'ER\' が使用できます．"
+
+# T1030 oneway function cannot have $1 parameter for \'$2\'"
+@@error_message[ :"T1030" ] = "一方向関数は \'$2\' のために $1 パラメータを持つことができません．"
+
+# T1031 $1: unsuitable initializer for array"
+@@error_message[ :"T1031" ] = "$1: 配列に対する不適当な初期化子です．"
+
+# T1032 $1: incompatible pointer type"
+@@error_message[ :"T1032" ] = "$1: 互換性のないポインタ型です．"
+
+# T1033 $1: need cast to assign integer to pointer"
+@@error_message[ :"T1033" ] = "$1: 整数型をポインタへ割り当てるためにはキャストが必要です．"
+
+# T1034 $1: unsuitable string constant"
+@@error_message[ :"T1034" ] = "$1: 不適当な文字列定数です．"
+
+# T1035 $1: unsuitable initializer for pointer"
+@@error_message[ :"T1035" ] = "$1: ポインタに対する不適当な初期化子です．"
+
+# T1036 $1: unsuitable initializer for pointer"
+@@error_message[ :"T1036" ] = "$1: ポインタに対する不適当な初期化子です．"
+
+# T1037 $1: not number"
+@@error_message[ :"T1037" ] = "$1: 数値ではありません"
+
+# T1038 $1: initializer type mismatch. '$2' & '$3'"
+@@error_message[ :"T1038" ] = "$1: 初期化子の型が一致しません. '$2' と '$3'"
+
+# T1039 $1: struct tag mismatch $2 and $3"
+@@error_message[ :"T1039" ] = "$1: 構造体タグが $2 と $3 で一致しません"
+
+# T1040 $1 specified for void pointer type"
+@@error_message[ :"T1040" ] = "$1 void ポインタ型に指定されました"
+
+### gen_xml.rb
+# T2001 fail to create XML file $1"
+@@error_message[ :"T2001" ] = "XML ファイル $1 の生成に失敗しました"
+
+# TEMPORAL set_definition_join: uninitialized array member"
+@@error_message[ :"TEMPORAL" ] = "set_definition_join: 配列メンバが初期化されていません．"
+
+# V1001 $1: unable for $2"
+@@error_message[ :"V1001" ] = "$1: unable for $2"
+
+# V1002 $1: cannot cast to bool (implicitly)"
+@@error_message[ :"V1002" ] = "$1: ブール型への(暗黙的な)キャストを行うことができません．"
+
+# V1003 $1: cannot cast to integer (implicitly)"
+@@error_message[ :"V1003" ] = "$1: 整数型への(暗黙的な)キャストを行うことができません．"
+
+# V1004 $1: cannot cast to float (implicitly)"
+@@error_message[ :"V1004" ] = "$1: 浮動小数点型への(暗黙的な)キャストを行うことができません．"
+
+# V1005 Cannot cast pointer to float"
+@@error_message[ :"V1005" ] = "ポインタ型を浮動小数点型へキャストを行うことができません．"
+
+# V1006 pointer value cannot cast to $1"
+@@error_message[ :"V1006" ] = "ポインタ値は $1 へキャストを行うことができません．"
+
+# V1007 convert pointer value to bool"
+@@error_message[ :"V1007" ] = "ポインタ値をブール型へ変換しました．"
+
+# V1008 convert pointer value to integer without cast"
+@@error_message[ :"V1008" ] = "ポインタ値をキャスト無しで整数型へ変換しました．"
+
+# V1009 / : divieded by zero"
+@@error_message[ :"V1009" ] = "/ : ゼロ除算エラーです．"
+
+# V1010 / : divieded by zero"
+@@error_message[ :"V1010" ] = "/ : ゼロ除算エラーです．"
+
+# V1011 % : divieded by zero"
+@@error_message[ :"V1011" ] = "% : ゼロ除算エラーです．"
+
+# V1012 % : divieded by zero"
+@@error_message[ :"V1012" ] = "% : ゼロ除算エラーです．"
+
+# V1013 integer value cannot cast to $1"
+@@error_message[ :"V1013" ] = "整数値は $1 へキャストを行うことができません．"
+
+# V1014 comparing bool value with \'$1\'"
+@@error_message[ :"V1014" ] = "ブール値を \'$1\' と比較しました．"
+
+# V1015 comparing bool value with \'$1\'"
+@@error_message[ :"V1015" ] = "ブール値を \'$1\' と比較しました．"
+
+# V1016 bool value cannot cast to $1"
+@@error_message[ :"V1016" ] = "ブール値は $1 へキャストを行うことができません．"
+
+# V1017 / : divieded by zero"
+@@error_message[ :"V1017" ] = "/ : ゼロ除算エラーです．"
+
+# V1018 % : divieded by zero"
+@@error_message[ :"V1018" ] = "% : ゼロ除算エラーです．"
+
+# V1019 floating value cannot cast to $1"
+@@error_message[ :"V1019" ] = "浮動小数点値は $1 へのキャストを行うことができません．"
+
+# V1020 convert floating value to bool without cast"
+@@error_message[ :"V1020" ] = "浮動小数点値をキャスト無しでブール型へ変換しました．"
+
+# V1021 convert floating value to integer without cast"
+@@error_message[ :"V1021" ] = "浮動小数点型をキャスト無しで整数型へ変換しました．"
+
+# V1022 string cannot cast to integer"
+@@error_message[ :"V1022" ] = "文字列は整数型にキャストできません"
+
+# V1023 string cannot cast to float"
+@@error_message[ :"V1023" ] = "文字列は浮動小数点型にキャストできません"
+
+# V1024 string cannot cast to pointer"
+@@error_message[ :"V1024" ] = "文字列はポインタ型にキャストできません"
+
+# V1025 string cannot cast to $1"
+@@error_message[ :"V1025" ] = "文字列は $1 にキャストできません"
+
+###
+# warning メッセージ
+@@warning_message = {}
+
+### componentobj.rb
+# W1001 \'$1\': unknown context type. usually specifiy task, non-task or any"
+@@warning_message[ :"W1001" ] = "\'$1\': 不明なコンテキスト型です．通常 task, non-task または any を指定して下さい．"
+
+# W1002 $1: non-active celltype has no entry port & factory"
+@@warning_message[ :"W1002" ] = "$1: 非アクティブなセルタイプが受け口及びファクトリを持っていません．"
+
+# W1003 $1 : require call port overridden in $2"
+@@warning_message[ :"W1003" ] = "$1 : リクワイア呼び口が $2 でオーバーライドされました．"
+
+# W1004 $1 : specified singleton but has no singleton in this celltype"
+@@warning_message[ :"W1004" ] = "$1 : specified singleton but has no singleton in this celltype"
+
+# W1005 $1 : idx_is_id is ineffective for composite celltype"
+@@warning_message[ :"W1005" ] = "$1 : idx_is_id は複合セルタイプに対しては無効です．"
+
+# W1006 $1 : only prototype, unused and undefined cell"
+@@warning_message[ :"W1006" ] = "$1 : プロトタイプのみ，未使用，かつ未定義のセルです．"
+
+# W1007 $1 : non-active cell has no entry join and no factory"
+@@warning_message[ :"W1007" ] = "$1 : 非アクティブセルに受け口の結合及びファクトリがありません．"
+
+# W1008 $1: reuse designation mismatch with previous import"
+@@warning_message[ :"W1008" ] = "$1: 再使用の指示が以前のインポートのと整合しません．"
+
+# "W1009 $1: fixed join entry port has multi join"
+@@warning_message[ :"W1009" ] = "$1: 固定結合受け口が複数の結合を持っています．"
+
+### types.rb
+# W2001 signed int$1_t: obsolete. use int$2_t"
+@@warning_message[ :"W2001" ] = "signed int$1_t: 推奨されません．int$2_t をお使いください．"
+
+# W2002 unsinged int$1_t: obsolete. use uint$2_t"
+@@warning_message[ :"W2002" ] = "unsinged int$1_t: 推奨されません．uint$2_t をお使いください．"
+
+# W2003 $1: too large to cast to $2, clipped($3)"
+@@warning_message[ :"W2003" ] = "$1: $2 へキャストするのに大きすぎます．切り詰めました($3)"
+
+# W2004 $1: too small to cast to $2, clipped($3)"
+@@warning_message[ :"W2004" ] = "$1: $2 へキャストするのに小さすぎます．切り詰めました($3)"
+
+# W2005 $1: negative value for unsigned: convert to $2"
+@@warning_message[ :"W2005" ] = "$1: 符号無し整数型に対して負数値です : $2 へ変換しました．"
+
+### syntaxobj.rb
+# W3001 $1: duplicate"
+@@warning_message[ :"W3001" ] = "$1: 重複しています．"
+
+# W3002 $1: this string might cause buffer over run"
+@@warning_message[ :"W3002" ] = "$1: この文字列はバッファーオーバーランを引き起こすかもしれません．"
+
+# W3003 $1 pointer level mismatch"
+@@warning_message[ :"W3003" ] = "$1 ポインターレベルの不整合です．"
+
+# W3004 $1 pointer type has returned. specify deviate or stop return pointer"
+@@error_message[ :"W3004" ] = "$1 ポインタ型が返されました。deviate を指定するかポインタを返すのを止めてください"
+
+# W3005 '$1' size_is always lower than max. max is ignored"
+@@error_message[ :"W3005" ] = "'$1' size_is は常に max より小さい. max は無視されます"
+
+### bnf.y.rb
+# W5001 bool: obsolete type. use bool_t"
+@@warning_message[ :"W5001" ] = "bool: 推奨されないデータ型です．bool_t をお使いください．"
+
+# W5002 float: obsolete type. use float32_t"
+@@warning_message[ :"W5002" ] = "float: 推奨されないデータ型です．float32_t をお使いください．"
+
+# W5003 double: obsolete type. use double64_t"
+@@warning_message[ :"W5003" ] = "double: 推奨されないデータ型です．double64_t をお使いください．"
+
+# W5004 char: obsolete type. use char_t"
+@@warning_message[ :"W5004" ] = "char: 推奨されないデータ型です．char_t をお使いください．"
+
+# W5005 int8: obsolete. use int8_t"
+@@warning_message[ :"W5005" ] = "int8: 推奨されません．int8_t をお使いください．"
+
+# W5006 int16: obsolete. use int16_t"
+@@warning_message[ :"W5006" ] = "int16: 推奨されません．int16_t をお使いください．"
+
+# W5007 int32: obsolete. use int32_t"
+@@warning_message[ :"W5007" ] = "int32: 推奨されません．int32_t をお使いください．"
+
+# W5008 int64: obsolete. use int64_t"
+@@warning_message[ :"W5008" ] = "int64: 推奨されません．int64_t をお使いください．"
+
+# W5009 int64: obsolete. use int64_t"
+@@warning_message[ :"W5009" ] = "int64: 推奨されません．int64_t をお使いください．"
+
+# W5010 need 'void' for no parameter"
+@@warning_message[ :"W5010" ] = "パラメータが存在しない場合 'void' が必要です"
+
+# W5011 need 'void' for no parameter"
+@@warning_message[ :"W5011" ] = "パラメータが存在しない場合 'void' が必要です"
+
+### C_parser.y.rb
+# W6001 need 'void' for no parameter"
+@@warning_message[ :"W6001" ] = "パラメータが存在しない場合 'void' が必要です"
+
+# W6002 need 'void' for no parameter"
+@@warning_message[ :"W6002" ] = "パラメータが存在しない場合 'void' が必要です"
+
+# W6003 need 'void' for no parameter"
+@@warning_message[ :"W6003" ] = "パラメータが存在しない場合 'void' が必要です"
+
+# W6004 need 'void' for no parameter"
+@@warning_message[ :"W6004" ] = "パラメータが存在しない場合 'void' が必要です"
+
+###
+# info メッセージ
+@@info_message = {}
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_file_en_US.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_file_en_US.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_file_en_US.rb	(revision 398)
@@ -0,0 +1,342 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+
+# File Messages for en_US 
+class TECSMsg
+
+## generate.rb ##
+
+@@comment = {}
+
+# MSg.note
+# @@comment[ :note ] = " * このファイルは tecsgen により自動生成されました
+#  * このファイルを編集して使用することは、意図されていません
+# "
+@@comment[ :note ] = " * This file was automatically generated by tecsgen.
+ * This file is not intended to be edited.
+"
+
+# @@comment[ :preamble_note ] = "/* #[<PREAMBLE>]#
+#  * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+#  * tecsmerge によるマージに使用されます
+# "
+@@comment[ :preamble_note ] = "/* #[<PREAMBLE>]#
+ * Don't edit the comments between #[<...>]# and #[</...>]#
+ * These comment are used by tecsmerege when merging.
+"
+
+# @@comment[ :postamble_note ] = "/* #[<POSTAMBLE>]#
+#  *   これより下に非受け口関数を書きます
+#  * #[</POSTAMBLE>]#*/
+# "
+@@comment[ :postamble_note ] = "/* #[<POSTAMBLE>]#
+ *   Put non-entry functions below.
+ * #[</POSTAMBLE>]#*/
+"
+
+# @@comment[ :template_note ] = "/*
+#  * このファイルは tecsgen によりテンプレートとして自動生成されました
+#  * このファイルを編集して使用することが意図されていますが
+#  * tecsgen の再実行により上書きされてしまうため、通常
+#  *   gen/%s_templ.c => src/%s.c
+#  * のように名前, フォルダを変更してから修正します
+#  */
+# "
+@@comment[ :template_note ] = "/*
+ * This file was automatically generated by tecsgen.
+ * Move and rename like below before editing,
+ *   gen/%s_templ.c => src/%s.c
+ * to avoid to be overwritten by tecsgen.
+ */
+"
+
+# @@comment[ :inline_template_note ] = "/*
+#  * このファイルは tecsgen によりテンプレートとして自動生成されました
+#  * このファイルを編集して使用することが意図されていますが
+#  * tecsgen の再実行により上書きされてしまうため、通常
+#  *   gen/%s_inline_template.h => src/%s_inline.h
+#  * のように名前, フォルダを変更してから修正します
+#  */
+# "
+@@comment[ :inline_template_note ] = "/*
+ * This file was automatically generated by tecsgen.
+ * Move and rename like below before editing,
+ *   gen/%s_inline_template.h => src/%s_inline.h
+ * to avoid to be overwritten by tecsgen.
+ */
+"
+
+# @@comment[ :Makefile_note ] = "# このファイルは tecsgen により自動生成されました
+# # Makefile.temp は gen の一つ上のディレクトリに移して使用します
+# #  % mv Makefile.temp Makefile
+# # 
+# # clean のデフォルト動作は $(GEN_DIR)/Makefile.* を削除します
+# 
+# "
+@@comment[ :Makefile_note ] = "# This file was automatically generated by tecsgen.
+# Move Makefile.temp upper directory like below before editing.
+#  % mv Makefile.temp Makefile
+# 
+# \"make clean\" deletes $(GEN_DIR)/Makefile.* by default.
+#
+# This file is generated suitable for GNU make and a target on POSIX environemnt using gcc.
+# You might have to adjust vpath, CFLAGS, OTHER_OBJS, etc.
+# For other target you have to modify this file.
+
+"
+
+# @@comment[ :oneway_ercd_note ] = "/* oneway の場合 E_OK しか返せません */"
+@@comment[ :oneway_ercd_note ] = "/* Oneway function always returns E_OK. */"
+
+# @@comment[ :ercd_note ] = "/* エラー処理コードをここに記述します */"
+@@comment[ :ercd_note ] = "/* Write error processing code here */"
+
+# @@comment[ :IMP_comment ] = "\n/* import_C により import されるヘッダ %s */\n"
+@@comment[ :IMP_comment ] = "\n/* header imported by import_C %s */\n"
+
+# @@comment[ :MVAR_comment ] = "# 変数 %s\n"
+@@comment[ :MVAR_comment ] = "# var %s\n"
+
+# @@comment[ :MRUL_comment ] = "# ルール %s\n"
+@@comment[ :MRUL_comment ] = "# Rule %s\n"
+
+# @@comment[ :TCM_comment ] = "# テンプレートコードでメークしてみる場合 %s\n"
+@@comment[ :TCM_comment ] = "# in case build with template code %s\n"
+
+# @@comment[ :MDEP_comment ] = "\n# depend を include %s\n"
+@@comment[ :MDEP_comment ] = "\n# include dependcy %s\n"
+
+# @@comment[ :SDI_comment ] = "/* シグニチャディスクリプタ参照ヘッダ %s */\n"
+@@comment[ :SDI_comment ] = "/* descriptor referencing signature header %s */\n"
+
+# @@comment[ :SD_comment ] = "/* シグニチャディスクリプタ %s */\n"
+@@comment[ :SD_comment ] = "/* signature descriptor %s */\n"
+
+# @@comment[ :SFT_comment ] = "/* シグニチャ関数テーブル %s */\n"
+@@comment[ :SFT_comment ] = "/* signature function table %s */\n"
+
+# @@comment[ :SDES_comment ] = "/* シグニチャディスクリプタ(動的結合用) %s */\n"
+@@comment[ :SDES_comment ] = "/* signature descriptor %s for dynamic join */\n"
+
+# @@comment[ :IRTH_comment ] = "/* ランタイムヘッダ %s */\n"
+
+# @@comment[ :UDF_comment ] = "/* inline のための undef %s */\n"
+@@comment[ :UDF_comment ] = "/* undef for inline %s */\n"
+
+# @@comment[ :IGH_comment ] = "/* グローバルヘッダ %s */\n"
+@@comment[ :IGH_comment ] = "/* global header %s */\n"
+
+# @@comment[ :ISH_comment ] = "/* シグニチャヘッダ %s */\n"
+@@comment[ :ISH_comment ] = "/* signature header %s */\n"
+
+# @@comment[ :ICT_comment ] = "/* 最適化のため参照するセルタイプの CB 型の定義を取込む %s */\n"
+@@comment[ :ICT_comment ] = "/* to get the definition of CB type of referenced celltype for optimization %s */\n"
+
+# @@comment[ :NIDB_comment ] = "ID のベース "
+@@comment[ :NIDB_comment ] = "ID Base "
+
+# @@comment[ :NCEL_comment ] = "セルの個数"
+@@comment[ :NCEL_comment ] = " number of cells"
+
+# @@comment[ :CVI_comment ] = "/* IDXの正当性チェックマクロ %s */\n"
+@@comment[ :CVI_comment ] = "/* IDX validation macro %s */\n"
+
+# @@comment[ :CVIA_comment ] = "/* IDXの正当性チェックマクロ（短縮形） %s */\n"
+@@comment[ :CVIA_comment ] = "/* IDX validation macro (abbrev.) %s */\n"
+
+# @@comment[ :NCPA_comment ] = "/* 呼び口配列の大きさを得るマクロ %s */\n"
+@@comment[ :NCPA_comment ] = "/* call port array size macro %s */\n"
+
+# @@comment[ :NEPA_comment ] = "/* 受け口配列の大きさを得るマクロ %s */\n"
+@@comment[ :NEPA_comment ] = "/* entry port array size macro %s */\n"
+
+# @@comment[ :TOCP_comment ] = "/* optional 呼び口をテストするマクロ %s */\n"
+@@comment[ :TOCP_comment ] = "/* optional call port test macro %s */\n"
+
+# @@comment[ :TOCPA_comment ] = "/* optional 呼び口をテストするマクロ（短縮形） %s */\n"
+@@comment[ :TOCPA_comment ] = "/* optional call port test macro (abbrev) %s */\n"
+
+# @@comment[ :GCB_comment ] = "\n/* セルCBを得るマクロ %s */\n"
+@@comment[ :GCB_comment ] = "\n/* celll CB macro %s */\n"
+
+# @@comment[ :GCBA_comment ] = "\n/* セルCBを得るマクロ(短縮形) %s */\n"
+@@comment[ :GCBA_comment ] = "\n/* cell CB macro (abbrev) %s */\n"
+
+# @@comment[ :CCT_comment ] = "/* CELLCB 型(短縮形) %s */\n"
+@@comment[ :CCT_comment ] = "/* CELLCB type (abbrev) %s */\n"
+
+# @@comment[ :CTIXA_comment ] = "/* セルタイプのIDX型(短縮形) %s */\n"
+@@comment[ :CTIXA_comment ] = "/* celltype IDX type (abbrev) %s */\n"
+
+# @@comment[ :AAM_comment ] = "\n/* 属性アクセスマクロ %s */\n"
+@@comment[ :AAM_comment ] = "\n/* attr access  %s */\n"
+
+# @@comment[ :VAM_comment ] = "\n/* var アクセスマクロ %s */\n"
+@@comment[ :VAM_comment ] = "\n/* var access macro %s */\n"
+
+# @@comment[ :AAMA_comment ] = "\n/* 属性アクセスマクロ(短縮形) %s */\n"
+@@comment[ :AAMA_comment ] = "\n/* attr access macro (abbrev) %s */\n"
+
+# @@comment[ :VAMA_comment ] = "\n/* var アクセスマクロ(短縮形) %s */\n"
+@@comment[ :VAMA_comment ] = "\n/* var access macro (abbrev) %s */\n"
+
+# @@comment[ :CPM_comment ] = " /* 呼び口関数マクロ %s */\n"
+@@comment[ :CPM_comment ] = " /* call port function macro %s */\n"
+
+# @@comment[ :CPMA_comment ] = "/* 呼び口関数マクロ（短縮形）%s */\n"
+@@comment[ :CPMA_comment ] = "/* call port function macro (abbrev) %s */\n"
+
+# @@comment[ :EPM_comment ] = "\n/* 受け口関数マクロ（短縮形） %s */\n"
+@@comment[ :EPM_comment ] = "\n/* entry port function macro (abbrev) %s */\n"
+
+# @@comment[ :CRD_comment ] = "\n/* ディスクリプタ参照関数 %s */\n"
+@@comment[ :CRD_comment ] = "/* refer to descriptor function %s */\n"
+
+# @@comment[ :CRDA_comment ] = "\n/* ディスクリプタ参照マクロ（短縮形） %s */\n"
+@@comment[ :CRDA_comment ] = "\n/* refer to descriptor macro (abbrev) %s */\n"
+
+# @@comment[ :SDF_comment ] = "/* ディスクリプタ設定関数 %s */\n"
+@@comment[ :SDF_comment ] = "/* set descriptor function %s */\n"
+
+# @@comment[ :SDMA_comment ] = "\n/* ディスクリプタ設定マクロ（短縮形） %s */\n"
+@@comment[ :SDMA_comment ] = "\n/* set descriptor macro (abbrev) %s */\n"
+
+# @@comment[ :CTIX_comment ] = "\n/* セルタイプのIDX型 %s */\n"
+@@comment[ :CTIX_comment ] = "\n/* celltype IDX type %s */\n"
+
+# @@comment[ :EPP_comment ] = "\n/* 受け口関数プロトタイプ宣言 %s */\n"
+@@comment[ :EPP_comment ] = "\n/* prototype declaration of entry port function %s */\n"
+
+# @@comment[ :EPSP_comment ] = "\n/* 受け口スケルトン関数プロトタイプ宣言（VMT不要最適化により参照するもの） %s */\n"
+@@comment[ :EPSP_comment ] = "\n/* prototype declaration of entry port function (referenced when VMT useless optimise enabled) %s */\n"
+
+# @@comment[ :INL_comment ] = "/* inline ヘッダの include %s */\n"
+@@comment[ :INL_comment ] = "/*  include inline header %s */\n"
+
+# @@comment[ :CIP_comment ] = "/* セル INIB 型宣言 %s */\n"
+@@comment[ :CIP_comment ] = "/* cell INIB type definition %s */\n"
+
+# @@comment[ :CCTPA_comment ] = "/* セル CB 型宣言 %s */\n"
+@@comment[ :CCTPA_comment ] = "/* cell CB type definition %s */\n"
+
+# @@comment[ :CCDP_comment ] = "/* セル CB (ダミー)型宣言 %s */\n"
+@@comment[ :CCDP_comment ] = "/* cell CB (dummy) type definition %s */\n"
+
+# @@comment[ :CCTPO_comment ] = "/* セル CB 型宣言 %s */\n"
+@@comment[ :CCTPO_comment ] = "/* cell CB type definition %s */\n"
+
+# @@comment[ :SCP_comment ] = "/* シングルトンセル CB プロトタイプ宣言 %s */\n"
+@@comment[ :SCP_comment ] = "/* singleton cell CB prototype declaration %s */\n"
+
+# @@comment[ :DCI_comment ] = "\n/* CB は存在しない。INIB を CB の代わりに使用するための define %s */\n"
+@@comment[ :DCI_comment ] = "\n/* CB not exist. CB corresponding to INIB %s */\n"
+
+# @@comment[ :FEC_comment ] = "/* イテレータコード (FOREACH_CELL)の生成 %s */\n"
+@@comment[ :FEC_comment ] = "/* iteration code (FOREACH_CELL) %s */\n"
+
+# @@comment[ :DAL_comment ] = "/* deallocate マクロ %s */\n"
+@@comment[ :DAL_comment ] = "/* deallocate macro %s */\n"
+
+# @@comment[ :NFEC_comment ] = "/* イテレータコード (FOREACH_CELL)の生成(CB,INIB は存在しない) %s */\n"
+@@comment[ :NFEC_comment ] = "/* iteration code (FOREACH_CELL) (niether CB, nor NIB exit) %s */\n"
+
+# @@comment[ :CIM_comment ] = "/* CB 初期化マクロ %s */\n"
+@@comment[ :CIM_comment ] = "/* CB initialize macro %s */\n"
+
+# @@comment[ :EDT_comment ] = "/* 受け口ディスクリプタ型 %s */\n"
+@@comment[ :EDT_comment ] = "/* entry port descriptor type %s */\n"
+
+# @@comment[ :EPSF_comment ] = "/* 受け口スケルトン関数 %s */\n"
+@@comment[ :EPSF_comment ] = "/* entry port skelton function %s */\n"
+
+# @@comment[ :EPSFT_comment ] = "/* 受け口スケルトン関数テーブル %s */\n"
+@@comment[ :EPSFT_comment ] = "/* entry port skelton function table %s */\n"
+
+# @@comment[ :CPEPD_comment ] = "/* 呼び口の参照する受け口ディスクリプタ(実際の型と相違した定義) %s */\n"
+@@comment[ :CPEPD_comment ] = "/* entry port descriptor referenced by call port (differ from actual definition) %s */\n"
+
+# @@comment[ :CPA_comment ] = "/* 呼び口配列 %s */\n"
+@@comment[ :CPA_comment ] = "/* call port array %s */\n"
+
+# @@comment[ :CIC_comment ] = "/* CB 初期化コード %s */\n"
+@@comment[ :CIC_comment ] = "/* CB initialize code %s */\n"
+
+# @@comment[ :AVAI_comment ] = "/* 属性・変数の配列 %s */\n"
+@@comment[ :AVAI_comment ] = "/* array of attr/var %s */\n"
+
+# @@comment[ :AVI_comment ] = "/* 変数(構造体、配列)初期値 %s */\n"
+@@comment[ :AVI_comment ] = "/* var (struct, array) initial value %s */\n"
+
+# @@comment[ :INIB_comment ] = "/* セル INIB %s */\n"
+@@comment[ :INIB_comment ] = "/* cell INIB %s */\n"
+
+# @@comment[ :CB_comment ] = "/* セル CB %s */\n"
+@@comment[ :CB_comment ] = "/* cell CB %s */\n"
+
+# @@comment[ :EPD_comment ] = "/* 受け口ディスクリプタ %s */\n"
+@@comment[ :EPD_comment ] = "/* entry port descriptor %s */\n"
+
+# @@comment[ :PAC_comment ] = "/* プロトタイプ宣言や変数の定義をここに書きます %s */\n"
+@@comment[ :PAC_comment ] = "/* Put prototype declaration and/or variale definition here %s */\n"
+
+# @@comment[ :CAAM_comment ] = " *\n * 属性アクセスマクロ %s\n"
+@@comment[ :CAAM_comment ] = " *\n * attr access macro %s\n"
+
+# @@comment[ :CAAMI_comment ] = " *\n * 属性アクセスマクロ %s\n"
+@@comment[ :CAAMI_comment ] = " *\n * attr access macro %s\n"
+
+# @@comment[ :TYP_comment ] = " *\n * 型 %s\n * CELLCB 型  : %s\n * CELLIDX 型 : %s\n"
+@@comment[ :TYP_comment ] = " *\n * type %s\n * CELLCB type  : %s\n * CELLIDX type : %s\n"
+
+# @@comment[ :TCPF_comment ] = " * 呼び口関数 %s\n"
+@@comment[ :TCPF_comment ] = " * call port function %s\n"
+
+# @@comment[ :TEPF_comment ] = "/* 受け口関数 %s */\n"
+@@comment[ :TEPF_comment ] = "/* entry port function %s */\n"
+
+# @@comment[ :TEFB_comment ] = "\t/* ここに処理本体を記述します %s */\n"
+@@comment[ :TEFB_comment ] = "\t/* Put statements here %s */\n"
+
+# @@comment[ :MCPP_comment ] = "/* セル CB プロトタイプ宣言 %s */\n"
+@@comment[ :MCPP_comment ] = "/* cell CB prototype declaration %s */\n"
+
+# @@comment[ :MCPB_comment ] = "/* セル CB プロトタイプ宣言 %s */\n"
+@@comment[ :MCPB_comment ] = "/* cell CB prototype declaration %s */\n"
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_file_ja_JP.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_file_ja_JP.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/messages/messages_file_ja_JP.rb	(revision 398)
@@ -0,0 +1,168 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+
+# File Messages for ja_JP
+class TECSMsg
+
+## generate.rb ##
+
+@@comment = {}
+
+# MSg.note
+@@comment[ :note ] = " * このファイルは tecsgen により自動生成されました
+ * このファイルを編集して使用することは、意図されていません
+"
+
+@@comment[ :preamble_note ] = "/* #[<PREAMBLE>]#
+ * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+ * tecsmerge によるマージに使用されます
+"
+
+@@comment[ :postamble_note ] = "/* #[<POSTAMBLE>]#
+ *   これより下に非受け口関数を書きます
+ * #[</POSTAMBLE>]#*/
+"
+
+@@comment[ :template_note ] = "/*
+ * このファイルは tecsgen によりテンプレートとして自動生成されました
+ * このファイルを編集して使用することが意図されていますが
+ * tecsgen の再実行により上書きされてしまうため、通常
+ *   gen/%s_templ.c => src/%s.c
+ * のように名前, フォルダを変更してから修正します
+ */
+"
+
+@@comment[ :inline_template_note ] = "/*
+ * このファイルは tecsgen によりテンプレートとして自動生成されました
+ * このファイルを編集して使用することが意図されていますが
+ * tecsgen の再実行により上書きされてしまうため、通常
+ *   gen/%s_inline_template.h => src/%s_inline.h
+ * のように名前, フォルダを変更してから修正します
+ */
+"
+
+@@comment[ :Makefile_note ] = "# このファイルは tecsgen により自動生成されました
+# Makefile.temp は gen の一つ上のディレクトリに移して使用します
+#  % mv Makefile.temp Makefile
+# 
+# clean のデフォルト動作は $(GEN_DIR)/Makefile.* を削除します
+#
+# このファイルは GNU make で gcc を用い POSIX 環境で動作するモジュールをビルドするのに適切なように生成されています
+# vpath, CFLAGS, OTHER_OBJS などを調整する必要があるかもしれません
+# 他の環境やターゲットの場合、このファイルを元に変更する必要があります
+
+"
+
+@@comment[ :oneway_ercd_note ] = "/* oneway の場合 E_OK しか返せません */"
+@@comment[ :ercd_note ] = "/* エラー処理コードをここに記述します */"
+
+@@comment[ :IMP_comment ] = "\n/* import_C により import されるヘッダ %s */\n"
+@@comment[ :MVAR_comment ] = "# 変数 %s\n"
+@@comment[ :MRUL_comment ] = "# ルール %s\n"
+@@comment[ :TCM_comment ] = "# テンプレートコードでメークしてみる場合 %s \n"
+@@comment[ :MDEP_comment ] = "\n# depend を include %s\n"
+@@comment[ :SDI_comment ] = "/* シグニチャディスクリプタ参照ヘッダ %s */\n"
+@@comment[ :SD_comment ] = "/* シグニチャディスクリプタ %s */\n"
+@@comment[ :SFT_comment ] = "/* シグニチャ関数テーブル %s */\n"
+@@comment[ :SDES_comment ] = "/* シグニチャディスクリプタ(動的結合用) %s */\n"
+# @@comment[ :IRTH_comment ] = "/* ランタイムヘッダ %s */\n"
+@@comment[ :UDF_comment ] = "/* inline のための undef %s */\n"
+@@comment[ :IGH_comment ] = "/* グローバルヘッダ %s */\n"
+@@comment[ :ISH_comment ] = "/* シグニチャヘッダ %s */\n"
+@@comment[ :ICT_comment ] = "/* 最適化のため参照するセルタイプの CB 型の定義を取込む %s */\n"
+@@comment[ :NIDB_comment ] = "ID のベース "
+@@comment[ :NCEL_comment ] = "セルの個数"
+@@comment[ :CVI_comment ] = "/* IDXの正当性チェックマクロ %s */\n"
+@@comment[ :CVIA_comment ] = "/* IDXの正当性チェックマクロ（短縮形） %s */\n"
+@@comment[ :NCPA_comment ] = "/* 呼び口配列の大きさを得るマクロ %s */\n"
+@@comment[ :NEPA_comment ] = "/* 受け口配列の大きさを得るマクロ %s */\n"
+@@comment[ :TOCP_comment ] = "/* optional 呼び口をテストするマクロ %s */\n"
+@@comment[ :TOCPA_comment ] = "/* optional 呼び口をテストするマクロ（短縮形） %s */\n"
+@@comment[ :GCB_comment ] = "\n/* セルCBを得るマクロ %s */\n"
+@@comment[ :GCBA_comment ] = "\n/* セルCBを得るマクロ(短縮形) %s */\n"
+@@comment[ :CCT_comment ] = "/* CELLCB 型(短縮形) %s */\n"
+@@comment[ :CTIXA_comment ] = "/* セルタイプのIDX型(短縮形) %s */\n"
+@@comment[ :AAM_comment ] = "\n/* 属性アクセスマクロ %s */\n"
+@@comment[ :VAM_comment ] = "\n/* var アクセスマクロ %s */\n"
+@@comment[ :AAMA_comment ] = "\n/* 属性アクセスマクロ(短縮形) %s */\n"
+@@comment[ :VAMA_comment ] = "\n/* var アクセスマクロ(短縮形) %s */\n"
+@@comment[ :CPM_comment ] = " /* 呼び口関数マクロ %s */\n"
+@@comment[ :CPMA_comment ] = "/* 呼び口関数マクロ（短縮形）%s */\n"
+@@comment[ :EPM_comment ] = "\n/* 受け口関数マクロ（短縮形） %s */\n"
+@@comment[ :CRD_comment ] = "/* ディスクリプタ参照関数 %s */\n"
+@@comment[ :CRDA_comment ] = "\n/* ディスクリプタ参照マクロ（短縮形） %s */\n"
+@@comment[ :SDF_comment ] = "/* ディスクリプタ設定関数 %s */\n"
+@@comment[ :SDMA_comment ] = "\n/* ディスクリプタ設定マクロ（短縮形） %s */\n"
+@@comment[ :CTIX_comment ] = "\n/* セルタイプのIDX型 %s */\n"
+@@comment[ :EPP_comment ] = "\n/* 受け口関数プロトタイプ宣言 %s */\n"
+@@comment[ :EPSP_comment ] = "\n/* 受け口スケルトン関数プロトタイプ宣言（VMT不要最適化により参照するもの） %s */\n"
+@@comment[ :INL_comment ] = "/* inline ヘッダの include %s */\n"
+@@comment[ :CIP_comment ] = "/* セル INIB 型宣言 %s */\n"
+@@comment[ :CCTPA_comment ] = "/* セル CB 型宣言 %s */\n"
+@@comment[ :CCDP_comment ] = "/* セル CB (ダミー)型宣言 %s */\n"
+@@comment[ :CCTPO_comment ] = "/* セル CB 型宣言 %s */\n"
+@@comment[ :SCP_comment ] = "/* シングルトンセル CB プロトタイプ宣言 %s */\n"
+@@comment[ :DCI_comment ] = "\n/* CB は存在しない。INIB を CB の代わりに使用するための define %s */\n"
+@@comment[ :FEC_comment ] = "/* イテレータコード (FOREACH_CELL)の生成 %s */\n"
+@@comment[ :DAL_comment ] = "/* deallocate マクロ %s */\n"
+@@comment[ :NFEC_comment ] = "/* イテレータコード (FOREACH_CELL)の生成(CB,INIB は存在しない) %s */\n"
+@@comment[ :CIM_comment ] = "/* CB 初期化マクロ %s */\n"
+@@comment[ :EDT_comment ] = "/* 受け口ディスクリプタ型 %s */\n"
+@@comment[ :EPSF_comment ] = "/* 受け口スケルトン関数 %s */\n"
+@@comment[ :EPSFT_comment ] = "/* 受け口スケルトン関数テーブル %s */\n"
+@@comment[ :CPEPD_comment ] = "/* 呼び口の参照する受け口ディスクリプタ(実際の型と相違した定義) %s */\n"
+@@comment[ :CPA_comment ] = "/* 呼び口配列 %s */\n"
+@@comment[ :CIC_comment ] = "/* CB 初期化コード %s */\n"
+@@comment[ :AVAI_comment ] = "/* 属性・変数の配列 %s */\n"
+@@comment[ :AVI_comment ] = "/* 変数(構造体、配列)初期値 %s */\n"
+@@comment[ :INIB_comment ] = "/* セル INIB %s */\n"
+@@comment[ :CB_comment ] = "/* セル CB %s */\n"
+@@comment[ :EPD_comment ] = "/* 受け口ディスクリプタ %s */\n"
+@@comment[ :PAC_comment ] = "/* プロトタイプ宣言や変数の定義をここに書きます %s */\n"
+@@comment[ :CAAM_comment ] = " *\n * 属性アクセスマクロ %s\n"
+@@comment[ :CAAMI_comment ] = " *\n * 属性アクセスマクロ %s\n"
+@@comment[ :TYP_comment ] = " *\n * 型 %s\n * CELLCB 型  : %s\n * CELLIDX 型 : %s\n"
+@@comment[ :TCPF_comment ] = " * 呼び口関数 %s\n"
+@@comment[ :TEPF_comment ] = "/* 受け口関数 %s */\n"
+@@comment[ :TEFB_comment ] = "\t/* ここに処理本体を記述します %s */\n"
+@@comment[ :MCPP_comment ] = "/* CB プロトタイプ宣言 %s */\n"
+@@comment[ :MCPB_comment ] = "/* CB プロトタイプ宣言 %s */\n"
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1AlarmPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1AlarmPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1AlarmPlugin.rb	(revision 398)
@@ -0,0 +1,200 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator Cell-type plugin
+#      for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project TECS-WG
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+class ATK1AlarmPlugin < CelltypePlugin
+#@celltype:: Celltype
+#@option:: String     :オプション文字列
+
+  #signature::     Celltype        シグニチャ（インスタンス）
+  def initialize( celltype, option )
+    super
+  end
+
+  #===  CDL ファイルの生成
+  #      typedef, signature, celltype, cell のコードを生成
+  #      重複して生成してはならない
+  #      すでに生成されている場合は出力しないこと。
+  #      もしくは同名の import により、重複を避けること。
+  #file::        FILE       生成するファイル
+#  def gen_cdl_file file
+#  end
+
+  def new_cell cell
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     このメソッドが未定義の場合、ジェネレータは受け口関数のテンプレートを生成する
+  #     このメソッドが定義済みの場合、（テンプレートではなく、変更する必要のない）セルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+#  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+#  end
+
+  def gen_factory file
+
+  file2 = CFile.open( "#{$gen}/ALARM_tecsgen.oil", "w" )
+
+    # ALARM
+    @celltype.get_cell_list.each { |cell|
+
+    if cell.is_generate?
+
+      file2.print "\tALARM #{cell.get_name} {\n"
+
+      # COUNTER
+      join = cell.get_join_list.get_item( :counter )
+      if join then
+        str = join.get_rhs.to_s.gsub(/^"(.*)"$/, '\1')
+        file2.print "\t\tCOUNTER = #{str};\n"
+      end
+
+      # ACTION
+      join = cell.get_join_list.get_item( :action )
+      if join then
+        str = join.get_rhs.to_s.gsub(/^"(.*)"$/, '\1')
+      end
+
+      case str
+      when "SETEVENT"
+        file2.print "\t\tACTION = #{str} {\n"
+        join2 = cell.get_join_list.get_item( :task )
+        if join2 then
+          str = join2.get_rhs.to_s.gsub(/^"(.*)"$/, '\1')
+          file2.print "\t\t\tTASK = #{str};\n"
+        end
+        join2 = cell.get_join_list.get_item( :event )
+        if join2 then
+          str = join2.get_rhs.to_s.gsub(/^"(.*)"$/, '\1')
+          file2.print "\t\t\tEVENT = #{str};\n"
+        end
+        file2.print "\t\t};\n"
+      when "ACTIVATETASK"
+        file2.print "\t\tACTION = #{str} {\n"
+        join2 = cell.get_join_list.get_item( :task )
+        if join2 then
+          str = join2.get_rhs.to_s.gsub(/^"(.*)"$/, '\1')
+          file2.print "\t\t\tTASK = #{str};\n"
+        end
+        file2.print "\t\t};\n"
+      when "ALARMCALLBACK"
+        file2.print "\t\tACTION = #{str} {\n"
+        join2 = cell.get_join_list.get_item( :callbackName )
+        if join2 then
+          str = join2.get_rhs.to_s
+          file2.print "\t\t\tALARMCALLBACKNAME = #{str};\n"
+        end
+        file2.print "\t\t};\n"
+      else
+      end
+
+      # AUTOSTART
+      join = cell.get_join_list.get_item( :autoStart )
+      if join then
+        str = join.get_rhs.to_s
+      end
+
+      if str == "TRUE" then
+        file2.print "\t\tAUTOSTART = TRUE {\n"
+        join2 = cell.get_join_list.get_item( :alarmTime )
+        if join2 then
+        str = join2.get_rhs.to_s
+        file2.print "\t\t\tALARMTIME = #{str};\n"
+        end
+        join2 = cell.get_join_list.get_item( :cycleTime )
+        if join2 then
+          str = join2.get_rhs.to_s
+          file2.print "\t\t\tCYCLETIME = #{str};\n"
+        end
+        join2 = cell.get_join_list.get_item( :appMode )
+        delim = ""
+        if join2 then
+          join2.get_rhs.each { |mode|
+            str = mode.to_s.gsub(/^"(.*)"$/, '\1')
+            file2.print "\t\t\tAPPMODE = #{str};\n"
+            delim = ";"
+          }
+        end
+        file2.print "\t\t};\n"
+      else
+        file2.print "\t\tAUTOSTART = FALSE;\n"
+      end
+
+      file2.print "\t};\n"
+      file2.print "\n"
+
+    end
+  }
+
+  file2.close
+
+  # 追記するために AppFile を使う（文字コード変換されない）
+  file = AppFile.open( "#{$gen}/tAlarm_tecsgen.#{$c_suffix}" )
+  file.print "\n/* Generated by ATK1AlarmPlugin */\n"
+  @celltype.get_cell_list.each { |cell|
+    if cell.is_generate?
+      name_array = @celltype.get_name_array( cell )
+      join2 = cell.get_join_list.get_item( :callbackName )
+      if join2 then
+        str = join2.get_rhs.to_s.gsub(/^"(.*)"$/, '\1')
+        file.print <<EOT
+ALARMCALLBACK( #{str} );
+ALARMCALLBACK( #{str} )
+{
+    CELLCB *p_cellcb = #{name_array[8]};
+    cBody_main();
+}
+
+EOT
+      end
+    end
+  }
+
+  file.close
+
+  end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1DelayTaskPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1DelayTaskPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1DelayTaskPlugin.rb	(revision 398)
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator Cell-type plugin
+#      for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project TECS-WG
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+class ATK1DelayTaskPlugin < CelltypePlugin
+#@celltype:: Celltype
+#@option:: String     :オプション文字列
+
+  #signature::     Celltype        シグニチャ（インスタンス）
+  def initialize( celltype, option )
+    super
+  end
+
+  #===  CDL ファイルの生成
+  #      typedef, signature, celltype, cell のコードを生成
+  #      重複して生成してはならない
+  #      すでに生成されている場合は出力しないこと。
+  #      もしくは同名の import により、重複を避けること。
+  #file::        FILE       生成するファイル
+#  def gen_cdl_file file
+#  end
+
+  def new_cell cell
+#    join_list = cell.get_join_list
+#    a = join_list.get_item( :resource )
+#    if a == nil
+#     Generator.error( "resource: must be initialized")
+#    elsif ! a.get_rhs.instance_of? Array
+#      Generator.error( "resource: initializer must be in format of '{val1, val2 ...}'")
+#    end
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     このメソッドが未定義の場合、ジェネレータは受け口関数のテンプレートを生成する
+  #     このメソッドが定義済みの場合、（テンプレートではなく、変更する必要のない）セルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+#  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+#  end
+
+  def gen_factory file
+
+    # 追記するために AppFile を使う（文字コード変換されない）
+    file2 = AppFile.open( "#{$gen}/tDelayTaskBody_factory.#{$h_suffix}" )
+    file2.print "\n/* Generated by ATK1DelayTaskPlugin */\n\n"
+    @celltype.get_cell_list.each { |cell|
+      if cell.is_generate?
+        name_array = @celltype.get_name_array( cell )
+
+        join = cell.get_join_list.get_item( :event )
+        if join then
+          str = join.get_rhs.to_s
+          if str =~ /&(.*)/ then
+              str = $1
+          end
+
+          file2.print "DeclareEvent( #{str} );\n"
+        end
+
+      end
+    }
+
+    file2.close
+
+  end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1EventPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1EventPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1EventPlugin.rb	(revision 398)
@@ -0,0 +1,154 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator Cell-type plugin
+#      for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project TECS-WG
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id
+#++
+
+#== ATK1 Event celltype プラグインクラス
+class ATK1EventPlugin < CelltypePlugin
+#@@instancies:: []     :セル実体群
+@@instancies = []
+
+  #===  初期化
+  #      全てのセルの実体を意味解析後に参照する必要があるために
+  #      初期化時に singleton の instancies に格納する
+  #signature::     Celltype        シグニチャ（インスタンス）
+  def initialize( celltype, option )
+    super
+    @@instancies << self
+  end
+
+  #===  cellの生成
+  def new_cell cell
+  end
+
+  #===  意味解析実行後のコード生成
+  def self.gen_post_code file
+
+    @@instancies.each { |inst|
+      inst.gen_oil_code file
+    }
+
+  end
+
+  #===  OILファイル出力
+  def gen_oil_code file
+
+    file2 = CFile.open( "#{$gen}/EVENT_tecsgen.oil", "w" )
+
+    whole_mask = 0
+
+    # EVENT
+    @celltype.get_cell_list.each { |cell|
+
+#      if cell.is_generate?
+        join = cell.get_join_list.get_item( :mask )
+
+        # AUTO type search and change to zero
+        if join then
+          #mask_bit = join.get_rhs.to_s.eval_cnst( nil )
+          mask_bit = join.get_rhs.to_s.to_i
+          mask_str = join.get_rhs.to_s
+          if mask_str == "AUTO" then
+            new_rhs = Expression.create_integer_constant( 32, @locale )
+            join.change_rhs new_rhs
+          else
+            mask_pattern = 1 << mask_bit
+            whole_mask |= mask_pattern
+          end
+        else
+          new_rhs = Expression.create_integer_constant( 32, @locale )
+          join = Join.new( :mask, nil, new_rhs )
+          cell.new_join(join)
+        end
+
+#        file2.print "\t /* working #{join.get_rhs.to_s} */\n"
+#      end
+
+    }
+
+    mask_count = 0;
+    mask_place = 0;
+
+    @celltype.get_cell_list.each { |cell|
+
+#      if cell.is_generate?
+        # bit place to mask pattern
+        file2.print "\tEVENT #{cell.get_name} {\n"
+        join = cell.get_join_list.get_item( :mask )
+        if join then
+          mask_bit = join.get_rhs.to_s.to_i
+          if mask_bit == 32 then
+            while 1
+    p("mask_count, current_mask")
+    p mask_count
+              current_mask = (1 << mask_count)
+    p current_mask
+              if 0 == whole_mask & current_mask
+                new_rhs = Expression.create_integer_constant( current_mask, @locale )
+                join.change_rhs new_rhs
+                whole_mask = whole_mask | current_mask
+                mask_place = mask_count
+                break
+              end
+              if current_mask >= 0x8000
+                mask_place = 0
+                break
+              end
+              mask_count = mask_count + 1
+            end
+          else
+            mask_place = join.get_rhs.to_s.to_i
+            current_mask = 1 << mask_place
+            new_rhs = Expression.create_integer_constant( current_mask, @locale )
+            join.change_rhs new_rhs
+          end
+          file2.print "\t\tMASK = #{mask_place.to_s};\n"
+        end
+
+        file2.print "\t};\n"
+        file2.print "\n"
+
+#      end
+
+    }
+
+    file2.close
+
+  end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1ISRPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1ISRPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1ISRPlugin.rb	(revision 398)
@@ -0,0 +1,178 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator Cell-type plugin
+#      for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project TECS-WG
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+class ATK1ISRPlugin < CelltypePlugin
+#@celltype:: Celltype
+#@option:: String     :オプション文字列
+
+  #signature::     Celltype        シグニチャ（インスタンス）
+  def initialize( celltype, option )
+    super
+  end
+
+  #===  CDL ファイルの生成
+  #      typedef, signature, celltype, cell のコードを生成
+  #      重複して生成してはならない
+  #      すでに生成されている場合は出力しないこと。
+  #      もしくは同名の import により、重複を避けること。
+  #file::        FILE       生成するファイル
+#  def gen_cdl_file file
+#  end
+
+  def new_cell cell
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     このメソッドが未定義の場合、ジェネレータは受け口関数のテンプレートを生成する
+  #     このメソッドが定義済みの場合、（テンプレートではなく、変更する必要のない）セルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+#  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+#  end
+
+  def gen_factory file
+
+  file2 = CFile.open( "#{$gen}/ISR_tecsgen.oil", "w" )
+
+    # ISR
+    @celltype.get_cell_list.each { |cell|
+
+    if cell.is_generate?
+
+      file2.print "\tISR #{cell.get_name} {\n"
+
+      # CATEGORY
+      join = cell.get_join_list.get_item( :category )
+      if join then
+        file2.print "\t\tCATEGORY = #{join.get_rhs.to_s};\n"
+      end
+
+      # PRIORITY
+      join = cell.get_join_list.get_item( :priority )
+      if join then
+        file2.print "\t\tPRIORITY = #{join.get_rhs.to_s};\n"
+      end
+
+      # ENTRY (entryはtecsgenの予約語のためNumberを付加)
+      join = cell.get_join_list.get_item( :entryNumber )
+      if join then
+        file2.print "\t\tENTRY = #{join.get_rhs.to_s};\n"
+      end
+
+      # RESOURCE
+      join2 = cell.get_join_list.get_item( :resource )
+      delim = ""
+      if join2 then
+        join2.get_rhs.each { |res|
+          str = res.to_s.gsub(/^"(.*)"$/, '\1')
+          file2.print "\t\tRESOURCE = #{str};\n"
+          delim = ";"
+        }
+      end
+
+      # MESSAGE
+      join2 = cell.get_join_list.get_item( :message )
+      delim = ""
+      if join2 then
+        join2.get_rhs.each { |msg|
+          str = msg.to_s.gsub(/^"(.*)"$/, '\1')
+          file2.print "\t\tMESSAGE = #{str};\n"
+          delim = ";"
+        }
+      end
+
+      file2.print "\t};\n"
+      file2.print "\n"
+
+    end
+  }
+
+  file2.close
+
+  # 追記するために AppFile を使う（文字コード変換されない）
+  file = AppFile.open( "#{$gen}/tISR_tecsgen.#{$c_suffix}" )
+  file.print "\n/* Generated by ATK1ISRPlugin */\n"
+  @celltype.get_cell_list.each { |cell|
+    if cell.is_generate?
+      name_array = @celltype.get_name_array( cell )
+      join2 = cell.get_join_list.get_item( :category )
+      if join2 then
+        str = join2.get_rhs.to_s
+        if str == "1" then
+          file.print <<EOT
+#if defined( OMIT_ISR1_ENTRY )
+EOT
+          file.print "/* ISR1入り口未生成時は本関数を割込み関数指定する  */\n"
+          file.print <<EOT
+#pragma INTERRUPT  #{cell.get_name}
+#endif  /* OMIT_ISR1_ENTRY  */
+void  RxHwSerialInt( void );
+void
+RxHwSerialInt( void )
+EOT
+        else
+          file.print <<EOT
+ISR(#{cell.get_name})
+EOT
+        end
+      end
+
+      file.print <<EOT
+{
+    CELLCB *p_cellcb = #{name_array[8]};
+    cBody_main();
+}
+
+EOT
+    end
+  }
+
+  file.close
+
+  end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1KernelPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1KernelPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1KernelPlugin.rb	(revision 398)
@@ -0,0 +1,294 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator Cell-type plugin
+#      for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project TECS-WG
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+class ATK1KernelPlugin < CelltypePlugin
+#@celltype:: Celltype
+#@option:: String     :オプション文字列
+  @@cell_list = []
+
+  #signature::     Celltype        シグニチャ（インスタンス）
+  def initialize( celltype, option )
+    super
+  end
+
+  #===  CDL ファイルの生成
+  #      typedef, signature, celltype, cell のコードを生成
+  #      重複して生成してはならない
+  #      すでに生成されている場合は出力しないこと。
+  #      もしくは同名の import により、重複を避けること。
+  #file::        FILE       生成するファイル
+#  def gen_cdl_file file
+#  end
+
+  def new_cell cell
+#    join_list = cell.get_join_list
+#    a = join_list.get_item( :resource )
+#    if a == nil
+#     Generator.error( "resource: must be initialized")
+#    elsif ! a.get_rhs.instance_of? Array
+#      Generator.error( "resource: initializer must be in format of '{val1, val2 ...}'")
+#    end
+  @@cell_list << cell
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     このメソッドが未定義の場合、ジェネレータは受け口関数のテンプレートを生成する
+  #     このメソッドが定義済みの場合、（テンプレートではなく、変更する必要のない）セルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+#  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+#  end
+
+  def gen_factory file
+
+    file2 = CFile.open( "#{$gen}/Kernel_tecsgen.oil", "w" )
+
+    # Kernel
+    @celltype.get_cell_list.each { |cell|
+
+      if cell.is_generate?
+
+        file2.print "\tOS #{cell.get_name} {\n"
+
+        # STATUS
+        join = cell.get_join_list.get_item( :status )
+        if join then
+          str = join.get_rhs.to_s.gsub(/^"(.*)"$/, '\1')
+          file2.print "\t\tSTATUS = #{str};\n"
+        end
+
+        # STARTUPHOOK
+        join = cell.get_join_list.get_item( :useStartupHook )
+        if join then
+          str = join.get_rhs.to_s
+          file2.print "\t\tSTARTUPHOOK = #{str};\n"
+        end
+
+        # ERRORHOOK
+        join = cell.get_join_list.get_item( :useErrorHook )
+        if join then
+          str = join.get_rhs.to_s
+          file2.print "\t\tERRORHOOK = #{str};\n"
+        end
+
+        # SHUTDOWNHOOK
+        join = cell.get_join_list.get_item( :useShutdownHook )
+        if join then
+          str = join.get_rhs.to_s
+          file2.print "\t\tSHUTDOWNHOOK = #{str};\n"
+        end
+
+        # PRETASKHOOK
+        join = cell.get_join_list.get_item( :usePreTaskHook )
+        if join then
+          str = join.get_rhs.to_s
+          file2.print "\t\tPRETASKHOOK = #{str};\n"
+        end
+
+        # POSTASKHOOK
+        join = cell.get_join_list.get_item( :usePostTaskHook )
+        if join then
+          str = join.get_rhs.to_s
+          file2.print "\t\tPOSTTASKHOOK = #{str};\n"
+        end
+
+        # USEGETSERVICEID
+        join = cell.get_join_list.get_item( :useGetServiceId )
+        if join then
+          str = join.get_rhs.to_s
+          file2.print "\t\tUSEGETSERVICEID = #{str};\n"
+        end
+
+        # USEPARAMETERACCESS
+        join = cell.get_join_list.get_item( :useParameterAccess )
+        if join then
+          str = join.get_rhs.to_s
+          file2.print "\t\tUSEPARAMETERACCESS = #{str};\n"
+        end
+
+        # USERESSCHEDULER
+        join = cell.get_join_list.get_item( :useResourceScheduler )
+        if join then
+          str = join.get_rhs.to_s
+          file2.print "\t\tUSERESSCHEDULER = #{str};\n"
+        end
+
+        file2.print "\t};\n\n"
+
+      end
+
+    }
+
+    file2.close
+
+    # 追記するために AppFile を使う（文字コード変換されない）
+    file2 = AppFile.open( "#{$gen}/tKernel_tecsgen.#{$c_suffix}" )
+    file2.print "\n/* Generated by ATK1KernelPlugin */\n\n"
+    @celltype.get_cell_list.each { |cell|
+      if cell.is_generate?
+        name_array = @celltype.get_name_array( cell )
+
+        join = cell.get_join_list.get_item( :useStartupHook )
+        if join then
+          str = join.get_rhs.to_s
+          if str == "TRUE" then
+            file2.print <<EOT
+#ifdef USE_STARTUPHOOK
+void StartupHook(void)
+{
+/*    CELLCB *p_cellcb = #{name_array[8]}; */
+    INT32 i;
+    for(i = 0; i < N_CP_cStartupHookBody; i++){
+        cStartupHookBody_main(i);
+    }
+}
+#endif /* USE_STARTUPHOOK */
+EOT
+          end
+        end
+
+        join = cell.get_join_list.get_item( :useErrorHook )
+        if join then
+          str = join.get_rhs.to_s
+          if str == "TRUE" then
+            file2.print <<EOT
+#ifdef USE_ERRORHOOK
+void ErrorHook(StatusType ercd)
+{
+/*    CELLCB *p_cellcb = #{name_array[8]}; */
+    cErrorHookBody_main( ercd );
+}
+#endif /* USE_ERRORHOOK */
+
+EOT
+          end
+        end
+
+        join = cell.get_join_list.get_item( :useShutdownHook )
+        if join then
+          str = join.get_rhs.to_s
+          if str == "TRUE" then
+            file2.print <<EOT
+#ifdef USE_SHUTDOWNHOOK
+void ShutdownHook(StatusType ercd)
+{
+/*    CELLCB *p_cellcb = #{name_array[8]}; */
+    INT32 i;
+    for(i = 0; i < N_CP_cShutdownHookBody; i++){
+        cShutdownHookBody_main( i, ercd );
+    }
+}
+#endif /* USE_SHUTDOWNHOOK */
+
+EOT
+          end
+        end
+
+        join = cell.get_join_list.get_item( :usePreTaskHook )
+        if join then
+          str = join.get_rhs.to_s
+          if str == "TRUE" then
+            file2.print <<EOT
+#ifdef USE_PRETASKHOOK
+void PreTaskHook(void)
+{
+/*    CELLCB *p_cellcb = #{name_array[8]}; */
+    cPreTaskHookBody_main();
+}
+#endif /* USE_PRETASKHOOK */
+
+EOT
+          end
+        end
+
+        join = cell.get_join_list.get_item( :usePostTaskHook )
+        if join then
+          str = join.get_rhs.to_s
+          if str == "TRUE" then
+            file2.print <<EOT
+#ifdef USE_POSTTASKHOOK
+void PostTaskHook(void)
+{
+/*    CELLCB *p_cellcb = #{name_array[8]}; */
+    cPostTaskHookBody_main();
+}
+#endif /* USE_POSTTASKHOOK */
+
+EOT
+          end
+        end
+
+      end
+    }
+
+    file2.close
+
+  end
+
+  def self.gen_post_code file
+
+  @@cell_list.each { |cell|
+    join =  cell.get_join_list.get_item( :useResourceScheduler )
+    if join then
+      flag = join.get_rhs.to_s
+      if flag == "TRUE" then
+        file.print <<EOT
+cell tResource RES_SCHEDULER {
+	property = "STANDARD";
+};
+EOT
+      else
+        file.print <<EOT
+EOT
+      end
+    end
+  }
+  
+  end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1ResourcePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1ResourcePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1ResourcePlugin.rb	(revision 398)
@@ -0,0 +1,128 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator Cell-type plugin
+#      for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project TECS-WG
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+class ATK1ResourcePlugin < CelltypePlugin
+#@celltype:: Celltype
+#@option:: String     :オプション文字列
+
+  #signature::     Celltype        シグニチャ（インスタンス）
+  def initialize( celltype, option )
+    super
+  end
+
+  #===  CDL ファイルの生成
+  #      typedef, signature, celltype, cell のコードを生成
+  #      重複して生成してはならない
+  #      すでに生成されている場合は出力しないこと。
+  #      もしくは同名の import により、重複を避けること。
+  #file::        FILE       生成するファイル
+#  def gen_cdl_file file
+#  end
+
+  def new_cell cell
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     このメソッドが未定義の場合、ジェネレータは受け口関数のテンプレートを生成する
+  #     このメソッドが定義済みの場合、（テンプレートではなく、変更する必要のない）セルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+#  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+#  end
+
+  def gen_factory file
+
+  file2 = CFile.open( "#{$gen}/RESOURCE_tecsgen.oil", "w" )
+  file3 = CFile.open( "#{$gen}/#{@celltype.get_name}_factory.#{$h_suffix}", "w" )
+
+  # RESOURCE
+  @celltype.get_cell_list.each { |cell|
+
+    if cell.is_generate?
+
+      str = cell.get_name
+
+      if str.to_s == "RES_SCHEDULER" then
+
+        cell.set_specified_id( 1 )
+
+      else
+
+        file3.print "DeclareResource( #{cell.get_name} );\n"
+
+        file2.print "\tRESOURCE #{cell.get_name} {\n"
+
+        # PROPERTY
+        join = cell.get_join_list.get_item( :property )
+        if join then
+          str = join.get_rhs.to_s.gsub(/^"(.*)"$/, '\1')
+
+          if str == "LINKED" then
+            file2.print "\t\tRESOURCEPROPERTY = #{str} {\n"
+            join2 = cell.get_join_list.get_item( :linkedResource )
+            str2 = join2.get_rhs.to_s.gsub(/^"(.*)"$/, '\1')
+            file2.print "\t\t\tLINKEDRESOURCE = #{str2};\n"
+            file2.print "\t\t};\n"
+          else
+            file2.print "\t\tRESOURCEPROPERTY = #{str};\n"
+          end
+        end
+
+        file2.print "\t};\n"
+        file2.print "\n"
+
+      end
+
+    end
+  }
+
+  file2.close
+  file3.close
+
+  end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1TaskPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1TaskPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ATK1TaskPlugin.rb	(revision 398)
@@ -0,0 +1,225 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator Cell-type plugin
+#      for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project TECS-WG
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+class ATK1TaskPlugin < CelltypePlugin
+#@celltype:: Celltype
+#@option:: String     :オプション文字列
+
+  #signature::     Celltype        シグニチャ（インスタンス）
+  def initialize( celltype, option )
+    super
+  end
+
+  #===  CDL ファイルの生成
+  #      typedef, signature, celltype, cell のコードを生成
+  #      重複して生成してはならない
+  #      すでに生成されている場合は出力しないこと。
+  #      もしくは同名の import により、重複を避けること。
+  #file::        FILE       生成するファイル
+#  def gen_cdl_file file
+#  end
+
+  def new_cell cell
+#    join_list = cell.get_join_list
+#    a = join_list.get_item( :resource )
+#    if a == nil
+#     Generator.error( "resource: must be initialized")
+#    elsif ! a.get_rhs.instance_of? Array
+#      Generator.error( "resource: initializer must be in format of '{val1, val2 ...}'")
+#    end
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     このメソッドが未定義の場合、ジェネレータは受け口関数のテンプレートを生成する
+  #     このメソッドが定義済みの場合、（テンプレートではなく、変更する必要のない）セルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+#  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+#  end
+
+  def gen_factory file
+
+  file2 = CFile.open( "#{$gen}/TASK_tecsgen.oil", "w" )
+
+  extended_task_count = 1
+
+  # TASK
+  @celltype.get_cell_list.each { |cell|
+
+    if cell.is_generate?
+
+      file2.print "\tTASK #{cell.get_name} {\n"
+
+      # AUTOSTART
+      join = cell.get_join_list.get_item( :autoStart )
+      if join then
+        str = join.get_rhs.to_s
+
+        if str == "TRUE" then
+          join2 = cell.get_join_list.get_item( :appMode )
+          if join2 then
+            file2.print "\t\tAUTOSTART = TRUE {\n"
+            delim = ""
+            join2.get_rhs.each { |mode|
+              str = mode.to_s.gsub(/^"(.*)"$/, '\1')
+              file2.print "\t\t\tAPPMODE = #{str};\n"
+              delim = ";"
+            }
+            file2.print "\t\t};\n"
+          else
+            file2.print "\t\tAUTOSTART = TRUE;\n"
+          end
+        elsif str == "FALSE" then
+          file2.print "\t\tAUTOSTART = FALSE;\n"
+        else
+        end
+      end
+
+      # PRIORITY
+      join = cell.get_join_list.get_item( :priority )
+      if join then
+        file2.print "\t\tPRIORITY = #{join.get_rhs.to_s};\n"
+      end
+
+      # ACTIVATION
+      join = cell.get_join_list.get_item( :activation )
+      if join then
+        file2.print "\t\tACTIVATION = #{join.get_rhs.to_s};\n"
+      end
+
+      # SCHEDULE
+      join = cell.get_join_list.get_item( :schedule )
+      if join then
+        str = join.get_rhs.to_s.gsub(/^"(.*)"$/, '\1')
+        file2.print "\t\tSCHEDULE = #{str};\n"
+      end
+
+      # EVENT
+      join = cell.get_join_list.get_item( :event )
+      delim = ""
+      if join then
+        join.get_rhs.each { |evt|
+          str = evt.to_s.gsub(/^"(.*)"$/, '\1')
+          if !(str == "OMISSIBLE")
+              file2.print "\t\tEVENT = #{str};\n"
+          end
+          delim = ";"
+        }
+        join.get_rhs.each { |evt|
+          str = evt.to_s.gsub(/^"(.*)"$/, '\1')
+          if !(str == "OMISSIBLE")
+              cell.set_specified_id( extended_task_count );
+              ++extended_task_count;
+              break
+          end
+        }
+      end
+
+      # RESOURCE
+      join = cell.get_join_list.get_item( :resource )
+      delim = ""
+      if join then
+        join.get_rhs.each { |res|
+          str = res.to_s.gsub(/^"(.*)"$/, '\1')
+          if !(str == "OMISSIBLE")
+              file2.print "\t\tRESOURCE = #{str};\n"
+          end
+          delim = ";"
+        }
+      end
+
+      # MESSAGE
+      join = cell.get_join_list.get_item( :message )
+      delim = ""
+      if join then
+        join.get_rhs.each { |msg|
+          str = msg.to_s.gsub(/^"(.*)"$/, '\1')
+          if !(str == "OMISSIBLE")
+              file2.print "\t\tMESSAGE = #{str};\n"
+          end
+          delim = ";"
+        }
+      end
+
+      # STACKSIZE
+      join = cell.get_join_list.get_item( :stackSize )
+      if join then
+        file2.print "\t\tSTACKSIZE = #{join.get_rhs.to_s};\n"
+      end
+
+      file2.print "\t};\n"
+      file2.print "\n"
+
+    end
+  }
+
+  file2.close
+
+  # 追記するために AppFile を使う（文字コード変換されない）
+  file = AppFile.open( "#{$gen}/tTask_tecsgen.#{$c_suffix}" )
+  file.print "\n/* Generated by ATK1TaskPlugin */\n"
+  @celltype.get_cell_list.each { |cell|
+    if cell.is_generate?
+      name_array = @celltype.get_name_array( cell )
+      file.print <<EOT
+TASK(#{cell.get_name})
+{
+    CELLCB *p_cellcb = #{name_array[8]};
+    cBody_main();
+    terminate();
+}
+
+EOT
+    end
+  }
+
+  file.close
+
+  end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/C2TECSBridgePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/C2TECSBridgePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/C2TECSBridgePlugin.rb	(revision 398)
@@ -0,0 +1,214 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2015 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== C => TECS 受け口呼び出しのプラグイン
+class C2TECSBridgePlugin < SignaturePlugin
+#@signature:: Signature   プラグインの対象となるシグニチャ
+#@option:: String   '"', '"' で囲まれた文字列
+
+  # プラグイン引数名と Proc
+  C2TECSBridgePluginArgProc = {
+    "prefix" => Proc.new { |obj,rhs| obj.set_prefix rhs },
+    "suffix" => Proc.new { |obj,rhs| obj.set_suffix rhs },
+    "header_name" => Proc.new { |obj,rhs| obj.set_header_name rhs },
+  }
+
+
+  @@signature_list = { }
+
+  #signature::     Signature        シグニチャ（インスタンス）
+  def initialize( signature, option )
+    super
+
+    @signature = signature
+    @header_name = "#{$gen}/C2TECS_#{@signature.get_global_name}.h"
+    @prefix = ""
+    @suffix = ""
+    @celltype_name = :"t#{@signature.get_global_name}"
+    @plugin_arg_check_proc_tab = C2TECSBridgePluginArgProc
+    parse_plugin_arg
+  end
+
+  def gen_cdl_file file
+    if @@signature_list[ @signature.get_global_name ] then
+      @@signature_list[ @signature.get_global_name ] << self
+      cdl_warning( "C2TW001 signature '$1' duplicate. ignored current one", @signature.get_namespace_path )
+      return
+    end
+
+    @@signature_list[ @signature.get_global_name ] = [ self ]
+    print_msg "  C2TECSBridgePlugin: [celltype] C2TECS::#{@celltype_name}. Create cell then join the call port 'cCall' to the target cell\n"
+    file.print <<EOT
+namespace nC2TECS{
+  [singleton, active]    // this celltype is not active actually. 'active' is specified to prevent W1002.
+  celltype #{@celltype_name} {
+    call #{@signature.get_namespace_path} cCall;
+  };
+};
+EOT
+  end
+
+  #=== 後ろのコードを生成
+  #プラグインの後ろのコードを生成
+  #file:: File: 
+  def self.gen_post_code( file )
+    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+    # file.print "/* '#{self.class.name}' post code */\n"
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     通常であれば、ジェネレータは受け口関数のテンプレートを生成する
+  #     プラグインの場合、変更する必要のないセルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    # nothing to do
+
+  end
+
+
+  def gen_postamble( file, b_singleton, ct_name, global_name )
+
+    header_file = open( @header_name, "w" )
+
+    header_comment =<<EOT
+/*
+ * This file was generated by C2TECSBridgePlugin and has prototype
+ * decalarations of functions in signature '#{@signature.get_namespace_path}'
+ */
+
+EOT
+
+    file.print header_comment
+    header_file.print header_comment
+    header_file.print <<EOT
+#ifndef #{@signature.get_global_name}__h
+#define #{@signature.get_global_name}__h
+
+/*
+ * function prototype declarations
+ *    signature: '#{@signature.get_namespace_path}'
+ *
+ * These functions can be called from C sources directly.
+ * If function name collides, please consider to specify 'prefix' option for C2TECSBridgePlugin.
+ */
+EOT
+
+    # generate C functions calling function of call port
+    @signature.get_function_head_array.each { |func_head|
+      func_name = func_head.get_name
+      ret_type  = func_head.get_return_type
+      params    = func_head.get_paramlist.get_items
+
+      # p "celltype_name, sig_name, func_name, func_global_name"
+      # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
+
+      # function header
+      file.print( "#{ret_type.get_type_str}\n" )
+      header_file.printf( "%-16s", ret_type.get_type_str )
+      file.print( "#{@prefix}#{func_name}#{@suffix}(" )
+      header_file.print( "#{@prefix}#{func_name}#{@suffix}(" )
+
+      delim = ""
+      params.each{ |param|
+        file.printf( "#{delim} #{param.get_type.get_type_str} #{param.get_name}#{param.get_type.get_type_str_post}" )
+        header_file.printf( "#{delim} #{param.get_type.get_type_str} #{param.get_name}#{param.get_type.get_type_str_post}" )
+        delim = ","
+      }
+      file.print( " )\n{\n" )
+      header_file.print( " );\n" )
+
+      # call function in call port
+      if ! ret_type.is_void? then
+        file.print( "  #{ret_type.get_type_str}  retval;\n" )
+        file.print( "  retval = " )
+      else
+        file.print( "  " )
+      end
+
+      file.print( "cCall_#{func_name}(" )
+
+      delim = ""
+      params.each{ |param|
+        file.printf( "#{delim} #{param.get_name}" )
+        delim = ","
+      }
+      file.print( " );\n" )
+
+      if ! ret_type.is_void? then
+        file.print( "  return retval;\n" )
+      end
+      file.print( "}\n\n" )
+    }
+
+    header_file.print <<EOT
+
+#endif /* #{@signature.get_global_name}__h */
+
+EOT
+    
+    header_file.close
+  end
+
+  #===  set_prefix - prefix プラグインオプション
+  def set_prefix rhs
+    @prefix = rhs.to_s
+  end
+  #===  set_suffix - suffix プラグインオプション
+  def set_suffix rhs
+    @suffix = rhs.to_s
+  end
+  #===  set_header_name - header_name プラグインオプション
+  def set_header_name rhs
+    @header_name = "#{$gen}/" + rhs.to_s
+    if ! ( @header_name =~ /\.h\Z/ ) then
+      @header_name += ".h"
+    end
+  end
+  
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/CellPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/CellPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/CellPlugin.rb	(revision 398)
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2011 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+class CellPlugin < Plugin
+
+  #=== CellPlugin# initialize
+  #cell::     Cell        セル（インスタンス）
+  # このメソッドは、セルの構文解析が終わったところで呼び出される
+  # この段階では意味解析が終わっていない
+  def initialize( cell, option )
+    super()
+    @cell = cell
+    @plugin_arg_str = CDLString.remove_dquote option
+    # @plugin_arg_str = option.gsub( /\A"(.*)/, '\1' )    # 前後の "" を取り除く
+    # @plugin_arg_str.sub!( /(.*)"\z/, '\1' )
+    @plugin_arg_list = {}
+  end
+
+  #=== 後ろの CDL コードを生成
+  #プラグインの後ろの CDL コードを生成
+  #file:: File: 
+  def self.gen_post_code( file )
+    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+    # file.print "/* '#{self.class.name}' post code */\n"
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/CelltypePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/CelltypePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/CelltypePlugin.rb	(revision 398)
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+class CelltypePlugin < Plugin
+
+  #celltype::     Celltype        セルタイプ（インスタンス）
+  def initialize( celltype, option )
+    super()
+    @celltype = celltype
+    # @plugin_arg_str = option.gsub( /\A"(.*)/, '\1' )    # 前後の "" を取り除く
+    # @plugin_arg_str.sub!( /(.*)"\z/, '\1' )
+    @plugin_arg_str = CDLString.remove_dquote option
+    @plugin_arg_list = {}
+  end
+
+  #=== 新しいセル
+  #cell::        Cell            セル
+  #
+  # celltype プラグインを指定されたセルタイプのセルが生成された
+  # セルタイププラグインに対する新しいセルの報告
+  def new_cell( cell )
+  end
+
+
+  #=== tCelltype_factory.h に挿入するコードを生成する
+  # file 以外の他のファイルにファクトリコードを生成してもよい
+  # セルタイププラグインが指定されたセルタイプのみ呼び出される
+  def gen_factory file
+  end
+
+  #=== 後ろの CDL コードを生成
+  #プラグインの後ろの CDL コードを生成
+  #file:: File: 
+  def self.gen_post_code( file )
+    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+    # file.print "/* '#{self.class.name}' post code */\n"
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/CompositePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/CompositePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/CompositePlugin.rb	(revision 398)
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== CompositeCelltype プラグインの共通の親クラス
+class CompositePlugin < Plugin
+
+  #celltype::     CompositeCelltype        セルタイプ（インスタンス）
+  def initialize( celltype, option )
+    super()
+    @celltype = celltype
+    # @plugin_arg_str = option.gsub( /\A"(.*)/, '\1' )    # 前後の "" を取り除く
+    # @plugin_arg_str.sub!( /(.*)"\z/, '\1' )
+    @plugin_arg_str = CDLString.remove_dquote option
+    @plugin_arg_list = {}
+  end
+
+  #=== 新しいセル
+  #cell::        Cell            セル
+  #
+  # celltype プラグインを指定されたセルタイプのセルが生成された
+  # セルタイププラグインに対する新しいセルの報告
+  def new_cell( cell )
+  end
+
+  #=== 後ろの CDL コードを生成
+  #プラグインの後ろの CDL コードを生成
+  #file:: File: 
+  def self.gen_post_code( file )
+    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+    # file.print "/* '#{self.class.name}' post code */\n"
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/DomainPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/DomainPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/DomainPlugin.rb	(revision 398)
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== ドメインプラグインの親クラス
+class DomainPlugin < Plugin
+
+  #== domain 指定されたリージョンが定義された
+  # region で domain 指定があった
+  #domain_type_name::Symbol : domain 指定子の第一引数
+  #option::String : domain 指定子の第二引数
+  def initialize( region, domain_type_name, option )
+    super()
+  end
+
+  #== 結合 join にプラグインを挿入する
+  #join::Join : 結合に関する情報
+  #return::[ plugin_name::String, option::String ]: 挿入するプラグイン。 挿入するものがなければ nil を返す
+  #return::(1) [ plugin_name, option ] or (2) [[ plugin_name, option ], ...], or [] or nil:  (2): not supported now
+  #   nil: region 間の結合禁止, []: region 間の結合可(プラグイン挿入無し)
+  #   [ plugin_name, option ]: *_through( plugin_name, option ) 指定したのと同等
+  #
+  # region 間の through が指定されている場合、out_through, to_through
+  # では、それらによって指定されたプラグインの後ろに、in_through の場合
+  # in_through プラグインの前に挿入される
+  #
+  # このメソッドが呼出された時点では Join#get_rhs_cell など意味解析後
+  # にしか呼び出せないメソッドを呼出しても、有効な値は得られない
+  #
+  def add_through_plugin( join, current_region, next_region, through_type )
+    # join.get_owner:Cell  左辺のセル
+    # join.get_definition:Port 呼び口
+    # join.get_subscript:Integer or nil 呼び口配列の添数 (Join::@subscript の説明参照)
+    # join.get_cell:Cell 右辺のセル
+    # join.get_port_name:Symbol 受け口
+    # get_rhs_subscript:Integer or nil 受け口配列の添数 (Join::@rhs_subscript の説明参照)
+    # return []
+    return nil
+  end
+
+  #== require が結合可能か？
+  def joinable?(current_region, next_region, through_type )
+    return false
+  end
+
+  #== ドメイン種別を返す
+  #return::Symbol :kernel, :user, :OutOfDomain
+  def get_kind
+    :kernel
+  end
+
+  #== factory 生成
+  # DomainPlugin の factory は特定のファイルへの出力が想定されていない
+  def gen_factory
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2AlarmHandlerPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2AlarmHandlerPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2AlarmHandlerPlugin.rb	(revision 398)
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2012 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#
+#   $Id$
+#  
+#++
+
+#require "HRP2KernelObjectPlugin"
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+#== celltype プラグインの共通の親クラス
+class HRP2AlarmHandlerPlugin < HRP2KernelObjectPlugin
+    @@ep = [:eStartAlarm, :eStopAlarm, :eManageAlarm, :eReferAlarm ]
+    ##
+    #
+    # file : output file (ex.tecsgen.cfg)
+    # cell : 
+    # val  : 
+    # tab  : 
+    def print_cfg_cre(file, cell, val, tab)
+        val[:id] = val[:id].gsub( /(^|[^\$])\$id\$/, "\\1#{@celltype.get_name.to_s}_#{cell.get_name.to_s}" )
+        # $cbp$  #983
+        name_array = @celltype.get_name_array cell
+        cell_CBP = name_array[8]    # CBP
+        # CRE_XXXの生成
+        if (cell.get_region.get_region_type != :DOMAIN) || (cell.get_region.get_param != :KERNEL_DOMAIN)
+            # 無所属 or ユーザドメインに属する場合
+                raise "alarm handler #{val[:id]} must belong to kernel domain."
+        else
+            file.print <<EOT
+#{tab}CRE_ALM(#{val[:id]}, { #{val[:attribute]}, #{cell_CBP}, tAlarmHandler_start });
+EOT
+        end
+    end
+
+    def print_cfg_sac(file, val, acv)
+       file.puts "SAC_ALM(#{val[:id]}, { #{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]} });"
+    end
+
+    #tAlarmの受け口リスト 
+    def get_entry_ports_name_list()
+        @@ep
+    end
+    
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2Cache.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2Cache.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2Cache.rb	(revision 398)
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+
+#   $Id$
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2CyclicHandlerPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2CyclicHandlerPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2CyclicHandlerPlugin.rb	(revision 398)
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#require "HRP2KernelObjectPlugin"
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+
+#== celltype プラグインの共通の親クラス
+class HRP2CyclicHandlerPlugin < HRP2KernelObjectPlugin
+    @@ep = [:eStartCyclic, :eStopCyclic, :eManageCyclic, :eReferCyclic ]
+    ##
+    #
+    # file : output file (ex.tecsgen.cfg)
+    # cell : 
+    # val  : 
+    # tab  : 
+    def print_cfg_cre(file, cell, val, tab)
+        val[:id] = val[:id].gsub( /(^|[^\$])\$id\$/, "\\1#{@celltype.get_name.to_s}_#{cell.get_name.to_s}" )
+        # $cbp$  #983
+        name_array = @celltype.get_name_array cell
+        cell_CBP = name_array[8]    # CBP
+        # CRE_XXXの生成
+        if (cell.get_region.get_region_type != :DOMAIN) || (cell.get_region.get_param != :KERNEL_DOMAIN)
+            # 無所属 or ユーザドメインに属する場合
+                raise "cyclic handler #{val[:id]} must belong to kernel domain."
+        else
+            file.print <<EOT
+#{tab}CRE_CYC(#{val[:id]}, { #{val[:attribute]}, #{cell_CBP}, tCyclicHandler_start, #{val[:cyclicTime]}, #{val[:cyclicPhase]} });
+EOT
+        end
+    end
+
+    def print_cfg_sac(file, val, acv)
+       file.puts "SAC_CYC(#{val[:id]}, { #{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]} });"
+    end
+
+    #tCyclicHandlerの受け口リスト 
+    def get_entry_ports_name_list()
+        @@ep
+    end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2DataqueuePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2DataqueuePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2DataqueuePlugin.rb	(revision 398)
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#require "HRP2KernelObjectPlugin"
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+
+
+class HRP2DataqueuePlugin < HRP2KernelObjectPlugin
+    @@ep = [:eSendDataqueue, :eReceiveDataqueue, :eManageDataqueue, :eReferDataqueue ]
+    #=== HRP2DataqueuePlugin#print_cfg_cre
+    # CRE_DTQの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # tab :: string:   インデント用のtab
+    def print_cfg_cre(file, cell, val, tab)
+        file.print tab
+        file.puts "CRE_DTQ(#{val[:id]}, {#{val[:attribute]}, #{val[:count]}, #{val[:dtqmb]}});"
+    end
+    #=== HRP2DataqueuePlugin#print_cfg_sac
+    # SAC_DTQの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # acv :: string:   アクセスベクタ    
+    def print_cfg_sac(file, val, acv)
+        file.puts "SAC_DTQ(#{val[:id]}, {#{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]}});"
+    end
+    #tDataqueueの受け口リスト 
+    def get_entry_ports_name_list()
+        @@ep
+    end
+end
+
+
+  
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2EventflagPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2EventflagPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2EventflagPlugin.rb	(revision 398)
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#require "HRP2KernelObjectPlugin"
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+
+
+class HRP2EventflagPlugin < HRP2KernelObjectPlugin
+    @@ep = [:eSetEventflag, :eWaitEventflag, :eManageEventflag, :eReferEventflag ]
+    #=== HRP2EventflagPlugin#print_cfg_cre
+    # CRE_FLGの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # tab :: string:   インデント用のtab
+    def print_cfg_cre(file, cell, val, tab)
+        file.print tab
+        file.puts "CRE_FLG(#{val[:id]}, {#{val[:attribute]}, #{val[:flagPattern]}});"
+    end
+    #=== HRP2EventflagPlugin#print_cfg_sac
+    # SAC_FLGの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # acv :: string:   アクセスベクタ    
+    def print_cfg_sac(file, val, acv)
+        file.puts "SAC_FLG(#{val[:id]}, {#{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]}});"
+    end
+    #tEventflagの受け口リスト 
+    def get_entry_ports_name_list()
+        @@ep
+    end
+end
+
+
+  
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2FixedSizeMemoryPoolPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2FixedSizeMemoryPoolPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2FixedSizeMemoryPoolPlugin.rb	(revision 398)
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#require "HRP2KernelObjectPlugin"
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+
+
+class HRP2FixedSizeMemoryPoolPlugin < HRP2KernelObjectPlugin
+    @@ep = [:eSendFixedSizeMemoryPool, :eReceiveFixedSizeMemoryPool, :eManageFixedSizeMemoryPool, :eReferFixedSizeMemoryPool ]
+    #=== HRP2FixedSizeMemoryPoolPlugin#print_cfg_cre
+    # CRE_MPFの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # tab :: string:   インデント用のtab
+    def print_cfg_cre(file, cell, val, tab)
+        file.print tab
+        file.puts "CRE_MPF(#{val[:id]}, {#{val[:attribute]}, #{val[:blockCount]}, #{val[:blockSize]}, #{val[:mpf]}, #{val[:mpfmb]}});"
+    end
+    #=== HRP2FixedSizeMemoryPoolPlugin#print_cfg_sac
+    # SAC_MPFの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # acv :: string:   アクセスベクタ    
+    def print_cfg_sac(file, val, acv)
+        file.puts "SAC_MPF(#{val[:id]}, {#{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]}});"
+    end
+    #tFixedSizeMemoryPoolの受け口リスト 
+    def get_entry_ports_name_list()
+        @@ep
+    end
+end
+
+
+  
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2HandlerPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2HandlerPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2HandlerPlugin.rb	(revision 398)
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#require "HRP2KernelObjectPlugin"
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+
+#== celltype プラグインの共通の親クラス
+class HRP2HandlerPlugin < HRP2KernelObjectPlugin
+    @@ep = [:eStartAlarm, :eStopAlarm, :eManageAlarm, :eReferAlarm ]
+    ##
+    #
+    # file : output file (ex.tecsgen.cfg)
+    # cell : 
+    # val  : 
+    # tab  : 
+    def print_cfg_cre(file, cell, val, tab)
+        if !val[:id].nil?
+            val[:id] = val[:id].gsub( /(^|[^\$])\$id\$/, "\\1#{@celltype.get_name.to_s}_#{cell.get_name.to_s}" )
+        end
+        # $cbp$  #983
+        name_array = @celltype.get_name_array cell
+        cell_CBP = name_array[8]    # CBP
+        # CRE_XXXの生成
+        domainOption = cell.get_region.get_domain_root.get_domain_type.get_option
+        # if (cell.get_region.get_region_type != :DOMAIN) || (cell.get_region.get_param != :KERNEL_DOMAIN)
+        if (domainOption == "OutOfDomain") || (domainOption != "trusted")
+            # 無所属 or ユーザドメインに属する場合
+                raise "#{@plugin_arg_str.to_s.downcase} handler #{val[:id]} must belong to kernel domain."
+        elsif @plugin_arg_str == "ALARM"
+            file.print <<EOT
+#{tab}CRE_ALM(#{val[:id]}, { #{val[:attribute]}, #{cell_CBP}, tAlarmHandler_start });
+EOT
+        elsif @plugin_arg_str == "CYCLIC"
+            file.print <<EOT
+#{tab}CRE_CYC(#{val[:id]}, { #{val[:attribute]}, #{cell_CBP}, tCyclicHandler_start, #{val[:cyclicTime]}, #{val[:cyclicPhase]} });
+EOT
+        elsif @plugin_arg_str == "CONFIG_INT"
+            file.print <<EOT
+#{tab}CFG_INT( #{val[:interruptNumber]}, { #{val[:attribute]}, #{val[:interruptPriority]} });
+EOT
+        elsif @plugin_arg_str == "ISR"
+            file.print <<EOT
+#{tab}ATT_ISR({ #{val[:attribute]}, #{cell_CBP}, #{val[:interruptNumber]}, tISR_start, #{val[:priority]} });
+EOT
+        elsif @plugin_arg_str == "INIT_ROUTINE"
+            file.print <<EOT
+#{tab}ATT_INI({ #{val[:attribute]}, #{cell_CBP}, tInitializeRoutine_start });
+EOT
+        elsif @plugin_arg_str == "TERM_ROUTINE"
+            file.print <<EOT
+#{tab}ATT_TER({ #{val[:attribute]}, #{cell_CBP}, tTerminateRoutine_start });
+EOT
+        else
+            raise "#{@plugin_arg_str} is unknown option"
+        end
+    end
+
+    def print_cfg_sac(file, val, acv)
+        if @plugin_arg_str == "ALARM"
+            file.puts "SAC_ALM(#{val[:id]}, { #{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]} });"
+        elsif @plugin_arg_str == "CYCLIC"
+            file.puts "SAC_CYC(#{val[:id]}, { #{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]} });"
+        elsif @plugin_arg_str == "CONFIG_INT"
+            # nothing to do
+        elsif @plugin_arg_str == "ISR"
+            # nothing to do
+        elsif @plugin_arg_str == "INIT_ROUTINE"
+            # nothing to do
+        elsif @plugin_arg_str == "TERM_ROUTINE"
+            # nothing to do
+        else
+            raise "#{@plugin_arg_str} is unknown option"
+        end
+    end
+
+=begin
+    #tAlarmの受け口リスト 
+    def get_entry_ports_name_list()
+        @@ep
+    end
+=end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2KernelObjectPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2KernelObjectPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2KernelObjectPlugin.rb	(revision 398)
@@ -0,0 +1,375 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# Regionクラスにメソッドを追加
+=begin
+class Region
+    def get_params
+        return @region_type_param
+    end
+
+    def get_param
+        return @region_type_param[0]
+    end
+
+    def is_root
+        return self == @@root_namespace
+    end
+end
+=end
+
+# Cellクラスにインスタンス変数とメソッドを追加
+=begin
+class Cell
+    def set_referenced_region( region )
+        if @referenced_regions.nil?
+            @referenced_regions = Array.new
+        end
+        if !@referenced_regions.include?(region)
+            @referenced_regions << region
+        end
+    end
+
+    def get_referenced_regions
+        return @referenced_regions
+    end
+
+    # set_referenced_cellにしたほうがよい
+    # def set_referenced_region( region, port_name )
+    def set_referenced_cell( cell, port_name )
+        if @referenced_cells.nil?
+            @referenced_cells = Hash.new
+        end
+        if !@referenced_cells.include?(port_name)
+            @referenced_cells[port_name] = Array.new
+        end
+        if !@referenced_cells[port_name].include?(cell)
+            @referenced_cells[port_name] << cell
+        end
+
+        region = cell.get_region
+        puts "***** set_referenced_regions *****"
+        puts "region=#{region.get_name}, port=#{port_name}(#{port_name.class})"
+        if @referenced_regions.nil?
+            @referenced_regions = Hash.new
+        end
+        if !@referenced_regions.include?(port_name)
+            @referenced_regions[port_name] = Array.new
+        end
+        if !@referenced_regions[port_name].include?(region)
+            @referenced_regions[port_name] << region
+        end
+        puts "#{@referenced_regions[port_name]}"
+    end
+
+    def get_referenced_cells( port_name )
+        if !@referenced_cells.nil? && @referenced_cells.include?(port_name)
+            return @referenced_cells[port_name]
+        else
+            return nil
+        end
+    end
+
+    def get_referenced_regions( port_name )
+        if !@referenced_regions.nil? && @referenced_regions.include?(port_name)
+            return @referenced_regions[port_name]
+        else
+            return nil
+        end
+    end
+
+    def self.get_cell_list
+        return @@cell_list
+    end
+
+    def self.get_cell_list2
+        return @@cell_list2
+    end
+end
+=end
+
+#== celltype プラグインの共通の親クラス
+class HRP2KernelObjectPlugin < CelltypePlugin
+    # @@obj_hash = {}
+
+    #@celltype:: Celltype
+    #@option:: String     :オプション文字列
+    def initialize( celltype, option )
+        super
+        # それぞれのカーネルオブジェクトを解析対象セルタイプに追加
+        HRP2KernelObjectPlugin.set_celltype(celltype)
+    end
+  
+    #=== HRP2KernelObjectPlugin#print_cfg_cre
+    # 各種カーネルオブジェクトのCRE_*の出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # tab :: string:   インデント用のtab
+    def print_cfg_cre(file, cell, val, tab)
+        raise "called virtual method print_cfg_cre in #{@celltype.get_name} plugin"
+    end
+  
+    #=== HRP2KernelObjectPlugin#print_cfg_sac
+    # 各種カーネルオブジェクトのSAC_*の出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # acv :: string:   アクセスベクタ
+    def print_cfg_sac(file, val, acv)
+        raise "called virtual method print_cfg_sac in #{@celltype.get_name} plugin"
+    end
+  
+    #=== HRP2KernelObjectPlugin#get_entry_ports_name_list
+    # カーネルオブジェクトの各種アクセスの種別の受け口名を取得
+    def get_entry_ports_name_list()
+        raise "called virtual method get_entry_ports_name_list in #{@celltype.get_name} plugin"
+    end
+
+    def string_cfg_cre(cell, val)
+        raise "called virtual method string_cfg_cre in #{@celltype.get_name} plugin"
+    end
+
+    def gen_factory file
+        puts "===== begin #{@celltype.get_name.to_s} plugin ====="
+
+        # 対象となるすべてのセルについて、受け口に結合されている
+        # セルの所属ドメインを解析
+        if !HRP2KernelObjectPlugin.isChecked()
+            HRP2KernelObjectPlugin.check_referenced_cells()
+        else
+            puts "***** already checked"
+        end
+
+        # 追記するために AppFile を使う（文字コード変換されない）
+        file2 = AppFile.open( "#{$gen}/tecsgen.cfg" )
+        file2.print "\n/* Generated by #{self.class.name} */\n\n"
+
+        @celltype.get_cell_list.each { |cell|
+            if cell.is_generate?
+                puts "===== begin check my domain #{cell.get_name} ====="
+                # attrの値をハッシュに入れる
+                val = {}
+                @celltype.get_attribute_list.each{ |a|
+                    # p a.get_name
+                    if a.get_type.kind_of?( ArrayType )
+                        val[a.get_name] = []
+                        if j = cell.get_join_list.get_item(a.get_name)
+                            # セル生成時に初期化する場合
+                            j.get_rhs.each { |elem|
+                                val[a.get_name] << elem.to_s
+                            }
+                        elsif i = a.get_initializer
+                            # セルタイプの初期化値を使う場合
+                            i.each { |elem|
+                                val[a.get_name] << elem.to_s
+                            }
+                        else
+                            raise "attribute is not initialized"
+                        end
+                    else
+                        if j = cell.get_join_list.get_item(a.get_name)
+                            # セル生成時に初期化する場合
+                            val[a.get_name] = j.get_rhs.to_s
+                        elsif i = a.get_initializer
+                            # セルタイプの初期化値を使う場合
+                            val[a.get_name] = i.to_s
+                        else
+                            raise "attribute is not initialized"
+                        end
+                    end
+                }
+                # generate.rbを参考に
+                # $id$を置換
+                if val[:id].nil? != true
+                    puts val[:id]
+                    #val[:id] = val[:id].gsub( /(^|[^\$])\$id\$/, "\\1#{@celltype.get_name.to_s}_#{cell.get_name.to_s}" )
+                    val[:id] = @celltype.subst_name( val[:id], @celltype.get_name_array( cell ) )
+                end
+                # $cbp$の代わり
+                index = cell.get_id - @celltype.get_id_base
+                cell_CB_name = "#{@celltype.get_global_name}_CB_tab[#{index}]"
+                cell_domain_root = cell.get_region.get_domain_root
+                cell_domain_type = cell.get_region.get_domain_root.get_domain_type
+
+                # CRE_XXX/DEF_XXXの生成
+                if cell_domain_type.get_option.to_s != "OutOfDomain"
+                    # 保護ドメインに属する場合
+                    if !HRP2KernelObjectPlugin.include_region(cell_domain_root.get_name.to_s)
+                        # その保護ドメインの.cfgが生成されていない場合
+                        HRP2KernelObjectPlugin.set_region_list(cell_domain_root.get_name.to_s)
+                        puts "~~~~~ #{cell_domain_root.get_name.to_s} is registered!"
+
+                        # if cell.get_region.get_param == :KERNEL_DOMAIN
+                        if cell_domain_type.get_option.to_s == "trusted"
+                            # file2.print "#{cell.get_region.get_name.to_s}{\n"
+                            file2.print "KERNEL_DOMAIN{\n"
+                        else
+                            file2.print "DOMAIN(#{cell_domain_root.get_name.to_s}){\n"
+                        end
+                        file2.puts "\tINCLUDE(\"#{$gen}/tecsgen_#{cell_domain_root.get_name.to_s}.cfg\");" 
+                        file2.puts "}\n"
+                    else
+                        dbgPrint "~~~~~ #{cell.get_region.get_name.to_s} is included in"
+                        # p @@region_list
+                    end
+                    file3 = AppFile.open( "#{$gen}/tecsgen_#{cell_domain_root.get_name.to_s}.cfg" )
+                    print_cfg_cre(file3, cell, val,"")
+                    file3.close
+                else
+                    # 無所属の場合
+                    puts "~~~~~ #{cell_domain_root.get_name.to_s} is OutOfDomain"
+                    print_cfg_cre(file2, cell, val, "")
+                end
+
+                puts "===== end check my domain #{cell.get_name} ====="
+                # SAC_XXXの生成
+                if !val[:accessPattern].nil?
+                    puts "===== begin check regions #{cell.get_name} ====="
+                    # p val[:accessPattern]
+                    # p val[:accessPattern].class
+
+                    #ep = [ :eTaskActivate, :eTaskControl, :eTaskManage, :eTaskRefer ]
+                    #各カーネルオブジェクトの受け口名を取得
+                    # ep = get_entry_ports_name_list()
+                    i = 0
+                    acv = []
+                    # アクセス許可ベクタの生成
+                    val[:accessPattern].each { |acptnx|
+                        # アクセス許可パターンの生成
+                        if acptnx != "OMIT"
+                            acv << acptnx
+                            # p acv[i]
+                        elsif cell_domain_type.get_option.to_s == "trusted"
+                            acv << "TACP_KERNEL"
+                            # p acv[i]
+                        elsif cell_domain_type.get_option.to_s != "OutOfDomain"
+                            acv << "TACP(#{cell_domain_root.get_name.to_s})"
+                        else
+                            acv << "TACP_SHARED"
+                        end
+
+                        i += 1
+                    }
+
+                    dbgPrint "acv = "
+                    p acv
+
+                    #各種SACの生成
+                    domainOption = cell_domain_type.get_option
+                    # if cell.get_region.get_region_type == :DOMAIN
+                    if domainOption != "OutOfDomain"
+                        # 保護ドメインに属する場合
+                        file3 = AppFile.open( "#{$gen}/tecsgen_#{cell.get_region.get_name.to_s}.cfg" )
+                        print_cfg_sac(file3, val, acv)
+                        file3.close
+                    else
+                        # 無所属の場合
+                        print_cfg_sac(file2, val, acv)
+                    end
+
+                    puts "===== end check regions #{cell.get_name} ====="
+                end
+            end
+        }
+
+        puts "===== end #{@celltype.get_name.to_s} plugin ====="
+        file2.close
+    end
+
+    # カーネルオブジェクトセルタイプの管理
+    # HRP2KernelObjectPluginクラスに対してメソッド呼出しを行うことを想定
+    @@checked = false
+    @@celltype_list = []
+    @@region_list = []
+
+    def self.isChecked()
+        return @@checked
+    end
+
+    def self.check_referenced_cells()
+        dbgPrint "===== begin check registered celltype =====\n"
+        self.get_celltype_list.each { |ct|
+            dbgPrint( ct.get_name.to_s + "\n" )
+        }
+        dbgPrint "===== end check registered celltype =====\n"
+
+=begin
+        Cell.get_cell_list2.each { |cell|
+            cell.get_celltype.get_port_list.each{ |p|
+                next if p.get_port_type != :CALL
+                j = cell.get_join_list.get_item(p.get_name)
+                printf "===== check call port : "
+                # p p.get_name.to_s
+                next if j.nil? # 未結合の場合
+                if @@celltype_list.include?(j.get_celltype)
+                    # j.get_cell.set_referenced_region(cell.get_region)
+                    # j.get_cell.set_referenced_region(cell.get_region, j.get_port_name)
+                    j.get_cell.set_referenced_cell(cell, j.get_port_name)
+                    printf "===== check joined rhs cell : "
+                    # p j.get_cell.get_name.to_s
+                    printf "===== check joined rhs port_name : "
+                    # p j.get_port_name
+                end
+            }
+        }
+=end
+        @@checked = true
+    end
+
+    def self.set_celltype( celltype )
+        @@celltype_list << celltype
+    end
+
+    def self.get_celltype_list
+        return @@celltype_list
+    end
+
+    def self.set_region_list( region )
+        @@region_list << region
+    end
+
+    def self.include_region( region )
+        return @@region_list.include?(region)
+    end
+
+    def self.include_celltype?( celltype )
+        return @@celltype_list.include?(celltype)
+    end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2ObjectPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2ObjectPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2ObjectPlugin.rb	(revision 398)
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#require "HRP2KernelObjectPlugin"
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+
+
+class HRP2ObjectPlugin < HRP2KernelObjectPlugin
+    # @@ep = [:eSignalSemaphore, :eWaitSemaphore, :eManageSemaphore, :eReferSemaphore ]
+    @@api = {
+        "SEMAPHORE"=>["SEM", :id, :attribute, :count, :max],
+        "EVENTFLAG"=>["FLG", :id, :attribute, :flagPattern],
+        "DATAQUEUE"=>["DTQ", :id, :attribute, :count, :dtqmb],
+        "PRIORITY_DATAQUEUE"=>["PDQ", :id, :attribute, :count, :maxDataPriority, :pdqmb],
+        "FIXED_SIZE_MEMORYPOOL"=>["MPF", :id, :attribute, :blockCount, :blockSize, :mpf, :mpfmb],
+        "KERNEL"=>["SYS"],
+        "MESSAGE_BUFFER"=>["MBF", :id, :attribute, :maxSize, :bufferSize, :mbfmb],
+    }
+
+    #=== HRP2SemaphorePlugin#print_cfg_cre
+    # CRE_SEMの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # tab :: string:   インデント用のtab
+    def print_cfg_cre(file, cell, val, tab)
+        if @@api.has_key?(@plugin_arg_str) == false
+            raise "#{@plugin_arg_str} is unknown"
+        elsif @plugin_arg_str != "KERNEL"
+            arg_list = []
+            @@api[@plugin_arg_str].slice(2..-1).each { |attr|
+                arg_list << "#{val[attr]}"
+            }
+            file.print tab
+            file.puts "CRE_#{@@api[@plugin_arg_str].at(0)}(#{val[:id]}, { #{arg_list.join(", ")} });"
+        end
+    end
+    #=== HRP2SemaphorePlugin#print_cfg_sac
+    # SAC_SEMの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # acv :: string:   アクセスベクタ    
+    def print_cfg_sac(file, val, acv)
+        if @@api.has_key?(@plugin_arg_str) == false
+            raise "#{@plugin_arg_str} is unknown"
+        elsif @plugin_arg_str != "KERNEL"
+            file.puts "SAC_#{@@api[@plugin_arg_str].at(0)}(#{val[:id]}, { #{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3] }});"
+        else
+            file.puts "SAC_#{@@api[@plugin_arg_str].at(0)}({ #{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]} });"
+        end
+    end
+
+=begin
+    #tSemaphoreの受け口リスト 
+    def get_entry_ports_name_list()
+        @@ep
+    end
+=end
+end
+
+
+  
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2Plugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2Plugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2Plugin.rb	(revision 398)
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#
+# 各メソッドの役割りは、DomainPlugin.rb を参照のこと
+# HRP2カーネル用ドメインプラグイン
+class HRP2Plugin < DomainPlugin
+
+  def initialize( region, name, option )
+    super
+    print "HRP2Plugin: initialize: region=#{region.get_name}, domainName=#{name}, option=#{option}\n"
+    @region = region
+    @name   = name
+
+    case option
+    when "trusted", "nontrusted", "OutOfDomain"
+      # OK
+      @option = option
+    else
+      cdl_error( "HRPPlugin: '$1' is unacceptable domain kind, specify 'trusted' or 'nontrusted'", option )
+      @option = "trusted"   # とりあえず trusted を設定しておく
+    end
+  end
+
+  def add_through_plugin( join, current_region, next_region, through_type )
+    # join.get_owner:Cell  左辺のセル
+    # join.get_definition:Port 呼び口
+    # join.get_subscript:Integer or nil 呼び口配列の添数 (Join::@subscript の説明参照)
+    # join.get_cell:Cell 右辺のセル
+    # join.get_port_name:Symbol 受け口
+    # get_rhs_subscript:Integer or nil 受け口配列の添数 (Join::@rhs_subscript の説明参照)
+    # return []
+    print "HRP2Plugin: add_through_plugin: #{current_region.get_name}=>#{next_region.get_name}, #{join.get_owner.get_name}.#{join.get_definition.get_name}=>#{join.get_cell.get_name}.#{join.get_port_name}, #{through_type}\n"
+
+    puts "=====Join Check Start====="
+    puts "caller: #{join.get_owner.get_name.to_s}, callee: #{join.get_cell.get_name.to_s}"
+    puts "=====Join Check param====="
+    current_domain = current_region.get_domain_root.get_domain_type
+    next_domain = next_region.get_domain_root.get_domain_type
+    puts current_domain.get_option.to_s
+    if !next_domain.nil?
+        puts next_domain.get_option.to_s
+    else
+        puts "next domain is nil!"
+    end
+
+    if HRP2KernelObjectPlugin.include_celltype?(join.get_cell.get_celltype)
+        # 結合先がカーネルオブジェクトセル
+        # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
+        # 何もしないthrough
+        puts "***** #{join.get_cell.get_celltype.get_name} is kernel object"
+        return []
+        # return [ :HRP2SVCPlugin, "channelCelltype=tMessagebufferChannel,noClientSemaphore=true" ]
+    # elsif @end_region.is_root?
+    # elsif next_region.get_option == OutOfDomain
+    # elsif next_domain.nil?
+    elsif next_domain.get_option.to_s == "OutOfDomain"
+    #     # 結合先が無所属
+    #     # 何もしないthrough
+    #     # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
+        puts "***** nil"
+        return []
+        # return [ :HRP2SVCPlugin, "channelCelltype=tMessagebufferChannel,noClientSemaphore=true" ]
+    #elsif @start_region.get_param != :KERNEL_DOMAIN && @end_region.get_param == :KERNEL_DOMAIN
+    elsif current_domain.get_option.to_s != "trusted" && next_domain.get_option.to_s == "trusted"
+        # ユーザドメインからカーネルドメインへの結合
+        # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
+        puts "***** svc"
+        return [ :HRP2SVCPlugin, "" ]
+    elsif current_domain != next_domain
+        # ユーザドメインから別のユーザドメインへの結合
+        # @plugin_body = HRP2RPCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
+        puts "***** rpc"
+        return [ :HRP2RPCPlugin, "channelCelltype=tMessagebufferChannel,noClientSemaphore=true" ]
+    else
+        # その他
+        # 何もしないthrough
+        # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
+        print "warning: at HRP2 Join Check"
+        return nil
+    end
+
+    puts "=====Join Check End====="
+  end
+
+  #== ドメイン種別を返す
+  #return::Symbol :kernel, :user, :OutOfDomain
+  def get_kind
+    case @option
+    when "trusted"
+      return :kernel
+    when "nontrusted"
+      return :user
+    when "OutOfDomain"
+      return :OutOfDomain
+    end
+  end
+
+  def joinable?(current_region, next_region, through_type )
+    print "HRP2Plugin: joinable? from #{current_region.get_name} to #{next_region.get_name} (#{through_type})\n"
+    return true
+  end
+
+  def self.gen_post_code file
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2PostHook.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2PostHook.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2PostHook.rb	(revision 398)
@@ -0,0 +1,113 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#require "HRP2KernelObjectPlugin"
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+
+class HRP2PostHook
+    #@celltype:: Celltype
+    def initialize( celltype )
+        puts "new post hook #{celltype.get_name}"
+        @celltype = celltype
+    end
+
+    def generate
+        # カーネルオブジェクトのセルタイプはメモリ保護しない
+#=begin
+        # TODO: テストのために無効化
+        if HRP2KernelObjectPlugin.include_celltype?( @celltype )
+            puts "nothing is generated for kernel object component"
+            return
+        end
+#=end
+
+        rlist = @celltype.get_region_list
+        if @celltype.is_singleton?
+            # singletonの場合
+            puts "<singleton>"
+
+            if rlist.length == 0
+                file = AppFile.open( "#{$gen}/tecsgen.cfg" )
+            else
+                file = AppFile.open( "#{$gen}/tecsgen_#{rlist[0].get_param.to_s}.cfg" )
+            end
+            # セル管理ブロックとスケルトンのメモリ保護
+            file.print "ATT_MOD(\"#{@celltype.get_global_name}_tecsgen.o\");\n"
+            if !@celltype.is_all_entry_inline?
+                # セルタイプコードのメモリ保護
+                file.print "ATT_MOD(\"#{@celltype.get_global_name}.o\");\n"
+            end
+
+            file.close
+
+        else
+            # singletonでない場合
+            puts "<non-singleton>"
+
+            # スケルトンとセルタイプコードの保護
+            if (rlist.length == 1) && 
+                (@celltype.get_n_cell_gen == @celltype.get_n_cell_gen_r( rlist[0] ))
+                # 所属する保護ドメインが1つの場合
+                puts "<private celltype>"
+                file = AppFile.open( "#{$gen}/tecsgen_#{rlist[0].get_param.to_s}.cfg" )
+            else
+                # 無所属 or 所属する保護ドメインが複数の場合
+                puts "<shared celltype>"
+                file = AppFile.open( "#{$gen}/tecsgen.cfg" )
+            end
+
+            # スケルトンのメモリ保護
+            file.print "ATT_MOD(\"#{@celltype.get_global_name}_tecsgen.o\");\n"
+            if !@celltype.is_all_entry_inline?
+                # セルタイプコードのメモリ保護
+                file.print "ATT_MOD(\"#{@celltype.get_global_name}.o\");\n"
+            end
+            file.close
+
+            # セル管理ブロックの保護
+            rlist.each { |reg|
+                file = AppFile.open( "#{$gen}/tecsgen_#{reg.get_param.to_s}.cfg" )
+                file.print "ATT_MOD(\"#{@celltype.get_global_name}_#{reg.get_name.to_s}_tecsgen.o\");\n"
+                file.close
+            }
+
+        end
+    end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2PriorityDataqueuePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2PriorityDataqueuePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2PriorityDataqueuePlugin.rb	(revision 398)
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2012 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+
+class HRP2PriorityDataqueuePlugin < HRP2KernelObjectPlugin
+    @@ep = [:eSendPriorityDataqueue, :eReceivePriorityDataqueue, :eManagePriorityDataqueue, :eReferPriorityDataqueue ]
+    #=== HRP2PriorityDataqueuePlugin#print_cfg_cre
+    # CRE_PDQの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # tab :: string:   インデント用のtab
+    def print_cfg_cre(file, cell, val, tab)
+        file.print tab
+        file.puts "CRE_PDQ(#{val[:id]}, {#{val[:attribute]}, #{val[:count]}, #{val[:maxDataPriority]}, #{val[:pdqmb]}});"
+    end
+    #=== HRP2PriorityDataqueuePlugin#print_cfg_sac
+    # SAC_PDQの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # acv :: string:   アクセスベクタ    
+    def print_cfg_sac(file, val, acv)
+        file.puts "SAC_PDQ(#{val[:id]}, {#{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]}});"
+    end
+    #tPriorityDataqueueの受け口リスト 
+    def get_entry_ports_name_list()
+        @@ep
+    end
+end
+
+
+  
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2RPCPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2RPCPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2RPCPlugin.rb	(revision 398)
@@ -0,0 +1,327 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+require_tecsgen_lib "lib/GenHRP2Marshaler.rb"
+
+# require_tecsgen_lib "GenParamCopy.rb"
+
+#= Transparent RPC プラグイン
+# Transparent RPC チャンネルを生成する
+# プラグイン引数は以下の RPCPluginArgProc を参照
+
+# mikan through plugin: namespace が考慮されていない
+# これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必要がある
+# tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl
+
+# 以下を仮定（制限事項）
+#  呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
+#  有符号、無符号でサイズが同じ
+
+#
+# RPCを用いたドメイン間通信の
+# throughプラグイン
+# HRP2ドメインプラグインによって挿入される
+#
+class HRP2RPCPlugin < ThroughPlugin
+
+  include GenTransparentMarshaler
+  # include GenParamCopy
+
+  # RPCPlugin 専用のオプション
+  TransparentRPCPluginArgProc = RPCPluginArgProc.dup  # 複製を作って元を変更しないようにする
+  TransparentRPCPluginArgProc[ "noClientSemaphore"  ] = Proc.new { |obj,rhs| obj.set_noClientSemaphore rhs }
+  TransparentRPCPluginArgProc[ "semaphoreCelltype"  ] = Proc.new { |obj,rhs| obj.set_semaphoreCelltype rhs }
+
+  #=== RPCPlugin の initialize
+  #  説明は ThroughPlugin (plugin.rb) を参照
+  def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
+    super
+    @b_noClientSemaphore = false
+    @semaphoreCelltype = "tSemaphore"
+    initialize_transparent_marshaler cell_name
+
+    # オプション：GenTransparentMarshaler 参照
+    @plugin_arg_check_proc_tab = TransparentRPCPluginArgProc
+    parse_plugin_arg
+
+    @rpc_channel_celltype_name = "tRPCPlugin_#{@TDRCelltype}_#{@channelCelltype}_#{@signature.get_name}"
+    @rpc_channel_celltype_file_name = "#{$gen}/#{@rpc_channel_celltype_name}.cdl"
+
+    if @signature.need_PPAllocator? then
+      if @PPAllocatorSize == nil then
+        cdl_error( "PPAllocatorSize must be speicified for oneway [in] array" )
+        # @PPAllocatorSize = 0   # 仮に 0 としておく (cdl の構文エラーを避けるため)
+      end
+    end
+
+#    @signature.each_param{ |func_decl, param_decl|
+#      if func_decl.get_type.is_oneway? then
+#        if ( param_decl.get_size || param_decl.get_count ) && param_decl.get_string then
+#          cdl_error( "array of string not supported for oneway function in Transparent RPC" )  # mikan 文字列の配列
+#        elsif param_decl.get_string == -1 then
+#          cdl_error( "length unspecified string is not permited for oneway function in Transparent RPC" )  # mikan 長さ未指定文字列
+#        end
+#      end
+#    }
+  end
+
+  #=== plugin の宣言コード (celltype の定義) 生成
+  def gen_plugin_decl_code( file )
+
+    ct_name = "#{@ct_name}_#{@channelCelltype}"
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if @@generated_celltype[ ct_name ] == nil then
+      @@generated_celltype[ ct_name ] = [ self ]
+    else
+      @@generated_celltype[ ct_name ] << self
+      return
+    end
+
+    gen_marshaler_celltype
+
+    if @PPAllocatorSize then
+      alloc_cell = "  cell tPPAllocator PPAllocator {\n    heapSize = #{@PPAllocatorSize};\n  };\n"
+      alloc_call_port_join = "    cPPAllocator = PPAllocator.ePPAllocator;\n"
+    else
+      alloc_cell = ""
+      alloc_call_port_join = ""
+    end
+
+    if @b_noClientSemaphore == false then
+      semaphore1 = <<EOT
+  // Semaphore for Multi-task use ("specify noClientSemaphore" option to delete this)
+  cell #{@semaphoreCelltype} Semaphore {
+    count = 1;
+    attribute = C_EXP( "TA_NULL" );
+  };
+EOT
+      semaphore2 = "    cLockChannel = Semaphore.eSemaphore;\n"
+    else
+      semaphore1 = ""
+      semaphore2 = ""
+    end
+
+    f = CFile.open( @rpc_channel_celltype_file_name, "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    f.print <<EOT
+import( "#{@marshaler_celltype_file_name}" );
+
+composite #{@rpc_channel_celltype_name}Client {
+  /* Interface */
+  entry #{@signature.get_name} eThroughEntry;
+  //call sTDR       cTDR;
+  call sEventflag cEventflag;
+  call sSemaphore cSemaphore;
+  call sMessageBuffer cMessageBuffer;
+
+  /* Implementation */
+#{semaphore1}
+  cell #{@marshaler_celltype_name} #{@signature.get_name}_marshaler{
+    //cTDR         => composite.cTDR;
+    cEventflag   => composite.cEventflag;
+    cSemaphore   => composite.cSemaphore;
+    cMessageBuffer => composite.cMessageBuffer;
+#{semaphore2}  };
+  composite.eThroughEntry => #{@signature.get_name}_marshaler.eClientEntry;
+};
+
+[active]
+composite #{@rpc_channel_celltype_name}Server {
+  /* Interface */
+  attr {
+    PRI taskPriority;
+  };
+  call #{@signature.get_name} #{@call_port_name};
+  //call sTDR       cTDR;
+  call sEventflag cEventflag;
+  call sSemaphore cSemaphore;
+  call sMessageBuffer cMessageBuffer;
+
+  /* Implementation */
+#{alloc_cell}  cell #{@unmarshaler_celltype_name} #{@signature.get_name}_unmarshaler{
+    //cTDR        => composite.cTDR;
+    cEventflag  => composite.cEventflag;
+    cSemaphore  => composite.cSemaphore;
+    cMessageBuffer => composite.cMessageBuffer;
+    cServerCall => composite.#{@call_port_name};
+#{alloc_call_port_join}  };
+  cell tRPCDedicatedTaskMain RPCTaskMain{
+    cMain = #{@signature.get_name}_unmarshaler.eUnmarshalAndCallFunction;
+  };
+  cell tTask Task {
+    cBody     = RPCTaskMain.eMain;
+    priority  = taskPriority;
+    taskAttribute = C_EXP( "TA_ACT" );  /* mikan : marshaler starts at the beginning */
+    //stackSize     = 4096;
+    userStackSize     = 4096;
+  };
+};
+EOT
+    # mikan stackSize option & 最新 tecs_package 対応
+
+    f.close
+  end
+
+  #===  through cell コードを生成
+  #
+  #
+  def gen_through_cell_code( file )
+
+    gen_plugin_decl_code( file )
+
+    # セルを探す
+    # path =["::",@next_cell.get_name]
+    # cell = Namespace.find( path )
+    cell = Namespace.find( @next_cell.get_namespace_path )
+
+    file.print <<EOT
+import( "#{@rpc_channel_celltype_file_name}" );
+EOT
+
+    #nest = @end_region.gen_region_str_pre file
+    indent_str = ""
+
+    file.print <<EOT
+#{indent_str}// one way channel cell
+#{indent_str}cell #{@channelCelltype} #{@channelCellName} {
+#{indent_str}};
+
+#{indent_str}// RPC channel cell
+EOT
+
+    nest = @start_region.gen_region_str_pre file
+    indent_str = "  " * nest
+
+    # #473 が解決された場合、composite リレーアロケータに変更すべき
+    # アロケータの指定があるか？
+    if cell.get_allocator_list.length > 0 then
+
+      dbgPrint "make allocator\n"
+      file.print "#{indent_str}[allocator("
+
+      delim = ""
+      cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc|
+
+        file.print delim
+        delim = ",\n#{indent_str}           "        # 最終行には出さない
+
+        if subsc then        # 配列添数
+          subsc_str = '[#{subsc}]'
+        else
+          subsc_str = ""
+        end
+
+        eport = "eThroughEntry" #RPCの受け口名に変更
+        file.print  "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc}"
+      end
+
+      file.puts ")]"
+    end
+
+    file.print <<EOT
+#{indent_str}cell #{@rpc_channel_celltype_name}Client #{@cell_name} {
+#{indent_str}  //cTDR         = #{@channelCellName}.eTDR;
+#{indent_str}  cEventflag   = #{@channelCellName}.eEventflag;
+#{indent_str}  cSemaphore   = #{@channelCellName}.eSemaphore;
+#{indent_str}  cMessageBuffer   = #{@channelCellName}.eMessageBuffer;
+#{indent_str}};
+EOT
+
+    @start_region.gen_region_str_post file
+
+    nest = @end_region.gen_region_str_pre file
+    indent_str = "  " * nest
+    nest_str = "  " * nest
+    if @next_cell_port_subscript then
+      subscript = '[' + @next_cell_port_subscript.to_s + ']'
+    else
+      subscript = ""
+    end
+
+    file.print <<EOT
+#{indent_str}cell #{@rpc_channel_celltype_name}Server #{@cell_name}Body {
+#{indent_str}    #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
+//#{indent_str}    #{@call_port_name} = #{@next_cell.get_name}.#{@next_cell_port_name};
+#{indent_str}  //cTDR         = #{@channelCellName}.eTDR;
+#{indent_str}  cEventflag   = #{@channelCellName}.eEventflag;
+#{indent_str}  cSemaphore   = #{@channelCellName}.eSemaphore;
+#{indent_str}  cMessageBuffer  = #{@channelCellName}.eMessageBuffer;
+#{indent_str}  taskPriority = #{@task_priority};
+#{indent_str}};
+EOT
+
+    @end_region.gen_region_str_post file
+  end
+
+
+  #=== プラグイン引数 noClientSemaphore のチェック
+  def set_noClientSemaphore rhs
+    rhs = rhs.to_sym
+    if rhs == :true then
+      @b_noClientSemaphore = true
+    elsif rhs == :false then
+      @b_noClientSemaphore = false
+    else
+      cdl_error( "RPCPlugin: specify true or false for noClientSemaphore" )
+    end
+  end
+
+  #=== プラグイン引数 semaphoreCelltype のチェック
+  def set_semaphoreCelltype rhs
+    @semaphoreCelltype = rhs.to_sym
+    nsp = NamespacePath.analyze( @semaphoreCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: semaphoreCelltype '#{rhs}' not celltype or not defined" )
+    end
+  end
+
+  #=== NamespacePath を得る
+  # 生成するセルの namespace path を生成する
+  def get_cell_namespace_path
+#    nsp = @region.get_namespace.get_namespace_path
+    nsp = @start_region.get_namespace_path
+    return nsp.append( @cell_name )
+  end
+
+end
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2SVCPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2SVCPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2SVCPlugin.rb	(revision 398)
@@ -0,0 +1,474 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# mikan through plugin: namespace が考慮されていない
+# これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必要がある
+# tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl
+
+# 以下を仮定（制限事項）
+#  呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
+#  有符号、無符号でサイズが同じ
+
+class SVCManage
+    # TODO: デフォルトの拡張サービスコール分を予約しておく
+    # デフォルトの拡張サービスコール（syslogなど）もコンポーネント化するまで
+    @@id = 20
+    @@func_ids = {}
+    def self.get_func_id func_name
+        return @@func_ids[ func_name ]
+    end
+    def self.set_func_id func_name
+        @@func_ids[ func_name ] = self.assign_id
+        puts @@func_ids[ func_name ]
+    end
+    def self.include_func_id? func_name
+        return @@func_ids.has_key?( func_name )
+    end
+    def self.get_id
+        return @@id
+    end
+    def self.set_id id
+        @@id = id
+    end
+    def self.assign_id
+        @@id += 1
+        return @@id
+    end
+end
+
+#
+# 拡張サービスコールを用いたドメイン間通信の
+# throughプラグイン
+# HRP2ドメインプラグインによって挿入される
+#
+class HRP2SVCPlugin < ThroughPlugin
+
+  #=== RPCPlugin の initialize
+  #  説明は ThroughPlugin (plugin.rb) を参照
+  @@generated_celltype_header = {}
+
+  def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
+    super
+    @ct_name_body = "#{@ct_name}SVCBody_#{@next_cell.get_name}_#{@next_cell_port_name}".to_sym
+    @ct_name = "#{@ct_name}SVCCaller_#{@next_cell.get_name}_#{@next_cell_port_name}".to_sym
+    @cell_name_body = "#{@cell_name}SVCBody".to_sym
+    @cell_name = "#{@cell_name}SVCCaller".to_sym
+    puts "%%%% "
+    p @next_cell.get_name
+    p @caller_cell.get_name
+  end
+
+  #=== NamespacePath を得る
+  # 生成するセルの namespace path を生成する
+  def get_cell_namespace_path
+#    nsp = @region.get_namespace.get_namespace_path
+    nsp = @start_region.get_namespace_path
+    return nsp.append( @cell_name )
+  end
+
+  def gen_plugin_decl_code( file )
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if !HRP2KernelObjectPlugin.include_celltype?(@next_cell.get_celltype)
+    if @@generated_celltype[ @ct_name_body ] == nil then
+        @@generated_celltype[ @ct_name_body ] = [ self ]
+        file2 = CFile.open( "#{$gen}/#{@ct_name_body}.cdl", "w" )
+        file2.print <<EOT
+[active]
+celltype #{@ct_name_body} {
+    call #{@signature.get_name} #{@call_port_name};
+};
+EOT
+        file2.close
+    else
+      @@generated_celltype[ @ct_name_body ] << self
+    end
+    file.print "import( \"#{$gen}/#{@ct_name_body}.cdl\" );\n"
+    end
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if @@generated_celltype[ @ct_name ] == nil then
+        @@generated_celltype[ @ct_name ] = [ self ]
+        file2 = CFile.open( "#{$gen}/#{@ct_name}.cdl", "w" )
+        if !HRP2KernelObjectPlugin.include_celltype?(@next_cell.get_celltype)
+        file2.print <<EOT
+celltype #{@ct_name} {
+    entry #{@signature.get_name} #{@entry_port_name};
+};
+EOT
+        else
+            # TODO inlineにした方が効率がよいが，tecsgenの生成したヘッダファイルの
+            # 読込順のためにエラーとなる
+        file2.print <<EOT
+celltype #{@ct_name} {
+    //[inline] entry #{@signature.get_name} #{@entry_port_name};
+    entry #{@signature.get_name} #{@entry_port_name};
+    call #{@signature.get_name} #{@call_port_name};
+};
+EOT
+        end
+        
+        file2.close
+    else
+      @@generated_celltype[ @ct_name ] << self
+    end
+    file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
+
+=begin
+    # TODO: send. receive 対応
+    send_receive = []
+    if @signature != nil then
+      @signature.each_param{ |fd,param|
+        dir =param.get_direction
+        case dir
+        when :SEND, :RECEIVE
+          send_receive << [ dir, fd, param ]
+        end
+      }
+    end
+=end
+
+=begin
+composite #{@ct_name} {
+    entry #{@signature.get_name} #{@entry_port_name};
+    call #{@signature.get_name} #{@call_port_name};
+
+    cell #{@ct_name}Client #{@cell_name}Client{
+    };
+
+    [active]
+    cell #{@ct_name}Server #{@cell_name}Server{
+        #{@call_port_name} => composite.#{@call_port_name};
+    };
+
+    composite.#{@entry_port_name} => #{@cell_name}.#{@entry_port_name};
+};
+=end
+
+  end
+
+  #===  through cell コードを生成
+  #
+  #
+  def gen_through_cell_code( file )
+    #require "HRP2Cache"
+
+    gen_plugin_decl_code( file )
+
+    if !HRP2KernelObjectPlugin.include_celltype?(@next_cell.get_celltype)
+    # セルを探す
+    # path =["::",@next_cell.get_name]  # mikan namespace
+    # cell = Namespace.find( path )
+    # cell = Namespace.find( @next_cell.get_namespace_path )
+
+    ##### クライアント側のセルの生成 #####
+    # file.print "[domain(HRP2, \"trusted\")]"
+    nest = @start_region.gen_region_str_pre file
+    nest_str = "  " * nest
+
+    # クライアント側チャンネルの生成
+    # 拡張サービスコール呼出し
+    file.print <<EOT
+#{nest_str}  //  Client Side Channel
+#{nest_str}  cell #{@ct_name} #{@cell_name}{
+#{nest_str}  };
+
+EOT
+
+    @start_region.gen_region_str_post file
+    file.print "\n\n"
+
+    ##### サーバー側のセルの生成 #####
+    nest = @end_region.gen_region_str_pre file
+    nest_str = "  " * nest
+    if @next_cell_port_subscript then
+      subscript = '[' + @next_cell_port_subscript.to_s + ']'
+    else
+      subscript = ""
+    end
+
+    # サーバー側チャンネルの生成 
+    # 拡張サービスコール本体
+    file.print <<EOT
+
+#{nest_str}  //  Server Side Channel
+#{nest_str}  cell #{@ct_name_body} #{@cell_name_body}{
+#{nest_str}    #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
+#{nest_str}  };
+EOT
+
+    @end_region.gen_region_str_post file
+
+    file2 = AppFile.open( "#{$gen}/tecsgen.cfg" )
+    file2.print "\n/* Generated by HRP2SVCPlugin */\n\n"
+    file2.print <<EOT
+#include "#{@ct_name_body}_factory.h"
+EOT
+    file2.close
+    else
+
+    ##### クライアント側のセルの生成 #####
+    nest = @start_region.gen_region_str_pre file
+    nest_str = "  " * nest
+    if @next_cell_port_subscript then
+      subscript = '[' + @next_cell_port_subscript.to_s + ']'
+    else
+      subscript = ""
+    end
+
+    # クライアント側チャンネルの生成
+    # 拡張サービスコール呼出し
+    file.print <<EOT
+#{nest_str}  //  Client Side Channel
+#{nest_str}  cell #{@ct_name} #{@cell_name}{
+#{nest_str}    #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
+#{nest_str}  };
+
+EOT
+
+    @start_region.gen_region_str_post file
+    file.print "\n\n"
+
+    end
+   end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     通常であれば、ジェネレータは受け口関数のテンプレートを生成する
+  #     プラグインの場合、変更する必要のないセルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+      puts "generate ep_func for #{ct_name}"
+
+    if !HRP2KernelObjectPlugin.include_celltype?(@next_cell.get_celltype)
+        # 拡張サービスコール呼出し
+        if ! func_type.get_type.kind_of?( VoidType ) then
+            file.print( "  #{func_type.get_type_str}  retval;\n" )
+        end
+
+        if ! b_singleton then
+
+            file.print <<EOT
+  #{ct_name}_CB    *p_cellcb;
+  if( VALID_IDX( idx ) ){
+    p_cellcb = #{global_ct_name}_GET_CELLCB(idx);
+  }else{
+     /* エラー処理コードをここに記述 */
+  }
+
+EOT
+        end
+
+        # p "celltype_name, sig_name, func_name, func_global_name"
+        # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
+
+        delim = ""
+        if ! func_type.get_type.kind_of?( VoidType ) then
+            file.print( "  retval = (#{func_type.get_type_str})" )
+        else
+            file.print( "  " )
+        end
+
+        #file.print( "#{@call_port_name}_#{func_name}(" )
+        # svcid = SVCManage.assign_id
+        new_func = false
+        if SVCManage.include_func_id?( "#{@ct_name_body}_#{func_name}" ) == false
+            new_func = true
+            SVCManage.set_func_id( "#{@ct_name_body}_#{func_name}" )
+        end
+        svcid = SVCManage.get_func_id( "#{@ct_name_body}_#{func_name}" )
+        #file.print( "cal_svc( #{@ct_name_body}_#{func_name}" )
+        file.print( "cal_svc( #{svcid.to_s}" )
+
+        #    if ( ! b_singleton ) then
+        #      file.print( " tecs_this" )
+        #      delim = ","
+        #    end
+
+        i = 0
+        params.each{ |param|
+            delim = ","
+            file.printf( "#{delim} #{param.get_name}" )
+            i += 1
+        }
+
+        while(i < 5) do
+            delim = ","
+            file.printf( "#{delim} 0" )
+            i += 1
+        end
+
+        file.print( " );\n" )
+
+        if ! func_type.get_type.kind_of?( VoidType ) then
+            file.print( "  return retval;\n" )
+        end
+
+        # 拡張サービスコール本体
+        if new_func
+            file2 = AppFile.open( "#{$gen}/#{@ct_name_body}.c" )
+
+#             if @@generated_celltype_header[ @ct_name_body ].nil?
+#                 @@generated_celltype_header[ @ct_name_body ] = true
+#                 p @@generated_celltype_header[ @ct_name_body ]
+#                 file2.print <<EOT
+# /*
+#  * このファイルは tecsgen により自動生成されました
+#  * このファイルを編集して使用することは、意図されていません
+#  */
+# /* #[<PREAMBLE>]#
+#  * #[<...>]# から #[</...>]# で囲まれたコメントは編集しないでください
+#  * tecsmerge によるマージに使用されます
+#  *
+#  * #[</PREAMBLE>]# */
+# 
+# /* プロトタイプ宣言や変数の定義をここに書きます #_PAC_# */
+# #include "#{@ct_name_body}_tecsgen.h"
+# 
+# #ifndef E_OK
+# #define	E_OK	0		/* success */
+# #define	E_ID	(-18)	/* illegal ID */
+# #endif
+# 
+# EOT
+#             end
+
+            if func_type.get_type.kind_of?( VoidType ) then
+                retval_assign = ""
+                retval_return = ""
+            else
+                retval_assign = "retval = (ER_UINT)"
+                retval_return = "retval"
+            end
+
+            file2.print <<EOT
+ER_UINT
+#{@ct_name_body}_#{func_name}(intptr_t par1, intptr_t par2, intptr_t par3, intptr_t par4, intptr_t par5, ID cdmid)
+{
+    #{@ct_name_body}_CB    *p_cellcb;
+#if 0
+    if( VALID_IDX( idx ) ){
+      p_cellcb = #{@ct_name_body}_GET_CELLCB(idx);
+    }else{
+       /* エラー処理コードをここに記述 */
+    }
+#else
+    p_cellcb = NULL;
+#endif
+
+    ER_UINT retval = 0;
+
+EOT
+
+            num = 1
+            params.each{ |param|
+                if param.get_declarator.get_ptr_level > 0 then
+                    if param.get_direction == :IN then
+                        file2.print <<EOT
+    if(prb_mem((void *)par#{num.to_s}, sizeof(#{param.get_type.get_type_str}), TSK_SELF, TPM_READ) != E_OK){
+        return E_MACV;
+    }
+EOT
+
+                    elsif param.get_direction == :OUT then
+                        file2.print <<EOT
+    if(prb_mem((void *)par#{num.to_s}, sizeof(#{param.get_type.get_type_str}), TSK_SELF, TPM_WRITE) != E_OK){
+        return E_MACV;
+    }
+EOT
+
+                    end
+                end
+                num += 1
+            }
+
+            file2.print"    #{retval_assign}#{@call_port_name}_#{func_name}("
+
+            delim = ""
+            num = 1
+            params.each{ |param|
+                file2.print "#{delim}"
+                delim = ", "
+                file2.print "(#{param.get_type.get_type_str})"
+                file2.print "par" + num.to_s
+                file2.print param.get_type.get_type_str_post
+                num += 1
+            }
+
+            file2.print ");\n"
+
+            if !func_type.get_type.kind_of?( VoidType ) then
+                file2.print "\n    return #{retval_return};\n"
+            end
+            file2.print "}\n\n"
+
+            file2.close
+
+            file2 = AppFile.open( "#{$gen}/tecsgen.cfg" )
+            file2.print "\n/* Generated by HRP2SVCPlugin */\n\n"
+            # TODO: スタックサイズは適当
+            file2.print <<EOT
+KERNEL_DOMAIN{
+    DEF_SVC( #{svcid.to_s}, { TA_NULL, #{@ct_name_body}_#{func_name}, 256 } );
+}
+EOT
+            file2.close
+
+            file2 = AppFile.open( "#{$gen}/#{@ct_name_body}_factory.h" )
+            file2.print "\n/* Generated by HRP2SVCPlugin */\n\n"
+            file2.print <<EOT
+extern ER_UINT #{@ct_name_body}_#{func_name}(intptr_t par1, intptr_t par2, intptr_t par3, intptr_t par4, intptr_t par5, ID cdmid);
+EOT
+            file2.close
+        end
+    else
+        # カーネルドメインのセルは特別なことは何もせず，普通に呼び出す
+        super
+    end
+  end
+end
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2SemaphorePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2SemaphorePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2SemaphorePlugin.rb	(revision 398)
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2011 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#require "HRP2KernelObjectPlugin"
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+
+class HRP2SemaphorePlugin < HRP2KernelObjectPlugin
+    @@ep = [:eSignalSemaphore, :eWaitSemaphore, :eManageSemaphore, :eReferSemaphore ]
+    #=== HRP2SemaphorePlugin#print_cfg_cre
+    # CRE_SEMの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # tab :: string:   インデント用のtab
+    def print_cfg_cre(file, cell, val, tab)
+        file.print tab
+        file.puts "CRE_SEM(#{val[:id]}, {#{val[:attribute]}, #{val[:count]}, #{val[:max]}});"
+    end
+    #=== HRP2SemaphorePlugin#print_cfg_sac
+    # SAC_SEMの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # acv :: string:   アクセスベクタ    
+    def print_cfg_sac(file, val, acv)
+        file.puts "SAC_SEM(#{val[:id]}, {#{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]}});"
+    end
+    #tSemaphoreの受け口リスト 
+    def get_entry_ports_name_list()
+        @@ep
+    end
+end
+
+
+  
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2TaskPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2TaskPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRP2TaskPlugin.rb	(revision 398)
@@ -0,0 +1,202 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#require "HRP2KernelObjectPlugin"
+require_tecsgen_lib "HRP2KernelObjectPlugin.rb"
+#== celltype プラグインの共通の親クラス
+class HRP2TaskPlugin < HRP2KernelObjectPlugin
+    # @@ep = [:eActivateTask, :eControlTask, :eManageTask, :eReferTask ]
+    # ATT_MODを生成済みかどうか
+    @@generate_memory_module = false
+
+    ##
+    #
+    # file : output file (ex.tecsgen.cfg)
+    # cell : 
+    # val  : 
+    # tab  : 
+    def print_cfg_cre(file, cell, val, tab)
+        #val[:id] = val[:id].gsub( /(^|[^\$])\$id\$/, "\\1#{@celltype.get_name.to_s}_#{cell.get_global_name.to_s}" )
+        #val[:id] = @celltype.subst_name( val[:id], @celltype.get_name_array( cell ) )
+        # $cbp$の代わり
+        index = cell.get_id - @celltype.get_id_base
+        #cell_CB_name = "#{@celltype.get_global_name}_pCB_tab[#{index}]"
+        cell_CB_name = "#{index}"
+        # CRE_XXX/DEF_XXXの生成
+        dbgPrint "assign task plugin\n"
+        domainOption = cell.get_region.get_domain_root.get_domain_type.get_option
+        # if cell.get_region.get_region_type == :DOMAIN
+# cell.show_tree 1
+        if domainOption != "OutOfDomain"
+            # 保護ドメインに属する場合
+            if domainOption == "trusted"
+                # カーネルドメイン
+                if val[:userStackSize] != "OMIT"
+                    raise "system task cannot have user stack."
+                end
+p "CRE_TSK 0 user=#{val[:userStackSize]} system=#{val[:systemStackSize]}"
+                file.print <<EOT
+#{tab}CRE_TSK(#{val[:id]}, { #{val[:taskAttribute]}, #{cell_CB_name}, tTask_start_task, #{val[:priority]}, #{val[:systemStackSize]}, NULL });
+EOT
+            else
+                # ユーザドメイン
+                if val[:userStackSize] == "OMIT"
+                    raise "user task must have user stack."
+                end
+p "CRE_TSK 1"
+                if val[:systemStackSize] == "OMIT"
+                    file.print <<EOT
+#{tab}CRE_TSK(#{val[:id]}, { #{val[:taskAttribute]}, #{cell_CB_name}, tTask_start_task, #{val[:priority]}, #{val[:userStackSize]}, NULL });
+EOT
+                else
+p "CRE_TSK 2"
+                    file.print <<EOT
+#{tab}CRE_TSK(#{val[:id]}, { #{val[:taskAttribute]}, #{cell_CB_name}, tTask_start_task, #{val[:priority]}, #{val[:userStackSize]}, NULL, #{val[:systemStackSize]}, NULL });
+EOT
+                end
+            end
+        else
+            # 無所属の場合
+            raise "task #{val[:id]} must belong to a domain."
+        end
+   
+        # 例外用のを生成
+        file.print <<EOT
+#{tab}DEF_TEX(#{val[:id]}, { #{val[:exceptionAttribute]}, tTask_start_exception });
+EOT
+    end
+
+    def print_cfg_sac(file, val, acv)
+       file.puts "SAC_TSK(#{val[:id]}, { #{acv[0]}, #{acv[1]}, #{acv[2]}, #{acv[3]} });"
+    end
+
+=begin
+    #tTaskの受け口リスト 
+    def get_entry_ports_name_list()
+        @@ep
+    end
+=end
+    # 
+    #  ATT_MODの生成
+    #  gen_factory実行時には，すべてのセルタイププラグインを生成済みのはずなので，
+    #  カーネルAPIコードのメモリ保護を省略できる．
+    #
+    def gen_factory file
+        super
+        if @@generate_memory_module == false
+            check_celltype_list = []
+
+            Cell.get_cell_list2.each { |cell|
+                # すべてのセルを走査してセルタイプをチェック
+                ct = cell.get_celltype
+                if ct.class == Celltype && check_celltype_list.include?( ct ) == false
+                    # チェック済みセルタイプに登録
+                    check_celltype_list << ct
+
+                    # 未チェックのセルタイプだった場合
+                    # puts "check for ATT_MOD : #{ct.classget_global_name}"
+                    puts "check for ATT_MOD : #{ct.get_global_name}"
+                        
+                    # カーネルAPIのコード，データはメモリ保護しない
+                    next if HRP2KernelObjectPlugin.include_celltype?( ct )
+
+                    # 必要のないセルタイプのコード，データはメモリ保護しない
+                    next if ! ct.need_generate?
+
+                    # HRP2のドメインリージョンを取得
+                    regions = ct.get_domain_roots
+                    regions_hrp2 = regions[ :HRP2 ]
+                    dbgPrint "HRP2 domain in #{ct.get_name}: "
+                    regions_hrp2.each { |reg|
+                        dbgPrint reg.get_name
+                    }
+                    puts ""
+
+                    # セル管理ブロックとスケルトンのメモリ保護
+                    # gen_celltype_names_domain 相当の処理
+                    if regions_hrp2.include?( Region.get_root ) == false && regions_hrp2.length > 1
+                        # ドメインが複数で，OutOfDomainにセルが存在しないセルタイプの場合
+                        # 共有のセル管理ブロックとスケルトンコードを登録する
+                        file = AppFile.open( "#{$gen}/tecsgen.cfg" )
+                        file.print "ATT_MOD(\"#{ct.get_global_name}_tecsgen.o\");\n"
+                        file.close
+                    end
+
+                    regions_hrp2.each { |reg|
+                        if reg.is_root? 
+                            nsp = ""
+                        else
+                            nsp = "_#{reg.get_namespace_path.get_global_name}"
+                        end
+                        file = AppFile.open( "#{$gen}/tecsgen#{nsp}.cfg" )
+                        file.print "ATT_MOD(\"#{ct.get_global_name}#{nsp}_tecsgen.o\");\n"
+                        file.close
+                    }
+
+                    # セルタイプコードがない場合はスキップ
+                    next if ct.is_all_entry_inline? && ! ct.is_active?
+
+                    # セルタイプコードのメモリ保護
+                    # gen_celltype_names_domain2 相当の処理
+                    if regions_hrp2.include?( Region.get_root ) == true || regions_hrp2.length > 1
+                        # OutOfDomainにセルが存在するセルタイプの場合
+                        # または，複数のドメインにセルが存在するセルタイプの場合
+                        # セルタイプコードを共有するように登録する
+                        file = AppFile.open( "#{$gen}/tecsgen.cfg" )
+                    else
+                        # OutOfDomainでない単一のドメインにセルが存在するセルタイプの場合
+                        # セルタイプコードを専有するように登録する
+                        file = AppFile.open( "#{$gen}/tecsgen_#{regions_hrp2[0].get_namespace_path.get_global_name}.cfg" )
+                    end
+
+                    file.print "ATT_MOD(\"#{ct.get_global_name}.o\");\n"
+                    file.close
+                else
+                    # 何もしない
+                end
+            }
+
+            @@generate_memory_module = true
+        else
+            # 何もしない
+        end
+    end
+    
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPHandlerPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPHandlerPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPHandlerPlugin.rb	(revision 398)
@@ -0,0 +1,129 @@
+# coding: utf-8
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#++
+
+require_tecsgen_lib "HRPKernelObjectPlugin.rb"
+
+
+#== celltype プラグインの共通の親クラス
+class HRPHandlerPlugin < HRPKernelObjectPlugin
+
+    ##
+    # oyama: add to avoid Ruby exception in code generation phase.
+    def new_cell cell
+        domainOption = cell.get_region.get_domain_root.get_domain_type.get_option
+        if (domainOption == "OutOfDomain") || (domainOption != "kernel")
+          cdl_error( "HRP9999 HRP handler '$1' must belong to kernel domain", cell.get_name )
+        end
+    end
+
+    ##
+    #
+    # file : output file (ex.tecsgen.cfg)
+    # cell : 
+    # val  : 
+    # tab  : 
+    def print_cfg_cre(file, cell, val, tab)
+        if !val[:id].nil?
+            val[:id] = val[:id].gsub( /(^|[^\$])\$id\$/, "\\1#{@celltype.get_name.to_s}_#{cell.get_name.to_s}" )
+        end
+        # $cbp$の代わり
+        index = cell.get_id - @celltype.get_id_base
+        #cell_CB_name = "#{@celltype.get_global_name}_CB_tab[#{index}]"
+        name_array = cell.get_celltype.get_name_array cell
+        cell_CBP = name_array[8]
+        # CRE_XXXの生成
+        domainOption = cell.get_region.get_domain_root.get_domain_type.get_option
+        if (domainOption == "OutOfDomain") || (domainOption != "kernel")
+            # 無所属 or ユーザドメインに属する場合
+                raise "#{@plugin_arg_str.to_s.downcase} handler #{val[:id]} must belong to kernel domain."
+        elsif @plugin_arg_str == "CONFIG_INT"
+            file.print <<EOT
+#{tab}CFG_INT( #{val[:interruptNumber]}, { #{val[:attribute]}, #{val[:interruptPriority]} });
+EOT
+        elsif @plugin_arg_str == "ISR"
+            file.print <<EOT
+#{tab}CRE_ISR(#{val[:id]}, { #{val[:attribute]}, #{cell_CBP}, #{val[:interruptNumber]}, tISR_start, #{val[:isrPriority]} });
+EOT
+        elsif @plugin_arg_str == "DEF_INH"
+            name_array = @celltype.get_name_array cell
+            start = @celltype.subst_name( "$id$_start", name_array )
+            file.print <<EOT
+#{tab}DEF_INH(#{val[:interruptHandlerNumber]}, { #{val[:attribute]}, #{start} });
+EOT
+        elsif @plugin_arg_str == "DEF_EXC"
+            name_array = @celltype.get_name_array cell
+            start = @celltype.subst_name( "$id$_start", name_array )
+            file.print <<EOT
+#{tab}DEF_EXC(#{val[:cpuExceptionHandlerNumber]}, { #{val[:attribute]}, #{start} });
+EOT
+        elsif @plugin_arg_str == "INIT_ROUTINE"
+            file.print <<EOT
+#{tab}ATT_INI({ #{val[:attribute]}, #{cell_CBP}, tInitializeRoutine_start });
+EOT
+        elsif @plugin_arg_str == "TERM_ROUTINE"
+            file.print <<EOT
+#{tab}ATT_TER({ #{val[:attribute]}, #{cell_CBP}, tTerminateRoutine_start });
+EOT
+        else
+            raise "#{@plugin_arg_str} is unknown option"
+        end
+    end
+
+    def print_cfg_sac(file, val, acv)
+        if @plugin_arg_str == "CONFIG_INT"
+            # nothing to do
+        elsif @plugin_arg_str == "ISR"
+            # kernel.cdl の tISR で accessPattern1 ～ accessPattern4 が定義されているときの名残。
+            # accessPattern1 が定義されていない場合、こここへは来ない．復活したときに備えて残しておく．
+            # file.puts "SAC_#{@plugin_arg_str}(#{val[:id]}, { #{acv[:accessPattern1]}, #{acv[:accessPattern2]}, #{acv[:accessPattern3]}, #{acv[:accessPattern4]} });"
+            puts "*** Unsupported *** SAC_#{@plugin_arg_str}(#{val[:id]}, { #{acv[:accessPattern1]}, #{acv[:accessPattern2]}, #{acv[:accessPattern3]}, #{acv[:accessPattern4]} });\n"
+        elsif @plugin_arg_str == "DEF_INH"
+            # nothing to do
+        elsif @plugin_arg_str == "DEF_EXC"
+            # nothing to do
+        elsif @plugin_arg_str == "INIT_ROUTINE"
+            # nothing to do
+        elsif @plugin_arg_str == "TERM_ROUTINE"
+            # nothing to do
+        else
+            raise "#{@plugin_arg_str} is unknown option"
+        end
+    end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPKernelObjectManager.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPKernelObjectManager.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPKernelObjectManager.rb	(revision 398)
@@ -0,0 +1,71 @@
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2015-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#
+#   $Id$
+#  
+#++
+# This file has been generated by gen_kernel_celltype.py
+class HRPKernelObjectManager
+	@@kernel_objs = [\
+		:tKernel, \
+		:tTask, \
+		:tSemaphore, \
+		:tEventflag, \
+		:tDataqueue, \
+		:tPriorityDataqueue, \
+		:tMutex, \
+		:tFixedSizeMemoryPool, \
+		:tTimeEventHandler, \
+		:tCyclicNotifier, \
+		:tAlarmNotifier, \
+		:tInterruptRequest, \
+		:tISR, \
+		:tInterruptHandler, \
+		:tCpuExceptionHandler, \
+		:tInitializeRoutine, \
+		:tTerminateRoutine, \
+		:tMessageBuffer, \
+	]
+
+    def initialize()
+        # 
+        #  本クラスはインスタンスを持たない仮想的なクラスである
+        #
+        raise "class #{self.class.name} shall not have instances"
+    end
+    def self.include_celltype?(str)
+        return @@kernel_objs.include?(str)
+    end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPKernelObjectPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPKernelObjectPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPKernelObjectPlugin.rb	(revision 398)
@@ -0,0 +1,336 @@
+# coding: utf-8
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#
+#  $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+class HRPKernelObjectPlugin < CelltypePlugin
+    # @@obj_hash = {}
+
+    #@celltype:: Celltype
+    #@option:: String     :オプション文字列
+    def initialize( celltype, option )
+        super
+        #
+        #  それぞれのカーネルオブジェクトを解析対象セルタイプに追加
+        #  目的：
+        #   - カーネルオブジェクトのセルをメモリ保護対象外とする
+        #    - カーネルオブジェクト本体の管理はTECSでなくOSで実施するため
+        #   - カーネルオブジェクトのセルへのアクセスを直接関数呼出し
+        #   　とする
+        #    - システムサービス呼出しはOSが提供するため
+        HRPKernelObjectPlugin.set_celltype(celltype)
+    end
+  
+    #=== HRPKernelObjectPlugin#print_cfg_cre
+    # 各種カーネルオブジェクトのCRE_*の出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # tab :: string:   インデント用のtab
+    def print_cfg_cre(file, cell, val, tab)
+        raise "called virtual method print_cfg_cre in #{@celltype.get_name} plugin"
+    end
+  
+    #=== HRPKernelObjectPlugin#print_cfg_sac
+    # 各種カーネルオブジェクトのSAC_*の出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # acv :: string:   アクセスベクタ
+    def print_cfg_sac(file, val, acv)
+        raise "called virtual method print_cfg_sac in #{@celltype.get_name} plugin"
+    end
+  
+    #
+    #  セルタイププラグインの本体メソッド
+    #   - 静的APIの生成
+    #  file:: FILE:     出力先ファイル
+    #
+    def gen_factory file
+        dbgPrint "===== begin #{@celltype.get_name.to_s} plugin =====\n"
+
+        #
+        # 対象となるすべてのセルについて、受け口に結合されている
+        # セルの所属ドメインを解析
+        #  - 生成すべきcfgファイル名を取得するために必要
+        #
+        if !HRPKernelObjectPlugin.isChecked()
+            HRPKernelObjectPlugin.check_referenced_cells()
+        else
+            dbgPrint "***** already checked\n"
+        end
+
+        # 追記するために AppFile を使う（文字コード変換されない）
+        file2 = AppFile.open( "#{$gen}/tecsgen.cfg" )
+        file2.print "\n/* Generated by #{self.class.name} */\n\n"
+
+        @celltype.get_cell_list.each { |cell|
+            if cell.is_generate?
+                dbgPrint "===== begin check my domain #{cell.get_name} =====\n"
+                #
+                #  カーネルオブジェクトの属性を，valにコピー
+                #
+                val = {}
+                @celltype.get_attribute_list.each{ |a|
+                    # p a.get_name
+                    if a.get_type.kind_of?( ArrayType )
+                        val[a.get_name] = []
+                        if j = cell.get_join_list.get_item(a.get_name)
+                            # セル生成時に初期化する場合
+                            j.get_rhs.each { |elem|
+                                val[a.get_name] << elem.to_s
+                            }
+                        elsif i = a.get_initializer
+                            # セルタイプの初期化値を使う場合
+                            i.each { |elem|
+                                val[a.get_name] << elem.to_s
+                            }
+                        else
+                            raise "attribute is not initialized"
+                        end
+                    else
+                        if j = cell.get_join_list.get_item(a.get_name)
+                            # セル生成時に初期化する場合
+                            val[a.get_name] = j.get_rhs.to_s
+                        elsif i = a.get_initializer
+                            # セルタイプの初期化値を使う場合
+                            val[a.get_name] = i.to_s
+                        else
+                            raise "attribute is not initialized"
+                        end
+                    end
+                }
+                # generate.rbを参考に
+                # $id$を置換
+                if val[:id].nil? != true
+                    name_array = @celltype.get_name_array( cell )
+                    val[:id]   = @celltype.subst_name( val[:id], name_array )
+                end
+                # $cbp$の代わり
+                cell_domain_root = cell.get_region.get_domain_root
+                cell_domain_type = cell.get_region.get_domain_root.get_domain_type
+
+                # CRE_XXX/DEF_XXXの生成
+                if cell_domain_type.get_option.to_s != "OutOfDomain"
+                    # 保護ドメインに属する場合
+                    if !HRPKernelObjectPlugin.include_region(cell_domain_root.get_name.to_s)
+                        # その保護ドメインの.cfgが生成されていない場合
+                        HRPKernelObjectPlugin.set_region_list(cell_domain_root.get_name.to_s)
+                        dbgPrint "~~~~~ #{cell_domain_root.get_name.to_s} is registered!\n"
+
+#                        # if cell.get_region.get_param == :KERNEL_DOMAIN
+#                        if cell_domain_type.get_option.to_s == "kernel"
+#                            file2.print "KERNEL_DOMAIN{\n"
+#                        else
+#                            file2.print "DOMAIN(#{cell_domain_root.get_name.to_s}){\n"
+#                        end
+#                        file2.puts "\tINCLUDE(\"#{$gen}/tecsgen_#{cell_domain_root.get_name.to_s}.cfg\");" 
+#                        file2.puts "}\n"
+                    else
+                        dbgPrint "~~~~~ #{cell.get_region.get_namespace_path} is included in"
+                        #p @@region_list
+                    end
+                    file3 = AppFile.open( "#{$gen}/tecsgen_#{cell_domain_root.get_global_name}.cfg" )
+                    print_cfg_cre(file3, cell, val,"")
+                    file3.close
+                else
+                    # 無所属の場合
+                    dbgPrint "~~~~~ #{cell_domain_root.get_namespace_path} is OutOfDomain\n"
+                    # print "~~~~~ #{cell_domain_root.get_namespace_path} is OutOfDomain\n"
+                    # p cell_domain_root.get_name
+                    if cell_domain_root.get_name == "::" then
+                      print_cfg_cre(file2, cell, val, "")
+                    else
+#                      if !HRPKernelObjectPlugin.include_region(cell_domain_root.get_name.to_s)
+#                        # その保護ドメインの.cfgが生成されていない場合
+#                        HRPKernelObjectPlugin.set_region_list(cell_domain_root.get_name.to_s)
+#                        file2.puts "INCLUDE(\"#{$gen}/tecsgen_#{cell_domain_root.get_name.to_s}.cfg\");\n"
+#                      end
+                      file3 = AppFile.open( "#{$gen}/tecsgen_#{cell_domain_root.get_name.to_s}.cfg" )
+                      print_cfg_cre(file3, cell, val,"")
+                      file3.close
+                    end
+
+                end
+
+                dbgPrint "===== end check my domain #{cell.get_name} =====\n"
+
+                #
+                # SAC_XXXの生成
+                #
+                if !val[:accessPattern1].nil?
+                    dbgPrint "===== begin check regions #{cell.get_name} =====\n"
+                    i = 0
+                    acv = { \
+                            :accessPattern1 => val[:accessPattern1], \
+                            :accessPattern2 => val[:accessPattern2], \
+                            :accessPattern3 => val[:accessPattern3], \
+                            :accessPattern4 => val[:accessPattern4] \
+                    }
+                    acv_tmp = []
+                    domain_roots = HRPPlugin.get_inter_domain_join_roots cell
+                    # 結合先セルのドメインを加える
+                    if cell_domain_type.get_kind != :OutOfDomain then
+                      domain_roots << cell_domain_root
+                    end
+                    domain_roots.each{ |dr|
+                      case dr.get_domain_type.get_kind
+                      when :user
+                        acv_tmp << "TACP(#{dr.get_name})"
+                      when :kernel
+                        acv_tmp << "TACP_KERNEL"
+                      when :OutOfDomain
+                        if cell_domain_type.get_kind == :OutOfDomain then
+                          # 呼び元も、呼び先も OutOfDomain の場合
+                          acv_tmp << "TACP_SHARED"
+                        end
+                      end
+                    }
+                    acv_tmp.uniq!
+                    if acv_tmp.length == 0 then
+                      # 呼び先セルが無所属かつ、呼び元も無所属のみ、または結合無しの場合
+                      acv_tmp = [ "TACP_SHARED" ]
+                    end
+                    b_info = false
+                    b_warn = false
+                    acv.each { |key, acp|
+                        if !acp.nil?
+                            if acp != "OMIT"
+                            elsif cell_domain_type.get_kind != :OutOfDomain
+                              # p "UserDomainCell or KernelDomainCell"
+                              domain_roots = HRPPlugin.get_inter_domain_join_roots cell
+                              domain_roots.each{ |dr|
+                                # 
+                                case dr.get_domain_type.get_kind
+                                when :kernel
+                                when :user
+                                  if dr.get_namespace_path != cell.get_region.get_domain_root.get_namespace_path
+                                    # 他のユーザードメインからの結合
+                                    if( b_warn == false ) then
+                                      cdl_error( "HRP9999 '$1': kernel object joined from other user domain. kernel object joined from multi-user-domain must be placed out of domain", cell.get_name )
+                                      b_warn = true
+                                    end
+                                  end
+                                when :OutOfDomain
+                                  if( b_info == false ) then
+                                    # 無所属からの結合
+                                    # cdl_error( "HRP9999 kernel object joined from out of domain" )
+                                    if cell_domain_type.get_kind == :OutOfDomain
+                                      # この情報は、不要と判断する (無所属から無所属へ結合があると、アクセス許可ベクタが設定されない)
+                                      # cdl_info2( cell.get_locale, "HRP9999 '$1': kernel object joined from out of domain, access vector is not set", cell.get_name )
+                                      b_info = true
+                                    end
+                                  end
+                                else
+                                  raise "unknown domain kind"
+                                end
+                              }
+                              # acv[key] = "TACP(#{cell_domain_root.get_name.to_s})"
+                            else
+                              # p "OutOfDomainCell"
+                              # 無所属のセル
+                              # 結合元ドメインに許可する
+                              # 結合元に無所属のセルがあると、TACP_SHARED が設定される. フロー解析してドメインを特定できるのが、あるべき仕様
+                            end
+                            if acp == "OMIT"
+                              acv[key] = acv_tmp.join( '|' )
+                            end 
+                        end
+                    }
+                    #各種SACの生成
+                    domainOption = cell_domain_type.get_option
+                    # p "domain_root ", cell.get_region.get_domain_root.get_name
+                    if domainOption != "OutOfDomain" || cell.get_region.get_domain_root.get_name != "::"
+                        # 保護ドメインに属する場合
+                        file3 = AppFile.open( "#{$gen}/tecsgen_#{cell.get_region.get_name.to_s}.cfg" )
+                        print_cfg_sac(file3, val, acv)
+                        file3.close
+                    else
+                        # 無所属の場合
+                        print_cfg_sac(file2, val, acv)
+                    end
+
+                    dbgPrint "===== end check regions #{cell.get_name} =====\n"
+                end
+            end
+        }
+        dbgPrint "===== end #{@celltype.get_name.to_s} plugin =====\n"
+        file2.close
+    end
+
+    # カーネルオブジェクトセルタイプの管理
+    # HRPKernelObjectPluginクラスに対してメソッド呼出しを行うことを想定
+    @@checked = false
+    @@celltype_list = []
+    @@region_list = []
+
+    def self.isChecked()
+        return @@checked
+    end
+
+    def self.check_referenced_cells()
+        dbgPrint "===== begin check registered celltype =====\n"
+        self.get_celltype_list.each { |ct|
+          dbgPrint( ct.get_name.to_s + "\n" )
+        }
+        dbgPrint "===== end check registered celltype =====\n"
+
+        @@checked = true
+    end
+
+    def self.set_celltype( celltype )
+        @@celltype_list << celltype
+    end
+
+    def self.get_celltype_list
+        return @@celltype_list
+    end
+
+    def self.set_region_list( region )
+        @@region_list << region
+    end
+
+    def self.include_region( region )
+        return @@region_list.include?(region)
+    end
+
+    def self.include_celltype?( celltype )
+        return @@celltype_list.include?(celltype)
+    end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPObjectPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPObjectPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPObjectPlugin.rb	(revision 398)
@@ -0,0 +1,97 @@
+# coding: utf-8
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#  $Id$
+#++
+
+require_tecsgen_lib "HRPKernelObjectPlugin.rb"
+
+
+class HRPObjectPlugin < HRPKernelObjectPlugin
+    @@api = {
+        "SEMAPHORE"=>["SEM", :id, :attribute, :initialCount, :maxCount],
+        "EVENTFLAG"=>["FLG", :id, :attribute, :flagPattern],
+        "DATAQUEUE"=>["DTQ", :id, :attribute, :dataCount, :dataqueueManagementBuffer],
+        "PRIORITY_DATAQUEUE"=>["PDQ", :id, :attribute, :dataCount, :maxDataPriority, :priorityDataqueueManagementBuffer],
+        "FIXED_SIZE_MEMORYPOOL"=>["MPF", :id, :attribute, :blockCount, :blockSize, :memoryPool, :memoryPoolManagementBuffer],
+        "KERNEL"=>["SYS"],
+        "MESSAGE_BUFFER"=>["MBF", :id, :attribute, :maxMessageSize, :bufferSize, :mbfmb],
+        "MUTEX"=>["MTX", :id, :attribute, :ceilingPriority]
+    }
+
+    #=== HRPObjectPlugin#print_cfg_cre
+    # CRE_XXXの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # tab :: string:   インデント用のtab
+    def print_cfg_cre(file, cell, val, tab)
+        if @@api.has_key?(@plugin_arg_str) == false
+            raise "#{@plugin_arg_str} is unknown"
+        elsif @plugin_arg_str != "KERNEL"
+            arg_list = []
+            params = @@api[@plugin_arg_str]
+            if @plugin_arg_str == "MUTEX" && ((val[:attribute] =~ /\bTA_CEILING\b/)==nil)
+              slice_end = -2   # :ceilingPriority を外す
+            else
+              slice_end = -1
+            end
+            # p @plugin_arg_str, slice_end, val[:attribute], (val[:attribute] =~ /\bTA_CEILING\b/)
+            params.slice(2..slice_end).each { |attr|
+                arg_list << "#{val[attr]}"
+            }
+            file.print tab
+            file.puts "CRE_#{@@api[@plugin_arg_str].at(0)}(#{val[:id]}, { #{arg_list.join(", ")} });"
+        end
+    end
+    #=== HRPObjectPlugin#print_cfg_sac
+    # SAC_XXXの出力
+    # file:: FILE:     出力先ファイル
+    # val :: string:   カーネルオブジェクトの属性の解析結果
+    # acv :: string:   アクセスベクタ    
+    def print_cfg_sac(file, val, acv)
+        if @@api.has_key?(@plugin_arg_str) == false
+            raise "#{@plugin_arg_str} is unknown"
+        elsif @plugin_arg_str != "KERNEL"
+            file.puts "SAC_#{@@api[@plugin_arg_str].at(0)}(#{val[:id]}, { #{acv[:accessPattern1]}, #{acv[:accessPattern2]}, #{acv[:accessPattern3]}, #{acv[:accessPattern4]} });"
+        else
+            file.puts "SAC_#{@@api[@plugin_arg_str].at(0)}({ #{acv[:accessPattern1]}, #{acv[:accessPattern2]}, #{acv[:accessPattern3]}, #{acv[:accessPattern4]} });"
+        end
+    end
+
+end
+
+
+  
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPPlugin.rb	(revision 398)
@@ -0,0 +1,355 @@
+# coding: utf-8
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2014-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#  $Id$
+#++
+
+
+require_tecsgen_lib "HRPKernelObjectManager.rb"
+#
+# 各メソッドの役割りは、DomainPlugin.rb を参照のこと
+# HRPカーネル用ドメインプラグイン
+class HRPPlugin < DomainPlugin
+  
+  def initialize( region, name, option )
+    super
+    dbgPrint "HRPPlugin: initialize: region=#{region.get_name}, domainName=#{name}, option=#{option}\n"
+    @region = region
+    @name   = name
+    case option
+    when "kernel", "user", "OutOfDomain"
+      # OK
+      @option = option
+    else
+      cdl_error( "HRPPlugin: '$1' is unacceptable domain kind, specify 'kernel' or 'user'", option )
+      @option = "kernel"   # とりあえず kernel を設定しておく
+    end
+  end
+
+  def add_through_plugin( join, current_region, next_region, through_type )
+    # join.get_owner:Cell  左辺のセル
+    # join.get_definition:Port 呼び口
+    # join.get_subscript:Integer or nil 呼び口配列の添数 (Join::@subscript の説明参照)
+    # join.get_cell:Cell 右辺のセル
+    # join.get_port_name:Symbol 受け口
+    # get_rhs_subscript:Integer or nil 受け口配列の添数 (Join::@rhs_subscript の説明参照)
+    # return []
+    dbgPrint "MyDomainPlugin: add_through_plugin: #{current_region.get_name}=>#{next_region.get_name}, #{join.get_owner.get_name}.#{join.get_definition.get_name}=>#{join.get_cell.get_name}.#{join.get_port_name}, #{through_type}\n"
+
+    #puts "=====Join Check Start====="
+    #puts "caller: #{join.get_owner.get_name.to_s}, callee: #{join.get_cell.get_name.to_s}"
+    #puts "=====Join Check param====="
+    current_domain = current_region.get_domain_root.get_domain_type
+    next_domain = next_region.get_domain_root.get_domain_type
+    #puts current_domain.get_option.to_s
+    # if !next_domain.nil?
+    #     puts next_domain.get_option.to_s
+    # else
+    #     puts "next domain is nil!"
+    # end
+
+    HRPPlugin.add_inter_domain_join_set join
+    # p join.get_cell.get_name
+    # p join.get_cell.get_real_celltype(join.get_rhs_port1).get_name
+    # if HRPKernelObjectManager.include_celltype?(join.get_cell.get_celltype.get_global_name)   #oyama: get_name => get_global_name 
+    if HRPKernelObjectManager.include_celltype?(join.
+                                                 get_cell.
+                                                 get_real_celltype(join.get_rhs_port1).
+                                                 get_global_name)                #oyama: get_name => get_global_name 
+        # 結合先がカーネルオブジェクトセル
+        # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
+        # 何もしないthrough
+        # puts "***** #{join.get_cell.get_celltype.get_name} is kernel object"
+        return []
+        # return [ :HRP2SVCPlugin, "channelCelltype=tMessagebufferChannel,noClientSemaphore=true" ]
+    # elsif @end_region.is_root?
+    # elsif next_region.get_option == OutOfDomain
+    # elsif next_domain.nil?
+    elsif next_domain.get_option.to_s == "OutOfDomain"
+    #     # 結合先が無所属
+    #     # 何もしないthrough
+    #     # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
+        # puts "***** nil"
+        return []
+    #elsif @start_region.get_param != :KERNEL_DOMAIN && @end_region.get_param == :KERNEL_DOMAIN
+    elsif current_domain.get_option.to_s != "kernel" && next_domain.get_option.to_s == "kernel"
+        # ユーザドメインからカーネルドメインへの結合
+        # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
+        # puts "***** svc"
+        return [ :HRPSVCPlugin, "" ]
+    elsif current_domain != next_domain
+        # 別のユーザドメインへの結合
+        # @plugin_body = HRP2RPCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
+        # puts "***** rpc"
+        # return [ :HRPRPCPlugin, "channelCelltype=tMessagebufferChannel,noClientSemaphore=true" ]
+        # puts "HRPPlugin:RPC:PPAllocatorSize=256"
+        return [ :HRPRPCPlugin, "noClientSemaphore=false,PPAllocatorSize=256" ]
+    else
+        # その他
+        # 何もしないthrough
+        # @plugin_body = HRP2SVCPlugin.new(cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell)
+        dbgPrint "warning: at HRP Join Check"
+        return nil
+    end
+
+    # puts "=====Join Check End====="
+  end
+
+  def joinable?(current_region, next_region, through_type )
+    dbgPrint "MyDomainPlugin: joinable? from #{current_region.get_name} to #{next_region.get_name} (#{through_type})\n"
+    return true
+  end
+
+  #== ドメイン種別を返す
+  #return::Symbol :kernel, :user, :OutOfDomain
+  def get_kind
+    return @option.to_sym
+  end
+  
+  def self.gen_post_code file
+  end
+
+  # ATT_MODを生成済みかどうか                   # 2017.8.27
+  @@generate_memory_module = false
+
+  @@include_extsvc_fncd = false  # 17.07.26 暫定
+  # 
+  #  ATT_MODの生成
+  #  gen_factory実行時には，すべてのセルタイププラグインを生成済みのはずなので，
+  #  カーネルAPIコードのメモリ保護を省略できる．
+  #
+  def gen_factory
+    super
+
+    if @@include_extsvc_fncd == false
+      file = AppFile.open( "#{$gen}/tecsgen.cfg" )
+      file.print "/* HRPPlugin 001 */\n"
+      file.print "#include \"extsvc_fncode.h\"\n"   ## 2017.7.26
+      file.close
+      @@include_extsvc_fncd = true
+    end
+
+    if @@generate_memory_module == false
+
+      # INCLUDE を出力
+      #  すべてのドメインに対する cfg を先に生成しておく
+      #  もし、ドメインに属するカーネルオブジェクトも、モジュールもない場合でも、cfg が出力される
+      regions = DomainType.get_domain_regions[ :HRP ]
+      file = AppFile.open( "#{$gen}/tecsgen.cfg" )
+      file.print "/* HRPPlugin 002 */\n"
+      regions.each{ |region|
+        if ! region.is_root? then
+          nsp = "#{region.get_global_name}"
+          file2 = AppFile.open( "#{$gen}/tecsgen_#{nsp}.cfg" )
+          file2.close
+          case region.get_domain_type.get_kind
+          when :kernel
+            pre = "KERNEL_DOMAIN{\n    "
+            post = "}\n"
+          when :user
+            pre = "DOMAIN(#{region.get_name}){\n    "
+            post = "}\n"
+          when :OutOfDomain
+            pre = ""
+            post = "\n"
+          end
+          file.puts "#{pre}INCLUDE(\"#{$gen}/tecsgen_#{nsp}.cfg\");\n#{post}"
+        end
+      }
+      file.print "/* HRPPlugin 002 end */\n\n"
+      file.close
+
+      check_celltype_list = []
+
+      # 
+      #  ATT_MODの生成
+      #
+      Cell.get_cell_list2.each { |cell|
+        # すべてのセルを走査してセルタイプをチェック
+        ct = cell.get_celltype
+        if ct.class == Celltype && check_celltype_list.include?( ct ) == false
+          # チェック済みセルタイプに登録
+          check_celltype_list << ct
+
+          # 未チェックのセルタイプだった場合
+          # puts "check for ATT_MOD : #{ct.classget_global_name}"
+          # puts "check for ATT_MOD : #{ct.get_global_name}"
+
+          # カーネルAPIのコード，データはメモリ保護しない # HRP3 oyama delete by Takada's request
+          # next if HRPKernelObjectManager.include_celltype?( ct.get_name )
+
+          # 必要のないセルタイプのコード，データはメモリ保護しない
+          next if ! ct.need_generate?
+
+          # HRPのドメインリージョンを取得
+          regions = ct.get_domain_roots
+          regions_hrp = regions[ :HRP ]
+          dbgPrint "HRP domain in #{ct.get_name}: "
+          regions_hrp.each { |reg|
+            dbgPrint reg.get_name
+          }
+          # puts ""
+
+          # セル管理ブロックとスケルトンのメモリ保護
+          # gen_celltype_names_domain 相当の処理
+          if regions_hrp.include?( Region.get_root ) == false && regions_hrp.length > 1
+            # ドメインが複数で，OutOfDomainにセルが存在しないセルタイプの場合
+            # 共有のセル管理ブロックとスケルトンコードを登録する
+            file = AppFile.open( "#{$gen}/tecsgen.cfg" )
+            file.printf "%-60s/* HRPPlugin 003 */\n", "ATT_MOD(\"#{ct.get_global_name}_tecsgen.o\");"
+            file.close
+          end
+
+          regions_hrp.each { |reg|
+            if reg.is_root? 
+              nsp = ""
+            else
+              nsp = "_#{reg.get_global_name}"
+            end
+            file = AppFile.open( "#{$gen}/tecsgen#{nsp}.cfg" )
+            file.printf "%-50s/* HRPPlugin 004 */\n", "ATT_MOD(\"#{ct.get_global_name}#{nsp}_tecsgen.o\");"
+            file.close
+          }
+
+          # セルタイプコードがない場合はスキップ
+          next if ct.is_all_entry_inline? && ! ct.is_active?
+
+          # セルタイプコードのメモリ保護
+          # gen_celltype_names_domain2 相当の処理
+          if regions_hrp.include?( Region.get_root ) == true || regions_hrp.length > 1
+            # OutOfDomainにセルが存在するセルタイプの場合
+            # または，複数のドメインにセルが存在するセルタイプの場合
+            # セルタイプコードを共有するように登録する
+            file = AppFile.open( "#{$gen}/tecsgen.cfg" )
+          else
+            # OutOfDomainでない単一のドメインにセルが存在するセルタイプの場合
+            # セルタイプコードを専有するように登録する
+            file = AppFile.open( "#{$gen}/tecsgen_#{regions_hrp[0].get_global_name}.cfg" )
+          end
+
+          file.printf "%-50s/* HRPPlugin 005 */\n", "ATT_MOD(\"#{ct.get_global_name}.o\");"
+          file.close
+        else
+          # 何もしない
+        end
+      }
+
+      @@generate_memory_module = true
+    else
+      # 何もしない
+    end
+  end
+
+  #----- Inter Domain Join Set -----#
+  @@inter_domain_join_set = {}      #{entry_cell =>{domain_root=>count} }  Hash of inter domain join
+  def self.add_inter_domain_join_set join
+    rhs_cell = join.get_cell
+    dbgPrint "--------- add_inter_domain:#{join.get_owner.get_namespace_path} => #{join.get_cell.get_namespace_path}-----\n"
+    domain_root = join.get_owner.get_region.get_domain_root   # lhs cell's domain root
+    if @@inter_domain_join_set[ rhs_cell ] == nil then
+      @@inter_domain_join_set[ rhs_cell ] = []
+    end
+    # 左辺のドメインルートを記録
+    @@inter_domain_join_set[ rhs_cell ] << join
+  end
+  def self.get_inter_domain_join_set rhs_cell
+    if @@inter_domain_join_set[ rhs_cell ] then
+      @@inter_domain_join_set[ rhs_cell ].uniq!
+    else
+      @@inter_domain_join_set[ rhs_cell ] = []
+    end
+    return @@inter_domain_join_set[ rhs_cell ]
+  end
+  def self.get_inter_domain_join_roots rhs_cell
+    dbgPrint "--------- get_inter_domain #{rhs_cell.get_namespace_path} -----\n"
+    domain_roots = []
+    set = get_inter_domain_join_set rhs_cell
+    set.each{ |join|
+      dbgPrint "--------- get_inter_domain:#{join.get_owner.get_namespace_path} => #{join.get_cell.get_namespace_path}-----\n"
+      # if join.get_owner.get_region.get_domain_root.get_domain_type.get_option == "user" then
+        domain_roots << join.get_owner.get_region.get_domain_root
+      # end
+    }
+    return domain_roots.uniq
+  end
+
+  def self.get_sac_str cell
+    domain_roots = self.get_inter_domain_join_roots cell
+    delim = ""
+    acv = ""
+    cell_domain_root = cell.get_region.get_domain_root
+    if cell_domain_root.get_domain_type.get_kind != :OutOfDomain then
+      domain_roots << cell.get_region.get_domain_root  # 結合先のドメインも含める
+    end
+    domain_roots.each{ |dr|
+      case dr.get_domain_type.get_kind
+      when :kernel
+        acv += "#{delim}TACP_KERNEL"
+        delim = "|"
+      when :user
+        acv += "#{delim}TACP(#{dr.get_name})"
+        delim = "|"
+        if cell_domain_root.get_domain_type.get_kind != :OutOfDomain &&
+           dr.get_namespace_path != cell_domain_root.get_namespace_path then
+          cdl_error( "HRP9999 '$1': kernel object joined from other user domain. kernel object joined from multi-user-domain must be placed out of domain", cell.get_name )
+        end
+      when :OutOfDomain
+        if cell_domain_root.get_domain_type.get_kind == :OutOfDomain then
+          acv += "#{delim}TACP_SHARED"
+          delim = "|"
+        end
+      else
+        raise "unkown domain kind"
+      end
+    }
+    if acv == "" then
+      # 呼び先セルが無所属かつ、呼び元も無所属のみ、または結合無しの場合
+      acv = "TACP_SHARED"
+    end
+    sac_str = "{"
+    delim = ""
+    [:accessPattern1, :accessPattern2, :accessPattern3, :accessPattern4].each{ |acp|
+      init = (cell.get_attr_initializer acp).to_s
+      if init != "OMIT"
+        sac_str += delim + init
+      else
+        sac_str += delim + acv
+      end
+      delim = ", "
+    }
+    return sac_str + '}'
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPRPCPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPRPCPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPRPCPlugin.rb	(revision 398)
@@ -0,0 +1,415 @@
+# coding: utf-8
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#  $Id$
+#++
+
+require_tecsgen_lib "lib/GenOpaqueMarshaler.rb"
+require_tecsgen_lib "lib/GenParamCopy.rb"
+
+#= HRPRPCPlugin プラグイン
+# スループラグイン (through)
+# ・OpaqueMarshalerPlugin を使用してマーシャラセルタイプを生成する
+# ・マーシャラ、TDR、チャンネル、メッセージバッファを生成する
+#
+class HRPRPCPlugin < ThroughPlugin
+
+  include GenOpaqueMarshaler
+  include GenParamCopy
+
+  # RPCPlugin 専用のオプション
+  HRPRPCPluginArgProc = RPCPluginArgProc.dup  # 複製を作って元を変更しないようにする
+  HRPRPCPluginArgProc[ "noClientSemaphore"  ] = Proc.new { |obj,rhs| obj.set_noClientSemaphore rhs }
+  HRPRPCPluginArgProc[ "semaphoreCelltype"  ] = Proc.new { |obj,rhs| obj.set_semaphoreCelltype rhs }
+  @@isFirstInstance = true
+
+  #=== RPCPlugin の initialize
+  #  説明は ThroughPlugin (plugin.rb) を参照
+  def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
+    super
+    @b_noClientSemaphore = false
+    @semaphoreCelltype = "tSemaphore"
+    initialize_opaque_marshaler
+
+    # オプション：GenOpaqueMarshaler 参照
+    @plugin_arg_check_proc_tab = HRPRPCPluginArgProc
+    parse_plugin_arg
+
+    @rpc_channel_celltype_name = "tRPCPlugin_#{@TDRCelltype}_#{@channelCelltype}_#{@signature.get_name}"
+    @rpc_channel_celltype_file_name = "#{$gen}/#{@rpc_channel_celltype_name}.cdl"
+
+    if @signature.get_context == "non-task" then
+        cdl_error( "HRP9999 RPC cannot be applied to non-task context signature '$1'", @signature.get_name )
+    elsif @signature.get_context == "any" then
+        cdl_info( "HRP9999 RPC is applied to any context signature '$1'", @signature.get_name )
+    end
+
+    if @signature.need_PPAllocator?(true) then
+      if @PPAllocatorSize == nil then
+        cdl_error( "HRP9999 PPAllocatorSize must be speicified for pointer argments" )
+        # @PPAllocatorSize = 0   # 仮に 0 としておく (cdl の構文エラーを避けるため)
+      end
+    elsif @PPAllocatorSize then
+      cdl_warning( "HRP9999 PPAllocatorSize speicified in spite of PPAllocator unnecessary" )
+      @PPAllocatorSize = nil
+    end
+
+#    @signature.each_param{ |func_decl, param_decl|
+#      if func_decl.get_type.is_oneway? then
+#        if ( param_decl.get_size || param_decl.get_count ) && param_decl.get_string then
+#          cdl_error( "array of string not supported for oneway function in Transparent RPC" )  # mikan 文字列の配列
+#        elsif param_decl.get_string == -1 then
+#          cdl_error( "length unspecified string is not permited for oneway function in Transparent RPC" )  # mikan 長さ未指定文字列
+#        end
+#      end
+#    }
+
+    # 
+    #  tecsgen/tecs/rpcにincludeパスを通す
+    #  #include "tecs_rpc.h" を実現するために必要
+    #    大山:削除 Makefile.tecsgen に vpath, INCLUDES を入れるのは、よくない考え
+    #             TECSGEN.add_search_path で Makefile_templ に入れるのがよい
+    # if @@isFirstInstance
+    #     f = AppFile.open( "#{$gen}/Makefile.tecsgen" )
+    #     f.puts "INCLUDES := $(INCLUDES) -I $(TECSPATH) -I $(TECSPATH)/rpc"
+    #     f.puts "vpath %.c $(TECSPATH) $(TECSPATH)/rpc"
+    #     f.close()
+    #     @@isFirstInstance = false
+    # end
+  end
+
+  #=== plugin の宣言コード (celltype の定義) 生成
+  def gen_plugin_decl_code( file )
+
+    ct_name = "#{@ct_name}_#{@channelCelltype}"
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if @@generated_celltype[ ct_name ] == nil then
+      @@generated_celltype[ ct_name ] = [ self ]
+    else
+      @@generated_celltype[ ct_name ] << self
+      return
+    end
+
+    f = CFile.open( @rpc_channel_celltype_file_name, "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    f.print <<EOT
+import( <rpc.cdl> );
+import( <tMessageBufferCEP.cdl> );
+generate( OpaqueMarshalerPlugin, #{@signature.get_namespace_path}, "" );
+
+composite tOpaqueMarshaler_#{@signature.get_global_name}_through {
+  entry #{@signature.get_namespace_path} eThroughEntry;
+  call sTDR       cTDR;
+  [optional]
+    call sSemaphore cLockChannel;
+  [optional]
+    call sRPCErrorHandler cErrorHandler;
+
+  cell tOpaqueMarshaler_#{@signature.get_global_name} Marshaler{
+    cTDR          => composite.cTDR;
+    cLockChannel  => composite.cLockChannel;
+    cErrorHandler => composite.cErrorHandler;
+  };
+  composite.eThroughEntry => Marshaler.eClientEntry;
+};
+
+EOT
+
+    f.close
+  end
+
+  #===  through cell コードを生成
+  #
+  #
+  def gen_through_cell_code( file )
+
+    gen_plugin_decl_code( file )
+    file.print <<EOT
+import( <#{@rpc_channel_celltype_file_name}> );
+EOT
+
+    case @start_region.get_domain_root.get_domain_type.get_kind
+    when :kernel
+      tacp_str = "\"TACP_KERNEL"
+    when :user
+      tacp_str = "\"TACP(#{@start_region.get_domain_root.get_name})"
+    when :OutOfDomain
+      tacp_str = "\"TACP_SHARED"
+    end
+    # p "end_region=#{@end_region.get_name} kind=#{@end_region.get_domain_root.get_domain_type.get_kind}"
+    case @end_region.get_domain_root.get_domain_type.get_kind
+    when :kernel
+      tacp_str += "|TACP_KERNEL\""
+    when :user
+      tacp_str += "|TACP(#{@end_region.get_domain_root.get_name})\""
+    when :OutOfDomain
+      tacp_str += "|TACP_SHARED\""
+    end
+    nest_str = ""
+    file.print <<EOT
+#{nest_str}  //  MessageBuffer client=>server
+#{nest_str}  cell tMessageBuffer #{@clientChannelCell}Body0{
+#{nest_str}      maxMessageSize = 64;      /* This value must be same as MessageBufferCEP's buffer size */
+#{nest_str}      bufferSize     = 128;
+#{nest_str}      accessPattern1 = C_EXP( #{tacp_str} );
+#{nest_str}      accessPattern2 = C_EXP( #{tacp_str} );
+#{nest_str}      accessPattern3 = C_EXP( #{tacp_str} );
+#{nest_str}      accessPattern4 = C_EXP( #{tacp_str} );
+#{nest_str}  };
+EOT
+    file.print <<EOT
+
+#{nest_str}  //  MessageBuffer server=>client
+#{nest_str}  cell tMessageBuffer #{@clientChannelCell}Body1{
+#{nest_str}      maxMessageSize = 64;      /* This value must be same as MessageBufferCEP's buffer size */
+#{nest_str}      bufferSize     = 128;
+#{nest_str}      accessPattern1 = C_EXP( #{tacp_str} );
+#{nest_str}      accessPattern2 = C_EXP( #{tacp_str} );
+#{nest_str}      accessPattern3 = C_EXP( #{tacp_str} );
+#{nest_str}      accessPattern4 = C_EXP( #{tacp_str} );
+#{nest_str}  };
+EOT
+
+    ##### クライアント側のセルの生成 #####
+    nest = @start_region.gen_region_str_pre file
+    nest_str = "  " * nest
+
+    # セマフォの生成
+    if @b_noClientSemaphore == false then
+      file.print <<EOT
+#{nest_str}  //  Semaphore for Multi-task use ("specify noClientSemaphore" option to delete this)
+#{nest_str}  cell #{@semaphoreCelltype} #{@serverChannelCell}_Semaphore{
+#{nest_str}    initialCount = 1;
+#{nest_str}  };
+EOT
+    end
+
+    # クライアント側チャンネル (tMessageBufferCEP)の生成
+    # チャンネルは必ずリージョン下にあるので、 '::' でつなぐ (でなければ、ルートリージョンにないかチェックが必要）
+
+    file.print <<EOT
+#{nest_str}  //  Client Side Channel
+#{nest_str}  cell tMessageBufferCEP #{@clientChannelCell}_CEP{
+#{nest_str}      cMessageBuffer0 = #{@clientChannelCell}Body0.eMessageBuffer;
+#{nest_str}      cMessageBuffer1 = #{@clientChannelCell}Body1.eMessageBuffer;
+#{nest_str}  };
+
+#{nest_str}  //  Client Side TDR
+#{nest_str}  cell tTDR #{@clientChannelCell}_TDR{
+#{nest_str}    cChannel = #{@clientChannelCell}_CEP.eChannel;
+#{nest_str}  };
+
+#{nest_str}  //  Marshaler
+EOT
+
+    # セマフォの結合文
+    if @b_noClientSemaphore == false then
+      semaphore = "#{nest_str}    cLockChannel = #{@serverChannelCell}_Semaphore.eSemaphore;\n"
+    else
+      semaphore = ""
+    end
+
+    ### クライアント側チャンネル (マーシャラ+TDR)の生成 ###
+    cell = @next_cell
+    # アロケータの指定があるか？
+    if cell.get_allocator_list.length > 0 then
+
+      file.print nest_str
+      file.print "[allocator("
+
+      delim = ""
+      cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc|
+
+        alloc_str = alloc.to_s
+        subst = @substituteAllocator[alloc_str.to_sym]
+        if subst then
+          alloc_str = subst[2]+"."+subst[3]
+        end
+
+        file.print delim
+        delim = ",\n"        # 最終行には出さない
+
+        if subsc then        # 配列添数
+          subsc_str = '[#{subsc}]'
+        else
+          subsc_str = ""
+        end
+
+        eport = "eThroughEntry" #RPCの受け口名に変更
+        file.print nest_str
+        file.print  "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc_str}"
+      end
+
+      file.puts ")]"
+    end
+
+    if @clientErrorHandler then
+      clientErrorHandler_str = "#{nest_str}    cErrorHandler = #{@clientErrorHandler};\n"
+    else
+      clientErrorHandler_str = ""
+    end
+
+    file.print <<EOT
+#{nest_str}  cell tOpaqueMarshaler_#{@signature.get_global_name}_through #{@cell_name} {
+#{nest_str}    cTDR = #{@clientChannelCell}_TDR.eTDR;
+#{clientErrorHandler_str}#{semaphore}#{nest_str}  };
+EOT
+    ### END: クライアント側チャンネル (マーシャラ+TDR)の生成 ###
+    @start_region.gen_region_str_post file
+    file.print "\n\n"
+
+    ##### サーバー側のセルの生成 #####
+    nest = @end_region.gen_region_str_pre file
+    nest_str = "  " * nest
+
+    if @serverErrorHandler then
+      serverErrorHandler_str = "#{nest_str}    cErrorHandler = #{@serverErrorHandler};\n"
+    else
+      serverErrorHandler_str = ""
+    end
+
+    if @b_genOpener then
+      opener = "#{nest_str}    cOpener       = #{@serverChannelCell}.eOpener;\n"
+    else
+      opener = ""
+    end
+
+    # サーバー側チャンネル (tMessageBufferCEP)
+    if @PPAllocatorSize then
+      alloc_cell =<<EOT
+
+#{nest_str}  cell tPPAllocator #{@serverChannelCell}_PPAllocator {
+#{nest_str}    heapSize = #{@PPAllocatorSize};
+#{nest_str}  };
+EOT
+      alloc_call_port_join = "#{nest_str}    cPPAllocator = #{@serverChannelCell}_PPAllocator.ePPAllocator;\n"
+    else
+      alloc_cell = ""
+      alloc_call_port_join = ""
+    end
+
+    file.print <<EOT
+#{nest_str}  //  Server Side Channel
+#{nest_str}  cell tMessageBufferCEP #{@serverChannelCell}_CEP{
+#{nest_str}      cMessageBuffer0 = #{@clientChannelCell}Body1.eMessageBuffer;
+#{nest_str}      cMessageBuffer1 = #{@clientChannelCell}Body0.eMessageBuffer;
+#{nest_str}  };
+EOT
+
+    # サーバー側TDR
+    file.print <<EOT
+
+#{nest_str}  //  Server Side TDR
+#{nest_str}  cell tTDR #{@serverChannelCell}_TDR{
+#{nest_str}    cChannel = #{@serverChannelCell}_CEP.eChannel;
+#{nest_str}  };
+EOT
+
+    if @next_cell_port_subscript then
+      subscript = '[' + @next_cell_port_subscript.to_s + ']'
+    else
+      subscript = ""
+    end
+
+    # サーバー側チャンネル (アンマーシャラ)
+    file.print <<EOT
+#{alloc_cell}
+#{nest_str}  //  Unmarshaler
+#{nest_str}  cell tOpaqueUnmarshaler_#{@signature.get_global_name} #{@serverChannelCell}_Unmarshaler {
+#{nest_str}    cTDR        = #{@serverChannelCell}_TDR.eTDR;
+#{nest_str}    cServerCall = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
+#{alloc_call_port_join}#{serverErrorHandler_str}#{nest_str}  };
+EOT
+
+    # サーバー側タスクメイン
+    file.print <<EOT
+
+#{nest_str}  //  Unmarshaler Task Main
+#{nest_str}  cell #{@taskMainCelltype} #{@serverChannelCell}_TaskMain {
+#{nest_str}    cMain         = #{@serverChannelCell}_Unmarshaler.eService;
+#{opener}#{nest_str}  };
+EOT
+
+    # サーバー側タスク
+    file.print <<EOT
+
+#{nest_str}  //  Unmarshaler Task
+#{nest_str}  cell #{@taskCelltype} #{@serverChannelCell}_Task {
+#{nest_str}    cTaskBody = #{@serverChannelCell}_TaskMain.eMain;
+#{nest_str}    priority  = #{@taskPriority};
+#{nest_str}    stackSize = #{@stackSize};
+#{nest_str}    attribute = C_EXP( "TA_ACT" );  /* mikan : marshaler task starts at beginning */
+#{nest_str}  };
+EOT
+    @end_region.gen_region_str_post file
+  end
+
+
+  #=== プラグイン引数 noClientSemaphore のチェック
+  def set_noClientSemaphore rhs
+    rhs = rhs.to_sym
+    if rhs == :true then
+      @b_noClientSemaphore = true
+    elsif rhs == :false then
+      @b_noClientSemaphore = false
+    else
+      cdl_error( "RPCPlugin: specify true or false for noClientSemaphore" )
+    end
+  end
+
+  #=== プラグイン引数 semaphoreCelltype のチェック
+  def set_semaphoreCelltype rhs
+    @semaphoreCelltype = rhs.to_sym
+    nsp = NamespacePath.analyze( @semaphoreCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: semaphoreCelltype '#{rhs}' not celltype or not defined" )
+    end
+  end
+
+  #=== NamespacePath を得る
+  # 生成するセルの namespace path を生成する
+  def get_cell_namespace_path
+#    nsp = @region.get_namespace.get_namespace_path
+    nsp = @start_region.get_namespace_path
+    return nsp.append( @cell_name )
+  end
+
+end
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPSVCPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPSVCPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPSVCPlugin.rb	(revision 398)
@@ -0,0 +1,861 @@
+# coding: utf-8
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#  $Id$
+#++
+
+# mikan through plugin: namespace が考慮されていない
+# これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必要がある
+# tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl
+
+# 以下を仮定（制限事項）
+#  呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
+#  有符号、無符号でサイズが同じ
+
+class SVCManage
+    #
+    #  @@id: TECSのプラグインで生成した拡張サービスコールに割り当てるid
+    #        実際の拡張サービスコールIDは，TFN_TECSGEN_ORIGINで下駄を
+    #        履かせた値となる
+    #        TFN_TECSGEN_ORIGINは，hrp3/include/extsvc_fncode.h で定義
+    #        される
+    #  @@func_ids: 拡張サービスコールの関数名と拡張サービスコールIDを
+    #  　　　対応づけるハッシュ
+    #
+    @@id = 0
+    @@func_ids = {}
+    def initialize()
+        # 
+      #  本クラスはインスタンスを持たない仮想的なクラスである
+        #
+        raise "class #{self.class.name} shall not have instances"
+    end
+    def self.get_func_id func_name
+        return @@func_ids[ func_name ]
+    end
+    def self.set_func_id func_name
+        @@func_ids[ func_name ] = self.assign_id
+        # puts @@func_ids[ func_name ]
+    end
+    def self.get_id
+        return @@id
+    end
+    def self.set_id id
+        @@id = id
+    end
+    def self.assign_id
+        assignedId = @@id
+        @@id += 1
+        return assignedId
+    end
+end
+
+#
+#  拡張サービスコールを用いたドメイン間通信の
+#  throughプラグイン
+#  HRPドメインプラグインによって挿入される
+#  前提条件: 呼出し先がカーネルオブジェクトかどうかの判定はHRPドメインプラグイン
+#  　　　　　で実施されるため，ここでは判定しないこととした
+#
+class HRPSVCPlugin < ThroughPlugin
+
+  NUM_SVC_ARG_MAX = 5              # HRP3 の拡張サービスコールで扱うことのできる引数の最大個数
+
+  @@generated_celltype ={}    # セルタイプの重複排除用
+  @@generated_cell = {}       # セルの重複排除用
+
+  def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
+    super
+
+    # 受け口配列の場合、配列添数ごとに別のセルタイプとする
+    # セルタイプをシングルトン化したいため。
+    # さもないと、セルを識別する引数を渡す必要があり、NUM_SVC_ARG_MAX(5) つしか渡せない引数の一つを消費することになるため。
+    if @next_cell_port_subscript then
+      subscript = "__" + @next_cell_port_subscript.to_s
+    else
+      subscript = ""
+    end
+    @ct_name_body = "#{@ct_name}SVCBody_#{@next_cell.get_name}_#{@next_cell_port_name}#{subscript}".to_sym
+    @ct_name = "#{@ct_name}SVCCaller_#{@next_cell.get_name}_#{@next_cell_port_name}#{subscript}".to_sym
+    @cell_name_body = "#{@cell_name}SVCBody".to_sym
+    @cell_name = "#{@cell_name}SVCCaller".to_sym
+    # puts "%%%% "
+    # p @next_cell.get_name
+    # p @caller_cell.get_name
+    @b_printed_include_stdint = false
+    check_signature signature
+  end
+
+  #=== NamespacePath を得る
+  # 生成するセルの namespace path を生成する
+  def get_cell_namespace_path
+#    nsp = @region.get_namespace.get_namespace_path
+    nsp = @start_region.get_namespace_path
+    return nsp.append( @cell_name )
+  end
+
+  def gen_plugin_decl_code( file )
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if @@generated_celltype[ @ct_name_body ] == nil then
+        @@generated_celltype[ @ct_name_body ] = [ self ]
+        file2 = CFile.open( "#{$gen}/#{@ct_name_body}.cdl", "w" )
+        file2.print <<EOT
+import_C( "t_stdlib.h" );
+
+/* HRPSVC0001 */
+[active,singleton]
+celltype #{@ct_name_body} {
+    call #{@signature.get_name} #{@call_port_name};
+    FACTORY {
+		write("$ct$_tecsgen.h", "#include \\"kernel_cfg.h\\"");
+    };
+};
+EOT
+        file2.close
+    else
+      @@generated_celltype[ @ct_name_body ] << self
+    end
+    file.print "import( \"#{$gen}/#{@ct_name_body}.cdl\" );\n"
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if @@generated_celltype[ @ct_name ] == nil then
+        @@generated_celltype[ @ct_name ] = [ self ]
+        file2 = CFile.open( "#{$gen}/#{@ct_name}.cdl", "w" )
+        file2.print <<EOT
+/* HRPSVC0002 */
+celltype #{@ct_name} {
+    entry #{@signature.get_name} #{@entry_port_name};
+    FACTORY {
+		write("$ct$_tecsgen.h", "#include \\"extsvc_fncode.h\\"");
+    };
+};
+EOT
+        file2.close
+    else
+      @@generated_celltype[ @ct_name ] << self
+    end
+    file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
+
+=begin
+    # TODO: send. receive 対応
+    send_receive = []
+    if @signature != nil then
+      @signature.each_param{ |fd,param|
+        dir =param.get_direction
+        case dir
+        when :SEND, :RECEIVE
+          send_receive << [ dir, fd, param ]
+        end
+      }
+    end
+=end
+
+=begin
+composite #{@ct_name} {
+    entry #{@signature.get_name} #{@entry_port_name};
+    call #{@signature.get_name} #{@call_port_name};
+
+    cell #{@ct_name}Client #{@cell_name}Client{
+    };
+
+    [active]
+    cell #{@ct_name}Server #{@cell_name}Server{
+        #{@call_port_name} => composite.#{@call_port_name};
+    };
+
+    composite.#{@entry_port_name} => #{@cell_name}.#{@entry_port_name};
+};
+=end
+
+  end
+
+  #===  through cell コードを生成
+  #
+  #
+  def gen_through_cell_code( file )
+
+    # gen_plugin_decl_code( file )  this is called from super.
+
+    # セルを探す
+    # path =["::",@next_cell.get_name]  # mikan namespace
+    # cell = Namespace.find( path )
+    # cell = Namespace.find( @next_cell.get_namespace_path )
+
+    ##### クライアント側のセルの生成 #####
+    # file.print "[domain(HRP, \"kernel\")]"
+    nest = @start_region.gen_region_str_pre file
+    nest_str = "  " * nest
+
+    # クライアント側チャンネルの生成
+    # 拡張サービスコール呼出し
+    file.print <<EOT
+/* HRPSVC0003 */
+#{nest_str}  //  Client Side Channel
+#{nest_str}  cell #{@ct_name} #{@cell_name}{
+#{nest_str}  };
+
+EOT
+
+    @start_region.gen_region_str_post file
+    file.print "\n\n"
+
+    ##### サーバー側のセルの生成 #####
+    # print "######  #{@cell_name_body} ... #{@ct_name_body} #{@@generated_cell[ @ct_name_body ].class}  #####\n"
+
+    if @@generated_cell[ @ct_name_body ] then
+      file.print "/* cell #{@ct_name_body} #{@@generated_cell[ @ct_name_body ]}: already generated. */\n"
+    else
+      @@generated_cell[ @ct_name_body ] = @cell_name_body
+      nest = @end_region.gen_region_str_pre file
+      nest_str = "  " * nest
+      if @next_cell_port_subscript then
+        subscript = '[' + @next_cell_port_subscript.to_s + ']'
+      else
+        subscript = ""
+      end
+
+      # サーバー側チャンネルの生成 
+      # 拡張サービスコール本体
+      file.print <<EOT
+
+/* HRPSVC0004 */
+#{nest_str}  //  Server Side Channel
+#{nest_str}  cell #{@ct_name_body} #{@cell_name_body}{
+#{nest_str}    #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
+#{nest_str}  };
+EOT
+
+      @end_region.gen_region_str_post file
+
+      file2 = AppFile.open( "#{$gen}/tecsgen.cfg" )
+      file2.print "\n/* Generated by HRPSVCPlugin */\n\n"
+      file2.print <<EOT
+/* HRPSVC0005 */
+#include "#{@ct_name_body}_factory.h"
+EOT
+      file2.close
+
+      # callee_cell のget_restricted_regions を呼び出しておく
+      # restrict が参照された印をつけるため
+      @callee_cell.get_restricted_regions( :dummy_entry_name, :dummy_func_name )
+    end
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     通常であれば、ジェネレータは受け口関数のテンプレートを生成する
+  #     プラグインの場合、変更する必要のないセルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+        # puts "generate ep_func for #{ct_name}"
+
+        #
+        #  拡張サービスコール呼出し側の関数生成
+        #
+        #  完成形のイメージ
+        #  
+        # ER_UINT
+        # eThroughEntry_write(CELLIDX idx, const char* buffer, uint_t length)
+        # {
+        #   ER_UINT  retval;
+        #   tHRPSVCPlugin_<Sig>SVCCaller_<Cell>_<Entry>_CB    *p_cellcb;
+        #   if( VALID_IDX( idx ) ){
+        #       p_cellcb = tHRPSVCPlugin_<Sig>SVCBody_<Cell>_<Entry>_GET_CELLCB(idx);
+        #   }else{
+        #       /* エラー処理コードをここに記述 */
+        #   }
+        # 
+        #   retval = (ER_UINT)cal_svc( TFN_TECSGEN_ORIGIN + svcid, 
+        #                              (intptr_t)par1, (intptr_t)par2, 0, 0, 0 );
+        #
+        #   return retval;
+        # }
+
+        if ! func_type.get_type.kind_of?( VoidType ) then
+            file.print( "  #{func_type.get_type_str}  retval;\n" )
+        end
+
+        # p "celltype_name, sig_name, func_name, func_global_name"
+        # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
+
+        delim = ""
+        if ! func_type.get_type.kind_of?( VoidType ) then
+            file.print( "  retval = (#{func_type.get_type_str})" )
+        else
+            file.print( "  " )
+        end
+
+        #file.print( "#{@call_port_name}_#{func_name}(" )
+        SVCManage.set_func_id( "#{@ct_name_body}_#{func_name}" )
+        svcid = SVCManage.get_func_id( "#{@ct_name_body}_#{func_name}" )
+        #file.print( "cal_svc( #{@ct_name_body}_#{func_name}" )
+        file.print( "cal_svc( TFN_TECSGEN_ORIGIN + #{svcid.to_s}" )
+
+        #    if ( ! b_singleton ) then
+        #      file.print( " tecs_this" )
+        #      delim = ","
+        #    end
+
+        i = 0
+        passed_param = {}
+        params.each{ |param|
+            delim = ","
+            file.printf( "#{delim} (intptr_t)#{param.get_name}" )
+            passed_param[i] = param.get_name
+            i += 1
+        }
+
+        while(i < NUM_SVC_ARG_MAX) do
+            delim = ","
+            file.printf( "#{delim} 0" )
+            passed_param[i] = "par#{i+1}"
+            i += 1
+        end
+
+        file.print( " );\n\n" )
+
+        if ! func_type.get_type.kind_of?( VoidType ) then
+            file.print( "  return retval;\n" )
+        end
+
+        #
+        #  拡張サービスコール本体側の関数生成
+        #
+        #  完成形のイメージ
+        #  
+        # ER_UINT
+        # eThroughEntry_write(CELLIDX idx, const char* buffer, uint_t length)
+        # {
+        #   ER_UINT  retval;
+        #   tHRPSVCPlugin_<Sig>SVCBody_<Cell>_<Entry>_CB    *p_cellcb;
+        #   if( VALID_IDX( idx ) ){
+        #       p_cellcb = tHRPSVCPlugin_<Sig>SVCBody_<Cell>_<Entry>_GET_CELLCB(idx);
+        #   }else{
+        #       /* エラー処理コードをここに記述 */
+        #   }
+        # 
+        #   retval = (ER_UINT)cal_svc( TFN_TECSGEN_ORIGIN + svcid, 
+        #                              (intptr_t)par1, (intptr_t)par2, 0, 0, 0 );
+        #
+        #   return retval;
+        # }
+            file2 = AppFile.open( "#{$gen}/#{@ct_name_body}.c" )
+            if @b_printed_include_stdint == false then
+              file2.print <<EOT
+#ifndef SIZE_MAX
+#define  SIZE_MAX   (~0UL)
+#endif
+
+EOT
+              @b_printed_include_stdint = true
+            end
+
+            if func_type.get_type.kind_of?( VoidType ) then
+                retval_assign = ""
+            else
+                retval_assign = "retval = (ER_UINT)"
+            end
+
+            file2.print <<EOT
+/* HRPSVC0006 */
+ER_UINT
+#{@ct_name_body}_#{func_name}(intptr_t #{passed_param[0]}, intptr_t #{passed_param[1]}, intptr_t #{passed_param[2]}, intptr_t #{passed_param[3]}, intptr_t #{passed_param[4]}, ID cdmid)
+{
+    ER_UINT retval = E_OK;
+
+EOT
+
+            # 
+            #  エラーチェック処理の生成
+            #
+
+            # 
+            #  呼出し元ドメインのチェック
+            #   * private method: gen_caller_check_code参照
+            #
+            generated_check_code = gen_caller_check_code(func_name)
+            check_code = generated_check_code["check_code"]
+            user_cannot_callable = generated_check_code["user_cannot_callable"]
+
+            # 
+            #  パラメータにポインタが存在する場合，呼出し元タスクに対する
+            #  アクセス権のチェック処理を出力する
+            #  ※ cdmidがカーネルドメイン(拡張サービスコール呼出し中のユーザ
+            #    ドメインを含む)であればprb_memの処理をスキップし，初段の
+            #    拡張サービスコールのみprb_memを呼出し元タスクに発行する
+            #
+            num = 0
+            params.each{ |param|
+                if param.get_declarator.get_ptr_level > 0 then
+                    align_check_str = "!ALIGN_TYPE(#{passed_param[num]}, #{param.get_type.get_referto.get_type_str}) || "
+                  
+                    if param.get_type.get_referto.kind_of?(IntType) then
+                        case param.get_type.get_referto.get_bit_size
+                        when -11, -1, 8   # char, char_t, int8_t (無符号含む)
+                        #
+                        #  charデータの場合，ALIGN_TYPEは必ずTRUE
+                        #  となるので，エラーチェックを省略
+                        #  char型の@bit_sizeは-11
+                        #  tecsgen/tecslib/core/types.rbを参照
+                        #
+                          align_check_str = ""
+                        end
+                    end
+                    if param.get_direction == :IN then
+                        #
+                        #  入力([in])のポインタパラメータは，呼出し元タスクに
+                        #  TPM_READ(読出し可能)のアクセス権が必要
+                        #
+                        # 二重ポインタが不可のため、size_is と string が同時に設定されることはない
+                        prb_func = "prb_mem"
+                        if param.get_size then
+                          size_str = param.get_size.to_s
+                        elsif param.get_string == -1 then
+                          size_str = "SIZE_MAX"
+                          prb_func = "prb_str"
+                        elsif param.get_string then
+                          size_str = param.get_string.to_s
+                          prb_func = "prb_str"
+                        else
+                          size_str = "1"
+                        end
+                        check_code.concat <<EOT
+        /* HRPSVC0007 */
+        if (#{align_check_str}#{prb_func}((void *)#{passed_param[num]}, sizeof(#{param.get_type.get_referto.get_type_str}) * (#{size_str}), TSK_SELF, TPM_READ) != E_OK) {
+            return E_MACV;
+        }
+EOT
+
+                    elsif param.get_direction == :OUT || param.get_direction == :INOUT then
+                        #
+                        #  出力([out])のポインタパラメータは，呼出し元タスクに
+                        #  TPM_WRITE(書込み可能)のアクセス権が必要
+                        #
+                        prb_func = "prb_mem"
+                        if param.get_size then
+                          size_str = param.get_size.to_s
+                        elsif param.get_string then          # 引数なしの string はない
+                          size_str = param.get_string.to_s
+                          # prb_func = "prb_str"             # out, inout の場合、必ず領域を確保する. prb_mem を用いる
+                        else
+                          size_str = "1"
+                        end
+                        check_code.concat <<EOT
+        /* HRPSVC0008 */
+        if (#{align_check_str}#{prb_func}((void *)#{passed_param[num]}, sizeof(#{param.get_type.get_referto.get_type_str}) * (#{size_str}), TSK_SELF, TPM_WRITE) != E_OK) {
+            return E_MACV;
+        }
+EOT
+
+                    end
+                end
+                num += 1
+            }
+
+            # 
+            #  呼出し元がカーネルドメインのみ許可されている場合，
+            #  すべてのユーザドメインからの呼出しに対し，E_OACVを返す
+            #
+            if user_cannot_callable
+                check_code = "\t\treturn E_OACV;"
+            end
+
+            if check_code != ""
+                # 
+                #  呼出し元がカーネルドメインの場合，アクセス権のチェック
+                #  処理をスキップさせる
+                #
+                file2.print <<eot
+    if (cdmid != TDOM_KERNEL) {
+#{check_code}
+    }
+eot
+            end
+
+            # 
+            #  拡張サービスコール本体(本来の受け口関数)を呼び出す
+            #
+            file2.print"    #{retval_assign}#{@call_port_name}_#{func_name}("
+
+            delim = ""
+            num = 0
+            params.each{ |param|
+                file2.print "#{delim}"
+                delim = ", "
+                file2.print "(#{param.get_type.get_type_str})"
+                file2.print passed_param[num]
+                file2.print param.get_type.get_type_str_post
+                num += 1
+            }
+
+            file2.print ");\n"
+
+            file2.print "\n    return retval;\n"
+            file2.print "}\n\n"
+
+            file2.close
+
+            # 
+            #  拡張サービスコールの登録
+            #
+            file2 = AppFile.open( "#{$gen}/tecsgen.cfg" )
+            file2.print "\n/* Generated by HRPSVCPlugin */\n\n"
+            file2.print <<EOT
+/* HRPSVC0009 */
+KERNEL_DOMAIN{
+    DEF_SVC( TFN_TECSGEN_ORIGIN + #{svcid.to_s}, { TA_NULL, #{@ct_name_body}_#{func_name}, SSZ_#{func_global_name} } );
+}
+EOT
+            file2.close
+
+            # 
+            #  拡張サービスコール登録に必要な情報をヘッダに出力
+            #   - 拡張サービスコール呼出し時のチェックで使用するスタックサイズを出力
+            #   - 拡張サービスコールとして登録する関数名のextern宣言を出力
+            #
+            file2 = AppFile.open( "#{$gen}/#{@ct_name_body}_factory.h" )
+            file2.print "\n/* Generated by HRPSVCPlugin */\n\n"
+            file2.print <<EOT
+/* HRPSVC0010 */
+#ifndef SSZ_#{func_global_name}
+#define SSZ_#{func_global_name}	DefaultExtsvcStackSize
+#endif /* SSZ_#{func_global_name} */
+
+/* HRPSVC0011 */
+extern ER_UINT #{@ct_name_body}_#{func_name}(intptr_t par1, intptr_t par2, intptr_t par3, intptr_t par4, intptr_t par5, ID cdmid);
+EOT
+            file2.close
+  end
+
+  def get_callee_cell
+      return @callee_cell
+  end
+
+  def get_caller_cell
+      return @caller_cell
+  end
+
+  def get_callee_ep_name
+      return @join.get_port_name
+  end
+
+  private
+  # 
+  #  拡張サービスコール本体における，呼出し元チェックのコードを
+  #  出力する
+  #  gen_ep_func_body からのみ呼び出される
+  #  引数: 対象の関数名
+  #  返り値: 下記のハッシュ
+  #    {"check_code"=>出力するエラーチェックコード, 
+  #     "user_cannot_callable"=>ユーザドメインが呼出し不可能かどうかのフラグ}
+  #
+  def gen_caller_check_code(func_name)  
+    dbgPrint "gen_caller_check_code(func_name): #{@callee_cell.get_name}\n"
+      # 
+      #  エラーチェック処理
+      #
+      check_code = ""
+      user_cannot_callable = false
+      all_domain_callable = false
+      caller_unrestricted = false
+
+      # 
+      #  呼出し元ドメインのチェック処理
+      #  callable_domains: 拡張サービスコールを呼出し可能なドメインのリスト
+      #    - 無所属のセルから結合されている場合，すべてのセルに対して，
+      #    　callable?をチェックし，呼出し可能なすべてのドメインを返す
+      #    - 無所属以外のセルから結合されている場合，そのセルに対して
+      #      callable?をチェックし，呼出し可能であれば，そのドメインを返す
+      #
+      callable_domains = []
+      @@generated_celltype[ @ct_name_body ].each { |svcplugin|
+          if svcplugin.get_caller_cell.get_region.get_domain_root.get_domain_type.get_option == "OutOfDomain"
+              # 無所属かつ active な場合も、restrict に従う
+              # if svcplugin.get_caller_cell.get_celltype.is_active?
+              #    #
+              #    #  無所属かつactiveなセルは、TECSから存在が認識されていないのを
+              #    #  含む任意のドメインから呼び出される可能性も存在する
+              #    #
+              #    caller_unrestricted = true
+              # else
+              #     # 
+              #     #  無所属から接続されている場合は，すべてのセルの
+              #     #  restrictをチェック
+              #     #
+              #     Cell.get_cell_list2.each { |cell|
+              #         if cell.callable?(svcplugin.get_callee_cell, svcplugin.get_callee_ep_name, func_name)
+              #             callable_domains << cell.get_region.get_domain_root
+              #         end
+              #     }
+              #     print "callable_domains: "
+              #     callable_domains.each{ |dm| print dm.get_name, " " }
+              #     print "\n"
+              # end
+
+              # restrict 指定がある場合には、それに従う。さもなければ、チェックしない
+              callable_domains = @callee_cell.get_restricted_regions( get_callee_ep_name, func_name )
+              if callable_domains == nil then
+                caller_unrestricted = true
+              end
+              #  print "restrict_list: "
+              #  delim = ""
+              #  callable_domains.each{ |domain|
+              #    print delim, domain
+              #    delim = ", "
+              #  }
+              #  print "\n"
+
+          elsif svcplugin.get_caller_cell.callable?( svcplugin.get_callee_cell, svcplugin.get_callee_ep_name, func_name )
+              # 
+              #  特定のドメインから接続されている場合は，呼出し元セルの
+              #  restrictをチェック
+              #
+              callable_domains << svcplugin.get_caller_cell.get_region.get_domain_root
+          else
+              # 
+              #  無所属から結合されておらず，特定の呼出し元ドメインにアクセス権
+              #  がない場合，callable_domainsは空となる
+              #
+              # pp "#{svcplugin.get_caller_cell.get_name} cannot call #{svcplugin.get_callee_cell.get_name}_#{svcplugin.get_callee_ep_name}_#{func_name}"
+          end
+      }
+
+      if caller_unrestricted
+          # pp "caller_unrestricted: #{@ct_name_body}"
+          return {"check_code"=>"", "user_cannot_callable"=>false}
+      end
+
+      # 
+      #  重複を削除
+      #
+      callable_domains.uniq!
+      # 
+      #  無所属に対するドメインチェックは実施しない
+      #  カーネルドメインに対するドメインチェックは実施しない
+      #
+      callable_domains = callable_domains.select { |domain|
+          ((domain.get_domain_type.get_option != "OutOfDomain") && \
+           (domain.get_domain_type.get_option != "kernel"))
+      }
+      # pp "callable_domains"
+      # pp callable_domains.map{|domain| domain.get_name }
+      # 
+      #  すべてのユーザドメインから呼出し可能な場合，ドメインチェックは
+      #  実施しない
+      #
+      all_domain_regions = DomainType.get_domain_regions[:HRP].select { |reg|
+          ((reg.get_domain_type.get_option != "OutOfDomain") && \
+           (reg.get_domain_type.get_option != "kernel"))
+
+      }
+      # pp "all domains"
+      # pp all_domain_regions.map {|reg| reg.get_name}
+      if all_domain_regions.all? {|reg| callable_domains.include?(reg)}
+          all_domain_callable = true
+      end
+
+      # 
+      #  呼出し元ドメインのチェック処理本体の生成
+      #
+      if callable_domains.length == 0
+        dbgPrint "callable_domain.length = 0\n"
+          # 
+          #  ユーザドメインから呼出し不可能な場合は
+          #  個別のエラーチェックはせず，問答無用でE_OACVを返す
+          #
+          user_cannot_callable = true
+      elsif callable_domains.length == 1
+        dbgPrint "callable_domain.length = 1\n"
+          # 
+          #  呼出し可能なユーザドメインが単一の場合は
+          #  cdmid != <domain名> の形式でチェックする
+          #
+          check_code += "\t/* HRPSVC0012.1 */\n"
+          check_code += "\tif (cdmid != #{callable_domains[0].get_name}) {\n"
+      elsif callable_domains.length > 1 && !all_domain_callable
+        dbgPrint "callable_domain.length > 1 && not all_domains \n"
+          # 
+          #  呼出し可能なユーザドメインが複数の場合は
+          #  TACP(cdmid) & (TACP(<domain名>) | ...) != 0U
+          #  の形式でチェックする
+          #
+          check_code += "\t/* HRPSVC0012.2 */\n"
+          check_code += "\tif((TACP(cdmid) & ("
+          check_code += (callable_domains.map { |domain| "TACP(#{domain.get_name})"}).join("|")
+          check_code += ")) != 0U) {\n"
+      else
+        dbgPrint "callable_all_domains\n"
+      end
+      if check_code != ""
+          # 
+          #  呼出し可能なユーザドメインのチェックがある場合は
+          #  エラーコードを返すためのコードを出力する
+          #
+          check_code += <<EOS
+            /* HRPSVC0013 */
+            return E_OACV;
+        }
+EOS
+      end
+
+      return {"check_code"=>check_code, "user_cannot_callable"=>user_cannot_callable}
+  end
+
+  #---------------------------------------------------------#
+  #=== シグニチャのチェック
+  def check_signature signature
+    signature.get_function_head_array.each{ |fh|
+      type = fh.get_return_type
+      check_return_type signature, fh, type
+      if fh.get_paramlist.get_items.length > NUM_SVC_ARG_MAX then
+        cdl_error( "HSV0005 $1.$2: # of parameter more than #{NUM_SVC_ARG_MAX}", signature.get_name, fh.get_name )
+      end
+      fh.get_paramlist.get_items.each{ |param|
+        check_param signature, fh, param
+      }
+    }
+  end
+  #=== 戻り値の型のチェック
+  # ER, ER_UINT は推奨される型
+  # 整数、ブール、void は可能、他は不可
+  def check_return_type signature, fh, type
+    ot = type.get_original_type
+    if( type.get_type_str == "ER" || type.get_type_str == "ER_UINT" ) then
+      # OK!
+    elsif ot.kind_of?( IntType ) || ot.kind_of?( VoidType ) || ot.kind_of?( BoolType ) then
+      cdl_warning( "HSW0001 $1.$2: $3 return type cannot get access violation error", signature.get_name, fh.get_name, type.get_type_str.downcase )
+      check_intptr "#{signature.get_name}.#{fh.get_name} return type", type
+    else
+      cdl_error( "HSV0001 $1.$2 return type $3 cannot be used", signature.get_name, fh.get_name, type.get_type_str.to_s+type.get_type_str_post.to_s )
+    end
+  end
+  #=== 引数の型のチェック
+  def check_param signature, fh, param
+    type = param.get_type
+    ot = type.get_original_type
+    dir = param.get_direction
+    case dir
+    when :IN
+      if ot.kind_of?( IntType ) || ot.kind_of?( BoolType ) then
+        # OK!
+        check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}", type
+      elsif ot.kind_of? PtrType then
+        check_ptr signature, fh, param, dir
+      else
+        cdl_error( "HSV0002 $1.$2.$3 $4 param type cannot be used", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s+type.get_type_str_post.to_s )
+      end
+    when :OUT, :INOUT
+      if ot.kind_of? PtrType then
+        check_ptr signature, fh, param, dir
+      else
+        # error
+      end
+    when :SEND, :RECEIVE
+      cdl_error( "HSV0008 $1.$2.$3 param direction '$4' cannot be used", signature.get_name, fh.get_name, param.get_name, param.get_direction.to_s.downcase )
+    end
+  end
+  def check_ptr signature, fh, param, dir
+    type = param.get_type.get_referto
+    ot = type.get_original_type
+    if ot.kind_of?( IntType ) || ot.kind_of?( BoolType ) || ot.kind_of?( FloatType ) then
+      # OK!
+      check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}", type
+    elsif ot.kind_of? PtrType then
+      cdl_error( "HSV0003 $1.$2.$3 multi-pointer type cannot be used", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s+type.get_type_str_post.to_s )
+    elsif  ot.kind_of? StructType then
+      check_struct signature, fh, param
+    else
+      cdl_error( "HSV0004 $1.$2.$3 $4 type cannot be used", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s+type.get_type_str_post.to_s )
+    end
+    if ( dir == :OUT || dir == :INOUT) && param.get_string == -1 then
+      cdl_error( "HSV0009 $1.$2.$3 string argment is necessary for out/inout parameter", signature.get_name, fh.get_name, param.get_name )
+    end
+  end
+  def check_struct signature, fh, param
+    type = param.get_type.get_referto
+    ot = type.get_original_type
+    ot.get_members_decl.get_items.each{ |decl|
+      type = decl.get_type
+      ot = type.get_original_type
+      if ot.kind_of?( IntType ) || ot.kind_of?( BoolType ) || ot.kind_of?( FloatType ) then
+        # OK!
+        check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}.#{decl.get_name} member", type
+      else
+        dbgPrint "struct member #{decl.get_name} #{type} #{decl.get_type} #{decl.get_type.get_original_type}\n"
+        if( decl.get_type.get_original_type.kind_of? ArrayType ) then
+          dbgPrint "member array type #{decl.get_type.get_original_type.get_type} #{decl.get_type.get_original_type.get_type.get_original_type}\n"
+          check_struct_member_array signature, fh, param, decl
+        else
+          cdl_error( "HSV0006 $1.$2.$3 $4 type cannot be used as struct member", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s+type.get_type_str_post.to_s )
+        end
+      end
+    }
+  end
+  def check_struct_member_array signature, fh, param, member_decl
+    # p "check_struct_member_array: #{member_decl.get_type.get_type_str}"
+    type = member_decl.get_type.get_type
+    ot = type.get_original_type
+    if ot.kind_of?( IntType ) || ot.kind_of?( BoolType ) || ot.kind_of?( FloatType ) then
+      # OK!
+      check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}.#{member_decl.get_name} member", type
+    else
+      cdl_error( "HSV0007 $1.$2.$3 $4 type cannot be used as struct member", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s+type.get_type_str_post )
+    end
+  end
+  def check_intptr msg, type
+    dbgPrint "check_intptr IN\n"
+    t = type
+    while( t.kind_of? DefinedType )
+      dbgPrint "check_intptr #{msg} #{t.get_type_str} #{t.get_original_type.get_type_str}\n"
+      tstr = t.get_type_str
+      tstr.sub!( /const /, "" )
+      tstr.sub!( /volatile /, "" )
+      if tstr == "intptr_t" || tstr == "uintptr_t" then
+        cdl_info( "HSI0001 $1 type '$2' not checked by plugin", msg, type.get_type_str )
+      end
+      t = t.get_type
+    end
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPTaskPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPTaskPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/HRPTaskPlugin.rb	(revision 398)
@@ -0,0 +1,109 @@
+# coding: utf-8
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#  $Id$
+#++
+
+require_tecsgen_lib "HRPKernelObjectPlugin.rb"
+require_tecsgen_lib "HRPKernelObjectManager.rb"
+#== celltype プラグインの共通の親クラス
+class HRPTaskPlugin < HRPKernelObjectPlugin
+    ##
+    # oyama: add to avoid Ruby exception in code generation phase.
+    def new_cell cell
+      region = cell.get_region
+      dbgPrint "HRPTaskCelltypePlugin new_cell=#{cell.get_name} region=#{region.get_name}\n"
+      domainOption = cell.get_region.get_domain_root.get_domain_type.get_option
+      if domainOption == "OutOfDomain"
+        cdl_error( "HRP9999 HRP task '$1' must belong to a domain", cell.get_name )
+      end
+    end
+
+    # # ATT_MODを生成済みかどうか                   # 2017.8.27
+    # @@generate_memory_module = false
+
+    #
+    #  CRE_TSKの出力
+    #  file:: FILE:     出力先ファイル
+    #  cell :: Cell タスクセルインスタンス
+    #  val :: Hash {attr => string}:   カーネルオブジェクトの属性の解析結果
+    #  tab :: string: タブ
+    #
+    def print_cfg_cre(file, cell, val, tab)
+        val[:id] = val[:id].gsub( /(^|[^\$])\$id\$/, "\\1#{@celltype.get_name.to_s}_#{cell.get_name.to_s}" )
+        # $cbp$の代わり
+        cell_IDX = @celltype.get_name_array(cell)[7]
+        # CRE_TSKの生成
+        dbgPrint "assign task plugin\n"
+        domainOption = cell.get_region.get_domain_root.get_domain_type.get_option
+        # if cell.get_region.get_region_type == :DOMAIN
+        if domainOption != "OutOfDomain"
+            if val[:systemStackSize] == "0"
+                # 
+                #  システムスタックの定義を省略
+                #
+                file.print <<EOT
+CRE_TSK(#{val[:id]}, { #{val[:attribute]}, #{cell_IDX}, tTask_start, #{val[:priority]}, #{val[:stackSize]}, NULL });
+EOT
+            else
+                # 
+                #  システムスタックの定義を追加
+                #
+                file.print <<EOT
+CRE_TSK(#{val[:id]}, { #{val[:attribute]}, #{cell_IDX}, tTask_start, #{val[:priority]}, #{val[:stackSize]}, NULL, #{val[:systemStackSize]}, NULL });
+EOT
+            end
+        else
+            #
+            #  無所属のタスクは存在してはならないため，エラーとする
+            #
+            raise "task #{val[:id]} must belong to a domain."
+        end
+    end
+
+    #
+    #  SAC_TSKの出力
+    #  file:: FILE:     出力先ファイル
+    #  val :: Hash {attr => string}:   カーネルオブジェクトの属性の解析結果
+    #  acv :: Hash {accessPatternx => string}:   アクセス許可ベクタ
+    #
+    def print_cfg_sac(file, val, acv)
+       # pp "SAC_TSK"
+       # pp val
+       file.puts "SAC_TSK(#{val[:id]}, { #{acv[:accessPattern1]}, #{acv[:accessPattern2]}, #{acv[:accessPattern3]}, #{acv[:accessPattern4]} });"
+    end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/Mruby2CBridgePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/Mruby2CBridgePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/Mruby2CBridgePlugin.rb	(revision 398)
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+#
+#  mruby => TECS bridge
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#
+
+class Mruby2CBridgePlugin < SignaturePlugin
+  @@signature_list = { }
+
+  def initialize( signature, option )
+    super
+
+    @celltype_name = :"t#{@signature.get_global_name}"
+    @class_name = :"T#{@signature.get_global_name}"
+
+    parse_plugin_arg
+  end
+
+  def gen_cdl_file( file )
+    if( @@signature_list.length == 0 )then
+      print_msg "  Mruby2CBridgePlugin: [initialize function] 'void initializeBridge( mrb_state *mrb )' must be called from VM.\n"
+      c2tecs = "generate( C2TECSBridgePlugin, nMruby::sInitializeBridge, \"silent=true\" );\n"
+    end
+
+    if @@signature_list[ @signature.get_global_name ] then
+      @@signature_list[ @signature.get_global_name ] << self
+      cdl_warning( "MRCW001 signature '$1' duplicate. ignored current one", @signature.get_namespace_path )
+      return
+    end
+
+    @@signature_list[ @signature.get_global_name ] = [self]
+    print_msg "  Mruby2CBridgePlugin: [object creattion]    object = TECS::#{@class_name}.new( 'C#{@signature.get_global_name}' )\n"
+    print_msg "  Mruby2CBridgePlugin: [function call]       result = object.function( params )  # substitute 'function' and params \n"
+
+    cf = CFile.open( "#{$gen}/Mruby2C_tsInitializerBridge.cdl", "w")
+    cf.print <<EOT
+cell nC2TECS::tnMruby_sInitializeBridge C2TECS_tsInitializeBridge{
+    cCall = VM_TECSInitializer.eInitialize;
+};
+EOT
+    cf.close
+
+    file.print <<EOT
+generate( MrubyBridgePlugin, #{@signature.get_namespace_path}, "silent=true" );
+generate( TECS2CBridgePlugin, #{@signature.get_namespace_path}, "silent=true" );
+#{c2tecs}
+cell nMruby::t#{@signature.get_name} C#{@signature.get_name}{
+    cTECS = TECS2C_#{@signature.get_name}.eEnt;
+};
+cell nTECS2C::t#{@signature.get_name} TECS2C_#{@signature.get_name}{};
+
+import( "Mruby2C_tsInitializerBridge.cdl" );
+EOT
+
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeCellPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeCellPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeCellPlugin.rb	(revision 398)
@@ -0,0 +1,267 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+class MrubyBridgeCellPlugin < CellPlugin
+
+  # プラグイン引数名 => Proc
+  MrubyBridgePluginArgProc = { 
+      "ignoreUnsigned" => Proc.new { |obj,rhs| obj.set_ignoreUnsigned rhs },
+      "exclude_port" => Proc.new { |obj,rhs| obj.set_exclude_port rhs },
+      "exclude_port_func" => Proc.new { |obj,rhs| obj.set_exclude_port_func rhs },
+      "auto_exclude" => Proc.new { |obj,rhs| obj.set_auto_exclude rhs },
+  }
+  @@b_gen_post_code_by_dependent = false  # true if gen_post_code is called by MrubyBridgeCelltypePlugin
+  @@cell_list = {}      # gen_cdl_file'ed list to avoid duplicate generation
+  @@signature_list = {}
+
+  require_tecsgen_lib( "MrubyBridgeSignaturePlugin.rb" )
+
+  #@exclude_port::[ String(port_name) ] : 
+  #@exclude_port_func::{ [ String(port_name) ] => [ String(func_name) ] } : 
+  #@port_list::{ String(port_name) => String(include/exclude=func_name) }  : all included port and opt_string
+
+  #=== CellPlugin# initialize
+  #cell::     Cell        セル（インスタンス）
+  # このメソッドは、セルの構文解析が終わったところで呼び出される
+  # この段階では意味解析が終わっていない
+  def initialize( cell, option )
+    dbgPrint "  #{self.class.name}: initialzie=#{cell.get_name} option=#{option}\n"
+    super
+    @cell = cell
+
+    # option
+    @b_ignoreUnsigned = false
+    @exclude_port = []
+    @exclude_port_func = {}
+    @b_auto_exclude = true     # auto_exclude = true by default 
+    MrubyBridgeSignaturePlugin.set_gen_post_code_by_dependent
+
+    @plugin_arg_str = CDLString.remove_dquote option
+    # @plugin_arg_str = option.gsub( /\A"(.*)/, '\1' )    # 前後の "" を取り除く
+    # @plugin_arg_str.sub!( /(.*)"\z/, '\1' )
+    @plugin_arg_list = {}
+    dbgPrint "#{self.class.name}: initialzie: #{cell.get_name}\n"
+    @plugin_arg_check_proc_tab = MrubyBridgePluginArgProc
+    parse_plugin_arg
+
+    @port_list = {}         # set @port_list before return
+    ct = @cell.get_celltype
+    return if ct == nil     # error case
+
+    port_list = ct.get_port_list
+    if @exclude_port.length > 0 then
+      # この実装では、存在しない port を指定されてもチェックできない
+      # print "MRBBridgeCellPlugin: exclude list\n"
+      port_list.each{ |port|
+        if ! @exclude_port.include?( port.get_name.to_s ) then
+          # print "MRBBridgeCellPlugin: #{port.get_name} included\n"
+          @port_list[ port ] = ""
+        else
+          # print "MRBBridgeCellPlugin: #{port.get_name} excluded\n"
+        end
+      }
+    else
+      port_list.each{ |port|
+        @port_list[ port ] = ""
+      }
+    end
+
+    if @exclude_port_func.length > 0 then
+      @port_list.each{ |port, opt_str|
+        delim = ""
+        if @exclude_port_func.include?( port.get_name.to_s ) then
+          @exclude_port_func[ port.get_name.to_s ].each{ |func_name|
+            opt_str += delim + "exclude=" + func_name
+            delim = ","
+          }
+        end
+        @port_list[ port ] = opt_str
+      }
+    end
+  end
+
+  def gen_cdl_file file
+    dbgPrint "#{self.class.name}: gen_cdl_file: #{@cell.get_name}\n"
+
+    file.print <<EOT
+/* MrubyBridgeCellPlugin: generate for cell=#{@cell.get_name} */
+EOT
+
+    if @@cell_list[ @cell ] then
+      file.print <<EOT
+
+/*
+ * generate for #{@cell.get_name} duplicate and ignored.
+ * This might comes from generate for celltype.
+ */
+EOT
+      cdl_info( "MrubyBridgeCellPlugin: generate duplicate for cell '$1'", @cell.get_name )
+      return
+    end
+    @@cell_list[ @cell ] = @cell
+                
+    @port_list.each{ |port, opt_str|
+      next if port.get_signature == nil
+
+      case port.get_signature.get_context
+      when "task", "any"
+      else
+        next
+      end
+
+      if port.get_port_type == :ENTRY then
+        print "  MrubyBridgeCellPlugin: [cell.port] #{@cell.get_name}.#{port.get_name} => [mruby instance] TECS::T#{port.get_signature.get_name}.new( '#{@cell.get_name}#{port.get_name}Bridge' ) \n"
+        if @@signature_list[ port.get_signature ] == nil then
+          opt_str = "ignoreUnsigned=#{@b_ignoreUnsigned}, auto_exclude=#{@b_auto_exclude}, " + opt_str
+          # p "opt_str=#{opt_str}"
+
+          file.print <<EOT
+
+/* cell.port=#{@cell.get_name}.#{port.get_name} */
+generate( MrubyBridgePlugin, #{port.get_signature.get_namespace_path}, "#{opt_str}" );
+EOT
+          @@signature_list[ port.get_signature ] = true
+        end
+
+        # mikan option
+        nest = @cell.get_region.gen_region_str_pre file
+        nest_str = "  " * nest
+
+        file.print <<EOT
+#{nest_str}/* BridgeCell */
+#{nest_str}cell nMruby::t#{port.get_signature.get_name} #{@cell.get_name}#{port.get_name}Bridge {
+#{nest_str}    cTECS = #{@cell.get_namespace_path}.#{port.get_name};
+#{nest_str}};
+EOT
+        @cell.get_region.gen_region_str_post file
+      end
+    }
+  end
+
+  #=== 後ろの CDL コードを生成
+  #プラグインの後ろの CDL コードを生成
+  #file:: File: 
+  def self.gen_post_code( file )
+    dbgPrint "#{self.name}: gen_post_code\n"
+    if ! @@b_gen_post_code_by_dependent then
+      gen_post_code_body file
+    end
+  end
+
+  def self.set_gen_post_code_by_dependent # by MrubyBridgeCelltypePlugin
+    dbgPrint "#{self.name}: set_gen_post_code_by_dependent\n"
+    @@b_gen_post_code_by_dependent = true
+    MrubyBridgeSignaturePlugin.set_gen_post_code_by_dependent
+  end
+
+  def self.gen_post_code_body file
+    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+    # file.print "/* '#{self.class.name}' post code */\n"
+    dbgPrint "#{self.name}: gen_post_code_body\n"
+    MrubyBridgeSignaturePlugin.gen_post_code_body file
+  end
+
+  #=== プラグイン引数 ignoreUnsigned
+  def set_ignoreUnsigned rhs
+    if rhs == "true" || rhs == nil then
+      @b_ignoreUnsigned = true
+    end
+  end
+
+  #=== プラグイン引数 exclude_port
+  def set_exclude_port rhs
+    ports = rhs.split ','
+    ct = @cell.get_celltype
+    return if ct == nil    # error case
+    ports.each{ |rhs_port|
+      obj = ct.find( rhs_port.to_sym )
+      if( ( ! obj.instance_of? Port ) || obj.get_port_type != :ENTRY ) then
+        cdl_error( "MRB9999 exclude_port '$1' not found or not entry in celltype '$2'", rhs_port, ct.get_name )
+      else
+        # print "MRBBridgeCellPlugin: exclude #{rhs_port}\n"
+        @exclude_port << rhs_port
+      end
+    }
+  end
+
+  #=== プラグイン引数 exclude_port_func
+  def set_exclude_port_func rhs
+    port_funcs = rhs.split ','
+    ct = @cell.get_celltype
+    return if ct == nil    # error case
+    port_funcs.each{ |rhs_port_func|
+      port_func = rhs_port_func.split '.'
+      if port_func.length != 2 then
+        cdl_error( "MRB9999 exclude_port_func: '$1' not in 'port.func' form", rhs_port_func )
+      end
+      obj = ct.find( port_func[0].to_sym )
+      if( ( ! obj.instance_of? Port ) || obj.get_port_type != :ENTRY ) then
+        cdl_error( "MRB9999 exclude_port_func: port '$1' not found in celltype '$2'", rhs_port, ct.get_name )
+      else
+        signature = obj.get_signature
+        next if signature == nil     # error case
+        if signature.get_function_head port_func[1].to_sym
+          # print "MRBBridgeCellPlugin: #{port_func[0]}.#{port_func[1]} exclude\n"
+          if @exclude_port_func[ port_func[0] ] then
+            @exclude_port_func[ port_func[0] ] <<  port_func[1]
+          else
+            @exclude_port_func[ port_func[0] ] = [ port_func[1] ]
+          end
+        else
+          cdl_error( "MRB9999 exclude_port_func: func '$1' not found in port '$2' celltype $3",
+                     port_func[1], port_func[0], ct.get_name )
+        end
+      end
+    }
+  end
+  #=== プラグイン引数 auto_exclude
+  def set_auto_exclude rhs
+    # print "MrubyBridgeCellPlugin: auto_exclude=#{rhs}\n"
+    if rhs == "false" then
+      @b_auto_exclude = false
+    elsif rhs == "true" then
+      @b_auto_exclude = true     # auto_exclude = true by default 
+    else
+      cdl_warning( "MRB9999 auto_exclude: unknown rhs value ignored. specify true or false" )
+    end
+  end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeCelltypePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeCelltypePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeCelltypePlugin.rb	(revision 398)
@@ -0,0 +1,294 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+require_tecsgen_lib 'tecslib/plugin/lib/MrubyBridgeCelltypePluginModule.rb'
+
+#== MrubyBridgeCompositePlugin
+class MrubyBridgeCelltypePlugin < CompositePlugin
+  dbgPrint "MrubyBridgeCelltypePlugin loaded\n"
+  include MrubyBridgeCelltypePluginModule
+
+  def self.gen_post_code( file )
+    MrubyBridgeCelltypePluginModule.gen_post_code file
+  end
+end
+
+
+#
+##== celltype プラグインの共通の親クラス
+#class MrubyBridgeCelltypePlugin < CelltypePlugin
+#
+#  # プラグイン引数名 => Proc
+#  MrubyBridgePluginArgProc = { 
+#      "ignoreUnsigned" => Proc.new { |obj,rhs| obj.set_ignoreUnsigned rhs },
+#      "include_inner_cell" => Proc.new { |obj,rhs| obj.set_include_inner_cell rhs },
+#      "exclude_cell" => Proc.new { |obj,rhs| obj.set_exclude_cell rhs },
+#      "exclude_port" => Proc.new { |obj,rhs| obj.set_exclude_port rhs },
+#      "exclude_port_func" => Proc.new { |obj,rhs| obj.set_exclude_port_func rhs },
+#      "auto_exclude" => Proc.new { |obj,rhs| obj.set_auto_exclude rhs },
+#  }
+#
+#  require_tecsgen_lib( "MrubyBridgeCellPlugin.rb" )
+#  @@plugin_list = []
+#  @@count = 1
+#
+#  #celltype::     Celltype        セルタイプ（インスタンス）
+#  def initialize( celltype, option )
+#    dbgPrint "#{self.class.name}: initialzie: #{celltype.get_name}\n"
+#
+#    super
+#    @celltype = celltype
+#    @cell_list = []
+#    @include_inner_cell = false
+#    @exclude_cells = []
+#    @exclude_port = []
+#    @exclude_port_func = {}
+#    @b_ignoreUnsigned = false
+#    @b_auto_exclude = true     # auto_exclude = true by default 
+#    @@plugin_list << self
+#
+#    @plugin_arg_check_proc_tab = MrubyBridgePluginArgProc
+#    @plugin_arg_str = CDLString.remove_dquote option
+#    parse_plugin_arg
+#
+#    MrubyBridgeCellPlugin.set_gen_post_code_by_dependent
+#  end
+#
+#  #=== 新しいセル
+#  #cell::        Cell            セル
+#  #
+#  # celltype プラグインを指定されたセルタイプのセルが生成された
+#  # セルタイププラグインに対する新しいセルの報告
+#  # generate 文により呼び出された場合、それまでに定義された cell については、initialize のタイミングで呼び出される
+#  def new_cell( cell )
+#    dbgPrint "MrubyBridgeCelltypePlugin: new_cell: #{cell.get_name}\n"
+#
+#    return if @cell_list.include? cell   # この行は、本来不要のはず
+#    if TECSGEN.post_coded?               # post_code 以降のセルは対象から外す
+#      cdl_info( "I9999 MrubyBridgeCelltypePlugin: $1 is excluded because cell generated after post_coded", cell.get_name )
+#      return
+#    end
+#
+#    # include_inner_cell option
+#    if cell.is_cloned? && @include_inner_cell == false then
+#    #   p "#{cell.get_name} excluded"
+#      cdl_info( "I9999 MrubyBridgeCelltypePlugin: inner cell $1 is excluded", cell.get_name )
+#      return
+#    # else
+#    #   p "#{cell.get_name} included"
+#    end
+#
+#    # exclude_cell option
+#    if @exclude_cells.include?( cell.get_name ) then
+#      return
+#    end
+#
+#    opt_str = "ignoreUnsigned=#{@b_ignoreUnsigned}, auto_exclude=#{@b_auto_exclude}"
+#    @exclude_port.each{ |port|
+#      opt_str += ",exclude_port=#{port}"
+#    }
+#    @exclude_port_func.each{ |port, funcs|
+#      funcs.each{ |func|
+#        opt_str += ",exclude_port_func=#{port}.#{func}"
+#      }
+#    }
+#
+#    # p "MrubyBridgeCelltypePlugin: opt_str=#{opt_str}"
+#
+#    # mikan option, region
+#    fn2 = "#{$gen}/tmp_MrubyBridgeCelltypePlugin_#{@celltype.get_name}_#{@@count}.cdl"
+#    f2 = File.open( fn2, "w" )
+#    f2.print <<EOT
+#/* MrubyBridgeCelltypePlugin: celltype=#{@celltype.get_name} */
+#generate( MrubyBridgeCellPlugin, #{cell.get_namespace_path}, "#{opt_str}" );
+#EOT
+#    f2.close
+#    Import.new "#{fn2}"
+#    @@count += 1
+#  end
+#
+#### 意味解析段階で呼び出されるメソッド ###
+#  #===  CDL ファイルの生成
+#  #      typedef, signature, celltype, cell のコードを生成
+#  #      重複して生成してはならない
+#  #      すでに生成されている場合は出力しないこと。
+#  #      もしくは同名の import により、重複を避けること。
+#  #file::        FILE       生成するファイル
+#  def gen_cdl_file file
+##   この段階で呼びだすと generate 文が呼び出される前のセルのみの出力となる
+#    
+##    dbgPrint "MrubyBridgeCelltypePlugin: gen_cdl_file: #{@celltype.get_name}\n"
+##    file.print <<EOT
+##/* MrubyBridgeCelltypePlugin: celltype=#{@celltype.get_name}
+## *
+## *    cell's generate before celltype's generate
+## */
+##
+##EOT
+##    @celltype.get_cell_list.each { |cell|
+##      @cell_list << cell
+##      # mikan option, region
+##      dbgPrint "MrubyBridgeCelltypePlugin: cell=#{cell.get_name}\n"
+##      file.print <<EOT
+##generate( MrubyBridgeCellPlugin, #{cell.get_namespace_path}, "" );
+##EOT
+##    }
+#
+#  end
+#
+#  #=== tCelltype_factory.h に挿入するコードを生成する
+#  # file 以外の他のファイルにファクトリコードを生成してもよい
+#  # セルタイププラグインが指定されたセルタイプのみ呼び出される
+#  def gen_factory file
+#  end
+#
+#  def get_celltype
+#    @celltype
+#  end
+#
+#  #=== 後ろの CDL コードを生成
+#  #プラグインの後ろの CDL コードを生成
+#  #file:: File: 
+#  def self.gen_post_code( file )
+#    dbgPrint "#{self.name}: gen_post_code_body\n"
+#    print "#{self.name}: gen_post_code_body\n"
+##    この段階で生成すると、同じポストコードで出力される mruby の初期化コードに反映されない
+#    
+##    # MrubyBridgeCelltypePlugin の生成する generate 文は、
+##    fn2 = "#{$gen}/tmp_MrubyBridgeCelltypePlugin_post.cdl"
+##    f2 = File.open( fn2, "w" )
+##    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+##    dbgPrint "MrubyBridgeCelltypePlugin: gen_post_code\n"
+##    f2.print "/* '#{self.name}' post code */\n"
+##    @@plugin_list.each{ |plugin|
+##      plugin.get_celltype.get_cell_list.each{ |cell|
+##        # mikan option, region
+##        f2.print <<EOT
+##generate( MrubyBridgeCellPlugin, #{cell.get_namespace_path}, "" );
+##EOT
+##      }
+##    }
+##    f2.close
+##    p Import
+##    Import.new "#{fn2}"
+#
+#    MrubyBridgeCellPlugin.gen_post_code_body file
+#  end
+#
+#  #=== プラグイン引数 
+#
+#  #=== プラグイン引数 ignoreUnsigned
+#  def set_ignoreUnsigned rhs
+#    if rhs == "true" || rhs == nil then
+#      @b_ignoreUnsigned = true
+#    end
+#  end
+#
+#  def set_include_inner_cell rhs
+#    if rhs == "true" || rhs == nil then
+#      @include_inner_cell = true
+#    end
+#  end
+#
+#  def set_exclude_cell rhs
+#    cells = rhs.split ','
+#    cells.each{ |rhs_cell|
+#      rhs_cell.gsub!( /\s/, "" )
+#      @exclude_cells << rhs_cell.to_sym
+#    }
+#  end
+#  def set_exclude_port rhs
+#    ports = rhs.split ','
+#    ct = @cell.get_celltype
+#    return if ct == nil    # error case
+#    ports.each{ |rhs_port|
+#      obj = ct.find( rhs_port.to_sym )
+#      if( ( ! obj.instance_of? Port ) || obj.get_port_type != :ENTRY ) then
+#        cdl_error( "MRB9999 exclude_port '$1' not found or not entry in celltype '$2'", rhs_port, ct.get_name )
+#      else
+#        # print "MRBBridgeCellPlugin: exclude #{rhs_port}\n"
+#        @exclude_port << rhs_port
+#      end
+#    }
+#  end
+#
+#  #=== プラグイン引数 exclude_port_func
+#  def set_exclude_port_func rhs
+#    port_funcs = rhs.split ','
+#    ct = @celltype
+#    return if ct == nil    # error case
+#    port_funcs.each{ |rhs_port_func|
+#      port_func = rhs_port_func.split( '.' )
+#      if port_func.length != 2 then
+#        cdl_error( "MRB9999 exclude_port_func: '$1' not in 'port.func' form", rhs_port_func )
+#      end
+#      obj = ct.find( port_func[0].to_sym )
+#      if( ( ! obj.instance_of? Port ) || obj.get_port_type != :ENTRY ) then
+#        cdl_error( "MRB9999 exclude_port_func: port '$1' not found in celltype '$2'", rhs_port_func, ct.get_name )
+#      else
+#        signature = obj.get_signature
+#        next if signature == nil     # error case
+#        if signature.get_function_head port_func[1].to_sym
+#          # print "MRBBridgeCellPlugin: #{port_func[0]}.#{port_func[1]} exclude\n"
+#          if @exclude_port_func[ port_func[0] ] then
+#            @exclude_port_func[ port_func[0] ] <<  port_func[1]
+#          else
+#            @exclude_port_func[ port_func[0] ] = [ port_func[1] ]
+#          end
+#        else
+#          cdl_error( "MRB9999 include_port_func: func '$1' not found in port '$2' celltype $3",
+#                     port_func[1], port_func[0], ct.get_name )
+#        end
+#      end
+#    }
+#  end
+#
+#  #=== プラグイン引数 auto_exclude
+#  def set_auto_exclude rhs
+#    # print "MrubyBridgeCellPlugin: auto_exclude=#{rhs}\n"
+#    if rhs == "false" then
+#      @b_auto_exclude = false
+#    elsif rhs == "true" then
+#      @b_auto_exclude = true     # auto_exclude = true by default 
+#    else
+#      cdl_warning( "MRB9999 auto_exclude: unknown rhs value ignored. specify true or false" )
+#    end
+#  end
+#end
+#
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeCompositePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeCompositePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeCompositePlugin.rb	(revision 398)
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+require_tecsgen_lib 'tecslib/plugin/lib/MrubyBridgeCelltypePluginModule.rb'
+
+#== MrubyBridgeCompositePlugin
+class MrubyBridgeCompositePlugin < CompositePlugin
+  dbgPrint "MrubyBridgeCompositePlugin loaded\n"
+  include MrubyBridgeCelltypePluginModule
+
+  def self.gen_post_code( file )
+    MrubyBridgeCelltypePluginModule.gen_post_code file
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgePlugin.rb	(revision 398)
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+#
+#  mruby => TECS bridge
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#
+
+#== MrubyBridgePlugin クラス
+class MrubyBridgePlugin < MultiPlugin
+  def self.get_plugin superClass
+    # case when (つまりは ===) では、期待したように一致しない模様
+    if superClass == SignaturePlugin then
+      dbgPrint "MrubyBridgePlugin: SignaturePlugin"
+      require_tecsgen_lib 'tecslib/plugin/MrubyBridgeSignaturePlugin.rb'
+      return MrubyBridgeSignaturePlugin
+    elsif superClass == CelltypePlugin
+      dbgPrint "MrubyBridgePlugin: CelltypePlugin"
+      require_tecsgen_lib 'tecslib/plugin/MrubyBridgeCelltypePlugin.rb'
+      return MrubyBridgeCelltypePlugin
+    elsif superClass == CompositePlugin
+      dbgPrint "MrubyBridgePlugin: CompositePlugin"
+      require_tecsgen_lib 'tecslib/plugin/MrubyBridgeCompositePlugin.rb'
+      return MrubyBridgeCompositePlugin
+    elsif superClass == CellPlugin
+      dbgPrint "MrubyBridgePlugin: CellPlugin"
+      require_tecsgen_lib 'tecslib/plugin/MrubyBridgeCellPlugin.rb'
+      return MrubyBridgeCellPlugin
+    #elsif superClass == ThroughPlugin
+    #  return ThroughPlugin
+    #elsif superClass == DomainPlugin
+    #  return DomainPlugin
+    else
+      dbgPrint "MrubyBridgePlugin: unsupported"
+      return nil
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeSignaturePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeSignaturePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MrubyBridgeSignaturePlugin.rb	(revision 398)
@@ -0,0 +1,1313 @@
+# -*- coding: utf-8 -*-
+#
+#  mruby => TECS bridge
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#
+
+# Todo:
+# 生成するもの
+#  gen_cdl_file
+#    ブリッジ初期化セルタイプ (シグニチャごと)
+#       @@init_celltypes に記録
+#    ブリッジセルタイプ (シグニチャごと)
+#       @@celltypes に記録
+#    構造体セルタイプ
+#       @@struct_list に記録
+#  new_cell
+#    TECS 初期化セル(プロトタイプ宣言)
+#       @@VM_init_cells に記録
+#       @@VM_struct_list に記録
+#       @@VM_ptr_list に記録
+#  gen_post_code
+#    構造体初期化セル
+#    ポインタ初期化セル
+#    TECS 初期化セル
+#
+#   ep_func の作成
+#     signature, ポインタ、構造体 … 初期化受け口＝mruby VM への登録
+#     ポインタ
+#   preamble の作成
+#     ポインタ、構造体 … アクセス用コードの生成
+#     signature … ブリッジ関数のプロトタイプ宣言
+#   postamble の作成
+#     signature … ブリッジ関数の定義
+
+class MrubyBridgeSignaturePlugin < SignaturePlugin
+
+  # プラグイン引数名 => Proc
+  MrubyBridgePluginArgProc = { 
+      "ignoreUnsigned" => Proc.new { |obj,rhs| obj.set_ignoreUnsigned rhs },
+      "include" => Proc.new { |obj,rhs| obj.set_include rhs },
+      "exclude" => Proc.new { |obj,rhs| obj.set_exclude rhs },
+      "auto_exclude" => Proc.new { |obj,rhs| obj.set_auto_exclude rhs },
+  }
+
+  @@b_no_banner = false         #
+  @@b_gen_post_code_by_dependent = false  # true if gen_post_code is called by MrubyBridgeCellPlugin
+  @@celltypes = { }             # {celltype_name => [ BridgePlugin のインスタンスの配列 }
+  @@init_celltypes = { }        # {celltype_name => [ BridgePlugin のインスタンスの配列 }
+  @@struct_list = { }           # {struct_name=>StructType}
+  @@ptr_list = { }              # {ptr_celltype_name=> @@TYPE_MAP の対応するもの}
+  @@VM_list = { }               # VM_name => true
+  @@VM_celltypes = {  }             # VM_name => { @celltype_name => セルの配列 }
+  @@VM_struct_list = { }           # {name=>StructType}
+  @@VM_ptr_list = { }              # { VM_name => {name=> @@TYPE_MAP の対応するもの} }
+  @@TYPE_MAP = {           # type_str   class             GET_SET
+    :char_t            => [:char_t,    "Char",     :Char,  :INT   ],
+    :uchar_t           => [:uchar_t,   "UChar",    :Char,  :INT   ],
+    :schar_t           => [:schar_t,   "SChar",    :Char,  :INT   ],
+
+    :bool_t            => [:bool_t,    "Bool",     :Bool,  :BOOL  ],
+    :int8_t            => [:int8_t,    "Int8",     :Int,   :INT   ],
+    :int16_t           => [:int16_t,   "Int16",    :Int,   :INT   ],
+    :int32_t           => [:int32_t,   "Int32",    :Int,   :INT   ],
+    :int64_t           => [:int64_t,   "Int64",    :Int,   :INT   ],
+    :uint8_t           => [:uint8_t,   "UInt8",    :Int,   :INT   ],
+    :uint16_t          => [:uint16_t,  "UInt16",   :Int,   :INT   ],
+    :uint32_t          => [:uint32_t,  "UInt32",   :Int,   :INT   ],
+    :uint64_t          => [:uint64_t,  "UInt64",   :Int,   :INT   ],
+
+    :int               => [:int,       "Int",      :Int,  :INT   ], 
+    :char              => [:char,      "Char",     :Char, :INT   ],    # char は char_t として扱う
+    :short             => [:short,     "Short",    :Int,  :INT   ],
+    :long              => [:long,      "Long",     :Int,  :INT   ],
+
+    :"unsigned char"   => [:uchar_t,   "UChar",         :Char, :INT   ],
+    :"unsigned int"    => [:"unsigned int",   "UInt",   :Int,  :INT   ],
+    :"unsigned short"  => [:"unsigned short", "UShort", :Int,  :INT   ],
+    :"unsigned long"   => [:"unsigned long",  "ULong",  :Int,  :INT   ],
+    :"signed char"     => [:schar_t,   "SChar",    :Char,  :INT   ],
+    :"signed int"      => [:int,       "Int",      :Int,   :INT   ],
+    :"signed short"    => [:short,     "Short",    :Int,   :INT   ],
+    :"signed long"     => [:long,      "Long",     :Int,   :INT   ],
+
+    :float32_t         => [:float32_t, "Float32",  :Float, :FLOAT ],
+    :double64_t        => [:double64_t,"Double64", :Float, :FLOAT ],
+
+    :float             => [:float,     "Float32",  :Float, :FLOAT ],
+    :double            => [:double,    "Double64", :Float, :FLOAT ]
+  }
+
+  # included  or excluded functions
+
+  ### ロードされた時点で実行される ###
+
+  # -I に $(TECSPATH)/mruby を追加
+  # TECSGEN::Makefile.add_obj "$(MRUBY_MAIN_OBJ)"
+  TECSGEN::Makefile.add_ldflag "-lmruby -L$(MRUBYPATH)/lib -lm"
+  TECSGEN::Makefile.add_search_path "$(MRUBYPATH)/include"
+  TECSGEN::Makefile.add_var "MRUBYPATH",      "..",  "CHANGE this to suitable path"
+  # TECSGEN::Makefile.add_var "MRUBY_MAIN_OBJ", "$(_TECS_OBJ_DIR)tecs_mruby.o", "CHANGE this if your have your main"
+
+  #=== プラグインインスタンスの初期化
+  # 戻り値、引数の型が使用可能なものかチェックする
+  #
+  def initialize( signature, option )
+    super
+
+    if ! @@b_no_banner
+      STDERR << "MrubyBridgePlugin: version 1.3.0 (Suitable for mruby ver 1.3.0 & ver 1.2.0). \n"
+      @@b_no_banner = true
+    end
+
+    @b_ignoreUnsigned = false
+    @includes = []
+    @excludes = []
+    @struct_list = { }
+    @ptr_list = { }
+    @auto_exclude_list = {}
+    @b_auto_exclude = true     # auto_exclude = true by default 
+
+    @plugin_arg_check_proc_tab = MrubyBridgePluginArgProc
+    parse_plugin_arg
+
+    @celltype_name = :"t#{@signature.get_global_name}"
+    @init_celltype_name = :"#{@celltype_name}_Initializer"
+        # this variable is sometimes not used. rhs coded directry.
+    @class_name = :"T#{@signature.get_global_name}"
+
+    @func_head_array = []
+    fh_array = []
+    if @includes.length > 0 && @excludes.length > 0 then
+      cdl_error( "MRB1011 both include && exclude are specified" )
+    end
+
+    if signature.get_function_head_array == nil then
+      return   # 以前に文法エラー発生
+    end
+
+    signature.get_function_head_array.each{ |func_head|
+      if @includes.length > 0 then
+        if @includes.index func_head.get_name then
+          dbgPrint "MrubyBridgePlugin: #{func_head.get_name} INCLUDED\n"
+          fh_array << func_head
+        else
+          dbgPrint "MrubyBridgePlugin: #{func_head.get_name} NOT included\n"
+        end
+      elsif @excludes.length > 0 then
+        if @excludes.index( func_head.get_name ) == nil then
+          dbgPrint "MrubyBridgePlugin: #{func_head.get_name} NOT excluded\n"
+          fh_array << func_head
+        else
+          dbgPrint "MrubyBridgePlugin: #{func_head.get_name} EXCLUDED\n"
+        end
+      else
+        fh_array << func_head
+      end
+    }
+
+    check_name_and_return_type fh_array
+    check_parameter_type fh_array
+
+    fh_array.each{ |fh|
+      if @auto_exclude_list[ fh.get_name ] == nil then
+        @func_head_array << fh
+      else
+        dbgPrint "MrubyBridgePlugin: auto_exclude #{fh.get_name}\n"
+      end
+    }
+
+    if @func_head_array.length == 0 then
+      cdl_error( "MRB1012 '$1' no function remained by exclude", @signature.get_name )
+    end
+  end
+
+  #=== check function name & return type
+  def check_name_and_return_type func_head_array
+    b_init = false; b_init_cell = false
+    func_head_array.each{ |func_head|
+      if( func_head.get_name == :initialize )then
+        cdl_warning( "MRW2001 initialize: internally defined. change to initialize_cell in ruby" )
+        b_init = true
+      elsif( func_head.get_name == :initialize_cell )then
+        b_init_cell = true
+      end
+      rtype = func_head.get_return_type.get_original_type
+      case rtype
+      when BoolType, IntType, FloatType, VoidType
+      else
+        if @b_auto_exclude then
+          cdl_info( "MRI0001 cannot return type $1, $2 automatcally excluded", rtype.get_type_str, func_head.get_name )
+          @auto_exclude_list[ func_head.get_name ] = func_head
+        else
+          cdl_error( "MRB1001 cannot return type $1", rtype.get_type_str )
+        end
+      end
+    }
+    if( b_init && b_init_cell )then
+      cdl_warning( "MRB1002 initialize: internally defined. change to initialize_cell in ruby" )
+    end
+  end
+
+  #=== check paramter type
+  def check_parameter_type func_head_array
+    # check type of parameters
+    func_head_array.each{ |fh|
+      fh.get_paramlist.get_items.each{ |param_decl|
+        case param_decl.get_direction
+        when :SEND, :RECEIVE
+          if @b_auto_exclude then
+            cdl_info( "MRI0002 $1: $2 parameter cannot be used in mruby Bridge, $3 automatcally excluded",
+                      param_decl.get_name, param_decl.get_direction.to_s.downcase, fh.get_name )
+            @auto_exclude_list[ fh.get_name ] = fh
+          else
+            cdl_error( "MRB1003 $1: $2 parameter cannot be used in mruby Bridge",  param_decl.get_name, param_decl.get_direction.to_s.downcase )
+          end
+        end
+        type = param_decl.get_type
+        type_org = type.get_original_type
+        type_str = type.get_type_str + type.get_type_str_post
+
+        b_ng = false
+        case type_org
+        when IntType
+          case  type_org.get_bit_size
+          when 8, 16, 32, 64
+          when -1, -2, -3, -4, -11
+          else
+            b_ng = true
+          end
+        when BoolType
+        when FloatType
+        when PtrType
+          ttype_org = type_org.get_type       # ポインタの指している先の型
+          ttype = ttype_org.get_original_type # 上記の typedef されている場合、元の型
+          register_ptr_type ttype_org, fh
+
+          if( type_org.get_string.to_s == "-1" ) then
+            case param_decl.get_direction
+            when :OUT, :INOUT
+              if @b_auto_exclude then
+                cdl_info( "MRB9999 string specifier without length cannot be used for out & inout parameter, $1 automatcally excluded", 
+                        fh.get_name )
+                @auto_exclude_list[ fh.get_name ] = fh
+              else
+                cdl_error( "MRB9999 string specifier without length cannot be used for out & inout parameter")
+              end
+            end
+          end
+
+          case ttype
+          when IntType
+            bit_size = ttype.get_bit_size
+            # if  bit_size < 0 && bit_size != -1 then
+            #   b_ng = true
+            # end
+          when FloatType
+          when BoolType
+          when StructType
+            if( type_org.get_size || type_org.get_string || type_org.get_count ) then
+              if @b_auto_exclude then
+                cdl_info( "MRI9999 $1: size_is, count_is, string cannot be specified for struct pointer, $2 automatcally excluded",
+                          param_decl.get_name, fh.get_name )
+                @auto_exclude_list[ fh.get_name ] = fh
+              else
+                cdl_error( "MRB1004 $1: size_is, count_is, string cannot be specified for struct pointer", param_decl.get_name )
+              end
+            end
+            check_struct_member ttype_org, fh
+          else
+            b_ng = true
+          end
+        when StructType
+          check_struct_member type_org, fh
+        else  # ArrayType, FuncType, EnumType, VoidType
+          b_ng = true
+        end
+        if b_ng then
+          if @b_auto_exclude then
+            cdl_info( "MRI9999 $1: type $2 cannot be used in mruby Bridge, $3 automatcally excluded",
+                      param_decl.get_name, type_str, fh.get_name )
+            @auto_exclude_list[ fh.get_name ] = fh
+          else
+            cdl_error( "MRB1005 $1: type $2 cannot be used in mruby Bridge", param_decl.get_name, type_str )
+          end
+        end
+      }
+    }
+  end
+
+  #=== 構造体のメンバーの型のチェック
+  def check_struct_member struct_type, fh
+    #p "tag name:#{struct_type.get_name}"
+    # sttype = Namespace.find_tag( struct_type.get_name )
+    sttype = struct_type.get_original_type
+    if sttype.get_name == nil then
+      if @b_auto_exclude then
+        cdl_info( "MRI9999 tagless-struct cannot be handled, $1 automatcally excluded", fh.get_name )
+        @auto_exclude_list[ fh.get_name ] = fh
+        return  # 登録しないように打ち切る
+      else
+        cdl_error( "MRB10007 tagless-struct cannot be handled")
+      end
+    end
+    sttype.get_members_decl.get_items.each { |d|
+      t = d.get_type.get_original_type
+      case t
+      when IntType, FloatType, BoolType
+      else
+        if @b_auto_exclude then
+          cdl_info( "MRI9999 $1: type $2 not allowed for struct member, $3 automatcally excluded",
+                    d.get_name, d.get_type.get_type_str + d.get_type.get_type_str_post, fh.get_name )
+          @auto_exclude_list[ fh.get_name ] = fh
+          return  # 登録しないように打ち切る
+        else
+          cdl_error( "MRB1006 $1: type $2 not allowed for struct member", d.get_name, d.get_type.get_type_str + d.get_type.get_type_str_post )
+        end
+      end
+    }
+    st_name = :"t{}"
+    if @struct_list[ sttype.get_name ] == nil then
+      # print_msg "  MrubyBridgePlugin: [struct]   #{struct_type.get_type_str} => class TECS::Struct#{sttype.get_name}\n"
+      print "  MrubyBridgePlugin: [struct]   #{struct_type.get_type_str} => class TECS::Struct#{sttype.get_name}\n"
+      @struct_list[ sttype.get_name ] = sttype
+    end
+  end
+
+  def register_ptr_type ttype, fh
+    t_org = ttype.get_original_type
+    tment = get_type_map_ent t_org
+    if tment == nil then
+      return
+      # cdl_error( "MRB1008 unknown pointer type '$1'", ttype.get_type_str )
+    end
+    ptr_celltype_name = :"t#{tment[1]}Pointer"
+    if @@ptr_list[ ptr_celltype_name ] == nil then
+      # print_msg "  MrubyBridgePlugin: [pointer]  #{ttype.get_type_str}* => class TECS::#{tment[1]}Pointer\n"
+      print "  MrubyBridgePlugin: [pointer]  #{ttype.get_type_str}* => class TECS::#{tment[1]}Pointer\n"
+      @@ptr_list[ ptr_celltype_name ] = tment
+    end
+    if @ptr_list[ ptr_celltype_name ] == nil then
+      @ptr_list[ ptr_celltype_name ] = tment
+    end
+  end
+
+  def get_type_map_ent ttype
+    # structure type is registerd in check_struct_member
+    if ttype.kind_of? StructType
+      return
+    end
+    tstr = ttype.get_type_str.sub( /const /, "" )    # const は無視
+    tstr = tstr.sub( /volatile /, "" )               # volatile も無視
+    if @b_ignoreUnsigned then
+      tstr = tstr.sub( /unsigned /, "" )             # volatile も無視
+      tstr = tstr.sub( /uint/, "int" )               # volatile も無視
+      tstr = tstr.sub( /[cs]char/, "char" )          # volatile も無視
+    end
+    return @@TYPE_MAP[ tstr.to_sym ]
+  end
+
+  #===  CDL ファイルの生成
+  #      typedef, signature, celltype, cell コードを生成
+  #file::        FILE       生成するファイル
+  def gen_cdl_file(file)
+
+    # ブリッジセルタイプの生成
+    if @@celltypes[ @celltype_name ] == nil then
+      @@celltypes[ @celltype_name ] = [ self ]
+      @@init_celltypes[ @init_celltype_name ] = true
+      print_msg <<EOT
+  MrubyBridgePlugin: [signature] #{@signature.get_namespace_path} => [celltype] nMruby::#{@celltype_name} => [class] TECS::#{@class_name}
+EOT
+
+      file.print <<EOT
+/*
+ * MrubyBridgeSignaturePlugin:
+ *     signature=#{@signature.get_namespace_path}
+ *
+ *   => celltype=nMruby::#{@celltype_name}
+ *      (bridge cell's celltype; generated in this file)
+ *      cell nMruby::#{@celltype_name} BridgeCellName { cTECS = CellName.eEntry; };
+ *        where eEntry's signature must be #{@signature.get_namespace_path}.
+ *      => class=TECS::#{@class_name}
+ *         (mruby's class; accessible from your script)
+ *          bridge = TECS::#{@class_name}.new("BridgeCellName")
+ */
+import( <mruby.cdl> );
+
+/****  Ruby => TECS Bridge Celltype (MBP500) ****/
+namespace nMruby{
+    // bridge celltype
+    [idx_is_id,active]   // not actually active, to avoid warning W1002, W1007
+    celltype #{@celltype_name} {
+        call #{@signature.get_namespace_path.to_s} cTECS;
+        attr {
+            [omit]
+            char_t *VMname = "VM";
+            [omit]
+            char_t *bridgeName = C_EXP( "$cell$" );
+        };
+    };
+    // bridge initializer celltype
+    celltype #{@init_celltype_name} {
+        entry sInitializeTECSBridge eInitialize;
+    };
+};
+EOT
+
+      # 構造体セルタイプの生成
+      @struct_list.each{ |name, sttype|
+        if @@struct_list[ name ] == nil then
+          file.print <<EOT
+namespace nMruby{
+    [singleton]
+    celltype #{name} {
+        entry sInitializeTECSBridge eInitialize;
+    };
+};
+EOT
+          @@struct_list[ name ] = sttype
+        end
+      }
+
+    else
+      cdl_info( "MRBW001 MrubyBridgePlugin: signature '$1' duplicate. ignored current one", @signature.get_namespace_path )
+      @@celltypes[ @celltype_name ] << self
+    end
+  end
+
+  #=== gen_cdl_file で定義したセルタイプに 新しいセルが定義された
+  # cell のセルタイプの名前は @celltype_name
+  def new_cell cell
+    if cell.get_celltype.get_name != @celltype_name then
+      return
+    end
+
+    join = cell.get_join_list.get_item :VMname
+    if join then
+      vm_name = CDLString.remove_dquote(join.get_rhs.to_s).to_sym
+    else
+      vm_name = :"VM"
+    end
+
+    if @@VM_list[ vm_name ] == nil then
+      @@VM_list[ vm_name ] = true
+
+      initializer_celltype_cdl = "#{$gen}/#{cell.get_name}Initializer.cdl"
+      file = CFile.open( initializer_celltype_cdl, "w" )
+
+      # TECS 初期化セル(プロトタイプ宣言)
+      print_msg "  MrubyBridgePlugin: join your VM's cInitialize to #{vm_name}_TECSInitializer.eInitialize\n"
+
+      file.print <<EOT
+
+  // prototype of TECSInitializer (MBP510)
+  cell nMruby::tTECSInitializer #{vm_name}_TECSInitializer;
+EOT
+      file.close
+
+      Generator.parse( initializer_celltype_cdl, self )
+    end
+
+    if @@VM_celltypes[ vm_name ] then
+      vma = @@VM_celltypes[ vm_name ]
+
+      if vma[ @celltype_name ] then
+        vma[ @celltype_name ] << cell
+      else
+        vma[ @celltype_name ] = [cell]
+        @@VM_celltypes[ vm_name ] = vma
+      end
+    else
+      vma = { }
+      vma[ @celltype_name ] = [cell]
+      @@VM_celltypes[ vm_name ] = vma
+    end
+
+    @struct_list.each{ |stname, sttype|
+      if @@VM_struct_list[ vm_name ] then
+        @@VM_struct_list[ vm_name ][ sttype.get_name ] = sttype
+      else
+        @@VM_struct_list[ vm_name ] = { sttype.get_name => sttype }
+      end
+    }
+    @ptr_list.each{ |ptr_celltype_name, tment|
+      if @@VM_ptr_list[ vm_name ] then
+        @@VM_ptr_list[ vm_name ][ ptr_celltype_name ] = tment
+      else
+        @@VM_ptr_list[ vm_name ] = { ptr_celltype_name => tment }
+      end
+    }
+
+  end
+
+  #=== プラグインが CDL の POST コードを生成
+  # tmp_plugin_post_code.cdl への出力
+  def self.gen_post_code file
+    dbgPrint "#{self.name}: gen_post_code\n"
+    if ! @@b_gen_post_code_by_dependent then
+      gen_post_code_body file
+    end
+  end
+
+  def self.set_gen_post_code_by_dependent # by MrubyBriddeCellPlugin
+    dbgPrint "#{self.name}: set_gen_post_code_by_dependent\n"
+    @@b_gen_post_code_by_dependent = true
+  end
+
+  def self.gen_post_code_body file
+    dbgPrint "#{self.name}: gen_post_code_body\n"
+
+#     file.print <<EOT
+# namespace nMruby {
+# EOT
+# 
+#     @@ptr_list.each{ |name,tment|
+#       file.print <<EOT
+# 
+#     // MBP600
+#     [singleton]
+#     celltype #{name} {
+#         entry  sInitializeTECSBridge eInitialize;
+#     };
+# EOT
+#     }
+# 
+#     file.print <<EOT
+# };
+# EOT
+
+# gen_post_code で生成した celltype は gen_ep_func が呼び出されない #847
+#    @@struct_list.each{ |name,sttype|
+#      file.print <<EOT
+#
+#    [singleton]
+#    celltype #{name} {
+#        entry  sInitializeTECSBridge eInitialize;
+#    };
+#EOT
+#    }
+
+    file.print "\n  // MrubyBridgeSignaturePlugin: MBP601\n"
+    @@VM_celltypes.each{ |vm_name, instance_list|
+      instance_list.each { |celltype_name, array|
+        cell = array[0]
+	if cell.get_celltype then
+	  ct_name = cell.get_celltype.get_name
+        file.print <<EOT
+  cell nMruby::#{ct_name}_Initializer #{vm_name}_#{ct_name}_Initializer{ };
+EOT
+        end
+      }
+    }
+
+    file.print "  // MBP602\n"
+    @@ptr_list.each{ |name,tment|
+      file.print <<EOT
+  cell nMruby::#{name} C#{name} { };
+EOT
+    }
+
+    file.print "  // MBP603\n"
+    @@struct_list.each{ |name,sttype|
+      file.print <<EOT
+  cell nMruby::#{name} C#{name} { };
+EOT
+    }
+
+    if @@VM_celltypes == nil
+      raise "MrubyBridgeSignaturePlugin: are0"
+    end
+    @@VM_celltypes.each{ |vm_name, instance_list|
+      file.print "  /* === VM name is '#{vm_name}' === (MBP610) */\n"
+      init_cell_name = "#{vm_name}_TECSInitializer"
+
+      file.print "  cell nMruby::tTECSInitializer #{init_cell_name} {\n"
+
+      instance_list.each { |celltype_name, array|
+#        array.each{ |cell|
+#          ct_name = cell.get_celltype.get_name
+          ct_name = celltype_name
+          file.print "    cInitialize[] = #{vm_name}_#{ct_name}_Initializer.eInitialize;\n"
+#        }
+      }
+      if @@VM_ptr_list[vm_name] then
+        @@VM_ptr_list[vm_name].each{ |name, tment|
+          file.print "    cInitialize[] = C#{name}.eInitialize;\n"
+        }
+      end
+      if @@VM_struct_list[vm_name] then
+        @@VM_struct_list[vm_name].each{ |name, sttype|
+          file.print "    cInitialize[] = C#{name}.eInitialize;\n"
+        }
+      end
+      file.print "  };"
+    }
+    
+  end
+
+  ####### 以下コード生成段階 ######
+
+  #===  受け口関数の本体コードを生成（頭部と末尾は別途出力）
+  #ct_name:: Symbol    (プラグインで生成された) セルタイプ名 ．Symbol として送られてくる
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    if @@celltypes[ ct_name ] then
+      gen_ep_func_body_bridge( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    elsif @@init_celltypes[ ct_name ] then
+      gen_ep_func_body_bridge_init( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    elsif @@ptr_list[ ct_name ] then
+      gen_ep_func_body_ptr( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    elsif @@struct_list[ ct_name ] then
+      gen_ep_func_body_struct( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    else
+      raise "MrubyBridgeSignaturePlugin: Unknown #{ct_name}"
+    end
+  end
+
+  def gen_ep_func_body_bridge( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    raise "MrubyBridgeSignaturePlugin: unexpected "
+  end
+
+  def gen_ep_func_body_bridge_init( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    file.print <<EOT
+    // CELLCB *p_cellcb = GET_CELLCB( idx );  /* no error check */     /* MBP700 */
+    struct RClass	*rc;
+
+    rc = mrb_define_class_under( mrb, TECS, \"#{@class_name}\", mrb->object_class );
+    mrb_define_method( mrb, rc, "initialize", MrubyBridge_#{@celltype_name}_initialize, MRB_ARGS_REQ(1) );
+    MRB_SET_INSTANCE_TT(rc, MRB_TT_DATA);
+EOT
+
+    @func_head_array.each{ |f|
+      if ! f.is_function? then
+        next
+      end
+      if f.get_name != :initialize then
+        func_name = f.get_name
+      else
+        func_name = :initialize_cell
+      end
+
+      ret_type = f.get_return_type
+      n_param = 0
+      f.get_paramlist.get_items.each{ |param|
+        case param.get_direction
+        when :IN, :INOUT, :OUT
+          n_param += 1
+        when :SEND, :RECEIVE
+          raise "MrubyBridgeSignaturePlugin: send, receive"
+        end
+      }
+      if n_param > 0 then
+        p_str = "MRB_ARGS_REQ( #{n_param} )"
+      else
+        p_str = "MRB_ARGS_NONE()"
+      end
+      file.print <<EOT
+	mrb_define_method( mrb, rc, "#{func_name}", MrubyBridge_#{@celltype_name}_#{func_name}, #{p_str} );
+EOT
+    }
+  end
+
+  def gen_ep_func_body_ptr( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    
+    t = @@ptr_list[ct_name]
+    type = t[1]
+    file.print <<EOT
+	struct RClass *a;                                /* MBP710 */
+
+    a = mrb_define_class_under(mrb, TECS, "#{type}Pointer", mrb->object_class);
+    MRB_SET_INSTANCE_TT(a, MRB_TT_DATA);
+
+    mrb_define_method(mrb, a, "initialize",      #{type}Pointer_initialize,   MRB_ARGS_REQ(1));
+    mrb_define_method(mrb, a, "[]",              #{type}Pointer_aget,         MRB_ARGS_REQ(1));
+    mrb_define_method(mrb, a, "value",           #{type}Pointer_get_val,      MRB_ARGS_NONE());
+    mrb_define_method(mrb, a, "[]=",             #{type}Pointer_aset,         MRB_ARGS_REQ(2));
+    mrb_define_method(mrb, a, "value=",          #{type}Pointer_set_val,      MRB_ARGS_REQ(1));
+    mrb_define_method(mrb, a, "size",            #{type}Pointer_size,         MRB_ARGS_NONE());
+    mrb_define_method(mrb, a, "length",          #{type}Pointer_size,         MRB_ARGS_NONE());
+EOT
+
+    if t[2] == :Char then
+      file.print <<EOT
+	mrb_define_method(mrb, a, "to_s",            CharPointer_to_s, MRB_ARGS_NONE());
+	mrb_define_method(mrb, a, "from_s",          CharPointer_from_s, MRB_ARGS_REQ(1));
+EOT
+    end
+  end
+
+  def gen_ep_func_body_struct( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    tag = ct_name
+    structType = @@struct_list[ tag ]
+    file.print  <<EOT
+	struct RClass *a;                                /* MBP720 */
+
+	a = mrb_define_class_under(mrb, TECS, "Struct#{tag}", mrb->object_class);
+	MRB_SET_INSTANCE_TT(a, MRB_TT_DATA);
+
+	mrb_define_method(mrb, a, "initialize", Struct_#{tag}_initialize, MRB_ARGS_NONE());
+EOT
+
+      structType.get_members_decl.get_items.each{ |d|
+        file.print "  STRUCT_INIT_MEMBER( #{tag}, #{d.get_name} )\n"
+      }
+  end
+
+  #===  受け口関数の preamble (C言語)を生成する
+  #     必要なら preamble 部に出力する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  def gen_preamble( file, b_singleton, ct_name, global_ct_name )
+    if @@celltypes[ ct_name ] then
+      gen_preamble_mruby( file, b_singleton, ct_name, global_ct_name )
+      gen_preamble_instance( file, b_singleton, ct_name, global_ct_name )
+      gen_preamble_instance_initialize( file, b_singleton, ct_name, global_ct_name )
+      gen_preamble_bridge_func( file, b_singleton, ct_name, global_ct_name )
+    elsif @@init_celltypes[ ct_name ] then
+      gen_preamble_mruby( file, b_singleton, ct_name, global_ct_name )
+      gen_preamble_instance_proto( file, b_singleton, ct_name, global_ct_name )
+    elsif @@ptr_list[ ct_name ] then
+      gen_preamble_ptr( file, b_singleton, ct_name, global_ct_name )
+    elsif @@struct_list[ ct_name ] then
+      gen_preamble_struct( file, b_singleton, ct_name, global_ct_name )
+    else
+      raise "MrubyBridgeSignaturePlugin: MrubyBridgeSignaturePlugin: Unknown #{ct_name}"
+    end
+  end
+
+  def gen_preamble_mruby( file, b_singleton, ct_name, global_ct_name )
+    file.print <<EOT
+/* MBP: MrubyBridgePlugin: MBP000 */
+#include "mruby.h"
+#include "mruby/class.h"
+#include "mruby/data.h"
+#include "mruby/string.h"
+#include "TECSPointer.h"
+#include "TECSStruct.h"
+
+#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+#define DLLEXPORT __declspec(dllexport)
+#else
+#define DLLEXPORT
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+EOT
+  end
+
+  def gen_preamble_instance( file, b_singleton, ct_name, global_ct_name )
+    # 「#1005  MrubyBridgePlugin-test のビルドに失敗」にて追加
+    # 「#1004 idx_is_id が true の場合(domain の場合は未指定でも true) の CBP のプロトタイプ宣言」にて不要になる見込み
+    nsp = NamespacePath.new( :nMruby, true )
+    nsp.append! ct_name
+    ct = Namespace.find nsp
+    if ct.idx_is_id_act? then
+      if ct.has_CB? then
+        inib_cb = "CB"
+      elsif ct.has_INIB? then
+        inib_cb = "INIB"
+      else
+        inib_cb = nil
+      end
+      if inib_cb then
+        ct.get_cell_list.each{ |cell|
+          if cell.is_generate? then
+            name_array = ct.get_name_array( cell )
+            file.print "extern #{ct.get_global_name}_CB  #{cell.get_global_name}_#{inib_cb};\n"
+          end
+        }
+      end
+    end
+
+    file.print <<EOT
+
+/* RData MBP001 */
+static void 
+#{@celltype_name}_free( mrb_state *mrb, void *p )
+{
+	if( p )
+		(void)mrb_free( mrb, p );
+}
+
+/* RData MBP002 */
+struct mrb_data_type data_type_#{@celltype_name} =
+{
+	"#{@celltype_name}",
+	#{@celltype_name}_free
+};
+
+/* RData MBP003 */
+struct tecs_#{@celltype_name} {
+    CELLCB  *cbp;
+};
+
+/* name_to_cbp MBP010 */
+const struct name_to_cbp_#{@celltype_name} {
+    char   *name;    /* Cell Name */
+    CELLCB *cbp;
+} Name_to_cbp_#{@celltype_name}[] = {
+EOT
+
+    nsp = NamespacePath.new( :nMruby, true )
+    nsp.append! ct_name
+    ct = Namespace.find nsp
+
+    ct.get_cell_list.each{ |cell|
+      if cell.is_generate? then
+        join_list = cell.get_join_list
+        join = join_list.get_item( :bridgeName )
+        if join == nil then
+          name = "\"#{cell.get_name}\""
+        else
+          rhs = join.get_rhs
+          attr_list = cell.get_celltype.get_attribute_list
+          name = rhs.eval_const join_list, attr_list
+        end
+
+        name_array = ct.get_name_array( cell )
+        file.print "\t{ #{name}, #{name_array[8]} },\n"
+      end
+    }
+
+    file.print <<EOT
+\t{ 0, 0 },
+};
+
+EOT
+
+  end
+
+  def gen_preamble_ptr( file, b_singleton, ct_name, global_ct_name )
+    tment = @@ptr_list[ ct_name ]
+    file.print <<EOT
+
+GET_SET_#{tment[3]}( #{tment[1]}, #{tment[0]} )
+POINTER_CLASS( #{tment[1]}, #{tment[0]} )
+EOT
+  end
+
+  def gen_preamble_struct( file, b_singleton, ct_name, global_ct_name )
+    tag = ct_name
+    structType = @@struct_list[ tag ]
+    file.print <<EOT
+/* struct #{tag} */
+STRUCT_CLASS( #{tag} )
+EOT
+
+    structType.get_members_decl.get_items.each{ |d|
+      type = d.get_type.get_original_type
+      case type
+      when IntType, CIntType
+        bit_size = type.get_bit_size
+        case bit_size
+        when -11, -1
+          tType = "Char"
+          ttype = "char"
+        when -2
+          tType = "Short"
+          ttype = "short"
+        when -3
+          tType = "Int"
+          ttype = "int"
+        when -4
+          tType = "Long"
+          ttype = "long"
+        when -5
+          tType = "IntPtr"
+          ttype = "intptr"
+        when 8, 16, 32, 64
+          tType = "Int#{bit_size}"
+          ttype = "int#{bit_size}"
+        else
+            raise "MrubyBridgeSignaturePlugin: MrubyBridgeSignaturePlugin: cannot handle bit_size #{bit_size}"
+        end
+        file.print "MEMBER_GET_SET_INT( #{tag}, #{d.get_name}, #{tType}, #{ttype} )\n"
+      when FloatType, CFloatType
+        file.print "MEMBER_GET_SET_FLOAT( #{tag}, #{d.get_name} )\n"
+      else
+        raise "MrubyBridgeSignaturePlugin: MrubyBridgeSignaturePlugin: cannot handle type"
+      end
+    }
+
+  end
+
+  def gen_preamble_instance_proto( file, b_singleton, ct_name, global_ct_name )
+    file.print <<EOT
+//  Prototype MBP400
+mrb_value  MrubyBridge_#{@celltype_name}_initialize( mrb_state *mrb, mrb_value self);
+EOT
+
+    @func_head_array.each{ |f|
+      if ! f.is_function? then
+        next
+      end
+      if f.get_name != :initialize then
+        func_name = f.get_name
+      else
+        func_name = :initialize_cell
+      end
+
+      ret_type  = f.get_return_type
+      ret_type0 = f.get_return_type.get_original_type
+      b_void    = ret_type0.is_void?
+      plist     = f.get_paramlist.get_items
+
+      file.print <<EOT
+mrb_value  MrubyBridge_#{@celltype_name}_#{func_name}( mrb_state *mrb, mrb_value self );
+EOT
+    }
+  end
+
+  def gen_preamble_instance_initialize( file, b_singleton, ct_name, global_ct_name )
+    file.print <<EOT
+
+/* MBP100 */
+mrb_value
+MrubyBridge_#{@celltype_name}_initialize( mrb_state *mrb, mrb_value self)
+{
+	mrb_value	name;
+	struct tecs_#{@celltype_name} *tecs_cb;
+	const struct name_to_cbp_#{@celltype_name} *ntc;
+
+	/* set DATA_TYPE earlier to avoid SEGV */
+	DATA_TYPE( self ) = &data_type_#{@celltype_name};
+
+	mrb_get_args(mrb, "o", &name );
+	if( mrb_type( name ) != MRB_TT_STRING ){
+		mrb_raise(mrb, E_NAME_ERROR, "cell name not string");
+	}
+	for( ntc = &Name_to_cbp_#{@celltype_name}[0]; ntc->name != NULL; ntc++ ){
+		if( strcmp( ntc->name, RSTRING_PTR( name ) ) == 0 )
+			break;
+	}
+	if( ntc->name == 0 ){
+		mrb_raise(mrb, E_ARGUMENT_ERROR, "cell not found");
+	}
+	tecs_cb = (struct tecs_#{@celltype_name} *)mrb_malloc(mrb, sizeof(struct tecs_#{@celltype_name}) );
+	tecs_cb->cbp = ntc->cbp;
+	DATA_PTR( self ) = (void *)tecs_cb;
+
+	return self;
+}
+EOT
+  end
+
+  def gen_preamble_bridge_func( file, b_singleton, ct_name, global_ct_name )
+
+    @func_head_array.each{ |f|
+      if ! f.is_function? then
+        next
+      end
+      if f.get_name != :initialize then
+        func_name = f.get_name
+      else
+        func_name = :initialize_cell
+      end
+
+      ret_type  = f.get_return_type
+      ret_type0 = f.get_return_type.get_original_type
+      b_void    = ret_type0.is_void?
+      plist     = f.get_paramlist.get_items
+
+      file.print <<EOT
+
+/* bridge function (MBP101) */
+mrb_value
+MrubyBridge_#{ct_name}_#{func_name}( mrb_state *mrb, mrb_value self )
+{
+	/* cellcbp (MBP105) */
+	CELLCB	*p_cellcb = ((struct tecs_#{@celltype_name} *)DATA_PTR(self))->cbp;
+EOT
+      
+      file.print "	/* variables for return & parameter (MBP110) */\n"
+      if ! b_void then
+        file.print "	", ret_type.get_type_str, "\tret_val", ret_type.get_type_str_post, ";\n"
+      end
+      arg_str = ""
+      n_param  = 0
+      n_scalar = 0
+      n_ptr    = 0
+      n_struct = 0
+      plist.each{ |param|
+        case param.get_direction
+        when :IN, :INOUT, :OUT
+          type = param.get_type.get_original_type
+          case type
+          when IntType
+            file.print "	mrb_int	mrb_", param.get_name, ";\n"
+            file.print "	#{param.get_type.get_type_str}	#{param.get_name}#{param.get_type.get_type_str_post};\n"
+            arg_str += "i"
+            n_param += 1
+            n_scalar += 1
+          when FloatType
+            file.print "	mrb_float	mrb_", param.get_name, ";\n"
+            file.print "	#{param.get_type.get_type_str}	#{param.get_name}#{param.get_type.get_type_str_post};\n"
+            arg_str += "f"
+            n_param += 1
+            n_scalar += 1
+          when BoolType
+            file.print "	mrb_value	mrb_", param.get_name, ";\n"
+            file.print "	#{param.get_type.get_type_str}	#{param.get_name}#{param.get_type.get_type_str_post};\n"
+            arg_str += "o"
+            n_param += 1
+            n_scalar += 1
+          when PtrType
+            file.print "	mrb_value	mrb_", param.get_name, ";\n"
+            file.print "	#{param.get_type.get_type_str}	#{param.get_name}#{param.get_type.get_type_str_post};\n"
+            arg_str += "o"
+            n_param += 1
+            n_ptr += 1
+          when StructType
+            file.print "	mrb_value	mrb_", param.get_name, ";\n"
+            file.print "	#{param.get_type.get_type_str}	*#{param.get_name}#{param.get_type.get_type_str_post};\n"
+            arg_str += "o"
+            n_param += 1
+            n_struct += 1
+          else
+            raise "MrubyBridgeSignaturePlugin: Unknown type"
+          end
+        end
+      }
+
+      if n_param > 0 then
+        file.print "	/* retrieve arguments (MBP111) */\n"
+        file.print "	mrb_get_args(mrb, \"#{arg_str}\""
+        plist.each{ |param|
+          case param.get_direction
+          when :IN, :INOUT, :OUT
+            type = param.get_type.get_original_type
+            case type
+            when IntType
+              file.print ", &mrb_", param.get_name
+            when FloatType
+              file.print ", &mrb_", param.get_name
+            when BoolType
+              file.print ", &mrb_", param.get_name
+            when PtrType
+              file.print ", &mrb_", param.get_name
+            when StructType
+              file.print ", &mrb_", param.get_name
+            else
+              raise "MrubyBridgeSignaturePlugin: Unknown type"
+            end
+          end
+        }
+        file.print " );\n"
+
+        if n_scalar > 0 || n_struct > 0 then
+          file.print "	/* convert mrb to C (MBP112) */\n"
+        end
+        plist.each{ |param|
+          case param.get_direction
+          when :IN, :INOUT, :OUT
+            type = param.get_type.get_original_type
+            case type
+            when IntType
+              ttype = type.get_original_type
+              tment = get_type_map_ent ttype
+              file.print "	VALCHECK_#{tment[1]}( mrb, mrb_#{param.get_name} );\n"
+              file.print "	#{param.get_name} = (#{param.get_type.get_type_str})mrb_#{param.get_name};\n"
+            when FloatType
+              file.print "	#{param.get_name} = (#{param.get_type.get_type_str})mrb_#{param.get_name};\n"
+            when BoolType
+              file.print "	#{param.get_name} = mrb_test( mrb_#{param.get_name} );\n"
+            when PtrType
+              ttype = type.get_type.get_original_type
+              case ttype
+              when StructType
+                file.print "	CHECK_STRUCT( #{ttype.get_name}, mrb_#{param.get_name} );\n"
+                file.print "	#{param.get_name} = (struct #{ttype.get_name}*)DATA_PTR(mrb_#{param.get_name});\n"
+              when IntType
+              when FloatType
+              when BoolType
+              else
+                raise "MrubyBridgeSignaturePlugin: cannot handle type"
+              end
+            when StructType
+              file.print "	CHECK_STRUCT( #{type.get_name}, mrb_#{param.get_name} );\n"
+              file.print "	#{param.get_name} = (struct #{type.get_name}*)DATA_PTR(mrb_#{param.get_name});\n"
+            else
+              raise( "MrubyBridgeSignaturePlugin: canot treat class" )
+            end
+          end
+        }
+
+        if n_ptr > 0 then
+          file.print "	/* convert mrb to C for pointer types (MBP113) */\n"
+        end
+        plist.each{ |param|
+          case param.get_direction
+          when :IN, :INOUT, :OUT
+            type = param.get_type.get_original_type
+            case type
+            when IntType
+            when FloatType
+            when BoolType
+            when PtrType
+              case type.get_type.get_original_type
+              when StructType
+              when IntType
+                ptrMrb2C file, type, param
+              when FloatType
+                ptrMrb2C file, type, param
+              when BoolType
+                ptrMrb2C file, type, param
+              else
+                raise "MrubyBridgeSignaturePlugin: cannot handle type"
+              end
+            when StructType
+            else
+              raise( "MrubyBridgeSignaturePlugin: canot treat class" )
+            end
+          end
+        }
+
+      end
+
+      file.print "	/* calling target (MBP120) */\n"
+      if ! b_void then
+        file.print "	ret_val = "
+      else
+        file.print "	"
+      end
+      delim = ""
+      file.print "cTECS_", f.get_name, "( "
+      plist.each{ |param|
+        if param.get_type.get_original_type.kind_of? StructType then
+          aster = "*"
+        else
+          aster = ""
+        end
+        file.print delim, aster, param.get_name
+        delim = ", "
+      }
+      file.print " );\n"
+      
+      file.print "	/* return (MBP130) */\n"
+      case ret_type0
+      when BoolType
+        file.print "	return ret_val ? mrb_true_value() : mrb_false_value();\n"
+      when IntType
+        file.print "	return mrb_fixnum_value( ret_val );\n"
+      when FloatType
+        file.print "	return mrb_float_value( mrb, ret_val );\n"
+      when VoidType
+        file.print "	return  mrb_nil_value();\n"
+      else
+        raise "MrubyBridgeSignaturePlugin: unknown type"
+      end
+
+      file.print "}\n"
+    }
+  end
+
+  def ptrMrb2C file, type, param
+    ttype = type.get_type.get_original_type
+    tment = get_type_map_ent ttype
+    tstr = tment[1]
+=begin
+    case ttype
+    when IntType
+      bit_size = ttype.get_bit_size
+      case bit_size
+      when -1, -11
+        tstr = "Char"
+      when 8, 16, 32, 64
+        tstr = "Int#{bit_size}"
+      when -2
+        tstr = "Short"
+      when -3
+        tstr = "Int"
+      when -4
+        tstr = "Long"
+      when -5
+        tstr = "IntPtr"
+      else
+        raise "MrubyBridgeSignaturePlugin: not handle type"
+      end
+    when FloatType
+      if ttype.get_bit_size == 32 then
+        tstr = "Float32"
+      else
+        tstr = "Double64"
+      end
+    when BoolType
+      tstr = "Bool"
+    when StructType
+      raise "MrubyBridgeSignaturePlugin: not handle type 2 #{ttype}"
+    else
+      raise "MrubyBridgeSignaturePlugin: not handle type 2 #{ttype}"
+    end
+=end
+    if( param.get_size ) then
+      sz_str = param.get_size.to_s
+    elsif param.get_string then      # mikan とりあえず size_is と string の同時指定 (二重ポインタ) はなし
+      sz_str = param.get_string.to_s
+    else
+      sz_str = "1"
+    end
+    # unsigned 型の場合には cast が必要
+    if ttype.get_original_type.get_type_str != param.get_type.get_type.get_type_str then
+      cast_str = "(#{param.get_type.get_type_str})"
+    else
+      cast_str = ""
+    end
+
+    modify = ""
+    case param.get_direction
+    when :OUT, :INOUT
+      case tstr
+      when "Char", "SChar", "UChar"
+        modify = "Mod"
+      end
+    end
+    if param.is_nullable? then
+      nullable = "Nullable"
+    else
+      nullable = ""
+    end
+
+    # file.print "	CHECK_POINTER( #{tstr}, mrb_#{param.get_name}, #{sz_str} );\n"
+    # file.print "	#{param.get_name} = #{cast_str}((struct #{tstr}PointerBody*)(DATA_PTR(mrb_#{param.get_name})))->buf;\n"
+    file.print "	#{param.get_name} = CheckAndGet#{tstr}Pointer#{modify}#{nullable}( mrb, mrb_#{param.get_name}, #{sz_str} );\n"
+  end
+
+  def get_celltype_name
+    @celltype_name
+  end
+
+  #=== プラグイン引数 ignoreUnsigned
+  def set_ignoreUnsigned rhs
+    if rhs == "true" || rhs == nil then
+      @b_ignoreUnsigned = true
+    end
+  end
+  #=== プラグイン引数 include
+  def set_include rhs
+    funcs = rhs.split ','
+    funcs.each{ |rhs_func|
+      found = false
+      rhs_func.gsub!( /\s/, "" )
+      @signature.get_function_head_array.each{ |a|
+        if rhs_func.to_sym == a.get_name then
+          found = true
+        end
+      }
+      if found == false then
+        cdl_error( "MRB1009 include function '$1' not found in signagture '$2'", rhs, @signature.get_name )
+      else
+        @includes << rhs_func.to_sym
+      end
+    }
+  end
+  #=== プラグイン引数 exclude
+  def set_exclude rhs
+    funcs = rhs.split ','
+    funcs.each{ |rhs_func|
+      rhs_func.gsub!( /\s/, "" )
+      func_head = @signature.get_function_head rhs_func.to_sym
+      if func_head == false then
+        cdl_error( "MRB1010 exclude function '$1' not found in signagture '$2", rhs, @signature.get_name )
+      else
+        @excludes << rhs_func.to_sym
+      end
+    }
+  end
+  #=== プラグイン引数 auto_exclude
+  def set_auto_exclude rhs
+    if rhs == "false" then
+      @b_auto_exclude = false
+    elsif rhs == "true" then
+      @b_auto_exclude = true     # auto_exclude = true by default 
+    else
+      cdl_warning( "MRB9999 auto_exclude: unknown rhs value ignored. specify true or false" )
+    end
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MultiPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MultiPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/MultiPlugin.rb	(revision 398)
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== MultiPlugin クラス
+class MultiPlugin < Node
+  def self.get_plugin superClass
+    # case when (つまりは ===) では、期待したように一致しない模様
+    if superClass == SignaturePlugin then
+      return SignaturePlugin
+    elsif superClass == CelltypePlugin
+      return CelltypePlugin
+    elsif superClass == CellPlugin
+      return CellPlugin
+    elsif superClass == ThroughPlugin
+      return ThroughPlugin
+    elsif superClass == DomainPlugin
+      return DomainPlugin
+    else
+      return nil
+    end
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/NotifierPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/NotifierPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/NotifierPlugin.rb	(revision 398)
@@ -0,0 +1,1193 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#
+#  Copyright (C) 2015 by Ushio Laboratory
+#              Graduate School of Engineering Science, Osaka Univ., JAPAN
+#  Copyright (C) 2015-2016 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+#  Copyright (C) 2015-2018 by TOPPERS Project
+#
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#  $Id$
+#++
+
+NotifierPluginArgProc = {
+	"factory" => Proc.new { |obj, rhs| obj.set_factory(rhs) },
+	"output_file" => Proc.new { |obj, rhs| obj.set_factory_output_file(rhs) }
+}
+
+class NotifierPlugin < CelltypePlugin
+
+	# ---------- アダプタ関数の生成 -------------
+	#
+	# siHandlerBodyの受け口関数は，タイムイベント通知の通知先として直接指定する
+	# ことはできない．シグネチャが一致していないことが理由である．このため，アダ
+	# プタとして動作する関数を生成し，カーネルからの呼出しをTECSの呼出しに変換で
+	# きるようにする必要がある．
+	#
+	# 基本的には，受け口毎にアダプタ関数を生成すれば十分である．しかし，これでは
+	# メモリ消費量が不必要に増加してしまう．そこで，通知先関数にintptr_t型の引数
+	# を渡せることに着目し，関数の"一般化"を図る．すなわち受け口のある属性(ここ
+	# では，結合先のセル，添字などを指す)を，アダプタ関数の引数として受け取れる
+	# ようにし，1個のアダプタ関数を2個以上の結合に対し用いることができるように
+	# する．
+	#
+	# アダプタ関数の属性について整理すると，
+	#  - 受け口関数 - 一般化を行うと，実行時コストが大きく増大してしまうことが
+	#    確認されている．このため，一般化は行わない．EntryPropertyにも含めない．
+	#  - セルインデックス - CELLIDX型で，型の規定はないが，"ホ゜インタ値て゛あったり
+	#    整数値て゛あったりする。" (TECS 5.3.6) より，インデックスかポインタある
+	#    ことが分かる．インデックスだとすると，この値はセルCBのアドレッシングに
+	#    使用されるので，intptr_tに収まる筈である．ポインタの場合，当然intptr_t
+	#    に収まる．
+	#  - 受け口配列の添字 - int_t．同様にintptr_tに収まる筈である．
+	# これらのうち，セルインデックスと受け口配列の添字はパラメータに含めることが
+	# できそうであるが，両方は無理である．
+	# 両方を格納した配列を生成し，その配列の要素へのポインタを渡すようにするとい
+	# う選択肢も可能であるが，実行速度を優先するために，この方法はとらなかった．
+	#
+	# このため，一般化は以下のパターンに分類して行う．
+	#
+	# 1. セルインデックスのみ一般化．セルインデックスのパターン数が受け口配列の
+	#    添字のパターン数より多いか，あるいは受け口が配列でない場合に行われる．
+	# 2. 受け口配列の添字のみ一般化．この場合，セルごとに異なる関数を用いる．
+	#
+	# これより，各受け口関数について，アダプタ関数の生成個数は，
+	#         O(min{セルインデックスのパターン数, 添字のパターン数})
+	# となる．
+	#
+	# プラグインでの処理をワンパスで行うために，tecsgen.cfgではアダプタ関数を直
+	# 接指定するのではなく，代わりにアダプタ関数を表すマクロを使用する．この
+	# マクロはアダプタ関数ハンドルと呼ぶことにする．
+	# アダプタ関数ハンドルは，次の2個の要素から成る．
+	#  - アダプタ関数へののポインタ
+	#  - アダプタ関数の引数
+	#
+	#   $Id$
+
+	# @private
+	class AdapterGenerator
+
+		# 結合先に関する属性を含む．セル，受け口配列の添字から成る．
+		# 同一のEntryPropertyとなる結合は，全く同じ方法でその受け口関数を呼び
+		# 出せる．
+		# @private
+		class EntryProperty
+			# @return [Cell] 受け口側のセル．
+			attr_reader :cell
+
+			# @return [Integer, nil] 受け口配列の添字．配列でない場合はnil．
+			attr_reader :subscript
+
+			def initialize(cell, subscript)
+				@cell = cell
+				@subscript = subscript
+			end
+
+			def self.from_join(join)
+				EntryProperty.new(join.get_rhs_cell, join.get_rhs_subscript)
+			end
+
+			# 同値性の定義．Hashのキーとして使用するのに必要．
+			def eql?(o) @cell == o.cell && @subscript == o.subscript end
+			def hash() @cell.hash ^ @subscript.hash end
+		end
+
+		# @private
+		class EntryPort
+			# @param [Port] port 結合先のセルのセルタイプの受け口．
+			def initialize(port, prefix)
+				@port = port
+				@global_name = "#{prefix}_#{@port.get_celltype.get_global_name}_#{@port.get_name}"
+
+				# 受け口関数名．siHandlerBodyを想定しているので，関数名はmainで固定である．
+				@entry_fn_name = "#{@port.get_celltype.get_global_name}_#{@port.get_name}_main"
+
+				@props = [] 	# Array<EntryProperty>
+				@prop_map = {}	# Hash<EntryProperty, Integer>
+			end
+
+			# @return [String] グローバルに一意(なものとして扱えるよう)な識別子．
+			attr_reader :global_name
+
+			# @return [Port]
+			attr_reader :port
+
+			# 指定したEntryPropertyに対応するアダプタ関数ハンドルを取得する．
+			# @param [EntryProperty] ep
+			# @return [String] アダプタ関数ハンドル．
+			# @private
+			def adapter_handle_for_entry_property(ep)
+				index = @prop_map.fetch(ep)
+				return [
+					"#{@global_name}_#{index}_fp",
+					"#{@global_name}_#{index}_arg"
+				]
+			end
+
+			# 結合先の情報に応じたアダプタ関数をソース・ヘッダーに出力する．
+			# 一般化指定は，`cell`または`subscript`の一方のみ行うことができる．
+			#
+			# @param [AdapterGenerator] context
+			# @param [String] fn_name 関数名．
+			# @param [Cell, Symbol] cell セル．セルについて一般化する場合は `:generic`
+			# @param [Integer, Symbol, nil] subscript 添字．添字について一般化する場合は `:generic`
+			# @param [Celltype] 呼び先のセルタイプ、cell==:generic の場合のみ有効
+			# @private
+			def generate_inner(context, fn_name, cell, subscript, callee_ct=nil)
+				source_file = context.source_file
+				header_file = context.header_file
+
+				source_file.print "void #{fn_name}(intptr_t extinf) {\n"
+
+				params = []
+				ct = @port.get_celltype
+
+				# シングルトンセルタイプ以外では，CELLIDXの指定が必要．
+				unless ct.is_singleton?
+					if cell == :generic
+						params << "(#{callee_ct.get_global_name}_IDX)extinf"
+						# params << "(CELLIDX)extinf"
+					else
+						# セルのCELLIDXを得る
+						if ct.has_INIB? || ct.has_CB?
+							params << ct.get_name_array(cell)[7]
+						else
+							params << "0"
+						end
+					end
+				end
+
+				# 受け口配列の添字．
+				if @port.get_array_size
+					if subscript == :generic
+						params << "(int_t)extinf"
+					else
+						params << "#{subscript}"
+					end
+				end
+
+				params_str = params.join(", ")
+
+				source_file.print "\t#{@entry_fn_name}(#{params_str});\n"
+				source_file.print "}\n\n"
+
+				header_file.print "extern void #{fn_name}(intptr_t extinf);\n\n"
+
+			end
+
+			# 指定したJoinに対応するアダプタ関数ハンドルを取得する．
+			# @return [Array] アダプタ関数ハンドル．
+			def make_adapter_handle(join)
+				prop = EntryProperty.from_join(join)
+				unless @prop_map.has_key?(prop)
+					@prop_map[prop] = @props.length
+					@props << prop
+				end
+				return adapter_handle_for_entry_property(prop)
+			end
+
+			# ソース・ヘッダーの記述を生成する．
+			# @param [AdapterGenerator] context
+			def generate(context)
+				header_file = context.header_file
+				return if @props.empty?
+
+				ct = @port.get_celltype
+
+				header_file.print "/*\n * #{@global_name}\n"
+
+				cells = @props.group_by { |prop| prop.cell }
+				subscripts = @props.group_by { |prop| prop.subscript }
+				no_cellidx = false
+				if !(ct.has_INIB? || ct.has_CB?)
+					# CB, INIB最適化により，CB, INIBが両方不要になったケース．
+					# CELLIDXが不要であるので，セルについて一般化しても意味
+					# はないので，添字による一般化を選択する．
+					generalize_by_cell_idx = false
+					no_cellidx = true
+
+					# 全てのセルを同一視する．
+					cells = { @props[0].cell => @props }
+
+					header_file.print " * No INIB & CB: generalized by subscript\n"
+				elsif @port.get_array_size
+					# 一般化パターンの分類を行うために，受け口側セルや添字の
+					# パターン数を分析して，最適な方を選択する．
+					generalize_by_cell_idx = cells.length >= subscripts.length
+					if generalize_by_cell_idx
+						header_file.print " * more cells than subscripts: generalized by cell\n"
+					else
+						header_file.print " * more subscripts than cells: generalized by subscript\n"
+					end
+				else
+					# 常にCELLIDXで一般化
+					generalize_by_cell_idx = true
+					header_file.print " * non-array entry port: generalized by cell\n"
+				end
+
+				header_file.print " */\n\n"
+
+				if generalize_by_cell_idx
+					# CELLIDXについて一般化
+					subscripts.each { |subscript, props|
+						if subscript
+							fn_name = "#{@global_name}_adap_#{subscript}"
+						else
+							# 受け口配列でない場合
+							fn_name = "#{@global_name}_adap"
+						end
+
+						generate_inner context, fn_name,
+							:generic, subscript, ct
+
+						props.each { |prop|
+							handle = adapter_handle_for_entry_property(prop)
+
+							# セルのCELLIDXを得る
+							if ct.has_INIB? || ct.has_CB?
+								idx = ct.get_name_array(prop.cell)[7]
+							else
+								idx = "0"
+							end
+							header_file.print "\#define #{handle[0]} &#{fn_name}\n"
+							header_file.print "\#define #{handle[1]} #{idx}\n\n"
+						}
+					}
+				else
+					# 添字について一般化
+					cells.each { |cell, props|
+						if no_cellidx
+							# CB/INIB なし
+							fn_name = "#{@global_name}_adap"
+						else
+							fn_name = "#{@global_name}_adap_#{cell.get_global_name}"
+						end
+
+						generate_inner context, fn_name,
+							cell, :generic
+
+						props.each { |prop|
+							handle = adapter_handle_for_entry_property(prop)
+
+							header_file.print "\#define #{handle[0]} &#{fn_name}\n"
+							header_file.print "\#define #{handle[1]} #{prop.subscript || 0}\n\n"
+						}
+					}
+				end
+			end
+		end
+
+		# @private
+		attr :source_file
+
+		# @private
+		attr :header_file
+
+		# @param [String] celltype_name ハンドラ関数のセルタイプ．
+		# @param [String] prefix 名前衝突を防ぐためのプレフィックス．
+		def initialize(celltype_name, prefix)
+			@celltype_name = celltype_name
+			@prefix = prefix
+
+			# Hash<Port, EntryPort>
+			@entry_ports = {}
+		end
+
+		# ===AdapterGenerator#make_adapter_handle===
+		# 指定した結合の呼出しを行うためのアダプタ関数ハンドルを生成する．
+		# @return [Array] アダプタ関数ハンドル．
+		def make_adapter_handle(join)
+			entry_port = @entry_ports[join.get_rhs_port]
+			unless entry_port
+				entry_port = EntryPort.new(join.get_rhs_port,
+					"#{@celltype_name}_#{@prefix}")
+				@entry_ports[join.get_rhs_port] = entry_port
+			end
+			return entry_port.make_adapter_handle(join)
+		end
+
+		# ===AdapterGenerator#finish===
+		# 各受け口に対し，アダプタ関数を生成する．
+		def finish
+			@source_file = AppFile.open( "#{$gen}/#{@celltype_name}.c" )
+	        @source_file.print "\n/* Generated by #{self.class.name} */\n\n"
+	        @source_file.print "\#include \"#{@celltype_name}_aux.h\"\n\n"
+	        @source_file.print "\#include \"#{@celltype_name}_tecsgen.h\"\n\n"
+
+			@header_file = AppFile.open( "#{$gen}/#{@celltype_name}.h" )
+	        @header_file.print "\n/* Generated by #{self.class.name} */\n\n"
+
+			# NotifierPluginを使用するセルタイプが複数ある場合，それぞれに
+			# 対しAdapterGenerator#finishが呼び出される．tTimeEventHandler.hに
+			# 続けて書き込んでしまうと，ヘッダーガードの関係で2回目以降の記述
+			# が読み込まれなくなってしまう．このため，ファイル名 + セルタイプ名
+			# という少し特殊なヘッダーガードを用いる．
+			header_guard = "#{@celltype_name}_H_#{@prefix}"
+
+	        @header_file.print "\#ifndef #{header_guard}\n"
+	        @header_file.print "\#define #{header_guard}\n\n"
+
+	        # カーネルコンフィギュレータを実行する際，ハンドラ受け口のセルタイプ
+	        # のセルCBの定義が必要な場合がある．
+	        @header_file.print "\#include \"#{@celltype_name}_aux.h\"\n\n"
+
+			# 結合先のセルタイプの定義は，自分のセルのtecsgen.hよりも先に
+			# 読み込まなければならないが，このプラグインが複数実行されると，
+			# 順序が崩れてしまう．そこで，結合先のセルタイプの定義はもう一つの
+			# ヘッダーファイル(tCelltypeName_aux.h)から読み込むようにする．
+			aux_header_file = AppFile.open( "#{$gen}/#{@celltype_name}_aux.h" )
+	        aux_header_file.print "\n/* Generated by #{self.class.name} */\n\n"
+
+			aux_header_guard = "#{@celltype_name}_AUX_H_#{@prefix}"
+
+	        aux_header_file.print "\#ifndef #{aux_header_guard}\n"
+	        aux_header_file.print "\#define #{aux_header_guard}\n\n"
+
+			cb_type_only_guard = "#{@celltype_name}_AUX_H_#{@prefix}_CB_TYPE_ONLY"
+
+			# 結合先のセルタイプの定義を読み込む
+			aux_header_file.print "#ifndef TOPPERS_CB_TYPE_ONLY\n"
+		    aux_header_file.print "#define TOPPERS_CB_TYPE_ONLY\n"
+		    aux_header_file.print "#define #{cb_type_only_guard}\n"
+			aux_header_file.print "#endif\n"
+			@entry_ports.values.map { |ep|
+				ep.port.get_celltype
+			}.uniq.each { |ct|
+				hname = "#{ct.get_global_name}_tecsgen.#{$h_suffix}"
+				aux_header_file.print "\#include \"#{hname}\"\n"
+			}
+			aux_header_file.print "#ifdef #{cb_type_only_guard}\n"
+		    aux_header_file.print "#undef #{cb_type_only_guard}\n"
+		    aux_header_file.print "#undef TOPPERS_CB_TYPE_ONLY\n"
+			aux_header_file.print "#endif\n\n"
+
+			aux_header_file.print "\#endif\n"
+			aux_header_file.close
+
+			@entry_ports.each { |port, entry_port|
+				entry_port.generate self
+			}
+
+	        @header_file.print "\#endif\n"
+
+			@source_file.close
+			@header_file.close
+		end
+
+	end
+
+	# ------ 通知のハンドラの種類の定義 -------
+
+	class Handler
+		def initialize(call_port_name)
+			@call_port_name = call_port_name
+		end
+
+		attr :call_port_name
+	end
+
+	# 通常のハンドラ
+	EVENT_HANDLER = Handler::new("ciNotificationHandler")
+
+	# エラーハンドラ (通常のハンドラが失敗した場合に呼び出される)
+	ERROR_HANDLER = Handler::new("ciErrorNotificationHandler")
+
+	HANDLERS = [
+		EVENT_HANDLER,
+		ERROR_HANDLER
+	]
+
+	class HandlerAttribute
+		def initialize(name, error_name = nil)
+			@name = name
+			@error_name = error_name || (name + 'ForError')
+		end
+
+		def name_for_handler(handler)
+			case handler
+			when EVENT_HANDLER then return @name
+			when ERROR_HANDLER then return @error_name
+			else raise "unknown handler #{handler}"
+			end
+		end
+	end
+
+	# ------ 通知の属性の定義 -------
+	#
+	# ハンドラタイプに合致しない属性が指定された場合に
+	# エラーを出力できるよう、全ての属性をここで列挙する。
+
+	SETVAR_ADDR_ATTR =   HandlerAttribute::new("setVariableAddress")
+	SETVAR_VALUE_ATTR =  HandlerAttribute::new("setVariableValue")
+	INCVAR_ADDR_ATTR =   HandlerAttribute::new("incrementedVariableAddress")
+	SNDDTQ_VALUE_ATTR =  HandlerAttribute::new("dataqueueSentValue")
+	SETFLG_FLAG_ATTR =   HandlerAttribute::new("flagPattern")
+
+	ATTRS = [
+		SETVAR_ADDR_ATTR,
+		SETVAR_VALUE_ATTR,
+		INCVAR_ADDR_ATTR,
+		SNDDTQ_VALUE_ATTR,
+		SETFLG_FLAG_ATTR
+	]
+
+	# ------ ハンドラタイプの定義 -------
+
+	class BaseHandlerType
+
+		def initialize()
+			super
+
+			# HandlerAttribute[]
+			@required_attributes = []
+		end
+
+		attr :required_attributes
+
+	    #=== NotifierPlugin#BaseHandlerType#validate_join
+	    # 指定したセルの結合先が、このハンドラタイプに該当するかを検証
+	    # handler:: Handler : ハンドラ
+	    # cell:: Cell : セル
+	    # join:: Join : 結合 (declarationがPortであるもの)
+		def validate_join(handler, cell, join)
+        return !generate_attr_map(handler, cell).nil?
+		end
+
+	    #=== NotifierPlugin#BaseHandlerType#generate_attr_map
+	    # 指定したセルの属性と、既知のHandlerAttributeのマッピングを
+	    # 生成し、Hash<HandlerAttribute, Join> (各属性とそれに対応する
+	    # Join(declarationがDeclのもの)を表すHash)、あるいは、
+		# マッピングが行えない場合(属性の不足、過剰)はnilを返す。
+	    #
+	    # handler:: Handler : ハンドラ
+	    # cell:: Cell : セル
+		def generate_attr_map(handler, cell)
+			map = {}
+
+			join_list = cell.get_join_list
+
+			ATTRS.each { |known_attr|
+				attr_name = known_attr.name_for_handler(handler)
+				join = join_list.get_item(attr_name.to_sym)
+
+				# このセルタイプにおいて必須の属性か?
+				is_required = @required_attributes.include?(known_attr)
+
+				# 属性の指定が不足している? or 過剰?
+				# 注: ハンドラタイプの判別には、セルで値が指定されているか
+				#     が考慮される。セルタイプで初期値が指定されていても、
+				#     それはハンドラタイプの決定に影響しない。
+				return nil if join.nil? != !is_required
+
+				# 必要のない属性であり、指定もされていないので飛ばす
+				next if join.nil?
+
+				# TODO: attrの結合であることを検証
+
+				map[known_attr] = join
+			}
+
+			return map
+		end
+
+	    #=== NotifierPlugin#BaseHandlerType#gen_cfg_handler_type
+	    # タイムイベントの通知の種類を表すコンフィギュレータの記述を生成し、Stringまたはnilを返す
+	    # handler:: Handler : ハンドラ
+		def gen_cfg_handler_type(handler)
+        	raise "called abstract method gen_cfg_handler_type"
+		end
+
+	    #=== NotifierPlugin#BaseHandlerType#gen_cfg_handler_parameters
+	    # タイムイベントの通知の引数を表すコンフィギュレータの記述を生成し、String[]を返す
+	    # handler:: Handler : ハンドラ
+	    # join:: Join : 結合 (declarationがPortであるもの)
+	    # attrMap:: Hash<HandlerAttribute, Join> :
+	    #     各属性とそれに対応するJoin (declarationがDeclのもの)
+	    # cell:: Cell : セル
+		# adpt_gen:: AdapterGenerator : アダプタ関数を生成するオブジェクト
+		def gen_cfg_handler_parameters(handler, join, attrMap, cell, adpt_gen)
+        	return nil
+		end
+
+	    #=== NotifierPlugin#BaseHandlerType#might_fail
+	    # 通知の際、エラーが発生し、その結果エラー通知を呼ぶ必要が生じる
+	    # かどうかを返す。
+		def might_fail
+			return false
+		end
+
+	end
+	class BaseTaskHandlerType < BaseHandlerType
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				join && join.get_rhs_cell.get_celltype.get_name == :tTask
+		end
+		def gen_cfg_handler_parameters(handler, join, attrMap, cell, adpt_gen)
+			taskCell = join.get_cell
+			id_attr_join = taskCell.get_join_list.get_item(:id)
+			id_attr = join.get_rhs_cell.get_celltype.find(:id)
+			if id_attr_join
+				# セル生成時に初期化する場合
+				id = id_attr_join.get_rhs.to_s
+			else
+				# セルタイプの初期化値を使う場合
+				id = id_attr.get_initializer.to_s
+			end
+
+			# $id$等の置換
+			name_array = taskCell.get_celltype.get_name_array(taskCell)
+			id = taskCell.get_celltype.subst_name(id, name_array)
+
+        	return [id]
+		end
+		def might_fail
+			return true
+		end
+	end
+	class ActivateTaskHandlerType < BaseTaskHandlerType
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				join.get_port_name == :eiActivateNotificationHandler
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when EVENT_HANDLER then return "TNFY_ACTTSK"
+				when ERROR_HANDLER then return "TENFY_ACTTSK"
+				else raise "unknown handler #{handler}"
+			end
+		end
+	end
+	class WakeUpTaskHandlerType < BaseTaskHandlerType
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				join.get_port_name == :eiWakeUpNotificationHandler
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when EVENT_HANDLER then return "TNFY_WUPTSK"
+				when ERROR_HANDLER then return "TENFY_WUPTSK"
+				else raise "unknown handler #{handler}"
+			end
+		end
+	end
+	class SetVariableHandlerType < BaseHandlerType
+		def initialize()
+			super
+			@required_attributes = [
+				SETVAR_ADDR_ATTR,
+				SETVAR_VALUE_ATTR
+			] # .to_set
+		end
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				join.nil? &&
+				handler == EVENT_HANDLER
+		end
+		def gen_cfg_handler_parameters(handler, join, attrMap, cell, adpt_gen)
+			var_addr = attrMap[SETVAR_ADDR_ATTR].get_rhs.to_s
+			var_value = attrMap[SETVAR_VALUE_ATTR].get_rhs.to_s
+
+			# $id$等の置換
+			name_array = cell.get_celltype.get_name_array(cell)
+			var_addr = cell.get_celltype.subst_name(var_addr, name_array)
+			var_value = cell.get_celltype.subst_name(var_value, name_array)
+
+        	return [var_addr, var_value]
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when EVENT_HANDLER then return "TNFY_SETVAR"
+				else raise "unknown handler #{handler}"
+			end
+		end
+	end
+	class SetVariableToErrorCodeHandlerType < BaseHandlerType
+		def initialize()
+			super
+			@required_attributes = [
+				SETVAR_ADDR_ATTR
+			] # .to_set
+		end
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				join.nil? &&
+				handler == ERROR_HANDLER
+		end
+		def gen_cfg_handler_parameters(handler, join, attrMap, cell, adpt_gen)
+			var_addr = attrMap[SETVAR_ADDR_ATTR].get_rhs.to_s
+
+			# $id$等の置換
+			name_array = cell.get_celltype.get_name_array(cell)
+			var_addr = cell.get_celltype.subst_name(var_addr, name_array)
+
+        	return [var_addr]
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when ERROR_HANDLER then return "TENFY_SETVAR"
+				else raise "unknown handler #{handler}"
+			end
+		end
+	end
+	class IncrementVariableHandlerType < BaseHandlerType
+		def initialize()
+			super
+			@required_attributes = [
+				INCVAR_ADDR_ATTR
+			] # .to_set
+		end
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				join.nil?
+		end
+		def gen_cfg_handler_parameters(handler, join, attrMap, cell, adpt_gen)
+			var_addr = attrMap[INCVAR_ADDR_ATTR].get_rhs.to_s
+
+			# $id$等の置換
+			name_array = cell.get_celltype.get_name_array(cell)
+			var_addr = cell.get_celltype.subst_name(var_addr, name_array)
+
+        	return [var_addr]
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when EVENT_HANDLER then return "TNFY_INCVAR"
+				when ERROR_HANDLER then return "TENFY_INCVAR"
+				else raise "unknown handler #{handler}"
+			end
+		end
+	end
+	class SignalSemaphoreHandlerType < BaseHandlerType
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				join && join.get_rhs_cell.get_celltype.get_name == :tSemaphore
+		end
+		def gen_cfg_handler_parameters(handler, join, attrMap, cell, adpt_gen)
+			semaphoreCell = join.get_cell
+			id_attr_join = semaphoreCell.get_join_list.get_item(:id)
+			id_attr = join.get_rhs_cell.get_celltype.find(:id)
+			if id_attr_join
+				# セル生成時に初期化する場合
+				id = id_attr_join.get_rhs.to_s
+			else
+				# セルタイプの初期化値を使う場合
+				id = id_attr.get_initializer.to_s
+			end
+
+			# $id$等の置換
+			name_array = semaphoreCell.get_celltype.get_name_array(semaphoreCell)
+			id = semaphoreCell.get_celltype.subst_name(id, name_array)
+
+        	return [id]
+		end
+		def might_fail
+			return true
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when EVENT_HANDLER then return "TNFY_SIGSEM"
+				when ERROR_HANDLER then return "TENFY_SIGSEM"
+				else raise "unknown handler #{handler}"
+			end
+		end
+	end
+	class SetEventflagHandlerType < BaseHandlerType
+		def initialize()
+			super
+			@required_attributes = [
+				SETFLG_FLAG_ATTR
+			] # .to_set
+		end
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				join && join.get_rhs_cell.get_celltype.get_name == :tEventflag
+		end
+		def gen_cfg_handler_parameters(handler, join, attrMap, cell, adpt_gen)
+			eventflagCell = join.get_cell
+			id_attr_join = eventflagCell.get_join_list.get_item(:id)
+			id_attr = join.get_rhs_cell.get_celltype.find(:id)
+			if id_attr_join
+				# セル生成時に初期化する場合
+				id = id_attr_join.get_rhs.to_s
+			else
+				# セルタイプの初期化値を使う場合
+				id = id_attr.get_initializer.to_s
+			end
+			flg_pattern = attrMap[SETFLG_FLAG_ATTR].get_rhs.to_s
+
+			# $id$等の置換
+			name_array = eventflagCell.get_celltype.get_name_array(eventflagCell)
+			id = eventflagCell.get_celltype.subst_name(id, name_array)
+
+			name_array = cell.get_celltype.get_name_array(cell)
+			flg_pattern = cell.get_celltype.subst_name(flg_pattern, name_array)
+
+        	return [id, flg_pattern]
+		end
+		def might_fail
+			return true
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when EVENT_HANDLER then return "TNFY_SETFLG"
+				when ERROR_HANDLER then return "TENFY_SETFLG"
+				else raise "unknown handler #{handler}"
+			end
+		end
+	end
+	class DataqueueHandlerType < BaseHandlerType
+		def initialize()
+			super
+		end
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				join && join.get_rhs_cell.get_celltype.get_name == :tDataqueue
+		end
+		def gen_cfg_handler_parameters(handler, join, attrMap, cell, adpt_gen)
+			dataqueueCell = join.get_cell
+			id_attr_join = dataqueueCell.get_join_list.get_item(:id)
+			id_attr = join.get_rhs_cell.get_celltype.find(:id)
+			if id_attr_join
+				# セル生成時に初期化する場合
+				id = id_attr_join.get_rhs.to_s
+			else
+				# セルタイプの初期化値を使う場合
+				id = id_attr.get_initializer.to_s
+			end
+
+			# $id$等の置換
+			name_array = dataqueueCell.get_celltype.get_name_array(dataqueueCell)
+			id = dataqueueCell.get_celltype.subst_name(id, name_array)
+
+			name_array = cell.get_celltype.get_name_array(cell)
+
+        	return [id]
+		end
+		def might_fail
+			return true
+		end
+	end
+	class SendToDataqueueHandlerType < DataqueueHandlerType
+		def initialize()
+			super
+			@required_attributes = [
+				SNDDTQ_VALUE_ATTR
+			] # .to_set
+		end
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) && handler == EVENT_HANDLER
+		end
+		def gen_cfg_handler_parameters(handler, join, attrMap, cell, adpt_gen)
+			params = super(handler, join, attrMap, cell, adpt_gen)
+
+			sent_value = attrMap[SNDDTQ_VALUE_ATTR].get_rhs.to_s
+
+			# $id$等の置換
+			name_array = cell.get_celltype.get_name_array(cell)
+			sent_value = cell.get_celltype.subst_name(sent_value, name_array)
+
+			params << sent_value
+
+        	return params
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when EVENT_HANDLER then return "TNFY_SNDDTQ"
+				else raise "unknown handler #{handler}"
+			end
+		end
+	end
+	class SendErrorCodeToDataqueueHandlerType < DataqueueHandlerType
+		def initialize()
+			super
+		end
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) && handler == ERROR_HANDLER
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when ERROR_HANDLER then return "TENFY_SNDDTQ"
+				else raise "unknown handler #{handler}"
+			end
+		end
+	end
+	class UserHandlerType < BaseHandlerType
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				handler != ERROR_HANDLER && # invalid for error handler
+				join && join.get_rhs_cell.get_celltype.get_name == :tTimeEventHandler
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when EVENT_HANDLER then return "TNFY_HANDLER"
+				else raise "unknown handler #{handler}"
+			end
+		end
+		def gen_cfg_handler_parameters(handler, join, attrMap, cell, adpt_gen)
+			# tTimeEventHandlerの結合先を取得
+			handler_cell = join.get_rhs_cell
+	    	call_join = handler_cell.get_join_list.get_item(:ciHandlerBody)
+
+			# 結合されていない場合はtecsgenがエラーを出すはずなのでここでは
+			# エラーにせず無視する．
+			return [] unless call_join
+
+			# アダプタ関数ハンドルを取得
+			adapter_handle = adpt_gen.make_adapter_handle(call_join)
+        	return [adapter_handle[1], adapter_handle[0]]
+		end
+	end
+	class NullHandlerType < BaseHandlerType
+		def validate_join(handler, cell, join, *args)
+			return super(handler, cell, join, *args) &&
+				join.nil? &&
+				handler != EVENT_HANDLER # handler is mandatory for normal handler!
+		end
+		def gen_cfg_handler_type(handler)
+			case handler
+				when ERROR_HANDLER then return nil
+				else raise "unknown handler #{handler}"
+			end
+		end
+	end
+
+	HANDLER_TYPES = [
+		ActivateTaskHandlerType.new,
+		WakeUpTaskHandlerType.new,
+		SetVariableHandlerType.new,
+		SetVariableToErrorCodeHandlerType.new,
+		IncrementVariableHandlerType.new,
+		SignalSemaphoreHandlerType.new,
+		SetEventflagHandlerType.new,
+		SendToDataqueueHandlerType.new,
+		SendErrorCodeToDataqueueHandlerType.new,
+		UserHandlerType.new,
+		NullHandlerType.new
+	]
+
+    #@celltype:: Celltype
+    #@option:: String     :オプション文字列
+    def initialize( celltype, option )
+    	super
+    	@plugin_arg_check_proc_tab = NotifierPluginArgProc
+    	@plugin_arg_str = option
+    	@plugin_arg_str = option.gsub( /\A"(.*)/, '\1' )    # 前後の "" を取り除く
+    	@plugin_arg_str.sub!( /(.*)"\z/, '\1' )
+    	@factory = nil
+    	@output_file = nil
+    	parse_plugin_arg
+    	unless @factory
+    		cdl_error("NTF1003 celltype $1: option factory is not specified",
+    			celltype.get_name)
+    	end
+    	unless @output_file
+    		cdl_error("NTF1003 celltype $1: option output_file is not specified",
+    			celltype.get_name)
+    	end
+    end
+
+    def set_factory(template_string)
+    	unless @factory.nil?
+    		cdl_error("NTF1003 celltype $1: option factory was specified more than once",
+    			celltype.get_name)
+    	end
+    	@factory = template_string
+    end
+
+    def set_factory_output_file(output_file)
+    	unless @output_file.nil?
+    		cdl_error("NTF1003 celltype $1: option output_file was specified more than once",
+    			celltype.get_name)
+    	end
+    	@output_file = output_file
+    end
+
+    def gen_factory file
+        # puts "===== begin #{@celltype.get_name.to_s} plugin ====="
+
+        kernelCfg = AppFile.open( "#{$gen}/#{@output_file}" )
+        kernelCfg.print "\n/* Generated by #{self.class.name} */\n"
+        kernelCfg.print "\#include \"tTimeEventHandler.h\"\n"
+
+		# アダプタ関数を生成する準備
+		@adpt_gen = AdapterGenerator.new("tTimeEventHandler", @celltype.get_global_name)
+
+    	# 属性置換が行えることを検証する。
+    	# ここで行うのは、factoryで指定された属性名が
+    	# 存在することを確認し、しなければエラーを出力することのみである。
+    	# セルごとの処理の最中にエラーを出力することも可能ではあるが、
+    	# そうするとセルタイプ側の問題であるのにもかかわらず、セルごとに
+    	# エラーが表示されてしまう。
+    	# {{attribute_name}} -> attribute_value
+    	@factory.scan(/\{\{([a-zA-Z0-9_]*?)\}\}/) { |match|
+    		name = $1.to_sym
+
+    		# {{_handler_params_}} はハンドラに関する指定。プラグイン内で値が生成される
+    		next if name == :_handler_params_
+
+			subst_attr = @celltype.find(name)
+			unless subst_attr
+	    		cdl_error( "NTF1007 celltype $1: additional_param: attribute $2 does not exist.",
+	    			@celltype.get_name, name)
+			end
+		}
+
+        @celltype.get_cell_list.each { |cell|
+        	gen_factory_for_cell kernelCfg, cell
+        }
+
+		# アダプタ関数の生成を完了させる
+		@adpt_gen.finish
+
+        kernelCfg.close
+        # puts "===== end #{@celltype.get_name.to_s} plugin ====="
+    end
+
+    def gen_factory_for_cell(kernelCfg, cell)
+      # print "########## gen_factory_for_cell cell=#{cell.get_name}\n"
+    	handler_flags = []
+    	handler_args = []
+
+    	event_handler_might_fail = true
+    	handler_flag = nil
+
+		# ignoreErrorsを取得
+		ignoreErrors_attr_join = cell.get_join_list.get_item(:ignoreErrors)
+		ignoreErrors_attr = cell.get_celltype.find(:ignoreErrors)
+		if ignoreErrors_attr_join
+			# セル生成時に初期化する場合
+			ignoreErrors = ignoreErrors_attr_join.get_rhs.to_s
+		else
+			# セルタイプの初期化値を使う場合
+			ignoreErrors = ignoreErrors_attr.get_initializer.to_s
+		end
+		case ignoreErrors
+			when 'true' then ignoreErrors = true
+			when 'false' then ignoreErrors = false
+			else
+				cdl_warning2( cell.get_locale, "NTF1005 cell $1: unrecognized value '$2' specified for ignoreErrors",
+					cell.get_name, ignoreErrors )
+				ignoreErrors = false
+		end
+
+    # ドメイン指定用文字列
+    pre_text  = ""
+    post_text = "\n"
+    indent    = ""
+ 
+    	[EVENT_HANDLER, ERROR_HANDLER].each { |handler|
+    		# 呼び口の結合を取得
+    		call_join = cell.get_join_list.get_item(handler.call_port_name.to_sym)
+        domain_root = cell.get_region.get_domain_root
+        if cell.get_region.get_domain_root.get_domain_type then
+          # print "cell=#{cell.get_name} domain_root=#{domain_root.get_name} domain_type=#{domain_root.get_domain_type.get_name} domain_option=#{domain_root.get_domain_type.get_option}\n"
+        else
+          # print "cell=#{cell.get_name} domain_root=#{cell.get_region.get_domain_root.get_name}\n"
+        end
+        if call_join
+          # print "validate_join: hanlder=#{handler.class.name} cell=#{cell.get_name} join=#{call_join.get_name} rhs_cell=#{call_join.get_cell}\n"
+        else
+          # print "validate_join: hanlder=#{handler.class.name} cell=#{cell.get_name}\n"
+        end
+
+	    	# ハンドラタイプを判別する
+	    	matches = HANDLER_TYPES.select { |handler_type|
+	    		handler_type.validate_join(handler, cell, call_join)
+	    	}
+
+	    	if matches.length == 0
+	    		cdl_error2( cell.get_locale, "NTF1001 cell $1: no matching handler type found for $2", cell.get_name, handler.call_port_name )
+	    		next
+        end
+
+			# 最初に見つかった有効なハンドラタイプを使用
+	    	ht = matches[0]
+
+      # ドメインプラグインが指定されている場合、所属ドメインのチェック
+      domain_root = cell.get_region.get_domain_root
+      if domain_root.get_domain_type then
+        if domain_root.get_domain_type.get_name == :HRP then
+          option = domain_root.get_domain_type.get_option
+          matches.each{ |match|
+            # p "match:#{match}"
+            case match
+            when ActivateTaskHandlerType,       WakeUpTaskHandlerType,
+                 SetVariableHandlerType,        SetVariableToErrorCodeHandlerType,
+ 		             IncrementVariableHandlerType,  SignalSemaphoreHandlerType, 
+		             SetEventflagHandlerType,       SendToDataqueueHandlerType,
+		             SendErrorCodeToDataqueueHandlerType
+              if option == "OutOfDomain" then
+                cdl_error2( cell.get_locale, "NTF9999: NotifierPlugin: $1 cannot be placed out of domain", cell.get_name )
+              elsif call_join.get_cell.get_region.get_domain_root == nil ||
+                    call_join.get_cell.get_region.get_domain_root != domain_root then
+                cdl_error2( cell.get_locale, "NTF9999: NotifierPlugin: $1 and $2 must be placed in same domain", cell.get_name, call_join.get_cell.get_name )
+              end
+              dbgPrint "#{self.class.name}: match pattern 1.\n"
+            when UserHandlerType
+              if option != "kernel" then
+                cdl_error2( cell.get_locale, "NTF9999: NotifierPlugin: $1 can be placed in kernel domain only, because notify target is handler", cell.get_name )
+              elsif call_join.get_cell.get_region.get_domain_root == nil ||
+                    call_join.get_cell.get_region.get_domain_root != domain_root then
+                cdl_error2( cell.get_locale, "NTF9999: NotifierPlugin: $1 and $2 must be placed in same domain", cell.get_name, call_join.get_cell.get_name )
+              end
+              dbgPrint "#{self.class.name}: match pattern 2.\n"
+		        when NullHandlerType.new  # エラー通知を指定していない
+              dbgPrint "#{self.class.name}: match pattern 3.\n"
+            end
+          }
+
+          # if cell.get_region.get_param == :KERNEL_DOMAIN
+          if option == "kernel"
+            pre_text  = "KERNEL_DOMAIN{\n"
+            post_text = "}\n"
+            indent    =  "\t"
+          elsif option != "OutOfDomain" then
+            pre_text  = "DOMAIN(#{domain_root.get_name.to_s}){\n"
+            post_text = "}\n"
+            indent    =  "\t"
+          end
+        else
+          cdl_error( "NTF9999: NotifierPlugin: unknown domain type $1", domain_root.get_domain_type.get_name )
+        end
+
+      end
+
+			# 通知ハンドラで「エラーが発生するはずがない」のに「エラーハンドラが指定されている」
+			# もしくはその逆のパターンを検出する。
+			# (handler_flagがnilである場合、ハンドラタイプが不明であり、エラーが発生するか不明
+			#  なため、検出は行わない。)
+    		if handler == ERROR_HANDLER && !ht.is_a?(NullHandlerType) && !event_handler_might_fail
+	    		cdl_error2( cell.get_locale, "NTF1004 cell $1: handler type $2 which never raises an error was inferred for the normal notification handler, but an error notification handler was specified.",
+	    			cell.get_name, handler_flag)
+    		end
+    		if handler == ERROR_HANDLER && ht.is_a?(NullHandlerType) && event_handler_might_fail && !ignoreErrors
+	    		cdl_warning2( cell.get_locale, "NTF1006 cell $1: handler type $2 which might raise an error was inferred for the normal notificaton handler, but an error notification handler was not specified.",
+	    			cell.get_name, handler_flag)
+    		end
+
+			# assertion
+	    	unless ht.validate_join(handler, cell, call_join)
+	    		raise "!validate_join"
+	    	end
+
+			# 通知方法の静的API記述を生成する
+	    	handler_flag = ht.gen_cfg_handler_type(handler)
+	    	handler_flags << handler_flag if handler_flag
+
+	    	attr_map = ht.generate_attr_map(handler, cell)
+
+	    	handler_arg = ht.gen_cfg_handler_parameters(handler, call_join, attr_map, cell, @adpt_gen)
+	    	handler_args += handler_arg if handler_arg
+
+	    	if handler == EVENT_HANDLER
+	    		event_handler_might_fail = ht.might_fail
+	    	end
+    	}
+
+		# $id$等の置換
+		name_array = cell.get_celltype.get_name_array(cell)
+		handler_args.collect! { |e|
+			if e == "$cbp$"
+				cell.get_celltype.subst_name(e, name_array)
+			else
+				e
+			end
+		}
+
+    	# tecsgen.cfgの記述を生成する。
+    	# factoryに対し、パラメータ置換を行う。
+    	# {{attribute_name}} -> attribute_value
+    	text = @factory.gsub(/\{\{([a-zA-Z0-9_]*?)\}\}/) { |match|
+    		name = $1.to_sym
+			subst_attr = cell.get_celltype.find(name)
+
+			# {{_handler_params_}} はハンドラの指定に置換する。
+			if name == :_handler_params_
+		    	args_joined = handler_flags.join(' | ')
+		    	if handler_args.length > 0
+			    	args_joined << ", "
+			    	args_joined << handler_args.join(', ')
+			    end
+			    next args_joined
+			end
+
+			unless subst_attr
+				# 属性が見つからないというエラーはすでに報告されているので
+				# ここではダミー値を返しておくだけである。
+				next ""
+			end
+
+			subst_attr_join = cell.get_join_list.get_item(name)
+			if subst_attr_join
+				# セル生成時に初期化する場合
+				subst = subst_attr_join.get_rhs.to_s
+			else
+				# セルタイプの初期化値を使う場合
+				subst = subst_attr.get_initializer.to_s
+			end
+
+			# $id$等の置換
+			cell.get_celltype.subst_name(subst, name_array)
+      }
+
+     # 出力 (CRE_xxx)
+     kernelCfg.print pre_text
+     kernelCfg.print indent, text, "\n"
+     gen_sac kernelCfg, cell, indent
+     kernelCfg.print post_text
+   end
+
+   def gen_sac file, cell, indent
+     domain_root = cell.get_region.get_domain_root
+     if domain_root.get_domain_type then
+       id = (cell.get_attr_initializer :id).to_s
+                 name_array = cell.get_celltype.get_name_array(cell)
+       case cell.get_celltype.get_name
+       when :tCyclicNotifier
+         obj_type = "CYC"
+       when :tAlarmNotifier
+         obj_type = "ALM"
+       else
+         raise "NotifierPlugin: unknown celltype #{cell.get_celltype.get_name}"
+       end
+       id = cell.get_celltype.subst_name(id, name_array)
+       # p obj_type
+       # p HRPPlugin.get_sac_str cell
+       file.print indent, "SAC_#{obj_type}( #{id}, #{HRPPlugin.get_sac_str cell} );\n"
+     end
+   end
+   private :gen_factory_for_cell
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/OpaqueMarshalerPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/OpaqueMarshalerPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/OpaqueMarshalerPlugin.rb	(revision 398)
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== OpaqueMarshaler
+# OpaqueRPC 用のマーシャラ、アンマーシャラセルタイプを生成するシグニチャプラグイン
+
+require_tecsgen_lib "lib/GenOpaqueMarshaler.rb"
+require_tecsgen_lib "lib/GenParamCopy.rb"
+
+class OpaqueMarshalerPlugin < SignaturePlugin
+
+  OpaqueMarshalerPluginArgProc = { }
+
+  include GenOpaqueMarshaler
+  include GenParamCopy
+
+  def initialize( signature, option )
+    super
+    @b_noClientSemaphore = false
+    @noServerChannelOpenerCode = true
+    initialize_opaque_marshaler
+
+    @plugin_arg_check_proc_tab = OpaqueMarshalerPluginArgProc
+    parse_plugin_arg
+    # check_PPAllocator
+    if @signature.need_PPAllocator?(true) then
+      @PPAllocatorSize = 1    # PPAllocatorの必要性有のために設定 (サイズは使われない)
+      necessity = "Necessary"
+    else
+      necessity = "Unnecessary"
+    end
+
+    print "OpaqueMarshalerPlugin: signature=#{signature.get_namespace_path}, PPAllocator=#{necessity}\n"
+  end
+
+  def gen_cdl_file file
+    gen_marshaler_celltype
+    file.print <<EOT
+import( "#{@marshaler_celltype_file_name}" );
+EOT
+  end
+
+  def subst_name( val )
+    return :"_"
+    # return nil
+  end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/OpaqueRPCPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/OpaqueRPCPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/OpaqueRPCPlugin.rb	(revision 398)
@@ -0,0 +1,329 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# 以下を仮定（制限事項）
+#  呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
+#  有符号、無符号でサイズが同じ
+
+require_tecsgen_lib "lib/GenOpaqueMarshaler.rb"
+require_tecsgen_lib "lib/GenParamCopy.rb"
+
+class OpaqueRPCPlugin < ThroughPlugin
+
+  include GenOpaqueMarshaler
+  include GenParamCopy
+
+  # OpaqueRPCPlugin 専用のオプション
+  OpaqueRPCPluginArgProc = RPCPluginArgProc.dup  # 複製を作って元を変更しないようにする
+  OpaqueRPCPluginArgProc[ "noClientSemaphore"  ] = Proc.new { |obj,rhs| obj.set_noClientSemaphore rhs }
+
+  #=== RPCPlugin の initialize
+  #  説明は ThroughPlugin (plugin.rb) を参照
+  def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
+    super
+    @b_noClientSemaphore = false
+    initialize_opaque_marshaler
+
+    @plugin_arg_check_proc_tab = OpaqueRPCPluginArgProc
+    parse_plugin_arg
+    check_opener_code
+    check_PPAllocator
+
+    print "OpaqueRPCPlugin: #{@clientChannelCell}\n"
+
+    @rpc_server_channel_celltype_name = "tOpaqueRPCPlugin_#{@TDRCelltype}_#{@serverChannelCelltype}_#{@signature.get_global_name}"
+    @rpc_server_channel_celltype_file_name = "#{$gen}/#{@rpc_server_channel_celltype_name}.cdl"
+    @rpc_client_channel_celltype_name = "tOpaqueRPCPlugin_#{@TDRCelltype}_#{@clientChannelCelltype}_#{@signature.get_global_name}"
+    @rpc_client_channel_celltype_file_name = "#{$gen}/#{@rpc_client_channel_celltype_name}.cdl"
+  end
+
+  def gen_plugin_decl_code( file )
+
+    gen_marshaler_celltype
+
+    # チャンネル composite セルタイプの生成
+    #  ここで生成された CDL ファイルは、tecsgen が直接 import するのではなく
+    #  セルコードの CDL から import される
+
+    f = CFile.open( @rpc_client_channel_celltype_file_name, "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    f.print <<EOT
+import( "#{@marshaler_celltype_file_name}" );
+
+/* RPC Client side composite celltype */
+composite #{@rpc_client_channel_celltype_name} {
+  /* marshaler entry port */
+  entry #{@signature.get_namespace_path} eThroughEntry;
+  call  sChannel cChannel;
+  [optional]
+    call sRPCErrorHandler cErrorHandler;
+  [optional]
+    call sSemaphore cLockChannel;
+
+  cell #{@TDRCelltype} TDR {
+    cChannel => composite.cChannel;
+  };
+  cell #{@marshaler_celltype_name} Marshaler{
+    cTDR = TDR.eTDR;
+    cErrorHandler => composite.cErrorHandler;
+    cLockChannel  => composite.cLockChannel;
+  };
+
+  composite.eThroughEntry => Marshaler.eClientEntry;
+};
+EOT
+    f.close
+
+    if @PPAllocatorSize then
+      alloc_cell = "  cell tPPAllocator PPAllocator {\n    heapSize = #{@PPAllocatorSize};\n  };\n"
+      alloc_call_port_join = "    cPPAllocator = PPAllocator.ePPAllocator;\n"
+    else
+      alloc_cell = ""
+      alloc_call_port_join = ""
+    end
+
+    f = CFile.open( @rpc_server_channel_celltype_file_name, "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    f.print <<EOT
+import( "#{@marshaler_celltype_file_name}" );
+
+/* RPC Server side composite celltype */
+composite #{@rpc_server_channel_celltype_name} {
+  /* Interface */
+  call  #{@signature.get_namespace_path} #{@call_port_name};
+  call  sChannel   cChannel;
+  [optional]
+    call sRPCErrorHandler cErrorHandler;
+  entry sUnmarshalerMain  eService;
+
+  /* Implementation */
+  cell #{@TDRCelltype} TDR {
+    cChannel => composite.cChannel;
+  };
+#{alloc_cell}  cell #{@unmarshaler_celltype_name} Unmarshaler{
+    cTDR        = TDR.eTDR;
+    cErrorHandler => composite.cErrorHandler;
+    cServerCall => composite.#{@call_port_name};
+#{alloc_call_port_join}  };
+  composite.eService => Unmarshaler.eService;
+};
+EOT
+
+    f.close
+  end
+
+  #===  through cell コードを生成
+  #
+  #
+  def gen_through_cell_code( file )
+
+    gen_plugin_decl_code( file )
+
+    # セルを探す
+    # path =["::",@next_cell.get_name]  # mikan namespace
+    # cell = Namespace.find( path )
+    cell = Namespace.find( @next_cell.get_namespace_path )
+
+    file.print <<EOT
+import( "#{@rpc_client_channel_celltype_file_name}" );
+import( "#{@rpc_server_channel_celltype_file_name}" );
+
+EOT
+
+    ##### クライアント側のセルの生成 #####
+    nest = @start_region.gen_region_str_pre file
+    nest_str = "  " * nest
+
+    # セマフォの生成
+    if @b_noClientSemaphore == false then
+      file.print <<EOT
+
+#{nest_str}  //  Semaphore for Multi-task use ("specify noClientSemaphore" option to delete this)
+#{nest_str}  cell #{@semaphoreCelltype} #{@serverChannelCell}_Semaphore{
+#{nest_str}    #{@semaphoreInitializer}
+#{nest_str}  };
+EOT
+    end
+
+    # クライアント側チャンネル (TINET, Socket など)の生成
+    file.print <<EOT
+#{nest_str}  //  Client Side Channel
+#{nest_str}  cell #{@clientChannelCelltype} #{@clientChannelCell}{
+#{nest_str}    #{@clientChannelInitializer}
+#{nest_str}  };
+
+#{nest_str}  //  Marshaler
+EOT
+
+    # セマフォの結合文
+    if @b_noClientSemaphore == false then
+      semaphore = "#{nest_str}    cLockChannel = #{@serverChannelCell}_Semaphore.eSemaphore;\n"
+    else
+      semaphore = ""
+    end
+
+    ### クライアント側チャンネル (マーシャラ+TDR)の生成 ###
+    # アロケータの指定があるか？
+    if cell.get_allocator_list.length > 0 then
+
+      file.print nest_str
+      file.print "[allocator("
+
+      delim = ""
+      cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc|
+
+        alloc_str = alloc.to_s
+        subst = @substituteAllocator[alloc_str.to_sym]
+        if subst then
+          alloc_str = subst[2]+"."+subst[3]
+        end
+
+        file.print delim
+        delim = ",\n"        # 最終行には出さない
+
+        if subsc then        # 配列添数
+          subsc_str = '[#{subsc}]'
+        else
+          subsc_str = ""
+        end
+
+        eport = "eThroughEntry" #RPCの受け口名に変更
+        file.print nest_str
+        file.print  "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc_str}"
+      end
+
+      file.puts ")]"
+    end
+
+    if @clientErrorHandler then
+      clientErrorHandler_str = "#{nest_str}    cErrorHandler = #{@clientErrorHandler};\n"
+    else
+      clientErrorHandler_str = ""
+    end
+
+    file.print <<EOT
+#{nest_str}  cell #{@rpc_client_channel_celltype_name} #{@cell_name} {
+#{nest_str}    cChannel = #{@clientChannelCell}.eC0;
+#{clientErrorHandler_str}#{semaphore}#{nest_str}  };
+
+EOT
+    ### END: クライアント側チャンネル (マーシャラ+TDR)の生成 ###
+
+    @start_region.gen_region_str_post file
+    file.print "\n\n"
+
+    ##### サーバー側のセルの生成 #####
+    nest = @end_region.gen_region_str_pre file
+    nest_str = "  " * nest
+    if @next_cell_port_subscript then
+      subscript = '[' + @next_cell_port_subscript.to_s + ']'
+    else
+      subscript = ""
+    end
+
+    if @serverErrorHandler then
+      serverErrorHandler_str = "#{nest_str}    cErrorHandler = #{@serverErrorHandler};\n"
+    else
+      serverErrorHandler_str = ""
+    end
+
+    if @b_genOpener then
+      opener = "#{nest_str}    cOpener       = #{@serverChannelCell}.eOpener;\n"
+    else
+      opener = ""
+    end
+
+    # サーバー側チャンネル (TINET, Socket など)
+    file.print <<EOT
+
+#{nest_str}  //  Server Side Channel
+#{nest_str}  cell #{@serverChannelCelltype} #{@serverChannelCell}{
+#{nest_str}    #{@serverChannelInitializer}
+#{nest_str}  };
+EOT
+
+    # サーバー側チャンネル (アンマーシャラ+TDR)
+    file.print <<EOT
+
+#{nest_str}  //  Unmarshaler
+#{nest_str}  cell #{@rpc_server_channel_celltype_name} #{@serverChannelCell}_Unmarshaler {
+#{nest_str}    cChannel = #{@serverChannelCell}.eC1;
+#{nest_str}    #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
+#{serverErrorHandler_str}#{nest_str}  };
+EOT
+
+    # サーバー側タスクメイン
+    file.print <<EOT
+
+#{nest_str}  //  Unmarshaler Task Main
+#{nest_str}  cell #{@taskMainCelltype} #{@serverChannelCell}_TaskMain {
+#{nest_str}    cMain         = #{@serverChannelCell}_Unmarshaler.eService;
+#{opener}#{nest_str}  };
+EOT
+
+    # サーバー側タスク
+    file.print <<EOT
+
+#{nest_str}  //  Unmarshaler Task
+#{nest_str}  cell #{@taskCelltype} #{@serverChannelCell}_Task {
+#{nest_str}    cBody         = #{@serverChannelCell}_TaskMain.eMain;
+#{nest_str}    priority      = #{@taskPriority};
+#{nest_str}    stackSize     = #{@stackSize};
+#{nest_str}    taskAttribute = C_EXP( "TA_ACT" );  /* mikan : marshaler task starts at beginning */
+#{nest_str}  };
+EOT
+    @end_region.gen_region_str_post file
+  end
+
+  #=== プラグイン引数 noClientSemaphore のチェック
+  def set_noClientSemaphore rhs
+    rhs = rhs.to_sym
+    if rhs == :true then
+      @b_noClientSemaphore = true
+    elsif rhs == :false then
+      @b_noClientSemaphore = false
+    else
+      cdl_error( "RPCPlugin: specify true or false for noClientSemaphore" )
+    end
+  end
+end
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/RPCPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/RPCPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/RPCPlugin.rb	(revision 398)
@@ -0,0 +1,273 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+require_tecsgen_lib "lib/GenTransparentMarshaler.rb"
+require_tecsgen_lib "lib/GenParamCopy.rb"
+
+#= Transparent RPC プラグイン
+# Transparent RPC チャンネルを生成する
+# プラグイン引数は以下の RPCPluginArgProc を参照
+
+# mikan through plugin: namespace が考慮されていない
+# これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必要がある
+# tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl
+
+# 以下を仮定（制限事項）
+#  呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
+#  有符号、無符号でサイズが同じ
+
+class RPCPlugin < ThroughPlugin
+
+  include GenTransparentMarshaler
+  include GenParamCopy
+
+  # RPCPlugin 専用のオプション
+  TransparentRPCPluginArgProc = RPCPluginArgProc.dup  # 複製を作って元を変更しないようにする
+  TransparentRPCPluginArgProc[ "noClientSemaphore"  ] = Proc.new { |obj,rhs| obj.set_noClientSemaphore rhs }
+  TransparentRPCPluginArgProc[ "semaphoreCelltype"  ] = Proc.new { |obj,rhs| obj.set_semaphoreCelltype rhs }
+
+  #=== RPCPlugin の initialize
+  #  説明は ThroughPlugin (plugin.rb) を参照
+  def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
+    super
+    @b_noClientSemaphore = false
+    @semaphoreCelltype = "tSemaphore"
+    initialize_transparent_marshaler cell_name
+
+    # オプション：GenTransparentMarshaler 参照
+    @plugin_arg_check_proc_tab = TransparentRPCPluginArgProc
+    parse_plugin_arg
+
+    @rpc_channel_celltype_name = "tRPCPlugin_#{@TDRCelltype}_#{@channelCelltype}_#{@signature.get_global_name}"
+    @rpc_channel_celltype_file_name = "#{$gen}/#{@rpc_channel_celltype_name}.cdl"
+
+    if @signature.need_PPAllocator? then
+      if @PPAllocatorSize == nil then
+        cdl_error( "PPAllocatorSize must be speicified for oneway [in] array" )
+        # @PPAllocatorSize = 0   # 仮に 0 としておく (cdl の構文エラーを避けるため)
+      end
+    end
+
+#    @signature.each_param{ |func_decl, param_decl|
+#      if func_decl.get_type.is_oneway? then
+#        if ( param_decl.get_size || param_decl.get_count ) && param_decl.get_string then
+#          cdl_error( "array of string not supported for oneway function in Transparent RPC" )  # mikan 文字列の配列
+#        elsif param_decl.get_string == -1 then
+#          cdl_error( "length unspecified string is not permited for oneway function in Transparent RPC" )  # mikan 長さ未指定文字列
+#        end
+#      end
+#    }
+  end
+
+  #=== plugin の宣言コード (celltype の定義) 生成
+  def gen_plugin_decl_code( file )
+
+    ct_name = "#{@ct_name}_#{@channelCelltype}"
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if @@generated_celltype[ ct_name ] == nil then
+      @@generated_celltype[ ct_name ] = [ self ]
+    else
+      @@generated_celltype[ ct_name ] << self
+      return
+    end
+
+    gen_marshaler_celltype
+
+    if @PPAllocatorSize then
+      alloc_cell = "  cell tPPAllocator PPAllocator {\n    heapSize = #{@PPAllocatorSize};\n  };\n"
+      alloc_call_port_join = "    cPPAllocator = PPAllocator.ePPAllocator;\n"
+    else
+      alloc_cell = ""
+      alloc_call_port_join = ""
+    end
+
+    if @b_noClientSemaphore == false then
+      semaphore1 = <<EOT
+  // Semaphore for Multi-task use ("specify noClientSemaphore" option to delete this)
+  cell #{@semaphoreCelltype} Semaphore {
+    count = 1;
+    attribute = C_EXP( "TA_NULL" );
+  };
+EOT
+      semaphore2 = "    cLockChannel = Semaphore.eSemaphore;\n"
+    else
+      semaphore1 = ""
+      semaphore2 = ""
+    end
+
+    f = CFile.open( @rpc_channel_celltype_file_name, "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    f.print <<EOT
+import( "#{@marshaler_celltype_file_name}" );
+
+[active]
+composite #{@rpc_channel_celltype_name} {
+  /* Interface */
+  attr {
+    PRI taskPriority;
+  };
+  call #{@signature.get_namespace_path} #{@call_port_name};
+  entry #{@signature.get_namespace_path} eThroughEntry;
+  call sTDR       cTDR;
+  call sEventflag cEventflag;
+
+  /* Implementation */
+#{semaphore1}
+  cell #{@marshaler_celltype_name} #{@signature.get_global_name}_marshaler{
+    cTDR         => composite.cTDR;
+    cEventflag   => composite.cEventflag;
+#{semaphore2}  };
+#{alloc_cell}  cell #{@unmarshaler_celltype_name} #{@signature.get_global_name}_unmarshaler{
+    cTDR        => composite.cTDR;
+    cEventflag  => composite.cEventflag;
+    cServerCall => composite.#{@call_port_name};
+#{alloc_call_port_join}  };
+  cell tRPCDedicatedTaskMain RPCTaskMain{
+    cMain = #{@signature.get_global_name}_unmarshaler.eUnmarshalAndCallFunction;
+  };
+  cell tTask Task {
+    cBody     = RPCTaskMain.eMain;
+    priority  = taskPriority;
+    taskAttribute = C_EXP( "TA_ACT" );  /* mikan : marshaler starts at the beginning */
+    stackSize     = 4096;
+  };
+  composite.eThroughEntry => #{@signature.get_global_name}_marshaler.eClientEntry;
+};
+EOT
+    # mikan stackSize option & 最新 tecs_package 対応
+
+    f.close
+  end
+
+  #===  through cell コードを生成
+  #
+  #
+  def gen_through_cell_code( file )
+
+    gen_plugin_decl_code( file )
+
+    # セルを探す
+    # path =["::",@next_cell.get_global_name]
+    # cell = Namespace.find( path )
+    cell = Namespace.find( @next_cell.get_namespace_path )
+
+    file.print <<EOT
+import( "#{@rpc_channel_celltype_file_name}" );
+
+EOT
+
+    nest = @region.gen_region_str_pre file
+    indent_str = "  " * nest
+    if @next_cell_port_subscript then
+      subscript = '[' + @next_cell_port_subscript.to_s + ']'
+    else
+      subscript = ""
+    end
+
+    file.print <<EOT
+#{indent_str}// 一方向チャンネルセル
+#{indent_str}cell #{@channelCelltype} #{@channelCellName} {
+#{indent_str}};
+
+#{indent_str}// RPC チャンネルセル
+EOT
+
+    # #473 が解決された場合、composite リレーアロケータに変更すべき
+    # アロケータの指定があるか？
+    if cell.get_allocator_list.length > 0 then
+
+      file.print "#{indent_str}[allocator("
+
+      delim = ""
+      cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc|
+
+        file.print delim
+        delim = ",\n#{indent_str}           "        # 最終行には出さない
+
+        if subsc then        # 配列添数
+          subsc_str = '[#{subsc}]'
+        else
+          subsc_str = ""
+        end
+
+        eport = "eThroughEntry" #RPCの受け口名に変更
+        file.print  "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc}"
+      end
+
+      file.puts ")]"
+    end
+
+    file.print <<EOT
+#{indent_str}cell #{@rpc_channel_celltype_name} #{@cell_name} {
+#{indent_str}  #{@call_port_name} = #{@next_cell.get_name}.#{@next_cell_port_name}#{subscript};
+#{indent_str}  cTDR         = #{@channelCellName}.eTDR;
+#{indent_str}  cEventflag   = #{@channelCellName}.eEventflag;
+#{indent_str}  taskPriority = #{@task_priority};
+#{indent_str}};
+EOT
+    @region.gen_region_str_post file
+  end
+
+
+  #=== プラグイン引数 noClientSemaphore のチェック
+  def set_noClientSemaphore rhs
+    rhs = rhs.to_sym
+    if rhs == :true then
+      @b_noClientSemaphore = true
+    elsif rhs == :false then
+      @b_noClientSemaphore = false
+    else
+      cdl_error( "RPCPlugin: specify true or false for noClientSemaphore" )
+    end
+  end
+
+  #=== プラグイン引数 semaphoreCelltype のチェック
+  def set_semaphoreCelltype rhs
+    @semaphoreCelltype = rhs.to_sym
+    nsp = NamespacePath.analyze( @semaphoreCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: semaphoreCelltype '#{rhs}' not celltype or not defined" )
+    end
+  end
+end
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/RepeatCellPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/RepeatCellPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/RepeatCellPlugin.rb	(revision 398)
@@ -0,0 +1,169 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#
+#  Copyright (C) 2015-2018 by TOPPERS Project
+#
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#  $Id$
+#++
+
+#== cell を count 個繰り返すセルプラグイン
+# 不完全点：
+#    指定子に対応していない
+#       cell の指定子 (allocator, id)
+#       結合の指定子 (through)
+class RepeatCellPlugin < CellPlugin
+
+  @@plugin_list = []
+  RepeatCellPluginArgProc = {
+    "count" => Proc.new { |obj,rhs| obj.set_count rhs }
+  }
+
+  def initialize( cell, option )
+    super
+    @@plugin_list << self
+    print "RepeatCellPlugin: #{@cell.get_name}\n"
+    # cell.show_tree 0
+    # @cell.get_join_list.get_items.each{ |j|
+    #  print "Join: #{j.get_name} = #{j.get_rhs.to_s}\n"
+    # }
+    @count = 0
+    @plugin_arg_check_proc_tab = RepeatCellPluginArgProc
+    parse_plugin_arg
+  end
+
+  def gen_cdl_file( file )
+    if $verbose then
+      print "#{self.class}: repeat #{@cell.get_name} #(num} times\n"
+    end
+
+    nest = @cell.get_region.gen_region_str_pre file
+    indent_str = "  " * nest
+    @cell.get_name.to_s =~ /.*[^0-9]([0-9]+)\z/
+    if $1 then
+      tail_zero = $1
+      bname = @cell.get_name.to_s.gsub( /[0-9]+\z/, "" )
+    else
+      cdl_error( "#{self.class}: #{@cell.get_name}'s name ends without '0-9'")
+      return
+    end
+    base_count = tail_zero.to_i
+
+    count = 1
+    num = @count
+    file.print "/*  #{num} times repeat of '#{@cell.get_name}' */\n"
+    while count < num
+
+      # セル名のカウント
+      count_str = (count + base_count).to_s
+      if tail_zero.length > count_str.length then
+        leading_zero = "0" * ( tail_zero.length - count_str.length )
+      else
+        leading_zero = ""
+      end
+      cname = bname + leading_zero + count_str
+
+      #   "cell tCelltype Cell {" 
+      file.print "#{indent_str}cell #{@cell.get_celltype.get_name} #{cname}{\n"
+
+      # Join の CDL 文字列生成
+      @cell.get_join_list.get_items.each{ |j|
+
+        # Join の右辺の解析
+        res = j.get_rhs.analyze_cell_join_expression
+        if res then
+          nsp, subscript, port_name = res[0], res[1], res[2]
+        else
+          nsp = j.get_rhs.analyze_single_identifier
+          if nsp then
+            subscript, port_name = nil, nil
+          else
+            file.print "#{indent_str}  #{j.get_name} = #{j.get_rhs.to_s};\n"
+            next
+          end
+        end
+
+        # 右辺のセル名 (末尾の数字をカウントアップ)
+        nsp.get_name.to_s =~ /(.*[^0-9])([0-9]+)\z/
+        if $2 then
+          rhs_tail_num = $2
+          rhs_name_count = count + rhs_tail_num.to_i
+          if rhs_tail_num.length > rhs_name_count.to_s.length then
+            leading_zero = "0" * ( rhs_tail_num.length - rhs_name_count.to_s.length )
+          else
+            leading_zero = ""
+          end
+          rhs_cname = $1 + leading_zero + rhs_name_count.to_s
+          nsp = nsp.change_name_clone rhs_cname
+        end
+
+        # Join 文字列の出力
+        if port_name then
+          # 右辺は セルの結合
+          if subscript then
+            file.print "#{indent_str}  #{j.get_name} = #{nsp.get_path_str}.#{port_name}[#{(count+subscript).to_s}];\n"
+          else
+            file.print "#{indent_str}  #{j.get_name} = #{nsp.get_path_str}.#{port_name};\n"
+          end
+        else
+          # 右辺は単一の識別子
+          file.print "#{indent_str}  #{j.get_name} = #{nsp.get_path_str};\n"
+        end
+      }
+
+      file.print "#{indent_str}};\n\n"
+      count += 1
+    end
+
+    @cell.get_region.gen_region_str_post file
+  end
+
+  #=== count オプションの解析
+  def set_count rhs
+    if rhs =~ /\A\d+\z/
+      @count = rhs.to_i
+    else
+      nsp = NamespacePath.new( rhs.to_sym, true )
+      expr = Expression.create_single_identifier( nsp, nil )
+      res = expr.eval_const( nil )
+      if res == nil then
+        cdl_error( "count value ($1): not single identifier or integer number", rhs.to_s )
+        @count = 0
+      else
+        @count = res
+      end
+    end
+  end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/RepeatJoinPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/RepeatJoinPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/RepeatJoinPlugin.rb	(revision 398)
@@ -0,0 +1,131 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#
+#  Copyright (C) 2015-2018 by TOPPERS Project
+#
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#  $Id$
+#++
+
+class RepeatJoinPlugin < CellPlugin
+
+  RepeatJoinPluginArgProc = {
+    "count" => Proc.new { |obj,rhs| obj.set_count rhs }
+  }
+
+  def initialize( cell, option )
+    super
+    print "RepeatJoinPlugin: #{@cell.get_name}\n"
+    # cell.show_tree 0
+    @plugin_arg_check_proc_tab = RepeatJoinPluginArgProc
+    parse_plugin_arg
+
+    @cell.get_join_list.get_items.each{ |j|
+      # print "Join: #{j.get_name} = #{j.get_rhs.to_s}\n"
+
+      # Join の右辺を解析
+      ret = j.get_rhs.analyze_cell_join_expression
+      if ret == nil then
+        next
+      end
+      rhs_nsp = ret[0]; rhs_subscript = ret[1]; rhs_port_name = ret[2]
+
+      # 呼び口配列で、添数が 0 の場合にのみカウントアップさせる
+      if j.get_subscript == 0 then
+        rhs_name = rhs_nsp.get_name.to_s
+        if rhs_name =~ /(.*[^0-9])([0-9]+)\z/ then
+          b_rhs_name_count = true
+          rhs_name = $1
+          n_digits = $2.length
+          rhs_count_base = $2.to_i
+        else
+          b_rhs_name_count = false
+          rhs_count_base = 0
+        end
+
+        if rhs_subscript && rhs_subscript == 0 then
+          b_rhs_subscript_count = true
+        else
+          b_rhs_subscript_count = false
+        end
+
+        count = 1
+        while count < @count
+          count_str = (count+rhs_count_base).to_s
+
+          if b_rhs_subscript_count then
+            rhs_subscript = count
+          end
+
+          if b_rhs_name_count then
+            if n_digits - count_str.length > 0 then
+              leading_zero = "0" * ( n_digits - count_str.length )
+            else
+              leading_zero = ""
+            end
+
+            rhs_name_real = rhs_name + leading_zero + count_str
+          else
+            rhs_name_real = rhs_name
+          end
+          rhs_nsp2 = rhs_nsp.change_name_clone rhs_name_real.to_sym
+
+          rhs = Expression.create_cell_join_expression( rhs_nsp2, rhs_subscript, rhs_port_name )
+          j2 = Join.new( j.get_name, count, rhs )
+          cell.new_join j2
+
+          count += 1
+        end
+      end
+    }
+  end
+
+  #=== count オプションの解析
+  def set_count rhs
+    if rhs =~ /\A\d+\z/
+      @count = rhs.to_i
+    else
+      nsp = NamespacePath.new( rhs.to_sym, true )
+      expr = Expression.create_single_identifier( nsp, nil )
+      res = expr.eval_const( nil )
+      if res == nil then
+        cdl_error( "count value ($1): not single identifier or integer number", rhs.to_s )
+        @count = 0
+      else
+        @count = res
+      end
+    end
+  end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/SharedOpaqueRPCPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/SharedOpaqueRPCPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/SharedOpaqueRPCPlugin.rb	(revision 398)
@@ -0,0 +1,370 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+require_tecsgen_lib "lib/GenOpaqueMarshaler.rb"
+require_tecsgen_lib "lib/GenParamCopy.rb"
+
+#= SharedOpaqueRPC プラグイン
+# SharedOpaqueRPC チャンネルを生成する
+# プラグイン引数は GenTransparentMarshaler 参照
+
+# mikan through plugin: namespace が考慮されていない
+# これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必要がある
+# tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl
+
+# 以下を仮定（制限事項）
+#  呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
+#  有符号、無符号でサイズが同じ
+
+class SharedOpaqueRPCPlugin < ThroughPlugin
+
+  # チャンネルを共有するプラグインオブジェクトへのハッシュリスト
+  @@shared_channel_list = {}    # { chan_name => [ Plugin_obj0, Plugin_Obj1, ... ] }
+
+  attr_reader :cell_name, :start_region, :end_region
+  include GenOpaqueMarshaler
+  include GenParamCopy
+
+  # SharedOpaqueRPCPlugin 専用のオプション
+  SharedOpaqueRPCPluginArgProc = RPCPluginArgProc.dup  # 複製を作って元を変更しないようにする
+  SharedOpaqueRPCPluginArgProc[ "sharedChannelName"  ] = Proc.new { |obj,rhs| obj.set_sharedChannelName rhs }
+
+  #=== RPCPlugin の initialize
+  #  説明は ThroughPlugin (plugin.rb) を参照
+  def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
+    super
+    initialize_opaque_marshaler
+    @entry_port_name = :"eClientEntry"   # Marshaler の受け口名 (through セルの入り口)
+
+    # オプション：GenOpaqueMarshaler 参照
+    @plugin_arg_check_proc_tab = SharedOpaqueRPCPluginArgProc
+    @sharedChannelName = nil
+    parse_plugin_arg
+    check_opener_code
+    check_PPAllocator
+
+    @shared_channel_ct_name = :"tSharedOpaqueRPCPluginChannel_tTDR"
+    @shared_channel_server_ct_name = :"#{@shared_channel_ct_name}_Server"
+    @shared_channel_client_ct_name = :"#{@shared_channel_ct_name}_Client"
+    @shared_channel_ct_file_name = "#{$gen}/#{@shared_channel_ct_name}.cdl"
+    if @sharedChannelName == nil then
+      cdl_error( "'sharedChannelName' option: mandatory")
+    else
+      @shared_channel_cell = @sharedChannelName
+    end
+
+    if @@shared_channel_list[ @shared_channel_cell ] == nil then
+      @@shared_channel_list[ @shared_channel_cell ] = [ self ]
+    else
+      @@shared_channel_list[ @shared_channel_cell ] << self
+    end
+    @sub_channel_no = ( @@shared_channel_list[ @shared_channel_cell ].length ) -1
+
+    prev_start = @@shared_channel_list[ @shared_channel_cell ][0].start_region
+    if @start_region != prev_start then
+      # 初出と start リージョン不一致 (初出は、自分自身とチェックされる。無駄だが小さいので放置)
+      cdl_error( "SharedRPCPlugin: start region mismatch current: #{@region.get_name} previous: #{prev_start.get_name}")
+    end
+
+    prev_end = @@shared_channel_list[ @shared_channel_cell ][0].end_region
+    if @end_region != prev_end then
+      # 初出と end リージョン不一致  (初出は、自分自身とチェックされる。無駄だが小さいので放置)
+      cdl_error( "SharedRPCPlugin: end region mismatch current: #{@region.get_name} previous: #{prev_end.get_name}")
+    end
+
+  end
+
+  # def set_through_info( start_region, end_region, through_type )
+  #   super
+  # end
+
+  #=== プラグイン引数 sharedChannelCell のチェック
+  def set_sharedChannelName( rhs )
+    @sharedChannelName = rhs
+    # path = [ "::", rhs ]
+    # obj = Namespace.find( path )
+    # if ! obj.instance_of?( Cell ) then
+    #   cdl_error( "SharedOpaqueRPCPlugin: sharedChannelName '#{rhs}' not cell" )
+    # end
+  end
+
+  def gen_plugin_decl_code( file )
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if @@generated_celltype[ @shared_channel_server_ct_name ] == nil then
+      @@generated_celltype[ @shared_channel_server_ct_name ] = [ self ]
+    else
+      @@generated_celltype[ @shared_channel_server_ct_name ] << self
+    end
+
+    gen_marshaler_celltype
+
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    if @PPAllocatorSize then
+      alloc_call_port = "  call sPPAllocator cPPAllocator;\n"
+      alloc_call_port_join = "  cPPAllocator => composite.cPPAllocator;\n"
+    else
+      alloc_call_port = ""
+      alloc_call_port_join = ""
+    end
+
+    f = CFile.open( @shared_channel_ct_file_name, "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    f.print <<EOT
+
+/* Shared Channel Celltype for Client */
+composite #{@shared_channel_client_ct_name} {
+  entry  sTDR       eTDR;
+  entry  sSemaphore eSemaphore[];
+  call   sChannel   cClientChannel;
+
+  cell tTDR TDR {
+    cChannel => composite.cClientChannel;
+  };
+  cell tSemaphore Semaphore {
+    count = 1;
+    attribute = C_EXP("TA_NULL");
+  };
+  cell tRPCSharedChannelMan SharedChannelMan{
+    cSemaphore             = Semaphore.eSemaphore;
+    cClientSideTDR         = TDR.eTDR;
+  };
+  composite.eSemaphore     => SharedChannelMan.eSemaphore;
+  composite.eTDR           => TDR.eTDR;
+};
+
+/* Shared Channel Celltype for Server */
+[active]
+composite #{@shared_channel_server_ct_name} {
+  entry  sTDR       eTDR;
+  call   sChannel   cServerChannel;
+  call   sUnmarshalerMain  cUnmarshalAndCallFunction[];
+  call   sServerChannelOpener cOpener;
+  attr {
+    PRI    priority;
+  };
+
+  cell tTDR TDR {
+    cChannel => composite.cServerChannel;
+  };
+  cell tRPCSharedTaskMainWithOpener RPCSharedTaskMain {
+    cUnmarshalAndCallFunction => composite.cUnmarshalAndCallFunction;
+    cServerSideTDR = TDR.eTDR;
+    cOpener => composite.cOpener;
+  };
+  cell tTask Task {
+    cBody = RPCSharedTaskMain.eMain;
+    taskAttribute = C_EXP("TA_ACT");
+    stackSize = 4096;
+    priority = composite.priority;
+  };
+  composite.eTDR           => TDR.eTDR;
+};
+
+EOT
+    f.close
+
+  end
+
+  #===  through cell コードを生成
+  #
+  #
+  def gen_through_cell_code( file )
+
+    gen_plugin_decl_code( file )
+
+    file.print <<EOT
+
+import( "#{@marshaler_celltype_file_name}" );
+import( "#{@shared_channel_ct_file_name}" );
+EOT
+
+#    nest = @caller_cell.get_region.gen_region_str_pre file
+    nest = @start_region.gen_region_str_pre file
+    indent_str = "  " * nest
+    nest_str = "  " * nest
+    if @next_cell_port_subscript then
+      subscript = '[' + @next_cell_port_subscript.to_s + ']'
+    else
+      subscript = ""
+    end
+
+    # セルを探す
+    # path =["::",@next_cell.get_name]
+    # cell = Namespace.find( path )
+    cell = Namespace.find( @next_cell.get_namespace_path )
+
+    # 共有される通信チャンネルの生成のプロトタイプ宣言
+    file.print <<EOT
+#{indent_str}cell #{@shared_channel_client_ct_name} #{@shared_channel_cell};
+EOT
+
+    # マーシャラセルの生成（アロケータコードの生成から）
+    # アロケータの指定があるか？
+    if cell.get_allocator_list.length > 0 then
+
+      file.print "#{indent_str}[allocator("
+
+      delim = ""
+      cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc|
+
+        alloc_str = alloc.to_s
+        subst = @substituteAllocator[alloc_str.to_sym]
+
+        if subst then
+          alloc_str = subst[2]+"."+subst[3]
+        end
+
+        file.print delim
+        delim = ",\n#{indent_str}           "        # 最終行には出さない
+
+        if subsc then        # 配列添数
+          subsc_str = '[#{subsc}]'
+        else
+          subsc_str = ""
+        end
+
+        eport = @entry_port_name #RPCの受け口名に変更
+        file.print  "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc_str}"
+      end
+
+      file.puts ")]"
+    end
+
+    # マーシャラセル本体生成
+    file.print <<EOT
+/* OpaqueRPC Marshaler Cell */
+#{indent_str}cell #{@marshaler_celltype_name} #{@cell_name} {
+#{indent_str}  cTDR         = #{@shared_channel_cell}.eTDR;
+#{indent_str}  cLockChannel = #{@shared_channel_cell}.eSemaphore[#{@sub_channel_no}];
+#{indent_str}};
+EOT
+    # @caller_cell.get_region.gen_region_str_post file
+    @start_region.gen_region_str_post file
+
+    # アンマーシャラセルの出力
+    # セル本体の生成
+    nest = @end_region.gen_region_str_pre file
+
+    file.print <<EOT
+/* Server Channel Cell prototype */
+#{indent_str}cell #{@shared_channel_server_ct_name} #{@sharedChannelName}_Server;
+
+EOT
+
+    # PPAllocator が必要か?
+    if @PPAllocatorSize then
+      if @sub_channel_no == 0 then
+        file.print <<EOT
+#{indent_str}cell tPPAllocator PPAllocator_#{@shared_channel_cell}{
+#{indent_str}  heapSize = #{@PPAllocatorSize};
+#{indent_str}};
+EOT
+      end
+
+      ppallocator_join = "#{indent_str}  cPPAllocator = PPAllocator_#{@shared_channel_cell}.ePPAllocator;\n"
+    else
+      ppallocator_join = ""
+    end
+
+    file.print <<EOT
+#{indent_str}cell #{@unmarshaler_celltype_name} #{@cell_name}_Server {
+#{indent_str}  cTDR         = #{@shared_channel_cell}_Server.eTDR;
+#{indent_str}  cServerCall  = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
+#{ppallocator_join}#{indent_str}};
+EOT
+    @end_region.gen_region_str_post file
+
+  end
+
+  #=== post コード(CDL) を生成
+  # プラグインの後のコードを生成
+  #file:: File: 
+  def self.gen_post_code( file )
+
+    file.print "/* '#{self.name}' post code */\n"
+
+    @@shared_channel_list.each{ |chan_name,plugin_obj_array|
+      file.print "/* '#{chan_name}' shared channel */\n"
+      plugin_obj_array[0].gen_post_code( file, plugin_obj_array )
+    }
+
+  end
+
+  #=== post コード(CDL) を生成
+  # 共有チャンネルを生成する
+  # このメソッドは、チャンネルを共有する最初のプラグインオブジェクトのみ呼び出される
+  def gen_post_code( file, plugin_obj_array )
+
+    # 共有されている通信チャンネルの生成
+    # 各プラグインインスタンスでは @shared_channel_ct_name として記憶している
+    # region = @caller_cell.get_region
+    nest = @start_region.gen_region_str_pre file
+    indent_str = "  " * nest
+    file.print <<EOT
+#{indent_str}cell #{@shared_channel_client_ct_name} #{@sharedChannelName} {
+#{indent_str}    cClientChannel = #{@clientChannelCell}.eC0;
+#{indent_str}};
+EOT
+    @start_region.gen_region_str_post file
+
+    nest = @end_region.gen_region_str_pre file
+    indent_str = "  " * nest
+    file.print "#{indent_str}cell #{@shared_channel_server_ct_name} #{@sharedChannelName}_Server {\n"
+      file.print <<EOT
+#{indent_str}    cServerChannel = #{@serverChannelCell}.eC1;
+#{indent_str}    cOpener        = #{@serverChannelCell}.eOpener;
+EOT
+    plugin_obj_array.each{ |po|
+      file.print <<EOT
+#{indent_str}    cUnmarshalAndCallFunction[] = #{po.cell_name}_Server.eService;
+EOT
+    }
+    file.printf <<EOT
+#{indent_str}    priority = #{@taskPriority};
+#{indent_str}};
+EOT
+    @end_region.gen_region_str_post file
+
+  end
+end
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/SharedRPCPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/SharedRPCPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/SharedRPCPlugin.rb	(revision 398)
@@ -0,0 +1,340 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+require_tecsgen_lib "lib/GenTransparentMarshaler.rb"
+require_tecsgen_lib "lib/GenParamCopy.rb"
+
+#= SharedRPC プラグイン
+# SharedRPC チャンネルを生成する
+# プラグイン引数は GenTransparentMarshaler 参照
+
+# mikan through plugin: namespace が考慮されていない
+# これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必要がある
+# tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl
+
+# 以下を仮定（制限事項）
+#  呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
+#  有符号、無符号でサイズが同じ
+
+class SharedRPCPlugin < ThroughPlugin
+
+  attr_reader :region
+  @@shared_channel_list = {}
+  include GenTransparentMarshaler
+  include GenParamCopy
+
+  #=== RPCPlugin の initialize
+  #  説明は ThroughPlugin (plugin.rb) を参照
+  def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
+
+    # mikan プラグインオプション指定の不一致のチェック task_priority, 
+
+    super
+    initialize_transparent_marshaler cell_name
+
+    # オプション：GenTransparentMarshaler 参照
+    @plugin_arg_check_proc_tab = RPCPluginArgProc
+    @channelCellName = ""     # nil にしておく
+    parse_plugin_arg
+
+    @shared_channel_ct_name = :"tSharedRPCPlugin_#{@channelCelltype}"
+    @shared_channel_ct_file_name = "#{$gen}/#{@shared_channel_ct_name}.cdl"
+    @rpc_channel_celltype_name = :"tSharedRPCPlugin_#{@TDRCelltype}_#{@channelCelltype}_#{@signature.get_global_name}"
+    @rpc_channel_celltype_file_name = "#{$gen}/#{@rpc_channel_celltype_name}.cdl"
+
+    @shared_channel_cell = @channelCellName
+    if @shared_channel_cell == "" then
+      cdl_error( "SharedRPCPlugin: need channelCellName option" )
+    end
+
+    if @@shared_channel_list[ @shared_channel_cell ] == nil then
+      # 初出
+      @@shared_channel_list[ @shared_channel_cell ] = [ self ]
+    else
+      # 二番目以降
+      @@shared_channel_list[ @shared_channel_cell ] << self
+    end
+    @sub_channel_no = ( @@shared_channel_list[ @shared_channel_cell ].length ) -1
+
+    if @region != @@shared_channel_list[ @shared_channel_cell ][0].region then
+      # 初出とリージョン不一致 (初出は、自分自身とチェックされる。無駄だが小さいので放置)
+      cdl_error( "SharedRPCPlugin: preferred region mismatch current: #{@region.get_name} previous: #{@@shared_channel_list[ @shared_channel_cell ][0].region.get_name}")
+    else
+      dbgPrint "SahredRPCPlugin: Region: #{@region.get_name}, #{@@shared_channel_list[ @shared_channel_cell ][0].region.get_name}\n"
+    end
+
+    if @signature.need_PPAllocator? then
+      if @PPAllocatorSize == nil then
+        cdl_error( "PPAllocatorSize must be speicified for oneway [in] array" )
+      end
+    end
+
+  end
+
+  # def set_through_info( start_region, end_region, through_type )
+  #   super
+  #  
+  # end
+
+  def gen_plugin_decl_code( file )
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if @@generated_celltype[ @shared_channel_ct_name ] == nil then
+      @@generated_celltype[ @shared_channel_ct_name ] = [ self ]
+    else
+      @@generated_celltype[ @shared_channel_ct_name ] << self
+    end
+
+    if @@generated_celltype[ @ct_name ] == nil then
+      @@generated_celltype[ @ct_name ] = [ self ]
+    else
+      @@generated_celltype[ @ct_name ] << self
+    end
+
+    gen_marshaler_celltype
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    if @signature.need_PPAllocator? then
+      alloc_call_port = "  call sPPAllocator cPPAllocator;\n"
+      alloc_call_port_join = "  cPPAllocator => composite.cPPAllocator;\n"
+    else
+      alloc_call_port = ""
+      alloc_call_port_join = ""
+    end
+
+    f = CFile.open( @rpc_channel_celltype_file_name, "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    f.print <<EOT
+import( "#{@marshaler_celltype_file_name}" );
+
+composite #{@rpc_channel_celltype_name} {
+  /* Interface */
+  call  #{@signature.get_namespace_path} #{@call_port_name};
+  entry #{@signature.get_namespace_path} eThroughEntry;
+  call  sTDR       cTDR;
+  call  sEventflag cEventflag;
+  entry sUnmarshalerMain  eUnmarshalAndCallFunction;
+#{alloc_call_port}
+  [optional]
+    call sSemaphore cLockChannel;
+
+  /* Implementation */
+  cell #{@marshaler_celltype_name} #{@signature.get_global_name}_marshaler{
+    cTDR         => composite.cTDR;
+    cEventflag   => composite.cEventflag;
+    cLockChannel => composite.cLockChannel;
+  };
+  cell #{@unmarshaler_celltype_name} #{@signature.get_global_name}_unmarshaler{
+    cTDR         => composite.cTDR;
+    cEventflag   => composite.cEventflag;
+    cServerCall  => composite.#{@call_port_name};
+#{alloc_call_port_join}  };
+  composite.eThroughEntry => #{@signature.get_global_name}_marshaler.eClientEntry;
+  composite.eUnmarshalAndCallFunction => #{@signature.get_global_name}_unmarshaler.eUnmarshalAndCallFunction;
+};
+EOT
+    # mikan stackSize option & 最新 tecs_package 対応
+
+    f.close
+
+    f = CFile.open( "#{$gen}/#{@shared_channel_ct_name}.cdl", "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    f.print <<EOT
+[active]
+composite #{@shared_channel_ct_name} {
+  /* Interface */
+  entry  sSemaphore eSemaphore[];
+  call   sUnmarshalerMain  cUnmarshalAndCallFunction[];
+
+  entry  sDataqueue eDataqueue;
+  entry  sTDR       eTDR;
+  entry  sEventflag eEventflag;
+
+  attr {
+    PRI    priority;
+  };
+
+  /* Implementation */
+  cell #{@channelCelltype} Channel{
+  };
+  cell tSemaphore Semaphore {count = 1; attribute = C_EXP("TA_NULL");};
+  cell tRPCSharedTaskMain RPCSharedTaskMain {
+    cUnmarshalAndCallFunction => composite.cUnmarshalAndCallFunction;
+    cServerSideTDR            = Channel.eTDR;
+  };
+  cell tRPCSharedChannelMan RPCChannelMan {
+    cSemaphore                = Semaphore.eSemaphore;
+    cClientSideTDR            = Channel.eTDR;
+  };
+  cell tTask RPCSharedTask {
+    cBody = RPCSharedTaskMain.eMain;
+    taskAttribute = C_EXP("TA_ACT");
+    stackSize = 4096;
+    priority = composite.priority;
+  };
+  composite.eTDR           => Channel.eTDR;
+  composite.eEventflag     => Channel.eEventflag;
+  composite.eSemaphore     => RPCChannelMan.eSemaphore;
+  composite.eDataqueue     => Channel.eDataqueue;
+};
+EOT
+    f.close
+
+  end
+
+  #===  through cell コードを生成
+  #
+  #
+  def gen_through_cell_code( file )
+
+    gen_plugin_decl_code( file )
+
+    file.print <<EOT
+import( "#{@rpc_channel_celltype_file_name}" );
+import( "#{$gen}/#{@shared_channel_ct_name}.cdl" );
+EOT
+
+    # nest = @next_cell.get_region.gen_region_str_pre file
+    nest = @region.gen_region_str_pre file
+    indent_str = "  " * nest
+    if @next_cell_port_subscript then
+      subscript = '[' + @next_cell_port_subscript.to_s + ']'
+    else
+      subscript = ""
+    end
+
+    # セルを探す
+    # path =["::",@next_cell.get_name]
+    # cell = Namespace.find( path )
+    cell = Namespace.find( @next_cell.get_namespace_path )
+
+    # PPAllocator が必要か?
+    if @signature.need_PPAllocator? then
+      if @sub_channel_no == 0 then
+        file.print <<EOT
+#{indent_str}cell tPPAllocator PPAllocator_#{@shared_channel_cell}{
+#{indent_str}  heapSize = #{@PPAllocatorSize};
+#{indent_str}};
+EOT
+      end
+
+      ppallocator_join = "#{indent_str}  cPPAllocator = PPAllocator_#{@shared_channel_cell}.ePPAllocator;\n"
+    else
+      ppallocator_join = ""
+    end
+
+    # 共有される通信チャンネルの生成のプロトタイプ宣言
+    file.print <<EOT
+#{indent_str}cell #{@shared_channel_ct_name} #{@shared_channel_cell};
+EOT
+
+    # ここから各結合ごとのセルを生成
+
+    # アロケータの指定があるか？
+    if cell.get_allocator_list.length > 0 then
+
+      file.print "#{indent_str}[allocator("
+
+      delim = ""
+      cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc|
+
+        file.print delim
+        delim = ",\n#{indent_str}           "        # 最終行には出さない
+
+        if subsc then        # 配列添数
+          subsc_str = '[#{subsc}]'
+        else
+          subsc_str = ""
+        end
+
+        eport = "eThroughEntry" #RPCの受け口名に変更
+        file.print  "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc}"
+      end
+
+      file.puts ")]"
+    end
+
+    # セル本体の生成
+    file.print <<EOT
+#{indent_str}cell #{@rpc_channel_celltype_name} #{@cell_name} {
+#{indent_str}  #{@call_port_name} = #{@next_cell.get_name}.#{@next_cell_port_name}#{subscript};
+#{indent_str}  cTDR         = #{@shared_channel_cell}.eTDR;
+#{indent_str}  cEventflag   = #{@shared_channel_cell}.eEventflag;
+#{indent_str}  cLockChannel =  #{@shared_channel_cell}.eSemaphore[#{@sub_channel_no}];
+#{ppallocator_join}#{indent_str}};
+EOT
+    @region.gen_region_str_post file
+  end
+
+  #=== 後ろのコードを生成
+  #プラグインの後ろのコードを生成
+  #file:: File: 
+  def self.gen_post_code( file )
+    file.print "/* '#{self.name}' post code */\n"
+    @@shared_channel_list.each{ |chan_name,plugin_obj|
+      plugin_obj[0].gen_post_code( file, plugin_obj )
+    }
+  end
+
+  #=== 後ろのコードを生成
+  # plugin_obj[0] が代表して出力する（インスタンス変数にアクセスしたいため）
+  def gen_post_code( file, plugin_obj )
+
+    chan_name = @shared_channel_cell
+
+    nest = @region.gen_region_str_pre file
+    indent_str = "  " * nest
+
+    # 共有されている通信チャンネルの生成
+    # 各プラグインインスタンスでは @shared_channel_ct_name として記憶している
+    file.print "#{indent_str}cell tSharedRPCPlugin_#{@channelCelltype} #{chan_name} {\n"
+    plugin_obj.each{ |po|
+      file.print <<EOT
+#{indent_str}    cUnmarshalAndCallFunction[] = #{@cell_name}.eUnmarshalAndCallFunction;
+EOT
+    }
+    file.printf "#{indent_str}    priority = #{@task_priority};\n#{indent_str}};\n"
+    @region.gen_region_str_post file
+
+  end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/SignaturePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/SignaturePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/SignaturePlugin.rb	(revision 398)
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== signature プラグインの共通の親クラス
+class SignaturePlugin < Plugin
+#@signature:: Signature   プラグインの対象となるシグニチャ
+#@option:: String   '"', '"' で囲まれた文字列
+
+  #signature::     Signature        シグニチャ（インスタンス）
+  def initialize( signature, option )
+    super()
+    @signature = signature
+    # @plugin_arg_str = option.gsub( /\A"(.*)/, '\1' )    # 前後の "" を取り除く
+    # @plugin_arg_str.sub!( /(.*)"\z/, '\1' )
+    @plugin_arg_str = CDLString.remove_dquote option
+    @plugin_arg_list = {}
+  end
+
+  #=== 後ろのコードを生成
+  #プラグインの後ろの CDL コードを生成
+  #file:: File: 
+  def self.gen_post_code( file )
+    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+    # file.print "/* '#{self.class.name}' post code */\n"
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     通常であれば、ジェネレータは受け口関数のテンプレートを生成する
+  #     プラグインの場合、変更する必要のないセルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    raise "gen_ep_func_body must be overridden by sub class"
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/TECS2CBridgePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/TECS2CBridgePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/TECS2CBridgePlugin.rb	(revision 398)
@@ -0,0 +1,185 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== TECS => C 呼び出しプラグイン
+class TECS2CBridgePlugin < SignaturePlugin
+#@signature:: Signature   プラグインの対象となるシグニチャ
+#@option:: String   '"', '"' で囲まれた文字列
+
+  @@signature_list = { }
+
+  #signature::     Signature        シグニチャ（インスタンス）
+  def initialize( signature, option )
+    super
+
+    @signature = signature
+    @header_name = "#{$gen}/#{@signature.get_global_name}.#{$h_suffix}"
+    @celltype_name = :"t#{@signature.get_global_name}"
+
+    parse_plugin_arg
+  end
+
+  def gen_cdl_file file
+    if @@signature_list[ @signature.get_global_name ] then
+      @@signature_list[ @signature.get_global_name ] << self
+      cdl_warning( "T2CW001 signature '$1' duplicate. ignored current one", @signature.get_namespace_path )
+      return
+    end
+    @@signature_list[ @signature.get_global_name ] = [ self ]
+
+    print_msg "  TECS2CBridgePlugin: [celltype] TECS2C::#{@celltype_name}. Create cell then join to entry port 'eEntry' from the caller cell\n"
+    file.print <<EOT
+namespace nTECS2C{
+  [singleton]
+  celltype #{@celltype_name} {
+    [inline]
+    entry #{@signature.get_namespace_path} eEnt;
+  };
+};
+EOT
+  end
+
+  #=== 後ろのコードを生成
+  #プラグインの後ろのコードを生成
+  #file:: File: 
+  def self.gen_post_code( file )
+    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+    # file.print "/* '#{self.class.name}' post code */\n"
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     通常であれば、ジェネレータは受け口関数のテンプレートを生成する
+  #     プラグインの場合、変更する必要のないセルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    ret_type = func_type.get_type
+    b_ret_void = ret_type.is_void?
+
+    if ! b_ret_void then
+      file.print( "  #{ret_type.get_type_str}  retval;\n" )
+    end
+
+    if ! b_singleton then
+
+      file.print <<EOT
+  #{ct_name}_CB    *p_cellcb;
+  if( VALID_IDX( idx ) ){
+    p_cellcb = #{global_ct_name}_GET_CELLCB(idx);
+  }else{
+     /* エラー処理コードをここに記述 */
+  }
+
+EOT
+    end
+
+    # p "celltype_name, sig_name, func_name, func_global_name"
+    # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
+
+    if ! b_ret_void then
+      file.print( "  retval = " )
+    else
+      file.print( "  " )
+    end
+
+    file.print( "#{func_name}(" )
+
+    delim = ""
+    params.each{ |param|
+      file.printf( "#{delim} #{param.get_name}" )
+      delim = ","
+    }
+
+    file.print( " );\n" )
+
+    if ! b_ret_void then
+      file.print( "  return retval;\n" )
+    end
+
+  end
+
+
+  def gen_postamble( file, b_singleton, ct_name, global_name )
+
+    # generate header file here, NOT postamble
+    file2 = CFile.open( @header_name, "w" )
+    file2.print <<EOT
+/*
+ * This file was generated by TECS2CBridgePlugin and has prototype
+ * decalarations of functions in signature '#{@signature.get_namespace_path}'
+ */
+
+#include "global_tecsgen.#{$h_suffix}"
+
+EOT
+    @signature.get_function_head_array.each { |f|
+      decl = f.get_declarator
+      func_type = decl.get_type
+      params = func_type.get_paramlist.get_items
+      func_name = decl.get_name
+
+      ret_type = func_type.get_type
+
+      # p "celltype_name, sig_name, func_name, func_global_name"
+      # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
+
+      file2.print( "#{ret_type.get_type_str}  #{func_name}(" )
+
+      delim = ""
+      params.each{ |param|
+        file2.printf( "#{delim} #{param.get_name}" )
+        delim = ","
+      }
+      
+      file2.print( " )#{ret_type.get_type_str_post};\n" )
+    }
+
+      file2.close
+  end
+
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/TECSInfoPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/TECSInfoPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/TECSInfoPlugin.rb	(revision 398)
@@ -0,0 +1,283 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+# 
+#   Copyright (C) 2017-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== CelltypePlugin for tTECSInfo
+class TECSInfoPlugin < CelltypePlugin
+
+  @@cell_list = []
+  #@celltype::Celltype
+  #@plugin_arg_str::String
+  #@plugin_arg_list::{argNameString=>argOptionString}
+  #@cell_list::[Cell]
+
+  #celltype::     Celltype        セルタイプ（インスタンス）
+  def initialize( celltype, option )
+    super
+    if $unopt_entry == false then
+      cdl_info( "TIF0001 forcely set --unoptimize-entry by TECSInfoPlugin (by importing TECSInfo.cdl)" )
+      $unopt_entry = true
+    end
+  end
+
+  #=== 新しいセル
+  #cell::        Cell            セル
+  #
+  # celltype プラグインを指定されたセルタイプのセルが生成された
+  # セルタイププラグインに対する新しいセルの報告
+  def new_cell( cell )
+    @@cell_list << cell
+
+    # AppFile は、重ね書きようなので、やめる
+    # p "import: cell nTECSInfo::tTECSInfoSub #{cell.get_namespace_path.to_s} under #{cell.get_region.get_name}"
+    # cell.show_tree 0
+    # TECSInfoSub セルのプロトタイプ宣言
+    fn = "#{$gen}/tmp_#{cell.get_region.get_global_name}_TECSInfoSub.cdl"
+    File.open( fn, "w" ){ |f|
+      f.print "/* prototype declaration of TECSInfoSub */\n"
+      nest = cell.get_region.gen_region_str_pre f
+      indent = "    " * nest
+      f.print <<EOT
+#{indent}[in_through()]
+#{indent}region rTECSInfo {
+#{indent}    cell nTECSInfo::tTECSInfoSub TECSInfoSub;
+#{indent}}; /* rTECSInfo} */
+EOT
+      cell.get_region.gen_region_str_post f
+    }
+    Import.new fn
+
+    # セルに cTECSInfo の結合があるか？
+    if cell.get_join_list.get_item( :cTECSInfo ) == nil then
+      # cTECSInfo = rTECSInfo::TECSInfosub.eTECSInfo; の追加
+      nsp = NamespacePath.new( :rTECSInfo, false )
+      nsp.append! :TECSInfoSub
+      rhs = Expression.create_cell_join_expression nsp, nil, :eTECSInfo
+      join = Join.new :cTECSInfo, nil, rhs
+      cell.new_join join
+    end
+  end
+
+  #=== tCelltype_factory.h に挿入するコードを生成する
+  # file 以外の他のファイルにファクトリコードを生成してもよい
+  # セルタイププラグインが指定されたセルタイプのみ呼び出される
+  def gen_factory file
+    File.open( "#{$gen}/include_all_signature_header.h", "w" ){ |f|
+      f.print <<EOT
+#ifndef include_all_signature_header_h
+#define include_all_signature_header_h
+
+EOT
+      Namespace.get_root.travers_all_signature{ |sig|
+        f.print "#include \"#{sig.get_global_name}_tecsgen.h\"\n"
+      }
+      f.print <<EOT
+
+#endif /* include_all_signature_header_h */
+EOT
+    }
+
+    undefs2 = [ :INITIALIZE_CB, :FOREACH_CELL, :END_FOREACH_CELL ]
+    f = AppFile.open( "#{$gen}/nTECSInfo_tVarDeclInfo_factory.h" )
+    Namespace.get_root.print_struct_define f
+
+    undefs = [ :VALID_IDX, :GET_CELLCB, :CELLCB, :CELLIDX,
+               :tVarDeclInfo_IDX, :ATTR_name, :ATTR_sizeIsExpr,
+               :ATTR_declType, :ATTR_offset ]
+
+    f.print <<EOT
+
+/***** Offset of attr & var of celltype  *****/
+#define TOPPERS_CB_TYPE_ONLY
+
+/* In case a celltype has 'inline' entry,
+ * some macros are temporally defined
+ * even if TOPPERS_CB_TYPE_ONLY is defined.
+ * To avoid redefinition warning, undef these macros.
+ */
+#{ str=""; undefs.each{|u| str += "#undef #{u}\n" }; str }
+EOT
+    if $ram_initializer then
+      undefs2.each{|u|
+        f.print "#undef #{u}\n"
+      }
+    end
+    Namespace.get_root.print_celltype_define_offset f
+    f.print <<EOT
+
+/* redefine macros */
+#define tVarDeclInfo_IDX  nTECSInfo_tVarDeclInfo_IDX
+
+EOT
+    if $ram_initializer then
+      f.print <<EOT
+#define FOREACH_CELL(i,p_cb)   { (void)(i);
+#define END_FOREACH_CELL   }
+#define INITIALIZE_CB(p_that)   (void)(p_that);
+#define SET_CB_INIB_POINTER(i,p_that)
+EOT
+    end
+    f.close
+
+    undefs = [ :N_CP_cEntryInfo, :NCP_cEntryInfo, :N_CP_cCallInfo, :NCP_cCallInfo,
+               :N_CP_cAttrInfo, :NCP_cAttrInfo, :N_CP_cVarInfo, :NCP_cVarInfo,
+               :VALID_IDX, :GET_CELLCB, :CELLCB, :CELLIDX, :ATTR_name, :ATTR_b_singleton,
+               :ATTR_b_IDX_is_ID_act, :ATTR_sizeOfCB, :ATTR_sizeOfINIB, :ATTR_n_cellInLinUnit,
+               :ATTR_n_cellInSystem, :cEntryInfo_getName, :cEntryInfo_getNameLength,
+               :cEntryInfo_getSignatureInfo, :cEntryInfo_getArraySize, :cEntryInfo_isInline,
+               :cCallInfo_getName, :cCallInfo_getNameLength, :cCallInfo_getSignatureInfo,
+               :cCallInfo_getArraySize, :cCallInfo_getSpecifierInfo, :cCallInfo_getInternalInfo,
+               :cCallInfo_getLocationInfo, :cCallInfo_getOptimizeInfo, :cAttrInfo_getName,
+               :cAttrInfo_getOffset, :cAttrInfo_getTypeInfo, :cAttrInfo_getSizeIsExpr,
+               :cAttrInfo_getSizeIs, :cVarInfo_getName, :cVarInfo_getOffset, :cVarInfo_getTypeInfo,
+               :cVarInfo_getSizeIsExpr, :cVarInfo_getSizeIs, :cEntryInfo_refer_to_descriptor,
+               :cEntryInfo_ref_desc, :cCallInfo_refer_to_descriptor, :cCallInfo_ref_desc,
+               :cAttrInfo_refer_to_descriptor, :cAttrInfo_ref_desc, :cVarInfo_refer_to_descriptor,
+               :cVarInfo_ref_desc, :is_cEntryInfo_joined, :is_cCallInfo_joined,
+               :is_cAttrInfo_joined, :is_cVarInfo_joined, :eCelltypeInfo_getName,
+               :eCelltypeInfo_getNameLength, :eCelltypeInfo_getNAttr, :eCelltypeInfo_getAttrInfo,
+               :eCelltypeInfo_getNVar, :eCelltypeInfo_getVarInfo, :eCelltypeInfo_getNCall,
+               :eCelltypeInfo_getCallInfo, :eCelltypeInfo_getNEntry, :eCelltypeInfo_getEntryInfo,
+               :eCelltypeInfo_isSingleton, :eCelltypeInfo_isIDX_is_ID, :eCelltypeInfo_hasCB,
+               :eCelltypeInfo_hasINIB, :FOREACH_CELL, :END_FOREACH_CELL ]
+
+    f = AppFile.open( "#{$gen}/nTECSInfo_tCelltypeInfo_factory.h" )
+    undefs.each{ |u|
+      f.print "#undef #{u}\n"
+    }
+    f.print "#define TOPPERS_CB_TYPE_ONLY\n"
+    Namespace.get_root.print_celltype_define f
+    # FOREACH_CELL を出しなおす
+    ct = Namespace.find [ "::", :nTECSInfo, :tCelltypeInfo ]
+    ct.gen_ph_foreach_cell f
+    ct.gen_ph_cb_initialize_macro f
+    f.print "\n"
+    f.close
+   
+    undefs = [ :VALID_IDX, :GET_CELLCB, :CELLCB, :CELLIDX,
+               :tCallInfo_IDX, :ATTR_name, :ATTR_offset, :ATTR_b_inCB,
+               :ATTR_b_optional, :ATTR_b_omit, :ATTR_b_dynamic,
+               :ATTR_b_ref_desc, :ATTR_b_allocator_port,
+               :ATTR_b_require_port, :ATTR_b_VMT_useless,
+               :ATTR_b_skelton_useless, :ATTR_b_cell_unique,
+               :cSignatureInfo_getName, :cSignatureInfo_getNameLength,
+               :cSignatureInfo_getNFunction,
+               :cSignatureInfo_getFunctionInfo,
+               :cSignatureInfo_refer_to_descriptor,
+               :cSignatureInfo_ref_desc, :eCallInfo_getName,
+               :eCallInfo_getNameLength, :eCallInfo_getSignatureInfo,
+               :eCallInfo_getArraySize, :eCallInfo_isOptional,
+               :eCallInfo_isDynamic, :eCallInfo_isRefDesc,
+               :eCallInfo_isOmit ]
+
+    f = AppFile.open( "#{$gen}/nTECSInfo_tCallInfo_factory.h" )
+    f.print <<EOT
+
+/***** Offset of attr & var of celltype  *****/
+#define TOPPERS_CB_TYPE_ONLY
+
+/* In case a celltype has 'inline' entry,
+ * some macros are temporally defined
+ * even if TOPPERS_CB_TYPE_ONLY is defined.
+ * To avoid redefinition warning, undef these macros.
+ */
+#{ str=""; undefs.each{|u| str += "#undef #{u}\n" }; str }
+EOT
+    if $ram_initializer then
+      undefs2.each{|u|
+        f.print "#undef #{u}\n"
+      }
+    end
+
+    Namespace.get_root.print_call_define f
+    f.print <<EOT
+
+/* redefine macros */
+#define tCallInfo_IDX  nTECSInfo_tCallInfo_IDX
+
+EOT
+    if $ram_initializer then
+      f.print <<EOT
+#define FOREACH_CELL(i,p_cb)   { (void)(i);
+#define END_FOREACH_CELL   }
+#define INITIALIZE_CB(p_that)   (void)(p_that);
+#define SET_CB_INIB_POINTER(i,p_that)
+
+EOT
+    end
+    f.close
+
+    f = AppFile.open( "#{$gen}/nTECSInfo_tEntryInfo_factory.h" )
+    Namespace.get_root.print_entry_define f
+    f.close
+
+    undefs = [ :GET_CELLCB, :CELLCB, :CELLIDX, :ATTR_name, :INITIALIZE_CB, :FOREACH_CELL ]
+    f = AppFile.open( "#{$gen}/nTECSInfo_tCellInfo_factory.h" )
+    undefs.each{ |u|
+      f.print "#undef #{u}\n"
+    }
+    Region.get_root.print_cell_define f
+    # FOREACH_CELL を出しなおす
+    ct = Namespace.find [ "::", :nTECSInfo, :tCellInfo ]
+    ct.gen_ph_foreach_cell f
+    ct.gen_ph_cb_initialize_macro f
+    f.close
+
+    f = AppFile.open( "#{$gen}/nTECSInfo_tRawEntryDescriptorInfo_factory.h" )
+    Region.get_root.print_entry_descriptor_define f
+    f.close
+  end
+
+  #=== 後ろの CDL コードを生成
+  #プラグインの後ろの CDL コードを生成
+  #file:: File:
+  def self.gen_post_code( file )
+    if Generator.get_n_error > 0 then
+      Generator.info( "I9999 TECSInfoPlugin does not generate TECSInfo code because of early error" )
+      return
+    end
+    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+    file.print <<EOT
+/*------------ #{self.name} post code ------------*/
+EOT
+    @@cell_list.each{|cell|
+      root = cell.get_region # .get_link_root
+      TECSInfo.print_info file, root
+    }
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ThroughPlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ThroughPlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/ThroughPlugin.rb	(revision 398)
@@ -0,0 +1,339 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+# mikan through plugin: namespace が考慮されていない
+
+#==  スループラグインの共通の親クラス　かつ （何もせず）スルーするセルを挿入するスループラグイン
+#    スループラグインは ThroughPlugin の子クラスとして定義する
+class ThroughPlugin < Plugin
+#@cell_name::      Symbol             生成するセル名（複数セルを生成する場合、受け口側のセル）
+#@plugin_arg_str:: string             through で指定された引数
+#@next_cell:: Cell                    呼び口を結合するセル
+#@next_cell_port_name:: Symbol       呼び口を結合する受口の名前
+#@next_cell_port_subscript::Nil|Integer   呼び口を結合する受口の配列添数．受け口配列でない場合 nil
+#@signature::      Signature          シグニチャ
+#@celltype::       Celltype           呼び先のセルのセルタイプ. through が連接する場合、最終的な呼び先のセルのセルタイプ
+#@entry_port_name::Symbol             生成するセルの受け口名  "eThroughEntry"
+#@call_port_name:: Symbol             生成するセルの呼び口名  "cCall"
+#@ct_name::        Symbol             生成するセルのセルタイプ名   "t#{self.class.name}_#{@signature.get_global_name}"
+#@plugin_arg_list:: Hash              プラグイン引数をパースした結果のハッシュ変数
+#@caller_cell::    Cell               呼び元のセル．through プラグインが連接する場合では、最も呼び元のセル．($source$)
+#                                     through プラグインが合流するケースでは、1つ目の呼び元セルのみ引数として与えられる
+#                                     従って TracePlugin の呼び元の判別に利用する場合は、異なる呼び元から呼ばれる可能性があることに注意しなくてはならない
+#@callee_cell:: Cell                  呼び先のセル($destination$)
+#@plugin_arg_check_proc_tab:: [string => Proc]  プラグイン引数名⇒チェック関数
+# 以下の変数は、initialize ではなく、後から設定される
+#@start_@region::  Region             始まりのリージョン： caller_cell のリージョンとは異なる可能性がある ($start_region$)
+#@end_region::  Region                終わりのリージョン： next_cell のリージョンとは異なる可能性がある ($end_region$)
+#@region:: Region                     @start_region と @end_region のいずれかで、cell を置くのが好ましいリージョン ($preferred_region$)
+#@through_type:: Symbol              :THROUGH, :TO_THROUGH, :IN_THROUGH, :OUT_THROUGH のいずれか
+
+  # この Plugin が生成したセルタイプのリスト
+  @@generated_celltype = {}
+
+  #=== ThroughPlugin の初期化
+  #     through が指定された時点で生成が行われる
+  #         初期化では、指定された引数を記録するに留める
+  #cell_name::      Symbol             生成すべきセル名（受口側）
+  #plugin_arg::     string             through で指定された引数
+  #next_cell::      Cell               呼び口を接続するセル
+  #next_cell_port_name:: Symbol        呼び口を接続する受口の名前
+  #next_cell_port_subscript:: Nil|Integer  呼び口を接続する受口配列添数
+  #signature::      Signature          シグニチャ
+  #celltype::       Celltype           セルタイプ (呼び先のセルのセルタイプ)
+  #caller_cell::    Cell               呼び元のセル．@caller_cell の項を参照
+  def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
+    super()
+    @cell_name = cell_name                      # 生成すべきセル名（受け口側のセル名）
+                                                # この呼び先に別セルを生成する場合、この名前を接頭辞とすべき
+    @next_cell = next_cell                      # 呼び先のセル
+    @next_cell_port_name = next_cell_port_name
+    @next_cell_port_subscript = next_cell_port_subscript
+    @signature = signature
+    @entry_port_name = :"eThroughEntry"
+    @call_port_name = :"cCall"
+    @ct_name = :"t#{self.class.name}_#{@signature.get_global_name}"
+    @celltype = celltype
+    @plugin_arg_str = plugin_arg
+    @plugin_arg_list = {}                       # プラグイン引数をパースした結果のハッシュ変数
+    @caller_cell     = caller_cell
+    Join.set_through_info self                  # 引数で渡らない(後から追加された)ものは set_through_info で設定される
+    print( "#{self.class.name}.new( '#{cell_name}', '#{plugin_arg}', '#{next_cell.get_name}', '#{next_cell_port_name}', #{celltype.get_name} )\n" )
+  end
+
+  #=== 情報を設定する
+  # 共有チャンネルの場合 caller_cell, next_cell のいずれの region でもないケースがある
+  # 後から追加したので initialize の引数ではなく、別メソッドで設定
+  # このメソッドは、オーバーライドしないでください
+  # Join と ThrougPlugin の間の連絡用で、今後とも引数が追加される可能性があるため
+  # このメソッドは V1.C.0.34 で位置が移動され、ThroughPlugin#initialize で呼び出される
+  def set_through_info( start_region, end_region, through_type, join, callee_cell, count )
+    @start_region = start_region
+    @end_region = end_region
+    @through_type = through_type
+    @join = join
+    @callee_cell = callee_cell
+    @count = count
+
+    # preferred_region の設定
+    case through_type
+    when :IN_THROUGH, :THROUGH
+      @region = end_region
+    when :OUT_THROUGH, :TO_THROUGH
+      @region = start_region
+    else
+      raise "Unknown through_type #{through_type}"
+    end
+  end
+
+  #===  セルの名前を得る
+  def get_cell_name
+    @cell_name
+  end
+
+  #=== NamespacePath を得る
+  # 生成するセルの namespace path を生成する
+  def get_cell_namespace_path
+#    nsp = @region.get_namespace.get_namespace_path
+    nsp = @region.get_namespace_path
+    return nsp.append( @cell_name )
+  end
+
+  #===  生成されたセルの受け口の名前を得る
+  def get_through_entry_port_name
+    @entry_port_name
+  end
+
+  #===  生成されたセルの受け口配列添数を得る
+  def get_through_entry_port_subscript
+    @entry_port_subscript
+  end
+
+  #===  宣言コードの生成
+  #      typedef, signature, celltype など（cell 以外）のコードを生成
+  #          重複して生成してはならない（すでに生成されている場合は出力しないこと）
+  #file::        FILE       生成するファイル
+  def gen_plugin_decl_code( file )
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if @@generated_celltype[ @ct_name ] == nil then
+      @@generated_celltype[ @ct_name ] = [ self ]
+    else
+      @@generated_celltype[ @ct_name ] << self
+      return
+    end
+
+    file2 = CFile.open( "#{$gen}/#{@ct_name}.cdl", "w" )
+
+    send_receive = []
+    if @signature != nil then
+      @signature.each_param{ |fd,param|
+        dir =param.get_direction
+        case dir
+        when :SEND, :RECEIVE
+          send_receive << [ dir, fd, param ]
+        end
+      }
+    end
+
+    file2.print <<EOT
+celltype #{@ct_name} {
+EOT
+
+    if send_receive.length > 0 then
+      file2.print "  [ allocator(\n"
+      delim = ""
+      send_receive.each { |a|
+        file2.print "#{delim}\t#{a[1].get_name}.#{a[2].get_name}<=#{@call_port_name}.#{a[1].get_name}.#{a[2].get_name}"
+        delim = ",\n"
+      }
+      file2.print "\n  )]\n"
+    end
+
+    file2.print <<EOT
+  entry #{@signature.get_namespace_path} #{@entry_port_name};
+  call  #{@signature.get_namespace_path} #{@call_port_name};
+};
+EOT
+    file2.close
+
+    file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
+  end
+
+  #=== CDL ファイルの生成
+  #file::     FILE    生成するファイル
+  def gen_cdl_file( file )
+    gen_plugin_decl_code( file )
+    gen_through_cell_code( file )
+  end
+
+  #===  セルコードの生成
+  #     through 指定により生じるセルコード(CDL)を生成する
+  #file::        FILE       生成するファイル
+  def gen_through_cell_code( file )
+
+    nest = @region.gen_region_str_pre file
+    nest_str = "  " * nest
+
+    file.print <<EOT
+#{nest_str}cell #{@ct_name} #{@cell_name} {
+#{nest_str}  #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name};
+#{nest_str}};
+EOT
+    @region.gen_region_str_post file
+
+  end
+
+  #=== 後ろのコードを生成
+  #プラグインの後ろのコード (CDL) を生成
+  #file:: File: 
+  def self.gen_post_code( file )
+    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+    # file.print "/* '#{self.class.name}' post code */\n"
+  end
+
+  #===  受け口関数の本体(C言語)を生成する
+  #     通常であれば、ジェネレータは受け口関数のテンプレートを生成する
+  #     プラグインの場合、変更する必要のないセルタイプコードを生成する
+  #file::           FILE        出力先ファイル
+  #b_singleton::    bool        true if singleton
+  #ct_name::        Symbol
+  #global_ct_name:: string
+  #sig_name::       string
+  #ep_name::        string
+  #func_name::      string
+  #func_global_name:: string
+  #func_type::      class derived from Type
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    ret_type = func_type.get_type
+    b_ret_void = ret_type.is_void?
+
+    if ! b_ret_void then
+      file.print( "  #{ret_type.get_type_str}  retval;\n" )
+    end
+
+    if ! b_singleton then
+
+      file.print <<EOT
+  #{ct_name}_CB    *p_cellcb;
+  if( VALID_IDX( idx ) ){
+    p_cellcb = #{global_ct_name}_GET_CELLCB(idx);
+  }else{
+     /* エラー処理コードをここに記述 */
+  }
+
+EOT
+    end
+
+    # p "celltype_name, sig_name, func_name, func_global_name"
+    # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
+
+    delim = ""
+    if ! b_ret_void then
+      file.print( "  retval = " )
+    end
+
+    file.print( "#{@call_port_name}_#{func_name}(" )
+
+#    if ( ! b_singleton ) then
+#      file.print( " tecs_this" )
+#      delim = ","
+#    end
+
+    params.each{ |param|
+      file.printf( "#{delim} #{param.get_name}" )
+      delim = ","
+    }
+
+    file.print( " );\n" )
+
+    if ! b_ret_void then
+      file.print( "  return retval;\n" )
+    end
+  end
+
+  #=== Through プラグインの引数の名前を置換する
+  def check_plugin_arg( ident, rhs )
+    rhs = subst_name rhs
+    super( ident, rhs )
+  end
+
+  #=== ThroughPlugin#名前の置換
+  # プラグインオプション引数内の文字列を置換する
+  #   $source$       … 呼び元のセル名
+  #   $destination$  … 呼び先のセル名
+  #   $SOURCE$       … 呼び元のセル名 (リージョン名を '_' で連結した global_name)
+  #   $DESTINATION$  … 呼び先のセル名 (リージョン名を '_' で連結した global_name)
+  #   $next$         … 次のセル名
+  #                     複数の through がつながっている場合、すぐ後ろに来るもの
+  #   $NEXT$         … 次のセル名 (リージョン名を '_' で連結した global_name)
+  #                     複数の through がつながっている場合、すぐ後ろに来るもの
+  #   $start_region$ … $source$ のセルの存在する region (global_name)
+  #   $end_region$   … $destination$ のセルの存在する region (global_name)
+  #   $preferred_region$  … 適切な region (global_name), start_region または end_region
+  #   $count$        … region 間の through の適用数
+  #   $$             … $ に置換
+  def subst_name( str )
+    # セル名の置換
+    str = str.gsub( /(^|[^\$])\$source\$/, "\\1#{@caller_cell.get_name}" )
+    str = str.gsub( /(^|[^\$])\$destination\$/, "\\1#{@callee_cell.get_name}" )
+    str = str.gsub( /(^|[^\$])\$SOURCE\$/, "\\1#{@caller_cell.get_global_name}" )
+    str = str.gsub( /(^|[^\$])\$DESTINATION\$/, "\\1#{@callee_cell.get_global_name}" )
+    str = str.gsub( /(^|[^\$])\$next\$/, "\\1#{@next_cell.get_name}" )
+    str = str.gsub( /(^|[^\$])\$NEXT\$/, "\\1#{@next_cell.get_global_name}" )
+    # region 名の置換
+    str = str.gsub( /(^|[^\$])\$start_region\$/, "\\1#{@start_region.get_global_name}" )
+    str = str.gsub( /(^|[^\$])\$end_region\$/, "\\1#{@end_region.get_global_name}" )
+    str = str.gsub( /(^|[^\$])\$preferred_region\$/, "\\1#{@region.get_global_name}" )
+    str = str.gsub( /(^|[^\$])\$count\$/, "\\1#{@count}" )
+
+    str = str.gsub( /\$\$/, "\$" )                       # $$ を $ に置換
+
+    return str
+  end
+
+  def show_tree( indent )
+    indent.times { print "  " }
+    puts "Plugin: celltype: #{@ct_name} cell: #{@cell_name}"
+    (indent+1).times { print "  " }
+    puts "next: signature: #{@signature.get_namespace_path} call = #{@next_cell.get_name}.#{@next_cell_port_name}"
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/TracePlugin.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/TracePlugin.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/TracePlugin.rb	(revision 398)
@@ -0,0 +1,494 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+class TracePlugin < ThroughPlugin
+#@cellEntry_list::[ "Cell.eEntry", "Cell2.eEntry2", ... ]
+#@b_generate::bool  : true : TracePlugin を生成する必要がある
+
+  #=== TracePlugin の initialize
+  #  説明は ThroughPlugin (plugin.rb) を参照
+  def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell )
+
+    @maxArrayDisplay = 16
+    @cellEntry_list  = []
+    @probeName       = ""
+    @b_generate      = false
+    @b_displayTime   = false
+    @kernelCelltype  = :"tKernel"
+    @syslogCelltype  = :"tSysLog"
+
+    super
+    @plugin_arg_check_proc_tab = TracePluginArgProc
+    parse_plugin_arg
+
+    if @cellEntry_list.length > 0 then
+      @cellEntry_list.each{ |ce|
+        if "#{next_cell.get_name}.#{next_cell_port_name}".to_sym == ce.to_sym
+          @b_generate = true
+        end
+      }
+    else
+      @b_generate = true
+    end
+
+    if @b_generate == false then
+      # 元々呼び出すセルに結合するものとする
+      @entry_port_name = next_cell_port_name
+      @cell_name = next_cell.get_name
+    end
+  end
+
+  #===  宣言コードの生成
+  #      typedef, signature, celltype など（cell 以外）のコードを生成
+  #          重複して生成してはならない（すでに生成されている場合は出力しないこと）
+  #file::        FILE       生成するファイル
+  def gen_plugin_decl_code( file )
+
+    # このセルタイプ（同じシグニチャ）は既に生成されているか？
+    if @@generated_celltype[ @ct_name ] == nil then
+      @@generated_celltype[ @ct_name ] = [ self ]
+    else
+      @@generated_celltype[ @ct_name ] << self
+      return
+    end
+
+    file2 = CFile.open( "#{$gen}/#{@ct_name}.cdl", "w" )
+
+    send_receive = []
+    if @signature != nil then
+      @signature.each_param{ |fd,param|
+        dir =param.get_direction
+        case dir
+        when :SEND, :RECEIVE
+          send_receive << [ dir, fd, param ]
+        end
+      }
+    end
+
+    file2.print <<EOT
+celltype #{@ct_name} {
+EOT
+
+    if send_receive.length > 0 then
+      file2.print "  [ allocator(\n"
+      delim = ""
+      send_receive.each { |a|
+        file2.print "#{delim}\t#{a[1].get_name}.#{a[2].get_name}<=#{@call_port_name}.#{a[1].get_name}.#{a[2].get_name}"
+        delim = ",\n"
+      }
+      file2.print "\n  )]\n"
+    end
+
+    file2.print <<EOT
+  entry #{@signature.get_namespace_path} #{@entry_port_name};
+  call  #{@signature.get_namespace_path} #{@call_port_name};
+  attr{
+    char_t   *probeName_str      = "";
+    char_t   *from_str           = "";
+  };
+  require  #{@syslogCelltype}.eSysLog;
+  require  #{@kernelCelltype}.eKernel;
+};
+EOT
+#    char_t   *cell_port_name_str = "";
+
+    file2.close
+
+    file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
+  end
+
+  def gen_through_cell_code( file )
+
+    gen_plugin_decl_code( file )
+
+    if @b_generate != false then
+      nest = @region.gen_region_str_pre file
+      indent_str =  "  " * nest
+      if @next_cell_port_subscript then
+        subscript = '[' + @next_cell_port_subscript.to_s + ']'
+      else
+        subscript = ""
+      end
+
+      if @probeName then
+        probeName_str = "#{indent_str}  probeName_str = \"" + @probeName + ": \";\n"
+      else
+        probeName_str = ""
+      end
+      if @caller_cell then
+        caller_cell_str = "#{indent_str}  from_str = \"#{@caller_cell.get_name}\";\n"
+      else
+        caller_cell_str = ""
+      end
+
+      file.print <<EOT
+#{indent_str}cell #{@ct_name} #{@cell_name} {
+#{indent_str}  #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
+#{probeName_str}#{caller_cell_str}#{indent_str}};
+EOT
+#  cell_port_name_str = \"#{@next_cell.get_name}.#{@next_cell_port_name}\";
+      @region.gen_region_str_post file
+    end
+
+  end
+
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    if ! func_type.get_type.is_void? then
+      file.print( "\t#{func_type.get_type_str}\tretval;\n" )
+    end
+
+    file.print( "\tSYSUTM\tutime;\n" )
+
+    if ! b_singleton then
+
+      file.print <<EOT
+\t#{ct_name}_CB *p_cellcb;
+\tif( VALID_IDX( idx ) ){
+\t\tp_cellcb = #{global_ct_name}_GET_CELLCB(idx);
+\t}else{
+\t\t/* put code here for error */
+\t}
+
+EOT
+    end
+
+#    p "celltype_name, sig_name, func_name, func_global_name"
+#    p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
+
+
+    file.print <<EOT
+\tgetMicroTime( &utime );
+\tsyslog( LOG_INFO, \"Enter: %sTime=%d: #{@next_cell.get_name}.#{@next_cell_port_name}.#{func_name} calledFrom: %s\", ATTR_probeName_str, utime, ATTR_from_str );
+EOT
+
+    print_params( params, file, 0, :IN )
+
+    delim = ""
+    if ! func_type.get_type.is_void? then
+      file.print( "\tretval = " )
+    else
+      file.print( "\t" )
+    end
+
+    file.print( "#{@call_port_name}_#{func_name}(" )
+
+    params.each{ |param|
+      file.printf( "#{delim} #{param.get_name}" )
+      delim = ","
+    }
+    file.print( " );\n" )
+    if @next_cell_port_subscript then
+      subscript = '[' + @next_cell_port_subscript.to_s + ']'
+    else
+      subscript = ""
+    end
+
+    file.print <<EOT
+\tgetMicroTime( &utime );
+\tsyslog( LOG_INFO, \"Leave: %sTime=%d: #{@next_cell.get_name}.#{@next_cell_port_name}#{subscript}.#{func_name}\", ATTR_probeName_str, utime );
+EOT
+
+    print_params( params, file, 0, :OUT )
+
+    if( ! func_type.get_type.is_void? ) then
+      print_param( "retval", func_type.get_type, file, 0, :RETURN, func_type.get_type.get_type_str, nil, nil)
+      file.print( "\treturn retval;\n" )
+    end
+
+  end
+
+  def print_params( params, file, nest, direction )
+    params.each{ |param|
+      dir = param.get_direction
+      if( direction == :IN )then
+        case dir
+        when :IN, :INOUT, :SEND
+          print_param( param.get_name, param.get_type, file, nest, dir, param.get_type.get_type_str, nil, nil )
+        end
+      else
+        case dir
+        when :OUT, :INOUT
+          print_param( param.get_name, param.get_type, file, nest, dir, param.get_type.get_type_str, nil, nil )
+        when  :RECEIVE
+          outer = "*"
+          outer2 = nil
+          print_param( param.get_name, param.get_type.get_referto, file, nest, dir,
+                       param.get_type.get_referto.get_type_str, outer, outer2 )
+        end
+      end
+    }
+  end
+
+  def print_param( name, type, file, nest, direction, type_str, outer, outer2, name_list = nil )
+    indent = "    " * ( nest + 1 )
+
+    case type
+    when DefinedType
+      print_param( name, type.get_type, file, nest, direction, type_str, outer, outer2, name_list )
+    when VoidType
+    when BoolType
+      file.print( "#{indent}syslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %d;\", #{outer}#{name}#{outer2} );\n" )
+    when IntType
+      file.print <<EOT
+#{indent}if( sizeof(#{outer}#{name}#{outer2}) > sizeof(int_t) )
+#{indent}\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %ld;\", (long)#{outer}#{name}#{outer2} );
+#{indent}else
+#{indent}\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %d;\", #{outer}#{name}#{outer2} );
+EOT
+#      file.print( "#{indent}syslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %ld;\", (long)#{outer}#{name}#{outer2} );\n" )
+    when FloatType
+      file.print( "#{indent}syslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %g;\", (double)#{outer}#{name}#{outer2} );\n" )
+    when EnumType  # mikan EnumType
+
+    when StructType
+      members_decl =type.get_members_decl
+      if outer || outer2
+        outer = "(#{outer}#{name}#{outer2})."
+      else
+        outer = "#{name}."
+      end
+      members_decl.get_items.each { |m|
+        print_param( m.get_name, m.get_type, file, nest, direction, m.get_type.get_type_str, outer, nil, members_decl )
+      }
+    when FuncType  # mikan FuncType
+    when ArrayType # mikan ArrayType
+    when PtrType
+
+      se = type.get_size
+      ce = type.get_count
+      max_loop = @maxArrayDisplay
+      loop_count = nil
+
+      if se then
+        loop_count = "(((#{se.to_str( name_list, outer, outer2 )})>#{max_loop}) ? #{max_loop} : (#{se.to_str( name_list, outer, outer2 )}))"
+        file.print( "#{indent}syslog( LOG_INFO, \"#{indent}size_is(#{se.to_str( name_list, outer, outer2 )})=%d\", #{se.to_str( name_list, outer, outer2 )} );\n" )
+        size = "#{se.to_str( name_list, outer, outer2 )}"
+      elsif ce then
+        loop_count = "(((#{ce.to_str( name_list, outer, outer2 )})>#{max_loop}) ? #{max_loop} : (#{ce.to_str( name_list, outer, outer2 )})) "
+        file.print( "#{indent}syslog( LOG_INFO, \"#{indent}count_is(#{ce.to_str( name_list, outer, outer2 )})=%d\", #{ce.to_str( name_list, outer, outer2 )} );\n" )
+        size = "#{ce.to_str( name_list, outer, outer2 )}"
+      end
+
+      # mikan PtrType: string
+
+      referto = type.get_referto
+      type0 = type
+      type = referto
+      type_str = type.get_type_str
+      if type.kind_of?( DefinedType ) then
+        type = type.get_original_type
+      end
+
+      if type0.is_nullable? then
+        nest += 1
+        indent0 = indent
+        outer0 = outer
+        outer20 = outer2
+        indent += "    "
+        file.print"#{indent0}if( #{outer}#{name}#{outer2} ){\n"
+      end
+
+      if loop_count == nil then
+        case type
+        when StructType
+          members = type.get_members_decl
+          if outer || outer2
+            outer = "(#{outer}#{name}#{outer2})->"
+          else
+            outer = "#{name}->"
+          end
+          outer2 = nil
+          members.get_items.each { |m|
+            print_param( m.get_name, m.get_type, file, nest, direction, m.get_type.get_type_str, outer, outer2, members )
+          }
+        when FuncType  # mikan FuncType
+        when ArrayType # mikan ArrayType
+        when BoolType, IntType, FloatType, EnumType, PtrType
+          outer = "*#{outer}"
+          outer2 = "#{outer2}"
+          print_param( name, type, file, nest, direction, type_str, outer, outer2 )
+        end
+      else # loop_count != nil
+        if type.kind_of?( PtrType ) || type.kind_of?( StructType ) then
+          num_per_loop = 1
+        else
+          num_per_loop = 4
+        end
+
+          file.print <<EOT
+#{indent}{
+#{indent}\tint i__#{nest}, loop_count__ = #{loop_count};
+#{indent}\tfor( i__#{nest} = 0; i__#{nest} < loop_count__; i__#{nest}+=#{num_per_loop} ){
+EOT
+
+        case type
+        when StructType
+          members = type.get_members_decl
+          if outer || outer2
+            outer = "(#{outer}#{name}#{outer2})[i__#{nest}]."
+          else
+            outer = "#{name}[i__#{nest}]."
+          end
+          members.get_items.each { |m|
+            print_param( m.get_name, m.get_type, file, nest + 1, direction, m.get_type.get_type_str, outer, nil, members )
+          }
+        when FuncType  # mikan FuncType
+        when ArrayType # mikan ArrayType
+
+        when BoolType, FloatType
+          if outer || outer2
+            outer = "(#{outer}"
+            outer2 = "#{outer2})"
+          end
+
+          file.print <<EOT
+#{indent}\t\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{name}[%d]: %d %d %d %d\",
+#{indent}\t\t\t\ti__#{nest}, #{outer}#{name}#{outer2}[i__#{nest}], #{outer}#{name}#{outer2}[i__#{nest}+1], #{outer}#{name}#{outer2}[i__#{nest}+2], #{outer}#{name}#{outer2}[i__#{nest}+3] );
+EOT
+        when IntType
+          if outer || outer2
+            outer = "(#{outer}"
+            outer2 = "#{outer2})"
+          end
+
+          file.print <<EOT
+#{indent}\t\tif( sizeof(#{outer}#{name}#{outer2}) > sizeof(int_t) )
+#{indent}\t\t\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{name}[%d]: %02x %02x %02x %02x\",
+#{indent}\t\t\t\t\ti__#{nest}, #{outer}#{name}#{outer2}[i__#{nest}], #{outer}#{name}#{outer2}[i__#{nest}+1], #{outer}#{name}#{outer2}[i__#{nest}+2], #{outer}#{name}#{outer2}[i__#{nest}+3] );
+#{indent}\t\telse
+#{indent}\t\t\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{name}[%d]: %02lx %02lx %02lx %02lx\",
+#{indent}\t\t\t\t\ti__#{nest}, #{outer}#{name}#{outer2}[i__#{nest}], #{outer}#{name}#{outer2}[i__#{nest}+1], #{outer}#{name}#{outer2}[i__#{nest}+2], #{outer}#{name}#{outer2}[i__#{nest}+3] );
+EOT
+
+        when PtrType
+          # type = type.get_referto
+          if outer || outer2
+            outer = "(#{outer}"
+            outer2 = "#{outer2})[i__#{nest}]"
+          else
+            outer = ""
+            outer2 = "[i__#{nest}]"
+          end
+          print_param( name, type, file, nest + 1, direction, type_str, outer, outer2 )
+        end
+
+        file.print <<EOT
+#{indent}\t} /* for ( i__#{nest} ) */
+#{indent}\tif( i__#{nest} < #{size} )
+#{indent}\t\tsyslog( LOG_INFO, \"#{indent}(%d elements are omitted)\", #{size} - i__#{nest} );
+#{indent}\telse if( i__#{nest} > #{size} )
+#{indent}\t\tsyslog( LOG_INFO, \"#{indent}(last %d elements are void)\", i__#{nest} - #{size} );
+#{indent}}
+EOT
+      end # loop_count == nil
+
+      if type0.is_nullable? then
+        file.print <<EOT
+#{indent0}} else {
+#{indent0}    syslog( LOG_INFO, \"#{indent0}[#{direction}]#{outer0}#{name}#{outer20} = NULL\" );
+#{indent0}}
+EOT
+      end
+    end
+  end
+
+  # プラグイン引数名と Proc
+  TracePluginArgProc = {
+    "maxArrayDisplay"    => Proc.new { |obj,rhs| obj.set_maxArrayDisplay rhs },
+    "cellEntry"          => Proc.new { |obj,rhs| obj.set_cellEntry rhs },
+    "probeName"          => Proc.new { |obj,rhs| obj.set_probeName rhs },
+    "displayTime"        => Proc.new { |obj,rhs| obj.set_displayTime rhs },
+    "kernelCelltype"     => Proc.new { |obj,rhs| obj.set_kernelCelltype rhs },
+    "syslogCelltype"     => Proc.new { |obj,rhs| obj.set_syslogCelltype rhs },
+  }
+
+  def set_maxArrayDisplay rhs
+    @maxArrayDisplay = rhs
+  end
+
+  def set_cellEntry rhs
+    ces = rhs.to_s.split /\s*,\s*/
+    ces.each{ |ce|
+      if ce =~ /^[A-Za-z_]\w*\.[A-Za-z_]\w*$/ then
+        # OK
+      else
+        cdl_error( "#{ce}: TracePlugin arg not in \"symbol.symbol\" form" )
+      end
+    }
+    @cellEntry_list.concat ces
+  end
+
+  def set_probeName rhs
+    @probeName = rhs.to_s
+  end
+
+  def set_displayTime rhs
+    if rhs.to_s == "true"
+      @b_diplayTime = true
+    elsif rhs.to_s == "false"
+      @b_diplayTime = false
+    else
+      cdl_error( "displayTime : #{rhs} unsuitable: specify true or false" )
+    end
+  end
+
+  #=== プラグイン引数 tKernel のチェック
+  def set_kernelCelltype( rhs )
+    @kernelCelltype = rhs.to_sym
+    nsp = NamespacePath.analyze( @kernelCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "TracePlugin: kernelCelltype '#{rhs}' not celltype or not defined" )
+    end
+  end
+
+  #=== プラグイン引数 tSyslog のチェック
+  def set_syslogCelltype( rhs )
+    @syslogCelltype = rhs.to_sym
+    nsp = NamespacePath.analyze( @syslogCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "TracePlugin: syslogCelltype '#{rhs}' not celltype or not defined" )
+    end
+  end
+
+end
+
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenHRP2Marshaler.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenHRP2Marshaler.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenHRP2Marshaler.rb	(revision 398)
@@ -0,0 +1,770 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#プラグインオプション用変数
+#@task_priority:: Integer
+#@channelCelltype:: String
+#@channelCellName:: String
+#@PPAllocatorSize:: Integer
+module GenTransparentMarshaler
+
+  # プラグイン引数名と Proc
+  RPCPluginArgProc = {
+    "taskPriority"    => Proc.new { |obj,rhs| obj.set_taskPriority rhs },
+    "channelCelltype" => Proc.new { |obj,rhs| obj.set_channelCelltype rhs },
+    "TDRCelltype"     => Proc.new { |obj,rhs| obj.set_TDRCelltype rhs },
+    "channelCell"     => Proc.new { |obj,rhs| obj.set_channelCellName rhs },
+    "PPAllocatorSize" => Proc.new { |obj,rhs| obj.set_PPAllocatorSize rhs },
+  }
+
+  #=== プラグイン引数 taskPriority のチェック
+  def set_taskPriority( rhs )
+    @task_priority = rhs
+  end
+
+  #=== プラグイン引数 channelCelltype のチェック
+  def set_channelCelltype( rhs )
+    @channelCelltype = rhs.to_sym
+    # path = [ "::", @channelCelltype ]
+    # obj = Namespace.find( path )
+    nsp = NamespacePath.analyze( @channelCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: channeclCelltype '#{rhs}' not celltype or not found" )
+    end
+  end
+
+  #=== プラグイン引数 TDRCelltype のチェック
+  def set_TDRCelltype( rhs )
+    @TDRCelltype = rhs.to_sym
+    # path = [ "::", @TDRCelltype ]
+    # obj = Namespace.find( path )
+    nsp = NamespacePath.analyze( @TDRCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: TDRCelltype '#{rhs}' not celltype or not found" )
+    end
+  end
+
+  #=== プラグイン引数 channelCellName のチェック
+  def set_channelCellName( rhs )
+    @channelCellName = rhs
+    if @channelCellName =~ /\A[a-zA-Z_]\w*/ then
+      # OK
+    else
+      cdl_error( "RPCPlugin: channeclCellName '#{rhs}' unsuitable for identifier" )
+    end
+  end
+
+  #=== プラグイン引数 PPAllocatorSize のチェック
+  def set_PPAllocatorSize( rhs )
+    @PPAllocatorSize = rhs
+  end
+
+  #=== marshaler のセルタイプ名を設定する
+  def initialize_transparent_marshaler cell_name
+    @task_priority = 8
+    @channelCelltype = "tDataqueueOWChannel"
+    @TDRCelltype     = "tTDR"
+    @channelCellName = "#{cell_name}_Channel"
+    @PPAllocatorSize = nil
+
+    @marshaler_celltype_name = "tMarshaler_#{@signature.get_name}"
+    @unmarshaler_celltype_name = "tUnmarshaler_#{@signature.get_name}"
+    @marshaler_celltype_file_name = "#{$gen}/#{@marshaler_celltype_name}.cdl"
+  end
+
+  def gen_marshaler_celltype 
+
+    if @PPAllocatorSize then
+      alloc_call_port = "  call sPPAllocator cPPAllocator;\n"
+    else
+      alloc_call_port = ""
+    end
+
+    f = CFile.open( @marshaler_celltype_file_name, "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    # modified by ishikawa
+    f.print <<EOT
+
+celltype #{@marshaler_celltype_name} {
+  entry #{@signature.get_name} eClientEntry;
+  call sEventflag  cEventflag;
+  call sSemaphore  cSemaphore;
+  call sMessageBuffer cMessageBuffer;
+  //[optional]
+  //  call sSemaphore cLockChannel;  // this port is eliminated by optimize
+};
+celltype #{@unmarshaler_celltype_name} {
+  call #{@signature.get_name} cServerCall;
+  call sEventflag  cEventflag;
+  call sSemaphore  cSemaphore;
+  call sMessageBuffer cMessageBuffer;
+  entry sTaskBody  eUnmarshalAndCallFunction;
+#{alloc_call_port}
+  FACTORY{
+    write("$ct$_factory.h", "#include <t_syslog.h>");
+  };
+};
+EOT
+    f.close
+  end
+
+  #===  受け口関数の本体コードを生成（頭部と末尾は別途出力）
+  #ct_name:: Symbol    (through プラグインで生成された) セルタイプ名 ．Symbol として送られてくる（らしい）
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    # unmarshaler クラスか?
+    if ct_name == @unmarshaler_celltype_name.to_sym then
+      gen_ep_func_body_unmarshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    else
+      gen_ep_func_body_marshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    end
+  end
+
+  #===  marshal コードの生成
+  def gen_ep_func_body_marshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    b_void = false
+    b_ret_er = false
+
+    # 関数の戻り値の元の型を得る(typedef されている場合)
+    type = func_type.get_type.get_original_type
+
+    # 戻り値記憶用の変数を出力（void 型の関数では出力しない）
+    if ! type.kind_of?( VoidType ) then
+      if func_type.get_type.kind_of?( DefinedType ) && ( func_type.get_type.get_type_str == "ER" || func_type.get_type.get_type_str == "ER_INT" ) then
+        file.print( "    #{func_type.get_type.get_type_str}  retval_ = E_OK;\n" )
+        b_ret_er = true
+      else
+        file.print( "    #{func_type.get_type.get_type_str}  retval_;\n" )
+      end
+    else
+      b_void = true
+    end
+
+    file.print( "    ER      ercd_;\n" )
+    file.print( "    FLGPTN  flgptn;\n" )
+
+    # 呼び先の signature を取り出す
+    signature = @signature
+
+    # 関数 ID （整数値）
+    func_id = signature.get_id_from_func_name( func_name )
+    file.print( "    int16_t  func_id_ = #{func_id};    /* id of #{func_name}: #{func_id} */\n" )
+
+    file.print( "    uint8_t  msg[256];\n" )
+
+    # シングルトンでないか？
+    if ! b_singleton then
+
+      # singleton でなければ p_cellcb 取得コードを出力
+      file.print <<EOT
+    #{ct_name}_CB *p_cellcb;
+
+    if( VALID_IDX( idx ) ){
+        p_cellcb = GET_CELLCB(idx);
+EOT
+
+      # エラーを返すか？
+      if b_ret_er then
+        file.print <<EOT
+    }else{
+         return ERCD( E_RPC, E_ID );
+    }
+EOT
+      else
+        file.print <<EOT
+    }else{
+        /* エラー処理コードをここに記述 */
+    }
+EOT
+      end
+    end
+
+    # channel lock コード
+    file.print <<EOT
+    ///* Channel Lock */
+    //if( is_cLockChannel_joined() )
+    //  cLockChannel_wait();
+
+EOT
+
+=begin
+    # SOP を送信
+    file.print "    /* SOPの送出 */\n"
+    file.print "    if( ( ercd_ = cTDR_sendSOP( true ) ) != E_OK )\n"
+    file.print "      goto error_reset;\n"
+=end
+
+    # func_id を送信
+    file.print "    /* 関数 id の送出 */\n"
+=begin
+    file.print "    if( ( ercd_ = cTDR_putInt16( func_id_ ) ) != E_OK )\n"
+    file.print "        goto error_reset;\n"
+=end
+    file.print "    *((int16_t *)(&msg[0])) = func_id_;\n"   
+
+    # p "celltype_name, sig_name, func_name, func_global_name"
+    # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
+
+    b_get = false    # marshal なら put
+    b_marshal = true  # marshal
+
+    # in 方向の入出力を出力
+    @index = 2
+    file.print "    /* 入力引数送出 */\n"
+    print_params( params, file, 1, b_marshal, b_get, true, func_type.is_oneway? )
+    print_params( params, file, 1, b_marshal, b_get, false, func_type.is_oneway? )
+=begin
+    if ! b_void && ! func_type.is_oneway? then
+      ret_ptr_type = PtrType.new( func_type.get_type )
+      print_param_nc( "retval_", ret_ptr_type, file, 1, :RETURN, "&", nil, b_get )
+    end
+=end
+
+    file.print "    /* EOPの送出（パケットの掃きだし） */\n"
+    if ! func_type.is_oneway? then
+      b_continue = "true"
+    else
+      b_continue = "false"
+    end
+=begin
+    file.print "    if( (ercd_=cTDR_sendEOP(#{b_continue})) != E_OK )\n"
+    file.print "        goto error_reset;\n\n"
+=end
+    file.print "    if( (ercd_=cMessageBuffer_send(msg, #{@index})) != E_OK )\n"
+    file.print "        goto error_reset;\n\n"
+
+    file.print "        cSemaphore_signal();\n\n"
+
+    if ! func_type.is_oneway? then
+      file.print <<EOT
+    if( (ercd_=cEventflag_wait( 0x01, TWF_ANDW, &flgptn )) != E_OK ){
+      ercd_ = ERCD(E_RPC,ercd_);
+      goto error_reset;
+    }
+    if( (ercd_=cEventflag_clear( 0x00 ) ) != E_OK ){
+      ercd_ = ERCD(E_RPC,ercd_);
+      goto error_reset;
+    }
+EOT
+    end # ! func_type.is_oneway?
+
+    file.print <<EOT
+    ///* Channel Lock */
+    //if( is_cLockChannel_joined() )
+    //  cLockChannel_signal();
+EOT
+
+    if( b_void == false )then
+      # 呼び元に戻り値をリターン
+      file.print( "    cMessageBuffer_receive(&retval_);\n" )
+      file.print( "    return retval_;\n" )
+    else
+      file.print( "    return;\n" )
+    end
+
+    file.print <<EOT
+
+error_reset:
+#if 0
+    if( ercd_ != ERCD( E_RPC, E_RESET ) )
+        (void)cTDR_reset();
+#endif
+EOT
+
+    # channel lock コード
+    file.print <<EOT
+    ///* Channel Lock */
+    //if( is_cLockChannel_joined() )
+    //  cLockChannel_signal();
+
+EOT
+
+    if( b_ret_er != false )then
+      # 呼び元に戻り値をリターン
+      file.print( "    return ercd_;\n" )
+    else
+      file.print( "    return;\n" )
+    end
+
+  end
+
+  #===  unmarshal コードの生成
+  def gen_ep_func_body_unmarshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+#    b_ret_er = true
+    b_ret_er = false
+
+    # func_id を得るコードを生成
+    file.print <<EOT
+
+    int16_t   func_id_;
+    ER        ercd_;
+
+    #{ct_name}_CB *p_cellcb;
+
+    if( VALID_IDX( idx ) ){
+        p_cellcb = GET_CELLCB(idx);
+EOT
+
+    if b_ret_er then
+        file.print <<EOT
+    }else{
+        return ERCD( E_RPC, E_ID );
+    }
+EOT
+    else
+        file.print <<EOT
+    }else{
+        /* エラー処理コードをここに記述 */
+    }
+EOT
+    end
+
+    file.print <<EOT
+
+    cSemaphore_wait();
+
+#if 0
+    /* SOPのチェック */
+    if( (ercd_=cTDR_receiveSOP( false )) != E_OK )
+        goto error_reset;
+    /* func_id の取得 */
+    if( (ercd_=cTDR_getInt16( &func_id_ )) != E_OK )
+        goto error_reset;
+#endif
+
+    if( (ercd_ = cMessageBuffer_receive(msg) < 0 ) )
+        goto error_reset;
+    func_id_ = ((int16_t *)msg)[0];
+
+#ifdef RPC_DEBUG
+    syslog(LOG_INFO, "unmarshaler task: func_id: %d", func_id_ );
+#endif
+    switch( func_id_ ){
+EOT
+
+    # 呼び先の signature を取り出す
+    # port = @celltype.find( @next_cell_port_name )
+    # signature = port.get_signature
+    signature = @signature
+
+    # through の signature に含まれる すべての関数について
+    signature.get_function_head_array.each { |f|
+      f_name = f.get_name
+      f_type = f.get_declarator.get_type
+      id = signature.get_id_from_func_name( f_name )
+
+      # 関数は返り値を持つか?
+      if f_type.get_type.kind_of?( VoidType ) then
+        b_void = true
+      else
+        b_void = false
+      end
+
+      # パケットの終わりをチェック（未受け取りのデータが残っていないかチェック）
+      file.print "    case #{id}:       /*** #{f_name} ***/ \n"
+      file.print "        if( tTransparentUnmarshaler_#{@signature.get_name}_#{f_name}() != E_OK )\n"
+      file.print "            goto error_reset;\n"
+      file.print "        break;\n"
+
+    } # 
+
+    if @PPAllocatorSize then
+      ppallocator_dealloc_str = "    /* PPAllocator のすべてを解放 */\n    cPPAllocator_dealloc_all();"
+    else
+      ppallocator_dealloc_str = ""
+    end
+
+
+    file.print <<EOT
+    default:
+#if 0 // deleted by ishikawa: tSysLogが未実装
+        syslog(LOG_INFO, "unmarshaler task: ERROR: unknown func_id: %d", func_id_ );
+#endif /* 0 */
+        break;
+    };
+#{ppallocator_dealloc_str}
+    return;
+
+error_reset:
+#if 0
+    if( ercd_ != ERCD( E_RPC, E_RESET ) )
+        (void)cTDR_reset();
+#else
+    return ercd_;
+#endif
+#{ppallocator_dealloc_str}
+EOT
+
+  end
+
+  # IN b_marshal, b_get
+  #  b_marshal = true  && b_get == false   :  マーシャラで入力引数送出
+  #  b_marshal = true  && b_get == true    :  マーシャラで出力引数受取
+  #  b_marshal = false && b_get == true    :  アンマーシャラで入力引数受取
+  #  b_marshal = false && b_get == get     :  アンマーシャラで出力引数送出
+  def print_params( params, file, nest, b_marshal, b_get, b_referenced, b_oneway = false )
+    params.each{ |param|
+# p "#{param.get_name}:  b_marshal: #{b_marshal} b_get: #{b_get}"
+      if ! ( b_referenced == param.is_referenced? ) then
+        next
+      end
+
+      dir = param.get_direction
+      type = param.get_type
+      if b_oneway && dir == :IN && type.get_original_type.kind_of?( PtrType ) || type.get_original_type.kind_of?( ArrayType ) then
+        # oneway, in, PtrType の場合コピー
+        alloc_cp = "cPPAllocator_alloc"
+        alloc_cp_extra = nil
+        print_param( param.get_name, type, file, nest, dir, nil, nil, b_get, alloc_cp, alloc_cp_extra )
+      else
+        if( b_get == false && b_marshal == true || b_get == true && b_marshal == false  )then
+          case dir
+#          when :IN, :INOUT, :SEND
+          when :IN, :INOUT, :OUT, :SEND, :RECEIVE
+            print_param_nc( param.get_name, type, file, nest, b_marshal, nil, nil, b_get )
+          end
+        else
+#         case dir
+#         when :OUT, :INOUT, :RECEIVE
+#         when :RECEIVE
+#           print_param_nc( param.get_name, type, file, nest, b_marshal, nil, nil, b_get )
+#         end
+        end
+      end
+    }
+  end
+
+  #=== コピーしない引数渡しコードの出力
+  def print_param_nc( name, type, file, nest, b_marshal, outer, outer2, b_get )
+    indent = "    " * ( nest + 1 )
+
+    case type
+    when DefinedType
+      print_param_nc( name, type.get_type, file, nest, b_marshal, outer, outer2, b_get )
+    when BoolType, IntType, FloatType, PtrType, ArrayType
+      case type
+      when BoolType
+        type_str = "Int8"
+        cast_str = "int8_t"
+      when IntType
+        bit_size = type.get_bit_size
+        case type.get_sign
+        when :UNSIGNED
+          signC = "U"
+          sign  = "u"
+        when :SIGNED
+          if bit_size == -1 || bit_size == -11 then
+            # signed char の場合、signed を指定する
+            signC = "S"
+            sign  = "s"
+          else
+            signC = ""
+            sign  = ""
+          end
+        else
+          signC = ""
+          sign  = ""
+        end
+
+        # p "pn:: #{name} #{bit_size} #{type.get_type_str}"
+        case bit_size
+        when  -1, -11  # -1: char_t, -11: char
+          type_str = "#{signC}Char"
+          cast_str = "#{sign}char_t"
+        when -2
+          type_str = "#{signC}Short"
+          cast_str = "#{sign}short_t"
+        when -3
+          type_str = "#{signC}Int"
+          cast_str = "#{sign}int_t"
+        when -4
+          type_str = "#{signC}Long"
+          cast_str = "#{sign}long_t"
+        when -5
+          type_str = "Intptr"
+          cast_str = "intptr_t"
+        when 8, 16, 32, 64, 128
+          type_str = "#{signC}Int#{bit_size}"
+          cast_str = "#{sign}int#{bit_size}_t"
+        else
+          raise "unknown bit_size '#{bit_size}' for int type "
+        end
+
+      when FloatType
+        bit_size = type.get_bit_size
+        if bit_size == 32 then
+          type_str = "Float32"
+          cast_str = "float32_t"
+        else
+          type_str = "Double64"
+          cast_str = "double64_t"
+        end
+
+      when PtrType
+        type_str = "Intptr"
+        cast_str = "intptr_t"
+      when ArrayType
+        type_str = "Intptr"
+        cast_str = "intptr_t"
+      end
+
+      if type.get_type_str == cast_str then
+        cast_str = ""
+      else
+        cast_str = "(" + cast_str + ")"
+      end
+
+      if( b_get )then
+        cast_str.gsub!( /\)$/, "*)" )
+        file.print "    " * nest
+=begin
+        file.print "if( ( ercd_ = cTDR_get#{type_str}( #{cast_str}&(#{outer}#{name}#{outer2}) ) ) != E_OK )\n"
+        file.print "    " * nest
+        file.print "    goto error_reset;\n"
+=end
+        file.print "#{name} = *((#{type.get_type_str} *)(&msg[#{@index}]));\n"
+        if bit_size.nil?
+            raise "HRP2 RPC supports only specified bit_size"
+        else
+            case bit_size
+            when 8, 16, 32, 64, 128
+            else
+                raise "HRP2 RPC supports only specified bit_size"
+            end
+        end
+        @index += bit_size / 8
+      else
+        file.print "    " * nest
+=begin
+        file.print "if( ( ercd_ = cTDR_put#{type_str}( #{cast_str}#{outer}#{name}#{outer2} ) ) != E_OK )\n"
+        file.print "    " * nest
+        file.print "    goto error_reset;\n"
+=end
+        file.print "*((#{type.get_type_str} *)(&msg[#{@index}])) = #{name};\n"
+        if bit_size.nil?
+            raise "HRP2 RPC supports only specified bit_size"
+        else
+            case bit_size
+            when 8, 16, 32, 64, 128
+            else
+                raise "HRP2 RPC supports only specified bit_size"
+            end
+        end
+        @index += bit_size / 8
+      end
+
+    when StructType
+      members_decl =type.get_members_decl
+      members_decl.get_items.each { |m|
+        if m.is_referenced? then
+          print_param_nc( m.get_name, m.get_type, file, nest, b_marshal, "#{outer}#{name}#{outer2}.", nil, b_get )
+        end
+      }
+      members_decl.get_items.each { |m|
+        if ! m.is_referenced? then
+          print_param_nc( m.get_name, m.get_type, file, nest, b_marshal, "#{outer}#{name}#{outer2}.", nil, b_get )
+        end
+      }
+
+    when VoidType
+    when EnumType  # mikan EnumType
+    when FuncType  # mikan FuncType
+    end
+  end
+
+
+  #=== PREAMBLE 部のコード生成
+  # アンマーシャラセルタイプの場合、アンマーシャラ関数のプロトタイプ宣言を生成
+  def gen_preamble file, b_singleton, ct_name, global_name
+    if ct_name != @unmarshaler_celltype_name.to_sym then
+      return
+    end
+
+    file.print "/* アンマーシャラ関数のプロトタイプ宣言 */\n"
+    # signature に含まれる すべての関数について
+    @signature.get_function_head_array.each { |f|
+      f_name = f.get_name
+      f_type = f.get_declarator.get_type
+      id = @signature.get_id_from_func_name( f_name )
+      file.print "static ER  tTransparentUnmarshaler_#{@signature.get_name}_#{f_name}();\t/* func_id: #{id} */\n"
+    }
+    file.print "\n"
+    file.print "static uint8_t msg[256];\n"
+    file.print "\n"
+  end
+
+  #=== POSTAMBLE 部のコード生成
+  # アンマーシャラセルタイプの場合、アンマーシャラ関数の生成
+  def gen_postamble file, b_singleton, ct_name, global_name
+    if ct_name != @unmarshaler_celltype_name.to_sym then
+      return
+    end
+
+    file.print "\n/*** アンマーシャラ関数 ***/\n\n"
+    @signature.get_function_head_array.each { |f|
+      f_name = f.get_name
+      f_type = f.get_declarator.get_type
+      id = @signature.get_id_from_func_name( f_name )
+
+      # 関数は返り値を持つか?
+      if f_type.get_type.kind_of?( VoidType ) then
+        b_void = true
+      else
+        b_void = false
+      end
+
+      file.print <<EOT
+/*
+ * name:    #{f_name}
+ * func_id: #{id} 
+ */
+EOT
+      file.print "static ER\n"
+      file.print "tTransparentUnmarshaler_#{@signature.get_name}_#{f_name}()\n"
+      file.print "{\n"
+      file.print "	ER  ercd_;\n"
+
+      # 引数を受取る変数の定義
+      param_list = f.get_declarator.get_type.get_paramlist.get_items
+           # FuncHead->  Decl->    FuncType->ParamList
+      param_list.each{ |par|
+        name = par.get_name
+        type = par.get_type
+        if type.kind_of? ArrayType then
+          type = type.get_type
+          aster = "(*"
+          aster2 = ")"
+        else
+          aster = ""
+          aster2 = ""
+        end
+
+        type_str = type.get_type_str.gsub( /\bconst\b */, "" ) # "const" を外す
+
+        file.printf( "    %-12s %s%s%s%s;\n", type_str, aster, name, aster2, type.get_type_str_post )
+      }
+
+      # 戻り値を受け取る変数の定義
+      if ! b_void then
+        if f.is_oneway? then
+          retval_ptr = ""   # oneway の場合、受け取るが捨てられる
+        else
+          # =begin ishikawa modified
+          # retval_ptr = "*"
+          retval_ptr = ""
+          # =end ishikawa modified
+        end
+        file.printf( "    %-12s #{retval_ptr}retval_%s;\n", f_type.get_type.get_type_str, f_type.get_type.get_type_str_post )
+      end
+
+      # in 方向の入出力を入力
+      file.print "\n        /* 入力引数受取 */\n"
+      b_get = true    # unmarshal では get
+      b_marshal  = false
+      @index = 2
+      print_params( param_list, file, 1, b_marshal, b_get, true, f.is_oneway? )
+      print_params( param_list, file, 1, b_marshal, b_get, false, f.is_oneway? )
+=begin
+      if ! b_void && ! f.is_oneway? then
+        ret_ptr_type = PtrType.new( f_type.get_type )
+        print_param_nc( "retval_", ret_ptr_type, file, 2, :RETURN, nil, nil, b_get )
+      end
+=end
+      # パケットの受信完了
+      # mikan 本当は、対象関数を呼出す後に実施したい．呼出しパケットの使用終わりを宣言する目的として
+      file.print "        /* パケット終わりをチェック */\n"
+      if ! f.is_oneway? then
+        b_continue = "true"
+      else
+        b_continue = "false"
+      end
+=begin
+      file.print "    if( (ercd_=cTDR_receiveEOP(#{b_continue})) != E_OK )\n"
+      file.print "        goto error_reset;\n\n"
+=end
+      # 対象関数を呼出す
+      file.print "    /* 対象関数の呼出し */\n"
+      if b_void then
+        file.print( "    cServerCall_#{f_name}(" )
+      else
+        file.print( "    #{retval_ptr}retval_ = cServerCall_#{f_name}(" )
+      end
+
+      delim = " "
+      param_list.each{ |par|
+        file.print delim
+        delim = ", "
+        file.print "#{par.get_name}"
+      }
+      file.print( " );\n" )
+
+      # 戻り値、出力引数の受取コードの生成
+
+      if ! b_void && ! f.is_oneway? then
+        file.print "    if( (ercd_ = cMessageBuffer_send(&retval_, sizeof(#{f_type.get_type.get_type_str})) != E_OK ) )\n"
+        file.print "        goto error_reset;\n"
+
+      end
+      # oneway の場合出力、戻り値が無く、受取を待たない（非同期な呼出し）
+      if ! f.is_oneway? then
+        file.print <<EOT
+    /* 関数処理の終了を通知 */
+    if( ( ercd_ = cEventflag_set( 0x01 ) ) != E_OK ){
+      goto error_reset;
+    }
+EOT
+      end  # ! f.is_oneway?
+      file.print <<EOT
+    return E_OK;
+error_reset:
+    return ercd_;
+}
+
+EOT
+
+    }
+
+  end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenOpaqueMarshaler.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenOpaqueMarshaler.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenOpaqueMarshaler.rb	(revision 398)
@@ -0,0 +1,1110 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2018 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== GenOpaqueMarshaler
+# OpaqueRPCPlugin, sharedOpaqueRPCPlugin 共通の要素を集めたモジュール
+module GenOpaqueMarshaler
+
+  # プラグイン引数名と Proc
+  RPCPluginArgProc = {
+    "clientChannelCelltype" => Proc.new { |obj,rhs| obj.set_clientChannelCelltype rhs },
+    "serverChannelCelltype" => Proc.new { |obj,rhs| obj.set_serverChannelCelltype rhs },
+    "clientChannelCell" => Proc.new { |obj,rhs| obj.set_clientChannelCell rhs },
+    "serverChannelCell" => Proc.new { |obj,rhs| obj.set_serverChannelCell rhs },
+    "clientChannelInitializer" => Proc.new { |obj,rhs| obj.set_clientChannelInitializer rhs },
+    "serverChannelInitializer" => Proc.new { |obj,rhs| obj.set_serverChannelInitializer rhs },
+    "clientSemaphoreCelltype" => Proc.new { |obj,rhs| obj.set_clientSemaphoreCelltype rhs },
+    "clientSemaphoreInitializer" => Proc.new { |obj,rhs| obj.set_clientSemaphoreInitializer rhs },
+    "clientErrorHandler" => Proc.new { |obj,rhs| obj.set_clientErrorHandler rhs },
+    "serverErrorHandler" => Proc.new { |obj,rhs| obj.set_serverErrorHandler rhs },
+    "TDRCelltype"     => Proc.new { |obj,rhs| obj.set_TDRCelltype rhs },
+    "PPAllocatorSize" => Proc.new { |obj,rhs| obj.set_PPAllocatorSize rhs },
+    "substituteAllocator"  => Proc.new { |obj,rhs| obj.set_substituteAllocator rhs },
+    "noServerChannelOpenerCode"  => Proc.new { |obj,rhs| obj.set_noServerChannelOpenerCode rhs },
+    "taskCelltype"    => Proc.new { |obj,rhs| obj.set_taskCelltype rhs },
+    "taskPriority"    => Proc.new { |obj,rhs| obj.set_taskPriority rhs },
+    "stackSize"      => Proc.new { |obj,rhs| obj.set_stackSize rhs },
+  }
+
+  ##### プラグイン引数チェック関数
+
+  #=== プラグイン引数 taskPriority のチェック
+  def set_taskPriority( rhs )
+    @taskPriority = rhs
+  end
+
+  #=== プラグイン引数 serverChannelCelltype のチェック
+  def set_serverChannelCelltype( rhs )
+    @serverChannelCelltype = rhs.to_sym
+    # path = [ "::", @serverChannelCelltype ]
+    # obj = Namespace.find( path )
+    nsp = NamespacePath.analyze( @serverChannelCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: serverChannelCelltype '#{rhs}' not celltype or not defined" )
+    end
+  end
+
+  #=== プラグイン引数 clientChannelCelltype のチェック
+  def set_clientChannelCelltype( rhs )
+    @clientChannelCelltype = rhs.to_sym
+    # path = [ "::", @clientChannelCelltype ]
+    # obj = Namespace.find( path )
+    nsp = NamespacePath.analyze( @clientChannelCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: clientChanneclCelltype '#{rhs}' not celltype or not defined" )
+    end
+  end
+
+  #=== プラグイン引数 serverChannelCell のチェック
+  def set_serverChannelCell( rhs )
+    @serverChannelCell = rhs.to_sym
+    # ChannelCell はプラグインで生成されるため、ここではチェックできない
+    # path = [ "::", @serverChannelCell ]
+    # obj = Namespace.find( path )
+    # if ! obj.instance_of?( Cell ) then
+    #   cdl_error( "RPCPlugin: serverChanneclCell '#{rhs}' not cell or not defined" )
+    # end
+  end
+
+  #=== プラグイン引数 clientChannelCell のチェック
+  def set_clientChannelCell( rhs )
+    @clientChannelCell = rhs.to_sym
+    # ChannelCell はプラグインで生成されるため、ここではチェックできない
+    # path = [ "::", @clientChannelCell ]
+    # obj = Namespace.find( path )
+    # if ! obj.instance_of?( Cell ) then
+    #   cdl_error( "RPCPlugin: clientChanneclCell '#{rhs}' not cell or not defined" )
+    # end
+  end
+
+  #=== プラグイン引数 serverChannelInitializer のチェック
+  def set_serverChannelInitializer( rhs )
+    @serverChannelInitializer = rhs.to_sym
+  end
+
+  #=== プラグイン引数 clientChannelInitializer のチェック
+  def set_clientChannelInitializer( rhs )
+    @clientChannelInitializer = rhs.to_sym
+  end
+
+  #=== タスクタイプ taskCellype のチェック
+  def set_taskCelltype( rhs )
+    @taskCelltype = rhs.to_sym
+    # path = [ "::", @taskCelltype ]
+    # obj = Namespace.find( path )
+    nsp = NamespacePath.analyze( @taskCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: taskCelltype '#{rhs}' not celltype or not defined" )
+    end
+  end
+
+  #=== タスクタイプ stack\size のチェック
+  def set_stackSize( rhs )
+    @stackSize = rhs
+  end
+
+  #=== プラグイン引数 PPAllocatorSize のチェック
+  def set_PPAllocatorSize( rhs )
+    @PPAllocatorSize = rhs
+  end
+
+  #=== プラグイン引数 TDRCelltype のチェック
+  def set_TDRCelltype( rhs )
+    @TDRCelltype = rhs.to_sym
+    # path = [ "::", @TDRCelltype ]
+    # obj = Namespace.find( path )
+    nsp = NamespacePath.analyze( @TDRCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: TDRCelltype '#{rhs}' not celltype or not found" )
+    end
+  end
+
+  #=== プラグイン引数 substituteAllocator のチェック
+  # オプション引数が、以下の形式であることをチェック
+  #     substituteAllocator(Alloc.eAlloc=>Subst.eAlloc,Alloc2.eAlloc=>Subst2.eAlloc)
+  def set_substituteAllocator( rhs )
+    #str::String : 破壊される（マッチした残りになる）。str.empty? で空になったことをチェックできる
+    #regexp::Regexp : 期待するトークンにマッチする正規表現。 "\A" 出始める
+    #expected::String: 期待するトークン、regexp が出現しなかった場合にエラーメッセージとして表示
+    def optparse (str,regexp,expected)
+      str.strip!
+      token = nil
+      res = str.sub!( regexp ){ |matched|  token = matched;  "" }
+      if ! token then
+        cdl_error( "syntax error in substituteAllocator option near '#{str}', expected '#{expected}'" )
+      end
+      return token
+    end
+
+    opt = rhs.dup
+    ident_rexpr = /\A(\w[\w\d]*)/
+
+    # "Alloc.eAlloc=>CAlloc.eAlloc" の形式になっていることをチェック
+    while true
+      lhs_alloc_cell = optparse( opt, ident_rexpr, "allocator cell name" )
+      break if ! lhs_alloc_cell
+
+      res = optparse( opt, /\A\./, "." )
+      break if ! res
+
+      lhs_alloc_ent = optparse( opt, ident_rexpr, "allocator cell entry name" )
+      break if ! lhs_alloc_ent
+
+      res = optparse( opt, /\A\=\>/, "=>" )
+      break if ! res
+
+      rhs_alloc_cell = optparse( opt, ident_rexpr, "allocator cell name" )
+      break if ! rhs_alloc_cell
+
+      res = optparse( opt, /\A\./, "." )
+      break if ! res
+
+      rhs_alloc_ent = optparse( opt, ident_rexpr, "allocator cell entry name" )
+      break if ! rhs_alloc_ent
+
+#  ここでは、右辺のチェックはできない。右辺のセルは前方参照となる
+#      path = [ "::", rhs_alloc_cell.to_sym ]   # mikan namespace
+#      obj = Namespace.find( path )
+#      if ! obj.instance_of?( Cell ) || obj.get_region.get_path_string != @clientRegion then
+#        cdl_error( "RPCPlugin: substituteAllocator: '#{rhs_alloc_cell}' not cell or not found in client region" )
+#      else
+#        ct = obj.get_celltype
+#        if ct #  nil なら既にエラー
+#          ent = ct.find rhs_alloc_ent
+#          if ! ent.instance_of? Port || ent.get_port_type != :ENTRY || ent.get_signature == nil || ! ent.get_signature.is_allocator?
+#            cdl_error( "RPCPlugin: substituteAllocator: '#{rhs_alloc_cell}.#{rhs_alloc_ent}' not entry port or not have alllocator signature" )
+#          end
+#        end
+#      end
+
+      @substituteAllocator[ "#{lhs_alloc_cell}.#{lhs_alloc_ent}".to_sym ] =
+        [ lhs_alloc_cell, lhs_alloc_ent, rhs_alloc_cell, rhs_alloc_ent ]
+
+# p "substituteAllocator: #{lhs_alloc_cell}.#{lhs_alloc_ent}=>#{rhs_alloc_cell}.#{rhs_alloc_ent}"
+
+      break if opt.empty?
+
+      res = optparse( opt, /\A\,/, "," )
+      break if ! res
+    end
+
+  end
+
+  #=== プラグイン引数 noServerChannelOpenerCode のチェック
+  def set_noServerChannelOpenerCode( rhs )
+    rhs = rhs.to_sym
+    if rhs == :true
+      @noServerChannelOpenerCode = true
+    elsif rhs == :false then
+      @noServerChannelOpenerCode = false
+    else
+      cdl_error( "RPCPlugin: specify true or false for noServerChannelOpenerCode" )
+    end
+  end
+
+  #=== プラグイン引数 clientSemaphoreCelltype のチェック
+  def set_clientSemaphoreCelltype rhs
+    @semaphoreCelltype = rhs.to_sym
+    nsp = NamespacePath.analyze( @semaphoreCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: clientSemaphoreCelltype '#{rhs}' not celltype or not defined" )
+    end
+  end
+
+  #=== プラグイン引数 clientSemaphoreInitializer のチェック
+  def set_clientSemaphoreInitializer rhs
+    @semaphoreInitializer = rhs.to_sym
+  end
+
+  #=== プラグイン引数 clientErrorHandler のチェック
+  def set_clientErrorHandler rhs
+    @clientErrorHandler = rhs.to_sym
+  end
+
+  #=== プラグイン引数 serverErrorHandler のチェック
+  def set_serverErrorHandler rhs
+    @serverErrorHandler = rhs.to_sym
+  end
+
+
+  #===  セルの名前を得る
+  # ThroughPlugin::get_cell_name plugin.rb をオーバーライド
+  def get_cell_name
+    @cell_name
+    # @clientChannelCell
+  end
+
+  #=== marshaler のセルタイプ名を設定する
+  def initialize_opaque_marshaler
+
+    # オプション設定される変数のデフォルトを設定
+    @taskPriority = 11
+    @stackSize  = 4096
+    @serverChannelCelltype = :"tSocketServer"
+    @clientChannelCelltype = :"tSocketClient"
+    @serverChannelCell = :"#{@cell_name}Server"
+    @clientChannelCell = :"#{@cell_name}Client"
+    @serverChannelInitializer = subst_name( "portNo=8931+$count$;" ).to_sym
+    @clientChannelInitializer = subst_name( "portNo=8931+$count$; serverAddr=\"127.0.0.1\"; " ).to_sym
+    @taskCelltype = :"tTask"
+    @PPAllocatorSize = nil
+    # @TDRCelltype  = :"tTDR"   # "tNBOTDR" に変更の予定
+    @TDRCelltype  = :"tNBOTDR"
+    @substituteAllocator = {}
+    @noServerChannelOpenerCode = false
+    @semaphoreCelltype = :"tSemaphore"
+    @semaphoreInitializer = :"count = 1; attribute = C_EXP( \"TA_NULL\" ); ";
+    @clientErrorHandler = nil
+    @serverErrorHandler = nil
+    @b_genOpener = false
+    @taskMainCelltype = :"tRPCDedicatedTaskMain"
+
+    @marshaler_celltype_name = :"tOpaqueMarshaler_#{@signature.get_global_name}"
+    @unmarshaler_celltype_name = :"tOpaqueUnmarshaler_#{@signature.get_global_name}"
+    @marshaler_celltype_file_name = "#{$gen}/#{@marshaler_celltype_name}.cdl"
+
+    # signature で対応できないものをチェック
+    @signature.each_param{ |func_decl, param_decl|
+      if param_decl.get_direction == :OUT then
+        if param_decl.get_count && ! param_decl.get_size then
+          cdl_error( "#{@signature.get_namespace_path}.#{func_decl.get_name}.#{param_decl.get_name}: size_is must be specified for out parameter of Opaque RPC" )
+        end
+        if param_decl.get_string == -1 then
+          cdl_error( "#{@signature.get_namespace_path}.#{func_decl.get_name}.#{param_decl.get_name}: string length must be specified for out parameter of Opaque RPC" )
+        end
+      end
+    }
+  end
+
+  #=== GenOpaqueMarshaler# Opener Code の生成時のチェック
+  def check_opener_code
+    # サーバーチャンネルセルタイプが entry sServerChannelOpener eOpener を持つかどうかをチェック
+    # mikan entry か (call でないか) をチェックしていない
+    # scct = Namespace.find ["::", @serverChannelCelltype] # mikan namespace
+    nsp = NamespacePath.analyze( @serverChannelCelltype.to_s )
+    scct = Namespace.find nsp
+    if scct then
+      obj = scct.find( :"eOpener" )
+      if obj.instance_of? Port then
+        if obj.get_signature.get_name.to_sym == :sServerChannelOpener then
+          if @noServerChannelOpenerCode == false then
+            @b_genOpener = true
+            @taskMainCelltype = :"tRPCDedicatedTaskMainWithOpener"
+          end
+        end
+      end
+    end
+    if @noServerChannelOpenerCode == false && @taskMainCelltype != :"tRPCDedicatedTaskMainWithOpener" then
+      cdl_warning( "O9999 ServerChannelOpener code not generated, not found 'entry sServerChannelOpener eOpener'")
+    end
+  end
+
+  #=== GenOpaqueMarshaler# PPAllocator の必要性をチェックする
+  def check_PPAllocator
+    if @signature.need_PPAllocator?(true) then
+      if @PPAllocatorSize == nil then
+        cdl_error( "PPAllocatorSize must be speicified for size_is array" )
+      end
+    end
+  end
+
+  ##### 
+
+  def gen_marshaler_celltype
+    f = CFile.open( @marshaler_celltype_file_name, "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    if @PPAllocatorSize then
+      alloc_call_port = "  call sPPAllocator cPPAllocator;\n"
+    else
+      alloc_call_port = ""
+    end
+
+    f.print <<EOT
+
+celltype #{@marshaler_celltype_name} {
+  entry #{@signature.get_namespace_path} eClientEntry;
+  call sTDR       cTDR;
+  [optional]
+    call sSemaphore cLockChannel;
+  [optional]
+    call sRPCErrorHandler cErrorHandler;
+};
+celltype #{@unmarshaler_celltype_name} {
+  call #{@signature.get_namespace_path} cServerCall;
+  call  sTDR       cTDR;
+  [optional]
+    call sRPCErrorHandler cErrorHandler;
+  entry sUnmarshalerMain  eService;
+#{alloc_call_port}};
+EOT
+    f.close
+  end
+
+  #===  受け口関数の本体コードを生成（頭部と末尾は別途出力）
+  #ct_name:: Symbol    (through プラグインで生成された) セルタイプ名 ．Symbol として送られてくる（らしい）
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    # unmarshaler クラスか?
+    if ct_name == @unmarshaler_celltype_name.to_sym then
+      gen_ep_func_body_unmarshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    else
+      gen_ep_func_body_marshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    end
+  end
+
+  #===  marshal コードの生成
+  def gen_ep_func_body_marshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    b_void = false
+    b_ret_er = false
+
+    # 関数の戻り値の元の型を得る(typedef されている場合)
+    type = func_type.get_type.get_original_type
+
+    # 戻り値記憶用の変数を出力（void 型の関数では出力しない）
+    if ! type.is_void? then
+      file.print( "\t#{func_type.get_type.get_type_str}\t\tretval_;\n" )
+      if func_type.get_type.kind_of?( DefinedType ) && ( func_type.get_type.get_type_str == "ER" || func_type.get_type.get_type_str == "ER_INT" ) then
+        b_ret_er = true
+      end
+    else
+      b_void = true
+    end
+
+    file.print( "\tER\t\tercd_;\n" )
+    file.print( "\tint16_t\tstate_;\n" )
+
+    # 関数 ID （整数値）
+    func_id = "FUNCID_#{@signature.get_global_name}_#{func_name}".upcase
+    fid = @signature.get_id_from_func_name( func_name )
+    file.print( "\tint16_t\tfunc_id_ = #{func_id};	/* (id of '#{func_name}') = #{fid}*/\n" )
+
+    # シングルトンでないか？
+    if ! b_singleton then
+
+      # singleton でなければ p_cellcb 取得コードを出力
+      file.print <<EOT
+	#{ct_name}_CB *p_cellcb;
+
+	if( VALID_IDX( idx ) ){
+		p_cellcb = GET_CELLCB(idx);
+EOT
+
+      # エラーを返すか？
+      if b_ret_er then
+        file.print <<EOT
+	}else{
+		return ERCD( E_RPC, E_ID );
+	}
+EOT
+      else
+        file.print <<EOT
+	}else{
+		/* エラー処理コードをここに記述 */
+	}
+
+EOT
+      end
+    end
+
+    if func_type.has_receive? then
+      file.print "	/* initialize receive parameters */\n"
+      params.each{ |param|
+        if param.get_direction == :RECEIVE then
+          file.print "	*#{param.get_name} = 0;\n"
+        end
+      }
+    end
+
+    # channel lock コード
+    file.print <<EOT
+
+	/* Channel Lock */
+	SET_RPC_STATE( state_, RPCSTATE_CLIENT_GET_SEM );
+	if( is_cLockChannel_joined() ){
+		if( (ercd_=cLockChannel_wait()) != E_OK )
+			goto error_reset;
+	}
+EOT
+
+    # SOP を送信
+    file.print "	/* SOPの送出 */\n"
+    file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_SEND_SOP );\n"
+    file.print "	if( ( ercd_ = cTDR_sendSOP( true ) ) != E_OK )\n"
+    file.print "		goto error_reset;\n"
+
+    # func_id を送信
+    file.print "	/* 関数 id の送出 */\n"
+    file.print "	if( ( ercd_ = cTDR_putInt16( func_id_ ) ) != E_OK )\n"
+    file.print "		goto error_reset;\n"
+
+    # p "celltype_name, sig_name, func_name, func_global_name"
+    # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
+
+    b_get = false    # marshal なら put
+    b_marshal = true  # marshal
+
+    # in 方向の入出力を出力
+    if func_type.has_inward? then
+      file.print "	/* 入力引数送出 */\n"
+      file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_SEND_BODY );\n"
+      print_params( params, file, 1, b_marshal, b_get, true, "eClientEntry", func_name )
+      print_params( params, file, 1, b_marshal, b_get, false, "eClientEntry", func_name )
+    end
+    print_out_nullable( params, file, 1, b_marshal );
+
+    if ! func_type.is_oneway? then
+      b_continue = "true"
+    else
+      b_continue = "false"
+    end
+    file.print "	/* EOPの送出（パケットの掃きだし） */\n"
+    file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_SEND_EOP );\n"
+    file.print "	if( (ercd_=cTDR_sendEOP(#{b_continue})) != E_OK )\n"
+    file.print "		goto error_reset;\n\n"
+
+    # send のメモリをデアロケート
+    if func_type.has_send? then
+      file.print "	/* dealloc send parameter while executing */\n"
+      file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_EXEC );\n"
+      dir = :SEND; nest = 1; dealloc_cp = "eClientEntry_#{func_name}"
+      dealloc_for_params( params, file, nest, dir, dealloc_cp )
+      file.print "\n"
+    end
+
+    if ! func_type.is_oneway? then
+
+      file.print "	/* パケットの始まりをチェック */\n"
+      file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_RECV_SOP );\n"
+      file.print "	if( (ercd_=cTDR_receiveSOP( true )) != E_OK )\n"
+      file.print "		goto error_reset;\n"
+
+      b_get = true     # marshaler は get
+      file.print "	/* 戻り値の受け取り */\n"
+      print_param( "retval_", func_type.get_type, file, 1, :RETURN, nil, nil, b_marshal, b_get )
+
+      if func_type.has_outward? then
+        if b_ret_er then
+          indent_level = 2
+          file.print "	if( MERCD( retval_ ) != E_RPC ){\n"
+        else
+          indent_level = 1
+        end
+        indent = "	" * indent_level
+
+        file.print "#{indent}/* 出力値の受け取り */\n"
+        file.print "#{indent}SET_RPC_STATE( state_, RPCSTATE_CLIENT_RECV_BODY );\n"
+        print_params( params, file, indent_level, b_marshal, b_get, true, "eClientEntry", func_name )
+        print_params( params, file, indent_level, b_marshal, b_get, false, "eClientEntry", func_name )
+
+        if b_ret_er then
+          file.print "	}\n"
+        end
+      end
+
+      file.print "\n	/* パケットの終わりをチェック */\n"
+      file.print "	SET_RPC_STATE( state_, RPCSTATE_CLIENT_RECV_EOP );\n"
+      file.print "	if( (ercd_=cTDR_receiveEOP(false)) != E_OK )\n"  # b_continue = false
+      file.print "		goto error_reset;\n"
+
+    end # ! func_type.is_oneway?
+
+    # channel lock コード
+    file.print <<EOT
+	/* Channel Unlock */
+	SET_RPC_STATE( state_, RPCSTATE_CLIENT_RELEASE_SEM );
+	if( is_cLockChannel_joined() ){
+		if( (ercd_=cLockChannel_signal()) != E_OK )
+			goto error_reset;
+	}
+EOT
+
+    file.print <<EOT
+	/* state_ is not used in normal case */
+  /* below is to avoid 'set but not used' warnning */
+	(void)state_;
+EOT
+
+    if( b_void == false )then
+      # 呼び元に戻り値をリターン
+      file.print( "	return retval_;\n" )
+    else
+      file.print( "	return;\n" )
+    end
+
+    file.print <<EOT
+
+error_reset:
+EOT
+    # send のメモリをデアロケート
+    if func_type.has_send? then
+      file.print "	/* dealloc send parameter */\n"
+      file.print "	if( state_ < RPCSTATE_CLIENT_EXEC ){\n"
+      dir = :SEND; nest = 2; dealloc_cp = "eClientEntry_#{func_name}"
+      dealloc_for_params( params, file, nest, dir, dealloc_cp )
+      file.print "	}\n"
+    end
+
+    # receive のメモリをデアロケート
+    if func_type.has_receive? then
+      file.print( "	/* receive parameter */\n" )
+      dir = :RECEIVE; nest = 1; dealloc_cp = "eClientEntry_#{func_name}"
+      dealloc_for_params( params, file, nest, dir, dealloc_cp, true )
+    end
+
+    file.print <<EOT
+	if( MERCD( ercd_ ) != E_RESET )
+		(void)cTDR_reset();
+EOT
+
+    # channel lock コード
+    file.print <<EOT
+	/* Channel Unlock */
+	if( is_cLockChannel_joined() )
+		cLockChannel_signal();
+
+	if( ercd_ != E_OK && is_cErrorHandler_joined() )
+		cErrorHandler_errorOccured( func_id_, ercd_, state_ );
+EOT
+
+    if( b_ret_er != false )then
+      # 呼び元に戻り値をリターン
+      file.print( "	return ERCD( E_RPC, MERCD( ercd_ ) );\n" )
+    else
+      file.print( "	return;\n" )
+    end
+
+  end
+
+  #===  unmarshal コードの生成
+  def gen_ep_func_body_unmarshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    b_ret_er = true
+
+    # func_id を得るコードを生成
+    file.print <<EOT
+
+	int16_t	func_id_;
+	ER		ercd_ = E_OK;
+	int16_t	state_;
+
+	#{ct_name}_CB *p_cellcb;
+
+	if( VALID_IDX( idx ) ){
+		p_cellcb = GET_CELLCB(idx);
+EOT
+
+    if b_ret_er then
+        file.print <<EOT
+	}else{
+		return E_ID;
+	}
+EOT
+    else
+        file.print <<EOT
+	}else{
+		/* エラー処理コードをここに記述 */
+	}
+EOT
+    end
+
+    file.print <<EOT
+
+#ifdef RPC_DEBUG
+	syslog(LOG_INFO, "Entering RPC service loop" );
+#endif
+
+	/* SOPのチェック */
+	SET_RPC_STATE( state_, RPCSTATE_SERVER_RECV_SOP );
+	if( (ercd_=cTDR_receiveSOP( false )) != E_OK )
+		goto error_reset;
+	/* func_id の取得 */
+	if( (ercd_=cTDR_getInt16( &func_id_ )) != E_OK )
+		goto error_reset;
+
+#ifdef RPC_DEBUG
+	syslog(LOG_INFO, "unmarshaler task: func_id: %d", func_id_ );
+#endif
+	switch( func_id_ ){
+EOT
+
+    # signature に含まれる すべての関数について
+    @signature.get_function_head_array.each { |f|
+      f_name = f.get_name
+      f_type = f.get_declarator.get_type
+      func_id = "FUNCID_#{@signature.get_global_name}_#{f_name}".upcase
+      fid = @signature.get_id_from_func_name( f_name )
+
+      file.print "	case #{func_id}:		/* (id of '#{f_name}') = #{fid} */ \n"
+      file.print "		ercd_ = tOpaqueUnmarshaler_#{@signature.get_global_name}_#{f_name}( p_cellcb, &state_ );\n"
+      file.print "		break;\n"
+
+    } #
+
+    if @PPAllocatorSize then
+      ppallocator_dealloc_str = "	/* PPAllocator のすべてを解放 */\n	cPPAllocator_dealloc_all();"
+    else
+      ppallocator_dealloc_str = ""
+    end
+
+    file.print <<EOT
+	default:
+		syslog(LOG_INFO, "unmarshaler task: ERROR: unknown func_id: %d", func_id_ );
+		ercd_ = E_ID;
+	};
+error_reset:  /* OK cases also come here */
+#{ppallocator_dealloc_str}
+	if( ercd_ == E_OK )
+		return ercd_;
+	if( is_cErrorHandler_joined() )
+		ercd_ = cErrorHandler_errorOccured( func_id_, ercd_, state_ );
+	if( MERCD( ercd_ ) != E_RESET )
+		(void)cTDR_reset();
+	return ercd_;
+EOT
+
+  end
+
+  #=== PREAMBLE 部のコード生成
+  # アンマーシャラセルタイプの場合、アンマーシャラ関数のプロトタイプ宣言を生成
+  def gen_preamble file, b_singleton, ct_name, global_name
+    if ct_name != @unmarshaler_celltype_name.to_sym then
+      return
+    end
+
+    # string.h の include (memset, strlen のため)
+    file.print "/* header file (strlen, memset) */\n"
+    file.print "#include\t<string.h>\n\n"
+
+    file.print "/* アンマーシャラ関数のプロトタイプ宣言 */\n"
+    # signature に含まれる すべての関数について
+    @signature.get_function_head_array.each { |f|
+      f_name = f.get_name
+      f_type = f.get_declarator.get_type
+      id = @signature.get_id_from_func_name( f_name )
+      file.print "static ER  tOpaqueUnmarshaler_#{@signature.get_global_name}_#{f_name}(CELLCB *p_cellcb, int16_t *state);\t/* func_id: #{id} */\n"
+    }
+    file.print "\n"
+  end
+
+  #=== POSTAMBLE 部のコード生成
+  # アンマーシャラセルタイプの場合、個々のアンマーシャラ関数の生成
+  def gen_postamble file, b_singleton, ct_name, global_name
+    if ct_name != @unmarshaler_celltype_name.to_sym then
+      return
+    end
+
+    file.print "\n/*** アンマーシャラ関数 ***/\n\n"
+    @signature.get_function_head_array.each { |f|
+      f_name = f.get_name
+      f_type = f.get_declarator.get_type
+      id = @signature.get_id_from_func_name( f_name )
+
+      # 関数は返り値を持つか?
+      b_ret_er = false
+      init_retval = ""
+      if f_type.get_type.is_void? then
+        b_void = true
+      else
+        b_void = false
+        if f_type.get_type.get_type_str == "ER" || f_type.get_type.get_type_str == "ER_INT" then
+          b_ret_er = true
+          init_retval = " = E_OK"
+        end
+      end
+
+      file.print <<EOT
+/*
+ * name:    #{f_name}
+ * func_id: #{id} 
+ */
+EOT
+      file.print "static ER\n"
+      file.print "tOpaqueUnmarshaler_#{@signature.get_global_name}_#{f_name}(CELLCB *p_cellcb, int16_t *state_)\t\t\n"
+      file.print "{\n"
+      file.print "	ER      ercd_;\n"
+
+      # 引数を受取る変数の定義
+      params = f.get_declarator.get_type.get_paramlist.get_items
+           # FuncHead->  Decl->    FuncType->ParamList
+      params.each{ |par|
+        name = par.get_name
+        type = par.get_type.get_original_type
+
+        dir = par.get_direction
+        if( dir == :RECEIVE )then
+          # type は PtrType で、それを取り除いた型
+          type = type.get_type
+        end
+        if( dir == :SEND || dir == :RECEIVE )then
+          init = " = 0"
+        else
+          init = ""
+        end
+
+        if type.kind_of? ArrayType then
+          type = type.get_type
+          aster = "(*"
+          aster2 = ")"
+        else
+          aster = ""
+          aster2 = ""
+        end
+
+        type_str = type.get_type_str.gsub( /\bconst\b */, "" ) # "const" を外す
+        file.printf( "	%-12s %s%s%s%s%s;\n", type_str, aster, name, aster2, type.get_type_str_post, init )
+
+        if dir == :OUT && type.is_nullable? then
+          file.print( "	int8_t\tb_#{name}_null_;\n" )
+        end
+      }
+
+      if ! b_void then
+        file.printf( "	%-12s retval_%s%s;\n", f_type.get_type.get_type_str, f_type.get_type.get_type_str_post, init_retval )
+      end
+
+      # in 方向の入出力を入力
+      file.print "\n	/* 入力引数受取 */\n"
+      file.print "	SET_RPC_STATE( *state_, RPCSTATE_SERVER_RECV_BODY );\n"
+      b_get = true    # unmarshal では get
+      b_marshal  = false
+      print_params( params, file, 1, b_marshal, b_get, true, "cServerCall", f_name )
+      print_params( params, file, 1, b_marshal, b_get, false, "cServerCall", f_name )
+      print_out_nullable( params, file, 1, b_marshal );
+
+
+      # パケットの受信完了
+      file.print "	/* パケット終わりをチェック */\n"
+      file.print "	SET_RPC_STATE( *state_, RPCSTATE_SERVER_RECV_EOP );\n"
+      if ! f_type.is_oneway? then
+        b_continue = "true"
+      else
+        b_continue = "false"
+      end
+      file.print "	if( (ercd_=cTDR_receiveEOP(#{b_continue})) != E_OK )\n"
+      file.print "		goto error_reset;\n\n"
+
+      # out のメモリをアロケート
+      dir = :OUT; alloc_cp = "cPPAllocator_alloc"; alloc_cp_extra = nil; nest = 1
+      alloc_for_out_params( params, file, nest, dir, alloc_cp, alloc_cp_extra )
+
+      # 対象関数を呼出す
+      file.print "	/* 対象関数の呼出し */\n"
+      file.print "	SET_RPC_STATE( *state_, RPCSTATE_SERVER_EXEC );\n"
+      if b_void then
+        file.print( "	cServerCall_#{f_name}(" )
+      else
+        file.print( "	retval_ = cServerCall_#{f_name}(" )
+      end
+
+      delim = " "
+      params.each{ |par|
+        file.print delim
+        delim = ", "
+        if par.get_direction == :RECEIVE then
+          file.print "&"
+        end
+        file.print par.get_name
+      }
+      file.print( " );\n" )
+
+      # 戻り値、出力引数の受取コードの生成
+
+      # oneway の場合出力、戻り値が無く、受取を待たない（非同期な呼出し）
+      if ! f.is_oneway? then
+
+        file.print "\n	/* SOPの送出 */\n"
+        file.print "	SET_RPC_STATE( *state_, RPCSTATE_SERVER_SEND_SOP );\n"
+
+        file.print "	if( ( ercd_ = cTDR_sendSOP( false ) ) != E_OK )\n"
+        file.print "		goto error_reset;\n"
+
+        b_get = false     # unmarshaler は put
+        if( ! b_void )then
+          file.print "	/* 戻り値の送出 */\n"
+          print_param( "retval_", f_type.get_type, file, 1, :RETURN, nil, nil, b_marshal, b_get )
+        end
+
+        if f_type.has_outward? then
+          if b_ret_er then
+            indent_level = 2
+            file.print "	if( MERCD( retval_ ) != E_RPC ){\n"
+          else
+            indent_level = 1
+          end
+          indent = "	" * indent_level
+
+          file.print "#{indent}/* 出力値の送出 */\n"
+          file.print "#{indent}SET_RPC_STATE( *state_, RPCSTATE_SERVER_SEND_BODY );\n"
+          print_params( params, file, indent_level, b_marshal, b_get, true, "cServerCall", f_name )
+          print_params( params, file, indent_level, b_marshal, b_get, false, "cServerCall", f_name )
+
+          # receive のメモリをデアロケート
+          if f_type.has_receive? then
+            file.print "#{indent}/* dealloc receive parameter */\n"
+            dir = :RECEIVE; dealloc_cp = "cServerCall_#{f_name}"
+            dealloc_for_params( params, file, indent_level, dir, dealloc_cp )
+          end
+
+          if b_ret_er then
+            file.print "	}\n"
+          end
+        end
+
+        file.print "	/* パケットの終わり（掃きだし） */\n"
+        file.print "	SET_RPC_STATE( *state_, RPCSTATE_SERVER_SEND_EOP );\n"
+        file.print "	if( (ercd_=cTDR_sendEOP(false)) != E_OK )\n"  # b_continue = false
+        file.print "		goto error_reset;\n"
+      end  # ! f.is_oneway?
+
+      file.print "	return E_OK;\n"
+      file.print <<EOT
+
+error_reset:
+EOT
+      # send のリセット用デアロケート
+      if f_type.has_send? then
+        file.print "	/* dealloc send parameter */\n"
+        file.print "	if( *state_ < RPCSTATE_SERVER_EXEC ){\n"
+        dir = :SEND; indent_level = 2; dealloc_cp = "cServerCall_#{f_name}"
+        dealloc_for_params( params, file, indent_level, dir, dealloc_cp, true )
+        file.print "	}\n"
+      end
+
+      # receive のメモリをデアロケート
+      if f_type.has_receive? && b_ret_er then
+        file.print "	/* dealloc receive parameter */\n"
+        file.print "	if( MERCD( retval_ ) != E_RPC ){\n"
+        dir = :RECEIVE; indent_level = 2; dealloc_cp = "cServerCall_#{f_name}"
+        dealloc_for_params( params, file, indent_level, dir, dealloc_cp )
+        file.print "	}\n"
+      end
+
+      file.print "	return ERCD( E_RPC, MERCD( ercd_ ) );\n"
+      file.print "}\n\n"
+
+      # ここ（個々の関数）ではエラーハンドラーは呼び出さない。呼び元（サーバーのメイン関数）で呼び出す。
+    }
+  end
+ 
+
+  #b_marshal:: bool
+  #b_get:: bool
+  #  b_marshal = true  && b_get == false   :  マーシャラで入力引数送出
+  #  b_marshal = true  && b_get == true    :  マーシャラで出力引数受取
+  #  b_marshal = false && b_get == false   :  アンマーシャラで入力引数受取
+  #  b_marshal = false && b_get == true    :  アンマーシャラで出力引数送出
+  #b_referenced:: size_is, count_is, string で参照されているものを出力
+  def print_params( params, file, nest, b_marshal, b_get, b_referenced, port_name, func_name )
+    params.each{ |param|
+# p "#{param.get_name}:  b_marshal: #{b_marshal} b_get: #{b_get}"
+      if ! ( b_referenced == param.is_referenced? ) then
+        next
+      end
+
+      dir = param.get_direction
+      if( b_get == false && b_marshal == true || b_get == true && b_marshal == false  )then
+        case dir
+        when :IN, :INOUT
+          alloc_cp = "cPPAllocator_alloc"
+          alloc_cp_extra = nil
+          print_param( param.get_name, param.get_type, file, nest, dir, nil, nil, b_marshal, b_get, alloc_cp, alloc_cp_extra )
+        when :SEND
+          alloc_cp = "#{port_name}_#{func_name}_#{param.get_name}_alloc"
+          alloc_cp_extra = nil
+          print_param( param.get_name, param.get_type, file, nest, dir, nil, nil, b_marshal, b_get, alloc_cp, alloc_cp_extra )
+        end
+      else
+        case dir
+        when :OUT, :INOUT
+          alloc_cp = nil        # inout の b_get==true&&b_marsha==true のときアロケータコードは不用
+          alloc_cp_extra = nil
+          print_param( param.get_name, param.get_type, file, nest, dir, nil, nil, b_marshal, b_get, alloc_cp, alloc_cp_extra )
+        when :RECEIVE
+          alloc_cp = "#{port_name}_#{func_name}_#{param.get_name}_alloc"
+          alloc_cp_extra = nil
+          if b_get then
+            outer = "(*"         # マーシャラ側では、ポインタが (send と比べ) 一つ多い
+            outer2 = ")"
+          else
+            outer = nil          # アンマーシャラ側では、ポインタが一つ外されている
+            outer2 = nil
+          end
+          type = param.get_type.get_referto
+          print_param( param.get_name, type, file, nest, dir, outer, outer2, b_marshal, b_get, alloc_cp, alloc_cp_extra )
+        end
+      end
+    }
+  end
+
+  #=== アロケータコードを生成 (out のアンマーシャラ用)
+  def alloc_for_out_params( params, file, nest, dir, alloc_cp, alloc_cp_extra )
+    params.each{ |param|
+      dir = param.get_direction
+      if dir == :OUT then
+        alloc_for_out_param( param.get_name, param.get_type, file, nest, nil, nil, alloc_cp, alloc_cp_extra )
+      end
+    }
+  end
+
+  #=== アロケータコードを生成 (out のアンマーシャラ用個別パラメータの生成)
+  def alloc_for_out_param( name, type, file, nest, outer, outer2, alloc_cp, alloc_cp_extra )
+    org_type = type.get_original_type
+    if org_type.is_nullable? then
+      indent = "\t" * nest
+      file.print "#{indent}if( ! b_#{name}_null_  ){\n"
+      nest += 1
+    end
+    case org_type
+    when PtrType
+      indent = "\t" * nest
+      count = type.get_count; size = type.get_size; string = type.get_string
+      if count || size || string then
+        loop_counter_type = IntType.new(16)   # mikan 方を size_is, count_is の引数の型とする
+        if count then
+          len = type.get_count.to_s
+        elsif size then
+          len = type.get_size.to_s
+        elsif string then
+          if  type.get_string.instance_of? Expression then
+            len = type.get_string.to_s
+          else
+            raise "unsuscripted string used for out parameter #{name}"
+          end
+        end
+
+        # size_is に max 指定がある場合、length が max を超えているかチェックするコードを生成
+        if org_type.get_max != nil && string == nil then
+          file.print "#{indent}if( #{len} > #{type.get_max} ){\t/* GenOpaqueMarshaler max check 2 */\n"
+          file.print "#{indent}	ercd_ = E_PAR;\n"
+          file.print "#{indent}	goto error_reset;\n"
+          file.print "#{indent}}\n"
+        end
+
+        file.print <<EOT
+#{indent}if((ercd_=#{alloc_cp}(sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post})*#{len},(void **)&#{outer}#{name}#{outer2}#{alloc_cp_extra}))!=E_OK)\t/* GenOpaqueMarshaler 1 */
+#{indent}	goto error_reset;
+EOT
+
+        if type.get_type.kind_of? PtrType then
+          file.print "#{indent}{\n"
+          file.print "#{indent}	#{loop_counter_type.get_type_str}  i__#{nest}, length__#{nest} = #{len};\n"
+          file.print "#{indent}	for( i__#{nest} = 0; i__#{nest} < length__#{nest}; i__#{nest}++ ){\n"
+          alloc_for_out_param( name, type.get_type, file, nest + 2, outer, "#{outer2}[i__#{nest}]", alloc_cp, alloc_cp_extra )
+          file.print "#{indent}	}\n"
+          file.print "#{indent}}\n"
+        end
+
+      else
+        file.print <<EOT
+#{indent}if((ercd_=#{alloc_cp}(sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post}),(void **)&#{outer}#{name}#{outer2}#{alloc_cp_extra}))!=E_OK)\t/* GenOpaqueMarshaler 2 */
+#{indent}	goto error_reset;
+EOT
+      end
+    end
+    if org_type.is_nullable? then
+      nest -= 1
+      indent = "\t" * nest
+      file.print "#{indent}} else {\n"
+      file.print "#{indent}	#{name} = NULL;\n"
+      file.print "#{indent}}\n"
+      nest += 1
+    end
+  end
+
+  #=== 引数の一括デアロケートコードの生成
+  # send：マーシャラの最後、receive：アンマーシャラの最後で一括して引数をデアロケートする
+  def dealloc_for_params( params, file, nest, dir, dealloc_cp, b_reset = false )
+    if b_reset then
+      reset_str = "_reset"
+    else
+      reset_str = ""
+    end
+
+    params.each{ |param|
+      if dir == param.get_direction then
+        indent = "\t" * nest
+        type = param.get_type.get_original_type
+        aster = ""
+        if dir == :RECEIVE then
+          type = type.get_type.get_original_type   # ポインタを一つ外す
+          if b_reset then
+            aster = "*"
+          end
+        end
+        count = type.get_count; size = type.get_size
+        if (size || count) && type.get_type.has_pointer? then
+          if count then
+            len = ", #{type.get_count.to_s}"
+          elsif size then
+            len = ", #{type.get_size.to_s}"
+          end
+        else
+          len = ""
+        end
+        cp = "#{dealloc_cp}_#{param.get_name}_dealloc#{reset_str}".upcase
+        file.print "#{indent}#{cp}(#{aster}#{param.get_name}#{len});\n"
+      end
+    }
+  end
+
+  #== out で nullable な引数の情報を渡す
+  # out nullable の場合、in, send, receive のように、値を渡す直前ではなく、呼出し時に渡す
+  def  print_out_nullable( params, file, nest, b_marshal );
+    indent = "\t" * nest
+    params.each{ |param|
+      next if param.get_direction != :OUT
+      next if ! param.is_nullable?
+      if b_marshal then
+        file.print "#{indent}if( (ercd_=cTDR_putInt8( (int8_t)(#{param.get_name} == NULL) )) != E_OK )\n"
+        file.print "#{indent}\tgoto error_reset;\n"
+      else
+        # 呼び先は alloc_for_out_param で nullable の対応する
+        file.print "#{indent}if( (ercd_=cTDR_getInt8( &b_#{param.get_name}_null_)) != E_OK )\n"
+        file.print "#{indent}\tgoto error_reset;\n"
+      end
+    }
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenParamCopy.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenParamCopy.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenParamCopy.rb	(revision 398)
@@ -0,0 +1,364 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#= ParamCopy
+#
+# パラメータコピーするマーシャラ／アンマーシャラコードを生成するメソッド print_param を提供する．
+# RPCPlugin, OpaqueRPCPlugin に include される．
+# RPCPlugin (トランスペアレント) では、oneway 関数で in のポインタ引数の場合に限って print_param が用いられる．
+#
+module  GenParamCopy
+
+  #=== 引数の転送コードを生成
+
+  def print_param( name, type, file, nest, dir, outer, outer2, b_marshal, b_get, alloc_cp = nil, alloc_cp_extra = nil, name_list = nil )
+    if type.get_original_type.kind_of?( ArrayType ) && b_get && dir != :OUT then
+      indent = "	" * nest
+      subsc = type.get_subscript
+      if subsc == nil
+        raise "Unsubscripted Array Not Supported"
+      else        
+        size_str = subsc.to_str( name_list, outer, outer2 )
+        file.print <<EOT
+#{indent}if((ercd_=#{alloc_cp}(sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post})*(#{size_str}),(void **)&#{outer}#{name}#{outer2}#{alloc_cp_extra}))!=E_OK)\t/* GenParamCopy 1 */
+#{indent}	goto error_reset;
+EOT
+        if ( dir == :SEND || dir == :RECEIVE ) && type.get_type.has_pointer? then
+          # send, receive の場合は、エラーリセットに備え NULL にする
+          file.print <<EOT
+#{indent}memset( (void *)#{outer}#{name}#{outer2}#{alloc_cp_extra}, 0, sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post})*(#{size_str});   /* GenParamCopy Alloc1 */
+EOT
+        end
+      end
+    end
+    print_param0( name, type, file, nest, dir, outer, outer2, b_marshal, b_get, alloc_cp, alloc_cp_extra, name_list )
+  end
+
+  def print_param0( name, type, file, nest, dir, outer, outer2, b_marshal, b_get, alloc_cp = nil, alloc_cp_extra = nil, name_list = nil )
+    indent = "	" * nest
+
+    case type
+    when DefinedType
+      print_param0( name, type.get_type, file, nest, dir, outer, outer2, b_marshal, b_get, alloc_cp, alloc_cp_extra )
+    when BoolType, IntType, FloatType
+      case type
+      when BoolType
+        type_str = "Bool"
+      when IntType
+        bit_size = type.get_bit_size
+        case type.get_sign
+        when :UNSIGNED
+          sign = "U"
+        when :SIGNED
+          if bit_size == -1 || bit_size == -11 then
+            sign = "S"   # signed char の場合のみ S がつく
+          else
+            sign = ""
+          end
+        else
+          sign = ""
+        end
+
+        case bit_size
+        when -1, -11  # -1: char_t, -11: char
+          type_str = "#{sign}Char"
+        when -2
+          type_str = "#{sign}Short"
+        when -3
+          type_str = "#{sign}Int"
+        when -4
+          type_str = "#{sign}Long"
+        when -5
+          type_str = "Intptr"
+        when 8, 16, 32, 64, 128
+          type_str = "#{sign}Int#{bit_size}"
+        else
+          raise "unknown bit_size '#{bit_size}' for int type "
+        end
+
+      when FloatType
+        bit_size = type.get_bit_size
+        if bit_size == 32 then
+          type_str = "Float32"
+        else
+          type_str = "Double64"
+        end
+
+      end
+
+      if( b_get )then
+        file.print indent
+        file.print "if( ( ercd_ = cTDR_get#{type_str}( &(#{outer}#{name}#{outer2}) ) ) != E_OK )\t/* GenParamCopy 2 */\n"
+        file.print indent
+        file.print "	goto error_reset;\n"
+      else
+        file.print indent
+        file.print "if( ( ercd_ = cTDR_put#{type_str}( #{outer}#{name}#{outer2} ) ) != E_OK )\t/* GenParamCopy 3 */\n"
+        file.print indent
+        file.print "	goto error_reset;\n"
+      end
+
+    when PtrType
+
+      count = type.get_count; size = type.get_size; string = type.get_string
+      if count || size || string then
+        nest = print_nullable_pre( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
+        indent = "\t" * nest
+        loop_counter_type = IntType.new(32)   # mikan 型を size_is, count_is の引数の型とする
+        file.print "#{indent}{\t/* GenParamCopy 4 */\n"
+        file.print "#{indent}	#{loop_counter_type.get_type_str}  i__#{nest}, length__#{nest};\n"
+
+        if size || count then
+          if size then
+            size_str = size.to_str( name_list, outer, outer2 )
+          end
+
+          if count then
+            count_str = count.to_str( name_list, outer, outer2 )
+          else
+            # size_is は必須. count_is はオプション
+            count_str = size_str
+          end
+          file.print "#{indent}	length__#{nest} = #{count_str};\t/* GenParamCopy 5 */\n"
+
+          # size_is に max 指定がある場合、length が max を超えているかチェックするコードを生成
+              # alloc_cp == nil のとき dir は INOUT, OUT のはず (条件が冗長)。試験が終わっているので、次回見直し時に外す
+          if b_get && type.get_max != nil && ! ( ( dir == :INOUT || dir == :OUT ) && alloc_cp == nil ) then
+            file.print "#{indent}	if( length__#{nest} > #{type.get_max.to_s} ){\t/* GenParamCopy max check 1 */\n"
+            file.print "#{indent}		ercd_ = E_PAR;\n"
+            file.print "#{indent}		goto error_reset;\n"
+            file.print "#{indent}	}\n"
+          end
+
+        else # if string then
+          case type.get_type.get_bit_size
+          when -1              # char_t
+            b_size = 8
+          when 8, 16, 32, 64   # intN_t, uintN_t
+            b_size = type.get_type.get_bit_size
+          else
+            cdl_error( "R9999 $1: string specifier cannot be specified to '$2' in current implementation",
+                       name, type.get_type.get_type_str + type.get_type.get_type_str_post )
+          end
+          if ! b_get then
+            if  string.instance_of? Expression then
+              len = string.to_str( name_list, outer, outer2 )
+              file.print "#{indent}	length__#{nest} = STRNLEN#{b_size}(#{outer}#{name}#{outer2},(#{len}-1))+1;\t/* GenParamCopy 6 */\n"
+              file.print "#{indent}	if( length__#{nest} < #{len})\tlength__#{nest} += 1;\n"
+            else
+              file.print "#{indent}	length__#{nest} = STRLEN#{b_size}(#{outer}#{name}#{outer2})+1;\t/* GenParamCopy 7 */\n"
+            end
+            size_str = "length__#{nest}"     # string の場合、strnlen 以上の領域を確保しない
+          else
+            if ( dir == :INOUT ) then
+              if ( string.instance_of? Expression ) then
+                len = string.to_str( name_list, outer, outer2 )
+                size_str = "#{len}"              # string(len) の場合 len を確保する
+              else
+                raise "unsuscripted string used for inout parameter #{name}"
+              end
+            else
+              size_str = "length__#{nest}"     # string の場合、strnlen 以上の領域を確保しない
+            end
+          end
+          print_param0( "length__#{nest}", loop_counter_type, file, nest + 1, dir, nil, nil, b_marshal, b_get )
+        end
+
+        if b_get && ( dir == :IN || dir == :INOUT || dir == :SEND || dir == :RECEIVE ) && alloc_cp then
+          file.print <<EOT
+#{indent}	if((ercd_=#{alloc_cp}(sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post})*(#{size_str}),(void **)&#{outer}#{name}#{outer2}#{alloc_cp_extra}))!=E_OK)\t/* GenParamCopy 8 */
+#{indent}		goto error_reset;
+EOT
+          if ( dir == :SEND || dir == :RECEIVE ) && type.get_type.has_pointer? then
+            # send, receive の場合は、エラーリセットに備え NULL にする
+            file.print <<EOT
+#{indent}	memset( (void *)#{outer}#{name}#{outer2}#{alloc_cp_extra}, 0, sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post})*(#{size_str}) );   /* GenParamCopy Alloc2 */
+EOT
+          end
+        end
+        file.print "#{indent}	for( i__#{nest} = 0; i__#{nest} < length__#{nest}; i__#{nest}++ ){\t/* GenParamCopy 9 */\n"
+
+        print_param0( name, type.get_type, file, nest + 2, dir, outer, "#{outer2}[i__#{nest}]", b_marshal, b_get, alloc_cp, alloc_cp_extra )
+        file.print "#{indent}	}\n"
+        file.print "#{indent}}\n"
+
+        nest = print_nullable_post( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
+        indent = "\t" * nest
+      else
+
+        # nullable (pre)
+        nest = print_nullable_pre( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
+        indent = "	" * nest
+
+        # allocate memory for getting value
+        if b_get && ( dir == :IN || dir == :INOUT || dir == :SEND || dir == :RECEIVE ) && alloc_cp then
+          file.print <<EOT
+#{indent}if((ercd_=#{alloc_cp}(sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post}),(void **)&#{outer}#{name}#{outer2}#{alloc_cp_extra}))!=E_OK)\t/* GenParamCopy 10 */
+#{indent}	 goto error_reset;
+EOT
+          if ( dir == :SEND || dir == :RECEIVE ) && type.get_type.has_pointer? then
+            # send, receive の場合は、エラーリセットに備え NULL にする
+            file.print <<EOT
+#{indent}memset( (void *)#{outer}#{name}#{outer2}#{alloc_cp_extra}, 0, sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post}) );   /* GenParamCopy Alloc3 */
+EOT
+          end
+        end
+
+        print_param0( name, type.get_type, file, nest, dir, "(*#{outer}", "#{outer2})", b_marshal, b_get, alloc_cp, alloc_cp_extra )
+        # nullable (post)
+        nest = print_nullable_post( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
+        indent = "	" * nest
+      end
+    when StructType
+      members_decl =type.get_members_decl
+      members_decl.get_items.each { |m|
+        if m.is_referenced?
+          print_param0( m.get_name, m.get_type, file, nest, dir, "#{outer}#{name}#{outer2}.", nil, b_marshal, b_get, alloc_cp, alloc_cp_extra, members_decl )
+        end
+      }
+      members_decl.get_items.each { |m|
+        if ! m.is_referenced?
+          print_param0( m.get_name, m.get_type, file, nest, dir, "#{outer}#{name}#{outer2}.", nil, b_marshal, b_get, alloc_cp, alloc_cp_extra, members_decl )
+        end
+      }
+
+    when VoidType
+    when EnumType  # mikan EnumType
+    when FuncType  # mikan FuncType
+    when ArrayType # mikan ArrayType
+      subsc = type.get_subscript
+      if subsc == nil
+        raise "Unsubscripted Array Not Supported"
+      else        
+        size_str = subsc.to_str( name_list, outer, outer2 )
+
+        loop_counter_type = IntType.new(32)   # mikan 型を size_is, count_is の引数の型とする
+        file.print "#{indent}{\t/* GenParamCopy 11 */\n"
+        file.print "#{indent}	#{loop_counter_type.get_type_str}  i__#{nest}, length__#{nest} = #{size_str};\n"
+
+        file.print "#{indent}	for( i__#{nest} = 0; i__#{nest} < length__#{nest}; i__#{nest}++ ){\n"
+        print_param0( name, type.get_type, file, nest + 2, dir, outer, "#{outer2}[i__#{nest}]", b_marshal, b_get, alloc_cp, alloc_cp_extra )
+        file.print "#{indent}	}\n"
+        file.print "#{indent}}\n"
+      end
+    end
+  end
+
+  #=== nullable (pre)
+  def print_nullable_pre( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
+    if type.is_nullable? then
+      indent = "	" * nest
+      if dir == :OUT then  # OUT の場合 print_out_nullable で NULL かどうかの情報を渡す
+        # 'null or not' is sent in the function 'print_out_nullable'
+        if b_get then
+          file.print "#{indent}if( #{outer}#{name}#{outer2} ){\t/* GenParamCopy Null 10 */\n"
+        else
+          file.print "#{indent}if( ! b_#{name}_null_ ){\t/* GenParamCopy Null 11 */\n"
+        end
+        nest += 1
+      else # dir = :IN, :INOUT, :SEND, :RECEIVE
+        if b_get then
+          file.print "#{indent}{\n"
+          if ! ( dir == :INOUT && b_marshal == true ) then
+            file.print <<EOT
+#{indent}	int8_t  b_null_;
+#{indent}	if((ercd_=cTDR_getInt8( &b_null_ )) != E_OK )\t/* GenParamCopy Null 20 */
+#{indent}		 goto error_reset;
+#{indent}	if( ! b_null_ ){
+EOT
+          else # dir = :INOUT, b_marshal = true, b_get = true の場合、NULL かどうかの情報を渡さない
+            file.print <<EOT
+#{indent}	int8_t  b_null_ = (#{outer}#{name}#{outer2} == NULL);\t/* GenParamCopy Null 21 */
+#{indent}	if( ! b_null_ ){
+EOT
+          end
+        else
+          file.print <<EOT
+#{indent}{
+#{indent}	int8_t  b_null_ = (int8_t)(#{outer}#{name}#{outer2} == NULL);\t/* GenParamCopy Null 31 */
+EOT
+
+          if ! ( dir == :INOUT && b_marshal == false ) then
+            # dir = :INOUT, b_marshal = false, b_get = false の場合
+            file.print <<EOT
+#{indent}	if((ercd_=cTDR_putInt8( b_null_ )) != E_OK )\t/* GenParamCopy Null 32 */
+#{indent}		 goto error_reset;
+EOT
+          end
+
+          file.print <<EOT
+#{indent}	if( ! b_null_ ){\t/* GenParamCopy Null 33 */
+EOT
+        end
+        nest += 2
+      end
+    end
+    return nest
+  end
+
+  #== nullable (post)
+  def print_nullable_post( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
+    if type.is_nullable? then
+      if dir == :OUT then  # OUT の場合 print_out_nullable で NULL かどうかの情報を渡す
+        nest -= 1
+        indent = "	" * nest
+        file.print "#{indent}}  /* ! b_#{name}_null_   GenParamCopy Null 50 */\n"
+      else # ( dir == :IN || dir == :INOUT || dir == :SEND || dir == :RECEIVE )
+        nest -= 2
+        indent = "	" * nest
+        if b_get then
+          if ! ( dir == :INOUT && b_marshal == true ) then
+            file.print <<EOT
+
+#{indent}	} else { /* null  GenParamCopy Null 51 */
+#{indent}		#{outer}#{name}#{outer2} = NULL;
+#{indent}	}  /* ! b_null_ */
+EOT
+          else # dir = :INOUT, b_marshal = true   # inout の out 方向
+            file.print "#{indent}	}  /* ! b_null_  GenParamCopy Null 52 */\n"
+          end
+        else
+          file.print "#{indent}	}\t/* GenParamCopy Null 53 */\n"
+        end
+        file.print "#{indent}}\t/* GenParamCopy Null 54 */\n"
+      end
+    end
+    return nest
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenTransparentMarshaler.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenTransparentMarshaler.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenTransparentMarshaler.rb	(revision 398)
@@ -0,0 +1,692 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2014 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#プラグインオプション用変数
+#@task_priority:: Integer
+#@channelCelltype:: String
+#@channelCellName:: String
+#@PPAllocatorSize:: Integer
+module GenTransparentMarshaler
+
+  # プラグイン引数名と Proc
+  RPCPluginArgProc = {
+    "taskPriority"    => Proc.new { |obj,rhs| obj.set_taskPriority rhs },
+    "channelCelltype" => Proc.new { |obj,rhs| obj.set_channelCelltype rhs },
+    "TDRCelltype"     => Proc.new { |obj,rhs| obj.set_TDRCelltype rhs },
+    "channelCell"     => Proc.new { |obj,rhs| obj.set_channelCellName rhs },
+    "PPAllocatorSize" => Proc.new { |obj,rhs| obj.set_PPAllocatorSize rhs },
+  }
+
+  #=== プラグイン引数 taskPriority のチェック
+  def set_taskPriority( rhs )
+    @task_priority = rhs
+  end
+
+  #=== プラグイン引数 channelCelltype のチェック
+  def set_channelCelltype( rhs )
+    @channelCelltype = rhs.to_sym
+    # path = [ "::", @channelCelltype ]
+    # obj = Namespace.find( path )
+    nsp = NamespacePath.analyze( @channelCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: channeclCelltype '#{rhs}' not celltype or not found" )
+    end
+  end
+
+  #=== プラグイン引数 TDRCelltype のチェック
+  def set_TDRCelltype( rhs )
+    @TDRCelltype = rhs.to_sym
+    # path = [ "::", @TDRCelltype ]
+    # obj = Namespace.find( path )
+    nsp = NamespacePath.analyze( @TDRCelltype.to_s )
+    obj = Namespace.find( nsp )
+    if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
+      cdl_error( "RPCPlugin: TDRCelltype '#{rhs}' not celltype or not found" )
+    end
+  end
+
+  #=== プラグイン引数 channelCellName のチェック
+  def set_channelCellName( rhs )
+    @channelCellName = rhs
+    if @channelCellName =~ /\A[a-zA-Z_]\w*/ then
+      # OK
+    else
+      cdl_error( "RPCPlugin: channeclCellName '#{rhs}' unsuitable for identifier" )
+    end
+  end
+
+  #=== プラグイン引数 PPAllocatorSize のチェック
+  def set_PPAllocatorSize( rhs )
+    @PPAllocatorSize = rhs
+  end
+
+  #=== marshaler のセルタイプ名を設定する
+  def initialize_transparent_marshaler cell_name
+    @task_priority = 8
+    @channelCelltype = "tDataqueueOWChannel"
+    @TDRCelltype     = "tTDR"
+    @channelCellName = "#{cell_name}_Channel"
+    @PPAllocatorSize = nil
+
+    @marshaler_celltype_name = "tMarshaler_#{@signature.get_global_name}"
+    @unmarshaler_celltype_name = "tUnmarshaler_#{@signature.get_global_name}"
+    @marshaler_celltype_file_name = "#{$gen}/#{@marshaler_celltype_name}.cdl"
+  end
+
+  def gen_marshaler_celltype 
+
+    if @PPAllocatorSize then
+      alloc_call_port = "  call sPPAllocator cPPAllocator;\n"
+    else
+      alloc_call_port = ""
+    end
+
+    f = CFile.open( @marshaler_celltype_file_name, "w" )
+    # 同じ内容を二度書く可能性あり (AppFile は不可)
+
+    f.print <<EOT
+
+celltype #{@marshaler_celltype_name} {
+  entry #{@signature.get_namespace_path} eClientEntry;
+  call sTDR        cTDR;
+  call sEventflag  cEventflag;
+  [optional]
+    call sSemaphore cLockChannel;  // this port is eliminated by optimize
+};
+celltype #{@unmarshaler_celltype_name} {
+  call #{@signature.get_namespace_path} cServerCall;
+  call sTDR        cTDR;
+  call sEventflag  cEventflag;
+  entry sUnmarshalerMain  eUnmarshalAndCallFunction;
+#{alloc_call_port}};
+EOT
+    f.close
+  end
+
+  #===  受け口関数の本体コードを生成（頭部と末尾は別途出力）
+  #ct_name:: Symbol    (through プラグインで生成された) セルタイプ名 ．Symbol として送られてくる（らしい）
+  def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    # unmarshaler クラスか?
+    if ct_name == @unmarshaler_celltype_name.to_sym then
+      gen_ep_func_body_unmarshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    else
+      gen_ep_func_body_marshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+    end
+  end
+
+  #===  marshal コードの生成
+  def gen_ep_func_body_marshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+    b_void = false
+    b_ret_er = false
+
+    # 関数の戻り値の元の型を得る(typedef されている場合)
+    type = func_type.get_type.get_original_type
+
+    # 戻り値記憶用の変数を出力（void 型の関数では出力しない）
+    if ! type.is_void? then
+      if func_type.get_type.kind_of?( DefinedType ) && ( func_type.get_type.get_type_str == "ER" || func_type.get_type.get_type_str == "ER_INT" ) then
+        file.print( "    #{func_type.get_type.get_type_str}  retval_ = E_OK;\n" )
+        b_ret_er = true
+      else
+        file.print( "    #{func_type.get_type.get_type_str}  retval_;\n" )
+      end
+    else
+      b_void = true
+    end
+
+    file.print( "    ER      ercd_;\n" )
+    file.print( "    FLGPTN  flgptn;\n" )
+
+    # 呼び先の signature を取り出す
+    signature = @signature
+
+    # 関数 ID （整数値）
+    func_id = signature.get_id_from_func_name( func_name )
+    file.print( "    int16_t  func_id_ = #{func_id};    /* id of #{func_name}: #{func_id} */\n" )
+
+    # シングルトンでないか？
+    if ! b_singleton then
+
+      # singleton でなければ p_cellcb 取得コードを出力
+      file.print <<EOT
+    #{ct_name}_CB *p_cellcb;
+
+    if( VALID_IDX( idx ) ){
+        p_cellcb = GET_CELLCB(idx);
+EOT
+
+      # エラーを返すか？
+      if b_ret_er then
+        file.print <<EOT
+    }else{
+         return ERCD( E_RPC, E_ID );
+    }
+EOT
+      else
+        file.print <<EOT
+    }else{
+        /* エラー処理コードをここに記述 */
+    }
+EOT
+      end
+    end
+
+    # channel lock コード
+    file.print <<EOT
+    /* Channel Lock */
+    if( is_cLockChannel_joined() )
+      cLockChannel_wait();
+
+EOT
+
+    # SOP を送信
+    file.print "    /* SOPの送出 */\n"
+    file.print "    if( ( ercd_ = cTDR_sendSOP( true ) ) != E_OK )\n"
+    file.print "      goto error_reset;\n"
+
+    # func_id を送信
+    file.print "    /* 関数 id の送出 */\n"
+    file.print "    if( ( ercd_ = cTDR_putInt16( func_id_ ) ) != E_OK )\n"
+    file.print "        goto error_reset;\n"
+
+    # p "celltype_name, sig_name, func_name, func_global_name"
+    # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
+
+    b_get = false    # marshal なら put
+    b_marshal = true  # marshal
+
+    # in 方向の入出力を出力
+    file.print "    /* 入力引数送出 */\n"
+    print_params( params, file, 1, b_marshal, b_get, true, func_type.is_oneway? )
+    print_params( params, file, 1, b_marshal, b_get, false, func_type.is_oneway? )
+    if ! b_void && ! func_type.is_oneway? then
+      ret_ptr_type = PtrType.new( func_type.get_type )
+      print_param_nc( "retval_", ret_ptr_type, file, 1, :RETURN, "&", nil, b_get )
+    end
+
+    file.print "    /* EOPの送出（パケットの掃きだし） */\n"
+    if ! func_type.is_oneway? then
+      b_continue = "true"
+    else
+      b_continue = "false"
+    end
+    file.print "    if( (ercd_=cTDR_sendEOP(#{b_continue})) != E_OK )\n"
+    file.print "        goto error_reset;\n\n"
+
+    if ! func_type.is_oneway? then
+      file.print <<EOT
+    if( (ercd_=cEventflag_wait( 0x01, TWF_ANDW, &flgptn )) != E_OK ){
+      ercd_ = ERCD(E_RPC,ercd_);
+      goto error_reset;
+    }
+    if( (ercd_=cEventflag_clear( 0x00 ) ) != E_OK ){
+      ercd_ = ERCD(E_RPC,ercd_);
+      goto error_reset;
+    }
+EOT
+    end # ! func_type.is_oneway?
+
+    file.print <<EOT
+    /* Channel Lock */
+    if( is_cLockChannel_joined() )
+      cLockChannel_signal();
+EOT
+
+    if( b_void == false )then
+      # 呼び元に戻り値をリターン
+      file.print( "    return retval_;\n" )
+    else
+      file.print( "    return;\n" )
+    end
+
+    file.print <<EOT
+
+error_reset:
+    if( ercd_ != ERCD( E_RPC, E_RESET ) )
+        (void)cTDR_reset();
+EOT
+
+    # channel lock コード
+    file.print <<EOT
+    /* Channel Lock */
+    if( is_cLockChannel_joined() )
+      cLockChannel_signal();
+
+EOT
+
+    if( b_ret_er != false )then
+      # 呼び元に戻り値をリターン
+      file.print( "    return ercd_;\n" )
+    else
+      file.print( "    return;\n" )
+    end
+
+  end
+
+  #===  unmarshal コードの生成
+  def gen_ep_func_body_unmarshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
+
+#    b_ret_er = true
+    b_ret_er = false
+
+    # func_id を得るコードを生成
+    file.print <<EOT
+
+    int16_t   func_id_;
+    ER        ercd_;
+
+    #{ct_name}_CB *p_cellcb;
+
+    if( VALID_IDX( idx ) ){
+        p_cellcb = GET_CELLCB(idx);
+EOT
+
+    if b_ret_er then
+        file.print <<EOT
+    }else{
+        return ERCD( E_RPC, E_ID );
+    }
+EOT
+    else
+        file.print <<EOT
+    }else{
+        /* エラー処理コードをここに記述 */
+    }
+EOT
+    end
+
+    file.print <<EOT
+
+    /* SOPのチェック */
+    if( (ercd_=cTDR_receiveSOP( false )) != E_OK )
+        goto error_reset;
+    /* func_id の取得 */
+    if( (ercd_=cTDR_getInt16( &func_id_ )) != E_OK )
+        goto error_reset;
+
+#ifdef RPC_DEBUG
+    syslog(LOG_INFO, "unmarshaler task: func_id: %d", func_id_ );
+#endif
+    switch( func_id_ ){
+EOT
+
+    # 呼び先の signature を取り出す
+    # port = @celltype.find( @next_cell_port_name )
+    # signature = port.get_signature
+    signature = @signature
+
+    # through の signature に含まれる すべての関数について
+    signature.get_function_head_array.each { |f|
+      f_name = f.get_name
+      f_type = f.get_declarator.get_type
+      id = signature.get_id_from_func_name( f_name )
+
+      # 関数は返り値を持つか?
+      if f_type.get_type.is_void? then
+        b_void = true
+      else
+        b_void = false
+      end
+
+      # パケットの終わりをチェック（未受け取りのデータが残っていないかチェック）
+      file.print "    case #{id}:       /*** #{f_name} ***/ \n"
+      file.print "        if( tTransparentUnmarshaler_#{@signature.get_global_name}_#{f_name}() != E_OK )\n"
+      file.print "            goto error_reset;\n"
+      file.print "        break;\n"
+
+    } # 
+
+    if @PPAllocatorSize then
+      ppallocator_dealloc_str = "    /* PPAllocator のすべてを解放 */\n    cPPAllocator_dealloc_all();"
+    else
+      ppallocator_dealloc_str = ""
+    end
+
+
+    file.print <<EOT
+    default:
+        syslog(LOG_INFO, "unmarshaler task: ERROR: unknown func_id: %d", func_id_ );
+    };
+#{ppallocator_dealloc_str}
+    return E_OK;
+
+error_reset:
+    if( ercd_ != ERCD( E_RPC, E_RESET ) )
+        (void)cTDR_reset();
+#{ppallocator_dealloc_str}
+    return E_OK;
+EOT
+
+  end
+
+  # IN b_marshal, b_get
+  #  b_marshal = true  && b_get == false   :  マーシャラで入力引数送出
+  #  b_marshal = true  && b_get == true    :  マーシャラで出力引数受取
+  #  b_marshal = false && b_get == true    :  アンマーシャラで入力引数受取
+  #  b_marshal = false && b_get == get     :  アンマーシャラで出力引数送出
+  def print_params( params, file, nest, b_marshal, b_get, b_referenced, b_oneway = false )
+    params.each{ |param|
+# p "#{param.get_name}:  b_marshal: #{b_marshal} b_get: #{b_get}"
+      if ! ( b_referenced == param.is_referenced? ) then
+        next
+      end
+
+      dir = param.get_direction
+      type = param.get_type
+      if b_oneway && dir == :IN && type.get_original_type.kind_of?( PtrType ) || type.get_original_type.kind_of?( ArrayType ) then
+        # oneway, in, PtrType の場合コピー
+        alloc_cp = "cPPAllocator_alloc"
+        alloc_cp_extra = nil
+        print_param( param.get_name, type, file, nest, dir, nil, nil, b_marshal, b_get, alloc_cp, alloc_cp_extra )
+      else
+        if( b_get == false && b_marshal == true || b_get == true && b_marshal == false  )then
+          case dir
+#          when :IN, :INOUT, :SEND
+          when :IN, :INOUT, :OUT, :SEND, :RECEIVE
+            print_param_nc( param.get_name, type, file, nest, b_marshal, nil, nil, b_get )
+          end
+        else
+#         case dir
+#         when :OUT, :INOUT, :RECEIVE
+#         when :RECEIVE
+#           print_param_nc( param.get_name, type, file, nest, b_marshal, nil, nil, b_get )
+#         end
+        end
+      end
+    }
+  end
+
+  #=== コピーしない引数渡しコードの出力
+  def print_param_nc( name, type, file, nest, b_marshal, outer, outer2, b_get )
+    indent = "    " * ( nest + 1 )
+
+    case type
+    when DefinedType
+      print_param_nc( name, type.get_type, file, nest, b_marshal, outer, outer2, b_get )
+    when BoolType, IntType, FloatType, PtrType, ArrayType
+      case type
+      when BoolType
+        type_str = "Int8"
+        cast_str = "int8_t"
+      when IntType
+        bit_size = type.get_bit_size
+        case type.get_sign
+        when :UNSIGNED
+          signC = "U"
+          sign  = "u"
+        when :SIGNED
+          if bit_size == -1 || bit_size == -11 then
+            # signed char の場合、signed を指定する
+            signC = "S"
+            sign  = "s"
+          else
+            signC = ""
+            sign  = ""
+          end
+        else
+          signC = ""
+          sign  = ""
+        end
+
+        # p "pn:: #{name} #{bit_size} #{type.get_type_str}"
+        case bit_size
+        when  -1, -11  # -1: char_t, -11: char
+          type_str = "#{signC}Char"
+          cast_str = "#{sign}char_t"
+        when -2
+          type_str = "#{signC}Short"
+          cast_str = "#{sign}short_t"
+        when -3
+          type_str = "#{signC}Int"
+          cast_str = "#{sign}int_t"
+        when -4
+          type_str = "#{signC}Long"
+          cast_str = "#{sign}long_t"
+        when -5
+          type_str = "Intptr"
+          cast_str = "intptr_t"
+        when 8, 16, 32, 64, 128
+          type_str = "#{signC}Int#{bit_size}"
+          cast_str = "#{sign}int#{bit_size}_t"
+        else
+          raise "unknown bit_size '#{bit_size}' for int type "
+        end
+
+      when FloatType
+        bit_size = type.get_bit_size
+        if bit_size == 32 then
+          type_str = "Float32"
+          cast_str = "float32_t"
+        else
+          type_str = "Double64"
+          cast_str = "double64_t"
+        end
+
+      when PtrType
+        type_str = "Intptr"
+        cast_str = "intptr_t"
+      when ArrayType
+        type_str = "Intptr"
+        cast_str = "intptr_t"
+      end
+
+      if type.get_type_str == cast_str then
+        cast_str = ""
+      else
+        cast_str = "(" + cast_str + ")"
+      end
+
+      if( b_get )then
+        cast_str.gsub!( /\)$/, "*)" )
+        file.print "    " * nest
+        file.print "if( ( ercd_ = cTDR_get#{type_str}( #{cast_str}&(#{outer}#{name}#{outer2}) ) ) != E_OK )\n"
+        file.print "    " * nest
+        file.print "    goto error_reset;\n"
+      else
+        file.print "    " * nest
+        file.print "if( ( ercd_ = cTDR_put#{type_str}( #{cast_str}#{outer}#{name}#{outer2} ) ) != E_OK )\n"
+        file.print "    " * nest
+        file.print "    goto error_reset;\n"
+      end
+
+    when StructType
+      members_decl =type.get_members_decl
+      members_decl.get_items.each { |m|
+        if m.is_referenced? then
+          print_param_nc( m.get_name, m.get_type, file, nest, b_marshal, "#{outer}#{name}#{outer2}.", nil, b_get )
+        end
+      }
+      members_decl.get_items.each { |m|
+        if ! m.is_referenced? then
+          print_param_nc( m.get_name, m.get_type, file, nest, b_marshal, "#{outer}#{name}#{outer2}.", nil, b_get )
+        end
+      }
+
+    when VoidType
+    when EnumType  # mikan EnumType
+    when FuncType  # mikan FuncType
+    end
+  end
+
+
+  #=== PREAMBLE 部のコード生成
+  # アンマーシャラセルタイプの場合、アンマーシャラ関数のプロトタイプ宣言を生成
+  def gen_preamble file, b_singleton, ct_name, global_name
+    if ct_name != @unmarshaler_celltype_name.to_sym then
+      return
+    end
+
+    file.print "/* アンマーシャラ関数のプロトタイプ宣言 */\n"
+    # signature に含まれる すべての関数について
+    @signature.get_function_head_array.each { |f|
+      f_name = f.get_name
+      f_type = f.get_declarator.get_type
+      id = @signature.get_id_from_func_name( f_name )
+      file.print "static ER  tTransparentUnmarshaler_#{@signature.get_global_name}_#{f_name}();\t/* func_id: #{id} */\n"
+    }
+    file.print "\n"
+  end
+
+  #=== POSTAMBLE 部のコード生成
+  # アンマーシャラセルタイプの場合、アンマーシャラ関数の生成
+  def gen_postamble file, b_singleton, ct_name, global_name
+    if ct_name != @unmarshaler_celltype_name.to_sym then
+      return
+    end
+
+    file.print "\n/*** アンマーシャラ関数 ***/\n\n"
+    @signature.get_function_head_array.each { |f|
+      f_name = f.get_name
+      f_type = f.get_declarator.get_type
+      id = @signature.get_id_from_func_name( f_name )
+
+      # 関数は返り値を持つか?
+      if f_type.get_type.is_void? then
+        b_void = true
+      else
+        b_void = false
+      end
+
+      file.print <<EOT
+/*
+ * name:    #{f_name}
+ * func_id: #{id} 
+ */
+EOT
+      file.print "static ER\n"
+      file.print "tTransparentUnmarshaler_#{@signature.get_global_name}_#{f_name}()\n"
+      file.print "{\n"
+      file.print "	ER  ercd_;\n"
+      file.print "	CELLCB  *p_cellcb;\n"
+
+      # 引数を受取る変数の定義
+      param_list = f.get_declarator.get_type.get_paramlist.get_items
+           # FuncHead->  Decl->    FuncType->ParamList
+      param_list.each{ |par|
+        name = par.get_name
+        type = par.get_type
+        if type.kind_of? ArrayType then
+          type = type.get_type
+          aster = "(*"
+          aster2 = ")"
+        else
+          aster = ""
+          aster2 = ""
+        end
+
+        type_str = type.get_type_str.gsub( /\bconst\b */, "" ) # "const" を外す
+
+        file.printf( "    %-12s %s%s%s%s;\n", type_str, aster, name, aster2, type.get_type_str_post )
+      }
+
+      # 戻り値を受け取る変数の定義
+      if ! b_void then
+        if f.is_oneway? then
+          retval_ptr = ""   # oneway の場合、受け取るが捨てられる
+        else
+          retval_ptr = "*"
+        end
+        file.printf( "    %-12s #{retval_ptr}retval_%s;\n", f_type.get_type.get_type_str, f_type.get_type.get_type_str_post )
+      end
+
+      # in 方向の入出力を入力
+      file.print "\n        /* 入力引数受取 */\n"
+      b_get = true    # unmarshal では get
+      b_marshal  = false
+      print_params( param_list, file, 1, b_marshal, b_get, true, f.is_oneway? )
+      print_params( param_list, file, 1, b_marshal, b_get, false, f.is_oneway? )
+      if ! b_void && ! f.is_oneway? then
+        ret_ptr_type = PtrType.new( f_type.get_type )
+        print_param_nc( "retval_", ret_ptr_type, file, 2, :RETURN, nil, nil, b_get )
+      end
+
+      # パケットの受信完了
+      # mikan 本当は、対象関数を呼出す後に実施したい．呼出しパケットの使用終わりを宣言する目的として
+      file.print "        /* パケット終わりをチェック */\n"
+      if ! f.is_oneway? then
+        b_continue = "true"
+      else
+        b_continue = "false"
+      end
+      file.print "    if( (ercd_=cTDR_receiveEOP(#{b_continue})) != E_OK )\n"
+      file.print "        goto error_reset;\n\n"
+
+      # 対象関数を呼出す
+      file.print "    /* 対象関数の呼出し */\n"
+      if b_void then
+        file.print( "    cServerCall_#{f_name}(" )
+      else
+        file.print( "    #{retval_ptr}retval_ = cServerCall_#{f_name}(" )
+      end
+
+      delim = " "
+      param_list.each{ |par|
+        file.print delim
+        delim = ", "
+        file.print "#{par.get_name}"
+      }
+      file.print( " );\n" )
+
+      # 戻り値、出力引数の受取コードの生成
+
+      # oneway の場合出力、戻り値が無く、受取を待たない（非同期な呼出し）
+      if ! f.is_oneway? then
+        file.print <<EOT
+    /* 関数処理の終了を通知 */
+    if( ( ercd_ = cEventflag_set( 0x01 ) ) != E_OK ){
+      goto error_reset;
+    }
+EOT
+      end  # ! f.is_oneway?
+      file.print <<EOT
+    return E_OK;
+error_reset:
+    return ercd_;
+}
+
+EOT
+
+    }
+
+  end
+
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/MrubyBridgeCelltypePluginModule.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/MrubyBridgeCelltypePluginModule.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/MrubyBridgeCelltypePluginModule.rb	(revision 398)
@@ -0,0 +1,284 @@
+# -*- coding: utf-8 -*-
+#
+#  TECS Generator
+#      Generator for TOPPERS Embedded Component System
+#  
+#   Copyright (C) 2008-2011 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#== celltype プラグインの共通の親クラス
+module MrubyBridgeCelltypePluginModule
+
+  # プラグイン引数名 => Proc
+  MrubyBridgePluginArgProc = { 
+      "ignoreUnsigned" => Proc.new { |obj,rhs| obj.set_ignoreUnsigned rhs },
+      "include_inner_cell" => Proc.new { |obj,rhs| obj.set_include_inner_cell rhs },
+      "exclude_cell" => Proc.new { |obj,rhs| obj.set_exclude_cell rhs },
+      "exclude_port" => Proc.new { |obj,rhs| obj.set_exclude_port rhs },
+      "exclude_port_func" => Proc.new { |obj,rhs| obj.set_exclude_port_func rhs },
+      "auto_exclude" => Proc.new { |obj,rhs| obj.set_auto_exclude rhs },
+  }
+
+  require_tecsgen_lib( "MrubyBridgeCellPlugin.rb" )
+  @@plugin_list = []
+  @@count = 1
+
+  #celltype::     Celltype        セルタイプ（インスタンス）
+  def initialize( celltype, option )
+    dbgPrint "#{self.class.name}: initialzie: #{celltype.get_name}\n"
+
+    super
+    @celltype = celltype
+    @cell_list = []
+    @include_inner_cell = false
+    @exclude_cells = []
+    @exclude_port = []
+    @exclude_port_func = {}
+    @b_ignoreUnsigned = false
+    @b_auto_exclude = true     # auto_exclude = true by default 
+    @@plugin_list << self
+
+    @plugin_arg_check_proc_tab = MrubyBridgePluginArgProc
+    @plugin_arg_str = CDLString.remove_dquote option
+    parse_plugin_arg
+
+    MrubyBridgeCellPlugin.set_gen_post_code_by_dependent
+  end
+
+  #=== 新しいセル
+  #cell::        Cell            セル
+  #
+  # celltype プラグインを指定されたセルタイプのセルが生成された
+  # セルタイププラグインに対する新しいセルの報告
+  # generate 文により呼び出された場合、それまでに定義された cell については、initialize のタイミングで呼び出される
+  def new_cell( cell )
+    dbgPrint "MrubyBridgeCelltypePluginModule: new_cell: #{cell.get_name}\n"
+
+    return if @cell_list.include? cell   # この行は、本来不要のはず
+    if TECSGEN.post_coded?               # post_code 以降のセルは対象から外す
+      cdl_info( "I9999 MrubyBridgeCelltypePlugin: $1 is excluded because cell generated after post_coded", cell.get_name )
+      return
+    end
+
+    # include_inner_cell option
+    if cell.is_cloned? && @include_inner_cell == false then
+    #   p "#{cell.get_name} excluded"
+      cdl_info( "I9999 MrubyBridgeCelltypePlugin: inner cell $1 is excluded", cell.get_name )
+      return
+    # else
+    #   p "#{cell.get_name} included"
+    end
+
+    # exclude_cell option
+    if @exclude_cells.include?( cell.get_name ) then
+      return
+    end
+
+    opt_str = "ignoreUnsigned=#{@b_ignoreUnsigned}, auto_exclude=#{@b_auto_exclude}"
+    @exclude_port.each{ |port|
+      opt_str += ",exclude_port=#{port}"
+    }
+    @exclude_port_func.each{ |port, funcs|
+      funcs.each{ |func|
+        opt_str += ",exclude_port_func=#{port}.#{func}"
+      }
+    }
+
+    # p "MrubyBridgeCelltypePlugin: opt_str=#{opt_str}"
+
+    fn2 = "#{$gen}/tmp_MrubyBridgeCelltypePluginModule_#{@celltype.get_name}_#{@@count}.cdl"
+    f2 = File.open( fn2, "w" )
+    f2.print <<EOT
+/* MrubyBridgeCelltypePluginModule: celltype=#{@celltype.get_name} */
+generate( MrubyBridgeCellPlugin, #{cell.get_namespace_path}, "#{opt_str}" );
+EOT
+    f2.close
+    dbgPrint "MrubyBridgeCelltypePluginModule new_cell: Import #{fn2}\n"
+    Import.new "#{fn2}"
+    @@count += 1
+  end
+
+### 意味解析段階で呼び出されるメソッド ###
+  #===  CDL ファイルの生成
+  #      typedef, signature, celltype, cell のコードを生成
+  #      重複して生成してはならない
+  #      すでに生成されている場合は出力しないこと。
+  #      もしくは同名の import により、重複を避けること。
+  #file::        FILE       生成するファイル
+  def gen_cdl_file file
+#   この段階で呼びだすと generate 文が呼び出される前のセルのみの出力となる
+    
+#    dbgPrint "MrubyBridgeCelltypePlugin: gen_cdl_file: #{@celltype.get_name}\n"
+#    file.print <<EOT
+#/* MrubyBridgeCelltypePlugin: celltype=#{@celltype.get_name}
+# *
+# *    cell's generate before celltype's generate
+# */
+#
+#EOT
+#    @celltype.get_cell_list.each { |cell|
+#      @cell_list << cell
+#      # mikan option, region
+#      dbgPrint "MrubyBridgeCelltypePlugin: cell=#{cell.get_name}\n"
+#      file.print <<EOT
+#generate( MrubyBridgeCellPlugin, #{cell.get_namespace_path}, "" );
+#EOT
+#    }
+
+  end
+
+  #=== tCelltype_factory.h に挿入するコードを生成する
+  # file 以外の他のファイルにファクトリコードを生成してもよい
+  # セルタイププラグインが指定されたセルタイプのみ呼び出される
+  def gen_factory file
+  end
+
+  def get_celltype
+    @celltype
+  end
+
+  @@b_gen_post_code_called = false
+  #=== 後ろの CDL コードを生成
+  #プラグインの後ろの CDL コードを生成
+  #file:: File: 
+  def self.gen_post_code( file )
+    dbgPrint "#{self.name}: gen_post_code_body\n"
+
+    if @@b_gen_post_code_called == false then
+      @@b_gen_post_code_called = true
+      MrubyBridgeCellPlugin.gen_post_code_body file
+    end
+
+#    この段階で生成すると、同じポストコードで出力される mruby の初期化コードに反映されない
+    
+#    # MrubyBridgeCelltypePlugin の生成する generate 文は、
+#    fn2 = "#{$gen}/tmp_MrubyBridgeCelltypePlugin_post.cdl"
+#    f2 = File.open( fn2, "w" )
+#    # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
+#    dbgPrint "MrubyBridgeCelltypePlugin: gen_post_code\n"
+#    f2.print "/* '#{self.name}' post code */\n"
+#    @@plugin_list.each{ |plugin|
+#      plugin.get_celltype.get_cell_list.each{ |cell|
+#        # mikan option, region
+#        f2.print <<EOT
+#generate( MrubyBridgeCellPlugin, #{cell.get_namespace_path}, "" );
+#EOT
+#      }
+#    }
+#    f2.close
+#    p Import
+#    Import.new "#{fn2}"
+  end
+
+  #=== プラグイン引数 
+
+  #=== プラグイン引数 ignoreUnsigned
+  def set_ignoreUnsigned rhs
+    if rhs == "true" || rhs == nil then
+      @b_ignoreUnsigned = true
+    end
+  end
+
+  def set_include_inner_cell rhs
+    if rhs == "true" || rhs == nil then
+      @include_inner_cell = true
+    end
+  end
+
+  def set_exclude_cell rhs
+    cells = rhs.split ','
+    cells.each{ |rhs_cell|
+      rhs_cell.gsub!( /\s/, "" )
+      @exclude_cells << rhs_cell.to_sym
+    }
+  end
+  def set_exclude_port rhs
+    ports = rhs.split ','
+    ct = @cell.get_celltype
+    return if ct == nil    # error case
+    ports.each{ |rhs_port|
+      obj = ct.find( rhs_port.to_sym )
+      if( ( ! obj.instance_of? Port ) || obj.get_port_type != :ENTRY ) then
+        cdl_error( "MRB9999 exclude_port '$1' not found or not entry in celltype '$2'", rhs_port, ct.get_name )
+      else
+        # print "MRBBridgeCellPlugin: exclude #{rhs_port}\n"
+        @exclude_port << rhs_port
+      end
+    }
+  end
+
+  #=== プラグイン引数 exclude_port_func
+  def set_exclude_port_func rhs
+    port_funcs = rhs.split ','
+    ct = @celltype
+    return if ct == nil    # error case
+    port_funcs.each{ |rhs_port_func|
+      port_func = rhs_port_func.split( '.' )
+      if port_func.length != 2 then
+        cdl_error( "MRB9999 exclude_port_func: '$1' not in 'port.func' form", rhs_port_func )
+      end
+      obj = ct.find( port_func[0].to_sym )
+      if( ( ! obj.instance_of? Port ) || obj.get_port_type != :ENTRY ) then
+        cdl_error( "MRB9999 exclude_port_func: port '$1' not found in celltype '$2'", rhs_port_func, ct.get_name )
+      else
+        signature = obj.get_signature
+        next if signature == nil     # error case
+        if signature.get_function_head port_func[1].to_sym
+          # print "MRBBridgeCellPlugin: #{port_func[0]}.#{port_func[1]} exclude\n"
+          if @exclude_port_func[ port_func[0] ] then
+            @exclude_port_func[ port_func[0] ] <<  port_func[1]
+          else
+            @exclude_port_func[ port_func[0] ] = [ port_func[1] ]
+          end
+        else
+          cdl_error( "MRB9999 include_port_func: func '$1' not found in port '$2' celltype $3",
+                     port_func[1], port_func[0], ct.get_name )
+        end
+      end
+    }
+  end
+
+  #=== プラグイン引数 auto_exclude
+  def set_auto_exclude rhs
+    # print "MrubyBridgeCellPlugin: auto_exclude=#{rhs}\n"
+    if rhs == "false" then
+      @b_auto_exclude = false
+    elsif rhs == "true" then
+      @b_auto_exclude = true     # auto_exclude = true by default 
+    else
+      cdl_warning( "MRB9999 auto_exclude: unknown rhs value ignored. specify true or false" )
+    end
+  end
+end
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/version.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/version.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecslib/version.rb	(revision 398)
@@ -0,0 +1,2 @@
+$package = "tecsgen"
+$version = "1.6.4"
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsmerge
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsmerge	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsmerge	(revision 398)
@@ -0,0 +1,6 @@
+#! /bin/sh
+
+# $Id$
+
+tecsmerge.rb $*
+
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsmerge.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsmerge.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tecsgen/tecsmerge.rb	(revision 398)
@@ -0,0 +1,760 @@
+#! /usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+#
+#  TECS merger
+#      Merger for TECS generated templates
+#  
+#   Copyright (C) 2008-2017 by TOPPERS Project
+#--
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   $Id$
+#++
+
+#= tecsgen  : TECS のマージャ
+#
+#Authors::   大山 博司
+#Version::   
+#Copyright:: Copyright (C) TOPPERS Project, 2008-2017. All rights reserved.
+#License::   TOPPERS ライセンスに準拠
+
+=begin
+tecsmerge はテンプレートファイルを元に作成されたセルタイプコード（含インライン関数を記述したセルタイプインラインヘッダ）を保守するものである。
+セルタイプに以下の改変が加えられた場合に対応する。
+・受け口関数が増えた
+・受け口の名前が変更された
+・受け口関数の名前が変更された
+
+% tecsmerge source_dir   dest_dir
+% tecsmerge source_files dest_dir
+
+% tecsmerge -p port_name -f old_name:new_name source_file dest_dir
+% tecsmerge -p old_name:new_name source_file dest_dir
+
+source_file の名前は _teml.c, _templ.h で終わっていなくてはならない
+dest_file は source_file の _templ を取り除いた名前でなくてはならない
+dest_file が存在しない場合、_templ を取り除いた名前でコピーするだけである
+
+以下のキーワードを 含む行を探す
+
+0) 先頭
+1) /* #[<PREAMBLE>]#,
+2)  * #[</PREAMBLE>]#
+3) /* #[<ENTRY_PORT>]#
+4)  * #[</ENTRY_PORT>]#
+5) /* #[<ENTRY_FUNC>]#
+6) {                       # new mode (function header is changed)
+    * #[/<ENTRY_FUNC>]#    # when --old-mode
+    * #[/ENTRY_FUNC>]#     # for Bug compatibility
+7) /* #[<POSTAMBLE>]#
+8)  * #[</POSTAMBLE>]#
+9) 終わり
+
+上記のうち 1), 3), 5), 7) を開始キーワードと呼ぶ。
+なお、特に断りのない場合、9) も開始キーワードに含む。
+
+名前の変更
+
+a) 受け口名の変更
+
+  -p old_port_name:new_port_name
+
+b) 受け口関数名の変更
+
+  -f old_port_name:new_port_name
+
+ old_port_name, new_port_name は、次の形式でなくてはならない。
+
+  受け口名 + '_' + 関数名
+
+
+i) ヘッダ１
+
+  0) と開始キーワードの間
+
+ii) ヘッダ２
+
+  1) と開始キーワードの間
+
+通常、これが複数存在することはないが、複数存在した場合、すべてファイル
+の先頭に出力される。
+
+iii) 受け口ヘッダ
+
+  3) と開始キーワードの間
+
+受け口ヘッダは、後続の受け口関数の受け口を表すものと仮定される。
+受け口ヘッダは、重要ではない。
+
+iv) 受け口関数
+
+  5) と開始キーワードの間
+
+=end
+
+require 'optparse'
+$n_err   = 0
+$b_show  = false
+$b_exist = false            # コピー先にファイルがある場合のみマージ
+$old_mode = false           # old_mode (関数本体として /<ENTRY_FUNC> の代わりに '{' を使う
+
+#2.0
+def write_array( file, array )
+  array.each{ |line|
+    file.write line
+  }
+end
+
+class PortRenamer
+  @@port_renamer_list = {}
+  @@port_renamer_current = nil
+
+  def initialize( old_port_name, new_port_name )
+    old_port_name = old_port_name.to_sym
+    if new_port_name then
+      new_port_name = new_port_name.to_sym
+    end
+    # p "port_renamer: #{old_port_name}"
+    @@port_renamer_list[old_port_name] = self
+    @@port_renamer_current = self
+    @old_port_name = old_port_name
+    @new_port_name = new_port_name
+    @func_renamer_list = {}
+  end
+
+  def self.add_func( old_name, new_name )
+    # p "add_func: #{old_name}"
+    if @@port_renamer_current == nil then
+      STDERR.puts( "error: #{old_name}: specify -p before -f" )
+      n_err += 1
+    else
+      @@port_renamer_current.add_func( old_name, new_name )
+    end
+  end
+
+  def add_func( old_name, new_name )
+    old_name = old_name.to_sym
+    new_name = new_name.to_sym
+    if @func_renamer_list[old_name] then
+      STDERR.puts( "error: #{old_name}: duplicate in port #{@old_port_name}" )
+      $n_err += 1
+    elsif old_name == new_name then
+      STDERR.puts( "error: #{old_name}: old and new are the same name" )
+      $n_err += 1
+    end
+    @func_renamer_list[old_name] = new_name
+  end
+
+  def self.show
+    if @@port_renamer_list then
+      @@port_renamer_list.each { |pr,pc|
+        pc.show
+      }
+    end
+  end
+
+  def self.get_list
+    @@port_renamer_list
+  end
+
+  attr_accessor  :old_port_name, :new_port_name, :func_renamer_list
+
+  def show
+    print "port: #{@old_port_name}"
+    if @new_port_name then
+      print " => #{@new_port_name}"
+    end
+    puts ""
+
+    @func_renamer_list.each { |old,new|
+      print "  func: #{old} => #{new}\n"
+    }
+  end
+end
+
+
+class CDLContents
+  #@head::             [string]
+  #@preamble_comment:: [string]
+  #@preamble_body::    [string]
+  #@entry_port::       {ep_name=>CDLEntryPort}
+  #@entry_port_array:: [CDLEntryPort]
+  #@postamble_comment::[string]
+  #@postamble_body::   [string]
+
+  @@DELIMITERS = {
+    # state             => [ regexp_original,                 [previous states]                   , Regexp ]
+    :HEAD               => [ "#[<BeginingOfFile>]#",          []                       ],
+    :PREAMBLE_COMMENT   => [ "/* #[<PREAMBLE>]#",             [:HEAD]                  ],
+    :PREAMBLE_BODY      => [ " * #[</PREAMBLE>]#",            [:PREAMBLE_COMMENT]      ],
+    :ENTRY_COMMENT      => [ "/* #[<ENTRY_PORT>]# PORT_NAME", [:PREAMBLE_BODY, :ENTRY_FUNC_BODY, :ENTRY_FUNC_BODY2] ],
+    :ENTRY_BODY         => [ " * #[</ENTRY_PORT>]#",          [:ENTRY_COMMENT]         ],
+    :ENTRY_FUNC_COMMENT => [ "/* #[<ENTRY_FUNC>]# FUNC_NAME", [:ENTRY_BODY, :ENTRY_FUNC_BODY, :ENTRY_FUNC_BODY2]    ],
+    :POSTAMBLE_COMMENT  => [ "/* #[<POSTAMBLE>]#",            [:ENTRY_FUNC_BODY, :ENTRY_FUNC_BODY2, :PREAMBLE_BODY] ],
+    :POSTAMBLE_BODY     => [ " * #[</POSTAMBLE>]#",           [:POSTAMBLE_COMMENT]     ],
+    :EOF                => [ "#[</EndOfFile>]#",              [:POSTAMBLE_BODY,:ENTRY_FUNC_BODY, :ENTRY_FUNC_BODY2, :PREAMBLE_BODY]  ],
+  }
+
+  @@DELIMITERS_FUNC_BY_COMMENT = {
+    :ENTRY_FUNC_BODY    => [ " * #[</ENTRY_FUNC>]#",          [:ENTRY_FUNC_COMMENT]    ],
+    :ENTRY_FUNC_BODY2   => [ " * #[/ENTRY_FUNC>]#",           [:ENTRY_FUNC_COMMENT]    ],  # for Bug compatibility
+  }
+
+  @@DELIMITERS_FUNC_BY_BRACKET = {
+    :ENTRY_FUNC_BODY    => [ "\\\{",                          [:ENTRY_FUNC_COMMENT]    ],
+  }
+
+  def self.rewrite_DELIMITERS  delimiters
+    delimiters.each{ |stat, stat_info|
+      s = stat_info[0].gsub( /([\*\[\]])/, "\\\\\\1" )   # *, [, ] の前に \\ を挿入
+      s.gsub!( /\s*\w*_NAME/, "\\s*(\\w*)" )             # ..._NAME を (w*) に変更
+      s = "^" + s                                        # ^ を先頭に挿入
+      stat_info[2] = Regexp.new( s )
+      # p stat_info[2]
+    }
+  end
+
+  rewrite_DELIMITERS @@DELIMITERS
+  rewrite_DELIMITERS @@DELIMITERS_FUNC_BY_COMMENT
+  rewrite_DELIMITERS @@DELIMITERS_FUNC_BY_BRACKET
+
+  #=== モードに従い DELIMITERS に DELIMITERS_FUNC_BY_* をマージする
+  # mode :OLD_FUNC_BODY, :NEW_FUNC_BODY
+  def self.merge_DELIMITERS mode
+    case mode
+    when :OLD_FUNC_BODY
+      @@DELIMITERS.merge! @@DELIMITERS_FUNC_BY_COMMENT
+    when :NEW_FUNC_BODY
+      @@DELIMITERS.merge! @@DELIMITERS_FUNC_BY_BRACKET
+    else
+      raise "unknown mode"
+    end
+  end
+
+  #all_contents:: [string,...]
+  def initialize all_contents
+    part = []
+    line_no = 0
+    stat = :HEAD
+    arg = nil
+    port_name = nil
+    func_name = nil
+
+    @entry_port = {}
+    @entry_port_array = []
+
+    @head = []
+    @preamble_comment = []
+    @preamble_body = []
+    @postamble_comment = []
+    @postamble_body = []
+
+    (all_contents+[nil]).each{ |line|  # nil: EOF
+      line_no += 1
+      # p "L: #{line}"
+      b_delim = false        # デリミタキーワードの行
+      @@DELIMITERS.each { |next_stat,stat_info|
+
+        next if next_stat == :HEAD || ( next_stat == :EOF && line != nil )
+        # #1002 tecsmerge の非受け口関数 (POSTAMBLE部) の行頭に '{' があるとエラーになる 	
+        if (! $old_mode) && ( /^\{/ =~ line ) && ( stat == :PREAMBLE_BODY || stat == :POSTAMBLE_BODY )
+          p line + "  next_stat=" + next_stat.to_s + "stat=" + stat.to_s
+          next
+        end
+
+        # p "R: #{stat_info[0]}"
+        if stat_info[2] =~ line || ( line == nil && next_stat == :EOF ) then
+          # p "D: #{line}: #{stat}"
+          b_delim = true
+
+          found = false
+          stat_info[1].each{ |prev_stat|
+            if stat == prev_stat then
+              found = true
+            end
+          }
+          if ! found then
+            STDERR.puts "error #{line_no}: unsuitable previous keyword"
+            STDERR.puts "error #{line_no}:   previous:  \"#{@@DELIMITERS[stat][0]}\""
+            STDERR.puts "error #{line_no}:   current:   \"#{@@DELIMITERS[next_stat][0]}\""
+            expect = ""; delim = ""
+            stat_info[1].each{ |prev_stat| expect = "#{expect+delim}\"#{@@DELIMITERS[prev_stat][0]}\""; delim = ", " }
+            STDERR.puts "error #{line_no}:   suitable previous: #{expect}"
+            $n_err += 1
+          end
+
+          case stat
+          when :PREAMBLE_COMMENT, :ENTRY_COMMENT, :ENTRY_FUNC_COMMENT, :POSTAMBLE_COMMENT
+            part << line
+          end
+
+          case stat   # 前の状態
+          when :HEAD
+            @head = part
+          when :PREAMBLE_COMMENT
+            @preamble_comment = part
+          when :PREAMBLE_BODY
+            @preamble_body = part
+          when :ENTRY_COMMENT
+            port_name = arg.to_sym
+            @entry_port[ port_name ] = CDLEntryPort.new
+            @entry_port_array << port_name
+            @entry_port[ port_name ].entry_comment = part
+          when :ENTRY_BODY
+            @entry_port[ port_name ].entry_body = part
+          when :ENTRY_FUNC_COMMENT
+            func_name = arg.to_sym
+            if @entry_port[ port_name ] then   # nil なら既にエラー
+              @entry_port[ port_name ].entry_func_comment[ func_name ] = part
+              @entry_port[ port_name ].entry_func_array << func_name
+            end
+          when :ENTRY_FUNC_BODY, :ENTRY_FUNC_BODY2
+            if @entry_port[ port_name ] then   # nil なら既にエラー
+              @entry_port[ port_name ].entry_func_body[ func_name ] = part
+            end
+          when :POSTAMBLE_COMMENT
+            @postamble_comment = part
+          when :POSTAMBLE_BODY
+            @postamble_body = part
+          else
+            raise "Unknown state #{stat}"
+          end
+
+          case next_stat
+          when :PREAMBLE_COMMENT, :ENTRY_COMMENT, :ENTRY_FUNC_COMMENT, :POSTAMBLE_COMMENT
+            part = [ line ]
+          else
+            part = []
+          end
+
+          stat = next_stat
+          arg = $1     # arg に取っておく
+          # p stat, arg
+          break
+        end
+      }
+
+      if ! b_delim then
+        part << line
+      end
+    }
+      
+  end
+
+  def check template
+    # template にないものをチェック
+    @entry_port.each{ |port_name, entry_port|
+      temp_entry_port = template.entry_port[port_name]
+      if temp_entry_port == nil then
+        STDERR.puts "info: #{port_name} is deleted port"
+        next
+      end
+      # temp_entry_port.entry_func_body.each{ |f,b|  p f }
+      entry_port.entry_func_body.each{ |func_name, func_body|
+        if temp_entry_port.entry_func_body[func_name] == nil then
+          STDERR.puts "info: #{func_name} is deleted function"
+        end
+      }
+    }
+  end
+
+  def rename
+
+    renamed_entry_port = {}
+    PortRenamer.get_list.each{ |pon,pr|
+
+      # 対象受け口を捜す
+      ep = @entry_port[pon]
+      if ep == nil then
+        STDERR.puts "warning: #{pon}: renaming port not found"
+        next
+      end
+
+      # ポートの rename
+      pnn = pr.new_port_name    # 置換後の名前
+      if pnn then
+        # 置換する名前があれば、登録しなおす
+        renamed_entry_port[pnn] = @entry_port[pon]
+        @entry_port.delete pon
+      end
+
+      # 指定された関数の置換
+      renamed_func_comment = {}
+      renamed_func_body = {}
+      pr.func_renamer_list.each{ |old,new|
+        ofn = "#{pon}_#{old}".to_sym
+        nfn = "#{pon}_#{new}".to_sym
+        # p "fnn: #{ofn} #{nfn} #{pon}"
+        if ep.entry_func_comment[ofn] == nil then
+          STDERR.puts "warning: #{old}: renaming function not found"
+          next
+        end
+        ep.entry_func_array.map! { |fn|
+          # p fn, nfn, ofn, fn==ofn ? nfn : fn
+          fn==ofn ? nfn : fn
+        }
+        renamed_func_comment[nfn] = ep.entry_func_comment[ofn]
+        renamed_func_body[nfn]    = ep.entry_func_body[ofn]
+        ep.entry_func_comment.delete ofn
+        ep.entry_func_body.delete    ofn
+      }
+      ep.entry_func_comment.merge! renamed_func_comment
+      ep.entry_func_body.merge!    renamed_func_body
+
+      # ポート名の変更による関数名の置換
+      renamed_func_comment = {}
+      renamed_func_body = {}
+      if pnn then
+        ep.entry_func_array.map! { |ofn|
+          nfn = ofn.to_s.sub( /#{pon.to_s}/, pnn.to_s ).to_sym
+          # p "pnn: #{ofn} #{nfn} #{pon}  #{pnn}"
+          if nfn != ofn then
+            renamed_func_comment[nfn] = ep.entry_func_comment[ofn]
+            renamed_func_body[nfn]    = ep.entry_func_body[ofn]
+            ep.entry_func_comment.delete ofn
+            ep.entry_func_body.delete    ofn
+            nfn
+          else
+            ofn
+          end
+        }
+        ep.entry_func_comment.merge! renamed_func_comment
+        ep.entry_func_body.merge!    renamed_func_body
+
+        # ep.entry_func_comment.each { |f,e| p "FF: #{f}" }
+        # ep.entry_func_array.each { |f,e| p "FA: #{f}" }
+      end
+    }
+    # p renamed_entry_port
+    @entry_port.merge! renamed_entry_port
+  end
+
+  def merge src
+    @head = src.head
+    @preamble_body = src.preamble_body
+    @postamble_body = src.postamble_body
+
+    @entry_port_array.each{ |port_name|
+      # p "merging #{port_name}"
+      entry_port = @entry_port[ port_name ]
+      src_entry_port = src.entry_port[port_name]
+      if src_entry_port == nil then
+        print "port merged:   #{port_name}\n"
+        next
+      end
+      entry_port.entry_body = src_entry_port.entry_body
+      entry_port.entry_func_array.each{ |func_name|
+        # p "merging #{func_name}"
+        func_body = entry_port.entry_func_body[ func_name ]
+        if src_entry_port.entry_func_body[func_name] == nil then
+          print "func merged:   #{func_name}\n"
+          next
+        end
+        print "func remained: #{func_name}\n"
+        # entry_port.entry_func_comment[func_name] = src_entry_port.entry_func_comment[func_name]
+        entry_port.entry_func_body[func_name]    = src_entry_port.entry_func_body[func_name]
+      }
+    }
+  end
+
+  def write file
+#2.0    file.write @head
+    write_array( file, @head )
+#2.0    file.write @preamble_comment
+    write_array( file, @preamble_comment )
+#2.0    file.write @preamble_body
+    write_array( file, @preamble_body )
+    @entry_port_array.each{ |port_name| @entry_port[port_name].write file }
+#2.0    file.write @postamble_comment
+    write_array( file, @postamble_comment )
+#2.0    file.write @postamble_body
+    write_array( file, @postamble_body )
+  end
+
+  attr_accessor :head, :preamble_comment, :preamble_body, :entry_port, :postamble_body
+end
+
+class CDLEntryPort
+  #@entry_comment::      [string]
+  #@entry_body::         [string]
+  #@entry_func_comment:: {ep_func_name=>string}
+  #@entry_func_body::    {ep_func_name=>string}
+  #@entry_func_array::   [string]
+
+  def initialize
+    @entry_comment = []
+    @entry_body = []
+    @entry_func_comment = {}
+    @entry_func_body = {}
+    @entry_func_array = []
+  end
+
+  def write file
+#2.0    file.write @entry_comment
+    write_array( file, @entry_comment )
+#2.0    file.write @entry_body
+    write_array( file, @entry_body )
+    @entry_func_array.each{ |fnm|
+      # p @entry_func_comment[fnm][0]
+
+#2.0      file.write @entry_func_comment[fnm]
+      write_array( file, @entry_func_comment[fnm] )
+#2.0      file.write @entry_func_body[fnm]
+      write_array( file, @entry_func_body[fnm] )
+    }
+  end
+
+  attr_accessor :entry_comment, :entry_body, :entry_func_comment, :entry_func_body, :entry_func_array
+end
+
+def merge( src_file, dst_dir )
+  unless src_file =~ /(.*)_templ(.[ch])$/ then
+    STDERR.puts( "error: #{src_file}: not end with _templ.c/h" )
+    exit 1
+  end
+
+  fname = "#{$1}#{$2}"
+  dst_file = "#{dst_dir}/#{File.basename fname}"
+  if FileTest.file?( dst_file ) then
+    print( "merging #{src_file} to #{dst_file}\n" )
+    # dst_file の読込み
+    begin
+      dst = open( dst_file )
+#2.0
+      set_encoding dst
+      old_contents = dst.readlines
+    rescue
+      STDERR.puts "error: cannot open #{dst_file}"
+      $n_err += 1
+      exit 1
+    ensure
+      dst.close
+    end
+    old = CDLContents.new( old_contents )
+
+    # template の読込み
+    begin
+      src = open( src_file )
+#2.0
+      set_encoding src
+      new_contents = src.readlines
+    rescue
+      STDERR.puts "error: cannot open #{src_file}"
+      $n_err += 1
+      exit 1
+    ensure
+      src.close
+    end
+    templ = CDLContents.new( new_contents )
+
+    old.rename
+    error_check dst_file, 1
+
+    old.check templ
+    error_check dst_file, 2
+
+    templ.merge old
+    error_check dst_file, 3
+
+    bkup_file = rename_dst( dst_file )
+
+    begin
+      dst = open( dst_file, "w" )
+#2.0
+      set_encoding dst
+      templ.write dst
+    ensure
+      dst.close
+    end
+
+  elsif $b_exist == false then
+    # src_file を dst_file へコピー
+    begin
+      src = File.open( src_file )
+#2.0
+      set_encoding src
+      contents = src.readlines
+    rescue
+      print "#{src_file}: fail to read\n"
+    ensure
+      src.close
+    end
+
+    begin
+      dst = File.open( dst_file, "w" )
+      set_encoding dst
+#2.0      dst.write( contents )
+      contents.each{ |line|
+        dst.print line
+      }
+    rescue
+      print "#{dst_file}: fail to write\n"
+    ensure
+      dst.close
+    end
+  else
+    print "info: #{dst_file} skipped\n"
+  end
+end
+
+def error_check dst_file, level
+  if $n_err > 0 then
+    STDERR.puts "=== #{dst_file} not generated because of error ==="
+    exit level
+  end
+end
+
+
+#=== ファイルのエンコーディングを ASCII-8BIT に変更
+# Ruby 1.9 以上の場合に変更
+def set_encoding file
+  if RUBY_VERSION >= "1.9.0" then
+    file.set_encoding "ASCII-8BIT"
+  end
+end
+
+#=== rename_dst
+# dst_file のバックアップファイル名を決定し、リネームする
+# 成功すれば、リネーム後のファイル名を返す
+# dst_file が存在しなければ（リネームは行われず）nil を返す。
+def rename_dst( dst_file )
+  begin
+    File.stat dst_file
+  rescue
+    STDERR.puts( "info: backup not generated for #{dst_file}" )
+    # なければ終わり
+    return nil
+  end
+
+  i = 0
+  found = true
+  while found == true
+    begin
+      i = i + 1
+      bkup_file = "#{dst_file}_#{i}"
+      File.stat bkup_file
+    rescue
+      found = false
+    end
+  end
+
+  begin
+    File.rename( dst_file, bkup_file )
+    STDERR.puts( "info: backup generated for #{dst_file} to #{bkup_file}" )
+    return bkup_file
+  rescue
+    STDERR.puts( "error: fail to rename backup file: #{bkup_file}" )
+    exit 1
+  end
+
+  return nil
+end
+
+ARGV.options {|parser|
+  parser.banner =<<EOT
+Usage: tecsmerge [options] files_templ.c   src_dir
+       tecsmerge [options] gen_dir         src_dir
+EOT
+  parser.on('-e', '--exist-only',  "merge if exist in destination directory") { |fs|
+    $b_exist = true
+  }
+  parser.on('-p', '--port=old_name:new_name',  "specify entry port name change") { |ps|
+    p = ps.split( ':' )
+    PortRenamer.new( p[0], p[1] )
+  }
+  parser.on('-f', '--func=old_name:new_name',  "specify entry function name change") { |fs|
+    f = fs.split( ':' )
+    PortRenamer.add_func( f[0], f[1] )
+  }
+  parser.on('-s', '--show_change_set',  "show change set. all substitute") {
+    $b_show = true
+  }
+  parser.on('-o', '--old-mode',  "old mode (function head not substituted)") { |fs|
+    $old_mode = true
+  }
+  parser.version = #{$version}
+  parser.release = nil
+  parser.parse!
+#  if ARGV.empty?
+  if ARGV.length < 2 then
+    puts parser.help
+    exit 1
+  end
+}
+
+if $b_show then
+  PortRenamer.show
+end
+
+if $old_mode then
+  CDLContents.merge_DELIMITERS :OLD_FUNC_BODY
+else
+  CDLContents.merge_DELIMITERS :NEW_FUNC_BODY
+end
+
+if $n_err > 0 then
+  STDERR.puts( "#{$n_err} errors" )
+  exit 1
+end
+
+src = ARGV[0,ARGV.length-1]
+dst = ARGV[-1]
+
+begin
+  stat = File.stat dst
+rescue
+  STDERR.puts( "error: #{dst}: not found" )
+  exit 1
+ensure
+  if stat && ! stat.directory? then
+    STDERR.puts( "error: #{dst}: not directory" )
+    exit 1
+  end
+end
+
+src.each { |s|
+  begin
+    stat = File.stat s
+  rescue
+    STDERR.puts( "error: #{s}: not found or cannot access" )
+    exit 1
+  end
+
+  if stat.directory? then
+    Dir.foreach(s) {|file|
+      if file =~ /_templ.[ch]$/ then
+        merge( "#{s}/#{file}", dst )
+      end
+    }
+  elsif stat.file? then
+    merge( s, dst )
+  end
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/Makefile.tinet
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/Makefile.tinet	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/Makefile.tinet	(revision 398)
@@ -0,0 +1,389 @@
+#
+#   TINET (TCP/IP Protocol Stack)
+#  
+#   Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+#                    Tomakomai National College of Technology, JAPAN
+#   Copyright (C) 2008-2009 by Hokkaido Industrial Research Institute, JAPAN
+# 
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次の条件を満たすこと．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+# 
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#  
+#   @(#) $Id$
+#
+
+#
+#  「ミドルウェアの Makefile のインクルード」に追加する。
+#
+
+#
+#  カーネルの識別
+#
+ifdef SRCLANG
+	TARGET_KERNEL = ASP
+	TINET_CDEFS := $(TINET_CDEFS) -DTARGET_KERNEL_ASP
+else
+	TARGET_KERNEL = JSP
+	TINET_CDEFS := $(TINET_CDEFS) -DTARGET_KERNEL_JSP
+endif
+
+#
+#  TINET ソースファイルのディレクトリの定義
+#
+TINET_ROOT = $(SRCDIR)/tinet
+
+#
+#  TINET 1.1 との互換性のための定義
+#
+ifndef SUPPORT_INET4
+	ifndef SUPPORT_INET6
+		SUPPORT_INET4 = true
+	endif
+endif
+
+#
+#  TINET 1.7 以降は、ネットワーク層の指定を変更した。
+#
+
+ifeq ($(SUPPORT_INET6),true)
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_INET6
+endif
+
+ifeq ($(SUPPORT_INET4),true)
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_INET4
+endif
+
+ifeq ($API_CFG_IP4MAPPED_ADDR,true)
+	TINET_CDEFS := $(TINET_CDEFS) -DAPI_CFG_IP4MAPPED_ADDR
+endif
+
+ifeq ($(SUPPORT_IGMP),true)
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_IGMP
+endif
+
+#
+#  ネットワークサービスに関する定義
+#
+
+#  汎用通信機能
+
+TINET_DIRS = $(TINET_ROOT)/net:$(TINET_ROOT)/netinet:$(TINET_ROOT)/netinet6
+TINET_COBJS := $(TINET_COBJS) \
+               net_buf.o net_count.o net_subr.o net_timer.o if.o \
+               in_subr.o route_cfg.o
+TINET_CFG_COBJS := $(TINET_CFG_COBJS) tinet_cfg.o
+TINET_CFG2_OUT_SRCS := $(TINET_CFG2_OUT_SRCS) tinet_cfg.h tinet_cfg.c
+
+#  IPv6
+
+TINET_COBJS := $(TINET_COBJS) \
+               in6.o in6_ifattach.o nd6_rtr.o \
+               in6_subr.o ip6_input.o icmp6.o \
+               dest6.o route6.o frag6.o \
+               ah_input.o esp_input.o \
+               nd6.o nd6_nbr.o ip6_output.o scope6.o
+TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netinet6/ip6.cfg
+
+#  IPv4
+
+TINET_COBJS := $(TINET_COBJS) \
+               ip_input.o ip_output.o ip_icmp.o ip_igmp.o in4_subr.o
+TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netinet/ip.cfg
+
+#  loop back
+
+ifeq ($(NET_IF),loop)
+
+	TINET_COBJS := $(TINET_COBJS) if_loop.o
+	TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/net/if_loop.cfg
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_LOOP
+
+endif
+
+#  ppp
+
+ifeq ($(NET_IF),ppp)
+
+	TINET_COBJS := $(TINET_COBJS) \
+	               ppp.o ppp_hdlc.o ppp_lcp.o ppp_fsm.o \
+	               ppp_auth.o ppp_upap.o
+	TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/net/ppp.cfg
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_PPP
+
+#  IPv6用 cp
+	TINET_COBJS := $(TINET_COBJS) ppp_ipv6cp.o
+
+#  IPv4用 cp
+	TINET_COBJS := $(TINET_COBJS) ppp_ipcp.o
+
+ifeq ($(PPP_CFG_MODEM),true)
+
+	TINET_COBJS := $(TINET_COBJS) ppp_modem.o 
+	TINET_CDEFS := $(TINET_CDEFS) -DPPP_CFG_MODEM
+
+endif
+
+endif
+
+#  ターゲット依存の定義のインクルード
+
+ifeq ($(TARGET_KERNEL),ASP)
+
+	-include $(TARGETDIR)/Makefile.tinet
+
+endif
+
+ifeq ($(TARGET_KERNEL),JSP)
+
+	ifdef TOOL
+		ifdef SYS
+			-include $(SRCDIR)/config/$(CPU)-$(TOOL)/$(SYS)/Makefile.tinet
+		endif
+		-include $(SRCDIR)/config/$(CPU)-$(TOOL)/Makefile.tinet
+	else
+		ifdef SYS
+			-include $(SRCDIR)/config/$(CPU)/$(SYS)/Makefile.tinet
+		endif
+		-include $(SRCDIR)/config/$(CPU)/Makefile.tinet
+	endif
+
+endif
+
+#  ethernet
+
+ifeq ($(NET_IF),ether)
+
+	TINET_COBJS := $(TINET_COBJS) ethernet.o if6_ether.o if_ether.o
+	TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) \
+	                    $(TINET_ROOT)/net/ethernet.cfg \
+	                    $(TINET_ROOT)/netinet/if_ether.cfg
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_ETHER
+	include $(TINET_ROOT)/netdev/$(NET_DEV)/Makefile.tinet
+
+endif
+
+#  TCP
+
+ifeq ($(SUPPORT_TCP),true)
+
+	TINET_COBJS := $(TINET_COBJS) \
+	               tcp_input.o tcp_output.o tcp_timer.o \
+	               tcp_subr.o tcp_subr_cs.o tcp_subr_ncs.o 
+	TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netinet/tcp.cfg
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_TCP
+
+endif
+
+#  UDP
+
+ifeq ($(SUPPORT_UDP),true)
+
+	TINET_COBJS := $(TINET_COBJS) \
+	               udp_input.o udp_output.o udp_subr.o
+	TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netinet/udp.cfg
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_UDP
+
+endif
+
+#
+#  TINET ライブラリの定義
+#
+
+ifeq ($(NO_USE_TINET_LIBRARY),true)
+
+	ifeq ($(SUPPORT_TCP),true)
+		TINET_COBJS := $(TINET_COBJS) tcp_usrreq.o 
+	endif
+
+	ifeq ($(SUPPORT_UDP),true)
+		TINET_COBJS := $(TINET_COBJS) udp_usrreq.o udp_usrreq_nblk.o
+	endif
+
+else
+
+	ifeq ($(SUPPORT_TCP),true)
+		TINET_LCSRCS := $(TINET_LCSRCS) tcp_usrreq.c 
+	endif
+
+	ifeq ($(SUPPORT_UDP),true)
+		TINET_LCSRCS := $(TINET_LCSRCS) udp_usrreq.c udp_usrreq_nblk.c
+	endif
+
+	TINET_CDEFS := $(TINET_CDEFS) -DTCP_CFG_LIBRARY -DUDP_CFG_LIBRARY
+
+	ifdef TINET_LIB
+		MAKE_TINET_LIB :=
+		LIBTINET := $(TINET_LIB)/libtinet.a
+	else
+		MAKE_TINET_LIB := libtinet.a
+		LIBTINET := $(MAKE_TINET_LIB)
+	endif
+
+	MAKE_MTASK := $(MAKE_MTASK) $(LIBTINET)
+
+endif
+
+#
+#  ライブラリ化するソースファイルから生成される
+#  オブジェクトファイルの定義
+#
+TINET_LCOBJS = $(foreach file,$(TINET_LCSRCS),$($(file:.c=)))
+
+tcp_usrreq = 	tcp_cre_rep.o tcp_del_rep.o \
+		tcp_cre_cep.o tcp_del_cep.o \
+		tcp_acp_cep.o tcp_con_cep.o tcp_sht_cep.o \
+		tcp_cls_cep.o tcp_can_cep.o \
+		tcp_snd_dat.o tcp_rcv_dat.o \
+		tcp_snd_oob.o tcp_rcv_oob.o \
+		tcp_get_buf.o tcp_snd_buf.o \
+		tcp_rcv_buf.o tcp_rel_buf.o \
+		tcp_set_opt.o tcp_get_opt.o
+
+udp_usrreq = 	udp_can_cep.o udp_send_data.o \
+		udp_can_snd.o udp_can_rcv.o \
+		udp_snd_dat.o udp_rcv_dat.o \
+		udp_set_opt.o udp_get_opt.o \
+		udp_cre_cep.o udp_del_cep.o
+
+udp_usrreq_nblk = \
+		udp_can_snd_nblk.o udp_can_rcv_nblk.o \
+		udp_snd_dat_nblk.o udp_rcv_dat_nblk.o
+
+#
+#  ライブラリ化するソースファイルから生成される
+#  オブジェクトファイルの依存関係の定義
+#
+$(tcp_usrreq) $(tcp_usrreq:.o=.s) $(tcp_usrreq:.o=.d): tcp_usrreq.c tcpn_usrreq.c
+$(udp_usrreq) $(udp_usrreq:.o=.s) $(udp_usrreq:.o=.d): udp_usrreq.c udpn_usrreq.c
+$(udp_usrreq_nblk) $(udp_usrreq_nblk:.o=.s) $(udp_usrreq_nblk:.o=.d): udp_usrreq_nblk.c
+
+#
+#  TINET ライブラリの定義
+#
+TINET_LIB_OBJS = $(TINET_LCOBJS)
+
+#
+#  TINET コンフィギュレーションファイルの定義
+#
+
+ifeq ($(TARGET_KERNEL),ASP)
+
+TINET_CFG_OUT = tinet_cfg.c tinet_cfg.h tinet_kern.cfg
+TINET_KERNEL_CFG :=	$(TINET_KERNEL_CFG) \
+			$(TINET_ROOT)/tinet_asp.cfg $(TINET_ROOT)/net/net_asp.cfg 
+
+endif
+
+ifeq ($(TARGET_KERNEL),JSP)
+
+TINET_CFG = tinet_$(UNAME).cfg
+TINET_CFG_OUT = tinet_cfg.c tinet_id.h tinet_kern.cfg
+TINET_KERNEL_CFG :=	$(TINET_KERNEL_CFG) tinet_kern.cfg \
+			$(TINET_ROOT)/tinet.cfg $(TINET_ROOT)/net/net_jsp.cfg 
+TINET_CFG_OUT := $(TINET_CFG_OUT) $(IPSEC_CFG_OUT)
+
+endif
+
+#
+#  共通コンパイルオプションの定義への追加
+#
+CDEFS := $(CDEFS) $(TINET_CDEFS)
+INCLUDES := $(INCLUDES) -I$(TINET_ROOT)
+
+#
+#  TINET コンパイルオプションの定義への追加
+#
+TINET_CFLAGS := $(TINET_CFLAGS) -fno-strict-aliasing
+
+#
+#  システムサービス、ミドルウェアに関する定義
+#
+
+ifeq ($(TARGET_KERNEL),ASP)
+
+	SYSSVC_DIRS := $(SYSSVC_DIRS):$(TINET_DIRS)
+	SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+	SYSSVC_COBJS := $(SYSSVC_COBJS) $(TINET_COBJS)
+	SYSSVC_CFLAGS := $(SYSSVC_CFLAGS) $(TINET_CFLAGS)
+	SYSSVC_LIBS := $(SYSSVC_LIBS) $(LIBTINET) -lc
+
+	CFG_COBJS := $(CFG_COBJS) $(TINET_CFG_COBJS)
+	CFG2_OUT_SRCS := $(CFG2_OUT_SRCS) $(TINET_CFG2_OUT_SRCS)
+
+	CLEAN_FILES := $(CLEAN_FILES) $(TINET_CFG_OUT) $(MAKE_TINET_LIB)
+
+endif
+
+ifeq ($(TARGET_KERNEL),JSP)
+
+	MTASK_CFG := $(MTASK_CFG) $(TINET_CFG)
+	MTASK_KERNEL_CFG := $(MTASK_KERNEL_CFG) $(TINET_KERNEL_CFG)
+	MTASK_DIR := $(MTASK_DIRS):$(TINET_DIRS)
+	MTASK_LCSRCS := $(MTASK_LCSRCS) $(TINET_LCSRCS)
+	MTASK_ASMOBJS := $(MTASK_ASMOBJS)
+	ifdef USE_CXX
+		MTASK_CXXOBJS := $(MTASK_CXXOBJS)
+		MTASK_COBJS := $(MTASK_COBJS) $(TINET_COBJS)
+	else
+		MTASK_COBJS := $(MTASK_COBJS) $(TINET_COBJS)
+	endif
+	MTASK_CFLAGS := $(MTASK_CFLAGS) $(TINET_CFLAGS)
+	MTASK_LIBS := $(MTASK_LIBS) $(LIBTINET) -lc
+	MTASK_CLEAN_FILES := $(MTASK_CLEAN_FILES) $(TINET_CFG_OUT) $(MAKE_TINET_LIB)
+
+endif
+
+#
+#  TINET ライブラリファイルの生成
+#
+libtinet.a: $(TINET_LIB_OBJS)
+	rm -f libtinet.a
+	$(AR) -rcs libtinet.a $(TINET_LIB_OBJS)
+	$(RANLIB) libtinet.a
+
+#
+#  コンパイルルールの定義
+#
+
+ifeq ($(TARGET_KERNEL),ASP)
+
+$(TINET_LCOBJS): %.o:
+	$(CC) -D__$(*F) -o $@ -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+tinet_cfg1_out.o: %.o: %.c
+	$(CC) -c $(CFLAGS) $(KERNEL_CFG_CFLAGS) $<
+
+endif
+
+ifeq ($(TARGET_KERNEL),JSP)
+
+$(TINET_LCOBJS): %.o:
+	$(CC) -D__$(*F) -o $@ -c $(CFLAGS) $(MTASK_CFLAGS) $<
+
+endif
+
+#
+#  コンパイル結果の消去
+#
+cleantinet:
+	rm -f $(TINET_CFG_OUT) $(MAKE_TINET_LIB)
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ether_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ether_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ether_var.h	(revision 398)
@@ -0,0 +1,48 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _ETHER_VAR_H_
+#define _ETHER_VAR_H_
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  Ethernet 処理タスク
+ */
+
+extern void ether_input_task(intptr_t exinf);
+extern void ether_output_task(intptr_t exinf);
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#endif	/* of #ifndef _ETHER_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ethernet.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ethernet.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ethernet.c	(revision 398)
@@ -0,0 +1,590 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  Ethernet 処理タスクの本体
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_llc.h>
+#include <net/if_arp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+
+#include <netinet6/if6_ether.h>
+#include <netinet6/nd6.h>
+
+#include <net/if_var.h>
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  変数
+ */
+
+#if defined(_IP4_CFG)
+
+const uint8_t ether_broad_cast_addr[ETHER_ADDR_LEN] = {
+	UINT_C(0xff), UINT_C(0xff), UINT_C(0xff),
+	UINT_C(0xff), UINT_C(0xff), UINT_C(0xff)
+	};
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+/*
+ *  変数
+ */
+
+/* ネットワークインタフェース構造体 */
+
+static T_IFNET ether_ifnet;
+
+#ifdef SUPPORT_MIB
+
+/*  SNMP の 管理情報ベース (MIB) */
+
+T_IF_STATS if_stats;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+#ifdef ETHER_CFG_802_WARNING
+
+/*
+ *  関数
+ */
+
+static void ieee_802_input (T_NET_BUF *input);
+
+/*
+ *  ieee_802_input -- IEEE 802.3 入力処理
+ */
+
+static void
+ieee_802_input (T_NET_BUF *input)
+{
+	T_8023MAC_HDR	*mhdr;
+	T_8022SNAP_HDR	*shdr;
+
+	mhdr = GET_8023MAC_HDR(input);
+	shdr = GET_8022SNAP_HDR(input);
+	syslog(LOG_WARNING, "[ETHER] unexp 802.3 from: %s, proto: 0x%04x.",
+	                    mac2str(NULL, mhdr->shost), ntohs(*(uint16_t*)&shdr->type));
+	}
+
+#endif	/* of #ifdef ETHER_CFG_802_WARNING */
+
+/*
+ *  ether_srand -- 乱数を初期値を返す。
+ */
+
+uint32_t
+ether_srand (void)
+{
+	T_IF_SOFTC	*ic;
+	uint32_t	rval;
+
+	ic = IF_ETHER_NIC_GET_SOFTC();
+	rval  = (ic->ifaddr.lladdr[2] << 24)
+	      + (ic->ifaddr.lladdr[3] << 16)
+	      + (ic->ifaddr.lladdr[4] <<  8)
+	      + (ic->ifaddr.lladdr[5]      );
+
+#ifdef ETHER_CFG_COLLECT_ADDR
+
+	rval += (ether_collect_addr.lladdr[2] << 24)
+	      + (ether_collect_addr.lladdr[3] << 16)
+	      + (ether_collect_addr.lladdr[4] <<  8)
+	      + (ether_collect_addr.lladdr[5]      );
+
+#endif	/* of #ifdef ETHER_CFG_COLLECT_ADDR */
+
+	return rval;
+	}
+
+/*
+ *  ether_get_ifnet -- ネットワークインタフェース構造体を返す。
+ */
+
+T_IFNET *
+ether_get_ifnet (void)
+{
+	return &ether_ifnet;
+	}
+
+#if defined(_IP6_CFG)
+
+/*
+ *  ether_in6_resolve_multicast -- イーサネットのマルチキャストアドレスへの変換
+ */
+
+ER
+ether_in6_resolve_multicast (T_ETHER_ADDR *ifaddr, const T_IN6_ADDR *maddr)
+{
+	/* マルチキャストアドレスかチェックする。*/
+	if (!IN6_IS_ADDR_MULTICAST(maddr))
+		return E_PAR;
+
+	/* イーサネットのマルチキャストアドレスへの変換 */
+	ether_map_ipv6_multicast(ifaddr, maddr);
+
+	return E_OK;
+	}
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+/**
+ * ether_set_link_up -- リンクしたときにNICから呼び出される
+ */
+void
+ether_set_link_up()
+{
+	if (!(ether_ifnet.flags & IF_FLAG_LINK_UP)) {
+		ether_ifnet.flags |= IF_FLAG_LINK_UP;
+
+		if (ether_ifnet.flags & IF_FLAG_UP) {
+#if defined(_IP4_CFG) && defined(SUPPORT_ETHER)
+			/* ARP再構築？ */
+#endif /* #if defined(_IP4_CFG) && defined(SUPPORT_ETHER) */
+
+#ifdef SUPPORT_IGMP
+			/* IGMP参加 */
+#endif /* #ifdef SUPPORT_IGMP */
+			}
+		if (ether_ifnet.link_callback) {
+			(ether_ifnet.link_callback)(&ether_ifnet);
+			}
+		}
+	}
+
+/**
+ * ether_set_link_up -- リンクが切断したときにNICから呼び出される
+ */
+void
+ether_set_link_down()
+{
+	if (ether_ifnet.flags & IF_FLAG_LINK_UP) {
+		ether_ifnet.flags &= ~IF_FLAG_LINK_UP;
+		if (ether_ifnet.link_callback) {
+			(ether_ifnet.link_callback)(&ether_ifnet);
+			}
+		}
+	}
+
+/*
+ * ether_set_up -- DHCPでアドレスが設定されたとき呼び出される
+ */
+
+void
+ether_set_up()
+{
+	if (!(ether_ifnet.flags & IF_FLAG_UP)) {
+		ether_ifnet.flags |= IF_FLAG_UP;
+		if (ether_ifnet.link_callback) {
+			(ether_ifnet.link_callback)(&ether_ifnet);
+			}
+		}
+	}
+
+/*
+ * ether_set_down -- DHCPでアドレスが解放されたとき呼び出される
+ */
+
+void
+ether_set_down()
+{
+	if (ether_ifnet.flags & IF_FLAG_UP) {
+		ether_ifnet.flags &= ~IF_FLAG_UP;
+		if (ether_ifnet.link_callback) {
+			(ether_ifnet.link_callback)(&ether_ifnet);
+			}
+		}
+	}
+
+/*
+ * ether_set_link_callback -- リンク状態変化時のコールバック登録
+ */
+
+void
+ether_set_link_callback(ether_status_callback_fn link_callback)
+{
+	ether_ifnet.link_callback = link_callback;
+	if (ether_ifnet.link_callback) {
+		(ether_ifnet.link_callback)(&ether_ifnet);
+		}
+	}
+
+/*
+ *  ether_raw_output -- Ethernet インタフェースの出力関数、MAC アドレス解決無し
+ */
+
+ER
+ether_raw_output (T_NET_BUF *output, TMO tmout)
+{
+	ER error = E_OK;
+
+	/* Ethernet 出力キューに投入する。*/
+	if ((error = tsnd_dtq(DTQ_ETHER_OUTPUT, (intptr_t)output, tmout)) != E_OK) {
+		NET_COUNT_ETHER(net_count_ether.out_err_packets, 1);
+		NET_COUNT_MIB(if_stats.ifOutDiscards, 1);
+
+		/* IF でネットワークバッファを開放しないフラグをチェックする。*/
+		if ((output->flags & NB_FLG_NOREL_IFOUT) == 0) {
+			syscall(rel_net_buf(output));
+			}
+		else {
+			output->flags &= (uint8_t)~NB_FLG_NOREL_IFOUT;
+			}
+		IF_ETHER_NIC_RESET(IF_ETHER_NIC_GET_SOFTC());
+		}
+	return error;
+	}
+
+/*
+ *  ether_output -- Ethernet インタフェースの出力関数、MAC アドレス解決有り
+ */
+
+ER
+ether_output (T_NET_BUF *output, const void *dst, T_IF_ADDR *gw, TMO tmout)
+{
+	T_IF_SOFTC	*ic;
+	ER		error = E_OK;
+	T_ETHER_HDR *eth;
+
+	/* 送信元 MAC アドレスを設定する。*/
+	ic = IF_ETHER_NIC_GET_SOFTC();
+	eth = GET_ETHER_HDR(output);
+	memcpy(eth->shost, ic->ifaddr.lladdr, ETHER_ADDR_LEN);
+
+	switch(ntohs(eth->type)) {
+
+#if defined(_IP4_CFG)
+
+	case ETHER_TYPE_IP:		/* IPv4	*/
+#ifdef ETHER_CFG_MULTICAST
+		/* マルチキャストアドレスの場合 */
+		if(IN4_IS_ADDR_MULTICAST(*(uint32_t*)dst)){
+			/* イーサネットのマルチキャストアドレスへの変換 */
+			ether_map_ipv4_multicast((T_ETHER_ADDR *)&eth->dhost, *(T_IN4_ADDR*)dst);
+			error = ether_raw_output(output, tmout);
+			break;
+			}
+#endif
+		if (arp_resolve(&ic->ifaddr, output, *(uint32_t*)dst)) {	/* true ならアドレス解決済 */
+			error = ether_raw_output(output, tmout);
+			}
+		break;
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG)
+
+	case ETHER_TYPE_IPV6:		/* IPv6	*/
+		error = nd6_storelladdr((T_ETHER_ADDR*)eth->dhost,
+		                        (const T_IN6_ADDR*)dst, gw);
+		if (error == E_OK)
+			error = ether_raw_output(output, tmout);
+
+		/* IF でネットワークバッファを開放しないフラグをチェックする。*/
+		else if ((output->flags & NB_FLG_NOREL_IFOUT) == 0) {
+			syscall(rel_net_buf(output));
+			}
+		else {
+			output->flags &= (uint8_t)~NB_FLG_NOREL_IFOUT;
+			}
+		break;
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+	default:
+		NET_COUNT_MIB(if_stats.ifOutErrors, 1);
+
+		/* IF でネットワークバッファを開放しないフラグをチェックする。*/
+		if ((output->flags & NB_FLG_NOREL_IFOUT) == 0) {
+			syscall(rel_net_buf(output));
+			}
+		else {
+			output->flags &= (uint8_t)~NB_FLG_NOREL_IFOUT;
+			}
+		error = E_PAR;
+		break;
+		}
+
+	if (error != E_OK)
+		NET_COUNT_ETHER(net_count_ether.out_err_packets, 1);
+	return error;
+	}
+
+/*
+ *  Ethernet 出力タスク
+ */
+
+void
+ether_output_task(intptr_t exinf)
+{
+	T_IF_SOFTC	*ic;
+	T_NET_BUF	*output;
+	ID		tskid;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[ETHER OUTPUT:%d] started.", tskid);
+
+	ic = IF_ETHER_NIC_GET_SOFTC();
+
+	while (true) {
+		while (rcv_dtq(DTQ_ETHER_OUTPUT, (intptr_t*)&output) == E_OK) {
+			NET_COUNT_ETHER(net_count_ether.out_octets,  output->len);
+			NET_COUNT_MIB(if_stats.ifOutOctets, output->len + 8);
+			NET_COUNT_ETHER(net_count_ether.out_packets, 1);
+
+#ifdef SUPPORT_MIB
+			if ((*(GET_ETHER_HDR(output)->dhost) & ETHER_MCAST_ADDR) == 0) {
+				NET_COUNT_MIB(if_stats.ifOutUcastPkts, 1);
+				}
+			else {
+				NET_COUNT_MIB(if_stats.ifOutNUcastPkts, 1);
+				}
+#endif	/* of #ifdef SUPPORT_MIB */
+
+			syscall(wai_sem(ic->semid_txb_ready));
+
+			IF_ETHER_NIC_START(ic, output);
+
+#ifndef ETHER_NIC_CFG_RELEASE_NET_BUF
+
+			if ((output->flags & NB_FLG_NOREL_IFOUT) == 0) {
+				syscall(rel_net_buf(output));
+				}
+			else {
+				output->flags &= (uint8_t)~NB_FLG_NOREL_IFOUT;
+
+#ifdef SUPPORT_TCP
+				sig_sem(SEM_TCP_POST_OUTPUT);
+#endif	/* of #ifdef SUPPORT_TCP */
+				}
+
+#endif	/* of #ifndef ETHER_NIC_CFG_RELEASE_NET_BUF */
+
+			}
+		}
+	}
+
+/*
+ *  Ethernet 入力タスク
+ */
+
+void
+ether_input_task(intptr_t exinf)
+{
+	T_IF_SOFTC	*ic;
+	T_NET_BUF	*input;
+	T_ETHER_HDR	*eth;
+	ID		tskid;
+	uint16_t	proto;
+	uint8_t		rcount = 0;
+
+	/* ネットワークインタフェース管理を初期化する。*/
+	ifinit();
+
+	/* イーサネットネットワークインタフェース管理を初期化する。*/
+
+#if defined(_IP4_CFG)
+
+	ether_ifnet.in4_ifaddr.addr = IPV4_ADDR_LOCAL;		/* IPv4 アドレス		*/
+	ether_ifnet.in4_ifaddr.mask = IPV4_ADDR_LOCAL_MASK;	/* サブネットマスク		*/
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+	/* NIC を初期化する。*/
+	ic = IF_ETHER_NIC_GET_SOFTC();
+	IF_ETHER_NIC_PROBE(ic);
+	IF_ETHER_NIC_INIT(ic);
+
+	/* Ethernet 出力タスクを起動する */
+	syscall(act_tsk(ETHER_OUTPUT_TASK));
+
+	/* ネットワークタイマタスクを起動する */
+	syscall(act_tsk(NET_TIMER_TASK));
+
+	get_tid(&tskid);
+
+	syslog(LOG_NOTICE, "[ETHER INPUT:%2d] started on MAC Addr: %s.",
+	                   tskid, mac2str(NULL, ic->ifaddr.lladdr));
+
+#if defined(_IP4_CFG)
+
+	/* ARP を初期化する。*/
+	arp_init();
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+	ether_ifnet.ic = ic;
+
+	/* 乱数生成を初期化する。*/
+	net_srand(0);
+
+	while (true) {
+		syscall(wai_sem(ic->semid_rxb_ready));
+		if ((input = IF_ETHER_NIC_READ(ic)) != NULL) {
+			NET_COUNT_ETHER(net_count_ether.in_octets,  input->len);
+			NET_COUNT_MIB(if_stats.ifInOctets, input->len + 8);
+			NET_COUNT_ETHER(net_count_ether.in_packets, 1);
+			eth = GET_ETHER_HDR(input);
+			proto = ntohs(eth->type);
+
+			/* 乱数生成を初期化する。*/
+			if (rcount == 0) {
+
+#ifdef ETHER_CFG_COLLECT_ADDR
+				memcpy(ether_collect_addr.lladdr, eth->shost, 
+				sizeof(ether_collect_addr.lladdr));
+#endif	/* of #ifdef ETHER_CFG_COLLECT_ADDR */
+
+				net_srand(0);
+				}
+			rcount ++;
+
+
+#ifdef SUPPORT_MIB
+			if ((*eth->dhost & ETHER_MCAST_ADDR) == 0) {
+				NET_COUNT_MIB(if_stats.ifInUcastPkts, 1);
+				}
+			else {
+				NET_COUNT_MIB(if_stats.ifInNUcastPkts, 1);
+				}
+#endif	/* of #ifdef SUPPORT_MIB */
+
+#if defined(_IP4_CFG) && defined(ETHER_CFG_ACCEPT_ALL)
+
+			if ((*eth->dhost & ETHER_MCAST_ADDR) && *eth->dhost != 0xff) {
+
+#ifdef ETHER_CFG_MCAST_WARNING
+
+				if (proto <= 1500)
+					proto = ntohs(*(uint16_t*)&(GET_8022SNAP_HDR(input)->type));
+				syslog(LOG_WARNING, "[ETHER] mcast addr  from: %s, to: %s, proto: 0x%04x.",
+				                    mac2str(NULL, eth->shost), mac2str(NULL, eth->dhost), proto);
+
+#endif	/* of #ifdef ETHER_CFG_MCAST_WARNING */
+
+				NET_COUNT_ETHER(net_count_ether.in_err_packets, 1);
+				NET_COUNT_MIB(if_stats.ifInErrors, 1);
+				syscall(rel_net_buf(input));
+				continue;
+				}
+
+#endif	/* of #if defined(_IP4_CFG) && defined(ETHER_CFG_ACCEPT_ALL) */
+
+			switch(proto) {
+
+#if defined(_IP4_CFG)
+
+			case ETHER_TYPE_IP:		/* IP	*/
+				ip_input(input);
+				break;
+
+			case ETHER_TYPE_ARP:		/* ARP	*/
+				arp_input(&ic->ifaddr, input);
+				break;
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG)
+
+			case ETHER_TYPE_IPV6:		/* IPv6	*/
+				ip6_input(input);
+				break;
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+			default:
+
+#ifdef ETHER_CFG_UNEXP_WARNING
+
+#ifdef ETHER_CFG_802_WARNING
+
+				if (proto <= 1500)
+					ieee_802_input(input);
+				else
+					syslog(LOG_NOTICE, "[ETHER] unexp proto from: %s, proto: 0x%04x.",
+					                   mac2str(NULL, GET_ETHER_HDR(input)->shost), proto);
+
+#else	/* of #ifdef ETHER_CFG_802_WARNING */
+
+				syslog(LOG_INFO, "[ETHER] unexp proto from: %s, proto: 0x%04x.",
+				                   mac2str(NULL, GET_ETHER_HDR(input)->shost), proto);
+
+#endif	/* of #ifdef ETHER_CFG_802_WARNING */
+
+#endif	/* of #ifdef ETHER_CFG_UNEXP_WARNING */
+
+				NET_COUNT_ETHER(net_count_ether.in_err_packets, 1);
+				NET_COUNT_MIB(if_stats.ifUnknownProtos, 1);
+				syscall(rel_net_buf(input));
+				break;
+				}
+			}
+		}
+	}
+
+#endif /* of #ifdef SUPPORT_ETHER */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ethernet.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ethernet.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ethernet.cfg	(revision 398)
@@ -0,0 +1,49 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  Ethernet コンフィギュレーションファイル
+ */
+
+#ifdef SUPPORT_ETHER
+
+CRE_TSK(ETHER_OUTPUT_TASK, { TA_HLNG       , 0, ether_output_task, ETHER_OUTPUT_PRIORITY, ETHER_OUTPUT_STACK_SIZE, NULL });
+CRE_TSK(ETHER_INPUT_TASK,  { TA_HLNG|TA_ACT, 0, ether_input_task,  ETHER_INPUT_PRIORITY,  ETHER_INPUT_STACK_SIZE,  NULL });
+
+CRE_DTQ(DTQ_ETHER_OUTPUT,  { TA_TFIFO, NUM_DTQ_ETHER_OUTPUT,  NULL });
+
+/* サポート関数 max2str 用セマフォ */
+
+CRE_SEM(SEM_MAC2STR_BUFF_LOCK,	{ TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef SUPPORT_ETHER */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ethernet.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ethernet.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ethernet.h	(revision 398)
@@ -0,0 +1,325 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ * Fundamental constants relating to ethernet.
+ *
+ * $FreeBSD: src/sys/net/ethernet.h,v 1.9.2.1 1999/08/29 16:28:13 peter Exp $
+ *
+ */
+
+#ifndef _ETHERNET_H_
+#define _ETHERNET_H_
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  フィールド長
+ */
+
+#define ETHER_ADDR_LEN		6	/* Ethernet (MAC) Address	*/
+#define ETHER_TYPE_LEN		2	/* Type		*/
+#define ETHER_CRC_LEN		0/*4*/	/* CRC		*/
+
+/*
+ *  フレーム長 (Ethernet ヘッダと CRC を含む)
+ */
+
+#define ETHER_MIN_LEN		64
+#define ETHER_MAX_LEN		(IF_MTU + sizeof(T_ETHER_HDR) + ETHER_CRC_LEN)
+
+/*
+ *  Ethernet ヘッダ
+ */
+
+#ifndef IF_ETHER_NIC_HDR_ALIGN
+#error IF_ETHER_NIC_HDR_ALIGN expected.
+#endif	/* of #ifndef IF_ETHER_NIC_HDR_ALIGN */
+
+#if defined(__RX)
+#pragma pack
+#elif defined(_MSC_VER)
+#pragma pack(push, 1)
+#endif
+
+#if defined(__RX) || defined(_MSC_VER)
+
+typedef struct t_ether_header {
+
+#if IF_ETHER_NIC_HDR_ALIGN != 0
+
+	uint8_t		align[IF_ETHER_NIC_HDR_ALIGN];	/* アライン調整 */
+
+#endif	/* of #if IF_ETHER_NIC_HDR_ALIGN != 0 */
+
+	uint8_t		dhost[ETHER_ADDR_LEN];
+	uint8_t		shost[ETHER_ADDR_LEN];
+	uint16_t	type;
+	} T_ETHER_HDR;
+
+#elif defined(TOPPERS_S810_CLG3_85)	/* of #if defined(__RX) */
+
+typedef struct t_ether_header {
+
+#if IF_ETHER_NIC_HDR_ALIGN != 0
+
+	uint8_t		align[IF_ETHER_NIC_HDR_ALIGN];	/* アライン調整 */
+
+#endif	/* of #if IF_ETHER_NIC_HDR_ALIGN != 0 */
+
+	uint8_t		dhost[ETHER_ADDR_LEN];
+	uint8_t		shost[ETHER_ADDR_LEN];
+	uint16_t	type;
+	} T_ETHER_HDR;
+
+#else	/* of #if defined(__RX) */
+
+typedef struct t_ether_header {
+
+#if IF_ETHER_NIC_HDR_ALIGN != 0
+
+	uint8_t		align[IF_ETHER_NIC_HDR_ALIGN];	/* アライン調整 */
+
+#endif	/* of #if IF_ETHER_NIC_HDR_ALIGN != 0 */
+
+	uint8_t		dhost[ETHER_ADDR_LEN];
+	uint8_t		shost[ETHER_ADDR_LEN];
+	uint16_t	type;
+	} __attribute__((packed, aligned(2))) T_ETHER_HDR;
+
+#endif	/* of #if defined(__RX) */
+
+#define GET_ETHER_HDR(nbuf)		((T_ETHER_HDR*)((nbuf)->buf))
+
+/*
+ *  MAC アドレスの定義
+ */
+
+#define ETHER_MCAST_ADDR	UINT_C(0x01)	/* マルチキャスト・アドレス	*/
+#define ETHER_LOCAL_ADDR	UINT_C(0x02)	/* ローカル・アドレス		*/
+
+typedef struct t_ether_addr {
+	uint8_t		lladdr[ETHER_ADDR_LEN];
+	} __attribute__((packed, aligned(2))) T_ETHER_ADDR;
+
+#if defined(__RX)
+#pragma packoption
+#elif defined(_MSC_VER)
+#pragma pack(pop)
+#endif
+
+/*
+ *  Type フィールド
+ */
+
+#define ETHER_TYPE_IP		UINT_C(0x0800)	/* IPv4	*/
+#define ETHER_TYPE_ARP		UINT_C(0x0806)	/* ARP	*/
+#define ETHER_TYPE_IPV6		UINT_C(0x86dd)	/* IPv6	*/
+
+/*
+ *  インタフェースの選択マクロ
+ */
+
+#define T_IF_HDR		T_ETHER_HDR		/* インタフェースのヘッダ				*/
+#define T_IF_ADDR		T_ETHER_ADDR		/* インタフェースのアドレス			*/
+#define IF_HDR_ALIGN		2			/* ヘッダのアライン単位				*/
+#define IF_MTU			1500			/* インタフェースの MTU				*/
+#define IF_MIN_LEN		ETHER_MIN_LEN		/* インターフェースフレームの最短長		*/
+
+#define IF_OUTPUT(o,d,g,t)	ether_output(o,d,g,t)	/* インタフェースの出力関数			*/
+#define IF_RAW_OUTPUT(o,t)	ether_raw_output(o,t)	/* インタフェースの出力関数、アドレス解決無し	*/
+#define IF_SET_PROTO(b,p)	(GET_ETHER_HDR(b)->type = htons(p))
+							/* インタフェースのプロトコル設定関数		*/
+#define IF_SOFTC_TO_IFADDR(s)	((T_IF_ADDR*)(s)->ifaddr.lladdr)
+							/* ソフトウェア情報から MAC アドレスを取り出す	*/
+#define IF_GET_IFNET()		ether_get_ifnet()	/* ネットワークインタフェース構造体を返す。		*/
+#define IF_TYPE			IFT_ETHER		/* インタフェースの型				*/
+#define IF_SRAND()		ether_srand()	/* インタフェースの乱数初期値			*/
+
+/* IPv4 関係 */
+
+#define IF_PROTO_IP		ETHER_TYPE_IP		/* インタフェースの IPv4 プロトコル指定		*/
+#define IF_PROTO_ARP		ETHER_TYPE_ARP		/* インタフェースの ARP プロトコル指定		*/
+
+/* IPv6 関係 */
+
+#define MAX_IF_MADDR_CNT	2			/* インタフェースのマルチキャストアドレス配列の最大サイズ	*/
+#define IF_MADDR_INIT		{ { { 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0 } } }
+							/* インタフェースのマルチキャストアドレス配列の初期化	*/
+#define IF_PROTO_IPV6		ETHER_TYPE_IPV6		/* インタフェースの IPv6 プロトコル指定			*/
+#define IF_ADDMULTI(s)		IF_ETHER_NIC_ADDMULTI(s)
+							/* マルチキャストアドレスの登録				*/
+#define IF_IN6_NEED_CACHE(i)	(true)			/* 近隣探索キャッシュを使用する。				*/
+#define IF_IN6_IFID(i,a)	IF_ETHER_NIC_IN6_IFID(i,a)
+							/* インタフェース識別子の設定				*/
+#define IF_IN6_RESOLVE_MULTICAST(i,m)	\
+				ether_in6_resolve_multicast(i,m)
+							/* インタフェースのマルチキャストアドレスへの変換		*/
+
+#define IF_FLAG_UP				0x01U
+#define IF_FLAG_LINK_UP			0x10U
+
+/*
+ *  前方参照
+ */
+
+#ifndef T_IFNET_DEFINED
+
+typedef struct t_ifnet T_IFNET;
+
+#define T_IFNET_DEFINED
+
+#endif	/* of #ifndef T_IFNET_DEFINED */
+
+#ifndef T_IF_SOFTC_DEFINED
+
+typedef struct t_if_softc T_IF_SOFTC;
+
+#define T_IF_SOFTC_DEFINED
+
+#endif	/* of #ifndef T_IF_SOFTC_DEFINED */
+
+#ifndef T_IN4_ADDR_DEFINED
+
+typedef uint32_t T_IN4_ADDR;
+
+#define T_IN4_ADDR_DEFINED
+
+#endif	/* of #ifndef T_IN4_ADDR_DEFINED */
+
+#ifndef T_NET_BUF_DEFINED
+
+typedef struct t_net_buf T_NET_BUF;
+
+#define T_NET_BUF_DEFINED
+
+#endif	/* of #ifndef T_NET_BUF_DEFINED */
+
+/*
+ *  ネットワークインタフェースに依存しないソフトウェア情報
+ */
+
+#ifdef T_IF_ETHER_NIC_SOFTC
+
+struct t_if_softc {
+	T_IF_ADDR		ifaddr;			/* ネットワークインタフェースのアドレス	*/
+	uint16_t		timer;			/* 送信タイムアウト			*/
+	T_IF_ETHER_NIC_SOFTC	*sc;			/* ディバイス依存のソフトウェア情報	*/
+	ID			semid_txb_ready;	/* 送信セマフォ				*/
+	ID			semid_rxb_ready;	/* 受信セマフォ				*/
+
+#ifdef _IP6_CFG
+
+	T_IF_ADDR 	maddrs[MAX_IF_MADDR_CNT];	/* マルチキャストアドレスリスト	*/
+
+#endif	/* of #ifdef _IP6_CFG */
+	};
+
+#endif	/* of #ifdef T_IF_ETHER_NIC_SOFTC */
+
+/*
+ *  変数
+ */
+
+#ifdef ETHER_CFG_COLLECT_ADDR
+
+T_ETHER_ADDR ether_collect_addr;
+
+#endif	/* of #ifdef ETHER_CFG_COLLECT_ADDR */
+
+/*
+ *  関数
+ */
+
+#ifdef _IP6_CFG
+
+/* 前方参照 */
+
+#ifndef T_IN6_ADDR_DEFINED
+
+typedef struct t_in6_addr T_IN6_ADDR;
+
+#define T_IN6_ADDR_DEFINED
+
+#endif	/* of #ifndef T_IN6_ADDR_DEFINED */
+
+extern ER ether_in6_resolve_multicast(T_ETHER_ADDR *ifaddr, const T_IN6_ADDR *maddr);
+
+#endif	/* of #ifdef _IP6_CFG */
+
+extern T_IFNET *ether_get_ifnet (void);
+extern ER ether_output (T_NET_BUF *data, const void *dst, T_IF_ADDR *gw, TMO tmout);
+extern ER ether_raw_output (T_NET_BUF *data, TMO tmout);
+extern uint32_t ether_srand (void);
+
+typedef void (*ether_status_callback_fn)(T_IFNET *ether);
+extern void ether_set_link_callback(ether_status_callback_fn link_callback);
+extern void ether_set_link_up();
+extern void ether_set_link_down();
+extern void ether_set_up();
+extern void ether_set_down();
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#endif	/* of #ifndef _ETHERNET_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/fcstab.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/fcstab.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/fcstab.c	(revision 398)
@@ -0,0 +1,34 @@
+static UH 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,
+	};
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/genfcstab.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/genfcstab.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/genfcstab.c	(revision 398)
@@ -0,0 +1,32 @@
+/*
+ * Generate a FCS table for the HDLC FCS (RFC1171).
+ *
+ * Drew D. Perkins at Carnegie Mellon University.
+ *
+ * Code liberally borrowed from Mohsen Banan and D. Hugh Redelmeier.
+ */
+
+#include <stdio.h>
+
+/* The HDLC polynomail: X**0 + X**5 + X**12 + X**16 (0x8408) */
+
+#define Polynomial	0x8408
+
+int
+main (int argc, char *argv[])
+{
+	unsigned int	count, octet;
+	int		bit;
+
+	printf("%s = {\n", argv[1]);
+	for (count = 0; count < 256; count ++) {
+		octet = count;
+		for (bit = 8; bit-- > 0; )
+			octet = (octet & 0x01) ? ((octet >> 1) ^ Polynomial) : (octet >> 1);
+		printf("%c0x%04x,", count % 8 ? ' ' : '\t', octet & 0xffff);
+		if (count % 8 == 7)
+			putchar('\n');
+		}
+	fputs("\t};\n", stdout);
+	return 0;
+	}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if.c	(revision 398)
@@ -0,0 +1,182 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1980, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)if.c	8.3 (Berkeley) 1/4/94
+ * $FreeBSD: src/sys/net/if.c,v 1.64.2.1 1999/08/29 16:28:14 peter Exp $
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#include <netinet6/in6.h>
+#include <netinet6/in6_var.h>
+
+#include <net/if_var.h>
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  関数
+ */
+
+static void if_slowtimo (void *ignore);
+
+/*
+ *  if_slowtimo -- インタフェースのワッチドッグタイマ制御
+ */
+
+static void
+if_slowtimo (void *ignore)
+{
+	T_IF_SOFTC	*ic;
+
+	ic = IF_ETHER_NIC_GET_SOFTC();
+
+	if (ic->timer > 0) {
+		ic->timer --;
+		if (ic->timer == 0)
+			IF_ETHER_NIC_WATCHDOG(ic);
+		}
+	timeout(if_slowtimo, NULL, IF_TIMER_TMO);
+	}
+
+/*
+ *  ifinit -- インタフェース管理の初期化
+ */
+
+void
+ifinit (void)
+{
+	timeout(if_slowtimo, NULL, IF_TIMER_TMO);
+	}
+
+#endif /* of #ifdef SUPPORT_ETHER */
+
+#ifdef _IP6_CFG
+
+/*
+ *  if_addmulti -- マルチキャストアドレスの登録
+ */
+
+ER
+if_addmulti (T_IFNET *ifp, void *maddr, uint8_t type)
+{
+#if MAX_IF_MADDR_CNT > 0
+
+	T_IF_ADDR	llmaddr;
+	ER		error = E_OK;
+	int_t		ix;
+
+	if (type == AT_INET6) {
+
+		if ((ix = in6_addr2maix((T_IN6_ADDR*)maddr)) == IPV6_MADDR_IX_EXTRA)
+			return E_PAR;
+
+		/* IPv6 マルチキャストアドレスを登録する。*/
+		ifp->in6_maddrs[ix] = *(T_IN6_ADDR*)maddr;
+
+		/* インタフェースのアドレスに変換し、登録する。*/
+		error = IF_IN6_RESOLVE_MULTICAST(&llmaddr, (T_IN6_ADDR*)maddr);
+		if (error != E_OK)
+			return error;
+		ifp->ic->maddrs[ix] = llmaddr;
+		}
+
+	return IF_ADDMULTI(ifp->ic);
+
+#else	/* of #if MAX_IF_MADDR_CNT > 0 */
+
+	return E_OK;
+
+#endif	/* of #if MAX_IF_MADDR_CNT > 0 */
+	}
+
+#endif	/* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if.h	(revision 398)
@@ -0,0 +1,108 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)if.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if.h,v 1.49.2.1 1999/08/29 16:28:15 peter Exp $
+ */
+
+#ifndef _IF_H_
+#define _IF_H_
+
+/*
+ *  ネットワークインタフェース用タイマの定義
+ */
+
+#define IF_TIMER_TMO		NET_TIMER_HZ	/* タイムアウト、1 [s]	*/
+#define IF_TIMER_HZ		1		/* タイマの周波数、1 [s]	*/
+
+/*
+ *  ネットワークインタフェースのフラグ
+ */
+
+#define IFF_UP			UINT_C(0x0001)	/* 起動済み		*/
+#define IFF_RUNNING		UINT_C(0x0002)	/* 動作中		*/
+
+/*
+ *  汎用定義
+ */
+
+#define IF_HDR_SIZE		(sizeof(T_IF_HDR))
+#define IF_PDU_SIZE		(IF_HDR_SIZE + IF_MTU)	/* Protocol Data Unit */
+
+/*
+ *  関数
+ */
+
+#ifdef SUPPORT_ETHER
+
+extern void ifinit (void);
+
+#else	/* of #ifdef SUPPORT_ETHER */
+
+#define ifinit
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#endif	/* of #ifndef _IF_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if6_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if6_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if6_var.h	(revision 398)
@@ -0,0 +1,142 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#ifndef _IF6_VAR_H_
+#define _IF6_VAR_H_
+
+/*
+ *  ネットワークインタフェース構造体
+ */
+
+#if defined(_IP6_CFG)
+
+#if defined(_IP4_CFG)
+
+struct t_ifnet {
+	T_IF_SOFTC	*ic;		/* ネットワークインタフェースのソフトウェア情報	*/
+	T_IN6_IFADDR 	in6_ifaddrs[NUM_IN6_IFADDR_ENTRY];
+					/* IPv6 アドレス情報				*/
+	T_IN6_ADDR	in6_maddrs [MAX_IN6_MADDR_CNT];
+					/* マルチキャスト IPv6 アドレス			*/
+	T_IN4_IFADDR 	in4_ifaddr;	/* IPv4 アドレス情報				*/
+	ether_status_callback_fn link_callback;
+	uint8_t		flags;		/* フラグ					*/
+	};
+
+#else	/* of #if defined(_IP4_CFG) */
+
+struct t_ifnet {
+	T_IF_SOFTC	*ic;		/* ネットワークインタフェースのソフトウェア情報	*/
+	T_IN6_IFADDR 	in6_ifaddrs[NUM_IN6_IFADDR_ENTRY];
+					/* IPv6 アドレス情報				*/
+	T_IN6_ADDR	in6_maddrs [MAX_IN6_MADDR_CNT];
+					/* マルチキャスト IPv6 アドレス			*/
+	ether_status_callback_fn link_callback;
+	uint8_t		flags;		/* フラグ					*/
+	};
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+struct t_ifnet {
+	T_IF_SOFTC	*ic;		/* ネットワークインタフェースのソフトウェア情報	*/
+	T_IN4_IFADDR 	in4_ifaddr;	/* IPv4 アドレス情報				*/
+	ether_status_callback_fn link_callback;
+	uint8_t		flags;		/* フラグ					*/
+	};
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#ifndef T_IFNET_DEFINED
+
+typedef struct t_ifnet T_IFNET;
+
+#define T_IFNET_DEFINED
+
+#endif	/* of #ifndef T_IFNET_DEFINED */
+
+#if defined(_IP6_CFG)
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+#define ND6_IFPTOMAC(i)		(IF_SOFTC_TO_IFADDR((i)->ic))
+
+/*
+ *  関数
+ */
+
+extern ER if_addmulti (T_IFNET *ifp, void *maddr, uint8_t type);
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#endif	/* of #ifndef _IF6_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_arp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_arp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_arp.h	(revision 398)
@@ -0,0 +1,137 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)if_arp.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if_arp.h,v 1.10.2.3 1999/11/19 09:30:31 julian Exp $
+ */
+
+#ifndef _IF_ARP_H_
+#define _IF_ARP_H_
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  Address Resolution Protocol.
+ *
+ *  RFC 826 参照
+ */
+
+/*
+ *  構造体
+ */
+
+/* ARP ヘッダ */
+
+typedef struct t_arp_hdr {
+	uint16_t	hrd_addr;	/* 物理アドレスフォーマット	*/
+	uint16_t	proto;		/* プロトコル			*/
+	uint8_t		hdr_len;	/* 物理アドレス長		*/
+	uint8_t		proto_len;	/* プロトコル長			*/
+	uint16_t	opcode;		/* 命令コード			*/
+	} __attribute__((packed, aligned(2))) T_ARP_HDR;
+
+#define ARP_HDR_SIZE			(sizeof(T_ARP_HDR))
+#define IF_ARP_HDR_SIZE			(IF_HDR_SIZE + ARP_HDR_SIZE)
+
+#define GET_ARP_HDR(nbuf)		((T_ARP_HDR*)((nbuf)->buf + IF_HDR_SIZE))
+
+#define GET_IF_ARP_HDR_SIZE(nbuf)	(IF_HDR_SIZE + ARP_HDR_SIZE)
+
+/* hrd_addr、物理アドレスフォーマットの値 */
+
+#define ARPHRD_ETHER	1	/* Ethernet	*/
+
+/* opcode, 命令コードの値 */
+
+#define ARPOP_REQUEST		UINT_C(1)	/* アドレス解決要求		*/
+#define ARPOP_REPLY		UINT_C(2)	/* アドレス解決応答		*/
+#define ARPOP_REV_REQUEST	UINT_C(3)	/* プロトコル・アドレス解決要求	*/
+#define ARPOP_REV_REPLY		UINT_C(4)	/* プロトコル・アドレス解決要求	*/
+#define ARPOP_INV_REQUEST	UINT_C(8)	/* 終端識別要求			*/
+#define ARPOP_INV_REPLY		UINT_C(9)	/* 終端識別要求			*/
+
+/*
+ *  イーサネットドライバモジュールで使用される ARP 情報
+ */
+
+typedef struct arpcom {
+	uint8_t		mac_addr[ETHER_ADDR_LEN];
+	} __attribute__((packed, aligned(2))) T_ARPCOM;
+
+/*
+ *  ARP キャッシュ更新タイマの定義
+ */
+
+#define ARP_TIMER_TMO		(60*NET_TIMER_HZ)	/* タイムアウト、60 [s]	*/
+
+/*
+ *  変数
+ */
+
+extern const uint8_t	ether_broad_cast_addr[ETHER_ADDR_LEN];
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#endif	/* of #ifndef _IF_ARP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_llc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_llc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_llc.h	(revision 398)
@@ -0,0 +1,109 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *      @(#)if_llc.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if_llc.h,v 1.6.4.1 1999/08/29 16:28:18 peter Exp $
+ */
+
+#ifndef _IF_LLC_H_
+#define _IF_LLC_H_
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  長さの定義
+ */
+
+#define SNAP_ORG_LEN		3
+#define SNAP_TYPE_LEN		2
+
+/*
+ *  802.3 ヘッダ
+ */
+
+typedef struct t_8023mac_header {
+	uint8_t		dhost[ETHER_ADDR_LEN];
+	uint8_t		shost[ETHER_ADDR_LEN];
+	uint16_t	len;
+	} __attribute__((packed, aligned(2)))T_8023MAC_HDR;
+
+typedef struct t_8022llc_header {
+	uint8_t		dsap;
+	uint8_t		ssap;
+	uint8_t		control;
+	} __attribute__((packed, aligned(2)))T_8022LLC_HDR;
+
+typedef struct t_8022snap_header {
+	uint8_t		original[SNAP_ORG_LEN];
+	uint8_t		type[SNAP_TYPE_LEN];
+	} __attribute__((packed, aligned(2)))T_8022SNAP_HDR;
+
+#define GET_8023MAC_HDR(nbuf)		((T_8023MAC_HDR*)((nbuf)->buf))
+#define GET_8022LLC_HDR(nbuf)		((T_8022LLC_HDR*)((nbuf)->buf + sizeof(T_8023MAC_HDR)))
+#define GET_8022SNAP_HDR(nbuf)		((T_8022SNAP_HDR*)((nbuf)->buf + sizeof(T_8023MAC_HDR) + sizeof(T_8022LLC_HDR)))
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#endif	/* of #ifndef _IF_LLC_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_loop.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_loop.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_loop.c	(revision 398)
@@ -0,0 +1,231 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)if_loop.c	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/net/if_loop.c,v 1.37.2.1 1999/08/29 16:28:19 peter Exp $
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+
+#include <net/if_var.h>
+
+#ifdef SUPPORT_LOOP
+
+/*
+ *  ローカルループバックインタフェース
+ */
+
+/*
+ *  外部関数の定義
+ */
+
+extern const char *itron_strerror (ER ercd);
+
+/*
+ *  変数
+ */
+
+/* ネットワークインタフェース構造体 */
+
+#if defined(_IP6_CFG)
+
+static T_IFNET loop_ifnet = {
+	NULL,			/* ネットワークインタフェースのソフトウェア情報	*/
+	{},			/* IPv6 アドレス情報				*/
+	{},			/* マルチキャスト IPv6 アドレス			*/
+	};
+
+#elif defined(_IP4_CFG)	/* of #if defined(_IP6_CFG) */
+
+static T_IFNET loop_ifnet = {
+	NULL,			/* ネットワークインタフェースのソフトウェア情報	*/
+	{
+		IPV4_ADDR_LOOPBACK,		/* IPv4 アドレス			*/
+		IPV4_ADDR_LOOPBACK_MASK,	/* サブネットマスク			*/
+		},
+	};
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+/*
+ *  loop_get_ifnet -- ネットワークインタフェース構造体を返す。
+ */
+
+T_IFNET *
+loop_get_ifnet (void)
+{
+	return &loop_ifnet;
+	}
+
+/*
+ *  looutput -- ローカルループバックインタフェースの出力関数
+ */
+
+ER
+looutput (T_NET_BUF *output, TMO tmout)
+{
+	ER error;
+
+	NET_COUNT_LOOP(net_count_loop.out_octets,  output->len);
+	NET_COUNT_LOOP(net_count_loop.out_packets, 1);
+
+	if ((error = tsnd_dtq(DTQ_LOOP_OUTPUT, output, tmout)) != E_OK)
+		syslog(LOG_NOTICE, "[LOOP] drop error: %s", itron_strerror(error));
+	return error;
+	}
+
+/*
+ *  ローカルループバックインタフェース・出力タスク
+ */
+
+void
+if_loop_output_task (intptr_t exinf)
+{
+	T_NET_BUF	*output;
+	ER		error;
+	ID		tskid;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[LOOP OUTPUT:%d] started.", tskid);
+	while (true) {
+		if (rcv_dtq(DTQ_LOOP_OUTPUT, (intptr_t*)&output) == E_OK) {
+			NET_COUNT_LOOP(net_count_loop.in_octets,  output->len);
+			NET_COUNT_LOOP(net_count_loop.in_packets, 1);
+			if ((error = snd_dtq(DTQ_LOOP_INPUT, output)) != E_OK)
+				syslog(LOG_NOTICE, "[LOOP OUTPUT] drop error: %s", itron_strerror(error));
+			}
+		}
+	}
+
+/*
+ *  ローカルループバックインタフェース・入力タスク
+ */
+
+void
+if_loop_input_task (intptr_t exinf)
+{
+	T_NET_BUF	*input;
+	ID		tskid;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[LOOP INPUT:%d] started.", tskid);
+	while (true) {
+		if (rcv_dtq(DTQ_LOOP_INPUT, (intptr_t)&input) == E_OK) {
+			NET_COUNT_LOOP(net_count_loop.in_octets,  input->len);
+			NET_COUNT_LOOP(net_count_loop.in_packets, 1);
+
+#if defined(_IP4_CFG)
+
+			/* IPv4 入力関数を呼び出す */
+			if (IP4_VHL_V(GET_IP4_HDR(input)->vhl) == IPV4_VERSION)
+				ip_input(input);
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG)
+
+			/* IPv6 入力関数を呼び出す */
+			if (IP6_VCF_V(ntohl(GET_IP6_HDR(input)->vcf)) == IPV6_VERSION)
+				ip6_input(input);
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+			}
+		}
+	}
+
+#endif	/* of #ifdef SUPPORT_LOOP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_loop.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_loop.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_loop.cfg	(revision 398)
@@ -0,0 +1,61 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ループバックインタフェース・コンフィギュレーションファイル
+ */
+
+#ifdef SUPPORT_LOOP
+
+CRE_TSK(LOOP_OUTPUT_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	if_loop_output_task,
+	LOOP_OUTPUT_PRIORITY,
+	LOOP_OUTPUT_STACK_SIZE,
+	NULL
+	});
+
+CRE_TSK(LOOP_INPUT_TASK,  {
+	TA_HLNG|TA_ACT,
+	0,
+	if_loop_input_task,
+	LOOP_INPUT_PRIORITY,
+	LOOP_INPUT_STACK_SIZE,
+	NULL
+	});
+
+CRE_DTQ(DTQ_LOOP_OUTPUT,  { TA_TFIFO, NUM_DTQ_LOOP_OUTPUT, NULL });
+CRE_DTQ(DTQ_LOOP_INPUT,   { TA_TFIFO, NUM_DTQ_LOOP_INPUT,  NULL });
+
+#endif	/* of #ifdef SUPPORT_LOOP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_loop.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_loop.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_loop.h	(revision 398)
@@ -0,0 +1,154 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ */
+
+#ifndef _IF_LOOP_H_
+#define _IF_LOOP_H_
+
+#ifdef SUPPORT_LOOP
+
+/*
+ *  ローカルループバックインタフェース・ヘッダとアドレス
+ */
+
+typedef struct t_loop_hdr  { } T_LOOP_HDR;
+typedef struct t_loop_addr { } T_LOOP_ADDR;
+
+/*
+ *  インタフェースの選択マクロ
+ */
+
+#define T_IF_HDR		T_LOOP_HDR		/* インタフェースのヘッダ	*/
+#define T_IF_ADDR		T_LOOP_ADDR		/* インタフェースのアドレス	*/
+#define IF_HDR_ALIGN		4			/* ヘッダのアライン単位		*/
+#define IF_MTU			LOMTU			/* インタフェースの MTU		*/
+
+#define IF_OUTPUT(o,d,g,t)	looutput(o,t)		/* インタフェースの出力関数	*/
+#define IF_RAW_OUTPUT(o,t)	looutput(o,t)		/* インタフェースの出力関数、アドレス解決無し*/
+#define IF_SET_PROTO(b,p)				/* インタフェースのプロトコル設定関数	*/
+#define IF_GET_IFNET()		loop_get_ifnet()	/* ネットワークインタフェース構造体を返す。		*/
+#define IF_SRAND()		(0)			/* インターフェースの乱数初期値			*/
+
+/* IPv4 関係 */
+
+#define IF_PROTO_IP		0			/* インタフェースの IP プロトコル指定		*/
+
+/* IPv6 関係 */
+
+#define MAX_IF_MADDR_CNT	0			/* インタフェースのマルチキャストアドレス配列の最大サイズ	*/
+#define IF_IN6_NEED_CACHE(i)	(false)			/* 近隣探索キャッシュを使用する。				*/
+
+/*
+ *  前方参照
+ */
+
+#ifndef T_NET_BUF_DEFINED
+
+typedef struct t_net_buf T_NET_BUF;
+
+#define T_NET_BUF_DEFINED
+
+#endif	/* of #ifndef T_NET_BUF_DEFINED */
+
+#ifndef T_IF_SOFTC_DEFINED
+
+typedef struct t_if_softc T_IF_SOFTC;
+
+#define T_IF_SOFTC_DEFINED
+
+#endif	/* of #ifndef T_IF_SOFTC_DEFINED */
+
+#ifndef T_IFNET_DEFINED
+
+typedef struct t_ifnet T_IFNET;
+
+#define T_IFNET_DEFINED
+
+#endif	/* of #ifndef T_IFNET_DEFINED */
+
+/*
+ *  ネットワークインタフェースに依存しないソフトウェア情報
+ */
+
+struct t_if_softc { };
+
+/*
+ *  関数
+ */
+
+extern T_IFNET *loop_get_ifnet (void);
+ER looutput (T_NET_BUF *output, TMO tmout);
+
+/*
+ *  ローカルループバックインタフェース・処理タスク
+ */
+
+extern void	if_loop_output_task(intptr_t exinf);
+extern void	if_loop_input_task(intptr_t exinf);
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+#endif	/* of #ifndef _IF_LOOP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_ppp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_ppp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_ppp.h	(revision 398)
@@ -0,0 +1,157 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * 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.
+ *
+ * $FreeBSD: src/sys/net/if_ppp.h,v 1.13.2.1 1999/08/29 16:28:21 peter Exp $
+ */
+
+#ifndef _IF_PPP_H_
+#define _IF_PPP_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  PPP アドレスの定義（ダミー）
+ */
+
+typedef struct t_ppp_addr {
+	uint8_t		lladdr[0];
+	} T_PPP_ADDR;
+
+/*
+ *  インタフェースの選択マクロ
+ */
+
+#define T_IF_HDR		T_PPP_HDR		/* インタフェースのヘッダ		*/
+#define T_IF_ADDR		T_PPP_ADDR		/* インタフェースのアドレス			*/
+#define IF_HDR_ALIGN		2			/* ヘッダのアライン単位			*/
+#define IF_MTU			DEF_PPP_MTU		/* インタフェースの MTU			*/
+
+#define IF_OUTPUT(o,d,g,t)	ppp_output(o,t)		/* インタフェースの出力関数		*/
+#define IF_RAW_OUTPUT(o,t)	ppp_output(o,t)		/* インタフェースの出力関数、アドレス解決無し*/
+#define IF_SET_PROTO(b,p)	(*GET_PPP_HDR(b) = htons(p))
+							/* インタフェースのプロトコル設定関数	*/
+#define IF_SOFTC_TO_IFADDR(s)	((T_IF_ADDR*)(s)->ifaddr.lladdr)
+							/* ソフトウェア情報から PPP アドレスを取り出す	*/
+#define IF_GET_IFNET()		ppp_get_ifnet()		/* ネットワークインタフェース構造体を返す。*/
+#define IF_SRAND()		(0)			/* インターフェースの乱数初期値			*/
+
+/* IPv4 関係 */
+
+#define IF_PROTO_IP		PPP_IP			/* インタフェースの IPv4 プロトコル指定	*/
+
+/* IPv6 関係 */
+
+#define MAX_IF_MADDR_CNT	0			/* インタフェースのマルチキャストアドレス配列の最大サイズ*/
+#define IF_PROTO_IPV6		PPP_IPV6		/* インタフェースの IPv6 プロトコル指定	*/
+#define IF_IN6_NEED_CACHE(i)	(false)			/* 近隣探索キャッシュを使用する。	*/
+#define IF_IN6_IFID(i,a)	get_rand_ifid(i,a)	/* インタフェース識別子の設定		*/
+#define IF_IN6_RESOLVE_MULTICAST(i,m)	{}		/* インタフェースのマルチキャストアドレスへの変換		*/
+
+/*
+ *  MTU (MRU) に関する定義
+ */
+
+#define DEF_PPP_MTU		1500	/* PPP の 標準 MTU	*/
+#define MAX_PPP_MTU		16384	/* PPP の 最大 MTU	*/
+#define MIN_PPP_MTU		128	/* PPP の 最小 MTU	*/
+
+/*
+ *  PPP ヘッダ
+ */
+
+typedef uint16_t T_PPP_HDR;				/* 上位プロトコル		*/
+
+/*
+ *  前方参照
+ */
+
+#ifndef T_IFNET_DEFINED
+
+typedef struct t_ifnet T_IFNET;
+
+#define T_IFNET_DEFINED
+
+#endif	/* of #ifndef T_IFNET_DEFINED */
+
+#ifndef T_IF_SOFTC_DEFINED
+
+typedef struct t_if_softc T_IF_SOFTC;
+
+#define T_IF_SOFTC_DEFINED
+
+#endif	/* of #ifndef T_IF_SOFTC_DEFINED */
+
+#ifndef T_NET_BUF_DEFINED
+
+typedef struct t_net_buf T_NET_BUF;
+
+#define T_NET_BUF_DEFINED
+
+#endif	/* of #ifndef T_NET_BUF_DEFINED */
+
+/*
+ *  ネットワークインタフェースに依存しないソフトウェア情報
+ */
+
+struct t_if_softc {
+	T_IF_ADDR	ifaddr;		/* ネットワークインタフェースのアドレス	*/
+	};
+
+/*
+ *  関数
+ */
+
+extern T_IFNET *ppp_get_ifnet (void);
+ER ppp_output (T_NET_BUF *data, TMO tmout);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _IF_PPP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_types.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_types.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_types.h	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+/*-
+ * Copyright (c) 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 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.
+ *
+ *	@(#)if_types.h	8.3 (Berkeley) 4/28/95
+ * $FreeBSD: src/sys/net/if_types.h,v 1.23.6.1 2008/11/25 02:59:29 kensmith Exp $
+ * $NetBSD: if_types.h,v 1.16 2000/04/19 06:30:53 itojun Exp $
+ */
+
+#ifndef _IF_TYPES_
+#define _IF_TYPES_
+
+/*
+ *  インタフェースの型の定義
+ */
+
+#define IFT_ETHER	0x6	/* Ethernet CSMA/CD	*/
+
+#endif	/* of #ifndef _IF_TYPES_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/if_var.h	(revision 398)
@@ -0,0 +1,97 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#ifndef _IF_VAR_H_
+#define _IF_VAR_H_
+
+#include <net/if6_var.h>
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+typedef struct t_if_stats {
+	uint32_t	ifInOctets;
+	uint32_t	ifInUcastPkts;
+	uint32_t	ifInNUcastPkts;
+/*	uint32_t	ifInDiscards;*/
+	uint32_t	ifInErrors;
+	uint32_t	ifUnknownProtos;
+	uint32_t	ifOutOctets;
+	uint32_t	ifOutUcastPkts;
+	uint32_t	ifOutNUcastPkts;
+	uint32_t	ifOutDiscards;
+	uint32_t	ifOutErrors;
+/*	uint32_t	ifOutQlen;*/
+} T_IF_STATS;
+
+extern T_IF_STATS if_stats;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+#endif	/* of #ifndef _IF_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net.cfg	(revision 398)
@@ -0,0 +1,65 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  共通 汎用ネットワークコンフィギュレーションファイル
+ */
+
+/*
+ * ネットワークタイマ
+ */
+
+CRE_TSK(NET_TIMER_TASK, {
+		TA_HLNG,
+		0,
+		net_timer_task,
+		NET_TIMER_PRIORITY,
+		NET_TIMER_STACK_SIZE,
+		NULL
+		});
+
+CRE_CYC(NET_TIMER_HANDLER, {
+		TA_STA,
+		{ TNFY_HANDLER, 0, net_timer_handler },
+		NET_TIMER_CYCLE,
+		1
+		});
+
+/* ネットワークタイマの呼出しエントリ用セマフォ */
+
+CRE_SEM(SEM_CALL_OUT_LOCK,	{ TA_TPRI, 1, 1 });
+CRE_SEM(SEM_CALL_OUT_TIMEOUT,	{ TA_TPRI, 0, NUM_NET_CALLOUT });
+
+/* サポート関数 ip2str、ipv62str 用セマフォ */
+
+CRE_SEM(SEM_IP2STR_BUFF_LOCK,	{ TA_TPRI, 1, 1 });
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net.h	(revision 398)
@@ -0,0 +1,141 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#ifndef _NET_H_
+#define _NET_H_
+
+/*
+ *  プロトコルを識別するフラグに関する定義
+ *
+ *    ・統計情報
+ */
+
+#define PROTO_FLG_PPP_HDLC	ULONG_C(0x00000001)	/* ppp_hdlc.c	*/
+#define PROTO_FLG_PPP_FSM	ULONG_C(0x00000002)	/* ppp_fsm.c	*/
+#define PROTO_FLG_PPP_AUTH	ULONG_C(0x00000004)	/* ppp_auth.c	*/
+#define PROTO_FLG_PPP_LCP	ULONG_C(0x00000008)	/* ppp_lcp.c	*/
+#define PROTO_FLG_PPP_IPCP	ULONG_C(0x00000010)	/* ppp_ipcp.c	*/
+#define PROTO_FLG_PPP_IPV6CP	ULONG_C(0x00000020)	/* ppp_ipv6cp.c	*/
+#define PROTO_FLG_PPP_CCP	ULONG_C(0x00000040)	/* ppp_ccp.c	*/
+#define PROTO_FLG_PPP_PAP	ULONG_C(0x00000080)	/* ppp_upap.c	*/
+#define PROTO_FLG_PPP_MODEM	ULONG_C(0x00000100)	/* ppp_modem.c	*/
+#define PROTO_FLG_PPP		ULONG_C(0x00000200)	/* ppp.c	*/
+
+#define PROTO_FLG_ETHER_NIC	ULONG_C(0x00000001)	/* if_??.c	*/
+
+#define PROTO_FLG_LOOP		ULONG_C(0x00000100)	/* if_loop.c	*/
+
+#define PROTO_FLG_ETHER		ULONG_C(0x00000100)	/* ethernet.c	*/
+
+#define PROTO_FLG_IF		ULONG_C(0x00000800)	/* if.c		*/
+
+#define PROTO_FLG_ARP		ULONG_C(0x00008000)	/* if_ether.c	*/
+
+#define PROTO_FLG_IP4		ULONG_C(0x00010000)	/* ip_*.c	*/
+#define PROTO_FLG_ICMP4		ULONG_C(0x00040000)	/* ip_icmp.c	*/
+#define PROTO_FLG_IGMP		ULONG_C(0x00080000)	/* ip_igmp.c	*/
+
+#define PROTO_FLG_IP6		ULONG_C(0x00100000)	/* ip6_*.c	*/
+#define PROTO_FLG_ICMP6		ULONG_C(0x00400000)	/* icmp6.c	*/
+#define PROTO_FLG_ND6		ULONG_C(0x00800000)	/* nd6_*.c	*/
+
+#define PROTO_FLG_UDP		ULONG_C(0x08000000)	/* udp_*.c	*/
+
+#define PROTO_FLG_TCP		ULONG_C(0x01000000)	/* tcp_*.c	*/
+
+#define PROTO_FLG_NET_BUF	ULONG_C(0x10000000)	/* net_buf.c	*/
+#define PROTO_FLG_NET		ULONG_C(0x80000000)	/* route.c, net*.c	*/
+
+/*
+ *  アドレス形式の定義
+ */
+
+#define AT_ETHER		UINT_C(0x01)		/* イーサネット		*/
+#define AT_INET4		UINT_C(0x10)		/* IPv4 アドレス	*/
+#define AT_INET6		UINT_C(0x20)		/* IPv6 アドレス	*/
+
+/*
+ *  IPv4 UDPオプションの定義
+ */
+
+#define IP_MULTICAST_IF    32
+#define IP_MULTICAST_TTL   33
+#define IP_MULTICAST_LOOP  34
+#define IP_ADD_MEMBERSHIP  35
+#define IP_DROP_MEMBERSHIP 36
+#define IP_MSFILTER        41
+
+#if !defined(TOPPERS_MACRO_ONLY) && !defined(_MACRO_ONLY)
+
+/*
+ *  TINET 独自関数
+ */
+
+extern char *mac2str (char *buf, uint8_t *macaddr);
+
+#endif /* #if !defined(TOPPERS_MACRO_ONLY) && !defined(_MACRO_ONLY) */
+
+#endif	/* of #ifndef _NET_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_asp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_asp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_asp.cfg	(revision 398)
@@ -0,0 +1,174 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ASP用 汎用ネットワークコンフィギュレーションファイル
+ */
+
+/*
+ *  共通 汎用ネットワークコンフィギュレーションファイルのインクルード
+ */
+
+INCLUDE("net/net.cfg");
+
+#ifndef NOUSE_MPF_NET_BUF
+
+/*
+ * ネットワークバッファ
+ */
+
+#if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0
+CRE_MPF(MPF_NET_BUF_CSEG, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_CSEG,
+		sizeof(T_NET_BUF_CSEG),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0 */
+
+#if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0
+CRE_MPF(MPF_NET_BUF_64, {
+		TA_TFIFO, NUM_MPF_NET_BUF_64,
+		sizeof(T_NET_BUF_64),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0
+CRE_MPF(MPF_NET_BUF_128, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_128,
+		sizeof(T_NET_BUF_128),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0
+CRE_MPF(MPF_NET_BUF_256, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_256,
+		sizeof(T_NET_BUF_256),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0
+CRE_MPF(MPF_NET_BUF_512, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_512,
+		sizeof(T_NET_BUF_512),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0
+CRE_MPF(MPF_NET_BUF_IP_MSS, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_IP_MSS,
+		sizeof(T_NET_BUF_IP_MSS),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0 */
+
+#if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0
+CRE_MPF(MPF_NET_BUF_1024, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_1024,
+		sizeof(T_NET_BUF_1024),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0
+CRE_MPF(MPF_NET_BUF_IPV6_MMTU, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_IPV6_MMTU,
+		sizeof(T_NET_BUF_IPV6_MMTU),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0 */
+
+#if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0
+CRE_MPF(MPF_NET_BUF_IF_PDU, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_IF_PDU,
+		sizeof(T_NET_BUF_IF_PDU),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
+
+#if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0
+
+CRE_MPF(MPF_NET_BUF_REASSM, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF6_REASSM,
+		sizeof(T_NET_BUF6_REASSM),
+		NULL,
+		NULL
+		});
+
+#else /* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
+
+#if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0
+
+CRE_MPF(MPF_NET_BUF_REASSM, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF4_REASSM,
+		sizeof(T_NET_BUF4_REASSM),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0 */
+
+#endif	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
+
+#if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0
+CRE_MPF(MPF_NET_BUF6_65536, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF6_65536,
+		sizeof(T_NET_BUF6_65536),
+		NULL,
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0 */
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_buf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_buf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_buf.c	(revision 398)
@@ -0,0 +1,588 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+
+#ifndef NOUSE_MPF_NET_BUF
+
+/*
+ *  関数
+ */
+
+extern const char *itron_strerror (ER ercd);
+
+/*
+ *  変数
+ */
+
+static T_NET_BUF_ENTRY net_buf_table[] = {
+
+#if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0
+	{
+		MPF_NET_BUF6_65536,
+		IF_IP6_HDR_SIZE + 65536,
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF6_65536,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0 */
+
+#if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0
+
+	{
+		MPF_NET_BUF_REASSM,
+		IP6_CFG_FRAG_REASSM_SIZE,
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF6_REASSM,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+
+#else	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
+
+#if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0
+
+	{
+		MPF_NET_BUF_REASSM,
+		IP4_CFG_FRAG_REASSM_SIZE,
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF4_REASSM,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+
+#endif	/* of #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0 */
+
+#endif	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
+
+#if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0
+	{
+		MPF_NET_BUF_IF_PDU,
+		IF_PDU_SIZE,
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF_IF_PDU,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
+
+#if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0
+	{
+		MPF_NET_BUF_IPV6_MMTU,
+		IF_HDR_SIZE + IPV6_MMTU,
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF_IPV6_MMTU,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0 */
+
+#if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0
+	{
+		MPF_NET_BUF_1024,
+		UINT_C(1024),
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF_1024,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0
+	{
+		MPF_NET_BUF_IP_MSS,
+		IF_HDR_SIZE + IP4_MSS,
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF_IP_MSS,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0 */
+
+#if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0
+	{
+		MPF_NET_BUF_512,
+		UINT_C(512),
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF_512,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0
+	{
+		MPF_NET_BUF_256,
+		UINT_C(256),
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF_256,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0
+	{
+		MPF_NET_BUF_128,
+		UINT_C(128),
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF_128,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0 */
+
+#if defined(_IP6_CFG)
+
+#if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0
+	{
+		MPF_NET_BUF_CSEG,
+		IF_HDR_SIZE + IP_HDR_SIZE + TCP_HDR_SIZE,
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF_CSEG,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0 */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0
+	{
+		MPF_NET_BUF_64,
+		UINT_C(64),
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF_64,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0 */
+
+#if defined(_IP4_CFG) && !defined(_IP6_CFG)
+
+#if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0
+	{
+		MPF_NET_BUF_CSEG,
+		IF_HDR_SIZE + IP_HDR_SIZE + TCP_HDR_SIZE,
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+		NUM_MPF_NET_BUF_CSEG,
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+		},
+#endif	/* of #if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0 */
+
+#endif	/* of #if defined(_IP4_CFG) && !defined(_IP6_CFG) */
+
+	};
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+/*
+ *  nbuf_get_tbl -- ネットワークバッファ管理表を獲得する。
+ *
+ *    注意: ネットワーク統計情報の計測用
+ */
+
+const T_NET_BUF_ENTRY *
+nbuf_get_tbl (void)
+{
+	return net_buf_table;
+	}
+
+/*
+ *  nbuf_get_tbl_size -- ネットワークバッファ管理エントリ数を獲得する。
+ *
+ *    注意: ネットワーク統計情報の計測用
+ */
+
+uint_t
+nbuf_get_tbl_size (void)
+{
+	return sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
+	}
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+/*
+ *  tget_net_buf_up -- 大きなサイズの方向に探索して、ネットワークバッファを獲得する。
+ */
+
+static ER
+tget_net_buf_up (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, TMO tmout)
+{
+	int_t	ix, req_ix;
+	ER	error = E_OK;
+
+	/* 最適なサイズの固定長メモリプールを探す。*/
+	ix = sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
+	while (ix -- > 0 && minlen > net_buf_table[ix].size)
+		;
+	req_ix = ix;
+
+	NET_COUNT_NET_BUF(net_buf_table[req_ix].requests, 1);
+
+	while (1) {
+		if ((error = tget_mpf((ID)net_buf_table[ix].index, (void **)buf, ix == 0 ? tmout : TMO_POL)) == E_OK) {
+			(*buf)->idix  = (uint8_t)ix;
+			(*buf)->len   = (uint16_t)minlen;
+			(*buf)->flags = 0;
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+			NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
+			net_buf_table[ix].busies ++;
+#endif
+			return error;
+			}
+		ix --;
+		if (ix < 0 || net_buf_table[ix].size > maxlen)
+			break;
+		}
+
+	syslog(LOG_WARNING, "[BUF] busy, up   index:%d,%d[%4d], len:%4d.",
+	                    (uint16_t)req_ix, ix, net_buf_table[req_ix].size, minlen);
+	*buf = NULL;
+	NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
+	return error;
+	}
+
+/*
+ *  tget_net_buf_down -- 小さなサイズの方向に探索して、ネットワークバッファを獲得する。
+ */
+
+static ER
+tget_net_buf_down (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, TMO tmout)
+{
+	int_t	ix, req_ix;
+	ER	error = E_OK;
+
+	/* 最適なサイズの固定長メモリプールを探す。*/
+	ix = sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
+	while (ix -- > 0 && maxlen > net_buf_table[ix].size)
+		;
+	req_ix = ix;
+
+	NET_COUNT_NET_BUF(net_buf_table[req_ix].requests, 1);
+
+	while (1) {
+		if ((error = tget_mpf((ID)net_buf_table[ix].index, (void **)buf,
+		                      ix == sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY) - 1 ? tmout : TMO_POL)) == E_OK) {
+			(*buf)->idix  = (uint8_t)ix;
+			(*buf)->len   = net_buf_table[ix].size;
+			(*buf)->flags = 0;
+#ifdef IF_ETHER_MULTI_NIC
+			(*buf)->conn_pos = 0;
+#endif
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+			NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
+			net_buf_table[ix].busies ++;
+#endif
+			return error;
+			}
+		ix ++;
+		if (ix == sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY) || net_buf_table[ix].size < minlen)
+			break;
+		}
+
+	syslog(LOG_WARNING, "[BUF] busy, down index:%d,%d[%4d], len:%4d.",
+	                    (uint16_t)req_ix, ix, net_buf_table[req_ix].size, minlen);
+	*buf = NULL;
+	NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
+	return error;
+	}
+
+/*
+ *  tget_net_buf_ex -- ネットワークバッファを獲得する（拡張機能）。
+ */
+
+ER
+tget_net_buf_ex (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, ATR nbatr, TMO tmout)
+{
+	/* 最小サイズが最大サイズを超えていたらエラー */
+	if ((nbatr & NBA_SEARCH_DESCENT) != 0 && minlen > maxlen) {
+		syslog(LOG_WARNING, "[NET BUF] E_PAR, minlen=%4d > maxlen=%4d.", minlen, maxlen);
+		return E_PAR;
+		}
+
+	/* 割当て可能な最大のサイズを超えていたらエラー */
+	if (minlen > net_buf_table[0].size || maxlen > net_buf_table[0].size) {
+		syslog(LOG_WARNING, "[NET BUF] E_PAR, minlen=%4d or maxlen=%4d > %4d",
+		                    minlen, maxlen, net_buf_table[0].size);
+		return E_PAR;
+		}
+
+#if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE)
+
+	/* TCP で予約したネットワークバッファを取り出す。*/
+	if ((nbatr & NBA_RESERVE_TCP) != 0) {
+		if ((*buf = TCP_PULL_RES_NBUF(nbatr)) != NULL) {
+			return E_OK;
+			}
+		}
+
+#endif	/* of #if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE) */
+
+	if ((nbatr & NBA_SEARCH_DESCENT) != 0)
+		return tget_net_buf_down(buf, minlen, maxlen, tmout);
+	else if ((nbatr & NBA_SEARCH_ASCENT) != 0)
+		return tget_net_buf_up(buf, minlen, (uint_t)net_buf_table[0].size, tmout);
+	else {
+		syslog(LOG_WARNING, "[NET BUF] E_PAR, nbatr=%08x.", nbatr);
+		return E_PAR;
+		}
+	}
+
+/*
+ *  tget_net_buf -- ネットワークバッファを獲得する（互換）。
+ */
+
+ER
+tget_net_buf (T_NET_BUF **buf, uint_t len, TMO tmout)
+{
+	return tget_net_buf_ex(buf, len, (uint_t)net_buf_table[0].size, NBA_SEARCH_ASCENT, tmout);
+	}
+
+/*
+ * rel_net_buf -- ネットワークバッファを返却する。
+ */
+
+ER
+rel_net_buf (T_NET_BUF *buf)
+{
+	ER	error = E_OK;
+
+	/* ネットワークバッファの ID の正当性を検証する。*/
+	if ((int_t)buf->idix >= (int_t)(sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY))) {
+		syslog(LOG_WARNING, "[NET BUF] E_ID, ID=%d.", buf->idix);
+		error = E_ID;
+		}
+	else {
+
+#if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE)
+
+		/* TCP で、ネットワークバッファを予約する。*/
+		if (TCP_PUSH_RES_NBUF(buf) == NULL)
+			return E_OK;
+
+#endif	/* of #if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE) */
+
+		/* 固定メモリプールに返す。*/
+
+		int idix = buf->idix;
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+		net_buf_table[idix].busies --;
+#endif
+		if ((error = rel_mpf((ID)net_buf_table[idix].index, buf)) != E_OK) {
+			syslog(LOG_WARNING, "[NET BUF] %s, ID=%d.", itron_strerror(error), idix);
+			}
+		}
+	return error;
+	}
+
+/*
+ * rus_net_buf -- ネットワークバッファを再利用する。
+ */
+
+ER
+rus_net_buf (T_NET_BUF *buf)
+{
+	ER	error = E_OK;
+
+	if (buf->idix >= sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY)) {
+		syslog(LOG_WARNING, "[NET BUF] E_ID, ID=%d.", buf->idix);
+		error = E_ID;
+		}
+	else {
+		buf->len   = net_buf_table[buf->idix].size;
+		buf->flags = 0;
+		error = E_OK;
+		}
+	return error;
+	}
+
+/*
+ * net_buf_siz -- ネットワークバッファのサイズを返す。
+ */
+
+ER_UINT
+net_buf_siz (T_NET_BUF *buf)
+{
+	if (buf->idix >= sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY)) {
+		syslog(LOG_WARNING, "[BUF SIZ] E_ID, ID=%d.", buf->idix);
+		return E_ID;
+		}
+	else
+		return (ER_UINT)net_buf_table[buf->idix].size;
+	}
+
+/*
+ * net_buf_max_siz -- ネットワークバッファの最大サイズを返す。
+ */
+
+uint_t
+net_buf_max_siz (void)
+{
+	return (uint_t)net_buf_table[0].size;
+	}
+
+#else
+#include <stdlib.h>
+
+/*
+ *  tget_net_buf_ex -- ネットワークバッファを獲得する（拡張機能）。
+ */
+
+ER
+tget_net_buf_ex (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, ATR nbatr, TMO tmout)
+{
+	uint_t len = (minlen > maxlen) ? minlen : maxlen;
+	*buf = (T_NET_BUF *)malloc(sizeof(T_NET_BUF) - sizeof(((T_NET_BUF *)0)->buf) + len);
+	if (*buf == NULL)
+		return E_NOMEM;
+
+	(*buf)->idix = 0;
+	(*buf)->len = (uint16_t)len;
+	(*buf)->flags = 0;
+
+	return E_OK;
+	}
+
+/*
+ *  tget_net_buf -- ネットワークバッファを獲得する（互換）。
+ */
+
+ER
+tget_net_buf (T_NET_BUF **buf, uint_t len, TMO tmout)
+{
+	return tget_net_buf_ex(buf, len, len, NBA_SEARCH_ASCENT, tmout);
+	}
+
+
+/*
+ * rel_net_buf -- ネットワークバッファを返却する。
+ */
+
+ER
+rel_net_buf (T_NET_BUF *buf)
+{
+	free(buf);
+
+	return E_OK;
+	}
+
+
+/*
+ * net_buf_max_siz -- ネットワークバッファの最大サイズを返す。
+ */
+
+uint_t
+net_buf_max_siz (void)
+{
+	return (uint_t)IF_PDU_SIZE;
+	}
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_buf.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_buf.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_buf.h	(revision 398)
@@ -0,0 +1,250 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _NET_BUF_H_
+#define _NET_BUF_H_
+
+/*
+ *  ネットワークバッファ
+ *
+ *    4 オクテットでアラインする必要のあるプロセッサを考慮して、
+ *    IF ヘッダサイズが 4 オクテット境界でないの場合、
+ *    IP ヘッダ以降を 4 オクテット境界に調整する。
+ */
+
+#ifndef CPU_NET_ALIGN
+#error "CPU_NET_ALIGN expected."
+#endif
+
+/*
+ *  テンプレート
+ */
+
+struct t_net_buf {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IF_MIN_LEN];	/* バッファ本体 */
+	};
+
+#ifndef T_NET_BUF_DEFINED
+
+typedef struct t_net_buf T_NET_BUF;
+
+#define T_NET_BUF_DEFINED
+
+#endif	/* of #ifndef T_NET_BUF_DEFINED */
+
+/*
+ *  64 オクテット
+ */
+
+typedef struct t_net_buf_64 {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[64]; /* バッファ本体	*/
+	} T_NET_BUF_64;
+
+/*
+ *  128 オクテット
+ */
+
+typedef struct t_net_buf_128 {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[128]; /* バッファ本体	*/
+	} T_NET_BUF_128;
+
+/*
+ *  256 オクテット
+ */
+
+typedef struct t_net_buf_256 {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[256]; /* バッファ本体	*/
+	} T_NET_BUF_256;
+
+/*
+ *  512 オクテット
+ */
+
+typedef struct t_net_buf_512 {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[512];/* バッファ本体	*/
+	} T_NET_BUF_512;
+
+/*
+ *  1024 オクテット
+ */
+
+typedef struct t_net_buf_1024 {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[1024]; /* バッファ本体	*/
+	} T_NET_BUF_1024;
+
+/*
+ *  ネットワークインタフェースの最大 PDU サイズ
+ */
+
+#if defined(IF_PDU_SIZE)
+
+typedef struct t_net_buf_if_pdu {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IF_PDU_SIZE];
+				/* バッファ本体		*/
+#if defined(IF_PDU_HDR_PADDING)
+	uint8_t		padding[IF_PDU_HDR_PADDING];
+#endif				/* ヘッダの余分		*/
+	} T_NET_BUF_IF_PDU;
+
+#endif	/* of #if defined(IF_PDU_SIZE) */
+
+/*
+ *  ネットワークバッファ表
+ */
+
+typedef struct t_net_buf_entry {
+
+	uint16_t	index;
+	uint_t		size;
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+	ulong_t		prepares;
+	ulong_t		busies;
+	ulong_t		requests;
+	ulong_t		allocs;
+	ulong_t		errors;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+	} T_NET_BUF_ENTRY;
+
+/*
+ *  ネットワークバッファ・フラグ	
+ */
+
+/*
+ *  ネットワークインタフェース出力後にネットワークバッファを開放しない。
+ *  注意: 出力後にこのフラグはクリアされる。
+ */
+#define NB_FLG_NOREL_IFOUT	UINT_C(0x80)
+
+/*
+ *  ESP 用フラグ
+ */
+#define NB_FLG_DECRYPED		UINT_C(0x40)
+
+/*
+ *  ネットワークバッファ獲得属性
+ */
+
+/* 探索属性 */
+
+#define NBA_SEARCH_ASCENT	UINT_C(0x1000)	/* 大きなサイズの方向に探索する。	*/
+#define NBA_SEARCH_DESCENT	UINT_C(0x2000)	/* 小さなサイズの方向に探索する。	*/
+#define NBA_RESERVE_TCP		UINT_C(0x4000)	/* TCP 用にネットワークバッファを予約する。*/
+#define NBA_ID_MASK		UINT_C(0x0fff)	/* 通信端点 ID を渡す場合のマスク値	*/
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+#define get_net_buf(b,l)	tget_net_buf((b),(l),TMO_FEVR)
+
+/*
+ *  関数
+ */
+
+extern ER tget_net_buf_ex (T_NET_BUF **blk, uint_t minlen, uint_t maxlen, ATR nbatr, TMO tmout);
+extern ER tget_net_buf (T_NET_BUF **blk, uint_t len, TMO tmout);
+extern ER rel_net_buf (T_NET_BUF *blk);
+extern ER rus_net_buf (T_NET_BUF *blk);
+extern ER_UINT net_buf_siz (T_NET_BUF *blk);
+extern uint_t net_buf_max_siz (void);
+extern const T_NET_BUF_ENTRY *nbuf_get_tbl (void);
+extern uint_t nbuf_get_tbl_size (void);
+
+#endif	/* of #ifndef _NET_BUF_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_count.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_count.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_count.c	(revision 398)
@@ -0,0 +1,268 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+/* 
+ *  ネットワーク統計情報の計測
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_count.h>
+
+/*
+ *  計測用変数
+ */
+
+#ifdef SUPPORT_PPP
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP
+
+T_NET_COUNT	net_count_ppp;
+T_NET_COUNT_VAL	net_count_ppp_no_bufs;		/* net_buf 割り当て失敗数	*/
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_LCP
+
+T_NET_COUNT_VAL	net_count_ppp_lcp_in_octets;
+T_NET_COUNT_VAL	net_count_ppp_lcp_in_packets;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_LCP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPV6CP
+
+T_NET_COUNT_VAL	net_count_ppp_ipv6cp_in_octets;
+T_NET_COUNT_VAL	net_count_ppp_ipv6cp_in_packets;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPV6CP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPCP
+
+T_NET_COUNT_VAL	net_count_ppp_ipcp_in_octets;
+T_NET_COUNT_VAL	net_count_ppp_ipcp_in_packets;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPCP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_PAP
+
+T_NET_COUNT_VAL	net_count_ppp_upap_in_octets;
+T_NET_COUNT_VAL	net_count_ppp_upap_in_packets;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_PAP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_HDLC
+
+T_NET_COUNT	net_count_hdlc;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_HDLC */
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_LOOP
+
+#if NET_COUNT_ENABLE & PROTO_FLG_LOOP
+
+T_NET_COUNT	net_count_loop;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_LOOP */
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+#ifdef SUPPORT_ETHER
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ETHER
+
+T_NET_COUNT	net_count_ether;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ETHER */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ETHER_NIC
+
+T_NET_COUNT_VAL net_count_ether_nic[NC_ETHER_NIC_SIZE];
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ETHER_NIC */
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#if defined(_IP4_CFG)
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ARP
+
+T_NET_COUNT	net_count_arp;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ARP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_IP4
+
+T_NET_COUNT_VAL net_count_ip4[NC_IP4_SIZE];
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IP4 */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ICMP4
+
+T_NET_COUNT	net_count_icmp4;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ICMP4 */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_IGMP
+
+T_NET_COUNT	net_count_igmp;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IGMP */
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG)
+
+#if NET_COUNT_ENABLE & PROTO_FLG_IP6
+
+T_NET_COUNT_VAL net_count_ip6[NC_IP6_SIZE];
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IP6 */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ICMP6
+
+T_NET_COUNT_VAL	net_count_icmp6[NC_ICMP6_SIZE];
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ICMP6 */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ND6
+
+T_NET_COUNT_VAL	net_count_nd6[NC_ND6_SIZE];
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ND6 */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#ifdef SUPPORT_TCP
+
+#if NET_COUNT_ENABLE & PROTO_FLG_TCP
+
+T_NET_COUNT_VAL net_count_tcp[NC_TCP_SIZE];
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_TCP */
+
+#endif	/* of #ifdef SUPPORT_TCP */
+
+#ifdef SUPPORT_UDP
+
+#if NET_COUNT_ENABLE & PROTO_FLG_UDP
+
+T_NET_COUNT	net_count_udp;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_UDP */
+
+#endif	/* of #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_count.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_count.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_count.h	(revision 398)
@@ -0,0 +1,597 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#ifndef _NET_COUNT_H_
+#define _NET_COUNT_H_
+
+/*
+ *  ネットワーク統計情報の計測
+ */
+
+#if NET_COUNT_ENABLE != 0
+
+#ifndef _MACRO_ONLY
+
+#ifdef _int64_
+typedef uint64_t T_NET_COUNT_VAL;
+#else
+typedef uint32_t T_NET_COUNT_VAL;
+#endif
+
+typedef struct t_net_count {
+	T_NET_COUNT_VAL	in_octets;		/* 受信オクテット数	*/
+	T_NET_COUNT_VAL	out_octets;		/* 送信オクテット数	*/
+	T_NET_COUNT_VAL	in_packets;		/* 受信バケット数	*/
+	T_NET_COUNT_VAL	out_packets;		/* 送信バケット数	*/
+	T_NET_COUNT_VAL	in_err_packets;		/* 受信エラーバケット数	*/
+	T_NET_COUNT_VAL	out_err_packets;	/* 送信エラーバケット数	*/
+	} T_NET_COUNT;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#endif	/* of #if NET_COUNT_ENABLE != 0 */
+
+#ifdef SUPPORT_PPP
+
+/* PPP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP
+
+#define NET_COUNT_PPP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT	net_count_ppp;
+extern T_NET_COUNT_VAL	net_count_ppp_no_bufs;	/* net_buf 割り当て失敗数	*/
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#define NC_PPP_SIZE	7			/* カウンタ数 */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP */
+
+#define NET_COUNT_PPP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP */
+
+/* PPP HDLC */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_HDLC
+
+#define NET_COUNT_PPP_HDLC(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT	net_count_hdlc;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_HDLC */
+
+#define NET_COUNT_PPP_HDLC(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_HDLC */
+
+/* PPP LCP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_LCP
+
+#define NET_COUNT_PPP_LCP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL net_count_ppp_lcp_in_octets;
+extern T_NET_COUNT_VAL net_count_ppp_lcp_in_packets;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_LCP */
+
+#define NET_COUNT_PPP_LCP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_LCP */
+
+/* PPP IPV6CP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPV6CP
+
+#define NET_COUNT_PPP_IPV6CP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL net_count_ppp_ipv6cp_in_octets;
+extern T_NET_COUNT_VAL net_count_ppp_ipv6cp_in_packets;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPV6CP */
+
+#define NET_COUNT_PPP_IPV6CP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPV6CP */
+
+/* PPP IPCP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPCP
+
+#define NET_COUNT_PPP_IPCP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL net_count_ppp_ipcp_in_octets;
+extern T_NET_COUNT_VAL net_count_ppp_ipcp_in_packets;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPCP */
+
+#define NET_COUNT_PPP_IPCP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPCP */
+
+/* PPP CCP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_CCP
+
+#define NET_COUNT_PPP_CCP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL net_count_ppp_ccp_in_octets;
+extern T_NET_COUNT_VAL net_count_ppp_ccp_in_packets;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_CCP */
+
+#define NET_COUNT_PPP_CCP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_CCP */
+
+/* PPP PAP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_PAP
+
+#define NET_COUNT_PPP_PAP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL net_count_ppp_upap_in_octets;
+extern T_NET_COUNT_VAL net_count_ppp_upap_in_packets;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_PAP */
+
+#define NET_COUNT_PPP_PAP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_PAP */
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_LOOP
+
+/* ループバック */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_LOOP
+
+#define NET_COUNT_LOOP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT	net_count_loop;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_LOOP */
+
+#define NET_COUNT_LOOP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_LOOP */
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+#ifdef SUPPORT_ETHER
+
+/* Ethernet */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ETHER
+
+#define NET_COUNT_ETHER(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT	net_count_ether;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ETHER */
+
+#define NET_COUNT_ETHER(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ETHER */
+
+/* NIC (if_ed) */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ETHER_NIC
+
+#define NC_ETHER_NIC_RESETS		0	/* リセット数			*/
+#define NC_ETHER_NIC_TXB_QOVRS		1	/* 送信セマフォ資源返却上限オーバー数*/
+#define NC_ETHER_NIC_TIMEOUTS		2	/* 送信タイムアウト数		*/
+#define NC_ETHER_NIC_COLS		3	/* コリジョン数			*/
+#define NC_ETHER_NIC_OUT_ERR_PACKETS	4	/* 送信エラーバケット数		*/
+#define NC_ETHER_NIC_OUT_PACKETS	5	/* 送信バケット数		*/
+#define NC_ETHER_NIC_OUT_OCTETS		6	/* 送信オクテット数		*/
+#define NC_ETHER_NIC_RXB_QOVRS		7	/* 受信セマフォ資源返却上限オーバー数*/
+#define NC_ETHER_NIC_NO_BUFS		8	/* net_buf 割り当て失敗数	*/
+#define NC_ETHER_NIC_IN_ERR_PACKETS	9	/* 受信エラーバケット数		*/
+#define NC_ETHER_NIC_IN_PACKETS		10	/* 受信バケット数		*/
+#define NC_ETHER_NIC_IN_OCTETS		11	/* 受信オクテット数		*/
+#define NC_ETHER_NIC_SIZE		12	/* カウンタ数			*/
+
+#define NET_COUNT_ETHER_NIC(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL net_count_ether_nic[NC_ETHER_NIC_SIZE];
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ETHER_NIC */
+
+#define NET_COUNT_ETHER_NIC(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ETHER_NIC */
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+/* ネットワークバッファ */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+
+#define NET_COUNT_NET_BUF(v,c)		((v)+=(c))
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+#define NET_COUNT_NET_BUF(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
+
+#if defined(_IP4_CFG)
+
+/* ARP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ARP
+
+#define NET_COUNT_ARP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT	net_count_arp;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ARP */
+
+#define NET_COUNT_ARP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ARP */
+
+/* IPv4 */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_IP4
+
+#define NC_IP4_FRAG_OUT_FRAGS		0	/* 分割送信、フラグメント数	*/
+#define NC_IP4_FRAG_OUT			1	/* 分割送信数			*/
+#define NC_IP4_OUT_ERR_PACKETS		2	/* 送信エラーデータグラム数	*/
+#define NC_IP4_OUT_PACKETS		3	/* 送信データグラム数		*/
+#define NC_IP4_OUT_OCTETS		4	/* 送信オクテット数		*/
+#define NC_IP4_FRAG_IN_TMOUT		5	/* 分割受信タイムアウト数		*/
+#define NC_IP4_FRAG_IN_NO_BUF		6	/* 分割受信バッファり当て失敗数	*/
+#define NC_IP4_FRAG_IN_DROP		7	/* 分割受信破棄数		*/
+#define NC_IP4_FRAG_IN_OK		8	/* 分割受信再構成成功数		*/
+#define NC_IP4_FRAG_IN_FRAGS		9	/* 分割受信フラグメント数		*/
+#define NC_IP4_FRAG_IN			10	/* 分割受信数			*/
+#define NC_IP4_OPTS			11	/* オプション入力数		*/
+#define NC_IP4_IN_ERR_PROTO		12	/* プロトコルエラー数		*/
+#define NC_IP4_IN_ERR_ADDR		13	/* アドレスエラー数		*/
+#define NC_IP4_IN_ERR_VER		14	/* バージョンエラー数		*/
+#define NC_IP4_IN_ERR_SHORT		15	/* 長さエラー数			*/
+#define NC_IP4_IN_ERR_CKSUM		16	/* チェックサムエラー数		*/
+#define NC_IP4_IN_ERR_PACKETS		17	/* 受信エラーデータグラム数	*/
+#define NC_IP4_IN_PACKETS		18	/* 受信データグラム数		*/
+#define NC_IP4_IN_OCTETS		19	/* 受信オクテット数		*/
+#define NC_IP4_SIZE			20	/* カウンタ数			*/
+
+#define NET_COUNT_IP4(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL net_count_ip4[NC_IP4_SIZE];
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IP4 */
+
+#define NET_COUNT_IP4(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IP4 */
+
+/* ICMP4 */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ICMP4
+
+#define NET_COUNT_ICMP4(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT	net_count_icmp4;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ICMP4 */
+
+#define NET_COUNT_ICMP4(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ICMP4 */
+
+/* IGMP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_IGMP
+
+#define NET_COUNT_IGMP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT	net_count_igmp;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IGMP */
+
+#define NET_COUNT_IGMP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IGMP */
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG)
+
+/* IPv6 */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_IP6
+
+#define NC_IP6_FRAG_OUT_FRAGS		0	/* 分割送信、フラグメント数	*/
+#define NC_IP6_FRAG_OUT			1	/* 分割送信数			*/
+#define NC_IP6_OUT_ERR_PACKETS		2	/* 送信エラーデータグラム数	*/
+#define NC_IP6_OUT_PACKETS		3	/* 送信データグラム数		*/
+#define NC_IP6_OUT_OCTETS		4	/* 送信オクテット数		*/
+#define NC_IP6_FRAG_IN_TMOUT		5	/* 分割受信タイムアウト数		*/
+#define NC_IP6_FRAG_IN_NO_BUF		6	/* 分割受信バッファり当て失敗数	*/
+#define NC_IP6_FRAG_IN_DROP		7	/* 分割受信破棄数		*/
+#define NC_IP6_FRAG_IN_OK		8	/* 分割受信再構成成功数		*/
+#define NC_IP6_FRAG_IN_FRAGS		9	/* 分割受信フラグメント数		*/
+#define NC_IP6_FRAG_IN			10	/* 分割受信数			*/
+#define NC_IP6_IN_ERR_PROTO		11	/* プロトコルエラー数		*/
+#define NC_IP6_IN_ERR_ADDR		12	/* アドレスエラー数		*/
+#define NC_IP6_IN_ERR_VER		13	/* バージョンエラー数		*/
+#define NC_IP6_IN_ERR_SHORT		14	/* 長さエラー数			*/
+#define NC_IP6_IN_ERR_PACKETS		15	/* 受信エラーデータグラム数	*/
+#define NC_IP6_IN_PACKETS		16	/* 受信データグラム数		*/
+#define NC_IP6_IN_OCTETS		17	/* 受信オクテット数		*/
+#define NC_IP6_SIZE			18	/* カウンタ数			*/
+
+#define NET_COUNT_IP6(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL net_count_ip6[NC_IP6_SIZE];
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IP6 */
+
+#define NET_COUNT_IP6(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IP6 */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ICMP6
+
+#define NC_ICMP6_OUT_ERR_PACKETS	0	/* 送信エラー ICMP データ数	*/
+#define NC_ICMP6_OUT_PACKETS		1	/* 送信 ICMP データ数		*/
+#define NC_ICMP6_OUT_OCTETS		2	/* 送信 ICMP オクテット数		*/
+#define NC_ICMP6_IN_ERR_CKSUM		3	/* 長さエラー数			*/
+#define NC_ICMP6_IN_ERR_PACKETS		4	/* 受信エラー ICMP データ数	*/
+#define NC_ICMP6_IN_PACKETS		5	/* 受信 ICMP データ数		*/
+#define NC_ICMP6_IN_OCTETS		6	/* 受信 ICMP オクテット数		*/
+#define NC_ICMP6_SIZE			7	/* カウンタ数			*/
+
+#define NET_COUNT_ICMP6(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL	net_count_icmp6[NC_ICMP6_SIZE];
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ICMP6 */
+
+#define NET_COUNT_ICMP6(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ICMP6 */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_ND6
+
+#define NC_ND6_DAD_OUT_PACKETS		0	/* 重複アドレス検出送信数		*/
+#define NC_ND6_NS_OUT_PACKETS		1	/* 近隣要請送信数		*/
+#define NC_ND6_NS_IN_PACKETS		2	/* 近隣要請受信数		*/
+#define NC_ND6_NA_OUT_PACKETS		3	/* 近隣通知送信数		*/
+#define NC_ND6_NA_IN_PACKETS		4	/* 近隣通知受信数		*/
+#define NC_ND6_RS_OUT_PACKETS		5	/* ルータ要請出力数		*/
+#define NC_ND6_RA_IN_PACKETS		6	/* ルータ通知受信数		*/
+#define NC_ND6_SIZE			7	/* カウンタ数			*/
+
+#define NET_COUNT_ND6(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL	net_count_nd6[NC_ND6_SIZE];
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ND6 */
+
+#define NET_COUNT_ND6(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ND6 */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#ifdef SUPPORT_TCP
+
+/* TCP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_TCP
+
+#define NC_TCP_CONNECTS			0	/* 能動オープン数		*/
+#define NC_TCP_ACCEPTS			1	/* 受動オープン数		*/
+#define NC_TCP_RTT_UPDATES		2	/* RTT 更新数			*/
+#define NC_TCP_SEND_RSTS		3	/* 送信、RST 数			*/
+#define NC_TCP_SEND_ACKS		4	/* 送信、ACK 数			*/
+#define NC_TCP_SEND_URG_SEGS		5	/* 送信、緊急セグメント数	*/
+#define NC_TCP_SEND_DATA_SEGS		6	/* 送信データセグメント数	*/
+#define NC_TCP_SEND_REXMIT_SEGS		7	/* 再送信セグメント数		*/
+#define NC_TCP_SEND_SEGS		8	/* 送信セグメント数		*/
+#define NC_TCP_SEND_CNTL_SEGS		9	/* 送信制御セグメント数		*/
+#define NC_TCP_SEND_DATA_OCTETS		10	/* 送信データオクテット数	*/
+#define NC_TCP_FREE_RCV_QUEUE		11	/* 受信キュー解放数		*/
+#define NC_TCP_RECV_DUP_SEGS		12	/* 受信、多重数			*/
+#define NC_TCP_RECV_DROP_SEGS		13	/* 受信、破棄数			*/
+#define NC_TCP_RECV_RSTS		14	/* 受信、RST 数			*/
+#define NC_TCP_RECV_DUP_ACKS		15	/* 受信、多重 ACK 数		*/
+#define NC_TCP_RECV_ACKS		16	/* 受信、ACK 数			*/
+#define NC_TCP_RECV_BAD_CKSUMS		17	/* 受信、チェックサム不正数	*/
+#define NC_TCP_RECV_BAD_HEADERS		18	/* 受信、ヘッダ不正数		*/
+#define NC_TCP_RECV_URG_SEGS		19	/* 受信、緊急セグメント数	*/
+#define NC_TCP_RECV_DATA_SEGS		20	/* 受信データセグメント数	*/
+#define NC_TCP_RECV_SEGS		21	/* 受信セグメント数		*/
+#define NC_TCP_RECV_DATA_OCTETS		22	/* 受信データオクテット数	*/
+#define NC_TCP_RECV_OCTETS		23	/* 受信オクテット数		*/
+#define NC_TCP_SIZE			24	/* カウンタ数			*/
+
+#define NET_COUNT_TCP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL net_count_tcp[NC_TCP_SIZE];
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_TCP */
+
+#define NET_COUNT_TCP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_TCP */
+
+#endif	/* of #ifdef SUPPORT_TCP */
+
+#ifdef SUPPORT_UDP
+
+/* UDP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_UDP
+
+#define NET_COUNT_UDP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT	net_count_udp;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_UDP */
+
+#define NET_COUNT_UDP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_UDP */
+
+#endif	/* of #ifdef SUPPORT_UDP */
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+#define NET_COUNT_MIB(v, c)		((v)+=(c))
+
+#else	/* of #ifdef SUPPORT_MIB */
+
+#define NET_COUNT_MIB(v, c)
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+#endif	/* of #ifndef _NET_COUNT_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_endian.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_endian.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_endian.h	(revision 398)
@@ -0,0 +1,197 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#ifndef _NET_ENDIAN_H_
+#define _NET_ENDIAN_H_
+
+/*
+ *  バイトオーダの定義
+ */
+
+#define _NET_CFG_LITTLE_ENDIAN	1234
+#define _NET_CFG_BIG_ENDIAN	4321
+
+#ifdef TARGET_KERNEL_ASP
+
+#if defined(SIL_ENDIAN_LITTLE)
+
+#define _NET_CFG_BYTE_ORDER	_NET_CFG_LITTLE_ENDIAN
+
+#elif defined(SIL_ENDIAN_BIG)
+
+#define _NET_CFG_BYTE_ORDER	_NET_CFG_BIG_ENDIAN
+
+#else	/* of #if defined(SIL_ENDIAN_BIG) */
+
+#error "SIL_ENDIAN expected."
+
+#endif	/* of #if defined(SIL_ENDIAN_BIG) */
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#if SIL_ENDIAN == SIL_ENDIAN_LITTLE
+
+#define _NET_CFG_BYTE_ORDER	_NET_CFG_LITTLE_ENDIAN
+
+#elif SIL_ENDIAN == SIL_ENDIAN_BIG	/* of #if SIL_ENDIAN == SIL_ENDIAN_LITTLE */
+
+#define _NET_CFG_BYTE_ORDER	_NET_CFG_BIG_ENDIAN
+
+#else	/* of #if SIL_ENDIAN == SIL_ENDIAN_LITTLE */
+
+#error "SIL_ENDIAN expected."
+
+#endif	/* of #if SIL_ENDIAN == SIL_ENDIAN_LITTLE */
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+/*
+ *  バイトオーダ変換の定義
+ */
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
+
+#define ntohs(n)		((uint16_t)n)
+#define htons(h)		((uint16_t)h)
+#define ntohl(n)		((uint32_t)n)
+#define htonl(h)		((uint32_t)h)
+
+#define NTOHS(n)
+#define HTONS(h)
+#define NTOHL(n)
+#define HTONL(h)
+
+/*
+ *  注意: IPヘッダ以降は、4 バイト境界にアラインされている事を
+ *        前提としているが、4 バイト境界でアクセスする
+ *        プロセッサで、ネットワーク側のデータが、4 バイト境界にアライン
+ *        されていない場合は、ntoahl、ahtonl、nahcmpl を使用すること。
+ */
+
+#define ntoahs(h,n)		memcpy((void*)&(h),(n),sizeof(uint16_t))
+#define ahtons(n,h)		memcpy((n),(void*)&(h),sizeof(uint16_t))
+#define ntoahl(h,n)		memcpy((void*)&(h),(n),sizeof(uint32_t))
+#define ahtonl(n,h)		memcpy((n),(void*)&(h),sizeof(uint32_t))
+
+#define nahcmpl(n,h)		memcmp((n),(void*)&(h),sizeof(uint32_t))
+
+#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN	/* of #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#ifndef NET_REV_ENDIAN_HWORD
+
+#define NET_REV_ENDIAN_HWORD(d)	((uint16_t)((((uint16_t)(d)&0xff)<<8)|(((uint16_t)(d)>>8)&0xff)))
+
+#endif	/* of #ifndef NET_REV_ENDIAN_HWORD */
+
+#ifndef NET_REV_ENDIAN_WORD
+
+#define NET_REV_ENDIAN_WORD(d)	((uint32_t)((((uint32_t)(d)&0xff)<<24)|(((uint32_t)(d)&0xff00)<<8)| \
+				            (((uint32_t)(d)>>8)&0xff00)|(((uint32_t)(d)>>24)&0xff)))
+
+#endif	/* of #ifndef NET_REV_ENDIAN_WORD */
+
+#define ntohs(n)		NET_REV_ENDIAN_HWORD(n)
+#define htons(h)		NET_REV_ENDIAN_HWORD(h)
+#define ntohl(n)		NET_REV_ENDIAN_WORD(n)
+#define htonl(h)		NET_REV_ENDIAN_WORD(h)
+
+#define NTOHS(n)		((n)=NET_REV_ENDIAN_HWORD(n))
+#define HTONS(h)		((h)=NET_REV_ENDIAN_HWORD(h))
+#define NTOHL(n)		((n)=NET_REV_ENDIAN_WORD(n))
+#define HTONL(h)		((h)=NET_REV_ENDIAN_WORD(h))
+
+/*
+ *  注意: IPヘッダ以降は、4 バイト境界にアラインされている事を
+ *        前提としているが、4 バイト境界でアクセスする
+ *        プロセッサで、ネットワーク側のデータが、4 バイト境界にアライン
+ *        されていない場合は、ntoahl、ahtonl、nahcmpl を使用すること。
+ */
+
+#ifndef _MACRO_ONLY
+
+extern void rev_memcpy_word  (void *dst, void *src);
+extern void rev_memcpy_hword (void *dst, void *src);
+
+extern int  rev_memcmp_word (void *data1, void *data2);
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#define ntoahs(h,n)		rev_memcpy_hword((void*)&(h),(n))
+#define ahtons(n,h)		rev_memcpy_hword((n),(void*)&(h))
+#define ntoahl(h,n)		rev_memcpy_word((void*)&(h),(n))
+#define ahtonl(n,h)		rev_memcpy_word((n),(void*)&(h))
+
+#define nahcmpl(n,h)		rev_memcmp_word((n),(void*)&(h))
+
+#else	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#error "_NET_CFG_BYTE_ORDER expected."
+
+#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#endif	/* of #ifndef _NET_ENDIAN_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_jsp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_jsp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_jsp.cfg	(revision 398)
@@ -0,0 +1,160 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  JSP用 汎用ネットワークコンフィギュレーションファイル
+ */
+
+
+/*
+ *  共通 汎用ネットワークコンフィギュレーションファイルのインクルード
+ */
+
+#include "net/net.cfg"
+
+/*
+ * ネットワークバッファ
+ */
+
+#if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0
+CRE_MPF(MPF_NET_BUF_CSEG, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_CSEG,
+		sizeof(T_NET_BUF_CSEG),
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0 */
+
+#if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0
+CRE_MPF(MPF_NET_BUF_64, {
+		TA_TFIFO, NUM_MPF_NET_BUF_64,
+		sizeof(T_NET_BUF_64),
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0
+CRE_MPF(MPF_NET_BUF_128, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_128,
+		sizeof(T_NET_BUF_128),
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0
+CRE_MPF(MPF_NET_BUF_256, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_256,
+		sizeof(T_NET_BUF_256),
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0
+CRE_MPF(MPF_NET_BUF_512, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_512,
+		sizeof(T_NET_BUF_512),
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0
+CRE_MPF(MPF_NET_BUF_IP_MSS, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_IP_MSS,
+		sizeof(T_NET_BUF_IP_MSS),
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0 */
+
+#if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0
+CRE_MPF(MPF_NET_BUF_1024, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_1024,
+		sizeof(T_NET_BUF_1024),
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0 */
+
+#if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0
+CRE_MPF(MPF_NET_BUF_IPV6_MMTU, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_IPV6_MMTU,
+		sizeof(T_NET_BUF_IPV6_MMTU),
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0 */
+
+#if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0
+CRE_MPF(MPF_NET_BUF_IF_PDU, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF_IF_PDU,
+		sizeof(T_NET_BUF_IF_PDU),
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
+
+#if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0
+
+CRE_MPF(MPF_NET_BUF_REASSM, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF6_REASSM,
+		sizeof(T_NET_BUF6_REASSM),
+		NULL
+		});
+
+#else	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
+
+#if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0
+
+CRE_MPF(MPF_NET_BUF_REASSM, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF4_REASSM,
+		sizeof(T_NET_BUF4_REASSM),
+		NULL
+		});
+
+#endif	/* of #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0 */
+
+#endif	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
+
+#if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0
+CRE_MPF(MPF_NET_BUF6_65536, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF6_65536,
+		sizeof(T_NET_BUF6_65536),
+		NULL
+		});
+#endif	/* of #if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_rename.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_rename.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_rename.h	(revision 398)
@@ -0,0 +1,173 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _NET_RENAME_H_
+#define _NET_RENAME_H_
+
+/*
+ *  汎用ネットワークインタフェース内部名のリネーム
+ */
+
+/* net/ethernet.c */
+
+#define ether_input_task	_tinet_ether_input_task
+#define ether_get_ifnet		_tinet_ether_get_ifnet
+#define ether_in6_resolve_multicast	\
+				_tinet_ether_in6_resolve_multicast
+#define ether_srand		_tinet_ether_srand
+#define ether_output		_tinet_ether_output
+#define	ether_raw_output	_tinet_ether_raw_output
+#define ether_output_task	_tinet_ether_output_task
+
+#define ether_broad_cast_addr	_tinet_ether_broad_cast_addr
+#define ether_ipv4_addr_local	_tinet_ether_ipv4_addr_local
+#define ether_ipv4_addr_local_mask	\
+				_tinet_ether_ipv4_addr_local_mask
+
+#define ether_in6_ifaddr	_tinet_ether_in6_ifaddr
+#define ether_in6_ifaddr_list	_tinet_ether_in6_ifaddr_list
+
+/* net/if.c */
+
+#ifdef SUPPORT_ETHER
+
+#define ifinit			_tinet_ifinit
+#define if_addmulti		_tinet_if_addmulti
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+/* net/net_buf.c */
+
+#define tget_net_buf_ex		_tinet_tget_net_buf_ex
+#define tget_net_buf		_tinet_tget_net_buf
+#define rel_net_buf			_tinet_rel_net_buf
+#define rus_net_buf			_tinet_rus_net_buf
+#define net_buf_siz			_tinet_net_buf_siz
+#define net_buf_max_siz		_tinet_net_buf_max_siz
+#define nbuf_get_tbl		_tinet_nbuf_get_tbl
+#define nbuf_get_tbl_size	_tinet_nbuf_get_tbl_size
+
+/* net/net_subr.c */
+
+#define convert_hexdigit	_tinet_convert_hexdigit
+#define net_rand		_tinet_net_rand
+#define net_srand		_tinet_net_srand
+#define rev_memcpy_word		_tinet_rev_memcpy_word
+#define rev_memcmp_word		_tinet_rev_memcmp_word
+
+/* net/net_timer.c */
+
+#define timeout			_tinet_timeout
+#define untimeout		_tinet_untimeout
+#define busy_callout		_tinet_busy_callout
+#define max_busy		_tinet_max_busy
+
+/* route_cfg.c */
+
+#define routing6_tbl		_tinet_routing6_tbl
+#define routing4_tbl		_tinet_routing4_tbl
+
+#ifdef SUPPORT_PPP
+
+/* net/ppp.c */
+
+#define ppp_output		_tinet_ppp_output
+#define ppp_cp_output		_tinet_ppp_cp_output
+#define ppp_phase		_tinet_ppp_phase
+#define protocols		_tinet_protocols
+
+/* net/ppp_hdlc.c */
+
+#define HDLC_dummy_read		_tinet_HDLC_dummy_read
+#define HDLC_read		_tinet_HDLC_read
+#define HDLC_write		_tinet_HDLC_write
+#define remote_ACCM		_tinet_remote_ACCM
+
+/* net/ppp_lcp.c */
+
+#define lcp_close		_tinet_lcp_close
+#define lcp_open		_tinet_lcp_open
+#define lcp_lowerdown		_tinet_lcp_lowerdown
+#define lcp_sprotrej		_tinet_lcp_sprotrej
+#define lcp_lowerup		_tinet_lcp_lowerup
+#define lcp_finished		_tinet_lcp_finished
+#define lcp_down		_tinet_lcp_down
+#define lcp_callbacks		_tinet_lcp_callbacks
+#define lcp_fsm			_tinet_lcp_fsm
+#define lcp_protent		_tinet_lcp_protent
+#define lcp_local_ack_cfg	_tinet_lcp_local_ack_cfg
+#define lcp_remote_ack_cfg	_tinet_lcp_remote_ack_cfg
+
+/* net/ppp_fsm.c */
+
+#define fsm_init		_tinet_fsm_init
+#define fsm_open		_tinet_fsm_open
+#define fsm_input		_tinet_fsm_input
+#define fsm_protreject		_tinet_fsm_protreject
+#define fsm_lowerdown		_tinet_fsm_lowerdown
+#define fsm_close		_tinet_fsm_close
+#define fsm_lowerup		_tinet_fsm_lowerup
+#define ppp_open_mode		_tinet_ppp_open_mode
+
+/* net/ppp_auth.c */
+
+#define auth_reset		_tinet_auth_reset
+#define link_terminated		_tinet_link_terminated
+#define link_established	_tinet_link_established
+#define link_required		_tinet_link_required
+#define network_phase		_tinet_network_phase
+#define link_down		_tinet_link_down
+
+/* net/ppp_ipcp.c */
+
+#define wait_ipcp		_tinet_wait_ipcp
+#define ppp_get_ifnet		_tinet_ppp_get_ifnet
+#define ipcp_protent		_tinet_ipcp_protent
+#define ipcp_callbacks		_tinet_ipcp_callbacks
+#define ipcp_fsm		_tinet_ipcp_fsm
+#define ipcp_remote_ack_cfg	_tinet_ipcp_remote_ack_cfg
+#define ipcp_local_ack_cfg	_tinet_ipcp_local_ack_cfg
+
+/* net/ppp_upap.c */
+
+#define upap_auth_client	_tinet_upap_auth_client
+#define upap_auth_server	_tinet_upap_auth_server
+#define pap_protent		_tinet_pap_protent
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_LOOP
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+#endif	/* of #ifndef _NET_RENAME_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_subr.c	(revision 398)
@@ -0,0 +1,245 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+/* 
+ *  ネットワーク汎用サポートルーチン
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+
+/*
+ *  変数
+ */
+
+static uint32_t next = ULONG_C(1);
+
+/*
+ *  net_rand -- 乱数を返す。
+ */
+
+uint32_t
+net_rand (void)
+{
+	next = (next * 99991 + 12345) & ULONG_C(0x7fffffff);
+	return next;
+	}
+
+/*
+ *  srand -- 乱数を初期化する。
+ */
+
+void
+net_srand (uint32_t seed)
+{
+	SYSTIM now;
+
+	syscall(get_tim(&now));
+	next += now + seed + IF_SRAND();
+	}
+
+/*
+ *  convert_hexdigit -- 16進数→文字列変換
+ */
+
+int_t
+convert_hexdigit (char *buf, uint_t val, int_t radix, int_t width, char padchar)
+{
+	static const char radhex[] = "0123456789abcdef";
+
+	char	digits[11], *start;
+	int_t	ix, pad;
+
+	ix = 0;
+	start = buf;
+	do {
+		digits[ix ++] = radhex[(val % radix) & 0x0f];
+		val /= radix;
+		} while (val != 0);
+	for (pad = ix; pad < width; pad ++)
+		*buf ++ = padchar;
+	while (ix -- > 0)
+		*buf ++ = digits[ix];
+	*buf = '\0';
+	return (int_t)(buf - start);
+	}
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  mac2str -- MAC アドレスを文字列に変換する。
+ */
+
+char *
+mac2str (char *buf, uint8_t *macaddr)
+{
+	static char	addr_sbuf[NUM_MACADDR_STR_BUFF][sizeof("00:00:00:00:00:00")];
+	static int_t	bix = NUM_MACADDR_STR_BUFF;
+
+	char *start;
+
+	if (buf == NULL) {
+		syscall(wai_sem(SEM_MAC2STR_BUFF_LOCK));
+		buf = addr_sbuf[-- bix];
+		if (bix <= 0)
+			bix = NUM_MACADDR_STR_BUFF;
+		syscall(sig_sem(SEM_MAC2STR_BUFF_LOCK));
+		}
+
+	start = buf;
+	buf += convert_hexdigit(buf, (uint_t)(*macaddr ++), 16, 2, '0');
+	*(buf ++) = ':';
+	buf += convert_hexdigit(buf, (uint_t)(*macaddr ++), 16, 2, '0');
+	*(buf ++) = ':';
+	buf += convert_hexdigit(buf, (uint_t)(*macaddr ++), 16, 2, '0');
+	*(buf ++) = ':';
+	buf += convert_hexdigit(buf, (uint_t)(*macaddr ++), 16, 2, '0');
+	*(buf ++) = ':';
+	buf += convert_hexdigit(buf, (uint_t)(*macaddr ++), 16, 2, '0');
+	*(buf ++) = ':';
+	buf += convert_hexdigit(buf, (uint_t)(*macaddr ++), 16, 2, '0');
+	*buf = '\0';
+	return start;
+	}
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
+
+/*
+ *  rev_memcpy_hword -- 反転メモリコピー（2 バイト）
+ *
+ *    バイト単位にアクセスする事により、
+ *    境界へのアラインの問題を解決する。
+ */
+
+void
+rev_memcpy_hword (void *dst, void *src)
+{
+	*((uint8_t*)dst    ) = *((uint8_t*)src + 1);
+	*((uint8_t*)dst + 1) = *((uint8_t*)src    );
+	}
+
+/*
+ *  rev_memcpy_word -- 反転メモリコピー（4 バイト）
+ *
+ *    バイト単位にアクセスする事により、
+ *    境界へのアラインの問題を解決する。
+ */
+
+void
+rev_memcpy_word (void *dst, void *src)
+{
+	*((uint8_t*)dst    ) = *((uint8_t*)src + 3);
+	*((uint8_t*)dst + 1) = *((uint8_t*)src + 2);
+	*((uint8_t*)dst + 2) = *((uint8_t*)src + 1);
+	*((uint8_t*)dst + 3) = *((uint8_t*)src    );
+	}
+
+/*
+ *  rev_memcmp_word -- 反転メモリ比較（4 バイト）
+ *
+ *    バイト単位にアクセスする事により、
+ *    境界へのアラインの問題を解決する。
+ */
+
+int_t
+rev_memcmp_word (void *data1, void *data2)
+{
+	int_t	ix, diff;
+
+	for (ix = sizeof(uint32_t); ix -- > 0; ) {
+		diff = *((uint8_t*)data1 + ix) -  *((uint8_t*)data2 + (3 - ix));
+		if (diff != 0)
+			return diff;
+		}
+	return 0;
+	}
+
+#endif	/* of #if _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_timer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_timer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_timer.c	(revision 398)
@@ -0,0 +1,244 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+/*
+ *  変数
+ */
+
+static T_NET_CALLOUT callout[NUM_NET_CALLOUT];
+
+/*
+ *  呼出しエントリ登録
+ */
+
+void
+timeout (callout_func func, void *arg, RELTIM timeout)
+{
+	int_t ix;
+
+	/* 呼出しエントリを獲得する */
+	syscall(wai_sem(SEM_CALL_OUT_LOCK));
+	for (ix = NUM_NET_CALLOUT; callout[-- ix].func != NULL; )
+		if (ix == 0) {
+			syslog(LOG_WARNING, "[NET] callout busy, size=%d.", NUM_NET_CALLOUT);
+			syscall(sig_sem(SEM_CALL_OUT_LOCK));
+			return;
+			}
+
+	/* 呼出しエントリを設定する */
+	callout[ix].func	= func;
+	callout[ix].arg		= arg;
+	callout[ix].timeout	= timeout;
+	syscall(sig_sem(SEM_CALL_OUT_LOCK));
+	}
+
+/*
+ *  呼出しエントリ削除
+ */
+
+void
+untimeout (callout_func func, void *arg)
+{
+	int_t ix;
+
+	/* エントリを探す */
+	for (ix = NUM_NET_CALLOUT; ix -- > 0; ) {
+		syscall(wai_sem(SEM_CALL_OUT_LOCK));
+		if (callout[ix].func == func && callout[ix].arg == arg && callout[ix].timeout > 0) {
+			callout[ix].func = NULL;
+			syscall(sig_sem(SEM_CALL_OUT_LOCK));
+			break;
+			}
+		syscall(sig_sem(SEM_CALL_OUT_LOCK));
+		}
+	}
+
+/*
+ *  ネットワークタイマタスク
+ *
+ *    注意: タスクコンテキストで実行する必要があるため，
+ *          周期ハンドラは使用できない。
+ */
+
+static char const tinet_banner[] =
+"\n"
+"TINET %d.%d.%d (" __DATE__ ", " __TIME__ ")\n"
+"Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering\n"
+"                    Tomakomai National College of Technology, JAPAN\n";
+
+void
+net_timer_task(intptr_t exinf)
+{
+	ID		tskid;
+	int_t		ix;
+	callout_func	func;
+	void 		*arg;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, tinet_banner,
+	       (TINET_PRVER   >> 12) & UINT_C(0x0f),
+	       (TINET_PRVER   >>  4) & UINT_C(0x0f),
+	        TINET_PRVER          & UINT_C(0x0f));
+	syslog(LOG_NOTICE, "[NET/TIMER:%d] started.", tskid);
+
+	/* IP を初期化する。*/
+
+#if defined(_IP6_CFG)
+	ip6_init();
+#endif
+
+#if defined(_IP4_CFG)
+	ip_init();
+#endif
+
+#ifdef SUPPORT_TCP
+
+	/* TCP 出力タスクを起動する */
+	syscall(act_tsk(TCP_OUTPUT_TASK));
+
+#endif	/* of #ifdef SUPPORT_TCP */
+
+#if defined(SUPPORT_UDP) && defined(UDP_CFG_NON_BLOCKING)
+
+	/* UDP 出力タスクを起動する */
+	syscall(act_tsk(UDP_OUTPUT_TASK));
+
+#endif	/* of #if defined(SUPPORT_UDP) && defined(UDP_CFG_NON_BLOCKING) */
+
+	while (true) {
+		/* タイムアウトしたエントリを呼出す。*/
+		syscall(wai_sem(SEM_CALL_OUT_TIMEOUT));
+		for (ix = NUM_NET_CALLOUT; ix -- > 0; ) {
+			syscall(wai_sem(SEM_CALL_OUT_LOCK));
+			if (callout[ix].func != NULL && callout[ix].timeout == 0) {
+				func = callout[ix].func;
+				arg  = callout[ix].arg;
+				callout[ix].func = NULL;
+				syscall(sig_sem(SEM_CALL_OUT_LOCK));
+				(func)(arg);
+				}
+			else
+				syscall(sig_sem(SEM_CALL_OUT_LOCK));
+			}
+		}
+	}
+
+/*
+ *  ネットワークタイマハンドラ
+ *
+ *    NET_TIMER_CYCLE (100ms) 毎に呼出される。
+ */
+
+void
+net_timer_handler(intptr_t exinf)
+{
+	int_t	ix, count = 0;
+
+	for (ix = NUM_NET_CALLOUT; ix -- > 0; ) {
+		if (callout[ix].func != NULL && callout[ix].timeout > 0) {
+			callout[ix].timeout --;
+			if (callout[ix].timeout == 0)
+				count ++;
+			}
+		}
+
+	if (count)
+		syscall(isig_sem(SEM_CALL_OUT_TIMEOUT));
+	}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_timer.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_timer.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_timer.h	(revision 398)
@@ -0,0 +1,118 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#ifndef _NET_TIMER_H_
+#define _NET_TIMER_H_
+
+#include <tinet_kernel_defs.h>	/* カーネルに関する互換性定義ファイルをインクルードする。*/
+
+/*
+ *  TOPPERS/JSP カーネル、システム時刻 (SYSTIM) の周波数
+ */
+
+#define SYSTIM_HZ		ULONG_C(1000000)	/* [us]					*/
+
+/*
+ *  ネットワークタイマの定義
+ */
+
+#define NET_TIMER_CYCLE		ULONG_C(100000)	/* [us]、fast timeout 使用時の動作周期	*/
+						/* タイマの周波数			*/
+#define NET_TIMER_HZ		(SYSTIM_HZ/NET_TIMER_CYCLE)
+
+#ifdef _IP6_CFG
+#define NUM_NET_CALLOUT		12		/* タイムアウト呼出し数、10 以上	*/
+#else
+#define NUM_NET_CALLOUT		10		/* タイムアウト呼出し数、10 以上	*/
+#endif
+
+/*
+ *  タイムアウト呼出しエントリ
+ */
+
+typedef void	(*callout_func)(void*);
+
+typedef struct t_net_callout {
+	callout_func	func;		/* 呼出す関数		*/
+	void		*arg;		/* 関数への引数		*/
+	RELTIM		timeout;	/* タイムアウト		*/
+	} T_NET_CALLOUT;
+
+/*
+ *  関数
+ */
+
+extern void timeout (callout_func func, void *arg, RELTIM timeout);
+extern void untimeout (callout_func func, void *arg);
+
+/*
+ *  ネットワークタイマタスクと周期ハンドラ
+ */
+
+extern void net_timer_task(intptr_t exinf);
+extern void net_timer_handler(intptr_t exinf);
+
+#endif	/* of #ifndef _NET_TIMER_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/net_var.h	(revision 398)
@@ -0,0 +1,83 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#ifndef _NET_VAR_H_
+#define _NET_VAR_H_
+
+/*
+ *  関数
+ */
+
+extern int_t convert_hexdigit (char *buf, uint_t val, int_t radix, int_t width, char padchar);
+
+/*
+ *  関数
+ */
+
+extern uint32_t net_rand (void);
+extern void net_srand (uint32_t seed);
+
+#endif	/* of #ifndef _NET_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp.c	(revision 398)
@@ -0,0 +1,437 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ */
+
+/* 
+ *  PPP 処理タスクの本体
+ */
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_hdlc.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_lcp.h>
+#include <net/ppp_ipv6cp.h>
+#include <net/ppp_ipcp.h>
+#include <net/ppp_ccp.h>
+#include <net/ppp_upap.h>
+#include <net/ppp_modem.h>
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  全域変数
+ */
+
+uint8_t	ppp_phase = PPP_PHASE_INITIALIZE;	/* リンクの状態		*/
+
+/*
+ *  プロトコル表
+ */
+
+T_PPP_PROTENT *protocols[] = {
+	&lcp_protent,
+
+#ifdef _IP6_CFG
+	&ipv6cp_protent,
+#endif	/* of #ifdef _IP6_CFG */
+
+#ifdef _IP4_CFG
+	&ipcp_protent,
+#endif	/* of #ifdef _IP4_CFG */
+
+#ifdef SUPPORT_CCP
+	&ccp_protent,
+#endif	/* of #ifdef SUPPORT_CCP */
+
+#ifdef LCP_CFG_PAP
+	&pap_protent,
+#endif	/* of #ifdef LCP_CFG_PAP */
+
+#ifdef LCP_CFG_CHAP
+	&chap_protent,
+#endif	/* of #ifdef LCP_CFG_CHAP */
+
+	NULL
+	};
+
+/*
+ *  変数
+ */
+
+#ifdef PPP_IDLE_TIMEOUT
+
+static bool_t idle = false;
+
+#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
+
+/*
+ *  関数
+ */
+
+static void parse_input (T_NET_BUF *input);
+
+#ifdef PPP_IDLE_TIMEOUT
+
+static void idle_timeout (void *arg);
+
+#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
+
+/*
+ *  PPP 入力の解析
+ */
+
+static void
+parse_input(T_NET_BUF *input)
+{
+	T_PPP_PROTENT	*entry;
+	int_t		ix;
+	uint16_t	proto;
+
+	NET_COUNT_PPP(net_count_ppp.in_octets,  input->len);
+	NET_COUNT_PPP(net_count_ppp.in_packets, 1);
+
+	/* フレーム長をチェックする */
+	if (input->len < sizeof(T_PPP_HDR)) {	/* FreeBSD では PPP_HDRLEN は 4 */
+		syslog(LOG_NOTICE, "[PPP] recv short frame.");
+		goto buf_rel;
+		}
+
+	proto = ntohs(*GET_PPP_HDR(input));
+
+	/* プロトコルが LCP 以外で、LCP がオープンされていなければエラー */
+	if (proto != PPP_LCP && lcp_fsm.state != PPP_FSM_OPENED) {
+		syslog(LOG_NOTICE, "[PPP] LCP not open.");
+		goto buf_rel;
+		}
+
+	/* リンクが認証状態以前は、LCP、LQR、PAP、CHAP のみ受け付ける */
+	if (ppp_phase <= PPP_PHASE_AUTHENTICATE &&
+	    !(proto == PPP_LCP || proto == PPP_LQR ||
+	      proto == PPP_PAP || proto == PPP_CHAP)) {
+		syslog(LOG_NOTICE, "[PPP] disc proto: 0x%04x, phase: %d.", proto, ppp_phase);
+		goto buf_rel;
+		}
+
+	/* 上位プロトコルの入力関数を呼出す */
+	for (ix = 0; (entry = protocols[ix]) != NULL; ix ++) {
+		if (entry->proto == proto && entry->input != NULL) {
+			(*entry->input)(input);
+			syscall(rel_net_buf(input));
+			return;
+			}
+		if ((entry->proto & ~0x8000) == proto && entry->datainput != NULL) {
+			(*entry->datainput)(input);
+			return;
+			}
+		}
+
+	syslog(LOG_INFO, "[PPP] unexp proto: 0x%04x.", proto);
+	lcp_sprotrej(input);
+
+buf_rel:
+	NET_COUNT_PPP(net_count_ppp.in_err_packets, 1);
+	syscall(rel_net_buf(input));
+	}
+
+/*
+ *  ppp_output -- PPP インタフェースの出力関数
+ */
+
+ER
+ppp_output (T_NET_BUF *output, TMO tmout)
+{
+	ER error = E_OK;
+
+#ifdef PPP_CFG_MODEM
+
+#if 0	/* 保留 */
+	/* モデムの接続完了まで待つ。*/
+	if ((error = wait_modem()) != E_OK)
+		goto buf_ret;
+#endif
+
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+#ifdef _IP6_CFG
+	/* IPV6CP の接続完了まで待つ。*/
+	if ((error = wait_ipv6cp()) != E_OK)
+		goto buf_ret;
+#endif	/* of #ifdef _IP6_CFG */
+
+#ifdef _IP4_CFG
+	/* IPCP の接続完了まで待つ。*/
+	if ((error = wait_ipcp()) != E_OK)
+		goto buf_ret;
+#endif	/* of #ifdef _IP4_CFG */
+
+#ifdef _IP4_CFG
+	/* IPCP の接続完了まで待つ。*/
+	if ((error = wait_ipcp()) != E_OK)
+		goto buf_ret;
+#endif	/* of #ifdef _IP4_CFG */
+
+#ifdef PPP_IDLE_TIMEOUT
+	wai_sem(SEM_IDLE_TIMEOUT);
+	if (idle) {
+		untimeout((FP)idle_timeout, NULL);
+		idle = false;
+		}
+	sig_sem(SEM_IDLE_TIMEOUT);
+#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
+
+	/* PPP 出力キューに投入する。*/
+	if ((error = tsnd_dtq(DTQ_PPP_OUTPUT, output, tmout)) != E_OK)
+		goto buf_ret;
+
+#ifdef PPP_IDLE_TIMEOUT
+	wai_sem(SEM_IDLE_TIMEOUT);
+	if (!idle && ppp_phase == PPP_PHASE_NETWORK) {
+		timeout((FP)idle_timeout, NULL, PPP_IDLE_TIMEOUT);
+		idle = true;
+		}
+	sig_sem(SEM_IDLE_TIMEOUT);
+#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
+
+	return error;
+
+buf_ret:
+	syscall(rel_net_buf(output));
+	NET_COUNT_PPP(net_count_ppp.out_err_packets, 1);
+	return error;
+	}
+
+/*
+ *  ppp_cp_output -- CP フレームの送信
+ */
+
+void
+ppp_cp_output (uint8_t code, uint8_t id, T_NET_BUF *output)
+{
+	T_PPP_CP_HDR	*cph;
+
+	/* CP ヘッダを設定する */
+	cph = GET_PPP_CP_HDR(output);
+	cph->code = code;
+	cph->id   = id;
+	cph->len  = htons(output->len - sizeof(T_PPP_HDR));
+
+	/* PPP 出力キューに投入する。*/
+	if (snd_dtq(DTQ_PPP_OUTPUT, output) != E_OK) {
+		syscall(rel_net_buf(output));
+		NET_COUNT_PPP(net_count_ppp.out_err_packets, 1);
+		}
+	}
+
+/*
+ *  PPP 入力タスク
+ */
+
+void
+ppp_input_task(intptr_t exinf)
+{
+	T_NET_BUF	*input;
+	T_PPP_PROTENT	*proto;
+	ID		tskid;
+	int_t		ix;
+	uint8_t		rcount = 0;
+
+	/* ポートを初期設定する */
+	syscall(serial_opn_por(HDLC_PORTID));
+	syscall(serial_ctl_por(HDLC_PORTID, IOCTL_FCSND | IOCTL_FCRCV));
+
+	get_tid(&tskid);
+
+#ifdef PPP_CFG_MODEM
+
+	init_modem();
+	syslog(LOG_NOTICE, "[PPP INPUT:%d] started with modem on port %d.", tskid, HDLC_PORTID);
+
+#else	/* of #ifdef PPP_CFG_MODEM */
+
+	syslog(LOG_NOTICE, "[PPP INPUT:%d] started on port %d.", tskid, HDLC_PORTID);
+
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+	/* ネットワークタイマタスクを起動する */
+	syscall(act_tsk(NET_TIMER_TASK));
+
+	/* 上位プロトコルを初期化する */
+	for (ix = 0; (proto = protocols[ix]) != NULL; ix ++)
+		if (proto->init != NULL)
+			(*proto->init)();
+
+	lcp_lowerup();
+	lcp_open(PPP_OPEN_PASSIVE);
+
+	/* PPP 出力タスクを起動する */
+	syscall(act_tsk(PPP_OUTPUT_TASK));
+
+	/* 乱数生成を初期化する。*/
+	net_srand(0);
+
+	while (true) {
+		if (tget_net_buf(&input, IF_PDU_SIZE, TMO_PPP_GET_NET_BUF) == E_OK) {
+			while (HDLC_read(input, IF_PDU_SIZE) != E_OK)
+				;
+			if (input->len > 0) {
+
+				/* 乱数生成を初期化する。*/
+				if (rcount == 0)
+					net_srand(input->len);
+				rcount ++;
+
+#ifdef PPP_IDLE_TIMEOUT
+				wai_sem(SEM_IDLE_TIMEOUT);
+				if (idle && ntohs(*GET_PPP_HDR(input)) != PPP_LCP) {
+					untimeout((FP)idle_timeout, NULL);
+					idle = false;
+					}
+				sig_sem(SEM_IDLE_TIMEOUT);
+#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
+
+				parse_input(input);
+				}
+			else
+				syscall(rel_net_buf(input));
+
+#ifdef PPP_IDLE_TIMEOUT
+			wai_sem(SEM_IDLE_TIMEOUT);
+			if (!idle && ppp_phase == PPP_PHASE_NETWORK) {
+				timeout((FP)idle_timeout, NULL, PPP_IDLE_TIMEOUT);
+				idle = true;
+				}
+			else if (idle && ppp_phase != PPP_PHASE_NETWORK) {
+				untimeout((FP)idle_timeout, NULL);
+				idle = false;
+				}
+			sig_sem(SEM_IDLE_TIMEOUT);
+#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
+
+			}
+		else {
+			HDLC_dummy_read();
+			NET_COUNT_PPP(net_count_ppp.in_err_packets, 1);
+			NET_COUNT_PPP(net_count_ppp_no_bufs, 1);
+			}
+		}
+	}
+
+/*
+ *  PPP 出力タスク
+ */
+
+void
+ppp_output_task(intptr_t exinf)
+{
+	T_NET_BUF	*output;
+	ID		tskid;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[PPP OUTPUT:%d] started.", tskid);
+
+	while (true) {
+		while (rcv_dtq(DTQ_PPP_OUTPUT, (intptr_t*)&output) == E_OK) {
+			NET_COUNT_PPP(net_count_ppp.out_octets,  output->len);
+			NET_COUNT_PPP(net_count_ppp.out_packets, 1);
+			syscall(HDLC_write(output));
+			syscall(rel_net_buf(output));
+			}
+		}
+	}
+
+#ifdef PPP_IDLE_TIMEOUT
+
+/*
+ *  アイドルタイムアウト処理
+ */
+
+static void
+idle_timeout (void *arg)
+{
+	syslog(LOG_NOTICE, "[PPP] idel %d [s], disconnecting.", (uint16_t)(PPP_IDLE_TIMEOUT / NET_TIMER_HZ));
+	lcp_close();
+	}
+
+#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
+
+#endif	/* fo #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp.cfg	(revision 398)
@@ -0,0 +1,74 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  PPP コンフィギュレーションファイル
+ */
+
+#ifdef SUPPORT_PPP
+
+CRE_TSK(PPP_OUTPUT_TASK, {
+	TA_HLNG,
+	0,
+	ppp_output_task,
+	PPP_OUTPUT_PRIORITY,
+	PPP_OUTPUT_STACK_SIZE,
+	NULL
+	});
+
+CRE_TSK(PPP_INPUT_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	ppp_input_task,
+	PPP_INPUT_PRIORITY,
+	PPP_INPUT_STACK_SIZE,
+	NULL
+	});
+
+CRE_DTQ(DTQ_PPP_OUTPUT,   { TA_TFIFO, NUM_DTQ_PPP_OUTPUT,  NULL });
+
+CRE_SEM(SEM_MODEM_READY,  { TA_TPRI, 0, 1 });
+
+#if defined(_IP6_CFG)
+CRE_SEM(SEM_IPV6CP_READY, { TA_TPRI, 0, 1 });
+#endif
+
+#if defined(_IP4_CFG)
+CRE_SEM(SEM_IPCP_READY,   { TA_TPRI, 0, 1 });
+#endif
+
+#ifdef PPP_IDLE_TIMEOUT
+CRE_SEM(SEM_IDLE_TIMEOUT, { TA_TPRI, 1, 1 });
+#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
+
+#endif	/* of #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp.h	(revision 398)
@@ -0,0 +1,138 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ */
+
+#ifndef _PPP_H_
+#define _PPP_H_
+
+/*
+ *  PPP ヘッダのプロトコルフィールドの値
+ */
+
+#define PPP_IP		UINT_C(0x0021)		/* IPv4		*/
+#define PPP_IPV6	UINT_C(0x0057)		/* IPv6		*/
+
+#define PPP_IPCP	UINT_C(0x8021)		/* IPCP		*/
+#define PPP_IPV6CP	UINT_C(0x8057)		/* IPV6CP	*/
+#define PPP_CCP		UINT_C(0x80fd)		/* CCP		*/
+
+#define PPP_LCP		UINT_C(0xc021)		/* LCP		*/
+#define PPP_PAP		UINT_C(0xc023)		/* PAP		*/
+#define PPP_LQR		UINT_C(0xc025)		/* LQR		*/
+#define PPP_CHAP	UINT_C(0xc223)		/* CHAP		*/
+
+#define GET_PPP_HDR(nbuf)	((T_PPP_HDR*)((nbuf)->buf))
+
+/*
+ *  リンクの状態
+ */
+
+#define PPP_PHASE_DEAD		0
+#define PPP_PHASE_INITIALIZE	1
+#define PPP_PHASE_DORMANT	2
+#define PPP_PHASE_ESTABLISH	3
+#define PPP_PHASE_AUTHENTICATE	4
+#define PPP_PHASE_CALLBACK	5
+#define PPP_PHASE_NETWORK	6
+#define PPP_PHASE_TERMINATE	7
+#define PPP_PHASE_HOLDOFF	8
+
+/*
+ *  PPP リンク制御 (CP) ヘッダ構造体
+ */
+
+typedef struct t_ppp_cp_hdr {
+	uint8_t		code;		/* 制御コード	*/
+	uint8_t		id;		/* 識別子	*/
+	uint16_t	len;		/* 長さ		*/
+	} __attribute__((packed, aligned(2)))T_PPP_CP_HDR;
+
+#define GET_PPP_CP_HDR(nbuf)	((T_PPP_CP_HDR*)((nbuf)->buf + sizeof(T_PPP_HDR)))
+
+/*
+ *  PPP リンク制御 (CP) の制御コード
+ */
+
+#define PPP_VENDER		UINT_C(0)	/* Vender Specific		*/
+#define PPP_CONFREQ		UINT_C(1)	/* Configuration Request	*/
+#define PPP_CONFACK		UINT_C(2)	/* Configuration ACK		*/
+#define PPP_CONFNAK		UINT_C(3)	/* Configuration NAK		*/
+#define PPP_CONFREJ		UINT_C(4)	/* Configuration Reject		*/
+#define PPP_TERMREQ		UINT_C(5)	/* Termination Request		*/
+#define PPP_TERMACK		UINT_C(6)	/* Termination ACK		*/
+#define PPP_CODEREJ		UINT_C(7)	/* Code Reject			*/
+
+/*
+ * 構成情報 (CI) ヘッダ
+ */
+
+typedef struct t_ppp_ci_hdr {
+	uint8_t		type;		/* CI の型	*/
+	uint8_t		len;		/* 長さ		*/
+	} __attribute__((packed, aligned(2)))T_PPP_CI_HDR;
+
+#endif	/* of #ifndef _PPP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_auth.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_auth.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_auth.c	(revision 398)
@@ -0,0 +1,281 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * auth.c - PPP authentication and phase control.
+ *
+ * Copyright (c) 1993 The Australian National 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 the Australian National 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *			PPP Secret Key Module
+ *
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan, Inc.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/auth.c,v 1.50 1999/12/27 11:43:30 brian Exp $
+ *
+ *	TODO:
+ *		o Implement check against with registered IP addresses.
+ */
+
+#include <s_services.h>
+#include <t_services.h>
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_auth.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_lcp.h>
+#include <net/ppp_upap.h>
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  定数
+ */
+
+#define PAP_PEND_SERVER		UINT_C(0x01)
+#define PAP_PEND_CLIENT		UINT_C(0x02)
+#define CHAP_PEND_SERVER	UINT_C(0x04)
+#define CHAP_PEND_CLIENT	UINT_C(0x08)
+
+/*
+ *  network_phase -- コネクション確立
+ */
+
+void
+network_phase (void)
+{
+	int_t		num, ix;
+	T_PPP_PROTENT	*proto;
+
+	ppp_phase = PPP_PHASE_NETWORK;
+
+	/* 上位プロトコルをオープンする */
+	num = 0;
+	for (ix = 0; (proto = protocols[ix]) != NULL; ix ++)
+#if 0	/* 保留、削除禁止 */
+		if (proto->proto < 0xc000 && proto->open != NULL) {
+#else	/* of #if 0 */
+		if (proto->open != NULL) {
+#endif	/* of #if 0 */
+			(*proto->open)();
+			if (proto->proto != PPP_CCP)
+				num ++;
+			}
+
+	if (num == 0)
+		/* 上位プロトコルがない */
+		lcp_close();
+	else
+		syslog(LOG_NOTICE, "[PPP] up.");
+	}
+
+/*
+ *  link_required -- リンクを開設する。
+ */
+
+void
+link_required (void)
+{
+	}
+
+/*
+ *  link_terminated -- ログアウトして、リンクを切断する。
+ */
+
+void
+link_terminated (void)
+{
+	ppp_phase     = PPP_PHASE_DEAD;
+	ppp_open_mode = PPP_OPEN_PASSIVE;
+	syslog(LOG_NOTICE, "[PPP] down.");
+	}
+
+/*
+ *  link_down -- リンクを解放する。
+ */
+
+void
+link_down (void)
+{
+	int_t		ix;
+	T_PPP_PROTENT	*proto;
+
+	/* 上位プロトコルを解放する */
+	for (ix = 0; (proto = protocols[ix]) != NULL; ix ++) {
+		if (proto->proto != PPP_LCP && proto->lowerdown != NULL)
+			(*proto->lowerdown)();
+		if (proto->proto < 0xc000 && proto->close != NULL)
+			(*proto->close)();
+		}
+
+	if (ppp_phase != PPP_PHASE_DEAD)
+		ppp_phase = PPP_PHASE_TERMINATE;
+	}
+
+/*
+ *  link_established -- リンクの接続が確立した。
+ */
+
+void
+link_established (void)
+{
+	int_t		ix;
+	T_PPP_PROTENT	*proto;
+
+#if defined(LCP_CFG_CHAP) || defined(LCP_CFG_PAP)
+
+	int		auth;
+
+#endif	/* of #if defined(LCP_CFG_CHAP) || defined(LCP_CFG_PAP) */
+
+	/* 上位プロトコルを起動する */
+	for (ix = 0; (proto = protocols[ix]) != NULL; ix ++)
+		if (proto->lowerup != NULL)
+			(*proto->lowerup)();
+
+	/* 認証オプションを確認する。【未実装】*/
+
+	ppp_phase = PPP_PHASE_AUTHENTICATE;
+
+#if defined(LCP_CFG_CHAP) || defined(LCP_CFG_PAP)
+
+	auth = 0;
+
+#ifdef AUTH_CFG_SERVER
+
+#if defined(LCP_CFG_CHAP)
+
+	if (lcp_local_ack_cfg.options & LCP_CFG_CHAP) {
+		chap_auth_server();
+		auth |= CHAP_PEND_SERVER;
+		}
+
+#endif	/* of #if defined(LCP_CFG_CHAP) */
+
+#if defined(LCP_CFG_PAP)
+	
+	if (lcp_local_ack_cfg.options & LCP_CFG_PAP) {
+		upap_auth_server();
+		auth |= PAP_PEND_SERVER;
+		}
+
+#endif	/* of #if defined(LCP_CFG_PAP) */
+
+#endif	/* of #ifdef AUTH_CFG_SERVER */
+
+#ifdef AUTH_CFG_CLIENT
+
+#if defined(LCP_CFG_PAP)
+	
+	if (lcp_remote_ack_cfg.options & LCP_CFG_PAP) {
+		upap_auth_client();
+		auth |= PAP_PEND_CLIENT;
+		}
+
+#endif	/* of #if defined(LCP_CFG_PAP) */
+
+#endif	/* of #ifdef AUTH_CFG_CLIENT */
+
+	if (auth == 0)
+		network_phase();
+
+#else	/* of #if defined(LCP_CFG_CHAP) || defined(LCP_CFG_PAP) */
+
+	network_phase();
+
+#endif	/* of #if defined(LCP_CFG_CHAP) || defined(LCP_CFG_PAP) */
+
+	}
+
+/*
+ *  auth_reset -- 認証オプションを再確認する。
+ */
+
+void
+auth_reset (void)
+{
+	}
+
+#endif	/* fo #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_auth.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_auth.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_auth.h	(revision 398)
@@ -0,0 +1,74 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/auth.h,v 1.18 1999/08/28 01:18:16 peter Exp $
+ *
+ *	TODO:
+ */
+
+#ifndef _PPP_AUTH_H_
+#define _PPP_AUTH_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  関数
+ */
+
+extern void link_required (void);
+extern void link_established (void);
+extern void link_terminated (void);
+extern void link_down (void);
+extern void auth_reset (void);
+extern void network_phase (void);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _PPP_AUTH_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ccp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ccp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ccp.c	(revision 398)
@@ -0,0 +1,240 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * ccp.c - PPP Compression Control Protocol.
+ *
+ * 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.
+ */
+
+/*
+ *	   PPP Compression Control Protocol (CCP) Module
+ *
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1994, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan, Inc.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/ccp.c,v 1.54.2.2 2000/08/19 09:29:59 brian Exp $
+ *
+ *	TODO:
+ *		o Support other compression protocols
+ */
+
+/*
+ *  実装予定、現在はすべて拒否
+ */
+
+#include <t_services.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_ccp.h>
+
+/*
+ *  関数
+ */
+
+static void ccp_init (void);
+static void ccp_input (T_NET_BUF *nbuf);
+static void ccp_protrej (void);
+static void ccp_lowerup (void);
+static void ccp_lowerdown (void);
+static void ccp_open (void);
+static void ccp_close (void);
+
+/*
+ * FSM から呼出されるコールバック関
+ */
+
+static int_t  ccp_reqci	(T_PPP_FSM *fsm, T_NET_BUF *nbuf);
+					/* 相手の構成情報を確認する。	*/
+
+/*
+ *  全域変数
+ */
+
+T_PPP_FSM_CALLBACKS ccp_callbacks = {
+	NULL,				/* 自構成情報をリセットする。	*/
+	NULL,				/* 構成情報の長さを返す。		*/
+	NULL,				/* 自構成情報を追加する。		*/
+	NULL,				/* ACK を受信したときの処理	*/
+	NULL,				/* NAK を受信したときの処理	*/
+	NULL,				/* REJ を受信したときの処理	*/
+	ccp_reqci,			/* 相手の構成情報を確認する。	*/
+	NULL,				/* リンク接続を確立する。		*/
+	NULL,				/* リンク接続を解放する。		*/
+	NULL,				/* 下位層を開始する。		*/
+	NULL,				/* 下位層を終了する。		*/
+	NULL,				/* 再送する。			*/
+	NULL,				/* 不明な CP を受信したときの処理	*/
+	};
+
+T_PPP_FSM ccp_fsm = {
+	&ccp_callbacks,			/* コールバック関数		*/
+	PPP_CCP,			/* プロトコル			*/
+	};
+
+T_PPP_PROTENT ccp_protent = {
+	PPP_CCP,
+	ccp_init,			/* 初期化			*/
+	ccp_input,			/* 入力				*/
+	ccp_protrej,			/* Proto-REJ 受信処理		*/
+	ccp_lowerup,			/* 下位層を起動する		*/
+	ccp_lowerdown,			/* 下位層を停止する		*/
+	ccp_open,			/* オープンする			*/
+	ccp_close,			/* クローズする			*/
+	NULL,				/* データ入力			*/
+	};
+
+/*
+ *  ccp_init -- CCP モジュールの初期化
+ */
+
+static void
+ccp_init (void)
+{
+	fsm_init(&ccp_fsm);
+	}
+
+/*
+ *  ccp_input -- CCP 入力
+ */
+
+static void
+ccp_input (T_NET_BUF *nbuf)
+{
+	NET_COUNT_PPP_CCP(net_count_ppp_ccp_in_octets,  nbuf->len);
+	NET_COUNT_PPP_CCP(net_count_ppp_ccp_in_packets, 1);
+	fsm_input(&ccp_fsm, nbuf);
+	}
+
+/*
+ *  ccp_reqci -- 相手の構成情報を解析する。
+ */
+
+static int_t
+ccp_reqci (T_PPP_FSM *fsm, T_NET_BUF *nbuf)
+{
+/*
+ *  実装予定、現在はすべてのオプションを拒否する。
+ */
+	return nbuf->len > (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)) ? PPP_CONFREJ : PPP_CONFACK;
+	}
+
+/*
+ *  ccp_protrej -- Proto-REJ を受信したときの処理
+ */
+
+static void
+ccp_protrej (void)
+{
+	fsm_lowerdown(&ccp_fsm);
+	}
+
+/*
+ *  ccp_lowerup -- CCP 下位層を起動する。
+ */
+
+static void
+ccp_lowerup (void)
+{
+	fsm_lowerup(&ccp_fsm);
+	}
+
+/*
+ *  ccp_lowerdown -- CCP 下位層を停止する。
+ */
+
+static void
+ccp_lowerdown (void)
+{
+	fsm_lowerdown(&ccp_fsm);
+	}
+
+/*
+ *  ccp_open -- CCP のオープ
+ */
+
+static void
+ccp_open (void)
+{
+	fsm_open(&ccp_fsm);
+	}
+
+/*
+ *  ccp_close -- CCP のクローズ
+ */
+
+static void
+ccp_close (void)
+{
+	fsm_close(&ccp_fsm);
+	}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ccp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ccp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ccp.h	(revision 398)
@@ -0,0 +1,98 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * ccp.h - Definitions for PPP Compression Control Protocol.
+ *
+ * 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.
+ *
+ * $FreeBSD: src/usr.sbin/pppd/ccp.h,v 1.7.2.1 1999/08/29 15:46:56 peter Exp $
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/ccp.h,v 1.22 1999/08/28 01:18:19 peter Exp $
+ *
+ *	TODO:
+ */
+
+#ifndef _PPP_CCP_H_
+#define _PPP_CCP_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  変数
+ */
+
+extern T_PPP_PROTENT	ccp_protent;
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _PPP_CCP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_fsm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_fsm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_fsm.c	(revision 398)
@@ -0,0 +1,807 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * fsm->c - {Link, IP} Control Protocol Finite State Machine.
+ *
+ * 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *		PPP Finite State Machine for LCP/IPCP
+ *
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan, Inc.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/fsm->c,v 1.52.2.3 2000/08/19 09:30:03 brian Exp $
+ *
+ *  TODO:
+ */
+
+#include <string.h>
+
+#include <s_services.h>
+#include <t_services.h>
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_timer.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_hdlc.h>
+#include <net/ppp_fsm.h>
+
+#include <netinet/in.h>
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  全域変数
+ */
+
+uint8_t	ppp_open_mode = PPP_OPEN_PASSIVE;	/* オープン時の動作モード	*/
+
+/*
+ *  関数
+ */
+
+static void fsm_sconfreq	(T_PPP_FSM *fsm, int_t retansmit);
+static void fsm_rconfreq	(T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input);
+static void fsm_rconfack	(T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input);
+static void fsm_rconfnakrej	(T_PPP_FSM *fsm, uint8_t code, uint8_t id, T_NET_BUF *input);
+static void fsm_rtermreq	(T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input);
+static void fsm_rtermack	(T_PPP_FSM *fsm, T_NET_BUF *input);
+static void fsm_rcoderej	(T_PPP_FSM *fsm, T_NET_BUF *input);
+static void fsm_stermreq	(T_PPP_FSM *fsm, uint8_t id);
+static void fsm_timeout		(void *arg);
+
+/*
+ *  fsm_sconfreq -- Configure-Request を送信する。
+ */
+
+static void
+fsm_sconfreq (T_PPP_FSM *fsm, int_t retransmit)
+{
+	T_NET_BUF	*output;
+	uint16_t	len;
+
+	if (!(fsm->state == PPP_FSM_REQSENT ||
+	      fsm->state == PPP_FSM_ACKRCVD ||
+	      fsm->state == PPP_FSM_ACKSENT)) {
+		/* まだネゴをしていない。オプションをリセットする。 */
+		if (fsm->callbacks->resetci)
+			(*fsm->callbacks->resetci)(fsm);
+		fsm->failures = 0;
+		}
+	if (retransmit == 0) {
+		/* 新しいリクエスト。再送カウンタをリセットし、新しい ID を設定する。 */
+		fsm->retrans = MAX_PPP_CONFIGURES;
+		fsm->reqid   = ++ fsm->id;
+		}
+
+	fsm->seen_ack = 0;
+
+	if (fsm->callbacks->cilen && fsm->callbacks->addci) {
+		/* 構成情報パケットを作る。 */
+		len = (*fsm->callbacks->cilen)(fsm);
+
+		syscall(get_net_buf(&output, len + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
+		(*fsm->callbacks->addci)(fsm, output);
+
+		/* 構成情報パケットを送信する。 */
+		IF_SET_PROTO(output, fsm->proto);
+		ppp_cp_output(PPP_CONFREQ, fsm->reqid, output);
+
+		-- fsm->retrans;
+		timeout((FP)fsm_timeout, fsm, DEF_PPP_TIMEOUT);
+		}
+	}
+
+/*
+ *  fsm_rconfreq -- Configure-Request を受信したときの処理
+ */
+
+static void
+fsm_rconfreq (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input)
+{
+	T_NET_BUF	*output;
+	uint16_t	code;
+
+	switch (fsm->state) {
+	case PPP_FSM_CLOSED:
+		syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
+		memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+		ppp_cp_output(PPP_TERMACK, id, output);
+		return;
+		break;
+
+	case PPP_FSM_CLOSING:
+	case PPP_FSM_STOPPING:
+		return;
+		break;
+
+	case PPP_FSM_OPENED:
+		/* 上位層を停止して、ネゴに移る。 */
+		if (fsm->callbacks->down != NULL)
+			(*fsm->callbacks->down)(fsm);
+		fsm_sconfreq(fsm, 0);		/* 最初の Configure-Request を送る。 */
+		break;
+
+	case PPP_FSM_STOPPED:
+		/* 相手からネゴが開始された */
+		fsm_sconfreq(fsm, 0);		/* 最初の Configure-Request を送る。 */
+		fsm->state = PPP_FSM_REQSENT;
+		break;
+
+		}
+
+	syscall(get_net_buf(&output, input->len));
+
+	/* 上位プロトコルに要求された Configure-Request を送る。 */
+	if (fsm->callbacks->reqci != NULL)	/* 構成情報をチェックする。 */
+		code = (*fsm->callbacks->reqci)(fsm, input, output);
+	else if (output->len > sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR))
+		code = PPP_CONFREJ;
+	else
+		code = PPP_CONFACK;
+
+	/* 相手に ACK, NAK または REJ を送信する。 */
+	ppp_cp_output(code, id, output);
+
+	if (code == PPP_CONFACK) {
+		if (fsm->state == PPP_FSM_ACKRCVD) {
+			untimeout((FP)fsm_timeout, fsm);
+			fsm->state = PPP_FSM_OPENED;
+			if (fsm->callbacks->up != NULL)
+				(*fsm->callbacks->up)(fsm);
+			}
+		else
+			fsm->state = PPP_FSM_ACKSENT;
+		fsm->failures = 0;
+		}
+	else {
+		/* ACK か REJ を送る */
+		if (fsm->state != PPP_FSM_ACKRCVD)
+			fsm->state = PPP_FSM_REQSENT;
+		if (code == PPP_CONFNAK)
+			fsm->failures ++;
+		}
+	}
+
+/*
+ *  fsm_rconfnakrej -- Configure-NAK/REJ を受信したときの処理
+ */
+
+static void
+fsm_rconfnakrej (T_PPP_FSM *fsm, uint8_t code, uint8_t id, T_NET_BUF *input)
+{
+	int_t		ret = 0;
+	T_NET_BUF	*output;
+
+	/* 予期した ID でないか、NAK/REJ を予期していないときは終了する。*/
+	if (id != fsm->reqid || fsm->seen_ack) {
+		syslog(LOG_WARNING, "[PPP/FSM] bad ID or unexp NAK/REJ.");
+		return;
+		}
+
+	if (code == PPP_CONFNAK) {
+		if (fsm->callbacks->nakci != NULL && (ret = (*fsm->callbacks->nakci)(fsm, input)) == 0) {
+			syslog(LOG_WARNING, "[PPP/FSM] bad NAK.");
+			return;
+			}
+		}
+	else {
+		if (fsm->callbacks->rejci != NULL && (ret = (*fsm->callbacks->rejci)(fsm, input)) == 0) {
+			syslog(LOG_WARNING, "[PPP/FSM] bad REJ.");
+			return;
+			}
+		}
+
+	fsm->seen_ack = 1;
+
+	switch (fsm->state) {
+	case PPP_FSM_CLOSED:
+	case PPP_FSM_STOPPED:
+		syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
+		memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+		ppp_cp_output(PPP_TERMACK, id, output);
+		return;
+		break;
+
+	case PPP_FSM_REQSENT:
+	case PPP_FSM_ACKSENT:
+		untimeout((FP)fsm_timeout, fsm);
+		if (ret < 0)		/* 送信した Conf-Req が破損し空の NAK/REJ が届いた。*/
+			fsm->state = PPP_FSM_STOPPED;
+		else
+			fsm_sconfreq(fsm, 0);
+		break;
+
+	case PPP_FSM_ACKRCVD:
+		untimeout((FP)fsm_timeout, fsm);
+		fsm_sconfreq(fsm, 0);
+		fsm->state = PPP_FSM_REQSENT;
+		break;
+
+	case PPP_FSM_OPENED:
+		/* 再起動し、ネゴをやり直す。*/
+		if (fsm->callbacks->down != NULL)
+			(*fsm->callbacks->down)(fsm);
+		fsm_sconfreq(fsm, 0);
+		fsm->state = PPP_FSM_REQSENT;
+		break;
+		}
+	}
+
+/*
+ *  fsm_rconfack -- Configure-ACK を受信したときの処理
+ */
+
+static void
+fsm_rconfack (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input)
+{
+	T_NET_BUF	*output;
+
+	/* 予期した ID でないか、ACK を予期していないときは終了する。*/
+	if (id != fsm->reqid || fsm->seen_ack) {
+		syslog(LOG_WARNING, "[PPP/FSM] bad ID or unexp ACK.");
+		return;
+		}
+
+	if (fsm->callbacks->ackci != NULL) {
+		if ((*fsm->callbacks->ackci)(fsm, input) != true) {
+			syslog(LOG_WARNING, "[PPP/FSM] bad ACK.");
+			return;
+			}
+		}
+	else if (input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)) != 0) {
+		syslog(LOG_WARNING, "[PPP/FSM] bad ACK.");
+		return;
+		}
+
+	fsm->seen_ack = 1;
+
+	switch (fsm->state) {
+	case PPP_FSM_CLOSED:
+	case PPP_FSM_STOPPED:
+		syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
+		memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+		ppp_cp_output(PPP_TERMACK, id, output);
+		break;
+
+	case PPP_FSM_REQSENT:
+		fsm->state = PPP_FSM_ACKRCVD;
+		fsm->retrans = MAX_PPP_CONFIGURES;
+		break;
+
+	case PPP_FSM_ACKRCVD:
+		untimeout((FP)fsm_timeout, fsm);
+		fsm_sconfreq(fsm, 0);
+		fsm->state = PPP_FSM_REQSENT;
+		break;
+
+	case PPP_FSM_ACKSENT:
+		untimeout((FP)fsm_timeout, fsm);
+		fsm->state = PPP_FSM_OPENED;
+		fsm->retrans = MAX_PPP_CONFIGURES;
+		if (fsm->callbacks->up != NULL)
+			(*fsm->callbacks->up)(fsm);
+		break;
+
+	case PPP_FSM_OPENED:
+		/* 再起動し、ネゴをやり直す。*/
+		if (fsm->callbacks->down != NULL)
+			(*fsm->callbacks->down)(fsm);
+		fsm_sconfreq(fsm, 0);
+		fsm->state = PPP_FSM_REQSENT;
+		break;
+
+	default	:
+		syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in recv Conf-ACK.", fsm->state);
+		break;
+		}
+
+	}
+
+/*
+ *  fsm_rtermreq -- Terminate-Request を受信したときの処理
+ */
+
+static void
+fsm_rtermreq (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input)
+{
+	T_NET_BUF	*output;
+
+	switch (fsm->state) {
+	case PPP_FSM_ACKRCVD:
+	case PPP_FSM_ACKSENT:
+		fsm->state = PPP_FSM_REQSENT;
+		break;
+
+	case PPP_FSM_OPENED:
+		if (fsm->callbacks->down != NULL)
+			(*fsm->callbacks->down)(fsm);
+		fsm->retrans = 0;
+		fsm->state = PPP_FSM_STOPPING;
+		timeout((FP)fsm_timeout, fsm, DEF_PPP_TIMEOUT);
+		break;
+		}
+	syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
+	memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+	ppp_cp_output(PPP_TERMACK, id, output);
+	}
+
+/*
+ *  fsm_rtermack -- Terminate-ACK を受信したときの処理
+ */
+
+static void
+fsm_rtermack (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	switch (fsm->state) {
+	case PPP_FSM_CLOSING:
+		untimeout((FP)fsm_timeout, fsm);
+#if 0	/* 本来の動作は CLOSED に遷移する。*/
+		fsm->state = PPP_FSM_CLOSED;
+#else	/* of #if 0 */
+		fsm->state = PPP_FSM_STOPPED;
+#endif	/* of #if 0 */
+		if (fsm->callbacks->finished != NULL)
+			(*fsm->callbacks->finished)(fsm);
+		break;
+
+	case PPP_FSM_STOPPING:
+		untimeout((FP)fsm_timeout, fsm);
+		fsm->state = PPP_FSM_STOPPED;
+		if (fsm->callbacks->finished != NULL)
+			(*fsm->callbacks->finished)(fsm);
+		break;
+
+	case PPP_FSM_ACKRCVD:
+		fsm->state = PPP_FSM_REQSENT;
+		break;
+
+	case PPP_FSM_OPENED:
+		if (fsm->callbacks->down != NULL)
+			(*fsm->callbacks->down)(fsm);
+		fsm_sconfreq(fsm, 0);
+		break;
+		}
+	}
+
+/*
+ *  fsm_rcoderej -- Code-REJ を受信したときの処理
+ */
+
+static void
+fsm_rcoderej (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_PPP_CP_HDR	*hdr;
+
+ 	/* PPP リンク制御 (CP) ヘッダより短ければエラー */
+ 	if (input->len < sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)) {
+ 		syslog(LOG_WARNING, "[PPP/FSM] bad len: %d in recv Code-REJ.", input->len);
+ 		return;
+ 		}
+
+ 	hdr = GET_PPP_CP_HDR(input);
+
+	syslog(LOG_WARNING, "[PPP/FSM] recv Code-REJ, code=%d, id=%d.", hdr->code, hdr->id);
+
+	if (fsm->state == PPP_FSM_ACKRCVD)
+		fsm->state = PPP_FSM_REQSENT;
+	}
+
+/*
+ *  fsm_timeout -- タイムアウト処理
+ */
+
+static void
+fsm_timeout (void *arg)
+{
+	T_PPP_FSM *fsm = (T_PPP_FSM*)arg;
+
+	switch (fsm->state) {
+	case PPP_FSM_CLOSING:
+	case PPP_FSM_STOPPING:
+		if (fsm->retrans <= 0) {
+			/* 最大再送回数を超えたときの処理 */
+#if 0	/* 本来の動作は CLOSED に遷移する。*/
+			fsm->state = (fsm->state == PPP_FSM_CLOSING) ? PPP_FSM_CLOSED : PPP_FSM_STOPPED;
+#else	/* of #if 0 */
+			fsm->state = PPP_FSM_STOPPED;
+#endif	/* of #if 0 */
+			if (fsm->callbacks->finished != NULL)
+				(*fsm->callbacks->finished)(fsm);
+			}
+		else {
+			/* Terminate-Request を送信する。*/
+			fsm_stermreq(fsm, ++ fsm->id);
+			}
+		break;
+	case PPP_FSM_REQSENT:
+	case PPP_FSM_ACKRCVD:
+	case PPP_FSM_ACKSENT:
+		if (fsm->retrans <= 0) {
+			/* 最大再送回数を超えたときの処理 */
+			syslog(LOG_WARNING, "[PPP/FSM] retrans Conf-Req.");
+			fsm->state = PPP_FSM_STOPPED;
+			if (ppp_open_mode != PPP_OPEN_PASSIVE && fsm->callbacks->finished)
+				(*fsm->callbacks->finished)(fsm);
+			}
+		else {
+			/* Configure-Request を再送する。*/
+			if (fsm->callbacks->retrans != NULL)
+				(*fsm->callbacks->retrans)(fsm);
+			fsm_sconfreq(fsm, 1);
+			if (fsm->state == PPP_FSM_ACKRCVD)
+				fsm->state = PPP_FSM_REQSENT;
+			}
+
+		break;
+
+	default	:
+		syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in timeout.", fsm->state);
+		break;
+		}
+	}
+
+/*
+ *  fsm_stermreq -- Terminate-Request を送信する。
+ */
+
+static void
+fsm_stermreq (T_PPP_FSM *fsm, uint8_t id)
+{
+	T_NET_BUF	*input;
+
+	syscall(get_net_buf(&input, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
+	IF_SET_PROTO(input, fsm->proto);
+	ppp_cp_output(PPP_TERMREQ, id, input);
+
+	timeout((FP)fsm_timeout, fsm, DEF_PPP_TIMEOUT);
+	fsm->retrans --;
+	}
+
+/*
+ *  fsm_init -- FSM モジュールの初期化
+ */
+
+void
+fsm_init (T_PPP_FSM *fsm)
+{
+	fsm->state = PPP_FSM_INITIAL;
+	fsm->id	   = 0;
+	}
+
+/*
+ *  fsm_lowerup -- FSM 下位層を起動する。
+ */
+
+void
+fsm_lowerup (T_PPP_FSM *fsm)
+{
+	switch (fsm->state) {
+	case PPP_FSM_INITIAL:
+		fsm->state = PPP_FSM_CLOSED;
+		break;
+
+	case PPP_FSM_STARTING:
+		if (ppp_open_mode == PPP_OPEN_PASSIVE)
+			fsm->state = PPP_FSM_STOPPED;
+        	else {
+			fsm_sconfreq(fsm, 0);
+			fsm->state = PPP_FSM_REQSENT;
+			}
+		break;
+
+	default	:
+		syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in lowerup", fsm->state);
+		break;
+		}
+	}
+
+/*
+ *  fsm_lowerdown -- FSM 下位層を停止する。
+ */
+
+void
+fsm_lowerdown (T_PPP_FSM *fsm)
+{
+	switch (fsm->state) {
+	case PPP_FSM_CLOSED:
+		fsm->state = PPP_FSM_INITIAL;
+		break;
+
+	case PPP_FSM_STOPPED:
+		fsm->state = PPP_FSM_STARTING;
+		if (fsm->callbacks->starting != NULL)
+			(*fsm->callbacks->starting)(fsm);
+		break;
+
+	case PPP_FSM_CLOSING:
+		fsm->state = PPP_FSM_INITIAL;
+		untimeout((FP)fsm_timeout, fsm);
+		break;
+
+	case PPP_FSM_STOPPING:
+	case PPP_FSM_REQSENT:
+	case PPP_FSM_ACKRCVD:
+	case PPP_FSM_ACKSENT:
+		fsm->state = PPP_FSM_STARTING;
+		untimeout((FP)fsm_timeout, fsm);
+		break;
+
+	case PPP_FSM_OPENED:
+		if (fsm->callbacks->down != NULL)
+			(*fsm->callbacks->down)(fsm);
+		fsm->state = PPP_FSM_STARTING;
+		break;
+
+	default	:
+		syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in lowerdown", fsm->state);
+		break;
+		}
+	}
+
+/*
+ *  fsm_open -- FSM のオープン
+ */
+
+void
+fsm_open (T_PPP_FSM *fsm)
+{
+	switch (fsm->state) {
+	case PPP_FSM_INITIAL:
+		fsm->state = PPP_FSM_STARTING;
+		if (fsm->callbacks->starting != NULL)
+			(*fsm->callbacks->starting)(fsm);
+		break;
+
+	case PPP_FSM_CLOSED:
+		if (ppp_open_mode == PPP_OPEN_PASSIVE)
+			fsm->state = PPP_FSM_STOPPED;
+		else {
+			fsm_sconfreq(fsm, 0);
+			fsm->state = PPP_FSM_REQSENT;
+			}
+		break;
+
+	case PPP_FSM_CLOSING:
+		fsm->state = PPP_FSM_STOPPING;
+		/* nobreak;	下に落ちる */
+
+	case PPP_FSM_STOPPED:
+	case PPP_FSM_OPENED:
+		fsm_lowerdown(fsm);
+		fsm_lowerup(fsm);
+		break;
+		}
+	}
+
+/*
+ *  fsm_close -- リンクの切断を開始する。
+ */
+
+void
+fsm_close (T_PPP_FSM *fsm)
+{
+	switch (fsm->state) {
+	case PPP_FSM_STARTING:
+		fsm->state = PPP_FSM_INITIAL;
+		break;
+
+#if 0	/* 本来の動作は CLOSED に遷移する。*/
+	case PPP_FSM_STOPPED:
+		fsm->state = PPP_FSM_CLOSED;
+		break;
+#endif	/* of #if 0 */
+
+	case PPP_FSM_STOPPING:
+		fsm->state = PPP_FSM_CLOSING;
+		break;
+
+	case PPP_FSM_REQSENT:
+	case PPP_FSM_ACKRCVD:
+	case PPP_FSM_ACKSENT:
+	case PPP_FSM_OPENED:
+		if (fsm->state != PPP_FSM_OPENED)
+			untimeout((FP)fsm_timeout, fsm);
+		else if (fsm->callbacks->down != NULL)
+			(*fsm->callbacks->down)(fsm);
+
+		/* タイムアウトを設定し、Terminate-Request を送信する。*/
+		fsm->retrans = MAX_PPP_TERMINATES;
+		fsm_stermreq(fsm, fsm->reqid = ++ fsm->id);
+		fsm->state = PPP_FSM_CLOSING;
+		break;
+		}
+	}
+
+/*
+ *  fsm_input -- 入力、PPP リンク制御 (CP) の制御コードにより適当な関数を呼出す
+ */
+
+void
+fsm_input (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_PPP_CP_HDR	*hdr;
+	T_NET_BUF	*output;
+
+ 	/* PPP リンク制御 (CP) ヘッダより短ければエラー */
+ 	if (input->len < (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR))) {
+ 		syslog(LOG_WARNING, "[PPP/FSM] short hdr: %d.", input->len);
+ 		return;
+ 		}
+
+ 	hdr = GET_PPP_CP_HDR(input);
+
+ 	/* ヘッダの長さと入力データサイズが一致しなければエラー */
+ 	if (hdr->len != input->len - sizeof(T_PPP_HDR)) {
+ 		syslog(LOG_WARNING, "[PPP/FSM] bad len: %d.", hdr->len);
+ 		return;
+ 		}
+ 
+ 	/* 状態が INITIAL か STARTING ならエラー */
+ 	if (fsm->state == PPP_FSM_INITIAL || fsm->state == PPP_FSM_STARTING) {
+ 		syslog(LOG_WARNING, "[PPP/FSM] unexp state: %d in input.", fsm->state);
+ 		return;
+ 		}
+ 
+ 	/*
+ 	 *  制御コードにより適当な関数を呼出す
+ 	 */
+
+	switch (hdr->code) {
+	case PPP_CONFREQ:
+		fsm_rconfreq(fsm, hdr->id, input);
+		break;
+
+	case PPP_CONFACK:
+		fsm_rconfack(fsm, hdr->id, input);
+		break;
+
+	case PPP_CONFNAK:
+	case PPP_CONFREJ:
+		fsm_rconfnakrej(fsm, hdr->code, hdr->id, input);
+		break;
+
+	case PPP_TERMREQ:
+		fsm_rtermreq(fsm, hdr->id, input);
+		break;
+
+	case PPP_TERMACK:
+		fsm_rtermack(fsm, input);
+		break;
+
+	case PPP_CODEREJ:
+		fsm_rcoderej(fsm, input);
+		break;
+
+	default:
+		if (fsm->callbacks->extcode == NULL ||
+		    (*fsm->callbacks->extcode)(fsm, hdr->code, hdr->id, input) != true) {
+			syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
+			memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+			ppp_cp_output(PPP_CODEREJ, ++ fsm->id, output);
+			}
+		break;
+		}
+	}
+
+/*
+ *  fsm_protoreject -- Proto-REJ を受信したときの処理
+ */
+
+void
+fsm_protreject (T_PPP_FSM *fsm)
+{
+	switch (fsm->state) {
+	case PPP_FSM_CLOSING:
+		untimeout((FP)fsm_timeout, fsm);
+
+#if 0	/* 本来の動作は CLOSED に遷移する。*/
+		/* 下に落ちる */
+#else	/* of #if 0 */
+		fsm->state = PPP_FSM_STOPPED;
+		if (fsm->callbacks->finished != NULL)
+			(*fsm->callbacks->finished)(fsm);
+		break;
+#endif	/* of #if 0 */
+
+	case PPP_FSM_CLOSED:
+		fsm->state = PPP_FSM_CLOSED;
+		if (fsm->callbacks->finished != NULL)
+			(*fsm->callbacks->finished)(fsm);
+		break;
+
+	case PPP_FSM_STOPPING:
+	case PPP_FSM_REQSENT:
+	case PPP_FSM_ACKRCVD:
+	case PPP_FSM_ACKSENT:
+		untimeout((FP)fsm_timeout, fsm);
+		/* 下に落ちる */
+
+	case PPP_FSM_STOPPED:
+		fsm->state = PPP_FSM_STOPPED;
+		if (fsm->callbacks->finished != NULL)
+			(*fsm->callbacks->finished)(fsm);
+		break;
+
+	case PPP_FSM_OPENED:
+		if (fsm->callbacks->down != NULL)
+			(*fsm->callbacks->down)(fsm);
+
+		/* タイムアウトを設定し、Terminate-Request を送信する。*/
+		fsm->retrans = MAX_PPP_TERMINATES;
+		fsm_stermreq(fsm, fsm->reqid = ++ fsm->id);
+		fsm->state = PPP_FSM_STOPPING;
+		break;
+
+		}
+	}
+
+#endif	/* fo #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_fsm.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_fsm.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_fsm.h	(revision 398)
@@ -0,0 +1,183 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * fsm.h - {Link, IP} Control Protocol Finite State Machine 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD: src/usr.sbin/pppd/fsm.h,v 1.6.2.1 1999/08/29 15:47:00 peter Exp $
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/fsm.h,v 1.23 1999/12/27 11:54:53 brian Exp $
+ *
+ *	TODO:
+ */
+
+#ifndef _PPP_FSM_H_
+#define _PPP_FSM_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  状態管理構造体
+ */
+
+struct t_ppp_fsm_callbacks;
+
+typedef struct t_fsm {
+	struct t_ppp_fsm_callbacks	*callbacks;	/* コールバック関数*/
+	uint16_t	proto;		/* プロトコル				*/
+	uint8_t		state;		/* FSM の状態				*/
+	uint8_t		id;		/* 現在の ID				*/
+	uint8_t		reqid;		/* 要求 ID				*/
+	uint8_t		seen_ack;	/* 要求に対し正常な ACK/NAK/REJ を受信	*/
+	int8_t		failures;	/* 黙認した NAK 数			*/
+	int8_t		retrans;	/* Configure-Request または、		*/
+					/* Terminate-Request の再送回数		*/
+	} T_PPP_FSM;
+
+#define T_PPP_FSM_DEFINED
+
+/*
+ *  コールバック関数構造体
+ */
+
+typedef struct t_ppp_fsm_callbacks {
+	void (*resetci)	(T_PPP_FSM *);	/* 自構成情報をリセットする。	*/
+	int_t  (*cilen)	(T_PPP_FSM *);	/* 構成情報の長さを返す。		*/
+	void (*addci)	(T_PPP_FSM *, T_NET_BUF *);
+					/* 自構成情報を追加する。		*/
+	bool_t (*ackci)	(T_PPP_FSM *, T_NET_BUF *);
+					/* ACK を受信したときの処理	*/
+	int_t  (*nakci)	(T_PPP_FSM *, T_NET_BUF *);
+					/* NAK を受信したときの処理	*/
+	int_t  (*rejci)	(T_PPP_FSM *, T_NET_BUF *);
+					/* REJ を受信したときの処理	*/
+	int_t  (*reqci)	(T_PPP_FSM *, T_NET_BUF *, T_NET_BUF *);
+					/* 相手の構成情報を確認する。	*/
+	void (*up)	(T_PPP_FSM *);	/* リンクの接続を確立する。	*/
+	void (*down)	(T_PPP_FSM *);	/* リンクの接続を解放する。	*/
+	void (*starting)(T_PPP_FSM *);	/* 下位層を開始する。		*/
+	void (*finished)(T_PPP_FSM *);	/* 下位層を終了する。		*/
+	void (*retrans)	(T_PPP_FSM *);	/* 再送する。			*/
+					/* 不明な CP を受信したときの処理	*/
+	bool_t  (*extcode)(T_PPP_FSM *, uint8_t, uint8_t, T_NET_BUF *);
+	} T_PPP_FSM_CALLBACKS;
+
+/*
+ *  FSM の状態
+ */
+
+#define PPP_FSM_INITIAL		0	/* 未接続、未オープン	*/
+#define PPP_FSM_STARTING	1	/* 未接続、オープン	*/
+#define PPP_FSM_CLOSED		2	/* 接続、  未オープン	*/
+#define PPP_FSM_STOPPED		3	/* オープン、切断待ち	*/
+#define PPP_FSM_CLOSING		4	/* 切断中、未オープン	*/
+#define PPP_FSM_STOPPING	5	/* 切断中、オープン	*/
+#define PPP_FSM_REQSENT		6	/* Config REQ 送信済み	*/
+#define PPP_FSM_ACKRCVD		7	/* Config ACK 受信済み	*/
+#define PPP_FSM_ACKSENT		8	/* Config ACK 送信済み	*/
+#define PPP_FSM_OPENED		9	/* 接続、通信可能	*/
+
+/*
+ *  オープン時の動作モード
+ */
+
+#define PPP_OPEN_PASSIVE	false	/* 受動オープン		*/
+#define PPP_OPEN_ACTIVE		true	/* 能動オープン		*/
+
+/*
+ *  再送、タイムアウトの既定値
+ */
+
+#define DEF_PPP_TIMEOUT		(3*NET_TIMER_HZ)
+					/* RFC1661 では  3 秒			*/
+#define MAX_PPP_TERMINATES	2	/* Terminate-Requests の最大再送回数	*/
+					/* RFC1661 では  2 回			*/
+#define MAX_PPP_CONFIGURES	10	/* Configure-Requests の最大再送回数	*/
+					/* RFC1661 では 10 回			*/
+#define MAX_PPP_FAILURES	5	/* Configure-NAK の最大黙認回数		*/
+					/* RFC1661 では  5 回			*/
+
+/*
+ *  関数
+ */
+
+extern void fsm_init    (T_PPP_FSM *fsm);
+extern void fsm_lowerup (T_PPP_FSM *fsm);
+extern void fsm_lowerdown(T_PPP_FSM *fsm);
+extern void fsm_open    (T_PPP_FSM *fsm);
+extern void fsm_close	(T_PPP_FSM *fsm);
+extern void fsm_input	(T_PPP_FSM *fsm, T_NET_BUF *data);
+extern void fsm_protreject(T_PPP_FSM *fsm);
+
+/*
+ *  変数
+ */
+
+extern uint8_t ppp_open_mode;
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _PPP_FSM_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_hdlc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_hdlc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_hdlc.c	(revision 398)
@@ -0,0 +1,534 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	     PPP High Level Link Control (HDLC) Module
+ *
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan, Inc.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/hdlc.c,v 1.46 1999/12/20 20:29:42 brian Exp $
+ *
+ *	TODO:
+ */
+
+#include <s_services.h>
+#include <t_services.h>
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_hdlc.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_lcp.h>
+#include <net/ppp_modem.h>
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  RFC1171 (PPP) の HDLC 部の定義
+ */
+
+/*
+ *  変数
+ */
+
+uint32_t remote_ACCM	= DEF_REMOTE_ACCM;
+
+/*
+ *  関数
+ */
+
+static ER HDLC_putoctet (uint8_t octet);
+static ER HDLC_getoctet (uint8_t *octet);
+
+/*
+ *  genfcstab.c により作成した FCS のルックアップ表
+ *  RFC1171 参照
+ */
+
+static uint16_t fcstab[256] = {
+	UINT_C(0x0000), UINT_C(0x1189), UINT_C(0x2312), UINT_C(0x329b),
+	UINT_C(0x4624), UINT_C(0x57ad), UINT_C(0x6536), UINT_C(0x74bf),
+	UINT_C(0x8c48), UINT_C(0x9dc1), UINT_C(0xaf5a), UINT_C(0xbed3),
+	UINT_C(0xca6c), UINT_C(0xdbe5), UINT_C(0xe97e), UINT_C(0xf8f7),
+	UINT_C(0x1081), UINT_C(0x0108), UINT_C(0x3393), UINT_C(0x221a),
+	UINT_C(0x56a5), UINT_C(0x472c), UINT_C(0x75b7), UINT_C(0x643e),
+	UINT_C(0x9cc9), UINT_C(0x8d40), UINT_C(0xbfdb), UINT_C(0xae52),
+	UINT_C(0xdaed), UINT_C(0xcb64), UINT_C(0xf9ff), UINT_C(0xe876),
+	UINT_C(0x2102), UINT_C(0x308b), UINT_C(0x0210), UINT_C(0x1399),
+	UINT_C(0x6726), UINT_C(0x76af), UINT_C(0x4434), UINT_C(0x55bd),
+	UINT_C(0xad4a), UINT_C(0xbcc3), UINT_C(0x8e58), UINT_C(0x9fd1),
+	UINT_C(0xeb6e), UINT_C(0xfae7), UINT_C(0xc87c), UINT_C(0xd9f5),
+	UINT_C(0x3183), UINT_C(0x200a), UINT_C(0x1291), UINT_C(0x0318),
+	UINT_C(0x77a7), UINT_C(0x662e), UINT_C(0x54b5), UINT_C(0x453c),
+	UINT_C(0xbdcb), UINT_C(0xac42), UINT_C(0x9ed9), UINT_C(0x8f50),
+	UINT_C(0xfbef), UINT_C(0xea66), UINT_C(0xd8fd), UINT_C(0xc974),
+	UINT_C(0x4204), UINT_C(0x538d), UINT_C(0x6116), UINT_C(0x709f),
+	UINT_C(0x0420), UINT_C(0x15a9), UINT_C(0x2732), UINT_C(0x36bb),
+	UINT_C(0xce4c), UINT_C(0xdfc5), UINT_C(0xed5e), UINT_C(0xfcd7),
+	UINT_C(0x8868), UINT_C(0x99e1), UINT_C(0xab7a), UINT_C(0xbaf3),
+	UINT_C(0x5285), UINT_C(0x430c), UINT_C(0x7197), UINT_C(0x601e),
+	UINT_C(0x14a1), UINT_C(0x0528), UINT_C(0x37b3), UINT_C(0x263a),
+	UINT_C(0xdecd), UINT_C(0xcf44), UINT_C(0xfddf), UINT_C(0xec56),
+	UINT_C(0x98e9), UINT_C(0x8960), UINT_C(0xbbfb), UINT_C(0xaa72),
+	UINT_C(0x6306), UINT_C(0x728f), UINT_C(0x4014), UINT_C(0x519d),
+	UINT_C(0x2522), UINT_C(0x34ab), UINT_C(0x0630), UINT_C(0x17b9),
+	UINT_C(0xef4e), UINT_C(0xfec7), UINT_C(0xcc5c), UINT_C(0xddd5),
+	UINT_C(0xa96a), UINT_C(0xb8e3), UINT_C(0x8a78), UINT_C(0x9bf1),
+	UINT_C(0x7387), UINT_C(0x620e), UINT_C(0x5095), UINT_C(0x411c),
+	UINT_C(0x35a3), UINT_C(0x242a), UINT_C(0x16b1), UINT_C(0x0738),
+	UINT_C(0xffcf), UINT_C(0xee46), UINT_C(0xdcdd), UINT_C(0xcd54),
+	UINT_C(0xb9eb), UINT_C(0xa862), UINT_C(0x9af9), UINT_C(0x8b70),
+	UINT_C(0x8408), UINT_C(0x9581), UINT_C(0xa71a), UINT_C(0xb693),
+	UINT_C(0xc22c), UINT_C(0xd3a5), UINT_C(0xe13e), UINT_C(0xf0b7),
+	UINT_C(0x0840), UINT_C(0x19c9), UINT_C(0x2b52), UINT_C(0x3adb),
+	UINT_C(0x4e64), UINT_C(0x5fed), UINT_C(0x6d76), UINT_C(0x7cff),
+	UINT_C(0x9489), UINT_C(0x8500), UINT_C(0xb79b), UINT_C(0xa612),
+	UINT_C(0xd2ad), UINT_C(0xc324), UINT_C(0xf1bf), UINT_C(0xe036),
+	UINT_C(0x18c1), UINT_C(0x0948), UINT_C(0x3bd3), UINT_C(0x2a5a),
+	UINT_C(0x5ee5), UINT_C(0x4f6c), UINT_C(0x7df7), UINT_C(0x6c7e),
+	UINT_C(0xa50a), UINT_C(0xb483), UINT_C(0x8618), UINT_C(0x9791),
+	UINT_C(0xe32e), UINT_C(0xf2a7), UINT_C(0xc03c), UINT_C(0xd1b5),
+	UINT_C(0x2942), UINT_C(0x38cb), UINT_C(0x0a50), UINT_C(0x1bd9),
+	UINT_C(0x6f66), UINT_C(0x7eef), UINT_C(0x4c74), UINT_C(0x5dfd),
+	UINT_C(0xb58b), UINT_C(0xa402), UINT_C(0x9699), UINT_C(0x8710),
+	UINT_C(0xf3af), UINT_C(0xe226), UINT_C(0xd0bd), UINT_C(0xc134),
+	UINT_C(0x39c3), UINT_C(0x284a), UINT_C(0x1ad1), UINT_C(0x0b58),
+	UINT_C(0x7fe7), UINT_C(0x6e6e), UINT_C(0x5cf5), UINT_C(0x4d7c),
+	UINT_C(0xc60c), UINT_C(0xd785), UINT_C(0xe51e), UINT_C(0xf497),
+	UINT_C(0x8028), UINT_C(0x91a1), UINT_C(0xa33a), UINT_C(0xb2b3),
+	UINT_C(0x4a44), UINT_C(0x5bcd), UINT_C(0x6956), UINT_C(0x78df),
+	UINT_C(0x0c60), UINT_C(0x1de9), UINT_C(0x2f72), UINT_C(0x3efb),
+	UINT_C(0xd68d), UINT_C(0xc704), UINT_C(0xf59f), UINT_C(0xe416),
+	UINT_C(0x90a9), UINT_C(0x8120), UINT_C(0xb3bb), UINT_C(0xa232),
+	UINT_C(0x5ac5), UINT_C(0x4b4c), UINT_C(0x79d7), UINT_C(0x685e),
+	UINT_C(0x1ce1), UINT_C(0x0d68), UINT_C(0x3ff3), UINT_C(0x2e7a),
+	UINT_C(0xe70e), UINT_C(0xf687), UINT_C(0xc41c), UINT_C(0xd595),
+	UINT_C(0xa12a), UINT_C(0xb0a3), UINT_C(0x8238), UINT_C(0x93b1),
+	UINT_C(0x6b46), UINT_C(0x7acf), UINT_C(0x4854), UINT_C(0x59dd),
+	UINT_C(0x2d62), UINT_C(0x3ceb), UINT_C(0x0e70), UINT_C(0x1ff9),
+	UINT_C(0xf78f), UINT_C(0xe606), UINT_C(0xd49d), UINT_C(0xc514),
+	UINT_C(0xb1ab), UINT_C(0xa022), UINT_C(0x92b9), UINT_C(0x8330),
+	UINT_C(0x7bc7), UINT_C(0x6a4e), UINT_C(0x58d5), UINT_C(0x495c),
+	UINT_C(0x3de3), UINT_C(0x2c6a), UINT_C(0x1ef1), UINT_C(0x0f78),
+	};
+
+/*
+ *  インライン関数
+ */
+
+Inline uint16_t Next_FCS (uint16_t FCS, uint8_t Octet) {
+	return (FCS >> 8) ^ fcstab[(FCS ^ Octet) & 0xff];
+	};
+
+/*
+ *  HDLC_putoctet -- HDLC オクテット出力
+ */
+
+static
+ER HDLC_putoctet (uint8_t octet)
+{
+	static uint8_t escape[2] = { HDLC_CNTL_ESC };
+
+	ER error;
+
+	NET_COUNT_PPP_HDLC(net_count_hdlc.out_octets, 1);
+
+	if ((octet < 0x20 && ((1 << octet) & lcp_remote_ack_cfg.ACCM)) ||
+	    octet == HDLC_CNTL_ESC || octet == HDLC_FLAG_SEQ) {
+		escape[1] = octet ^ HDLC_ESC_MASK;
+		error = serial_wri_dat(HDLC_PORTID, escape, sizeof(escape));
+		}
+	else
+		error = serial_wri_dat(HDLC_PORTID, &octet, sizeof(octet));
+
+	return error > 0 ? E_OK : error;
+	}
+
+/*
+ *  HDLC_wirte -- HDLC 出力
+ */
+
+ER HDLC_write (T_NET_BUF *nbuf)
+{
+	static char flag_seq_ac[4] = {
+		HDLC_FLAG_SEQ,
+		HDLC_ADDR_ALL,
+		HDLC_CNTL_ESC,
+		HDLC_CNTL_UI ^ HDLC_ESC_MASK,
+		};
+
+#ifdef LCP_CFG_ACCOMP
+
+	static char flag_seq = HDLC_FLAG_SEQ;
+
+#endif	/* of #ifdef LCP_CFG_ACCOMP */
+
+	ER		error;
+	uint32_t	fcs;
+	uint16_t	len;
+	uint8_t 	*buf;
+
+	NET_COUNT_PPP_HDLC(net_count_hdlc.out_packets, 1);
+
+#ifdef LCP_CFG_ACCOMP
+
+	if (lcp_local_ack_cfg.options & LCP_CFG_ACCOMP) {
+		NET_COUNT_PPP_HDLC(net_count_hdlc.out_octets, sizeof(flag_seq));
+		/* フレーム開始フラグシーケンス を送信する    */
+		if ((error = serial_wri_dat(HDLC_PORTID, &flag_seq, sizeof(flag_seq))) < 0) {
+			goto err_ret;
+			}
+		fcs = HDLC_INIT_FCS;
+		}
+	else {
+
+		NET_COUNT_PPP_HDLC(net_count_hdlc.out_octets, sizeof(flag_seq_ac));
+		/* フレーム開始フラグシーケンス、Address と Control を送信する    */
+		if ((error = serial_wri_dat(HDLC_PORTID, flag_seq_ac, sizeof(flag_seq_ac))) < 0) {
+			goto err_ret;
+			}
+		/* Address と Control の FCS の計算は HDLC_INIT_FCS_AC に含めている */
+		fcs = HDLC_INIT_FCS_AC;
+		}
+
+#else	/* of #ifdef LCP_CFG_ACCOMP */
+
+	NET_COUNT_PPP_HDLC(net_count_hdlc.out_octets, sizeof(flag_seq_ac));
+	/* フレーム開始フラグシーケンス、Address と Control を送信する    */
+	if ((error = serial_wri_dat(HDLC_PORTID, flag_seq_ac, sizeof(flag_seq_ac))) < 0) {
+		goto err_ret;
+		}
+	/* Address と Control の FCS の計算は HDLC_INIT_FCS_AC に含めている */
+	fcs = HDLC_INIT_FCS_AC;
+
+#endif	/* of #ifdef LCP_CFG_ACCOMP */
+
+	buf = nbuf->buf;
+	len = nbuf->len;
+
+#ifdef LCP_CFG_PCOMP
+
+	if ((lcp_local_ack_cfg.options & LCP_CFG_ACCOMP) && *buf == 0 && *(buf + 1) < 0xff) {
+		buf ++;
+		len --;
+		}
+
+#endif	/* of #ifdef LCP_CFG_PCOMP */
+
+	/* データを送信する */
+	while (len -- > 0) {
+
+		if ((error = HDLC_putoctet(*buf)) != E_OK)
+			goto err_ret;
+		fcs = Next_FCS(fcs, *buf);
+		buf ++;
+		}
+
+	/* FCS を送信する */
+	fcs = ~fcs;
+	if ((error = HDLC_putoctet(fcs & 0xff)) != E_OK)
+		goto err_ret;
+	if ((error = HDLC_putoctet(fcs >> 8)) != E_OK)
+		goto err_ret;
+
+	/* フレーム終了フラグシーケンスを送信する */
+	if ((error = serial_wri_dat(HDLC_PORTID, &flag_seq_ac[0], sizeof(char))) < 0)
+		goto err_ret;
+
+	return E_OK;
+
+err_ret:
+	NET_COUNT_PPP_HDLC(net_count_hdlc.out_err_packets, 1);
+	return error;
+	}
+
+/*
+ *  HDLC_getoctet -- HDLC オクテット入力
+ *
+ *	戻り値が true ならフラグシーケンス
+ */
+
+static
+ER_BOOL HDLC_getoctet (uint8_t *octet)
+{
+	ER error;
+
+	/* 1オクテット入力する */
+	if ((error = serial_rea_dat(HDLC_PORTID, octet, sizeof(uint8_t))) <= 0) {
+		return error;
+		}
+
+	/* 入力したオクテットがフラグシーケンスなら true を返す */
+	if (*octet == HDLC_FLAG_SEQ)
+		return true;
+
+	/* 入力したオクテットがエスケープなら、もう１オクテット入力しマスクを解除する */
+	if (*octet == HDLC_CNTL_ESC) {
+		if ((error = serial_rea_dat(HDLC_PORTID, octet, sizeof(uint8_t))) <= 0)
+			return error;
+		*octet ^= HDLC_ESC_MASK;
+		}
+
+	NET_COUNT_PPP_HDLC(net_count_hdlc.in_octets, 1);
+	return E_OK;
+	}
+
+/*
+ *  HDLC_read -- HDLC 入力
+ *
+ *	HDLC フレームを入力する。
+ */
+
+ER HDLC_read (T_NET_BUF *nbuf, uint16_t size)
+{
+	ER		error;
+	uint32_t	fcs = 0;
+	uint16_t	olen = 0;
+	uint8_t		*buf, octet;
+
+	buf = nbuf->buf;
+
+	/* フレーム開始フラグシーケンスまで入力を読み飛ばす */
+	while ((error = HDLC_getoctet(&octet)) != true) {
+
+		if (error != E_OK)
+			goto err_ret;
+
+#ifdef PPP_CFG_MODEM
+
+		else if (octet == '\n') {
+			/* モデム制御を呼び出す。*/
+			modem_cntl(modem_getline(nbuf, size));
+			/* 一度、この関数を終了する。*/
+			nbuf->len = 0;
+			return E_OK;
+			}
+
+#endif/* of #ifdef PPP_CFG_MODEM */
+
+		}
+
+	/* フレーム開始フラグシーケンスの間は入力を読み飛ばす */
+	while (1) {
+		if ((error = HDLC_getoctet(&octet)) == E_OK)
+			break;
+		else if (error != true)
+			goto err_ret;
+		}
+
+	NET_COUNT_PPP_HDLC(net_count_hdlc.in_packets, 1);
+
+	/* 入力したオクテットは Address: All-Stations か */
+	if (octet == HDLC_ADDR_ALL) {
+
+		/* 次は Control: UI */
+		if ((error = HDLC_getoctet(&octet)) != E_OK || octet != HDLC_CNTL_UI) {
+			error = E_SYS;
+			goto err_ret;
+			}
+		if ((error = HDLC_getoctet(&octet)) != E_OK)
+			goto err_ret;
+		/* Address と Control の FCS の計算は HDLC_INIT_FCS_AC に含めている */
+		fcs = HDLC_INIT_FCS_AC;
+		}
+
+#ifdef LCP_CFG_ACCOMP
+
+	else if (lcp_remote_ack_cfg.options & LCP_CFG_ACCOMP) {
+		fcs = HDLC_INIT_FCS;
+		}
+
+#endif/* of #ifdef LCP_CFG_ACCOMP */
+
+	else {
+		error = E_SYS;
+		goto err_ret;
+		}
+
+	nbuf->len = 0;
+
+#ifdef LCP_CFG_PCOMP
+
+	if ((lcp_remote_ack_cfg.options & LCP_CFG_PCOMP) && (octet & 0x01) != 0) {
+		*buf ++ = 0x00;
+		size  --;
+		nbuf->len ++;
+		}
+
+#endif	/* of #ifdef LCP_CFG_PCOMP */
+
+	fcs = Next_FCS(fcs, octet);
+	*buf ++ = octet;
+	size  --;
+	nbuf->len ++;
+
+	/* SUD + FCS を入力する */
+	while ((error = HDLC_getoctet(&octet)) == E_OK) {
+		fcs = Next_FCS(fcs, octet);
+		if (size > 0) {
+			*buf ++ = octet;
+			size  --;
+			}
+		else
+			olen ++;
+		nbuf->len ++;
+		}
+
+	if (error == true) {
+		if (size > 0)
+			nbuf->len -= 2;
+		else if (olen <= 2)
+			nbuf->len -= olen;
+		else {
+			error = E_BOVR;
+			goto err_ret;
+			}
+		}
+	else
+		goto err_ret;
+
+	/* FCS をチェックする */
+	if (fcs != HDLC_GOOD_FCS) {
+		error = E_SYS;
+		goto err_ret;
+		}
+
+	return E_OK;
+
+err_ret:
+	NET_COUNT_PPP_HDLC(net_count_hdlc.in_err_packets, 1);
+	return error;
+	}
+
+/*
+ *  HDLC_dummy_read -- HDLC 入力 (空読み)
+ *
+ *	HDLC フレームを空読みする。
+ */
+
+void
+HDLC_dummy_read (void)
+{
+	uint8_t	octet;
+	ER	error;
+
+	/* フレーム開始フラグシーケンスまで入力を読み飛ばす */
+	while ((error = HDLC_getoctet(&octet)) != true) {
+		if (error != E_OK)
+			return;
+		}
+
+	/* フレーム開始フラグシーケンスの間は入力を読み飛ばす */
+	while (octet == HDLC_FLAG_SEQ)
+		if (HDLC_getoctet(&octet) != E_OK)
+			return;
+
+	/* 入力したオクテットは Address: All-Stations か */
+	if (octet == HDLC_ADDR_ALL) {
+
+		/* 次は Control: UI */
+		if (HDLC_getoctet(&octet) != E_OK || octet != HDLC_CNTL_UI)
+			return;
+		if (HDLC_getoctet(&octet) != E_OK)
+			return;
+		}
+
+#ifdef LCP_CFG_ACCOMP
+
+	else if (lcp_remote_ack_cfg.options & LCP_CFG_ACCOMP)
+		;
+
+#endif/* of #ifdef LCP_CFG_ACCOMP */
+
+	else
+		return;
+
+	while (HDLC_getoctet(&octet) == E_OK)
+		;
+	}
+
+#ifdef PPP_CFG_MODEM
+
+/*
+ *  HDLC_raw_getoctet -- HDLC オクテット (Raw) 入力
+ */
+
+int HDLC_raw_getoctet (void)
+{
+	uint8_t ch;
+
+	/* 1オクテット入力する */
+	if (serial_rea_dat(HDLC_PORTID, &ch, sizeof(ch)) <= 0)
+		return '\0';
+
+	NET_COUNT_PPP_HDLC(net_count_hdlc.in_octets, 1);
+	return ch;
+	}
+
+/*
+ *  HDLC_raw_putoctet -- HDLC オクテット (Raw) 出力
+ */
+
+void HDLC_raw_putoctet (uint8_t ch)
+{
+	NET_COUNT_PPP_HDLC(net_count_hdlc.out_octets, 1);
+	/* 1オクテット出力する */
+	serial_wri_dat(HDLC_PORTID, &ch, sizeof(ch));
+	}
+
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+#endif	/* fo #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_hdlc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_hdlc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_hdlc.h	(revision 398)
@@ -0,0 +1,96 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/hdlc.h,v 1.21 1999/12/30 13:27:15 brian Exp $
+ *
+ *	TODO:
+ */
+
+#ifndef _PPP__HDLC_H_
+#define _PPP__HDLC_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  RFC1171 (PPP) の HDLC 部の定義
+ */
+
+/*
+ *  既定値
+ */
+
+#define HDLC_FLAG_SEQ		UINT_C(0x7e)		/* Flag Sequence			*/
+#define HDLC_CNTL_ESC		UINT_C(0x7d)		/* Control Escape octet			*/
+#define HDLC_ADDR_ALL		UINT_C(0xff)		/* Address: All-Stations		*/
+#define HDLC_CNTL_UI		UINT_C(0x03)		/* Control: UI				*/
+#define HDLC_ESC_MASK		UINT_C(0x20)		/* Escape Mask				*/
+#define HDLC_INIT_FCS		UINT_C(0xffff)		/* Initial FCS value			*/
+#define HDLC_INIT_FCS_AC	UINT_C(0x3de3)		/* Initial FCS value with		*/
+							/* Address and Control: UI		*/
+#define HDLC_GOOD_FCS		UINT_C(0xf0b8)		/* Good final FCS value			*/
+
+/*
+ *  関数
+ */
+
+extern ER HDLC_write (T_NET_BUF *data);
+extern ER HDLC_read (T_NET_BUF *data, uint16_t size);
+extern void HDLC_dummy_read (void);
+
+#ifdef PPP_CFG_MODEM
+
+extern int_t HDLC_raw_getoctet (void);
+extern void HDLC_raw_putoctet (uint8_t ch);
+
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _PPP__HDLC_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipcp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipcp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipcp.c	(revision 398)
@@ -0,0 +1,675 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * ipcp.c - PPP IP Control Protocol.
+ *
+ * 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *	PPP IP Control Protocol (IPCP) Module
+ *
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan, Inc.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/ipcp.c,v 1.90.2.4 2000/08/19 09:30:03 brian Exp $
+ *
+ *	TODO:
+ *		o Support IPADDRS properly
+ *		o Validate the length in IpcpDecodeConfig
+ */
+
+#include <string.h>
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_lcp.h>
+#include <net/ppp_ipcp.h>
+#include <net/ppp_modem.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/udp_var.h>
+
+#include <net/if_var.h>
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  関数
+ */
+
+static void ipcp_init (void);
+static void ipcp_input (T_NET_BUF *input);
+static void ipcp_protrej (void);
+static void ipcp_lowerup (void);
+static void ipcp_lowerdown (void);
+static void ipcp_open (void);
+static void ipcp_close (void);
+
+/*
+ * FSM から呼出されるコールバック関
+ */
+
+static void  ipcp_resetci(T_PPP_FSM *fsm);	/* 自構成情報をリセットする。	*/
+static int_t ipcp_cilen	(T_PPP_FSM *fsm);	/* 構成情報の長さを返す。		*/
+static void  ipcp_addci	(T_PPP_FSM *fsm, T_NET_BUF *output);
+						/* 自構成情報を追加する。		*/
+static bool_t  ipcp_ackci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* ACK を受信したときの処理	*/
+static bool_t  ipcp_nakci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* NAK を受信したときの処理	*/
+static bool_t  ipcp_rejci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* REJ を受信したときの処理	*/
+static int_t ipcp_reqci	(T_PPP_FSM *fsm, T_NET_BUF *input, T_NET_BUF *output);
+						/* 相手の構成情報を確認する。	*/
+static void ipcp_up	(T_PPP_FSM *fsm);	/* リンク接続を確立する。		*/
+static void ipcp_down	(T_PPP_FSM *fsm);	/* リンク接続を解放する。		*/
+static void ipcp_finished(T_PPP_FSM *fsm);	/* 下位層を終了する。		*/
+
+/*
+ *  変数
+ */
+
+static T_IFNET ipcp_local_def_cfg = {		/* 自構成情報の規定値		*/
+	NULL,
+	{
+		IPV4_ADDR_LOCAL,		/* IPv4 アドレス			*/
+		UINT_C(0),			/* サブネットマスク		*/
+		},
+	};
+
+static T_IFNET ipcp_remote_def_cfg = {		/* 相手の構成情報の規定値	*/
+	NULL,
+	{
+		IPV4_ADDR_REMOTE,		/* IPv4 アドレス			*/
+		UINT_C(0),			/* サブネットマスク		*/
+		}
+	};
+
+static T_IFNET ipcp_local_neg_cfg;		/* ネゴ中の自構成情報		*/
+
+static T_IFNET ipcp_remote_neg_cfg;		/* ネゴ中の相手の構成情報		*/
+
+/*
+ *  全域変数
+ */
+
+T_PPP_FSM_CALLBACKS ipcp_callbacks = {
+	ipcp_resetci,			/* 自構成情報をリセットする。	*/
+	ipcp_cilen,			/* 構成情報の長さを返す。		*/
+	ipcp_addci,			/* 自構成情報を追加する。		*/
+	ipcp_ackci,			/* ACK を受信したときの処理	*/
+	ipcp_nakci,			/* NAK を受信したときの処理	*/
+	ipcp_rejci,			/* REJ を受信したときの処理	*/
+	ipcp_reqci,			/* 相手の構成情報を確認する。	*/
+	ipcp_up,			/* リンク接続を確立する。		*/
+	ipcp_down,			/* リンク接続を解放する。		*/
+	NULL,				/* 下位層を開始する。		*/
+	ipcp_finished,			/* 下位層を終了する。		*/
+	NULL,				/* 再送する。			*/
+	NULL,				/* 不明な CP を受信したときの処理	*/
+	};
+
+T_PPP_FSM ipcp_fsm = {
+	&ipcp_callbacks,		/* コールバック関数		*/
+	PPP_IPCP,			/* プロトコル			*/
+	};
+
+T_PPP_PROTENT ipcp_protent = {
+	PPP_IPCP,
+	ipcp_init,			/* 初期化			*/
+	ipcp_input,			/* 入力				*/
+	ipcp_protrej,			/* Proto-REJ 受信処理		*/
+	ipcp_lowerup,			/* 下位層を起動する		*/
+	ipcp_lowerdown,			/* 下位層を停止する		*/
+	ipcp_open,			/* オープンする			*/
+	ipcp_close,			/* クローズする			*/
+	ip_input,			/* データ入力、IPv4 入力	*/
+	};
+
+T_IFNET ipcp_local_ack_cfg;		/* 相手に許可されたの自構成情報	*/
+T_IFNET ipcp_remote_ack_cfg;		/* 相手に許可した構成情報	*/
+
+/*
+ *  ppp_get_ifnet -- ネットワークインタフェース構造体を返す。
+ */
+
+T_IFNET *
+ppp_get_ifnet (void)
+{
+	return &ipcp_local_ack_cfg;
+	}
+
+/*
+ *  wait_ipcp -- IP 接続完了まで待つ。
+ *
+ *	戻り値: 接続に失敗したら E_OBJ を返す。
+ */
+
+ER
+wait_ipcp (void)
+{
+#ifdef PPP_CFG_MODEM
+	ER error;
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+	if (ipcp_fsm.state <= PPP_FSM_STOPPED) {
+
+#ifdef PPP_CFG_MODEM
+
+		/* モデムの接続完了まで待つ。*/
+		if ((error = wait_modem()) != E_OK)
+			return error;
+
+#else	/* of #ifdef PPP_CFG_MODEM */
+
+		/*
+		 * 受動オープンし、相手からの接続待ちなら LCP を一度クローズし、
+		 * 能動オープン状態で、再オープンする。
+		 */
+		lcp_close();
+		lcp_open(PPP_OPEN_ACTIVE);
+
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+		}
+
+	if (ipcp_fsm.state != PPP_FSM_OPENED) {
+		/* IP 接続完了まで待つ。*/
+		wai_sem(SEM_IPCP_READY);
+		if (ipcp_fsm.state != PPP_FSM_OPENED)
+			return E_OBJ;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  ipcp_init -- IPCP モジュールの初期化
+ */
+
+static void
+ipcp_init (void)
+{
+	fsm_init(&ipcp_fsm);
+	}
+
+/*
+ *  ipcp_input -- IPCP 入力
+ */
+
+static void
+ipcp_input (T_NET_BUF *input)
+{
+	NET_COUNT_PPP_IPCP(net_count_ppp_ipcp_in_octets,  input->len);
+	NET_COUNT_PPP_IPCP(net_count_ppp_ipcp_in_packets, 1);
+	fsm_input(&ipcp_fsm, input);
+	}
+
+/*
+ *  ipcp_resetci -- IPCPの構成情報をリセットする。
+ */
+
+static void
+ipcp_resetci (T_PPP_FSM *fsm)
+{
+	/* 自構成情報の初期設定 */
+	ipcp_local_neg_cfg = ipcp_local_def_cfg;
+	memset((void*)&ipcp_local_ack_cfg, 0, sizeof(T_IFNET));
+
+	/* 相手の構成情報の初期設定 */
+	ipcp_remote_neg_cfg = ipcp_remote_def_cfg;
+	memset((void*)&ipcp_remote_ack_cfg, 0, sizeof(T_IFNET));
+	}
+
+/*
+ *  ipcp_cilen -- 構成情報の長さを返す。
+ */
+
+static int_t
+ipcp_cilen (T_PPP_FSM *fsm)
+{
+	int_t cilen = 0;
+
+	cilen += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);	/* IPv4 アドレス */
+
+	return cilen;
+	}
+
+/*
+ *  ipcp_addci -- IPCPの構成情報を追加する。
+ */
+
+static void
+ipcp_addci (T_PPP_FSM *fsm, T_NET_BUF *output)
+{
+	uint8_t *buf;
+
+	buf = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+
+	/* IPv4 アドレスオプションを追加する。 */
+	*buf ++ = IPCP_CIT_ADDR;
+	*buf ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+	ahtonl(buf, ipcp_local_neg_cfg.in4_ifaddr.addr);
+	buf += sizeof(uint32_t);
+	}
+
+/*
+ *  ipcp_ackci -- ACK を受信したときの処理
+ *
+ *	戻り値:	true  ACK は正常
+ *		false ACK は異常
+ */
+
+static bool_t
+ipcp_ackci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	uint8_t		*buf;
+	uint16_t	len;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	/*
+	 *  構成情報は送信した順に完全に一致しなければならない。
+	 *  従って、ipcp_addci で作成した順に解析する。
+	 */
+
+	/* ADDR オプションを解析する。 */
+	if (len < sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)	||
+	    *buf ++ != IPCP_CIT_ADDR			||
+	    *buf ++ != sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)||
+	    nahcmpl(buf, ipcp_local_neg_cfg.in4_ifaddr.addr))
+		return false;
+	buf += sizeof(uint32_t);
+	len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+
+	return true;
+	}
+
+/*
+ *  ipcp_nakci -- NAK を受信したときの処理
+ *
+ *	戻り値:	1  NAK は正常
+ *		0  NAK は異常
+ */
+
+static int_t
+ipcp_nakci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_IFNET		new_cfg;
+	uint32_t	cilong;
+	uint16_t	len;
+	uint8_t		*buf, cilen;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	new_cfg = ipcp_local_neg_cfg;
+
+	/* ADDR オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)		&&
+	    * buf      == IPCP_CIT_ADDR				&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)) {
+	    	ntoahl(cilong, buf + 2);
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		new_cfg.in4_ifaddr.addr = cilong;
+		}
+
+	/* 後は無視する。*/
+	while (len > sizeof(T_PPP_CI_HDR)) {
+		cilen = *(buf + 1);
+		if (len < cilen)
+			return 0;
+		buf += cilen;
+		len -= cilen;
+		}
+
+	/* 長さが 0 でなければエラー */
+	if (len != 0)
+		return 0;
+
+	/* 新しいオプションを設定する。*/
+	if (fsm->state != PPP_FSM_OPENED)
+		ipcp_local_neg_cfg = new_cfg;
+               		
+	return 1;
+	}
+
+/*
+ *  ipcp_rejci -- REJ を受信したときの処理
+ *
+ *	戻り値:	1  REJ は正常
+ *		0  REJ は異常
+ */
+
+static int_t
+ipcp_rejci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_IFNET		new_cfg;
+	uint8_t		*buf;
+	uint16_t	len;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	new_cfg = ipcp_local_neg_cfg;
+
+	/* ADDR オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)		&&
+	    * buf      == IPCP_CIT_ADDR				&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)) {
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		new_cfg.in4_ifaddr.addr = 0;
+		}
+
+	/* 長さが 0 でなければエラー */
+	if (len != 0)
+		return 0;
+
+	/* 新しいオプションを設定する。*/
+	if (fsm->state != PPP_FSM_OPENED)
+		ipcp_local_neg_cfg = new_cfg;
+
+	return 1;
+	}
+
+/*
+ *  ipcp_reqci -- 相手の構成情報を解析する。
+ */
+
+static int_t
+ipcp_reqci (T_PPP_FSM *fsm, T_NET_BUF *input, T_NET_BUF *output)
+{
+	uint32_t	addr;
+	uint16_t	code, final, len, cilen;
+	uint8_t		*np, *rp, *ap, *cp, type = 0;
+
+	rp = ap = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+				/* rp: REJ、ap: ACK する CI のポインタ	*/
+				/* 拒否する場合は、引数 buf に上書きする。	*/
+	len   = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+	np    = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	final = PPP_CONFACK;	/* 最終的に送信するコード */
+	while (len > 0) {
+		code = PPP_CONFACK;
+		cp   = ap;	/* cp: 現在処理中の CI	*/
+
+		if (len < sizeof(T_PPP_CI_HDR)) {
+
+			/* 残りが CI ヘッダより短い */
+			syslog(LOG_NOTICE, "[PPP/IPCP] bad CI len: %d.", len);
+			cilen = len;	/* データ長が異常の場合の処置	*/
+			len  = 0;	/* ループから抜ける。		*/
+			code  = PPP_CONFREJ;
+			goto endswitch;
+			}
+
+		type  = *ap ++;	/* CI の型		*/
+		cilen = *ap ++;	/* CI の長さ		*/
+		if (len < cilen) {
+
+			/* 残りが CI 長より短い */
+			syslog(LOG_NOTICE, "[PPP/IPCP] bad CI len: %d.", cilen);
+			cilen = len;	/* データ長が異常の場合の処置	*/
+			len  = 0;	/* ループから抜ける。		*/
+			code  = PPP_CONFREJ;
+			goto endswitch;
+			}
+		len -= sizeof(T_PPP_CI_HDR);
+
+		/* CI の型により分岐する。*/
+		switch (type) {
+
+		case IPCP_CIT_ADDR:	/* IPv4 アドレス */
+
+		 	/* CI 長が、ヘッダ + 4 オクテットでなければエラー */
+		 	if (cilen != sizeof(T_PPP_CI_HDR) + sizeof(uint32_t))
+				code = PPP_CONFREJ;
+			else {
+				ntoahl(addr, ap);
+				if (addr != ipcp_remote_neg_cfg.in4_ifaddr.addr &&
+				    (addr == 0 || ipcp_remote_neg_cfg.in4_ifaddr.addr != 0)) {
+					*np ++ = IPCP_CIT_ADDR;
+					*np ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+					ahtonl(np, ipcp_remote_neg_cfg.in4_ifaddr.addr);
+					np  += sizeof(uint32_t);
+					code = PPP_CONFNAK;
+					}
+#if 1	/* 要確認 */
+				else if (addr == 0 && ipcp_remote_neg_cfg.in4_ifaddr.addr == 0)
+#else
+				else if (addr == 0 || ipcp_remote_neg_cfg.in4_ifaddr.addr == 0)
+#endif
+					code = PPP_CONFREJ;
+				else
+					ipcp_remote_neg_cfg.in4_ifaddr.addr = addr;
+				}
+			break;
+
+		default:
+			syslog(LOG_INFO, "[PPP/IPCP] unexp opt: %d.", type);
+			code = PPP_CONFREJ;
+			break;
+			}
+endswitch:
+
+		if (code == PPP_CONFNAK) {
+			/* CI の型が Magic Number の場合を除いて、NAK の回数が	*/
+			/* 最大値 MAX_PPP_FAILURES  を超えたら拒否する。	*/
+			if (fsm->failures >= MAX_PPP_FAILURES)
+				code = PPP_CONFREJ;
+			else if (final != PPP_CONFREJ)
+				final = PPP_CONFNAK;
+			}
+
+		/* この CI を拒否する */
+		if (code == PPP_CONFREJ) {
+			if (rp < cp)		/* 前に詰める。*/
+				memcpy(rp, cp, cilen);
+			rp += cilen;
+			final = PPP_CONFREJ;
+			}
+
+		ap   += cilen - sizeof(T_PPP_CI_HDR);
+		len  -= cilen - sizeof(T_PPP_CI_HDR);
+		}
+
+	/* 最終的な長さを調整する。*/
+	switch (final) {
+	case PPP_CONFNAK:
+		output->len = np - output->buf;
+		memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+		break;
+	case PPP_CONFREJ:
+		memcpy(output->buf, input->buf, output->len = rp - input->buf);
+		break;
+	case PPP_CONFACK:
+		memcpy(output->buf, input->buf, input->len);
+		break;
+		}
+
+	return final;
+	}
+
+/*
+ *  ipcp_up -- リンク接続を確立する。
+ */
+
+static void
+ipcp_up (T_PPP_FSM *fsm)
+{
+	/* 自構成情報の初期設定 */
+	ipcp_local_ack_cfg = ipcp_local_neg_cfg;
+
+	/*
+	 *  サブネットマスクと
+	 *  ローカル・ブロードキャスト IPv4 アドレスを設定する。
+	 */
+	ipcp_local_ack_cfg.in4_ifaddr.mask = MAKE_IPV4_LOCAL_MASK(ipcp_local_neg_cfg.in4_ifaddr.addr);
+
+	/* 相手の構成情報の初期設定 */
+	ipcp_remote_ack_cfg = ipcp_remote_neg_cfg;
+
+	/*
+	 *  サブネットマスクと
+	 *  ローカル・ブロードキャスト IPv4 アドレスを設定する。
+	 */
+	ipcp_remote_ack_cfg.in4_ifaddr.mask = MAKE_IPV4_LOCAL_MASK(ipcp_remote_neg_cfg.in4_ifaddr.addr);
+
+	sig_sem(SEM_IPCP_READY);
+
+	syslog(LOG_NOTICE, "[PPP/IPCP] up, Local IPv4 Addr: %s, Remote IPv4 Addr: %s.",
+	                   ip2str(NULL, &ipcp_local_neg_cfg.in4_ifaddr.addr),
+	                   ip2str(NULL, &ipcp_remote_neg_cfg.in4_ifaddr.addr));
+	}
+
+/*
+ *  ipcp_down -- リンク接続を解放する。
+ */
+
+static void
+ipcp_down (T_PPP_FSM *fsm)
+{
+	sig_sem(SEM_IPCP_READY);
+	syslog(LOG_NOTICE, "[PPP/IPCP] down.");
+	}
+
+/*
+ *  ipcp_finished -- 下位層を終了する。
+ */
+
+static void
+ipcp_finished (T_PPP_FSM *fsm)
+{
+	}
+
+/*
+ *  ipcp_protrej -- Proto-REJ を受信したときの処理
+ */
+
+static void
+ipcp_protrej (void)
+{
+	fsm_lowerdown(&ipcp_fsm);
+	}
+
+/*
+ *  ipcp_lowerup -- IPCP 下位層を起動する。
+ */
+
+static void
+ipcp_lowerup (void)
+{
+	fsm_lowerup(&ipcp_fsm);
+	}
+
+/*
+ *  ipcp_lowerdown -- IPCP 下位層を停止する。
+ */
+
+static void
+ipcp_lowerdown (void)
+{
+	fsm_lowerdown(&ipcp_fsm);
+	}
+
+/*
+ *  ipcp_open -- IPCP のオープン
+ */
+
+static void
+ipcp_open (void)
+{
+	fsm_open(&ipcp_fsm);
+	}
+
+/*
+ *  ipcp_close -- IPCP のクローズ
+ */
+
+static void
+ipcp_close (void)
+{
+	fsm_close(&ipcp_fsm);
+	}
+
+#endif	/* fo #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipcp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipcp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipcp.h	(revision 398)
@@ -0,0 +1,129 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * ipcp.h - IP Control 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD: src/usr.sbin/pppd/ipcp.h,v 1.9.2.1 1999/08/29 15:47:01 peter Exp $
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/ipcp.h,v 1.30.2.2 2000/06/15 17:08:28 brian Exp $
+ *
+ *	TODO:
+ */
+
+#ifndef _PPP_IPCP_H_
+#define _PPP_IPCP_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  IPCP の構成情報 (CI)
+ */
+
+/*
+ *  CI の型
+ */
+
+#define IPCP_CIT_ADDRS		UINT_C(1)	/* IP アドレス (廃棄)	*/
+#define IPCP_CIT_COMP_TYPE	UINT_C(2)	/* 圧縮方式		*/
+#define IPCP_CIT_ADDR		UINT_C(3)	/* IP アドレス		*/
+
+/*
+ *  前方参照
+ */
+
+#ifndef T_IFNET_DEFINED
+
+typedef struct t_ifnet T_IFNET;
+
+#define T_IFNET_DEFINED
+
+#endif	/* of #ifndef T_IFNET_DEFINED */
+
+/*
+ *  変数
+ */
+
+#ifdef T_PPP_FSM_DEFINED
+extern T_PPP_FSM	ipcp_fsm;
+#endif	/* of #ifdef T_PPP_FSM_DEFINED */
+
+#ifdef T_PPP_PROTENT_DEFINED
+extern T_PPP_PROTENT	ipcp_protent;
+#endif	/* of #ifdef T_PPP_PROTENT_DEFINED */
+
+extern T_IFNET	ipcp_local_ack_cfg;
+extern T_IFNET	ipcp_remote_ack_cfg;
+
+/*
+ *  関数
+ */
+
+extern ER wait_ipcp (void);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _PPP_IPCP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.c	(revision 398)
@@ -0,0 +1,663 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * ipv6cp.c - PPP IP Control Protocol.
+ *
+ * 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *	PPP IP Control Protocol (IPV6CP) Module
+ *
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan, Inc.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/ipv6cp.c,v 1.90.2.4 2000/08/19 09:30:03 brian Exp $
+ *
+ *	TODO:
+ *		o Support IPADDRS properly
+ *		o Validate the length in IpcpDecodeConfig
+ */
+
+#include <string.h>
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_lcp.h>
+#include <net/ppp_ipv6cp.h>
+#include <net/ppp_modem.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/udp_var.h>
+
+#include <net/if_var.h>
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  関数
+ */
+
+static void ipv6cp_init (void);
+static void ipv6cp_input (T_NET_BUF *input);
+static void ipv6cp_protrej (void);
+static void ipv6cp_lowerup (void);
+static void ipv6cp_lowerdown (void);
+static void ipv6cp_open (void);
+static void ipv6cp_close (void);
+
+/*
+ * FSM から呼出されるコールバック関
+ */
+
+static void  ipv6cp_resetci(T_PPP_FSM *fsm);	/* 自構成情報をリセットする。	*/
+static int_t ipv6cp_cilen	(T_PPP_FSM *fsm);	/* 構成情報の長さを返す。		*/
+static void  ipv6cp_addci	(T_PPP_FSM *fsm, T_NET_BUF *output);
+						/* 自構成情報を追加する。		*/
+static bool_t  ipv6cp_ackci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* ACK を受信したときの処理	*/
+static bool_t  ipv6cp_nakci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* NAK を受信したときの処理	*/
+static bool_t  ipv6cp_rejci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* REJ を受信したときの処理	*/
+static int_t ipv6cp_reqci	(T_PPP_FSM *fsm, T_NET_BUF *input, T_NET_BUF *output);
+						/* 相手の構成情報を確認する。	*/
+static void ipv6cp_up	(T_PPP_FSM *fsm);	/* リンク接続を確立する。		*/
+static void ipv6cp_down	(T_PPP_FSM *fsm);	/* リンク接続を解放する。		*/
+static void ipv6cp_finished(T_PPP_FSM *fsm);	/* 下位層を終了する。		*/
+
+/*
+ *  変数
+ */
+
+static T_IFNET ipv6cp_local_def_cfg = {		/* 自構成情報の規定値		*/
+	NULL,					/* ネットワークインタフェースのソフトウェア情報	*/
+	{},					/* IPv6 アドレス情報				*/
+	{},					/* マルチキャスト IPv6 アドレス			*/
+	0,					/* フラグ					*/
+	};
+
+static T_IFNET ipv6cp_remote_def_cfg = {	/* 相手の構成情報の規定値	*/
+	NULL,					/* ネットワークインタフェースのソフトウェア情報	*/
+	{},					/* IPv6 アドレス情報				*/
+	{},					/* マルチキャスト IPv6 アドレス			*/
+	0,					/* フラグ					*/
+	};
+
+static T_IFNET ipv6cp_local_neg_cfg;		/* ネゴ中の自構成情報		*/
+
+static T_IFNET ipv6cp_remote_neg_cfg;		/* ネゴ中の相手の構成情報		*/
+
+/*
+ *  全域変数
+ */
+
+T_PPP_FSM_CALLBACKS ipv6cp_callbacks = {
+	ipv6cp_resetci,			/* 自構成情報をリセットする。	*/
+	ipv6cp_cilen,			/* 構成情報の長さを返す。		*/
+	ipv6cp_addci,			/* 自構成情報を追加する。		*/
+	ipv6cp_ackci,			/* ACK を受信したときの処理	*/
+	ipv6cp_nakci,			/* NAK を受信したときの処理	*/
+	ipv6cp_rejci,			/* REJ を受信したときの処理	*/
+	ipv6cp_reqci,			/* 相手の構成情報を確認する。	*/
+	ipv6cp_up,			/* リンク接続を確立する。		*/
+	ipv6cp_down,			/* リンク接続を解放する。		*/
+	NULL,				/* 下位層を開始する。		*/
+	ipv6cp_finished,			/* 下位層を終了する。		*/
+	NULL,				/* 再送する。			*/
+	NULL,				/* 不明な CP を受信したときの処理	*/
+	};
+
+T_PPP_FSM ipv6cp_fsm = {
+	&ipv6cp_callbacks,		/* コールバック関数		*/
+	PPP_IPV6CP,			/* プロトコル			*/
+	};
+
+T_PPP_PROTENT ipv6cp_protent = {
+	PPP_IPV6CP,
+	ipv6cp_init,			/* 初期化			*/
+	ipv6cp_input,			/* 入力				*/
+	ipv6cp_protrej,			/* Proto-REJ 受信処理		*/
+	ipv6cp_lowerup,			/* 下位層を起動する		*/
+	ipv6cp_lowerdown,		/* 下位層を停止する		*/
+	ipv6cp_open,			/* オープンする			*/
+	ipv6cp_close,			/* クローズする			*/
+	ip6_input,			/* データ入力、IPv6 入力	*/
+	};
+
+T_IFNET ipv6cp_local_ack_cfg;		/* 相手に許可されたの自構成情報	*/
+T_IFNET ipv6cp_remote_ack_cfg;		/* 相手に許可した構成情報	*/
+
+/*
+ *  ppp_get_ifnet -- ネットワークインタフェース構造体を返す。
+ */
+
+T_IFNET *
+ppp_get_ifnet (void)
+{
+	return &ipv6cp_local_ack_cfg;
+	}
+
+/*
+ *  wait_ipv6cp -- IP 接続完了まで待つ。
+ *
+ *	戻り値: 接続に失敗したら E_OBJ を返す。
+ */
+
+ER
+wait_ipv6cp (void)
+{
+#ifdef PPP_CFG_MODEM
+	ER error;
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+	if (ipv6cp_fsm.state <= PPP_FSM_STOPPED) {
+
+#ifdef PPP_CFG_MODEM
+
+		/* モデムの接続完了まで待つ。*/
+		if ((error = wait_modem()) != E_OK)
+			return error;
+
+#else	/* of #ifdef PPP_CFG_MODEM */
+
+		/*
+		 * 受動オープンし、相手からの接続待ちなら LCP を一度クローズし、
+		 * 能動オープン状態で、再オープンする。
+		 */
+		lcp_close();
+		lcp_open(PPP_OPEN_ACTIVE);
+
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+		}
+
+	if (ipv6cp_fsm.state != PPP_FSM_OPENED) {
+		/* IP 接続完了まで待つ。*/
+		wai_sem(SEM_IPV6CP_READY);
+		if (ipv6cp_fsm.state != PPP_FSM_OPENED)
+			return E_OBJ;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  ipv6cp_init -- IPV6CP モジュールの初期化
+ */
+
+static void
+ipv6cp_init (void)
+{
+	fsm_init(&ipv6cp_fsm);
+	}
+
+/*
+ *  ipv6cp_input -- IPV6CP 入力
+ */
+
+static void
+ipv6cp_input (T_NET_BUF *input)
+{
+	NET_COUNT_PPP_IPV6CP(net_count_ppp_ipv6cp_in_octets,  input->len);
+	NET_COUNT_PPP_IPV6CP(net_count_ppp_ipv6cp_in_packets, 1);
+	fsm_input(&ipv6cp_fsm, input);
+	}
+
+/*
+ *  ipv6cp_resetci -- IPV6CPの構成情報をリセットする。
+ */
+
+static void
+ipv6cp_resetci (T_PPP_FSM *fsm)
+{
+	/* 自構成情報の初期設定 */
+	ipv6cp_local_neg_cfg = ipv6cp_local_def_cfg;
+	memset((void*)&ipv6cp_local_ack_cfg, 0, sizeof(T_IFNET));
+
+	/* 相手の構成情報の初期設定 */
+	ipv6cp_remote_neg_cfg = ipv6cp_remote_def_cfg;
+	memset((void*)&ipv6cp_remote_ack_cfg, 0, sizeof(T_IFNET));
+	}
+
+/*
+ *  ipv6cp_cilen -- 構成情報の長さを返す。
+ */
+
+static int_t
+ipv6cp_cilen (T_PPP_FSM *fsm)
+{
+	int_t cilen = 0;
+
+	cilen += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);	/* IPv6 アドレス */
+
+	return cilen;
+	}
+
+/*
+ *  ipv6cp_addci -- IPV6CPの構成情報を追加する。
+ */
+
+static void
+ipv6cp_addci (T_PPP_FSM *fsm, T_NET_BUF *output)
+{
+	uint8_t *buf;
+
+	buf = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+
+	/* IPv6 アドレスオプションを追加する。 */
+	*buf ++ = IPV6CP_CIT_ADDR;
+	*buf ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+	ahtonl(buf, ipv6cp_local_neg_cfg.in6_ifaddrs[0].addr);
+	buf += sizeof(uint32_t);
+	}
+
+/*
+ *  ipv6cp_ackci -- ACK を受信したときの処理
+ *
+ *	戻り値:	true  ACK は正常
+ *		false ACK は異常
+ */
+
+static bool_t
+ipv6cp_ackci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	uint8_t		*buf;
+	uint16_t	len;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	/*
+	 *  構成情報は送信した順に完全に一致しなければならない。
+	 *  従って、ipv6cp_addci で作成した順に解析する。
+	 */
+
+	/* ADDR オプションを解析する。 */
+	if (len < sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)	||
+	    *buf ++ != IPV6CP_CIT_ADDR			||
+	    *buf ++ != sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)||
+	    nahcmpl(buf, ipv6cp_local_neg_cfg.in6_ifaddrs[0].addr))
+		return false;
+	buf += sizeof(uint32_t);
+	len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+
+	return true;
+	}
+
+/*
+ *  ipv6cp_nakci -- NAK を受信したときの処理
+ *
+ *	戻り値:	1  NAK は正常
+ *		0  NAK は異常
+ */
+
+static int_t
+ipv6cp_nakci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_IFNET		new_cfg;
+	uint32_t	addr;
+	uint16_t	len;
+	uint8_t		*buf, cilen;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	new_cfg = ipv6cp_local_neg_cfg;
+
+	/* ADDR オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(addr)		&&
+	    * buf      == IPV6CP_CIT_ADDR			&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(addr)) {
+		memcpy(&new_cfg.in6_ifaddrs[0].addr, buf + 2, sizeof(addr));
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(addr);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(addr);
+		}
+
+	/* 後は無視する。*/
+	while (len > sizeof(T_PPP_CI_HDR)) {
+		cilen = *(buf + 1);
+		if (len < cilen)
+			return 0;
+		buf += cilen;
+		len -= cilen;
+		}
+
+	/* 長さが 0 でなければエラー */
+	if (len != 0)
+		return 0;
+
+	/* 新しいオプションを設定する。*/
+	if (fsm->state != PPP_FSM_OPENED)
+		ipv6cp_local_neg_cfg = new_cfg;
+               		
+	return 1;
+	}
+
+/*
+ *  ipv6cp_rejci -- REJ を受信したときの処理
+ *
+ *	戻り値:	1  REJ は正常
+ *		0  REJ は異常
+ */
+
+static int_t
+ipv6cp_rejci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_IFNET		new_cfg;
+	uint8_t		*buf;
+	uint16_t	len;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	new_cfg = ipv6cp_local_neg_cfg;
+
+	/* ADDR オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr)	&&
+	    * buf      == IPV6CP_CIT_ADDR					&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr)) {
+		memcpy(&new_cfg.in6_ifaddrs[0].addr, &in6_addr_unspecified,
+		 sizeof(new_cfg.in6_ifaddrs[0].addr));
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr);
+		}
+
+	/* 長さが 0 でなければエラー */
+	if (len != 0)
+		return 0;
+
+	/* 新しいオプションを設定する。*/
+	if (fsm->state != PPP_FSM_OPENED)
+		ipv6cp_local_neg_cfg = new_cfg;
+
+	return 1;
+	}
+
+/*
+ *  ipv6cp_reqci -- 相手の構成情報を解析する。
+ */
+
+static int_t
+ipv6cp_reqci (T_PPP_FSM *fsm, T_NET_BUF *input, T_NET_BUF *output)
+{
+	T_IN6_ADDR	addr;
+	uint16_t	code, final, len, cilen;
+	uint8_t		*np, *rp, *ap, *cp, type = 0;
+
+	rp = ap = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+				/* rp: REJ、ap: ACK する CI のポインタ	*/
+				/* 拒否する場合は、引数 buf に上書きする。	*/
+	len   = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+	np    = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	final = PPP_CONFACK;	/* 最終的に送信するコード */
+	while (len > 0) {
+		code = PPP_CONFACK;
+		cp   = ap;	/* cp: 現在処理中の CI	*/
+
+		if (len < sizeof(T_PPP_CI_HDR)) {
+
+			/* 残りが CI ヘッダより短い */
+			syslog(LOG_NOTICE, "[PPP/IPV6CP] bad CI len: %d.", len);
+			cilen = len;	/* データ長が異常の場合の処置	*/
+			len  = 0;	/* ループから抜ける。		*/
+			code  = PPP_CONFREJ;
+			goto endswitch;
+			}
+
+		type  = *ap ++;	/* CI の型		*/
+		cilen = *ap ++;	/* CI の長さ		*/
+		if (len < cilen) {
+
+			/* 残りが CI 長より短い */
+			syslog(LOG_NOTICE, "[PPP/IPV6CP] bad CI len: %d.", cilen);
+			cilen = len;	/* データ長が異常の場合の処置	*/
+			len  = 0;	/* ループから抜ける。		*/
+			code  = PPP_CONFREJ;
+			goto endswitch;
+			}
+		len -= sizeof(T_PPP_CI_HDR);
+
+		/* CI の型により分岐する。*/
+		switch (type) {
+
+		case IPV6CP_CIT_ADDR:	/* IPv6 アドレス */
+
+		 	/* CI 長が、ヘッダ + 4 オクテットでなければエラー */
+		 	if (cilen != sizeof(T_PPP_CI_HDR) + sizeof(addr))
+				code = PPP_CONFREJ;
+			else {
+				memcpy((uint8_t*)&ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr, ap,
+				           sizeof(ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr));
+				if (!IN6_ARE_ADDR_EQUAL(&addr, &ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr) &&
+				    (IN6_IS_ADDR_UNSPECIFIED(&addr) ||
+				     IN6_IS_ADDR_UNSPECIFIED(&ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr))) {
+					memcpy(np, (uint8_t*)&ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr,
+					               sizeof(ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr));
+					*np ++ = IPV6CP_CIT_ADDR;
+					*np ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+					np    += sizeof(ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr);
+					code = PPP_CONFNAK;
+					}
+#if 1	/* 要確認 */
+				else if (IN6_IS_ADDR_UNSPECIFIED(&addr) &&
+				         IN6_IS_ADDR_UNSPECIFIED(&ipv6cp_remote_neg_cfg.in6_ifaddrs[0]))
+#else
+				else if (IN6_IS_ADDR_UNSPECIFIED(&addr) ||
+				         IN6_IS_ADDR_UNSPECIFIED(&ipv6cp_remote_neg_cfg.in6_ifaddrs[0]))
+#endif
+					code = PPP_CONFREJ;
+				else
+					ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr = addr;
+				}
+			break;
+
+		default:
+			syslog(LOG_INFO, "[PPP/IPV6CP] unexp opt: %d.", type);
+			code = PPP_CONFREJ;
+			break;
+			}
+endswitch:
+
+		if (code == PPP_CONFNAK) {
+			/* CI の型が Magic Number の場合を除いて、NAK の回数が	*/
+			/* 最大値 MAX_PPP_FAILURES  を超えたら拒否する。	*/
+			if (fsm->failures >= MAX_PPP_FAILURES)
+				code = PPP_CONFREJ;
+			else if (final != PPP_CONFREJ)
+				final = PPP_CONFNAK;
+			}
+
+		/* この CI を拒否する */
+		if (code == PPP_CONFREJ) {
+			if (rp < cp)		/* 前に詰める。*/
+				memcpy(rp, cp, cilen);
+			rp += cilen;
+			final = PPP_CONFREJ;
+			}
+
+		ap   += cilen - sizeof(T_PPP_CI_HDR);
+		len  -= cilen - sizeof(T_PPP_CI_HDR);
+		}
+
+	/* 最終的な長さを調整する。*/
+	switch (final) {
+	case PPP_CONFNAK:
+		output->len = np - output->buf;
+		memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+		break;
+	case PPP_CONFREJ:
+		memcpy(output->buf, input->buf, output->len = rp - input->buf);
+		break;
+	case PPP_CONFACK:
+		memcpy(output->buf, input->buf, input->len);
+		break;
+		}
+
+	return final;
+	}
+
+/*
+ *  ipv6cp_up -- リンク接続を確立する。
+ */
+
+static void
+ipv6cp_up (T_PPP_FSM *fsm)
+{
+	/* 自構成情報の初期設定 */
+	ipv6cp_local_ack_cfg = ipv6cp_local_neg_cfg;
+
+	sig_sem(SEM_IPV6CP_READY);
+
+	syslog(LOG_NOTICE, "[PPP/IPV6CP] up, Local IPv6 Addr: %s, Remote IPv6 Addr: %s.",
+	                   ipv62str(NULL, &ipv6cp_local_neg_cfg.in6_ifaddrs[0].addr),
+	                   ipv62str(NULL, &ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr));
+	}
+
+/*
+ *  ipv6cp_down -- リンク接続を解放する。
+ */
+
+static void
+ipv6cp_down (T_PPP_FSM *fsm)
+{
+	sig_sem(SEM_IPV6CP_READY);
+	syslog(LOG_NOTICE, "[PPP/IPV6CP] down.");
+	}
+
+/*
+ *  ipv6cp_finished -- 下位層を終了する。
+ */
+
+static void
+ipv6cp_finished (T_PPP_FSM *fsm)
+{
+	}
+
+/*
+ *  ipv6cp_protrej -- Proto-REJ を受信したときの処理
+ */
+
+static void
+ipv6cp_protrej (void)
+{
+	fsm_lowerdown(&ipv6cp_fsm);
+	}
+
+/*
+ *  ipv6cp_lowerup -- IPV6CP 下位層を起動する。
+ */
+
+static void
+ipv6cp_lowerup (void)
+{
+	fsm_lowerup(&ipv6cp_fsm);
+	}
+
+/*
+ *  ipv6cp_lowerdown -- IPV6CP 下位層を停止する。
+ */
+
+static void
+ipv6cp_lowerdown (void)
+{
+	fsm_lowerdown(&ipv6cp_fsm);
+	}
+
+/*
+ *  ipv6cp_open -- IPV6CP のオープン
+ */
+
+static void
+ipv6cp_open (void)
+{
+	fsm_open(&ipv6cp_fsm);
+	}
+
+/*
+ *  ipv6cp_close -- IPV6CP のクローズ
+ */
+
+static void
+ipv6cp_close (void)
+{
+	fsm_close(&ipv6cp_fsm);
+	}
+
+#endif	/* fo #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.h	(revision 398)
@@ -0,0 +1,129 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * ipv6cp.h - IP Control 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD: src/usr.sbin/pppd/ipv6cp.h,v 1.9.2.1 1999/08/29 15:47:01 peter Exp $
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/ipv6cp.h,v 1.30.2.2 2000/06/15 17:08:28 brian Exp $
+ *
+ *	TODO:
+ */
+
+#ifndef _PPP_IPV6CP_H_
+#define _PPP_IPV6CP_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  IPV6CP の構成情報 (CI)
+ */
+
+/*
+ *  CI の型
+ */
+
+#define IPV6CP_CIT_ADDRS		UINT_C(1)	/* IP アドレス (廃棄)	*/
+#define IPV6CP_CIT_COMP_TYPE	UINT_C(2)	/* 圧縮方式		*/
+#define IPV6CP_CIT_ADDR		UINT_C(3)	/* IP アドレス		*/
+
+/*
+ *  前方参照
+ */
+
+#ifndef T_IFNET_DEFINED
+
+typedef struct t_ifnet T_IFNET;
+
+#define T_IFNET_DEFINED
+
+#endif	/* of #ifndef T_IFNET_DEFINED */
+
+/*
+ *  変数
+ */
+
+#ifdef T_PPP_FSM_DEFINED
+extern T_PPP_FSM	ipv6cp_fsm;
+#endif	/* of #ifdef T_PPP_FSM_DEFINED */
+
+#ifdef T_PPP_PROTENT_DEFINED
+extern T_PPP_PROTENT	ipv6cp_protent;
+#endif	/* of #ifdef T_PPP_PROTENT_DEFINED */
+
+extern T_IFNET	ipv6cp_local_ack_cfg;
+extern T_IFNET	ipv6cp_remote_ack_cfg;
+
+/*
+ *  関数
+ */
+
+extern ER wait_ipv6cp (void);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _PPP_IPV6CP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_lcp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_lcp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_lcp.c	(revision 398)
@@ -0,0 +1,1332 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * lcp.c - PPP Link Control Protocol.
+ *
+ * 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *	      PPP Link Control Protocol (LCP) Module
+ *
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan, Inc.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/lcp.c,v 1.81.2.3 2000/08/19 09:30:04 brian Exp $
+ *
+ */
+
+#include <string.h>
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_hdlc.h>
+#include <net/ppp_auth.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_lcp.h>
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  関数
+ */
+
+static void lcp_init    (void);
+static void lcp_protrej (void);
+static void lcp_input   (T_NET_BUF *input);
+
+#if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC
+
+static void send_echo_req  (T_PPP_FSM *fsm);
+static void recv_echo_rep  (T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input);
+static void echo_timeout   (void *arg);
+static void echo_lowerup   (void);
+static void echo_lowerdown (void);
+
+#endif	/* of #if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC */
+
+/*
+ * FSM から呼出されるコールバック関数
+ */
+
+static void  lcp_resetci(T_PPP_FSM *fsm);	/* 自構成情報をリセットする。	*/
+static int_t lcp_cilen	(T_PPP_FSM *fsm);	/* 構成情報の長さを返す。		*/
+static void  lcp_addci	(T_PPP_FSM *fsm, T_NET_BUF *output);
+						/* 自構成情報を追加する。		*/
+static bool_t lcp_ackci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* ACK を受信したときの処理	*/
+static bool_t lcp_nakci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* NAK を受信したときの処理	*/
+static bool_t lcp_rejci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* REJ を受信したときの処理	*/
+static int_t lcp_reqci	(T_PPP_FSM *fsm, T_NET_BUF *input, T_NET_BUF *output);
+						/* 相手の構成情報を確認する。	*/
+static void lcp_up	(T_PPP_FSM *fsm);	/* リンク接続を確立する。		*/
+static void lcp_starting(T_PPP_FSM *fsm);	/* 下位層を開始する。		*/
+static bool_t lcp_extcode	(T_PPP_FSM *fsm, uint8_t code, uint8_t id, T_NET_BUF *input);
+						/* 不明な CP を受信したときの処理	*/
+static void lcp_rprotrej(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* Proto-REJ を受信したときの処理	*/
+/*
+ *  変数
+ */
+
+static T_LCP_CONFIGS lcp_def_cfg = {		/* 構成情報の初期設定値		*/
+	DEF_REMOTE_ACCM,			/* ACCM				*/
+
+#ifdef LCP_CFG_MAGIC
+
+	ULONG_C(0),				/* マジック番号			*/
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+	DEF_PPP_MTU,				/* MRU				*/
+	UINT_C(0),				/* オプションフラグ		*/
+	};
+
+static T_LCP_CONFIGS lcp_local_def_cfg = {	/* 自構成情報の規定値		*/
+	DEF_LOCAL_ACCM,				/* ACCM				*/
+
+#ifdef LCP_CFG_MAGIC
+
+	ULONG_C(0),				/* マジック番号			*/
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+	DEF_PPP_MTU,				/* MRU				*/
+	DEF_LCP_LOCAL_CFGS,			/* オプションフラグ		*/
+	};
+
+static T_LCP_CONFIGS lcp_local_neg_cfg;		/* ネゴ中の自構成情報		*/
+
+static T_LCP_CONFIGS lcp_remote_neg_cfg;	/* ネゴ中の相手の構成情報		*/
+
+#if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC
+
+static uint8_t echo_pending  = UINT_C(0);
+static uint8_t echo_number   = UINT_C(0);
+static uint8_t timer_running = false;
+
+#endif	/* of #if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC */
+
+/*
+ *  全域変数
+ */
+
+T_PPP_FSM_CALLBACKS lcp_callbacks = {
+	lcp_resetci,			/* 自構成情報をリセットする。	*/
+	lcp_cilen,			/* 構成情報の長さを返す。		*/
+	lcp_addci,			/* 自構成情報を追加する。		*/
+	lcp_ackci,			/* ACK を受信したときの処理	*/
+	lcp_nakci,			/* NAK を受信したときの処理	*/
+	lcp_rejci,			/* REJ を受信したときの処理	*/
+	lcp_reqci,			/* 相手の構成情報を確認する。	*/
+	lcp_up,				/* リンク接続を確立する。		*/
+	lcp_down,			/* リンク接続を解放する。		*/
+	lcp_starting,			/* 下位層を開始する。		*/
+	lcp_finished,			/* 下位層を終了する。		*/
+	NULL,				/* 再送する。			*/
+	lcp_extcode,			/* 不明な CP を受信したときの処理	*/
+	};
+
+T_PPP_FSM lcp_fsm = {
+	&lcp_callbacks,			/* コールバック関数		*/
+	PPP_LCP,			/* プロトコル			*/
+	};
+
+T_PPP_PROTENT lcp_protent = {
+	PPP_LCP,
+	lcp_init,			/* 初期化			*/
+	lcp_input,			/* 入力				*/
+	lcp_protrej,			/* Proto-REJ 受信処理		*/
+	NULL,				/* 下位層を起動する		*/
+	lcp_lowerdown,			/* 下位層を停止する		*/
+	NULL,				/* オープンする			*/
+	lcp_close,			/* クローズする			*/
+	NULL,				/* データ入力			*/
+	};
+
+T_LCP_CONFIGS lcp_local_ack_cfg;	/* 相手に許可されたの自構成情報	*/
+T_LCP_CONFIGS lcp_remote_ack_cfg;	/* 相手に許可した構成情報		*/
+
+/*
+ *  lcp_init -- LCP モジュールの初期化
+ */
+
+static void
+lcp_init (void)
+{
+	fsm_init(&lcp_fsm);
+	}
+
+/*
+ *  lcp_input -- LCP 入力
+ */
+
+static void
+lcp_input (T_NET_BUF *input)
+{
+	NET_COUNT_PPP_LCP(net_count_ppp_lcp_in_octets,  input->len);
+	NET_COUNT_PPP_LCP(net_count_ppp_lcp_in_packets, 1);
+	fsm_input(&lcp_fsm, input);
+	}
+
+/*
+ *  lcp_resetci -- LCPの構成情報をリセットする。
+ */
+
+static void
+lcp_resetci (T_PPP_FSM *fsm)
+{
+#ifdef LCP_CFG_MAGIC
+
+	SYSTIM	time;
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+	/* 自構成情報の初期設定 */
+	lcp_local_neg_cfg	= lcp_local_def_cfg;
+	lcp_local_ack_cfg	= lcp_def_cfg;
+
+	/* 相手の構成情報の初期設定 */
+	lcp_remote_neg_cfg	= lcp_def_cfg;
+	lcp_remote_ack_cfg	= lcp_def_cfg;
+
+#ifdef LCP_CFG_MAGIC
+
+	syscall(get_tim(&time));
+	net_srand((unsigned int)time);
+	lcp_local_neg_cfg.magic = net_rand();
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+	auth_reset();
+	}
+
+/*
+ *  lcp_cilen -- 構成情報の長さを返す。
+ */
+
+static int_t
+lcp_cilen (T_PPP_FSM *fsm)
+{
+	int_t cilen = 0;
+
+	if (lcp_local_neg_cfg.options & LCP_CFG_MRU)
+		cilen += sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);	/* MRU   */
+
+	if (lcp_local_neg_cfg.options & LCP_CFG_ACCM)
+		cilen += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);	/* ACCM  */
+
+#ifdef LCP_CFG_MAGIC
+
+	if (lcp_local_neg_cfg.options & LCP_CFG_MAGIC)
+		cilen += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);	/* Magic */
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+#ifdef LCP_CFG_PAP
+
+	if (lcp_local_neg_cfg.options & LCP_CFG_PAP)
+		cilen += sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);	/* PAP   */
+
+#endif	/* of #ifdef LCP_CFG_PAP */
+
+#ifdef LCP_CFG_PCOMP
+
+	if (lcp_local_neg_cfg.options & LCP_CFG_PCOMP)
+		cilen += sizeof(T_PPP_CI_HDR);			/* プロトコル圧縮 */
+
+#endif	/* of #ifdef LCP_CFG_PCOMP */
+
+#ifdef LCP_CFG_ACCOMP
+
+	if (lcp_local_neg_cfg.options & LCP_CFG_ACCOMP)
+		cilen += sizeof(T_PPP_CI_HDR);			/* アドレス・制御圧縮 */
+
+#endif	/* of #ifdef LCP_CFG_ACCOMP */
+
+	return cilen;
+	}
+
+/*
+ *  lcp_addci -- LCPの構成情報を追加する。
+ */
+
+static void
+lcp_addci (T_PPP_FSM *fsm, T_NET_BUF *output)
+{
+	uint8_t *buf;
+
+	buf = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+
+	/* MRU オプションを追加する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_MRU) {
+		*buf ++ = LCP_CIT_MRU;
+		*buf ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		*((uint16_t*)buf) = htons(lcp_local_neg_cfg.MRU);
+		buf += sizeof(uint16_t);
+		}
+
+	/* ACCM オプションを追加する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_ACCM) {
+		*buf ++ = LCP_CIT_ACCM;
+		*buf ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		ahtonl(buf, lcp_local_neg_cfg.ACCM);
+		buf += sizeof(uint32_t);
+		}
+
+#ifdef LCP_CFG_MAGIC
+
+	/* Magic Number オプションを追加する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_MAGIC) {
+		*buf ++ = LCP_CIT_MAGIC;
+		*buf ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		ahtonl(buf, lcp_local_neg_cfg.magic);
+		buf += sizeof(uint32_t);
+		}
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+#ifdef LCP_CFG_PAP
+
+	/* 認証プロトコルオプションを追加する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_PAP) {
+		*buf ++ = LCP_CIT_AUTH;
+		*buf ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		*((uint16_t*)buf) = htons(PPP_PAP);
+		buf += sizeof(uint16_t);
+		}
+
+#endif	/* of #ifdef LCP_CFG_PAP */
+
+#ifdef LCP_CFG_PCOMP
+
+	/* プロトコル圧縮オプションを追加する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_PCOMP) {
+		*buf ++ = LCP_CIT_PCOMP;
+		*buf ++ = sizeof(T_PPP_CI_HDR);
+		}
+
+#endif	/* of #ifdef LCP_CFG_PCOMP */
+
+#ifdef LCP_CFG_ACCOMP
+
+	/* アドレス・制御圧縮オプションを追加する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_ACCOMP) {
+		*buf ++ = LCP_CIT_ACCOMP;
+		*buf ++ = sizeof(T_PPP_CI_HDR);
+		}
+
+#endif	/* of #ifdef LCP_CFG_ACCOMP */
+	}
+
+/*
+ *  lcp_ackci -- ACK を受信したときの処理
+ *
+ *	戻り値:	TURE  ACK は正常
+ *		false ACK は異常
+ */
+
+static bool_t
+lcp_ackci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	uint8_t		*buf;
+	uint16_t	len;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	/*
+	 *  構成情報は送信した順に完全に一致しなければならない。
+	 *  従って、lcp_addci で作成した順に解析する。
+	 */
+
+	/* MRU オプションを解析する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_MRU) {
+		if (len < sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)	||
+		    *buf ++ != LCP_CIT_MRU			||
+		    *buf ++ != sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)||
+		    *((uint16_t*)buf) != htons(lcp_local_neg_cfg.MRU)	)
+			return false;
+		buf += sizeof(uint16_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		}
+
+	/* ACCM オプションを解析する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_ACCM) {
+		if (len < sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)	||
+		    *buf ++ != LCP_CIT_ACCM			||
+		    *buf ++ != sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)||
+		    nahcmpl(buf, lcp_local_neg_cfg.ACCM)        )
+			return false;
+		buf += sizeof(uint32_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		}
+
+#ifdef LCP_CFG_MAGIC
+
+	/* Magic Number オプションを解析する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_MAGIC) {
+		if (len < sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)	||
+		    *buf ++ != LCP_CIT_MAGIC			||
+		    *buf ++ != sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)||
+		    nahcmpl(buf, lcp_local_neg_cfg.magic)       )
+			return false;
+		buf += sizeof(uint32_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		}
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+#ifdef LCP_CFG_PAP
+
+	/* 認証プロトコルオプションを解析する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_PAP) {
+		if (len < sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)	||
+		    *buf ++ != LCP_CIT_AUTH			||
+		    *buf ++ != sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)||
+		    *((uint16_t*)buf) != htons(PPP_PAP)		)
+			return false;
+		buf += sizeof(uint16_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		}
+
+#endif	/* of #ifdef LCP_CFG_PAP */
+
+#ifdef LCP_CFG_PCOMP
+
+	/* プロトコル圧縮オプションを解析する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_PCOMP) {
+		if (len < sizeof(T_PPP_CI_HDR)			||
+		    *buf ++ != LCP_CIT_PCOMP			||
+		    *buf ++ != sizeof(T_PPP_CI_HDR))
+			return false;
+		len -= sizeof(T_PPP_CI_HDR);
+		}
+
+#endif	/* of #ifdef LCP_CFG_PCOMP */
+
+#ifdef LCP_CFG_ACCOMP
+
+	/* アドレス・制御圧縮オプションを解析する。 */
+	if (lcp_local_neg_cfg.options & LCP_CFG_ACCOMP) {
+		if (len < sizeof(T_PPP_CI_HDR)			||
+		    *buf ++ != LCP_CIT_ACCOMP			||
+		    *buf ++ != sizeof(T_PPP_CI_HDR))
+			return false;
+		len -= sizeof(T_PPP_CI_HDR);
+		}
+
+#endif	/* of #ifdef LCP_CFG_ACCOMP */
+	return true;
+	}
+
+/*
+ *  lcp_nakci -- NAK を受信したときの処理
+ *
+ *	戻り値:	1  NAK は正常
+ *		0  NAK は異常
+ */
+
+static int_t
+lcp_nakci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_LCP_CONFIGS	new_cfg;
+	bool_t		loop = false;	/* ループバックをチェック */
+	uint32_t	cilong;
+	uint16_t	cishort, len;
+	uint8_t		*buf, cilen;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	new_cfg = lcp_local_neg_cfg;
+
+	/* MRU オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)		&&
+	    * buf      == LCP_CIT_MRU				&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)	&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_MRU)) {
+	    	cishort = ntohs(*((uint16_t*)(buf + 2)));
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		if (cishort <= lcp_local_neg_cfg.MRU || cishort <= DEF_PPP_MTU)
+			new_cfg.MRU = cishort;
+		}
+
+	/* ACCM オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)		&&
+	    * buf      == LCP_CIT_ACCM				&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)	&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_ACCM)) {
+	    	ntoahl(cilong, buf + 2);
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		new_cfg.ACCM |= cilong;
+		}
+
+#ifdef LCP_CFG_MAGIC
+
+	/* Magic Number オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)		&&
+	    * buf      == LCP_CIT_MAGIC				&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)	&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_MAGIC)) {
+	    	ntoahl(cilong, buf + 2);
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		new_cfg.magic = cilong;
+		loop = true;
+		}
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+#ifdef LCP_CFG_PAP
+
+	/* 認証プロトコルオプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)		&&
+	    * buf      == LCP_CIT_AUTH				&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)	&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_PAP)) {
+	    	cishort = ntohs(*((uint16_t*)(buf + 2)));
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		if (cishort == PPP_PAP)
+			new_cfg.options &= ~LCP_CFG_PAP;
+		else
+			return 0;
+		}
+
+#endif	/* of #ifdef LCP_CFG_PAP */
+
+#ifdef LCP_CFG_PCOMP
+
+	/* プロトコル圧縮オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR)				&&
+	    * buf      == LCP_CIT_PCOMP				&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR)			&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_PCOMP)) {
+		buf += sizeof(T_PPP_CI_HDR);
+		len -= sizeof(T_PPP_CI_HDR);
+		new_cfg.options &= ~LCP_CFG_PCOMP;
+		}
+
+#endif	/* of #ifdef LCP_CFG_PCOMP */
+
+#ifdef LCP_CFG_ACCOMP
+
+	/* アドレス・制御圧縮オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR)				&&
+	    * buf      == LCP_CIT_ACCOMP			&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR)			&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_ACCOMP)) {
+		buf += sizeof(T_PPP_CI_HDR);
+		len -= sizeof(T_PPP_CI_HDR);
+		new_cfg.options &= ~LCP_CFG_ACCOMP;
+		}
+
+#endif	/* of #ifdef LCP_CFG_ACCOMP */
+
+	/* 後は無視する。*/
+	while (len > sizeof(T_PPP_CI_HDR)) {
+		cilen = *(buf + 1);
+		if (len < cilen)
+			return 0;
+		buf += cilen;
+		len -= cilen;
+		}
+
+	/* 長さが 0 でなければエラー */
+	if (len != 0)
+		return 0;
+
+	/* 新しいオプションを設定する。*/
+	if (fsm->state != PPP_FSM_OPENED) {
+		if (loop) {
+			syslog(LOG_WARNING, "[PPP/LCP] line looped.");
+			lcp_close();
+			}
+		lcp_local_neg_cfg = new_cfg;
+		}
+	return 1;
+	}
+
+/*
+ *  lcp_rejci -- REJ を受信したときの処理
+ *
+ *	戻り値:	1  REJ は正常
+ *		0  REJ は異常
+ */
+
+static int_t
+lcp_rejci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_LCP_CONFIGS	new_cfg;
+	uint32_t	cilong;
+	uint16_t	cishort, len;
+	uint8_t		*buf;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	new_cfg = lcp_local_neg_cfg;
+
+	/* MRU オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)		&&
+	    * buf      == LCP_CIT_MRU					&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)	&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_MRU)) {
+	    	cishort = ntohs(*((uint16_t*)(buf + 2)));
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		if (cishort != lcp_local_neg_cfg.MRU)
+			return 0;
+		else
+			new_cfg.options &= ~LCP_CFG_MRU;
+		}
+		
+	/* ACCM オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)		&&
+	    * buf      == LCP_CIT_ACCM					&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)	&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_ACCM)) {
+	    	ntoahl(cilong, buf + 2);
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		if (cilong != lcp_local_neg_cfg.ACCM)
+			return 0;
+		else
+			new_cfg.options &= ~LCP_CFG_ACCM;
+		}
+
+#ifdef LCP_CFG_MAGIC
+
+	/* Magic Number オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)		&&
+	    * buf      == LCP_CIT_MAGIC					&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)	&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_MAGIC)) {
+	    	ntoahl(cilong, buf + 2);
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+		if (cilong != lcp_local_neg_cfg.magic)
+			return 0;
+		else
+			new_cfg.options &= ~LCP_CFG_MAGIC;
+		}
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+#ifdef LCP_CFG_PAP
+
+	/* 認証プロトコルオプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)		&&
+	    * buf      == LCP_CIT_AUTH					&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(uint16_t)	&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_PAP)) {
+	    	cishort = ntohs(*((uint16_t*)(buf + 2)));
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+		if (cishort != PPP_PAP)
+			return 0;
+		else
+			new_cfg.options &= ~LCP_CFG_PAP;
+		}
+
+#endif	/* of #ifdef LCP_CFG_PAP */
+
+#ifdef LCP_CFG_PCOMP
+
+	/* プロトコル圧縮オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR)				&&
+	    * buf      == LCP_CIT_PCOMP				&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR)			&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_PCOMP)) {
+		buf += sizeof(T_PPP_CI_HDR);
+		len -= sizeof(T_PPP_CI_HDR);
+		new_cfg.options &= ~LCP_CFG_PCOMP;
+		}
+
+#endif	/* of #ifdef LCP_CFG_PCOMP */
+
+#ifdef LCP_CFG_ACCOMP
+
+	/* アドレス・制御圧縮オプションを解析する。 */
+	if (len >= sizeof(T_PPP_CI_HDR)				&&
+	    * buf      == LCP_CIT_ACCOMP			&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR)			&&
+	    (lcp_local_neg_cfg.options & LCP_CFG_ACCOMP)) {
+		buf += sizeof(T_PPP_CI_HDR);
+		len -= sizeof(T_PPP_CI_HDR);
+		new_cfg.options &= ~LCP_CFG_ACCOMP;
+		}
+
+#endif	/* of #ifdef LCP_CFG_ACCOMP */
+
+	/* 長さが 0 でなければエラー */
+	if (len != 0)
+		return 0;
+
+	/* 新しいオプションを設定する。*/
+	if (fsm->state != PPP_FSM_OPENED)
+		lcp_local_neg_cfg = new_cfg;
+
+	return 1;
+	}
+
+/*
+ *  lcp_reqci -- 相手の構成情報を解析する。
+ */
+
+static int_t
+lcp_reqci (T_PPP_FSM *fsm, T_NET_BUF *input, T_NET_BUF *output)
+{
+#if DEF_LCP_REMOTE_CFGS & LCP_CFG_MAGIC
+
+	uint32_t	cilong;
+
+#endif	/* of #if DEF_LCP_REMOTE_CFGS & LCP_CFG_MAGIC */
+
+	uint16_t	code, final, len, cilen, cishort;
+	uint8_t		*np, *rp, *ap, *cp, type = 0;
+
+	rp = ap = input->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+				/* rp: REJ、ap: ACK する CI のポインタ		*/
+				/* 拒否する場合は、引数 input に上書きする。	*/
+	len   = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+	np    = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	final = PPP_CONFACK;	/* 最終的に送信するコード */
+	while (len > 0) {
+		code = PPP_CONFACK;
+		cp   = ap;	/* cp: 現在処理中の CI	*/
+
+		if (len < sizeof(T_PPP_CI_HDR)) {
+
+			/* 残りが CI ヘッダより短い */
+			syslog(LOG_WARNING, "[PPP/LCP] bad CI len: %d.", len);
+			cilen = len;	/* データ長が異常の場合の処置	*/
+			len   = 0;	/* ループから抜ける。		*/
+			code  = PPP_CONFREJ;
+			goto endswitch;
+			}
+
+		type  = *ap ++;	/* CI の型		*/
+		cilen = *ap ++;	/* CI の長さ		*/
+		if (len < cilen) {
+
+			/* 残りが CI 長より短い */
+			syslog(LOG_WARNING, "[PPP/LCP] bad CI len: %d.", cilen);
+			cilen = len;	/* データ長が異常の場合の処置	*/
+			len   = 0;	/* ループから抜ける。		*/
+			code  = PPP_CONFREJ;
+			goto endswitch;
+			}
+		len -= sizeof(T_PPP_CI_HDR);
+
+		/* CI の型により分岐する。*/
+		switch (type) {
+
+		case LCP_CIT_MRU:	/* 最大受信量 (Maximum Receive Unit) */
+
+#if (DEF_LCP_REMOTE_CFGS & LCP_CFG_MRU) == 0
+
+			code = PPP_CONFREJ;
+
+#else	/* of #if (DEF_LCP_REMOTE_CFGS & LCP_CFG_MRU) == 0 */
+
+		 	/* CI 長が、ヘッダ + 2 オクテットでなければ REJ */
+		 	if (cilen != sizeof(T_PPP_CI_HDR) + sizeof(uint16_t))
+				code = PPP_CONFREJ;
+			{
+				cishort = ntohs(*(uint16_t*)ap);
+
+				/* 最小受信量より小さければ NAK */
+				if (cishort < MIN_PPP_MTU) {
+					*np ++ = LCP_CIT_MRU;
+					*np ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint16_t);
+					*((uint16_t*)np) = htons(MIN_PPP_MTU);
+					np  += sizeof(uint16_t);
+					code = PPP_CONFNAK;
+					}
+				else {
+					lcp_remote_neg_cfg.MRU = cishort;
+					lcp_remote_neg_cfg.options |= LCP_CFG_MRU;
+					}
+				}
+
+#endif	/* of #if (DEF_LCP_REMOTE_CFGS & LCP_CFG_MRU) == 0 */
+
+			break;
+
+		case LCP_CIT_ACCM:	/* Async Control Character Map */
+
+#if (DEF_LCP_REMOTE_CFGS & LCP_CFG_ACCM) == 0
+
+			code = PPP_CONFREJ;
+
+#else	/* of #if (DEF_LCP_REMOTE_CFGS & LCP_CFG_ACCM) == 0 */
+
+		 	/* CI 長が、ヘッダ + 4 オクテットでなければ REJ */
+		 	if (cilen != sizeof(T_PPP_CI_HDR) + sizeof(uint32_t))
+				code = PPP_CONFREJ;
+			else {
+				ntoahl(lcp_remote_neg_cfg.ACCM, ap);
+				lcp_remote_neg_cfg.options |= LCP_CFG_ACCM;
+				}
+
+#endif	/* of #if (DEF_LCP_REMOTE_CFGS & LCP_CFG_ACCM) == 0 */
+
+			break;
+
+		case LCP_CIT_MAGIC:	/* マジック番号 */
+
+#if (DEF_LCP_REMOTE_CFGS & LCP_CFG_MAGIC) == 0
+
+			code = PPP_CONFREJ;
+
+#else	/* of #if (DEF_LCP_REMOTE_CFGS & LCP_CFG_MAGIC) == 0 */
+
+		 	/* CI 長が、ヘッダ + 4 オクテットでなければ REJ */
+		 	if (cilen != sizeof(T_PPP_CI_HDR) + sizeof(uint32_t))
+				code = PPP_CONFREJ;
+			else {
+				ntoahl(cilong, ap);
+
+				/* 番号が自分と同じなら NAK */
+				if (cilong == lcp_local_neg_cfg.magic) {
+					cilong = net_rand();
+					*np ++ = LCP_CIT_MAGIC;
+					*np ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+					ahtonl(np, cilong);
+					np  += sizeof(uint32_t);
+					code = PPP_CONFNAK;
+					}
+				else {
+					lcp_remote_neg_cfg.magic = cilong;
+					lcp_remote_neg_cfg.options |= LCP_CFG_MAGIC;
+					}
+				}
+
+#endif	/* of #if (DEF_LCP_REMOTE_CFGS & LCP_CFG_MAGIC) == 0 */
+
+			break;
+
+#ifdef LCP_CFG_PAP
+		/* CHAP は実装予定	*/
+
+		case LCP_CIT_AUTH:	/* 認証プロトコル */
+
+		 	/* CI 長が、ヘッダ + 2 オクテットより短いときはエラー */
+		 	if (cilen < sizeof(T_PPP_CI_HDR) + sizeof(uint16_t))
+				code = PPP_CONFREJ;
+			else {
+				cishort = ntohs(*(uint16_t*)ap);
+
+				/* 認証プロトコルにより分岐する	*/
+				if (cishort == PPP_PAP &&
+				    cilen   == sizeof(T_PPP_CI_HDR) + sizeof(uint16_t) &&
+			 	    (DEF_LCP_REMOTE_CFGS & LCP_CFG_PAP) != 0)
+					lcp_remote_neg_cfg.options |= LCP_CFG_PAP;
+				else
+					code = PPP_CONFREJ;
+				}
+			break;
+
+#endif	/* of #ifdef LCP_CFG_PAP */
+
+#ifdef LCP_CFG_PCOMP
+
+		case LCP_CIT_PCOMP:	/* プロトコル部圧縮は実装予定 */
+
+#if (DEF_LCP_REMOTE_CFGS & LCP_CFG_PCOMP) == 0
+
+			code = PPP_CONFREJ;
+
+#else	/* of #if (DEF_LCP_REMOTE_CFGS & LCP_CFG_PCOMP) == 0 */
+
+		 	/* CI 長が、ヘッダ長だけでなければ REJ */
+		 	if (cilen != sizeof(T_PPP_CI_HDR))
+				code = PPP_CONFREJ;
+			else
+				lcp_remote_neg_cfg.options |= LCP_CFG_PCOMP;
+
+#endif	/* of #if (DEF_LCP_REMOTE_CFGS & LCP_CFG_PCOMP) == 0 */
+
+			break;
+
+#endif	/* of #ifdef LCP_CFG_PCOMP */
+
+#ifdef LCP_CFG_ACCOMP
+
+		case LCP_CIT_ACCOMP:	/* アドレス・制御部圧縮 */
+
+#if (DEF_LCP_REMOTE_CFGS & LCP_CFG_ACCOMP) == 0
+
+			code = PPP_CONFREJ;
+
+#else	/* of #if (DEF_LCP_REMOTE_CFGS & LCP_CFG_ACCOMP) == 0 */
+
+		 	/* CI 長が、ヘッダ長だけでなければ REJ */
+		 	if (cilen != sizeof(T_PPP_CI_HDR))
+				code = PPP_CONFREJ;
+			else
+				lcp_remote_neg_cfg.options |= LCP_CFG_ACCOMP;
+
+#endif	/* of #if (DEF_LCP_REMOTE_CFGS & LCP_CFG_ACCOMP) == 0 */
+
+			break;
+
+#endif	/* of #ifdef LCP_CFG_ACCOMP */
+
+		default:
+			syslog(LOG_WARNING, "[PPP/LCP] unexp opt: %d.", type);
+			code  = PPP_CONFREJ;
+			break;
+			}
+endswitch:
+		if (code == PPP_CONFNAK) {
+			/* CI の型が Magic Number の場合を除いて、NAK の回数が	*/
+			/* 最大値 MAX_PPP_FAILURES  を超えたら拒否する。	*/
+			if (fsm->failures >= MAX_PPP_FAILURES && type != LCP_CIT_MAGIC)
+				code = PPP_CONFREJ;
+			else if (final != PPP_CONFREJ)
+				final = PPP_CONFNAK;
+			}
+
+		/* この CI を拒否する */
+		if (code == PPP_CONFREJ) {
+			if (rp < cp)		/* 前に詰める。*/
+				memcpy(rp, cp, cilen);
+			rp += cilen;
+			final = PPP_CONFREJ;
+			}
+
+		ap   += cilen - sizeof(T_PPP_CI_HDR);
+		len  -= cilen - sizeof(T_PPP_CI_HDR);
+		}
+
+	/* 最終的な長さを調整する。*/
+	switch (final) {
+	case PPP_CONFNAK:
+		output->len = np - output->buf;
+		memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+		break;
+	case PPP_CONFREJ:
+		memcpy(output->buf, input->buf, output->len = rp - input->buf);
+		break;
+	case PPP_CONFACK:
+		memcpy(output->buf, input->buf, input->len);
+		break;
+		}
+	return final;
+	}
+
+/*
+ *  lcp_up -- リンク接続を確立する (Phase: Establish に移行する)。
+ */
+
+static void
+lcp_up (T_PPP_FSM *fsm)
+{
+	/* 自構成情報の設定 */
+	lcp_local_ack_cfg = lcp_local_neg_cfg;
+
+	/* 相手の構成情報の設定 */
+	lcp_remote_ack_cfg = lcp_remote_neg_cfg;
+
+#if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC
+
+	echo_lowerup();
+
+#endif	/* of #if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC */
+
+	link_established();
+	}
+
+/*
+ *  lcp_starting -- 下位層を開始する。
+ */
+
+static void
+lcp_starting (T_PPP_FSM *fsm)
+{
+	link_required();
+	}
+
+/*
+ *  lcp_extcode -- LCP 特有の CP を受信したときの処理
+ */
+
+static bool_t
+lcp_extcode (T_PPP_FSM *fsm, uint8_t code, uint8_t id, T_NET_BUF *input)
+{
+#if DEF_LCP_REMOTE_CFGS & LCP_CFG_MAGIC
+
+	T_NET_BUF *output;
+
+#endif	/* of #if DEF_LCP_REMOTE_CFGS & LCP_CFG_MAGIC */
+
+	switch (code) {
+	case PPP_PROTREJ:
+		lcp_rprotrej(fsm, input);
+		break;
+
+	case PPP_ECHOREQ:
+
+#if DEF_LCP_REMOTE_CFGS & LCP_CFG_MAGIC
+
+		if (fsm->state == PPP_FSM_OPENED) {
+			syscall(get_net_buf(&output, sizeof(T_PPP_HDR)
+			                           + sizeof(T_PPP_CP_HDR)
+			                           + sizeof(uint32_t)));
+			*(uint32_t*)(output->buf + sizeof(T_PPP_HDR)
+			                   + sizeof(T_PPP_CP_HDR)) = lcp_local_ack_cfg.magic;
+			IF_SET_PROTO(output, PPP_LCP);
+			ppp_cp_output(PPP_ECHOREP, id, output);
+			}
+
+#endif	/* of #if DEF_LCP_REMOTE_CFGS & LCP_CFG_MAGIC */
+
+		break;
+
+	case PPP_ECHOREP:
+
+#if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC
+
+		recv_echo_rep(fsm, id, input);
+
+#endif	/* of #if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC */
+
+		break;
+
+	case PPP_DISCREQ:
+		break;
+
+	default:
+		return false;
+		break;
+
+		}
+	return true;
+	}
+
+/*
+ *  lcp_rprotrej -- Proto-REJ を受信したときの処理
+ */
+
+static void
+lcp_rprotrej (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_PPP_PROTENT	*entry;
+	int_t		ix;
+	uint16_t	proto;
+
+	if (input->len < sizeof(uint16_t)) {
+		syslog(LOG_WARNING, "[PPP/LCP] bad len: %d in recv Proto-REJ.");
+		return;
+		}
+
+	proto = ntohs(*GET_PPP_HDR(input));
+
+	if (fsm->state != PPP_FSM_OPENED) {
+		return;
+		}
+
+	/* 上位プロトコルを初期化する */
+	for (ix = 0; (entry = protocols[ix]) != NULL; ix ++)
+		if (entry->proto == proto) {
+			(*entry->protrej)();
+			return;
+			}
+
+	syslog(LOG_WARNING, "[PPP/LCP] unexp proto: %d in recv Proto-REJ.", proto);
+	}
+
+/*
+ *  lcp_protrej -- Proto-REJ を受信したときの処理
+ */
+
+static void
+lcp_protrej (void)
+{
+	fsm_protreject(&lcp_fsm);
+	}
+
+/*
+ *  lcp_lowerup -- LCP 下位層を起動する。
+ */
+
+void
+lcp_lowerup (void)
+{
+	fsm_lowerup(&lcp_fsm);
+	}
+
+/*
+ *  lcp_lowerdown -- LCP 下位層を停止する。
+ */
+
+void
+lcp_lowerdown (void)
+{
+	fsm_lowerdown(&lcp_fsm);
+	}
+
+/*
+ *  lcp_open -- LCP のオープ
+ */
+
+void
+lcp_open (uint8_t open_mode)
+{
+	ppp_open_mode = open_mode;	/* オープン時の動作モード	*/
+	fsm_open(&lcp_fsm);
+	}
+
+/*
+ *  lcp_close -- LCP のクローズ
+ */
+
+void
+lcp_close (void)
+{
+	if (ppp_phase != PPP_PHASE_DEAD)
+		ppp_phase = PPP_PHASE_TERMINATE;
+
+	if (ppp_open_mode == PPP_OPEN_PASSIVE && lcp_fsm.state == PPP_FSM_STOPPED) {
+		lcp_fsm.state = PPP_FSM_CLOSED;
+		lcp_finished(&lcp_fsm);
+		}
+	else
+		fsm_close(&lcp_fsm);
+	}
+
+/*
+ *  lcp_sprotrej -- 認識できないプロトコルが送られてきたときの処理
+ */
+
+void
+lcp_sprotrej (T_NET_BUF *input)
+{
+	T_NET_BUF	*output;
+	/*
+	 *  Protocol-Reject を送り返す。
+	 */
+
+	syscall(get_net_buf(&output, input->len + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
+
+	memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+	memcpy(output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR), input->buf, input->len);
+
+	IF_SET_PROTO(output, PPP_LCP);
+	ppp_cp_output(PPP_PROTREJ, ++ lcp_fsm.id, output);
+	}
+
+/*
+ *  lcp_down -- リンク接続を解放する (Phase: Dead に移行する)。
+ */
+
+void
+lcp_down (T_PPP_FSM *fsm)
+{
+
+#if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC
+
+	echo_lowerdown();
+
+#endif	/* of #if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC */
+
+	link_down();
+	}
+
+/*
+ *  lcp_finished -- 下位層を終了する。
+ */
+
+void
+lcp_finished (T_PPP_FSM *fsm)
+{
+	link_terminated();
+	}
+
+#if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC
+
+/*
+ *  recv_echo_rep -- ECHOREP を受信したときの処理
+ */
+
+static void
+recv_echo_rep(T_PPP_FSM *fsm, uint8_t id, T_NET_BUF *input)
+{
+	T_PPP_CP_HDR	*hdr;
+	uint32_t	magic;
+
+ 	hdr = GET_PPP_CP_HDR(input);
+
+ 	/* Magic Number の長さ以下ならエラー */
+ 	if (hdr->len < sizeof(T_PPP_CP_HDR) + sizeof(uint32_t)) {
+		syslog(LOG_WARNING, "[PPP/LCP] bad ECHOREP len: %d.", hdr->len);
+		return;
+		}
+
+	ntoahl(magic, input->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+ 	/* 受信した Magic Number が自分と同じならループしている。*/
+	if ((lcp_local_ack_cfg.options & LCP_CFG_MAGIC) && magic == lcp_local_ack_cfg.magic) {
+		syslog(LOG_WARNING, "[PPP/LCP] ECHOREP looped.");
+		return;
+		}
+
+	echo_pending = 0;
+	}
+
+/*
+ *  echo_timeout -- ECHO REQ/REP のタイムアウト処理
+ */
+
+static void
+echo_timeout (void *arg)
+{
+	if (timer_running) {
+		timer_running = false;
+		send_echo_req((T_PPP_FSM *)arg);
+		}
+	}
+
+/*
+ *  send_echo_req -- ECHO REQ を送信する。
+ */
+
+static void
+send_echo_req (T_PPP_FSM *fsm)
+{
+	T_NET_BUF	*input;
+
+#if LCP_ECHO_FAILS > 0
+
+	if (echo_pending >= LCP_ECHO_FAILS) {
+		syslog(LOG_WARNING, "[PPP/LCP] no reply to ECHOREQ.");
+		lcp_close();
+		echo_pending = 0;
+		}
+
+#endif	/* of #if LCP_ECHO_FAILS > 0 */
+
+	if (fsm->state == PPP_FSM_OPENED) {
+
+		/* ECHOREQ を送信する。*/
+		syscall(get_net_buf(&input, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR) + sizeof(uint32_t)));
+		*(uint32_t*)(input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)) = lcp_local_ack_cfg.magic;
+		IF_SET_PROTO(input, PPP_LCP);
+		ppp_cp_output(PPP_ECHOREQ, echo_number ++, input);
+		echo_pending ++;
+
+		/* タイマーをスタートする。*/
+		timeout((FP)echo_timeout, fsm, LCP_ECHO_INTERVAL);
+		timer_running = true;
+		}
+	}
+
+/*
+ *  echo_lowerup -- ECHO REQ/REP の起動
+ */
+
+static void
+echo_lowerup (void)
+{
+	echo_pending  = 0;
+	echo_number   = 0;
+	timer_running = false;
+
+	send_echo_req(&lcp_fsm);
+	}
+
+/*
+ *  echo_lowerdown -- ECHO REQ/REP の停止
+ */
+
+static void
+echo_lowerdown (void)
+{
+	if (timer_running) {
+		untimeout((FP)echo_timeout, &lcp_fsm);
+		timer_running = false;
+		}
+	}
+
+#endif	/* of #if DEF_LCP_LOCAL_CFGS & LCP_CFG_MAGIC */
+
+#endif	/* fo #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_lcp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_lcp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_lcp.h	(revision 398)
@@ -0,0 +1,151 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * lcp.h - Link Control 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD: src/usr.sbin/pppd/lcp.h,v 1.6.2.1 1999/08/29 15:47:03 peter Exp $
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/lcp.h,v 1.23.2.1 2000/08/19 09:30:04 brian Exp $
+ *
+ *	TODO:
+ */
+
+#ifndef _PPP_LCP_H_
+#define _PPP_LCP_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  LCP 特有の PPP リンク制御 (CP) の制御コード
+ */
+
+#define PPP_PROTREJ		UINT_C(8)	/* Protocol Reject	*/
+#define PPP_ECHOREQ		UINT_C(9)	/* Echo Request		*/
+#define PPP_ECHOREP		UINT_C(10)	/* Echo Reply		*/
+#define PPP_DISCREQ		UINT_C(11)	/* Discard Request	*/
+
+/*
+ *  LCP の構成情報 (CI)
+ */
+
+/*
+ *  CI の型
+ */
+
+#define LCP_CIT_MRU		UINT_C(1)	/* 最大受信量 (Maximum Receive Unit)	*/
+#define LCP_CIT_ACCM		UINT_C(2)	/* Async Control Character Map		*/
+#define LCP_CIT_AUTH		UINT_C(3)	/* 認証プロトコル			*/
+#define LCP_CIT_QUALITY		UINT_C(4)	/* 品質プロトコルは未実装			*/
+#define LCP_CIT_MAGIC		UINT_C(5)	/* マジック番号				*/
+#define LCP_CIT_PCOMP		UINT_C(7)	/* プロトコル部圧縮は実装予定		*/
+#define LCP_CIT_ACCOMP		UINT_C(8)	/* アドレス・制御部圧縮は実装予定		*/
+#define LCP_CIT_FCS_ALTER	UINT_C(9)	/* FCS-Alternatives は未実装		*/
+#define LCP_CIT_SELF_PAD	UINT_C(10)	/* Self-Describing-Padding は未実装	*/
+#define LCP_CIT_CALLBACK	UINT_C(13)	/* Callback は未実装			*/
+#define LCP_CIT_CFRAMES		UINT_C(15)	/* Compound-Frames は未実装		*/
+
+/*
+ *  LCP の構成情報オプション
+ */
+
+typedef struct t_lcp_configs {
+	uint32_t	ACCM;		/* ACCM			*/
+
+#ifdef LCP_CFG_MAGIC
+
+	uint32_t	magic;		/* マジック番号		*/
+
+#endif	/* of #ifdef LCP_CFG_MAGIC */
+
+	uint16_t	MRU;		/* MRU			*/
+	uint16_t	options;	/* オプションフラグ	*/
+	} __attribute__((packed, aligned(2)))T_LCP_CONFIGS;
+
+/*
+ *  変数
+ */
+
+extern T_PPP_FSM	lcp_fsm;
+extern T_PPP_PROTENT	lcp_protent;
+extern T_LCP_CONFIGS	lcp_local_ack_cfg;	/* 相手に許可されたの自構成情報	*/
+extern T_LCP_CONFIGS	lcp_remote_ack_cfg;	/* 相手に許可した構成情報		*/
+
+/*
+ *  関数
+ */
+
+extern void lcp_lowerup (void);
+extern void lcp_lowerdown (void);
+extern void lcp_down (T_PPP_FSM *fsm);
+extern void lcp_finished (T_PPP_FSM *fsm);
+extern void lcp_open (uint8_t open_mode);
+extern void lcp_close (void);
+extern void lcp_sprotrej (T_NET_BUF *data);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _PPP_LCP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_modem.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_modem.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_modem.c	(revision 398)
@@ -0,0 +1,306 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  PPP モデム制御
+ */
+
+#include <string.h>
+
+#include <t_services.h>
+#include "kernel_id.h"
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_hdlc.h>
+#include <net/ppp_modem.h>
+#include <net/ppp_lcp.h>
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  全域変数
+ */
+
+uint8_t	modem_state = PPP_MODEM_DOWN;	/* モデムの状態		*/
+
+/*
+ *  モデム入力文字列
+ */
+
+#define MODEM_RCODE_OK		0
+#define MODEM_RCODE_CONNECT	1
+#define MODEM_RCODE_RING	2
+#define MODEM_RCODE_NO_CARRIER	3
+#define MODEM_RCODE_ERROR	4
+#define MODEM_RCODE_NO_DIALTONE	5
+#define MODEM_RCODE_BUSY	6
+#define MODEM_RCODE_DELAYED	7
+
+/*
+ *  変数
+ */
+
+static uint8_t *modem_rcode[] = {
+	"OK",
+	"CONNECT",
+	"RING",
+	"NO CARRIER",
+	"ERROR",
+	"NO DIALTONE",
+	"BUSY",
+	"DELAYED"
+	};
+
+static int_t dial_retry;
+
+/*
+ *  関数
+ */
+
+static void do_dial (void);
+static void modem_putstr (uint8_t *str);
+static void modem_wait (uint8_t *line);
+static void modem_putline (uint8_t *line);
+
+/*
+ *  modem_getline -- モデム行入力
+ */
+
+T_NET_BUF *
+modem_getline (T_NET_BUF *nbuf, uint16_t size)
+{
+	uint8_t *buf;
+
+	buf = nbuf->buf;
+	size --;			/* '\0' の分 */
+	while (size > 0 && (*buf = HDLC_raw_getoctet()) != '\r') {
+		buf  ++;
+		size --;
+		}
+	*buf = '\0';
+	HDLC_raw_getoctet();		/* \n を読み飛ばす。*/
+	nbuf->len = buf - nbuf->buf;
+	return nbuf;
+	}
+
+/*
+ *  モデム制御
+ *
+ *	戻り値: モデムからのリザルトコード
+ */
+
+int_t
+modem_cntl (T_NET_BUF *input)
+{
+	int_t	code;
+
+	code = sizeof(modem_rcode) / sizeof(uint8_t*) - 1;
+	while (strcmp(modem_rcode[code], input->buf) != 0) {
+		if (code == 0)
+			return modem_state;
+		code --;
+		}
+
+	switch (modem_state) {
+
+	case PPP_MODEM_UP:
+		if (code == MODEM_RCODE_RING)
+			modem_state = PPP_MODEM_RING;
+		break;
+
+	case PPP_MODEM_DIAL:
+		if (code == MODEM_RCODE_CONNECT) {
+			syslog(LOG_NOTICE, "[MODEM] up.");
+			modem_state = PPP_MODEM_CONNECT;
+			lcp_open(PPP_OPEN_ACTIVE);
+			sig_sem(SEM_MODEM_READY);
+			}
+		else {
+			syslog(LOG_NOTICE, "[MODEM] dial failed '%s'.", modem_rcode[code]);
+			if (-- dial_retry == 0) {
+				syslog(LOG_WARNING, "[MODEM] dial failed %d times.", MODEM_CFG_RETRY_CNT);
+				modem_state = PPP_MODEM_UP;
+				}
+			else {
+				syscall(dly_tsk(MODEM_CFG_RETRY_WAIT));
+				do_dial();
+				}
+			}
+		break;
+
+	case PPP_MODEM_RING:
+		if (code == MODEM_RCODE_CONNECT) {
+			syslog(LOG_NOTICE, "[MODEM] up.");
+			modem_state = PPP_MODEM_CONNECT;
+			lcp_open(PPP_OPEN_PASSIVE);
+			}
+		else
+			modem_state = PPP_MODEM_UP;
+		break;
+
+	default:
+		if (code == MODEM_RCODE_NO_CARRIER) {
+			if (lcp_fsm.state == PPP_FSM_OPENED)
+				lcp_close();
+			syslog(LOG_NOTICE, "[MODEM] down.");
+			modem_state = PPP_MODEM_UP;
+			}
+		break;
+
+		}
+
+	return code;
+	}
+
+/*
+ *  init_modem -- モデムを初期化する。
+ */
+
+void
+init_modem (void)
+{
+	modem_putline("AT");
+
+#ifdef MODEM_CFG_INIT
+
+	modem_putline(MODEM_CFG_INIT);
+
+#endif	/* of #ifdef MODEM_CFG_INIT */
+
+	modem_state = PPP_MODEM_UP;
+	}
+
+/*
+ *  wait_modem -- 接続完了まで待つ。
+ *
+ *	戻り値: 接続に失敗したら E_OBJ を返す。
+ */
+
+ER
+wait_modem (void)
+{
+	ER error = E_OK;
+
+	if (modem_state == PPP_MODEM_UP) {
+		dial();
+		}
+
+	if (modem_state != PPP_MODEM_CONNECT) {
+		/* 接続完了まで待つ。*/
+		wai_sem(SEM_MODEM_READY);
+		if (modem_state != PPP_MODEM_CONNECT)
+			error = E_OBJ;
+		}
+
+	return error;
+	}
+
+/*
+ *  dial -- ダイヤルする。リトライ回数をセットする。
+ */
+
+void
+dial (void)
+{
+	do_dial();
+	dial_retry = MODEM_CFG_RETRY_CNT;
+	modem_state = PPP_MODEM_DIAL;
+	}
+
+/*
+ *  do_dial -- ダイヤルする。dial() の下請け関数
+ */
+
+static void
+do_dial (void)
+{
+	syslog(LOG_NOTICE, "[MODEM] dial: %s.", MODEM_CFG_PHONE_NUMBER);
+	modem_putstr(MODEM_CFG_DIAL);
+	modem_putstr(MODEM_CFG_PHONE_NUMBER);
+	modem_putstr("\r");
+	}
+
+/*
+ *  modem_putstr -- モデム文字列出力
+ */
+
+static void
+modem_putstr (uint8_t *str)
+{
+	while (*str)
+		HDLC_raw_putoctet(*str ++);
+	}
+
+/*
+ *  modem_wait -- モデムから文字列を待つ
+ */
+
+static void
+modem_wait (uint8_t *line)
+{
+	int_t ch, state, len = strlen(line);
+
+	state = len;
+	while (state != 0) {
+		ch = HDLC_raw_getoctet();
+		if (ch != line[len - state])
+			state = len;
+		if (ch == line[len - state])
+			state --;
+		}
+	}
+
+/*
+ *  modem_putline -- モデム行出力
+ */
+
+static void
+modem_putline (uint8_t *line)
+{
+	modem_putstr(line);
+	modem_putstr("\r");
+	modem_wait("OK\r\n");
+	}
+
+#endif	/* fo #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_modem.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_modem.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_modem.h	(revision 398)
@@ -0,0 +1,80 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _PPP_MODEM_H_
+#define _PPP_MODEM_H_
+
+#ifdef SUPPORT_PPP
+
+#ifdef PPP_CFG_MODEM
+
+/*
+ *  モデムの状態
+ */
+
+#define PPP_MODEM_CONNECT	UINT_C(0)
+#define PPP_MODEM_DISCONN	UINT_C(1)
+#define PPP_MODEM_RING		UINT_C(2)
+#define PPP_MODEM_DIAL		UINT_C(3)
+#define PPP_MODEM_UP		UINT_C(4)
+#define PPP_MODEM_DOWN		UINT_C(5)
+
+/*
+ *  全域変数
+ */
+
+extern uint8_t modem_state;	/* モデムの状態		*/
+
+/*
+ *  関数
+ */
+
+extern T_NET_BUF *modem_getline (T_NET_BUF *nbuf, uint16_t size);
+extern int modem_cntl (T_NET_BUF *input);
+extern void init_modem (void);
+extern void dial (void);
+extern ER wait_modem (void);
+
+#else	/* of #ifdef PPP_CFG_MODEM */
+
+/*
+ *  関数
+ */
+
+#define init_modem
+
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _PPP_MODEM_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_upap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_upap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_upap.c	(revision 398)
@@ -0,0 +1,608 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * upap.c - User/Password Authentication Protocol.
+ *
+ * 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *			PPP PAP Module
+ *
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993-94, Internet Initiative Japan, Inc.
+ *		     All rights reserverd.
+ *
+ * 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 Internet Initiative Japan, Inc.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/pap.c,v 1.42.2.1 2000/08/19 09:30:05 brian Exp $
+ *
+ *	TODO:
+ */
+
+#include <string.h>
+
+#include <s_services.h>
+#include <t_services.h>
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_hdlc.h>
+#include <net/ppp_auth.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_lcp.h>
+#include <net/ppp_upap.h>
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  関数
+ */
+
+static void upap_init (void);
+static void upap_input (T_NET_BUF *input);
+static void upap_protrej (void);
+static void upap_lowerup (void);
+static void upap_lowerdown (void);
+static bool_t compare (uint8_t *rstr, uint8_t *lstr, uint8_t rlen);
+
+#ifdef AUTH_CFG_CLIENT
+
+static void upap_sauthreq (void);
+static void upap_rauthack (void);
+static void upap_rauthnak (void);
+
+#if defined(DEF_PAP_TIMEOUT)
+
+static void upap_timeout(void *arg);
+
+#endif	/* of #if defined(DEF_PAP_TIMEOUT) */
+
+#endif	/* of #ifdef AUTH_CFG_CLIENT */
+
+#ifdef AUTH_CFG_SERVER
+
+static void upap_rauthreq (T_NET_BUF *input);
+static void upap_sresp    (uint8_t code, uint8_t id);
+
+#if defined(DEF_PAP_REQTIME)
+
+static void upap_reqtimeout(void *arg);
+
+#endif	/* of #if defined(DEF_PAP_REQTIME) */
+
+#endif	/* of #ifdef AUTH_CFG_SERVER */
+
+/*
+ *  全域変数
+ */
+
+T_PPP_PROTENT pap_protent = {
+	PPP_PAP,
+	upap_init,			/* 初期化			*/
+	upap_input,			/* 入力				*/
+	upap_protrej,			/* Proto-REJ 受信処理		*/
+	upap_lowerup,			/* 下位層を起動する		*/
+	upap_lowerdown,			/* 下位層を停止する		*/
+	NULL,				/* オープンする			*/
+	NULL,				/* クローズする			*/
+	NULL,				/* データ入力			*/
+	};
+
+/*
+ *  変数
+ */
+
+#ifdef AUTH_CFG_CLIENT
+
+static uint8_t client_state;
+static uint8_t client_cp_id;
+
+#if defined(DEF_PAP_TIMEOUT)
+
+static uint8_t client_rexmt = 0;
+
+#endif	/* of #if defined(DEF_PAP_TIMEOUT) */
+
+#endif	/* of #ifdef AUTH_CFG_CLIENT */
+
+#ifdef AUTH_CFG_SERVER
+
+static uint8_t server_state;
+
+#endif	/* of #ifdef AUTH_CFG_SERVER */
+
+/*
+ *  upap_init -- UPAP モジュールの初期化
+ */
+
+static void
+upap_init (void)
+{
+#ifdef AUTH_CFG_CLIENT
+
+	client_cp_id = 0;
+	client_state = PAP_CS_INIT;
+
+#endif	/* of #ifdef AUTH_CFG_CLIENT */
+
+#ifdef AUTH_CFG_SERVER
+
+	server_state = PAP_SS_INIT;
+
+#endif	/* of #ifdef AUTH_CFG_SERVER */
+	}
+
+/*
+ *  upap_input -- UPAP 入力
+ */
+
+static void
+upap_input (T_NET_BUF *input)
+{
+	T_PPP_CP_HDR	*hdr;
+
+	NET_COUNT_PPP_PAP(net_count_ppp_upap_in_octets,  input->len);
+	NET_COUNT_PPP_PAP(net_count_ppp_upap_in_packets, 1);
+
+ 	/* PPP リンク制御 (CP) ヘッダより短ければエラー */
+ 	if (input->len < (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR))) {
+ 		syslog(LOG_WARNING, "[PPP/PAP] short hdr: %d.", input->len);
+ 		return;
+ 		}
+
+ 	hdr = GET_PPP_CP_HDR(input);
+
+ 	/* ヘッダの長さと入力データサイズが一致しなければエラー */
+ 	if (hdr->len != input->len - sizeof(T_PPP_HDR)) {
+ 		syslog(LOG_WARNING, "[PPP/PAP] bad len: %d.", hdr->len);
+ 		return;
+ 		}
+ 
+ 	/*
+ 	 *  制御コードにより適当な関数を呼出す
+ 	 */
+
+	switch (hdr->code) {
+
+#ifdef AUTH_CFG_CLIENT
+
+	case PAP_AUTHACK:
+		upap_rauthack();
+		break;
+
+	case PAP_AUTHNAK:
+		upap_rauthnak();
+		break;
+
+#endif	/* of #ifdef AUTH_CFG_CLIENT */
+
+#ifdef AUTH_CFG_SERVER
+
+	case PAP_AUTHREQ:
+		upap_rauthreq(input);
+		break;
+
+#endif	/* of #ifdef AUTH_CFG_SERVER */
+
+		}
+	}
+
+/*
+ *  upap_protrej -- Proto-REJ を受信したときの処理
+ */
+
+static void
+upap_protrej (void)
+{
+#ifdef AUTH_CFG_CLIENT
+
+	if (client_state == PAP_CS_AUTHREQ)
+	 	syslog(LOG_WARNING, "[PPP/PAP] proto-rej recved.");
+
+#endif	/* of #ifdef AUTH_CFG_CLIENT */
+
+#ifdef AUTH_CFG_SERVER
+
+	if (server_state == PAP_SS_LISTEN) {
+	 	syslog(LOG_WARNING, "[PPP/PAP] proto-rej recved.");
+		lcp_close();
+		}
+
+#endif	/* of #ifdef AUTH_CFG_SERVER */
+
+	upap_lowerdown();
+	}
+
+/*
+ *  upap_lowerup -- UPAP 下位層を起動する。
+ */
+
+static void
+upap_lowerup (void)
+{
+#ifdef AUTH_CFG_CLIENT
+
+	if (client_state == PAP_CS_INIT)
+		client_state = PAP_CS_CLOSED;
+	else if (client_state == PAP_CS_PENDING)
+		upap_sauthreq();
+
+#endif	/* of #ifdef AUTH_CFG_CLIENT */
+
+#ifdef AUTH_CFG_SERVER
+
+	if (server_state == PAP_SS_INIT)
+		server_state = PAP_SS_CLOSED;
+	else if (server_state == PAP_SS_PENDING) {
+		server_state = PAP_SS_LISTEN;
+
+#if defined(DEF_PAP_REQTIME)
+
+		timeout((FP)upap_reqtimeout, NULL, DEF_PAP_REQTIME);
+
+#endif	/* of #if defined(DEF_PAP_REQTIME) */
+
+		}
+
+#endif	/* of #ifdef AUTH_CFG_SERVER */
+	}
+
+/*
+ *  upap_lowerdown -- UPAP 下位層を停止する。
+ */
+
+static void
+upap_lowerdown (void)
+{
+#ifdef AUTH_CFG_CLIENT
+
+#if defined(DEF_PAP_TIMEOUT)
+
+	if (client_state == PAP_CS_AUTHREQ)
+		untimeout((FP)upap_timeout, NULL);
+
+#endif	/* of #if defined(DEF_PAP_TIMEOUT) */
+
+	client_state = PAP_CS_INIT;
+
+#endif	/* of #ifdef AUTH_CFG_CLIENT */
+
+#ifdef AUTH_CFG_SERVER
+
+#if defined(DEF_PAP_REQTIME)
+
+	if (server_state == PAP_SS_LISTEN)
+		untimeout((FP)upap_reqtimeout, NULL);
+
+#endif	/* of #if defined(DEF_PAP_REQTIME) */
+
+	server_state = PAP_SS_INIT;
+
+#endif	/* of #ifdef AUTH_CFG_SERVER */
+	}
+#ifdef AUTH_CFG_CLIENT
+
+/*
+ *  クライアントモードで PAP 認証を開始する。
+ */
+
+void
+upap_auth_client (void)
+{
+#if defined(DEF_PAP_TIMEOUT)
+
+	client_rexmt = 0;
+
+#endif	/* of #if defined(DEF_PAP_TIMEOUT) */
+
+	if (client_state == PAP_CS_INIT || client_state == PAP_CS_PENDING) {
+		client_state = PAP_CS_PENDING;
+		return;
+		}
+
+	upap_sauthreq();
+	}
+
+/*
+ *  upap_rauthack -- 認証 ACK 処理
+ */
+
+static void
+upap_rauthack (void)
+{
+	if (client_state == PAP_CS_AUTHREQ) {
+		client_state = PAP_CS_OPEN;
+		network_phase();
+		}
+	}
+
+/*
+ *  upap_rauthnak -- 認証 NAK 処理
+ */
+
+static void
+upap_rauthnak (void)
+{
+ 	syslog(LOG_WARNING, "[PPP/PAP] auth-req NAKed.");
+	client_state = PAP_CS_BADAUTH;
+	}
+
+/*
+ *  upap_sauthreq -- 認証要求処理
+ */
+
+static void
+upap_sauthreq (void)
+{
+	T_NET_BUF	*output;
+	uint8_t		*data;
+
+	syscall(get_net_buf(&output, sizeof(T_PPP_HDR)        + sizeof(T_PPP_CP_HDR)
+	                           + sizeof(AUTH_REMOTE_USER) + sizeof(AUTH_REMOTE_PASSWD)));
+
+	data = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+
+	/* ユーザ名を設定する。*/
+	*data = sizeof(AUTH_REMOTE_USER) - 1;
+	strcpy(data + 1, AUTH_REMOTE_USER);
+
+	/* パスワードを設定する。*/
+	*(data + sizeof(AUTH_REMOTE_USER)) = sizeof(AUTH_REMOTE_PASSWD) - 1;
+	strcpy(data + sizeof(AUTH_REMOTE_USER) + 1, AUTH_REMOTE_PASSWD);
+
+	/* 送信する */
+	IF_SET_PROTO(output, PPP_PAP);
+	ppp_cp_output(PAP_AUTHREQ, ++ client_cp_id, output);
+
+#if defined(DEF_PAP_TIMEOUT)
+
+	timeout((FP)upap_timeout, NULL, DEF_PAP_TIMEOUT);
+	client_rexmt ++;
+
+#endif	/* of #if defined(DEF_PAP_TIMEOUT) */
+
+	client_state = PAP_CS_AUTHREQ;
+	}
+
+#if defined(DEF_PAP_TIMEOUT)
+
+/*
+ *  upap_timeout -- タイムアウト処理
+ */
+
+static void
+upap_timeout (void *arg)
+{
+	if (client_state != PAP_CS_AUTHREQ)
+		return;
+
+	if (client_rexmt >= MAX_PAP_REXMT) {
+ 		syslog(LOG_WARNING, "[PPP/PAP] no reply auth-req.");
+		client_state = PAP_CS_BADAUTH;
+		return;
+		}
+
+	upap_sauthreq();
+	}
+
+#endif	/* of #if defined(DEF_PAP_TIMEOUT) */
+
+#endif	/* of #ifdef AUTH_CFG_CLIENT */
+
+#ifdef AUTH_CFG_SERVER
+
+/*
+ *  サーバモードで PAP 認証を開始する。
+ */
+
+void
+upap_auth_server (void)
+{
+	if (server_state == PAP_SS_INIT || server_state == PAP_SS_PENDING) {
+		server_state = PAP_SS_PENDING;
+		return;
+		}
+
+	server_state = PAP_SS_LISTEN;
+
+#if defined(DEF_PAP_REQTIME)
+
+	timeout((FP)upap_reqtimeout, NULL, DEF_PAP_REQTIME);
+
+#endif	/* of #if defined(DEF_PAP_REQTIME) */
+	}
+
+/*
+ *  upap_rauthreq -- 認証要求応答処理
+ */
+
+static void
+upap_rauthreq (T_NET_BUF *input)
+{
+	int16_t	cplen;
+	uint8_t	*data, *user, ulen, plen, code, id;
+
+	if (server_state < PAP_SS_LISTEN)
+		return;
+
+	/*
+	 *  再要求があったときの処理
+	 */
+	id = GET_PPP_CP_HDR(input)->id;
+	if (server_state == PAP_SS_OPEN) {
+		upap_sresp(PAP_AUTHACK, id);
+		return;
+		}
+
+	if (server_state == PAP_SS_BADAUTH) {
+		upap_sresp(PAP_AUTHNAK, id);
+		return;
+		}
+
+	cplen = GET_PPP_CP_HDR(input)->len;
+	data  = input->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+
+	/*
+	 *  ユーザ名を特定する。
+	 */
+	ulen  = *data;
+	if (cplen < sizeof(T_PPP_CP_HDR) + ulen + sizeof(uint8_t)) {
+ 		syslog(LOG_WARNING, "[PPP/PAP] bad req len: %d.", cplen);
+ 		return;
+		}
+	user = ++ data;
+	data += ulen;
+
+	/*
+	 *  パスワードを特定する。
+	 */
+	plen  = *data;
+	if (cplen < sizeof(T_PPP_CP_HDR) + ulen + plen + sizeof(uint8_t) * 2) {
+ 		syslog(LOG_WARNING, "[PPP/PAP] bad req len: %d.", cplen);
+ 		return;
+		}
+
+	/*
+	 *  ユーザ名とパスワードをチェックする。
+	 */
+	if (compare(user,     AUTH_LOCAL_USER,   ulen) &&
+	    compare(data + 1, AUTH_LOCAL_PASSWD, plen))
+		code = PAP_AUTHACK;
+	else
+		code = PAP_AUTHNAK;
+
+	upap_sresp(code, id);
+
+	if (code == PAP_AUTHACK) {
+		network_phase();
+		server_state = PAP_SS_OPEN;
+		}
+	else {
+		lcp_close();
+		server_state = PAP_SS_BADAUTH;
+		}
+
+#if defined(DEF_PAP_REQTIME)
+
+	untimeout((FP)upap_reqtimeout, NULL);
+
+#endif	/* of #if defined(DEF_PAP_REQTIME) */
+	}
+
+/*
+ *  upap_sresp -- 応答を返す。
+ */
+
+static void
+upap_sresp (uint8_t code, uint8_t id)
+{
+	T_NET_BUF *output;
+
+	/* 送信する */
+	syscall(get_net_buf(&output, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR)));
+	IF_SET_PROTO(output, PPP_PAP);
+	ppp_cp_output(code, id, output);
+	}
+
+/*
+ *  compare -- ユーザ名とパスワードの比較
+ */
+
+static bool_t
+compare (uint8_t *rstr, uint8_t *lstr, uint8_t rlen)
+{
+	while (rlen -- > 0) {
+		if (*rstr != *lstr)
+			return false;
+		rstr ++;
+		lstr ++;
+		}
+	return *lstr ? false : true;
+	}
+
+#if defined(DEF_PAP_REQTIME)
+
+/*
+ *  upap_reqtimeout -- 要求タイムアウト処理
+ */
+
+static void
+upap_reqtimeout (void *arg)
+{
+	if (server_state == PAP_SS_LISTEN) {
+		lcp_close();
+		server_state = PAP_SS_BADAUTH;
+		}
+	}
+
+#endif	/* of #if defined(DEF_PAP_REQTIME) */
+
+#endif	/* of #ifdef AUTH_CFG_SERVER */
+
+#endif	/* fo #ifdef SUPPORT_PPP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_upap.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_upap.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_upap.h	(revision 398)
@@ -0,0 +1,127 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * upap.h - User/Password Authentication 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD: src/usr.sbin/pppd/upap.h,v 1.6.2.1 1999/08/29 15:47:10 peter Exp $
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/pap.h,v 1.11 1999/08/28 01:18:37 peter Exp $
+ *
+ *	TODO:
+ */
+
+#ifndef _PPP_UPAP_H_
+#define _PPP_UPAP_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  PAP の制御コード
+ */
+
+#define PAP_AUTHREQ		UINT_C(1)	/* 認証要求	*/
+#define PAP_AUTHACK		UINT_C(2)	/* 認証 ACK	*/
+#define PAP_AUTHNAK		UINT_C(3)	/* 認証 NAK	*/
+
+/*
+ *  クライアントの状態
+ */
+
+#define PAP_CS_INIT		UINT_C(0)	/* 未接続		*/
+#define PAP_CS_CLOSED		UINT_C(1)	/* 接続、未認証		*/
+#define PAP_CS_PENDING		UINT_C(2)	/* 未接続、認証		*/
+#define PAP_CS_AUTHREQ		UINT_C(3)	/* 認証要求送信済み	*/
+#define PAP_CS_OPEN		UINT_C(4)	/* ACK 受信		*/
+#define PAP_CS_BADAUTH		UINT_C(5)	/* NAK 受信		*/
+
+/*
+ *  サーバの状態
+ */
+
+#define PAP_SS_INIT		UINT_C(0)	/* 未接続		*/
+#define PAP_SS_CLOSED		UINT_C(1)	/* 接続、未認証		*/
+#define PAP_SS_PENDING		UINT_C(2)	/* 未接続、認証		*/
+#define PAP_SS_LISTEN		UINT_C(3)	/* 認証要求受信待ち	*/
+#define PAP_SS_OPEN		UINT_C(4)	/* ACK 送信		*/
+#define PAP_SS_BADAUTH		UINT_C(5)	/* NAK 送信		*/
+
+/*
+ *  変数
+ */
+
+extern T_PPP_PROTENT	pap_protent;
+
+/*
+ *  関数
+ */
+
+extern void upap_auth_client (void);
+extern void upap_auth_server (void);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _PPP_UPAP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/ppp_var.h	(revision 398)
@@ -0,0 +1,116 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * 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 Internet Initiative Japan.  The name of the
+ * IIJ 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.
+ */
+
+#ifndef PPP_VAR_H_
+#define PPP_VAR_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  PPP プロトコルエントリ構造体
+ */
+
+typedef struct t_ppp_protent {
+	uint16_t	proto;			/* プロトコル番号	*/
+	void		(*init)		(void);	/* 初期化関数		*/
+	void		(*input)	(T_NET_BUF *data);
+						/* 入力関数		*/
+	void		(*protrej)	(void);	/* Ptoto-REJ 受信処理	*/
+	void		(*lowerup)	(void);	/* 下位層を起動する。	*/
+	void		(*lowerdown)	(void);	/* 下位層を停止する。	*/
+	void		(*open)		(void);	/* オープンする。	*/
+	void		(*close)	(void);	/* クローズする。	*/
+	void		(*datainput)	(T_NET_BUF *data);
+					/* データ入力関数	*/
+	} T_PPP_PROTENT;
+
+#define T_PPP_PROTENT_DEFINED
+
+/*
+ *  変数
+ */
+
+extern T_PPP_PROTENT	*protocols[];	/* プロトコル表			*/
+extern uint8_t		ppp_phase;	/* リンクの状態			*/
+
+/*
+ *  関数
+ */
+
+extern void ppp_cp_output(uint8_t code, uint8_t id, T_NET_BUF *data);
+
+/*
+ *  PPP 処理タスク
+ */
+
+extern void	ppp_input_task(intptr_t exinf);
+extern void	ppp_output_task(intptr_t exinf);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef PPP_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/route.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/route.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/route.h	(revision 398)
@@ -0,0 +1,80 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1980, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)route.h	8.3 (Berkeley) 4/19/94
+ * $FreeBSD: src/sys/net/route.h,v 1.28.2.2 1999/09/15 08:38:05 ru Exp $
+ */
+
+#ifndef _ROUTE_H_
+#define _ROUTE_H_
+
+/*
+ * TINET 1.1 との互換性確保
+ */
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#endif	/* of #ifndef _ROUTE_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/tinet.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/tinet.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/net/tinet.h	(revision 398)
@@ -0,0 +1,47 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TINET_H_
+#define _TINET_H_
+
+#if !defined(TOPPERS_MACRO_ONLY) && !defined(_MACRO_ONLY)
+
+/*
+ *  TINET 独自関数
+ */
+
+extern char *mac2str (char *buf, uint8_t *macaddr);
+
+#endif /* #if !defined(TOPPERS_MACRO_ONLY) && !defined(_MACRO_ONLY) */
+
+#endif	/* of #ifndef _TINET_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/Makefile.netapp
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/Makefile.netapp	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/Makefile.netapp	(revision 398)
@@ -0,0 +1,399 @@
+#
+#   TINET (TCP/IP Protocol Stack)
+#  
+#   Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+#                    Tomakomai National College of Technology, JAPAN
+# 
+#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+#   によって公表されている GNU General Public License の Version 2 に記
+#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+#   利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次の条件を満たすこと．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+# 
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+#  
+#   @(#) $Id$
+# 
+
+#
+#  サンプルのネットワーク応用プログラムに関する定義
+#
+
+#
+#  カーネルの識別
+#
+ifdef SRCLANG
+	TARGET_KERNEL = ASP
+	TINET_CDEFS := $(TINET_CDEFS) -DTARGET_KERNEL_ASP
+else
+	TARGET_KERNEL = JSP
+	TINET_CDEFS := $(TINET_CDEFS) -DTARGET_KERNEL_JSP
+endif
+
+#  応用プログラム
+
+TINET_ROOT = $(SRCDIR)/tinet
+NETAPP_DIRS = $(TINET_ROOT)/netapp
+NETAPP_COBJS := $(NETAPP_COBJS) netapp_subr.o
+
+ifeq ($(USE_LCD),true)
+
+	NETAPP_COBJS := $(NETAPP_COBJS) lcd.o
+
+ifeq ($(TARGET_KERNEL),ASP)
+	NETAPP_COBJS := $(NETAPP_COBJS) target_lcd.o sc1602.o
+endif
+
+ifeq ($(TARGET_KERNEL),JSP)
+	NETAPP_COBJS := $(NETAPP_COBJS) hw_lcd.o sc1602.o
+endif
+
+endif
+
+#  トランスポート層の選択
+
+#SUPPORT_TCP = false
+#SUPPORT_UDP = false
+
+# 
+#  共通クライアント・サーバプログラムの設定
+# 
+
+ifeq ($(USE_WWW4_SRV),true)
+	USE_WWW_SRV = true
+	CDEFS := $(CDEFS) -DUSE_WWW4_SRV
+endif
+
+ifeq ($(USE_WWW_SRV),true)
+
+	SUPPORT_TCP = true
+	USE_NETAPP_SUBR = true
+	CDEFS := $(CDEFS) -DUSE_WWW_SRV
+	NETAPP_COBJS := $(NETAPP_COBJS) wwws.o
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/wwws.cfg
+
+endif
+
+ifeq ($(USE_TCP4_ECHO_SRV),true)
+	TCP_ECHO_SRV = tcp_echo_srv1
+	CDEFS := $(CDEFS) -DUSE_TCP4_ECHO_SRV
+endif
+
+ifeq ($(TCP_ECHO_SRV),tcp_echo_srv1)		# 送受信タスク同一型
+
+	SUPPORT_TCP = true
+	USE_NETAPP_SUBR = true
+	CDEFS := $(CDEFS) -DUSE_TCP_ECHO_SRV1
+	NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_srv1.o
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/tcp_echo_srv1.cfg
+
+	ifeq ($(USE_TCP_NON_BLOCKING),true)
+		NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_srv1_nblk.o
+	endif
+
+	ifeq ($(USE_TCP_EXTENTIONS),true)
+		NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_srv1_ext.o
+	endif
+
+endif
+
+ifeq ($(TCP_ECHO_SRV),tcp_echo_srv2)		# 送受信タスク分離型
+	SUPPORT_TCP = true
+	USE_NETAPP_SUBR = true
+	CDEFS := $(CDEFS) -DUSE_TCP_ECHO_SRV2
+	NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_srv2.o
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/tcp_echo_srv2.cfg
+endif
+
+ifeq ($(USE_UDP4_ECHO_SRV),true)
+	USE_UDP_ECHO_SRV = true
+endif
+
+ifeq ($(USE_UDP_ECHO_SRV),true)
+
+	CDEFS := $(CDEFS) -DUSE_UDP_ECHO_SRV
+
+	ifeq ($(SUPPORT_INET6),true)
+		SUPPORT_UDP = true
+		USE_NETAPP_SUBR = true
+		CDEFS := $(CDEFS) -DUSE_UDP6_ECHO_SRV_TSK
+		NETAPP_COBJS := $(NETAPP_COBJS) udp6_echo_srv.o
+		NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp6_echo_srv.cfg
+
+		ifeq ($(SUPPORT_INET4),true)
+			ifeq ($(USE_UDP4_ECHO_SRV),true)
+				CDEFS := $(CDEFS) -DUSE_UDP4_ECHO_SRV_TSK
+				NETAPP_COBJS := $(NETAPP_COBJS) udp4_echo_srv.o
+				NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp4_echo_srv.cfg
+			endif
+		endif
+	else
+		ifeq ($(SUPPORT_INET4),true)
+			SUPPORT_UDP = true
+			USE_NETAPP_SUBR = true
+			CDEFS := $(CDEFS) -DUSE_UDP4_ECHO_SRV_TSK
+			NETAPP_COBJS := $(NETAPP_COBJS) udp4_echo_srv.o
+			NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp4_echo_srv.cfg
+		endif
+	endif
+endif
+
+
+ifeq ($(USE_TCP4_ECHO_CLI),true)
+	USE_TCP_ECHO_CLI = true
+	CDEFS := $(CDEFS) -DUSE_TCP4_ECHO_CLI
+endif
+
+ifeq ($(USE_TCP_ECHO_CLI),true)
+	SUPPORT_TCP = true
+	USE_NETAPP_SUBR = true
+	CDEFS := $(CDEFS) -DUSE_TCP_ECHO_CLI
+	NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_cli.o tcp_echo_cli_snd.o tcp_echo_cli_rcv.o
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/tcp_echo_cli.cfg
+endif
+
+ifeq ($(USE_UDP4_ECHO_CLI),true)
+	USE_UDP_ECHO_CLI = true
+endif
+
+ifeq ($(USE_UDP_ECHO_CLI),true)
+
+	CDEFS := $(CDEFS) -DUSE_UDP_ECHO_CLI
+
+	ifeq ($(SUPPORT_INET6),true)
+		SUPPORT_UDP = true
+		USE_NETAPP_SUBR = true
+		CDEFS := $(CDEFS) -DUSE_UDP6_ECHO_CLI_TSK
+		NETAPP_COBJS := $(NETAPP_COBJS) udp6_echo_cli.o
+		NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp6_echo_cli.cfg
+
+		ifeq ($(SUPPORT_INET4),true)
+			ifeq ($(USE_UDP4_ECHO_CLI),true)
+				CDEFS := $(CDEFS) -DUSE_UDP4_ECHO_CLI_TSK
+				NETAPP_COBJS := $(NETAPP_COBJS) udp4_echo_cli.o
+				NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp4_echo_cli.cfg
+			endif
+		endif
+		else
+		ifeq ($(SUPPORT_INET4),true)
+			SUPPORT_UDP = true
+			USE_NETAPP_SUBR = true
+			CDEFS := $(CDEFS) -DUSE_UDP4_ECHO_CLI_TSK
+			NETAPP_COBJS := $(NETAPP_COBJS) udp4_echo_cli.o
+			NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp4_echo_cli.cfg
+		endif
+
+	endif
+endif
+
+ifeq ($(USE_TCP_DISCARD_SRV),true)
+	SUPPORT_TCP = true
+	USE_NETAPP_SUBR = true
+	CDEFS := $(CDEFS) -DUSE_TCP_DISCARD_SRV
+	NETAPP_COBJS := $(NETAPP_COBJS) tcp_discard_srv.o
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/tcp_discard_srv.cfg
+endif
+
+ifeq ($(USE_TCP_DISCARD_CLI),true)
+	SUPPORT_TCP = true
+	USE_NETAPP_SUBR = true
+	CDEFS := $(CDEFS) -DUSE_TCP_DISCARD_CLI
+	NETAPP_COBJS := $(NETAPP_COBJS) tcp_discard_cli.o
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/tcp_discard_cli.cfg
+endif
+
+ifeq ($(USE_UDP_DISCARD_CLI),true)
+	SUPPORT_UDP = true
+	USE_NETAPP_SUBR = true
+	CDEFS := $(CDEFS) -DUSE_UDP_DISCARD_CLI
+	NETAPP_COBJS := $(NETAPP_COBJS) udp_discard_cli.o
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp_discard_cli.cfg
+endif
+
+ifeq ($(USE_NET_CONS),true)
+	ifeq ($(TCP_CFG_NON_BLOCKING),true)
+		SUPPORT_TCP = true
+		USE_DBG_CONS = true
+		USE_NETAPP_SUBR = true
+		CDEFS := $(CDEFS) -DUSE_NET_CONS
+		NETAPP_COBJS := $(NETAPP_COBJS) net_cons.o
+		NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/net_cons.cfg
+	endif
+endif
+
+ifeq ($(USE_DBG_CONS),true)
+	USE_NETAPP_SUBR = true
+	CDEFS := $(CDEFS) -DUSE_DBG_CONS
+	NETAPP_COBJS := $(NETAPP_COBJS) dbg_cons.o 
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/dbg_cons.cfg
+	ifeq ($(USE_DBG_CONS_PARSER),true)
+		CDEFS := $(CDEFS) -DUSE_DBG_CONS_PARSER
+	endif
+	ifeq ($(USE_DBG_CONS_EXTRA_PARSE),true)
+		CDEFS := $(CDEFS) -DUSE_DBG_CONS_EXTRA_PARSE
+	endif
+endif
+
+ifeq ($(USE_PING),true)
+	USE_NETAPP_SUBR = true
+	CDEFS := $(CDEFS) -DUSE_PING
+	ifeq ($(SUPPORT_INET4),true)
+		NETAPP_COBJS := $(NETAPP_COBJS) ping.o
+	endif
+	ifeq ($(SUPPORT_INET6),true)
+		NETAPP_COBJS := $(NETAPP_COBJS) ping6.o
+	endif
+endif
+
+ifeq ($(USE_RESOLVER),true)
+	SUPPORT_UDP = true
+	CDEFS := $(CDEFS) -DUSE_RESOLVER
+	NETAPP_COBJS := $(NETAPP_COBJS) resolver.o 
+
+endif
+
+ifeq ($(USE_DHCP6_CLI),true)
+	ifeq ($(SUPPORT_INET6),true)
+		SUPPORT_UDP = true
+		UDP_CFG_NON_BLOCKING = true
+		USE_UDP_NON_BLOCKING = true
+		CDEFS := $(CDEFS) -DDHCP6_CLI_CFG
+		NETAPP_COBJS := $(NETAPP_COBJS) dhcp6_cli.o 
+	endif
+endif
+
+ifeq ($(USE_DHCP4_CLI),true)
+	ifeq ($(SUPPORT_INET4),true)
+		SUPPORT_UDP = true
+		UDP_CFG_NON_BLOCKING = true
+		USE_UDP_NON_BLOCKING = true
+		CDEFS := $(CDEFS) -DDHCP4_CLI_CFG
+		NETAPP_COBJS := $(NETAPP_COBJS) dhcp4_cli.o 
+	endif
+endif
+
+ifeq ($(USE_NETAPP_SUBR),true)
+	CDEFS := $(CDEFS) -DUSE_NETAPP_SUBR
+endif
+
+ifeq ($(API_CFG_IP4MAPPED_ADDR),true)
+	CDEFS := $(CDEFS) -DAPI_CFG_IP4MAPPED_ADDR
+endif
+
+ifeq ($(USE_COPYSAVE_API),true)
+	CDEFS := $(CDEFS) -DUSE_COPYSAVE_API
+endif
+
+ifeq ($(TCP_CFG_RWBUF_CSAVE_ONLY),true)
+	CDEFS := $(CDEFS) -DTCP_CFG_RWBUF_CSAVE_ONLY -DTCP_CFG_RWBUF_CSAVE
+endif
+
+ifeq ($(TCP_CFG_RWBUF_CSAVE),true)
+	CDEFS := $(CDEFS) -DTCP_CFG_RWBUF_CSAVE
+endif
+
+ifeq ($(TCP_CFG_SWBUF_CSAVE_ONLY),true)
+	CDEFS := $(CDEFS) -DTCP_CFG_SWBUF_CSAVE_ONLY -DTCP_CFG_SWBUF_CSAVE
+endif
+
+ifeq ($(TCP_CFG_SWBUF_CSAVE),true)
+	CDEFS := $(CDEFS) -DTCP_CFG_SWBUF_CSAVE
+endif
+
+ifeq ($(TCP_CFG_NON_BLOCKING),true)
+	ifeq ($(USE_TCP_NON_BLOCKING),true)
+		CDEFS := $(CDEFS) -DUSE_TCP_NON_BLOCKING
+	endif
+else
+	CDEFS := $(CDEFS) -DUNDEF_TCP_CFG_NON_BLOCKING
+endif
+
+ifeq ($(TCP_CFG_EXTENTIONS),true)
+	CDEFS := $(CDEFS) -DTCP_CFG_EXTENTIONS
+	ifeq ($(USE_TCP_EXTENTIONS),true)
+		CDEFS := $(CDEFS) -DUSE_TCP_EXTENTIONS
+	endif
+endif
+
+ifeq ($(UDP_CFG_NON_BLOCKING),true)
+	ifeq ($(USE_UDP_NON_BLOCKING),true)
+		CDEFS := $(CDEFS) -DUSE_UDP_NON_BLOCKING
+	else
+		ifeq ($(USE_UDP_CALL_BACK),true)
+			CDEFS := $(CDEFS) -DUSE_UDP_CALL_BACK
+		endif
+	endif
+else
+	CDEFS := $(CDEFS) -DUNDEF_UDP_CFG_NON_BLOCKING
+	ifeq ($(USE_UDP_CALL_BACK),true)
+		CDEFS := $(CDEFS) -DUSE_UDP_CALL_BACK
+	endif
+endif
+
+ifeq ($(UDP_CFG_EXTENTIONS),true)
+	CDEFS := $(CDEFS) -DUDP_CFG_EXTENTIONS
+	ifeq ($(USE_UDP_EXTENTIONS),true)
+		CDEFS := $(CDEFS) -DUSE_UDP_EXTENTIONS
+	endif
+endif
+
+ifeq ($(USE_LCD),true)
+	CDEFS := $(CDEFS) -DUSE_LCD
+endif
+
+#
+#  アプリケーションプログラムに関する定義への追加
+#
+
+ifeq ($(TARGET_KERNEL),ASP)
+
+	APPLDIR := $(APPLDIR) $(NETAPP_DIRS)
+	APPL_COBJS := $(APPL_COBJS) $(NETAPP_COBJS)
+	APPL_CFLAGS := $(APPL_CFLAGS) -fno-strict-aliasing
+
+endif
+
+ifeq ($(TARGET_KERNEL),JSP)
+
+	UTASK_DIRS := $(UTASK_DIRS):$(NETAPP_DIRS)
+	UTASK_COBJS := $(UTASK_COBJS) $(NETAPP_COBJS)
+	UTASK_CFLAGS := $(UTASK_CFLAGS) -fno-strict-aliasing
+
+endif
+
+ifeq ($(USE_LCD),true)
+
+ifeq ($(TARGET_KERNEL),ASP)
+
+	APPLDIR := $(APPLDIR) $(SRCDIR)/pdic/sc1602
+
+endif
+
+ifeq ($(TARGET_KERNEL),JSP)
+
+	UTASK_DIRS := $(UTASK_DIRS):$(SRCDIR)/pdic/sc1602
+
+endif
+
+endif
+
+#
+#  TINET コンフィギュレーションファイルの定義への追加
+#
+TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(NETAPP_KERNEL_CFG)
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dbg_cons.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dbg_cons.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dbg_cons.c	(revision 398)
@@ -0,0 +1,3272 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  デバッグコンソール
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <syssvc/serial.h>
+#include <syssvc/logtask.h>
+#include "kernel/kernel_impl.h"
+#include "kernel/task.h"
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#include "../kernel/jsp_kernel.h"
+#include "../kernel/task.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/ppp_var.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_lcp.h>
+#include <net/ppp_ipcp.h>
+#include <net/ppp_modem.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include <netinet6/nd6.h>
+
+#include <net/if_var.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/wwws.h>
+#include <netapp/tcp_echo_srv1.h>
+#include <netapp/tcp_echo_srv2.h>
+#include <netapp/tcp_echo_cli.h>
+#include <netapp/tcp_discard_cli.h>
+#include <netapp/udp6_echo_srv.h>
+#include <netapp/udp4_echo_srv.h>
+#include <netapp/udp6_echo_cli.h>
+#include <netapp/udp4_echo_cli.h>
+#include <netapp/udp_discard_cli.h>
+#include <netapp/resolver.h>
+#include <netapp/dbg_cons.h>
+#include <netapp/dhcp6_cli.h>
+#include <netapp/dhcp4_cli.h>
+#include "lcd.h"
+
+#ifdef USE_DBG_CONS
+
+/*
+ *  dbg_cons_task_status -- タスクの状態の出力
+ */
+
+static const char task_stat_str[][sizeof("SUSPENDED")] = {
+	"DORMANT",		/* 休止状態		*/
+	"RUNNABLE",		/* 実行できる状態	*/
+	"WAINTING",		/* 待ち状態		*/
+	"SUSPENDED",		/* 強制待ち状態		*/
+	"SLEEP",		/* 起床待ち状態		*/
+	"WOBJ",			/* 同期・通信オブジェクトに対する待ち状態	*/
+	"WOBJCB",		/* 共通部分の待ちキューにつながっている。	*/
+	};
+
+void
+dbg_cons_task_status (ID portid, char *line)
+{
+	TCB	*tcb;
+	int_t	ix, st, sx;
+
+	WAI_NET_CONS_PRINTF();
+	cons_printf(portid,
+	            "TASK Status\n"
+	            "ID PI State\n");
+	for (ix = TMIN_TSKID; ix <= tmax_tskid; ix ++) {
+		tcb = get_tcb(ix);
+		cons_printf(portid, "%2d %2d ", ix, tcb->priority);
+		st = tcb->tstat;
+		for (sx = 0; st; sx ++) {
+			if (st & 0x01) {
+				cons_printf(portid, "%s", task_stat_str[sx]);
+				if (st & 0xfe)
+					cons_printf(portid, "|");
+				}
+			st >>= 1;
+			}
+		cons_putchar(portid, '\n');
+		}
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#ifdef SUPPORT_TCP
+
+/*
+ *  tcp_status -- TCP の状態の出力
+ */
+
+static const char tcp_fsm_str[][sizeof("ESTABLISHED")] = {
+	"CLOSED",		/* クローズ			*/
+	"LISTEN",		/* 受動オープン			*/
+	"SYN_SENT",		/* 能動オープン、SYN 送信済み	*/
+	"SYN_RECVD",		/* 受動オープン、SYN 受信済み	*/
+	"ESTABLISHED",		/* コネクション開設完了		*/
+	"CLOSE_WAIT",		/* 相手から FIN 受信、APP の終了待ち	*/
+	"FIN_WAIT_1",		/* APP が終了、FIN 送信済み、ACK 待ち	*/
+	"CLOSING",		/* 同時クローズ、FIN 交換済み、ACK 待ち	*/
+	"LAST_ACK",		/* APP が終了、ACK 待ち			*/
+	"FIN_WAIT_2",		/* 相手からの FIN 待ち			*/
+	"TIME_WAIT",		/* 相手からの FIN 受信済み、時間待ち	*/
+	};
+
+#if defined(SUPPORT_INET6)
+
+static void
+tcp_cep_status (ID portid, char *line)
+{
+	T_TCP_CEP*	cep;
+	int		len;
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+	T_TCP_TWCEP*	twcep;
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+	cons_printf(portid,
+	            "TCP CEP Status\n"
+	            "ID  Snd-Q Rcv-Q Foreign Address                               State\n");
+
+	for (cep = tcp_cep; cep < &tcp_cep[tmax_tcp_cepid]; cep ++)
+		if (!VALID_TCP_CEP(cep)) {
+			cons_printf(portid,
+			            "%2d%c%c     0     0"
+			            " -                                            "
+			            " INVALID\n",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
+			}
+		else if (cep->fsm_state == TCP_FSM_CLOSED) {
+			cons_printf(portid,
+			            "%2d%c%c     0     0"
+			            " -                                            "
+			            " CLOSED\n",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
+			}
+		else if (cep->fsm_state == TCP_FSM_LISTEN) {
+			cons_printf(portid,
+			            "%2d%c%c     0     0"
+			            " -                                            "
+			            " LISTEN\n",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
+			}
+		else {
+			cons_printf(portid,
+			            "%2d%c%c %5d %5d ",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4',
+			            cep->swbuf_count, cep->rwbuf_count);
+
+#if defined(SUPPORT_INET4)
+
+			if (TCP_IS_CEP_IPV4(cep)) {
+				T_IN4_ADDR	addr;
+
+				addr = ntohl(cep->dstaddr.ipaddr.s6_addr32[3]);
+				len  = put_ipv4addr(portid, &addr, 0);
+				}
+			else
+				len  = put_ipv6addr(portid, &cep->dstaddr.ipaddr, 0);
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+			len  = put_ipv6addr(portid, &cep->dstaddr.ipaddr, 0);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+			cons_putchar(portid, '.');
+			len += cons_putnumber(portid, cep->dstaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 44 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			if (cep->fsm_state == TCP_FSM_TIME_WAIT)
+				cons_printf(portid, " %s(%d)\n", tcp_fsm_str[cep->fsm_state],
+				                    cep->timer[TCP_TIM_2MSL] / TCP_SLOW_HZ);
+			else
+				cons_printf(portid, " %s\n", tcp_fsm_str[cep->fsm_state]);
+			}
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+	for (twcep = tcp_twcep; twcep < &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep ++) {
+		if (twcep->fsm_state == TCP_FSM_CLOSED) {
+			cons_printf(portid,
+			            "%2dTW     0     0"
+			            " -                                            "
+			            " CLOSED\n",
+			            GET_TCP_TWCEPID(twcep));
+			}
+		else {
+			cons_printf(portid, "%2dTW     0     0 ", GET_TCP_TWCEPID(twcep));
+
+#if defined(SUPPORT_INET4)
+
+			if (TCP_IS_CEP_IPV4(twcep)) {
+				T_IN4_ADDR	addr;
+
+				addr = ntohl(twcep->dstaddr.ipaddr.s6_addr32[3]);
+				len  = put_ipv4addr(portid, &addr, 0);
+				}
+			else
+				len  = put_ipv6addr(portid, &twcep->dstaddr.ipaddr, 0);
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+			len  = put_ipv6addr(portid, &twcep->dstaddr.ipaddr, 0);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+			cons_putchar(portid, '.');
+			len += cons_putnumber(portid, twcep->dstaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 44 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			if (twcep->fsm_state == TCP_FSM_TIME_WAIT)
+				cons_printf(portid, " %s(%d)\n", tcp_fsm_str[twcep->fsm_state],
+				                    twcep->timer_2msl / TCP_SLOW_HZ);
+			else
+				cons_printf(portid, " %s\n", tcp_fsm_str[twcep->fsm_state]);
+			}
+		}
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+static void
+tcp_cep_status (ID portid, char *line)
+{
+	T_TCP_CEP*	cep;
+	uint_t		len;
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+	T_TCP_TWCEP*	twcep;
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+	cons_printf(portid,
+	            "TCP CEP Status\n"
+	            "ID  Snd-Q Rcv-Q Local Address         Foreign Address       State\n");
+
+	for (cep = tcp_cep; cep < &tcp_cep[tmax_tcp_cepid]; cep ++)
+		if (!VALID_TCP_CEP(cep)) {
+			cons_printf(portid,
+			            "%2d%c%c     0     0"
+			            " -                    "
+			            " -                    "
+			            " INVALID\n",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
+			}
+		else if (cep->fsm_state == TCP_FSM_CLOSED) {
+			cons_printf(portid,
+			            "%2d%c%c     0     0"
+			            " -                    "
+			            " -                    "
+			            " CLOSED\n",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
+			}
+		else if (cep->fsm_state == TCP_FSM_LISTEN) {
+			cons_printf(portid,
+			            "%2d%c%c     0     0 ",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
+			len  = PUT_IPADDR(portid, &cep->myaddr.ipaddr, 0);
+			cons_putchar(portid, ':');
+			len += cons_putnumber(portid, cep->myaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 20 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			cons_printf(portid,
+			            " -                    "
+			            " LISTEN\n");
+			}
+		else {
+			cons_printf(portid,
+			            "%2d%c %5d %5d ",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : ' ',
+			            cep->swbuf_count, cep->rwbuf_count);
+			len  = PUT_IPADDR(portid, &cep->myaddr.ipaddr, 0);
+			cons_putchar(portid, ':');
+			len += cons_putnumber(portid, cep->myaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 21 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			len  = PUT_IPADDR(portid, &cep->dstaddr.ipaddr, 0);
+			cons_putchar(portid, ':');
+			len += cons_putnumber(portid, cep->dstaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 20 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			if (cep->fsm_state == TCP_FSM_TIME_WAIT)
+				cons_printf(portid, " %s(%d)\n", tcp_fsm_str[cep->fsm_state],
+				                    cep->timer[TCP_TIM_2MSL] / TCP_SLOW_HZ);
+			else
+				cons_printf(portid, " %s\n", tcp_fsm_str[cep->fsm_state]);
+			}
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+	for (twcep = tcp_twcep; twcep < &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep ++) {
+		if (twcep->fsm_state == TCP_FSM_CLOSED) {
+			cons_printf(portid,
+			            "%2dTW     0     0"
+			            " -                    "
+			            " -                    "
+			            " CLOSED\n",
+			            GET_TCP_TWCEPID(twcep));
+			}
+		else {
+			cons_printf(portid, "%2dTW     0     0 ", GET_TCP_TWCEPID(twcep));
+			len  = PUT_IPADDR(portid, &twcep->myaddr.ipaddr, 0);
+			cons_putchar(portid, ':');
+			len += cons_putnumber(portid, twcep->myaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 21 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			len  = PUT_IPADDR(portid, &twcep->dstaddr.ipaddr, 0);
+			cons_putchar(portid, ':');
+			len += cons_putnumber(portid, twcep->dstaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 20 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			if (twcep->fsm_state == TCP_FSM_TIME_WAIT)
+				cons_printf(portid, " %s(%d)\n", tcp_fsm_str[twcep->fsm_state],
+				                    twcep->timer_2msl / TCP_SLOW_HZ);
+			else
+				cons_printf(portid, " %s\n", tcp_fsm_str[twcep->fsm_state]);
+			}
+		}
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if TNUM_TCP6_REPID > 0
+
+static void
+tcp6_rep_status (ID portid, char *line)
+{
+	T_TCP_CEP*	cep;
+	T_TCP6_REP*	rep;
+	ID		repid;
+	int_t		cnt;
+	uint_t		len;
+
+	cons_printf(portid,
+	            "TCP6 REP Status\n"
+	            "ID  Local Address         CEP\n");
+	for (repid = TMIN_TCP6_REPID; repid <= tmax_tcp6_repid; repid ++) {
+		rep = GET_TCP6_REP(repid);
+		cons_printf(portid, "%2d%c ", GET_TCP6_REPID(rep), DYNAMIC_TCP_REP(rep) ? 'D' : ' ');
+		if (VALID_TCP_REP(rep)) {
+			len  = PUT_IPADDR(portid, &rep->myaddr.ipaddr, 0);
+			cons_putchar(portid, '.');
+			len += cons_putnumber(portid, rep->myaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 21 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			cnt = 0;
+			for (cep = tcp_cep; cep < &tcp_cep[tmax_tcp_cepid]; cep ++) {
+				if (TCP_IS_CEP_IPV6(cep) && cep->rep == rep) {
+					if (cnt > 0)
+						cons_printf(portid, ",%d", GET_TCP_CEPID(cep));
+					else
+						cons_printf(portid, "%d", GET_TCP_CEPID(cep));
+					cnt ++;
+					}
+				}
+			}
+		else
+			cons_printf(portid, "INVALID");
+		cons_putchar(portid, '\n');
+		}
+	}
+
+#endif	/* of #if TNUM_TCP6_REPID > 0 */
+
+#if TNUM_TCP4_REPID > 0
+
+static void
+tcp4_rep_status (ID portid, char *line)
+{
+	T_TCP_CEP*	cep;
+	T_TCP4_REP*	rep;
+	ID		repid;
+	int_t		cnt;
+	uint_t		len;
+
+	cons_printf(portid,
+	            "TCP4 REP Status\n"
+	            "ID  Local Address         CEP\n");
+	for (repid = TMIN_TCP4_REPID; repid <= tmax_tcp4_repid; repid ++) {
+		rep = GET_TCP4_REP(repid);
+		cons_printf(portid, "%2d%c ", GET_TCP4_REPID(rep), DYNAMIC_TCP_REP(rep) ? 'D' : ' ');
+		if (VALID_TCP_REP(rep)) {
+			len  = put_ipv4addr(portid, &rep->myaddr.ipaddr, 0);
+			cons_putchar(portid, ':');
+			len += cons_putnumber(portid, rep->myaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 21 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			cnt = 0;
+			for (cep = tcp_cep; cep < &tcp_cep[tmax_tcp_cepid]; cep ++) {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+				if (TCP_IS_CEP_IPV4(cep) && cep->rep4 == rep) {
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+				if (TCP_IS_CEP_IPV4(cep) && cep->rep == rep) {
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+					if (cnt > 0)
+						cons_printf(portid, ",%d", GET_TCP_CEPID(cep));
+					else
+						cons_printf(portid, "%d", GET_TCP_CEPID(cep));
+					cnt ++;
+					}
+				}
+			}
+		else
+			cons_printf(portid, "INVALID");
+		cons_putchar(portid, '\n');
+		}
+	}
+
+#endif	/* of #if TNUM_TCP4_REPID > 0 */
+
+static void
+tcp_status (ID portid, char *line)
+{
+	WAI_NET_CONS_PRINTF();
+
+	tcp_cep_status(portid, line);
+
+#if TNUM_TCP6_REPID > 0
+	tcp6_rep_status(portid, line);
+#endif
+
+#if TNUM_TCP4_REPID > 0
+	tcp4_rep_status(portid, line);
+#endif
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #ifdef SUPPORT_TCP */
+
+#ifdef SUPPORT_UDP
+
+/*
+ *  udp6_status -- UDP の状態の出力
+ */
+
+#if TNUM_UDP6_CEPID > 0
+
+extern const ID tmax_tcp_cepid;
+
+static void
+udp6_status (ID portid, char *line)
+{
+	T_UDP6_CEP*	cep;
+	ID		cepid;
+	uint_t		len;
+
+	cons_printf(portid,
+	            "UDP6 CEP Status\n"
+	            "ID  Local Address\n");
+
+	for (cepid = TMIN_UDP6_CEPID; cepid <= tmax_udp6_cepid; cepid ++) {
+		cep = GET_UDP6_CEP(cepid);
+		cons_printf(portid, "%2d%c ", GET_UDP6_CEPID(cep), DYNAMIC_UDP_CEP(cep) ? 'D' : ' ');
+		if (VALID_UDP_CEP(cep)) {
+			len  = put_ipv6addr(portid, &cep->myaddr.ipaddr, 0);
+			cons_putchar(portid, '.');
+			len += cons_putnumber(portid, cep->myaddr.portno, 10, radhex, 0, false, ' ');
+			}
+		else
+			cons_printf(portid, "INVALID");
+		cons_putchar(portid, '\n');
+		}
+
+	SIG_NET_CONS_PRINTF();
+	}
+
+#endif	/* of #if TNUM_UDP6_CEPID > 0 */
+
+/*
+ *  udp4_status -- UDP の状態の出力
+ */
+
+#if TNUM_UDP4_CEPID > 0
+
+static void
+udp4_status (ID portid, char *line)
+{
+	T_UDP4_CEP*	cep;
+	ID		cepid;
+	uint_t		len;
+
+	cons_printf(portid,
+	            "UDP4 CEP Status\n"
+	            "ID  Local Address\n");
+
+	for (cepid = TMIN_UDP4_CEPID; cepid <= tmax_udp4_cepid; cepid ++) {
+		cep = GET_UDP4_CEP(cepid);
+		cons_printf(portid, "%2d%c ", GET_UDP4_CEPID(cep), DYNAMIC_UDP_CEP(cep) ? 'D' : ' ');
+		if (VALID_UDP_CEP(cep)) {
+			len  = put_ipv4addr(portid, &cep->myaddr.ipaddr, 0);
+			cons_putchar(portid, '.');
+			len += cons_putnumber(portid, cep->myaddr.portno, 10, radhex, 0, false, ' ');
+			}
+		else
+			cons_printf(portid, "INVALID");
+		cons_putchar(portid, '\n');
+		}
+
+	SIG_NET_CONS_PRINTF();
+	}
+
+#endif	/* of #if TNUM_UDP4_CEPID > 0 */
+
+static void
+udp_status (ID portid, char *line)
+{
+	WAI_NET_CONS_PRINTF();
+
+#if TNUM_UDP6_CEPID > 0
+	udp6_status(portid, line);
+#endif
+
+#if TNUM_UDP4_CEPID > 0
+	udp4_status(portid, line);
+#endif
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #ifdef SUPPORT_UDP */
+
+#ifdef SUPPORT_ETHER
+
+#if defined(SUPPORT_INET6)
+
+/*
+ * ifa6_status -- 近隣キャッシュ状態の出力
+ */
+
+static const char nd_state_str[][sizeof("INCOMPLETE")] = {
+	"FREE",			/* 未使用		*/
+	"NO STATE",		/* 状態未定義		*/
+	"INCOMPLETE",		/* 未解決		*/
+	"REACHABLE",		/* 到達可能		*/
+	"STALE",		/* 到達可能性は未確認	*/
+	"DELAY",		/* 到達可能性の確認待機	*/
+	"PROBE",		/* 到達可能性を確認中	*/
+	};
+
+static void
+ifa6_status (ID portid, char *line)
+{
+	const T_LLINFO_ND6	*cache;
+	SYSTIM			now;
+	int_t			ix;
+
+	WAI_NET_CONS_PRINTF();
+	cons_printf(portid,
+	            "ND Cache Status\n"
+	            "IX Expire State      MAC Address       IP Address\n");
+
+	/* expire の単位は [us]。*/
+	get_tim(&now);
+	cache = nd6_get_cache();
+	for (ix = 0; ix < NUM_ND6_CACHE_ENTRY; ix ++) {
+		if (cache[ix].state != ND6_LLINFO_FREE) {
+			cons_printf(portid, "%2d %6ld %10s %M %lI\n",
+			            ix, 
+			            cache[ix].state == ND6_LLINFO_STALE ||
+			            (uint32_t)((int32_t)(cache[ix].expire - now) <= 0
+			                 ? 0 : (int32_t)(cache[ix].expire - now) / SYSTIM_HZ),
+			            nd_state_str[cache[ix].state],
+			            &cache[ix].ifaddr,
+			            &cache[ix].addr);
+			}
+		}
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+/*
+ *  ifa4_status -- ARP キャッシュ出力
+ */
+
+static void
+ifa4_status (ID portid, char *line)
+{
+	const T_ARP_ENTRY	*cache;
+	int_t			ix;
+
+	WAI_NET_CONS_PRINTF();
+	cons_printf(portid,
+	            "ARP Cache\n"
+	            "IX Expire MAC Address       IP Address\n");
+
+	/* expire の単位は [us]。*/
+	cache = arp_get_cache();
+	for (ix = 0; ix < NUM_ARP_ENTRY; ix ++) {
+		if (cache[ix].expire != 0)
+			cons_printf(portid, "%2d %6d %M %hI\n",
+			                    ix, cache[ix].expire / NET_TIMER_HZ,
+			                    cache[ix].mac_addr, &cache[ix].ip_addr);
+		}
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#if NET_COUNT_ENABLE
+
+/*
+ *  net_count_struct -- ネットワーク統計情報
+ */
+
+static void
+net_count_struct (ID portid, char *name, T_NET_COUNT *item)
+{
+	cons_printf(portid, "\n%s\n", name);
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",	item->in_octets);
+	cons_printf(portid, "\t送信オクテット数\t%lu\n",	item->out_octets);
+	cons_printf(portid, "\t受信バケット数\t%lu\n",		item->in_packets);
+	cons_printf(portid, "\t送信バケット数\t%lu\n",		item->out_packets);
+	cons_printf(portid, "\t受信エラーバケット数\t%lu\n",	item->in_err_packets);
+	cons_printf(portid, "\t送信エラーバケット数\t%lu\n",	item->out_err_packets);
+	}
+
+/*
+ *  net_count -- ネットワーク統計情報
+ */
+
+static void
+net_count (ID portid, char *line)
+{
+	const T_NET_BUF_ENTRY	*tbl;
+	SYSTIM			now;
+	int_t			ix;
+
+	WAI_NET_CONS_PRINTF();
+	get_tim(&now);
+	cons_printf(portid, "ネットワーク統計情報\t経過時間[us]\t%lu\t", now);
+	if (now > (1000 * 3600 * 24))
+		cons_printf(portid, "%3lu日 %2lu時間 %2lu分 %2lu秒\n",
+		             now / (1000 * 3600 * 24),
+		            (now / (1000 * 3600)) % 24,
+		            (now / (1000 * 60  )) % 60,
+		            (now /  1000        ) % 60);
+	else
+		cons_printf(portid, "%2lu時間 %2lu分 %2lu秒\n",
+		            (now / (1000 * 3600)) % 24,
+		            (now / (1000 * 60  )) % 60,
+		            (now /  1000        ) % 60);
+
+#ifdef SUPPORT_PPP
+
+	net_count_struct(portid, "HDLC", &net_count_hdlc);
+	cons_printf(portid, "\nPPP\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",	net_count_ppp.in_octets);
+	cons_printf(portid, "\t送信オクテット数\t%lu\n",	net_count_ppp.out_octets);
+	cons_printf(portid, "\t受信バケット数\t%lu\n",		net_count_ppp.in_packets);
+	cons_printf(portid, "\t送信バケット数\t%lu\n",		net_count_ppp.out_packets);
+	cons_printf(portid, "\t受信エラーバケット数\t%lu\n",	net_count_ppp.in_err_packets);
+	cons_printf(portid, "\t送信エラーバケット数\t%lu\n",	net_count_ppp.out_err_packets);
+	cons_printf(portid, "\tnet_buf 割り当て失敗数\t%lu\n",	net_count_ppp_no_bufs);
+
+	cons_printf(portid, "\nLCP\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",	net_count_ppp_lcp_in_octets);
+	cons_printf(portid, "\t受信バケット数\t%lu\n",		net_count_ppp_lcp_in_packets);
+
+	cons_printf(portid, "\nIPCP\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",	net_count_ppp_ipcp_in_octets);
+	cons_printf(portid, "\t受信バケット数\t%lu\n",		net_count_ppp_ipcp_in_packets);
+
+	cons_printf(portid, "\nPAP\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",	net_count_ppp_upap_in_octets);
+	cons_printf(portid, "\t受信バケット数\t%lu\n",		net_count_ppp_upap_in_packets);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_ETHER
+
+	net_count_struct(portid, "イーサネット", &net_count_ether);
+
+	cons_printf(portid, "\nイーサネット・ネットワークインタフェース\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",			net_count_ether_nic[NC_ETHER_NIC_IN_OCTETS]);
+	cons_printf(portid, "\t受信バケット数\t%lu\n",				net_count_ether_nic[NC_ETHER_NIC_IN_PACKETS]);
+	cons_printf(portid, "\t受信エラーバケット数\t%lu\n",			net_count_ether_nic[NC_ETHER_NIC_IN_ERR_PACKETS]);
+	cons_printf(portid, "\tnet_buf 割り当て失敗数\t%lu\n",			net_count_ether_nic[NC_ETHER_NIC_NO_BUFS]);
+	cons_printf(portid, "\t受信セマフォ資源返却上限オーバー数\t%lu\n",	net_count_ether_nic[NC_ETHER_NIC_RXB_QOVRS]);
+	cons_printf(portid, "\t送信オクテット数\t%lu\n",			net_count_ether_nic[NC_ETHER_NIC_OUT_OCTETS]);
+	cons_printf(portid, "\t送信バケット数\t%lu\n",				net_count_ether_nic[NC_ETHER_NIC_OUT_PACKETS]);
+	cons_printf(portid, "\t送信エラーバケット数\t%lu\n",			net_count_ether_nic[NC_ETHER_NIC_OUT_ERR_PACKETS]);
+	cons_printf(portid, "\tコリジョン数\t%lu\n",				net_count_ether_nic[NC_ETHER_NIC_COLS]);
+	cons_printf(portid, "\t送信セマフォ資源返却上限オーバー数\t%lu\n",	net_count_ether_nic[NC_ETHER_NIC_TXB_QOVRS]);
+	cons_printf(portid, "\t送信タイムアウト数	\t%lu\n",		net_count_ether_nic[NC_ETHER_NIC_TIMEOUTS]);
+	cons_printf(portid, "\tリセット数\t%lu\n",				net_count_ether_nic[NC_ETHER_NIC_RESETS]);
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#if defined(SUPPORT_INET6)
+
+	cons_printf(portid, "\nIPv6\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",		net_count_ip6[NC_IP6_IN_OCTETS]);
+	cons_printf(portid, "\t受信データグラム数\t%lu\n",		net_count_ip6[NC_IP6_IN_PACKETS]);
+	cons_printf(portid, "\t受信エラーデータグラム数\t%lu\n",	net_count_ip6[NC_IP6_IN_ERR_PACKETS]);
+	cons_printf(portid, "\t長さエラー数\t%lu\n",			net_count_ip6[NC_IP6_IN_ERR_SHORT]);
+	cons_printf(portid, "\tバージョンエラー数\t%lu\n",		net_count_ip6[NC_IP6_IN_ERR_VER]);
+	cons_printf(portid, "\tアドレスエラー数\t%lu\n",		net_count_ip6[NC_IP6_IN_ERR_ADDR]);
+	cons_printf(portid, "\tプロトコルエラー数\t%lu\n",		net_count_ip6[NC_IP6_IN_ERR_PROTO]);
+	cons_printf(portid, "\t分割受信数\t%lu\n",			net_count_ip6[NC_IP6_FRAG_IN]);
+	cons_printf(portid, "\t分割受信フラグメント数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_IN_FRAGS]);
+	cons_printf(portid, "\t分割受信再構成成功数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_IN_OK]);
+	cons_printf(portid, "\t分割受信破棄数\t%lu\n",			net_count_ip6[NC_IP6_FRAG_IN_DROP]);
+	cons_printf(portid, "\t分割受信バッファり当て失敗数\t%lu\n",	net_count_ip6[NC_IP6_FRAG_IN_NO_BUF]);
+	cons_printf(portid, "\t分割受信タイムアウト数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_IN_TMOUT]);
+	cons_printf(portid, "\t送信オクテット数\t%lu\n",		net_count_ip6[NC_IP6_OUT_OCTETS]);
+	cons_printf(portid, "\t送信データグラム数\t%lu\n",		net_count_ip6[NC_IP6_OUT_PACKETS]);
+	cons_printf(portid, "\t送信エラーデータグラム数\t%lu\n",	net_count_ip6[NC_IP6_OUT_ERR_PACKETS]);
+	cons_printf(portid, "\t分割送信数\t%lu\n",			net_count_ip6[NC_IP6_FRAG_OUT]);
+	cons_printf(portid, "\t分割送信フラグメント数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_OUT_FRAGS]);
+
+	cons_printf(portid, "\nICMPv6\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",		net_count_icmp6[NC_ICMP6_IN_OCTETS]);
+	cons_printf(portid, "\t受信パケット数\t%lu\n",			net_count_icmp6[NC_ICMP6_IN_PACKETS]);
+	cons_printf(portid, "\t受信エラーパケット数\t%lu\n",		net_count_icmp6[NC_ICMP6_IN_ERR_PACKETS]);
+	cons_printf(portid, "\t受信チックサムエラー数\t%lu\n",		net_count_icmp6[NC_ICMP6_IN_ERR_CKSUM]);
+	cons_printf(portid, "\t送信オクテット数\t%lu\n",		net_count_icmp6[NC_ICMP6_OUT_OCTETS]);
+	cons_printf(portid, "\t送信パケット数\t%lu\n",			net_count_icmp6[NC_ICMP6_OUT_PACKETS]);
+	cons_printf(portid, "\t送信エラーパケット数\t%lu\n",		net_count_icmp6[NC_ICMP6_OUT_ERR_PACKETS]);
+
+	cons_printf(portid, "\n近隣探索\n");
+	cons_printf(portid, "\tルータ通知受信数\t%lu\n",		net_count_nd6[NC_ND6_RA_IN_PACKETS]);
+	cons_printf(portid, "\tルータ要請送信数\t%lu\n",		net_count_nd6[NC_ND6_RS_OUT_PACKETS]);
+	cons_printf(portid, "\t近隣通知受信数\t%lu\n",			net_count_nd6[NC_ND6_NA_IN_PACKETS]);
+	cons_printf(portid, "\t近隣通知送信数\t%lu\n",			net_count_nd6[NC_ND6_NA_OUT_PACKETS]);
+	cons_printf(portid, "\t近隣要請受信数\t%lu\n",			net_count_nd6[NC_ND6_NS_IN_PACKETS]);
+	cons_printf(portid, "\t近隣要請送信数\t%lu\n",			net_count_nd6[NC_ND6_NS_OUT_PACKETS]);
+	cons_printf(portid, "\t重複アドレス検出送信数\t%lu\n",		net_count_nd6[NC_ND6_DAD_OUT_PACKETS]);
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#ifdef SUPPORT_ETHER
+
+	net_count_struct(portid, "ARP", &net_count_arp);
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+	cons_printf(portid, "\nIPv4\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",		net_count_ip4[NC_IP4_IN_OCTETS]);
+	cons_printf(portid, "\t受信データグラム数\t%lu\n",		net_count_ip4[NC_IP4_IN_PACKETS]);
+	cons_printf(portid, "\t受信エラーデータグラム数\t%lu\n",	net_count_ip4[NC_IP4_IN_ERR_PACKETS]);
+	cons_printf(portid, "\tチェックサムエラー数\t%lu\n",		net_count_ip4[NC_IP4_IN_ERR_CKSUM]);
+	cons_printf(portid, "\t長さエラー数\t%lu\n",			net_count_ip4[NC_IP4_IN_ERR_SHORT]);
+	cons_printf(portid, "\tバージョンエラー数\t%lu\n",		net_count_ip4[NC_IP4_IN_ERR_VER]);
+	cons_printf(portid, "\tアドレスエラー数\t%lu\n",		net_count_ip4[NC_IP4_IN_ERR_ADDR]);
+	cons_printf(portid, "\tプロトコルエラー数\t%lu\n",		net_count_ip4[NC_IP4_IN_ERR_PROTO]);
+	cons_printf(portid, "\tオプション入力数\t%lu\n",		net_count_ip4[NC_IP4_OPTS]);
+	cons_printf(portid, "\t分割受信数\t%lu\n",			net_count_ip4[NC_IP4_FRAG_IN]);
+	cons_printf(portid, "\t分割受信フラグメント数\t%lu\n",		net_count_ip4[NC_IP4_FRAG_IN_FRAGS]);
+	cons_printf(portid, "\t分割受信再構成成功数\t%lu\n",		net_count_ip4[NC_IP4_FRAG_IN_OK]);
+	cons_printf(portid, "\t分割受信破棄数\t%lu\n",			net_count_ip4[NC_IP4_FRAG_IN_DROP]);
+	cons_printf(portid, "\t分割受信バッファり当て失敗数\t%lu\n",	net_count_ip4[NC_IP4_FRAG_IN_NO_BUF]);
+	cons_printf(portid, "\t分割受信タイムアウト数\t%lu\n",		net_count_ip4[NC_IP4_FRAG_IN_TMOUT]);
+	cons_printf(portid, "\t送信オクテット数\t%lu\n",		net_count_ip4[NC_IP4_OUT_OCTETS]);
+	cons_printf(portid, "\t送信データグラム数\t%lu\n",		net_count_ip4[NC_IP4_OUT_PACKETS]);
+	cons_printf(portid, "\t送信エラーデータグラム数\t%lu\n",	net_count_ip4[NC_IP4_OUT_ERR_PACKETS]);
+	cons_printf(portid, "\t分割送信数\t%lu\n",			net_count_ip4[NC_IP4_FRAG_OUT]);
+	cons_printf(portid, "\t分割送信フラグメント数\t%lu\n",		net_count_ip4[NC_IP4_FRAG_OUT_FRAGS]);
+
+	net_count_struct(portid, "ICMP", &net_count_icmp4);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#ifdef SUPPORT_TCP
+
+	cons_printf(portid, "\nTCP\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",		net_count_tcp[NC_TCP_RECV_OCTETS]);
+	cons_printf(portid, "\t受信データオクテット数\t%lu\n",		net_count_tcp[NC_TCP_RECV_DATA_OCTETS]);
+	cons_printf(portid, "\t受信セグメント数\t%lu\n",		net_count_tcp[NC_TCP_RECV_SEGS]);
+	cons_printf(portid, "\t受信データセグメント数\t%lu\n",		net_count_tcp[NC_TCP_RECV_DATA_SEGS]);
+	cons_printf(portid, "\t受信、緊急セグメント数\t%lu\n",		net_count_tcp[NC_TCP_RECV_URG_SEGS]);
+	cons_printf(portid, "\t受信、ヘッダ不正数\t%lu\n",		net_count_tcp[NC_TCP_RECV_BAD_HEADERS]);
+	cons_printf(portid, "\t受信、チェックサム不正数\t%lu\n",	net_count_tcp[NC_TCP_RECV_BAD_CKSUMS]);
+	cons_printf(portid, "\t受信、ACK 数\t%lu\n",			net_count_tcp[NC_TCP_RECV_ACKS]);
+	cons_printf(portid, "\t受信、多重 ACK 数\t%lu\n",		net_count_tcp[NC_TCP_RECV_DUP_ACKS]);
+	cons_printf(portid, "\t受信、RST 数\t%lu\n",			net_count_tcp[NC_TCP_RECV_RSTS]);
+	cons_printf(portid, "\t受信、多重数\t%lu\n",			net_count_tcp[NC_TCP_RECV_DUP_SEGS]);
+	cons_printf(portid, "\t受信、破棄数\t%lu\n",			net_count_tcp[NC_TCP_RECV_DROP_SEGS]);
+	cons_printf(portid, "\t受信キュー解放数\t%lu\n",		net_count_tcp[NC_TCP_FREE_RCV_QUEUE]);
+	cons_printf(portid, "\t送信データオクテット数\t%lu\n",		net_count_tcp[NC_TCP_SEND_DATA_OCTETS]);
+	cons_printf(portid, "\t送信制御セグメント数\t%lu\n",		net_count_tcp[NC_TCP_SEND_CNTL_SEGS]);
+	cons_printf(portid, "\t送信セグメント数\t%lu\n",		net_count_tcp[NC_TCP_SEND_SEGS]);
+	cons_printf(portid, "\t再送信セグメント数\t%lu\n",		net_count_tcp[NC_TCP_SEND_REXMIT_SEGS]);
+	cons_printf(portid, "\t送信データセグメント数\t%lu\n",		net_count_tcp[NC_TCP_SEND_DATA_SEGS]);
+	cons_printf(portid, "\t送信、緊急セグメント数\t%lu\n",		net_count_tcp[NC_TCP_SEND_URG_SEGS]);
+	cons_printf(portid, "\t送信、ACK 数\t%lu\n",			net_count_tcp[NC_TCP_SEND_ACKS]);
+	cons_printf(portid, "\t送信、RST 数\t%lu\n",			net_count_tcp[NC_TCP_SEND_RSTS]);
+	cons_printf(portid, "\tRTT 更新数\t%lu\n",			net_count_tcp[NC_TCP_RTT_UPDATES]);
+	cons_printf(portid, "\t受動オープン数\t%lu\n",			net_count_tcp[NC_TCP_ACCEPTS]);
+	cons_printf(portid, "\t能動オープン数\t%lu\n",			net_count_tcp[NC_TCP_CONNECTS]);
+
+#endif	/* of #ifdef SUPPORT_TCP */
+
+#ifdef SUPPORT_UDP
+
+	net_count_struct(portid, "UDP",  &net_count_udp);
+
+#endif	/* of #ifdef SUPPORT_UDP */
+
+	tbl = nbuf_get_tbl();
+	cons_printf(portid, "\nネットワークバッファ\n\tサイズ\t用意数\t使用中数\t割当要求数\t割当数\t割当てエラー数\n");
+	for (ix = nbuf_get_tbl_size(); ix -- > 0; ) {
+		cons_printf(portid, "\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\n",
+		                    tbl[ix].size,
+		                    tbl[ix].prepares,
+		                    tbl[ix].busies,
+		                    tbl[ix].requests,
+		                    tbl[ix].allocs,
+		                    tbl[ix].errors);
+		}
+
+	cons_printf(portid, "\nネットワーク統計情報\t経過時間[us]\t%lu\t", now);
+	if (now > (1000 * 3600 * 24))
+		cons_printf(portid, "%3lu日 %2lu時間 %2lu分 %2lu秒\n",
+		             now / (1000 * 3600 * 24),
+		            (now / (1000 * 3600)) % 24,
+		            (now / (1000 * 60  )) % 60,
+		            (now /  1000        ) % 60);
+	else
+		cons_printf(portid, "%2lu時間 %2lu分 %2lu秒\n",
+		            (now / (1000 * 3600)) % 24,
+		            (now / (1000 * 60  )) % 60,
+		            (now /  1000        ) % 60);
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#if defined(SUPPORT_INET4)
+
+#ifdef IP4_CFG_FRAGMENT
+
+/*
+ *  nbuf_stat_ip4_frag_queue -- IPv4 再構成キュー内ネットワークバッファ情報
+ */
+
+static void
+nbuf_stat_ip4_frag_queue (ID portid)
+{
+	const T_NET_BUF_ENTRY	*tbl;
+	const T_NET_BUF		*nbuf, **queue;
+	int_t			ix, fix, count;
+
+	cons_printf(portid, "\nIPv4再構成キュー内\nIndex\tTime");
+	tbl = nbuf_get_tbl();
+	for (ix = nbuf_get_tbl_size(); ix -- > 0; )
+		cons_printf(portid, "\t%d", tbl[ix].size);
+	cons_putchar(portid, '\n');
+
+	queue = ip_get_frag_queue();
+	for (fix = 0; fix < NUM_IP4_FRAG_QUEUE; fix ++) {
+		if (queue[fix] != NULL) {
+			cons_printf(portid, "%d\t%d", fix, GET_QIP4_HDR(queue[fix])->ttl);
+			for (ix = nbuf_get_tbl_size(); ix -- > 0; ) {
+				count = 0;
+				for (nbuf = queue[fix]; nbuf != NULL; nbuf = GET_QIP4_HDR(nbuf)->next)
+					if (nbuf->idix == ix)
+						count ++;
+				cons_printf(portid, "\t%d", count);
+				}
+			cons_putchar(portid, '\n');
+			}
+		}
+	}
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+#ifdef IP6_CFG_FRAGMENT
+
+/*
+ *  nbuf_stat_ip6_frag_queue -- IPv6 再構成キュー内ネットワークバッファ情報
+ */
+
+static void
+nbuf_stat_ip6_frag_queue (ID portid)
+{
+	const T_NET_BUF_ENTRY	*tbl;
+	const T_NET_BUF		*nbuf, **queue;
+	int_t			ix, fix, count;
+
+	cons_printf(portid, "\nIPv6再構成キュー内\nIndex\tTime");
+	tbl = nbuf_get_tbl();
+	for (ix = nbuf_get_tbl_size(); ix -- > 0; )
+		cons_printf(portid, "\t%d", tbl[ix].size);
+	cons_putchar(portid, '\n');
+
+	queue = ip6_get_frag_queue();
+	for (fix = 0; fix < NUM_IP6_FRAG_QUEUE; fix ++) {
+		if (queue[fix] != NULL) {
+			cons_printf(portid, "%d\t%d", fix, GET_QIP6_HDR(queue[fix])->ftim);
+			for (ix = nbuf_get_tbl_size(); ix -- > 0; ) {
+				count = 0;
+				for (nbuf = queue[fix]; nbuf != NULL; nbuf = GET_QIP6_HDR(nbuf)->next_frag)
+					if (nbuf->idix == ix)
+						count ++;
+				cons_printf(portid, "\t%d", count);
+				}
+			cons_putchar(portid, '\n');
+			}
+		}
+	}
+
+#endif	/* of #ifdef IP6_CFG_FRAGMENT */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if NET_COUNT_ENABLE */
+
+/*
+ *  nbuf_status -- ネットワークバッファ情報
+ */
+
+static void
+nbuf_status (ID portid, char *line)
+{
+	SYSTIM		now;
+
+#if NET_COUNT_ENABLE
+	const T_NET_BUF_ENTRY	*tbl;
+	int_t			ix;
+#endif	/* of #if NET_COUNT_ENABLE */
+
+#ifdef SUPPORT_TCP
+	T_NET_BUF		*nbuf;
+	T_TCP_CEP*		cep;
+	T_TCP_Q_HDR*		tqhdr;
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+	T_TCP_HDR*		tcph;
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+#endif	/* of #ifdef SUPPORT_TCP */
+
+	WAI_NET_CONS_PRINTF();
+	get_tim(&now);
+	cons_printf(portid, "ネットワークバッファ情報\t経過時間[us]\t%u\n", now);
+
+#if NET_COUNT_ENABLE
+
+	cons_printf(portid, "\nネットワークバッファ\n\tサイズ\t用意数\t使用中数\t割当要求数\t割当数\t割当てエラー数\n");
+	tbl = nbuf_get_tbl();
+	for (ix = nbuf_get_tbl_size(); ix -- > 0; ) {
+		cons_printf(portid, "\t%u\t%u\t%u\t%u\t%u\t%u\n",
+		                    tbl[ix].size,
+		                    tbl[ix].prepares,
+		                    tbl[ix].busies,
+		                    tbl[ix].requests,
+		                    tbl[ix].allocs,
+		                    tbl[ix].errors);
+		}
+
+#endif	/* of #if NET_COUNT_ENABLE */
+
+#ifdef SUPPORT_TCP
+
+	cons_printf(portid, "\nCEP内\nCEPID\n");
+
+	for (cep = tcp_cep; cep < &tcp_cep[tmax_tcp_cepid]; cep ++) {
+		cons_printf(portid, "%2d", GET_TCP_CEPID(cep));
+		for (nbuf = cep->reassq; nbuf != NULL; nbuf = tqhdr->next) {
+			tqhdr = GET_TCP_Q_HDR(nbuf, GET_TCP_HDR_OFFSET(nbuf));
+			cons_printf(portid, "[a:%6lu-%6lu] ",
+			            ntohl(tqhdr->seq) - cep->irs + tqhdr->soff,
+			            ntohl(tqhdr->seq) - cep->irs + tqhdr->soff + tqhdr->slen);
+			}
+
+#ifdef TCP_CFG_RWBUF_CSAVE
+		for (nbuf = cep->rwbufq; nbuf != NULL; nbuf = tqhdr->next) {
+			tqhdr = GET_TCP_Q_HDR(nbuf, GET_TCP_HDR_OFFSET(nbuf));
+			cons_printf(portid, "[r:%6lu-%6lu] ",
+			            ntohl(tqhdr->seq) - cep->irs + tqhdr->soff,
+			            ntohl(tqhdr->seq) - cep->irs + tqhdr->soff + tqhdr->slen);
+			}
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE */
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+		if (cep->swbufq != NULL) {
+			tcph = GET_TCP_HDR(cep->swbufq, GET_TCP_HDR_OFFSET(cep->swbufq));
+#if 0
+			cons_printf(portid, "[s:%6lu-%6lu] ",
+			            ntohl(tcph->seq) - cep->iss,
+			            ntohl(tcph->seq) - cep->iss + (GET_IP_SDU_SIZE(cep->swbufq) - 
+			                                           GET_TCP_HDR_SIZE(cep->swbufq, GET_TCP_HDR_OFFSET(cep->swbufq))));
+#else
+			cons_printf(portid, "[s:%6lu-%6lu,%08x,%08x] ",
+			            ntohl(tcph->seq) - cep->iss,
+			            ntohl(tcph->seq) - cep->iss + (GET_IP_SDU_SIZE(cep->swbufq) - 
+			                                           GET_TCP_HDR_SIZE(cep->swbufq, GET_TCP_HDR_OFFSET(cep->swbufq))),
+			            ntohl(tcph->seq), cep->iss);
+#endif
+			}
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+		cons_putchar(portid, '\n');
+		}
+
+#endif	/* of #ifdef SUPPORT_TCP */
+
+#if NET_COUNT_ENABLE
+
+#if defined(SUPPORT_INET4)
+
+#ifdef IP4_CFG_FRAGMENT
+
+	nbuf_stat_ip4_frag_queue(portid);
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+#ifdef IP6_CFG_FRAGMENT
+
+	nbuf_stat_ip6_frag_queue(portid);
+
+#endif	/* of #ifdef IP6_CFG_FRAGMENT */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if NET_COUNT_ENABLE */
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#ifdef USE_RESOLVER
+
+/*
+ *  show_dns_soa -- DNS の SOA RDATA を表示する。
+ */
+
+static ER_UINT
+show_dns_soa (ID portid, uint8_t *msg, ER_UINT length, uint_t offset)
+{
+	T_RSLV_SOA	soa;
+	ER_UINT		error;
+	uint_t		rn_offset;
+
+	if ((error = dns_analyze_soa(&soa, offset, msg, length)) < 0)
+		return error;
+
+	cons_printf(portid, "    mname:   ");
+	rn_offset = show_dns_domain_name(portid, msg, offset);
+	cons_putchar(portid, '\n');
+	cons_printf(portid, "    rname:   ");
+	show_dns_domain_name(portid, msg, rn_offset);
+	cons_putchar(portid, '\n');
+
+	cons_printf(portid, "    serial:  %d\n", soa.serial);
+	cons_printf(portid, "    refresh: %d\n", soa.refresh);
+	cons_printf(portid, "    retry:   %d\n", soa.retry);
+	cons_printf(portid, "    expirel: %d\n", soa.expire);
+	cons_printf(portid, "    minimum: %d\n", soa.minimum);
+
+	return E_OK;
+	}
+
+/*
+ *  show_dns_qdsection -- DNS の Question セクションを表示する。
+ */
+
+static ER_UINT
+show_dns_qdsection (ID portid, uint8_t *msg, ER_UINT length, T_RSLV_DNS_MSG *rslv)
+{
+	T_RSLV_QD	qd;
+	ER_UINT		offset, error;
+	int		scount;
+
+	cons_printf(portid, "question   section: %d\n", rslv->dns_hdr.qdcount);
+	offset = rslv->qd_offset;
+	for (scount = 1; scount <= rslv->dns_hdr.qdcount; scount ++) {
+		if ((error = dns_analyze_qd(&qd, offset, msg, length)) < 0)
+			return error;
+
+		cons_printf(portid, "%2d: ", scount);
+		show_dns_domain_name(portid, msg, offset);
+		cons_printf(portid, "\n    type: %-4s, class: %2s\n", dns_strtype(qd.type), dns_strclass(qd.class));
+		offset = error;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  show_dns_section -- DNS の各セクションを表示する。
+ */
+
+static ER_UINT
+show_dns_section (ID portid, uint8_t *msg, ER_UINT length, uint_t scount, uint_t offset, char *title)
+{
+	T_RSLV_RR	rr;
+	T_IN4_ADDR	in4_addr;
+	ER_UINT		error;
+	int		count, dcount, col;
+	T_IN6_ADDR	in6_addr;
+
+	cons_printf(portid, "%10s section: %d\n", title, scount);
+	for (count = 1; count <= scount; count ++) {
+		if ((error = dns_analyze_rr(&rr, offset, msg, length)) < 0)
+			return error;
+
+		cons_printf(portid, "%2d: ", count);
+		show_dns_domain_name(portid, msg, offset);
+		cons_printf(portid, "\n    type: %-4s, class: %2s, TTL: %2d, len: %3d, offset: 0x%02x\n",
+		            dns_strtype(rr.type), dns_strclass(rr.class), rr.ttl, rr.rdlength, rr.rdata_offset);
+
+		switch (rr.type) {
+		case DNS_TYPE_A:
+			memcpy((void*)&in4_addr, (void*)(msg + rr.rdata_offset), sizeof(in4_addr));
+			in4_addr = ntohl(in4_addr);
+			cons_printf(portid, "    IPv4 addr: %hI\n", &in4_addr);
+			break;
+		case DNS_TYPE_NS:
+			cons_printf(portid, "    host: ");
+			show_dns_domain_name(portid, msg, rr.rdata_offset);
+			cons_putchar(portid, '\n');
+			break;
+		case DNS_TYPE_CNAME:
+			cons_printf(portid, "    host: ");
+			show_dns_domain_name(portid, msg, rr.rdata_offset);
+			cons_putchar(portid, '\n');
+			break;
+		case DNS_TYPE_SOA:
+			show_dns_soa(portid, msg, length, rr.rdata_offset);
+			break;
+		case DNS_TYPE_PTR:
+			cons_printf(portid, "     PTR: ");
+			show_dns_domain_name(portid, msg, rr.rdata_offset);
+			cons_putchar(portid, '\n');
+			break;
+		case DNS_TYPE_AAAA:
+			memcpy((void*)&in6_addr, (void*)(msg + rr.rdata_offset), sizeof(in6_addr));
+			cons_printf(portid, "    IPv6 addr: %lI\n", &in6_addr);
+			break;
+		default:
+			cons_printf(portid, "    data: ");
+			col = 32;
+			for (dcount = 0; dcount < rr.rdlength; dcount ++) {
+				cons_printf(portid, "%02x", *(msg + rr.rdata_offset + dcount));
+				if (-- col == 0) {
+					cons_printf(portid, "\n          ");
+					col = 32;
+					}
+				}
+			cons_putchar(portid, '\n');
+			break;
+			}
+		}
+
+	return E_OK;
+	}
+/*
+ *  dns_info -- DNS 情報の表示
+ */
+
+static void
+dns_info (ID portid)
+{
+#if defined(SUPPORT_INET6)
+	T_IN6_ADDR	in6_addr;
+#endif
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	in4_addr;
+#endif
+
+#if defined(SUPPORT_INET6)
+
+	cons_printf(portid, "domain name:     %s\n", dns_in6_get_dname());
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+	cons_printf(portid, "domain name:     %s\n", dns_in4_get_dname());
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET6)
+	dns_in6_get_addr(&in6_addr);
+	cons_printf(portid, "IPv6 DNS server: ");
+	if (IN6_IS_ADDR_UNSPECIFIED(&in6_addr))
+		cons_printf(portid, "not available.\n");
+	else
+		cons_printf(portid, "%lI.\n", &in6_addr);
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+	dns_in4_get_addr(&in4_addr);
+	cons_printf(portid, "IPv4 DNS server: ");
+	if (in4_addr == IPV4_ADDRANY)
+		cons_printf(portid, "not available.\n");
+	else
+		cons_printf(portid, "%hI.\n", &in4_addr);
+#endif	/* of #if defined(SUPPORT_INET4) */
+	}
+
+/*
+ *  name_lookup -- ホスト名－IP アドレス変換
+ */
+
+const char *rcode_str[] = {
+	"no error",
+	"format error",
+	"server error",
+	"name error",
+	"not implement",
+	"refused",
+	};
+
+static void
+name_lookup (ID portid, char *line)
+{
+	static char hostname[DBG_LINE_SIZE + 1];
+
+	T_RSLV_DNS_MSG	rslv;
+	ER_UINT		length, offset;
+	ER		error;
+	uint_t		flags = 0;
+	uint8_t 	*msg;
+
+	/* コマンドのオプションを設定する。*/
+	line = skip_blanks(resolv_options(&flags, line, DEFAULT_API_PROTO));
+	if ((flags & (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) == 0) {
+		cons_printf(portid, "DNS server not available.\n");
+		return;
+		}
+
+	/* 照会するホスト名・IP アドレスを解析する。*/
+	resolv_hoststr(&flags, hostname, sizeof(hostname), line);
+
+	/* 正引きでも逆引きでもプロトコル上は正引きを指定する。*/
+	flags |= DNS_LUP_OPCODE_FORWARD;
+
+	/* IPv6 アドレス、または IPv4 アドレスが指定された時は、照会タイプは PTR に設定する。*/
+	if (((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_IPV6) ||
+	    ((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_IPV4))
+		flags = (flags & ~DNS_LUP_FLAGS_QTYPE_MASK) | DNS_LUP_FLAGS_QTYPE_PTR;
+
+	if ((error = tget_mpf(MPF_RSLV_SRBUF, (void*)&msg, TMO_FEVR)) != E_OK) {
+		cons_printf(portid, "get buffer error: %s.\n", itron_strerror(error));
+		return;
+		}
+
+	if ((length = dns_lookup_host(flags | DNS_LUP_FLAGS_MSG, line, msg, DNS_UDP_MSG_LENGTH, &rslv)) < 0) {
+		//cons_printf(portid, "error: %s.\n", itron_strerror(length));
+		goto err_ret;
+		}
+
+	dly_tsk(1 * 1000);
+	cons_printf(portid, "DNS header: flags: ");
+	if (rslv.dns_hdr.code & (DNS_QR_RESPONSE | DNS_AUTHORITATIVE     |
+	                         DNS_TRUN_CATION | DNS_RECURSION_DESIRED | DNS_RECURSION_AVAILABLE)) {
+		cons_printf(portid, (rslv.dns_hdr.code & DNS_QR_RESPONSE)         ? "QR," : "");
+		cons_printf(portid, (rslv.dns_hdr.code & DNS_AUTHORITATIVE)       ? "AA," : "");
+		cons_printf(portid, (rslv.dns_hdr.code & DNS_TRUN_CATION)         ? "TC," : "");
+		cons_printf(portid, (rslv.dns_hdr.code & DNS_RECURSION_DESIRED)   ? "RD," : "");
+		cons_printf(portid, (rslv.dns_hdr.code & DNS_RECURSION_AVAILABLE) ? "RA," : "");
+		cons_printf(portid, " ");
+		}
+	cons_printf(portid, "opcode: ");
+	cons_printf(portid, (rslv.dns_hdr.code & DNS_OPCODE_REVERSE)      ? "RV"  : "FW");
+	cons_printf(portid, (rslv.dns_hdr.code & DNS_OPCODE_STATUS)       ? ",ST" : "");
+	cons_printf(portid, ", rcode: %s.\n",
+	            (rslv.dns_hdr.code & DNS_RCODE_MASK) > DNS_RCODE_REFUSED
+	            	? "6" : rcode_str[rslv.dns_hdr.code & DNS_RCODE_MASK]);
+
+	if ((offset = show_dns_qdsection(portid, msg, length, &rslv)) < 0) {
+		cons_printf(portid, "msg error: %s.\n", itron_strerror(offset));
+		}
+	if ((offset = show_dns_section(portid, msg, length, rslv.dns_hdr.ancount, rslv.an_offset, "answer")) < 0) {
+		cons_printf(portid, "msg error: %s.\n", itron_strerror(offset));
+		}
+	if ((offset = show_dns_section(portid, msg, length, rslv.dns_hdr.nscount, rslv.ns_offset, "authority")) < 0) {
+		cons_printf(portid, "msg error: %s.\n", itron_strerror(offset));
+		}
+	if ((offset = show_dns_section(portid, msg, length, rslv.dns_hdr.arcount, rslv.ar_offset, "additional")) < 0) {
+		cons_printf(portid, "msg error: %s.\n", itron_strerror(offset));
+		}
+
+err_ret:
+	if ((error = rel_mpf(MPF_RSLV_SRBUF, msg)) != E_OK)
+		cons_printf(portid, "release buffer error: %s.\n", itron_strerror(error));
+	return;
+	}
+
+#endif	 /* of #ifdef USE_RESOLVER */
+
+#if defined(DHCP6_CLI_CFG)
+
+/*
+ *  dhcp6c_info -- DHCPv6 クライアント情報の表示
+ */
+
+static void
+dhcp6c_info (ID portid)
+{
+	T_IN6_ADDR	svaddr;
+	SYSTIM		bind_start;
+	ER		error;
+	uint32_t	expire, renew, rebind, deprefer;
+
+	if ((error = dhcp6c_get_info(&svaddr, &expire, &renew, &rebind, &deprefer, &bind_start)) == E_OK) {
+		cons_printf(portid, "      DHCPv6 server: %lI.\n", &svaddr);
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+	
+		cons_printf(portid, "      DHCPv6 mode:   stateless.\n");
+
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+		cons_printf(portid, "      DHCPv6 mode:   statefull,\n");
+		cons_printf(portid, "        Renew:       %u:%02u:%02u, Deprefer: %u:%02u:%02u,\n",
+		                       renew / 3600, (   renew / 60) % 60,    renew % 60,
+		                    deprefer / 3600, (deprefer / 60) % 60, deprefer % 60);
+		cons_printf(portid, "        Rebind:      %u:%02u:%02u, Expire:   %u:%02u:%02u.\n",
+		                      rebind / 3600, (  rebind / 60) % 60,   rebind % 60,
+		                      expire / 3600, (  expire / 60) % 60,   expire % 60);
+
+#else	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+		}
+	else if (error == E_OBJ)
+		cons_printf(portid, "      DHCPv6 server: not available.\n");
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG) */
+
+#if defined(DHCP4_CLI_CFG)
+
+/*
+ *  dhcp4c_info -- DHCPv4 クライアント情報の表示
+ */
+
+static void
+dhcp4c_info (ID portid)
+{
+	T_IN4_ADDR	svaddr;
+	SYSTIM		bind_start;
+	ER		error;
+	uint32_t	expire, renew, rebind;
+
+	if ((error = dhcp4c_get_info(&svaddr, &expire, &renew, &rebind, &bind_start)) == E_OK) {
+		cons_printf(portid, "      DHCPv4 server: %hI,\n", &svaddr);
+		cons_printf(portid, "        Renew:       %u:%02u:%02u,\n", 
+		                      renew  / 3600, (renew  / 60) % 60, renew % 60);
+		cons_printf(portid, "        Rebind:      %u:%02u:%02u, Expire:   %u:%02u:%02u.\n",
+		                      rebind / 3600, (rebind / 60) % 60, rebind % 60,
+		                      expire / 3600, (expire / 60) % 60, expire % 60);
+		}
+	else if (error == E_OBJ)
+		cons_printf(portid, "      DHCPv4 server: not available.\n");
+	}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG) */
+
+#if defined(DHCP6_CLI_CFG) || defined(DHCP4_CLI_CFG)
+
+/*
+ *  dhcpc -- DHCP クライアント情報の表示と制御
+ */
+
+static void
+dhcpc (ID portid, char *line)
+{
+	WAI_NET_CONS_PRINTF();
+
+	switch (*line) {
+
+#if defined(DHCP6_CLI_CFG)
+	case '6':			/* DHCPv6 の制御 */
+		switch (*(line + 1)) {
+		case 'r':		/* アドレス情報を解放する。*/
+			dhcp6c_rel_info();
+			break;
+
+		case 'n':		/* アドレス情報を再取得する。*/
+			dhcp6c_renew_info();
+			break;
+
+		default:
+			dhcp6c_info(portid);
+			break;
+			}
+		break;
+#endif	/* of #if defined(DHCP6_CLI_CFG) */
+
+#if defined(DHCP4_CLI_CFG)
+	case '4':		/* DHCPv4 の制御 */
+		switch (*(line + 1)) {
+		case 'r':		/* アドレス情報を解放する。*/
+			dhcp4c_rel_info();
+			break;
+
+		case 'n':		/* アドレス情報を再取得する。*/
+			dhcp4c_renew_info();
+			break;
+
+		default:
+			dhcp4c_info(portid);
+			break;
+			}
+		break;
+#endif	/* of #if defined(DHCP4_CLI_CFG) */
+
+	default:
+
+#if defined(DHCP6_CLI_CFG)
+		dhcp6c_info(portid);
+#endif
+
+#if defined(DHCP4_CLI_CFG)
+		dhcp4c_info(portid);
+#endif
+		break;
+		}
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG) || defined(DHCP4_CLI_CFG) */
+
+#if defined(SUPPORT_INET6)
+
+#if NUM_ND6_DEF_RTR_ENTRY > 0
+
+/*
+ *  defrtrlist_status -- ディフォルトルータ・リスト状態の出力
+ */
+
+static void
+defrtrlist_status (ID portid, char *line)
+{
+	const T_DEF_ROUTER	*dr;
+	SYSTIM			now;
+	int_t			rix, pix, pcnt, ptitle;
+	uint_t			count, mask;
+
+	WAI_NET_CONS_PRINTF();
+	cons_printf(portid,
+	            "Default Router List Status\n"
+	            "IX Expire Lifetime flags prefix");
+	for (ptitle = NUM_ND6_PREFIX_ENTRY * 2 - sizeof("prefix"); ptitle -- > 0; )
+		cons_printf(portid, " ");
+	cons_printf(portid, " IP Address\n");
+
+	/* expire の単位は [us]。*/
+	get_tim(&now);
+	dr = nd6_get_drl(&count);
+	for (rix = 0; rix < count; rix ++) {
+		if (dr[rix].state == ND6_DEF_RTR_BUSY) {
+			cons_printf(portid, "%2d", rix);
+			if (dr[rix].lifetime == ND6_INFINITE_LIFETIME)
+				cons_printf(portid, "  INFIN    INFIN");
+			else
+				cons_printf(portid, " %6d %8d",
+				            (uint32_t)(dr[rix].expire - now) <= 0
+				                ? 0 : (dr[rix].expire - now) / SYSTIM_HZ,
+				            dr[rix].lifetime / SYSTIM_HZ);
+			cons_printf(portid, "    %02x", dr[rix].flags);
+			pcnt = NUM_ND6_PREFIX_ENTRY;
+			ptitle = NUM_ND6_PREFIX_ENTRY * 2 - sizeof(" prefix");
+			mask = 1;
+			for (pix = 0; pix < NUM_ND6_PREFIX_ENTRY; pix ++) {
+				if ((dr[rix].plistmap & mask) != 0) {
+					if (pcnt == NUM_ND6_PREFIX_ENTRY)
+						cons_printf(portid, " ");
+					else
+						cons_printf(portid, ",");
+					cons_printf(portid, "%d", pix);
+					pcnt --;
+					ptitle -= 2;
+					}
+				mask <<= 1;
+				}
+			while (pcnt --) {
+				cons_printf(portid, "  ");
+				ptitle -= 2;
+				}
+			while (ptitle -- > 0)
+				cons_printf(portid, " ");
+			cons_printf(portid, " %lI\n",  &dr[rix].addr);
+			}
+		}
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+/*
+ *  prefixlist_status -- プレフィックス・リスト状態の出力
+ */
+
+static void
+prefixlist_status (ID portid, char *line)
+{
+	const T_ND6_PREFIX	*pr;
+	SYSTIM			now;
+	int_t			rix, pix, rcnt, rtitle;
+	uint_t			mask;
+
+	WAI_NET_CONS_PRINTF();
+	cons_printf(portid,
+	            "Prefix List Status\n"
+	            "IX  Expire Lifetime flags router");
+	for (rtitle = NUM_ND6_DEF_RTR_ENTRY * 2 - sizeof("router"); rtitle -- > 0; )
+		cons_printf(portid, " ");
+	cons_printf(portid, " Len Prefix\n");
+
+	/* expire の単位は [s]。*/
+	get_tim(&now);
+	now /= SYSTIM_HZ;
+	pr = nd6_get_prl();
+	for (pix = 0; pix < NUM_ND6_PREFIX_ENTRY; pix ++) {
+		if ((pr[pix].flags & ND6_PREFIX_STATE_BUSY) != 0) {
+			cons_printf(portid, "%2d", pix);
+			if (pr[pix].vltime == ND6_INFINITE_LIFETIME)
+				cons_printf(portid, "  INFIN    INFIN");
+			else
+				cons_printf(portid, " %7d %8d",
+				            (uint32_t)(pr[pix].expire - now) <= 0
+				                ? 0 : (pr[pix].expire - now),
+				             pr[pix].vltime);
+			cons_printf(portid, "    %02x", pr[pix].flags);
+			rcnt = NUM_ND6_DEF_RTR_ENTRY;
+			rtitle = NUM_ND6_DEF_RTR_ENTRY * 2 - sizeof(" router");
+			mask = 1;
+			for (rix = 0; rix < NUM_ND6_DEF_RTR_ENTRY; rix ++) {
+				if ((pr[pix].routermap & mask) != 0) {
+					if (rcnt == NUM_ND6_DEF_RTR_ENTRY)
+						cons_printf(portid, " ");
+					else
+						cons_printf(portid, ",");
+					cons_printf(portid, "%d", rix);
+					rcnt --;
+					rtitle -= 2;
+					}
+				mask <<= 1;
+				}
+			while (rcnt --) {
+				cons_printf(portid, "  ");
+				rtitle -= 2;
+				}
+			while (rtitle -- > 0)
+				cons_printf(portid, " ");
+			cons_printf(portid, "%4d %lI\n",  pr[pix].prefix_len, &pr[pix].prefix);
+			}
+		}
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #if NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+#if NUM_IN6_ROUTE_ENTRY > 0
+
+/*
+ *  routing6_table_status -- 経路表（IPv6）の出力
+ */
+
+static void
+routing6_table_status (ID portid, char *line)
+{
+	SYSTIM	now;
+	int_t	ix;
+
+	WAI_NET_CONS_PRINTF();
+	cons_printf(portid,
+	            "\nRouting Table Status (IPv6)\n"
+	            "IX Expire flags Prefix Target                         Gateway\n");
+
+	for (ix = 0; ix < NUM_IN6_STATIC_ROUTE_ENTRY; ix ++) {
+		cons_printf(portid, "%2d STATIC     - %6d %30lI %lI\n",
+		            ix,
+		             routing6_tbl[ix].prefix_len,
+		            &routing6_tbl[ix].target,
+		            &routing6_tbl[ix].gateway);
+		            
+		}
+
+	/* expire の単位は [s]。*/
+	get_tim(&now);
+	now /= SYSTIM_HZ;
+
+	for ( ; ix < NUM_IN6_ROUTE_ENTRY; ix ++)
+		if (routing6_tbl[ix].flags & IN_RTF_DEFINED)
+			cons_printf(portid, "%2d %6d    %02x %6d %30lI %lI\n",
+			            ix,
+			            (uint32_t)(routing6_tbl[ix].expire - now) <= 0
+			                ? 0 : routing6_tbl[ix].expire - now,
+			             routing6_tbl[ix].flags,
+			             routing6_tbl[ix].prefix_len,
+			            &routing6_tbl[ix].target,
+			            &routing6_tbl[ix].gateway);
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #if NUM_IN6_ROUTE_ENTRY > 0 */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#if NUM_IN4_ROUTE_ENTRY > 0
+
+/*
+ *  routing4_table_status -- 経路表（IPv4）の出力
+ */
+
+static void
+routing4_table_status (ID portid, char *line)
+{
+	int_t	ix;
+
+	if ('0' <= *(line = skip_blanks(line)) && *line <= '9') {
+		T_IN4_ADDR	target, mask, gateway;
+
+		ix = atoi(line);
+		while ('0' <= *line && *line <= '9')
+			line ++;
+		line = get_ipv4addr(&target,  skip_blanks(line));
+		line = get_ipv4addr(&mask,    skip_blanks(line));
+		       get_ipv4addr(&gateway, skip_blanks(line));
+		in4_add_route(ix, target, mask, gateway);
+		}
+
+	WAI_NET_CONS_PRINTF();
+	cons_printf(portid,
+	            "\nRouting Table Status (IPv4)\n"
+	            "IX Target          Mask            Gateway         Expire\n");
+
+	for (ix = 0; ix < NUM_IN4_ROUTE_ENTRY; ix ++) {
+		if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) == 0)
+			;
+		else if ((routing4_tbl[ix].flags & IN_RTF_REDIRECT) != 0)
+			cons_printf(portid, "%2d %15hI %15hI %15hI %4d\n",
+			            ix,
+			            &routing4_tbl[ix].target,
+			            &routing4_tbl[ix].mask,
+			            &routing4_tbl[ix].gateway,
+			            &routing4_tbl[ix].expire);
+		else
+			cons_printf(portid, "%2d %15hI %15hI %hI\n",
+			            ix,
+			            &routing4_tbl[ix].target,
+			            &routing4_tbl[ix].mask,
+			            &routing4_tbl[ix].gateway);
+		            
+		}
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #if NUM_IN4_ROUTE_ENTRY > 0 */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+/*
+ *  routing_status -- 経路情報
+ */
+
+static void
+routing_status (ID portid, char *line)
+{
+	switch (*line) {
+
+#if defined(SUPPORT_INET6) && NUM_ND6_DEF_RTR_ENTRY > 0
+
+	case 'l':		/* ディフォルトルータ・リスト情報 */
+		defrtrlist_status(portid, line + 1);
+		break;
+
+	case 'p':		/* プレフィックス・リスト情報 */
+		prefixlist_status(portid, line + 1);
+		break;
+
+#endif	/* #if defined(SUPPORT_INET6) && NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+	default:
+
+		/* 経路表情報 */
+
+#if defined(SUPPORT_INET6) && NUM_IN6_ROUTE_ENTRY > 0
+		routing6_table_status(portid, line);
+#endif
+
+#if defined(SUPPORT_INET4) && NUM_IN4_ROUTE_ENTRY > 0
+		routing4_table_status(portid, line);
+#endif
+
+		break;
+		}
+	}
+
+/*
+ *  dbg_cons_network_status -- ネットワークの状態の出力
+ */
+
+void
+dbg_cons_network_status (ID portid, char *line)
+{
+	switch (*line) {
+
+#ifdef SUPPORT_ETHER
+
+	case 'a':		/* IF アドレス情報 */
+
+#if defined(SUPPORT_INET6)
+		ifa6_status(portid, line + 1);
+#endif
+#if defined(SUPPORT_INET4)
+		ifa4_status(portid, line + 1);
+#endif
+
+		break;
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+	case 'b':		/* ネットワークバッファ情報 */
+		nbuf_status(portid, line + 1);
+		break;
+
+#if NET_COUNT_ENABLE
+
+	case 'c':		/* ネットワーク統計情報 */
+		net_count(portid, line + 1);
+		break;
+
+#endif	/* of #if NET_COUNT_ENABLE */
+
+	case 'r':		/* 経路情報 */
+		routing_status(portid, line + 1);
+		break;
+
+#ifdef USE_RESOLVER
+
+	case 's':		/* name lookup */
+		if (*(line = skip_blanks(line + 1)) == '\0')
+			dns_info(portid);
+		else
+			name_lookup(portid, line);
+		break;
+
+#endif	 /* of #ifdef USE_RESOLVER */
+
+#ifdef SUPPORT_TCP
+
+	case 't':		/* TCP status */
+		tcp_status(portid, line + 1);
+		break;
+
+#endif	 /* of #ifdef SUPPORT_TCP */
+
+#ifdef SUPPORT_UDP
+
+	case 'u':		/* UDP status */
+		udp_status(portid, line + 1);
+		break;
+
+#endif	 /* of #ifdef SUPPORT_UDP */
+
+	default:
+		cons_printf(portid, "no such command: '%c%c'.\n", *(line - 1), *line);
+		SIG_NET_CONS_PRINTF();
+		FLUSH_SND_BUFF();
+		break;
+		}
+	}
+
+/*
+ *  dbg_cons_ifconfig -- ネットワークインタフェースの構成情報
+ */
+
+void
+dbg_cons_ifconfig (ID portid, char *line)
+{
+#ifdef SUPPORT_ETHER
+
+	T_IF_SOFTC	*ic;
+
+	WAI_NET_CONS_PRINTF();
+	ic = IF_ETHER_NIC_GET_SOFTC();
+	cons_printf(portid, "ether: %M\n", ic->ifaddr.lladdr);
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+	}
+
+#if defined(NETAPP_IP6_CFG)
+
+/*
+ *  dbg_cons_ifconfig6 -- ネットワークインタフェース（IPv6）の構成情報
+ */
+
+void
+dbg_cons_ifconfig6 (ID portid, char *line)
+{
+#ifdef SUPPORT_ETHER
+
+	T_IFNET		*ifp = IF_GET_IFNET();
+	int_t		ix;
+	SYSTIM		now;
+
+	WAI_NET_CONS_PRINTF();
+
+	/* expire と vltime の単位は [s]。*/
+	get_tim(&now);
+	now /= SYSTIM_HZ;
+
+	cons_printf(portid, "IPv6:\nIX   Expire Preffered RTR PFX Flags IP Address\n");
+	for (ix = 0; ix < NUM_IN6_IFADDR_ENTRY; ix ++) {
+		if (ifp->in6_ifaddrs[ix].flags & IN6_IFF_DEFINED) {
+			cons_printf(portid, " %d", ix);
+			if (ifp->in6_ifaddrs[ix].lifetime.vltime == ND6_INFINITE_LIFETIME)
+				cons_printf(portid, "    INFIN     INFIN");
+			else
+				cons_printf(portid, " %8d %9d",
+				                    (uint32_t)(ifp->in6_ifaddrs[ix].lifetime.expire - now) <= 0 
+				                         ? 0 : ifp->in6_ifaddrs[ix].lifetime.expire - now,
+				                    (uint32_t)(ifp->in6_ifaddrs[ix].lifetime.preferred - now) <= 0
+				                         ? 0 : ifp->in6_ifaddrs[ix].lifetime.preferred - now);
+			if (ifp->in6_ifaddrs[ix].router_index == IN6_RTR_IX_UNREACH)
+				cons_printf(portid, "   -");
+			else
+				cons_printf(portid, " %3d", ifp->in6_ifaddrs[ix].router_index);
+			if (ifp->in6_ifaddrs[ix].prefix_index == ND6_PREFIX_IX_INVALID)
+				cons_printf(portid, "   -");
+			else
+				cons_printf(portid, " %3d", ifp->in6_ifaddrs[ix].prefix_index);
+			cons_printf(portid, "    %02x %lI\n",
+			                     ifp->in6_ifaddrs[ix].flags,
+			                    &ifp->in6_ifaddrs[ix].addr);
+			}
+		}
+
+#ifdef DHCP6_CLI_CFG
+	dhcp6c_info(portid);
+#endif
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+	}
+
+#endif	/* of #if defined(NETAPP_IP6_CFG) */
+
+#if defined(NETAPP_IP4_CFG)
+
+/*
+ *  dbg_cons_ifconfig4 -- ネットワークインタフェース（IPv4）の構成情報
+ */
+
+void
+dbg_cons_ifconfig4 (ID portid, char *line)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN4_ADDR	bc;
+
+#ifdef SUPPORT_ETHER
+
+	if (*(line = skip_blanks(line))) {
+		T_IN4_ADDR	addr, mask;
+
+		get_ipv4addr(&mask, skip_blanks(get_ipv4addr(&addr, line)));
+		in4_add_ifaddr(addr, mask);
+		}
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+	WAI_NET_CONS_PRINTF();
+
+	bc = (ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask;
+	cons_printf(portid,
+	            "IPv4: %hI, mask: %hI, broadcast: %hI\n",
+	            &ifp->in4_ifaddr.addr,
+	            &ifp->in4_ifaddr.mask,
+	            &bc);
+
+#ifdef DHCP4_CLI_CFG
+	dhcp4c_info(portid);
+#endif
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #if defined(NETAPP_IP4_CFG) */
+
+/*
+ *  dbg_cons_show_config -- コンフィギュレーション設定の表示
+ */
+
+void
+dbg_cons_show_config (ID portid, char *line)
+{
+#if defined(SUPPORT_ETHER)
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	addr;
+#endif
+#endif	/* of #if defined(SUPPORT_ETHER) */
+
+	cons_printf(portid, "DHCP:\n");
+	cons_printf(portid, "  DHCP6_CLI_CFG: ");
+
+#if defined(DHCP6_CLI_CFG)
+
+	cons_printf(portid, "On\n           Mode: ");
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+	cons_printf(portid, "STATELESS\n");
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+	cons_printf(portid, "STATEFULL\n");
+#endif
+
+#else	/* of #if define(DHCP6_CLI_CFG) */
+
+	cons_printf(portid, "Off\n");
+
+#endif	/* of #if define(DHCP6_CLI_CFG) */
+
+	cons_printf(portid, "  DHCP4_CLI_CFG: ");
+
+#if defined(DHCP4_CLI_CFG)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "Resolver:\n");
+	cons_printf(portid, "  USE_RESOLVER: ");
+
+#if defined(USE_RESOLVER)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+#if defined(SUPPORT_TCP)
+
+	cons_printf(portid, "TCP:\n");
+
+	cons_printf(portid, "  TCP_CFG_OPT_MSS:      ");
+#if defined(TCP_CFG_OPT_MSS)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  TCP_CFG_DELAY_ACK:    ");
+#if defined(TCP_CFG_DELAY_ACK)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  TCP_CFG_ALWAYS_KEEP:  ");
+#if defined(TCP_CFG_ALWAYS_KEEP)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  TCP_CFG_RWBUF_CSAVE:  ");
+#if defined(TCP_CFG_RWBUF_CSAVE_ONLY)
+	cons_printf(portid, "Only, ");
+#if defined(TCP_CFG_RWBUF_CSAVE_MAX_QUEUES)
+	cons_printf(portid, "TCP_CFG_RWBUF_CSAVE_MAX_QUEUES: %2d\n",
+	                     TCP_CFG_RWBUF_CSAVE_MAX_QUEUES);
+#else
+	cons_printf(portid, "TCP_CFG_RWBUF_CSAVE_MAX_QUEUES: Undefined\n");
+#endif
+#elif defined(TCP_CFG_RWBUF_CSAVE)
+	cons_printf(portid, "On,   ");
+#if defined(TCP_CFG_RWBUF_CSAVE_MAX_QUEUES)
+	cons_printf(portid, "TCP_CFG_RWBUF_CSAVE_MAX_QUEUES: %2d\n",
+	                     TCP_CFG_RWBUF_CSAVE_MAX_QUEUES);
+#else
+	cons_printf(portid, "TCP_CFG_RWBUF_CSAVE_MAX_QUEUES: Undefined\n");
+#endif
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  TCP_CFG_SWBUF_CSAVE:  ");
+#if defined(TCP_CFG_SWBUF_CSAVE_ONLY)
+	cons_printf(portid, "Only, TCP_CFG_SWBUF_CSAVE_MAX_SIZE: %4d\n"
+	                    "                        "
+	                    "      TCP_CFG_SWBUF_CSAVE_MIN_SIZE: %4d\n",
+	                    TCP_CFG_SWBUF_CSAVE_MAX_SIZE, 
+                            TCP_CFG_SWBUF_CSAVE_MIN_SIZE);
+#elif defined(TCP_CFG_SWBUF_CSAVE)
+	cons_printf(portid, "On,   TCP_CFG_SWBUF_CSAVE_MAX_SIZE: %4d\n"
+	                    "                        "
+	                    "      TCP_CFG_SWBUF_CSAVE_MIN_SIZE: %4d\n",
+	                    TCP_CFG_SWBUF_CSAVE_MAX_SIZE, 
+                            TCP_CFG_SWBUF_CSAVE_MIN_SIZE);
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  TCP_CFG_NON_BLOCKING: ");
+#if defined(TCP_CFG_NON_BLOCKING)
+#if defined(USE_TCP_NON_BLOCKING)
+	cons_printf(portid, "Use\n");
+#else
+	cons_printf(portid, "On\n");
+#endif
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  TCP_CFG_NON_BLOCKING_COMPAT14: ");
+#if defined(TCP_CFG_NON_BLOCKING_COMPAT14)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  TCP_CFG_EXTENTIONS:   ");
+#if defined(TCP_CFG_EXTENTIONS)
+#if defined(USE_TCP_EXTENTIONS)
+	cons_printf(portid, "Use\n");
+#if defined(SUPPORT_INET6)
+	cons_printf(portid, "  NUM_VRID_TCP6_REPS:   %3d\n", NUM_VRID_TCP6_REPS);
+	cons_printf(portid, "  NUM_VRID_TCP6_CEPS:   %3d\n", NUM_VRID_TCP6_CEPS);
+#endif
+#if defined(SUPPORT_INET4)
+	cons_printf(portid, "  NUM_VRID_TCP4_REPS:   %3d\n", NUM_VRID_TCP4_REPS);
+	cons_printf(portid, "  NUM_VRID_TCP4_CEPS:   %3d\n", NUM_VRID_TCP4_CEPS);
+#endif
+#else
+	cons_printf(portid, "On\n");
+#endif
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  USE_COPYSAVE_API:     ");
+#if defined(USE_COPYSAVE_API)
+	cons_printf(portid, "Use\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+#if NUM_TCP_TW_CEP_ENTRY > 0
+	cons_printf(portid, "  TCP_TW_CEP:           On, NUM_TCP_TW_CEP_ENTRY:     %d\n", NUM_TCP_TW_CEP_ENTRY);
+#else
+	cons_printf(portid, "  TCP_TW_CEP:           Off\n");
+#endif
+
+#if defined(TCP_CFG_TRACE)
+	cons_printf(portid, "  TCP_CFG_TRACE:        On, TCP_CFG_TRACE_LPORTNO:    %d\n", TCP_CFG_TRACE_LPORTNO);
+#if defined(SUPPORT_INET4)
+	addr = TCP_CFG_TRACE_IPV4_RADDR;
+	cons_printf(portid, "                            TCP_CFG_TRACE_IPV4_RADDR: %hI\n", &addr);
+#endif
+	cons_printf(portid, "                            TCP_CFG_TRACE_RPORTNO:    %d\n", TCP_CFG_TRACE_RPORTNO);
+#else
+	cons_printf(portid, "  TCP_CFG_TRACE:        Off\n");
+#endif
+
+	cons_printf(portid, "  MAX_TCP_SND_SEG:      %4d\n", MAX_TCP_SND_SEG);
+	cons_printf(portid, "  DEF_TCP_SND_SEG:      %4d\n", DEF_TCP_SND_SEG);
+	cons_printf(portid, "  MAX_TCP_RCV_SEG:      %4d\n", MAX_TCP_RCV_SEG);
+	cons_printf(portid, "  DEF_TCP_RCV_SEG:      %4d\n", DEF_TCP_RCV_SEG);
+	cons_printf(portid, "  MAX_TCP_REALLOC_SIZE: %4d\n", MAX_TCP_REALLOC_SIZE);
+
+#endif	/* of #if defined(SUPPORT_TCP) */
+
+#if defined(SUPPORT_UDP)
+
+	cons_printf(portid, "UDP:\n");
+
+	cons_printf(portid, "  UDP_CFG_IN_CHECKSUM:  ");
+#if defined(UDP_CFG_IN_CHECKSUM)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  UDP_CFG_OUT_CHECKSUM: ");
+#if defined(UDP_CFG_OUT_CHECKSUM)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  UDP_CFG_NON_BLOCKING: ");
+#if defined(UDP_CFG_NON_BLOCKING)
+#if defined(USE_UDP_NON_BLOCKING)
+	cons_printf(portid, "Use\n");
+#else
+	cons_printf(portid, "On\n");
+#endif
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  UDP_CFG_NON_BLOCKING_COMPAT14: ");
+#if defined(UDP_CFG_NON_BLOCKING_COMPAT14)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  UDP_CFG_EXTENTIONS:   ");
+#if defined(UDP_CFG_EXTENTIONS)
+#if defined(USE_UDP_EXTENTIONS)
+	cons_printf(portid, "Use\n");
+#else
+	cons_printf(portid, "On\n");
+#endif
+	cons_printf(portid, "  NUM_VRID_UDP4_CEPS:   %3d\n", NUM_VRID_UDP4_CEPS);
+	cons_printf(portid, "  NUM_VRID_UDP6_CEPS:   %3d\n", NUM_VRID_UDP6_CEPS);
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  NUM_DTQ_UDP_RCVQ:     %3d\n", NUM_DTQ_UDP_RCVQ);
+	cons_printf(portid, "  NUM_DTQ_UDP_OUTPUT:   %3d\n", NUM_DTQ_UDP_OUTPUT);
+
+#endif	/* of #if defined(SUPPORT_UDP) */
+
+	cons_printf(portid, "ICMP:\n");
+
+	cons_printf(portid, "  ICMP_CFG_CALLBACK_ECHO_REPLY: ");
+#if defined(ICMP_CFG_CALLBACK_ECHO_REPLY)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  ICMP_REPLY_ERROR:             ");
+#if defined(ICMP_REPLY_ERROR)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+#if defined(NUM_REDIRECT_ROUTE_ENTRY)
+#if NUM_REDIRECT_ROUTE_ENTRY > 0
+	cons_printf(portid, "  TMO_IN_REDIRECT: %4d[s]\n", TMO_IN_REDIRECT / NET_TIMER_HZ);
+#endif
+#endif	/* of #if defined(NUM_REDIRECT_ROUTE_ENTRY) */
+
+#if defined(SUPPORT_INET6)
+
+	cons_printf(portid, "IPv6:\n");
+
+	cons_printf(portid, "  IP6_IPV4_MAPPED_ADDR:   ");
+#if defined(IP6_CFG_IPV4_MAPPED_ADDR)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  Routing Table:\n");
+	cons_printf(portid, "    NUM_IN6_STATIC_ROUTE_ENTRY:   %d\n", NUM_IN6_STATIC_ROUTE_ENTRY);
+	cons_printf(portid, "    NUM_IN6_REDIRECT_ROUTE_ENTRY: %d\n", NUM_IN6_REDIRECT_ROUTE_ENTRY);
+
+	cons_printf(portid, "ND:\n");
+	cons_printf(portid, "  TMO_ND6_RTR_SOL_DELAY:    %5d[us]\n", TMO_ND6_RTR_SOL_DELAY);
+	cons_printf(portid, "  TMO_ND6_RTR_SOL_INTERVAL: %5d[us]\n", TMO_ND6_RTR_SOL_INTERVAL);
+	cons_printf(portid, "  NUM_IP6_DAD_COUNT:        %5d\n",     NUM_IP6_DAD_COUNT);
+	cons_printf(portid, "  NUM_ND6_CACHE_ENTRY:      %5d\n",     NUM_ND6_CACHE_ENTRY);
+
+#if defined(SUPPORT_ETHER)
+
+	cons_printf(portid, "  NUM_ND6_DEF_RTR_ENTRY     %5d\n",     NUM_ND6_DEF_RTR_ENTRY);
+	cons_printf(portid, "  NUM_ND6_RTR_SOL_RETRY     %5d\n",     NUM_ND6_RTR_SOL_RETRY);
+
+	cons_printf(portid, "  IP6_CFG_AUTO_LINKLOCAL: ");
+#if defined(IP6_CFG_AUTO_LINKLOCAL)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+#endif	/* of #if defined(SUPPORT_ETHER) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+	cons_printf(portid, "IPv4:\n");
+
+	cons_printf(portid, "  IP4_CFG_FRAGMENT: ");
+
+#if defined(IP4_CFG_FRAGMENT)
+	cons_printf(portid, "On\n");
+	cons_printf(portid, "    NUM_IP4_FRAG_QUEUE:       %4d\n", NUM_IP4_FRAG_QUEUE);
+	cons_printf(portid, "    IP4_CFG_FRAG_REASSM_SIZE: %4d\n", IP4_CFG_FRAG_REASSM_SIZE);
+#else
+	cons_printf(portid, "Off\n");
+#endif	/* of #if defined(IP4_CFG_FRAGMENT) */
+
+#if defined(SUPPORT_ETHER)
+	addr = IPV4_ADDR_LOCAL;
+	cons_printf(portid, "  IPV4_ADDR_LOCAL:      %hI\n", &addr);
+	addr = IPV4_ADDR_LOCAL_MASK;
+	cons_printf(portid, "  IPV4_ADDR_LOCAL_MASK: %hI\n", &addr);
+	addr = IPV4_ADDR_DEFAULT_GW;
+	cons_printf(portid, "  IPV4_ADDR_DEFAULT_GW: %hI\n", &addr);
+#endif	/* of #if defined(SUPPORT_ETHER) */
+
+	cons_printf(portid, "  Routing Table:\n");
+	cons_printf(portid, "    NUM_IN4_STATIC_ROUTE_ENTRY:   %d\n", NUM_IN4_STATIC_ROUTE_ENTRY);
+	cons_printf(portid, "    NUM_IN4_REDIRECT_ROUTE_ENTRY: %d\n", NUM_IN4_REDIRECT_ROUTE_ENTRY);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET4) && defined(SUPPORT_ETHER)
+
+	cons_printf(portid, "ARP:\n");
+	cons_printf(portid, "  ARP_CACHE_KEEP: %4d[s]\n", ARP_CACHE_KEEP / NET_TIMER_HZ);
+
+#endif	/* of #if defined(SUPPORT_INET4) && defined(SUPPORT_ETHER) */
+
+#if defined(SUPPORT_ETHER)
+
+	cons_printf(portid, "Ethernet:\n");
+
+	cons_printf(portid, "  NUM_DTQ_ETHER_OUTPUT:    %3d\n", NUM_DTQ_ETHER_OUTPUT);
+
+	cons_printf(portid, "  ETHER_CFG_ACCEPT_ALL:    ");
+#if defined(ETHER_CFG_ACCEPT_ALL)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  ETHER_CFG_UNEXP_WARNING: ");
+#if defined(ETHER_CFG_UNEXP_WARNING)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  ETHER_CFG_802_WARNING:   ");
+#if defined(ETHER_CFG_802_WARNING)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  ETHER_CFG_MCAST_WARNING: ");
+#if defined(ETHER_CFG_MCAST_WARNING)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "  ETHER_COLLECT_ADDR:      ");
+#if defined(ETHER_COLLECT_ADDR)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+#endif	/* of #if defined(SUPPORT_ETHER) */
+
+#if defined(SUPPORT_PPP)
+
+	cons_printf(portid, "PPP:\n");
+
+	cons_printf(portid, "  HDLC_PORTNO: %d", HDLC_PORTID);
+
+	cons_printf(portid, "  PPP_IDLE_TIMEOUT: ");
+#if defined(PPP_IDLE_TIMEOUT)
+	cons_printf(portid, "  %4d[s]\n", PPP_IDLE_TIMEOUT / NET_TIMER_HZ);
+#else
+	cons_printf(portid, "  Off\n");
+#endif
+
+	cons_printf(portid, "  PPP_CFG_MODEM: ");
+#if defined(PPP_CFG_MODEM)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+#endif	/* of #if defined(SUPPORT_PPP) */
+
+	cons_printf(portid, "Network Buffer:\n");
+
+#if defined(NUM_MPF_NET_BUF_64)
+	cons_printf(portid, "  NUM_MPF_NET_BUF_64:        %2d\n", NUM_MPF_NET_BUF_64);
+#endif
+
+#if defined(NUM_MPF_NET_BUF_CSEG)
+	cons_printf(portid, "  NUM_MPF_NET_BUF_CSEG:      %2d\n", NUM_MPF_NET_BUF_CSEG);
+#endif
+
+#if defined(NUM_MPF_NET_BUF_128)
+	cons_printf(portid, "  NUM_MPF_NET_BUF_128:       %2d\n", NUM_MPF_NET_BUF_128);
+#endif
+
+#if defined(NUM_MPF_NET_BUF_256)
+	cons_printf(portid, "  NUM_MPF_NET_BUF_256:       %2d\n", NUM_MPF_NET_BUF_256);
+#endif
+
+#if defined(NUM_MPF_NET_BUF_512)
+	cons_printf(portid, "  NUM_MPF_NET_BUF_512:       %2d\n", NUM_MPF_NET_BUF_512);
+#endif
+
+#if defined(NUM_MPF_NET_BUF_IP_MSS)
+	cons_printf(portid, "  NUM_MPF_NET_BUF_IP_MSS:    %2d\n", NUM_MPF_NET_BUF_IP_MSS);
+#endif
+
+#if defined(NUM_MPF_NET_BUF_1024)
+	cons_printf(portid, "  NUM_MPF_NET_BUF_1024:      %2d\n", NUM_MPF_NET_BUF_1024);
+#endif
+
+#if defined(NUM_MPF_NET_BUF_IPV6_MMTU)
+	cons_printf(portid, "  NUM_MPF_NET_BUF_IPV6_MMTU: %2d\n", NUM_MPF_NET_BUF_IPV6_MMTU);
+#endif
+
+#if defined(NUM_MPF_NET_BUF_IF_PDU)
+	cons_printf(portid, "  NUM_MPF_NET_BUF_IF_PDU:    %2d\n", NUM_MPF_NET_BUF_IF_PDU);
+#endif
+
+#if defined(NUM_MPF_NET_BUF_REASSM)
+	cons_printf(portid, "  NUM_MPF_NET_BUF_REASSM:    %2d\n", NUM_MPF_NET_BUF_REASSM);
+#endif
+
+#if defined(NUM_MPF_NET_BUF6_65536)
+	cons_printf(portid, "  NUM_MPF_NET_BUF6_65536:    %2d\n", NUM_MPF_NET_BUF6_65536);
+#endif
+
+	cons_printf(portid, "Network Counter Mask: %08x\n", NET_COUNT_ENABLE);
+
+	cons_printf(portid, "SUPPORT_MIB: ");
+#if defined(SUPPORT_MIB)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#ifdef USE_PING
+
+/*
+ *  ping コマンド
+ */
+
+void
+dbg_cons_ping_comd (ID portid, char *line)
+{
+	int_t	tmo, size;
+	char	apip = DEFAULT_API_PROTO;
+
+#if defined(SUPPORT_INET6)
+	T_IN6_ADDR	addr;
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	addr4;
+#endif
+#else
+	T_IN4_ADDR	addr;
+#endif
+
+#if defined(PING_CFG_I6RLP)
+
+	static const char i6rlp_pmtu_str1[] = " FF1E::1:2 1 1452";
+	static const char i6rlp_pmtu_str2[] = " FF1E::1:2 1 1352";
+	static const char i6rlp_pmtu_str3[] = " fe80::0200:00ff:fe00:0100 1 2";
+
+	if      (apip == '1')
+		strcpy(line, i6rlp_pmtu_str1);
+	else if (apip == '2')
+		strcpy(line, i6rlp_pmtu_str2);
+	else if (apip == '3')
+		strcpy(line, i6rlp_pmtu_str3);
+
+#endif	/* of #ifdef PING_CFG_I6RLP */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if ('0' <= *line && *line <= '9') {
+		if (*line == '6')
+			apip = API_PROTO_IPV6;
+		if (*line == '4')
+			apip = API_PROTO_IPV4;
+		line ++;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
+		syslog(LOG_NOTICE, "[PING] unknown host.");
+		return;
+		}
+
+	line = skip_blanks(line);
+	if ('0' <= *line && *line <= '9')
+		line = get_int(&tmo, line);
+	else
+		tmo = 3;
+
+	line = skip_blanks(line);
+	if ('0' <= *line && *line <= '9')
+		line = get_int(&size, line);
+	else
+		size = 64;
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+	if (apip == API_PROTO_IPV6) {
+		syslog(LOG_NOTICE, "[PING6] size: %d, tmo: %d, host: %s", size, tmo, ipv62str(NULL, &addr));
+		ping6(&addr, (uint_t)tmo, (uint_t)size);
+		}
+	else {
+		addr4 = ntohl(addr.s6_addr32[3]);
+		syslog(LOG_NOTICE, "[PING4] size: %d, tmo: %d, host: %s", size, tmo, ip2str(NULL, &addr4));
+		ping4(&addr4, (uint_t)tmo, (uint_t)size);
+		}
+
+#else /* of #if defined(SUPPORT_INET4) */
+
+	syslog(LOG_NOTICE, "[PING6] size: %d, tmo: %d, host: %s", size, tmo, ipv62str(NULL, &addr));
+	ping6(&addr, (uint_t)tmo, (uint_t)size);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+
+	syslog(LOG_NOTICE, "[PING4] size: %d, tmo: %d, host: %s", size, tmo, ip2str(NULL, &addr));
+	ping4(&addr, (uint_t)tmo, (uint_t)size);
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+	}
+
+#endif	/* of #ifdef USE_PING */
+
+#ifdef USE_DBG_CONS_PARSER
+
+/*
+ *  デバッグコマンド解析
+ */
+
+void
+dbg_parse (ID portid, char *line)
+{
+	int_t	cepid;
+	ER	error = E_OK;
+
+#if defined(SUPPORT_UDP) && defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+	int_t	udp_cep_ipproto;
+#endif
+
+	switch (*line) {
+
+	case 'c':		/* cancel CEP */
+		switch (*(line + 1)) {
+
+		case 'f':	/* show configurations */
+			dbg_cons_show_config(portid, line + 1);
+			break;
+
+#ifdef SUPPORT_TCP
+
+		case 't':	/* cancel TCP */
+			cepid = atoi(line = skip_blanks(line + 2));
+			while ('0' <= *line && *line <= '9')
+				line ++;
+			if ((error = tcp_can_cep((ID)cepid, atoi(skip_blanks(line)))) != E_OK && error != E_RLWAI) {
+				cons_printf(portid, "[TCP CAN CEP] error: %s.\n", itron_strerror(error));
+				SIG_NET_CONS_PRINTF();
+				FLUSH_SND_BUFF();
+				}
+			break;
+
+#endif	/* of #ifdef SUPPORT_TCP */
+
+#ifdef SUPPORT_UDP
+
+		case 'u':	/* cancel UDP */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+			udp_cep_ipproto = (*(line + 2) == '4' ? API_PROTO_IPV4 : API_PROTO_IPV6);
+			cepid = atoi(line = skip_blanks(line + 3));
+			while ('0' <= *line && *line <= '9')
+				line ++;
+
+#if TNUM_UDP6_CEPID > 0
+
+			if (udp_cep_ipproto == API_PROTO_IPV6) {
+				if ((error = udp_can_cep((ID)cepid, atoi(skip_blanks(line)))) != E_OK && error != E_RLWAI) {
+					cons_printf(portid, "[UDP CAN CEP] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				}
+
+#endif	/* of #if TNUM_UDP6_CEPID > 0 */
+
+#if TNUM_UDP4_CEPID > 0
+
+			if (udp_cep_ipproto == API_PROTO_IPV4) {
+				if ((error = udp_can_cep((ID)cepid, atoi(skip_blanks(line)))) != E_OK && error != E_RLWAI) {
+					cons_printf(portid, "[UDP CAN CEP] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				}
+
+#endif	/* of #if TNUM_UDP4_CEPID > 0 */
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+#if TNUM_UDP6_CEPID > 0
+
+			cepid = atoi(line = skip_blanks(line + 2));
+			while ('0' <= *line && *line <= '9')
+				line ++;
+
+			if ((error = udp_can_cep((ID)cepid, atoi(skip_blanks(line)))) != E_OK && error != E_RLWAI) {
+				cons_printf(portid, "[UDP CAN CEP] error: %s.\n", itron_strerror(error));
+				SIG_NET_CONS_PRINTF();
+				FLUSH_SND_BUFF();
+				}
+
+#endif	/* of #if TNUM_UDP6_CEPID > 0 */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#if TNUM_UDP4_CEPID > 0
+
+			cepid = atoi(line = skip_blanks(line + 2));
+			while ('0' <= *line && *line <= '9')
+				line ++;
+
+			if ((error = udp_can_cep((ID)cepid, atoi(skip_blanks(line)))) != E_OK && error != E_RLWAI) {
+				cons_printf(portid, "[UDP CAN CEP] error: %s.\n", itron_strerror(error));
+				SIG_NET_CONS_PRINTF();
+				FLUSH_SND_BUFF();
+				}
+
+#endif	/* of #if TNUM_UDP4_CEPID > 0 */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+			break;
+
+#endif	/* of #ifdef SUPPORT_UDP */
+
+			}
+
+		break;
+
+	case 'd':	/* discard client */
+		switch (*(line + 1)) {
+
+#if defined(SUPPORT_PPP)
+
+		case 'c':		/* disconnect */
+			if (lcp_fsm.state != PPP_FSM_STOPPED)
+				lcp_close();
+			break;
+
+#endif	/* of #if defined(SUPPORT_PPP) */
+
+#if defined(SUPPORT_ETHER) && defined(USE_NET_CONS)
+
+		case 'c':		/* disconnect */
+			discon_net_cons();
+			break;
+
+#endif	/* of #if defined(SUPPORT_ETHER) && defined(USE_NET_CONS) */
+
+#if defined(DHCP6_CLI_CFG) || defined(DHCP4_CLI_CFG)
+
+		case 'h':		/* DHCP client */
+			dhcpc(portid, line + 2);
+			break;
+
+#endif	/* of #if defined(DHCP6_CLI_CFG) || defined(DHCP4_CLI_CFG) */
+
+#ifdef USE_TCP_DISCARD_CLI
+
+		case 't':	/* TCP discard client */
+			line += 2;
+			switch (*line) {
+
+			case 's':	/* cancel TCP discard client */
+				tcp_discard_cli_valid = false;
+				break;
+
+			default:
+				if ((error = psnd_dtq(DTQ_TCP_DISCARD_CLI, (intptr_t)line)) != E_OK) {
+					cons_printf(portid, "[TCP DISCARD CLI] error: %s.\n",
+					       itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				break;
+
+				}
+			break;
+
+#endif	/* of #ifdef USE_TCP_DISCARD_CLI */
+
+#ifdef USE_UDP_DISCARD_CLI
+
+		case 'u':	/* UDP discard client */
+			line += 2;
+			switch (*line) {
+
+			case 's':	/* cancel UDP discard client */
+				udp_discard_cli_valid = false;
+				break;
+
+			default:
+				if ((error = psnd_dtq(DTQ_UDP_DISCARD_CLI, (intptr_t)line)) != E_OK) {
+					cons_printf(portid, "[UDP DISCARD CLI] error: %s.\n",
+					       itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				break;
+
+				}
+			break;
+
+#endif	/* of #ifdef USE_UDP_DISCARD_CLI */
+
+			}
+
+		break;
+
+#if defined(USE_TCP_ECHO_CLI) || defined(USE_UDP_ECHO_CLI)
+
+	case 'e':	/* echo client */
+		switch (*(line + 1)) {
+
+#ifdef USE_TCP_ECHO_CLI
+
+		case 't':	/* TCP echo client */
+			line += 2;
+			switch (*line) {
+
+			case 's':	/* cancel TCP echo */
+				tcp_echo_cli_valid = false;
+				break;
+
+			default:
+				if ((error = psnd_dtq(DTQ_TCP_ECHO_CLI_SND, (intptr_t)line)) != E_OK) {
+					cons_printf(portid, "[TCP ECHO CLI] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				break;
+
+				}
+			break;
+
+#endif	/* of #ifdef USE_TCP_ECHO_CLI */
+
+#if defined(USE_UDP_ECHO_CLI)
+
+		case 'u':	/* UDP echo client */
+			switch (*(line + 2)) {
+
+			case 's':	/* cancel UDP echo */
+
+#if defined(USE_UDP6_ECHO_CLI_TSK)
+
+#if defined(USE_UDP4_ECHO_CLI_TSK)
+
+				if (*(line + 3) == '4')
+					udp4_echo_cli_valid = false;
+				else
+					udp6_echo_cli_valid = false;
+
+#else	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
+
+				udp6_echo_cli_valid = false;
+
+#endif	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
+
+#else	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
+
+#if defined(USE_UDP4_CLI_TSK)
+
+				udp4_echo_cli_valid = false;
+
+#endif	/* of #if defined(USE_UDP4_CLI_TSK) */
+
+#endif	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
+
+
+				break;
+
+			default:
+
+				line += 2;
+
+#if defined(USE_UDP6_ECHO_CLI_TSK)
+
+#if defined(USE_UDP4_ECHO_CLI_TSK)
+
+				if (*line == '4') {
+					line ++;
+					error = psnd_dtq(DTQ_UDP4_ECHO_CLI, (intptr_t)line);
+					}
+				else {
+					if (*line && *line != ' ')
+						line ++;
+					error = psnd_dtq(DTQ_UDP6_ECHO_CLI, (intptr_t)line);
+					}
+
+#else	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
+
+				if (*line && *line != ' ')
+					line ++;
+				error = psnd_dtq(DTQ_UDP6_ECHO_CLI, (intptr_t)line);
+
+#endif	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
+
+#else	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
+
+				if (*line && *line != ' ')
+					line ++;
+				error = psnd_dtq(DTQ_UDP4_ECHO_CLI, (intptr_t)line);
+
+#endif	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
+
+				if (error != E_OK) {
+					cons_printf(portid, "[UDP ECHO CLI] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+
+				break;
+
+				}
+			break;
+
+#endif	/* of #if defined(USE_UDP_ECHO_CLI) */
+
+			}
+
+		break;
+
+#endif	/* of #if defined(USE_TCP_ECHO_CLI) || defined(USE_UDP_ECHO_CLI) */
+
+	case 'i':
+
+		if (*(line + 1) == 'f') {
+
+			dbg_cons_ifconfig (portid, line + 2);
+
+#if defined(NETAPP_IP6_CFG)
+			dbg_cons_ifconfig6(portid, line + 2);
+#endif
+
+#if defined(NETAPP_IP4_CFG)
+			dbg_cons_ifconfig4(portid, line + 2);
+#endif
+
+			}
+
+#ifdef SUPPORT_PPP
+
+#ifdef PPP_CFG_MODEM
+
+		else if (lcp_fsm.state == PPP_FSM_STOPPED)
+			dial();		/* initiate */
+
+#else	/* of #ifdef PPP_CFG_MODEM */
+
+		else if (lcp_fsm.state == PPP_FSM_STOPPED)
+			lcp_open(PPP_OPEN_ACTIVE);
+
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+		break;
+
+	case 'n':		/* network status */
+		dbg_cons_network_status(portid, line + 1);
+		break;
+
+	case 'p':		/* ping or task status */
+
+		if (*(line + 1) == 's')
+			dbg_cons_task_status(portid, skip_blanks(line + 2));
+
+#ifdef USE_PING
+
+		else
+			dbg_cons_ping_comd(portid, line + 1);
+
+#endif	/* of #ifdef USE_PING */
+
+		break;
+
+	case 'r':		/* release wait task */
+		if ((error = rel_wai(atoi(skip_blanks(line + 1)))) != E_OK) {
+			cons_printf(portid, "[REL WAI TSK] error: %s.\n", itron_strerror(error));
+			SIG_NET_CONS_PRINTF();
+			FLUSH_SND_BUFF();
+			}
+		break;
+
+	case 't':		/* terminate (delete) REP/CEP */
+		switch (*(line + 1)) {
+
+#ifdef USE_TCP_EXTENTIONS
+
+		case 't':		/* TCP REP */
+	
+			error = tcp_del_rep(atoi(skip_blanks(line + 2)));
+			if (error != E_OK) {
+				cons_printf(portid, "[TCP DEL REP] ID: %d, error: %s.\n", 
+				                    atoi(skip_blanks(line + 2)),
+				                    itron_strerror(error));
+				SIG_NET_CONS_PRINTF();
+				FLUSH_SND_BUFF();
+				}
+			break;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_UDP_EXTENTIONS
+
+		case 'u':		/* UDP CEP */
+
+#if defined(USE_UDP6_ECHO_SRV_TSK)
+
+#if defined(USE_UDP4_ECHO_SRV_TSK)
+
+			if (*(line + 2) == '4') {
+				if ((error = udp_del_cep(atoi(skip_blanks(line + 3)))) != E_OK) {
+					cons_printf(portid, "[UDP DEL CEP] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				}
+			else {
+				if ((error = udp6_del_cep(atoi(skip_blanks(line + 2)))) != E_OK) {
+					cons_printf(portid, "[UDP DEL CEP] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				}
+
+#else	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+			if ((error = udp6_del_cep(atoi(skip_blanks(line + 2)))) != E_OK) {
+				cons_printf(portid, "[UDP DEL CEP] error: %s.\n", itron_strerror(error));
+				SIG_NET_CONS_PRINTF();
+				FLUSH_SND_BUFF();
+				}
+
+#endif	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+#else	/* of #if defined(USE_UDP6_ECHO_SRV_TSK) */
+
+#if defined(USE_UDP4_ECHO_SRV_TSK)
+
+			if ((error = udp_del_cep(atoi(skip_blanks(line + 2)))) != E_OK) {
+				cons_printf(portid, "[UDP DEL CEP] error: %s.\n", itron_strerror(error));
+				SIG_NET_CONS_PRINTF();
+				FLUSH_SND_BUFF();
+				}
+
+#endif	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+#endif	/* of #if defined(USE_UDP6_ECHO_SRV_TSK) */
+
+			break;
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+			}
+		break;
+
+#if defined(USE_TCP_EXTENTIONS) || defined(USE_UDP_EXTENTIONS)
+
+	case 'w':		/* wakeup server */
+				/* wake up task */
+		switch (*(line + 1)) {
+
+#ifdef USE_TCP_EXTENTIONS
+
+		case 't':		/* tcp server */
+			switch (*(line + 2)) {
+
+#ifdef USE_TCP_DISCARD_SRV
+			case 'd':		/* tcp discard server */
+				if ((error = wup_tsk(TCP_DISCARD_SRV_TASK)) != E_OK) {
+					//cons_printf(portid, "[WUP TCP DISCARD SRV] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				break;
+#endif	/* of #ifdef USE_TCP_DISCARD_SRV */
+
+#if defined(USE_TCP_ECHO_SRV1)
+			case 'e':		/* tcp echo server */
+				if ((error = wakeup_tcp_echo_srv((*(line + 3) == '4' ? API_PROTO_IPV4 : API_PROTO_IPV6))) != E_OK) {
+					//cons_printf(portid, "[WUP TCP ECHO SRV] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				break;
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
+
+#if defined(USE_TCP_ECHO_SRV2)
+			case 'e':		/* tcp echo server */
+				if ((error = wup_tsk(TCP_ECHO_SRV_TASK2)) != E_OK) {
+					//cons_printf(portid, "[WUP TCP ECHO SRV] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				break;
+#endif	/* of #if defined(USE_TCP_ECHO_SRV2) */
+
+#ifdef USE_WWW_SRV
+			case 'w':		/* WWW server */
+				if ((error = wakeup_www_srv((*(line + 3) == '4' ? API_PROTO_IPV4 : API_PROTO_IPV6))) != E_OK) {
+					//cons_printf(portid, "[WUP WWW SRV] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				break;
+#endif	/* of #ifdef USE_TCP_DISCARD_SRV */
+
+				}
+			break;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_UDP_EXTENTIONS
+
+		case 'u':		/* udp server */
+			switch (*(line + 2)) {
+
+#if !defined(USE_UDP_CALL_BACK)
+
+			case 'e':		/* udp echo server */
+
+#if defined(USE_UDP6_ECHO_SRV_TSK)
+
+#if defined(USE_UDP4_ECHO_SRV_TSK)
+
+				if (*(line + 3) == '4') {
+					if ((error = wup_tsk(UDP4_ECHO_SRV_TASK)) != E_OK) {
+						cons_printf(portid, "[WUP UDP4 ECHO SRV] error: %s.\n", itron_strerror(error));
+						SIG_NET_CONS_PRINTF();
+						FLUSH_SND_BUFF();
+						}
+					}
+				else {
+					if ((error = wup_tsk(UDP6_ECHO_SRV_TASK)) != E_OK) {
+						cons_printf(portid, "[WUP UDP6 ECHO SRV] error: %s.\n", itron_strerror(error));
+						SIG_NET_CONS_PRINTF();
+						FLUSH_SND_BUFF();
+						}
+					}
+
+#else	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+				if ((error = wup_tsk(UDP6_ECHO_SRV_TASK)) != E_OK) {
+					cons_printf(portid, "[WUP UDP6 ECHO SRV] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+
+#endif	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+#else	/* of #if defined(USE_UDP6_ECHO_SRV_TSK) */
+
+#if defined(USE_UDP4_ECHO_SRV_TSK)
+
+				if ((error = wup_tsk(UDP4_ECHO_SRV_TASK)) != E_OK) {
+					cons_printf(portid, "[WUP UDP4 ECHO SRV] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+
+#endif	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+#endif	/* of #if defined(USE_UDP6_ECHO_SRV_TSK) */
+
+				break;
+
+#endif	/* of #if !defined(USE_UDP_CALL_BACK) */
+
+				}
+			break;
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+		default:
+			if ((error = wup_tsk(atoi(skip_blanks(line + 1)))) != E_OK) {
+				cons_printf(portid, "[WUP TSK] error: %s.\n", itron_strerror(error));
+				SIG_NET_CONS_PRINTF();
+				FLUSH_SND_BUFF();
+				}
+			break;
+
+			}
+		break;
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) || defined(USE_UDP_EXTENTIONS) */
+
+	case 'w':		/* wake up task */
+		if ((error = wup_tsk(atoi(skip_blanks(line + 1)))) != E_OK) {
+			cons_printf(portid, "[WUP TSK] error: %s.\n", itron_strerror(error));
+			SIG_NET_CONS_PRINTF();
+			FLUSH_SND_BUFF();
+			}
+		break;
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) || defined(USE_UDP_EXTENTIONS) */
+
+	default:
+
+		if (*line) {
+
+#ifdef USE_DBG_CONS_EXTRA_PARSE
+
+			//cons_printf(portid, "extra command: '%c'.\n", *line);
+			dbg_cons_extra_parse(portid, line);
+
+#else	/* of #ifdef USE_DBG_CONS_EXTRA_PARSE */
+
+			//cons_printf(portid, "command: '%c'.\n", *line);
+			cons_printf(portid, "no such command: '%c'.\n", *line);
+			SIG_NET_CONS_PRINTF();
+			FLUSH_SND_BUFF();
+
+#endif	/* of #ifdef USE_DBG_CONS_EXTRA_PARSE */
+
+			}
+		break;
+		}
+	}
+
+#endif	/* of #ifdef USE_DBG_CONS_PARSER */
+
+/*
+ *  デバッグコンソールタスク
+ */
+
+void
+dbg_con_task (intptr_t exinf)
+{
+	static char line[DBG_LINE_SIZE + 1];
+
+	ID	tskid;
+
+#ifdef USE_LCD
+#ifdef SUPPORT_ETHER
+
+#if 0
+#if defined(SUPPORT_INET6)
+
+	uint32_t	lllen;
+	const uint8_t	*lladdr;
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+#endif
+
+	lcd_initialize(0);
+
+#if 0
+#if defined(SUPPORT_INET6)
+
+	dly_tsk(1 * 1000);
+	lladdr = IF_ETHER_NIC_GET_SOFTC()->ifaddr.lladdr;
+	for (lllen = ETHER_ADDR_LEN; lllen --; )
+		lcd_printf(LCD_PORTID, "%02x", *lladdr ++);
+	lcd_putc(LCD_PORTID, '\n');
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+	if ((TINET_PRVER & UINT_C(0x0f)) > 0)
+		lcd_printf(LCD_PORTID, "TINET-%d.%d.%d\n",
+		       (TINET_PRVER   >> 12) & UINT_C(0x0f),
+		       (TINET_PRVER   >>  4) & UINT_C(0x0f),
+		        TINET_PRVER          & UINT_C(0x0f));
+	else
+		lcd_printf(LCD_PORTID, "TINET-%d.%d\n",
+		       (TINET_PRVER   >> 12) & UINT_C(0x0f),
+		       (TINET_PRVER   >>  4) & UINT_C(0x0f));
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+#endif
+
+#if 0
+#if defined(SUPPORT_INET4)
+
+	dly_tsk(1 * 1000);
+	lcd_puts(LCD_PORTID, ip2str(NULL, in4_get_ifaddr(0)));
+	lcd_putc(LCD_PORTID, '\n');
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+#endif
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+#endif	/* of #ifdef USE_LCD */
+
+	get_tid(&tskid);
+	cons_printf(CONSOLE_PORTID, "[CONSOLE:%d] started.\n", tskid);
+	serial_ctl_por(CONSOLE_PORTID,
+	               IOCTL_ECHO  | IOCTL_CRLF  |
+	               IOCTL_FCSND | IOCTL_FCANY | IOCTL_FCRCV);
+	netapp_srand (tskid);
+	while (true) {
+		cons_getline(CONSOLE_PORTID, line, DBG_LINE_SIZE);
+		dbg_parse(CONSOLE_PORTID, line);
+		}
+	}
+
+#endif	/* of #ifdef USE_DBG_CONS */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dbg_cons.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dbg_cons.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dbg_cons.cfg	(revision 398)
@@ -0,0 +1,51 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  デバッグコンソールのフィギュレーションファイル
+ */
+
+#ifdef USE_DBG_CONS
+
+/* タスク */
+
+CRE_TSK(DBG_CON_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	dbg_con_task,
+	DBG_CON_PRIORITY,
+	DBG_CON_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_DBG_CONS */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dbg_cons.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dbg_cons.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dbg_cons.h	(revision 398)
@@ -0,0 +1,65 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _DBG_CONS_
+#define _DBG_CONS_
+
+/* 
+ *  コンソール
+ */
+
+#define	DBG_CON_STACK_SIZE	1024		/* コンソールタスクのスタックサイズ */
+#define DBG_CON_PRIORITY	5		/* コンソールタスクの優先度 */
+
+/*
+ *  タスク
+ */
+
+extern void	dbg_con_task (intptr_t exinf);
+
+/*
+ *  関数
+ */
+
+extern void act_tasks (void);
+extern void dbg_parse (ID portid, char *line);
+extern void dbg_cons_extra_parse (ID portid, char *line);
+extern void dbg_cons_task_status (ID portid, char *line);
+extern void dbg_cons_network_status (ID portid, char *line);
+extern void dbg_cons_ifconfig (ID portid, char *line);
+extern void dbg_cons_ifconfig6 (ID portid, char *line);
+extern void dbg_cons_ifconfig4 (ID portid, char *line);
+extern void dbg_cons_show_config (ID portid, char *line);
+extern void dbg_cons_ping_comd (ID portid, char *line);
+
+#endif	/* of #ifndef _DBG_CONS_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4.h	(revision 398)
@@ -0,0 +1,372 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP4_H
+#define DHCP4_H
+
+/*
+ *  DHCP に関する定義
+ *
+ *    RFC2131
+ */
+
+/*
+ *  DHCP メッセージの定数の定義
+ */
+
+#define DHCP4_CHADDR_LEN	16
+#define DHCP4_SNAME_LEN		64
+#define DHCP4_FILE_LEN		128
+#define DHCP4_DFLT_OPT_LEN	312
+#define DHCP4_UDP_MSG_LENGTH	(sizeof(uint32_t)*7+DHCP4_CHADDR_LEN	\
+				 +DHCP4_SNAME_LEN+DHCP4_FILE_LEN+DHCP4_DFLT_OPT_LEN)
+#define DHCP4_SNAME_OFFSET	(sizeof(uint32_t)*7+DHCP4_CHADDR_LEN)
+#define DHCP4_FILE_OFFSET	(DHCP4_SNAME_OFFSET+DHCP4_SNAME_LEN)
+#define DHCP4_OPTION_OFFSET	(DHCP4_FILE_OFFSET+DHCP4_FILE_LEN)
+#define DHCP4_TIME_INFINITY	UINT_C(0xffffffff)
+
+/*
+ *  DHCP メッセージ
+ */
+
+typedef struct dhcp4_msg {
+	uint8_t		op;			/* packet type			*/
+	uint8_t		htype;			/* hardware address type	*/
+	uint8_t		hlen;			/* hardware address length	*/
+	uint8_t		hops;			/* gateway hops			*/
+	uint32_t	xid;			/* transaction ID		*/
+	uint16_t	secs;			/* seconds since boot began	*/
+	uint16_t	flags;
+	uint32_t	ciaddr;			/* client IP address		*/
+	uint32_t	yiaddr;			/* your   IP address		*/
+	uint32_t	siaddr;			/* server IP address		*/
+	uint32_t	giaddr;			/* relay agent IP address	*/
+	uint8_t		chaddr [DHCP4_CHADDR_LEN];	/* client hardware address	*/
+	uint8_t		sname  [DHCP4_SNAME_LEN];	/* server host name		*/
+	uint8_t		file   [DHCP4_FILE_LEN];		/* boot file name		*/
+	uint8_t		options[DHCP4_DFLT_OPT_LEN];	/* optional parameters field	*/
+	} __attribute__((packed)) T_DHCP4_MSG;
+
+/* packet type の定義 */
+
+#define DHCP4_REQUEST		UINT_C(1)
+#define DHCP4_REPLY		UINT_C(2)
+
+/* hardware address type の定義 */
+
+#define DHCP4_HWA_TYPE_ETHER	UINT_C(1)
+#define DHCP4_HWA_TYPE_IEEE802	UINT_C(6)
+
+/*
+ *  DHCP オプション
+ *
+ *    RFC1533
+ */
+
+/*
+ *  オプションの穴埋め
+ */
+#define DHCP4_OPT_PAD		UINT_C(0)
+
+/*
+ *  サブネットマスク
+ *
+ *     code   len   subnet mask
+ *   +------+-----+-----+-----+-----+-----+
+ *   |   1  |  4  |  m1 |  m2 |  m3 |  m4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_SUBNET_MASK	UINT_C(1)
+
+/*
+ *  ルータ
+ *
+ *     code   len   addres #1               address #2
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ *   |   3  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 | ...
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_ROUTER		UINT_C(3)
+
+/*
+ *  DNS サーバ
+ *
+ *     code   len   addres #1               address #2
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ *   |   6  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 | ...
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_DNS_SERVER	UINT_C(6)
+
+/*
+ *  ホスト名
+ *
+ *     code   len   host name
+ *   +------+-----+-----+-----+-----+-----+---
+ *   |  12  |  n  |  h1 |  h2 |  h3 |  h4 | ...
+ *   +------+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_HOST_NAME	UINT_C(12)
+
+/*
+ *  ドメイン名
+ *
+ *     code   len   domain name
+ *   +------+-----+-----+-----+-----+-----+---
+ *   |  15  |  n  |  d1 |  d2 |  d3 |  d4 | ...
+ *   +------+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_DOMAIN_NAME	UINT_C(15)
+
+/*
+ *  ルータ探索
+ *
+ *     code   len  value
+ *   +------+-----+-----+
+ *   |  31  |  1  | 0/1 |
+ *   +------+-----+-----+
+ */
+#define DHCP4_OPT_RTR_DISOVERY	UINT_C(31)
+
+/*
+ *  静的経路
+ *
+ *     code   len   destination #1          router #1
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ *   |  33  |  n  |  d1 |  d2 |  d3 |  d4 |  r1 |  r2 | ...
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_STATIC_ROUTE	UINT_C(33)
+
+/*
+ *  ベンダー固有情報
+ *
+ *     code   len   vendor-specific informations
+ *   +------+-----+-----+-----+-----+---
+ *   |  43  |  n  |  i1 |  i2 |  i3 | ...  
+ *   +------+-----+-----+-----+-----+---
+ *
+ */
+#define DHCP4_OPT_VENDOR_INFO	UINT_C(43)
+
+/*
+ *  NetBIOS over TCP/IP ネームサーバ
+ *
+ *     code   len   addres #1               address #2
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ *   |  44  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 | ...
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_NETBIOS_NS	UINT_C(44)
+
+/*
+ *  NetBIOS over TCP/IP ノードタイプ
+ *
+ *     code   len   type
+ *   +------+-----+-----+
+ *   |  46  |  1  | type|
+ *   +------+-----+-----+
+ */
+#define DHCP4_OPT_NETBIOS_NODE	UINT_C(46)
+
+/*
+ *  NetBIOS over TCP/IP スコープ
+ *
+ *     code   len   NetBIOS scope
+ *   +------+-----+-----+-----+-----+-----+---
+ *   |  44  |  n  |  s1 |  s2 |  s3 |  s4 |  ...
+ *   +------+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_NETBIOS_SCOPE	UINT_C(47)
+
+/*
+ *  特定の IPv4 アドレス要求
+ *
+ *     code   len   IPv4 address
+ *   +------+-----+-----+-----+-----+-----+
+ *   |  50  |  4  |  a1 |  a2 |  a3 |  a4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_REQ_IPV4	UINT_C(50)
+
+/*
+ *  リース時間
+ *
+ *     code   len   lease time
+ *   +------+-----+-----+-----+-----+-----+
+ *   |  51  |  4  |  t1 |  t2 |  t3 |  t4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_LEASE_TIME	UINT_C(51)
+
+/*
+ *  オプションオーバーロード
+ *
+ *     code   len  value
+ *   +------+-----+-----+
+ *   |  52  |  1  | 1-3 |
+ *   +------+-----+-----+
+ */
+#define DHCP4_OPT_OPT_OVERLOAD	UINT_C(52)
+
+/* value の定義 */
+
+#define DHCP4_OPTOL_FILE	UINT_C(0x01)
+#define DHCP4_OPTOL_SNAME	UINT_C(0x02)
+#define DHCP4_OPTOL_BOTH	UINT_C(0x03)
+
+/*
+ *  DHCP メッセージタイプ
+ *
+ *     code   len   type
+ *   +------+-----+-----+
+ *   |  53  |  1  | 1-7 |
+ *   +------+-----+-----+
+ */
+#define DHCP4_OPT_MSG_TYPE	UINT_C(53)
+
+/* type の定義 */
+
+#define DHCP4_MTYPE_BOOTP	UINT_C(0)
+#define DHCP4_MTYPE_DISCOVER	UINT_C(1)
+#define DHCP4_MTYPE_OFFER	UINT_C(2)
+#define DHCP4_MTYPE_REQUEST	UINT_C(3)
+#define DHCP4_MTYPE_DECLINE	UINT_C(4)
+#define DHCP4_MTYPE_ACK		UINT_C(5)
+#define DHCP4_MTYPE_NAK		UINT_C(6)
+#define DHCP4_MTYPE_RELEASE	UINT_C(7)
+#define DHCP4_MTYPE_INFOMATION	UINT_C(8)
+
+/*
+ *  サーバ ID
+ *
+ *     code   len   IPv4 address
+ *   +------+-----+-----+-----+-----+-----+
+ *   |  54  |  4  |  a1 |  a2 |  a3 |  a4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_SERVER_ID	UINT_C(54)
+
+/*
+ *  要求パラメータリスト
+ *
+ *     code   len   option code
+ *   +------+-----+-----+-----+-----+---
+ *   |  55  |  n  |  c1 |  c2 |  c3 | ...  
+ *   +------+-----+-----+-----+-----+---
+ *
+ */
+#define DHCP4_OPT_REQ_PARAM	UINT_C(55)
+
+/*
+ *  Renewal (T1) 時間
+ *
+ *     code   len   T1 interval
+ *   +------+-----+-----+-----+-----+-----+
+ *   |  58  |  4  |  t1 |  t2 |  t3 |  t4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_RENEWAL_T1	UINT_C(58)
+
+/*
+ *  Rebinding (T2) 時間
+ *
+ *     code   len   T2 interval
+ *   +------+-----+-----+-----+-----+-----+
+ *   |  59  |  4  |  t1 |  t2 |  t3 |  t4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_REBINDING_T2	UINT_C(59)
+
+/*
+ *  ベンダークラス ID（RFC2132）
+ *
+ *     code   len   vendor class ID
+ *   +------+-----+-----+-----+-----+---
+ *   |  60  |  n  |  i1 |  i2 |  i3 | ...  
+ *   +------+-----+-----+-----+-----+---
+ *
+ */
+#define DHCP4_OPT_VCLASS_ID	UINT_C(60)
+
+/*
+ *  クライアント ID
+ *
+ *     code   len   type  client ID
+ *   +------+-----+-----+-----+-----+---
+ *   |  61  |  n  | type|  i1 |  i2 | ...  
+ *   +------+-----+-----+-----+-----+---
+ *
+ *   type       : ハードウェアアドレスタイプ
+ *   i1, i2, ...: 通常 MAC アドレス
+ */
+#define DHCP4_OPT_CLIENT_ID	UINT_C(61)
+
+/*
+ *  クラスなし静的経路（RFC3442）
+ *
+ *     code   len   destination #1     router #1
+ *   +------+-----+-----+------+-----+-----+-----+-----+---
+ *   |  121 |  n  |  d1 |  ... |  dN |  r1 |  r2 |  r3 | ...
+ *   +------+-----+-----+------+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_CLASSLESS_RTE	UINT_C(121)
+
+/*
+ *  オプションの終了
+ */
+#define DHCP4_OPT_END		UINT_C(255)
+
+/*
+ *  magic 番号（RFC1048）
+ */
+
+#define DHCP4_RFC1048_MAGIC	{ UINT_C(99), UINT_C(130), UINT_C(83), UINT_C(99), }
+#define DHCP4_MAGIC_LEN		4
+
+/*
+ *  UDP ポート番号
+ */
+
+#ifndef DHCP4_SRV_CFG_PORTNO
+#define DHCP4_SRV_CFG_PORTNO	67	/* server	*/
+#endif
+
+#ifndef DHCP4_CLI_CFG_PORTNO
+#define DHCP4_CLI_CFG_PORTNO	68	/* client	*/
+#endif
+
+#endif	/* of #ifndef DHCP4_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.c	(revision 398)
@@ -0,0 +1,2176 @@
+/*
+ * Copyright 2004 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.    All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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 Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM 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 INTERNET SOFTWARE CONSORTIUM 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 software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ *
+ * This client was substantially modified and enhanced by Elliot Poger
+ * for use on Linux while he was working on the MosquitoNet project at
+ * Stanford.
+ *
+ * The current version owes much to Elliot's Linux enhancements, but
+ * was substantially reorganized and partially rewritten by Ted Lemon
+ * so as to use the same networking framework that the Internet Software
+ * Consortium DHCP server uses.   Much system-specific configuration code
+ * was moved into a shell script so that as support for more operating
+ * systems is added, it will not be necessary to port and maintain
+ * system-specific configuration code to these operating systems - instead,
+ * the shell script can invoke the native tools to accomplish the same
+ * purpose.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project 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 DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/if_ether.h>
+
+#include <net/if_var.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/dhcp4_cli.h>
+#include <netapp/dhcp4_cli_var.h>
+#include <netapp/resolver.h>
+#include "lcd.h"
+
+/*
+ *  DHCP クライアントタスク
+ */
+
+#ifdef DHCP4_CLI_CFG
+
+/*
+ *  変数
+ */
+
+static T_DHCP4_CLI_CONTEXT	context;			/* クライアントコンテキスト	*/
+static uint8_t	magicno[DHCP4_MAGIC_LEN] = DHCP4_RFC1048_MAGIC;	/* magic 番号（RFC1048）*/
+
+/* 必須オプションリスト */
+#ifdef DHCP4_CLI_CFG_REQUIRED_OLIST
+static uint8_t	required_plist[] = DHCP4_CLI_CFG_REQUIRED_OLIST;
+#endif
+
+/* 要求オプションリスト */
+#ifdef DHCP4_CLI_CFG_REQUEST_OLIST
+static uint8_t	request_plist[] = DHCP4_CLI_CFG_REQUEST_OLIST;
+#endif
+
+#ifdef SEM_DHCP4_CLI_TIMER
+#define DHCP4_CLI_TIMER_LOCK() do { syscall(wai_sem(SEM_DHCP4_CLI_TIMER)); } while(0)
+#define DHCP4_CLI_TIMER_UNLOCK() do { syscall(sig_sem(SEM_DHCP4_CLI_TIMER)); } while(0)
+#else
+#define DHCP4_CLI_TIMER_LOCK() do { } while(0)
+#define DHCP4_CLI_TIMER_UNLOCK() do { } while(0)
+#endif
+
+#ifdef SEM_DHCP4_CLI_READY
+#define DHCP4_CLI_READY_WAIT(ct) do { syscall(wai_sem(SEM_DHCP4_CLI_READY)); } while(0)
+#define DHCP4_CLI_READY_SIGNAL(ct) do { syscall(sig_sem(SEM_DHCP4_CLI_READY)); } while(0)
+#else
+#define DHCP4_CLI_READY_WAIT(ct) do { } while(0)
+#define DHCP4_CLI_READY_SIGNAL(ct) do { syscall(wup_tsk(ct->tskid)); } while(0)
+#endif
+
+/*
+ *  dhcp4_cksum -- チェックサムの計算関数
+ */
+
+static uint32_t
+dhcp4_cksum (void *data, uint_t len /*オクテット単位*/)
+{
+	uint32_t carry, sum = 0;
+
+	for ( ; len > 0; len -= 2) {
+		sum += (*(uint8_t*)data << 8) + *((uint8_t*)data + 1);
+		data = (uint8_t*)data + 2;
+		}
+
+	while (sum >= 0x00010000) {
+		carry = sum >> 16;
+		sum   = (sum & 0xffff) + carry;
+		}
+
+	return sum;
+	}
+
+/*
+ *  create_xid -- トランザクション ID を生成する。
+ */
+
+static uint32_t
+create_xid (void)
+{
+	T_IF_SOFTC	*ic;
+	SYSTIM		time;
+
+	ic = IF_ETHER_NIC_GET_SOFTC();
+	get_tim(&time);
+	return (dhcp4_cksum((void*)&ic->ifaddr.lladdr, ETHER_ADDR_LEN) << 16)
+	      + dhcp4_cksum((void*)&time, sizeof(time));
+	}
+
+/*
+ *  find_option_sub -- 指定したオプションを探索する。
+ *
+ *    注意: 引数 size が 0 の時はオプションサイズを検証しない。
+ */
+
+static uint8_t *
+find_option_sub (T_DHCP4_CLI_MSG *msg, uint_t off, uint_t len, 
+                                      uint_t tag, uint_t size, bool_t overload)
+{
+	uint8_t	*opt, *tmp;
+
+	opt = (uint8_t*)&msg->msg + off;
+	while (opt < (uint8_t*)&msg->msg + off + len && *opt != DHCP4_OPT_END) {
+		if (*opt == DHCP4_OPT_PAD)
+			opt ++;
+		else if ((*opt == DHCP4_OPT_OPT_OVERLOAD) && overload) {
+			if (*(opt + 2) & DHCP4_OPTOL_FILE) {
+				tmp = find_option_sub(msg, DHCP4_FILE_OFFSET, DHCP4_FILE_LEN, tag, len, false);
+				if (tmp != NULL)
+					return tmp;
+				}
+			if (*(opt + 2) & DHCP4_OPTOL_SNAME) {
+				tmp = find_option_sub(msg, DHCP4_SNAME_OFFSET, DHCP4_SNAME_LEN, tag, len, false);
+				if (tmp != NULL)
+					return tmp;
+				}
+			opt += *(opt + 1) + 2;
+			}
+		else if (*opt == tag && (size == 0 || *(opt + 1) == size))
+			return opt;
+		else
+			opt += *(opt + 1) + 2;
+		}
+	return NULL;
+	}
+
+/*
+ *  find_option -- 指定したオプションを探索する。
+ *
+ *    注意: 引数 size が 0 の時はオプションサイズを検証しない。
+ */
+
+static uint8_t *
+find_option (T_DHCP4_CLI_MSG *msg, uint_t tag, uint_t size)
+{
+	return find_option_sub(msg, DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN,
+	                       msg->len - (DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN),
+	                       tag, size, true);
+	}
+
+/*
+ *  is_equal_sid -- メッセージ内の SERVER ID を比較する。
+ */
+
+static bool_t
+is_equal_sid (T_DHCP4_CLI_MSG *msg1, T_DHCP4_CLI_MSG *msg2)
+{
+	uint8_t	*opt1, *opt2;
+
+	if ((opt1 = find_option(msg1, DHCP4_OPT_SERVER_ID, sizeof(T_IN4_ADDR))) == NULL)
+		return false;
+	if ((opt2 = find_option(msg2, DHCP4_OPT_SERVER_ID, sizeof(T_IN4_ADDR))) == NULL)
+		return false;
+
+	return msg2host32(opt1) == msg2host32(opt2);
+	}
+
+/*
+ *  timer_value -- メッセージから時間情報を取り出す。
+ */
+
+static uint32_t
+timer_value (T_DHCP4_CLI_MSG *msg, uint_t tag, uint32_t def_value)
+{
+	uint8_t 	*opt;
+	uint32_t	seconds;
+
+	if ((opt = find_option(msg, tag, sizeof(uint32_t))) == NULL)
+		return def_value;
+	else {
+
+		/* サーバからのリース時間は[s]。*/
+		seconds = msg2host32(opt + 2);
+
+		/* コンテキスト内のリース時間は SYSTIM_HZ。*/
+		if (seconds == DHCP4_TIME_INFINITY)
+			return DHCP4_TIME_INFINITY;
+		else if (seconds > SYSTIM2SEC(DHCP4_TIME_INFINITY))
+			return DHCP4_TIME_INFINITY;
+		else
+			return SEC2SYSTIM(seconds);
+		}
+	}
+
+/*
+ *  rel_addr -- IPv4 アドレス、サブネットマスク、静的経路表を解放する。
+ */
+
+static void
+rel_addr (void)
+{
+	ER	error;
+	uint_t	count = 0;
+
+	if ((error = in4_add_ifaddr(IPV4_ADDRANY, IPV4_ADDRANY)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, IPv4 addr: %s", itron_strerror(error));
+		count ++;
+		}
+
+	if ((error = in4_add_route(0, IPV4_ADDRANY, IPV4_ADDRANY, IPV4_ADDRANY)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, release routing table: %s", itron_strerror(error));
+		count ++;
+		}
+
+	if ((error = in4_add_route(1, IPV4_ADDRANY, IPV4_ADDRANY, IPV4_ADDRANY)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, release routing table: %s", itron_strerror(error));
+		count ++;
+		}
+
+	if ((error = in4_add_route(2, 0xffffffff, 0xffffffff, IPV4_ADDRANY)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, release routing table: %s", itron_strerror(error));
+		count ++;
+		}
+
+	if (count == 0) {
+		syslog(LOG_NOTICE, "[DHCP4C] release IPv4 addr.");
+
+#if 0
+#ifdef USE_LCD
+		dly_tsk(1 * 1000);
+		lcd_puts(LCD_PORTID, "0.0.0.0\n");
+#endif	/* of #ifdef USE_LCD */
+#endif
+		ether_set_down();
+		}
+	}
+
+/*
+ *  rel_options -- リースされたオプションを解析して値を解放する。
+ */
+
+static void
+rel_options (T_DHCP4_CLI_CONTEXT *ct, uint_t off, uint_t len, bool_t overload)
+{
+#if defined(USE_RESOLVER)
+	T_IN4_ADDR	addr;
+#endif
+
+	uint8_t	*opt;
+
+	opt = (uint8_t*)&ct->act_msg->msg + off;
+	while (opt < (uint8_t*)&ct->act_msg->msg + off + len && *opt != DHCP4_OPT_END) {
+		if (*opt == DHCP4_OPT_PAD)
+			opt ++;
+		else if ((*opt == DHCP4_OPT_OPT_OVERLOAD) && overload) {
+			if (*(opt + 2) & DHCP4_OPTOL_FILE)
+				rel_options(ct, DHCP4_FILE_OFFSET, DHCP4_FILE_LEN, false);
+			if (*(opt + 2) & DHCP4_OPTOL_SNAME)
+				rel_options(ct, DHCP4_SNAME_OFFSET, DHCP4_SNAME_LEN, false);
+			opt += *(opt + 1) + 2;
+			}
+		else {
+
+			switch (*opt) {
+
+#if defined(USE_RESOLVER)
+
+			case DHCP4_OPT_DNS_SERVER:
+				addr = IPV4_ADDRANY;
+				dns_in4_set_addr(&addr);
+				break;
+
+			case DHCP4_OPT_HOST_NAME:
+				break;
+
+			case DHCP4_OPT_DOMAIN_NAME:
+				dns_in4_set_dname("", 0);
+				break;
+
+#else	/* of #if defined(USE_RESOLVER) */
+
+			case DHCP4_OPT_DNS_SERVER:
+			case DHCP4_OPT_HOST_NAME:
+			case DHCP4_OPT_DOMAIN_NAME:
+
+#endif	/* of #if defined(USE_RESOLVER) */
+
+			case DHCP4_OPT_SUBNET_MASK:
+			case DHCP4_OPT_ROUTER:
+			case DHCP4_OPT_LEASE_TIME:
+			case DHCP4_OPT_RENEWAL_T1:
+			case DHCP4_OPT_REBINDING_T2:
+				break;
+
+			default:
+				break;
+				}
+
+			opt += *(opt + 1) + 2;
+			}
+		}
+	}
+
+/*
+ *  rel_lease -- リースされた情報を解放する。
+ */
+
+static void
+rel_lease (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* 有効なリース・メッセージ構造体が無ければ何もしない。*/
+	if (ct->act_msg == NULL)
+		return;
+
+	/* リースされたオプションを解析して値を解放する。*/
+	rel_options(ct, DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN,
+	              ct->act_msg->len - (DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN), true);
+	rel_addr();
+
+	/* 有効なリース・メッセージ構造体を解放する。*/
+	syscall(rel_mpf(MPF_DHCP4_CLI_MSG, (void*)ct->act_msg));
+	ct->act_msg = NULL;
+	}
+
+/*
+ *  set_addr -- IPv4 アドレス、サブネットマスク、静的経路表を設定する。
+ */
+
+static void
+set_addr (T_DHCP4_CLI_CONTEXT *ct, uint8_t *mopt, uint8_t *ropt)
+{
+	ER		error;
+	T_IN4_ADDR	addr, mask, router, net_addr;
+
+	addr     = ntohl(ct->act_msg->msg.yiaddr);
+	mask     = msg2host32(mopt + 2);
+	net_addr = addr & mask;
+	router   = msg2host32(ropt + 2);
+	
+	if ((error = in4_add_ifaddr(addr, mask)) != E_OK)
+		syslog(LOG_NOTICE, "[DHCP4C] error, set IPv4 addr: %s", itron_strerror(error));
+
+	if ((error = in4_add_route(0, IPV4_ADDRANY, IPV4_ADDRANY, router)) != E_OK)
+		syslog(LOG_NOTICE, "[DHCP4C] error, set routing table: %s", itron_strerror(error));
+
+	if ((error = in4_add_route(1, net_addr, mask, IPV4_ADDRANY)) != E_OK)
+		syslog(LOG_NOTICE, "[DHCP4C] error, set routing table: %s", itron_strerror(error));
+
+	if ((error = in4_add_route(2, 0xffffffff, 0xffffffff, IPV4_ADDRANY)) != E_OK)
+		syslog(LOG_NOTICE, "[DHCP4C] error, set routing table: %s", itron_strerror(error));
+
+	if (error == E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] set IPv4 addr: %s.", ip2str(NULL, &addr));
+
+#ifdef USE_LCD
+		dly_tsk(1 * 1000);
+		lcd_puts(LCD_PORTID, ip2str(NULL, &addr));
+		lcd_putc(LCD_PORTID, '\n');
+#endif	/* of #ifdef USE_LCD */
+		ether_set_up();
+		}
+	}
+
+/*
+ *  set_options -- リースされたオプションを解析して値を設定する。
+ */
+
+static void
+set_options (T_DHCP4_CLI_CONTEXT *ct, uint_t off, uint_t len, bool_t overload)
+{
+#if defined(USE_RESOLVER)
+	T_IN4_ADDR	addr;
+#endif
+
+	uint8_t	*opt, *mopt = NULL, *ropt = NULL;
+
+	opt = (uint8_t*)&ct->act_msg->msg + off;
+	while (opt < (uint8_t*)&ct->act_msg->msg + off + len && *opt != DHCP4_OPT_END) {
+		if (*opt == DHCP4_OPT_PAD)
+			opt ++;
+		else if ((*opt == DHCP4_OPT_OPT_OVERLOAD) && overload) {
+			if (*(opt + 2) & DHCP4_OPTOL_FILE)
+				set_options(ct, DHCP4_FILE_OFFSET, DHCP4_FILE_LEN, false);
+			if (*(opt + 2) & DHCP4_OPTOL_SNAME)
+				set_options(ct, DHCP4_SNAME_OFFSET, DHCP4_SNAME_LEN, false);
+			opt += *(opt + 1) + 2;
+			}
+		else {
+
+			switch (*opt) {
+			case DHCP4_OPT_SUBNET_MASK:
+				mopt = opt;
+				break;
+
+			case DHCP4_OPT_ROUTER:
+				ropt = opt;
+				break;
+
+#if defined(USE_RESOLVER)
+
+			case DHCP4_OPT_DNS_SERVER:
+				addr = msg2host32(opt + 2);
+				dns_in4_set_addr(&addr);
+				break;
+
+			case DHCP4_OPT_HOST_NAME:
+				break;
+
+			case DHCP4_OPT_DOMAIN_NAME:
+				dns_in4_set_dname(opt + 2, *(opt + 1));
+				break;
+
+#else	/* of #if defined(USE_RESOLVER) */
+
+			case DHCP4_OPT_DNS_SERVER:
+			case DHCP4_OPT_HOST_NAME:
+			case DHCP4_OPT_DOMAIN_NAME:
+
+#endif	/* of #if defined(USE_RESOLVER) */
+
+			case DHCP4_OPT_LEASE_TIME:
+			case DHCP4_OPT_RENEWAL_T1:
+			case DHCP4_OPT_REBINDING_T2:
+				break;
+
+			default:
+				break;
+				}
+
+			opt += *(opt + 1) + 2;
+			}
+		}
+	if (!(mopt == NULL || ropt == NULL))
+		set_addr(ct, mopt, ropt);
+	}
+
+/*
+ *  set_lease -- リースされた情報を設定する。
+ */
+
+static void
+set_lease (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* リースされたオプションを解析して値を設定する。*/
+	set_options(ct, DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN,
+	              ct->act_msg->len - (DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN), true);
+	}
+
+/*
+ *  validate_duplicate -- 指定された IPv4 アドレスが使われていないか検証する。
+ *
+ *    使われていない時は true を返す。
+ */
+
+static bool_t
+validate_duplicate (T_DHCP4_CLI_MSG *msg)
+{
+	T_IN4_ADDR	yiaddr;
+
+	/* 指定された IPv4 アドレスが ADDR ANY なら使われていないと判断する。*/
+	yiaddr = ntohl(msg->msg.yiaddr);
+	if (yiaddr == IPV4_ADDRANY)
+		return true;
+
+	/* ARP キャッシュにあれば使われていると判断する。*/
+	if (arp_lookup(yiaddr, false) != NULL)
+		return false;
+
+	/*
+	 *  ARP 要求を出力して TMO_DHCP4C_ARP_WAIT 待ち、
+	 *  ARP キャッシュになければ使われていないと判断する。
+	 */
+	arp_request(&IF_ETHER_NIC_GET_SOFTC()->ifaddr, yiaddr);
+	dly_tsk(TMO_DHCP4C_ARP_WAIT);
+	return arp_lookup(yiaddr, false) == NULL;
+	}
+
+/*
+ *  validate_rcv_msg -- 受信メッセージを検証する。
+ */
+
+static ER
+validate_rcv_msg (T_DHCP4_CLI_CONTEXT *ct, T_DHCP4_CLI_MSG *msg)
+{
+	uint8_t 	*opt;
+
+	/* packet type が DHCP4_REPLY であることを確認する。*/
+	if (!(msg->msg.op == DHCP4_REPLY))
+		return false;
+
+	/* メッセージタイプオプションがあることを確認する。*/
+	if ((opt = find_option(msg, DHCP4_OPT_MSG_TYPE, 1)) == NULL)
+		return E_PAR;
+
+	/* メッセージのタイプが一致していることを検証する。*/
+	msg->type = *(opt + 2);
+	switch (ct->fsm) {
+
+	case DHCP4_FSM_SELECT:
+		if (!(msg->type == DHCP4_MTYPE_OFFER))
+			return E_PAR;
+		break;
+
+	case DHCP4_FSM_REQUEST:
+	case DHCP4_FSM_REBOOT:
+	case DHCP4_FSM_RENEW:
+	case DHCP4_FSM_REBIND:
+	case DHCP4_FSM_REL_INFO:
+		if (!((msg->type == DHCP4_MTYPE_ACK) || (msg->type == DHCP4_MTYPE_NAK)))
+			return E_PAR;
+		break;
+
+	case DHCP4_FSM_INIT:
+	case DHCP4_FSM_BOUND:
+	case DHCP4_FSM_INIT_REBOOT:
+		return E_PAR;
+		break;
+
+	default:
+		syslog(LOG_NOTICE, "[DHCP4C] error, unknown state: %d.", ct->fsm);
+		return E_PAR;
+		break;
+		}
+
+	/* マジック番号を検証する。*/
+	if (memcmp((uint8_t*)&msg->msg.options, magicno, DHCP4_MAGIC_LEN))
+		return E_PAR;
+
+	/* トランザクション ID が異なっていればエラー */
+	if (ntohl(msg->msg.xid) != ct->xid)
+		return E_PAR;
+
+	/* ハードウェアアドレス長が 6（MAC アドレス長）でなければエラー */
+	if (msg->msg.hlen != ETHER_ADDR_LEN)
+		return E_PAR;
+
+	/* ハードウェアアドレスが異なっていればエラー */
+	if (memcmp(&msg->msg.chaddr, &ct->sc->ifaddr.lladdr, sizeof(ct->sc->ifaddr.lladdr)))
+		return E_PAR;
+
+	/*
+	 *  メッセージタイプが OFFER の場合は、
+	 *  ARP を使用して、指定された IPv4 アドレスが使われていないか検証する。
+	 *  使われている時は、他の IPv4 アドレスの提供を待つ。
+	 */
+	if (msg->type == DHCP4_MTYPE_OFFER) {
+		if (!validate_duplicate(msg))
+			return E_PAR;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  eval_prefer -- 受信メッセージの推奨度を評価する。
+ */
+
+static void
+eval_prefer (T_DHCP4_CLI_MSG *msg)
+{
+	int	ix;
+
+	/* 無効の場合は終了する。*/
+	if (msg == NULL)
+		return;
+
+	/* 指定された IPv4 アドレスが ADDR ANY なら推奨度を 0に設定する。*/
+	if (ntohl(msg->msg.yiaddr) == IPV4_ADDRANY)
+		msg->prefer = 0;
+	else
+		msg->prefer = DHCP4_CLI_CFG_PREFER_ADDR;
+
+#if defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+
+	/* 要求オプションを検証する。*/
+	for (ix = sizeof(request_plist); ix -- > 0; ) {
+		if (find_option(msg, request_plist[ix], 0) != NULL)
+			msg->prefer ++;
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUEST_OLIST) */
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST)
+
+	/* 必須オプションを検証する。*/
+	for (ix = sizeof(required_plist); ix -- > 0; ) {
+		if (find_option(msg, required_plist[ix], 0) == NULL)
+			msg->prefer = 0;
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) */
+	}
+
+/*
+ *  eval_rcv_msg -- 受信メッセージを評価する。
+ */
+
+static ER
+eval_rcv_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG	*evl, *msg;
+
+	/* メッセージを受信していなければ中止する。*/
+	syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+	if (ct->val_lst == NULL) {
+		syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+		return E_OK;
+		}
+
+	/* 検証メッセージリストから評価メッセージを取り出す。*/
+	evl         = ct->val_lst;
+	ct->val_lst = ct->val_lst->next;
+	evl->next   = NULL;
+	syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+
+	/* 評価メッセージを検証する。*/
+	if (validate_rcv_msg(ct, evl) != E_OK) {
+
+		/* エラーが発生した評価メッセージを受信メッセージ構造体リストに戻す。*/
+		goto rcv_ret;
+		}
+
+	/* 受信したメッセージが NAK の時の処理 */
+	if (evl->type == DHCP4_MTYPE_NAK) {
+
+		/* リースされた情報を解放する。*/
+		rel_lease(ct);
+
+		/* 内部エラーを設定して終了する。*/
+		return E_PAR;
+		}
+
+	/* REL_INFO 状態の時の処理 */
+	//cons_printf(CONSOLE_PORTID, "evl_rcv_msg3[s=%d]\n", ct->fsm);
+	if (ct->fsm == DHCP4_FSM_REL_INFO) {
+		syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+		evl->next   = ct->prf_lst;
+		ct->prf_lst = evl;
+		syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+		return E_OK;
+		}
+
+	/* 評価メッセージの推奨度を評価する。*/
+	eval_prefer(evl);
+
+	/* 推奨メッセージリストが空なら評価メッセージを移して終了する。*/
+	if (ct->prf_lst == NULL) {
+		ct->max_prefer = evl->prefer;
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+
+	/* 評価メッセージの推奨度と推奨メッセージリストの最大推奨度を比較する。*/
+	if (evl->prefer > ct->max_prefer) {
+
+		/* 
+		 *  評価メッセージの推奨度が推奨メッセージリストの最大推奨度より高ければ、
+		 *  推奨メッセージリストを受信メッセージ構造体リストに戻し、
+		 *  評価メッセージを推奨メッセージリストに移す。
+		 */
+		ct->max_prefer = evl->prefer;
+		syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+		if (ct->rcv_lst == NULL)
+			ct->rcv_lst = ct->prf_lst;
+		else {
+			for (msg = ct->rcv_lst; msg->next != NULL; msg = msg->next)
+				;
+			msg->next = ct->prf_lst;
+			}
+		syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+
+	else if (evl->prefer == ct->max_prefer) {
+		for (msg = ct->prf_lst; msg != NULL; msg = msg->next) {
+			if (is_equal_sid(evl, msg)) {
+
+				/*
+				 *  推奨メッセージリストに同じ DHCP4_OPT_SERVER_ID のメッセージがあれば、
+				 *  評価メッセージを受信メッセージ構造体リストに戻す。
+				 */
+				goto rcv_ret;
+				}
+			}
+
+		/* 
+		 *  評価メッセージを推奨メッセージリストに移す。
+		 */
+		evl->next   = ct->prf_lst;
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+	
+	/*else */
+		/* 
+		 *  評価メッセージの推奨度が推奨メッセージリストの最大推奨度より低ければ、
+		 *  評価メッセージを受信メッセージ構造体リストに戻す。
+		 */
+
+rcv_ret:
+	syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+	evl->next   = ct->rcv_lst;
+	ct->rcv_lst = evl;
+	syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+	return E_OK;
+	}
+
+/*
+ *  select_msg -- 推奨メッセージを選択する。
+ */
+
+static T_DHCP4_CLI_MSG*
+select_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG		*msg, *select;
+
+	syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+	if (ct->prf_lst == NULL) {
+		/* メッセージを受信していなければ中止する。*/
+		syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+		return NULL;
+		}
+
+	/* 推奨メッセージリストの先頭のメッセージを選択する。*/
+	select = ct->prf_lst;
+	ct->prf_lst  = ct->prf_lst->next;
+	select->next = NULL;
+
+	/* 選択されなかった検証メッセージを受信メッセージ構造体リストに戻す。*/
+	if (ct->rcv_lst == NULL)
+		ct->rcv_lst = ct->prf_lst;
+	else {
+		for (msg = ct->rcv_lst; msg->next != NULL; msg = msg->next)
+			;
+		msg->next = ct->prf_lst;
+		}
+	syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+	return select;
+	}
+
+/*
+ *  select_ack -- ACK メッセージを検証する。
+ *
+ *    受け入れることが可能の時は true を返す。
+ */
+
+static bool_t
+select_ack (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG	*msg;
+
+	if ((msg = select_msg(ct)) == NULL)
+		return false;
+
+	/* 有効なリース・メッセージが残っていれば、受信メッセージ構造体リストに戻す。*/
+	if (ct->act_msg != NULL) {
+		syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+		ct->act_msg->next = ct->rcv_lst;
+		ct->rcv_lst = ct->act_msg;
+		syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+		}
+
+	/* 有効なリース・メッセージに設定する。*/
+	ct->act_msg = msg;
+	return true;
+	}
+
+/*
+ *  select_offer -- OFFER メッセージを検証する。
+ *
+ *    受け入れることが可能の時は true を返す。
+ */
+
+static bool_t
+select_offer (T_DHCP4_CLI_CONTEXT *ct)
+{
+	return (ct->off_msg = select_msg(ct)) != NULL;
+	}
+
+/*
+ *  cancel_all_timers -- 全ての TIMER をキャンセルする。
+ */
+
+static void
+cancel_all_timers (T_DHCP4_CLI_CONTEXT *ct)
+{
+	int ix;
+
+	DHCP4_CLI_TIMER_LOCK();
+	for (ix = NUM_DHCP4C_TIMERS; ix -- > 0; )
+		ct->timers[ix] = 0;
+	DHCP4_CLI_TIMER_UNLOCK();
+	}
+
+
+/*
+ *  start_select -- DISCOVER メッセージを送信して SELECT 状態に遷移する。
+ */
+
+static void
+start_select (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* 送信を開始した時間を記録する。*/
+	get_tim(&ct->snd_start);
+
+	/* OFFER メッセージ受信タイムアウトを設定する。*/
+	DHCP4_CLI_TIMER_LOCK();
+	ct->timers[DHCP4C_TIMER_RCV_OFFER] = SYSTIM2TIMER(TMO_DHCP4C_OFFER);
+	DHCP4_CLI_TIMER_UNLOCK();
+
+	/* 送信先アドレスにローカルネットワークへのブロードキャストを設定する。*/
+	ct->dst.ipaddr = IPV4_ADDRBROADCAST;
+
+	/* 送信間隔をリセットする。*/
+	ct->interval = 0;
+
+	/* SELECT 状態に遷移する。*/
+	ct->fsm = DHCP4_FSM_SELECT;
+
+	/* DISCOVER メッセージを送信する。*/
+	ct->flags |= DHCP4C_FLAG_TMOUT_SND_DISC;
+	DHCP4_CLI_READY_SIGNAL(ct);
+	}
+
+/*
+ *  start_bound -- BOUND 状態に遷移する。
+ */
+
+static void
+start_bound (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* リースされた情報を設定する。*/
+	set_lease(ct);
+
+	/* リースの有効時間を設定する。*/
+	ct->expire = timer_value(ct->act_msg, DHCP4_OPT_LEASE_TIME, TMO_DHCP4C_DEF_LEASE);
+
+	/* リース時間が TMO_DHCP4C_MIN_LEASE 以下の時は、TMO_DHCP4C_MIN_LEASE に設定する。*/
+	if (ct->expire < TMO_DHCP4C_MIN_LEASE)
+		ct->expire = TMO_DHCP4C_MIN_LEASE;
+
+	/* RENEW 状態までの時間を設定する。*/
+	ct->renew = timer_value(ct->act_msg, DHCP4_OPT_RENEWAL_T1, ct->expire / 2);
+
+	/* REBIND 状態までの時間を設定する。*/
+	ct->rebind = timer_value(ct->act_msg, DHCP4_OPT_REBINDING_T2, ct->renew + ct->renew / 2 + ct->renew / 4);
+
+	/* EXPIRE、RENEW、REBIND タイマーを設定する。*/
+	DHCP4_CLI_TIMER_LOCK();
+	ct->timers[DHCP4C_TIMER_EXPIRE] = SYSTIM2TIMER(ct->expire);		/* EXPIRE      までの時間 */
+	ct->timers[DHCP4C_TIMER_REBIND] = SYSTIM2TIMER(ct->rebind);		/* REBIND（T2）までの時間 */
+	ct->timers[DHCP4C_TIMER_RENEW]  = SYSTIM2TIMER(ct->renew);		/* RENEW （T1）までの時間 */
+	DHCP4_CLI_TIMER_UNLOCK();
+
+	/* BOUND 状態に遷移する。*/
+	ct->fsm = DHCP4_FSM_BOUND;
+
+	/* BIND を開始した時間を記録する。*/
+	get_tim(&ct->bind_start);
+	}
+
+/*
+ *  start_send_request -- REQUEST メッセージを送信して、指定された状態に遷移する。
+ */
+
+static void
+start_send_request (T_DHCP4_CLI_CONTEXT *ct, uint_t fsm)
+{
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	/* 送信を開始した時間を記録する。*/
+	get_tim(&ct->snd_start);
+
+	/* 遷移する状態が RENEW 以外では ACK/NAK メッセージ受信タイムアウトを設定する。*/
+	if (fsm != DHCP4_FSM_RENEW) { 
+		DHCP4_CLI_TIMER_LOCK();
+		ct->timers[DHCP4C_TIMER_RCV_ACK] = SYSTIM2TIMER(TMO_DHCP4C_ACK);
+		DHCP4_CLI_TIMER_UNLOCK();
+		}
+
+	/*
+	 *  遷移する状態が RENEW で、
+	 *  SERVER ID オプションがあればローカルネットワークへのブロードキャストを送信する。
+	 */
+	if ((fsm == DHCP4_FSM_RENEW) &&
+	    (find_option(ct->act_msg, DHCP4_OPT_SERVER_ID, sizeof(T_IN4_ADDR)) !=  NULL))
+		ct->dst.ipaddr = (ifp->in4_ifaddr.addr &  ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask;
+	else
+		ct->dst.ipaddr = IPV4_ADDRBROADCAST;
+
+	/* 送信間隔をリセットする。*/
+	ct->interval = 0;
+
+	/* 指定された状態に遷移する。*/
+	ct->fsm = fsm;
+
+	/* REQUEST メッセージを送信する。*/
+	ct->flags |= DHCP4C_FLAG_TMOUT_SND_REQ;
+	DHCP4_CLI_READY_SIGNAL(ct);
+	}
+
+/*
+ *  start_rel_info -- アドレス情報を解放する。
+ *
+ *    注意: DHCPv4 の RFC2131 には無い
+ */
+
+static void
+start_rel_info (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* 全ての TIMER をキャンセルする。*/
+	cancel_all_timers(ct);
+
+	/* 有効なリース情報が無ければ SLEEP に遷移する。*/
+	if (ct->act_msg == NULL) {
+		ct->fsm = DHCP4_FSM_SLEEP;
+		return;
+		}
+
+	/* 送信先アドレスにローカルネットワークへのブロードキャストを設定する。*/
+	ct->dst.ipaddr = IPV4_ADDRBROADCAST;
+
+	/* RELEASE メッセージを送信する。*/
+	ct->flags |= DHCP4C_FLAG_TMOUT_SND_REL;
+	DHCP4_CLI_READY_SIGNAL(ct);
+	}
+
+/*
+ *  setup_dhcp_com_msg -- DHCP メッセージの共通部分を作成する。
+ */
+
+static uint8_t *
+setup_dhcp_com_msg (T_DHCP4_CLI_CONTEXT *ct, uint_t op, uint_t type)
+{
+	uint8_t	*option;
+
+	memset((void*)&ct->snd_msg->msg, 0, sizeof(ct->snd_msg->msg));
+	ct->snd_msg->len = sizeof(ct->snd_msg->msg);
+
+	/* ヘッダ部を設定する。*/
+	ct->snd_msg->msg.op = op;
+	ct->snd_msg->msg.htype = DHCP4_HWA_TYPE_ETHER;
+	ct->snd_msg->msg.hlen = ETHER_ADDR_LEN;
+	HOST2MSG32(ct->snd_msg->msg.xid, ct->xid);
+
+	/* MAC アドレスを設定する。*/
+	memcpy(&ct->snd_msg->msg.chaddr, &ct->sc->ifaddr.lladdr, ETHER_ADDR_LEN);
+
+	/*
+	 *  オプション部を設定する。
+	 */
+
+	/* RFC1048 に定義されているマジック番号を設定する。*/
+	memcpy(&ct->snd_msg->msg.options, magicno, DHCP4_MAGIC_LEN);
+	option = ct->snd_msg->msg.options + DHCP4_MAGIC_LEN;
+
+	/* DHCP メッセージタイプを設定する。*/
+	*(option ++) = DHCP4_OPT_MSG_TYPE;
+	*(option ++) = 1;
+	*(option ++) = type;
+
+	return option;
+	}
+
+/*
+ *  setup_release_msg -- RELEASE メッセージを作成する。
+ */
+
+static ER
+setup_release_msg (T_DHCP4_CLI_CONTEXT *ct, T_DHCP4_CLI_MSG *ref)
+{
+	uint8_t *opt, *ref_opt;
+
+	/* 有効なリース・メッセージがなければエラー */
+	if (ref == NULL)
+		return E_PAR;
+
+	ct->xid = create_xid();
+	if ((opt = setup_dhcp_com_msg(ct, DHCP4_REQUEST, DHCP4_MTYPE_RELEASE)) == NULL)
+		return E_PAR;
+
+	/*
+	 *  サーバ ID（server-ip）を設定する。
+	 *  RFC2131 4.4.1 Initialization and allocation of network address 参照
+	 */
+	if ((ref_opt = find_option(ref, DHCP4_OPT_SERVER_ID, sizeof(T_IN4_ADDR))) == NULL)
+		return E_PAR;
+	*(opt ++) = *(ref_opt ++);
+	*(opt ++) = *(ref_opt ++);
+	memcpy(opt, ref_opt, *(ref_opt - 1));
+	opt += *(ref_opt - 1);
+
+	/* 
+	 *  クライアント ID（MAC アドレス）を設定する。
+	 *  RFC2131 4.4.1 Initialization and allocation of network address 参照
+	 */
+	*(opt ++) = DHCP4_OPT_CLIENT_ID;
+	*(opt ++) = ETHER_ADDR_LEN + 1;
+	*(opt ++) = DHCP4_HWA_TYPE_ETHER;
+	memcpy(opt, &ct->sc->ifaddr.lladdr, ETHER_ADDR_LEN);
+	opt += ETHER_ADDR_LEN;
+
+	/* オプションの終了を設定する。*/
+	*(opt ++) = DHCP4_OPT_END;
+
+	/*
+	 *  クライアント IP アドレス（ciaddr）を設定する。
+	 *  RFC2131 4.4.1 Initialization and allocation of network address 参照
+	 */
+	HOST2MSG32(ct->snd_msg->msg.ciaddr, IF_GET_IFNET()->in4_ifaddr.addr);
+
+	/* メッセージ長を設定する。*/
+	ct->snd_msg->len = sizeof(ct->snd_msg->msg) - DHCP4_DFLT_OPT_LEN
+	             + (opt - (uint8_t*)&ct->snd_msg->msg.options);
+	return E_OK;
+	}
+
+
+/*
+ *  setup_request_msg -- REQUEST メッセージを作成する。
+ */
+
+static ER
+setup_request_msg (T_DHCP4_CLI_CONTEXT *ct, T_DHCP4_CLI_MSG *ref)
+{
+	uint8_t *opt, *ref_opt;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+	uint_t	len = 0;
+#endif
+
+	/* 参照するメッセージがなければエラー */
+	if (ref == NULL)
+		return E_PAR;
+
+	ct->xid = create_xid();
+	if ((opt = setup_dhcp_com_msg(ct, DHCP4_REQUEST, DHCP4_MTYPE_REQUEST)) == NULL)
+		return E_PAR;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+
+	/* 追加のオプションを設定する。*/
+
+	*opt  = DHCP4_OPT_REQ_PARAM;
+	 opt += 2;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST)
+
+	/* 要求オプションリストを設定する。*/
+	if (sizeof(required_plist) > 0) {
+		memcpy(opt, required_plist, sizeof(required_plist));
+		opt += sizeof(required_plist);
+		len += sizeof(required_plist);
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) */
+
+#if defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+
+	/* 要求オプションリストを設定する。*/
+	if (sizeof(request_plist) > 0) {
+		memcpy(opt, request_plist, sizeof(request_plist));
+		opt += sizeof(request_plist);
+		len += sizeof(request_plist);
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUEST_OLIST) */
+
+	*(opt - len - 1) = len;
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST) */
+
+	/*
+	 *  サーバ ID（server-ip）を設定する。
+	 *  RFC2131 4.4.1 Initialization and allocation of network address 参照
+	 */
+	if (ct->fsm == DHCP4_FSM_REQUEST) {
+		if ((ref_opt = find_option(ref, DHCP4_OPT_SERVER_ID, sizeof(T_IN4_ADDR))) == NULL)
+			return E_PAR;
+		*(opt ++) = *(ref_opt ++);
+		*(opt ++) = *(ref_opt ++);
+		memcpy(opt, ref_opt, *(ref_opt - 1));
+		opt += *(ref_opt - 1);
+		}
+
+	/*
+	 *  要求 IP アドレス（requested-ip）を設定する。
+	 *  RFC2131 4.4.1 Initialization and allocation of network address 参照
+	 *  RFC2131 では、DHCP4_FSM_RENEW の時 MUST NOT になっているが、
+	 *  MUST のようである。
+	 */
+	*(opt ++) = DHCP4_OPT_REQ_IPV4;
+	*(opt ++) = sizeof(ref->msg.yiaddr);
+	if (ct->fsm == DHCP4_FSM_REQUEST || ct->fsm == DHCP4_FSM_INIT_REBOOT ||
+	    ct->fsm == DHCP4_FSM_RENEW   || ct->fsm == DHCP4_FSM_REBIND)
+	 	/* 参照メッセージと同じ IP アドレス（requested-ip）を要求する。*/
+		memcpy(opt, (uint8_t*)&ref->msg.yiaddr, sizeof(ref->msg.yiaddr));
+	else
+		host2msg32(opt, IPV4_ADDRANY);
+	opt += sizeof(ref->msg.yiaddr);
+
+	/* 
+	 *  クライアント ID（MAC アドレス）を設定する。
+	 *  RFC2131 4.4.1 Initialization and allocation of network address 参照
+	 */
+	*(opt ++) = DHCP4_OPT_CLIENT_ID;
+	*(opt ++) = ETHER_ADDR_LEN + 1;
+	*(opt ++) = DHCP4_HWA_TYPE_ETHER;
+	memcpy(opt, &ct->sc->ifaddr.lladdr, ETHER_ADDR_LEN);
+	opt += ETHER_ADDR_LEN;
+
+	/* オプションの終了を設定する。*/
+	*(opt ++) = DHCP4_OPT_END;
+
+	/*
+	 *  クライアント IP アドレス（ciaddr）を設定する。
+	 *  RFC2131 4.4.1 Initialization and allocation of network address 参照
+	 */
+	if (ct->fsm == DHCP4_FSM_RENEW || ct->fsm == DHCP4_FSM_REBIND)
+		HOST2MSG32(ct->snd_msg->msg.ciaddr, IF_GET_IFNET()->in4_ifaddr.addr);
+	else
+		HOST2MSG32(ct->snd_msg->msg.ciaddr, IPV4_ADDRANY);
+
+	/* メッセージ長を設定する。*/
+	ct->snd_msg->len = sizeof(ct->snd_msg->msg) - DHCP4_DFLT_OPT_LEN
+	             + (opt - (uint8_t*)&ct->snd_msg->msg.options);
+	return E_OK;
+	}
+
+/*
+ *  setup_discover_msg -- DISCOVER メッセージを作成する。
+ */
+
+static ER
+setup_discover_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	uint8_t *opt;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+	uint_t	len = 0;
+#endif
+
+	ct->xid = create_xid();
+	if ((opt = setup_dhcp_com_msg(ct, DHCP4_REQUEST, DHCP4_MTYPE_DISCOVER)) == NULL)
+		return E_PAR;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+
+	/* 追加のオプションを設定する。*/
+
+	*opt  = DHCP4_OPT_REQ_PARAM;
+	 opt += 2;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST)
+
+	/* 要求オプションリストを設定する。*/
+	if (sizeof(required_plist) > 0) {
+		memcpy(opt, required_plist, sizeof(required_plist));
+		opt += sizeof(required_plist);
+		len += sizeof(required_plist);
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) */
+
+#if defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+
+	/* 要求オプションリストを設定する。*/
+	if (sizeof(request_plist) > 0) {
+		memcpy(opt, request_plist, sizeof(request_plist));
+		opt += sizeof(request_plist);
+		len += sizeof(request_plist);
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUEST_OLIST) */
+
+	*(opt - len - 1) = len;
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST) */
+
+	/* 既にアドレス情報がリースされていれば、同じ IP アドレスを要求する。*/
+	if (ct->act_msg != NULL) {
+		*(opt ++) = DHCP4_OPT_REQ_IPV4;
+		*(opt ++) = sizeof(ct->act_msg->msg.yiaddr);
+		memcpy(opt, (uint8_t*)&ct->act_msg->msg.yiaddr, sizeof(ct->act_msg->msg.yiaddr));
+		opt += sizeof(ct->act_msg->msg.yiaddr);
+		}
+
+	/* クライアント ID（MAC アドレス）を設定する。*/
+	*(opt ++) = DHCP4_OPT_CLIENT_ID;
+	*(opt ++) = ETHER_ADDR_LEN + 1;
+	*(opt ++) = DHCP4_HWA_TYPE_ETHER;
+	memcpy(opt, &ct->sc->ifaddr.lladdr, ETHER_ADDR_LEN);
+	opt += ETHER_ADDR_LEN;
+
+	/* オプションの終了を設定する。*/
+	*(opt ++) = DHCP4_OPT_END;
+
+	/* 送信先アドレスを設定する。*/
+	ct->dst.ipaddr = IPV4_ADDRBROADCAST;
+
+	/* メッセージ長を設定する。*/
+	ct->snd_msg->len = sizeof(ct->snd_msg->msg) - DHCP4_DFLT_OPT_LEN
+	             + (opt - (uint8_t*)&ct->snd_msg->msg.options);
+	return E_OK;
+	}
+
+/*
+ *  ack_msg_timeout -- ACK/NAK メッセージ受信タイムアウト処理
+ */
+
+static void
+ack_msg_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* ACK メッセージを受信していれば。BOUND 状態に遷移する。*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+	if (select_ack(ct)) {
+
+		/* REQUEST メッセージ送信タイマーを停止する。*/
+		DHCP4_CLI_TIMER_LOCK();
+		ct->timers[DHCP4C_TIMER_SND_REQ] = 0;
+		DHCP4_CLI_TIMER_UNLOCK();
+
+		/*
+		 *  状態が REQUEST の時は、
+		 *  OFFER メッセージを受信メッセージ構造体リストに戻す。
+		 */
+		if (ct->fsm == DHCP4_FSM_REQUEST && ct->off_msg != NULL) {
+			syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+			ct->off_msg->next = ct->rcv_lst;
+			ct->rcv_lst = ct->off_msg;
+			syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+			ct->off_msg = NULL;
+			}
+
+		/* BOUND 状態に遷移する。*/
+		start_bound(ct);
+		return;
+		}
+	else {
+
+		/* リース情報を解放する。*/
+		rel_lease(ct);
+
+		ct->error = E_TMOUT;
+		}
+	}
+
+/*
+ *  send_request_msg -- REQUEST メッセージを送信する。
+ */
+
+static void
+send_request_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG	*ref;
+	ER		error;
+	SYSTIM		time;
+	RELTIM		interval;
+	uint16_t	secs;
+
+	/* タイムアウトフラグをクリアーする。*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* ACK メッセージを受信していれば。BOUND 状態に遷移する。*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+	if (select_ack(ct)) {
+
+		/* ACK/NAK メッセージ受信タイマーを停止する。*/
+		DHCP4_CLI_TIMER_LOCK();
+		ct->timers[DHCP4C_TIMER_RCV_ACK] = 0;
+		DHCP4_CLI_TIMER_UNLOCK();
+
+		/*
+		 *  状態が REQUEST の時は、
+		 *  OFFER メッセージを受信メッセージ構造体リストに戻す。
+		 */
+		if (ct->fsm == DHCP4_FSM_REQUEST && ct->off_msg != NULL) {
+			syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+			ct->off_msg->next = ct->rcv_lst;
+			ct->rcv_lst = ct->off_msg;
+			syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+			ct->off_msg = NULL;
+			}
+
+		/* BOUND 状態に遷移する。*/
+		start_bound(ct);
+		return;
+		}
+
+	/* REQUEST メッセージを作成する。*/
+	if (ct->fsm == DHCP4_FSM_REQUEST)
+		ref = ct->off_msg;
+	else
+		ref = ct->act_msg;
+	if ((error = setup_request_msg(ct, ref)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, setup request message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* 送信を開始してからの時間を得る。*/
+	get_tim(&time);
+	interval = time - ct->snd_start;
+
+	/*
+	 * 送信を開始してからの時間（秒）をメッセージに設定する。
+	 * 最大値は 65535。
+	 */
+	if (ct->fsm == DHCP4_FSM_REQUEST)
+		secs = ct->secs;
+	else {
+		if (SYSTIM2SEC(interval) < 65536)
+			secs = SYSTIM2SEC(interval);
+		else
+			secs = 65535;
+		}
+	HOST2MSG16(ct->snd_msg->msg.secs, secs);
+
+	/* ノンブロッキングコールでメッセージを送信する。*/
+	error = udp_snd_dat(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, send request message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* 送信間隔を設定する。*/
+	if (ct->interval == 0)
+		/* 未設定 */
+		ct->interval = TMO_DHCP4C_INIT_INTVL;
+	else
+		/* バックオフアルゴリズムで 2倍にした（乱数使用）送信間隔を加算する。*/
+		ct->interval += (netapp_rand() >> 2) % (ct->interval << 1);
+	
+	/* 送信周期の制限値を超えないようにする。*/
+	if (ct->interval > TMO_DHCP4C_MAX_BACKOFF)
+		ct->interval = (TMO_DHCP4C_MAX_BACKOFF >> 1) + ((netapp_rand() >> 2) % TMO_DHCP4C_MAX_BACKOFF);
+
+	/* リース時間のタイムアウト【先送り】 */
+	if (ct->fsm != DHCP4_FSM_REQUEST &&
+	    TIMEC_GT(ct->interval + time, ct->expire + ct->bind_start))
+		ct->interval = ct->expire + ct->bind_start - time + SYSTIM_HZ;
+
+	/* 再送信タイムアウトを設定する。*/
+	DHCP4_CLI_TIMER_LOCK();
+	ct->timers[DHCP4C_TIMER_SND_REQ] = SYSTIM2TIMER(ct->interval);
+	DHCP4_CLI_TIMER_UNLOCK();
+	}
+
+/*
+ *  send_release_msg -- RELEASE メッセージを送信する。
+ */
+
+static void
+send_release_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	ER		error;
+
+	/* タイムアウトフラグをクリアーする。*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* RELEASE メッセージを作成する。*/
+	if ((error = setup_release_msg(ct, ct->act_msg)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, setup release message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* リース情報を解放する。*/
+	rel_lease(ct);
+
+	/* ノンブロッキングコールでメッセージを送信する。*/
+	error = udp_snd_dat(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, send release message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* メッセージ送信待ちを行う。*/
+	DHCP4_CLI_READY_WAIT(ct);
+
+	/* SLEEP 状態に遷移する。*/
+	ct->fsm = DHCP4_FSM_SLEEP;
+	}
+
+/*
+ *  offer_msg_timeout -- OFFER メッセージ受信タイムアウト処理
+ */
+
+static void
+offer_msg_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* OFFER メッセージを受信していれば。REQUEST 状態に遷移する。*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+	if (select_offer(ct)) {
+
+		/* DISCOVER メッセージ送信タイマーを停止する。*/
+		DHCP4_CLI_TIMER_LOCK();
+		ct->timers[DHCP4C_TIMER_SND_DISC] = 0;
+		DHCP4_CLI_TIMER_UNLOCK();
+
+		/* REQUEST メッセージを送信して REQUEST 状態に遷移する。*/
+		start_send_request(ct, DHCP4_FSM_REQUEST);
+		}
+	else
+		ct->error = E_TMOUT;
+	}
+
+/*
+ *  send_discover_msg -- DISCOVERメッセージを送信する。
+ */
+
+static void
+send_discover_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	ER	error;
+	SYSTIM	time;
+	RELTIM	interval;
+
+	/* タイムアウトフラグをクリアーする。*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* OFFER メッセージを受信していれば。REQUEST 状態に遷移する。*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+	if (select_offer(ct)) {
+
+		/* OFFER メッセージ受信タイマーを停止する。*/
+		DHCP4_CLI_TIMER_LOCK();
+		ct->timers[DHCP4C_TIMER_RCV_OFFER] = 0;
+		DHCP4_CLI_TIMER_UNLOCK();
+
+		/* REQUEST メッセージを送信して REQUEST 状態に遷移する。*/
+		start_send_request(ct, DHCP4_FSM_REQUEST);
+		return;
+		}
+
+	/* DISCOVER メッセージを作成する。*/
+	if ((error = setup_discover_msg(ct)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, setup discover message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* 送信を開始してからの時間を得る。*/
+	get_tim(&time);
+	interval = time - ct->snd_start;
+
+	/*
+	 * 送信を開始してからの時間（秒）をメッセージに設定する。
+	 * 最大値は 65535。
+	 */
+	if (SYSTIM2SEC(interval) < 65536)
+		ct->secs = SYSTIM2SEC(interval);
+	else
+		ct->secs = 65535;
+	HOST2MSG16(ct->snd_msg->msg.secs, ct->secs);
+
+	/* ノンブロッキングコールでメッセージを送信する。*/
+	error = udp_snd_dat(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, send discover message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* 送信間隔を設定する。*/
+	if (ct->interval == 0)
+		/* 未設定 */
+		ct->interval = TMO_DHCP4C_INIT_INTVL;
+	else
+		/* バックオフアルゴリズムで 2倍にした（乱数使用）送信間隔を加算する。*/
+		ct->interval += (netapp_rand() >> 2) % (ct->interval << 1);
+	
+	/* 送信周期の制限値を超えないようにする。*/
+	if (ct->interval > TMO_DHCP4C_MAX_BACKOFF)
+		ct->interval = (TMO_DHCP4C_MAX_BACKOFF >> 1) + ((netapp_rand() >> 2) % TMO_DHCP4C_MAX_BACKOFF);
+
+	/* OFFER メッセージの受信タイムアウトを超えないように調整する。*/
+	if (TIMEC_GT(time + ct->interval, ct->snd_start + TMO_DHCP4C_OFFER))
+		ct->interval = (TMO_DHCP4C_INIT_INTVL + TMO_DHCP4C_OFFER) - time + 1;
+
+	/* 再送信タイムアウトを設定する。*/
+	DHCP4_CLI_TIMER_LOCK();
+	ct->timers[DHCP4C_TIMER_SND_DISC] = SYSTIM2TIMER(ct->interval);
+	DHCP4_CLI_TIMER_UNLOCK();
+	}
+
+#ifdef DHCP4_CLI_TASK
+
+/*
+ *  dhcpc_timer -- TIMER 管理
+ */
+
+static void
+dhcpc_timer (T_DHCP4_CLI_CONTEXT *ct)
+{
+	int ix;
+
+	DHCP4_CLI_TIMER_LOCK();
+	for (ix = NUM_DHCP4C_TIMERS; ix -- > 0; ) {
+		if (ct->timers[ix] != 0) {
+			ct->timers[ix] --;
+			if (ct->timers[ix] == 0) {
+				ct->flags = (ct->flags & ~DHCP4C_FLAG_TMOUT_MASK) | DHCP4C_FLAG_TMOUT_TIMER | ix;
+				DHCP4_CLI_READY_SIGNAL(ct);
+				}
+			}
+		}
+	DHCP4_CLI_TIMER_UNLOCK();
+
+	/* 1秒毎にタイムアウトする。*/
+	timeout((callout_func)dhcpc_timer, ct, NET_TIMER_HZ);
+	}
+
+#endif
+
+/*
+ *  expire_timeout -- EXPIRE タイムアウト処理
+ */
+
+static void
+expire_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	//ER	error;
+
+	/* タイムアウトフラグをクリアーする。*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* 状態が REQUEST の時は何もしない。*/
+	if (ct->fsm == DHCP4_FSM_REQUEST)
+		return;
+
+	/* 全ての TIMER をキャンセルする。*/
+	cancel_all_timers(ct);
+
+	/* リースされた情報を解放する。*/
+	rel_lease(ct);
+
+	ct->error = E_TMOUT;
+	}
+
+/*
+ *  rebind_timeout -- REBIND タイムアウト処理
+ */
+
+static void
+rebind_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* タイムアウトフラグをクリアーする。*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* 全ての TIMER をキャンセルする。*/
+	cancel_all_timers(ct);
+
+	/* REQUEST メッセージを送信して REBIND 状態に遷移する。*/
+	start_send_request(ct, DHCP4_FSM_REBIND);
+	}
+
+/*
+ *  renew_timeout -- RENEW タイムアウト処理
+ */
+
+static void
+renew_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* タイムアウトフラグをクリアーする。*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* REQUEST メッセージを送信して RENEW 状態に遷移する。*/
+	start_send_request(ct, DHCP4_FSM_RENEW);
+	}
+
+/*
+ *  dispatch_timeout -- タイムアウトした時の処理
+ */
+
+static ER
+dispatch_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	switch (ct->flags & DHCP4C_FLAG_TMOUT_TIMER_MASK) {
+
+	case DHCP4C_TIMER_SND_DISC:
+		send_discover_msg(ct);
+		break;
+
+	case DHCP4C_TIMER_SND_REQ:
+		send_request_msg(ct);
+		break;
+
+	case DHCP4C_TIMER_RCV_OFFER:
+		offer_msg_timeout(ct);
+		break;
+
+	case DHCP4C_TIMER_RCV_ACK:
+		ack_msg_timeout(ct);
+		break;
+
+	case DHCP4C_TIMER_RENEW:
+		renew_timeout(ct);
+		break;
+
+	case DHCP4C_TIMER_REBIND:
+		rebind_timeout(ct);
+		break;
+
+	case DHCP4C_TIMER_EXPIRE:
+		expire_timeout(ct);
+		break;
+
+	case DHCP4C_TIMER_SND_REL:
+		send_release_msg(ct);
+		break;
+
+	default:
+		break;
+		}
+
+	return ct->error;
+	}
+
+#ifdef DHCP4_CLI_TASK
+
+/*
+ *  dispatch_event -- イベント毎の処理
+ */
+
+static ER
+dispatch_event (T_DHCP4_CLI_CONTEXT *ct)
+{
+	ER	error = E_OK;
+
+	while (ct->fsm != DHCP4_FSM_SLEEP && error == E_OK) {
+
+		/* メッセージの受信とタイムアウトを待つ。*/
+		DHCP4_CLI_READY_WAIT(ct);
+
+		if (ct->flags & DHCP4C_FLAG_RCV_MSG) {
+			while (ct->val_lst != NULL) {
+				error = eval_rcv_msg(ct);
+				}
+			ct->flags &= ~DHCP4C_FLAG_RCV_MSG;
+			}
+		if (ct->flags & DHCP4C_FLAG_TMOUT_MASK)
+			error = dispatch_timeout(ct);
+
+		if (ct->error != E_OK)
+			error = ct->error;
+		}
+
+	return error;
+	}
+
+#endif
+
+/*
+ *  init_context -- DHCP クライアントコンテキスト構造体を初期化する。
+ */
+
+static void
+init_context (T_DHCP4_CLI_CONTEXT *ct, ID tskid, ID cepid)
+{
+  	memset(ct, 0, sizeof(*ct));
+	ct->tskid	= tskid;
+	ct->cepid	= cepid;
+	ct->sc		= IF_ETHER_NIC_GET_SOFTC();
+	ct->dst.portno	= DHCP4_SRV_CFG_PORTNO;
+	ct->dst.ipaddr	= IPV4_ADDRANY;
+	}
+
+/*
+ *  rel_cli_msg -- メッセージ構造体を解放する。
+ */
+
+static void
+rel_cli_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG	*ptr, *cell;
+
+	for (ptr = ct->rcv_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP4_CLI_MSG, (void*)cell));
+		}
+
+	for (ptr = ct->val_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP4_CLI_MSG, (void*)cell));
+		}
+
+	for (ptr = ct->prf_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP4_CLI_MSG, (void*)cell));
+		}
+
+	if (ct->snd_msg != NULL)
+		syscall(rel_mpf(MPF_DHCP4_CLI_MSG, (void*)ct->snd_msg));
+	ct->rcv_lst = ct->prf_lst = ct->val_lst = ct->snd_msg = NULL;
+	}
+
+/*
+ *  init_cli_msg -- 各メッセージ構造体を初期化する。
+ */
+
+static ER
+init_cli_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG	*cell;
+	ER		error;
+	int		count;
+
+	/* 送信メッセージ構造体を獲得する。*/
+	if ((error = tget_mpf(MPF_DHCP4_CLI_MSG, (void*)&ct->snd_msg, TMO_DHCP4C_MPF_GET)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, tget_mpf() for send: %s.", itron_strerror(error));
+		return error;
+		}
+
+	/*
+	 *  有効なリース・メッセージ構造体がある場合は、
+	 *  獲得する受信メッセージ構造体リストの構造体を 1減らす。
+	 */
+	if (ct->act_msg == NULL)
+		count = NUM_DHCP4_MSG_LIST;
+	else
+		count = NUM_DHCP4_MSG_LIST - 1;
+
+	/* 受信メッセージ構造体を獲得する。*/
+	while (count --> 0) {
+		if ((error = tget_mpf(MPF_DHCP4_CLI_MSG, (void*)&cell, TMO_DHCP4C_MPF_GET)) != E_OK) {
+			syslog(LOG_NOTICE, "[DHCP4C] error, tget_mpf() for receive: %s.", itron_strerror(error));
+			break;
+			}
+		cell->next  = ct->rcv_lst;
+		ct->rcv_lst = cell;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  dhcp4c_renew_info -- ネットワーク情報を再取得する。
+ */
+
+ER
+dhcp4c_renew_info (void)
+{
+	if (context.fsm == DHCP4_FSM_BOUND) {
+
+		/* REL_INFO 状態に遷移した後に SLEEP を解除するように設定する。*/
+		context.flags |= DHCP4C_FLAG_RENEW;
+		start_rel_info(&context);
+		return E_OK;
+		}
+	else if (context.fsm == DHCP4_FSM_SLEEP) {
+
+		/* SLEEP を解除する。*/
+		context.fsm = DHCP4_FSM_WAKE;
+		context.timer = 0;
+		wup_tsk(context.tskid);
+		return E_OK;
+		}
+	else
+		return E_OBJ;
+	}
+
+/*
+ *  dhcp4c_rel_info -- DHCP で設定されたネットワーク情報を解放する。
+ */
+
+ER
+dhcp4c_rel_info (void)
+{
+	/* REL_INFO 状態に遷移する。*/
+	start_rel_info(&context);
+	return E_OK;
+	}
+
+/*
+ *  dhcp4c_get_info -- DHCP で設定されたネットワーク情報を返す。
+ */
+
+ER
+dhcp4c_get_info (T_IN4_ADDR *addr, uint32_t *expire, uint32_t *renew,
+                                   uint32_t *rebind, SYSTIM *bind_start)
+{
+	if (addr  == NULL || expire == NULL || 
+	    renew == NULL || rebind == NULL || bind_start == NULL)
+		return E_PAR;
+	else if (context.act_msg == NULL)
+		return E_OBJ;
+	else {
+		*addr		= context.act_msg->srv.ipaddr;
+		*expire		= context.timers[DHCP4C_TIMER_EXPIRE];
+		*renew		= context.timers[DHCP4C_TIMER_RENEW];
+		*rebind		= context.timers[DHCP4C_TIMER_REBIND];
+		*bind_start	= context.bind_start;
+		return E_OK;
+		}
+	}
+
+/*
+ *  コールバック関数
+ */
+
+ER
+callback_nblk_dhcp4_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	T_DHCP4_CLI_MSG	*msg;
+	ER_UINT		len;
+
+	len = *(ER_UINT*)p_parblk;
+	if (len < 0 && len != E_RLWAI) {
+		/* E_RLWAI 以外で、0 以下の場合は、エラーを意味している。*/
+		syslog(LOG_NOTICE, "[DHCPC(CBR)] error: %s, fncd: %s", itron_strerror(len), in_strtfn(fncd));
+		}
+	else {
+		if (fncd == TEV_UDP_RCV_DAT) {
+
+			/* 受信メッセージリストが空の時は、受信しないでデータグラムを捨てる。*/
+			if (context.rcv_lst == NULL) 
+				syslog(LOG_NOTICE, "[DHCP4C(CBR)] receive buffer all busy.");
+			else {
+				/* メッセージを受信するメッセージ構造体を準備する。*/
+				syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+				msg = context.rcv_lst;
+				context.rcv_lst = context.rcv_lst->next;
+				syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+
+				/* メッセージを受信する。*/
+				len = udp_rcv_dat(context.cepid, &msg->srv, &msg->msg, sizeof(msg->msg), TMO_POL);
+
+				syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+				msg->len = len;
+				if (len >= 0) {
+					/* 受信したメッセージを検証メッセージリストに移す。*/
+					msg->next = context.val_lst;
+					context.val_lst = msg;
+					context.flags |= DHCP4C_FLAG_RCV_MSG;
+					}
+				else {
+					/* メッセージ構造体を受信メッセージリストに戻す。*/
+					context.error = len;
+					msg->next = context.rcv_lst;
+					context.rcv_lst = msg;
+					}
+				syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+				}
+			}
+		DHCP4_CLI_READY_SIGNAL((&context));
+		}
+	return E_OK;
+	}
+
+#ifdef DHCP4_CLI_TASK
+
+/*
+ *  dhcp4_cli_task -- DHCP クライアントタスク
+ */
+
+void
+dhcp4_cli_task (intptr_t exinf)
+{
+	T_DHCP4_CLI_CONTEXT	*ct;
+	ID			tskid;
+	ER			error = E_OK;
+
+	dly_tsk(1000);
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[DHCP4C:%d,%d] started.", tskid, (ID)exinf);
+	dly_tsk(500);
+	ct = &context;
+
+	/* DHCP クライアントコンテキスト構造体を初期化する。*/
+	init_context(ct, tskid, (ID)exinf);
+	ct->fsm = DHCP4_FSM_SLEEP;
+
+	while (true) {
+
+		/* リースを解放後、再取得が指定されていなければ休止する。*/
+		if (!(ct->flags & DHCP4C_FLAG_RENEW)) {
+
+			/* 休止する。*/
+			if (error == E_OK) {
+				if (ct->fsm != DHCP4_FSM_SLEEP)
+					syslog(LOG_NOTICE, "[DHCP4C] lease released, go to sleep.");
+			}
+			else {
+				syslog(LOG_NOTICE, "[DHCP4C] server not available, go to sleep, error: %s.", itron_strerror(error));
+				ct->fsm = DHCP4_FSM_SLEEP;
+				}
+			slp_tsk();
+			}
+		ct->flags = 0;
+		ct->error = E_OK;
+
+		/* 1秒毎にタイムアウトするようにタイマーを設定する。*/
+		timeout((callout_func)dhcpc_timer, ct, NET_TIMER_HZ / DHCP4C_TIMER_HZ);
+
+		/* メッセージ構造体を初期化する。*/
+		if ((error = init_cli_msg(ct)) == E_OK) {
+
+			/* SELECT 状態に遷移する。*/
+			start_select(ct);
+
+			/* メインループ */
+			error = dispatch_event(ct);
+			}
+
+		/* 全ての TIMER をキャンセルする。*/
+		cancel_all_timers(ct);
+
+		/* タイマーを停止する。*/
+		untimeout((callout_func)dhcpc_timer, ct);
+
+		/* メッセージ構造体を解放する。*/
+		rel_cli_msg (ct);
+		}
+	}
+
+#else
+
+T_DHCP4_CLI_CONTEXT *
+dhcp4_cli_initialize(ID tskid, ID cepid)
+{
+	T_DHCP4_CLI_CONTEXT *ct = &context;
+	/* DHCP クライアントコンテキスト構造体を初期化する。*/
+	init_context(ct, tskid, cepid);
+	ct->fsm = DHCP4_FSM_SLEEP;
+	ct->timer = TMO_FEVR;
+	return ct;
+	}
+
+int
+dhcp4_cli_get_timer(T_DHCP4_CLI_CONTEXT *ct)
+{
+	if (ct->fsm == DHCP4_FSM_SLEEP)
+		return TMO_FEVR;
+
+	return ct->timer;
+	}
+
+void
+dhcp4_cli_progress(T_DHCP4_CLI_CONTEXT *ct, int elapse)
+{
+	int ix;
+
+	if ((ct->fsm == DHCP4_FSM_SLEEP) || (ct->timer == TMO_FEVR))
+		return;
+
+	ct->timer -= elapse;
+	if (ct->timer > 0)
+		return;
+
+	/* 1秒毎にタイムアウトするようにタイマーを設定する。*/
+	ct->timer = 1000 * 1000;
+
+	for (ix = NUM_DHCP4C_TIMERS; ix-- > 0; ) {
+		if (ct->timers[ix] != 0) {
+			ct->timers[ix] --;
+			if (ct->timers[ix] <= 0) {
+				ct->timers[ix] = 0;
+				ct->flags = (ct->flags & ~DHCP4C_FLAG_TMOUT_MASK) | DHCP4C_FLAG_TMOUT_TIMER | ix;
+				DHCP4_CLI_READY_SIGNAL(ct);
+				}
+			}
+		}
+	}
+
+void
+dhcp4_cli_wakeup(T_DHCP4_CLI_CONTEXT *ct)
+{
+	if (ct->fsm == DHCP4_FSM_WAKE) {
+		ct->flags = 0;
+		ct->error = E_OK;
+
+		/* メッセージ構造体を初期化する。*/
+		if ((ct->error = init_cli_msg(ct)) != E_OK)
+			return;
+
+		ct->timer = 1000 * 1000;
+
+		/* SELECT 状態に遷移する。*/
+		start_select(ct);
+		}
+
+	if (ct->flags & DHCP4C_FLAG_RCV_MSG) {
+		while (ct->val_lst != NULL) {
+			ct->error = eval_rcv_msg(ct);
+			}
+		ct->flags &= ~DHCP4C_FLAG_RCV_MSG;
+		}
+	}
+
+void
+dhcp4_cli_timeout(T_DHCP4_CLI_CONTEXT *ct)
+{
+	if (ct->flags & DHCP4C_FLAG_TMOUT_MASK)
+		ct->error = dispatch_timeout(ct);
+
+	if (ct->error != E_OK || ct->fsm == DHCP4_FSM_SLEEP) {
+		/* 全ての TIMER をキャンセルする。*/
+		cancel_all_timers(ct);
+		ct->timer = TMO_FEVR;
+
+		/* メッセージ構造体を解放する。*/
+		rel_cli_msg(ct);
+
+		/* リースを解放後、再取得が指定されていなければ休止する。*/
+		if (!(ct->flags & DHCP4C_FLAG_RENEW)) {
+
+			/* 休止する。*/
+			if (ct->error == E_OK) {
+				if (ct->fsm != DHCP4_FSM_SLEEP)
+					syslog(LOG_NOTICE, "[DHCP4C] lease released, go to sleep.");
+			}
+			else {
+				syslog(LOG_NOTICE, "[DHCP4C] server not available, go to sleep, error: %s.", itron_strerror(ct->error));
+				ct->error = E_OK;
+				ct->fsm = DHCP4_FSM_SLEEP;
+				}
+			}
+		}
+	}
+
+#endif /* DHCP4_CLI_TASK */
+#endif	/* of #ifdef DHCP4_CLI_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.cfg	(revision 398)
@@ -0,0 +1,62 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifdef DHCP4_CLI_CFG
+
+/*
+ *  DHCP クライアント
+ *  コンフィギュレーションファイル
+ */
+
+/* タスク */
+
+CRE_TSK(DHCP4_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	UDP4_DHCP_CLI_CEPID,
+	dhcp4_cli_task,
+	DHCP4_CLI_MAIN_PRIORITY,
+	DHCP4_CLI_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
+
+/* セマフォ */
+
+#ifdef DHCP4_CLI_CFG
+
+CRE_SEM(SEM_DHCP4_CLI_READY,	{ TA_TPRI, 0, 1 });
+CRE_SEM(SEM_DHCP4_CLI_TIMER,	{ TA_TPRI, 1, 1 });
+CRE_SEM(SEM_DHCP4_CLI_LOCK,	{ TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.h	(revision 398)
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2004 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.    All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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 Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM 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 INTERNET SOFTWARE CONSORTIUM 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 software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ *
+ * This client was substantially modified and enhanced by Elliot Poger
+ * for use on Linux while he was working on the MosquitoNet project at
+ * Stanford.
+ *
+ * The current version owes much to Elliot's Linux enhancements, but
+ * was substantially reorganized and partially rewritten by Ted Lemon
+ * so as to use the same networking framework that the Internet Software
+ * Consortium DHCP server uses.   Much system-specific configuration code
+ * was moved into a shell script so that as support for more operating
+ * systems is added, it will not be necessary to port and maintain
+ * system-specific configuration code to these operating systems - instead,
+ * the shell script can invoke the native tools to accomplish the same
+ * purpose.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project 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 DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP4_CLI_H
+#define DHCP4_CLI_H
+
+#include <netapp/dhcp4.h>
+
+/* 
+ *  DHCP クライアントのスタックサイズ
+ */
+
+#define DHCP4_CLI_STACK_SIZE		1024		/* DHCP クライアントタスクのスタックサイズ	*/
+
+/* 
+ *  DHCP クライアントの優先度
+ */
+
+#define DHCP4_CLI_MAIN_PRIORITY		5		/* DHCP クライアントタスクの優先度		*/
+
+/* 推奨度の定義 */
+#define DHCP4_CLI_CFG_PREFER_ADDR	100		/* アドレスの推奨度	*/
+
+/* DHCP クライアントメッセージの受信リストサイズ（2以上指定すること） */
+#define NUM_DHCP4_MSG_LIST		3
+
+/*
+ *  DHCP クライアントメッセージ構造体数【変更禁止】
+ *  +1 は送信用
+ */
+#define NUM_MPF_DHCP4_CLI_MSG		(NUM_DHCP4_MSG_LIST+1)
+
+/* 
+ *  コンパイル時コンフィギュレーション
+ */
+
+/* DHCP 必須オプションリスト */
+
+#ifndef DHCP4_CLI_CFG_REQUIRED_OLIST
+
+#define DHCP4_CLI_CFG_REQUIRED_OLIST {	\
+	DHCP4_OPT_SUBNET_MASK,		\
+	DHCP4_OPT_ROUTER,		\
+}
+
+#endif	/* of #ifndef DHCP4_CLI_CFG_REQUIRED_OLIST */
+
+/* DHCP 要求オプションリスト */
+
+#ifndef DHCP4_CLI_CFG_REQUEST_OLIST
+
+#if defined(USE_RESOLVER)
+
+#define DHCP4_CLI_CFG_REQUEST_OLIST {	\
+	DHCP4_OPT_DNS_SERVER,		\
+	DHCP4_OPT_DOMAIN_NAME,		\
+}
+
+#endif	/* of #if defined(USE_RESOLVER) */
+
+#endif	/* of #ifndef DHCP4_CLI_CFG_REQUEST_OLIST */
+
+/*
+ *  タイムアウト値
+ */
+
+/* 受信タイムアウト	*/
+#define TMO_DHCP4C_OFFER	(ULONG_C(120)*SYSTIM_HZ)	/* OFFER メッセージ	*/
+#define TMO_DHCP4C_ACK		(ULONG_C(60)*SYSTIM_HZ)	/* ACK/NAK メッセージ	*/
+
+/* リース時間の既定値	*/
+#define TMO_DHCP4C_DEF_LEASE	(ULONG_C(12*60*60)*SYSTIM_HZ)	/* 標準時間	*/
+#define TMO_DHCP4C_MIN_LEASE	(ULONG_C(60)*SYSTIM_HZ)	/* 最小時間	*/
+
+/* メッセージの送信周期	*/
+#define TMO_DHCP4C_INIT_INTVL	(ULONG_C(3)*SYSTIM_HZ)		/* 初期値	*/
+#define TMO_DHCP4C_MAX_BACKOFF	(ULONG_C(15)*SYSTIM_HZ)	/* 制限値	*/
+
+/* DHCP サーバへの UDP 送信タイムアウト	*/
+#define TMO_DHCP4C_UDP_SND	ULONG_C(1000000)		/* [us] */
+
+/* メッセージ構造体獲得タイムアウト	*/
+#define TMO_DHCP4C_MPF_GET	ULONG_C(1000000)		/* [us] */
+
+/* ARP 要求を送信してからの待ち時間	*/
+#define TMO_DHCP4C_ARP_WAIT	ULONG_C(1000000)		/* [us] */
+
+/* RELEASE メッセージを送信してからの待ち時間	*/
+#define TMO_DHCP4C_SND_REL_WAIT	ULONG_C(1000000)	/* [us] */
+
+#ifndef _MACRO_ONLY
+
+#ifdef T_IPV4EP_DEFINED
+
+/*
+ *  DHCP クライアントメッセージ構造体
+ */
+
+typedef struct dhcp4_cli_msg {
+	/* 4バイト境界にアラインする。*/
+	T_DHCP4_MSG		msg;		/* DHCP メッセージ構造体	*/
+	struct dhcp4_cli_msg	*next;		/* リストの次のメッセージ構造体	*/
+	T_IPV4EP		srv;		/* サーバのIPv4アドレス/ポート番号 */
+	uint16_t		len;		/* msg の有効長			*/
+	uint16_t		prefer;		/* msg の推奨度			*/
+	uint8_t			type;		/* メッセージタイプ		*/
+	} T_DHCP4_CLI_MSG;
+
+#endif	/*of #ifdef T_IPV4EP_DEFINED */
+
+/*
+ *  コールバック関数
+ */
+
+extern ER callback_nblk_dhcp4_cli (ID cepid, FN fncd, void *p_parblk);
+
+/*
+ *  タスク
+ */
+
+extern void	dhcp4_cli_task(intptr_t exinf);
+
+/*
+ *  関数
+ */
+
+#ifdef T_IN4_ADDR_DEFINED
+
+extern ER dhcp4c_rel_info (void);
+extern ER dhcp4c_renew_info (void);
+extern ER dhcp4c_get_info (T_IN4_ADDR *addr, uint32_t *expire, uint32_t *renew,
+                                             uint32_t *rebind, SYSTIM *bind_start);
+
+#endif	/* of #ifdef T_IN4_ADDR_DEFINED */
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#endif	/* of #ifndef DHCP4_CLI_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_asp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_asp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_asp.cfg	(revision 398)
@@ -0,0 +1,60 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ASP 用 DHCP クライアントのシステムコンフィギュレーションファイル
+ */
+
+/*
+ *  共通 DHCP クライアントのシステムコンフィギュレーションファイルのインクルード
+ */
+
+#ifdef DHCP4_CLI_CFG
+
+INCLUDE("netapp/dhcp4_cli.cfg");
+
+/*
+ * 固定メモリプール
+ */
+
+/* 送受信バッファ */
+
+CRE_MPF(MPF_DHCP4_CLI_MSG, {
+	TA_TFIFO,
+	NUM_MPF_DHCP4_CLI_MSG,
+	sizeof(T_DHCP4_CLI_MSG),
+	NULL,
+	NULL
+	});
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_jsp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_jsp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_jsp.cfg	(revision 398)
@@ -0,0 +1,59 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  JSP 用 DHCP クライアントのシステムコンフィギュレーションファイル
+ */
+
+/*
+ *  共通 DHCP クライアントのシステムコンフィギュレーションファイルのインクルード
+ */
+
+#ifdef DHCP4_CLI_CFG
+
+#include "netapp/dhcp4_cli.cfg"
+
+/*
+ * 固定メモリプール
+ */
+
+/* 送受信バッファ */
+
+CRE_MPF(MPF_DHCP4_CLI_MSG, {
+	TA_TFIFO,
+	NUM_MPF_DHCP4_CLI_MSG,
+	sizeof(T_DHCP4_CLI_MSG),
+	NULL
+	});
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_var.h	(revision 398)
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2004 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.    All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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 Internet Software Consortium 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 INTERNET SOFTWARE CONSORTIUM 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 INTERNET SOFTWARE CONSORTIUM 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 software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ *
+ * This client was substantially modified and enhanced by Elliot Poger
+ * for use on Linux while he was working on the MosquitoNet project at
+ * Stanford.
+ *
+ * The current version owes much to Elliot's Linux enhancements, but
+ * was substantially reorganized and partially rewritten by Ted Lemon
+ * so as to use the same networking framework that the Internet Software
+ * Consortium DHCP server uses.   Much system-specific configuration code
+ * was moved into a shell script so that as support for more operating
+ * systems is added, it will not be necessary to port and maintain
+ * system-specific configuration code to these operating systems - instead,
+ * the shell script can invoke the native tools to accomplish the same
+ * purpose.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project 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 DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP4_CLI_VAR_H
+#define DHCP4_CLI_VAR_H
+
+/*
+ *  DHCP クライアントコンテキスト構造体
+ */
+
+/* TIMER の定義 */
+
+#define DHCP4C_TIMER_SND_DISC	0
+#define DHCP4C_TIMER_SND_REQ	1
+#define DHCP4C_TIMER_SND_REL	2
+#define DHCP4C_TIMER_RCV_OFFER	3
+#define DHCP4C_TIMER_RCV_ACK	4
+#define DHCP4C_TIMER_RENEW	5
+#define DHCP4C_TIMER_REBIND	6
+#define DHCP4C_TIMER_EXPIRE	7
+#define NUM_DHCP4C_TIMERS	8
+
+#define DHCP4C_TIMER_HZ		1
+
+typedef struct dhcp4_cli_context {
+	T_DHCP4_CLI_MSG	*rcv_lst;	/* 受信メッセージ構造体リスト		*/
+	T_DHCP4_CLI_MSG	*val_lst;	/* 検証メッセージ構造体リスト		*/
+	T_DHCP4_CLI_MSG	*prf_lst;	/* 推奨メッセージ構造体リスト		*/
+	T_DHCP4_CLI_MSG	*snd_msg;	/* 送信メッセージ構造体			*/
+	T_DHCP4_CLI_MSG	*off_msg;	/* 通知されたリース・メッセージ構造体	*/
+	T_DHCP4_CLI_MSG	*act_msg;	/* 有効なリース・メッセージ構造体	*/
+	T_IF_SOFTC	*sc;		/* IF のソフトウェア情報		*/
+	T_IPV4EP	dst;		/* 送信先のIPアドレス/ポート番号	*/
+	SYSTIM		snd_start;	/* 送信を開始した時間			*/
+	SYSTIM		bind_start;	/* BINDを開始した時間			*/
+	SYSTIM		expire;		/* リースの有効時間（ms）		*/
+	SYSTIM		renew;		/* RENEW（T1）までの時間（ms）	*/
+	SYSTIM		rebind;		/* REBIND（T2）までの時間（ms）	*/
+	SYSTIM		timers[NUM_DHCP4C_TIMERS];	
+					/* タイマー配列			*/
+	RELTIM		interval;	/* 送信間隔			*/
+	ER_UINT		error;		/* エラー・データ長		*/
+	ID			tskid;		/* タスクID */
+	ID			cepid;		/* CEP ID			*/
+	uint32_t	xid;		/* トランザクション ID		*/
+	uint16_t	flags;		/* 各種フラグ			*/
+	uint16_t	max_prefer;	/* 受信メッセージの最大推奨度	*/
+	uint16_t	secs;		/* seconds since boot began	*/
+	uint8_t		fsm;		/* 現在の状態			*/
+	int timer;
+	} T_DHCP4_CLI_CONTEXT;
+
+/* fsm（状態遷移）の定義 */
+
+#define DHCP4_FSM_INIT		1
+#define DHCP4_FSM_SELECT	2
+#define DHCP4_FSM_REQUEST	3
+#define DHCP4_FSM_BOUND		4
+#define DHCP4_FSM_RENEW		5
+#define DHCP4_FSM_REBIND	6
+#define DHCP4_FSM_INIT_REBOOT	7
+#define DHCP4_FSM_REBOOT	8
+#define DHCP4_FSM_REL_INFO	11	/* DHCPv4 の RFC2131 には無い。*/
+#define DHCP4_FSM_SLEEP		12	/* DHCPv4 の RFC2131 には無い。*/
+#define DHCP4_FSM_WAKE		13	/* DHCPv4 の RFC2131 には無い。*/
+
+/* flag の定義 */
+
+#define DHCP4C_FLAG_TMOUT_SND_DISC	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_SND_DISC)
+#define DHCP4C_FLAG_TMOUT_SND_REQ	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_SND_REQ)
+#define DHCP4C_FLAG_TMOUT_SND_REL	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_SND_REL)
+#define DHCP4C_FLAG_TMOUT_RCV_OFFER	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_RCV_OFFER)
+#define DHCP4C_FLAG_TMOUT_RCV_ACK	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_RCV_ACK)
+#define DHCP4C_FLAG_TMOUT_EXPIRE	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_EXPIRE)
+#define DHCP4C_FLAG_TMOUT_RENEW		(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_RENEW)
+#define DHCP4C_FLAG_TMOUT_REBIND	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_REBIND)
+#define DHCP4C_FLAG_TMOUT_TIMER		UINT_C(0x0010)
+#define DHCP4C_FLAG_TMOUT_TIMER_MASK	UINT_C(0x000f)
+#define DHCP4C_FLAG_TMOUT_MASK		UINT_C(0x001f)
+
+#define DHCP4C_FLAG_RCV_MSG		UINT_C(0x0200)
+#define DHCP4C_FLAG_RENEW		UINT_C(0x0400)
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+/* タイムアウトの計算 */
+
+#define DHCP4C_TMOC(t)		(((t)-1000)+dhcp_rand()%2000)
+
+/* 時間比較 */
+
+#define TIMEC_GT(a,b)		((int32_t)((a)-(b))>0)
+#define TIMEC_GE(a,b)		((int32_t)((a)-(b))>=0)
+
+/* 時間定数の変換 */
+
+#define SYSTIM2TIMER(t)		(((t)<SYSTIM_HZ/DHCP4C_TIMER_HZ)?(DHCP4C_TIMER_HZ):((t)*DHCP4C_TIMER_HZ)/SYSTIM_HZ)
+#define SYSTIM2SEC(t)		(((t)<SYSTIM_HZ)?1:((t)/SYSTIM_HZ))
+#define SEC2TIMER(t)		((t)*DHCP4C_TIMER_HZ)
+#define SEC2SYSTIM(t)		((t)*SYSTIM_HZ)
+
+#endif	/* of #ifndef DHCP4_CLI_VAR_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6.h	(revision 398)
@@ -0,0 +1,326 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP6_H
+#define DHCP6_H
+
+/*
+ *  DHCPv6 に関する定義
+ *
+ *    RFC3315
+ */
+
+/*
+ *  DHCPv6 メッセージの定数の定義
+ */
+
+#define DHCP6_XID_LEN		3
+#define DHCP6_OPTION_LEN	(512-(1+DHCP6_XID_LEN))
+
+/*
+ *  DHCPv6 メッセージ
+ */
+
+typedef struct dhcp6_msg_hdr {
+	uint8_t	type;				/* message type		*/
+	uint8_t	xid[DHCP6_XID_LEN];		/* transaction ID	*/
+	} T_DHCP6_MSG_HDR;
+
+typedef struct dhcp6_msg {
+	T_DHCP6_MSG_HDR	hdr;
+	uint8_t		options[DHCP6_OPTION_LEN];	/* options	*/
+	} T_DHCP6_MSG;
+
+/* message type の定義 */
+
+#define DHCP6_SOLICIT		UINT_C(1)
+#define DHCP6_ADVERTISE		UINT_C(2)
+#define DHCP6_REQUEST		UINT_C(3)
+#define DHCP6_CONFIRM		UINT_C(4)
+#define DHCP6_RENEW		UINT_C(5)
+#define DHCP6_REBIND		UINT_C(6)
+#define DHCP6_REPLY		UINT_C(7)
+#define DHCP6_RELEASE		UINT_C(8)
+#define DHCP6_DECLINE		UINT_C(9)
+#define DHCP6_RECONFIGURE	UINT_C(10)
+#define DHCP6_INFO_REQ		UINT_C(11)
+#define DHCP6_RELAY_FORW	UINT_C(12)
+#define DHCP6_RELAY_REPL	UINT_C(13)
+
+/*
+ *  DHCPv6 オプション
+ */
+
+#define DHCP6_OPT_CLIENTID	UINT_C(1)
+#define DHCP6_OPT_SERVERID	UINT_C(2)
+#define DHCP6_OPT_IA_NA		UINT_C(3)
+#define DHCP6_OPT_IA_TA		UINT_C(4)
+#define DHCP6_OPT_IAADDR	UINT_C(5)
+#define DHCP6_OPT_ORO		UINT_C(6)
+#define DHCP6_OPT_PREFERENCE	UINT_C(7)
+#define DHCP6_OPT_UNICAST	UINT_C(12)
+#define DHCP6_OPT_STATUS_CODE	UINT_C(13)
+#define DHCP6_OPT_RAPID_COMMIT	UINT_C(14)
+#define DHCP6_OPT_NAME_SERVERS	UINT_C(23)
+#define DHCP6_OPT_DOMAIN_SEARCH	UINT_C(24)
+#define DHCP6_OPT_IA_PD		UINT_C(25)
+
+/* hardware address type の定義 */
+
+#define DHCP6_HWA_TYPE_ETHER	UINT_C(1)
+#define DHCP6_HWA_TYPE_IEEE802	UINT_C(6)
+
+/* STATUS CODE の定義 */
+
+#define DHCP6_STAT_SUCCESS	UINT_C(0)
+#define DHCP6_STAT_UNSPECIFID	UINT_C(1)
+#define DHCP6_STAT_NO_AVAIL	UINT_C(2)
+#define DHCP6_STAT_NO_BINDING	UINT_C(3)
+#define DHCP6_STAT_NO_ONLINK	UINT_C(4)
+#define DHCP6_STAT_USE_MCAST	UINT_C(5)
+
+/* 時間定数[s]の定義 */
+
+#define DHCP6_MAX_TIME		UINT_C(0xffffffff)
+
+/*
+ *  オプションのヘッダ部の定義
+ */
+
+/* オプションの共通部 */
+
+typedef struct dhcp6_option {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	} T_DHCP6_OPTION;
+
+/* オプションの共通部 */
+
+/* CLIENTID オプション */
+
+typedef struct dhcp6_opt_clientid {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	} T_DHCP6_OPT_CLIENTID;
+
+/* SERVERID オプション */
+
+typedef struct dhcp6_opt_serverid {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	} T_DHCP6_OPT_SERVERID;
+
+/* IA_NA/IA_PD オプション */
+
+typedef struct dhcp6_opt_ia_na_pd {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	uint32_t	iaid;		/* IA ID		*/
+	uint32_t	renew;		/* renew  timeout (T1)	*/
+	uint32_t	rebind;		/* rebind timeout (T2)	*/
+	} T_DHCP6_OPT_IA_NA_PD;
+
+/* IA_TA オプション */
+
+typedef struct dhcp6_opt_ia_ta {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	uint32_t	iaid;		/* IA ID		*/
+	} T_DHCP6_OPT_IA_TA;
+
+/* IAADDR オプション */
+
+#ifdef T_IN6_ADDR_DEFINED
+
+typedef struct dhcp6_opt_iaaddr {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	T_IN6_ADDR	addr;		/* IPv6 address		*/
+	uint32_t	prefer;		/* preferred lifetime	*/
+	uint32_t	valid;		/* valid     lifetime	*/
+	} T_DHCP6_OPT_IAADDR;
+
+#endif	/* of #ifdef T_IN6_ADDR_DEFINED */
+
+/* ORO オプション */
+
+typedef struct dhcp6_opt_oro {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	} T_DHCP6_OPT_ORO;
+
+/* PREFERENCE オプション */
+
+typedef struct dhcp6_opt_preference {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	uint8_t		prefer;		/* preference value	*/
+	} T_DHCP6_OPT_PREFERENCE;
+
+/* UNICAST オプション */
+
+#ifdef T_IN6_ADDR_DEFINED
+
+typedef struct dhcp6_opt_unicast {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	T_IN6_ADDR	addr;		/* IPv6 address for server*/
+	} T_DHCP6_OPT_UNICAST;
+
+#endif	/* of #ifdef T_IN6_ADDR_DEFINED */
+
+/* STATUS CODE オプション */
+
+typedef struct dhcp6_opt_status_code {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	uint16_t	status;		/* status code		*/
+	} T_DHCP6_OPT_STATUS_CODE;
+
+/* NAME SERVERS オプション */
+
+typedef struct dhcp6_opt_name_servers {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	T_IN6_ADDR	addrs[1];	/* IPv6 address		*/
+	} T_DHCP6_OPT_NAME_SERVERS;
+
+/* DOMAIN SEARCH オプション */
+
+typedef struct dhcp6_opt_domain_search {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	uint8_t		name[1];	/* domain search	*/
+	} T_DHCP6_OPT_DOMAIN_SEARCH;
+
+/*
+ *  DHCPv6 タイミング定数【RFC3315 5.5 参照】
+ *  その他のタイミング定数は dhcp6_cli.h 参照
+ */
+
+#ifdef SYSTIM_HZ
+
+#define TMO_SOL_MAX_DELAY	(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_SOL_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_SOL_MAX_RT		(120*SYSTIM_HZ)	/* 120[s] 	*/
+#define TMO_REQ_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_REQ_MAX_RT		(30*SYSTIM_HZ)	/*  30[s] 	*/
+#define TMO_REQ_MAX_RC		10		/* 再送信回数	*/
+#define TMO_CNF_MAX_DELAY	(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_CNF_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_CNF_MAX_RT		(4*SYSTIM_HZ)	/*   4[s] 	*/
+#define TMO_CNF_MAX_RD		(10*SYSTIM_HZ)	/*  10[s] 	*/
+#define TMO_REN_TIMEOUT		(10*SYSTIM_HZ)	/*  10[s] 	*/
+#define TMO_REN_MAX_RT		(600*SYSTIM_HZ)	/* 600[s] 	*/
+#define TMO_REB_TIMEOUT		(10*SYSTIM_HZ)	/*  10[s] 	*/
+#define TMO_REB_MAX_RT		(600*SYSTIM_HZ)	/* 600[s] 	*/
+#define TMO_INF_MAX_DELAY	(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_INF_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_INF_MAX_RT		(120*SYSTIM_HZ)	/* 120[s] 	*/
+#define TMO_REL_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_REL_MAX_RC		5		/* 再送信回数	*/
+#define TMO_DEC_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_DEC_MAX_RC		5		/* 再送信回数	*/
+#define TMO_REC_TIMEOUT		(2*SYSTIM_HZ)	/*   2[s] 	*/
+#define TMO_REC_MAX_RC		8		/* 再送信回数	*/
+
+#endif	/* of #ifdef SYSTIM_HZ */
+
+/*
+ *  DUID -- DHCP Unique ID
+ */
+
+/* DUID_LLT 構造体 */
+
+typedef struct dhcp6_duid_llt_hdr {
+	uint16_t	code;		/* DUID code		*/
+	uint16_t	type;		/* hardware type	*/
+	uint32_t	time;		/* time			*/
+	} T_DHCP6_DUID_LLT_HDR;
+
+/* DUID_LL 構造体 */
+
+typedef struct dhcp6_duid_ll_hdr {
+	uint16_t	code;		/* DUID code		*/
+	uint16_t	type;		/* hardware type	*/
+	} T_DHCP6_DUID_LL_HDR;
+
+/* DUID タイプ【RFC3315 9参照】*/
+
+#define DUID_LLT		1
+#define DUID_EN			2
+#define DUID_LL			3
+
+/*
+ *  DUID 時間の調整
+ *  DUID 時間の開始は 2001/1/1
+ */
+
+#define DUID_TIME_EPOCH		0
+
+/* リレー転送の最大ホップ数 */
+
+#define HOP_COUNT_LIMIT		32
+
+/*
+ *  IPv6 アドレス
+ */
+
+#define IPV6_ADDR_ALL_DHCP_RELAY_SERVERS_INIT	\
+	{{{ UINT_C(0xff), UINT_C(0x02), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x01), UINT_C(0x00), UINT_C(0x02) }}}
+
+#define IPV6_ADDR_ALL_DHCP_SERVERS_INIT	\
+	{{{ UINT_C(0xff), UINT_C(0x05), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x01), UINT_C(0x00), UINT_C(0x03) }}}
+
+/*
+ *  UDP ポート番号
+ */
+
+#ifndef DHCP6_SRV_CFG_PORTNO
+#define DHCP6_SRV_CFG_PORTNO	547	/* server	*/
+#endif
+
+#ifndef DHCP6_CLI_CFG_PORTNO
+#define DHCP6_CLI_CFG_PORTNO	546	/* client	*/
+#endif
+
+#endif	/* of #ifndef DHCP6_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.c	(revision 398)
@@ -0,0 +1,3221 @@
+/*
+ * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-2003 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ *
+ *   Internet Systems Consortium, Inc.
+ *   950 Charter Street
+ *   Redwood City, CA 94063
+ *   <info@isc.org>
+ *   https://www.isc.org/
+ *
+ * This code is based on the original client state machine that was
+ * written by Elliot Poger.  The code has been extensively hacked on
+ * by Ted Lemon since then, so any mistakes you find are probably his
+ * fault and not Elliot's.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project 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 DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+
+#include <net/if_var.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/dhcp6_cli.h>
+#include <netapp/dhcp6_cli_var.h>
+#include <netapp/resolver.h>
+
+/*
+ *  DHCPv6 クライアントタスク
+ */
+
+#ifdef DHCP6_CLI_CFG
+
+/*
+ *  DHCP 動作モード
+ *
+ *    #define DHCP6_CLI_CFG_MODE で指定する。
+ *
+ */
+
+#if !defined(DHCP6_CLI_CFG_MODE)
+#define DHCP6_CLI_CFG_MODE	DHCP6_CLI_CFG_MODE_DEFAULT
+#endif
+
+/*
+ *  変数
+ */
+
+static const T_IN6_ADDR in6_addr_all_DHCP_relay_servers =
+	IPV6_ADDR_ALL_DHCP_RELAY_SERVERS_INIT;			/* リレー・サーバの IPv6 アドレス	*/
+static T_DHCP6_CLI_CONTEXT	context;			/* クライアントコンテキスト	*/
+
+#ifdef DHCP6_CLI_CFG_REQUIRED_OLIST
+static uint8_t	required_plist[] = DHCP6_CLI_CFG_REQUIRED_OLIST;	/* 必須オプションリスト		*/
+#endif
+
+#ifdef DHCP6_CLI_CFG_REQUEST_OLIST
+static uint8_t	request_plist[] = DHCP6_CLI_CFG_REQUEST_OLIST;		/* 要求オプションリスト		*/
+#endif
+
+/*
+ *  dhcp6_rand -- RFC3315 に規定された乱数を発生する。
+ */
+
+static int32_t
+dhcp6_rand (SYSTIM base)
+{
+	SYSTIM 		range, split;
+	uint32_t	rval;
+
+	split = (base - 1) / 10;
+	if (split == 0)
+		return 0;
+	range = (split * 2) + 10;
+	rval = netapp_rand() % range - split;
+
+	return rval;
+	}
+
+/*
+ *  init_duid -- クライアントの DUID を設定する。
+ */
+
+static void
+init_duid (T_DHCP6_CLI_CONTEXT *ct)
+{
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+
+	/* 動作モードに STATELESS が指定された時は LL 形式にする。*/
+
+	T_DHCP6_DUID_LL_HDR	*ll;
+
+	ll = (T_DHCP6_DUID_LL_HDR*)&ct->duid[0];
+	HOST2MSG16(ll->code, DUID_LL);
+	HOST2MSG16(ll->type, DHCP6_HWA_TYPE_ETHER);
+	memcpy(&ct->duid[sizeof(*ll)], &ct->sc->ifaddr.lladdr, sizeof(ct->sc->ifaddr.lladdr));
+	ct->duid_len = sizeof(*ll) + sizeof(ct->sc->ifaddr.lladdr);	/* DIUD 長を記録する。*/
+
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+	/*
+	 *    動作モードに DHCP6_CLI_CFG_STATEFULL が指定された時は LLT 形式にする。
+	 *    time メンバーには現在の時間[s]を設定する。
+	 *    注意: 暫定的に get_tim() の値を使うが、要検討
+	 */
+
+	T_DHCP6_DUID_LLT_HDR	*llt;
+	SYSTIM			time;
+
+	get_tim(&time);
+	time = SYSTIM2SEC(time) - DUID_TIME_EPOCH;
+	llt = (T_DHCP6_DUID_LLT_HDR*)&ct->duid[0];
+	HOST2MSG16(llt->code, DUID_LLT);
+	HOST2MSG16(llt->type, DHCP6_HWA_TYPE_ETHER);
+	HOST2MSG32(llt->time, time);
+	memcpy(&ct->duid[sizeof(*llt)], &ct->sc->ifaddr.lladdr, sizeof(ct->sc->ifaddr.lladdr));
+	ct->duid_len = sizeof(*llt) + sizeof(ct->sc->ifaddr.lladdr);	/* DIUD 長を記録する。*/
+
+#else	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+	}
+
+/*
+ *  cancel_all_timers -- 全ての TIMER をキャンセルする。
+ */
+
+static void
+cancel_all_timers (T_DHCP6_CLI_CONTEXT *ct)
+{
+	int ix;
+
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	for (ix = NUM_DHCP6C_TIMERS; ix -- > 0; )
+		ct->timers[ix] = 0;
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+	}
+
+/*
+ *  dhcpc_timer -- TIMER 管理
+ */
+
+static void
+dhcpc_timer (T_DHCP6_CLI_CONTEXT *ct)
+{
+	int ix;
+
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	for (ix = NUM_DHCP6C_TIMERS; ix -- > 0; ) {
+		if (ct->timers[ix] != 0) {
+			ct->timers[ix] --;
+			if (ct->timers[ix] == 0) {
+				ct->flags = (ct->flags & ~DHCP6C_FLAG_TMOUT_MASK) | DHCP6C_FLAG_TMOUT_TIMER | ix;
+				syscall(sig_sem(SEM_DHCP6_CLI_READY));
+				}
+			}
+		}
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* 1秒毎にタイムアウトする。*/
+	timeout((callout_func)dhcpc_timer, ct, NET_TIMER_HZ / DHCP6C_TIMER_HZ);
+	}
+
+/*
+ *  find_option -- 指定したオプションを探索する。
+ *
+ *    注意: 引数 len が 0 の時はオプションサイズを検証しない。
+ *          引数 len にはオプション全体のサイズを指定すること。
+ */
+
+static uint8_t *
+find_option (uint8_t *msg, uint_t msg_len, uint_t code, uint_t len)
+{
+	T_DHCP6_OPTION	*hdr;
+	uint8_t		*last;
+
+	last = msg + msg_len;
+	while (msg < last) {
+		hdr = (T_DHCP6_OPTION*)msg;
+		if (MSG2HOST16(hdr->code) == code && (len == 0 || (MSG2HOST16(hdr->len) + sizeof(*hdr)) == len))
+			return msg;
+		else
+			msg += MSG2HOST16(hdr->len) + sizeof(*hdr);
+		}
+	return NULL;
+	}
+
+/*
+ *  find_msg_option -- 指定したオプションを探索する。
+ *
+ *    注意: 引数 len が 0 の時はオプションサイズを検証しない。
+ *          引数 len にはオプション全体のサイズを指定すること。
+ */
+
+static uint8_t *
+find_msg_option (T_DHCP6_CLI_MSG *cli_msg, uint_t code, uint_t len)
+{
+	return find_option(cli_msg->msg.options, cli_msg->len, code, len);
+	}
+
+/*
+ *  is_equal_sid -- メッセージ内の SERVER ID を比較する。
+ */
+
+static bool_t
+is_equal_sid (T_DHCP6_CLI_MSG *msg1, T_DHCP6_CLI_MSG *msg2)
+{
+	T_DHCP6_OPT_SERVERID	*sid1;
+	T_DHCP6_OPT_SERVERID	*sid2;
+
+	if ((sid1 = (T_DHCP6_OPT_SERVERID*)find_msg_option(msg1, DHCP6_OPT_SERVERID, 0)) == NULL)
+		return false;
+	if ((sid2 = (T_DHCP6_OPT_SERVERID*)find_msg_option(msg2, DHCP6_OPT_SERVERID, 0)) == NULL)
+		return false;
+	if (MSG2HOST16(sid1->len) != MSG2HOST16(sid2->len))
+		return false;
+
+	return memcmp((uint8_t*)sid1 + sizeof(*sid1),
+	              (uint8_t*)sid2 + sizeof(*sid2), MSG2HOST16(sid1->len)) == 0;
+	}
+
+/*
+ *  validate_iaaddrs -- アドレス情報（IAADDR）を検証する。
+ */
+
+static ER
+validate_iaaddrs (uint8_t *opt, uint_t len)
+{
+	T_DHCP6_OPT_IAADDR	*iaa;
+
+	/* オプションが IAADDR であることを検証する。*/
+	iaa = (T_DHCP6_OPT_IAADDR*)opt;
+	if (MSG2HOST16(iaa->code) != DHCP6_OPT_IAADDR)
+		return E_PAR;
+
+	while (len > 0) {
+		/* オプション長を検証する。*/
+		if (len < sizeof(*iaa))
+			return E_PAR;
+
+		/* オプション長が T_DHCP6_OPT_IAADDR のサイズと一致していなければエラー */
+		iaa = (T_DHCP6_OPT_IAADDR*)opt;
+		if ((MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) < (sizeof(*iaa) - sizeof(T_DHCP6_OPTION)))
+			return E_PAR;
+
+		/*
+		 *  perferred-lifetime と valid-lifetime の値が矛盾しているときはエラー
+		 *  【RFC3315 (22.6) 参照】
+		 */
+		if (MSG2HOST32(iaa->prefer) > MSG2HOST32(iaa->valid))
+			return E_PAR;
+
+		len -= (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(T_DHCP6_OPTION);
+		opt += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(T_DHCP6_OPTION);
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  validate_ia_na_pd -- IA_NA/IA_PD オプションを検証する。
+ */
+
+static ER
+validate_ia_na_pd (T_DHCP6_CLI_MSG *msg, uint16_t code)
+{
+	T_DHCP6_OPT_IA_NA_PD	*na;
+	uint8_t			*opt;
+
+	/* IA_NA/IA_PD が無ければ検証しない。*/
+	if ((opt = find_msg_option(msg, code, 0)) == NULL)
+		return E_OK;
+
+	/* オプション長を検証する。*/
+	na = (T_DHCP6_OPT_IA_NA_PD*)opt;
+	if (!(msg->len >= (opt - (uint8_t*)&msg->msg) + sizeof(*na) &&
+	                         (MSG2HOST16(na->len) & ~DHCP6C_IAA_FLAG_MASK) >= sizeof(*na)))
+		return E_PAR;
+
+	/*
+	 *  T1 と T2 の値が矛盾している時、またはアドレス情報が誤っている時はエラー
+	 *  【RFC3315 (22.4) 参照】
+	 */
+	if (MSG2HOST32(na->renew) > 0 && MSG2HOST32(na->rebind) > 0 &&
+	    MSG2HOST32(na->renew) >      MSG2HOST32(na->rebind))
+		return E_PAR;
+
+	if (validate_iaaddrs(opt + sizeof(*na), (MSG2HOST16(na->len) & ~DHCP6C_IAA_FLAG_MASK) - (sizeof(*na) - sizeof(T_DHCP6_OPTION))) != E_OK)
+		return E_PAR;
+
+	return E_OK;
+	}
+
+/*
+ *  validate_ia_ta -- IA_TA オプションを検証する。
+ */
+
+static ER
+validate_ia_ta (T_DHCP6_CLI_MSG *msg)
+{
+	T_DHCP6_OPT_IA_TA	*ta;
+	uint8_t			*opt;
+
+	/* IA_TA が無ければ検証しない。*/
+	if ((opt = find_msg_option(msg, DHCP6_OPT_IA_TA, 0)) == NULL)
+		return E_OK;
+
+	/* オプション長を検証する。*/
+	ta = (T_DHCP6_OPT_IA_TA	*)opt;
+	if (!(msg->len >= (opt - (uint8_t*)&msg->msg) + sizeof(*ta) &&
+	                         (MSG2HOST16(ta->len) & ~DHCP6C_IAA_FLAG_MASK) >= sizeof(*ta)))
+		return E_PAR;
+
+	/*
+	 *  アドレス情報が誤っている時はエラー【RFC3315 (22.4) 参照】
+	 */
+	if (validate_iaaddrs(opt + sizeof(*ta), (MSG2HOST16(ta->len) & ~DHCP6C_IAA_FLAG_MASK) - (sizeof(*ta) - sizeof(T_DHCP6_OPTION))) != E_OK)
+		return E_PAR;
+
+	return E_OK;
+	}
+/*
+ *  classify_reply -- 応答メッセージを分類する。
+ */
+
+static ER
+classify_reply (T_DHCP6_CLI_MSG *msg)
+{
+	ER	error;
+
+	/* IA_NA オプションを検証する。*/
+	if ((error = validate_ia_na_pd(msg, DHCP6_OPT_IA_NA)) != E_OK)
+		return error;
+
+	/* IA_TA オプションを検証する。*/
+	if ((error = validate_ia_ta(msg)) != E_OK)
+		return error;
+
+	/* IA_PD オプションを検証する。*/
+	if ((error = validate_ia_na_pd(msg, DHCP6_OPT_IA_PD)) != E_OK)
+		return error;
+
+	/* サーバ DUID があることを検証する。*/
+	if (find_msg_option(msg, DHCP6_OPT_SERVERID, 0) == NULL)
+		return E_PAR;
+
+	return E_OK;
+	}
+
+/*
+ *  validate_reply -- 応答メッセージを検証する。
+ */
+
+static ER
+validate_reply (T_DHCP6_CLI_CONTEXT *ct, T_DHCP6_CLI_MSG *msg)
+{
+	T_DHCP6_OPT_CLIENTID	*cid;
+	uint8_t			*opt;
+
+	/* サーバ DUID があることを検証する。*/
+	if (find_msg_option(msg, DHCP6_OPT_SERVERID, 0) == NULL)
+		return E_PAR;
+
+	/* クライアント DUID があり、自分のクライアント DUID と同じことを検証する。*/
+	if ((opt = find_msg_option(msg, DHCP6_OPT_CLIENTID, 0)) == NULL)
+		return E_PAR;
+
+	cid = (T_DHCP6_OPT_CLIENTID*)opt;
+	if (MSG2HOST16(cid->len) != ct->duid_len)
+		return E_PAR;
+	if (memcmp(opt + sizeof(*cid), ct->duid, ct->duid_len) != 0)
+		return E_PAR;
+
+	return E_OK;
+	}
+
+/*
+ *  get_status_code -- STATUS オプションの結果コードを獲得する。
+ */
+
+static ER_UINT
+get_status_code (uint8_t *msg, uint_t msg_len)
+{
+	T_DHCP6_OPT_STATUS_CODE	*status;
+	uint8_t			*opt;
+
+	/* STATUS オプションが無ければ検証しない。*/
+	if ((opt = find_option(msg, msg_len, DHCP6_OPT_STATUS_CODE, 0)) == NULL)
+		return DHCP6_STAT_SUCCESS;
+
+	/* オプション長を検証する。*/
+	status = (T_DHCP6_OPT_STATUS_CODE*)opt;
+	if (msg_len < sizeof(*status))
+		return E_PAR;
+	if (MSG2HOST16(status->len) < sizeof(*status) - sizeof(T_DHCP6_OPTION))
+		return E_PAR;
+
+	return MSG2HOST16(status->status);
+	}
+
+/*
+ *  get_msg_status_code -- STATUS オプションの結果コードを獲得する。
+ */
+
+static ER_UINT
+get_msg_status_code (T_DHCP6_CLI_MSG *cli_msg, uint_t *code)
+{
+	T_DHCP6_OPTION		*opt;
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	T_DHCP6_OPT_IA_TA	*ta;
+	ER_UINT			status;
+	uint8_t			*msg, *last;
+
+	*code = 0;
+	cli_msg->status = DHCP6_CLI_STAT_UNDEFINED;
+	if ((status = get_status_code(cli_msg->msg.options, cli_msg->len)) == DHCP6_STAT_SUCCESS) {
+
+		msg = cli_msg->msg.options;
+		last = msg + (cli_msg->len - sizeof(T_DHCP6_MSG_HDR));
+		while (msg < last) {
+
+			opt = (T_DHCP6_OPTION*)msg;
+			status = get_status_code(msg + sizeof(*opt), MSG2HOST16(opt->len));
+			if (status != DHCP6_STAT_SUCCESS) {
+				*code = MSG2HOST16(opt->code);
+				break;
+				}
+
+			if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_NA || MSG2HOST16(opt->code) == DHCP6_OPT_IA_PD) {
+
+				ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+				status = get_status_code(msg + sizeof(*opt), MSG2HOST16(ia->len));
+				if (status != DHCP6_STAT_SUCCESS) {
+					*code = MSG2HOST16(((T_DHCP6_OPTION*)((uint8_t*)opt + sizeof(*opt)))->code);
+					break;
+					}
+				}
+
+			else if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_TA) {
+
+				ta = (T_DHCP6_OPT_IA_TA*)opt;
+				status = get_status_code(msg + sizeof(*opt), MSG2HOST16(ta->len));
+				if (status != DHCP6_STAT_SUCCESS) {
+					*code = MSG2HOST16(((T_DHCP6_OPTION*)((uint8_t*)opt + sizeof(*opt)))->code);
+					break;
+					}
+				}
+
+			msg += MSG2HOST16(opt->len) + sizeof(*opt);
+			}
+		cli_msg->status = status;
+		}
+	
+	return status;
+	}
+
+/*
+ *  validate_rcv_msg -- 受信メッセージを検証する。
+ */
+
+static ER
+validate_rcv_msg (T_DHCP6_CLI_CONTEXT *ct, T_DHCP6_CLI_MSG *msg)
+{
+	ER	error;
+	uint_t	code;
+
+	/* メッセージのタイプが一致していることを検証する。*/
+	switch (ct->fsm) {
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	case DHCP6_FSM_SELECT:
+		if (msg->msg.hdr.type != DHCP6_REPLY)
+			return E_PAR;
+		break;
+	case DHCP6_FSM_INFORMED:
+		return E_PAR;
+		break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	case DHCP6_FSM_INIT:
+		if (msg->msg.hdr.type != DHCP6_ADVERTISE)
+			return E_PAR;
+		break;
+
+	case DHCP6_FSM_SELECT:
+	case DHCP6_FSM_RENEW:
+	case DHCP6_FSM_REBIND:
+	case DHCP6_FSM_REL_INFO:
+		if (msg->msg.hdr.type != DHCP6_REPLY)
+			return E_PAR;
+		break;
+
+	case DHCP6_FSM_BOUND:
+		return E_PAR;
+		break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+	default:
+		syslog(LOG_NOTICE, "[DHCP6C] error, unknown state: %d.", ct->fsm);
+		return E_PAR;
+		break;
+		}
+
+	/* 受信メッセージを検証する。*/
+	if ((error = validate_reply(ct, msg)) != E_OK)
+		return error;
+
+	/* 受信メッセージを分類する。*/
+	if ((error = classify_reply(msg)) != E_OK)
+		return error;
+
+	/* 受信したメッセージ内の STATUS CODE オプションを検証する。*/
+	error = get_msg_status_code(msg, &code);
+	if (error != E_OK)
+		return error > 0 ? E_PAR : error;
+
+	return E_OK;
+	}
+
+/*
+ *  eval_ia_prefer -- IA_NA/IA_TA/IA_PD の推奨度を評価する。
+ */
+
+static void
+eval_ia_prefer (T_DHCP6_CLI_MSG *cli_msg)
+{
+	T_DHCP6_OPTION		*opt;
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	T_DHCP6_OPT_IA_TA	*ta;
+	T_DHCP6_OPT_IAADDR	*iaa;
+	uint8_t		*msg, *last;
+	uint_t		aoff, asize;
+
+	/* 無効の場合は終了する。*/
+	if (cli_msg == NULL)
+		return;
+
+	msg = cli_msg->msg.options;
+	last = msg + (cli_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	while (msg < last) {
+		opt = (T_DHCP6_OPTION*)msg;
+
+		if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_NA || MSG2HOST16(opt->code) == DHCP6_OPT_IA_PD) {
+
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			aoff  = sizeof(*ia);
+			asize = MSG2HOST16(ia->len) + sizeof(*opt);
+			while (aoff < asize) {
+				cli_msg->prefer += DHCP6_CLI_CFG_PREFER_IAADDR;
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				aoff += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(*iaa);
+				}
+			cli_msg->prefer = (cli_msg->prefer + DHCP6_CLI_CFG_PREFER_IA) | DHCP6_ClI_MSG_PREFER_ADDR;
+			}
+
+		else if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_TA) {
+
+			ta = (T_DHCP6_OPT_IA_TA*)opt;
+			aoff  = sizeof(*ta);
+			asize = MSG2HOST16(ta->len) + sizeof(*opt);
+			while (aoff < asize) {
+				cli_msg->prefer += DHCP6_CLI_CFG_PREFER_IAADDR;
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				aoff += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(*iaa);
+				}
+			cli_msg->prefer = (cli_msg->prefer + DHCP6_CLI_CFG_PREFER_IA) | DHCP6_ClI_MSG_PREFER_ADDR;
+			}
+
+		msg += MSG2HOST16(opt->len) + sizeof(*opt);
+		}
+
+	}
+
+/*
+ *  eval_prefer -- 受信メッセージの推奨度を評価する。
+ */
+
+static void
+eval_prefer (T_DHCP6_CLI_MSG *msg)
+{
+	uint8_t			*opt;
+	int			ix;
+
+	/* 無効の場合は終了する。*/
+	if (msg == NULL)
+		return;
+
+	/* PREFERENCE オプションを評価する。*/
+	if ((opt = find_msg_option(msg, DHCP6_OPT_PREFERENCE, sizeof(T_DHCP6_OPT_PREFERENCE))) != NULL)
+		msg->prefer = MSG2HOST16(((T_DHCP6_OPT_PREFERENCE*)opt)->prefer) | DHCP6_ClI_MSG_PREFER_OPTION;
+	else
+		msg->prefer = 1;
+
+#if defined(DHCP6_CLI_CFG_REQUIRED_OLIST)
+
+	/* 必須オプションを検証する。*/
+	for (ix = sizeof(required_plist); ix -- > 0; ) {
+		if (find_msg_option(msg, required_plist[ix], 0) == NULL)
+			msg->prefer = 0;
+		}
+	msg->prefer |= DHCP6_ClI_MSG_PREFER_REQUIRED;
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_REQUIRED_OLIST) */
+
+#if defined(DHCP6_CLI_CFG_REQUEST_OLIST)
+
+	/* 要求オプションを検証する。*/
+	for (ix = sizeof(request_plist); ix -- > 0; ) {
+		if (find_msg_option(msg, request_plist[ix], 0) != NULL)
+			msg->prefer = (msg->prefer + 1) | DHCP6_ClI_MSG_PREFER_REQUEST;
+		}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_REQUEST_OLIST) */
+	}
+
+/*
+ *  eval_rcv_msg -- 受信メッセージを評価する。
+ */
+
+static ER
+eval_rcv_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG	*evl, *msg;
+	SYSTIM		time;
+
+	/* メッセージを受信していなければ中止する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	if (ct->val_lst == NULL) {
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return E_OK;
+		}
+
+	/* 検証メッセージリストから評価メッセージを取り出す。*/
+	evl         = ct->val_lst;
+	ct->val_lst = ct->val_lst->next;
+	evl->next   = NULL;
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+	/* 受信時間を設定する。*/
+	get_tim(&time);
+	evl->rcv_time = time;
+
+	/* 評価メッセージを検証する。*/
+	if (validate_rcv_msg(ct, evl) != E_OK) {
+
+		/* エラーが発生した評価メッセージを受信メッセージ構造体リストに戻す。*/
+		goto rcv_ret;
+		}
+
+	/* REL_INFO 状態の時の処理 */
+	if (ct->fsm == DHCP6_FSM_REL_INFO) {
+		syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+		if (evl->status == DHCP6_STAT_SUCCESS) {
+			/*
+			 *  STATUS CODE が DHCP6_STAT_SUCCESS なら、
+			 *  評価メッセージを推奨メッセージリストに設定して終了する。
+			 */
+			evl->next   = ct->prf_lst;
+			ct->prf_lst = evl;
+			}
+		else {
+			/* 評価メッセージを受信メッセージ構造体リストに戻して終了する。*/
+			evl->next   = ct->rcv_lst;
+			ct->rcv_lst = evl;
+			}
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return E_OK;
+		}
+
+	/* 評価メッセージの推奨度を評価する。*/
+	eval_prefer(evl);
+	eval_ia_prefer(evl);
+
+	/* 推奨メッセージリストが空なら評価メッセージを移して終了する。*/
+	if (ct->prf_lst == NULL) {
+		ct->max_prefer = evl->prefer & DHCP6_ClI_MSG_PREFER_VALUE_MASK;
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+
+	/* 評価メッセージの推奨度と推奨メッセージリストの最大推奨度を比較する。*/
+	if ((evl->prefer & DHCP6_ClI_MSG_PREFER_VALUE_MASK) > ct->max_prefer) {
+
+		/* 
+		 *  評価メッセージの推奨度が推奨メッセージリストの最大推奨度より高ければ、
+		 *  推奨メッセージリストを受信メッセージ構造体リストに戻し、
+		 *  評価メッセージを推奨メッセージリストに移す。
+		 */
+		ct->max_prefer = evl->prefer & DHCP6_ClI_MSG_PREFER_VALUE_MASK;
+		syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+		if (ct->rcv_lst == NULL)
+			ct->rcv_lst = ct->prf_lst;
+		else {
+			for (msg = ct->rcv_lst; msg->next != NULL; msg = msg->next)
+				;
+			msg->next = ct->prf_lst;
+			}
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+
+	else if ((evl->prefer & DHCP6_ClI_MSG_PREFER_VALUE_MASK) == ct->max_prefer) {
+		for (msg = ct->prf_lst; msg != NULL; msg = msg->next) {
+			if (is_equal_sid(evl, msg)) {
+
+				/*
+				 *  推奨メッセージリストに同じ DHCP6_OPT_SERVERID のメッセージがあれば、
+				 *  評価メッセージを受信メッセージ構造体リストに戻す。
+				 */
+				goto rcv_ret;
+				}
+			}
+
+		/* 
+		 *  評価メッセージを推奨メッセージリストに移す。
+		 */
+		evl->next   = ct->prf_lst;
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+	
+	/*else */
+		/* 
+		 *  評価メッセージの推奨度が推奨メッセージリストの最大推奨度より低ければ、
+		 *  評価メッセージを受信メッセージ構造体リストに戻す。
+		 */
+
+rcv_ret:
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	evl->next   = ct->rcv_lst;
+	ct->rcv_lst = evl;
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+	return E_OK;
+	}
+
+/*
+ *  select_msg -- 推奨メッセージリストの先頭のメッセージを選択する。
+ */
+
+static T_DHCP6_CLI_MSG*
+select_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG		*msg, *select;
+
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	if (ct->prf_lst == NULL) {
+		/* メッセージを受信していなければ中止する。*/
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return NULL;
+		}
+
+	select = ct->prf_lst;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+
+	if ((select->prefer & DHCP6_ClI_MSG_PREFER_REQUIRED) == 0) {
+		/* 必須オプションが無ければ選択しない。*/
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return NULL;
+		}
+
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+	if (((select->prefer & DHCP6_ClI_MSG_PREFER_REQUIRED) == 0) ||
+	    ((select->prefer & DHCP6_ClI_MSG_PREFER_ADDR)     == 0)) {
+		/* 必須オプションとアドレスが無ければ選択しない。*/
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return NULL;
+		}
+
+#else	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+	/* 推奨メッセージリストの先頭のメッセージを選択する。*/
+	ct->prf_lst  = ct->prf_lst->next;
+	select->next = NULL;
+
+	/* 選択されなかった検証メッセージを受信メッセージ構造体リストに戻す。*/
+	if (ct->rcv_lst == NULL)
+		ct->rcv_lst = ct->prf_lst;
+	else {
+		for (msg = ct->rcv_lst; msg->next != NULL; msg = msg->next)
+			;
+		msg->next = ct->prf_lst;
+		}
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+	return select;
+	}
+
+/*
+ *  advance_retrans -- 再送信タイムアウトを更新する。
+ */
+
+static void
+advance_retrans (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/*
+	 *  再送信間隔（RT）を更新する。
+	 *  再送信毎に約 2倍するが、
+	 *  最大送信間隔（MRT）を超えないようにする。
+	 */
+	ct->RT += ct->RT + dhcp6_rand(ct->RT);
+	if ((ct->MRT != 0) && (ct->RT > ct->MRT))
+		ct->RT = ct->MRT + dhcp6_rand(ct->MRT);
+
+	/* 再送信回数を更新する。*/
+	ct->txcount ++;
+	}
+
+/*
+ *  init_retrans -- 再送信回数、トランザクション ID、その他を設定する。
+ */
+
+static void
+init_retrans (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* 送信回数をリセットする。*/
+	ct->txcount = 0;
+
+	/* 再送信間隔を設定する。*/
+	ct->RT = ct->IRT + dhcp6_rand(ct->IRT);
+
+	/* トランザクション ID を設定する。*/
+	ct->xid = netapp_rand() % 0x00ffffff;
+
+	/* 受信メッセージの最大推奨度をリセットする。*/
+	ct->max_prefer = 0;
+	}
+
+/*
+ *  setup_msg_header -- メッセージのヘッダ部分を作成する。
+ */
+
+static uint8_t *
+setup_msg_header (T_DHCP6_CLI_CONTEXT *ct, uint_t type)
+{
+	memset((void*)&ct->snd_msg->msg, sizeof(ct->snd_msg->msg), 0);
+	ct->snd_msg->len = sizeof(ct->snd_msg->msg);
+
+	/* ヘッダ部を設定する。*/
+	ct->snd_msg->msg.hdr.type   = type;
+	ct->snd_msg->msg.hdr.xid[0] = (ct->xid >> 16) & 0xff;
+	ct->snd_msg->msg.hdr.xid[1] = (ct->xid >>  8) & 0xff;
+	ct->snd_msg->msg.hdr.xid[2] =  ct->xid        & 0xff;
+
+	return (uint8_t*)&ct->snd_msg->msg + sizeof(ct->snd_msg->msg.hdr);
+	}
+
+/*
+ *  common_options -- 標準オプションを追加する。
+ */
+
+static uint8_t *
+common_options (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t type, T_DHCP6_CLI_MSG *lease)
+{
+	T_DHCP6_OPT_CLIENTID	*cid;
+	T_DHCP6_OPT_SERVERID	*sid;
+
+#if defined(DHCP6_CLI_CFG_REQUIRED_OLIST) || defined(DHCP6_CLI_CFG_REQUEST_OLIST)
+	T_DHCP6_OPT_ORO		*oro;
+#endif
+
+	uint8_t			*opt;
+	uint_t			opt_len;
+	int_t			ix;
+
+#if defined(DHCP6_CLI_CFG_RAPID_COMMIT)
+
+	/* Rapid-commit の指定 */
+	if (type == DHCP6_SOLICIT)
+		;
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_RAPID_COMMIT) */
+
+	/* クライアント DUID を追加する。*/
+	cid = (T_DHCP6_OPT_CLIENTID*)msg;
+	HOST2MSG16(cid->code, DHCP6_OPT_CLIENTID);
+	HOST2MSG16(cid->len,  ct->duid_len);
+	memcpy(msg + sizeof(T_DHCP6_OPT_CLIENTID), ct->duid, ct->duid_len);
+	msg += ct->duid_len + sizeof(T_DHCP6_OPT_CLIENTID);
+
+	/* サーバ DUID を追加する。*/
+	if (lease == NULL) {
+		if (!(type == DHCP6_SOLICIT || type == DHCP6_INFO_REQ))
+			return NULL;
+		}
+	else if (!(type == DHCP6_CONFIRM || type == DHCP6_REBIND)) {
+		if ((opt = find_msg_option(lease, DHCP6_OPT_SERVERID, 0)) != NULL) {
+			sid = (T_DHCP6_OPT_SERVERID*)opt;
+			opt_len = MSG2HOST16(sid->len);
+			memcpy(msg, opt, opt_len + sizeof(*sid));
+			msg += opt_len + sizeof(*sid);
+			}
+		}
+
+#if defined(DHCP6_CLI_CFG_REQUIRED_OLIST) || defined(DHCP6_CLI_CFG_REQUEST_OLIST)
+
+	/* 必須・要求オプションを追加する。*/
+	oro = (T_DHCP6_OPT_ORO*)msg;
+	HOST2MSG16(oro->code, DHCP6_OPT_ORO);
+	HOST2MSG16(oro->len, 0);
+	msg += sizeof(oro->code) + sizeof(oro->len);
+
+#if defined(DHCP6_CLI_CFG_REQUIRED_OLIST)
+
+	/* 必須オプションを追加する。*/
+	HOST2MSG16(oro->len, MSG2HOST16(oro->len) + sizeof(required_plist) * 2);
+	for (ix = sizeof(required_plist); ix -- > 0; ) {
+		host2msg16(msg, required_plist[ix]);
+		msg += sizeof(uint16_t);
+		}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_REQUIRED_OLIST) */
+
+#if defined(DHCP6_CLI_CFG_REQUEST_OLIST)
+
+	/* 要求オプションを追加する。*/
+	HOST2MSG16(oro->len, MSG2HOST16(oro->len) + sizeof(request_plist) * 2);
+	for (ix = sizeof(request_plist); ix -- > 0; ) {
+		host2msg16(msg, request_plist[ix]);
+		msg += sizeof(uint16_t);
+		}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_REQUEST_OLIST) */
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_REQUIRED_OLIST) || defined(DHCP6_CLI_CFG_REQUEST_OLIST) */
+
+	return msg;
+	}
+
+/*
+ *  rel_lease -- リースされたオプションを解析して値を解放する。
+ */
+
+static void
+rel_lease (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPTION			*hdr;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+	T_DHCP6_OPT_IA_NA_PD		*ia;
+	T_DHCP6_OPT_IAADDR		*iaa;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL */
+
+	uint8_t		*opt, *last;
+
+	/* 有効なリース・メッセージ構造体が無ければ何もしない。*/
+	if (ct->act_msg == NULL)
+		return;
+
+	opt  = ct->act_msg->msg.options;
+	last = opt + (ct->act_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	while (opt < last) {
+		hdr = (T_DHCP6_OPTION*)opt;
+		switch (MSG2HOST16(hdr->code)) {
+
+		case DHCP6_OPT_NAME_SERVERS:
+			dns_in6_set_addr(NULL);
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+			syslog(LOG_NOTICE, "[DHCP6C] release DNS server addr.");
+#endif
+			break;
+
+		case DHCP6_OPT_DOMAIN_SEARCH:
+			dns_in6_set_dname(NULL, 0);
+			break;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+		case DHCP6_OPT_IA_NA:
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			if (MSG2HOST16(ia->len) > sizeof(*iaa)) {
+				iaa = (T_DHCP6_OPT_IAADDR*)(opt + sizeof(*ia));
+				in6_del_ifaddr(&iaa->addr);
+				}
+			break;
+
+		case DHCP6_OPT_IA_TA:
+			break;
+
+		case DHCP6_OPT_IA_PD:
+			break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL */
+
+		default:
+			break;
+			}
+		opt += MSG2HOST16(hdr->len) + sizeof(*hdr);
+		}
+	}
+
+/*
+ *  set_lease -- リースされたオプションを解析して値を設定する。
+ */
+
+static void
+set_lease (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPTION			*hdr;
+	T_DHCP6_OPT_NAME_SERVERS	*ns;
+	T_DHCP6_OPT_DOMAIN_SEARCH	*ds;
+	const uint8_t			*dname;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+	T_DHCP6_OPT_IA_NA_PD		*ia;
+	T_DHCP6_OPT_IAADDR		*iaa;
+	SYSTIM				time, delay;
+	ER				error;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL */
+
+	uint8_t		*opt, *last;
+
+	opt  = ct->act_msg->msg.options;
+	last = opt + (ct->act_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	while (opt < last) {
+		hdr = (T_DHCP6_OPTION*)opt;
+		switch (MSG2HOST16(hdr->code)) {
+
+		case DHCP6_OPT_NAME_SERVERS:
+			ns = (T_DHCP6_OPT_NAME_SERVERS*)opt;
+			dns_in6_set_addr(&ns->addrs[0]);
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+			syslog(LOG_NOTICE, "[DHCP6C] set DNS server addr: %s.", ipv62str(NULL, &ns->addrs[0]));
+#endif
+			break;
+
+		case DHCP6_OPT_DOMAIN_SEARCH:
+			ds = (T_DHCP6_OPT_DOMAIN_SEARCH*)opt;
+			dname = dns_in6_set_dname(ds->name, MSG2HOST16(ds->len));
+			break;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+		case DHCP6_OPT_IA_NA:
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			if (MSG2HOST16(ia->len) > sizeof(*iaa)) {
+				get_tim(&time);
+				delay = time - ct->act_msg->rcv_time;
+				iaa = (T_DHCP6_OPT_IAADDR*)(opt + sizeof(*ia));
+				error = in6_upd_ifaddr(&iaa->addr, 64, MSG2HOST32(iaa->valid)  - SYSTIM2SEC(delay),
+				                                       MSG2HOST32(iaa->prefer) - SYSTIM2SEC(delay));
+				if (error == E_OK)
+					syslog(LOG_NOTICE, "[DHCP6C] set IPv6 addr: %s.", ipv62str(NULL, &iaa->addr));
+				else
+					syslog(LOG_NOTICE, "[DHCP6C] set IPv6 addr, error: %s.", itron_strerror(error));
+				}
+			break;
+
+		case DHCP6_OPT_IA_TA:
+			break;
+
+		case DHCP6_OPT_IA_PD:
+			break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL */
+
+		default:
+			break;
+			}
+		opt += MSG2HOST16(hdr->len) + sizeof(*hdr);
+		}
+	}
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+/*
+ *  start_req_info -- INFO-REQUEST を開始する。
+ *
+ *    注意: DHCPv6 の RFC3315 には無い
+ */
+
+static void
+start_req_info (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* タイムアウトを設定する。【RFC3315 (18.1.5) 参照】*/
+	ct->IRT = TMO_INF_TIMEOUT;
+	ct->MRT = TMO_INF_MAX_RT;
+	ct->MRC = 0;
+
+	/* DHCP6_CLI_CFG_ONE_TRYが指定されていなければ標準タイムアウトまで再送する。*/
+#if defined(DHCP6_CLI_CFG_ONE_TRY)
+	ct->MRD = 0;
+#else
+	ct->MRD = TMO_DHCP6C_NORMAL;
+#endif
+
+	/* 再送回数とトランザクション ID を設定する。*/
+	init_retrans(ct);
+
+	/* REPLY メッセージの受信タイムアウトを設定する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RCV_REPLY] = SYSTIM2TIMER(ct->MRD);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/*
+	 *  INFO-REQUEST メッセージ送信遅延時間を設定する。
+	 *  ただし、TMO_INF_MAX_DELAY が 1[s]なので、dly_tsk()を使用する。
+	 */
+	dly_tsk(netapp_rand() % TMO_INF_MAX_DELAY);
+
+	/* SELECT 状態に遷移する。*/
+	ct->fsm = DHCP6_FSM_SELECT;
+
+	/* INFO-REQUEST メッセージを送信する。*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_IREQ;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  start_informed -- INFORMED 状態に遷移する。
+ *
+ *    注意: DHCPv6 の RFC3315 には無い
+ */
+
+static void
+start_informed (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* 有効なリース情報が無ければ SLEEP に遷移する。*/
+	if (ct->act_msg == NULL) {
+		ct->fsm = DHCP6_FSM_SLEEP;
+		return;
+		}
+
+	/* リース情報を設定する。*/
+	set_lease(ct);
+
+	/* INFORMED 状態に遷移する。*/
+	ct->fsm = DHCP6_FSM_INFORMED;
+
+	//ct->flags |= DHCP6C_FLAG_STAY_STATE;
+	}
+
+/*
+ *  start_rel_info -- アドレス情報を解放する。
+ *
+ *    注意: DHCPv6 の RFC3315 には無い
+ */
+
+static void
+start_rel_info (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* リース情報を解放する。*/
+	rel_lease(ct);
+
+	/* SLEEP に遷移する。*/
+	ct->fsm = DHCP6_FSM_SLEEP;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  select_info_reply -- 最適な REPLY (INFO-REQUEST への応答) メッセージを選択する。
+ */
+
+static bool_t
+select_info_reply (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG		*msg;
+
+	/* 最適な REPLY メッセージを選択する。*/
+	if ((msg = select_msg(ct)) == NULL)
+		return false;
+	
+	ct->act_msg = msg;
+	return true;
+	}
+
+/*
+ *  setup_info_req_msg -- INFO-REQUEST メッセージを作成する。
+ */
+
+static ER
+setup_info_req_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	uint8_t	*msg;
+
+	/* メッセージのヘッダ部分を作成する。*/
+	if ((msg = setup_msg_header(ct, DHCP6_INFO_REQ)) == NULL)
+		return E_PAR;
+
+	if ((msg = common_options(ct, msg, DHCP6_INFO_REQ, NULL)) == NULL)
+		return E_PAR;
+
+	/* メッセージ構造体長を設定する。*/
+	ct->snd_msg->len = msg - (uint8_t*)&ct->snd_msg->msg;
+
+	/* 送信先アドレスを設定する。*/
+	ct->dst.ipaddr	= in6_addr_all_DHCP_relay_servers;
+	return E_OK;
+	}
+
+/*
+ *  send_info_req_msg -- INFO-REQUEST メッセージを送信する。
+ */
+
+static void
+send_info_req_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	ER	error;
+
+
+	/* REPLY メッセージの選択が終了していれば、BOUND 状態に遷移する。*/
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	if (select_info_reply(ct)) {
+
+		/* REPLY メッセージ受信タイマーを停止する。*/
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_RCV_REPLY] = 0;
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+		/* INFORMED 状態に遷移する。*/
+		start_informed(ct);
+		return;
+		}
+
+	/* 再送信回数を確認する。*/
+	if ((ct->MRC != 0) && (ct->txcount > ct->MRC)) {
+		ct->error  = E_TMOUT;
+		return;
+		}
+
+	/* INFO-REQUEST メッセージを作成する。*/
+	if ((error = setup_info_req_msg(ct)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, setup request message: %s.", itron_strerror(error));
+		ct->error = error;
+		return;
+		}
+
+	/* INFO-REQUEST メッセージを送信する。*/
+	error = UDP_SND_DAT(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, send info-request message: %s.", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* 再送信タイムアウトを設定する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_IREQ] = SYSTIM2TIMER(ct->RT);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* 再送信タイムアウトを更新する。*/
+	advance_retrans(ct);
+	}
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+/*
+ *  select_reply -- 最適な REPLY メッセージを選択する。
+ */
+
+static bool_t
+select_reply (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG		*msg;
+
+	/* 最適な REPLY メッセージを選択する。*/
+	if ((msg = select_msg(ct)) == NULL)
+		return false;
+
+	if (ct->adv_msg != NULL) {
+		eval_prefer(ct->adv_msg);
+		eval_ia_prefer(ct->adv_msg);
+		}
+
+	/*
+	 *  最適な REPLY メッセージの推奨度が ADVERTISE メッセージ推奨度の
+	 *  1/2 以下の時は受信メッセージ構造体リストに戻す。
+	 */
+	if ((ct->adv_msg != NULL) && (ct->max_prefer < (ct->adv_msg->prefer & DHCP6_ClI_MSG_PREFER_VALUE_MASK) / 2)) {
+		syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+		msg->next = ct->rcv_lst;
+		ct->rcv_lst = msg;
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		}
+	else {
+
+		/*
+		 *  ct->act_msg にある有効な元 REPLY メッセージを
+		 *  受信メッセージ構造体リストに戻して、
+		 *  最適な REPLY メッセージを act に移す。
+		 */
+		if (ct->act_msg != NULL) {
+			syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+			ct->act_msg->next = ct->rcv_lst;
+			ct->rcv_lst = ct->act_msg;
+			syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+			}
+		ct->act_msg = msg;
+		}
+
+	return ct->act_msg != NULL;
+	}
+
+/*
+ *  select_adv -- 最適な ADVERTISE メッセージを選択する。
+ */
+
+static bool_t
+select_adv (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* 最適な ADVERTISE メッセージを adv に移す。*/
+	if ((ct->adv_msg = select_msg(ct)) != NULL) {
+
+		/*
+		 *  最適な ADVERTISE メッセージのサーバの IPv6 アドレスを
+		 *  次から送信するアドレスに設定する。
+		 */
+		ct->dst = ct->adv_msg->srv;
+		return true;
+		}
+	else
+		return false;
+	}
+
+/*
+ *  eval_expire -- 推奨有効時間と有効時間を決定する。
+ */
+
+static void
+eval_expire (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPTION		*opt;
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	T_DHCP6_OPT_IAADDR	*iaa;
+	SYSTIM		time;
+	uint32_t	depref, expire,
+			high, low, renew, rebind,
+			tval, iaa_high, iaa_low;
+	uint8_t		*msg, *last;
+	uint_t		aoff, asize, addrs;
+
+	/* タイマーを停止する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RENEW]  = 0;
+	ct->timers[DHCP6C_TIMER_REBIND] = 0;
+	ct->timers[DHCP6C_TIMER_DEPREF] = 0;
+	ct->timers[DHCP6C_TIMER_EXPIRE] = 0;
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+	
+	addrs = high = expire = 0;
+	low = renew = rebind = depref = DHCP6_MAX_TIME;
+
+	msg = ct->act_msg->msg.options;
+	last = msg + (ct->act_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	get_tim(&time);
+	while (msg < last) {
+		opt = (T_DHCP6_OPTION*)msg;
+
+		/* IA_NA/IA_PD オプションであれば、有効時間を更新する。*/
+		if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_NA || MSG2HOST16(opt->code) == DHCP6_OPT_IA_PD) {
+
+			//dump_msg_option("evl_expire1", msg);
+			iaa_high = 0;
+			iaa_low  = DHCP6_MAX_TIME;
+
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			aoff  = sizeof(*ia);
+			asize = MSG2HOST16(ia->len) + sizeof(*opt);
+			while (aoff < asize) {
+
+				/* 最短の推奨有効時間を更新する。*/
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				//dump_msg_option("evl_depref1", (uint8_t*)iaa);
+				if (!(MSG2HOST16(iaa->len) & DHCP6C_IAA_FLAG_DEPREFERD)) {
+					if (MSG2HOST32(iaa->prefer) == DHCP6_MAX_TIME)
+						tval = DHCP6_MAX_TIME;
+					else
+						tval = MSG2HOST32(iaa->prefer) + SYSTIM2SEC(ct->act_msg->rcv_time);
+					if (tval < depref)
+						depref = tval;
+					}
+
+				/* IAADDR の有効時間を更新する。*/
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				if (!(MSG2HOST16(iaa->len) & DHCP6C_IAA_FLAG_EXPIRED)) {
+					if (MSG2HOST32(iaa->valid) == DHCP6_MAX_TIME)
+						tval = DHCP6_MAX_TIME;
+					else
+						tval = MSG2HOST32(iaa->valid) + SYSTIM2SEC(ct->act_msg->rcv_time);
+					tval -= SYSTIM2SEC(ct->act_msg->rcv_time);
+					if (tval > iaa_high)
+						iaa_high = tval;
+					if (tval < iaa_low)
+						iaa_low  = tval;
+					addrs ++;
+					}
+
+				aoff += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(*iaa);
+				}
+
+			/* iaa_low と iaa_high/2 の最長の方を有効時間として選択する。*/
+			if (iaa_low <= (iaa_high / 2))
+				expire = iaa_high;
+			else
+				expire = iaa_low;
+
+			/* expire が 最大値（無制限）か 1 以下なら既定値に設定する。*/
+			if ((expire == DHCP6_MAX_TIME) || (expire <= 1))
+				expire  = SYSTIM2SEC(TMO_DHCP6C_REQ_LEASE) / 2;
+			else
+				expire /= 2;
+
+			/* renew を決定する。*/
+			if (MSG2HOST32(ia->renew) == 0)
+				tval = expire + SYSTIM2SEC(ct->act_msg->rcv_time);
+			else if (MSG2HOST32(ia->renew) == DHCP6_MAX_TIME)
+				tval = DHCP6_MAX_TIME;
+			else
+				tval = MSG2HOST32(ia->renew) + SYSTIM2SEC(ct->act_msg->rcv_time);
+			if (tval < renew)
+				renew = tval;
+
+			/* rebind を決定する。*/
+			if (MSG2HOST32(ia->rebind) == 0)
+				tval = (expire + expire / 2) + SYSTIM2SEC(ct->act_msg->rcv_time);
+			else if (MSG2HOST32(ia->rebind) == DHCP6_MAX_TIME)
+				tval = DHCP6_MAX_TIME;
+			else
+				tval = MSG2HOST32(ia->rebind) + SYSTIM2SEC(ct->act_msg->rcv_time);
+			if (tval < rebind)
+				rebind = tval;
+
+			/* 最短有効時間と最長有効時間を更新する。*/
+			iaa_low  += SYSTIM2SEC(ct->act_msg->rcv_time);
+			iaa_high += SYSTIM2SEC(ct->act_msg->rcv_time);
+			if (iaa_low < low)
+				low = iaa_low;
+			if (iaa_high > high)
+				high = iaa_high;
+			}
+
+		msg += MSG2HOST16(opt->len) + sizeof(*opt);
+		}
+
+	/* アドレスが送られていなければ、SLEEP 状態に遷移する。*/
+	if (addrs == 0) {
+		ct->fsm    = DHCP6_FSM_SLEEP;
+		}
+
+	/* 状態に依存する処理 */
+	switch (ct->fsm) {
+
+	case DHCP6_FSM_BOUND:
+
+		/* RENEW タイムアウトの設定 */
+		if ((rebind > SYSTIM2SEC(time)) && (renew < rebind)) {
+			ct->next_MRD = SEC2SYSTIM(rebind) - time;
+			syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+			ct->timers[DHCP6C_TIMER_RENEW] = SEC2TIMER(renew) - SYSTIM2TIMER(time);
+			syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+			break;
+			}
+		/* break; */	/* 下に抜ける。*/
+
+	case DHCP6_FSM_RENEW:
+
+		/* REBIND タイムアウトの設定 */
+		ct->MRD = SEC2SYSTIM(rebind);
+		if (rebind != DHCP6_MAX_TIME) {
+			ct->next_MRD = SEC2SYSTIM(high) - time;
+			syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+			ct->timers[DHCP6C_TIMER_REBIND] = SEC2TIMER(rebind) - SYSTIM2TIMER(time);
+			syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+			}
+		break;
+
+	case DHCP6_FSM_REBIND:
+
+		ct->next_MRD = (SEC2TIMER(high) - time) - time;
+		break;
+
+	default:
+		break;
+		}
+
+	/* DEPREF タイムアウトの設定 */
+	if (depref != DHCP6_MAX_TIME) {
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_DEPREF] = SEC2TIMER(depref) - SYSTIM2TIMER(time);
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+		}
+
+	/* EXPIRE タイムアウトの設定 */
+	if (low != DHCP6_MAX_TIME) {
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_EXPIRE] = SEC2TIMER(low) - SYSTIM2TIMER(time);
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+		}
+	}
+
+/*
+ *  start_init -- INIT 状態に遷移する。
+ */
+
+static void
+start_init (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* タイムアウトを設定する。【RFC3315 (17.1.2) 参照】*/
+	ct->IRT = TMO_SOL_TIMEOUT;
+	ct->MRT = TMO_SOL_MAX_RT;
+	ct->MRC = 0;
+
+	/* DHCP6_CLI_CFG_ONE_TRYが指定されていなければ標準タイムアウトまで再送する。*/
+#if defined(DHCP6_CLI_CFG_ONE_TRY)
+	ct->MRD = 0;
+#else
+	ct->MRD = TMO_DHCP6C_NORMAL;
+#endif
+
+	/* 再送回数とトランザクション ID を設定する。*/
+	init_retrans(ct);
+
+	/* RFC3315 (17.1.2) の規定に従ってタイムアウトを調整する。*/
+	if (ct->RT <= ct->IRT)
+		ct->RT = ct->IRT + (ct->IRT - ct->RT);
+	if (ct->RT <= ct->IRT)
+		ct->RT = ct->IRT + SEC2SYSTIM(1);
+
+	/* ADVERTISE メッセージの受信タイムアウトを設定する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RCV_ADV] = SYSTIM2TIMER(ct->MRD);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/*
+	 *  SOLICIT メッセージ送信遅延時間を設定する。
+	 *  ただし、TMO_SOL_MAX_DELAY が 1[s]なので、dly_tsk()を使用する。
+	 */
+	dly_tsk(netapp_rand() % TMO_SOL_MAX_DELAY);
+
+	/* INIT 状態に遷移する。*/
+	ct->fsm = DHCP6_FSM_INIT;
+
+	/* SOLICIT メッセージを送信する。*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_SOL;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  start_select -- REQUEST メッセージを送信して SELECT 状態に遷移する。
+ */
+
+static void
+start_select (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* 有効な ADVERTISE メッセージを受信していなければ SLEEP 状態に遷移する。*/
+	if (ct->adv_msg == NULL) {
+		ct->fsm = DHCP6_FSM_SLEEP;
+		return;
+		}
+
+	/* タイムアウトを設定する。【RFC3315 (18.1.1) 参照】*/
+	ct->IRT = TMO_REQ_TIMEOUT;
+	ct->MRT = TMO_REQ_MAX_RT;
+	ct->MRC = TMO_REQ_MAX_RC;
+	ct->MRD = 0;
+
+	/* 再送回数とトランザクション ID を設定する。*/
+	init_retrans(ct);
+
+	/* REPLY メッセージの受信タイムアウトを設定する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RCV_REPLY] = SYSTIM2TIMER(ct->MRD);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* SELECT 状態に遷移する。*/
+	ct->fsm = DHCP6_FSM_SELECT;
+
+	/* REQUEST メッセージを送信する。*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_REQ;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  start_bound -- BOUND 状態に遷移する。
+ */
+
+static void
+start_bound (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* 有効なリース情報が無ければ SLEEP に遷移する。*/
+	if (ct->act_msg == NULL)
+		ct->fsm = DHCP6_FSM_SLEEP;
+
+	/* BOUND 状態に遷移する。*/
+	ct->fsm    = DHCP6_FSM_BOUND;
+
+	/* リース情報を設定する。*/
+	set_lease(ct);
+
+	/* 有効時間を決定する。*/
+	eval_expire(ct);
+
+	}
+/*
+ *  start_renew -- RENEW 状態に遷移する。
+ */
+
+static void
+start_renew (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* 有効なリース情報が無ければ SLEEP に遷移する。*/
+	if (ct->act_msg == NULL) {
+		ct->fsm = DHCP6_FSM_SLEEP;
+		return;
+		}
+
+	/* タイムアウトを設定する。【RFC3315 (18.1.3) 参照】*/
+	ct->IRT = TMO_REN_TIMEOUT;
+	ct->MRT = TMO_REN_MAX_RT;
+	ct->MRC = 0;
+	ct->MRD = ct->next_MRD;
+
+	/* 再送回数とトランザクション ID を設定する。*/
+	init_retrans(ct);
+
+	/* REFRESH メッセージタイプを設定する。*/
+	ct->refresh_type = DHCP6_RENEW;
+
+	/* REPLY メッセージの受信タイムアウトを設定する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RCV_REPLY] = SYSTIM2TIMER(ct->MRD);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* RENEW 状態に遷移する。*/
+	ct->fsm = DHCP6_FSM_RENEW;
+
+	/* REFRESH メッセージを送信する。*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_REF;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  start_rebind -- REBIND 状態に遷移する。
+ */
+
+static void
+start_rebind (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* 有効なリース情報が無ければ SLEEP に遷移する。*/
+	if (ct->act_msg == NULL) {
+		ct->fsm = DHCP6_FSM_SLEEP;
+		return;
+		}
+
+	/* タイムアウトを設定する。【RFC3315 (18.1.4) 参照】*/
+	ct->IRT = TMO_REB_TIMEOUT;
+	ct->MRT = TMO_REB_MAX_RT;
+	ct->MRC = 0;
+	ct->MRD = ct->next_MRD;
+
+	/* 再送回数とトランザクション ID を設定する。*/
+	init_retrans(ct);
+
+	/* REFRESH メッセージタイプを設定する。*/
+	ct->refresh_type = DHCP6_REBIND;
+
+	/* REPLY メッセージの受信タイムアウトを設定する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RCV_REPLY] = SYSTIM2TIMER(ct->MRD);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* 送信先アドレスを設定する。*/
+	ct->dst.ipaddr	= in6_addr_all_DHCP_relay_servers;
+
+	/* REBIND 状態に遷移する。*/
+	ct->fsm = DHCP6_FSM_REBIND;
+
+	/* REFRESH メッセージを送信する。*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_REF;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  start_rel_info -- アドレス情報を解放する。
+ *
+ *    注意: DHCPv6 の RFC3315 には無い
+ */
+
+static void
+start_rel_info (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* 全ての TIMER をキャンセルする。*/
+	cancel_all_timers(ct);
+
+	/* リース情報を解放する。*/
+	rel_lease(ct);
+
+	/* 有効なリース情報が無ければ SLEEP に遷移する。*/
+	if (ct->act_msg == NULL) {
+		ct->fsm = DHCP6_FSM_SLEEP;
+		return;
+		}
+
+	/* タイムアウトを設定する。【RFC3315 (18.1.1) 参照】*/
+	ct->IRT = TMO_REL_TIMEOUT;
+	ct->MRT = 0;
+	ct->MRC = TMO_REL_MAX_RC;
+	ct->MRD = 0;
+
+	/* 再送回数とトランザクション ID を設定する。*/
+	init_retrans(ct);
+
+	/* REL_INFO 状態に遷移する。*/
+	ct->fsm = DHCP6_FSM_REL_INFO;
+
+	/* RELEASE メッセージを送信する。*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_REL;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+#if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_TA) || defined(DHCP6_CLI_CFG_IA_PD)
+
+/*
+ *  solicit_ia_option -- SOLICIT メッセージの IA_NA/IA_TA/IA_PD オプションの共通部分を追加する。
+ */
+
+static void
+solicit_ia_option (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t code)
+{
+	T_DHCP6_OPT_IA_TA	*ia;
+	uint_t			off, len;
+
+	/* オプションコードを設定する。*/
+	ia = (T_DHCP6_OPT_IA_TA*)msg;
+	HOST2MSG16(ia->code, code);
+
+	/* IAID を設定する。*/
+	if (sizeof(ct->sc->ifaddr.lladdr) > sizeof(uint32_t)) {
+		off = sizeof(ct->sc->ifaddr.lladdr) - 4;
+		len = 4;
+		}
+	else {
+		off = 0;
+		len = sizeof(ct->sc->ifaddr.lladdr);
+		}
+	memcpy((uint8_t*)&ia->iaid, ((uint8_t*)ct->sc->ifaddr.lladdr) + off, len);
+	}
+
+/*
+ *  solicit_iaaddr_option -- SOLICIT メッセージの IAADDR オプションを追加する。
+ */
+
+static uint_t
+solicit_iaaddr_option (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t code)
+{
+	T_DHCP6_OPT_IAADDR	*iaa;
+	uint32_t		t1, t2;
+	uint8_t			*opt;
+	uint_t			len;
+
+	/*
+	 *  有効なリース・メッセージが残っていて、
+	 *  指定されたオプション（IA_NA/IA_TA/IA_PD）がある場合は
+	 *  同じアドレスを要求する。
+	 */
+	if ((ct->act_msg == NULL) || (opt = find_msg_option(ct->act_msg, code, 0)) == NULL)
+		return 0;
+
+	/* オプションコードを設定する。*/
+	iaa = (T_DHCP6_OPT_IAADDR*)msg;
+	HOST2MSG16(iaa->code, DHCP6_OPT_IAADDR);
+
+	/* IAADDR オプションを除いたオプション長を設定する。*/
+	HOST2MSG16(iaa->len, sizeof(*iaa) - sizeof(T_DHCP6_OPTION));
+
+	/* アドレスを設定する。*/
+	len = code == DHCP6_OPT_IA_TA ? sizeof(T_DHCP6_OPT_IA_TA)
+	                              : sizeof(T_DHCP6_OPT_IA_NA_PD);
+	memcpy(&iaa->addr, opt + sizeof(T_DHCP6_OPTION) + len, sizeof(iaa->addr));
+
+	/* T1、T2 を設定する。*/
+	t1 = TMO_DHCP6C_REQ_LEASE / 2;
+	t2 = t1 + (t1 / 2);
+	HOST2MSG32(iaa->prefer, t1);
+	HOST2MSG32(iaa->valid,  t2);
+
+	return sizeof(*iaa);
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_TA) || defined(DHCP6_CLI_CFG_IA_PD) */
+
+/*
+ *  solicit_ia_na_pd -- SOLICIT メッセージの IA_NA/IA_PD オプションを追加する。
+ */
+
+#if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_PD)
+
+static uint8_t *
+solicit_ia_na_pd (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t code)
+{
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	uint32_t		t1, t2;
+	uint_t			len;
+
+	/* IA_NA/IA_TA/IA_PD オプションの共通部分を追加する。*/
+	solicit_ia_option(ct, msg, code);
+	ia = (T_DHCP6_OPT_IA_NA_PD*)msg;
+
+	/* T1、T2 を設定する。*/
+	t1 = TMO_DHCP6C_REQ_LEASE / 2;
+	t2 = t1 + (t1 / 2);
+	HOST2MSG32(ia->renew,  SYSTIM2SEC(t1));
+	HOST2MSG32(ia->rebind, SYSTIM2SEC(t2));
+
+	/*
+	 *  有効なリース・メッセージが残っていて、
+	 *  指定されたオプション（IA_NA/IA_PD）がある場合は
+	 *  同じアドレスを要求する。
+	 */
+	msg += sizeof(*ia);
+	len  = solicit_iaaddr_option(ct, msg, code);
+
+	/* IA_NAIA_TA/IA_PD オプションを除いたオプション長を設定する。*/
+	HOST2MSG16(ia->len, (sizeof(*ia) + len) - sizeof(T_DHCP6_OPTION));
+
+	return msg + len;
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_PD) */
+
+/*
+ *  solicit_ia_ta -- SOLICIT メッセージの IA_TA オプションを追加する。
+ */
+
+#if defined(DHCP6_CLI_CFG_IA_TA)
+
+static uint8_t *
+solicit_ia_ta (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg)
+{
+	T_DHCP6_OPT_IA_TA	*ia;
+
+	/* IA_NA/IA_TA/IA_PD オプションの共通部分を追加する。*/
+	solicit_ia_option(ct, msg, DHCP6_OPT_IA_TA);
+
+	/* IA_NAIA_TA/IA_PD オプションを除いたオプション長を設定する。*/
+	ia = (T_DHCP6_OPT_IA_TA*)msg;
+	HOST2MSG16(ia->len, sizeof(*ia) - sizeof(T_DHCP6_OPTION));
+
+	/*
+	 *  有効なリース・メッセージが残っていて、
+	 *  指定されたオプション（IA_TA）がある場合は
+	 *  同じアドレスを要求する。
+	 */
+	msg += sizeof(*ia);
+	return msg + solicit_iaaddr_option(ct, msg, code);
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_TA) */
+
+/*
+ *  setup_solicit_msg -- SOLICIT メッセージを作成する。
+ */
+
+static ER
+setup_solicit_msg (T_DHCP6_CLI_CONTEXT *ct, T_DHCP6_CLI_MSG *lease)
+{
+	uint8_t	*head, *msg;
+
+	/* メッセージのヘッダ部分を作成する。*/
+	if ((head = setup_msg_header(ct, DHCP6_SOLICIT)) == NULL)
+		return E_PAR;
+
+	if ((msg = common_options(ct, head, DHCP6_SOLICIT, lease)) == NULL)
+		return E_PAR;
+
+#if defined(DHCP6_CLI_CFG_IA_NA)
+
+	/* IA_NA を追加する。*/
+	msg = solicit_ia_na_pd(ct, msg, DHCP6_OPT_IA_NA);
+#endif
+
+#if defined(DHCP6_CLI_CFG_IA_TA)
+
+	/* IA_TA を追加する。*/
+	msg = solicit_ia_ta(ct, msg);
+#endif
+
+#if defined(DHCP6_CLI_CFG_IA_PD)
+
+	/* IA_PD を追加する。*/
+	msg = solicit_ia_na_pd(ct, msg, DHCP6_OPT_IA_PD);
+#endif
+
+	/* メッセージ構造体長を設定する。*/
+	ct->snd_msg->len = msg - (uint8_t*)&ct->snd_msg->msg;
+
+	/* 送信先アドレスを設定する。*/
+	ct->dst.ipaddr	= in6_addr_all_DHCP_relay_servers;
+	return E_OK;
+	}
+
+/*
+ *  send_solicit_msg -- SOLICIT メッセージを送信する。
+ */
+
+static void
+send_solicit_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	ER	error;
+
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	ct->error = E_OK;
+
+	/* ADVERTISE メッセージの選択が終了していれば、SELECT 状態に遷移する。*/
+	if (select_adv(ct)) {
+
+		/* ADVERTISE メッセージ受信タイマーを停止する。*/
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_RCV_ADV] = 0;
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+ 		/* REQUEST メッセージを送信して SELECT 状態に遷移する。*/
+ 		start_select(ct);
+		return;
+		}
+
+	/* 再送信回数を確認する。*/
+	if ((ct->MRC != 0) && (ct->txcount > ct->MRC)) {
+		ct->error  = E_TMOUT;
+		return;
+		}
+
+	/* SOLICIT メッセージを作成する。*/
+	if ((error = setup_solicit_msg(ct, NULL)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, setup solicit message: %s.", itron_strerror(error));
+		ct->error = error;
+		return;
+		}
+
+	/* SOLICIT メッセージを送信する。*/
+	error = UDP_SND_DAT(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, send solicit message: %s.", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* 再送信タイムアウトを設定する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_SOL] = SYSTIM2TIMER(ct->RT);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* 再送信タイムアウトを更新する。*/
+	advance_retrans(ct);
+	}
+
+/*
+ *  request_ia_option -- REQUEST メッセージの IA_NA/IA_TA/IA_PD オプションの共通部分を追加する。
+ */
+
+#if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_TA) || defined(DHCP6_CLI_CFG_IA_PD)
+
+static uint8_t *
+request_ia_option (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t code, uint8_t *lease)
+{
+	T_DHCP6_OPT_IA_NA_PD	*dst, *src;
+
+	dst = (T_DHCP6_OPT_IA_NA_PD*)msg;
+	src = (T_DHCP6_OPT_IA_NA_PD*)lease;
+
+	/* オプションコードを設定する。*/
+	HOST2MSG16(dst->code, code);
+
+	/* IA_NAIA_TA/IA_PD オプションを除いたオプション長を設定する。*/
+	HOST2MSG16(dst->len, sizeof(*dst) - (sizeof(dst->code) + sizeof(dst->len)));
+
+	/* ADVERTISE メッセージから IA ID をコピーする。*/
+	memcpy(&dst->iaid, &src->iaid, sizeof(src->iaid));
+
+	return msg + sizeof(uint16_t) * 2 + sizeof(uint32_t);
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_TA) || defined(DHCP6_CLI_CFG_IA_PD) */
+
+/*
+ *  request_ia_na_pd -- REQUEST メッセージの IA_NA/IA_PD オプションを追加する。
+ */
+
+#if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_PD)
+
+static uint8_t *
+request_ia_na_pd (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t msg_type, uint_t opt_code, T_DHCP6_CLI_MSG *lease)
+{
+	T_DHCP6_OPT_IA_NA_PD	*dia,  *sia;
+	T_DHCP6_OPT_IAADDR	*diaa, *siaa;
+	uint8_t			*opt;
+	uint32_t		t1, t2;
+	uint_t			ix, nsiaa;
+
+	/* ADVERTISE メッセージに指定されたオプションがあることを確認する。*/
+	if ((opt = find_msg_option(lease, opt_code, 0)) == NULL)
+		return msg;
+
+	/* IA_NA/IA_TA/IA_PD オプションの共通部分を追加する。*/
+	dia = (T_DHCP6_OPT_IA_NA_PD*)msg;
+	sia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+	msg = request_ia_option(ct, msg, opt_code, opt);
+
+	/* T1、T2 を決定する。*/
+	switch (msg_type) {
+	case DHCP6_REQUEST:
+	case DHCP6_RENEW:
+	case DHCP6_REBIND:
+		t1 = SYSTIM2TIMER(TMO_DHCP6C_REQ_LEASE);
+		t2 = t1 + (t1 / 2);
+		break;
+
+	case DHCP6_CONFIRM:
+	case DHCP6_RELEASE:
+	case DHCP6_DECLINE:
+		t1 = t2 = 0;
+		break;
+
+	default:
+		syslog(LOG_NOTICE, "[DHCP6C] unkown msg_type in setup IA_NA/IA_PD for request message: %d.", msg_type);
+		return NULL;
+		break;
+		}
+
+	/* T1、T2 を設定する。*/
+	HOST2MSG32(dia->renew,  t1);
+	HOST2MSG32(dia->rebind, t2);
+	msg += sizeof(dia->renew) + sizeof(dia->rebind);
+
+	/* IAADDR オプションを設定する。*/
+	nsiaa = ((MSG2HOST16(sia->len) & ~DHCP6C_IAA_FLAG_MASK) - (sizeof(*sia) - (sizeof(sia->code) + sizeof(sia->len)))) / sizeof(*siaa);
+
+	for (ix = 0; ix <nsiaa; ix++) {
+		diaa = (T_DHCP6_OPT_IAADDR*)(msg + sizeof(*diaa) * ix);
+		siaa = (T_DHCP6_OPT_IAADDR*)((opt + sizeof(*sia)) + sizeof(*siaa) * ix);
+
+		/* アドレスの有効期限が切れていればスキップする。*/
+		if (MSG2HOST16(siaa->len) & DHCP6C_IAA_FLAG_EXPIRED)
+			continue;
+
+		/* コードと長さを設定する。*/
+		memcpy(&diaa->code, &siaa->code, sizeof(siaa->code));
+		HOST2MSG16(diaa->len, MSG2HOST16(siaa->len) & ~DHCP6C_IAA_FLAG_MASK);
+		msg += sizeof(dia->code) + sizeof(dia->len);
+
+		/* IPv6 アドレスをコピーする。*/
+		memcpy(&diaa->addr, &siaa->addr, sizeof(siaa->addr));
+		msg += sizeof(diaa->addr);
+
+		/* T1、T2 を決定する。*/
+		switch (msg_type) {
+		case DHCP6_REQUEST:
+		case DHCP6_RENEW:
+		case DHCP6_REBIND:
+			t1 = SYSTIM2TIMER(TMO_DHCP6C_REQ_LEASE);
+			t2 = t1 + 300;
+			break;
+
+		case DHCP6_CONFIRM:
+		case DHCP6_RELEASE:
+		case DHCP6_DECLINE:
+			t1 = t2 = 0;
+			break;
+
+		default:
+			syslog(LOG_NOTICE, "[DHCP6C] unknown msg_type in setup IA_NA/IA_PD for request: %d.", msg_type);
+			return NULL;
+			break;
+			}
+
+		/* T1、T2 を設定する。*/
+		HOST2MSG32(diaa->prefer, t1);
+		HOST2MSG32(diaa->valid,  t2);
+		msg += sizeof(diaa->prefer) + sizeof(diaa->valid);
+
+		/* IAADDR に付加オプションを追加する【先送り】。*/
+		}
+
+	HOST2MSG16(((T_DHCP6_OPTION*)dia)->len, 
+	MSG2HOST16(((T_DHCP6_OPTION*)dia)->len) + (msg - (uint8_t*)dia) - sizeof(*dia));
+	return msg;
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_PD) */
+
+/*
+ *  request_ia_ta -- REQUEST メッセージの IA_TA オプションを追加する。
+ */
+
+#if defined(DHCP6_CLI_CFG_IA_TA)
+
+static uint8_t *
+request_ia_ta (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t msg_type, T_DHCP6_CLI_MSG *lease)
+{
+	T_DHCP6_OPT_IA_TA	*dia,  *sia;
+	T_DHCP6_OPT_IAADDR	*diaa, *siaa;
+	uint8_t			*opt;
+	uint32_t		t1, t2;
+	uint_t			ix, nsiaa;
+
+	/* ADVERTISE メッセージに IA_TA オプションがあることを確認する。*/
+	if ((opt = find_msg_option(lease, DHCP6_OPT_IA_TA, 0)) == NULL)
+		return msg;
+
+	/* IA_NA/IA_TA/IA_PD オプションの共通部分を追加する。*/
+	dia = (T_DHCP6_OPT_IA_TA*)msg;
+	sia = (T_DHCP6_OPT_IA_TA*)opt;
+	msg = request_ia_option(ct, msg, DHCP6_OPT_IA_TA, opt);
+
+	/* IAADDR オプションを設定する。*/
+	nsiaa = ((MSG2HOST16(sia->len) & ~DHCP6C_IAA_FLAG_MASK) - (sizeof(*sia) - (sizeof(sia->code) + sizeof(sia->len)))) / sizeof(*siaa);
+
+	for (ix = 0; ix <nsiaa; ix++) {
+		diaa = (T_DHCP6_OPT_IAADDR*)(msg + sizeof(*diaa) * ix);
+		siaa = (T_DHCP6_OPT_IAADDR*)((opt + sizeof(*sia)) + sizeof(*siaa) * ix);
+
+		/* アドレスの有効期限が切れていればスキップする。*/
+		if (MSG2HOST16(siaa->len) & DHCP6C_IAA_FLAG_EXPIRED)
+			continue;
+
+		/* コードと長さを設定する。*/
+		memcpy(diaa->code, siaa->code, sizeof(siaa->code));
+		diaa->len  = HOST2MSG16(MSG2HOST16(siaa->len) & ~DHCP6C_IAA_FLAG_MASK);
+		msg += sizeof(dia->code) + sizeof(dia->len);
+
+		/* IPv6 アドレスをコピーする。*/
+		memcpy(diaa->addr, siaa->addr, sizeof(siaa->addr));
+		msg += sizeof(diaa->addr);
+
+		/* T1、T2 を決定する。*/
+		switch (msg_type) {
+		case DHCP6_REQUEST:
+		case DHCP6_RENEW:
+		case DHCP6_REBIND:
+			t1 = SYSTIM2TIMER(TMO_DHCP6C_REQ_LEASE);
+			t2 = t1 + 300;
+			break;
+
+		case DHCP6_CONFIRM:
+		case DHCP6_RELEASE:
+		case DHCP6_DECLINE:
+			t1 = t2 = 0;
+			break;
+
+		default:
+			syslog(LOG_NOTICE, "[DHCP6C] unknown msg_type in setup IA_TA for request message: %d.", msg_type);
+			return NULL;
+			break;
+			}
+
+		/* T1、T2 を設定する。*/
+		HOST2MSG32(diaa->prefer, t1);
+		HOST2MSG32(diaa->valid,  t2);
+		msg += sizeof(diaa->prefer) + sizeof(diaa->valid);
+
+		/* IAADDR に付加オプションを追加する【先送り】。*/
+		}
+
+	return msg;
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_TA) */
+
+/*
+ *  setup_request_msg -- REQUEST メッセージを作成する。
+ */
+
+static ER
+setup_request_msg (T_DHCP6_CLI_CONTEXT *ct, T_DHCP6_CLI_MSG *lease, uint_t type)
+{
+	uint8_t	*msg;
+
+	/* メッセージのヘッダ部分を作成する。*/
+	if ((msg = setup_msg_header(ct, type)) == NULL)
+		return E_PAR;
+
+	if ((msg = common_options(ct, msg, type, lease)) == NULL)
+		return E_PAR;
+
+#if defined(DHCP6_CLI_CFG_IA_NA)
+
+	/* IA_NA を追加する。*/
+	msg = request_ia_na_pd(ct, msg, type, DHCP6_OPT_IA_NA, lease);
+#endif
+
+#if defined(DHCP6_CLI_CFG_IA_TA)
+
+	/* IA_TA を追加する。*/
+	msg = request_ia_ta(ct, msg, type, lease);
+#endif
+
+#if defined(DHCP6_CLI_CFG_IA_PD)
+
+	/* IA_PD を追加する。*/
+	msg = request_ia_na_pd(ct, msg, type, DHCP6_OPT_IA_PD, lease);
+#endif
+
+	/* メッセージ構造体長を設定する。*/
+	ct->snd_msg->len = msg - (uint8_t*)&ct->snd_msg->msg;
+	return E_OK;
+	}
+
+/*
+ *  send_request_msg -- REQUEST メッセージを送信する。
+ */
+
+static void
+send_request_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	ER	error;
+
+	ct->error = E_OK;
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+
+	/* ADVERTISE メッセージを受信していなければエラー */
+	if (ct->adv_msg == NULL) {
+		ct->error  = E_OBJ;
+		return;
+		}
+
+	/* REPLY メッセージの選択が終了していれば、BOUND 状態に遷移する。*/
+	if (select_reply(ct)) {
+
+		/* REPLY メッセージ受信タイマーを停止する。*/
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_RCV_REPLY] = 0;
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	 	/* ADVERTISE メッセージを受信メッセージ構造体リストに戻す。*/
+		syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+		ct->adv_msg->next = ct->rcv_lst;
+		ct->rcv_lst = ct->adv_msg;
+		ct->adv_msg = NULL;
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+		/* BOUND 状態に遷移する。*/
+		start_bound(ct);
+		return;
+		}
+
+	/* 再送信回数を確認する。*/
+	if ((ct->MRC != 0) && (ct->txcount > ct->MRC)) {
+		ct->error  = E_TMOUT;
+		return;
+		}
+
+	/* REQUEST メッセージを作成する。*/
+	if ((error = setup_request_msg(ct, ct->adv_msg, DHCP6_REQUEST)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, setup request message: %s.", itron_strerror(error));
+		ct->error = error;
+		return;
+		}
+
+	/* REQUEST メッセージを送信する。*/
+	error = UDP_SND_DAT(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, send request message: %s.", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* 再送信タイムアウトを設定する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_REQ] = SYSTIM2TIMER(ct->RT);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* 再送信タイムアウトを更新する。*/
+	advance_retrans(ct);
+	}
+
+/*
+ *  send_refresh_msg -- REFRESH メッセージを送信する。
+ */
+
+static void
+send_refresh_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPT_UNICAST	*uc;
+	ER			error;
+	uint8_t			*opt;
+
+	/* 有効なリース情報がなければエラー */
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	if (ct->act_msg == NULL)
+		ct->error = E_OBJ;
+
+	/* REFRESH タイプが RENEW または REBIND でなければエラー */
+	if (!((ct->refresh_type == DHCP6_RENEW) || (ct->refresh_type == DHCP6_REBIND)))
+		ct->error = E_PAR;
+
+	/* REPLY メッセージの選択が終了していれば、BOUND 状態に遷移する。*/
+	if (select_reply(ct)) {
+
+		/* REPLY メッセージ受信タイマーを停止する。*/
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_RCV_REPLY] = 0;
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+		/* リース情報を解放する。*/
+		rel_lease(ct);
+
+		/* BOUND 状態に遷移する。*/
+		start_bound(ct);
+		return;
+		}
+
+	/* 再送信回数を確認する。*/
+	if ((ct->MRC != 0) && (ct->txcount > ct->MRC)) {
+		eval_expire(ct);
+		return;
+		}
+
+	/*
+	 *  サーバから UNICAST オプションを受信したときは
+	 *  指定したアドレスを送信先アドレスに設定する。
+	 */
+	if ((opt = find_msg_option(ct->act_msg, DHCP6_OPT_UNICAST, sizeof(T_DHCP6_OPT_UNICAST))) != NULL) {
+		uc = (T_DHCP6_OPT_UNICAST*)opt;
+		ct->dst.ipaddr = uc->addr;
+		}
+
+	/* REFRESH (REQUEST) メッセージを作成する。*/
+	if ((error = setup_request_msg(ct, ct->act_msg, ct->refresh_type)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, setup refresh message: %s.", itron_strerror(error));
+		ct->error = error;
+		return;
+		}
+
+	/* REFRESH メッセージを送信する。*/
+	error = UDP_SND_DAT(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, send refresh message: %s.", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* 再送信タイムアウトを設定する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_REF] = SYSTIM2TIMER(ct->RT);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* 再送信タイムアウトを更新する。*/
+	advance_retrans(ct);
+	}
+
+/*
+ *  setup_release_msg -- RELEASE メッセージを作成する。
+ */
+
+static ER
+setup_release_msg (T_DHCP6_CLI_CONTEXT *ct, T_DHCP6_CLI_MSG *lease, uint_t type)
+{
+	uint8_t	*msg;
+
+	/* メッセージのヘッダ部分を作成する。*/
+	if ((msg = setup_msg_header(ct, type)) == NULL)
+		return E_PAR;
+
+	if ((msg = common_options(ct, msg, type, lease)) == NULL)
+		return E_PAR;
+
+#if defined(DHCP6_CLI_CFG_IA_NA)
+
+	/* IA_NA を追加する。*/
+	msg = request_ia_na_pd(ct, msg, type, DHCP6_OPT_IA_NA, lease);
+#endif
+
+#if defined(DHCP6_CLI_CFG_IA_PD)
+
+	/* IA_PD を追加する。*/
+	msg = request_ia_na_pd(ct, msg, type, DHCP6_OPT_IA_PD, lease);
+#endif
+
+	/* メッセージ構造体長を設定する。*/
+	ct->snd_msg->len = msg - (uint8_t*)&ct->snd_msg->msg;
+	return E_OK;
+	}
+
+/*
+ *  send_release_msg -- RELEASE メッセージを送信する。
+ */
+
+static void
+send_release_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	ER	error;
+
+	/* 有効な REPLY メッセージを受信していなければエラー */
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	if (ct->act_msg == NULL)
+		ct->error = E_OBJ;
+
+	/* 有効な REPLY メッセージを受信していれば、SLEEP 状態に遷移する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	if (ct->prf_lst != NULL) {
+
+		/* 再送信タイマーを停止する。*/
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_RCV_REPLY] = 0;
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+		/* 有効なリース・メッセージ構造体を解放する。*/
+		if (ct->act_msg != NULL) {
+			syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)ct->act_msg));
+			ct->act_msg = NULL;
+			}
+
+		/* SLEEP 状態に遷移する。*/
+		ct->fsm    = DHCP6_FSM_SLEEP;
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return;
+		}
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+	/* 再送信回数を確認する。*/
+	if ((ct->MRC != 0) && (ct->txcount > ct->MRC)) {
+		ct->error  = E_TMOUT;
+		return;
+		}
+
+	/* RELEASE メッセージを作成する。*/
+	if ((error = setup_release_msg(ct, ct->act_msg, DHCP6_RELEASE)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, setup release message: %s.", itron_strerror(error));
+		ct->error = error;
+		return;
+		}
+
+	/* RELEASE メッセージを送信する。*/
+	error = UDP_SND_DAT(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, send release message: %s.", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* 再送信タイムアウトを設定する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_REL] = SYSTIM2TIMER(ct->RT);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* 再送信タイムアウトを更新する。*/
+	advance_retrans(ct);
+	}
+
+/*
+ *  advertise_msg_timeout -- ADVERTISE メッセージのタイムアウト処理
+ */
+
+static void
+advertise_msg_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* SOLICIT メッセージ送信タイマーを停止する。*/
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_SOL] = 0;
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	if (select_adv(ct)) {
+		/*
+		 *  ADVERTISE メッセージの選択が終了していれば、
+ 		 *  REQUEST メッセージを送信して SELECT 状態に遷移する。
+ 		 */
+ 		start_select(ct);
+		}
+	else
+		ct->error  = E_TMOUT;
+	}
+
+/*
+ *  renew_timeout -- RENEW タイムアウト処理
+ */
+
+static void
+renew_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* RENEW 状態に遷移する。*/
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	start_renew(ct);
+	}
+
+/*
+ *  rebind_timeout -- REBIND タイムアウト処理
+ */
+
+static void
+rebind_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* REBIND 状態に遷移する。*/
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	start_rebind(ct);
+	}
+
+/*
+ *  depref_timeout -- DEPREF タイムアウト処理
+ */
+
+static void
+depref_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPTION		*opt;
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	T_DHCP6_OPT_IAADDR	*iaa;
+	SYSTIM		time;
+	uint8_t		*msg, *last;
+	uint_t		aoff, asize;
+
+	/* 有効なリースが無ければ処理終了 */
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	if (ct->act_msg == NULL) {
+		return;
+		}
+
+	get_tim(&time);
+	msg = ct->act_msg->msg.options;
+	last = msg + (ct->act_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	while (msg < last) {
+
+		/* IA_NA/IA_PD オプションであれば、推奨有効時間を確認する。*/
+		opt = (T_DHCP6_OPTION*)msg;
+		if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_NA || MSG2HOST16(opt->code) == DHCP6_OPT_IA_PD) {
+
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			asize = MSG2HOST16(ia->len) + sizeof(*opt);
+			for (aoff  = sizeof(*ia); aoff < asize;
+				                  aoff += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(*iaa)) {
+
+				/* すでに推奨有効時間を経過していれば処理しない。*/
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				if ((MSG2HOST16(iaa->len) & DHCP6C_IAA_FLAG_DEPREFERD))
+					continue;
+
+				/* 推奨有効時間経過していれば FLAG を設定する。*/
+				if (TIMEC_GE(time, ct->act_msg->rcv_time + MSG2HOST32(iaa->prefer))) {
+					HOST2MSG16(iaa->len, MSG2HOST16(iaa->len) | DHCP6C_IAA_FLAG_DEPREFERD);
+					if (MSG2HOST16(ia->code) == DHCP6_OPT_IA_NA)
+						syslog(LOG_NOTICE, "[DHCP6C] address depreferd: %s.", ipv62str(NULL, &iaa->addr));
+					else
+						syslog(LOG_NOTICE, "[DHCP6C] prefix  depreferd: %s.", ipv62str(NULL, &iaa->addr));
+
+					/*【DNS の処理が必要】*/
+					}
+				}
+			}
+		msg += MSG2HOST16(opt->len) + sizeof(*opt);
+		}
+
+	eval_expire(ct);
+	}
+
+/*
+ *  expire_timeout -- EXPIRE タイムアウト処理
+ */
+
+static void
+expire_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPTION		*opt;
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	T_DHCP6_OPT_IAADDR	*iaa;
+	SYSTIM		time;
+	uint8_t		*msg, *last;
+	uint_t		aoff, asize, addrs = 0;
+
+	/* 有効なリースが無ければ処理終了 */
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	if (ct->act_msg == NULL) {
+		return;
+		}
+
+	get_tim(&time);
+	msg = ct->act_msg->msg.options;
+	last = msg + (ct->act_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	while (msg < last) {
+
+		/* IA_NA/IA_PD オプションであれば、有効時間を確認する。*/
+		opt = (T_DHCP6_OPTION*)msg;
+		if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_NA || MSG2HOST16(opt->code) == DHCP6_OPT_IA_PD) {
+
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			asize = MSG2HOST16(ia->len) + sizeof(*opt);
+			for (aoff  = sizeof(*ia); aoff < asize;
+				                  aoff += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(*iaa)) {
+
+				/* すでに有効時間を経過していれば処理しない。*/
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				if ((MSG2HOST16(iaa->len) & DHCP6C_IAA_FLAG_EXPIRED))
+					continue;
+
+				/* 有効時間経過していれば FLAG を設定する。*/
+				if (TIMEC_GE(time, ct->act_msg->rcv_time + MSG2HOST32(iaa->valid))) {
+					HOST2MSG16(iaa->len, MSG2HOST16(iaa->len) | DHCP6C_IAA_FLAG_EXPIRED);
+					if (MSG2HOST16(ia->code) == DHCP6_OPT_IA_NA)
+						syslog(LOG_NOTICE, "[DHCP6C] address expired: %s.", ipv62str(NULL, &iaa->addr));
+					else
+						syslog(LOG_NOTICE, "[DHCP6C] prefix  expired: %s.", ipv62str(NULL, &iaa->addr));
+
+					/*【DNS の処理が必要】*/
+					continue;
+					}
+				addrs ++;
+				}
+			}
+		msg += MSG2HOST16(opt->len) + sizeof(*opt);
+		}
+
+	/* 有効なアドレスが全て無くなった時は INIT 状態に遷移する。*/
+	if (addrs == 0) {
+
+	 	/* ACTIVE リースを受信メッセージ構造体リストに戻す。*/
+		syslog(LOG_NOTICE, "[DHCP6C] all address expired.");
+		syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+		ct->act_msg->next = ct->rcv_lst;
+		ct->rcv_lst = ct->act_msg;
+		ct->act_msg = NULL;
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+		/* 全ての TIMER をキャンセルする。*/
+		cancel_all_timers(ct);
+
+		/* INIT 状態に遷移する。*/
+		start_init(ct);
+		return;
+		}
+
+	eval_expire(ct);
+	}
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+/*
+ *  reply_msg_timeout -- REPLY メッセージのタイムアウト処理
+ */
+
+static void
+reply_msg_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* SOLICIT メッセージ送信タイマーを停止する。*/
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_REQ] = 0;
+	ct->timers[DHCP6C_TIMER_SND_REF] = 0;
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	/* STATELES モードではSLEEP に遷移する。*/
+	ct->error = E_TMOUT;
+	ct->fsm   = DHCP6_FSM_SLEEP;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	/* RENEW メッセージの選択が終了していれば、BOUND 状態に遷移する。*/
+	if (select_reply(ct)) {
+
+		/* リース情報を解放する。*/
+		rel_lease(ct);
+
+		/* BOUND 状態に遷移する。*/
+		start_bound(ct);
+		}
+	else if (ct->fsm == DHCP6_FSM_RENEW || ct->fsm == DHCP6_FSM_REBIND)
+		eval_expire(ct);
+	else {
+		/* SLEEP に遷移する。*/
+		ct->error = E_TMOUT;
+		ct->fsm   = DHCP6_FSM_SLEEP;
+		}
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+	}
+
+/*
+ *  dispatch_timeout -- タイムアウトした時の処理
+ */
+
+static ER
+dispatch_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+
+	switch (ct->flags & DHCP6C_FLAG_TMOUT_TIMER_MASK) {
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	case DHCP6C_TIMER_SND_IREQ:
+		send_info_req_msg(ct);
+		break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	case DHCP6C_TIMER_SND_SOL:
+		send_solicit_msg(ct);
+		break;
+
+	case DHCP6C_TIMER_SND_REQ:
+		send_request_msg(ct);
+		break;
+
+	case DHCP6C_TIMER_SND_REF:
+		send_refresh_msg(ct);
+		break;
+
+	case DHCP6C_TIMER_SND_REL:
+		send_release_msg(ct);
+		break;
+
+	case DHCP6C_TIMER_RCV_ADV:
+		advertise_msg_timeout(ct);
+		break;
+
+	case DHCP6C_TIMER_RENEW:
+		renew_timeout(ct);
+		break;
+
+	case DHCP6C_TIMER_REBIND:
+		rebind_timeout(ct);
+		break;
+
+	case DHCP6C_TIMER_DEPREF:
+		depref_timeout(ct);
+		break;
+
+	case DHCP6C_TIMER_EXPIRE:
+		expire_timeout(ct);
+		break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+	case DHCP6C_TIMER_RCV_REPLY:
+		reply_msg_timeout(ct);
+		break;
+
+	default:
+		syslog(LOG_NOTICE, "[DHCP6C] error, unknown timeout: %d.", ct->flags & DHCP6C_FLAG_TMOUT_TIMER_MASK);
+		break;
+		}
+
+	return ct->error;
+	}
+
+/*
+ *  dispatch_event -- イベント毎の処理
+ */
+
+static ER
+dispatch_event (T_DHCP6_CLI_CONTEXT *ct)
+{
+	ER	error = E_OK;
+
+	while (ct->fsm != DHCP6_FSM_SLEEP && error == E_OK) {
+
+		/* メッセージの送受信とタイムアウトを待つ。*/
+		syscall(wai_sem(SEM_DHCP6_CLI_READY));
+
+		if (ct->flags & DHCP6C_FLAG_RCV_MSG) {
+			while (ct->val_lst != NULL) {
+				error = eval_rcv_msg(ct);
+				}
+			ct->flags &= ~DHCP6C_FLAG_RCV_MSG;
+			}
+
+		if (ct->flags & DHCP6C_FLAG_TMOUT_MASK)
+			error = dispatch_timeout(ct);
+
+		if (ct->error != E_OK)
+			error = ct->error;
+		}
+
+	return error;
+	}
+
+/*
+ *  init_context -- DHCPv6 クライアントコンテキスト構造体を初期化する。
+ */
+
+static void
+init_context (T_DHCP6_CLI_CONTEXT *ct, ID cepid)
+{
+  	memset(ct, 0, sizeof(*ct));
+	ct->cepid	= cepid;
+	ct->sc		= IF_ETHER_NIC_GET_SOFTC();
+	ct->dst.portno	= DHCP6_SRV_CFG_PORTNO;
+	}
+
+/*
+ *  rel_cli_msg -- メッセージ構造体を解放する。
+ */
+
+static void
+rel_cli_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG	*ptr, *cell;
+
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	for (ptr = ct->rcv_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)cell));
+		}
+
+	for (ptr = ct->val_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)cell));
+		}
+
+	for (ptr = ct->prf_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)cell));
+		}
+
+	if (ct->snd_msg != NULL)
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)ct->snd_msg));
+	if (ct->adv_msg != NULL)
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)ct->adv_msg));
+	ct->rcv_lst = ct->prf_lst = ct->val_lst = ct->snd_msg = ct->adv_msg = NULL;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+
+	/* ステートレスの時は有効なリース・メッセージ構造体も解放する。*/
+	if (ct->act_msg != NULL) {
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)ct->act_msg));
+		ct->act_msg = NULL;
+		}
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+	}
+
+/*
+ *  init_cli_msg -- 各メッセージ構造体を初期化する。
+ */
+
+static ER
+init_cli_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG	*cell;
+	ER		error;
+	int		count;
+
+	/* 送信メッセージ構造体を獲得する。*/
+	if ((error = tget_mpf(MPF_DHCP6_CLI_MSG, (void*)&ct->snd_msg, TMO_DHCP6C_MPF_GET)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, tget_mpf() for send: %s.", itron_strerror(error));
+		return error;
+		}
+
+	/*
+	 *  有効なリース・メッセージ構造体がある場合は、
+	 *  獲得する受信メッセージ構造体リストの構造体を 1減らす。
+	 */
+	if (ct->act_msg == NULL)
+		count = NUM_DHCP6_CLI_MSG_LIST;
+	else
+		count = NUM_DHCP6_CLI_MSG_LIST - 1;
+
+	/* 受信メッセージ構造体を獲得する。*/
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	while (count --> 0) {
+		if ((error = tget_mpf(MPF_DHCP6_CLI_MSG, (void*)&cell, TMO_DHCP6C_MPF_GET)) != E_OK) {
+			syslog(LOG_NOTICE, "[DHCP6C] error, tget_mpf() for receive: %s.", itron_strerror(error));
+			break;
+			}
+		cell->next  = ct->rcv_lst;
+		ct->rcv_lst = cell;
+		}
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+	return E_OK;
+	}
+
+/*
+ *  dhcp6c_renew_info -- ネットワーク情報を再取得する。
+ */
+
+ER
+dhcp6c_renew_info (void)
+{
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+
+	if (context.fsm == DHCP6_FSM_INFORMED) {
+
+		/* REL_INFO 状態に遷移した後に SLEEP を解除するように設定する。*/
+		context.flags |= DHCP6C_FLAG_RENEW;
+		start_rel_info(&context);
+		return E_OK;
+		}
+	else if (context.fsm == DHCP6_FSM_SLEEP) {
+
+		/* SLEEP を解除する。*/
+		wup_tsk(DHCP6_CLI_TASK);
+		return E_OK;
+		}
+	else
+		return E_OBJ;
+
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+	if (context.fsm == DHCP6_FSM_BOUND) {
+
+		/* RENEW 状態に遷移する。*/
+		start_renew(&context);
+		return E_OK;
+		}
+	else if (context.fsm == DHCP6_FSM_SLEEP) {
+
+		/* SLEEP を解除する。*/
+		wup_tsk(DHCP6_CLI_TASK);
+		return E_OK;
+		}
+	else
+		return E_OBJ;
+
+#else	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+	}
+
+/*
+ *  dhcp6c_rel_info -- DHCP で設定されたネットワーク情報を解放する。
+ */
+
+ER
+dhcp6c_rel_info (void)
+{
+	/* REL_INFO 状態に遷移する。*/
+	start_rel_info(&context);
+	return E_OK;
+	}
+
+/*
+ *  dhcp6c_get_info -- DHCP で設定されたネットワーク情報を返す。
+ */
+
+ER
+dhcp6c_get_info (T_IN6_ADDR *addr, uint32_t *expire, uint32_t *renew,
+                                   uint32_t *rebind, uint32_t *deprefer, SYSTIM *bind_start)
+{
+	if (addr   == NULL || expire ==   NULL || renew == NULL || 
+	    rebind == NULL || deprefer == NULL || bind_start == NULL)
+		return E_PAR;
+	else if (context.act_msg == NULL)
+		return E_OBJ;
+	else {
+		//            context.timers[DHCP6C_TIMER_EXPIRE],
+		//            context.timers[DHCP6C_TIMER_RENEW],
+		//            context.timers[DHCP6C_TIMER_REBIND],
+		//            context.timers[DHCP6C_TIMER_DEPREF]);
+
+		*addr = context.act_msg->srv.ipaddr;
+		*expire		= context.timers[DHCP6C_TIMER_EXPIRE];
+		*renew		= context.timers[DHCP6C_TIMER_RENEW];
+		*rebind		= context.timers[DHCP6C_TIMER_REBIND];
+		*deprefer	= context.timers[DHCP6C_TIMER_DEPREF];
+		*bind_start	= context.act_msg->rcv_time;
+		return E_OK;
+		}
+	}
+
+/*
+ *  コールバック関数
+ */
+
+ER
+callback_nblk_dhcp6_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	T_DHCP6_CLI_MSG	*msg;
+	ER_UINT		len;
+
+	len = *(ER_UINT*)p_parblk;
+	if (len < 0 && len != E_RLWAI) {
+		/* E_RLWAI 以外で、0 以下の場合は、エラーコード */
+		syslog(LOG_NOTICE, "[DHCP6C(CBR)] error: %s, fncd: %s.", itron_strerror(len), in_strtfn(fncd));
+		}
+	else {
+		if (fncd == TEV_UDP_RCV_DAT) {
+
+			/* 受信メッセージリストが空の時は、受信しないでデータグラムを捨てる。*/
+			if (context.rcv_lst == NULL) 
+				syslog(LOG_NOTICE, "[DHCP6C(CBR)] receive buffer all busy.");
+			else {
+				/* メッセージを受信するメッセージ構造体を準備する。*/
+				syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+				msg = context.rcv_lst;
+				context.rcv_lst = context.rcv_lst->next;
+				syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+				/* メッセージを受信する。*/
+				len = UDP_RCV_DAT(context.cepid, &msg->srv, &msg->msg, sizeof(msg->msg), TMO_POL);
+
+				syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+				msg->len = len;
+				if (len >= 0) {
+					/* 受信したメッセージを検証メッセージリストに移す。*/
+					msg->next = context.val_lst;
+					context.val_lst = msg;
+					context.flags |= DHCP6C_FLAG_RCV_MSG;
+					}
+				else {
+					/* メッセージ構造体を受信メッセージリストに戻す。*/
+					context.error = len;
+					msg->next = context.rcv_lst;
+					context.rcv_lst = msg;
+					}
+				syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+				}
+			}
+		syscall(sig_sem(SEM_DHCP6_CLI_READY));
+		}
+	return E_OK;
+	}
+/*
+ *  dhcp6_cli_task -- DHCPv6 クライアントタスク
+ */
+
+void
+dhcp6_cli_task (intptr_t exinf)
+{
+	T_DHCP6_CLI_CONTEXT	*ct;
+	ID			tskid;
+	ER			error;
+
+	dly_tsk(1000);
+	get_tid(&tskid);
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+	syslog(LOG_NOTICE, "[DHCP6C:%d] started in stateless.", tskid);
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+	syslog(LOG_NOTICE, "[DHCP6C:%d] started in statefull.", tskid);
+#else
+#endif
+
+	dly_tsk(500);
+	ct = &context;
+
+	/* DHCP クライアントコンテキスト構造体を初期化する。*/
+	init_context(ct, (ID)exinf);
+
+	while (true) {
+
+		/* 1秒毎にタイムアウトするようにタイマーを設定する。*/
+		timeout((callout_func)dhcpc_timer, ct, NET_TIMER_HZ / DHCP6C_TIMER_HZ);
+
+		/* クライアント DUID を設定する。*/
+		init_duid(ct);
+
+		/* メッセージ構造体を初期化する。*/
+		if ((error = init_cli_msg(ct))  == E_OK) {
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+			start_req_info(ct);
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+			start_init(ct);
+#else
+#endif
+
+			/* メインループ */
+			error = dispatch_event(ct);
+			}
+
+		/* 全ての TIMER をキャンセルする。*/
+		cancel_all_timers(ct);
+
+		/* タイマーを停止する。*/
+		untimeout((callout_func)dhcpc_timer, ct);
+
+		/* メッセージ構造体を解放する。*/
+		rel_cli_msg(ct);
+
+		/* リースを解放後、再取得が指定されていなければ休止する。*/
+		if (!(ct->flags & DHCP6C_FLAG_RENEW)) {
+
+			/* 休止する。*/
+			if (error == E_OK)
+				syslog(LOG_NOTICE, "[DHCP6C] lease released, go to sleep.");
+			else {
+				syslog(LOG_NOTICE, "[DHCP6C] server not available, go to sleep, error: %s.", itron_strerror(error));
+				ct->fsm = DHCP6_FSM_SLEEP;
+				}
+			slp_tsk();
+			}
+		ct->flags = 0;
+		ct->error = E_OK;
+		}
+	}
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.cfg	(revision 398)
@@ -0,0 +1,58 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  DHCPv6 クライアント
+ *  コンフィギュレーションファイル
+ */
+
+#ifdef DHCP6_CLI_CFG
+
+/* タスク */
+
+CRE_TSK(DHCP6_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	UDP6_DHCP_CLI_CEPID,
+	dhcp6_cli_task,
+	DHCP6_CLI_MAIN_PRIORITY,
+	DHCP6_CLI_STACK_SIZE,
+	NULL
+	});
+
+/* セマフォ */
+
+CRE_SEM(SEM_DHCP6_CLI_READY,	{ TA_TPRI, 0, 1 });
+CRE_SEM(SEM_DHCP6_CLI_TIMER,	{ TA_TPRI, 1, 1 });
+CRE_SEM(SEM_DHCP6_CLI_LOCK,	{ TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.h	(revision 398)
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-2003 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ *
+ *   Internet Systems Consortium, Inc.
+ *   950 Charter Street
+ *   Redwood City, CA 94063
+ *   <info@isc.org>
+ *   https://www.isc.org/
+ *
+ * This code is based on the original client state machine that was
+ * written by Elliot Poger.  The code has been extensively hacked on
+ * by Ted Lemon since then, so any mistakes you find are probably his
+ * fault and not Elliot's.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project 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 DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP6_CLI_H
+#define DHCP6_CLI_H
+
+#ifdef DHCP6_CLI_CFG
+
+#include <netinet/in.h>
+#include <netapp/dhcp6.h>
+
+/* 
+ *  DHCP クライアントのスタックサイズ
+ */
+
+#define DHCP6_CLI_STACK_SIZE		1024		/* DHCP クライアントタスクのスタックサイズ	*/
+
+/* 
+ *  DHCP クライアントの優先度
+ */
+
+#define DHCP6_CLI_MAIN_PRIORITY		5		/* DHCP クライアントタスクの優先度		*/
+
+/* 
+ *  コンパイル時コンフィギュレーション
+ */
+
+/*
+ *  DHCPv6 動作モード
+ *
+ *    #define DHCP6_CLI_CFG_MODE で指定する。
+ *    指定されていなければ、ステートレスに設定する。
+ *
+ */
+
+#define DHCP6_CLI_CFG_STATELESS		0	/* ステートレスに設定する。		*/
+#define DHCP6_CLI_CFG_STATEFULL		1	/* ステートフルに設定する。		*/
+#define DHCP6_CLI_CFG_RA		2	/* RA の M/O ビットにより設定する。	*/
+#define DHCP6_CLI_CFG_MODE_DEFAULT	DHCP6_CLI_CFG_STATELESS
+
+/* IA の設定 */
+#define DHCP6_CLI_CFG_IA_NA		1
+//#define DHCP6_CLI_CFG_IA_TA		1
+//#define DHCP6_CLI_CFG_IA_PD		1
+
+/* Rapid-commit の指定 */
+//#define DHCP6_CLI_CFG_RAPID_COMMIT	1
+
+/* 推奨度の定義 */
+#define DHCP6_CLI_CFG_PREFER_IA		50	/* IA_NA/TA/PD 当たりの推奨度	*/
+#define DHCP6_CLI_CFG_PREFER_IAADDR	100	/* アドレス当たりの推奨度	*/
+
+/* DHCPv6 クライアントメッセージの受信リストサイズ（2以上指定すること） */
+#define NUM_DHCP6_CLI_MSG_LIST		3
+
+/*
+ *  DHCPv6 クライアントメッセージ構造体数【変更禁止】
+ *  +1 は送信用
+ */
+#define NUM_MPF_DHCP6_CLI_MSG		(NUM_DHCP6_CLI_MSG_LIST+1)
+
+/* DHCP 必須オプションリスト */
+
+#ifndef DHCP6_CLI_CFG_REQUIRED_OLIST
+
+#if defined(USE_RESOLVER)
+
+#define DHCP6_CLI_CFG_REQUIRED_OLIST {	\
+	DHCP6_OPT_NAME_SERVERS,		\
+	}
+
+#else	/* of #if defined(USE_RESOLVER) */
+
+#endif	/* of #if defined(USE_RESOLVER) */
+
+#endif	/* of #ifndef DHCP6_CLI_CFG_REQUIRED_OLIST */
+
+/* DHCP 要求オプションリスト */
+
+#ifndef DHCP6_CLI_CFG_REQUEST_OLIST
+
+#if defined(USE_RESOLVER)
+
+#define DHCP6_CLI_CFG_REQUEST_OLIST {	\
+	DHCP6_OPT_DOMAIN_SEARCH,	\
+	}
+
+#else	/* of #if defined(USE_RESOLVER) */
+
+#endif	/* of #if defined(USE_RESOLVER) */
+
+#endif	/* of #ifndef DHCP6_CLI_CFG_REQUEST_OLIST */
+
+/*
+ *  タイムアウト定数
+ *  RFC3315 に規定されたタイミング定数は dhcp6.h 参照
+ */
+
+/* 標準メッセージの再送信タイムアウト	*/
+#define TMO_DHCP6C_NORMAL	ULONG_C(60*1000)
+
+/* 標準要求リース時間			*/
+#define TMO_DHCP6C_REQ_LEASE	ULONG_C(7200*1000)
+
+/* メッセージ構造体獲得タイムアウト	*/
+#define TMO_DHCP6C_MPF_GET	ULONG_C(1000)
+
+/* メッセージ受信タイムアウト	*/
+#define TMO_DHCP6C_RCV_DAT	ULONG_C(1000)
+
+/*
+ *  DHCPv6 クライアントメッセージ構造体
+ */
+
+typedef struct dhcp6_cli_msg {
+	/* 4バイト境界にアラインする。*/
+	T_DHCP6_MSG		msg;		/* DHCPv6 メッセージ構造体	*/
+	struct dhcp6_cli_msg	*next;		/* リストの次のメッセージ構造体	*/
+	SYSTIM			rcv_time;	/* 受信した時間			*/
+	T_IPV6EP		srv;		/* サーバのIPv6アドレス/ポート番号 */
+	uint16_t		len;		/* msg の有効長			*/
+	uint16_t		prefer;		/* msg の推奨度			*/
+	uint16_t		status;		/* STATUS CODE オプションの status */
+	} T_DHCP6_CLI_MSG;
+
+/* prefer のフラグ */
+
+#define DHCP6_ClI_MSG_PREFER_ADDR	UINT_C(0x8000)	/* アドレス情報あり		*/
+#define DHCP6_ClI_MSG_PREFER_REQUIRED	UINT_C(0x4000)	/* 必須オプションあり		*/
+#define DHCP6_ClI_MSG_PREFER_REQUEST	UINT_C(0x2000)	/* 要求オプションあり		*/
+#define DHCP6_ClI_MSG_PREFER_OPTION	UINT_C(0x1000)	/* PREFER オプションあり	*/
+#define DHCP6_ClI_MSG_PREFER_FLAG_MASK	UINT_C(0xf000)
+#define DHCP6_ClI_MSG_PREFER_VALUE_MASK	(~(DHCP6_ClI_MSG_PREFER_FLAG_MASK))
+
+/*
+ *  STATUS CODE オプションが無い時の値
+ */
+
+#define DHCP6_CLI_STAT_UNDEFINED	(-1)
+
+/*
+ *  コールバック関数
+ */
+
+extern ER callback_nblk_dhcp6_cli (ID cepid, FN fncd, void *p_parblk);
+
+/*
+ *  タスク
+ */
+
+extern void	dhcp6_cli_task(intptr_t exinf);
+
+/*
+ *  関数
+ */
+
+extern ER dhcp6c_rel_info (void);
+extern ER dhcp6c_renew_info (void);
+extern ER dhcp6c_get_info (T_IN6_ADDR *addr, uint32_t *expire, uint32_t *renew,
+                                             uint32_t *rebind, uint32_t *deprefer, SYSTIM *bind_start);
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
+
+#endif	/* of #ifndef DHCP6_CLI_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_asp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_asp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_asp.cfg	(revision 398)
@@ -0,0 +1,60 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ASP 用 DHCP クライアントのシステムコンフィギュレーションファイル
+ */
+
+/*
+ *  共通 DHCP クライアントのシステムコンフィギュレーションファイルのインクルード
+ */
+
+#ifdef DHCP6_CLI_CFG
+
+INCLUDE("netapp/dhcp6_cli.cfg");
+
+/*
+ * 固定メモリプール
+ */
+
+/* 送受信バッファ */
+
+CRE_MPF(MPF_DHCP6_CLI_MSG, {
+	TA_TFIFO,
+	NUM_MPF_DHCP6_CLI_MSG,
+	sizeof(T_DHCP6_CLI_MSG),
+	NULL,
+	NULL
+	});
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_jsp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_jsp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_jsp.cfg	(revision 398)
@@ -0,0 +1,59 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  JSP 用 DHCP クライアントのシステムコンフィギュレーションファイル
+ */
+
+/*
+ *  共通 DHCP クライアントのシステムコンフィギュレーションファイルのインクルード
+ */
+
+#ifdef DHCP6_CLI_CFG
+
+#include "netapp/dhcp6_cli.cfg"
+
+/*
+ * 固定メモリプール
+ */
+
+/* 送受信バッファ */
+
+CRE_MPF(MPF_DHCP6_CLI_MSG, {
+	TA_TFIFO,
+	NUM_MPF_DHCP6_CLI_MSG,
+	sizeof(T_DHCP6_CLI_MSG),
+	NULL
+	});
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_var.h	(revision 398)
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-2003 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ *
+ *   Internet Systems Consortium, Inc.
+ *   950 Charter Street
+ *   Redwood City, CA 94063
+ *   <info@isc.org>
+ *   https://www.isc.org/
+ *
+ * This code is based on the original client state machine that was
+ * written by Elliot Poger.  The code has been extensively hacked on
+ * by Ted Lemon since then, so any mistakes you find are probably his
+ * fault and not Elliot's.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project 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 DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP6_CLI_VAR_H
+#define DHCP6_CLI_VAR_H
+
+#ifdef DHCP6_CLI_CFG
+
+/*
+ *  DHCP クライアントコンテキスト構造体
+ */
+
+/* TIMER の定義 */
+
+#define DHCP6C_TIMER_SND_SOL	0
+#define DHCP6C_TIMER_SND_REQ	1
+#define DHCP6C_TIMER_SND_REL	2
+#define DHCP6C_TIMER_RCV_ADV	3
+#define DHCP6C_TIMER_RCV_REPLY	4
+#define DHCP6C_TIMER_RENEW	5
+#define DHCP6C_TIMER_REBIND	6
+#define DHCP6C_TIMER_EXPIRE	7
+#define DHCP6C_TIMER_DEPREF	8
+#define DHCP6C_TIMER_SND_REF	9
+#define DHCP6C_TIMER_SND_IREQ	10
+#define NUM_DHCP6C_TIMERS	11
+
+#define DHCP6C_TIMER_HZ		1
+
+/* 定数の定義 */
+
+#define MAX_DUID_LEN		(ETHER_ADDR_LEN+8)
+
+typedef struct dhcp6_cli_context {
+	T_DHCP6_CLI_MSG		*rcv_lst;	/* 受信メッセージ構造体リスト		*/
+	T_DHCP6_CLI_MSG		*val_lst;	/* 検証メッセージ構造体リスト		*/
+	T_DHCP6_CLI_MSG		*prf_lst;	/* 推奨メッセージ構造体リスト		*/
+	T_DHCP6_CLI_MSG		*snd_msg;	/* 送信メッセージ構造体			*/
+	T_DHCP6_CLI_MSG		*adv_msg;	/* 通知されたリース・メッセージ構造体	*/
+	T_DHCP6_CLI_MSG		*act_msg;	/* 有効なリース・メッセージ構造体	*/
+	T_IF_SOFTC		*sc;		/* IF のソフトウェア情報		*/
+	T_IPV6EP		dst;		/* 送信先のIPアドレス/ポート番号	*/
+	SYSTIM			RT;		/* 再送信間隔				*/
+	SYSTIM			IRT;		/* 初期再送信間隔			*/
+	SYSTIM			MRT;		/* 最大再送信間隔			*/
+	SYSTIM			MRD;		/* 最大再送信継続時間			*/
+	SYSTIM			next_MRD;	/* 次の最大再送信継続時間		*/
+	SYSTIM			timers[NUM_DHCP6C_TIMERS];	
+						/* タイマー配列			*/
+	ER_UINT			error;		/* エラー・データ長		*/
+	ID			cepid;		/* CEP ID			*/
+	uint32_t		xid;		/* トランザクション ID		*/
+	uint16_t		flags;		/* 各種フラグ			*/
+	uint16_t		max_prefer;	/* 受信メッセージの最大推奨度	*/
+	uint8_t			duid[MAX_DUID_LEN];	
+						/* client DHCP Unique ID	*/
+	uint8_t			duid_len;	/* client DUID 長		*/
+	uint8_t			fsm;		/* 現在の状態			*/
+	uint8_t			MRC;		/* 最大再送信回数		*/
+	uint8_t			txcount;	/* 再送信回数			*/
+	uint8_t			refresh_type;	/* REFRESH のメッセージタイプ	*/
+	} T_DHCP6_CLI_CONTEXT;
+
+/* fsm（状態遷移）の定義 */
+
+#define DHCP6_FSM_INIT		1
+#define DHCP6_FSM_SELECT	2
+#define DHCP6_FSM_BOUND		4
+#define DHCP6_FSM_RENEW		5
+#define DHCP6_FSM_REBIND	6
+#define DHCP6_FSM_REQ_INFO	9	/* DHCPv6 の RFC3315 には無い。*/
+#define DHCP6_FSM_INFORMED	10	/* DHCPv6 の RFC3315 には無い。*/
+#define DHCP6_FSM_REL_INFO	11	/* DHCPv6 の RFC3315 には無い。*/
+#define DHCP6_FSM_SLEEP		12	/* DHCPv6 の RFC3315 には無い。*/
+
+/* flag の定義 */
+
+#define DHCP6C_FLAG_TMOUT_SND_SOL	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_SND_SOL)
+#define DHCP6C_FLAG_TMOUT_SND_REQ	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_SND_REQ)
+#define DHCP6C_FLAG_TMOUT_SND_REL	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_SND_REL)
+#define DHCP6C_FLAG_TMOUT_RCV_ADV	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_RCV_ADV)
+#define DHCP6C_FLAG_TMOUT_RCV_REPLY	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_RCV_REPLY)
+#define DHCP6C_FLAG_TMOUT_RENEW		(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_RENEW)
+#define DHCP6C_FLAG_TMOUT_REBIND	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_REBIND)
+#define DHCP6C_FLAG_TMOUT_EXPIRE	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_EXPIRE)
+#define DHCP6C_FLAG_TMOUT_DEPREF	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_DEPREF)
+#define DHCP6C_FLAG_TMOUT_SND_REF	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_SND_REF)
+#define DHCP6C_FLAG_TMOUT_SND_IREQ	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_SND_IREQ)
+#define DHCP6C_FLAG_TMOUT_TIMER		UINT_C(0x0010)
+#define DHCP6C_FLAG_TMOUT_TIMER_MASK	UINT_C(0x000f)
+#define DHCP6C_FLAG_TMOUT_MASK		UINT_C(0x001f)
+
+#define DHCP6C_FLAG_RCV_MSG		UINT_C(0x0200)
+#define DHCP6C_FLAG_RENEW		UINT_C(0x0400)
+
+/* IAADDR 構造体の FLAG の定義（len に多重化する）*/
+
+#define DHCP6C_IAA_FLAG_EXPIRED		UINT_C(0x8000)
+#define DHCP6C_IAA_FLAG_DEPREFERD	UINT_C(0x4000)
+#define DHCP6C_IAA_FLAG_MASK		UINT_C(0xc000)
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+/* 時間比較 */
+
+#define TIMEC_GT(a,b)		((int32_t)((a)-(b))>0)
+#define TIMEC_GE(a,b)		((int32_t)((a)-(b))>=0)
+
+/* 時間定数の変換 */
+
+#define SYSTIM2TIMER(t)		(((t)<SYSTIM_HZ/DHCP6C_TIMER_HZ)?(DHCP6C_TIMER_HZ):((t)*DHCP6C_TIMER_HZ)/SYSTIM_HZ)
+#define SYSTIM2SEC(t)		(((t)<SYSTIM_HZ)?1:((t)/SYSTIM_HZ))
+#define SEC2TIMER(t)		((t)*DHCP6C_TIMER_HZ)
+#define SEC2SYSTIM(t)		((t)*SYSTIM_HZ)
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
+
+#endif	/* of #ifndef DHCP6_CLI_VAR_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dns.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dns.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/dns.h	(revision 398)
@@ -0,0 +1,278 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DNS_H
+#define DNS_H
+
+/*
+ *  DNS メッセージに関する定義
+ *
+ *    RFC1034、RFC1035、RFC1886、RFC2136、
+ *    RFC2671、RFC2845、RFC2930、RFC3596
+ *
+ *  DNS メッセージ
+ *
+ *  +---------------------+
+ *  |       Header        |
+ *  +---------------------+
+ *  |      Question       | Question section 形式
+ *  +---------------------+
+ *  |       Answer        | RR (Resouce Record) 形式
+ *  +---------------------+
+ *  |     Authority       | RR (Resouce Record) 形式
+ *  +---------------------+
+ *  |     Additional      | RR (Resouce Record) 形式
+ *  +---------------------+
+ *
+ *  DNS ヘッダ
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                      ID                       |
+ *  +--+-----------+--+--+--+--+--------+-----------+
+ *  |QR|   Opcode  |AA|TC|RD|RA|    Z   |   RCODE   |
+ *  +--+--------+--+--+--+--+--+--------+-----------+
+ *  |                    QDCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    ANCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    NSCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    ARCOUNT                    |
+ *  +-----------------------------------------------+
+ */
+
+typedef struct dns_hdr {
+	uint16_t	id;		/* ID */
+	uint16_t	code;	/* QR:		1
+				   Opcode:	4
+				   AA:		1
+				   TC:		1
+				   RD:		1
+				   RA:		1
+				   Z:		3
+				   RCODE:	4
+				   */
+	uint16_t	qdcount;	/* question   section */
+	uint16_t	ancount;	/* answer     section */
+	uint16_t	nscount;	/* authority  section */
+	uint16_t	arcount;	/* additional section */
+	} T_DNS_HDR;
+
+/*
+ *  code の定義
+ */
+
+/* QR の定義 */
+
+#define DNS_QR_QUERY		0x0000U
+#define DNS_QR_RESPONSE		0x8000U
+
+/* Opcode の定義 */
+
+#define DNS_OPCODE_MASK		0x7800U
+#define DNS_OPCODE_FORWARD	0x0000U
+#define DNS_OPCODE_REVERSE	0x0800U
+#define DNS_OPCODE_STATUS	0x1000U
+
+/* AA の定義 */
+
+#define DNS_AUTHORITATIVE	0x0400U
+
+/* TC の定義 */
+
+#define DNS_TRUN_CATION		0x0200U
+
+/* RD の定義 */
+
+#define DNS_RECURSION_DESIRED	0x0100U
+
+/* RA の定義 */
+
+#define DNS_RECURSION_AVAILABLE	0x0080U
+
+/* RCODE の定義 */
+
+#define DNS_RCODE_MASK		0x000fU
+#define DNS_RCODE_NO_ERROR	0x0000U
+#define DNS_RCODE_FORMAT_ERROR	0x0001U
+#define DNS_RCODE_SERVER_ERROR	0x0002U
+#define DNS_RCODE_NAME_ERROR	0x0003U
+#define DNS_RCODE_NOT_IMPLEMENT	0x0004U
+#define DNS_RCODE_REFUSED	0x0005U
+
+/*
+ * DNS TYPE の定義
+ */
+
+#define DNS_TYPE_A		(uint16_t)1U
+#define DNS_TYPE_NS		(uint16_t)2U
+#define DNS_TYPE_CNAME		(uint16_t)5U
+#define DNS_TYPE_SOA		(uint16_t)6U
+#define DNS_TYPE_PTR		(uint16_t)12U
+#define DNS_TYPE_AAAA		(uint16_t)28U
+
+/*
+ * DNS CLASS の定義
+ */
+
+#define DNS_CLASS_IN		(uint16_t)1U
+
+/*
+ *  RR (Resouce Record) 形式
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                      NAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                      TYPE                     |
+ *  +-----------------------------------------------+
+ *  |                      CLASS                    |
+ *  +-----------------------------------------------+
+ *  |                       TTL                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    RDLENGTH                   |
+ *  +-----------------------------------------------+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     RDATA                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *
+ *    注意: offset の原点は DNS message の先頭
+ */
+
+typedef struct dns_rr {
+					/* NAME			*/
+	uint16_t	type;		/* TYPE			*/
+	uint16_t	class;		/* CLASS		*/
+	uint32_t	ttl;		/* TTL			*/
+	uint16_t	rdlength;	/* RDATA length		*/
+					/* RDATA		*/
+	} T_DNS_RR;
+
+#define T_DNS_RR_SIZE	(sizeof(uint16_t)*3+sizeof(uint32_t))
+
+/*
+ *  Question section 形式
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     QNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                     QTYPE                     |
+ *  +-----------------------------------------------+
+ *  |                     QCLASS                    |
+ *  +-----------------------------------------------+
+ */
+
+typedef struct dns_qd {
+					/* QNAME		*/
+	uint16_t	type;		/* TYPE			*/
+	uint16_t	class;		/* CLASS		*/
+	} T_DNS_QD;
+
+#define T_DNS_QD_SIZE	(sizeof(uint16_t)*2)
+
+/*
+ *  SOA RDATA 形式
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     MNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     RNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                    SERIAL                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    REFRESH                    |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                     RETRY                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    EXPIRE                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    MINIMUM                    |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *
+ *    注意: offset の原点は DNS message の先頭
+ */
+
+typedef struct dns_soa {
+					/* MNAME		*/
+					/* RNAME		*/
+	uint32_t	serial;		/* SERIAL		*/
+	uint32_t	refresh;	/* REFRESH		*/
+	uint32_t	retry;		/* RETRY		*/
+	uint32_t	expire;		/* EXPIRE		*/
+	uint32_t	minimum;	/* MINIMUM		*/
+	} T_DNS_SOA;
+
+#define T_DNS_SOA_SIZE	(sizeof(uint32_t)*5)
+
+/*
+ *  DNS の定数の定義
+ */
+
+#define DNS_LABEL_LENGTH	63
+#define DNS_NAME_LENGTH		255
+#define DNS_UDP_MSG_LENGTH	512
+
+#define DNS_MSG_COMP_MARK	0xc0
+
+#endif	/* of #ifndef DNS_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/lcd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/lcd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/lcd.c	(revision 398)
@@ -0,0 +1,482 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <sil.h>
+#include "target_syssvc.h"
+#include "target_lcd.h"
+#include <kernel.h>
+#include <t_syslog.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "hw_lcd.h"
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/lcd.h>
+
+/*
+ *  局所変数の定義
+ */
+
+static bool_t newline = false;
+static int_t col = 0;
+static int8_t line[LCD_COLUMN_SIZE + 1] = { "                " };
+
+/*
+ *  lcd_cls -- LCD 表示クリア
+ */
+
+void
+lcd_cls (void)
+{
+	target_lcd_cls();
+	col = 0;
+	newline = false;
+	}
+
+/*
+ *  lcd_newline -- LCD の表示を改行する。
+ */
+
+static void
+lcd_newline (void)
+{
+	target_lcd_newline(line, col);
+	col = 0;
+	newline = false;
+	}
+
+/*
+ *  lcd_initialize -- LCD 初期化
+ */
+
+void
+lcd_initialize (intptr_t exinf)
+{
+	target_lcd_initialize();
+	lcd_cls();
+	}
+
+/*
+ *  lcd_putc -- LCD 出力
+ */
+
+void
+lcd_putc (ID portid, int8_t data)
+{
+	if (data == '\n')
+		newline = true;
+	else {
+		if (newline)
+			lcd_newline();
+		target_lcd_data_putc(data);
+		line[col ++] = data;
+		if (col >= LCD_COLUMN_SIZE)
+			newline = true;
+		}
+	}
+
+/*
+ *  lcd_puts -- LCD への文字列の出力
+ */
+
+void
+lcd_puts (ID portid, const char *str)
+{
+	while (*str != '\0')
+		lcd_putc(portid, *str ++);
+	}
+
+/*
+ *  LCD への書式付文字列出力ライブラリ
+ */
+
+/*
+ *  数値変換のための変換表
+ */
+
+static const char radhex[] = "0123456789abcdef";
+static const char radHEX[] = "0123456789ABCDEF";
+
+/*
+ *  もっとも長い整数型 (LONGEST) と符号なし整数型 (ULONGEST)
+ */
+
+#ifdef _int64_
+
+typedef _int64_			LONGEST;
+typedef unsigned _int64_	ULONGEST;
+
+#else	/* of #ifdef _int64_ */
+
+#ifdef _int32_
+
+typedef _int32_			LONGEST;
+typedef unsigned _int32_	ULONGEST;
+
+#else	/* of #ifdef _int32_ */
+
+typedef int_t			LONGEST;
+typedef uint_t			ULONGEST;
+
+#endif	/* of #ifdef _int32_ */
+
+#endif	/* of #ifdef _int64_ */
+
+/*
+ *  convert -- lcd_printf の数値変換
+ */
+
+static int_t
+convert (ID portid, ULONGEST val, int_t radix,
+         const char *radchar, int_t width, bool_t minus, char padchar)
+{
+	char	digits[24];
+	int_t	ix, pad, pchars;
+	bool_t	left;
+
+	if (width < 0) {
+		width = -width;
+		left = true;
+		}
+	else
+		left = false;
+
+	ix = 0;
+	do {
+		digits[ix ++] = radchar[val % radix];
+		val /= radix;
+		} while (val != 0);
+
+	if (minus)
+		digits[ix ++] = '-';
+
+	if (width > ix)
+		pchars = width;
+	else
+		pchars = ix;
+
+	pad = ix;
+	if (!left)	/* 右詰め */
+		for ( ; pad < width; pad ++)
+			lcd_putc(portid, padchar);
+
+	while (ix -- > 0)
+		lcd_putc(portid, digits[ix]);
+
+	if (left)	/* 左詰め */
+		for ( ; pad < width; pad ++)
+			lcd_putc(portid, padchar);
+
+	return pchars;
+	}
+
+#if defined(SUPPORT_INET4)
+
+/*
+ *  ipv4addr -- IPv4 アドレス出力
+ */
+
+static void
+put_ipv4addr (ID portid, T_IN4_ADDR *addr, int_t width)
+{
+	int_t len = 3;	/* 3 は '.' の文字数 */
+
+	len += convert(portid, (*addr >> 24) & 0xff, 10, radhex, 0, false, ' '); 
+	lcd_putc(portid, '.');
+	len += convert(portid, (*addr >> 16) & 0xff, 10, radhex, 0, false, ' '); 
+	lcd_putc(portid, '.');
+	len += convert(portid, (*addr >>  8) & 0xff, 10, radhex, 0, false, ' '); 
+	lcd_putc(portid, '.');
+	len += convert(portid,  *addr        & 0xff, 10, radhex, 0, false, ' '); 
+
+	for ( ; len < width; len ++)
+		lcd_putc(portid, ' ');
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+/*
+ *  ipv6addr -- IPv6 アドレス出力
+ */
+
+static void
+put_ipv6addr (ID portid, const T_IN6_ADDR *addr, int_t width)
+{
+	int_t	len = 0, ix;
+	bool_t	omit = false, zero = false;
+
+	if (addr == NULL || IN6_IS_ADDR_UNSPECIFIED(addr)) {
+		lcd_putc(portid, ':');
+		lcd_putc(portid, ':');
+		}
+	else {
+		for (ix = 0; ix < sizeof(T_IN6_ADDR) / 2; ix ++) {
+			if (omit) {
+				if (ix < 7) {
+					lcd_putc(portid, ':');
+					len ++;
+					}
+				}
+			else if (ix > 0 && ix < 7 && addr->s6_addr16[ix] == 0)
+				zero = true;
+			else {
+				if (zero) {
+					omit = true;
+					lcd_putc(portid, ':');
+					len ++;
+					}
+				if (ix < 7) {
+					lcd_putc(portid, ':');
+					len ++;
+					}
+				}
+			}
+
+		for ( ; len < width; len ++)
+			lcd_putc(portid, ' ');
+		}
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/*
+ *  macaddr -- MAC アドレス出力
+ */
+
+static void
+macaddr (ID portid, uint8_t *mac, int_t width)
+{
+	int_t oct, len;
+
+	for (oct = 5; oct -- > 0; ) {
+		convert(portid, *mac ++, 16, radhex, 2, false, '0'); 
+		lcd_putc(portid, ':');
+		}
+	convert(portid, *mac, 16, radhex, 2, false, '0'); 
+
+	for (len = 17; len < width; len ++)
+		lcd_putc(portid, ' ');
+	}
+
+/*
+ *  引数を取り出すためのマクロ
+ */
+
+#ifdef _int32_
+
+#define GET_ARG(ap,lf)	 (lf ? va_arg(ap, _int32_) : va_arg(ap, int_t))
+
+#else	/* of #ifdef _int32_ */
+
+#define GET_ARG(ap,lf)	(va_arg(ap, int_t))
+
+#endif	/* of #ifdef _int32_ */
+
+/*
+ *  lcd_printf -- シリアルポートへの書式付文字列出力
+ */
+
+void
+lcd_printf (ID portid, const char *fmt, ...)
+{
+	va_list	ap;
+	LONGEST	val;
+	char	padchar, *str;
+	int_t	ch, width, longflag, shortflag, left;
+
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	*addr;
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+	va_start(ap, fmt);
+	while ((ch = *fmt ++) != '\0') {
+		if (ch != '%') {		/* 書式指定以外 */
+			lcd_putc(portid, (char)ch);
+			continue;
+			}
+
+		width = longflag = shortflag = 0;
+		padchar = ' ';
+
+		if (ch == '-') {		/* 左詰め */
+			fmt ++;
+			left = -1;
+			}
+		else
+			left = 1;
+
+		if ((ch = *fmt ++) == '0') {	/* 上位桁の 0 */
+			padchar = '0';
+			ch = *fmt ++;
+			}
+
+		while ('0' <= ch && ch <= '9') {	/* 出力幅 */
+			width = width * 10 + ch - '0';
+			ch = *fmt ++;
+			}
+
+		while (ch == 'l') {		/* long (long) の指定 */
+			longflag ++;
+			ch = *fmt ++;
+			}
+
+		while (ch == 'h') {		/* short の指定 */
+			shortflag ++;
+			ch = *fmt ++;
+			}
+
+		switch (ch) {
+		case 'd':
+			val = GET_ARG(ap, longflag);
+			if (val >= 0)
+				convert(portid, val, 10, radhex, width * left, false, padchar);
+			else
+				convert(portid, -val, 10, radhex, width * left, true, padchar);
+			break;
+
+		case 'u':
+			val = GET_ARG(ap, longflag);
+			convert(portid, val, 10, radhex, width * left, false, padchar);
+			break;
+
+		case 'x':
+			val = GET_ARG(ap, longflag);
+			convert(portid, val, 16, radhex, width * left, false, padchar);
+			break;
+
+		case 'X':
+			val = GET_ARG(ap, longflag);
+			convert(portid, val, 16, radHEX, width * left, false, padchar);
+			break;
+
+		case 'c':
+			ch = va_arg(ap, int_t);
+			lcd_putc(portid, (char)ch);
+			break;
+
+		case 's':
+			str = va_arg(ap, char*);
+			while ((ch = *str ++) != '\0')
+				lcd_putc(portid, (char)ch);
+			break;
+
+		case 'I':
+
+			if (longflag) {
+
+#if defined(SUPPORT_INET6)
+
+				str = va_arg(ap, char*);
+				put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+				addr = va_arg(ap, T_IN4_ADDR *);
+				put_ipv4addr(portid, addr, width);
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+				}
+			else if (shortflag) {
+
+#if defined(SUPPORT_INET4)
+
+				addr = va_arg(ap, T_IN4_ADDR *);
+				put_ipv4addr(portid, addr, width);
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+				str = va_arg(ap, char*);
+				put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+				}
+			else {
+
+#if defined(SUPPORT_INET6)
+
+				str = va_arg(ap, char*);
+				put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+				addr = va_arg(ap, T_IN4_ADDR *);
+				put_ipv4addr(portid, addr, width);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+				}
+			break;
+
+		case 'M':
+			str = va_arg(ap, char*);
+			macaddr(portid, str, width);
+			break;
+
+		case '%':
+			lcd_putc(portid, '%');
+			break;
+
+		case '0':
+			fmt --;
+			break;
+
+		default:
+			break;
+			}
+
+		}
+	va_end(ap);
+	}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/lcd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/lcd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/lcd.h	(revision 398)
@@ -0,0 +1,66 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  汎用 LCD ドライバ
+ */
+
+#ifndef LCD_H
+#define LCD_H
+
+/*
+ *  lcd_cls -- LCD 表示クリア
+ */
+extern void lcd_cls (void);
+
+/*
+ *  lcd_initialize -- LCD 初期化
+ */
+extern void lcd_initialize (intptr_t exinf);
+
+/*
+ *  lcd_putc -- LCD 出力
+ */
+extern void lcd_putc (ID portid, int8_t data);
+
+/*
+ *  lcd_puts -- LCD への文字列の出力
+ */
+extern void lcd_puts (ID portid, const char *str);
+
+/*
+ *  LCD への書式付文字列出力ライブラリ
+ */
+extern void lcd_printf (ID portid, const char *fmt, ...);
+
+#endif	/* of #ifndef LCD_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/net_cons.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/net_cons.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/net_cons.c	(revision 398)
@@ -0,0 +1,593 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  ネットワーク経由コンソール入出力
+ */
+
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <syssvc/serial.h>
+#include <syssvc/logtask.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/net_cons.h>
+
+#ifdef USE_NET_CONS
+
+/*
+ *  マクロ定義
+ */
+
+/*  リネームの解除  */
+
+#undef syslog
+#undef serial_rea_dat
+#undef serial_ctl_por
+
+#define EOF		(-1)
+
+/*  TELNET オプション */
+
+#define TELNET_OPT_SE		(240)
+#define TELNET_OPT_NOP		(241)
+#define TELNET_OPT_DM		(242)
+#define TELNET_OPT_BRK		(243)
+#define TELNET_OPT_IP		(244)
+#define TELNET_OPT_AO		(245)
+#define TELNET_OPT_AYT		(246)
+#define TELNET_OPT_EC		(247)
+#define TELNET_OPT_EL		(248)
+#define TELNET_OPT_GA		(249)
+#define TELNET_OPT_SB		(250)
+#define TELNET_OPT_WILL		(251)
+#define TELNET_OPT_WONT		(252)
+#define TELNET_OPT_DO		(253)
+#define TELNET_OPT_DONT		(254)
+#define TELNET_OPT_IAC		(255)
+
+#if defined(SUPPORT_INET6)
+#define API_PROTO		'6'
+#else
+#define API_PROTO		'4'
+#endif
+
+/*
+ *  変数
+ */
+
+/*  TCP 送受信ウィンドバッファ  */
+
+uint8_t net_cons_swbuf[NET_CONS_SWBUF_SIZE];
+uint8_t net_cons_rwbuf[NET_CONS_RWBUF_SIZE];
+
+bool_t	connected	= false;	/* コネクションの状態	*/
+bool_t	wait_accept	= false;	/* 接続要求待ち中	*/
+
+#if defined(SUPPORT_INET6)
+
+T_IPV6EP	dst;
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+T_IPV4EP	dst;
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+uint8_t		*snd_buff	= NULL;
+uint8_t		*rcv_buff	= NULL;
+uint_t		snd_off		= 0;
+uint_t		rcv_off		= 0;
+uint_t		net_ioctl	= IOCTL_NULL;
+ER_UINT		snd_len		= 0;
+ER_UINT		rcv_len		= 0;
+
+/*
+ *  ノンブロッキングコールのコールバック関数
+ */
+
+ER
+callback_nblk_net_cons (ID cepid, FN fncd, void *p_parblk)
+{
+	ER	error = E_OK;
+	SYSTIM	now;
+
+	switch (fncd) {
+
+	case TFN_TCP_ACP_CEP:
+		get_tim(&now);
+		if (*(ER*)p_parblk == E_OK) {
+			syslog(LOG_NOTICE, "[NCS%c:%02u CBN] conct: %7lu, from: %s.%u",
+			                   API_PROTO, cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+			connected = true;
+			}
+		else
+			syslog(LOG_NOTICE, "[NCS%c:%02d CBN] error: %s",
+			                   API_PROTO, itron_strerror(*(ER*)p_parblk));
+		snd_len = snd_off = rcv_len = rcv_off = 0;
+		wait_accept = false;
+		break;
+
+	case TFN_TCP_CLS_CEP:
+	case TFN_TCP_RCV_BUF:
+	case TFN_TCP_GET_BUF:
+	case TFN_TCP_RCV_DAT:
+	case TFN_TCP_SND_DAT:
+	case TFN_TCP_CON_CEP:
+	case TFN_TCP_SND_OOB:
+	default:
+		error = E_PAR;
+		break;
+		}
+	return error;
+	}
+
+/*
+ *  送信バッファのフラッシュ
+ */
+
+void
+flush_snd_buff (void)
+{
+	ER_UINT	error;
+
+	if (connected) {
+		syscall(wai_sem(SEM_NET_CONS_SEND));
+		if (snd_off > 0) {
+			if ((error = tcp_snd_buf(NET_CONS_CEPID, snd_off)) != E_OK && error != E_CLS)
+				syslog(LOG_NOTICE, "[NCS%c:%02d SND] flush send error: %s",
+				                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
+			snd_len = snd_off = 0;
+			}
+		syscall(sig_sem(SEM_NET_CONS_SEND));
+		}
+	return;
+	}
+
+/*
+ *  文字送信
+ */
+
+void
+cons_putchar (ID portid, char ch)
+{
+	ER_UINT	error;
+
+	if (connected) {
+		if (ch == '\n' && (net_ioctl & IOCTL_CRLF) != 0)
+			cons_putchar(portid, '\r');
+		syscall(wai_sem(SEM_NET_CONS_SEND));
+		if (snd_off >= snd_len) {
+			if ((error = tcp_snd_buf(NET_CONS_CEPID, snd_off)) != E_OK) {
+				if (error != E_CLS)
+					syslog(LOG_NOTICE, "[NCS%c:%02d SND] send buff error: %s",
+					                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
+				syscall(sig_sem(SEM_NET_CONS_SEND));
+				return;
+				}
+			snd_off = 0;
+			if ((snd_len = tcp_get_buf(NET_CONS_CEPID, (void*)&snd_buff, TMO_FEVR)) <= 0) {
+				if (snd_len != E_CLS)
+					syslog(LOG_NOTICE, "[NCS%c:%02d SND] get buff error: %s",
+					                   API_PROTO, NET_CONS_CEPID, itron_strerror(snd_len));
+				syscall(sig_sem(SEM_NET_CONS_SEND));
+				return;
+				}
+			}
+		snd_buff[snd_off ++] = ch;
+		syscall(sig_sem(SEM_NET_CONS_SEND));
+		}
+	else
+		serial_wri_dat(portid, &ch, sizeof(ch));
+	}
+
+/*
+ *  文字受信（変換なし）
+ */
+
+static int_t
+cons_getchar_raw (void)
+{
+	ER	error = E_OK;
+
+	if (connected) {
+		if (rcv_off >= rcv_len) {
+			rcv_off = 0;
+			if ((error = tcp_rel_buf(NET_CONS_CEPID, rcv_len)) != E_OK) {
+				if (error != E_CLS)
+					syslog(LOG_NOTICE, "[NCS%c:%02d RCV] release buff error: %s",
+					                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
+				discon_net_cons();
+				return EOF;
+				}
+			if ((rcv_len = tcp_rcv_buf(NET_CONS_CEPID, (void*)&rcv_buff, TMO_FEVR)) == 0) {
+				discon_net_cons();
+				return EOF;
+				}
+			else if (rcv_len < 0) {
+				if (rcv_len != E_CLS)
+					syslog(LOG_NOTICE, "[NCS%c:%02d RCV] recieve buff error: %s",
+					                   API_PROTO, NET_CONS_CEPID, itron_strerror(rcv_len));
+				discon_net_cons();
+				return EOF;
+				}
+			}
+		return rcv_buff[rcv_off ++];
+		}
+	else
+		return EOF;
+	}
+
+/*
+ *  文字受信（TELNET オプションをスキップ）
+ */
+
+int_t
+cons_getchar (ID portid)
+{
+	T_SERIAL_RPOR	rpor;
+	int_t		ch;
+	char		uch;
+	ER		error;
+
+	if (!wait_accept && !connected) {
+		wait_accept = true;
+		error = TCP_ACP_CEP(NET_CONS_CEPID, NET_CONS_REPID, &dst, TMO_NBLK);
+#if 0
+		syslog(LOG_NOTICE, "[NCS%c:%02d ACP] status: %s",
+		                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
+#endif
+		if (error != E_WBLK)
+			return EOF;
+		}
+
+	while (true) {
+		if (connected) {
+			while ((ch = cons_getchar_raw()) == TELNET_OPT_IAC || ch == '\0') {
+				if (ch != '\0') {
+					switch (ch = cons_getchar_raw()) {
+					case TELNET_OPT_WILL:
+					case TELNET_OPT_WONT:
+					case TELNET_OPT_DO:
+					case TELNET_OPT_DONT:
+						cons_getchar_raw();
+						break;
+					case TELNET_OPT_SB:
+						while ((ch = cons_getchar_raw()) != EOF && ch != TELNET_OPT_IAC) {
+							if ((ch = cons_getchar_raw()) == EOF || ch == TELNET_OPT_SE)
+								break;
+							}
+						break;
+					default:
+						break;
+						}
+					}
+				}
+			if (ch != '\n') {
+				if ((net_ioctl & IOCTL_ECHO) != 0 && ch != EOF) {
+					cons_putchar(portid, ch);
+					flush_snd_buff();
+					}
+				return ch;
+				}
+			}
+
+		else if (serial_ref_por(portid, &rpor) == E_OK && rpor.reacnt > 0) {
+			if (serial_rea_dat(portid, &uch, sizeof(uch)) > 0)
+				return uch;
+			else
+				return EOF;
+			}
+		dly_tsk(100);
+		}
+	return EOF;
+	}
+
+/*
+ *  コネクションを切断
+ */
+
+ER
+discon_net_cons (void)
+{
+	ER	error = E_OK;
+	SYSTIM	now;
+
+	if (connected) {
+		syscall(wai_sem(SEM_NET_CONS_SEND));
+		if (snd_off > 0) {
+			if ((error = tcp_snd_buf(NET_CONS_CEPID, snd_off)) != E_OK && error != E_CLS)
+				syslog(LOG_NOTICE, "[NCS%c:%02d SND] send buff error: %s",
+				                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
+			}
+		if ((error = tcp_sht_cep(NET_CONS_CEPID)) != E_OK)
+			syslog(LOG_NOTICE, "[NCS%c:%02d SHT] shutdown error: %s",
+			                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
+		if ((error = tcp_cls_cep(NET_CONS_CEPID, TMO_FEVR)) != E_OK)
+			syslog(LOG_NOTICE, "[NCS%c:%02d CLS] close error: %s",
+			                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
+		connected = false;
+		syscall(sig_sem(SEM_NET_CONS_SEND));
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[NCS%c:%02u SND] discn: %7lu, from: %s.%u",
+		                   API_PROTO, NET_CONS_CEPID, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+		}
+	return error;
+	}
+
+/*
+ *  シリアルポートの制御
+ */
+
+ER
+net_serial_ctl_por (ID portid, uint_t ioctl)
+{
+	net_ioctl = ioctl;
+	return serial_ctl_por(portid, ioctl);
+	}
+
+/*
+ *  ログ出力
+ */
+
+ER
+net_syslog (uint_t prio, const char *format, ...)
+{
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	*addr;
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+	ulong_t		val;
+	SYSLOG		log;
+	va_list		ap;
+	char		padchar, *str;
+	int_t		ch, width, left, i;
+	bool_t		longflag;
+
+	if (connected) {
+		syscall(wai_sem(SEM_NET_CONS_PRINTF));
+		va_start(ap, format);
+		while ((ch = *format ++) != '\0') {
+			if (ch != '%') {		/* 書式指定以外 */
+				cons_putchar(CONSOLE_PORTID, (char)ch);
+				continue;
+				}
+
+			width = 0;
+			longflag = false;
+			padchar = ' ';
+
+			if (ch == '-') {		/* 左詰め */
+				format ++;
+				left = -1;
+				}
+			else
+				left = 1;
+
+			if ((ch = *format ++) == '0') {	/* 上位桁の 0 */
+				padchar = '0';
+				ch = *format ++;
+				}
+
+			while ('0' <= ch && ch <= '9') {	/* 出力幅 */
+				width = width * 10 + ch - '0';
+				ch = *format ++;
+				}
+
+			while (ch == 'l') {		/* long (long) の指定 */
+				longflag = true;
+				ch = *format ++;
+				}
+
+			switch (ch) {
+			case 'd':
+				val = longflag ? (ulong_t)va_arg(ap, long_t)
+				               : (ulong_t)va_arg(ap, int_t);
+				if ((long_t)val >= 0)
+					cons_putnumber(CONSOLE_PORTID,  val, 10, radhex, width * left, false, padchar);
+				else
+					cons_putnumber(CONSOLE_PORTID, -val, 10, radhex, width * left, true, padchar);
+				break;
+
+			case 'u':
+				val = longflag ? (ulong_t)va_arg(ap, ulong_t)
+				               : (ulong_t)va_arg(ap, uint_t);
+				cons_putnumber(CONSOLE_PORTID, val, 10, radhex, width * left, false, padchar);
+				break;
+
+			case 'x':
+				val = longflag ? (ulong_t)va_arg(ap, ulong_t)
+				               : (ulong_t)va_arg(ap, uint_t);
+				cons_putnumber(CONSOLE_PORTID, val, 16, radhex, width * left, false, padchar);
+				break;
+
+			case 'X':
+				val = longflag ? (ulong_t)va_arg(ap, ulong_t)
+				               : (ulong_t)va_arg(ap, uint_t);
+				cons_putnumber(CONSOLE_PORTID, val, 16, radHEX, width * left, false, padchar);
+				break;
+
+			case 'c':
+				ch = va_arg(ap, int_t);
+				cons_putchar(CONSOLE_PORTID, (char)ch);
+				break;
+
+			case 's':
+				str = va_arg(ap, char*);
+				while ((ch = *str ++) != '\0') {
+					cons_putchar(CONSOLE_PORTID, (char)ch);
+					width --;
+					}
+				while (width -- > 0)
+					cons_putchar(CONSOLE_PORTID, ' ');
+				break;
+
+			case 'I':
+
+#if defined(SUPPORT_INET4)
+
+				addr = va_arg(ap, T_IN4_ADDR*);
+				put_ipv4addr(CONSOLE_PORTID, addr, width);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+				str = va_arg(ap, char*);
+				put_ipv6addr(CONSOLE_PORTID, (T_IN6_ADDR *)str, width);
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+				break;
+
+			case 'M':
+				str = va_arg(ap, char*);
+				put_macaddr(CONSOLE_PORTID, (uint8_t *)str, width);
+				break;
+
+			case '%':
+				cons_putchar(CONSOLE_PORTID, '%');
+				break;
+
+			case '0':
+				format --;
+				break;
+
+			default:
+				break;
+				}
+
+			}
+		va_end(ap);
+		cons_putchar(CONSOLE_PORTID, '\n');
+		flush_snd_buff();
+		syscall(sig_sem(SEM_NET_CONS_PRINTF));
+		return E_OK;
+		}
+	else {
+		log.logtype = LOG_TYPE_COMMENT;
+		log.loginfo[0] = (intptr_t)format;
+		i = 1;
+		va_start(ap, format);
+
+		while ((ch = *format++) != '\0' && i < TMAX_LOGINFO) {
+			if (ch != '%') {
+				continue;
+				}
+
+			longflag = false;
+
+			ch = *format++;
+			while ('0' <= ch && ch <= '9') {
+				ch = *format++;
+				}
+
+			while (ch == 'l') {		/* long (long) の指定 */
+				longflag = true;
+				ch = *format ++;
+				}
+
+			switch (ch) {
+			case 'd':
+				log.loginfo[i++] = longflag
+					? (intptr_t)va_arg(ap, long_t) 
+					: (intptr_t)va_arg(ap, int_t);
+				break;
+			case 'u':
+			case 'x':
+			case 'X':
+				log.loginfo[i++] = longflag
+					? (intptr_t)va_arg(ap, ulong_t)
+					: (intptr_t)va_arg(ap, uint_t);
+				break;
+			case 'p':
+				log.loginfo[i++] = (intptr_t)va_arg(ap, void *);
+				break;
+			case 'c':
+				log.loginfo[i++] = (intptr_t)va_arg(ap, int_t);
+				break;
+			case 's':
+				log.loginfo[i++] = (intptr_t)va_arg(ap, const char *);
+				break;
+			case '\0':
+				format--;
+				break;
+			default:
+				break;
+				}
+			}
+		va_end(ap);
+
+#ifdef TARGET_KERNEL_ASP
+
+		return(syslog_wri_log(prio, &log));
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+		return(vwri_log(prio, &log));
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+		}
+	}
+
+#endif	/* of #ifdef USE_NET_CONS */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/net_cons.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/net_cons.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/net_cons.cfg	(revision 398)
@@ -0,0 +1,44 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ネットワーク経由コンソール入出力
+ *  システムコンフィギュレーションファイル
+ */
+
+#ifdef USE_NET_CONS
+
+CRE_SEM(SEM_NET_CONS_PRINTF, { TA_TPRI, 1, 1 });
+CRE_SEM(SEM_NET_CONS_SEND,   { TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef USE_NET_CONS */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/net_cons.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/net_cons.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/net_cons.h	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ネットワーク経由コンソール入出力
+ */
+
+/*  TCP 送受信ウィンドバッファサイズ  */
+
+#define NET_CONS_SWBUF_SIZE	512
+#define NET_CONS_RWBUF_SIZE	512
+
+#ifndef _MACRO_ONLY
+
+/*  TCP 送受信ウィンドバッファ  */
+
+extern uint8_t net_cons_swbuf[];
+extern uint8_t net_cons_rwbuf[];
+
+/*  ノンブロッキングコールのコールバック関数  */
+
+extern ER	callback_nblk_net_cons(ID cepid, FN fncd, void *p_parblk);
+
+#endif /* _MACRO_ONLY */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp.h	(revision 398)
@@ -0,0 +1,99 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _NETAPP_H_
+#define _NETAPP_H_
+
+/*
+ *  IPv4 と IPv6 の切換えマクロ
+ */
+
+#if defined(SUPPORT_INET6)
+
+#define PUT_IPADDR(p,a,w)	put_ipv6addr(p,a,w)
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#define PUT_IPADDR(p,a,w)	put_ipv4addr(p,a,w)
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/*
+ *  コンソールに用いるシリアルポート番号
+ */
+
+#ifndef CONSOLE_PORTID
+#define	CONSOLE_PORTID		LOGTASK_PORTID
+#endif
+
+/*
+ *  コンソールに用いる LCD ポート番号
+ */
+
+#define	LCD_PORTID		0
+
+/*
+ *  数値変換のための変換表
+ */
+
+extern const char radhex[];
+extern const char radHEX[];
+
+/*
+ *  関数
+ */
+
+extern char *skip_blanks (char *line);
+extern int_t cons_getline (ID portid, char *line, int_t size);
+extern char *get_int (int_t *val, char *line);
+extern char *get_xuint (uint_t *val, char *line);
+extern void cons_putchar (ID portid, char ch);
+extern int_t cons_getchar (ID portid);
+extern int_t cons_putnumber (ID portid, ulong_t val, int_t radix,
+                           const char *radchar, int_t width,
+                           bool_t minus, char padchar);
+extern void cons_printf (ID portid, const char *fmt, ...);
+extern int_t put_macaddr (ID portid, uint8_t *mac, int_t width);
+
+#ifdef T_IN4_ADDR_DEFINED
+extern int_t put_ipv4addr (ID portid, T_IN4_ADDR *addr, int_t width);
+#endif
+#ifdef T_IN6_ADDR_DEFINED
+extern int_t put_ipv6addr (ID portid, const T_IN6_ADDR *addr, int_t width);
+#endif
+
+#endif	/* of #ifndef _NETAPP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp_subr.c	(revision 398)
@@ -0,0 +1,1229 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  ネットワーク応用プログラムサポートルーチン
+ */
+
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <syssvc/serial.h>
+#include <target_syssvc.h>
+#define LOGTASK_PORTID SIO_PORTID
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/net.h>
+#include <net/net_endian.h>
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/resolver.h>
+
+#ifdef USE_NETAPP_SUBR
+
+/*
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#if defined(SUPPORT_INET6)
+
+#ifdef USE_TCP_EXTENTIONS
+
+const ID vrid_tcp6_cep[] =
+{
+#if NUM_VRID_TCP6_CEPS >= 1
+	TCP6_RSV_CEPID1,
+#endif
+#if NUM_VRID_TCP6_CEPS >= 2
+	TCP6_RSV_CEPID2,
+#endif
+#if NUM_VRID_TCP6_CEPS >= 3
+	TCP6_RSV_CEPID3,
+#endif
+#if NUM_VRID_TCP6_CEPS >= 4
+	TCP6_RSV_CEPID4,
+#endif
+	};
+
+const ID vrid_tcp6_rep[] =
+{
+#if NUM_VRID_TCP6_REPS >= 1
+	TCP6_RSV_REPID1,
+#endif
+#if NUM_VRID_TCP6_REPS >= 2
+	TCP6_RSV_REPID2,
+#endif
+	};
+
+ID tskid_tcp6_cep[NUM_VRID_TCP6_CEPS];
+ID tskid_tcp6_rep[NUM_VRID_TCP6_REPS];
+
+#endif	/* #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_UDP_EXTENTIONS
+
+const ID vrid_udp6_cep[] =
+{
+#if NUM_VRID_UDP6_CEPS >= 1
+	UDP6_RSV_CEPID1,
+#endif
+#if NUM_VRID_UDP6_CEPS >= 2
+	UDP6_RSV_CEPID2,
+#endif
+	};
+
+ID tskid_udp6_cep[NUM_VRID_UDP6_CEPS];
+
+#endif	/* #ifdef USE_UDP_EXTENTIONS */
+
+#undef	TCP_CRE_REP
+#undef	UDP_CRE_CEP
+#undef	UDP_DEL_CEP
+#undef	TCP_IS_CEPID
+#undef  ALLOC_TCP_REP
+#undef  ALLOC_TCP_CEP
+#undef  ALLOC_UDP_CEP
+#undef  FREE_TCP_REP
+#undef  FREE_TCP_CEP
+#undef  FREE_UDP_CEP
+#undef	T_TCPN_CREP
+#undef	T_UDPN_CCEP
+#undef	NUM_VRID_TCP_CEPS
+#undef	NUM_VRID_TCP_REPS
+#undef	NUM_VRID_UDP_CEPS
+#undef	VRID_TCP_CEP
+#undef	VRID_UDP_CEP
+#undef	VRID_TCP_REP
+#undef	TSKID_TCP_CEP
+#undef	TSKID_TCP_REP
+#undef	TSKID_UDP_CEP
+#undef	API_IPPROTO
+
+#define TCP_CRE_REP		tcp6_cre_rep
+#define UDP_CRE_CEP		udp6_cre_cep
+#define UDP_DEL_CEP		udp6_del_cep
+
+#define TCP_IS_CEPID		tcp6_is_cepid
+#define ALLOC_TCP_REP		alloc_tcp6_rep
+#define ALLOC_TCP_CEP		alloc_tcp6_cep
+#define ALLOC_UDP_CEP		alloc_udp6_cep
+#define FREE_TCP_REP		free_tcp6_rep
+#define FREE_TCP_CEP		free_tcp6_cep
+#define FREE_UDP_CEP		free_udp6_cep
+#define T_TCPN_CREP		T_TCP6_CREP
+#define T_UDPN_CCEP		T_UDP6_CCEP
+#define NUM_VRID_TCP_CEPS	NUM_VRID_TCP6_CEPS
+#define NUM_VRID_TCP_REPS	NUM_VRID_TCP6_REPS
+#define NUM_VRID_UDP_CEPS	NUM_VRID_UDP6_CEPS
+#define VRID_TCP_CEP		vrid_tcp6_cep
+#define VRID_TCP_REP		vrid_tcp6_rep
+#define VRID_UDP_CEP		vrid_udp6_cep
+#define TSKID_TCP_CEP		tskid_tcp6_cep
+#define TSKID_TCP_REP		tskid_tcp6_rep
+#define TSKID_UDP_CEP		tskid_udp6_cep
+#define API_IPPROTO		API_PROTO_IPV6
+
+#include <netapp/netappn_subr.c>
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#ifdef USE_TCP_EXTENTIONS
+
+const ID vrid_tcp4_cep[] =
+{
+#if NUM_VRID_TCP4_CEPS >= 1
+	TCP4_RSV_CEPID1,
+#endif
+#if NUM_VRID_TCP4_CEPS >= 2
+	TCP4_RSV_CEPID2,
+#endif
+#if NUM_VRID_TCP4_CEPS >= 3
+	TCP4_RSV_CEPID3,
+#endif
+#if NUM_VRID_TCP4_CEPS >= 4
+	TCP4_RSV_CEPID4,
+#endif
+	};
+
+const ID vrid_tcp4_rep[] =
+{
+#if NUM_VRID_TCP4_REPS >= 1
+	TCP4_RSV_REPID1,
+#endif
+#if NUM_VRID_TCP4_REPS >= 2
+	TCP4_RSV_REPID2,
+#endif
+	};
+
+ID tskid_tcp4_cep[NUM_VRID_TCP4_CEPS];
+ID tskid_tcp4_rep[NUM_VRID_TCP4_REPS];
+
+#endif	/* #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_UDP_EXTENTIONS
+
+const ID vrid_udp4_cep[] =
+{
+#if NUM_VRID_UDP4_CEPS >= 1
+	UDP4_RSV_CEPID1,
+#endif
+#if NUM_VRID_UDP4_CEPS >= 2
+	UDP4_RSV_CEPID2,
+#endif
+	};
+
+ID tskid_udp4_cep[NUM_VRID_UDP4_CEPS];
+
+#endif	/* #ifdef USE_UDP_EXTENTIONS */
+
+#undef	TCP_CRE_REP
+#undef	UDP_CRE_CEP
+#undef	UDP_DEL_CEP
+#undef	TCP_IS_CEPID
+#undef  ALLOC_TCP_REP
+#undef  ALLOC_TCP_CEP
+#undef  ALLOC_UDP_CEP
+#undef  FREE_TCP_REP
+#undef  FREE_TCP_CEP
+#undef  FREE_UDP_CEP
+#undef	T_TCPN_CREP
+#undef	T_UDPN_CCEP
+#undef	NUM_VRID_TCP_CEPS
+#undef	NUM_VRID_TCP_REPS
+#undef	NUM_VRID_UDP_CEPS
+#undef	VRID_TCP_CEP
+#undef	VRID_TCP_REP
+#undef	VRID_UDP_CEP
+#undef	TSKID_TCP_CEP
+#undef	TSKID_TCP_REP
+#undef	TSKID_UDP_CEP
+#undef	API_IPPROTO
+
+#define TCP_CRE_REP		tcp_cre_rep
+#define UDP_CRE_CEP		udp_cre_cep
+#define UDP_DEL_CEP		udp_del_cep
+#define TCP_IS_CEPID		tcp4_is_cepid
+#define ALLOC_TCP_REP		alloc_tcp4_rep
+#define ALLOC_TCP_CEP		alloc_tcp4_cep
+#define ALLOC_UDP_CEP		alloc_udp4_cep
+#define FREE_TCP_REP		free_tcp4_rep
+#define FREE_TCP_CEP		free_tcp4_cep
+#define FREE_UDP_CEP		free_udp4_cep
+#define T_TCPN_CREP		T_TCP_CREP
+#define T_UDPN_CCEP		T_UDP_CCEP
+#define NUM_VRID_TCP_CEPS	NUM_VRID_TCP4_CEPS
+#define NUM_VRID_TCP_REPS	NUM_VRID_TCP4_REPS
+#define NUM_VRID_UDP_CEPS	NUM_VRID_UDP4_CEPS
+#define VRID_TCP_CEP		vrid_tcp4_cep
+#define VRID_TCP_REP		vrid_tcp4_rep
+#define VRID_UDP_CEP		vrid_udp4_cep
+#define TSKID_TCP_CEP		tskid_tcp4_cep
+#define TSKID_TCP_REP		tskid_tcp4_rep
+#define TSKID_UDP_CEP		tskid_udp4_cep
+#define API_IPPROTO		API_PROTO_IPV4
+
+#include <netapp/netappn_subr.c>
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#undef	TCP_CRE_REP
+#undef  ALLOC_TCPN_REP
+#undef  ALLOC_TCPN_CEP
+#undef  ALLOC_UDPN_CEP
+#undef  FREE_TCPN_REP
+#undef  FREE_TCPN_CEP
+#undef  FREE_UDPN_CEP
+#undef	T_TCPN_CREP
+#undef	NUM_VRID_TCP_REPS
+#undef	NUM_VRID_UDP_CEPS
+#undef	VRID_TCP_CEP
+#undef	VRID_TCP_REP
+#undef	VRID_UDP_CEP
+#undef	TSKID_TCP_CEP
+#undef	TSKID_TCP_REP
+#undef	TSKID_UDP_CEP
+
+/*
+ *  変数
+ */
+
+static uint32_t rand_next = ULONG_C(1);
+
+#if !defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+const T_IN6_ADDR in6_addr_unspecified =
+	IPV6_ADDR_UNSPECIFIED_INIT;
+
+#endif	/* of #if !defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  シリアルポートへの書式付文字列出力ライブラリ
+ */
+
+#define EOF		(-1)
+
+/*
+ *  数値変換のための変換表
+ */
+
+const char radhex[] = "0123456789abcdef";
+const char radHEX[] = "0123456789ABCDEF";
+
+/*
+ *  netapp_rand -- 乱数を返す。
+ */
+
+uint32_t
+netapp_rand (void)
+{
+	rand_next = (rand_next * 99991 + 12345) & ULONG_C(0x7fffffff);
+	return rand_next;
+	}
+
+/*
+ *  srand -- 乱数を初期化する。
+ */
+
+void
+netapp_srand (uint32_t seed)
+{
+	SYSTIM now;
+
+	syscall(get_tim(&now));
+	rand_next += now + seed;
+	}
+
+#ifndef USE_NET_CONS
+
+/*
+ *  cons_putchar -- シリアルポートへの文字出力
+ */
+
+void
+cons_putchar (ID portid, char ch)
+{
+	serial_wri_dat(portid, &ch, 1);
+	}
+
+/*
+ *  cons_getchar -- シリアルポートからの文字入力
+ */
+
+int_t
+cons_getchar (ID portid)
+{
+	char ch;
+
+	if (serial_rea_dat(portid, &ch, sizeof(ch)) > 0)
+		return ch;
+	else
+		return EOF;
+	}
+
+#endif	/* of #ifndef USE_NET_CONS */
+
+/*
+ *  cons_putnumber -- cons_printf の数値変換
+ */
+
+int_t
+cons_putnumber(ID portid, ulong_t 	val, int_t radix,
+         const char *radchar, int_t width, bool_t minus, char padchar)
+{
+	char	digits[24];
+	int_t	ix, pad, pchars;
+	bool_t	left;
+
+	if (width < 0) {
+		width = -width;
+		left = true;
+		}
+	else
+		left = false;
+
+	ix = 0;
+	do {
+		digits[ix ++] = radchar[val % radix];
+		val /= radix;
+		} while (val != 0);
+
+	if (minus)
+		digits[ix ++] = '-';
+
+	if (width > ix)
+		pchars = width;
+	else
+		pchars = ix;
+
+	pad = ix;
+	if (!left)	/* 右詰め */
+		for ( ; pad < width; pad ++)
+			cons_putchar(portid, padchar);
+
+	while (ix -- > 0)
+		cons_putchar(portid, digits[ix]);
+
+	if (left)	/* 左詰め */
+		for ( ; pad < width; pad ++)
+			cons_putchar(portid, padchar);
+
+	return pchars;
+	}
+
+/*
+ *  put_ipv4addr -- IPv4 アドレス出力
+ */
+
+int_t
+put_ipv4addr (ID portid, T_IN4_ADDR *addr, int_t width)
+{
+	int_t len = 3;	/* 3 は '.' の文字数 */
+
+	len += cons_putnumber(portid, (*addr >> 24) & 0xff, 10, radhex, 0, false, ' '); 
+	cons_putchar(portid, '.');
+	len += cons_putnumber(portid, (*addr >> 16) & 0xff, 10, radhex, 0, false, ' '); 
+	cons_putchar(portid, '.');
+	len += cons_putnumber(portid, (*addr >>  8) & 0xff, 10, radhex, 0, false, ' '); 
+	cons_putchar(portid, '.');
+	len += cons_putnumber(portid,  *addr        & 0xff, 10, radhex, 0, false, ' '); 
+
+	for ( ; len < width; len ++)
+		cons_putchar(portid, ' ');
+
+	return len;
+	}
+
+/*
+ *  ipv6addr -- IPv6 アドレス出力
+ */
+
+int_t
+put_ipv6addr (ID portid, const T_IN6_ADDR *addr, int_t width)
+{
+	int_t	len = 0, ix, len6;
+	bool_t	omit = false, zero = false;
+
+	if (addr == NULL || IN6_IS_ADDR_UNSPECIFIED(addr)) {
+		cons_putchar(portid, '0');
+		cons_putchar(portid, ':');
+		cons_putchar(portid, ':');
+		cons_putchar(portid, '0');
+		len = 4;
+		}
+	else {
+		if (in6_is_addr_ipv4mapped(addr))
+			len6 = sizeof(T_IN6_ADDR) / 2 - 2;
+		else
+			len6 = sizeof(T_IN6_ADDR) / 2;
+		for (ix = 0; ix < len6; ix ++) {
+			if (omit) {
+				len += cons_putnumber(portid, ntohs(addr->s6_addr16[ix]), 16, radhex, 0, false, ' '); 
+				if (ix < 7) {
+					cons_putchar(portid, ':');
+					len ++;
+					}
+				}
+			else if (ix > 0 && ix < 7 && addr->s6_addr16[ix] == 0)
+				zero = true;
+			else {
+				if (zero) {
+					omit = true;
+					cons_putchar(portid, ':');
+					len ++;
+					}
+				len += cons_putnumber(portid, ntohs(addr->s6_addr16[ix]), 16, radhex, 0, false, ' '); 
+				if (ix < 7) {
+					cons_putchar(portid, ':');
+					len ++;
+					}
+				}
+			}
+
+		if (len6 == sizeof(T_IN6_ADDR) / 2 - 2) {
+			T_IN4_ADDR ip4addr;
+
+			ip4addr = ntohl(addr->s6_addr32[3]);
+			len += put_ipv4addr(portid, &ip4addr, 0);
+			}
+
+		for ( ; len < width; len ++)
+			cons_putchar(portid, ' ');
+		}
+	return len;
+	}
+
+/*
+ *  put_macaddr -- MAC アドレス出力
+ */
+
+int_t
+put_macaddr (ID portid, uint8_t *mac, int_t width)
+{
+	int_t oct, len;
+
+	for (oct = 5; oct -- > 0; ) {
+		cons_putnumber(portid, *mac ++, 16, radhex, 2, false, '0'); 
+		cons_putchar(portid, ':');
+		}
+	cons_putnumber(portid, *mac, 16, radhex, 2, false, '0'); 
+
+	for (len = 17; len < width; len ++)
+		cons_putchar(portid, ' ');
+
+	return len;
+	}
+
+/*
+ *  cons_printf -- シリアルポートへの書式付文字列出力
+ */
+
+void
+cons_printf (ID portid, const char *fmt, ...)
+{
+	va_list	ap;
+	long_t	val;
+	char	padchar, *str;
+	int_t	ch, width, longflag, shortflag, left;
+	T_IN4_ADDR	*addr;
+
+	va_start(ap, fmt);
+	while ((ch = *fmt ++) != '\0') {
+		if (ch != '%') {		/* 書式指定以外 */
+			cons_putchar(portid, (char)ch);
+			continue;
+			}
+
+		width = longflag = shortflag = 0;
+		padchar = ' ';
+
+		if (*fmt == '-') {		/* 左詰め */
+			fmt ++;
+			left = -1;
+			}
+		else
+			left = 1;
+
+		if ((ch = *fmt ++) == '0') {	/* 上位桁の 0 */
+			padchar = '0';
+			ch = *fmt ++;
+			}
+
+		while ('0' <= ch && ch <= '9') {	/* 出力幅 */
+			width = width * 10 + ch - '0';
+			ch = *fmt ++;
+			}
+
+		while (ch == 'l') {		/* long (long) の指定 */
+			longflag ++;
+			ch = *fmt ++;
+			}
+
+		while (ch == 'h') {		/* short の指定 */
+			shortflag ++;
+			ch = *fmt ++;
+			}
+
+		switch (ch) {
+		case 'd':
+			val = longflag ? (ulong_t)va_arg(ap, long_t)
+			               : (ulong_t)va_arg(ap, int_t);
+			if (val >= 0)
+				cons_putnumber(portid,  val, 10, radhex, width * left, false, padchar);
+			else
+				cons_putnumber(portid, -val, 10, radhex, width * left, true, padchar);
+			break;
+
+		case 'u':
+			val = longflag ? (ulong_t)va_arg(ap, ulong_t)
+			               : (ulong_t)va_arg(ap, uint_t);
+			cons_putnumber(portid, val, 10, radhex, width * left, false, padchar);
+			break;
+
+		case 'x':
+			val = longflag ? (ulong_t)va_arg(ap, ulong_t)
+			               : (ulong_t)va_arg(ap, uint_t);
+			cons_putnumber(portid, val, 16, radhex, width * left, false, padchar);
+			break;
+
+		case 'X':
+			val = longflag ? (ulong_t)va_arg(ap, ulong_t)
+			               : (ulong_t)va_arg(ap, uint_t);
+			cons_putnumber(portid, val, 16, radHEX, width * left, false, padchar);
+			break;
+
+		case 'c':
+			ch = va_arg(ap, int_t);
+			cons_putchar(portid, (char)ch);
+			break;
+
+		case 's':
+			str = va_arg(ap, char*);
+			while ((ch = *str ++) != '\0') {
+				cons_putchar(portid, (char)ch);
+				width --;
+				}
+			while (width -- > 0)
+				cons_putchar(portid, ' ');
+			break;
+
+		case 'I':
+
+			if (longflag) {
+				str = va_arg(ap, char*);
+				put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
+				}
+			else if (shortflag) {
+				addr = va_arg(ap, T_IN4_ADDR *);
+				put_ipv4addr(portid, addr, width);
+				}
+			else {
+
+#if defined(SUPPORT_INET6)
+
+				str = va_arg(ap, char*);
+				put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+				addr = va_arg(ap, T_IN4_ADDR *);
+				put_ipv4addr(portid, addr, width);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+				}
+			break;
+
+		case 'M':
+			str = va_arg(ap, char*);
+			put_macaddr(portid, (uint8_t *)str, width);
+			break;
+
+		case '%':
+			cons_putchar(portid, '%');
+			break;
+
+		case '0':
+			fmt --;
+			break;
+
+		default:
+			break;
+			}
+
+		}
+	va_end(ap);
+	}
+
+/*
+ *  host2msg16 -- 16ビットの値を、バイトオーダーを調整してメッセージに書き込む。
+ */
+
+void
+host2msg16 (void *msg, uint16_t host_data)
+{
+	uint16_t	msg_data;
+
+	msg_data = htons(host_data);
+	memcpy(msg, &msg_data, sizeof(msg_data));
+	}
+
+/*
+ *  host2msg32 -- 32ビットの値を、バイトオーダーを調整してメッセージに書き込む。
+ */
+
+void
+host2msg32 (void *msg, uint32_t host_data)
+{
+	uint32_t	msg_data;
+
+	msg_data = htonl(host_data);
+	memcpy(msg, &msg_data, sizeof(msg_data));
+	}
+
+/*
+ *  msg2host16 -- 16ビットの値を、バイトオーダーを調整してメッセージから読み出す。
+ */
+
+uint16_t
+msg2host16 (void *msg)
+{
+	uint16_t	host_data;
+
+	memcpy(&host_data, msg, sizeof(host_data));
+	return htons(host_data);
+	}
+
+/*
+ *  msg2host32 -- 32ビットの値を、バイトオーダーを調整してメッセージから読み出す。
+ */
+
+uint32_t
+msg2host32 (void *msg)
+{
+	uint32_t	host_data;
+
+	memcpy(&host_data, msg, sizeof(host_data));
+	return htonl(host_data);
+	}
+
+/*
+ *  skip_blanks -- 空白と TAB をスキップする。
+ */
+
+char *
+skip_blanks (char *line)
+{
+	while (*line == ' ' || *line == '\t')
+		line ++;
+	return line;
+	}
+
+/*
+ *  get_ipv4addr -- 文字列の IPv4 アドレスを T_IN4_ADDR 値に変換する。
+ */
+
+char *
+get_ipv4addr (T_IN4_ADDR *addr, char *line)
+{
+	int_t oct;
+
+	*addr = IPV4_ADDRANY;
+	while ('0' <= *line && *line <= '9') {
+		oct = 0;
+		while ('0' <= *line && *line <= '9')
+			oct = oct * 10 + (*line ++) - '0';
+		*addr = (*addr << 8) | (oct & 0xff);
+		if (*line == '.')
+			line ++;
+		}
+#if 1
+	return *addr == IPV4_ADDRANY ? NULL : line;
+#else
+	return line;
+#endif
+	}
+
+#if defined(SUPPORT_INET6) || defined(USE_RESOLVER)
+
+/*
+ *  get_ipv6addr -- 文字列の IPv6 アドレスを T_IN6_ADDR 値に変換する。
+ */
+
+char *
+get_ipv6addr (T_IN6_ADDR *addr, char *line)
+{
+	int_t word, ix = 0, omit = 0, six;
+	char *ipv4line;
+
+	memset(addr, 0, sizeof(T_IN6_ADDR));
+
+	/*
+	 * IPv4 アドレス（数字.）を検出したら IPv4 アドレスとして入力し、
+	 * IPv4 射影アドレスに変換する。
+	 */
+	for (ipv4line = line; '0' <= *ipv4line && *ipv4line <= '9'; ipv4line ++)
+		;
+	if (*ipv4line == '.') {
+		T_IN4_ADDR ipv4addr;
+
+		line = get_ipv4addr(&ipv4addr, line);
+		in6_make_ipv4mapped (addr, ipv4addr);
+		}
+	else {
+		while (ix < 8 &&
+		       (('0' <= *line && *line <= '9') ||
+		        ('a' <= *line && *line <= 'f') ||
+		        ('A' <= *line && *line <= 'F'))) {
+			word = 0;
+			while (('0' <= *line && *line <= '9') ||
+ 		               ('a' <= *line && *line <= 'f') ||
+		               ('A' <= *line && *line <= 'F')) {
+				if      ('0' <= *line && *line <= '9')
+					word = (word << 4) + (*line ++) - '0';
+				else if ('a' <= *line && *line <= 'f')
+					word = (word << 4) + (*line ++) - 'a' + 10;
+				else if ('A' <= *line && *line <= 'F')
+					word = (word << 4) + (*line ++) - 'A' + 10;
+				}
+			addr->s6_addr16[ix ++] = htons(word);
+			if (*line == ':') {
+				line ++;
+				if (*line == ':') {
+					omit = ix;
+					line ++;
+					}
+				}
+			}
+		if (omit > 0) {
+			six = 7;
+			while (ix > omit) {
+				addr->s6_addr16[six --] = addr->s6_addr16[-- ix];
+				addr->s6_addr16[ ix   ] = 0;
+				}
+			}
+		}
+	return line;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) || defined(USE_RESOLVER) */
+
+/*
+ *  デバッグ行入力
+ */
+
+int_t
+cons_getline (ID portid, char *line, int_t size)
+{
+	int_t	ch, len;
+
+	len = size;
+	while (size > 0) {
+		if ((ch = cons_getchar(portid)) != EOF) {
+			if (ch == '\r') {
+				cons_putchar(portid, '\n');
+				break;
+				}
+			else if (ch == '\b') {
+				if (size < len) {
+					line --;
+					size ++;
+					}
+				}
+			else {
+				*line ++ = ch;
+				size --;
+				}
+			}
+		}
+	*line = '\0';
+	return len - size;
+	}
+
+/*
+ *  get_int -- 整数変換
+ */
+
+char *
+get_int (int_t *val, char *line)
+{
+	int_t sign = 1;
+
+	line = skip_blanks(line);
+	if (*line == '-') {
+		sign = -1;
+		line ++;
+		}
+	else if (*line == '+')
+		line ++;
+
+	line = skip_blanks(line);
+	*val = 0;
+	while ('0' <= *line && *line <= '9') {
+		*val = *val * 10 + *line - '0';
+		line ++;
+		}
+
+	*val = *val * sign;
+	return line;
+	}
+
+/*
+ *  get_xuint -- 符号なし整数 (16進) 変換
+ */
+
+char *
+get_xuint (uint_t *val, char *line)
+{
+	line = skip_blanks(line);
+	*val = 0;
+	while (1) {
+		if      ('0' <= *line && *line <= '9')
+			*val = (*val << 4) + *line - '0';
+		else if ('a' <= *line && *line <= 'f')
+			*val = (*val << 4) + *line - 'a' + 10;
+		else if ('A' <= *line && *line <= 'F')
+			*val = (*val << 4) + *line - 'A' + 10;
+		else
+			break;
+		line ++;
+		}
+	return line;
+	}
+
+#ifdef USE_RESOLVER
+
+/*
+ *  dns_strtype -- DNS の type の文字列を返す。
+ */
+
+const char *
+dns_strtype (uint_t type)
+{
+	switch (type) {
+	case DNS_TYPE_A:
+		return "A";
+		break;
+	case DNS_TYPE_NS:
+		return "NS";
+		break;
+	case DNS_TYPE_CNAME:
+		return "CNAME";
+		break;
+	case DNS_TYPE_SOA:
+		return "SOA";
+		break;
+	case DNS_TYPE_PTR:
+		return "PTR";
+		break;
+	case DNS_TYPE_AAAA:
+		return "AAAA";
+		break;
+	default:
+		return "unknown type";
+		break;
+		}
+	}
+
+/*
+ *  dns_strclass -- DNS の class を表示する。
+ */
+
+const char *
+dns_strclass (uint_t class)
+{
+	switch (class) {
+	case DNS_CLASS_IN:
+		return "IN";
+		break;
+	default:
+		return "unknown class";
+		break;
+		}
+	}
+
+/*
+ *  resolv_hoststr -- 文字列のFQDN・ホスト名・IPv6/IPv4 アドレスを解析する。
+ */
+
+#define IS_HOSTCH_DIGIT(c)	(('0'<=(c)&&(c)<='9'))
+#define IS_HOSTCH_XDIGIT(c)	(IS_HOSTCH_DIGIT(c)||('a'<=(c)&&(c)<='f')||('A'<=(c)&&(c)<='F'))
+#define IS_HOSTCH_ALPHA(c)	(('a'<=(c)&&(c)<='z')||('A'<=(c)&&(c)<='z'))
+#define IS_HOSTCH_ALNUM(c)	(IS_HOSTCH_ALPHA(c)||IS_HOSTCH_DIGIT(c))
+#define IS_HOSTCH_IPV6ADDR(c)	(IS_HOSTCH_XDIGIT(c)||(c)==':')
+#define IS_HOSTCH_IPV4ADDR(c)	(IS_HOSTCH_DIGIT(c)||(c)=='.')
+#define IS_HOSTCH_IPADDR(c)	(IS_HOSTCH_XDIGIT(c)||(c)==':'||(c)=='.')
+#define IS_HOSTCH_NAME_FIRST(c)	(IS_HOSTCH_ALPHA(c))
+#define IS_HOSTCH_NAME(c)	(IS_HOSTCH_ALNUM(c)||(c)=='-'||(c)=='.')
+#define IS_HOSTCH_BLANK(c)	((c)=='\0'||(c)==' '||(c)=='\t')
+
+char *
+resolv_hoststr (uint_t *flags, char *hostname, uint_t name_size, char *line)
+{
+	char *h, *p;
+
+	h = hostname;
+	p = line = skip_blanks(line);
+
+	if (IS_HOSTCH_IPADDR(*p)) {
+		while (IS_HOSTCH_DIGIT(*p)) {
+			if (h - hostname > name_size)
+				return NULL;
+			*h ++ = *p ++;
+			}
+		if (p > line && *p == '.') {
+			while (IS_HOSTCH_IPV4ADDR(*p)) {
+				if (h - hostname > name_size)
+					return NULL;
+				*h ++ = *p ++;
+				}
+			if (IS_HOSTCH_BLANK(*p)) {
+				*flags |= HOSTSTR_IPV4;
+				*h = '\0';
+				return p;
+				}
+			}
+		else if (IS_HOSTCH_IPADDR(*p)) {
+			while (IS_HOSTCH_IPADDR(*p)) {
+				if (h - hostname > name_size)
+					return NULL;
+				*h ++ = *p ++;
+				}
+			if (IS_HOSTCH_BLANK(*p)) {
+				*flags |= HOSTSTR_IPV6;
+				*h = '\0';
+				return p;
+				}
+			}
+		h = hostname;
+		p = line;
+		}
+
+	if (IS_HOSTCH_NAME_FIRST(*p)) {
+		*flags |= HOSTSTR_HOSTNAME;
+		while (IS_HOSTCH_NAME(*p)) {
+			if (h - hostname > name_size)
+				return NULL;
+			if (*p == '.')
+				*flags |= HOSTSTR_FQDN;
+			*h ++ = *p ++;
+			}
+		}
+	else
+		*flags |= HOSTSTR_OTHER;
+
+	*h = '\0';
+	return p;
+	}
+
+/*
+ *  show_dns_domain_name -- DNS のドメイン名を表示する。
+ */
+
+uint_t
+show_dns_domain_name (ID portid, uint8_t *hdr, uint_t offset)
+{
+	uint8_t	*ptr;
+	uint_t	c;
+
+	ptr = hdr + offset;
+	while (*ptr) {
+		if ((*ptr & DNS_MSG_COMP_MARK) == DNS_MSG_COMP_MARK) {
+			show_dns_domain_name(portid, hdr, (*ptr & ~DNS_MSG_COMP_MARK) << 8 | *(ptr + 1));
+			ptr += 2;
+			break;
+			}
+		else {
+			for (c = 1; c <= *ptr; c++)
+				cons_printf(portid, "%c", *(ptr + c));
+			ptr += *ptr + 1;
+			if (*ptr)
+				cons_printf(portid, ".");
+			}
+		}
+	return ptr - hdr;
+	}
+
+/*
+ *  resolv_options -- アドレス解決のオプション解析
+ */
+
+char *
+resolv_options (uint_t *flags, char *line, char apip)
+{
+#if defined(SUPPORT_INET6)
+	T_IN6_ADDR	in6_addr;
+#endif
+
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	in4_addr;
+#endif
+
+	line = skip_blanks(line);
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+	*flags |= DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4;
+	if (apip == API_PROTO_IPV4)
+		*flags |= DNS_LUP_FLAGS_QTYPE_A;
+	else
+		*flags |= DNS_LUP_FLAGS_QTYPE_AAAA;
+
+	if (*line == '-') {
+		line ++;
+		if (*line == '6') {
+			line ++;
+			*flags &= ~DNS_LUP_FLAGS_PROTO_IPV4;
+			}
+		else if (*line == '4') {
+			line ++;
+			*flags &= ~DNS_LUP_FLAGS_PROTO_IPV6;
+			}
+		if (*line == 'Q' || *line == 'q') {
+			*flags &= ~DNS_LUP_FLAGS_QTYPE_A;
+			line ++;                   
+			}
+		else if (*line == 'A' || *line == 'a') {
+			*flags &= ~DNS_LUP_FLAGS_QTYPE_AAAA;
+			line ++;                   
+			}
+		while (*line && !(*line == ' ' || *line == '\t'))
+			line ++;
+		}
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+	*flags = DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_QTYPE_AAAA;
+	if (*line == '-') {
+		line ++;
+		while (*line && !(*line == ' ' || *line == '\t'))
+			line ++;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+	*flags = DNS_LUP_FLAGS_PROTO_IPV4 | DNS_LUP_FLAGS_QTYPE_A;
+	if (*line == '-') {
+		line ++;
+		while (*line && !(*line == ' ' || *line == '\t'))
+			line ++;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET6)
+
+	if (*flags | DNS_LUP_FLAGS_PROTO_IPV6) {
+		/*
+		 *  IPv6 で DNS サーバに照会することが指定されても、
+		 *  サーバの IPv6 アドレスが未定義の時は、指定を外す。
+		 */
+		dns_in6_get_addr(&in6_addr);
+		if (IN6_IS_ADDR_UNSPECIFIED(&in6_addr))
+			*flags &= ~DNS_LUP_FLAGS_PROTO_IPV6;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+	if (*flags | DNS_LUP_FLAGS_PROTO_IPV4) {
+		/*
+		 *  IPv4 で DNS サーバに照会することが指定されても、
+		 *  サーバの IPv4 アドレスが未定義の時は、指定を外す。
+		 */
+		dns_in4_get_addr(&in4_addr);
+		if (in4_addr == IPV4_ADDRANY)
+			*flags &= ~DNS_LUP_FLAGS_PROTO_IPV4;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+	return line;
+	}
+
+#endif	/* of #ifdef USE_RESOLVER */
+
+/*
+ *  lookup_ipaddr -- ホスト名・リテラルのIPアドレスをIP アドレスに変換する。
+ */
+
+char *
+lookup_ipaddr (T_IN_ADDR *addr, char *line, char apip)
+{
+
+#ifdef USE_RESOLVER
+
+	static char hostname[DBG_LINE_SIZE + 1];
+
+	ER_UINT	error;
+	uint_t	flags = 0;
+	char	*last;
+
+	line = skip_blanks(resolv_options(&flags, line, apip));
+	if ((last = resolv_hoststr(&flags, hostname, sizeof(hostname), line)) == NULL) {
+		cons_printf(CONSOLE_PORTID, "unknown host: %s.\n", hostname);
+		return NULL;
+		}
+
+	switch (flags & DNS_LUP_FLAGS_NAME_MASK) {
+	case DNS_LUP_FLAGS_NAME_IPV4:
+	case DNS_LUP_FLAGS_NAME_IPV6:
+		line = GET_IPADDR(addr, line);		/* IP Address by Literal */
+		break;
+
+	case DNS_LUP_FLAGS_NAME_HOST:
+	case DNS_LUP_FLAGS_NAME_FQDN:
+		line = last;
+		if ((flags & (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) == 0) {
+			cons_printf(CONSOLE_PORTID, "DNS server not available.\n");
+			return NULL;
+			}
+
+		flags |= DNS_LUP_OPCODE_FORWARD;
+		if ((error = dns_host_addr(flags, hostname, addr)) != E_OK) {
+			cons_printf(CONSOLE_PORTID, "error: %s.\n", itron_strerror(error));
+			return NULL;
+			}
+		break;
+
+		}
+
+	return line;
+
+#else	/* of #ifdef USE_RESOLVER */
+
+	return GET_IPADDR(addr, skip_blanks(line));		/* IP Address by Literal */
+
+#endif	 /* of #ifdef USE_RESOLVER */
+
+	}
+
+#endif	/* of #ifdef USE_NETAPP_SUBR */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp_subr.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp_subr.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp_subr.cfg	(revision 398)
@@ -0,0 +1,50 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  サンプルアプリケーション共通
+ *  コンフィギュレーションファイル
+ */
+
+#ifdef USE_TCP_EXTENTIONS
+
+CRE_SEM(SEM_ALLOC_TCP_REP_LOCK,	{ TA_TPRI, 1, 1 });
+CRE_SEM(SEM_ALLOC_TCP_CEP_LOCK,	{ TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_UDP_EXTENTIONS
+
+CRE_SEM(SEM_ALLOC_UDP_CEP_LOCK,	{ TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netapp_var.h	(revision 398)
@@ -0,0 +1,267 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _NETAPP_VAR_H_
+#define _NETAPP_VAR_H_
+
+/*
+ *  TOPPERS/JSP カーネル、システム時刻 (SYSTIM) の周波数
+ */
+
+#define SYSTIM_HZ		ULONG_C(1000000)	/* [us]					*/
+
+/*
+ *  IPv6/IPv4 に関する定義
+ */
+
+/*
+ *  指定されたマクロに対するサンプルアプリケーション内部のマクロの定義
+ *
+ *    SUPPORT_INET6		 .   .  ON  ON  ON  ON
+ *    SUPPORT_INET4		ON  ON   .   .  ON  ON
+ *    API_CFG_IP4MAPPED_ADDR	 .  ON   .  ON   .  ON
+ *    ----------------------    ----------------------
+ *    NETAPP_IP6_CFG             .   .  ON  ON  ON  ON
+ *    NETAPP_IP4_CFG            ON  ON   .  ON  ON  ON
+ *    
+ */
+
+#if defined(SUPPORT_INET6)
+
+#define	NETAPP_IP6_CFG
+
+#endif	/* #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4) || (defined(SUPPORT_INET6) && defined(API_CFG_IP4MAPPED_ADDR))
+#define NETAPP_IP4_CFG
+#endif
+
+/*
+ *  IPv4 と IPv6 をコンパイル時に選択するためのマクロ
+ */
+
+#define DBG_LINE_SIZE		63
+
+#if defined(SUPPORT_INET6)
+
+#define T_IN_ADDR		T_IN6_ADDR
+#define T_IPEP			T_IPV6EP
+#define IP_ADDRANY		IPV6_ADDRANY
+#define T_TCPN_CREP		T_TCP6_CREP
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#define T_IN_ADDR		T_IN4_ADDR
+#define T_IPEP			T_IPV4EP
+#define IP_ADDRANY		IPV4_ADDRANY
+#define T_TCPN_CREP		T_TCP_CREP
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/*
+ *  API IPプロトコルの指定
+ */
+
+#if defined(SUPPORT_INET6)
+#define DEFAULT_API_PROTO	API_PROTO_IPV6
+#else
+#define DEFAULT_API_PROTO	API_PROTO_IPV4
+#endif
+
+/*
+ *  resolv_hoststr が返す flags の値の定義
+ *
+ *    注意:
+ *
+ *      dns.h で定義されている DNS_OPCODE、
+ *      resolver.h で定義されている DNS_LUP_FLAGS と重ならない事。
+ */
+
+#define HOSTSTR_OTHER		0x0000U
+#define HOSTSTR_IPV4		DNS_LUP_FLAGS_NAME_IPV4
+#define HOSTSTR_IPV6		DNS_LUP_FLAGS_NAME_IPV6
+#define HOSTSTR_HOSTNAME	DNS_LUP_FLAGS_NAME_HOST
+#define HOSTSTR_FQDN		DNS_LUP_FLAGS_NAME_FQDN
+
+/*
+ *  定数の定義
+ */
+
+#define DBG_LINE_SIZE		63
+
+#if defined(SUPPORT_INET6)
+
+#define NUM_VRID_TCP_CEPS	NUM_VRID_TCP6_CEPS
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#define NUM_VRID_TCP_CEPS	NUM_VRID_TCP4_CEPS
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+/* メッセージからの読出し */
+
+#define MSG2HOST16(p)		(msg2host16((void*)&(p)))
+#define MSG2HOST32(p)		(msg2host32((void*)&(p)))
+
+/* メッセージへの書込み */
+
+#define HOST2MSG16(p,v)		(host2msg16((void*)&(p),(v)))
+#define HOST2MSG32(p,v)		(host2msg32((void*)&(p),(v)))
+
+/*
+ *  ネットワーク経由コンソール入出力
+ */
+
+#ifdef USE_NET_CONS
+
+/* リネーム */
+
+#define syslog		net_syslog
+#define serial_ctl_por	net_serial_ctl_por
+
+/* 関数シミュレーションマクロ */
+
+#define FLUSH_SND_BUFF()	flush_snd_buff()
+#define WAI_NET_CONS_PRINTF()	syscall(wai_sem(SEM_NET_CONS_PRINTF))
+#define SIG_NET_CONS_PRINTF()	sig_sem(SEM_NET_CONS_PRINTF)
+
+#else	/* of #ifdef USE_NET_CONS */
+
+/* 関数シミュレーションマクロ */
+
+#define FLUSH_SND_BUFF()
+#define WAI_NET_CONS_PRINTF()
+#define SIG_NET_CONS_PRINTF()
+
+#endif	/* of #ifdef USE_NET_CONS */
+
+/*
+ *  関数
+ */
+
+extern const char *in_strtfn (FN fncd);
+extern const char *itron_strerror (ER ercd);
+extern const char *dns_strtype (uint_t type);
+extern const char *dns_strclass (uint_t class);
+extern ER	net_syslog(uint_t prio, const char *format, ...) throw();
+extern ER	net_serial_ctl_por(ID portid, uint_t ioctl) throw();
+extern void	flush_snd_buff (void);
+extern ER	discon_net_cons (void);
+extern void	wup_net_cons (void);
+extern bool_t	tcp6_is_cepid (ID cepid);
+extern ER	alloc_tcp6_rep (ID *repid, ID tskid, T_TCP6_CREP *crep);
+extern ER	alloc_tcp6_cep (ID *cepid, ID tskid, T_TCP_CCEP *ccep);
+extern ER	alloc_udp6_cep (ID *cepid, ID tskid, T_UDP6_CCEP *ccep);
+extern ER	free_tcp6_rep (ID repid, bool_t call_tcp_del_rep);
+extern ER	free_tcp6_cep (ID cepid);
+extern ER	free_udp6_cep (ID cepid, bool_t call_udp_del_cep);
+extern bool_t	tcp4_is_cepid (ID cepid);
+extern ER	alloc_tcp4_rep (ID *repid, ID tskid, T_TCP_CREP *crep);
+extern ER	alloc_tcp4_cep (ID *cepid, ID tskid, T_TCP_CCEP *ccep);
+extern ER	alloc_udp4_cep (ID *cepid, ID tskid, T_UDP_CCEP *ccep);
+extern ER	free_tcp4_rep (ID repid, bool_t call_tcp_del_rep);
+extern ER	free_tcp4_cep (ID cepid);
+extern ER	free_udp4_cep (ID cepid, bool_t call_udp_del_cep);
+extern void	ping6 (T_IN6_ADDR *addr, uint_t tmo, uint_t len);
+extern void	ping4 (T_IN4_ADDR *addr, uint_t tmo, uint_t len);
+extern char	*get_ipv6addr (T_IN6_ADDR *addr, char *line);
+extern char	*get_ipv4addr (T_IN4_ADDR *addr, char *line);
+extern char	*resolv_options (uint_t *flags, char *line, char apip);
+extern char	*resolv_hoststr (uint_t *flags, char *hostname, uint_t name_size, char *line);
+extern char	*lookup_ipaddr (T_IN_ADDR *addr, char *line, char apip);
+extern uint_t	show_dns_domain_name (ID portid, uint8_t *hdr, uint_t offset);
+extern void	host2msg16 (void *msg, uint16_t host_data);
+extern void	host2msg32 (void *msg, uint32_t host_data);
+extern uint16_t	msg2host16 (void *msg);
+extern uint32_t	msg2host32 (void *msg);
+extern uint32_t	netapp_rand (void);
+extern void	netapp_srand (uint32_t seed);
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_CRE_REP(i,r)	tcp6_cre_rep(i,r)
+#define TCP_CRE_CEP(i,c)	tcp6_cre_cep(i,c)
+#define UDP_CRE_CEP(i,c)	udp6_cre_cep(i,c)
+#define TCP_ACP_CEP(c,r,d,t)	tcp6_acp_cep(c,r,d,t)
+#define TCP_CON_CEP(c,m,d,t)	tcp6_con_cep(c,m,d,t)
+
+#define UDP_SND_DAT(c,d,b,l,t)	udp6_snd_dat(c,d,b,l,t)
+#define UDP_RCV_DAT(c,d,b,l,t)	udp6_rcv_dat(c,d,b,l,t)
+
+#define TCP_IS_CEPID(i)		tcp6_is_cepid(i)
+#define ALLOC_TCP_REP(i,t,r)	alloc_tcp6_rep(i,t,r)
+#define ALLOC_TCP_CEP(i,t,c)	alloc_tcp6_cep(i,t,c)
+#define ALLOC_UDP_CEP(i,t,c)	alloc_udp6_cep(i,t,c)
+#define FREE_TCP_REP(i,r)	free_tcp6_rep(i,r)
+#define FREE_TCP_CEP(i)		free_tcp6_cep(i)
+#define FREE_UDP_CEP(i,c)	free_udp6_cep(i,c)
+
+#define IP2STR(s,a)		ipv62str(s,a)
+#define GET_IPADDR(a,l)		get_ipv6addr(a,l)
+#define PING(a,t,l)		ping6(a,t,l)
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#define TCP_CRE_REP(i,r)	tcp_cre_rep(i,r)
+#define TCP_CRE_CEP(i,c)	tcp_cre_cep(i,c)
+#define UDP_CRE_CEP(i,c)	udp_cre_cep(i,c)
+#define TCP_ACP_CEP(c,r,d,t)	tcp_acp_cep(c,r,d,t)
+#define TCP_CON_CEP(c,m,d,t)	tcp_con_cep(c,m,d,t)
+
+#define UDP_SND_DAT(c,d,b,l,t)	udp_snd_dat(c,d,b,l,t)
+#define UDP_RCV_DAT(c,d,b,l,t)	udp_rcv_dat(c,d,b,l,t)
+
+#define TCP_IS_CEPID(i)		tcp4_is_cepid(i)
+#define ALLOC_TCP_REP(i,t,r)	alloc_tcp4_rep(i,t,r)
+#define ALLOC_TCP_CEP(i,t,c)	alloc_tcp4_cep(i,t,c)
+#define ALLOC_UDP_CEP(i,t,c)	alloc_udp4_cep(i,t,c)
+#define FREE_TCP_REP(i,r)	free_tcp4_rep(i,r)
+#define FREE_TCP_CEP(i)		free_tcp4_cep(i)
+#define FREE_UDP_CEP(i,c)	free_udp4_cep(i,c)
+
+#define IP2STR(s,a)		ip2str(s,a)
+#define GET_IPADDR(a,l)		get_ipv4addr(a,l)
+#define PING(a,t,l)		ping4(a,t,l)
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #ifndef _NETAPP_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netappn_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netappn_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/netappn_subr.c	(revision 398)
@@ -0,0 +1,207 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  ネットワーク応用プログラムサポートルーチン
+ */
+
+#ifdef USE_TCP_EXTENTIONS
+
+/*
+ *  alloc_tcp_rep -- TCP 受付口を獲得する。
+ */
+
+ER
+ALLOC_TCP_REP (ID *repid, ID tskid, T_TCPN_CREP *crep)
+{
+	int_t	ix;
+
+	*repid = TCP_REP_NONE;
+	syscall(wai_sem(SEM_ALLOC_TCP_REP_LOCK));
+	for (ix = NUM_VRID_TCP_REPS; ix -- > 0; ) {
+		if (TSKID_TCP_REP[ix] == TSK_NONE) {
+			*repid = VRID_TCP_REP[ix];
+			TSKID_TCP_REP[ix] = tskid;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_TCP_REP_LOCK));
+
+	if (*repid == TCP_REP_NONE)
+		return E_NOEXS;
+	else
+		return TCP_CRE_REP(*repid, crep);
+	}
+
+/*
+ *  free_tcp_rep -- TCP 受付口を解放する。
+ */
+
+ER
+FREE_TCP_REP (ID repid, bool_t call_tcp_del_rep)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_ALLOC_TCP_REP_LOCK));
+	for (ix = NUM_VRID_TCP_REPS; ix -- > 0; ) {
+		if (repid == VRID_TCP_REP[ix]) {
+			TSKID_TCP_REP[ix] = TSK_NONE;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_TCP_REP_LOCK));
+
+	if (call_tcp_del_rep)
+		return tcp_del_rep(repid);
+	else
+		return E_OK;
+	}
+
+/*
+ *  tcpn_is_cepid -- TCP 通信端点が指定されたネットワーク層なら true を返す。
+ */
+
+bool_t
+TCP_IS_CEPID (ID cepid)
+{
+	int_t	ix;
+
+	for (ix = NUM_VRID_TCP_CEPS; ix -- > 0; ) {
+		if (cepid == VRID_TCP_CEP[ix])
+			return true;
+		}
+	return false;
+	}
+
+/*
+ *  alloc_tcp_cep -- TCP 通信端点を獲得する。
+ */
+
+ER
+ALLOC_TCP_CEP (ID *cepid, ID tskid, T_TCP_CCEP *ccep)
+{
+	int_t	ix;
+
+	*cepid = TCP_CEP_NONE;
+	syscall(wai_sem(SEM_ALLOC_TCP_CEP_LOCK));
+	for (ix = NUM_VRID_TCP_CEPS; ix -- > 0; ) {
+		if (TSKID_TCP_CEP[ix] == TSK_NONE) {
+			*cepid = VRID_TCP_CEP[ix];
+			TSKID_TCP_CEP[ix] = tskid;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_TCP_CEP_LOCK));
+
+	if (*cepid == TCP_CEP_NONE)
+		return E_NOEXS;
+	else
+		return tcp_cre_cep(*cepid, ccep);
+	}
+
+/*
+ *  free_tcp_cep -- TCP 通信端点を解放する。
+ */
+
+ER
+FREE_TCP_CEP (ID cepid)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_ALLOC_TCP_CEP_LOCK));
+	for (ix = NUM_VRID_TCP_CEPS; ix -- > 0; ) {
+		if (cepid == VRID_TCP_CEP[ix]) {
+			TSKID_TCP_CEP[ix] = TSK_NONE;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_TCP_CEP_LOCK));
+
+	return tcp_del_cep(cepid);
+	}
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_UDP_EXTENTIONS
+
+/*
+ *  alloc_udp_cep -- UDP 通信端点を獲得する。
+ */
+
+ER
+ALLOC_UDP_CEP (ID *cepid, ID tskid, T_UDPN_CCEP *ccep)
+{
+	int_t	ix;
+
+	*cepid = UDP_CEP_NONE;
+	syscall(wai_sem(SEM_ALLOC_UDP_CEP_LOCK));
+	for (ix = NUM_VRID_UDP_CEPS; ix -- > 0; ) {
+		if (TSKID_UDP_CEP[ix] == TSK_NONE) {
+			*cepid = VRID_UDP_CEP[ix];
+			TSKID_UDP_CEP[ix] = tskid;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_UDP_CEP_LOCK));
+
+	if (*cepid == UDP_CEP_NONE)
+		return E_NOEXS;
+	else
+		return UDP_CRE_CEP(*cepid, ccep);
+	}
+
+/*
+ *  free_udp_cep -- UDP 通信端点を解放する。
+ */
+
+ER
+FREE_UDP_CEP (ID cepid, bool_t call_udp_del_cep)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_ALLOC_UDP_CEP_LOCK));
+	for (ix = NUM_VRID_UDP_CEPS; ix -- > 0; ) {
+		if (cepid == VRID_UDP_CEP[ix]) {
+			TSKID_UDP_CEP[ix] = TSK_NONE;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_UDP_CEP_LOCK));
+
+	if (call_udp_del_cep)
+		return UDP_DEL_CEP(cepid);
+	else
+		return E_OK;
+	}
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/ping.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/ping.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/ping.c	(revision 398)
@@ -0,0 +1,172 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  ping -- ICMP ECHO メッセージを送信する。
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/ppp_var.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/icmp_var.h>
+
+#ifdef USE_PING
+
+#if defined(SUPPORT_INET4)
+
+/*
+ *  変数
+ */
+
+#if 0
+static uint16_t	curr_icmp_id;
+static uint16_t	curr_icmp_len;
+#endif
+
+static uint16_t	icmp_id = 0;
+static SYSTIM	icmp_start_time;
+
+/*
+ *  icmp_reply_timeout -- ICMP REPLY タイムアウト処理
+ */
+
+static void
+icmp_reply_timeout (void *arg)
+{
+	syslog(LOG_NOTICE, "[PING4] request timeout.");
+	}
+
+/*
+ *  icmp_echo_reply -- ICMP ECHO REPLY メッセージを処理する。
+ */
+
+void
+icmp_echo_reply (T_NET_BUF *input, uint_t ihoff)
+{
+	SYSTIM		time;
+	T_IN4_ADDR	addr;
+
+	syscall(get_tim(&time));
+	addr = ntohl(GET_IP4_HDR(input)->src);
+	untimeout(icmp_reply_timeout, NULL);
+	syslog(LOG_NOTICE, "[PING4] reply: %5ld [ms] from: %s",
+	                   (time - icmp_start_time) * 1000 / SYSTIM_HZ,
+	                   ip2str(NULL, &addr));
+	}
+
+/*
+ *  ping4 -- ICMP ECHO メッセージを送信する。
+ */
+
+void
+ping4 (T_IN4_ADDR *addr, uint_t tmo, uint_t len)
+{
+	T_ICMP4_HDR	*icmp4h;
+	T_NET_BUF	*output;
+	uint8_t		*sdu;
+	int_t		ix;
+
+	/* 送信用の IP データグラムを獲得する。*/
+	if (in4_get_datagram(&output, ICMP4_HDR_SIZE + len, 0,
+	                     addr, NULL, IPPROTO_ICMP,
+	                     IP4_DEFTTL, NBA_SEARCH_ASCENT, TMO_FEVR) != E_OK)
+		return;
+
+	/* ICMP ヘッダを設定する。*/
+	icmp4h			= GET_ICMP4_HDR(output, IF_IP4_ICMP4_HDR_OFFSET);
+	icmp4h->type		= ICMP4_ECHO_REQUEST;
+	icmp4h->code		= 0;
+	icmp4h->data.id_seq.id	= htons(icmp_id);
+	icmp4h->data.id_seq.seq	= 0;
+
+	/* データを設定する。*/
+	sdu = GET_ICMP4_SDU(output, IF_IP4_ICMP4_HDR_OFFSET) + len;
+	for (ix = len; ix -- > 0; )
+		*-- sdu = ('0' + icmp_id + ix) & 0xff;
+
+	/* チェックサムを計算する。*/
+	icmp4h->sum = 0;
+	icmp4h->sum = in_cksum(icmp4h, ICMP4_HDR_SIZE + len);
+
+	/* 応答チェック用の変数を設定する。*/
+#if 0
+	curr_icmp_id  = icmp_id ++;
+	curr_icmp_len = len;
+#endif
+
+	NET_COUNT_MIB(icmp_stats.icmpOutMsgs, 1);
+	NET_COUNT_MIB(icmp_stats.icmpOutEchos, 1);
+
+	/* 送信後、現在の時間を記憶し、タイムアウトを設定する。*/
+	ip_output(output, TMO_FEVR);
+
+	syscall(get_tim(&icmp_start_time));
+	timeout(icmp_reply_timeout, NULL, tmo * NET_TIMER_HZ);
+
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #ifdef USE_PING */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/ping6.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/ping6.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/ping6.c	(revision 398)
@@ -0,0 +1,197 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  ping6 -- ICMPv6 ECHO メッセージを送信する。
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/ppp_var.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+
+#include <netinet6/nd6.h>
+
+#include <net/if_var.h>
+
+#ifdef USE_PING
+
+#if defined(SUPPORT_INET6)
+
+/*
+ *  変数
+ */
+
+#if 0
+static uint16_t	curr_icmp6_id;
+static uint16_t	curr_icmp6_size;
+#endif
+
+static uint16_t	send_icmp6_id = 0;
+static uint16_t	reply_count;
+static SYSTIM	icmp6_start_time;
+
+/*
+ *  icmp6_reply_timeout -- ICMP6 REPLY タイムアウト処理
+ */
+
+static void
+icmp6_reply_timeout (void *arg)
+{
+	if (reply_count == 0)
+		syslog(LOG_NOTICE, "[PING6] request timeout.");
+	}
+
+/*
+ *  icmp6_echo_reply -- ICMP6 ECHO REPLY メッセージを処理する。
+ */
+
+void
+icmp6_echo_reply (T_NET_BUF *input, uint_t ihoff)
+{
+	SYSTIM	time;
+
+	syscall(get_tim(&time));
+	untimeout(icmp6_reply_timeout, NULL);
+	syslog(LOG_NOTICE, "[PING6] reply: %5ld [ms] from: %s",
+	                   (time - icmp6_start_time) * 1000 / SYSTIM_HZ,
+	                   ipv62str(NULL, &GET_IP6_HDR(input)->src));
+	reply_count ++;
+	}
+
+/*
+ *  ping6 -- ICMP ECHO メッセージを送信する。
+ */
+
+void
+ping6 (T_IN6_ADDR *addr, uint_t tmo, uint_t size)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_ICMP6_HDR	*icmp6h;
+	T_NET_BUF	*output;
+	T_IN6_IFADDR	*ia;
+	int_t		ix;
+	uint16_t	ipflags = 0;
+	uint8_t		*sdu;
+
+	/*
+	 *  宛先アドレスにふさわしい送信元アドレスを、
+	 *  ネットワークインタフェースから探索して利用する。
+	 */
+	if ((ia = in6_ifawithifp(ifp, addr)) == NULL)
+		return;
+
+	if (IN6_IS_ADDR_MULTICAST(addr))
+		ipflags = IPV6_OUT_SET_HOP_LIMIT(IPV6_OUT_FLG_HOP_LIMIT, IPV6_DEFHLIM);
+
+	/* 送信用の IP データグラムを獲得する。*/
+	if (in6_get_datagram(&output, ICMP6_HDR_SIZE + size, 0,
+	                     addr, &ia->addr, IPPROTO_ICMPV6,
+	                     IPV6_DEFHLIM, NBA_SEARCH_ASCENT, TMO_FEVR) != E_OK)
+		return;
+
+	/* ICMP ヘッダを設定する。*/
+	icmp6h           = GET_ICMP6_HDR(output, IF_IP6_ICMP6_HDR_OFFSET);
+	icmp6h->type     = ICMP6_ECHO_REQUEST;
+	icmp6h->code     = 0;
+	icmp6h->icmp6_id = htons(send_icmp6_id);
+	icmp6h->icmp6_seq= 0;
+
+	/* データを設定する。*/
+	sdu = GET_ICMP6_SDU(output, IF_IP6_ICMP6_HDR_OFFSET) + size;
+	for (ix = size; ix -- > 0; )
+		*-- sdu = ('0' + send_icmp6_id + ix) & 0xff;
+
+	/* チェックサムを計算する。*/
+	icmp6h->sum = 0;
+	icmp6h->sum = in6_cksum(output, IPPROTO_ICMPV6,
+	                        (uint8_t*)icmp6h - output->buf, ICMP6_HDR_SIZE + size);
+
+	/* 応答チェック用の変数を設定する。*/
+	reply_count = 0;
+
+#if 0
+	curr_icmp6_id   = send_icmp6_id ++;
+	curr_icmp6_size = size;
+#endif
+
+#if 0
+	syslog(LOG_NOTICE, "[PING6] send: TMO:%d, SIZE:%d, to: %s, from %s",
+	                   tmo, size,
+	                   ipv62str(NULL, addr), ipv62str(NULL, &ia->addr));
+#endif
+
+	/* 送信後、現在の時間を記憶し、タイムアウトを設定する。*/
+	ip6_output(output, ipflags, TMO_FEVR);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutMsgs, 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutEchos, 1);
+
+	syscall(get_tim(&icmp6_start_time));
+	timeout(icmp6_reply_timeout, NULL, tmo * NET_TIMER_HZ);
+
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #ifdef USE_PING */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver.c	(revision 398)
@@ -0,0 +1,1166 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ホスト名←→IP アドレス変換
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <target_syssvc.h>
+#define LOGTASK_PORTID SIO_PORTID
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_config.h>
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/resolver.h>
+
+#if defined(USE_RESOLVER)
+
+/*
+ *  局所変数
+ */
+
+static uint8_t	dns_domain_name[DNS_NAME_LENGTH + 1] = RSLV_CFG_DNS_DOMAIN_NAME_STR;
+
+#if defined(SUPPORT_INET6)
+static T_IN6_ADDR in6_addr_dns      = IPV6_ADDR_DNS_INIT;
+static T_IN6_ADDR in6_addr_dns_init = IPV6_ADDR_DNS_INIT;
+#endif
+
+#if defined(SUPPORT_INET4)
+static T_IN4_ADDR in4_addr_dns = IPV4_ADDR_DNS;
+#endif
+
+static uint16_t	dns_msg_id = 0;
+
+/*
+ *  get_dns_header -- DNS メッセージから DNS ヘッダを取り出す。
+ */
+
+static ER_UINT
+get_dns_header (uint8_t *msg, uint_t length, T_RSLV_DNS_MSG *rslv)
+{
+	T_DNS_HDR	*dns_hdr;
+
+	/* DNS ヘッダを取り出す。*/
+	if (length < sizeof(rslv->dns_hdr))
+		return EV_RSLV_ESIZE;
+	dns_hdr = (T_DNS_HDR*)msg;
+	rslv->dns_hdr.id	= MSG2HOST16(dns_hdr->id);
+	rslv->dns_hdr.code	= MSG2HOST16(dns_hdr->code);
+	rslv->dns_hdr.qdcount	= MSG2HOST16(dns_hdr->qdcount);
+	rslv->dns_hdr.ancount	= MSG2HOST16(dns_hdr->ancount);
+	rslv->dns_hdr.nscount	= MSG2HOST16(dns_hdr->nscount);
+	rslv->dns_hdr.arcount	= MSG2HOST16(dns_hdr->arcount);
+	return sizeof(rslv->dns_hdr);
+	}
+
+/*
+ *  dns_strtype -- DNS の type の文字列を返す。
+ */
+
+static const char *
+dns_flag_qtype (uint16_t flags)
+{
+	if      (flags & DNS_LUP_FLAGS_QTYPE_AAAA)
+		return "AAAA";
+	else if (flags & DNS_LUP_FLAGS_QTYPE_A)
+		return "   A";
+	else if (flags & DNS_LUP_FLAGS_QTYPE_PTR)
+		return " PTR";
+	else
+		return "unknown type";
+	}
+
+#if defined(SUPPORT_INET6)
+
+/*
+ *  udp6_dns -- UDP/IPv6 により DNS サーバからメッセージを受信する。
+ */
+
+static ER
+udp6_dns (uint16_t flags, T_IN6_ADDR *addr, uint8_t *msg, uint_t msg_size, uint_t length)
+{
+	T_IPV6EP	ep_dns;
+	ER_UINT		len = E_OK;
+	int		retry;
+
+	/* DNS サーバの IPv6 アドレスが未定義の時はパラメータエラー */
+	if (IN6_IS_ADDR_UNSPECIFIED(addr) || (in6_is_addr_ipv4mapped(addr) && addr->s6_addr32[3] == IPV4_ADDRANY)) {
+		syslog(LOG_NOTICE, "[RSLV] undefined IPv6 DNS server address.");
+		return E_PAR;
+		}
+
+	memcpy(&ep_dns.ipaddr, addr, sizeof(*addr));
+	ep_dns.portno = RSLV_CFG_DNS_PORTNO;
+	for (retry = NUM_DNS_UDP_RETRY + 1; retry -- > 0; ) {
+		if ((len = udp6_snd_dat(UDP6_RESOLVER_CEPID, &ep_dns, msg, length, TMO_DNS_UDP_SND)) >= 0) {
+			if ((len = udp6_rcv_dat(UDP6_RESOLVER_CEPID, &ep_dns, msg, msg_size, TMO_DNS_UDP_RCV)) >= 0)
+				return len;
+			}
+		if (flags & DNS_LUP_FLAGS_MSG) {
+			if (len == E_TMOUT)
+				syslog(LOG_NOTICE, "[RSLV] TMOUT: %d, type: %s, server: %s.%d.",
+				       NUM_DNS_UDP_RETRY + 1 - retry,
+				       dns_flag_qtype(flags),
+				       ipv62str(NULL, &ep_dns.ipaddr), ep_dns.portno);
+			else {
+				syslog(LOG_NOTICE, "[RSLV] error:  %s, type: %s,\n       server: %s.%d.",
+				       itron_strerror(len),
+				       dns_flag_qtype(flags),
+				       ipv62str(NULL, &ep_dns.ipaddr), ep_dns.portno);
+				return len;
+				}
+			}
+		}
+	return E_TMOUT;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+/*
+ *  udp4_dns -- UDP/IPv4 により DNS サーバからメッセージを受信する。
+ */
+
+static ER
+udp4_dns (uint16_t flags, T_IN4_ADDR *addr, uint8_t *msg, uint_t msg_size, uint_t length)
+{
+	T_IPV4EP	ep_dns;
+	ER_UINT		len = E_OK;
+	int		retry;
+
+	/* DNS サーバの IPv4 アドレスが未定義の時はパラメータエラー */
+	if (*addr == IPV4_ADDRANY) {
+		syslog(LOG_NOTICE, "[RSLV] undefined IPv4 DNS server address.");
+		return E_PAR;
+		}
+
+	memcpy(&ep_dns.ipaddr, addr, sizeof(*addr));
+	ep_dns.portno = RSLV_CFG_DNS_PORTNO;
+	for (retry = NUM_DNS_UDP_RETRY + 1; retry -- > 0; ) {
+		if ((len = udp_snd_dat(UDP4_RESOLVER_CEPID, &ep_dns, msg, length, TMO_DNS_UDP_SND)) >= 0) {
+			if ((len = udp_rcv_dat(UDP4_RESOLVER_CEPID, &ep_dns, msg, msg_size, TMO_DNS_UDP_RCV)) >= 0)
+				return len;
+			}
+		if (flags & DNS_LUP_FLAGS_MSG) {
+			if (len == E_TMOUT)
+				syslog(LOG_NOTICE, "[RSLV] TMOUT: %d, type: %s, server: %s.%d.",
+				       NUM_DNS_UDP_RETRY + 1 - retry,
+				       dns_flag_qtype(flags),
+				       ip2str(NULL, &ep_dns.ipaddr), ep_dns.portno);
+			else {
+				syslog(LOG_NOTICE, "[RSLV] error: %s, type: %s, server: %s.%d.",
+				       itron_strerror(len),
+				       dns_flag_qtype(flags),
+				       ip2str(NULL, &ep_dns.ipaddr), ep_dns.portno);
+				return len;
+				}
+			}
+		}
+	return E_TMOUT;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+/*
+ *  skip_label -- ラベルを読み飛ばす。
+ */
+
+static char *
+skip_label (char *name)
+{
+	while (!(*name == '\0' || *name == '.'))
+		name ++;
+	return name;
+	}
+
+/*
+ *  add_name -- メッセージに名前を追加する。
+ */
+
+static ER_UINT
+add_name (uint8_t *msg, uint_t size, uint_t offset, char *name)
+{
+	uint_t		label_len;
+	uint8_t		*tail;
+
+	while (*name != '\0') {
+
+		/* メッセージサイズに達していたらエラー */
+		if (offset + 1 > size)
+			return E_BOVR;
+
+		/* ラベルの終わりを見つける。*/
+		tail = skip_label(name);
+
+		/* ラベル長を設定する。*/
+		label_len = tail - (uint8_t*)name;
+		if (label_len > DNS_LABEL_LENGTH) {	/* 63 オクテットを超えるとエラー */
+			syslog(LOG_NOTICE, "[RSLV] label length(%d) too long > %d.",
+			                   label_len, DNS_LABEL_LENGTH);
+			return E_PAR;
+			}
+
+		*(msg + offset) = (uint8_t)label_len;
+		offset ++;
+
+		/* ラベル名を設定する。*/
+		if (offset + label_len > size) {	/* メッセージサイズを超えるとエラー */
+			syslog(LOG_NOTICE, "[RSLV] message length(%d) too long > %d.",
+			                   offset + label_len, size);
+			return E_BOVR;
+			}
+
+		memcpy((void*)(msg + offset), (void*)name, label_len);
+		offset += label_len;
+
+		/* 次のラベルに移動する。*/
+		if (*tail == '\0')
+			name = tail;
+		else
+			name = tail + 1;	/* '.' をスキップする。*/
+		}
+
+	return offset;
+	}
+
+/*
+ *  add_ipv6addr -- メッセージに IPv6 アドレスを追加する。
+ */
+
+static ER_UINT
+add_ipv6addr (uint8_t *msg, uint_t size, uint_t offset, char *name)
+{
+	T_IN6_ADDR	addr;
+	ER_UINT		error;
+	uint_t		len;
+	int			col;
+	char		digit[2];
+
+	len = strlen(name);
+	if (len == 0)
+		return E_PAR;
+
+	digit[1] = '\0';
+	get_ipv6addr(&addr, name);
+	for (col = sizeof(T_IN6_ADDR) * 2; -- col >= 0; ) {
+
+		/* 16進数 1桁の値を、名前として追加する。*/
+		digit[0] = (addr.s6_addr8[col / 2] >> ((1 - (col % 2)) << 2)) & 0x0f;
+		if (digit[0] >= 10)
+			digit[0] += 'a' - 10;
+		else
+			digit[0] += '0';
+		if ((error = add_name(msg, size, offset, digit)) < 0)
+			return error;
+		offset = error;
+		}
+
+	/* "ip6" を追加する。*/
+	if ((error = add_name(msg, size, offset, "ip6")) < 0)
+		return error;
+
+	/* "arpa" を追加する。*/
+	return add_name(msg, size, error, "arpa");
+	}
+
+/*
+ *  add_ipv4addr -- メッセージに IPv4 アドレスを追加する。
+ */
+
+static ER_UINT
+add_ipv4addr (uint8_t *msg, uint_t size, uint_t offset, char *name)
+{
+	T_IN4_ADDR	addr;
+	ER_UINT		error;
+	uint_t		len, octet;
+	int			col;
+	char		*op, ostr[4];
+
+	len = strlen(name);
+	if (len == 0)
+		return E_PAR;
+
+	ostr[3] = '\0';
+	get_ipv4addr(&addr, name);
+	for (col = 0; col < sizeof(T_IN4_ADDR); col ++) {
+
+		/* 1オクテットの値を、整数値からリテラルに変換する。*/
+		octet = (addr >> (col << 3)) & 0xff;
+		op = &ostr[3];
+		while (octet > 0) {
+			*(-- op) = octet % 10 + '0';
+			octet   /= 10;
+			}
+
+		/* 1オクテットの値を、名前として追加する。*/
+		if ((error = add_name(msg, size, offset, op)) < 0)
+			return error;
+		offset = error;
+		}
+
+	/* "in-addr" を追加する。*/
+	if ((error = add_name(msg, size, offset, "in-addr")) < 0)
+		return error;
+
+	/* "arpa" を追加する。*/
+	return add_name(msg, size, error, "arpa");
+	}
+
+/*
+ *  setup_dns_msg -- DNS メッセージを作成する。
+ */
+
+static ER
+setup_dns_msg (uint16_t flags, char *name, uint8_t *msg, uint_t msg_size)
+{
+	T_DNS_HDR	dns_hdr;
+	ER_UINT		offset;
+
+	memset((void*)&dns_hdr, 0, sizeof(dns_hdr));
+
+	dns_msg_id++;
+	HOST2MSG16(dns_hdr.id,      dns_msg_id);
+	HOST2MSG16(dns_hdr.code,    (flags & DNS_OPCODE_MASK) | DNS_RECURSION_DESIRED);
+	HOST2MSG16(dns_hdr.qdcount, 1);
+
+	memcpy((void*)msg, (void*)&dns_hdr, sizeof(dns_hdr));
+	offset = sizeof(dns_hdr);
+
+	switch (flags & DNS_LUP_FLAGS_NAME_MASK) {
+
+	case DNS_LUP_FLAGS_NAME_HOST:
+	case DNS_LUP_FLAGS_NAME_FQDN:
+
+		/* ホスト名、または FQDN の時の処理。*/
+		/* ホスト名を追加する。*/
+		if ((offset = add_name(msg, msg_size, offset, name)) < 0)
+			return offset;
+
+		if (offset - sizeof(dns_hdr) > DNS_NAME_LENGTH) {		/* 名前が 255 オクテットを超えるとエラー */
+			syslog(LOG_NOTICE, "[RSLV] name length(%d) too long > %d.",
+			                   offset - sizeof(dns_hdr), DNS_NAME_LENGTH);
+			return E_PAR;
+			}
+
+		/* ホスト名だけの時は、ドメイン名を追加する。*/
+		if ((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_HOST) {
+
+			/* ドメイン名を追加する。*/
+			if ((offset = add_name(msg, msg_size, offset, dns_domain_name)) < 0)
+				return offset;
+
+			if (offset - sizeof(dns_hdr) > DNS_NAME_LENGTH) {		/* 名前が 255 オクテットを超えるとエラー */
+				syslog(LOG_NOTICE, "[RSLV] name length(%d) too long > %d.",
+				                   offset - sizeof(dns_hdr), DNS_NAME_LENGTH);
+				return E_PAR;
+				}
+			}
+		break;
+
+	case DNS_LUP_FLAGS_NAME_IPV4:
+		if ((offset = add_ipv4addr(msg, msg_size, offset, name)) < 0)
+			return offset;
+		break;
+
+	case DNS_LUP_FLAGS_NAME_IPV6:
+		if ((offset = add_ipv6addr(msg, msg_size, offset, name)) < 0)
+			return offset;
+		break;
+
+	default:
+		syslog(LOG_NOTICE, "[RSLV] unknown name type: %04x.", flags & DNS_LUP_FLAGS_NAME_MASK);
+		return E_PAR;
+		break;
+
+		}
+
+	/* 名前の終了コード、TYPE、CLASS を追加してもメッセージ長を超えないことを確認する。*/
+	if (offset + sizeof(uint16_t) * 2 + 1 > msg_size) {
+		syslog(LOG_NOTICE, "[RSLV] message length(%d) too long > %d.",
+		                   offset + sizeof(uint16_t) * 2 + 1, msg_size);
+		return E_BOVR;
+		}
+
+	/* 名前の終了コードを設定する。*/
+	*(msg + offset) = '\0';
+	offset ++;
+
+	/* DNS の TYPE を設定する。*/
+	if (flags & DNS_LUP_FLAGS_QTYPE_PTR)
+		host2msg16(msg + offset, DNS_TYPE_PTR);
+	else if (flags & DNS_LUP_FLAGS_QTYPE_AAAA)
+		host2msg16(msg + offset, DNS_TYPE_AAAA);
+	else if (flags & DNS_LUP_FLAGS_QTYPE_A)
+		host2msg16(msg + offset, DNS_TYPE_A);
+	else {
+		syslog(LOG_NOTICE, "[RSLV] unknown query type: %04x.", flags & DNS_LUP_FLAGS_QTYPE_MASK);
+		return E_PAR;
+		}
+	offset += sizeof(uint16_t);
+
+	/* DNS の CLASS を設定する。*/
+	host2msg16(msg + offset, DNS_CLASS_IN);
+
+	return offset + sizeof(uint16_t);
+	}
+
+/*
+ *  skip_dns_name -- DNS メッセージの名前を読み飛ばす。
+ *
+ *    注意: 圧縮形式を考慮する。上位 2ビットが 11なら圧縮形式。
+ */
+
+static ER_UINT
+skip_dns_name (uint8_t *name, uint_t offset, uint_t length)
+{
+	while (*(name + offset)) {
+		if ((*(name + offset) & 0xc0) == 0xc0) {
+			if (offset + 2 > length)
+				return EV_RSLV_ESIZE;
+			else
+				return offset + 2;
+			}
+		else if (offset + *name + 1 > length)
+			return EV_RSLV_ESIZE;
+		else
+			offset += *name + 1;
+		}
+	return offset + 1;
+	}
+
+/*
+ *  skip_dns_qd -- DNS Question section を読み飛ばす。
+ */
+
+static ER_UINT
+skip_dns_qd (uint8_t *msg, uint_t offset, uint_t length, uint_t count)
+{
+	ER_UINT	next;
+
+	while (count != 0) {
+		/* name を読み飛ばす。*/
+		if ((next = skip_dns_name(msg, offset, length)) < 0)
+			return next;
+		offset = next;
+
+		/* type、class を読み飛ばす。*/
+		if ((offset + sizeof(uint16_t) + sizeof(uint16_t)) > length)
+			return EV_RSLV_ESIZE;
+		offset += sizeof(uint16_t) + sizeof(uint16_t);
+
+		count --;
+		}
+
+	return offset;
+	}
+
+/*
+ *  skip_dns_rr -- DNS RR を読み飛ばす。
+ */
+
+static ER_UINT
+skip_dns_rr (uint8_t *msg, uint_t offset, uint_t length, uint_t count)
+{
+	ER_UINT		next;
+	uint16_t	len = 0;
+
+	while (count != 0) {
+		/* name を読み飛ばす。*/
+		if ((next = skip_dns_name(msg, offset, length)) < 0)
+			return next;
+		offset = next;
+
+		/* type、class、TTL を読み飛ばす。*/
+		if (offset + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) > length)
+			return EV_RSLV_ESIZE;
+		offset += sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t);
+
+		/* RD length と RDATA を読み飛ばす。*/
+		if (offset + sizeof(uint16_t) > length)
+			return EV_RSLV_ESIZE;
+		len = msg2host16(msg + offset);
+
+		if (offset + sizeof(uint16_t) + len > length)
+			return EV_RSLV_ESIZE;
+		offset += sizeof(uint16_t) + len;
+
+		count --;
+		}
+
+	return offset;
+	}
+
+/*
+ *  dns_analyze_qd -- DNS メッセージの question section を解析する。
+ */
+
+ER_UINT
+dns_analyze_qd (T_RSLV_QD *qd, uint_t offset, uint8_t *msg, uint_t length)
+{
+	ER_UINT		error;
+	T_DNS_QD	*dns_qd;
+
+	if ((error = skip_dns_name(msg, offset, length)) < 0)
+		return error;
+	offset = error;
+
+	/* DNS メッセージ内の形式のサイズでチェックする。*/
+	if (offset + T_DNS_QD_SIZE > length)
+		return EV_RSLV_ESIZE;
+
+	/*
+	 *  DNS メッセージ内の SOA RDATA をバイトオーダーを調整して
+	 *  内部構造体にコピーする。
+	 */
+	dns_qd = (T_DNS_QD*)(msg + offset);
+	qd->type  = MSG2HOST16(dns_qd->type);
+	qd->class = MSG2HOST16(dns_qd->class);
+
+	return offset + T_DNS_QD_SIZE;
+	}
+
+/*
+ *  dns_analyze_soa -- DNS メッセージの SOA RDATA を解析する。
+ */
+
+ER_UINT
+dns_analyze_soa (T_RSLV_SOA *soa, uint_t offset, uint8_t *msg, uint_t length)
+{
+	ER_UINT		error;
+	T_DNS_SOA	*dns_soa;
+
+	/* MNAME をスキップする。*/
+	if ((error = skip_dns_name(msg, offset, length)) < 0)
+		return error;
+	offset = error;
+
+	/* RNAME をスキップする。*/
+	if ((error = skip_dns_name(msg, offset, length)) < 0)
+		return error;
+	offset = error;
+
+	/* DNS メッセージ内の形式のサイズでチェックする。*/
+	if (offset + T_DNS_SOA_SIZE > length)
+		return EV_RSLV_ESIZE;
+
+	/*
+	 *  DNS メッセージ内の SOA RDATA をバイトオーダーを調整して
+	 *  内部構造体にコピーする。
+	 */
+	dns_soa = (T_DNS_SOA*)(msg + offset);
+	soa->serial  = MSG2HOST32(dns_soa->serial);
+	soa->refresh = MSG2HOST32(dns_soa->refresh);
+	soa->retry   = MSG2HOST32(dns_soa->retry);
+	soa->expire  = MSG2HOST32(dns_soa->expire);
+	soa->minimum = MSG2HOST32(dns_soa->minimum);
+
+	return offset + T_DNS_SOA_SIZE;
+	}
+
+/*
+ *  dns_analyze_rr -- DNS メッセージの AN/NS/AR section を解析する。
+ */
+
+ER_UINT
+dns_analyze_rr (T_RSLV_RR *rr, uint_t offset, uint8_t *msg, uint_t length)
+{
+	ER_UINT		error;
+	T_DNS_RR	*dns_rr;
+
+	if ((error = skip_dns_name(msg, offset, length)) < 0)
+		return error;
+	offset = error;
+
+	/* DNS メッセージ内の形式のサイズでチェックする。*/
+	if (offset + T_DNS_RR_SIZE > length)
+		return EV_RSLV_ESIZE;
+
+	/*
+	 *  DNS メッセージ内の SOA RDATA をバイトオーダーを調整して
+	 *  内部構造体にコピーする。
+	 */
+	dns_rr = (T_DNS_RR*)(msg + offset);
+	rr->type	= MSG2HOST16(dns_rr->type);
+	rr->class	= MSG2HOST16(dns_rr->class);
+	rr->ttl		= MSG2HOST32(dns_rr->ttl);
+	rr->rdlength	= MSG2HOST16(dns_rr->rdlength);
+	rr->rdata_offset= offset + sizeof(rr->type) + sizeof(rr->class)
+	                         + sizeof(rr->ttl)  + sizeof(rr->rdlength);
+
+	return offset + T_DNS_RR_SIZE + rr->rdlength;
+	}
+
+/*
+ *  analyze_dns_msg -- DNS メッセージを解析する。
+ */
+
+static ER_UINT
+analyze_dns_msg (uint8_t *msg, uint_t length, T_RSLV_DNS_MSG *rslv)
+{
+	ER_UINT	offset;
+
+	/* DNS ヘッダを取り出す。*/
+	if ((offset = get_dns_header(msg, length, rslv)) < 0)
+		return offset;
+
+	/* question section を読み飛ばす。*/
+	rslv->qd_offset = offset;
+	if ((offset = skip_dns_qd(msg, offset, length, rslv->dns_hdr.qdcount)) < 0)
+		return offset;
+
+	/* answer section を読み飛ばす。*/
+	rslv->an_offset = offset;
+	if ((offset = skip_dns_rr(msg, offset, length, rslv->dns_hdr.ancount)) < 0)
+		return offset;
+
+	/* authority records section を読み飛ばす。*/
+	rslv->ns_offset = offset;
+	if ((offset = skip_dns_rr(msg, offset, length, rslv->dns_hdr.nscount)) < 0)
+		return offset;
+
+	/* additional records  section を読み飛ばす。*/
+	rslv->ar_offset = offset;
+	if ((offset = skip_dns_rr(msg, offset, length, rslv->dns_hdr.arcount)) < 0)
+		return offset;
+
+	return E_OK;
+	}
+
+/*
+ *  dns_lookup_host_sub -- DNS によりホストの情報を取得する（補助関数）。
+ */
+
+static ER_UINT
+dns_lookup_host_sub (uint16_t flags, char *hostname, uint8_t *msg, 
+                     uint_t msg_size, T_RSLV_DNS_MSG *rslv)
+{
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+	uint16_t	proto;
+#endif
+	ER_UINT		length;
+	ER		error;
+
+	if ((length = setup_dns_msg(flags, hostname, msg, msg_size)) < 0)
+		return length;
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+	if (flags & DNS_LUP_FLAGS_PROTO_IPV6) {
+		proto = DNS_LUP_FLAGS_PROTO_IPV6;
+		if ((length = udp6_dns(flags, &in6_addr_dns, msg, msg_size, length)) < 0)
+			return length;
+		}
+	else if (flags & DNS_LUP_FLAGS_PROTO_IPV4) {
+		proto = DNS_LUP_FLAGS_PROTO_IPV4;
+		if ((length = udp4_dns(flags, &in4_addr_dns, msg, msg_size, length)) < 0)
+			return length;
+		}
+	else {
+		syslog(LOG_NOTICE, "[RSLV] unknown lookup protocol: %04x.", flags & DNS_LUP_FLAGS_PROTO_MASK);
+		return E_PAR;
+		}
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+	if (flags & DNS_LUP_FLAGS_PROTO_IPV6) {
+		if ((length = udp6_dns(flags, &in6_addr_dns, msg, msg_size, length)) < 0)
+			return length;
+		}
+	else {
+		syslog(LOG_NOTICE, "[RSLV] unknown lookup protocol: %04x.", flags & DNS_LUP_FLAGS_PROTO_MASK);
+		return E_PAR;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+	if (flags & DNS_LUP_FLAGS_PROTO_IPV4) {
+		if ((length = udp4_dns(flags, &in4_addr_dns, msg, msg_size, length)) < 0)
+			return length;
+		}
+	else {
+		syslog(LOG_NOTICE, "[RSLV] unknown lookup protocol: %04x.", flags & DNS_LUP_FLAGS_PROTO_MASK);
+		return E_PAR;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+	if ((error = analyze_dns_msg(msg, length, rslv)) != E_OK)
+		return error;
+	else {
+		if ((rslv->dns_hdr.ancount > 0) && (flags & DNS_LUP_FLAGS_MSG)) {
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+			if (proto & DNS_LUP_FLAGS_PROTO_IPV6) {
+				syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+				       dns_flag_qtype(flags),
+				       ipv62str(NULL, &in6_addr_dns),
+				       RSLV_CFG_DNS_PORTNO);
+				}
+			else {
+				syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+				       dns_flag_qtype(flags),
+				       ip2str(NULL, &in4_addr_dns),
+				       RSLV_CFG_DNS_PORTNO);
+				}
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+			syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+			       dns_flag_qtype(flags),
+			       ipv62str(NULL, &in6_addr_dns),
+			       RSLV_CFG_DNS_PORTNO);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+			syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+			       dns_flag_qtype(flags),
+			       ip2str(NULL, &in4_addr_dns),
+			       RSLV_CFG_DNS_PORTNO);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+			}
+		return length;
+		}
+	}
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+/*
+ *  udp64_dns -- DNS/IPv6、DNS/IPv4 により DNS サーバからメッセージを受信する。
+ */
+
+static ER_UINT
+udp64_dns (uint16_t flags, char *hostname, uint8_t *msg, 
+           uint_t msg_size, T_RSLV_DNS_MSG *rslv)
+{
+	ER_UINT		length;
+	ER		error;
+	uint16_t	proto;
+
+	/* DNS メッセージを作成する。*/
+	if ((length = setup_dns_msg(flags, hostname, msg, msg_size)) < 0)
+		return length;
+
+	/* UDP/IPv6 の DNS サーバに照会する。*/
+	proto = DNS_LUP_FLAGS_PROTO_IPV6;
+	if ((length = udp6_dns(flags, &in6_addr_dns, msg, msg_size, length)) < 0) {
+		/*  UDP/IPv6 の DNS サーバへの照会がエラーになった時は、UDP/IPv4 の DNS サーバに照会する。*/
+		if ((length = setup_dns_msg(flags, hostname, msg, msg_size)) < 0)
+			return length;
+
+		/* UDP/IPv4 の DNS サーバに照会する。*/
+		proto = DNS_LUP_FLAGS_PROTO_IPV4;
+		if ((length = udp4_dns(flags, &in4_addr_dns, msg, msg_size, length)) < 0)
+			return length;
+		}
+
+	/* DNS メッセージを解析する。*/
+	if ((error = analyze_dns_msg(msg, length, rslv)) != E_OK)
+		return error;
+	else {
+		if ((rslv->dns_hdr.ancount > 0) && (flags & DNS_LUP_FLAGS_MSG)) {
+			if (proto & DNS_LUP_FLAGS_PROTO_IPV6) {
+				syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+				       dns_flag_qtype(flags),
+				       ipv62str(NULL, &in6_addr_dns),
+				       RSLV_CFG_DNS_PORTNO);
+				}
+			else {
+				syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+				       dns_flag_qtype(flags),
+				       ip2str(NULL, &in4_addr_dns),
+				       RSLV_CFG_DNS_PORTNO);
+				}
+			}
+		return length;
+		}
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  dns_lookup_host -- DNS によりホストの情報を取得する。
+ */
+
+ER_UINT
+dns_lookup_host (uint16_t flags, char *hostname, uint8_t *msg, 
+              uint_t msg_size, T_RSLV_DNS_MSG *rslv)
+{
+	ER	error;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if ((flags & DNS_LUP_FLAGS_PROTO_MASK) == (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) {
+
+		/*
+		 *  IPv6/IPv4 の両方が指定された時の処理
+		 *  まず type == AAAA で DNS サーバに照会する。
+		 */
+		if (flags & DNS_LUP_FLAGS_QTYPE_PTR) {
+			if ((error = udp64_dns(flags, hostname, msg, msg_size, rslv)) < 0)
+				return error;
+			}
+		else if (flags & DNS_LUP_FLAGS_QTYPE_AAAA) {
+			if ((error = udp64_dns(flags & ~DNS_LUP_FLAGS_QTYPE_A, hostname, msg, msg_size, rslv)) < 0)
+				return error;
+			}
+		else {
+			HOST2MSG16(rslv->dns_hdr.ancount, 0);
+			error = E_OK;
+			}
+
+		if (rslv->dns_hdr.ancount == 0) {
+
+			/*
+			 *  type == AAAA でアドレス解決ができなかった時の処理
+			 *  type == A で DNS サーバに照会する。
+			 */
+			if (flags & DNS_LUP_FLAGS_QTYPE_A)
+				return udp64_dns(flags & ~DNS_LUP_FLAGS_QTYPE_AAAA, hostname, msg, msg_size, rslv);
+			else {
+				syslog(LOG_NOTICE, "[RSLV] unknown query type: %04x.", flags & DNS_LUP_FLAGS_QTYPE_MASK);
+				return E_PAR;
+				}
+			}
+		else
+			return error;
+		}
+
+	if ((flags & DNS_LUP_FLAGS_QTYPE_MASK) == (DNS_LUP_FLAGS_QTYPE_AAAA | DNS_LUP_FLAGS_QTYPE_A)) {
+
+		/*
+		 *  type == AAAA と A の両方が指定された時の処理
+		 *  まず type == AAAA で DNS サーバに照会する。
+		 */
+		if ((error = dns_lookup_host_sub(flags & ~DNS_LUP_FLAGS_QTYPE_A, hostname, msg, msg_size, rslv)) < 0)
+			return error;
+
+		if (rslv->dns_hdr.ancount == 0) {
+
+			/*
+			 *  type == AAAA でアドレス解決ができなかった時の処理
+			 *  type == A で DNS サーバに照会する。
+			 */
+			return dns_lookup_host_sub(flags & ~DNS_LUP_FLAGS_QTYPE_AAAA, hostname, msg, msg_size, rslv);
+			}
+#if 0
+		else {
+			syslog(LOG_NOTICE, "[RSLV] unknown query type: %04x.", flags & DNS_LUP_FLAGS_QTYPE_MASK);
+			return E_PAR;
+			}
+#endif
+		}
+
+	else {
+		/* IPv6/IPv4 のどちらか一方が指定された時の処理 */
+		error = dns_lookup_host_sub(flags, hostname, msg, msg_size, rslv);
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	error = dns_lookup_host_sub(flags, hostname, msg, msg_size, rslv);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	return error;
+	}
+
+#if defined(SUPPORT_INET6)
+
+/*
+ *  dns_in6_set_dname -- DNS の ドメイン名を設定する（DHCPv6用）。
+ *
+ *    注意: new に NULL を指定すると、初期値に戻す。
+ */
+
+const uint8_t *
+dns_in6_set_dname (const uint8_t *new, uint_t len)
+{
+	uint8_t	*dst;
+	int	label_len, name_len = DNS_NAME_LENGTH;
+
+	if (new == NULL)
+		strcpy(dns_domain_name, RSLV_CFG_DNS_DOMAIN_NAME_STR);
+	else {
+		dst = dns_domain_name;
+		while ((*new != 0) && (name_len > 0) && (len > 0)) {
+			label_len = *new ++;
+			len --;
+			while ((name_len > 0) && (len > 0) && (label_len > 0)) {
+				*dst ++ = *new ++;
+				name_len  --;
+				len       --;
+				label_len --;
+				}
+			if ((*new != 0) && (name_len > 0)) {
+				*dst ++ = '.';
+				name_len --;
+				}
+			}
+		*dst = '\0';
+		}
+	return dns_domain_name;
+	}
+
+/*
+ *  dns_in6_get_dname -- DNS の ドメイン名を得る。
+ */
+
+const uint8_t *
+dns_in6_get_dname (void)
+{
+	return dns_domain_name;
+	}
+
+/*
+ *  dns_in6_set_addr -- DNS サーバの IPv6 アドレスを設定する（DHCPv6用）。
+ *
+ *    注意: new に NULL を指定すると、初期値に戻す。
+ */
+
+T_IN6_ADDR *
+dns_in6_set_addr (T_IN6_ADDR *new)
+{
+	if (new == NULL)
+		in6_addr_dns = in6_addr_dns_init;
+	else
+		in6_addr_dns = *new;
+	return &in6_addr_dns;
+	}
+
+/*
+ *  dns_in6_get_addr -- DNS サーバの IPv6 アドレスを得る。
+ */
+
+T_IN6_ADDR *
+dns_in6_get_addr (T_IN6_ADDR *dst)
+{
+	if (dst == NULL)
+		return NULL;
+	else {
+		*dst = in6_addr_dns;
+		return dst;
+		}
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+/*
+ *  dns_in4_set_dname -- DNS の ドメイン名を設定する（DHCPv4用）。
+ *
+ *    注意: new に NULL を指定すると、初期値に戻す。
+ */
+
+const uint8_t *
+dns_in4_set_dname (const uint8_t *new, uint_t len)
+{
+	uint8_t	*dst;
+	int	name_len = DNS_NAME_LENGTH;
+
+	if (new == NULL)
+		strcpy(dns_domain_name, RSLV_CFG_DNS_DOMAIN_NAME_STR);
+	else {
+		dst = dns_domain_name;
+		while ((name_len -- > 0) && (len -- > 0) && *new)
+			*dst ++ = *new ++;
+		*dst = '\0';
+		}
+	return dns_domain_name;
+	}
+
+/*
+ *  dns_in4_get_dname -- DNS の ドメイン名を得る。
+ */
+
+const uint8_t *
+dns_in4_get_dname (void)
+{
+	return dns_domain_name;
+	}
+
+/*
+ *  dns_in4_set_addr -- DNS サーバの IPv4 アドレスを設定する（DHCPv4用）。
+ *
+ *    注意: new に NULL を指定すると、初期値に戻す。
+ */
+
+T_IN4_ADDR *
+dns_in4_set_addr (T_IN4_ADDR *new)
+{
+	if (new == NULL)
+		in4_addr_dns = IPV4_ADDR_DNS;
+	else
+		in4_addr_dns = *new;
+	return &in4_addr_dns;
+	}
+
+/*
+ *  dns_in4_get_addr -- DNS サーバの IPv4 アドレスを得る。
+ */
+
+T_IN4_ADDR *
+dns_in4_get_addr (T_IN4_ADDR *dst)
+{
+	if (dst == NULL)
+		return NULL;
+	else {
+		*dst = in4_addr_dns;
+		return dst;
+		}
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+/*
+ *  dns_host_addr -- ホスト名を IP アドレスに変換する。
+ */
+
+ER
+dns_host_addr (uint16_t flags, char *hostname, T_IN_ADDR *addr)
+{
+	T_RSLV_DNS_MSG	rslv;
+	T_RSLV_RR	rr;
+	ER_UINT		length, offset;
+	ER		error = E_OK;
+	int		scount;
+	uint8_t 	*msg;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	T_IN4_ADDR	addr4;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	if ((error = tget_mpf(MPF_RSLV_SRBUF, (void*)&msg, TMO_FEVR)) != E_OK)
+		return error;
+
+	if ((length = dns_lookup_host(flags, hostname, msg, DNS_UDP_MSG_LENGTH, &rslv)) < 0) {
+		error = length;
+		goto err_ret;
+		}
+
+	offset = rslv.an_offset;
+	for (scount = 1; scount <= rslv.dns_hdr.ancount; scount ++) {
+		if ((offset = dns_analyze_rr(&rr, offset, msg, length)) < 0) {
+			error = offset;
+			goto err_ret;
+			}
+
+#if defined(SUPPORT_INET6)
+
+		if (rr.type == DNS_TYPE_AAAA && rr.class == DNS_CLASS_IN &&  rr.rdlength == sizeof(*addr)) {
+			memcpy((void*)addr, (void*)(msg + rr.rdata_offset), sizeof(*addr));
+			break;
+			}
+
+#if defined(SUPPORT_INET4)
+
+		if (rr.type == DNS_TYPE_A && rr.class == DNS_CLASS_IN && rr.rdlength == sizeof(addr4)) {
+			addr4 = msg2host32(msg + rr.rdata_offset);
+			in6_make_ipv4mapped(addr, addr4);
+			break;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+		if (rr.type == DNS_TYPE_A && rr.class == DNS_CLASS_IN && rr.rdlength == sizeof(*addr)) {
+			*addr = msg2host32((msg + rr.rdata_offset));
+			break;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+		}
+	if (scount > rslv.dns_hdr.ancount)
+		error = EV_RSLV_UNEXPCT;
+
+err_ret:
+	rel_mpf(MPF_RSLV_SRBUF, (void*)msg);
+	return error;
+	}
+
+#endif	/* of #if defined(USE_RESOLVER) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver.h	(revision 398)
@@ -0,0 +1,315 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ホスト名←→IP アドレス変換
+ */
+
+#ifndef RESOLVER_H
+#define RESOLVER_H
+
+#include <netapp/dns.h>
+
+/*
+ *  コンパイル時コンフィギュレーションの指定
+ */
+
+/* ポート番号 */
+
+#define RSLV_CFG_DNS_PORTNO	53
+
+/*
+ *  タイムアウト値
+ */
+
+#define TMO_DNS_UDP_SND		ULONG_C(1*1000*1000)	/* [us]、DNS サーバへの   UDP 送信タイムアウト	*/
+#define TMO_DNS_UDP_RCV		ULONG_C(5*1000*1000)	/* [us]、DNS サーバからの UDP 受信タイムアウト	*/
+#define NUM_DNS_UDP_RETRY	1		/* リトライ回数					*/
+
+/*
+ *  ドメイン名
+ */
+
+
+#if !defined(RSLV_CFG_DNS_DOMAIN_NAME_STR)
+#define RSLV_CFG_DNS_DOMAIN_NAME_STR	""
+#endif
+
+/*
+ *  DNS サーバーの IPアドレス
+ */
+
+#if !defined(IPV6_ADDR_DNS_INIT)
+#define IPV6_ADDR_DNS_INIT	IPV6_ADDR_UNSPECIFIED_INIT
+#endif
+
+#if !defined(IPV4_ADDR_DNS)
+#define	IPV4_ADDR_DNS		IPV4_ADDRANY
+#endif
+
+/*
+ *  送受信バッファ数
+ */
+
+#define NUM_MPF_RSLV_SRBUF	1
+
+/*
+ *  プログラムで使用する情報の定義
+ */
+
+/*
+ *  プログラムで使用する DNS ヘッダ
+ *
+ *    注意: メンバはホストバイトオーダー
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                      ID                       |
+ *  +--+-----------+--+--+--+--+--------+-----------+
+ *  |QR|   Opcode  |AA|TC|RD|RA|    Z   |   RCODE   |
+ *  +--+--------+--+--+--+--+--+--------+-----------+
+ *  |                    QDCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    ANCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    NSCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    ARCOUNT                    |
+ *  +-----------------------------------------------+
+ */
+
+typedef struct rslv_dns_hdr {
+	uint16_t	id;		/* ID */
+	uint16_t	code;	/* QR:		1
+				   Opcode:	4
+				   AA:		1
+				   TC:		1
+				   RD:		1
+				   RA:		1
+				   Z:		3
+				   RCODE:	4
+				   */
+	uint16_t	qdcount;	/* question   section */
+	uint16_t	ancount;	/* answer     section */
+	uint16_t	nscount;	/* authority  section */
+	uint16_t	arcount;	/* additional section */
+	} __attribute__((packed))T_RSLV_DNS_HDR;
+
+/*
+ *  DNS message data
+ *
+ *    注意: メンバはホストバイトオーダー
+ */
+
+typedef struct rslv_dns_msg {
+	T_RSLV_DNS_HDR	dns_hdr;	/* DNS heder                            */
+	uint_t		qd_offset;	/* offset of question           section */
+	uint_t		an_offset;	/* offset of answer             section */
+	uint_t		ns_offset;	/* offset of authority  records section */
+	uint_t		ar_offset;	/* offset of additional records section */
+	} __attribute__((packed))T_RSLV_DNS_MSG;
+
+/*
+ *  RR (Resouce Record) 形式
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                      NAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                      TYPE                     |
+ *  +-----------------------------------------------+
+ *  |                      CLASS                    |
+ *  +-----------------------------------------------+
+ *  |                       TTL                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    RDLENGTH                   |
+ *  +-----------------------------------------------+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     RDATA                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *
+ *    注意: offset の原点は DNS message の先頭
+ *          メンバはホストバイトオーダー
+ */
+
+typedef struct rslv_rr {
+	uint16_t	type;		/* TYPE			*/
+	uint16_t	class;		/* CLASS		*/
+	uint32_t	ttl;		/* TTL			*/
+	uint16_t	rdlength;	/* RDATA length		*/
+	uint_t		rdata_offset;	/* offset of RDATA	*/
+	} __attribute__((packed))T_RSLV_RR;
+
+/*
+ *  Question section 形式
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     QNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                     QTYPE                     |
+ *  +-----------------------------------------------+
+ *  |                     QCLASS                    |
+ *  +-----------------------------------------------+
+ *
+ *    注意: メンバはホストバイトオーダー
+ */
+
+typedef struct rslv_qd {
+	uint16_t	type;		/* TYPE			*/
+	uint16_t	class;		/* CLASS		*/
+	} __attribute__((packed))T_RSLV_QD;
+
+/*
+ *  SOA RDATA 形式
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     MNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     RNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                    SERIAL                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    REFRESH                    |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                     RETRY                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    EXPIRE                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    MINIMUM                    |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *
+ *    注意: offset の原点は DNS message の先頭
+ *          メンバはホストバイトオーダー
+ */
+
+typedef struct rslv_soa {
+	uint32_t	serial;		/* SERIAL		*/
+	uint32_t	refresh;	/* REFRESH		*/
+	uint32_t	retry;		/* RETRY		*/
+	uint32_t	expire;		/* EXPIRE		*/
+	uint32_t	minimum;	/* MINIMUM		*/
+	} __attribute__((packed))T_RSLV_SOA;
+
+/*
+ *  dns_lookup_host の flags の定義
+ *
+ *    注意:
+ *      dns.h で定義されている DNS_OPCODE と重ならないこと。
+ *      #define DNS_OPCODE_MASK		0x7800U
+ */
+
+#define DNS_LUP_FLAGS_NAME_IPV4		0x0004U
+#define DNS_LUP_FLAGS_NAME_IPV6		0x0006U
+#define DNS_LUP_FLAGS_NAME_HOST		0x0010U
+#define DNS_LUP_FLAGS_NAME_FQDN		0x0011U
+#define DNS_LUP_FLAGS_NAME_MASK		0x001fU
+
+#define DNS_LUP_OPCODE_FORWARD		DNS_OPCODE_FORWARD
+#define DNS_LUP_OPCODE_REVERSE		DNS_OPCODE_REVERSE
+#define DNS_LUP_OPCODE_STATUS		DNS_OPCODE_STATUS
+#define DNS_LUP_OPCODE_MASK		DNS_OPCODE_MASK
+
+#define DNS_LUP_FLAGS_PROTO_IPV4	0x0040U
+#define DNS_LUP_FLAGS_PROTO_IPV6	0x0080U
+#define DNS_LUP_FLAGS_PROTO_MASK	0x00c0U
+
+#define DNS_LUP_FLAGS_QTYPE_A		0x0100U
+#define DNS_LUP_FLAGS_QTYPE_AAAA	0x0200U
+#define DNS_LUP_FLAGS_QTYPE_PTR		0x0400U
+#define DNS_LUP_FLAGS_QTYPE_MASK	0x0700U
+
+#define DNS_LUP_FLAGS_MSG		0x0020U
+
+/*
+ *  ネットワークエラーコード
+ */
+
+#define EV_RSLV_ESIZE			(-100)		/* DNSメッセージの名前長異常	*/
+#define EV_RSLV_UNEXPCT			(-101)		/* 予期しないDNSメッセージ	*/
+
+/*
+ *  関数
+ */
+
+extern ER_UINT	dns_lookup_host (uint16_t flags, char *hostname, uint8_t *msg, uint_t msg_len, T_RSLV_DNS_MSG *rslv);
+extern ER	dns_host_addr (uint16_t flags, char *hostname, T_IN_ADDR *addr);
+extern ER_UINT	dns_analyze_qd (T_RSLV_QD *qd, uint_t offset, uint8_t *msg, uint_t length);
+extern ER_UINT	dns_analyze_rr (T_RSLV_RR *rr, uint_t offset, uint8_t *msg, uint_t length);
+extern ER_UINT	dns_analyze_soa (T_RSLV_SOA *soa, uint_t offset, uint8_t *msg, uint_t length);
+
+/*
+ *  注意: dns_in6_set_dname、dns_in4_set_dname、
+ *        dns_in6_set_addr、 dns_in4_set_addr で、
+ *        new に NULL を指定すると、初期値に戻す。
+ */
+
+extern const uint8_t *dns_in6_set_dname (const uint8_t *new, uint_t len);
+extern const uint8_t *dns_in6_get_dname (void);
+extern const uint8_t *dns_in4_set_dname (const uint8_t *new, uint_t len);
+extern const uint8_t *dns_in4_get_dname (void);
+extern T_IN6_ADDR *dns_in6_set_addr (T_IN6_ADDR *new);
+extern T_IN6_ADDR *dns_in6_get_addr (T_IN6_ADDR *dst);
+extern T_IN4_ADDR *dns_in4_set_addr (T_IN4_ADDR *new);
+extern T_IN4_ADDR *dns_in4_get_addr (T_IN4_ADDR *dst);
+
+#endif	/* of #ifndef RESOLVER_H */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver_asp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver_asp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver_asp.cfg	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ASP 用 Resolver のシステムコンフィギュレーションファイル
+ */
+
+#ifdef USE_RESOLVER
+
+/*
+ * 固定メモリプール
+ */
+
+/* 送受信バッファ */
+
+CRE_MPF(MPF_RSLV_SRBUF, {
+	TA_TFIFO,
+	NUM_MPF_RSLV_SRBUF,
+	DNS_UDP_MSG_LENGTH,
+	NULL,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_RESOLVER */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver_jsp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver_jsp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/resolver_jsp.cfg	(revision 398)
@@ -0,0 +1,53 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  JSP 用 Resolver のシステムコンフィギュレーションファイル
+ */
+
+#ifdef USE_RESOLVER
+
+/*
+ * 固定メモリプール
+ */
+
+/* 送受信バッファ */
+
+CRE_MPF(MPF_RSLV_SRBUF, {
+	TA_TFIFO,
+	NUM_MPF_RSLV_SRBUF,
+	DNS_UDP_MSG_LENGTH,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_RESOLVER */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.c	(revision 398)
@@ -0,0 +1,520 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP DISCARD クライアント
+ *
+ *    ・ノンブロッキングコール
+ *    ・IPv4
+ *    ・IPv6
+ */
+
+#include <stdlib.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_discard_cli.h>
+
+#ifdef USE_TCP_DISCARD_CLI
+
+/* discard サーバのポート番号 */
+
+#define DISCARD_SRV_PORTNO	UINT_C(9)
+
+/* 表示 */
+
+/*#define SHOW_RCV_RANGE*/
+
+/* 送信間隔 */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define START_DLY	(10*SYSTIM_HZ)
+#define SND_ITV		(5*SYSTIM_HZ)
+#define SLP_ITV		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#define START_DLY	(10*SYSTIM_HZ)
+#define SND_ITV		(5*SYSTIM_HZ)
+#define SLP_ITV		(60*SYSTIM_HZ)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+/* 自動実行 */
+
+#if defined(TCP_DISCARD_CLI_AUTO_RUN_STR)
+#else
+#if 0
+#if defined(SUPPORT_INET6)
+#define TCP_DISCARD_CLI_AUTO_RUN_STR	"fd90:cce5:25f6:ff81:201:2ff:fe81:e7c9 - 0"
+#else
+#define TCP_DISCARD_CLI_AUTO_RUN_STR	"172.25.129.142 - 0"
+#endif
+#endif
+#endif
+
+/*
+ *  バッファサイズの定義
+ */
+
+#define NUM_DISCARD		5
+#define NUM_REP_PAT		40
+#define PAT_BEGIN		' '
+#define PAT_END			'~'
+#define SND_BUF_SIZE		((PAT_END - PAT_BEGIN + 1) * NUM_REP_PAT)
+
+/*
+ *  全域変数
+ */
+
+bool_t tcp_discard_cli_valid;
+
+/* TCP 送受信ウィンドバッファ */
+
+#ifndef TCP_CFG_SWBUF_CSAVE_ONLY
+uint8_t tcp_discard_cli_swbuf[TCP_DISCARD_CLI_SWBUF_SIZE];
+#endif
+
+#ifdef USE_TCP_NON_BLOCKING
+
+/*
+ *  変数
+ */
+
+static T_IPEP		nblk_src = {
+				IP_ADDRANY,
+				TCP_PORTANY,
+				};
+static T_IPEP		nblk_dst;
+static ER_UINT		nblk_error;
+
+/*
+ *  ノンブロッキングコールのコールバック関数
+ */
+
+ER
+callback_nblk_tcp_discard_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	ER	error = E_OK;
+
+	nblk_error = *(ER*)p_parblk;
+
+	switch (fncd) {
+
+	case TFN_TCP_CON_CEP:
+		syscall(sig_sem(SEM_TCP_DISCARD_CLI_NBLK_READY));
+		break;
+
+	case TFN_TCP_CLS_CEP:
+		if (nblk_error < 0)
+			syslog(LOG_NOTICE, "[TDCn:%02u CBN] close error: %s", cepid, itron_strerror(nblk_error));
+		syscall(sig_sem(SEM_TCP_DISCARD_CLI_NBLK_READY));
+		break;
+
+	case TFN_TCP_ACP_CEP:
+	case TFN_TCP_SND_DAT:
+	case TFN_TCP_GET_BUF:
+	case TFN_TCP_SND_OOB:
+	default:
+		error = E_PAR;
+		break;
+		}
+	return error;
+	}
+
+/*
+ *  send_tcp_discard -- DISCARD/TCP サーバにメッセージを送信する。
+ */
+
+static ER
+send_tcp_discard (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno)
+{
+	static char smsg[SND_BUF_SIZE];
+
+	ER_UINT		slen;
+	ER		error;
+	SYSTIM		time;
+	uint32_t	total;
+	uint16_t	soff, discard, rep, scount;
+	uint8_t		pat, *p;
+
+	nblk_dst.ipaddr = *ipaddr;
+	nblk_dst.portno = portno;
+
+	p = smsg;
+	for (rep = NUM_REP_PAT; rep -- > 0; )
+		for (pat = PAT_BEGIN; pat <= PAT_END; pat ++)
+			*p ++ = pat;
+
+	if ((error = TCP_CON_CEP(cepid, &nblk_src, &nblk_dst, TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] connect error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+
+	/* 接続が完了するまで待つ。*/
+	syscall(wai_sem(SEM_TCP_DISCARD_CLI_NBLK_READY));
+
+	if (nblk_error != E_OK)
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] connect error: %s", cepid, itron_strerror(nblk_error));
+	else {
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] conct: %7lu, to:   %s.%d",
+		                   cepid, time / SYSTIM_HZ, IP2STR(NULL, ipaddr), nblk_dst.portno);
+
+		scount = total = 0;
+		for (discard = NUM_DISCARD; discard -- > 0; ) {
+			soff = 0;
+			while (soff < SND_BUF_SIZE) {
+				if ((slen = tcp_snd_dat(cepid, smsg + soff, sizeof(smsg) - soff, TMO_FEVR)) < 0) {
+					syslog(LOG_NOTICE, "[TDCn:%02u SND] send error: %s",
+					                   cepid, itron_strerror(slen));
+					goto cls_ret;
+					}
+				soff  += (uint16_t)slen;
+				total +=     slen;
+				scount ++;
+
+#ifdef SHOW_RCV_RANGE
+				syslog(LOG_NOTICE, "[TDCn:%02u SND] send:  %7lu, len: %4u, off: %4u",
+				                   cepid, scount, (uint16_t)slen, soff);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+				syscall(dly_tsk(500 + netapp_rand() % SYSTIM_HZ));
+				}
+			}
+
+	cls_ret:
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] finsh: %7lu, ttl: %lu",
+		                   cepid, time / SYSTIM_HZ, scount, total);
+
+		if ((error = tcp_sht_cep(cepid)) < 0)
+			syslog(LOG_NOTICE, "[TDCn:%02u SND] shutdown error: %s", cepid, itron_strerror(error));
+
+		if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK)
+			syslog(LOG_NOTICE, "[TDCn:%02u SND] close error: %s", cepid, itron_strerror(error));
+
+		/* 開放が完了するまで待つ。*/
+		syscall(wai_sem(SEM_TCP_DISCARD_CLI_NBLK_READY));
+		}
+
+	return E_OK;
+	}
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+/*
+ *  send_tcp_discard -- DISCARD/TCP サーバにメッセージを送信する。
+ */
+
+static ER
+send_tcp_discard (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno)
+{
+	static char smsg[SND_BUF_SIZE];
+	static T_IPEP src = {
+		IP_ADDRANY,
+		TCP_PORTANY,
+		};
+
+	T_IPEP		dst;
+	ER_UINT		slen;
+	ER		error;
+	SYSTIM		time;
+	uint16_t	pat, soff, discard, rep, scount, total;
+	uint8_t		*p;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+
+	p = smsg;
+	for (rep = NUM_REP_PAT; rep -- > 0; )
+		for (pat = PAT_BEGIN; pat <= PAT_END; pat ++)
+			*p ++ = pat;
+
+	if ((error = TCP_CON_CEP(cepid, &src, &dst, 60 * 1000)) != E_OK) {
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] connect error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TDCn:%02u SND] conct: %7lu, to:   %s.%d",
+	                   cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+
+	scount = total = 0;
+	for (discard = NUM_DISCARD; discard -- > 0; ) {
+		soff = 0;
+		while (soff < SND_BUF_SIZE) {
+			if ((slen = tcp_snd_dat(cepid, smsg + soff, sizeof(smsg) - soff, TMO_FEVR)) < 0) {
+				syslog(LOG_NOTICE, "[TDCn:%02u SND] send error: %s", cepid, itron_strerror(slen));
+				goto cls_ret;
+				}
+			soff  += (uint16_t)slen;
+			total +=     slen;
+			scount ++;
+
+#ifdef SHOW_RCV_RANGE
+			syslog(LOG_NOTICE, "[TDCn:%02u SND] send:  %7lu, len: %4u, off: %4u",
+			                   cepid, scount, (uint16_t)slen, soff);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+			syscall(dly_tsk(500 + netapp_rand() % SYSTIM_HZ));
+			}
+		}
+
+cls_ret:
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TDCn:%02u SND] finsh: %7lu, ttl: %lu",
+	                   cepid, time / SYSTIM_HZ, scount, total);
+
+	if ((error = tcp_sht_cep(cepid)) < 0)
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] shutdown error: %s", cepid, itron_strerror(error));
+
+	if ((error = tcp_cls_cep(cepid, TMO_FEVR)) < 0)
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] close error: %s", cepid, itron_strerror(error));
+
+	return E_OK;
+	}
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+/*
+ *  getcomd -- コマンドを得る。
+ */
+
+#ifdef TCP_DISCARD_CLI_AUTO_RUN_STR
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER		error;
+	char		*line = NULL;
+	static char	auto_run_str[] = TCP_DISCARD_CLI_AUTO_RUN_STR;
+	static int_t	count = 0;
+
+	if (retry || (count == 0)) {
+		line = auto_run_str;
+		dly_tsk(3 * 1000);
+		}
+	else {
+		while ((error = rcv_dtq(DTQ_TCP_DISCARD_CLI, (intptr_t*)&line)) != E_OK) {
+			syslog(LOG_NOTICE, "[TDCn:%02u TSK] error: %s", cepid, itron_strerror(error));
+			dly_tsk(SLP_ITV);
+			}
+		}
+
+	count ++;
+	return line;
+	}
+
+#else	/* of #ifdef TCP_DISCARD_CLI_AUTO_RUN_STR */
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER	error;
+	char	*line = NULL;
+
+	while ((error = rcv_dtq(DTQ_TCP_DISCARD_CLI, (intptr_t*)&line)) != E_OK) {
+		syslog(LOG_NOTICE, "[TDCn:%02u TSK] error: %s", cepid, itron_strerror(error));
+		dly_tsk(SLP_ITV);
+		}
+	return line;
+	}
+
+#endif	/* of #ifdef TCP_DISCARD_CLI_AUTO_RUN_STR */
+
+void
+tcp_discard_cli_task (intptr_t exinf)
+{
+	ID		tskid, cepid;
+	T_IN_ADDR	addr;
+	ER		error;
+	uint8_t		*line;
+	int_t		rep, count;
+	bool_t		retry = false;
+	uint16_t	portno;
+	char		apip;
+
+#ifdef USE_TCP_EXTENTIONS
+
+	T_TCP_CCEP	ccep;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef TCP_ECHO_CLI_AUTO_RUN_STR
+	dly_tsk(START_DLY);
+#endif
+	get_tid(&tskid);
+
+#if defined(SUPPORT_INET6)
+	apip = API_PROTO_IPV6;
+#if defined(SUPPORT_INET4)
+	syslog(LOG_NOTICE, "[TCPn DISCARD CLI:%d,%d] started.", tskid, (ID)exinf);
+#else
+	syslog(LOG_NOTICE, "[TCP6 DISCARD CLI:%d,%d] started.", tskid, (ID)exinf);
+#endif
+#else
+	apip = API_PROTO_IPV4;
+	syslog(LOG_NOTICE, "[TCP4 DISCARD CLI:%d,%d] started.", tskid, (ID)exinf);
+#endif
+
+	while (true) {
+		line = skip_blanks(getcomd((ID)exinf, retry));
+
+		if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
+			syslog(LOG_NOTICE, "[TDCn:%02u TSK] sleep %d.%03u[s], unknown host.",
+			       (ID)exinf, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			dly_tsk(SLP_ITV);
+			syslog(LOG_NOTICE, "[TDCn:%02u TSK] resume.", (ID)exinf);
+			retry = true;
+			continue;
+			}
+		else
+			retry = false;
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {	/* Port No */
+			line = get_int(&rep, line);
+			portno = (uint16_t)rep;
+			}
+		else {
+			line ++;
+			portno = DISCARD_SRV_PORTNO;
+			}
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9')	/* Repeat */
+			line = get_int(&rep, line);
+		else
+			rep = 1;
+
+#ifdef USE_TCP_EXTENTIONS
+
+		ccep.cepatr = 0;
+		ccep.sbufsz = TCP_DISCARD_CLI_SWBUF_SIZE;
+		ccep.rbufsz = 0;
+		ccep.rbuf = NADR;
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+		ccep.sbuf = NADR;
+#else
+		ccep.sbuf = tcp_discard_cli_swbuf;
+#endif
+#ifdef USE_TCP_NON_BLOCKING
+		ccep.callback = (FP)callback_nblk_tcp_discard_cli;
+#else
+		ccep.callback = NULL;
+#endif
+
+		if ((error = ALLOC_TCP_CEP(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[TDCn:%02u TSK] CEP create error: %s", cepid, itron_strerror(error));
+			continue;
+			}
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		cepid = (ID)exinf;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		tcp_discard_cli_valid = true;
+		count = 0;
+		while (rep == 0 || count < rep) {
+			if (!tcp_discard_cli_valid) {
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] canceled.", cepid);
+				break;
+				}
+
+			count ++;
+			if (rep == 0) {
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] start:       repeat: %d", cepid, count);
+				error = send_tcp_discard(cepid, &addr, portno);
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] finsh:       repeat: %d", cepid, count);
+				}
+			else {
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] start:       repeat: %d/%d", cepid, count, rep);
+				error = send_tcp_discard(cepid, &addr, portno);
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] finsh:       repeat: %d/%d", cepid, count, rep);
+				}
+
+			if (error != E_OK) {
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] sleep %d.%03u[s], error: %s",
+				                   cepid, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ, itron_strerror(error));
+				tslp_tsk(SLP_ITV);
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] resume.", cepid);
+				}
+
+#if defined(SND_ITV)
+#if SND_ITV > 0
+			if (count < rep) {
+				uint_t itv;
+				
+				itv = SND_ITV;
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] interval: %d[s].", cepid, itv / SYSTIM_HZ);
+				syscall(dly_tsk(SND_ITV));
+				}
+#endif
+#endif
+			}
+
+#ifdef USE_TCP_EXTENTIONS
+
+		if ((error = FREE_TCP_CEP(cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[TDCn:%02u TSK] CEP delete error: %s", cepid, itron_strerror(error));
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		}
+	}
+
+#endif	/* of #ifdef USE_TCP_DISCARD_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.cfg	(revision 398)
@@ -0,0 +1,79 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP DISCARD クライアント
+ *  コンフィギュレーションファイル
+ */
+
+#ifdef USE_TCP_DISCARD_CLI
+
+/* タスク */
+
+#ifdef USE_TCP_EXTENTIONS
+
+CRE_TSK(TCP_DISCARD_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	tcp_discard_cli_task,
+	TCP_DISCARD_CLI_MAIN_PRIORITY,
+	TCP_DISCARD_CLI_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+CRE_TSK(TCP_DISCARD_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	TCP_DISCARD_CLI_CEPID,
+	tcp_discard_cli_task,
+	TCP_DISCARD_CLI_MAIN_PRIORITY,
+	TCP_DISCARD_CLI_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/* コマンドキュー */
+
+CRE_DTQ(DTQ_TCP_DISCARD_CLI,  { TA_TFIFO, 1, NULL });
+
+/* セマフォ */
+
+#ifdef USE_TCP_NON_BLOCKING
+
+CRE_SEM(SEM_TCP_DISCARD_CLI_NBLK_READY,	{ TA_TPRI, 0, 1 });
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef USE_TCP_DISCARD_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.h	(revision 398)
@@ -0,0 +1,86 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TCP_DISCARD_CLI_H_
+#define _TCP_DISCARD_CLI_H_
+
+/* スタックサイズ */
+
+#define TCP_DISCARD_CLI_STACK_SIZE	1024		/* TCP DISCARD クライアントタスクのスタックサイズ */
+
+/* 優先度 */
+
+#define TCP_DISCARD_CLI_MAIN_PRIORITY	5	/* TCP DISCARD クライアントタスクの優先度 */
+
+/*
+ *  TCP 送受信ウインドバッファサイズ
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_DISCARD_CLI_SWBUF_SIZE	(1024)
+
+#elif defined(SUPPORT_INET4)
+
+#define TCP_DISCARD_CLI_SWBUF_SIZE	(512)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define TCP_DISCARD_CLI_SWBUF_SIZE	(2048)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+/*
+ *  変数
+ */
+
+extern bool_t	tcp_discard_cli_valid;
+
+/* TCP 送受信バッファ */
+
+extern uint8_t tcp_discard_cli_swbuf[];
+extern uint8_t tcp_discard_cli_rwbuf[];
+
+/* タスク */
+
+extern void tcp_discard_cli_task(intptr_t exinf);
+
+/* 関数 */
+
+extern ER callback_nblk_tcp_discard_cli (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _TCP_DISCARD_CLI_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.c	(revision 398)
@@ -0,0 +1,356 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  DISCARD サーバ
+ *
+ *    ・省コピー API
+ *    ・IPv4
+ *    ・IPv6
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_discard_srv.h>
+
+#ifdef USE_TCP_DISCARD_SRV
+
+/*
+ *  表示
+ */
+
+//#define SHOW_RCV_RANGE
+//#define SHOW_RCV_DATA
+
+/*
+ *  全域変数
+ */
+
+/* TCP 送受信ウィンドバッファ */
+
+#ifndef TCP_CFG_RWBUF_CSAVE_ONLY
+uint8_t tcp_discard_srv_rwbuf[TCP_DISCARD_SRV_RWBUF_SIZE];
+#endif
+
+/*
+ *  TCP DISCARD サーバタスク
+ */
+
+#define BUF_SIZE	TCP_DISCARD_SRV_RWBUF_SIZE
+
+#ifdef USE_COPYSAVE_API
+
+static ER
+tcp_discard_srv (ID cepid, ID repid)
+{
+	T_IPEP		dst;
+	ER_UINT		rlen;
+	ER		error;
+	SYSTIM		time;
+	uint32_t	total;
+	uint16_t	count;
+	uint8_t		*buf;
+
+#ifdef SHOW_RCV_DATA
+	uint_t	ix;
+#endif	/* of #ifdef SHOW_RCV_DATA */
+
+	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
+		syslog(LOG_NOTICE, "[TDSn:%02u ACP] accept error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+
+#ifdef USE_TCP_EXTENTIONS
+	if ((error = FREE_TCP_REP(repid, true)) != E_OK) {
+		syslog(LOG_NOTICE, "[TDSn:%02u DEL] REP delete error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	count = total = 0;
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TDSn:%02u RCV] conct: %7lu, from: %s.%d",
+	                   cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+	while ((rlen = tcp_rcv_buf(cepid, (void*)&buf, TMO_FEVR)) > 0) {
+		count ++;
+
+#ifdef SHOW_RCV_RANGE
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] count: %6lu, len: %4u, data: %02x -> %02x",
+		       cepid, count, (uint16_t)rlen, *buf, *(buf + rlen - 1));
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+#ifdef SHOW_RCV_DATA
+		for (ix = 0; ix < rlen; ix ++)
+			cons_putchar(CONSOLE_PORTID,  *(buf + ix));
+#endif	/* of #ifdef SHOW_RCV_DATA */
+
+		if ((error = tcp_rel_buf(cepid, rlen)) != E_OK) {
+			syslog(LOG_NOTICE, "[TDSn:%02u RCV] rel buf error: %s",
+			                    cepid, itron_strerror(error));
+			rlen = 0;
+			break;
+			}
+		total += rlen;
+		}
+
+	if (rlen != 0)
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] recv buf error: %s", cepid, itron_strerror(rlen));
+
+	if ((error = tcp_sht_cep(cepid)) != E_OK)
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] shutdown error: %s", cepid, itron_strerror(error));
+
+	if ((error = tcp_cls_cep(cepid, TMO_FEVR)) != E_OK)
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] close error: %s", cepid, itron_strerror(error));
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TDSn:%02u RCV] finsh: %7lu, ttl: %lu",
+	                   cepid, time / SYSTIM_HZ, count, total);
+
+	return error;
+	}
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+static ER
+tcp_discard_srv (ID cepid, ID repid)
+{
+	static char buffer[BUF_SIZE];
+
+	T_IPEP		dst;
+	ER_UINT		rlen;
+	ER		error;
+	SYSTIM		time;
+	uint32_t	total;
+	uint16_t	count;
+	uint8_t		*buf = buffer;
+
+	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] accept error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+
+#ifdef USE_TCP_EXTENTIONS
+	if ((error = FREE_TCP_REP(repid, true)) != E_OK) {
+		syslog(LOG_NOTICE, "[TDSn:%02u DEL] REP delete error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	count = total = 0;
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TDSn:%02u RCV] conct: %7lu, from: %s.%d",
+	                   cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+	while ((rlen = tcp_rcv_dat(cepid, buf, BUF_SIZE - 1, TMO_FEVR)) > 0) {
+		count ++;
+
+#ifdef SHOW_RCV_RANGE
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] count: %6lu, len: %4u, data: %02x -> %02x",
+		       cepid, count, (uint16_t)rlen, *buf, *(buf + rlen - 1));
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+		total += rlen;
+		}
+	if (rlen != 0)
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] recv error: %s", cepid, itron_strerror(rlen));
+
+	if ((error = tcp_sht_cep(cepid)) != E_OK)
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] shutdown error: %s", cepid, itron_strerror(error));
+
+	if ((error = tcp_cls_cep(cepid, TMO_FEVR)) != E_OK)
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] close error: %s", cepid, itron_strerror(error));
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TDSn:%02u RCV] finsh: %7lu, ttl: %lu",
+	                   cepid, time / SYSTIM_HZ, count, total);
+
+	return error;
+	}
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+#ifdef USE_TCP_EXTENTIONS
+
+/*
+ *  get_tcp_rep -- TCP 受付口を獲得する。
+ */
+
+static ER
+get_tcp_rep (ID *repid)
+{
+	ID		tskid;
+	T_TCPN_CREP	crep;
+
+	get_tid(&tskid);
+
+	crep.repatr = UINT_C(0);
+	crep.myaddr.portno = UINT_C(9);
+
+#if defined(SUPPORT_INET6)
+
+	memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#else	/* #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+	crep.myaddr.ipaddr = IPV4_ADDRANY;
+#endif
+
+#endif	/* #if defined(SUPPORT_INET6) */
+
+	return ALLOC_TCP_REP(repid, tskid, &crep);
+	}
+
+/*
+ *  get_tcp_cep -- TCP 通信端点とを獲得する。
+ */
+
+static ER
+get_tcp_cep (ID *cepid)
+{
+	ID		tskid;
+	T_TCP_CCEP	ccep;
+
+	get_tid(&tskid);
+
+	ccep.cepatr = UINT_C(0);
+	ccep.sbuf = NADR;
+	ccep.sbufsz = 0;
+	ccep.rbufsz = TCP_DISCARD_SRV_RWBUF_SIZE;
+	ccep.callback = NULL;
+
+#ifdef TCP_CFG_RWBUF_CSAVE
+	ccep.rbuf = NADR;
+#else
+	ccep.rbuf = tcp_discard_srv_rwbuf;
+#endif
+
+	return ALLOC_TCP_CEP(cepid, tskid, &ccep);
+	}
+
+/*
+ *  tcp_discard_srv_task -- TCP エコーサーバタスク
+ */
+
+void
+tcp_discard_srv_task (intptr_t exinf)
+{
+	ID	tskid, cepid, repid;
+	ER	error = E_OK;
+
+	syscall(get_tid(&tskid));
+
+#if defined(SUPPORT_INET6)
+#if defined(SUPPORT_INET4)
+	syslog(LOG_NOTICE, "[TCPn DISCARD SRV:%d] started.", tskid);
+#else
+	syslog(LOG_NOTICE, "[TCP6 DISCARD SRV:%d] started.", tskid);
+#endif
+#else
+	syslog(LOG_NOTICE, "[TCP4 DISCARD SRV:%d] started.", tskid);
+#endif
+
+	while (true) {
+
+		syscall(slp_tsk());
+		if ((error = get_tcp_cep (&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TDSn:00 EXT] CEP create error: %s", itron_strerror(error));
+			continue;
+			}
+
+		while (true) {
+
+			if ((error = get_tcp_rep (&repid)) != E_OK) {
+				syslog(LOG_NOTICE, "[TDSn:00 EXT] REP create error: %s", itron_strerror(error));
+				break;
+				}
+			else if ((error = tcp_discard_srv(cepid, repid)) != E_OK) {
+				error = FREE_TCP_REP(repid, error != E_DLT);
+				break;
+				}
+			}
+
+		if ((error = FREE_TCP_CEP(cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[TDSn:%02u EXT] CEP delete error: %s", cepid, itron_strerror(error));
+
+		}
+	}
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+void
+tcp_discard_srv_task(intptr_t exinf)
+{
+	ID	tskid;
+
+	get_tid(&tskid);
+
+#if defined(SUPPORT_INET6)
+#if defined(SUPPORT_INET4)
+	syslog(LOG_NOTICE, "[TCPn DISCARD SRV:%d,%d] started.", tskid, (ID)exinf);
+#else
+	syslog(LOG_NOTICE, "[TCP6 DISCARD SRV:%d,%d] started.", tskid, (ID)exinf);
+#endif
+#else
+	syslog(LOG_NOTICE, "[TCP4 DISCARD SRV:%d,%d] started.", tskid, (ID)exinf);
+#endif
+
+	while (true) {
+		while (tcp_discard_srv((ID)exinf, TCP_DISCARD_SRV_REPID) == E_OK)
+			;
+		}
+	}
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_TCP_DISCARD_SRV */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.cfg	(revision 398)
@@ -0,0 +1,68 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP DISCARD サーバコンフィギュレーションファイル
+ */
+
+#ifdef USE_TCP_DISCARD_SRV
+
+/*
+ * タスク
+ */
+
+#ifdef USE_TCP_EXTENTIONS
+
+CRE_TSK(TCP_DISCARD_SRV_TASK,  {
+	TA_HLNG | TA_ACT,
+	0,
+	tcp_discard_srv_task,
+	TCP_DISCARD_SRV_MAIN_PRIORITY,
+	TCP_DISCARD_SRV_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+CRE_TSK(TCP_DISCARD_SRV_TASK,  {
+	TA_HLNG | TA_ACT,
+	TCP_DISCARD_SRV_CEPID,
+	tcp_discard_srv_task,
+	TCP_DISCARD_SRV_MAIN_PRIORITY,
+	TCP_DISCARD_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_TCP_DISCARD_SRV */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.h	(revision 398)
@@ -0,0 +1,76 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TCP_DISCARD_SRV_H_
+#define _TCP_DISCARD_SRV_H_
+
+/* スタックサイズ */
+
+#define TCP_DISCARD_SRV_STACK_SIZE	1024		/* TCP DISCARD サーバタスクのスタックサイズ */
+
+/* 優先度 */
+
+#define TCP_DISCARD_SRV_MAIN_PRIORITY	5	/* TCP DISCARD サーバタスクの優先度 */
+
+/*
+ *  TCP 送受信ウインドバッファサイズ
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_DISCARD_SRV_RWBUF_SIZE	(1024)
+
+#elif defined(SUPPORT_INET4)
+
+#define TCP_DISCARD_SRV_RWBUF_SIZE	(512)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define TCP_DISCARD_SRV_RWBUF_SIZE	(2048)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+/* TCP 送受信バッファ */
+
+extern uint8_t tcp_discard_srv_swbuf[];
+extern uint8_t tcp_discard_srv_rwbuf[];
+
+/* タスク */
+
+extern void tcp_discard_srv_task(intptr_t exinf);
+
+#endif	/* of #ifndef _TCP_DISCARD_SRV_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.c	(revision 398)
@@ -0,0 +1,495 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO クライアント
+ *
+ *    ・送受信タスク分離型
+ *    ・ノンブロッキングコール
+ *    ・省コピー API
+ *    ・IPv4
+ *    ・IPv6
+ */
+
+#include <stdlib.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_cli.h>
+
+#ifdef USE_TCP_ECHO_CLI
+
+/* echo サーバのポート番号 */
+
+#define ECHO_SRV_PORTNO		UINT_C(7)
+
+/* 緊急データの送信 */
+
+#ifdef USE_TCP_EXTENTIONS
+
+//#define SND_URG_DATA_SIZE	4
+#define SND_URG_COUNT		10
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/* 送信間隔 */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+//#define SND_DLY		(500)
+#define START_DLY	(10*SYSTIM_HZ)
+#define SND_ITV		(5*SYSTIM_HZ)
+#define SLP_ITV		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+//#define SND_DLY		(500)
+#define START_DLY	(10*SYSTIM_HZ)
+#define SND_ITV		(5*SYSTIM_HZ)
+#define SLP_ITV		(60*SYSTIM_HZ)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+/* 自動実行 */
+
+#if defined(TCP_ECHO_CLI_AUTO_RUN_STR)
+#else
+#if 0
+#if defined(SUPPORT_INET6)
+#define TCP_ECHO_CLI_AUTO_RUN_STR	"fd90:cce5:25f6:ff81:201:2ff:fe81:e7c9 - 0"
+#else
+#define TCP_ECHO_CLI_AUTO_RUN_STR	"172.25.129.140 - 0"
+#endif
+#endif
+#endif
+
+#if defined(SUPPORT_INET6)
+#if defined(SUPPORT_INET4)
+#define API_PROTO		'n'
+#else
+#define API_PROTO		'6'
+#endif
+#else
+#define API_PROTO		'4'
+#endif
+
+/*
+ *  全域変数
+ */
+
+bool_t	tcp_echo_cli_valid;
+uint_t	tcp_echo_cli_scount;
+
+/* TCP 送受信ウィンドバッファ */
+
+#ifndef TCP_CFG_SWBUF_CSAVE
+uint8_t tcp_echo_cli_swbuf[TCP_ECHO_CLI_SWBUF_SIZE];
+#endif
+
+#ifndef TCP_CFG_RWBUF_CSAVE
+uint8_t tcp_echo_cli_rwbuf[TCP_ECHO_CLI_RWBUF_SIZE];
+#endif
+
+#ifdef USE_TCP_NON_BLOCKING
+
+/*
+ *  全域変数
+ */
+
+ER_UINT	tcp_echo_cli_nblk_error;
+
+/*
+ *  ノンブロッキングコールのコールバック関数
+ */
+
+ER
+callback_nblk_tcp_echo_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	ER	error = E_OK;
+
+	tcp_echo_cli_nblk_error = *(ER*)p_parblk;
+
+	switch (fncd) {
+
+	case TFN_TCP_CON_CEP:
+		syscall(sig_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+		break;
+
+	case TFN_TCP_RCV_BUF:
+		if (tcp_echo_cli_nblk_error < 0)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CBN] error: %s",
+			                   API_PROTO, cepid, itron_strerror(tcp_echo_cli_nblk_error));
+		syscall(sig_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+		break;
+
+	case TFN_TCP_CLS_CEP:
+		if (tcp_echo_cli_nblk_error < 0)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CBN] error: %s",
+			                   API_PROTO, cepid, itron_strerror(tcp_echo_cli_nblk_error));
+		syscall(sig_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+		break;
+
+	case TFN_TCP_RCV_DAT:
+		if (tcp_echo_cli_nblk_error < 0)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CBN] error: %s",
+			                   API_PROTO, cepid, itron_strerror(tcp_echo_cli_nblk_error));
+		syscall(sig_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+		break;
+
+	case TFN_TCP_SND_OOB:
+		if (tcp_echo_cli_nblk_error > 0)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CBN] snd urg: %4u",
+			                   API_PROTO, cepid, tcp_echo_cli_nblk_error);
+		else
+			syslog(LOG_NOTICE, "[TEC%c:%02u CBN] error: %s",
+			                   API_PROTO, cepid, itron_strerror(tcp_echo_cli_nblk_error));
+		break;
+
+	case TFN_TCP_ACP_CEP:
+	case TFN_TCP_SND_DAT:
+	case TFN_TCP_GET_BUF:
+	default:
+		error = E_PAR;
+		break;
+		}
+	return error;
+	}
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+/*
+ *  getcomd -- コマンドを得る。
+ */
+
+#ifdef TCP_ECHO_CLI_AUTO_RUN_STR
+
+static char *
+getcomd (ID cepid, bool_t retry, char *apip)
+{
+	ER		error;
+	char		*line = NULL;
+	static char	auto_run_str[] = TCP_ECHO_CLI_AUTO_RUN_STR;
+	static int_t	count = 0;
+
+	if (retry || (count == 0)) {
+		line = auto_run_str;
+		dly_tsk(3 * 1000);
+		}
+	else {
+		while ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_SND, (intptr_t*)&line)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", API_PROTO, cepid, itron_strerror(error));
+			dly_tsk(SLP_ITV);
+			}
+		}
+
+	count ++;
+	return line;
+	}
+
+#else	/* of #ifdef TCP_ECHO_CLI_AUTO_RUN_STR */
+
+static char *
+getcomd (ID cepid, bool_t retry, char *apip)
+{
+	ER	error;
+	char	*line = NULL;
+
+	while ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_SND, (intptr_t*)&line)) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", API_PROTO, cepid, itron_strerror(error));
+		dly_tsk(SLP_ITV);
+		}
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+	if (*line == '6') {
+		line ++;
+		*apip = API_PROTO_IPV6;
+		}
+	else if (*line == '4') {
+		line ++;
+		*apip = API_PROTO_IPV4;
+		}
+	else {
+		*apip= DEFAULT_API_PROTO;
+		if (*line && *line != ' ')
+			line ++;
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	*apip= DEFAULT_API_PROTO;
+	if (*line && *line != ' ')
+		line ++;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	return line;
+	}
+
+#endif	/* of #ifdef TCP_ECHO_CLI_AUTO_RUN_STR */
+
+/*
+ *  TCP ECHO クライアント送信タスク
+ */
+
+/*
+ *  IP アドレスの指定
+ */
+
+#define ADDR_IPVn	'n'
+#define ADDR_IPV6	'6'
+#define ADDR_IPV4	'4'
+
+void
+tcp_echo_cli_snd_task (intptr_t exinf)
+{
+	ID		tskid, cepid;
+	ER		error;
+	T_IN_ADDR	addr;
+	char		*line;
+	int_t		rep, count;
+	bool_t		retry = false;
+	uint16_t	portno;
+	char		apip;
+
+#ifdef USE_TCP_EXTENTIONS
+
+	T_TCP_CCEP	ccep;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef TCP_ECHO_CLI_AUTO_RUN_STR
+	dly_tsk(START_DLY);
+#endif
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP%c ECHO CLI SND:%d,%d] started.", DEFAULT_API_PROTO, tskid, (ID)exinf);
+	while (true) {
+		line = skip_blanks(getcomd((ID)exinf, retry, &apip));
+
+#if defined(SUPPORT_INET6) && !defined(SUPPORT_INET4) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+		if (apip == API_PROTO_IPV4) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: E_PAR", API_PROTO, (ID)exinf);
+			retry = true;
+			continue;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET6) && !defined(SUPPORT_INET4) && !defined(API_CFG_IP4MAPPED_ADDR) */
+
+		if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] sleep %d.%03u[s], unknown host.",
+			       API_PROTO, (ID)exinf, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			dly_tsk(SLP_ITV);
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] resume.", API_PROTO, (ID)exinf);
+			retry = true;
+			continue;
+			}
+		else
+			retry = false;
+
+#if defined(SUPPORT_INET6)
+
+#if defined(USE_TCP4_ECHO_CLI)
+
+#else	/* of #if defined(USE_TCP4_ECHO_CLI) */
+
+		if (in6_is_addr_ipv4mapped(&addr))
+			apip = API_PROTO_IPV4;
+		else
+			apip = API_PROTO_IPV6;
+
+#endif	/* of #if defined(USE_TCP4_ECHO_CLI) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+		if (apip == API_PROTO_IPV6) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: E_PAR", API_PROTO, (ID)exinf);
+			retry = true;
+			continue;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {	/* Port No */
+			line = get_int(&rep, line);
+			portno = (uint16_t)rep;
+			}
+		else {
+			line ++;
+			portno = ECHO_SRV_PORTNO;
+			}
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9')	/* Repeat */
+			line = get_int(&rep, line);
+		else {
+			line ++;
+			rep = 1;
+			}
+
+#ifdef USE_TCP_EXTENTIONS
+
+		ccep.cepatr = 0;
+		ccep.sbufsz = TCP_ECHO_CLI_SWBUF_SIZE;
+		ccep.rbufsz = TCP_ECHO_CLI_RWBUF_SIZE;
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+		ccep.sbuf = NADR;
+#else
+		ccep.sbuf = tcp_echo_cli_swbuf;
+#endif
+#ifdef TCP_CFG_RWBUF_CSAVE
+		ccep.rbuf = NADR;
+#else
+		ccep.rbuf = tcp_echo_cli_rwbuf;
+#endif
+#ifdef USE_TCP_NON_BLOCKING
+		ccep.callback = (FP)callback_nblk_tcp_echo_cli;
+#else
+		ccep.callback = NULL;
+#endif
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+		if (apip == API_PROTO_IPV6) {
+			if ((error = alloc_tcp6_cep(&cepid, tskid, &ccep)) != E_OK) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", apip, cepid, itron_strerror(error));
+				continue;
+				}
+			}
+		else {
+			if ((error = alloc_tcp4_cep(&cepid, tskid, &ccep)) != E_OK) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", apip, cepid, itron_strerror(error));
+				continue;
+				}
+			}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+		if ((error = ALLOC_TCP_CEP(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", apip, cepid, itron_strerror(error));
+			continue;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+		if (apip == API_PROTO_IPV6)
+			cepid = (ID)exinf;
+		else
+			cepid = TCP4_ECHO_CLI_CEPID;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+		cepid = (ID)exinf;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		tcp_echo_cli_valid = true;
+		count = 0;
+		while (rep == 0 || count < rep) {
+			if (!tcp_echo_cli_valid) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] canceled.", apip, cepid);
+				break;
+				}
+
+			count ++;
+			if (rep == 0) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] start:       repeat: %d", apip, cepid, count);
+				error = tcp_echo_cli_snd(cepid, &addr, portno, apip);
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] finsh:       repeat: %d", apip, cepid, count);
+				}
+			else {
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] start:       repeat: %d/%d", apip, cepid, count, rep);
+				error = tcp_echo_cli_snd(cepid, &addr, portno, apip);
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] finsh:       repeat: %d/%d", apip, cepid, count, rep);
+				}
+
+			if (error != E_OK) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] sleep %d.%03u[s], error: %s",
+				                   apip, cepid, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ, itron_strerror(error));
+				tslp_tsk(SLP_ITV);
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] resume.", apip, cepid);
+				}
+
+#if defined(SND_ITV)
+#if SND_ITV > 0
+			if (count < rep) {
+				uint_t itv;
+				
+				itv = SND_ITV;
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] interval: %d[s].", apip, cepid, itv / SYSTIM_HZ);
+				syscall(dly_tsk(SND_ITV));
+				}
+#endif
+#endif
+			}
+
+#ifdef USE_TCP_EXTENTIONS
+
+		if ((error = FREE_TCP_CEP(cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", apip, cepid, itron_strerror(error));
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		}
+	}
+
+#endif	/* of #ifdef USE_TCP_ECHO_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.cfg	(revision 398)
@@ -0,0 +1,98 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO クライアント
+ *  コンフィギュレーションファイル
+ */
+
+#ifdef USE_TCP_ECHO_CLI
+
+/* タスク */
+
+#ifdef USE_TCP_EXTENTIONS
+
+CRE_TSK(TCP_ECHO_CLI_SND_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	tcp_echo_cli_snd_task,
+	TCP_ECHO_CLI_SND_MAIN_PRIORITY,
+	TCP_ECHO_CLI_SND_STACK_SIZE,
+	NULL
+	});
+
+CRE_TSK(TCP_ECHO_CLI_RCV_TASK,  {
+	TA_HLNG|TA_ACT,
+	0,
+	tcp_echo_cli_rcv_task,
+	TCP_ECHO_CLI_RCV_MAIN_PRIORITY,
+	TCP_ECHO_CLI_RCV_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+CRE_TSK(TCP_ECHO_CLI_SND_TASK, {
+	TA_HLNG|TA_ACT,
+	TCP_ECHO_CLI_CEPID,
+	tcp_echo_cli_snd_task,
+	TCP_ECHO_CLI_SND_MAIN_PRIORITY,
+	TCP_ECHO_CLI_SND_STACK_SIZE,
+	NULL
+	});
+
+CRE_TSK(TCP_ECHO_CLI_RCV_TASK,  {
+	TA_HLNG|TA_ACT,
+	TCP_ECHO_CLI_CEPID,
+	tcp_echo_cli_rcv_task,
+	TCP_ECHO_CLI_RCV_MAIN_PRIORITY,
+	TCP_ECHO_CLI_RCV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/* コマンドキュー */
+
+CRE_DTQ(DTQ_TCP_ECHO_CLI_SND,  { TA_TFIFO, 1, NULL });
+CRE_DTQ(DTQ_TCP_ECHO_CLI_RCV,  { TA_TFIFO, 1, NULL });
+
+/* セマフォ */
+
+#ifdef USE_TCP_NON_BLOCKING
+
+CRE_SEM(SEM_TCP_ECHO_CLI_NBLK_READY,	{ TA_TPRI, 0, 1 });
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef USE_TCP_ECHO_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.h	(revision 398)
@@ -0,0 +1,118 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TCP_ECHO_CLI_H_
+#define _TCP_ECHO_CLI_H_
+
+/* スタックサイズ */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define TCP_ECHO_CLI_RCV_STACK_SIZE	512		/* TCP ECHO クライアント受信タスクのスタックサイズ	*/
+#define TCP_ECHO_CLI_SND_STACK_SIZE	512		/* TCP ECHO クライアント送信タスクのスタックサイズ	*/
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#define TCP_ECHO_CLI_RCV_STACK_SIZE	1024		/* TCP ECHO クライアント受信タスクのスタックサイズ	*/
+#define TCP_ECHO_CLI_SND_STACK_SIZE	1024		/* TCP ECHO クライアント送信タスクのスタックサイズ	*/
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+/* 優先度 */
+
+#define TCP_ECHO_CLI_RCV_MAIN_PRIORITY	5		/* TCP ECHO クライアント受信タスクの優先度		*/
+#define TCP_ECHO_CLI_SND_MAIN_PRIORITY	5		/* TCP ECHO クライアント送信タスクの優先度		*/
+
+/*
+ *  TCP 送受信ウインドバッファサイズ
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_ECHO_CLI_SWBUF_SIZE		(1024)
+#define TCP_ECHO_CLI_RWBUF_SIZE		(1024)
+
+#elif defined(SUPPORT_INET4)
+
+#define TCP_ECHO_CLI_SWBUF_SIZE		(512)
+#define TCP_ECHO_CLI_RWBUF_SIZE		(512)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define TCP_ECHO_CLI_SWBUF_SIZE		(2048)
+#define TCP_ECHO_CLI_RWBUF_SIZE		(2048)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+/*
+ *  バッファサイズの定義
+ */
+
+#define NUM_ECHO		20
+#define NUM_REP_PAT		20
+#define PAT_BEGIN		' '
+#define PAT_END			'~'
+#define SND_BUF_SIZE		((PAT_END - PAT_BEGIN + 1) * NUM_REP_PAT)
+#define RCV_BUF_SIZE		(SND_BUF_SIZE*15/10)
+
+/*
+ *  変数
+ */
+
+extern bool_t	tcp_echo_cli_valid;
+extern uint_t	tcp_echo_cli_scount;
+extern ER_UINT	tcp_echo_cli_nblk_error;
+
+/* TCP 送受信バッファ */
+
+extern uint8_t tcp_echo_cli_swbuf[];
+extern uint8_t tcp_echo_cli_rwbuf[];
+
+/* タスク*/
+
+extern void	tcp_echo_cli_rcv_task(intptr_t exinf);
+extern void	tcp_echo_cli_snd_task(intptr_t exinf);
+
+/* 関数 */
+
+extern ER callback_nblk_tcp_echo_cli (ID cepid, FN fncd, void *p_parblk);
+
+#ifdef T_IN_ADDR
+extern ER tcp_echo_cli_snd (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char apip);
+#endif
+
+#endif	/* of #ifndef _TCP_ECHO_CLI_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_rcv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_rcv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_rcv.c	(revision 398)
@@ -0,0 +1,438 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO クライアント受信タスク
+ */
+
+#include <stdlib.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_cli.h>
+
+#ifdef USE_TCP_ECHO_CLI
+
+/* 表示 */
+
+//#define SHOW_TIME_OUT
+//#define SHOW_RCV_RANGE
+
+/* タイムアウト */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define CLS_TMO		TMO_FEVR					/* Close Wait は標準で 60秒 */
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+//#define CLS_TMO		TMO_FEVR				/* Close Wait は標準で 60秒 */
+#define CLS_TMO		(70*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*10)
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(40*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*20)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+/*
+ *  API IPプロトコルの指定
+ */
+
+#undef  DEFAULT_API_PROTO
+
+#if defined(SUPPORT_INET6)
+#if defined(SUPPORT_INET4)
+#define DEFAULT_API_PROTO	API_PROTO_IPVn
+#else
+#define DEFAULT_API_PROTO	API_PROTO_IPV6
+#endif
+#else
+#define DEFAULT_API_PROTO	API_PROTO_IPV4
+#endif
+
+/*
+ *  TCP ECHO クライアント受信タスク
+ */
+
+#ifdef USE_TCP_NON_BLOCKING
+
+#ifdef USE_COPYSAVE_API
+
+void
+tcp_echo_cli_rcv_task (intptr_t exinf)
+{
+	ID		tskid, cepid;
+	ER		error;
+	SYSTIM		time;
+	uint32_t	total, rcount;
+	uint16_t	roff, rlen;
+	char		*rmsg, head, tail, apip = DEFAULT_API_PROTO;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP%c ECHO CLI (NBLK,CS) RCV:%d] started.", DEFAULT_API_PROTO, tskid);
+	while (true) {
+		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s",
+			                   DEFAULT_API_PROTO, cepid, itron_strerror(error));
+			}
+                else {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+#ifdef USE_TCP_EXTENTIONS
+
+			apip = API_PROTO_IPVn;
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+			if (cepid == TCP4_ECHO_CLI_CEPID)
+				apip = API_PROTO_IPV4;
+			else
+				apip = API_PROTO_IPV6;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+			roff = rcount = total = 0;
+			while (true) {
+				if ((error = tcp_rcv_buf(cepid, (void**)&rmsg, TMO_NBLK)) != E_WBLK) {
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] error: %s", apip, cepid, itron_strerror(error));
+					break;
+					}
+
+				/* 受信バッファの獲得が完了するまで待つ。*/
+				syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+				if (tcp_echo_cli_nblk_error < 0)
+					break;
+
+				rlen = tcp_echo_cli_nblk_error;
+				head = *rmsg;
+				tail = *(rmsg + rlen - 1);
+				if (rlen > 0) {
+					roff  += rlen;
+					total += rlen;
+					rcount ++;
+#ifdef SHOW_RCV_RANGE
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] "
+					                   "count: %7lu, len: %4u, off: %4u, data: %02x -> %02x",
+					                   apip, cepid, rcount, rlen, roff, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+					}
+				else
+					break;
+
+				if ((error = tcp_rel_buf(cepid, rlen)) != E_OK)
+					syslog(LOG_NOTICE, "[TEC%c:%02u REL] error: %s", 
+					                   apip, cepid, itron_strerror(error));
+				}
+
+			if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK && error != E_OK)
+				syslog(LOG_NOTICE, "[TEC%c:%02u CLS] error: %s", apip, cepid, itron_strerror(error));
+
+			/* 切断が完了するまで待つ。*/
+			syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[TEC%c:%02u RCV] finsh: %7lu, ttl: %lu",
+			                   apip, cepid, time / SYSTIM_HZ, total);
+			}
+
+		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
+		}
+	}
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+void
+tcp_echo_cli_rcv_task (intptr_t exinf)
+{
+	static char rmsg[RCV_BUF_SIZE];
+
+	ID		tskid, cepid;
+	ER		error;
+	SYSTIM		time;
+	uint32_t	total, rcount;
+	uint16_t	roff, rlen;
+	char		head, tail, apip = DEFAULT_API_PROTO;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP%c ECHO CLI (NBLK) RCV:%d] started.", DEFAULT_API_PROTO, tskid);
+	while (true) {
+		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s",
+			                   DEFAULT_API_PROTO, cepid, itron_strerror(error));
+			}
+                else {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+			if (cepid == TCP4_ECHO_CLI_CEPID)
+				apip = API_PROTO_IPV4;
+			else
+				apip = API_PROTO_IPV6;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+			roff = rcount = total = 0;
+			while (true) {
+				if ((error = tcp_rcv_dat(cepid, rmsg, sizeof(rmsg), TMO_NBLK)) != E_WBLK) {
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] error: %s", apip, cepid, itron_strerror(error));
+					break;
+					}
+
+				/* 受信が完了するまで待つ。*/
+				syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+				if (tcp_echo_cli_nblk_error < 0)
+					break;
+
+				rlen = tcp_echo_cli_nblk_error;
+				head = *rmsg;
+				tail = *(rmsg + rlen - 1);
+				rcount ++;
+				if (rlen > 0) {
+					roff  += rlen;
+					total += rlen;
+#ifdef SHOW_RCV_RANGE
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] "
+					                   "count: %7lu, len: %4u, off: %4u, data: %02x -> %02x",
+					                   apip, cepid, rcount, rlen, roff, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+					}
+				else
+					break;
+				}
+
+			if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK && error != E_OK)
+				syslog(LOG_NOTICE, "[TEC%c:%02u CLS] error: %s", apip, cepid, itron_strerror(error));
+
+			/* 切断が完了するまで待つ。*/
+			syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[TEC%c:%02u RCV] finsh: %7lu, ttl: %lu",
+			                   apip, cepid, time / SYSTIM_HZ, total);
+			}
+
+		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
+		}
+	}
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#ifdef USE_COPYSAVE_API
+
+void
+tcp_echo_cli_rcv_task (intptr_t exinf)
+{
+	ID		tskid, cepid;
+	ER_UINT		rlen;
+	ER		error;
+	SYSTIM		time, tmo;
+	uint32_t	total = 0, rcount;
+	uint16_t	roff;
+	char		*rmsg, apip = DEFAULT_API_PROTO;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP%c ECHO CLI (CS) RCV:%d] started.", DEFAULT_API_PROTO, tskid);
+	while (true) {
+		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s",
+			                   DEFAULT_API_PROTO, cepid, itron_strerror(error));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+#ifdef USE_TCP_EXTENTIONS
+
+			if (tcp6_is_cepid(cepid))
+				apip = API_PROTO_IPV6;
+			else
+				apip = API_PROTO_IPV4;
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+			if (cepid == TCP4_ECHO_CLI_CEPID)
+				apip = API_PROTO_IPV4;
+			else
+				apip = API_PROTO_IPV6;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+			}
+		else {
+			roff = rcount = total = 0;
+			while (true) {
+				tmo = RCV_TMO;
+#ifdef SHOW_TIME_OUT
+				syslog(LOG_NOTICE, "[TEC%c:%02u RCV] tmo:   %7lu", apip, cepid, tmo);;
+#endif	/* of #ifdef SHOW_TIME_OUT */
+				if ((rlen = tcp_rcv_buf(cepid, (void**)&rmsg, tmo)) < 0) {
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] error: %s",
+					                   apip, cepid, itron_strerror(rlen));
+					break;
+					}
+				else if (rlen > 0) {
+					roff  += (uint16_t)rlen;
+					total +=     rlen;
+					rcount ++;
+#ifdef SHOW_RCV_RANGE
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] count: %7lu, len: %4u, data: %02x -> %02x",
+					                   apip, cepid, rcount, (uint16_t)rlen, *rmsg, *(rmsg + rlen - 1));
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+					}
+				else
+					break;
+				if ((error = tcp_rel_buf(cepid, rlen)) != E_OK)
+					syslog(LOG_NOTICE, "[TEC%c:%02u REL] error: %s", apip, cepid, itron_strerror(error));
+				}
+
+			tmo = CLS_TMO;
+#ifdef SHOW_TIME_OUT
+			syslog(LOG_NOTICE, "[TEC%c:%02u CLS] tmo:   %7lu", apip, cepid, tmo);;
+#endif	/* of #ifdef SHOW_TIME_OUT */
+			if ((error = tcp_cls_cep(cepid, tmo)) < 0)
+				syslog(LOG_NOTICE, "[TEC%c:%02u CLS] error: %s", apip, cepid, itron_strerror(error));
+
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[TEC%c:%02u RCV] finsh: %7lu, ttl: %lu",
+			                   apip, cepid, time / SYSTIM_HZ, total);
+			}
+
+		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
+		}
+	}
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+void
+tcp_echo_cli_rcv_task (intptr_t exinf)
+{
+	static char rmsg[RCV_BUF_SIZE];
+
+	ID		tskid, cepid;
+	ER_UINT		rlen;
+	ER		error;
+	SYSTIM		time, tmo;
+	uint32_t	total, rcount;
+	uint16_t	roff;
+	char		apip = DEFAULT_API_PROTO;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP%c ECHO CLI RCV:%d] started.", DEFAULT_API_PROTO, tskid);
+	while (true) {
+		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s",
+			                   DEFAULT_API_PROTO, cepid, itron_strerror(error));
+			}
+                else {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+			if (cepid == TCP4_ECHO_CLI_CEPID)
+				apip = API_PROTO_IPV4;
+			else
+				apip = API_PROTO_IPV6;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+			roff = rcount = total = 0;
+			while (true) {
+#ifdef SHOW_TIME_OUT
+				syslog(LOG_NOTICE, "[TEC%c:%02u RCV] tmo:   %7lu", apip, cepid, tmo);;
+#endif	/* of #ifdef SHOW_TIME_OUT */
+				tmo = RCV_TMO;
+				if ((rlen = tcp_rcv_dat(cepid, rmsg, sizeof(rmsg), tmo)) < 0) {
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] error: %s", apip, cepid, itron_strerror(rlen));
+					tcp_can_cep(cepid, TFN_TCP_ALL);
+					break;
+					}
+				else if (rlen > 0) {
+					roff  += (uint16_t)rlen;
+					total +=     rlen;
+					rcount ++;
+#ifdef SHOW_RCV_RANGE
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] count: %7lu, len: %4u, data: %02x -> %02x",
+					                   apip, cepid, rcount, (uint16_t)rlen, *rmsg, *(rmsg + rlen - 1));
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+					}
+				else
+					break;
+				}
+
+#ifdef SHOW_TIME_OUT
+			syslog(LOG_NOTICE, "[TEC%c:%02u CLS] tmo:   %7lu", apip, cepid, tmo);;
+#endif	/* of #ifdef SHOW_TIME_OUT */
+			tmo = CLS_TMO;
+			if ((error = tcp_cls_cep(cepid, tmo)) < 0)
+				syslog(LOG_NOTICE, "[TEC%c:%02u CLS] error: %s", apip, cepid, itron_strerror(error));
+
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[TEC%c:%02u RCV] finsh: %7lu, ttl: %lu",
+			                   apip, cepid, time / SYSTIM_HZ, total);
+			}
+
+		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
+		}
+	}
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef USE_TCP_ECHO_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_snd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_snd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_snd.c	(revision 398)
@@ -0,0 +1,483 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO クライアント送信関数
+ */
+
+#include <stdlib.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_cli.h>
+
+#ifdef USE_TCP_ECHO_CLI
+
+/* 表示 */
+
+//#define SHOW_TIME_OUT
+//#define SHOW_SND_COUNT
+
+/* タイムアウト */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define CON_TMO		TMO_FEVR
+//#define CON_TMO		(60*SYSTIM_HZ)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#define CON_TMO		TMO_FEVR
+//#define CON_TMO		(60*SYSTIM_HZ)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(30*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*30)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#ifdef USE_TCP_NON_BLOCKING
+
+/*
+ *  変数
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+static T_IPV4EP	nblk_src4 = {
+			IPV4_ADDRANY,
+			TCP_PORTANY,
+			};
+static T_IPV4EP	nblk_dst4;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+static T_IPEP	nblk_src = {
+			IP_ADDRANY,
+			TCP_PORTANY,
+			};
+static T_IPEP	nblk_dst;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+/*
+ *  tcp4_active_open -- 能動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ */
+
+static ER
+tcp4_active_open (ID cepid, T_IN4_ADDR ipaddr, uint16_t portno)
+{
+	ER		error;
+	SYSTIM		time;
+
+	nblk_dst4.ipaddr = ipaddr;
+	nblk_dst4.portno = portno;
+
+	if ((error = tcp_con_cep(cepid, &nblk_src4, &nblk_dst4, TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[TEC4:%02u CON] error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+
+	/* 接続が完了するまで待つ。*/
+	syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+
+	if ((error = tcp_echo_cli_nblk_error) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC4:%02u CON] error: %s", cepid, itron_strerror(tcp_echo_cli_nblk_error));
+		return error;
+		}
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TEC4:%02u CON] conct: %7lu,  to: %s.%u",
+	                   cepid, time / SYSTIM_HZ, ip2str(NULL, &nblk_dst4.ipaddr), nblk_dst4.portno);
+	return error;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+/*
+ *  tcp_active_open -- 能動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ */
+
+static ER
+tcp_active_open (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char apip)
+{
+	ER		error;
+	SYSTIM		time;
+
+	nblk_dst.ipaddr = *ipaddr;
+	nblk_dst.portno = portno;
+
+	if ((error = TCP_CON_CEP(cepid, &nblk_src, &nblk_dst, TMO_NBLK)) != E_WBLK) {
+		if (error == E_PAR || error == E_ID)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s, API: IPv%c, addr: %s",
+			                   apip, cepid, itron_strerror(error), apip, IP2STR(NULL, ipaddr));
+		else
+			syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s",
+			                   apip, cepid, itron_strerror(error));
+		return error;
+		}
+
+	/* 接続が完了するまで待つ。*/
+	syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+
+	if ((error = tcp_echo_cli_nblk_error) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s",
+		                   apip, cepid, itron_strerror(tcp_echo_cli_nblk_error));
+		return error;
+		}
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TEC%c:%02u CON] conct: %7lu,  to: %s.%u",
+	                   apip, cepid, time / SYSTIM_HZ,
+	                   IP2STR(NULL, &nblk_dst.ipaddr), nblk_dst.portno);
+	return error;
+	}
+
+/*
+ *  tcp_echo_cli_snd -- ECHO/TCP サーバにメッセージを送信する。
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ */
+
+ER
+tcp_echo_cli_snd (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char apip)
+{
+	static char smsg[SND_BUF_SIZE];
+
+	ER_UINT		slen;
+	ER		error;
+	uint32_t	total;
+	uint16_t	soff, echo, rep;
+	char		*p, pat;
+
+#ifdef SND_URG_DATA_SIZE
+	int_t	urg = SND_URG_COUNT;
+#endif
+
+	p = smsg;
+	for (rep = NUM_REP_PAT; rep -- > 0; )
+		for (pat = PAT_BEGIN; pat <= PAT_END; pat ++)
+			*p ++ = pat;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+	if (apip == API_PROTO_IPV6) {
+		if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+			return error;
+		}
+	else if (in6_is_addr_ipv4mapped(ipaddr)) {
+		if ((error = tcp4_active_open(cepid, ntohl(ipaddr->s6_addr32[3]), portno)) != E_OK)
+			return error;
+		}
+	else {
+		if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+			return error;
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+		return error;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	if ((error = psnd_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t)cepid)) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s", apip, cepid, itron_strerror(error));
+		goto cls_ret;
+		}
+
+	tcp_echo_cli_scount = total = 0;
+	for (echo = NUM_ECHO; echo -- > 0; ) {
+		soff = 0;
+		while (soff < SND_BUF_SIZE) {
+#ifdef SHOW_TIME_OUT
+			syslog(LOG_NOTICE, "[TEC%c:%02u SND] tmo:   %7lu", apip, cepid, SND_TMO);;
+#endif/* of #ifdef SHOW_TIME_OUT */
+			if ((slen = tcp_snd_dat(cepid, smsg + soff, sizeof(smsg) - soff, SND_TMO)) < 0) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u SND] error: %s",
+				                   apip, cepid, itron_strerror(slen));
+				error = slen;
+				goto cls_ret;
+				}
+			soff  += (uint16_t)slen;
+			total +=     slen;
+			tcp_echo_cli_scount ++;
+#ifdef SHOW_SND_COUNT
+			syslog(LOG_NOTICE, "[TEC%c:%02u SND] count: %7lu, len: %4u, off: %4u",
+			                   apip, cepid, tcp_echo_cli_scount, (uint16_t)slen, soff);
+#endif/* of #ifdef SHOW_SND_COUNT */
+
+#ifdef SND_URG_DATA_SIZE
+			if (urg) {
+				if (urg == 1) {
+					if ((error = tcp_snd_oob(cepid, smsg, SND_URG_DATA_SIZE, TMO_NBLK)) != E_WBLK)
+						syslog(LOG_NOTICE, "[TEC%c:%02u OOB] error: %s",
+						                   apip, cepid, itron_strerror(error));
+					}
+				urg --;
+				}
+#endif/* of #ifdef SND_URG_DATA_SIZE */
+
+#if defined(SND_DLY)
+#if SND_DLY > 0
+			syscall(dly_tsk(SND_DLY + netapp_rand() % SYSTIM_HZ));
+#endif
+#endif
+			}
+		}
+
+cls_ret:
+	if ((error = tcp_sht_cep(cepid)) < 0)
+		syslog(LOG_NOTICE, "[TEC%c:%02u SHT] error: %s", apip, cepid, itron_strerror(error));
+
+	/* 受信が完了するまで待つ。*/
+	syscall(slp_tsk());
+
+	return error;
+	}
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+/*
+ *  tcp4_active_open -- 能動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+static ER
+tcp4_active_open (ID cepid, T_IN4_ADDR ipaddr, uint16_t portno)
+{
+	static T_IPV4EP src = {
+		IPV4_ADDRANY,
+		TCP_PORTANY,
+		};
+
+	T_IPV4EP	dst;
+	ER		error;
+	SYSTIM		time;
+
+	dst.ipaddr = ipaddr;
+	dst.portno = portno;
+
+#ifdef SHOW_TIME_OUT
+	syslog(LOG_NOTICE, "[TEC%c:%02u CON] tmo:   %7lu", API_PROTO_IPV4, cepid, CON_TMO);
+#endif	/* of #ifdef SHOW_TIME_OUT */
+	if ((error = tcp_con_cep(cepid, &src, &dst, CON_TMO)) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s, addr: %s",
+		                   API_PROTO_IPV4, cepid, itron_strerror(error), ip2str(NULL, &ipaddr));
+		return error;
+		}
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TEC%c:%02u CON] conct: %7lu,  to: %s.%u",
+	                   API_PROTO_IPV4, cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno);
+	return error;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+/*
+ *  tcp_active_open -- 能動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+static ER
+tcp_active_open (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char apip)
+{
+	static T_IPEP src = {
+		IP_ADDRANY,
+		TCP_PORTANY,
+		};
+
+	T_IPEP		dst;
+	ER		error;
+	SYSTIM		time;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+
+#ifdef SHOW_TIME_OUT
+	syslog(LOG_NOTICE, "[TEC%c:%02u CON] tmo:   %7lu", apip, cepid, CON_TMO);
+#endif	/* of #ifdef SHOW_TIME_OUT */
+	if ((error = TCP_CON_CEP(cepid, &src, &dst, CON_TMO)) != E_OK) {
+		if (error == E_PAR || error == E_ID)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s, API: IPv%c, addr: %s",
+			                   apip, cepid, itron_strerror(error), apip, IP2STR(NULL, ipaddr));
+		else
+			syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s", apip, cepid, itron_strerror(error));
+		return error;
+		}
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TEC%c:%02u CON] conct: %7lu,  to: %s.%u",
+	                   apip, cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+	return error;
+	}
+
+/*
+ *  tcp_echo_cli_snd -- ECHO/TCP サーバにメッセージを送信する。
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+ER
+tcp_echo_cli_snd (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char apip)
+{
+	static char smsg[SND_BUF_SIZE];
+
+	ER_UINT		slen;
+	ER		error;
+	uint32_t	total;
+	uint16_t	soff, echo, rep;
+	char		*p, pat;
+
+#ifdef SND_URG_DATA_SIZE
+	int_t	urg = SND_URG_COUNT;
+#endif
+
+	p = smsg;
+	for (rep = NUM_REP_PAT; rep -- > 0; )
+		for (pat = PAT_BEGIN; pat <= PAT_END; pat ++)
+			*p ++ = pat;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+	if (apip == API_PROTO_IPV6) {
+		if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+			return error;
+		}
+	else if (in6_is_addr_ipv4mapped(ipaddr)) {
+		if ((error = tcp4_active_open(cepid, ntohl(ipaddr->s6_addr32[3]), portno)) != E_OK)
+			return error;
+		}
+	else {
+		if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+			return error;
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+		return error;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	if ((error = psnd_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t)cepid)) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s", apip, cepid, itron_strerror(error));
+		goto cls_ret;
+		}
+
+	tcp_echo_cli_scount = total = 0;
+	for (echo = NUM_ECHO; echo -- > 0; ) {
+		soff = 0;
+		while (soff < SND_BUF_SIZE) {
+#ifdef SHOW_TIME_OUT
+			syslog(LOG_NOTICE, "[TEC%c:%02u SND] tmo:   %7lu", apip, cepid, SND_TMO);
+#endif	/* of #ifdef SHOW_TIME_OUT */
+			if ((slen = tcp_snd_dat(cepid, smsg + soff, sizeof(smsg) - soff, SND_TMO)) < 0) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u SND] error: %s", apip, cepid, itron_strerror(slen));
+				error = slen;
+				goto cls_ret;
+				}
+			soff  += (uint16_t)slen;
+			total +=     slen;
+			tcp_echo_cli_scount ++;
+#ifdef SHOW_SND_COUNT
+			syslog(LOG_NOTICE, "[TEC%c:%02u SND] count: %7lu, len: %4u",
+			                   apip, cepid, tcp_echo_cli_scount, (uint16_t)slen);
+#endif	/* of #ifdef SHOW_SND_COUNT */
+
+#ifdef SND_URG_DATA_SIZE
+			if (urg > 0) {
+				if (urg == 1) {
+#ifdef SHOW_TIME_OUT
+					syslog(LOG_NOTICE, "[TEC%c:%02u SND] tmo:   %7lu", apip, cepid, SND_TMO);
+#endif	/* of #ifdef SHOW_TIME_OUT */
+					if ((slen = tcp_snd_oob(cepid, smsg, SND_URG_DATA_SIZE, SND_TMO)) >= 0)
+						syslog(LOG_NOTICE, "[TEC%c:%02u SND] urg:   %7lu",
+						                   apip, cepid, (uint16_6)slen);
+					else
+						syslog(LOG_NOTICE, "[TEC%c:%02u OOB] error: %s",
+						                   apip, cepid, itron_strerror(slen));
+					}
+				urg --;
+				}
+#endif	/* of #ifdef SND_URG_DATA_SIZE */
+
+#if defined(SND_DLY)
+#if SND_DLY > 0
+			syscall(dly_tsk(SND_DLY + netapp_rand() % SYSTIM_HZ));
+#endif
+#endif
+			}
+		}
+
+cls_ret:
+	if ((error = tcp_sht_cep(cepid)) < 0)
+		syslog(LOG_NOTICE, "[TEC%c:%02u SHT] error: %s", apip, cepid, itron_strerror(error));
+
+	/* 受信が完了するまで待つ。*/
+	syscall(slp_tsk());
+
+	return error;
+	}
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef USE_TCP_ECHO_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.c	(revision 398)
@@ -0,0 +1,558 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO サーバ #1
+ *
+ *    ・送受信タスク同一型
+ *    ・ノンブロッキングコール
+ *    ・省コピー API
+ *    ・IPv4/IPv6
+ *    ・緊急データの受信
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_srv1.h>
+#include <netapp/tcp_echo_srv1_var.h>
+
+#if defined(_NET_CFG_BYTE_ORDER)
+#error "net/net.h included."
+#endif
+
+#ifdef USE_TCP_ECHO_SRV1
+
+/*
+ *  表示
+ */
+
+//#define SHOW_RCV_RANGE
+
+/*
+ *  コネクション切断方法の指定
+ */
+
+#define USE_TCP_SHT_CEP
+
+/*
+ *  タイムアウト
+ */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define CLS_TMO		TMO_FEVR		/* Close Wait は標準で 60秒 */
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+//#define CLS_TMO		TMO_FEVR	/* Close Wait は標準で 60秒 */
+#define CLS_TMO		(70*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*10)
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*30)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(40*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*20)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+/*
+ *  全域変数
+ */
+
+/* TCP 送受信ウィンドバッファ */
+
+#ifndef TCP_CFG_SWBUF_CSAVE
+uint8_t tcp_echo_srv_swbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_SWBUF_SIZE];
+#endif
+
+#ifndef TCP_CFG_RWBUF_CSAVE
+uint8_t tcp_echo_srv_rwbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_RWBUF_SIZE];
+#endif
+
+#ifndef USE_TCP_NON_BLOCKING
+
+/*
+ *  変数
+ */
+
+#ifdef USE_TCP_EXTENTIONS
+
+T_TCP_ECHO_SRV_INFO tcp_echo_srv_info[NUM_TCP_ECHO_SRV_TASKS];
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+T_TCP_ECHO_SRV_INFO tcp_echo_srv_info[] = {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV)
+
+	{ TCP4_ECHO_SRV_CEPID1, TCP4_ECHO_SRV_REPID },
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+	{ TCP_ECHO_SRV_CEPID1, TCP_ECHO_SRV_REPID },
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+	{ TCP_ECHO_SRV_CEPID2, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+	{ TCP_ECHO_SRV_CEPID3, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+	{ TCP_ECHO_SRV_CEPID4, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+	{ TCP_ECHO_SRV_CEPID5, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+	{ TCP_ECHO_SRV_CEPID6, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+	{ TCP_ECHO_SRV_CEPID7, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+	{ TCP_ECHO_SRV_CEPID8, TCP_ECHO_SRV_REPID },
+#endif
+
+	};
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/*
+ *  tcp_passive_open -- 受動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+static ER
+tcp_passive_open (T_TCP_ECHO_SRV_INFO *info, char apip)
+{
+	ER		error = E_OK;
+
+#if TNUM_TCP4_REPID > 0
+	T_IPV4EP	dst4;
+#endif
+
+	if (apip == API_PROTO_IPV6) {
+
+#if TNUM_TCP6_REPID > 0
+
+		/* 受付口は IPv6 */
+		if ((error = tcp6_acp_cep(info->cepid, info->repid, &info->dst, TMO_FEVR)) != E_OK)
+			return error;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp6_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #if TNUM_TCP6_REPID > 0 */
+
+		}
+	else {
+
+#if TNUM_TCP4_REPID > 0
+
+		/* 受付口は IPv4 */
+		if ((error = tcp_acp_cep(info->cepid, info->repid, &dst4, TMO_FEVR)) != E_OK)
+			return error;
+		in6_make_ipv4mapped (&info->dst.ipaddr, dst4.ipaddr);
+		info->dst.portno = dst4.portno;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp4_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #if TNUM_TCP4_REPID > 0 */
+
+		}
+
+	return error;
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  tcp_passive_open -- 受動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+static ER
+tcp_passive_open (T_TCP_ECHO_SRV_INFO *info, char apip)
+{
+	ER		error = E_OK;
+
+	if ((error = TCP_ACP_CEP(info->cepid, info->repid, &info->dst, TMO_FEVR)) != E_OK)
+		return error;
+
+#ifdef USE_TCP_EXTENTIONS
+	if ((error = FREE_TCP_REP(info->repid, true)) != E_OK)
+		return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	return error;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+#ifdef USE_COPYSAVE_API
+
+/*
+ *  tcp_echo_srv -- TCP エコーサーバ
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ *    USE_COPYSAVE_API		ON
+ */
+
+ER
+tcp_echo_srv (uint_t six, char apip)
+{
+	ER		error = E_OK;
+	ER_UINT		rblen, sblen;
+	SYSTIM		now;
+	uint32_t	total;
+	uint16_t	rlen, slen, soff, scount, rcount;
+	char		*rbuf, *sbuf;
+
+#ifdef SHOW_RCV_RANGE
+	char		head, tail;
+#endif
+
+	if ((error = tcp_passive_open(&tcp_echo_srv_info[six], apip)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES%c:%02u OPN] error: %s",
+		                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+		return error;
+		}
+
+	syscall(get_tim(&now));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if (apip == API_PROTO_IPV6)
+		syslog(LOG_NOTICE, "[TES6:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ipv62str(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+		                   tcp_echo_srv_info[six].dst.portno);
+	else {
+		T_IN4_ADDR	addr;
+
+		addr = ntohl(tcp_echo_srv_info[six].dst.ipaddr.s6_addr32[3]);
+		syslog(LOG_NOTICE, "[TES4:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ip2str(NULL, &addr), tcp_echo_srv_info[six].dst.portno);
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	syslog(LOG_NOTICE, "[TES%c:%02u ACP] conct: %7lu,from: %s.%u",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+	                   IP2STR(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+	                   tcp_echo_srv_info[six].dst.portno);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	scount = rcount = total = 0;
+	while (true) {
+		if ((rblen = tcp_rcv_buf(tcp_echo_srv_info[six].cepid, (void**)&rbuf, RCV_TMO)) <= 0) {
+			if (rblen != E_OK)
+				syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s",
+				                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(rblen));
+			break;
+			}
+
+		rcount ++;
+
+#ifdef SHOW_RCV_RANGE
+		head = *rbuf;
+		tail = *(rbuf + rblen - 1);
+
+		//syslog(LOG_NOTICE, "[TES%c:%02u RCV] len:   %7lu",
+		//                   apip, tcp_echo_srv_info[six].cepid, (uint16_t)rblen);
+		syslog(LOG_NOTICE, "[TES%c:%02u RCV] rcount: %7lu, len: %6lu, data %02x -> %02x",
+		                   apip, tcp_echo_srv_info[six].cepid, rcount, (uint16_t)rblen, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+		rlen   = (uint16_t)rblen;
+		total +=     rblen;
+		soff = 0;
+		while (rlen > 0) {
+
+			if ((sblen = tcp_get_buf(tcp_echo_srv_info[six].cepid, (void**)&sbuf, SND_TMO)) < 0) {
+				syslog(LOG_NOTICE, "[TES%c:%02u GET] error: %s",
+				                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(sblen));
+				goto err_fin;
+				}
+
+			//syslog(LOG_NOTICE, "[TES%c:%02u SND] len:   %7lu",
+			//                   apip, tcp_echo_srv_info[six].cepid, (uint16_t)sblen);
+			scount ++;
+			slen = rlen < (uint16_t)sblen ? rlen : (uint16_t)sblen;
+			memcpy(sbuf, rbuf + soff, slen);
+			if ((error = tcp_snd_buf(tcp_echo_srv_info[six].cepid, slen)) != E_OK) {
+				syslog(LOG_NOTICE, "[TES%c:%02u SND] error: %s",
+				                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+				goto err_fin;
+				}
+#ifdef SHOW_RCV_RANGE
+			syslog(LOG_NOTICE, "[TES%c:%02u SND] scount: %4u, len: %4u",
+			                   apip, tcp_echo_srv_info[six].cepid, scount, slen);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+			rlen -= slen;
+			soff += slen;
+			}
+
+		if ((error = tcp_rel_buf(tcp_echo_srv_info[six].cepid, rblen)) < 0) {
+			syslog(LOG_NOTICE, "[TES%c:%02u REL] error: %s",
+			                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+			break;
+			}
+		}
+err_fin:
+
+#ifdef USE_TCP_SHT_CEP
+	if ((error = tcp_sht_cep(tcp_echo_srv_info[six].cepid)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u SHT] error: %s",
+		                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+#endif	/* of #ifdef USE_TCP_SHT_CEP */
+
+	if ((error = tcp_cls_cep(tcp_echo_srv_info[six].cepid, CLS_TMO)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u CLS] error: %s",
+		                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+
+	syscall(get_tim(&now));
+#if 1
+	syslog(LOG_NOTICE, "[TES%c:%02u FIN] finsh: %7lu, ttl: %lu",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ, total);
+#else
+	syslog(LOG_NOTICE, "[TES%c:%02u FIN] finsh: %7lu, ttl: %lu, error: %s",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ, total, itron_strerror(error));
+#endif
+
+	return error;
+	}
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+/*
+ *  tcp_echo_srv -- TCP エコーサーバ
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ *    USE_COPYSAVE_API		OFF
+ */
+
+ER
+tcp_echo_srv (uint_t six, char apip)
+{
+	ID		cepid;
+	ER		error = E_OK;
+	ER_UINT		rlen, slen;
+	SYSTIM		now;
+	uint32_t	total;
+	uint16_t	soff, scount, rcount;
+
+	if ((error = tcp_passive_open(&tcp_echo_srv_info[six], apip)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES%c:%02u OPN] error: %s",
+		                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+		return error;
+		}
+	
+	syscall(get_tim(&now));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if (apip == API_PROTO_IPV6)
+		syslog(LOG_NOTICE, "[TES6:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ipv62str(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+		                   tcp_echo_srv_info[six].dst.portno);
+	else	{
+		T_IN4_ADDR	addr;
+
+		addr = ntohl(tcp_echo_srv_info[six].dst.ipaddr.s6_addr32[3]);
+		syslog(LOG_NOTICE, "[TES4:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ip2str(NULL, &addr), tcp_echo_srv_info[six].dst.portno);
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	syslog(LOG_NOTICE, "[TES%c:%02u ACP] conct: %7lu,from: %s.%u",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+	                   IP2STR(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+	                   tcp_echo_srv_info[six].dst.portno);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	cepid =  tcp_echo_srv_info[six].cepid;
+	scount = rcount = total = 0;
+	while (true) {
+		if ((rlen = tcp_rcv_dat(cepid, tcp_echo_srv_info[six].buffer, BUF_SIZE - 1, RCV_TMO)) <= 0) {
+			if (rlen != E_OK)
+				syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s",
+				                   apip, cepid, itron_strerror(rlen));
+			break;
+			}
+
+		rcount ++;
+#ifdef SHOW_RCV_RANGE
+		syslog(LOG_NOTICE, "[TES%c:%02u RCV] rcount: %4u, len: %4u, data %02x -> %02x",
+		                   apip, cepid, rcount,
+		                   (uint16_t)rlen, * tcp_echo_srv_info[six].tcp_echo_srv_info[six].buffer,
+		                                   *(tcp_echo_srv_info[six].tcp_echo_srv_info[six].buffer + rlen - 1));
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+		total += rlen;
+		soff = 0;
+		while (rlen > 0) {
+			scount ++;
+			if ((slen = tcp_snd_dat(cepid, &tcp_echo_srv_info[six].buffer[soff], rlen, SND_TMO)) < 0) {
+				syslog(LOG_NOTICE, "[TES%c:%02u SND] error: %s",
+				                   apip, cepid, itron_strerror(slen));
+				goto err_fin;
+				}
+#ifdef SHOW_RCV_RANGE
+			syslog(LOG_NOTICE, "[TES%c:%02u SND] scount: %4u, len: %4u",
+			                   apip, cepid, scount, (uint16_t)slen);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+			rlen -= slen;
+			soff += slen;
+			}
+		}
+err_fin:
+
+#ifdef USE_TCP_SHT_CEP
+	if ((error = tcp_sht_cep(cepid)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u SHT] error: %s", 
+		                    apip, cepid, itron_strerror(error));
+#endif	/* of #ifdef USE_TCP_SHT_CEP */
+
+	if ((error = tcp_cls_cep(cepid, CLS_TMO)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u CLS] error: %s",
+		                   apip, cepid, itron_strerror(error));
+
+	syscall(get_tim(&now));
+	syslog(LOG_NOTICE, "[TES%c:%02u FIN] finsh: %7lu, ttl: %lu",
+	                   apip, cepid, now / SYSTIM_HZ, total);
+
+	return error;
+	}
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+#endif	/* of #ifndef USE_TCP_NON_BLOCKING */
+
+#ifndef USE_TCP_EXTENTIONS
+
+/*
+ *  tcp_echo_srv_task -- TCP エコーサーバタスク
+ */
+
+void
+tcp_echo_srv_task(intptr_t exinf)
+{
+	ID	tskid, cepid;
+	ER	error;
+	uint_t	six;
+	char	apip;
+
+	six = INDEX_SRV_INFO((ID)exinf);
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV)
+
+	if (six >= NUM_TCP4_ECHO_SRV_TASKS)
+		apip = API_PROTO_IPV6;
+	else
+		apip = API_PROTO_IPV4;
+
+#else	/* of #if defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+	apip = API_PROTO_IPV6;
+
+#endif	/* of #if defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+	apip = API_PROTO_IPV4;
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+	syscall(get_tid(&tskid));
+	cepid = tcp_echo_srv_info[six].cepid;
+	syslog(LOG_NOTICE, "[TCP%c ECHO SRV:%d,%d] started.", apip, tskid, cepid);
+
+	while (true) {
+		while ((error = tcp_echo_srv(six, apip)) == E_OK)
+			;
+		syslog(LOG_NOTICE, "[TES%c:%02u TSK] sleep 60[s], error: %s", apip, cepid, itron_strerror(error));
+		tslp_tsk(60 * 1000 * 1000);
+		syslog(LOG_NOTICE, "[TES%c:%02u TSK] resume.", apip, cepid);
+		}
+	}
+
+#endif	/* of #ifndef USE_TCP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.cfg	(revision 398)
@@ -0,0 +1,173 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO サーバ #1、送受信タスク同一型
+ *  コンフィギュレーションファイル
+ */
+
+#ifdef USE_TCP_ECHO_SRV1
+
+/* タスク */
+
+CRE_TSK(TCP_ECHO_SRV_TASK1,  {
+	TA_HLNG | TA_ACT,
+	1,
+	tcp_echo_srv_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+
+CRE_TSK(TCP_ECHO_SRV_TASK2,  {
+	TA_HLNG | TA_ACT,
+	2,
+	tcp_echo_srv_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+
+CRE_TSK(TCP_ECHO_SRV_TASK3,  {
+	TA_HLNG | TA_ACT,
+	3,
+	tcp_echo_srv_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+
+CRE_TSK(TCP_ECHO_SRV_TASK4,  {
+	TA_HLNG | TA_ACT,
+	4,
+	tcp_echo_srv_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+
+CRE_TSK(TCP_ECHO_SRV_TASK5,  {
+	TA_HLNG | TA_ACT,
+	5,
+	tcp_echo_srv_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+
+CRE_TSK(TCP_ECHO_SRV_TASK6,  {
+	TA_HLNG | TA_ACT,
+	6,
+	tcp_echo_srv_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+
+CRE_TSK(TCP_ECHO_SRV_TASK7,  {
+	TA_HLNG | TA_ACT,
+	7,
+	tcp_echo_srv_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+
+CRE_TSK(TCP_ECHO_SRV_TASK8,  {
+	TA_HLNG | TA_ACT,
+	8,
+	tcp_echo_srv_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
+
+/* セマフォ */
+
+#ifdef USE_TCP_NON_BLOCKING
+
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY1,	{ TA_TPRI, 0, 1 });
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY2,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY3,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY4,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY5,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY6,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY7,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY8,	{ TA_TPRI, 0, 1 });
+#endif
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.h	(revision 398)
@@ -0,0 +1,121 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifdef USE_TCP_ECHO_SRV1
+
+#ifndef _TCP_ECHO_SRV1_H_
+#define _TCP_ECHO_SRV1_H_
+
+/* 
+ *  TCP ECHO サーバ #1
+ *
+ *    ・送受信タスク同一型
+ *    ・ノンブロッキングコール
+ *    ・省コピー API
+ *    ・IPv4/IPv6
+ *    ・緊急データの受信
+ */
+
+/* スタックサイズ */
+
+#define TCP_ECHO_SRV_STACK_SIZE		1024		/* TCP ECHO サーバタスクのスタックサイズ		*/
+
+/* 優先度 */
+
+#define TCP_ECHO_SRV_MAIN_PRIORITY	5		/* TCP ECHO サーバタスクの優先度			*/
+
+/*
+ *  TCP 送受信ウインドバッファサイズ
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(1024)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(1024)
+
+#elif defined(SUPPORT_INET4)
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(512)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(512)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(1024)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(1024)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+/*
+ *  タスク数
+ */
+
+#ifndef NUM_TCP_ECHO_SRV_TASKS
+#define NUM_TCP_ECHO_SRV_TASKS		1
+#endif
+
+/* IPv4 用の TCP エコーサーバタスクは 1個に制限する。*/
+
+#ifdef  NUM_TCP4_ECHO_SRV_TASKS
+#undef  NUM_TCP4_ECHO_SRV_TASKS
+#endif
+#define NUM_TCP4_ECHO_SRV_TASKS		1
+
+/*
+ *  変数
+ */
+
+/* TCP 送受信ウィンドバッファ */
+
+extern uint8_t tcp_echo_srv_swbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_SWBUF_SIZE];
+extern uint8_t tcp_echo_srv_rwbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_RWBUF_SIZE];
+
+/*
+ *  タスク
+ */
+
+extern void	tcp_echo_srv_task(intptr_t exinf);
+
+/*
+ *  関数
+ */
+
+extern ER callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk);
+extern ER wakeup_tcp_echo_srv (char apip);
+
+#endif	/* of #ifndef _TCP_ECHO_SRV1_H_ */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_ext.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_ext.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_ext.c	(revision 398)
@@ -0,0 +1,368 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO サーバ #1
+ *
+ *    ・送受信タスク同一型
+ *    ・ノンブロッキングコール
+ *    ・省コピー API
+ *    ・IPv4/IPv6
+ *    ・緊急データの受信
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_srv1.h>
+#include <netapp/tcp_echo_srv1_var.h>
+
+#ifdef USE_TCP_ECHO_SRV1
+
+/*
+ *  表示
+ */
+
+//#define SHOW_RCV_RANGE
+
+/*
+ *  コネクション切断方法の指定
+ */
+
+#define USE_TCP_SHT_CEP
+
+/*
+ *  タイムアウト
+ */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define CLS_TMO		TMO_FEVR		/* Close Wait は標準で 60秒 */
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+//#define CLS_TMO		TMO_FEVR	/* Close Wait は標準で 60秒 */
+#define CLS_TMO		(70*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*10)
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*30)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(40*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*20)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#ifdef USE_TCP_EXTENTIONS
+
+/*
+ *  変数
+ */
+
+typedef struct t_tcp_echo_srv_task_info {
+	ID	taskid;		/* タスク ID		*/
+	bool_t	active;		/* 動作状態		*/
+	char	apip;		/* API IPプロトコル	*/
+	} T_TCP_ECHO_SRV_TASK_INFO;
+
+static T_TCP_ECHO_SRV_TASK_INFO tcp_echo_srv_task_info[NUM_TCP_ECHO_SRV_TASKS] = {
+
+				{ TCP_ECHO_SRV_TASK1, false },
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+				{ TCP_ECHO_SRV_TASK2, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+				{ TCP_ECHO_SRV_TASK3, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+				{ TCP_ECHO_SRV_TASK4, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+				{ TCP_ECHO_SRV_TASK5, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+				{ TCP_ECHO_SRV_TASK6, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+				{ TCP_ECHO_SRV_TASK7, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+				{ TCP_ECHO_SRV_TASK8, false },
+#endif
+
+			};
+
+/*
+ *  get_tcp_rep -- TCP 受付口を獲得する。
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+static ER
+get_tcp_rep (ID *repid, char apip)
+{
+	ID		tskid;
+	T_TCP6_CREP	crep6;
+	T_TCP_CREP	crep4;
+
+	get_tid(&tskid);
+	if (apip == API_PROTO_IPV6) {
+		crep6.repatr = UINT_C(0);
+		crep6.myaddr.portno = UINT_C(7);
+		memcpy(&crep6.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+		return alloc_tcp6_rep(repid, tskid, &crep6);
+		}
+	else {
+		crep4.repatr = UINT_C(0);
+		crep4.myaddr.portno = UINT_C(7);
+		crep4.myaddr.ipaddr = IPV4_ADDRANY;
+		return alloc_tcp4_rep(repid, tskid, &crep4);
+		}
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+static ER
+get_tcp_rep (ID *repid, char apip)
+{
+	ID		tskid;
+	T_TCPN_CREP	crep;
+
+	get_tid(&tskid);
+
+	crep.repatr = UINT_C(0);
+	crep.myaddr.portno = UINT_C(7);
+
+#if defined(SUPPORT_INET6)
+
+	memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#else	/* #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+	crep.myaddr.ipaddr = IPV4_ADDRANY;
+#endif
+
+#endif	/* #if defined(SUPPORT_INET6) */
+
+	return ALLOC_TCP_REP(repid, tskid, &crep);
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  get_tcp_cep -- TCP 通信端点を獲得する。
+ */
+
+static ER
+get_tcp_cep (ID *cepid, char apip)
+{
+	ID		tskid;
+	T_TCP_CCEP	ccep;
+
+	get_tid(&tskid);
+
+	ccep.cepatr = UINT_C(0);
+	ccep.sbufsz = TCP_ECHO_SRV_SWBUF_SIZE;
+	ccep.rbufsz = TCP_ECHO_SRV_RWBUF_SIZE;
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+	ccep.sbuf = NADR;
+#else
+	ccep.sbuf = tcp_echo_srv_swbuf;
+#endif
+#ifdef TCP_CFG_RWBUF_CSAVE
+	ccep.rbuf = NADR;
+#else
+	ccep.rbuf = tcp_echo_srv_rwbuf;
+#endif
+#ifdef USE_TCP_NON_BLOCKING
+	ccep.callback = (FP)callback_nblk_tcp_echo_srv;
+#else
+	ccep.callback = NULL;
+#endif
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if (apip == API_PROTO_IPV6)
+		return alloc_tcp6_cep(cepid, tskid, &ccep);
+	else
+		return alloc_tcp4_cep(cepid, tskid, &ccep);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	return ALLOC_TCP_CEP(cepid, tskid, &ccep);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	}
+
+/*
+ *  wakeup_tcp_echo_srv -- TCP エコーサーバタスクの休止解除
+ */
+
+ER
+wakeup_tcp_echo_srv (char apip)
+{
+	int	ix;
+
+	for (ix = NUM_TCP_ECHO_SRV_TASKS; -- ix >= 0; )
+		if (!tcp_echo_srv_task_info[ix].active) {
+			syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] wake up.",
+			                   apip, tcp_echo_srv_task_info[ix].taskid);
+			tcp_echo_srv_task_info[ix].apip   = apip;
+			tcp_echo_srv_task_info[ix].active = true;
+			return syscall(wup_tsk(tcp_echo_srv_task_info[ix].taskid));
+			}
+	syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] wake up error: %s.",
+			   apip, tcp_echo_srv_task_info[ix].taskid, itron_strerror(E_ID));
+	return E_ID;
+	}
+
+/*
+ *  tcp_echo_srv_task -- TCP エコーサーバタスク
+ */
+
+void
+tcp_echo_srv_task (intptr_t exinf)
+{
+	ID	tskid;
+	ER	error = E_OK;
+	int	ix;
+	char	apip;
+
+	syscall(get_tid(&tskid));
+	syslog(LOG_NOTICE, "[TCPn ECHO SRV(EXT):%d] started.", tskid);
+	while (true) {
+		syslog(LOG_NOTICE, "[TCPn ECHO SRV(EXT):%d] goto sleep.", tskid);
+		syscall(slp_tsk());
+
+		for (ix = NUM_TCP_ECHO_SRV_TASKS; -- ix >= 0; ) {
+			if (tcp_echo_srv_task_info[ix].taskid == tskid) {
+				break;
+				}
+			}
+
+		apip = tcp_echo_srv_task_info[ix].apip;
+		if ((error = get_tcp_cep(&tcp_echo_srv_info[ix].cepid, apip)) != E_OK) {
+			syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] create CEP error: %s",
+		                           apip, tskid, itron_strerror(error));
+			continue;
+			}
+
+		while (true) {
+
+			if ((error = get_tcp_rep(&tcp_echo_srv_info[ix].repid, apip)) != E_OK) {
+				syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] create REP error: %s",
+		                                   apip, tskid, itron_strerror(error));
+				break;
+				}
+			else if ((error = tcp_echo_srv(ix, apip)) != E_OK) {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+				if (apip == API_PROTO_IPV6)
+					error = free_tcp6_rep(tcp_echo_srv_info[ix].repid, error != E_DLT);
+				else
+					error = free_tcp4_rep(tcp_echo_srv_info[ix].repid, error != E_DLT);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+				error = FREE_TCP_REP(tcp_echo_srv_info[ix].repid, error != E_DLT);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+				if (error != E_OK) {
+					syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] delete REP error: %s",
+		                                           apip, tskid, itron_strerror(error));
+					}
+
+				break;
+				}
+			}
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+		if (apip == API_PROTO_IPV6)
+			error = free_tcp6_cep(tcp_echo_srv_info[ix].cepid);
+		else
+			error = free_tcp4_cep(tcp_echo_srv_info[ix].cepid);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		error = FREE_TCP_CEP(tcp_echo_srv_info[ix].cepid);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		if (error != E_OK) {
+			syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] delete CEP error: %s",
+		                           apip, tskid, itron_strerror(error));
+			}
+
+		for (ix = NUM_TCP_ECHO_SRV_TASKS; -- ix >= 0; ) {
+			if (tcp_echo_srv_task_info[ix].taskid == tskid) {
+				tcp_echo_srv_task_info[ix].active = false;
+				break;
+				}
+			}
+
+		}
+	}
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_nblk.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_nblk.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_nblk.c	(revision 398)
@@ -0,0 +1,634 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO サーバ #1
+ *
+ *    ・送受信タスク同一型
+ *    ・ノンブロッキングコール
+ *    ・省コピー API
+ *    ・IPv4/IPv6
+ *    ・緊急データの受信
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_srv1.h>
+#include <netapp/tcp_echo_srv1_var.h>
+
+#ifdef USE_TCP_ECHO_SRV1
+
+/*
+ *  表示
+ */
+
+//#define SHOW_RCV_RANGE
+
+/*
+ *  コネクション切断方法の指定
+ */
+
+#define USE_TCP_SHT_CEP
+
+/*
+ *  タイムアウト
+ */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define CLS_TMO		TMO_FEVR		/* Close Wait は標準で 60秒 */
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+//#define CLS_TMO		TMO_FEVR	/* Close Wait は標準で 60秒 */
+#define CLS_TMO		(70*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*10)
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*30)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(40*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*20)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#ifdef USE_TCP_NON_BLOCKING
+
+/*
+ *  変数
+ */
+
+#ifdef USE_TCP_EXTENTIONS
+
+T_TCP_ECHO_SRV_INFO tcp_echo_srv_info[] = {
+
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY1 },
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY2 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY3 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY4 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY5 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY6 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY7 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY8 },
+#endif
+
+	};
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+T_TCP_ECHO_SRV_INFO tcp_echo_srv_info[] = {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV)
+
+	{ TCP4_ECHO_SRV_CEPID1, TCP4_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY1 },
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+	{ TCP_ECHO_SRV_CEPID1, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY1 },
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+	{ TCP_ECHO_SRV_CEPID2, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY2 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+	{ TCP_ECHO_SRV_CEPID3, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY3 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+	{ TCP_ECHO_SRV_CEPID4, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY4 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+	{ TCP_ECHO_SRV_CEPID5, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY5 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+	{ TCP_ECHO_SRV_CEPID6, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY6 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+	{ TCP_ECHO_SRV_CEPID7, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY7 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+	{ TCP_ECHO_SRV_CEPID8, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY8 },
+#endif
+
+	};
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/*
+ *  find_srv_info -- 接続相手の情報構造体を探索する。
+ */
+
+static 
+T_TCP_ECHO_SRV_INFO *find_srv_info (ID cepid)
+{
+	T_TCP_ECHO_SRV_INFO	*ri;
+
+	for (ri = &tcp_echo_srv_info[sizeof(tcp_echo_srv_info) / sizeof(T_TCP_ECHO_SRV_INFO)]; ri --; )
+		if (ri->cepid == cepid)
+			return ri;
+	return NULL;
+	}
+
+/*
+ *  ノンブロッキングコールのコールバック関数
+ */
+
+ER
+callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	ER		error = E_OK;
+	T_TCP_ECHO_SRV_INFO	*ri;
+
+	if ((ri = find_srv_info(cepid)) == NULL) {
+		syslog(LOG_NOTICE, "[TESn:%02u CBN] CEPID not found", cepid);
+		return E_PAR;
+		}
+
+	switch (fncd) {
+
+	case TFN_TCP_ACP_CEP:
+		ri->error = *(ER*)p_parblk;
+		syscall(sig_sem(ri->semid));
+		break;
+
+	case TFN_TCP_RCV_DAT:
+		if ((ri->rlen = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u CBN] error: %s", cepid, itron_strerror(ri->rlen));
+		syscall(sig_sem(ri->semid));
+		break;
+
+	case TFN_TCP_SND_DAT:
+		if ((ri->slen = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u CBN] error: %s", cepid, itron_strerror(ri->slen));
+		syscall(sig_sem(ri->semid));
+		break;
+
+	case TFN_TCP_CLS_CEP:
+		if ((ri->error = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u CBN] error: %s", cepid, itron_strerror(ri->error));
+		syscall(sig_sem(ri->semid));
+		break;
+
+	case TFN_TCP_RCV_BUF:
+		if ((ri->rlen = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u CBN] error: %s", cepid, itron_strerror(ri->rlen));
+		syscall(sig_sem(ri->semid));
+		break;
+
+	case TFN_TCP_GET_BUF:
+		if ((ri->slen = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u CBN] error: %s", cepid, itron_strerror(ri->slen));
+		syscall(sig_sem(ri->semid));
+		break;
+
+#ifdef USE_TCP_EXTENTIONS
+
+	case TEV_TCP_RCV_OOB:
+		if ((ri->rlen = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u OOB] error: %s", cepid, itron_strerror(ri->rlen));
+		else if (ri->rlen > 0) {
+			char ch;
+
+			if ((ri->rlen = tcp_rcv_oob(cepid, &ch, sizeof(ch))) > 0)
+				syslog(LOG_NOTICE, "[TESn:%02u OOB] recv oob: 0x%02x", cepid, ch);
+			else if (ri->rlen < 0)
+				syslog(LOG_NOTICE, "[TESn:%02u OOB] error: %s", cepid, itron_strerror(ri->rlen));
+			}
+		break;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	case TFN_TCP_CON_CEP:
+	case TFN_TCP_SND_OOB:
+	default:
+		error = E_PAR;
+		break;
+		}
+	return error;
+	}
+
+/*
+ *  tcp_passive_open -- 受動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+static ER
+tcp_passive_open (T_TCP_ECHO_SRV_INFO *info, char apip)
+{
+	ER		error;
+	T_IPV4EP	dst4;
+
+	if (apip == API_PROTO_IPV6) {
+		/* 受付口は IPv6 */
+		if ((error = tcp6_acp_cep(info->cepid, info->repid, &info->dst, TMO_NBLK)) != E_WBLK)
+			return error;
+
+		/* 相手から接続されるまで待つ。*/
+		syscall(wai_sem(info->semid));
+
+		if (info->error != E_OK)
+			return info->error;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp6_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		}
+	else {
+		/* 受付口は IPv4 */
+		if ((error = tcp_acp_cep(info->cepid, info->repid, &dst4, TMO_NBLK)) != E_WBLK)
+			return error;
+
+		/* 相手から接続されるまで待つ。*/
+		syscall(wai_sem(info->semid));
+
+		if (info->error != E_OK)
+			return info->error;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp4_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		in6_make_ipv4mapped (&info->dst.ipaddr, dst4.ipaddr);
+		info->dst.portno = dst4.portno;
+
+		}
+
+	return E_OK;
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+static ER
+tcp_passive_open (T_TCP_ECHO_SRV_INFO *info, char apip)
+{
+	ER		error;
+
+	if ((error = TCP_ACP_CEP(info->cepid, info->repid, &info->dst, TMO_NBLK)) != E_WBLK)
+		return error;
+
+	/* 相手から接続されるまで待つ。*/
+	syscall(wai_sem(info->semid));
+
+	if (info->error != E_OK)
+		return info->error;
+
+#ifdef USE_TCP_EXTENTIONS
+	if ((error = FREE_TCP_REP(info->repid, true)) != E_OK)
+		return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	return E_OK;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+#ifdef USE_COPYSAVE_API
+
+/*
+ *  tcp_echo_srv -- TCP エコーサーバ
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ *    USE_COPYSAVE_API		ON
+ */
+
+ER
+tcp_echo_srv (uint_t six, char apip)
+{
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+	T_IN4_ADDR	ipv4addr;
+#endif
+	ER		error;
+	SYSTIM		now;
+	uint32_t	total;
+	uint16_t	rblen, sblen, rlen, slen, soff, scount, rcount;
+	char		*rbuf, *sbuf, head, tail;
+
+	if ((error = tcp_passive_open(&tcp_echo_srv_info[six], apip)) != E_OK)
+		return error;
+
+	syscall(get_tim(&now));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if (apip == API_PROTO_IPV6)
+		syslog(LOG_NOTICE, "[TES6:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ipv62str(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+		                   tcp_echo_srv_info[six].dst.portno);
+	else {
+		ipv4addr = ntohl(tcp_echo_srv_info[six].dst.ipaddr.s6_addr32[3]);
+		syslog(LOG_NOTICE, "[TES4:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ip2str(NULL, &ipv4addr),
+		                   tcp_echo_srv_info[six].dst.portno);
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	syslog(LOG_NOTICE, "[TES%c:%02u ACP] conct: %7lu,from: %s.%u",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+	                   IP2STR(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+	                   tcp_echo_srv_info[six].dst.portno);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	rlen = scount = rcount = total = 0;
+	while (true) {
+		if ((error = tcp_rcv_buf(tcp_echo_srv_info[six].cepid, (void**)&rbuf, TMO_NBLK)) != E_WBLK) {
+			syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s",
+	                                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+			break;
+			}
+
+		/* 受信するまで待つ。*/
+		syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+		if (tcp_echo_srv_info[six].rlen < 0) {	/* エラー */
+			syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s", 
+	                                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(tcp_echo_srv_info[six].rlen));
+			break;
+			}
+		else if (tcp_echo_srv_info[six].rlen == 0)	/* 受信終了 */
+			break;
+
+		rblen = tcp_echo_srv_info[six].rlen;
+
+		/* バッファの残りにより、受信長を調整する。*/
+		if (rblen > BUF_SIZE - rlen)
+			rblen = BUF_SIZE - rlen;
+		total += rblen;
+		rlen   = rblen;
+
+		head = *rbuf;
+		tail = *(rbuf + rblen - 1);
+		rcount ++;
+
+#ifdef SHOW_RCV_RANGE
+		syslog(LOG_NOTICE, "[TES%c:%02u RCV] "
+		                   "rcount: %7lu, len: %6lu, data %02x -> %02x",
+	                           apip, tcp_echo_srv_info[six].cepid, rcount, rblen, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+		memcpy(tcp_echo_srv_info[six].buffer, rbuf, rblen);
+
+		if ((error = tcp_rel_buf(tcp_echo_srv_info[six].cepid, rlen)) < 0) {
+			syslog(LOG_NOTICE, "[TES%c:%02u REL] error: %s",
+	                                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+			break;
+			}
+
+		soff = 0;
+		while (rlen > 0) {
+
+			if ((error = tcp_get_buf(tcp_echo_srv_info[six].cepid, (void**)&sbuf, TMO_NBLK)) != E_WBLK) {
+				syslog(LOG_NOTICE, "[TES%c:%02u GET] error: %s",
+	                                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+				goto err_fin;
+				}
+
+			/* 送信バッファの獲得が完了するまで待つ。*/
+			syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+			if (tcp_echo_srv_info[six].slen < 0) {
+				syslog(LOG_NOTICE, "[TES%c:%02u GET] error: %s",
+	                                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(tcp_echo_srv_info[six].slen));
+				goto err_fin;
+				}
+
+			sblen = tcp_echo_srv_info[six].slen;
+			scount ++;
+			slen = sblen < rlen ? sblen : rlen;
+			memcpy(sbuf, tcp_echo_srv_info[six].buffer + soff, slen);
+
+			if ((error = tcp_snd_buf(tcp_echo_srv_info[six].cepid, slen)) != E_OK) {
+				syslog(LOG_NOTICE, "[TES%c:%02u SND] error: %s",
+	                                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+				goto err_fin;
+				}
+#ifdef SHOW_RCV_RANGE
+			syslog(LOG_NOTICE, "[TES%c:%02u SND] scount: %7lu, len: %4u",
+	                                   apip, cepid, scount, slen);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+			rlen -= slen;
+			soff += slen;
+			}
+		}
+err_fin:
+
+#ifdef USE_TCP_SHT_CEP
+	if ((error = tcp_sht_cep(tcp_echo_srv_info[six].cepid)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u SHT] error: %s",
+	                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+#endif	/* of #ifdef USE_TCP_SHT_CEP */
+
+	if ((error = tcp_cls_cep(tcp_echo_srv_info[six].cepid, TMO_NBLK)) != E_WBLK)
+		syslog(LOG_NOTICE, "[TES%c:%02u CLS] error: %s",
+	                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+
+	/* 開放が完了するまで待つ。*/
+	syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+	syscall(get_tim(&now));
+	syslog(LOG_NOTICE, "[TES%c:%02u FIN] finsh: %7lu, ttl: %lu",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ, total);
+
+	return error == E_WBLK ? E_OK : error;
+	}
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+/*
+ *  tcp_echo_srv -- TCP エコーサーバ
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ *    USE_COPYSAVE_API		OFF
+ */
+
+ER
+tcp_echo_srv (uint_t six, char apip)
+{
+	T_IN4_ADDR	ipv4addr;
+	ER		error;
+	SYSTIM		now;
+	uint32_t	total;
+	uint16_t	rlen, slen, soff, scount, rcount;
+	char		head, tail;
+
+	if ((error = tcp_passive_open(&tcp_echo_srv_info[six], apip)) != E_OK)
+		return error;
+
+	syscall(get_tim(&now));
+	if (apip == API_PROTO_IPV6)
+		syslog(LOG_NOTICE, "[TES6:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ipv62str(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+		                   tcp_echo_srv_info[six].dst.portno);
+	else {
+		ipv4addr = ntohl(tcp_echo_srv_info[six].dst.ipaddr.s6_addr32[3]);
+		syslog(LOG_NOTICE, "[TES4:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ip2str(NULL, &ipv4addr),
+		                   tcp_echo_srv_info[six].dst.portno);
+		}
+
+	scount = rcount = total = 0;
+	while (true) {
+		if ((error = tcp_rcv_dat(tcp_echo_srv_info[six].cepid, tcp_echo_srv_info[six].buffer, BUF_SIZE - 1, TMO_NBLK)) != E_WBLK) {
+			syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s",
+	                                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+			break;
+			}
+
+		/* 受信完了まで待つ。*/
+		syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+		if (tcp_echo_srv_info[six].rlen < 0) {
+			syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s",
+	                                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(tcp_echo_srv_info[six].rlen));
+			break;
+			}
+		else if (tcp_echo_srv_info[six].rlen == 0)
+			break;
+
+		rlen = tcp_echo_srv_info[six].rlen;
+		head = * tcp_echo_srv_info[six].buffer;
+		tail = *(tcp_echo_srv_info[six].buffer + rlen - 1);
+		rcount ++;
+
+#ifdef SHOW_RCV_RANGE
+		syslog(LOG_NOTICE, "[TES%c:%02u RCV] rcount: %4u, len: %4u, data %02x -> %02x",
+	                           apip, tcp_echo_srv_info[six].cepid, rcount, rlen, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+		total += rlen;
+		soff = 0;
+		while (rlen > 0) {
+			scount ++;
+			if ((error = tcp_snd_dat(tcp_echo_srv_info[six].cepid, &tcp_echo_srv_info[six].buffer[soff], rlen, TMO_NBLK)) != E_WBLK) {
+				syslog(LOG_NOTICE, "[TES%c:%02u SND] error: %s",
+	                                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+				goto err_fin;
+				}
+
+			/* 送信完了まで待つ。*/
+			syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+			if (tcp_echo_srv_info[six].slen < 0) {
+				syslog(LOG_NOTICE, "[TES%c:%02u SND] error: %s",
+	                                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(tcp_echo_srv_info[six].slen));
+				goto err_fin;
+				}
+
+			slen = tcp_echo_srv_info[six].slen;
+
+#ifdef SHOW_RCV_RANGE
+			syslog(LOG_NOTICE, "[TES%c:%02u SND] scount: %4u, len: %4u",
+	                                   apip, tcp_echo_srv_info[six].cepid, scount, slen);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+			rlen -= slen;
+			soff += slen;
+			}
+		}
+err_fin:
+
+#ifdef USE_TCP_SHT_CEP
+	if ((error = tcp_sht_cep(tcp_echo_srv_info[six].cepid)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u SHT] error: %s",
+	                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+#endif	/* of #ifdef USE_TCP_SHT_CEP */
+
+	if ((error = tcp_cls_cep(tcp_echo_srv_info[six].cepid, TMO_NBLK)) != E_WBLK)
+		syslog(LOG_NOTICE, "[TES%c:%02u CLS] error: %s",
+	                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+
+	/* 開放が完了するまで待つ。*/
+	syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+	syscall(get_tim(&now));
+	syslog(LOG_NOTICE, "[TES%c:%02u FIN] finsh: %7lu, ttl: %lu",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ, total);
+
+	return error == E_WBLK ? E_OK : error;
+	}
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_var.h	(revision 398)
@@ -0,0 +1,97 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifdef USE_TCP_ECHO_SRV1
+
+#ifndef _TCP_ECHO_SRV1_VAR_H_
+#define _TCP_ECHO_SRV1_VAR_H_
+
+/*
+ *  注意:
+ *
+ *    BUF_SIZE は TCP の
+ *    送信ウインドウバッファサイズ + 受信ウインドウバッファサイズの 
+ *    3/2 倍以上の大きさがなければ、デッドロックする可能性がある。
+ */
+
+#define BUF_SIZE	((TCP_ECHO_SRV_SWBUF_SIZE + \
+                          TCP_ECHO_SRV_RWBUF_SIZE) * 3 / 2)
+
+/*
+ *  サーバ情報構造体
+ */
+
+typedef struct t_tcp_echo_srv_info {
+	ID	cepid;		/* 通信端点 ID		*/
+	ID	repid;		/* 受付口   ID		*/
+
+#ifdef USE_TCP_NON_BLOCKING
+	ID	semid;		/* NBLK 用 セマフォID	*/
+	ER	error;		/* NBLK 用 error	*/
+	ER_UINT	slen;		/* NBLK 用 送信データ数	*/
+	ER_UINT	rlen;		/* NBLK 用 受信データ数	*/
+#endif
+
+	T_IPEP	dst;		/* 接続相手アドレス情報	*/
+
+#ifdef USE_TCP_NON_BLOCKING
+
+	char	buffer[BUF_SIZE];
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#ifndef USE_COPYSAVE_API
+	char	buffer[BUF_SIZE];
+#endif
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+	} T_TCP_ECHO_SRV_INFO;
+
+#define INDEX_SRV_INFO(id)	((id)-1)
+
+/*
+ *  変数
+ */
+
+extern T_TCP_ECHO_SRV_INFO tcp_echo_srv_info[];
+
+/*
+ *  関数
+ */
+
+extern ER tcp_echo_srv (uint_t six, char apip);
+
+#endif	/* of #ifndef _TCP_ECHO_SRV1_VAR_H_ */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.c	(revision 398)
@@ -0,0 +1,740 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO サーバ #2
+ *
+ *    ・送受信タスク分離型
+ *    ・ノンブロッキングコール
+ *    ・IPv4/IPv6
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_srv2.h>
+
+#ifdef USE_TCP_ECHO_SRV2
+
+/*
+ *  表示
+ */
+
+/*#define SHOW_RCV_RANGE*/
+
+/*
+ *  コネクション切断方法の指定
+ */
+
+/*#define USE_TCP_SHT_CEP*/
+
+/*
+ *  全域変数
+ */
+
+/* TCP 送受信ウィンドバッファ */
+
+#ifndef TCP_CFG_SWBUF_CSAVE
+uint8_t tcp_echo_srv_swbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_SWBUF_SIZE];
+#endif
+
+#ifndef TCP_CFG_RWBUF_CSAVE
+uint8_t tcp_echo_srv_rwbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_RWBUF_SIZE];
+#endif
+
+/*
+ *  変数
+ */
+
+/*
+ *  注意:
+ *
+ *    BUF_SIZE は TCP の
+ *    送信ウインドウバッファサイズ + 受信ウインドウバッファサイズの 
+ *    3/2 倍以上の大きさがなければ、デッドロックする可能性がある。
+ */
+
+#define BUF_SIZE	((TCP_ECHO_SRV_SWBUF_SIZE + \
+                          TCP_ECHO_SRV_RWBUF_SIZE) * 3 / 2)
+
+static char	buffer[BUF_SIZE];	/* バッファ		*/
+
+static T_IPEP	dst;			/* 接続相手		*/
+static bool_t	ena_rcv;		/* 受信可能フラグ	*/
+static char	*rptr = buffer;		/* 受信ポインタ		*/
+static char	*sptr = buffer;		/* 送信ポインタ		*/
+static uint32_t	rcv_total;		/* 受信文字数		*/
+static uint32_t	snd_total;		/* 送信文字数		*/
+static uint16_t	chars;			/* バッファ内の文字数	*/
+static uint16_t	rcv_count;		/* 受信回数		*/
+static uint16_t	snd_count;		/* 送信回数		*/
+
+#ifdef USE_TCP_NON_BLOCKING
+
+static ER	rcv_error = E_OK;	/* 受信、ノンブロッキングコールエラー */
+static ER	snd_error = 1;		/* 送信、ノンブロッキングコールエラー */
+
+/*
+ *  ノンブロッキングコールのコールバック関数
+ */
+
+ER
+callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	ER		error = E_OK;
+	ER_UINT		slen, rlen;
+	SYSTIM		now;
+	uint16_t	last;
+	char		head, tail;
+
+	get_tim(&now);
+
+	switch (fncd) {
+
+	case TFN_TCP_ACP_CEP:
+		rcv_error = *(ER*)p_parblk;
+		if (rcv_error == E_OK) {
+			sptr = rptr = buffer;
+			snd_count = snd_total = rcv_count = rcv_total = chars = 0;
+			snd_error = 1;
+			ena_rcv   = true;
+			syslog(LOG_NOTICE, "[TES:%02u CBN] connect: %6lu, from: %s.%d",
+			                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+			}
+		else
+			syslog(LOG_NOTICE, "[TES:%02u CBN] accept error: %s\n", cepid, itron_strerror(rcv_error));
+
+		syscall(sig_sem(SEM_TCP_ECHO_SRV_RCV_READY));
+		break;
+
+	case TFN_TCP_SND_DAT:
+		slen = snd_error = *(ER*)p_parblk;
+		if (slen > 0) {
+			head = *sptr;
+			tail = *(sptr + slen - 1);
+#ifdef SHOW_RCV_RANGE
+			syslog(LOG_NOTICE, "[TES:%02u CBN] send len: %4u, data %02x -> %02x",
+			                   cepid, (uint16_t)slen, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+			snd_count ++;
+			snd_total += slen;
+
+			syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
+
+			/* 送信ポインタを進める。*/
+			if (sptr - buffer + slen >= sizeof(buffer))
+				sptr -= sizeof(buffer) - slen;
+			else
+				sptr += slen;
+
+			/* バッファ内の文字数を減らす。*/
+			last   = chars;
+			chars -= slen;
+
+ 			/* バッファ内に文字があれば、送信タスクを起床する。*/
+			if (chars > 0 || (!ena_rcv && chars == 0))
+				sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
+
+ 			/* 受信可能で、バッファ内に空きができれば、受信タスクを起床する。*/
+			if (ena_rcv && last == sizeof(buffer) && sizeof(buffer) - chars > 0)
+				syscall(sig_sem(SEM_TCP_ECHO_SRV_RCV_READY));
+
+			syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
+			}
+		else {
+			syslog(LOG_NOTICE, "[TES:%02u CBN] send error = %s", cepid, itron_strerror(snd_error));
+			sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
+			}
+		break;
+
+	case TFN_TCP_RCV_DAT:
+		rlen = rcv_error = *(ER*)p_parblk;
+		if (rlen > 0) {
+			head = *rptr;
+			tail = *(rptr + rlen - 1);
+#ifdef SHOW_RCV_RANGE
+			syslog(LOG_NOTICE, "[TES:%02u CBN] recv len: %4u, data %02x -> %02x",
+			                   cepid, (uint16_t)rlen, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+			rcv_count ++;
+			rcv_total += rlen;
+
+			syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
+
+			/* 受信ポインタを進める。*/
+			if (rptr - buffer + rlen >= sizeof(buffer))
+				rptr -= sizeof(buffer) - rlen;
+			else
+				rptr += rlen;
+
+			/* バッファ内の文字数を増やす。*/
+			last   = chars;
+			chars += rlen;
+
+ 			/* バッファ内に文字が入れば、送信タスクを起床する。*/
+			if (last == 0 && chars > 0)
+				sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
+
+ 			/* バッファ内に空きがあれば、受信タスクを起床する。*/
+			if (sizeof(buffer) - chars > 0)
+				sig_sem(SEM_TCP_ECHO_SRV_RCV_READY);
+
+			syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
+			}
+		else {
+			if (rlen < 0)
+				syslog(LOG_NOTICE, "[TES:%02u CBN] recv error = %s", cepid, itron_strerror(rcv_error));
+			sig_sem(SEM_TCP_ECHO_SRV_RCV_READY);
+			}
+		break;
+
+	case TFN_TCP_CLS_CEP:
+		snd_error = *(ER*)p_parblk;
+		if (snd_error != E_OK)
+			syslog(LOG_NOTICE, "[TES:%02u CBN] close error = %s", cepid, itron_strerror(snd_error));
+
+		syslog(LOG_NOTICE, "[TES:%02u CBN] finish:  %6lu, snd: %4u, rcv: %4u, len: %ld",
+		                   cepid, now / SYSTIM_HZ, snd_count, rcv_count, snd_total);
+
+		sig_sem(SEM_TCP_ECHO_SRV_CLS_READY);
+		break;
+
+	case TFN_TCP_CON_CEP:
+	case TFN_TCP_GET_BUF:
+	case TFN_TCP_RCV_BUF:
+	case TFN_TCP_SND_OOB:
+	default:
+		error = E_PAR;
+		}
+	return error;
+	}
+
+/*
+ *  TCP ECHO サーバ受信ルーチン (ノンブロッキングコール使用)
+ */
+
+ER
+tcp_echo_srv_rcv (ID cepid, ID repid)
+{
+	ER		error;
+	uint16_t	blen;
+
+	if ((error = psnd_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t)cepid)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES:%02u RCV] sync error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+
+	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[TES:%02u ACP] accept error = %s", cepid, itron_strerror(error));
+		return error;
+		}
+
+	/* コネクション開設完了まで待つ。*/
+	syscall(wai_sem(SEM_TCP_ECHO_SRV_RCV_READY));
+
+	/* 待っている間にエラーになったら、コネクションの開設待ちに戻る。*/
+	if (rcv_error != E_OK)
+		return rcv_error;
+
+#ifdef USE_TCP_EXTENTIONS
+	if ((error = FREE_TCP_REP(repid, true)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES:%02u DEL] REP delete error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	while (true) {
+
+		/* 受信サイズを計算する。*/
+		syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
+		if (sptr > rptr)
+			blen = sptr - rptr;
+		else
+			blen = sizeof(buffer) - (rptr - buffer);
+		syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
+
+		/* 受信する。*/
+		if ((error = tcp_rcv_dat(cepid, rptr, blen, TMO_NBLK)) != E_WBLK) {
+			syslog(LOG_NOTICE, "[TES:%02u RCV] recv error = %s", cepid, itron_strerror(error));
+			break;
+			}
+
+		/* 受信バッファに空ができるまで待つ。*/
+		syscall(wai_sem(SEM_TCP_ECHO_SRV_RCV_READY));
+
+		/* 待っている間に、受信文字数が 0 になるか、エラーになったら終了する。*/
+		if (rcv_error <= 0)
+			break;
+
+		}
+
+	/* 受信完了 */
+	ena_rcv = false;
+
+	/* 受信バッファに文字が入るのを待っている送信タスクを起床する。*/
+	if (chars == 0)
+		sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
+
+	/* コネクション切断完了まで待つ。*/
+	syscall(wai_sem(SEM_TCP_ECHO_SRV_CLS_READY));
+
+	return error == E_WBLK ? E_OK : error;
+	}
+
+/*
+ *  TCP ECHO サーバ送信タスク (ノンブロッキングコール使用)
+ */
+
+void
+tcp_echo_srv_snd_task(intptr_t exinf)
+{
+	ER		error;
+	ID		tskid, cepid;
+	uint16_t	blen;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND:%d] started.", tskid);
+	while (true) {
+		if ((error = rcv_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t*)&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TES:%02u SND] sync error: %s",
+			                   cepid, itron_strerror(error));
+			continue;
+			}
+
+		while (true) {
+
+			/* バッファに文字が入るまで待つ。*/
+			syscall(wai_sem(SEM_TCP_ECHO_SRV_SND_READY));
+
+			/* 待っている間にエラーになったら終了する。*/
+			if (snd_error <= 0)
+				break;
+
+			/* 受信完了で、バッファに文字がなければ終了する。*/
+			if (!ena_rcv && chars == 0)
+				break;
+
+			/* 送信サイズを計算する。*/
+			syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
+			if (rptr > sptr)
+				blen = rptr - sptr;
+			else
+				blen = sizeof(buffer) - (sptr - buffer);
+			syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
+
+			/* 送信する。*/
+			if ((error = tcp_snd_dat(cepid, sptr, blen, TMO_NBLK)) != E_WBLK) {
+				syslog(LOG_NOTICE, "[TES:%02u SND] send error = %s", cepid, itron_strerror(error));
+				break;
+				}
+			}
+
+		/* 受信バッファに空ができるを待っている受信タスクを起床する。*/
+		if (chars == sizeof(buffer))
+			sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
+
+#ifdef USE_TCP_SHT_CEP
+		if ((error = tcp_sht_cep(cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[TES:%02u SND] shutdown error = %s", cepid, itron_strerror(error));
+#endif	/* of #ifdef USE_TCP_SHT_CEP */
+
+		if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK) {
+			syslog(LOG_NOTICE, "[TES:%02u SND] close error = %s", cepid, itron_strerror(error));
+			}
+
+		pol_sem(SEM_TCP_ECHO_SRV_SND_READY);
+		pol_sem(SEM_TCP_ECHO_SRV_RCV_READY);
+		}
+	}
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+/*
+ *  TCP ECHO サーバ受信ルーチン
+ */
+
+ER
+tcp_echo_srv_rcv (ID cepid, ID repid)
+{
+	ER_UINT		rlen;
+	ER		error;
+	SYSTIM		now;
+	uint16_t	blen, last;
+	char		head, tail;
+
+	if ((error = psnd_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t)cepid)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES:%02u RCV] sync error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+
+	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES:%02u ACP] accept error = %s", cepid, itron_strerror(error));
+		return error;
+		}
+
+#ifdef USE_TCP_EXTENTIONS
+	if ((error = FREE_TCP_REP(repid, true)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES:%02u DEL] REP delete error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	syscall(get_tim(&now));
+	syslog(LOG_NOTICE, "[TES:%02u ACP] connect: %6lu, from: %s.%d",
+	                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+	sptr = rptr = buffer;
+	snd_count = snd_total = rcv_count = rcv_total = chars = 0;
+	ena_rcv   = true;
+	while (true) {
+
+		/* 受信サイズを計算する。*/
+		syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
+		if (sptr > rptr)
+			blen = sptr - rptr;
+		else
+			blen = sizeof(buffer) - (rptr - buffer);
+		syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
+
+		/* 受信する。*/
+		if ((rlen = tcp_rcv_dat(cepid, rptr, blen, TMO_FEVR)) <= 0) {
+			if (rlen < 0)
+				syslog(LOG_NOTICE, "[TES:%02u RCV] recv error = %s",
+				                   cepid, itron_strerror(rlen));
+			break;
+			}
+		head = *rptr;
+		tail = *(rptr + rlen - 1);
+#ifdef SHOW_RCV_RANGE
+		syslog(LOG_NOTICE, "[TES:%02u RCV] len: %4u, data %02x -> %02x",
+		                   cepid, (uint16_t)rlen, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+		rcv_count ++;
+		rcv_total += rlen;
+
+		syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
+
+		/* 受信ポインタを進める。*/
+		if (rptr - buffer + rlen >= sizeof(buffer))
+			rptr -= sizeof(buffer) - rlen;
+		else
+			rptr += rlen;
+
+		/* バッファ内の文字数を増やす。*/
+		last   =     chars;
+		chars += (uint16_t)rlen;
+
+ 				/* バッファ内に文字が入れば、送信タスクを起床する。*/
+		if (last == 0 && chars > 0)
+			sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
+
+ 				/* バッファ内に空きがあれば、受信タスクを起床する。*/
+		if (sizeof(buffer) - chars > 0)
+			sig_sem(SEM_TCP_ECHO_SRV_RCV_READY);
+
+		syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
+
+		/* バッファに空きができるまで待つ。*/
+		syscall(wai_sem(SEM_TCP_ECHO_SRV_RCV_READY));
+		}
+
+	/* 受信完了 */
+	ena_rcv = false;
+
+	/* 受信バッファに文字が入るのを待っている送信タスクを起床する。*/
+	if (chars == 0)
+		sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
+
+	/* コネクションの切断が完了するまで待つ。*/
+	syscall(wai_sem(SEM_TCP_ECHO_SRV_CLS_READY));
+
+	return error;
+	}
+
+/*
+ *  TCP ECHO サーバ送信タスク
+ */
+
+void
+tcp_echo_srv_snd_task(intptr_t exinf)
+{
+	ID		tskid, cepid;
+	ER		error;
+	ER_UINT		slen;
+	SYSTIM		now;
+	uint16_t	blen, last;
+	char		head, tail;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP ECHO SRV SND:%d] started.", tskid);
+	while (true) {
+		if ((error = rcv_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t*)&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TES:%02u SND] sync error: %s",
+			                   cepid, itron_strerror(error));
+			continue;
+			}
+
+		while (true) {
+
+			/* バッファに文字が入るまで待つ。*/
+			syscall(wai_sem(SEM_TCP_ECHO_SRV_SND_READY));
+
+			/* 受信完了で、バッファに文字がなければ終了する。*/
+			if (!ena_rcv && chars == 0)
+				break;
+
+			/* 送信サイズを計算する。*/
+			syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
+			if (rptr > sptr)
+				blen = rptr - sptr;
+			else
+				blen = sizeof(buffer) - (sptr - buffer);
+			syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
+
+			if ((slen = tcp_snd_dat(cepid, sptr, blen, TMO_FEVR)) <= 0) {
+				syslog(LOG_NOTICE, "[TES:%02u SND] send error = %s", cepid, itron_strerror(slen));
+				break;
+				}
+
+			head = *sptr;
+			tail = *(sptr + slen - 1);
+#ifdef SHOW_RCV_RANGE
+			syslog(LOG_NOTICE, "[TES:%02u SND] len: %4u, data %02x -> %02x",
+			                   cepid, (uint16_t)slen, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+			snd_count ++;
+			snd_total += slen;
+
+			syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
+
+			/* 送信ポインタを進める。*/
+			if (sptr - buffer + slen >= sizeof(buffer))
+				sptr -= sizeof(buffer) - slen;
+			else
+				sptr += slen;
+
+			/* バッファ内の文字数を減らす。*/
+			last   =     chars;
+			chars -= (uint16_t)slen;
+
+			/* 受信完了で、バッファに文字がなければ終了する。*/
+			if (!ena_rcv && chars == 0) {
+				syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
+				break;
+				}
+
+ 			/* バッファ内に文字があれば、送信タスクを起床する。*/
+			if (chars > 0)
+				sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
+
+ 			/* 受信可能で、バッファ内に空きができれば、受信タスクを起床する。*/
+			if (ena_rcv && last == sizeof(buffer) && sizeof(buffer) - chars > 0)
+				sig_sem(SEM_TCP_ECHO_SRV_RCV_READY);
+
+			syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
+			}
+
+		/* 受信バッファに空ができるを待っている受信タスクを起床する。*/
+		if (chars == sizeof(buffer))
+			sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
+
+#ifdef USE_TCP_SHT_CEP
+		if ((error = tcp_sht_cep(cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[TES:%02u SND] shtudown error = %s", cepid, itron_strerror(error));
+#endif	/* of #ifdef USE_TCP_SHT_CEP */
+
+		if ((error = tcp_cls_cep(cepid, TMO_FEVR)) != E_OK)
+			syslog(LOG_NOTICE, "[TES:%02u SND] close error = %s", cepid, itron_strerror(error));
+
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[TES:%02u SND] finish:  %6lu, snd: %4u, rcv: %4u, len: %ld",
+		                   cepid, now / SYSTIM_HZ, snd_count, rcv_count, snd_total);
+
+		sig_sem(SEM_TCP_ECHO_SRV_CLS_READY);
+
+		pol_sem(SEM_TCP_ECHO_SRV_SND_READY);
+		pol_sem(SEM_TCP_ECHO_SRV_RCV_READY);
+		}
+	}
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#ifdef USE_TCP_EXTENTIONS
+
+/*
+ *  get_tcp_rep -- TCP 受付口を獲得する。
+ */
+
+static ER
+get_tcp_rep (ID *repid)
+{
+	ID		tskid;
+	T_TCP_CREP	crep;
+
+	get_tid(&tskid);
+
+	crep.repatr = UINT_C(0);
+	crep.myaddr.portno = UINT_C(7);
+
+#if defined(SUPPORT_INET4)
+	crep.myaddr.ipaddr = IPV4_ADDRANY;
+#endif
+
+#if defined(SUPPORT_INET6)
+	memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+#endif
+
+	return ALLOC_TCP_REP(repid, tskid, &crep);
+	}
+
+/*
+ *  get_tcp_cep -- TCP 通信端点を獲得する。
+ */
+
+static ER
+get_tcp_cep (ID *cepid)
+{
+	ID		tskid;
+	T_TCP_CCEP	ccep;
+
+	get_tid(&tskid);
+
+	ccep.cepatr = UINT_C(0);
+	ccep.sbufsz = TCP_ECHO_SRV_SWBUF_SIZE;
+	ccep.rbufsz = TCP_ECHO_SRV_RWBUF_SIZE;
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+	ccep.sbuf = NADR;
+#else
+	ccep.sbuf = tcp_echo_srv_swbuf;
+#endif
+#ifdef TCP_CFG_RWBUF_CSAVE
+	ccep.rbuf = NADR;
+#else
+	ccep.rbuf = tcp_echo_srv_rwbuf;
+#endif
+#ifdef USE_TCP_NON_BLOCKING
+	ccep.callback = (FP)callback_nblk_tcp_echo_srv;
+#else
+	ccep.callback = NULL;
+#endif
+
+	return ALLOC_TCP_CEP(cepid, tskid, &ccep);
+	}
+
+/*
+ *  TCP ECHO サーバ受信タスク
+ */
+
+void
+tcp_echo_srv_rcv_task (intptr_t exinf)
+{
+	ID	tskid, cepid, repid;
+	ER	error = E_OK;
+
+	syscall(get_tid(&tskid));
+	syslog(LOG_NOTICE, "[TCP ECHO SRV:%d] started.", tskid);
+	while (true) {
+
+		syscall(slp_tsk());
+		if ((error = get_tcp_cep (&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TES:00 EXT] CEP create error: %s", itron_strerror(error));
+			continue;
+			}
+
+		while (true) {
+
+			if ((error = get_tcp_rep (&repid)) != E_OK) {
+				syslog(LOG_NOTICE, "[TES:00 EXT] REP create error: %s", itron_strerror(error));
+				break;
+				}
+			else if ((error = tcp_echo_srv_rcv(cepid, repid)) != E_OK) {
+				error = FREE_TCP_REP(repid, error != E_DLT);
+				break;
+				}
+			}
+
+		if ((error = free_tcp_cep(cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[TES:%02u EXT] CEP delete error: %s", cepid, itron_strerror(error));
+
+		}
+	}
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+void
+tcp_echo_srv_rcv_task(intptr_t exinf)
+{
+	ID	tskid;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP ECHO SRV RCV:%d,%d] started.", tskid, (ID)exinf);
+	while (true) {
+		while (tcp_echo_srv_rcv((ID)exinf, TCP_ECHO_SRV_REPID) == E_OK)
+			;
+		}
+	}
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV2 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.cfg	(revision 398)
@@ -0,0 +1,96 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO サーバ #2、送受信タスク分離型
+ *  コンフィギュレーションファイル
+ */
+
+#ifdef USE_TCP_ECHO_SRV2
+
+/* タスク */
+
+#ifdef USE_TCP_EXTENTIONS
+
+CRE_TSK(TCP_ECHO_SRV_TASK,  {
+	TA_HLNG | TA_ACT,
+	0,
+	tcp_echo_srv_rcv_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+CRE_TSK(TCP_ECHO_SRV_SND_TASK,  {
+	TA_HLNG | TA_ACT,
+	0,
+	tcp_echo_srv_snd_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+CRE_TSK(TCP_ECHO_SRV_TASK,  {
+	TA_HLNG | TA_ACT,
+	TCP_ECHO_SRV_CEPID1,
+	tcp_echo_srv_rcv_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+CRE_TSK(TCP_ECHO_SRV_SND_TASK,  {
+	TA_HLNG | TA_ACT,
+	TCP_ECHO_SRV_CEPID1,
+	tcp_echo_srv_snd_task,
+	TCP_ECHO_SRV_MAIN_PRIORITY,
+	TCP_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/* コマンドキュー */
+
+CRE_DTQ(DTQ_TCP_ECHO_SRV_SND,  { TA_TFIFO, 1, NULL });
+
+/* セマフォ */
+
+CRE_SEM(SEM_TCP_ECHO_SRV_LOCK,		{ TA_TPRI, 1, 1 });
+CRE_SEM(SEM_TCP_ECHO_SRV_RCV_READY,	{ TA_TPRI, 0, 1 });
+CRE_SEM(SEM_TCP_ECHO_SRV_SND_READY,	{ TA_TPRI, 0, 1 });
+CRE_SEM(SEM_TCP_ECHO_SRV_CLS_READY,	{ TA_TPRI, 0, 1 });
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV2 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.h	(revision 398)
@@ -0,0 +1,113 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifdef USE_TCP_ECHO_SRV2
+
+#ifndef _TCP_ECHO_SRV2_H_
+#define _TCP_ECHO_SRV2_H_
+
+/* 
+ *  TCP ECHO サーバ #2
+ *
+ *    ・送受信タスク分離型
+ *    ・ノンブロッキングコール
+ *    ・IPv4/IPv6
+ */
+
+/* スタックサイズ */
+
+#define TCP_ECHO_SRV_STACK_SIZE		1024		/* TCP ECHO サーバタスクのスタックサイズ		*/
+
+/* 優先度 */
+
+#define TCP_ECHO_SRV_MAIN_PRIORITY	5		/* TCP ECHO サーバタスクの優先度			*/
+
+/*
+ *  TCP 送受信ウインドバッファサイズ
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(1024)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(1024)
+
+#elif defined(SUPPORT_INET4)
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(512)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(512)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(1024)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(1024)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+/* タスク数 */
+
+#if defined(USE_TCP_ECHO_SRV2)
+#if defined(NUM_TCP_ECHO_SRV_TASKS)
+#undef  NUM_TCP_ECHO_SRV_TASKS
+#endif	/* of #if defined(NUM_TCP_ECHO_SRV_TASKS) */
+#define NUM_TCP_ECHO_SRV_TASKS		1
+#endif	/* of #if defined(USE_TCP_ECHO_SRV2) */
+
+/*
+ *  変数
+ */
+
+/* TCP 送受信ウィンドバッファ */
+
+extern uint8_t tcp_echo_srv_swbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_SWBUF_SIZE];
+extern uint8_t tcp_echo_srv_rwbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_RWBUF_SIZE];
+
+/*
+ *  タスク
+ */
+
+extern void	tcp_echo_srv_rcv_task(intptr_t exinf);
+extern void	tcp_echo_srv_snd_task(intptr_t exinf);
+
+/*
+ *  関数
+ */
+
+extern ER callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _TCP_ECHO_SRV2_H_ */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV2 */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_dbg_cons.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_dbg_cons.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_dbg_cons.cfg	(revision 398)
@@ -0,0 +1,143 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  デバッグコンソール
+ *  TCP/IP コンフィギュレーションファイル
+ */
+
+#ifdef USE_DBG_CONS
+
+#ifdef USE_TCP_EXTENTIONS
+
+/* TCP 受付口 */
+
+#ifdef SUPPORT_INET6
+
+#if NUM_VRID_TCP6_REPS >= 1
+VRID_TCP6_REP (TCP6_RSV_REPID1);
+#endif
+
+#if NUM_VRID_TCP6_REPS >= 2
+VRID_TCP6_REP (TCP6_RSV_REPID2);
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+#if NUM_VRID_TCP4_REPS >= 1
+VRID_TCP_REP (TCP4_RSV_REPID1);
+#endif
+
+#if NUM_VRID_TCP4_REPS >= 2
+VRID_TCP_REP (TCP4_RSV_REPID2);
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+/* TCP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+#if NUM_VRID_TCP6_CEPS >= 1
+VRID_TCP6_CEP (TCP6_RSV_CEPID1);
+#endif
+
+#if NUM_VRID_TCP6_CEPS >= 2
+VRID_TCP6_CEP (TCP6_RSV_CEPID2);
+#endif
+
+#if NUM_VRID_TCP6_CEPS >= 3
+VRID_TCP6_CEP (TCP6_RSV_CEPID3);
+#endif
+
+#if NUM_VRID_TCP6_CEPS >= 4
+VRID_TCP6_CEP (TCP6_RSV_CEPID4);
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+#if NUM_VRID_TCP4_CEPS >= 1
+VRID_TCP_CEP (TCP4_RSV_CEPID1);
+#endif
+
+#if NUM_VRID_TCP4_CEPS >= 2
+VRID_TCP_CEP (TCP4_RSV_CEPID2);
+#endif
+
+#if NUM_VRID_TCP4_CEPS >= 3
+VRID_TCP_CEP (TCP4_RSV_CEPID3);
+#endif
+
+#if NUM_VRID_TCP4_CEPS >= 4
+VRID_TCP_CEP (TCP4_RSV_CEPID4);
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_UDP_EXTENTIONS
+
+/* UDP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+#if NUM_VRID_UDP6_CEPS >= 1
+VRID_UDP6_CEP (UDP6_RSV_CEPID1);
+#endif
+
+#if NUM_VRID_UDP6_CEPS >= 2
+VRID_UDP6_CEP (UDP6_RSV_CEPID2);
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+#if NUM_VRID_UDP4_CEPS >= 1
+VRID_UDP_CEP (UDP4_RSV_CEPID1);
+#endif
+
+#if NUM_VRID_UDP4_CEPS >= 2
+VRID_UDP_CEP (UDP4_RSV_CEPID2);
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_DBG_CONS */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_dhcp4_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_dhcp4_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_dhcp4_cli.cfg	(revision 398)
@@ -0,0 +1,49 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  DHCP クライアント
+ *  TCP/IP コンフィギュレーションファイル
+ */
+
+#ifdef DHCP4_CLI_CFG
+
+/* UDP 通信端点 */
+
+UDP_CRE_CEP (UDP4_DHCP_CLI_CEPID, {
+	0,
+	{ IPV4_ADDRANY, DHCP4_CLI_CFG_PORTNO },
+	callback_nblk_dhcp4_cli
+	} );
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_dhcp6_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_dhcp6_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_dhcp6_cli.cfg	(revision 398)
@@ -0,0 +1,49 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  DHCP/DHCPv6 クライアント
+ *  TCP/IP コンフィギュレーションファイル
+ */
+
+#ifdef DHCP6_CLI_CFG
+
+/* UDP 通信端点 */
+
+UDP6_CRE_CEP (UDP6_DHCP_CLI_CEPID, {
+	0,
+	{ IPV6_ADDRANY, DHCP6_CLI_CFG_PORTNO },
+	callback_nblk_dhcp6_cli
+	} );
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_net_cons.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_net_cons.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_net_cons.cfg	(revision 398)
@@ -0,0 +1,123 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ネットワーク経由コンソール入出力
+ *  TCP/IP コンフィギュレーションファイル
+ */
+
+#ifdef USE_NET_CONS
+
+/* TCP 受付口 */
+
+#ifdef SUPPORT_INET6
+
+TCP6_CRE_REP (NET_CONS_REPID, {
+	0,
+	{ IPV6_ADDRANY, 23 }
+	} );
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+TCP_CRE_REP (NET_CONS_REPID, {
+	0,
+	{ IPV4_ADDRANY, 23 }
+	} );
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+/* TCP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+TCP6_CRE_CEP (NET_CONS_CEPID, {
+	0,
+	NADR,
+	NET_CONS_SWBUF_SIZE,
+	NADR,
+	NET_CONS_RWBUF_SIZE,
+	callback_nblk_net_cons
+	} );
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+TCP6_CRE_CEP (NET_CONS_CEPID, {
+	0,
+	net_cons_swbuf,
+	NET_CONS_SWBUF_SIZE,
+	net_cons_rwbuf,
+	NET_CONS_RWBUF_SIZE,
+	callback_nblk_net_cons
+	} );
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+TCP_CRE_CEP (NET_CONS_CEPID, {
+	0,
+	NADR,
+	NET_CONS_SWBUF_SIZE,
+	NADR,
+	NET_CONS_RWBUF_SIZE,
+	callback_nblk_net_cons
+	} );
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+TCP_CRE_CEP (NET_CONS_CEPID, {
+	0,
+	net_cons_swbuf,
+	NET_CONS_SWBUF_SIZE,
+	net_cons_rwbuf,
+	NET_CONS_RWBUF_SIZE,
+	callback_nblk_net_cons
+	} );
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#endif	/* of #ifdef USE_NET_CONS */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_resolver.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_resolver.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_resolver.cfg	(revision 398)
@@ -0,0 +1,63 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  RESOLVER クライアント
+ *  TCP/IP コンフィギュレーションファイル
+ */
+
+#ifdef USE_RESOLVER
+
+/* UDP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+UDP6_CRE_CEP (UDP6_RESOLVER_CEPID, {
+	0,
+	{ IPV6_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+UDP_CRE_CEP (UDP4_RESOLVER_CEPID, {
+	0,
+	{ IPV4_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef USE_RESOLVER */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1.cfg	(revision 398)
@@ -0,0 +1,476 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO サーバの TCP/IP コンフィギュレーションファイル
+ *
+ *    SUPPORT_INET4
+ *    USE_TCP_NON_BLOCKING: OFF
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP 通信端点、NUM_TCP_ECHO_SRV_TASKS >= 2 以降
+ * 
+ */
+
+/* TCP 通信端点 */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1_nblk.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1_nblk.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1_nblk.cfg	(revision 398)
@@ -0,0 +1,474 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO サーバの TCP/IP コンフィギュレーションファイル
+ *
+ *    SUPPORT_INET4
+ *    USE_TCP_NON_BLOCKING: ON
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP 通信端点、NUM_TCP_ECHO_SRV_TASKS >= 2 以降
+ * 
+ */
+
+/* TCP 通信端点 */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1.cfg	(revision 398)
@@ -0,0 +1,350 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO サーバの TCP/IP コンフィギュレーションファイル
+ *
+ *    SUPPORT_INET6
+ *    SUPPORT_INET4
+ *    USE_TCP_NON_BLOCKING: OFF
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP 受付口
+ *    TCP 通信端点、NUM_TCP_ECHO_SRV_TASKS == 1
+ * 
+ */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+/*
+ * TCP 受付口
+ */
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+TCP6_CRE_REP (TCP_ECHO_SRV_REPID, {
+	TA_NULL,
+	{ IPV6_ADDRANY, 7 }
+	} );
+
+#if defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV)
+
+TCP_CRE_REP (TCP4_ECHO_SRV_REPID, {
+	TA_NULL,
+	{ IPV4_ADDRANY, 7 }
+	} );
+
+#endif	/* of #if defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+TCP_CRE_REP (TCP_ECHO_SRV_REPID, {
+	TA_NULL,
+	{ IPV4_ADDRANY, 7 }
+	} );
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+/*
+ * TCP 通信端点
+ *
+ * 定義する TCP 通信端点（TCP?_ECHO_SRV_CEPID1）の選択
+ *
+ *   INET6 INET4 USE_TCP4  TCP6_CRE_CEP TCP_CRE_CEP
+ *     ○    ○     ○          ×         TCP4
+ *     ○    ○     ×          TCP        ×
+ *     ○    ×     ○          TCP        ×
+ *     ○    ×     ×          TCP        ×
+ *     ×    ○     ○          ×         TCP
+ *     ×    ○     ×          ×         TCP
+ *     ×    ×     ○          ×         ×
+ *     ×    ×     ×          ×         ×
+ *
+ */
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_TCP4_ECHO_SRV)
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #if defined(USE_TCP4_ECHO_SRV) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(USE_TCP4_ECHO_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#elif defined(SUPPORT_INET4)	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1_nblk.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1_nblk.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1_nblk.cfg	(revision 398)
@@ -0,0 +1,308 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO サーバの TCP/IP コンフィギュレーションファイル
+ *
+ *    SUPPORT_INET6
+ *    SUPPORT_INET4
+ *    USE_TCP_NON_BLOCKING: ON
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP 通信端点、NUM_TCP_ECHO_SRV_TASKS == 1
+ * 
+ */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+/*
+ * TCP 通信端点
+ *
+ * 定義する TCP 通信端点（TCP?_ECHO_SRV_CEPID1）の選択
+ *
+ *   INET6 INET4 USE_TCP4  TCP6_CRE_CEP TCP_CRE_CEP
+ *     ○    ○     ○          ×         TCP4
+ *     ○    ○     ×          TCP        ×
+ *     ○    ×     ○          TCP        ×
+ *     ○    ×     ×          TCP        ×
+ *     ×    ○     ○          ×         TCP
+ *     ×    ○     ×          ×         TCP
+ *     ×    ×     ○          ×         ×
+ *     ×    ×     ×          ×         ×
+ *
+ */
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_TCP4_ECHO_SRV)
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #if defined(USE_TCP4_ECHO_SRV) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(USE_TCP4_ECHO_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#elif defined(SUPPORT_INET4)	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if !defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1.cfg	(revision 398)
@@ -0,0 +1,470 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO サーバの TCP/IP コンフィギュレーションファイル
+ *
+ *    SUPPORT_INET6
+ *    USE_TCP_NON_BLOCKING: OFF
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP 通信端点、NUM_TCP_ECHO_SRV_TASKS >= 2 以降
+ * 
+ */
+
+/* TCP 通信端点 */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1_nblk.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1_nblk.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1_nblk.cfg	(revision 398)
@@ -0,0 +1,470 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO サーバの TCP/IP コンフィギュレーションファイル
+ *
+ *    SUPPORT_INET6
+ *    USE_TCP_NON_BLOCKING: ON
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP 通信端点、NUM_TCP_ECHO_SRV_TASKS >= 2 以降
+ * 
+ */
+
+/* TCP 通信端点 */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_cli.cfg	(revision 398)
@@ -0,0 +1,165 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP DISCARD クライアント
+ *  TCP/IP コンフィギュレーションファイル
+ */
+
+#ifdef USE_TCP_DISCARD_CLI
+
+#ifndef USE_TCP_EXTENTIONS
+
+/* TCP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+#ifdef USE_TCP_NON_BLOCKING
+
+#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
+
+TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	NADR,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	callback_nblk_tcp_discard_cli
+	} );
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	tcp_discard_cli_swbuf,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	callback_nblk_tcp_discard_cli
+	} );
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
+
+TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	NADR,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	NULL
+	} );
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	tcp_discard_cli_swbuf,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	NULL
+	} );
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+#ifdef USE_TCP_NON_BLOCKING
+
+#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
+
+TCP_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	NADR,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	callback_nblk_tcp_discard_cli
+	} );
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+TCP_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	tcp_discard_cli_swbuf,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	callback_nblk_tcp_discard_cli
+	} );
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
+
+TCP_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	NADR,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	NULL
+	} );
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+TCP_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	tcp_discard_cli_swbuf,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	NULL
+	} );
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#endif	/* of #ifndef USE_TCP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_TCP_DISCARD_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_srv.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_srv.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_srv.cfg	(revision 398)
@@ -0,0 +1,126 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP DISCARD サーバの TCP/IP コンフィギュレーションファイル
+ */
+
+#ifdef USE_TCP_DISCARD_SRV
+
+#ifndef USE_TCP_EXTENTIONS
+
+/* TCP 受付口 */
+
+#ifdef SUPPORT_INET6
+
+TCP6_CRE_REP (TCP_DISCARD_SRV_REPID, {
+	TA_NULL,
+	{ IPV6_ADDRANY, 9 }
+	} );
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+TCP_CRE_REP (TCP_DISCARD_SRV_REPID, {
+	TA_NULL,
+	{ IPV4_ADDRANY, 9 }
+	} );
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+/* TCP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+#ifdef TCP_CFG_RWBUF_CSAVE_ONLY
+
+TCP6_CRE_CEP (TCP_DISCARD_SRV_CEPID, {
+	TA_NULL,
+	NADR,
+	0,
+	NADR,
+	TCP_DISCARD_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+TCP6_CRE_CEP (TCP_DISCARD_SRV_CEPID, {
+	TA_NULL,
+	NADR,
+	0,
+	tcp_discard_srv_rwbuf,
+	TCP_DISCARD_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+#ifdef TCP_CFG_RWBUF_CSAVE_ONLY
+
+TCP_CRE_CEP (TCP_DISCARD_SRV_CEPID, {
+	TA_NULL,
+	NADR,
+	0,
+	NADR,
+	TCP_DISCARD_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+TCP_CRE_CEP (TCP_DISCARD_SRV_CEPID, {
+	TA_NULL,
+	NADR,
+	0,
+	tcp_discard_srv_rwbuf,
+	TCP_DISCARD_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#endif	/* of #ifndef USE_TCP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_TCP_DISCARD_SRV */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_cli.cfg	(revision 398)
@@ -0,0 +1,407 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO クライアント
+ *  TCP/IP コンフィギュレーションファイル
+ */
+
+#ifdef USE_TCP_ECHO_CLI
+
+#ifndef USE_TCP_EXTENTIONS
+
+/* TCP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+#ifdef USE_TCP_NON_BLOCKING
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#ifdef SUPPORT_INET4
+
+#ifdef USE_TCP4_ECHO_CLI
+
+#ifdef USE_TCP_NON_BLOCKING
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef USE_TCP4_ECHO_CLI */
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+#ifdef USE_TCP_NON_BLOCKING
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#endif	/* of #ifndef USE_TCP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_TCP_ECHO_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_srv2.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_srv2.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_srv2.cfg	(revision 398)
@@ -0,0 +1,306 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO サーバの TCP/IP コンフィギュレーションファイル
+ */
+
+#if defined(USE_TCP_ECHO_SRV2)
+
+#ifndef USE_TCP_EXTENTIONS
+
+/* TCP 受付口 */
+
+#if defined(SUPPORT_INET6)
+
+TCP6_CRE_REP (TCP_ECHO_SRV_REPID, {
+	0,
+	{ IPV6_ADDRANY, 7 }
+	} );
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+TCP_CRE_REP (TCP_ECHO_SRV_REPID, {
+	0,
+	{ IPV4_ADDRANY, 7 }
+	} );
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/* TCP 通信端点 */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #ifndef USE_TCP_EXTENTIONS */
+
+#endif	/* of #defined(USE_TCP_ECHO_SRV2) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_cli.cfg	(revision 398)
@@ -0,0 +1,77 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO クライアント
+ *  TCP/IP コンフィギュレーションファイル
+ */
+
+#if defined(USE_UDP4_ECHO_CLI_TSK)
+
+#if !defined(USE_UDP_EXTENTIONS)
+
+/* UDP 通信端点 */
+
+#if defined(USE_UDP_NON_BLOCKING)
+
+UDP_CRE_CEP (UDP4_ECHO_CLI_CEPID, {
+	0,
+	{ IPV4_ADDRANY, UDP_PORTANY },
+	callback_nblk_udp4_echo_cli
+	} );
+
+#else	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#if defined(USE_UDP_CALL_BACK)
+
+UDP_CRE_CEP (UDP4_ECHO_CLI_CEPID, {
+	0,
+	{ IPV4_ADDRANY, UDP_PORTANY },
+	callback_udp4_echo_cli
+	} );
+
+#else	/* of #if defined(USE_UDP_CALL_BACK) */
+
+UDP_CRE_CEP (UDP4_ECHO_CLI_CEPID, {
+	0,
+	{ IPV4_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#endif	/* of #if defined(USE_UDP_CALL_BACK) */
+
+#endif	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#endif	/* of #if !defined(USE_UDP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_srv.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_srv.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_srv.cfg	(revision 398)
@@ -0,0 +1,79 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO サーバ
+ *  UDP/IP コンフィギュレーションファイル
+ *
+ *    IPv4
+ */
+
+#ifdef USE_UDP4_ECHO_SRV_TSK
+
+#ifndef USE_UDP_EXTENTIONS
+
+/* UDP 通信端点 */
+
+#ifdef USE_UDP_NON_BLOCKING
+
+UDP_CRE_CEP (UDP4_ECHO_SRV_CEPID, {
+	0,
+	{ IPV4_ADDRANY, 7 },
+	callback_nblk_udp4_echo_srv
+	} );
+
+#else	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+#ifdef USE_UDP_CALL_BACK
+
+UDP_CRE_CEP (UDP4_ECHO_SRV_CEPID, {
+	0,
+	{ IPV4_ADDRANY, 7 },
+	callback_udp4_echo_srv
+	} );
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+UDP_CRE_CEP (UDP4_ECHO_SRV_CEPID, {
+	0,
+	{ IPV4_ADDRANY, 7 },
+	NULL
+	} );
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+#endif	/* of #ifndef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP4_ECHO_SRV_TSK */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_cli.cfg	(revision 398)
@@ -0,0 +1,77 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO クライアント
+ *  TCP/IP コンフィギュレーションファイル
+ */
+
+#if defined(USE_UDP6_ECHO_CLI_TSK)
+
+#if !defined(USE_UDP_EXTENTIONS)
+
+/* UDP 通信端点 */
+
+#if defined(USE_UDP_NON_BLOCKING)
+
+UDP6_CRE_CEP (UDP6_ECHO_CLI_CEPID, {
+	0,
+	{ IPV6_ADDRANY, UDP_PORTANY },
+	callback_nblk_udp6_echo_cli
+	} );
+
+#else	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#if defined(USE_UDP_CALL_BACK)
+
+UDP6_CRE_CEP (UDP6_ECHO_CLI_CEPID, {
+	0,
+	{ IPV6_ADDRANY, UDP_PORTANY },
+	callback_udp6_echo_cli
+	} );
+
+#else	/* of #if defined(USE_UDP_CALL_BACK) */
+
+UDP6_CRE_CEP (UDP6_ECHO_CLI_CEPID, {
+	0,
+	{ IPV6_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#endif	/* of #if defined(USE_UDP_CALL_BACK) */
+
+#endif	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#endif	/* of #if !defined(USE_UDP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_srv.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_srv.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_srv.cfg	(revision 398)
@@ -0,0 +1,79 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO サーバ
+ *  UDP/IP コンフィギュレーションファイル
+ *
+ *    IPv6
+ */
+
+#ifdef USE_UDP6_ECHO_SRV_TSK
+
+#ifndef USE_UDP_EXTENTIONS
+
+/* UDP 通信端点 */
+
+#ifdef USE_UDP_NON_BLOCKING
+
+UDP6_CRE_CEP (UDP6_ECHO_SRV_CEPID, {
+	0,
+	{ IPV6_ADDRANY, 7 },
+	callback_nblk_udp6_echo_srv
+	} );
+
+#else	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+#ifdef USE_UDP_CALL_BACK
+
+UDP6_CRE_CEP (UDP6_ECHO_SRV_CEPID, {
+	0,
+	{ IPV6_ADDRANY, 7 },
+	callback_udp6_echo_srv
+	} );
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+UDP6_CRE_CEP (UDP6_ECHO_SRV_CEPID, {
+	0,
+	{ IPV6_ADDRANY, 7 },
+	NULL
+	} );
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+#endif	/* of #ifndef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP6_ECHO_SRV_TSK */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp_discard_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp_discard_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_udp_discard_cli.cfg	(revision 398)
@@ -0,0 +1,69 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP DISCARD クライアント
+ *  UDP/IP コンフィギュレーションファイル
+ */
+
+#ifdef USE_UDP_DISCARD_CLI
+
+#ifndef USE_UDP_EXTENTIONS
+
+/* UDP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+UDP6_CRE_CEP (UDP_DISCARD_CLI_CEPID, { 
+	0,
+	{ IPV6_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+UDP_CRE_CEP (UDP_DISCARD_CLI_CEPID, {
+	0,
+	{ IPV4_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#endif	/* of #ifndef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP_DISCARD_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_wwws.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_wwws.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/tinet_wwws.cfg	(revision 398)
@@ -0,0 +1,460 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  WWW サーバの TCP/IP コンフィギュレーションファイル
+ *
+ *    SUPPORT_INET6
+ *    SUPPORT_INET4
+ *    USE_TCP_NON_BLOCKING: OFF
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP 受付口
+ *    TCP 通信端点
+ * 
+ */
+
+#if defined(USE_WWW_SRV)
+
+/*
+ * TCP 受付口
+ */
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+TCP6_CRE_REP (WWW_SRV_REPID, {
+	0,
+	{ IPV6_ADDRANY, 80 }
+	} );
+
+#if defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+TCP_CRE_REP (WWW4_SRV_REPID, {
+	0,
+	{ IPV4_ADDRANY, 80 }
+	} );
+
+#endif	/* of #if defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET6 */
+
+#if defined(SUPPORT_INET4)
+
+TCP_CRE_REP (WWW_SRV_REPID, {
+	0,
+	{ IPV4_ADDRANY, 80 }
+	} );
+
+#endif	/* of #if defined(SUPPORT_INET4 */
+
+#endif	/* of #if defined(SUPPORT_INET6 */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS */
+
+/*
+ * TCP 通信端点
+ *
+ * 定義する TCP 通信端点（WWW?_CEPID1）の選択
+ *
+ *   INET6 INET4 USE_TCP4  TCP6_CRE_CEP TCP_CRE_CEP
+ *     ○    ○     ○          ×         WWW4
+ *     ○    ○     ×          WWW        ×
+ *     ○    ×     ○          WWW        ×
+ *     ○    ×     ×          WWW        ×
+ *     ×    ○     ○          ×         WWW
+ *     ×    ○     ×          ×         WWW
+ *     ×    ×     ○          ×         ×
+ *     ×    ×     ×          ×         ×
+ *
+ */
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_WWW4_SRV)
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (WWW4_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (WWW4_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (WWW4_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (WWW4_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #if defined(USE_WWW4_SRV) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(USE_WWW4_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET4 */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(SUPPORT_INET4 */
+
+#if NUM_WWW_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[1],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	www_srv_swbuf[1],
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	www_srv_swbuf[1],
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[1],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_WWW_SRV_TASKS >= 2 */
+
+#elif defined(SUPPORT_INET4)	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if NUM_WWW_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[1],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	www_srv_swbuf[1],
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	www_srv_swbuf[1],
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[1],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_WWW_SRV_TASKS >= 2 */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_WWW_SRV) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.c	(revision 398)
@@ -0,0 +1,477 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  UDP4 ECHO クライアント
+ */
+
+#include <string.h>
+
+#if defined(TARGET_KERNEL_ASP)
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #if defined(TARGET_KERNEL_ASP) */
+
+#if defined(TARGET_KERNEL_JSP)
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #if defined(TARGET_KERNEL_JSP) */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/udp4_echo_cli.h>
+
+#if defined(USE_UDP4_ECHO_CLI_TSK)
+
+/* echo サーバのポート番号 */
+
+#define ECHO_SRV_PORTNO		UINT_C(7)
+
+/* 送信間隔 */
+
+#if defined(TOPPERS_S810_CLG3_85)
+
+#define SLP_ITV		(30*SYSTIM_HZ)
+
+#else	/* of #if defined(TOPPERS_S810_CLG3_85) */
+
+#define SLP_ITV		(60*SYSTIM_HZ)
+
+#endif	/* of #if defined(TOPPERS_S810_CLG3_85) */
+
+/* 自動実行 */
+
+#if defined(UDP4_ECHO_CLI_AUTO_RUN_STR)
+#else
+#if 0
+#define UDP4_ECHO_CLI_AUTO_RUN_STR	"172.25.193.140 - 1000"
+#endif
+#endif
+
+/*
+ *  全域変数
+ */
+
+bool_t udp4_echo_cli_valid;
+
+/*
+ * 変数
+ */
+
+#define BUF_SIZE	2048
+
+static char		udp_buf[BUF_SIZE];
+static T_IPV4EP		dst;
+
+#if defined(USE_UDP_NON_BLOCKING)
+
+static ER_UINT		nblk_len;
+static ID		nblk_tskid;
+
+/*
+ *  ノンブロッキングコールのコールバック関数
+ */
+
+ER
+callback_nblk_udp4_echo_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	nblk_len = *(ER_UINT*)p_parblk;
+	syscall(wup_tsk(nblk_tskid));
+	return E_OK;
+	}
+
+/*
+ *  udp4_echo_cli -- ECHO/UDP サーバにメッセージを送信する (ノンブロッキングコール使用)。
+ */
+
+ER
+udp4_echo_cli (ID cepid, T_IN4_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	ER_UINT	error;
+	SYSTIM	time;
+	uint_t	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len         = strlen(line);
+	get_tim(&time);
+	get_tid(&nblk_tskid);
+	if ((error = udp_snd_dat(cepid, &dst, line, len, TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[UEC4:%02u SND(NBLK)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return error;
+		}
+	else
+		syslog(LOG_NOTICE, "[UEC4:%02u SND(NBLK)] send:  %7lu,  to: %s.%d\n"
+		                   "                                    msg: %s",
+		                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, line);
+
+	syscall(slp_tsk());
+	get_tim(&time);
+	if (nblk_len < 0) {	/* 0 以下の場合は、エラーコード */
+		syslog(LOG_NOTICE, "[UEC4:%02u CBR(NBLK)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return nblk_len;
+		}
+
+	if ((error = udp_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV(NBLK)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return error;
+		}
+
+	syscall(slp_tsk());
+	get_tim(&time);
+	if (nblk_len < 0) {	/* 0 以下の場合は、エラーコード */
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV(NBLK)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return nblk_len;
+		}
+	else {
+		udp_buf[nblk_len] = '\0';
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV(NBLK)] recv:  %7lu,from: %s.%d\n"
+		                   "                                    msg: %s",
+		                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		nblk_len = E_OK;
+		}
+
+	return nblk_len;
+	}
+
+#else	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#if defined(USE_UDP_CALL_BACK)
+
+/*
+ *  コールバック関数
+ */
+
+ER
+callback_udp4_echo_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	get_tim(&time);
+	if ((len = udp_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), TMO_FEVR)) >= 0) {
+		*(udp_buf + len) = '\0';
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV(CB)] recv:  %7lu,from: %s.%d\n"
+		                   "                                  msg: %s",
+		                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		}
+	else
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV(CB)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+
+	return E_OK;
+	}
+
+/*
+ *  udp4_echo_cli -- ECHO/UDP サーバにメッセージを送信する (コールバック関数使用)。
+ */
+
+ER
+udp4_echo_cli (ID cepid, T_IN4_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len        = strlen(line);
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[UEC4:%02u SND(CB)] send:  %7lu,  to: %s.%d\n"
+	                   "                                  msg: %s",
+	                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, line);
+	if ((len = udp_snd_dat(cepid, &dst, line, len, TMO_FEVR)) < 0)
+		syslog(LOG_NOTICE, "[UEC4:%02u SND(CB)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+
+	return E_OK;
+	}
+
+#else	/* of #if defined(USE_UDP_CALL_BACK) */
+
+/*
+ *  udp4_echo_cli -- ECHO/UDP サーバにメッセージを送信する (コールバック関数未使用)。
+ */
+
+ER
+udp4_echo_cli (ID cepid, T_IN4_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len         = strlen(line);
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[UEC4:%02u SND] send:  %7lu,  to: %s.%d\n"
+	                   "                              msg: %s",
+	                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, line);
+	if ((len = udp_snd_dat(cepid, &dst, line, len, TMO_FEVR)) < 0) {
+		syslog(LOG_NOTICE, "[UEC4:%02u SND] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+		return len;
+		}
+
+	if ((len = udp_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), 10*1000)) >= 0) {
+		*(udp_buf + len) = '\0';
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		return E_OK;
+		}
+	else {
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV] error: %7lu,%s",
+		       cepid, time / SYSTIM_HZ, itron_strerror(len));
+		return len;
+		}
+	}
+
+#endif	/* of #if defined(USE_UDP_CALL_BACK) */
+
+#endif	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+/*
+ *  getcomd -- コマンドを得る。
+ */
+
+#if defined(UDP4_ECHO_CLI_AUTO_RUN_STR)
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER		error;
+	char		*line = NULL;
+	static char	auto_run_str[] = UDP4_ECHO_CLI_AUTO_RUN_STR;
+	static int_t	count = 0;
+
+	if (retry || count == 0) {
+		line = auto_run_str;
+		dly_tsk(6 * 1000);
+		}
+	else {
+		while ((error = rcv_dtq(DTQ_UDP4_ECHO_CLI, (intptr_t*)&line)) != E_OK) {
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] error:%s", cepid, itron_strerror(error));
+			dly_tsk(SLP_ITV);
+			}
+		}
+
+	count ++;
+	return line;
+	}
+
+#else	/* of #if defined(UDP4_ECHO_CLI_AUTO_RUN_STR) */
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER	error;
+	char	*line = NULL;
+
+	while ((error = rcv_dtq(DTQ_UDP4_ECHO_CLI, (intptr_t*)&line)) != E_OK) {
+		syslog(LOG_NOTICE, "[UEC4:%02u TSK] error:%s", cepid, itron_strerror(error));
+		dly_tsk(SLP_ITV);
+		}
+	return line;
+	}
+
+#endif	/* of #if defined(UDP4_ECHO_CLI_AUTO_RUN_STR) */
+
+#define MESSAGE_FORMAT	"MSG 1000000"
+
+/*
+ *  UDP4 ECHO クライアント送信タスク
+ */
+
+void
+udp4_echo_cli_task (intptr_t exinf)
+{
+	static char msg[sizeof(MESSAGE_FORMAT)] = MESSAGE_FORMAT;
+
+	ID		tskid, cepid;
+	ER		error = E_OK;
+	SYSTIM		time;
+	T_IN4_ADDR	addr;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+	T_IN6_ADDR	addr6;
+#endif
+
+	char		*line, *p;
+	int_t		rep;
+	uint32_t	count, msgno;
+	bool_t		retry = false;
+	uint16_t	portno = ECHO_SRV_PORTNO;
+
+#if defined(USE_UDP_EXTENTIONS)
+	T_UDP_CCEP	ccep;
+#endif
+
+	dly_tsk(10*1000);
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP4 ECHO CLI:%d,%d] started.", tskid, (ID)exinf);
+	while (true) {
+		line = skip_blanks(getcomd((ID)exinf, retry));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+		line = lookup_ipaddr(&addr6, line, API_PROTO_IPV4);
+		if (line == NULL || !in6_is_addr_ipv4mapped(&addr6)) {
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] sleep %d.%03u[s], unknown host.",
+			       (ID)exinf, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			dly_tsk(SLP_ITV);
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] resume.", (ID)exinf);
+			retry = true;
+			continue;
+			}
+		addr = ntohl(addr6.s6_addr32[3]);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		if ((line = lookup_ipaddr(&addr, line, DEFAULT_API_PROTO)) == NULL) {
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] sleep %d.%03u[s], unknown host.",
+			       (ID)exinf, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			dly_tsk(SLP_ITV);
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] resume.", (ID)exinf);
+			retry = true;
+			continue;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {	/* Port No */
+			line = get_int(&rep, line);
+			portno = (uint16_t)rep;
+			}
+		else if (*line == '-')
+			line ++;
+
+#if defined(USE_UDP_EXTENTIONS)
+
+		ccep.cepatr = UINT_C(0);
+		ccep.myaddr.portno = UDP_PORTANY;
+
+#if defined(SUPPORT_INET6)
+
+		memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#else	/* #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+		ccep.myaddr.ipaddr = IPV4_ADDRANY;
+#endif
+
+#endif	/* #if defined(SUPPORT_INET6) */
+
+#if defined(USE_UDP_NON_BLOCKING)
+		ccep.callback = (FP)callback_nblk_udp4_echo_cli;
+#else
+		ccep.callback = NULL;
+#endif
+
+		if ((error = alloc_udp4_cep(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] CEP create error:%s", cepid, itron_strerror(error));
+			continue;
+			}
+
+#else/* of #if defined(USE_UDP_EXTENTIONS) */
+
+		cepid = (ID)exinf;
+
+#endif/* of #if defined(USE_UDP_EXTENTIONS) */
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {				/* Repeat */
+			line = get_int(&rep, line);
+#if 0
+			if (rep > 1000000)
+				rep = 1000000;
+#endif
+			udp4_echo_cli_valid = true;
+			count = 0;
+			while (rep == 0 || count < rep) {
+				if (!udp4_echo_cli_valid) {
+					syslog(LOG_NOTICE, "[UEC4:%02u TSK] canceled.", cepid);
+					break;
+					}
+					
+				count ++;
+				p = &msg[sizeof(MESSAGE_FORMAT)] - 1;
+				for (msgno = count; msgno > 0; msgno /= 10)
+					*(-- p) = msgno % 10 + '0';
+				while (*(p - 2) != 'G')
+					*(-- p) = ' ';
+
+				if ((error = udp4_echo_cli(cepid, &addr, portno, msg)) != E_OK)
+					dly_tsk(30 * SYSTIM_HZ);
+
+				dly_tsk(25 * SYSTIM_HZ + netapp_rand() % (10 * SYSTIM_HZ));
+				}
+			}
+
+		else								/* Single Message */
+			error = udp4_echo_cli(cepid, &addr, portno, line);
+
+		if (error != E_OK) {
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[UEC4:%02u SND] error: %7lu,%s",
+			                   cepid, time / SYSTIM_HZ, itron_strerror(error));
+			}
+
+#if defined(USE_UDP_EXTENTIONS)
+
+		if ((error = free_udp4_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] CEP delete error:%s", cepid, itron_strerror(error));
+
+#endif	/* of #if defined(USE_UDP_EXTENTIONS) */
+
+		}
+	}
+
+#endif	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.cfg	(revision 398)
@@ -0,0 +1,70 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ECHO サーバ試験プログラムのシステムコンフィギュレーションファイル
+ */
+
+#ifdef USE_UDP4_ECHO_CLI_TSK
+
+/* タスク */
+
+#ifdef USE_UDP_EXTENTIONS
+
+CRE_TSK(UDP4_ECHO_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	udp4_echo_cli_task,
+	UDP4_ECHO_CLI_MAIN_PRIORITY,
+	UDP4_ECHO_CLI_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+CRE_TSK(UDP4_ECHO_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	UDP4_ECHO_CLI_CEPID,
+	udp4_echo_cli_task,
+	UDP4_ECHO_CLI_MAIN_PRIORITY,
+	UDP4_ECHO_CLI_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+/* コマンドキュー */
+
+CRE_DTQ(DTQ_UDP4_ECHO_CLI,  { TA_TFIFO, 1, NULL });
+
+#endif	/* of #ifdef USE_UDP4_ECHO_CLI_TSK */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.h	(revision 398)
@@ -0,0 +1,62 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _UDP4_ECHO_CLI_H_
+#define _UDP4_ECHO_CLI_H_
+
+/* スタックサイズ */
+
+#define UDP4_ECHO_CLI_STACK_SIZE	1024		/* UDP ECHO クライアントタスク（IPv4）のスタックサイズ	*/
+
+/* 優先度 */
+
+#define UDP4_ECHO_CLI_MAIN_PRIORITY	5		/* UDP ECHO クライアントタスク（IPv4）の優先度		*/
+
+/* 変数 */
+
+extern bool_t	udp4_echo_cli_valid;
+
+/* タスク */
+
+extern void	udp4_echo_cli_task(intptr_t exinf);
+
+/* 関数 */
+
+extern ER callback_udp4_echo_cli (ID cepid, FN fncd, void *p_parblk);
+extern ER callback_nblk_udp4_echo_cli (ID cepid, FN fncd, void *p_parblk);
+
+#ifdef T_IN4_ADDR_DEFINED
+extern ER udp4_echo_cli (ID cepid, T_IN4_ADDR *ipaddr, uint16_t portno, char *line);
+#endif
+
+#endif	/* of #ifndef _UDP4_ECHO_CLI_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.c	(revision 398)
@@ -0,0 +1,303 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  UDP ECHO サーバ
+ *
+ *    IPv4
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/udp4_echo_srv.h>
+
+#ifdef USE_UDP4_ECHO_SRV_TSK
+
+/*
+ *  受信タイムアウト
+ */
+
+#define RCV_TMOUT	TMO_FEVR
+//#define RCV_TMOUT	(30*ULONG_C(1000))
+
+#define BUF_SIZE	2048
+
+static char	echo_rcv_buf[BUF_SIZE];
+static T_IPV4EP	dst;
+
+#ifdef USE_UDP_CALL_BACK
+
+/*
+ *  コールバック関数
+ */
+
+ER
+callback_udp4_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	ER_UINT	len;
+	SYSTIM	now;
+
+	if ((len = udp_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), TMO_FEVR)) >= 0) {
+		echo_rcv_buf[len] = '\0';
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES4:%02u UCB] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		if (len > 0) {
+			len = udp_snd_dat(cepid, &dst, echo_rcv_buf, len, TMO_FEVR);
+			get_tim(&now);
+			if (len >= 0)
+				syslog(LOG_NOTICE, "[UES4:%02u UCB] send:  %7lu, len: %d",
+				                   cepid, now / SYSTIM_HZ, len);
+			else
+				syslog(LOG_NOTICE, "[UES4:%02u UCB] error: %7lu,%s",
+				                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+			}
+		len = E_OK;
+		}
+	else {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES4:%02u UCB] error: %7lu,%s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+		}
+
+	return len;
+	}
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+#ifdef USE_UDP_NON_BLOCKING
+
+/*
+ *  変数
+ */
+
+static ER_UINT		nblk_len;
+
+/*
+ *  ノンブロッキングコールのコールバック関数
+ */
+
+ER
+callback_nblk_udp4_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	SYSTIM	now;
+
+	get_tim(&now);
+	nblk_len = *(ER_UINT*)p_parblk;
+	if (nblk_len < 0) {	/* 0 以下の場合は、エラーコード */
+		syslog(LOG_NOTICE, "[UES4:%02u CBR] error,      %7lu,%s, fncd: %s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(nblk_len), in_strtfn(fncd));
+		}
+	else if (fncd == TFN_UDP_RCV_DAT) {
+		echo_rcv_buf[nblk_len] = '\0';
+		syslog(LOG_NOTICE, "[UES4:%02u CBR] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		}
+	syscall(wup_tsk(UDP4_ECHO_SRV_TASK));
+	return E_OK;
+	}
+
+/*
+ *  UDP ECHO サーバ
+ */
+
+ER
+udp4_echo_srv (ID cepid)
+{
+	ER	error;
+	SYSTIM	now;
+
+	if ((error = udp_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), TMO_NBLK)) != E_WBLK) {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES4:%02u RCV] error: %7lu,%s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(error));
+		return error;
+		}
+
+	syscall(slp_tsk());
+	if (nblk_len < 0)
+		error = nblk_len;
+	else {
+		if ((error = udp_snd_dat(cepid, &dst, echo_rcv_buf, nblk_len, TMO_NBLK)) != E_WBLK) {
+			get_tim(&now);
+			syslog(LOG_NOTICE, "[UES4:%02u SND] error: %7lu,%s",
+			                   cepid, now / SYSTIM_HZ, itron_strerror(error));
+			return error;
+			}
+
+		syscall(slp_tsk());
+		if (nblk_len < 0)
+			error = nblk_len;
+		else {
+			get_tim(&now);
+			syslog(LOG_NOTICE, "[UES4:%02u SND] send:  %7lu, len: %d",
+			                   cepid, now / SYSTIM_HZ, nblk_len);
+			error = E_OK;
+			}
+		}
+
+	return error;
+	}
+
+#else	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+/*
+ *  UDP ECHO サーバ
+ */
+
+ER
+udp4_echo_srv (ID cepid)
+{
+	ER_UINT	len;
+	SYSTIM	now;
+
+	if ((len = udp_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), RCV_TMOUT)) >= 0) {
+		get_tim(&now);
+		echo_rcv_buf[len] = '\0';
+		syslog(LOG_NOTICE, "[UES4:%02u RCV] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		if (len > 0) {
+			len = udp_snd_dat(cepid, &dst, echo_rcv_buf, len, TMO_FEVR);
+			get_tim(&now);
+			if (len >= 0)
+				syslog(LOG_NOTICE, "[UES4:%02u SND] send:  %7lu, len: %d",
+				                   cepid, now / SYSTIM_HZ, (uint16_t)len);
+			else
+				syslog(LOG_NOTICE, "[UES4:%02u SND] error: %7lu,%s",
+				                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+			}
+		}
+	else {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES4:%02u RCV] error: %7lu,%s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+		}
+
+	return len >= 0 || len == E_TMOUT ? E_OK : len;
+	}
+
+#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+/*
+ *  UDP ECHO サーバタスク
+ */
+
+#ifdef USE_UDP_EXTENTIONS
+
+void
+udp4_echo_srv_task (intptr_t exinf)
+{
+	ID		tskid, cepid;
+	ER		error;
+	T_UDP_CCEP	ccep;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP4 ECHO SRV(EXT):%d] started.", tskid);
+	while (true) {
+
+		syscall(slp_tsk());
+		syslog(LOG_NOTICE, "[UDP4 ECHO SRV(EXT):%d] wake up.", tskid);
+
+		ccep.cepatr = UINT_C(0);
+		ccep.myaddr.portno = UINT_C(7);
+		ccep.myaddr.ipaddr = IPV4_ADDRANY;
+
+#ifdef USE_UDP_NON_BLOCKING
+		ccep.callback = (FP)callback_nblk_udp4_echo_srv;
+#else
+		ccep.callback = NULL;
+#endif
+
+		if ((error = alloc_udp4_cep(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[UES4:%02u TSK] CEP create error:%s", cepid, itron_strerror(error));
+			continue;
+			}
+
+		while (error == E_OK) {
+			if ((error = udp4_echo_srv(cepid)) != E_OK) {
+				if ((error = free_udp4_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
+					syslog(LOG_NOTICE, "[UES4:%02u TSK] CEP delete error:%s", cepid, itron_strerror(error));
+				break;
+				}
+			}
+
+		}
+	slp_tsk();
+	}
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+void
+udp4_echo_srv_task (intptr_t exinf)
+{
+	ID	tskid;
+	ER	error = E_OK;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP4 ECHO SRV:%d,%d] started.", tskid, (ID)exinf);
+	while (error == E_OK) {
+		error = udp4_echo_srv((ID)exinf);
+		}
+	slp_tsk();
+	}
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP4_ECHO_SRV_TSK */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.cfg	(revision 398)
@@ -0,0 +1,76 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO サーバコンフィギュレーションファイル
+ *
+ *    IPv4
+ */
+
+#ifdef USE_UDP4_ECHO_SRV_TSK
+
+/*
+ * タスク
+ */
+
+#ifdef USE_UDP_CALL_BACK
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+#ifdef USE_UDP_EXTENTIONS
+
+CRE_TSK(UDP4_ECHO_SRV_TASK, {
+	TA_HLNG | TA_ACT,
+	0,
+	udp4_echo_srv_task,
+	UDP4_ECHO_SRV_MAIN_PRIORITY,
+	UDP4_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+CRE_TSK(UDP4_ECHO_SRV_TASK, {
+	TA_HLNG | TA_ACT,
+	UDP4_ECHO_SRV_CEPID,
+	udp4_echo_srv_task,
+	UDP4_ECHO_SRV_MAIN_PRIORITY,
+	UDP4_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP4_ECHO_SRV_TSK */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.h	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _UDP4_ECHO_SRV_H_
+#define _UDP4_ECHO_SRV_H_
+
+/* スタックサイズ */
+
+#define UDP4_ECHO_SRV_STACK_SIZE	1024		/* UDP ECHO サーバタスク（IPV4）のスタックサイズ	*/
+
+/* 優先度 */
+
+#define UDP4_ECHO_SRV_MAIN_PRIORITY	5		/* UDP ECHO サーバタスク（IPV4）の優先度		*/
+
+/* タスク */
+
+extern void	udp4_echo_srv_task(intptr_t exinf);
+
+/* 関数 */
+
+extern ER callback_udp4_echo_srv (ID cepid, FN fncd, void *p_parblk);
+extern ER callback_nblk_udp4_echo_srv (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _UDP4_ECHO_SRV_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.c	(revision 398)
@@ -0,0 +1,447 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  UDP6 ECHO クライアント
+ */
+
+#include <string.h>
+
+#if defined(TARGET_KERNEL_ASP)
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #if defined(TARGET_KERNEL_ASP) */
+
+#if defined(TARGET_KERNEL_JSP)
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #if defined(TARGET_KERNEL_JSP) */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/udp4_echo_cli.h>
+#include <netapp/udp6_echo_cli.h>
+
+#if defined(USE_UDP6_ECHO_CLI_TSK)
+
+/* echo サーバのポート番号 */
+
+#define ECHO_SRV_PORTNO		UINT_C(7)
+
+/* 送信間隔 */
+
+#if defined(TOPPERS_S810_CLG3_85)
+
+#define SLP_ITV		(30*SYSTIM_HZ)
+
+#else	/* of #if defined(TOPPERS_S810_CLG3_85) */
+
+#define SLP_ITV		(60*SYSTIM_HZ)
+
+#endif	/* of #if defined(TOPPERS_S810_CLG3_85) */
+
+/* 自動実行 */
+
+#if defined(UDP6_ECHO_CLI_AUTO_RUN_STR)
+#else
+#if 0
+#define UDP6_ECHO_CLI_AUTO_RUN_STR	"fe80::211:2fff:fe8a:e8c0 - 1000"
+#endif
+#endif
+
+/*
+ *  全域変数
+ */
+
+bool_t udp6_echo_cli_valid;
+
+/*
+ * 変数
+ */
+
+#define BUF_SIZE	2048
+
+static char		udp_buf[BUF_SIZE];
+static T_IPV6EP		dst;
+
+#if defined(USE_UDP_NON_BLOCKING)
+
+static ER_UINT		nblk_len;
+static ID		nblk_tskid;
+
+/*
+ *  ノンブロッキングコールのコールバック関数
+ */
+
+ER
+callback_nblk_udp6_echo_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	nblk_len = *(ER_UINT*)p_parblk;
+	syscall(wup_tsk(nblk_tskid));
+	return E_OK;
+	}
+
+/*
+ *  udp6_echo_cli -- ECHO/UDP サーバにメッセージを送信する (ノンブロッキングコール使用)。
+ */
+
+static ER
+udp6_echo_cli (ID cepid, T_IN6_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	ER_UINT	error;
+	SYSTIM	time;
+	uint_t	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len         = strlen(line);
+	get_tim(&time);
+	get_tid(&nblk_tskid);
+	if ((error = udp6_snd_dat(cepid, &dst, line, len, TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[UEC6:%02u SDN] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return error;
+		}
+	else
+		syslog(LOG_NOTICE, "[UEC6:%02u SDN] send:  %7lu,  to: %s.%d\n"
+		                   "                                    msg: %s",
+		                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, line);
+
+	syscall(slp_tsk());
+	get_tim(&time);
+	if (nblk_len < 0) {	/* 0 以下の場合は、エラーコード */
+		syslog(LOG_NOTICE, "[UEC6:%02u CBR] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return nblk_len;
+		}
+
+	if ((error = udp6_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[UEC6:%02u RVN] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return error;
+		}
+
+	syscall(slp_tsk());
+	get_tim(&time);
+	if (nblk_len < 0) {	/* 0 以下の場合は、エラーコード */
+		syslog(LOG_NOTICE, "[UEC6:%02u RVN] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return nblk_len;
+		}
+	else {
+		udp_buf[nblk_len] = '\0';
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC6:%02u RVN] recv:  %7lu,from: %s.%d\n"
+		                   "                                    msg: %s",
+		                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		nblk_len = E_OK;
+		}
+
+	return nblk_len;
+	}
+
+#else	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#if defined(USE_UDP_CALL_BACK)
+
+/*
+ *  コールバック関数
+ */
+
+ER
+callback_udp6_echo_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	get_tim(&time);
+	if ((len = udp6_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), TMO_FEVR)) >= 0) {
+		*(udp_buf + len) = '\0';
+		syslog(LOG_NOTICE, "[UEC6:%02u RVC)] recv:  %7lu,from: %s.%d\n"
+		                   "                                  msg: %s",
+		                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		}
+	else
+		syslog(LOG_NOTICE, "[UEC6:%02u RVC] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+
+	return E_OK;
+	}
+
+/*
+ *  udp6_echo_cli -- ECHO/UDP サーバにメッセージを送信する (コールバック関数使用)。
+ */
+
+static ER
+udp6_echo_cli (ID cepid, T_IN6_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len        = strlen(line);
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[UEC6:%02u SDC)] send:  %7lu,  to: %s.%d\n"
+		           "                                  msg: %s",
+	                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, line);
+	if ((len = udp6_snd_dat(cepid, &dst, line, len, TMO_FEVR)) < 0)
+		syslog(LOG_NOTICE, "[UEC6:%02u SDC] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+
+	return E_OK;
+	}
+
+#else	/* of #if defined(USE_UDP_CALL_BACK) */
+
+/*
+ *  udp6_echo_cli -- ECHO/UDP サーバにメッセージを送信する (コールバック関数未使用)。
+ */
+
+static ER
+udp6_echo_cli (ID cepid, T_IN6_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len         = strlen(line);
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[UEC6:%02u SND] send:  %7lu,  to: %s.%d\n"
+		           "                              msg: %s",
+	                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, line);
+	if ((len = udp6_snd_dat(cepid, &dst, line, len, TMO_FEVR)) < 0) {
+		syslog(LOG_NOTICE, "[UEC6:%02u SND] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+		return len;
+		}
+
+	if ((len = udp6_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), 10*1000)) >= 0) {
+		*(udp_buf + len) = '\0';
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC6:%02u RCV] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		return E_OK;
+		}
+	else {
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC6:%02u RCV] error: %7lu,%s",
+		       cepid, time / SYSTIM_HZ, itron_strerror(len));
+		return len;
+		}
+	}
+
+#endif	/* of #if defined(USE_UDP_CALL_BACK) */
+
+#endif	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+/*
+ *  getcomd -- コマンドを得る。
+ */
+
+#if defined(UDP6_ECHO_CLI_AUTO_RUN_STR)
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER		error;
+	char		*line = NULL;
+	static char	auto_run_str[] = UDP6_ECHO_CLI_AUTO_RUN_STR;
+	static int_t	count = 0;
+
+	if (retry || count == 0) {
+		line = auto_run_str;
+		dly_tsk(6 * 1000);
+		}
+	else {
+		while ((error = rcv_dtq(DTQ_UDP6_ECHO_CLI, (intptr_t*)&line)) != E_OK) {
+			syslog(LOG_NOTICE, "[UEC6:%02u TSK] error:%s", cepid, itron_strerror(error));
+			dly_tsk(SLP_ITV);
+			}
+		}
+
+	count ++;
+	return line;
+	}
+
+#else	/* of #if defined(UDP6_ECHO_CLI_AUTO_RUN_STR) */
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER	error;
+	char	*line = NULL;
+
+	while ((error = rcv_dtq(DTQ_UDP6_ECHO_CLI, (intptr_t*)&line)) != E_OK) {
+		syslog(LOG_NOTICE, "[UEC6:%02u TSK] error:%s", cepid, itron_strerror(error));
+		dly_tsk(SLP_ITV);
+		}
+	return line;
+	}
+
+#endif	/* of #if defined(UDP6_ECHO_CLI_AUTO_RUN_STR) */
+
+#define MESSAGE_FORMAT	"MSG 1000000"
+
+/*
+ *  UDP6 ECHO クライアント送信タスク
+ */
+
+void
+udp6_echo_cli_task (intptr_t exinf)
+{
+	static char msg[sizeof(MESSAGE_FORMAT)] = MESSAGE_FORMAT;
+
+	ID		tskid, cepid;
+	ER		error = E_OK;
+	SYSTIM		time;
+	T_IN6_ADDR	addr;
+	char		*line, *p;
+	int_t		rep;
+	uint32_t	count, msgno;
+	bool_t		retry = false;
+	uint16_t	portno = ECHO_SRV_PORTNO;
+
+#if defined(USE_UDP_EXTENTIONS)
+	T_UDP6_CCEP	ccep;
+#endif
+
+	dly_tsk(10*1000);
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP6 ECHO CLI:%d,%d] started.", tskid, (ID)exinf);
+	while (true) {
+		line = skip_blanks(getcomd((ID)exinf, retry));
+
+		if ((line = lookup_ipaddr(&addr, line, API_PROTO_IPV6)) == NULL) {
+			syslog(LOG_NOTICE, "[UEC6:%02u TSK] sleep %d.%03u[s], unknown host.",
+			       (ID)exinf, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			dly_tsk(SLP_ITV);
+			syslog(LOG_NOTICE, "[UEC6:%02u TSK] resume.", (ID)exinf);
+			retry = true;
+			continue;
+			}
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {	/* Port No */
+			line = get_int(&rep, line);
+			portno = (uint16_t)rep;
+			}
+		else if (*line == '-')
+			line ++;
+
+#if defined(USE_UDP_EXTENTIONS)
+
+		ccep.cepatr = UINT_C(0);
+		ccep.myaddr.portno = UDP_PORTANY;
+		memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#ifdef USE_UDP_NON_BLOCKING
+		ccep.callback = (FP)callback_nblk_udp6_echo_cli;
+#else
+		ccep.callback = NULL;
+#endif
+
+		if ((error = alloc_udp6_cep(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[UEC6:%02u TSK] CEP create error:%s", cepid, itron_strerror(error));
+			continue;
+			}
+
+#else/* of #ifdef USE_UDP_EXTENTIONS */
+
+		cepid = (ID)exinf;
+
+#endif	/* of #if defined(USE_UDP_EXTENTIONS) */
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {				/* Repeat */
+			line = get_int(&rep, line);
+#if 0
+			if (rep > 1000000)
+				rep = 1000000;
+#endif
+			udp6_echo_cli_valid = true;
+			count = 0;
+			while (rep == 0 || count < rep) {
+				if (!udp6_echo_cli_valid) {
+					syslog(LOG_NOTICE, "[UEC6:%02u TSK] canceled.", cepid);
+					break;
+					}
+					
+				count ++;
+				p = &msg[sizeof(MESSAGE_FORMAT)] - 1;
+				for (msgno = count; msgno > 0; msgno /= 10)
+					*(-- p) = msgno % 10 + '0';
+				while (*(p - 2) != 'G')
+					*(-- p) = ' ';
+
+				if ((error = udp6_echo_cli(cepid, &addr, portno, msg)) != E_OK)
+					dly_tsk(30 * SYSTIM_HZ);
+
+				dly_tsk(25 * SYSTIM_HZ + netapp_rand() % (10 * SYSTIM_HZ));
+				}
+			}
+
+		else								/* Single Message */
+
+			error = udp6_echo_cli(cepid, &addr, portno, line);
+
+		if (error != E_OK) {
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[UEC6:%02u SND] error: %7lu,%s",
+			                   cepid, time / SYSTIM_HZ, itron_strerror(error));
+			}
+
+#if defined(USE_UDP_EXTENTIONS)
+
+		if ((error = free_udp6_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
+			syslog(LOG_NOTICE, "[UEC6:%02u TSK] CEP delete error:%s", cepid, itron_strerror(error));
+
+#endif	/* of #if defined(USE_UDP_EXTENTIONS) */
+
+		}
+	}
+
+#endif	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.cfg	(revision 398)
@@ -0,0 +1,70 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ECHO サーバ試験プログラムのシステムコンフィギュレーションファイル
+ */
+
+#ifdef USE_UDP6_ECHO_CLI_TSK
+
+/* タスク */
+
+#ifdef USE_UDP_EXTENTIONS
+
+CRE_TSK(UDP6_ECHO_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	udp6_echo_cli_task,
+	UDP6_ECHO_CLI_MAIN_PRIORITY,
+	UDP6_ECHO_CLI_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+CRE_TSK(UDP6_ECHO_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	UDP6_ECHO_CLI_CEPID,
+	udp6_echo_cli_task,
+	UDP6_ECHO_CLI_MAIN_PRIORITY,
+	UDP6_ECHO_CLI_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+/* コマンドキュー */
+
+CRE_DTQ(DTQ_UDP6_ECHO_CLI,  { TA_TFIFO, 1, NULL });
+
+#endif	/* of #ifdef USE_UDP6_ECHO_CLI_TSK */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.h	(revision 398)
@@ -0,0 +1,58 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _UDP6_ECHO_CLI_H_
+#define _UDP6_ECHO_CLI_H_
+
+/* スタックサイズ */
+
+#define UDP6_ECHO_CLI_STACK_SIZE	1024		/* UDP ECHO クライアントタスク（IPv6）のスタックサイズ	*/
+
+/* 優先度 */
+
+#define UDP6_ECHO_CLI_MAIN_PRIORITY	5		/* UDP ECHO クライアントタスク（IPv6）の優先度		*/
+
+/* 変数 */
+
+extern bool_t	udp6_echo_cli_valid;
+
+/* タスク */
+
+extern void	udp6_echo_cli_task(intptr_t exinf);
+
+/* 関数 */
+
+extern ER callback_udp6_echo_cli (ID cepid, FN fncd, void *p_parblk);
+extern ER callback_nblk_udp6_echo_cli (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _UDP6_ECHO_CLI_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.c	(revision 398)
@@ -0,0 +1,302 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  UDP ECHO サーバ
+ *
+ *    IPv6
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/udp6_echo_srv.h>
+
+#ifdef USE_UDP6_ECHO_SRV_TSK
+
+/*
+ *  受信タイムアウト
+ */
+
+#define RCV_TMOUT	TMO_FEVR
+//#define RCV_TMOUT	(30*ULONG_C(1000))
+
+#define BUF_SIZE	2048
+
+static char	echo_rcv_buf[BUF_SIZE];
+static T_IPV6EP	dst;
+
+#ifdef USE_UDP_CALL_BACK
+
+/*
+ *  コールバック関数
+ */
+
+ER
+callback_udp6_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	ER_UINT	len;
+	SYSTIM	now;
+
+	if ((len = udp6_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), TMO_FEVR)) >= 0) {
+		echo_rcv_buf[len] = '\0';
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES6:%02u UCB] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		if (len > 0) {
+			len = udp6_snd_dat(cepid, &dst, echo_rcv_buf, len, TMO_FEVR);
+			get_tim(&now);
+			if (len >= 0)
+				syslog(LOG_NOTICE, "[UES6:%02u UCB] send:  %7lu, len: %d",
+				                   cepid, now / SYSTIM_HZ, len);
+			else
+				syslog(LOG_NOTICE, "[UES6:%02u UCB] error: %7lu,%s",
+				                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+			}
+		len = E_OK;
+		}
+	else {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES6:%02u UCB] recv:  %7lu,%s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+		}
+
+	return len;
+	}
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+#ifdef USE_UDP_NON_BLOCKING
+
+/*
+ *  変数
+ */
+
+static ER_UINT		nblk_len;
+
+/*
+ *  ノンブロッキングコールのコールバック関数
+ */
+
+ER
+callback_nblk_udp6_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	SYSTIM	now;
+
+	get_tim(&now);
+	nblk_len = *(ER_UINT*)p_parblk;
+	if (nblk_len < 0) {	/* 0 以下の場合は、エラーコード */
+		syslog(LOG_NOTICE, "[UES6:%02u CBR] error: %7lu,%s, fncd: %s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(nblk_len), in_strtfn(fncd));
+		}
+	else if (fncd == TFN_UDP_RCV_DAT) {
+		echo_rcv_buf[nblk_len] = '\0';
+		syslog(LOG_NOTICE, "[UES6:%02u CBR] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		}
+	syscall(wup_tsk(UDP6_ECHO_SRV_TASK));
+	return E_OK;
+	}
+
+/*
+ *  UDP ECHO サーバ
+ */
+
+ER
+udp6_echo_srv (ID cepid)
+{
+	ER	error;
+	SYSTIM	now;
+
+	if ((error = udp6_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), TMO_NBLK)) != E_WBLK) {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES6:%02u RCV] error: %7lu,%s", cepid, now / SYSTIM_HZ, itron_strerror(error));
+		return error;
+		}
+
+	syscall(slp_tsk());
+	if (nblk_len < 0)
+		error = nblk_len;
+	else {
+		if ((error = udp6_snd_dat(cepid, &dst, echo_rcv_buf, nblk_len, TMO_NBLK)) != E_WBLK) {
+			get_tim(&now);
+			syslog(LOG_NOTICE, "[UES6:%02u SND] error  %7lu,%s",
+			                   cepid, now / SYSTIM_HZ, itron_strerror(error));
+			return error;
+			}
+
+		syscall(slp_tsk());
+		if (nblk_len < 0)
+			error = nblk_len;
+		else {
+			get_tim(&now);
+			syslog(LOG_NOTICE, "[UES6:%02u SND] send:  %7lu, len: %d",
+			                   cepid, now / SYSTIM_HZ, nblk_len);
+			error = E_OK;
+			}
+		}
+
+	return error;
+	}
+
+#else	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+/*
+ *  UDP ECHO サーバ
+ */
+
+ER
+udp6_echo_srv (ID cepid)
+{
+	ER_UINT	len;
+	SYSTIM	now;
+
+	if ((len = udp6_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), RCV_TMOUT)) >= 0) {
+		get_tim(&now);
+		echo_rcv_buf[len] = '\0';
+		syslog(LOG_NOTICE, "[UES6:%02u RCV] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		if (len > 0) {
+			len = udp6_snd_dat(cepid, &dst, echo_rcv_buf, len, TMO_FEVR);
+			get_tim(&now);
+			if (len >= 0)
+				syslog(LOG_NOTICE, "[UES6:%02u SND] send:  %7lu, len: %d",
+				                   cepid, now / SYSTIM_HZ, (uint16_t)len);
+			else
+				syslog(LOG_NOTICE, "[UES6:%02u SND] error: %7lu,%s",
+				                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+			}
+		}
+	else {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES6:%02u RCV] error: %7lu,%s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+		}
+
+	return len >= 0 || len == E_TMOUT ? E_OK : len;
+	}
+
+#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+/*
+ *  UDP ECHO サーバタスク
+ */
+
+#ifdef USE_UDP_EXTENTIONS
+
+void
+udp6_echo_srv_task (intptr_t exinf)
+{
+	ID		tskid, cepid;
+	ER		error;
+	T_UDP6_CCEP	ccep;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP6 ECHO SRV(EXT):%d] started.", tskid);
+	while (true) {
+
+		syscall(slp_tsk());
+		syslog(LOG_NOTICE, "[UDP6 ECHO SRV(EXT):%d] wake up.", tskid);
+
+		ccep.cepatr = UINT_C(0);
+		ccep.myaddr.portno = UINT_C(7);
+		memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#ifdef USE_UDP_NON_BLOCKING
+		ccep.callback = (FP)callback_nblk_udp6_echo_srv;
+#else
+		ccep.callback = NULL;
+#endif
+
+		if ((error = alloc_udp6_cep(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[UES6:%02u TSK] CEP create error:%s", cepid, itron_strerror(error));
+			continue;
+			}
+
+		while (error == E_OK) {
+			if ((error = udp6_echo_srv(cepid)) != E_OK) {
+				if ((error = free_udp6_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
+					syslog(LOG_NOTICE, "[UES6:%02u TSK] CEP delete error:%s", cepid, itron_strerror(error));
+				break;
+				}
+			}
+
+		}
+	slp_tsk();
+	}
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+void
+udp6_echo_srv_task (intptr_t exinf)
+{
+	ID	tskid;
+	ER	error = E_OK;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP6 ECHO SRV:%d,%d] started.", tskid, (ID)exinf);
+	while (error == E_OK) {
+		error = udp6_echo_srv((ID)exinf);
+		}
+	slp_tsk();
+	}
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP6_ECHO_SRV_TSK */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.cfg	(revision 398)
@@ -0,0 +1,76 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO サーバコンフィギュレーションファイル
+ *
+ *    IPv6
+ */
+
+#ifdef USE_UDP6_ECHO_SRV_TSK
+
+/*
+ * タスク
+ */
+
+#ifdef USE_UDP_CALL_BACK
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+#ifdef USE_UDP_EXTENTIONS
+
+CRE_TSK(UDP6_ECHO_SRV_TASK, {
+	TA_HLNG | TA_ACT,
+	0,
+	udp6_echo_srv_task,
+	UDP6_ECHO_SRV_MAIN_PRIORITY,
+	UDP6_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+CRE_TSK(UDP6_ECHO_SRV_TASK, {
+	TA_HLNG | TA_ACT,
+	UDP6_ECHO_SRV_CEPID,
+	udp6_echo_srv_task,
+	UDP6_ECHO_SRV_MAIN_PRIORITY,
+	UDP6_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP6_ECHO_SRV_TSK */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.h	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _UDP6_ECHO_SRV_H_
+#define _UDP6_ECHO_SRV_H_
+
+/* スタックサイズ */
+
+#define UDP6_ECHO_SRV_STACK_SIZE	1024		/* UDP ECHO サーバタスク（IPv6）のスタックサイズ		*/
+
+/* 優先度 */
+
+#define UDP6_ECHO_SRV_MAIN_PRIORITY	5		/* UDP ECHO サーバタスク（IPv6）の優先度			*/
+
+/* タスク */
+
+extern void	udp6_echo_srv_task(intptr_t exinf);
+
+/* 関数 */
+
+extern ER callback_udp6_echo_srv (ID cepid, FN fncd, void *p_parblk);
+extern ER callback_nblk_udp6_echo_srv (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _UDP6_ECHO_SRV_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.c	(revision 398)
@@ -0,0 +1,238 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  UDP DISCARD クライアント
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/udp_discard_cli.h>
+
+#ifdef USE_UDP_DISCARD_CLI
+
+/* discard サーバのポート番号 */
+
+#define DISCARD_SRV_PORTNO	UINT_C(9)
+
+/*
+ * 変数
+ */
+
+#define PAT_BEGIN	' '
+#define PAT_END		'~'
+
+#if defined(SUPPORT_INET6)
+#define API_PROTO		'6'
+#else
+#define API_PROTO		'4'
+#endif
+
+/*
+ *  全域変数
+ */
+
+bool_t udp_discard_cli_valid;
+
+/*
+ *  send_udp_discard -- DISCARD/UDP サーバにメッセージを送信する。
+ */
+
+static ER
+send_udp_discard (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno)
+{
+#if defined(SUPPORT_INET6)
+	static char smsg[IPV6_MMTU - (IP6_HDR_SIZE + UDP_HDR_SIZE)];
+#else
+	static char smsg[IP4_MSS - (IP4_HDR_SIZE + UDP_HDR_SIZE)];
+#endif
+
+	T_IPEP		dst;
+	ER_UINT		len;
+	SYSTIM		time;
+	char		*p;
+	uint32_t	total;
+	uint16_t	pat, slen, scount;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+
+	p = smsg;
+	for (slen = sizeof(smsg); slen > 0; )
+		for (pat = PAT_BEGIN; slen > 0 && pat <= PAT_END; pat ++, slen --)
+			*p ++ = pat;
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[UDC%c:%02u SND] send:  %7lu, to:   %s.%d",
+	                   API_PROTO, cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+
+	scount = total = 0;
+	udp_discard_cli_valid = true;
+	for (slen = sizeof(smsg); udp_discard_cli_valid && slen > 0; slen --) {
+		scount ++;
+		if ((len = UDP_SND_DAT(cepid, &dst, smsg, slen, TMO_FEVR)) < 0) {
+			syslog(LOG_NOTICE, "[UDC%c:%02u SND] error: %s", API_PROTO, cepid, itron_strerror(len));
+			return len;
+			}
+		else
+			syslog(LOG_NOTICE, "[UDC%c:%02u SND] send:  %7lu, %4u", API_PROTO, cepid, scount, slen);
+		total += len;
+		dly_tsk(10 * SYSTIM_HZ + netapp_rand() % (10 * SYSTIM_HZ));
+		}
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[UDC%c:%02u SND] finsh: %7lu, snd: %4u,            len: %ld",
+		           API_PROTO, cepid, time / SYSTIM_HZ, scount, total);
+	return E_OK;
+	}
+
+/*
+ *  UDP DISCARD クライアント送信タスク
+ */
+
+void
+udp_discard_cli_task (intptr_t exinf)
+{
+	T_IN_ADDR	addr;
+	ID		tskid, cepid;
+	ER		error;
+	char		*line;
+	int_t		no;
+	uint16_t	portno;
+	char		apip;
+
+#ifdef USE_UDP_EXTENTIONS
+
+#if defined(SUPPORT_INET6)
+	T_UDP6_CCEP	ccep;
+#else
+	T_UDP_CCEP	ccep;
+#endif
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#if defined(SUPPORT_INET6)
+	apip = API_PROTO_IPV6;
+#else
+	apip = API_PROTO_IPV4;
+#endif
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP DISCARD CLI:%d,%d] started.", tskid, (ID)exinf);
+	while (true) {
+		if (rcv_dtq(DTQ_UDP_DISCARD_CLI, (intptr_t*)&line) == E_OK) {
+			line = skip_blanks(GET_IPADDR(&addr, skip_blanks(line)));	/* IP Address */
+
+			if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
+				syslog(LOG_NOTICE, "[UDC%c:%02u TSK] unknown host.", (ID)exinf);
+				continue;
+				}
+
+			if ('0' <= *line && *line <= '9') {				/* Port No */
+				line = get_int(&no, line);
+				portno = (uint16_t)no;
+				}
+			else {
+				line ++;
+				portno = DISCARD_SRV_PORTNO;
+				}
+
+#ifdef USE_UDP_EXTENTIONS
+
+			ccep.cepatr = UINT_C(0);
+			ccep.callback = NULL;
+			ccep.myaddr.portno = UDP_PORTANY;
+
+#if defined(SUPPORT_INET6)
+
+			memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#else	/* #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+			ccep.myaddr.ipaddr = IPV4_ADDRANY;
+#endif
+
+#endif	/* #if defined(SUPPORT_INET6) */
+
+			if ((error = ALLOC_UDP_CEP(&cepid, tskid, &ccep)) != E_OK) {
+				syslog(LOG_NOTICE, "[UDC%c:%02u TSK] CEP create error: %s", API_PROTO, cepid, itron_strerror(error));
+				continue;
+				}
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+			cepid = (ID)exinf;
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+			if ((error = send_udp_discard(cepid, &addr, portno)) != E_OK)
+				syslog(LOG_NOTICE, "[UDC%c:%02u TSK] error: %s", API_PROTO, cepid, itron_strerror(error));
+
+#ifdef USE_UDP_EXTENTIONS
+
+			if ((error = FREE_UDP_CEP(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
+				syslog(LOG_NOTICE, "[UDC%c:%02u TSK] CEP delete error: %s", API_PROTO, cepid, itron_strerror(error));
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+			}
+		}
+	}
+
+#endif	/* of #ifdef USE_UDP_DISCARD_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.cfg	(revision 398)
@@ -0,0 +1,71 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP DISCARD クライアント
+ *  コンフィギュレーションファイル
+ */
+
+#ifdef USE_UDP_DISCARD_CLI
+
+/* タスク */
+
+#ifdef USE_UDP_EXTENTIONS
+
+CRE_TSK(UDP_DISCARD_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	udp_discard_cli_task,
+	UDP_DISCARD_CLI_MAIN_PRIORITY,
+	UDP_DISCARD_CLI_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+CRE_TSK(UDP_DISCARD_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	UDP_DISCARD_CLI_CEPID,
+	udp_discard_cli_task,
+	UDP_DISCARD_CLI_MAIN_PRIORITY,
+	UDP_DISCARD_CLI_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+/* コマンドキュー */
+
+CRE_DTQ(DTQ_UDP_DISCARD_CLI,  { TA_TFIFO, 1, NULL });
+
+#endif	/* of #ifdef USE_UDP_DISCARD_CLI */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.h	(revision 398)
@@ -0,0 +1,58 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _UDP_DISCARD_CLI_H_
+#define _UDP_DISCARD_CLI_H_
+
+/* スタックサイズ */
+
+#define UDP_DISCARD_CLI_STACK_SIZE	1024		/* UDP DISCARD クライアントタスクのスタックサイズ	*/
+
+/* 優先度 */
+
+#define UDP_DISCARD_CLI_MAIN_PRIORITY	5		/* UDP DISCARD クライアントタスクの優先度		*/
+
+/* 変数 */
+
+extern bool_t	udp_discard_cli_valid;
+
+/* タスク */
+
+extern void	udp_discard_cli_task(intptr_t exinf);
+
+/* 関数 */
+
+extern ER callback_udp_discard_cli (ID cepid, FN fncd, void *p_parblk);
+extern ER callback_nblk_udp_discard_cli (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _UDP_DISCARD_CLI_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws.c	(revision 398)
@@ -0,0 +1,2022 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  WWW サーバ
+ *
+ *    ・送受信タスク同一型
+ *    ・ノンブロッキングコール
+ *    ・省コピー API
+ *    ・IPv4/IPv6
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel/kernel_impl.h"
+#include "target_config.h"
+#include "target_syssvc.h"
+#include "target_stddef.h"
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/wwws.h>
+
+#ifdef USE_WWW_SRV
+
+/*
+ *  送受信 API の選択
+ */
+
+#define EOF		(-1)
+
+typedef struct file {
+	ER		(*func)(ID cepid, T_WWW_RWBUF *srbuf);
+	char		*uri;
+	} T_FILE;
+
+typedef struct status {
+	uint16_t	code;
+	uint8_t		*reason;
+	} T_STATUS;
+
+/*
+ *  関数
+ */
+
+static ER index_html(ID cepid, T_WWW_RWBUF *srbuf);
+
+#if NET_COUNT_ENABLE
+
+static ER stat_html(ID cepid, T_WWW_RWBUF *srbuf);
+
+#endif	/* of #if NET_COUNT_ENABLE */
+
+#ifdef USE_TCP_EXTENTIONS
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+#if NUM_WWW_SRV_TASKS >= 2		/* 2 を超える個数は想定していない。	*/
+
+#define WWW4_SRV_TASK	WWW_SRV_TASK1
+#define WWW6_SRV_TASK	WWW_SRV_TASK2
+
+#else	/* of #if NUM_WWW_SRV_TASKS >= 2 */
+
+#define WWW4_SRV_TASK	WWW_SRV_TASK1
+#define WWW6_SRV_TASK	WWW_SRV_TASK1
+
+#endif	/* of #if NUM_WWW_SRV_TASKS >= 2 */
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+#define WWW4_SRV_TASK	WWW_SRV_TASK1
+#define WWW6_SRV_TASK	WWW_SRV_TASK1
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+
+/*
+ *  全域変数
+ */
+
+/* TCP 送受信ウィンドバッファ */
+
+#ifndef TCP_CFG_SWBUF_CSAVE
+uint8_t www_srv_swbuf[NUM_WWW_SRV_TASKS][WWW_SRV_SWBUF_SIZE];
+#endif
+
+#ifndef TCP_CFG_RWBUF_CSAVE
+uint8_t www_srv_rwbuf[NUM_WWW_SRV_TASKS][WWW_SRV_RWBUF_SIZE];
+#endif
+
+/*
+ *  変数
+ */
+
+SYSTIM	srv_start;
+
+static const T_FILE file[] = {
+	{ index_html,	"/"		},
+	{ index_html,	"/index.html"	},
+
+#if NET_COUNT_ENABLE
+
+	{ stat_html,	"/stat.html"	},
+
+#endif	/* of #if NET_COUNT_ENABLE */
+	};
+
+#define NUM_FILES	(sizeof(file) / sizeof(T_FILE))
+
+static const char *status[] = {
+	"200 OK",
+	"404 Not Found",
+	};
+
+#define NUM_STATUS	(sizeof(status) / sizeof(T_STATUS))
+
+#define ST_OK		0
+#define ST_NOT_FOUND	1
+
+/*
+ *  接続相手の情報構造体
+ */
+
+#ifdef  NUM_WWW4_SRV_TASKS
+#undef  NUM_WWW4_SRV_TASKS
+#endif
+#define NUM_WWW4_SRV_TASKS		1
+
+typedef struct t_www_srv_info {
+	ID	cepid;		/* 通信端点 ID		*/
+	ID	repid;		/* 受付口   ID		*/
+	T_IPEP	dst;		/* 接続相手アドレス情報	*/
+	} T_WWW_SRV_INFO;
+
+#define INDEX_SRV_INFO(id)	((id)-1)
+
+#ifdef USE_TCP_EXTENTIONS
+
+static T_WWW_SRV_INFO www_srv_info[NUM_WWW_SRV_TASKS];
+					/* 2 を超える個数は想定していない。	*/
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+static T_WWW_SRV_INFO www_srv_info[] = {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+	{ WWW4_SRV_CEPID1, WWW4_SRV_REPID },
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	{ WWW_SRV_CEPID1, WWW_SRV_REPID },
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+#if NUM_WWW_SRV_TASKS >= 2		/* 2 を超える個数は想定していない。	*/
+	{ WWW_SRV_CEPID2, WWW_SRV_REPID },
+#endif
+
+	};
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_COPYSAVE_API
+
+/*
+ *  get_char -- 一文字入力する。
+ */
+
+static int_t
+get_char (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	int_t	len, ch;
+	ER	error;
+
+	if (srbuf->unget) {
+		ch = srbuf->unget;
+		srbuf->unget = 0;
+		}
+	else  {
+		if (srbuf->rbuf.index >= srbuf->rbuf.len) {
+			if ((error = tcp_rel_buf(cepid, srbuf->rbuf.len)) != E_OK)
+				syslog(LOG_WARNING, "[WWWn:%02u REL] tcp_rel_buf error: %s",
+				       cepid, itron_strerror(error));
+			srbuf->rbuf.index = 0;
+			if ((len = tcp_rcv_buf(cepid, (void**)&srbuf->rbuf.buf, TMO_FEVR)) <= 0) {
+				if (len < 0)
+					syslog(LOG_WARNING, "[WWWn:%02u RCV] tcp_rcv_buf error: %s",
+					       cepid, itron_strerror(len));
+				srbuf->rbuf.len = 0;
+				return EOF;
+				}
+			else
+				srbuf->rbuf.len = len;
+			}
+		ch = srbuf->rbuf.buf[srbuf->rbuf.index ++];
+		}
+	return ch;
+	}
+
+/*
+ *  flush_sbuf -- 送信バッファをフラッシュする。
+ */
+
+static ER
+flush_sbuf (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	ER_UINT	error;
+
+	error = tcp_snd_buf(cepid, srbuf->sbuf.index);
+	srbuf->sbuf.index = srbuf->sbuf.len = 0;
+
+	return error;
+	}
+
+/*
+ *  put_str -- 文字列を出力する。
+ */
+
+static uint_t
+put_str (ID cepid, T_WWW_RWBUF *srbuf, const char *str)
+{
+	ER		error;
+	ER_UINT		blen;
+	uint16_t	len, off = 0;
+
+	len = strlen(str);
+	while (len > 0) {
+		if (srbuf->sbuf.index >= srbuf->sbuf.len)
+			if ((error = flush_sbuf(cepid, srbuf)) != E_OK) {
+				syslog(LOG_WARNING, "[WWWn:%02u SND] error: %s", cepid, itron_strerror(error));
+			return 0;
+			}
+
+		if (srbuf->sbuf.len == 0) {
+			if ((blen = tcp_get_buf(cepid, (void**)&srbuf->sbuf.buf, TMO_FEVR)) < 0) {
+				syslog(LOG_WARNING, "[WWWn:%02u GET] error: %s", cepid, itron_strerror(srbuf->sbuf.len));
+				return 0;
+				}
+			srbuf->sbuf.len = (uint16_t)blen;
+			}
+
+		if (len > srbuf->sbuf.len - srbuf->sbuf.index)
+			blen = srbuf->sbuf.len - srbuf->sbuf.index;
+		else
+			blen = len;
+		memcpy(&srbuf->sbuf.buf[srbuf->sbuf.index], str + off, blen);
+		srbuf->sbuf.index += (uint16_t)blen;
+		off               += (uint16_t)blen;
+		len               -= (uint16_t)blen;
+		}
+
+	return off;
+	}
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+/*
+ *  get_char -- 一文字入力する。
+ */
+
+static int_t
+get_char (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	int_t	len, ch;
+
+	if (srbuf->unget) {
+		ch = srbuf->unget;
+		srbuf->unget = 0;
+		}
+	else  {
+		if (srbuf->rbuf.index >= srbuf->rbuf.len) {
+			if ((len = tcp_rcv_dat(cepid, srbuf->rbuf.buf, sizeof(srbuf->rbuf.buf), TMO_FEVR)) <= 0) {
+				if (len < 0) {
+					syslog(LOG_WARNING, "[WWWn:%02u RCV] error: %s",
+					       cepid, itron_strerror(len));
+					}
+				return EOF;
+				}
+			else {
+				srbuf->rbuf.len   = len;
+				srbuf->rbuf.index = 0;
+				}
+			}
+		ch = srbuf->rbuf.buf[srbuf->rbuf.index ++];
+		}
+	return ch;
+	}
+
+/*
+ *  flush_sbuf -- 送信バッファをフラッシュする。
+ */
+
+static ER
+flush_sbuf (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	ER_UINT		len = E_OK;
+	uint16_t	off = 0;
+
+	while (off < srbuf->sbuf.index) {
+		if ((len = tcp_snd_dat(cepid, srbuf->sbuf.buf + off, srbuf->sbuf.index - off, TMO_FEVR)) < 0)
+			break;
+		off += len;
+		}
+	srbuf->sbuf.index = 0;
+
+	return len < 0 ? len : E_OK;
+	}
+
+/*
+ *  put_str -- 文字列を出力する。
+ */
+
+static uint16_t
+put_str (ID cepid, T_WWW_RWBUF *srbuf, const char *str)
+{
+	ER		error;
+	uint16_t	blen, len, off = 0;
+
+	len = strlen(str);
+	while (len > 0) {
+		if (srbuf->sbuf.index >= srbuf->sbuf.len)
+			if ((error = flush_sbuf(cepid, srbuf)) != E_OK) {
+				syslog(LOG_WARNING, "[WWWn:%02u SND] error: %s", cepid, itron_strerror(error));
+			return 0;
+			}
+		if (len > srbuf->sbuf.len - srbuf->sbuf.index)
+			blen = srbuf->sbuf.len - srbuf->sbuf.index;
+		else
+			blen = len;
+		memcpy(&srbuf->sbuf.buf[srbuf->sbuf.index], str + off, blen);
+		srbuf->sbuf.index += blen;
+		off               += blen;
+		len               -= blen;
+		}
+
+	return off;
+	}
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+/*
+ *  get_line -- 一行入力する。
+ */
+
+static uint16_t
+get_line (ID cepid, T_WWW_LINE *line, T_WWW_RWBUF *srbuf)
+{
+	int_t		ch = 0;
+	uint16_t	len;
+	char		*p, *t;
+
+	p = line->buf;
+	t = line->buf + WWW_LINE_SIZE;
+	while (p < t && (ch = get_char(cepid, srbuf)) != EOF && ch != '\n' && ch != '\r')
+		*p ++ = ch;
+	*p = '\0';
+	len = p - line->buf;
+	if (p >= t) {
+		while ((ch = get_char(cepid, srbuf)) != EOF && ch != '\n' && ch != '\r')
+			len ++;
+		}
+	if (ch == '\r') {
+		len ++;
+		if ((ch = get_char(cepid, srbuf)) != EOF && ch != '\n')
+			srbuf->unget = ch;
+		}
+	if (ch == '\n')
+		len ++;
+	line->len = len;
+	return p - line->buf;
+	}
+
+#if NET_COUNT_ENABLE
+
+#ifdef _int64_
+#define VAL_TYPE	uint64_t
+#else
+#define VAL_TYPE	uint32_t
+#endif
+
+/*
+ *  convert -- 数値変換
+ */
+
+static int_t
+convert (char *buf, VAL_TYPE val, int_t radix, int_t width, bool_t minus, char padchar)
+{
+	static const char radhex[] = "0123456789abcdef";
+
+	char	digits[23], *start;
+	int_t	ix, pad;
+
+	ix = 0;
+	start = buf;
+	do {
+		digits[ix ++] = radhex[val % radix];
+		val /= radix;
+		} while (val != 0);
+	if (minus)
+		digits[ix ++] = '-';
+	for (pad = ix; pad < width; pad ++)
+		*buf ++ = padchar;
+	while (ix -- > 0)
+		*buf ++ = digits[ix];
+	*buf = '\0';
+	return buf - start;
+	}
+
+#endif	/* of #if NET_COUNT_ENABLE */
+
+/*
+ * split_fields -- フィールドに分割する。
+ */
+
+static void
+split_fields (T_WWW_LINE *line, char *delim)
+{
+	char	*p, quote;
+	int_t	ix = 0;
+
+	line->off[ix ++] = 0;
+	for (p = line->buf; ix < WWW_NUM_FIELDS && *p; p ++) {
+		if (strchr("\"'`", *p) != NULL) {
+			for (quote = *p ++; *p && *p != quote; p ++)
+				;
+			}
+		else if (strchr(delim, *p) != NULL) {
+			*p = '\0';
+			line->off[ix ++] = (uint8_t)(p - line->buf + 1);
+			}
+		}
+	line->num = ix;
+	}
+
+/*
+ *  put_status -- status line を出力する。
+ */
+
+static uint16_t
+put_status (ID cepid, T_WWW_RWBUF *srbuf, int_t index)
+{
+	uint16_t	len = 0;
+
+	len += put_str(cepid, srbuf, "HTTP/1.0 ");
+	len += put_str(cepid, srbuf, status[index]);
+	len += put_str(cepid, srbuf, "\r\n");
+	return len;
+	}
+
+/*
+ *  put_content_length -- Content-length を出力する。
+ */
+
+static uint16_t
+put_content_length (ID cepid, T_WWW_RWBUF *srbuf, int_t content_len)
+{
+	uint16_t	len = 0;
+#if 0
+	char		length[TD_DIGITS + 1];
+
+	convert(length, content_len, 10, 0, false, ' ');
+	len += put_str(cepid, srbuf, "Content-length: ");
+	len += put_str(cepid, srbuf, length);
+	len += put_str(cepid, srbuf, "\r\n");
+#endif	/* of #if 0 */
+	return len;
+	}
+
+/*
+ *  get_method -- GET メソッドの処理
+ */
+
+static ER
+get_method (ID cepid, T_WWW_RWBUF *srbuf, T_WWW_LINE *line)
+{
+	int_t	ix;
+
+	for (ix = NUM_FILES; ix -- > 0; ) {
+		if (!strcmp(file[ix].uri, &line->buf[line->off[1]])) {
+			//syslog(LOG_NOTICE, "[WWWn:%02u PTH] '%s'", cepid, &line->buf[line->off[1]]);
+			return (*file[ix].func)(cepid, srbuf);
+			}
+		}
+	put_status(cepid, srbuf, ST_NOT_FOUND);
+	return E_NOEXS;
+	}
+
+/*
+ *  parse_request -- リクエストを解析する。
+ */
+
+static ER
+parse_request (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	T_WWW_LINE	*method, *line;
+	ER		error = E_OK;
+	int_t		blen = 0;
+
+	if ((error = tget_mpf(MPF_WWW_LINE, (void*)&method, TMO_FEVR)) != E_OK) {
+		syslog(LOG_CRIT, "[WWWn:%02u MPF] get line error: %s.",
+		       cepid, itron_strerror(error));
+		return error;
+		}
+
+	if (get_line(cepid, method, srbuf) == 0) {
+		if ((error = rel_mpf(MPF_WWW_LINE, method)) != E_OK)
+			syslog(LOG_WARNING, "[WWWn:%02u MPF] release line buffer error: %s.",
+			       cepid, itron_strerror(error));
+		return error;
+		}
+
+	if ((error = tget_mpf(MPF_WWW_LINE, (void*)&line, TMO_FEVR)) != E_OK) {
+		syslog(LOG_CRIT, "[WWWn:%02u MPF] get line buffer error: %s.",
+		       cepid, itron_strerror(error));
+		if ((error = rel_mpf(MPF_WWW_LINE, method)) != E_OK)
+			syslog(LOG_WARNING, "[WWWn:%02u MPF] release line buffer error: %s.",
+			       cepid, itron_strerror(error));
+		return error;
+		}
+
+	while (get_line(cepid, line, srbuf) > 0) {	/* ヘッダをスキップする。*/
+		split_fields(line, ": ");
+		if (strcmp("Content-Length", &line->buf[line->off[0]]) == 0)
+			blen = atoi(&line->buf[line->off[1]]);
+		}
+	while (blen > 0 && get_line(cepid, line, srbuf) > 0) {
+		/* エンティティ・ボディをスキップする。*/
+		blen -= line->len;
+		}
+
+	if ((error = rel_mpf(MPF_WWW_LINE, line)) != E_OK)
+		syslog(LOG_WARNING, "[WWWn:%02u MPF] release line buffer error: %s.",
+		       cepid, itron_strerror(error));
+	
+	split_fields(method, ": ");
+	if (!strcmp(&method->buf[method->off[0]], "GET"))
+		error = get_method(cepid, srbuf, method);
+
+	flush_sbuf(cepid, srbuf);
+
+	if ((error = rel_mpf(MPF_WWW_LINE, method)) != E_OK)
+		syslog(LOG_WARNING, "[WWWn:%02u MPF] release line buffer error: %s.",
+		       cepid, itron_strerror(error));
+
+	return error;
+	}
+
+/*
+ *  index_html -- /index.html ファイル
+ */
+
+static ER
+index_html (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	static const char response[] =
+		"\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD html 3.2//EN\">\r\n"
+		"<html><head>\r\n"
+
+#ifdef TOPPERS_S810_CLG3_85
+		"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\">\r\n"
+#else
+		"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=EUC-JP\">\r\n"
+#endif
+
+		"<title>TINET TCP/IP Protocol Stack</title>\r\n"
+		"</head><body bgcolor=\"#ffffbb\">\r\n"
+		"<hr>この WWW サーバは<br>"
+
+#ifdef TARGET_KERNEL_ASP
+		"ASP Kernel for " TARGET_NAME " (" __DATE__ "," __TIME__ ") と<br>\r\n"
+#endif
+
+#ifdef TARGET_KERNEL_JSP
+		"JSP Kernel for " TARGET_NAME " (" __DATE__ "," __TIME__ ") と<br>\r\n"
+#endif
+
+		"TINET TCP/IP プロトコルスタックによりサービスしています。<br><hr>\r\n"
+
+#if NET_COUNT_ENABLE
+
+		"<ul><li type=\"square\"><a href=\"stat.html\">ネットワーク統計情報</a></ul><hr>\r\n"
+
+#else	/* of #if NET_COUNT_ENABLE */
+
+		"<ul><li type=\"square\">ネットワーク統計情報</ul><hr>\r\n"
+
+#endif	/* of #if NET_COUNT_ENABLE */
+
+		"FreeBSD: Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995<br>\r\n"
+		"The Regents of the University of California.  All rights reserved.<br><br>\r\n"
+
+#ifdef SUPPORT_PPP
+
+		"pppd: Copyright (c) 1989 Carnegie Mellon University.<br>\r\n"
+		"All rights reserved.<br><br>\r\n"
+		"ppp: Written by Toshiharu OHNO (tony-o@iij.ad.jp)<br>\r\n"
+		"Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.<br><br>\r\n"
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_ETHER
+
+ 		"if_ed: Copyright (c) 1995, David Greenman<br>\r\n"
+		"All rights reserved.<br><br>\r\n"
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#ifdef TARGET_KERNEL_ASP
+		"TOPPERS/ASP Kernel<br>\r\n"
+		"Toyohashi Open Platform for Embedded Real-Time Systems/<br>\r\n"
+		"Advanced Standard Profile Kernel<br>\r\n"
+		"Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory<br>\r\n"
+		"Toyohashi Univ. of Technology, JAPAN<br>\r\n"
+		"Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory<br>\r\n"
+		"Graduate School of Information Science, Nagoya Univ., JAPAN<br><br>\r\n"
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+		"TOPPERS/JSP Kernel<br>\r\n"
+		"Toyohashi Open Platform for Embedded Real-Time Systems/<br>\r\n"
+		"Just Standard Profile Kernel<br>\r\n"
+		"Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory<br>\r\n"
+		"Toyohashi Univ. of Technology, JAPAN<br>\r\n"
+		"Copyright (C) 2005 by Embedded and Real-Time Systems Laboratory<br>\r\n"
+		"Graduate School of Information Science, Nagoya Univ., JAPAN<br><br>\r\n"
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+		"TINET (TCP/IP Protocol Stack)<br>\r\n"
+		"Copyright (C) 2001-2008 by Dep. of Computer Science and Engineering<br>\r\n"
+		"Tomakomai National College of Technology, JAPAN\r\n"
+		"</body></html>\r\n"
+		;
+
+	SYSTIM		start, finish;
+	uint16_t	len = 0;
+
+	get_tim(&start);
+	len += put_status(cepid, srbuf, ST_OK);
+	len += put_content_length(cepid, srbuf, strlen(response) - 2);	/* 2 は最初の \r\n */
+	len += put_str(cepid, srbuf, response);
+	get_tim(&finish);
+	syslog(LOG_NOTICE, "[WWWn:%02u SND] send: index.html, len: %4u, time: %lu [us]",
+	                   cepid, len, (finish - start) * 1000 / SYSTIM_HZ);
+	return E_OK;
+	}
+
+#if NET_COUNT_ENABLE
+
+#define TD_TEMPLATE1	"<tr><td></td><td align=\"right\"></td>\r\n<td align=\"right\"></td>\r\n<td align=\"right\"></td>\r\n<td align=\"right\"></td>\r\n<td align=\"right\"></td>\r\n<td align=\"right\"></td></tr>\r\n"
+#define TD_TEMPLATE2	"<tr><td></td><td align=\"right\"></td><td align=\"right\"></td></tr>\r\n"
+#define TD_TEMPLATE3	"<tr><td></td><td align=\"right\"></td></tr>\r\n"
+#define TD_TEMPLATE4	"<tr><td></td><td align=\"right\"></td><td align=\"right\"></td><td align=\"right\"></td></tr>\r\n"
+
+#define TD_LEN1(i)	(sizeof(i) +  sizeof(TD_TEMPLATE1) + TD_DIGITS  * 6 - 2)
+#define TD_LEN2(i)	(sizeof(i) +  sizeof(TD_TEMPLATE2) + TD_DIGITS  * 2 - 2)
+#define TD_LEN4(i)	(sizeof(i) +  sizeof(TD_TEMPLATE4) + TD_DIGITS  * 3 - 2)
+#define TD_DIGITS	20
+
+static const char time_prefix[] =
+	"経過時間: "
+	;
+
+static const char time_suffix[] =
+	"<hr>\r\n"
+	;
+
+static const char table_suffix[] = "</table><br><hr>";
+
+#if defined(SUPPORT_INET4)
+
+static const char table_prefix_ip4[] =
+	"<h2>IPv4</h2><table border>\r\n"
+	"<tr><th>項目</th><th>カウント</th></tr>\r\n"
+	;
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+static const char table_prefix_ip6[] =
+	"<h2>IPv6</h2><table border>\r\n"
+	"<tr><th>項目</th><th>カウント</th></tr>\r\n"
+	;
+
+static const char table_prefix_icmp6[] =
+	"<h2>ICMPv6</h2><table border>\r\n"
+	"<tr><th>項目</th><th>カウント</th></tr>\r\n"
+	;
+
+static const char table_prefix_nd6[] =
+	"<h2>近隣探索</h2><table border>\r\n"
+	"<tr><th>項目</th><th>カウント</th></tr>\r\n"
+	;
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+static const char table_prefix_tcp[] =
+	"<h2>TCP</h2><table border>\r\n"
+	"<tr><th>項目</th><th>カウント</th></tr>\r\n"
+	;
+
+static const char table_prefix_net_buf[] =
+	"<h2>ネットワークバッファ</h2><table border>\r\n"
+	"<tr><th>サイズ</th>"
+	"<th>用意数</th>"
+	"<th>割当要求数</th>"
+	"<th>割当数</th>"
+	"<th>割当て<br>エラー数</th></tr>\r\n"
+	;
+
+#ifdef SUPPORT_PPP
+
+static const char table_prefix_ppp[] =
+	"<h2>PPP ネットワークインタフェース</h2><table border>\r\n"
+	"<tr><th>項目</th><th>カウント</th></tr>\r\n"
+	;
+
+static const char *ppp_item[NC_PPP_SIZE] = {
+	"受信オクテット数",
+	"送信オクテット数",
+	"受信フレーム数",
+	"送信フレーム数",
+	"受信エラーフレーム数",
+	"送信エラーフレーム数",
+	"バッファ割り当て失敗数",
+	};
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_ETHER
+
+static const char table_prefix_ether_nic[] =
+	"<h2>イーサネット・ネットワークインタフェース</h2><table border>\r\n"
+	"<tr><th>項目</th><th>カウント</th></tr>\r\n"
+	;
+
+static const char *ether_nic_item[NC_ETHER_NIC_SIZE] = {
+	"リセット数",
+	"送信セマフォ資源返却オーバー数",
+	"送信タイムアウト数",
+	"衝突数",
+	"送信エラーフレーム数",
+	"送信フレーム数",
+	"送信オクテット数",
+	"受信セマフォ資源返却オーバー数",
+	"受信バッファ割り当て失敗数",
+	"受信エラーフレーム数",
+	"受信フレーム数",
+	"受信オクテット数",
+	};
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#if defined(SUPPORT_INET4)
+
+static const char *ip4_item[NC_IP4_SIZE] = {
+	"分割送信、フラグメント数",
+	"分割送信数",
+	"送信エラーデータグラム数",
+	"送信データグラム数",
+	"送信オクテット数",
+	"分割受信タイムアウト数",
+	"分割受信バッファ割り当て失敗数",
+	"分割受信破棄数",
+	"分割受信再構成成功数",
+	"分割受信フラグメント数",
+	"分割受信数",
+	"オプション入力数",
+	"プロトコルエラー数",
+	"アドレスエラー数",
+	"バージョンエラー数",
+	"長さエラー数",
+	"チェックサムエラー数",
+	"受信エラーデータグラム数",
+	"受信データグラム数",
+	"受信オクテット数",
+	};
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+static const char *ip6_item[NC_IP6_SIZE] = {
+	"分割送信、フラグメント数",
+	"分割送信数",
+	"送信エラーデータグラム数",
+	"送信データグラム数",
+	"送信オクテット数	",
+	"分割受信タイムアウト数",
+	"分割受信バッファ割り当て失敗数",
+	"分割受信破棄数",
+	"分割受信再構成成功数",
+	"分割受信フラグメント数",
+	"分割受信数",
+	"プロトコルエラー数	",
+	"アドレスエラー数	",
+	"バージョンエラー数	",
+	"長さエラー数",
+	"受信エラーデータグラム数",
+	"受信データグラム数",
+	"受信オクテット数	",
+	};
+
+static const char *icmp6_item[NC_ICMP6_SIZE] = {
+	"送信エラー ICMP データ数	",
+	"送信 ICMP データ数",
+	"送信 ICMP オクテット数",
+	"長さエラー数",
+	"受信エラー ICMP データ数	",
+	"受信 ICMP データ数",
+	"受信 ICMP オクテット数",
+	};
+
+static const char *nd6_item[NC_ND6_SIZE] = {
+	"重複アドレス検出送信数",
+	"近隣要請送信数",
+	"近隣要請受信数",
+	"近隣通知送信数",
+	"近隣通知受信数",
+	"ルータ要請出力数",
+	"ルータ通知受信数",
+	};
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+static const char *tcp_item[NC_TCP_SIZE] = {
+	"能動オープン数",
+	"受動オープン数",
+	"RTT 更新数",
+	"送信 RST 数",
+	"送信 ACK 数",
+	"送信緊急セグメント数",
+	"送信データセグメント数",
+	"再送セグメント数",
+	"送信セグメント数",
+	"送信制御セグメント数",
+	"送信データオクテット数",
+	"受信キュー解放数",
+	"受信多重数",
+	"受信破棄数",
+	"受信 RST 数",
+	"受信多重 ACK 数",
+	"受信 ACK 数",
+	"受信チェックサム不正数",
+	"受信ヘッダ不正数",
+	"受信緊急セグメント数",
+	"受信データセグメント数",
+	"受信セグメント数",
+	"受信データオクテット数",
+	"受信オクテット数",
+	};
+
+/*
+ *  put_count_item1 -- カウンタの内容を出力する。グループ 1
+ */
+
+static uint16_t
+put_count_item1 (ID cepid, T_WWW_RWBUF *srbuf, const char *item, T_NET_COUNT *counter)
+{
+	char		buf[TD_DIGITS + 1];
+	uint16_t	len = 0;
+
+	len += put_str(cepid, srbuf, "<tr><td>");
+	len += put_str(cepid, srbuf, item);
+	len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+
+	convert(buf, counter->in_octets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td>\r\n<td align=\"right\">");
+
+	convert(buf, counter->out_octets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td>\r\n<td align=\"right\">");
+
+	convert(buf, counter->in_packets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td>\r\n<td align=\"right\">");
+
+	convert(buf, counter->out_packets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td>\r\n<td align=\"right\">");
+
+	convert(buf, counter->in_err_packets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td>\r\n<td align=\"right\">");
+
+	convert(buf, counter->out_err_packets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td></tr>\r\n");
+
+	return len;
+	}
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  put_count_item2 -- カウンタの内容を出力する。グループ 2
+ */
+
+static uint16_t
+put_count_item2 (ID cepid, T_WWW_RWBUF *srbuf, const char *item, uint32_t octets, uint32_t packets)
+{
+	char		buf[TD_DIGITS + 1];
+	uint16_t	len = 0;
+
+	len += put_str(cepid, srbuf, "<tr><td>");
+	len += put_str(cepid, srbuf, item);
+	len += put_str(cepid, srbuf, "</td><td>");
+
+	convert(buf, octets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+
+	convert(buf, packets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td></tr>\r\n");
+
+	return len;
+	}
+
+/*
+ *  td_len_ppp -- put_count_ppp で出力する文字数。
+ */
+
+static uint16_t
+td_len_ppp (void)
+{
+	int_t		ix;
+	uint16_t	len = 0;
+
+	for (ix = NC_PPP_SIZE; ix -- > 0; )
+		len += strlen(ppp_item[ix]);
+	return len + (sizeof(TD_TEMPLATE3) + TD_DIGITS - 1) * NC_PPP_SIZE;
+	}
+
+/*
+ *  put_count_ppp -- カウンタ (PPP) の内容を出力する。
+ */
+
+static uint16_t
+put_count_ppp (ID cepid, T_WWW_RWBUF *srbuf)
+{
+
+	char		buf[TD_DIGITS + 1];
+	uint16_t	len = 0;
+
+	len += put_str(cepid, srbuf, table_prefix_ppp);
+
+	len += put_str(cepid, srbuf, "<tr><td>");
+	len += put_str(cepid, srbuf, ppp_item[0]);
+	len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+	convert(buf, net_count_ppp.in_octets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td></tr>\r\n");
+
+	len += put_str(cepid, srbuf, "<tr><td>");
+	len += put_str(cepid, srbuf, ppp_item[1]);
+	len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+	convert(buf, net_count_ppp.out_octets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td></tr>\r\n");
+
+	len += put_str(cepid, srbuf, "<tr><td>");
+	len += put_str(cepid, srbuf, ppp_item[2]);
+	len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+	convert(buf, net_count_ppp.in_packets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td></tr>\r\n");
+
+	len += put_str(cepid, srbuf, "<tr><td>");
+	len += put_str(cepid, srbuf, ppp_item[3]);
+	len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+	convert(buf, net_count_ppp.out_packets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td></tr>\r\n");
+
+	len += put_str(cepid, srbuf, "<tr><td>");
+	len += put_str(cepid, srbuf, ppp_item[4]);
+	len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+	convert(buf, net_count_ppp.in_err_packets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td></tr>\r\n");
+
+	len += put_str(cepid, srbuf, "<tr><td>");
+	len += put_str(cepid, srbuf, ppp_item[5]);
+	len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+	convert(buf, net_count_ppp.out_err_packets, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td></tr>\r\n");
+
+	len += put_str(cepid, srbuf, "<tr><td>");
+	len += put_str(cepid, srbuf, ppp_item[6]);
+	len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+	convert(buf, net_count_ppp_no_bufs, 10, TD_DIGITS, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, "</td></tr>\r\n");
+
+	len += put_str(cepid, srbuf, table_suffix);
+
+	return len;
+	}
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#if defined(SUPPORT_INET4)
+
+/*
+ *  td_len_ip4 -- put_count_ip4 で出力する文字数。
+ */
+
+static uint16_t
+td_len_ip4 (void)
+{
+	int_t		ix;
+	uint16_t	len = 0;
+
+	for (ix = NC_IP4_SIZE; ix -- > 0; )
+		len += strlen(ip4_item[ix]);
+	return len + (sizeof(TD_TEMPLATE3) + TD_DIGITS - 1) * NC_IP4_SIZE;
+	}
+
+/*
+ *  put_count_ip4 -- カウンタ (IP4) の内容を出力する。
+ */
+
+static uint16_t
+put_count_ip4 (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	char		buf[TD_DIGITS + 1];
+	uint16_t	len = 0;
+	int_t		ix;
+
+	len += put_str(cepid, srbuf, table_prefix_ip4);
+	for (ix = NC_IP4_SIZE; ix -- > 0; ) {
+		len += put_str(cepid, srbuf, "<tr><td>");
+		len += put_str(cepid, srbuf, ip4_item[ix]);
+		len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+		convert(buf, net_count_ip4[ix], 10, TD_DIGITS, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td></tr>\r\n");
+		}
+	len += put_str(cepid, srbuf, table_suffix);
+
+	return len;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+/*
+ *  td_len_nd6 -- put_count_nd6 で出力する文字数。
+ */
+
+static uint16_t
+td_len_nd6 (void)
+{
+	int_t		ix;
+	uint16_t	len = 0;
+
+	for (ix = NC_ND6_SIZE; ix -- > 0; )
+		len += strlen(nd6_item[ix]);
+	return len + (sizeof(TD_TEMPLATE3) + TD_DIGITS - 1) * NC_ND6_SIZE;
+	}
+
+/*
+ *  put_count_nd6 -- カウンタ (ND6) の内容を出力する。
+ */
+
+static uint16_t
+put_count_nd6 (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	char		buf[TD_DIGITS + 1];
+	uint16_t	len = 0;
+	int_t		ix;
+
+	len += put_str(cepid, srbuf, table_prefix_nd6);
+	for (ix = NC_ND6_SIZE; ix -- > 0; ) {
+		len += put_str(cepid, srbuf, "<tr><td>");
+		len += put_str(cepid, srbuf, nd6_item[ix]);
+		len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+		convert(buf, net_count_nd6[ix], 10, TD_DIGITS, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td></tr>\r\n");
+		}
+	len += put_str(cepid, srbuf, table_suffix);
+
+	return len;
+	}
+
+/*
+ *  td_len_icmp6 -- put_count_icmp6 で出力する文字数。
+ */
+
+static uint16_t
+td_len_icmp6 (void)
+{
+	int_t		ix;
+	uint16_t	len = 0;
+
+	for (ix = NC_ICMP6_SIZE; ix -- > 0; )
+		len += strlen(icmp6_item[ix]);
+	return len + (sizeof(TD_TEMPLATE3) + TD_DIGITS - 1) * NC_ICMP6_SIZE;
+	}
+
+/*
+ *  put_count_icmp6 -- カウンタ (ICMP6) の内容を出力する。
+ */
+
+static uint16_t
+put_count_icmp6 (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	char		buf[TD_DIGITS + 1];
+	uint16_t	len = 0;
+	int_t		ix;
+
+	len += put_str(cepid, srbuf, table_prefix_icmp6);
+	for (ix = NC_ICMP6_SIZE; ix -- > 0; ) {
+		len += put_str(cepid, srbuf, "<tr><td>");
+		len += put_str(cepid, srbuf, icmp6_item[ix]);
+		len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+		convert(buf, net_count_icmp6[ix], 10, TD_DIGITS, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td></tr>\r\n");
+		}
+	len += put_str(cepid, srbuf, table_suffix);
+
+	return len;
+	}
+
+/*
+ *  td_len_ip6 -- put_count_ip6 で出力する文字数。
+ */
+
+static uint16_t
+td_len_ip6 (void)
+{
+	int_t		ix;
+	uint16_t	len = 0;
+
+	for (ix = NC_IP6_SIZE; ix -- > 0; )
+		len += strlen(ip6_item[ix]);
+	return len + (sizeof(TD_TEMPLATE3) + TD_DIGITS - 1) * NC_IP6_SIZE;
+	}
+
+/*
+ *  put_count_ip6 -- カウンタ (IP6) の内容を出力する。
+ */
+
+static uint16_t
+put_count_ip6 (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	char		buf[TD_DIGITS + 1];
+	uint16_t	len = 0;
+	int_t		ix;
+
+	len += put_str(cepid, srbuf, table_prefix_ip6);
+	for (ix = NC_IP6_SIZE; ix -- > 0; ) {
+		len += put_str(cepid, srbuf, "<tr><td>");
+		len += put_str(cepid, srbuf, ip6_item[ix]);
+		len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+		convert(buf, net_count_ip6[ix], 10, TD_DIGITS, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td></tr>\r\n");
+		}
+	len += put_str(cepid, srbuf, table_suffix);
+
+	return len;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/*
+ *  td_len_tcp -- put_count_tcp で出力する文字数。
+ */
+
+static uint16_t
+td_len_tcp (void)
+{
+	int_t		ix;
+	uint16_t	len = 0;
+
+	for (ix = NC_TCP_SIZE; ix -- > 0; )
+		len += strlen(tcp_item[ix]);
+	return len + (sizeof(TD_TEMPLATE3) + TD_DIGITS - 1) * NC_TCP_SIZE;
+	}
+
+/*
+ *  put_count_tcp -- カウンタ (TCP) の内容を出力する。
+ */
+
+static uint16_t
+put_count_tcp (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	char		buf[TD_DIGITS + 1];
+	uint16_t	len = 0;
+	int_t		ix;
+
+	len += put_str(cepid, srbuf, table_prefix_tcp);
+	for (ix = NC_TCP_SIZE; ix -- > 0; ) {
+		len += put_str(cepid, srbuf, "<tr><td>");
+		len += put_str(cepid, srbuf, tcp_item[ix]);
+		len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+		convert(buf, net_count_tcp[ix], 10, TD_DIGITS, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td></tr>\r\n");
+		}
+	len += put_str(cepid, srbuf, table_suffix);
+
+	return len;
+	}
+
+/*
+ *  put_elapse_time -- 経過時間を出力する。
+ */
+
+static uint16_t
+put_elapse_time (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	SYSTIM		now, elapse;
+	char		buf[TD_DIGITS + 1];
+	uint16_t	len = 0;
+
+	get_tim(&now);
+	elapse = now - srv_start;
+
+	len += put_str(cepid, srbuf, time_prefix);
+
+	convert(buf, elapse / (60 * 60 * SYSTIM_HZ), 10, 4, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, ":");
+
+	convert(buf, (elapse / (60 * SYSTIM_HZ)) % 60, 10, 2, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+	len += put_str(cepid, srbuf, ":");
+
+	convert(buf, (elapse / SYSTIM_HZ) % 60, 10, 2, false, ' ');
+	len += put_str(cepid, srbuf, buf);
+
+	len += put_str(cepid, srbuf, time_suffix);
+
+	return len;
+	}
+
+/*
+ *  put_count_net_buf -- カウンタ (TCP) の内容を出力する。
+ */
+
+static uint16_t
+put_count_net_buf (ID cepid, T_WWW_RWBUF *srbuf)
+{
+
+	const T_NET_BUF_ENTRY	*tbl;
+	char			buf[TD_DIGITS + 1];
+	uint16_t		len = 0;
+	int_t			ix;
+
+	len += put_str(cepid, srbuf, table_prefix_net_buf);
+	tbl = nbuf_get_tbl();
+	for (ix = nbuf_get_tbl_size(); ix -- > 0; ) {
+		len += put_str(cepid, srbuf, "<tr><td align=\"right\">");
+		convert(buf, tbl[ix].size, 10, 4, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+		convert(buf, tbl[ix].prepares, 10, TD_DIGITS, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+		convert(buf, tbl[ix].requests, 10, TD_DIGITS, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+		convert(buf, tbl[ix].allocs, 10, TD_DIGITS, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+		convert(buf, tbl[ix].errors, 10, TD_DIGITS, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td></tr>\r\n");
+		}
+	len += put_str(cepid, srbuf, table_suffix);
+
+	return len;
+	}
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  td_len_ether_nic -- put_count_ether_nic で出力する文字数。
+ */
+
+static uint16_t
+td_len_ether_nic (void)
+{
+	int_t		ix;
+	uint16_t	len = 0;
+
+	for (ix = NC_ETHER_NIC_SIZE; ix -- > 0; )
+		len += strlen(ether_nic_item[ix]);
+	return len + (sizeof(TD_TEMPLATE3) + TD_DIGITS - 1) * NC_ETHER_NIC_SIZE;
+	}
+
+/*
+ *  put_count_ether_nic -- カウンタ (ETHER_NIC) の内容を出力する。
+ */
+
+static uint16_t
+put_count_ether_nic (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	char		buf[TD_DIGITS + 1];
+	uint16_t	len = 0;
+	int_t		ix;
+
+	len += put_str(cepid, srbuf, table_prefix_ether_nic);
+	for (ix = NC_ETHER_NIC_SIZE; ix -- > 0; ) {
+		len += put_str(cepid, srbuf, "<tr><td>");
+		len += put_str(cepid, srbuf, ether_nic_item[ix]);
+		len += put_str(cepid, srbuf, "</td><td align=\"right\">");
+		convert(buf, net_count_ether_nic[ix], 10, TD_DIGITS, false, ' ');
+		len += put_str(cepid, srbuf, buf);
+		len += put_str(cepid, srbuf, "</td></tr>\r\n");
+		}
+	len += put_str(cepid, srbuf, table_suffix);
+
+	return len;
+	}
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+/*
+ *  stat_html -- /stat.html ファイル
+ */
+
+static ER
+stat_html (ID cepid, T_WWW_RWBUF *srbuf)
+{
+	static const char res_prefix[] =
+		"\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD html 3.2//EN\">\r\n"
+		"<html><head>\r\n"
+
+#ifdef TOPPERS_S810_CLG3_85
+		"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\">\r\n"
+#else
+		"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=EUC-JP\">\r\n"
+#endif
+
+		"<title>ネットワーク統計情報</title>\r\n"
+		"</head><body bgcolor=\"#ffffbb\">\r\n"
+		"<hr><h1 align=\"center\">ネットワーク統計情報</h1><hr>\r\n"
+		;
+
+	static const char res_suffix[] =
+		"</body></html>\r\n"
+		;
+
+	static const char table_prefix1[] =
+		"<h2>グループ 1</h2><table border>\r\n"
+		"<tr><th>項目</th>\r\n"
+		"<th>受信オクテット数</th>"
+		"<th>送信オクテット数</th>\r\n"
+		"<th>受信パケット数</th>"
+		"<th>送信パケット数</th>\r\n"
+		"<th>受信エラー<br>パケット数</th>"
+		"<th>送信エラー<br>パケット数</th></tr>\r\n"
+		;
+
+#ifdef SUPPORT_PPP
+
+	static const char table_prefix2[] =
+		"<h2>グループ 2</h2><table border>\r\n"
+		"<tr><th>項目</th>"
+		"<th>受信オクテット数</th>"
+		"<th>受信フレーム数</th></tr>\r\n"
+		;
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+	uint16_t	content_len, len = 0;
+	SYSTIM		start, finish;
+
+	get_tim(&start);
+	content_len = 0
+
+#ifdef SUPPORT_PPP
+
+	    + TD_LEN1("HDLC")
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_PPP
+
+	    + td_len_ppp()
+	    + TD_LEN2("LCP")
+	    + TD_LEN2("IPCP")
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_ETHER
+
+	    + TD_LEN1("ARP")
+	    + td_len_ether_nic()
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+	    + TD_LEN1("ICMP")
+	    + TD_LEN1("UDP")
+
+#if defined(SUPPORT_INET4)
+
+	    + td_len_ip4()
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+	    + td_len_ip6()
+	    + td_len_nd6()
+	    + td_len_icmp6()
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+	    + td_len_tcp()
+	    + TD_LEN4("0123") * nbuf_get_tbl_size();
+	    ;
+
+	len += put_status(cepid, srbuf, ST_OK);
+	len += put_content_length(cepid, srbuf, strlen(res_prefix) 
+	                        + strlen(res_suffix)
+	                        + strlen(time_prefix)
+	                        + strlen("1234:12:12")
+	                        + strlen(time_suffix)
+	                        + strlen(table_prefix1)
+	                        + strlen(table_prefix_net_buf)
+
+#if defined(SUPPORT_INET4)
+
+	                        + strlen(table_prefix_ip4)
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+	                        + strlen(table_prefix_ip6)
+	                        + strlen(table_prefix_nd6)
+	                        + strlen(table_prefix_icmp6)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+	                        + strlen(table_prefix_tcp)
+	                        + strlen(table_suffix) * 3
+
+#ifdef SUPPORT_PPP
+	                        + strlen(table_prefix2)
+	                        + strlen(table_prefix_ppp)
+	                        + strlen(table_suffix) * 2
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_ETHER
+
+	                        + strlen(table_prefix_ether_nic)
+	                        + strlen(table_suffix) * 1
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+	                        + content_len
+	                        - 2);	/* 2 は最初の \r\n */
+
+	len += put_str(cepid, srbuf, res_prefix);
+	len += put_elapse_time(cepid, srbuf);
+	len += put_str(cepid, srbuf, table_prefix1);
+
+#ifdef SUPPORT_PPP
+
+	len += put_count_item1(cepid, srbuf, "HDLC", &net_count_hdlc);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_ETHER
+
+	len += put_count_item1(cepid, srbuf, "Ethernet", &net_count_ether);
+
+#if defined(SUPPORT_INET4)
+
+	len += put_count_item1(cepid, srbuf, "ARP", &net_count_arp);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#if defined(SUPPORT_INET4)
+
+	len += put_count_item1(cepid, srbuf, "ICMP", &net_count_icmp4);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#ifdef SUPPORT_UDP
+
+	len += put_count_item1(cepid, srbuf, "UDP", &net_count_udp);
+
+#endif	/* of #ifdef SUPPORT_UDP */
+
+	len += put_str(cepid, srbuf, table_suffix);
+
+#ifdef SUPPORT_PPP
+
+	len += put_str(cepid, srbuf, table_prefix2);
+	len += put_count_item2(cepid, srbuf, "LCP", 
+	                       net_count_ppp_lcp_in_octets,
+	                       net_count_ppp_lcp_in_packets);
+	len += put_count_item2(cepid, srbuf, "IPCP", 
+	                       net_count_ppp_ipcp_in_octets,
+	                       net_count_ppp_ipcp_in_packets);
+	len += put_str(cepid, srbuf, table_suffix);
+
+	len += put_count_ppp(cepid, srbuf);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_ETHER
+
+	len += put_count_ether_nic(cepid, srbuf);
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#if defined(SUPPORT_INET4)
+
+	len += put_count_ip4(cepid, srbuf);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+	len += put_count_ip6(cepid, srbuf);
+	len += put_count_nd6(cepid, srbuf);
+	len += put_count_icmp6(cepid, srbuf);
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+	len += put_count_tcp(cepid, srbuf);
+
+	len += put_count_net_buf(cepid, srbuf);
+
+	len += put_str(cepid, srbuf, res_suffix);
+
+	get_tim(&finish);
+	syslog(LOG_NOTICE, "[WWWn:%02u SND]send: stat.html,  len: %4u, time: %lu [us]",
+	                   cepid, len, (finish - start) * 1000 / SYSTIM_HZ);
+	return E_OK;
+	}
+
+#endif	/* of #if NET_COUNT_ENABLE */
+
+#ifdef USE_TCP_EXTENTIONS
+
+/*
+ *  get_tcp_rep -- TCP 受付口を獲得する。
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+static ER
+get_tcp_rep (ID *repid)
+{
+	ID		tskid;
+	T_TCP6_CREP	crep6;
+	T_TCP_CREP	crep4;
+
+	get_tid(&tskid);
+	if (tskid == WWW4_SRV_TASK) {
+		crep4.repatr = UINT_C(0);
+		crep4.myaddr.portno = UINT_C(80);
+		crep4.myaddr.ipaddr = IPV4_ADDRANY;
+		return alloc_tcp4_rep(repid, tskid, &crep4);
+		}
+	else {
+		crep6.repatr = UINT_C(0);
+		crep6.myaddr.portno = UINT_C(80);
+		memcpy(&crep6.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+		return alloc_tcp6_rep(repid, tskid, &crep6);
+		}
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+static ER
+get_tcp_rep (ID *repid)
+{
+	ID		tskid;
+	T_TCPN_CREP	crep;
+
+	get_tid(&tskid);
+
+	crep.repatr = UINT_C(0);
+	crep.myaddr.portno = UINT_C(80);
+
+#if defined(SUPPORT_INET6)
+
+	memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#else	/* #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+	crep.myaddr.ipaddr = IPV4_ADDRANY;
+#endif
+
+#endif	/* #if defined(SUPPORT_INET6) */
+
+	return ALLOC_TCP_REP(repid, tskid, &crep);
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  get_tcp_cep -- TCP 通信端点を獲得する。
+ */
+
+static ER
+get_tcp_cep (ID *cepid)
+{
+	ID		tskid;
+	T_TCP_CCEP	ccep;
+
+	get_tid(&tskid);
+
+	ccep.cepatr = UINT_C(0);
+	ccep.sbufsz = WWW_SRV_SWBUF_SIZE;
+	ccep.rbufsz = WWW_SRV_RWBUF_SIZE;
+	ccep.callback = NULL;
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+	ccep.sbuf = NADR;
+#else
+	ccep.sbuf = www_srv_swbuf[0];
+#endif
+#ifdef TCP_CFG_RWBUF_CSAVE
+	ccep.rbuf = NADR;
+#else
+	ccep.rbuf = www_srv_rwbuf[0];
+#endif
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if (tskid == WWW4_SRV_TASK)
+		return alloc_tcp4_cep(cepid, tskid, &ccep);
+	else
+		return alloc_tcp6_cep(cepid, tskid, &ccep);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	return ALLOC_TCP_CEP(cepid, tskid, &ccep);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	}
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/*
+ *  tcp_passive_open -- 受動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+static ER
+tcp_passive_open (T_WWW_SRV_INFO *info, char apip)
+{
+	ER		error = E_OK;
+	T_IPV4EP	dst4;
+
+	if (apip == API_PROTO_IPV6) {
+		/* 受付口は IPv6 */
+		if ((error = tcp6_acp_cep(info->cepid, info->repid, &info->dst, TMO_FEVR)) != E_OK)
+			return error;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp6_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		}
+	else {
+		/* 受付口は IPv4 */
+		if ((error = tcp_acp_cep(info->cepid, info->repid, &dst4, TMO_FEVR)) != E_OK)
+			return error;
+		in6_make_ipv4mapped (&info->dst.ipaddr, dst4.ipaddr);
+		info->dst.portno = dst4.portno;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp4_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+		}
+
+	return error;
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+static ER
+tcp_passive_open (T_WWW_SRV_INFO *info, char apip)
+{
+	ER		error = E_OK;
+
+	if ((error = TCP_ACP_CEP(info->cepid, info->repid, &info->dst, TMO_FEVR)) != E_OK)
+		return error;
+
+#ifdef USE_TCP_EXTENTIONS
+	if ((error = FREE_TCP_REP(info->repid, true)) != E_OK)
+		return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	return error;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  WWW サーバ
+ */
+
+static ER
+www_srv (uint_t six, char apip)
+{
+	T_WWW_RWBUF	*srbuf;
+	ER		error;
+	SYSTIM		now;
+
+	if ((error = tcp_passive_open(&www_srv_info[six], apip)) != E_OK)
+		return error;
+
+	syscall(get_tim(&now));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+	if (apip == API_PROTO_IPV6)
+		syslog(LOG_NOTICE, "[WWW6:%02u ACP] conct:  %6lu,from: %s.%u",
+		                   www_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ipv62str(NULL, &www_srv_info[six].dst.ipaddr),
+		                   www_srv_info[six].dst.portno);
+	else
+		syslog(LOG_NOTICE, "[WWW4:%02u ACP] conct:  %6lu,from: %s.%u",
+		                   www_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ip2str(NULL, &www_srv_info[six].dst.ipaddr.s6_addr32[3]),
+		                   www_srv_info[six].dst.portno);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	syslog(LOG_NOTICE, "[WWWn:%02u ACP] conct:  %6lu,from: %s.%u",
+	                   www_srv_info[six].cepid, now / SYSTIM_HZ,
+	                   IP2STR(NULL, &www_srv_info[six].dst.ipaddr),
+	                   www_srv_info[six].dst.portno);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	if ((error = tget_mpf(MPF_WWW_RWBUF, (void*)&srbuf, TMO_FEVR)) != E_OK) {
+		syslog(LOG_CRIT, "[WWWn:%02u MPF] get buffer error: %s.",
+		                 www_srv_info[six].cepid, itron_strerror(error));
+		srbuf = NULL;
+		}
+	else {
+		srbuf->rbuf.len = srbuf->rbuf.index = srbuf->sbuf.index = srbuf->unget = 0;
+
+#ifdef USE_COPYSAVE_API
+
+		srbuf->sbuf.len = 0;
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+		srbuf->sbuf.len = sizeof(srbuf->sbuf.buf);
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+		if ((error = parse_request(www_srv_info[six].cepid, srbuf)) != E_OK)
+			syslog(LOG_WARNING, "[WWWn:%02u RCV] parse request error: %s",
+			                    www_srv_info[six].cepid, itron_strerror(error));
+		}
+
+	if ((error = tcp_sht_cep(www_srv_info[six].cepid)) != E_OK)
+		syslog(LOG_WARNING, "[WWWn:%02u SHD] shutdown error: %s", 
+		                    www_srv_info[six].cepid, itron_strerror(error));
+
+	if (srbuf != NULL) {
+		while (get_char(www_srv_info[six].cepid, srbuf) != EOF)
+			;
+		if (srbuf != NULL && (error = rel_mpf(MPF_WWW_RWBUF, srbuf)) != E_OK)
+			syslog(LOG_WARNING, "[WWWn:%02u REL] release buffer error: %s.",
+			                    www_srv_info[six].cepid, itron_strerror(error));
+		}
+
+	if ((error = tcp_cls_cep(www_srv_info[six].cepid, TMO_FEVR)) != E_OK)
+		syslog(LOG_WARNING, "[WWWn:%02u CLS] close error: %s",
+ 		                    www_srv_info[six].cepid, itron_strerror(error));
+
+	get_tim(&now);
+	syslog(LOG_NOTICE, "[WWWn:%02u FIN] finsh:  %6lu",
+	                   www_srv_info[six].cepid, now / SYSTIM_HZ);
+
+	return error;
+	}
+
+#ifdef USE_TCP_EXTENTIONS
+
+/*
+ *  WWW サーバタスク
+ */
+
+void
+www_srv_task(intptr_t exinf)
+{
+	ID	tskid;
+	ER	error = E_OK;
+	uint_t	six;
+	char	apip;
+
+	syscall(get_tid(&tskid));
+	six = INDEX_SRV_INFO((ID)exinf);
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+	if (six >= NUM_WWW4_SRV_TASKS)
+		apip = API_PROTO_IPV6;
+	else
+		apip = API_PROTO_IPV4;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	apip = API_PROTO_IPVn;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	syslog(LOG_NOTICE, "[WWW%c:%d] started.", apip, tskid);
+	while (true) {
+
+		syscall(slp_tsk());
+		if ((error = get_tcp_cep(&www_srv_info[six].cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[WWW%c:%02u EXT] create CEP error: %s",
+				           apip, www_srv_info[six].cepid, itron_strerror(error));
+			continue;
+			}
+
+		while (true) {
+
+			if ((error = get_tcp_rep(&www_srv_info[six].repid)) != E_OK) {
+				syslog(LOG_NOTICE, "[WWW%c:%02u EXT] create REP error: %02u, %s",
+				                   apip, www_srv_info[six].cepid, www_srv_info[six].repid, itron_strerror(error));
+				break;
+				}
+			else if ((error = www_srv(six, apip)) != E_OK) {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+				if (tskid == WWW4_SRV_TASK)
+					error = free_tcp4_rep(www_srv_info[six].repid, error != E_DLT);
+				else
+					error = free_tcp6_rep(www_srv_info[six].repid, error != E_DLT);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+				error = FREE_TCP_REP(www_srv_info[six].repid, error != E_DLT);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+				if (error != E_OK) {
+					syslog(LOG_NOTICE, "[WWW%c:%02u EXT] delete REP error: %02u, %s",
+				                           apip, www_srv_info[six].cepid,
+				                                              www_srv_info[six].repid, itron_strerror(error));
+
+					}
+				break;
+				}
+			}
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+		if (tskid == WWW4_SRV_TASK) {
+			if ((error = free_tcp4_cep(www_srv_info[six].cepid)) != E_OK)
+				syslog(LOG_NOTICE, "[WWW%c:%02u EXT] delete CEP error: %s",
+					           apip, www_srv_info[six].cepid, itron_strerror(error));
+			}
+		else {
+			if ((error = free_tcp6_cep(www_srv_info[six].cepid)) != E_OK)
+				syslog(LOG_NOTICE, "[WWW%c:%02u EXT] delete CEP error: %s",
+					           apip, www_srv_info[six].cepid, itron_strerror(error));
+			}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		if ((error = FREE_TCP_CEP(www_srv_info[six].cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[WWW%c:%02u EXT] delete CEP error: %s",
+				           apip, www_srv_info[six].cepid, itron_strerror(error));
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		}
+	}
+
+/*
+ *  wakeup_www_srv -- WWW サーバタスクの休止解除
+ */
+
+ER
+wakeup_www_srv (char apip)
+{
+	ID	taskid;
+
+	if (apip == API_PROTO_IPV6)
+		taskid = WWW6_SRV_TASK;
+	else
+		taskid = WWW4_SRV_TASK;
+	syslog(LOG_NOTICE, "[WWW%c(EXT):%d] wake up.", apip, taskid);
+	return wup_tsk(taskid);
+	}
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/*
+ *  WWW サーバタスク
+ */
+
+void
+www_srv_task(intptr_t exinf)
+{
+	ID	tskid, cepid;
+	uint_t	six;
+	char	apip;
+
+	get_tim(&srv_start);
+	get_tid(&tskid);
+	six = INDEX_SRV_INFO((ID)exinf);
+	cepid = www_srv_info[INDEX_SRV_INFO((ID)exinf)].cepid;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+	if (six >= NUM_WWW4_SRV_TASKS)
+		apip = API_PROTO_IPV6;
+	else
+		apip = API_PROTO_IPV4;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	apip = API_PROTO_IPVn;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	syslog(LOG_NOTICE, "[WWW%c SRV:%d,%d] started.", apip, tskid, cepid);
+
+	while (true) {
+		while (www_srv(six, apip) == E_OK)
+			;
+		}
+	}
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_WWW_SRV */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws.cfg	(revision 398)
@@ -0,0 +1,64 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  WWW サーバのシステムコンフィギュレーションファイル
+ */
+
+#ifdef USE_WWW_SRV
+
+/* タスク */
+
+CRE_TSK(WWW_SRV_TASK1,  {
+	TA_HLNG | TA_ACT,
+	1,
+	www_srv_task,
+	WWW_SRV_MAIN_PRIORITY,
+	WWW_SRV_STACK_SIZE,
+	NULL
+	});
+
+#if NUM_WWW_SRV_TASKS >= 2
+
+CRE_TSK(WWW_SRV_TASK2,  {
+	TA_HLNG | TA_ACT,
+	2,
+	www_srv_task,
+	WWW_SRV_MAIN_PRIORITY,
+	WWW_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #if NUM_WWW_SRV_TASKS >= 2 */
+
+#endif	/* of #ifdef USE_WWW_SRV */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws.h	(revision 398)
@@ -0,0 +1,138 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _WWWS_H_
+#define _WWWS_H_
+
+/* 
+ *  WWW サーバ
+ */
+
+#ifdef TOPPERS_S810_CLG3_85
+#define	WWW_SRV_STACK_SIZE		768		/* タスクのスタックサイズ	*/
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+#define	WWW_SRV_STACK_SIZE		1024		/* タスクのスタックサイズ	*/
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+#define WWW_SRV_MAIN_PRIORITY		5		/* タスクの優先度		*/
+
+/*
+ *  TCP 送受信ウインドバッファサイズ
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+#define WWW_SRV_SWBUF_SIZE	(1024)
+#elif defined(SUPPORT_INET4)
+#define WWW_SRV_SWBUF_SIZE	(512)
+#endif
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define WWW_SRV_SWBUF_SIZE	(2048)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#if defined(SUPPORT_INET6)
+#define WWW_SRV_RWBUF_SIZE	(1024)
+#elif defined(SUPPORT_INET4)
+#define WWW_SRV_RWBUF_SIZE	(512)
+#endif
+
+#define WWW_RBUFF_SIZE		(WWW_SRV_RWBUF_SIZE)
+#define WWW_LINE_SIZE		80
+#define WWW_NUM_FIELDS		4
+
+/*
+ *  タスク数
+ */
+
+#ifndef _MACRO_ONLY
+
+typedef struct line {
+	uint8_t		len;
+	uint8_t		num;
+	uint8_t		off[WWW_NUM_FIELDS];
+	char		buf[WWW_LINE_SIZE + 1];
+	} T_WWW_LINE;
+
+#ifdef USE_COPYSAVE_API
+
+typedef struct www_buffer {
+	char		*buf;
+	uint16_t	len;
+	uint16_t	index;
+	} T_WWW_BUFFER;
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+typedef struct www_buffer {
+	uint16_t	len;
+	uint16_t	index;
+	char		buf[WWW_RBUFF_SIZE];
+	} T_WWW_BUFFER;
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+typedef struct www_rwbuf {
+	T_WWW_BUFFER	sbuf;
+	T_WWW_BUFFER	rbuf;
+	char		unget;
+	} T_WWW_RWBUF;
+
+/* タスク */
+
+extern void	www_srv_task (intptr_t exinf);
+
+/*
+ *  変数
+ */
+
+/* TCP 送受信ウィンドバッファ */
+
+#ifdef NUM_WWW_SRV_TASKS
+
+extern uint8_t www_srv_swbuf[NUM_WWW_SRV_TASKS][WWW_SRV_SWBUF_SIZE];
+extern uint8_t www_srv_rwbuf[NUM_WWW_SRV_TASKS][WWW_SRV_RWBUF_SIZE];
+
+#endif	/* of #ifdef NUM_WWW_SRV_TASKS */
+
+/*
+ *  関数
+ */
+
+extern ER	wakeup_www_srv (char apip);
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#endif	/* of #ifndef _WWWS_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws_asp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws_asp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws_asp.cfg	(revision 398)
@@ -0,0 +1,70 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ASP 用 WWW サーバのシステムコンフィギュレーションファイル
+ */
+
+/*
+ *  共通 WWW サーバのシステムコンフィギュレーションファイルのインクルード
+ */
+
+INCLUDE("netapp/wwws.cfg");
+
+#ifdef USE_WWW_SRV
+
+/*
+ * 固定メモリプール
+ */
+
+/* 受信バッファ */
+
+CRE_MPF(MPF_WWW_RWBUF, {
+	TA_TFIFO,
+	1,
+	sizeof(T_WWW_RWBUF),
+	NULL,
+	NULL
+	});
+
+/* 行バッファ */
+
+CRE_MPF(MPF_WWW_LINE, {
+	TA_TFIFO,
+	2,
+	sizeof(T_WWW_LINE),
+	NULL,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_WWW_SRV */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws_jsp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws_jsp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netapp/wwws_jsp.cfg	(revision 398)
@@ -0,0 +1,68 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  JSP 用 WWW サーバのシステムコンフィギュレーションファイル
+ */
+
+/*
+ *  共通 WWW サーバのシステムコンフィギュレーションファイルのインクルード
+ */
+
+#include "netapp/wwws.cfg"
+
+#ifdef USE_WWW_SRV
+
+/*
+ * 固定メモリプール
+ */
+
+/* 受信バッファ */
+
+CRE_MPF(MPF_WWW_RWBUF, {
+	TA_TFIFO,
+	1,
+	sizeof(T_WWW_RWBUF),
+	NULL
+	});
+
+/* 行バッファ */
+
+CRE_MPF(MPF_WWW_LINE, {
+	TA_TFIFO,
+	2,
+	sizeof(T_WWW_LINE),
+	NULL
+	});
+
+#endif	/* of #ifdef USE_WWW_SRV */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/Makefile.tinet
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/Makefile.tinet	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/Makefile.tinet	(revision 398)
@@ -0,0 +1,45 @@
+#
+#   TINET (TCP/IP Protocol Stack)
+#  
+#   Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+#                    Tomakomai National College of Technology, JAPAN
+#  
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#     (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+#         報告すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+#  
+#   @(#) $Id$
+#
+
+#
+#  コンパイルオプション
+#
+INCLUDES	:= $(INCLUDES) -I$(TINET_ROOT)/netdev/$(NET_DEV)
+TINET_DIRS	:= $(TINET_DIRS):$(TINET_ROOT)/netdev/$(NET_DEV)
+TINET_COBJS	:= $(TINET_COBJS) ether_phy.o if_rx62n.o
+TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netdev/$(NET_DEV)/if_rx62n.cfg
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/ether_phy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/ether_phy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/ether_phy.c	(revision 398)
@@ -0,0 +1,368 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014-2017 by Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include "ether_phy.h"
+#include <kernel.h>
+#include <sil.h>
+
+#define PHY_CONTROL_REGISTER	0x00
+
+#define PHY_CONTROL_RESET			0x8000
+#define PHY_CONTROL_LOOPBACK		0x4000
+#define PHY_CONTROL_SPEED_SELECT	0x2000
+#define PHY_CONTROL_A_N_ENABLE		0x1000
+#define PHY_CONTROL_POWER_DOWN		0x0800
+#define PHY_CONTROL_ISOLATE			0x0400
+#define PHY_CONTROL_RESTART_A_N		0x0200
+#define PHY_CONTROL_DUPLEX_MODE		0x0100
+#define PHY_CONTROL_COLLISION_TEST	0x0080
+
+#define PHY_STATUS_REGISTER		0x01
+
+#define PHY_STATUS_100BASE_T4				0x8000
+#define PHY_STATUS_100BASE_TX_FULL_DUPLEX	0x4000
+#define PHY_STATUS_100BASE_TX_HALF_DUPLEX	0x2000
+#define PHY_STATUS_10BASE_T_FULL_DUPLEX		0x1000
+#define PHY_STATUS_10BASE_T_HALF_DUPLEX		0x0800
+#define PHY_STATUS_A_N_COMPLETE				0x0020
+#define PHY_STATUS_REMOTE_FAULT				0x0010
+#define PHY_STATUS_A_N_ABILITY				0x0008
+#define PHY_STATUS_LINK_STATUS				0x0004
+#define PHY_STATUS_JABBER_DETECT			0x0002
+#define PHY_STATUS_EXTENDED_CAPABILITY		0x0001
+
+#define PHY_AN_ADVERTISEMENT_REGISTER	0x04
+
+#define PHY_AN_AD_100BASE_T4				0x0200
+#define PHY_AN_AD_100BASE_TX_FULL_DUPLEX	0x0100
+#define PHY_AN_AD_100BASE_TX_HALF_DUPLEX	0x0080
+#define PHY_AN_AD_10BASE_T_FULL_DUPLEX		0x0040
+#define PHY_AN_AD_10BASE_T_HALF_DUPLEX		0x0020
+#define PHY_AN_AD_SELECTOR_FIELD			0x0001
+
+#define PHY_AN_STATUS_REGISTER	0x05
+
+#define PHY_AN_STATUS_100BASE_T4				0x0200
+#define PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX	0x0100
+#define PHY_AN_STATUS_100BASE_TX_HALF_DUPLEX	0x0080
+#define PHY_AN_STATUS_10BASE_T_FULL_DUPLEX		0x0040
+#define PHY_AN_STATUS_10BASE_T_HALF_DUPLEX		0x0020
+
+static void phy_write_bit(bool_t bit);
+static void phy_release_bus();
+static bool_t phy_read_bit();
+static void phy_single_rel_bus();
+
+PHY_STATE_T phy_reset(PHY_STATE_T state, uint8_t phy_addr)
+{
+	switch(state){
+	case PHY_STATE_UNINIT:
+		/* PHYのリセット */
+		phy_write_reg(phy_addr, PHY_CONTROL_REGISTER, PHY_CONTROL_RESET);
+
+		/* 500ms待つ */
+		dly_tsk(500 * 1000);
+		/* continue; */
+	case PHY_STATE_RESETING:
+		/* リセット完了の確認 */
+		if((phy_read_reg(phy_addr, PHY_CONTROL_REGISTER) & PHY_CONTROL_RESET) != 0)
+			return PHY_STATE_RESETING;
+
+		return PHY_STATE_RESET;
+	default:
+		return state;
+	}
+}
+
+PHY_STATE_T phy_initialize(PHY_STATE_T state, uint8_t phy_addr, PHY_MODE_T *mode)
+{
+#if defined(_MSC_VER) || defined(__c2__)
+	static int reset = 0;
+#endif
+	uint16_t status;
+	*mode = (PHY_MODE_T)0;
+
+	switch(state){
+	case PHY_STATE_RESET:
+		/* オートネゴシエーションのお知らせを有効に設定 */
+		phy_write_reg(phy_addr, PHY_AN_ADVERTISEMENT_REGISTER, 
+			PHY_AN_AD_100BASE_T4 | PHY_AN_AD_100BASE_TX_FULL_DUPLEX | PHY_AN_AD_100BASE_TX_HALF_DUPLEX
+			| PHY_AN_AD_10BASE_T_FULL_DUPLEX | PHY_AN_AD_10BASE_T_HALF_DUPLEX | PHY_AN_AD_SELECTOR_FIELD);
+
+		/* オートネゴシエーションを有効に設定 */
+		phy_write_reg(phy_addr, PHY_CONTROL_REGISTER, PHY_CONTROL_SPEED_SELECT | PHY_CONTROL_A_N_ENABLE);
+		/* continue; */
+	case PHY_STATE_LINKE_WAIT:
+#if defined(_MSC_VER) || defined(__c2__)
+		reset++;
+		if(reset < 2){
+#endif
+		/* リンク完了の確認 */
+		if(!phy_is_link(phy_addr))
+			return PHY_STATE_LINKE_WAIT;
+#if defined(_MSC_VER) || defined(__c2__)
+		}
+		reset = 0;
+#endif
+		/* continue; */
+	case PHY_STATE_LINKED:
+#if defined(_MSC_VER) || defined(__c2__)
+		reset++;
+		if(reset < 2){
+#endif
+		/* オートネゴシエーション完了の確認 */
+		if((phy_read_reg(phy_addr, PHY_STATUS_REGISTER) & PHY_STATUS_A_N_COMPLETE) == 0)
+			return PHY_STATE_LINKED;
+#if defined(_MSC_VER) || defined(__c2__)
+		}
+#endif
+		status = phy_read_reg(phy_addr, PHY_AN_STATUS_REGISTER);
+
+		if ((status & (PHY_AN_STATUS_100BASE_T4 | PHY_AN_STATUS_10BASE_T_FULL_DUPLEX | PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX)) != 0)
+			*mode = (PHY_MODE_T)(((int)*mode) | 0x01);
+
+		if ((status & (PHY_AN_STATUS_100BASE_T4 | PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX | PHY_AN_STATUS_100BASE_TX_HALF_DUPLEX)) != 0)
+			*mode = (PHY_MODE_T)(((int)*mode) | 0x02);
+
+		return PHY_STATE_NEGOTIATED;
+	}
+
+	return state;
+}
+
+bool_t phy_is_link(uint8_t phy_addr)
+{
+#if !defined(_MSC_VER) && !defined(__c2__)
+	/* リンクの確認 */
+	return (phy_read_reg(phy_addr, PHY_STATUS_REGISTER) & PHY_STATUS_LINK_STATUS) != 0;
+#else
+	return true;
+#endif
+}
+
+uint16_t phy_read_reg(uint8_t phy_addr, uint8_t reg_addr)
+{
+	uint16_t result = 0, bit;
+	int i;
+
+	/* PRE ：32個の連続した1b */
+	for (i = 0; i < 32; i++)
+		phy_write_bit(true);
+
+	/* ST ：フレームの先頭を示す01bのライト */
+	phy_write_bit(false);
+	phy_write_bit(true);
+
+	/* OP ：アクセス種別を示すコードのライト */
+	phy_write_bit(true);
+	phy_write_bit(false);
+
+	/* PHYAD ：PHY-LSIのアドレスが1番の場合、00001bをライト（MSB から順次ライト）。 */
+	phy_write_bit((phy_addr & 0x10) != 0);
+	phy_write_bit((phy_addr & 0x08) != 0);
+	phy_write_bit((phy_addr & 0x04) != 0);
+	phy_write_bit((phy_addr & 0x02) != 0);
+	phy_write_bit((phy_addr & 0x01) != 0);
+
+	/* REGAD ：レジスタアドレスが1番の場合、00001bをライト（MSBから順次ライト）。 */
+	phy_write_bit((reg_addr & 0x10) != 0);
+	phy_write_bit((reg_addr & 0x08) != 0);
+	phy_write_bit((reg_addr & 0x04) != 0);
+	phy_write_bit((reg_addr & 0x02) != 0);
+	phy_write_bit((reg_addr & 0x01) != 0);
+
+	/* TA ：MII/RMIIインタフェース上でデータの送信元を切り替える時間 */
+	/* 「バス解放」（Z0と表記）を行う */
+	phy_release_bus();
+
+	/* DATA ：16ビットのデータ。MSBから順次リード */
+	for (bit = 0x8000; bit != 0; bit >>= 1) {
+		if(phy_read_bit())
+			result |= bit;
+	}
+
+	/* IDLE ：次のMII管理フォーマット入力までの待機時間 */
+	/* すでにTA時にバス解放済みであり制御不要 */
+	phy_release_bus();
+
+	return result;
+}
+
+void phy_write_reg(uint8_t phy_addr, uint8_t reg_addr, uint16_t reg_data)
+{
+	int i;
+	uint16_t bit;
+
+	/* PRE ：32個の連続した1b */
+	for (i = 0; i < 32; i++)
+		phy_write_bit(true);
+
+	/* ST ：フレームの先頭を示す01bのライト */
+	phy_write_bit(false);
+	phy_write_bit(true);
+
+	/* OP ：アクセス種別を示すコードのライト */
+	phy_write_bit(false);
+	phy_write_bit(true);
+
+	/* PHYAD ：PHY-LSIのアドレスが1番の場合、00001bをライト（MSB から順次ライト）。 */
+	phy_write_bit((phy_addr & 0x10) != 0);
+	phy_write_bit((phy_addr & 0x08) != 0);
+	phy_write_bit((phy_addr & 0x04) != 0);
+	phy_write_bit((phy_addr & 0x02) != 0);
+	phy_write_bit((phy_addr & 0x01) != 0);
+
+	/* REGAD ：レジスタアドレスが1番の場合、00001bをライト（MSBから順次ライト）。 */
+	phy_write_bit((reg_addr & 0x10) != 0);
+	phy_write_bit((reg_addr & 0x08) != 0);
+	phy_write_bit((reg_addr & 0x04) != 0);
+	phy_write_bit((reg_addr & 0x02) != 0);
+	phy_write_bit((reg_addr & 0x01) != 0);
+
+	/* TA ：MII/RMIIインタフェース上でデータの送信元を切り替える時間 */
+	/* 10bをライト */
+	phy_write_bit(true);
+	phy_write_bit(false);
+
+	/* DATA ：16ビットのデータ。MSBから順次ライト */
+	for (bit = 0x8000; bit != 0; bit >>= 1) {
+		phy_write_bit((reg_data & bit) != 0);
+	}
+
+	/* IDLE ：次のMII管理フォーマット入力までの待機時間 */
+	/* 「単独バス解放」（Xと表記）を行う */
+	phy_single_rel_bus();
+}
+
+#define ETHERC_PIR_WAIT 4
+
+/*
+ * 1 ビットデータのライト
+ */
+static void phy_write_bit(bool_t bit)
+{
+	int i;
+	uint32_t data = bit ? ETHERC_PIR_MDO : 0;
+
+	/* PHY部インタフェースレジスタへのライト */
+	sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHY部インタフェースレジスタへのライト */
+	sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | ETHERC_PIR_MDC);
+
+	for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHY部インタフェースレジスタへのライト */
+	sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+}
+
+/*
+ * バス解放
+ */
+static void phy_release_bus()
+{
+	int i;
+
+	/* PHY部インタフェースレジスタへのライト */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHY部インタフェースレジスタへのライト */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | ETHERC_PIR_MDC);
+
+	for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHY部インタフェースレジスタへのライト */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+}
+
+/*
+ * 1 ビットデータのリード
+ */
+static bool_t phy_read_bit()
+{
+	bool_t bit;
+	int i;
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHY部インタフェースレジスタへのライト */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | ETHERC_PIR_MDC);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHY部インタフェースレジスタへのライト */
+	bit = (sil_rew_mem(ETHERC_PIR) & ETHERC_PIR_MDI) != 0;
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHY部インタフェースレジスタへのライト */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	return bit;
+}
+
+/*
+ * 単独バス解放
+ */
+static void phy_single_rel_bus()
+{
+	int i;
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHY部インタフェースレジスタへのライト */
+	sil_wrw_mem(ETHERC_PIR, ETHERC_PIR_MMD | ETHERC_PIR_MDC);
+
+	for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
+
+	/* PHY部インタフェースレジスタへのライト */
+	sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
+
+	for(i = ETHERC_PIR_WAIT; i > 0; i--);
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/ether_phy.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/ether_phy.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/ether_phy.h	(revision 398)
@@ -0,0 +1,67 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef ETHER_PHY
+#define ETHER_PHY
+
+#include "if_rx62nreg.h"
+
+typedef enum _phy_mode_t{
+	PHY_MODE_10BASE_HALF	= 0x00,
+	PHY_MODE_10BASE_FULL	= 0x01,
+	PHY_MODE_100BASE_HALF	= 0x02,
+	PHY_MODE_100BASE_FULL	= 0x03,
+} PHY_MODE_T;
+
+typedef enum _phy_state_t{
+	PHY_STATE_UNINIT,
+	PHY_STATE_RESETING,
+	PHY_STATE_RESET,
+	PHY_STATE_LINKE_WAIT,
+	PHY_STATE_LINKED,
+	PHY_STATE_NEGOTIATED,
+} PHY_STATE_T;
+
+extern PHY_STATE_T phy_reset(PHY_STATE_T state, uint8_t phy_addr);
+extern PHY_STATE_T phy_initialize(PHY_STATE_T state, uint8_t phy_addr, PHY_MODE_T *mode);
+extern bool_t phy_is_link(uint8_t phy_addr);
+extern uint16_t phy_read_reg(uint8_t phy_addr, uint8_t rReg);
+extern void phy_write_reg(uint8_t phy_addr, uint8_t wReg, uint16_t wdata);
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n.c	(revision 398)
@@ -0,0 +1,737 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014-2017 by Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1995, David Greenman
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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.
+ * 
+ * $FreeBSD: src/sys/i386/isa/if_ed.c,v 1.148.2.4 1999/09/25 13:08:18 nyan Exp $
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#define CAST(type, val)		((type)(val))
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "kernel/kernel_impl.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/net.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+#include <net/net_buf.h>
+
+#include "if_rx62nreg.h"
+#include <string.h>
+#include "ether_phy.h"
+
+#ifdef _MSC_VER
+#include <stdlib.h>
+#endif
+
+#ifndef TMO_IF_RX62N_GET_NET_BUF
+#define TMO_IF_RX62N_GET_NET_BUF		ULONG_C(1000000)	/* [us] */
+#endif
+
+void mbed_mac_address(char *mac);
+
+/*
+ *  ネットワークインタフェースに依存するソフトウェア情報 
+ */
+
+typedef struct t_rx62n_softc {
+	PHY_STATE_T state;
+	T_RX62N_TX_DESC *tx_write;
+	T_RX62N_RX_DESC *rx_read;
+	bool_t link_pre;
+	bool_t link_now;
+	bool_t over_flow;
+} T_RX62N_SOFTC;
+
+/*
+ *  ネットワークインタフェースのソフトウェア情報
+ */
+
+/* ネットワークインタフェースに依存するソフトウェア情報 */
+
+static T_RX62N_SOFTC rx62n_softc;
+
+typedef struct t_rx62n_buf {
+	uint8_t rx_buff[NUM_IF_RX62N_RXBUF][32 * (((int)&((T_NET_BUF *)0)->buf + IF_RX62N_BUF_PAGE_SIZE + 31) / 32)];
+	uint8_t tx_buff[NUM_IF_RX62N_TXBUF][32 * ((IF_RX62N_BUF_PAGE_SIZE + 31) / 32)];
+	T_RX62N_RX_DESC rx_desc[NUM_IF_RX62N_RXBUF];
+	T_RX62N_TX_DESC tx_desc[NUM_IF_RX62N_TXBUF];
+} T_RX62N_BUF;
+
+#if defined(__RX)
+#pragma	section	ETH_MEMORY
+#define __attribute__(x)
+#endif
+T_RX62N_BUF __attribute__((section("ETH_MEMORY"),aligned(16))) rx62n_buf;
+#if defined(__RX)
+#pragma	section
+#endif
+
+/* ネットワークインタフェースに依存しないソフトウェア情報 */
+
+T_IF_SOFTC if_softc = {
+	{0,},						/* ネットワークインタフェースのアドレス	*/
+	0,							/* 送信タイムアウト			*/
+	&rx62n_softc,				/* ディバイス依存のソフトウェア情報	*/
+	SEM_IF_RX62N_SBUF_READY,	/* 送信セマフォ			*/
+	SEM_IF_RX62N_RBUF_READY,	/* 受信セマフォ			*/
+
+#ifdef SUPPORT_INET6
+
+	IF_MADDR_INIT,				/* マルチキャストアドレスリスト	*/
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+};
+
+/*
+ *  局所変数
+ */
+
+static void rx62n_stop (T_RX62N_SOFTC *sc);
+static void rx62n_init_sub (T_IF_SOFTC *ic);
+static void rx62n_set_ecmr (T_IF_SOFTC *ic, PHY_MODE_T mode);
+
+#ifdef SUPPORT_INET6
+
+static uint32_t ds_crc (uint8_t *addr);
+static void ds_getmcaf (T_IF_SOFTC *ic, uint32_t *mcaf);
+
+/*
+ *  ds_crc -- イーサネットアドレスの CRC を計算する。
+ */
+
+#define POLYNOMIAL	0x04c11db6
+
+static uint32_t
+ds_crc (uint8_t *addr)
+{
+	uint32_t	crc = ULONG_C(0xffffffff);
+	int_t		carry, len, bit;
+	uint8_t		byte;
+
+	for (len = ETHER_ADDR_LEN; len -- > 0; ) {
+		byte = *addr ++;
+		for (bit = 8; bit -- > 0; ) {
+			carry   = ((crc & ULONG_C(0x80000000)) ? 1 : 0) ^ (byte & UINT_C(0x01));
+			crc   <<= 1;
+			byte   >>= 1;
+			if (carry)
+				crc = (crc ^ POLYNOMIAL) | carry;
+		}
+	}
+	return crc;
+}
+
+#undef POLYNOMIAL
+
+/*
+ *  ds_getmcaf -- マルチキャストアドレスのリストからマルチキャストアドレス
+ *                フィルタを計算する。
+ */
+
+static void
+ds_getmcaf (T_IF_SOFTC *ic, uint32_t *mcaf)
+{
+	uint32_t	count, index;
+	uint8_t		*af = (uint8_t*)mcaf;
+
+	mcaf[0] = mcaf[1] = 0;
+
+	for (count = MAX_IF_MADDR_CNT; count -- > 0; ) {
+		index = ds_crc(ic->maddrs[count].lladdr) >> 26;
+		af[index >> 3] |= 1 << (index & 7);
+	}
+}
+
+/*
+ * rx62n_setrcr -- 受信構成レジスタ (RCR) を設定する。
+ */
+
+static void
+rx62n_setrcr (T_IF_SOFTC *ic)
+{
+	T_RX62N_SOFTC	*sc = ic->sc;
+}
+
+/*
+ * rx62n_addmulti -- マルチキャストアドレスを追加する。
+ */
+
+ER
+rx62n_addmulti (T_IF_SOFTC *ic)
+{
+	rx62n_setrcr(ic);
+	return E_OK;
+}
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+/*
+ *  rx62n_stop -- ネットワークインタフェースを停止する。
+ * 
+ *    注意: NIC 割り込み禁止状態で呼び出すこと。
+ */
+
+static void
+rx62n_stop (T_RX62N_SOFTC *sc)
+{
+	/* 動作モードクリア */
+	sil_wrw_mem(ETHERC_ECMR, 0x00000000);
+	/* リンク変化割り込み無効 */
+	sil_wrw_mem(ETHERC_ECSIPR, 0x00000000);
+}
+
+/*
+ *  rx62n_init_sub -- ネットワークインタフェースの初期化
+ * 
+ *    注意: NIC 割り込み禁止状態で呼び出すこと。
+ */
+
+static void
+rx62n_init_sub (T_IF_SOFTC *ic)
+{
+	T_RX62N_SOFTC *sc = ic->sc;
+	uint8_t *mac_addr = ic->ifaddr.lladdr;
+	PHY_STATE_T state = PHY_STATE_UNINIT;
+
+	/* MAC部ソフトウエア・リセット */
+	sil_wrw_mem(EDMAC_EDMR, sil_rew_mem(EDMAC_EDMR) | EDMAC_EDMR_SWR_BIT);
+
+	dly_tsk(1000);
+
+	sil_wrw_mem(ETHERC_MAHR, ((uint32_t)mac_addr[0] << 24)
+		| ((uint32_t)mac_addr[1] << 16) | ((uint32_t)mac_addr[2] << 8 )
+		|  (uint32_t)mac_addr[3]);
+	sil_wrw_mem(ETHERC_MALR, ((uint32_t)mac_addr[4] << 8 )
+		| (uint32_t)mac_addr[5]);
+
+	/* PHYリセット */
+	while ((state = phy_reset(state, 0)) != PHY_STATE_RESET);
+	sc->state = state;
+
+	/* Clear all ETHERC status BFR, PSRTO, LCHNG, MPD, ICD */
+	sil_wrw_mem(ETHERC_ECSR, 0x00000037);
+
+	/* リンク変化割り込み有効 */
+	sil_wrw_mem(ETHERC_ECSIPR, sil_rew_mem(ETHERC_ECSIPR) | ETHERC_ECSIPR_LCHNGIP);
+
+	/* Clear all ETHERC and EDMAC status bits */
+	sil_wrw_mem(EDMAC_EESR, 0x47FF0F9F);
+
+	/* 送受信割り込み有効 */
+	sil_wrw_mem(EDMAC_EESIPR, (EDMAC_EESIPR_TCIP | EDMAC_EESIPR_FRIP | EDMAC_EESIPR_RDEIP | EDMAC_EESIPR_FROFIP));
+
+	/* 受信フレーム長上限（バッファサイズ） */
+	sil_wrw_mem(ETHERC_RFLR, IF_RX62N_BUF_PAGE_SIZE);
+
+	/* 96ビット時間（初期値） */
+	sil_wrw_mem(ETHERC_IPGR, 0x00000014);
+
+	/* Set little endian mode */
+	sil_wrw_mem(EDMAC_EDMR, sil_rew_mem(EDMAC_EDMR) | EDMAC_EDMR_DE_BIT);
+
+	/* Initialize Rx descriptor list address */
+	sil_wrw_mem(EDMAC_RDLAR, (uint32_t)rx62n_buf.rx_desc);
+	/* Initialize Tx descriptor list address */
+	sil_wrw_mem(EDMAC_TDLAR, (uint32_t)rx62n_buf.tx_desc);
+	/* Copy-back status is RFE & TFE only */
+	sil_wrw_mem(EDMAC_TRSCER, 0x00000000);
+	/* Threshold of Tx_FIFO */
+	sil_wrw_mem(EDMAC_TFTR, 0x00000000);
+	/* Transmit fifo & receive fifo is 2048 bytes */
+	sil_wrw_mem(EDMAC_FDR, 0x00000707);
+	/* RR in EDRRR is under driver control */
+	sil_wrw_mem(EDMAC_RMCR, 0x00000001);
+
+	sc->link_pre = false;
+	sc->link_now = false;
+
+#if defined(TARGET_KERNEL_ASP)
+
+	/* ターゲット依存部の割込み初期化 */
+	rx62n_inter_init();
+
+#endif	/* of #if defined(TARGET_KERNEL_ASP) */
+
+#if defined(TARGET_KERNEL_JSP) && TKERNEL_PRVER >= 0x1042u	/* JSP-1.4.2 以降 */
+
+	/* ターゲット依存部の割込み初期化 */
+	rx62n_inter_init();
+
+#endif	/* of #if defined(TARGET_KERNEL_JSP) && TKERNEL_PRVER >= 0x1042u */
+}
+
+
+/*
+ *  rx62n_set_ecmr -- ECMRレジスタの設定
+ */
+
+static void
+rx62n_set_ecmr (T_IF_SOFTC *ic, PHY_MODE_T mode)
+{
+	uint32_t ecmr;
+
+	ecmr = ETHERC_ECMR_RE | ETHERC_ECMR_TE/* | ETHERC_ECMR_PRM*/;
+
+	if ((mode & 0x01) != 0)
+		ecmr |= ETHERC_ECMR_DM;
+	if ((mode & 0x02) != 0)
+		ecmr |= ETHERC_ECMR_RTM;
+
+	/* 動作モード設定 */
+	sil_wrw_mem(ETHERC_ECMR, ecmr);
+}
+
+/*
+ * rx62n_reset -- ネットワークインタフェースをリセットする。
+ */
+
+void
+rx62n_reset (T_IF_SOFTC *ic)
+{
+#ifdef TARGET_KERNEL_JSP
+	IPM	ipm;
+#endif
+
+	/* NIC からの割り込みを禁止する。*/
+#ifdef TARGET_KERNEL_JSP
+	ipm = rx62n_dis_inter();
+#endif
+#ifdef TARGET_KERNEL_ASP
+	syscall(dis_int(INTNO_IF_RX62N_TRX));
+#endif
+	ether_set_link_down();
+
+	NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_RESETS], 1);
+	rx62n_stop(ic->sc);
+	rx62n_init_sub(ic);
+
+	if (sil_rew_mem(EDMAC_EDRRR) == 0) {
+		sil_wrw_mem(EDMAC_EDRRR, EDMAC_EDRRR_RR);
+	}
+
+	/* 送受信を有効 */
+	rx62n_set_ecmr(ic, 1);
+
+	/* NIC からの割り込みを許可する。*/
+#ifdef TARGET_KERNEL_JSP
+	rx62n_ena_inter(ipm);
+#endif
+#ifdef TARGET_KERNEL_ASP
+	syscall(ena_int(INTNO_IF_RX62N_TRX));
+#endif
+}
+
+/*
+ *  get_rx62n_softc -- ネットワークインタフェースのソフトウェア情報を返す。
+ */
+
+T_IF_SOFTC *
+rx62n_get_softc (void)
+{
+	return &if_softc;
+}
+
+/*
+ * rx62n_watchdog -- ネットワークインタフェースのワッチドッグタイムアウト
+ */
+
+void
+rx62n_watchdog (T_IF_SOFTC *ic)
+{
+	rx62n_reset(ic);
+}
+
+/*
+ * rx62n_probe -- ネットワークインタフェースの検出
+ */
+
+void
+rx62n_probe (T_IF_SOFTC *ic)
+{
+	int i;
+#if defined(TARGET_KERNEL_ASP)
+
+	/* ターゲット依存部のバスの初期化 */
+	rx62n_bus_init();
+
+#endif	/* of #if defined(TARGET_KERNEL_ASP) */
+#if defined(TARGET_KERNEL_JSP) && TKERNEL_PRVER >= 0x1042u	/* JSP-1.4.2 以降 */
+
+	/* ターゲット依存部のバスの初期化 */
+	rx62n_bus_init();
+
+#endif	/* of #if defined(TARGET_KERNEL_JSP) && TKERNEL_PRVER >= 0x1042u */
+
+	mbed_mac_address(ic->ifaddr.lladdr);
+}
+
+/*
+ * rx62n_init -- ネットワークインタフェースの初期化
+ */
+
+void
+rx62n_init (T_IF_SOFTC *ic)
+{
+#ifdef TARGET_KERNEL_JSP
+	IPM	ipm;
+#endif
+	T_RX62N_SOFTC *sc = ic->sc;
+	T_RX62N_TX_DESC *tdsc;
+	T_RX62N_RX_DESC *rdsc;
+	int i;
+
+	/* NIC からの割り込みを禁止する。*/
+#ifdef TARGET_KERNEL_JSP
+	ipm = rx62n_dis_inter();
+#endif
+#ifdef TARGET_KERNEL_ASP
+	syscall(dis_int(INTNO_IF_RX62N_TRX));
+#endif
+
+	tdsc = (T_RX62N_TX_DESC *)rx62n_buf.tx_desc;
+	sc->tx_write = tdsc;
+	for ( i=0 ; i < NUM_IF_RX62N_TXBUF ; i++ ) {
+		memset(tdsc, 0, sizeof(*tdsc));
+		tdsc->tbl = 0;
+		tdsc->tba = (uint32_t)&rx62n_buf.tx_buff[i];
+		tdsc++;
+	}
+	tdsc--;
+	tdsc->tdle = 1;
+
+	rdsc = (T_RX62N_RX_DESC *)rx62n_buf.rx_desc;
+	sc->rx_read = rdsc;
+	for ( i=0 ; i < NUM_IF_RX62N_RXBUF ; i++ ) {
+		memset(rdsc, 0, sizeof(*rdsc));
+		rdsc->rbl = IF_RX62N_BUF_PAGE_SIZE;
+		rdsc->rba = (uint32_t)&rx62n_buf.rx_buff[i] + (uint32_t)&((T_NET_BUF *)0)->buf;
+		rdsc->rfl = 0;
+		rdsc->ract = 1;
+		rdsc++;
+	}
+	rdsc--;
+	rdsc->rdle = 1;
+
+	/* rx62n_init 本体を呼び出す。*/
+	rx62n_init_sub(ic);
+
+	if (sil_rew_mem(EDMAC_EDRRR) == 0) {
+		sil_wrw_mem(EDMAC_EDRRR, EDMAC_EDRRR_RR);
+	}
+
+	/* 送受信を有効 */
+	rx62n_set_ecmr(ic, 1);
+
+	/* NIC からの割り込みを許可する。*/
+#ifdef TARGET_KERNEL_JSP
+	rx62n_ena_inter(ipm);
+#endif
+#ifdef TARGET_KERNEL_ASP
+	syscall(ena_int(INTNO_IF_RX62N_TRX));
+#endif
+
+	syscall(sta_cyc(CYC_IF_RX62N_LINK));
+}
+
+
+/* 
+ * rx62n_link -- リンク状態の変化に対する処理
+ */
+bool_t
+rx62n_link(T_IF_SOFTC *ic)
+{
+	T_RX62N_SOFTC *sc = ic->sc;
+	PHY_MODE_T mode;
+	uint8_t phy_addr = 0;
+
+	if(sc->state == PHY_STATE_NEGOTIATED){
+		if(!phy_is_link(phy_addr))
+			sc->state = PHY_STATE_RESET;
+		return true;
+	}
+
+	/* PHYの初期化 */
+	sc->state = phy_initialize(sc->state, phy_addr, &mode);
+	if(sc->state != PHY_STATE_NEGOTIATED){
+		return false;
+	}
+
+	/* ECMRレジスタの設定 */
+	rx62n_set_ecmr(ic, mode);
+	return true;
+}
+
+/*
+ * rx62n_read -- フレームの読み込み
+ */
+
+T_NET_BUF *
+rx62n_read (T_IF_SOFTC *ic)
+{
+	T_RX62N_SOFTC *sc = ic->sc;
+	T_RX62N_RX_DESC *desc;
+	uint16_t len;
+	T_NET_BUF *input = NULL;
+	uint16_t align;
+	uint8_t *dst;
+	ER error;
+	PHY_MODE_T mode;
+
+	sc->link_now = rx62n_link(ic);
+	if (sc->link_pre != sc->link_now) {
+		sc->link_pre = sc->link_now;
+		/* リンク状態に変化あり */
+		if (sc->link_now) {
+			ether_set_link_up();
+		}
+		else {
+			ether_set_link_down();
+		}
+	}
+
+	if (sc->over_flow) {
+		sc->over_flow = false;
+	}
+
+	desc = sc->rx_read;
+
+	if (desc->ract != 0) {
+		return NULL;
+	}
+
+	len = desc->rfl;
+	/*
+	 *  +-----------+--------+---------+---------+
+	 *  | Ehter HDR | IP HDR | TCP HDR | TCP SDU |
+	 *  +-----------+--------+---------+---------+
+	 *        14        20        20        n
+	 *   <----------------- len ---------------->
+	 *              ^
+	 *              t_net_buf で 4 オクテット境界にアラインされている。
+	 *
+	 *  tcp_input と udp_input では、擬似ヘッダと SDU でチェックサムを
+	 *  計算するが、n が 4 オクテット境界になるように SDU の後ろに 0 を
+	 *  パッディングする。その分を考慮して net_buf を獲得しなければならない。
+	 */
+	align = ((((len - sizeof(T_IF_HDR)) + 3) >> 2) << 2) + sizeof(T_IF_HDR);
+
+	if ((error = tget_net_buf(&input, align, TMO_IF_RX62N_GET_NET_BUF)) == E_OK && input != NULL) {
+		dst = input->buf + IF_ETHER_NIC_HDR_ALIGN;
+		memcpy(dst, (void *)desc->rba, len);
+	}
+	else {
+		NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_IN_ERR_PACKETS], 1);
+		NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_NO_BUFS], 1);
+	}
+
+	desc->rfp = 0;
+	desc->ract = 1;
+
+	desc++;
+	if (desc == &rx62n_buf.rx_desc[NUM_IF_RX62N_RXBUF]) {
+		desc = rx62n_buf.rx_desc;
+	}
+	sc->rx_read = desc;
+
+	if (sil_rew_mem(EDMAC_EDRRR) == 0) {
+		sil_wrw_mem(EDMAC_EDRRR, EDMAC_EDRRR_RR);
+	}
+
+	return input;
+}
+
+/*
+ * rx62n_start -- 送信フレームをバッファリングする。
+ */
+
+void
+rx62n_start (T_IF_SOFTC *ic, T_NET_BUF *output)
+{
+	T_RX62N_SOFTC *sc = ic->sc;
+	T_RX62N_TX_DESC *desc, *next;
+	uint8_t *buf = NULL;
+	int32_t len, res, pos;
+	uint32_t tfp;
+
+	for ( res = output->len, pos = 0; res > 0; res -= len, pos += len ) {
+		desc = sc->tx_write;
+
+		while (desc->tact != 0) {
+			tslp_tsk(1000);
+		}
+
+		buf = (uint8_t *)desc->tba + IF_ETHER_NIC_HDR_ALIGN;
+
+		next = desc + 1;
+		if (next == &rx62n_buf.tx_desc[NUM_IF_RX62N_TXBUF]) {
+			next = rx62n_buf.tx_desc;
+		}
+		sc->tx_write = next;
+
+		len = res;
+		if ( len > IF_RX62N_BUF_PAGE_SIZE ) {
+			len = IF_RX62N_BUF_PAGE_SIZE;
+			tfp = 0x0;
+		}
+		else
+			tfp = 0x1;
+
+		if (pos == 0)
+			tfp |= 0x2;
+
+		memcpy(buf, (uint8_t *)output->buf + pos, len);
+
+		desc->tbl = len;
+		desc->tfp = tfp;
+		desc->tact = 1;
+	}
+
+	if (sil_rew_mem(EDMAC_EDTRR) == 0) {
+		sil_wrw_mem(EDMAC_EDTRR, EDMAC_EDTRR_TR);
+	}
+}
+
+/*
+ *  RX62N Ethernet Controler 送受信割り込みハンドラ
+ */
+
+void
+if_rx62n_trx_handler (void)
+{
+	T_IF_SOFTC *ic;
+	T_RX62N_SOFTC *sc;
+	uint32_t ecsr, eesr;
+
+	ic = &if_softc;
+	sc = ic->sc;
+
+	ecsr = sil_rew_mem(ETHERC_ECSR);
+
+	if (ecsr & ETHERC_ECSR_LCHNG) {
+		/* ETHERC部割り込み要因クリア */
+		sil_wrw_mem(ETHERC_ECSR, ETHERC_ECSR_LCHNG);
+
+		/* 受信割り込み処理 */
+		isig_sem(ic->semid_rxb_ready);
+	}
+
+	eesr = sil_rew_mem(EDMAC_EESR);
+
+	if (eesr & EDMAC_EESR_FR) {
+		/* DMA部割り込み要因クリア */
+		sil_wrw_mem(EDMAC_EESR, EDMAC_EESR_FR);
+
+		/* 受信割り込み処理 */
+		isig_sem(ic->semid_rxb_ready);
+	}
+	if (eesr & EDMAC_EESR_TC) {
+		/* DMA部割り込み要因クリア */
+		sil_wrw_mem(EDMAC_EESR, EDMAC_EESR_TC);
+
+		/* 送信割り込み処理 */
+		isig_sem(ic->semid_txb_ready);
+	}
+	if (eesr & (EDMAC_EESR_FROF | EDMAC_EESR_RDE)) {
+		/* DMA部割り込み要因クリア */
+		sil_wrw_mem(EDMAC_EESR, EDMAC_EESR_FROF | EDMAC_EESR_RDE);
+
+		sc->over_flow = true;
+
+		/* 受信割り込み処理 */
+		isig_sem(ic->semid_rxb_ready);
+	}
+}
+
+void if_rx62n_cyclic_handler(void)
+{
+	T_IF_SOFTC *ic;
+	T_RX62N_SOFTC *sc;
+
+	ic = &if_softc;
+	sc = ic->sc;
+
+	/* 受信割り込み処理 */
+	isig_sem(ic->semid_rxb_ready);
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n.cfg	(revision 398)
@@ -0,0 +1,61 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  if_rx62n コンフィギュレーションファイル
+ */
+
+#ifdef SUPPORT_ETHER
+
+INCLUDE("<if_rx62nreg.h>");
+
+/* 割り込みハンドラ */
+
+DEF_INH(INHNO_IF_RX62N_TRX, { TA_HLNG, if_rx62n_trx_handler });
+
+/* 入出力同期用セマフォ */
+
+CRE_SEM(SEM_IF_RX62N_SBUF_READY,	{ TA_TPRI, NUM_IF_RX62N_TXBUF, NUM_IF_RX62N_TXBUF });
+CRE_SEM(SEM_IF_RX62N_RBUF_READY,	{ TA_TPRI, 0,                  NUM_IF_RX62N_RXBUF });
+
+/* リンク確認用周期ハンドラ */
+
+CRE_CYC(CYC_IF_RX62N_LINK, { TA_NULL, 0, if_rx62n_cyclic_handler, 1000, 0 });
+
+#endif	/* of #ifdef SUPPORT_ETHER */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n.h	(revision 398)
@@ -0,0 +1,110 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (C) 1993, David Greenman. This software may be used, modified,
+ *   copied, distributed, and sold, in both source and binary form provided
+ *   that the above copyright and these terms are retained. Under no
+ *   circumstances is the author responsible for the proper functioning
+ *   of this software, nor does the author assume any responsibility
+ *   for damages incurred with its use.
+ */
+
+#ifndef _IF_RX62N_H_
+#define _IF_RX62N_H_
+
+/*
+ *  NIC の選択マクロ
+ */
+
+#define IF_ETHER_NIC_GET_SOFTC()	rx62n_get_softc()
+#define IF_ETHER_NIC_WATCHDOG(i)	rx62n_watchdog(i)
+#define IF_ETHER_NIC_PROBE(i)		rx62n_probe(i)
+#define IF_ETHER_NIC_INIT(i)		rx62n_init(i)
+#define IF_ETHER_NIC_READ(i)		rx62n_read(i)
+#define IF_ETHER_NIC_RESET(i)		rx62n_reset(i)
+#define IF_ETHER_NIC_START(i,o)		rx62n_start(i,o)
+
+#define T_IF_ETHER_NIC_SOFTC		struct t_rx62n_softc
+
+/* IPv6 関係 */
+
+#define IF_ETHER_NIC_IN6_IFID(i,a)	get_mac6_ifid(i,a)	/* インタフェース識別子の設定		*/
+#define IF_ETHER_NIC_ADDMULTI(s)	rx62n_addmulti(s)		/* マルチキャストアドレスの登録		*/
+
+#if !defined(TOPPERS_MACRO_ONLY) && !defined(_MACRO_ONLY)
+
+/*
+ *  前方参照
+ */
+
+#ifndef T_IF_SOFTC_DEFINED
+
+typedef struct t_if_softc T_IF_SOFTC;
+
+#define T_IF_SOFTC_DEFINED
+
+#endif	/* of #ifndef T_IF_SOFTC_DEFINED */
+
+#ifndef T_NET_BUF_DEFINED
+
+typedef struct t_net_buf T_NET_BUF;
+
+#define T_NET_BUF_DEFINED
+
+#endif	/* of #ifndef T_NET_BUF_DEFINED */
+
+/*
+ *  関数
+ */
+
+extern T_IF_SOFTC *rx62n_get_softc(void);
+extern void rx62n_watchdog(T_IF_SOFTC *ic);
+extern void rx62n_probe(T_IF_SOFTC *ic);
+extern void rx62n_init(T_IF_SOFTC *ic);
+extern void rx62n_reset(T_IF_SOFTC *ic);
+extern T_NET_BUF *rx62n_read(T_IF_SOFTC *ic);
+extern void rx62n_start(T_IF_SOFTC *ic, T_NET_BUF *output);
+extern ER rx62n_addmulti(T_IF_SOFTC *ic);
+extern void if_rx62n_trx_handler(void);
+extern void if_rx62n_cyclic_handler(void);
+
+#endif /* #if !defined(TOPPERS_MACRO_ONLY) && !defined(_MACRO_ONLY) */
+
+#endif	/* of #ifndef _IF_RX62N_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n_sym.def
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n_sym.def	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62n_sym.def	(revision 398)
@@ -0,0 +1,4 @@
+INHNO_IF_RX62N_TRX
+INTNO_IF_RX62N_TRX
+INTATR_IF_RX62N_TRX
+INTPRI_IF_RX62N_TRX
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62nreg.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62nreg.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/if_rx62nreg.h	(revision 398)
@@ -0,0 +1,158 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014-2015 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef RX62NRegH
+#define RX62NRegH
+
+#include "t_stddef.h"
+
+#define EDMAC_EDMR			((uint32_t *)0x000C0000)	/* EDMACモードレジスタ */
+#define EDMAC_EDMR_SWR_BIT	0x00000001
+#define EDMAC_EDMR_DE_BIT	0x00000040
+
+#define EDMAC_EDTRR			((uint32_t *)0x000C0008)	/* EDMAC送信要求レジスタ */
+#define EDMAC_EDTRR_TR		0x00000001
+
+#define EDMAC_EDRRR			((uint32_t *)0x000C0010)	/* EDMAC受信要求レジスタ */
+#define EDMAC_EDRRR_RR		0x00000001
+
+#define EDMAC_TDLAR			((uint32_t *)0x000C0018)	/* 送信ディスクリプタリスト先頭アドレスレジスタ */
+#define EDMAC_RDLAR			((uint32_t *)0x000C0020)	/* 受信ディスクリプタリスト先頭アドレスレジスタ */
+
+#define EDMAC_EESR			((uint32_t *)0x000C0028)	/* ETHERC/EDMACステータスレジスタ */
+#define EDMAC_EESR_FROF		0x00010000
+#define EDMAC_EESR_RDE		0x00020000
+#define EDMAC_EESR_FR		0x00040000
+#define EDMAC_EESR_TC		0x00200000
+#define EDMAC_EESR_TWB		0x40000000
+
+#define EDMAC_EESIPR		((uint32_t *)0x000C0030)	/* ETHERC/EDMACステータス割り込み許可レジスタ */
+#define EDMAC_EESIPR_RMAFIP	0x00000080
+#define EDMAC_EESIPR_FROFIP	0x00010000
+#define EDMAC_EESIPR_RDEIP	0x00020000
+#define EDMAC_EESIPR_FRIP	0x00040000
+#define EDMAC_EESIPR_TCIP	0x00200000
+#define EDMAC_EESIPR_TWBIP	0x40000000
+
+#define EDMAC_TRSCER		((uint32_t *)0x000C0038)	/* 送受信ステータスコピー指示レジスタ */
+#define EDMAC_RMFCR			((uint32_t *)0x000C0040)	/* ミスドフレームカウンタレジスタ */
+#define EDMAC_TFTR			((uint32_t *)0x000C0048)	/* 送信FIFOしきい値指定レジスタ */
+#define EDMAC_FDR			((uint32_t *)0x000C0050)	/* FIFO容量指定レジスタ */
+#define EDMAC_RMCR			((uint32_t *)0x000C0058)	/* 受信方式制御レジスタ */
+#define EDMAC_TFUCR			((uint32_t *)0x000C0064)	/* 送信FIFOアンダランカウント */
+#define EDMAC_RFOCR			((uint32_t *)0x000C0068)	/* 受信FIFOオーバフローカウント */
+#define EDMAC_IOSR			((uint32_t *)0x000C006C)	/* 個別出力信号設定レジスタ */
+#define EDMAC_FCFTR			((uint32_t *)0x000C0070)	/* フロー制御開始FIFOしきい値設定レジスタ */
+#define EDMAC_RPADIR		((uint32_t *)0x000C0078)	/* 受信データパディング挿入設定レジスタ */
+#define EDMAC_TRIMD			((uint32_t *)0x000C007C)	/* 送信割り込み設定レジスタ */
+#define EDMAC_RBWAR			((uint32_t *)0x000C00C8)	/* 受信バッファライトアドレスレジスタ */
+#define EDMAC_RDFAR			((uint32_t *)0x000C00CC)	/* 受信ディスクリプタフェッチアドレスレジスタ */
+#define EDMAC_TBRAR			((uint32_t *)0x000C00D4)	/* 送信バッファリードアドレスレジスタ */
+#define EDMAC_TDFAR			((uint32_t *)0x000C00D8)	/* 送信ディスクリプタフェッチアドレスレジスタ */
+
+#define ETHERC_ECMR			((uint32_t *)0x000C0100)	/* ETHERCモードレジスタ */
+#define ETHERC_ECMR_PRM		0x00000001
+#define ETHERC_ECMR_DM		0x00000002
+#define ETHERC_ECMR_RTM		0x00000004
+#define ETHERC_ECMR_TE		0x00000020
+#define ETHERC_ECMR_RE		0x00000040
+
+#define ETHERC_RFLR			((uint32_t *)0x000C0108)	/* 受信フレーム長上限レジスタ */
+#define ETHERC_ECSR			((uint32_t *)0x000C0110)	/* ETHERCステータスレジスタ */
+#define ETHERC_ECSR_LCHNG	0x00000004
+#define ETHERC_ECSIPR		((uint32_t *)0x000C0118)	/* ETHERC割り込み許可レジスタ */
+#define ETHERC_ECSIPR_LCHNGIP	0x00000004
+#define ETHERC_PIR			((uint32_t *)0x000C0120)	/* PHY部インタフェースレジスタ */
+#define ETHERC_PIR_MDC		0x00000001
+#define ETHERC_PIR_MMD		0x00000002
+#define ETHERC_PIR_MDO		0x00000004
+#define ETHERC_PIR_MDI		0x00000008
+
+#define ETHERC_PSR			((uint32_t *)0x000C0128)	/* PHY部ステータスレジスタ */
+#define ETHERC_PSR_LMON		0x00000001
+
+#define ETHERC_RDMLR		((uint32_t *)0x000C0140)	/* 乱数生成カウンタ上限値設定レジスタ */
+#define ETHERC_IPGR			((uint32_t *)0x000C0150)	/* IPG設定レジスタ */
+#define ETHERC_APR			((uint32_t *)0x000C0154)	/* 自動PAUSEフレーム設定レジスタ */
+#define ETHERC_MPR			((uint32_t *)0x000C0158)	/* 手動PAUSEフレーム設定レジスタ */
+#define ETHERC_RFCF			((uint32_t *)0x000C0160)	/* 受信PAUSEフレームカウンタ */
+#define ETHERC_TPAUSER		((uint32_t *)0x000C0164)	/* 自動PAUSEフレーム再送回数設定レジスタ */
+#define ETHERC_TPAUSECR		((uint32_t *)0x000C0168)	/* PAUSEフレーム再送回数カウンタ */
+#define ETHERC_BCFRR		((uint32_t *)0x000C016C)	/* Broadcastフレーム受信回数設定レジスタ */
+#define ETHERC_MAHR			((uint32_t *)0x000C01C0)	/* MACアドレス上位設定レジスタ */
+#define ETHERC_MALR			((uint32_t *)0x000C01C8)	/* MACアドレス下位設定レジスタ */
+#define ETHERC_TROCR		((uint32_t *)0x000C01D0)	/* 送信リトライオーバカウンタレジスタ */
+#define ETHERC_CDCR			((uint32_t *)0x000C01D4)	/* 遅延衝突検出カウンタレジスタ */
+#define ETHERC_LCCR			((uint32_t *)0x000C01D8)	/* キャリア消失カウンタレジスタ */
+#define ETHERC_CNDCR		((uint32_t *)0x000C01DC)	/* キャリア未検出カウンタレジスタ */
+#define ETHERC_CEFCR		((uint32_t *)0x000C01E4)	/* CRCエラーフレーム受信カウンタレジスタ */
+#define ETHERC_FRECR		((uint32_t *)0x000C01E8)	/* フレーム受信エラーカウンタレジスタ */
+#define ETHERC_TSFRCR		((uint32_t *)0x000C01EC)	/* 64バイト未満フレーム受信カウンタレジスタ */
+#define ETHERC_TLFRCR		((uint32_t *)0x000C01F0)	/* 指定バイト超フレーム受信カウンタレジスタ */
+#define ETHERC_RFCR			((uint32_t *)0x000C01F4)	/* 端数ビットフレーム受信カウンタレジスタ */
+#define ETHERC_MAFCR		((uint32_t *)0x000C01F8)	/* マルチキャストアドレスフレーム受信カウンタレジスタ */
+
+/* 送信ディスクリプタ */
+typedef struct t_rx62n_tx_desc {
+	uint32_t	tfs : 26;
+	uint32_t	twbi : 1;
+	uint32_t	tfe : 1;
+	uint32_t	tfp : 2;
+	uint32_t	tdle : 1;
+	uint32_t	tact : 1;
+	uint32_t	: 16;
+	uint32_t	tbl : 16;
+	uint32_t	tba;
+	uint32_t	binding;
+} T_RX62N_TX_DESC;
+
+/* 受信ディスクリプタ */
+typedef struct t_rx62n_rx_desc {
+	uint32_t	rfs : 27;
+	uint32_t	rfe : 1;
+	uint32_t	rfp : 2;
+	uint32_t	rdle : 1;
+	uint32_t	ract : 1;
+	uint32_t	rfl : 16;
+	uint32_t	rbl : 16;
+	uint32_t	rba;
+	uint32_t	binding;
+} T_RX62N_RX_DESC;
+
+#endif /* RX62NRegH */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/nic.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/nic.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/nic.cfg	(revision 398)
@@ -0,0 +1,40 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include "if_rx62n.cfg"
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/nic_asp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/nic_asp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/nic_asp.cfg	(revision 398)
@@ -0,0 +1,62 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  if_rx62n コンフィギュレーションファイル
+ */
+
+#ifdef SUPPORT_ETHER
+
+#include "if_rx62nreg.h"
+
+/* 割り込みハンドラ */
+
+DEF_INH(INHNO_IF_RX62N_TRX, { TA_NULL, if_rx62n_trx_handler });
+CFG_INT(INTNO_IF_RX62N_TRX, { INTATR_IF_RX62N_TRX, INTPRI_IF_RX62N_TRX });
+
+/* 入出力同期用セマフォ */
+
+CRE_SEM(SEM_IF_RX62N_SBUF_READY,	{ TA_TPRI, NUM_IF_RX62N_TXBUF, NUM_IF_RX62N_TXBUF });
+CRE_SEM(SEM_IF_RX62N_RBUF_READY,	{ TA_TPRI, 0,                  NUM_IF_RX62N_RXBUF });
+
+/* リンク確認用周期ハンドラ */
+
+CRE_CYC(CYC_IF_RX62N_LINK, { TA_NULL, { TNFY_HANDLER, 0, if_rx62n_cyclic_handler }, 1000000, 0 });
+
+#endif	/* of #ifdef SUPPORT_ETHER */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/nic_rename.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/nic_rename.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/nic_rename.h	(revision 398)
@@ -0,0 +1,68 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _NIF_RENAME_H_
+#define _NIF_RENAME_H_
+
+/*
+ *  ネットワークインタフェース内部名のリネーム
+ */
+
+/* if_rx62n.c */
+
+#define rx62n_get_softc		_tinet_rx62n_get_softc
+#define rx62n_watchdog		_tinet_rx62n_watchdog
+#define rx62n_probe		_tinet_rx62n_probe
+#define rx62n_init			_tinet_rx62n_init
+#define rx62n_read			_tinet_rx62n_read
+#define rx62n_reset		_tinet_rx62n_reset
+#define rx62n_start		_tinet_rx62n_start
+#define if_softc		_tinet_if_softc
+
+/* config/<cpu>/tinet_cpu_config.c */
+
+#define rx62n_inter_clear	_tinet_rx62n_inter_clear
+
+#ifdef SUPPORT_INET6
+
+#define rx62n_addmulti		_tinet_rx62n_addmulti
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#endif	/* of #ifndef _NIF_RENAME_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/tinet_nic_config.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/tinet_nic_config.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/tinet_nic_config.h	(revision 398)
@@ -0,0 +1,51 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TINET_NIC_CONFIG_H_
+#define _TINET_NIC_CONFIG_H_
+
+/*
+ *  ネットワークインタフェースの内部識別名のリネーム
+ */
+
+#include "nic_rename.h"
+
+#include "if_rx62n.h"
+
+#endif	/* of #ifndef _TINET_NIC_CONFIG_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/tinet_nic_defs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/tinet_nic_defs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netdev/if_rx62n/tinet_nic_defs.h	(revision 398)
@@ -0,0 +1,51 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TINET_NIC_DEFS_H_
+#define _TINET_NIC_DEFS_H_
+
+#define IF_ETHER_RX62N
+
+/* 
+ *  T_ETHER_HDR で、アラインを調整する場合は、調整量を指定する。
+ *  調整しない場合は、0 を指定する。
+ */
+#define IF_ETHER_NIC_HDR_ALIGN		0
+
+#endif	/* of #ifndef _TINET_NIC_DEFS_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/icmp6.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/icmp6.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/icmp6.h	(revision 398)
@@ -0,0 +1,495 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet/icmp6.h,v 1.2.2.3 2001/07/06 05:36:35 sumikawa Exp $	*/
+/*	$KAME: icmp6.h,v 1.46 2001/04/27 15:09:48 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip_icmp.h	8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _IP_ICMP6_H_
+#define _IP_ICMP6_H_
+
+/*
+ *  ICMPv6 ヘッダ
+ */
+
+typedef struct t_icmp6_hdr {
+	uint8_t		type;		/* メッセージの型	*/
+	uint8_t		code;		/* サブ型		*/
+	uint16_t	sum;		/* チェックサム		*/
+	union {
+		uint32_t	data32;
+		uint16_t	data16[2];
+		uint8_t		data8[4];
+		} data;
+	} __attribute__((packed, aligned(2))) T_ICMP6_HDR;
+
+#define icmp6_data32			data.data32
+#define icmp6_data16			data.data16
+#define icmp6_data8			data.data8
+#define icmp6_pptr			data.data32		/* パラメータ異常	*/
+#define icmp6_mtu			data.data32		/* パラメータ異常	*/
+#define icmp6_id			data.data16[0]		/* エコー要求と応答	*/
+#define icmp6_seq			data.data16[1]		/* エコー要求と応答	*/
+
+#define ICMP6_HDR_SIZE			(sizeof(T_ICMP6_HDR))
+#define IF_IP6_ICMP6_HDR_OFFSET		(IF_IP6_HDR_SIZE)
+
+#define GET_ICMP6_HDR(nbuf,ihoff)	((T_ICMP6_HDR*)((uint8_t*)((nbuf)->buf) + ihoff))
+#define GET_ICMP6_SDU(nbuf,ihoff)	((uint8_t*)((nbuf)->buf) + ihoff + ICMP6_HDR_SIZE)
+
+#define GET_IP6_ICMP6_HDR_SIZE(nbuf)	(GET_IP6_HDR_SIZE(nbuf) + ICMP6_HDR_SIZE)
+#define GET_IF_IP6_ICMP6_HDR_SIZE(nbuf)	(IF_HDR_SIZE + GET_IP6_ICMP6_HDR_SIZE(nbuf))
+
+/*
+ *  ICMP6 タイプ
+ */
+
+#define ICMP6_DST_UNREACH		UINT_C(1)	/* 宛先到達不可能		*/
+#define ICMP6_PACKET_TOO_BIG		UINT_C(2)	/* パケットが大きすぎる。	*/
+#define ICMP6_TIME_EXCEEDED		UINT_C(3)	/* TTL を超過した。		*/
+#define ICMP6_PARAM_PROB		UINT_C(4)	/* IPv6 ヘッダが不正。		*/
+
+#define ICMP6_ECHO_REQUEST		UINT_C(128)	/* エコー要求			*/
+#define ICMP6_ECHO_REPLY		UINT_C(129)	/* エコー応答			*/
+
+#define ICMP6_MEMBERSHIP_QUERY		UINT_C(130)	/* グループメンバ照会		*/
+#define ICMP6_MEMBERSHIP_REPORT		UINT_C(131)	/* グループメンバ報告		*/
+#define ICMP6_MEMBERSHIP_REDUCTION	UINT_C(132)	/* グループメンバ終了		*/
+
+#define MLD_LISTENER_QUERY		UINT_C(130)	/* マルチキャスト受信者照会	*/
+#define MLD_LISTENER_REPORT		UINT_C(131)	/* マルチキャスト受信者報告	*/
+#define MLD_LISTENER_DONE		UINT_C(132)	/* マルチキャスト受信者終了	*/
+
+#define ND_ROUTER_SOLICIT		UINT_C(133)	/* ルータ要請			*/
+#define ND_ROUTER_ADVERT		UINT_C(134)	/* ルータ通知			*/
+#define ND_NEIGHBOR_SOLICIT		UINT_C(135)	/* 近隣要請			*/
+#define ND_NEIGHBOR_ADVERT		UINT_C(136)	/* 近隣通知			*/
+#define ND_REDIRECT			UINT_C(137)	/* 向け直し			*/
+
+#define ICMP6_ROUTER_RENUMBERING	UINT_C(138)	/* ルータ番号再設定		*/
+
+#define ICMP6_WRU_REQUEST		UINT_C(139)	/* 要求ノード探索		*/
+#define ICMP6_WRU_REPLY			UINT_C(140)	/* 応答ノード探索		*/
+
+#define ICMP6_FQDN_QUERY		UINT_C(139)	/* FQDN 照会			*/
+#define ICMP6_FQDN_REPLY		UINT_C(140)	/* FQDN 応答			*/
+
+#define ICMP6_NI_QUERY			UINT_C(139)	/* ノード情報照会		*/
+#define ICMP6_NI_REPLY			UINT_C(140)	/* ノード情報応答		*/
+
+#define ICMP6_MAX_TYPE			UINT_C(203)	/* ICMP6 タイプの最大値		*/
+
+/*
+ *  ICMP6 コード
+ */
+
+/* 宛先到達不可能 */
+
+#define ICMP6_DST_UNREACH_NOROUTE	UINT_C(0)	/* 到達ルートなし。		*/
+#define ICMP6_DST_UNREACH_ADMIN		UINT_C(1)	/* 管理者により無効化中。	*/
+#define ICMP6_DST_UNREACH_NOTEIGHBOR	UINT_C(2)	/* 近隣者ではなくなった。	*/
+#define ICMP6_DST_UNREACH_BEYOND_SCOPE	UINT_C(2)	/* スコープを超えている。	*/
+#define ICMP6_DST_UNREACH_ADDR		UINT_C(3)	/* 宛先アドレスに到達不可能。	*/
+#define ICMP6_DST_UNREACH_NOPORT	UINT_C(4)	/* 宛先ポートに到達不可能。	*/
+
+/* TTL 超過 */
+
+#define ICMP6_TIME_EXCEED_TRANSIT	UINT_C(0)	/* 転送時に TTL==0 になった。	*/
+#define ICMP6_TIME_EXCEED_REASSEMBLY	UINT_C(1)	/* IP 再構成でタイムアウトした。*/
+
+/* ヘッダ不正 */
+
+#define ICMP6_PARAMPROB_HEADER		UINT_C(0)	/* ヘッダに不正があった。	*/
+#define ICMP6_PARAMPROB_NEXT_HEADER	UINT_C(1)	/* 次ヘッダが認識できない。	*/
+#define ICMP6_PARAMPROB_OPTION		UINT_C(2)	/* オプションが認識できない。	*/
+
+/* 内部使用 */
+#define ND_REDIRECT_ONLINK		UINT_C(0)	/* オンリンクへの向け直し	*/
+#define ND_REDIRECT_ROUTER		UINT_C(1)	/* ルータへの向け直し		*/
+
+/*
+ *  制限値
+ */
+
+							/* ICMPv6 の最大ペイロード長	*/
+#define ICMPV6_PAYLOAD_MAXLEN		(IPV6_MMTU - (IP6_HDR_SIZE + ICMP6_HDR_SIZE))
+
+/*
+ *  近隣要請
+ */
+
+typedef struct t_neighbor_solicit_hdr {
+	T_ICMP6_HDR	hdr;
+	T_IN6_ADDR	target;
+	/* この後にオプションが続く */
+	} T_NEIGHBOR_SOLICIT_HDR;
+
+#define NEIGHBOR_SOLICIT_HDR_SIZE	(sizeof(T_NEIGHBOR_SOLICIT_HDR))
+#define IF_IP6_NEIGHBOR_SOLICIT_HDR_OFFSET	\
+					(IF_IP6_HDR_SIZE)
+
+#define GET_NEIGHBOR_SOLICIT_HDR(nbuf,nhoff)	\
+					((T_NEIGHBOR_SOLICIT_HDR*)((uint8_t*)((nbuf)->buf) + nhoff))
+#define GET_NEIGHBOR_SOLICIT_SDU(nbuf,nhoff)	\
+					((uint8_t*)((nbuf)->buf) + nhoff + NEIGHBOR_SOLICIT_HDR_SIZE)
+
+#define GET_IP6_NEIGHBOR_SOLICIT_HDR_SIZE(nbuf)		\
+					(GET_IP6_HDR_SIZE(nbuf) + NEIGHBOR_SOLICIT_HDR_SIZE)
+#define GET_IF_IP6_NEIGHBOR_SOLICIT_HDR_SIZE(nbuf)	\
+					(GET_IP6_NEIGHBOR_SOLICIT_HDR_SIZE(nbuf) + IF_HDR_SIZE)
+
+/*
+ *  近隣通知
+ */
+
+typedef struct t_neighbor_advert_hdr {
+	T_ICMP6_HDR	hdr;
+	T_IN6_ADDR	target;
+	/* この後にオプションが続く */
+	} __attribute__((packed, aligned(2))) T_NEIGHBOR_ADVERT_HDR;
+
+/* ICMP6 ヘッダのデータ部の定義 */
+
+#define nd_na_flags_reserved		hdr.data.data32
+
+#define NEIGHBOR_ADVERT_HDR_SIZE	(sizeof(T_NEIGHBOR_ADVERT_HDR))
+#define IP6_NEIGHBOR_ADVERT_HDR_SIZE	(IP6_HDR_SIZE + NEIGHBOR_ADVERT_HDR_SIZE)
+#define IF_IP6_NEIGHBOR_ADVERT_HDR_SIZE	\
+					(IF_IP6_HDR_SIZE + NEIGHBOR_ADVERT_HDR_SIZE)
+#define IF_IP6_NEIGHBOR_ADVERT_HDR_OFFSET	\
+					(IF_IP6_HDR_SIZE)
+
+#define GET_NEIGHBOR_ADVERT_HDR(nbuf,nhoff)	\
+					((T_NEIGHBOR_ADVERT_HDR*)((uint8_t*)((nbuf)->buf) + nhoff))
+#define GET_NEIGHBOR_ADVERT_SDU(nbuf,nhoff)	\
+					((uint8_t*)((nbuf)->buf) + nhoff + NEIGHBOR_ADVERT_HDR_SIZE)
+
+#define GET_IP6_NEIGHBOR_ADVERT_HDR_SIZE(nbuf)		\
+					(GET_IP6_HDR_SIZE(nbuf) + NEIGHBOR_ADVERT_HDR_SIZE)
+#define GET_IF_IP6_NEIGHBOR_ADVERT_HDR_SIZE(nbuf)	\
+					(GET_IP6_NEIGHBOR_ADVERT_HDR_SIZE(nbuf) + IF_HDR_SIZE)
+
+/*
+ *  近隣通知フラグ、nd_na_flags_reserved (hdr.data32) に設定する。
+ */
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
+
+#define ND_NA_FLG_OVERRIDE		ULONG_C(0x20000000)	/* 近隣キャッシュ上書き	*/
+#define ND_NA_FLG_SOLICITED		ULONG_C(0x40000000)	/* 近隣要請への応答	*/
+#define ND_NA_FLG_ROUTER		ULONG_C(0x80000000)	/* ルータ通知		*/
+
+#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
+
+#define ND_NA_FLG_OVERRIDE		ULONG_C(0x00000020)	/* 近隣キャッシュ上書き	*/
+#define ND_NA_FLG_SOLICITED		ULONG_C(0x00000040)	/* 近隣要請への応答	*/
+#define ND_NA_FLG_ROUTER		ULONG_C(0x00000080)	/* ルータ通知		*/
+
+#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+/*
+ *  ルータ通知
+ *
+ *    RFC4291: IP Version 6 Addressing Architecture
+ *    RFC4941: Privacy Extensions for Stateless Address Autoconfiguration in IPv6
+ *    RFC6106: IPv6 Router Advertisement Options for DNS Configuration
+ */
+
+typedef struct t_router_advert_hdr {
+	T_ICMP6_HDR	hdr;
+	uint32_t	reachable;		/* [us] 到達可能時間	*/
+	uint32_t	retransmit;		/* [us] 近隣要請送信間隔	*/
+	/* この後にオプションが続く */
+	} __attribute__((packed, aligned(2))) T_ROUTER_ADVERT_HDR;
+
+/* ICMP6 ヘッダのデータ部の定義 */
+
+#define nd_ra_current_hoplimit		hdr.data.data8[0]
+#define nd_ra_flags			hdr.data.data8[1]
+#define nd_ra_router_lifetime		hdr.data.data16[1]	/* [s] ルータ有効時間	*/
+
+#define ROUTER_ADVERT_HDR_SIZE		(sizeof(T_ROUTER_ADVERT_HDR))
+#define IP6_ROUTER_ADVERT_HDR_SIZE	(IP6_HDR_SIZE + ROUTER_ADVERT_HDR_SIZE)
+#define IF_IP6_ROUTER_ADVERT_HDR_SIZE	(IF_IP6_HDR_SIZE + ROUTER_ADVERT_HDR_SIZE)
+#define IF_IP6_ROUTER_ADVERT_HDR_OFFSET	(IF_IP6_HDR_SIZE)
+
+#define GET_ROUTER_ADVERT_HDR(nbuf,nhoff)	\
+					((T_ROUTER_ADVERT_HDR*)((uint8_t*)((nbuf)->buf) + nhoff))
+#define GET_ROUTER_ADVERT_SDU(nbuf,nhoff)	\
+					((uint8_t*)((nbuf)->buf) + nhoff + ROUTER_ADVERT_HDR_SIZE)
+
+#define GET_IP6_ROUTER_ADVERT_HDR_SIZE(nbuf)	\
+					(GET_IP6_HDR_SIZE(nbuf) + ROUTER_ADVERT_HDR_SIZE)
+#define GET_IF_IP6_ROUTER_ADVERT_HDR_SIZE(nbuf)	\
+					(GET_IP6_ROUTER_ADVERT_HDR_SIZE(nbuf) + IF_HDR_SIZE)
+
+/*
+ *  ルータ通知ヘッダのフラグ
+ */
+
+#define ND_RA_FLAG_MANAGED		UINT_C(0x80)
+#define ND_RA_FLAG_OTHER		UINT_C(0x40)
+#define ND_RA_FLAG_HA			UINT_C(0x20)
+
+/*
+ *  M: RA以外の方法で自動的にアドレスを設定することを許可する。
+ *  O: RA以外の方法で自動的にアドレス以外の情報を設定することをを許可する。
+ *
+ *   M   O
+ *  ON  ON	アドレスとそれ以外の情報をDHCPv6で設定する（statefull）
+ *  ON  OFF	アドレスはDHCPv6で設定するが、それ以外は手動で設定する。
+ *  OFF ON	アドレスは RA で設定するが、それ以外の情報をDHCPv6で設定する（stateless）
+ *  OFF OFF	DHCPv6 は使用しない。
+ */
+
+/*
+ *  ルータ要請
+ */
+
+typedef struct t_router_solicit_hdr {
+	T_ICMP6_HDR	hdr;
+	} __attribute__((packed, aligned(2))) T_ROUTER_SOLICIT_HDR;
+
+/* ICMP6 ヘッダのデータ部の定義 */
+
+#define nd_rs_reserved			hdr.data.data32
+
+#define ROUTER_SOLICIT_HDR_SIZE		(sizeof(T_ROUTER_SOLICIT_HDR))
+#define IP6_ROUTER_SOLICIT_HDR_SIZE	(IP6_HDR_SIZE + ROUTER_SOLICIT_HDR_SIZE)
+#define IF_IP6_ROUTER_SOLICIT_HDR_SIZE	(IF_IP6_HDR_SIZE + ROUTER_SOLICIT_HDR_SIZE)
+#define IF_IP6_ROUTER_SOLICIT_HDR_OFFSET	\
+					(IF_IP6_HDR_SIZE)
+
+#define GET_ROUTER_SOLICIT_HDR(nbuf,nhoff)	\
+					((T_ROUTER_SOLICIT_HDR*)((uint8_t*)((nbuf)->buf) + nhoff))
+#define GET_ROUTER_SOLICIT_SDU(nbuf,nhoff)	\
+					((uint8_t*)((nbuf)->buf) + nhoff + ROUTER_SOLICIT_HDR_SIZE)
+
+#define GET_IP6_ROUTER_SOLICIT_HDR_SIZE(nbuf)		\
+					(GET_IP6_HDR_SIZE(nbuf) + ROUTER_SOLICIT_HDR_SIZE)
+#define GET_IF_IP6_ROUTER_SOLICIT_HDR_SIZE(nbuf)	\
+					(GET_IP6_ROUTER_SOLICIT_HDR_SIZE(nbuf) + IF_HDR_SIZE)
+
+/*
+ *  近隣探索オプション
+ */
+
+/* 近隣探索ヘッダ */
+
+typedef struct t_neighbor_hdr {
+	T_ICMP6_HDR	hdr;
+	T_IN6_ADDR	target;
+	} __attribute__((packed, aligned(2))) T_NEIGHBOR_HDR;
+
+/* 近隣探索オプションヘッダ */
+
+typedef struct t_nd_opt_hdr {
+	uint8_t		type;			/* オプションタイプ			*/
+	uint8_t		len;			/* オプション長、単位は 8 バイト	*/
+	} __attribute__((packed, aligned(2))) T_ND_OPT_HDR;
+
+#define ND_OPT_HDR_SIZE			(sizeof(T_ND_OPT_HDR))
+
+#define ND_OPT_SOURCE_LINKADDR		UINT_C(1)	/* 送信先ネットワークインタフェースのアドレス	*/
+#define ND_OPT_TARGET_LINKADDR		UINT_C(2)	/* 対象ネットワークインタフェースのアドレス	*/
+#define ND_OPT_PREFIX_INFORMATION	UINT_C(3)	/* プレフィックス情報				*/
+#define ND_OPT_REDIRECTED_HEADER	UINT_C(4)	/* リダイレクト・ヘッダ				*/
+#define ND_OPT_MTU			UINT_C(5)	/* MTU						*/
+
+#define ND_OPT_PREFIX_INFO_COUNT	UINT_C(6)	/* プレフィックス情報の個数			*/
+#define ND_OPT_OFF_ARRAY_SIZE		UINT_C(7)	/* ND オプションのオフセットを記録する配列サイズ*/
+
+#define ND_OPT_OFF_ARRAY_IX(t)		((t)-1)		/* オフセット配列のインデックス			*/
+
+/* プレフィックスオプション */
+
+typedef struct t_nd_opt_prefix_info {
+	uint8_t		type;		/* 近隣探索オプションタイプ = 3	*/
+	uint8_t		len;		/* オプション長 = 8×4=32	*/
+	uint8_t		prefix_len;	/* プレフィックス長		*/
+	uint8_t		flags;		/* フラグ			*/
+	uint32_t	valid;		/* [s] 有効時間			*/
+	uint32_t	preferred;	/* [s] 推奨有効時間		*/
+	uint32_t	reserved;
+	T_IN6_ADDR	prefix;		/* プレフィックス		*/
+	} __attribute__((packed, aligned(2))) T_ND_OPT_PREFIX_INFO;
+
+#define ND_OPT_PI_FLAG_ONLINK	UINT_C(0x80)		/* オンリンクプレフィックス	*/
+#define ND_OPT_PI_FLAG_AUTO	UINT_C(0x40)		/* ステートレス・アドレス自動設定*/
+
+/* MTU オプションヘッダ */
+
+typedef struct t_nd_opt_mtu_hdr {
+	uint8_t		type;		/* オプションタイプ		*/
+	uint8_t		len;		/* オプション長、単位は 8 バイト*/
+	uint16_t	reserved;
+	uint32_t	mtu;		/* MTU				*/
+	} __attribute__((packed, aligned(2))) T_ND_OPT_MTU_HDR;
+
+/*
+ *  向け直し
+ */
+
+typedef struct t_nd_redirect_hdr {
+	T_ICMP6_HDR	hdr;
+	T_IN6_ADDR	target;		/* ルータのアドレス		*/
+	T_IN6_ADDR	dst;		/* 向け直しの終点アドレス		*/
+	/* この後にオプションが続く */
+	} __attribute__((packed, aligned(2))) T_ND_REDIRECT_HDR;
+
+#define ND_REDIRECT_HDR_SIZE		(sizeof(T_ND_REDIRECT_HDR))
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+typedef struct t_icmp6_ifstat {
+	uint32_t	ipv6IfIcmpInMsgs;
+	uint32_t	ipv6IfIcmpInErrors;
+	uint32_t	ipv6IfIcmpInDestUnreachs;
+/*	uint32_t	ipv6IfIcmpInAdminProhibs;*/
+	uint32_t	ipv6IfIcmpInTimeExcds;
+	uint32_t	ipv6IfIcmpInParmProblems;
+	uint32_t	ipv6IfIcmpInPktTooBigs;
+	uint32_t	ipv6IfIcmpInEchos;
+	uint32_t	ipv6IfIcmpInEchoReplies;
+/*	uint32_t	ipv6IfIcmpInRouterSolicits;*/
+	uint32_t	ipv6IfIcmpInRouterAdvertisements;
+	uint32_t	ipv6IfIcmpInNeighborSolicits;
+	uint32_t	ipv6IfIcmpInNeighborAdvertisements;
+	uint32_t	ipv6IfIcmpInRedirects;
+/*	uint32_t	ipv6IfIcmpInGroupMembQueries;*/
+/*	uint32_t	ipv6IfIcmpInGroupMembResponses;*/
+/*	uint32_t	ipv6IfIcmpInGroupMembReductions;*/
+	uint32_t	ipv6IfIcmpOutMsgs;
+	uint32_t	ipv6IfIcmpOutErrors;
+	uint32_t	ipv6IfIcmpOutDestUnreachs;
+/*	uint32_t	ipv6IfIcmpOutAdminProhibs;*/
+/*	uint32_t	ipv6IfIcmpOutTimeExcds;*/
+	uint32_t	ipv6IfIcmpOutParmProblems;
+	uint32_t	ipv6IfIcmpOutPktTooBigs;
+	uint32_t	ipv6IfIcmpOutEchos;
+	uint32_t	ipv6IfIcmpOutEchoReplies;
+	uint32_t	ipv6IfIcmpOutRouterSolicits;
+/*	uint32_t	ipv6IfIcmpOutRouterAdvertisements;*/
+	uint32_t	ipv6IfIcmpOutNeighborSolicits;
+	uint32_t	ipv6IfIcmpOutNeighborAdvertisements;
+/*	uint32_t	ipv6IfIcmpOutRedirects;*/
+/*	uint32_t	ipv6IfIcmpOutGroupMembQueries;*/
+/*	uint32_t	ipv6IfIcmpOutGroupMembResponses;*/
+/*	uint32_t	ipv6IfIcmpOutGroupMembReductions;*/
+} T_ICMP6_IFSTAT;
+
+extern T_ICMP6_IFSTAT icmp6_ifstat;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+/*
+ *  関数
+ */
+
+extern uint_t icmp6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+extern void icmp6_error (T_NET_BUF *input, uint8_t type, uint8_t code, uint32_t param);
+
+#ifdef ICMP_CFG_CALLBACK_ECHO_REPLY
+
+extern void icmp6_echo_reply (T_NET_BUF *input, uint_t ihoff);
+
+#endif	/* of #ifdef ICMP_CFG_CALLBACK_ECHO_REPLY */
+
+#endif	/* of #ifndef _IP_ICMP6_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/icmp_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/icmp_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/icmp_var.h	(revision 398)
@@ -0,0 +1,112 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)icmp_var.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/icmp_var.h,v 1.15.2.2 2001/12/07 09:23:11 ru Exp $
+ */
+
+#ifndef _ICMP_VAR_H_
+#define _ICMP_VAR_H_
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+typedef struct t_icmp_stats {
+/*	uint32_t	icmpInMsgs;*/
+	uint32_t	icmpInErrors;
+	uint32_t	icmpInDestUnreachs;
+/*	uint32_t	icmpInTimeExcds;*/
+/*	uint32_t	icmpInParmProbs;*/
+/*	uint32_t	icmpInSrcQuenchs;*/
+	uint32_t	icmpInRedirects;
+	uint32_t	icmpInEchos;
+	uint32_t	icmpInEchoReps;
+/*	uint32_t	icmpInTimestamps;*/
+/*	uint32_t	icmpInTimestampReps;*/
+/*	uint32_t	icmpInAddrMasks;*/
+/*	uint32_t	icmpInAddrMaskReps;*/
+	uint32_t	icmpOutMsgs;
+	uint32_t	icmpOutErrors;
+	uint32_t	icmpOutDestUnreachs;
+/*	uint32_t	icmpOutTimeExcds;*/
+/*	uint32_t	icmpOutParmProbs;*/
+/*	uint32_t	icmpOutSrcQuenchs;*/
+/*	uint32_t	icmpOutRedirects;*/
+	uint32_t	icmpOutEchos;
+	uint32_t	icmpOutEchoReps;
+/*	uint32_t	icmpOutTimestamps;*/
+/*	uint32_t	icmpOutTimestampReps;*/
+/*	uint32_t	icmpOutAddrMasks;*/
+/*	uint32_t	icmpOutAddrMaskReps;*/
+} T_ICMP_STATS;
+
+extern T_ICMP_STATS icmp_stats;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+#endif	/* of #ifndef _ICMP_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/if_ether.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/if_ether.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/if_ether.c	(revision 398)
@@ -0,0 +1,517 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)if_ether.c	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/if_ether.c,v 1.52.2.6 1999/10/18 11:59:31 sheldonh Exp $
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_var.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+
+#include <net/if_var.h>
+
+#if defined(_IP4_CFG) && defined(SUPPORT_ETHER)
+
+/*
+ *  ARP キャッシュエントリ
+ */
+
+static T_ARP_ENTRY arp_cache[NUM_ARP_ENTRY];
+
+/*
+ *  関数
+ */
+
+static void in_arpinput (T_IF_ADDR *ifaddr, T_NET_BUF *input);
+static void arp_timer (void *ignore);
+
+/*
+ *  in_arpinput -- TCP/IP 用 ARP の入力関数
+ */
+
+static void
+in_arpinput (T_IF_ADDR *ifaddr, T_NET_BUF *input)
+{
+	T_NET_BUF	*pending;
+	T_ETHER_HDR	*eth;
+	T_ARP_HDR	*arph;
+	T_ETHER_ARP_HDR	*et_arph;
+	T_ARP_ENTRY	*ent;
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN4_ADDR	saddr, taddr;
+
+	et_arph = GET_ETHER_ARP_HDR(input);
+
+	ntoahl(saddr, et_arph->sproto);		/* 送信元 IP アドレス	*/
+	ntoahl(taddr, et_arph->tproto);		/* 解決対象 IP アドレス	*/
+
+	/*
+	 *  以下の場合はエラー
+	 *    ・送信ホストの物理アドレスが自分
+	 *    ・送信ホストの物理アドレスがブロードキャスト
+	 */
+	if (memcmp(et_arph->shost, ifaddr->lladdr,        ETHER_ADDR_LEN) == 0 ||
+	    memcmp(et_arph->shost, ether_broad_cast_addr, ETHER_ADDR_LEN) == 0)
+		goto err_ret;
+
+	/*
+	 *  送信ホストの IP アドレスが自分の場合は、重複しているので
+	 *  相手にも知らせる。
+	 *  ただし、自分と相手のアドレスが未定義（IPV4_ADDRANY）の時は何もしない。
+	 */
+	if ((saddr == ifp->in4_ifaddr.addr) && (saddr != IPV4_ADDRANY)) {
+
+#ifdef ARP_CFG_CALLBACK_DUPLICATED
+
+		if (arp_callback_duplicated(et_arph->shost)) {
+			syslog(LOG_ERROR, "[ARP] IP address duplicated: %s",
+			                  ip2str(NULL, &ifp->in4_ifaddr.addr),
+			                  mac2str(NULL, et_arph->shost));
+			taddr = saddr;
+			goto reply;
+			}
+		else
+			goto buf_rel;
+
+#else	/* of #ifdef ARP_CFG_CALLBACK_DUPLICATED */
+
+		syslog(LOG_ERROR, "[ARP] IP address duplicated: %s",
+			          ip2str(NULL, &ifp->in4_ifaddr.addr),
+			          mac2str(NULL, et_arph->shost));
+		taddr = saddr;
+		goto reply;
+
+#endif	/* of #ifdef ARP_CFG_CALLBACK_DUPLICATED */
+
+		}
+
+	/*
+	 *  以下の場合は何もしない。
+	 *    ・解決対象 IP アドレスが自分ではない、注: 元の FreeBSD の
+	 *      実装では、ARP PROXY 等のため、自分以外の IP アドレスの
+	 *      解決も行っているが、本実装では、自分以外の IP
+	 *      アドレスの解決は行わない。
+	 */
+	if (taddr != ifp->in4_ifaddr.addr)
+		goto buf_rel;
+
+	/*
+	 *  送信元 IP アドレスが ARP キャッシュにあるか調べる。
+	 *  キャッシュになければ、新たにエントリを登録する。
+	 */
+	syscall(wai_sem(SEM_ARP_CACHE_LOCK));
+	ent = arp_lookup(saddr, true);
+
+	memcpy(ent->mac_addr, et_arph->shost, ETHER_ADDR_LEN);
+	ent->expire = ARP_CACHE_KEEP;
+
+	/*
+	 *  送信がペンデングされているフレームがあれば送信する。
+	 */
+	if (ent->hold) {
+
+		/* フレームの Ethernet ヘッダを設定する。*/
+		memcpy(GET_ETHER_HDR(ent->hold)->dhost, ent->mac_addr, ETHER_ADDR_LEN);
+
+		pending = ent->hold;
+		ent->hold = NULL;
+		syscall(sig_sem(SEM_ARP_CACHE_LOCK));
+
+		/* ペンディングされているフレームを送信する。*/
+		IF_RAW_OUTPUT(pending, TMO_FEVR);
+
+		}
+	else
+		syscall(sig_sem(SEM_ARP_CACHE_LOCK));
+
+reply:
+
+	arph = GET_ARP_HDR(input);
+
+	/* アドレス解決要求でなければ終了 */
+	if (ntohs(arph->opcode) != ARPOP_REQUEST)
+		goto buf_rel;
+
+	/* Ethernet ARP ヘッダを設定する。*/
+	memcpy(et_arph->thost, et_arph->shost, ETHER_ADDR_LEN);
+	memcpy(et_arph->shost, ifaddr->lladdr, ETHER_ADDR_LEN);
+	memcpy(et_arph->tproto, (uint8_t*)&et_arph->sproto, sizeof(T_IN_ADDR));
+	ahtonl(et_arph->sproto, taddr);
+
+	/* Ethernet ARP ヘッダを設定する。*/
+	arph->opcode = htons(ARPOP_REPLY);
+
+	/* Ethernet ヘッダを設定する。*/
+	eth = GET_ETHER_HDR(input);
+	memcpy(eth->dhost, eth->shost,     ETHER_ADDR_LEN);
+	memcpy(eth->shost, ifaddr->lladdr, ETHER_ADDR_LEN);
+
+	/* ARP 応答を送信する。*/
+	IF_RAW_OUTPUT(input, TMO_FEVR);
+	return;
+
+err_ret:
+	NET_COUNT_ARP(net_count_arp.in_err_packets, 1);
+buf_rel:
+	syscall(rel_net_buf(input));
+	}
+
+/*
+ *  arp_timer -- ARP キャッシュの更新
+ */
+
+static void
+arp_timer (void *ignore)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_ARP_CACHE_LOCK));
+
+	for (ix = NUM_ARP_ENTRY; ix -- > 0; ) {
+		if (arp_cache[ix].expire) {
+			arp_cache[ix].expire -= ARP_TIMER_TMO;
+			if (arp_cache[ix].expire == 0) {
+				/* 送信がペンデングされているフレームがあれば捨てる。*/
+				if (arp_cache[ix].hold) {
+					NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_ERR_PACKETS], 1);
+					syscall(rel_net_buf(arp_cache[ix].hold));
+					}
+				memset(&arp_cache[ix], 0, sizeof(T_ARP_ENTRY));
+				}
+			}
+		}
+
+	syscall(sig_sem(SEM_ARP_CACHE_LOCK));
+	timeout(arp_timer, NULL, ARP_TIMER_TMO);
+	}
+
+/*
+ *  arp_lookup -- ARP キャッシュの探索と登録
+ *
+ *    注意: SEM_ARP_CACHE_LOCK を獲得した状態で呼出すこと
+ */
+
+T_ARP_ENTRY *
+arp_lookup (T_IN4_ADDR addr, bool_t create)
+{
+	int_t		ix, six;
+	uint16_t	min;
+
+	for (ix = NUM_ARP_ENTRY; ix -- > 0; ) {
+		if (arp_cache[ix].expire && arp_cache[ix].ip_addr == addr)
+			return &arp_cache[ix];
+		}
+
+	/* create が真なら、新たなエントリを登録する。*/
+	if (create) {
+
+		/* まず、空きがあれば、その空きを利用する。*/
+		for (ix = NUM_ARP_ENTRY; ix -- > 0; ) {
+			if (arp_cache[ix].expire == 0) {
+				arp_cache[ix].ip_addr = addr;
+				return &arp_cache[ix];
+				}
+			}
+
+		/*
+		 *  空きがなければ、タイムアウトまで時間が最短の
+		 *  エントリーを破棄して利用する。
+		 */
+		syslog(LOG_NOTICE, "[ARP] cache busy, size=%d", NUM_ARP_ENTRY);
+		min = 0xffff;
+		for (six = ix = NUM_ARP_ENTRY; ix -- > 0; )
+			if (arp_cache[ix].expire < min) {
+				six = ix;
+				min = arp_cache[ix].expire;
+				}
+		arp_cache[six].expire  = 0;
+		arp_cache[six].ip_addr = addr;
+		return &arp_cache[six];
+		}
+	else
+		return NULL;
+	}
+
+/*
+ *  arp_request -- MAC アドレス解決要求
+ */
+
+ER
+arp_request (T_IF_ADDR *ifaddr, T_IN4_ADDR dst)
+{
+	ER		error;
+	T_IN4_ADDR	src;
+	T_ETHER_HDR	*eth;
+	T_ARP_HDR	*arph;
+	T_ETHER_ARP_HDR	*et_arph;
+	T_NET_BUF	*arp_req;
+
+	NET_COUNT_ARP(net_count_arp.out_octets , IF_ARP_ETHER_HDR_SIZE - IF_HDR_SIZE);
+	NET_COUNT_ARP(net_count_arp.out_packets, 1);
+
+	if ((error = tget_net_buf(&arp_req, IF_ARP_ETHER_HDR_SIZE, TMO_ARP_GET_NET_BUF)) == E_OK) {
+
+		/* イーサネットヘッダを設定する。*/
+		eth     = GET_ETHER_HDR(arp_req);
+		memcpy(eth->dhost, ether_broad_cast_addr, ETHER_ADDR_LEN);
+		memcpy(eth->shost, ifaddr->lladdr,        ETHER_ADDR_LEN);
+		eth->type = htons(ETHER_TYPE_ARP);
+
+		/* ARP ヘッダを設定する。*/
+		arph    = GET_ARP_HDR(arp_req);
+		arph->hrd_addr  = htons(ARPHRD_ETHER);
+		arph->proto     = htons(ETHER_TYPE_IP);
+		arph->hdr_len   = sizeof(et_arph->shost);
+		arph->proto_len = sizeof(et_arph->sproto);
+		arph->opcode    = htons(ARPOP_REQUEST);
+
+		/* イーサネット ARP ヘッダを設定する。*/
+		et_arph = GET_ETHER_ARP_HDR(arp_req);
+		src     = IF_GET_IFNET()->in4_ifaddr.addr;
+		memcpy(et_arph->shost, ifaddr->lladdr, ETHER_ADDR_LEN);
+		memset(et_arph->thost, 0,              ETHER_ADDR_LEN);
+		ahtonl(et_arph->sproto, src);
+		ahtonl(et_arph->tproto, dst);
+
+		/* 送信する。*/
+		error = IF_RAW_OUTPUT(arp_req, TMO_ARP_OUTPUT);
+		}
+	if (error != E_OK)
+		NET_COUNT_ARP(net_count_arp.out_err_packets, 1);
+	return error;
+	}
+
+/*
+ *  arp_get_cache -- ARP キャッシュを獲得する。
+ */
+
+const T_ARP_ENTRY *
+arp_get_cache (void)
+{
+	return arp_cache;
+	}
+
+/*
+ *  arp_input -- ARP の入力関数
+ */
+
+void
+arp_input (T_IF_ADDR *ifaddr, T_NET_BUF *input)
+{
+	T_ARP_HDR	*arph;
+
+	NET_COUNT_ARP(net_count_arp.in_octets , input->len - IF_HDR_SIZE);
+	NET_COUNT_ARP(net_count_arp.in_packets, 1);
+
+	/* ARP ヘッダの長さをチェックする。*/
+	if (input->len < IF_ARP_HDR_SIZE)
+		goto buf_rel;
+
+	arph = GET_ARP_HDR(input);
+
+	/*
+	 *  物理アドレスフォーマットが Ehternet 以外
+	 *  または、プロトコルが IP 以外はエラー。
+	 */
+	if (ntohs(arph->hrd_addr) != ARPHRD_ETHER ||
+	    ntohs(arph->proto)    != ETHER_TYPE_IP)
+		goto buf_rel;
+
+	/* ARP ヘッダ + Ether ARP ヘッダの長さをチェックする。*/
+	if (input->len < IF_ARP_ETHER_HDR_SIZE)
+		goto buf_rel;
+
+	in_arpinput(ifaddr, input);
+	return;
+
+buf_rel:
+	NET_COUNT_ARP(net_count_arp.in_err_packets, 1);
+	syscall(rel_net_buf(input));
+	}
+
+/*
+ *  arp_resolve -- MAC アドレス解決
+ *
+ *    アドレス解決ができれば、戻り値は true を返し、できなければ
+ *    送信をペンディングして、戻り値は false を返す。
+ */
+
+bool_t
+arp_resolve (T_IF_ADDR *ifaddr, T_NET_BUF *output, T_IN4_ADDR gw)
+{
+	T_ARP_ENTRY	*ent;
+	T_ETHER_HDR	*eth;
+	T_IFNET		*ifp = IF_GET_IFNET();
+
+	eth = GET_ETHER_HDR(output);
+
+	/*
+	 *  次の場合は、イーサネットのブロードキャストアドレスを返す。
+	 *
+	 *    ・全ビットが 1
+	 *    ・ホスト部の全ビットが 1 で、ネットワーク部がローカルアドレス
+	 */
+	if (gw == IPV4_ADDR_BROADCAST ||
+	    gw == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask)) {
+		memcpy(eth->dhost, ether_broad_cast_addr, ETHER_ADDR_LEN);
+		return true;
+		}
+
+	/* 送信先 GW の IP アドレスが ARP キャッシュにあるか調べる。*/
+	syscall(wai_sem(SEM_ARP_CACHE_LOCK));
+	ent = arp_lookup(gw, true);
+	if (ent->expire) {
+		memcpy(eth->dhost, ent->mac_addr, ETHER_ADDR_LEN);
+		syscall(sig_sem(SEM_ARP_CACHE_LOCK));
+		return true;
+		}
+	else {
+	 	/* 送信がペンデングされているフレームがあれば捨てる。*/
+		if (ent->hold) {
+			NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_ERR_PACKETS], 1);
+			syscall(rel_net_buf(ent->hold));
+			}
+
+		/*
+		 *  送信をペンディングする。
+		 *  IF でネットワークバッファを開放しないフラグが設定されているときは、
+		 *  送信をペンディングしない。
+		 */
+		if ((output->flags & NB_FLG_NOREL_IFOUT) == 0)
+			ent->hold = output;
+		else {
+			output->flags &= (uint8_t)~NB_FLG_NOREL_IFOUT;
+			ent->hold = NULL;
+			}
+		syscall(sig_sem(SEM_ARP_CACHE_LOCK));
+
+		/* アドレス解決要求を送信する。*/
+		arp_request(ifaddr, gw);
+		return false;
+		}
+	}
+
+/*
+ *  arp_init -- ARP 初期化
+ */
+
+void
+arp_init (void)
+{
+	timeout(arp_timer, NULL, ARP_TIMER_TMO);
+	}
+
+#ifdef ETHER_CFG_MULTICAST
+/*
+ *  ether_map_ipv4_multicast -- IPv4 マルチキャストアドレスからイーサネット・マルチキャストアドレスへの変換
+ */
+
+void
+ether_map_ipv4_multicast (T_ETHER_ADDR *eaddr, T_IN4_ADDR maddr)
+{
+	eaddr->lladdr[0] = UINT_C(0x01);
+	eaddr->lladdr[1] = UINT_C(0x00);
+	eaddr->lladdr[2] = UINT_C(0x5E);
+	eaddr->lladdr[3] = (uint8_t)((maddr & 0x7F0000) >> 16);
+	eaddr->lladdr[4] = (uint8_t)((maddr & 0xFF00) >> 8);
+	eaddr->lladdr[5] = (uint8_t)(maddr & 0xFF);
+	}
+#endif	/* ETHER_CFG_MULTICAST */
+
+#endif	/* of #if defined(_IP4_CFG) && defined(SUPPORT_ETHER) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/if_ether.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/if_ether.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/if_ether.cfg	(revision 398)
@@ -0,0 +1,44 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  Ethernet ARP コンフィギュレーションファイル
+ */
+
+#if defined(_IP4_CFG) && defined(SUPPORT_ETHER)
+
+/* ARP キャッシュ更新用セマフォ */
+
+CRE_SEM(SEM_ARP_CACHE_LOCK, { TA_TPRI, 1, 1 });
+
+#endif	/* of #if defined(_IP4_CFG) && defined(SUPPORT_ETHER) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/if_ether.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/if_ether.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/if_ether.h	(revision 398)
@@ -0,0 +1,131 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)if_ether.h	8.3 (Berkeley) 5/2/95
+ * $FreeBSD: src/sys/netinet/if_ether.h,v 1.21.2.1 1999/08/29 16:29:31 peter Exp $
+ */
+
+#ifndef _IF_ETHER_H_
+#define _IF_ETHER_H_
+
+#ifdef SUPPORT_ETHER
+
+/*
+ *  Ethernet Address Resolution Protocol.
+ *
+ *  RFC 826 参照
+ */
+
+typedef struct t_ether_arp_hdr {
+	uint8_t		shost[ETHER_ADDR_LEN];	/* 送信ホストの物理アドレス	*/
+	uint8_t		sproto[IPV4_ADDR_LEN];	/* 送信ホストの IP アドレス	*/
+	uint8_t		thost[ETHER_ADDR_LEN];	/* 解決対象物理アドレス		*/
+	uint8_t		tproto[IPV4_ADDR_LEN];	/* 解決対象 IP アドレス		*/
+	} __attribute__((packed, aligned(2)))T_ETHER_ARP_HDR;
+
+#define ETHER_ARP_HDR_SIZE		(sizeof(T_ETHER_ARP_HDR))
+#define IF_ARP_ETHER_HDR_SIZE		(IF_HDR_SIZE + ARP_HDR_SIZE + ETHER_ARP_HDR_SIZE)
+
+#define GET_ETHER_ARP_HDR(nbuf)		((T_ETHER_ARP_HDR*)((nbuf)->buf + GET_IF_ARP_HDR_SIZE(nbuf)))
+
+/*
+ *  ARP キャッシュエントリ
+ */
+
+typedef struct arp_entry {
+	T_NET_BUF	*hold;		/* ARP の解決待ち出力フレーム	*/
+	T_IN4_ADDR	ip_addr;	/* IP アドレス			*/
+	uint16_t	expire;		/* 破棄までの時間、0 なら未使用	*/
+	uint8_t		mac_addr[ETHER_ADDR_LEN];	/* MAC アドレス	*/
+	} __attribute__((packed, aligned(2)))T_ARP_ENTRY;
+
+/*
+ *  関数
+ */
+
+extern T_ARP_ENTRY *arp_lookup (T_IN4_ADDR addr, bool_t create);
+extern ER arp_request (T_IF_ADDR *ifaddr, T_IN4_ADDR dst);
+extern void arp_input (T_IF_ADDR *ifaddr, T_NET_BUF *input);
+extern bool_t arp_resolve (T_IF_ADDR *ifaddr, T_NET_BUF *output, T_IN4_ADDR gw);
+extern void arp_init (void);
+extern const T_ARP_ENTRY *arp_get_cache (void);
+
+#ifdef ETHER_CFG_MULTICAST
+extern void ether_map_ipv4_multicast (T_ETHER_ADDR *eaddr, T_IN4_ADDR maddr);
+#endif /* ETHER_CFG_MULTICAST */
+
+/*
+ *  TINET 独自 API
+ */
+
+#ifdef ARP_CFG_CALLBACK_DUPLICATED
+
+extern bool_t arp_callback_duplicated(uint8_t *shost);
+
+#endif	/* of #ifdef ARP_CFG_CALLBACK_DUPLICATED */
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#endif	/* of #ifndef _IF_ETHER_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in.h	(revision 398)
@@ -0,0 +1,178 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)in.h	8.3 (Berkeley) 1/3/94
+ * $FreeBSD: src/sys/netinet/in.h,v 1.38.2.3 1999/08/29 16:29:34 peter Exp $
+ */
+ 
+#ifndef _IN_H_
+#define _IN_H_
+
+#include <tinet_kernel_defs.h>
+
+#include <netinet/in4.h>
+#include <netinet6/in6.h>
+
+/*
+ *  TINET のバージョン情報
+ */
+
+#define TINET_PRVER		UINT_C(0x1070)	/* TINET のバージョン番号 */
+
+/*
+ *  インターネットシステムの定義、RFC790 参照
+ */
+
+/*
+ *  プロトコル (RFC1700)
+ */
+
+#define IPPROTO_IP		UINT_C(0)	/* IP のダミー				*/
+#define IPPROTO_HOPOPTS		UINT_C(0)	/* IPv6 中継点 (Hop-by-Hop) オプション	*/
+#define IPPROTO_ICMP		UINT_C(1)	/* ICMP					*/
+#define IPPROTO_IGMP		UINT_C(2)	/* IGMP					*/
+#define IPPROTO_TCP		UINT_C(6)	/* TCP					*/
+#define IPPROTO_UDP		UINT_C(17)	/* UDP					*/
+#define IPPROTO_IPV6		UINT_C(41)	/* IPv6					*/
+#define IPPROTO_ROUTING		UINT_C(43)	/* 経路制御オプション			*/
+#define IPPROTO_FRAGMENT	UINT_C(44)	/* 断片化オプション			*/
+#define IPPROTO_RSVP		UINT_C(46)	/* RSVP					*/
+#define IPPROTO_ESP		UINT_C(50)	/* IPv6 暗号化オプション		*/
+#define IPPROTO_AH		UINT_C(51)	/* IPv6 認証オプション			*/
+#define IPPROTO_ICMPV6		UINT_C(58)	/* ICMPv6				*/
+#define IPPROTO_NONE		UINT_C(59)	/* IPv6 次ヘッダ無し			*/
+#define IPPROTO_DSTOPTS		UINT_C(60)	/* IPv6 終点オプション			*/
+#define IPPROTO_IPCOMP		UINT_C(108)	/* ペイロード圧縮			*/
+#define IPPROTO_DONE		UINT_C(257)	/* IPv6 で上位プロトコル入力終了	*/
+
+/*
+ *  ポートの長さ
+ */
+
+#define PORT_NUM_LEN		2
+
+/*
+ *  ポート番号の定義
+ */
+
+#define TCP_PORTANY			UINT_C(0x0000)	/* ITRON TCP/IP 標準	*/
+#define UDP_PORTANY			UINT_C(0x0000)	/* ITRON TCP/IP 標準	*/
+
+#define TCP_PORT_LAST_WELL_KNOWN	UINT_C(1023)	/* Well Known 終了番号	*/
+#define TCP_PORT_FIRST_AUTO		UINT_C(1024)	/* 自動割り当て開始番号	*/
+#define TCP_PORT_LAST_AUTO		UINT_C(4999)	/* 自動割り当て終了番号	*/
+
+#define UDP_PORT_LAST_WELL_KNOWN	UINT_C(1023)	/* Well Known 終了番号	*/
+#define UDP_PORT_FIRST_AUTO		UINT_C(1024)	/* 自動割り当て開始番号	*/
+#define UDP_PORT_LAST_AUTO		UINT_C(4999)	/* 自動割り当て終了番号	*/
+
+/*
+ *  API IPプロトコルの指定
+ */
+
+#define API_PROTO_IPVn			'n'
+#define API_PROTO_IPV6			'6'
+#define API_PROTO_IPV4			'4'
+
+/*
+ *  動的生成用 TCP/IPv6 通信端点
+ */
+
+#define T_TCP6_CCEP			T_TCP_CCEP
+
+/*
+ *  バイトオーダ関数の定義
+ *
+ *    tinet/net/net.h でもバイトオーダの定義を行っているが、
+ *    tinet/net/net.h をインクルードしない
+ *    アプリケーションプログラム用に
+ *    ターゲット依存しないバイトオーダ関数を定義する。
+ */
+
+#if defined(_NET_CFG_BYTE_ORDER)
+
+/*  tinet/net/net.h をインクルードしている。*/
+
+#else	/* of #if defined(_NET_CFG_BYTE_ORDER) */
+
+extern uint16_t ntohs (uint16_t net);
+extern uint16_t htons (uint16_t host);
+extern uint32_t ntohl (uint32_t net);
+extern uint32_t htonl (uint32_t host);
+
+#define NTOHS(n)	(n=ntohs(n))
+#define HTONS(h)	(h=htons(h))
+#define NTOHL(n)	(n=ntohl(n))
+#define HTONL(h)	(h=htonl(h))
+
+#endif	/* of #if defined(_NET_CFG_BYTE_ORDER) */
+
+/*
+ *  TINET 独自 API
+ */
+
+extern const char *in_strtfn (FN fncd);
+
+#endif	/* of #ifndef _IN_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in4.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in4.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in4.h	(revision 398)
@@ -0,0 +1,204 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)in.h	8.3 (Berkeley) 1/3/94
+ * $FreeBSD: src/sys/netinet/in.h,v 1.38.2.3 1999/08/29 16:29:34 peter Exp $
+ */
+ 
+#ifndef _IN4_H_
+#define _IN4_H_
+
+/*
+ *  IPv4 アドレス
+ */
+
+/* 前方参照 */
+
+#ifndef T_IN4_ADDR_DEFINED
+
+typedef uint32_t T_IN4_ADDR;
+
+#define T_IN4_ADDR_DEFINED
+
+#endif	/* of #ifndef T_IN4_ADDR_DEFINED */
+
+/*
+ *  ITRON TCP/IPv4 アドレス/ポート番号の定義
+ */
+
+typedef struct t_ipv4ep {
+	uint32_t	ipaddr;		/* IPv4 アドレス	*/
+	uint16_t	portno;		/* ポート番号		*/
+	} T_IPV4EP;
+
+#define T_IPV4EP_DEFINED
+
+/*
+ *  アドレスの長さ
+ */
+
+#define IPV4_ADDR_LEN		4
+
+/*
+ *  IPv4 アドレスの定義
+ */
+
+#define IPV4_ADDRANY		ULONG_C(0x00000000)	/* ITRON TCP/IP 標準	*/
+#define IPV4_ADDRBROADCAST	ULONG_C(0xffffffff)
+
+#define IPV4_ADDR_LOOPBACK	ULONG_C(0x7f000001)
+#define IPV4_ADDR_LOOPBACK_MASK	IPV4_CLASS_A_MASK
+#define IPV4_ADDR_BROADCAST	ULONG_C(0xffffffff)
+
+#define IPV4_CLASS_A(i)		(((i) & ULONG_C(0x80000000)) == 0)
+#define IPV4_CLASS_A_NET	ULONG_C(0xff000000)
+#define IPV4_CLASS_A_MASK	ULONG_C(0xff000000)
+#define IPV4_CLASS_A_HOST	ULONG_C(0x00ffffff)
+
+#define IPV4_CLASS_B(i)		(((i) & ULONG_C(0xc0000000)) == ULONG_C(0x80000000))
+#define IPV4_CLASS_B_NET	ULONG_C(0xffff0000)
+#define IPV4_CLASS_B_MASK	ULONG_C(0xffff0000)
+#define IPV4_CLASS_B_HOST	ULONG_C(0x0000ffff)
+
+#define IPV4_CLASS_C(i)		(((i) & ULONG_C(0xe0000000)) == ULONG_C(0xc0000000))
+#define IPV4_CLASS_C_NET	ULONG_C(0xffffff00)
+#define IPV4_CLASS_C_MASK	ULONG_C(0xffffff00)
+#define IPV4_CLASS_C_HOST	ULONG_C(0x000000ff)
+
+#define IPV4_CLASS_D(i)		(((i) & ULONG_C(0xf0000000)) == ULONG_C(0xe0000000))
+
+#define IN4_IS_ADDR_MULTICAST(i)	IPV4_CLASS_D(i)
+
+#define MAKE_IPV4_LOCAL_BROADCAST(i)	(IPV4_CLASS_A(i)?((i)|IPV4_CLASS_A_HOST):\
+					 IPV4_CLASS_B(i)?((i)|IPV4_CLASS_B_HOST):\
+					 IPV4_CLASS_C(i)?((i)|IPV4_CLASS_C_HOST):\
+					 IPV4_ADDR_BROADCAST)
+
+#define MAKE_IPV4_LOCAL_MASK(i)		(IPV4_CLASS_A(i)?IPV4_CLASS_A_MASK:\
+					 IPV4_CLASS_B(i)?IPV4_CLASS_B_MASK:\
+					 IPV4_CLASS_C(i)?IPV4_CLASS_C_MASK:\
+					 IPV4_ADDRANY)
+
+#define MAKE_IPV4_ADDR(a,b,c,d)		((T_IN4_ADDR)(((uint32_t)(a)<<24)|((uint32_t)(b)<<16)|((uint32_t)(c)<<8)|(d)))
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+#define IN4_ARE_ADDR_EQUAL(dst,src)	(*(dst)==*(src))
+#define IN4_IS_ADDR_ANY(addr)		(*(addr)==IPV4_ADDRANY)
+#define IN4_IS_ADDR_BROADCAST(addr)	(*(addr)==IPV4_ADDRBROADCAST)
+#define ip2str(buf,p_ipaddr)		(ipv42str(buf,p_ipaddr))
+
+/*
+ *  動的生成用 TCP 通信端点
+ */
+
+typedef struct t_tcp_ccep {
+	/* 標準 */
+	ATR		cepatr;		/* 通信端点属性			*/
+	void		*sbuf;		/* 送信用ウィンドバッファ	*/
+	int_t		sbufsz;		/* 送信用ウィンドバッファサイズ	*/
+	void		*rbuf;		/* 受信用ウィンドバッファ	*/
+	int_t		rbufsz;		/* 受信用ウィンドバッファサイズ	*/
+	FP		callback;	/* コールバック			*/
+	/* 実装依存 */
+	} T_TCP_CCEP;
+
+/*
+ *  動的生成用 TCP 受付口
+ */
+
+typedef struct t_tcp_crep {
+	/* 標準 */
+	ATR		repatr;		/* 受付口属性		*/
+	T_IPV4EP	myaddr;		/* 自分のアドレス	*/
+	/* 実装依存 */
+	} T_TCP_CREP;
+
+/*
+ *  動的生成用 UDP 通信端点
+ */
+
+typedef struct t_udp_ccep {
+	/* 標準 */
+	ATR		cepatr;		/* UDP 通信端点属性		*/
+	T_IPV4EP	myaddr;		/* 自分のアドレス		*/
+	FP		callback;	/* コールバック関数		*/
+	/* 実装依存 */
+	} T_UDP_CCEP;
+
+/*
+ *  TINET 独自 API
+ */
+
+extern char *ipv42str (char *buf, const T_IN4_ADDR *p_ipaddr);
+extern uint_t in4_get_maxnum_ifaddr (void);
+extern const T_IN4_ADDR *in4_get_ifaddr (int_t index);
+extern ER in4_add_ifaddr (T_IN4_ADDR addr, T_IN4_ADDR mask);
+extern ER in4_add_route (int_t index, T_IN4_ADDR target,
+                                      T_IN4_ADDR mask, T_IN4_ADDR gateway);
+
+#endif	/* of #ifndef _IN4_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in4_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in4_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in4_subr.c	(revision 398)
@@ -0,0 +1,525 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+//#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <net/if_var.h>
+
+#ifdef SUPPORT_IGMP
+#include <netinet/udp_var.h>
+#include <netinet/ip_igmp.h>
+#endif /* of #ifdef SUPPORT_IGMP */
+
+#if defined(_IP4_CFG)
+
+#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
+
+/*
+ *  in_rtinit -- ルーティング表を初期化する。
+ */
+
+void
+in_rtinit (void)
+{
+	int_t ix;
+
+	for (ix = 0; ix < NUM_IN4_STATIC_ROUTE_ENTRY; ix ++)
+		routing4_tbl[ix].flags = IN_RTF_DEFINED;
+
+	for ( ; ix < NUM_IN4_ROUTE_ENTRY; ix ++)
+		routing4_tbl[ix].flags = 0;
+	}
+
+/*
+ *  in_rtnewentry -- 新しいエントリを獲得する。
+ */
+
+T_IN4_RTENTRY *
+in_rtnewentry (uint8_t flags, uint32_t tmo)
+{
+	SYSTIM		now;
+	T_IN4_RTENTRY	*rt, *frt = NULL;
+	int_t		ix;
+
+	/* 空きエントリを探す。*/
+	for (ix = NUM_IN4_STATIC_ROUTE_ENTRY; ix < NUM_IN4_ROUTE_ENTRY; ix ++) {
+		rt = &routing4_tbl[ix];
+		if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) == 0) {
+			frt = rt;
+			break;
+			}
+		}
+
+	/* expire の単位は [s]。*/
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	if (frt == NULL) {
+		/* 空きがなければ、有効時間がもっとも短いエントリを空きにする。*/
+		T_IN4_RTENTRY	*srt = NULL;
+		int_t		diff, sdiff = INT_MAX;
+
+		syscall(wai_sem(SEM_IN4_ROUTING_TBL));
+		for (ix = NUM_IN4_STATIC_ROUTE_ENTRY; ix < NUM_IN4_ROUTE_ENTRY; ix ++) {
+			rt = &routing4_tbl[ix];
+			diff = (int_t)(rt->expire - now);
+			if (diff <= 0) {	/* rt->expire <= now */
+				/* 既に、有効時間が過ぎている。*/
+				frt = rt;
+				break;
+				}
+			else if (diff < sdiff) {
+				srt = rt;
+				sdiff = diff;
+				}
+			}
+		if (frt == NULL)
+			frt = srt;
+		frt->flags = 0;
+		syscall(sig_sem(SEM_IN4_ROUTING_TBL));
+		}
+
+	frt->flags  = (uint8_t)(flags | IN_RTF_DEFINED);
+	frt->expire = now + tmo / SYSTIM_HZ;
+	return frt;
+	}
+
+/*
+ *  in_rttimer -- ルーティング表の管理タイマー
+ */
+
+void
+in_rttimer (void)
+{
+	SYSTIM	now;
+	int_t	ix;
+
+	/* expire の単位は [s]。*/
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	syscall(wai_sem(SEM_IN4_ROUTING_TBL));
+	for (ix = NUM_IN4_STATIC_ROUTE_ENTRY; ix < NUM_IN4_ROUTE_ENTRY; ix ++)
+		if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) &&
+		    (int_t)(routing4_tbl[ix].expire - now) <= 0)
+			routing4_tbl[ix].flags = 0;
+	syscall(sig_sem(SEM_IN4_ROUTING_TBL));
+	}
+
+#endif	/* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
+
+/*
+ *  in4_get_maxnum_ifaddr -- インタフェースに設定可能な最大アドレス数を返す。
+ */
+
+uint_t
+in4_get_maxnum_ifaddr (void)
+{
+	return 1;
+	}
+
+/*
+ *  in4_get_ifaddr -- インタフェースに設定されているアドレスを返す。
+ */
+
+const T_IN4_ADDR *
+in4_get_ifaddr (int_t index)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+
+	return &ifp->in4_ifaddr.addr;
+	}
+
+/*
+ *  in4_set_header -- IPv4 ヘッダを設定する。
+ */
+
+ER
+in4_set_header (T_NET_BUF *nbuf, uint_t len,
+                T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr, uint8_t proto, uint8_t ttl)
+{
+	T_IP4_HDR	*ip4h = GET_IP4_HDR(nbuf);
+	T_IFNET		*ifp = IF_GET_IFNET();
+
+	/* IP ヘッダを設定する。*/
+	ip4h->vhl	= IP4_MAKE_VHL(IPV4_VERSION, IP4_HDR_SIZE >> 2);
+	ip4h->len	= htons(IP4_HDR_SIZE + len);
+	ip4h->proto	= proto;
+	ip4h->ttl	= ttl;
+	ip4h->type	= 0;
+	ip4h->id	= ip4h->flg_off = ip4h->sum = 0;
+
+	/* IP アドレスを設定する。*/
+	ip4h->dst	= htonl(*dstaddr);
+
+	if (srcaddr == NULL || *srcaddr == IPV4_ADDRANY)
+		ip4h->src = htonl(ifp->in4_ifaddr.addr);
+	else
+		ip4h->src = htonl(*srcaddr);
+
+	return E_OK;
+	}
+
+/*
+ *  in4_get_datagram -- IPv4 データグラムを獲得し、ヘッダを設定する。
+ */
+
+ER
+in4_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
+                  T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr,
+                  uint8_t proto, uint8_t ttl, ATR nbatr, TMO tmout)
+{
+	ER	error;
+	uint_t	align;
+
+	/* データ長を 4 オクテット境界に調整する。*/
+	align = (len + 3) >> 2 << 2;
+
+	/* ネットワークバッファを獲得する。*/
+	if ((error = tget_net_buf_ex(nbuf, (uint_t)(IF_IP4_HDR_SIZE + align),
+	                                   (uint_t)(IF_IP4_HDR_SIZE + maxlen), nbatr, tmout)) != E_OK)
+		return error;
+
+	/*
+	 *  より大きなサイズのネットワークバッファを獲得する場合のみ長さを調整する。
+	 *  より小さなサイズのネットワークバッファの獲得は、送信ウィンドバッファの
+	 *  省コピー機能で使用され、実際に送信するまで、データサイズは決定できない。
+	 */
+	if ((nbatr & NBA_SEARCH_ASCENT) != 0)
+		(*nbuf)->len = (uint16_t)(IF_IP4_HDR_SIZE + len);
+
+	/* IP ヘッダを設定する。*/
+	if ((error = in4_set_header(*nbuf, len, dstaddr, srcaddr, proto, ttl)) != E_OK) {
+		syscall(rel_net_buf(*nbuf));
+		*nbuf = NULL;
+		return error;
+		}
+
+	/* 4 オクテット境界までパディングで埋める。*/
+	if (align > len)
+		memset((GET_IP4_SDU(*nbuf) + len), 0, (size_t)(align - len));
+
+	return E_OK;
+	}
+
+/*
+ *  in4_cksum -- IPv4 のトランスポート層ヘッダのチェックサムを計算する。
+ *
+ *  注意: 戻り値はネットワークバイトオーダ
+ */
+
+uint16_t
+in4_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len)
+{
+	uint32_t	sum;
+	uint_t		align;
+
+	/* 4 オクテット境界のデータ長 */
+	align = (len + 3) >> 2 << 2;
+
+	/* 4 オクテット境界までパディングで埋める。*/
+	if (align > len)
+		memset((uint8_t*)nbuf->buf + off + len, 0, (size_t)(align - len));
+
+	sum = in_cksum_sum(nbuf->buf + off, align)
+	    + in_cksum_sum(&GET_IP4_HDR(nbuf)->src, sizeof(T_IN4_ADDR) * 2)
+	    + len + proto;
+	sum = in_cksum_carry(sum);
+
+	return (uint16_t)(~htons((uint16_t)sum));
+	}
+
+/*
+ *  in_cksum -- チェックサム計算関数、IPv4、ICMPv4 用
+ *
+ *  注意: data は 4 オクテット単位でパディングすること。
+ *        data が 2 オクテット単位にアラインされていないと
+ *        例外が発生する可能性がある。
+ *        len  は 4 オクテット単位にアラインされていること。
+ *
+ *        戻り値はネットワークバイトオーダ
+ */
+
+uint16_t
+in_cksum (void *data, uint_t len /*オクテット単位*/)
+{
+	uint16_t	sum;
+
+	sum = (uint16_t)in_cksum_carry(in_cksum_sum(data, len));
+	return (uint16_t)(~htons(sum));
+	}
+
+/*
+ *  in4_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
+ *
+ *    注意: dstaddr は、
+ *          TINET-1.2 からネットワークバイトオーダ、
+ *          TINET-1.1 までは、ホストバイトオーダ
+ */
+
+bool_t
+in4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr)
+{
+	if (*myaddr == IPV4_ADDRANY)
+		return ntohl(*dstaddr) == IF_GET_IFNET()->in4_ifaddr.addr;
+	else
+		return ntohl(*dstaddr) == *myaddr;
+	}
+
+/*
+ *  inn4_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
+ *
+ *    注意: dstaddr は、
+ *          TINET-1.2 からネットワークバイトオーダ、
+ *          TINET-1.1 までは、ホストバイトオーダ
+ */
+
+bool_t
+inn4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *nbuf)
+{
+	T_IP4_HDR	*iph;
+
+	iph  = GET_IP4_HDR(nbuf);
+	if (*myaddr == IPV4_ADDRANY)
+		return ntohl(iph->dst) == IF_GET_IFNET()->in4_ifaddr.addr;
+	else
+		return ntohl(iph->dst) == *myaddr;
+	}
+
+/*
+ * in4_addrwithifp -- 宛先アドレスにふさわしい送信元アドレスを、
+ *                   ネットワークインタフェースから探索する。
+ *                   in6_addrwithifp をシミュレートするだけで、
+ *                   エラーを返すことはない。
+ */
+
+T_IN4_ADDR *
+in4_addrwithifp (T_IFNET *ifp, T_IN4_ADDR *src, T_IN4_ADDR *dst)
+{
+	*src = ifp->in4_ifaddr.addr;
+	return src;
+	}
+
+/*
+ *  in4_add_ifaddr -- インタフェースに IPv4 アドレスを設定する。
+ */
+
+ER
+in4_add_ifaddr (T_IN4_ADDR addr, T_IN4_ADDR mask)
+{
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	ifp->in4_ifaddr.addr = addr;
+	ifp->in4_ifaddr.mask = mask;
+	return E_OK;
+	}
+
+#if NUM_IN4_ROUTE_ENTRY > 0
+
+/*
+ *  in4_add_route -- 経路表にエントリを設定する。
+ */
+
+ER
+in4_add_route (int_t index, T_IN4_ADDR target, T_IN4_ADDR mask, T_IN4_ADDR gateway)
+{
+
+	if (0 <= index && index < NUM_IN4_STATIC_ROUTE_ENTRY) {
+		routing4_tbl[index].target  = target;
+		routing4_tbl[index].mask    = mask;
+		routing4_tbl[index].gateway = gateway;
+		return E_OK;
+		}
+	else
+		return E_PAR;
+	}
+
+#endif	/* of #if NUM_IN4_ROUTE_ENTRY > 0 */
+
+/*
+ *  in4_rtalloc -- ルーティング表を探索する。
+ */
+
+T_IN4_ADDR
+in4_rtalloc (T_IN4_ADDR dst)
+{
+	int_t ix;
+#ifdef ETHER_CFG_MULTICAST
+	if(IN4_IS_ADDR_MULTICAST(dst))
+		return dst;
+#endif /* of #ifdef ETHER_CFG_MULTICAST */
+	for (ix = NUM_IN4_ROUTE_ENTRY; ix --; )
+		if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) &&
+		    (dst & routing4_tbl[ix].mask) == routing4_tbl[ix].target) {
+			if (routing4_tbl[ix].gateway == 0)
+				return dst;
+			else {
+				return routing4_tbl[ix].gateway;
+				}
+			}
+	return dst;
+	}
+
+#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
+
+/*
+ *  in4_rtredirect -- ルーティング表にエントリを登録する。
+ *
+ *    注意: 引数 tmo の単位は [ms]。
+ */
+
+void
+in4_rtredirect (T_IN4_ADDR gateway, T_IN4_ADDR target, uint8_t flags, uint32_t tmo)
+{
+	T_IN4_RTENTRY	*frt;
+
+	frt = in_rtnewentry(flags, tmo);
+	frt->gateway    = gateway;
+	frt->target     = target;
+	frt->mask       = 0xffffffff;
+	}
+
+#endif	/* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
+
+/*
+ *  in4_timer -- IPv4 共通タイマー
+ *
+ *    1秒周期で起動される。
+ */
+
+static void
+in4_timer (void *ignore)
+{
+#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
+
+	in_rttimer();
+
+#endif	/* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
+
+#ifdef IP4_CFG_FRAGMENT
+
+	ip_frag_timer();
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+	timeout(in4_timer, NULL, IN_TIMER_TMO);
+	}
+
+/*
+ *  in4_init -- IPv4 共通機能を初期化する。
+ */
+
+void
+in4_init (void)
+{
+#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
+
+	in_rtinit();
+
+#endif	/* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
+
+#ifdef SUPPORT_IGMP
+	igmp_init();
+#endif /* of #ifdef SUPPORT_IGMP */
+
+	timeout(in4_timer, NULL, IN_TIMER_TMO);
+	}
+
+#endif	/* of #if defined(_IP4_CFG) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in4_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in4_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in4_var.h	(revision 398)
@@ -0,0 +1,201 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1985, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)in_var.h	8.2 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/netinet/in_var.h,v 1.29.2.1 1999/08/29 16:29:38 peter Exp $
+ */
+ 
+#ifndef _IN4_VAR_H_
+#define _IN4_VAR_H_
+
+#ifndef _MACRO_ONLY
+
+/*
+ *  インタフェースアドレス構造体
+ */
+
+typedef struct t_in4_ifaddr {
+	T_IN4_ADDR		addr;		/* IPv4 アドレス	*/
+	T_IN4_ADDR		mask;		/* サブネットマスク	*/
+	} T_IN4_IFADDR;
+
+/*
+ *  ルーティング表エントリ構造体
+ */
+
+typedef struct t_in4_rtentry {
+	T_IN4_ADDR	target;		/* 目標ネットワークアドレス			*/
+	T_IN4_ADDR	mask;		/* 目標ネットワークアドレスのサブネットマスク	*/
+	T_IN4_ADDR	gateway;	/* ゲートウェイの IP アドレス			*/
+	uint32_t	expire;		/* 有効時間が切れる時刻 [s]			*/
+	uint8_t		flags;		/* フラグ					*/
+	} T_IN4_RTENTRY;
+/*
+ *  TINET 1.1 との互換性のための定義
+ *
+ *  TINET 1.5 との互換性のために定義を無効にした。
+ */
+
+#if 0
+#ifdef NUM_ROUTE_ENTRY
+
+#define NUM_IN4_ROUTE_ENTRY		NUM_ROUTE_ENTRY
+#define NUM_IN4_STATIC_ROUTE_ENTRY	NUM_ROUTE_ENTRY
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	0
+#define T_RT_ENTRY			T_IN4_RTENTRY
+
+#endif	/* of #ifdef NUM_ROUTE_ENTRY */
+#endif
+
+/*
+ *  ルーティング表
+ */
+
+#ifdef SUPPORT_INET4
+
+extern T_IN4_RTENTRY routing4_tbl[];
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+/*
+ *  前方参照
+ */
+
+#ifndef T_NET_BUF_DEFINED
+typedef struct t_net_buf T_NET_BUF;
+#define T_NET_BUF_DEFINED
+#endif
+
+#ifndef T_IFNET_DEFINED
+typedef struct t_ifnet T_IFNET;
+#define T_IFNET_DEFINED
+#endif
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+#define IN4_COPY_TO_HOST(dst,nbuf)	(*(dst)=ntohl(GET_IP4_HDR(nbuf)->src))
+
+/*
+ *  関数
+ */
+
+extern void ip_input (T_NET_BUF *data);
+extern ER in4_set_header (T_NET_BUF *nbuf, uint_t len,
+                          T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr, uint8_t proto, uint8_t ttl);
+extern ER in4_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
+                            T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr,
+                            uint8_t proto, uint8_t ttl, ATR nbatr, TMO tmout);
+extern uint16_t in4_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len);
+extern T_IN4_ADDR in4_rtalloc (T_IN4_ADDR dst);
+extern void in4_rtredirect (T_IN4_ADDR gateway, T_IN4_ADDR target, uint8_t flags, uint32_t tmo);
+extern void in4_init (void);
+extern T_IN4_ADDR *in4_addrwithifp (T_IFNET *ifp, T_IN4_ADDR *src, T_IN4_ADDR *dst);
+extern const T_NET_BUF**ip_get_frag_queue (void);
+
+/*
+ *  in4_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
+ *
+ *    注意: dstaddr は、
+ *          TINET-1.2 からネットワークバイトオーダ、
+ *          TINET-1.1 までは、ホストバイトオーダ
+ */
+extern bool_t in4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr);
+extern bool_t inn4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *input);
+
+/*
+ *  in_cksum -- チェックサム計算関数、IPv4、ICMPv4 用
+ *
+ *  注意: data は 4 オクテット単位でパディングすること。
+ *        data が 2 オクテット単位にアラインされていないと
+ *        例外が発生する可能性がある。
+ *        len  は 4 オクテット単位にアラインされていること。
+ */
+extern uint16_t in_cksum(void *data, uint_t len /*オクテット単位*/);
+
+/*
+ *  in_cksum_sum -- チェックサムの合計計算関数
+ *
+ *  注意: data は 4 オクテット単位でパディングすること。
+ *        data が 2 オクテット単位にアラインされていないと
+ *        例外が発生する可能性がある。
+ *        len  は 4 オクテット単位にアラインされていること。
+ */
+extern uint32_t in_cksum_sum (void *data, uint_t len /*オクテット単位*/);
+
+/*
+ *  in_cksum_carry -- チェックサムの桁上げ計算関数
+ *
+ *  注意: data は 4 オクテット単位でパディングすること。
+ *        data が 2 オクテット単位にアラインされていないと
+ *        例外が発生する可能性がある。
+ *        len  は 4 オクテット単位にアラインされていること。
+ */
+extern uint32_t in_cksum_carry (uint32_t sum);
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#endif	/* of #ifndef _IN4_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_itron.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_itron.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_itron.h	(revision 398)
@@ -0,0 +1,147 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+ 
+#ifndef _IN_ITRON_H_
+#define _IN_ITRON_H_
+
+/*
+ *  API 機能・事象コード
+ */
+
+/* TCP 関係 */
+
+#define TFN_TCP_CRE_REP		(-0x201)
+#define TFN_TCP_DEL_REP		(-0x202)
+#define TFN_TCP_CRE_CEP		(-0x203)
+#define TFN_TCP_DEL_CEP		(-0x204)
+#define TFN_TCP_ACP_CEP		(-0x205)
+#define TFN_TCP_CON_CEP		(-0x206)
+#define TFN_TCP_SHT_CEP		(-0x207)
+#define TFN_TCP_CLS_CEP		(-0x208)
+#define TFN_TCP_SND_DAT		(-0x209)
+#define TFN_TCP_RCV_DAT		(-0x20a)
+#define TFN_TCP_GET_BUF		(-0x20b)
+#define TFN_TCP_SND_BUF		(-0x20c)
+#define TFN_TCP_RCV_BUF		(-0x20d)
+#define TFN_TCP_REL_BUF		(-0x20e)
+#define TFN_TCP_SND_OOB		(-0x20f)
+#define TFN_TCP_RCV_OOB		(-0x210)
+#define TFN_TCP_CAN_CEP		(-0x211)
+#define TFN_TCP_SET_OPT		(-0x212)
+#define TFN_TCP_GET_OPT		(-0x213)
+#define TFN_TCP_ALL		(0)
+
+#define TEV_TCP_RCV_OOB		(0x201)
+
+/* UDP 関係 */
+
+#define TFN_UDP_CRE_CEP		(-0x221)
+#define TFN_UDP_DEL_CEP		(-0x222)
+#define TFN_UDP_SND_DAT		(-0x223)
+#define TFN_UDP_RCV_DAT		(-0x224)
+#define TFN_UDP_CAN_CEP		(-0x225)
+#define TFN_UDP_SET_OPT		(-0x226)
+#define TFN_UDP_GET_OPT		(-0x227)
+#define TFN_UDP_ALL		(0)
+
+#define TEV_UDP_RCV_DAT		(0x221)
+
+/* 一般 */
+
+#define NADR			((void*)(-1))	/* 無効アドレス */
+#define IS_PTR_DEFINED(a)	((void*)(a)!=NADR&&(void*)(a)!=NULL)
+#define TCP_REP_NONE		UINT_C(0)
+#define TCP_CEP_NONE		UINT_C(0)
+#define UDP_CEP_NONE		UINT_C(0)
+
+/*
+ *  関数
+ */
+
+/* TCP 関係 */
+
+/* 【標準機能】 */
+
+extern ER	tcp_acp_cep (ID cepid, ID repid, T_IPV4EP *p_dstaddr, TMO tmout);
+extern ER	tcp_con_cep (ID cepid, T_IPV4EP *p_myaddr, T_IPV4EP *p_dstaddr, TMO tmout);
+extern ER	tcp_sht_cep (ID cepid);
+extern ER	tcp_cls_cep (ID cepid, TMO tmout);
+extern ER_UINT	tcp_snd_dat (ID cepid, void *data, int_t len, TMO tmout);
+extern ER_UINT	tcp_rcv_dat (ID cepid, void *data, int_t len, TMO tmout);
+extern ER_UINT	tcp_get_buf (ID cepid, void **p_buf, TMO tmout);
+extern ER	tcp_snd_buf (ID cepid, int_t len);
+extern ER_UINT	tcp_rcv_buf (ID cepid, void **p_buf, TMO tmout);
+extern ER	tcp_rel_buf (ID cepid, int_t len);
+extern ER	tcp_can_cep (ID cepid, FN fncd);
+
+extern ER	tcp6_acp_cep (ID cepid, ID repid, T_IPV6EP *p_dstaddr, TMO tmout);
+extern ER	tcp6_con_cep (ID cepid, T_IPV6EP *p_myaddr, T_IPV6EP *p_dstaddr, TMO tmout);
+
+/* 【拡張機能】 */
+
+extern ER	tcp_del_rep (ID cepid);
+extern ER	tcp_cre_cep (ID cepid, T_TCP_CCEP *pk_crep);
+extern ER	tcp_del_cep (ID cepid);
+extern ER_UINT	tcp_snd_oob (ID cepid, void *data, int_t len, TMO tmout);
+extern ER_UINT	tcp_rcv_oob (ID cepid, void *data, int_t len);
+extern ER	tcp_set_opt (ID cepid, int_t optname, void *optval, int_t optlen);
+extern ER	tcp_get_opt (ID cepid, int_t optname, void *optval, int_t optlen);
+extern ER	tcp_cre_rep (ID repid, T_TCP_CREP *pk_crep);
+
+extern ER	tcp6_cre_rep (ID repid, T_TCP6_CREP *pk_crep);
+
+/* UDP 関係 */
+
+/* 【標準機能】 */
+
+extern ER_UINT	udp_snd_dat (ID cepid, T_IPV4EP *p_dstaddr, void *data, int_t len, TMO tmout);
+extern ER_UINT	udp_rcv_dat (ID cepid, T_IPV4EP *p_dstaddr, void *data, int_t len, TMO tmout);
+extern ER	udp_can_cep (ID cepid, FN fncd);
+
+extern ER_UINT	udp6_snd_dat (ID cepid, T_IPV6EP *p_dstaddr, void *data, int_t len, TMO tmout);
+extern ER_UINT	udp6_rcv_dat (ID cepid, T_IPV6EP *p_dstaddr, void *data, int_t len, TMO tmout);
+extern ER	udp6_can_cep(ID cepid, FN fncd);
+
+/* 【拡張機能】 */
+
+extern ER	udp_del_cep (ID cepid);
+extern ER	udp_set_opt (ID cepid, int_t optname, void *optval, int_t optlen);
+extern ER	udp_get_opt (ID cepid, int_t optname, void *optval, int_t optlen);
+extern ER	udp_cre_cep (ID cepid, T_UDP_CCEP *pk_ccep);
+
+extern ER	udp6_del_cep(ID cepid);
+extern ER	udp6_set_opt(ID cepid, int_t optname, void *optval, int_t optlen);
+extern ER	udp6_get_opt(ID cepid, int_t optname, void *optval, int_t optlen);
+extern ER	udp6_cre_cep (ID cepid, T_UDP6_CCEP *pk_ccep);
+
+#endif	/* of #ifndef _IN_ITRON_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_rename.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_rename.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_rename.h	(revision 398)
@@ -0,0 +1,250 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _IN_RENAME_H_
+#define _IN_RENAME_H_
+
+/*
+ *  TCP/IP プロトコルスタック内部名のリネーム
+ */
+
+/* netinet/tcp_input.c */
+
+#define tcp_input		_tinet_tcp_input
+#define tcp_move_twcep		_tinet_tcp_move_twcep
+
+/* netinet/tcp_output.c */
+
+/* netinet/tcp_timer.c */
+
+#define	tcp_cancel_timers	_tinet_tcp_cancel_timers
+#define tcp_slow_timo		_tinet_tcp_slow_timo
+#define tcp_fast_timo		_tinet_tcp_fast_timo
+#define tcp_range_set		_tinet_tcp_range_set
+#define tcp_set_persist_timer	_tinet_tcp_set_persist_timer
+
+/* netinet/tcp_usrrq.c */
+
+#define tcp_user_closed		_tinet_tcp_user_closed
+
+/* netinet/tcp_subr.c */
+
+#define tcp_iss			_tinet_tcp_iss
+#define tcp_init		_tinet_tcp_init
+#define tcp_init_iss		_tinet_tcp_init_iss
+#define tcp_close		_tinet_tcp_close
+#define tcp_drop		_tinet_tcp_drop
+#define tcp_respond		_tinet_tcp_respond
+#define	tcp_get_segment		_tinet_tcp_get_segment
+#define tcp_rexmt_val		_tinet_tcp_rexmt_val
+#define tcp_init_cep		_tinet_tcp_init_cep
+#define tcp_notify		_tinet_tcp_notify
+#define tcp_alloc_auto_port	_tinet_tcp_alloc_auto_port
+#define tcp_alloc_port		_tinet_tcp_alloc_port
+#define tcp_free_reassq		_tinet_tcp_free_reassq
+#define tcp_move_ra2rw		_tinet_tcp_move_ra2rw
+#define tcp_wait_rwbuf		_tinet_tcp_wait_rwbuf
+#define tcp_write_raque		_tinet_tcp_write_raque
+#define tcp_lock_cep		_tinet_tcp_lock_cep
+#define tcp_can_send_more	_tinet_tcp_can_send_more
+#define tcp_can_recv_more	_tinet_tcp_can_recv_more
+#define tcp_output_trace	_tinet_tcp_output_trace
+#define tcp_input_trace		_tinet_tcp_input_trace
+#define tcp_find_cep		_tinet_tcp_find_cep
+#define tcp_find_twcep		_tinet_tcp_find_twcep
+#define tcp_is_addr_accept	_tinet_tcp_is_addr_accept
+#define tcp_move_twcep		_tinet_tcp_move_twcep
+#define tcpn_get_segment	_tinet_tcpn_get_segment
+
+/* netinet/tcp_subr_cs.c */
+
+#define tcp_read_rwbuf		_tinet_tcp_read_rwbuf
+#define tcp_write_rwbuf		_tinet_tcp_write_rwbuf
+#define tcp_drop_rwbuf		_tinet_tcp_drop_rwbuf
+#define tcp_free_rwbufq		_tinet_tcp_free_rwbufq
+#define tcp_get_rwbuf_addr	_tinet_tcp_get_rwbuf_addr
+
+#define tcp_free_rwbufq_cs	_tinet_tcp_free_rwbufq_cs
+#define tcp_get_rwbuf_addr_cs	_tinet_tcp_get_rwbuf_addr_cs
+#define tcp_read_rwbuf_cs	_tinet_tcp_read_rwbuf_cs
+#define tcp_write_rwbuf_cs	_tinet_tcp_write_rwbuf_cs
+#define tcp_drop_rwbuf_cs	_tinet_tcp_drop_rwbuf_cs
+
+#define tcp_wait_swbuf		_tinet_tcp_wait_swbuf
+#define tcp_init_swbuf		_tinet_tcp_init_swbuf
+#define tcp_alloc_swbuf		_tinet_tcp_alloc_swbuf
+#define tcp_is_swbuf_full	_tinet_tcp_is_swbuf_full
+#define tcp_drop_swbuf		_tinet_tcp_drop_swbuf
+#define tcp_free_swbufq		_tinet_tcp_free_swbufq
+#define tcp_read_swbuf		_tinet_tcp_read_swbuf
+#define tcp_write_swbuf		_tinet_tcp_write_swbuf
+#define tcp_pull_res_nbuf	_tinet_tcp_pull_res_nbuf
+#define tcp_push_res_nbuf	_tinet_tcp_push_res_nbuf
+#define tcp_get_swbuf_addr	_tinet_tcp_get_swbuf_addr
+#define tcp_send_swbuf		_tinet_tcp_send_swbuf
+
+#define tcp_get_swbuf_addr_cs	_tinet_tcp_get_swbuf_addr_cs
+#define tcp_wait_swbuf_cs	_tinet_tcp_wait_swbuf_cs
+#define tcp_is_swbuf_full_cs	_tinet_tcp_is_swbuf_full_cs
+#define tcp_alloc_swbuf_cs	_tinet_tcp_alloc_swbuf_cs
+#define tcp_send_swbuf_cs	_tinet_tcp_send_swbuf_cs
+#define tcp_free_swbufq_cs	_tinet_tcp_free_swbufq_cs
+#define tcp_drop_swbuf_cs	_tinet_tcp_drop_swbuf_cs
+#define tcp_write_swbuf_cs	_tinet_tcp_write_swbuf_cs
+
+/* netinet/tcp_subr_ncs.c */
+
+#define tcp_drop_rwbuf_ncs	_tinet_tcp_drop_rwbuf_ncs
+#define tcp_read_rwbuf_ncs	_tinet_tcp_read_rwbuf_ncs
+#define tcp_is_swbuf_full_ncs	_tinet_tcp_is_swbuf_full_ncs
+#define tcp_drop_swbuf_ncs	_tinet_tcp_drop_swbuf_ncs
+#define tcp_read_swbuf_ncs	_tinet_tcp_read_swbuf_ncs
+#define tcp_wait_swbuf_ncs	_tinet_tcp_wait_swbuf_ncs
+#define tcp_write_swbuf_ncs	_tinet_tcp_write_swbuf_ncs
+#define tcp_write_rwbuf_ncs	_tinet_tcp_write_rwbuf_ncs
+#define tcp_get_swbuf_addr_ncs	_tinet_tcp_get_swbuf_addr_ncs
+#define tcp_send_swbuf_ncs	_tinet_tcp_send_swbuf_ncs
+#define tcp_get_rwbuf_addr_ncs	_tinet_tcp_get_rwbuf_addr_ncs
+
+/* tcp_cfg.c */
+
+#define tcp6_rep		_tinet_tcp6_rep
+#define tcp4_rep		_tinet_tcp4_rep
+#define tcp_cep			_tinet_tcp_cep
+#define tcp_twcep		_tinet_tcp_twcep
+#define tmax_tcp_repid		_tinet_tmax_tcp_repid
+#define tmax_tcp_cepid		_tinet_tmax_tcp_cepid
+#define tmax_tcp_crepid		_tinet_tmax_tcp_repid	/* TINET 1.3 との互換性のための定義 */
+#define tmax_tcp_ccepid		_tinet_tmax_tcp_cepid	/* TINET 1.3 との互換性のための定義 */
+
+/* netinet/udp_input.c */
+
+#define udp6_reply_no_port	_tinet_udp6_reply_no_port
+#define udp6_input_select	_tinet_udp6_input_select
+#define udp6_input		_tinet_udp6_input
+#define udp4_reply_no_port	_tinet_udp4_reply_no_port
+#define udp4_input_select	_tinet_udp4_input_select
+#define udp4_input		_tinet_udp4_input
+
+/* netinet/udp_subr.c */
+
+#define udp6_alloc_port		_tinet_udp6_alloc_port
+#define udp6_alloc_auto_port	_tinet_udp6_alloc_auto_port
+#define udp6_notify		_tinet_udp6_notify
+#define udp6_find_cep		_tinet_udp6_find_cep
+#define udp4_alloc_port		_tinet_udp4_alloc_port
+#define udp4_alloc_auto_port	_tinet_udp4_alloc_auto_port
+#define udp4_notify		_tinet_udp4_notify
+#define udp4_find_cep		_tinet_udp4_find_cep
+
+/* netinet/udp_usrreq.c */
+
+#define udp_send_data		_tinet_udp_send_data
+
+/* netinet/udp_usrreq_nblk.c */
+
+#define udp_can_rcv		_tinet_udp_can_rcv
+#define udp_can_snd		_tinet_udp_can_snd
+
+/* udp_cfg.c */
+
+#define udp6_cep		_tinet_udp6_cep
+#define udp4_cep		_tinet_udp4_cep
+#define tmax_udp_cepid		_tinet_tmax_udp_cepid
+#define tmax_udp_ccepid		_tinet_tmax_udp_cepid	/* TINET 1.3 との互換性のための定義 */
+
+/* netinet/ip_icmp.c */
+
+#define icmp_input		_tinet_icmp_input
+#define icmp_error		_tinet_icmp_error
+#define icmp_echo_reply		_tinet_icmp_echo_reply
+
+/* netinet/ip_input.c */
+
+#define ip_input		_tinet_ip_input
+#define ip_init			_tinet_ip_init
+#define ip_frag_timer		_tinet_ip_frag_timer
+#define ip_get_frag_queue	_tinet_ip_get_frag_queue
+#define ip_remove_options	_tinet_ip_remove_options
+
+/* netinet/ip_output.c */
+
+#define ip_output		_tinet_ip_output
+
+/* netinet/in_subr.c */
+
+#define inn_addrwithifp		_tinet_inn_addrwithifp
+#define in_cksum_carry		_tinet_in_cksum_carry
+#define inn_is_addr_multicast	_tinet_inn_is_addr_multicast
+#define inn_get_datagram	_tinet_inn_get_datagram
+#define inn_is_dstaddr_accept	_tinet_inn_is_dstaddr_accept
+#define ip_exchg_addr		_tinet_ip_exchg_addr
+#define inn_copy_to_host	_tinet_inn_copy_to_host
+#define in_cksum_sum		_tinet_in_cksum_sum
+#define inn_are_net_srcaddr_equal	\
+				_tinet_inn_are_net_srcaddr_equal
+
+/* netinet/in4_subr.c */
+
+#define in4_add_ifaddr		_tinet_in4_add_ifaddr
+#define in4_set_header		_tinet_in4_set_header
+#define inn4_is_dstaddr_accept	_tinet_inn4_is_dstaddr_accept
+#define in4_rtredirect		_tinet_in4_rtredirect
+#define in_rtnewentry		_tinet_in_rtnewentry
+#define in_cksum		_tinet_in_cksum
+#define	in4_addrwithifp		_tinet_in4_addrwithifp
+#define in4_rtalloc		_tinet_in4_rtalloc
+#define in4_init		_tinet_in4_init
+#define in_rttimer		_tinet_in_rttimer
+#define in4_get_ifaddr		_tinet_in4_get_ifaddr
+#define in4_get_datagram	_tinet_in4_get_datagram
+#define in4_is_dstaddr_accept	_tinet_in4_is_dstaddr_accept
+#define in4_cksum		_tinet_in4_cksum
+#define in_rtinit		_tinet_in_rtinit
+#define in4_ifawithifp		_tinet_in4_ifawithifp
+
+/* netinet/if_ether.c */
+
+#define arp_request		_tinet_arp_request
+#define arp_input		_tinet_arp_input
+#define arp_resolve		_tinet_arp_resolve
+#define arp_init		_tinet_arp_init
+#define arp_get_cache		_tinet_arp_get_cache
+
+#define ether_map_ipv4_multicast	_tinet_ether_map_ipv4_multicast
+
+/* netinet6/icmp6.c */
+
+#define icmp6_input		_tinet_icmp6_input
+
+#endif	/* of #ifndef _IN_RENAME_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_subr.c	(revision 398)
@@ -0,0 +1,511 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/in_itron.h>
+
+#include <net/if_var.h>
+
+/*
+ *  in_cksum_sum -- チェックサムの合計計算関数
+ *
+ *  注意: data は 4 オクテット単位でパディングすること。
+ *        data が 2 オクテット単位にアラインされていないと
+ *        例外が発生する可能性がある。
+ *        len  は 4 オクテット単位にアラインされていること。
+ *
+ *        戻り値はホストバイトオーダ
+ */
+
+uint32_t
+in_cksum_sum (void *data, uint_t len /*オクテット単位*/)
+{
+	uint32_t sum = 0;
+
+	for ( ; len > 0; len -= 2) {
+		sum += *((uint16_t*)data);
+		data = (uint8_t*)data + 2;
+		}
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
+	return sum;
+#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
+	return ((sum >> 8) & 0xffff) + ((sum & 0xff) << 8) + ((sum >> 24) & 0xff);
+#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+	}
+
+/*
+ *  in_cksum_carry -- チェックサムの桁上げ計算関数
+ *
+ *  注意: data は 4 オクテット単位でパディングすること。
+ *        data が 2 オクテット単位にアラインされていないと
+ *        例外が発生する可能性がある。
+ *        len  は 4 オクテット単位にアラインされていること。
+ */
+
+uint32_t
+in_cksum_carry (uint32_t sum)
+{
+	uint32_t	carry;
+
+	while (sum >= 0x00010000) {
+		carry = sum >> 16;
+		sum   = (sum & 0xffff) + carry;
+		}
+
+	return sum;
+	}
+
+/*
+ *  in_strtfn -- API 機能コードの文字表現を返す。
+ */
+
+typedef struct t_strtfn {
+	FN		fncd;	/* API 機能コード	*/
+	const char	*str;	/* 文字表現		*/
+	} T_STRTFN;
+
+const T_STRTFN strtfn[] = {
+	{ TEV_TCP_RCV_OOB,	"TEV_TCP_RCV_OOB" },
+	{ TFN_TCP_DEL_REP,	"TFN_TCP_DEL_REP" },
+	{ TFN_TCP_CRE_CEP,	"TFN_TCP_CRE_CEP" },
+	{ TFN_TCP_DEL_CEP,	"TFN_TCP_DEL_CEP" },
+	{ TFN_TCP_ACP_CEP,	"TFN_TCP_ACP_CEP" },
+	{ TFN_TCP_CON_CEP,	"TFN_TCP_CON_CEP" },
+	{ TFN_TCP_SHT_CEP,	"TFN_TCP_SHT_CEP" },
+	{ TFN_TCP_CLS_CEP,	"TFN_TCP_CLS_CEP" },
+	{ TFN_TCP_SND_DAT,	"TFN_TCP_SND_DAT" },
+	{ TFN_TCP_RCV_DAT,	"TFN_TCP_RCV_DAT" },
+	{ TFN_TCP_GET_BUF,	"TFN_TCP_GET_BUF" },
+	{ TFN_TCP_SND_BUF,	"TFN_TCP_SND_BUF" },
+	{ TFN_TCP_RCV_BUF,	"TFN_TCP_RCV_BUF" },
+	{ TFN_TCP_REL_BUF,	"TFN_TCP_REL_BUF" },
+	{ TFN_TCP_SND_OOB,	"TFN_TCP_SND_OOB" },
+	{ TFN_TCP_RCV_OOB,	"TFN_TCP_RCV_OOB" },
+	{ TFN_TCP_CAN_CEP,	"TFN_TCP_CAN_CEP" },
+	{ TFN_TCP_SET_OPT,	"TFN_TCP_SET_OPT" },
+	{ TFN_TCP_GET_OPT,	"TFN_TCP_GET_OPT" },
+	{ TFN_TCP_ALL,		"TFN_TCP_ALL"     },
+
+	{ TEV_UDP_RCV_DAT,	"TEV_UDP_RCV_DAT" },
+	{ TFN_UDP_DEL_CEP,	"TFN_UDP_DEL_CEP" },
+	{ TFN_UDP_SND_DAT,	"TFN_UDP_SND_DAT" },
+	{ TFN_UDP_RCV_DAT,	"TFN_UDP_RCV_DAT" },
+	{ TFN_UDP_CAN_CEP,	"TFN_UDP_CAN_CEP" },
+	{ TFN_UDP_SET_OPT,	"TFN_UDP_SET_OPT" },
+	{ TFN_UDP_GET_OPT,	"TFN_UDP_GET_OPT" },
+	};
+
+const char *
+in_strtfn (FN fncd)
+{
+	int_t	ix;
+
+	for (ix = sizeof(strtfn) / sizeof(T_STRTFN); ix -- > 0; )
+		if (strtfn[ix].fncd == fncd)
+			return strtfn[ix].str;
+
+	return "unknown TFN";
+	}
+
+#if defined(_IP4_CFG)
+
+/*
+ *  ipv42str -- IPv4 アドレスを文字列に変換する。
+ */
+
+char *
+ipv42str (char *buf, const T_IN4_ADDR *ipaddr)
+{
+	static char	addr_sbuf[NUM_IPV4ADDR_STR_BUFF][sizeof("123.123.123.123")];
+	static int_t	bix = NUM_IPV4ADDR_STR_BUFF;
+
+	char *start;
+
+	if (buf == NULL) {
+		syscall(wai_sem(SEM_IP2STR_BUFF_LOCK));
+		buf = addr_sbuf[-- bix];
+		if (bix <= 0)
+			bix = NUM_IPV4ADDR_STR_BUFF;
+		syscall(sig_sem(SEM_IP2STR_BUFF_LOCK));
+		}
+
+	start = buf;
+	buf += convert_hexdigit(buf, (uint_t)((*ipaddr >> 24) & 0xff), 10, 0, ' ');
+	*(buf ++) = '.';
+	buf += convert_hexdigit(buf, (uint_t)((*ipaddr >> 16) & 0xff), 10, 0, ' ');
+	*(buf ++) = '.';
+	buf += convert_hexdigit(buf, (uint_t)((*ipaddr >>  8) & 0xff), 10, 0, ' ');
+	*(buf ++) = '.';
+	buf += convert_hexdigit(buf, (uint_t)((*ipaddr      ) & 0xff), 10, 0, ' ');
+	*buf = '\0';
+	return start;
+	}
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+/*
+ *  in6_is_addr_ipv4mapped -- IPv4 射影アドレスである事を検査する。
+ */
+
+bool_t
+in6_is_addr_ipv4mapped (const T_IN6_ADDR *addr)
+{
+	return IN6_IS_ADDR_V4MAPPED(addr);
+	}
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+
+/*
+ *  ip_exchg_addr -- IP アドレスを交換する。
+ */
+
+static void
+ip6_exchg_addr (T_NET_BUF *nbuf)
+{
+	T_IP6_HDR	*iph;
+	T_IN6_ADDR	ipaddr;
+
+	iph  = GET_IP6_HDR(nbuf);
+
+	/* IPv6 アドレスを交換する。*/
+	ipaddr = iph->src;
+	iph->src = iph->dst;
+	iph->dst = ipaddr;
+	}
+
+static void
+ip4_exchg_addr (T_NET_BUF *nbuf)
+{
+	T_IP4_HDR	*iph;
+	T_IN4_ADDR	ipaddr;
+
+	iph  = GET_IP4_HDR(nbuf);
+
+	/* IPv4 アドレスを交換する。*/
+	ipaddr = iph->src;
+	iph->src = iph->dst;
+	iph->dst = ipaddr;
+	}
+
+void
+ip_exchg_addr (T_NET_BUF *nbuf)
+{
+	if (GET_IP_VER(nbuf) == 6)
+		ip6_exchg_addr(nbuf);
+	else
+		ip4_exchg_addr(nbuf);
+	}
+
+#else	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+/*
+ *  ip_exchg_addr -- IP アドレスを交換する。
+ */
+
+void
+ip_exchg_addr (T_NET_BUF *nbuf)
+{
+	T_IP_HDR	*iph;
+	T_IN_ADDR	ipaddr;
+
+	iph  = GET_IP_HDR(nbuf);
+
+	/* IP アドレスを交換する。*/
+	ipaddr = iph->src;
+	iph->src = iph->dst;
+	iph->dst = ipaddr;
+	}
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+
+/*
+ *  inn_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
+ */
+
+bool_t
+inn_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *nbuf)
+{
+	if        (GET_IP_VER(nbuf)==IPV6_VERSION)
+		return INN6_IS_DSTADDR_ACCEPT(myaddr, nbuf);
+	else /*if (GET_IP_VER(nbuf)==IPV4_VERSION)*/ {
+		T_IP4_HDR	*ip4h;
+
+		ip4h  = GET_IP4_HDR(nbuf);
+		if (IN6_IS_ADDR_UNSPECIFIED(myaddr))
+			return ntohl(ip4h->dst) == IF_GET_IFNET()->in4_ifaddr.addr;
+		else {
+			T_IN6_ADDR	dstaddr;
+
+			return IN6_ARE_ADDR_EQUAL(myaddr, in6_make_ipv4mapped(&dstaddr, ntohl(ip4h->dst)));
+			}
+		}
+	}
+
+/*
+ *  inn_are_net_srcaddr_equal -- アドレスが同一かチェックする。
+ */
+
+bool_t
+inn_are_net_srcaddr_equal (T_IN6_ADDR *ipaddr, T_NET_BUF *nbuf)
+{
+	if        (GET_IP_VER(nbuf)==IPV6_VERSION)
+		return IN6_ARE_ADDR_EQUAL(ipaddr, &GET_IP6_HDR(nbuf)->src);
+	else /*if (GET_IP_VER(nbuf)==IPV4_VERSION)*/ {
+
+
+		T_IN6_ADDR	srcaddr;
+
+		return IN6_ARE_ADDR_EQUAL(ipaddr, in6_make_ipv4mapped(&srcaddr, ntohl(GET_IP4_HDR(nbuf)->src)));
+		}
+	}
+
+/*
+ *  inn_copy_to_host -- IP ヘッダからホスト表現変換して、IP アドレスをコピーする。
+ */
+
+void
+inn_copy_to_host (T_IN6_ADDR *dst, T_NET_BUF *nbuf)
+{
+	if        (GET_IP_VER(nbuf)==IPV6_VERSION)
+		memcpy(dst, &GET_IP6_HDR(nbuf)->src, sizeof(T_IN6_ADDR));
+	else /*if (GET_IP_VER(nbuf)==IPV4_VERSION)*/
+		in6_make_ipv4mapped(dst, ntohl(GET_IP4_HDR(nbuf)->src));
+
+	}
+
+/*
+ *  inn_get_datagram -- IPv6/IPv4 データグラムを獲得し、ヘッダを設定する。
+ */
+
+ER
+inn_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
+                  T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
+                  uint8_t next, uint8_t hlim, ATR nbatr, TMO tmout)
+{
+	if (IN6_IS_ADDR_V4MAPPED(dstaddr)) {
+		T_IN4_ADDR ip4dstaddr, ip4srcaddr;
+
+		ip4dstaddr = ntohl(dstaddr->s6_addr32[3]);
+		if (IN6_IS_ADDR_UNSPECIFIED(srcaddr))
+			ip4srcaddr = IF_GET_IFNET()->in4_ifaddr.addr;
+		else
+			ip4srcaddr = ntohl(srcaddr->s6_addr32[3]);
+
+		return in4_get_datagram(nbuf, len, maxlen, &ip4dstaddr, &ip4srcaddr, next, hlim, nbatr, tmout);
+		}
+	else
+		return in6_get_datagram(nbuf, len, maxlen, dstaddr, srcaddr, next, hlim, nbatr, tmout);
+	}
+
+/*
+ * inn_addrwithifp -- 宛先アドレスにふさわしい送信元アドレスを、
+ *                   ネットワークインタフェースから探索する。
+ */
+
+T_IN6_ADDR *
+inn_addrwithifp (T_IFNET *ifp, T_IN6_ADDR *src, T_IN6_ADDR *dst)
+{
+	T_IN6_IFADDR *ifaddr;
+
+	if (IN6_IS_ADDR_V4MAPPED(dst))
+		return in6_make_ipv4mapped (src, ifp->in4_ifaddr.addr);
+	else if ((ifaddr = in6_ifawithifp(ifp, dst)) == NULL)
+		return NULL;
+	else {
+		*src = ifaddr->addr;
+		return src;
+		}
+	}
+
+/*
+ *  inn_is_addr_multicast -- アドレスがマルチキャストアドレスかチェックする。
+ */
+
+bool_t
+inn_is_addr_multicast (T_IN6_ADDR *addr)
+{
+
+	if (IN6_IS_ADDR_V4MAPPED(addr))
+		return IN4_IS_ADDR_MULTICAST(ntohl(addr->s6_addr32[3]));
+	else
+		return IN6_IS_ADDR_MULTICAST(addr);
+	}
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+/*
+ *  バイトオーダ関数の定義
+ *
+ *    tinet/net/net.h でもバイトオーダの定義を行っているが、
+ *    tinet/net/net.h をインクルードしない
+ *    アプリケーションプログラム用に
+ *    ターゲット依存しないバイトオーダ関数を定義する。
+ */
+
+#if defined(_NET_CFG_BYTE_ORDER)
+
+#undef ntohs
+#undef htons
+#undef ntohl
+#undef htonl
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
+
+uint16_t
+ntohs (uint16_t net)
+{
+	return net;
+	}
+
+uint16_t
+htons (uint16_t host)
+{
+	return host;
+	}
+
+uint32_t
+ntohl (uint32_t net)
+{
+	return net;
+	}
+
+uint32_t
+htonl (uint32_t host)
+{
+	return host;
+	}
+
+#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN	/* of #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+uint16_t
+ntohs (uint16_t net)
+{
+	return NET_REV_ENDIAN_HWORD(net);
+	}
+
+uint16_t
+htons (uint16_t host)
+{
+	return NET_REV_ENDIAN_HWORD(host);
+	}
+
+uint32_t
+ntohl (uint32_t net)
+{
+	return NET_REV_ENDIAN_WORD(net);
+	}
+
+uint32_t
+htonl (uint32_t host)
+{
+	return NET_REV_ENDIAN_WORD(host);
+	}
+
+#else	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#error "_NET_CFG_BYTE_ORDER expected."
+
+#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#endif	/* of #if defined(_NET_CFG_BYTE_ORDER) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/in_var.h	(revision 398)
@@ -0,0 +1,207 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1985, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)in_var.h	8.2 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/netinet/in_var.h,v 1.29.2.1 1999/08/29 16:29:38 peter Exp $
+ */
+ 
+#ifndef _IN_VAR_H_
+#define _IN_VAR_H_
+
+#include <netinet/in4_var.h>
+#include <netinet6/in6_var.h>
+
+/*
+ *  独自のエラーコード
+ */
+
+#define EV_NOPND		(-97)		/* ペンディングしていない */
+
+/*
+ *  ネットワークエラーコード
+ */
+
+#define EV_MSIZE		(-98)		/* データグラム長超過	*/
+#define EV_NURCH		(-99)		/* ネットワーク到達不能	*/
+#define EV_HDOWN		(-100)		/* ホストダウン		*/
+#define EV_HURCH		(-101)		/* ホスト到達不能	*/
+#define EV_CNNRF		(-102)		/* 接続不能		*/
+#define EV_CNRST		(-103)		/* 接続リセット		*/
+#define EV_REXMTMO		(-104)		/* 再送タイムアウト	*/
+
+/*
+ *  共通タイマの起動周期の定義
+ */
+
+#define IN_TIMER_TMO		(SYSTIM_HZ/NET_TIMER_CYCLE)
+
+/*
+ *  ルーティングエントリ状態フラグ
+ */
+
+#define IN_RTF_DEFINED		UINT_C(0x01)	/* 定義済み			*/
+#define IN_RTF_REDIRECT		UINT_C(0x10)	/* 向け直しにより自動設定された	*/
+
+/*
+ *  IPv4 と IPv6 をコンパイル時に選択するためのマクロ
+ */
+
+#if defined(_IP6_CFG)
+
+#define T_IN_ADDR			T_IN6_ADDR
+#define T_IPEP				T_IPV6EP
+#define IP_ADDRANY			IPV6_ADDRANY
+
+#elif defined(_IP4_CFG)	/* of #if defined(_IP6_CFG) */
+
+#define T_IN_ADDR			T_IN4_ADDR
+#define T_IPEP				T_IPV4EP
+#define IP_ADDRANY			IPV4_ADDRANY
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP6_CFG)
+
+#if defined(_IP4_CFG)
+
+#define IN_CKSUM(nbuf,proto,off,len)	(GET_IP_VER(nbuf)==IPV6_VERSION	\
+					?in6_cksum(nbuf,proto,off,len)	\
+					:in4_cksum(nbuf,proto,off,len))
+#define IN_IS_DSTADDR_ACCEPT(myaddr,nbuf)	\
+					inn_is_dstaddr_accept(myaddr,nbuf)
+#define IN_ARE_HDR_ADDR_EQUAL(nbuf)	(GET_IP_VER(nbuf)==IPV6_VERSION	\
+					?IN6_ARE_ADDR_EQUAL(&GET_IP6_HDR(nbuf)->dst,&GET_IP6_HDR(nbuf)->src)	\
+					:IN4_ARE_ADDR_EQUAL(&GET_IP4_HDR(nbuf)->dst,&GET_IP4_HDR(nbuf)->src))
+#define IN_ARE_NET_SRCADDR_EQUAL(ipaddr,nbuf)	\
+		    			inn_are_net_srcaddr_equal(ipaddr,nbuf)
+#define IN_COPY_TO_HOST(dst,nbuf)	inn_copy_to_host(dst,nbuf)
+#define IN_GET_DATAGRAM(nbuf,len,maxlen,dst,src,next,hlim,nbatr,tmout)	\
+					inn_get_datagram(nbuf,len,maxlen,dst,src,next,hlim,nbatr,tmout)
+#define IN_IS_ADDR_MULTICAST(addr)	inn_is_addr_multicast(addr)
+#define IN_IS_NET_ADDR_MULTICAST(nbuf)	IN_IS_ADDR_MULTICAST(&GET_IP6_HDR(nbuf)->dst)
+#define IN_ADDRWITHIFP(ifp,src,dst)	inn_addrwithifp(ifp,src,dst)
+#define IN_IS_ADDR_ANY(addr)		IN6_IS_ADDR_UNSPECIFIED(addr)
+
+#else	/* of #if defined(_IP4_CFG) */
+
+#define IN_CKSUM(nbuf,proto,off,len)	in6_cksum(nbuf,proto,off,len)
+#define IN_IS_DSTADDR_ACCEPT(myaddr,nbuf)	\
+					INN6_IS_DSTADDR_ACCEPT(myaddr,nbuf)
+#define IN_ARE_HDR_ADDR_EQUAL(nbuf)	IN6_ARE_ADDR_EQUAL(&GET_IP6_HDR(nbuf)->dst,&GET_IP6_HDR(nbuf)->src)
+#define IN_ARE_NET_SRCADDR_EQUAL(ipaddr,nbuf)	\
+		    			IN6_ARE_ADDR_EQUAL(ipaddr,&GET_IP6_HDR(nbuf)->src)
+#define IN_COPY_TO_HOST(dst,nbuf)	IN6_COPY_TO_HOST(dst, nbuf)
+#define IN_GET_DATAGRAM(nbuf,len,maxlen,dst,src,next,hlim,nbatr,tmout)	\
+					in6_get_datagram(nbuf,len,maxlen,dst,src,next,hlim,nbatr,tmout)
+#define IN_IS_ADDR_MULTICAST(addr)	IN6_IS_ADDR_MULTICAST(addr)
+#define IN_IS_NET_ADDR_MULTICAST(nbuf)	IN6_IS_ADDR_MULTICAST(&GET_IP6_HDR(nbuf)->dst)
+#define IN_ADDRWITHIFP(ifp,src,dst)	in6_addrwithifp(ifp,src,dst)
+#define IN_IS_ADDR_ANY(addr)		IN6_IS_ADDR_UNSPECIFIED(addr)
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+#define IN_CKSUM(nbuf,proto,off,len)	in4_cksum(nbuf,proto,off,len)
+#define IN_IS_DSTADDR_ACCEPT(myaddr,nbuf)	\
+					inn4_is_dstaddr_accept(myaddr,nbuf)
+#define IN_ARE_HDR_ADDR_EQUAL(nbuf)	IN4_ARE_ADDR_EQUAL(&GET_IP4_HDR(nbuf)->dst,&GET_IP4_HDR(nbuf)->src)
+#define IN_ARE_NET_SRCADDR_EQUAL(ipaddr,nbuf)	\
+					(*(ipaddr)==ntohl(GET_IP4_HDR(nbuf)->src))
+#define IN_COPY_TO_HOST(dst,nbuf)	IN4_COPY_TO_HOST(dst, nbuf)
+#define IN_GET_DATAGRAM(nbuf,len,maxlen, dst,src,proto,ttl,nbatr,tmout)	\
+					in4_get_datagram(nbuf,len,maxlen, dst,src,proto,ttl,nbatr,tmout)
+#define IN_IS_ADDR_MULTICAST(addr)	IN4_IS_ADDR_MULTICAST(*(addr))
+#define IN_IS_NET_ADDR_MULTICAST(nbuf)	IN4_IS_ADDR_MULTICAST(ntohl(GET_IP4_HDR(nbuf)->dst))
+#define IN_ADDRWITHIFP(ifp,src,dst)	in4_addrwithifp(ifp,src,dst)
+#define IN_IS_ADDR_ANY(addr)		IN4_IS_ADDR_ANY(addr)
+
+#else	/* of #if defined(_IP4_CFG) */
+
+#error "not implemented."
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#ifndef _MACRO_ONLY
+
+/*
+ *  関数
+ */
+extern bool_t	inn_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *nbuf);
+extern bool_t	inn_is_addr_multicast (T_IN6_ADDR *addr);
+extern bool_t	inn_are_net_srcaddr_equal (T_IN6_ADDR *ipaddr, T_NET_BUF *nbuf);
+extern void	inn_copy_to_host (T_IN6_ADDR *dst, T_NET_BUF *nbuf);
+extern ER	inn_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
+		                  T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
+		                  uint8_t next, uint8_t hlim, ATR nbatr, TMO tmout);
+extern T_IN6_ADDR *inn_addrwithifp (T_IFNET *ifp, T_IN6_ADDR *src, T_IN6_ADDR *dst);
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#endif	/* of #ifndef _IN_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip.cfg	(revision 398)
@@ -0,0 +1,56 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  IPv4 で使用するカーネルオブジェクト
+ */
+
+#if defined(_IP4_CFG)
+
+#ifdef IP4_CFG_FRAGMENT
+
+/* データグラムの分割・再構成 */
+
+CRE_SEM(SEM_IP4_FRAG_QUEUE, { TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
+
+/* ルーティング表（向け直し）*/
+
+CRE_SEM(SEM_IN4_ROUTING_TBL, { TA_TPRI, 1, 1 });
+
+#endif	/* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
+
+#endif	/* of #if defined(_IP4_CFG) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip.h	(revision 398)
@@ -0,0 +1,146 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip.h	8.2 (Berkeley) 6/1/94
+ * $FreeBSD: src/sys/netinet/ip.h,v 1.15.2.1 1999/08/29 16:29:38 peter Exp $
+ */
+ 
+#ifndef _IP4_H_
+#define _IP4_H_
+
+#include <netinet/ip6.h>
+
+/*
+ *  IPv4 の定義、RFC791 参照
+ */
+
+#define IPV4_VERSION		4
+
+/*
+ *  IPv4 ヘッダの定義
+ */
+
+typedef struct t_ip4_hdr {
+	uint8_t		vhl;		/* version << 4 | header length >> 2	*/
+					/* length は 4 octets 単位		*/
+	uint8_t		type;		/* type of services			*/
+	uint16_t	len;		/* total length				*/
+
+	uint16_t	id;		/* identification			*/
+	uint16_t	flg_off;	/* fragment flag & offset		*/
+
+	uint8_t		ttl;		/* time to live				*/
+	uint8_t		proto;		/* protocol				*/
+	uint16_t	sum;		/* checksum				*/
+
+	T_IN4_ADDR	src;		/* source address			*/
+	T_IN4_ADDR	dst;		/* destination address			*/
+	} __attribute__((packed, aligned(2)))T_IP4_HDR;
+
+#define IP4_HDR_SIZE		(sizeof(T_IP4_HDR))
+
+/*
+ *  IPv4 ヘッダ構造体メンバアクセスマクロ
+ */
+
+#define IP4_MAKE_VHL(v,hl)	((uint8_t)(((uint8_t)(v)<<4)|(hl)))
+#define IP4_VHL_V(vhl)		((uint8_t)((uint8_t)(vhl)>>4))
+#define IP4_VHL_HL(vhl)		((uint8_t)((vhl)&0x0f))
+
+#define IP4_MAKE_FLGOFF(f,o)	((uint16_t)((f)|(o)))
+#define IP4_FLGOFF_FLG(f)	((uint16_t)((f)&~IP4_OFFMASK))
+#define IP4_FLGOFF_OFF(o)	((uint16_t)((o)&IP4_OFFMASK))
+
+/*
+ *  IPv4 ヘッダのフィールドの値の定義
+ */
+
+#define IP4_VHL_BORING	UINT_C(0x45)	/* オプションがない VHL 値	*/
+#define IP4_RF		UINT_C(0x8000)	/* off: 予約			*/
+#define IP4_DF		UINT_C(0x4000)	/* off: 分割禁止			*/
+#define IP4_MF		UINT_C(0x2000)	/* off: 分割あり			*/
+#define IP4_OFFMASK	UINT_C(0x1fff)	/* オフセット部のマスク値		*/
+
+/*
+ *  制限値
+ */
+
+#define IP4_MAXPACKET	UINT_C(65535)	/* 最大パケットサイズ		*/
+#define IP4_MAXTTL	UINT_C(255)	/* TTL 最大値			*/
+#define IP4_DEFTTL	UINT_C(64)	/* TTL 規定値 (RFC1340)		*/
+#define IP4_FRAGTTL	UINT_C(60)	/* 分割されたデータグラムの生存時間（秒）*/
+#define IP4_MSS		UINT_C(576)	/* 最大セグメントサイズの規定値	*/
+
+/* IPv4 と IPv6 をコンパイル時に選択するためのマクロ */
+
+#if !defined(_IP6_CFG) && defined(_IP4_CFG)
+
+#define IP_HDR_SIZE	IP4_HDR_SIZE
+#define T_IP_HDR	T_IP4_HDR
+#define IP_DEFTTL	IP4_DEFTTL
+
+#endif	/* of #if !defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+#endif	/* of #ifndef _IP4_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip4_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip4_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip4_var.h	(revision 398)
@@ -0,0 +1,255 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip_var.h	8.2 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/netinet/ip_var.h,v 1.45.2.1 1999/08/29 16:29:51 peter Exp $
+ */
+ 
+#ifndef _IP4_VAR_H_
+#define _IP4_VAR_H_
+
+/*
+ *  IPv4 ヘッダ・ペイロードアクセスマクロ
+ */
+
+#define IF_IP4_HDR_SIZE			(IF_HDR_SIZE + IP4_HDR_SIZE)
+
+#define GET_IP4_HDR(nbuf)		((T_IP4_HDR*)((nbuf)->buf + IF_HDR_SIZE))
+#define GET_IP4_SDU(nbuf)		((uint8_t*)((nbuf)->buf) + GET_IF_IP4_HDR_SIZE(nbuf))
+
+#define GET_IP4_HDR_SIZE(nbuf)		((uint8_t)IP4_VHL_HL(GET_IP4_HDR(nbuf)->vhl) << 2)
+#define GET_IP4_SDU_SIZE(nbuf)		(ntohs(GET_IP4_HDR(nbuf)->len) - GET_IP4_HDR_SIZE(nbuf))
+#define GET_IF_IP4_HDR_SIZE(nbuf)	(IF_HDR_SIZE + (GET_IP4_HDR_SIZE(nbuf)))
+
+#define SET_IP4_SDU_SIZE(nbuf,slen)	(GET_IP4_HDR(nbuf)->len=(uint16_t)htons((slen) + IP4_HDR_SIZE))
+
+/*
+ *  IP の MSS サイズのネットワークバッファ
+ */
+
+typedef struct t_net_buf_ip_mss {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IF_HDR_SIZE + IP4_MSS];
+				/* バッファ本体		*/
+	} T_NET_BUF_IP_MSS;
+
+/*
+ *  65536 オクテットサイズのネットワークバッファ
+ */
+
+typedef struct t_net_buf4_65536 {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IF_IP4_HDR_SIZE + 65536];
+				/* バッファ本体		*/
+#if defined(IF_PDU_HDR_PADDING)
+	uint8_t		padding[IF_PDU_HDR_PADDING];
+#endif				/* ヘッダの余分		*/
+	} T_NET_BUF4_65536;
+
+#ifdef IP4_CFG_FRAGMENT
+
+/*
+ *  再構成キュー用 IPv4 ヘッダの定義
+ */
+
+typedef struct t_qip4_hdr {
+	uint8_t		vhl;		/* version << 4 | header length >> 2	*/
+					/* length は 4 octets 単位		*/
+	uint8_t		type;		/* type of services			*/
+	uint16_t	len;		/* total length				*/
+
+	uint16_t	id;		/* identification			*/
+	uint16_t	flg_off;	/* fragment flag & offset		*/
+
+	uint8_t		ttl;		/* time to live				*/
+	uint8_t		proto;		/* protocol				*/
+	uint16_t	sum;		/* checksum				*/
+
+	uint32_t	src;		/* source address			*/
+
+	T_NET_BUF	*next;		/* 次の IPv4 フラグメント			*/
+	} __attribute__((packed, aligned(2))) T_QIP4_HDR;
+
+#define QIP4_HDR_SIZE			(sizeof(T_QIP4_HDR))
+#define IF_QIP4_HDR_SIZE		(IF_HDR_SIZE + QIP4_HDR_SIZE)
+
+#define GET_QIP4_HDR(nbuf)		((T_QIP4_HDR*)((nbuf)->buf + IF_HDR_SIZE))
+#define GET_QIP4_SDU(nbuf)		((uint8_t*)(nbuf)->buf + GET_IF_QIP4_HDR_SIZE(nbuf))
+
+#define GET_QIP4_HDR_SIZE(iph)		((uint8_t)IP4_VHL_HL((iph)->vhl) << 2)
+#define GET_IF_QIP4_HDR_SIZE(nbuf)	(IF_HDR_SIZE + (GET_QIP4_HDR_SIZE(GET_QIP4_HDR(nbuf))))
+
+/*
+ *  データグラム再構成用ネットワークバッファ
+ */
+
+typedef struct t_net_buf4_reassm {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		align[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IP4_CFG_FRAG_REASSM_SIZE];
+				/* バッファ本体		*/
+	} __attribute__((packed, aligned(2))) T_NET_BUF4_REASSM;
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+/*
+ *  TCP の再構成キューにおける IPv4 ヘッダの定義
+ */
+
+typedef struct t_ip4_tcp_q_hdr {
+	uint8_t		vhl;		/* version << 4 | header length >> 2	*/
+					/* length は 4 octets 単位		*/
+	uint8_t		type;		/* type of services			*/
+	uint16_t	len;		/* total length				*/
+
+	uint16_t	id;		/* identification			*/
+	uint16_t	flg_off;	/* fragment flag & offset		*/
+
+	uint8_t		ttl;		/* time to live				*/
+	uint8_t		proto;		/* protocol				*/
+	uint16_t	thoff;		/* TCP ヘッダのオフセット		*/
+
+	T_IN4_ADDR	src;		/* source address			*/
+	T_IN4_ADDR	dst;		/* destination address			*/
+	} __attribute__((packed, aligned(2))) T_IP4_TCP_Q_HDR;
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+typedef struct t_ip_stats {
+	uint32_t	ipInReceives;
+	uint32_t	ipInHdrErrors;
+	uint32_t	ipInAddrErrors;
+/*	uint32_t	ipForwDatagrams;*/
+	uint32_t	ipInUnknownProtos;
+/*	uint32_t	ipInDiscards;*/
+	uint32_t	ipInDelivers;
+	uint32_t	ipOutRequests;
+	uint32_t	ipOutDiscards;
+/*	uint32_t	ipOutNoRoutes;*/
+
+#ifdef IP4_CFG_FRAGMENT
+
+	uint32_t	ipReasmReqds;
+	uint32_t	ipReasmOKs;
+	uint32_t	ipReasmFails;
+	uint32_t	ipFragOKs;
+	uint32_t	ipFragFails;
+	uint32_t	ipFragCreates;
+
+#else	/* of #ifdef IP4_CFG_FRAGMENT */
+
+	uint32_t	ipReasmReqds;
+/*	uint32_t	ipReasmOKs;*/
+	uint32_t	ipReasmFails;
+/*	uint32_t	ipFragOKs;*/
+/*	uint32_t	ipFragFails;*/
+/*	uint32_t	ipFragCreates;*/
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+} T_IP_STATS;
+
+extern T_IP_STATS ip_stats;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+/*
+ *  関数
+ */
+
+extern void ip_frag_timer (void);
+extern void ip_init (void);
+extern ER ip_remove_options (T_NET_BUF *nbuf);
+extern ER ip_output (T_NET_BUF *nbuf, TMO tmout);
+extern void ip_exchg_addr (T_NET_BUF *nbuf);
+
+#endif	/* of #ifndef _IP4_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip6.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip6.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip6.h	(revision 398)
@@ -0,0 +1,293 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet/ip6.h,v 1.2.2.2 2001/07/03 11:01:46 ume Exp $	*/
+/*	$KAME: ip6.h,v 1.18 2001/03/29 05:34:30 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip.h	8.1 (Berkeley) 6/10/93
+ */
+ 
+#ifndef _IP6_H_
+#define _IP6_H_
+
+/*
+ *  IPv6 の定義、RFC2460 参照
+ */
+
+#define IPV6_VERSION	6
+
+/*
+ *  IPv6 ヘッダの定義
+ */
+
+typedef struct t_ip6_hdr {
+	uint32_t	vcf;		/* Version:        4 bit		*/
+					/* Traffic Class:  8 bit		*/
+					/* Flow Label:    20 bit		*/
+	uint16_t	plen;		/* Payload Length			*/
+	uint8_t		next;		/* Next Header				*/
+	uint8_t		hlim;		/* Hop Limit				*/
+	T_IN6_ADDR 	src;		/* Source Address			*/
+	T_IN6_ADDR 	dst;		/* Destination Address			*/
+	} __attribute__((packed, aligned(2)))T_IP6_HDR;
+
+#define IP6_HDR_SIZE		(sizeof(T_IP6_HDR))
+
+/*
+ *  IPv6 ヘッダ構造体メンバアクセスマクロ
+ */
+
+#define IP6_MAKE_VCF(v,cf)	(((uint32_t)(v)<<28)|(cf))
+#define IP6_VCF_V(vcf)		((uint32_t)(vcf)>>28)
+#define IP6_VCF_C(vcf)		(((uint32_t)(vcf)>>20)&ULONG_C(0xff))
+#define IP6_VCF_F(vcf)		((uint32_t)(vcf)&ULONG_C(0x000fffff))
+#define IP6_VCF_CF(vcf)		((uint32_t)(vcf)&ULONG_C(0x0fffffff))
+
+/*
+ *  拡張ヘッダ
+ */
+
+typedef struct t_ip6_ext_hdr {
+	uint8_t		next;		/* Next Header			*/
+	uint8_t		len;		/* 8 オクテット単位の長さ	*/
+	} __attribute__((packed, aligned(2)))T_IP6_EXT_HDR;
+
+/*
+ *  中継点 (Hop-by-Hop) オプションヘッダ
+ */
+
+typedef struct t_ip6_hbh_hdr {
+	uint8_t		next;		/* Next Header			*/
+	uint8_t		len;		/* 8 オクテット単位の長さ。ただし、
+					 * このオプションヘッダ全体のオクテット数を
+					 * 8 で割った値の - 1 が入る。
+					 */
+	} __attribute__((packed, aligned(2)))T_IP6_HBH_HDR;
+
+/*
+ *  終点 (Destination) オプションヘッダ
+ */
+
+typedef struct t_ip6_dest_hdr {
+	uint8_t		next;		/* Next Header			*/
+	uint8_t		len;		/* 8 オクテット単位の長さ。ただし、
+					 * このオプションヘッダ全体のオクテット数を
+					 * 8 で割った値の - 1 が入る。
+					 */
+	} __attribute__((packed, aligned(2)))T_IP6_DEST_HDR;
+
+/* 中継点 (Hop-by-Hop) オプション */
+
+#define IP6OPT_PAD1		UINT_C(0x00)	/* 00 0 00000 */
+#define IP6OPT_PADN		UINT_C(0x01)	/* 00 0 00001 */
+#define IP6OPT_JUMBO		UINT_C(0xc2)	/* 11 0 00010 */
+#define IP6OPT_NSAP_ADDR	UINT_C(0xc3)	/* 11 0 00011 */
+#define IP6OPT_TUNNEL_LIMIT	UINT_C(0x04)	/* 00 0 00100 */
+#define IP6OPT_RTR_ALERT	UINT_C(0x05)	/* 00 0 00101 */
+
+#define IP6OPT_MINLEN		2	/* オプションの最短長		*/
+
+/* 未知のオプションの処理の指定 */
+
+#define IP6OPT_TYPE_SKIP	UINT_C(0x00)	/* 無視する。			*/
+#define IP6OPT_TYPE_DISCARD	UINT_C(0x40)	/* データグラムを破棄する。	*/
+#define IP6OPT_TYPE_FORCEICMP	UINT_C(0x80)	/* 破棄して、ICMP を返送する。	*/
+#define IP6OPT_TYPE_ICMP	UINT_C(0xc0)
+		/* 破棄して、マルチキャストでなければ ICMP を返送する。	*/
+
+#define IP6OPT_TYPE(o)		((o)&UINT_C(0xc0))
+
+/*
+ *  経路制御ヘッダ
+ */
+
+typedef struct t_ip6_rt_hdr {
+	uint8_t		next;		/* Next Header			*/
+	uint8_t		len;		/* 8 オクテット単位の長さ。ただし、
+					 * このオプションヘッダ全体のオクテット数を
+					 * 8 で割った値の - 1 が入る。
+					 */
+	uint8_t		type;		/* 経路制御タイプ		*/
+	uint8_t		segleft;	/* セグメントの残り		*/
+	} __attribute__((packed, aligned(2)))T_IP6_RT_HDR;
+
+/*
+ *  タイプ 0 経路制御ヘッダ
+ */
+
+typedef struct t_ip6_rt0_hdr {
+	uint8_t		next;		/* Next Header			*/
+	uint8_t		len;		/* 8 オクテット単位の長さ。ただし、
+					 * このオプションヘッダ全体のオクテット数を
+					 * 8 で割った値の - 1 が入る。
+					 */
+	uint8_t		type;		/* 経路制御タイプ		*/
+	uint8_t		segleft;	/* セグメントの残り		*/
+	uint32_t	reserved;	/* 予約				*/
+	} __attribute__((packed, aligned(2)))T_IP6_RT0_HDR;
+
+/*
+ *  断片ヘッダ
+ */
+
+typedef struct t_ip6_frag_hdr {
+	uint8_t		next;		/* Next Header			*/
+	uint8_t		reserved;
+	uint16_t	off_flag;	/* オフセットとフラグ		*/
+	uint32_t	ident;		/* 分割識別子			*/
+	} __attribute__((packed, aligned(2)))T_IP6_FRAG_HDR;
+
+/* 断片ヘッダのオフセットとフラグ */
+
+#ifdef _NET_CFG_BYTE_ORDER
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
+
+#define IP6F_OFF_MASK		UINT_C(0xfff8)		/* オフセットを取出すマスク	*/
+#define IP6F_RESERVED_MASK	UINT_C(0x0006)		/* 予約を取出すマスク		*/
+#define IP6F_MORE_FRAG		UINT_C(0x0001)		/* 中間フラグメント		*/
+
+#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
+
+#define IP6F_OFF_MASK		UINT_C(0xf8ff)		/* オフセットを取出すマスク	*/
+#define IP6F_RESERVED_MASK	UINT_C(0x0600)		/* 予約を取出すマスク		*/
+#define IP6F_MORE_FRAG		UINT_C(0x0100)		/* 中間フラグメント		*/
+
+#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#endif	/* of #ifdef _NET_CFG_BYTE_ORDER */
+
+/*
+ *  制限値
+ */
+
+#define IPV6_MAXHLIM	UINT_C(255)	/* ホップリミットの最大値				*/
+#define IPV6_DEFHLIM	UINT_C(64)	/* ホップリミットの規定値				*/
+#define IPV6_FRAGTTL	UINT_C(60)	/* 分割されたデータグラムの生存時間（秒）	*/
+#define IPV6_MMTU	UINT_C(1280)	/* 最小 MTU。ペイロード (1024) + ヘッダ (256)	*/
+#define IPV6_MAXPACKET	UINT_C(65535)	/* ジャンボペイロードを除く最大パケットサイズ	*/
+
+/*
+ *  IPv6 と IPv4 をコンパイル時に選択するためのマクロ
+ */
+
+/*
+ *  ホップリミットの規定値は、ルータ通知により変更されることがある
+ */
+
+#if NUM_ND6_DEF_RTR_ENTRY > 0
+
+/* ルータ通知を受信する場合は、通知された値 */
+
+#define IP6_DEFTTL	ip6_defhlim
+
+#else	/* #if NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+/* ルータ通知を受信しない場合の値は既定値 */
+
+#define IP6_DEFTTL	IPV6_DEFHLIM
+
+#endif	/* #if NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+/* IPv4 と IPv6 をコンパイル時に選択するためのマクロ */
+
+#ifdef _IP6_CFG
+
+#define IP_HDR_SIZE	IP6_HDR_SIZE
+#define T_IP_HDR	T_IP6_HDR
+#define IP_DEFTTL	IP6_DEFTTL
+
+#endif	/* of #ifdef _IP6_CFG */
+
+#endif	/* of #ifndef _IP6_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_icmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_icmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_icmp.c	(revision 398)
@@ -0,0 +1,457 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip_icmp.c	8.2 (Berkeley) 1/4/94
+ * $FreeBSD: src/sys/netinet/ip_icmp.c,v 1.33.2.3 1999/10/14 11:49:38 des Exp $
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/icmp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+
+#include <net/if_var.h>
+
+#if defined(_IP4_CFG)
+
+/*
+ *  変数
+ */
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+T_ICMP_STATS icmp_stats;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+/*
+ *  関数
+ */
+
+static void icmp_echo (T_NET_BUF *input, uint_t ihoff);
+static void icmp_unreach (T_NET_BUF *input, uint_t ihoff);
+
+#if defined(NUM_REDIRECT_ROUTE_ENTRY)
+#if NUM_REDIRECT_ROUTE_ENTRY > 0
+
+static void icmp_redirect (T_NET_BUF *input, uint_t ihoff);
+
+#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if defined(NUM_REDIRECT_ROUTE_ENTRY) */
+
+/*
+ *  icmp_echo -- エコー要求を受信したときの処理
+ *
+ *    input には IF ヘッダと IP ヘッダも含まれている。
+ */
+
+static void
+icmp_echo (T_NET_BUF *input, uint_t ihoff)
+{
+	T_IP4_HDR	*ip4h;
+	T_ICMP4_HDR	*icmp4h;
+	T_IFNET		*ifp = IF_GET_IFNET();
+
+	NET_COUNT_MIB(icmp_stats.icmpInEchos, 1);
+
+	/* IPv4 アドレスが未定義の時は応答しない。*/
+	if (!IN4_IS_ADDR_ANY(&ifp->in4_ifaddr.addr)) {
+
+		/*
+		 *  メッセージの型をエコー要求 (8) から
+		 *  エコー応答 (0) に変更して送り返す。
+		 */
+
+		icmp4h = GET_ICMP4_HDR(input, ihoff);
+		icmp4h->type = ICMP4_ECHO_REPLY;
+
+		/*
+		 *  宛先アドレスは受信したメッセージの送信元アドレス。
+		 *  送信元アドレスは自 IPv4 アドレス。
+		 */
+		ip4h      = GET_IP4_HDR(input);
+		ip4h->dst = ip4h->src;
+		ip4h->src = htonl(ifp->in4_ifaddr.addr);
+
+		/* チェックサムを計算する。*/
+		icmp4h->sum = 0;
+		icmp4h->sum = in_cksum(icmp4h,
+		                       (uint_t)(((input->len - GET_IF_IP4_HDR_SIZE(input)) + 3) >> 2 << 2));
+
+		/* 送信する。*/
+		NET_COUNT_ICMP4(net_count_icmp4.out_octets,
+		               input->len - GET_IF_IP4_HDR_SIZE(input));
+		NET_COUNT_ICMP4(net_count_icmp4.out_packets, 1);
+		NET_COUNT_MIB(icmp_stats.icmpOutMsgs, 1);
+		NET_COUNT_MIB(icmp_stats.icmpOutEchoReps, 1);
+		ip_output(input, TMO_ICMP_OUTPUT);
+		}
+	}
+
+/*
+ *  icmp_unreach -- ICMP4_UNREACH を受信したときの処理
+ */
+
+static const int8_t code2error[] = {
+	EV_HURCH,	/* ICMP4_UNREACH_NET			 0 */
+	EV_HURCH,	/* ICMP4_UNREACH_HOST			 1 */
+	EV_CNNRF,	/* ICMP4_UNREACH_PROTOCOL		 2 */
+	EV_CNNRF,	/* ICMP4_UNREACH_PORT			 3 */
+	EV_MSIZE,	/* ICMP4_UNREACH_FLAG			 4 */
+	EV_HURCH,	/* ICMP4_UNREACH_SRC_FAIL		 5 */
+	EV_HURCH,	/* ICMP4_UNREACH_NET_UNKNOWN		 6 */
+	EV_HURCH,	/* ICMP4_UNREACH_HOST_UNKNOWN		 7 */
+	EV_HURCH,	/* ICMP4_UNREACH_ISOLATED		 8 */
+	EV_HURCH,	/* ICMP4_UNREACH_NET_PROHIB		 9 */
+	EV_HURCH,	/* ICMP4_UNREACH_HOST_PROHIB		10 */
+	EV_HURCH,	/* ICMP4_UNREACH_TOS_NET		11 */
+	EV_HURCH,	/* ICMP4_UNREACH_TOS_HOST		12 */
+	EV_HURCH,	/* ICMP4_UNREACH_FILTER_PROHIB		13 */
+	EV_HURCH,	/* ICMP4_UNREACH_HOST_PRECEDENCE	14 */
+	EV_HURCH,	/* ICMP4_UNREACH_PRECEDENCE_CUTOFF	15 */
+	};
+
+static void
+icmp_unreach (T_NET_BUF *input, uint_t ihoff)
+{
+	T_IP4_HDR	*ip4h;
+	uint8_t		code;
+	ER		error;
+
+	NET_COUNT_MIB(icmp_stats.icmpInDestUnreachs, 1);
+
+	ip4h   = (T_IP4_HDR*)GET_ICMP4_SDU(input, ihoff);
+	code  = GET_ICMP4_HDR(input, ihoff)->code;
+	error = code2error[code];
+
+	/* 最終ヘッダが TCP/UDP のみ対応する。*/
+	if (ip4h->proto == IPPROTO_TCP || ip4h->proto == IPPROTO_UDP) {
+
+		memcpy(GET_IP4_HDR(input), ip4h, input->len - (IP4_HDR_SIZE + ICMP4_HDR_SIZE));
+		input->len -= IP4_HDR_SIZE + ICMP4_HDR_SIZE;
+
+#if defined(SUPPORT_TCP)
+
+		if (ip4h->proto == IPPROTO_TCP)
+			tcp_notify(input, error);
+
+#endif	/* of #if defined(SUPPORT_TCP) */
+
+#if defined(SUPPORT_UDP) && TNUM_UDP4_CEPID > 0
+
+		if (ip4h->proto == IPPROTO_UDP)
+			udp4_notify(input, error);
+
+#endif	/* of #if defined(SUPPORT_UDP) && TNUM_UDP4_CEPID > 0 */
+
+		}
+	else
+		syslog(LOG_NOTICE, "[ICMP] error, code: %d.", code);
+	}
+
+#if defined(NUM_REDIRECT_ROUTE_ENTRY)
+#if NUM_REDIRECT_ROUTE_ENTRY > 0
+
+/*
+ *  icmp_redirect -- 向け直しメッセージを受信したときの処理
+ *
+ *    input には IF ヘッダと IP ヘッダも含まれている。
+ */
+
+static void
+icmp_redirect (T_NET_BUF *input, uint_t ihoff)
+{
+	T_IP4_HDR	*ip4h, *sip4h;
+	T_ICMP4_HDR	*icmp4h;
+
+	ip4h   = GET_IP4_HDR(input);
+	icmp4h = GET_ICMP4_HDR(input, ihoff);
+	sip4h  = (T_IP4_HDR *)GET_ICMP4_SDU(input, ihoff);
+
+	/*
+	 *  内容チェック、以下の場合はエラー
+	 *
+	 *    ・ICMP コードが、ICMP4_REDIRECT_PORT_AND_HOST (3) 以上
+	 *    ・データグラム長が、ICMP の最小長より短い (IP ヘッダ + ICMP ヘッダ + IP ヘッダ + 8)
+	 *    ・データグラム長が、ICMP の最大長より短い
+	 *    ・
+	 */
+	if (icmp4h->code > ICMP4_REDIRECT_PORT_AND_HOST ||
+	    ip4h->len < GET_IP4_ICMP4_HDR_SIZE(input) + 8 + IP4_HDR_SIZE ||
+	    ip4h->len < GET_IP4_ICMP4_HDR_SIZE(input) + 8 + (IP4_VHL_HL(sip4h->vhl) << 2)) {
+		NET_COUNT_ICMP4(net_count_icmp4.in_err_packets, 1);
+		return;
+		}
+
+	in4_rtredirect(icmp4h->data.addr, sip4h->dst, IN_RTF_REDIRECT, TMO_IN_REDIRECT);
+	}
+
+#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if defined(NUM_REDIRECT_ROUTE_ENTRY) */
+
+/*
+ *  icmp_input -- ICMP の入力関数
+ *
+ *    input には IF ヘッダと IP ヘッダも含まれている。
+ */
+
+uint_t
+icmp_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+	T_NET_BUF	*input = *inputp;
+	T_ICMP4_HDR	*icmp4h;
+	T_IN4_ADDR	addr;
+	uint_t		len, align;
+
+	NET_COUNT_ICMP4(net_count_icmp4.in_octets,
+	               input->len - GET_IF_IP4_HDR_SIZE(input));
+	NET_COUNT_ICMP4(net_count_icmp4.in_packets, 1);
+
+	/* ICMP ヘッダの長さをチェックする。*/
+	if (input->len < IF_IP4_ICMP4_HDR_SIZE) {
+		NET_COUNT_ICMP4(net_count_icmp4.in_err_packets, 1);
+		NET_COUNT_MIB(icmp_stats.icmpInErrors, 1);
+		goto buf_rel;
+		}
+
+	icmp4h = (T_ICMP4_HDR *)(input->buf + *offp);
+
+	/* 4 オクテット境界のデータ長 */
+	len   = input->len - *offp;
+	align = (len + 3) >> 2 << 2;
+
+	/* 4 オクテット境界までパディングで埋める。*/
+	if (align > len)
+		memset((uint8_t*)input->buf + input->len, 0, (size_t)(align - len));
+
+	/* チェックサムを計算する。*/
+	if (in_cksum(icmp4h, align) != 0) {
+		NET_COUNT_ICMP4(net_count_icmp4.in_err_packets, 1);
+		goto buf_rel;
+		}
+
+	/* メッセージの型により分岐する。*/
+	switch (icmp4h->type) {
+	case ICMP4_ECHO_REQUEST:
+		icmp_echo(input, *offp);
+		return IPPROTO_DONE;
+		break;
+	case ICMP4_ECHO_REPLY:
+
+#if defined(SUPPORT_INET4) && defined(ICMP_CFG_CALLBACK_ECHO_REPLY)
+
+		icmp_echo_reply(input, *offp);
+
+#endif	/* of #if defined(SUPPORT_INET4) && defined(ICMP_CFG_CALLBACK_ECHO_REPLY) */
+
+		break;
+	case ICMP4_UNREACH:
+		icmp_unreach(input, *offp);
+		break;
+	case ICMP4_REDIRECT:
+
+#if defined(NUM_REDIRECT_ROUTE_ENTRY)
+#if NUM_REDIRECT_ROUTE_ENTRY > 0
+
+		addr = ntohl(icmp4h->data.addr);
+		syslog(LOG_INFO, "[ICMP] redirect, addr: %s.", ip2str(NULL, &addr));
+		icmp_redirect(input, *offp);
+
+#else	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+
+		addr = ntohl(icmp4h->data.addr);
+		syslog(LOG_INFO, "[ICMP] redirect ignored, addr: %s.", ip2str(NULL, &addr));
+
+#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#else	/* of #if defined(NUM_REDIRECT_ROUTE_ENTRY) */
+
+		addr = ntohl(icmp4h->data.addr);
+		syslog(LOG_INFO, "[ICMP] redirect ignored, addr: %s.", ip2str(NULL, &addr));
+
+#endif	/* of #if defined(NUM_REDIRECT_ROUTE_ENTRY) */
+
+		break;
+	default:
+		syslog(LOG_INFO, "[ICMP] unknown type: %d.", icmp4h->type);
+		NET_COUNT_ICMP4(net_count_icmp4.in_err_packets, 1);
+		break;
+		}
+
+buf_rel:
+	syscall(rel_net_buf(input));
+	return IPPROTO_DONE;
+	}
+
+#ifdef ICMP_REPLY_ERROR
+
+/*
+ *  icmp_error -- ICMP エラー送信関数。
+ *
+ *    input には IF ヘッダと IP ヘッダも含まれている。
+ *    icmp_error では、ネットワークバッファ input を返却しないので、
+ *    呼出し側で、開放してから終了する。	
+ */
+
+void
+icmp_error (uint8_t code, T_NET_BUF *input)
+{
+	T_IP4_HDR	*ip4h;
+	T_ICMP4_HDR	*icmp4h;
+	T_NET_BUF	*output;
+	T_IN4_ADDR	saddr;
+	uint_t		len, ip4hl, align;
+
+	ip4h  = GET_IP4_HDR(input);
+	ip4hl = GET_IP4_HDR_SIZE(input);
+
+	/* 送信用の IP データグラムを獲得する。*/
+	if (input->len - ip4hl < 8)
+		len = input->len - ip4hl;
+	else
+		len = 8;
+	
+	saddr = ntohl(ip4h->src);
+	if (in4_get_datagram(&output, (uint_t)(ICMP4_HDR_SIZE + ip4hl + len), 0,
+	                     &saddr, NULL, IPPROTO_ICMP, IP4_DEFTTL, 
+	                     NBA_SEARCH_ASCENT, TMO_ICMP_OUTPUT) != E_OK)
+		return;
+
+	/* ICMP ヘッダを設定する。*/
+	icmp4h		= GET_ICMP4_HDR(output, IF_IP4_ICMP4_HDR_OFFSET);
+	icmp4h->type	= ICMP4_UNREACH;
+	icmp4h->code	= code;
+	icmp4h->data.addr= 0;
+
+	/* エラーが発生した IP ヘッダと データ 8 オクテットをコピーする。*/
+	memcpy(GET_ICMP4_SDU(output, IF_IP4_ICMP4_HDR_OFFSET),
+	       GET_IP4_HDR(input), (size_t)(ip4hl + len));
+
+	/* 4 オクテット境界のデータ長 */
+	align = (len + 3) >> 2 << 2;
+
+	/* 4 オクテット境界までパディングで埋める。*/
+	if (align > len)
+		memset((uint8_t*)GET_ICMP4_SDU(output, IF_IP4_ICMP4_HDR_OFFSET) + ip4hl + len,
+		       0, (size_t)(align - len));
+
+	/* チェックサムを計算する。*/
+	icmp4h->sum = 0;
+	icmp4h->sum = in_cksum(icmp4h, (uint_t)(ICMP4_HDR_SIZE + ip4hl + align));
+
+	/* 送信する。*/
+	NET_COUNT_ICMP4(net_count_icmp4.out_octets,
+	               output->len - GET_IF_IP4_HDR_SIZE(output));
+	NET_COUNT_ICMP4(net_count_icmp4.out_packets, 1);
+	NET_COUNT_MIB(icmp_stats.icmpOutMsgs, 1);
+	NET_COUNT_MIB(icmp_stats.icmpOutDestUnreachs, 1);
+	ip_output(output, TMO_ICMP_OUTPUT);
+	}
+
+#endif	/* of #ifdef ICMP_REPLY_ERROR */
+
+#endif	/* of #if defined(_IP4_CFG) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_icmp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_icmp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_icmp.h	(revision 398)
@@ -0,0 +1,187 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip_icmp.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/ip_icmp.h,v 1.12.2.2 1999/11/18 08:51:44 peter Exp $
+ */
+ 
+#ifndef _IP_ICMP_H_
+#define _IP_ICMP_H_
+
+#include <netinet/icmp6.h>
+
+/*
+ *  ICMP ヘッダの定義、RFC 792
+ */
+
+typedef struct t_icmp_hdr {
+	uint8_t		type;		/* メッセージの型	*/
+	uint8_t		code;		/* サブ型		*/
+	uint16_t	sum;		/* チェックサム		*/
+	union {
+		struct id_seq {
+			uint16_t	id;
+			uint16_t	seq;
+			} id_seq;
+		T_IN4_ADDR	addr;
+		} data;
+	} __attribute__((packed, aligned(2)))T_ICMP4_HDR;
+
+#define ICMP4_HDR_SIZE			(sizeof(T_ICMP4_HDR))
+#define IP4_ICMP4_HDR_SIZE		(IP4_HDR_SIZE + ICMP4_HDR_SIZE)
+#define IF_IP4_ICMP4_HDR_SIZE		(IF_IP4_HDR_SIZE + ICMP4_HDR_SIZE)
+#define IF_IP4_ICMP4_HDR_OFFSET		(IF_IP4_HDR_SIZE)
+
+#define GET_ICMP4_HDR(nbuf,ihoff)	((T_ICMP4_HDR*)((uint8_t*)((nbuf)->buf) + ihoff))
+#define GET_ICMP4_SDU(nbuf,ihoff)	((uint8_t*)((nbuf)->buf) + ihoff + ICMP4_HDR_SIZE)
+
+#define GET_ICMP4_HDR_OFFSET(nbuf)	(GET_IF_IP4_HDR_SIZE(nbuf))
+
+#define GET_IP4_ICMP4_HDR_SIZE(nbuf)	(GET_IP4_HDR_SIZE(nbuf) + ICMP4_HDR_SIZE)
+#define GET_IF_IP4_ICMP4_HDR_SIZE(nbuf)	(IF_HDR_SIZE + GET_IP4_ICMP4_HDR_SIZE(nbuf))
+
+/*
+ *  メッセージの型
+ */
+
+#define ICMP4_ECHO_REPLY	UINT_C(0)	/* エコー応答		*/
+#define ICMP4_UNREACH		UINT_C(3)	/* エラー		*/
+#define ICMP4_SOURCE_QUENCH	UINT_C(4)	/* 発信制限		*/
+#define ICMP4_REDIRECT		UINT_C(5)	/* 方向変更		*/
+#define ICMP4_ECHO_REQUEST	UINT_C(8)	/* エコー要求		*/
+#define ICMP4_TIME_EXCEEDED	UINT_C(11)	/* 発信制限		*/
+#define ICMP4_PARAMETER		UINT_C(12)	/* パラメータ異常	*/
+#define ICMP4_TIME_REQUEST	UINT_C(13)	/* タイムスタンプ要求	*/
+#define ICMP4_TIME_REPLY	UINT_C(14)	/* タイムスタンプ応答	*/
+#define ICMP4_MASK_REQUEST	UINT_C(17)	/* アドレスマスク要求	*/
+#define ICMP4_MASK_REPLY	UINT_C(18)	/* アドレスマスク応答	*/
+
+/*
+ *  サブ型
+ */
+
+/* ICMP4_UNREACH (3)	*/
+
+#define ICMP4_UNREACH_NET		UINT_C(0)	/* ネットワーク		*/
+#define ICMP4_UNREACH_HOST		UINT_C(1)	/* ホスト		*/
+#define ICMP4_UNREACH_PROTOCOL		UINT_C(2)	/* プロトコル		*/
+#define ICMP4_UNREACH_PORT		UINT_C(3)	/* ポート		*/
+#define ICMP4_UNREACH_FLAG		UINT_C(4)	/* 分割			*/
+#define ICMP4_UNREACH_SRC_FAIL		UINT_C(5)	/* ソース経路		*/
+#define ICMP4_UNREACH_NET_UNKNOWN	UINT_C(6)	/* ネットワーク不明	*/
+#define ICMP4_UNREACH_HOST_UNKNOWN	UINT_C(7)	/* ホスト不明		*/
+#define ICMP4_UNREACH_ISOLATED		UINT_C(8)	/* 分離			*/
+#define ICMP4_UNREACH_NET_PROHIB	UINT_C(9)	/* 			*/
+#define ICMP4_UNREACH_HOST_PROHIB	UINT_C(10)	/* 			*/
+#define ICMP4_UNREACH_TOS_NET		UINT_C(11)	/* ネットワークへの不正TOS*/
+#define ICMP4_UNREACH_TOS_HOST		UINT_C(12)	/* ホストへの不正TOS	*/
+#define ICMP4_UNREACH_FILTER_PROHIB	UINT_C(13)	/* 			*/
+#define ICMP4_UNREACH_HOST_PRECEDENCE	UINT_C(14)	/* 			*/
+#define ICMP4_UNREACH_PRECEDENCE_CUTOFF	UINT_C(15)	/* 			*/
+
+/* ICMP4_REDIRECT (5)	*/
+
+#define ICMP4_REDIRECT_NET		UINT_C(0)	/* ネットワーク		*/
+#define ICMP4_REDIRECT_HOST		UINT_C(1)	/* ホスト		*/
+#define ICMP4_REDIRECT_PORT_AND_NET	UINT_C(2)	/* ポート番号とネット	*/
+#define ICMP4_REDIRECT_PORT_AND_HOST	UINT_C(3)	/* ポート番号とホスト	*/
+
+/*
+ *  全域変数
+ */
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+#ifndef ICMP_REPLY_ERROR
+
+#define _tinet_icmp_error(code,data)
+
+#endif	/* of #ifdef ICMP_REPLY_ERROR */
+
+/*
+ *  関数
+ */
+
+extern uint_t icmp_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+
+#ifdef ICMP_REPLY_ERROR
+
+extern void icmp_error (uint8_t code, T_NET_BUF *data);
+
+#endif	/* of #ifdef ICMP_REPLY_ERROR */
+
+/*
+ *  TINET 独自 API
+ */
+
+#ifdef ICMP_CFG_CALLBACK_ECHO_REPLY
+
+extern void icmp_echo_reply (T_NET_BUF *input, uint_t ihoff);
+
+#endif	/* of #ifdef ICMP_CFG_CALLBACK_ECHO_REPLY */
+
+#endif	/* of #ifndef _IP_ICMP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_igmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_igmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_igmp.c	(revision 398)
@@ -0,0 +1,401 @@
+/*
+*  TINET (TCP/IP Protocol Stack)
+*
+*  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
+*                   Tomakomai National College of Technology, JAPAN
+*
+*  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation
+*  によって公表されている GNU General Public License の Version 2 に記
+*  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+*  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+*  利用と呼ぶ）することを無償で許諾する．
+*  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+*      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+*      スコード中に含まれていること．
+*  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+*      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+*      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+*      の無保証規定を掲載すること．
+*  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+*      用できない形で再配布する場合には，次の条件を満たすこと．
+*    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+*        作権表示，この利用条件および下記の無保証規定を掲載すること．
+*  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+*      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+*
+*  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+*  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+*  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+*  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+*
+*  @(#) $Id$
+*/
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+#include <netinet/ip_igmp.h>
+
+#include <net/if_var.h>
+#include <net/net_var.h>
+
+#ifdef SUPPORT_IGMP
+
+static T_IGMP_ENTRY igmp_groups[NUM_IGMP_ENTRY];
+static T_IN4_ADDR igmp_send_addrs[NUM_IGMP_ENTRY];
+
+static bool_t igmp_send_report_v2(T_IN4_ADDR dst);
+static int16_t igmp_get_timer(T_IGMP_ENTRY *entry);
+
+ER igmp_set_loop(T_UDP_CEP *cep, uint8_t optval)
+{
+	switch (optval) {
+	case 0:
+		cep->igmp_loopback = false;
+		return E_OK;
+	case 1:
+		cep->igmp_loopback = true;
+		return E_OK;
+	}
+
+	return E_PAR;
+}
+
+ER igmp_get_loop(T_UDP_CEP *cep, uint8_t *optval)
+{
+	if (optval == NULL)
+		return E_PAR;
+
+	*optval = cep->igmp_loopback ? 1 : 0;
+
+	return E_OK;
+}
+
+ER igmp_set_ttl(T_UDP_CEP *cep, uint8_t optval)
+{
+	cep->igmp_ttl = optval;
+
+	return E_OK;
+}
+
+ER igmp_get_ttl(T_UDP_CEP *cep, uint8_t *optval)
+{
+	if (optval == NULL)
+		return E_PAR;
+
+	*optval = cep->igmp_ttl;
+
+	return E_OK;
+}
+
+ER igmp_set_if(T_UDP_CEP *cep, T_IN4_ADDR *optval)
+{
+	if (optval == NULL)
+		return E_PAR;
+
+	cep->igmp_mcaddr = *optval;
+
+	return E_OK;
+}
+
+ER igmp_get_if(T_UDP_CEP *cep, T_IN4_ADDR *optval)
+{
+	if (optval == NULL)
+		return E_PAR;
+
+	*optval = cep->igmp_mcaddr;
+
+	return E_OK;
+}
+
+ER igmp_add_membership(T_UDP_CEP *cep, T_IP_MREQ *optval)
+{
+	T_IGMP_ENTRY *entry = NULL;
+	int		i;
+	T_IFNET	*ifp = IF_GET_IFNET();
+	ER ret = E_NOMEM;
+
+	if ((optval->imr_interface != IPV4_ADDRANY)
+		&& (optval->imr_interface != ifp->in4_ifaddr.addr))
+		return E_PAR;
+
+	syscall(wai_sem(SEM_IGMP_GROUP_LOCK));
+
+	for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+		entry = &igmp_groups[i];
+		if (entry->timer == -1) {
+			entry->timer = 0;
+			entry->ip_addr = optval->imr_multiaddr;
+			ret = E_OK;
+			break;
+		}
+	}
+
+	syscall(sig_sem(SEM_IGMP_GROUP_LOCK));
+
+	return ret;
+}
+
+ER igmp_drop_membership(T_UDP_CEP *cep, T_IP_MREQ *optval)
+{
+	T_IGMP_ENTRY *entry = NULL;
+	int		i;
+	ER ret = E_PAR;
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	if ((optval->imr_interface != IPV4_ADDRANY)
+		&& (optval->imr_interface != ifp->in4_ifaddr.addr))
+		return E_PAR;
+
+	syscall(wai_sem(SEM_IGMP_GROUP_LOCK));
+
+	for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+		entry = &igmp_groups[i];
+		if ((entry->timer >= 0) && (entry->ip_addr == optval->imr_multiaddr)) {
+			entry->timer = -1;
+			entry->ip_addr = 0;
+			ret = E_OK;
+			break;
+		}
+	}
+
+	syscall(sig_sem(SEM_IGMP_GROUP_LOCK));
+
+	return ret;
+}
+
+ER igmp_set_ip_msfilter(T_UDP_CEP *cep, const T_IP_MSFILTER *optval)
+{
+	return E_PAR;
+}
+
+ER igmp_get_ip_msfilter(T_UDP_CEP *cep, T_IP_MSFILTER *optval)
+{
+	return E_PAR;
+}
+
+uint_t igmp_input(T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+	T_NET_BUF	*input = *inputp;
+	T_IGMPV2_HDR	*igmph;
+	uint_t		len, align;
+	T_IP4_HDR	*ip4h;
+	int i;
+	T_IGMP_ENTRY *entry;
+	bool_t ret;
+
+	NET_COUNT_IGMP(net_count_igmp.in_octets,
+		input->len - GET_IF_IP4_HDR_SIZE(input));
+	NET_COUNT_IGMP(net_count_igmp.in_packets, 1);
+
+	/* ICMP ヘッダの長さをチェックする。*/
+	if (input->len < IF_IP4_IGMP_HDR_SIZE) {
+		NET_COUNT_IGMP(net_count_igmp.in_err_packets, 1);
+		NET_COUNT_MIB(igmp_stats.igmpInErrors, 1);
+		goto buf_rel;
+	}
+
+	igmph = (T_IGMPV2_HDR *)(input->buf + *offp);
+
+	/* 4 オクテット境界のデータ長 */
+	len = input->len - *offp;
+	align = (len + 3) >> 2 << 2;
+
+	/* 4 オクテット境界までパディングで埋める。*/
+	if (align > len)
+		memset((uint8_t*)input->buf + input->len, 0, (size_t)(align - len));
+
+	/* チェックサムを計算する。*/
+	if (in_cksum(igmph, align) != 0) {
+		NET_COUNT_IGMP(net_count_igmp.in_err_packets, 1);
+		goto buf_rel;
+	}
+
+	/* メッセージの型により分岐する。*/
+	switch (igmph->type) {
+	case IGMP_MEMBERSHIP_QUERY:
+		ip4h = GET_IP4_HDR(input);
+		ret = false;
+
+		/* 参加中のグループアドレスからのクエリーの場合 */
+		syscall(wai_sem(SEM_IGMP_GROUP_LOCK));
+
+		for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+			entry = &igmp_groups[i];
+			if ((entry->timer >= 0) && (entry->ip_addr == igmph->addr)) {
+				entry->resptime = igmph->time;
+				ret = true;
+				break;
+			}
+		}
+
+		syscall(sig_sem(SEM_IGMP_GROUP_LOCK));
+
+		if (ret) {
+			/* メンバーシップリポートを送信 */
+			igmp_send_report_v2(ip4h->src);
+		}
+		break;
+	}
+
+buf_rel:
+	syscall(rel_net_buf(input));
+	return IPPROTO_DONE;
+}
+
+static bool_t igmp_send_report_v2(T_IN4_ADDR dst)
+{
+	T_IGMPV2_HDR	*igmph;
+	T_NET_BUF		*output;
+	uint_t			len = 0, align;
+
+	if (in4_get_datagram(&output, (uint_t)(IF_IP4_IGMP_HDR_SIZE + len), 0,
+		&dst, NULL, IPPROTO_IGMP, IP4_DEFTTL,
+		NBA_SEARCH_ASCENT, TMO_IGMP_OUTPUT) != E_OK)
+		return false;
+
+	/* IGMP ヘッダを設定する。*/
+	igmph = GET_IGMPV2_HDR(output, IF_IP4_IGMP_HDR_OFFSET);
+	igmph->type = IGMP_MEMBERSHIP_REPORT_V2;
+	igmph->time = 0;
+	igmph->addr = htonl(dst);
+
+	/* 4 オクテット境界のデータ長 */
+	align = (len + 3) >> 2 << 2;
+
+	/* 4 オクテット境界までパディングで埋める。*/
+	if (align > len)
+		memset((uint8_t*)GET_IGMP_SDU(output, IF_IP4_IGMP_HDR_OFFSET) + len,
+			0, (size_t)(align - len));
+
+	/* チェックサムを計算する。*/
+	igmph->sum = 0;
+	igmph->sum = in_cksum(igmph, (uint_t)(IGMP_HDR_SIZE + align));
+
+	/* 送信する。*/
+	NET_COUNT_IGMP(net_count_igmp.out_octets,
+		output->len - GET_IF_IP4_HDR_SIZE(output));
+	NET_COUNT_IGMP(net_count_igmp.out_packets, 1);
+	NET_COUNT_MIB(icmp_stats.icmpOutMsgs, 1);
+	NET_COUNT_MIB(icmp_stats.icmpOutDestUnreachs, 1);
+	ip_output(output, TMO_IGMP_OUTPUT);
+
+	return true;
+}
+
+/*
+*  igmp_timer -- IGMP 共通タイマー
+*/
+static void igmp_timer(void *ignore)
+{
+	T_IGMP_ENTRY *entry = NULL;
+	int i, j = 0;
+
+	/* memset(igmp_send_addrs, 0, sizeof(igmp_send_addrs)); */
+
+	syscall(wai_sem(SEM_IGMP_GROUP_LOCK));
+
+	for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+		entry = &igmp_groups[i];
+		if (entry->timer > 0)
+			entry->timer--;
+		if (entry->timer == 0) {
+			entry->timer = igmp_get_timer(entry);
+			igmp_send_addrs[j++] = entry->ip_addr;
+		}
+	}
+
+	syscall(sig_sem(SEM_IGMP_GROUP_LOCK));
+
+	for (i = 0; i < j; i++) {
+		igmp_send_report_v2(igmp_send_addrs[i]);
+	}
+
+	timeout(igmp_timer, NULL, NET_TIMER_HZ / 1);
+}
+
+/*
+*  igmp_init -- IGMP 機能を初期化する。
+*/
+
+void igmp_init(void)
+{
+	int i;
+
+	for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+		igmp_groups[i].timer = -1;
+	}
+
+	timeout(igmp_timer, NULL, NET_TIMER_HZ / 1);
+}
+
+bool_t igmp_is_joined_group(T_IN4_ADDR addr)
+{
+	T_IGMP_ENTRY *entry = NULL;
+	int		i;
+	bool_t ret = false;
+
+	syscall(wai_sem(SEM_IGMP_GROUP_LOCK));
+
+	for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+		entry = &igmp_groups[i];
+		if ((entry->timer >= 0) && (entry->ip_addr == addr)) {
+			ret = true;
+			break;
+		}
+	}
+
+	syscall(sig_sem(SEM_IGMP_GROUP_LOCK));
+
+	return ret;
+}
+
+int16_t igmp_get_timer(T_IGMP_ENTRY *entry)
+{
+	int16_t time = entry->resptime;
+
+	if (time == 0)
+		time = 590;
+
+	return (int16_t)(net_rand() % time) + 10;
+}
+
+#endif /* of #ifdef SUPPORT_IGMP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_igmp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_igmp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_igmp.cfg	(revision 398)
@@ -0,0 +1,44 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  IGMP コンフィギュレーションファイル
+ */
+
+#if defined(_IP4_CFG) && defined(SUPPORT_IGMP)
+
+/* IGMP グループ更新用セマフォ */
+
+CRE_SEM(SEM_IGMP_GROUP_LOCK, { TA_TPRI, 1, 1 });
+
+#endif	/* of #if defined(_IP4_CFG) && defined(SUPPORT_IGMP) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_igmp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_igmp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_igmp.h	(revision 398)
@@ -0,0 +1,164 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ *
+ *  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+#ifndef _IP_IGMP_H_
+#define _IP_IGMP_H_
+
+#define NUM_IGMP_ENTRY				5	/* マルチキャストグループのエントリ数 */
+
+ /*
+  *  IGMPv1 ヘッダの定義、RFC 1112
+  */
+
+typedef struct t_igmpv1_hdr
+{
+	uint8_t		type;		/* メッセージの型	*/
+	uint8_t		unused;		/* 未使用			*/
+	uint16_t	sum;		/* チェックサム		*/
+	T_IN4_ADDR	addr;		/* グループアドレス */
+}  __attribute__((packed)) T_IGMPV1_HDR;
+
+/*
+*  IGMPv2 ヘッダの定義、RFC 2236
+*/
+
+typedef struct t_igmpv2_hdr
+{
+	uint8_t		type;		/* メッセージの型	*/
+	uint8_t		time;		/* 最大応答時間		*/
+	uint16_t	sum;		/* チェックサム		*/
+	T_IN4_ADDR	addr;		/* グループアドレス */
+}  __attribute__((packed)) T_IGMPV2_HDR;
+
+typedef struct t_igmpv3_query_hdr
+{
+	uint8_t		type;		/* メッセージの型	*/
+	uint8_t		time;		/* 最大応答時間		*/
+	uint16_t	sum;		/* チェックサム		*/
+	T_IN4_ADDR	grpaddr;	/* グループアドレス */
+	uint8_t		sqrv;		/* Sフラグ、Querier Robustness Value */
+	uint8_t		qqic;		/* Qurier's Query Interval Code */
+	uint16_t	num;		/* 送信元の数 */
+	T_IN4_ADDR	sdraddr;	/* 送信元アドレス */
+}  __attribute__((packed)) T_IGMPV3Q_HDR;
+
+typedef struct t_igmp_group_record
+{
+	uint8_t		type;		/* メッセージの型	*/
+	uint8_t		len;		/* 補助データ長		*/
+	uint16_t	num;		/* 送信元の数 */
+	T_IN4_ADDR	grpaddr;	/* グループアドレス */
+	T_IN4_ADDR	sdraddr;	/* 送信元アドレス	*/
+							/* 補助データ		*/
+}  __attribute__((packed)) T_IGMP_GROUP_RECORD;
+
+typedef struct t_igmpv3_report_hdr
+{
+	uint8_t		type;		/* メッセージの型	*/
+	uint8_t		rsv1;		/* 予約				*/
+	uint16_t	sum;		/* チェックサム		*/
+	uint16_t	rsv2;		/* 予約				*/
+	uint16_t	num;		/* グループレコードの数 */
+	T_IGMP_GROUP_RECORD record;	/* グループレコード */
+}  __attribute__((packed)) T_IGMPV3R_HDR;
+
+#define IGMP_HDR_SIZE			(sizeof(T_IGMPV1_HDR))
+#define IP4_IGMP_HDR_SIZE		(IP4_HDR_SIZE + IGMP_HDR_SIZE)
+#define IF_IP4_IGMP_HDR_SIZE		(IF_IP4_HDR_SIZE + IGMP_HDR_SIZE)
+#define IF_IP4_IGMP_HDR_OFFSET		(IF_IP4_HDR_SIZE)
+
+#define GET_IGMPV1_HDR(nbuf,ihoff)	((T_IGMPV1_HDR*)((uint8_t*)((nbuf)->buf) + ihoff))
+#define GET_IGMPV2_HDR(nbuf,ihoff)	((T_IGMPV2_HDR*)((uint8_t*)((nbuf)->buf) + ihoff))
+#define GET_IGMPV3Q_HDR(nbuf,ihoff)	((T_IGMPV3Q_HDR*)((uint8_t*)((nbuf)->buf) + ihoff))
+#define GET_IGMPV3R_HDR(nbuf,ihoff)	((T_IGMPV3R_HDR*)((uint8_t*)((nbuf)->buf) + ihoff))
+#define GET_IGMP_SDU(nbuf,ihoff)	((uint8_t*)((nbuf)->buf) + ihoff + IGMP_HDR_SIZE)
+
+/*
+*  メッセージの型
+*/
+
+#define IGMP_MEMBERSHIP_QUERY		0x11	/* メンバーシップクエリー		*/
+#define IGMP_MEMBERSHIP_REPORT		0x12	/* メンバーシップレポート		*/
+#define IGMP_MEMBERSHIP_REPORT_V2	0x16	/* メンバーシップレポート		*/
+#define IGMP_LEAVE_GROUP			0x17	/* リーブグループ				*/
+#define IGMP_MEMBERSHIP_REPORT_V3	0x22	/* メンバーシップレポート		*/
+
+/*
+*  UDP通信端点オプション
+*/
+
+typedef struct ip_mreq
+{
+	T_IN4_ADDR imr_multiaddr; /* IP multicast address of group */
+	T_IN4_ADDR imr_interface; /* local IP address of interface */
+} T_IP_MREQ;
+
+typedef struct ip_msfilter
+{
+	T_IN4_ADDR imsf_multiaddr;     /* IP multicast group address */
+	T_IN4_ADDR imsf_interface;     /* IP address of local interface */
+	uint32_t   imsf_fmode;         /* Filter-mode */
+	uint32_t   imsf_numsrc;        /* Number of sources in the following array */
+	T_IN4_ADDR imsf_slist[1];      /* Array of source addresses */
+} T_IP_MSFILTER;
+
+#define MCAST_INCLUDE     1
+#define MCAST_EXCLUDE     2
+
+extern ER igmp_set_loop(T_UDP_CEP *cep, uint8_t optval);
+extern ER igmp_get_loop(T_UDP_CEP *cep, uint8_t *optval);
+extern ER igmp_set_ttl(T_UDP_CEP *cep, uint8_t optval);
+extern ER igmp_get_ttl(T_UDP_CEP *cep, uint8_t *optval);
+extern ER igmp_set_if(T_UDP_CEP *cep, T_IN4_ADDR *optval);
+extern ER igmp_get_if(T_UDP_CEP *cep, T_IN4_ADDR *optval);
+extern ER igmp_add_membership(T_UDP_CEP *cep, T_IP_MREQ *optval);
+extern ER igmp_drop_membership(T_UDP_CEP *cep, T_IP_MREQ *optval);
+extern ER igmp_set_ip_msfilter(T_UDP_CEP *cep, const T_IP_MSFILTER *optval);
+extern ER igmp_get_ip_msfilter(T_UDP_CEP *cep, T_IP_MSFILTER *optval);
+
+/*
+ *  IGMP グループエントリ
+ */
+
+typedef struct igmp_entry
+{
+	int16_t		timer;		/* 送信までの時間[秒]	*/
+	int16_t		resptime;	/* 最大応答時間[秒]	*/
+	T_IN4_ADDR	ip_addr;	/* IP アドレス			*/
+} T_IGMP_ENTRY;
+
+extern void igmp_init(void);
+extern bool_t igmp_is_joined_group(T_IN4_ADDR addr);
+extern uint_t igmp_input(T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+
+#endif	/* of #ifndef _IP_IGMP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_input.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_input.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_input.c	(revision 398)
@@ -0,0 +1,608 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)input.c	8.2 (Berkeley) 1/4/94
+ * $FreeBSD: src/sys/netinet/input.c,v 1.111.2.4 1999/11/01 22:23:53 des Exp $
+ *	$ANA: input.c,v 1.5 1996/09/18 14:34:59 wollman Exp $
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/ip_igmp.h>
+
+#if defined(SUPPORT_IPSEC)
+//#include <stdio.h>
+#include <sys/types.h>
+#include <netinet6/ipsec.h>
+#include <netinet6/esp.h>
+#include <netkey/key.h>
+#include <netkey/key_debug.h>
+#endif /* of defined(SUPPORT_IPSEC) */
+
+#include <net/if_var.h>
+
+#if defined(_IP4_CFG)
+
+/*
+ *  変数
+ */
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+T_IP_STATS ip_stats;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+#ifdef IP4_CFG_FRAGMENT
+
+/*
+ *  データグラム再構成キュー
+ */
+
+static T_NET_BUF	*ip_frag_queue[NUM_IP4_FRAG_QUEUE];
+static T_IN4_ADDR	    frag_dst  [NUM_IP4_FRAG_QUEUE];
+
+/*
+ *  関数
+ */
+
+static void ip_freef (int_t ix);
+static T_NET_BUF *ip_reass (T_IP4_HDR *ip4h, T_NET_BUF *input);
+
+/*
+ *  ip_get_frag_queue -- データグラム再構成キューを獲得する。
+ */
+
+const T_NET_BUF **
+ip_get_frag_queue (void)
+{
+	return (const T_NET_BUF **)ip_frag_queue;
+	}
+
+/*
+ *  ip_freef -- データグラム再構成キューを解放する。
+ */
+
+static void
+ip_freef (int_t ix)
+{
+	T_NET_BUF	*frag, *next;
+
+	frag = ip_frag_queue[ix];
+	while (frag != NULL) {
+		next = GET_QIP4_HDR(frag)->next;
+		syscall(rel_net_buf(frag));
+		frag = next;
+		}
+	ip_frag_queue[ix] = NULL;
+	}
+
+/*
+ *  ip_frag_timer -- データグラム再構成管理タイマ
+ */
+
+void
+ip_frag_timer (void)
+{
+	T_NET_BUF	*frag;
+	int_t		ix;
+
+	syscall(wai_sem(SEM_IP4_FRAG_QUEUE));
+	for (ix = NUM_IP4_FRAG_QUEUE; ix -- > 0; ) {
+		frag = ip_frag_queue[ix];
+		if (frag != NULL && GET_QIP4_HDR(frag)->ttl > 0 &&
+		    -- GET_QIP4_HDR(frag)->ttl == 0) {
+			NET_COUNT_IP4(net_count_ip4[NC_IP4_FRAG_IN_TMOUT], 1);
+			NET_COUNT_IP4(net_count_ip4[NC_IP4_FRAG_IN_DROP], 1);
+			ip_freef(ix);
+			}
+		}
+	syscall(sig_sem(SEM_IP4_FRAG_QUEUE));
+	}
+
+/*
+ *  ip_reass -- データグラムを再構成する。
+ */
+
+static T_NET_BUF *
+ip_reass (T_IP4_HDR *ip4h, T_NET_BUF *input)
+{
+	T_NET_BUF	*frag, *prev;
+	T_IN4_ADDR	dst, src;
+	int_t		ix;
+	uint_t		id, off, len;
+
+	NET_COUNT_IP4(net_count_ip4[NC_IP4_FRAG_IN_FRAGS], 1);
+	NET_COUNT_MIB(ip_stats.ipReasmReqds, 1);
+
+	src = ntohl(ip4h->src);
+	dst = ntohl(ip4h->dst);
+	NTOHS(ip4h->id);
+	NTOHS(ip4h->flg_off);
+	id = ip4h->id;
+	ix = id % NUM_IP4_FRAG_QUEUE;
+
+	syscall(wai_sem(SEM_IP4_FRAG_QUEUE));
+
+	/*
+	 *  ID、IPアドレス、上位プロトコルが異なるフラグメントがキューに有れば破棄する。
+	 */
+	frag = ip_frag_queue[ix];
+	if (frag != NULL &&
+	    (id  != GET_IP4_HDR(frag)->id  ||
+	     dst != frag_dst[ix] ||
+	     src != ntohl(GET_IP4_HDR(frag)->src) ||
+	     ip4h->proto != GET_IP4_HDR(frag)->proto)) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_FRAG_IN_DROP], 1);
+		NET_COUNT_MIB(ip_stats.ipReasmFails, 1);
+		ip_freef(ix);
+		}
+
+	frag = ip_frag_queue[ix];
+	if (frag == NULL) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_FRAG_IN], 1);
+
+		/* 新規の ID なら、宛先アドレスを保存して、キューにつなぐ。*/
+		frag_dst  [ix] = dst;
+		ip_frag_queue[ix] = input;
+		((T_QIP4_HDR *)ip4h)->next = NULL;
+		input = NULL;
+
+		/* 再構成タイムアウトを設定する。*/
+		ip4h->ttl = IP4_FRAGTTL;
+		}
+	else {
+
+		/* 正しい位置に挿入する。*/
+		prev = NULL;
+		while (frag != NULL &&
+		       IP4_FLGOFF_OFF(ip4h->flg_off) >
+		       IP4_FLGOFF_OFF(GET_QIP4_HDR(frag)->flg_off)) {
+			prev = frag;
+			frag = GET_QIP4_HDR(frag)->next;
+			}
+		((T_QIP4_HDR *)ip4h)->next = frag;
+		if (prev == NULL) {
+			ip4h->ttl      = GET_QIP4_HDR(frag)->ttl;
+			ip_frag_queue[ix] = input;
+			}
+		else
+			GET_QIP4_HDR(prev)->next = input;
+		input = NULL;
+
+		/* 全てのフラグメントが揃っているか調べる。*/
+		off = 0;
+		for (frag = ip_frag_queue[ix]; frag != NULL; frag = GET_QIP4_HDR(frag)->next) {
+			if ((IP4_FLGOFF_OFF(GET_QIP4_HDR(frag)->flg_off) << 3) != off) {
+				/* 途中が抜けていたら終了する。*/
+				syscall(sig_sem(SEM_IP4_FRAG_QUEUE));
+				return NULL;
+				}
+			off += ntohs(GET_QIP4_HDR(frag)->len) - (IP4_VHL_HL(GET_QIP4_HDR(frag)->vhl) << 2);
+			prev = frag;				
+			}
+
+		/* 全てのフラグメントが揃ったら再構成する。*/
+		if ((GET_QIP4_HDR(prev)->flg_off & IP4_MF) == 0) {
+
+			/* ネットワークバッファを獲得する。*/
+			if (tget_net_buf(&input, IF_IP4_HDR_SIZE + off, TMO_IP4_FRAG_GET_NET_BUF) == E_OK) {
+				NET_COUNT_IP4(net_count_ip4[NC_IP4_FRAG_IN_OK], 1);
+				NET_COUNT_MIB(ip_stats.ipReasmOKs, 1);
+
+				/* IPv4 ヘッダを設定する。*/
+				frag  = ip_frag_queue[ix];
+				ip4h  = GET_IP4_HDR(input);
+				*ip4h = *GET_IP4_HDR(frag);
+				ip4h->dst     = htonl(frag_dst[ix]);
+				ip4h->len     = htons(IP4_HDR_SIZE + off);
+				ip4h->vhl     = IP4_MAKE_VHL(IPV4_VERSION, IP4_HDR_SIZE >> 2);
+				ip4h->ttl     = GET_QIP4_HDR(prev)->ttl;
+				ip4h->flg_off = ip4h->id = 0;
+
+				/* データグラムを再構成する。*/
+				off = IP4_HDR_SIZE;
+				while (frag != NULL) {
+					len = ntohs(GET_QIP4_HDR(frag)->len) - (IP4_VHL_HL(GET_QIP4_HDR(frag)->vhl) << 2);
+					memcpy((uint8_t *)ip4h + off, GET_QIP4_SDU(frag), len);
+					off += len;
+					frag = GET_QIP4_HDR(frag)->next;
+					}
+				}
+			else {
+				NET_COUNT_IP4(net_count_ip4[NC_IP4_FRAG_IN_NO_BUF], 1);
+				NET_COUNT_IP4(net_count_ip4[NC_IP4_FRAG_IN_DROP], 1);
+				NET_COUNT_MIB(ip_stats.ipReasmFails, 1);
+				}
+			/* キューを空にする。*/
+			ip_freef(ix);
+			}
+		}
+	syscall(sig_sem(SEM_IP4_FRAG_QUEUE));
+	return input;
+	}
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+/*
+ *  ip_init -- IP の初期化
+ */
+
+void
+ip_init (void)
+{
+	in4_init();
+	}
+
+/*
+ *  ip_remove_options -- IPv4 ヘッダのオプションを削除し、以降を前に詰める。
+ */
+
+ER
+ip_remove_options (T_NET_BUF *nbuf)
+{
+	T_IP4_HDR	*iph;
+	uint_t		hdr_size;
+
+	iph  = GET_IP4_HDR(nbuf);
+	hdr_size = GET_IP4_HDR_SIZE(nbuf);
+
+	if (hdr_size > IP4_HDR_SIZE) {
+		memmove((char *)iph + IP4_HDR_SIZE, GET_IP4_SDU(nbuf),
+		        (size_t)(iph->len - hdr_size));
+		iph->vhl   = IP4_MAKE_VHL(IPV4_VERSION, IP4_HDR_SIZE >> 2);
+		iph->len  -= (uint16_t)(hdr_size - IP4_HDR_SIZE);
+		nbuf->len -= (uint16_t)(hdr_size - IP4_HDR_SIZE);
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  ip_input -- IP の入力関数
+ */
+
+#if defined(SUPPORT_IPSEC)
+/*
+ * TODO: IPsec SPを検索し、パケットをリジェクトするかどうか判定する処理を実装する
+ */
+#endif /* of defined(SUPPORT_IPSEC) */
+
+void
+ip_input (T_NET_BUF *input)
+{
+	T_IP4_HDR	*ip4h;
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN4_ADDR	dst, src, bc;
+	uint_t		hlen, off;
+
+	NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_OCTETS], input->len - IF_HDR_SIZE);
+	NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_PACKETS], 1);
+	NET_COUNT_MIB(ip_stats.ipInReceives, 1);
+
+	/* IP ヘッダの長さをチェックする。*/
+	if (input->len < IF_IP4_HDR_SIZE) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_SHORT], 1);
+		NET_COUNT_MIB(ip_stats.ipInHdrErrors, 1);
+		goto buf_rel;
+		}
+
+	ip4h = GET_IP4_HDR(input);
+	hlen = GET_IP4_HDR_SIZE(input);
+
+	/* バージョンをチェックする。*/
+	if (IP4_VHL_V(ip4h->vhl) != IPV4_VERSION) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_VER], 1);
+		NET_COUNT_MIB(ip_stats.ipInHdrErrors, 1);
+		goto buf_rel;
+		}
+
+	/* IP ヘッダの長さをチェックし、オプションを解析する。*/
+	if (hlen > IP4_HDR_SIZE) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_OPTS], 1);
+		/* %%% オプションの解析 %%% */
+		}
+
+	/* データグラム長をチェックする。*/
+	if (ntohs(ip4h->len) > input->len - IF_HDR_SIZE) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_SHORT], 1);
+		NET_COUNT_MIB(ip_stats.ipInHdrErrors, 1);
+		goto buf_rel;
+		}
+
+	/* ネットワークバッファの長さをデータグラム長に調整する。*/
+	input->len = (uint16_t)(ntohs(ip4h->len) + IF_HDR_SIZE);
+
+	/* チェックサムをチェックする。*/
+	if (in_cksum(ip4h, hlen) != 0) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_CKSUM], 1);
+		NET_COUNT_MIB(ip_stats.ipInHdrErrors, 1);
+		goto buf_rel;
+		}
+
+	/* IP ヘッダの長さをチェックし、上位が ICMP 以外はオプションを消去する。*/
+	if (hlen > IP4_HDR_SIZE && ip4h->proto != IPPROTO_ICMP) {
+		memset((uint8_t*)ip4h + IP4_HDR_SIZE, 0, hlen - IP4_HDR_SIZE);
+		}
+
+	/* 送信元アドレスをチェックする。*/
+	src = ntohl(ip4h->src);
+	bc  = (ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask;
+
+#ifdef SUPPORT_LOOP
+
+	if (src == bc || src == IPV4_ADDR_BROADCAST || src == IPV4_ADDRANY) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_ADDR], 1);
+		NET_COUNT_MIB(ip_stats.ipInAddrErrors, 1);
+		goto buf_rel;
+		}
+
+#else	/* of #ifdef SUPPORT_LOOP */
+
+	if (src == ifp->in4_ifaddr.addr || src == bc || src == IPV4_ADDR_BROADCAST || src == IPV4_ADDRANY) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_ADDR], 1);
+		NET_COUNT_MIB(ip_stats.ipInAddrErrors, 1);
+		goto buf_rel;
+		}
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+	/* あて先アドレスをチェックする。*/
+	dst = ntohl(ip4h->dst);
+
+#ifdef DHCP_CFG
+
+	/*
+	 *  DHCP_CFG が定義されているときは、ローカルアドレスが未定義の
+	 *  場合もデータグラムを受信する。
+	 */
+
+#if defined(ETHER_CFG_MULTICAST)
+	if ((ifp->in4_ifaddr.addr != IPV4_ADDRANY) &&
+		(!(dst == ifp->in4_ifaddr.addr || dst == bc ||
+		   dst == IPV4_ADDR_BROADCAST  || dst == IPV4_ADDRANY ||
+		  IN4_IS_ADDR_MULTICAST(dst)))) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_ADDR], 1);
+		NET_COUNT_MIB(ip_stats.ipInAddrErrors, 1);
+		goto buf_rel;
+		}
+#else
+	if ((ifp->in4_ifaddr.addr != IPV4_ADDRANY) &&
+	    (!(dst == ifp->in4_ifaddr.addr || dst == bc ||
+	       dst == IPV4_ADDR_BROADCAST  || dst == IPV4_ADDRANY))) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_ADDR], 1);
+		NET_COUNT_MIB(ip_stats.ipInAddrErrors, 1);
+		goto buf_rel;
+		}
+#endif
+
+#else	/* of #ifdef DHCP_CFG */
+
+#if defined(ETHER_CFG_MULTICAST)
+	if (!(dst == ifp->in4_ifaddr.addr || dst == bc ||
+		  dst == IPV4_ADDR_BROADCAST || dst == IPV4_ADDRANY ||
+		  IN4_IS_ADDR_MULTICAST(dst))) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_ADDR], 1);
+		NET_COUNT_MIB(ip_stats.ipInAddrErrors, 1);
+		goto buf_rel;
+		}
+#else
+	if (!(dst == ifp->in4_ifaddr.addr || dst == bc ||
+	      dst == IPV4_ADDR_BROADCAST  || dst == IPV4_ADDRANY)) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_ADDR], 1);
+		NET_COUNT_MIB(ip_stats.ipInAddrErrors, 1);
+		goto buf_rel;
+		}
+#endif
+
+#endif	/* of #ifdef DHCP_CFG */
+
+#ifdef IP4_CFG_FRAGMENT
+
+	/* 分割されているかチェックする。*/
+	if (ntohs(ip4h->flg_off) & (IP4_MF | IP4_OFFMASK)) {
+		if ((input = ip_reass(ip4h, input)) == NULL)
+			return;
+		}
+
+#else	/* of #ifdef IP4_CFG_FRAGMENT */
+
+	/* 分割されているかチェックする。*/
+	if (ntohs(ip4h->flg_off) & (IP4_MF | IP4_OFFMASK)) {
+		T_IN4_ADDR	src;
+
+		NET_COUNT_MIB(ip_stats.ipReasmReqds, 1);
+		if ((ntohs(ip4h->flg_off) & IP4_OFFMASK) == 0) {
+			NET_COUNT_MIB(ip_stats.ipReasmFails, 1);
+			}
+		src = ntohl(ip4h->src);
+		syslog(LOG_WARNING, "[IP] flaged src: %s.", ip2str(NULL, &src));
+		goto buf_rel;
+		}
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+	off  = (uint_t)(GET_IP4_SDU(input) - input->buf);
+
+#if defined(SUPPORT_IPSEC)
+	/* ここでipsec4_in_rejectを実行する */
+	if ((ip4h->proto != IPPROTO_ESP) && ipsec4_in_reject (input)) {
+		goto buf_rel;
+	}
+#endif /* of #if defined(SUPPORT_IPSEC) */
+
+	/* プロトコルを選択する */
+	switch (ip4h->proto) {
+
+#if defined(SUPPORT_TCP)
+	case IPPROTO_TCP:
+		NET_COUNT_MIB(ip_stats.ipInDelivers, 1);
+		tcp_input(&input, &off, NULL);
+		return;
+		break;
+#endif	/* of #if defined(SUPPORT_TCP) */
+
+#if defined(SUPPORT_UDP) && ( (TNUM_UDP4_CEPID > 0) || \
+                             ((TNUM_UDP6_CEPID > 0) && defined(API_CFG_IP4MAPPED_ADDR)))
+	case IPPROTO_UDP:
+		NET_COUNT_MIB(ip_stats.ipInDelivers, 1);
+		udp4_input(&input, &off, NULL);
+		return;
+		break;
+#endif	/* of #if defined(SUPPORT_UDP) && TNUM_UDP4_CEPID > 0 */
+
+	case IPPROTO_ICMP:
+		NET_COUNT_MIB(ip_stats.ipInDelivers, 1);
+		icmp_input(&input, &off, NULL);
+		return;
+		break;
+
+#if defined(SUPPORT_IGMP)
+	case IPPROTO_IGMP:
+		NET_COUNT_MIB(ip_stats.ipInDelivers, 1);
+		igmp_input(&input, &off, NULL);
+		return;
+		break;
+#endif /* of #ifdef UDP_CFG_EXTENTIONS */
+
+#if defined(SUPPORT_IPSEC)
+	case IPPROTO_ESP:
+		NET_COUNT_MIB(ip_stats.ipInDelivers, 1);
+		esp4_input(input, &off);
+		return;
+		break;
+#endif /* of #if defined(SUPPORT_IPSEC) */
+
+	default:
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_PROTO], 1);
+		NET_COUNT_MIB(ip_stats.ipInUnknownProtos, 1);
+
+		/* ローカル IP アドレスに届いたデータグラムのみ ICMP エラーを通知する。*/
+		if (dst == ifp->in4_ifaddr.addr) {
+			T_IN4_ADDR	src;
+
+			src = ntohl(ip4h->src);
+			syslog(LOG_INFO, "[IP] unexp proto: %d, src=%s.", ip4h->proto, ip2str(NULL, &src));
+			icmp_error(ICMP4_UNREACH_PROTOCOL, input);
+			}
+		/*
+		 *  icmp_error では、ネットワークバッファ input を返却しないので
+		 *  開放してから終了する。
+		 */
+		break;
+		}
+
+buf_rel:
+	NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_PACKETS], 1);
+	syscall(rel_net_buf(input));
+	}
+
+#endif	/* of #if defined(_IP4_CFG) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_output.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_output.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_output.c	(revision 398)
@@ -0,0 +1,333 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)output.c	8.3 (Berkeley) 1/21/94
+ * $FreeBSD: src/sys/netinet/output.c,v 1.85.2.4 1999/08/29 16:29:49 peter Exp $
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#if defined(SUPPORT_IPSEC)
+#include <netinet6/ipsec.h>
+#endif
+
+#if defined(_IP4_CFG)
+
+static uint16_t frag_id = 0;
+
+/*
+ *  IP output -- IP の出力関数
+ *
+ *    注意: バージョンとヘッダ長は上位層で設定する。
+ */
+
+ER
+ip_output (T_NET_BUF *output, TMO tmout)
+{
+	T_IP4_HDR	*ip4h;
+	ER		error = E_OK;
+	T_IN4_ADDR	gw;
+
+#ifdef SUPPORT_IPSEC
+	T_SECPOLICY* sp;
+	int ipsec_error;
+        int policy;
+#endif /* SUPPORT_IPSEC */
+
+	NET_COUNT_MIB(ip_stats.ipOutRequests, 1);
+
+#ifdef SUPPORT_IPSEC
+        /* XXX: IPsecの処理はパケット断片化の前に行われる */
+
+	/* SPDを取得する */
+	sp = ipsec4_getpolicybyaddr(output, IPSEC_DIR_OUTBOUND, &ipsec_error);
+	if (sp==NULL) {
+                error = ipsec_error;
+                return error;
+        }
+
+        /* ポリシをチェックする*/
+#if 0
+        switch (sp->policy) {
+
+        case IPSEC_POLICY_BYPASS:
+        case IPSEC_POLICY_NONE:
+        case IPSEC_POLICY_TCP:
+                goto skip_ipsec;
+
+                break; /* NOTREACHED */
+
+        case  IPSEC_POLICY_IPSEC:
+                /* XXX: SH2ではここでillegal Instructionが発生する。コンパイラのバグ? */
+                if (sp->req == NULL) {
+                        /* 鍵交換デーモンに対してSAの取得を要求する */
+                        goto bad;
+                }
+                break;
+
+        default:
+                /* 不正なポリシ */
+                goto bad;
+                break;
+        }
+#else /* 0 */
+        /* XXX: コンパイラの不具合回避のため switchをやめif文で書き直した */
+        policy = sp->spinitb->policy;
+
+        if (policy == IPSEC_POLICY_BYPASS ||
+            policy == IPSEC_POLICY_NONE ||
+            policy == IPSEC_POLICY_TCP)
+                goto skip_ipsec;
+        else if (policy == IPSEC_POLICY_IPSEC) {
+                if (sp->req == NULL)
+                        /* 鍵交換デーモンに対してSAの取得を要求する */
+                        goto bad;
+        } else
+                goto bad;
+
+#endif /* 0 */
+
+		{
+			T_IPSEC_OUTPUT_STATE state;
+
+			state.m = output;
+			/* XXX: ipsec4_output()内では、ip->{len,off}をネットワークバイトオーダとする */
+			error = ipsec4_output (&state, sp, 0 /* flags */ );
+			output = state.m;
+
+			if (error) {
+				/* net_buf はipsec4_outputによって既に解放されている */
+				switch (error) {
+				default:
+					syslog (LOG_NOTICE, "ip_output:%d error", __LINE__);
+				}
+			}
+		}
+
+        /* ipsec4_outputに影響を受けた値を更新する */
+        /* XXX: 必要か? */
+
+skip_ipsec:
+#endif /* SUPPORT_IPSEC */
+
+#ifdef IP4_CFG_FRAGMENT
+
+	ip4h = GET_IP4_HDR(output);
+
+	gw = in4_rtalloc(ntohl(ip4h->dst));
+
+	/*
+	 *  データグラムサイズがネットワークの MTU を超えていれば、
+	 *  分割して送信する。
+	 */
+	if (ntohs(ip4h->len) > IF_MTU) {
+		T_NET_BUF	*frag;
+		T_IP4_HDR	*fip4h;
+		uint_t		off, hlen, len, flen, align;
+
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_FRAG_OUT], 1);
+		NET_COUNT_MIB(ip_stats.ipFragCreates, 1);
+
+		len  = ntohs(ip4h->len);
+		off  = hlen = GET_IP4_HDR_SIZE(output);
+		while (off < len) {
+			if (off + (IF_MTU - IP4_HDR_SIZE) < len)
+				flen = IF_MTU - IP4_HDR_SIZE;
+			else
+				flen = len - off;
+
+			/* データ長は 4 オクテット境界に調整する。	*/
+			align = (flen + 3) >> 2 << 2;
+
+			/* ネットワークバッファを獲得する。*/
+			if (tget_net_buf(&frag, align + IF_IP4_HDR_SIZE, TMO_IP4_FRAG_GET_NET_BUF) == E_OK) {
+
+				/* フラグメントをコピーする。*/
+				memcpy(GET_IP4_SDU(frag), (uint8_t *)ip4h + off, flen);
+
+				/* ヘッダを埋める。*/
+				fip4h		= GET_IP4_HDR(frag);
+				*fip4h		= *ip4h;
+				fip4h->flg_off	= htons(IP4_MAKE_FLGOFF(off + flen == len ? 0 : IP4_MF,
+						                       (off - hlen) >> 3));
+				fip4h->len	= htons(flen + IP4_HDR_SIZE);
+				fip4h->id	= htons(frag_id);
+				fip4h->sum	= 0;
+				fip4h->sum	= in_cksum(fip4h, GET_IP4_HDR_SIZE(frag));
+
+				NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_OCTETS], ntohs(fip4h->len));
+				NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_PACKETS], 1);
+				NET_COUNT_IP4(net_count_ip4[NC_IP4_FRAG_OUT_FRAGS], 1);
+
+				IF_SET_PROTO(frag, IF_PROTO_IP);
+				if ((error = IF_OUTPUT(frag, &gw, NULL, tmout)) != E_OK) {
+					syscall(rel_net_buf(output));
+					NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_ERR_PACKETS], 1);
+					NET_COUNT_MIB(ip_stats.ipFragFails, 1);
+					return error;
+					}
+				}
+			else {
+				/* 獲得できなければ、送信をあきらめる。*/
+				syscall(rel_net_buf(output));
+				NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_ERR_PACKETS], 1);
+				NET_COUNT_MIB(ip_stats.ipFragFails, 1);
+				return E_NOMEM;
+				}
+
+			off += IF_MTU - IP4_HDR_SIZE;
+			}
+		syscall(rel_net_buf(output));
+		frag_id ++;
+		NET_COUNT_MIB(ip_stats.ipFragOKs, 1);
+		}
+	else {
+
+		/* ヘッダを埋める。*/
+		ip4h->id  = htons(frag_id);
+		frag_id ++;
+		ip4h->sum = 0;
+		ip4h->sum = in_cksum(ip4h, GET_IP4_HDR_SIZE(output));
+
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_OCTETS], ntohs(ip4h->len));
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_PACKETS], 1);
+
+		IF_SET_PROTO(output, IF_PROTO_IP);
+		if ((error = IF_OUTPUT(output, &gw, NULL, tmout)) != E_OK)
+			NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_ERR_PACKETS], 1);
+		}
+
+#else	/* of #ifdef IP4_CFG_FRAGMENT */
+
+	ip4h = GET_IP4_HDR(output);
+
+	/* データグラムサイズがネットワークの MTU を超えていればエラー */
+	if (ntohs(ip4h->len) > IF_MTU)
+		return E_PAR;
+
+	/* ヘッダを埋める。*/
+	ip4h->id  = htons(frag_id);
+	frag_id ++;
+	ip4h->sum = 0;
+	ip4h->sum = in_cksum(ip4h, (uint_t)GET_IP4_HDR_SIZE(output));
+
+	NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_OCTETS], ntohs(ip4h->len));
+	NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_PACKETS], 1);
+
+#ifdef ETHER_CFG_MULTICAST
+	/* マルチキャストアドレスの場合はIPアドレスはそのまま */
+	gw = ntohl(ip4h->dst);
+	if(!IN4_IS_ADDR_MULTICAST(gw))
+		gw = in4_rtalloc(gw);
+#else
+	gw = in4_rtalloc(ntohl(ip4h->dst));
+#endif
+	IF_SET_PROTO(output, IF_PROTO_IP);
+	if ((error = IF_OUTPUT(output, &gw, NULL, tmout)) != E_OK)
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_ERR_PACKETS], 1);
+		NET_COUNT_MIB(ip_stats.ipOutDiscards, 1);
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+#ifdef SUPPORT_IPSEC
+	bad:
+#endif /* SUPPORT_IPSEC */
+
+	return error;
+	}
+
+#endif	/* of #if defined(_IP4_CFG) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/ip_var.h	(revision 398)
@@ -0,0 +1,155 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip_var.h	8.2 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/netinet/ip_var.h,v 1.45.2.1 1999/08/29 16:29:51 peter Exp $
+ */
+ 
+#ifndef _IP_VAR_H_
+#define _IP_VAR_H_
+
+#include <netinet/ip4_var.h>
+#include <netinet6/ip6_var.h>
+
+/*
+ *  IPv4 と IPv6 をコンパイル時に選択するためのマクロ
+ */
+
+#define GET_IP_VER(nbuf)		(*(uint8_t*)((nbuf)->buf+IF_HDR_SIZE)>>4)
+
+#if defined(_IP6_CFG)
+
+#if defined(_IP4_CFG)
+
+#define IF_IP_HDR_SIZE(nbuf)		(GET_IP_VER(nbuf)==IPV6_VERSION?IF_IP6_HDR_SIZE:IF_IP4_HDR_SIZE)
+#define IF_IP_NET_HDR_SIZE(addr)	(IN6_IS_ADDR_V4MAPPED(addr)?IF_IP4_HDR_SIZE:IF_IP6_HDR_SIZE)
+
+#define IP_OUTPUT(nbuf,tmout)		(GET_IP_VER(nbuf)==IPV6_VERSION?ip6_output(nbuf,0,tmout):ip_output(nbuf,tmout))
+#define IP_REMOVE_OPTIONS(nbuf)		(GET_IP_VER(nbuf)==IPV6_VERSION?ip6_remove_exthdrs(nbuf):ip_remove_options(nbuf))
+
+#define GET_IP_HDR(nbuf)		(GET_IP_VER(nbuf)==IPV6_VERSION?GET_IP6_HDR(nbuf):GET_IP4_HDR(nbuf))
+#define GET_IP_HDR_SIZE(nbuf)		(GET_IP_VER(nbuf)==IPV6_VERSION?GET_IP6_HDR_SIZE(nbuf):GET_IP4_HDR_SIZE(nbuf))
+#define GET_IP_SDU_SIZE(nbuf)		(GET_IP_VER(nbuf)==IPV6_VERSION?GET_IP6_SDU_SIZE(nbuf):GET_IP4_SDU_SIZE(nbuf))
+#define GET_IF_IP_HDR_SIZE(nbuf)	(GET_IP_VER(nbuf)==IPV6_VERSION?GET_IF_IP6_HDR_SIZE(nbuf):GET_IF_IP4_HDR_SIZE(nbuf))
+#define GET_IP_TCP_Q_HDR_OFFSET(nbuf)	(GET_IP_VER(nbuf)==IPV6_VERSION?\
+					((T_IP6_TCP_Q_HDR*)GET_IP6_HDR(nbuf))->thoff:((T_IP4_TCP_Q_HDR*)GET_IP4_HDR(nbuf))->thoff)
+
+#define SET_IP_CF(nbuf,cf)		(GET_IP_VER(nbuf)==IPV6_VERSION?SET_IP6_CF(nbuf,cf):(0))
+#define SET_IP_SDU_SIZE(nbuf,len)	(GET_IP_VER(nbuf)==IPV6_VERSION?SET_IP6_SDU_SIZE(nbuf,len):SET_IP4_SDU_SIZE(nbuf,len))
+#define SET_IP_TCP_Q_HDR_OFFSET(nbuf,thoff)	\
+					(GET_IP_VER(nbuf)==IPV6_VERSION\
+						?(((T_IP6_TCP_Q_HDR*)GET_IP6_HDR(nbuf))->thoff=thoff)\
+						:(((T_IP4_TCP_Q_HDR*)GET_IP4_HDR(nbuf))->thoff=thoff))
+
+#else	/* of #if defined(_IP4_CFG) */
+
+#define IF_IP_HDR_SIZE(nbuf)		IF_IP6_HDR_SIZE
+#define IF_IP_NET_HDR_SIZE(addr)	IF_IP6_HDR_SIZE
+
+#define IP_OUTPUT(nbuf,tmout)		ip6_output(nbuf,0,tmout)
+#define IP_REMOVE_OPTIONS(nbuf)		ip6_remove_exthdrs(nbuf)
+
+#define GET_IP_HDR(nbuf)		GET_IP6_HDR(nbuf)
+#define GET_IP_HDR_SIZE(nbuf)		GET_IP6_HDR_SIZE(nbuf)
+#define GET_IP_SDU_SIZE(nbuf)		GET_IP6_SDU_SIZE(nbuf)
+#define GET_IF_IP_HDR_SIZE(nbuf)	GET_IF_IP6_HDR_SIZE(nbuf)
+#define GET_IP_TCP_Q_HDR_OFFSET(nbuf)	(((T_IP6_TCP_Q_HDR*)GET_IP6_HDR(nbuf))->thoff)
+
+#define SET_IP_CF(nbuf,cf)		SET_IP6_CF(nbuf,cf)
+#define SET_IP_SDU_SIZE(nbuf,len)	SET_IP6_SDU_SIZE(nbuf,len)
+#define SET_IP_TCP_Q_HDR_OFFSET(nbuf,thoff)	\
+					(((T_IP6_TCP_Q_HDR*)GET_IP6_HDR(nbuf))->thoff=thoff)
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+#define IF_IP_HDR_SIZE(nbuf)		IF_IP4_HDR_SIZE
+#define IF_IP_NET_HDR_SIZE(addr)	IF_IP4_HDR_SIZE
+
+#define IP_OUTPUT(nbuf,tmout)		ip_output(nbuf,tmout)
+#define IP_REMOVE_OPTIONS(nbuf)		ip_remove_options(nbuf)
+
+#define GET_IP_HDR(nbuf)		GET_IP4_HDR(nbuf)
+#define GET_IP_HDR_SIZE(nbuf)		GET_IP4_HDR_SIZE(nbuf)
+#define GET_IP_SDU_SIZE(nbuf)		GET_IP4_SDU_SIZE(nbuf)
+#define GET_IF_IP_HDR_SIZE(nbuf)	GET_IF_IP4_HDR_SIZE(nbuf)
+#define GET_IP_TCP_Q_HDR_OFFSET(nbuf)	(((T_IP4_TCP_Q_HDR*)GET_IP4_HDR(nbuf))->thoff)
+
+#define SET_IP_SDU_SIZE(nbuf,len)	SET_IP4_SDU_SIZE(nbuf,len)
+#define SET_IP_TCP_Q_HDR_OFFSET(nbuf,thoff)	\
+					(((T_IP4_TCP_Q_HDR*)GET_IP4_HDR(nbuf))->thoff=thoff)
+
+#else	/* of #if defined(_IP4_CFG) */
+
+#error "not implemented."
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#endif	/* of #ifndef _IP_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp.cfg	(revision 398)
@@ -0,0 +1,60 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP で使用するカーネルオブジェクト
+ */
+
+#ifdef SUPPORT_TCP
+
+/* 出力タスク */
+
+CRE_TSK(TCP_OUTPUT_TASK, {
+	TA_HLNG,
+	0,
+	tcp_output_task,
+	TCP_OUT_TASK_PRIORITY,
+	TCP_OUT_TASK_STACK_SIZE,
+	NULL
+	});
+
+/* セマフォ */
+
+CRE_SEM(SEM_TCP_POST_OUTPUT,	{ TA_TPRI, 0, 1 });
+CRE_SEM(SEM_TCP_CEP,		{ TA_TPRI, 1, 1 });
+
+#ifdef TCP_CFG_TRACE
+CRE_SEM(SEM_TCP_TRACE,		{ TA_TPRI, 1, 1 });
+#endif	/* of #ifdef TCP_CFG_TRACE */
+
+#endif	/* of #ifdef SUPPORT_TCP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp.h	(revision 398)
@@ -0,0 +1,176 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/tcp.h,v 1.10.2.1 1999/08/29 16:29:52 peter Exp $
+ */
+ 
+#ifndef _TCP_H_
+#define _TCP_H_
+
+/*
+ *  TCP ヘッダ、RFC 793 参照
+ */
+
+typedef struct t_tcp_hdr {
+	uint16_t	sport;		/* 送信元ポート番号			*/
+	uint16_t	dport;		/* 宛先ポート番号			*/
+
+	uint32_t	seq;		/* SEQ 番号				*/
+
+	uint32_t	ack;		/* ACK 番号				*/
+
+	uint8_t		doff;		/* データオフセット(上位4ビット)	*/
+	uint8_t		flags;		/* フラグ(下位6ビット)			*/
+	uint16_t	win;		/* ウィンドサイズ			*/
+
+	uint16_t	sum;		/* チェックサム				*/
+	uint16_t	urp;		/* 緊急ポインタ				*/
+	} __attribute__((packed, aligned(2)))T_TCP_HDR;
+
+#define TCP_HDR_SIZE			(sizeof(T_TCP_HDR))
+
+/*
+ *  TCP ヘッダ構造体メンバアクセスマクロ
+ */
+
+#define TCP_MAKE_DATA_OFF(o)	((uint8_t)(((uint8_t)(o) << 2) & 0xf0))
+#define TCP_DATA_OFF(o)		(((uint8_t)(o) & UINT_C(0xf0)) >> 2)
+#define TCP_HDR_LEN(o)		(TCP_DATA_OFF(o))
+
+/*
+ *  TCP ヘッダのフラグフィールドの値の定義
+ */
+
+#define TCP_FLG_FIN		UINT_C(0x01)	/* FIN:	最終			*/
+#define TCP_FLG_SYN		UINT_C(0x02)	/* SYN:	同期			*/
+#define TCP_FLG_RST		UINT_C(0x04)	/* RST:	コネクションのリセット	*/
+#define TCP_FLG_PUSH		UINT_C(0x08)	/* PUSH:プッシュ機能		*/
+#define TCP_FLG_ACK		UINT_C(0x10)	/* ACK:	肯定応答		*/
+#define TCP_FLG_URG		UINT_C(0x20)	/* URG:	緊急情報		*/
+
+/*
+ *  TCP オプションの定義
+ */
+
+/* オプションの型 */
+
+#define TCP_OPT_EOL		UINT_C(0)	/* 最終				*/
+#define TCP_OPT_NOP		UINT_C(1)	/* 何もしない			*/
+#define TCP_OPT_MAXSEG		UINT_C(2)	/* 最大セグメント長		*/
+#define TCP_OPT_WINDOW		UINT_C(3)	/* ウィンドスケーリング		*/
+#define TCP_OPT_SACK_PERM	UINT_C(4)	/* 選択 ACK 許可		*/
+#define TCP_OPT_SACK		UINT_C(5)	/* 選択 ACK			*/
+#define TCP_OPT_TIMESTAMP	UINT_C(8)	/* タイムスタンプ		*/
+#define TCP_OPT_CC		UINT_C(11)	/* 接続カウント			*/
+#define TCP_OPT_CCNEW		UINT_C(12)	/* 接続カウント			*/
+#define TCP_OPT_CCECHO		UINT_C(13)	/* 接続カウント			*/
+
+/* オプションの長さ */
+
+#define TCP_OPT_LEN_MAXSEG	4		/* 最大セグメント長		*/
+#define TCP_OPT_LEN_WINDOW	3		/* ウィンドスケーリング		*/
+#define TCP_OPT_LEN_SACK_PERM	4		/* 選択 ACK 許可		*/
+#define TCP_OPT_LEN_SACK	5		/* 選択 ACK			*/
+#define TCP_OPT_LEN_TIMESTAMP	10		/* タイムスタンプ		*/
+#define TCP_OPT_LEN_CC		6		/* 接続カウント			*/
+#define TCP_OPT_LEN_CCNEW	6		/* 接続カウント			*/
+#define TCP_OPT_LEN_CCECHO	6		/* 接続カウント			*/
+
+/*
+ *  TCP 最大セグメントサイズ
+ */
+
+/*
+ *  IPv4 の TCP 最大セグメントサイズ
+ *  IP4_MSS は 576 で、標準の IPv4 ヘッダ長 (20) と
+ *  TCP ヘッダ長 (20) を引いた値 536 であるが、512 を標準とする。
+ */
+
+#define TCP_MSS			UINT_C(512)
+
+/*
+ *  IPv6 の TCP 最大セグメントサイズ
+ *  IPV6_MMTU は 1280 で、標準の IPv6 ヘッダ長 (40) と
+ *  TCP ヘッダ長 (20) を引いた値 1220 であるが、1024 を標準とする。
+ */
+
+#define TCP6_MSS		UINT_C(1024)
+
+/*
+ *  TCP 最小セグメントサイズ
+ *
+ *  256（最小リンク MTU）- 40 = 216
+ */
+
+#define TCP_MINMSS		UINT_C(216)
+
+/*
+ *  TCP 最大ウィンドウサイズ
+ */
+
+#define MAX_TCP_WIN_SIZE	UINT_C(65535)
+
+#endif	/* of #ifndef _TCP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_fsm.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_fsm.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_fsm.h	(revision 398)
@@ -0,0 +1,103 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp_fsm.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/tcp_fsm.h,v 1.10.2.3 1999/11/15 02:52:54 green Exp $
+ */
+ 
+#ifndef _TCP_FSM_H_
+#define _TCP_FSM_H_
+
+/*
+ *  TCP FSM 状態の定義、RFC 793 参照
+ */
+
+#define TCP_FSM_CLOSED		0	/* クローズ				*/
+#define TCP_FSM_LISTEN		1	/* 受動オープン				*/
+#define TCP_FSM_SYN_SENT	2	/* 能動オープン、SYN 送信済み		*/
+#define TCP_FSM_SYN_RECVD	3	/* 受動オープン、SYN 受信済み		*/
+#define TCP_FSM_ESTABLISHED	4	/* コネクション開設完了			*/
+#define TCP_FSM_CLOSE_WAIT	5	/* 相手から FIN 受信、APP の終了待ち	*/
+#define TCP_FSM_FIN_WAIT_1	6	/* APP が終了、FIN 送信済み、ACK 待ち	*/
+#define TCP_FSM_CLOSING		7	/* 同時クローズ、FIN 交換済み、ACK 待ち	*/
+#define TCP_FSM_LAST_ACK	8	/* APP が終了、ACK 待ち			*/
+#define TCP_FSM_FIN_WAIT_2	9	/* 相手からの FIN 待ち			*/
+#define TCP_FSM_TIME_WAIT	10	/* 相手からの FIN 受信済み、時間待ち	*/
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+#define TCP_FSM_HAVE_RCVD_SYN(s)	((s) >= TCP_FSM_SYN_RECVD)
+#define TCP_FSM_HAVE_ESTABLISHED(s)	((s) >= TCP_FSM_ESTABLISHED)
+#define TCP_FSM_HAVE_RCVD_FIN(s)	((s) >= TCP_FSM_TIME_WAIT)
+
+#define TCP_FSM_CAN_SEND_MORE(s)	((s) == TCP_FSM_ESTABLISHED || \
+					 (s) == TCP_FSM_CLOSE_WAIT)
+#define TCP_FSM_CAN_RECV_MORE(s)	((s) == TCP_FSM_ESTABLISHED || \
+					 (s) == TCP_FSM_FIN_WAIT_1  || \
+					 (s) == TCP_FSM_FIN_WAIT_2)
+
+#endif	/* of #ifndef _TCP_FSM_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_input.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_input.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_input.c	(revision 398)
@@ -0,0 +1,1845 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp_input.c	8.12 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/netinet/tcp_input.c,v 1.82.2.3 1999/10/14 11:49:38 des Exp $
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+
+#ifdef SUPPORT_TCP
+
+/*
+ *  戻り値
+ *
+ *      RET_OK		正常
+ *	RET_DROP	エラー、セグメントを破棄する。
+ *	RET_RST_DROP	エラー、RST を送信し、セグメントを破棄する。
+ */
+
+#define RET_OK		(0)
+#define RET_NEED_OUTPUT	(1)
+#define RET_RETURN	(2)
+#define RET_DROP	(-1)
+#define RET_RST_DROP	(-2)
+
+/*
+ *  関数
+ */
+
+static void close_connection	(T_TCP_CEP *cep, bool_t *needoutput);
+static void set_rexmt_timer	(T_TCP_CEP *cep,  T_TCP_TIME rtt);
+static uint8_t reassemble	(T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, uint8_t flags);
+static ER drop_after_ack	(T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff);
+static ER listening		(T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, T_TCP_SEQ iss);
+static ER proc_ack1		(T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, bool_t *needoutput);
+static ER proc_ack2		(T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, bool_t *needoutput);
+static ER syn_sent		(T_TCP_HDR *tcph,  T_TCP_CEP *cep);
+static void trim_length		(T_TCP_HDR *tcph,  T_TCP_CEP *cep);
+static void parse_option	(T_TCP_HDR *tcph,  T_TCP_CEP *cep);
+static bool_t update_wnd	(T_TCP_HDR *tcph,  T_TCP_CEP *cep);
+static void proc_urg		(T_TCP_HDR *tcph,  T_TCP_CEP *cep);
+
+/*
+ *  parse_option -- TCP ヘッダのオプションを解析する。
+ */
+
+static void
+parse_option (T_TCP_HDR *tcph, T_TCP_CEP *cep)
+{
+	uint8_t	*opt, type = 0;
+	uint_t	len, ol, ssize;
+
+	opt = (uint8_t*)tcph + TCP_HDR_SIZE;
+	len = (uint_t)(TCP_HDR_LEN(tcph->doff) - TCP_HDR_SIZE);
+	while (len > 0 && (type = *opt) != TCP_OPT_EOL) {
+		if (type == TCP_OPT_NOP)
+			ol = 1u;
+		else {
+			if (len < 2)
+				break;
+			ol = *(opt + 1);
+			if (ol < 2 || ol > len)
+				break;
+			}
+		switch (type) {
+		case TCP_OPT_NOP:
+			break;
+		case TCP_OPT_MAXSEG:
+			if ((ol == TCP_OPT_LEN_MAXSEG) && (tcph->flags & TCP_FLG_SYN)) {
+				ssize = ntohs(*(uint16_t*)(opt + 2));
+				if (ssize > MAX_TCP_SND_SEG)
+					cep->maxseg = MAX_TCP_SND_SEG;
+				else if (ssize < TCP_MINMSS)
+					cep->maxseg = TCP_MINMSS;
+				else
+					cep->maxseg = ssize;
+				}
+			break;
+
+		case TCP_OPT_WINDOW:
+		case TCP_OPT_SACK_PERM:
+		case TCP_OPT_TIMESTAMP:
+		case TCP_OPT_CC:
+		case TCP_OPT_CCNEW:
+		case TCP_OPT_CCECHO:
+			syslog(LOG_INFO, "[TCP] unsup opt: %d.", type);
+			break;
+
+		default:
+			syslog(LOG_NOTICE, "[TCP] unexp opt: %d.", type);
+			break;
+			}
+		opt += ol;
+		len -= ol;
+		}
+	}
+
+/*
+ *  set_rexmt_timer -- 新しい往復時間を収集し、再送タイマを更新する。
+ */
+
+static void
+set_rexmt_timer (T_TCP_CEP *cep, T_TCP_TIME rtt)
+{
+	T_TCP_TIME delta;
+
+	NET_COUNT_TCP(net_count_tcp[NC_TCP_RTT_UPDATES], 1);
+	if (cep->srtt != 0) {
+		/*
+		 *  srtt: 平滑化された RTT
+		 *
+		 *  計測された RTT (rtt) と現在の平滑化された RTT (srtt) の差 (delta) を求める。
+		 *
+		 *  delta は 2 ビット左シフト ( 4 倍) した値で保持する。
+		 *  srtt  は 5 ビット左シフト (32 倍) した値で保持されている。
+		 *
+		 *    delta = rtt / 8 - srtt / 8
+		 *
+		 *  新しい srtt は
+		 *
+		 *    srtt = rtt / 8 + srtt * 7 / 8
+		 *         = srtt + (rtt / 8 - srtt / 8)
+		 *
+		 *  で計算する。
+		 *  このため、rtt を 2 ビット左シフトし、srtt を (5 - 2) ビット右シフトして delta を求める。
+		 */
+		delta = ((rtt - 1) << TCP_DELTA_SHIFT) - (cep->srtt >> (TCP_SRTT_SHIFT - TCP_DELTA_SHIFT));
+		cep->srtt += delta;
+		if (cep->srtt <= 0)
+			cep->srtt = 1;
+
+		/*
+		 *  delta の絶対値 | delta | を求める。
+		 */
+		if (delta < 0)
+			delta = - delta;
+
+		/*
+		 *  rttvar: 平滑化された分散
+		 *
+		 *  rttvar は 4 ビット左シフト (16 倍) した値で保持されている。
+		 *
+		 *    delta = |delta| / 4 - rttvar / 4
+		 *
+		 *  新しい rttvar は
+		 *
+		 *    rttvar = |delta|/ 4 + rttvar * 3 /4
+		 *           = rttvar + (|delta| / 4 - rttvar / 4)
+		 *
+		 *  で計算する。
+		 */
+		delta -= cep->rttvar >> (TCP_RTTVAR_SHIFT - TCP_DELTA_SHIFT);
+		cep->rttvar += delta;
+		if (cep->rttvar <= 0)
+			cep->rttvar = 1;
+		}
+	else {
+		/*
+		 *  まだ srtt の設定が行われていないときは、今回計測された RTT を使用する。
+		 *  平滑化された RTT (srtt) には、RTT を 5 ビット左シフト (32倍) した値。
+		 *  平滑化された分散 (rttvar) には、RTT の 1/2 を 4 ビット左シフト (16倍) した値。
+		 */
+		cep->srtt   = rtt <<  TCP_SRTT_SHIFT;
+		cep->rttvar = rtt << (TCP_RTTVAR_SHIFT - 1);
+		}
+
+	/*
+	 *  rtt の測定を終了し、再送回数をリセットする。
+	 */
+	cep->rtt = cep->rxtshift = 0;
+
+	/*
+	 *  RTT に許される最小値 と rtt + 2 の大きな値の方を再送タイムアウトの最小値にする。
+	 */
+	if (rtt + 2 < TCP_TVAL_MIN)
+		cep->rxtcur = tcp_range_set(tcp_rexmt_val(cep),
+		                            (T_TCP_TIME)TCP_TVAL_MIN,
+		                            (T_TCP_TIME)TCP_TVAL_MAX_REXMT);
+	else
+		cep->rxtcur = tcp_range_set(tcp_rexmt_val(cep),
+		                            (T_TCP_TIME)(rtt + 2),
+		                            (T_TCP_TIME)TCP_TVAL_MAX_REXMT);
+	}
+
+/*
+ *  reassemble -- 受信セグメントを再構成する。順番通りに受信したときの処理
+ */
+
+static uint8_t
+reassemble (T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, uint8_t flags)
+{
+	T_TCP_Q_HDR 	*qhdr;
+	T_TCP_HDR	*tcph;
+
+	tcph = GET_TCP_HDR(input, thoff);
+	if (tcph->sum > cep->rbufsz - cep->rwbuf_count) {
+		/*
+		 *  受信ウィンドバッファに空きがないときは破棄する。
+		 */
+		NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DROP_SEGS], 1);
+		syscall(rel_net_buf(input));
+		cep->flags |= TCP_CEP_FLG_ACK_NOW;
+		flags &= ~TCP_FLG_FIN;
+		}
+	else if (tcph->seq == cep->rcv_nxt &&
+	         cep->reassq == NULL &&
+	         cep->fsm_state == TCP_FSM_ESTABLISHED) {
+		/*
+		 *  順番通りにセグメントを受信した時の処理
+		 *  受信セグメントの並べ替えは不要なので
+		 *  そのまま受信ウィンドバッファに書き込む。
+		 */
+
+#ifdef TCP_CFG_DELAY_ACK
+
+		cep->flags |= TCP_CEP_FLG_DEL_ACK;
+
+#else/* of #ifdef TCP_CFG_DELAY_ACK */
+
+		cep->flags |= TCP_CEP_FLG_ACK_NOW;
+
+#endif/* of #ifdef TCP_CFG_DELAY_ACK */
+
+		qhdr = GET_TCP_Q_HDR(input, thoff);
+
+		/*  TCP ヘッダの位置を保存する。*/
+		SET_IP_TCP_Q_HDR_OFFSET(input, thoff);
+
+		/* SDU のオフセット（元はウィンドサイズ）をリセットする。*/
+		qhdr->soff = 0;
+
+		/* データを受信ウィンドバッファに書き込む。*/
+		TCP_WRITE_RWBUF(cep, input, thoff);
+		}
+	else {
+		flags = tcp_write_raque(input, cep, thoff, flags);
+		cep->flags |= TCP_CEP_FLG_ACK_NOW;
+		}
+	return flags;
+	}
+
+/*
+ *  listening -- 受動オープンして，状態が LISTEN の処理
+ *
+ *    戻り値:
+ *      RET_OK		正常
+ *	RET_DROP	エラー、セグメントを破棄する。
+ *	RET_RST_DROP	エラー、RST を送信し、セグメントを破棄する。
+ */
+
+static ER
+listening (T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, T_TCP_SEQ iss)
+{
+	T_TCP_HDR	*tcph;
+
+	tcph = GET_TCP_HDR(input, thoff);
+
+	/* 
+	 *  フラグに RST がセットされていれば破棄する。
+	 */
+	if (tcph->flags & TCP_FLG_RST)
+		return RET_DROP;
+
+	/*  
+	 *  フラグに ACK がセットさてれいれば、
+	 *  リセットを送って破棄する。
+	 */
+	if (tcph->flags & TCP_FLG_ACK)
+		return RET_RST_DROP;
+
+	/* 
+	 *  フラグに SYN がセットされていなければれば破棄する。
+	 */
+	if ((tcph->flags & TCP_FLG_SYN) == 0)
+		return RET_DROP;
+
+	/*
+	 *  受信可能な IP アドレスとポート番号であることを確認する。
+	 */
+	if (!tcp_is_addr_accept(input, thoff))
+		return RET_DROP;
+
+	/* 相手のアドレスを記録する。*/
+	IN_COPY_TO_HOST(&cep->dstaddr.ipaddr, input);
+	cep->dstaddr.portno = tcph->sport;
+
+	/* オプションを処理する。*/
+	parse_option(tcph, cep);
+
+	/* シーケンス番号を初期化する。*/
+	if (tcp_iss == 0)
+		tcp_init_iss();
+
+	/* 自分のシーケンス番号の初期値を記録する。*/
+	if (iss != 0)
+		cep->iss = iss;
+	else
+		cep->iss = tcp_iss;
+
+	tcp_iss += TCP_ISS_INCR() / 4;
+
+	/* 相手のシーケンス番号の初期値を記録する。*/
+	cep->irs = tcph->seq;
+
+	/* 送受信シーケンス番号を初期化する。*/
+	init_send_seq(cep);
+	init_receive_seq(cep);
+
+	/* 送信ウインドサイズを設定する。*/
+	cep->snd_wnd = tcph->win;
+
+	/* 最終設定 */
+	cep->flags    |= TCP_CEP_FLG_ACK_NOW;
+	cep->fsm_state = TCP_FSM_SYN_RECVD;
+	cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_INIT;
+
+	return RET_OK;
+	}
+
+/*
+ *  syn_sent -- 能動オープンして、状態が SYN 送信済の処理
+ *
+ *    戻り値:
+ *      RET_OK		正常
+ *	RET_DROP	エラー、セグメントを破棄する。
+ *	RET_RST_DROP	エラー、RST を送信し、セグメントを破棄する。
+ */
+
+static ER
+syn_sent (T_TCP_HDR *tcph, T_TCP_CEP *cep)
+{
+	ER error = RET_OK;
+
+	/*
+	 *  相手から受信確認が送られて来ても、
+	 *
+	 *    ACK <= iss && 送信した最大 SEQ (snd_max) < ACK
+	 *
+	 *  なら、リセットを送ってセグメントを破棄する。
+	 */
+	if ((tcph->flags & TCP_FLG_ACK) &&
+	    (SEQ_LE(tcph->ack, cep->iss) || SEQ_GT(tcph->ack, cep->snd_max)))
+		return RET_RST_DROP;
+
+	/*
+	 *  RST/ACK フラグの応答があれば、ポートが開いていない
+	 *  ことを意味している。
+	 */
+	if (tcph->flags & TCP_FLG_RST) {
+		if (tcph->flags & TCP_FLG_ACK) {
+			cep->net_error = EV_CNNRF;
+			cep = tcp_drop(cep, E_CLS);
+			}
+		return RET_DROP;
+		}
+
+	/*
+	 *  SYN フラグがなければセグメントを破棄する。
+	 */
+	if ((tcph->flags & TCP_FLG_SYN) == 0)
+		return RET_DROP;
+
+	cep->snd_wnd = tcph->win;	/* snd_wnd: 相手の受信可能ウィンドサイズ	*/
+	cep->irs     = tcph->seq;	/* irs:     相手のシーケンス番号の初期値	*/
+	init_receive_seq(cep);		/* 送受信シーケンス番号を初期化する。		*/
+
+	if (tcph->flags & TCP_FLG_ACK) {
+		/*
+		 *  ACK フラグがあるときの処理
+		 *
+		 *  受信を期待している最大の SEQ (rcv_adv) を
+		 *  受信可能なウィンドサイズ (rcv_wnd) 分進める。
+		 */
+		cep->rcv_adv += cep->rcv_wnd;	/* rcv_adv: 受信を期待している最大の SEQ	*/
+						/* rcv_wnd: 受信可能なウィンドサイズ		*/
+
+		/* 未確認の最小送信 SEQ (snd_una) を SYN 分 (1 オクテット) 進める。*/
+		cep->snd_una ++;
+
+#ifdef TCP_CFG_DELAY_ACK
+
+		if (tcph->sum != 0)		/* tcph->sum は SDU 長 */
+			cep->flags |= TCP_CEP_FLG_DEL_ACK;
+		else
+			cep->flags |= TCP_CEP_FLG_ACK_NOW;
+
+#else/* of #ifdef TCP_CFG_DELAY_ACK */
+
+		cep->flags |= TCP_CEP_FLG_ACK_NOW;
+
+#endif/* of #ifdef TCP_CFG_DELAY_ACK */
+
+		if (cep->flags & TCP_CEP_FLG_NEED_FIN) {
+			/*
+			 *  CEP で FIN 送信が要求されていれば、
+			 *  切断処理を開始し、
+			 *  CEP の状態を FIN Wait 1 にする。
+			 */
+			cep->fsm_state = TCP_FSM_FIN_WAIT_1;
+			cep->flags  &= ~TCP_CEP_FLG_NEED_FIN;
+			tcph->flags &= ~TCP_FLG_SYN;
+			}
+		else {
+			/*
+			 *  相手から ACK が応答されたので、
+			 *  CEP の状態を コネクション開設完了状態にする。
+			 */
+			cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_IDLE;
+			cep->fsm_state  = TCP_FSM_ESTABLISHED;
+			NET_COUNT_MIB(tcp_stats.tcpActiveOpens, 1);
+			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_ESTABLISHED));
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+			if (cep->snd_nblk_tfn == TFN_TCP_CON_CEP) {
+
+				/* 相手のアドレスをコピーする。*/
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+
+				if (cep->flags & TCP_CEP_FLG_IPV4) {
+					(*cep->p_dstaddr4).ipaddr = ntohl(cep->dstaddr.ipaddr.s6_addr32[3]);
+					(*cep->p_dstaddr4).portno = cep->dstaddr.portno;
+					}
+				else
+					*cep->p_dstaddr = cep->dstaddr;
+
+#else	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+				*cep->p_dstaddr = cep->dstaddr;
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+				if (IS_PTR_DEFINED(cep->callback)) {
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+					NET_COUNT_TCP(net_count_tcp[NC_TCP_CONNECTS], 1);
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, E_OK);
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+					ER	error = E_OK;
+
+					NET_COUNT_TCP(net_count_tcp[NC_TCP_CONNECTS], 1);
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&error);
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+					}
+				else {
+					syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+					error = RET_RST_DROP;
+					}
+				cep->p_dstaddr = NULL;
+				cep->snd_tskid = TA_NULL;
+				cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+				}
+			else
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+				NET_COUNT_TCP(net_count_tcp[NC_TCP_CONNECTS], 1);
+			}
+		}
+	else {
+		/* ACK フラグがないときは、ACK を送って、CEP の状態を SYN 受信済みにする。*/
+		cep->flags |= TCP_CEP_FLG_ACK_NOW;
+		cep->timer[TCP_TIM_REXMT] = 0;
+		cep->fsm_state  = TCP_FSM_SYN_RECVD;
+		}
+
+	return error;
+	}
+
+/*
+ *  trim_length -- 受信した SDU 長を調整する。
+ */
+
+static void
+trim_length (T_TCP_HDR *tcph, T_TCP_CEP *cep)
+{
+	tcph->seq ++;
+	if (tcph->sum > cep->rcv_wnd) {		/* 注意: tcph->sum は SDU 長 */
+		/*
+		 *  SDU 長が受信ウィンドサイズより大きいときは、受信ウィンドサイズ以降は
+		 *  破棄し、FIN に応答しないことで、破棄したデータを再送させる。
+		 */
+		tcph->sum    = (uint16_t)cep->rcv_wnd;
+		tcph->flags &= ~TCP_FLG_FIN;
+		}
+	cep->snd_wl1 = tcph->seq - 1;		/* cep->snd_wl1: ウィンド更新 SEQ 番号	*/
+
+#ifdef TCP_CFG_EXTENTIONS
+	cep->rcv_up  = tcph->seq;		/* cep->rcv_up : 受信した緊急ポインタ	*/
+#endif
+	}
+
+/*
+ *  proc_ack2 -- ACK の処理 (2)
+ *
+ *    戻り値
+ *
+ *      RET_OK		正常
+ *      RET_RETURN	正常、リターンする。
+ *	RET_DROP	エラー、セグメントを破棄する。
+ *	RET_RST_DROP	エラー、RST を送信し、セグメントを破棄する。
+ */
+
+static ER
+proc_ack2 (T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, bool_t *needoutput)
+{
+	T_TCP_HDR	*tcph;
+	ER		ret = RET_OK;
+	uint32_t	acked;
+	bool_t		ourfinisacked = false;
+
+	tcph = GET_TCP_HDR(input, thoff);
+
+	/*
+	 *  相手に受信確認された ACK から、まだ確認されていない
+	 *  最小送信 SEQ (snd_una) を引くと、送信ウィンドバッファから
+	 *  削除してよいオクテット数 (acked) になる。
+	 */
+	acked = tcph->ack - cep->snd_una;
+	NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_ACKS], 1);
+
+	/*
+	 *  往復時間計測 (rtt) が設定されていて、計測開始 SEQ より
+	 *  後の ACK を受信したら、タイマバックオフをキャンセルし、
+	 *  再送タイマを再設定する。
+	 */
+	if (cep->rtt && SEQ_GT(tcph->ack, cep->rtseq)) {
+		set_rexmt_timer(cep, cep->rtt);
+		}
+
+	/*
+	 *  全ての未確認データが ACK されたら、再送タイマを停止し、
+	 *  再開を記憶する (さらに出力か持続)。
+	 *  もし、ACK すべき、さらに多くのデータがあるなら、再送タイマに
+	 *  現在の再送タイムアウトを設定する。
+	 */
+	if (tcph->ack == cep->snd_max) {	/* cep->snd_max: 送信した最大 SEQ */
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+		/*
+		 * 送信ウィンドバッファの省コピー機能が有効の場合は、
+		 * 送信済みで、ACKが完了するまで再送タイマを変更しない。
+		 */
+		if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_ACKED)
+			cep->timer[TCP_TIM_REXMT] = 0;
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+		cep->timer[TCP_TIM_REXMT] = 0;
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+		*needoutput = true;
+		}
+	else if (cep->timer[TCP_TIM_PERSIST] == 0) {
+	 	cep->timer[TCP_TIM_REXMT] = cep->rxtcur;	/* cep->rxtcur: 現在の再送タイムアウト */
+		}
+
+	/* 相手が受信確認したデータがあるときの処理 */
+	if (acked) {
+		uint32_t cw   = cep->snd_cwnd;	/* cep->snd_cwnd: 輻輳ウィンドサイズ	*/
+		uint32_t incr = cep->maxseg;		/* cep->maxseg:   最大セグメントサイズ	*/
+
+		/*
+		 *  新たに相手が受信確認したデータがあったときは、
+		 *  輻輳ウィンドサイズを大きくする。
+		 *  輻輳ウィンドサイズ (snd_cwnd) が
+		 *  輻輳ウィンドサイズのしきい値 (snd_ssthresh) より大きいときは
+		 *  輻輳回避制御を行い。
+		 *
+		 *    snd_cwnd = snd_cwnd + maxseg * maxseg / snd_cwnd;
+		 *
+		 *  等しいか小さいときは、スロースタート制御を行う。
+		 *
+		 *    snd_cwnd = snd_cwnd + maxseg
+		 *
+		 */
+		if (cw > cep->snd_ssthresh)
+			/* 輻輳回避制御 */
+			incr = incr * incr / cw;
+
+		if (cw + incr < MAX_TCP_WIN_SIZE)
+			cep->snd_cwnd = (uint16_t)(cw + incr);
+		else
+			cep->snd_cwnd = MAX_TCP_WIN_SIZE;
+
+		/*
+		 *  送信ウィンドバッファから、相手が受信確認したデータ数 (acked) のデータを削除する。
+		 */
+		if (acked > cep->swbuf_count) {
+			cep->snd_wnd -= cep->swbuf_count;
+			TCP_DROP_SWBUF(cep, (uint_t)cep->swbuf_count);
+			ourfinisacked = true;
+			}
+		else {
+			cep->snd_wnd -= (uint16_t)acked;
+			TCP_DROP_SWBUF(cep, (uint_t)acked);
+			ourfinisacked = false;
+			}
+
+		/* 送信ウィンドバッファに空きができたことを知らせる。*/
+		syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY));
+
+		/*
+		 *  送達確認されていない最小送信 SEQ (snd_una) を
+		 *  今回送達確認された ACK まで進め、
+		 *  次の送信データの SEQ (snd_nxt) も、新しい
+		 *  送達確認されていない最小送信 SEQ (snd_una)
+		 *  まで進める。
+		 */
+		cep->snd_una += acked;
+		if (SEQ_LT(cep->snd_nxt, cep->snd_una))
+			cep->snd_nxt = cep->snd_una;
+
+		/*
+		 *  状態により分岐
+		 */
+		switch (cep->fsm_state) {
+		case TCP_FSM_FIN_WAIT_1:	/* APP が終了、FIN 送信済み、ACK 待ち */
+			if (ourfinisacked) {
+				cep->fsm_state = TCP_FSM_FIN_WAIT_2;
+				cep->timer[TCP_TIM_2MSL] = TCP_TVAL_KEEP_COUNT * TCP_TVAL_KEEP_INTERVAL;
+				}
+			break;
+		case TCP_FSM_CLOSING:		/* 同時クローズ、FIN 交換済み、ACK 待ち */
+			if (ourfinisacked) {
+				/*
+				 *  送信した FIN が確認されていれば状態を変更し、
+				 *  すべてのタイマをリセットした後、2MSL タイマを設定する。
+				 */
+				cep->fsm_state = TCP_FSM_TIME_WAIT;
+				tcp_cancel_timers(cep);
+				cep->timer[TCP_TIM_2MSL] = 2 * TCP_TVAL_MSL;
+				}
+			break;
+		case TCP_FSM_LAST_ACK:		/* APP が終了、ACK 待ち */
+			if (ourfinisacked) {
+				/*
+				 *  送信した FIN が確認されていれば、cep をクローズし、
+				 *  セグメントを破棄する。
+				 */
+				cep = tcp_close(cep);
+				ret = RET_DROP;
+				}
+			break;
+		case TCP_FSM_TIME_WAIT:		/* 相手からの FIN 受信済み、時間待ち */
+			/*
+			 *  相手から FIN が再送された。もう一度2MSL タイマを設定し、
+			 *  ACK 送信後、セグメントを破棄する。
+			 */
+			cep->timer[TCP_TIM_2MSL] = 2 * TCP_TVAL_MSL;
+			return drop_after_ack(input, cep, thoff);
+			}
+		}
+
+	return ret;
+	}
+
+/*
+ *  proc_ack1 -- ACK の処理 (1)
+ *
+ *    戻り値:
+ *      RET_OK		正常
+ *      RET_RETURN	正常、リターンする。
+ *	RET_DROP	エラー、セグメントを破棄する。
+ *	RET_RST_DROP	エラー、RST を送信し、セグメントを破棄する。
+ *
+ */
+
+static ER
+proc_ack1 (T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, bool_t *needoutput)
+{
+	T_TCP_HDR *tcph = GET_TCP_HDR(input, thoff);
+
+	switch (cep->fsm_state) {
+	case TCP_FSM_SYN_RECVD:		/* SYN を受信し、SYN 送信済み	*/
+
+		/* 状態を変更する。*/
+		if (cep->flags & TCP_CEP_FLG_NEED_FIN) {
+			cep->fsm_state  = TCP_FSM_FIN_WAIT_1;
+			cep->flags &= ~TCP_CEP_FLG_NEED_FIN;
+			}
+		else {
+			cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_IDLE;
+			cep->fsm_state  = TCP_FSM_ESTABLISHED;
+
+			/* TCP 通信端点からTCP 受付口を解放する。*/
+			cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+			cep->rep4 = NULL;
+#endif
+
+			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_ESTABLISHED));
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+			if (cep->rcv_nblk_tfn == TFN_TCP_ACP_CEP) {
+
+				/* 相手のアドレスをコピーする。*/
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+
+				if (cep->flags & TCP_CEP_FLG_IPV4) {
+					(*cep->p_dstaddr4).ipaddr = ntohl(cep->dstaddr.ipaddr.s6_addr32[3]);
+					(*cep->p_dstaddr4).portno = cep->dstaddr.portno;
+					}
+				else
+					*cep->p_dstaddr = cep->dstaddr;
+
+#else	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+				*cep->p_dstaddr = cep->dstaddr;
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+				if (IS_PTR_DEFINED(cep->callback)) {
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+					NET_COUNT_MIB(tcp_stats.tcpPassiveOpens, 1);
+					NET_COUNT_TCP(net_count_tcp[NC_TCP_ACCEPTS], 1);
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, E_OK);
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+					ER	error = E_OK;
+
+					NET_COUNT_MIB(tcp_stats.tcpPassiveOpens, 1);
+					NET_COUNT_TCP(net_count_tcp[NC_TCP_ACCEPTS], 1);
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&error);
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+					cep->p_dstaddr = NULL;
+					cep->rcv_tskid = TA_NULL;
+					cep->rcv_tfn   = cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+					}
+				else {
+					syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+					cep->p_dstaddr = NULL;
+					cep->rcv_tskid = TA_NULL;
+					cep->rcv_tfn   = cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+					return RET_RST_DROP;
+					}
+				}
+
+			if (cep->snd_nblk_tfn == TFN_TCP_CON_CEP) {
+
+				/* 相手のアドレスをコピーする。*/
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+
+				if (cep->flags & TCP_CEP_FLG_IPV4) {
+					(*cep->p_dstaddr4).ipaddr = ntohl(cep->dstaddr.ipaddr.s6_addr32[3]);
+					(*cep->p_dstaddr4).portno = cep->dstaddr.portno;
+					}
+				else
+					*cep->p_dstaddr = cep->dstaddr;
+
+#else	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+				*cep->p_dstaddr = cep->dstaddr;
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+				if (IS_PTR_DEFINED(cep->callback)) {
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+					NET_COUNT_MIB(tcp_stats.tcpActiveOpens, 1);
+					NET_COUNT_TCP(net_count_tcp[NC_TCP_CONNECTS], 1);
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, E_OK);
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+					ER	error = E_OK;
+
+					NET_COUNT_MIB(tcp_stats.tcpActiveOpens, 1);
+					NET_COUNT_TCP(net_count_tcp[NC_TCP_CONNECTS], 1);
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&error);
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+					cep->p_dstaddr = NULL;
+					cep->snd_tskid = TA_NULL;
+					cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+					}
+				else {
+					syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+					cep->p_dstaddr = NULL;
+					cep->snd_tskid = TA_NULL;
+					cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+					return RET_RST_DROP;
+					}
+				}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+			if (cep->rcv_tfn == TFN_TCP_ACP_CEP) {
+				NET_COUNT_MIB(tcp_stats.tcpPassiveOpens, 1);
+				NET_COUNT_TCP(net_count_tcp[NC_TCP_ACCEPTS], 1);
+				}
+
+			if (cep->snd_tfn == TFN_TCP_CON_CEP) {
+				NET_COUNT_MIB(tcp_stats.tcpActiveOpens, 1);
+				NET_COUNT_TCP(net_count_tcp[NC_TCP_CONNECTS], 1);
+				}
+			}
+
+		/*
+		 *  SDU がなく FIN がついていなければ、tcp_move_ra2rw() を呼出す。
+		 */
+		if (tcph->sum == 0 && (tcph->flags & TCP_FLG_FIN) == 0)		/* tcph->sum は SDU 長 */
+			tcph->flags = tcp_move_ra2rw(cep, tcph->flags);
+		
+		cep->snd_wl1 = tcph->seq - 1;	/* snd_wl1: ウィンド更新 SEQ */
+
+		/* break; 下に落ちる。*/
+	
+	case TCP_FSM_ESTABLISHED:	/* コネクション開設完了		*/
+	case TCP_FSM_FIN_WAIT_1:	/* 終了して、FIN 送信済み		*/
+	case TCP_FSM_FIN_WAIT_2:	/* 終了、FIN 伝達確認受信、FIN待ち*/
+	case TCP_FSM_CLOSE_WAIT:	/* FIN 受信、クローズ待ち		*/
+	case TCP_FSM_CLOSING:		/* 終了、FIN 交換済み、ACK 待ち	*/
+	case TCP_FSM_LAST_ACK:		/* FIN 受信、終了、ACK 待ち	*/
+	case TCP_FSM_TIME_WAIT:		/* 終了、時間待ち		*/
+
+		if (SEQ_LE(tcph->ack, cep->snd_una)) {
+
+			/*
+			 *  受信確認 ACK が 未確認の最小送信 SEQ (snd_una) と同じか以前のときの処理
+			 *  つまり、多重に ACK を受信したことを意味している。
+			 */
+
+			if (tcph->sum == 0 && tcph->win == cep->snd_wnd) {	/* tcph->sum は SDU 長 */
+
+				/*
+				 *  SDU がなく、相手のウィンドサイズが変更されていなければ、
+				 *  すでに送信したセグメントの中で、ACK (tcph->ack) と
+				 *  同じ SEQ から始まるセグメントが、途中で消失した可能性がある。
+				 *  この場合は、高速再転送と高速リカバリを行う。
+				 */
+				NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DUP_ACKS], 1);
+
+				if (cep->timer[TCP_TIM_REXMT] == 0 || tcph->ack != cep->snd_una) {
+
+					/*
+					 *  再送タイマがセットされていないとき、
+					 *  または、ACK (tcph->ack) と未確認の最小送信 SEQが
+					 *  一致しないときは、多重 ACK 数を 0 にする。
+					 */
+					cep->dupacks = 0;
+					}
+
+				else if (++ cep->dupacks == MAX_TCP_REXMT_THRESH) {
+
+					/*
+					 *  多重 ACK 数がしきい値 (標準 3) になったら
+					 *  高速再転送処理を開始する。
+					 */
+					uint_t		win;
+
+					/*
+					 *  輻輳ウィンドサイズ(snd_cwnd)のしきい値を設定する。
+					 *
+					 *    相手の受信可能ウィンドサイズ (snd_wnd) か
+					 *    輻輳ウィンドサイズ (snd_cwnd) の 1/2。
+					 *    ただし、2 * maxseg 以上。
+					 *
+					 */
+					if (cep->snd_wnd < cep->snd_cwnd)
+						win = cep->snd_wnd / 2 / cep->maxseg;
+					else
+						win = cep->snd_cwnd / 2 / cep->maxseg;
+					if (win < 2)
+						win = 2;
+					cep->snd_ssthresh = win * cep->maxseg;
+
+					/* 再送タイマと往復時間をリセットする。*/
+					cep->timer[TCP_TIM_REXMT] = 0;
+					cep->rtt = 0;
+
+					/* 消失したセグメントを送信する。*/
+					cep->snd_old_nxt = cep->snd_nxt;
+					cep->snd_nxt     = tcph->ack;
+					cep->snd_cwnd    = cep->maxseg;
+
+					/*
+					 *  snd_nxt を元に戻すように設定して
+					 *  送信を指示する。
+					 */
+					cep->flags |=  TCP_CEP_FLG_POST_OUTPUT |
+					               TCP_CEP_FLG_FORCE       |
+					               TCP_CEP_FLG_FORCE_CLEAR |
+					               TCP_CEP_FLG_RESTORE_NEXT_OUTPUT;
+					sig_sem(SEM_TCP_POST_OUTPUT);
+
+					/* 輻輳ウィンドサイズを更新する。*/
+					cep->snd_cwnd = (uint16_t)(cep->snd_ssthresh
+					                   + cep->maxseg * cep->dupacks);
+					
+					return RET_DROP;
+					}
+
+				else if (cep->dupacks > MAX_TCP_REXMT_THRESH) {
+
+					/*
+					 *  多重 ACK 数がしきい値 (標準 3) を超えたら
+					 *  輻輳ウィンドサイズを増加しながら再送する。
+					 */
+					cep->snd_cwnd += cep->maxseg;
+
+					/* 送信を指示する。*/
+					cep->flags |=  TCP_CEP_FLG_POST_OUTPUT;
+					sig_sem(SEM_TCP_POST_OUTPUT);
+
+					return RET_DROP;
+					}
+				} 
+			else
+				cep->dupacks = 0;
+			break;
+			}
+
+		/*
+		 *  受信確認 ACK が 未確認の最小送信 SEQ (snd_una) 以降のときの処理
+		 */
+		if (cep->dupacks >= MAX_TCP_REXMT_THRESH && cep->snd_cwnd > cep->snd_ssthresh)
+		 	/*
+			 *  高速再転送を行っていたときは、輻輳ウィンドサイズをしきい値まで戻す。
+			 */
+			cep->snd_cwnd = (uint16_t)cep->snd_ssthresh;
+	
+		cep->dupacks = 0;
+
+		if (SEQ_GT(tcph->ack, cep->snd_max))
+			/*
+			 *  受信した ACK が送信した最大 SEQ を超えていたときの処理
+			 */
+			return drop_after_ack(input, cep, thoff);
+
+		if (cep->flags & TCP_CEP_FLG_NEED_SYN) {
+			/*
+			 *  SYN 送信要求を取り消して、未確認の最小送信 SEQ を進める。
+			 */
+			cep->flags &= ~TCP_CEP_FLG_NEED_SYN;
+			cep->snd_una ++;
+			}
+		
+		return proc_ack2(input, cep, thoff, needoutput);
+		break;
+		}
+	return RET_OK;
+	}
+
+/*
+ *  update_wnd -- ウィンドサイズを更新する。
+ *
+ *    戻り値: 送信が必要なら true を返す。
+ */
+
+static bool_t
+update_wnd (T_TCP_HDR *tcph, T_TCP_CEP *cep)
+{
+
+	/*
+	 *  更新条件
+	 *
+	 *    ACK フラグがセットされている &&
+	 *    (前回ウィンドを更新した SEQ (snd_wl1) が SEQ より前 ||
+	 *     前回ウィンドを更新した SEQ (snd_wl1) が SEQ と同じ &&
+	 *     (前回ウィンドを更新した ACK (snd_wl2) が ACK より前 ||
+	 *      (前回ウィンドを更新した ACK (snd_wl2) が ACK と同じ &&
+	 *       WIN が相手の受信可能ウィンドサイズ (snd_wnd) より大きい
+	 *       )
+	 *      )
+	 *     )
+	 */
+	if ((tcph->flags & TCP_FLG_ACK) &&
+	    (SEQ_LT(cep->snd_wl1, tcph->seq) ||
+	     (cep->snd_wl1 == tcph->seq &&
+	      (SEQ_LT(cep->snd_wl2, tcph->ack) ||
+	       (cep->snd_wl2 == tcph->ack && tcph->win > cep->snd_wnd))))) {
+
+		cep->snd_wnd = tcph->win;
+		cep->snd_wl1 = tcph->seq;
+		cep->snd_wl2 = tcph->ack;
+
+		if (cep->snd_wnd > cep->max_sndwnd)
+			/* 今までの最大送信ウィンドサイズを更新する。*/
+			cep->max_sndwnd = cep->snd_wnd;
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+		if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_WOPEN_PEND) {
+
+			/*
+			 *  送信ウィンドバッファ用のネットワークバッファ割り当て中で、
+			 *  相手の受信ウィンドが空くのを待っているときの処理
+			 */
+			if (cep->snd_wnd > 0) {
+
+				/*
+				 *  相手の受信ウィンドが空いたときは、
+				 *  送信ウィンドバッファ用のネットワークバッファ割り当てを再開する。
+				 */
+				cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK)
+				                         |  TCP_CEP_FLG_WBCS_FREE |  TCP_CEP_FLG_POST_OUTPUT;
+				sig_sem(SEM_TCP_POST_OUTPUT);
+				}
+			}
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+		return true;
+		}
+	else
+		return false;
+	}
+
+/*
+ *  proc_urg -- 緊急データつきのセグメントの処理
+ */
+
+#ifdef TCP_CFG_EXTENTIONS
+
+static void
+proc_urg (T_TCP_HDR *tcph, T_TCP_CEP *cep)
+{
+	if ((tcph->flags & TCP_FLG_URG) && VALID_URG_POINTER(tcph->urp) &&
+	    TCP_FSM_HAVE_RCVD_FIN(cep->fsm_state) == 0) {
+
+		/* 緊急データつきのセグメントの処理 */
+
+		NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_URG_SEGS], 1);
+		if (tcph->urp + cep->rwbuf_count > cep->rbufsz) {
+
+			/*
+			 *  緊急ポインタの位置が受信ウィンドバッファの
+			 *  範囲を超えるときは何もしない。
+			 */
+			tcph->urp    = 0;
+			tcph->flags &= ~TCP_FLG_URG;
+			}
+
+		if (SEQ_GT(tcph->seq + tcph->urp, cep->rcv_up))
+			/* 緊急ポインタが更新されたときの処理 */
+			cep->rcv_up = tcph->seq + tcph->urp;
+
+		if ((tcph->flags & TCP_FLG_URG) && (tcph->urp + TCP_CFG_URG_OFFSET) < tcph->sum) {	/* tcph->sum は TCP の SDU 長 */
+
+			/*
+			 *  緊急ポインタの位置が、今回受信したセグメント内の場合は、
+			 *  コールバック関数を呼び出す。
+			 */
+			cep->urg_tcph = tcph;
+			if (IS_PTR_DEFINED(cep->callback)) {
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+				(*cep->callback)(GET_TCP_CEPID(cep), TEV_TCP_RCV_OOB, (void*)(uint32_t)1);
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+				uint32_t	len = 1;
+
+				(*cep->callback)(GET_TCP_CEPID(cep), TEV_TCP_RCV_OOB, (void*)&len);
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+				}
+			else {
+				syslog(LOG_WARNING, "[TCP] no call back for OOB, CEP: %d.", GET_TCP_CEPID(cep));
+				}
+
+			if (cep->urg_tcph != NULL) {
+				/* コールバック関数内で tcp_rcv_oob() を呼出さなかった。*/
+				cep->urg_tcph = NULL;
+				tcph->urp = 0;
+				}
+			else {
+				/* 
+				 *  コールバック関数内で tcp_rcv_oob() を呼出した時は、
+				 *  SDU 長の補正値を設定する。
+				 */
+				tcph->urp = 1;
+				}
+			}
+		else if (tcph->urp > 0) {
+			tcph->urp = 0;
+			}
+
+		}
+	else if (SEQ_GT(cep->rcv_nxt, cep->rcv_up)) {
+		cep->rcv_up = cep->rcv_nxt;
+		tcph->urp = 0;
+		}
+	}
+
+#else	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+static void
+proc_urg (T_TCP_HDR *tcph, T_TCP_CEP *cep)
+{
+	tcph->urp = 0;
+	}
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+/*
+ *  drop_after_ack -- 受信セグメントを破棄した後、ACK を返す (注意: 名前とは合っていない)。
+ *
+ *    戻り値:
+ *      RET_RETURN	正常、リターンする。
+ *	RET_RST_DROP	エラー、RST を送信し、セグメントを破棄する。
+ */
+
+static ER
+drop_after_ack (T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff)
+{
+	T_TCP_HDR *tcph = GET_TCP_HDR(input, thoff);
+
+	/*
+	 *    SYN 受信状態で、ACK が送達確認されていない最小送信 SEQ (snd_una) より
+	 *    前の値か、送信された最大 SEQ (snd_max) より後の値の場合は、相手に RST を
+	 *    送って終了する。これは、"LAND" DoS 攻撃への防御であり、偽造された SYN
+	 *    セグメントを送信しつづけるポート間での ACK ストームを防ぐ。
+	 */
+	if (cep->fsm_state == TCP_FSM_SYN_RECVD && (tcph->flags & TCP_FLG_ACK) &&
+	    (SEQ_GT(cep->snd_una, tcph->ack) ||
+	     SEQ_GT(tcph->ack, cep->snd_max)))
+		return RET_RST_DROP;
+
+	syscall(rel_net_buf(input));
+
+	/* 送信を指示する。*/
+	cep->flags |=  TCP_CEP_FLG_ACK_NOW | TCP_CEP_FLG_POST_OUTPUT;
+	sig_sem(SEM_TCP_POST_OUTPUT);
+	return RET_RETURN;
+	}
+
+/*
+ *  close_connection -- コネクション開放処理、相手から FIN を受信した。
+ */
+
+static void
+close_connection (T_TCP_CEP *cep, bool_t *needoutput)
+{
+	if (TCP_FSM_HAVE_RCVD_FIN(cep->fsm_state) == 0) {
+
+#ifdef TCP_CFG_DELAY_ACK
+
+		if (cep->flags & TCP_CEP_FLG_NEED_SYN)
+			cep->flags |= TCP_CEP_FLG_DEL_ACK;
+		else
+			cep->flags |= TCP_CEP_FLG_ACK_NOW;
+
+#else/* of #ifdef TCP_CFG_DELAY_ACK */
+
+		cep->flags |= TCP_CEP_FLG_ACK_NOW;
+
+#endif/* of #ifdef TCP_CFG_DELAY_ACK */
+
+		cep->rcv_nxt ++;
+		}
+
+	switch (cep->fsm_state) {
+	case TCP_FSM_SYN_RECVD:		/* SYN を受信し、SYN 送信済み	*/
+	case TCP_FSM_ESTABLISHED:	/* コネクション開設完了		*/
+		cep->fsm_state = TCP_FSM_CLOSE_WAIT;
+		syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_RWBUF_READY));
+		break;
+
+	case TCP_FSM_FIN_WAIT_1:	/* APP が終了、FIN 送信済み、ACK 待ち */
+		cep->fsm_state = TCP_FSM_CLOSING;
+		break;
+
+	case TCP_FSM_FIN_WAIT_2:	/* 相手からの FIN 待ち */
+		cep->fsm_state = TCP_FSM_TIME_WAIT;
+		tcp_cancel_timers(cep);
+		cep->timer[TCP_TIM_2MSL] = 2 * TCP_TVAL_MSL;
+
+		/*
+		 *  FIN WAIT 2 状態では、
+		 *  受信は可能であるが、すでに送信は終了している。
+		 *  相手の送信も終了したので、入力タスクのみ起床する。
+		 */
+		syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY));
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+		/* 相手からの FIN に対して応答を返す。*/
+		tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una,
+		            cep->rbufsz - cep->rwbuf_count, TCP_FLG_ACK);
+		cep->flags &= ~TCP_CEP_FLG_ACK_NOW;
+		*needoutput = false;
+
+		/*
+		 *  必要な情報を Time Wait 用 TCP 通信端点に移して、
+		 *  標準の TCP 通信端点を開放する。
+		 */
+		tcp_move_twcep(cep);
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+		break;
+
+	case TCP_FSM_TIME_WAIT:		/* 相手からの FIN 受信済み、時間待ち */
+		cep->timer[TCP_TIM_2MSL] = 2 * TCP_TVAL_MSL;
+		break;
+		}
+	}
+
+/*
+ *  tcp_input -- TCP の入力関数
+ *
+ *	注意: input には IF ヘッダと IP ヘッダが先頭にある。
+ */
+
+uint_t
+tcp_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+	T_NET_BUF	*input = *inputp;
+	T_TCP_HDR	*tcph;
+	T_TCP_CEP	*cep = NULL;
+	T_TCP_SEQ	iss = 0;
+	ER		ret;
+	bool_t		needoutput = false;
+	int_t		rbfree;
+	int32_t		todrop, win;
+	uint16_t	seglen;
+	uint8_t		flags;
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+	T_TCP_TWCEP	*twcep;
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+	NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_OCTETS],
+	              input->len - GET_IF_IP_HDR_SIZE(input));
+	NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_SEGS], 1);
+	NET_COUNT_MIB(tcp_stats.tcpInSegs, 1);
+
+	/* ヘッダ長をチェックする。*/
+	if (input->len < IF_IP_TCP_HDR_SIZE(input)) {
+		NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_BAD_HEADERS], 1);
+		goto drop;
+		}
+
+	tcph = GET_TCP_HDR(input, *offp);
+
+	seglen  = input->len - *offp;				/* TCP のセグメント長 */
+
+	if (IN_CKSUM(input, IPPROTO_TCP, *offp, (uint_t)seglen) != 0) {
+		NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_BAD_CKSUMS], 1);
+		goto drop;
+		}
+
+	/* TCP ヘッダ長をチェックする。*/
+	if (TCP_HDR_LEN(tcph->doff) < TCP_HDR_SIZE || TCP_HDR_LEN(tcph->doff) > seglen) {
+		NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_BAD_HEADERS], 1);
+		goto drop;
+		}
+	tcph->sum = seglen - TCP_HDR_LEN(tcph->doff);		/* ここから tcph->sum は TCP の SDU 長 */
+
+	/*
+	 *  SYN と FIN の両ビットがセットされていれば破棄する。nmap 等の対策
+	 *  ただし、RFC1644 T/TCP 拡張機能と競合する。
+	 */
+	if ((tcph->flags & (TCP_FLG_SYN | TCP_FLG_FIN)) == (TCP_FLG_SYN | TCP_FLG_FIN))
+		goto drop;
+
+	/* ネットワークオーダーからホストオーダーに変換する。*/
+
+	NTOHL(tcph->seq);
+	NTOHL(tcph->ack);
+	NTOHS(tcph->win);
+	NTOHS(tcph->urp);
+	NTOHS(tcph->sport);
+	NTOHS(tcph->dport);
+
+	/* SDU 長 より 緊急ポインタが大きい場合 */
+	if (tcph->urp > tcph->sum)
+		goto drop;
+
+find_cep:
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+	/*
+	 *  状態が Time Wait 中の CEP を探索する。
+	 */
+	twcep = tcp_find_twcep(input, *offp);
+	if (twcep != NULL) {
+
+		if (tcph->flags & TCP_FLG_RST)		/* RST フラグを受信したときは無視する。*/
+			goto drop;
+		else {
+
+			/*
+			 *    TCP 通信端点が Time Wait の時、相手ホストからセグメントが来たときは、
+			 *    相手ホストの FIN に対する自ホストの ACK セグメントが途中で
+			 *    損失したことを意味しているので、ACK セグメントを再送する。
+			 */
+
+			/* ホストオーダーからネットワークオーダーに戻す。*/
+			HTONS(tcph->sport);
+			HTONS(tcph->dport);
+
+			tcp_respond(input, NULL, twcep->rcv_nxt, twcep->snd_una, twcep->rbufsz - twcep->rwbuf_count, TCP_FLG_ACK);
+			}
+		return IPPROTO_DONE;
+		}
+	else
+		/* 標準の TCP 通信端点を得る。*/
+		cep = tcp_find_cep(input, *offp);
+
+#else	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+	/* TCP 通信端点を得る。*/
+	cep = tcp_find_cep(input, *offp);
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+	/*
+	 *  TCP 通信端点がない場合と CEP の状態がクローズなら破棄する。
+	 */
+	if (cep == NULL) {
+		syslog(LOG_INFO, "[TCP] unexp port: %d.", tcph->dport);
+		goto reset_drop;
+		}
+
+#ifdef TCP_CFG_TRACE
+
+	tcp_input_trace(input, cep);
+
+#endif	/* of #ifdef TCP_CFG_TRACE */
+
+
+	if (cep->fsm_state == TCP_FSM_CLOSED)
+		goto drop;
+
+	/*
+	 *  コネクション開設済みでセグメントを受信したときは、
+	 *  アイドル時間と生存確認タイマをリセットする。
+	 */
+	cep->idle = 0;
+	if (TCP_FSM_HAVE_ESTABLISHED(cep->fsm_state)) {
+		cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_IDLE;
+		}
+
+	/* CEP の状態が LISTEN 以外の時は、オプションを処理する。*/
+	if (cep->fsm_state != TCP_FSM_LISTEN)
+		parse_option(tcph, cep);
+
+	/*
+	 *  受信可能ウィンドサイズを計算する。
+	 *
+	 *  rcv_nxt:     受信を期待している最小の SEQ（これ以前は受信済み）
+	 *  rcv_adv:     受信を期待している最大の SEQ
+	 *  rbufsz:      受信ウィンドバッファサイズ
+	 *  rwbuf_count:  受信ウィンドバッファにあるデータ量
+	 *  tcph->sum:   今回受信した SDU サイズ
+	 *
+	 *  今回受信したセグメントを順序整列キューに連結する
+	 *  可能性があるので tcph->sum を考慮する。
+	 *
+	 */
+	win = cep->rbufsz - (cep->rwbuf_count + tcph->sum);
+	if (win < 0)
+		win = 0;
+	if (win > (int32_t)(cep->rcv_adv - cep->rcv_nxt))
+		cep->rcv_wnd = win;
+	else
+		cep->rcv_wnd = cep->rcv_adv - cep->rcv_nxt;
+
+	/* CEP の状態により処理を行う。*/
+
+	if (cep->fsm_state == TCP_FSM_LISTEN) {		/* 受動オープン (LISTEN) の処理。*/
+		if ((ret = listening(input, cep, *offp, iss)) == RET_RST_DROP)
+			goto reset_drop;
+		else if (ret == RET_DROP)
+			goto drop;
+		trim_length(tcph, cep);			/* 受信した SDU 長を調整する。*/
+
+		if (tcph->flags & TCP_FLG_ACK) {	/* ACK フラグの処理 */
+			if ((ret = proc_ack2(input, cep, *offp, &needoutput)) == RET_DROP)
+				goto drop;
+			else if (ret == RET_RST_DROP)
+				goto reset_drop;
+			else if (ret == RET_RETURN)
+				return IPPROTO_DONE;
+			}
+		}
+	else if (cep->fsm_state == TCP_FSM_SYN_SENT) {	/* 能動オープン、SYN 送信済み	*/
+		if ((ret = syn_sent(tcph, cep)) == RET_RST_DROP)
+			goto reset_drop;
+		else if (ret == RET_DROP)
+			goto drop;
+		trim_length(tcph, cep);			/* 受信した SDU 長を調整する。*/
+
+		if (tcph->flags & TCP_FLG_ACK) {	/* ACK フラグの処理 */
+			if ((ret = proc_ack2(input, cep, *offp, &needoutput)) == RET_DROP)
+				goto drop;
+			else if (ret == RET_RST_DROP)
+				goto reset_drop;
+			else if (ret == RET_RETURN)
+				return IPPROTO_DONE;
+			}
+		}
+	else {
+		if (cep->fsm_state == TCP_FSM_SYN_RECVD) {	/* SYN を受信、SYN 送信済み	*/
+			/*
+			 *  相手から受信確認が送られて来ても、
+			 *
+			 *    ACK <= 未確認の最小送信 SEQ (snd_una) &&
+			 *           送信した最大     SEQ (snd_max) < ACK
+			 *
+			 *  なら、リセットを送ってセグメントを破棄する。
+			 */
+			if ((tcph->flags & TCP_FLG_ACK) &&
+			    (SEQ_LE(tcph->ack, cep->snd_una) ||
+			     SEQ_GT(tcph->ack, cep->snd_max)))
+			     	goto reset_drop;
+			}
+
+		/* 
+		 *  RST フラグを受信したときの処理 (異常切断)
+		 */
+		if (tcph->flags & TCP_FLG_RST) {
+			if (SEQ_GE(tcph->seq, cep->last_ack_sent) &&
+			    SEQ_LT(tcph->seq, cep->last_ack_sent + cep->rcv_wnd)) {
+				/*
+				 *  受信したセグメントの SEQ が、最後に送信した ACK (last_ack_sent)
+				 *  から、受信ウインドウサイズまでの間の処理
+				 */
+				switch (cep->fsm_state) {
+				case TCP_FSM_SYN_RECVD:		/* SYN を受信し、SYN 送信済み		*/
+
+					cep->net_error = EV_CNNRF;	/* 接続不能 */
+					cep->error     = E_CLS;
+					NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_RSTS], 1);
+					NET_COUNT_MIB(tcp_stats.tcpAttemptFails, 1);
+					cep = tcp_close(cep);
+					break;
+
+				case TCP_FSM_ESTABLISHED:	/* コネクション開設完了			*/
+				case TCP_FSM_CLOSE_WAIT:	/* FIN 受信、クローズ待ち		*/
+					NET_COUNT_MIB(tcp_stats.tcpEstabResets, 1);
+					/* fallthrough */
+
+				case TCP_FSM_FIN_WAIT_1:	/* 終了して、FIN 送信済み		*/
+				case TCP_FSM_FIN_WAIT_2:	/* 終了、FIN 伝達確認受信、FIN待ち	*/
+
+					cep->net_error = EV_CNRST;	/* 接続リセット */
+					cep->error     = E_CLS;
+					NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_RSTS], 1);
+					/* no break; */
+
+				case TCP_FSM_CLOSING:		/* 終了、FIN 交換済み、ACK 待ち	*/
+				case TCP_FSM_LAST_ACK:		/* FIN 受信、終了、ACK 待ち	*/
+
+					cep = tcp_close(cep);
+					break;
+					}
+				}
+			goto drop;
+			}
+
+		/*
+		 *  CEP の状態が SYN を受信し、SYN 送信済みの場合は、
+		 *  受信ウィンドに収まるようにデータを
+		 *  調整する前に、この接続によるパケットかどうかを検証する。
+		 *
+		 *    受信した相手の SEQ < 相手の SEQ の初期値 (irs)
+		 *
+		 *  これは、"LAND" DoS 攻撃の防御である。
+		 */
+		if (cep->fsm_state == TCP_FSM_SYN_RECVD && SEQ_LT(tcph->seq, cep->irs)) {
+			goto reset_drop;
+			}
+
+		/*
+		 *  受信を期待している最小の SEQ (rcv_nxt) - 受信した相手の SEQ が
+		 *  正なら、rcv_nxt 以前のデータはすでに受信しているので、その部分を
+		 *  削除する。
+		 *                           <---------- rcv_wnd --------->
+		 *                           rcv_nxt                      rcv_nxt + rcv_wnd
+		 *                           v                            v
+		 *                      -----+----------------------------+-----
+		 *                           |                            |
+		 *                      -----+----------------------------+-----
+		 *           +----------------------+
+		 *           |***************|      |
+		 *           +----------------------+
+		 *           ^                      ^
+		 *           seq                    seq + len
+		 *           <---------------> 削除する。
+		 */
+		todrop = cep->rcv_nxt - tcph->seq;
+		if (todrop > 0) {
+
+			/*
+			 *  SYN フラグがついているときは、その分 (1 オクテット)
+			 *  SEQ を進め、緊急ポインタと削除する長さを調整する。
+			 */
+			if (tcph->flags & TCP_FLG_SYN) {
+				tcph->flags &= ~TCP_FLG_SYN;
+				tcph->seq ++;
+				if (tcph->urp > 1)
+					tcph->urp --;
+				else
+					tcph->flags &= ~TCP_FLG_URG;
+				todrop --;
+				}
+
+			/*
+			 *  削除する長さが SDU より長い、つまり、受信を期待している
+			 *  最小の SEQ (rcv_nxt) に達していないか、
+			 *  削除する長さが SDU と同じで、FIN フラグがついてなければ
+			 *  全て削除する。
+			 */
+			if ( todrop >  tcph->sum ||		/* tcph->sum は TCP の SDU 長 */
+			    (todrop == tcph->sum && (tcph->flags & TCP_FLG_FIN) == 0)) {
+				tcph->flags &= ~TCP_FLG_FIN;
+				cep->flags |= TCP_CEP_FLG_ACK_NOW;
+				todrop = tcph->sum;		/* tcph->sum は TCP の SDU 長 */
+				}
+
+			/*
+			 *  SDU を前に詰める。
+			 */
+			if (todrop < tcph->sum) {		/* tcph->sum は TCP の SDU 長 */
+				memcpy(GET_TCP_SDU(input, *offp),
+				       GET_TCP_SDU(input, *offp) + todrop, (size_t)(tcph->sum - todrop));
+				}
+
+			/*
+			 *  SEQ と SDU 長を調整する。
+			 */
+			tcph->seq +=     todrop;
+			tcph->sum -= (uint16_t)todrop;	/* tcph->sum は TCP の SDU 長 */
+
+			/*
+			 *  緊急ポインタを調整する。
+			 */
+			if (tcph->urp > todrop)
+				tcph->urp -= (uint16_t)todrop;
+			else {
+				tcph->flags &= ~TCP_FLG_URG;
+				tcph->urp = 0;
+				}
+
+			NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DUP_SEGS], 1);
+			}
+
+		/*  
+		 *  もしユーザタスクが終了した後に、データを受信した
+		 *  場合は、RST を送る。
+		 */
+		if (cep->fsm_state == TCP_FSM_LAST_ACK && tcph->sum > 0) {	/* tcph->sum は TCP の SDU 長 */
+			cep = tcp_close(cep);
+			goto reset_drop;
+			}
+
+		/*
+		 *  受信セグメントが受信ウィンドを超える場合は、
+		 *  超えた分を削る。
+		 *
+		 *       <---------- rcv_wnd --------->
+		 *       rcv_nxt                      (rcv_nxt + rcv_wnd)
+		 *       v                            v
+		 *  -----+----------------------------+-----
+		 *       |                            |
+		 *  -----+----------------------------+-----
+		 *                    +----------------------+
+		 *                    |               |******|
+		 *                    +----------------------+
+		 *                    ^                      ^
+		 *                    seq                    seq + len
+		 *                                     <-----> 削除する。
+		 */
+		todrop = (tcph->seq + tcph->sum) - (cep->rcv_nxt + cep->rcv_wnd);	/* tcph->sum は TCP の SDU 長 */
+		if (todrop > 0) {
+			if (todrop > tcph->sum) {					/* tcph->sum は TCP の SDU 長 */
+				/*
+				 *  受信した SDU の全てが受信ウィンドを超える場合。
+				 *
+				 *  TIME_WAIT 中に、新たな接続要求を受信したら
+				 *  古い接続を破棄し、新たな接続を開始する。
+				 *  ただし、SEQ は前より進んでいなければならない。
+				 */
+				if ((tcph->flags & TCP_FLG_SYN) &&
+				    cep->fsm_state == TCP_FSM_TIME_WAIT &&
+				    SEQ_GT(tcph->seq, cep->rcv_nxt)) {
+					iss = cep->snd_nxt + TCP_ISS_INCR();
+					tcp_close(cep);
+					syscall(dly_tsk(0));
+					goto find_cep;
+				    	}
+
+				/*
+				 *  受信ウィンドが 0 で、受信した SEQ と
+				 *  受信を期待している最小の SEQ が一致したときは
+				 *  ACK を返す。それ以外はデータを破棄し、ACK を返す。
+				 */
+				if (cep->rcv_wnd == 0 && (tcph->seq == cep->rcv_nxt || tcph->sum == 0)) {
+					cep->flags |= TCP_CEP_FLG_ACK_NOW;
+					}
+				else if (drop_after_ack(input, cep, *offp) == RET_RST_DROP)
+					goto reset_drop;
+				else {
+					return IPPROTO_DONE;
+					}
+				}
+			tcph->sum -= (uint16_t)todrop;	/* tcph->sum は TCP の SDU 長 */
+			tcph->flags &= ~(TCP_FLG_PUSH | TCP_FLG_FIN);
+			}
+
+		/*
+		 *  もし、SYN がセットされていれば、
+		 *  エラーなので RST を送り、接続を破棄する。
+		 */
+		if (tcph->flags & TCP_FLG_SYN) {
+			cep->net_error = EV_CNRST;
+			cep = tcp_drop(cep, E_CLS);
+			goto reset_drop;
+			}
+
+		/*
+		 *  もし、ACK がセットされていない場合は、
+		 *  状態が SYN 受信済みか
+		 *  SYN を送信しようとしていれば、処理を続けるが、
+		 *  それ以外はセグメントを破棄して終了する。
+		 */
+		if ((tcph->flags & TCP_FLG_ACK) == 0) {
+			if (!(cep->fsm_state == TCP_FSM_SYN_RECVD || (cep->flags & TCP_CEP_FLG_NEED_SYN)))
+				goto drop;
+			}
+		else {
+			/*
+			 * ACK の処理
+			 */
+			ret = proc_ack1(input, cep, *offp, &needoutput);
+			if (ret == RET_DROP)
+				goto drop;
+			else if (ret == RET_RST_DROP)
+				goto reset_drop;
+			else if (ret == RET_RETURN)
+				return IPPROTO_DONE;
+			}
+		}
+
+/* step 6 */
+
+	/* 送信ウィンドを更新する。*/
+	if (update_wnd(tcph, cep) == true)
+		needoutput = true;
+
+	/* 緊急データを処理する。*/
+	proc_urg(tcph, cep);
+
+/* do data */
+
+	/*
+	 *  SDU があるか、FIN を未受信の状態で、最初に FIN を受信したとき、
+	 *  受信セグメントキューに net_buf を追加する。
+	 *  それ以外の場合は、セグメントを破棄する。
+	 */
+	flags = tcph->flags;
+	if ((tcph->sum > 0 || (flags & TCP_FLG_FIN)) &&		/* tcph->sum は TCP の SDU 長 */
+	    TCP_FSM_HAVE_RCVD_FIN(cep->fsm_state) == 0) {
+		flags = reassemble(input, cep, *offp, flags);
+		}
+	else {
+		syscall(rel_net_buf(input));
+		flags &= ~TCP_FLG_FIN;
+		}
+
+	/*
+	 *  FIN を受信したらコネクションをクローズする。
+	 */
+	if (flags & TCP_FLG_FIN)
+		close_connection(cep, &needoutput);
+
+	/* 出力を行った後終了する。*/
+	if (needoutput == true || (cep->flags & TCP_CEP_FLG_ACK_NOW)) {
+		/* 送信を指示する。*/
+		cep->flags |=  TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		}
+
+	return IPPROTO_DONE;
+
+reset_drop:
+	/*
+	 *  RST 送信処理
+	 */
+
+	if ((tcph->flags & TCP_FLG_RST) || IN_IS_NET_ADDR_MULTICAST(input))
+		goto drop;
+
+	/* ホストオーダーからネットワークオーダーに戻す。*/
+
+	HTONS(tcph->sport);
+	HTONS(tcph->dport);
+
+	if (cep == NULL)
+		rbfree = 0;
+	else
+		rbfree = cep->rbufsz - cep->rwbuf_count;
+
+	if (tcph->flags & TCP_FLG_ACK)
+		tcp_respond(input, cep, 0, tcph->ack, rbfree, TCP_FLG_RST);
+	else {
+		if (tcph->flags & TCP_FLG_SYN)
+			tcph->sum ++;		/* tcph->sum は SDU 長 */
+		tcp_respond(input, cep, tcph->seq + tcph->sum, 0, rbfree, TCP_FLG_RST | TCP_FLG_ACK);
+		}
+
+	/* input は tcp_respoond で返却される。*/
+	NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_RSTS], 1);
+	NET_COUNT_MIB(tcp_stats.tcpOutRsts, 1);
+	return IPPROTO_DONE;
+
+drop:
+	NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DROP_SEGS], 1);
+	NET_COUNT_MIB(tcp_stats.tcpInErrs, 1);
+	syscall(rel_net_buf(input));
+	return IPPROTO_DONE;
+	}
+
+#endif	/* of #ifdef SUPPORT_TCP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_output.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_output.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_output.c	(revision 398)
@@ -0,0 +1,1119 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp_output.c	8.4 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/netinet/tcp_output.c,v 1.32.2.2 1999/08/29 16:29:55 peter Exp $
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+
+#ifdef SUPPORT_TCP
+
+/*
+ *  関数
+ */
+
+static ER send_segment (bool_t *sendalot, T_TCP_CEP *cep, uint_t doff, uint_t win, uint_t len, uint8_t flags);
+static void tcp_output (T_TCP_CEP *cep);
+
+/*
+ *  変数
+ */
+
+/* 出力時のフラグを FSM 状態により選択するための表 */
+
+const static uint8_t tcp_outflags[] = {
+	TCP_FLG_RST | TCP_FLG_ACK,	/*  0, クローズ				*/
+	0,				/*  1, 受動オープン			*/
+	TCP_FLG_SYN,			/*  2, 能動オープン、SYN 送信済み	*/
+	TCP_FLG_SYN | TCP_FLG_ACK,	/*  3, SYM を受信し、SYN 送信済み	*/
+	TCP_FLG_ACK,			/*  4, コネクション開設完了		*/
+	TCP_FLG_ACK,			/*  5, FIN 受信、クローズ待ち		*/
+	TCP_FLG_FIN | TCP_FLG_ACK,	/*  6, 終了して、FIN 送信済み		*/
+	TCP_FLG_FIN | TCP_FLG_ACK,	/*  7, 終了、FIN 交換済み、ACK 待ち	*/
+	TCP_FLG_FIN | TCP_FLG_ACK,	/*  8, FIN 受信、終了、ACK 待ち		*/
+	TCP_FLG_ACK,			/*  9, 終了、FIN 伝達確認受信、FIN待ち	*/
+	TCP_FLG_ACK,			/* 10, 終了、時間待ち			*/
+	};
+
+/*
+ *  send_segment -- TCP 出力処理
+ */
+
+static ER
+send_segment (bool_t *sendalot, T_TCP_CEP *cep, uint_t doff, uint_t win, uint_t len, uint8_t flags)
+{
+	T_NET_BUF	*output;
+	T_TCP_HDR	*tcph;
+	uint_t		optlen, hdr_offset;
+	ER		error;
+
+#ifdef TCP_CFG_OPT_MSS
+
+	uint8_t		*optp;
+
+	if (flags & TCP_FLG_SYN)
+		optlen = TCP_OPT_LEN_MAXSEG;
+	else
+		optlen = 0;
+
+#else/* of #ifdef TCP_CFG_OPT_MSS */
+
+	optlen = 0;
+
+#endif/* of #ifdef TCP_CFG_OPT_MSS */
+
+	NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_SEGS], 1);
+	NET_COUNT_MIB(tcp_stats.tcpOutSegs, 1);
+
+	/*
+	 *  セグメント長を、相手の最大受信セグメント長に調整する。
+	 *  もし、超えている場合は、超えた分を後で送信する。
+	 *  このため、FIN ビットをクリアする。
+	 *
+	 *  オリジナルでは、t_maxopd を制限長にしているが、
+	 *  本実装では、相手の最大受信セグメントにする。
+	 */
+	if (len + optlen > cep->maxseg) {
+		flags &= ~TCP_FLG_FIN;
+		len = cep->maxseg - optlen;
+		*sendalot = true;
+		}
+
+	/*
+	 *  送信バッファが空になるときは PUSH フラグを設定する。
+	 */
+	if (len && doff + len >= cep->swbuf_count)
+		flags |= TCP_FLG_PUSH;
+
+#if defined(TCP_CFG_SWBUF_CSAVE_ONLY)
+		
+	if (len > 0 && ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_SEND_READY ||
+	                (cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_SENT)) {
+
+		/*
+		 *  送信ウインドバッファが開放されないようにして、
+		 *  ネットワークバッファを出力に移す。
+		 */
+		cep->swbufq->flags |= NB_FLG_NOREL_IFOUT;
+		output = cep->swbufq; 
+		}
+	else {
+
+		/*
+		 *  ACK 完了状態で、この関数が呼び出されることもある。
+		 *  この時は、len を 0 にして、処理を継続する。
+		 */
+		len = 0;
+		if ((error = tcpn_get_segment(&output, cep, optlen,
+	                                    len, (uint_t)net_buf_max_siz(),
+	                                    NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF)) != E_OK) {
+			if (cep->timer[TCP_TIM_REXMT] == 0)
+				cep->timer[TCP_TIM_REXMT] = cep->rxtcur;
+			goto err_ret;
+			}
+		}
+
+#elif defined(TCP_CFG_SWBUF_CSAVE)	/* of #if defined(TCP_CFG_SWBUF_CSAVE_ONLY) */
+
+	if (IS_PTR_DEFINED(cep->sbuf)) {
+		if ((error = tcpn_get_segment(&output, cep, optlen,
+		                             len, (uint_t)net_buf_max_siz(),
+		                             NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF)) != E_OK) {
+			if (cep->timer[TCP_TIM_REXMT] == 0)
+				cep->timer[TCP_TIM_REXMT] = cep->rxtcur;
+			goto err_ret;
+			}
+		}
+	else if (len > 0 && ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_SEND_READY ||
+	                     (cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_SENT)) {
+
+		/*
+		 *  送信ウインドバッファが開放されないようにして、
+		 *  ネットワークバッファを出力に移す。
+		 */
+		cep->swbufq->flags |= NB_FLG_NOREL_IFOUT;
+		output = cep->swbufq; 
+		}
+	else {
+
+		/*
+		 *  ACK 完了状態で、この関数が呼び出されることもある。
+		 *  この時は、len を 0 にして、処理を継続する。
+		 */
+		len = 0;
+		if ((error = tcpn_get_segment(&output, cep, optlen,
+	                                    len, (uint_t)net_buf_max_siz(),
+	                                    NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF)) != E_OK) {
+			if (cep->timer[TCP_TIM_REXMT] == 0)
+				cep->timer[TCP_TIM_REXMT] = cep->rxtcur;
+			goto err_ret;
+			}
+		}
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE_ONLY) */
+
+	if ((error = tcpn_get_segment(&output, cep, optlen,
+	                             len, (uint_t)net_buf_max_siz(),
+	                             NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF)) != E_OK) {
+		if (cep->timer[TCP_TIM_REXMT] == 0)
+			cep->timer[TCP_TIM_REXMT] = cep->rxtcur;
+		goto err_ret;
+		}
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE_ONLY) */
+
+	/*
+	 *  TCP オプションの設定を行う。
+	 *  本実装では、最大セグメントサイズのみ設定する。
+	 */
+	hdr_offset = IF_IP_TCP_HDR_OFFSET(output);
+	if (flags & TCP_FLG_SYN) {
+		cep->snd_nxt = cep->iss;
+
+#ifdef TCP_CFG_OPT_MSS
+
+		optp = GET_TCP_OPT(output, hdr_offset);
+		*optp ++ = TCP_OPT_MAXSEG;
+		*optp ++ = TCP_OPT_LEN_MAXSEG;
+		*(uint16_t*)optp = htons(DEF_TCP_RCV_SEG);
+
+#endif/* of #ifdef TCP_CFG_OPT_MSS */
+
+		}
+
+	/* TCP SDU に送信データをコピーする。*/
+
+	if (len > 0) {
+		if (SEQ_LT(cep->snd_nxt, cep->snd_max)) {
+			NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_REXMIT_SEGS], 1);
+			NET_COUNT_MIB(tcp_stats.tcpRetransSegs, 1);
+			}
+		TCP_READ_SWBUF(cep, output, len, doff);
+		}
+	else {
+		if (cep->flags & TCP_CEP_FLG_ACK_NOW)
+			NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_ACKS], 1);
+		if (flags & (TCP_FLG_FIN | TCP_FLG_SYN | TCP_FLG_RST))
+			NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_CNTL_SEGS],  1);
+
+
+#ifdef TCP_CFG_EXTENTIONS
+
+		if (SEQ_LT(cep->snd_up, cep->snd_una))
+			NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_URG_SEGS], 1);
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+		}
+
+	/*
+	 * snd_max: 送信した最大 SEQ
+	 * snd_nxt: 次に送信する SEQ
+	 *
+	 *  相手から FIN を受信し、まだ FIN を送信していないか、
+	 *  送るデータがないときは、FIN を相手に届けるため、
+	 *  セグメントを送信するが、SEQ は進めない。
+	 */
+	if ((flags & TCP_FLG_FIN) && (cep->flags & TCP_CEP_FLG_SENT_FIN) &&
+	    cep->snd_nxt == cep->snd_max) {
+		cep->snd_nxt --;
+		}
+
+	tcph = GET_TCP_HDR(output, hdr_offset);
+
+	/*
+	 *  SEQ、ACK、フラグの設定。
+	 */
+	if (len > 0 || (flags & (TCP_FLG_SYN | TCP_FLG_FIN)) || cep->timer[TCP_TIM_PERSIST] != 0)
+		tcph->seq = htonl(cep->snd_nxt);
+	else
+		tcph->seq = htonl(cep->snd_max);
+
+	/*
+	 *  rcv_nxt: 受信を期待している最小の SEQ
+	 */
+	tcph->ack   = htonl(cep->rcv_nxt);
+	tcph->flags = flags;
+
+	/*
+	 *  受信ウィンドの計算
+	 *
+	 *  rbufsz: 受信用バッファサイズ
+	 *  maxseg: 相手の最大受信セグメントサイズ	
+	 */
+	if (win < (cep->rbufsz / 4) && win < cep->maxseg)
+		win = 0;
+
+	/*
+	 *  rcv_nxt: 受信を期待している最小の SEQ
+	 *  rcv_adv: 受信を期待している最大の SEQ
+	 */
+	if ((int32_t)win < (int32_t)(cep->rcv_adv - cep->rcv_nxt))
+		win = (uint_t)(cep->rcv_adv - cep->rcv_nxt);
+
+	tcph->win = htons(win);
+
+#ifdef TCP_CFG_EXTENTIONS
+
+	/*
+	 *  緊急ポインタの設定
+	 */
+	if (SEQ_GT(cep->snd_up, cep->snd_nxt)) {
+		if (TCP_CFG_URG_OFFSET)
+			tcph->urp    = htons((uint16_t)(cep->snd_up - cep->snd_nxt));
+		else
+			tcph->urp    = htons((uint16_t)(cep->snd_up - cep->snd_nxt - 1));
+		tcph->flags |= TCP_FLG_URG;
+		}
+	else {
+		tcph->urp = 0;
+		cep->snd_up  = cep->snd_una;
+		}
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+	/*
+	 *  チェックサムを設定する。
+	 */
+	tcph->sum = 0;
+	tcph->sum = IN_CKSUM(output, IPPROTO_TCP, hdr_offset, GET_TCP_HDR_SIZE(output, hdr_offset) + len);
+
+	/* ネットワークバッファ長を調整する。*/
+	output->len = (uint16_t)(GET_IF_IP_TCP_HDR_SIZE(output, hdr_offset) + len);
+
+	/*
+	 *  タイマの調整
+	 */
+	if ((cep->flags & TCP_CEP_FLG_FORCE) == 0 || cep->timer[TCP_TIM_PERSIST] == 0) {
+		T_TCP_SEQ startseq = cep->snd_nxt;
+
+		/*
+		 *  次に送信する SEQ (snd_nxt) を今回送信するデータ数分進める。
+		 */
+		if (flags & TCP_FLG_SYN)
+			cep->snd_nxt ++;
+		if (flags & TCP_FLG_FIN) {
+			cep->flags |= TCP_CEP_FLG_SENT_FIN;
+			cep->snd_nxt ++;
+			}
+
+		cep->snd_nxt += len;
+
+		/*
+		 *  次に送信する SEQ (snd_nxt) が
+		 *  送信した最大 SEQ (snd_max) より進んでいれば、
+		 *  送信した最大 SEQ (snd_max) を更新する。
+		 */
+		if (SEQ_GT(cep->snd_nxt, cep->snd_max)) {
+			cep->snd_max = cep->snd_nxt;
+			/*
+			 *  もし、往復時間計測を行っていなければ、
+			 *  この送信に時間を合わせる。
+			 */
+			if (cep->rtt == 0) {
+				cep->rtt   = 1;
+				cep->rtseq = startseq;	/* 更新前の cep->snd_nxt */
+				}
+			}
+
+		/*
+		 *  もし設定されていないか、ACK または保留が発生していなければ、
+		 *  再送タイマを設定する。設定する初期値は、
+		 * 「滑らかな往復時間 + 2 × 往復時間変動」である。
+		 *  再送時間のバックオフに使われるシフトカウントも初期化する。
+		 */
+		if (cep->timer[TCP_TIM_REXMT] == 0 && cep->snd_nxt != cep->snd_una) {
+			cep->timer[TCP_TIM_REXMT] = cep->rxtcur;
+			if (cep->timer[TCP_TIM_PERSIST] != 0) {
+				cep->timer[TCP_TIM_PERSIST] = 0;
+				cep->rxtshift = 0;
+				}
+			}
+		}
+
+	/*
+	 *  次に送信する SEQ (snd_nxt) + 今回送信するデータ数 (len) が
+	 *  送信した最大 SEQ (snd_max) より進んでいれば、
+	 *  送信した最大 SEQ (snd_max) を更新する。
+	 */
+	else if (SEQ_GT(cep->snd_nxt + len, cep->snd_max))
+		cep->snd_max = cep->snd_nxt + len;
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+	if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_SEND_READY)
+		cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) | TCP_CEP_FLG_WBCS_SENT;
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+#ifdef TCP_CFG_TRACE
+
+	tcp_output_trace(output, cep);
+
+#endif	/* of #ifdef TCP_CFG_TRACE */
+
+	/* ネットワーク層 (IP) の出力関数を呼び出す。*/
+	if ((error = IP_OUTPUT(output, TMO_TCP_OUTPUT)) != E_OK)
+		goto err_ret;
+
+	/*
+	 *  相手に伝えたウィンドウサイズ (win) が 0 以上で、
+	 *  受信を期待している最小の SEQ (rcv_nxt) + win が
+	 *  受信を期待している最大の SEQ (rcv_adv) より進んでいれば
+	 *  受信を期待している最大の SEQ を更新する。
+	 */
+	if (win > 0 && SEQ_GT(cep->rcv_nxt + win, cep->rcv_adv)) {
+		cep->rcv_adv = cep->rcv_nxt + win;
+		}
+
+	/*
+	 *  最後に送信した ACK (last_ack_sent) を更新する。
+	 */
+	cep->last_ack_sent = cep->rcv_nxt;
+
+	/*
+	 *  フラグの設定を行う。
+	 */
+	cep->flags &= ~(TCP_CEP_FLG_ACK_NOW | TCP_CEP_FLG_DEL_ACK);
+	if (cep->flags & TCP_CEP_FLG_FORCE_CLEAR)
+		cep->flags &= ~(TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR);
+
+	return E_OK;
+
+err_ret:
+	/*
+	 * 以下に関係しないフラグをクリアーする。
+	 * ・送受信ウィンドバッファの省コピー機能
+	 * ・動的な通信端点の生成・削除機能
+	 */
+	cep->flags &= TCP_CEP_FLG_NOT_CLEAR;
+
+	return error;
+	}
+
+/*
+ *  tcp_output -- TCP 出力処理
+ */
+
+void
+tcp_output (T_TCP_CEP *cep)
+{
+	bool_t	sendalot = true, idle;
+	ER	error = E_OK;
+	int32_t	len;
+	uint_t	doff, win;
+	uint8_t	flags;
+
+	/*
+	 *  snd_una: 未確認の最小送信 SEQ	 または、確認された最大送信 SEQ
+	 *  snd_max: 送信した最大 SEQ
+	 */
+	idle = (cep->snd_max == cep->snd_una);
+
+	/*
+	 *  idle:   アイドル時間
+	 *  rxtcur: 現在の再送タイムアウト
+	 */
+	if (idle && cep->idle >= cep->rxtcur)
+
+		/*
+		 *  snd_cwnd: 輻輳ウィンドサイズ
+		 *  maxseg  : 相手の最大受信セグメントサイズ
+		 *
+		 *  長時間アイドルだったのでスロースタート制御に設定する。
+		 */
+		cep->snd_cwnd = cep->maxseg;
+
+	while (error == E_OK && sendalot) {
+		sendalot = false;
+
+		/*
+		 *  snd_nxt: 次に送信する SEQ、この時点では、前回送信した SEQ
+		 *  snd_una: 未確認の最小送信 SEQ、または確認された最大送信 SEQ
+		 *
+		 *  doff: 送信を開始するオフセット。
+		 *                                    swbuf_count (送信バッファにあるオクテット数)
+		 *    0                               V
+		 *    +-------------------------------------------+
+		 *    |                    sbuf                   |
+		 *    +-------------------------------------------+
+		 *    ^               ^
+		 *    |<------------->snd_nxt (前回送信した SEQ)
+		 *    |       doff
+		 *    snd_una (まだ確認されていない)
+		 */
+		doff = (uint_t)(cep->snd_nxt - cep->snd_una);
+
+		/*
+		 *  snd_wnd:  相手の受信可能ウィンドサイズ
+		 *  snd_cwnd: 輻輳ウィンドサイズ
+		 *
+		 *  win: どちらか小さいウィンドサイズに設定する。
+		 */
+		win   = cep->snd_wnd < cep->snd_cwnd ? cep->snd_wnd : cep->snd_cwnd;
+	
+		/* 出力フラグの設定 */
+		flags = tcp_outflags[cep->fsm_state];
+		if (cep->flags & TCP_CEP_FLG_NEED_FIN)
+			flags |= TCP_FLG_FIN;
+		if (cep->flags & TCP_CEP_FLG_NEED_SYN)
+			flags |= TCP_FLG_SYN;
+		if (cep->flags & TCP_CEP_FLG_FORCE) {
+
+			/*
+			 *  もし、送信ウインドサイズ (win) が 0 なら 1 オクテット送信する。
+			 *  そうでなければ、持続タイムアウトをキャンセルし、
+			 *  再送信回数 (rxtshift) を 0 にする。
+			 */
+			if (win == 0) {
+
+				/*
+				 *  doff:        送信するオクテット数。
+				 *  swbuf_count: 送信バッファの使用中サイズ
+				 *
+				 *  送信バッファに残っているオクテットが、これから
+				 *  送信しようとしているオクテット数より多ければ
+				 *  FIN フラグをクリアする。
+				 */
+				if (doff < cep->swbuf_count)
+					flags &=~TCP_FLG_FIN;
+				win = 1;
+				}
+			else {
+				/*
+				 *  TCP_TIM_PERSIST: 持続タイマ
+				 *  rxtshift:        再送信回数の log(2)
+				 */
+				cep->timer[TCP_TIM_PERSIST] = 0;
+				cep->rxtshift = 0;
+				}
+		 	}
+
+		/*
+		 *  len: 今回送信するオクテット数
+		 *        swbuf_count (送信バッファにあるオクテット数)
+		 *                                    |
+		 *    0                               V
+		 *    +-------------------------------------------+
+		 *    |                    sbuf       |           |
+		 *    +-------------------------------------------+
+		 *    ^               ^<------------->
+		 *    |               |      len
+		 *    |<------------->snd_nxt (前回送信した SEQ)
+		 *    |       doff
+		 *    snd_una (まだ確認されていない)
+		 */
+		if (cep->swbuf_count < win)
+			len = (int32_t)cep->swbuf_count - doff;
+		else
+			len = (int32_t)win - doff;
+
+		/*
+		 *  すでに送信されていれば、SYN ビットをオフする。
+		 *  しかし、以下の条件では送信を控える。
+		 *
+		 *    ・状態が SYN 送信。
+		 *    ・セグメントがデータを含んでいる。
+		 */
+		if ((flags & TCP_FLG_SYN) && SEQ_GT(cep->snd_nxt, cep->snd_una)) {
+			flags &= ~TCP_FLG_SYN;
+			doff --;		/* -1 は SYN フラグ分 */
+			len ++;			/* +1 は SYN フラグ分 */
+			if (len > 0 && cep->fsm_state == TCP_FSM_SYN_SENT)
+				break;
+			}
+
+		if (flags & TCP_FLG_SYN) {
+			len = 0;
+			flags &= ~TCP_FLG_FIN;
+			}
+
+		if (len < 0) {
+
+			/*
+			 *  len が 0 以下なら、0 に設定する。
+			 *  もし、送信ウィンドウサイズが 0 なら、
+			 *  再送信タイマをキャンセルし、
+			 *  前回送信した SEQ (snd_nxt) を
+			 *  確認された最大送信 SEQ (snd_una) に戻す。
+			 *  そして、持続タイマーが止まっていれば、再設定する。
+			 */
+			len = 0;
+			if (win == 0) {
+				cep->timer[TCP_TIM_REXMT] = 0;
+				cep->rxtshift = 0;
+				cep->snd_nxt  = cep->snd_una;
+				if (cep->timer[TCP_TIM_PERSIST] == 0)
+					tcp_set_persist_timer(cep);
+				}
+			}
+
+
+		/*
+		 *  今回送信するオクテット数 (len) は、
+		 *  相手の最大受信セグメントサイズ (maxseg) を超えないようにする。
+		 */
+		if (len > cep->maxseg) {
+			len = cep->maxseg;
+			sendalot = true;
+			}
+
+		/*
+                 *        swbuf_count (送信バッファにあるオクテット数)
+                 *                                           |
+		 *    0                                      V
+		 *    +-------------------------------------------+
+		 *    |                    sbuf       |           |
+		 *    +-------------------------------------------+
+		 *    ^               ^<------------->
+		 *    |               |      len
+		 *    |<------------->snd_nxt (前回送信した SEQ)
+		 *    |       doff
+		 *    snd_una (まだ確認されていない)
+		 *
+		 *  今回送信後も、送信バッファにデータが残っていれば
+		 *  FIN フラグをクリアする。
+		 */
+		if (SEQ_LT(cep->snd_nxt + len, cep->snd_una + cep->swbuf_count))
+			flags &= ~TCP_FLG_FIN;
+
+		/*
+		 *  ここから win は、受信ウィンドウサイズ。
+		 *  受信バッファの空き容量
+		 */
+		win = cep->rbufsz - cep->rwbuf_count;
+
+		/*
+		 *  愚かなウィンドウ・シンドロームの回避処理 (送信側)
+		 *
+		 *  以下の条件で、送信を行う。
+		 *
+		 *    ・フルサイズ (maxseg) のセグメントを送ることができる。
+		 *    ・相手の最大の受信ウィンドウサイズの 1/2 のデータを
+		 *      送ることができる。
+		 *    ・送信バッファを空にでき、アイドルか非遅延オプションが有効なとき。
+		 */
+		if (len) {
+
+			/*
+			 *  今回送信するオクテット数 (len) が
+			 *  相手の最大受信セグメントサイズ (maxseg) に
+			 *  一致するときは送信する。
+			 */
+			if (len == cep->maxseg) {
+				error = send_segment(&sendalot, cep, doff, win, (uint_t)len, flags);
+				continue;
+				}
+
+			/*
+			 *  今回の送信で、送信バッファを空にでき、
+			 *  アイドルか非 PUSH オプションが有効なとき。
+			 */
+			if ((idle || (cep->flags & TCP_CEP_FLG_NO_DELAY)) &&
+			    (cep->flags & TCP_CEP_FLG_NO_PUSH) == 0 &&
+			    len + doff >= cep->swbuf_count) {
+				error = send_segment(&sendalot, cep, doff, win, (uint_t)len, flags);
+				continue;
+				}
+
+			/*
+			 *  max_sndwnd: 今までの最大送信ウィンドサイズ
+			 *  snd_nxt:    次に送信する SEQ
+			 *  snd_max:    送信した最大 SEQ
+			 *
+			 *  次の条件では送信を行う。
+			 *
+			 *    ・強制送信フラグがセットされている。
+			 *    ・データ長が相手の最大の受信ウィンドウサイズの 1/2 以上で、
+			 *      相手の最大の受信ウィンドウサイズが 0 より大きい。
+			 *    ・次に送信する SEQ が送信した最大 SEQ より小さい、
+			 *      つまり、再送するとき。
+			 */
+			if ((cep->flags & TCP_CEP_FLG_FORCE) ||
+			    (len >= cep->max_sndwnd / 2 && cep->max_sndwnd > 0) ||
+			    SEQ_LT(cep->snd_nxt, cep->snd_max)) {
+				error = send_segment(&sendalot, cep, doff, win, (uint_t)len, flags);
+				continue;
+				}
+			}
+
+
+		/*
+		 *  愚かなウィンドウ・シンドロームの回避処理 (受信側)
+		 *
+		 *  ウィンドウサイズがフルサイズの 2 倍のセグメント、あるいは
+		 *  受信バッファ容量の 1/2 の、いずれか小さいほうの
+		 *  サイズで増加される場合は、ウィンドウサイズの更新を行う。
+		 */
+		if (win > 0) {
+			long adv;
+
+			/*
+			 *  win:              受信バッファの空き容量
+			 *  MAX_TCP_WIN_SIZE: TCP ヘッダの win フィールドに設定できる最大値
+			 *  rcv_adv:          受信を期待している最大の SEQ
+			 *  rcv_nxt:          受信を期待している最小の SEQ
+			 */
+			if (win < MAX_TCP_WIN_SIZE)
+				adv = win - (cep->rcv_adv - cep->rcv_nxt);
+			else
+				adv = MAX_TCP_WIN_SIZE - (cep->rcv_adv - cep->rcv_nxt);
+
+			if (adv     >= (long)(cep->maxseg * 2) ||
+			    adv * 2 >= (long) cep->rbufsz) {
+				error = send_segment(&sendalot, cep, doff, win, (uint_t)len, flags);
+				continue;
+				}
+			}
+	
+		/*
+		 *  ACK を送信する。
+		 */
+		if (cep->flags & TCP_CEP_FLG_ACK_NOW) {
+			error = send_segment(&sendalot, cep, doff, win, (uint_t)len, flags);
+			continue;
+			}
+
+		if ( (flags & TCP_FLG_RST) ||
+		    ((flags & TCP_FLG_SYN) && (cep->flags & TCP_CEP_FLG_NEED_SYN) == 0)) {
+			error = send_segment(&sendalot, cep, doff, win, (uint_t)len, flags);
+			continue;
+			}
+
+#ifdef TCP_CFG_EXTENTIONS
+
+		if (SEQ_GT(cep->snd_up, cep->snd_una)) {
+			error = send_segment(&sendalot, cep, doff, win, (uint_t)len, flags);
+			continue;
+			}
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+		/*
+		 *  snd_nxt: 次に送信する SEQ
+		 *  snd_una: 未確認の最小送信 SEQ、または確認された最大送信 SEQ
+		 *
+		 *  相手から FIN を受信し、まだ FIN を送信していないか、
+		 *  送るデータがないときは、FIN を相手に届けるため、
+		 *  セグメントを送信する。
+		 */
+		if ((flags & TCP_FLG_FIN) &&
+		    ((cep->flags & TCP_CEP_FLG_SENT_FIN) == 0 || cep->snd_nxt == cep->snd_una)) {
+			error = send_segment(&sendalot, cep, doff, win, (uint_t)len, flags);
+			continue;
+			}
+
+		/*
+		 *  送信すべきデータがあり、再送タイマと持続タイマが切れているときは
+		 *  持続タイマを設定する。
+		 */
+		if (cep->swbuf_count && cep->timer[TCP_TIM_REXMT  ] == 0 &&
+		                        cep->timer[TCP_TIM_PERSIST] == 0) {
+			cep->rxtshift = 0;
+			tcp_set_persist_timer(cep);
+			break;
+			}
+		
+		}
+	}
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+/*
+ *  tcptsk_alloc_swbufq -- 送信ウィンドバッファ割り当て
+ */
+
+static void
+tcptsk_alloc_swbufq (T_TCP_CEP *cep)
+{
+ 	ER	error;
+	uint_t	win;
+
+	/*
+	 *  snd_wnd:  相手の受信可能ウィンドサイズ
+	 *  snd_cwnd: 輻輳ウィンドサイズ
+	 *
+	 *  win: どちらか小さいウィンドサイズに設定する。
+	 */
+	win = cep->snd_wnd < cep->snd_cwnd ? cep->snd_wnd : cep->snd_cwnd;
+
+	/*
+	 *  相手の受信ウィンドが閉じている場合は、開くまで待機する。
+	 */
+	if (win == 0) {
+		cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) | TCP_CEP_FLG_WBCS_WOPEN_PEND;
+		}
+	else {
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		/* ノンブロッキングコール */
+		if (!IS_PTR_DEFINED(cep->callback)) {
+			syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+
+			/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+			cep->snd_tskid = TA_NULL;
+			cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+			return;
+			}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		if ((error = tcpn_get_segment(&cep->swbufq, cep, 0,
+		                             (uint_t)TCP_CFG_SWBUF_CSAVE_MIN_SIZE,
+		                             (uint_t)TCP_CFG_SWBUF_CSAVE_MAX_SIZE,
+		                             (ATR)(NBA_SEARCH_DESCENT |
+		                                   NBA_RESERVE_TCP    |
+		                                   (GET_TCP_CEPID(cep) & NBA_ID_MASK)), TMO_POL)) != E_OK) {
+
+			/* ネットワークバッファを予約する。*/
+			cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) | TCP_CEP_FLG_WBCS_NBUF_PEND;
+			}
+		else {
+
+			/* 送信ウィンドバッファを初期化する。*/
+			tcp_init_swbuf(cep);
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+			if (cep->snd_nblk_tfn == TFN_TCP_GET_BUF) {
+
+				uint_t len;
+
+				/* 送信ウィンドバッファの書き込みアドレスを設定する。*/
+				len = TCP_GET_SWBUF_ADDR(cep, cep->snd_p_buf);
+
+				/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)(uint32_t)len);
+#else
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&len);
+#endif
+
+
+				/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+				cep->snd_tskid = TA_NULL;
+				cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+				}
+
+			else {	/* cep->snd_nblk_tfn == TFN_TCP_SND_DAT || */
+				/* cep->snd_nblk_tfn == TFN_TCP_SND_OOB    */
+
+				uint_t len;
+
+				/* 送信ウィンドバッファにデータを書き込む。*/
+				len = TCP_WRITE_SWBUF(cep, cep->snd_data, (uint_t)cep->snd_len);
+
+#ifdef TCP_CFG_EXTENTIONS
+
+				/* 送信緊急ポインタを設定する。*/
+			        if (cep->snd_nblk_tfn == TFN_TCP_SND_OOB)
+					cep->snd_up = cep->snd_una + len;
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+				/* フラグを、送信可能に設定し、強制的に送信する。*/
+				cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR | TCP_CEP_FLG_POST_OUTPUT;
+
+				/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)(uint32_t)len);
+#else
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&len);
+#endif
+
+
+				/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+				cep->snd_tskid = TA_NULL;
+				cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+				}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+			}
+		}
+	}
+
+/*
+ *  tcptsk_free_swbufq -- 送信ウィンドバッファ開放
+ */
+
+static void
+tcptsk_free_swbufq (T_TCP_CEP *cep)
+{
+	/*
+	 *  受信確認が完了し、ネットワークインタフェースからの
+	 *  出力も完了したときは、送信ウィンドバッファキューを解放する。
+	 */
+
+	/* 送信ウィンドバッファの使用中サイズをリセットする。*/
+	cep->swbuf_count = 0;
+
+	/* 送信ウィンドバッファキューのネットワークバッファを解放する。*/
+	syscall(rel_net_buf(cep->swbufq));
+	cep->swbufq = NULL;
+
+	/* フラグを空きに設定する。*/
+	cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) | TCP_CEP_FLG_WBCS_FREE;
+
+	/* 送信ウィンドバッファに空きができたことを知らせる。*/
+	syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY));
+
+	/* 送信ウィンドバッファの空き待ちのときは、TCP 出力タスクを起動する。*/
+	if ((cep->flags & TCP_CEP_FLG_WBCS_NBUF_REQ) != 0) {
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		}
+	}
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+/*
+ *  TCP 出力タスク
+ */
+
+void
+tcp_output_task (intptr_t exinf)
+{
+	static int_t last_ix = 0;
+
+	T_TCP_CEP	*cep;
+	ID		tskid;
+ 	int_t		ix, sel_ix;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP OUTPUT:%d] started.", tskid);
+
+	tcp_init();
+
+#ifdef _IP6_CFG
+
+	/* IPv6 のステートレス・アドレス自動設定を実行する。*/
+	in6_if_up(IF_GET_IFNET());
+
+#endif	/* of #ifdef _IP6_CFG */
+
+	while (true) {
+
+		/* 出力がポストされるまで待つ。*/
+		syscall(wai_sem(SEM_TCP_POST_OUTPUT));
+
+		if (++ last_ix == tmax_tcp_cepid)
+			last_ix = 0;
+		sel_ix = ix = last_ix;
+		do {
+			cep = &tcp_cep[ix];
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+			if ((cep->flags & TCP_CEP_FLG_WBCS_NBUF_REQ) != 0 &&
+			    ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_FREE ||
+			     (cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_NBUF_RSVD)) {
+				tcptsk_alloc_swbufq(cep);
+				sel_ix = ix;
+				}
+
+			if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_ACKED &&
+			    (cep->swbufq->flags & NB_FLG_NOREL_IFOUT) == 0) {
+				tcptsk_free_swbufq(cep);
+				sel_ix = ix;
+				}
+
+			/*
+			 *  ネットワークインタフェースから送信が終わっていないときは、
+			 *  送信を予約する。
+			 */
+			if (cep->flags & TCP_CEP_FLG_POST_OUTPUT &&
+			   (cep->flags & TCP_CEP_FLG_WBCS_MASK) >= TCP_CEP_FLG_WBCS_SENT) {
+				syscall(wai_sem(cep->semid_lock));
+				if (cep->swbufq == NULL)
+					cep->flags &= ~TCP_CEP_FLG_POST_OUTPUT;
+				else if (cep->swbufq->flags & NB_FLG_NOREL_IFOUT) {
+					cep->flags &= ~TCP_CEP_FLG_POST_OUTPUT;
+					cep->flags |=  TCP_CEP_FLG_RESERVE_OUTPUT;
+					}
+				syscall(sig_sem(cep->semid_lock));
+				}
+
+			/*
+			 *  送信予約中に、ネットワークインタフェースから送信が終了したら、
+			 *  送信を開始する。ただし、完全に送信が終了したときは何もしない。
+			 */
+			if (cep->flags & TCP_CEP_FLG_RESERVE_OUTPUT) {
+				syscall(wai_sem(cep->semid_lock));
+				if (cep->swbufq != NULL && (cep->swbufq->flags & NB_FLG_NOREL_IFOUT) == 0) {
+					cep->flags |=  TCP_CEP_FLG_POST_OUTPUT;
+					}
+				syscall(sig_sem(cep->semid_lock));
+				cep->flags &= ~TCP_CEP_FLG_RESERVE_OUTPUT;
+				}
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+			if (cep->flags & TCP_CEP_FLG_POST_OUTPUT) {
+
+				cep->flags &= ~TCP_CEP_FLG_POST_OUTPUT;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+				if (cep->snd_nblk_tfn == TFN_TCP_CON_CEP && cep->myaddr.portno == TCP_PORTANY) {
+				 	ER	error;
+
+					/*
+					 *  tcp_con_cep のノンブロッキングコールで、
+					 *  未割当のの場合は、ポート番号を割り当てる。
+					 *  p_myaddr が NADR (-1) か、
+					 *  自ポート番号が TCP_PORTANY なら、自動で割り当てる。
+					 */
+					if (cep->p_myaddr == NADR || cep->p_myaddr->portno == TCP_PORTANY)
+						tcp_alloc_auto_port(cep);
+					else if ((error = tcp_alloc_port(cep, cep->p_myaddr->portno)) != E_OK) {
+
+						if (IS_PTR_DEFINED(cep->callback))
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+							(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)error);
+#else
+							(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&error);
+#endif
+						else
+							syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+
+						/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+						cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+						cep->snd_tskid = TA_NULL;
+						continue;
+						}
+					}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+				tcp_output(cep);
+
+				if (cep->flags & TCP_CEP_FLG_CLOSE_AFTER_OUTPUT) {
+					/* コネクションを閉じる。*/
+					tcp_close(cep);
+					cep->flags &= ~TCP_CEP_FLG_CLOSE_AFTER_OUTPUT;
+					}
+
+				if (cep->flags & TCP_CEP_FLG_RESTORE_NEXT_OUTPUT) {
+					/* snd_nxt を元に戻す。*/
+					if (SEQ_GT(cep->snd_old_nxt, cep->snd_nxt))
+						cep->snd_nxt = cep->snd_old_nxt;
+					cep->flags &= ~TCP_CEP_FLG_RESTORE_NEXT_OUTPUT;
+					}
+
+				sel_ix = ix;
+				}
+
+			if (++ ix == tmax_tcp_cepid)
+				ix = 0;
+			} while (ix != last_ix);
+
+		/* 次回は、処理した通信端点を後回しにする。*/
+		last_ix = sel_ix;
+		}
+	}
+
+#endif	/* of #ifdef SUPPORT_TCP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_seq.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_seq.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_seq.h	(revision 398)
@@ -0,0 +1,122 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp_seq.h	8.3 (Berkeley) 6/21/95
+ * $FreeBSD: src/sys/netinet/tcp_seq.h,v 1.8.4.1 1999/08/29 16:29:55 peter Exp $
+ */
+ 
+#ifndef _TCP_SEQ_H_
+#define _TCP_SEQ_H_
+
+/*
+ *  SEQ と ACK 番号は、32 ビット符号付整数で比較する。
+ */
+
+#define SEQ_LT(a,b)		((int32_t)((a)-(b)) <  0)
+#define SEQ_LE(a,b)		((int32_t)((a)-(b)) <= 0)
+#define SEQ_GT(a,b)		((int32_t)((a)-(b)) >  0)
+#define SEQ_GE(a,b)		((int32_t)((a)-(b)) >= 0)
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+#define	TCP_ISS_INCR()	((T_TCP_SEQ)122*1024 + (((T_TCP_SEQ)net_rand() >> 14) & 0x3ffff))
+
+/*
+ *  全域変数
+ */
+
+extern T_TCP_SEQ tcp_iss;		/* TCP の SEQ の初期値 */
+
+/*
+ *  インライン関数
+ */
+
+/*
+ *  init_receive_seq -- 受信 SEQ 番号を初期化する。
+ */
+
+Inline void
+init_receive_seq (T_TCP_CEP *cep)
+{
+	cep->rcv_adv = cep->rcv_nxt = cep->irs + 1;
+	}
+
+/*
+ *  init_send_seq -- 送信 SEQ 番号を初期化する。
+ */
+
+Inline void
+init_send_seq (T_TCP_CEP *cep)
+{
+	cep->snd_una = cep->snd_nxt = cep->snd_max = cep->iss;
+
+#ifdef TCP_CFG_EXTENTIONS
+	cep->snd_up = cep->iss;
+#endif
+	}
+
+#endif	/* of #ifndef _TCP_SEQ_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_subr.c	(revision 398)
@@ -0,0 +1,1940 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp_subr.c	8.2 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/netinet/tcp_subr.c,v 1.49.2.4 1999/08/29 16:29:55 peter Exp $
+ */
+
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <syssvc/serial.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+
+#ifdef SUPPORT_TCP
+
+/*
+ *  全域変数
+ */
+
+/*
+ *  TCP の SEQ の初期値、プログラムが起動して、最初に TCP セグメントを
+ *  送受信するときに、get_tim() により初期化する。
+ */
+T_TCP_SEQ tcp_iss = 0;
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+T_TCP_STATS tcp_stats;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+/*
+ *  局所変数
+ */
+
+static uint16_t tcp_port_auto = TCP_PORT_FIRST_AUTO;	/* 自動割り当て番号	*/
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+/*
+ *  タスクからの Time Wait 状態 CEP 分離機能
+ */
+
+/*
+ *  変数
+ */
+
+T_TCP_TWCEP tcp_twcep[NUM_TCP_TW_CEP_ENTRY];
+
+/*
+ *  tcp_move_twcep -- 必要な情報を Time Wait 用 TCP 通信端点に移して、
+ *                    標準の TCP 通信端点を開放する。
+ */
+
+void
+tcp_move_twcep (T_TCP_CEP *cep)
+{
+	T_TCP_TWCEP*	twcep;
+
+	/* 空きの Time Wait 用 TCP 通信端点を探索する。*/
+	for (twcep = &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep -- != tcp_twcep; ) {
+		if (twcep->fsm_state != TCP_FSM_TIME_WAIT) {
+
+			/*
+			 *  通信端点をロックし、
+			 *  必要な情報を Time Wait 用 TCP 通信端点に移す。
+			 */
+			syscall(wai_sem(cep->semid_lock));
+			twcep->flags		= (uint8_t)cep->flags;
+			twcep->rbufsz		= cep->rbufsz;
+			twcep->dstaddr		= cep->dstaddr;
+			twcep->myaddr		= cep->myaddr;
+			twcep->snd_una		= cep->snd_una;
+			twcep->rcv_nxt		= cep->rcv_nxt;
+			twcep->rwbuf_count	= cep->rwbuf_count;
+			twcep->fsm_state	= cep->fsm_state;
+			twcep->timer_2msl	= cep->timer[TCP_TIM_2MSL];
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+
+			/* 標準 TCP 通信端点を開放する。*/
+			tcp_close(cep);
+
+			break;
+			}
+		}
+	}
+
+/*
+ *  tcp_find_twcep -- ポート番号から Time Wait 用 TCP 通信端点を得る。
+ */
+
+T_TCP_TWCEP*
+tcp_find_twcep (T_NET_BUF *input, uint_t off)
+{
+	T_TCP_TWCEP*	twcep;
+	T_TCP_HDR	*tcph;
+
+	tcph = GET_TCP_HDR(input, off);
+	
+	/*
+	 *  状態が TIME WAIT で、
+	 *  IP アドレスとポート番号が一致する通信端点を探索する。
+	 */
+	for (twcep = &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep -- != tcp_twcep; ) {
+		if (twcep->fsm_state == TCP_FSM_TIME_WAIT                   &&
+		    IN_IS_DSTADDR_ACCEPT    (&twcep->myaddr.ipaddr,  input) &&
+		    IN_ARE_NET_SRCADDR_EQUAL(&twcep->dstaddr.ipaddr, input) &&
+		    tcph->dport == twcep->myaddr.portno                     &&
+		    tcph->sport == twcep->dstaddr.portno)
+			return twcep;
+		}
+
+	return NULL;
+	}
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+/*
+ *  tcp_find_cep -- ポート番号から TCP 通信端点を得る。
+ */
+
+T_TCP_CEP*
+tcp_find_cep (T_NET_BUF *input, uint_t off)
+{
+	T_TCP_CEP*	cep;
+	T_TCP_HDR	*tcph;
+
+	tcph = GET_TCP_HDR(input, off);
+	
+	/*
+	 *  状態が SYN 送信済み以後は、
+	 *  IP アドレスとポート番号が一致する TCP 通信端点を探索する。
+	 */
+	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
+		if (cep->fsm_state >= TCP_FSM_SYN_SENT                    &&
+		    IN_IS_DSTADDR_ACCEPT    (&cep->myaddr.ipaddr,  input) &&
+		    IN_ARE_NET_SRCADDR_EQUAL(&cep->dstaddr.ipaddr, input) &&
+		    tcph->dport == cep->myaddr.portno                     &&
+		    tcph->sport == cep->dstaddr.portno)
+			return cep;
+		}
+
+	/* IPv4 で受動オープン中の TCP 通信端点を先に探索する。*/	
+	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
+		if ((cep->flags & TCP_CEP_FLG_IPV4)                   &&
+		     cep->fsm_state == TCP_FSM_LISTEN                 &&
+		     GET_IP_VER(input) == IPV4_VERSION                &&
+		     IN_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+		     tcph->dport == cep->myaddr.portno)
+			return cep;
+		}
+
+	/* 受動オープン中の TCP 通信端点を探索する。*/	
+	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+
+		if (cep->flags & TCP_CEP_FLG_IPV4) {
+			if (cep->fsm_state == TCP_FSM_LISTEN                 &&
+		            GET_IP_VER(input) == IPV4_VERSION                &&
+			    IN_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+			    tcph->dport == cep->myaddr.portno)
+				return cep;
+			}
+		else {
+
+#if defined(API_CFG_IP4MAPPED_ADDR)
+
+			if (cep->fsm_state == TCP_FSM_LISTEN                 &&
+			    IN_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+			    tcph->dport == cep->myaddr.portno)
+				return cep;
+
+#else	/* of #if defined(API_CFG_IP4MAPPED_ADDR) */
+
+			if (cep->fsm_state == TCP_FSM_LISTEN                   &&
+			    INN6_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+			    tcph->dport == cep->myaddr.portno)
+				return cep;
+
+#endif	/* of #if defined(API_CFG_IP4MAPPED_ADDR) */
+
+			}
+
+#else	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+		if (cep->fsm_state == TCP_FSM_LISTEN                 &&
+		    IN_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+		    tcph->dport == cep->myaddr.portno)
+			return cep;
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+		}
+
+	return NULL;
+	}
+
+/*
+ *  tcp_is_addr_accept -- 受信可能な IP アドレスとポート番号であることを確認する。
+ */
+
+bool_t
+tcp_is_addr_accept (T_NET_BUF *input, uint_t off)
+{
+	T_TCP_HDR	*tcph;
+
+	tcph = GET_TCP_HDR(input, off);
+
+#if !defined(_IP6_CFG) && defined(_IP4_CFG) && defined(SUPPORT_LOOP)
+
+	/*
+	 *  次のときは破棄する。
+	 *    ・ポート番号が同一で、送受信 IP アドレス が同一。
+	 *      ただし、送信元 IP アドレスがローカルループバックなら良い。
+	 *    ・マルチキャストアドレス
+	 */
+
+	if (tcph->dport == tcph->sport && 
+	    (IN4_ARE_HDR_ADDR_EQUAL(input) && !IN4_ARE_NET_ADDR_EQUAL(&GET_IP4_HDR(input)->dst, &IPV4_ADDR_LOOPBACK)))
+		return RET_DROP;
+
+#else	/* of #if !defined(_IP6_CFG) && defined(_IP4_CFG) && defined(SUPPORT_LOOP) */
+
+	/*
+	 *  次のときは、受信可能ではない。
+	 *    ・ポート番号が同一で、送受信 IP アドレス が同一。
+	 *    ・マルチキャストアドレス
+	 */
+	if (tcph->dport == tcph->sport && IN_ARE_HDR_ADDR_EQUAL(input))
+		return false;
+
+#endif	/* of #if !defined(_IP6_CFG) && defined(_IP4_CFG) && defined(SUPPORT_LOOP) */
+
+	if (IN_IS_NET_ADDR_MULTICAST(input))
+		return false;
+	else
+		return true;
+	}
+
+/*
+ *  tcp_free_reassq -- 受信再構成キューのネットワークバッファを解放する。
+ *
+ *    注意:
+ *      必要であれば、この関数を呼び出す前に、通信端点をロックし、
+ *      戻った後、解除する必要がある。
+ */
+
+void
+tcp_free_reassq (T_TCP_CEP *cep)
+{
+	T_NET_BUF	*q, *nq;
+
+	for (q = cep->reassq; q != NULL; q = nq) {
+		nq = GET_TCP_Q_HDR(q, GET_IP_TCP_Q_HDR_OFFSET(q))->next;
+		syscall(rel_net_buf(q));
+		}
+	cep->reassq  = NULL;
+	NET_COUNT_TCP(net_count_tcp[NC_TCP_FREE_RCV_QUEUE],   1);
+	}
+
+/*
+ *  tcp_alloc_auto_port -- 自動割り当てポート番号を設定する。
+ */
+
+void
+tcp_alloc_auto_port (T_TCP_CEP *cep)
+{
+	int_t		ix;
+	uint16_t	portno;
+
+	while (true) {
+		portno = tcp_port_auto ++;
+		if (tcp_port_auto > TCP_PORT_LAST_AUTO)
+			tcp_port_auto = TCP_PORT_FIRST_AUTO;
+
+#if defined(TNUM_TCP6_REPID)
+#if TNUM_TCP6_REPID > 0
+
+		for (ix = tmax_tcp6_repid; ix -- > 0; ) {
+
+#ifdef TCP_CFG_EXTENTIONS
+
+			if (VALID_TCP_REP(&tcp6_rep[ix]) && tcp6_rep[ix].myaddr.portno == portno) {
+				portno = TCP_PORTANY;
+				break;
+				}
+
+#else	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+			if (tcp6_rep[ix].myaddr.portno == portno) {
+				portno = TCP_PORTANY;
+				break;
+				}
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+			}
+
+#endif	/* of #if TNUM_TCP6_REPID > 0 */
+#endif	/* of #if defined(TNUM_TCP6_REPID) */
+
+#if defined(TNUM_TCP4_REPID)
+#if TNUM_TCP4_REPID > 0
+
+		for (ix = tmax_tcp4_repid; ix -- > 0; ) {
+
+#ifdef TCP_CFG_EXTENTIONS
+
+			if (VALID_TCP_REP(&tcp4_rep[ix]) && tcp4_rep[ix].myaddr.portno == portno) {
+				portno = TCP_PORTANY;
+				break;
+				}
+
+#else	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+			if (tcp4_rep[ix].myaddr.portno == portno) {
+				portno = TCP_PORTANY;
+				break;
+				}
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+			}
+
+#endif	/* of #if TNUM_TCP4_REPID > 0 */
+#endif	/* of #if defined(TNUM_TCP4_REPID) */
+
+		if (portno != TCP_PORTANY) {
+
+			syscall(wai_sem(SEM_TCP_CEP));
+			for (ix = tmax_tcp_cepid; ix -- > 0; ) {
+				if (VALID_TCP_CEP(&tcp_cep[ix]) && tcp_cep[ix].myaddr.portno == portno) {
+					portno = TCP_PORTANY;
+					break;
+					}
+				}
+
+			if (portno != TCP_PORTANY) {
+				cep->myaddr.portno = portno;
+				syscall(sig_sem(SEM_TCP_CEP));
+				return;
+				}
+			syscall(sig_sem(SEM_TCP_CEP));
+			}
+		}
+	}
+
+/*
+ *  tcp_alloc_port -- 指定されたポート番号を設定する。
+ */
+
+ER
+tcp_alloc_port (T_TCP_CEP *cep, uint16_t portno)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_TCP_CEP));
+	for (ix = tmax_tcp_cepid; ix -- > 0; )
+		if (VALID_TCP_CEP(cep) && tcp_cep[ix].myaddr.portno == portno) {
+			syscall(sig_sem(SEM_TCP_CEP));
+			return E_PAR;
+			}
+	cep->myaddr.portno = portno;
+	syscall(sig_sem(SEM_TCP_CEP));
+	return E_OK;
+	}
+
+/*
+ *  tcp_init -- TCP モジュールの初期化
+ */
+
+void
+tcp_init (void)
+{
+	timeout(tcp_slow_timo, NULL, TCP_SLOW_TMO);
+
+#ifdef TCP_CFG_DELAY_ACK
+
+	timeout(tcp_fast_timo, NULL, TCP_FAST_TMO);
+
+#endif/* of #ifdef TCP_CFG_DELAY_ACK */
+	}
+
+/*
+ * tcp_init_iss シーケンス番号を初期化する。
+ */
+
+void
+tcp_init_iss (void)
+{
+	SYSTIM now;
+
+	syscall(get_tim(&now));
+	net_srand(now);
+	tcp_iss = net_rand();
+	}
+
+/*
+ *  tcp_close -- コネクションを開放する。
+ */
+
+T_TCP_CEP *
+tcp_close (T_TCP_CEP *cep)
+{
+	/* タイマーを停止する。*/
+	tcp_cancel_timers(cep);
+
+	/* 
+	 *  通信端点をロックし、
+	 *  受信再構成キューのネットワークバッファを解放する。
+	 */
+	syscall(wai_sem(cep->semid_lock));
+	tcp_free_reassq(cep);
+	syscall(sig_sem(cep->semid_lock));
+
+	/* 状態を未使用にする。*/
+	cep->fsm_state = TCP_FSM_CLOSED;
+
+	/*
+	 * 以下に関係しないフラグをクリアーする。
+	 * ・送受信ウィンドバッファの省コピー機能
+	 * ・動的な通信端点の生成・削除機能
+	 * ・通信端点のネットワーク層プロトコル
+	 */
+	cep->flags &= TCP_CEP_FLG_NOT_CLEAR;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	if (cep->snd_nblk_tfn != TFN_TCP_UNDEF || cep->rcv_nblk_tfn != TFN_TCP_UNDEF) {
+		/* ノンブロッキングコール */
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+		if (!IS_PTR_DEFINED(cep->callback))
+			syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+		else {
+			if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) {
+				ER_UINT len;
+
+				switch (cep->rcv_nblk_tfn) {
+
+				case TFN_TCP_ACP_CEP:
+					/* TCP 通信端点からTCP 受付口を解放する。*/
+					cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+					cep->rep4 = NULL;
+#endif
+
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_CLS);
+					break;
+
+				case TFN_TCP_RCV_BUF:
+
+					/* 受信ウィンドバッファの空アドレスを獲得する。*/
+					len = TCP_GET_RWBUF_ADDR(cep, cep->rcv_p_buf);
+
+					/* 異常切断等のエラーを設定する。*/
+					if (cep->error == E_TMOUT)
+						len = E_CLS;
+					else if (cep->error < 0)
+						len = cep->error;
+
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)(uint32_t)len);
+					break;
+
+				case TFN_TCP_RCV_DAT:
+
+					/* 受信ウィンドバッファからデータを取り出す。*/
+					len = TCP_READ_RWBUF(cep, cep->rcv_data, (uint_t)cep->rcv_len);
+
+					/* 異常切断等のエラーを設定する。*/
+					if (cep->error == E_TMOUT)
+						len = E_CLS;
+					else if (cep->error != E_OK)
+						len = cep->error;
+
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)(uint32_t)len);
+					break;
+
+				case TFN_TCP_CLS_CEP:
+
+					if (cep->error == E_TMOUT)
+						(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_CLS);
+					else
+						(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)cep->error);
+					break;
+
+				default:
+					syslog(LOG_WARNING, "[TCP] unexp TFN: %s.", in_strtfn((FN)cep->rcv_nblk_tfn));
+					break;
+					}
+
+				/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+				cep->rcv_tskid = TA_NULL;
+				cep->rcv_tfn   = cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+				}
+
+			if (cep->snd_nblk_tfn != TFN_TCP_UNDEF) {
+
+				switch (cep->snd_nblk_tfn) {
+
+				case TFN_TCP_CON_CEP:
+					/* TCP 通信端点から TCP 受付口を解放する。*/
+					cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+					cep->rep4 = NULL;
+#endif
+
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)E_CLS);
+					break;
+
+				case TFN_TCP_SND_DAT:
+				case TFN_TCP_GET_BUF:
+					if (cep->error == E_TMOUT)
+						(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)E_CLS);
+					else
+						(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)cep->error);
+					break;
+
+				default:
+					syslog(LOG_WARNING, "[TCP] unexp TFN: %s.", in_strtfn((FN)cep->snd_nblk_tfn));
+					break;
+					}
+
+				/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+				cep->snd_tskid = TA_NULL;
+				cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+				}
+
+			}
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+		if (!IS_PTR_DEFINED(cep->callback))
+			syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+		else {
+			if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) {
+				ER_UINT len;
+
+				switch (cep->rcv_nblk_tfn) {
+
+				case TFN_TCP_ACP_CEP:
+
+					/* TCP 通信端点からTCP 受付口を解放する。*/
+					cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+					cep->rep4 = NULL;
+#endif
+
+					/* 接続エラーを設定する。*/
+					len      = E_CLS;
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
+					break;
+
+				case TFN_TCP_RCV_BUF:
+
+					/* 受信ウィンドバッファの空アドレスを獲得する。*/
+					len = TCP_GET_RWBUF_ADDR(cep, cep->rcv_p_buf);
+
+					/* 異常切断等のエラーを設定する。*/
+					if (cep->error == E_TMOUT)
+						len = E_CLS;
+					else if (cep->error < 0)
+						len = cep->error;
+
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
+					break;
+
+				case TFN_TCP_RCV_DAT:
+
+					/* 受信ウィンドバッファからデータを取り出す。*/
+					len = TCP_READ_RWBUF(cep, cep->rcv_data, (uint_t)cep->rcv_len);
+
+					/* 異常切断等のエラーを設定する。*/
+					if (cep->error == E_TMOUT)
+						len = E_CLS;
+					else if (cep->error != E_OK)
+						len = cep->error;
+
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
+					break;
+
+				case TFN_TCP_CLS_CEP:
+					if (cep->error == E_TMOUT)
+						len = E_CLS;
+					else
+						len = cep->error;
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
+					break;
+
+				default:
+					syslog(LOG_WARNING, "[TCP] unexp TFN: %s.", in_strtfn((FN)cep->rcv_nblk_tfn));
+					break;
+					}
+
+				/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+				cep->rcv_tskid = TA_NULL;
+				cep->rcv_tfn   = cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+				}
+
+			if (cep->snd_nblk_tfn != TFN_TCP_UNDEF) {
+				ER_UINT len;
+
+				switch (cep->snd_nblk_tfn) {
+
+				case TFN_TCP_CON_CEP:
+
+					/* TCP 通信端点からTCP 受付口を解放する。*/
+					cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+					cep->rep4 = NULL;
+#endif
+
+					/* 接続エラーを設定する。*/
+					len      = E_CLS;
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&len);
+					break;
+
+				case TFN_TCP_SND_DAT:
+				case TFN_TCP_GET_BUF:
+					if (cep->error == E_TMOUT)
+						len = E_CLS;
+					else
+						len = cep->error;
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
+					break;
+
+				default:
+					syslog(LOG_WARNING, "[TCP] unexp TFN: %s.", in_strtfn((FN)cep->snd_nblk_tfn));
+					break;
+					}
+
+				/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+				cep->snd_tskid = TA_NULL;
+				cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+				}
+
+			}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+		/* 
+		 *  通信端点をロックし、
+		 *  送受信ウィンドバッファキューのネットワークバッファを解放する。
+		 */
+		syscall(wai_sem(cep->semid_lock));
+		TCP_FREE_RWBUFQ(cep);
+		TCP_FREE_SWBUFQ(cep);
+		syscall(sig_sem(cep->semid_lock));
+
+		/* 未使用になったことを知らせる。*/
+		syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+		}
+	else {	/* 非ノンブロッキングコール */
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+		cep->snd_tskid = cep->rcv_tskid = TA_NULL;
+		cep->snd_tfn   = cep->rcv_tfn   = TFN_TCP_UNDEF;
+
+		/* 
+		 *  通信端点をロックし、
+		 *  送受信ウィンドバッファキューのネットワークバッファを解放する。
+		 */
+		syscall(wai_sem(cep->semid_lock));
+		TCP_FREE_RWBUFQ(cep);
+		TCP_FREE_SWBUFQ(cep);
+		syscall(sig_sem(cep->semid_lock));
+
+		/* 未使用になったことを知らせる。*/
+		syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+
+		/*
+		 * 入出力タスクを起床して、
+		 * 送受信不可になったことを知らせる。
+		 */
+		syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY));
+		syscall(set_flg(cep->rcv_flgid, TCP_CEP_EVT_RWBUF_READY));
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	return NULL;
+	}
+
+/*
+ *  tcp_drop -- TCP 接続を破棄する。
+ */
+
+T_TCP_CEP *
+tcp_drop (T_TCP_CEP *cep, ER err)
+{
+#ifdef SUPPORT_MIB
+
+	if ((cep->fsm_state == TCP_FSM_SYN_SENT) || (cep->fsm_state == TCP_FSM_SYN_RECVD)) {
+		NET_COUNT_MIB(tcp_stats.tcpAttemptFails, 1);
+		}
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+	cep->error = err;
+	if (TCP_FSM_HAVE_RCVD_SYN(cep->fsm_state)) {
+		cep->fsm_state = TCP_FSM_CLOSED;
+
+		/* 送信と、送信後コネクションの切断を指示する。*/
+		cep->flags |=  TCP_CEP_FLG_POST_OUTPUT | TCP_CEP_FLG_CLOSE_AFTER_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		}
+	else {
+		cep = tcp_close(cep);
+		}
+	return cep;
+	}
+
+/*
+ *  tcp_respond -- TCP の単一メッセージを送信する。
+ */
+
+void
+tcp_respond (T_NET_BUF *output, T_TCP_CEP *cep,
+             T_TCP_SEQ ack, T_TCP_SEQ seq, uint_t rbfree, uint8_t flags)
+{
+	T_TCP_HDR	*tcph;
+	uint_t		win = 0;
+	uint_t		hdr_offset;
+
+	if ((flags & TCP_FLG_RST) == 0)
+		win = rbfree;
+
+	/*
+	 *  output が NULL でなければ、これは入力したセグメントの
+	 *  net_buf で、そのまま再利用する。
+	 */
+	if (output != NULL) {
+		uint16_t	portno;
+
+		/*
+		 * IPv4 では、IP ヘッダのオプションを削除する。
+		 * IPv6 では、拡張ヘッダを削除する。
+		 */
+		if (IP_REMOVE_OPTIONS(output) != E_OK) {
+			syscall(rel_net_buf(output));
+			return;
+			}
+
+		ip_exchg_addr(output);
+
+#if defined(_IP6_CFG)
+
+		/* トラヒッククラスとフローラベルをクリアする。*/
+		SET_IP_CF(output, 0);
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+		/* TCP SDU 長を 0 にする。*/
+		SET_IP_SDU_SIZE(output, TCP_HDR_SIZE);
+
+		tcph = GET_TCP_HDR(output, IF_IP_TCP_HDR_OFFSET(output));
+
+		/* ポート番号を交換する。*/
+		portno = tcph->sport;
+		tcph->sport = tcph->dport;
+		tcph->dport = portno;
+
+		/* TCP ヘッダに情報を設定する。*/
+		tcph->doff = TCP_MAKE_DATA_OFF(TCP_HDR_SIZE);
+		}
+	
+	/* cep が NULL であれば、何もしないで終了する。*/
+	else if (cep == NULL)
+		return;
+	else {
+		if (tcpn_get_segment(&output, cep, 0,
+		                    0, (uint_t)net_buf_max_siz(),
+		                    NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF) != E_OK)
+			return;
+		tcph = GET_TCP_HDR(output, IF_IP_TCP_HDR_OFFSET(output));
+		flags |= TCP_FLG_ACK;
+		}
+
+	tcph->seq   = htonl(seq);
+	tcph->ack   = htonl(ack);
+	tcph->win   = htons(win);
+	tcph->flags = flags;
+	tcph->urp   = tcph->sum = 0;
+
+	/*
+	 *  チェックサムを設定する。
+	 */
+	hdr_offset = IF_IP_TCP_HDR_OFFSET(output);
+	tcph->sum = IN_CKSUM(output, IPPROTO_TCP, hdr_offset, 
+	                     (uint_t)GET_TCP_HDR_SIZE(output, hdr_offset));
+
+	/* ネットワークバッファ長を調整する。*/
+	output->len = (uint16_t)GET_IF_IP_TCP_HDR_SIZE(output, hdr_offset);
+
+#ifdef TCP_CFG_TRACE
+
+	tcp_output_trace(output, cep);
+
+#endif	/* of #ifdef TCP_CFG_TRACE */
+
+	/* ネットワーク層 (IP) の出力関数を呼び出す。*/
+	IP_OUTPUT(output, TMO_TCP_OUTPUT);
+	}
+#if 0
+/*
+ *  tcp_get_segment -- TCP セグメントを獲得し、ヘッダを設定する。
+ *
+ *    戻り値	エラーコード
+ *    optlen	オプションサイズ、4 オクテット単位
+ *    maxlen	最大セグメントサイズ（IF/IP/TCP ヘッダサイズを含まない）
+ *    len	TCP SDU サイズ
+ */
+
+ER
+tcp_get_segment (T_NET_BUF **nbuf, T_TCP_CEP *cep,
+                 uint_t optlen, uint_t len, uint_t maxlen, ATR nbatr, TMO tmout)
+{
+	T_TCP_HDR	*tcph;
+	ER		error;
+
+	/* IP データグラムを獲得する。*/
+	if ((error = IN_GET_DATAGRAM(nbuf,
+	                             (uint_t)(TCP_HDR_SIZE + optlen + len),
+	                             (uint_t)(TCP_HDR_SIZE + maxlen),
+	                             &cep->dstaddr.ipaddr,
+	                             &cep->myaddr.ipaddr,
+	                             IPPROTO_TCP, IP_DEFTTL, nbatr, tmout)) != E_OK) {
+		syslog(LOG_WARNING, "[TCP] NET BUF busy, len: %d, CEP: %d.",
+		                    (uint16_t)(TCP_HDR_SIZE + optlen + len), GET_TCP_CEPID(cep));
+		return error;
+		}
+
+	/* TCP ヘッダに情報を設定する。*/
+
+	/* TCP ヘッダに情報を設定する。*/
+	tcph = GET_TCP_HDR(*nbuf, IF_IP_TCP_HDR_OFFSET(*nbuf));
+	tcph->sport	= htons(cep->myaddr.portno);
+	tcph->dport	= htons(cep->dstaddr.portno);
+	tcph->doff	= TCP_MAKE_DATA_OFF(TCP_HDR_SIZE + optlen);
+	tcph->sum	= tcph->flags = 0;
+
+	return E_OK;
+	}
+#endif
+/*
+ *  tcpn_get_segment -- TCP セグメントを獲得し、ヘッダを設定する。
+ *
+ *    戻り値	エラーコード
+ *    optlen	オプションサイズ、4 オクテット単位
+ *    maxlen	最大セグメントサイズ（IF/IP/TCP ヘッダサイズを含む）
+ *    len	TCP SDU サイズ
+ */
+
+ER
+tcpn_get_segment (T_NET_BUF **nbuf, T_TCP_CEP *cep,
+                 uint_t optlen, uint_t len, uint_t maxlen, ATR nbatr, TMO tmout)
+{
+	T_TCP_HDR	*tcph;
+	ER		error;
+
+	/* IP データグラムを獲得する。*/
+	if ((error = IN_GET_DATAGRAM(nbuf,
+	                             (uint_t)(TCP_HDR_SIZE + optlen + len),
+	                             (uint_t)(maxlen - IF_IP_NET_HDR_SIZE(&cep->dstaddr.ipaddr)),
+	                             &cep->dstaddr.ipaddr,
+	                             &cep->myaddr.ipaddr,
+	                             IPPROTO_TCP, IP_DEFTTL, nbatr, tmout)) != E_OK) {
+		syslog(LOG_WARNING, "[TCP] NET BUF busy,  len:%4d, CEP: %d.",
+		                    (uint16_t)(TCP_HDR_SIZE + optlen + len), GET_TCP_CEPID(cep));
+		return error;
+		}
+
+	/* TCP ヘッダに情報を設定する。*/
+
+	/* TCP ヘッダに情報を設定する。*/
+	tcph = GET_TCP_HDR(*nbuf, IF_IP_TCP_HDR_OFFSET(*nbuf));
+	tcph->sport	= htons(cep->myaddr.portno);
+	tcph->dport	= htons(cep->dstaddr.portno);
+	tcph->doff	= TCP_MAKE_DATA_OFF(TCP_HDR_SIZE + optlen);
+	tcph->sum	= tcph->flags = 0;
+
+	return E_OK;
+	}
+
+/*
+ *  tcp_can_send_more -- 送信できるか、通信端点の状態を見る。
+ */
+
+ER
+tcp_can_send_more (T_TCP_CEP *cep, FN fncd, TMO tmout)
+{
+	ER	error;
+
+	/* 送信できるか、CEP の FSM 状態を見る。*/
+	if (!TCP_FSM_CAN_SEND_MORE(cep->fsm_state)) {
+		if ((error = cep->error) == E_OK)
+			error = E_OBJ;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		/* タイムアウトをチェックする。*/
+		if (tmout == TMO_NBLK) {	/* ノンブロッキングコール */
+
+			if (!IS_PTR_DEFINED(cep->callback))
+				error = E_OBJ;
+			else {
+				/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+				(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)error);
+#else
+				(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)&error);
+#endif
+				error = E_WBLK;
+				}
+			}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		}
+	else {
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+		error = E_OK;
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+		if (!IS_PTR_DEFINED(cep->sbuf)) {
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+			/* タイムアウトをチェックする。*/
+			if (tmout == TMO_NBLK) {	/* ノンブロッキングコール */
+				if (!IS_PTR_DEFINED(cep->callback))
+					error = E_OBJ;
+				else {
+					error = E_OBJ;
+
+					/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+					(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)error);
+#else
+					(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)&error);
+#endif
+					error = E_WBLK;
+					}
+				}
+			else
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+				error = E_OBJ;
+			}
+		else
+			error = E_OK;
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+		}
+
+	return error;
+	}
+
+/*
+ *  tcp_can_recv_more -- 受信できるか、通信端点の状態を見る。
+ *
+ *  注意: 戻り値
+ *
+ *	E_OK	受信可能
+ *	E_OBJ	相手から切断されたか、エラーが発生した。
+ */
+
+ER
+tcp_can_recv_more (ER *error, T_TCP_CEP *cep, FN fncd, TMO tmout)
+{
+	/*
+	 *  受信できるか、fsm_state を見る。受信できない場合は
+	 *  長さ 0、またはエラーを返す。
+	 */
+	if (!TCP_FSM_CAN_RECV_MORE(cep->fsm_state) &&
+	    cep->rwbuf_count == 0 && cep->reassq == NULL) {
+		*error = cep->error;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		/* タイムアウトをチェックする。*/
+		if (tmout == TMO_NBLK) {	/* ノンブロッキングコール */
+
+			if (!IS_PTR_DEFINED(cep->callback))
+				*error = E_OBJ;
+			else {
+				/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+				(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)*error);
+#else
+				(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)error);
+#endif
+				*error = E_WBLK;
+				}
+			}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		/*
+		 *  通信端点をロックして、
+		 *  受信ウィンドバッファキューのネットワークバッファを解放する。
+		 */
+		syscall(wai_sem(cep->semid_lock));
+		TCP_FREE_RWBUFQ(cep);
+		syscall(sig_sem(cep->semid_lock));
+
+		return E_OBJ;
+		}
+	else {
+
+#ifndef TCP_CFG_RWBUF_CSAVE
+
+		if (!IS_PTR_DEFINED(cep->rbuf)) {
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+			/* タイムアウトをチェックする。*/
+			if (tmout == TMO_NBLK) {	/* ノンブロッキングコール */
+				if (!IS_PTR_DEFINED(cep->callback))
+					*error = E_OBJ;
+				else {
+					*error = E_OBJ;
+
+					/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+					(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)*error);
+#else
+					(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)error);
+#endif
+					*error = E_WBLK;
+					}
+				}
+			else
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+				*error = E_OBJ;
+
+			return E_OBJ;
+			}
+
+#endif	/* of #ifndef TCP_CFG_RWBUF_CSAVE */
+
+		return E_OK;
+		}
+	}
+
+/*
+ *  tcp_wait_rwbuf -- 受信ウィンドバッファにデータが入るのを待つ。
+ */
+
+ER
+tcp_wait_rwbuf (T_TCP_CEP *cep, TMO tmout)
+{
+	ER	error;
+	FLGPTN	flag;
+
+	if (cep->rwbuf_count == 0) {
+		/* 受信ウィンドバッファにデータがなければ、入力があるまで待つ。*/
+		while (cep->rwbuf_count == 0) {
+			if ((error = twai_flg(cep->rcv_flgid, TCP_CEP_EVT_RWBUF_READY, TWF_ORW, &flag, tmout)) != E_OK) {
+				return error;
+				}
+			syscall(clr_flg(cep->rcv_flgid, (FLGPTN)(~TCP_CEP_EVT_RWBUF_READY)));
+
+			/*
+			 *  受信できるか、fsm_state を見る。受信できない状態で、
+			 *  受信ウィンドバッファに文字がない場合は終了する。
+			 */
+			if (!TCP_FSM_CAN_RECV_MORE(cep->fsm_state) &&
+			    cep->rwbuf_count == 0 && cep->reassq == NULL) {
+
+				/*
+				 *  通信端点をロックして、
+				 *  受信ウィンドバッファキューのネットワークバッファを解放する。
+				 */
+				syscall(wai_sem(cep->semid_lock));
+				TCP_FREE_RWBUFQ(cep);
+				syscall(sig_sem(cep->semid_lock));
+
+				return cep->error;
+				}
+			}
+		}
+	else {
+		syscall(clr_flg(cep->rcv_flgid, (FLGPTN)(~TCP_CEP_EVT_RWBUF_READY)));
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  tcp_move_ra2rw -- 受信再構成キューで再構成したセグメントを受信ウィンドバッファに書き込む。
+ */
+
+uint8_t
+tcp_move_ra2rw (T_TCP_CEP *cep, uint8_t flags)
+{
+	T_NET_BUF	*q;
+	T_TCP_Q_HDR	*qhdr;
+
+	/*
+	 *  受信データを受信ウィンドバッファに書き込み、
+	 *  rcv_nxt を完了した SEQ だけ進める。
+	 */
+	if (TCP_FSM_HAVE_ESTABLISHED(cep->fsm_state)) {
+		while (cep->reassq != NULL) {
+			q = cep->reassq;
+			qhdr = GET_TCP_Q_HDR(q, GET_IP_TCP_Q_HDR_OFFSET(q));
+			if (qhdr->seq != cep->rcv_nxt)
+				break;
+
+			/* 次のセグメントに進む。*/
+			cep->reassq = qhdr->next;
+
+			/* FIN フラグのみ残す。*/
+			flags &= TCP_FLG_FIN;
+
+			/* データを受信ウィンドバッファに書き込む。*/
+			TCP_WRITE_RWBUF(cep, q, (uint_t)(GET_IP_TCP_Q_HDR_OFFSET(q)));
+			}
+		}
+	if (cep->reassq != NULL) {
+		cep->flags |= TCP_CEP_FLG_ACK_NOW;
+		flags &= ~TCP_FLG_FIN;
+		}
+	return flags;
+	}
+
+/*
+ *  tcp_write_raque -- 受信セグメントを再構成して、受信再構成キューに繋ぐ。
+ */
+
+uint8_t
+tcp_write_raque (T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, uint8_t flags)
+{
+	T_NET_BUF	*new;
+	T_NET_BUF	*p, *q, *nq;
+	T_TCP_Q_HDR	*qhdr, *inqhdr = GET_TCP_Q_HDR(input, thoff);
+	int32_t		len;
+
+	/*  TCP ヘッダの位置を保存する。*/
+	SET_IP_TCP_Q_HDR_OFFSET(input, thoff);
+
+	/*
+	 *  MAX_TCP_REALLOC_SIZE 以下の場合は、新たにネットワークバッファを
+	 *  割当てて、データをコピーする。
+	 *  このとき、IP のオプション（拡張ヘッダ）と TCP のオプションは削除する。
+	 */
+	len  = IF_IP_TCP_HDR_SIZE(input) + inqhdr->slen;
+
+	if (len <= MAX_TCP_REALLOC_SIZE) {
+
+		/*
+		 *  ネットワークバッファが確保できないときは割当てない。
+		 */
+		if (tget_net_buf(&new, (uint_t)len, TMO_TCP_GET_NET_BUF) != E_OK)
+			new = NULL;
+		}
+	else
+		new = NULL;
+
+	/*
+	 *    inqhdr->seq               
+	 *    |
+	 *    |<------- inqhdr->slen ------->|
+	 *    v                              v
+	 *    +------------------------------+
+	 *    |             input            |
+	 *    +------------------------------+
+	 *        ^                  ^
+	 *        |<----- slen ----->|
+	 *        |
+	 *        soff
+	 *
+	 */
+	inqhdr->soff = 0;
+
+	/*
+	 *  今回追加するセグメントより前(p)と後(q)のセグメントを探す。
+	 *
+	 *    +-------------------------+
+	 *    |            p            |
+	 *    +-------------------------+
+	 *    ^              +---------------------------+
+	 *    p->seq         |            input          |
+	 *                   +---------------------------+
+	 *                   ^                      +-------------------------+
+	 *                   inqhdr->seq            |            q            |
+	 *                                          +-------------------------+
+	 *                                          ^
+	 *                                          q->seq
+	 */
+	for (q = cep->reassq, p = NULL; q != NULL; ) {
+		qhdr = GET_TCP_Q_HDR(q, GET_IP_TCP_Q_HDR_OFFSET(q));
+		if (SEQ_GT(qhdr->seq, inqhdr->seq))
+			break;
+		p = q;
+		q = qhdr->next;
+		}
+
+	/*
+	 *  前(p)のセグメントがあれば、既に、今回と同じセグメントが
+	 *  あることもある。その場合は、その部分または全てを破棄する。
+	 *
+	 *    qhdr->seq
+	 *    |
+	 *    |<----- qhdr->slen ------>|
+	 *    v                         v
+	 *    +-------------------------+
+	 *    |            p            |
+	 *    +-------------------------+
+	 *                    <--len -->
+	 *                   +---------------------------+
+	 *                   |            input          |
+	 *                   +---------------------------+
+	 *                   ^
+	 *                   inqhdr->seq
+	 */
+	if (p != NULL) {
+		qhdr = GET_TCP_Q_HDR(p, GET_IP_TCP_Q_HDR_OFFSET(p));
+		len = qhdr->seq + qhdr->slen - inqhdr->seq;
+		if (len > 0) {
+
+			/*
+			 *  len が正であれば、前(p) のセグメントと今回の
+			 *  セグメントが重なっている。
+			 */
+			if (len >= inqhdr->slen) {
+
+				/*
+				 *  len が今回のセグメントと同じなら
+				 *  まったく同じセグメントなので何もしない。
+				 */
+				if (new != NULL) {
+					syscall(rel_net_buf(new));
+					}
+
+				syscall(rel_net_buf(input));
+				return flags;
+				}
+
+			/*
+			 *  追加するセグメントの SDU を len 分前に詰める。
+			 */
+			inqhdr->seq  += len;
+			inqhdr->soff += (uint16_t)len;
+			inqhdr->slen -= (uint16_t)len;
+			}
+		}
+
+	/*
+	 *  キューにつなぐ前に、新しいネットワークバッファにデータを移す。
+	 *  TCP のオプションは削除する。
+	 */
+	if (new != NULL) {
+		memcpy(new->buf, input->buf, (size_t)(thoff + TCP_HDR_SIZE));
+		memcpy((uint8_t*)GET_TCP_HDR(new, thoff) + TCP_HDR_SIZE,
+		                 GET_TCP_SDU(input, thoff), (size_t)(inqhdr->slen));
+		syscall(rel_net_buf(input));
+		input = new;
+		inqhdr = GET_TCP_Q_HDR(input, thoff);
+		inqhdr->doff = (uint8_t)TCP_MAKE_DATA_OFF(TCP_HDR_SIZE);
+		}
+
+	/*
+	 *  重なる後(q)のセグメントを調整する。
+	 *
+	 *    inqhdr->seq
+	 *    |
+	 *    |<----- inqhdr->slen ---->|
+	 *    v                         v
+	 *    +-------------------------+
+	 *    |          input          |
+	 *    +-------------------------+
+	 *                    <--len -->
+	 *                   +---------------------------+
+	 *                   |              q            |
+	 *                   +---------------------------+
+	 *                   ^
+	 *                   qhdr->seq
+	 */
+	while (q != NULL) {
+		qhdr = GET_TCP_Q_HDR(q, GET_IP_TCP_Q_HDR_OFFSET(q));
+		len = inqhdr->seq + inqhdr->slen - qhdr->seq;
+		if (len <= 0)
+			/* len が負なら重なっていない。*/
+			break;
+		else if (len < qhdr->slen) {
+
+			/*
+			 *  後ろで重なっているセグメントの SDU を len 分前に詰める。
+			 *
+			 *    inqhdr->seq
+			 *    |
+			 *    |<----- inqhdr->slen ---->|
+			 *    v                         v
+			 *    +-------------------------+
+			 *    |          input          |
+			 *    +-------------------------+
+			 *                    <--len -->
+			 *            +------+---------------------------+
+			 *            |      |              q            |
+			 *            +------+---------------------------+
+			 *                   ^--------->
+			 *                   qhdr->seq
+			 *                   qhdr->soff
+			 */
+			qhdr->seq  += len;
+			qhdr->soff += (uint16_t)len;
+			qhdr->slen -= (uint16_t)len;
+			break;
+			}
+		nq = qhdr->next;
+		if (p)
+			GET_TCP_Q_HDR(p, GET_IP_TCP_Q_HDR_OFFSET(p))->next = nq;
+		else
+			cep->reassq = nq;
+		syscall(rel_net_buf(q));
+		q = nq;
+		}
+
+	if (p == NULL) {
+		inqhdr->next = cep->reassq;
+		cep->reassq = input;
+		}
+	else {
+		inqhdr->next = GET_TCP_Q_HDR(p, GET_IP_TCP_Q_HDR_OFFSET(p))->next;
+		GET_TCP_Q_HDR(p, GET_IP_TCP_Q_HDR_OFFSET(p))->next = input;
+		}
+
+	return tcp_move_ra2rw(cep, flags);
+	}
+
+/*
+ *  tcp_rexmt_val -- 再送タイムアウト値を返す。
+ */
+
+T_TCP_TIME
+tcp_rexmt_val (T_TCP_CEP *cep)
+{
+	T_TCP_TIME val;
+
+	val = ((cep->srtt >> (TCP_SRTT_SHIFT - TCP_DELTA_SHIFT)) + cep->rttvar) >> TCP_DELTA_SHIFT;
+	if (val < TCP_TVAL_MIN)
+		return TCP_TVAL_MIN;
+	else
+		return val;
+	}
+
+/*
+ *  tcp_init_cep -- 通信端点を初期化する。
+ */
+
+void
+tcp_init_cep (T_TCP_CEP *cep)
+{
+
+#ifdef TCP_CFG_RWBUF_CSAVE
+	/*
+	 * 受信ウィンドバッファの省コピー機能を有効にした場合、
+	 * 受信ウィンドバッファが全て解放されないことがあるので、
+	 * ここで解放する。
+	 */
+	if (cep->rwbufq != NULL) {
+		cep->rwbuf_count = 0;
+		TCP_FREE_RWBUFQ(cep);
+		}
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE */
+
+
+	memset((uint8_t*)cep + offsetof(T_TCP_CEP, timer), 0,
+	       sizeof(T_TCP_CEP) - offsetof(T_TCP_CEP, timer));
+
+	cep->sbuf_rptr	= cep->sbuf_wptr = cep->sbuf;
+	cep->rbuf_rptr	= cep->rbuf_wptr = cep->rbuf;
+
+	cep->maxseg	= DEF_TCP_SND_SEG;		/* 送信最大セグメントサイズ		*/
+	cep->srtt	= TCP_TVAL_SRTT_BASE;		/* 滑らかな移動平均			*/
+	cep->rttvar	= ((TCP_TVAL_RTO_BASE - TCP_TVAL_SRTT_BASE) << TCP_RTTVAR_SHIFT) / 4;
+							/* 滑らかな分散				*/
+	cep->rxtcur	= TCP_TVAL_RTO_BASE;		/* 現在の再送値				*/
+	cep->snd_cwnd	=  MAX_TCP_WIN_SIZE;		/* 輻輳ウィンドサイズ			*/
+	cep->snd_ssthresh= MAX_TCP_WIN_SIZE;		/* 輻輳ウィンドサイズ(snd_cwnd)の	制限値	*/
+
+	/*
+	 * 以下に関係しないフラグをクリアーする。
+	 * ・送受信ウィンドバッファの省コピー機能
+	 * ・動的な通信端点の生成・削除機能
+	 * ・通信端点のネットワーク層プロトコル
+	 */
+	cep->flags &= TCP_CEP_FLG_NOT_CLEAR;
+
+	/* セマフォを初期化する。*/
+	sig_sem(cep->semid_lock);
+
+	/* フラグを初期化する。*/
+	syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY));
+	syscall(clr_flg(cep->rcv_flgid, TCP_CEP_EVT_RWBUF_READY));
+	}
+
+/*
+ *  tcp_notify -- ICMP エラーの処理
+ */
+
+void
+tcp_notify (T_NET_BUF *input, ER error)
+{
+	T_TCP_CEP	*cep;
+
+	if ((cep = tcp_find_cep(input, GET_TCP_HDR_OFFSET(input))) != NULL) {
+
+		/*
+		 *  コネクション開設済で、ホスト到達不能エラーの場合は、
+		 *  再送により処理する。
+		 */
+		if (cep->fsm_state == TCP_FSM_ESTABLISHED &&
+		    (error == EV_NURCH || error == EV_HURCH || error == EV_HDOWN))
+			return;
+
+		/*
+		 *  コネクション開設中、同じエラーを何度か受信した場合は、
+		 *  待ち状態を解除し、対応する関数にエラーを返させる。
+		 */
+		if (cep->fsm_state < TCP_FSM_ESTABLISHED && cep->rxtshift > 3 && cep->net_error != E_OK) {
+			cep->error = E_CLS;
+			tcp_close(cep);
+			}
+		else {
+			cep->net_error = error;
+
+			/* 送信を指示する。*/
+			cep->flags |=  TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+			}
+		}
+	}
+
+/*
+ *  tcp_lock_cep -- TCP 通信端点をロックする。
+ */
+
+ER
+tcp_lock_cep (ID cepid, T_TCP_CEP **p_cep, FN tfn)
+{
+	T_TCP_CEP	*cep;
+	ER		error = E_OK;
+
+	*p_cep = NULL;
+
+	/* TCP 通信端点 ID をチェックする。*/
+	if (!VALID_TCP_CEPID(cepid))
+		return E_ID;
+
+	/* TCP 通信端点を得る。*/
+	cep = GET_TCP_CEP(cepid);
+
+	/* TCP 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/* TCP 通信端点をチェックする。*/
+	if (!VALID_TCP_CEP(cep)) {
+		syscall(sig_sem(cep->semid_lock));
+		return E_NOEXS;
+		}
+
+	/*
+	 *  API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if (IS_TFN_TCP_RCV(tfn)) {
+		if (cep->rcv_tfn != TFN_TCP_UNDEF ||
+		    (tfn == TFN_TCP_ACP_CEP && cep->snd_tfn == TFN_TCP_CON_CEP)) 
+			error = E_OBJ;
+		else {
+			get_tid(&(cep->rcv_tskid));
+			cep->rcv_tfn = tfn;
+			}
+		}
+	else {
+		if (cep->snd_tfn != TFN_TCP_UNDEF ||
+		    (tfn == TFN_TCP_CON_CEP && cep->rcv_tfn == TFN_TCP_ACP_CEP) ||
+		    (tfn == TFN_TCP_CON_CEP && cep->rcv_tfn == TFN_TCP_CLS_CEP))
+			error = E_OBJ;
+		else {
+			get_tid(&(cep->snd_tskid));
+			cep->snd_tfn = tfn;
+			}
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	*p_cep = cep;
+	return error;
+	}
+
+#ifdef TCP_CFG_TRACE
+
+/*
+ *  トレース出力に用いるシリアルポート番号
+ */
+
+#ifndef CONSOLE_PORTID
+#define	CONSOLE_PORTID		LOGTASK_PORTID
+#endif
+
+/*
+ *  コネクションの状態
+ */
+
+static const char tcp_strfsm[][3] = {
+	{ 'C', 'D', '\0' },
+	{ 'L', 'I', '\0' },
+	{ 'S', 'S', '\0' },
+	{ 'S', 'R', '\0' },
+	{ 'E', 'S', '\0' },
+	{ 'C', 'W', '\0' },
+	{ 'F', '1', '\0' },
+	{ 'C', 'G', '\0' },
+	{ 'L', 'A', '\0' },
+	{ 'F', '2', '\0' },
+	{ 'T', 'W', '\0' },
+	};
+
+/*
+ *  trace_putchar -- シリアルポートへの文字出力
+ */
+
+static void
+trace_putchar (ID portid, char ch)
+{
+	serial_wri_dat(portid, &ch, 1);
+	/*cpu_putc(ch);*/
+	}
+
+/*
+ *  シリアルポートへの書式付文字列出力ライブラリ
+ */
+
+/*
+ *  数値変換のための変換表
+ */
+
+static const char radhex[] = "0123456789abcdef";
+static const char radHEX[] = "0123456789ABCDEF";
+
+/*
+ *  convert -- trace_printf の数値変換
+ */
+
+static int_t
+convert (ID portid, long_t val, int_t radix,
+         const char *radchar, int_t width, bool_t minus, char padchar)
+{
+	char	digits[24];
+	int_t	ix, pad, pchars;
+
+	ix = 0;
+	do {
+		if (minus)
+			digits[ix ++] = radchar[val % radix];
+		else
+			digits[ix ++] = radchar[(ulong_t)val % radix];
+		val /= radix;
+		} while (val != 0);
+
+	if (minus)
+		digits[ix ++] = '-';
+
+	if (width > ix)
+		pchars = width;
+	else
+		pchars = ix;
+
+	for (pad = ix; pad < width; pad ++)
+		trace_putchar(portid, padchar);
+
+	while (ix -- > 0)
+		trace_putchar(portid, digits[ix]);
+
+	return pchars;
+	}
+
+/*
+ *  trace_printf -- シリアルポートへの書式付文字列出力
+ */
+
+static void
+trace_printf (ID portid, const char *fmt, ...)
+{
+	va_list	ap;
+	ulong_t	val;
+	char	padchar, *str;
+	int_t	ch, width, longflag;
+
+	va_start(ap, fmt);
+	while ((ch = *fmt ++) != '\0') {
+		if (ch != '%') {		/* 書式指定以外 */
+			trace_putchar(portid, (char)ch);
+			continue;
+			}
+
+		width = longflag = 0;
+		padchar = ' ';
+		if ((ch = *fmt ++) == '0') {	/* 上位桁の 0 */
+			padchar = '0';
+			ch = *fmt ++;
+			}
+
+		while ('0' <= ch && ch <= '9') {	/* 出力幅 */
+			width = width * 10 + ch - '0';
+			ch = *fmt ++;
+			}
+
+		while (ch == 'l') {		/* long (long) の指定 */
+			longflag ++;
+			ch = *fmt ++;
+			}
+
+		switch (ch) {
+		case 'd':
+			val = longflag ? (ulong_t)va_arg(ap, long_t)
+			               : (ulong_t)va_arg(ap, int_t);
+			if (val >= 0)
+				convert(portid,  val, 10, radhex, width, false, padchar);
+			else
+				convert(portid, -val, 10, radhex, width, true, padchar);
+			break;
+
+		case 'u':
+			val = longflag ? (ulong_t)va_arg(ap, ulong_t)
+			               : (ulong_t)va_arg(ap, uint_t);
+			convert(portid, val, 10, radhex, width, false, padchar);
+			break;
+
+		case 'x':
+			val = longflag ? (ulong_t)va_arg(ap, ulong_t)
+			               : (ulong_t)va_arg(ap, uint_t);
+			convert(portid, val, 16, radhex, width, false, padchar);
+			break;
+
+		case 'X':
+			val = longflag ? (ulong_t)va_arg(ap, ulong_t)
+			               : (ulong_t)va_arg(ap, uint_t);
+			convert(portid, val, 16, radHEX, width, false, padchar);
+			break;
+
+		case 'c':
+			ch = va_arg(ap, int_t);
+			trace_putchar(portid, (char)ch);
+			break;
+
+		case 's':
+			str = va_arg(ap, char*);
+			while ((ch = *str ++) != '\0')
+				trace_putchar(portid, (char)ch);
+			break;
+
+		case '%':
+			trace_putchar(portid, '%');
+			break;
+
+		case '0':
+			fmt --;
+			break;
+
+		default:
+			break;
+			}
+
+		}
+	va_end(ap);
+	}
+
+/*
+ *  TCP フラグ文字列
+ */
+
+static char *
+get_tcp_flag_str (char *buf, uint8_t flags)
+{
+	static char tcp_flag_str[] = "FSRPAU";
+
+	int_t	bit, mask = 1;
+
+	for (bit = 0; bit < sizeof(tcp_flag_str); bit ++) {
+		buf[sizeof(tcp_flag_str) - bit - 1] = (char)((flags & mask) ? tcp_flag_str[bit] : '-');
+		mask <<= 1;
+		}
+	buf[sizeof(tcp_flag_str)] = '\0';
+	return buf;
+	}
+
+/*
+ *  送信 TCP ヘッダのトレース出力
+ */
+
+void
+tcp_output_trace (T_NET_BUF *output, T_TCP_CEP *cep)
+{
+	SYSTIM		time;
+	T_TCP_HDR	*tcph;
+	char		buf[9];
+
+	if (!(TCP_CFG_TRACE_LPORTNO == TCP_PORTANY || cep->myaddr.portno  == TCP_CFG_TRACE_LPORTNO) ||
+	    !(TCP_CFG_TRACE_RPORTNO == TCP_PORTANY || cep->dstaddr.portno == TCP_CFG_TRACE_RPORTNO))
+		return;
+
+#if defined(_IP4_CFG)
+
+#if defined(_IP6_CFG)
+
+	if (!((TCP_CFG_TRACE_IPV4_RADDR == IPV4_ADDRANY) ||
+	     ((cep->flags & TCP_CEP_FLG_IPV4) && 
+	      IN6_IS_ADDR_V4MAPPED(&cep->dstaddr.ipaddr) &&
+	      (ntohl(cep->dstaddr.ipaddr.s6_addr32[3]) == TCP_CFG_TRACE_IPV4_RADDR))))
+		return;
+
+#else	/* of #if defined(_IP6_CFG) */
+
+	if (!(TCP_CFG_TRACE_IPV4_RADDR == IPV4_ADDRANY || cep->dstaddr.ipaddr == TCP_CFG_TRACE_IPV4_RADDR))
+		return;
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+	syscall(wai_sem(SEM_TCP_TRACE));
+	syscall(get_tim(&time));
+	tcph = GET_TCP_HDR(output, GET_TCP_HDR_OFFSET(output));
+	if (time > 99999999)
+		trace_printf(CONSOLE_PORTID, "=O%10d", time / 1000);
+	else
+		trace_printf(CONSOLE_PORTID, "=O%6d.%03d", time / 1000, time % 1000);
+	if (cep == NULL)
+		trace_printf(CONSOLE_PORTID, "=c:-- s:-- f:--------");
+	else
+		trace_printf(CONSOLE_PORTID, "=c:%2d s:%s f:%08x",
+		                             GET_TCP_CEPID(cep),
+		                             tcp_strfsm[cep->fsm_state], cep->flags);
+	trace_printf(CONSOLE_PORTID, ":%s", get_tcp_flag_str(buf, tcph->flags));
+	if (cep->fsm_state >= TCP_FSM_ESTABLISHED)
+		trace_printf(CONSOLE_PORTID, " s:%10u a:%10u",
+		                             ntohl(tcph->seq) - cep->iss,
+		                             ntohl(tcph->ack) - cep->irs);
+	else
+		trace_printf(CONSOLE_PORTID, " s:%10u a:%10u",
+		                             ntohl(tcph->seq), ntohl(tcph->ack));
+	trace_printf(CONSOLE_PORTID, " w:%5d l:%4d>\n", 
+	                             ntohs(tcph->win),
+	                             GET_IP_SDU_SIZE(output) - TCP_HDR_LEN(tcph->doff));
+	syscall(sig_sem(SEM_TCP_TRACE));
+	}
+
+/*
+ *  受信 TCP ヘッダのトレース出力
+ *
+ *    注意: TCP ヘッダ内は、すでにホストバイトオーダ
+ */
+
+void
+tcp_input_trace (T_NET_BUF *input, T_TCP_CEP *cep)
+{
+	SYSTIM		time;
+	T_TCP_HDR	*tcph;
+	char		buf[9];
+
+	if (!(TCP_CFG_TRACE_LPORTNO == TCP_PORTANY || cep->myaddr.portno  == TCP_CFG_TRACE_LPORTNO) ||
+	    !(TCP_CFG_TRACE_RPORTNO == TCP_PORTANY || cep->dstaddr.portno == TCP_CFG_TRACE_RPORTNO))
+		return;
+
+#if defined(_IP4_CFG)
+
+#if defined(_IP6_CFG)
+
+	if (!((TCP_CFG_TRACE_IPV4_RADDR == IPV4_ADDRANY) ||
+	     ((cep->flags & TCP_CEP_FLG_IPV4) && 
+	      IN6_IS_ADDR_V4MAPPED(&cep->dstaddr.ipaddr) &&
+	      (ntohl(cep->dstaddr.ipaddr.s6_addr32[3]) == TCP_CFG_TRACE_IPV4_RADDR))))
+		return;
+
+#else	/* of #if defined(_IP6_CFG) */
+
+	if (!(TCP_CFG_TRACE_IPV4_RADDR == IPV4_ADDRANY || cep->dstaddr.ipaddr == TCP_CFG_TRACE_IPV4_RADDR))
+		return;
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+	syscall(wai_sem(SEM_TCP_TRACE));
+	syscall(get_tim(&time));
+	tcph = GET_TCP_HDR(input, GET_TCP_HDR_OFFSET(input));
+	if (time > 99999999)
+		trace_printf(CONSOLE_PORTID, "<I%10d", time / 1000);
+	else
+		trace_printf(CONSOLE_PORTID, "<I%6d.%03d", time / 1000, time % 1000);
+	if (cep == NULL)
+		trace_printf(CONSOLE_PORTID, "=c:-- s:-- f:--------");
+	else
+		trace_printf(CONSOLE_PORTID, "=c:%2d s:%s f:%08x",
+		                             GET_TCP_CEPID(cep),
+		                             tcp_strfsm[cep->fsm_state], cep->flags);
+	trace_printf(CONSOLE_PORTID, ":%s", get_tcp_flag_str(buf, tcph->flags));
+	if (cep->fsm_state >= TCP_FSM_SYN_RECVD)
+		trace_printf(CONSOLE_PORTID, " a:%10u s:%10u", tcph->ack - cep->iss, tcph->seq - cep->irs);
+	else
+		trace_printf(CONSOLE_PORTID, " a:%10u s:%10u", tcph->ack, tcph->seq);
+	trace_printf(CONSOLE_PORTID, " w:%5d l:%4d=\n", 
+	                             tcph->win, GET_IP_SDU_SIZE(input) - TCP_HDR_LEN(tcph->doff));
+	syscall(sig_sem(SEM_TCP_TRACE));
+	}
+
+#endif	/* of #ifdef TCP_CFG_TRACE */
+
+#endif	/* of #ifdef SUPPORT_TCP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_subr_cs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_subr_cs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_subr_cs.c	(revision 398)
@@ -0,0 +1,1096 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp_subr.c	8.2 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/netinet/tcp_subr.c,v 1.49.2.4 1999/08/29 16:29:55 peter Exp $
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+
+#ifdef SUPPORT_TCP
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+/*
+ *  TCP 通信端点の送信ウィンドバッファの省コピー機能が有効な場合
+ *  ただし、通信端点の送信ウィンドバッファ（cep->sbuf）の値により、
+ *  TCP 通信端点毎に送信ウィンドバッファの省コピー機能を使用するか、
+ *  使用しないかを切り替える。
+ */
+
+/*
+ *  tcp_drop_swbuf -- 送信ウィンドバッファから指定されたオクテット分削除する（選択）。
+ */
+
+void
+tcp_drop_swbuf (T_TCP_CEP *cep, uint_t len)
+{
+	if (IS_PTR_DEFINED(cep->sbuf))
+		tcp_drop_swbuf_ncs(cep, len);
+	else
+		tcp_drop_swbuf_cs(cep, len);
+	}
+
+/*
+ *  tcp_write_swbuf -- 送信ウィンドバッファにデータを書き込む（選択）。
+ */
+
+ER_UINT
+tcp_write_swbuf (T_TCP_CEP *cep, void *data, uint_t len)
+{
+	if (IS_PTR_DEFINED(cep->sbuf))
+		return tcp_write_swbuf_ncs(cep, data, len);
+	else
+		return tcp_write_swbuf_cs(cep, data, len);
+	}
+
+/*
+ *  tcp_read_swbuf -- 送信ウィンドバッファからデータを読み出す（選択）。
+ */
+
+void
+tcp_read_swbuf (T_TCP_CEP *cep, T_NET_BUF *output, uint_t len, uint_t doff)
+{
+	if (IS_PTR_DEFINED(cep->sbuf))
+		tcp_read_swbuf_ncs(cep, output, len, doff);
+	}
+
+/*
+ *  tcp_wait_swbuf -- 送信ウィンドバッファと相手の受信ウィンドが開くのを待つ（選択）。
+ */
+
+ER
+tcp_wait_swbuf (T_TCP_CEP *cep, TMO tmout)
+{
+	if (IS_PTR_DEFINED(cep->sbuf))
+		return tcp_wait_swbuf_ncs(cep, tmout);
+	else
+		return tcp_wait_swbuf_cs(cep, tmout);
+	}
+
+/*
+ *  tcp_get_swbuf_addr -- 送信ウィンドバッファの空きアドレスを獲得する（選択）。
+ */
+
+ER_UINT
+tcp_get_swbuf_addr (T_TCP_CEP *cep, void **p_buf)
+{
+	if (IS_PTR_DEFINED(cep->sbuf))
+		return tcp_get_swbuf_addr_ncs(cep, p_buf);
+	else
+		return tcp_get_swbuf_addr_cs(cep, p_buf);
+	}
+
+/*
+ *  tcp_send_swbuf -- 送信ウィンドバッファのデータを送信可能にする（選択）。
+ */
+
+void
+tcp_send_swbuf (T_TCP_CEP *cep, uint_t len)
+{
+	if (IS_PTR_DEFINED(cep->sbuf))
+		tcp_send_swbuf_ncs(cep, len);
+	else
+		tcp_send_swbuf_cs(cep, len);
+	}
+
+/*
+ *  tcp_free_swbufq -- 送信ウィンドバッファキューの解放を指示する（選択）。
+ */
+
+void
+tcp_free_swbufq (T_TCP_CEP *cep)
+{
+	if (!IS_PTR_DEFINED(cep->sbuf))
+		tcp_free_swbufq_cs(cep);
+	}
+
+/*
+ *  tcp_alloc_swbuf -- 送信ウィンドバッファ用のネットワークバッファの割り当てを指示する（選択）。
+ */
+
+void
+tcp_alloc_swbuf (T_TCP_CEP *cep)
+{
+	if (!IS_PTR_DEFINED(cep->sbuf))
+		tcp_alloc_swbuf_cs(cep);
+	}
+
+/*
+ *  tcp_is_swbuf_full -- 送信ウィンドバッファが満杯かチェックする（選択）。
+ */
+
+bool_t
+tcp_is_swbuf_full (T_TCP_CEP *cep)
+{
+	if (IS_PTR_DEFINED(cep->sbuf))
+		return tcp_is_swbuf_full_ncs(cep);
+	else
+		return tcp_is_swbuf_full_cs(cep);
+	}
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+/*
+ *  tcp_drop_swbuf_cs -- 送信ウィンドバッファから指定されたオクテット分削除する（専用）。
+ */
+
+void
+tcp_drop_swbuf_cs (T_TCP_CEP *cep, uint_t len)
+{
+
+	/*送信ウィンドバッファから指定されたオクテット分削除する。*/
+	cep->swbuf_count -= (uint16_t)len;
+
+	/* 送信済みで、ACK待ちの時は、ACK完了に変更する。*/
+	if (len > 0 && (cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_SENT) {
+		cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) | TCP_CEP_FLG_WBCS_ACKED;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		}
+	}
+
+/*
+ *  tcp_write_swbuf_cs -- 送信ウィンドバッファにデータを書き込む（専用）。
+ */
+
+ER_UINT
+tcp_write_swbuf_cs (T_TCP_CEP *cep, void *data, uint_t len)
+{
+	ER_UINT	error;
+	uint_t	hdr_size = IF_IP_TCP_NET_HDR_SIZE(&cep->dstaddr.ipaddr);
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	if ((error = net_buf_siz(cep->swbufq)) > 0 && error >= hdr_size) {
+
+		/*
+		 *  +-----------+--------+---------+---------+
+		 *  | Ehter HDR | IP HDR | TCP HDR | TCP SDU |
+		 *  +-----------+--------+---------+---------+
+		 *        14        20        20        n
+		 *   <---------------- error --------------->
+		 *              ^
+		 *              net_buf で 4 オクテット境界にアラインされている。
+		 *
+		 *  tcp_output と ip_output で、チェックサムを計算するとき、
+		 *  n が 4 オクテット境界になるように SDU の後ろに 0 を
+		 *  パッディングする。その分を考慮して送信ウィンドバッファの
+		 *  空きサイズを 4 オクテット境界に調整する。
+		 */
+		error = (uint_t)(((error - hdr_size) >> 2 << 2) + hdr_size);
+
+		if (len > cep->sbufsz - cep->swbuf_count)
+			len = (uint_t)(cep->sbufsz - cep->swbuf_count);
+		if (len > (error - hdr_size))
+			len = (uint_t)(error - hdr_size);
+
+		/* 送信ウインドサイズによりサイズを調整する。*/
+		if (len > cep->snd_wnd) 
+			len = cep->snd_wnd;
+		if (len > cep->snd_cwnd)
+			len = cep->snd_cwnd;
+
+		/* 相手の最大受信セグメントサイズ (maxseg) を超えないようにする。*/
+		if (len > cep->maxseg) 
+			len = cep->maxseg;
+
+		/* データを移す。*/
+		memcpy(cep->sbuf_wptr, (void*)((uint8_t*)data), (size_t)len);
+		cep->sbuf_wptr   += len;
+		cep->swbuf_count += len;
+		error             = len;
+
+		/* ネットワークバッファ長と IP データグラム長を設定する。*/
+		cep->swbufq->len = (uint16_t)(cep->swbuf_count + hdr_size);
+		SET_IP_SDU_SIZE(cep->swbufq, cep->swbuf_count + TCP_HDR_SIZE);
+
+		/* フラグを、送信可能に設定する。*/
+		cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) | TCP_CEP_FLG_WBCS_SEND_READY;
+		}
+
+	else {	/* 送信ウインドバッファが不正 */
+		syslog(LOG_WARNING, "[TCP] illegal window buff for send, CEP: %d, %4d < %4d.",
+		                    GET_TCP_CEPID(cep), error, hdr_size);
+
+		/* 送信ウィンドバッファキューのネットワークバッファを解放する。*/
+		tcp_free_swbufq_cs(cep);
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+/*
+ *  tcp_wait_swbuf_cs -- 送信ウィンドバッファと相手の受信ウィンドが開くのを待つ（専用）。
+ */
+
+ER
+tcp_wait_swbuf_cs (T_TCP_CEP *cep, TMO tmout)
+{
+	FLGPTN	flag;
+	SYSTIM	before, after;
+	ER	error;
+	int_t	win;
+
+	/* 送信ウィンドバッファが割当て済みで、空きがあれば終了する。*/
+	if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_NBUF_READY &&
+	    (cep->swbuf_count + IF_IP_TCP_NET_HDR_SIZE(&cep->dstaddr.ipaddr)) < net_buf_siz(cep->swbufq))
+		return E_OK;
+
+	/* 送信中であれば、終了するまで待機する。*/
+	while ((cep->flags & TCP_CEP_FLG_WBCS_MASK) != TCP_CEP_FLG_WBCS_FREE) {
+
+		/* 送信待ちの時間を tmout から減ずる。*/
+		if (!(tmout == TMO_POL || tmout == TMO_FEVR))
+			syscall(get_tim(&before));
+
+		if ((error = twai_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY,
+		                      TWF_ORW, &flag, tmout)) != E_OK)
+			return error;
+		syscall(clr_flg(cep->snd_flgid, (FLGPTN)(~TCP_CEP_EVT_SWBUF_READY)));
+
+		/* 送信待ちの時間を tmout から減ずる。*/
+		if (!(tmout == TMO_POL || tmout == TMO_FEVR)) {
+			syscall(get_tim(&after));
+			if (after - before > tmout)
+				return E_TMOUT;
+			tmout -= (TMO)(after - before);
+			}
+
+		/*
+		 *  送信できるか、CEP の FSM 状態を見る。
+		 *  送信ウインドバッファが空くまで待つ間に、送信不能になった場合は、
+		 *  コネクションが切断されたことを意味している。
+		 */
+		if (!TCP_FSM_CAN_SEND_MORE(cep->fsm_state))
+			return E_CLS;
+		}
+
+	/* 相手の受信ウィンドが閉じている場合は、開くまで待機する。*/
+	while (true) {
+
+		/*
+		 *  snd_wnd:  相手の受信可能ウィンドサイズ
+		 *  snd_cwnd: 輻輳ウィンドサイズ
+		 *
+		 *  win: どちらか小さいウィンドサイズに設定する。
+		 */
+		win = cep->snd_wnd < cep->snd_cwnd ? cep->snd_wnd : cep->snd_cwnd;
+		if (win > 0)
+			break;
+
+		/* 開き待ちの時間を tmout から減ずる。*/
+		if (!(tmout == TMO_POL || tmout == TMO_FEVR))
+			syscall(get_tim(&before));
+
+		if ((error = twai_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY,
+		                      TWF_ORW, &flag, tmout)) != E_OK)
+			return error;
+		syscall(clr_flg(cep->snd_flgid, (FLGPTN)(~TCP_CEP_EVT_SWBUF_READY)));
+
+		/* 開き待ちの時間を tmout から減ずる。*/
+		if (!(tmout == TMO_POL || tmout == TMO_FEVR)) {
+			syscall(get_tim(&after));
+			if (after - before > tmout)
+				return E_TMOUT;
+			tmout -= (TMO)(after - before);
+			}
+
+		/*
+		 *  送信できるか、CEP の FSM 状態を見る。
+		 *  送信ウインドバッファが空くまで待つ間に、送信不能になった場合は、
+		 *  コネクションが切断されたことを意味している。
+		 */
+		if (!TCP_FSM_CAN_SEND_MORE(cep->fsm_state))
+			return E_CLS;
+		}
+
+	/* ネットワークバッファを獲得する。*/
+	if ((error = tcpn_get_segment(&cep->swbufq, cep, 0,
+	                             TCP_CFG_SWBUF_CSAVE_MIN_SIZE,
+	                             TCP_CFG_SWBUF_CSAVE_MAX_SIZE,
+	                             NBA_SEARCH_DESCENT, tmout)) != E_OK)
+		return error;
+
+	/* 送信ウィンドバッファを初期化する。*/
+	tcp_init_swbuf(cep);
+
+	return E_OK;
+	}
+
+/*
+ *  tcp_get_swbuf_addr_cs -- 送信ウィンドバッファの空きアドレスを獲得する（専用）。
+ */
+
+ER_UINT
+tcp_get_swbuf_addr_cs (T_TCP_CEP *cep, void **p_buf)
+{
+	ER_UINT	error;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	if ((error = net_buf_siz(cep->swbufq)) > 0) {
+
+		/*
+		 *  +-----------+--------+---------+---------+
+		 *  | Ehter HDR | IP HDR | TCP HDR | TCP SDU |
+		 *  +-----------+--------+---------+---------+
+		 *        14        20        20        n
+		 *   <---------------- error --------------->
+		 *              ^
+		 *              net_buf で 4 オクテット境界にアラインされている。
+		 *
+		 *  tcp_output と ip_output で、チェックサムを計算するとき、
+		 *  n が 4 オクテット境界になるように SDU の後ろに 0 を
+		 *  パッディングする。その分を考慮して送信ウィンドバッファの
+		 *  空きサイズを 4 オクテット境界に調整する。
+		 */
+		error = (uint_t)(((error - IF_IP_TCP_NET_HDR_SIZE(&cep->dstaddr.ipaddr)) >> 2 << 2) - cep->swbuf_count);
+
+		/* 送信ウインドサイズによりサイズを調整する。*/
+		if (error > cep->snd_wnd) 
+			error = cep->snd_wnd;
+		if (error > cep->snd_cwnd)
+			error = cep->snd_cwnd;
+
+		/* 相手の最大受信セグメントサイズ (maxseg) を超えないようにする。*/
+		if (error > cep->maxseg) 
+			error = cep->maxseg;
+
+		/* 送信ウィンドバッファの空きデータ長を設定し、その値を返す。*/
+		cep->get_buf_len = error;
+
+		/* 送信ウィンドバッファの空きアドレスの先頭を設定する。*/
+		*p_buf = cep->sbuf_wptr;
+		}
+
+	else {	/* ネットワークバッファが不正 */
+
+		/* 送信ウィンドバッファキューのネットワークバッファを解放する。*/
+		tcp_free_swbufq_cs(cep);
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+/*
+ *  tcp_send_swbuf_cs -- 送信ウィンドバッファのデータを送信可能にする（専用）。
+ */
+
+void
+tcp_send_swbuf_cs (T_TCP_CEP *cep, uint_t len)
+{
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	cep->sbuf_wptr  += len;
+	cep->swbuf_count += len;
+
+	/* ネットワークバッファ長と IP データグラム長を設定する。*/
+	cep->swbufq->len = (uint16_t)(cep->swbuf_count + IF_IP_TCP_NET_HDR_SIZE(&cep->dstaddr.ipaddr));
+	SET_IP_SDU_SIZE(cep->swbufq, len + TCP_HDR_SIZE);
+
+	/* tcp_get_buf の割当て長をリセットする。*/
+	cep->get_buf_len = 0;
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	/* フラグを、送信可能に設定し、強制的に送信する。*/
+	cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) | TCP_CEP_FLG_WBCS_SEND_READY
+	                                               | TCP_CEP_FLG_FORCE
+	                                               | TCP_CEP_FLG_FORCE_CLEAR
+	                                               | TCP_CEP_FLG_POST_OUTPUT;
+	}
+
+/*
+ *  tcp_free_swbufq_cs -- 送信ウィンドバッファキューの解放を指示する（専用）。
+ *
+ *    注意:
+ *      必要であれば、この関数を呼び出す前に、通信端点をロックし、
+ *      戻った後、解除する必要がある。
+ */
+
+void
+tcp_free_swbufq_cs (T_TCP_CEP *cep)
+{
+	/* 送信ウィンドバッファの空き待ちを取り消す。*/
+	cep->flags &= ~TCP_CEP_FLG_WBCS_NBUF_REQ;
+
+	if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) != TCP_CEP_FLG_WBCS_FREE) {
+		/*
+		 *  送信ウィンドバッファを削除するために、フラグを ACK 完了に設定し、
+		 *  TCP 出力タスクを起動する。
+		 */
+		cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) | TCP_CEP_FLG_WBCS_ACKED;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		}
+	}
+
+/*
+ *  tcp_alloc_swbuf_cs -- 送信ウィンドバッファ用のネットワークバッファの割り当てを指示する（専用）。
+ */
+
+void
+tcp_alloc_swbuf_cs (T_TCP_CEP *cep)
+{
+	cep->flags |= TCP_CEP_FLG_WBCS_NBUF_REQ;
+
+	/*
+	 *  送信ウィンドバッファが未使用の場合のみ、
+	 *  送信ウィンドバッファ用のネットワークバッファの割り当てを指示する。
+	 */
+	if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_FREE)
+		sig_sem(SEM_TCP_POST_OUTPUT);
+	}
+
+/*
+ *  tcp_is_swbuf_full_cs -- 送信ウィンドバッファが満杯かチェックする（専用）。
+ */
+
+bool_t
+tcp_is_swbuf_full_cs (T_TCP_CEP *cep)
+{
+	return (cep->flags & TCP_CEP_FLG_WBCS_MASK) != TCP_CEP_FLG_WBCS_NBUF_READY ||
+	        cep->swbuf_count >= cep->swbufq->len - IF_IP_TCP_NET_HDR_SIZE(&cep->dstaddr.ipaddr);
+	}
+
+/*
+ *  tcp_init_swbuf -- 送信ウィンドバッファを初期化する（専用）。
+ *
+ *    注意: tcp_get_segment でネットワークバッファを獲得した
+ *          直後に呼び出すこと。
+ */
+
+void
+tcp_init_swbuf (T_TCP_CEP *cep)
+{
+	/* 送信ウインドバッファの使用中サイズをリセットする。*/
+	cep->swbuf_count = 0;
+
+	/* 送信ウインドバッファのアドレスを設定する。*/
+	cep->sbuf_wptr = cep->sbuf_rptr = GET_TCP_SDU(cep->swbufq, IF_IP_TCP_NET_HDR_OFFSET(&cep->dstaddr.ipaddr));
+
+	/* フラグを、ネットワークバッファ割当て済みに設定する。*/
+	cep->flags = (cep->flags & ~(TCP_CEP_FLG_WBCS_NBUF_REQ | TCP_CEP_FLG_WBCS_MASK))
+	                         |   TCP_CEP_FLG_WBCS_NBUF_READY;
+	}
+
+/*
+ *  tcp_push_res_nbuf -- ネットワークバッファを予約する（専用）。
+ */
+
+T_NET_BUF *
+tcp_push_res_nbuf (T_NET_BUF *nbuf)
+{
+	static int_t last_ix = 0;
+
+	T_TCP_CEP	*cep;
+ 	int_t		ix, sel_ix;
+
+	if (++ last_ix == tmax_tcp_cepid)
+		last_ix = 0;
+	sel_ix = ix = last_ix;
+	do {
+		cep = &tcp_cep[ix];
+		if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_NBUF_PEND) {
+
+			/* ネットワークバッファを予約する。*/
+			cep->swbufq = nbuf;
+			nbuf = NULL;
+
+			/* フラグを予約に設定する。*/
+			cep->flags = (cep->flags & ~TCP_CEP_FLG_WBCS_MASK) | TCP_CEP_FLG_WBCS_NBUF_RSVD;
+			sel_ix = ix;
+			break;
+			}
+		if (++ ix == tmax_tcp_cepid)
+			ix = 0;
+		} while (ix != last_ix);
+
+	last_ix = sel_ix;
+
+	return nbuf;
+	}
+
+/*
+ *  tcp_pull_res_nbuf -- 予約してあるネットワークバッファ返す（専用）。
+ */
+
+T_NET_BUF *
+tcp_pull_res_nbuf (ATR nbatr)
+{
+	T_NET_BUF	*nbuf;
+	T_TCP_CEP	*cep;
+
+	cep = GET_TCP_CEP(nbatr & NBA_ID_MASK);
+	if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_NBUF_RSVD) {
+
+		/* 予約してあるネットワークバッファを返す。*/
+		nbuf = cep->swbufq;
+		cep->swbufq = NULL;
+
+		/* TCP 出力タスクを起動する。*/
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		}
+	else
+		nbuf = NULL;
+
+	return nbuf;
+	}
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+#ifdef TCP_CFG_RWBUF_CSAVE 
+
+#ifdef TCP_CFG_RWBUF_CSAVE_ONLY
+
+#else	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+/*
+ *  TCP 通信端点の受信ウィンドバッファの省コピー機能が有効な場合
+ *  ただし、通信端点の受信ウィンドバッファ（cep->rbuf）の値により、
+ *  TCP 通信端点毎に受信ウィンドバッファの省コピー機能を使用するか、
+ *  使用しないかを切り替える。
+ */
+
+/*
+ *  tcp_drop_rwbuf -- 受信ウィンドバッファキューの最初のネットワークバッファを解放する。
+ */
+
+void
+tcp_drop_rwbuf (T_TCP_CEP *cep, uint_t len)
+{
+	if (IS_PTR_DEFINED(cep->rbuf))
+		tcp_drop_rwbuf_ncs(cep, len);
+	else
+		tcp_drop_rwbuf_cs(cep, len);
+	}
+
+/*
+ *  tcp_read_rwbuf -- 受信ウィンドバッファから指定されたオクテット分読み出す。
+ */
+
+uint_t
+tcp_read_rwbuf (T_TCP_CEP *cep, void *data, uint_t len)
+{
+	if (IS_PTR_DEFINED(cep->rbuf))
+		return tcp_read_rwbuf_ncs(cep, data, len);
+	else
+		return tcp_read_rwbuf_cs(cep, data, len);
+	}
+
+/*
+ *  tcp_get_rwbuf_addr -- 受信ウィンドバッファの空きアドレスを獲得する。
+ */
+
+uint_t
+tcp_get_rwbuf_addr (T_TCP_CEP *cep, void **p_buf)
+{
+	if (IS_PTR_DEFINED(cep->rbuf))
+		return tcp_get_rwbuf_addr_ncs(cep, p_buf);
+	else
+		return tcp_get_rwbuf_addr_cs(cep, p_buf);
+	}
+
+/*
+ *  tcp_free_rwbufq -- 受信ウィンドバッファキューを解放する。
+ */
+
+void
+tcp_free_rwbufq (T_TCP_CEP *cep)
+{
+	if (!IS_PTR_DEFINED(cep->rbuf))
+		tcp_free_rwbufq_cs(cep);
+	}
+
+/*
+ *  tcp_write_rwbuf -- 受信ウィンドバッファにデータを書き込む。
+ */
+
+void
+tcp_write_rwbuf (T_TCP_CEP *cep, T_NET_BUF *input, uint_t thoff)
+{
+	if (IS_PTR_DEFINED(cep->rbuf))
+		tcp_write_rwbuf_ncs(cep, input, thoff);
+	else
+		tcp_write_rwbuf_cs(cep, input, thoff);
+	}
+
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+/*
+ *  TCP 通信端点の受信ウィンドバッファの省コピー機能が有効
+ */
+
+/*
+ *  tcp_drop_rwbuf -- 受信ウィンドバッファキューの最初のネットワークバッファを解放する。
+ */
+
+void
+tcp_drop_rwbuf_cs (T_TCP_CEP *cep, uint_t len)
+{
+	T_TCP_Q_HDR	*qhdr;
+
+	if (cep->rwbufq != NULL) {
+
+		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq));
+		cep->rwbuf_count -= len;
+
+		/* ネットワークバッファにデータが無くなったら解放する。*/
+		if (len == qhdr->slen) {
+			T_NET_BUF *next;
+
+#ifdef TCP_CFG_RWBUF_CSAVE_MAX_QUEUES
+
+			cep->rwbufq_entries --;
+
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE_MAX_QUEUES */
+
+			next = qhdr->next;
+			syscall(rel_net_buf(cep->rwbufq));
+			cep->rwbufq = next;
+			}
+		else {
+			qhdr->slen -= len;
+			qhdr->soff += len;
+			}
+		}
+	}
+
+/*
+ *  tcp_read_rwbuf -- 受信ウィンドバッファから指定されたオクテット分読み出す。
+ */
+
+uint_t
+tcp_read_rwbuf_cs (T_TCP_CEP *cep, void *data, uint_t len)
+{
+	T_TCP_Q_HDR	*qhdr;
+	uint_t		blen, rlen = 0;
+	uint8_t		*buf = (uint8_t*)data;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 *  受信ウィンドバッファキューにネットワークバッファが無くなるか
+	 *  len が 0 になるまで続ける。
+	 */
+	while (cep->rwbufq != NULL && len > 0) {
+		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq));
+
+		/*
+		 *  len と受信ウィンドバッファキューの先頭ネットワークバッファの
+		 *  データ数の小さい方を移すデータ数にする。
+		 */
+		if (len > qhdr->slen)
+			blen = qhdr->slen;
+		else
+			blen = len;
+
+		memcpy(buf,
+		       GET_TCP_SDU(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq)) + qhdr->soff,
+		       (size_t)blen);
+
+		/*
+		 *  受信ウィンドバッファキューのネットワークバッファに
+		 *  データが無くなったら解放する。
+		 */
+		tcp_drop_rwbuf_cs(cep, blen);
+
+		buf  += blen;
+		rlen += blen;
+		len  -= blen;
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return rlen;
+	}
+
+/*
+ *  tcp_get_rwbuf_addr -- 受信ウィンドバッファの空きアドレスを獲得する。
+ */
+
+uint_t
+tcp_get_rwbuf_addr_cs (T_TCP_CEP *cep, void **p_buf)
+{
+	T_TCP_Q_HDR	*qhdr;
+	uint_t		len;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	if (cep->rwbufq == NULL) {
+
+		/* 受信ウィンドバッファが全て開放されているとき。*/
+		*p_buf = NULL;
+		len = 0;
+		}
+	else {
+
+		/* 受信ウィンドバッファのデータのアドレスの先頭を設定する。*/
+		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq));
+		*p_buf = GET_TCP_SDU(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq)) + qhdr->soff;
+
+		/* 受信ウィンドバッファのデータ長を計算する。*/
+		len = qhdr->slen;
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	/* 受信ウィンドバッファのデータ長を設定し、その値を返す。*/
+	cep->rcv_buf_len = len;
+	return len;
+	}
+
+/*
+ *  tcp_free_rwbufq -- 受信ウィンドバッファキューを解放する。
+ *
+ *    注意:
+ *      必要であれば、この関数を呼び出す前に、通信端点をロックし、
+ *      戻った後、解除する必要がある。
+ */
+
+void
+tcp_free_rwbufq_cs (T_TCP_CEP *cep)
+{
+	T_NET_BUF *next;
+
+	if (cep->rwbuf_count == 0 && cep->reassq == NULL) {
+		while (cep->rwbufq != NULL) {
+			next = GET_TCP_Q_HDR(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq))->next;
+
+#ifdef TCP_CFG_RWBUF_CSAVE_MAX_QUEUES
+
+			cep->rwbufq_entries --;
+
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE_MAX_QUEUES */
+
+			syscall(rel_net_buf(cep->rwbufq));
+			cep->rwbufq = next;
+			}
+
+		/* 受信ウィンドバッファの使用中サイズをリセットする。*/
+		cep->rwbuf_count = 0;
+		}
+	}
+
+/*
+ *  tcp_write_rwbuf -- 受信ウィンドバッファにデータを書き込む。
+ *
+ *    注意:
+ *	入力 input は、T_TCP_Q_HDR によりリンクされ、
+ *	並べ替えが終了していなければならない。また、
+ *	追加するデータは、受信ウィンドバッファに収まること。
+ */
+
+void
+tcp_write_rwbuf_cs (T_TCP_CEP *cep, T_NET_BUF *input, uint_t thoff)
+{
+	T_TCP_Q_HDR	*qhdr;
+	T_NET_BUF	**nextp;
+	uint_t		inlen, last;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	qhdr  = (T_TCP_Q_HDR*)GET_TCP_HDR(input, thoff);
+
+	inlen = qhdr->slen;
+
+#ifdef TCP_CFG_RWBUF_CSAVE_MAX_QUEUES
+
+	if (cep->rwbufq_entries >= TCP_CFG_RWBUF_CSAVE_MAX_QUEUES &&
+	    inlen > 0 && (qhdr->flags & TCP_FLG_FIN) == 0) {
+
+		/*
+		 *  TCP 通信端点の受信ウィンドバッファの省コピー機能の、
+		 *  受信ウィンドバッファキューの最大エントリ数を超えるときは、
+		 *  受信したセグメントを破棄する。
+		 *  ただし、SDU 長が 0 のセグメントと FIN セグメントは破棄しない。
+		 *  なお、正常に受信したセグメントも破棄するため、再送回数が増加する。
+		 */
+		syscall(rel_net_buf(input));
+
+		/* 通信端点のロックを解除する。*/
+		syscall(sig_sem(cep->semid_lock));
+		return;
+		}
+
+	cep->rwbufq_entries ++;
+
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE_MAX_QUEUES */
+
+	qhdr  = (T_TCP_Q_HDR*)GET_TCP_HDR(input, thoff);
+
+	/* 受信済みシーケンス番号を更新する。*/
+	cep->rcv_nxt += inlen;
+
+	/* 緊急データの SDU 補正を行う。*/
+	if (qhdr->urp > 0 && inlen > 0) {
+		inlen      -= qhdr->urp;
+		qhdr->slen -= qhdr->urp;
+		qhdr->urp   = 0;
+		}
+
+	last  = cep->rwbuf_count;
+
+	/* ネットワークバッファを受信ウィンドバッファキューの最後に連結する。*/
+	qhdr->next = NULL;
+	nextp = &cep->rwbufq;
+	while (*nextp)
+		nextp = &GET_TCP_Q_HDR(*nextp, GET_IP_TCP_Q_HDR_OFFSET(*nextp))->next;
+	*nextp = input;
+
+	/*
+	 *  FIN フラグが付いたセグメントは inlen == 0 になることもある。
+	 *  これは、アプリケーションに、相手からこれ以上データが送られて
+	 *  こないことを知らせるためである。
+	 */
+	if (inlen > 0) {
+		cep->rwbuf_count += inlen;
+		NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DATA_SEGS],   1);
+		NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DATA_OCTETS], inlen);
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	if (cep->rcv_nblk_tfn == TFN_TCP_RCV_BUF) {	/* ノンブロッキングコール */
+
+		int_t	len;
+
+		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq));
+		len = qhdr->slen;
+
+		/*
+		 *  FIN フラグが付いたセグメントは inlen == 0 になることもある。
+		 *  これは、アプリケーションに、相手からこれ以上データが送られて
+		 *  こないことを知らせるためである。
+		 */
+		if (len > 0 || inlen == 0) {
+
+			/* tcp_rcv_buf の割当て長を設定する。*/
+			cep->rcv_buf_len = len;
+
+			/* 受信ウィンドバッファのアドレスを返す。*/
+			*cep->rcv_p_buf = GET_TCP_SDU(cep->rwbufq,
+			                  GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq)) + qhdr->soff;
+
+			if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)len);
+#else
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
+#endif
+			else
+				syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+
+			if (len == 0) {
+
+				/*
+				 *  通信端点をロックして、
+				 *  受信ウィンドバッファキューのネットワークバッファを解放する。
+				 */
+				syscall(wai_sem(cep->semid_lock));
+				tcp_free_rwbufq_cs(cep);
+				syscall(sig_sem(cep->semid_lock));
+				}
+			}
+
+		/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+		cep->rcv_tskid = TA_NULL;
+		cep->rcv_tfn   = cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+		}
+
+	else if (cep->rcv_nblk_tfn == TFN_TCP_RCV_DAT) {	/* ノンブロッキングコール */
+		int_t	len;
+
+		/* 受信ウィンドバッファからデータを取り出す。*/
+		if ((len = tcp_read_rwbuf_cs(cep, cep->rcv_data, (uint_t)cep->rcv_len)) > 0) {
+			/* 相手にウィンドウサイズが変わったことを知らせるため出力をポストする。*/
+			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+			}
+
+		/*
+		 *  FIN フラグが付いたセグメントは inlen == 0 になることもある。
+		 *  これは、アプリケーションに、相手からこれ以上データが送られて
+		 *  こないことを知らせるためである。
+		 */
+		if (len > 0 || inlen == 0) {
+
+			if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)len);
+#else
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
+#endif
+			else
+				syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+			}
+
+		/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+		cep->rcv_tskid = TA_NULL;
+		cep->rcv_tfn   = cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+		}
+	else {
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		if (inlen == 0 && cep->rwbuf_count == 0) {
+			/*
+			 *  受信ウィンドバッファ内のデータ数が 0 で、
+			 *  相手から FIN フラグが付いたセグメントを受信したときは、
+			 *  通信端点をロックして、
+			 *  受信ウィンドバッファキューのネットワークバッファを解放する。
+			 */
+			syscall(wai_sem(cep->semid_lock));
+			tcp_free_rwbufq_cs(cep);
+			syscall(sig_sem(cep->semid_lock));
+			}
+
+		/*
+		 *  受信ウィンドバッファにデータが入るか、 inlen == 0 の時、入力タスクを起床する。
+		 *  FIN フラグが付いたセグメントは inlen == 0 になることもある。
+		 *  これは、アプリケーションに、相手からこれ以上データが送られて
+		 *  こないことを知らせるためである。
+		 */
+		if ((last == 0 && cep->rwbuf_count > 0) || inlen == 0) {
+			syscall(set_flg(cep->rcv_flgid, TCP_CEP_EVT_RWBUF_READY));
+			}
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	}
+
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE */
+
+#endif	/* of #ifdef SUPPORT_TCP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_subr_ncs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_subr_ncs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_subr_ncs.c	(revision 398)
@@ -0,0 +1,716 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp_subr.c	8.2 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/netinet/tcp_subr.c,v 1.49.2.4 1999/08/29 16:29:55 peter Exp $
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+
+#ifdef SUPPORT_TCP
+
+#ifndef TCP_CFG_SWBUF_CSAVE_ONLY
+
+/*
+ *  TCP 通信端点の送信ウィンドバッファの省コピー機能が無効
+ */
+
+/*
+ *  tcp_read_swbuf -- 送信ウィンドバッファからデータを読み出す。
+ */
+
+void
+tcp_read_swbuf_ncs (T_TCP_CEP *cep, T_NET_BUF *output, uint_t len, uint_t doff)
+{
+	uint8_t	*wptr, *rptr;
+	uint_t	sdu_size   = GET_IP_SDU_SIZE(output);
+	uint_t	hdr_offset = IF_IP_TCP_HDR_OFFSET(output);
+
+	/* SDU の大きさをチェックする。*/
+	if (sdu_size < GET_TCP_HDR_SIZE(output, hdr_offset) + len) {
+		syslog(LOG_INFO, "[TCP] shrink SUD len: %d -> %d",
+		       (uint16_t)len, (uint16_t)(sdu_size - GET_TCP_HDR_SIZE(output, hdr_offset)));
+		len = sdu_size - GET_TCP_HDR_SIZE(output, hdr_offset);
+		}
+
+	wptr = GET_TCP_SDU(output, hdr_offset);
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	rptr = cep->sbuf_rptr + doff;
+	if (rptr - (uint8_t*)cep->sbuf > cep->sbufsz) {
+
+		/* 転送開始が送信ウィンドバッファの終わりを超えるときの処理　*/
+		rptr = (uint8_t*)cep->sbuf_rptr - (cep->sbufsz - doff);
+		}
+	else if (len + (rptr - (uint8_t*)cep->sbuf) > cep->sbufsz) {
+		uint_t sub;
+
+		/* 転送範囲がラウンドするときの処理 */
+		sub = (uint_t)(cep->sbufsz - (rptr - (uint8_t*)cep->sbuf));
+		memcpy((void*)wptr, rptr, (size_t)sub);
+		len  -= sub;
+		wptr += sub;
+		rptr  = (uint8_t*)cep->sbuf;
+		}
+	memcpy((void*)wptr, rptr, (size_t)len);
+
+	NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_DATA_SEGS],   1);
+	NET_COUNT_TCP(net_count_tcp[NC_TCP_SEND_DATA_OCTETS], len);
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+	}
+
+/*
+ *  tcp_drop_swbuf -- 送信ウィンドバッファから指定されたオクテット分削除する。
+ */
+
+void
+tcp_drop_swbuf_ncs (T_TCP_CEP *cep, uint_t len)
+{
+	uint_t	last;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	last = cep->swbuf_count;
+
+	if (cep->sbuf_rptr + len > (uint8_t*)cep->sbuf + cep->sbufsz)
+		/* ラウンドするときの計算 */
+		cep->sbuf_rptr -= cep->sbufsz - len;
+	else
+		cep->sbuf_rptr += len;
+	cep->swbuf_count -= (uint16_t)len;
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	if (cep->snd_nblk_tfn == TFN_TCP_GET_BUF) {	/* ノンブロッキングコール */
+
+		/* 通信端点をロックする。*/
+		syscall(wai_sem(cep->semid_lock));
+
+		/* 送信データ長を計算する。*/
+		if (cep->sbufsz - cep->swbuf_count > cep->sbufsz - (cep->sbuf_wptr - (uint8_t*)cep->sbuf))
+			/* 書込みポインタがラウンドするときは、書込みポインタから送信ウィンドバッファの終わりまで */
+			len = (uint_t)(cep->sbufsz - (cep->sbuf_wptr - (uint8_t*)cep->sbuf));
+		else
+			len = cep->sbufsz - cep->swbuf_count;
+
+		/* 通信端点のロックを解除する。*/
+		syscall(sig_sem(cep->semid_lock));
+
+		if (len > 0) {
+
+			/* tcp_get_buf の割当て長を設定する。*/
+			cep->get_buf_len = len;
+
+			/* 送信ウィンドバッファのアドレスを返す。*/
+			*cep->snd_p_buf = cep->sbuf_wptr;
+
+			if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)(uint32_t)len);
+#else
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&len);
+#endif
+			else
+				syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+
+			/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+			cep->snd_tskid = TA_NULL;
+			cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+			}
+		}
+
+#ifdef TCP_CFG_EXTENTIONS
+
+	else if (cep->snd_nblk_tfn == TFN_TCP_SND_DAT ||
+	         cep->snd_nblk_tfn == TFN_TCP_SND_OOB) {	/* ノンブロッキングコール */
+
+#else	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+	else if (cep->snd_nblk_tfn == TFN_TCP_SND_DAT) {	/* ノンブロッキングコール */
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+		ER_UINT	error;
+
+	 	/* 送信ウィンドバッファにデータを書き込む。*/
+		error = TCP_WRITE_SWBUF(cep, cep->snd_data, (uint_t)cep->snd_len);
+
+#ifdef TCP_CFG_EXTENTIONS
+
+		/* 送信緊急ポインタを設定する。*/
+	        if (cep->snd_nblk_tfn == TFN_TCP_SND_OOB)
+			cep->snd_up = cep->snd_una + error;
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+		if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)error);
+#else
+			(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&error);
+#endif
+		else
+			syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+
+		/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+		cep->snd_tskid = TA_NULL;
+		cep->snd_tfn   = cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+		}
+	else {
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		/* 送信ウィンドバッファに空きが出来たら出力タスクを起床する。*/
+		if (last == cep->sbufsz && cep->swbuf_count < cep->sbufsz)
+			syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY));
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	if (cep->swbuf_count > 0) {
+		/* 送信ウィンドバッファにデータがあれば出力をポストする。*/
+		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		}
+	}
+
+/*
+ *  tcp_write_swbuf -- 送信ウィンドバッファにデータを書き込む。
+ */
+
+ER_UINT
+tcp_write_swbuf_ncs (T_TCP_CEP *cep, void *data, uint_t len)
+{
+	uint_t	offset;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/* len と送信ウィンドバッファの空きの小さい方を移すデータ数にする。*/
+	if (len > (cep->sbufsz - cep->swbuf_count))
+		len = cep->sbufsz - cep->swbuf_count;
+
+	/* 書き込みポインタがラウンドするときの処理 */
+	if (len > cep->sbufsz - (cep->sbuf_wptr - (uint8_t*)cep->sbuf)) {
+		offset = (uint_t)(cep->sbufsz - (cep->sbuf_wptr -(uint8_t*)cep->sbuf));
+		memcpy(cep->sbuf_wptr, data, (size_t)offset);
+		cep->sbuf_wptr  = (uint8_t*)cep->sbuf;
+		cep->swbuf_count += offset;
+		}
+	else
+		offset = 0;
+
+	memcpy(cep->sbuf_wptr, (void*)((uint8_t*)data + offset), (size_t)(len - offset));
+	cep->sbuf_wptr  += len - offset;
+	cep->swbuf_count += len - offset;
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return (ER_UINT)len;
+	}
+
+/*
+ *  tcp_wait_swbuf -- 送信ウィンドバッファが空くのを待つ。
+ */
+
+ER
+tcp_wait_swbuf_ncs (T_TCP_CEP *cep, TMO tmout)
+{
+	ER	error;
+	FLGPTN	flag;
+
+	while (cep->swbuf_count >= cep->sbufsz) {
+		/*
+		 *  送信ウィンドバッファの空きがなければ、出力をポストして、
+		 *  送信ウィンドバッファが空くまで待つ。
+		 */
+		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+
+		if ((error = twai_flg(cep->snd_flgid, TCP_CEP_EVT_SWBUF_READY, TWF_ORW, &flag, tmout)) != E_OK) {
+			return error;
+			}
+		syscall(clr_flg(cep->snd_flgid, (FLGPTN)(~TCP_CEP_EVT_SWBUF_READY)));
+
+		/*
+		 *  送信できるか、CEP の FSM 状態を見る。
+		 *  送信ウィンドバッファが空くまで待つ間に、送信不能になった場合は、
+		 *  コネクションが切断されたことを意味している。
+		 */
+		if (!TCP_FSM_CAN_SEND_MORE(cep->fsm_state)) {
+			return E_CLS;
+			}
+		}
+
+	return E_OK;
+	}
+/*
+ *  tcp_get_swbuf_addr -- 送信ウィンドバッファの空きアドレスを獲得する。
+ */
+
+ER_UINT
+tcp_get_swbuf_addr_ncs (T_TCP_CEP *cep, void **p_buf)
+{
+	uint_t	len;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/* 送信ウィンドバッファの空きアドレスの先頭を設定する。*/
+	*p_buf = cep->sbuf_wptr;
+
+	/* 送信ウィンドバッファの空きサイズを計算する。*/
+	if (cep->sbufsz - cep->swbuf_count > cep->sbufsz - (cep->sbuf_wptr - (uint8_t*)cep->sbuf))
+		/* 書込みポインタがラウンドするときは、書込みポインタから送信ウィンドバッファの終わりまで */
+		len = (uint_t)(cep->sbufsz - (cep->sbuf_wptr - (uint8_t*)cep->sbuf));
+	else
+		len = cep->sbufsz - cep->swbuf_count;
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	/* 送信ウィンドバッファの空きデータ長を設定し、その値を返す。*/
+	cep->get_buf_len = len;
+	return (ER_UINT)len;
+	}
+
+/*
+ *  tcp_send_swbuf -- 送信ウィンドバッファのデータを送信可能にする。
+ */
+
+void
+tcp_send_swbuf_ncs (T_TCP_CEP *cep, uint_t len)
+{
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	cep->sbuf_wptr  += len;
+	cep->swbuf_count += len;
+
+	/* 書込みポインタがラウンドするときの処理 */
+	if (cep->sbuf_wptr >= (uint8_t*)cep->sbuf + cep->sbufsz)
+		cep->sbuf_wptr  = (uint8_t*)cep->sbuf;
+
+	/* tcp_get_buf の割当て長をリセットする。*/
+	cep->get_buf_len = 0;
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	/* 送信ウィンドバッファがフルのときは強制的に送信する。*/
+	if (cep->swbuf_count >= cep->sbufsz)
+		cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR;
+	}
+
+/*
+ *  tcp_is_swbuf_full -- 送信ウィンドバッファが満杯かチェックする。
+ */
+
+bool_t
+tcp_is_swbuf_full_ncs (T_TCP_CEP *cep)
+{
+	return cep->swbuf_count >= cep->sbufsz;
+	}
+
+#endif	/* of #ifndef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+#ifndef TCP_CFG_RWBUF_CSAVE_ONLY
+
+/*
+ *  TCP 通信端点の受信ウィンドバッファの省コピー機能が無効
+ */
+
+/*
+ *  tcp_drop_rwbuf -- 受信ウィンドバッファから指定されたオクテット分削除する。
+ */
+
+void
+tcp_drop_rwbuf_ncs (T_TCP_CEP *cep, uint_t len)
+{
+	cep->rwbuf_count -= len;
+	cep->rbuf_rptr  += len;
+
+	/* 読み出しポインタがラウンドするときの処理 */
+	if (cep->rbuf_rptr >= (uint8_t*)cep->rbuf + cep->rbufsz)
+		cep->rbuf_rptr  = (uint8_t*)cep->rbuf;
+	}
+
+/*
+ *  tcp_read_rwbuf -- 受信ウィンドバッファから指定されたオクテット分読み出す。
+ */
+
+uint_t
+tcp_read_rwbuf_ncs (T_TCP_CEP *cep, void *data, uint_t len)
+{
+	uint_t	offset;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/* len と受信ウィンドバッファのデータ数の小さい方を取り出すデータ数にする。*/
+	if (len > cep->rwbuf_count)
+		len = cep->rwbuf_count;
+
+	/* 読み出しポインタがラウンドするときの処理 */
+	if (len > cep->rbufsz - (cep->rbuf_rptr - (uint8_t*)cep->rbuf)) {
+		offset = (uint_t)(cep->rbufsz - (cep->rbuf_rptr -(uint8_t*)cep->rbuf));
+		memcpy(data, cep->rbuf_rptr, (size_t)offset);
+		cep->rwbuf_count -= offset;
+		cep->rbuf_rptr   = (uint8_t*)cep->rbuf;
+		}
+	else
+		offset = 0;
+
+	memcpy((void*)((uint8_t*)data + offset), cep->rbuf_rptr, (size_t)(len - offset));
+	cep->rwbuf_count -= len - offset;
+	cep->rbuf_rptr  += len - offset;
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return len;
+	}
+
+/*
+ *  tcp_get_rwbuf_addr -- 受信ウィンドバッファの空きアドレスを獲得する。
+ */
+
+uint_t
+tcp_get_rwbuf_addr_ncs (T_TCP_CEP *cep, void **p_buf)
+{
+	uint_t	len;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/* 受信ウィンドバッファのデータ長を計算する。*/
+	if (cep->rwbuf_count > cep->rbufsz - (cep->rbuf_rptr - (uint8_t*)cep->rbuf))
+		/* ポインタがラウンドするときは受信ウィンドバッファの終わりまで */
+		len = (uint_t)(cep->rbufsz - (cep->rbuf_rptr - (uint8_t*)cep->rbuf));
+	else
+		len = cep->rwbuf_count;
+
+	/* 受信ウィンドバッファのデータのアドレスの先頭を設定する。*/
+	*p_buf = cep->rbuf_rptr;
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	/* 受信ウィンドバッファのデータ長を設定し、その値を返す。*/
+	cep->rcv_buf_len = len;
+	return len;
+	}
+
+/*
+ *  tcp_write_rwbuf -- 受信ウィンドバッファにデータを書き込む。
+ *
+ *    注意:
+ *	入力 input は、T_TCP_Q_HDR によりリンクされ、
+ *	並べ替えが終了していなければならない。また、
+ *	追加するデータは、受信ウィンドバッファに収まること。
+ */
+
+void
+tcp_write_rwbuf_ncs (T_TCP_CEP *cep, T_NET_BUF *input, uint_t thoff)
+{
+	T_TCP_Q_HDR	*qhdr;
+	uint_t		offset, inlen, last;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	qhdr  = (T_TCP_Q_HDR*)GET_TCP_HDR(input, thoff);
+
+	/* 受信済みシーケンス番号を更新する。*/
+	cep->rcv_nxt += qhdr->slen;
+
+	last  = cep->rwbuf_count;
+	inlen = qhdr->slen;
+
+	/* 緊急データの SDU 補正を行う。*/
+	if (qhdr->urp > 0 && inlen > 0) {
+		inlen      -= qhdr->urp;
+		qhdr->slen -= qhdr->urp;
+		qhdr->urp   = 0;
+		}
+
+	/*
+	 *  FIN フラグが付いたセグメントは inlen == 0 になることもある。
+	 *  これは、アプリケーションに、相手からこれ以上データが送られて
+	 *  こないことを知らせるためである。
+	 */
+	if (inlen > 0) {
+
+		/* 書き込みポインタがラウンドするときの処理 */
+		if (inlen > cep->rbufsz - (cep->rbuf_wptr - (uint8_t*)cep->rbuf)) {
+			offset = (uint_t)(cep->rbufsz - (cep->rbuf_wptr - (uint8_t*)cep->rbuf));
+			memcpy(cep->rbuf_wptr, (void*)(GET_TCP_SDU(input, thoff) + qhdr->soff), (size_t)offset);
+			cep->rbuf_wptr   = (uint8_t*)cep->rbuf;
+			cep->rwbuf_count += offset;
+			inlen           -= offset;
+			}
+		else
+			offset	= 0;
+
+		memcpy(cep->rbuf_wptr, (void*)(GET_TCP_SDU(input, thoff) + qhdr->soff + offset), (size_t)inlen);
+		cep->rbuf_wptr  += inlen;
+		cep->rwbuf_count += inlen;
+
+		NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DATA_SEGS],   1);
+		NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_DATA_OCTETS], inlen);
+		}
+
+	syscall(rel_net_buf(input));
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	if (cep->rcv_nblk_tfn == TFN_TCP_RCV_BUF) {	/* ノンブロッキングコール */
+
+		int_t	len;
+
+		/* 受信ウィンドバッファの空きデータ長を計算する。*/
+		if (cep->rwbuf_count > cep->rbufsz - (cep->rbuf_rptr - (uint8_t*)cep->rbuf)) {
+			/* ポインタがラウンドするときは受信ウィンドバッファの終わりまで */
+			len = (uint_t)(cep->rbufsz - (cep->rbuf_rptr - (uint8_t*)cep->rbuf));
+			}
+		else
+			len = cep->rwbuf_count;
+
+		/* 通信端点のロックを解除する。*/
+		syscall(sig_sem(cep->semid_lock));
+
+		/*
+		 *  FIN フラグが付いたセグメントは inlen == 0 になることもある。
+		 *  これは、アプリケーションに、相手からこれ以上データが送られて
+		 *  こないことを知らせるためである。
+		 */
+		if (len > 0 || inlen == 0) {
+
+			/* tcp_rcv_buf の割当て長を設定する。*/
+			cep->rcv_buf_len = len;
+
+			/* 受信ウィンドバッファのアドレスを返す。*/
+			*cep->rcv_p_buf = cep->rbuf_rptr;
+
+
+			if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)(uint32_t)len);
+#else
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
+#endif
+			else
+				syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+
+			if (len == 0) {
+
+				/*
+				 *  通信端点をロックして、
+				 *  受信ウィンドバッファキューのネットワークバッファを解放する。
+				 */
+				syscall(wai_sem(cep->semid_lock));
+				TCP_FREE_RWBUFQ(cep);
+				syscall(sig_sem(cep->semid_lock));
+				}
+			}
+
+		/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+		cep->rcv_tskid = TA_NULL;
+		cep->rcv_tfn   = cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+		}
+
+	else if (cep->rcv_nblk_tfn == TFN_TCP_RCV_DAT) {	/* ノンブロッキングコール */
+		ER_UINT	len;
+
+		/* 通信端点のロックを解除する。*/
+		syscall(sig_sem(cep->semid_lock));
+
+		/* 受信ウィンドバッファからデータを取り出す。*/
+		if ((len = TCP_READ_RWBUF(cep, cep->rcv_data, (uint_t)cep->rcv_len)) > 0) {
+			/* 相手にウィンドウサイズが変わったことを知らせるため出力をポストする。*/
+			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+			}
+
+		/*
+		 *  FIN フラグが付いたセグメントは inlen == 0 になることもある。
+		 *  これは、アプリケーションに、相手からこれ以上データが送られて
+		 *  こないことを知らせるためである。
+		 */
+		if (len > 0 || inlen == 0) {
+
+			if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)(uint32_t)len);
+#else
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
+#endif
+			else
+				syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
+			}
+
+		/* 記憶されているタスク ID と API 機能コードをクリアーする。*/
+		cep->rcv_tskid = TA_NULL;
+		cep->rcv_tfn   = cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+
+		}
+	else {
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		/* 通信端点のロックを解除する。*/
+		syscall(sig_sem(cep->semid_lock));
+
+		if (inlen == 0 && cep->rwbuf_count == 0) {
+			/*
+			 *  受信ウィンドバッファ内のデータ数が 0 で、
+			 *  相手から FIN フラグが付いたセグメントを受信したときは、
+			 *  通信端点をロックして、
+			 *  受信ウィンドバッファキューのネットワークバッファを解放する。
+			 */
+			syscall(wai_sem(cep->semid_lock));
+			TCP_FREE_RWBUFQ(cep);
+			syscall(sig_sem(cep->semid_lock));
+			}
+
+		/*
+		 *  受信ウィンドバッファにデータが入るか、 inlen == 0 の時、入力タスクを起床する。
+		 *  FIN フラグが付いたセグメントは inlen == 0 になることもある。
+		 *  これは、アプリケーションに、相手からこれ以上データが送られて
+		 *  こないことを知らせるためである。
+		 */
+		if ((last == 0 && cep->rwbuf_count > 0) || inlen == 0)
+			syscall(set_flg(cep->rcv_flgid, TCP_CEP_EVT_RWBUF_READY));
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	}
+
+#endif	/* of #ifndef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+#endif	/* of #ifdef SUPPORT_TCP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_timer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_timer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_timer.c	(revision 398)
@@ -0,0 +1,511 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp_timer.c	8.2 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/netinet/tcp_timer.c,v 1.28.2.1 1999/08/29 16:29:56 peter Exp $
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+
+#ifdef SUPPORT_TCP
+
+/*
+ *  局所関数
+ */
+
+static T_TCP_CEP *tcp_timers (T_TCP_CEP *cep, int_t tix);
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+static void tcp_tw_timo (void);
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+/*
+ *  バックオフ時間
+ *
+ *  再送を行うたびに、タイムアウトの時間を延長する。
+ */
+
+const static uint8_t tcp_back_off[] = {
+	UINT_C(1), 	UINT_C(2), 	UINT_C(4), 	UINT_C(8),
+	UINT_C(16), 	UINT_C(32), 	UINT_C(64), 	UINT_C(64),
+	UINT_C(64), 	UINT_C(64), 	UINT_C(64), 	UINT_C(64), 
+	UINT_C(64)
+	};
+
+#define TCP_TOTAL_BACK_OFF	511	/* バックオフ時間の合計 */
+
+/*
+ *  tcp_timers -- タイムアウト処理
+ */
+
+static T_TCP_CEP *
+tcp_timers (T_TCP_CEP *cep, int_t tix)
+{
+	uint16_t	win;
+
+
+	switch (tix) {
+
+	/*
+	 *  再送タイマ
+	 */
+	case TCP_TIM_REXMT:
+	
+		/*
+		 *  最大再送回数 (TCP_MAX_REXMT_SHIFT、標準 12 回) になったときは、
+		 *  コネクションを切断する。
+		 */
+		if (++ cep->rxtshift > TCP_MAX_REXMT_SHIFT) {
+			cep->rxtshift  = TCP_MAX_REXMT_SHIFT;
+			cep->net_error = EV_REXMTMO;
+			cep = tcp_drop(cep, E_CLS);
+			break;
+			}
+
+		/*
+		 *  再送タイムアウトを計算する。
+		 */
+		cep->rxtcur = tcp_range_set((T_TCP_TIME)(tcp_rexmt_val(cep) * tcp_back_off[cep->rxtshift]),
+		                            (T_TCP_TIME)TCP_TVAL_MIN, 
+		                            (T_TCP_TIME)TCP_TVAL_MAX_REXMT);
+		cep->timer[TCP_TIM_REXMT] = cep->rxtcur;
+
+		/*
+		 *  srtt:   平滑化された RTT
+		 *  rttvar: 平滑化された分散
+		 *
+		 *  再送回数が最大再送回数の 1/4 になったときは、
+		 *  平滑化された分散 (rttvar) に srtt を加算し、
+		 *  平滑化された RTT を 0 にする。
+		 *  
+		 */
+		if (cep->rxtshift > TCP_MAX_REXMT_SHIFT / 4) {
+			cep->rttvar += (cep->srtt >> TCP_SRTT_SHIFT);
+			cep->srtt    = 0;
+			}
+
+		/*
+		 *  snd_nxt: 次に送信する SEQ、この時点では、前回送信した SEQ
+		 *  snd_una: 未確認の最小送信 SEQ	 または、確認された最大送信 SEQ
+		 *
+		 *  前回送信した SEQ (snd_nxt) を 
+		 *  確認された最大送信 SEQ (snd_una) まで戻す。
+		 */
+		cep->snd_nxt = cep->snd_una;
+		cep->flags  |= TCP_CEP_FLG_ACK_NOW;
+
+		/*
+		 *  rtt: 往復時間の計測を中止する。
+		 */
+		cep->rtt     = 0;
+
+		/*
+		 *  送信ウインドの設定
+		 *
+		 *  snd_wnd:  相手の受信可能ウィンドサイズ
+		 *  snd_cwnd: 輻輳ウィンドサイズ
+		 *  maxseg  : 相手の最大受信セグメントサイズ
+		 *
+		 *  相手の受信可能ウィンドサイズ (snd_wnd) か、
+		 *  輻輳ウィンドサイズ (snd_cwnd) の
+		 *  どちらか小さいサイズの 1/2 を、更に
+		 *  相手の最大受信セグメントサイズ (maxseg) で割った値。
+		 *  ただし、2 以上
+		 */
+		if (cep->snd_wnd < cep->snd_cwnd)
+			win = cep->snd_wnd / 2 / cep->maxseg;
+		else
+			win = cep->snd_cwnd / 2 / cep->maxseg;
+
+		if (win < 2)
+			win = 2;
+
+		/*
+		 *  輻輳ウィンドサイズ (snd_cwnd) は
+		 *  相手の受信可能ウィンドサイズ (snd_wnd) に、
+		 *  輻輳ウィンドサイズのしきい値 (snd_ssthresh) は
+		 *  相手の受信可能ウィンドサイズ (snd_wnd) の win 倍に
+		 *  設定する。
+		 */
+		cep->snd_cwnd     = cep->maxseg;
+		cep->snd_ssthresh = win * cep->maxseg;
+		cep->dupacks      = 0;
+
+		/* 出力をポストする。*/
+		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		break;
+
+	/*
+	 *  持続タイマ	
+	 */
+	case TCP_TIM_PERSIST:
+
+		/*
+		 *  最大再送回数 (TCP_MAX_REXMT_SHIFT、標準 12 回) を超えていて、
+		 *  アイドル時間が、保留タイマの標準値 (TCP_TVAL_KEEP_IDLE、
+		 *  標準 2 * 60 * 60 秒) 以上か、
+		 *  再送タイムアウト値 * バックオフ時間の合計以上なら
+		 *  コネクションを切断する。
+		 */
+		if (cep->rxtshift > TCP_MAX_REXMT_SHIFT &&
+		    (cep->idle >= TCP_TVAL_KEEP_IDLE ||
+		     cep->idle >= tcp_rexmt_val(cep) * TCP_TOTAL_BACK_OFF)) {
+			cep->net_error = EV_REXMTMO;
+			cep = tcp_drop(cep, E_CLS);
+			break;
+			}
+
+		/* 持続タイマを再設定し、出力をポストする。*/
+		tcp_set_persist_timer(cep);
+
+		cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR | TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		break;
+
+	/*
+	 *  保留 (keep alive) タイマ
+	 */
+	case TCP_TIM_KEEP:
+
+		/*
+		 *  コネクションが開設されるまでにタイムアウトしたら
+		 *  コネクションの開設を中止する。
+		 */
+		if (cep->fsm_state < TCP_FSM_ESTABLISHED) {
+			cep->net_error = EV_REXMTMO;
+			cep = tcp_drop(cep, E_CLS);
+			break;
+			}
+
+#ifdef TCP_CFG_ALWAYS_KEEP
+
+		else if (cep->fsm_state < TCP_FSM_CLOSING) {
+			if (cep->idle >= TCP_TVAL_KEEP_IDLE + 
+			                 TCP_TVAL_KEEP_COUNT * TCP_TVAL_KEEP_INTERVAL) {
+				cep->net_error = EV_REXMTMO;
+				cep = tcp_drop(cep, E_CLS);
+				break;
+				}
+			else
+				tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una - 1,
+				                       cep->rbufsz - cep->rwbuf_count, 0);
+			cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_INTERVAL;
+			}
+		else
+			cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_IDLE;
+
+#else	/* of #ifdef TCP_CFG_ALWAYS_KEEP */
+
+		cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_IDLE;
+
+#endif	/* of #ifdef TCP_CFG_ALWAYS_KEEP */
+
+		break;
+
+	/*
+	 *  2MSL タイマ		
+	 */
+	case TCP_TIM_2MSL:
+
+		if (cep->fsm_state != TCP_FSM_TIME_WAIT &&
+		    cep->idle  <= TCP_TVAL_KEEP_COUNT * TCP_TVAL_KEEP_INTERVAL)
+			cep->timer[TCP_TIM_2MSL] = TCP_TVAL_KEEP_INTERVAL;
+		else
+			cep = tcp_close(cep);
+		break;
+		}
+
+	return cep;
+	}
+
+/*
+ *  tcp_cancel_timers -- 全てのタイマをキャンセルする。
+ */
+
+void
+tcp_cancel_timers (T_TCP_CEP *cep)
+{
+	int_t ix;
+
+	for (ix = NUM_TCP_TIMERS; ix -- > 0; )
+		cep->timer[ix] = 0;
+	}
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+/*
+ *  tcp_tw_timo -- Time Wait 用 TCP 通信端点のタイムアウト処理
+ */
+
+void
+tcp_tw_timo (void)
+{
+	T_TCP_CEP	*cep, *lcep;
+	T_TCP_TWCEP*	twcep;
+	T_TCP_TIME	longer;
+	int_t		frees, waits;
+
+	/*
+	 *  Time Wait 用 TCP 通信端点でタイムアウトのエントリを探索し、
+	 *  探索したエントリを空きにする。
+	 */
+	frees = 0;
+	for (twcep = &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep -- != tcp_twcep; )
+		if (twcep->fsm_state == TCP_FSM_TIME_WAIT && -- twcep->timer_2msl == 0) {
+			twcep->fsm_state = TCP_FSM_CLOSED;
+			frees ++;
+			}
+
+	/*
+	 *  Time Wait 用 TCP 通信端点の空きエントリが発生したら
+	 *  標準 TCP 通信端点で Time Wait 中の TCP 通信端点を探索し、
+	 *  必要な情報を Time Wait 用 TCP 通信端点に移して、
+	 *  標準の TCP 通信端点を開放する。
+	 */
+	if (frees > 0) {
+		waits = 0;
+		for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; )
+			if (cep->fsm_state == TCP_FSM_TIME_WAIT)
+				waits ++;
+		if (waits > frees)
+			waits = frees;
+
+		/*
+		 *  もっとも長い間 Time Wait している TCP 通信端点を開放する。
+		 */
+		while (waits > 0) {
+			longer = TCP_TVAL_MSL * 2;
+			lcep   = NULL;
+			for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; )
+				if (cep->fsm_state == TCP_FSM_TIME_WAIT && cep->timer[TCP_TIM_2MSL] < longer) {
+					longer = cep->timer[TCP_TIM_2MSL];
+					lcep   = cep;
+					}
+			if (lcep != NULL) {
+				tcp_move_twcep(lcep);
+				waits --;
+				}
+			else
+				break;
+			}
+		}
+	}
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+/*
+ *  tcp_slow_timo -- 500 [ms] 毎に呼出される TCP タイムアウト関数
+ */
+
+void
+tcp_slow_timo (void *ignore)
+{
+	T_TCP_CEP	*cep;
+	int_t		cix, tix;
+
+	for (cix = tmax_tcp_cepid; cix -- > 0; ) {
+		cep = &tcp_cep[cix];
+		if (!(cep->fsm_state == TCP_FSM_CLOSED || cep->fsm_state == TCP_FSM_LISTEN)) {
+			for (tix = NUM_TCP_TIMERS; cep != NULL && tix -- > 0; ) {
+				if (cep->timer[tix] != 0 && -- cep->timer[tix] == 0) {
+					cep = tcp_timers(cep, tix);
+					}
+				}
+			if (cep != NULL) {
+				cep->idle ++;
+				if (cep->rtt) {
+					cep->rtt ++;
+					}
+				}
+			}
+		}
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+	tcp_tw_timo();
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+	if (tcp_iss != 0) {
+		tcp_iss += TCP_ISS_INCR() / TCP_SLOW_HZ;
+		}
+
+	timeout(tcp_slow_timo, NULL, TCP_SLOW_TMO);
+	}
+
+#ifdef TCP_CFG_DELAY_ACK
+
+/*
+ *  tcp_fast_timo -- 200 [ms] 毎に呼出される TCP タイムアウト関数
+ */
+
+void
+tcp_fast_timo (void *ignore)
+{
+	T_TCP_CEP	*cep;
+	int_t		cix;
+
+	for (cix = tmax_tcp_cepid; cix -- > 0; ) {
+		cep = &tcp_cep[cix];
+		if (cep->flags & TCP_CEP_FLG_DEL_ACK) {
+			cep->flags &= ~TCP_CEP_FLG_DEL_ACK;
+			cep->flags |=  TCP_CEP_FLG_ACK_NOW | TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+			}
+		}
+
+	timeout(tcp_fast_timo, NULL, TCP_FAST_TMO);
+	}
+
+#endif/* of #ifdef TCP_CFG_DELAY_ACK */
+
+/*
+ *  tcp_range_set -- 時間を指定した範囲に設定する。
+ */
+
+T_TCP_TIME
+tcp_range_set (T_TCP_TIME value, T_TCP_TIME tvmin, T_TCP_TIME tvmax)
+{
+	if ((uint32_t)value < (uint32_t)tvmin)
+		return tvmin;
+	else if ((uint32_t)value > (uint32_t)tvmax)
+		return tvmax;
+	else
+		return value;
+	}
+
+/*
+ *  tcp_set_persist_timer -- 持続タイマの設定
+ */
+
+void
+tcp_set_persist_timer (T_TCP_CEP *cep)
+{
+	T_TCP_TIME time;
+
+	/*
+	 *  srtt:   平滑化された RTT
+	 *  rttvar: 平滑化された分散
+	 */
+	time = ((cep->srtt >> 2) + cep->rttvar) >> 1;
+
+	/*
+	 *  再送タイマも設定されていれば回復不能エラー
+	 */
+	if (cep->timer[TCP_TIM_REXMT])
+		/* %%% panic("tcp_output REXMT"); %%% */;
+
+	/*
+	 *  持続タイマを設定する。
+	 */
+	cep->timer[TCP_TIM_PERSIST] = tcp_range_set((T_TCP_TIME)(time * tcp_back_off[cep->rxtshift]),
+	                                            (T_TCP_TIME)TCP_TVAL_MIN_PERSIST,
+	                                            (T_TCP_TIME)TCP_TVAL_MAX_PERSIST);
+
+	/*
+	 *  再送回数を更新する。
+	 */
+	if (cep->rxtshift < TCP_MAX_REXMT_SHIFT)
+		cep->rxtshift ++;
+	}
+
+#endif	/* of #ifdef SUPPORT_TCP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_timer.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_timer.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_timer.h	(revision 398)
@@ -0,0 +1,146 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp_timer.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/tcp_timer.h,v 1.13.2.1 1999/08/29 16:29:56 peter Exp $
+ */
+ 
+#ifndef _TCP_TIMER_H_
+#define _TCP_TIMER_H_
+
+/* TCP タイマ変数 */
+
+//#define NUM_TCP_TIMERS		4	/* TCP のタイマ数	*/
+
+#define TCP_TIM_REXMT		0	/* 再送タイマ		*/
+#define TCP_TIM_PERSIST		1	/* 持続タイマ		*/
+#define TCP_TIM_KEEP		2	/* 保留 (keep alive) タイマ*/
+#define TCP_TIM_2MSL		3	/* 2MSL タイマ		*/
+
+/* MSL: Maximum Segment Lifetime, 最大セグメント生存時間 		*/
+
+/*
+ *  TCP/IP のタイマの定義
+ */
+
+#define TCP_SLOW_TMO		(ULONG_C(500000)/NET_TIMER_CYCLE)	/* 500,000 [us]	*/
+#define TCP_FAST_TMO		(ULONG_C(200000)/NET_TIMER_CYCLE)	/* 200,000 [us]	*/
+
+#define TCP_SLOW_HZ		(ULONG_C(1000000)/TCP_SLOW_TMO/NET_TIMER_CYCLE)	/* Hz	*/
+
+/* TCP タイマ値 */
+
+#define TCP_TVAL_MSL		(TCP_SLOW_HZ * 30)
+					/* 最大セグメント生存時間	*/
+
+#define TCP_TVAL_SRTT_BASE	0	/* 滑らかな往復時間の基準値*/
+
+#define TCP_TVAL_RTO_BASE	(TCP_SLOW_HZ * 3)
+		/* 情報が得られない場合の再送タイムアウトの基準値	*/
+
+#define TCP_TVAL_MIN_PERSIST	(TCP_SLOW_HZ * 5)
+				/* 持続タイムアウトの最小値	*/
+#define TCP_TVAL_MAX_PERSIST	(TCP_SLOW_HZ * 60)
+				/* 持続タイムアウトの最大値	*/
+
+#define TCP_TVAL_KEEP_INIT	(TCP_SLOW_HZ * 75)
+					/* 保留タイマの初期値	*/
+#define TCP_TVAL_KEEP_IDLE	(TCP_SLOW_HZ * 2 * 60 * 60)
+					/* 保留タイマ起動までの標準値*/
+#define TCP_TVAL_KEEP_INTERVAL	(TCP_SLOW_HZ * 75)
+					/* 保留タイマインターバルの標準値*/
+#define TCP_TVAL_KEEP_COUNT	8	/* 保留タイムアウトの最大値*/
+
+#define TCP_TVAL_MIN		(TCP_SLOW_HZ * 3)
+					/* 時間の最小単位	*/
+#define TCP_TVAL_MAX_REXMT	(TCP_SLOW_HZ * 64)
+					/* 最大再送時間		*/
+
+/*
+ *  以下の変数の値はマクロで設定する。
+ *
+ *  tcp_maixidle   = tcp_keepcnt * tcp_keepintvl
+ *                 = TCP_TVAL_KEEP_COUNT * TCP_TVAL_KEEP_INTERVAL
+ *  tcp_keepcnt    = TCP_TVAL_KEEP_COUNT
+ *  tcp_keepintval = TCP_TVAL_KEEP_INTERVAL
+ *
+ */
+
+/*
+ *  その他の定数
+ */
+
+#define TCP_MAX_REXMT_SHIFT	12	/* 最大再送回数		*/
+
+/*
+ *  関数
+ */
+
+extern void tcp_slow_timo (void *ignore);
+extern void tcp_fast_timo (void *ignore);
+
+extern T_TCP_TIME tcp_range_set (T_TCP_TIME value, T_TCP_TIME tvmin, T_TCP_TIME tvmax);
+
+#endif	/* of #ifndef _TCP_TIMER_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_usrreq.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_usrreq.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_usrreq.c	(revision 398)
@@ -0,0 +1,1596 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	From: @(#)tcp_usrreq.c	8.2 (Berkeley) 1/3/94
+ * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.40.2.3 1999/08/29 16:29:57 peter Exp $
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
+
+#include <net/if_var.h>
+
+#ifdef SUPPORT_TCP
+
+/*
+ *  TINET をライブラリ化しない場合は、全ての機能を
+ *  オブジェクトファイルに出力するため、マクロを有効にする。
+ */
+
+#ifndef TCP_CFG_LIBRARY
+
+#define __tcp_cre_rep
+#define __tcp_del_rep
+#define __tcp_cre_cep
+#define __tcp_del_cep
+#define __tcp_acp_cep
+#define __tcp_con_cep
+#define __tcp_sht_cep
+#define __tcp_cls_cep
+#define __tcp_snd_dat
+#define __tcp_rcv_dat
+#define __tcp_snd_oob
+#define __tcp_rcv_oob
+#define __tcp_get_buf
+#define __tcp_snd_buf
+#define __tcp_rcv_buf
+#define __tcp_rel_buf
+#define __tcp_can_cep
+#define __tcp_set_opt
+#define __tcp_get_opt
+
+#endif	/* of #ifndef TCP_CFG_LIBRARY */
+
+/*
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#if defined(SUPPORT_INET6)
+
+#define T_IPEP			T_IPV6EP
+#define TCP_ACP_CEP		tcp6_acp_cep
+#define TCP_CON_CEP		tcp6_con_cep
+#define TCP_FIND_CEP_REP	tcp6_find_cep_rep
+
+#if defined(SUPPORT_INET4)
+
+#undef	T_TCP_REP
+#define T_TCP_REP		T_TCP6_REP
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#define TCP_CRE_REP		tcp6_cre_rep
+#define TCP_DEL_REP_BODY	tcp6_del_rep_body
+#define GET_TCP_REP		GET_TCP6_REP
+#define VALID_TCP_REPID		VALID_TCP6_REPID
+#define T_TCPN_CREP		T_TCP6_CREP
+#define API_PROTO		API_PROTO_IPV6
+
+#include <netinet/tcpn_usrreq.c>
+
+#undef  T_IPEP
+#undef  TCP_ACP_CEP
+#undef  TCP_CON_CEP
+#undef	TCP_FIND_CEP_REP
+
+#undef  TCP_CRE_REP
+#undef	TCP_DEL_REP_BODY
+#undef	GET_TCP_REP
+#undef	VALID_TCP_REPID
+#undef	T_TCPN_CREP
+#undef  API_PROTO
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#define T_IPEP			T_IPV4EP
+#define TCP_ACP_CEP		tcp_acp_cep
+#define TCP_CON_CEP		tcp_con_cep
+#define TCP_FIND_CEP_REP	tcp4_find_cep_rep
+
+#if defined(SUPPORT_INET6)
+
+#undef	T_TCP_REP
+#define T_TCP_REP		T_TCP4_REP
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#define TCP_CRE_REP		tcp_cre_rep
+#define TCP_DEL_REP_BODY	tcp4_del_rep_body
+#define GET_TCP_REP		GET_TCP4_REP
+#define VALID_TCP_REPID		VALID_TCP4_REPID
+#define T_TCPN_CREP		T_TCP_CREP
+#define API_PROTO		API_PROTO_IPV4
+
+#include <netinet/tcpn_usrreq.c>
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#ifdef __tcp_cls_cep
+
+/*
+ *  tcp_user_closed -- ユーザからのコネクションの開放
+ */
+
+T_TCP_CEP *
+tcp_user_closed (T_TCP_CEP *cep)
+{
+	switch (cep->fsm_state) {
+
+	case TCP_FSM_CLOSED:		/* クローズ	*/
+	case TCP_FSM_LISTEN:		/* 受動オープン	*/
+		cep->fsm_state = TCP_FSM_CLOSED;
+		cep = tcp_close(cep);
+		break;
+
+	case TCP_FSM_SYN_SENT:		/* 能動オープン、SYN 送信済み	*/
+	case TCP_FSM_SYN_RECVD:		/* SYN を受信し、SYN 送信済み	*/
+		cep->flags |= TCP_CEP_FLG_NEED_FIN;
+		break;
+
+	case TCP_FSM_ESTABLISHED:	/* コネクション開設完了	*/
+		cep->fsm_state = TCP_FSM_FIN_WAIT_1;
+		break;
+
+	case TCP_FSM_CLOSE_WAIT:	/* 相手から FIN 受信、APP の終了待ち */
+		cep->fsm_state = TCP_FSM_LAST_ACK;
+		break;
+		}
+
+	if (cep != NULL && cep->fsm_state == TCP_FSM_FIN_WAIT_2)
+		cep->timer[TCP_TIM_2MSL] = TCP_TVAL_KEEP_COUNT * TCP_TVAL_KEEP_INTERVAL;
+	return cep;
+	}
+
+/*
+ *  tcp_cls_cep -- 通信端点のクローズ【標準機能】
+ */
+
+ER
+tcp_cls_cep (ID cepid, TMO tmout)
+{
+	T_TCP_CEP	*cep;
+	ER		error = E_OK;
+	FLGPTN		flag;
+
+#ifndef TCP_CFG_NON_BLOCKING
+
+	/* tmout が TMO_NBLK ならエラー */
+	if (tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifndef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_CLS_CEP)) != E_OK)
+		return error;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* タイムアウトをチェックする。*/
+	if (tmout == TMO_NBLK) {				/* ノンブロッキングコール */
+
+		if (!IS_PTR_DEFINED(cep->callback))
+			error = E_OBJ;
+		else if (cep->fsm_state == TCP_FSM_CLOSED) {	/* すでにクローズされているとき */
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_CLS_CEP, E_OK);
+			error = E_WBLK;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+			ER	error = E_OK;
+
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_CLS_CEP, (void*)&error);
+			error = E_WBLK;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+			}
+		else {
+			/* NBLK のAPI 機能コードを設定する。*/
+			cep->rcv_nblk_tfn = TFN_TCP_CLS_CEP;
+
+			if ((cep = tcp_user_closed(cep)) != NULL) {	/* コネクションを切断する。*/
+				/* 切断セグメント出力をポストする。*/
+				cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+				sig_sem(SEM_TCP_POST_OUTPUT);
+				}
+
+			/*  cep が NULL で戻ってきた場合は、
+			 *  既にコネクションが切断されていることを意味している。
+			 *  また、この場合コールバック関数が呼び出されている。
+			 */
+			return E_WBLK;
+			}
+		}
+	else {							/* 非ノンブロッキングコール */
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		if ((cep = tcp_user_closed(cep)) == NULL) {	/* コネクションを切断する。*/
+
+			/*  cep が NULL で戻ってきた場合は、
+			 *  既にコネクションが切断されていることを意味している。
+			 */
+			return error;
+			}
+		else {
+			/* 切断セグメント出力をポストする。*/
+			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+
+			/* イベントフラグが CLOSED になるまで待つ。*/
+			error = twai_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED, TWF_ORW, &flag, tmout);
+			if (error == E_OK && cep->error != E_OK)
+				error = cep->error;
+
+			if (error != E_OK) {
+				if (error == E_RLWAI) {
+					/* tcp_cls_cep がキャンセルされたときは、RST を送信する。*/
+					tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una - 1, 
+					            cep->rbufsz - cep->rwbuf_count, TCP_FLG_RST);
+					}
+
+				/* タイマーを停止する。*/
+				tcp_cancel_timers(cep);
+
+				/* 
+				 *  通信端点をロックし、
+				 *  受信再構成キューのネットワークバッファを解放する。
+				 */
+				syscall(wai_sem(cep->semid_lock));
+				tcp_free_reassq(cep);
+				syscall(sig_sem(cep->semid_lock));
+
+				/* 状態を未使用にする。*/
+				cep->fsm_state = TCP_FSM_CLOSED;
+
+				/*
+				 * 以下に関係しないフラグをクリアーする。
+				 * ・送受信ウィンドバッファの省コピー機能
+				 * ・動的な通信端点の生成・削除機能
+				 */
+				cep->flags &= TCP_CEP_FLG_NOT_CLEAR;
+
+				/* 
+				 *  通信端点をロックし、
+				 *  送受信ウィンドバッファキューのネットワークバッファを解放する。
+				 */
+				cep->rwbuf_count = 0;
+				syscall(wai_sem(cep->semid_lock));
+				TCP_FREE_RWBUFQ(cep);
+				TCP_FREE_SWBUFQ(cep);
+				syscall(sig_sem(cep->semid_lock));
+
+				syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+				}
+			}
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	cep->rcv_tskid = TA_NULL;
+	cep->rcv_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_cls_cep */
+
+#ifdef __tcp_sht_cep
+
+/*
+ *  tcp_sht_cep  -- データ送信の終了【標準機能】
+ */
+
+ER
+tcp_sht_cep (ID cepid)
+{
+	T_TCP_CEP	*cep;
+	ER		error = E_OK;
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SHT_CEP)) != E_OK)
+		return error;
+
+	/* TCP 通信端点のコネクションが確立状態でなければエラー */
+	if (!TCP_FSM_HAVE_ESTABLISHED(cep->fsm_state)) {
+		if ((error = cep->error) == E_OK)
+			error = E_OBJ;
+		}
+
+	else if ((cep = tcp_user_closed(cep)) != NULL) {		/* コネクションを切断する。*/
+
+		/* 切断セグメント出力をポストする。*/
+		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		}
+
+	cep->snd_tskid = TA_NULL;
+	cep->snd_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_sht_cep */
+
+#ifdef __tcp_snd_dat
+
+/*
+ *  tcp_snd_dat -- パケットの送信【標準機能】
+ */
+
+ER_UINT
+tcp_snd_dat (ID cepid, void *data, int_t len, TMO tmout)
+{
+	T_TCP_CEP	*cep;
+	ER_UINT		error;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* data が NULL か、len < 0 ならエラー */
+	if (data == NULL || len < 0)
+		return E_PAR;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
+	if (data == NULL || len < 0 || tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_DAT)) != E_OK)
+		return error;
+
+	/* 送信できるか、通信端点の状態を見る。*/
+	if ((error = tcp_can_send_more(cep, TFN_TCP_SND_DAT, tmout)) != E_OK)
+		goto err_ret;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* タイムアウトをチェックする。*/
+	if (tmout == TMO_NBLK) {		/* ノンブロッキングコール */
+
+		/* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
+		if (!TCP_IS_SWBUF_FULL(cep)) {
+
+		 	/* 送信ウィンドバッファにデータを書き込む。*/
+			error = TCP_WRITE_SWBUF(cep, data, (uint_t)len);
+
+			/* 出力をポストする。*/
+			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+
+			/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_DAT, (void*)error);
+#else
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_DAT, (void*)&error);
+#endif
+			error = E_WBLK;
+			goto err_ret;
+			}
+		else {
+			cep->snd_data     = data;
+			cep->snd_len      = len;
+			cep->snd_nblk_tfn = TFN_TCP_SND_DAT;
+			TCP_ALLOC_SWBUF(cep);
+
+			return E_WBLK;
+			}
+		}
+	else {		/* 非ノンブロッキングコール */
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	 	/* 送信ウィンドバッファが空くのを待つ。*/
+		if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
+			goto err_ret;
+
+	 	/* 送信ウィンドバッファにデータを書き込む。*/
+		if ((error = TCP_WRITE_SWBUF(cep, data, (uint_t)len)) > 0) {
+
+			/* データを送信する。送信ウィンドバッファがフルのときは強制的に送信する。*/
+			if (TCP_IS_SWBUF_FULL(cep))
+				cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR;
+
+			/* 出力をポストする。*/
+			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+			}
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+err_ret:
+	cep->snd_tskid = TA_NULL;
+	cep->snd_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_snd_dat */
+
+#ifdef __tcp_get_buf
+
+/*
+ *  tcp_get_buf -- 送信用バッファの獲得【標準機能】
+ */
+
+ER_UINT
+tcp_get_buf (ID cepid, void **p_buf, TMO tmout)
+{
+	T_TCP_CEP	*cep;
+	ER_UINT		error;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* p_buf が NULL ならエラー */
+	if (p_buf == NULL)
+		return E_PAR;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/* p_buf が NULL か、tmout が TMO_NBLK ならエラー */
+	if (p_buf == NULL || tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_GET_BUF)) != E_OK)
+		return error;
+
+	/* 送信できるか、通信端点の状態を見る。*/
+	if ((error = tcp_can_send_more(cep, TFN_TCP_GET_BUF, tmout)) != E_OK)
+		goto err_ret;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* タイムアウトをチェックする。*/
+	if (tmout == TMO_NBLK) {		/* ノンブロッキングコール */
+
+		if (!TCP_IS_SWBUF_FULL(cep)) {
+
+			/* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
+			error = TCP_GET_SWBUF_ADDR(cep, p_buf);
+
+			/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_GET_BUF, (void*)error);
+#else
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_GET_BUF, (void*)&error);
+#endif
+			error = E_WBLK;
+			goto err_ret;
+			}
+		else {
+			cep->snd_p_buf    = p_buf;
+			cep->snd_nblk_tfn = TFN_TCP_GET_BUF;
+			TCP_ALLOC_SWBUF(cep);
+			return E_WBLK;
+			}
+		}
+
+	else {		/* 非ノンブロッキングコール */
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	 	/* 送信ウィンドバッファが空くのを待つ。*/
+		if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
+			goto err_ret;
+
+	 	/* 送信ウィンドバッファの空アドレスを獲得する。*/
+		error = TCP_GET_SWBUF_ADDR(cep, p_buf);
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+err_ret:
+	cep->snd_tskid = TA_NULL;
+	cep->snd_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_get_buf */
+
+#ifdef __tcp_snd_buf
+
+/*
+ *  tcp_snd_buf -- バッファ内のデータの送信【標準機能】
+ */
+
+ER
+tcp_snd_buf (ID cepid, int_t len)
+{
+	T_TCP_CEP	*cep;
+	ER		error;
+
+	/* 送信する長さ len をチェックする。*/
+	if (len < 0)
+		return E_PAR;
+
+	/* 送信する長さlen が 0 であれば、何もしないで戻る。*/
+	if (len == 0)
+		return E_OK;
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_BUF)) != E_OK)
+		return error;
+
+	/* 送信する長さ len をチェックする。*/
+	if (len > cep->get_buf_len) {
+		error = E_OBJ;
+		goto err_ret;
+		}
+
+	/* 送信できるか、CEP の FSM 状態を見る。*/
+	if (!TCP_FSM_CAN_SEND_MORE(cep->fsm_state)) {
+		if ((error = cep->error) == E_OK)
+			error = E_OBJ;
+		goto err_ret;
+		}
+
+	/* 送信ウィンドバッファのデータを送信可能にする。*/
+	TCP_SEND_SWBUF(cep, (uint_t)len);
+
+	/* 出力をポストする。*/
+	cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+	sig_sem(SEM_TCP_POST_OUTPUT);
+
+err_ret:
+	cep->snd_tskid = TA_NULL;
+	cep->snd_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_snd_buf */
+
+#ifdef __tcp_rcv_dat
+
+/*
+ *  tcp_rcv_dat -- パケットの受信【標準機能】
+ */
+
+ER_UINT
+tcp_rcv_dat (ID cepid, void *data, int_t len, TMO tmout)
+{
+	T_TCP_CEP	*cep;
+	ER_UINT		error;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* data が NULL か、len < 0 ならエラー */
+	if (data == NULL || len < 0)
+		return E_PAR;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
+	if (data == NULL || len < 0 || tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_RCV_DAT)) != E_OK)
+		return error;
+
+	/* 受信できるか、通信端点の状態を見る。*/
+	if (tcp_can_recv_more(&error, cep, TFN_TCP_RCV_DAT, tmout) != E_OK)
+		goto err_ret;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* タイムアウトをチェックする。*/
+	if (tmout == TMO_NBLK) {		/* ノンブロッキングコール */
+
+		/* 受信ウィンドバッファにデータがあればコールバック関数を呼び出す。*/
+		if (cep->rwbuf_count > 0) {
+
+			/* 受信ウィンドバッファからデータを取り出す。*/
+			len = TCP_READ_RWBUF(cep, data, (uint_t)len);
+
+			/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_DAT, (void*)(uint32_t)len);
+#else
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_DAT, (void*)&len);
+#endif
+			error = E_WBLK;
+			goto err_ret;
+			}
+		else {
+			cep->rcv_data     = data;
+			cep->rcv_len      = len;
+			cep->rcv_nblk_tfn = TFN_TCP_RCV_DAT;
+			return E_WBLK;
+			}
+		}
+	else {		/* 非ノンブロッキングコール */
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		/* 受信ウィンドバッファにデータがなければ、入力があるまで待つ。*/
+		if ((error = tcp_wait_rwbuf(cep, tmout)) != E_OK)
+			goto err_ret;
+
+		/* 受信ウィンドバッファからデータを取り出す。*/
+		error = TCP_READ_RWBUF(cep, data, (uint_t)len);
+
+		/* 相手にウィンドウサイズが変わったことを知らせるため出力をポストする。*/
+		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+err_ret:
+	cep->rcv_tskid = TA_NULL;
+	cep->rcv_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_rcv_dat */
+
+#ifdef __tcp_rcv_buf
+
+/*
+ *  tcp_rcv_buf -- 受信したデータの入ったバッファの獲得【標準機能】
+ */
+
+ER_UINT
+tcp_rcv_buf (ID cepid, void **p_buf, TMO tmout)
+{
+	T_TCP_CEP	*cep;
+	ER_UINT		error;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* p_buf が NULL ならエラー */
+	if (p_buf == NULL)
+		return E_PAR;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/* p_buf が NULL か、tmout が TMO_NBLK ならエラー */
+	if (p_buf == NULL || tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_RCV_BUF)) != E_OK)
+		return error;
+
+	/* 受信できるか、通信端点の状態を見る。*/
+	if (tcp_can_recv_more(&error, cep, TFN_TCP_RCV_DAT, tmout) != E_OK)
+		goto err_ret;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* タイムアウトをチェックする。*/
+	if (tmout == TMO_NBLK) {		/* ノンブロッキングコール */
+
+		/* 受信ウィンドバッファにデータがあればコールバック関数を呼び出す。*/
+		if (cep->rwbuf_count > 0) {
+
+		 	/* 受信ウィンドバッファの空アドレスを獲得する。*/
+			error = TCP_GET_RWBUF_ADDR(cep, p_buf);
+
+			/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_BUF, (void*)error);
+#else
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_BUF, (void*)&error);
+#endif
+			error = E_WBLK;
+			goto err_ret;
+			}
+		else {
+			cep->rcv_p_buf    = p_buf;
+			cep->rcv_nblk_tfn = TFN_TCP_RCV_BUF;
+			return E_WBLK;
+			}
+		}
+	else {		/* 非ノンブロッキングコール */
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		/* 受信ウィンドバッファにデータがなければ、入力があるまで待つ。*/
+		if ((error = tcp_wait_rwbuf(cep, tmout)) != E_OK) {
+			cep->rwbuf_count = 0;
+			goto err_ret;
+			}
+
+	 	/* 受信ウィンドバッファのアドレスを獲得する。*/
+		error = TCP_GET_RWBUF_ADDR(cep, p_buf);
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+err_ret:
+	cep->rcv_tskid = TA_NULL;
+	cep->rcv_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_rcv_buf */
+
+#ifdef __tcp_rel_buf
+
+/*
+ *  tcp_rel_buf -- 受信用バッファの解放【標準機能】
+ */
+
+ER
+tcp_rel_buf (ID cepid, int_t len)
+{
+	T_TCP_CEP	*cep;
+	ER		error;
+
+	/* 解放する長さ len をチェックする。*/
+	if (len < 0)
+		return E_PAR;
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_REL_BUF)) != E_OK)
+		return error;
+
+	/* 解放する長さ len をチェックする。*/
+	if (len > cep->rcv_buf_len) {
+		error = E_OBJ;
+		goto err_ret;
+		}
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/* 受信ウィンドバッファから受信したオクテットを削除する。*/
+	TCP_DROP_RWBUF(cep, (uint_t)len);
+
+	/* tcp_rcv_buf の割当て長をリセットする。*/
+	cep->rcv_buf_len -= len;
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	/* 相手にウィンドウサイズが変わったことを知らせるため出力をポストする。*/
+	cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+	sig_sem(SEM_TCP_POST_OUTPUT);
+
+err_ret:
+	cep->rcv_tskid = TA_NULL;
+	cep->rcv_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_rel_buf */
+
+#ifdef __tcp_can_cep
+
+/*
+ *  tcp_can_snd -- ペンディングしている送信のキャンセル
+ */
+
+static ER
+tcp_can_snd (T_TCP_CEP *cep, FN fncd)
+{
+	ER	error = E_OK;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 *  snd_tskid が TA_NULL なら、
+	 *  ペンディングしていないのでエラー
+	 */
+	if (cep->snd_tskid == TA_NULL)
+		error = EV_NOPND;
+
+	/* ペンディング中の API 機能コードと一致しなければエラー */
+	else if (fncd != TFN_TCP_ALL && fncd != cep->snd_tfn)
+		error = E_OBJ;
+
+	/* 処理をキャンセルする。*/
+	else {
+
+		/* 受信再構成キューのネットワークバッファを解放する。*/
+		tcp_free_reassq(cep);
+
+		/* 受信ウィンドバッファキューのネットワークバッファを解放する。*/
+		cep->rwbuf_count = 0;
+		TCP_FREE_RWBUFQ(cep);
+
+		/* 送信ウィンドバッファキューのネットワークバッファを解放する。*/
+		TCP_FREE_SWBUFQ(cep);
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		if (cep->snd_nblk_tfn != TFN_TCP_UNDEF) {	/* ノンブロッキングコール */
+
+			switch (cep->snd_nblk_tfn) {
+
+			case TFN_TCP_CON_CEP:
+				/*
+				 *  通信端点から受付口を解放し、
+				 *  イベントフラグをクローズに設定する。
+				 */
+				cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+				cep->rep4 = NULL;
+#endif
+
+				cep->fsm_state = TCP_FSM_CLOSED;
+				syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+				break;
+
+			case TFN_TCP_SND_DAT:
+			case TFN_TCP_GET_BUF:
+			case TFN_TCP_SND_OOB:
+				break;
+				}
+
+			if (IS_PTR_DEFINED(cep->callback)) {
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)E_RLWAI);
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+				ER	error = E_RLWAI;
+
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&error);
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+				}
+			else
+				error = E_OBJ;
+			cep->snd_nblk_tfn = TFN_TCP_UNDEF;
+			}
+		else
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+			error = rel_wai(cep->snd_tskid);
+
+		cep->snd_tskid = TA_NULL;
+		cep->snd_tfn   = TFN_TCP_UNDEF;
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+/*
+ *  tcp_can_rcv -- ペンディングしている受信のキャンセル
+ */
+
+static ER
+tcp_can_rcv (T_TCP_CEP *cep, FN fncd)
+{
+	ER	error = E_OK;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 *  rcv_tskid が TA_NULL なら、
+	 *  ペンディングしていないのでエラー
+	 */
+	if (cep->rcv_tskid == TA_NULL)
+		error = EV_NOPND;
+
+	/* ペンディング中の API 機能コードと一致しなければエラー */
+	else if (fncd != TFN_TCP_ALL && fncd != cep->rcv_tfn)
+		error = E_OBJ;
+
+	/* 処理をキャンセルする。*/
+	else {
+
+		/* 受信再構成キューのネットワークバッファを解放する。*/
+		tcp_free_reassq(cep);
+
+		/* 受信ウィンドバッファキューのネットワークバッファを解放する。*/
+		cep->rwbuf_count = 0;
+		TCP_FREE_RWBUFQ(cep);
+
+		/* 送信ウィンドバッファキューのネットワークバッファを解放する。*/
+		TCP_FREE_SWBUFQ(cep);
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) {	/* ノンブロッキングコール */
+
+			switch (cep->rcv_nblk_tfn) {
+
+			case TFN_TCP_ACP_CEP:
+				/*
+				 *  通信端点から受付口を解放し、
+				 *  イベントフラグをクローズに設定する。
+				 */
+				cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+				cep->rep4 = NULL;
+#endif
+
+				cep->fsm_state = TCP_FSM_CLOSED;
+				syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+				break;
+
+			case TFN_TCP_RCV_DAT:
+			case TFN_TCP_RCV_BUF:
+				break;
+
+			case TFN_TCP_CLS_CEP:
+				cep->fsm_state = TCP_FSM_CLOSED;
+				tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una - 1,
+				            cep->rbufsz - cep->rwbuf_count, TCP_FLG_RST);
+				syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+				break;
+				}
+
+			if (IS_PTR_DEFINED(cep->callback)) {
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_RLWAI);
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+				ER	error = E_RLWAI;
+
+				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&error);
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+				}
+			else
+				error = E_OBJ;
+			cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+			}
+		else
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+			error = rel_wai(cep->rcv_tskid);
+
+		cep->rcv_tskid = TA_NULL;
+		cep->rcv_tfn   = TFN_TCP_UNDEF;
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+/*
+ *  tcp_can_cep -- ペンディングしている処理のキャンセル【標準機能】
+ */
+
+ER
+tcp_can_cep (ID cepid, FN fncd)
+{
+	T_TCP_CEP	*cep;
+	ER		error = E_OK, snd_err, rcv_err;
+
+	/* API 機能コードをチェックする。*/
+	if (!VALID_TFN_TCP_CAN(fncd))
+		return E_PAR;
+
+	/* TCP 通信端点 ID をチェックする。*/
+	if (!VALID_TCP_CEPID(cepid))
+		return E_ID;
+
+	/* TCP 通信端点を得る。*/
+	cep = GET_TCP_CEP(cepid);
+
+	/* TCP 通信端点をチェックする。*/
+	if (!VALID_TCP_CEP(cep))
+		return E_NOEXS;
+
+	if (fncd == TFN_TCP_ALL) {		/* TFN_TCP_ALL の処理 */
+		snd_err = tcp_can_snd(cep, fncd);
+		rcv_err = tcp_can_rcv(cep, fncd);
+
+		/*
+		 *  snd_err と rcv_err のどちらも EV_NOPND
+		 *  なら、ペンディングしていないのでエラー
+		 */
+		if (snd_err == EV_NOPND && rcv_err == EV_NOPND)
+			error = E_OBJ;
+		else {
+			if (snd_err == EV_NOPND)
+				snd_err = E_OK;
+			if (rcv_err == EV_NOPND)
+				rcv_err = E_OK;
+
+			if (snd_err != E_OK)
+				error = snd_err;
+			else if (rcv_err != E_OK)
+				error = rcv_err;
+			}
+		}
+
+	else if (IS_TFN_TCP_RCV(fncd)) {	/* 受信処理のキャンセル */
+		if ((error = tcp_can_rcv(cep, fncd)) == EV_NOPND)
+			error = E_OBJ;
+		}
+
+	else {					/* 送信処理のキャンセル */
+		if ((error = tcp_can_snd(cep, fncd)) == EV_NOPND)
+			error = E_OBJ;
+		}
+
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_can_cep */
+
+#ifdef TCP_CFG_EXTENTIONS
+
+#ifdef __tcp_cre_cep
+
+/*
+ *  tcp_cre_cep -- TCP 通信端点の生成【拡張機能】
+ */
+
+ER
+tcp_cre_cep (ID cepid, T_TCP_CCEP *pk_ccep)
+{
+	T_TCP_CEP	*cep;
+	ER		error;
+
+	/* TCP 通信端点 ID をチェックする。*/
+	if (!VALID_TCP_CEPID(cepid))
+		return E_ID;
+
+	/* pk_ccep が NULL ならエラー */
+	if (pk_ccep == NULL)
+		return E_PAR;
+
+	/* TCP 通信端点を得る。*/
+	cep = GET_TCP_CEP(cepid);
+
+	/* TCP 通信端点が、動的生成用でなければエラー */
+	if (!DYNAMIC_TCP_CEP(cep))
+		return E_ID;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 * TCP 通信端点をチェックする。生成済みであればエラー
+	 */
+	if (VALID_TCP_CEP(cep))
+		error = E_OBJ;
+	else {
+
+		/* TCP 通信端点生成情報をコピーする。*/
+		cep->cepatr   = pk_ccep->cepatr;		/* 通信端点属性			*/
+		cep->sbuf     = pk_ccep->sbuf;			/* 送信用ウィンドバッファ	*/
+		cep->sbufsz   = pk_ccep->sbufsz;		/* 送信用ウィンドバッファサイズ	*/
+		cep->rbuf     = pk_ccep->rbuf;			/* 受信用ウィンドバッファ	*/
+		cep->rbufsz   = pk_ccep->rbufsz;		/* 受信用ウィンドバッファサイズ	*/
+		cep->callback = (void*)pk_ccep->callback;	/* コールバック			*/
+
+		/* TCP 通信端点を生成済みにする。*/
+		cep->flags |= TCP_CEP_FLG_VALID;
+		error = E_OK;
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_cre_cep */
+
+/*
+ *  tcp_del_cep -- TCP 通信端点の削除【拡張機能】
+ */
+
+#ifdef __tcp_del_cep
+
+ER
+tcp_del_cep (ID cepid)
+{
+	T_TCP_CEP	*cep;
+	ER		error;
+
+	/* TCP 通信端点 ID をチェックする。*/
+	if (!VALID_TCP_CEPID(cepid))
+		return E_ID;
+
+	/* TCP 通信端点を得る。*/
+	cep = GET_TCP_CEP(cepid);
+
+	/* TCP 通信端点が、動的生成用でなければエラー */
+	if (!DYNAMIC_TCP_CEP(cep))
+		return E_ID;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 * TCP 通信端点をチェックする。以下の場合はエラー
+	 * ・未生成。
+	 * ・使用中。
+	 */
+	if (!VALID_TCP_CEP(cep))
+		error = E_NOEXS;
+	else if (cep->fsm_state != TCP_FSM_CLOSED)
+		error = E_OBJ;
+	else {
+
+		/* TCP 通信端点を未生成にする。*/
+		cep->flags &= ~TCP_CEP_FLG_VALID;
+		error = E_OK;
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_del_cep */
+
+#ifdef __tcp_snd_oob
+
+/*
+ *  tcp_snd_oob -- 緊急データの送信【拡張機能】
+ */
+
+ER_UINT
+tcp_snd_oob (ID cepid, void *data, int_t len, TMO tmout)
+{
+	T_TCP_CEP	*cep;
+	ER_UINT		error;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* data が NULL か、len < 0 ならエラー */
+	if (data == NULL || len < 0)
+		return E_PAR;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
+	if (data == NULL || len < 0 || tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_OOB)) != E_OK)
+		return error;
+
+	/* 送信できるか、通信端点の状態を見る。*/
+	if ((error = tcp_can_send_more(cep, TFN_TCP_SND_OOB, tmout)) != E_OK)
+		goto err_ret;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* タイムアウトをチェックする。*/
+	if (tmout == TMO_NBLK) {		/* ノンブロッキングコール */
+
+		/* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
+		if (!TCP_IS_SWBUF_FULL(cep)) {
+
+		 	/* 送信ウィンドバッファにデータを書き込む。*/
+			error = TCP_WRITE_SWBUF(cep, data, (uint_t)len);
+
+			/* 送信緊急ポインタを設定する。*/
+			cep->snd_up = cep->snd_una + cep->swbuf_count;
+
+			/* 出力をポストする。*/
+			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+
+			/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_OOB, (void*)error);
+#else
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_OOB, (void*)&error);
+#endif
+			error = E_WBLK;
+			goto err_ret;
+			}
+		else {
+			cep->snd_data     = data;
+			cep->snd_len      = len;
+			cep->snd_nblk_tfn = TFN_TCP_SND_OOB;
+			TCP_ALLOC_SWBUF(cep);
+
+			return E_WBLK;
+			}
+		}
+	else {		/* 非ノンブロッキングコール */
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	 	/* 送信ウィンドバッファが空くのを待つ。*/
+		if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
+			goto err_ret;
+
+	 	/* 送信ウィンドバッファにデータを書き込む。*/
+		if ((error = TCP_WRITE_SWBUF(cep, data, (uint_t)len)) > 0) {
+
+			/* 送信緊急ポインタを設定する。*/
+			cep->snd_up = cep->snd_una + cep->swbuf_count;
+
+			/* データを送信する。送信ウィンドバッファがフルのときは強制的に送信する。*/
+			if (TCP_IS_SWBUF_FULL(cep))
+				cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR;
+
+			/* 出力をポストする。*/
+			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+			}
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+err_ret:
+	cep->snd_tskid = TA_NULL;
+	cep->snd_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_snd_oob */
+
+#ifdef __tcp_rcv_oob
+
+/*
+ *  tcp_rcv_oob -- 緊急データの受信【拡張機能】
+ *
+ *    注意: 送信側が複数オクテットのデータを送信しても、
+ *          緊急ポインタが指す 1 オクテットのデータのみ受信する。
+ */
+
+ER_UINT
+tcp_rcv_oob (ID cepid, void *data, int_t len)
+{
+	T_TCP_CEP	*cep;
+	uint8_t		*urg;
+
+	/* TCP 通信端点 ID をチェックする。*/
+	if (!VALID_TCP_CEPID(cepid))
+		return E_ID;
+
+	/* data が NULL か、len < 0 ならエラー */
+	if (data == NULL || len < 0)
+		return E_PAR;
+
+	/* TCP 通信端点を得る。*/
+	cep = GET_TCP_CEP(cepid);
+
+	/* 受信できるか、通信端点の状態を見る。*/
+	/* 受信できるか、fsm_state を見る。*/
+	if (!TCP_FSM_CAN_RECV_MORE(cep->fsm_state))
+		return E_OBJ;
+
+	/*
+	 *  緊急データ入りのセグメントの TCP ヘッダが
+	 *  設定されていなければ、緊急データを受信していない。
+	 */
+	if (cep->urg_tcph == NULL)
+		return E_OBJ;
+
+	/* len == 0 ならバッファオーバーフロー */
+	if (len == 0)
+		return E_BOVR;
+
+	/* 緊急ポインタが指す 1 オクテットのデータを読み取る。*/
+	urg = (uint8_t*)cep->urg_tcph + TCP_DATA_OFF(cep->urg_tcph->doff) + cep->urg_tcph->urp + TCP_CFG_URG_OFFSET;
+	*(uint8_t*)data = *urg;
+
+	/* 読み取ったデータから後ろの SDU を前に詰める。*/
+	memcpy(urg, urg + 1, cep->urg_tcph->sum - (cep->urg_tcph->urp + TCP_CFG_URG_OFFSET) - 1);
+
+	/* tcp_rcv_oob() が呼出されたこと知らせるために、NULL を設定する。*/
+	cep->urg_tcph = NULL;
+
+	return 1;
+	}
+
+#endif	/* of #ifdef __tcp_rcv_oob */
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+#ifdef TCP_CFG_EXTENTIONS
+
+#ifdef __tcp_del_rep
+
+/*
+ *  tcp_del_rep -- TCP 受付口の削除【拡張機能】
+ */
+
+#if defined(SUPPORT_INET6) && TNUM_TCP6_REPID > 0
+
+#if defined(SUPPORT_INET4) && TNUM_TCP4_REPID > 0
+
+ER
+tcp_del_rep (ID repid)
+{
+
+	/*
+	 *  TCP 受付口 ID をチェックする。
+	 *  IPv6 用 TCP 受付口であれば、
+	 *  IPv6 用の「TCP 受付口の削除関数（本体）」を呼出す。
+	 */
+	//NET_DEBUG_TCP3("tcp_del_rep1[r=%d,n=%d,x=%d]\n",
+	//               repid, TMIN_TCP6_REPID, tmax_tcp6_repid);
+	//NET_DEBUG_TCP3("tcp_del_rep2[r=%d,n=%d,x=%d]\n",
+	//               repid, TMIN_TCP4_REPID, tmax_tcp4_repid);
+	if (VALID_TCP6_REPID(repid))
+		return tcp6_del_rep_body(repid);
+
+	/*
+	 *  TCP 受付口 ID をチェックする。
+	 *  IPv4 用 TCP 受付口であれば、
+	 *  IPv4 用の「TCP 受付口の削除関数（本体）」を呼出す。
+	 */
+	else if (VALID_TCP4_REPID(repid))
+		return tcp4_del_rep_body(repid);
+	else
+		return E_ID;
+
+	}
+
+#else	/* of #if defined(SUPPORT_INET4) && TNUM_TCP4_REPID > 0 */
+
+ER
+tcp_del_rep (ID repid)
+{
+
+	/* TCP 受付口 ID をチェックする。*/
+	if (VALID_TCP6_REPID(repid))
+		return tcp6_del_rep_body(repid);
+	else
+		return E_ID;
+
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) && TNUM_TCP4_REPID > 0 */
+
+#else	/* of #if defined(SUPPORT_INET6) && TNUM_TCP6_REPID > 0 */
+
+ER
+tcp_del_rep (ID repid)
+{
+
+	/* TCP 受付口 ID をチェックする。*/
+	if (VALID_TCP4_REPID(repid))
+		return tcp4_del_rep_body(repid);
+	else
+		return E_ID;
+
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && TNUM_TCP6_REPID > 0 */
+
+#endif	/* of #ifdef __tcp_del_rep */
+
+/*
+ *  tcp_set_opt -- TCP 通信端点オプションの設定【拡張機能】
+ *
+ *  注意: 設定可能な TCP 通信端点オプションは無いため、E_PAR が返される。
+ */
+
+#ifdef __tcp_set_opt
+
+ER
+tcp_set_opt (ID cepid, int_t optname, void *optval, int_t optlen)
+{
+	T_TCP_CEP	*cep;
+
+	/* TCP 通信端点 ID をチェックする。*/
+	if (!VALID_TCP_CEPID(cepid))
+		return E_ID;
+
+	/* TCP 通信端点を得る。*/
+	cep = GET_TCP_CEP(cepid);
+
+	/* TCP 通信端点をチェックする。*/
+	if (!VALID_TCP_CEP(cep))
+		return E_NOEXS;
+
+	return E_PAR;
+	}
+
+#endif	/* of #ifdef __tcp_set_opt */
+
+/*
+ *  tcp_get_opt -- TCP 通信端点オプションの設定【拡張機能】
+ *
+ *  注意: 設定可能な TCP 通信端点オプションは無いため、E_PAR が返される。
+ */
+
+#ifdef __tcp_get_opt
+
+ER
+tcp_get_opt (ID cepid, int_t optname, void *optval, int_t optlen)
+{
+	T_TCP_CEP	*cep;
+
+	/* TCP 通信端点 ID をチェックする。*/
+	if (!VALID_TCP_CEPID(cepid))
+		return E_ID;
+
+	/* TCP 通信端点を得る。*/
+	cep = GET_TCP_CEP(cepid);
+
+	/* TCP 通信端点をチェックする。*/
+	if (!VALID_TCP_CEP(cep))
+		return E_NOEXS;
+
+	return E_PAR;
+	}
+
+#endif	/* of #ifdef __tcp_get_opt */
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+#endif	/* of #ifdef SUPPORT_TCP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcp_var.h	(revision 398)
@@ -0,0 +1,943 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)tcp_var.h	8.4 (Berkeley) 5/24/95
+ * $FreeBSD: src/sys/netinet/tcp_var.h,v 1.49.2.1 1999/08/29 16:29:57 peter Exp $
+ */
+ 
+#ifndef _TCP_VAR_H_
+#define _TCP_VAR_H_
+
+/*
+ *  TCP ヘッダ・ペイロードアクセスマクロ
+ */
+
+#define GET_TCP_HDR(nbuf,thoff)		((T_TCP_HDR*)((uint8_t*)((nbuf)->buf) + thoff))
+#define GET_TCP_OPT(nbuf,thoff)		((uint8_t*)((nbuf)->buf) + thoff + TCP_HDR_SIZE)
+#define GET_TCP_SDU(nbuf,thoff)		((uint8_t*)((nbuf)->buf) + thoff + GET_TCP_HDR_SIZE(nbuf,thoff))
+
+#define GET_TCP_HDR_OFFSET(nbuf)	(GET_IF_IP_HDR_SIZE(nbuf))
+
+#define GET_TCP_HDR_SIZE(nbuf,thoff)	(TCP_HDR_LEN(GET_TCP_HDR(nbuf,thoff)->doff))
+
+#define GET_IP_TCP_HDR_SIZE(nbuf,thoff) (GET_IP_HDR_SIZE(nbuf) + GET_TCP_HDR_SIZE(nbuf,thoff))
+#define GET_IF_IP_TCP_HDR_SIZE(nbuf,thoff) \
+					(IF_HDR_SIZE + GET_IP_TCP_HDR_SIZE(nbuf,thoff))
+#define IF_IP_TCP_HDR_SIZE(nbuf)	(IF_IP_HDR_SIZE(nbuf) + TCP_HDR_SIZE)
+#define IF_IP_TCP_HDR_OFFSET(nbuf)	(IF_IP_HDR_SIZE(nbuf))
+#define IF_IP_TCP_NET_HDR_SIZE(addr)	(IF_IP_NET_HDR_SIZE(addr) + TCP_HDR_SIZE)
+#define IF_IP_TCP_NET_HDR_OFFSET(addr)	(IF_IP_NET_HDR_SIZE(addr))
+
+/*
+ *  TINET 1.1 との互換性のための定義
+ */
+
+#if !defined(_IP6_CFG) && defined(_IP4_CFG)
+
+#define IP4_TCP_HDR_SIZE		IP_TCP_HDR_SIZE
+#define IF_IP4_TCP_HDR_SIZE		IF_IP_TCP_HDR_SIZE
+#define GET_IP4_TCP_HDR_SIZE(nbuf)	GET_IP_TCP_HDR_SIZE1(nbuf)	
+#define GET_IF_IP4_TCP_HDR_SIZE(nbuf)	GET_IF_IP_TCP_HDR_SIZE1(nbuf)	
+
+#endif	/* of #if !defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+/*
+ *  TINET 1.3 との互換性のための定義
+ */
+
+#define	TMIN_TCP_CREPID			TMIN_TCP_REPID
+#define	TNUM_TCP_CREPID			TNUM_TCP_REPID
+
+#define	TMIN_TCP_CCEPID			TMIN_TCP_CEPID
+#define	TNUM_TCP_CCEPID			TNUM_TCP_CEPID
+
+/*
+ *  コールバック関数の定義
+ */
+
+typedef ER	(*t_tcp_callback)(ID cepid, FN fncd, void *p_parblk);
+
+/*
+ * TCP で使用する変数の型の定義
+ */
+
+typedef uint32_t T_TCP_SEQ;
+typedef uint16_t T_TCP_SEG;
+typedef uint16_t T_TCP_WND;
+typedef int16_t T_TCP_TIME;
+
+/*
+ *  TCP タイマ変数
+ */
+
+#define NUM_TCP_TIMERS		4	/* TCP のタイマ数	*/
+
+/*
+ *  TCP 受付口
+ */
+
+/* IPv6 用 TCP 受付口 */
+
+typedef struct t_tcp6_rep {
+
+	/*
+	 * ITRON TCP/IP API、TCP 受付口と同じメンバ
+	 */
+	ATR		repatr;		/* 受付口属性		*/
+	T_IPV6EP	myaddr;		/* 自分のアドレス	*/
+
+#ifdef TCP_CFG_EXTENTIONS
+	uint16_t	flags;		/* 受付口フラグ		*/
+	ID		semid_lock;	/* 受付口ロック		*/
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+	} T_TCP6_REP;
+
+/* IPv4 用 TCP 受付口 */
+
+typedef struct t_tcp4_rep {
+
+	/*
+	 * ITRON TCP/IP API、TCP 受付口と同じメンバ
+	 */
+	ATR		repatr;		/* 受付口属性		*/
+	T_IPV4EP	myaddr;		/* 自分のアドレス	*/
+
+#ifdef TCP_CFG_EXTENTIONS
+	uint16_t	flags;		/* 受付口フラグ		*/
+	ID		semid_lock;	/* 受付口ロック		*/
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+	} T_TCP4_REP;
+
+#if defined(_IP6_CFG)
+
+#define T_TCP_REP	T_TCP6_REP
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+#define T_TCP_REP	T_TCP4_REP
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#define T_TCP_REP_DEFINED
+
+/*
+ *  受付口フラグ
+ */
+
+#define TCP_REP_FLG_DYNAMIC	UINT_C(0x0400)	/* 動的生成・削除可能受付口。	*/
+#define TCP_REP_FLG_VALID	UINT_C(0x0800)	/* 生成済みで有効な受付口。	*/
+
+/*
+ *  TCP 通信端点
+ */
+
+#ifndef T_NET_BUF_DEFINED
+
+typedef struct t_net_buf T_NET_BUF;
+
+#define T_NET_BUF_DEFINED
+
+#endif	/* of #ifndef T_NET_BUF_DEFINED */
+
+typedef struct t_tcp_cep {
+
+	/*
+	 * ITRON TCP/IP API、TCP 通信端点と同じメンバ
+	 */
+	ATR		cepatr;		/* 通信端点属性			*/
+	void		*sbuf;		/* 送信用ウィンドバッファ	*/
+	int_t		sbufsz;		/* 送信用ウィンドバッファサイズ	*/
+	void		*rbuf;		/* 受信用ウィンドバッファ	*/
+	int_t		rbufsz;		/* 受信用ウィンドバッファサイズ	*/
+	t_tcp_callback	callback;	/* コールバック関数		*/
+
+	/*
+	 * TINET 独自のメンバ
+	 */
+	uint32_t	flags;		/* 通信端点フラグ		*/
+	ID		semid_lock;	/* 通信端点ロック		*/
+	ID		est_flgid;	/* コネクション状態イベントフラグ	*/
+	ID		snd_flgid;	/* 送信イベントフラグ		*/
+	ID		rcv_flgid;	/* 受信イベントフラグ		*/
+	ID		snd_tskid;	/* 送信タスク識別子		*/
+	ID		rcv_tskid;	/* 受信タスク識別子		*/
+	uint8_t		*sbuf_rptr;	/* 送信用読み出しポインタ	*/
+	uint8_t		*sbuf_wptr;	/* 送信用書き込みポインタ	*/
+	uint8_t		*rbuf_rptr;	/* 受信用読み出しポインタ	*/
+	uint8_t		*rbuf_wptr;	/* 受信用書き込みポインタ	*/
+	T_TCP_SEQ	snd_ssthresh;	/* 輻輳ウィンドサイズ(snd_cwnd)	*/
+					/* のしきい値			*/
+	T_TCP_TIME	rxtcur;		/* 現在の再送タイムアウト	*/
+	T_TCP_TIME	srtt;		/* 平滑化された RTT		*/
+	T_TCP_TIME	rttvar;		/* 平滑化された分散		*/
+	T_TCP_WND	snd_cwnd;	/* 輻輳ウィンドサイズ		*/
+
+	/*
+	 *  相手の最大受信セグメントサイズ	
+	 *
+	 *    オリジナルでは、一般のセグメントの最大サイズ (t_maxseg) と、
+	 *    オプション付きのセグメントの最大サイズ (t_maxopd) が別に
+	 *    なっている。これは、現在のインターネットでは、オプション付きの
+	 *    セグメントのほうが多いからと説明されているためである。
+	 *    本実装では、最大セグメントサイズオプション以外のオプションは
+	 *    実装しないので、t_maxseg の使用する。
+	 */
+	T_TCP_SEG	maxseg;
+
+	int16_t		snd_tfn;	/* 送信動作中の API 機能コード	*/
+	int16_t		rcv_tfn;	/* 受信動作中の API 機能コード	*/
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	T_IPEP 		*p_dstaddr;	/* 相手のアドレスへのポインタ	*/
+	T_IPEP	 	*p_myaddr;	/* 自分のアドレスへのポインタ	*/
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+	T_IPV4EP	*p_dstaddr4;	/* 相手のアドレスへのポインタ	*/
+	T_IPV4EP 	*p_myaddr4;	/* 自分のアドレスへのポインタ	*/
+#endif
+	
+	int16_t		snd_nblk_tfn;	/* 送信動作中の API 機能コード	*/
+	int16_t		rcv_nblk_tfn;	/* 受信動作中の API 機能コード	*/
+	void		*snd_data;	/* 送信データ領域の先頭アドレス	*/
+	int_t		snd_len;	/* 送信データ領域の長さ		*/
+	void		*rcv_data;	/* 受信データ領域の先頭アドレス	*/
+	int_t		rcv_len;	/* 受信データ領域の長さ		*/
+	void		**snd_p_buf;	/* 送信バッファへのポインタ	*/
+	void		**rcv_p_buf;	/* 受信バッファへのポインタ	*/
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+	T_NET_BUF	*swbufq;	/* 送信ウィンドバッファキュー	*/
+#endif
+
+	/*
+	 *  これ以降のメンバーは tcp_init_cep() 関数でゼロクリアーされる。
+	 */
+
+	T_TCP_TIME	timer[NUM_TCP_TIMERS];	/* TCP のタイマ		*/
+	T_IPEP		dstaddr;	/* 相手のアドレス		*/
+	T_IPEP		myaddr;		/* 自分のアドレス		*/
+	T_NET_BUF	*reassq;	/* 受信再構成キュー		*/
+
+#if defined(_IP6_CFG)
+
+#if defined(_IP4_CFG)
+
+	T_TCP4_REP	*rep4;		/* IPv4 用受付口		*/
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+	T_TCP6_REP	*rep;		/* IPv6 用受付口		*/
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+	T_TCP4_REP	*rep;		/* IPv4 用受付口		*/
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+
+#ifdef TCP_CFG_RWBUF_CSAVE
+	T_NET_BUF	*rwbufq;	/* 受信ウィンドバッファキュー	*/
+#endif
+
+#ifdef TCP_CFG_EXTENTIONS
+	T_TCP_HDR	*urg_tcph;	/* 緊急データ入りのセグメントの TCP ヘッダ	*/
+	T_TCP_SEQ	snd_up;		/* 送信した緊急ポインタ		*/
+	T_TCP_SEQ	rcv_up;		/* 受信した緊急ポインタ		*/
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+	T_TCP_SEQ	snd_una;	/* 未確認の最小送信 SEQ つまり	*/
+					/* 確認された最大送信 SEQ	*/
+	T_TCP_SEQ	snd_max;	/* 送信した最大 SEQ		*/
+	T_TCP_SEQ	snd_nxt;	/* 次に送信する SEQ		*/
+	T_TCP_SEQ	snd_old_nxt;	/* 元の snd_nxt			*/
+	T_TCP_SEQ	snd_wl1;	/* 前回ウィンドを更新した SEQ	*/
+	T_TCP_SEQ	snd_wl2;	/* 前回ウィンドを更新した ACK	*/
+	T_TCP_SEQ	iss;		/* 自分の SEQ の初期値		*/
+	T_TCP_SEQ	irs;		/* 相手の SEQ の初期値		*/
+	T_TCP_SEQ	rcv_nxt;	/* 受信を期待している最小の SEQ	*/
+	T_TCP_SEQ	rcv_adv;	/* 受信を期待している最大の SEQ	*/
+	T_TCP_SEQ	rcv_wnd;	/* 受信可能なウィンドサイズ	*/
+	T_TCP_SEQ	rtseq;		/* 時間計測を始めた SEQ		*/
+	T_TCP_SEQ	last_ack_sent;	/* 最後に送信した ACK		*/
+	T_TCP_TIME	idle;		/* アイドル時間			*/
+	ER		error;		/* 非同期に発生したエラー	*/
+	ER		net_error;	/* ネットワークのエラー状態	*/
+	T_TCP_WND	snd_wnd;	/* 相手の受信可能ウィンドサイズ	*/
+	T_TCP_WND	max_sndwnd;	/* 今までの最大送信ウィンドサイズ	*/
+	T_TCP_TIME	rtt;		/* 往復時間				*/
+	uint16_t	swbuf_count;	/* 送信ウィンドバッファの使用中サイズ	*/
+	uint16_t	rwbuf_count;	/* 受信ウィンドバッファの使用中サイズ	*/
+	uint16_t	rcv_buf_len;	/* tcp_rcv_buf の割当て長	*/
+	uint16_t	get_buf_len;	/* tcp_rcv_buf の割当て長	*/
+	uint8_t		rxtshift;	/* 再送信回数の log(2)		*/
+	uint8_t		fsm_state;	/* FSM 状態			*/
+	uint8_t		dupacks;	/* 再送 ACK 数			*/
+
+#if defined(TCP_CFG_RWBUF_CSAVE) && defined(TCP_CFG_RWBUF_CSAVE_MAX_QUEUES)
+	uint16_t	rwbufq_entries;	/* 受信ウィンドバッファキューのエントリ数	*/
+#endif
+
+	} T_TCP_CEP;
+
+#define T_TCP6_CEP	T_TCP_CEP
+#define T_TCP4_CEP	T_TCP_CEP
+
+/*
+ * Time Wait 用 TCP 通信端点
+ */
+
+typedef struct t_tcp_twcep {
+	int_t		rbufsz;		/* 受信用ウィンドバッファサイズ	*/
+	T_TCP_TIME	timer_2msl;	/* 2MSL タイマ			*/
+	T_IPEP		dstaddr;	/* 相手のアドレス		*/
+	T_IPEP		myaddr;		/* 自分のアドレス		*/
+	T_TCP_SEQ	snd_una;	/* 未確認の最小送信 SEQ つまり	*/
+					/* 確認された最大送信 SEQ	*/
+	T_TCP_SEQ	rcv_nxt;	/* 受信を期待している最小の SEQ	*/
+	uint16_t	rwbuf_count;	/* 受信ウィンドバッファの使用中サイズ	*/
+	uint8_t		fsm_state;	/* FSM 状態			*/
+	uint8_t	flags;			/* 通信端点フラグ		*/
+
+	} T_TCP_TWCEP;
+
+#define T_TCP_CEP_DEFINED
+
+/*
+ *  TCP 通信端点の状態フラグ
+ */
+
+#define TCP_CEP_FLG_IPV4		ULONG_C(0x00000001)	/* IPv4 用。			*/
+#define TCP_CEP_FLG_ACK_NOW		ULONG_C(0x00000100)	/* 直ちに相手に ACK を送る。	*/
+#define TCP_CEP_FLG_DEL_ACK		ULONG_C(0x00000200)	/* ACK を遅延する。		*/
+#define TCP_CEP_FLG_SENT_FIN		ULONG_C(0x00000400)	/* FIN を送ってある。		*/
+#define TCP_CEP_FLG_NEED_SYN		ULONG_C(0x00000800)	/* SYN を送信する。		*/
+#define TCP_CEP_FLG_NEED_FIN		ULONG_C(0x00001000)	/* FIN を送信する。		*/
+#define TCP_CEP_FLG_FORCE		ULONG_C(0x00002000)	/* 強制送信。			*/
+#define TCP_CEP_FLG_NO_PUSH		ULONG_C(0x00004000)	/* push しない。		*/
+#define TCP_CEP_FLG_NO_DELAY		ULONG_C(0x00008000)	/* 遅延しない。			*/
+#define TCP_CEP_FLG_FORCE_CLEAR		ULONG_C(0x00010000)	/* 強制送信した後フラグをクリアーする。*/
+#define TCP_CEP_FLG_POST_OUTPUT		ULONG_C(0x00020000)	/* 送信を開始する。		*/
+#define TCP_CEP_FLG_RESERVE_OUTPUT	ULONG_C(0x00040000)	/* 送信を予約する。		*/
+#define TCP_CEP_FLG_DYNAMIC		ULONG_C(0x00100000)	/* 動的生成・削除可能通信端点。	*/
+#define TCP_CEP_FLG_VALID		ULONG_C(0x00200000)	/* 生成済みで有効な通信端点。	*/
+#define TCP_CEP_FLG_CLOSE_AFTER_OUTPUT	ULONG_C(0x00400000)	/* 送信した後コネクションを閉じる。*/
+#define TCP_CEP_FLG_RESTORE_NEXT_OUTPUT	ULONG_C(0x00800000)	/* 送信した後、snd_nxt を元に戻す。*/
+
+/* 送受信ウィンドバッファの省コピー機能 */
+#define TCP_CEP_FLG_WBCS_NBUF_REQ	ULONG_C(0x80000000)	/* ネットワークバッファ割当て要求*/
+#define TCP_CEP_FLG_WBCS_MASK		ULONG_C(0x70000000)	/* マスク			*/
+#define TCP_CEP_FLG_WBCS_FREE		ULONG_C(0x00000000)	/* 送信ウィンドバッファ未使用	*/
+#define TCP_CEP_FLG_WBCS_WOPEN_PEND	ULONG_C(0x10000000)	/* 相手の受信ウィンドの開き待ち	*/
+#define TCP_CEP_FLG_WBCS_NBUF_PEND	ULONG_C(0x20000000)	/* ネットワークバッファ予約待ち	*/
+#define TCP_CEP_FLG_WBCS_NBUF_RSVD	ULONG_C(0x30000000)	/* ネットワークバッファ予約済み	*/
+#define TCP_CEP_FLG_WBCS_NBUF_READY	ULONG_C(0x40000000)	/* ネットワークバッファ割当て済み*/
+#define TCP_CEP_FLG_WBCS_SEND_READY	ULONG_C(0x50000000)	/* 送信可能			*/
+#define TCP_CEP_FLG_WBCS_SENT		ULONG_C(0x60000000)	/* 送信済みで、ACK待ち		*/
+#define TCP_CEP_FLG_WBCS_ACKED		ULONG_C(0x70000000)	/* 送信済みで、ACK完了		*/
+
+/* 初期化から除外するフラグの定義 */
+#define TCP_CEP_FLG_NOT_CLEAR		(TCP_CEP_FLG_WBCS_NBUF_REQ|TCP_CEP_FLG_WBCS_MASK|\
+					 TCP_CEP_FLG_DYNAMIC|TCP_CEP_FLG_VALID|TCP_CEP_FLG_IPV4)
+
+/*
+ *  通信端点イベントフラグ
+ */
+
+#define TCP_CEP_EVT_ESTABLISHED		ULONG_C(0x00000001)	/* コネクション確立		*/
+#define TCP_CEP_EVT_CLOSED		ULONG_C(0x00000002)	/* 未使用状態			*/
+#define TCP_CEP_EVT_SWBUF_READY		ULONG_C(0x00000004)	/* 送信ウィンドバッファ空き	*/
+#define TCP_CEP_EVT_RWBUF_READY		ULONG_C(0x00000008)	/* 送信ウィンドバッファデータあり*/
+#define TCP_CEP_EVT_ALL			ULONG_C(0xffffffff)	/* 全イベント			*/
+
+/*
+ *  追加 API 機能・事象コード
+ */
+
+/* TCP 関係 */
+
+#define TFN_TCP_UNDEF		(0)
+
+/*
+ *  srtt:   平滑化された RTT
+ *  rttvar: 平滑化された分散
+ *  rtt:    測定された往復時間
+ *
+ *  平滑化された RTT (srtt) と平滑化された分散 (rttvar) を
+ *  整数型で計算するために、左シフトしてスケールする。
+ *  srtt は 2 進小数点以下 3 ビット、
+ *  rttvar は 2 進小数点以下 2 ビットを保持する。
+ */
+
+#define TCP_DELTA_SHIFT		2
+			/* 差分 = rtt/8 + srtt*7/8 の計算のためのシフト値	*/
+#define TCP_SRTT_SHIFT		(TCP_DELTA_SHIFT + 3)
+					/* srtt のシフト値、3(+2)ビット	*/
+#define TCP_RTTVAR_SHIFT	(TCP_DELTA_SHIFT + 2)
+					/* rttvar のシフト値、2(+2)ビット	*/
+#define TCP_SRTT_SCALE		(1<<TCP_SRTT_SHIFT)
+#define TCP_RTTVAR_SCALE	(1<<TCP_RTTVAR_SHIFT)
+
+/*
+ *  高速再転送を開始する再送 ACK 数のしきい値
+ */
+
+#define MAX_TCP_REXMT_THRESH	3
+
+/*
+ *  受信再構成キューでの TCP ヘッダ
+ */
+
+typedef struct t_tcp_q_hdr {
+	uint16_t	sport;		/* 送信元ポート番号			*/
+	uint16_t	dport;		/* 宛先ポート番号			*/
+
+	uint32_t	seq;		/* SEQ 番号				*/
+
+	T_NET_BUF 	*next;		/* 次のセグメント、元は ACK 番号(ack)	*/
+
+	uint8_t		doff;		/* データオフセット(上位4ビット)	*/
+	uint8_t		flags;		/* フラグ(下位6ビット)			*/
+	uint16_t	soff;		/* SDU オフセット、元はウィンドサイズ(win)	*/
+
+	uint16_t	slen;		/* SDU 長、元はチェックサム(sum)	*/
+	uint16_t	urp;		/* 緊急ポインタ（SDU 長補正）		*/
+	} __attribute__((packed, aligned(2)))T_TCP_Q_HDR;
+
+#define GET_TCP_Q_HDR(nbuf,thoff)	((T_TCP_Q_HDR*)((uint8_t*)((nbuf)->buf) + thoff))
+
+/*
+ *  オブジェクト ID の最小値の定義
+ */
+
+#define	TMIN_TCP_REPID		1			/* TCP      受付口 ID の最小値			*/
+#define	TMIN_TCP6_REPID		1			/* TCP/IPv6 受付口 ID の最小値			*/
+#define	TMIN_TCP4_REPID		(TNUM_TCP6_REPID+1)	/* TCP/IPv4 受付口 ID の最小値			*/
+
+#define	TMIN_TCP_CEPID		1			/* TCP      通信端点 ID の最小値			*/
+#define	TMIN_TCP6_CEPID		1			/* TCP/IPv6 通信端点 ID の最小値			*/
+#define	TMIN_TCP4_CEPID		(TNUM_TCP6_CEPID+1)	/* TCP/IPv4 通信端点 ID の最小値			*/
+
+#define	TMIN_TCP_TWCEPID	1			/* Time Wait 用 TCP 通信端点 ID の最小値	*/
+
+/*
+ *  制御セグメント（データなし）サイズのネットワークバッファ
+ */
+
+#if defined(IF_HDR_SIZE) && defined(IP_HDR_SIZE)
+
+typedef struct t_net_buf_cseg {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IF_HDR_SIZE + IP_HDR_SIZE + TCP_HDR_SIZE];
+				/* バッファ本体		*/
+	} T_NET_BUF_CSEG;
+
+#endif	/* of #if defined(IF_HDR_SIZE) && defined(IP_HDR_SIZE) */
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+typedef struct t_tcp_stats {
+	uint32_t	tcpActiveOpens;
+	uint32_t	tcpPassiveOpens;
+	uint32_t	tcpAttemptFails;
+	uint32_t	tcpEstabResets;
+/*	uint32_t	tcpCurrEstab;*/
+	uint32_t	tcpInSegs;
+	uint32_t	tcpOutSegs;
+	uint32_t	tcpRetransSegs;
+	uint32_t	tcpInErrs;
+	uint32_t	tcpOutRsts;
+} T_TCP_STATS;
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+/* TCP 受付口 */
+
+#define VALID_TCP6_REPID(id)	(TMIN_TCP6_REPID<=(id)&&(id)<=tmax_tcp6_repid)
+#define VALID_TCP4_REPID(id)	(TMIN_TCP4_REPID<=(id)&&(id)<=tmax_tcp4_repid)
+
+#define INDEX_TCP6_REP(id)	((id)-TMIN_TCP6_REPID)
+#define INDEX_TCP4_REP(id)	((id)-TMIN_TCP4_REPID)
+
+#define GET_TCP6_REP(id)	(&(tcp6_rep[INDEX_TCP6_REP(id)]))
+#define GET_TCP4_REP(id)	(&(tcp4_rep[INDEX_TCP4_REP(id)]))
+
+#define GET_TCP6_REPID(rep)	((ID)(((rep)-tcp6_rep)+TMIN_TCP6_REPID))
+#define GET_TCP4_REPID(rep)	((ID)(((rep)-tcp4_rep)+TMIN_TCP4_REPID))
+
+#ifdef TCP_CFG_EXTENTIONS
+
+#define VALID_TCP_REP(rep)	(((rep)->flags&TCP_REP_FLG_VALID)!=0)
+#define DYNAMIC_TCP_REP(rep)	(((rep)->flags&TCP_REP_FLG_DYNAMIC)!=0)
+
+#else	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+#define VALID_TCP_REP(rep)	(true)
+#define DYNAMIC_TCP_REP(rep)	(false)
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+/* TCP 通信端点 */
+
+#define VALID_TCP_CEPID(id)	(TMIN_TCP_CEPID<=(id)&&(id)<=tmax_tcp_cepid)
+#define INDEX_TCP_CEP(id)	((id)-TMIN_TCP_CEPID)
+
+#define GET_TCP_CEP(id)		(&(tcp_cep[INDEX_TCP_CEP(id)]))
+
+#define GET_TCP_CEPID(cep)	((ID)(((cep)-tcp_cep)+TMIN_TCP_CEPID))
+#define GET_TCP_TWCEPID(cep)	((ID)(((cep)-tcp_twcep)+TMIN_TCP_TWCEPID))
+
+#define VALID_TCP_CEP(cep)	(((cep)->flags&TCP_CEP_FLG_VALID)!=0)
+#define DYNAMIC_TCP_CEP(cep)	(((cep)->flags&TCP_CEP_FLG_DYNAMIC)!=0)
+#define TCP_IS_CEP_IPV6(cep)	(((cep)->flags&TCP_CEP_FLG_IPV4)==0)
+#define TCP_IS_CEP_IPV4(cep)	(((cep)->flags&TCP_CEP_FLG_IPV4)!=0)
+
+#define IS_TFN_TCP_RCV(t)	((t)==TFN_TCP_ACP_CEP||(t)==TFN_TCP_RCV_DAT||\
+				 (t)==TFN_TCP_CLS_CEP||\
+				 (t)==TFN_TCP_RCV_BUF||(t)==TFN_TCP_REL_BUF||\
+				 (t)==TFN_TCP_RCV_OOB)
+
+#define VALID_TFN_TCP_CAN(t)	((t)==TFN_TCP_ACP_CEP||(t)==TFN_TCP_CON_CEP||\
+				 (t)==TFN_TCP_CLS_CEP||\
+				 (t)==TFN_TCP_SND_DAT||(t)==TFN_TCP_RCV_DAT||\
+				 (t)==TFN_TCP_GET_BUF||(t)==TFN_TCP_RCV_BUF||\
+				 (t)==TFN_TCP_SND_OOB||\
+				 (t)==TFN_TCP_ALL)
+
+#define VALID_URG_POINTER(urg)	(TCP_CFG_URG_OFFSET==0||urg!=0)
+
+/*
+ *  全域変数
+ */
+
+extern uint8_t tcp_initialized;
+
+extern T_TCP_STATS tcp_stats;
+
+/* TCP 受付口 */
+
+extern T_TCP6_REP tcp6_rep[];
+extern T_TCP4_REP tcp4_rep[];
+
+#if defined(SUPPORT_INET6)
+#define tcp_rep	tcp6_rep
+#elif defined(SUPPORT_INET4)
+#define tcp_rep	tcp4_rep
+#endif
+
+extern const ID tmax_tcp_repid;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+extern const ID tmax_tcp6_repid;
+extern const ID tmax_tcp4_repid;
+#else
+#define tmax_tcp6_repid	tmax_tcp_repid
+#define tmax_tcp4_repid	tmax_tcp_repid
+#endif
+
+/* TCP 通信端点 */
+
+extern T_TCP_CEP tcp_cep[];
+extern T_TCP_TWCEP tcp_twcep[];
+
+extern const ID tmax_tcp_cepid;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+extern const ID tmax_tcp6_cepid;
+extern const ID tmax_tcp4_cepid;
+#else
+#define tmax_tcp6_cepid	tmax_tcp_cepid
+#define tmax_tcp4_cepid	tmax_tcp_cepid
+#endif
+
+/*
+ *  Inline 関数
+ */
+
+#ifndef TCP_CFG_RWBUF_CSAVE
+
+/*
+ *  TCP 通信端点の受信ウィンドバッファの省コピー機能が
+ *  無効の場合は何もしないためのダミーの関数
+ */
+
+/*
+ *  tcp_free_rwbufq -- 受信ウィンドバッファキューを解放する。
+ */
+
+Inline void
+tcp_free_rwbufq_ncs (T_TCP_CEP *cep)
+{
+	}
+
+#endif	/* of #ifndef TCP_CFG_RWBUF_CSAVE */
+
+#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
+
+/*
+ *  TCP 通信端点の送信ウィンドバッファの省コピー機能のみが
+ *  有効の場合は何もしないためのダミーの関数
+ */
+
+/*
+ *  tcp_read_swbuf_cs -- 送信ウィンドバッファからデータを読み出す。
+ */
+
+Inline void
+tcp_read_swbuf_cs (T_TCP_CEP *cep, T_NET_BUF *output, uint_t len, uint_t doff)
+{
+	}
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+#ifndef TCP_CFG_SWBUF_CSAVE
+
+/*
+ *  TCP 通信端点の送信ウィンドバッファの省コピー機能が
+ *  無効の場合は何もしないためのダミーの関数
+ */
+
+/*
+ *  tcp_free_swbufq -- 送信ウィンドバッファキューを解放する。
+ */
+
+Inline void
+tcp_free_swbufq_ncs (T_TCP_CEP *cep)
+{
+	}
+
+/*
+ *  tcp_alloc_swbuf -- 送信ウィンドバッファ用のネットワークバッファの割り当てを指示する。
+ */
+
+Inline void
+tcp_alloc_swbuf_ncs (T_TCP_CEP *cep)
+{
+	}
+
+/*
+ *  tcp_push_res_nbuf -- ネットワークバッファを予約する。
+ */
+
+Inline T_NET_BUF *
+tcp_push_res_nbuf_ncs (T_NET_BUF *nbuf)
+{
+	return nbuf;
+	}
+
+/*
+ *  tcp_pull_res_nbuf -- 予約してあるネットワークバッファ返す。
+ */
+
+Inline T_NET_BUF *
+tcp_pull_res_nbuf_ncs (ATR nbatr)
+{
+	return NULL;
+	}
+
+#endif	/* of #ifndef TCP_CFG_SWBUF_CSAVE */
+
+/*
+ *  TCP 通信端点の受信ウィンドバッファの省コピー機能の切り替えマクロ
+ */
+
+#ifdef TCP_CFG_RWBUF_CSAVE
+
+#ifdef TCP_CFG_RWBUF_CSAVE_ONLY
+
+#define TCP_FREE_RWBUFQ(cep)			tcp_free_rwbufq_cs(cep)
+#define TCP_DROP_RWBUF(cep,len)			tcp_drop_rwbuf_cs(cep,len)
+#define TCP_READ_RWBUF(cep,data,len)		tcp_read_rwbuf_cs(cep,data,len)
+#define TCP_GET_RWBUF_ADDR(cep,buf)		tcp_get_rwbuf_addr_cs(cep,buf)
+#define TCP_WRITE_RWBUF(cep,input,thoff)	tcp_write_rwbuf_cs(cep,input,thoff)
+
+#else	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+#define TCP_FREE_RWBUFQ(cep)			tcp_free_rwbufq(cep)
+#define TCP_DROP_RWBUF(cep,len)			tcp_drop_rwbuf(cep,len)
+#define TCP_READ_RWBUF(cep,data,len)		tcp_read_rwbuf(cep,data,len)
+#define TCP_GET_RWBUF_ADDR(cep,buf)		tcp_get_rwbuf_addr(cep,buf)
+#define TCP_WRITE_RWBUF(cep,input,thoff)	tcp_write_rwbuf(cep,input,thoff)
+
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+#else	/* of #ifdef TCP_CFG_RWBUF_CSAVE */
+
+#define TCP_FREE_RWBUFQ(cep)			tcp_free_rwbufq_ncs(cep)
+#define TCP_DROP_RWBUF(cep,len)			tcp_drop_rwbuf_ncs(cep,len)
+#define TCP_READ_RWBUF(cep,data,len)		tcp_read_rwbuf_ncs(cep,data,len)
+#define TCP_GET_RWBUF_ADDR(cep,buf)		tcp_get_rwbuf_addr_ncs(cep,buf)
+#define TCP_WRITE_RWBUF(cep,input,thoff)	tcp_write_rwbuf_ncs(cep,input,thoff)
+
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE */
+
+/*
+ *  TCP 通信端点の送信ウィンドバッファの省コピー機能の切り替えマクロ
+ */
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+#define TCP_PUSH_RES_NBUF(nbuf)			tcp_push_res_nbuf(nbuf)
+#define TCP_PULL_RES_NBUF(atr)			tcp_pull_res_nbuf(atr)
+
+#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
+
+#define TCP_FREE_SWBUFQ(cep)			tcp_free_swbufq_cs(cep)
+#define TCP_ALLOC_SWBUF(cep)			tcp_alloc_swbuf_cs(cep)
+#define TCP_DROP_SWBUF(cep,len)			tcp_drop_swbuf_cs(cep,len)
+#define TCP_WRITE_SWBUF(cep,data,len)		tcp_write_swbuf_cs(cep,data,len)
+#define TCP_READ_SWBUF(cep,output,len,doff)	tcp_read_swbuf_cs(cep,output,len,doff)
+#define TCP_WAIT_SWBUF(cep,tmout)		tcp_wait_swbuf_cs(cep,tmout)
+#define TCP_GET_SWBUF_ADDR(cep,buf)		tcp_get_swbuf_addr_cs(cep,buf)
+#define TCP_SEND_SWBUF(cep,len)			tcp_send_swbuf_cs(cep,len)
+#define TCP_IS_SWBUF_FULL(cep)			tcp_is_swbuf_full_cs(cep)
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+#define TCP_FREE_SWBUFQ(cep)			tcp_free_swbufq(cep)
+#define TCP_ALLOC_SWBUF(cep)			tcp_alloc_swbuf(cep)
+#define TCP_DROP_SWBUF(cep,len)			tcp_drop_swbuf(cep,len)
+#define TCP_WRITE_SWBUF(cep,data,len)		tcp_write_swbuf(cep,data,len)
+#define TCP_READ_SWBUF(cep,output,len,doff)	tcp_read_swbuf(cep,output,len,doff)
+#define TCP_WAIT_SWBUF(cep,tmout)		tcp_wait_swbuf(cep,tmout)
+#define TCP_GET_SWBUF_ADDR(cep,buf)		tcp_get_swbuf_addr(cep,buf)
+#define TCP_SEND_SWBUF(cep,len)			tcp_send_swbuf(cep,len)
+#define TCP_IS_SWBUF_FULL(cep)			tcp_is_swbuf_full(cep)
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+#define TCP_READ_SWBUF(cep,output,len,doff)	tcp_read_swbuf_ncs(cep,output,len,doff)
+#define TCP_FREE_SWBUFQ(cep)			tcp_free_swbufq_ncs(cep)
+#define TCP_ALLOC_SWBUF(cep)			tcp_alloc_swbuf_ncs(cep)
+#define TCP_PUSH_RES_NBUF(nbuf)			tcp_push_res_nbuf_ncs(nbuf)
+#define TCP_PULL_RES_NBUF(atr)			tcp_pull_res_nbuf_ncs(atr)
+#define TCP_DROP_SWBUF(cep,len)			tcp_drop_swbuf_ncs(cep,len)
+#define TCP_WRITE_SWBUF(cep,data,len)		tcp_write_swbuf_ncs(cep,data,len)
+#define TCP_WAIT_SWBUF(cep,tmout)		tcp_wait_swbuf_ncs(cep,tmout)
+#define TCP_GET_SWBUF_ADDR(cep,buf)		tcp_get_swbuf_addr_ncs(cep,buf)
+#define TCP_SEND_SWBUF(cep,len)			tcp_send_swbuf_ncs(cep,len)
+#define TCP_IS_SWBUF_FULL(cep)			tcp_is_swbuf_full_ncs(cep)
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+/*
+ *  関数
+ */
+
+extern uint_t tcp_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+extern void tcp_init (void);
+extern void tcp_init_iss (void);
+extern T_TCP_CEP *tcp_close (T_TCP_CEP *cep);
+extern T_TCP_CEP *tcp_drop  (T_TCP_CEP *cep, ER err);
+extern void tcp_respond (T_NET_BUF *nbuf, T_TCP_CEP *cep,
+                         T_TCP_SEQ ack, T_TCP_SEQ seq, uint_t rbfree, uint8_t flags);
+extern ER tcp_get_segment (T_NET_BUF **nbuf, T_TCP_CEP *cep,
+                           uint_t optlen, uint_t len, uint_t maxlen, ATR nbatr, TMO tmout);
+extern ER tcpn_get_segment (T_NET_BUF **nbuf, T_TCP_CEP *cep,
+                            uint_t optlen, uint_t len, uint_t maxlen, ATR nbatr, TMO tmout);
+extern void tcp_init_cep (T_TCP_CEP *cep);
+extern void tcp_notify (T_NET_BUF *input, int code);
+extern T_TCP_TIME tcp_rexmt_val (T_TCP_CEP *cep);
+extern void tcp_set_persist_timer (T_TCP_CEP *cep);
+extern void tcp_cancel_timers (T_TCP_CEP *cep);
+extern void tcp_alloc_auto_port (T_TCP_CEP *cep);
+extern ER tcp_alloc_port (T_TCP_CEP *cep, uint16_t portno);
+extern ER tcp_lock_cep (ID cepid, T_TCP_CEP **p_cep, FN tfn);
+extern void tcp_free_reassq (T_TCP_CEP *cep);
+extern ER tcp_can_send_more (T_TCP_CEP *cep, FN fncd, TMO tmout);
+extern ER tcp_can_recv_more (ER *error, T_TCP_CEP *cep, FN fncd, TMO tmout);
+extern uint8_t tcp_move_ra2rw (T_TCP_CEP *cep, uint8_t flags);
+extern uint8_t tcp_write_raque (T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, uint8_t flags);
+extern ER tcp_wait_rwbuf (T_TCP_CEP *cep, TMO tmout);
+extern T_TCP_CEP *tcp_user_closed (T_TCP_CEP *cep);
+extern T_TCP_CEP *tcp_find_cep (T_NET_BUF *input, uint_t off);
+extern T_TCP_TWCEP*tcp_find_twcep (T_NET_BUF *input, uint_t off);
+extern bool_t tcp_is_addr_accept (T_NET_BUF *input, uint_t off);
+extern void tcp_move_twcep (T_TCP_CEP *cep);
+
+/*
+ *  TCP 通信端点の受信ウィンドバッファ用関数
+ */
+
+/*
+ *  TCP 通信端点の受信ウィンドバッファの省コピー機能が有効の場合、
+ *  関数の選択に使用する。
+ */
+
+extern void tcp_free_rwbufq (T_TCP_CEP *cep);
+extern void tcp_drop_rwbuf (T_TCP_CEP *cep, uint_t len);
+extern void tcp_write_rwbuf (T_TCP_CEP *cep, T_NET_BUF *input, uint_t tcpoff);
+extern uint_t tcp_read_rwbuf (T_TCP_CEP *cep, void *data, uint_t len);
+extern uint_t tcp_get_rwbuf_addr (T_TCP_CEP *cep, void **p_buf);
+
+/*
+ *  TCP 通信端点の受信ウィンドバッファの省コピー機能用関数
+ */
+
+extern void tcp_free_rwbufq_cs (T_TCP_CEP *cep);
+extern void tcp_drop_rwbuf_cs (T_TCP_CEP *cep, uint_t len);
+extern void tcp_write_rwbuf_cs (T_TCP_CEP *cep, T_NET_BUF *input, uint_t tcpoff);
+extern uint_t tcp_read_rwbuf_cs (T_TCP_CEP *cep, void *data, uint_t len);
+extern uint_t tcp_get_rwbuf_addr_cs (T_TCP_CEP *cep, void **p_buf);
+
+/*
+ *  TCP 通信端点の受信ウィンドバッファの【非】省コピー機能用関数
+ */
+
+extern void tcp_free_rwbufq_ncs (T_TCP_CEP *cep);
+extern void tcp_drop_rwbuf_ncs (T_TCP_CEP *cep, uint_t len);
+extern void tcp_write_rwbuf_ncs (T_TCP_CEP *cep, T_NET_BUF *input, uint_t tcpoff);
+extern uint_t tcp_read_rwbuf_ncs (T_TCP_CEP *cep, void *data, uint_t len);
+extern uint_t tcp_get_rwbuf_addr_ncs (T_TCP_CEP *cep, void **p_buf);
+
+/*
+ *  TCP 通信端点の送信ウィンドバッファ用関数
+ */
+
+/*
+ *  TCP 通信端点の送信ウィンドバッファの省コピー機能が有効の場合、
+ *  関数の選択に使用する。
+ */
+
+extern void tcp_free_swbufq (T_TCP_CEP *cep);
+extern void tcp_drop_swbuf (T_TCP_CEP *cep, uint_t len);
+extern ER_UINT tcp_write_swbuf (T_TCP_CEP *cep, void *data, uint_t len);
+extern void tcp_read_swbuf (T_TCP_CEP *cep, T_NET_BUF *output, uint_t len, uint_t doff);
+extern void tcp_send_swbuf (T_TCP_CEP *cep, uint_t len);
+extern ER_UINT tcp_get_swbuf_addr (T_TCP_CEP *cep, void **p_buf);
+extern ER tcp_wait_swbuf (T_TCP_CEP *cep, TMO tmout);
+extern T_NET_BUF *tcp_push_res_nbuf (T_NET_BUF *buf);
+extern T_NET_BUF *tcp_pull_res_nbuf (ATR nbatr);
+extern void tcp_alloc_swbuf (T_TCP_CEP *cep);
+extern bool_t tcp_is_swbuf_full (T_TCP_CEP *cep);
+extern void tcp_init_swbuf (T_TCP_CEP *cep);
+
+/*
+ *  TCP 通信端点の送信ウィンドバッファの省コピー機能用関数
+ */
+
+extern void tcp_free_swbufq_cs (T_TCP_CEP *cep);
+extern void tcp_drop_swbuf_cs (T_TCP_CEP *cep, uint_t len);
+extern ER_UINT tcp_write_swbuf_cs (T_TCP_CEP *cep, void *data, uint_t len);
+extern void tcp_read_swbuf_cs (T_TCP_CEP *cep, T_NET_BUF *output, uint_t len, uint_t doff);
+extern void tcp_send_swbuf_cs (T_TCP_CEP *cep, uint_t len);
+extern ER_UINT tcp_get_swbuf_addr_cs (T_TCP_CEP *cep, void **p_buf);
+extern ER tcp_wait_swbuf_cs (T_TCP_CEP *cep, TMO tmout);
+extern void tcp_alloc_swbuf_cs (T_TCP_CEP *cep);
+extern bool_t tcp_is_swbuf_full_cs (T_TCP_CEP *cep);
+
+/*
+ *  TCP 通信端点の送信ウィンドバッファの【非】省コピー機能用関数
+ */
+
+extern void tcp_free_swbufq_ncs (T_TCP_CEP *cep);
+extern void tcp_drop_swbuf_ncs (T_TCP_CEP *cep, uint_t len);
+extern ER_UINT tcp_write_swbuf_ncs (T_TCP_CEP *cep, void *data, uint_t len);
+extern void tcp_read_swbuf_ncs (T_TCP_CEP *cep, T_NET_BUF *output, uint_t len, uint_t doff);
+extern void tcp_send_swbuf_ncs (T_TCP_CEP *cep, uint_t len);
+extern ER_UINT tcp_get_swbuf_addr_ncs (T_TCP_CEP *cep, void **p_buf);
+extern ER tcp_wait_swbuf_ncs (T_TCP_CEP *cep, TMO tmout);
+extern T_NET_BUF *tcp_push_res_nbuf_ncs (T_NET_BUF *buf);
+extern T_NET_BUF *tcp_pull_res_nbuf_ncs (ATR nbatr);
+extern void tcp_alloc_swbuf_ncs (T_TCP_CEP *cep);
+extern bool_t tcp_is_swbuf_full_ncs (T_TCP_CEP *cep);
+
+/*
+ *  TCP ヘッダのトレース出力機能用関数
+ */
+extern void tcp_output_trace (T_NET_BUF *output, T_TCP_CEP *cep);
+extern void tcp_input_trace  (T_NET_BUF *input,  T_TCP_CEP *cep);
+
+/* TCP 出力タスク */
+
+extern void	tcp_output_task(intptr_t exinf);
+
+#endif	/* of #ifndef _TCP_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcpn_usrreq.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcpn_usrreq.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/tcpn_usrreq.c	(revision 398)
@@ -0,0 +1,758 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	From: @(#)tcp_usrreq.c	8.2 (Berkeley) 1/3/94
+ * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.40.2.3 1999/08/29 16:29:57 peter Exp $
+ */
+
+#ifdef TCP_CFG_EXTENTIONS
+
+#if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0)
+
+/*
+ *  tcp_cre_rep -- TCP 受付口の生成【拡張機能】
+ */
+
+#ifdef __tcp_cre_rep
+
+ER
+TCP_CRE_REP (ID repid, T_TCPN_CREP *pk_crep)
+{
+	T_TCP_REP	*rep;
+	ER		error;
+
+	/* TCP 受付口 ID をチェックする。*/
+	if (!VALID_TCP_REPID(repid))
+		return E_ID;
+
+	/* pk_crep が NULL ならエラー */
+	if (pk_crep == NULL)
+		return E_PAR;
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
+	 * IPv4 射影アドレスが指定されたらエラー
+	 */
+	if (in6_is_addr_ipv4mapped(&pk_crep->myaddr.ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+	/* TCP 受付口を得る。*/
+	rep = GET_TCP_REP(repid);
+
+	/* TCP 受付口が、動的生成用でなければエラー */
+	if (!DYNAMIC_TCP_REP(rep))
+		return E_ID;
+
+	/* 受付口をロックする。*/
+	syscall(wai_sem(rep->semid_lock));
+
+	/*
+	 * TCP 受付口をチェックする。生成済みであればエラー
+	 */
+	if (VALID_TCP_REP(rep))
+		error = E_OBJ;
+	else {
+
+		/* TCP 受付口生成情報をコピーする。*/
+		rep->repatr = pk_crep->repatr;			/* 受付口属性		*/
+		rep->myaddr.ipaddr = pk_crep->myaddr.ipaddr;	/* 自分のアドレス	*/
+		rep->myaddr.portno = pk_crep->myaddr.portno;	/* 自分のアドレス	*/
+
+		/* TCP 受付口を生成済みにする。*/
+		rep->flags |= TCP_REP_FLG_VALID;
+		error = E_OK;
+		}
+
+	/* 受付口のロックを解除する。*/
+	syscall(sig_sem(rep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_cre_rep */
+
+#ifdef __tcp_del_rep
+
+/*
+ *  tcp_find_cep_rep -- TCP 受付口をリンクしている TCP 通信端点を得る。
+ */
+
+static T_TCP_CEP*
+TCP_FIND_CEP_REP (T_TCP_REP* rep)
+{
+	T_TCP_CEP*	cep;
+
+	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
+		if (cep->rep4 == rep)
+#else
+		if (cep->rep == rep)
+#endif
+			return cep;
+		}
+
+	return NULL;
+	}
+
+/*
+ *  tcp_del_rep_body -- TCP 受付口の削除【拡張機能】の本体
+ */
+
+static ER
+TCP_DEL_REP_BODY (ID repid)
+{
+	T_TCP_CEP	*cep;
+	T_TCP_REP	*rep;
+	ER		error = E_OK;
+
+	/* TCP 受付口 ID のチェックは終了している。*/
+
+	/* TCP 受付口を得る。*/
+	rep = GET_TCP_REP(repid);
+
+	/* TCP 受付口が、動的生成用でなければエラー */
+	if (!DYNAMIC_TCP_REP(rep))
+		return E_ID;
+
+	/* 受付口をロックする。*/
+	syscall(wai_sem(rep->semid_lock));
+
+	/* TCP 受付口をチェックする。未生成の場合はエラー */
+	if (!VALID_TCP_REP(rep))
+		error = E_NOEXS;
+	else {
+		if ((cep = TCP_FIND_CEP_REP(rep)) != NULL) {
+			/*
+			 * すでに受動オープンしているとき
+			 *（tcp_acp_cep が呼ばれているとき）は、
+			 * tcp_acp_cep を終了させる。
+			 */
+
+			/* 通信端点をロックする。*/
+			syscall(wai_sem(cep->semid_lock));
+
+			/*
+			 *  通信端点から受付口を解放し、
+			 *  イベントフラグをクローズに設定する。
+			 */
+			cep->rep = NULL;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+			cep->rep4 = NULL;
+#endif
+
+			cep->fsm_state = TCP_FSM_CLOSED;
+			cep->error = E_DLT;
+			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+			if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) {
+				if (IS_PTR_DEFINED(cep->callback)) {
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_DLT);
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+					ER	error = E_DLT;
+
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&error);
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+					}
+				else
+					error = E_OBJ;
+				cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+				}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+			cep->rcv_tskid = TA_NULL;
+			cep->rcv_tfn   = TFN_TCP_UNDEF;
+
+			/* 通信端点のロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+
+			}
+		else
+			error = E_OK;
+
+		/* TCP 受付口を未生成にする。*/
+		rep->flags &= ~TCP_REP_FLG_VALID;
+		}
+
+	/* 受付口のロックを解除する。*/
+	syscall(sig_sem(rep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_del_rep */
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0) */
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+#if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0)
+
+/*
+ *  tcp_acp_cep -- 接続要求待ち (受動オープン)【標準機能】
+ */
+
+#ifdef __tcp_acp_cep
+
+ER
+TCP_ACP_CEP (ID cepid, ID repid, T_IPEP *p_dstaddr, TMO tmout)
+{
+	T_TCP_REP	*rep;
+	T_TCP_CEP	*cep;
+	ER		error;
+	FLGPTN		flag;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	/*
+	 * API (tcp6_acp_cep と tcp_acp_cep) と、
+	 * TCP通信端点のプロトコルが矛盾していればエラー
+	 */
+
+#if API_PROTO == API_PROTO_IPV6
+
+	if (GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4)
+		return E_ID;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV6 */
+
+#if API_PROTO == API_PROTO_IPV4
+
+	if ((GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4) == 0)
+		return E_ID;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	/* TCP 受付口をチェックする。*/
+	if (!VALID_TCP_REPID(repid))
+		return E_ID;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* p_dstaddr が NULL ならエラー */
+	if (p_dstaddr == NULL)
+		return E_PAR;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/* p_dstaddr が NULL か、tmout が TMO_NBLK ならエラー */
+	if (p_dstaddr == NULL || tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
+	 * IPv4 射影アドレスが指定されたらエラー
+	 */
+	if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_ACP_CEP)) != E_OK)
+		return error;
+
+	/* CEP の FSM がクローズ状態でなければエラー。*/
+	if (cep->fsm_state != TCP_FSM_CLOSED) {
+		error = E_OBJ;
+		goto err_ret;
+		}
+	syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
+
+	/* TCP 通信端点を初期化する。*/
+	tcp_init_cep(cep);
+
+	/* TCP 受付口を得る。*/
+
+	rep = GET_TCP_REP(repid);
+
+#ifdef TCP_CFG_EXTENTIONS
+
+	/* TCP 受付口をロックする。*/
+	syscall(wai_sem(rep->semid_lock));
+
+	/* TCP 受付口をチェックする。*/
+	if (!VALID_TCP_REP(rep)) {
+		syscall(sig_sem(rep->semid_lock));
+		error = E_NOEXS;
+		goto err_ret;
+		}
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+	/* TCP 通信端点にTCP受付口を記録する。*/
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+#if API_PROTO == API_PROTO_IPV6
+
+	cep->rep = rep;
+
+#else	/* of #if API_PROTO == API_PROTO_IPV6 */
+
+	cep->rep4 = rep;
+
+#endif	/*of #if API_PROTO == API_PROTO_IPV6 */
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	cep->rep = rep;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+#ifdef TCP_CFG_EXTENTIONS
+
+	/* TCP 受付口のロックを解除する。*/
+	syscall(sig_sem(rep->semid_lock));
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+	/* TCP 受付口のアドレスをコピーする。*/
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
+
+	if (rep->myaddr.ipaddr == IPV4_ADDRANY)
+		memcpy(&cep->myaddr.ipaddr, &in6_addr_unspecified,
+		                      sizeof(in6_addr_unspecified));
+	else
+		in6_make_ipv4mapped(&cep->myaddr.ipaddr, rep->myaddr.ipaddr);
+	cep->myaddr.portno = rep->myaddr.portno;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+	cep->myaddr = rep->myaddr;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+#if API_PROTO == API_PROTO_IPV4
+
+	/* TCP 通信端点のネットワーク層プロトコルを設定する。*/
+	cep->flags |= TCP_CEP_FLG_IPV4;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+	/* 通信端点を設定する。*/
+	cep->fsm_state = TCP_FSM_LISTEN;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* タイムアウトをチェックする。*/
+	if (tmout == TMO_NBLK) {
+		/* ノンブロッキングコール */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+#if API_PROTO == API_PROTO_IPV4
+
+		cep->p_dstaddr4   = p_dstaddr;
+		cep->p_dstaddr    = NULL;
+
+#else	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+		cep->p_dstaddr4   = NULL;
+		cep->p_dstaddr    = p_dstaddr;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		cep->p_dstaddr    = p_dstaddr;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		cep->rcv_nblk_tfn = TFN_TCP_ACP_CEP;
+		return E_WBLK;
+		}
+	else {
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		/*
+		 *  FSM が ESTABLISHED になるまで待つ。
+		 *  FSM が CLOSED になった場合は、エラーが発生したことを意味している。
+		 */
+		error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
+		                                  TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
+		if (error == E_OK) {
+			if (cep->error != E_OK)
+				error = cep->error;
+			else if (cep->fsm_state == TCP_FSM_CLOSED)
+				error = E_TMOUT;
+			}
+
+		syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
+
+		if (error == E_OK) {
+			/* 相手のアドレスをコピーする。*/
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
+			p_dstaddr->ipaddr = ntohl(cep->dstaddr.ipaddr.s6_addr32[3]);
+			p_dstaddr->portno = cep->dstaddr.portno;
+#else
+			*p_dstaddr = cep->dstaddr;
+#endif
+			}
+		else {
+			/*
+			 *  通信端点から受付口を解放し、
+			 *  イベントフラグをクローズに設定する。
+			 */
+			cep->rep = NULL;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+			cep->rep4 = NULL;
+#endif
+
+			cep->fsm_state = TCP_FSM_CLOSED;
+			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+			}
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+err_ret:
+	cep->rcv_tskid = TA_NULL;
+	cep->rcv_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_acp_cep */
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0) */
+
+/*
+ *  tcp_con_cep -- 接続要求 (能動オープン)【標準機能】
+ */
+
+#ifdef __tcp_con_cep
+
+ER
+TCP_CON_CEP (ID cepid, T_IPEP *p_myaddr, T_IPEP *p_dstaddr, TMO tmout)
+{
+	T_TCP_CEP	*cep;
+	ER		error;
+	FLGPTN		flag;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	/*
+	 * API (tcp6_acp_cep と tcp_acp_cep) と、
+	 * TCP通信端点のプロトコルが矛盾していればエラー
+	 */
+
+#if API_PROTO == API_PROTO_IPV6
+
+	if (GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4)
+		return E_ID;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV6 */
+
+#if API_PROTO == API_PROTO_IPV4
+
+	if ((GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4) == 0)
+		return E_ID;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	/*
+	 *  あて先がマルチキャストアドレスならエラー
+	 */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
+
+	if (IN4_IS_ADDR_MULTICAST(p_dstaddr->ipaddr))
+		return E_PAR;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+	if (IN_IS_ADDR_MULTICAST(&p_dstaddr->ipaddr))
+		return E_PAR;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
+	 * IPv4 射影アドレスが指定されたらエラー
+	 */
+	if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/*
+	 *  p_dstaddr または p_myaddr が NULL ならエラー
+	 */
+	if (p_myaddr == NULL || p_dstaddr == NULL)
+		return E_PAR;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  p_dstaddr または p_myaddr が NULL 、
+	 *  tmout が TMO_NBLK ならエラー
+	 */
+	if (p_myaddr == NULL || p_dstaddr == NULL || tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_CON_CEP)) != E_OK)
+		return error;
+
+	/* CEP の FSM がクローズ状態でなければエラー。*/
+	if (cep->fsm_state != TCP_FSM_CLOSED) {
+		error = E_OBJ;
+		goto err_ret;
+		}
+	syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
+
+	/* シーケンス番号を初期化する。*/
+	if (tcp_iss == 0)
+		tcp_init_iss();
+
+	/* 通信端点を初期化する。*/
+	tcp_init_cep(cep);
+
+	/*
+	 *  IP アドレスを設定する。
+	 *  p_myaddr が NADR (-1) ではなく、自 IP アドレスが ANY でなければ、
+	 *  指定された IP アドレスを割り当てる。
+	 */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
+
+	if (p_myaddr != NADR && !IN4_IS_ADDR_ANY(&p_myaddr->ipaddr))
+		in6_make_ipv4mapped(&cep->myaddr.ipaddr, p_myaddr->ipaddr);
+	else
+		in6_make_ipv4mapped(&cep->myaddr.ipaddr, IF_GET_IFNET()->in4_ifaddr.addr);
+
+	in6_make_ipv4mapped(&cep->dstaddr.ipaddr, p_dstaddr->ipaddr);
+	cep->dstaddr.portno = p_dstaddr->portno;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+	if (p_myaddr != NADR && !IN_IS_ADDR_ANY(&p_myaddr->ipaddr))
+		cep->myaddr.ipaddr = p_myaddr->ipaddr;
+	else {
+		if (IN_ADDRWITHIFP(IF_GET_IFNET(), &cep->myaddr.ipaddr, &p_dstaddr->ipaddr) == NULL) {
+			error = E_PAR;
+			goto err_ret;
+			}
+		}
+
+	cep->dstaddr   = *p_dstaddr;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+#if API_PROTO == API_PROTO_IPV4
+
+	/* TCP 通信端点のネットワーク層プロトコルを設定する。*/
+	cep->flags |= TCP_CEP_FLG_IPV4;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+	/* 通信端点を設定する。*/
+	//NET_DEBUG_TCP5("tcp_con_cep3[c=%d,d=%lI.%d,s=%lI.%d]\n",
+	cep->fsm_state = TCP_FSM_SYN_SENT;
+	cep->iss       = tcp_iss;
+	cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_INIT;
+	tcp_iss += TCP_ISS_INCR() / 2;
+	init_send_seq(cep);
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* タイムアウトをチェックする。*/
+	if (tmout == TMO_NBLK) {
+		/* ノンブロッキングコール */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+#if API_PROTO == API_PROTO_IPV4
+
+		cep->p_dstaddr4   = p_dstaddr;
+		cep->p_myaddr4    = p_myaddr;
+		cep->p_dstaddr    = NULL;
+		cep->p_myaddr     = NADR;
+
+#else	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+		cep->p_dstaddr4   = NULL;
+		cep->p_myaddr4    = NADR;
+		cep->p_dstaddr    = p_dstaddr;
+		cep->p_myaddr     = p_myaddr;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		cep->p_dstaddr    = p_dstaddr;
+		cep->p_myaddr     = p_myaddr;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		cep->snd_nblk_tfn = TFN_TCP_CON_CEP;
+
+		/* コネクションの開設をポストする。*/
+		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		return E_WBLK;
+		}
+	else {
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		/*
+		 *  p_myaddr が NADR (-1) か、
+		 *  自ポート番号が TCP_PORTANY なら、自動で割り当てる。
+		 */
+		if (p_myaddr == NADR || p_myaddr->portno == TCP_PORTANY)
+			tcp_alloc_auto_port(cep);
+		else if ((error = tcp_alloc_port(cep, p_myaddr->portno)) != E_OK)
+			goto err_ret;
+
+		/* コネクションの開設をポストする。*/
+		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+
+		/*
+		 *  イベントが ESTABLISHED になるまで待つ。
+		 *  イベントが CLOSED になった場合は、何らかのエラーが発生したか、
+		 *  接続要求が拒否されたことを意味している。
+		 */
+		error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
+		                                  TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
+		if (error == E_OK) {
+			if (cep->error != E_OK)
+				error = cep->error;
+			else if (cep->fsm_state == TCP_FSM_CLOSED)
+				error = E_CLS;
+			}
+
+		syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
+
+		if (error != E_OK) {
+			/*
+			 *  通信端点から受付口を解放し、
+			 *  イベントフラグをクローズに設定する。
+			 */
+			cep->rep = NULL;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+			cep->rep4 = NULL;
+#endif
+
+			cep->fsm_state = TCP_FSM_CLOSED;
+			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+			}
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+err_ret:
+	cep->snd_tskid = TA_NULL;
+	cep->snd_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_con_cep */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp.cfg	(revision 398)
@@ -0,0 +1,63 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP で使用するカーネルオブジェクト
+ */
+
+#ifdef SUPPORT_UDP
+
+/*
+ *  ノンブロッキングコールを行う場合に組み込むタスクとセマフォ
+ */
+
+#ifdef UDP_CFG_NON_BLOCKING
+
+CRE_TSK(UDP_OUTPUT_TASK, {
+	TA_HLNG,
+	0,
+	udp_output_task,
+	UDP_OUT_TASK_PRIORITY,
+	UDP_OUT_TASK_STACK_SIZE,
+	NULL
+	});
+
+/* セマフォ */
+
+CRE_SEM(SEM_UDP_POST_OUTPUT,	{ TA_TPRI, 0, 1 });
+
+#endif	/* of #ifdef UDP_CFG_NON_BLOCKING */
+
+CRE_SEM(SEM_UDP_CEP,		{ TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef SUPPORT_UDP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp.h	(revision 398)
@@ -0,0 +1,87 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)udp.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/udp.h,v 1.6.4.1 1999/08/29 16:29:58 peter Exp $
+ */
+ 
+#ifndef _UDP_H_
+#define _UDP_H_
+
+/*
+ *  UDP ヘッダ、RFC768 参照
+ */
+
+typedef struct t_udp_hdr {
+	uint16_t	sport;		/* 送信元ポート番号	*/
+	uint16_t	dport;		/* 宛先ポート番号	*/
+
+	uint16_t	ulen;		/* データグラム長	*/
+	uint16_t	sum;		/* チェックサム		*/
+	} __attribute__((packed, aligned(2)))T_UDP_HDR;
+
+#define UDP_HDR_SIZE			(sizeof(T_UDP_HDR))
+
+#endif	/* of #ifndef _UDP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp4_input.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp4_input.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp4_input.c	(revision 398)
@@ -0,0 +1,93 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+/*
+ *  udp_reply_no_port -- 送信元にポートが定義されていないことを通知する。
+ */
+
+void
+UDP_REPLY_NO_PORT (T_NET_BUF *input, uint_t off)
+{
+	T_UDP_HDR	*udph;
+
+	udph = (T_UDP_HDR *)(input->buf + off);
+
+	NET_COUNT_MIB(udp_stats.udpNoPorts, 1);
+
+	/* ローカル IP アドレスに届いたデータグラムのみ ICMP エラーを通知する。*/
+	if (ntohl(GET_IP4_HDR(input)->dst) == IF_GET_IFNET()->in4_ifaddr.addr) {
+		syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport));
+
+		icmp_error(ICMP4_UNREACH_PORT, input);
+		/* icmp_error では、ネットワークバッファ input を返却しないので下へ抜ける。*/
+	
+		}
+	syscall(rel_net_buf(input));
+
+	NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
+	NET_COUNT_MIB(udp_stats.udpInErrors, 1);
+	NET_COUNT_MIB(udp_stats.udpNoPorts, 1);
+	}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp4_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp4_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp4_subr.c	(revision 398)
@@ -0,0 +1,183 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce 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.
+ */
+
+#ifdef SUPPORT_IGMP
+#define UDP4_IS_ADDR_MULTICAST igmp_is_joined_group
+#else
+#define UDP4_IS_ADDR_MULTICAST IN4_IS_ADDR_MULTICAST
+#endif
+
+#ifdef DHCP_CFG
+#ifdef ETHER_CFG_MULTICAST
+/*
+ *  udp4_is_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
+ *
+ *    DHCP_CFG が定義されているときは、以下のデータグラムを受信する。
+ *
+ *      ・あて先アドレスがブロードキャスト
+ *      ・ローカルアドレスが未定義
+ */
+
+static bool_t
+udp4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IP4_HDR	*ip4h;
+	T_IN4_ADDR	dst;
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	ip4h = GET_IP4_HDR(input);
+	dst = ntohl(ip4h->dst);
+
+	if (ifp->in4_ifaddr.addr == IPV4_ADDRANY    ||
+		dst == IPV4_ADDR_BROADCAST ||
+		dst == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask) ||
+		UDP4_IS_ADDR_MULTICAST(dst))
+		return true;
+	else
+		return inn4_is_dstaddr_accept(myaddr, input);
+	}
+#else
+/*
+ *  udp4_is_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
+ *
+ *    DHCP_CFG が定義されているときは、以下のデータグラムを受信する。
+ *
+ *      ・あて先アドレスがブロードキャスト
+ *      ・ローカルアドレスが未定義
+ */
+
+static bool_t
+udp4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IP4_HDR	*ip4h;
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	ip4h = GET_IP4_HDR(input);
+
+	if (ifp->in4_ifaddr.addr == IPV4_ADDRANY    ||
+	    ntohl(ip4h->dst) == IPV4_ADDR_BROADCAST ||
+	    ntohl(ip4h->dst) == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask))
+		return true;
+	else
+		return inn4_is_dstaddr_accept(myaddr, input);
+	}
+#endif	/* of #ifdef ETHER_CFG_MULTICAST */
+#else
+#ifdef ETHER_CFG_MULTICAST
+
+/*
+ *  udp_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
+ *
+ *    以下の場合もデータグラムを受信する。
+ *
+ *      ・あて先アドレスがブロードキャスト
+ */
+
+static bool_t
+udp4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IP4_HDR	*ip4h;
+	T_IN4_ADDR	dst;
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	ip4h = GET_IP4_HDR(input);
+	dst = ntohl(ip4h->dst);
+
+	if (dst == IPV4_ADDR_BROADCAST ||
+	    dst == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask) ||
+		UDP4_IS_ADDR_MULTICAST(dst))
+		return true;
+	else
+		return inn4_is_dstaddr_accept(myaddr, input);
+	}
+
+#else	/* of #ifdef ETHER_CFG_MULTICAST */
+
+/*
+ *  udp4_is_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
+ *
+ *    以下の場合もデータグラムを受信する。
+ *
+ *      ・あて先アドレスがブロードキャスト
+ */
+
+static bool_t
+udp4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IP4_HDR	*ip4h;
+	T_IFNET		*ifp = IF_GET_IFNET();
+
+	ip4h = GET_IP4_HDR(input);
+
+	if (ntohl(ip4h->dst) == IPV4_ADDR_BROADCAST ||
+	    ntohl(ip4h->dst) == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask))
+		return true;
+	else
+		return inn4_is_dstaddr_accept(myaddr, input);
+	}
+
+#endif	/* of #ifdef ETHER_CFG_MULTICAST */
+#endif	/* of #ifdef DHCP_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_input.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_input.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_input.c	(revision 398)
@@ -0,0 +1,175 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include <net/if_var.h>
+
+#ifdef SUPPORT_UDP
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+T_UDP_STATS udp_stats;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+/*
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#undef	IN_COPY_TO_HOST
+
+#if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0
+
+#define UDP_INPUT		udp6_input
+#define UDP_INPUT_SELECT	udp6_input_select
+#define UDP_REPLY_NO_PORT	udp6_reply_no_port
+#define UDP_FIND_CEP		udp6_find_cep
+#define GET_UDP_CEPID		GET_UDP6_CEPID
+#define T_UDP_CEP		T_UDP6_CEP
+#define API_PROTO		API_PROTO_IPV6
+
+#if defined(_IP4_CFG)
+#define IN_COPY_TO_HOST		inn_copy_to_host
+#else
+#define IN_COPY_TO_HOST		IN6_COPY_TO_HOST
+#endif
+
+#include <netinet6/udp6_input.c>
+#include <netinet/udpn_input.c>
+
+#undef	UDP_INPUT
+#undef	UDP_INPUT_SELECT
+#undef	UDP_REPLY_NO_PORT
+#undef	UDP_FIND_CEP
+#undef	GET_UDP_CEPID
+#undef	T_UDP_CEP
+#undef	IN_COPY_TO_HOST
+#undef  API_PROTO
+
+#endif	/* of #if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0 */
+
+#if defined(_IP4_CFG) && ( (TNUM_UDP4_CEPID > 0) || \
+                          ((TNUM_UDP6_CEPID > 0) && defined(API_CFG_IP4MAPPED_ADDR)))
+
+#define UDP_INPUT		udp4_input
+#define UDP_INPUT_SELECT	udp4_input_select
+#define UDP_REPLY_NO_PORT	udp4_reply_no_port
+#define UDP_FIND_CEP		udp4_find_cep
+#define GET_UDP_CEPID		GET_UDP4_CEPID
+#define T_UDP_CEP		T_UDP4_CEP
+#define IN_COPY_TO_HOST		IN4_COPY_TO_HOST
+#define API_PROTO		API_PROTO_IPV4
+
+#include <netinet/udp4_input.c>
+#include <netinet/udpn_input.c>
+
+#endif	/* of #if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0 */
+
+#endif	/* of #ifdef SUPPORT_UDP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_output.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_output.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_output.c	(revision 398)
@@ -0,0 +1,211 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#ifdef SUPPORT_UDP
+
+#ifdef UDP_CFG_NON_BLOCKING
+
+/*
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#undef	IN_GET_DATAGRAM
+
+#if defined(_IP6_CFG) 
+
+#define UDP_OUTPUT		udp6_output
+#define GET_UDP_CEPID		GET_UDP6_CEPID
+#define T_UDP_CEP		T_UDP6_CEP
+#define API_PROTO		API_PROTO_IPV6
+
+#if defined(_IP4_CFG)
+#define	IN_GET_DATAGRAM		inn_get_datagram
+#else
+#define	IN_GET_DATAGRAM		in6_get_datagram
+#endif
+
+#include <netinet/udpn_output.c>
+
+#undef	UDP_OUTPUT
+#undef	GET_UDP_CEPID
+#undef	T_UDP_CEP
+#undef  API_PROTO
+#undef	IN_GET_DATAGRAM
+
+#endif	/* of #if defined(_IP6_CFG)  */
+
+#if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0
+
+#define UDP_OUTPUT		udp4_output
+#define GET_UDP_CEPID		GET_UDP4_CEPID
+#define T_UDP_CEP		T_UDP4_CEP
+#define API_PROTO		API_PROTO_IPV4
+
+#define	IN_GET_DATAGRAM		in4_get_datagram
+
+#include <netinet/udpn_output.c>
+
+#endif	/* of #if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0 */
+
+/*
+ *  UDP 出力タスク
+ *  ノンブロッキングコールを組み込んだとき使用する。
+ */
+
+void
+udp_output_task (intptr_t exinf)
+{
+	ID	tskid;
+	int_t	ix;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP OUTPUT:%d] started.", tskid);
+
+
+#if defined(_IP6_CFG) && !defined(SUPPORT_TCP)
+
+	/* IPv6 のステートレス・アドレス自動設定を実行する。*/
+	in6_if_up(IF_GET_IFNET());
+
+#endif	/* of #if defined(_IP6_CFG) && !defined(SUPPORT_TCP) */
+
+	while (true) {
+
+		/* 出力がポストされるまで待つ。*/
+		syscall(wai_sem(SEM_UDP_POST_OUTPUT));
+
+#if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0
+
+		for (ix = TNUM_UDP6_CEPID - 1; ix -- > 0; ) {
+
+			if (udp6_cep[ix].flags & UDP_CEP_FLG_POST_OUTPUT) {
+				udp6_cep[ix].flags &= ~UDP_CEP_FLG_POST_OUTPUT;
+				udp6_output(&udp6_cep[ix]);
+				}
+			}
+
+#endif	/* of #if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0 */
+
+#if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0
+
+		for (ix = TNUM_UDP4_CEPID - 1; ix -- > 0; ) {
+
+			if (udp4_cep[ix].flags & UDP_CEP_FLG_POST_OUTPUT) {
+				udp4_cep[ix].flags &= ~UDP_CEP_FLG_POST_OUTPUT;
+				udp4_output(&udp4_cep[ix]);
+				}
+			}
+
+#endif	/* of #if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0 */
+
+		}
+	}
+
+#endif	/* of #ifdef UDP_CFG_NON_BLOCKING */
+
+#endif	/* of #ifdef SUPPORT_UDP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_subr.c	(revision 398)
@@ -0,0 +1,196 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce 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.
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/ppp_ipcp.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/ip_igmp.h>
+
+#include <net/if_var.h>
+
+#ifdef SUPPORT_UDP
+
+/*
+ *  局所変数
+ */
+
+#if (defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0) || (defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0)
+
+static uint16_t udp_port_auto = UDP_PORT_FIRST_AUTO;	/* 自動割り当て番号	*/
+
+#endif	/* of #if (defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0) || (defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0) */
+
+/*
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0
+
+#if defined(_IP4_CFG) && defined(API_CFG_IP4MAPPED_ADDR)
+
+#define UDP_IS_DSTADDR_ACCEPT	udpn_is_dstaddr_accept
+
+#else	/* of #if defined(_IP4_CFG) */
+
+#define UDP_IS_DSTADDR_ACCEPT	udp6_is_dstaddr_accept
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#define UDP_SEND_DATA		udp6_send_data
+#define UDP_CAN_SND		udp6_can_snd
+#define UDP_CAN_RCV		udp6_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp6_alloc_auto_port
+#define UDP_ALLOC_PORT		udp6_alloc_port
+#define UDP_FIND_CEP		udp6_find_cep
+#define UDP_NOTIFY		udp6_notify
+#define TMAX_UDP_CEPID		(TNUM_UDP6_CEPID - 1)
+#define UDP_CEP			udp6_cep
+#define T_UDP_CEP		T_UDP6_CEP
+#define T_IPEP			T_IPV6EP
+#define API_PROTO		API_PROTO_IPV6
+
+#include <netinet6/udp6_subr.c>
+#include <netinet/udpn_subr.c>
+
+#undef	UDP_SEND_DATA
+#undef	UDP_CAN_SND
+#undef	UDP_CAN_RCV
+#undef	UDP_ALLOC_AUTO_PORT
+#undef	UDP_ALLOC_PORT
+#undef	UDP_FIND_CEP
+#undef	UDP_NOTIFY
+#undef	UDP_IS_DSTADDR_ACCEPT
+#undef	TMAX_UDP_CEPID
+#undef	UDP_CEP
+#undef	T_UDP_CEP
+#undef  T_IPEP
+#undef  API_PROTO
+
+#endif	/* of #if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0 */
+
+#if defined(_IP4_CFG) && ( (TNUM_UDP4_CEPID > 0) || \
+                          ((TNUM_UDP6_CEPID > 0) && defined(API_CFG_IP4MAPPED_ADDR)))
+
+#define UDP_IS_DSTADDR_ACCEPT	udp4_is_dstaddr_accept
+
+#define UDP_SEND_DATA		udp4_send_data
+#define UDP_CAN_SND		udp4_can_snd
+#define UDP_CAN_RCV		udp4_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp4_alloc_auto_port
+#define UDP_ALLOC_PORT		udp4_alloc_port
+#define UDP_FIND_CEP		udp4_find_cep
+#define UDP_NOTIFY		udp4_notify
+#define TMAX_UDP_CEPID		(TNUM_UDP4_CEPID - 1)
+#define T_UDP_CEP		T_UDP4_CEP
+#define UDP_CEP			udp4_cep
+#define T_IPEP			T_IPV4EP
+#define API_PROTO		API_PROTO_IPV4
+
+#include <netinet/udp4_subr.c>
+#include <netinet/udpn_subr.c>
+
+#endif	/* of #if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0 */
+
+#endif	/* of #ifdef SUPPORT_UDP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_usrreq.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_usrreq.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_usrreq.c	(revision 398)
@@ -0,0 +1,271 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce 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.
+ *
+ *	@(#)udp_usrreq.c	8.6 (Berkeley) 5/23/95
+ * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.49.2.2 1999/08/29 16:29:58 peter Exp $
+ */
+
+/*
+ *  ノンブロッキングコールを組込まない場合にリンクされる関数の定義
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/ppp_ipcp.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/ip_igmp.h>
+
+#ifdef SUPPORT_UDP
+
+/*
+ *  TINET をライブラリ化しない場合は、全ての機能を
+ *  オブジェクトファイルに出力するため、マクロを有効にする。
+ */
+
+#ifndef UDP_CFG_LIBRARY
+
+#define __udp_send_data
+#define __udp_cre_cep
+#define __udp_del_cep
+#define __udp_can_cep
+#define __udp_set_opt
+#define __udp_get_opt
+#define __udp_can_snd
+#define __udp_can_rcv
+#define __udp_snd_dat
+#define __udp_rcv_dat
+
+#endif	/* of #ifndef UDP_CFG_LIBRARY */
+
+/*
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#undef	IN_GET_DATAGRAM
+#undef	IN_COPY_TO_HOST
+
+#if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0
+
+#define UDP_CANCEL_CEP		udp6_cancel_cep
+#define UDP_DELETE_CEP		udp6_delete_cep
+#define UDP_SET_OPTION		udp6_set_option
+#define UDP_GET_OPTION		udp6_get_option
+#define UDP_CRE_CEP		udp6_cre_cep
+#define UDP_DEL_CEP		udp6_del_cep
+#define UDP_SET_OPT		udp6_set_opt
+#define UDP_GET_OPT		udp6_get_opt
+#define UDP_SND_DAT		udp6_snd_dat
+#define UDP_RCV_DAT		udp6_rcv_dat
+#define UDP_CAN_SND		udp6_can_snd
+#define UDP_CAN_RCV		udp6_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp6_alloc_auto_port
+#define UDP_ALLOC_PORT		udp6_alloc_port
+#define UDP_SEND_DATA		udp6_send_data
+#define VALID_UDP_CEPID		VALID_UDP6_CEPID
+#define GET_UDP_CEP		GET_UDP6_CEP
+#define GET_UDP_CEPID		GET_UDP6_CEPID
+#define T_UDP_CEP		T_UDP6_CEP
+#define T_UDPN_CCEP		T_UDP6_CCEP
+#define T_IPEP			T_IPV6EP
+#define API_PROTO		API_PROTO_IPV6
+
+#if defined(_IP4_CFG)
+#define	IN_GET_DATAGRAM		inn_get_datagram
+#define IN_COPY_TO_HOST		inn_copy_to_host
+#else
+#define	IN_GET_DATAGRAM		in6_get_datagram
+#define IN_COPY_TO_HOST		IN6_COPY_TO_HOST
+#endif
+
+#include <netinet/udpn_usrreq.c>
+
+#undef	UDP_CANCEL_CEP
+#undef	UDP_DELETE_CEP
+#undef	UDP_SET_OPTION
+#undef	UDP_GET_OPTION
+#undef	UDP_CRE_CEP
+#undef	UDP_DEL_CEP
+#undef	UDP_SET_OPT
+#undef	UDP_GET_OPT
+#undef	UDP_SND_DAT
+#undef	UDP_RCV_DAT
+#undef	UDP_CAN_SND
+#undef	UDP_CAN_RCV
+#undef	UDP_ALLOC_AUTO_PORT
+#undef	UDP_ALLOC_PORT
+#undef	UDP_SEND_DATA
+#undef	VALID_UDP_CEPID
+#undef	GET_UDP_CEP
+#undef	GET_UDP_CEPID
+#undef	T_UDP_CEP
+#undef	T_UDPN_CCEP
+#undef  T_IPEP
+#undef  API_PROTO
+#undef	IN_GET_DATAGRAM
+#undef	IN_COPY_TO_HOST
+
+#endif	/* of #if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0 */
+
+#if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0
+
+#define UDP_CANCEL_CEP		udp4_cancel_cep
+#define UDP_DELETE_CEP		udp4_delete_cep
+#define UDP_SET_OPTION		udp4_set_option
+#define UDP_GET_OPTION		udp4_get_option
+#define UDP_CRE_CEP		udp_cre_cep
+#define UDP_DEL_CEP		udp_del_cep
+#define UDP_SET_OPT		udp_set_opt
+#define UDP_GET_OPT		udp_get_opt
+#define UDP_SND_DAT		udp_snd_dat
+#define UDP_RCV_DAT		udp_rcv_dat
+#define UDP_CAN_SND		udp4_can_snd
+#define UDP_CAN_RCV		udp4_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp4_alloc_auto_port
+#define UDP_ALLOC_PORT		udp4_alloc_port
+#define UDP_SEND_DATA		udp4_send_data
+#define VALID_UDP_CEPID		VALID_UDP4_CEPID
+#define GET_UDP_CEP		GET_UDP4_CEP
+#define GET_UDP_CEPID		GET_UDP4_CEPID
+#define T_UDP_CEP		T_UDP4_CEP
+#define T_UDPN_CCEP		T_UDP_CCEP
+#define T_IPEP			T_IPV4EP
+#define API_PROTO		API_PROTO_IPV4
+
+#define IN_COPY_TO_HOST		IN4_COPY_TO_HOST
+#define	IN_GET_DATAGRAM		in4_get_datagram
+
+#include <netinet/udpn_usrreq.c>
+
+#endif	/* of #if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0 */
+
+#if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0)
+
+/*
+ *  udp_can_cep -- ペンディングしている処理のキャンセル【標準機能】
+ */
+
+#ifdef __udp_can_cep
+
+ER
+udp_can_cep (ID cepid, FN fncd)
+{
+	/* IPv6 用の UDP 通信端点 ID をチェックする。*/
+	if (VALID_UDP6_CEPID(cepid)) {
+
+		/* UDP 通信端点を得てメイン関数を呼び出す。*/
+		return udp6_cancel_cep(GET_UDP6_CEP(cepid), fncd);
+		}
+
+	/* IPv4 用の UDP 通信端点 ID をチェックする。*/
+	else if (VALID_UDP4_CEPID(cepid)) {
+
+		/* UDP 通信端点を得てメイン関数を呼び出す。*/
+		return udp4_cancel_cep(GET_UDP4_CEP(cepid), fncd);
+		}
+
+	else
+		return E_ID;
+	}
+
+#endif	/* of #ifdef __udp_can_cep */
+
+#endif	/* of #if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0) */
+
+#endif	/* of #ifdef SUPPORT_UDP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_usrreq_nblk.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_usrreq_nblk.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_usrreq_nblk.c	(revision 398)
@@ -0,0 +1,198 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce 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.
+ *
+ *	@(#)udp_usrreq.c	8.6 (Berkeley) 5/23/95
+ * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.49.2.2 1999/08/29 16:29:58 peter Exp $
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/ppp_ipcp.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#ifdef SUPPORT_UDP
+
+/*
+ *  TINET をライブラリ化しない場合は、全ての機能を
+ *  オブジェクトファイルに出力するため、マクロを有効にする。
+ */
+
+#ifndef UDP_CFG_LIBRARY
+
+#define __udp_can_snd_nblk
+#define __udp_can_rcv_nblk
+#define __udp_snd_dat_nblk
+#define __udp_rcv_dat_nblk
+
+#endif	/* of #ifndef UDP_CFG_LIBRARY */
+
+#ifdef UDP_CFG_NON_BLOCKING
+
+/*
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#undef	IN_COPY_TO_HOST
+
+#if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0
+
+#define UDP_SND_DAT		udp6_snd_dat
+#define UDP_RCV_DAT		udp6_rcv_dat
+#define UDP_CAN_SND		udp6_can_snd
+#define UDP_CAN_RCV		udp6_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp6_alloc_auto_port
+#define UDP_SEND_DATA		udp6_send_data
+#define VALID_UDP_CEPID		VALID_UDP6_CEPID
+#define GET_UDP_CEP		GET_UDP6_CEP
+#define GET_UDP_CEPID		GET_UDP6_CEPID
+#define T_UDP_CEP		T_UDP6_CEP
+#define T_IPEP			T_IPV6EP
+#define API_PROTO		API_PROTO_IPV6
+
+#if defined(SUPPORT_INET4)
+#define IN_COPY_TO_HOST		inn_copy_to_host
+#else
+#define IN_COPY_TO_HOST		IN6_COPY_TO_HOST
+#endif
+
+#include <netinet/udpn_usrreq_nblk.c>
+
+#undef	UDP_SND_DAT
+#undef	UDP_RCV_DAT
+#undef	UDP_CAN_SND
+#undef	UDP_CAN_RCV
+#undef	UDP_ALLOC_AUTO_PORT
+#undef	UDP_SEND_DATA
+#undef	VALID_UDP_CEPID
+#undef	GET_UDP_CEP
+#undef	GET_UDP_CEPID
+#undef	T_UDP_CEP
+#undef  T_IPEP
+#undef  API_PROTO
+#undef	IN_COPY_TO_HOST
+
+#endif	/* of #if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0 */
+
+#if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0
+
+#define UDP_SND_DAT		udp_snd_dat
+#define UDP_RCV_DAT		udp_rcv_dat
+#define UDP_CAN_SND		udp4_can_snd
+#define UDP_CAN_RCV		udp4_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp4_alloc_auto_port
+#define UDP_SEND_DATA		udp4_send_data
+#define VALID_UDP_CEPID		VALID_UDP4_CEPID
+#define GET_UDP_CEP		GET_UDP4_CEP
+#define GET_UDP_CEPID		GET_UDP4_CEPID
+#define T_UDP_CEP		T_UDP4_CEP
+#define T_IPEP			T_IPV4EP
+#define API_PROTO		API_PROTO_IPV4
+
+#define IN_COPY_TO_HOST		IN4_COPY_TO_HOST
+
+#include <netinet/udpn_usrreq_nblk.c>
+
+#endif	/* of #if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0 */
+
+#endif	/* of #ifdef UDP_CFG_NON_BLOCKING */
+
+#endif	/* of #ifdef SUPPORT_UDP */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udp_var.h	(revision 398)
@@ -0,0 +1,336 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)udp_var.h	8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/udp_var.h,v 1.16.2.2 1999/08/29 16:29:59 peter Exp $
+ */
+ 
+#ifndef _UDP_VAR_H_
+#define _UDP_VAR_H_
+
+/*
+ *  UDP ヘッダ・ペイロードアクセスマクロ
+ */
+
+#define GET_UDP_HDR(nbuf,uhoff)		((T_UDP_HDR*)((uint8_t*)((nbuf)->buf) + uhoff))
+#define GET_UDP_HDR_OFFSET(nbuf)	(GET_IF_IP_HDR_SIZE(nbuf))
+#define GET_UDP_SDU(nbuf,uhoff)		((uint8_t*)((nbuf)->buf) + uhoff+ UDP_HDR_SIZE)
+
+#define IF_IP_UDP_HDR_SIZE(nbuf)	(IF_IP_HDR_SIZE(nbuf) + UDP_HDR_SIZE)
+#define IF_IP_UDP_HDR_OFFSET(nbuf)	(IF_IP_HDR_SIZE(nbuf))
+
+/*
+ *  TINET 1.1 との互換性のための定義
+ */
+
+#if defined(_IP4_CFG)
+
+#define IP4_UDP_HDR_SIZE		IP_UDP_HDR_SIZE
+#define IF_IP4_UDP_HDR_SIZE		IF_IP_UDP_HDR_SIZE
+#define GET_IP4_UDP_HDR_SIZE(nbuf)	GET_IP_UDP_HDR_SIZE(nbuf)	
+#define GET_IF_IP4_UDP_HDR_SIZE(nbuf)	GET_IF_IP_UDP_HDR_SIZE(nbuf)
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+/*
+ *  コールバック関数の定義
+ */
+
+typedef ER	(*t_udp_callback)(ID cepid, FN fncd, void *p_parblk);
+
+typedef struct t_udp_rcv_dat_para {
+	uint_t		len;
+	T_NET_BUF	*input;
+	uint_t		off;
+	union {
+		T_IPV4EP rep4;
+		T_IPV6EP rep6;
+	};
+	} T_UDP_RCV_DAT_PARA;
+
+/*
+ *  UDP 通信端点
+ */
+
+/* IPv6 用 UDP 通信端点 */
+
+typedef struct t_udp6_cep {
+
+	/*
+	 * ITRON TCP/IP API、TCP 通信端点と同じメンバ
+	 */
+	ATR		cepatr;		/* UDP 通信端点属性		*/
+	T_IPV6EP	myaddr;		/* 自分のアドレス		*/
+	t_udp_callback	callback;	/* コールバック関数		*/
+
+	/*
+	 * TINET 独自のメンバ
+	 */
+	uint16_t	flags;		/* 通信端点フラグ		*/
+	ID		semid_lock;	/* 通信端点ロック		*/
+	ID		snd_tskid;	/* 送信タスク識別子		*/
+	ID		rcv_tskid;	/* 受信タスク識別子		*/
+	ID		rcvqid;		/* 非コールバック用受信キュー識別子*/
+	T_NET_BUF	*cb_netbuf;	/* コールバック用受信ネットワークバッファ*/
+
+#ifdef UDP_CFG_NON_BLOCKING
+
+	T_IPV6EP 	*snd_p_dstaddr;	/* 送信相手のアドレスへのポインタ*/
+	T_IPV6EP 	*rcv_p_dstaddr;	/* 受信相手のアドレスへのポインタ*/
+	void		*snd_data;	/* 送信データ領域の先頭アドレス	*/
+	int_t		snd_len;	/* 送信データ領域の長さ		*/
+	void		*rcv_data;	/* 受信データ領域の先頭アドレス	*/
+	int_t		rcv_len;	/* 受信データ領域の長さ		*/
+
+#endif	/* of #ifdef UDP_CFG_NON_BLOCKING */
+
+#ifdef UDP_CFG_EXTENTIONS
+	ER		error;		/* 待ち中に発生したエラー	*/
+#endif
+
+#ifdef SUPPORT_IGMP
+	bool_t igmp_loopback;
+	uint8_t igmp_ttl;
+	T_IN4_ADDR 	igmp_mcaddr;	/*  */
+#endif
+
+	} T_UDP6_CEP;
+
+/* IPv4 用 UDP 通信端点 */
+
+typedef struct t_udp4_cep {
+
+	/*
+	 * ITRON TCP/IP API、TCP 通信端点と同じメンバ
+	 */
+	ATR		cepatr;		/* UDP 通信端点属性		*/
+	T_IPV4EP	myaddr;		/* 自分のアドレス		*/
+	t_udp_callback	callback;	/* コールバック関数		*/
+
+	/*
+	 * TINET 独自のメンバ
+	 */
+	uint16_t	flags;		/* 通信端点フラグ		*/
+	ID		semid_lock;	/* 通信端点ロック		*/
+	ID		snd_tskid;	/* 送信タスク識別子		*/
+	ID		rcv_tskid;	/* 受信タスク識別子		*/
+	ID		rcvqid;		/* 非コールバック用受信キュー識別子*/
+	T_NET_BUF	*cb_netbuf;	/* コールバック用受信ネットワークバッファ*/
+
+#ifdef UDP_CFG_NON_BLOCKING
+
+	T_IPV4EP 	*snd_p_dstaddr;	/* 送信相手のアドレスへのポインタ*/
+	T_IPV4EP	*rcv_p_dstaddr;	/* 受信相手のアドレスへのポインタ*/
+	void		*snd_data;	/* 送信データ領域の先頭アドレス	*/
+	int_t		snd_len;	/* 送信データ領域の長さ		*/
+	void		*rcv_data;	/* 受信データ領域の先頭アドレス	*/
+	int_t		rcv_len;	/* 受信データ領域の長さ		*/
+
+#endif	/* of #ifdef UDP_CFG_NON_BLOCKING */
+
+#ifdef UDP_CFG_EXTENTIONS
+	ER		error;		/* 待ち中に発生したエラー	*/
+#endif
+
+#ifdef SUPPORT_IGMP
+	bool_t igmp_loopback;
+	uint8_t igmp_ttl;
+	T_IN4_ADDR 	igmp_mcaddr;	/*  */
+#endif
+
+	} T_UDP4_CEP;
+
+#if defined(_IP6_CFG)
+
+#define T_UDP_CEP	T_UDP6_CEP
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+#define T_UDP_CEP	T_UDP4_CEP
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+/*
+ *  UDP 通信端点フラグ
+ */
+
+#define UDP_CEP_FLG_POST_OUTPUT	UINT_C(0x0200)	/* 送信を開始する。		*/
+#define UDP_CEP_FLG_DYNAMIC	UINT_C(0x0400)	/* 動的生成・削除可能通信端点。	*/
+#define UDP_CEP_FLG_VALID	UINT_C(0x0800)	/* 生成済みで有効な通信端点。	*/
+
+/*
+ *  オブジェクト ID の最小値の定義
+ */
+
+#define	TMIN_UDP_CEPID		1			/* UDP      通信端点 ID の最小値 */
+#define	TMIN_UDP6_CEPID		1			/* UDP/IPv6 通信端点 ID の最小値 */
+#define	TMIN_UDP4_CEPID		(TNUM_UDP6_CEPID+1)	/* UDP/IPv4 通信端点 ID の最小値 */
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+typedef struct t_udp_stats {
+	uint32_t	udpInDatagrams;
+	uint32_t	udpNoPorts;
+	uint32_t	udpInErrors;
+	uint32_t	udpOutDatagrams;
+} T_UDP_STATS;
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+#define VALID_UDP6_CEPID(id)	(TMIN_UDP6_CEPID<=(id)&&(id)<=tmax_udp6_cepid)
+#define VALID_UDP4_CEPID(id)	(TMIN_UDP4_CEPID<=(id)&&(id)<=tmax_udp4_cepid)
+
+#define INDEX_UDP6_CEP(id)	((id)-TMIN_UDP6_CEPID)
+#define INDEX_UDP4_CEP(id)	((id)-TMIN_UDP4_CEPID)
+
+#define GET_UDP6_CEP(id)	(&(udp6_cep[INDEX_UDP6_CEP(id)]))
+#define GET_UDP4_CEP(id)	(&(udp4_cep[INDEX_UDP4_CEP(id)]))
+
+#define GET_UDP6_CEPID(cep)	((ID)(((cep)-udp6_cep)+TMIN_UDP6_CEPID))
+#define GET_UDP4_CEPID(cep)	((ID)(((cep)-udp4_cep)+TMIN_UDP4_CEPID))
+
+#define VALID_TFN_UDP_CAN(t)	((t)==TFN_UDP_SND_DAT||(t)==TFN_UDP_RCV_DAT||\
+				 (t)==TFN_UDP_ALL)
+
+#define VALID_UDP_CEP(cep)	(((cep)->flags&UDP_CEP_FLG_VALID)!=0)
+#define DYNAMIC_UDP_CEP(cep)	(((cep)->flags&UDP_CEP_FLG_DYNAMIC)!=0)
+
+/*
+ *  全域変数
+ */
+
+extern T_UDP_STATS udp_stats;
+
+/* UDP 通信端点 */
+
+extern T_UDP6_CEP udp6_cep[];
+extern T_UDP4_CEP udp4_cep[];
+
+#if defined(SUPPORT_INET6)
+#define udp_cep	udp6_cep
+#elif defined(SUPPORT_INET4)
+#define udp_cep	udp4_cep
+#endif
+
+extern const ID tmax_udp_cepid;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+extern const ID tmax_udp6_cepid;
+extern const ID tmax_udp4_cepid;
+#else
+#define tmax_udp6_cepid	tmax_udp_cepid
+#define tmax_udp4_cepid	tmax_udp_cepid
+#endif
+
+/*
+ *  TINET 1.3 との互換性のための定義
+ */
+
+#define	TMIN_UDP_CCEPID		TMIN_UDP_CEPID
+#define	TNUM_UDP_CCEPID		TNUM_UDP_CEPID
+
+/*
+ *  関数
+ */
+
+/* IPv6 */
+
+extern uint_t udp6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+extern ER_UINT udp6_send_data (T_UDP6_CEP *cep, T_IPV6EP *p_dstaddr,
+                               void *data, int_t len, TMO tmout);
+extern ER udp6_can_snd (T_UDP6_CEP *cep, ER error);
+extern ER udp6_can_rcv (T_UDP6_CEP *cep, ER error);
+extern ER udp6_alloc_auto_port (T_UDP6_CEP *cep);
+extern ER udp6_alloc_port (T_UDP6_CEP *cep, uint16_t portno);
+extern T_UDP6_CEP*udp6_find_cep (T_NET_BUF *input, uint_t off);
+extern void udp6_notify (T_NET_BUF *input, ER error);
+extern void udp6_input_select (T_UDP6_CEP *cep, T_NET_BUF *input, uint_t off);
+
+/* IPv4 */
+
+extern uint_t udp4_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+extern ER_UINT udp4_send_data (T_UDP4_CEP *cep, T_IPV4EP *p_dstaddr,
+                               void *data, int_t len, TMO tmout);
+extern ER udp4_can_snd (T_UDP4_CEP *cep, ER error);
+extern ER udp4_can_rcv (T_UDP4_CEP *cep, ER error);
+extern ER udp4_alloc_auto_port (T_UDP4_CEP *cep);
+extern ER udp4_alloc_port (T_UDP4_CEP *cep, uint16_t portno);
+extern T_UDP4_CEP*udp4_find_cep (T_NET_BUF *input, uint_t off);
+extern void udp4_notify (T_NET_BUF *input, ER error);
+extern void udp4_input_select (T_UDP4_CEP *cep, T_NET_BUF *input, uint_t off);
+
+/* ノンブロッキングコールを行う場合に組み込むタスク */
+
+extern void	udp_output_task(intptr_t exinf);
+
+#endif	/* of #ifndef _UDP_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_input.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_input.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_input.c	(revision 398)
@@ -0,0 +1,248 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#if (API_PROTO == API_PROTO_IPV6) || (TNUM_UDP4_CEPID > 0)
+
+/*
+ *  udp_input_select -- UDP の入力処理の選択
+ */
+
+void
+UDP_INPUT_SELECT (T_UDP_CEP *cep, T_NET_BUF *input, uint_t off)
+{
+	T_UDP_HDR	*udph;
+	T_UDP_RCV_DAT_PARA para;
+
+	udph = (T_UDP_HDR *)(input->buf + off);
+	para.len  = (uint_t)(ntohs(udph->ulen) - UDP_HDR_SIZE);
+
+	if (cep->rcv_tskid != TA_NULL) {	/* 非ノンブロッキングコールでペンディング中 */
+		if (psnd_dtq(cep->rcvqid, (intptr_t)input) != E_OK) {
+			NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
+			NET_COUNT_MIB(udp_stats.udpInErrors, 1);
+			syscall(rel_net_buf(input));
+			}
+		}
+
+#ifdef UDP_CFG_NON_BLOCKING
+
+	else if (cep->rcv_p_dstaddr != NULL) {	/* ノンブロッキングコールでペンディング中 */
+
+		/* p_dstaddr を設定する。*/
+		cep->rcv_p_dstaddr->portno = ntohs(udph->sport);
+		IN_COPY_TO_HOST(&cep->rcv_p_dstaddr->ipaddr, input);
+
+		/* データをバッファに移す。*/
+		memcpy(cep->rcv_data, GET_UDP_SDU(input, off),
+		       (size_t)(para.len < cep->rcv_len ? para.len : cep->rcv_len));
+		syscall(rel_net_buf(input));
+
+		if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)(uint32_t)para.len);
+#else
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)&para.len);
+#endif
+		else
+			syslog(LOG_WARNING, "[UDP] no call back, CEP: %d.", GET_UDP_CEPID(cep));
+		cep->rcv_p_dstaddr = NULL;
+		}
+
+#endif/* of #ifdef UDP_CFG_NON_BLOCKING */
+
+	else if (IS_PTR_DEFINED(cep->callback)) {
+
+		/* コールバック関数を呼び出す。*/
+		cep->cb_netbuf = input;
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+		(*cep->callback)(GET_UDP_CEPID(cep), TEV_UDP_RCV_DAT, (void*)(uint32_t)para.len);
+#else
+		para.input = input;
+		para.off = off;
+#if API_PROTO == API_PROTO_IPV4
+		para.rep4.portno = ntohs(udph->sport);
+		IN_COPY_TO_HOST(&para.rep4.ipaddr, input);
+#else
+		para.rep6.portno = ntohs(udph->sport);
+		IN_COPY_TO_HOST(&para.rep6.ipaddr, input);
+#endif
+		(*cep->callback)(GET_UDP_CEPID(cep), TEV_UDP_RCV_DAT, (void*)&para.len);
+#endif
+		/*
+		 *  ネットワークバッファがそのままであれば、コールバック関数内で
+		 *  データを読み出さなかったことになるので、捨てる。
+		 */
+		if (cep->cb_netbuf != NULL) {
+			if ((input->flags & NB_FLG_NOREL_IFOUT) == 0)
+				syscall(rel_net_buf(cep->cb_netbuf));
+			cep->cb_netbuf = NULL;
+			}
+		}
+	else {
+		NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
+		NET_COUNT_MIB(udp_stats.udpInErrors, 1);
+		syscall(rel_net_buf(input));
+		}
+
+	}
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) || (TNUM_UDP4_CEPID > 0) */
+
+/*
+ *  udp_input -- UDP の入力関数
+ */
+
+uint_t
+UDP_INPUT (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+	T_NET_BUF	*input = *inputp;
+	T_UDP_CEP	*cep;
+	T_UDP_HDR	*udph;
+	uint_t		hlen, ulen;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG) && API_PROTO == API_PROTO_IPV4
+	T_UDP6_CEP	*cep6;
+#endif
+
+	hlen = (uint_t)GET_IF_IP_HDR_SIZE(input);
+
+	NET_COUNT_UDP(net_count_udp.in_octets,  input->len - hlen);
+	NET_COUNT_UDP(net_count_udp.in_packets, 1);
+	NET_COUNT_MIB(udp_stats.udpInDatagrams, 1);
+
+	/* ヘッダ長をチェックする。*/
+	if (input->len < hlen + UDP_HDR_SIZE)
+		goto buf_rel;
+
+	udph = (T_UDP_HDR *)(input->buf + *offp);
+
+	/* データグラム長をチェックする */
+	ulen  = ntohs(udph->ulen);
+	if (ulen != input->len - hlen)
+		goto buf_rel;
+
+	/* 宛先ポートが 0 のデータグラムは破棄する。RFC768 */
+	if (udph->dport == 0)
+		goto buf_rel;
+
+#ifdef UDP_CFG_IN_CHECKSUM
+
+	/* チェックサムをチェックする */
+	if (udph->sum && IN_CKSUM(input, IPPROTO_UDP, *offp, ulen) != 0)
+		goto buf_rel;
+
+#endif	/* of #ifdef UDP_CFG_IN_CHECKSUM */
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG) && API_PROTO == API_PROTO_IPV4
+
+#if TNUM_UDP4_CEPID > 0
+
+	/* UDP 通信端点を得る。*/
+	cep = udp4_find_cep(input, *offp);
+
+	if (cep != NULL)
+		udp4_input_select(cep, input, *offp);
+	else if ((cep6 = udp6_find_cep(input, *offp)) != NULL)
+		udp6_input_select(cep6, input, *offp);
+	else
+		udp4_reply_no_port(input, *offp);
+
+	return IPPROTO_DONE;
+
+#else	/* of #if TNUM_UDP4_CEPID > 0 */
+
+	cep = 0;	/* warning 回避用のダミー */
+	if ((cep6 = udp6_find_cep(input, *offp)) != NULL)
+		udp6_input_select(cep6, input, *offp);
+	else
+		udp4_reply_no_port(input, *offp);
+
+	return IPPROTO_DONE;
+
+#endif	/* of #if TNUM_UDP4_CEPID > 0 */
+
+#else	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) && API_PROTO == API_PROTO_IPV4 */
+
+	/* UDP 通信端点を得る。*/
+	cep = UDP_FIND_CEP(input, *offp);
+
+	if (cep != NULL)
+		UDP_INPUT_SELECT(cep, input, *offp);
+	else
+		UDP_REPLY_NO_PORT(input, *offp);
+
+	return IPPROTO_DONE;
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) && API_PROTO == API_PROTO_IPV4 */
+
+buf_rel:
+	NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
+	NET_COUNT_MIB(udp_stats.udpInErrors, 1);
+	syscall(rel_net_buf(input));
+	return IPPROTO_DONE;
+	}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_output.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_output.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_output.c	(revision 398)
@@ -0,0 +1,161 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+/*
+ *  udp_output -- UDP の出力関数
+ *  ノンブロッキングコールを組み込んだとき使用する。
+ */
+
+static void
+UDP_OUTPUT (T_UDP_CEP *cep)
+{
+	T_NET_BUF	*output;
+	T_UDP_HDR	*udph;
+	ER_UINT		error;
+
+#ifdef UDP_CFG_OUT_CHECKSUM
+	uint16_t	sum;
+#endif	/* of #ifdef UDP_CFG_OUT_CHECKSUM */
+
+	/* IP データグラムを割り当てる。*/
+	if ((error = IN_GET_DATAGRAM(&output, (uint_t)(UDP_HDR_SIZE + cep->snd_len), 0,
+	                             &cep->snd_p_dstaddr->ipaddr,
+	                             &cep->myaddr.ipaddr,
+	                             IPPROTO_UDP, IP_DEFTTL, 
+	                             NBA_SEARCH_ASCENT, TMO_UDP_OUTPUT)) != E_OK) {
+		goto err_ret;
+		}
+
+	/* UDP ヘッダに情報を設定する。*/
+	udph		= GET_UDP_HDR(output, IF_IP_UDP_HDR_OFFSET(output));
+	udph->sport	= htons(cep->myaddr.portno);
+	udph->dport	= htons(cep->snd_p_dstaddr->portno);
+	udph->ulen	= htons(UDP_HDR_SIZE + cep->snd_len);
+	udph->sum	= 0;
+
+	/* データをコピーする。*/
+	memcpy((void*)GET_UDP_SDU(output, IF_IP_UDP_HDR_OFFSET(output)),
+	       cep->snd_data, (size_t)cep->snd_len);
+
+#ifdef UDP_CFG_OUT_CHECKSUM
+
+	sum = IN_CKSUM(output, IPPROTO_UDP, IF_IP_UDP_HDR_OFFSET(output),
+	               (uint_t)(UDP_HDR_SIZE + cep->snd_len));
+
+	/* 計算したチェックサムの値が 0 なら 0xffff を入れる。*/
+	if (sum == 0)
+		sum = UINT_C(0xffff);
+	udph->sum = sum;
+
+#endif/* of #ifdef UDP_CFG_OUT_CHECKSUM */
+
+	/* ネットワークバッファ長を調整する。*/
+	output->len = (uint16_t)(IF_IP_UDP_HDR_SIZE(output) + cep->snd_len);
+
+	/* ネットワーク層 (IP) の出力関数を呼び出す。*/
+	if ((error = IP_OUTPUT(output, TMO_UDP_OUTPUT)) != E_OK)
+		goto err_ret;
+
+
+	NET_COUNT_MIB(udp_stats.udpOutDatagrams, 1);
+
+	if (IS_PTR_DEFINED(cep->callback)) {
+
+		if (error == E_OK)
+			error = cep->snd_len;
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)error);
+#else
+		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)&error);
+#endif
+		}
+	else
+		syslog(LOG_WARNING, "[UDP] no call back, CEP: %d.", GET_UDP_CEPID(cep));
+	cep->snd_p_dstaddr = NULL;
+	return;
+
+err_ret:
+	NET_COUNT_UDP(net_count_udp.out_err_packets, 1);
+	if (IS_PTR_DEFINED(cep->callback)) {
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)E_NOMEM);
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+		error = E_NOMEM;
+		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)&error);
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+		}
+	else
+		syslog(LOG_WARNING, "[UDP] no call back, CEP: %d.", GET_UDP_CEPID(cep));
+	cep->snd_p_dstaddr = NULL;
+	return;
+	}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_subr.c	(revision 398)
@@ -0,0 +1,158 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce 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.
+ */
+
+/*
+ *  udp_alloc_auto_port -- 自動割り当てポート番号を設定する。
+ */
+
+ER
+UDP_ALLOC_AUTO_PORT (T_UDP_CEP *cep)
+{
+	int_t	ix;
+	uint16_t	portno, portno_start;
+
+	portno_start = udp_port_auto;
+	do {
+		portno = udp_port_auto ++;
+		if (udp_port_auto > UDP_PORT_LAST_AUTO)
+			udp_port_auto = UDP_PORT_FIRST_AUTO;
+
+		syscall(wai_sem(SEM_UDP_CEP));
+		for (ix = TMAX_UDP_CEPID; ix -- > 0; ) {
+			if (VALID_UDP_CEP(&UDP_CEP[ix]) && UDP_CEP[ix].myaddr.portno == portno) {
+				portno = UDP_PORTANY;
+				break;
+				}
+			}
+
+		if (portno != UDP_PORTANY) {
+			cep->myaddr.portno = portno;
+			syscall(sig_sem(SEM_UDP_CEP));
+			return E_OK;
+			}
+		syscall(sig_sem(SEM_UDP_CEP));
+
+		} while (portno_start != udp_port_auto);
+
+	return E_NOID;
+	}
+
+/*
+ *  udp_alloc_port -- 指定されたポート番号を設定する。
+ */
+
+ER
+UDP_ALLOC_PORT (T_UDP_CEP *cep, uint16_t portno)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_UDP_CEP));
+	for (ix = TMAX_UDP_CEPID; ix -- > 0; )
+		if (VALID_UDP_CEP(&UDP_CEP[ix]) && UDP_CEP[ix].myaddr.portno == portno) {
+			syscall(sig_sem(SEM_UDP_CEP));
+			return E_PAR;
+			}
+	cep->myaddr.portno = portno;
+	syscall(sig_sem(SEM_UDP_CEP));
+	return E_OK;
+	}
+
+/*
+ *  udp_find_cep -- ポート番号から UDP 通信端点を得る。
+ */
+
+T_UDP_CEP*
+UDP_FIND_CEP (T_NET_BUF *input, uint_t off)
+{
+	T_UDP_CEP*	cep;
+	T_UDP_HDR	*udph;
+
+	udph = GET_UDP_HDR(input, off);
+	
+	/*
+	 *  IP アドレスとポート番号が一致する通信端点を探索する。
+	 */
+	for (cep = &UDP_CEP[TMAX_UDP_CEPID]; cep -- != UDP_CEP; ) {
+		if (VALID_UDP_CEP(cep)                                &&
+		    UDP_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+		    ntohs(udph->dport) == cep->myaddr.portno)
+			return cep;
+		}
+
+	return NULL;
+	}
+
+/*
+ *  udp_notify -- ICMP エラーの処理
+ */
+
+void
+UDP_NOTIFY (T_NET_BUF *input, ER error)
+{
+	if (UDP_FIND_CEP(input, GET_UDP_HDR_OFFSET(input)) != NULL) {
+		syslog(LOG_NOTICE, "[UDP] error, code: %d.", error);
+		}
+	}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_usrreq.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_usrreq.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_usrreq.c	(revision 398)
@@ -0,0 +1,803 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce 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.
+ *
+ *	@(#)udp_usrreq.c	8.6 (Berkeley) 5/23/95
+ * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.49.2.2 1999/08/29 16:29:58 peter Exp $
+ */
+
+#ifdef __udp_send_data
+
+/*
+ *  udp_send_data -- パケット送信の主要部
+ */
+
+ER_UINT
+UDP_SEND_DATA (T_UDP_CEP *cep, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
+{
+	T_NET_BUF	*output;
+	T_UDP_HDR	*udph;
+	SYSTIM		before, after;
+	ER		error = E_OK;
+
+#ifdef UDP_CFG_OUT_CHECKSUM
+	uint16_t	sum;
+#endif	/* of #ifdef UDP_CFG_OUT_CHECKSUM */
+
+	NET_COUNT_UDP(net_count_udp.out_octets,  len);
+	NET_COUNT_UDP(net_count_udp.out_packets, 1);
+
+	/* IP データグラム割り当ての時間を tmout から減ずる。*/
+	if (!(tmout == TMO_POL || tmout == TMO_FEVR))
+		syscall(get_tim(&before));
+
+	/* IP データグラムを割り当てる。*/
+	if ((error = IN_GET_DATAGRAM(&output, (uint_t)(UDP_HDR_SIZE + len), 0,
+	                             &p_dstaddr->ipaddr,
+	                             &cep->myaddr.ipaddr,
+	                             IPPROTO_UDP, IP_DEFTTL, 
+	                             NBA_SEARCH_ASCENT, tmout)) != E_OK)
+		goto err_ret;
+
+	/* IP データグラム割り当ての時間を tmout から減ずる。*/
+	if (!(tmout == TMO_POL || tmout == TMO_FEVR)) {
+		syscall(get_tim(&after));
+		if (after - before > tmout) {
+			syscall(rel_net_buf(output));
+			error = E_TMOUT;
+			goto err_ret;
+			}
+		tmout -= (TMO)(after - before);
+		}
+
+	/* UDP ヘッダに情報を設定する。*/
+	udph		= GET_UDP_HDR(output, IF_IP_UDP_HDR_OFFSET(output));
+	udph->sport	= htons(cep->myaddr.portno);
+	udph->dport	= htons(p_dstaddr->portno);
+	udph->ulen	= htons(UDP_HDR_SIZE + len);
+	udph->sum	= 0;
+
+	/* データをコピーする。*/
+	memcpy((void*)GET_UDP_SDU(output, IF_IP_UDP_HDR_OFFSET(output)), data, (size_t)len);
+
+#ifdef UDP_CFG_OUT_CHECKSUM
+
+	sum = IN_CKSUM(output, IPPROTO_UDP, IF_IP_UDP_HDR_OFFSET(output), (uint_t)(UDP_HDR_SIZE + len));
+
+	/* 計算したチェックサムの値が 0 なら 0xffff を入れる。*/
+	if (sum == 0)
+		sum = 0xffff;
+	udph->sum = sum;
+
+#endif	/* of #ifdef UDP_CFG_OUT_CHECKSUM */
+
+	/* ネットワークバッファ長を調整する。*/
+	output->len = (uint16_t)(IF_IP_UDP_HDR_SIZE(output) + len);
+
+	/* ネットワーク層 (IP) の出力関数を呼び出す。*/
+	if ((error = IP_OUTPUT(output, tmout)) == E_OK) {
+		NET_COUNT_MIB(udp_stats.udpOutDatagrams, 1);
+		cep->snd_tskid = TA_NULL;
+		return len;
+		}
+
+err_ret:
+	NET_COUNT_UDP(net_count_udp.out_err_packets, 1);
+	cep->snd_tskid = TA_NULL;
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_send_data */
+
+/*
+ *  udp_cancel_cep -- ペンディングしている処理をキャンセルする。
+ *
+ *    udp_can_cep から呼出されるメイン関数
+ */
+
+#ifdef __udp_can_cep
+
+static ER
+UDP_CANCEL_CEP (T_UDP_CEP *cep, FN fncd)
+{
+	ER	error = E_OK, snd_err, rcv_err;
+
+	/* UDP 通信端点をチェックする。*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/* API 機能コードをチェックする。*/
+	if (!VALID_TFN_UDP_CAN(fncd))
+		return E_PAR;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	if (fncd == TFN_UDP_ALL) {	/* TFN_UDP_ALL の処理 */
+
+		snd_err = UDP_CAN_SND(cep, E_RLWAI);
+		rcv_err = UDP_CAN_RCV(cep, E_RLWAI);
+
+		/*
+		 *  snd_err と rcv_err のどちらも EV_NOPND
+		 *  なら、ペンディングしていないのでエラー
+		 */
+		if (snd_err == EV_NOPND && rcv_err == EV_NOPND)
+			error = E_OBJ;
+		else {
+			if (snd_err == EV_NOPND)
+				snd_err = E_OK;
+			if (rcv_err == EV_NOPND)
+				rcv_err = E_OK;
+
+			if (snd_err != E_OK)
+				error = snd_err;
+			else if (rcv_err != E_OK)
+				error = rcv_err;
+			}
+		}
+	else if (fncd == TFN_UDP_SND_DAT) {	/* 送信処理のキャンセル */
+		if ((error = UDP_CAN_SND(cep, E_RLWAI)) == EV_NOPND)
+			error = E_OBJ;
+		}
+	else if (fncd == TFN_UDP_RCV_DAT) {	/* 受信処理のキャンセル */
+		if ((error = UDP_CAN_RCV(cep, E_RLWAI)) == EV_NOPND)
+			error = E_OBJ;
+		}
+	else
+		error = E_PAR;
+
+	/* 通信端点をロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_can_cep */
+
+#if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0)
+
+#else	/* of #if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0) */
+
+/*
+ *  udp_can_cep -- ペンディングしている処理のキャンセル【標準機能】
+ */
+
+#ifdef __udp_can_cep
+
+ER
+udp_can_cep (ID cepid, FN fncd)
+{
+	T_UDP_CEP	*cep;
+
+	/* UDP 通信端点 ID をチェックする。*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP 通信端点を得る。*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* メイン関数を呼び出す。*/
+	return UDP_CANCEL_CEP(cep, fncd);
+	}
+
+#endif	/* of #ifdef __udp_can_cep */
+
+#endif	/* of #if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0) */
+
+#ifdef UDP_CFG_EXTENTIONS
+
+/*
+ *  udp_cre_cep -- UDP 通信端点の生成【拡張機能】
+ */
+
+#ifdef __udp_cre_cep
+
+ER
+UDP_CRE_CEP (ID cepid, T_UDPN_CCEP *pk_ccep)
+{
+	T_UDP_CEP	*cep;
+	ER		error;
+
+	/* UDP 通信端点 ID をチェックする。*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* pk_ccep が NULL ならエラー */
+	if (pk_ccep == NULL)
+		return E_PAR;
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
+	 * IPv4 射影アドレスが指定されたらエラー
+	 */
+	if (in6_is_addr_ipv4mapped(&pk_ccep->myaddr.ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+	/* UDP 通信端点を得る。*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* UDP 通信端点をチェックする。*/
+	if (VALID_UDP_CEP(cep))
+		return E_OBJ;
+
+	/* UDP 通信端点が、動的生成用でなければエラー */
+	if (!DYNAMIC_UDP_CEP(cep))
+		return E_ID;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 * UDP 通信端点をチェックする。生成済みであればエラー
+	 */
+	if (VALID_UDP_CEP(cep))
+		error = E_OBJ;
+	else {
+
+		/*
+		 *  自ポート番号が UDP_PORTANY なら、自動で割り当てる。
+		 */
+		if (pk_ccep->myaddr.portno == UDP_PORTANY)
+			error = UDP_ALLOC_AUTO_PORT(cep);
+		else 
+			error = UDP_ALLOC_PORT(cep, pk_ccep->myaddr.portno);
+
+			if (error == E_OK) {
+				/* UDP 通信端点生成情報をコピーする。*/
+				cep->cepatr        = pk_ccep->cepatr;			/* 通信端点属性		*/
+				cep->myaddr.ipaddr = pk_ccep->myaddr.ipaddr;		/* 自分のアドレス	*/
+				cep->callback      = (void*)pk_ccep->callback;		/* コールバック		*/
+
+				/* UDP 通信端点を生成済みにする。*/
+				cep->flags |= UDP_CEP_FLG_VALID;
+				}
+			}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_cre_cep */
+
+#ifdef __udp_del_cep
+
+/*
+ *  udp_delete_cep -- UDP 通信端点を削除する。
+ *
+ *    udp_del_cep から呼出されるメイン関数
+ */
+
+static ER
+UDP_DELETE_CEP (T_UDP_CEP *cep)
+{
+	ER	error;
+
+	/* UDP 通信端点をチェックする。*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/* UDP 通信端点が、動的生成用でなければエラー */
+	if (!DYNAMIC_UDP_CEP(cep))
+		return E_ID;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 * UDP 通信端点をチェックする。未生成の場合はエラー
+	 * ・未生成。
+	 */
+	if (!VALID_UDP_CEP(cep))
+		error = E_NOEXS;
+	else {
+		UDP_CAN_SND(cep, E_DLT);
+		UDP_CAN_RCV(cep, E_DLT);
+
+		/* UDP 通信端点を未生成にする。*/
+		cep->flags &= ~UDP_CEP_FLG_VALID;
+		error = E_OK;
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+/*
+ *  udp_del_cep -- UDP 通信端点の削除【拡張機能】
+ */
+
+ER
+UDP_DEL_CEP (ID cepid)
+{
+	T_UDP_CEP	*cep;
+
+	/* UDP 通信端点 ID をチェックする。*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP 通信端点を得る。*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* メイン関数を呼び出す。*/
+	return UDP_DELETE_CEP(cep);
+	}
+
+#endif	/* of #ifdef __udp_del_cep */
+
+#ifdef __udp_set_opt
+
+/*
+ *  udp_set_option -- UDP 通信端点オプションを設定する。
+ *
+ *    udp_set_opt から呼出されるメイン関数
+ */
+
+static ER
+UDP_SET_OPTION (T_UDP_CEP *cep, int_t optname, void *optval, int_t optlen)
+{
+	/* UDP 通信端点をチェックする。*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+#if defined(SUPPORT_INET6)
+#elif defined(SUPPORT_INET4) && defined(SUPPORT_IGMP) && TNUM_UDP4_CEPID > 0
+	switch (optname) {
+	case IP_MULTICAST_LOOP:
+		if (optlen >= sizeof(uint8_t)) {
+			return igmp_set_loop(cep, *(uint8_t *)optval);
+			}
+		break;
+	case IP_MULTICAST_TTL:
+		if (optlen >= sizeof(uint8_t)) {
+			return igmp_set_ttl(cep, *(uint8_t *)optval);
+			}
+		break;
+	case IP_MULTICAST_IF:
+		if (optlen >= sizeof(T_IN4_ADDR)) {
+			return igmp_set_if(cep, (T_IN4_ADDR *)optval);
+			}
+		break;
+	case IP_ADD_MEMBERSHIP:
+		if (optlen >= sizeof(T_IP_MREQ)) {
+			return igmp_add_membership(cep, (T_IP_MREQ *)optval);
+			}
+		break;
+	case IP_DROP_MEMBERSHIP:
+		if (optlen >= sizeof(T_IP_MREQ)) {
+			return igmp_drop_membership(cep, (T_IP_MREQ *)optval);
+			}
+		break;
+	case IP_MSFILTER:
+		if (optlen >= sizeof(T_IP_MSFILTER)) {
+			return igmp_set_ip_msfilter(cep, (T_IP_MSFILTER *)optval);
+			}
+		break;
+		}
+#endif
+	return E_PAR;
+	}
+
+/*
+ *  udp_set_opt -- UDP 通信端点オプションの設定【拡張機能】
+ *
+ *  注意: 設定可能な UDP 通信端点オプションは無いため、E_PAR が返される。
+ */
+
+ER
+UDP_SET_OPT (ID cepid, int_t optname, void *optval, int_t optlen)
+{
+	T_UDP_CEP	*cep;
+
+	/* UDP 通信端点 ID をチェックする。*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP 通信端点を得る。*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* メイン関数を呼び出す。*/
+	return UDP_SET_OPTION(cep, optname, optval, optlen);
+	}
+
+#endif	/* of #ifdef __udp_set_opt */
+
+#ifdef __udp_get_opt
+
+/*
+ *  udp_get_option -- UDP 通信端点オプションを獲得する。
+ *
+ *    udp_get_opt から呼出されるメイン関数
+ */
+
+static ER
+UDP_GET_OPTION (T_UDP_CEP *cep, int_t optname, void *optval, int_t optlen)
+{
+	/* UDP 通信端点をチェックする。*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+#if defined(SUPPORT_INET6)
+#elif defined(SUPPORT_INET4) && defined(SUPPORT_IGMP) && TNUM_UDP4_CEPID > 0
+	switch (optname) {
+	case IP_MULTICAST_LOOP:
+		if (optlen >= sizeof(uint8_t)) {
+			return igmp_get_loop(cep, (uint8_t *)optval);
+			}
+		break;
+	case IP_MULTICAST_TTL:
+		if (optlen >= sizeof(uint8_t)) {
+			return igmp_get_ttl(cep, (uint8_t *)optval);
+			}
+		break;
+	case IP_MULTICAST_IF:
+		if (optlen >= sizeof(uint32_t)) {
+			return igmp_get_if(cep, (uint32_t *)optval);
+			}
+		break;
+	case IP_MSFILTER:
+		if (optlen >= sizeof(T_IP_MSFILTER)) {
+			return igmp_get_ip_msfilter(cep, (T_IP_MSFILTER *)optval);
+			}
+		break;
+		}
+#endif
+	return E_PAR;
+	}
+
+/*
+ *  udp_get_opt -- UDP 通信端点オプションの獲得【拡張機能】
+ *
+ *  注意: 設定可能な UDP 通信端点オプションは無いため、E_PAR が返される。
+ */
+
+ER
+UDP_GET_OPT (ID cepid, int_t optname, void *optval, int_t optlen)
+{
+	T_UDP_CEP	*cep;
+
+	/* UDP 通信端点 ID をチェックする。*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP 通信端点を得る。*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* メイン関数を呼び出す。*/
+	return UDP_GET_OPTION(cep, optname, optval, optlen);
+	}
+
+#endif	/* of #ifdef __udp_get_opt */
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+#ifdef UDP_CFG_NON_BLOCKING
+
+#else	/* of #ifdef UDP_CFG_NON_BLOCKING */
+
+#ifdef __udp_can_snd
+
+/*
+ *  udp_can_snd -- ペンディングしている送信のキャンセル
+ */
+
+ER
+UDP_CAN_SND (T_UDP_CEP *cep, ER error)
+{
+	if (cep->snd_tskid != TA_NULL) {	/* 非ノンブロッキングコールでペンディング中 */
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* 待ち中に発生したエラー情報を設定する。*/
+		cep->error = error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		error = rel_wai(cep->snd_tskid);
+		cep->snd_tskid = TA_NULL;
+		}
+	else					/* どちらでもないならペンディングしていない */
+		error = EV_NOPND;
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_can_snd */
+
+#ifdef __udp_can_rcv
+
+/*
+ *  udp_can_rcv -- ペンディングしている受信のキャンセル
+ */
+
+ER
+UDP_CAN_RCV (T_UDP_CEP *cep, ER error)
+{
+	if (cep->rcv_tskid != TA_NULL) {	/* 非ノンブロッキングコールでペンディング中 */
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* 待ち中に発生したエラー情報を設定する。*/
+		cep->error = error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		error = rel_wai(cep->rcv_tskid);
+		cep->rcv_tskid = TA_NULL;
+		}
+	else					/* どちらでもないならペンディングしていない */
+		error = EV_NOPND;
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_can_rcv */
+
+#ifdef __udp_snd_dat
+
+/*
+ *  udp_snd_dat -- パケットの送信【標準機能】
+ */
+
+ER_UINT
+UDP_SND_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
+{
+	T_UDP_CEP	*cep;
+	ER		error;
+
+	/* p_dstaddr または data が NULL か、tmout が TMO_NBLK ならエラー */
+	if (p_dstaddr == NULL || data == NULL || tmout == TMO_NBLK)
+		return E_PAR;
+
+	/* データ長をチェックする。*/
+	if (len < 0 || len + IP_HDR_SIZE + UDP_HDR_SIZE > IF_MTU)
+		return E_PAR;
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
+	 * IPv4 射影アドレスが指定されたらエラー
+	 */
+	if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+	/* UDP 通信端点 ID をチェックする。*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP 通信端点を得る。*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* UDP 通信端点をチェックする。*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/*
+	 *  自ポート番号が UDP_PORTANY なら、自動で割り当てる。
+	 */
+	if (cep->myaddr.portno == UDP_PORTANY) {
+		if ((error = UDP_ALLOC_AUTO_PORT(cep)) != E_OK)
+			return error;
+		}
+	
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	if (cep->snd_tskid != TA_NULL) {
+
+		/* 非ノンブロッキングコールでペンディング中 */
+		error = E_QOVR;
+
+		/* 通信端点をロックを解除する。*/
+		syscall(sig_sem(cep->semid_lock));
+		}
+	else {
+		/* 現在のタスク識別子を記録する。*/
+		get_tid(&(cep->snd_tskid));
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* 待ち中に発生したエラー情報をリセットする。*/
+		cep->error = E_OK;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		/* 通信端点をロックを解除する。*/
+		syscall(sig_sem(cep->semid_lock));
+
+		/* パケットを送信する。*/
+		error = UDP_SEND_DATA(cep, p_dstaddr, data, len, tmout);
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* 待ち中に発生したエラー情報を返す。*/
+		if (error == E_RLWAI)
+			error = cep->error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+		}
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_snd_dat */
+
+#ifdef __udp_rcv_dat
+
+/*
+ *  udp_rcv_dat -- パケットの受信【標準機能】
+ */
+
+ER_UINT
+UDP_RCV_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
+{
+	T_NET_BUF	*input;
+	T_UDP_CEP	*cep;
+	T_UDP_HDR	*udph;
+	ER_UINT		error;
+	uint_t		ulen, uhoff;
+
+	/* p_dstaddr または data が NULL 、len < 0 か、tmout が TMO_NBLK ならエラー */
+	if (p_dstaddr == NULL || data == NULL || len < 0 || tmout == TMO_NBLK)
+		return E_PAR;
+
+	/* UDP 通信端点 ID をチェックする。*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP 通信端点を得る。*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* UDP 通信端点をチェックする。*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	if (cep->rcv_tskid != TA_NULL) {
+
+		/* 非ノンブロッキングコールでペンディング中 */
+		error = E_QOVR;
+
+		/* 通信端点をロックを解除する。*/
+		syscall(sig_sem(cep->semid_lock));
+		}
+	else {
+
+		/* 現在のタスク識別子を記録する。*/
+		get_tid(&(cep->rcv_tskid));
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* 待ち中に発生したエラー情報をリセットする。*/
+		cep->error = E_OK;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		/* 通信端点をロックを解除する。*/
+		syscall(sig_sem(cep->semid_lock));
+
+		/* 入力があるまで待つ。*/
+		if (cep->cb_netbuf != NULL) {
+
+			/*
+			 *  ここにくる場合は、コールバック関数の中から
+			 *  udp_rcv_dat を呼び出していることになり、
+			 *  すでに入力済みである。
+			 */
+			input = cep->cb_netbuf;
+			cep->cb_netbuf = NULL;
+			}
+		else if ((error = trcv_dtq(cep->rcvqid, (intptr_t*)&input, tmout)) != E_OK) {
+
+#ifdef UDP_CFG_EXTENTIONS
+
+			/* 待ち中に発生したエラー情報を返す。*/
+			if (error == E_RLWAI)
+				error = cep->error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+			cep->rcv_tskid = TA_NULL;
+			return error;
+			}
+
+		/* p_dstaddr を設定する。*/
+		uhoff = (uint_t)GET_UDP_HDR_OFFSET(input);
+		udph = GET_UDP_HDR(input, uhoff);
+		p_dstaddr->portno = ntohs(udph->sport);
+		IN_COPY_TO_HOST(&p_dstaddr->ipaddr, input);
+
+		/* データをバッファに移す。*/
+		ulen = ntohs(udph->ulen);
+		if (ulen - UDP_HDR_SIZE > len)
+			error = E_BOVR;
+		else {
+			len   =    (uint_t)(ulen - UDP_HDR_SIZE);
+			error = (ER_UINT)(ulen - UDP_HDR_SIZE);
+			}
+
+		memcpy(data, GET_UDP_SDU(input, uhoff), (size_t)len);
+
+		syscall(rel_net_buf(input));
+
+		cep->rcv_tskid = TA_NULL;
+		}
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_rcv_dat */
+
+#endif	/* of #ifdef UDP_CFG_NON_BLOCKING */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_usrreq_nblk.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_usrreq_nblk.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet/udpn_usrreq_nblk.c	(revision 398)
@@ -0,0 +1,408 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce 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.
+ *
+ *	@(#)udp_usrreq.c	8.6 (Berkeley) 5/23/95
+ * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.49.2.2 1999/08/29 16:29:58 peter Exp $
+ */
+
+#ifdef __udp_can_snd_nblk
+
+/*
+ *  udp_can_snd -- ペンディングしている送信のキャンセル
+ */
+
+ER
+UDP_CAN_SND (T_UDP_CEP *cep, ER error)
+{
+	if (cep->snd_p_dstaddr != NULL) {	/* ノンブロッキングコールでペンディング中 */
+		if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)error);
+#else
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)&error);
+#endif
+		else
+			error = E_OBJ;
+		cep->snd_p_dstaddr = NULL;
+		}
+	else if (cep->snd_tskid != TA_NULL) {	/* 非ノンブロッキングコールでペンディング中 */
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* 待ち中に発生したエラー情報を設定する。*/
+		cep->error = error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		error = rel_wai(cep->snd_tskid);
+		cep->snd_tskid = TA_NULL;
+		}
+	else					/* どちらでもないならペンディングしていない */
+		error = EV_NOPND;
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_can_snd_nblk */
+
+#ifdef __udp_can_rcv_nblk
+
+/*
+ *  udp_can_rcv -- ペンディングしている受信のキャンセル
+ */
+
+ER
+UDP_CAN_RCV (T_UDP_CEP *cep, ER error)
+{
+	if (cep->rcv_p_dstaddr != NULL) {	/* ノンブロッキングコールでペンディング中 */
+		if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_CAN_CEP, (void*)error);
+#else
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_CAN_CEP, (void*)&error);
+#endif
+		else
+			error = E_OBJ;
+		cep->rcv_p_dstaddr = NULL;
+		}
+	else if (cep->rcv_tskid != TA_NULL) {	/* 非ノンブロッキングコールでペンディング中 */
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* 待ち中に発生したエラー情報を設定する。*/
+		cep->error = error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		error = rel_wai(cep->rcv_tskid);
+		cep->rcv_tskid = TA_NULL;
+		}
+	else					/* どちらでもないならペンディングしていない */
+		error = EV_NOPND;
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_can_rcv_nblk */
+
+#ifdef __udp_snd_dat_nblk
+
+/*
+ *  udp_snd_dat -- パケットの送信【標準機能】
+ */
+
+ER_UINT
+UDP_SND_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
+{
+	T_UDP_CEP	*cep;
+	ER		error;
+
+	/* p_dstaddr または data が NULL ならエラー */
+	if (p_dstaddr == NULL || data == NULL)
+		return E_PAR;
+
+	/* データ長をチェックする。*/
+	if (len < 0 || len + IP_HDR_SIZE + UDP_HDR_SIZE > IF_MTU)
+		return E_PAR;
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API が IPv6 で IPv4 射影アドレスが認められていないのにもかかわらず、
+	 * IPv4 射影アドレスが指定されたらエラー
+	 */
+	if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+	/* UDP 通信端点 ID をチェックする。*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP 通信端点を得る。*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* UDP 通信端点をチェックする。*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/*
+	 *  自ポート番号が UDP_PORTANY なら、自動で割り当てる。
+	 */
+	if (cep->myaddr.portno == UDP_PORTANY) {
+		if ((error = UDP_ALLOC_AUTO_PORT(cep)) != E_OK)
+			return error;
+		}
+
+	/*
+	 * タイムアウトをチェックする。
+	 */
+	if (tmout == TMO_NBLK) {	/* ノンブロッキングコール */
+
+		/* 通信端点をロックする。*/
+		syscall(wai_sem(cep->semid_lock));
+
+		if (cep->snd_p_dstaddr != NULL) {
+
+			/* ノンブロッキングコールでペンディング中 */
+			error = E_QOVR;
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else if (cep->snd_tskid != TA_NULL) {
+
+			/* 非ノンブロッキングコールでペンディング中 */
+			error = E_OBJ;
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else {
+
+			cep->snd_p_dstaddr = p_dstaddr;
+			cep->snd_data	= data;
+			cep->snd_len	= len;
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+
+			cep->flags |= UDP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_UDP_POST_OUTPUT);
+			error = E_WBLK;
+			}
+		}
+	else {				/* 非ノンブロッキングコール */
+	
+		/* 通信端点をロックする。*/
+		syscall(wai_sem(cep->semid_lock));
+
+		if (cep->snd_p_dstaddr != NULL) {
+
+			/* ノンブロッキングコールでペンディング中 */
+			error = E_OBJ;
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else if (cep->snd_tskid != TA_NULL) {
+
+			/* 非ノンブロッキングコールでペンディング中 */
+			error = E_QOVR;
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else {
+
+			/* 現在のタスク識別子を記録する。*/
+			get_tid(&(cep->snd_tskid));
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+
+			/* パケットを送信する。*/
+			error = UDP_SEND_DATA(cep, p_dstaddr, data, len, tmout);
+			}
+		}
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_snd_dat_nblk */
+
+#ifdef __udp_rcv_dat_nblk
+
+/*
+ *  udp_rcv_dat -- パケットの受信【標準機能】
+ */
+
+ER_UINT
+UDP_RCV_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
+{
+	T_NET_BUF	*input;
+	T_UDP_CEP	*cep;
+	T_UDP_HDR	*udph;
+	ER_UINT		error;
+	uint_t		ulen, uhoff;
+
+	/* p_dstaddr または data が NULL か、len < 0 ならエラー */
+	if (p_dstaddr == NULL || data == NULL || len < 0)
+		return E_PAR;
+
+	/* UDP 通信端点 ID をチェックする。*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP 通信端点を得る。*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* UDP 通信端点をチェックする。*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/*
+	 * タイムアウトをチェックする。
+	 */
+
+	if (tmout == TMO_NBLK) {	/* ノンブロッキングコール */
+
+		/* 通信端点をロックする。*/
+		syscall(wai_sem(cep->semid_lock));
+
+		if (cep->rcv_p_dstaddr != NULL)
+
+			/* ノンブロッキングコールでペンディング中 */
+			error = E_QOVR;
+
+		else if (cep->rcv_tskid != TA_NULL)
+
+			/* 非ノンブロッキングコールでペンディング中 */
+			error = E_OBJ;
+		else {
+			cep->rcv_p_dstaddr = p_dstaddr;
+			cep->rcv_data	= data;
+			cep->rcv_len	= len;
+			error = E_WBLK;
+			}
+
+		/* 通信端点をロックを解除する。*/
+		syscall(sig_sem(cep->semid_lock));
+		return error;
+		}
+	else {				/* 非ノンブロッキングコール */
+
+		/* 通信端点をロックする。*/
+		syscall(wai_sem(cep->semid_lock));
+
+		if (cep->rcv_p_dstaddr != NULL) {
+
+			/* ノンブロッキングコールでペンディング中 */
+			error = E_OBJ;
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else if (cep->rcv_tskid != TA_NULL) {
+
+			/* 非ノンブロッキングコールでペンディング中 */
+			error = E_QOVR;
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else {
+
+			/* 現在のタスク識別子を記録する。*/
+			get_tid(&(cep->rcv_tskid));
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+
+			/* 入力があるまで待つ。*/
+			if (cep->cb_netbuf != NULL) {
+
+				/*
+				 *  ここにくる場合は、コールバック関数の中から
+				 *  udp_rcv_dat を呼び出していることになり、
+				 *  すでに入力済みである。
+				 */
+				input = cep->cb_netbuf;
+				cep->cb_netbuf = NULL;
+				}
+			else if ((error = trcv_dtq(cep->rcvqid, (intptr_t*)&input, tmout)) != E_OK) {
+				cep->rcv_tskid = TA_NULL;
+				return error;
+				}
+
+			/* p_dstaddr を設定する。*/
+			uhoff = (uint_t)GET_UDP_HDR_OFFSET(input);
+			udph = GET_UDP_HDR(input, uhoff);
+			p_dstaddr->portno = ntohs(udph->sport);
+			IN_COPY_TO_HOST(&p_dstaddr->ipaddr, input);
+
+			/* データをバッファに移す。*/
+			ulen = ntohs(udph->ulen);
+			if (ulen - UDP_HDR_SIZE > len)
+				error = E_BOVR;
+			else {
+				len   =     (int_t)(ulen - UDP_HDR_SIZE);
+				error = (ER_UINT)(ulen - UDP_HDR_SIZE);
+				}
+
+			memcpy(data, GET_UDP_SDU(input, uhoff), (size_t)len);
+
+			syscall(rel_net_buf(input));
+
+			cep->rcv_tskid = TA_NULL;
+			}
+		return error;
+		}
+	}
+
+#endif	/* of #ifdef __udp_rcv_dat_nblk */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ah.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ah.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ah.h	(revision 398)
@@ -0,0 +1,82 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/ah.h,v 1.7 2002/04/19 04:46:22 suz Exp $	*/
+/*	$KAME: ah.h,v 1.16 2001/09/04 08:43:19 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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 _AH_H_
+#define _AH_H_
+
+/*
+ *  RFC2402 認証ヘッダ
+ */
+
+typedef struct t_ip6_ah_hdr {
+	uint8_t		next;	/* Next Header				*/
+	uint8_t		len;	
+	/* 4 オクテット単位の長さ。ただし、データ長 + 1 が入る。	*/
+	uint16_t	reserved;
+	uint32_t	spi;	/* Security Parameter Index (SPI)	*/
+	uint32_t	seq;	/* シーケンス番号			*/
+	} __attribute__((packed, aligned(2))) T_IP6_AH_HDR;
+
+#endif	/* of #ifndef _AH_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ah6.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ah6.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ah6.h	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/ah6.h,v 1.4 2001/06/11 12:39:03 ume Exp $	*/
+/*	$KAME: ah.h,v 1.13 2000/10/18 21:28:00 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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 _AH6_H_
+#define _AH6_H_
+
+/*
+ *  関数
+ */
+
+extern uint_t ah6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+
+#endif	/* of #ifndef _AH6_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ah_input.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ah_input.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ah_input.c	(revision 398)
@@ -0,0 +1,118 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/ah_input.c,v 1.12 2002/04/19 04:46:22 suz Exp $	*/
+/*	$KAME: ah_input.c,v 1.67 2002/01/07 11:39:56 kjc Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/ppp_ipcp.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet6/nd6.h>
+#include <netinet6/ah.h>
+#include <netinet6/ah6.h>
+
+#ifdef _IP6_CFG
+
+/*
+ *  ah6_input -- 認証ヘッダの入力関数
+ *
+ *    本実装では、データグラムを破棄する。
+ */
+
+uint_t
+ah6_input (T_NET_BUF **input, uint_t *offp, uint_t *nextp)
+{
+	syscall(rel_net_buf(*input));
+	return IPPROTO_DONE;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/dest6.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/dest6.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/dest6.c	(revision 398)
@@ -0,0 +1,165 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/dest6.c,v 1.7 2002/04/19 04:46:22 suz Exp $	*/
+/*	$KAME: dest6.c,v 1.34 2002/01/08 02:40:55 k-sugyou Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet6/nd6.h>
+
+#ifdef _IP6_CFG
+
+/*
+ *  dest6_input -- 終点オプションヘッダの入力関数
+ *
+ *    本実装では、パディング以外のオプションを全て未知オプションとして処理する。
+ */
+
+uint_t
+dest6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+	T_NET_BUF	*input = *inputp;
+	T_IP6_DEST_HDR	*desth;
+	ER_UINT		optlen;
+	uint_t		len, off = *offp;
+	uint8_t		*opt;
+
+	/* ネットワークバッファの残りの長さをチェックする。*/
+	if (input->len - off < sizeof(T_IP6_DEST_HDR))
+		goto buf_rel;
+
+	desth  = (T_IP6_DEST_HDR *)(input->buf + off);
+	len    = (desth->len + 1) << 3;
+
+	/* 終点オプションヘッダの長さをチェックする。*/
+	if (input->len < off + len)
+		goto buf_rel;
+
+	*nextp = *offp - IF_HDR_SIZE + offsetof(T_IP6_DEST_HDR, next);
+	*offp += len;
+	opt    = (uint8_t *)desth + sizeof(T_IP6_DEST_HDR);
+
+	for (len -= sizeof(T_IP6_DEST_HDR); len > 0; len -= optlen) {
+		switch (*opt) {
+		case IP6OPT_PAD1:
+			optlen = 1;
+			break;
+		case IP6OPT_PADN:
+			if (len < IP6OPT_MINLEN)
+				goto buf_rel;
+			optlen = *(opt + 1) + 2;
+			break;
+		default:
+			if (len < IP6OPT_MINLEN)
+				goto buf_rel;
+			optlen = ip6_unknown_opt(input, opt);
+			if (optlen == IP6_OPT_RET_ERR)
+				goto buf_rel;
+			else if (optlen == IP6_OPT_RET_REL)
+				return IPPROTO_DONE;
+			optlen += 2;
+			break;
+			}
+
+		opt += optlen;
+		}
+
+	return desth->next;
+
+buf_rel:
+	syscall(rel_net_buf(input));
+	return IPPROTO_DONE;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/esp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/esp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/esp.h	(revision 398)
@@ -0,0 +1,129 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2008-2009 by Hokkaido Industrial Research Institute, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/esp.h,v 1.6 2002/04/19 04:46:22 suz Exp $	*/
+/*	$KAME: esp.h,v 1.19 2001/09/04 08:43:19 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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 _ESP_H_
+#define _ESP_H_
+
+/*
+ *  RFC2406 暗号化ヘッダ
+ */
+
+typedef struct t_esp_hdr {
+	int32_t	spi;	/* Security Parameter Index (SPI)	*/
+	int32_t	seq;	/* シーケンス番号			*/
+	} __attribute__((packed, aligned(2)))T_ESP_HDR;
+
+typedef struct t_esp_tail {
+	int8_t	padlen;	/* パディング長				*/	
+	int8_t	next;	/* Next Header				*/
+	} __attribute__((packed, aligned(2)))T_ESP_TAIL;
+
+struct t_secas_var;
+
+struct t_esp_algorithm {
+	size_t padbound;	/* pad boundary, in byte */
+	int_t ivlenval;		/* iv length, in byte */
+	int_t (*mature) (struct t_secas_var *);
+	int_t keymin;	/* in bits */
+	int_t keymax;	/* in bits */
+	//int_t (*schedlen) (const struct t_esp_algorithm *);
+	int32_t (*schedlen) (const struct t_esp_algorithm *);
+	const char *name;
+	int_t (*ivlen) (const struct t_esp_algorithm *, struct t_secas_var *);
+	int_t (*decrypt) (T_NET_BUF *, size_t,
+		struct t_secas_var *, const struct t_esp_algorithm *, int_t,
+			T_NET_BUF *, size_t);
+	int_t (*encrypt) (T_NET_BUF *, size_t, size_t, int8_t*,
+		struct t_secas_var *, const struct t_esp_algorithm *, int_t,
+			T_NET_BUF *, size_t);
+	/* not supposed to be called directly */
+	int_t (*schedule) (const struct t_esp_algorithm *, struct t_secas_var *);
+	int_t (*blockdecrypt) (const struct t_esp_algorithm *,
+		struct t_secas_var *, int8_t *, int8_t *);
+	int_t (*blockencrypt) (const struct t_esp_algorithm *,
+		struct t_secas_var *, int8_t *, int8_t *);
+};
+
+typedef struct t_esp_algorithm T_ESP_ALGORITHM;
+
+#define MAXIVLEN	16
+
+/*
+ * 関数
+ */
+
+extern const struct t_esp_algorithm *esp_algorithm_lookup (int_t);
+extern int_t esp_max_ivlen (void);
+extern int_t esp_schedule (const struct t_esp_algorithm *, struct t_secas_var *);
+extern int_t esp4_input(T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+
+#ifdef T_IPSEC_REQUEST_DEFINED
+
+extern int_t esp4_output(T_NET_BUF *m, T_IPSEC_REQUEST *isr, T_NET_BUF** result);
+
+#endif	/* of #ifdef T_IPSEC_REQUEST_DEFINED */
+
+#endif	/* of #ifndef _ESP_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/esp6.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/esp6.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/esp6.h	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/esp6.h,v 1.4 2001/06/11 12:39:04 ume Exp $	*/
+/*	$KAME: esp.h,v 1.16 2000/10/18 21:28:00 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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 _ESP6_H_
+#define _ESP6_H_
+
+/*
+ *  関数
+ */
+
+extern uint_t esp6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+
+#endif	/* of #ifndef _ESP6_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/esp_input.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/esp_input.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/esp_input.c	(revision 398)
@@ -0,0 +1,124 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/esp_input.c,v 1.14 2002/08/24 04:48:13 ume Exp $	*/
+/*	$KAME: esp_input.c,v 1.62 2002/01/07 11:39:57 kjc Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet6/nd6.h>
+#include <netinet6/ah.h>
+#include <netinet6/ah6.h>
+#include <netinet6/esp.h>
+#include <netinet6/esp6.h>
+
+#ifdef _IP6_CFG
+
+/*
+ *  esp6_input -- 暗号化ヘッダの入力関数
+ *
+ *    本実装では、データグラムを破棄する。
+ */
+
+uint_t
+esp6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+#if 0
+	*nextp = <T_ESP_TAIL の next フィールドの位置（IPv6 ヘッダの先頭からのオフセット）>;
+	*offp  = <次ヘッダの位置（input->buf からのオフセット）>;
+#endif
+	syscall(rel_net_buf(*inputp));
+	return IPPROTO_DONE;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/frag6.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/frag6.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/frag6.c	(revision 398)
@@ -0,0 +1,671 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/frag6.c,v 1.9 2002/04/19 04:46:22 suz Exp $	*/
+/*	$KAME: frag6.c,v 1.33 2002/01/07 11:34:48 kjc Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_var.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet6/nd6.h>
+
+#ifdef _IP6_CFG
+
+#ifdef IP6_CFG_FRAGMENT
+
+/*
+ *  データグラム再構成キュー配列
+ */
+
+static T_NET_BUF	*ip6_frag_queue[NUM_IP6_FRAG_QUEUE];
+static T_IN6_ADDR	 ip6_frag_dest [NUM_IP6_FRAG_QUEUE];
+
+/*
+ *  ip6_get_frag_queue -- データグラム再構成キューを獲得する。
+ */
+
+const T_NET_BUF **
+ip6_get_frag_queue (void)
+{
+	return (const T_NET_BUF **)ip6_frag_queue;
+	}
+
+/*
+ *  frag6_free_queue -- データグラム再構成キューを解放する。
+ *
+ *    注意: データグラム再構成キュー配列をロックしてから呼び出すこと。
+ */
+
+static void
+frag6_free_queue (T_NET_BUF **queue)
+{
+	T_NET_BUF 	*frag, *next;
+	T_QIP6_HDR	*qip6h;
+
+	frag = *queue;
+	while (frag != NULL) {
+		qip6h = GET_QIP6_HDR(frag);
+		next  = qip6h->next_frag;
+		syscall(rel_net_buf(frag));
+		frag = next;
+		}
+	*queue = NULL;
+	}
+
+/*
+ *  frag6_timer -- データグラム再構成管理タイマ
+ */
+
+void
+frag6_timer (void)
+{
+	T_NET_BUF	*frag;
+	T_QIP6_HDR	*qip6h;
+	T_IP6_FRAG_HDR	*qip6fh;
+	int_t		ix;
+
+	syscall(wai_sem(SEM_IP6_FRAG_QUEUE));
+	for (ix = NUM_IP6_FRAG_QUEUE; ix -- > 0; ) {
+		frag = ip6_frag_queue[ix];
+		if (frag != NULL) {
+			qip6h = GET_QIP6_HDR(frag);
+			if (qip6h->ftim > 0 && -- qip6h->ftim == 0) {
+
+				qip6fh = (T_IP6_FRAG_HDR *)(frag->buf + qip6h->foff);
+				if (ntohs(qip6fh->off_flag & IP6F_OFF_MASK) == 0) {
+
+					/*
+					 *  先頭の断片のオフセットが 0 の時のみ
+					 *  ICMPv6 エラーメッセージを送信する。
+					 */
+
+					/* 先頭の断片をデータグラム再構成キューから外す。*/
+					ip6_frag_queue[ix] = qip6h->next_frag;
+
+					/* あて先アドレスを元に戻す。*/
+					GET_IP6_HDR(frag)->dst = ip6_frag_dest[ix];
+
+					/* ICMPv6 エラーメッセージを送信する。*/
+					icmp6_error(frag, ICMP6_TIME_EXCEEDED,
+					                  ICMP6_TIME_EXCEED_REASSEMBLY, 0);
+					}
+
+				/* データグラム再構成キューを解放する。*/
+				NET_COUNT_IP6(net_count_ip6[NC_IP6_FRAG_IN_TMOUT], 1);
+				NET_COUNT_IP6(net_count_ip6[NC_IP6_FRAG_IN_DROP], 1);
+				frag6_free_queue(&ip6_frag_queue[ix]);
+				}
+			}
+		}
+	syscall(sig_sem(SEM_IP6_FRAG_QUEUE));
+	}
+
+#endif	/* #ifdef IP6_CFG_FRAGMENT */
+
+/*
+ *  frag6_input -- 断片ヘッダの入力関数
+ */
+
+uint_t
+frag6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+	T_IP6_HDR	*ip6h;
+	T_IP6_FRAG_HDR	*ip6fh;
+	T_NET_BUF	*input = *inputp;
+	uint_t		off = *offp;
+
+#ifdef IP6_CFG_FRAGMENT
+
+	T_QIP6_HDR	*qip6h, *rip6h;
+	T_IP6_FRAG_HDR	*qip6fh = NULL;
+	T_NET_BUF	**ip6fq = NULL, *prev, *next, *frag;
+	int_t		ix;
+	int32_t		unfraglen, diff;
+	uint16_t	fragpartlen, qfragpartlen, fragoff, qfragoff, plen;
+	uint8_t		ftim, *prev_next;
+	uint_t		nextproto = IPPROTO_DONE;
+
+#endif	/* #ifdef IP6_CFG_FRAGMENT */
+
+	/* ネットワークバッファの残りの長さをチェックする。*/
+	if (input->len - off < sizeof(T_IP6_FRAG_HDR))
+		goto buf_rel;
+
+	/* 
+	 *  巨大ペイロードオプションと断片ヘッダを同時に使用することは
+	 *  できない。ペイロード長がが 0 なら、巨大ペイロードオプションが
+	 *  指定されていることになるので ICMP でエラーを送信者に
+	 *  通知する。
+	 */
+	ip6h = GET_IP6_HDR(input);
+	if (ip6h->plen == 0) {
+		icmp6_error(input, ICMP6_PARAM_PROB,
+		                   ICMP6_PARAMPROB_HEADER,
+		                   off - IF_HDR_SIZE);
+		NET_COUNT_MIB(in6_stats.ipv6IfStatsReasmFails, 1);
+		return IPPROTO_DONE;
+		}
+
+	/*
+	 *  オフセットが 0 で、最終フラグメントであれば、
+	 *  分割不要のデータグラムなので、
+	 *  次ヘッダを指す変数を調整して終了する。
+	 */
+	ip6fh = (T_IP6_FRAG_HDR *)(input->buf + off);
+	if (ip6fh->off_flag == 0) {
+		*nextp = *offp - IF_HDR_SIZE + offsetof(T_IP6_FRAG_HDR, next);
+		*offp = off + sizeof(T_IP6_FRAG_HDR);
+		return ip6fh->next;
+		}
+
+#ifdef IP6_CFG_FRAGMENT
+
+	/*
+	 *  ペイロード長をチェックする。
+	 */
+	if ((ip6fh->off_flag & IP6F_MORE_FRAG) && 
+	    ((ntohs(ip6h->plen) - (off - IF_HDR_SIZE)) & 0x7) != 0) {
+		icmp6_error(input, ICMP6_PARAM_PROB,
+		                   ICMP6_PARAMPROB_HEADER,
+		                   offsetof(T_IP6_HDR, plen));
+		NET_COUNT_MIB(in6_stats.ipv6IfStatsReasmFails, 1);
+		return nextproto;
+		}
+	NET_COUNT_MIB(in6_stats.ipv6IfStatsReasmReqds, 1);
+
+	syscall(wai_sem(SEM_IP6_FRAG_QUEUE));
+
+	/*
+ 	 *  データグラム再構成キュー配列から、対応するエントリを探す。
+ 	 */
+	for (ix = NUM_IP6_FRAG_QUEUE; ix -- > 0; ) {
+		if (ip6_frag_queue[ix] != NULL) {
+			qip6h  = GET_QIP6_HDR(ip6_frag_queue[ix]);
+			qip6fh = (T_IP6_FRAG_HDR *)(ip6_frag_queue[ix]->buf + qip6h->foff);
+			if (ip6fh->ident == qip6fh->ident               &&
+			    IN6_ARE_ADDR_EQUAL(&ip6h->src, &qip6h->src) &&
+			    IN6_ARE_ADDR_EQUAL(&ip6h->dst, &ip6_frag_dest[ix])) {
+				ip6fq = &ip6_frag_queue[ix];
+			    	break;
+			    	}
+			}
+		}
+
+ 	if (ip6fq == NULL) {
+
+		/*
+	 	 *  断片の正当性をチェックする。
+		 */
+		unfraglen = 0;
+		fragoff = ntohs(ip6fh->off_flag & IP6F_OFF_MASK);
+		if (fragoff == 0) {
+
+			/*
+		 	 *  入力した断片が先頭の断片
+			 *  分割できない部分の長さ unfraglen を計算する。
+			 */
+			unfraglen = (off - IF_HDR_SIZE) - sizeof(T_IP6_HDR);
+			}
+
+		/*
+		 *             off
+		 *  |<--------------------------->|
+		 *  |          off - IF_HDR_SIZE  |
+		 *  |        |<------------------>|
+		 *  |        | off - IF_HDR_SIZE + IP6_FRAG_HDR_SIZE |
+		 *  |        |<------------------------------------->|
+		 *  +--------+----------+---------+------------------+-------------+
+		 *  | IF HDR | IPv6 HDR | EXT HDR |     FRAG HDR     |   Payload   |
+		 *  +--------+----------+---------+------------------+-------------+
+		 *                      |<---------------------------------------->|
+		 *                      |             Payload Size                 |
+		 *           |<--------------------------------------------------->|
+		 *           |         IP6_HDR_SIZE + Payload Size                 |
+		 *                                                   |<----------->|
+		 *                                                   | fragpartlen |
+		 */
+		fragpartlen = sizeof(T_IP6_HDR) + ntohs(ip6h->plen) - (off - IF_HDR_SIZE + sizeof(T_IP6_FRAG_HDR));
+		if (unfraglen + fragoff + fragpartlen > IPV6_MAXPACKET) {
+			icmp6_error(input, ICMP6_PARAM_PROB,
+			                   ICMP6_PARAMPROB_HEADER,
+			                   (off - IF_HDR_SIZE) +
+			                   offsetof(T_IP6_FRAG_HDR, off_flag));
+			goto sig_ret;
+			}
+
+		/*
+	 	 *  ip6fq == NULL であれば、対応するエントリは無いので、
+	 	 *  データグラム再構成キュー配列に、エントリを追加する。
+	 	 */
+		for (ix = NUM_IP6_FRAG_QUEUE; ix -- > 0; ) {
+
+			/* 空きエントリを探す。*/
+			if (ip6_frag_queue[ix] == NULL) {
+				ip6fq = &ip6_frag_queue[ix];
+				break;
+				}
+			}
+
+		/*
+		 *  ip6fq == NULL であれば、空きエントリが無いので、
+		 *  タイムアウト（hlim）が短いエントリを開放する。
+		 */
+ 		if (ip6fq == NULL) {
+
+		 	ftim = IPV6_MAXHLIM;
+			for (ix = NUM_IP6_FRAG_QUEUE; ix -- > 0; ) {
+				if (ip6_frag_queue[ix] != NULL) {
+					rip6h  = GET_QIP6_HDR(ip6_frag_queue[ix]);
+					if (rip6h->ftim < ftim) {
+						ftim  = rip6h->ftim;
+						ip6fq = &ip6_frag_queue[ix];
+						}
+					}
+				}
+			frag6_free_queue(ip6fq);
+			}
+
+		/*
+		 *  エントリを設定する。
+		 */
+		*ip6fq = input; 
+		ip6_frag_dest[ip6fq - ip6_frag_queue] = ip6h->dst;
+		qip6h  = GET_QIP6_HDR(*ip6fq);
+		qip6h->ftim = IPV6_FRAGTTL;
+		qip6h->foff = off;
+		qip6h->flen = fragpartlen;
+		qip6h->next_frag = NULL;
+ 		}
+ 	else {
+
+		/*
+	 	 *  断片の正当性をチェックする。
+		 */
+		unfraglen = 0;
+		fragoff = ntohs(((T_IP6_FRAG_HDR *)((*ip6fq)->buf + GET_QIP6_HDR(*ip6fq)->foff))->off_flag & IP6F_OFF_MASK);
+		if (fragoff == 0) {
+
+			/*
+		 	 *  データグラム再構成キューの最初の断片が先頭の断片
+			 *  分割できない部分の長さ unfraglen を計算する。
+			 */
+			unfraglen = (GET_QIP6_HDR(*ip6fq)->foff - IF_HDR_SIZE) - sizeof(T_IP6_HDR);
+			}
+
+		fragoff = ntohs(ip6fh->off_flag & IP6F_OFF_MASK);
+		if (fragoff == 0) {
+
+			/*
+		 	 *  入力した断片が先頭の断片
+			 *  分割できない部分の長さ unfraglen を計算する。
+			 */
+			unfraglen = (off - IF_HDR_SIZE) - sizeof(T_IP6_HDR);
+			}
+
+		/*
+		 *             off
+		 *  |<--------------------------->|
+		 *  |          off - IF_HDR_SIZE  |
+		 *  |        |<------------------>|
+		 *  |        | off - IF_HDR_SIZE + IP6_FRAG_HDR_SIZE |
+		 *  |        |<------------------------------------->|
+		 *  +--------+----------+---------+------------------+-------------+
+		 *  | IF HDR | IPv6 HDR | EXT HDR |     FRAG HDR     |   Payload   |
+		 *  +--------+----------+---------+------------------+-------------+
+		 *                      |<---------------------------------------->|
+		 *                      |             Payload Size                 |
+		 *           |<--------------------------------------------------->|
+		 *           |         IP6_HDR_SIZE + Payload Size                 |
+		 *                                                   |<----------->|
+		 *                                                   | fragpartlen |
+		 */
+		fragpartlen = sizeof(T_IP6_HDR) + ntohs(ip6h->plen) - (off - IF_HDR_SIZE + sizeof(T_IP6_FRAG_HDR));
+		if (unfraglen + fragoff + fragpartlen > IPV6_MAXPACKET) {
+			icmp6_error(input, ICMP6_PARAM_PROB,
+			                   ICMP6_PARAMPROB_HEADER,
+			                   (off - IF_HDR_SIZE) +
+			                   offsetof(T_IP6_FRAG_HDR, off_flag));
+			goto sig_ret;
+			}
+		
+		if (ntohs(ip6fh->off_flag & IP6F_OFF_MASK) == 0) {
+
+			/*
+		 	 *  入力した断片が先頭の断片
+		 	 *  データグラム再構成キューの最後の断片が、
+		 	 *  データグラムの最大長を超えていないかチェックする。
+			 */
+
+			/* 最後の断片を探索する。*/
+			next = *ip6fq;
+			while ((qip6h = GET_QIP6_HDR(next))->next_frag != NULL)
+				next = qip6h->next_frag;
+
+			/* 最後の断片のオフセットと断片サイズを計算する。*/
+			qip6fh = (T_IP6_FRAG_HDR *)(next->buf + qip6h->foff);
+			fragoff = ntohs(qip6fh->off_flag & IP6F_OFF_MASK);
+			fragpartlen = sizeof(T_IP6_HDR) + ntohs(qip6h->plen) - (qip6h->foff - IF_HDR_SIZE + sizeof(T_IP6_FRAG_HDR));
+			if (unfraglen + fragoff + fragpartlen > IPV6_MAXPACKET) {
+
+				/*
+				 *  データグラムの最大長を超えている場合は、
+			 	 *  データグラム再構成キュー全体を破棄する。
+			 	 */
+				frag6_free_queue(ip6fq);
+				syscall(rel_net_buf(input));
+				goto sig_ret;
+				}
+			}
+
+		/* ECN の正当性チェックは未実装 */
+
+		/*
+		 *  断片をエントリに挿入する。
+	 	 *  データグラム再構成キューから、入力した断片より前の断片を探索する。
+		 */
+		prev = NULL;
+		next = *ip6fq;
+		while (next != NULL) {
+			qip6h  = GET_QIP6_HDR(next);
+			qip6fh = (T_IP6_FRAG_HDR *)(next->buf + qip6h->foff);
+			if (ntohs(ip6fh->off_flag & IP6F_OFF_MASK) <= ntohs(qip6fh->off_flag & IP6F_OFF_MASK))
+				break;
+			prev = next;
+			next = qip6h->next_frag;
+			}
+
+		/*
+		 *  prev は、入力した断片より前の断片。ただし NULL の場合は、
+		 *  入力した断片がデータグラム再構成キューの中で最も前の断片。
+		 *  next は、入力した断片より後の断片。ただし NULL の場合は、
+		 *  入力した断片がデータグラム再構成キューの中で最も後の断片。
+		 */
+		fragoff = ntohs(ip6fh->off_flag & IP6F_OFF_MASK);
+		if (prev != NULL) {
+
+			/*
+			 *  前の断片と、入力した断片が重なっていないかチェックする。
+			 *
+			 *    qfragoff
+			 *    |   qfragparglen
+			 *    |<------------------>|
+			 *    +--------------------+
+			 *    |        prev        |
+			 *    +--------------------+
+			 *
+			 *                         +--------------------+
+			 *                         |        input       |
+			 *                         +--------------------+
+			 *                         |
+			 *                         fragoff
+			 */
+			qip6h  = GET_QIP6_HDR(prev);
+			qip6fh = (T_IP6_FRAG_HDR *)(prev->buf + qip6h->foff);
+			qfragoff = ntohs(qip6fh->off_flag & IP6F_OFF_MASK);
+			qfragpartlen = sizeof(T_IP6_HDR) + ntohs(qip6h->plen) - (off - IF_HDR_SIZE + sizeof(T_IP6_FRAG_HDR));
+
+			diff = ((int32_t)qfragoff + qfragpartlen) - fragoff;
+			if (diff > 0) {
+
+				/* 重なっていれば、入力した断片を破棄して終了する。*/
+				syscall(rel_net_buf(input));
+				goto sig_ret;
+				}
+			}
+
+		if (next != NULL) {
+
+			/*
+			 *  後の断片と、入力した断片が重なっていないかチェックする。
+			 *
+			 *    fragoff
+			 *    |    fragparglen
+			 *    |<------------------>|
+			 *    +--------------------+
+			 *    |       input        |
+			 *    +--------------------+
+			 *
+			 *                         +--------------------+
+			 *                         |         next       |
+			 *                         +--------------------+
+			 *                         |
+			 *                         qfragoff
+			 */
+			qip6h  = GET_QIP6_HDR(next);
+			qip6fh = (T_IP6_FRAG_HDR *)(next->buf + qip6h->foff);
+			qfragoff = ntohs(qip6fh->off_flag & IP6F_OFF_MASK);
+			fragpartlen = sizeof(T_IP6_HDR) + ntohs(ip6h->plen) - (off - IF_HDR_SIZE + sizeof(T_IP6_FRAG_HDR));
+
+			diff = ((int32_t)fragoff + fragpartlen) - qfragoff;
+			if (diff > 0) {
+
+				/* 重なっていれば、入力した断片を破棄して終了する。*/
+				syscall(rel_net_buf(input));
+				goto sig_ret;
+				}
+			}
+
+		/* 入力した断片を設定する。*/
+		qip6h  = GET_QIP6_HDR(input);
+		qip6h->foff = off;
+		qip6h->flen = sizeof(T_IP6_HDR) + ntohs(qip6h->plen) - (off - IF_HDR_SIZE + sizeof(T_IP6_FRAG_HDR));
+
+		if (prev == NULL) {
+			*ip6fq = input;
+			qip6h->ftim = IPV6_FRAGTTL;
+			}
+		else
+			GET_QIP6_HDR(prev)->next_frag = input;
+		qip6h->next_frag = next;
+
+		/*
+		 *  全ての断片を受信したかチェックする。
+		 */
+		plen = 0;
+		frag = *ip6fq;
+		while (frag != NULL) {
+			qip6h  = GET_QIP6_HDR(frag);
+			qip6fh = (T_IP6_FRAG_HDR *)(frag->buf + qip6h->foff);
+			if (ntohs(qip6fh->off_flag & IP6F_OFF_MASK) != plen) {
+
+				/* 断片が連続していない。*/
+				goto sig_ret;
+				}
+			plen += qip6h->flen;
+			frag = qip6h->next_frag;
+			}
+		if (ntohs(qip6fh->off_flag & IP6F_MORE_FRAG) != 0) {
+
+			/* 最後の断片を受信していない。*/
+			goto sig_ret;
+			}
+
+		/*
+		 *  全ての断片を受信したので、再構成する。
+		 */
+
+		/* ネットワークバッファを獲得する。*/
+		qip6h  = GET_QIP6_HDR(*ip6fq);
+		qip6fh = (T_IP6_FRAG_HDR *)((*ip6fq)->buf + qip6h->foff);
+		if (tget_net_buf(inputp, qip6h->foff + plen, TMO_IP6_FRAG_GET_NET_BUF) == E_OK) {
+
+			/*
+			 *  断片ヘッダの直前のヘッダの NEXT フィールドのアドレスを獲得し、
+			 *  元に戻す。
+			 */
+			if ((prev_next = ip6_get_prev_hdr(*ip6fq, qip6h->foff)) == NULL) {
+				syscall(rel_net_buf(input));
+				goto sig_ret;
+				}
+			*prev_next = qip6fh->next;
+			input = *inputp;
+
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_FRAG_IN_OK], 1);
+			NET_COUNT_MIB(in6_stats.ipv6IfStatsReasmOKs, 1);
+
+			/*
+			 *  IPv6 ヘッダと分割できない部分を
+			 *  データグラム再構成キューの中の先頭の断片からコピーする。
+			 */
+			memcpy(input->buf, (*ip6fq)->buf, qip6h->foff);
+
+			/* 送信先アドレスを元に戻す。*/
+			ip6h = GET_IP6_HDR(input);
+			memcpy(&ip6h->dst, &ip6_frag_dest[ip6fq - ip6_frag_queue], sizeof(T_IN6_ADDR));
+
+			/* offp を、再構成した断片の先頭に設定する。*/
+			*offp = qip6h->foff;
+
+			/* ネットワークバッファ長を設定する。*/
+			input->len = plen + qip6h->foff;
+
+			/*
+			 *  全ての断片をコピーする。
+			 */
+			frag = *ip6fq;
+			off  = qip6h->foff;
+			while (frag != NULL) {
+				qip6h  = GET_QIP6_HDR(frag);
+				memcpy(input->buf + off,
+				       frag->buf + qip6h->foff + sizeof(T_IP6_FRAG_HDR),
+				       qip6h->flen);
+				off += qip6h->flen;
+				frag = qip6h->next_frag;
+				}
+
+			/* ペイロード長を設定する。*/
+			ip6h->plen = htons(plen);
+
+			*nextp = offsetof(T_IP6_HDR, next);
+			nextproto = ip6h->next;
+			}
+		else {
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_FRAG_IN_NO_BUF], 1);
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_FRAG_IN_DROP], 1);
+			NET_COUNT_MIB(in6_stats.ipv6IfStatsReasmFails, 1);
+			}
+
+		/* データグラム再構成キューを解放する。*/
+		frag6_free_queue(ip6fq);
+ 		}
+
+sig_ret:
+	syscall(sig_sem(SEM_IP6_FRAG_QUEUE));
+	return nextproto;
+
+#else	/* #ifdef IP6_CFG_FRAGMENT */
+
+	/*
+	 *  データグラムの分割・再構成行わない場合は、全断片を破棄し、
+	 *  最後の断片を受信したとき、
+	 *  ICMP エラーを送信者に通知する。
+	 */
+	if ((ip6fh->off_flag & IP6F_MORE_FRAG) == 0) {
+		icmp6_error(input, ICMP6_TIME_EXCEEDED,
+		                   ICMP6_TIME_EXCEED_REASSEMBLY, 0);
+		NET_COUNT_MIB(in6_stats.ipv6IfStatsReasmFails, 1);
+		return IPPROTO_DONE;
+		}
+
+#endif	/* #ifdef IP6_CFG_FRAGMENT */
+
+buf_rel:
+	syscall(rel_net_buf(input));
+	return IPPROTO_DONE;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/icmp6.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/icmp6.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/icmp6.c	(revision 398)
@@ -0,0 +1,716 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/icmp66.c,v 1.6.2.6 2001/07/10 09:44:16 ume Exp $	*/
+/*	$KAME: icmp66.c,v 1.211 2001/04/04 05:56:20 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip_icmp6.c	8.2 (Berkeley) 1/4/94
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+
+#include <netinet6/nd6.h>
+
+#ifdef _IP6_CFG
+
+/*
+ *  変数
+ */
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+T_ICMP6_IFSTAT icmp6_ifstat;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+/*
+ *  icmp6_output -- ICMP6 パケットを送信する。
+ */
+
+static void
+icmp6_output (T_NET_BUF *output, uint_t off)
+{
+	T_IN6_IFADDR	*ia;
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IP6_HDR	*ip6h;
+	T_ICMP6_HDR	*icmp6h;
+
+	/*
+	 *  宛先アドレスにふさわしい送信元アドレスを、
+	 *  ネットワークインタフェースから探索して利用する。
+	 */
+	ip6h = GET_IP6_HDR(output);
+	if ((ia = in6_ifawithifp(ifp, &ip6h->dst)) == NULL) {
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutErrors, 1);
+		syscall(rel_net_buf(output));
+		return;
+		}
+	memcpy(&ip6h->src, &ia->addr, sizeof(T_IN6_ADDR));
+
+	icmp6h = GET_ICMP6_HDR(output, off);
+
+	/* チェックサムを計算する。*/
+	icmp6h->sum = 0;
+	icmp6h->sum = in6_cksum(output, IPPROTO_ICMPV6, (uint8_t*)icmp6h - output->buf, 
+	                        ntohs(ip6h->plen) - (off - IF_IP6_HDR_SIZE));
+
+	/* 送信する。*/
+	NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_OUT_OCTETS],
+	               output->len - GET_IF_IP6_HDR_SIZE(output));
+	NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_OUT_PACKETS], 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutMsgs, 1);
+	ip6_output(output, 0, TMO_ICMP_OUTPUT);
+	}
+
+/*
+ *  icmp6_echo_request -- エコー要求を受信したときの処理
+ */
+
+static void
+icmp6_echo_request (T_NET_BUF *input, uint_t off)
+{
+	T_IP6_HDR	*ip6h;
+	T_ICMP6_HDR	*icmp6h;
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN6_IFADDR	*ia;
+	T_IN6_ADDR	dst;
+	uint_t		diff;
+
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInEchos, 1);
+
+	ip6h       = GET_IP6_HDR(input);
+
+	/*
+	 *  IPv6 ヘッダと ICMPv6 ヘッダ間の拡張ヘッダを除去する。
+	 */
+	diff = off - IF_IP6_HDR_SIZE;
+	if (diff > 0) {
+		/* ICMPv6 ヘッダを前に詰める。*/
+		memmove(input->buf + IF_IP6_HDR_SIZE, input->buf + off, input->len - off);
+		off = IF_IP6_HDR_SIZE;
+
+		/* ペイロード長を調整する。*/
+		ip6h->plen  = htons(ntohs(ip6h->plen) - diff);
+		input->len -= diff;
+		}
+
+	icmp6h = GET_ICMP6_HDR(input, off);
+	if (icmp6h->code != 0) {
+		NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_IN_ERR_PACKETS], 1);
+		syscall(rel_net_buf(input));
+		return;
+		}
+
+	/*
+	 *  メッセージの型をエコー要求 (128) から
+	 *  エコー応答 (129) に変更して送り返す。
+	 */
+	icmp6h->type = ICMP6_ECHO_REPLY;
+
+	/* IPv6 ヘッダの発信元アドレスと宛先アドレスを入替える。*/
+	memcpy(&dst, &ip6h->dst, sizeof(T_IN6_ADDR));
+	memcpy(&ip6h->dst, &ip6h->src, sizeof(T_IN6_ADDR));
+	memcpy(&ip6h->src, &dst, sizeof(T_IN6_ADDR));
+
+	/*
+	 *  元の宛先アドレスがマルチキャストの場合は、
+	 *  宛先アドレスにふさわしい送信元アドレスを、
+	 *  ネットワークインタフェースから探索して利用する。
+	 */
+	if (IN6_IS_ADDR_MULTICAST(&dst)) {
+		if ((ia = in6_ifawithifp(ifp, &ip6h->dst)) == NULL) {
+			syscall(rel_net_buf(input));
+			return;
+			}
+		else
+			memcpy(&ip6h->src, &ia->addr, sizeof(T_IN6_ADDR));
+		}
+
+	/* 次ヘッダとホップリミットを設定する。*/
+	ip6h->next = IPPROTO_ICMPV6;
+	ip6h->hlim = IP6_DEFTTL;
+
+	/* チェックサムを計算する。*/
+	icmp6h->sum = 0;
+	icmp6h->sum = in6_cksum(input, IPPROTO_ICMPV6, (uint8_t*)icmp6h - input->buf, 
+	                        ntohs(ip6h->plen) - (off - IF_IP6_HDR_SIZE));
+
+	/* 送信する。*/
+	NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_OUT_OCTETS],
+	               input->len - GET_IF_IP6_HDR_SIZE(input));
+	NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_OUT_PACKETS], 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutMsgs, 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutEchoReplies, 1);
+	ip6_output(input, 0, TMO_ICMP_OUTPUT);
+	}
+
+/*
+ *  icmp6_notify_error -- エラーを通知する。
+ */
+
+static void
+icmp6_notify_error(T_NET_BUF *input, uint_t poff)
+{
+	T_ICMP6_HDR	*icmp6h;
+	ER_UINT		loff;
+	uint_t		len, next;
+
+	len  = input->len - poff;
+
+	/* データグラム長が ICMP6 ヘッダ長 + IP6 ヘッダ長以下なら何もしない。*/
+	if (len < ICMP6_HDR_SIZE + IP6_HDR_SIZE)
+		return;
+
+	icmp6h = GET_ICMP6_HDR(input, poff);
+
+	/* 最終ヘッダを探索する。*/
+	loff = ip6_lasthdr(input, poff + ICMP6_HDR_SIZE, IPPROTO_IPV6, &next);
+
+	/* 最終ヘッダが TCP/UDP のみ対応する。*/
+	if (loff >= 0 && (next == IPPROTO_TCP || next == IPPROTO_UDP)) {
+
+		memcpy(GET_IP6_HDR(input), input->buf + (loff + ICMP6_HDR_SIZE),
+		                           input->len - (loff + ICMP6_HDR_SIZE));
+		input->len -= loff + ICMP6_HDR_SIZE;
+
+#if defined(SUPPORT_TCP)
+
+		if (next == IPPROTO_TCP)
+
+			tcp_notify(input, icmp6h->code == ICMP6_DST_UNREACH_NOPORT ? EV_CNNRF : EV_HURCH);
+
+#endif	/* of #if defined(SUPPORT_TCP) */
+
+#if defined(SUPPORT_UDP) && TNUM_UDP6_CEPID > 0
+
+		if (next == IPPROTO_UDP)
+
+			udp6_notify(input, icmp6h->code == ICMP6_DST_UNREACH_NOPORT ? EV_CNNRF : EV_HURCH);
+
+#endif	/* of #if defined(SUPPORT_UDP) && TNUM_UDP6_CEPID > 0 */
+
+		}
+	else
+		syslog(LOG_NOTICE, "[ICMP6] error code: %d.", icmp6h->code);
+	}
+
+#if NUM_IN6_HOSTCACHE_ENTRY > 0
+
+/*
+ *  icmp6_mtudisc_update -- Path MTU を更新する。
+ */
+
+static void
+icmp6_mtudisc_update(T_NET_BUF *input, uint_t off, uint32_t mtu)
+{
+	T_IP6_HDR	*pip6h;
+
+	pip6h = (T_IP6_HDR*)GET_ICMP6_SDU(input, off);
+
+	if (mtu < IP6_HDR_SIZE + sizeof(T_IP6_FRAG_HDR) + 8)
+		return;
+
+	if (mtu > IF_MTU)
+		return;
+
+	in6_hostcache_update(&pip6h->dst, mtu);
+	}
+
+#endif	/* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
+
+#if defined(NUM_IN6_REDIRECT_ROUTE_ENTRY)
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
+
+/*
+ *  icmp6_redirect_input -- 向け直しメッセージの処理
+ */
+
+static void
+icmp6_redirect_input (T_NET_BUF *input, uint_t off)
+{
+	T_IP6_HDR		*ip6h;
+	const T_IN6_ADDR	*gw;
+	T_ND_REDIRECT_HDR	*rdh;
+	T_ND_OPT_HDR		*opth;
+	T_IFNET			*ifp = IF_GET_IFNET();
+	bool_t			router, onlink;
+	uint_t			lladdr_len = 0;
+	uint8_t			*lladdr = NULL;
+	uint8_t			nd_opt_off[ND_OPT_OFF_ARRAY_SIZE];
+
+	ip6h = GET_IP6_HDR(input);
+
+	/*
+	 *  IP ヘッダのチェック、以下の場合は破棄する。
+	 *    ・リンクローカル以外から送られてきたメッセージ
+	 *    ・ホップリミットが IPV6_MAXHLIM (255) 以外
+	 */
+	if (!IN6_IS_ADDR_LINKLOCAL(&ip6h->src) || ip6h->hlim != IPV6_MAXHLIM)
+		goto err_ret;
+
+	rdh  = (T_ND_REDIRECT_HDR *)(input->buf + off);
+
+	/* 向け直しの終点アドレスがマルチキャストアドレスの場合は破棄する。*/
+	if (IN6_IS_ADDR_MULTICAST(&rdh->dst))
+		goto err_ret;
+
+	/* ターゲットアドレスが経路表に登録されているかチェックする。*/
+	if ((gw = in6_rtalloc(ifp, &rdh->dst)) != NULL) {
+		/* GW アドレスと送信元アドレスが異なっていれば破棄する。*/
+		if (!IN6_ARE_ADDR_EQUAL(gw, &ip6h->src))
+			goto err_ret;
+		}
+	else	/* 経路表になければ破棄する。*/
+		goto err_ret;
+
+	router = onlink = false;
+
+	/*
+	 *  ターゲットアドレスがリンクローカルアドレスであれば、
+	 *  ターゲットはルータ
+	 */
+	if (IN6_IS_ADDR_LINKLOCAL(&rdh->target))
+		router = true;
+
+	/*
+	 *  ターゲットアドレスと終点アドレスが同一であれば、オンリンク
+	 */
+	if (IN6_ARE_ADDR_EQUAL(&rdh->target, &rdh->dst))
+		onlink = true;
+		
+	/*
+	 *  ルータでも、オンリンクでもなければエラー
+	 */
+	if (!router && !onlink)
+		goto err_ret;
+
+	/* 近隣探索オプションのオフセットを記録する。*/
+	if (nd6_options(nd_opt_off, input->buf +  off + ND_REDIRECT_HDR_SIZE,
+	                            input->len - (off + ND_REDIRECT_HDR_SIZE)) != E_OK)
+		goto err_ret;
+
+	/* 近隣探索オプション (向け直しのルータのリンクアドレス) */
+	if (nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_TARGET_LINKADDR)]) {
+		opth = (T_ND_OPT_HDR *)((uint8_t *)(input->buf + off + ND_REDIRECT_HDR_SIZE) +
+		                        nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_TARGET_LINKADDR)] - 8);
+	 	/* 注意: オプションオフセット配列には、オフセット + 8 が設定されている。*/
+		lladdr     = (uint8_t *)(opth + 1);
+		lladdr_len = (opth->len << 3);
+		}
+
+	/*
+	 *  ネットワークインタフェースのアドレス長が一致しなければエラー
+	 */
+	if (lladdr && lladdr_len != ((sizeof(T_IF_ADDR) + sizeof(T_ND_OPT_HDR) + 7) & ~7))
+		goto err_ret;
+
+	/* 向け直しのルータのリンクアドレスを近隣キャッシュに登録する。*/
+	nd6_cache_lladdr(ifp, &rdh->target, (T_IF_ADDR *)lladdr, ND_REDIRECT, 
+	                 onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER);
+
+	/* ルーティング表に登録する。*/
+	in6_rtredirect(&rdh->target, &rdh->dst, 128, IN_RTF_REDIRECT, TMO_IN_REDIRECT);
+
+	syscall(rel_net_buf(input));
+	return;
+
+err_ret:
+	NET_COUNT_ICMP6(net_count_nd6[NC_ICMP6_IN_ERR_PACKETS], 1);
+	syscall(rel_net_buf(input));
+	}
+
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if defined(NUM_IN6_REDIRECT_ROUTE_ENTRY) */
+
+/*
+ *  icmp6_input -- ICMP6 の入力関数
+ */
+
+uint_t
+icmp6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+	T_NET_BUF	*input = *inputp;
+	T_IP6_HDR	*ip6h;
+	T_ICMP6_HDR	*icmp6h;
+	uint_t		len, off = *offp;
+	uint8_t		code;
+
+	NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_IN_OCTETS],
+	               input->len - GET_IF_IP6_HDR_SIZE(input));
+	NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_IN_PACKETS], 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInMsgs, 1);
+
+	/* ICMP6 ヘッダの長さをチェックする。*/
+	len  = input->len - off;
+	if (len < ICMP6_HDR_SIZE) {
+		NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_IN_ERR_PACKETS], 1);
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInErrors, 1);
+		goto buf_rel;
+		}
+
+	ip6h   = GET_IP6_HDR(input);
+	icmp6h = GET_ICMP6_HDR(input, off);
+
+	/* チェックサムを計算する。*/
+	if ((in6_cksum(input, IPPROTO_ICMPV6, off, ntohs(ip6h->plen) - (off - IF_IP6_HDR_SIZE)) & 0xffff) != 0) {
+		NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_IN_ERR_PACKETS], 1);
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInErrors, 1);
+		goto buf_rel;
+		}
+
+	code = icmp6h->code;
+
+	/* メッセージの型により分岐する。*/
+	switch (icmp6h->type) {
+
+	case ICMP6_DST_UNREACH:			/* 宛先到達不可能		*/
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInDestUnreachs, 1);
+		icmp6_notify_error(input, off);
+		break;
+
+	case ICMP6_ECHO_REQUEST:		/* エコー要求			*/
+		icmp6_echo_request(input, off);
+		return IPPROTO_DONE;
+		break;
+
+	case ICMP6_ECHO_REPLY:			/* エコー応答			*/
+
+#ifdef ICMP_CFG_CALLBACK_ECHO_REPLY
+
+		icmp6_echo_reply(input, off);
+
+#endif	/* of #ifdef ICMP_CFG_CALLBACK_ECHO_REPLY */
+
+		break;
+
+	case ND_ROUTER_ADVERT:			/* ルータ通知			*/
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInRouterAdvertisements, 1);
+		if (code != 0 || len < ROUTER_ADVERT_HDR_SIZE)
+			goto buf_rel;
+		nd6_ra_input(input, off);
+		return IPPROTO_DONE;
+		break;
+
+	case ND_NEIGHBOR_SOLICIT:		/* 近隣要請			*/
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInNeighborSolicits, 1);
+		if (code != 0 || len < NEIGHBOR_SOLICIT_HDR_SIZE)
+			goto buf_rel;
+		nd6_ns_input(input, off);
+		return IPPROTO_DONE;
+		break;
+
+	case ND_NEIGHBOR_ADVERT:		/* 近隣通知			*/
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInNeighborAdvertisements, 1);
+		if (code != 0 || len < NEIGHBOR_ADVERT_HDR_SIZE)
+			goto buf_rel;
+		nd6_na_input(input, off);
+		return IPPROTO_DONE;
+		break;
+
+	case ND_REDIRECT:			/* 向け直し			*/
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInRedirects, 1);
+
+#if defined(NUM_IN6_REDIRECT_ROUTE_ENTRY)
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
+
+		if (code != 0 || len < ND_REDIRECT_HDR_SIZE)
+			goto buf_rel;
+		icmp6_redirect_input(input, off);
+		return IPPROTO_DONE;
+
+#else	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
+
+		syslog(LOG_WARNING, "[ICMP6] redirect ignored.");
+
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
+#else	/* of #if defined(NUM_IN6_REDIRECT_ROUTE_ENTRY) */
+
+		syslog(LOG_WARNING, "[ICMP6] redirect ignored.");
+
+#endif	/* of #if defined(NUM_IN6_REDIRECT_ROUTE_ENTRY) */
+
+		break;
+
+	case ICMP6_PACKET_TOO_BIG:		/* パケットが大きすぎる。	*/
+
+#if NUM_IN6_HOSTCACHE_ENTRY > 0
+
+		icmp6_mtudisc_update(input, off, ntohl(icmp6h->icmp6_mtu));
+
+#endif	/* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
+
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInPktTooBigs, 1);
+		break;
+
+	case ICMP6_TIME_EXCEEDED:		/* TTL を超過した。		*/
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInTimeExcds, 1);
+		break;
+
+	case ICMP6_PARAM_PROB:			/* IPv6 ヘッダが不正。		*/
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInParmProblems, 1);
+		break;
+
+	case MLD_LISTENER_QUERY:		/* マルチキャスト受信者照会	*/
+	case MLD_LISTENER_REPORT:		/* マルチキャスト受信者報告	*/
+	case MLD_LISTENER_DONE:			/* マルチキャスト受信者終了	*/
+	case ND_ROUTER_SOLICIT:			/* ルータ要請			*/
+	case ICMP6_ROUTER_RENUMBERING:		/* ルータ番号再設定		*/
+	case ICMP6_FQDN_QUERY:			/* FQDN 照会			*/
+	case ICMP6_FQDN_REPLY:			/* FQDN 応答			*/
+		syslog(LOG_INFO, "[ICMP6] unsupported type: %d.", icmp6h->type);
+		break;
+
+	default:
+		syslog(LOG_WARNING, "[ICMP6] unknown type: %d.", icmp6h->type);
+		NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_IN_ERR_PACKETS], 1);
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInErrors, 1);
+		break;
+		}
+
+buf_rel:
+	syscall(rel_net_buf(input));
+	return IPPROTO_DONE;
+	}
+
+/*
+ *  icmp6_error -- ICMP6 エラー送信関数
+ */
+
+void
+icmp6_error (T_NET_BUF *input, uint8_t type, uint8_t code, uint32_t param)
+{
+	T_NET_BUF	*output;
+	T_IP6_HDR	*ip6h;
+	T_ICMP6_HDR	*icmp6h;
+	ER_UINT		off;
+	uint_t		next, len;
+
+	ip6h = GET_IP6_HDR(input);
+
+	/*
+	 *  宛先アドレスが、マルチキャストの場合は、
+	 *  以下の条件以外のときは処理を行わない。
+	 *
+	 *    ・データグラムが大きすぎる。
+	 *    ・IPv6 ヘッダの不正で、オプションが認識できない。
+	 */
+	if (IN6_IS_ADDR_MULTICAST(&ip6h->dst) &&
+	    !((type == ICMP6_PACKET_TOO_BIG) ||
+	      (type == ICMP6_PARAM_PROB && code == ICMP6_PARAMPROB_OPTION)))
+		goto buf_rel;
+
+	/*
+	 *  始点アドレスが、以下の場合は処理を行わない。
+	 *
+	 *    ・無指定
+	 *    ・マルチキャスト
+	 */
+	if (IN6_IS_ADDR_UNSPECIFIED(&ip6h->src) ||
+	    IN6_IS_ADDR_MULTICAST  (&ip6h->src))
+		goto buf_rel;
+
+	/* 最後のヘッダを探索する。*/
+	off = ip6_lasthdr(input, 0, IPPROTO_IPV6, &next);
+
+	/*
+	 *  タイプが、エラーか向け直しの ICMP6 パケットのエラーには返答しない。
+	 */
+	if (off >= 0 && next == IPPROTO_ICMPV6) {
+		T_ICMP6_HDR	*icmp6h;
+
+		if (input->len - off < ICMP6_HDR_SIZE)
+			goto buf_rel;
+
+		icmp6h = GET_ICMP6_HDR(input, off);
+		if (icmp6h->type <  ICMP6_ECHO_REQUEST ||
+		    icmp6h->type == ND_REDIRECT)
+			goto buf_rel;
+		}
+
+	/* DoS 攻撃に対する防御は未実装 */
+
+	/*
+	 *  送り返すメッセージ長を、ICMPv6 の最大ペイロード長に調整する。
+	 *  IPV6_MMTU - (IP6_HDR_SIZE + ICMP6_HDR_SIZE)
+	 */
+	if (input->len - IF_HDR_SIZE > IPV6_MMTU - (IP6_HDR_SIZE + ICMP6_HDR_SIZE))
+		len = IPV6_MMTU - (IP6_HDR_SIZE + ICMP6_HDR_SIZE);
+	else
+		len = input->len - IF_HDR_SIZE;
+
+	/* 送信用のネットワークバッファを獲得する。*/
+	if (in6_get_datagram(&output, len + ICMP6_HDR_SIZE, 0,
+	                     &ip6h->src, &in6_addr_unspecified,
+	                     IPPROTO_ICMPV6, IPV6_MAXHLIM,
+	                     NBA_SEARCH_ASCENT, TMO_ICMP_OUTPUT) != E_OK)
+		goto buf_rel;
+
+	/* ICMP6 ヘッダを設定する。*/
+ 	icmp6h = GET_ICMP6_HDR(output, IF_IP6_ICMP6_HDR_OFFSET);
+ 	icmp6h->type       = type;
+ 	icmp6h->code       = code;
+ 	icmp6h->icmp6_pptr = htonl(param);
+ 
+ 	/* エラーデータを設定する。*/
+ 	memcpy(GET_ICMP6_SDU(output, IF_IP6_ICMP6_HDR_OFFSET), (uint8_t *)ip6h, len);
+
+#ifdef SUPPORT_MIB
+
+	switch (type) {
+	case ICMP6_DST_UNREACH:
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutDestUnreachs, 1);
+		break;
+
+	case ICMP6_PARAM_PROB:
+		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutParmProblems, 1);
+		break;
+
+	default:
+		break;
+
+		}
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+	/* 送信する。*/
+	icmp6_output(output, IF_IP6_HDR_SIZE);
+
+buf_rel:
+	syscall(rel_net_buf(input));
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/if6_ether.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/if6_ether.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/if6_ether.c	(revision 398)
@@ -0,0 +1,121 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_timer.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+
+#include <netinet6/in6.h>
+#include <netinet6/in6_var.h>
+
+#include <net/if_var.h>
+
+#if defined(_IP6_CFG) && defined(SUPPORT_ETHER)
+
+/*
+ *  ether_map_ipv6_multicast -- IPv6 マルチキャストアドレスからイーサネット・マルチキャストアドレスへの変換
+ */
+
+void
+ether_map_ipv6_multicast (T_ETHER_ADDR *eaddr, const T_IN6_ADDR *maddr)
+{
+	eaddr->lladdr[0] = UINT_C(0x33);
+	eaddr->lladdr[1] = UINT_C(0x33);
+	eaddr->lladdr[2] = maddr->s6_addr8[12];
+	eaddr->lladdr[3] = maddr->s6_addr8[13];
+	eaddr->lladdr[4] = maddr->s6_addr8[14];
+	eaddr->lladdr[5] = maddr->s6_addr8[15];
+	}
+
+#endif /* of #if defined(_IP6_CFG) && defined(SUPPORT_ETHER) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/if6_ether.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/if6_ether.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/if6_ether.h	(revision 398)
@@ -0,0 +1,76 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#ifndef _IF6_ETHER_H_
+#define _IF6_ETHER_H_
+
+/*
+ *  関数
+ */
+
+extern void ether_map_ipv6_multicast (T_ETHER_ADDR *eaddr, const T_IN6_ADDR *maddr);
+
+#endif	/* of #ifndef _IF6_ETHER_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6.c	(revision 398)
@@ -0,0 +1,524 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/in6.c,v 1.21 2002/04/19 04:46:22 suz Exp $	*/
+/*	$KAME: in6.c,v 1.259 2002/01/21 11:37:50 keiichi Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)in.c	8.2 (Berkeley) 11/15/93
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#include <netinet6/in6.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
+#include <netinet6/in6_ifattach.h>
+
+#include <net/if_var.h>
+
+#ifdef _IP6_CFG
+
+/*
+ *  全域変数
+ */
+
+const T_IN6_ADDR in6_addr_unspecified =
+	IPV6_ADDR_UNSPECIFIED_INIT;
+
+const T_IN6_ADDR in6_addr_linklocal_allnodes =
+	IPV6_ADDR_LINKLOCAL_ALLNODES_INIT;
+
+const T_IN6_ADDR in6_addr_linklocal_allrouters =
+	IPV6_ADDR_LINKLOCAL_ALLROUTERS_INIT;
+
+/*
+ *  in6_addmulti -- マルチキャストアドレスを登録する。
+ */
+
+static ER
+in6_addmulti (T_IFNET *ifp, T_IN6_ADDR *maddr)
+{
+	ER	error = E_OK;
+
+	if ((error = if_addmulti(ifp, maddr, AT_INET6)) != E_OK)
+		return error;
+
+	return error;
+	}
+
+/*
+ *  in6_ifinit -- インタフェースにアドレス情報を設定し、初期化する。
+ */
+
+static ER
+in6_ifinit (T_IFNET *ifp, T_IN6_IFADDR *ia, const T_IN6_ADDR *addr, uint_t prefix_len)
+{
+	/* アドレスとプレフィックス長を設定する。*/
+	ia->addr       = *addr;
+	ia->prefix_len = prefix_len;
+
+	/* フラグを初期化する。*/
+	ia->flags = 0;
+
+	/*
+	 *  初めてアドレスが設定されたとき、インタフェース独自の初期化を行う。
+	 */
+
+	return E_OK;
+	}
+
+/*
+ *  in6_ifainit -- インタフェースアドレス構造体の初期化
+ */
+
+void
+in6_ifainit (void)
+{
+	T_IN6_IFADDR	*ia = NULL;
+	T_IFNET		*ifp = IF_GET_IFNET();
+	int_t 		ix;
+
+	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
+		ia = &ifp->in6_ifaddrs[ix];
+		memset(ia, sizeof(T_IN6_IFADDR), 0);
+		ia->router_index = IN6_RTR_IX_UNREACH;
+		ia->prefix_index = ND6_PREFIX_IX_INVALID;
+		}
+	}
+
+/*
+ *  in6_if2idlen -- インタフェース ID 長を返す。
+ */
+
+int_t
+in6_if2idlen (T_IFNET *ifp)
+{
+#if IF_TYPE == IFT_ETHER
+	return 64;
+#else
+	return 64;
+#endif
+	}
+
+/*
+ *  in6_addr2ifaix -- アドレスからインタフェースアドレス情報のインデックスに変換する。
+ */
+
+int_t
+in6_addr2ifaix (const T_IN6_ADDR *addr)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN6_IFADDR	*ia;
+	int_t 		ix;
+
+	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
+		ia = &ifp->in6_ifaddrs[ix];
+		if ((ia->flags & IN6_IFF_DEFINED) != 0 &&
+		    in6_are_prefix_equal(addr, &ia->addr, ia->prefix_len))
+			return ix;
+		}
+
+	return IPV6_IFADDR_IX_INVALID;
+	}
+
+/*
+ *  in6_addr2maix -- アドレスからマルチキャストアドレスのインデックスに変換する。
+ */
+
+int_t
+in6_addr2maix (const T_IN6_ADDR *addr)
+{
+	if (addr->s6_addr8[0] == 0xff) {
+		if (addr->s6_addr8[1] == 0x02) {
+			if (addr->s6_addr8[11] == 0x01 && addr->s6_addr8[12] == 0xff)
+				return IPV6_MADDR_IX_SOL_NODE;
+			else
+				return IPV6_MADDR_IX_LL_ALL_NODE;
+			}
+		else
+			return IPV6_MADDR_IX_EXTRA;
+		}
+	else
+		return IPV6_MADDR_IX_EXTRA;
+	}
+
+/*
+ *  in6_update_ifa -- インタフェースのアドレス情報を更新する。
+ */
+
+ER
+in6_update_ifa (T_IFNET *ifp, T_IN6_IFADDR *ia, const T_IN6_ADDR *addr,
+                uint_t prefix_len, uint32_t vltime, uint32_t pltime,
+                int_t router_index, int_t prefix_index, uint_t flags)
+{
+	T_IN6_ADDR	llsol;
+	ER		error = E_OK;
+	SYSTIM		now;
+
+	/* 引数をチェックする。*/
+	if (addr == NULL)
+		return E_PAR;
+
+	/*
+	 *  有効時間をチェックする。
+	 *  vltime (有効時間) と pltime (推奨有効時間) の単位は [s]。
+	 */
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	if (((vltime != ND6_INFINITE_LIFETIME) && (vltime + now < now)) || vltime == 0)
+		return E_PAR;
+
+	if ((pltime != ND6_INFINITE_LIFETIME) && (pltime + now < now))
+		return E_PAR;
+
+	/* インタフェースを初期化する。*/
+	if ((error = in6_ifinit(ifp, ia, addr, prefix_len)) != E_OK)
+		return error;
+
+	if (IN6_IS_ADDR_LINKLOCAL(addr)) {
+
+		/* 要請マルチキャストアドレスを登録する。*/
+		llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
+		llsol.s6_addr32[1] = 0x00000000;
+		llsol.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
+		llsol.s6_addr32[3] = addr->s6_addr32[3];
+		llsol.s6_addr8[12] = 0xff;
+		if ((error = in6_addmulti(ifp, &llsol)) != E_OK)
+			return error;
+
+		/* 全ノード・リンクローカル・マルチキャストアドレスを登録する。*/
+		llsol.s6_addr32[2] = 0x00000000;
+		llsol.s6_addr32[3] = IPV6_ADDR_INT32_ONE;
+		if ((error = in6_addmulti(ifp, &llsol)) != E_OK)
+			return error;
+
+		}
+
+	/* ルータインデックスを設定する。*/
+	ia->router_index = router_index;
+
+	/* プレフィックスインデックスを設定する。*/
+	ia->prefix_index = prefix_index;
+
+	/* フラグを設定する。*/
+	ia->flags  = flags & ~(IN6_IFF_DUPLICATED | IN6_IFF_NODAD);
+	ia->flags |= IN6_IFF_DEFINED;
+
+ 	/*
+ 	 *  アドレス有効時間を設定する。
+	 *  vltime (有効時間) と pltime (推奨有効時間) の単位は [s]。
+ 	 */
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+ 	ia->lifetime.vltime = vltime;
+ 	if (vltime != ND6_INFINITE_LIFETIME)
+ 		ia->lifetime.expire = now + vltime;
+ 	else
+ 		ia->lifetime.expire = 0;
+
+ 	ia->lifetime.pltime = pltime;
+ 	if (pltime != ND6_INFINITE_LIFETIME)
+ 		ia->lifetime.preferred = now + pltime;
+ 	else
+ 		ia->lifetime.preferred = 0;
+
+	/* 近隣探索の初期設定を行う。*/
+	nd6_ifattach(ifp);
+
+	/* 重複アドレス検出を行う。*/
+	if ((flags & IN6_IFF_NODAD) == 0) {
+		ia->flags |= IN6_IFF_TENTATIVE;
+		nd6_dad_start(ifp, ia, NULL);
+		}
+
+	return error;
+	}
+
+/*
+ * in6ifa_ifpwithix -- インデックス番号から、ネットワークインタフェースに
+ *                     割り当てられているアドレスを探索する。
+ */
+
+T_IN6_IFADDR *
+in6ifa_ifpwithix (T_IFNET *ifp, int_t ix)
+{
+	return ix < NUM_IN6_IFADDR_ENTRY? &ifp->in6_ifaddrs[ix] : NULL;
+	}
+
+/*
+ * in6ifa_ifpwithrtrix -- ルータのインデックス番号から、ネットワークインタフェースに
+ *                        割り当てられているアドレスを探索する。
+ */
+
+T_IN6_IFADDR *
+in6ifa_ifpwithrtrix (T_IFNET *ifp, int_t router_index)
+{
+	int_t ix;
+
+	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; )
+		if (ifp->in6_ifaddrs[ix].router_index == router_index)
+			return &ifp->in6_ifaddrs[ix];
+	return NULL;
+	}
+
+/*
+ * in6_ifawithifp -- 宛先アドレスにふさわしい送信元アドレス情報を、
+ *                   ネットワークインタフェースから探索する。
+ */
+
+T_IN6_IFADDR *
+in6_ifawithifp (T_IFNET *ifp, const T_IN6_ADDR *dst)
+{
+	uint_t	scope;
+	int_t	ix;
+
+	/* 宛先アドレスと同じスコープのアドレスを返す。*/
+	if ((ix = in6_addr2ifaix(dst)) != IPV6_IFADDR_IX_INVALID)
+		return &ifp->in6_ifaddrs[ix];
+	else if ((ix = in6_addr2maix(dst)) == IPV6_MADDR_IX_SOL_NODE ||
+	          ix                       == IPV6_MADDR_IX_LL_ALL_NODE)
+		return &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
+	else {
+		scope = in6_addrscope(dst);
+		for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
+			if ((ifp->in6_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
+			    (ifp->in6_ifaddrs[ix].flags & IN6_IFF_DETACHED) == 0 &&
+			    in6_addrscope(&ifp->in6_ifaddrs[ix].addr) == scope) {
+				return &ifp->in6_ifaddrs[ix];
+				}
+			}
+		return NULL;
+		}
+	}
+
+/*
+ * in6_addrwithifp -- 宛先アドレスにふさわしい送信元アドレスを、
+ *                    ネットワークインタフェースから探索する。
+ */
+
+const T_IN6_ADDR *
+in6_addrwithifp (T_IFNET *ifp, T_IN6_ADDR *src, const T_IN6_ADDR *dst)
+{
+	T_IN6_IFADDR *ifaddr;
+
+	if ((ifaddr = in6_ifawithifp(ifp, dst)) == NULL)
+		return NULL;
+	else {
+		*src = ifaddr->addr;
+		return src;
+		}
+	}
+
+/*
+ * in6_if_up -- インタフェース起動後の重複アドレス検出を行う。
+ */
+
+void
+in6_if_up (T_IFNET *ifp)
+{
+#if 0						/* 保留 */
+	int_t dad_delay, ix;
+#endif	/* of #if 0 */
+
+	in6_ifattach(ifp);
+
+#if 0						/* 保留 */
+	/* 重複アドレス検出を行う。*/
+	dad_delay = 0;
+	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; )
+		if ((ifp->in6_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
+		    (ifp->in6_ifaddrs[ix].flags & IN6_IFF_TENTATIVE))
+			nd6_dad_start(ifp, &ifp->in6_ifaddrs[ix], &dad_delay);
+#endif	/* of #if 0 */
+
+#if NUM_ND6_RTR_SOL_RETRY > 0
+
+	/* ルータ要請を出力する。*/
+	nd6_rtrsol_ctl();
+
+#endif	/* of #if NUM_ND6_RTR_SOL_RETRY > 0 */
+	}
+
+/*
+ *  in6_are_prefix_equal -- プレフィックスが同一か調べる。
+ */
+
+bool_t
+in6_are_prefix_equal (const T_IN6_ADDR *addr, const T_IN6_ADDR *prefix, uint_t prefix_len)
+{
+	uint_t bitlen, bytelen;
+
+	bytelen = prefix_len / 8;
+	if (memcmp(&addr->s6_addr, &prefix->s6_addr, bytelen))
+		return false;
+
+	bitlen = prefix_len % 8;
+	if (  addr->s6_addr[bytelen] >> (8 - bitlen) !=
+	    prefix->s6_addr[bytelen] >> (8 - bitlen))
+		return false;
+
+	return true;
+	}
+
+/*
+ *  in6_ifaddr_timer -- ネットワークインタフェースのアドレスの管理タイマー
+ */
+
+void
+in6_ifaddr_timer (T_IFNET *ifp)
+{
+	T_IN6_IFADDR	*ia;
+	SYSTIM		now;
+	int_t		ix;
+
+	syscall(get_tim(&now));
+	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
+		ia = &ifp->in6_ifaddrs[ix];
+
+		if ((ia->flags & IN6_IFF_DEFINED) == 0)
+			;
+		else if (IFA6_IS_INVALID(ia, now)) {
+
+			/*
+			 *  有効時間を過ぎたので削除する。
+			 */
+			ia->flags &= ~IN6_IFF_DEFINED;
+			}
+
+		else if (IFA6_IS_DEPRECATED(ia, now)) {
+
+			/*
+			 *  推奨有効時間を過ぎたので非推奨にする。
+			 */
+			ia->flags |= IN6_IFF_DEPRECATED;
+			}
+		}
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6.h	(revision 398)
@@ -0,0 +1,303 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/in6.h,v 1.7.2.4 2001/07/04 09:45:23 ume Exp $	*/
+/*	$KAME: in6.h,v 1.89 2001/05/27 13:28:35 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)in.h	8.3 (Berkeley) 1/3/94
+ */
+ 
+#ifndef _IN6_H_
+#define _IN6_H_
+
+/*
+ *  IPv6 アドレス構造
+ *
+ *    RFC4291（RFC1884、RFC2373、RFC3513 のアップデート）
+ */
+
+/*
+ *  IPv6 アドレス
+ */
+
+struct t_in6_addr {
+	union {
+		uint8_t		__u6_addr8[16];
+		uint16_t	__u6_addr16[8];
+		uint32_t	__u6_addr32[4];
+		} __u6_addr;
+	};
+
+#define s6_addr		__u6_addr.__u6_addr8
+#define s6_addr8	__u6_addr.__u6_addr8
+#define s6_addr16	__u6_addr.__u6_addr16
+#define s6_addr32	__u6_addr.__u6_addr32
+
+#ifndef T_IN6_ADDR_DEFINED
+
+typedef struct t_in6_addr T_IN6_ADDR;
+
+#define T_IN6_ADDR_DEFINED
+
+#endif	/* of #ifndef T_IN6_ADDR_DEFINED */
+
+/*
+ *  IPv6 アドレスの初期化データ
+ */
+
+#define IPV6_ADDR_UNSPECIFIED_INIT	\
+	{{{ UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00) }}}
+
+#define IPV6_ADDR_LINKLOCAL_ALLNODES_INIT	\
+	{{{ UINT_C(0xff), UINT_C(0x02), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x01) }}}
+
+#define IPV6_ADDR_LINKLOCAL_ALLROUTERS_INIT	\
+	{{{ UINT_C(0xff), UINT_C(0x02), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x02) }}}
+
+/*
+ *  特別なアドレスのチェック
+ */
+
+/* 無指定 */
+
+#define IN6_IS_ADDR_UNSPECIFIED(a)	\
+	(memcmp((void *)(a), (void *)&in6_addr_unspecified, sizeof(T_IN6_ADDR)) == 0)
+
+/* ループバック */
+
+#define IN6_IS_ADDR_LOOPBACK(a)		\
+	(memcmp((void *)(a), (void *)&in6_addr_unspecified, sizeof(T_IN6_ADDR) - 1) == 0 && \
+	 (a)->s6_addr8[15] == 0x01)
+
+/*
+ *  スコープ ID
+ */
+
+#define IPV6_ADDR_SCOPE_NODELOCAL	UINT_C(0x01)
+#define IPV6_ADDR_SCOPE_LINKLOCAL	UINT_C(0x02)
+#define IPV6_ADDR_SCOPE_SITELOCAL	UINT_C(0x05)
+#define IPV6_ADDR_SCOPE_ORGLOCAL	UINT_C(0x08)
+#define IPV6_ADDR_SCOPE_GLOBAL		UINT_C(0x0e)
+
+/*
+ *  ユニキャスト・スコープ
+ *
+ *  注意: 上位 10 ビットのみチェックしなければならない。RFC2373 参照
+ */
+
+/* リンクローカル */
+
+#define IN6_IS_ADDR_LINKLOCAL(a)	\
+	(((a)->s6_addr8[0] == UINT_C(0xfe)) && (((a)->s6_addr8[1] & UINT_C(0xc0)) == UINT_C(0x80)))
+
+/* サイトローカル */
+
+#define IN6_IS_ADDR_SITELOCAL(a)	\
+	(((a)->s6_addr8[0] == UINT_C(0xfe)) && (((a)->s6_addr8[1] & UINT_C(0xc0)) == UINT_C(0xc0)))
+
+/* 集約可能ユニキャスト (グローバル) */
+
+#define IN6_IS_ADDR_AGGREGATE_UNICAST(a)	\
+	(((a)->s6_addr8[0] & UINT_C(0xe0)) == UINT_C(0x20))
+
+/*
+ *  マルチキャスト
+ */
+
+#define IN6_IS_ADDR_MULTICAST(a)	((a)->s6_addr8[0] == UINT_C(0xff))
+
+/*
+ *  同一のチェック
+ */
+
+#define IN6_ARE_ADDR_EQUAL(a,b)		(memcmp((a), (b), sizeof(T_IN6_ADDR)) == 0)
+
+/*
+ *  経路制御用定義
+ */
+
+#define IPV6_RTHDR_TYPE_0		UINT_C(0)	/* IPv6 経路制御ヘッダタイプ 0	*/
+
+/*
+ *  規定値と制限値
+ */
+
+#define IPV6_DEFAULT_MULTICAST_HOPS	1	/* マルチキャスト時のホップリミットの規定値	*/
+#define ND6_INFINITE_LIFETIME		0xffffffff	/* アドレスの無制限有効時間		*/
+
+/*
+ *  ITRON TCP/IPv6 アドレス/ポート番号の定義
+ */
+
+typedef struct t_ipv6ep {
+	T_IN6_ADDR	ipaddr;		/* IPv6 アドレス	*/
+	uint16_t	portno;		/* ポート番号	*/
+	} T_IPV6EP;
+
+#define T_IPV6EP_DEFINED
+
+/*
+ *  ITRON/TCP/IP 用 IP アドレスの定義
+ */
+
+#define IPV6_ADDRANY		IPV6_ADDR_UNSPECIFIED_INIT
+
+/*
+ *  動的生成用 IPv6 TCP 受付口
+ */
+
+typedef struct t_tcp6_crep {
+	/* 標準 */
+	ATR		repatr;		/* 受付口属性		*/
+	T_IPV6EP	myaddr;		/* 自分のアドレス	*/
+	/* 実装依存 */
+	} T_TCP6_CREP;
+
+/*
+ *  動的生成用 IPv6 UDP 通信端点
+ */
+
+typedef struct t_udp6_ccep {
+	/* 標準 */
+	ATR		cepatr;		/* UDP 通信端点属性		*/
+	T_IPV6EP	myaddr;		/* 自分のアドレス		*/
+	FP		callback;	/* コールバック関数		*/
+	/* 実装依存 */
+	} T_UDP6_CCEP;
+
+/*
+ *  前方参照
+ */
+
+#ifndef T_IFNET_DEFINED
+
+typedef struct t_ifnet T_IFNET;
+
+#define T_IFNET_DEFINED
+
+#endif	/* of #ifndef T_IFNET_DEFINED */
+
+/*
+ *  全域変数
+ */
+
+extern const T_IN6_ADDR in6_addr_unspecified;
+extern const T_IN6_ADDR in6_addr_linklocal_allnodes;
+extern const T_IN6_ADDR in6_addr_linklocal_allrouters;
+
+#define ipv6_addrany	in6_addr_unspecified
+
+/*
+ *  TINET 独自 API
+ */
+
+extern char *ipv62str (char *buf, const T_IN6_ADDR *p_addr);
+extern uint_t in6_get_maxnum_ifaddr (void);
+extern const T_IN6_ADDR *in6_get_ifaddr (int_t index);
+extern ER in6_upd_ifaddr (T_IN6_ADDR *addr, uint_t prefixlen,
+                          uint32_t vltime, uint32_t pltime);
+extern ER in6_del_ifaddr (T_IN6_ADDR *addr);
+extern T_IN6_ADDR *in6_make_ipv4mapped (T_IN6_ADDR *dst, T_IN4_ADDR src);
+extern bool_t in6_is_addr_ipv4mapped (const T_IN6_ADDR *addr);
+
+#endif	/* of #ifndef _IN6_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.c	(revision 398)
@@ -0,0 +1,200 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/in6_ifattach.c,v 1.2.2.5 2001/08/13 16:26:17 ume Exp $	*/
+/*	$KAME: in6_ifattach.c,v 1.118 2001/05/24 07:44:00 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#include <netinet6/in6.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
+#include <netinet6/in6_ifattach.h>
+
+#include <net/if_var.h>
+
+#ifdef _IP6_CFG
+
+/*
+ * EUI64 の定義
+ */
+
+#define EUI64_UBIT		0x02
+
+#ifdef SUPPORT_ETHER
+
+/*
+ * get_mac6_ifid -- MAC (6 オクテット) アドレスで、インタフェース識別子を設定する。
+ */
+
+static ER
+get_mac6_ifid (T_IFNET *ifp, T_IN6_ADDR *ifra_addr)
+{
+	ifra_addr->s6_addr[ 8] = ifp->ic->ifaddr.lladdr[0] ^ EUI64_UBIT;
+	ifra_addr->s6_addr[ 9] = ifp->ic->ifaddr.lladdr[1];
+	ifra_addr->s6_addr[10] = ifp->ic->ifaddr.lladdr[2];
+	ifra_addr->s6_addr[11] = UINT_C(0xff);
+	ifra_addr->s6_addr[12] = UINT_C(0xfe);
+	ifra_addr->s6_addr[13] = ifp->ic->ifaddr.lladdr[3];
+	ifra_addr->s6_addr[14] = ifp->ic->ifaddr.lladdr[4];
+	ifra_addr->s6_addr[15] = ifp->ic->ifaddr.lladdr[5];
+
+	return E_OK;
+	}
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#ifdef SUPPORT_PPP
+
+/*
+ * get_rand_ifid -- 乱数により、インタフェース識別子を設定する。
+ */
+
+static ER
+get_rand_ifid (T_IFNET *ifp, T_IN6_ADDR *ifra_addr)
+{
+	return E_OK;
+	}
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef IP6_CFG_AUTO_LINKLOCAL
+
+/*
+ *  in6_ifattach_linklocal -- インタフェースにリンクローカル・アドレスを割り当てる。
+ */
+
+static ER
+in6_ifattach_linklocal (T_IFNET *ifp)
+{
+	T_IN6_ADDR	addr;
+	ER		error = E_OK;
+
+	/*
+	 *  リンクローカル・プレフィックス fe80::/64 を設定する。
+	 */
+	addr.s6_addr32[0] = IPV6_ADDR_INT32_ULL;
+	addr.s6_addr32[1] = ULONG_C(0);
+
+	/* インタフェース識別子を設定する。*/
+	if ((error = IF_IN6_IFID(ifp, &addr)) != E_OK)
+		return error;
+
+	/* インタフェースのアドレス情報を更新する。*/
+	if ((error = in6_update_ifa(ifp, &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL],
+	                            &addr, 64, ND6_INFINITE_LIFETIME,
+	                                       ND6_INFINITE_LIFETIME, 
+	                                       IN6_RTR_IX_UNREACH, ND6_PREFIX_IX_INVALID, 0)) != E_OK)
+		return error;
+
+	return error;
+	}
+
+#endif	/* of #ifdef IP6_CFG_AUTO_LINKLOCAL */
+
+/*
+ *  in6_ifattach -- インタフェースにアドレスを割り当てる。
+ */
+
+ER
+in6_ifattach (T_IFNET *ifp)
+{
+	ER error = E_OK;
+
+#ifdef IP6_CFG_AUTO_LINKLOCAL
+
+	if ((ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL].flags & IN6_IFF_DEFINED) == 0)
+		if ((error = in6_ifattach_linklocal(ifp)) != E_OK)
+			return error;
+
+#endif	/* of #ifdef IP6_CFG_AUTO_LINKLOCAL */
+
+	return error;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.h	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/in6_ifattach.h,v 1.3 2001/06/11 12:39:05 ume Exp $	*/
+/*	$KAME: in6_ifattach.h,v 1.14 2001/02/08 12:48:39 jinmei Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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 _IN6_IFATTACH_H_
+#define _IN6_IFATTACH_H_
+
+/*
+ *  関数
+ */
+
+extern ER in6_ifattach (T_IFNET *ifp);
+
+#endif	/* of #ifndef _IN6_IFATTACH_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_rename.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_rename.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_rename.h	(revision 398)
@@ -0,0 +1,180 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _IN6_RENAME_H_
+#define _IN6_RENAME_H_
+
+/*
+ *  TCP/IPv6 プロトコルスタック内部名のリネーム
+ */
+
+/* netinet6/in6.c */
+
+#define in6_are_prefix_equal	_tinet_in6_are_prefix_equal
+#define in6ifa_ifpwithrtrix	_tinet_in6ifa_ifpwithrtrix
+#define in6_if_up		_tinet_in6_if_up
+#define in6_if2idlen		_tinet_in6_if2idlen
+#define in6_ifaddr_timer	_tinet_in6_ifaddr_timer
+#define in6ifa_ifpwithix	_tinet_in6ifa_ifpwithix
+#define in6_addr2maix		_tinet_in6_addr2maix
+#define in6_ifawithifp		_tinet_in6_ifawithifp
+#define in6_addr2ifaix		_tinet_in6_addr2ifaix
+#define in6_update_ifa		_tinet_in6_update_ifa
+#define in6_ifainit		_tinet_in6_ifainit
+#define in6_addrwithifp		_tinet_in6_addrwithifp
+#define in6_addr_loopback	_tinet_in6_addr_loopback
+
+/* netinet6/in6_ifattach.c */
+
+#define in6_ifattach		_tinet_in6_ifattach
+
+/* netinet6/in6_subr.c */
+
+#define inn6_is_dstaddr_accept	_tinet_inn6_is_dstaddr_accept
+#define in6_lookup_ifaddr	_tinet_in6_lookup_ifaddr
+#define in6_rtalloc		_tinet_in6_rtalloc
+#define in6_get_ifaddr		_tinet_in6_get_ifaddr
+#define in6_cksum		_tinet_in6_cksum
+#define in6_gateway_lookup	_tinet_in6_gateway_lookup
+#define in6_is_dstaddr_accept	_tinet_in6_is_dstaddr_accept
+#define in6_hostcache_getmtu	_tinet_in6_hostcache_getmtu
+#define in6_set_header		_tinet_in6_set_header
+#define in6_get_datagram	_tinet_in6_get_datagram
+#define in6_rtredirect		_tinet_in6_rtredirect
+#define get_ip6_hdr_size	_tinet_get_ip6_hdr_size
+#define in6_plen2pmask		_tinet_in6_plen2pmask
+#define in6_rtnewentry		_tinet_in6_rtnewentry
+#define in6_rtinit		_tinet_in6_rtinit
+#define in6_rttimer		_tinet_in6_rttimer
+#define in6_lookup_multi	_tinet_in6_lookup_multi
+#define in6_hostcache_update	_tinet_in6_hostcache_update
+#define in6_init		_tinet_in6_init
+
+/* netinet6/if6_ether.c */
+
+#define ether_map_ipv6_multicast	\
+				_tinet_ether_map_ipv6_multicast
+
+/* netinet6/ip6_input.c */
+
+#define ip6_input		_tinet_ip6_input
+#define ip6_lasthdr		_tinet_ip6_lasthdr
+#define ip6_unknown_opt		_tinet_ip6_unknown_opt
+#define ip6_init		_tinet_ip6_init
+#define ip6_nexthdr		_tinet_ip6_nexthdr
+#define ip6_remove_exthdrs	_tinet_ip6_remove_exthdrs
+#define ip6_get_prev_hdr	_tinet_ip6_get_prev_hdr
+
+/* netinet6/ip6_output.c */
+
+#define ip6_output		_tinet_ip6_output
+#define linkmtu			_tinet_linkmtu
+
+/* netinet6/dest6.c */
+
+#define dest6_input		_tinet_dest6_input
+
+/* netinet6/rout6.c */
+
+#define route6_input		_tinet_route6_input
+
+/* netinet6/frag6.c */
+
+#define frag6_input		_tinet_frag6_input
+#define frag6_timer		_tinet_frag6_timer
+#define ip6_get_frag_queue	_tinet_ip6_get_frag_queue
+
+/* netinet6/ah_input.c */
+
+#define ah6_input		_tinet_ah6_input
+
+/* netinet6/esp_input.c */
+
+#define esp6_input		_tinet_esp6_input
+
+/* netinet6/icmp6.c */
+
+#define icmp6_input		_tinet_icmp6_input
+#define icmp6_error		_tinet_icmp6_error
+#define icmp6_echo_reply	_tinet_icmp6_echo_reply
+
+/* netinet6/nd6.c */
+
+#define nd6_ifattach		_tinet_nd6_ifattach
+#define nd6_is_addr_neighbor	_tinet_nd6_is_addr_neighbor
+#define nd6_cache_lladdr	_tinet_nd6_cache_lladdr
+#define nd6_output_hold		_tinet_nd6_output_hold
+#define nd6_init		_tinet_nd6_init
+#define nd6_output		_tinet_nd6_output
+#define nd6_options		_tinet_nd6_options
+#define nd6_storelladdr		_tinet_nd6_storelladdr
+#define nd6_lookup		_tinet_nd6_lookup
+#define nd6_get_drl		_tinet_nd6_get_drl
+#define nd6_get_cache		_tinet_nd6_get_cache
+#define nd6_timer		_tinet_nd6_timer
+
+/* netinet6/nd6_nbr.c */
+
+#define nd6_dad_start		_tinet_nd6_dad_start
+#define nd6_ns_input		_tinet_nd6_ns_input
+#define nd6_na_input		_tinet_nd6_na_input
+#define nd6_ns_output		_tinet_nd6_ns_output
+#define nd6_na_output		_tinet_nd6_na_output
+
+/* netinet6/nd6_rtr.c */
+
+#define nd6_get_prl		_tinet_nd6_get_prl
+#define nd6_router_lookup	_tinet_nd6_router_lookup
+#define nd6_onlink_prefix_lookup	\
+				_tinet_nd6_onlink_prefix_lookup
+#define nd6_defrtrlist_del	_tinet_nd6_defrtrlist_del
+#define nd6_prefix_onlink	_tinet_nd6_prefix_onlink
+#define nd6_get_drl		_tinet_nd6_get_drl
+#define nd6_rtrsol_ctl		_tinet_nd6_rtrsol_ctl
+#define nd6_defrtrlist_timer	_tinet_nd6_defrtrlist_timer
+#define nd6_ra_input		_tinet_nd6_ra_input
+#define nd6_prelist_timer	_tinet_nd6_prelist_timer
+#define nd6_prefix_offlink	_tinet_nd6_prefix_offlink
+#define nd6_defrtrlist_lookup	_tinet_nd6_defrtrlist_lookup
+#define ip6_defhlim		_tinet_ip6_defhlim
+#define nd6_reachable_time	_tinet_nd6_reachable_time
+#define nd6_base_reachable_time	_tinet_nd6_base_reachable_time
+#define nd6_recalc_reachtm_interval	\
+				_tinet_nd6_recalc_reachtm_interval
+#define nd6_retrans_time	_tinet_nd6_retrans_time
+
+/* netinet6/scope6.c */
+
+#define in6_addrscope		_tinet_in6_addrscope
+
+#endif	/* of #ifndef _IN6_RENAME_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_subr.c	(revision 398)
@@ -0,0 +1,946 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1985, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <netinet6/nd6.h>
+#include <netinet6/ah.h>
+
+#include <net/if_var.h>
+
+/*
+ *  in6_make_ipv4mapped -- IPv4 射影アドレスを生成する。
+ *
+ *  注意:
+ *    src はホストバイトオーダー
+ *
+ */
+
+T_IN6_ADDR *
+in6_make_ipv4mapped (T_IN6_ADDR *dst, T_IN4_ADDR src)
+{
+	dst->s6_addr32[0] = ULONG_C(0x00000000);
+	dst->s6_addr32[1] = ULONG_C(0x00000000);
+	dst->s6_addr32[2] = IPV6_ADDR_INT32_0000FFFF;
+	dst->s6_addr32[3] = htonl(src);
+
+	return dst;
+	}
+
+#ifdef _IP6_CFG
+
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
+
+/*
+ *  in6_rtinit -- ルーティング表を初期化する。
+ */
+
+void
+in6_rtinit (void)
+{
+	int_t ix;
+
+	for (ix = 0; ix < NUM_IN6_STATIC_ROUTE_ENTRY; ix ++)
+		routing6_tbl[ix].flags = IN_RTF_DEFINED;
+
+	for ( ; ix < NUM_IN6_ROUTE_ENTRY; ix ++)
+		routing6_tbl[ix].flags = 0;
+	}
+
+/*
+ *  in6_rtnewentry -- 新しいエントリを獲得する。
+ */
+
+T_IN6_RTENTRY *
+in6_rtnewentry (uint8_t flags, uint32_t tmo)
+{
+	SYSTIM		now;
+	T_IN6_RTENTRY	*rt, *frt = NULL;
+	int_t		ix;
+
+	/* 空きエントリを探す。*/
+	for (ix = NUM_IN6_STATIC_ROUTE_ENTRY; ix < NUM_IN6_ROUTE_ENTRY; ix ++) {
+		rt = &routing6_tbl[ix];
+		if ((routing6_tbl[ix].flags & IN_RTF_DEFINED) == 0) {
+			frt = rt;
+			break;
+			}
+		}
+
+	/* expire の単位は [s]。*/
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	if (frt == NULL) {
+		/* 空きがなければ、有効時間がもっとも短いエントリを空きにする。*/
+		T_IN6_RTENTRY	*srt = NULL;
+		int_t		diff, sdiff = INT_MAX;
+
+		syscall(wai_sem(SEM_IN6_ROUTING_TBL));
+		for (ix = NUM_IN6_STATIC_ROUTE_ENTRY; ix < NUM_IN6_ROUTE_ENTRY; ix ++) {
+			rt = &routing6_tbl[ix];
+			diff = (int_t)(rt->expire - now);
+			if (diff <= 0) {	/* rt->expire <= now */
+				/* 既に、有効時間が過ぎている。*/
+				frt = rt;
+				break;
+				}
+			else if (diff < sdiff) {
+				srt = rt;
+				sdiff = diff;
+				}
+			}
+		if (frt == NULL)
+			frt = srt;
+		frt->flags = 0;
+		syscall(sig_sem(SEM_IN6_ROUTING_TBL));
+		}
+
+	frt->flags  = (uint8_t)(flags | IN_RTF_DEFINED);
+	frt->expire = now + tmo / SYSTIM_HZ;
+	return frt;
+	}
+
+/*
+ *  in6_rttimer -- ルーティング表の管理タイマー
+ */
+
+void
+in6_rttimer (void)
+{
+	SYSTIM	now;
+	int_t	ix;
+
+	/* expire の単位は [s]。*/
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	syscall(wai_sem(SEM_IN6_ROUTING_TBL));
+	for (ix = NUM_IN6_STATIC_ROUTE_ENTRY; ix < NUM_IN6_ROUTE_ENTRY; ix ++)
+		if ((routing6_tbl[ix].flags & IN_RTF_DEFINED) &&
+		    (int_t)(routing6_tbl[ix].expire - now) <= 0)
+			routing6_tbl[ix].flags = 0;
+	syscall(sig_sem(SEM_IN6_ROUTING_TBL));
+	}
+
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
+
+#if NUM_IN6_HOSTCACHE_ENTRY > 0
+
+/*
+ *  ホストキャッシュ
+ */
+
+static T_IN6_HOSTCACHE_ENTRY in6_hostcache[NUM_IN6_HOSTCACHE_ENTRY];
+
+#endif	/* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
+
+/*
+ *  in6_lookup_ifaddr -- ネットワークインタフェースに割り当てられているアドレスを探索する。
+ */
+
+T_IN6_IFADDR *
+in6_lookup_ifaddr (T_IFNET *ifp, const T_IN6_ADDR *addr)
+{
+	int_t ix;
+
+	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
+		if ((ifp->in6_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
+		    IN6_ARE_ADDR_EQUAL(addr, &ifp->in6_ifaddrs[ix].addr))
+			return &ifp->in6_ifaddrs[ix];
+		}
+	return NULL;
+	}
+
+/*
+ *  in6_lookup_multi -- ネットワークインタフェースのマルチキャストアドレスを検索する。
+ */
+
+bool_t
+in6_lookup_multi (T_IFNET *ifp, const T_IN6_ADDR *maddr)
+{
+	int_t ix;
+
+	for (ix = MAX_IN6_MADDR_CNT; ix -- > 0; )
+		if (IN6_ARE_ADDR_EQUAL(maddr, &ifp->in6_maddrs[ix]))
+			return true;
+	return false;
+	}
+
+/*
+ *  in6_set_header -- IPv6 ヘッダを設定する。
+ */
+
+ER
+in6_set_header (T_NET_BUF *nbuf, uint_t len,
+                const T_IN6_ADDR *dstaddr, const T_IN6_ADDR *srcaddr,
+                uint8_t next, uint8_t hlim)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IP6_HDR	*ip6h;
+	T_IN6_IFADDR	*ia;
+
+	/*
+	 *  宛先アドレスにふさわしい送信元アドレスを、
+	 *  ネットワークインタフェースから探索して利用する。
+	 */
+	if (srcaddr == NULL || !IN6_IS_ADDR_UNSPECIFIED(srcaddr))
+		;
+	else if ((ia = in6_ifawithifp(ifp, dstaddr)) == NULL)
+		return E_SYS;
+	else
+		srcaddr = &ia->addr;
+
+	/* IPv6 ヘッダを設定する。*/
+	ip6h		= GET_IP6_HDR(nbuf);
+	ip6h->vcf	= htonl(IP6_MAKE_VCF(IPV6_VERSION, 0));
+	ip6h->plen	= htons(len);
+	ip6h->next	= next;
+	ip6h->hlim	= hlim;
+
+	if (dstaddr == NULL)
+		memset(&ip6h->dst, 0, sizeof(T_IN6_ADDR));
+	else
+		memcpy(&ip6h->dst, dstaddr, sizeof(T_IN6_ADDR));
+
+	if (srcaddr == NULL)
+		memset(&ip6h->src, 0, sizeof(T_IN6_ADDR));
+	else
+		memcpy(&ip6h->src, srcaddr, sizeof(T_IN6_ADDR));
+
+	return E_OK;
+	}
+
+/*
+ *  in6_get_datagram -- IPv6 データグラムを獲得し、ヘッダを設定する。
+ */
+
+ER
+in6_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
+                  const T_IN6_ADDR *dstaddr, const T_IN6_ADDR *srcaddr,
+                  uint8_t next, uint8_t hlim, ATR nbatr, TMO tmout)
+{
+	ER		error;
+	uint_t		align;
+
+	/* データ長は 4 オクテット境界に調整する。	*/
+	align = (len + 3) >> 2 << 2;
+
+	/* ネットワークバッファを獲得する。	*/
+	if ((error = tget_net_buf_ex(nbuf, IF_IP6_HDR_SIZE + align,
+	                                   IF_IP6_HDR_SIZE + maxlen, nbatr, tmout)) != E_OK)
+		return error;
+
+	/*
+	 *  より大きなサイズのネットワークバッファを獲得する場合のみ長さを調整する。
+	 *  より小さなサイズのネットワークバッファの獲得は、送信ウィンドバッファの
+	 *  省コピー機能で使用され、実際に送信するまで、データサイズは決定できない。
+	 */
+	if ((nbatr & NBA_SEARCH_ASCENT) != 0)
+		(*nbuf)->len = IF_IP6_HDR_SIZE + len;
+
+	/* IPv6 ヘッダを設定する。*/
+	if ((error = in6_set_header(*nbuf, len, dstaddr, srcaddr, next, hlim)) != E_OK) {
+		syscall(rel_net_buf(*nbuf));
+		*nbuf = NULL;
+		return error;
+		}
+
+	/* 4 オクテット境界までパディングで埋める。*/
+	if (align > len)
+		memset(GET_IP6_SDU(*nbuf) + len, 0, align - len);
+
+	return E_OK;
+	}
+
+/*
+ *  in6_get_maxnum_ifaddr -- インタフェースに設定可能な最大アドレス数を返す。
+ */
+
+uint_t
+in6_get_maxnum_ifaddr (void)
+{
+	return NUM_IN6_IFADDR_ENTRY;
+	}
+
+/*
+ *  in6_get_ifaddr -- インタフェースに設定されているアドレスを返す。
+ */
+
+const T_IN6_ADDR *
+in6_get_ifaddr (int_t index)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+
+	if (index < NUM_IN6_IFADDR_ENTRY &&
+	    (ifp->in6_ifaddrs[index].flags & IN6_IFF_DEFINED))
+		return &ifp->in6_ifaddrs[index].addr;
+	else
+		return NULL;
+	}
+
+/*
+ *  ipv62str -- IPv6 アドレスを文字列に変換する。
+ */
+
+char *
+ipv62str (char *buf, const T_IN6_ADDR *p_addr)
+{
+	static char	addr_sbuf[NUM_IPV6ADDR_STR_BUFF][sizeof("0123:4567:89ab:cdef:0123:4567:255.255.255.255")];
+	static int_t	bix = NUM_IPV6ADDR_STR_BUFF;
+
+	bool_t	omit = false, zero = false;
+	char	*start;
+	int_t	ix, len6;
+
+	if (buf == NULL) {
+		syscall(wai_sem(SEM_IP2STR_BUFF_LOCK));
+		buf = addr_sbuf[-- bix];
+		if (bix <= 0)
+			bix = NUM_IPV6ADDR_STR_BUFF;
+		syscall(sig_sem(SEM_IP2STR_BUFF_LOCK));
+		}
+
+	start = buf;
+	if (p_addr == NULL || IN6_IS_ADDR_UNSPECIFIED(p_addr)) {
+		*buf ++ = '0';
+		*buf ++ = ':';
+		*buf ++ = ':';
+		*buf ++ = '0';
+		}
+	else {
+		if (IN6_IS_ADDR_V4MAPPED(p_addr))
+			len6 = sizeof(T_IN6_ADDR) / 2 - 2;
+		else
+			len6 = sizeof(T_IN6_ADDR) / 2;
+		for (ix = 0; ix < len6; ix ++) {
+			if (omit) {
+				buf += convert_hexdigit(buf, ntohs(p_addr->s6_addr16[ix]), 16, 0, ' '); 
+				if (ix < 7)
+					*buf ++ = ':';
+				}
+			else if (ix > 0 && ix < 7 && p_addr->s6_addr16[ix] == 0)
+				zero = true;
+			else {
+				if (zero) {
+					omit = true;
+					*buf ++ = ':';
+					}
+				buf += convert_hexdigit(buf, ntohs(p_addr->s6_addr16[ix]), 16, 0, ' '); 
+				if (ix < 7)
+					*buf ++ = ':';
+				}
+			}
+
+		if (len6 == sizeof(T_IN6_ADDR) / 2 - 2) {
+			T_IN4_ADDR ipv4addr;
+
+			ipv4addr = ntohl(p_addr->s6_addr32[3]);
+			buf += convert_hexdigit(buf, (uint_t)((ipv4addr >> 24) & 0xff), 10, 0, ' ');
+			*(buf ++) = '.';
+			buf += convert_hexdigit(buf, (uint_t)((ipv4addr >> 16) & 0xff), 10, 0, ' ');
+			*(buf ++) = '.';
+			buf += convert_hexdigit(buf, (uint_t)((ipv4addr >>  8) & 0xff), 10, 0, ' ');
+			*(buf ++) = '.';
+			buf += convert_hexdigit(buf, (uint_t)((ipv4addr      ) & 0xff), 10, 0, ' ');
+			}
+		}
+	*buf = '\0';
+	return start;
+	}
+
+/*
+ *  in6_cksum -- IPv6 のトランスポート層ヘッダのチェックサムを計算する。
+ *
+ *  注意: 戻り値はネットワークバイトオーダ
+ */
+
+uint16_t
+in6_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len)
+{
+	uint32_t	sum;
+	uint_t		align;
+
+	/* 4 オクテット境界のデータ長 */
+	align = (len + 3) >> 2 << 2;
+
+	/* 4 オクテット境界までパディングで埋める。*/
+	if (align > len)
+		memset((uint8_t*)nbuf->buf + off + len, 0, align - len);
+
+	sum = in_cksum_sum(nbuf->buf + off, align)
+	    + in_cksum_sum(&GET_IP6_HDR(nbuf)->src, sizeof(T_IN6_ADDR) * 2)
+	    + len + proto;
+	sum = in_cksum_carry(sum);
+
+	return ~htons((uint16_t)sum);
+	}
+
+/*
+ *  get_ip6_hdr_size -- 拡張ヘッダも含めた IPv6 ヘッダ長を返す。
+ */
+
+uint_t
+get_ip6_hdr_size (T_NET_BUF *nbuf)
+{
+	T_IP6_HDR	*iph = GET_IP6_HDR(nbuf);
+	uint_t		size = IP6_HDR_SIZE, hsize;
+	uint8_t		curr = iph->next, next;
+	uint8_t		*hdr = ((uint8_t *)iph) + IP6_HDR_SIZE;
+
+	while (1) {
+		next = *hdr;
+		if (curr ==IPPROTO_NONE)		/* 次ヘッダ無し			*/
+			break;
+		else if (curr == IPPROTO_FRAGMENT)	/* 断片化			*/
+			hsize = sizeof(T_IP6_FRAG_HDR);
+		else if (curr == IPPROTO_AH)		/* IPv6 認証			*/
+			hsize = (((T_IP6_AH_HDR *)hdr)->len + 2) * 4;
+		else if (curr == IPPROTO_HOPOPTS ||	/* 中継点 (Hop-by-Hop) オプション	*/
+		         curr == IPPROTO_DSTOPTS ||	/* IPv6 終点オプション		*/
+		         curr == IPPROTO_ROUTING)	/* 経路制御			*/
+			hsize = (((T_IP6_EXT_HDR *)hdr)->len + 1) * 8;
+		else
+			break;
+		size += hsize;
+		hdr  += hsize;
+		curr = next;
+		}
+	return size;
+	}
+
+/*
+ *  in6_plen2pmask -- プレフィックス長からマスクを生成する。
+ */
+
+void
+in6_plen2pmask (T_IN6_ADDR *mask, uint_t prefix_len)
+{
+	uint8_t	*ptr, bit;
+
+	memset(mask->s6_addr + prefix_len / 8, 0, (128 - prefix_len + 7) / 8);
+	for (ptr = mask->s6_addr; prefix_len > 0; ptr ++) {
+		for (bit = 0x80; bit && (prefix_len > 0); prefix_len --) {
+			*ptr |= bit;
+			bit >>= 1;
+			}
+		}
+	}
+
+/*
+ *  in6_rtalloc -- ルーティング表を探索する。
+ */
+
+const T_IN6_ADDR *
+in6_rtalloc (T_IFNET *ifp, const T_IN6_ADDR *dst)
+{
+	if (IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MULTICAST(dst))
+		return dst;
+	else {
+		T_IN6_IFADDR	*ia;
+		SYSTIM		now;
+		int_t		ix;
+
+		/*
+		 *  サイトローカルアドレスか集約可能（グローバル）アドレスの場合は、
+		 *  同一リンク内のノードであるかをチェックする。
+		 */
+
+		syscall(get_tim(&now));
+		now /= SYSTIM_HZ;
+
+		/* 推奨有効時間内のアドレスを探索する。*/
+		for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
+			ia = &ifp->in6_ifaddrs[ix];
+			if (IFA6_IS_READY(ia) &&
+			    in6_are_prefix_equal(dst, &ia->addr, ia->prefix_len) &&
+			    (int32_t)(ia->lifetime.preferred - now) > 0) {
+		                   /* ia->lifetime.preferred > now */
+				return dst;
+				}
+			}
+
+		/* 有効時間内のアドレスを探索する。*/
+		for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
+			ia = &ifp->in6_ifaddrs[ix];
+			if (IFA6_IS_READY(ia) &&
+			    in6_are_prefix_equal(dst, &ia->addr, ia->prefix_len) &&
+			    (int32_t)(ia->lifetime.expire - now) > 0)
+		                   /* ia->lifetime.expire > now */
+				return dst;
+			}
+
+		/*
+		 *  プレフィックスを探索する。
+		 */
+		if (nd6_onlink_prefix_lookup (dst) != NULL)
+			return dst;
+
+		/*
+		 *  静的経路表を探索する。
+		 */
+
+#if NUM_IN6_ROUTE_ENTRY > 0
+
+		syscall(wai_sem(SEM_IN6_ROUTING_TBL));
+		for (ix = NUM_IN6_ROUTE_ENTRY; ix --; ) {
+			if ((routing6_tbl[ix].flags & IN_RTF_DEFINED) &&
+			    in6_are_prefix_equal(dst, &routing6_tbl[ix].target,
+			                               routing6_tbl[ix].prefix_len)) {
+
+				/*
+				 *  向け直しによるエントリは、有効時間が切れる時刻を延長する。
+				 *  expire の単位は [s]。
+				 *  TMO_IN_REDIRECT の単位は [ms]。
+				 */
+				if (ix > NUM_IN6_STATIC_ROUTE_ENTRY) {
+					SYSTIM	now;
+
+					syscall(get_tim(&now));
+					routing6_tbl[ix].expire = now / SYSTIM_HZ + TMO_IN_REDIRECT / 1000;
+					}
+
+				syscall(sig_sem(SEM_IN6_ROUTING_TBL));
+				return &routing6_tbl[ix].gateway;
+				}
+			}
+		syscall(sig_sem(SEM_IN6_ROUTING_TBL));
+
+#endif	/* of #if NUM_IN6_ROUTE_ENTRY > 0 */
+
+		/*
+		 *  ディフォルトルータ・リストを探索する。
+		 */
+		return nd6_router_lookup();
+		}
+	}
+
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
+
+/*
+ *  in6_gateway_lookup -- ルーティング表のルータを探索する。
+ */
+
+T_IN6_RTENTRY *
+in6_gateway_lookup (const T_IN6_ADDR *gw)
+{
+	int_t	ix;
+
+	for (ix = NUM_IN6_ROUTE_ENTRY; ix --; )
+		if ((routing6_tbl[ix].flags & IN_RTF_DEFINED) &&
+		    IN6_ARE_ADDR_EQUAL(&routing6_tbl[ix].gateway, gw))
+			return &routing6_tbl[ix];
+	return NULL;
+	}
+
+/*
+ *  in6_rtredirect -- ルーティング表にエントリを登録する。
+ *
+ *    注意: 引数 tmo の単位は [us]。
+ */
+
+void
+in6_rtredirect (const T_IN6_ADDR *gateway, const T_IN6_ADDR *target, uint_t prefix_len, uint8_t flags, uint32_t tmo)
+{
+	T_IN6_RTENTRY	*frt;
+
+	frt = in6_rtnewentry(flags, tmo);
+	memcpy(&frt->gateway, gateway, sizeof(T_IN6_ADDR));
+	memcpy(&frt->target, target, sizeof(T_IN6_ADDR));
+	frt->prefix_len = prefix_len;
+	}
+
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
+
+#if NUM_IN6_HOSTCACHE_ENTRY > 0
+
+/*
+ *  in6_hostcache_lookup -- IPv6 ホストキャッシュを探索する。
+ */
+
+static T_IN6_HOSTCACHE_ENTRY*
+in6_hostcache_lookup (const T_IN6_ADDR *dst)
+{
+	int_t ix;
+
+	for (ix = NUM_IN6_HOSTCACHE_ENTRY; ix -- > 0; ) {
+		if (IN6_ARE_ADDR_EQUAL(dst, &in6_hostcache[ix].dst))
+			return &in6_hostcache[ix];
+		}
+	return NULL;
+	}
+
+/*
+ *  in6_hostcache_update -- IPv6 ホストキャッシュを更新する。
+ */
+
+void
+in6_hostcache_update (T_IN6_ADDR *dst, uint32_t mtu)
+{
+	T_IN6_HOSTCACHE_ENTRY	*hc;
+	SYSTIM	now, old;
+	int_t	ix, oix;
+
+	syscall(get_tim(&now));
+
+	/* 既に登録されているか探索する。*/
+	if ((hc = in6_hostcache_lookup (dst)) == NULL) {
+
+		/* 空きのホストキャッシュを探す。*/
+		for (ix = NUM_IN6_HOSTCACHE_ENTRY; ix -- > 0; ) {
+			if (IN6_IS_HOSTCACHE_FREE(&in6_hostcache[ix]))
+				break;
+			}
+
+		if (ix < 0) {
+			/*
+			 *  空きが無い時は、有効時間の切れる時間が、
+			 *  最も短いホストキャッシュを置換する。
+			 */
+			old = now - 1;
+			oix = 0;
+			for (ix = NUM_IN6_HOSTCACHE_ENTRY; ix -- > 0; ) {
+				hc = &in6_hostcache[ix];
+				if (IN6_IS_HOSTCACHE_BUSY(hc) && (int32_t)(hc->expire - old) < 0) {
+				                                        /* hc->expire < old */
+					oix = ix;
+					old = hc->expire;
+					}
+				}
+			ix = oix;
+			}
+		hc = &in6_hostcache[ix];
+		}
+	else if (mtu > hc->mtu &&
+	         (int32_t)(hc->expire - now) >= (IN6_HOSTCACHE_EXPIRE - IN6_HOSTCACHE_INCREASE)) {
+
+		/*
+		 *  既に登録されていて、新しい MTU が、登録されている MTU より大きいとき、
+		 *  IN6_HOSTCACHE_INCREASE（推奨 10 分）間は更新しない。
+		 */
+		return;
+		}
+	memcpy(&hc->dst, dst, sizeof(T_IN6_ADDR));
+	hc->expire = now + IN6_HOSTCACHE_EXPIRE;
+	hc->mtu    = mtu;
+	}
+
+/*
+ *  in6_hostcache_getmtu -- IPv6 ホストキャッシュをから MTU を取得する。
+ *
+ *    戻り値が 0 であれば、ホストキャッシュに登録されていない。
+ */
+
+uint32_t
+in6_hostcache_getmtu (const T_IN6_ADDR *dst)
+{
+	T_IN6_HOSTCACHE_ENTRY	*hc;
+
+	/* 既に登録されているか探索する。*/
+	if ((hc = in6_hostcache_lookup(dst)) == NULL)
+		return 0;
+	else
+		return hc->mtu;
+	}
+
+/*
+ *  in6_hostcache_timer -- IPv6 ホストキャッシュ更新タイマー
+ *
+ *    1秒周期で起動される。
+ */
+
+static void
+in6_hostcache_timer (void)
+{
+	static int_t interval = IN6_HOSTCACHE_PRUNE / SYSTIM_HZ;
+
+	SYSTIM	now;
+
+	interval --;
+	if (interval <= 0) {
+		syscall(get_tim(&now));
+		interval = IN6_HOSTCACHE_PRUNE / SYSTIM_HZ;
+		}
+	}
+
+#endif	/* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
+
+/*
+ *  in6_timer -- IPv6 共通タイマー
+ *
+ *    1秒周期で起動される。
+ */
+
+static void
+in6_timer (void)
+{
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
+
+	in6_rttimer();
+
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
+
+#ifdef IP6_CFG_FRAGMENT
+
+	frag6_timer();
+
+#endif	/* of #ifdef IP6_CFG_FRAGMENT */
+
+#if NUM_IN6_HOSTCACHE_ENTRY > 0
+
+	in6_hostcache_timer();
+
+#endif	/* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
+
+	timeout((callout_func)in6_timer, NULL, IN_TIMER_TMO);
+	}
+
+/*
+ *  in6_init -- IPv6 共通機能を初期化する。
+ */
+
+void
+in6_init (void)
+{
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
+
+	in6_rtinit();
+
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
+
+	timeout((callout_func)nd6_timer, NULL, ND6_TIMER_TMO);
+	timeout((callout_func)in6_timer, NULL, IN_TIMER_TMO);
+	}
+
+/*
+ *  in6_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
+ */
+
+bool_t
+in6_is_dstaddr_accept (const T_IN6_ADDR *myaddr, const T_IN6_ADDR *dstaddr)
+{
+	if (IN6_IS_ADDR_UNSPECIFIED(myaddr))
+		return in6_lookup_ifaddr(IF_GET_IFNET(), dstaddr) != NULL;
+	else
+		return IN6_ARE_ADDR_EQUAL(dstaddr, myaddr);
+	}
+
+#if defined(DHCP6_CLI_CFG)
+
+/*
+ *  in6_add_ifaddr -- インタフェースに IPv6 アドレスを設定する。
+ *
+ *    vltime と pltime の単位は[s]
+ */
+
+static ER
+in6_add_ifaddr (T_IN6_ADDR *addr, uint_t prefix_len,
+                uint32_t vltime, uint32_t pltime)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN6_IFADDR	*ia = NULL;
+	int_t		ix;
+
+	/* 空きのエントリーを探す。*/
+	ix = 0;
+	while (true) {
+		ia = in6ifa_ifpwithix(ifp, ix ++);
+
+		/* 空きが無ければエラー */
+		if (ia == NULL)
+			return E_OBJ;
+
+		if ((ia->flags & IN6_IFF_DEFINED) == 0)
+			break;
+		}
+
+	/* 登録する。*/
+	return in6_update_ifa(ifp, ia, addr, prefix_len, vltime, pltime,
+	                      IN6_RTR_IX_UNREACH, ND6_PREFIX_IX_INVALID, 0);
+	}
+
+/*
+ *  in6_upd_ifaddr -- インタフェースに設定されている IPv6 アドレスを更新する。
+ *
+ *    登録されていなければ、追加する。
+ *    vltime と pltime の単位は[s]
+ */
+
+ER
+in6_upd_ifaddr (T_IN6_ADDR *addr, uint_t prefix_len,
+                uint32_t vltime, uint32_t pltime)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN6_IFADDR	*ia;
+	int_t		ix;
+
+	/*
+	 *  アドレスが一致するエントリーを探す。
+	 *  無ければ登録する。
+	 */
+	if ((ix = in6_addr2ifaix(addr)) == IPV6_IFADDR_IX_INVALID)
+		return in6_add_ifaddr(addr, prefix_len, vltime, pltime);
+
+	/*
+	 *  インデックス番号から、エントリーに変換する。
+	 *  エラーにならないはずであるが、確認する。
+	 */
+	if ((ia = in6ifa_ifpwithix (ifp, ix)) == NULL)
+		return E_OBJ;
+
+	/* 更新する。*/
+	return in6_update_ifa(ifp, ia, addr, prefix_len, vltime, pltime,
+	                      IN6_RTR_IX_UNREACH, ND6_PREFIX_IX_INVALID, 0);
+	}
+
+/*
+ *  in6_del_ifaddr -- インタフェースに設定されている IPv6 アドレスを削除する。
+ */
+
+ER
+in6_del_ifaddr (T_IN6_ADDR *addr)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	int_t		ix;
+
+	/* アドレスが一致するエントリーを探す。*/
+	if ((ix = in6_addr2ifaix(addr)) != IPV6_IFADDR_IX_INVALID) {
+
+		/* エントリーを無効にする。*/
+		ifp->in6_ifaddrs[ix].flags &= ~IN6_IFF_DEFINED;
+		return E_OK;
+		}
+	return E_PAR;
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG) */
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/in6_var.h	(revision 398)
@@ -0,0 +1,369 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/in6_var.h,v 1.3.2.2 2001/07/03 11:01:52 ume Exp $	*/
+/*	$KAME: in6_var.h,v 1.56 2001/03/29 05:34:31 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1985, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)in_var.h	8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _IN6_VAR_H_
+#define _IN6_VAR_H_
+
+/*
+ *  アドレスの定義
+ */
+
+#ifdef _NET_CFG_BYTE_ORDER
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
+
+#define IPV6_ADDR_INT32_ONE		ULONG_C(0x00000001)
+#define IPV6_ADDR_INT32_TWO		ULONG_C(0x00000002)
+#define IPV6_ADDR_INT32_0000FFFF	ULONG_C(0x0000ffff)
+#define IPV6_ADDR_INT32_MNL		ULONG_C(0xff010000)
+#define IPV6_ADDR_INT32_MLL		ULONG_C(0xff020000)
+#define IPV6_ADDR_INT32_ULL		ULONG_C(0xfe800000)
+#define IPV6_ADDR_INT16_ULL		UINT_C(0xfe80)
+#define IPV6_ADDR_INT16_USL		UINT_C(0xfec0)
+#define IPV6_ADDR_INT16_MLL		UINT_C(0xff02)
+
+#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
+
+#define IPV6_ADDR_INT32_ONE		ULONG_C(0x01000000)
+#define IPV6_ADDR_INT32_TWO		ULONG_C(0x02000000)
+#define IPV6_ADDR_INT32_0000FFFF	ULONG_C(0xffff0000)
+#define IPV6_ADDR_INT32_MNL		ULONG_C(0x000001ff)
+#define IPV6_ADDR_INT32_MLL		ULONG_C(0x000002ff)
+#define IPV6_ADDR_INT32_ULL		ULONG_C(0x000080fe)
+#define IPV6_ADDR_INT16_ULL		UINT_C(0x80fe)
+#define IPV6_ADDR_INT16_USL		UINT_C(0xc0fe)
+#define IPV6_ADDR_INT16_MLL		UINT_C(0x02ff)
+
+#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#endif	/* of #ifdef _NET_CFG_BYTE_ORDER */
+
+/*
+ *  特別なアドレスのチェック
+ */
+
+/* IPv4 互換 */
+
+#ifdef _NET_CFG_BYTE_ORDER
+#define IN6_IS_ADDR_V4COMPAT(a)		\
+	(memcmp((void *)(a), (void *)&in6_addr_unspecified, sizeof(T_IN6_ADDR) - 4) == 0 && \
+	 (a)->s6_addr32[3] > IPV6_ADDR_INT32_ONE)
+#endif
+
+/* IPv4 射影 */
+
+#ifdef _NET_CFG_BYTE_ORDER
+#define IN6_IS_ADDR_V4MAPPED(a)		\
+	(((a)->s6_addr32[0] == ULONG_C(0x00000000)) && \
+	 ((a)->s6_addr32[1] == ULONG_C(0x00000000)) && \
+	 ((a)->s6_addr32[2] == IPV6_ADDR_INT32_0000FFFF))
+#endif
+
+/* 要請マルチキャスト */
+
+#ifdef _NET_CFG_BYTE_ORDER
+#define IN6_IS_ADDR_NS_MULTICAST(a)	\
+	(((a)->s6_addr32[0] == IPV6_ADDR_INT32_MLL) && \
+	 ((a)->s6_addr32[1] == ULONG_C(0x00000000)) && \
+	 ((a)->s6_addr32[2] == IPV6_ADDR_INT32_ONE) && \
+	 ((a)->s6_addr8[12] == UINT_C(0xff)))
+#endif
+
+#ifndef _MACRO_ONLY
+
+/*
+ *  アドレス有効時間構造体
+ */
+
+typedef struct in6_addr_lifetime {
+
+	/*
+	 * expire と perferred は、システムが起動してからの経過時間
+	 */
+	uint32_t	expire;		/* 有効時間が切れる時刻 [s]	*/
+	uint32_t	preferred;	/* 推奨有効時間が切れる時刻 [s]	*/
+
+	/*
+	 * vltime と pltime は、追加/変更してからの相対時間
+	 */
+	uint32_t	vltime;		/* 有効時間 [us]			*/
+	uint32_t	pltime;		/* 推奨有効時間 [us]		*/
+	} __attribute__((packed, aligned(2)))T_IN6_ADDR_LIFETIME;
+
+/*
+ *  インタフェースアドレス構造体
+ */
+
+typedef struct t_in6_ifaddr {
+	T_IN6_ADDR		addr;		/* IPv6 アドレス		*/
+	T_IN6_ADDR_LIFETIME	lifetime;	/* 有効時間		*/
+	uint8_t			flags;		/* フラグ		*/
+	uint8_t			prefix_len;	/* プレフィックス長	*/
+	uint8_t			router_index;	/* ルータインデックス	*/
+	uint8_t			prefix_index;	/* プレフィックスインデックス	*/
+	uint8_t			na_icount;	/* 重複アドレス検出 (DAD) 通知の入力回数	*/
+	uint8_t			ns_icount;	/* 重複アドレス検出 (DAD) 要請の入力回数	*/
+	uint8_t			ns_ocount;	/* 重複アドレス検出 (DAD) 要請の出力回数	*/
+	} __attribute__((packed, aligned(2)))T_IN6_IFADDR;
+
+/*
+ *  アドレス状態フラグ
+ */
+
+#define IN6_IFF_ANYCAST		UINT_C(0x01)	/* エニーキャスト	*/
+#define IN6_IFF_DEFINED		UINT_C(0x02)	/* 定義済み		*/
+#define IN6_IFF_TENTATIVE	UINT_C(0x04)	/* 重複検出中		*/
+#define IN6_IFF_DUPLICATED	UINT_C(0x08)	/* 重複を検出した	*/
+#define IN6_IFF_DEPRECATED	UINT_C(0x10)	/* 非推奨		*/
+#define IN6_IFF_NODAD		UINT_C(0x20)	/* 重複検出不要		*/
+#define IN6_IFF_AUTOCONF	UINT_C(0x40)	/* 自動設定された	*/
+#define IN6_IFF_DETACHED	UINT_C(0x80)	/* 非使用		*/
+
+/*
+ *  アドレスの有効性チェック
+ */
+
+#define IFA6_IS_READY(a)	(((a)->flags & IN6_IFF_DEFINED) != 0 && \
+				 ((a)->flags & (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED|IN6_IFF_DETACHED)) == 0)
+#define IFA6_IS_NOTREADY(a)	(((a)->flags & IN6_IFF_DEFINED) == 0 ||	\
+				 ((a)->flags & (IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED|IN6_IFF_DETACHED)) != 0)
+
+#define IFA6_IS_DEPRECATED(a,n)	\
+	((a)->lifetime.preferred != 0 && (int32_t)((a)->lifetime.preferred - ((n / SYSTIM_HZ))) < 0)
+
+#define IFA6_IS_INVALID(a,n)	\
+	((a)->lifetime.expire != 0 && (int32_t)((a)->lifetime.expire - ((n / SYSTIM_HZ))) < 0)
+
+/*
+ *  ルータのインデックス
+ */
+
+#define IN6_RTR_IX_UNREACH	0xff
+
+/*
+ *  制限値
+ */
+
+#define IP6_HDR_NEST_LIMIT	50	/* IPv6 ヘッダのネスト制限値	*/
+
+/*
+ *  アドレス情報配列のインデックス
+ */
+
+#define IPV6_IFADDR_IX_LINKLOCAL	0
+#define IPV6_IFADDR_IX_INVALID		0xff
+
+/*
+ *  IPv6 マルチキャストアドレス配列のインデックス
+ */
+
+#define IPV6_MADDR_IX_SOL_NODE		0	/* 要請マルチキャスト・アドレス			*/
+#define IPV6_MADDR_IX_LL_ALL_NODE	1	/* 全ノード・リンクローカル・マルチキャストアドレス	*/
+#define IPV6_MADDR_IX_EXTRA		2
+
+#define MAX_IN6_MADDR_CNT		MAX_IF_MADDR_CNT
+						/* IPv6 マルチキャストアドレス配列の最大サイズ	*/
+
+/* ルーティング表エントリ構造体 */
+
+typedef struct t_in6_rtentry {
+	T_IN6_ADDR	target;		/* 目標ネットワークアドレス	*/
+	T_IN6_ADDR	gateway;	/* ゲートウェイの IP アドレス	*/
+	uint32_t	expire;		/* 有効時間が切れる時刻 [s]	*/
+	uint8_t		flags;		/* フラグ			*/
+	uint8_t		prefix_len;	/* プレフィックス長		*/
+	} __attribute__((packed, aligned(2)))T_IN6_RTENTRY;
+
+/*
+ *  ホストキャッシュ
+ */
+
+/* ホストキャッシュ構造体 */
+
+typedef struct t_in6_hostcache_entry {
+	T_IN6_ADDR	dst;		/* 目標ネットワークアドレス	*/
+	uint32_t	expire;		/* 有効時間が切れる時刻 [s]	*/
+	uint32_t	mtu;		/* Path MTU			*/
+	} __attribute__((packed, aligned(2)))T_IN6_HOSTCACHE_ENTRY;
+
+#define IN6_HOSTCACHE_EXPIRE	(60*60*SYSTIM_HZ)	/* 有効時間	*/
+#define IN6_HOSTCACHE_PRUNE	(5*60*SYSTIM_HZ)	/* 更新間隔	*/
+#define IN6_HOSTCACHE_INCREASE	(10*60*SYSTIM_HZ)	/* 増加する場合の保護時間	*/
+
+#define IN6_IS_HOSTCACHE_FREE(e)	IN6_IS_ADDR_UNSPECIFIED(&((e)->dst))
+#define IN6_IS_HOSTCACHE_BUSY(e)	(!IN6_IS_HOSTCACHE_FREE(e))
+
+/*
+ *  ルーティング表
+ */
+
+extern T_IN6_RTENTRY routing6_tbl[];
+
+/*
+ *  前方参照
+ */
+
+#ifndef T_IFNET_DEFINED
+
+typedef struct t_ifnet T_IFNET;
+
+#define T_IFNET_DEFINED
+
+#endif	/* of #ifndef T_IFNET_DEFINED */
+
+/*
+ *  変数
+ */
+
+extern uint32_t linkmtu;
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+#define IN6_COPY_TO_HOST(dst,nbuf)	memcpy(dst,&GET_IP6_HDR(nbuf)->src,sizeof(T_IN6_ADDR))
+#define INN6_IS_DSTADDR_ACCEPT(addr,nbuf)	\
+					in6_is_dstaddr_accept(addr,&GET_IP6_HDR(nbuf)->dst)
+
+/*
+ *  関数
+ */
+
+extern void in6_ifainit (void);
+extern int_t in6_addr2maix (const T_IN6_ADDR *addr);
+extern ER in6_update_ifa (T_IFNET *ifp, T_IN6_IFADDR *ia, const T_IN6_ADDR *addr,
+                          uint_t prefix_len, uint32_t vltime, uint32_t pltime,
+                          int_t router_index, int_t prefix_index, uint_t flags);
+extern ER in6_set_header (T_NET_BUF *nbuf, uint_t len,
+                          const T_IN6_ADDR *dstaddr, const T_IN6_ADDR *srcaddr,
+                          uint8_t next, uint8_t hlim);
+extern ER in6_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
+                            const T_IN6_ADDR *dstaddr, const T_IN6_ADDR *srcaddr,
+                            uint8_t next, uint8_t hlim, ATR nbatr, TMO tmout);
+extern uint16_t in6_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len);
+extern T_IN6_IFADDR *in6ifa_ifpwithix (T_IFNET *ifp, int_t ix);
+extern T_IN6_IFADDR *in6ifa_ifpwithrtrix (T_IFNET *ifp, int_t rtr_ix);
+extern T_IN6_IFADDR *in6_ifawithifp (T_IFNET *ifp, const T_IN6_ADDR *dst);
+extern const T_IN6_ADDR *in6_addrwithifp (T_IFNET *ifp, T_IN6_ADDR *src, const T_IN6_ADDR *dst);
+extern void ip6_input (T_NET_BUF *input);
+extern T_IN6_IFADDR *in6_lookup_ifaddr (T_IFNET *ifp, const T_IN6_ADDR *addr);
+extern bool_t in6_lookup_multi (T_IFNET *ifp, const T_IN6_ADDR *maddr);
+extern bool_t in6_is_dstaddr_accept (const T_IN6_ADDR *myaddr, const T_IN6_ADDR *dstaddr);
+extern bool_t inn6_is_dstaddr_accept (const T_IN6_ADDR *myaddr, T_NET_BUF *input);
+extern const T_IN6_ADDR *in6_rtalloc (T_IFNET *ifp, const T_IN6_ADDR *dst);
+extern int_t in6_if2idlen (T_IFNET *ifp);
+extern int_t in6_addr2ifaix (const T_IN6_ADDR *addr);
+extern void in6_plen2pmask (T_IN6_ADDR *mask, uint_t prefix_len);
+extern bool_t in6_are_prefix_equal (const T_IN6_ADDR *addr, const T_IN6_ADDR *prefix,
+                                  uint_t prefix_len);
+extern void in6_ifaddr_timer (T_IFNET *ifp);
+extern T_IN6_RTENTRY *in6_gateway_lookup (const T_IN6_ADDR *src);
+extern void in6_rtredirect (const T_IN6_ADDR *gateway, const T_IN6_ADDR *target,
+                            uint_t prefix_len, uint8_t flags, uint32_t tmo);
+extern void in6_init (void);
+extern void in6_if_up (T_IFNET *ifp);
+extern void in6_hostcache_update (T_IN6_ADDR *dst, uint32_t mtu);
+extern uint32_t in6_hostcache_getmtu (const T_IN6_ADDR *dst);
+extern uint_t in6_addrscope (const T_IN6_ADDR *addr);
+extern const T_NET_BUF**ip6_get_frag_queue (void);
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#endif	/* of #ifndef _IN6_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6.cfg	(revision 398)
@@ -0,0 +1,68 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  IPv6 で使用するカーネルオブジェクト
+ */
+
+#ifdef _IP6_CFG
+
+/* 近隣キャッシュ */
+
+CRE_SEM(SEM_ND6_CACHE, { TA_TPRI, 1, 1 });
+
+#if NUM_ND6_DEF_RTR_ENTRY > 0
+
+/* ディフォルトルータ・リスト */
+
+CRE_SEM(SEM_ND6_DEFRTRLIST, { TA_TPRI, 1, 1 });
+
+#endif	/* of #if NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+#ifdef IP6_CFG_FRAGMENT
+
+/* 分割ヘッダ */
+
+CRE_SEM(SEM_IP6_FRAG_QUEUE, { TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef IP6_CFG_FRAGMENT */
+
+#if NUM_IN6_ROUTE_ENTRY > 0
+
+/* ルーティング表 */
+
+CRE_SEM(SEM_IN6_ROUTING_TBL, { TA_TPRI, 1, 1 });
+
+#endif	/* of #if NUM_IN6_ROUTE_ENTRY > 0 */
+
+#endif	/* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6_input.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6_input.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6_input.c	(revision 398)
@@ -0,0 +1,665 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/ip6_input.c,v 1.11.2.10 2001/07/24 19:10:18 brooks Exp $	*/
+/*	$KAME: ip6_input.c,v 1.194 2001/05/27 13:28:35 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip_input.c	8.2 (Berkeley) 1/4/94
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+
+#include <netinet6/nd6.h>
+#include <netinet6/ah6.h>
+#include <netinet6/esp6.h>
+
+#include <net/if_var.h>
+
+#ifdef _IP6_CFG
+
+/*
+ *  関数
+ */
+
+static uint_t ip6_no_header_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+
+/*
+ *  上位プロトコル選択構造体
+ */
+
+typedef struct t_proto_switch {
+	uint_t (*func)(T_NET_BUF **, uint_t *, uint_t *);	/* 入力関数		*/
+	uint_t proto;						/* プロトコル番号	*/
+	} T_PROTO_SWITCH;
+
+static const T_PROTO_SWITCH proto_switch[] = {
+	{ esp6_input,	IPPROTO_ESP		},	/* IPv6 暗号化ヘッダ	*/
+	{ ah6_input,	IPPROTO_AH		},	/* IPv6 認証ヘッダ	*/
+	{ frag6_input,	IPPROTO_FRAGMENT	},	/* 断片ヘッダ		*/
+	{ route6_input,	IPPROTO_ROUTING		},	/* 経路制御ヘッダ	*/
+	{ dest6_input,	IPPROTO_DSTOPTS		},	/* IPv6 終点オプション	*/
+	{ ip6_no_header_input,
+			IPPROTO_NONE		},	/* 次ヘッダ無し		*/
+	{ icmp6_input,	IPPROTO_ICMPV6		},
+
+#if defined(SUPPORT_TCP)
+
+	{ tcp_input,	IPPROTO_TCP		},
+
+#endif	/* of #if defined(SUPPORT_TCP) */
+
+#if defined(SUPPORT_UDP) && TNUM_UDP6_CEPID > 0
+
+	{ udp6_input,	IPPROTO_UDP		},
+
+#endif	/* of #if defined(SUPPORT_UDP) && TNUM_UDP6_CEPID > 0 */
+
+	};
+
+#ifdef SUPPORT_MIB
+
+T_IN6_IFSTAT in6_ifstat;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+/*
+ *  get_upper_proto -- 上位プロトコル処理関数を返す。
+ */
+
+static uint_t (*
+get_upper_proto(uint_t proto))(T_NET_BUF **, uint_t *, uint_t *)
+{
+	int_t ix;
+
+	for (ix = sizeof(proto_switch) / sizeof(T_PROTO_SWITCH); ix -- > 0; )
+		if (proto_switch[ix].proto == proto)
+			return proto_switch[ix].func;
+	return NULL;
+	}
+
+/*
+ *  ip6_no_header_input -- 次ヘッダが無しの場合の入力処理
+ */
+
+static uint_t
+ip6_no_header_input (T_NET_BUF **input, uint_t *offp, uint_t *nextp)
+{
+	syscall(rel_net_buf(*input));
+	return IPPROTO_DONE;
+	}
+
+/*
+ *  ip6_hopopts_input -- 中継点オプション入力処理
+ *
+ *    本実装では、パディング以外のオプションを全て未知オプションとして処理する。
+ *
+ *    戻り値:
+ *
+ *      0 以上 		正常
+ *      IP6_OPT_RET_ERR (-1)	エラー、呼出側でネットワークバッファを開放する。
+ *      IP6_OPT_RET_REL (-2)	エラー、ネットワークバッファは開放されている。
+ */
+
+static ER_UINT
+ip6_hopopts_input (T_NET_BUF *input, uint_t *offp, uint_t *nextp)
+{
+	T_IP6_HBH_HDR	*hbh;
+	ER_UINT		optlen;
+	uint_t		len;
+	uint8_t		*opt;
+
+	hbh    = (T_IP6_HBH_HDR *)(input->buf + *offp);
+	len    = (hbh->len + 1) << 3;
+	*nextp = *offp - IF_HDR_SIZE + offsetof(T_IP6_HBH_HDR, next);
+	*offp += len;
+	opt    = (uint8_t *)hbh + sizeof(T_IP6_HBH_HDR);
+
+	for (len -= sizeof(T_IP6_HBH_HDR); len > 0; len -= optlen) {
+		switch (*opt) {
+		case IP6OPT_PAD1:
+			optlen = 1;
+			break;
+		case IP6OPT_PADN:
+			if (len < IP6OPT_MINLEN)
+				return IP6_OPT_RET_ERR;
+			optlen = *(opt + 1) + 2;
+			break;
+		case IP6OPT_JUMBO:
+		case IP6OPT_NSAP_ADDR:
+		case IP6OPT_TUNNEL_LIMIT:
+		case IP6OPT_RTR_ALERT:
+		default:
+			if (len < IP6OPT_MINLEN)
+				return IP6_OPT_RET_ERR;
+			optlen = ip6_unknown_opt(input, opt);
+			if (optlen < 0)
+				return optlen;
+			optlen += 2;
+			break;
+			}
+
+		opt += optlen;
+		}
+
+	return *offp;
+	}
+
+/*
+ *  ip6_get_prev_hdr -- 直前の拡張ヘッダの next フィールドのアドレスを返す。
+ *
+ *    注意: off には IF_HDR_SIZE も含まれている。
+ */
+
+uint8_t *
+ip6_get_prev_hdr (T_NET_BUF *nbuf, uint_t off)
+{
+	T_IP6_HDR	*ip6h;
+	T_IP6_EXT_HDR	*ip6eh;
+	uint_t		len;
+	uint8_t		next;
+
+	ip6h = GET_IP6_HDR(nbuf);
+	if (off == IF_HDR_SIZE + sizeof(T_IP6_HDR))
+		return &ip6h->next;
+	else {
+		next  = ip6h->next;
+		len   = IF_HDR_SIZE + sizeof(T_IP6_HDR);
+		ip6eh = NULL;
+
+		while (len < off) {
+			ip6eh = (T_IP6_EXT_HDR *)(nbuf->buf + len);
+
+			switch (next) {
+			case IPPROTO_FRAGMENT:
+				len += sizeof(T_IP6_FRAG_HDR);
+				break;
+			case IPPROTO_AH:
+				len += (ip6eh->len + 2) << 2;
+				break;
+			default:
+				len += (ip6eh->len + 2) << 3;
+				break;
+				}
+			next  = ip6eh->next;
+			}
+
+		if (ip6eh == NULL)
+			return NULL;
+		else
+			return &ip6eh->next;
+		}
+	}
+
+/*
+ *  ip6_init -- IPv6 の初期化関数
+ */
+
+void
+ip6_init (void)
+{
+	in6_init();
+	in6_ifainit();
+	}
+
+/*
+ *  ip6_input -- IPv6 の入力関数
+ */
+
+void
+ip6_input (T_NET_BUF *input)
+{
+	T_IP6_HDR	*ip6h;
+	T_IN6_IFADDR	*ia6;
+	T_IFNET		*ifp;
+	ER_UINT		noff;
+	uint_t		next, nest, plen, offp, nextp;
+	uint_t		(*func)(T_NET_BUF **, uint_t *, uint_t *);
+
+	NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_OCTETS], input->len - IF_HDR_SIZE);
+	NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_PACKETS], 1);
+	NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInReceives, 1);
+
+	/* IP ヘッダの長さをチェックする。*/
+	if (input->len < IF_IP6_HDR_SIZE) {
+		NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_SHORT], 1);
+		NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInHdrErrors, 1);
+		goto buf_rel;
+		}
+
+	ip6h = GET_IP6_HDR(input);
+
+	/* バージョンをチェックする。*/
+	if (IP6_VCF_V(ntohl(ip6h->vcf)) != IPV6_VERSION) {
+		NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_VER], 1);
+		NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInHdrErrors, 1);
+		goto buf_rel;
+		}
+
+	/*
+	 *  次のデータグラムは破棄する。
+	 *
+	 *    ・始点アドレスがマルチキャスト
+	 *    ・終点アドレスが未定義
+	 *
+	 *  ネットワークインタフェースがループバックでないとき、
+	 *  次のデータグラムも破棄する。
+	 *
+	 *    ・始点アドレスがループバック
+	 *    ・終点アドレスがループバック
+	 *
+	 *  悪意のあるユーザが TCP/UDP スタックの混乱や
+	 *  セキュリティチェックをバイパスするため、IPv4
+	 *  マップアドレスを悪用することを防ぐため
+	 *  以下のデータグラムは破棄する。  
+	 *
+	 *    ・始点アドレスが ::ffff:127.0.0.1
+	 *    ・終点アドレスが ::ffff:127.0.0.1
+	 */
+
+	if (IN6_IS_ADDR_MULTICAST(&ip6h->src) ||
+	    IN6_IS_ADDR_UNSPECIFIED(&ip6h->dst)) {
+		NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_ADDR], 1);
+		NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInAddrErrors, 1);
+		goto buf_rel;
+		}
+
+	if (IN6_IS_ADDR_V4MAPPED(&ip6h->src) ||
+	    IN6_IS_ADDR_V4MAPPED(&ip6h->dst)) {
+		NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_ADDR], 1);
+		NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInAddrErrors, 1);
+		goto buf_rel;
+		}
+
+#ifdef SUPPORT_LOOP
+
+#else	/* of #ifdef SUPPORT_LOOP */
+
+	if (IN6_IS_ADDR_LOOPBACK(&ip6h->src) ||
+	    IN6_IS_ADDR_LOOPBACK(&ip6h->dst)) {
+		NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_ADDR], 1);
+		NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInAddrErrors, 1);
+		goto buf_rel;
+		}
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+	ifp = IF_GET_IFNET();
+
+	if (IN6_IS_ADDR_MULTICAST(&ip6h->dst)) {
+		/* 宛先がマルチキャストの場合の処理 */
+		NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInMcastPkts, 1);
+		if (!in6_lookup_multi(ifp, &ip6h->dst)) {
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_ADDR], 1);
+			NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInAddrErrors, 1);
+			goto buf_rel;
+			}
+		}
+	else {
+		if ((ia6 = in6_lookup_ifaddr(ifp, &ip6h->dst)) == NULL) {
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_ADDR], 1);
+			NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInAddrErrors, 1);
+			goto buf_rel;
+			}
+
+		/*  アドレスが未解決の場合はデータグラムを破棄する。*/
+		if (IFA6_IS_NOTREADY(ia6)) {
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_ADDR], 1);
+			NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInAddrErrors, 1);
+			goto buf_rel;
+			}
+		}
+
+	/* オフセットを設定する。*/
+	offp  = GET_IP6_NEXT_HDR(input) - input->buf;
+
+	/* ペイロード長を取り出す。*/
+	plen = ntohs(ip6h->plen);
+
+
+	/* 次ヘッダの位置を初期化する。*/
+	nextp = offsetof(T_IP6_HDR, next);
+
+	/*
+	 *  中継点 (Hop-by-Hop) オプションヘッダのチェック
+	 */
+	if (ip6h->next == IPPROTO_HOPOPTS) {
+
+		/* 中継点ヘッダの長さをチェックする。*/
+		if (plen < sizeof(T_IP6_HBH_HDR)) {
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_SHORT], 1);
+			NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInHdrErrors, 1);
+			goto buf_rel;
+			}
+
+		if ((noff = ip6_hopopts_input(input, &offp, &nextp)) < 0) {
+			if (noff == IP6_OPT_RET_ERR) {
+				NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_PACKETS], 1);
+				NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInHdrErrors, 1);
+				goto buf_rel;
+				}
+			else if (noff == IP6_OPT_RET_REL) {
+				NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_PACKETS], 1);
+				NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInHdrErrors, 1);
+				return;
+				}
+			}
+
+		/*
+		 *  ペイロード長が 0 で、中継点オプションがあるときは、
+		 *  巨大ペイロード・オプションが含まれなければならない。
+		 *  このとき、巨大ペイロード・オプションにある
+		 *  ペイロード長をチェックする必要があるが、本実装では、
+		 *  巨大ペイロード・オプションを未知のオプションとして
+		 *  扱うので、何もしない。
+		 */
+		next = ((T_IP6_HBH_HDR *)(ip6h + 1))->next;
+		}
+	else
+		next = ip6h->next;
+
+	/* IPv6 データグラム長をチェックする。*/
+	if (input->len - IF_IP6_HDR_SIZE < plen) {
+		NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_SHORT], 1);
+		NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInTruncatedPkts, 1);
+		goto buf_rel;
+		}
+	else if (input->len > IF_IP6_HDR_SIZE + plen)
+		input->len = IF_IP6_HDR_SIZE + plen;
+
+	/* 上位プロトコル処理関数を呼び出す。*/
+	nest = 0;
+	while (next != IPPROTO_DONE) {
+		if (++ nest > IP6_HDR_NEST_LIMIT) {
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_PROTO], 1);
+			NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInUnknownProtos, 1);
+			goto buf_rel;
+			}
+		else if ((func = get_upper_proto(next)) == NULL) {
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_PROTO], 1);
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_PACKETS], 1);
+			NET_COUNT_MIB(in6_ifstat.ipv6IfStatsInUnknownProtos, 1);
+
+			/* icmp6_error でネットワークバッファを開放する。*/
+			icmp6_error(input, ICMP6_PARAM_PROB,
+			                   ICMP6_PARAMPROB_NEXT_HEADER, nextp);
+			return;
+			}
+		else {
+			next = (*func)(&input, &offp, &nextp);
+			}
+		}
+	return;
+
+buf_rel:
+	NET_COUNT_IP6(net_count_ip6[NC_IP6_IN_ERR_PACKETS], 1);
+	syscall(rel_net_buf(input));
+	}
+
+/*
+ *  ip6_nexthdr -- 次のヘッダのオフセットを返す。
+ *
+ *    戻り値 == -1 : 最後のヘッダ、またはエラー。
+ *    戻り値 >   0 : さらにヘッダが続く。
+ */
+
+ER_UINT
+ip6_nexthdr (T_NET_BUF *nbuf, uint_t off, uint_t proto, uint_t *nextp)
+{
+	T_IP6_FRAG_HDR	*ip6fh;
+	T_IP6_EXT_HDR	*ip6eh;
+
+	switch (proto) {
+
+	case IPPROTO_IPV6:				/* IPv6 */
+		if (nbuf->len < off + IP6_HDR_SIZE)
+			return (ER_UINT)-1;
+		*nextp = ((T_IP6_HDR *)(nbuf->buf + off))->next;
+		return off + IP6_HDR_SIZE;
+		break;
+
+	case IPPROTO_FRAGMENT:			/* 断片ヘッダ */
+		if (nbuf->len < off + sizeof(T_IP6_FRAG_HDR))
+			return (ER_UINT)-1;
+
+		/* 中間のフラグメントの場合は処理をやめる。*/
+		ip6fh = (T_IP6_FRAG_HDR *)(nbuf->buf + off);
+		if (ntohs(ip6fh->off_flag) & IP6F_MORE_FRAG)
+			return (ER_UINT)-1;
+
+		*nextp = ip6fh->next;
+		return off + sizeof(T_IP6_FRAG_HDR);
+		break;
+
+	case IPPROTO_AH:		/* IPv6 認証ヘッダ			*/
+	case IPPROTO_HOPOPTS:		/* IPv6 中継点 (Hop-by-Hop) オプション	*/
+	case IPPROTO_ROUTING:		/* 経路制御ヘッダ			*/
+	case IPPROTO_DSTOPTS:		/* IPv6 終点オプション			*/
+		if (nbuf->len < off + sizeof(T_IP6_EXT_HDR))
+			return (ER_UINT)-1;
+
+		ip6eh = (T_IP6_EXT_HDR *)(nbuf->buf + off);
+		*nextp =  ip6eh->next;
+		if (proto == IPPROTO_AH)
+			return off + ((ip6eh->len + 2) << 2);
+		else
+			return off + ((ip6eh->len + 1) << 3);
+		break;
+		}
+
+	return (ER_UINT)-1;
+	}
+
+/*
+ *  ip6_lasthdr -- 最後のヘッダのオフセットを返す。
+ */
+
+ER_UINT
+ip6_lasthdr (T_NET_BUF *nbuf, uint_t off, uint_t proto, uint_t *nextp)
+{
+	ER_UINT	newoff;
+
+	while (1) {
+		newoff = ip6_nexthdr(nbuf, off, proto, nextp);
+		if (newoff < 0)
+			return (ER_UINT)off;
+		off   = newoff;
+		proto = *nextp;
+		}
+	return (ER_UINT)0u;
+	}
+
+/*
+ *  ip6_unknown_opt -- 未知のオプションの処理
+ *
+ *    戻り値:
+ *
+ *      0 以上 			正常、オプション長。
+ *      IP6_OPT_RET_ERR (-1)	エラー、呼出側でネットワークバッファを開放する。
+ *      IP6_OPT_RET_REL (-2)	エラー、ネットワークバッファは開放されている。
+ */
+
+ER_UINT
+ip6_unknown_opt (T_NET_BUF *input, uint8_t *opt)
+{
+	switch (IP6OPT_TYPE(*opt)) {
+	case IP6OPT_TYPE_SKIP:		/* 無視する。			*/
+		return *(opt + 1);
+		break;
+	case IP6OPT_TYPE_ICMP:		/* 破棄して、マルチキャストでなければ ICMP を返送する。	*/
+		if (IN6_IS_ADDR_MULTICAST(&GET_IP6_HDR(input)->dst))
+			return IP6_OPT_RET_ERR;
+		/* no break; */
+	case IP6OPT_TYPE_FORCEICMP:	/* 破棄して、ICMP を返送する。	*/
+		icmp6_error(input, ICMP6_PARAM_PROB,
+		                   ICMP6_PARAMPROB_OPTION,
+		                   (opt - input->buf) - IF_HDR_SIZE);
+		return IP6_OPT_RET_REL;
+		break;
+	/*case IP6OPT_TYPE_DISCARD:	データグラムを破棄する。	*/
+		}
+
+	return IP6_OPT_RET_ERR;
+	}
+
+/*
+ *  ip6_remove_exthdrs -- IPv6 拡張ヘッダを削除し、以降を前に詰める。
+ */
+
+ER
+ip6_remove_exthdrs (T_NET_BUF *nbuf)
+{
+	ER_UINT	off;
+	uint_t	next;
+
+	/* 開始オフセットを IP ヘッダに設定する。*/
+	off = ((uint8_t *)GET_IP6_HDR(nbuf)) - nbuf->buf;
+
+	/* 最終ヘッダを探索する。*/
+	off = ip6_lasthdr(nbuf, off, IPPROTO_IPV6, &next);
+
+	if (off <= 0)
+		return E_OBJ;
+	else {
+		uint_t sdu;
+
+		sdu = GET_IP6_SDU(nbuf) - nbuf->buf;
+		if (off > sdu) {
+			memmove(nbuf->buf + sdu, nbuf->buf + off, off - sdu);
+			GET_IP6_HDR(nbuf)->plen -= off - sdu;
+			nbuf->len              -= off - sdu;
+			}
+		}
+	return E_OK;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6_output.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6_output.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6_output.c	(revision 398)
@@ -0,0 +1,374 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/ip6_output.c,v 1.43 2002/10/31 19:45:48 ume Exp $	*/
+/*	$KAME: ip6_output.c,v 1.279 2002/01/26 06:12:30 jinmei Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip_output.c	8.3 (Berkeley) 1/21/94
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+
+#include <netinet6/nd6.h>
+
+#include <net/if_var.h>
+
+#ifdef _IP6_CFG
+
+/*
+ *  全域変数
+ */
+
+/* リンク MTU */
+
+uint32_t	linkmtu = IF_MTU;
+
+/*
+ *  局所変数
+ */
+
+#ifdef IP6_CFG_FRAGMENT
+
+static uint32_t	ip6_id;
+
+#endif	/* of #ifdef IP6_CFG_FRAGMENT */
+
+/*
+ *  ip6_output -- IPv6 の出力関数
+ */
+
+ER
+ip6_output (T_NET_BUF *output, uint16_t flags, TMO tmout)
+{
+	T_IP6_HDR		*ip6h;
+	const T_IN6_ADDR	*gw;
+	T_IFNET			*ifp = IF_GET_IFNET();
+	ER			error = E_OK;
+
+#ifdef IP6_CFG_FRAGMENT
+
+	T_IP6_HDR	*fip6h;
+	T_IP6_FRAG_HDR	*fip6f;
+	T_NET_BUF	*frag;
+	uint32_t	mtu, id;
+	uint16_t	plen, foff, flen;
+	uint8_t		nextproto;
+	bool_t		alwaysfrag = false;
+
+#endif	/* of #ifdef IP6_CFG_FRAGMENT */
+
+	ip6h = GET_IP6_HDR(output);
+
+	NET_COUNT_IP6(net_count_ip6[NC_IP6_OUT_OCTETS],
+	              GET_IP6_HDR_SIZE(output) + GET_IP6_SDU_SIZE(output));
+	NET_COUNT_IP6(net_count_ip6[NC_IP6_OUT_PACKETS], 1);
+	NET_COUNT_MIB(in6_ifstat.ipv6IfStatsOutRequests, 1);
+
+	/*
+	 *  重複アドレス検出要請以外には、送信元アドレスに
+	 *  無指定を指定できない。
+	 */
+	if (IN6_IS_ADDR_UNSPECIFIED(&ip6h->src) && (flags & IPV6_OUT_FLG_DAD) == 0) {
+		error = E_PAR;
+		goto drop;
+		}
+
+	/* 送信元アドレスにはマルチキャストアドレスを指定できない。*/
+	if (IN6_IS_ADDR_MULTICAST(&ip6h->src)) {
+		error = E_PAR;
+		goto drop;
+		}
+
+	/*
+	 *  経路選択を行う。
+	 */
+	if ((gw = in6_rtalloc(ifp, &ip6h->dst)) == NULL) {
+		error = E_PAR;
+		goto drop;
+		}
+
+	if (!IN6_IS_ADDR_MULTICAST(&ip6h->dst)) {
+		/* ユニキャストアドレスの処理 */
+		}
+	else {
+		/* マルチキャストアドレスの処理 */
+		NET_COUNT_MIB(in6_ifstat.ipv6IfStatsOutMcastPkts, 1);
+		if (flags & IPV6_OUT_FLG_HOP_LIMIT)
+			ip6h->hlim = IPV6_OUT_GET_HOP_LIMIT(flags);
+		else
+			ip6h->hlim = IPV6_DEFAULT_MULTICAST_HOPS;
+		}
+
+	/* Traffic Class と Flow Label をサポートしないので 0 に設定する。*/
+	ip6h->vcf = htonl(IP6_MAKE_VCF(IPV6_VERSION, 0));
+
+#ifdef IP6_CFG_FRAGMENT
+
+
+#if NUM_IN6_HOSTCACHE_ENTRY > 0
+
+	mtu = in6_hostcache_getmtu(&ip6h->dst);
+
+	if (0 < mtu && mtu <= IPV6_MMTU) {
+
+		/*
+		 *  Path MTU が登録されている場合、
+		 *  MTU が IPv6 MMTU（1280 オクテット）以下の場合は、
+		 *  MTU を IPv6 MMTU に設定し分割して送信する。
+		 */
+		mtu = IPV6_MMTU;
+		alwaysfrag = true;
+		}
+	else if (mtu == 0)
+		mtu  = linkmtu;
+
+#else	/* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
+
+	mtu  = linkmtu;
+
+#endif	/* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
+
+	plen = ntohs(ip6h->plen);
+	if (plen + IP6_HDR_SIZE <= mtu && !alwaysfrag) {
+
+		/* 分割する必要がないときの処理 */
+		if ((error = nd6_output(ifp, output, gw, NULL, tmout)) != E_OK) {
+			NET_COUNT_IP6(net_count_ip6[NC_IP6_OUT_ERR_PACKETS], 1);
+			NET_COUNT_MIB(in6_ifstat.ipv6IfStatsOutDiscards, 1);
+			}
+		}
+	else {
+
+		/* 断片 ID を設定する。*/
+		id = ip6_id ++;
+
+		/* MTU が IPv6 の最大パケットサイズを超えないようにする。*/
+		if (mtu > IPV6_MAXPACKET)
+			mtu = IPV6_MAXPACKET;
+
+		/*
+		 *  MTU から、分割不能部分（TINET-1.4 では、分割ヘッダ以外の
+		 *  拡張ヘッダの出力は未実装のため 0 オクテット）
+		 *  と断片ヘッダのサイズを引いたとき、8 オクテット以上なければ
+		 *  分割して送信できないためエラーにする。
+		 */
+		if (((mtu - sizeof(T_IP6_FRAG_HDR)) & ~7) < 8) {
+			error = E_PAR;
+			goto drop;
+			}
+
+		/*
+		 *  IPv6 ヘッダの next フィールドに設定する値は、断片ヘッダ。
+		 *  断片ヘッダの  next フィールドに設定する値は、
+		 *  元のデータグラムの next フィールドの値。
+		 */
+		nextproto  = ip6h->next;
+		ip6h->next = IPPROTO_FRAGMENT;
+
+		/* 分割して送信する。*/
+		NET_COUNT_IP6(net_count_ip6[NC_IP6_FRAG_OUT], 1);
+		for (foff = 0; foff < plen; foff += flen) {
+
+			/* 断片の長さを計算し、8 オクテット境界に調整する。*/
+			if (foff + (mtu - (IP6_HDR_SIZE + sizeof(T_IP6_FRAG_HDR))) < plen)
+				flen = (mtu - (IP6_HDR_SIZE + sizeof(T_IP6_FRAG_HDR))) >> 3 << 3;
+			else
+				flen = plen - foff;
+
+			/* ネットワークバッファを獲得する。*/
+			if (tget_net_buf(&frag, flen + IF_IP6_HDR_SIZE + sizeof(T_IP6_FRAG_HDR), TMO_IP6_FRAG_GET_NET_BUF) == E_OK) {
+
+				/* IPv6 ヘッダをコピーする。*/
+				fip6h = GET_IP6_HDR(frag);
+				*fip6h = *ip6h;
+
+				/* IPv6 ヘッダを埋める。*/
+				fip6h->plen	= htons(flen + sizeof(T_IP6_FRAG_HDR));
+
+				/* 断片ヘッダを埋める。*/
+				fip6f = (T_IP6_FRAG_HDR *)GET_IP6_NEXT_HDR(frag);
+				fip6f->off_flag	= htons((uint16_t)(foff & ~7));
+				if (foff + (mtu - (IP6_HDR_SIZE + sizeof(T_IP6_FRAG_HDR))) < plen)
+					fip6f->off_flag	|= IP6F_MORE_FRAG;
+				fip6f->reserved	= 0;
+				fip6f->ident	= htonl(id);
+				fip6f->next	= nextproto;
+
+				/* SDU をコピーする。*/
+				memcpy((uint8_t*)(fip6f + 1), GET_IP6_NEXT_HDR(output) + foff, flen);
+				NET_COUNT_IP6(net_count_ip6[NC_IP6_FRAG_OUT_FRAGS], 1);
+				NET_COUNT_MIB(in6_ifstat.ipv6IfStatsOutFragCreates, 1);
+
+				/* 送信する。*/
+				if ((error = nd6_output(ifp, frag, gw, NULL, tmout)) != E_OK) {
+					NET_COUNT_MIB(in6_ifstat.ipv6IfStatsOutFragFails, 1);
+					goto drop;
+					}
+				}
+			else {
+				/* ネットワークバッファが獲得できなければ、送信をあきらめる。*/
+				error = E_NOMEM;
+				goto drop;
+				}
+			}
+
+		/* IF でネットワークバッファを開放しないフラグをチェックする。*/
+		if ((output->flags & NB_FLG_NOREL_IFOUT) == 0) {
+			syscall(rel_net_buf(output));
+			}
+		else
+			output->flags &= (uint8_t)~NB_FLG_NOREL_IFOUT;
+
+		NET_COUNT_MIB(in6_ifstat.ipv6IfStatsOutFragOKs, 1);
+		}
+
+#else	/* #ifdef IP6_CFG_FRAGMENT */
+
+	if ((error = nd6_output(ifp, output, gw, NULL, tmout)) != E_OK) {
+		NET_COUNT_IP6(net_count_ip6[NC_IP6_OUT_ERR_PACKETS], 1);
+		NET_COUNT_MIB(in6_ifstat.ipv6IfStatsOutDiscards, 1);
+		}
+
+#endif	/* #ifdef IP6_CFG_FRAGMENT */
+
+	return error;
+
+drop:
+	/* IF でネットワークバッファを開放しないフラグをチェックする。*/
+	if ((output->flags & NB_FLG_NOREL_IFOUT) == 0) {
+		syscall(rel_net_buf(output));
+		}
+	else
+		output->flags &= (uint8_t)~NB_FLG_NOREL_IFOUT;
+
+	NET_COUNT_IP6(net_count_ip6[NC_IP6_OUT_ERR_PACKETS], 1);
+	NET_COUNT_MIB(in6_ifstat.ipv6IfStatsOutDiscards, 1);
+	return error;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6_var.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6_var.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ip6_var.h	(revision 398)
@@ -0,0 +1,310 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/ip6_var.h,v 1.10 2002/10/16 01:54:45 sam Exp $	*/
+/*	$KAME: ip6_var.h,v 1.62 2001/05/03 14:51:48 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)ip_var.h	8.1 (Berkeley) 6/10/93
+ */
+ 
+#ifndef _IP6_VAR_H_
+#define _IP6_VAR_H_
+
+/*
+ *  IPv6 ヘッダ・ペイロードアクセスマクロ
+ */
+
+#define IF_IP6_HDR_SIZE			(IF_HDR_SIZE + IP6_HDR_SIZE)
+
+#define GET_IP6_HDR(nbuf)		((T_IP6_HDR*)((nbuf)->buf + IF_HDR_SIZE))
+#define GET_IP6_SDU(nbuf)		((uint8_t*)((nbuf)->buf) + GET_IF_IP6_HDR_SIZE(nbuf))
+#define GET_IP6_NEXT_HDR(nbuf)		((uint8_t*)((nbuf)->buf) + IF_IP6_HDR_SIZE)
+
+#define GET_IP6_HDR_SIZE(nbuf)		(get_ip6_hdr_size(nbuf))
+#define GET_IP6_SDU_SIZE(nbuf)		(ntohs(GET_IP6_HDR(nbuf)->plen))
+#define GET_IF_IP6_HDR_SIZE(nbuf)	(IF_HDR_SIZE + (GET_IP6_HDR_SIZE(nbuf)))
+
+#define SET_IP6_CF(nbuf,cf)		(GET_IP6_HDR(nbuf)->vcf=htonl(IP6_MAKE_VCF(IP6_VCF_V(ntohl(GET_IP6_HDR(nbuf)->vcf)),cf)))
+#define SET_IP6_SDU_SIZE(nbuf,slen)	(GET_IP6_HDR(nbuf)->plen=htons(slen))
+
+/* ip6_output のフラグ */
+
+#define IPV6_OUT_FLG_DAD		0x0100	/* 重複アドレス検出	*/
+#define IPV6_OUT_FLG_HOP_LIMIT		0x0200	/* ホップリミット指定	*/
+
+/* ホップリミットフラグが付く時、ホップリミット値を操作するマクロ */
+
+#define IPV6_OUT_GET_HOP_LIMIT(f)	((f)&0x00ff)
+#define IPV6_OUT_SET_HOP_LIMIT(f,l)	((f)|(l))
+
+/*
+ *  ip6_unknown_opt -- 未知のオプションの処理
+ *
+ *    戻り値:
+ *
+ *      0 以上 			正常、オプション長。
+ *      IP6_OPT_RET_ERR (-1)	エラー、呼出側でネットワークバッファを開放する。
+ *      IP6_OPT_RET_REL (-2)	エラー、ネットワークバッファは開放されている。
+ */
+
+#define IP6_OPT_RET_ERR		(-1)
+#define IP6_OPT_RET_REL		(-2)
+
+/*
+ *  IPv6 の MMTU サイズのネットワークバッファ
+ */
+
+#if defined(IF_HDR_SIZE)
+
+typedef struct t_net_buf_ipv6_mmtu {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		unit;	/* インタフェース番号	*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IF_HDR_SIZE + IPV6_MMTU];
+				/* バッファ本体		*/
+	} T_NET_BUF_IPV6_MMTU;
+
+#endif	/* of #if defined(IF_HDR_SIZE) */
+
+/*
+ *  65536 オクテットサイズのネットワークバッファ
+ */
+
+typedef struct t_net_buf6_65536 {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IF_IP6_HDR_SIZE + 65536];
+				/* バッファ本体		*/
+#if defined(IF_PDU_HDR_PADDING)
+	uint8_t		padding[IF_PDU_HDR_PADDING];
+#endif				/* ヘッダの余分		*/
+	} T_NET_BUF6_65536;
+
+#ifdef IP6_CFG_FRAGMENT
+
+/*
+ *  再構成キュー用 IPv6 ヘッダの定義
+ */
+
+typedef struct t_qip6_hdr {
+	uint32_t		vcf;		/* Version:        4 bit		*/
+					/* Traffic Class:  8 bit		*/
+					/* Flow Label:    20 bit		*/
+	uint16_t	plen;		/* Payload Length			*/
+	uint8_t		next;		/* Next Header				*/
+	uint8_t		hlim;		/* Hop Limit				*/
+	T_IN6_ADDR	src;		/* Source Address			*/
+	T_NET_BUF	*next_frag;	/* 次の IPv6 フラグメント	*/
+	uint16_t	foff;		/* 断片ヘッダのオフセット		*/
+	uint16_t	flen;		/* 断片長				*/
+	uint16_t	ftim;		/* 再構成タイムアウト			*/
+	uint16_t	dummy1;
+	uint8_t		dummy2[sizeof(T_IN6_ADDR) - (sizeof(T_NET_BUF*) + sizeof(uint16_t) * 4)];
+	} __attribute__((packed, aligned(2)))T_QIP6_HDR;
+
+#define QIP6_HDR_SIZE			(sizeof(T_QIP6_HDR))
+#define IF_QIP6_HDR_SIZE		(IF_HDR_SIZE + QIP6_HDR_SIZE)
+
+#define GET_QIP6_HDR(nbuf)		((T_QIP6_HDR*)((nbuf)->buf + IF_HDR_SIZE))
+#define GET_QIP6_SDU(nbuf)		((uint8_t*)(nbuf)->buf + GET_IF_QIP6_HDR_SIZE(nbuf))
+
+#define GET_QIP6_HDR_SIZE(iph)		((uint8_t)IP6_VHL_HL((iph)->vhl) << 2)
+#define GET_IF_QIP6_HDR_SIZE(nbuf)	(IF_HDR_SIZE + (GET_QIP6_HDR_SIZE(GET_QIP6_HDR(nbuf))))
+
+/*
+ *  データグラム再構成用ネットワークバッファ
+ */
+
+typedef struct t_net_buf6_reassm {
+	uint16_t	len;	/* データの長さ		*/
+	uint8_t		idix;	/* mpfid のインデックス	*/
+	uint8_t		flags;	/* フラグ		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		align[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IP6_CFG_FRAG_REASSM_SIZE];
+				/* バッファ本体		*/
+	} T_NET_BUF6_REASSM;
+
+#endif	/* of #ifdef IP6_CFG_FRAGMENT */
+
+/*
+ *  TCP の再構成キューにおける IPv6 ヘッダの定義
+ */
+
+typedef struct t_ip6_tcp_q_hdr {
+	uint8_t vc;		/* Version:        4 bit		*/
+	uint8_t cf;		/* Traffic Class:  8 bit		*/
+			/* Flow Label:     4 bit (20 bit)	*/
+	uint16_t thoff;	/* TCP ヘッダのオフセット		*/
+	uint16_t plen;	/* Payload Length			*/
+	uint8_t next;	/* Next Header				*/
+	uint8_t hlim;	/* Hop Limit				*/
+	T_IN6_ADDR src;	/* Source Address			*/
+	T_IN6_ADDR dst;	/* Destination Address			*/
+	} __attribute__((packed, aligned(2))) T_IP6_TCP_Q_HDR;
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP の 管理情報ベース (MIB)
+ */
+
+typedef struct t_in6_ifstat {
+	uint32_t	ipv6IfStatsInReceives;
+	uint32_t	ipv6IfStatsInHdrErrors;
+/*	uint32_t	ipv6IfStatsInTooBigErrors;*/
+/*	uint32_t	ipv6IfStatsInNoRoutes;*/
+	uint32_t	ipv6IfStatsInAddrErrors;
+	uint32_t	ipv6IfStatsInUnknownProtos;
+	uint32_t	ipv6IfStatsInTruncatedPkts;
+/*	uint32_t	ipv6IfStatsInDiscards;*/
+/*	uint32_t	ipv6IfStatsInDelivers;*/
+/*	uint32_t	ipv6IfStatsOutForwDatagrams;*/
+	uint32_t	ipv6IfStatsOutRequests;
+	uint32_t	ipv6IfStatsOutDiscards;
+	uint32_t	ipv6IfStatsOutFragOKs;
+	uint32_t	ipv6IfStatsOutFragFails;
+	uint32_t	ipv6IfStatsOutFragCreates;
+	uint32_t	ipv6IfStatsReasmReqds;
+	uint32_t	ipv6IfStatsReasmOKs;
+	uint32_t	ipv6IfStatsReasmFails;
+	uint32_t	ipv6IfStatsInMcastPkts;
+	uint32_t	ipv6IfStatsOutMcastPkts;
+} T_IN6_IFSTAT;
+
+extern T_IN6_IFSTAT in6_ifstat;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+/*
+ *  変数
+ */
+
+extern uint8_t	ip6_defhlim;
+
+/*
+ *  関数
+ */
+
+extern ER ip6_output (T_NET_BUF *output, uint16_t flags, TMO tmout);
+extern void ip6_init (void);
+extern uint8_t *ip6_get_prev_hdr (T_NET_BUF *nbuf, uint_t off);
+extern uint_t get_ip6_hdr_size (T_NET_BUF *nbuf);
+extern ER_UINT ip6_nexthdr (T_NET_BUF *nbuf, uint_t off, uint_t proto, uint_t *nextp);
+extern ER_UINT ip6_lasthdr (T_NET_BUF *nbuf, uint_t off, uint_t proto, uint_t *nextp);
+extern ER_UINT ip6_unknown_opt (T_NET_BUF *input, uint8_t *opt);
+extern uint_t dest6_input  (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+extern uint_t route6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+extern uint_t frag6_input  (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+extern void frag6_timer (void);
+extern ER ip6_remove_exthdrs (T_NET_BUF *nbuf);
+
+#endif	/* of #ifndef _IP6_VAR_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ipsec.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ipsec.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/ipsec.cfg	(revision 398)
@@ -0,0 +1,42 @@
+
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *  Copyright (C) 2008-2009 by Hokkaido Industrial Research Institute, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  IPsec で使用するカーネルオブジェクト
+ */
+
+#ifdef SUPPORT_IPSEC
+
+#endif	/* of #ifdef SUPPORT_IPSEC */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6.c	(revision 398)
@@ -0,0 +1,700 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/nd6.c,v 1.20 2002/08/02 20:49:14 rwatson Exp $	*/
+/*	$KAME: nd6.c,v 1.144 2001/05/24 07:44:00 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * XXX
+ * KAME 970409 note:
+ * BSD/OS version heavily modifies this code, related to llinfo.
+ * Since we don't have BSD/OS version of net/route.c in our hand,
+ * I left the code mostly as it was in 970310.  -- itojun
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/ppp.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+
+#include <netinet6/nd6.h>
+
+#include <net/if_var.h>
+
+#ifdef _IP6_CFG
+
+/*
+ *  近隣キャッシュ
+ */
+
+static T_LLINFO_ND6 nd6_cache[NUM_ND6_CACHE_ENTRY];
+
+/*
+ *  nd6_free -- ルータを削除する。
+ */
+
+static void
+nd6_free (T_LLINFO_ND6	*ln)
+{
+	T_DEF_ROUTER	*dr;
+
+	dr = nd6_defrtrlist_lookup(&ln->addr);
+	if (dr != NULL) {
+		ln->state = ND6_LLINFO_INCOMPLETE;
+
+		/* プレフィックス・リストからルータを削除する。*/
+		nd6_defrtrlist_del(dr);
+		}
+	}
+
+/*
+ *  nd6_timer -- 近隣探索管理タイマー
+ */
+
+void
+nd6_timer (void)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_LLINFO_ND6	*ln;
+	SYSTIM		now;
+	int_t		ix;
+
+	/* 近隣キャッシュの処理 */
+	syscall(wai_sem(SEM_ND6_CACHE));
+	syscall(get_tim(&now));
+	for (ix = NUM_ND6_CACHE_ENTRY; ix -- > 0; ) {
+		ln = &nd6_cache[ix];
+		if (ln->state >= ND6_LLINFO_NO_STATE && (int32_t)(ln->expire - now) < 0) {
+		                                               /* ln->expire < now */
+
+			switch (ln->state) {
+
+			case ND6_LLINFO_INCOMPLETE:	/* 未解決		*/
+				if (ln->asked < ND6_MAX_MCAST_QUERY) {
+					/*
+					 *  マルチキャストアドレス要請の再送回数以下の場合の処理
+					 */
+					ln->asked ++;
+					ln->expire = now + ND6_RETRANS_TIME;	/* 近隣探索送信間隔 */
+					nd6_ns_output(ifp, &in6_addr_unspecified, &ln->addr, ln, false);
+					}
+				else  {
+					if (ln->hold != NULL) {
+						/*
+						 *  最終的には、保留されているネットワークバッファが
+						 *  あれば、ICMP6 ERROR を自分自身に返したあと、
+						 *  ネットワークバッファを開放する。
+						 *  しかし、現在、icmp6_error の実装が不完全のため、
+						 *  ネットワークバッファの開放のみ行う。
+						 */
+#if 0	/* 保留 */
+						icmp6_error(ln->hold, ICMP6_DST_UNREACH,
+						                      ICMP6_DST_UNREACH_ADDR, 0);
+#endif	/* #if 0 */
+						syscall(rel_net_buf(ln->hold));
+						ln->hold = NULL;
+						}
+					nd6_free(ln);
+					memset((void*)ln, 0, sizeof(*ln));
+					}
+				break;
+
+			case ND6_LLINFO_REACHABLE:	/* 到達可能		*/
+				if (ln->expire) {
+					ln->expire = now + ND6_GCOLLECTION_TIME;
+					ln->state = ND6_LLINFO_STALE;
+					}
+				break;
+
+			case ND6_LLINFO_STALE:		/* 到達可能性は未確認	*/
+				if (ln->expire) {
+					if (ln->hold != NULL) {
+						syscall(rel_net_buf(ln->hold));
+						ln->hold = NULL;
+						}
+					nd6_free(ln);
+					memset((void*)ln, 0, sizeof(*ln));
+					}
+				break;
+
+			case ND6_LLINFO_DELAY:		/* 到達可能性の確認待機	*/
+				ln->asked = 1;
+				ln->expire = now + ND6_RETRANS_TIME;		/* 近隣探索送信間隔 */
+				ln->state = ND6_LLINFO_PROBE;
+				nd6_ns_output(ifp, &ln->addr, &ln->addr, ln, false);
+				break;
+
+			case ND6_LLINFO_PROBE:		/* 到達可能性を確認中	*/
+				if (ln->asked < ND6_MAX_UCAST_QUERY) {
+					/*
+					 *  ユニキャストアドレス要請の再送回数以下の場合の処理
+					 */
+					ln->asked ++;
+					ln->expire += ND6_RETRANS_TIME;	/* 近隣探索送信間隔 */
+					nd6_ns_output(ifp, &ln->addr, &ln->addr, ln, false);
+					}
+				else {
+					if (ln->hold != NULL) {
+						syscall(rel_net_buf(ln->hold));
+						ln->hold = NULL;
+						}
+					nd6_free(ln);
+					memset((void*)ln, 0, sizeof(*ln));
+					}
+				break;
+
+				}
+			}
+		}
+	syscall(sig_sem(SEM_ND6_CACHE));
+
+	/* ディフォルトルータ・リストの処理 */
+	nd6_defrtrlist_timer();
+
+	/* プレフィックス・リストの処理 */
+	nd6_prelist_timer();
+
+	/* ネットワークインタフェースのアドレスの処理 */
+	in6_ifaddr_timer(ifp);
+
+	/*
+	 *  到達可能状態の有効時間の更新
+	 */
+	if ((int32_t)(nd6_recalc_reachtm_interval - now) < 0) {
+	           /* nd6_recalc_reachtm_interval < now */
+		nd6_recalc_reachtm_interval	= now + ND6_RECALC_REACHTM_INTERVAL;
+		nd6_reachable_time		= ND6_CALC_REACH_TIME(nd6_base_reachable_time);
+		}
+	timeout((callout_func)nd6_timer, NULL, ND6_TIMER_TMO);
+	}
+
+/*
+ *  nd6_get_cache -- 近隣キャッシュを獲得する。
+ */
+
+const T_LLINFO_ND6 *
+nd6_get_cache (void)
+{
+	return nd6_cache;
+	}
+
+/*
+ *  nd6_ifattach -- 近隣探索の初期設定を行う。
+ */
+
+void
+nd6_ifattach (T_IFNET *ifp)
+{
+	}
+
+/*
+ *  nd6_output_hold -- 近隣探索キャッシュに保留されている
+ *                     アドレス解決待ちのデータグラムがあれば送信する。
+ *
+ *    注意: セマフォ SEM_ND6_CACHE によりロック状態で呼出すこと。
+ */
+
+ER
+nd6_output_hold (T_IFNET *ifp, T_LLINFO_ND6 *ln)
+{
+	SYSTIM now;
+
+	/* アドレス解決待ちのデータグラムがあれば送信する。*/
+	if (ln->hold) {
+
+		/* タイムアウトの処理 */
+		if (ln->tmout != TMO_FEVR) {
+
+			/*
+			 *  タイムアウトの指定が永久でなく、時間を過ぎていれば、
+			 *  出力しないで終了する。
+			 */
+			syscall(get_tim(&now));
+			if ((int32_t)(ln->tmout - now) < 0) {
+			           /* ln->tmout < now */
+				syscall(rel_net_buf(ln->hold));
+				ln->hold = NULL;
+				return E_TMOUT;
+				}
+			}
+				
+		nd6_output(ifp, ln->hold, &ln->addr, ln, TMO_FEVR);
+		ln->hold = NULL;
+		}
+	return E_OK;
+	}
+
+/*
+ *  nd6_lookup -- 近隣探索キャッシュを探索する。
+ *
+ *    注意: セマフォ SEM_ND6_CACHE によりロック状態で呼出すこと。
+ *
+ */
+
+T_LLINFO_ND6 *
+nd6_lookup (const T_IN6_ADDR *addr, bool_t create)
+{
+	SYSTIM	min = 0xffffffff;
+	int_t	ix, fix = -1, mix = -1;
+
+	for (ix = NUM_ND6_CACHE_ENTRY; ix -- > 0; ) {
+		if (nd6_cache[ix].state == 0) {
+			/* 未使用エントリのインデックスを記録する。*/
+			if (fix == -1)
+				fix = ix;
+			}
+		else if (IN6_ARE_ADDR_EQUAL(addr, &nd6_cache[ix].addr)) {
+			return &nd6_cache[ix];
+			}
+		else if ((int32_t)(nd6_cache[ix].expire - min) < 0) {	/* nd6_cache[ix].expire < min */
+			/* 有効期限が最短エントリのインデックスを記録する。*/
+			min = nd6_cache[ix].expire;
+			mix = ix;
+			}
+		}
+
+	if (create) {
+		if (fix == -1)  {
+			if (nd6_cache[mix].hold != NULL) {
+				syscall(rel_net_buf(nd6_cache[mix].hold));
+				nd6_cache[mix].hold = NULL;
+				}
+			fix = mix;
+			}
+		syscall(get_tim(&nd6_cache[fix].expire));
+		nd6_cache[fix].addr   = *addr;
+		nd6_cache[fix].state  = ND6_LLINFO_NO_STATE;
+		return &nd6_cache[fix];
+		}
+	else
+		return NULL;
+	}
+
+/*
+ *  nd6_cache_lladdr -- 近隣探索キャッシュに登録する。
+ */
+
+T_LLINFO_ND6 *
+nd6_cache_lladdr (T_IFNET *ifp, const T_IN6_ADDR *from,
+                  T_IF_ADDR *lladdr, uint8_t type, uint8_t code)
+{
+	T_LLINFO_ND6	*ln;
+	SYSTIM		now;
+	bool_t		newentry, olladdr, llchange, doupdate;
+	int_t		newstate = ND6_LLINFO_INCOMPLETE;
+
+	/* アドレスが無指定なら何もしない。*/
+	if (IN6_IS_ADDR_UNSPECIFIED(from))
+		return NULL;
+
+	/* 近隣キャッシュに登録する。*/
+	syscall(wai_sem(SEM_ND6_CACHE));
+	if ((ln = nd6_lookup(from, false)) == NULL) {
+		ln = nd6_lookup(from, true);
+		newentry = true;
+		}
+	else
+		newentry = false;
+
+	olladdr = ln->state > ND6_LLINFO_INCOMPLETE;
+	if (!olladdr || lladdr == NULL)
+		llchange = false;
+	else if (memcmp(lladdr, &ln->ifaddr, sizeof(T_IF_ADDR)))
+		llchange = true;
+	else
+		llchange = false;
+
+	/*
+	 *  状態遷移表
+	 *
+	 *  nd_na_flags
+	 *  newnetry olladdr lladdr llchange 処理 (L: lladdr を登録する)
+	 *
+	 *      F       F       N       -    (1)
+	 *      F       T       N       -    (2)
+	 *      F       F       Y       -    (3) L * -> STALE
+	 *      F       T       Y       F    (4) L
+	 *      F       T       Y       T    (5) L * -> STALE
+	 *      T       -       N       -    (6)   * -> NO_STATE
+	 *      T       -       Y       -    (7) L * -> STALE
+	 */
+
+	/* データリンク層のアドレスが通知されていれば更新する。*/
+	if (lladdr != NULL) {
+		ln->ifaddr = *(T_IF_ADDR *)lladdr;
+		}
+
+	if (newentry) {
+		if (lladdr != NULL)					/* (7) */
+			newstate = ND6_LLINFO_STALE;
+		else							/* (6) */
+			newstate = ND6_LLINFO_NO_STATE;
+		doupdate = true;
+		}
+	else {
+		if ((!olladdr && lladdr != NULL) ||			/* (3) */
+		    ( olladdr && lladdr != NULL && llchange)) {		/* (5) */
+			newstate = ND6_LLINFO_STALE;
+			doupdate = true;
+			}
+		else							/* (1),(2),(4) */
+			doupdate = false;
+		}
+
+	/* 近隣キャッシュエントリを更新する。*/
+	if (doupdate) {
+		ln->state = newstate;
+
+		syscall(get_tim(&now));
+		if (ln->state == ND6_LLINFO_STALE) {
+			ln->expire = now + ND6_GCOLLECTION_TIME;
+
+			/* アドレス解決待ちのデータグラムがあれば送信する。*/
+			nd6_output_hold(ifp, ln);
+			}
+		else if (ln->state == ND6_LLINFO_INCOMPLETE)
+			ln->expire = now;
+		}
+	syscall(sig_sem(SEM_ND6_CACHE));
+
+
+	/* ルータ通知の処理 */
+	switch (type) {
+
+	case ND_NEIGHBOR_SOLICIT:
+		if (newentry)
+			ln->flags &= ~ND6_LLIF_ROUTER;
+		break;
+
+	case ND_REDIRECT:
+		if (code == ND_REDIRECT_ROUTER)
+			ln->flags |=  ND6_LLIF_ROUTER;
+		else if (newentry)
+			ln->flags &= ~ND6_LLIF_ROUTER;
+		break;
+
+	case ND_ROUTER_SOLICIT:
+		ln->flags &= ~ND6_LLIF_ROUTER;
+		break;
+
+	case ND_ROUTER_ADVERT:
+		if ((!newentry && (olladdr || lladdr != NULL)) ||
+		    ( newentry && lladdr))
+			ln->flags |=  ND6_LLIF_ROUTER;
+		break;
+		}
+
+	return ln;
+	}
+
+/*
+ *  nd6_is_addr_neighbor -- 指定されたアドレスのノードが同一リンクにあるかチェックする。
+ */
+
+bool_t
+nd6_is_addr_neighbor (T_IFNET *ifp, const T_IN6_ADDR *addr)
+{
+	if (IN6_IS_ADDR_LINKLOCAL(addr))
+		return true;
+
+	if (nd6_onlink_prefix_lookup(addr) != NULL)
+		return true;
+
+	if (nd6_lookup(addr, false) != NULL)
+		return true;
+
+	return false;
+	}
+
+/*
+ *  nd6_output -- 近隣探索の出力関数
+ *
+ *    注意: セマフォ SEM_ND6_CACHE によりロック状態で呼出すこと。
+ */
+
+ER
+nd6_output (T_IFNET *ifp, T_NET_BUF *output, const T_IN6_ADDR *dst, T_LLINFO_ND6 *ln, TMO tmout)
+{
+	ER	error = E_OK;
+	SYSTIM	now;
+
+	/*
+	 *  あて先アドレスがマルチキャストか、近隣キャッシュが
+	 *  不要の場合は直ちに送信する。
+	 */
+	if (!(IN6_IS_ADDR_MULTICAST(dst) || !IF_IN6_NEED_CACHE(ifp))) {
+		if (ln == NULL) {
+			/* 近隣キャッシュが未定義の場合 */
+			if (nd6_is_addr_neighbor(ifp, dst)) {
+				/*
+				 *  指定されたアドレスのノードが同一リンクにある時は、
+				 *  近隣キャッシュを探索し、未定義の場合は登録する。
+				 */
+				ln = nd6_lookup(dst, true);
+				}
+			else {
+				error = E_CLS;
+				goto err_ret;
+				}
+			}
+
+		/*
+		 *  近隣キャッシュの状態が、データリンク層のアドレスが分かっていても、
+		 *  到達可能性が確認されていないときは、到達不能通知を開始する。
+		 */
+		if (ln->state == ND6_LLINFO_STALE) {
+			syscall(get_tim(&now));
+			ln->expire = now + ND6_DELAY_TIME;
+			ln->asked = 0;
+			ln->state = ND6_LLINFO_DELAY;
+			}
+
+		/*
+		 *  近隣キャッシュの状態が、データリンク層のアドレス未解決の場合は
+		 *  近隣探索を行う。
+		 */
+		if (ln->state <= ND6_LLINFO_INCOMPLETE) {
+
+			/* タイムアウトの指定がポーリングならタイムアウトで終了する。*/
+			if (tmout == TMO_POL) {
+				error = E_TMOUT;
+				goto err_ret;
+				}
+
+			if (ln->state == ND6_LLINFO_NO_STATE)
+				ln->state = ND6_LLINFO_INCOMPLETE;
+
+			/* すでに、未解決のネットワークバッファがあれば、開放する。*/
+			if (ln->hold != NULL) {
+				syscall(rel_net_buf(ln->hold));
+				ln->hold = NULL;
+				}
+
+			/*
+			 *  送信をペンディングする。
+			 *  IF でネットワークバッファを開放しないフラグが設定されているときは、
+			 *  送信をペンディングしない。
+			 */
+			if ((output->flags & NB_FLG_NOREL_IFOUT) == 0) {
+				ln->hold = output;
+
+				/* タイムアウトの設定 */
+				if (tmout == TMO_FEVR)
+					ln->tmout = tmout;
+				else {
+					syscall(get_tim(&now));
+					ln->tmout = now + tmout;
+					}
+				}
+			else {
+				output->flags &= ~NB_FLG_NOREL_IFOUT;
+				syscall(get_tim(&now));
+				ln->tmout = now + tmout;
+				}
+
+			if (ln->expire) {
+				if (ln->asked < ND6_MAX_MCAST_QUERY) {
+					syscall(get_tim(&now));
+					if ((int32_t)(ln->expire - now) < 0) {
+					           /* ln->expire < now */
+						ln->expire += ND6_RETRANS_TIME;	/* 近隣探索送信間隔 */
+						ln->asked ++;
+						nd6_ns_output(ifp, &in6_addr_unspecified, dst, ln, false);
+						}
+					}
+				}
+			return error;
+			}
+		}
+
+	/*
+	 *  重複が検出されたインタフェースには出力しない。
+	 */
+	if ((ifp->flags & ND6_IFF_IFDISABLED) != 0) {
+		return E_OK;
+		}
+
+	IF_SET_PROTO(output, IF_PROTO_IPV6);
+	error = IF_OUTPUT(output, dst, ln ? & ln->ifaddr : NULL, tmout);
+	return error;
+
+err_ret:
+	syscall(rel_net_buf(output));
+	return error;
+	}
+
+/*
+ *  nd6_storelladdr -- 出力するネットワークインタフェースのアドレスを返す。
+ */
+
+ER
+nd6_storelladdr (T_IF_ADDR *out, const T_IN6_ADDR *dst, T_IF_ADDR *ifa)
+{
+	if (IN6_IS_ADDR_MULTICAST(dst)) {
+		IF_IN6_RESOLVE_MULTICAST(out, dst);
+		}
+	else {
+		*out = *ifa;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  nd6_option -- 近隣探索オプションの処理
+ *
+ *    注意: オプションオフセット配列には、オフセット + 8 が設定されている。
+ */
+
+ER
+nd6_options (uint8_t *opt, void *nh, uint_t len)
+{
+	T_ND_OPT_HDR	*opth;
+	ER		error = E_OK;
+	int_t		pi_count = 0;	/* プレフィックス情報の個数 */
+
+	opth = (T_ND_OPT_HDR *)nh;
+	memset(opt, 0, ND_OPT_OFF_ARRAY_SIZE);
+
+	while (error == E_OK && ((uint8_t *)opth - (uint8_t *)nh) < (256 - 8) && len > 0) {
+
+		/* オプション長が 0 の時は、不正なオプションとして処理する。*/
+		if (opth->len == 0) {
+			error = E_PAR;
+			break;
+			}
+
+		/* オプションのタイプにより分岐する。*/
+		switch (opth->type) {
+		case ND_OPT_SOURCE_LINKADDR:		/* 送信先ネットワークインタフェースのアドレス	*/
+		case ND_OPT_TARGET_LINKADDR:		/* 対象ネットワークインタフェースのアドレス	*/
+		case ND_OPT_REDIRECTED_HEADER:		/* リダイレクト・ヘッダ				*/
+		case ND_OPT_MTU:			/* MTU						*/
+			if (opt[ND_OPT_OFF_ARRAY_IX(opth->type)]) {
+				/* プレフィックス情報以外の同じオプションが複数指定されている。*/
+				error = E_PAR;
+				}
+			else {
+				opt[ND_OPT_OFF_ARRAY_IX(opth->type)] = (uint8_t *)opth - (uint8_t *)nh + 8;
+				}
+			break;
+		case ND_OPT_PREFIX_INFORMATION:		/* プレフィックス情報				*/
+			if (!opt[ND_OPT_OFF_ARRAY_IX(ND_OPT_PREFIX_INFORMATION)]) {
+				/*
+				 *  プレフィックス情報は最初に現れたオフセットのみ記録する。
+				 */
+				opt[ND_OPT_OFF_ARRAY_IX(opth->type)] = (uint8_t *)opth - (uint8_t *)nh + 8;
+				}
+			pi_count ++;
+			break;
+		default:
+			/*
+			 *  将来定義されるプロトコルへの拡張に対応するため、
+			 *  認識できないオプションは単に無視し、処理を続行する。
+			 */
+			break;
+			}
+		len -= opth->len << 3;		/* オプション長の単位は 8 バイト */
+		opth = (T_ND_OPT_HDR *)((uint8_t *)opth + (opth->len << 3));
+		}
+
+	opt[ND_OPT_OFF_ARRAY_IX(ND_OPT_PREFIX_INFO_COUNT)] = pi_count;
+	return error;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6.h	(revision 398)
@@ -0,0 +1,268 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/nd6.h,v 1.10 2002/04/19 04:46:23 suz Exp $	*/
+/*	$KAME: nd6.h,v 1.76 2001/12/18 02:10:31 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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 _ND6_H_
+#define _ND6_H_
+
+/*
+ *  ネットワークインタフェース構造体（T_IFNET）のフラグ
+ */
+
+#define ND6_IFF_IFDISABLED	UINT_C(0x01)	/* インタフェースを無効にする。*/
+
+/*
+ *  近隣キャッシュ 
+ */
+
+typedef struct t_llinfo_nd6 {
+	T_IN6_ADDR	addr;
+	T_NET_BUF	*hold;
+	TMO		tmout;
+	SYSTIM		expire;		/* [us] 有効時間が切れる時刻	*/
+	T_IF_ADDR	ifaddr;
+	uint8_t		state;
+	uint8_t		asked;
+	uint8_t		flags;
+	} T_LLINFO_ND6;
+
+/* 近隣キャッシュの状態 */
+
+#define ND6_LLINFO_FREE			0	/* 未使用		*/
+#define ND6_LLINFO_NO_STATE		1	/* 状態未定義		*/
+#define ND6_LLINFO_INCOMPLETE		2	/* 未解決		*/
+#define ND6_LLINFO_REACHABLE		3	/* 到達可能		*/
+#define ND6_LLINFO_STALE		4	/* 到達可能性は未確認	*/
+#define ND6_LLINFO_DELAY		5	/* 到達可能性の確認待機	*/
+#define ND6_LLINFO_PROBE		6	/* 到達可能性を確認中	*/
+
+#define ND6_IS_LLINFO_PROBREACH(n)	((n)->state > ND6_LLINFO_INCOMPLETE)
+
+/* 近隣キャッシュの制御ビット */
+
+#define ND6_LLIF_ROUTER			UINT_C(0x80)	/* ルータ		*/
+#define ND6_LLIF_ASKED			UINT_C(0x40)	/* 通知済み		*/
+#define ND6_LLIF_STATE_MASK		UINT_C(0x07)	/* 状態マスク		*/
+
+/* 近隣探索キャッシュ、有効時間の定義 */
+
+#define ND6_SLOW_TMO			((60*60*1000)/NET_TIMER_HZ)
+							/* 1 [時間]				*/
+							/* 近隣探索キャッシュ更新タイムアウト	*/
+
+#define ND6_MAX_DAD_TRY			15		/* 重複アドレス検出の再送回数		*/
+#define ND6_MAX_MCAST_QUERY		3		/* マルチキャストアドレス要請の再送回数	*/
+#define ND6_MAX_UCAST_QUERY		3		/* ユニキャストアドレス要請の再送回数	*/
+
+#define ND6_GCOLLECTION_TIME		(60*60*24*SYSTIM_HZ)
+							/* ゴミ拾い周期、1 日			*/
+#define	ND6_DELAY_TIME			(5*SYSTIM_HZ)	/* 確認待機遅延				*/
+#define ND6_FIRST_DAD_DELAY_TIME	(1*SYSTIM_HZ)	/* 最初の重複アドレス検出送信遅延	*/
+#define ND6_DAD_DELAY_TIME		(5*SYSTIM_HZ/10)
+							/* 重複アドレス検出送信遅延		*/
+
+/* 近隣探索用タイマの設定 */
+
+#define ND6_TIMER_TMO			((SYSTIM_HZ/NET_TIMER_CYCLE)/5)	/* 0.2[s] 間隔		*/
+
+/*
+ *  到達可能状態の有効時間
+ */
+
+#define	ND6_DEF_REACHABLE_TIME		(30*SYSTIM_HZ)	/* 到達可能状態の有効時間の既定値		*/
+#define	ND6_MAX_REACHABLE_TIME		(60*60*SYSTIM_HZ)
+							/* 到達可能状態の有効時間の既定値		*/
+#define	ND6_RECALC_REACHTM_INTERVAL	(60*60*2*SYSTIM_HZ)
+							/* 到達可能状態の有効時間再計算間隔	*/
+
+#define	ND6_MIN_REACHTM_RAND_FACTOR	512		/* 最小乱数補正値、1,024 * 0.5		*/
+
+#if 1							/* タイマーの起動間隔を考慮し、規定より短く設定	*/
+#define	ND6_MAX_REACHTM_RAND_FACTOR	1484		/* 最小乱数補正値、1,024 * 1.45			*/
+#else
+#define	ND6_MAX_REACHTM_RAND_FACTOR	1536		/* 最小乱数補正値、1,024 * 1.5			*/
+#endif
+
+/* 到達可能状態の有効時間の計算マクロ */
+
+#define ND6_CALC_REACH_TIME(b)		\
+	 ((ND6_MIN_REACHTM_RAND_FACTOR * ((uint32_t)(b) >> 10)) + \
+	  (net_rand() & ((ND6_MAX_REACHTM_RAND_FACTOR - ND6_MIN_REACHTM_RAND_FACTOR) * ((uint32_t)(b) >> 10))))
+
+/*
+ *  近隣探索の送信間隔
+ */
+
+#define ND6_DEF_RETRANS_TIME		(1*SYSTIM_HZ)
+
+/*
+ *  ルータ通知により変更されることがある値
+ */
+
+#if NUM_ND6_DEF_RTR_ENTRY > 0
+
+/* ルータ通知を受信する場合は、通知された値 */
+
+#define	ND6_REACHABLE_TIME		nd6_reachable_time
+#define ND6_RETRANS_TIME		nd6_retrans_time
+
+#else	/* #if NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+/* ルータ通知を受信しない場合の値は既定値 */
+
+#define	ND6_REACHABLE_TIME		ND6_DEF_REACHABLE_TIME
+#define ND6_RETRANS_TIME		ND6_DEF_RETRANS_TIME
+
+#endif	/* #if NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+/*
+ *  ディフォルトルータ・リスト
+ */
+
+typedef struct t_def_router {
+	T_IN6_ADDR	addr;
+	SYSTIM		expire;		/* [us] 有効時間が切れる時刻	*/
+	uint32_t	lifetime;	/* [us] 有効時間			*/
+	uint16_t	plistmap;	/* プレフィックスマップ		*/
+	uint8_t		flags;		/* ルータ通知のフラグ		*/
+	uint8_t		state;
+	} T_DEF_ROUTER;
+
+/* ディフォルトルータ・リストの状態 */
+
+#define ND6_DEF_RTR_BUSY		0xff	/* 使用中		*/
+
+/* プレフィックスのインデックス */
+
+#define ND6_PREFIX_IX_INVALID		0xff
+
+/*
+ *  プレフィックス・リスト
+ */
+
+typedef struct t_nd6_prefix {
+	T_IN6_ADDR	prefix;		/* プレフィックス		*/
+	uint32_t	expire;		/* [s] 有効時間が切れる時刻	*/
+	uint32_t	preferred;	/* [s] 推奨有効時間が切れる時刻	*/
+	uint32_t	vltime;		/* [s] 有効時間			*/
+	uint32_t	pltime;		/* [s] 推奨有効時間		*/
+	uint16_t	routermap;	/* ルータマップ			*/
+	uint8_t		flags;		/* フラグ			*/
+	uint8_t		prefix_len;	/* プレフィックス長		*/
+	} T_ND6_PREFIX;
+
+/* フラグ */
+
+#define ND6_PREFIX_FLAG_ONLINK		UINT_C(0x80)	/* オンリンクプレフィックス	*/
+#define ND6_PREFIX_FLAG_AUTO		UINT_C(0x40)	/* ステートレス・アドレス自動設定*/
+
+#define ND6_PREFIX_STATE_BUSY		UINT_C(0x01)	/* 使用中		*/
+#define ND6_PREFIX_STATE_ONLINK		UINT_C(0x02)	/* オンリンク状態	*/
+#define ND6_PREFIX_STATE_DETACHED	UINT_C(0x04)	/* 非使用状態	*/
+
+/*
+ *  変数
+ */
+
+extern SYSTIM	nd6_base_reachable_time;
+extern SYSTIM	nd6_reachable_time;
+extern SYSTIM	nd6_recalc_reachtm_interval;
+extern SYSTIM	nd6_retrans_time;
+
+/*
+ *  関数
+ */
+
+extern void nd6_ifattach (T_IFNET *ifp);
+extern void nd6_ns_output (T_IFNET *ifp, const T_IN6_ADDR *daddr,
+                           const T_IN6_ADDR *taddr, T_LLINFO_ND6 *ln, bool_t dad);
+extern void nd6_na_output (T_IFNET *ifp, const T_IN6_ADDR *daddr,
+                           const T_IN6_ADDR *taddr, uint32_t flags, bool_t tlladdr);
+extern void nd6_dad_start (T_IFNET *ifp, T_IN6_IFADDR *ia, int_t *tick);
+extern ER nd6_output (T_IFNET *ifp, T_NET_BUF *output,
+                      const T_IN6_ADDR *dst, T_LLINFO_ND6 *ln, TMO tmout);
+extern void nd6_na_input (T_NET_BUF *input, uint_t off);
+extern void nd6_ns_input (T_NET_BUF *input, uint_t off);
+extern void nd6_ra_input (T_NET_BUF *input, uint_t off);
+extern ER nd6_storelladdr (T_IF_ADDR *out, const T_IN6_ADDR *dst, T_IF_ADDR *ifa);
+extern ER nd6_options (uint8_t *opt, void *nh, uint_t len);
+extern T_LLINFO_ND6 *nd6_lookup (const T_IN6_ADDR *addr, bool_t create);
+extern ER nd6_output_hold (T_IFNET *ifp, T_LLINFO_ND6 *ln);
+extern T_LLINFO_ND6 *nd6_cache_lladdr (T_IFNET *ifp, const T_IN6_ADDR *from, 
+                                       T_IF_ADDR *lladdr, uint8_t type, uint8_t code);
+extern void nd6_defrtrlist_timer (void);
+extern void nd6_prelist_timer (void);
+extern void nd6_rtrsol_ctl (void);
+extern const T_IN6_ADDR *nd6_router_lookup (void);
+extern T_DEF_ROUTER *nd6_defrtrlist_lookup (const T_IN6_ADDR *src);
+extern void nd6_defrtrlist_del (T_DEF_ROUTER *dr);
+extern void nd6_timer (void);
+extern const T_DEF_ROUTER *nd6_get_drl (uint_t *count);
+extern const T_ND6_PREFIX *nd6_get_prl (void);
+extern const T_LLINFO_ND6 *nd6_get_cache (void);
+extern ER nd6_prefix_onlink (T_ND6_PREFIX *pr);
+extern ER nd6_prefix_offlink (T_ND6_PREFIX *pr);
+extern T_ND6_PREFIX *nd6_onlink_prefix_lookup (const T_IN6_ADDR *dst);
+
+#endif	/* of #ifndef _ND6_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6_nbr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6_nbr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6_nbr.c	(revision 398)
@@ -0,0 +1,851 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/nd6_nbr.c,v 1.13 2002/10/16 01:54:45 sam Exp $	*/
+/*	$KAME: nd6_nbr.c,v 1.86 2002/01/21 02:33:04 jinmei Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+
+#include <netinet6/nd6.h>
+
+#include <net/if6_var.h>
+
+#ifdef _IP6_CFG
+
+/*
+ *  局所関数
+ */
+
+static void nd6_dad_timer (T_IN6_IFADDR *ifa);
+static void nd6_dad_duplicated (T_IFNET *ifp, T_IN6_IFADDR *ifa);
+static void nd6_dad_ns_output (T_IFNET *ifp, T_IN6_IFADDR *ifa);
+static void nd6_dad_ns_input (T_IFNET *ifp, T_IN6_IFADDR *ifa);
+static void nd6_dad_na_input (T_IFNET *ifp, T_IN6_IFADDR *ifa);
+
+/*
+ *  nd6_dad_duplicated -- 重複アドレスを検出した時の処理
+ */
+
+static void
+nd6_dad_duplicated (T_IFNET *ifp, T_IN6_IFADDR *ifa)
+{
+	if ((ifa->flags & IN6_IFF_TENTATIVE) == 0)
+		syslog(LOG_ERROR, "[ND6 DAD DUP] no pending.");
+	else {
+		syslog(LOG_ERROR, "[ND6 DAD DUP] dup IPv6 addr: %s.", ipv62str(NULL, &ifa->addr));
+		ifa->flags &= ~IN6_IFF_TENTATIVE;
+		ifa->flags |=  IN6_IFF_DUPLICATED;
+
+		/* タイマーを停止する。*/
+		untimeout((callout_func)nd6_dad_timer, ifa);
+
+		/*
+		 *  もし IPv6 アドレスが、ユニークに割り当てらた
+		 * （イーサネット用の EUI-64）ハードウェアアドレスをベースとした
+		 *  インタフェース ID で生成されたのであれば、
+		 *  このインタフェースでの IPv6 の動作は無効にすべきである
+		 * （RFC2462bis-03 セクション 5.4.5）。
+		 */
+		if (IN6_IS_ADDR_LINKLOCAL(&ifa->addr))
+			ifp->flags |= ND6_IFF_IFDISABLED;
+		}
+	}
+
+/*
+ *  nd6_dad_ns_output -- 重複アドレス検出 (DAD) 要請を出力する。
+ */
+
+static void
+nd6_dad_ns_output (T_IFNET *ifp, T_IN6_IFADDR *ifa)
+{
+	NET_COUNT_ICMP6(net_count_nd6[NC_ND6_DAD_OUT_PACKETS], 1);
+
+	ifa->ns_ocount ++;
+	nd6_ns_output(ifp, &in6_addr_unspecified, &ifa->addr, NULL, true);
+	}
+
+/*
+ *  nd6_dad_ns_input -- 重複アドレス検出 (DAD) 要請入力
+ */
+
+static void
+nd6_dad_ns_input (T_IFNET *ifp, T_IN6_IFADDR *ifa)
+{
+	NET_COUNT_ICMP6(net_count_nd6[NC_ND6_NS_IN_PACKETS], 1);
+
+	/*
+	 *  まだ、重複アドレス検出要請を出力していない場合
+	 */
+	if (ifa->ns_ocount == 0)
+		nd6_dad_duplicated(ifp, ifa);
+	else
+		ifa->ns_icount ++;
+	}
+
+/*
+ *  nd6_dad_na_input -- 重複アドレス検出 (DAD) 通知入力
+ */
+
+static void
+nd6_dad_na_input (T_IFNET *ifp, T_IN6_IFADDR *ifa)
+{
+	NET_COUNT_ICMP6(net_count_nd6[NC_ND6_NA_IN_PACKETS], 1);
+	ifa->na_icount ++;
+	nd6_dad_duplicated(ifp, ifa);
+	}
+
+/*
+ *  nd6_dad_timer -- 重複アドレス検出 (DAD) タイマー
+ */
+
+static void
+nd6_dad_timer (T_IN6_IFADDR *ifa)
+{
+	T_IFNET *ifp = IF_GET_IFNET();
+
+	if (ifa->flags & IN6_IFF_DUPLICATED) {
+		syslog(LOG_ERROR, "[ND6 DAD] dup IPv6 addr: %s.", ipv62str(NULL, &ifa->addr));
+		return;
+		}
+
+	if ((ifa->flags & IN6_IFF_TENTATIVE) == 0) {
+		syslog(LOG_ERROR, "[ND6 DAD] no tentative IPv6 addr: %s.", ipv62str(NULL, &ifa->addr));
+		return;
+		}
+
+	if (ifa->ns_ocount < NUM_IP6_DAD_COUNT) {
+		nd6_dad_ns_output(ifp, ifa);
+
+		/* タイムアウトを近隣探索の送信間隔に設定する。*/
+		timeout((callout_func)nd6_dad_timer, ifa, ND6_RETRANS_TIME * NET_TIMER_HZ / SYSTIM_HZ);
+		}
+	else if (ifa->na_icount || ifa->ns_icount)
+		nd6_dad_duplicated(ifp, ifa);
+	else {
+		ifa->flags &= ~IN6_IFF_TENTATIVE;
+		syslog(LOG_NOTICE, "[ND6 DAD] no dup IPv6 addr: %s.", ipv62str(NULL, &ifa->addr));
+		}
+	}
+
+/*
+ *  nd6_ns_input -- 近隣要請の入力処理。
+ */
+
+void
+nd6_ns_input (T_NET_BUF *input, uint_t off)
+{
+	T_IFNET			*ifp = IF_GET_IFNET();
+	T_IP6_HDR		*ip6h;
+	T_NEIGHBOR_SOLICIT_HDR	*nsh;
+	T_ND_OPT_HDR		*opth;
+	T_IN6_IFADDR		*ifa;
+	bool_t			tlladdr;
+	uint_t			lladdr_len = 0;
+	uint32_t		flags;
+	uint8_t			*lladdr = NULL;
+	uint8_t			nd_opt_off[ND_OPT_OFF_ARRAY_SIZE];
+
+	NET_COUNT_ICMP6(net_count_nd6[NC_ND6_NS_IN_PACKETS], 1);
+
+	ip6h = GET_IP6_HDR(input);
+
+	/*
+	 *  ヘッダのチェック、以下の場合は破棄する。
+	 *    ・ホップリミットが IPV6_MAXHLIM (255) 以外
+	 *    ・ヘッダ長が短い
+	 */
+	if (ip6h->hlim != IPV6_MAXHLIM || input->len - off < NEIGHBOR_SOLICIT_HDR_SIZE)
+		goto err_ret;
+
+	nsh  = (T_NEIGHBOR_SOLICIT_HDR *)(input->buf + off);
+
+	if (IN6_IS_ADDR_UNSPECIFIED(&ip6h->src)) {
+		/*
+		 *  始点アドレスが無指定なら、重複アドレス検出
+		 *  あて先アドレスは、要請マルチキャストでなければならない。
+		 */
+		if (!IN6_IS_ADDR_NS_MULTICAST(&ip6h->dst))
+			goto err_ret;
+		}
+
+	/* 目的アドレスがマルチキャストならエラー */
+	if (IN6_IS_ADDR_MULTICAST(&nsh->target))
+		goto err_ret;
+
+	/* 近隣探索オプションのオフセットを記録する。*/
+	if (nd6_options(nd_opt_off, input->buf + (off + NEIGHBOR_SOLICIT_HDR_SIZE),
+	                            input->len - (off + NEIGHBOR_SOLICIT_HDR_SIZE)) != E_OK)
+		goto err_ret;
+
+	/* 近隣探索オプション (始点リンクアドレス) */
+	if (nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_SOURCE_LINKADDR)]) {
+		opth = (T_ND_OPT_HDR *)((uint8_t *)(input->buf + off + NEIGHBOR_SOLICIT_HDR_SIZE) +
+		                        nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_SOURCE_LINKADDR)] - 8);
+	 	/* 注意: オプションオフセット配列には、オフセット + 8 が設定されている。*/
+		lladdr     = (uint8_t *)(opth + 1);
+		lladdr_len = (opth->len << 3);
+		}
+
+	if (IN6_IS_ADDR_UNSPECIFIED(&ip6h->src) && lladdr != NULL)
+		goto err_ret;
+
+	/* 宛先アドレスがマルチキャストなら近隣通知にデータリンク層のアドレスを付ける。*/
+	if (IN6_IS_ADDR_MULTICAST(&ip6h->dst))
+		tlladdr = true;
+	else
+		tlladdr = false;
+
+	/*
+	 *  目的アドレスが、自分のネットワークインタフェースに
+	 *  割り当てられているアドレスか調べる。
+	 *  なお、代理サービスは実装していない。
+	 */
+	ifa = in6_lookup_ifaddr(ifp, &nsh->target);
+
+	if (ifa == NULL)
+		goto free_ret;
+
+	/* 探索結果アドレスが重複していれば応答しないで終了する。*/
+	if (ifa->flags & IN6_IFF_DUPLICATED)
+		goto err_ret;
+
+	/*
+	 *  ネットワークインタフェースのアドレス長が一致しなければエラー
+	 */
+	if (lladdr && lladdr_len != ((sizeof(T_IF_ADDR) + sizeof(T_ND_OPT_HDR) + 7) & ~7))
+		goto err_ret;
+
+	/*
+	 *  始点アドレスが自分のアドレスと一致すれば重複している。
+	 */
+	if (IN6_ARE_ADDR_EQUAL(&ifa->addr, &ip6h->src))
+		goto free_ret;
+
+	/* 重複検出中に、近隣要請を受信したときの処理 */
+	if (ifa->flags & IN6_IFF_TENTATIVE) {
+		if (IN6_IS_ADDR_UNSPECIFIED(&ip6h->src))
+			nd6_dad_ns_input(ifp, ifa);
+		goto free_ret;
+		}
+
+	if ((ifa->flags & IN6_IFF_ANYCAST) || !tlladdr)
+		flags = 0;
+	else
+		flags = ND_NA_FLG_OVERRIDE;
+
+	/*
+	 *  始点アドレスが無指定なら、送信相手は重複アドレス検出中で、
+	 *  直接送信することはできないので、全ノードマルチキャスト
+	 *  アドレスに送信する。
+	 */
+	if (IN6_IS_ADDR_UNSPECIFIED(&ip6h->src)) {
+		nd6_na_output(ifp, &in6_addr_linklocal_allnodes, &nsh->target, flags, tlladdr);
+		goto free_ret;
+		}
+
+	/* 近隣キャッシュに登録する。*/
+	nd6_cache_lladdr(ifp, &ip6h->src, (T_IF_ADDR *)lladdr, ND_NEIGHBOR_SOLICIT, 0);
+
+	nd6_na_output(ifp, &ip6h->src, &nsh->target, flags | ND_NA_FLG_SOLICITED, tlladdr);
+
+free_ret:
+	syscall(rel_net_buf(input));
+	return;
+
+err_ret:
+	NET_COUNT_ICMP6(net_count_nd6[NC_ICMP6_IN_ERR_PACKETS], 1);
+	syscall(rel_net_buf(input));
+	}
+
+/*
+ *  nd6_ns_output -- 近隣要請を出力する。
+ */
+
+void
+nd6_ns_output (T_IFNET *ifp, const T_IN6_ADDR *daddr,
+               const T_IN6_ADDR *taddr, T_LLINFO_ND6 *ln, bool_t dad)
+{
+	T_NEIGHBOR_SOLICIT_HDR	*nsh;
+	T_NET_BUF		*output;
+	T_IP6_HDR		*ip6h;
+	T_IF_ADDR		*mac = NULL;
+	uint_t			len;
+	uint16_t		ipflags = 0;
+
+	NET_COUNT_ICMP6(net_count_nd6[NC_ND6_NS_OUT_PACKETS], 1);
+
+	if (IN6_IS_ADDR_MULTICAST(taddr))
+		return;
+
+	/* 近隣要請ペイロード長を計算する。*/
+	if (!dad && IF_SOFTC_TO_IFADDR(ifp->ic))
+		len = (NEIGHBOR_SOLICIT_HDR_SIZE + ND_OPT_HDR_SIZE + sizeof(T_IF_ADDR) + 7) >> 3 << 3;
+	else
+		len = (NEIGHBOR_SOLICIT_HDR_SIZE + 7) >> 3 << 3;
+
+	/*
+	 *  要請マルチキャスト・アドレス宛の近隣探索では、
+	 *  他のリンクからの偽造されたデータグラムを
+	 *  排除するため、ホップリミットに IPV6_MAXHLIM (255) を設定する。
+	 */
+	if (IN6_IS_ADDR_UNSPECIFIED(daddr) || IN6_IS_ADDR_MULTICAST(daddr))
+		ipflags = IPV6_OUT_SET_HOP_LIMIT(IPV6_OUT_FLG_HOP_LIMIT, IPV6_MAXHLIM);
+
+	/* ネットワークバッファを獲得し、IPv6 ヘッダを設定する。*/
+	if (in6_get_datagram(&output, len, 0, daddr, NULL,
+	                     IPPROTO_ICMPV6, IPV6_MAXHLIM,
+	                     NBA_SEARCH_ASCENT, TMO_ND6_NS_OUTPUT) != E_OK)
+		return;
+
+	ip6h = GET_IP6_HDR(output);
+
+	if (IN6_IS_ADDR_UNSPECIFIED(daddr)) {
+
+		/* 宛先アドレスが無指定の場合は、要請マルチキャストアドレスを設定する。*/
+		ip6h->dst.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
+		ip6h->dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
+		ip6h->dst.s6_addr32[3] = taddr->s6_addr32[3];
+		ip6h->dst.s6_addr8[12] = 0xff;
+		}
+
+	/* 送信元アドレスの設定 */
+	if (!dad) {
+
+		/* 重複アドレス検出ではない時の送信元アドレス決定処理。*/
+		T_IN6_ADDR *saddr;
+
+		if (ln && ln->hold) {
+			/*
+			 * 送信がペンディングされているデータグラムの
+			 * 送信元アドレスを利用する。
+			 */
+			if (ln->hold->len > IF_IP6_HDR_SIZE)
+				saddr = &GET_IP6_HDR(ln->hold)->src;
+			else
+				saddr = NULL;
+			}
+		else
+			saddr = NULL;
+
+		if (saddr && in6_lookup_ifaddr(ifp, saddr))
+			memcpy(&ip6h->src, saddr, sizeof(T_IN6_ADDR));
+		else {
+			/*
+			 *  宛先アドレスにふさわしい送信元アドレスを、
+			 *  ネットワークインタフェースから探索して利用する。
+			 */
+			T_IN6_IFADDR *ifa;
+
+			if ((ifa = in6_ifawithifp(ifp, &ip6h->dst)) == NULL) {
+				syscall(rel_net_buf(output));
+				return;
+				}
+			memcpy(&ip6h->src, &ifa->addr, sizeof(T_IN6_ADDR));
+			}
+		}
+	else {
+
+		/* 重複アドレス検出時の送信元アドレスは無指定。*/
+		memset(&ip6h->src, 0, sizeof(T_IN6_ADDR));
+		}
+
+ 	/* 近隣要請ヘッダを設定する。*/
+ 	nsh = GET_NEIGHBOR_SOLICIT_HDR(output, IF_IP6_NEIGHBOR_SOLICIT_HDR_OFFSET);
+ 	nsh->hdr.type        = ND_NEIGHBOR_SOLICIT;
+ 	nsh->hdr.code        = 0;
+ 	nsh->hdr.data.data32 = 0;
+	memcpy(&nsh->target, taddr, sizeof(T_IN6_ADDR));
+
+	if (!dad && (mac = IF_SOFTC_TO_IFADDR(ifp->ic)) != NULL) {
+
+		/* 近隣探索オプションとして、探索目標の MAC アドレスを設定する。*/
+		T_ND_OPT_HDR	*opth;
+		uint_t		optlen;
+
+		opth   = (T_ND_OPT_HDR *)GET_NEIGHBOR_SOLICIT_SDU(output, IF_IP6_NEIGHBOR_SOLICIT_HDR_OFFSET);
+		optlen = (ND_OPT_HDR_SIZE + sizeof(T_IF_ADDR) + 7) >> 3 << 3;
+		memset(opth, 0, optlen);
+		opth->type = ND_OPT_SOURCE_LINKADDR;
+		opth->len  = optlen >> 3;
+		memcpy((uint8_t *)opth + sizeof(T_ND_OPT_HDR), mac, sizeof(T_IF_ADDR));
+		}
+
+	/* チェックサムを計算する。*/
+	nsh->hdr.sum = 0;
+	nsh->hdr.sum = in6_cksum(output, IPPROTO_ICMPV6, (uint8_t*)nsh - output->buf, len);
+
+	/* 送信する。*/
+	NET_COUNT_ICMP6(net_count_nd6[NC_ICMP6_OUT_OCTETS],
+	               output->len - GET_IF_IP6_HDR_SIZE(output));
+	NET_COUNT_ICMP6(net_count_nd6[NC_ICMP6_OUT_PACKETS], 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutMsgs, 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutNeighborSolicits, 1);
+	ip6_output(output, ipflags | IPV6_OUT_FLG_DAD, TMO_ND6_NS_OUTPUT);
+	}
+
+/*
+ *  nd6_na_input -- 近隣通知の入力処理。
+ */
+
+void
+nd6_na_input (T_NET_BUF *input, uint_t off)
+{
+	T_IFNET			*ifp = IF_GET_IFNET();
+	T_IP6_HDR		*ip6h;
+	T_NEIGHBOR_ADVERT_HDR	*nah;
+	T_ND_OPT_HDR		*opth;
+	T_IN6_IFADDR		*ifa;
+	T_LLINFO_ND6		*ln;
+	SYSTIM			now;
+	bool_t			llchange;
+	uint_t			lladdr_len = 0;
+	uint8_t			*lladdr = NULL;
+	uint8_t			nd_opt_off[ND_OPT_OFF_ARRAY_SIZE];
+
+	NET_COUNT_ICMP6(net_count_nd6[NC_ND6_NS_IN_PACKETS], 1);
+
+	ip6h = GET_IP6_HDR(input);
+
+	/*
+	 *  ヘッダのチェック、以下の場合は破棄する。
+	 *    ・ホップリミットが IPV6_MAXHLIM (255) 以外
+	 *    ・ヘッダ長が短い
+	 */
+	if (ip6h->hlim != IPV6_MAXHLIM || input->len - off < NEIGHBOR_ADVERT_HDR_SIZE)
+		goto err_ret;
+
+	nah  = (T_NEIGHBOR_ADVERT_HDR *)(input->buf + off);
+
+	/* 目的アドレスがマルチキャストならエラー */
+	if (IN6_IS_ADDR_MULTICAST(&nah->target))
+		goto err_ret;
+
+	/* 近隣要請への応答で、宛先アドレスがマルチキャストならエラー */
+	if ((nah->nd_na_flags_reserved & ND_NA_FLG_SOLICITED) &&
+	    IN6_IS_ADDR_MULTICAST(&ip6h->dst))
+		goto err_ret;
+
+	/* 近隣探索オプションのオフセットを記録する。*/
+	if (nd6_options(nd_opt_off, input->buf + (off + NEIGHBOR_ADVERT_HDR_SIZE), 
+	                            input->len - (off + NEIGHBOR_ADVERT_HDR_SIZE)) != E_OK)
+		goto err_ret;
+
+	/* 近隣探索オプション (目的リンクアドレス) */
+	if (nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_TARGET_LINKADDR)]) {
+		opth = (T_ND_OPT_HDR *)((uint8_t *)(input->buf + off + NEIGHBOR_ADVERT_HDR_SIZE) +
+		                        nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_TARGET_LINKADDR)] - 8);
+	 	/* 注意: オプションオフセット配列には、オフセット + 8 が設定されている。*/
+		lladdr     = (uint8_t *)(opth + 1);
+		lladdr_len = (opth->len << 3);
+		}
+
+	ifa = in6_lookup_ifaddr(ifp, &nah->target);
+
+	/*
+	 *  目的アドレスが自分のネットワークインタフェースに割り当てられているアドレスの
+	 *  いずれかに一致したときは、重複していることを意味している。
+	 */
+	if (ifa) {
+		if (ifa->flags & IN6_IFF_TENTATIVE)
+			nd6_dad_na_input(ifp, ifa);
+		else
+			syslog(LOG_ERROR, "[ND6 NA INPUT] dup IPv6 addr: %s.", ipv62str(NULL, &ifa->addr));
+		goto err_ret;
+		}
+
+	/*
+	 *  ネットワークインタフェースのアドレス長が一致しなければエラー
+	 */
+	if (lladdr && lladdr_len != ((sizeof(T_IF_ADDR) + sizeof(T_ND_OPT_HDR) + 7) & ~7))
+		goto err_ret;
+
+	/* 近隣キャッシュを探索する。*/
+	syscall(wai_sem(SEM_ND6_CACHE));
+	if ((ln = nd6_lookup(&nah->target, false)) == NULL)
+		goto free_ret;
+
+	/* 近隣キャッシュの状態が、データリンク層のアドレス未解決の場合 */
+	if (ln->state == ND6_LLINFO_INCOMPLETE) {
+		/* 通知されたデータリンク層のアドレスの長さが 0 の場合 */
+		if (lladdr == NULL)
+			goto free_ret;
+
+		ln->ifaddr = *(T_IF_ADDR *)lladdr;
+		if (nah->nd_na_flags_reserved & ND_NA_FLG_SOLICITED) {
+			ln->state = ND6_LLINFO_REACHABLE;
+			/*ln->byhint = 0*/;
+			if (ln->expire) {
+				syscall(get_tim(&now));
+				ln->expire = now + ND6_REACHABLE_TIME;
+				}
+			}
+		else {
+			syscall(get_tim(&now));
+			ln->expire = now + ND6_GCOLLECTION_TIME;
+			ln->state  = ND6_LLINFO_STALE;
+			}
+
+		if ((nah->nd_na_flags_reserved & ND_NA_FLG_ROUTER) != 0)
+			ln->flags |=  ND6_LLIF_ROUTER;
+		else
+			ln->flags &= ~ND6_LLIF_ROUTER;
+		if ((ln->flags & ND6_LLIF_ROUTER) != 0)
+			/*pfxlist_onlink_check()*/;
+		}
+	else {
+		if (lladdr == NULL)
+			llchange = false;
+		else if (memcmp(lladdr, &ln->ifaddr, sizeof(T_IF_ADDR)))
+			llchange = true;
+		else
+			llchange = false;
+
+		/*
+		 *  状態遷移表
+		 *
+		 *  nd_na_flags_reserved
+		 *  OVERRIDE    SOLICTED lladdr llchange 処理 (L: lladdr を登録する)
+		 *
+		 *      F           F       N      -    (2c)
+		 *      F           F       Y      F    (2b) L
+		 *      F           F       Y      T    (1)    REACHABLE -> STALE
+		 *      F           T       N      -    (2c)           * -> REACHABLE
+		 *      F           T       Y      F    (2b) L         * -> REACHABLE
+		 *      F           T       Y      T    (1)    REACHABLE -> STALE
+		 *      T           F       N      -    (2a)
+		 *      T           F       Y      F    (2a) L
+		 *      T           F       Y      T    (2a) L         *-> STALE
+		 *      T           T       N      -    (2a)           * -> REACHABLE
+		 *      T           T       Y      F    (2a) L         * -> REACHABLE
+		 *      T           T       Y      T    (2a) L         * -> REACHABLE
+		 */
+		if ((nah->nd_na_flags_reserved & ND_NA_FLG_OVERRIDE) == 0 && (lladdr != NULL && llchange)) {	/* (1) */
+			/* 状態が REACHABLE なら STALE に遷移する。*/
+			if (ln->state == ND6_LLINFO_REACHABLE) {
+				syscall(get_tim(&now));
+				ln->expire = now + ND6_GCOLLECTION_TIME;
+				ln->state  = ND6_LLINFO_STALE;
+				}
+			goto free_ret;
+			}
+		else if ((nah->nd_na_flags_reserved & ND_NA_FLG_OVERRIDE) ||						/* (2a) */
+		         ((nah->nd_na_flags_reserved & ND_NA_FLG_OVERRIDE) == 0 && (lladdr != NULL && !llchange)) ||	/* (2b) */
+		         lladdr == NULL) {										/* (2c) */
+
+			/* データリンク層のアドレスが通知されていれば更新する。*/
+			if (lladdr != NULL)
+				ln->ifaddr = *(T_IF_ADDR *)lladdr;
+
+			/* 近隣要請への応答なら REACHABLE に遷移する。*/
+			if (nah->nd_na_flags_reserved & ND_NA_FLG_SOLICITED) {
+				ln->state = ND6_LLINFO_REACHABLE;
+				/*ln->byhint = 0*/;
+				if (ln->expire) {
+					syscall(get_tim(&now));
+					ln->expire = now + ND6_REACHABLE_TIME;
+					}
+				}
+			/*
+			 *  データリンク層のアドレスが通知され、
+			 *  異なるアドレスなら更新する。
+			 */
+			else if (lladdr != NULL && llchange) {
+				syscall(get_tim(&now));
+				ln->expire = now + ND6_GCOLLECTION_TIME;
+				ln->state  = ND6_LLINFO_STALE;
+				}
+			}
+
+		/* ルータ通知フラグの処理 */
+		if ((ln->flags        & ND6_LLIF_ROUTER ) != 0 &&
+		    (nah->nd_na_flags_reserved & ND_NA_FLG_ROUTER) == 0) {
+			/*
+			 *  送信相手がルータ通知フラグを無効にした場合。
+			 *  ディフォルト・ルータリストから対象のルータを削除し、
+			 *  近隣探索キャッシュを更新する。
+			 */
+			T_DEF_ROUTER	*dr = NULL;
+
+			syscall(wai_sem(SEM_ND6_DEFRTRLIST));
+			if ((dr = nd6_defrtrlist_lookup(&ln->addr)) != NULL) {
+				nd6_defrtrlist_del(dr);
+				}
+			syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+			}
+		if ((nah->nd_na_flags_reserved & ND_NA_FLG_ROUTER) != 0)
+			ln->flags |=  ND6_LLIF_ROUTER;
+		else
+			ln->flags &= ~ND6_LLIF_ROUTER;
+		}
+
+	ln->asked = 0;
+
+	/* アドレス解決待ちのデータグラムがあれば送信する。*/
+	nd6_output_hold(ifp, ln);
+
+free_ret:
+	syscall(sig_sem(SEM_ND6_CACHE));
+	syscall(rel_net_buf(input));
+	return;
+
+err_ret:
+	NET_COUNT_ICMP6(net_count_nd6[NC_ICMP6_IN_ERR_PACKETS], 1);
+	syscall(rel_net_buf(input));
+	}
+
+/*
+ *  nd6_na_output -- 近隣通知を出力する。
+ */
+
+void
+nd6_na_output (T_IFNET *ifp, const T_IN6_ADDR *daddr,
+               const T_IN6_ADDR *taddr, uint32_t flags, bool_t tlladdr)
+{
+	T_NEIGHBOR_ADVERT_HDR	*nah;
+	T_NET_BUF		*output;
+	T_IP6_HDR		*ip6h;
+	T_IN6_IFADDR		*ifa;
+	T_IF_ADDR		*mac = NULL;
+	uint_t			len;
+	uint16_t		ipflags = 0;
+
+	NET_COUNT_ICMP6(net_count_nd6[NC_ND6_NA_OUT_PACKETS], 1);
+
+	/*
+	 *  近隣通知ペイロード長を計算する。
+	 *  tlladdr が真ならネットワークインタフェースのアドレスを追加する。
+	 */
+	if (tlladdr && IF_SOFTC_TO_IFADDR(ifp->ic))
+		len = (NEIGHBOR_ADVERT_HDR_SIZE + ND_OPT_HDR_SIZE + sizeof(T_IF_ADDR) + 7) >> 3 << 3;
+	else
+		len = (NEIGHBOR_ADVERT_HDR_SIZE + 7) >> 3 << 3;
+
+	/*
+	 *  他のリンクからの偽造されたデータグラムを
+	 *  排除するため、ホップリミットに IPV6_MAXHLIM (255) を設定する。
+	 */
+	ipflags = IPV6_OUT_SET_HOP_LIMIT(IPV6_OUT_FLG_HOP_LIMIT, IPV6_MAXHLIM);
+
+	/* ネットワークバッファを獲得し、IPv6 ヘッダを設定する。*/
+	if (in6_get_datagram(&output, len, 0, daddr, NULL,
+	                     IPPROTO_ICMPV6, IPV6_MAXHLIM,
+	                     NBA_SEARCH_ASCENT, TMO_ND6_NA_OUTPUT) != E_OK)
+		return;
+
+	ip6h = GET_IP6_HDR(output);
+
+	if (IN6_IS_ADDR_UNSPECIFIED(daddr)) {
+		/*
+		 *  宛先アドレスが無指定の場合は、
+		 *  リンクローカル全ノード・マルチキャストアドレスを設定する。
+		 */
+		ip6h->dst.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
+		ip6h->dst.s6_addr32[1] = 0;
+		ip6h->dst.s6_addr32[2] = 0;
+		ip6h->dst.s6_addr32[3] = IPV6_ADDR_INT32_ONE;
+		flags &= ~ND_NA_FLG_SOLICITED;
+		}
+	else
+		memcpy(&ip6h->dst, daddr, sizeof(T_IN6_ADDR));
+
+	/*
+	 *  宛先アドレスにふさわしい送信元アドレスを、
+	 *  ネットワークインタフェースから探索して利用する。
+	 */
+	if ((ifa = in6_ifawithifp(ifp, &ip6h->dst)) == NULL) {
+		syscall(rel_net_buf(output));
+		return;
+		}
+	memcpy(&ip6h->src, &ifa->addr, sizeof(T_IN6_ADDR));
+
+	/* 近隣通知ヘッダを設定する。*/
+	nah = GET_NEIGHBOR_ADVERT_HDR(output, IF_IP6_NEIGHBOR_ADVERT_HDR_OFFSET);
+	nah->hdr.type        = ND_NEIGHBOR_ADVERT;
+	nah->hdr.code        = 0;
+	memcpy(&nah->target, taddr, sizeof(T_IN6_ADDR));
+
+	/* tlladdr が真ならネットワークインタフェースのアドレスを追加する。*/
+	if (tlladdr && (mac = IF_SOFTC_TO_IFADDR(ifp->ic)) != NULL) {
+
+		T_ND_OPT_HDR	*opth;
+		uint_t		optlen;
+
+		opth   = (T_ND_OPT_HDR *)GET_NEIGHBOR_ADVERT_SDU(output, IF_IP6_NEIGHBOR_ADVERT_HDR_OFFSET);
+		optlen = (ND_OPT_HDR_SIZE + sizeof(T_IF_ADDR) + 7) >> 3 << 3;
+		memset(opth, 0, optlen);
+		opth->type = ND_OPT_TARGET_LINKADDR;
+		opth->len  = optlen >> 3;
+		memcpy((uint8_t *)opth + sizeof(T_ND_OPT_HDR), mac, sizeof(T_IF_ADDR));
+		}
+	else
+		flags &= ~ND_NA_FLG_OVERRIDE;
+
+	nah->nd_na_flags_reserved = flags;
+
+	/* チェックサムを計算する。*/
+	nah->hdr.sum = 0;
+	nah->hdr.sum = in6_cksum(output, IPPROTO_ICMPV6, (uint8_t*)nah - output->buf, len);
+
+	/* 送信する。*/
+	NET_COUNT_ICMP6(net_count_nd6[NC_ICMP6_OUT_OCTETS],
+	               output->len - GET_IF_IP6_HDR_SIZE(output));
+	NET_COUNT_ICMP6(net_count_nd6[NC_ICMP6_OUT_PACKETS], 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutMsgs, 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutNeighborAdvertisements, 1);
+	ip6_output(output, ipflags, TMO_ND6_NS_OUTPUT);
+	}
+
+/*
+ *  nd6_dad_start -- 重複アドレス検出 (DAD) を開始する。
+ *
+ *    第3引数のtick は、インタフェースが起動されてから、重複検出を
+ *    送信するまでの最小遅延値である。
+ */
+
+void
+nd6_dad_start (T_IFNET *ifp, T_IN6_IFADDR *ifa, int_t *tick)
+{
+	/* フラグをチェックする。*/
+	if (!(ifa->flags & IN6_IFF_TENTATIVE))
+		return;
+
+#if NUM_IP6_DAD_COUNT == 0
+
+	ifa->flags &= ~IN6_IFF_TENTATIVE;
+
+#else	/* of #if NUM_IP6_DAD_COUNT == 0 */
+
+	if (ifa->flags & IN6_IFF_ANYCAST) {
+		ifa->flags &= ~IN6_IFF_TENTATIVE;
+		return;
+		}
+	else if ((ifa->flags & IN6_IFF_TENTATIVE) == 0)
+		return;
+
+	/* 重複アドレス検出カウンタをリセットする。*/
+	ifa->ns_icount = ifa->na_icount = ifa->ns_ocount = 0;
+
+	/*
+	 *  重複アドレス検出要請を送信する。ただし、インタフェースを
+	 *  初期化した直後に、最初に送信する場合は、ランダムな遅延を行う。
+	 */
+	if (tick == NULL) {
+		nd6_dad_ns_output(ifp, ifa);
+
+		/* タイムアウトを近隣探索の送信間隔に設定する。*/
+		timeout((callout_func)nd6_dad_timer, ifa, ND6_RETRANS_TIME * NET_TIMER_HZ / SYSTIM_HZ);
+		}
+	else {
+		int_t ntick;
+
+		if (*tick == 0)	/* 最初の送信 */
+			ntick = net_rand() % (ND6_FIRST_DAD_DELAY_TIME * NET_TIMER_HZ / SYSTIM_HZ);
+		else
+			ntick = *tick + net_rand() % (ND6_DAD_DELAY_TIME * NET_TIMER_HZ / SYSTIM_HZ);
+		*tick = ntick;
+		timeout((callout_func)nd6_dad_timer, ifa, ntick);
+		}
+
+#endif	/* of #if NUM_IP6_DAD_COUNT == 0 */
+
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6_rtr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6_rtr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/nd6_rtr.c	(revision 398)
@@ -0,0 +1,1438 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/nd6_rtr.c,v 1.11 2002/04/19 04:46:23 suz Exp $	*/
+/*	$KAME: nd6_rtr.c,v 1.111 2001/04/27 01:37:15 jinmei Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+
+#include <netinet6/nd6.h>
+#include <netinet6/in6_ifattach.h>
+
+#include <net/if_var.h>
+
+/*
+ *  外部関数の定義
+ */
+
+extern const char *itron_strerror (ER ercd);
+
+#ifdef _IP6_CFG
+
+#if NUM_ND6_DEF_RTR_ENTRY > 0
+
+/*
+ *  全域変数
+ */
+
+SYSTIM	nd6_base_reachable_time		= ND6_DEF_REACHABLE_TIME;	/* ルータから通知された値		*/
+SYSTIM	nd6_reachable_time		= ND6_DEF_REACHABLE_TIME;	/* ルータから通知された値の補正値	*/
+SYSTIM	nd6_recalc_reachtm_interval	= ND6_RECALC_REACHTM_INTERVAL;	/* 到達可能状態の有効時間再計算間隔	*/
+SYSTIM	nd6_retrans_time		= ND6_DEF_RETRANS_TIME;		/* 近隣探索の送信間隔			*/
+uint8_t	ip6_defhlim			= IPV6_DEFHLIM;			/* ホップリミットの規定値		*/
+
+/*
+ *  局所変数
+ */
+
+/*
+ *  プレフィックス・リスト
+ */
+
+static T_ND6_PREFIX nd6_prefix[NUM_ND6_PREFIX_ENTRY];
+
+/*
+ *  ディフォルトルータ・リスト
+ */
+
+static T_DEF_ROUTER	nd6_def_router[NUM_ND6_DEF_RTR_ENTRY];
+static uint_t		def_router_count = 0;				/* リストにあるルータ数 */
+
+/*
+ *  make_mask -- マップ用のマスクを生成する。
+ */
+
+static uint_t
+make_mask (int_t index)
+{
+	uint_t	mask;
+	int_t	ix;
+
+	/* マスクを生成する。*/
+	mask = 1;
+	for (ix = index; ix -- > 0; )
+		mask <<= 1;
+
+	return mask;
+	}
+
+/*
+ *  find_pfxlist_reachable_router --
+ *      指定したプレフィックスを通知したルータがリンク上に存在するかチェックする。
+ */
+
+static T_DEF_ROUTER *
+find_pfxlist_reachable_router (T_ND6_PREFIX *pr)
+{
+	T_DEF_ROUTER	*dr = NULL;
+	T_LLINFO_ND6	*ln;
+	uint_t		mask;
+	int_t		ix;
+
+	mask = 1;
+	for (ix = 0; ix < def_router_count; ix ++) {
+		if ((pr->routermap & mask) != 0) {
+			if ((ln = nd6_lookup(&nd6_def_router[ix].addr, false)) != NULL &&
+			    ND6_IS_LLINFO_PROBREACH(ln))
+				return dr;
+			}
+		mask <<= 1;
+		}
+	return NULL;
+	}
+
+/*
+ *  pfxlist_onlink_check -- プレフィックス・リストのオンリンク状態をチェックする。
+ *
+ *    注意: この関数を呼び出すときは、SEM_ND6_DEFRTRLIST で、
+ *          ロックしてから呼び出すこと。
+ */
+
+static void
+pfxlist_onlink_check (void)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_ND6_PREFIX	*pr = NULL;
+	T_IN6_IFADDR	*ia;
+	ER		error;
+	int_t		ix;
+
+	for (ix = NUM_ND6_PREFIX_ENTRY; ix -- > 0; ) {
+		pr = &nd6_prefix[ix];
+		if ((pr->flags & ND6_PREFIX_FLAG_ONLINK) != 0 &&
+		    find_pfxlist_reachable_router(pr))
+			break;
+		}
+
+	if (ix >= 0) {
+		/*
+		 *  オンリンク状態のプレフィックスが最低一つ存在するときの処理。
+		 *  各プレフィックスのオンリンク状態を、それらを通知してきたルータの
+		 *  状態に従って設定する。
+		 */
+
+		
+		for (ix = NUM_ND6_PREFIX_ENTRY; ix -- > 0; ) {
+			pr = &nd6_prefix[ix];
+
+			if ((pr->flags & ND6_PREFIX_FLAG_ONLINK) == 0)
+				continue;
+
+			if ((pr->flags & ND6_PREFIX_STATE_DETACHED) == 0 &&
+			    find_pfxlist_reachable_router(pr) == NULL)
+				pr->flags |= ND6_PREFIX_STATE_DETACHED;
+
+			if ((pr->flags & ND6_PREFIX_STATE_DETACHED) != 0 &&
+			    find_pfxlist_reachable_router(pr) != NULL)
+				pr->flags &= ~ND6_PREFIX_STATE_DETACHED;
+			}
+		}
+	else {
+		/*
+		 *  どのプレフィックスもオンリンクではなく、
+		 *  ディフォルトルータも存在しないときの処理。
+		 *  すべてのプレフィックスを使用可能状態に設定する。
+		 */
+
+		
+		for (ix = NUM_ND6_PREFIX_ENTRY; ix -- > 0; ) {
+			pr = &nd6_prefix[ix];
+
+			if ((pr->flags & ND6_PREFIX_FLAG_ONLINK) == 0)
+				continue;
+
+			if ((pr->flags & ND6_PREFIX_STATE_DETACHED) != 0)
+				pr->flags &= ~ND6_PREFIX_STATE_DETACHED;
+			}
+		}
+
+	/*
+	 *  各プレフィックス毎に、通知してきたルータの状態と
+	 *  オンリンクの状態が一致しなければ、オンリンク状態を更新する。
+	 */
+	for (ix = NUM_ND6_PREFIX_ENTRY; ix -- > 0; ) {
+		pr = &nd6_prefix[ix];
+
+		if ((pr->flags & ND6_PREFIX_FLAG_ONLINK) == 0)
+			continue;
+
+		if ((pr->flags & ND6_PREFIX_STATE_DETACHED) != 0 &&
+		    (pr->flags & ND6_PREFIX_STATE_ONLINK  ) != 0) {
+			if ((error = nd6_prefix_offlink(pr)) != E_OK)
+				syslog(LOG_ERROR, "[ND6 RTR] prefix offlink failed: %s", itron_strerror(error));
+			}
+
+		if ((pr->flags & ND6_PREFIX_STATE_DETACHED) == 0 &&
+		    (pr->flags & ND6_PREFIX_STATE_ONLINK  ) == 0 &&
+		    (pr->flags & ND6_PREFIX_FLAG_ONLINK   ) == 0) {
+			if ((error = nd6_prefix_onlink(pr)) != E_OK)
+				syslog(LOG_ERROR, "[ND6 RTR] prefix onlink failed: %s", itron_strerror(error));
+			}
+		}
+
+	/*
+	 *  リンク上にプレフィックスを通知しているルータが
+	 *  少なくとも 1 台存在するか確認する。
+	 */
+	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
+		ia = &ifp->in6_ifaddrs[ix];
+		if ((ia->flags & (IN6_IFF_DEFINED | IN6_IFF_AUTOCONF)) != 0 &&
+		     ia->prefix_index != ND6_PREFIX_IX_INVALID) {
+			pr = &nd6_prefix[ia->prefix_index];
+			if (find_pfxlist_reachable_router(pr) != NULL)
+				break;
+			}
+		}
+
+	if (ix >= 0) {
+		/*
+		 *  リンク上にプレフィックスを通知しているルータが
+		 *  少なくとも 1 台存在する時の処理。
+		 */
+		for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
+			ia = &ifp->in6_ifaddrs[ix];
+			if ((ia->flags & (IN6_IFF_DEFINED | IN6_IFF_AUTOCONF)) != 0 &&
+			     ia->prefix_index != ND6_PREFIX_IX_INVALID) {
+				pr = &nd6_prefix[ia->prefix_index];
+				if (find_pfxlist_reachable_router(pr) != NULL)
+					ia->flags &= ~IN6_IFF_DETACHED;
+				else
+					ia->flags |= IN6_IFF_DETACHED;
+				}
+			}
+		}
+	else {
+		/*
+		 *  リンク上にプレフィックスを通知しているルータが
+		 *  1 台存在しない時は全てのアドレスを利用できるようにする。
+		 */
+		for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
+			ia = &ifp->in6_ifaddrs[ix];
+			if ((ia->flags & (IN6_IFF_DEFINED | IN6_IFF_AUTOCONF)) != 0)
+				ia->flags &= ~IN6_IFF_DETACHED;
+			}
+		}
+	}
+
+/*
+ *  pfxrtr_add -- プレフィックスエントリとディフォルトルータ・エントリをリンクする。
+ *
+ *    注意: この関数を呼び出すときは、SEM_ND6_DEFRTRLIST で、
+ *          ロックしてから呼び出すこと。
+ */
+
+static void
+pfxrtr_add (int_t prefix_index, int_t rtr_index)
+{
+	/*  プレフィックスエントリとディフォルトルータ・エントリをリンクする。*/
+	nd6_prefix[prefix_index].routermap |= make_mask(rtr_index);
+	nd6_def_router[rtr_index].plistmap |= make_mask(prefix_index);
+
+	pfxlist_onlink_check();
+	}
+
+/*
+ *  nd6_pfxrtr_lookup -- プレフィックスエントリからルータを探索する。
+ */
+
+static uint_t
+pfxrtr_lookup (const T_ND6_PREFIX *pr, int_t rtr_index)
+{
+	return (pr->routermap & make_mask(rtr_index)) == 0 ? IN6_RTR_IX_UNREACH : rtr_index;
+	}
+
+/*
+ *  defrouter_select -- 優先ディフォルト・ルータを選択しなおす。
+ *
+ *    注意: この関数を呼び出すときは、SEM_ND6_DEFRTRLIST で、
+ *          ロックしてから呼び出すこと。
+ */
+
+static void
+defrouter_select (void)
+{
+	T_DEF_ROUTER	*dr = NULL, router;
+	T_LLINFO_ND6	*ln;
+	int_t		ix, tix;
+
+	for (ix = 0; ix < def_router_count; ix ++) {
+		dr = &nd6_def_router[ix];
+		if ((ln = nd6_lookup(&dr->addr, false)) != NULL && ND6_IS_LLINFO_PROBREACH(ln)) {
+		
+			/* 選択したルータを先頭に移す。*/
+			router = *dr;
+			for (tix = ix; tix > 0; tix --)
+				nd6_def_router[tix] = nd6_def_router[tix - 1];
+			nd6_def_router[0] = router;
+			break;
+			}
+		}
+	}
+
+/*
+ *  defrtrlist_update -- ディフォルトルータ・リストを更新する。
+ *
+ *  	戻り値は、ルータのインデックス。
+ *      ただし、値が -1 なら、プレフィックス・リストは更新しない。
+ */
+
+static int_t
+defrtrlist_update (T_IN6_ADDR *src, uint32_t lifetime, uint8_t flags)
+{
+	T_DEF_ROUTER	*dr, *fdr = NULL;
+	SYSTIM		now;
+	int_t		ix;
+
+	syscall(get_tim(&now));
+	syscall(wai_sem(SEM_ND6_DEFRTRLIST));
+
+	/* 登録済か調べる。*/
+	if ((fdr = nd6_defrtrlist_lookup(src)) != NULL) {
+		/* 登録済みの場合の処理 */
+		if (lifetime == 0) {
+			nd6_defrtrlist_del(fdr);
+			syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+			return -1;
+			}
+		else {
+			fdr->lifetime = lifetime * SYSTIM_HZ;		/* lifetime の単位は秒 */
+			fdr->flags    = flags;
+			fdr->expire   = now + fdr->lifetime;
+			syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+			return fdr - nd6_def_router;
+			}
+		}
+	else if (lifetime == 0) {
+		syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+		return -1;
+		}
+
+	if (fdr == NULL && def_router_count < NUM_ND6_DEF_RTR_ENTRY) {
+		/*
+		 *  def_router_count < NUM_ND6_DEF_RTR_ENTRY であれば、
+		 *  nd6_def_router[def_router_count]; が空きエントリ
+		 */
+		fdr = &nd6_def_router[def_router_count];
+		}
+
+	/* 空きエントリがなければ、有効時間が短いエントリを削除する。*/
+	if (fdr == NULL) {
+		T_DEF_ROUTER	*sdr = NULL;
+		int32_t		diff, sdiff = 0xffffffff;
+
+		for (ix = def_router_count; ix -- > 0; ) {
+			dr = &nd6_def_router[ix];
+			diff = (int32_t)(dr->expire - now);
+			if (diff <= 0) {	/* dr->expire <= now */
+				/* 既に、有効時間が過ぎている。*/
+				sdr = dr;
+				break;
+				}
+			else if (diff < sdiff)
+				sdr = dr;
+			}
+		if (sdr != NULL) {
+			fdr = sdr;
+			nd6_defrtrlist_del(fdr);
+			}
+		}
+
+	/* 各メンバに値を設定する。*/
+	fdr->plistmap = 0;
+	memcpy(&fdr->addr, src, sizeof(T_IN6_ADDR));
+	fdr->lifetime = lifetime * SYSTIM_HZ;		/* lifetime の単位は秒 */
+	fdr->flags    = flags;
+	fdr->expire   = now + fdr->lifetime;
+	fdr->state    = ND6_DEF_RTR_BUSY;
+	def_router_count ++;
+
+	/*
+	 *  ディフォルトルータとして登録するが、
+	 *  既にディフォルトルータがあれば選択しなおさない。
+	 */
+	if (fdr - nd6_def_router != 0)
+		defrouter_select();
+
+	syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+	return fdr - nd6_def_router;
+	}
+
+/*
+ *  in6_ifadd -- インタフェースにアドレスを追加する。
+ */
+
+static ER
+in6_ifadd (T_ND6_PREFIX *pr, T_IN6_IFADDR *ia, int_t router_index)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN6_ADDR	mask, addr;
+	T_IN6_IFADDR	*lla;
+	int_t		ix;
+
+	lla = &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
+
+	/*
+	 *  リンクローカルアドレスが未登録であれば何もしない。
+	 */
+	if ((lla->flags & IN6_IFF_DEFINED) == 0)
+		return E_OBJ;
+
+	/*
+	 *  ルータから通知されたプレフィックス長が、
+	 *  リンクローカルアドレスのプレフィックス長と
+	 *  異なっていればエラー
+	 */
+	if (lla->prefix_len != pr->prefix_len)
+		return E_PAR;
+
+	/* プレフィックスマスクを生成する。*/
+	in6_plen2pmask(&mask, pr->prefix_len);
+
+	/* アドレスを生成する。*/
+	for (ix = 0; ix < 4; ix ++)
+		addr.s6_addr32[ix] = (pr->prefix.s6_addr32[ix] &  mask.s6_addr32[ix])
+		                   | ( lla->addr.s6_addr32[ix] & ~mask.s6_addr32[ix]);
+
+	/* フラグを初期化する。*/
+	ia->flags = 0;
+
+	return in6_update_ifa(ifp, ia, &addr,
+	                      pr->prefix_len, pr->vltime, pr->pltime,
+	                      router_index, pr - nd6_prefix, IN6_IFF_AUTOCONF);
+	}
+
+/*
+ *  nd6_prefix_lookup -- プレフィックスを探索する。
+ */
+
+static T_ND6_PREFIX *
+nd6_prefix_lookup (const T_IN6_ADDR *prefix, uint_t plen)
+{
+	T_ND6_PREFIX	*pr;
+	int_t		ix;
+
+	for (ix = NUM_ND6_PREFIX_ENTRY; ix -- > 0; ) {
+		pr = &nd6_prefix[ix];
+		if ((pr->flags & ND6_PREFIX_STATE_BUSY) &&
+		     pr->prefix_len == plen && IN6_ARE_ADDR_EQUAL(&pr->prefix, prefix))
+			return pr;
+		}
+
+	return NULL;
+	}
+
+/*
+ *  prelist_remove -- プレフィックスリストからプレフィックスを削除する。
+ *
+ *    注意: この関数を呼び出すときは、SEM_ND6_DEFRTRLIST で、
+ *          ロックしてから呼び出すこと。
+ */
+
+static void
+prelist_remove (T_ND6_PREFIX *pr)
+{
+	ER	error = E_OK;
+	uint_t	mask;
+	int_t	rix;
+
+	/* 有効時間切れにする。*/
+	pr->vltime = 0;
+	pr->pltime = 0;
+
+	if ((pr->flags & ND6_PREFIX_STATE_ONLINK) != 0 &&
+	    (error = nd6_prefix_offlink(pr)) != E_OK) {
+		syslog(LOG_ERROR, "[ND6 RTR] prefix remove failed: %s", itron_strerror(error));
+		return;
+		}
+
+	/*  プレフィックスエントリとディフォルトルータ・エントリのリンクを解除する。*/
+	pr->routermap = 0;
+	mask = make_mask(pr - nd6_prefix);
+	for (rix = def_router_count; rix --; )
+		nd6_def_router[rix].plistmap &= ~mask;
+
+	/* プレフィックスを無効にする。*/
+	pr->flags &= ~ND6_PREFIX_STATE_BUSY;
+
+	pfxlist_onlink_check();
+	}
+
+/*
+ *  nd6_prefix_onlink -- プレフィックスをオンリンクに設定し、アドレスを使用可能にする。
+ *
+ *    注意: この関数を呼び出すときは、SEM_ND6_DEFRTRLIST で、
+ *          ロックしてから呼び出すこと。
+ */
+
+ER
+nd6_prefix_onlink (T_ND6_PREFIX *pr)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN6_IFADDR	*lla, *ia = NULL;
+	int_t		ix;
+
+	/* 既にオンリンク状態になっている場合はエラー。*/
+	if ((pr->flags & ND6_PREFIX_STATE_ONLINK) != 0)
+		return E_OBJ;
+
+	/* リンクローカルアドレスが未登録であれば何もしない。*/
+	lla = &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
+	if ((lla->flags & IN6_IFF_DEFINED) == 0)
+		return E_OK;
+
+	/*
+	 *  指定されたプレフィックスが割り当てられているインタフェースの
+	 *  アドレス情報を探す。
+	 */
+	for (ix = NUM_IN6_IFADDR_ENTRY; ix --; ) {
+		ia = &ifp->in6_ifaddrs[ix];
+		if (ia->prefix_index == (pr - nd6_prefix))
+			break;
+		}
+
+	if (ix >= 0) {
+
+		/* アドレス情報を使用可能にする。*/
+		ia->flags &= ~IN6_IFF_DETACHED;
+
+		/* プレフィックスをオンリンクに設定する。*/
+		pr->flags |= ND6_PREFIX_STATE_ONLINK;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  nd6_prefix_offlink -- プレフィックスをオフリンクに設定し、アドレスを使用不可にする。
+ *
+ *    注意: この関数を呼び出すときは、SEM_ND6_DEFRTRLIST で、
+ *          ロックしてから呼び出すこと。
+ */
+
+ER
+nd6_prefix_offlink (T_ND6_PREFIX *pr)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN6_IFADDR	*ia = NULL;
+	int_t		ix;
+
+	/* 既にオフリンク状態になっている場合はエラー。*/
+	if ((pr->flags & ND6_PREFIX_STATE_ONLINK) == 0)
+		return E_OBJ;
+
+	/*
+	 *  指定されたプレフィックスが割り当てられているインタフェースの
+	 *  アドレス情報を探す。
+	 */
+	for (ix = NUM_IN6_IFADDR_ENTRY; ix --; ) {
+		ia = &ifp->in6_ifaddrs[ix];
+		if (ia->prefix_index == (pr - nd6_prefix))
+			break;
+		}
+
+	if (ix >= 0) {
+
+		/* アドレス情報を使用不可にする。*/
+		ia->flags |= IN6_IFF_DETACHED;
+
+		/* プレフィックスをオフリンクに設定する。*/
+		pr->flags &= ~ND6_PREFIX_STATE_ONLINK;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  in6_init_prefix_ltimes -- プレフィックスの有効時間を設定する。
+ */
+
+static ER
+in6_init_prefix_ltimes (T_ND6_PREFIX *pr)
+{
+	SYSTIM		now;
+
+	/* 推奨有効時間が有効時間より長いときはエラー */
+	if (pr->pltime > pr->vltime)
+		return E_PAR;
+
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	if (pr->pltime == ND6_INFINITE_LIFETIME)
+		pr->preferred = 0;
+	else
+		pr->preferred = pr->pltime + now;
+
+	if (pr->vltime == ND6_INFINITE_LIFETIME)
+		pr->expire = 0;
+	else
+		pr->expire = pr->vltime + now;
+
+	return E_OK;
+	}
+
+/*
+ *  nd6_prelist_add -- プレフィックスリストにプレフィックスを追加する。
+ *
+ *    注意: この関数を呼び出すときは、SEM_ND6_DEFRTRLIST で、
+ *          ロックしてから呼び出すこと。
+ */
+
+static T_ND6_PREFIX *
+nd6_prelist_add (T_ND_OPT_PREFIX_INFO *pi, int_t rtr_index)
+{
+	T_ND6_PREFIX	*pr = NULL;
+	int_t		ix;
+
+	/* プレフィックスリストから空きのプレフィックスエントリを探索する。*/
+	for (ix = NUM_ND6_PREFIX_ENTRY; ix --; ) {
+		pr = &nd6_prefix[ix];
+		if ((pr->flags & ND6_PREFIX_STATE_BUSY) == 0)
+			break;
+		}
+
+	/* プレフィックスリストに空きがなければエラー */
+	if (ix < 0)
+		return NULL;
+
+	pr->flags |= ND6_PREFIX_STATE_BUSY;
+
+	/* プレフィックスを追加する。*/
+	pr->prefix     = pi->prefix;
+	pr->prefix_len = pi->prefix_len;
+
+	/* フラグを設定する。*/
+	if ((pi->flags & ND_OPT_PI_FLAG_ONLINK) != 0)
+		pr->flags |= ND6_PREFIX_FLAG_ONLINK;
+	if ((pi->flags & ND_OPT_PI_FLAG_AUTO) != 0)
+		pr->flags |= ND6_PREFIX_FLAG_AUTO;
+
+	/* プレフィックスの有効時間を設定する。*/
+	pr->vltime = ntohl(pi->valid);
+	pr->pltime = ntohl(pi->preferred);
+	in6_init_prefix_ltimes(pr);
+
+	if ((pr->flags & ND6_PREFIX_FLAG_ONLINK) != 0) {
+		if (nd6_prefix_onlink(pr) != E_OK)
+			return NULL;
+		}
+
+	/* ルータマップを初期化する。*/
+	pr->routermap = 0;
+
+	/* ルータを追加する。*/
+	pfxrtr_add(pr - nd6_prefix, rtr_index);
+
+	return pr;
+	}
+
+/*
+ *  prelist_update -- プレフィックス・リストを更新する。
+ */
+
+static void
+prelist_update (T_ND_OPT_PREFIX_INFO *pi, uint_t router_index)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_ND6_PREFIX	*pr;
+	T_IN6_IFADDR	*ia = NULL;
+	int_t		ix, ifidlen;
+
+	syscall(wai_sem(SEM_ND6_DEFRTRLIST));
+	if ((pr = nd6_prefix_lookup(&pi->prefix, pi->prefix_len)) != NULL) {
+		/*
+		 *  登録済みの場合は、プレフィックスリストを更新する。
+		 */
+
+		/*
+		 *  フラグの更新の注意:
+		 *    on-link ビットと autonomous ビットは
+		 *    1 から 0 に変更してはならない。
+		 */
+
+		if ((pi->flags & ND_OPT_PI_FLAG_ONLINK) != 0)
+			pr->flags |= ND6_PREFIX_FLAG_ONLINK;
+		if ((pi->flags & ND_OPT_PI_FLAG_AUTO) != 0)
+			pr->flags |= ND6_PREFIX_FLAG_AUTO;
+
+		if ((pi->flags & ND_OPT_PI_FLAG_ONLINK) != 0) {
+			/*
+			 *  通知されたプレフィックスがオンリンクの時は、
+			 *  有効時間を更新する。
+			 */
+			pr->vltime = ntohl(pi->valid);
+			pr->pltime = ntohl(pi->preferred);
+			in6_init_prefix_ltimes(pr);
+			}
+
+		if ((pi->flags & ND_OPT_PI_FLAG_ONLINK  ) != 0 &&
+		    (pr->flags & ND6_PREFIX_STATE_ONLINK) == 0) {
+			/*
+			 *  オフリンクのプレフィックスがオンリンクになった時の処理を実行する。
+			 */
+			if (nd6_prefix_onlink(pr) != E_OK) {
+				syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+				syslog(LOG_ERROR, "[ND6 RTR] prefix update failed.");
+				return;
+				}
+			}
+
+		if (router_index != IN6_RTR_IX_UNREACH && pfxrtr_lookup(pr, router_index) == IN6_RTR_IX_UNREACH)
+			pfxrtr_add(pr - nd6_prefix, router_index);
+		}
+	else {	/* 未登録の場合 */
+
+		/* 有効時間 0 のプレフィックスは追加しない。*/
+		if (pi->valid == 0) {
+			syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+			return;
+			}
+
+		/* オフリンクでアドレス自動設定に使用しなければ追加しない。*/
+		if ((pi->flags & (ND_OPT_PI_FLAG_ONLINK | ND_OPT_PI_FLAG_AUTO)) !=
+		                 (ND_OPT_PI_FLAG_ONLINK | ND_OPT_PI_FLAG_AUTO)) {
+			syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+			return;
+			}
+
+		/* プレフィックスを追加する。*/
+		if ((pr = nd6_prelist_add(pi, router_index)) == NULL) {
+			syslog(LOG_ERROR, "[ND6 RTR] prefix add failed.");
+			syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+			return;
+			}
+
+#if 1		/* プレフィックスが未登録の場合だけ表示する。*/
+		syslog(LOG_NOTICE, "[ND6 RTR] add prefix: flags[MOH]: %02x, addr: %s\n"
+		                   "                                      from: %s.",
+		                   nd6_def_router[router_index].flags,
+		                   ipv62str(NULL, &pi->prefix),
+		                   ipv62str(NULL, &nd6_def_router[router_index].addr));
+#endif
+		if ((pr->flags & ND6_PREFIX_FLAG_ONLINK) == 0) {
+			/*
+			 *  オフリンク・プレフィックスの場合は、有効時間を 0 に設定する。
+			 *  あとで有効期限切れとなり、リストから削除される。
+			 */
+			pr->vltime = 0;
+			pr->pltime = 0;
+			in6_init_prefix_ltimes(pr);
+			}
+		}
+
+	/*
+	 *  ステートレス・アドレス自動設定を行う。
+	 */
+	if ((pr->flags & ND6_PREFIX_FLAG_AUTO) == 0) {
+		syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+		return;
+		}
+
+	/*
+	 *  通知されたプレフィックスが割り当てられているインタフェースの
+	 *  アドレス情報を探す。
+	 */
+	for (ix = NUM_IN6_IFADDR_ENTRY; ix --; ) {
+		ia = &ifp->in6_ifaddrs[ix];
+		if ((ia->flags & IN6_IFF_DEFINED) != 0 &&
+		    ia->prefix_len == pr->prefix_len &&
+		    in6_are_prefix_equal(&ia->addr, &pr->prefix, pr->prefix_len))
+			break;
+		}
+
+	if (ix >= 0) {	/* 登録済みのとき */
+		if ((ia->flags & IN6_IFF_AUTOCONF) == 0) {
+			/*
+			 *  ステートレス・アドレス自動設定により
+			 *  設定されていなければ更新しない。
+			 */
+			;
+			}
+		else if (ia->flags & IN6_IFF_TENTATIVE) {
+			/*
+			 *  重複検出中なら更新しない。
+			 */
+			;
+			}
+		else {
+			T_IN6_ADDR	mask, addr;
+			T_IN6_IFADDR	*lla;
+			uint32_t		vltime;
+			SYSTIM		now;
+			int_t		ix;
+
+			/* 有効時間を設定する。*/
+			syscall(get_tim(&now));
+
+			if (ia->lifetime.vltime == ND6_INFINITE_LIFETIME)
+				vltime = ND6_INFINITE_LIFETIME;
+			else if (IFA6_IS_INVALID(ia, now))
+				vltime = 0;
+			else
+				vltime = ia->lifetime.expire - now / SYSTIM_HZ;
+
+			if (pr->vltime > (2 * 60 * 60) || pr->vltime > vltime) {
+				/*
+				 *  lifetime.expire、pi->valid (有効時間) と
+				 *  pi->preferred (推奨有効時間) の単位は [s]。
+				 *  通知された有効時間が 2 時間以上か、現在の残り時間より
+				 *  長ければ、新しい有効時間には、通知された有効時間を設定する。
+				 */
+				vltime = pr->vltime;
+				}
+			else if (vltime <= (2 * 60 * 60))
+				;
+			else {
+				/*
+				 *  IPsec は未実装のため、2 時間を設定する。
+				 */
+				vltime = 2 * 60 * 60;
+				}
+
+			lla = &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
+
+			/* プレフィックスマスクを生成する。*/
+			in6_plen2pmask(&mask, pr->prefix_len);
+
+			/* アドレスを生成する。*/
+			for (ix = 0; ix < 4; ix ++)
+				addr.s6_addr32[ix] = (pr->prefix.s6_addr32[ix] &  mask.s6_addr32[ix])
+				                   | ( lla->addr.s6_addr32[ix] & ~mask.s6_addr32[ix]);
+
+			in6_update_ifa(ifp, ia, &addr, pr->prefix_len, vltime,
+			               pr->pltime, router_index, pr - nd6_prefix,
+			               IN6_IFF_AUTOCONF | IN6_IFF_NODAD);
+			}
+		}
+
+	else { /* 未登録のとき */
+
+		/*
+		 *  プレフィックス長をチェックする。
+		 *  もし、プレフィックス長とインタフェース ID の合計が
+		 *  128 ビットに一致しない時は、プレフィックス情報を無視する。
+		 */
+		if ((ifidlen = in6_if2idlen(ifp)) < 0)
+			syslog(LOG_ERROR, "[ND6 RTR] IFID undefined.");
+		else if (ifidlen + pr->prefix_len != 128)
+			syslog(LOG_NOTICE, "[ND6 RTR] invalid prefix len: %d.", pr->prefix_len);
+		else {
+
+			for (ix = NUM_IN6_IFADDR_ENTRY; ix --; ) {
+				ia = &ifp->in6_ifaddrs[ix];
+				if ((ia->flags & IN6_IFF_DEFINED) == 0) {
+					in6_ifadd(pr, ia, router_index);
+					pfxlist_onlink_check();
+					break;
+					}
+				}
+
+			if (ix < 0)
+				syslog(LOG_ERROR, "[ND6 RTR] prefix update failed.");
+			}
+		}
+	syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+	}
+
+/*
+ *  nd6_prelist_timer -- プレフィックス・リストの管理タイマー
+ */
+
+void
+nd6_prelist_timer (void)
+{
+	T_ND6_PREFIX	*pr;
+	SYSTIM		now;
+	int_t		ix;
+
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;		/* 有効時間の単位は [s] */
+
+	syscall(wai_sem(SEM_ND6_DEFRTRLIST));
+	for (ix = NUM_ND6_PREFIX_ENTRY; ix -- > 0; ) {
+		pr = &nd6_prefix[ix];
+		if ((pr->flags & ND6_PREFIX_STATE_BUSY) != 0 && (int32_t)(pr->expire - now) <= 0)
+		                                                       /* pr->expire <= now */
+			prelist_remove(pr);
+		}
+	syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+	}
+
+/*
+ *  nd6_rs_output -- ルータ要請を出力する。
+ */
+
+static void
+nd6_rs_output (void)
+{
+	T_ROUTER_SOLICIT_HDR	*rsh;
+	T_NET_BUF		*output;
+	T_IN6_IFADDR		*ifa;
+	const T_IN6_ADDR	*saddr;
+	uint16_t		len;
+
+	NET_COUNT_ICMP6(net_count_nd6[NC_ND6_RS_OUT_PACKETS], 1);
+
+	/*
+	 *  送信元アドレスには、リンクローカルアドレスを設定するが、
+	 *  まだ設定されいなければ、無指定を設定する。
+	 */
+	if ((ifa = in6ifa_ifpwithix(IF_GET_IFNET(), IPV6_IFADDR_IX_LINKLOCAL)) != NULL && !IFA6_IS_NOTREADY(ifa))
+		saddr = &ifa->addr;
+	else
+		saddr = &in6_addr_unspecified;
+
+	len = (ROUTER_SOLICIT_HDR_SIZE + 7) >> 3 << 3;
+
+	/* ネットワークバッファを獲得し、IPv6 ヘッダを設定する。*/
+	if (in6_get_datagram(&output, len, 0, &in6_addr_linklocal_allrouters,
+	                     saddr, IPPROTO_ICMPV6,
+	                     IPV6_MAXHLIM, NBA_SEARCH_ASCENT, TMO_ND6_RS_OUTPUT) != E_OK)
+		return;
+
+	/* ルータ要請ヘッダを設定する。*/
+	rsh = GET_ROUTER_SOLICIT_HDR(output, IF_IP6_ROUTER_SOLICIT_HDR_OFFSET);
+	rsh->hdr.type       = ND_ROUTER_SOLICIT;
+	rsh->hdr.code       = 0;
+	rsh->nd_rs_reserved = 0;
+
+	/* チェックサムを計算する。*/
+	rsh->hdr.sum = 0;
+	rsh->hdr.sum = in6_cksum(output, IPPROTO_ICMPV6, (uint8_t*)rsh - output->buf, len);
+
+	/* 送信する。*/
+	NET_COUNT_ICMP6(net_count_nd6[NC_ICMP6_OUT_OCTETS],
+	               output->len - GET_IF_IP6_HDR_SIZE(output));
+	NET_COUNT_ICMP6(net_count_nd6[NC_ICMP6_OUT_PACKETS], 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutMsgs, 1);
+	NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpOutRouterSolicits, 1);
+	ip6_output(output, IPV6_OUT_SET_HOP_LIMIT(IPV6_OUT_FLG_HOP_LIMIT, IPV6_MAXHLIM), TMO_ND6_RS_OUTPUT);
+	}
+
+/*
+ *  nd6_defrtrlist_lookup -- ディフォルトルータ・リストを探索する。
+ */
+
+T_DEF_ROUTER *
+nd6_defrtrlist_lookup (const T_IN6_ADDR *src)
+{
+	T_DEF_ROUTER	*dr = NULL;
+	int_t		ix;
+
+	for (ix = def_router_count; ix -- > 0; ) {
+		dr = &nd6_def_router[ix];
+		if (IN6_ARE_ADDR_EQUAL(&dr->addr, src)) {
+			return dr;
+			}
+		}
+	return NULL;
+	}
+
+/*
+ *  nd6_router_lookup -- ルータのアドレスを返す。
+ *
+ */
+
+const T_IN6_ADDR *
+nd6_router_lookup (void)
+{
+	if (def_router_count > 0)
+		return &nd6_def_router[0].addr;
+	else
+		return NULL;
+	}
+
+/*
+ *  nd6_defrtrlist_del -- ディフォルトルータ・リストからルータを削除する。
+ *
+ *    注意: この関数を呼び出すときは、SEM_ND6_DEFRTRLIST で、
+ *          ロックしてから呼び出すこと。
+ */
+
+void
+nd6_defrtrlist_del (T_DEF_ROUTER *dr)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN6_IFADDR	*ia;
+	T_ND6_PREFIX	*pr;
+	uint_t		mask;
+	int_t		ix, rix, pix, rtrix = dr - nd6_def_router;
+
+	if ((ia = in6ifa_ifpwithrtrix(ifp, rtrix)) != NULL) {
+		/*
+		 *  ネットワークインタフェースのプレフィックスを通知した
+		 *  ルータを到達不能にする。
+		 */
+		ia->router_index = IN6_RTR_IX_UNREACH;
+		}
+
+	/* プレフィックスリストからルータを削除する。*/
+	mask = make_mask(rtrix);
+	for (pix = NUM_ND6_PREFIX_ENTRY; pix --; )
+		nd6_prefix[pix].routermap &= ~mask;
+
+	/* 削除したルータ以降を前に詰める。*/
+	for (rix = rtrix + 1; rix < def_router_count; rix ++)
+		nd6_def_router[rix - 1] = nd6_def_router[rix];
+
+	/* プレフィックスリストのルータも更新する。*/
+	if (dr != nd6_def_router) {
+
+		/* マスクを生成する。*/
+		mask = 1;
+		for (ix = rtrix - 1; ix -- > 0; )
+			mask = (mask << 1) | 1;
+
+		for (pix = NUM_ND6_PREFIX_ENTRY; pix --; ) {
+			pr = &nd6_prefix[pix];
+			pr->routermap = (pr->routermap & mask) | (((pr->routermap & ~mask) >> 1) & ~mask);
+			}
+		}
+	def_router_count --;
+
+	/* プレフィックスのオンリンク状態を確認する。*/
+	pfxlist_onlink_check();
+
+	/*
+	 *  削除するルータが優先ディフォルトルータの場合は、
+	 *  優先ディフォルトルータを選択しなおす。
+	 */
+	if (rtrix == 0)
+		defrouter_select();
+	}
+
+/*
+ *  nd6_defrtrlist_timer -- ディフォルトルータ・リストの管理タイマー
+ */
+
+void
+nd6_defrtrlist_timer (void)
+{
+	T_DEF_ROUTER	*dr;
+	SYSTIM		now;
+	int_t		ix;
+
+	syscall(get_tim(&now));
+
+	syscall(wai_sem(SEM_ND6_DEFRTRLIST));
+	for (ix = def_router_count; ix -- > 0; ) {
+		dr = &nd6_def_router[ix];
+		if ((int32_t)(dr->expire - now) <= 0) {
+		           /* dr->expire <= now */
+			nd6_defrtrlist_del(dr);
+			}
+		}
+	syscall(sig_sem(SEM_ND6_DEFRTRLIST));
+	}
+
+/*
+ *  nd6_get_drl -- ディフォルトルータ・リストを獲得する。
+ */
+
+const T_DEF_ROUTER *
+nd6_get_drl (uint_t *count)
+{
+	*count = def_router_count;
+	return nd6_def_router;
+	}
+
+/*
+ *  nd6_get_prl -- プレフィックス・リストを獲得する。
+ */
+
+const T_ND6_PREFIX *
+nd6_get_prl (void)
+{
+	return nd6_prefix;
+	}
+
+#endif	/* of #if NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+/*
+ *  nd6_ra_input -- ルータ通知の入力処理。
+ */
+
+void
+nd6_ra_input (T_NET_BUF *input, uint_t off)
+{
+#if NUM_ND6_DEF_RTR_ENTRY > 0
+
+	T_IFNET			*ifp = IF_GET_IFNET();
+	T_IP6_HDR		*ip6h;
+	T_ROUTER_ADVERT_HDR	*rah;
+	T_ND_OPT_HDR		*opth;
+	SYSTIM			now;
+	int_t			rix;
+	uint_t			lladdr_len = 0;
+	uint32_t		advrea;
+	uint8_t			*lladdr = NULL;
+	uint8_t			nd_opt_off[ND_OPT_OFF_ARRAY_SIZE];
+
+	NET_COUNT_ICMP6(net_count_nd6[NC_ND6_RA_IN_PACKETS], 1);
+
+	ip6h = GET_IP6_HDR(input);
+
+	/*
+	 *  ヘッダのチェック、以下の場合は破棄する。
+	 *    ・ホップリミットが IPV6_MAXHLIM (255) 以外
+	 *    ・ヘッダ長が短い
+	 *    ・始点アドレスが、リンクローカルではない (RFC2461)
+	 */
+	if (ip6h->hlim != IPV6_MAXHLIM                ||
+	    input->len - off < ROUTER_ADVERT_HDR_SIZE ||
+	    !IN6_IS_ADDR_LINKLOCAL(&ip6h->src))
+		goto err_ret;
+
+	rah  = GET_ROUTER_ADVERT_HDR(input, off);
+
+	/* 近隣探索オプションのオフセットを記録する。*/
+	if (nd6_options(nd_opt_off, input->buf + (off + ROUTER_ADVERT_HDR_SIZE),
+	                            input->len - (off + ROUTER_ADVERT_HDR_SIZE)) != E_OK)
+		goto err_ret;
+	/*
+	 *  到達可能状態の有効時間の更新
+
+	 */
+	if (rah->reachable) {
+		advrea = ntohl(rah->reachable) * SYSTIM_HZ / 1000;	/* rah->reachable の単位は ms */
+		if (advrea <= ND6_MAX_REACHABLE_TIME &&
+		    advrea != nd6_base_reachable_time) {
+			syscall(get_tim(&now));
+			nd6_recalc_reachtm_interval
+				= now + ND6_RECALC_REACHTM_INTERVAL;
+			nd6_base_reachable_time	= advrea;
+			nd6_reachable_time
+				= ND6_CALC_REACH_TIME(nd6_base_reachable_time);
+			}
+		}
+
+	/* 近隣探索の送信間隔の更新 */
+	if (rah->retransmit) {
+		nd6_retrans_time = ntohl(rah->retransmit) * SYSTIM_HZ / 1000;
+									/* rah->retransmit の単位は ms */
+		}
+
+	/* ホップリミットの規定値の更新 */
+	if (rah->nd_ra_current_hoplimit) {
+		ip6_defhlim = rah->nd_ra_current_hoplimit;
+		}
+
+	/* ディフォルトルータリストの更新 */
+	rix = defrtrlist_update(&ip6h->src,
+	                       ntohs(rah->nd_ra_router_lifetime),
+	                       rah->nd_ra_flags);		/* rah->nd_ra_router_lifetime の単位は秒 */
+
+	/* プレフィックスリストの更新 */
+	if (nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_PREFIX_INFO_COUNT)]) {
+		T_ND_OPT_PREFIX_INFO	*pi;
+		uint_t			pi_off, pi_count;
+
+		pi_count = nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_PREFIX_INFO_COUNT)];
+		pi_off   = off + ROUTER_ADVERT_HDR_SIZE
+		               + nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_PREFIX_INFORMATION)] - 8;
+	 	/* 注意: オプションオフセット配列には、オフセット + 8 が設定されている。*/
+		while (pi_count -- > 0) {
+			pi = (T_ND_OPT_PREFIX_INFO*)(input->buf + pi_off);
+			if (pi->type != ND_OPT_PREFIX_INFORMATION)
+				/* オプションタイプがプレフィックス情報でなければ何もしない。*/
+				;
+			else if (pi->len != 4)
+			    	/* プレフィックス情報の長さが 32 (8×4) でなければ不正 */
+				syslog(LOG_NOTICE, "[ND6 RTR] prefix opt len: %d.", pi->len);
+			else if (pi->prefix_len > 128)
+				/* プレフィックス長は 128 ビット以下 */
+				syslog(LOG_NOTICE, "[ND6 RTR] prefix len: %d.", pi->prefix_len);
+			else if (IN6_IS_ADDR_MULTICAST(&pi->prefix) ||
+			         IN6_IS_ADDR_LINKLOCAL(&pi->prefix))
+				/* マルチキャストとリンクローカルは不正 */
+				syslog(LOG_NOTICE, "[ND6 RTR] invalid addr: %s from %s.",
+				                   ipv62str(NULL, &pi->prefix), ipv62str(NULL, &ip6h->src));
+#if 0	/* FreeBSD 6.3 で削除されている。*/
+			else if (IN6_IS_ADDR_AGGREGATE_UNICAST(&pi->prefix) &&		
+			         (pi->prefix_len != 64)                       )
+				/* 集約可能ユニキャストで、プレフィックス長が 64 ビット以外は不正 */
+				syslog(LOG_NOTICE, "[ND6 RTR] invalid prefix len for global: %d.", pi->prefix_len);
+#endif
+			else if (ntohl(pi->preferred) > ntohl(pi->valid))
+				/* 推奨有効時間が有効時間より長ければ不正 */
+				syslog(LOG_NOTICE, "[ND6 RTR] preferred(%d) > valid time(%d).", ntohl(pi->preferred), ntohl(pi->valid));
+			else {
+#if 0	/* プレフィックスが未登録の場合だけ表示する。*/
+				syslog(LOG_NOTICE, "[ND6 RTR] update prefix: flags[MOH]: %02x, addr: %s\n"
+				                   "                                         from: %s.",
+				                   rah->nd_ra_flags, ipv62str(NULL, &pi->prefix), ipv62str(NULL, &ip6h->src));
+#endif
+				if (rix >= 0) {
+					/*
+					 *  defrtrlist_update の戻り値は、ルータのインデックス。
+					 *  ただし、値が -1 なら、プレフィックス・リストは更新しない。
+					 */
+					prelist_update(pi, rix);	/* プレフィックス・リストを更新する。*/
+					}
+				}
+			pi_off += pi->len << 3;		/* オプション長の単位は 8 バイト */
+			}
+		}
+
+	/* MTU の更新 */
+	if (nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_MTU)]) {
+		T_ND_OPT_MTU_HDR	*optmtuh;
+		uint32_t			mtu;
+
+		optmtuh = (T_ND_OPT_MTU_HDR *)((uint8_t *)(input->buf + off + ROUTER_ADVERT_HDR_SIZE) +
+		                               nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_MTU)] - 8);
+
+		/*
+		 *  値のチェック
+		 *
+		 *    オプション長: 1
+		 *    予約:         0
+		 */
+		if (optmtuh->len != 1 || optmtuh->reserved != 0)
+			goto err_ret;
+
+		/* MTU が IPv6 MMTU（1280 オクテット）以下なら無視する。*/
+		mtu = ntohl(optmtuh->mtu);
+		if (mtu >= IPV6_MMTU) {
+			if (mtu <= (linkmtu > IF_MTU ? linkmtu : IF_MTU))
+				linkmtu = mtu;
+			}
+		}
+
+	/*
+	 *  ルータの始点リンクアドレスを近隣キャッシュに登録する。
+	 */
+	if (nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_SOURCE_LINKADDR)]) {
+		opth = (T_ND_OPT_HDR *)((uint8_t *)(input->buf + off + ROUTER_ADVERT_HDR_SIZE) +
+		                        nd_opt_off[ND_OPT_OFF_ARRAY_IX(ND_OPT_SOURCE_LINKADDR)] - 8);
+	 	/* 注意: オプションオフセット配列には、オフセット + 8 が設定されている。*/
+		lladdr     = (uint8_t *)(opth + 1);
+		lladdr_len = (opth->len << 3);
+		}
+
+	/*
+	 *  ネットワークインタフェースのアドレス長が一致しなければエラー
+	 */
+	if (lladdr && lladdr_len != ((sizeof(T_IF_ADDR) + sizeof(T_ND_OPT_HDR) + 7) & ~7))
+		goto err_ret;
+
+	/* 近隣キャッシュに登録する。*/
+	nd6_cache_lladdr(ifp, &ip6h->src, (T_IF_ADDR *)lladdr, ND_ROUTER_ADVERT, 0);
+
+	/*
+	 *  ルータの始点リンクアドレスを近隣キャッシュに登録したので、
+	 *  オンリンク状態が変化する可能性があるため、それをチェックする。
+	 */
+	pfxlist_onlink_check();
+
+	syscall(rel_net_buf(input));
+	return;
+
+err_ret:
+	NET_COUNT_ICMP6(net_count_nd6[NC_ICMP6_IN_ERR_PACKETS], 1);
+	syscall(rel_net_buf(input));
+
+#else	/* of #if NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+	/*
+	 *  ルータ通知を受信しない場合は、破棄して終了する。
+	 */
+	NET_COUNT_ICMP6(net_count_nd6[NC_ND6_RA_IN_PACKETS], 1);
+	syscall(rel_net_buf(input));
+
+#endif	/* of #if NUM_ND6_DEF_RTR_ENTRY > 0 */
+	}
+
+#if NUM_ND6_RTR_SOL_RETRY > 0
+
+/*
+ *  nd6_rtrsol_ctl -- ルータ要請出力の制御
+ */
+
+void
+nd6_rtrsol_ctl (void)
+{
+	T_IN6_IFADDR	*ifa;
+	int_t		try;
+
+	/* リンクローカルアドレスのアドレス情報を得る。*/
+	if ((ifa = in6ifa_ifpwithix(IF_GET_IFNET(), IPV6_IFADDR_IX_LINKLOCAL)) == NULL)
+		return;
+
+	/* リンクローカルアドレスの重複検出終了を待つ。*/
+	do {
+		/* リンクローカルアドレスの重複検出終了待ち時間を設定する。*/
+		syscall(dly_tsk(net_rand() % TMO_ND6_RTR_SOL_DELAY));
+
+		/* 待っている間に重複が検出されたら終了する。*/
+		if (ifa->flags & IN6_IFF_DUPLICATED)
+			return;
+
+		} while (!((ifa->flags & IN6_IFF_DEFINED) && (ifa->flags & IN6_IFF_TENTATIVE) == 0));
+
+	for (try = 0; try < NUM_ND6_RTR_SOL_RETRY; try ++) {
+
+		/* ディフォルトルータ・リストにエントリがあれば終了 */
+		if (def_router_count > 0)
+			return;
+
+		/* ルータ要請を出力する。*/
+		nd6_rs_output();
+
+		/* 出力の 2 回目以降の遅延時間を設定する。*/
+		syscall(dly_tsk(TMO_ND6_RTR_SOL_INTERVAL));
+		}
+	}
+
+#endif	/* of #if NUM_ND6_RTR_SOL_RETRY > 0 */
+
+/*
+ *  nd6_onlink_prefix_lookup -- プレフィックスを探索する。
+ */
+
+T_ND6_PREFIX *
+nd6_onlink_prefix_lookup (const T_IN6_ADDR *dst)
+{
+	SYSTIM		now;
+	T_ND6_PREFIX	*pr;
+	int_t		ix;
+
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	/* 推奨有効時間内のプレフィックスを探索する。*/
+	for (ix = NUM_ND6_PREFIX_ENTRY; ix -- > 0; ) {
+		pr = &nd6_prefix[ix];
+		if ((pr->flags & ND6_PREFIX_STATE_BUSY)  &&
+		    (pr->flags & ND6_PREFIX_FLAG_ONLINK) &&
+		    in6_are_prefix_equal(dst, &pr->prefix, pr->prefix_len) &&
+		    (int32_t)(pr->preferred - now) > 0) {
+		           /* pr->preferred > now */
+			return pr;
+			}
+		}
+
+	/* 有効時間内のプレフィックスを探索する。*/
+	for (ix = NUM_ND6_PREFIX_ENTRY; ix -- > 0; ) {
+		pr = &nd6_prefix[ix];
+		if ((pr->flags & ND6_PREFIX_STATE_BUSY)  &&
+		    (pr->flags & ND6_PREFIX_FLAG_ONLINK) &&
+		    in6_are_prefix_equal(dst, &pr->prefix, pr->prefix_len) &&
+		    (int32_t)(pr->expire - now) > 0) {
+		           /* pr->expire > now */
+			return pr;
+			}
+		}
+
+	return NULL;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/route6.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/route6.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/route6.c	(revision 398)
@@ -0,0 +1,231 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/route6.c,v 1.6 2002/10/16 01:54:45 sam Exp $	*/
+/*	$KAME: route6.c,v 1.24 2001/03/14 03:07:05 itojun Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/ppp_ipcp.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet6/nd6.h>
+
+#ifdef _IP6_CFG
+
+#if 0
+/*
+ *  通信帯域を食いつぶす攻撃への対応のため、
+ *  タイプ 0 経路制御ヘッダの処理を行わない。
+ */
+
+/*
+ *  ip6_rthdr0 -- タイプ 0 経路制御ヘッダの入力関数
+ */
+
+static ER
+ip6_rthdr0 (T_NET_BUF *input, T_IP6_RT0_HDR *rt0h)
+{
+	if (rt0h->segleft == 0) {
+		/* 中継ノード数は 0 なので、終点ノード */
+		return E_OK;
+		}
+
+	/* len と segleft の正当性チェック */
+#ifdef IP6_CFG_COMPAT_RFC1883
+	if ((rt0h->len % 2) || (rt0h->len > 46)) {
+#else
+	if (rt0h->len % 2) {
+#endif
+		/*
+		 *  len は偶数で、(23 * 2) まで。
+		 *  ただし、(23 * 2) の制限は RFC 2462 で削除されている。
+		 */
+		icmp6_error(input, ICMP6_PARAM_PROB,
+		                   ICMP6_PARAMPROB_HEADER,
+		                   ((uint8_t*)&rt0h->len - input->buf) - IF_HDR_SIZE);
+		return E_PAR;
+		}
+
+	/* len が中継ノード数と矛盾していないかチェックする。*/
+	if ((rt0h->len / 2) < rt0h->segleft) {
+		/*
+		 *  len は 8オクテット単位、segleft は 16オクテット単位なので、
+		 *  len / 2 == segleft となるはず。
+		 *  len / 2 <  segleft はエラー。
+		 */
+		icmp6_error(input, ICMP6_PARAM_PROB,
+		                   ICMP6_PARAMPROB_HEADER,
+		                   ((uint8_t*)&rt0h->segleft - input->buf) - IF_HDR_SIZE);
+		return E_PAR;
+		}
+
+	/*
+	 *  残りの中継ノード数が 1 以上であれば、このノードは最終的な
+	 *  終点ノードではない。本実装では、中継をしないので、
+	 *  入力データグラムの処理を終了する。
+	 */
+	syscall(rel_net_buf(input));
+	return E_PAR;
+	}
+
+#endif
+
+/*
+ *  route6_input -- 経路制御ヘッダの入力関数
+ */
+
+uint_t
+route6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+	T_NET_BUF	*input = *inputp;
+	T_IP6_RT_HDR	*rth;
+	uint_t		len, off = *offp;
+
+	/* ネットワークバッファの残りの長さをチェックする。*/
+	if (input->len - off < sizeof(T_IP6_RT_HDR))
+		goto buf_rel;
+
+	rth = (T_IP6_RT_HDR *)(input->buf + off);
+	len = (rth->len + 1) << 3;
+
+	/* 経路制御ヘッダの長さをチェックする。*/
+	if (input->len < off + len)
+		goto buf_rel;
+
+#if 0
+	/*
+	 *  通信帯域を食いつぶす攻撃への対応のため、
+	 *  タイプ 0 経路制御ヘッダの処理を行わない。
+	 */
+	if (rth->type == IPV6_RTHDR_TYPE_0) {
+		if (ip6_rthdr0(input, (T_IP6_RT0_HDR*)rth) != E_OK) {
+
+			/* エラーの場合は、ip6_rthdr0 でバッファを開放している。*/
+			return IPPROTO_DONE;
+			}
+		}
+	else if (rth->segleft != 0) {
+
+		/*
+		 *  残りの中継ノード数が 1 以上であれば、このノードは最終的な
+		 *  終点ノードではない。本実装では、中継をしないので、
+		 *  ICMP6 エラーを返送して処理を終了する。
+		 */
+		icmp6_error(input, ICMP6_PARAM_PROB,
+		                   ICMP6_PARAMPROB_HEADER,
+		                   ((uint8_t*)&rth->type - input->buf) - IF_HDR_SIZE);
+		return IPPROTO_DONE;
+		}
+#else
+	if (rth->segleft != 0) {
+
+		/*
+		 *  残りの中継ノード数が 1 以上であれば、このノードは最終的な
+		 *  終点ノードではない。本実装では、中継をしないので、
+		 *  ICMP6 エラーを返送して処理を終了する。
+		 */
+		icmp6_error(input, ICMP6_PARAM_PROB,
+		                   ICMP6_PARAMPROB_HEADER,
+		                   ((uint8_t*)&rth->type - input->buf) - IF_HDR_SIZE);
+		return IPPROTO_DONE;
+		}
+#endif
+
+	*nextp = *offp - IF_HDR_SIZE + offsetof(T_IP6_RT_HDR, next);
+	*offp += len;
+	return rth->next;
+
+buf_rel:
+	syscall(rel_net_buf(input));
+	return IPPROTO_DONE;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/scope6.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/scope6.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/scope6.c	(revision 398)
@@ -0,0 +1,174 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*	$FreeBSD: src/sys/netinet6/in6.c,v 1.21 2002/04/19 04:46:22 suz Exp $	*/
+/*	$KAME: in6.c,v 1.259 2002/01/21 11:37:50 keiichi Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ *
+ *	@(#)in.c	8.2 (Berkeley) 11/15/93
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#include <netinet6/in6.h>
+#include <netinet6/in6_var.h>
+
+#ifdef _IP6_CFG
+
+/*
+ *  in6_addrscope -- アドレスのスコープ ID を返す。
+ */
+
+uint_t
+in6_addrscope (const T_IN6_ADDR *addr)
+{
+	uint_t scope;
+
+	if (addr->s6_addr8[0] == 0xfe) {
+		if      ((addr->s6_addr8[1] & 0xc0) == 0x80)
+			return IPV6_ADDR_SCOPE_LINKLOCAL;
+		else if ((addr->s6_addr8[1] & 0xc0) == 0xc0)
+			return IPV6_ADDR_SCOPE_SITELOCAL;
+		else
+			return IPV6_ADDR_SCOPE_GLOBAL;
+		}
+
+	else if (addr->s6_addr8[0] == 0xff) {
+		scope = addr->s6_addr8[1] & 0x0f;
+		if (scope == IPV6_ADDR_SCOPE_NODELOCAL ||
+		    scope == IPV6_ADDR_SCOPE_SITELOCAL ||
+		    scope == IPV6_ADDR_SCOPE_SITELOCAL)
+			return scope;
+		else
+			return IPV6_ADDR_SCOPE_GLOBAL;
+		}
+
+	else if (memcmp(addr, &in6_addr_unspecified, sizeof(T_IN6_ADDR) - 1) == 0) {
+		if      (addr->s6_addr8[15] == 1)
+			return IPV6_ADDR_SCOPE_NODELOCAL;
+		else if (addr->s6_addr8[15] == 0)
+			return IPV6_ADDR_SCOPE_LINKLOCAL;
+		}
+
+	return IPV6_ADDR_SCOPE_GLOBAL;
+	}
+
+#endif /* of #ifdef _IP6_CFG */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/udp6_input.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/udp6_input.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/udp6_input.c	(revision 398)
@@ -0,0 +1,123 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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.
+ */
+
+/*
+ *  udp_reply_no_port -- 送信元にポートが定義されていないことを通知する。
+ */
+
+void
+UDP_REPLY_NO_PORT (T_NET_BUF *input, uint_t off)
+{
+	T_UDP_HDR	*udph;
+
+	udph = (T_UDP_HDR *)(input->buf + off);
+
+#if defined(_IP4_CFG)
+
+	if (GET_IP_VER(input)==IPV6_VERSION) {
+
+		/* マルチキャストアドレスに届いたデータグラムは ICMP エラーを通知しない。*/
+		if (!IN6_IS_ADDR_MULTICAST(&GET_IP6_HDR(input)->dst)) {
+			syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport));
+
+			/* icmp6_error で、ネットワークバッファ input を返却する。*/
+			icmp6_error(input, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
+			}
+		else
+			syscall(rel_net_buf(input));
+		}
+	else /*if (GET_IP_VER(input)==IPV4_VERSION)*/ {
+
+		/* ローカル IP アドレスに届いたデータグラムのみ ICMP エラーを通知する。*/
+		if (ntohl(GET_IP4_HDR(input)->dst) == IF_GET_IFNET()->in4_ifaddr.addr) {
+			syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport));
+
+			icmp_error(ICMP4_UNREACH_PORT, input);
+			/* icmp_error では、ネットワークバッファ input を返却しないので下へ抜ける。*/
+			}
+		syscall(rel_net_buf(input));
+		}
+
+#else	/* of #if defined(_IP4_CFG) */
+
+	NET_COUNT_MIB(udp_stats.udpNoPorts, 1);
+
+	/* マルチキャストアドレスに届いたデータグラムは ICMP エラーを通知しない。*/
+	if (!IN6_IS_ADDR_MULTICAST(&GET_IP6_HDR(input)->dst)) {
+		syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport));
+
+		/* icmp6_error で、ネットワークバッファ input を返却する。*/
+		icmp6_error(input, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
+		}
+	else
+		syscall(rel_net_buf(input));
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+	NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
+	NET_COUNT_MIB(udp_stats.udpInErrors, 1);
+	NET_COUNT_MIB(udp_stats.udpNoPorts, 1);
+	}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/udp6_subr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/udp6_subr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/netinet6/udp6_subr.c	(revision 398)
@@ -0,0 +1,154 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce 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.
+ */
+
+/*
+ *  udp6_is_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
+ *
+ *    以下の場合もデータグラムを受信する。
+ *
+ *      ・あて先アドレスがマルチキャスト
+ */
+
+static bool_t
+udp6_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IP6_HDR	*ip6h;
+
+	ip6h = GET_IP6_HDR(input);
+
+	if (IN6_IS_ADDR_MULTICAST(&ip6h->dst))
+		return true;
+	else
+		return INN6_IS_DSTADDR_ACCEPT(myaddr, input);
+	}
+
+#if defined(_IP4_CFG) && defined(API_CFG_IP4MAPPED_ADDR)
+
+#ifdef DHCP_CFG
+
+/*
+ *  udpn_is_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
+ *
+ *    DHCP_CFG が定義されているときは、以下のデータグラムを受信する。
+ *
+ *      ・あて先アドレスがブロードキャスト
+ *      ・ローカルアドレスが未定義
+ */
+
+static bool_t
+udpn_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IFNET *ifp = IF_GET_IFNET();
+
+	if        (GET_IP_VER(input)==IPV6_VERSION)
+		return udp6_is_dstaddr_accept(myaddr, input);
+	else /*if (GET_IP_VER(input)==IPV4_VERSION)*/ {
+		T_IP4_HDR	*ip4h;
+
+		ip4h = GET_IP4_HDR(input);
+
+		if (ifp->in4_ifaddr.addr == IPV4_ADDRANY    ||
+		    ntohl(ip4h->dst) == IPV4_ADDR_BROADCAST ||
+		    ntohl(ip4h->dst) == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask))
+			return true;
+		else
+			return inn_is_dstaddr_accept(myaddr, input);
+		}
+	}
+
+#else	/* of #ifdef DHCP_CFG */
+
+/*
+ *  udpn_is_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
+ *
+ *    以下の場合もデータグラムを受信する。
+ *
+ *      ・あて先アドレスがブロードキャスト
+ */
+
+static bool_t
+udpn_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IFNET *ifp = IF_GET_IFNET();
+
+	if        (GET_IP_VER(input) == IPV6_VERSION)
+		return udp6_is_dstaddr_accept(myaddr, input);
+	else /*if (GET_IP_VER(input) == IPV4_VERSION)*/ {
+		T_IP4_HDR	*ip4h;
+
+		ip4h = GET_IP4_HDR(input);
+
+		if (ntohl(ip4h->dst) == IPV4_ADDR_BROADCAST ||
+		    ntohl(ip4h->dst) == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask))
+			return true;
+		else
+			return inn_is_dstaddr_accept(myaddr, input);
+		}
+	}
+
+#endif	/* of #ifdef DHCP_CFG */
+
+#endif	/* of #if defined(_IP4_CFG) && defined(API_CFG_IP4MAPPED_ADDR) */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tcpip_api.def
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tcpip_api.def	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tcpip_api.def	(revision 398)
@@ -0,0 +1,12 @@
+TCP_CRE_REP  #tcp4_repid* { .tcp4_repatr { &ipv4addr &portno } }  
+TCP6_CRE_REP #tcp6_repid* { .tcp6_repatr { &ipv6addr &portno } }  
+TCP_CRE_CEP  #tcp4_cepid* { .tcp4_cepatr &sbuf &sbufsz &rbuf &rbufsz &callback }  
+TCP6_CRE_CEP #tcp6_cepid* { .tcp6_cepatr &sbuf &sbufsz &rbuf &rbufsz &callback }  
+UDP_CRE_CEP  #udp4_cepid* { .udp4_cepatr { &ipv4addr &portno } &callback }  
+UDP6_CRE_CEP #udp6_cepid* { .udp6_cepatr { &ipv6addr &portno } &callback }  
+VRID_TCP_REP  #vrid_tcp4_repid*  
+VRID_TCP_CEP  #vrid_tcp4_cepid*  
+VRID_TCP6_REP #vrid_tcp6_repid*  
+VRID_TCP6_CEP #vrid_tcp6_cepid*  
+VRID_UDP_CEP  #vrid_udp4_cepid*  
+VRID_UDP6_CEP #vrid_udp6_cepid*  
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tcpip_sym.def
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tcpip_sym.def	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tcpip_sym.def	(revision 398)
@@ -0,0 +1,82 @@
+TA_HLNG
+TA_TFIFO
+TA_WSGL
+NUM_IPV4ADDR_STR_BUFF
+NUM_IPV4ADDR_STR_BUFF
+NUM_IPV6ADDR_STR_BUFF
+NUM_MACADDR_STR_BUFF
+NUM_MACADDR_STR_BUFF
+TMO_IP4_FRAG_GET_NET_BUF
+TMO_IP6_FRAG_GET_NET_BUF
+TMO_PPP_GET_NET_BUF
+TMO_ARP_GET_NET_BUF
+TMO_TCP_GET_NET_BUF
+TMO_TCP_OUTPUT
+TMO_UDP_OUTPUT
+TMO_ICMP_OUTPUT
+TMO_IGMP_OUTPUT
+TMO_ND6_NS_OUTPUT
+TMO_ND6_NA_OUTPUT
+TMO_ND6_RS_OUTPUT
+TMO_ARP_OUTPUT
+TMO_ND6_RTR_SOL_DELAY
+TMO_ND6_RTR_SOL_INTERVAL
+TMO_IN_REDIRECT
+TCP_OUT_TASK_STACK_SIZE
+UDP_OUT_TASK_STACK_SIZE
+PPP_INPUT_STACK_SIZE
+PPP_OUTPUT_STACK_SIZE
+ETHER_INPUT_STACK_SIZE
+ETHER_OUTPUT_STACK_SIZE
+LOOP_INPUT_STACK_SIZE
+LOOP_OUTPUT_STACK_SIZE
+NET_TIMER_STACK_SIZE
+TCP_OUT_TASK_PRIORITY
+UDP_OUT_TASK_PRIORITY
+PPP_INPUT_PRIORITY
+PPP_OUTPUT_PRIORITY
+ETHER_INPUT_PRIORITY
+ETHER_OUTPUT_PRIORITY
+LOOP_INPUT_PRIORITY
+LOOP_OUTPUT_PRIORITY
+NET_TIMER_PRIORITY
+NUM_DTQ_UDP_RCVQ
+NUM_DTQ_UDP_OUTPUT
+NUM_DTQ_PPP_OUTPUT
+NUM_DTQ_ETHER_OUTPUT
+NUM_DTQ_LOOP_INPUT
+NUM_DTQ_LOOP_OUTPUT
+TCP_REP_FLG_DYNAMIC
+TCP_REP_FLG_VALID
+TCP_CEP_FLG_IPV4
+TCP_CEP_FLG_ACK_NOW
+TCP_CEP_FLG_DEL_ACK
+TCP_CEP_FLG_SENT_FIN
+TCP_CEP_FLG_NEED_SYN
+TCP_CEP_FLG_NEED_FIN
+TCP_CEP_FLG_FORCE
+TCP_CEP_FLG_NO_PUSH
+TCP_CEP_FLG_NO_DELAY
+TCP_CEP_FLG_FORCE_CLEAR
+TCP_CEP_FLG_POST_OUTPUT
+TCP_CEP_FLG_RESERVE_OUTPUT
+TCP_CEP_FLG_DYNAMIC
+TCP_CEP_FLG_VALID
+TCP_CEP_FLG_CLOSE_AFTER_OUTPUT
+TCP_CEP_FLG_RESTORE_NEXT_OUTPUT
+TCP_CEP_FLG_WBCS_NBUF_REQ
+TCP_CEP_FLG_WBCS_MASK
+TCP_CEP_FLG_WBCS_FREE
+TCP_CEP_FLG_WBCS_WOPEN_PEND
+TCP_CEP_FLG_WBCS_NBUF_PEND
+TCP_CEP_FLG_WBCS_NBUF_RSVD
+TCP_CEP_FLG_WBCS_NBUF_READY
+TCP_CEP_FLG_WBCS_SEND_READY
+TCP_CEP_FLG_WBCS_SENT
+TCP_CEP_FLG_WBCS_ACKED
+TCP_CEP_FLG_NOT_CLEAR
+TCP_CEP_EVT_ESTABLISHED
+TCP_CEP_EVT_CLOSED
+TCP_CEP_EVT_SWBUF_READY
+TCP_CEP_EVT_RWBUF_READY
+TCP_CEP_EVT_ALL
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet.trb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet.trb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet.trb	(revision 398)
@@ -0,0 +1,595 @@
+# ======================================================================
+# 
+#   TINET (TCP/IP Protocol Stack)
+# 
+#   Copyright (C) 2001-2007 by Dep. of Computer Science and Engineering
+#                    Tomakomai National College of Technology, JAPAN
+#  
+#   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+#   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+#   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#       スコード中に含まれていること．
+#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#       の無保証規定を掲載すること．
+#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+#       と．
+#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+#       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+#       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+#       免責すること．
+#  
+#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+#   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+#   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+#   の責任を負わない．
+# 
+#   @(#) $Id$
+#  
+# =====================================================================
+
+# =====================================================================
+# tinet_cfg.h の生成
+# =====================================================================
+
+$tinetCfgH = GenFile.new("tinet_cfg.h")
+$tinetCfgH.add("/* tinet_cfg.h */")
+$tinetCfgH.add("#ifndef _TINET_CFG_H_")
+$tinetCfgH.add("#define _TINET_CFG_H_")
+$tinetCfgH.add()
+
+$tinetCfgH.add("#define TNUM_TCP6_REPID	#{$cfgData[:TCP6_CRE_REP].size + $cfgData[:VRID_TCP6_REP].size}")
+$tinetCfgH.add("#define TNUM_TCP4_REPID	#{$cfgData[:TCP_CRE_REP].size + $cfgData[:VRID_TCP_REP].size}")
+$tinetCfgH.add("#define TNUM_TCP_REPID	#{$cfgData[:TCP6_CRE_REP].size + $cfgData[:VRID_TCP6_REP].size + $cfgData[:TCP_CRE_REP].size + $cfgData[:VRID_TCP_REP].size}")
+$tinetCfgH.add()
+
+$tinetCfgH.add("#define TNUM_TCP6_CEPID	#{$cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}")
+$tinetCfgH.add("#define TNUM_TCP4_CEPID	#{$cfgData[:TCP_CRE_CEP].size + $cfgData[:VRID_TCP_CEP].size}")
+$tinetCfgH.add("#define TNUM_TCP_CEPID	#{$cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size + $cfgData[:TCP_CRE_CEP].size + $cfgData[:VRID_TCP_CEP].size}")
+$tinetCfgH.add()
+
+$tinetCfgH.add("#define TNUM_UDP6_CEPID	#{$cfgData[:UDP6_CRE_CEP].size + $cfgData[:VRID_UDP6_CEP].size}")
+$tinetCfgH.add("#define TNUM_UDP4_CEPID	#{$cfgData[:UDP_CRE_CEP].size + $cfgData[:VRID_UDP_CEP].size}")
+$tinetCfgH.add("#define TNUM_UDP_CEPID	#{$cfgData[:UDP6_CRE_CEP].size + $cfgData[:VRID_UDP6_CEP].size + $cfgData[:UDP_CRE_CEP].size + $cfgData[:VRID_UDP_CEP].size}")
+$tinetCfgH.add()
+
+$cfgData[:TCP6_CRE_REP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:tcp6_repid]}	#{params[:tcp6_repid].val}")
+end
+$cfgData[:VRID_TCP6_REP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_tcp6_repid]}	#{params[:vrid_tcp6_repid].val + $cfgData[:TCP6_CRE_REP].size}")
+end
+$cfgData[:TCP_CRE_REP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:tcp4_repid]}	#{params[:tcp4_repid].val + $cfgData[:TCP6_CRE_REP].size + $cfgData[:VRID_TCP6_REP].size}")
+end
+$cfgData[:VRID_TCP_REP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_tcp4_repid]}	#{params[:vrid_tcp4_repid].val + $cfgData[:TCP_CRE_REP].size + $cfgData[:TCP6_CRE_REP].size + $cfgData[:VRID_TCP6_REP].size}")
+end
+$tinetCfgH.add()
+
+$cfgData[:TCP6_CRE_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:tcp6_cepid]}	#{params[:tcp6_cepid].val}")
+end
+$cfgData[:VRID_TCP6_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_tcp6_cepid]}	#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}")
+end
+$cfgData[:TCP_CRE_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:tcp4_cepid]}	#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}")
+end
+$cfgData[:VRID_TCP_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_tcp4_cepid]}	#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}")
+end
+$tinetCfgH.add()
+
+$cfgData[:UDP6_CRE_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:udp6_cepid]}	#{params[:udp6_cepid].val}")
+end
+$cfgData[:VRID_UDP6_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_udp6_cepid]}	#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size}")
+end
+$cfgData[:UDP_CRE_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:udp4_cepid]}	#{params[:udp4_cepid].val + $cfgData[:UDP6_CRE_CEP].size + $cfgData[:VRID_UDP6_CEP].size}")
+end
+$cfgData[:VRID_UDP_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_udp4_cepid]}	#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size + $cfgData[:UDP6_CRE_CEP].size + $cfgData[:VRID_UDP6_CEP].size}")
+end
+$tinetCfgH.add()
+$tinetCfgH.add("#endif /* _TINET_CFG_H_ */")
+
+# =====================================================================
+# tinet_cfg.c の生成
+# =====================================================================
+
+$tinetCfgC = GenFile.new("tinet_cfg.c")
+$tinetCfgC.add(<<EOS)
+/* tinet_cfg.c */
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+#include <tinet_defs.h>
+#include <tinet_config.h>
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+
+EOS
+# 
+#  インクルードディレクティブ（#include）
+# 
+$tinetCfgC.add()
+$tinetCfgC.add("/*")
+$tinetCfgC.add(" *  Include Directives (#include)")
+$tinetCfgC.add(" */")
+$tinetCfgC.add()
+$includeFiles.each do |file|
+  $tinetCfgC.add("#include #{file}")
+end
+
+$tinetCfgC.add()
+$tinetCfgC.add("const ID tmax_tcp_repid = (TMIN_TCP_REPID + TNUM_TCP6_REPID + TNUM_TCP4_REPID - 1);")
+
+$tinetCfgC.add()
+$tinetCfgC.add("#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)")
+$tinetCfgC.add("const ID tmax_tcp6_repid = (TMIN_TCP6_REPID + TNUM_TCP6_REPID - 1);")
+$tinetCfgC.add("const ID tmax_tcp4_repid = (TMIN_TCP4_REPID + TNUM_TCP4_REPID - 1);")
+$tinetCfgC.add("#endif")
+
+$tinetCfgC.add()
+$tinetCfgC.add("const ID tmax_tcp_cepid = (TMIN_TCP_CEPID + TNUM_TCP6_CEPID + TNUM_TCP4_CEPID - 1);")
+
+$tinetCfgC.add()
+$tinetCfgC.add("#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)")
+$tinetCfgC.add("const ID tmax_tcp6_cepid = (TMIN_TCP_CEPID + TNUM_TCP6_CEPID - 1);")
+$tinetCfgC.add("const ID tmax_tcp4_cepid = (TMIN_TCP_CEPID + TNUM_TCP4_CEPID - 1);")
+$tinetCfgC.add("#endif")
+
+$tinetCfgC.add()
+$tinetCfgC.add("const ID tmax_udp_cepid = (TMIN_UDP_CEPID + TNUM_UDP6_CEPID + TNUM_UDP4_CEPID - 1);")
+
+$tinetCfgC.add()
+$tinetCfgC.add("#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)")
+$tinetCfgC.add("const ID tmax_udp6_cepid = (TMIN_UDP6_CEPID + TNUM_UDP6_CEPID - 1);")
+$tinetCfgC.add("const ID tmax_udp4_cepid = (TMIN_UDP4_CEPID + TNUM_UDP4_CEPID - 1);")
+$tinetCfgC.add("#endif")
+
+#	// TCP (IPv6) 受付口
+$sem_tcp_rep_lock_id = 0
+if $cfgData[:TCP6_CRE_REP].size > 0 || $cfgData[:VRID_TCP6_REP].size > 0
+	$tinetCfgC.add()
+	$tinetCfgC.add("T_TCP6_REP tcp6_rep[TNUM_TCP6_REPID] = {")
+	$cfgData[:TCP6_CRE_REP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t#{params[:tcp6_repatr]},")
+			$tinetCfgC.add("\t\t{ #{params[:ipv6addr]}, #{params[:portno]} },")
+		$tinetCfgC.add("#if defined(TCP_CFG_EXTENTIONS)")
+			$tinetCfgC.add("\t\tTCP_REP_FLG_VALID,")
+			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id},")
+		$tinetCfgC.add("#endif")
+			$tinetCfgC.add("\t\t},")
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$cfgData[:VRID_TCP6_REP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t{ IPV6_ADDRANY, TCP_PORTANY },")
+	$tinetCfgC.add("#if defined(TCP_CFG_EXTENTIONS)")
+			$tinetCfgC.add("\t\tTCP_REP_FLG_DYNAMIC,")
+			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id},")
+	$tinetCfgC.add("#endif")
+			$tinetCfgC.add("\t\t},")
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$tinetCfgC.add("\t};")
+end
+
+#	// TCP (IPv4) 受付口
+if $cfgData[:TCP_CRE_REP].size > 0 || $cfgData[:VRID_TCP_REP].size > 0
+	$tinetCfgC.add()
+	$tinetCfgC.add("T_TCP4_REP tcp4_rep[TNUM_TCP4_REPID] = {")
+	$cfgData[:TCP_CRE_REP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t#{params[:tcp4_repatr]},")
+			$tinetCfgC.add("\t\t{ #{params[:ipv4addr]}, #{params[:portno]} },")
+	$tinetCfgC.add("#if defined(TCP_CFG_EXTENTIONS)")
+			$tinetCfgC.add("\t\tTCP_REP_FLG_VALID,")
+			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id},")
+	$tinetCfgC.add("#endif")
+			$tinetCfgC.add("\t\t},")
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$cfgData[:VRID_TCP_REP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t{ IPV4_ADDRANY, TCP_PORTANY },")
+	$tinetCfgC.add("#if defined(TCP_CFG_EXTENTIONS)")
+			$tinetCfgC.add("\t\tTCP_REP_FLG_DYNAMIC,")
+			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id},")
+	$tinetCfgC.add("#endif")
+			$tinetCfgC.add("\t\t},")
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$tinetCfgC.add("\t};")
+end
+
+#	// TCP 通信端点
+if $cfgData[:TCP6_CRE_CEP].size > 0 || $cfgData[:VRID_TCP6_CEP].size > 0 || $cfgData[:TCP_CRE_CEP].size > 0 || $cfgData[:VRID_TCP_CEP].size > 0
+	$tinetCfgC.add()
+	$tinetCfgC.add("T_TCP_CEP tcp_cep[TNUM_TCP6_CEPID + TNUM_TCP4_CEPID] = {")
+	$cfgData[:TCP6_CRE_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t#{params[:tcp6_cepatr]},")
+			$tinetCfgC.add("\t\t(void*)#{params[:sbuf]},")
+			$tinetCfgC.add("\t\t#{params[:sbufsz]},")
+			$tinetCfgC.add("\t\t(void*)#{params[:rbuf]},")
+			$tinetCfgC.add("\t\t#{params[:rbufsz]},")
+			$tinetCfgC.add("\t\t(t_tcp_callback)(FP)#{params[:callback]},")
+			$tinetCfgC.add("\t\tTCP_CEP_FLG_VALID,")
+			$tinetCfgC.add("\t\tSEM_TCP_CEP_LOCK#{params[:tcp6_cepid].val},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_EST#{params[:tcp6_cepid].val},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_SND#{params[:tcp6_cepid].val},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_RCV#{params[:tcp6_cepid].val},")
+			$tinetCfgC.add("\t\t},")
+	end
+	$cfgData[:VRID_TCP6_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t(void*)NULL,")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t(void*)NULL,")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t(t_tcp_callback)(FP)NULL,")
+			$tinetCfgC.add("\t\tTCP_CEP_FLG_DYNAMIC,")
+			$tinetCfgC.add("\t\tSEM_TCP_CEP_LOCK#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_EST#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_SND#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_RCV#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size},")
+			$tinetCfgC.add("\t\t},")
+	end
+	$cfgData[:TCP_CRE_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t#{params[:tcp4_cepatr]},")
+			$tinetCfgC.add("\t\t(void*)#{params[:sbuf]},")
+			$tinetCfgC.add("\t\t#{params[:sbufsz]},")
+			$tinetCfgC.add("\t\t(void*)#{params[:rbuf]},")
+			$tinetCfgC.add("\t\t#{params[:rbufsz]},")
+			$tinetCfgC.add("\t\t(t_tcp_callback)(FP)#{params[:callback]},")
+			$tinetCfgC.add("\t\tTCP_CEP_FLG_VALID|TCP_CEP_FLG_IPV4,")
+			$tinetCfgC.add("\t\tSEM_TCP_CEP_LOCK#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_EST#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_SND#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_RCV#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\t},")
+	end
+	$cfgData[:VRID_TCP_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t(void*)NULL,")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t(void*)NULL,")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t(t_tcp_callback)(FP)NULL,")
+			$tinetCfgC.add("\t\tTCP_CEP_FLG_DYNAMIC|TCP_CEP_FLG_IPV4,")
+			$tinetCfgC.add("\t\tSEM_TCP_CEP_LOCK#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_EST#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_SND#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_RCV#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\t},")
+	end
+		$tinetCfgC.add("\t};")
+end
+
+#	// UDP (IPv6) 通信端点
+if $cfgData[:UDP6_CRE_CEP].size > 0 || $cfgData[:VRID_UDP6_CEP].size > 0
+	$tinetCfgC.add()
+	$tinetCfgC.add("T_UDP6_CEP udp6_cep[TNUM_UDP6_CEPID] = {")
+	$cfgData[:UDP6_CRE_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t#{params[:udp6_cepatr]},")
+			$tinetCfgC.add("\t\t{ #{params[:ipv6addr]}, #{params[:portno]} },")
+			$tinetCfgC.add("\t\t(t_udp_callback)(FP)#{params[:callback]},")
+			$tinetCfgC.add("\t\tUDP_CEP_FLG_VALID,")
+			$tinetCfgC.add("\t\tSEM_UDP6_CEP_LOCK#{params[:udp6_cepid].val},")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tDTQ_UDP6_RCVQ#{params[:udp6_cepid].val},")
+			$tinetCfgC.add("\t\t},")
+	end
+	$cfgData[:VRID_UDP6_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t{ IPV6_ADDRANY, UDP_PORTANY },")
+			$tinetCfgC.add("\t\t(t_udp_callback)(FP)NULL,")
+			$tinetCfgC.add("\t\tUDP_CEP_FLG_DYNAMIC,")
+			$tinetCfgC.add("\t\tSEM_UDP6_CEP_LOCK#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size},")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tDTQ_UDP6_RCVQ#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size},")
+			$tinetCfgC.add("\t\t},")
+	end
+		$tinetCfgC.add("\t};")
+end
+
+#	// UDP (IPv4) 通信端点
+if $cfgData[:UDP_CRE_CEP].size > 0 || $cfgData[:VRID_UDP_CEP].size > 0
+	$tinetCfgC.add()
+	$tinetCfgC.add("T_UDP4_CEP udp4_cep[TNUM_UDP4_CEPID] = {")
+	$cfgData[:UDP_CRE_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t#{params[:udp4_cepatr]},")
+			$tinetCfgC.add("\t\t{ #{params[:ipv4addr]}, #{params[:portno]} },")
+			$tinetCfgC.add("\t\t(t_udp_callback)(FP)#{params[:callback]},")
+			$tinetCfgC.add("\t\tUDP_CEP_FLG_VALID,")
+			$tinetCfgC.add("\t\tSEM_UDP4_CEP_LOCK#{params[:udp4_cepid].val},")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tDTQ_UDP4_RCVQ#{params[:udp4_cepid].val},")
+			$tinetCfgC.add("\t\t},")
+	end
+	$cfgData[:VRID_UDP_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t{ IPV4_ADDRANY, UDP_PORTANY },")
+			$tinetCfgC.add("\t\t(t_udp_callback)(FP)NULL,")
+			$tinetCfgC.add("\t\tUDP_CEP_FLG_DYNAMIC,")
+			$tinetCfgC.add("\t\tSEM_UDP4_CEP_LOCK#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size},")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tDTQ_UDP4_RCVQ#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size},")
+			$tinetCfgC.add("\t\t},")
+	end
+		$tinetCfgC.add("\t};")
+end
+
+# =====================================================================
+# tinet_kern.cfg の生成
+# =====================================================================
+
+#	// TCP (IPv6) 受付口
+$sem_tcp_rep_lock_id = 0
+if $cfgData[:TCP6_CRE_REP].size > 0 || $cfgData[:VRID_TCP6_REP].size > 0
+	$cfgData[:TCP6_CRE_REP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$cfgData[:VRID_TCP6_REP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+end
+
+#	// TCP (IPv4) 受付口
+if $cfgData[:TCP_CRE_REP].size > 0 || $cfgData[:VRID_TCP_REP].size > 0
+	$cfgData[:TCP_CRE_REP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$cfgData[:VRID_TCP_REP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+end
+
+#	// TCP (IPv6) 通信端点
+if $cfgData[:TCP6_CRE_CEP].size > 0 || $cfgData[:VRID_TCP6_CEP].size > 0
+	$cfgData[:TCP6_CRE_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_CEP_LOCK#{params[:tcp6_cepid].val}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_EST#{params[:tcp6_cepid].val}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:tcp6_cepid].val}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_SWBUF_READY, "TCP_CEP_EVT_SWBUF_READY")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:tcp6_cepid].val}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = 0
+		$cfgFileInfo.push(cfgInfo)
+	end
+	$cfgData[:VRID_TCP6_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_CEP_LOCK#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_EST#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_SWBUF_READY, "TCP_CEP_EVT_SWBUF_READY")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = 0
+		$cfgFileInfo.push(cfgInfo)
+	end
+end
+
+#	// TCP (IPv4) 通信端点
+if $cfgData[:TCP_CRE_CEP].size > 0 || $cfgData[:VRID_TCP_CEP].size > 0
+	$cfgData[:TCP_CRE_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_CEP_LOCK#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_EST#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_SWBUF_READY, "TCP_CEP_EVT_SWBUF_READY")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = 0
+		$cfgFileInfo.push(cfgInfo)
+	end
+	$cfgData[:VRID_TCP_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_CEP_LOCK#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_EST#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_SWBUF_READY, "TCP_CEP_EVT_SWBUF_READY")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = 0
+		$cfgFileInfo.push(cfgInfo)
+	end
+end
+
+#	// UDP (IPv6) 通信端点
+if $cfgData[:UDP6_CRE_CEP].size > 0 || $cfgData[:VRID_UDP6_CEP].size > 0
+	$cfgData[:UDP6_CRE_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_UDP6_CEP_LOCK#{params[:udp6_cepid].val}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_DTQ" }
+		cfgInfo["dtqid"] = "DTQ_UDP6_RCVQ#{params[:udp6_cepid].val}"
+		cfgInfo["dtqatr"] = NumStr.new($TA_TFIFO, "TA_TFIFO")
+		cfgInfo["dtqcnt"] = NumStr.new($NUM_DTQ_UDP_RCVQ, "NUM_DTQ_UDP_RCVQ")
+		#cfgInfo["dtqmb"] = NumStr.new($NULL, "NULL")
+		$cfgFileInfo.push(cfgInfo)
+	end
+	$cfgData[:VRID_UDP6_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_UDP6_CEP_LOCK#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_DTQ" }
+		cfgInfo["dtqid"] = "DTQ_UDP6_RCVQ#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size}"
+		cfgInfo["dtqatr"] = NumStr.new($TA_TFIFO, "TA_TFIFO")
+		cfgInfo["dtqcnt"] = NumStr.new($NUM_DTQ_UDP_RCVQ, "NUM_DTQ_UDP_RCVQ")
+		#cfgInfo["dtqmb"] = NumStr.new($NULL, "NULL")
+		$cfgFileInfo.push(cfgInfo)
+	end
+end
+
+#	// UDP (IPv4) 通信端点
+if $cfgData[:UDP_CRE_CEP].size > 0 || $cfgData[:VRID_UDP_CEP].size > 0
+	$cfgData[:UDP_CRE_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_UDP4_CEP_LOCK#{params[:udp4_cepid].val}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_DTQ" }
+		cfgInfo["dtqid"] = "DTQ_UDP4_RCVQ#{params[:udp4_cepid].val}"
+		cfgInfo["dtqatr"] = NumStr.new($TA_TFIFO, "TA_TFIFO")
+		cfgInfo["dtqcnt"] = NumStr.new($NUM_DTQ_UDP_RCVQ, "NUM_DTQ_UDP_RCVQ")
+		#cfgInfo["dtqmb"] = NumStr.new($NULL, "NULL")
+		$cfgFileInfo.push(cfgInfo)
+	end
+	$cfgData[:VRID_UDP_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_UDP4_CEP_LOCK#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_DTQ" }
+		cfgInfo["dtqid"] = "DTQ_UDP4_RCVQ#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size}"
+		cfgInfo["dtqatr"] = NumStr.new($TA_TFIFO, "TA_TFIFO")
+		cfgInfo["dtqcnt"] = NumStr.new($NUM_DTQ_UDP_RCVQ, "NUM_DTQ_UDP_RCVQ")
+		#cfgInfo["dtqmb"] = NumStr.new($NULL, "NULL")
+		$cfgFileInfo.push(cfgInfo)
+	end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_asp.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_asp.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_asp.cfg	(revision 398)
@@ -0,0 +1,78 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TINET の標準システムコンフィギュレーションファイル
+ */
+
+#include "target_sil.h"
+
+#include <itron.h>
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/ppp_var.h>
+#include <net/ether_var.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+
+/*
+ *  TINET プロトコルスタック内部のカーネルオブジェクトの指定
+ */
+
+INCLUDE("nic_asp.cfg");
+
+INCLUDE("net/net_asp.cfg");
+INCLUDE("net/ethernet.cfg");
+
+INCLUDE("netinet/if_ether.cfg");
+INCLUDE("netinet/ip.cfg");
+INCLUDE("netinet/ip_igmp.cfg");
+INCLUDE("netinet/tcp.cfg");
+INCLUDE("netinet/udp.cfg");
+INCLUDE("netinet6/ip6.cfg");
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_asp_configure
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_asp_configure	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_asp_configure	(revision 398)
@@ -0,0 +1,514 @@
+#! /usr/bin/perl
+#
+#   TINET (TCP/IP Protocol Stack)
+#  
+#  Copyright (C) 2001-2003 by Embedded and Real-Time Systems Laboratory
+#                              Toyohashi Univ. of Technology, JAPAN
+#  Copyright (C) 2006-2008 by Embedded and Real-Time Systems Laboratory
+#              Graduate School of Information Science, Nagoya Univ., JAPAN
+#  Copyright (C) 2001-2007 by Dep. of Computer Science and Engineering
+#                   Tomakomai National College of Technology, JAPAN
+# 
+#  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+#  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+#  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+#  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+#      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+#      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+#  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+#      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+#      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+#      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+#      ã¨ï¼
+#    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+#        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+#  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+#      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+#      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+#      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+#      å
+è²¬ãããã¨ï¼
+# 
+#  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+#  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+#  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+#  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+#  ã®è²¬ä»»ãè² ããªãï¼
+# 
+#  @(#) $Id$
+# 
+
+require "getopt.pl";
+
+#  ãªãã·ã§ã³ã®å®ç¾©
+#
+#  -T <target>		ã¿ã¼ã²ããåï¼å¿
+é ï¼
+#  -A <applname>	ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã å
+#  -a <appldir>		ã¢ããªã±ã¼ã·ã§ã³ã®ãã£ã¬ã¯ããªå
+#  -U <applobjs>	ä»ã®ã¢ããªã±ã¼ã·ã§ã³ãã­ã°ã©ã ãã¡ã¤ã«
+#			ï¼.oãã¡ã¤ã«åã§æå®ï¼è¤æ°æå®å¯ï¼
+#  -L <kernel_lib>	ã«ã¼ãã«ã©ã¤ãã©ãªï¼libkernel.aï¼ã®ãã£ã¬ã¯ããªå
+#			ï¼çç¥ããå ´åï¼ã«ã¼ãã«ã©ã¤ãã©ãªãmakeããï¼
+#  -f			ã«ã¼ãã«ãé¢æ°åä½ã§ã³ã³ãã¤ã«ãããã©ããã®æå®
+#  -D <srcdir>		ã«ã¼ãã«ç­ã®ã½ã¼ã¹ã®ç½®ããã¦ãããã£ã¬ã¯ããª
+#  -l <srclang>		ãã­ã°ã©ãã³ã°è¨èªï¼ç¾æç¹ã§ã¯cã¨c++ã®ã¿ãµãã¼ãï¼
+#  -t <templatedir>	ãã³ãã¬ã¼ããã£ã¬ã¯ããªãæå®ï¼ããã©ã«ãã¯tinet/asp_sampleï¼
+#  -d <dbgenv>		å®è¡ç°å¢ã®åç§°
+#  -r			ãã¬ã¼ã¹ã­ã°è¨é²ã®ãµã³ãã«ã³ã¼ããä½¿ç¨ãããã©ããã®æå®
+#  -p <perl>		perlã®ãã¹åï¼æç¤ºçã«æå®ããå ´åï¼
+#  -g <cfg>		ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ï¼cfgï¼ã®ãã¹å
+#  -e <tinetdir>	TINET ã®ã½ã¼ã¹ã®ç½®ããã¦ãããã£ã¬ã¯ããª
+#  -i <net_if>		ãããã¯ã¼ã¯ã¤ã³ã¿ãã§ã¼ã¹ï¼å¿
+é ï¼
+#			etherãpppãloop ã®ä½ãããæå®ããã
+#  -v <net_dev>		ã¤ã¼ãµãããã»ãã£ãã¤ã¹ãã©ã¤ã
+#  			ï¼ãããã¯ã¼ã¯ã¤ã³ã¿ãã§ã¼ã¹ã« ether ãæå®ããå ´åã¯å¿
+é ï¼
+#  -n <net_proto>	ãããã¯ã¼ã¯å±¤ãã­ãã³ã«ï¼å¿
+é ï¼
+#			inet6ãinet4ãinet6/inet4ãinet6mãinet6m/inet4 ã®ä½ãããæå®ããã
+#  -s <trans_proto>	ãã©ã³ã¹ãã¼ãå±¤ãã­ãã³ã«ï¼å¿
+é ï¼
+#			tcpãudpãtcp/udp ã®ä½ãããæå®ããã
+#  -m <asptemplatedir>	ASPãã³ãã¬ã¼ããã£ã¬ã¯ããªãæå®ï¼ããã©ã«ãã¯sampleï¼
+
+#  ä½¿ç¨ä¾(1)
+#
+#  % ../tinet/tinet_asp_configure -T akih8_3069f_gcc -A echos4 -i ether -v if_ed -n inet4 -s tcp
+
+#
+#  ãªãã¸ã§ã¯ããã¡ã¤ã«åã®æ¡å¼µå­ãè¿ã
+#
+sub get_objext {
+	local(@uname);
+
+	use POSIX;
+	@uname = &uname();
+	if ($uname[0] =~ /^cygwin/i) {
+		return("exe");
+	}
+	else {
+		return("");
+	}
+}
+
+#
+#  ãã­ã°ã©ã ã®å ´æãæ¤ç´¢ãã
+#
+sub get_path {
+	local($progname, @pathlist) = @_;
+	local($path);
+
+	foreach $path (@pathlist) {
+		if (-x $path."/".$progname) {
+			return($path."/".$progname);
+		}
+	}
+	return("");
+}
+
+#
+#  Makefile ãå¤æãã
+#
+sub convMakefileSub {
+	local($infile, $outfile) = @_;
+	local($line, $varname, $varval);
+
+	unless (open(INFILE, $infile)) {
+		print STDERR "tinet_asp_configure: can't open $infile\n";
+		exit(1);
+	}
+	unless (open(OUTFILE, ">> ".$outfile)) {
+		print STDERR "tinet_asp_configure: can't open $outfile\n";
+		exit(1);
+	}
+
+	while ($line = <INFILE>) {
+		chop $line;
+		while ($line =~ /^(.*)\@\(([A-Za-z0-9_]+)\)(.*)$/) {
+			$line = $1.$vartable{$2}.$3;
+		}
+		print OUTFILE $line,"\n";
+	}
+
+	close(INFILE);
+	close(OUTFILE);
+}
+
+#
+#  Makefile ãå¤æãã
+#
+sub convMakefile {
+	local($infile, $copyright, $outfile) = @_;
+	local($aspMakefile);
+
+	# Mekfile æãã°ãªãã¼ã ããã
+	print STDERR "tinet_asp_configure: Generating $outfile from $infile.\n";
+	if (-f $outfile) {
+		print STDERR "tinet_asp_configure: $outfile exists.",
+						"  Save as $outfile.bak.\n";
+		rename($outfile, $outfile.".bak");
+	}
+
+	# TINET ã®ã³ãã¼ã©ã¤ããæ¸ãè¾¼ã
+	&convMakefileSub($copyright, $outfile);
+
+	# åºåãã Makefile ããªã¼ãã³ãã
+	unless (open(OUTFILE, ">> ".$outfile)) {
+		print STDERR "tinet_asp_configure: can't open $outfile\n";
+		exit(1);
+	}
+
+	# åç
+§ãã sample/Makefile ããªã¼ãã³ããã
+	$aspMakefile = $aspsampledir."/Makefile";
+	unless (open(ASPFILE, $aspMakefile)) {
+		print STDERR "tinet_asp_configure: can't open $aspMakefile\n";
+		exit(1);
+	}
+
+	# åç
+§ãã sample/Makefile ã®ã³ãã¼ã©ã¤ããèª­ã¿é£ã°ãã
+	while ($line = <ASPFILE>) {
+		chop $line;
+		if ($line !~ /^#/) {
+			print OUTFILE $line,"\n";
+			last;
+		}
+	}
+
+	# 'APPLNAME = @(APPLNAME)' ã®è¡ã¾ã§æ¸ãè¾¼ã
+	while ($line = <ASPFILE>) {
+		chop $line;
+		while ($line =~ /^(.*)\@\(([A-Za-z0-9_]+)\)(.*)$/) {
+			$line = $1.$vartable{$2}.$3;
+		}
+		print OUTFILE $line,"\n";
+		if ($line =~ /^APPLNAME = /) {
+			last;
+		}
+	}
+
+	# '#' åã®è¡ã¾ã§æ¸ãè¾¼ã
+	while ($line = <ASPFILE>) {
+		chop $line;
+		while ($line =~ /^(.*)\@\(([A-Za-z0-9_]+)\)(.*)$/) {
+			$line = $1.$vartable{$2}.$3;
+		}
+		if ($line =~ /^#/) {
+			last;
+		}
+		print OUTFILE $line,"\n";
+	}
+
+	# ä¸åº¦åºåãã Makefile ãã¯ã­ã¼ãºããã
+	close(OUTFILE);
+
+	# TINET ã® Makefile ãæ¸ãè¾¼ã
+	&convMakefileSub($infile, $outfile);
+
+	# ããä¸åº¦åºåãã Makefile ããªã¼ãã³ãã
+	unless (open(OUTFILE, ">> ".$outfile)) {
+		print STDERR "tinet_asp_configure: can't open $outfile\n";
+		exit(1);
+	}
+
+	# åç
+§ãã sample/Makefile ã®æçµè¡ã¾ã§æ¸ãè¾¼ã
+	while ($line = <ASPFILE>) {
+		chop $line;
+		while ($line =~ /^(.*)\@\(([A-Za-z0-9_]+)\)(.*)$/) {
+			$line = $1.$vartable{$2}.$3;
+		}
+		print OUTFILE $line,"\n";
+	}
+
+	close(OUTFILE);
+	close(ASPFILE);
+}
+
+#
+#  Makefile ãçæãã
+#
+sub genMakefile {
+	local($file, $mandatory) = @_;
+	local($path, $copyright);
+
+	$path = $sampledir.$file.".".$applname;
+	$copyright = $sampledir.$file.".copyright";
+	if (-f $path) {
+		&convMakefile($path, $copyright, $file);
+		return;
+	}	
+
+	$path = $sampledir.$file;
+	if ($mandatory || -f $path) {
+		&convMakefile($path, $copyright, $file);
+	}	
+}
+
+#
+#  ãã¡ã¤ã«ãå¤æãã
+#
+sub convert {
+	local($infile, $outfile) = @_;
+	local($line, $varname, $varval);
+
+	print STDERR "tinet_asp_configure: Generating $outfile from $infile.\n";
+	if (-f $outfile) {
+		print STDERR "tinet_asp_configure: $outfile exists.",
+						"  Save as $outfile.bak.\n";
+		rename($outfile, $outfile.".bak");
+	}
+	unless (open(INFILE, $infile)) {
+		print STDERR "tinet_asp_configure: can't open $infile\n";
+		exit(1);
+	}
+	unless (open(OUTFILE, "> ".$outfile)) {
+		print STDERR "tinet_asp_configure: can't open $outfile\n";
+		exit(1);
+	}
+
+	while ($line = <INFILE>) {
+		chop $line;
+		while ($line =~ /^(.*)\@\(([A-Za-z0-9_]+)\)(.*)$/) {
+			$line = $1.$vartable{$2}.$3;
+		}
+		print OUTFILE $line,"\n";
+	}
+
+	close(INFILE);
+	close(OUTFILE);
+}
+
+#
+#  ãµã³ãã«ãè¦ã¤ãã¦ãã¡ã¤ã«ãçæãã
+#
+sub generate {
+	local($file, $mandatory) = @_;
+	local($path);
+
+	$path = $sampledir.$file.".".$applname;
+	if (-f $path) {
+		&convert($path, $file);
+		return;
+	}	
+
+	$path = $sampledir.$file;
+	if ($mandatory || -f $path) {
+		&convert($path, $file);
+	}	
+}
+
+#
+#  ã¡ã¤ã³å¦ç
+#
+#  ãªãã·ã§ã³ã®å¦ç
+#
+&Getopt("TAaULDltdpgiensv");
+
+#
+#  å¤æ°ã®åæå
+#
+$perl = $opt_p ? $opt_p : &get_path("perl", ("/usr/local/bin", "/usr/bin"));
+$target = $opt_T;
+$applname = $opt_A ? $opt_A : "";
+$appldir = $opt_a ? $opt_a : "";
+$applobjs = $opt_U ? $opt_U : "";
+$kernel_lib = $opt_L ? $opt_L : "";
+$kernel_funcobjs = $opt_f ? "true" : "";
+$srclang = $opt_l ? $opt_l : "c";
+$templatedir = $opt_t ? $opt_t : "asp_sample";
+$dbgenv = $opt_d ? "TOPPERS_".$opt_d : "";
+$enable_trace = $opt_r ? "true" : "";
+$net_if = $opt_i;
+$net_dev = $opt_v;
+$net_proto = $opt_n;
+$trans_proto = $opt_s;
+$aspsampledir = $opt_m ? $opt_m : "sample";
+$cfg = $opt_g ? $opt_g : "\$(SRCDIR)/cfg/cfg/cfg";
+$cfgfile = $opt_g ? $opt_g : $srcdir."/cfg/cfg/cfg";
+
+#
+#  ãªãã·ã§ã³ã®ç¢ºèª
+#
+unless ($opt_T) {
+	print STDERR "tinet_asp_configure: -T option is mandatory\n";
+	print STDERR "Installed targets are:\n";
+	foreach $targetname (<$srcdir/target/[a-zA-Z1-9]*>) {
+		$targetname =~ s|$srcdir/target/||;
+		print STDERR "\t$targetname\n";
+	}
+	exit(1);
+}
+unless ($opt_i) {
+	print STDERR "tinet_asp_configure: -i option is mandatory\n";
+	exit(1);
+}
+else {
+	unless ($opt_v) {
+		print STDERR "tinet_asp_configure: -v option is mandatory\n";
+		exit(1);
+	}
+}
+if ($opt_n) {
+	unless ($opt_n eq "inet6" || $opt_n eq "inet4" || $opt_n eq "inet6/inet4" || $opt_n eq "inet6m" || $opt_n eq "inet6m/inet4") {
+		print STDERR "tinet_asp_configure: inet6, inet4, inet6/inet4, inet6m or inet6m/inet4 expected in -n option\n";
+		exit(1);
+	}
+}
+else {
+	print STDERR "tinet_asp_configure: -n option is mandatory\n";
+	exit(1);
+}
+if ($opt_s) {
+	unless ($opt_s eq "tcp" || $opt_s eq "udp" || $opt_s eq "tcp/udp") {
+		print STDERR "tinet_asp_configure: tcp, udp or tcp/udp expected in -s option\n";
+		exit(1);
+	}
+}
+else {
+	print STDERR "tinet_asp_configure: -s option is mandatory\n";
+	exit(1);
+}
+
+#
+#  TINET ã®ã½ã¼ã¹ãã£ã¬ã¯ããªåãåãåºã
+#
+$pwd = `pwd`; chop $pwd;
+if ($opt_e) {
+	$tinetabsdir = $tinetdir = $opt_e;
+}
+elsif ($0 =~ /(.*)\/tinet_asp_configure/) {
+	$tinetdir = $1;
+	if ($tinetdir =~ /^\//) {
+		$tinetabsdir = $tinetdir;
+	}
+	else {
+		$tinetabsdir = $pwd."/".$tinetdir;
+	}
+}
+else {
+	$tinetabsdir = $tinetdir = $pwd;
+}
+$sampledir = $tinetdir."/".$templatedir."/";
+
+#
+#  ã½ã¼ã¹ãã£ã¬ã¯ããªåãåãåºã
+#
+$pwd = `pwd`; chop $pwd;
+if ($opt_D) {
+	$srcabsdir = $srcdir = $opt_D;
+}
+elsif ($0 =~ /(.*)\/tinet\/tinet_asp_configure/) {
+	$srcdir = $1;
+	if ($srcdir =~ /^\//) {
+		$srcabsdir = $srcdir;
+	}
+	else {
+		$srcabsdir = $pwd."/".$srcdir;
+	}
+}
+else {
+	$srcabsdir = $srcdir = $pwd;
+}
+$aspsampledir = $srcdir."/".$aspsampledir;
+
+#
+#  å¤æ°ãã¼ãã«ã®ä½æ
+#
+%vartable = ();
+$vartable{"TARGET"} = $target;
+$vartable{"APPLNAME"} = $applname;
+$vartable{"APPLDIR"} = $appldir;
+$vartable{"APPLOBJS"} = $applobjs;
+$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{"OBJEXT"} = &get_objext();
+$vartable{"PERL"} = $perl;
+$vartable{"CFG"} = $cfg;
+$vartable{"TINETDIR"} = $tinetdir;
+$vartable{"TINETABSDIR"} = $tinetabsdir;
+$vartable{"NET_IF"} = $net_if;
+$vartable{"NET_DEV"} = $net_dev;
+
+#
+#  -n ãªãã·ã§ã³ã®å¦ç
+#
+
+$vartable{"SUPPORT_INET6"} = "#SUPPORT_INET6 = true";
+$vartable{"SUPPORT_INET4"} = "#SUPPORT_INET4 = true";
+if ($net_proto eq "inet6" || $net_proto eq "inet6/inet4" || $net_proto eq "inet6m" || $net_proto eq "inet6m/inet4") {
+	$vartable{"SUPPORT_INET6"} = "SUPPORT_INET6 = true";
+}
+if ($net_proto eq "inet4" || $net_proto eq "inet6/inet4" || $net_proto eq "inet6m/inet4") {
+	$vartable{"SUPPORT_INET4"} = "SUPPORT_INET4 = true";
+}
+
+$vartable{"API_CFG_IP4MAPPED_ADDR"} = "#API_CFG_IP4MAPPED_ADDR = true";
+if ($net_proto eq "inet6m" || $net_proto eq "inet6m/inet4") {
+	$vartable{"API_CFG_IP4MAPPED_ADDR"} = "API_CFG_IP4MAPPED_ADDR = true";
+}
+
+#
+#  -s ãªãã·ã§ã³ã®å¦ç
+#
+
+$vartable{"SUPPORT_TCP"} = "#SUPPORT_TCP = true";
+$vartable{"SUPPORT_UDP"} = "#SUPPORT_UDP = true";
+if ($trans_proto eq "tcp" || $trans_proto eq "tcp/udp") {
+	$vartable{"SUPPORT_TCP"} = "SUPPORT_TCP = true";
+}
+if ($trans_proto eq "udp" || $trans_proto eq "tcp/udp") {
+	$vartable{"SUPPORT_UDP"} = "SUPPORT_UDP = true";
+}
+
+#
+#  ã¿ã¼ã²ãããã£ã¬ã¯ããªã®ãã§ãã¯
+#
+
+if (! -d $srcdir."/target/".$target) {
+	print STDERR "tinet_asp_configure: $srcdir/target/$target not exist\n";
+	exit(1);
+}
+
+#
+#  Makefile ã¨ã¢ããªã±ã¼ã·ã§ã³ãã¡ã¤ã«ã®çæ
+#
+
+&genMakefile("Makefile", 1);
+&generate($applname.".c", 0);
+&generate($applname.".cpp", 0);
+&generate($applname.".h", 0);
+&generate($applname.".cfg", 0);
+&generate("tinet_".$applname.".cfg", 0);
+&generate("route_cfg.c", 0);
+&generate("tinet_app_config.h", 0);
+
+#
+#  cfg ãã§ãã¦ãããã®ãã§ãã¯
+#
+
+if (!(-x ($objext == "" ? $cfgfile : $cfgfile.".".$objext))) {
+	print STDERR "Please compile the configurator (cfg).\n";
+}
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_config.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_config.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_config.h	(revision 398)
@@ -0,0 +1,487 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TINET_CONFIG_H_
+#define _TINET_CONFIG_H_
+
+/*
+ *  TINET 1.2 との互換性のための定義
+ */
+
+/* TCPの受動オープンをサポートする【TINET 1.7 以降不要になった】。*/
+
+#if 0
+#define TCP_CFG_PASSIVE_OPEN
+#endif
+
+/* TCPのノンブロッキングコール機能を組込む。*/
+
+#define TCP_CFG_NON_BLOCKING
+
+/* UDPのノンブロッキングコール機能を組込む。*/
+
+#define UDP_CFG_NON_BLOCKING
+
+/*
+ *  NIC、システム、CPU、応用プログラムに
+ *  依存する定義ファイルをインクルードする。
+ */
+
+#if defined(TARGET_KERNEL_JSP)
+
+#ifdef SUPPORT_ETHER
+
+#include "tinet_nic_config.h"
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#include "tinet_sys_config.h"
+#include "tinet_cpu_config.h"
+#include "tinet_app_config.h"
+
+#elif defined(TARGET_KERNEL_ASP)
+
+#ifdef SUPPORT_ETHER
+
+#include "tinet_nic_config.h"
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#include "tinet_target_config.h"
+#include "tinet_app_config.h"
+
+#endif	/* of #if defined(TARGET_KERNEL_JSP) */
+
+/*
+ *  TINET 1.1 との互換性のための定義
+ */
+
+#ifdef  TMO_ICMP4_OUTPUT
+#define TMO_ICMP_OUTPUT	TMO_ICMP4_OUTPUT
+#endif
+
+/*
+ *  TINET 1.2 との互換性のための定義
+ */
+
+#ifdef  NUM_MPF_NET_BUF_4096
+#define NUM_MPF_NET_BUF_REASSM	NUM_MPF_NET_BUF_4096
+#endif
+
+/*
+ *  TINET 1.3 との互換性のための定義
+
+#ifdef  NUM_MPF_NET_BUF_REASSM
+#define NUM_MPF_NET_BUF4_REASSM	NUM_MPF_NET_BUF_REASSM
+#endif
+ */
+
+/*
+ *  TINET 1.5 との互換性のための定義
+ */
+
+/* ルーティング表のエントリ数の定義 */
+
+#define NUM_IN6_ROUTE_ENTRY			\
+	(NUM_IN6_STATIC_ROUTE_ENTRY + NUM_IN6_REDIRECT_ROUTE_ENTRY)
+					/* ルーティング表のエントリ数	*/
+
+#define NUM_IN4_ROUTE_ENTRY		\
+	(NUM_IN4_STATIC_ROUTE_ENTRY + NUM_IN4_REDIRECT_ROUTE_ENTRY)
+					/* ルーティング表のエントリ数	*/
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+#else	/* #if defined(SUPPORT_INET4) */
+
+#ifndef NUM_IN6_STATIC_ROUTE_ENTRY
+#define NUM_IN6_STATIC_ROUTE_ENTRY	NUM_STATIC_ROUTE_ENTRY
+#endif
+
+#ifndef NUM_IN6_REDIRECT_ROUTE_ENTRY
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	NUM_REDIRECT_ROUTE_ENTRY
+#endif
+
+#ifdef  NUM_ROUTE_ENTRY
+#undef  NUM_ROUTE_ENTRY
+#endif
+#define NUM_ROUTE_ENTRY			NUM_IN6_ROUTE_ENTRY
+
+#endif	/* #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#ifndef NUM_IN4_STATIC_ROUTE_ENTRY
+#define NUM_IN4_STATIC_ROUTE_ENTRY	NUM_STATIC_ROUTE_ENTRY
+#endif
+
+#ifndef NUM_IN4_REDIRECT_ROUTE_ENTRY
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	NUM_REDIRECT_ROUTE_ENTRY
+#endif
+
+#ifdef  NUM_ROUTE_ENTRY
+#undef  NUM_ROUTE_ENTRY
+#endif
+#define NUM_ROUTE_ENTRY			NUM_IN4_ROUTE_ENTRY
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/* DHCP の定義 */
+
+#ifdef  DHCP4_CLI_CFG
+#define DHCP_CFG
+#endif
+
+/*
+ *  IPv6/IPv4 に関する定義
+ */
+
+/*
+ *  指定されたマクロに対する TINET 内部のマクロの定義
+ *
+ *    SUPPORT_INET6		 .   .  ON  ON  ON  ON
+ *    SUPPORT_INET4		ON  ON   .   .  ON  ON
+ *    API_CFG_IP4MAPPED_ADDR	 .  ON   .  ON   .  ON
+ *    ----------------------    ----------------------
+ *    _IP6_CFG                   .   .  ON  ON  ON  ON
+ *    _IP4_CFG                  ON  ON   .  ON  ON  ON
+ *    
+ */
+
+#if !defined(SUPPORT_INET6) && defined(API_CFG_IP4MAPPED_ADDR)
+#error option selection: !defined(SUPPORT_INET6) && defined(API_CFG_IP4MAPPED_ADDR)
+#endif
+
+#if defined(SUPPORT_INET6)
+#define	_IP6_CFG
+#endif
+
+#if defined(SUPPORT_INET4) || (defined(SUPPORT_INET6) && defined(API_CFG_IP4MAPPED_ADDR))
+#define _IP4_CFG
+#endif
+
+/*
+ *  TCP に関する定義
+ */
+
+/*
+ *  MAX_TCP_RCV_SEG: 受信セグメントサイズの最大値
+ *
+ *    注意: 変更すべきではない。
+ */
+
+#ifndef MAX_TCP_RCV_SEG
+#define MAX_TCP_RCV_SEG		(IF_MTU - (IP_HDR_SIZE + TCP_HDR_SIZE))
+#endif
+
+/*
+ *  DEF_TCP_SND_SEG: 送信セグメントサイズの規定値
+ */
+
+#ifndef DEF_TCP_SND_SEG
+#define DEF_TCP_SND_SEG		MAX_TCP_SND_SEG
+#endif
+
+/*
+ *  TCP 通信端点の送受信ウィンドバッファの省コピー機能
+ */
+
+#ifdef  TCP_CFG_SWBUF_CSAVE_ONLY
+#ifndef TCP_CFG_SWBUF_CSAVE
+#define TCP_CFG_SWBUF_CSAVE
+#endif
+#endif	/* of #ifdef  TCP_CFG_SWBUF_CSAVE_ONLY */
+
+#ifdef  TCP_CFG_RWBUF_CSAVE_ONLY
+#ifndef TCP_CFG_RWBUF_CSAVE
+#define TCP_CFG_RWBUF_CSAVE
+#endif
+#endif	/* of #ifdef  TCP_CFG_RWBUF_CSAVE_ONLY */
+
+/*
+ *  TCP_CFG_URG_OFFSET: 緊急データの最後のバイトのオフセット
+ *
+ *    -1: BSD の実装、緊急ポインタは、緊急データの最後のバイトの次のバイトを差す。
+ *     0: RFC1122 の規定、緊急ポインタは、緊急データの最後のバイトを差す。
+ */
+
+#ifndef TCP_CFG_URG_OFFSET
+#define TCP_CFG_URG_OFFSET	-1
+#endif
+
+/*
+ *  ARP に関する定義
+ */
+
+#ifndef ARP_CACHE_KEEP
+#define ARP_CACHE_KEEP		(20*60*NET_TIMER_HZ)	/* ARP キャッシュのタイムアウト	*/
+#endif
+
+/*
+ *  ループバックインタフェースに関する定義
+ */
+
+#ifndef LOMTU
+#define LOMTU			1500	/* ループバックの MTU			*/
+#endif
+
+/*
+ * TINET サポート関数に関する定義
+ */
+
+#ifndef NUM_IPV4ADDR_STR_BUFF		/* ip2str における IP アドレス文字列用バッファ数 */
+
+#if defined(SUPPORT_PPP)
+
+#define NUM_IPV4ADDR_STR_BUFF	2
+
+#else	/* of #if defined(SUPPORT_PPP) */
+
+#define NUM_IPV4ADDR_STR_BUFF	1
+
+#endif	/* of #if defined(SUPPORT_PPP) */
+
+#endif	/* of #ifndef NUM_IPV4ADDR_STR_BUFF */
+
+#ifndef NUM_IPV6ADDR_STR_BUFF
+#define NUM_IPV6ADDR_STR_BUFF	2	/* ip62str における IP アドレス文字列用バッファ数 */
+#endif
+
+#ifndef NUM_MACADDR_STR_BUFF		/* macstr における MAC アドレス文字列用バッファ数 */
+
+#if defined(SUPPORT_INET4) && defined(ETHER_CFG_ACCEPT_ALL) && defined(ETHER_CFG_MCAST_WARNING)
+
+#define NUM_MACADDR_STR_BUFF	2
+
+#else	/* of #if defined(SUPPORT_INET4) && defined(ETHER_CFG_ACCEPT_ALL) && defined(ETHER_CFG_MCAST_WARNING) */
+
+#define NUM_MACADDR_STR_BUFF	1
+
+#endif	/* of #if defined(SUPPORT_INET4) && defined(ETHER_CFG_ACCEPT_ALL) && defined(ETHER_CFG_MCAST_WARNING) */
+
+#endif	/* of #ifndef NUM_MACADDR_STR_BUFF */
+
+/*
+ *  TINET 内部のタイムアウト値の設定
+ */
+
+#ifndef TMO_IP4_FRAG_GET_NET_BUF
+#define TMO_IP4_FRAG_GET_NET_BUF	ULONG_C(1000000)	/* [us]、IPv4 データグラム再構成用ネットワークバッファ獲得タイムアウト	*/
+#endif
+
+#ifndef TMO_IP6_FRAG_GET_NET_BUF
+#define TMO_IP6_FRAG_GET_NET_BUF	ULONG_C(1000000)	/* [us]、IPv6 データグラム再構成用ネットワークバッファ獲得タイムアウト	*/
+#endif
+
+#ifndef TMO_PPP_GET_NET_BUF
+#define TMO_PPP_GET_NET_BUF		ULONG_C(1000000)	/* [us]、PPP 受信用ネットワークバッファ獲得タイムアウト	*/
+#endif
+
+#ifndef TMO_ARP_GET_NET_BUF
+#define TMO_ARP_GET_NET_BUF		ULONG_C(1000000)	/* [us]、ARP のネットワークバッファ獲得タイムアウト	*/
+#endif
+
+#ifndef TMO_TCP_GET_NET_BUF
+#define TMO_TCP_GET_NET_BUF		ULONG_C(1000000)	/* [us]、TCP のネットワークバッファ獲得タイムアウト	*/
+#endif
+
+#ifndef TMO_TCP_OUTPUT
+#define TMO_TCP_OUTPUT			ULONG_C(1000000)	/* [us]、TCP 出力タイムアウト				*/
+#endif
+
+#ifndef TMO_UDP_OUTPUT
+#define TMO_UDP_OUTPUT			ULONG_C(1000000)	/* [us]、UDP 出力タイムアウト				*/
+#endif
+
+#ifndef TMO_ICMP_OUTPUT
+#define TMO_ICMP_OUTPUT			ULONG_C(1000000)	/* [us]、ICMP 出力タイムアウト				*/
+#endif
+
+#ifndef TMO_IGMP_OUTPUT
+#define TMO_IGMP_OUTPUT			ULONG_C(1000000)	/* [us]、IGMP 出力タイムアウト				*/
+#endif
+
+#ifndef TMO_ND6_NS_OUTPUT
+#define TMO_ND6_NS_OUTPUT		ULONG_C(1000000)	/* [us]、近隣要請出力タイムアウト			*/
+#endif
+
+#ifndef TMO_ND6_NA_OUTPUT
+#define TMO_ND6_NA_OUTPUT		ULONG_C(1000000)	/* [us]、近隣通知出力タイムアウト			*/
+#endif
+
+#ifndef TMO_ND6_RS_OUTPUT
+#define TMO_ND6_RS_OUTPUT		ULONG_C(1000000)	/* [us]、ルータ要請出力タイムアウト			*/
+#endif
+
+#ifndef TMO_ARP_OUTPUT
+#define TMO_ARP_OUTPUT			ULONG_C(1000000)	/* [us]、アドレス解決要求出力タイムアウト		*/
+#endif
+
+#ifndef TMO_ND6_RTR_SOL_DELAY
+#define TMO_ND6_RTR_SOL_DELAY		ULONG_C(1000000)	/* [us]、ルータ要請出力遅延				*/
+#endif
+
+#ifndef TMO_ND6_RTR_SOL_INTERVAL
+#define TMO_ND6_RTR_SOL_INTERVAL	ULONG_C(4000000)	/* [us]、ルータ要請出力間隔				*/
+#endif
+
+#ifndef TMO_IN_REDIRECT
+					/* [s]、向け直しルーティングエントリタイムアウト*/
+#define TMO_IN_REDIRECT			(10*60*NET_TIMER_HZ)
+#endif
+
+/*
+ *  TINET 内部のタスクのスタックサイズの設定
+ */
+
+#ifndef TCP_OUT_TASK_STACK_SIZE
+#define	TCP_OUT_TASK_STACK_SIZE	1024	/* TCP 出力タスクのスタックサイズ		*/
+#endif
+
+#ifndef UDP_OUT_TASK_STACK_SIZE
+#define	UDP_OUT_TASK_STACK_SIZE	1024	/* UDP 出力タスクのスタックサイズ			*/
+#endif
+
+#ifndef PPP_INPUT_STACK_SIZE
+#define	PPP_INPUT_STACK_SIZE	1024	/* PPP タスクのスタックサイズ		*/
+#endif
+
+#ifndef PPP_OUTPUT_STACK_SIZE
+#define	PPP_OUTPUT_STACK_SIZE	1024	/* PPP 出力タスクのスタックサイズ		*/
+#endif
+
+#ifndef ETHER_INPUT_STACK_SIZE
+#define	ETHER_INPUT_STACK_SIZE	1024	/* Ethernet 入力タスクのスタックサイズ	*/
+#endif
+
+#ifndef ETHER_OUTPUT_STACK_SIZE
+#define	ETHER_OUTPUT_STACK_SIZE	1024	/* Ethernet 出力タスクのスタックサイズ	*/
+#endif
+
+#ifndef LOOP_INPUT_STACK_SIZE
+#define	LOOP_INPUT_STACK_SIZE	1024	/* ループバック入力タスクのスタックサイズ	*/
+#endif
+
+#ifndef LOOP_OUTPUT_STACK_SIZE
+#define	LOOP_OUTPUT_STACK_SIZE	1024	/* ループバック出力タスクのスタックサイズ	*/
+#endif
+
+#ifndef NET_TIMER_STACK_SIZE
+#define	NET_TIMER_STACK_SIZE	1024	/* ネットワークタイマタスクのスタックサイズ */
+#endif
+
+/*
+ *  TINET 内部のタスクの優先度の設定
+ */
+
+#ifndef TCP_OUT_TASK_PRIORITY
+#define TCP_OUT_TASK_PRIORITY	5	/* TCP 出力タスクの優先度			*/
+#endif
+
+#ifndef UDP_OUT_TASK_PRIORITY
+#define UDP_OUT_TASK_PRIORITY	5	/* UDP 出力タスクの優先度				*/
+#endif
+
+#ifndef PPP_INPUT_PRIORITY
+#define PPP_INPUT_PRIORITY	5	/* PPP タスクの優先度			*/
+#endif
+
+#ifndef PPP_OUTPUT_PRIORITY
+#define PPP_OUTPUT_PRIORITY	5	/* PPP タスクの優先度			*/
+#endif
+
+#ifndef ETHER_INPUT_PRIORITY
+#define ETHER_INPUT_PRIORITY	5	/* Ethernet 入力タスクの優先度		*/
+#endif
+
+#ifndef ETHER_OUTPUT_PRIORITY
+#define ETHER_OUTPUT_PRIORITY	5	/* Ethernet 出力タスクの優先度		*/
+#endif
+
+#ifndef LOOP_INPUT_PRIORITY
+#define LOOP_INPUT_PRIORITY	5	/* ループバック入力タスクの優先度		*/
+#endif
+
+#ifndef LOOP_OUTPUT_PRIORITY
+#define LOOP_OUTPUT_PRIORITY	5	/* ループバック出力タスクの優先度		*/
+#endif
+
+#ifndef NET_TIMER_PRIORITY
+#define NET_TIMER_PRIORITY	5	/* ネットワークタイマタスクの優先度 */
+#endif
+
+/*
+ *  TINET 内部のデータキューのエントリ数の設定
+ */
+
+/* UDP 受信キューサイズ */
+
+#ifndef NUM_DTQ_UDP_RCVQ
+#define NUM_DTQ_UDP_RCVQ	1	/* 非コールバック用	*/
+#endif
+
+#ifndef NUM_DTQ_UDP_OUTPUT
+#define NUM_DTQ_UDP_OUTPUT	1	/* UDP 出力データキューサイズ			*/
+#endif
+
+#ifndef NUM_DTQ_PPP_OUTPUT
+#define NUM_DTQ_PPP_OUTPUT	2	/* PPP 出力データキューサイズ、2 以上	*/
+#endif
+
+#ifndef NUM_DTQ_ETHER_OUTPUT
+#define NUM_DTQ_ETHER_OUTPUT	2	/* Ethernet 出力データキューサイズ	*/
+#endif
+
+#ifndef NUM_DTQ_LOOP_INPUT
+#define NUM_DTQ_LOOP_INPUT	0	/* ループバック入力データキューサイズ	*/
+#endif
+
+#ifndef NUM_DTQ_LOOP_OUTPUT
+#define NUM_DTQ_LOOP_OUTPUT	0	/* ループバック出力データキューサイズ	*/
+#endif
+
+/*
+ *  TINET プロトコルスタック内部のリネーム
+ */
+
+#include <net/net_rename.h>
+#include <netinet/in_rename.h>
+#include <netinet6/in6_rename.h>
+
+#endif /* _TINET_CONFIG_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_defs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_defs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_defs.h	(revision 398)
@@ -0,0 +1,63 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TINET_DEFS_H_
+#define _TINET_DEFS_H_
+
+#include "tinet_kernel_defs.h"
+
+#ifdef SUPPORT_ETHER
+
+#include "tinet_nic_defs.h"
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+/*
+ *  カーネルの識別
+ */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include "tinet_cpu_defs.h"
+
+#else	/* of #ifdef TARGET_KERNEL_JSP */
+
+#ifdef TARGET_KERNEL_ASP
+
+#include "tinet_target_defs.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#endif /* _TINET_DEFS_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_kernel_defs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_kernel_defs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/tinet/tinet_kernel_defs.h	(revision 398)
@@ -0,0 +1,114 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  カーネルに関する互換性定義ファイル
+ */
+
+#ifndef _TINET_KERNEL_DEFS_H_
+#define _TINET_KERNEL_DEFS_H_
+
+#if defined(TARGET_KERNEL_JSP)
+
+#ifndef _MACRO_ONLY
+
+/*
+ *  データ型の定義（inttype.h）
+ */
+
+#ifdef _int8_
+typedef _int8_			int8_t;		/* 符号付き 8 ビット整数 */
+typedef unsigned _int8_		uint8_t;	/* 符号無し 8 ビット整数 */
+#endif	/* of #ifdef _int8_ */
+
+#ifdef _int16_
+typedef _int16_			int16_t;	/* 符号付き 16 ビット整数 */
+typedef unsigned _int16_	uint16_t;	/* 符号無し 16 ビット整数 */
+#endif	/* of #ifdef _int16_ */
+
+#ifdef _int32_
+typedef _int32_			int32_t;	/* 符号付き 32 ビット整数 */
+typedef unsigned _int32_	uint32_t;	/* 符号無し 32 ビット整数 */
+#endif	/* of #ifdef _int32_ */
+
+#ifdef _int64_
+typedef unsigned _int64_	uint64_t;	/* 符号無し 64 ビット整数 */
+#endif	/* of #ifdef _int64_ */
+
+typedef signed int		int_t;		/* 自然なサイズの符号付き整数 */
+typedef unsigned int		uint_t;		/* 自然なサイズの符号無し整数 */
+
+typedef signed long		long_t;		/* 長めのサイズの符号付き整数 */
+typedef unsigned long		ulong_t;	/* 長めのサイズの符号無し整数 */
+
+#ifdef _vp_int_
+typedef _vp_int_		intptr_t;	/* ポインタまたは符号付き整数 */
+#else	/* of #ifdef _vp_int_ */
+typedef VP			intptr_t;	/* ポインタまたは符号付き整数 */
+#endif	/* of #ifdef _vp_int_ */
+
+typedef int			bool_t;		/* 真偽値 */
+
+#ifndef true
+#define true			1		/* 真 */
+#endif /* true */
+
+#ifndef false
+#define false			0		/* 偽 */
+#endif /* false */
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+/* 構造体 structure 中のフィールド field のバイト位置を返すマクロ */
+#ifndef offsetof
+#define offsetof(structure, field) ((size_t) &(((structure *) 0)->field))
+#endif	/* of #ifndef offsetof */
+
+/*
+ *  整数定数を作るマクロ
+ */
+#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 */
+
+#elif defined(TARGET_KERNEL_ASP)
+
+#define syscall(api)		(api)
+
+#endif	/* of #if defined(TARGET_KERNEL_JSP) */
+
+#endif	/* of #ifndef _TINET_KERNEL_DEFS_H_ */
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/applyrename.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/applyrename.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/applyrename.rb	(revision 398)
@@ -0,0 +1,121 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+#
+#  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-2016 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$
+# 
+
+require "fileutils"
+
+#
+#  ファイルにリネームを適用する
+#
+def applyRename(inFileName, syms)
+  symsRegexp = syms.join("|")
+  outFileName = inFileName + ".new"
+
+  begin
+    inFile = File.open(inFileName)
+    outFile = File.open(outFileName, "w")
+  rescue Errno::ENOENT, Errno::EACCES => ex
+    abort(ex.message)
+  end
+
+  inFile.each do |line|
+    line.gsub!(/\b(_?)(#{symsRegexp})\b/, "\\1_kernel_\\2")
+    outFile.print line
+  end
+
+  inFile.close
+  outFile.close
+
+  if FileUtils.cmp(inFileName, outFileName)
+    # ファイルの内容が変化しなかった場合
+    FileUtils.remove(outFileName)
+  else
+    # ファイルの内容が変化した場合
+    FileUtils.move(inFileName, inFileName + ".bak")
+    FileUtils.move(outFileName, inFileName)
+    puts("Modified: #{inFileName}")
+  end
+end
+
+#
+#  エラーチェック
+#
+if ARGV.length < 1
+  abort("Usage: ruby appyrename.rb <prefix> <filelists>")
+end
+
+#
+#  初期化
+#
+syms = []
+name = ARGV.shift
+
+#
+#  シンボルリストを読み込む
+#
+defFileName = name + "_rename.def"
+
+begin
+  defFile = File.open(defFileName)
+rescue Errno::ENOENT, Errno::EACCES => ex
+  abort(ex.message)
+end
+
+defFile.each do |line|
+  line.chomp!
+  if /^#\s*(.*)$/ =~ line
+    # do nothing
+  elsif /^INCLUDE\s+(.*)$/ =~ line
+    # do nothing
+  elsif line != ""
+    syms.push(line)
+  end
+end
+
+#
+#  ファイルにリネームを適用する
+#
+ARGV.each do |inFileName|
+  if inFileName != defFileName && File.readable?(inFileName)
+    applyRename(inFileName, syms)
+  end
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/genrename.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/genrename.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/genrename.rb	(revision 398)
@@ -0,0 +1,183 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+#
+#  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-2016 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$
+# 
+
+#
+#  先頭につける文字列
+#
+def prefixString(sym)
+  if sym =~ /[a-z]/
+    return("_kernel_")
+  else
+    return("_KERNEL_")
+  end
+end
+
+#
+#  リネーム定義を生成する
+#
+def generateDefine(outFile, sym, prefix)
+  outFile.print("#define #{prefix}#{sym}");
+  outFile.print("\t" * [(6 - (sym.length + prefix.length) / 4), 0].max);
+  outFile.print("\t#{prefix}#{prefixString(sym)}#{sym}\n");
+end
+
+#
+#  リネーム解除を生成する
+#
+def generateUndef(outFile, sym, prefix)
+  outFile.print("#undef #{prefix}#{sym}\n");
+end
+
+#
+#  コメントを生成する
+#
+def generateComment(outFile, comment)
+  outFile.print("/*\n")
+  outFile.print(" *  #{comment}\n")
+  outFile.print(" */\n")
+end
+
+#
+#  エラーチェック
+#
+if ARGV.length < 1
+  abort("Usage: ruby genrename.rb <prefix>")
+end
+
+#
+#  初期化
+#
+syms = []
+name = ARGV.shift
+NAME = name.upcase
+
+inFileName = name + "_rename.def"
+headerDefineSymbol = "TOPPERS_" + NAME + "_RENAME_H"
+
+#
+#  シンボルリストを読み込む
+#
+begin
+  inFile = File.open(inFileName)
+rescue Errno::ENOENT, Errno::EACCES => ex
+  abort(ex.message)
+end
+
+inFile.each do |line|
+  syms.push(line.chomp)
+end
+
+#
+#  ???_rename.h を生成する
+#
+begin
+  outFile = File.open(name + "_rename.h", "w")
+rescue Errno::ENOENT, Errno::EACCES => ex
+  abort(ex.message)
+end
+
+outFile.print <<EOS
+/* This file is generated from #{inFileName} by genrename. */
+
+#ifndef #{headerDefineSymbol}
+#define #{headerDefineSymbol}
+
+EOS
+
+includes = ""
+syms.each do |sym|
+  if /^#\s*(.*)$/ =~ sym
+    generateComment(outFile, $1)
+  elsif /^INCLUDE\s+(.*)$/ =~ sym
+    fileName = $1.sub(/([>"])$/, "_rename.h\\1")
+    includes += "#include #{fileName}\n"
+  elsif sym != ""
+    generateDefine(outFile, sym, "")
+  else
+    outFile.print("\n")
+  end
+end
+
+outFile.print <<EOS
+
+#{includes}
+#endif /* #{headerDefineSymbol} */
+EOS
+
+#
+#  ???_unrename.h を生成する
+#
+begin
+  outFile = File.open(name + "_unrename.h", "w")
+rescue Errno::ENOENT, Errno::EACCES => ex
+  abort(ex.message)
+end
+
+outFile.print <<EOS
+/* This file is generated from #{inFileName} by genrename. */
+
+/* This file is included only when #{name}_rename.h has been included. */
+#ifdef #{headerDefineSymbol}
+#undef #{headerDefineSymbol}
+
+EOS
+
+includes = ""
+syms.each do |sym|
+  if /^#\s*(.*)$/ =~ sym
+    generateComment(outFile, $1)
+  elsif /^INCLUDE\s+(.*)$/ =~ sym
+    fileName = $1.sub(/([>"])$/, "_unrename.h\\1")
+    includes += "#include #{fileName}\n"
+  elsif sym != ""
+    generateUndef(outFile, sym, "")
+  else
+    outFile.print("\n")
+  end
+end
+
+outFile.print <<EOS
+
+#{includes}
+#endif /* #{headerDefineSymbol} */
+EOS
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/gentest.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/gentest.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/gentest.rb	(revision 398)
@@ -0,0 +1,472 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2007-2016 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$
+# 
+
+#
+#		テストプログラム生成ツール
+#
+	
+#
+#  生成動作を決めるための設定
+#
+$parameterDefinition = {
+  "get_tst" => { 2 => "STAT" },
+  "get_pri" => { 2 => "PRI" },
+  "get_inf" => { 1 => "intptr_t" },
+  "ref_tsk" => { 2 => "T_RTSK" },
+  "ref_sem" => { 2 => "T_RSEM" },
+  "wai_flg" => { 4 => "FLGPTN" },
+  "pol_flg" => { 4 => "FLGPTN" },
+  "twai_flg" => { 4 => "FLGPTN" },
+  "ref_flg" => { 2 => "T_RFLG" },
+  "rcv_dtq" => { 2 => "intptr_t" },
+  "prcv_dtq" => { 2 => "intptr_t" },
+  "trcv_dtq" => { 2 => "intptr_t" },
+  "ref_dtq" => { 2 => "T_RDTQ" },
+  "rcv_pdq" => { 2 => "intptr_t" , 3 => "PRI" },
+  "prcv_pdq" => { 2 => "intptr_t" , 3 => "PRI" },
+  "trcv_pdq" => { 2 => "intptr_t" , 3 => "PRI" },
+  "ref_pdq" => { 2 => "T_RPDQ" },
+  "ref_mtx" => { 2 => "T_RMTX" },
+  "ref_mbf" => { 2 => "T_RMBF" },
+  "get_mpf" => { 2 => "void *" },
+  "pget_mpf" => { 2 => "void *" },
+  "tget_mpf" => { 2 => "void *" },
+  "ref_mpf" => { 2 => "T_RMPF" },
+  "get_tim" => { 1 => "SYSTIM" },
+  "ref_cyc" => { 2 => "T_RCYC" },
+  "ref_alm" => { 2 => "T_RALM" },
+  "ref_ovr" => { 2 => "T_ROVR" },
+  "get_tid" => { 1 => "ID" },
+  "get_did" => { 1 => "ID" },
+  "get_lod" => { 2 => "uint_t" },
+  "mget_lod" => { 3 => "uint_t" },
+  "get_nth" => { 3 => "ID" },
+  "mget_nth" => { 4 => "ID" },
+  "get_ipm" => { 1 => "PRI" },
+  "get_som" => { 1 => "ID" }
+}
+
+$functionParameters = {
+  "target_hrt_set_event" => "HRTCNT hrtcnt"
+}
+  
+$functionValue = {
+  "target_hrt_get_current" => "HRTCNT"
+}
+  
+$functionReturn = {
+  "target_hrt_get_current" => "0U"
+}
+  
+$functionCheckParameter = {
+  "target_hrt_set_event" => "hrtcnt"
+}
+
+#
+#  処理単位のコードを格納するクラス
+#
+class PUCode
+  # 初期化
+  def initialize(puName)
+    @puName = puName						# 処理単位の名前
+    @currentCount = ""						# 処理カウント
+    @countFlag = false						# 処理カウントが使われたか
+    @code = Hash.new { |h,k| h[k] = [] }	# 処理単位のコード
+    @variableList = {}						# 処理単位の変数
+    @silFlag = false						# SILが使われたか
+
+    # 処理カウント変数名の生成
+    case puName
+    when /^TASK([0-9]*)$/
+      @count_var = "task#{$1}_count"
+    when /^CYC([0-9]*)$/
+      @count_var = "cyclic#{$1}_count"
+    when /^ALM([0-9]*)$/
+      @count_var = "alarm#{$1}_count"
+    when /^OVR$/
+      @count_var = "overrun_count"
+    when /^ISR([0-9]*)$/
+      @count_var = "isr#{$1}_count"
+    when /^INTHDR([0-9]*)$/
+      @count_var = "inthdr#{$1}_count"
+    when /^CPUEXC([0-9]*)$/
+      @count_var = "cpuexc#{$1}_count"
+    when /^EXTSVC([0-9]*)$/
+      @count_var = "extsvc#{$1}_count"
+    else
+      @count_var = puName + "_count"
+    end
+  end
+
+  # 処理カウントの設定
+  def setCount(count)
+    @countFlag = true if count != ""
+    @currentCount = count
+  end
+
+  # 処理カウントのインクリメント
+  def incrementCount
+    if @currentCount != ""
+      @currentCount = (@currentCount.to_i + 1).to_s
+    end
+  end
+
+  # コードの追加
+  def append(*lines)
+    lines.each do |line|
+      @code[@currentCount].push(line)
+        end
+  end
+
+  # 変数の追加
+  def addVariable(varName, typeName)
+    @variableList[varName] = typeName
+  end
+
+  # SILの使用
+  def useSil
+    @silFlag = true
+  end
+
+  # 処理単位のコードの出力
+  def generateCode
+    # 不要な処理単位の判定
+    return if @code.length == 0
+
+    # 処理カウント変数の生成
+    if @countFlag
+      print("\nstatic uint_t\t#{@count_var} = 0;\n")
+    end
+
+    # 関数ヘッダの生成
+    case @puName
+    when /^TASK([0-9]*)$/
+      print("\nvoid\n")
+      print("task#{$1}(intptr_t exinf)\n")
+    when /^CYC([0-9]*)$/
+      print("\nvoid\n")
+      print("cyclic#{$1}_handler(intptr_t exinf)\n")
+    when /^ALM([0-9]*)$/
+      print("\nvoid\n")
+      print("alarm#{$1}_handler(intptr_t exinf)\n")
+    when /^OVR$/
+      print("\nvoid\n")
+      print("overrun_handler(ID tskid, intptr_t exinf)\n")
+    when /^ISR([0-9]*)$/
+      print("\nvoid\n")
+      print("isr#{$1}(intptr_t exinf)\n")
+    when /^INTHDR([0-9]*)$/
+      print("\nvoid\n")
+      print("inthdr#{$1}_handler(void)\n")
+    when /^CPUEXC([0-9]*)$/
+      print("\nvoid\n")
+      print("cpuexc#{$1}_handler(void *p_excinf)\n")
+    when /^EXTSVC([0-9]*)$/
+      print("\nER_UINT\n")
+      print("extsvc#{$1}_routine")
+      print("(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")
+    else
+      if $functionValue[@puName]
+        print("\n#{$functionValue[@puName]}\n")
+      else
+        print("\nvoid\n")
+      end
+      print(@puName)
+      if $functionParameters[@puName]
+        print("(#{$functionParameters[@puName]})\n")
+      else
+        print("(void)\n")
+      end
+    end
+
+    print("{\n")
+
+    @variableList.each do |varName, varType|
+      if /^(.+)\w*\*$/ =~ varType
+        varBaseType = $1
+        print("\t#{varBaseType}")
+        print(varBaseType.length < 4 ? "\t\t*" : "\t*")
+      else
+        print("\t#{varType}")
+        print(varType.length < 4 ? "\t\t" : "\t")
+      end
+      print("#{varName};\n")
+    end
+    if @silFlag
+      print("\tSIL_PRE_LOC;\n")
+    end
+    print("\n")
+
+    if @countFlag
+      print("\tswitch (++#{@count_var}) {\n")
+      @code.keys.sort_by { |c| c.to_i }.each do |count|
+        print("\tcase #{count}:\n")
+        @code[count].each do |line|
+          print("\t",line) if line != ""
+          print("\n")
+        end
+        print("\t\tcheck_point(0);\n\n")
+      end
+      print("\tdefault:\n")
+      print("\t\tcheck_point(0);\n")
+      print("\t}\n")
+    else
+      @code[""].each do |line|
+        print(line,"\n")
+      end
+    end
+
+    print("\tcheck_point(0);\n")
+    if /^EXTSVC([0-9]*)$/ =~ @puName
+      print("\treturn(E_SYS);\n")
+    elsif $functionReturn[@pu_nama]
+      print("\treturn(#{$functionReturn[@puName]});\n")
+    end
+    print("}\n")
+  end
+end
+
+#
+#  サービスコール呼び出しの読み込み
+#
+def genServiceCall(pu, svc_call, error_code)
+  pu.addVariable("ercd", "ER_UINT")
+  pu.append("\tercd = #{svc_call};")
+
+  if /^([a-z_]+)\((.*)\)$/ =~ svc_call
+    svcName = $1;
+    params = $2.split(/\s*,\s*/)
+
+    if $parameterDefinition.has_key?(svcName)
+      $parameterDefinition[svcName].each do |pos, type|
+        if params.size >= pos
+          varName = params[pos - 1].sub(/^\&/, "")
+          pu.addVariable(varName, type)
+        end
+      end
+    end
+  end
+
+  if !error_code
+    # E_OKが返る場合
+    pu.append("\tcheck_ercd(ercd, E_OK);", "")
+  elsif error_code == "noreturn"
+    # リターンしない場合
+    pu.append("")
+  else
+    pu.append("\tcheck_ercd(ercd, #{error_code});", "")
+  end
+end
+
+#
+#  テスト開始コードの生成
+#
+def testStartCode(pu)
+  # テスト開始コードは一度のみ出力する
+  if $startFlag == 0
+    pu.append("\ttest_start(__FILE__);", "")
+    $startFlag = 1
+  end
+end
+
+#
+#  ターゲット依存部関数の振る舞いの読み込み
+#
+def targetFunction(line, checkNum)
+  if /^([a-zA-Z_]+)\s*(.*)$/ =~ line
+    functionName = $1
+    line = $2
+    if (pu = $puList[functionName]).nil?
+      # 新しい処理単位の生成
+      pu = $puList[functionName] = PUCode.new(functionName)
+      pu.setCount("1")
+      testStartCode(pu)
+    end
+  end
+
+  if /\-\>\s*([^\s]+)\s*(.*)$/ =~ line
+    retval = $1
+    line = $2
+  end
+  if /\<\-\s*([^\s]+)\s*(.*)$/ =~ line
+    param = $1
+    line = $2
+  end
+
+  pu.append("\tcheck_point(#{checkNum});");
+  if param && $functionCheckParameter[functionName]
+    pu.append(sprintf("\tcheck_assert(%s == %s);",
+					$functionCheckParameter[functionName], param), "")
+  end
+  if retval
+    pu.append("\treturn(#{retval});", "")
+  else
+    pu.append("\treturn;", "")
+  end
+  pu.incrementCount()
+end
+
+#
+#  テストスクリプトの読み込み
+#
+def parseLine(line)
+  if /^==\s*(([a-zA-Z_]+)[0-9]*)(.*)$/ =~ line
+    # 処理単位の開始
+    $procFlag = 1
+    puName = $1
+    line2 = $3
+    if (pu = $puList[puName]).nil?
+      # 新しい処理単位の生成
+      pu = $puList[puName] = PUCode.new(puName)
+    end
+    $currentPu = pu
+
+    case line2
+    when /^\-([0-9]+)(.*)$/
+      pu.setCount($1)
+    when /^\-[nN](.*)$/
+      # do nothing.
+    else
+      pu.setCount("")
+    end
+    testStartCode(pu) if /^START/ !~ puName
+  elsif $procFlag != 0
+    pu = $currentPu
+    if /^([0-9]+\:)\s*(.*)$/ =~ line
+      # チェックポイント番号の処理
+      originalCheckNum = $1
+      line = $2
+      checkNum = ($lastCheckPoint += 1).to_s
+      $outputLine.sub!(/#{originalCheckNum}/, "#{checkNum}:")
+
+      case line
+      when /^END$/
+        pu.append("\tcheck_finish(#{checkNum});")
+        $procFlag = 0
+        return
+      when /^HOOK\((.*)\)$/
+        pu.append(sprintf("\t#{$1};", checkNum))
+        return
+      when /^\[(.*)\]$/
+        targetFunction($1, checkNum)
+        return
+      else
+        pu.append("\tcheck_point(#{checkNum});")
+      end
+    end
+
+    case line
+    when /^((assert|state|ipm)\(.*\))$/
+      pu.append("\tcheck_#{$1};", "")
+    when /^(call|DO)\((.*)\)$/
+      call_string = $2
+      pu.append("\t#{call_string};", "")
+      pu.useSil() if /^SIL_..._INT\(\)$/ =~ call_string
+    when /^RETURN((\(.*\))?)$/
+      pu.append("\treturn#{$1};", "")
+      pu.incrementCount()
+    when /^GOTO\((.*)\)$/
+      pu.append("\tgoto #{$1};", "")
+    when /^LABEL\((.*)\)$/
+      pu.append("#{$1}:", "")
+    when /^([a-z_]+\(.*\))\s*(\-\>\s*([A-Za-z0-9_]*))?\s*$/
+      genServiceCall(pu, $1, $3)
+    else
+      warn("Error: #{line}")
+    end
+  end
+end
+
+#
+#  エラーチェック
+#
+if ARGV.length < 1
+  abort("Usage: ruby gentest.rb <test_program>")
+end
+
+#
+#  初期化
+#
+inFileName = ARGV.shift
+
+#
+#  スクリプトファイル読み込み処理
+#
+$lastCheckPoint = 0		# 最後のチェックポイント番号
+$procFlag = 0				# スクリプト処理中フラグ
+$startFlag = 0			# テスト開始コードの出力フラグ
+$currentPu = nil			# 読み込み中の処理単位
+$puList = {}				# 処理単位のリスト
+
+begin
+  inFile = File.open(inFileName)
+rescue Errno::ENOENT, Errno::EACCES => ex
+  abort(ex.message)
+end
+
+while line = inFile.gets do
+  $outputLine = line.dup
+  line.chomp!
+  line.sub!(/^\s*\*\s*/, "")
+  line.sub!(/\s*\/\/.*$/, "")
+  line.sub!(/\s*\.\.\..*$/, "")
+
+  while line.sub!(/\\$/, "") do
+    line1 = inFile.gets
+    $outputLine += line1.dup
+    line1.chomp!
+    line1.sub!(/^\s*\*\s*/, "")
+    line1.sub!(/\s*\/\/.*$/, "")
+    line1.sub!(/\s*\.\.\..*$/, "")
+    line += line1
+  end
+  parseLine(line) if line != ""
+  print($outputLine)
+  break if /DO NOT DELETE THIS LINE/ =~ $outputLine
+end
+
+#
+#  テストプログラム出力処理
+#
+$puList.keys.sort.each do |puName|
+  $puList[puName].generateCode()
+end
Index: /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/makerelease.rb
===================================================================
--- /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/makerelease.rb	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/asp3_dcre/utils/makerelease.rb	(revision 398)
@@ -0,0 +1,171 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+#
+#  TOPPERS Software
+#      Toyohashi Open Platform for Embedded Real-Time Systems
+# 
+#  Copyright (C) 2006-2016 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$
+# 
+
+require "shell"
+
+#
+#  ".."を含むパスの整形
+#
+#  例）"yyy/../zzz" → "zzz"
+#  例）"xxx/yyy/../zzz" → "xxx/zzz"
+#
+def canonicalPath(path)
+  while path.sub!(/([^\/]+\/\.\.\/)/, "") do end
+  return(path)
+end
+
+#
+#  ファイルの読み込み
+#
+def readFile(inFileName)
+  baseDirectory = File.dirname(inFileName)
+  if (baseDirectory == ".")
+    baseDirectory = ""
+  else
+    baseDirectory += "/"
+  end
+
+  begin
+    inFile = File.open(inFileName)
+  rescue Errno::ENOENT, Errno::EACCES => ex
+    abort(ex.message)
+  end
+
+  inFile.each do |line|
+    line.chomp!
+    line.sub!(/\s*\#.*$/, "")
+    next if /^\s*$/ =~ line
+
+    if /^E_PACKAGE[ \t]+(.*)$/ =~ line
+      if $package != ""
+        abort("Duplicated E_PACKAGE directive.")
+      else
+        $package = $1
+        $e_package = 1
+      end
+    elsif /^PACKAGE[ \t]+(.*)$/ =~ line
+      if $package != ""
+        if !$e_package && $package != $1
+          abort("Inconsistent PACKAGE directive.")
+        end
+      else
+        $package = $1
+      end
+    elsif /^VERSION[ \t]+(.*)$/ =~ line
+      if $version != ""
+        if !$e_package && $version != $1
+          abort("Inconsistent VERSION directive.")
+        end
+      else
+        $version = $1
+        if /%date/ =~ $version
+          currentTime = Time.now.localtime
+          vdate = sprintf("%04d%02d%02d", currentTime.year,
+									currentTime.month, currentTime.day)
+          $version.sub!(/%date/, vdate)
+        end
+      end
+    elsif /^INCLUDE[ \t]+(.*)$/ =~ line
+      readFile(canonicalPath(baseDirectory + $1))
+    else
+      fileName = $prefix + "/" + canonicalPath(baseDirectory + line)
+      if !File.file?("../" + fileName)
+        abort("#{fileName} is not a file.")
+      elsif $fileList.index(fileName)
+        abort("#{fileName} is duplicated.")
+      else 
+        $fileList.push(fileName)
+      end
+    end
+  end
+end
+
+#
+#  初期化
+#
+$package = ""
+$e_package = 0
+$version = ""
+$fileList = []
+
+#
+#  プリフィックス（./カレントディレクトリ名）の取り出し
+#
+cwd = Shell.new.cwd
+$prefix = "./" + File.basename(cwd)
+
+#
+#  パラメータの取り出し
+#
+if ARGV.length >= 1
+  arg = ARGV.shift.dup
+  arg.sub!(/\/$/, "/MANIFEST")
+  arg.sub!(/^\.\//, "")
+else
+  arg = "MANIFEST"
+end
+
+#
+#  ファイルの読み込み
+#
+readFile(arg)
+if $package == ""
+  abort("PACKAGE/E_PACKAGE directive not found.")
+end
+if $version == ""
+  abort("VERSION directive not found.")
+end
+
+#
+#  RELEASEディレクトリの作成
+#
+if !File.directory?("RELEASE")
+  Dir.mkdir("RELEASE")
+end
+
+#
+#  アーカイブ（.tar.gz）の作成
+#
+archiveName = $package + "-" + $version + ".tar.gz"
+fileListStr = $fileList.join(" ")
+command = "tar cvfz RELEASE/#{archiveName} -C .. #{fileListStr}\n";
+system(command)
+puts("== RELEASE/#{archiveName} is generated. ==\n")
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/.cproject
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/.cproject	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/.cproject	(revision 398)
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1147582331">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1147582331" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings>
+					<externalSetting>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/app_iothub_client"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/azure_iothub"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/app_iothub_client/Debug"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/azure_iothub/Debug"/>
+						<entry flags="RESOLVED" kind="libraryFile" name="app_iothub_client" srcPrefixMapping="" srcRootPath=""/>
+						<entry flags="RESOLVED" kind="libraryFile" name="azure_iothub" srcPrefixMapping="" srcRootPath=""/>
+					</externalSetting>
+				</externalSettings>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="com.renesas.cdt.managedbuild.core.toolchainInfo">
+				<option id="toolchain.id" value="RENESAS_GCC_RX"/>
+				<option id="toolchain.version" value="4.8.4.201803"/>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1147582331" name="Debug" parent="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib">
+					<folderInfo id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1147582331." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib.1204364355" name="GCC for Renesas RX" superClass="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib">
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.1522851200" name="Optimization Level" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.debug" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections.232071790" name="Data sections (-fdata-sections)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.2049562845" name="Debug format" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.Default" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.2140028846" name="Architecture" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture" useByScannerDiscovery="false" value="com.renesas.cdt.managedbuild.gcc.rx.architecture.v1" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability.495364278" name="Architecture Applicability" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability" useByScannerDiscovery="false" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName.284528877" name="DeviceName" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName" useByScannerDiscovery="false" value="R5F563NBDxFP" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand.1123020123" name="DeviceCommand" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand" useByScannerDiscovery="false" value="R5F563NB" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.functionsections.1608575239" name="Function sections (-ffunction-sections)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.64bitdouble.1748526067" name="Make the double data type be 64 bits in size" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.64bitdouble" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize.211865635" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize" useByScannerDiscovery="false" value="100" valueType="string"/>
+							<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.gcc.core.option.debug.otherFlags.540013108" name="Other flags" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.otherFlags" useByScannerDiscovery="false" valueType="stringList">
+								<listOptionValue builtIn="false" value="-nostdinc"/>
+							</option>
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.renesas.cdt.managedbuild.gcc.core.targetPlatform.586655381" isAbstract="false" osList="all" superClass="com.renesas.cdt.managedbuild.gcc.core.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/app_iothub_client}/Debug" id="com.renesas.cdt.managedbuild.gcc.core.builder.2039692157" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GCC for Renesas Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.managedbuild.gcc.core.builder"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen.1941731977" name="Library Generator" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen">
+								<option id="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary.541067605" name="Select Library" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.selectLibrary.newLib" valueType="enumerated"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.rx.option.libraryType.936774991" name="Library type" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.libraryType" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType.preBuilt" valueType="enumerated"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.1209063629" name="Compiler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.149607231" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" useByScannerDiscovery="false" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/arch/gcc}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/arch/rx630_gcc}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/target/gr_sakura_gcc}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/c-utility/inc}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/c-utility/pal/toppers}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/iothub_client/inc}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/iothub_client/inc/internal}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/deps/parson}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/umqtt/inc}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mbedtls-2.16.1/include}&quot;"/>
+								</option>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.source.std.1830375473" name="Language standard" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.source.std" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.compiler.common.gnu99" valueType="enumerated"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.macroDefines.526399039" name="Macro Defines" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.macroDefines" useByScannerDiscovery="false" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="USE_WOLFSSL=1"/>
+								</option>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.1180149000" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler.1418116643" name="Compiler CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.661908907" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" useByScannerDiscovery="false" valueType="includePath"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler.431159709" name="Assembler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler">
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor.1619298191" name="Use preprocessor" superClass="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor" useByScannerDiscovery="false"/>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler.670000795" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.linker.2007197882" name="Linker" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.linker">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.rx.option.linker.archives.archiveSearchDirectories.1948958568" name="Standard archive search directories" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.linker.archives.archiveSearchDirectories" useByScannerDiscovery="false" valueType="stringList"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker.1001918836" name="Linker CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.rx.option.linker.cpp.archives.archiveSearchDirectories.460388117" name="Standard archive search directories" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.linker.cpp.archives.archiveSearchDirectories" useByScannerDiscovery="false" valueType="stringList"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy.1400446087" name="Objcopy" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver.875651585" name="Archiver" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry excluding="adapters/httpapi_curl.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="c-utility"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="certs"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="deps"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="iothub_client"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="umqtt"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="app_iothub_client.com.renesas.cdt.managedbuild.gcc.rx.ui.projectType.lib.173965709" name="static ã©ã¤ãã©ãªã¼" projectType="com.renesas.cdt.managedbuild.gcc.rx.ui.projectType.lib"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<scannerConfigBuildInfo instanceId="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.release.lib.1078548993;com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.release.lib.1078548993.;com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.699345248;com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.2118951029">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1147582331;com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1147582331.;com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.1209063629;com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.1180149000">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+	<storageModule moduleId="refreshScope"/>
+</cproject>
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/.project
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/.project	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/.project	(revision 398)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>azure_iothub</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/agenttime_mbed.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/agenttime_mbed.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/agenttime_mbed.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/adapters/httpapi_compact.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/httpapi_compact.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/httpapi_compact.c	(revision 398)
@@ -0,0 +1,1570 @@
+// 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_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;
+        }
+        /*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];
+}
+
+/*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 = %s)", MU_ENUM_TO_STRING(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 = %s)", MU_ENUM_TO_STRING(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 = %s)", MU_ENUM_TO_STRING(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 = %s)", MU_ENUM_TO_STRING(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 = %s)", MU_ENUM_TO_STRING(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 = %s)", MU_ENUM_TO_STRING(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 = %s)", MU_ENUM_TO_STRING(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_mbedtls/trunk/azure_iothub/c-utility/adapters/platform_toppers.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/platform_toppers.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/platform_toppers.c	(revision 398)
@@ -0,0 +1,65 @@
+/*
+ *  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_mbedtls.h"
+#include "target_syssvc.h"
+
+int platform_init(void)
+{
+	return 0;
+}
+
+const IO_INTERFACE_DESCRIPTION* platform_get_default_tlsio(void)
+{
+	return tlsio_mbedtls_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/ASP3; "TARGET_NAME")");
+}
+
+void platform_deinit(void)
+{
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/socketio_berkeley.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/socketio_berkeley.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/socketio_berkeley.c	(revision 398)
@@ -0,0 +1,1137 @@
+// 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 <netinet/tcp.h>
+#endif
+#include <netdb.h>
+#include <unistd.h>
+#include <fcntl.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 <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+
+#define SOCKET_SUCCESS                 0
+#define INVALID_SOCKET                 -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;
+    void* on_bytes_received_context;
+    void* on_io_error_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];
+} 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_and_initiate_socket_connection(SOCKET_IO_INSTANCE* socket_io_instance)
+{
+    int result;
+    int err;
+
+    struct addrinfo addrInfoHintIp;
+    struct sockaddr_un addrInfoUn;
+    struct sockaddr* connect_addr = NULL;
+    socklen_t connect_addr_len;
+    struct addrinfo* addrInfoIp = NULL;
+
+    if (socket_io_instance->address_type == ADDRESS_TYPE_IP)
+    {
+        char portString[16];
+
+        memset(&addrInfoHintIp, 0, sizeof(addrInfoHintIp));
+        addrInfoHintIp.ai_family = AF_INET;
+        addrInfoHintIp.ai_socktype = SOCK_STREAM;
+
+        sprintf(portString, "%u", socket_io_instance->port);
+        err = getaddrinfo(socket_io_instance->hostname, portString, &addrInfoHintIp, &addrInfoIp);
+        if (err != 0)
+        {
+            LogError("Failure: getaddrinfo failure %d.", err);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            connect_addr = addrInfoIp->ai_addr;
+            connect_addr_len = sizeof(*addrInfoIp->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)
+    {
+        int flags;
+
+        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
+        {
+            err = connect(socket_io_instance->socket, connect_addr, connect_addr_len);
+            if ((err != 0) && (errno != EINPROGRESS))
+            {
+                LogError("Failure: connect failure %d.", errno);
+                result = MU_FAILURE;
+            }
+        }
+    }
+
+    if (addrInfoIp != NULL)
+    {
+        freeaddrinfo(addrInfoIp);
+    }
+
+    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__
+
+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)
+        {
+            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.");
+                free(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.");
+                    singlylinkedlist_destroy(result->pending_io_list);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    result->port = socket_io_config->port;
+                    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);
+        }
+
+        singlylinkedlist_destroy(socket_io_instance->pending_io_list);
+        free(socket_io_instance->hostname);
+        free(socket_io_instance->target_mac_address);
+        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 == 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->io_state = IO_STATE_OPEN;
+            }
+            else
+            {
+                if (socket_io_instance->socket >= SOCKET_SUCCESS)
+                {
+                    close(socket_io_instance->socket);
+                }
+                socket_io_instance->socket = INVALID_SOCKET;
+            }
+        }
+    }
+
+    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 ((send_result < 0) || ((size_t)send_result != 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*/
+                            result = 0;
+                        }
+                        else
+                        {
+                            LogError("Failure: sending socket failed. errno=%d (%s).", errno, strerror(errno));
+                            result = MU_FAILURE;
+                        }
+                    }
+                    else
+                    {
+                        /* queue data */
+                        if (add_pending_io(socket_io_instance, buffer + send_result, size - send_result, 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;
+        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;
+            }
+
+            signal(SIGPIPE, SIG_IGN);
+
+            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);
+        }
+    }
+}
+
+// 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_mbedtls/trunk/azure_iothub/c-utility/adapters/threadapi_toppers.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/threadapi_toppers.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/threadapi_toppers.c	(revision 398)
@@ -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/ASP3 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/ASP3 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(10000);
+	}
+
+	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 * 1000);
+	if (ret != E_OK) {
+		LogError("dly_tsk error. %s", itron_strerror(ret));
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/tickcounter_toppers.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/tickcounter_toppers.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/tickcounter_toppers.c	(revision 398)
@@ -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) / 1000;
+			tick_counter_instance->last_clock_value = now;
+			*current_ms = tick_counter_instance->current_ms;
+			result = 0;
+		}
+	}
+
+	return result;
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/tlsio_mbedtls.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/tlsio_mbedtls.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/tlsio_mbedtls.c	(revision 398)
@@ -0,0 +1,999 @@
+// 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 <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "mbedtls/config.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/error.h"
+#include "mbedtls/certs.h"
+#include "mbedtls/entropy_poll.h"
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/optimize_size.h"
+#include "azure_c_shared_utility/tlsio.h"
+#include "azure_c_shared_utility/tlsio_mbedtls.h"
+#include "azure_c_shared_utility/socketio.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/shared_util_options.h"
+#include "azure_c_shared_utility/threadapi.h"
+
+static const char *const OPTION_UNDERLYING_IO_OPTIONS = "underlying_io_options";
+
+#define HANDSHAKE_TIMEOUT_MS 5000
+#define HANDSHAKE_WAIT_INTERVAL_MS 10
+
+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;
+    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;
+
+    mbedtls_entropy_context entropy;
+    mbedtls_ctr_drbg_context ctr_drbg;
+    mbedtls_ssl_context ssl;
+    mbedtls_ssl_config config;
+    mbedtls_x509_crt trusted_certificates_parsed;
+    mbedtls_ssl_session ssn;
+    char *trusted_certificates;
+
+    char *hostname;
+    mbedtls_x509_crt owncert;
+    mbedtls_pk_context pKey;
+
+    char* x509_certificate;
+    char* x509_private_key;
+
+    int tls_status;
+} TLS_IO_INSTANCE;
+
+typedef enum TLS_STATE_TAG
+{
+    TLS_STATE_NOT_INITIALIZED,
+    TLS_STATE_INITIALIZED,
+    TLS_STATE_CLOSING,
+} TLS_STATE;
+
+static void indicate_error(TLS_IO_INSTANCE *tls_io_instance)
+{
+    if ((tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN) || (tls_io_instance->tlsio_state == TLSIO_STATE_ERROR))
+    {
+        return;
+    }
+    tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
+    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 = 1;
+
+    while (rcv_bytes > 0)
+    {
+        rcv_bytes = mbedtls_ssl_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);
+            }
+        }
+    }
+
+    return result;
+}
+
+static void on_underlying_io_open_complete(void *context, IO_OPEN_RESULT open_result)
+{
+    if (context == NULL)
+    {
+        LogError("Invalid context NULL value passed");
+    }
+    else
+    {
+        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)context;
+        int result = 0;
+
+        if (open_result != IO_OPEN_OK)
+        {
+            xio_close(tls_io_instance->socket_io, NULL, NULL);
+            tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
+            indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
+        }
+        else
+        {
+            tls_io_instance->tlsio_state = TLSIO_STATE_IN_HANDSHAKE;
+
+            do
+            {
+                result = mbedtls_ssl_handshake(&tls_io_instance->ssl);
+            } while (result == MBEDTLS_ERR_SSL_WANT_READ || result == MBEDTLS_ERR_SSL_WANT_WRITE);
+
+            if (result == 0)
+            {
+                tls_io_instance->tlsio_state = TLSIO_STATE_OPEN;
+                indicate_open_complete(tls_io_instance, IO_OPEN_OK);
+            }
+            else
+            {
+                xio_close(tls_io_instance->socket_io, NULL, NULL);
+                tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
+                indicate_open_complete(tls_io_instance, IO_OPEN_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)
+        {
+            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
+    {
+        LogError("NULL value passed in context");
+    }
+}
+
+static void on_underlying_io_error(void *context)
+{
+    if (context == NULL)
+    {
+        LogError("Invalid context NULL value passed");
+    }
+    else
+    {
+        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)context;
+
+        switch (tls_io_instance->tlsio_state)
+        {
+        default:
+        case TLSIO_STATE_NOT_OPEN:
+        case TLSIO_STATE_ERROR:
+            break;
+
+        case TLSIO_STATE_OPENING_UNDERLYING_IO:
+        case TLSIO_STATE_IN_HANDSHAKE:
+            // Existing socket impls are all synchronous close, and this
+            // adapter does not yet support async close.
+            xio_close(tls_io_instance->socket_io, NULL, NULL);
+            tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
+            indicate_open_complete(tls_io_instance, IO_OPEN_ERROR);
+            break;
+
+        case TLSIO_STATE_OPEN:
+            indicate_error(tls_io_instance);
+            break;
+        }
+    }
+}
+
+static void on_underlying_io_close_complete_during_close(void *context)
+{
+    if (context == NULL)
+    {
+        LogError("NULL value passed in context");
+    }
+    else
+    {
+        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)context;
+
+        tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
+
+        if (tls_io_instance->on_io_close_complete != NULL)
+        {
+            tls_io_instance->on_io_close_complete(tls_io_instance->on_io_close_complete_context);
+        }
+    }
+}
+
+static int on_io_recv(void *context, unsigned char *buf, size_t sz)
+{
+    int result;
+    if (context == NULL)
+    {
+        LogError("Invalid context NULL value passed");
+        result = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+    }
+    else
+    {
+        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)context;
+        unsigned char *new_socket_io_read_bytes;
+        int pending = 0;
+
+        while (tls_io_instance->socket_io_read_byte_count == 0)
+        {
+            xio_dowork(tls_io_instance->socket_io);
+
+            if (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN)
+            {
+                break;
+            }
+            else if (tls_io_instance->tlsio_state == TLSIO_STATE_NOT_OPEN ||
+                     tls_io_instance->tlsio_state == TLSIO_STATE_CLOSING ||
+                     tls_io_instance->tlsio_state == TLSIO_STATE_ERROR)
+            {
+                // Underlying io error, exit.
+                return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+            }
+            else
+            {
+                // Handkshake
+                if (tls_io_instance->socket_io_read_byte_count == 0)
+                {
+                    if (pending++ >= HANDSHAKE_TIMEOUT_MS / HANDSHAKE_WAIT_INTERVAL_MS)
+                    {
+                        // The connection is close from server side and no response.
+                        LogError("Tlsio_Failure: encountered unknow connection issue, the connection will be restarted.");
+                        indicate_error(tls_io_instance);
+                        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+                    }
+                    ThreadAPI_Sleep(HANDSHAKE_WAIT_INTERVAL_MS);
+                }
+            }
+        }
+
+        result = tls_io_instance->socket_io_read_byte_count;
+        if (result > (int)sz)
+        {
+            result = sz;
+        }
+
+        if (result > 0)
+        {
+            (void)memcpy((void *)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 ((result == 0) && (tls_io_instance->tlsio_state == TLSIO_STATE_OPEN))
+        {
+            result = MBEDTLS_ERR_SSL_WANT_READ;
+        }
+    }
+    return result;
+}
+
+static int on_io_send(void *context, const unsigned char *buf, size_t sz)
+{
+    int result;
+    if (context == NULL)
+    {
+        LogError("Invalid context NULL value passed");
+        result = 0;
+    }
+    else
+    {
+        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)context;
+
+        if (xio_send(tls_io_instance->socket_io, buf, sz, tls_io_instance->on_send_complete, tls_io_instance->on_send_complete_callback_context) != 0)
+        {
+            indicate_error(tls_io_instance);
+            result = -1;
+        }
+        else
+        {
+            result = sz;
+        }
+    }
+    return result;
+}
+
+static int tlsio_entropy_poll(void *v, unsigned char *output, size_t len, size_t *olen)
+{
+    (void)v;
+    int result = 0;
+    srand((unsigned int)time(NULL));
+    for (uint16_t i = 0; i < len; i++)
+    {
+        output[i] = rand() % 256;
+    }
+    *olen = len;
+    return result;
+}
+
+// Un-initialize mbedTLS
+static void mbedtls_uninit(TLS_IO_INSTANCE *tls_io_instance)
+{
+    if (tls_io_instance->tls_status != TLS_STATE_NOT_INITIALIZED)
+    {
+        // mbedTLS cleanup...
+        mbedtls_ssl_close_notify(&tls_io_instance->ssl);
+        mbedtls_ssl_free(&tls_io_instance->ssl);
+        mbedtls_ssl_config_free(&tls_io_instance->config);
+        mbedtls_x509_crt_free(&tls_io_instance->trusted_certificates_parsed);
+        mbedtls_ctr_drbg_free(&tls_io_instance->ctr_drbg);
+        mbedtls_entropy_free(&tls_io_instance->entropy);
+
+        tls_io_instance->tls_status = TLS_STATE_NOT_INITIALIZED;
+    }
+    else
+    {
+        LogError("Uninitialzing when not previously initialized");
+    }
+}
+
+static void mbedtls_init(TLS_IO_INSTANCE *tls_io_instance)
+{
+    const char* pers = "azure_iot_client";
+    if (tls_io_instance->tls_status != TLS_STATE_INITIALIZED)
+    {
+        if (tls_io_instance->tls_status == TLS_STATE_CLOSING)
+        {
+            // The underlying connection has been closed, so here un-initialize first
+            mbedtls_uninit(tls_io_instance);
+        }
+
+        // mbedTLS initialize...
+        mbedtls_x509_crt_init(&tls_io_instance->trusted_certificates_parsed);
+
+        mbedtls_entropy_init(&tls_io_instance->entropy);
+        // Add a weak entropy source here,avoid some platform doesn't have strong / hardware entropy
+        mbedtls_entropy_add_source(&tls_io_instance->entropy, tlsio_entropy_poll, NULL, MBEDTLS_ENTROPY_MAX_GATHER, MBEDTLS_ENTROPY_SOURCE_WEAK);
+
+        mbedtls_ctr_drbg_init(&tls_io_instance->ctr_drbg);
+        mbedtls_ctr_drbg_seed(&tls_io_instance->ctr_drbg, mbedtls_entropy_func, &tls_io_instance->entropy, (const unsigned char *)pers, strlen(pers));
+
+        mbedtls_ssl_config_init(&tls_io_instance->config);
+        mbedtls_ssl_config_defaults(&tls_io_instance->config, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
+        mbedtls_ssl_conf_rng(&tls_io_instance->config, mbedtls_ctr_drbg_random, &tls_io_instance->ctr_drbg);
+        mbedtls_ssl_conf_authmode(&tls_io_instance->config, MBEDTLS_SSL_VERIFY_REQUIRED);
+        mbedtls_ssl_conf_min_version(&tls_io_instance->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); // v1.2
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+        mbedtls_ssl_conf_renegotiation(&tls_io_instance->config, MBEDTLS_SSL_RENEGOTIATION_ENABLED);
+#endif
+
+        mbedtls_ssl_init(&tls_io_instance->ssl);
+        mbedtls_ssl_set_bio(&tls_io_instance->ssl, tls_io_instance, on_io_send, on_io_recv, NULL);
+        mbedtls_ssl_set_hostname(&tls_io_instance->ssl, tls_io_instance->hostname);
+
+        mbedtls_ssl_session_init(&tls_io_instance->ssn);
+
+        mbedtls_ssl_set_session(&tls_io_instance->ssl, &tls_io_instance->ssn);
+        mbedtls_ssl_setup(&tls_io_instance->ssl, &tls_io_instance->config);
+
+        tls_io_instance->tls_status = TLS_STATE_INITIALIZED;
+    }
+}
+
+CONCRETE_IO_HANDLE tlsio_mbedtls_create(void *io_create_parameters)
+{
+    TLSIO_CONFIG *tls_io_config = (TLSIO_CONFIG *)io_create_parameters;
+    TLS_IO_INSTANCE *result;
+
+    if (tls_io_config == NULL)
+    {
+        LogError("NULL tls_io_config");
+        result = NULL;
+    }
+    else
+    {
+        /* Codes_SRS_TLSIO_MBED_OS5_TLS_99_006: [ The tlsio_mbedtls_create shall return NULL if allocating memory for TLS_IO_INSTANCE failed. ]*/
+        result = calloc(1, sizeof(TLS_IO_INSTANCE));
+        if (result != NULL)
+        {
+            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)
+            {
+                free(result);
+                result = NULL;
+                LogError("Failed getting socket IO interface description.");
+            }
+            else
+            {
+                if (mallocAndStrcpy_s((char **)&result->hostname, tls_io_config->hostname) != 0)
+                {
+                    free(result);
+                    result = NULL;
+                    LogError("Failure allocating hostname.");
+                }
+                else if ((result->socket_io = xio_create(underlying_io_interface, io_interface_parameters)) == NULL)
+                {
+                    LogError("socket xio create failed");
+                    free(result->hostname);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    result->tls_status = TLS_STATE_NOT_INITIALIZED;
+                    mbedtls_init((void*)result);
+
+                    result->tlsio_state = TLSIO_STATE_NOT_OPEN;
+                }
+            }
+        }
+        else
+        {
+            LogError("Failure allocating TLS object");
+        }
+    }
+
+    return result;
+}
+
+void tlsio_mbedtls_destroy(CONCRETE_IO_HANDLE tls_io)
+{
+    if (tls_io != NULL)
+    {
+        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)tls_io;
+
+        mbedtls_uninit(tls_io_instance);
+
+        xio_close(tls_io_instance->socket_io, NULL, NULL);
+
+        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;
+        }
+        xio_destroy(tls_io_instance->socket_io);
+        if (tls_io_instance->hostname != NULL)
+        {
+            free(tls_io_instance->hostname);
+            tls_io_instance->hostname = NULL;
+        }
+        if (tls_io_instance->trusted_certificates != NULL)
+        {
+            free(tls_io_instance->trusted_certificates);
+            tls_io_instance->trusted_certificates = NULL;
+        }
+        if (tls_io_instance->x509_certificate != NULL)
+        {
+            free(tls_io_instance->x509_certificate);
+            tls_io_instance->x509_certificate = NULL;
+        }
+        if (tls_io_instance->x509_private_key != NULL)
+        {
+            free(tls_io_instance->x509_private_key);
+            tls_io_instance->x509_private_key = NULL;
+        }
+        free(tls_io);
+    }
+}
+
+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)
+{
+    int result = 0;
+
+    if (tls_io == NULL)
+    {
+        LogError("Invalid parameter specified tls_io: NULL");
+        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("IO should not be open: %d", tls_io_instance->tlsio_state);
+            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;
+
+            mbedtls_ssl_session_reset(&tls_io_instance->ssl);
+
+            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("Underlying IO open failed");
+                tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
+                result = MU_FAILURE;
+            }
+        }
+    }
+    return result;
+}
+
+int tlsio_mbedtls_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("Invalid parameter specified tls_io: NULL");
+        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("IO should not be closed: %d", tls_io_instance->tlsio_state);
+            result = MU_FAILURE;
+        }
+        else
+        {
+            if (tls_io_instance->tls_status == TLS_STATE_INITIALIZED)
+            {
+                mbedtls_ssl_close_notify(&tls_io_instance->ssl);
+            }
+
+            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_during_close, tls_io_instance) != 0)
+            {
+                LogError("xio_close failed");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+    }
+    return result;
+}
+
+int tlsio_mbedtls_send(CONCRETE_IO_HANDLE tls_io, const void *buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void *callback_context)
+{
+    int result = 0;
+
+    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("Invalid state specified %d", tls_io_instance->tlsio_state);
+            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 = mbedtls_ssl_write(&tls_io_instance->ssl, buffer, size);
+            if (res != (int)size)
+            {
+                LogError("Unexpected data size returned from  mbedtls_ssl_write %d/%d", res, (int)size);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+            tls_io_instance->on_send_complete = NULL;
+            tls_io_instance->on_send_complete_callback_context = NULL;
+        }
+    }
+    return result;
+}
+
+void tlsio_mbedtls_dowork(CONCRETE_IO_HANDLE tls_io)
+{
+    if (tls_io != NULL)
+    {
+        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)tls_io;
+
+        if (tls_io_instance->tlsio_state == TLSIO_STATE_OPENING_UNDERLYING_IO)
+        {
+            xio_dowork(tls_io_instance->socket_io);
+        }
+        else if (tls_io_instance->tlsio_state == TLSIO_STATE_IN_HANDSHAKE || tls_io_instance->tlsio_state == TLSIO_STATE_OPEN)
+        {
+            decode_ssl_received_bytes(tls_io_instance);
+            // Note: no need to call xio_dowork here because it's called in on_io_recv which is the callback function of decode_ssl_received_bytes
+        }
+    }
+}
+
+/*this function will clone an option given by name and value*/
+static void *tlsio_mbedtls_CloneOption(const char *name, const void *value)
+{
+    void *result = NULL;
+    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_UNDERLYING_IO_OPTIONS) == 0)
+        {
+            result = (void *)value;
+        }
+        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 if (strcmp(name, OPTION_X509_ECC_CERT) == 0)
+        {
+            if (mallocAndStrcpy_s((char**)&result, value) != 0)
+            {
+                LogError("unable to mallocAndStrcpy_s x509EccCertificate value");
+                result = NULL;
+            }
+            else
+            {
+                /*return as is*/
+            }
+        }
+        else if (strcmp(name, OPTION_X509_ECC_KEY) == 0)
+        {
+            if (mallocAndStrcpy_s((char**)&result, value) != 0)
+            {
+                LogError("unable to mallocAndStrcpy_s x509EccKey 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_mbedtls_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) ||
+            (strcmp(name, OPTION_X509_ECC_CERT) == 0) ||
+            (strcmp(name, OPTION_X509_ECC_KEY) == 0)
+            )
+        {
+            free((void*)value);
+        }
+        else if (strcmp(name, OPTION_UNDERLYING_IO_OPTIONS) == 0)
+        {
+            OptionHandler_Destroy((OPTIONHANDLER_HANDLE)value);
+        }
+        else
+        {
+            LogError("not handled option : %s", name);
+        }
+    }
+}
+
+int tlsio_mbedtls_setoption(CONCRETE_IO_HANDLE tls_io, const char *optionName, const void *value)
+{
+    int result = 0;
+
+    if (tls_io == NULL || optionName == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)tls_io;
+
+        if (strcmp(OPTION_TRUSTED_CERT, optionName) == 0)
+        {
+            if (tls_io_instance->trusted_certificates != NULL)
+            {
+                // Free the memory if it has been previously allocated
+                free(tls_io_instance->trusted_certificates);
+                tls_io_instance->trusted_certificates = NULL;
+            }
+            if (mallocAndStrcpy_s(&tls_io_instance->trusted_certificates, (const char *)value) != 0)
+            {
+                LogError("unable to mallocAndStrcpy_s");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                int parse_result = mbedtls_x509_crt_parse(&tls_io_instance->trusted_certificates_parsed, (const unsigned char *)value, (int)(strlen(value) + 1));
+                if (parse_result != 0)
+                {
+                    LogInfo("Malformed pem certificate");
+                    result = MU_FAILURE;
+                }
+                else
+                {
+                    mbedtls_ssl_conf_ca_chain(&tls_io_instance->config, &tls_io_instance->trusted_certificates_parsed, NULL);
+                }
+            }
+        }
+        else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0)
+        {
+            if (tls_io_instance->x509_certificate != NULL)
+            {
+                // Free the memory if it has been previously allocated
+                free(tls_io_instance->x509_certificate);
+            }
+
+            if (mallocAndStrcpy_s(&tls_io_instance->x509_certificate, (const char *)value) != 0)
+            {
+                LogError("unable to mallocAndStrcpy_s on certificate");
+                result = MU_FAILURE;
+            }
+            else if (mbedtls_x509_crt_parse(&tls_io_instance->owncert, (const unsigned char *)value, (int)(strlen(value) + 1)) != 0)
+            {
+                LogError("failure parsing certificate");
+                free(tls_io_instance->x509_certificate);
+                result = MU_FAILURE;
+            }
+            else if (tls_io_instance->pKey.pk_info != NULL && mbedtls_ssl_conf_own_cert(&tls_io_instance->config, &tls_io_instance->owncert, &tls_io_instance->pKey) != 0)
+            {
+                LogError("failure calling mbedtls_ssl_conf_own_cert");
+                free(tls_io_instance->x509_certificate);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+        else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0)
+        {
+            if (tls_io_instance->x509_private_key != NULL)
+            {
+                // Free the memory if it has been previously allocated
+                free(tls_io_instance->x509_private_key);
+            }
+
+            if (mallocAndStrcpy_s(&tls_io_instance->x509_private_key, (const char *)value) != 0)
+            {
+                LogError("unable to mallocAndStrcpy_s on private key");
+                result = MU_FAILURE;
+            }
+            else if (mbedtls_pk_parse_key(&tls_io_instance->pKey, (const unsigned char *)value, (int)(strlen(value) + 1), NULL, 0) != 0)
+            {
+                LogError("failure parsing Private Key");
+                free(tls_io_instance->x509_private_key);
+                result = MU_FAILURE;
+            }
+            else if (tls_io_instance->owncert.version > 0 && mbedtls_ssl_conf_own_cert(&tls_io_instance->config, &tls_io_instance->owncert, &tls_io_instance->pKey))
+            {
+                LogError("failure calling mbedtls_ssl_conf_own_cert on cert");
+                free(tls_io_instance->x509_private_key);
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+        else if (strcmp(optionName, OPTION_UNDERLYING_IO_OPTIONS) == 0)
+        {
+            if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, (void*)tls_io_instance->socket_io) != OPTIONHANDLER_OK)
+            {
+                LogError("failed feeding options to underlying I/O instance");
+                result = MU_FAILURE;
+            }
+            else
+            {
+                result = 0;
+            }
+        }
+        else
+        {
+            // tls_io_instance->socket_io is never NULL
+            result = xio_setoption(tls_io_instance->socket_io, optionName, value);
+        }
+    }
+
+    return result;
+}
+
+OPTIONHANDLER_HANDLE tlsio_mbedtls_retrieveoptions(CONCRETE_IO_HANDLE handle)
+{
+    OPTIONHANDLER_HANDLE result = NULL;
+    if (handle == NULL)
+    {
+        LogError("invalid parameter detected: CONCRETE_IO_HANDLE handle=%p", handle);
+        result = NULL;
+    }
+    else
+    {
+        result = OptionHandler_Create(tlsio_mbedtls_CloneOption, tlsio_mbedtls_DestroyOption, tlsio_mbedtls_setoption);
+        if (result == NULL)
+        {
+            LogError("unable to OptionHandler_Create");
+            /*return as is*/
+        }
+        else
+        {
+            /*this layer cares about the certificates*/
+            TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)handle;
+            OPTIONHANDLER_HANDLE underlying_io_options;
+
+            if ((underlying_io_options = xio_retrieveoptions(tls_io_instance->socket_io)) == NULL ||
+                OptionHandler_AddOption(result, OPTION_UNDERLYING_IO_OPTIONS, underlying_io_options) != OPTIONHANDLER_OK)
+            {
+                LogError("unable to save underlying_io options");
+                OptionHandler_Destroy(underlying_io_options);
+                OptionHandler_Destroy(result);
+                result = NULL;
+            }
+            else if (tls_io_instance->trusted_certificates != NULL &&
+                     OptionHandler_AddOption(result, OPTION_TRUSTED_CERT, tls_io_instance->trusted_certificates) != OPTIONHANDLER_OK)
+            {
+                LogError("unable to save TrustedCerts option");
+                OptionHandler_Destroy(result);
+                result = NULL;
+            }
+            else if (&tls_io_instance->owncert != NULL && tls_io_instance->x509_certificate != NULL &&
+                    OptionHandler_AddOption(result, SU_OPTION_X509_CERT, tls_io_instance->x509_certificate) != OPTIONHANDLER_OK)
+            {
+                LogError("unable to save x509certificate option");
+                OptionHandler_Destroy(result);
+                result = NULL;
+            }
+            else if (
+                (&tls_io_instance->pKey != NULL) && tls_io_instance->x509_private_key != NULL &&
+                (OptionHandler_AddOption(result, SU_OPTION_X509_PRIVATE_KEY, tls_io_instance->x509_private_key) != OPTIONHANDLER_OK)
+                )
+            {
+                LogError("unable to save x509privatekey 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_mbedtls_interface_description =
+    {
+        tlsio_mbedtls_retrieveoptions,
+        tlsio_mbedtls_create,
+        tlsio_mbedtls_destroy,
+        tlsio_mbedtls_open,
+        tlsio_mbedtls_close,
+        tlsio_mbedtls_send,
+        tlsio_mbedtls_dowork,
+        tlsio_mbedtls_setoption};
+
+const IO_INTERFACE_DESCRIPTION *tlsio_mbedtls_get_interface_description(void)
+{
+    return &tlsio_mbedtls_interface_description;
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/uniqueid_stub.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/uniqueid_stub.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/adapters/uniqueid_stub.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/agenttime.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/agenttime.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/agenttime.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/azure_base64.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/azure_base64.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/azure_base64.h	(revision 398)
@@ -0,0 +1,83 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+/** @file base64.h
+*    @brief Prototypes for functions related to encoding/decoding
+*    a @c buffer using standard base64 encoding.
+*/
+
+#ifndef BASE64_H
+#define BASE64_H
+
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/buffer_.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+
+/**
+ * @brief    Base64 encodes a buffer and returns the resulting string.
+ *
+ * @param    input    The buffer that needs to be base64 encoded.
+ *
+ *             Base64_Encode takes as a parameter a pointer to a BUFFER. If @p input is @c NULL then
+ *             @c 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
+ *             Base64_Encode returns @c NULL. Otherwise
+ *             @c 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 Base64_Encode_Bytes returns @c NULL
+ *             If @p source is not @c NULL and @p size is zero, then @c Base64_Encode_Bytes produces
+ *             an empty @c STRING_HANDLE. Otherwise, @c Base64_Encode_Bytes produces a
+ *             @c STRING_HANDLE containing the Base64 representation of the buffer. In case of
+ *             any errors, @c 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 /* BASE64_H */
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/buffer_.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/buffer_.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/buffer_.h	(revision 398)
@@ -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 BUFFER_H
+#define BUFFER_H
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/condition.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/condition.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/condition.h	(revision 398)
@@ -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_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/lock.h"
+#include "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/connection_string_parser.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/connection_string_parser.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/connection_string_parser.h	(revision 398)
@@ -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 CONNECTION_STRING_PARSER_H
+#define CONNECTION_STRING_PARSER_H
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+#include "azure_c_shared_utility/map.h" 
+#include "azure_c_shared_utility/strings.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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/consolelogger.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/consolelogger.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/consolelogger.h	(revision 398)
@@ -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 */
+
+    extern 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))
+    extern 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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/const_defines.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/const_defines.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/const_defines.h	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/constbuffer.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/constbuffer.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/constbuffer.h	(revision 398)
@@ -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 CONSTBUFFER_H
+#define CONSTBUFFER_H
+
+#include "azure_c_shared_utility/buffer_.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+/*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);
+
+/*this creates a new constbuffer from a memory area*/
+MOCKABLE_FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_Create, const unsigned char*, source, size_t, size);
+
+/*this creates a new constbuffer from an existing BUFFER_HANDLE*/
+MOCKABLE_FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateFromBuffer, BUFFER_HANDLE, buffer);
+
+MOCKABLE_FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateWithMoveMemory, unsigned char*, source, size_t, size);
+
+MOCKABLE_FUNCTION(, CONSTBUFFER_HANDLE, CONSTBUFFER_CreateWithCustomFree, const unsigned char*, source, size_t, size, CONSTBUFFER_CUSTOM_FREE_FUNC, customFreeFunc, void*, customFreeFuncContext);
+
+MOCKABLE_FUNCTION(, void, CONSTBUFFER_IncRef, CONSTBUFFER_HANDLE, constbufferHandle);
+
+MOCKABLE_FUNCTION(, void, CONSTBUFFER_DecRef, CONSTBUFFER_HANDLE, constbufferHandle);
+
+MOCKABLE_FUNCTION(, const CONSTBUFFER*, CONSTBUFFER_GetContent, CONSTBUFFER_HANDLE, constbufferHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* CONSTBUFFER_H */
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/constmap.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/constmap.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/constmap.h	(revision 398)
@@ -0,0 +1,132 @@
+// 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
+
+#include "azure_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/map.h"
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/crt_abstractions.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/crt_abstractions.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/crt_abstractions.h	(revision 398)
@@ -0,0 +1,132 @@
+// 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
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstdio>
+#include <cstring>
+#include <cerrno>
+#include <cmath>
+extern "C" {
+#else // __cplusplus
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#endif // __cplusplus
+
+#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))
+/*C99 compiler or C11*/
+#define HAS_STDBOOL
+#include <stdbool.h>
+#endif //  ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L))
+#endif // __STDC_VERSION__
+#endif //  _MSC_VER
+
+#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) */
+
+extern int strcpy_s(char* dst, size_t dstSizeInBytes, const char* src);
+extern int strcat_s(char* dst, size_t dstSizeInBytes, const char* src);
+extern int strncpy_s(char* dst, size_t dstSizeInBytes, const char* src, size_t maxCount);
+extern int sprintf_s(char* dst, size_t dstSizeInBytes, const char* format, ...);
+#endif // _MSC_VER || MINGW_HAS_SECURE_API
+
+extern unsigned long long strtoull_s(const char* nptr, char** endPtr, int base);
+extern float strtof_s(const char* nptr, char** endPtr);
+extern 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))
+/*C99 compiler or C11*/
+#define ISNAN isnan
+#else //  ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L))
+#error update this file to contain the latest C standard.
+#endif // ((__STDC_VERSION__  == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L))
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/doublylinkedlist.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/doublylinkedlist.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/doublylinkedlist.h	(revision 398)
@@ -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 DOUBLYLINKEDLIST_H
+#define DOUBLYLINKEDLIST_H
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#endif
+
+#include <stdint.h>
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gb_rand.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gb_rand.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gb_rand.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gb_stdio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gb_stdio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gb_stdio.h	(revision 398)
@@ -0,0 +1,69 @@
+// 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
+#include <stdio.h>
+#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
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+
+#ifdef __cplusplus
+#include <cstdio.h>
+extern "C"
+{
+#else
+#include <stdio.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gb_time.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gb_time.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gb_time.h	(revision 398)
@@ -0,0 +1,57 @@
+// 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
+#include <time.h>
+#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.h>
+extern "C"
+{
+#else
+#include <time.h>
+#endif
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gballoc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gballoc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gballoc.h	(revision 398)
@@ -0,0 +1,86 @@
+// 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
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdlib>
+extern "C"
+{
+#else
+#include <stddef.h>
+#include <stdlib.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gbnetwork.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gbnetwork.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/gbnetwork.h	(revision 398)
@@ -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.
+
+#ifndef GBNETWORK_H
+#define GBNETWORK_H
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdlib>
+#include <cstdint>
+extern "C"
+{
+#else
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#endif
+
+#ifdef WIN32
+    #include <winsock2.h>
+#else
+    #include <sys/socket.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/hmac.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/hmac.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/hmac.h	(revision 398)
@@ -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.
+
+#ifndef HMAC_H
+#define HMAC_H
+
+#include "azure_c_shared_utility/sha.h"
+#include "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/hmacsha256.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/hmacsha256.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/hmacsha256.h	(revision 398)
@@ -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 HMACSHA256_H
+#define HMACSHA256_H
+
+#include "azure_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/http_proxy_io.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/http_proxy_io.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/http_proxy_io.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpapi.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpapi.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpapi.h	(revision 398)
@@ -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.
+
+/** @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
+
+#include "azure_c_shared_utility/httpheaders.h"
+#include "azure_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpapiex.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpapiex.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpapiex.h	(revision 398)
@@ -0,0 +1,106 @@
+// 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
+
+#include "azure_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/httpapi.h"
+#include "azure_c_shared_utility/umock_c_prod.h"
+ 
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#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	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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpapiexsas.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpapiexsas.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpapiexsas.h	(revision 398)
@@ -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 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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpheaders.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpheaders.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/httpheaders.h	(revision 398)
@@ -0,0 +1,158 @@
+// 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
+
+#include "azure_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/lock.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/lock.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/lock.h	(revision 398)
@@ -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_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/macro_utils.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/macro_utils.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/macro_utils.h	(revision 398)
@@ -0,0 +1,11604 @@
+// 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.tt */
+
+#ifndef MACRO_UTILS_H
+#define MACRO_UTILS_H
+
+#include <string.h>
+#include <stddef.h>
+#include "azure_c_shared_utility/optimize_size.h"
+
+/*"pointer or NULL" macro - because when printf-ing arguments NULL is not valid for %p or %s (section 7.1.4 of C11 standard) */
+#define MU_P_OR_NULL(p) (((p)!=NULL)?(p):"NULL")
+
+#define MU_TOSTRING_(x) #x
+#define MU_TOSTRING(x) MU_TOSTRING_(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_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_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_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_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_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
+
+#define MU_TRIGGER_PARENTHESIS(...) ,
+
+#define MU_LPAREN (
+
+#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_DISPTACH_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_DISPTACH_EMPTY_1000 1
+#define MU_DISPTACH_EMPTY_0000 0
+#define MU_DISPTACH_EMPTY_1100 0
+#define MU_DISPTACH_EMPTY_1111 0
+#define MU_DISPTACH_EMPTY_1001 0
+#define MU_DISPTACH_EMPTY_1010 0
+
+
+#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
+
+
+#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_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__) \
+DO_0(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_2(MACRO, ...) \
+MACRO(2, __VA_ARGS__) \
+DO_1(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_3(MACRO, ...) \
+MACRO(3, __VA_ARGS__) \
+DO_2(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_4(MACRO, ...) \
+MACRO(4, __VA_ARGS__) \
+DO_3(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_5(MACRO, ...) \
+MACRO(5, __VA_ARGS__) \
+DO_4(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_6(MACRO, ...) \
+MACRO(6, __VA_ARGS__) \
+DO_5(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_7(MACRO, ...) \
+MACRO(7, __VA_ARGS__) \
+DO_6(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_8(MACRO, ...) \
+MACRO(8, __VA_ARGS__) \
+DO_7(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_9(MACRO, ...) \
+MACRO(9, __VA_ARGS__) \
+DO_8(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_10(MACRO, ...) \
+MACRO(10, __VA_ARGS__) \
+DO_9(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_11(MACRO, ...) \
+MACRO(11, __VA_ARGS__) \
+DO_10(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_12(MACRO, ...) \
+MACRO(12, __VA_ARGS__) \
+DO_11(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_13(MACRO, ...) \
+MACRO(13, __VA_ARGS__) \
+DO_12(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_14(MACRO, ...) \
+MACRO(14, __VA_ARGS__) \
+DO_13(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_15(MACRO, ...) \
+MACRO(15, __VA_ARGS__) \
+DO_14(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_16(MACRO, ...) \
+MACRO(16, __VA_ARGS__) \
+DO_15(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_17(MACRO, ...) \
+MACRO(17, __VA_ARGS__) \
+DO_16(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_18(MACRO, ...) \
+MACRO(18, __VA_ARGS__) \
+DO_17(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_19(MACRO, ...) \
+MACRO(19, __VA_ARGS__) \
+DO_18(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_20(MACRO, ...) \
+MACRO(20, __VA_ARGS__) \
+DO_19(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_21(MACRO, ...) \
+MACRO(21, __VA_ARGS__) \
+DO_20(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_22(MACRO, ...) \
+MACRO(22, __VA_ARGS__) \
+DO_21(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_23(MACRO, ...) \
+MACRO(23, __VA_ARGS__) \
+DO_22(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_24(MACRO, ...) \
+MACRO(24, __VA_ARGS__) \
+DO_23(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_25(MACRO, ...) \
+MACRO(25, __VA_ARGS__) \
+DO_24(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_26(MACRO, ...) \
+MACRO(26, __VA_ARGS__) \
+DO_25(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_27(MACRO, ...) \
+MACRO(27, __VA_ARGS__) \
+DO_26(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_28(MACRO, ...) \
+MACRO(28, __VA_ARGS__) \
+DO_27(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_29(MACRO, ...) \
+MACRO(29, __VA_ARGS__) \
+DO_28(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_30(MACRO, ...) \
+MACRO(30, __VA_ARGS__) \
+DO_29(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_31(MACRO, ...) \
+MACRO(31, __VA_ARGS__) \
+DO_30(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_32(MACRO, ...) \
+MACRO(32, __VA_ARGS__) \
+DO_31(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_33(MACRO, ...) \
+MACRO(33, __VA_ARGS__) \
+DO_32(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_34(MACRO, ...) \
+MACRO(34, __VA_ARGS__) \
+DO_33(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_35(MACRO, ...) \
+MACRO(35, __VA_ARGS__) \
+DO_34(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_36(MACRO, ...) \
+MACRO(36, __VA_ARGS__) \
+DO_35(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_37(MACRO, ...) \
+MACRO(37, __VA_ARGS__) \
+DO_36(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_38(MACRO, ...) \
+MACRO(38, __VA_ARGS__) \
+DO_37(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_39(MACRO, ...) \
+MACRO(39, __VA_ARGS__) \
+DO_38(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_40(MACRO, ...) \
+MACRO(40, __VA_ARGS__) \
+DO_39(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_41(MACRO, ...) \
+MACRO(41, __VA_ARGS__) \
+DO_40(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_42(MACRO, ...) \
+MACRO(42, __VA_ARGS__) \
+DO_41(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_43(MACRO, ...) \
+MACRO(43, __VA_ARGS__) \
+DO_42(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_44(MACRO, ...) \
+MACRO(44, __VA_ARGS__) \
+DO_43(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_45(MACRO, ...) \
+MACRO(45, __VA_ARGS__) \
+DO_44(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_46(MACRO, ...) \
+MACRO(46, __VA_ARGS__) \
+DO_45(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_47(MACRO, ...) \
+MACRO(47, __VA_ARGS__) \
+DO_46(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_48(MACRO, ...) \
+MACRO(48, __VA_ARGS__) \
+DO_47(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_49(MACRO, ...) \
+MACRO(49, __VA_ARGS__) \
+DO_48(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_50(MACRO, ...) \
+MACRO(50, __VA_ARGS__) \
+DO_49(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_51(MACRO, ...) \
+MACRO(51, __VA_ARGS__) \
+DO_50(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_52(MACRO, ...) \
+MACRO(52, __VA_ARGS__) \
+DO_51(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_53(MACRO, ...) \
+MACRO(53, __VA_ARGS__) \
+DO_52(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_54(MACRO, ...) \
+MACRO(54, __VA_ARGS__) \
+DO_53(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_55(MACRO, ...) \
+MACRO(55, __VA_ARGS__) \
+DO_54(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_56(MACRO, ...) \
+MACRO(56, __VA_ARGS__) \
+DO_55(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_57(MACRO, ...) \
+MACRO(57, __VA_ARGS__) \
+DO_56(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_58(MACRO, ...) \
+MACRO(58, __VA_ARGS__) \
+DO_57(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_59(MACRO, ...) \
+MACRO(59, __VA_ARGS__) \
+DO_58(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_60(MACRO, ...) \
+MACRO(60, __VA_ARGS__) \
+DO_59(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_61(MACRO, ...) \
+MACRO(61, __VA_ARGS__) \
+DO_60(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_62(MACRO, ...) \
+MACRO(62, __VA_ARGS__) \
+DO_61(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_63(MACRO, ...) \
+MACRO(63, __VA_ARGS__) \
+DO_62(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_64(MACRO, ...) \
+MACRO(64, __VA_ARGS__) \
+DO_63(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_65(MACRO, ...) \
+MACRO(65, __VA_ARGS__) \
+DO_64(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_66(MACRO, ...) \
+MACRO(66, __VA_ARGS__) \
+DO_65(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_67(MACRO, ...) \
+MACRO(67, __VA_ARGS__) \
+DO_66(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_68(MACRO, ...) \
+MACRO(68, __VA_ARGS__) \
+DO_67(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_69(MACRO, ...) \
+MACRO(69, __VA_ARGS__) \
+DO_68(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_70(MACRO, ...) \
+MACRO(70, __VA_ARGS__) \
+DO_69(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_71(MACRO, ...) \
+MACRO(71, __VA_ARGS__) \
+DO_70(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_72(MACRO, ...) \
+MACRO(72, __VA_ARGS__) \
+DO_71(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_73(MACRO, ...) \
+MACRO(73, __VA_ARGS__) \
+DO_72(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_74(MACRO, ...) \
+MACRO(74, __VA_ARGS__) \
+DO_73(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_75(MACRO, ...) \
+MACRO(75, __VA_ARGS__) \
+DO_74(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_76(MACRO, ...) \
+MACRO(76, __VA_ARGS__) \
+DO_75(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_77(MACRO, ...) \
+MACRO(77, __VA_ARGS__) \
+DO_76(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_78(MACRO, ...) \
+MACRO(78, __VA_ARGS__) \
+DO_77(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_79(MACRO, ...) \
+MACRO(79, __VA_ARGS__) \
+DO_78(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_80(MACRO, ...) \
+MACRO(80, __VA_ARGS__) \
+DO_79(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_81(MACRO, ...) \
+MACRO(81, __VA_ARGS__) \
+DO_80(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_82(MACRO, ...) \
+MACRO(82, __VA_ARGS__) \
+DO_81(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_83(MACRO, ...) \
+MACRO(83, __VA_ARGS__) \
+DO_82(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_84(MACRO, ...) \
+MACRO(84, __VA_ARGS__) \
+DO_83(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_85(MACRO, ...) \
+MACRO(85, __VA_ARGS__) \
+DO_84(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_86(MACRO, ...) \
+MACRO(86, __VA_ARGS__) \
+DO_85(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_87(MACRO, ...) \
+MACRO(87, __VA_ARGS__) \
+DO_86(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_88(MACRO, ...) \
+MACRO(88, __VA_ARGS__) \
+DO_87(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_89(MACRO, ...) \
+MACRO(89, __VA_ARGS__) \
+DO_88(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_90(MACRO, ...) \
+MACRO(90, __VA_ARGS__) \
+DO_89(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_91(MACRO, ...) \
+MACRO(91, __VA_ARGS__) \
+DO_90(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_92(MACRO, ...) \
+MACRO(92, __VA_ARGS__) \
+DO_91(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_93(MACRO, ...) \
+MACRO(93, __VA_ARGS__) \
+DO_92(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_94(MACRO, ...) \
+MACRO(94, __VA_ARGS__) \
+DO_93(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_95(MACRO, ...) \
+MACRO(95, __VA_ARGS__) \
+DO_94(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_96(MACRO, ...) \
+MACRO(96, __VA_ARGS__) \
+DO_95(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_97(MACRO, ...) \
+MACRO(97, __VA_ARGS__) \
+DO_96(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_98(MACRO, ...) \
+MACRO(98, __VA_ARGS__) \
+DO_97(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_99(MACRO, ...) \
+MACRO(99, __VA_ARGS__) \
+DO_98(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_100(MACRO, ...) \
+MACRO(100, __VA_ARGS__) \
+DO_99(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_101(MACRO, ...) \
+MACRO(101, __VA_ARGS__) \
+DO_100(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_102(MACRO, ...) \
+MACRO(102, __VA_ARGS__) \
+DO_101(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_103(MACRO, ...) \
+MACRO(103, __VA_ARGS__) \
+DO_102(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_104(MACRO, ...) \
+MACRO(104, __VA_ARGS__) \
+DO_103(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_105(MACRO, ...) \
+MACRO(105, __VA_ARGS__) \
+DO_104(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_106(MACRO, ...) \
+MACRO(106, __VA_ARGS__) \
+DO_105(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_107(MACRO, ...) \
+MACRO(107, __VA_ARGS__) \
+DO_106(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_108(MACRO, ...) \
+MACRO(108, __VA_ARGS__) \
+DO_107(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_109(MACRO, ...) \
+MACRO(109, __VA_ARGS__) \
+DO_108(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_110(MACRO, ...) \
+MACRO(110, __VA_ARGS__) \
+DO_109(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_111(MACRO, ...) \
+MACRO(111, __VA_ARGS__) \
+DO_110(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_112(MACRO, ...) \
+MACRO(112, __VA_ARGS__) \
+DO_111(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_113(MACRO, ...) \
+MACRO(113, __VA_ARGS__) \
+DO_112(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_114(MACRO, ...) \
+MACRO(114, __VA_ARGS__) \
+DO_113(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_115(MACRO, ...) \
+MACRO(115, __VA_ARGS__) \
+DO_114(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_116(MACRO, ...) \
+MACRO(116, __VA_ARGS__) \
+DO_115(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_117(MACRO, ...) \
+MACRO(117, __VA_ARGS__) \
+DO_116(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_118(MACRO, ...) \
+MACRO(118, __VA_ARGS__) \
+DO_117(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_119(MACRO, ...) \
+MACRO(119, __VA_ARGS__) \
+DO_118(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_120(MACRO, ...) \
+MACRO(120, __VA_ARGS__) \
+DO_119(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_121(MACRO, ...) \
+MACRO(121, __VA_ARGS__) \
+DO_120(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_122(MACRO, ...) \
+MACRO(122, __VA_ARGS__) \
+DO_121(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_123(MACRO, ...) \
+MACRO(123, __VA_ARGS__) \
+DO_122(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_124(MACRO, ...) \
+MACRO(124, __VA_ARGS__) \
+DO_123(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_125(MACRO, ...) \
+MACRO(125, __VA_ARGS__) \
+DO_124(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_126(MACRO, ...) \
+MACRO(126, __VA_ARGS__) \
+DO_125(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_127(MACRO, ...) \
+MACRO(127, __VA_ARGS__) \
+DO_126(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_128(MACRO, ...) \
+MACRO(128, __VA_ARGS__) \
+DO_127(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_129(MACRO, ...) \
+MACRO(129, __VA_ARGS__) \
+DO_128(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_130(MACRO, ...) \
+MACRO(130, __VA_ARGS__) \
+DO_129(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_131(MACRO, ...) \
+MACRO(131, __VA_ARGS__) \
+DO_130(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_132(MACRO, ...) \
+MACRO(132, __VA_ARGS__) \
+DO_131(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_133(MACRO, ...) \
+MACRO(133, __VA_ARGS__) \
+DO_132(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_134(MACRO, ...) \
+MACRO(134, __VA_ARGS__) \
+DO_133(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_135(MACRO, ...) \
+MACRO(135, __VA_ARGS__) \
+DO_134(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_136(MACRO, ...) \
+MACRO(136, __VA_ARGS__) \
+DO_135(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_137(MACRO, ...) \
+MACRO(137, __VA_ARGS__) \
+DO_136(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_138(MACRO, ...) \
+MACRO(138, __VA_ARGS__) \
+DO_137(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_139(MACRO, ...) \
+MACRO(139, __VA_ARGS__) \
+DO_138(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_140(MACRO, ...) \
+MACRO(140, __VA_ARGS__) \
+DO_139(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_141(MACRO, ...) \
+MACRO(141, __VA_ARGS__) \
+DO_140(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_142(MACRO, ...) \
+MACRO(142, __VA_ARGS__) \
+DO_141(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_143(MACRO, ...) \
+MACRO(143, __VA_ARGS__) \
+DO_142(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_144(MACRO, ...) \
+MACRO(144, __VA_ARGS__) \
+DO_143(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_145(MACRO, ...) \
+MACRO(145, __VA_ARGS__) \
+DO_144(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_146(MACRO, ...) \
+MACRO(146, __VA_ARGS__) \
+DO_145(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_147(MACRO, ...) \
+MACRO(147, __VA_ARGS__) \
+DO_146(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_148(MACRO, ...) \
+MACRO(148, __VA_ARGS__) \
+DO_147(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_149(MACRO, ...) \
+MACRO(149, __VA_ARGS__) \
+DO_148(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_150(MACRO, ...) \
+MACRO(150, __VA_ARGS__) \
+DO_149(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_151(MACRO, ...) \
+MACRO(151, __VA_ARGS__) \
+DO_150(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_152(MACRO, ...) \
+MACRO(152, __VA_ARGS__) \
+DO_151(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_153(MACRO, ...) \
+MACRO(153, __VA_ARGS__) \
+DO_152(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_154(MACRO, ...) \
+MACRO(154, __VA_ARGS__) \
+DO_153(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_155(MACRO, ...) \
+MACRO(155, __VA_ARGS__) \
+DO_154(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_156(MACRO, ...) \
+MACRO(156, __VA_ARGS__) \
+DO_155(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_157(MACRO, ...) \
+MACRO(157, __VA_ARGS__) \
+DO_156(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_158(MACRO, ...) \
+MACRO(158, __VA_ARGS__) \
+DO_157(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_159(MACRO, ...) \
+MACRO(159, __VA_ARGS__) \
+DO_158(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_160(MACRO, ...) \
+MACRO(160, __VA_ARGS__) \
+DO_159(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_161(MACRO, ...) \
+MACRO(161, __VA_ARGS__) \
+DO_160(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_162(MACRO, ...) \
+MACRO(162, __VA_ARGS__) \
+DO_161(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_163(MACRO, ...) \
+MACRO(163, __VA_ARGS__) \
+DO_162(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_164(MACRO, ...) \
+MACRO(164, __VA_ARGS__) \
+DO_163(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_165(MACRO, ...) \
+MACRO(165, __VA_ARGS__) \
+DO_164(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_166(MACRO, ...) \
+MACRO(166, __VA_ARGS__) \
+DO_165(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_167(MACRO, ...) \
+MACRO(167, __VA_ARGS__) \
+DO_166(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_168(MACRO, ...) \
+MACRO(168, __VA_ARGS__) \
+DO_167(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_169(MACRO, ...) \
+MACRO(169, __VA_ARGS__) \
+DO_168(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_170(MACRO, ...) \
+MACRO(170, __VA_ARGS__) \
+DO_169(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_171(MACRO, ...) \
+MACRO(171, __VA_ARGS__) \
+DO_170(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_172(MACRO, ...) \
+MACRO(172, __VA_ARGS__) \
+DO_171(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_173(MACRO, ...) \
+MACRO(173, __VA_ARGS__) \
+DO_172(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_174(MACRO, ...) \
+MACRO(174, __VA_ARGS__) \
+DO_173(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_175(MACRO, ...) \
+MACRO(175, __VA_ARGS__) \
+DO_174(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_176(MACRO, ...) \
+MACRO(176, __VA_ARGS__) \
+DO_175(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_177(MACRO, ...) \
+MACRO(177, __VA_ARGS__) \
+DO_176(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_178(MACRO, ...) \
+MACRO(178, __VA_ARGS__) \
+DO_177(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_179(MACRO, ...) \
+MACRO(179, __VA_ARGS__) \
+DO_178(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_180(MACRO, ...) \
+MACRO(180, __VA_ARGS__) \
+DO_179(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_181(MACRO, ...) \
+MACRO(181, __VA_ARGS__) \
+DO_180(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_182(MACRO, ...) \
+MACRO(182, __VA_ARGS__) \
+DO_181(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_183(MACRO, ...) \
+MACRO(183, __VA_ARGS__) \
+DO_182(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_184(MACRO, ...) \
+MACRO(184, __VA_ARGS__) \
+DO_183(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_185(MACRO, ...) \
+MACRO(185, __VA_ARGS__) \
+DO_184(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_186(MACRO, ...) \
+MACRO(186, __VA_ARGS__) \
+DO_185(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_187(MACRO, ...) \
+MACRO(187, __VA_ARGS__) \
+DO_186(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_188(MACRO, ...) \
+MACRO(188, __VA_ARGS__) \
+DO_187(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_189(MACRO, ...) \
+MACRO(189, __VA_ARGS__) \
+DO_188(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_190(MACRO, ...) \
+MACRO(190, __VA_ARGS__) \
+DO_189(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_191(MACRO, ...) \
+MACRO(191, __VA_ARGS__) \
+DO_190(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_192(MACRO, ...) \
+MACRO(192, __VA_ARGS__) \
+DO_191(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_193(MACRO, ...) \
+MACRO(193, __VA_ARGS__) \
+DO_192(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_194(MACRO, ...) \
+MACRO(194, __VA_ARGS__) \
+DO_193(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_195(MACRO, ...) \
+MACRO(195, __VA_ARGS__) \
+DO_194(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_196(MACRO, ...) \
+MACRO(196, __VA_ARGS__) \
+DO_195(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_197(MACRO, ...) \
+MACRO(197, __VA_ARGS__) \
+DO_196(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_198(MACRO, ...) \
+MACRO(198, __VA_ARGS__) \
+DO_197(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_199(MACRO, ...) \
+MACRO(199, __VA_ARGS__) \
+DO_198(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_200(MACRO, ...) \
+MACRO(200, __VA_ARGS__) \
+DO_199(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_201(MACRO, ...) \
+MACRO(201, __VA_ARGS__) \
+DO_200(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_202(MACRO, ...) \
+MACRO(202, __VA_ARGS__) \
+DO_201(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_203(MACRO, ...) \
+MACRO(203, __VA_ARGS__) \
+DO_202(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_204(MACRO, ...) \
+MACRO(204, __VA_ARGS__) \
+DO_203(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_205(MACRO, ...) \
+MACRO(205, __VA_ARGS__) \
+DO_204(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_206(MACRO, ...) \
+MACRO(206, __VA_ARGS__) \
+DO_205(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_207(MACRO, ...) \
+MACRO(207, __VA_ARGS__) \
+DO_206(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_208(MACRO, ...) \
+MACRO(208, __VA_ARGS__) \
+DO_207(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_209(MACRO, ...) \
+MACRO(209, __VA_ARGS__) \
+DO_208(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_210(MACRO, ...) \
+MACRO(210, __VA_ARGS__) \
+DO_209(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_211(MACRO, ...) \
+MACRO(211, __VA_ARGS__) \
+DO_210(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_212(MACRO, ...) \
+MACRO(212, __VA_ARGS__) \
+DO_211(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_213(MACRO, ...) \
+MACRO(213, __VA_ARGS__) \
+DO_212(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_214(MACRO, ...) \
+MACRO(214, __VA_ARGS__) \
+DO_213(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_215(MACRO, ...) \
+MACRO(215, __VA_ARGS__) \
+DO_214(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_216(MACRO, ...) \
+MACRO(216, __VA_ARGS__) \
+DO_215(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_217(MACRO, ...) \
+MACRO(217, __VA_ARGS__) \
+DO_216(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_218(MACRO, ...) \
+MACRO(218, __VA_ARGS__) \
+DO_217(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_219(MACRO, ...) \
+MACRO(219, __VA_ARGS__) \
+DO_218(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_220(MACRO, ...) \
+MACRO(220, __VA_ARGS__) \
+DO_219(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_221(MACRO, ...) \
+MACRO(221, __VA_ARGS__) \
+DO_220(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_222(MACRO, ...) \
+MACRO(222, __VA_ARGS__) \
+DO_221(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_223(MACRO, ...) \
+MACRO(223, __VA_ARGS__) \
+DO_222(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_224(MACRO, ...) \
+MACRO(224, __VA_ARGS__) \
+DO_223(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_225(MACRO, ...) \
+MACRO(225, __VA_ARGS__) \
+DO_224(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_226(MACRO, ...) \
+MACRO(226, __VA_ARGS__) \
+DO_225(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_227(MACRO, ...) \
+MACRO(227, __VA_ARGS__) \
+DO_226(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_228(MACRO, ...) \
+MACRO(228, __VA_ARGS__) \
+DO_227(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_229(MACRO, ...) \
+MACRO(229, __VA_ARGS__) \
+DO_228(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_230(MACRO, ...) \
+MACRO(230, __VA_ARGS__) \
+DO_229(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_231(MACRO, ...) \
+MACRO(231, __VA_ARGS__) \
+DO_230(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_232(MACRO, ...) \
+MACRO(232, __VA_ARGS__) \
+DO_231(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_233(MACRO, ...) \
+MACRO(233, __VA_ARGS__) \
+DO_232(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_234(MACRO, ...) \
+MACRO(234, __VA_ARGS__) \
+DO_233(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_235(MACRO, ...) \
+MACRO(235, __VA_ARGS__) \
+DO_234(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_236(MACRO, ...) \
+MACRO(236, __VA_ARGS__) \
+DO_235(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_237(MACRO, ...) \
+MACRO(237, __VA_ARGS__) \
+DO_236(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_238(MACRO, ...) \
+MACRO(238, __VA_ARGS__) \
+DO_237(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_239(MACRO, ...) \
+MACRO(239, __VA_ARGS__) \
+DO_238(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_240(MACRO, ...) \
+MACRO(240, __VA_ARGS__) \
+DO_239(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_241(MACRO, ...) \
+MACRO(241, __VA_ARGS__) \
+DO_240(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_242(MACRO, ...) \
+MACRO(242, __VA_ARGS__) \
+DO_241(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_243(MACRO, ...) \
+MACRO(243, __VA_ARGS__) \
+DO_242(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_244(MACRO, ...) \
+MACRO(244, __VA_ARGS__) \
+DO_243(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_245(MACRO, ...) \
+MACRO(245, __VA_ARGS__) \
+DO_244(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_246(MACRO, ...) \
+MACRO(246, __VA_ARGS__) \
+DO_245(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_247(MACRO, ...) \
+MACRO(247, __VA_ARGS__) \
+DO_246(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_248(MACRO, ...) \
+MACRO(248, __VA_ARGS__) \
+DO_247(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_249(MACRO, ...) \
+MACRO(249, __VA_ARGS__) \
+DO_248(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_250(MACRO, ...) \
+MACRO(250, __VA_ARGS__) \
+DO_249(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_251(MACRO, ...) \
+MACRO(251, __VA_ARGS__) \
+DO_250(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_252(MACRO, ...) \
+MACRO(252, __VA_ARGS__) \
+DO_251(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_253(MACRO, ...) \
+MACRO(253, __VA_ARGS__) \
+DO_252(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_254(MACRO, ...) \
+MACRO(254, __VA_ARGS__) \
+DO_253(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_255(MACRO, ...) \
+MACRO(255, __VA_ARGS__) \
+DO_254(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_256(MACRO, ...) \
+MACRO(256, __VA_ARGS__) \
+DO_255(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_257(MACRO, ...) \
+MACRO(257, __VA_ARGS__) \
+DO_256(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_258(MACRO, ...) \
+MACRO(258, __VA_ARGS__) \
+DO_257(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_259(MACRO, ...) \
+MACRO(259, __VA_ARGS__) \
+DO_258(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_260(MACRO, ...) \
+MACRO(260, __VA_ARGS__) \
+DO_259(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_261(MACRO, ...) \
+MACRO(261, __VA_ARGS__) \
+DO_260(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_262(MACRO, ...) \
+MACRO(262, __VA_ARGS__) \
+DO_261(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_263(MACRO, ...) \
+MACRO(263, __VA_ARGS__) \
+DO_262(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_264(MACRO, ...) \
+MACRO(264, __VA_ARGS__) \
+DO_263(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_265(MACRO, ...) \
+MACRO(265, __VA_ARGS__) \
+DO_264(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_266(MACRO, ...) \
+MACRO(266, __VA_ARGS__) \
+DO_265(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_267(MACRO, ...) \
+MACRO(267, __VA_ARGS__) \
+DO_266(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_268(MACRO, ...) \
+MACRO(268, __VA_ARGS__) \
+DO_267(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_269(MACRO, ...) \
+MACRO(269, __VA_ARGS__) \
+DO_268(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_270(MACRO, ...) \
+MACRO(270, __VA_ARGS__) \
+DO_269(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_271(MACRO, ...) \
+MACRO(271, __VA_ARGS__) \
+DO_270(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_272(MACRO, ...) \
+MACRO(272, __VA_ARGS__) \
+DO_271(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_273(MACRO, ...) \
+MACRO(273, __VA_ARGS__) \
+DO_272(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_274(MACRO, ...) \
+MACRO(274, __VA_ARGS__) \
+DO_273(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_275(MACRO, ...) \
+MACRO(275, __VA_ARGS__) \
+DO_274(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_276(MACRO, ...) \
+MACRO(276, __VA_ARGS__) \
+DO_275(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_277(MACRO, ...) \
+MACRO(277, __VA_ARGS__) \
+DO_276(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_278(MACRO, ...) \
+MACRO(278, __VA_ARGS__) \
+DO_277(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_279(MACRO, ...) \
+MACRO(279, __VA_ARGS__) \
+DO_278(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_280(MACRO, ...) \
+MACRO(280, __VA_ARGS__) \
+DO_279(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_281(MACRO, ...) \
+MACRO(281, __VA_ARGS__) \
+DO_280(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_282(MACRO, ...) \
+MACRO(282, __VA_ARGS__) \
+DO_281(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_283(MACRO, ...) \
+MACRO(283, __VA_ARGS__) \
+DO_282(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_284(MACRO, ...) \
+MACRO(284, __VA_ARGS__) \
+DO_283(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_285(MACRO, ...) \
+MACRO(285, __VA_ARGS__) \
+DO_284(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_286(MACRO, ...) \
+MACRO(286, __VA_ARGS__) \
+DO_285(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_287(MACRO, ...) \
+MACRO(287, __VA_ARGS__) \
+DO_286(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_288(MACRO, ...) \
+MACRO(288, __VA_ARGS__) \
+DO_287(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_289(MACRO, ...) \
+MACRO(289, __VA_ARGS__) \
+DO_288(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_290(MACRO, ...) \
+MACRO(290, __VA_ARGS__) \
+DO_289(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_291(MACRO, ...) \
+MACRO(291, __VA_ARGS__) \
+DO_290(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_292(MACRO, ...) \
+MACRO(292, __VA_ARGS__) \
+DO_291(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_293(MACRO, ...) \
+MACRO(293, __VA_ARGS__) \
+DO_292(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_294(MACRO, ...) \
+MACRO(294, __VA_ARGS__) \
+DO_293(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_295(MACRO, ...) \
+MACRO(295, __VA_ARGS__) \
+DO_294(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_296(MACRO, ...) \
+MACRO(296, __VA_ARGS__) \
+DO_295(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_297(MACRO, ...) \
+MACRO(297, __VA_ARGS__) \
+DO_296(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_298(MACRO, ...) \
+MACRO(298, __VA_ARGS__) \
+DO_297(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_299(MACRO, ...) \
+MACRO(299, __VA_ARGS__) \
+DO_298(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_300(MACRO, ...) \
+MACRO(300, __VA_ARGS__) \
+DO_299(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_301(MACRO, ...) \
+MACRO(301, __VA_ARGS__) \
+DO_300(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_302(MACRO, ...) \
+MACRO(302, __VA_ARGS__) \
+DO_301(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_303(MACRO, ...) \
+MACRO(303, __VA_ARGS__) \
+DO_302(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_304(MACRO, ...) \
+MACRO(304, __VA_ARGS__) \
+DO_303(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_305(MACRO, ...) \
+MACRO(305, __VA_ARGS__) \
+DO_304(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_306(MACRO, ...) \
+MACRO(306, __VA_ARGS__) \
+DO_305(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_307(MACRO, ...) \
+MACRO(307, __VA_ARGS__) \
+DO_306(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_308(MACRO, ...) \
+MACRO(308, __VA_ARGS__) \
+DO_307(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_309(MACRO, ...) \
+MACRO(309, __VA_ARGS__) \
+DO_308(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_310(MACRO, ...) \
+MACRO(310, __VA_ARGS__) \
+DO_309(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_311(MACRO, ...) \
+MACRO(311, __VA_ARGS__) \
+DO_310(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_312(MACRO, ...) \
+MACRO(312, __VA_ARGS__) \
+DO_311(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_313(MACRO, ...) \
+MACRO(313, __VA_ARGS__) \
+DO_312(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_314(MACRO, ...) \
+MACRO(314, __VA_ARGS__) \
+DO_313(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_315(MACRO, ...) \
+MACRO(315, __VA_ARGS__) \
+DO_314(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_316(MACRO, ...) \
+MACRO(316, __VA_ARGS__) \
+DO_315(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_317(MACRO, ...) \
+MACRO(317, __VA_ARGS__) \
+DO_316(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_318(MACRO, ...) \
+MACRO(318, __VA_ARGS__) \
+DO_317(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_319(MACRO, ...) \
+MACRO(319, __VA_ARGS__) \
+DO_318(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_320(MACRO, ...) \
+MACRO(320, __VA_ARGS__) \
+DO_319(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_321(MACRO, ...) \
+MACRO(321, __VA_ARGS__) \
+DO_320(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_322(MACRO, ...) \
+MACRO(322, __VA_ARGS__) \
+DO_321(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_323(MACRO, ...) \
+MACRO(323, __VA_ARGS__) \
+DO_322(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_324(MACRO, ...) \
+MACRO(324, __VA_ARGS__) \
+DO_323(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_325(MACRO, ...) \
+MACRO(325, __VA_ARGS__) \
+DO_324(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_326(MACRO, ...) \
+MACRO(326, __VA_ARGS__) \
+DO_325(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_327(MACRO, ...) \
+MACRO(327, __VA_ARGS__) \
+DO_326(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_328(MACRO, ...) \
+MACRO(328, __VA_ARGS__) \
+DO_327(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_329(MACRO, ...) \
+MACRO(329, __VA_ARGS__) \
+DO_328(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_330(MACRO, ...) \
+MACRO(330, __VA_ARGS__) \
+DO_329(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_331(MACRO, ...) \
+MACRO(331, __VA_ARGS__) \
+DO_330(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_332(MACRO, ...) \
+MACRO(332, __VA_ARGS__) \
+DO_331(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_333(MACRO, ...) \
+MACRO(333, __VA_ARGS__) \
+DO_332(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_334(MACRO, ...) \
+MACRO(334, __VA_ARGS__) \
+DO_333(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_335(MACRO, ...) \
+MACRO(335, __VA_ARGS__) \
+DO_334(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_336(MACRO, ...) \
+MACRO(336, __VA_ARGS__) \
+DO_335(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_337(MACRO, ...) \
+MACRO(337, __VA_ARGS__) \
+DO_336(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_338(MACRO, ...) \
+MACRO(338, __VA_ARGS__) \
+DO_337(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_339(MACRO, ...) \
+MACRO(339, __VA_ARGS__) \
+DO_338(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_340(MACRO, ...) \
+MACRO(340, __VA_ARGS__) \
+DO_339(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_341(MACRO, ...) \
+MACRO(341, __VA_ARGS__) \
+DO_340(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_342(MACRO, ...) \
+MACRO(342, __VA_ARGS__) \
+DO_341(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_343(MACRO, ...) \
+MACRO(343, __VA_ARGS__) \
+DO_342(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_344(MACRO, ...) \
+MACRO(344, __VA_ARGS__) \
+DO_343(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_345(MACRO, ...) \
+MACRO(345, __VA_ARGS__) \
+DO_344(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_346(MACRO, ...) \
+MACRO(346, __VA_ARGS__) \
+DO_345(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_347(MACRO, ...) \
+MACRO(347, __VA_ARGS__) \
+DO_346(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_348(MACRO, ...) \
+MACRO(348, __VA_ARGS__) \
+DO_347(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_349(MACRO, ...) \
+MACRO(349, __VA_ARGS__) \
+DO_348(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_350(MACRO, ...) \
+MACRO(350, __VA_ARGS__) \
+DO_349(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_351(MACRO, ...) \
+MACRO(351, __VA_ARGS__) \
+DO_350(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_352(MACRO, ...) \
+MACRO(352, __VA_ARGS__) \
+DO_351(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_353(MACRO, ...) \
+MACRO(353, __VA_ARGS__) \
+DO_352(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_354(MACRO, ...) \
+MACRO(354, __VA_ARGS__) \
+DO_353(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_355(MACRO, ...) \
+MACRO(355, __VA_ARGS__) \
+DO_354(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_356(MACRO, ...) \
+MACRO(356, __VA_ARGS__) \
+DO_355(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_357(MACRO, ...) \
+MACRO(357, __VA_ARGS__) \
+DO_356(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_358(MACRO, ...) \
+MACRO(358, __VA_ARGS__) \
+DO_357(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_359(MACRO, ...) \
+MACRO(359, __VA_ARGS__) \
+DO_358(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_360(MACRO, ...) \
+MACRO(360, __VA_ARGS__) \
+DO_359(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_361(MACRO, ...) \
+MACRO(361, __VA_ARGS__) \
+DO_360(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_362(MACRO, ...) \
+MACRO(362, __VA_ARGS__) \
+DO_361(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_363(MACRO, ...) \
+MACRO(363, __VA_ARGS__) \
+DO_362(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_364(MACRO, ...) \
+MACRO(364, __VA_ARGS__) \
+DO_363(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_365(MACRO, ...) \
+MACRO(365, __VA_ARGS__) \
+DO_364(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_366(MACRO, ...) \
+MACRO(366, __VA_ARGS__) \
+DO_365(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_367(MACRO, ...) \
+MACRO(367, __VA_ARGS__) \
+DO_366(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_368(MACRO, ...) \
+MACRO(368, __VA_ARGS__) \
+DO_367(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_369(MACRO, ...) \
+MACRO(369, __VA_ARGS__) \
+DO_368(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_370(MACRO, ...) \
+MACRO(370, __VA_ARGS__) \
+DO_369(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_371(MACRO, ...) \
+MACRO(371, __VA_ARGS__) \
+DO_370(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_372(MACRO, ...) \
+MACRO(372, __VA_ARGS__) \
+DO_371(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_373(MACRO, ...) \
+MACRO(373, __VA_ARGS__) \
+DO_372(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_374(MACRO, ...) \
+MACRO(374, __VA_ARGS__) \
+DO_373(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_375(MACRO, ...) \
+MACRO(375, __VA_ARGS__) \
+DO_374(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_376(MACRO, ...) \
+MACRO(376, __VA_ARGS__) \
+DO_375(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_377(MACRO, ...) \
+MACRO(377, __VA_ARGS__) \
+DO_376(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_378(MACRO, ...) \
+MACRO(378, __VA_ARGS__) \
+DO_377(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_379(MACRO, ...) \
+MACRO(379, __VA_ARGS__) \
+DO_378(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_380(MACRO, ...) \
+MACRO(380, __VA_ARGS__) \
+DO_379(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_381(MACRO, ...) \
+MACRO(381, __VA_ARGS__) \
+DO_380(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_382(MACRO, ...) \
+MACRO(382, __VA_ARGS__) \
+DO_381(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_383(MACRO, ...) \
+MACRO(383, __VA_ARGS__) \
+DO_382(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_384(MACRO, ...) \
+MACRO(384, __VA_ARGS__) \
+DO_383(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_385(MACRO, ...) \
+MACRO(385, __VA_ARGS__) \
+DO_384(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_386(MACRO, ...) \
+MACRO(386, __VA_ARGS__) \
+DO_385(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_387(MACRO, ...) \
+MACRO(387, __VA_ARGS__) \
+DO_386(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_388(MACRO, ...) \
+MACRO(388, __VA_ARGS__) \
+DO_387(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_389(MACRO, ...) \
+MACRO(389, __VA_ARGS__) \
+DO_388(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_390(MACRO, ...) \
+MACRO(390, __VA_ARGS__) \
+DO_389(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_391(MACRO, ...) \
+MACRO(391, __VA_ARGS__) \
+DO_390(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_392(MACRO, ...) \
+MACRO(392, __VA_ARGS__) \
+DO_391(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_393(MACRO, ...) \
+MACRO(393, __VA_ARGS__) \
+DO_392(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_394(MACRO, ...) \
+MACRO(394, __VA_ARGS__) \
+DO_393(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_395(MACRO, ...) \
+MACRO(395, __VA_ARGS__) \
+DO_394(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_396(MACRO, ...) \
+MACRO(396, __VA_ARGS__) \
+DO_395(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_397(MACRO, ...) \
+MACRO(397, __VA_ARGS__) \
+DO_396(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_398(MACRO, ...) \
+MACRO(398, __VA_ARGS__) \
+DO_397(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_399(MACRO, ...) \
+MACRO(399, __VA_ARGS__) \
+DO_398(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_400(MACRO, ...) \
+MACRO(400, __VA_ARGS__) \
+DO_399(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_401(MACRO, ...) \
+MACRO(401, __VA_ARGS__) \
+DO_400(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_402(MACRO, ...) \
+MACRO(402, __VA_ARGS__) \
+DO_401(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_403(MACRO, ...) \
+MACRO(403, __VA_ARGS__) \
+DO_402(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_404(MACRO, ...) \
+MACRO(404, __VA_ARGS__) \
+DO_403(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_405(MACRO, ...) \
+MACRO(405, __VA_ARGS__) \
+DO_404(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_406(MACRO, ...) \
+MACRO(406, __VA_ARGS__) \
+DO_405(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_407(MACRO, ...) \
+MACRO(407, __VA_ARGS__) \
+DO_406(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_408(MACRO, ...) \
+MACRO(408, __VA_ARGS__) \
+DO_407(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_409(MACRO, ...) \
+MACRO(409, __VA_ARGS__) \
+DO_408(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_410(MACRO, ...) \
+MACRO(410, __VA_ARGS__) \
+DO_409(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_411(MACRO, ...) \
+MACRO(411, __VA_ARGS__) \
+DO_410(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_412(MACRO, ...) \
+MACRO(412, __VA_ARGS__) \
+DO_411(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_413(MACRO, ...) \
+MACRO(413, __VA_ARGS__) \
+DO_412(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_414(MACRO, ...) \
+MACRO(414, __VA_ARGS__) \
+DO_413(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_415(MACRO, ...) \
+MACRO(415, __VA_ARGS__) \
+DO_414(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_416(MACRO, ...) \
+MACRO(416, __VA_ARGS__) \
+DO_415(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_417(MACRO, ...) \
+MACRO(417, __VA_ARGS__) \
+DO_416(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_418(MACRO, ...) \
+MACRO(418, __VA_ARGS__) \
+DO_417(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_419(MACRO, ...) \
+MACRO(419, __VA_ARGS__) \
+DO_418(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_420(MACRO, ...) \
+MACRO(420, __VA_ARGS__) \
+DO_419(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_421(MACRO, ...) \
+MACRO(421, __VA_ARGS__) \
+DO_420(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_422(MACRO, ...) \
+MACRO(422, __VA_ARGS__) \
+DO_421(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_423(MACRO, ...) \
+MACRO(423, __VA_ARGS__) \
+DO_422(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_424(MACRO, ...) \
+MACRO(424, __VA_ARGS__) \
+DO_423(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_425(MACRO, ...) \
+MACRO(425, __VA_ARGS__) \
+DO_424(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_426(MACRO, ...) \
+MACRO(426, __VA_ARGS__) \
+DO_425(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_427(MACRO, ...) \
+MACRO(427, __VA_ARGS__) \
+DO_426(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_428(MACRO, ...) \
+MACRO(428, __VA_ARGS__) \
+DO_427(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_429(MACRO, ...) \
+MACRO(429, __VA_ARGS__) \
+DO_428(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_430(MACRO, ...) \
+MACRO(430, __VA_ARGS__) \
+DO_429(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_431(MACRO, ...) \
+MACRO(431, __VA_ARGS__) \
+DO_430(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_432(MACRO, ...) \
+MACRO(432, __VA_ARGS__) \
+DO_431(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_433(MACRO, ...) \
+MACRO(433, __VA_ARGS__) \
+DO_432(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_434(MACRO, ...) \
+MACRO(434, __VA_ARGS__) \
+DO_433(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_435(MACRO, ...) \
+MACRO(435, __VA_ARGS__) \
+DO_434(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_436(MACRO, ...) \
+MACRO(436, __VA_ARGS__) \
+DO_435(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_437(MACRO, ...) \
+MACRO(437, __VA_ARGS__) \
+DO_436(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_438(MACRO, ...) \
+MACRO(438, __VA_ARGS__) \
+DO_437(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_439(MACRO, ...) \
+MACRO(439, __VA_ARGS__) \
+DO_438(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_440(MACRO, ...) \
+MACRO(440, __VA_ARGS__) \
+DO_439(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_441(MACRO, ...) \
+MACRO(441, __VA_ARGS__) \
+DO_440(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_442(MACRO, ...) \
+MACRO(442, __VA_ARGS__) \
+DO_441(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_443(MACRO, ...) \
+MACRO(443, __VA_ARGS__) \
+DO_442(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_444(MACRO, ...) \
+MACRO(444, __VA_ARGS__) \
+DO_443(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_445(MACRO, ...) \
+MACRO(445, __VA_ARGS__) \
+DO_444(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_446(MACRO, ...) \
+MACRO(446, __VA_ARGS__) \
+DO_445(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_447(MACRO, ...) \
+MACRO(447, __VA_ARGS__) \
+DO_446(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_448(MACRO, ...) \
+MACRO(448, __VA_ARGS__) \
+DO_447(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_449(MACRO, ...) \
+MACRO(449, __VA_ARGS__) \
+DO_448(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_450(MACRO, ...) \
+MACRO(450, __VA_ARGS__) \
+DO_449(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_451(MACRO, ...) \
+MACRO(451, __VA_ARGS__) \
+DO_450(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_452(MACRO, ...) \
+MACRO(452, __VA_ARGS__) \
+DO_451(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_453(MACRO, ...) \
+MACRO(453, __VA_ARGS__) \
+DO_452(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_454(MACRO, ...) \
+MACRO(454, __VA_ARGS__) \
+DO_453(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_455(MACRO, ...) \
+MACRO(455, __VA_ARGS__) \
+DO_454(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_456(MACRO, ...) \
+MACRO(456, __VA_ARGS__) \
+DO_455(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_457(MACRO, ...) \
+MACRO(457, __VA_ARGS__) \
+DO_456(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_458(MACRO, ...) \
+MACRO(458, __VA_ARGS__) \
+DO_457(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_459(MACRO, ...) \
+MACRO(459, __VA_ARGS__) \
+DO_458(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_460(MACRO, ...) \
+MACRO(460, __VA_ARGS__) \
+DO_459(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_461(MACRO, ...) \
+MACRO(461, __VA_ARGS__) \
+DO_460(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_462(MACRO, ...) \
+MACRO(462, __VA_ARGS__) \
+DO_461(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_463(MACRO, ...) \
+MACRO(463, __VA_ARGS__) \
+DO_462(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_464(MACRO, ...) \
+MACRO(464, __VA_ARGS__) \
+DO_463(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_465(MACRO, ...) \
+MACRO(465, __VA_ARGS__) \
+DO_464(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_466(MACRO, ...) \
+MACRO(466, __VA_ARGS__) \
+DO_465(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_467(MACRO, ...) \
+MACRO(467, __VA_ARGS__) \
+DO_466(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_468(MACRO, ...) \
+MACRO(468, __VA_ARGS__) \
+DO_467(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_469(MACRO, ...) \
+MACRO(469, __VA_ARGS__) \
+DO_468(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_470(MACRO, ...) \
+MACRO(470, __VA_ARGS__) \
+DO_469(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_471(MACRO, ...) \
+MACRO(471, __VA_ARGS__) \
+DO_470(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_472(MACRO, ...) \
+MACRO(472, __VA_ARGS__) \
+DO_471(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_473(MACRO, ...) \
+MACRO(473, __VA_ARGS__) \
+DO_472(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_474(MACRO, ...) \
+MACRO(474, __VA_ARGS__) \
+DO_473(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_475(MACRO, ...) \
+MACRO(475, __VA_ARGS__) \
+DO_474(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_476(MACRO, ...) \
+MACRO(476, __VA_ARGS__) \
+DO_475(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_477(MACRO, ...) \
+MACRO(477, __VA_ARGS__) \
+DO_476(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_478(MACRO, ...) \
+MACRO(478, __VA_ARGS__) \
+DO_477(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_479(MACRO, ...) \
+MACRO(479, __VA_ARGS__) \
+DO_478(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_480(MACRO, ...) \
+MACRO(480, __VA_ARGS__) \
+DO_479(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_481(MACRO, ...) \
+MACRO(481, __VA_ARGS__) \
+DO_480(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_482(MACRO, ...) \
+MACRO(482, __VA_ARGS__) \
+DO_481(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_483(MACRO, ...) \
+MACRO(483, __VA_ARGS__) \
+DO_482(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_484(MACRO, ...) \
+MACRO(484, __VA_ARGS__) \
+DO_483(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_485(MACRO, ...) \
+MACRO(485, __VA_ARGS__) \
+DO_484(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_486(MACRO, ...) \
+MACRO(486, __VA_ARGS__) \
+DO_485(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_487(MACRO, ...) \
+MACRO(487, __VA_ARGS__) \
+DO_486(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_488(MACRO, ...) \
+MACRO(488, __VA_ARGS__) \
+DO_487(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_489(MACRO, ...) \
+MACRO(489, __VA_ARGS__) \
+DO_488(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_490(MACRO, ...) \
+MACRO(490, __VA_ARGS__) \
+DO_489(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_491(MACRO, ...) \
+MACRO(491, __VA_ARGS__) \
+DO_490(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_492(MACRO, ...) \
+MACRO(492, __VA_ARGS__) \
+DO_491(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_493(MACRO, ...) \
+MACRO(493, __VA_ARGS__) \
+DO_492(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_494(MACRO, ...) \
+MACRO(494, __VA_ARGS__) \
+DO_493(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_495(MACRO, ...) \
+MACRO(495, __VA_ARGS__) \
+DO_494(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_496(MACRO, ...) \
+MACRO(496, __VA_ARGS__) \
+DO_495(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_497(MACRO, ...) \
+MACRO(497, __VA_ARGS__) \
+DO_496(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_498(MACRO, ...) \
+MACRO(498, __VA_ARGS__) \
+DO_497(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_499(MACRO, ...) \
+MACRO(499, __VA_ARGS__) \
+DO_498(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_500(MACRO, ...) \
+MACRO(500, __VA_ARGS__) \
+DO_499(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_501(MACRO, ...) \
+MACRO(501, __VA_ARGS__) \
+DO_500(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_502(MACRO, ...) \
+MACRO(502, __VA_ARGS__) \
+DO_501(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_503(MACRO, ...) \
+MACRO(503, __VA_ARGS__) \
+DO_502(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_504(MACRO, ...) \
+MACRO(504, __VA_ARGS__) \
+DO_503(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_505(MACRO, ...) \
+MACRO(505, __VA_ARGS__) \
+DO_504(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_506(MACRO, ...) \
+MACRO(506, __VA_ARGS__) \
+DO_505(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_507(MACRO, ...) \
+MACRO(507, __VA_ARGS__) \
+DO_506(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_508(MACRO, ...) \
+MACRO(508, __VA_ARGS__) \
+DO_507(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_509(MACRO, ...) \
+MACRO(509, __VA_ARGS__) \
+DO_508(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_510(MACRO, ...) \
+MACRO(510, __VA_ARGS__) \
+DO_509(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_511(MACRO, ...) \
+MACRO(511, __VA_ARGS__) \
+DO_510(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_512(MACRO, ...) \
+MACRO(512, __VA_ARGS__) \
+DO_511(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_513(MACRO, ...) \
+MACRO(513, __VA_ARGS__) \
+DO_512(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_514(MACRO, ...) \
+MACRO(514, __VA_ARGS__) \
+DO_513(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_515(MACRO, ...) \
+MACRO(515, __VA_ARGS__) \
+DO_514(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_516(MACRO, ...) \
+MACRO(516, __VA_ARGS__) \
+DO_515(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_517(MACRO, ...) \
+MACRO(517, __VA_ARGS__) \
+DO_516(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_518(MACRO, ...) \
+MACRO(518, __VA_ARGS__) \
+DO_517(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_519(MACRO, ...) \
+MACRO(519, __VA_ARGS__) \
+DO_518(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_520(MACRO, ...) \
+MACRO(520, __VA_ARGS__) \
+DO_519(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_521(MACRO, ...) \
+MACRO(521, __VA_ARGS__) \
+DO_520(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_522(MACRO, ...) \
+MACRO(522, __VA_ARGS__) \
+DO_521(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_523(MACRO, ...) \
+MACRO(523, __VA_ARGS__) \
+DO_522(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_524(MACRO, ...) \
+MACRO(524, __VA_ARGS__) \
+DO_523(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_525(MACRO, ...) \
+MACRO(525, __VA_ARGS__) \
+DO_524(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_526(MACRO, ...) \
+MACRO(526, __VA_ARGS__) \
+DO_525(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_527(MACRO, ...) \
+MACRO(527, __VA_ARGS__) \
+DO_526(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_528(MACRO, ...) \
+MACRO(528, __VA_ARGS__) \
+DO_527(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_529(MACRO, ...) \
+MACRO(529, __VA_ARGS__) \
+DO_528(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_530(MACRO, ...) \
+MACRO(530, __VA_ARGS__) \
+DO_529(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_531(MACRO, ...) \
+MACRO(531, __VA_ARGS__) \
+DO_530(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_532(MACRO, ...) \
+MACRO(532, __VA_ARGS__) \
+DO_531(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_533(MACRO, ...) \
+MACRO(533, __VA_ARGS__) \
+DO_532(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_534(MACRO, ...) \
+MACRO(534, __VA_ARGS__) \
+DO_533(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_535(MACRO, ...) \
+MACRO(535, __VA_ARGS__) \
+DO_534(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_536(MACRO, ...) \
+MACRO(536, __VA_ARGS__) \
+DO_535(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_537(MACRO, ...) \
+MACRO(537, __VA_ARGS__) \
+DO_536(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_538(MACRO, ...) \
+MACRO(538, __VA_ARGS__) \
+DO_537(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_539(MACRO, ...) \
+MACRO(539, __VA_ARGS__) \
+DO_538(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_540(MACRO, ...) \
+MACRO(540, __VA_ARGS__) \
+DO_539(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_541(MACRO, ...) \
+MACRO(541, __VA_ARGS__) \
+DO_540(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_542(MACRO, ...) \
+MACRO(542, __VA_ARGS__) \
+DO_541(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_543(MACRO, ...) \
+MACRO(543, __VA_ARGS__) \
+DO_542(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_544(MACRO, ...) \
+MACRO(544, __VA_ARGS__) \
+DO_543(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_545(MACRO, ...) \
+MACRO(545, __VA_ARGS__) \
+DO_544(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_546(MACRO, ...) \
+MACRO(546, __VA_ARGS__) \
+DO_545(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_547(MACRO, ...) \
+MACRO(547, __VA_ARGS__) \
+DO_546(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_548(MACRO, ...) \
+MACRO(548, __VA_ARGS__) \
+DO_547(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_549(MACRO, ...) \
+MACRO(549, __VA_ARGS__) \
+DO_548(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_550(MACRO, ...) \
+MACRO(550, __VA_ARGS__) \
+DO_549(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_551(MACRO, ...) \
+MACRO(551, __VA_ARGS__) \
+DO_550(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_552(MACRO, ...) \
+MACRO(552, __VA_ARGS__) \
+DO_551(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_553(MACRO, ...) \
+MACRO(553, __VA_ARGS__) \
+DO_552(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_554(MACRO, ...) \
+MACRO(554, __VA_ARGS__) \
+DO_553(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_555(MACRO, ...) \
+MACRO(555, __VA_ARGS__) \
+DO_554(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_556(MACRO, ...) \
+MACRO(556, __VA_ARGS__) \
+DO_555(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_557(MACRO, ...) \
+MACRO(557, __VA_ARGS__) \
+DO_556(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_558(MACRO, ...) \
+MACRO(558, __VA_ARGS__) \
+DO_557(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_559(MACRO, ...) \
+MACRO(559, __VA_ARGS__) \
+DO_558(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_560(MACRO, ...) \
+MACRO(560, __VA_ARGS__) \
+DO_559(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_561(MACRO, ...) \
+MACRO(561, __VA_ARGS__) \
+DO_560(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_562(MACRO, ...) \
+MACRO(562, __VA_ARGS__) \
+DO_561(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_563(MACRO, ...) \
+MACRO(563, __VA_ARGS__) \
+DO_562(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_564(MACRO, ...) \
+MACRO(564, __VA_ARGS__) \
+DO_563(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_565(MACRO, ...) \
+MACRO(565, __VA_ARGS__) \
+DO_564(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_566(MACRO, ...) \
+MACRO(566, __VA_ARGS__) \
+DO_565(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_567(MACRO, ...) \
+MACRO(567, __VA_ARGS__) \
+DO_566(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_568(MACRO, ...) \
+MACRO(568, __VA_ARGS__) \
+DO_567(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_569(MACRO, ...) \
+MACRO(569, __VA_ARGS__) \
+DO_568(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_570(MACRO, ...) \
+MACRO(570, __VA_ARGS__) \
+DO_569(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_571(MACRO, ...) \
+MACRO(571, __VA_ARGS__) \
+DO_570(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_572(MACRO, ...) \
+MACRO(572, __VA_ARGS__) \
+DO_571(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_573(MACRO, ...) \
+MACRO(573, __VA_ARGS__) \
+DO_572(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_574(MACRO, ...) \
+MACRO(574, __VA_ARGS__) \
+DO_573(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_575(MACRO, ...) \
+MACRO(575, __VA_ARGS__) \
+DO_574(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_576(MACRO, ...) \
+MACRO(576, __VA_ARGS__) \
+DO_575(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_577(MACRO, ...) \
+MACRO(577, __VA_ARGS__) \
+DO_576(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_578(MACRO, ...) \
+MACRO(578, __VA_ARGS__) \
+DO_577(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_579(MACRO, ...) \
+MACRO(579, __VA_ARGS__) \
+DO_578(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_580(MACRO, ...) \
+MACRO(580, __VA_ARGS__) \
+DO_579(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_581(MACRO, ...) \
+MACRO(581, __VA_ARGS__) \
+DO_580(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_582(MACRO, ...) \
+MACRO(582, __VA_ARGS__) \
+DO_581(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_583(MACRO, ...) \
+MACRO(583, __VA_ARGS__) \
+DO_582(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_584(MACRO, ...) \
+MACRO(584, __VA_ARGS__) \
+DO_583(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_585(MACRO, ...) \
+MACRO(585, __VA_ARGS__) \
+DO_584(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_586(MACRO, ...) \
+MACRO(586, __VA_ARGS__) \
+DO_585(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_587(MACRO, ...) \
+MACRO(587, __VA_ARGS__) \
+DO_586(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_588(MACRO, ...) \
+MACRO(588, __VA_ARGS__) \
+DO_587(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_589(MACRO, ...) \
+MACRO(589, __VA_ARGS__) \
+DO_588(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_590(MACRO, ...) \
+MACRO(590, __VA_ARGS__) \
+DO_589(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_591(MACRO, ...) \
+MACRO(591, __VA_ARGS__) \
+DO_590(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_592(MACRO, ...) \
+MACRO(592, __VA_ARGS__) \
+DO_591(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_593(MACRO, ...) \
+MACRO(593, __VA_ARGS__) \
+DO_592(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_594(MACRO, ...) \
+MACRO(594, __VA_ARGS__) \
+DO_593(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_595(MACRO, ...) \
+MACRO(595, __VA_ARGS__) \
+DO_594(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_596(MACRO, ...) \
+MACRO(596, __VA_ARGS__) \
+DO_595(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_597(MACRO, ...) \
+MACRO(597, __VA_ARGS__) \
+DO_596(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_598(MACRO, ...) \
+MACRO(598, __VA_ARGS__) \
+DO_597(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_599(MACRO, ...) \
+MACRO(599, __VA_ARGS__) \
+DO_598(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_600(MACRO, ...) \
+MACRO(600, __VA_ARGS__) \
+DO_599(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_601(MACRO, ...) \
+MACRO(601, __VA_ARGS__) \
+DO_600(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_602(MACRO, ...) \
+MACRO(602, __VA_ARGS__) \
+DO_601(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_603(MACRO, ...) \
+MACRO(603, __VA_ARGS__) \
+DO_602(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_604(MACRO, ...) \
+MACRO(604, __VA_ARGS__) \
+DO_603(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_605(MACRO, ...) \
+MACRO(605, __VA_ARGS__) \
+DO_604(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_606(MACRO, ...) \
+MACRO(606, __VA_ARGS__) \
+DO_605(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_607(MACRO, ...) \
+MACRO(607, __VA_ARGS__) \
+DO_606(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_608(MACRO, ...) \
+MACRO(608, __VA_ARGS__) \
+DO_607(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_609(MACRO, ...) \
+MACRO(609, __VA_ARGS__) \
+DO_608(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_610(MACRO, ...) \
+MACRO(610, __VA_ARGS__) \
+DO_609(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_611(MACRO, ...) \
+MACRO(611, __VA_ARGS__) \
+DO_610(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_612(MACRO, ...) \
+MACRO(612, __VA_ARGS__) \
+DO_611(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_613(MACRO, ...) \
+MACRO(613, __VA_ARGS__) \
+DO_612(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_614(MACRO, ...) \
+MACRO(614, __VA_ARGS__) \
+DO_613(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_615(MACRO, ...) \
+MACRO(615, __VA_ARGS__) \
+DO_614(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_616(MACRO, ...) \
+MACRO(616, __VA_ARGS__) \
+DO_615(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_617(MACRO, ...) \
+MACRO(617, __VA_ARGS__) \
+DO_616(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_618(MACRO, ...) \
+MACRO(618, __VA_ARGS__) \
+DO_617(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_619(MACRO, ...) \
+MACRO(619, __VA_ARGS__) \
+DO_618(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_620(MACRO, ...) \
+MACRO(620, __VA_ARGS__) \
+DO_619(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_621(MACRO, ...) \
+MACRO(621, __VA_ARGS__) \
+DO_620(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_622(MACRO, ...) \
+MACRO(622, __VA_ARGS__) \
+DO_621(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_623(MACRO, ...) \
+MACRO(623, __VA_ARGS__) \
+DO_622(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_624(MACRO, ...) \
+MACRO(624, __VA_ARGS__) \
+DO_623(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_625(MACRO, ...) \
+MACRO(625, __VA_ARGS__) \
+DO_624(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_626(MACRO, ...) \
+MACRO(626, __VA_ARGS__) \
+DO_625(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_627(MACRO, ...) \
+MACRO(627, __VA_ARGS__) \
+DO_626(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_628(MACRO, ...) \
+MACRO(628, __VA_ARGS__) \
+DO_627(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_629(MACRO, ...) \
+MACRO(629, __VA_ARGS__) \
+DO_628(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_630(MACRO, ...) \
+MACRO(630, __VA_ARGS__) \
+DO_629(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_631(MACRO, ...) \
+MACRO(631, __VA_ARGS__) \
+DO_630(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_632(MACRO, ...) \
+MACRO(632, __VA_ARGS__) \
+DO_631(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_633(MACRO, ...) \
+MACRO(633, __VA_ARGS__) \
+DO_632(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_634(MACRO, ...) \
+MACRO(634, __VA_ARGS__) \
+DO_633(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_635(MACRO, ...) \
+MACRO(635, __VA_ARGS__) \
+DO_634(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_636(MACRO, ...) \
+MACRO(636, __VA_ARGS__) \
+DO_635(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_637(MACRO, ...) \
+MACRO(637, __VA_ARGS__) \
+DO_636(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_638(MACRO, ...) \
+MACRO(638, __VA_ARGS__) \
+DO_637(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_639(MACRO, ...) \
+MACRO(639, __VA_ARGS__) \
+DO_638(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_640(MACRO, ...) \
+MACRO(640, __VA_ARGS__) \
+DO_639(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_641(MACRO, ...) \
+MACRO(641, __VA_ARGS__) \
+DO_640(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_642(MACRO, ...) \
+MACRO(642, __VA_ARGS__) \
+DO_641(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_643(MACRO, ...) \
+MACRO(643, __VA_ARGS__) \
+DO_642(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_644(MACRO, ...) \
+MACRO(644, __VA_ARGS__) \
+DO_643(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_645(MACRO, ...) \
+MACRO(645, __VA_ARGS__) \
+DO_644(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_646(MACRO, ...) \
+MACRO(646, __VA_ARGS__) \
+DO_645(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_647(MACRO, ...) \
+MACRO(647, __VA_ARGS__) \
+DO_646(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_648(MACRO, ...) \
+MACRO(648, __VA_ARGS__) \
+DO_647(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_649(MACRO, ...) \
+MACRO(649, __VA_ARGS__) \
+DO_648(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_650(MACRO, ...) \
+MACRO(650, __VA_ARGS__) \
+DO_649(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_651(MACRO, ...) \
+MACRO(651, __VA_ARGS__) \
+DO_650(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_652(MACRO, ...) \
+MACRO(652, __VA_ARGS__) \
+DO_651(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_653(MACRO, ...) \
+MACRO(653, __VA_ARGS__) \
+DO_652(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_654(MACRO, ...) \
+MACRO(654, __VA_ARGS__) \
+DO_653(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_655(MACRO, ...) \
+MACRO(655, __VA_ARGS__) \
+DO_654(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_656(MACRO, ...) \
+MACRO(656, __VA_ARGS__) \
+DO_655(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_657(MACRO, ...) \
+MACRO(657, __VA_ARGS__) \
+DO_656(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_658(MACRO, ...) \
+MACRO(658, __VA_ARGS__) \
+DO_657(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_659(MACRO, ...) \
+MACRO(659, __VA_ARGS__) \
+DO_658(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_660(MACRO, ...) \
+MACRO(660, __VA_ARGS__) \
+DO_659(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_661(MACRO, ...) \
+MACRO(661, __VA_ARGS__) \
+DO_660(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_662(MACRO, ...) \
+MACRO(662, __VA_ARGS__) \
+DO_661(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_663(MACRO, ...) \
+MACRO(663, __VA_ARGS__) \
+DO_662(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_664(MACRO, ...) \
+MACRO(664, __VA_ARGS__) \
+DO_663(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_665(MACRO, ...) \
+MACRO(665, __VA_ARGS__) \
+DO_664(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_666(MACRO, ...) \
+MACRO(666, __VA_ARGS__) \
+DO_665(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_667(MACRO, ...) \
+MACRO(667, __VA_ARGS__) \
+DO_666(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_668(MACRO, ...) \
+MACRO(668, __VA_ARGS__) \
+DO_667(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_669(MACRO, ...) \
+MACRO(669, __VA_ARGS__) \
+DO_668(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_670(MACRO, ...) \
+MACRO(670, __VA_ARGS__) \
+DO_669(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_671(MACRO, ...) \
+MACRO(671, __VA_ARGS__) \
+DO_670(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_672(MACRO, ...) \
+MACRO(672, __VA_ARGS__) \
+DO_671(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_673(MACRO, ...) \
+MACRO(673, __VA_ARGS__) \
+DO_672(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_674(MACRO, ...) \
+MACRO(674, __VA_ARGS__) \
+DO_673(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_675(MACRO, ...) \
+MACRO(675, __VA_ARGS__) \
+DO_674(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_676(MACRO, ...) \
+MACRO(676, __VA_ARGS__) \
+DO_675(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_677(MACRO, ...) \
+MACRO(677, __VA_ARGS__) \
+DO_676(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_678(MACRO, ...) \
+MACRO(678, __VA_ARGS__) \
+DO_677(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_679(MACRO, ...) \
+MACRO(679, __VA_ARGS__) \
+DO_678(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_680(MACRO, ...) \
+MACRO(680, __VA_ARGS__) \
+DO_679(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_681(MACRO, ...) \
+MACRO(681, __VA_ARGS__) \
+DO_680(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_682(MACRO, ...) \
+MACRO(682, __VA_ARGS__) \
+DO_681(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_683(MACRO, ...) \
+MACRO(683, __VA_ARGS__) \
+DO_682(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_684(MACRO, ...) \
+MACRO(684, __VA_ARGS__) \
+DO_683(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_685(MACRO, ...) \
+MACRO(685, __VA_ARGS__) \
+DO_684(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_686(MACRO, ...) \
+MACRO(686, __VA_ARGS__) \
+DO_685(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_687(MACRO, ...) \
+MACRO(687, __VA_ARGS__) \
+DO_686(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_688(MACRO, ...) \
+MACRO(688, __VA_ARGS__) \
+DO_687(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_689(MACRO, ...) \
+MACRO(689, __VA_ARGS__) \
+DO_688(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_690(MACRO, ...) \
+MACRO(690, __VA_ARGS__) \
+DO_689(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_691(MACRO, ...) \
+MACRO(691, __VA_ARGS__) \
+DO_690(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_692(MACRO, ...) \
+MACRO(692, __VA_ARGS__) \
+DO_691(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_693(MACRO, ...) \
+MACRO(693, __VA_ARGS__) \
+DO_692(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_694(MACRO, ...) \
+MACRO(694, __VA_ARGS__) \
+DO_693(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_695(MACRO, ...) \
+MACRO(695, __VA_ARGS__) \
+DO_694(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_696(MACRO, ...) \
+MACRO(696, __VA_ARGS__) \
+DO_695(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_697(MACRO, ...) \
+MACRO(697, __VA_ARGS__) \
+DO_696(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_698(MACRO, ...) \
+MACRO(698, __VA_ARGS__) \
+DO_697(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_699(MACRO, ...) \
+MACRO(699, __VA_ARGS__) \
+DO_698(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_700(MACRO, ...) \
+MACRO(700, __VA_ARGS__) \
+DO_699(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_701(MACRO, ...) \
+MACRO(701, __VA_ARGS__) \
+DO_700(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_702(MACRO, ...) \
+MACRO(702, __VA_ARGS__) \
+DO_701(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_703(MACRO, ...) \
+MACRO(703, __VA_ARGS__) \
+DO_702(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_704(MACRO, ...) \
+MACRO(704, __VA_ARGS__) \
+DO_703(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_705(MACRO, ...) \
+MACRO(705, __VA_ARGS__) \
+DO_704(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_706(MACRO, ...) \
+MACRO(706, __VA_ARGS__) \
+DO_705(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_707(MACRO, ...) \
+MACRO(707, __VA_ARGS__) \
+DO_706(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_708(MACRO, ...) \
+MACRO(708, __VA_ARGS__) \
+DO_707(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_709(MACRO, ...) \
+MACRO(709, __VA_ARGS__) \
+DO_708(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_710(MACRO, ...) \
+MACRO(710, __VA_ARGS__) \
+DO_709(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_711(MACRO, ...) \
+MACRO(711, __VA_ARGS__) \
+DO_710(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_712(MACRO, ...) \
+MACRO(712, __VA_ARGS__) \
+DO_711(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_713(MACRO, ...) \
+MACRO(713, __VA_ARGS__) \
+DO_712(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_714(MACRO, ...) \
+MACRO(714, __VA_ARGS__) \
+DO_713(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_715(MACRO, ...) \
+MACRO(715, __VA_ARGS__) \
+DO_714(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_716(MACRO, ...) \
+MACRO(716, __VA_ARGS__) \
+DO_715(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_717(MACRO, ...) \
+MACRO(717, __VA_ARGS__) \
+DO_716(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_718(MACRO, ...) \
+MACRO(718, __VA_ARGS__) \
+DO_717(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_719(MACRO, ...) \
+MACRO(719, __VA_ARGS__) \
+DO_718(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_720(MACRO, ...) \
+MACRO(720, __VA_ARGS__) \
+DO_719(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_721(MACRO, ...) \
+MACRO(721, __VA_ARGS__) \
+DO_720(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_722(MACRO, ...) \
+MACRO(722, __VA_ARGS__) \
+DO_721(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_723(MACRO, ...) \
+MACRO(723, __VA_ARGS__) \
+DO_722(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_724(MACRO, ...) \
+MACRO(724, __VA_ARGS__) \
+DO_723(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_725(MACRO, ...) \
+MACRO(725, __VA_ARGS__) \
+DO_724(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_726(MACRO, ...) \
+MACRO(726, __VA_ARGS__) \
+DO_725(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_727(MACRO, ...) \
+MACRO(727, __VA_ARGS__) \
+DO_726(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_728(MACRO, ...) \
+MACRO(728, __VA_ARGS__) \
+DO_727(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_729(MACRO, ...) \
+MACRO(729, __VA_ARGS__) \
+DO_728(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_730(MACRO, ...) \
+MACRO(730, __VA_ARGS__) \
+DO_729(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_731(MACRO, ...) \
+MACRO(731, __VA_ARGS__) \
+DO_730(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_732(MACRO, ...) \
+MACRO(732, __VA_ARGS__) \
+DO_731(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_733(MACRO, ...) \
+MACRO(733, __VA_ARGS__) \
+DO_732(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_734(MACRO, ...) \
+MACRO(734, __VA_ARGS__) \
+DO_733(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_735(MACRO, ...) \
+MACRO(735, __VA_ARGS__) \
+DO_734(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_736(MACRO, ...) \
+MACRO(736, __VA_ARGS__) \
+DO_735(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_737(MACRO, ...) \
+MACRO(737, __VA_ARGS__) \
+DO_736(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_738(MACRO, ...) \
+MACRO(738, __VA_ARGS__) \
+DO_737(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_739(MACRO, ...) \
+MACRO(739, __VA_ARGS__) \
+DO_738(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_740(MACRO, ...) \
+MACRO(740, __VA_ARGS__) \
+DO_739(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_741(MACRO, ...) \
+MACRO(741, __VA_ARGS__) \
+DO_740(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_742(MACRO, ...) \
+MACRO(742, __VA_ARGS__) \
+DO_741(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_743(MACRO, ...) \
+MACRO(743, __VA_ARGS__) \
+DO_742(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_744(MACRO, ...) \
+MACRO(744, __VA_ARGS__) \
+DO_743(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_745(MACRO, ...) \
+MACRO(745, __VA_ARGS__) \
+DO_744(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_746(MACRO, ...) \
+MACRO(746, __VA_ARGS__) \
+DO_745(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_747(MACRO, ...) \
+MACRO(747, __VA_ARGS__) \
+DO_746(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_748(MACRO, ...) \
+MACRO(748, __VA_ARGS__) \
+DO_747(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_749(MACRO, ...) \
+MACRO(749, __VA_ARGS__) \
+DO_748(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_750(MACRO, ...) \
+MACRO(750, __VA_ARGS__) \
+DO_749(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_751(MACRO, ...) \
+MACRO(751, __VA_ARGS__) \
+DO_750(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_752(MACRO, ...) \
+MACRO(752, __VA_ARGS__) \
+DO_751(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_753(MACRO, ...) \
+MACRO(753, __VA_ARGS__) \
+DO_752(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_754(MACRO, ...) \
+MACRO(754, __VA_ARGS__) \
+DO_753(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_755(MACRO, ...) \
+MACRO(755, __VA_ARGS__) \
+DO_754(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_756(MACRO, ...) \
+MACRO(756, __VA_ARGS__) \
+DO_755(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_757(MACRO, ...) \
+MACRO(757, __VA_ARGS__) \
+DO_756(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_758(MACRO, ...) \
+MACRO(758, __VA_ARGS__) \
+DO_757(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_759(MACRO, ...) \
+MACRO(759, __VA_ARGS__) \
+DO_758(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_760(MACRO, ...) \
+MACRO(760, __VA_ARGS__) \
+DO_759(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_761(MACRO, ...) \
+MACRO(761, __VA_ARGS__) \
+DO_760(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_762(MACRO, ...) \
+MACRO(762, __VA_ARGS__) \
+DO_761(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_763(MACRO, ...) \
+MACRO(763, __VA_ARGS__) \
+DO_762(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_764(MACRO, ...) \
+MACRO(764, __VA_ARGS__) \
+DO_763(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_765(MACRO, ...) \
+MACRO(765, __VA_ARGS__) \
+DO_764(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_766(MACRO, ...) \
+MACRO(766, __VA_ARGS__) \
+DO_765(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_767(MACRO, ...) \
+MACRO(767, __VA_ARGS__) \
+DO_766(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_768(MACRO, ...) \
+MACRO(768, __VA_ARGS__) \
+DO_767(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_769(MACRO, ...) \
+MACRO(769, __VA_ARGS__) \
+DO_768(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_770(MACRO, ...) \
+MACRO(770, __VA_ARGS__) \
+DO_769(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_771(MACRO, ...) \
+MACRO(771, __VA_ARGS__) \
+DO_770(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_772(MACRO, ...) \
+MACRO(772, __VA_ARGS__) \
+DO_771(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_773(MACRO, ...) \
+MACRO(773, __VA_ARGS__) \
+DO_772(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_774(MACRO, ...) \
+MACRO(774, __VA_ARGS__) \
+DO_773(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_775(MACRO, ...) \
+MACRO(775, __VA_ARGS__) \
+DO_774(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_776(MACRO, ...) \
+MACRO(776, __VA_ARGS__) \
+DO_775(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_777(MACRO, ...) \
+MACRO(777, __VA_ARGS__) \
+DO_776(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_778(MACRO, ...) \
+MACRO(778, __VA_ARGS__) \
+DO_777(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_779(MACRO, ...) \
+MACRO(779, __VA_ARGS__) \
+DO_778(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_780(MACRO, ...) \
+MACRO(780, __VA_ARGS__) \
+DO_779(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_781(MACRO, ...) \
+MACRO(781, __VA_ARGS__) \
+DO_780(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_782(MACRO, ...) \
+MACRO(782, __VA_ARGS__) \
+DO_781(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_783(MACRO, ...) \
+MACRO(783, __VA_ARGS__) \
+DO_782(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_784(MACRO, ...) \
+MACRO(784, __VA_ARGS__) \
+DO_783(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_785(MACRO, ...) \
+MACRO(785, __VA_ARGS__) \
+DO_784(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_786(MACRO, ...) \
+MACRO(786, __VA_ARGS__) \
+DO_785(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_787(MACRO, ...) \
+MACRO(787, __VA_ARGS__) \
+DO_786(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_788(MACRO, ...) \
+MACRO(788, __VA_ARGS__) \
+DO_787(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_789(MACRO, ...) \
+MACRO(789, __VA_ARGS__) \
+DO_788(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_790(MACRO, ...) \
+MACRO(790, __VA_ARGS__) \
+DO_789(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_791(MACRO, ...) \
+MACRO(791, __VA_ARGS__) \
+DO_790(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_792(MACRO, ...) \
+MACRO(792, __VA_ARGS__) \
+DO_791(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_793(MACRO, ...) \
+MACRO(793, __VA_ARGS__) \
+DO_792(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_794(MACRO, ...) \
+MACRO(794, __VA_ARGS__) \
+DO_793(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_795(MACRO, ...) \
+MACRO(795, __VA_ARGS__) \
+DO_794(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_796(MACRO, ...) \
+MACRO(796, __VA_ARGS__) \
+DO_795(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_797(MACRO, ...) \
+MACRO(797, __VA_ARGS__) \
+DO_796(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_798(MACRO, ...) \
+MACRO(798, __VA_ARGS__) \
+DO_797(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_799(MACRO, ...) \
+MACRO(799, __VA_ARGS__) \
+DO_798(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_800(MACRO, ...) \
+MACRO(800, __VA_ARGS__) \
+DO_799(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_801(MACRO, ...) \
+MACRO(801, __VA_ARGS__) \
+DO_800(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_802(MACRO, ...) \
+MACRO(802, __VA_ARGS__) \
+DO_801(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_803(MACRO, ...) \
+MACRO(803, __VA_ARGS__) \
+DO_802(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_804(MACRO, ...) \
+MACRO(804, __VA_ARGS__) \
+DO_803(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_805(MACRO, ...) \
+MACRO(805, __VA_ARGS__) \
+DO_804(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_806(MACRO, ...) \
+MACRO(806, __VA_ARGS__) \
+DO_805(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_807(MACRO, ...) \
+MACRO(807, __VA_ARGS__) \
+DO_806(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_808(MACRO, ...) \
+MACRO(808, __VA_ARGS__) \
+DO_807(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_809(MACRO, ...) \
+MACRO(809, __VA_ARGS__) \
+DO_808(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_810(MACRO, ...) \
+MACRO(810, __VA_ARGS__) \
+DO_809(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_811(MACRO, ...) \
+MACRO(811, __VA_ARGS__) \
+DO_810(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_812(MACRO, ...) \
+MACRO(812, __VA_ARGS__) \
+DO_811(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_813(MACRO, ...) \
+MACRO(813, __VA_ARGS__) \
+DO_812(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_814(MACRO, ...) \
+MACRO(814, __VA_ARGS__) \
+DO_813(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_815(MACRO, ...) \
+MACRO(815, __VA_ARGS__) \
+DO_814(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_816(MACRO, ...) \
+MACRO(816, __VA_ARGS__) \
+DO_815(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_817(MACRO, ...) \
+MACRO(817, __VA_ARGS__) \
+DO_816(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_818(MACRO, ...) \
+MACRO(818, __VA_ARGS__) \
+DO_817(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_819(MACRO, ...) \
+MACRO(819, __VA_ARGS__) \
+DO_818(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_820(MACRO, ...) \
+MACRO(820, __VA_ARGS__) \
+DO_819(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_821(MACRO, ...) \
+MACRO(821, __VA_ARGS__) \
+DO_820(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_822(MACRO, ...) \
+MACRO(822, __VA_ARGS__) \
+DO_821(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_823(MACRO, ...) \
+MACRO(823, __VA_ARGS__) \
+DO_822(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_824(MACRO, ...) \
+MACRO(824, __VA_ARGS__) \
+DO_823(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_825(MACRO, ...) \
+MACRO(825, __VA_ARGS__) \
+DO_824(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_826(MACRO, ...) \
+MACRO(826, __VA_ARGS__) \
+DO_825(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_827(MACRO, ...) \
+MACRO(827, __VA_ARGS__) \
+DO_826(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_828(MACRO, ...) \
+MACRO(828, __VA_ARGS__) \
+DO_827(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_829(MACRO, ...) \
+MACRO(829, __VA_ARGS__) \
+DO_828(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_830(MACRO, ...) \
+MACRO(830, __VA_ARGS__) \
+DO_829(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_831(MACRO, ...) \
+MACRO(831, __VA_ARGS__) \
+DO_830(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_832(MACRO, ...) \
+MACRO(832, __VA_ARGS__) \
+DO_831(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_833(MACRO, ...) \
+MACRO(833, __VA_ARGS__) \
+DO_832(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_834(MACRO, ...) \
+MACRO(834, __VA_ARGS__) \
+DO_833(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_835(MACRO, ...) \
+MACRO(835, __VA_ARGS__) \
+DO_834(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_836(MACRO, ...) \
+MACRO(836, __VA_ARGS__) \
+DO_835(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_837(MACRO, ...) \
+MACRO(837, __VA_ARGS__) \
+DO_836(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_838(MACRO, ...) \
+MACRO(838, __VA_ARGS__) \
+DO_837(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_839(MACRO, ...) \
+MACRO(839, __VA_ARGS__) \
+DO_838(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_840(MACRO, ...) \
+MACRO(840, __VA_ARGS__) \
+DO_839(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_841(MACRO, ...) \
+MACRO(841, __VA_ARGS__) \
+DO_840(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_842(MACRO, ...) \
+MACRO(842, __VA_ARGS__) \
+DO_841(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_843(MACRO, ...) \
+MACRO(843, __VA_ARGS__) \
+DO_842(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_844(MACRO, ...) \
+MACRO(844, __VA_ARGS__) \
+DO_843(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_845(MACRO, ...) \
+MACRO(845, __VA_ARGS__) \
+DO_844(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_846(MACRO, ...) \
+MACRO(846, __VA_ARGS__) \
+DO_845(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_847(MACRO, ...) \
+MACRO(847, __VA_ARGS__) \
+DO_846(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_848(MACRO, ...) \
+MACRO(848, __VA_ARGS__) \
+DO_847(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_849(MACRO, ...) \
+MACRO(849, __VA_ARGS__) \
+DO_848(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_850(MACRO, ...) \
+MACRO(850, __VA_ARGS__) \
+DO_849(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_851(MACRO, ...) \
+MACRO(851, __VA_ARGS__) \
+DO_850(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_852(MACRO, ...) \
+MACRO(852, __VA_ARGS__) \
+DO_851(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_853(MACRO, ...) \
+MACRO(853, __VA_ARGS__) \
+DO_852(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_854(MACRO, ...) \
+MACRO(854, __VA_ARGS__) \
+DO_853(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_855(MACRO, ...) \
+MACRO(855, __VA_ARGS__) \
+DO_854(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_856(MACRO, ...) \
+MACRO(856, __VA_ARGS__) \
+DO_855(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_857(MACRO, ...) \
+MACRO(857, __VA_ARGS__) \
+DO_856(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_858(MACRO, ...) \
+MACRO(858, __VA_ARGS__) \
+DO_857(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_859(MACRO, ...) \
+MACRO(859, __VA_ARGS__) \
+DO_858(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_860(MACRO, ...) \
+MACRO(860, __VA_ARGS__) \
+DO_859(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_861(MACRO, ...) \
+MACRO(861, __VA_ARGS__) \
+DO_860(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_862(MACRO, ...) \
+MACRO(862, __VA_ARGS__) \
+DO_861(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_863(MACRO, ...) \
+MACRO(863, __VA_ARGS__) \
+DO_862(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_864(MACRO, ...) \
+MACRO(864, __VA_ARGS__) \
+DO_863(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_865(MACRO, ...) \
+MACRO(865, __VA_ARGS__) \
+DO_864(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_866(MACRO, ...) \
+MACRO(866, __VA_ARGS__) \
+DO_865(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_867(MACRO, ...) \
+MACRO(867, __VA_ARGS__) \
+DO_866(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_868(MACRO, ...) \
+MACRO(868, __VA_ARGS__) \
+DO_867(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_869(MACRO, ...) \
+MACRO(869, __VA_ARGS__) \
+DO_868(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_870(MACRO, ...) \
+MACRO(870, __VA_ARGS__) \
+DO_869(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_871(MACRO, ...) \
+MACRO(871, __VA_ARGS__) \
+DO_870(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_872(MACRO, ...) \
+MACRO(872, __VA_ARGS__) \
+DO_871(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_873(MACRO, ...) \
+MACRO(873, __VA_ARGS__) \
+DO_872(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_874(MACRO, ...) \
+MACRO(874, __VA_ARGS__) \
+DO_873(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_875(MACRO, ...) \
+MACRO(875, __VA_ARGS__) \
+DO_874(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_876(MACRO, ...) \
+MACRO(876, __VA_ARGS__) \
+DO_875(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_877(MACRO, ...) \
+MACRO(877, __VA_ARGS__) \
+DO_876(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_878(MACRO, ...) \
+MACRO(878, __VA_ARGS__) \
+DO_877(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_879(MACRO, ...) \
+MACRO(879, __VA_ARGS__) \
+DO_878(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_880(MACRO, ...) \
+MACRO(880, __VA_ARGS__) \
+DO_879(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_881(MACRO, ...) \
+MACRO(881, __VA_ARGS__) \
+DO_880(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_882(MACRO, ...) \
+MACRO(882, __VA_ARGS__) \
+DO_881(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_883(MACRO, ...) \
+MACRO(883, __VA_ARGS__) \
+DO_882(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_884(MACRO, ...) \
+MACRO(884, __VA_ARGS__) \
+DO_883(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_885(MACRO, ...) \
+MACRO(885, __VA_ARGS__) \
+DO_884(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_886(MACRO, ...) \
+MACRO(886, __VA_ARGS__) \
+DO_885(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_887(MACRO, ...) \
+MACRO(887, __VA_ARGS__) \
+DO_886(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_888(MACRO, ...) \
+MACRO(888, __VA_ARGS__) \
+DO_887(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_889(MACRO, ...) \
+MACRO(889, __VA_ARGS__) \
+DO_888(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_890(MACRO, ...) \
+MACRO(890, __VA_ARGS__) \
+DO_889(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_891(MACRO, ...) \
+MACRO(891, __VA_ARGS__) \
+DO_890(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_892(MACRO, ...) \
+MACRO(892, __VA_ARGS__) \
+DO_891(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_893(MACRO, ...) \
+MACRO(893, __VA_ARGS__) \
+DO_892(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_894(MACRO, ...) \
+MACRO(894, __VA_ARGS__) \
+DO_893(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_895(MACRO, ...) \
+MACRO(895, __VA_ARGS__) \
+DO_894(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_896(MACRO, ...) \
+MACRO(896, __VA_ARGS__) \
+DO_895(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_897(MACRO, ...) \
+MACRO(897, __VA_ARGS__) \
+DO_896(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_898(MACRO, ...) \
+MACRO(898, __VA_ARGS__) \
+DO_897(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_899(MACRO, ...) \
+MACRO(899, __VA_ARGS__) \
+DO_898(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_900(MACRO, ...) \
+MACRO(900, __VA_ARGS__) \
+DO_899(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_901(MACRO, ...) \
+MACRO(901, __VA_ARGS__) \
+DO_900(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_902(MACRO, ...) \
+MACRO(902, __VA_ARGS__) \
+DO_901(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_903(MACRO, ...) \
+MACRO(903, __VA_ARGS__) \
+DO_902(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_904(MACRO, ...) \
+MACRO(904, __VA_ARGS__) \
+DO_903(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_905(MACRO, ...) \
+MACRO(905, __VA_ARGS__) \
+DO_904(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_906(MACRO, ...) \
+MACRO(906, __VA_ARGS__) \
+DO_905(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_907(MACRO, ...) \
+MACRO(907, __VA_ARGS__) \
+DO_906(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_908(MACRO, ...) \
+MACRO(908, __VA_ARGS__) \
+DO_907(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_909(MACRO, ...) \
+MACRO(909, __VA_ARGS__) \
+DO_908(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_910(MACRO, ...) \
+MACRO(910, __VA_ARGS__) \
+DO_909(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_911(MACRO, ...) \
+MACRO(911, __VA_ARGS__) \
+DO_910(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_912(MACRO, ...) \
+MACRO(912, __VA_ARGS__) \
+DO_911(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_913(MACRO, ...) \
+MACRO(913, __VA_ARGS__) \
+DO_912(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_914(MACRO, ...) \
+MACRO(914, __VA_ARGS__) \
+DO_913(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_915(MACRO, ...) \
+MACRO(915, __VA_ARGS__) \
+DO_914(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_916(MACRO, ...) \
+MACRO(916, __VA_ARGS__) \
+DO_915(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_917(MACRO, ...) \
+MACRO(917, __VA_ARGS__) \
+DO_916(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_918(MACRO, ...) \
+MACRO(918, __VA_ARGS__) \
+DO_917(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_919(MACRO, ...) \
+MACRO(919, __VA_ARGS__) \
+DO_918(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_920(MACRO, ...) \
+MACRO(920, __VA_ARGS__) \
+DO_919(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_921(MACRO, ...) \
+MACRO(921, __VA_ARGS__) \
+DO_920(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_922(MACRO, ...) \
+MACRO(922, __VA_ARGS__) \
+DO_921(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_923(MACRO, ...) \
+MACRO(923, __VA_ARGS__) \
+DO_922(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_924(MACRO, ...) \
+MACRO(924, __VA_ARGS__) \
+DO_923(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_925(MACRO, ...) \
+MACRO(925, __VA_ARGS__) \
+DO_924(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_926(MACRO, ...) \
+MACRO(926, __VA_ARGS__) \
+DO_925(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_927(MACRO, ...) \
+MACRO(927, __VA_ARGS__) \
+DO_926(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_928(MACRO, ...) \
+MACRO(928, __VA_ARGS__) \
+DO_927(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_929(MACRO, ...) \
+MACRO(929, __VA_ARGS__) \
+DO_928(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_930(MACRO, ...) \
+MACRO(930, __VA_ARGS__) \
+DO_929(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_931(MACRO, ...) \
+MACRO(931, __VA_ARGS__) \
+DO_930(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_932(MACRO, ...) \
+MACRO(932, __VA_ARGS__) \
+DO_931(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_933(MACRO, ...) \
+MACRO(933, __VA_ARGS__) \
+DO_932(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_934(MACRO, ...) \
+MACRO(934, __VA_ARGS__) \
+DO_933(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_935(MACRO, ...) \
+MACRO(935, __VA_ARGS__) \
+DO_934(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_936(MACRO, ...) \
+MACRO(936, __VA_ARGS__) \
+DO_935(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_937(MACRO, ...) \
+MACRO(937, __VA_ARGS__) \
+DO_936(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_938(MACRO, ...) \
+MACRO(938, __VA_ARGS__) \
+DO_937(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_939(MACRO, ...) \
+MACRO(939, __VA_ARGS__) \
+DO_938(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_940(MACRO, ...) \
+MACRO(940, __VA_ARGS__) \
+DO_939(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_941(MACRO, ...) \
+MACRO(941, __VA_ARGS__) \
+DO_940(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_942(MACRO, ...) \
+MACRO(942, __VA_ARGS__) \
+DO_941(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_943(MACRO, ...) \
+MACRO(943, __VA_ARGS__) \
+DO_942(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_944(MACRO, ...) \
+MACRO(944, __VA_ARGS__) \
+DO_943(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_945(MACRO, ...) \
+MACRO(945, __VA_ARGS__) \
+DO_944(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_946(MACRO, ...) \
+MACRO(946, __VA_ARGS__) \
+DO_945(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_947(MACRO, ...) \
+MACRO(947, __VA_ARGS__) \
+DO_946(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_948(MACRO, ...) \
+MACRO(948, __VA_ARGS__) \
+DO_947(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_949(MACRO, ...) \
+MACRO(949, __VA_ARGS__) \
+DO_948(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_950(MACRO, ...) \
+MACRO(950, __VA_ARGS__) \
+DO_949(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_951(MACRO, ...) \
+MACRO(951, __VA_ARGS__) \
+DO_950(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_952(MACRO, ...) \
+MACRO(952, __VA_ARGS__) \
+DO_951(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_953(MACRO, ...) \
+MACRO(953, __VA_ARGS__) \
+DO_952(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_954(MACRO, ...) \
+MACRO(954, __VA_ARGS__) \
+DO_953(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_955(MACRO, ...) \
+MACRO(955, __VA_ARGS__) \
+DO_954(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_956(MACRO, ...) \
+MACRO(956, __VA_ARGS__) \
+DO_955(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_957(MACRO, ...) \
+MACRO(957, __VA_ARGS__) \
+DO_956(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_958(MACRO, ...) \
+MACRO(958, __VA_ARGS__) \
+DO_957(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_959(MACRO, ...) \
+MACRO(959, __VA_ARGS__) \
+DO_958(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_960(MACRO, ...) \
+MACRO(960, __VA_ARGS__) \
+DO_959(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_961(MACRO, ...) \
+MACRO(961, __VA_ARGS__) \
+DO_960(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_962(MACRO, ...) \
+MACRO(962, __VA_ARGS__) \
+DO_961(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_963(MACRO, ...) \
+MACRO(963, __VA_ARGS__) \
+DO_962(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_964(MACRO, ...) \
+MACRO(964, __VA_ARGS__) \
+DO_963(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_965(MACRO, ...) \
+MACRO(965, __VA_ARGS__) \
+DO_964(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_966(MACRO, ...) \
+MACRO(966, __VA_ARGS__) \
+DO_965(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_967(MACRO, ...) \
+MACRO(967, __VA_ARGS__) \
+DO_966(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_968(MACRO, ...) \
+MACRO(968, __VA_ARGS__) \
+DO_967(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_969(MACRO, ...) \
+MACRO(969, __VA_ARGS__) \
+DO_968(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_970(MACRO, ...) \
+MACRO(970, __VA_ARGS__) \
+DO_969(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_971(MACRO, ...) \
+MACRO(971, __VA_ARGS__) \
+DO_970(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_972(MACRO, ...) \
+MACRO(972, __VA_ARGS__) \
+DO_971(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_973(MACRO, ...) \
+MACRO(973, __VA_ARGS__) \
+DO_972(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_974(MACRO, ...) \
+MACRO(974, __VA_ARGS__) \
+DO_973(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_975(MACRO, ...) \
+MACRO(975, __VA_ARGS__) \
+DO_974(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_976(MACRO, ...) \
+MACRO(976, __VA_ARGS__) \
+DO_975(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_977(MACRO, ...) \
+MACRO(977, __VA_ARGS__) \
+DO_976(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_978(MACRO, ...) \
+MACRO(978, __VA_ARGS__) \
+DO_977(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_979(MACRO, ...) \
+MACRO(979, __VA_ARGS__) \
+DO_978(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_980(MACRO, ...) \
+MACRO(980, __VA_ARGS__) \
+DO_979(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_981(MACRO, ...) \
+MACRO(981, __VA_ARGS__) \
+DO_980(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_982(MACRO, ...) \
+MACRO(982, __VA_ARGS__) \
+DO_981(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_983(MACRO, ...) \
+MACRO(983, __VA_ARGS__) \
+DO_982(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_984(MACRO, ...) \
+MACRO(984, __VA_ARGS__) \
+DO_983(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_985(MACRO, ...) \
+MACRO(985, __VA_ARGS__) \
+DO_984(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_986(MACRO, ...) \
+MACRO(986, __VA_ARGS__) \
+DO_985(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_987(MACRO, ...) \
+MACRO(987, __VA_ARGS__) \
+DO_986(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_988(MACRO, ...) \
+MACRO(988, __VA_ARGS__) \
+DO_987(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_989(MACRO, ...) \
+MACRO(989, __VA_ARGS__) \
+DO_988(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_990(MACRO, ...) \
+MACRO(990, __VA_ARGS__) \
+DO_989(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_991(MACRO, ...) \
+MACRO(991, __VA_ARGS__) \
+DO_990(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_992(MACRO, ...) \
+MACRO(992, __VA_ARGS__) \
+DO_991(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_993(MACRO, ...) \
+MACRO(993, __VA_ARGS__) \
+DO_992(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_994(MACRO, ...) \
+MACRO(994, __VA_ARGS__) \
+DO_993(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_995(MACRO, ...) \
+MACRO(995, __VA_ARGS__) \
+DO_994(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_996(MACRO, ...) \
+MACRO(996, __VA_ARGS__) \
+DO_995(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_997(MACRO, ...) \
+MACRO(997, __VA_ARGS__) \
+DO_996(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_998(MACRO, ...) \
+MACRO(998, __VA_ARGS__) \
+DO_997(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_999(MACRO, ...) \
+MACRO(999, __VA_ARGS__) \
+DO_998(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1000(MACRO, ...) \
+MACRO(1000, __VA_ARGS__) \
+DO_999(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1001(MACRO, ...) \
+MACRO(1001, __VA_ARGS__) \
+DO_1000(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1002(MACRO, ...) \
+MACRO(1002, __VA_ARGS__) \
+DO_1001(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1003(MACRO, ...) \
+MACRO(1003, __VA_ARGS__) \
+DO_1002(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1004(MACRO, ...) \
+MACRO(1004, __VA_ARGS__) \
+DO_1003(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1005(MACRO, ...) \
+MACRO(1005, __VA_ARGS__) \
+DO_1004(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1006(MACRO, ...) \
+MACRO(1006, __VA_ARGS__) \
+DO_1005(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1007(MACRO, ...) \
+MACRO(1007, __VA_ARGS__) \
+DO_1006(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1008(MACRO, ...) \
+MACRO(1008, __VA_ARGS__) \
+DO_1007(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1009(MACRO, ...) \
+MACRO(1009, __VA_ARGS__) \
+DO_1008(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1010(MACRO, ...) \
+MACRO(1010, __VA_ARGS__) \
+DO_1009(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1011(MACRO, ...) \
+MACRO(1011, __VA_ARGS__) \
+DO_1010(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1012(MACRO, ...) \
+MACRO(1012, __VA_ARGS__) \
+DO_1011(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1013(MACRO, ...) \
+MACRO(1013, __VA_ARGS__) \
+DO_1012(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1014(MACRO, ...) \
+MACRO(1014, __VA_ARGS__) \
+DO_1013(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1015(MACRO, ...) \
+MACRO(1015, __VA_ARGS__) \
+DO_1014(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1016(MACRO, ...) \
+MACRO(1016, __VA_ARGS__) \
+DO_1015(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1017(MACRO, ...) \
+MACRO(1017, __VA_ARGS__) \
+DO_1016(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1018(MACRO, ...) \
+MACRO(1018, __VA_ARGS__) \
+DO_1017(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1019(MACRO, ...) \
+MACRO(1019, __VA_ARGS__) \
+DO_1018(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1020(MACRO, ...) \
+MACRO(1020, __VA_ARGS__) \
+DO_1019(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1021(MACRO, ...) \
+MACRO(1021, __VA_ARGS__) \
+DO_1020(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1022(MACRO, ...) \
+MACRO(1022, __VA_ARGS__) \
+DO_1021(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1023(MACRO, ...) \
+MACRO(1023, __VA_ARGS__) \
+DO_1022(MACRO, __VA_ARGS__)
+
+
+#define MU_DO_1024(MACRO, ...) \
+MACRO(1024, __VA_ARGS__) \
+DO_1023(MACRO, __VA_ARGS__)
+
+
+
+#define MU_DO(TIMES, MACRO, ...) MU_C2(MU_DO_, TIMES)(MACRO, __VA_ARGS__)
+
+
+/* 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
+
+
+
+#define MU_DEFINE_ENUMERATION_CONSTANT(x) x,
+/*MU_DEFINE_ENUM goes to header*/
+#define MU_DEFINE_ENUM(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);
+
+
+#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 goes to .c*/
+#define MU_DEFINE_ENUM_STRINGS(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>=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;                                                      \
+    }                                                                           \
+}                                                                               \
+
+#define MU_DEFINE_LOCAL_ENUM(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];                 \
+    }                                                              \
+}
+
+
+#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_DEFINE_MICROMOCK_ENUM_TO_STRING(type, ...) MICROMOCK_ENUM_TO_STRING(type, MU_FOR_EACH_1(MU_DEFINE_ENUMERATION_CONSTANT_AS_WIDESTRING, __VA_ARGS__));
+
+#define MU_EMPTY()
+#define MACRO_UTILS_DELAY(id) id MU_EMPTY MU_LPAREN )
+
+#endif /*MACRO_UTILS_H*/
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/map.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/map.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/map.h	(revision 398)
@@ -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.
+
+/** @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
+
+#include "azure_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/strings.h"
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/optimize_size.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/optimize_size.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/optimize_size.h	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/optionhandler.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/optionhandler.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/optionhandler.h	(revision 398)
@@ -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 OPTIONHANDLER_H
+#define OPTIONHANDLER_H
+
+#include "azure_c_shared_utility/macro_utils.h"
+
+#define OPTIONHANDLER_RESULT_VALUES \
+OPTIONHANDLER_OK, \
+OPTIONHANDLER_ERROR, \
+OPTIONHANDLER_INVALIDARG
+
+MU_DEFINE_ENUM(OPTIONHANDLER_RESULT, OPTIONHANDLER_RESULT_VALUES)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/platform.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/platform.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/platform.h	(revision 398)
@@ -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 "azure_c_shared_utility/umock_c_prod.h"
+
+#define GUID_LENGTH 64
+
+typedef enum PLATFORM_INFO_OPTION_VALUES
+{
+    PLATFORM_INFO_OPTION_DEFAULT,
+    PLATFORM_INFO_OPTION_RETRIEVE_SQM
+} PLATFORM_INFO_OPTION;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+    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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/refcount.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/refcount.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/refcount.h	(revision 398)
@@ -0,0 +1,122 @@
+// 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
+
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/macro_utils.h"
+
+#ifdef __cplusplus
+#include <cstdlib>
+#include <cstdint>
+extern "C"
+{
+#else
+#include <stdlib.h>
+#include <stdint.h>
+#endif
+
+// Include the platform-specific file that defines atomic functionality
+#include "refcount_os.h"
+
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/sastoken.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/sastoken.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/sastoken.h	(revision 398)
@@ -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 SASTOKEN_H
+#define SASTOKEN_H
+
+#include "azure_c_shared_utility/strings.h"
+#include <stdbool.h>
+#include "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/sha-private.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/sha-private.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/sha-private.h	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/sha.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/sha.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/sha.h	(revision 398)
@@ -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.
+
+/**************************** sha.h ****************************/
+/******************* See RFC 4634 for details ******************/
+#ifndef _SHA_H_
+#define _SHA_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ *  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
+ */
+
+#include <stdint.h>
+/*
+ * 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
+ *
+ */
+
+#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 */
+extern int SHA1Reset(SHA1Context *);
+extern int SHA1Input(SHA1Context *, const uint8_t *bytes, unsigned int bytecount);
+extern int SHA1FinalBits(SHA1Context *, const uint8_t bits, unsigned int bitcount);
+extern int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1HashSize]);
+
+/* SHA-224 */
+extern int SHA224Reset(SHA224Context *);
+extern int SHA224Input(SHA224Context *, const uint8_t *bytes, unsigned int bytecount);
+extern int SHA224FinalBits(SHA224Context *, const uint8_t bits, unsigned int bitcount);
+extern int SHA224Result(SHA224Context *, uint8_t Message_Digest[SHA224HashSize]);
+
+/* SHA-256 */
+extern int SHA256Reset(SHA256Context *);
+extern int SHA256Input(SHA256Context *, const uint8_t *bytes, unsigned int bytecount);
+extern int SHA256FinalBits(SHA256Context *, const uint8_t bits, unsigned int bitcount);
+extern int SHA256Result(SHA256Context *, uint8_t Message_Digest[SHA256HashSize]);
+
+/* SHA-384 */
+extern int SHA384Reset(SHA384Context *);
+extern int SHA384Input(SHA384Context *, const uint8_t *bytes, unsigned int bytecount);
+extern int SHA384FinalBits(SHA384Context *, const uint8_t bits, unsigned int bitcount);
+extern int SHA384Result(SHA384Context *, uint8_t Message_Digest[SHA384HashSize]);
+
+/* SHA-512 */
+extern int SHA512Reset(SHA512Context *);
+extern int SHA512Input(SHA512Context *, const uint8_t *bytes, unsigned int bytecount);
+extern int SHA512FinalBits(SHA512Context *, const uint8_t bits, unsigned int bitcount);
+extern int SHA512Result(SHA512Context *, uint8_t Message_Digest[SHA512HashSize]);
+
+/* Unified SHA functions, chosen by whichSha */
+extern int USHAReset(USHAContext *, SHAversion whichSha);
+extern int USHAInput(USHAContext *, const uint8_t *bytes, unsigned int bytecount);
+extern int USHAFinalBits(USHAContext *, const uint8_t bits, unsigned int bitcount);
+extern int USHAResult(USHAContext *, uint8_t Message_Digest[USHAMaxHashSize]);
+extern int USHABlockSize(enum SHAversion whichSha);
+extern int USHAHashSize(enum SHAversion whichSha);
+extern 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.
+ */
+extern 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.
+ */
+extern int hmacReset(HMACContext *ctx, enum SHAversion whichSha, const unsigned char *key, int key_len);
+extern int hmacInput(HMACContext *ctx, const unsigned char *text, int text_len);
+
+extern int hmacFinalBits(HMACContext *ctx, const uint8_t bits, unsigned int bitcount);
+extern int hmacResult(HMACContext *ctx, uint8_t digest[USHAMaxHashSize]);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SHA_H_ */
+
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/shared_util_options.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/shared_util_options.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/shared_util_options.h	(revision 398)
@@ -0,0 +1,57 @@
+// 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";
+
+    // 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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/singlylinkedlist.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/singlylinkedlist.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/singlylinkedlist.h	(revision 398)
@@ -0,0 +1,57 @@
+// 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
+extern "C" {
+#else
+#include "stdbool.h"
+#endif /* __cplusplus */
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/socketio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/socketio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/socketio.h	(revision 398)
@@ -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 SOCKETIO_H
+#define SOCKETIO_H
+
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstddef>
+#else
+#include <stddef.h>
+#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;
+
+#define RECEIVE_BYTES_VALUE     64
+
+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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/string_token.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/string_token.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/string_token.h	(revision 398)
@@ -0,0 +1,92 @@
+// 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>
+extern "C"
+{
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/string_tokenizer.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/string_tokenizer.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/string_tokenizer.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/string_tokenizer_types.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/string_tokenizer_types.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/string_tokenizer_types.h	(revision 398)
@@ -0,0 +1,9 @@
+// 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
+
+typedef struct STRING_TOKEN_TAG* STRING_TOKENIZER_HANDLE;
+
+#endif  /*STRING_TOKENIZER_TYPES_H*/
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/strings.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/strings.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/strings.h	(revision 398)
@@ -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 STRINGS_H
+#define STRINGS_H
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+#include "azure_c_shared_utility/strings_types.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/strings_types.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/strings_types.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/strings_types.h	(revision 398)
@@ -0,0 +1,9 @@
+// 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
+
+typedef struct STRING_TAG* STRING_HANDLE;
+
+#endif  /*STRINGS_TYPES_H*/
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tcpsocketconnection_c.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tcpsocketconnection_c.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tcpsocketconnection_c.h	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/threadapi.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/threadapi.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/threadapi.h	(revision 398)
@@ -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_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tickcounter.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tickcounter.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tickcounter.h	(revision 398)
@@ -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 TICKCOUNTER_H
+#define TICKCOUNTER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include <stdint.h>
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#if defined(_WIN32) || defined(__MBED__)
+    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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tlsio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tlsio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tlsio.h	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tlsio_mbedtls.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tlsio_mbedtls.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/tlsio_mbedtls.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/umock_c_prod.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/umock_c_prod.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/umock_c_prod.h	(revision 398)
@@ -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.
+
+#undef MOCKABLE_FUNCTION
+
+/* 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).
+*/
+
+#ifdef ENABLE_MOCKS
+
+/* 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_UMOCK_INTERNAL_WITH_MOCK(modifiers, result, function, __VA_ARGS__)
+
+#include "umock_c.h"
+
+#else
+
+#include "azure_c_shared_utility/macro_utils.h"
+
+#define UMOCK_C_PROD_ARG_IN_SIGNATURE(count, arg_type, arg_name) arg_type arg_name MU_IFCOMMA(count)
+
+/* 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, ...) \
+    result modifiers function(MU_IF(MU_COUNT_ARG(__VA_ARGS__),,void) MU_FOR_EACH_2_COUNTED(UMOCK_C_PROD_ARG_IN_SIGNATURE, __VA_ARGS__));
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uniqueid.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uniqueid.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uniqueid.h	(revision 398)
@@ -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 UNIQUEID_H
+#define UNIQUEID_H
+
+#include "azure_c_shared_utility/macro_utils.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#endif
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/urlencode.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/urlencode.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/urlencode.h	(revision 398)
@@ -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 URLENCODE_H
+#define URLENCODE_H
+
+#include "azure_c_shared_utility/strings.h"
+
+#include "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/utf8_checker.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/utf8_checker.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/utf8_checker.h	(revision 398)
@@ -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 UTF8_CHECKER_H
+#define UTF8_CHECKER_H
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stdbool.h>
+#include <stddef.h>
+#endif
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uuid.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uuid.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uuid.h	(revision 398)
@@ -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 UUID_H
+#define UUID_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdint>
+extern "C" {
+#else
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#endif /* __cplusplus */
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uws_client.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uws_client.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uws_client.h	(revision 398)
@@ -0,0 +1,118 @@
+// 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
+
+#include "xio.h"
+#include "azure_c_shared_utility/umock_c_prod.h"
+#include "azure_c_shared_utility/optionhandler.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+#include <cstdint>
+extern "C" {
+#else
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uws_frame_encoder.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uws_frame_encoder.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/uws_frame_encoder.h	(revision 398)
@@ -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 UWS_FRAME_ENCODER_H
+#define UWS_FRAME_ENCODER_H
+
+#include "azure_c_shared_utility/buffer_.h"
+#include "azure_c_shared_utility/umock_c_prod.h"
+#include "azure_c_shared_utility/macro_utils.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stdbool.h>
+#include <stddef.h>
+#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(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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/vector.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/vector.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/vector.h	(revision 398)
@@ -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 VECTOR_H
+#define VECTOR_H
+
+#include "azure_c_shared_utility/crt_abstractions.h"
+#include "azure_c_shared_utility/umock_c_prod.h"
+#include "azure_c_shared_utility/vector_types.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C"
+{
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#endif
+
+/* creation */
+MOCKABLE_FUNCTION(, VECTOR_HANDLE, VECTOR_create, size_t, elementSize);
+MOCKABLE_FUNCTION(, VECTOR_HANDLE, VECTOR_move, VECTOR_HANDLE, handle);
+MOCKABLE_FUNCTION(, void, VECTOR_destroy, VECTOR_HANDLE, handle);
+
+/* insertion */
+MOCKABLE_FUNCTION(, int, VECTOR_push_back, VECTOR_HANDLE, handle, const void*, elements, size_t, numElements);
+
+/* removal */
+MOCKABLE_FUNCTION(, void, VECTOR_erase, VECTOR_HANDLE, handle, void*, elements, size_t, numElements);
+MOCKABLE_FUNCTION(, void, VECTOR_clear, VECTOR_HANDLE, handle);
+
+/* access */
+MOCKABLE_FUNCTION(, void*, VECTOR_element, VECTOR_HANDLE, handle, size_t, index);
+MOCKABLE_FUNCTION(, void*, VECTOR_front, VECTOR_HANDLE, handle);
+MOCKABLE_FUNCTION(, void*, VECTOR_back, VECTOR_HANDLE, handle);
+MOCKABLE_FUNCTION(, void*, VECTOR_find_if, VECTOR_HANDLE, handle, PREDICATE_FUNCTION, pred, const void*, value);
+
+/* capacity */
+MOCKABLE_FUNCTION(, size_t, VECTOR_size, VECTOR_HANDLE, handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VECTOR_H */
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/vector_types.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/vector_types.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/vector_types.h	(revision 398)
@@ -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.
+
+#ifndef VECTOR_TYPES_H
+#define VECTOR_TYPES_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#else
+#include <stdbool.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/vector_types_internal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/vector_types_internal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/vector_types_internal.h	(revision 398)
@@ -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 VECTOR_TYPES_INTERNAL_H
+#define VECTOR_TYPES_INTERNAL_H
+
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+
+typedef struct VECTOR_TAG
+{
+    void* storage;
+    size_t count;
+    size_t elementSize;
+} VECTOR;
+
+#endif /* VECTOR_TYPES_INTERNAL_H */
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/wsio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/wsio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/wsio.h	(revision 398)
@@ -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 WSIO_H
+#define WSIO_H
+
+#include "azure_c_shared_utility/xio.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/umock_c_prod.h"
+
+#ifdef __cplusplus
+extern "C" {
+#include <cstddef>
+#else
+#include <stddef.h>
+#include <stdbool.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/xio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/xio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/xio.h	(revision 398)
@@ -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.
+
+#ifndef XIO_H
+#define XIO_H
+
+#include "azure_c_shared_utility/optionhandler.h"
+
+#include "azure_c_shared_utility/umock_c_prod.h"
+#include "azure_c_shared_utility/macro_utils.h"
+
+#ifdef __cplusplus
+#include <cstddef>
+extern "C" {
+#else
+#include <stddef.h>
+#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_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/xlogging.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/xlogging.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/inc/azure_c_shared_utility/xlogging.h	(revision 398)
@@ -0,0 +1,163 @@
+// 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
+
+#include "azure_c_shared_utility/agenttime.h"
+#include "azure_c_shared_utility/optimize_size.h"
+
+#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
+extern "C" {
+#else
+#include <stdio.h>
+#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 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__ but the call is behind an if (0) so that it does
+// not actually get executed at runtime
+#if defined _MSC_VER
+// ignore warning C4127 
+#define LOG(log_category, log_options, format, ...) \
+{ \
+    __pragma(warning(suppress: 4127)) \
+    if (0) \
+    { \
+        (void)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
+#define LOG(log_category, log_options, format, ...) { if (0) { (void)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_mbedtls/trunk/azure_iothub/c-utility/pal/toppers/refcount_os.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/pal/toppers/refcount_os.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/pal/toppers/refcount_os.h	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/azure_base64.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/azure_base64.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/azure_base64.c	(revision 398)
@@ -0,0 +1,368 @@
+// 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 <stdint.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 Base64_Encode shall return NULL.]*/
+    encoded = (char*)malloc(neededSize);
+    if (encoded == NULL)
+    {
+        result = NULL;
+        LogError("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 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("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 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 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 Base64_Encode shall return NULL.]*/
+    if (input == NULL)
+    {
+        result = NULL;
+        LogError("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("Base64_Encode:: BUFFER_routines failure.");
+        }
+        else
+        {
+            result = Base64_Encode_Internal(inputBinary, inputSize);
+        }
+    }
+    return result;
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/buffer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/buffer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/buffer.c	(revision 398)
@@ -0,0 +1,670 @@
+// 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 <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*)malloc(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*)malloc(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*)malloc(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.] */
+        result = MU_FAILURE;
+    }
+    else
+    {
+        BUFFER* b = (BUFFER*)handle;
+        if (b->buffer != NULL)
+        {
+            LogError("Failure buffer data is NULL");
+            free(b->buffer);
+            b->buffer = NULL;
+            b->size = 0;
+            result = 0;
+        }
+        else
+        {
+            /* Codes_SRS_BUFFER_07_015: [BUFFER_unbuild shall return a nonzero value if the unsigned char* referenced by BUFFER_HANDLE is NULL.] */
+            result = MU_FAILURE;
+        }
+    }
+    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*)malloc(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_mbedtls/trunk/azure_iothub/c-utility/src/connection_string_parser.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/connection_string_parser.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/connection_string_parser.c	(revision 398)
@@ -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 "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 <stdbool.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) != 0)
+                                        {
+                                            /* 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_mbedtls/trunk/azure_iothub/c-utility/src/consolelogger.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/consolelogger.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/consolelogger.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/constbuffer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/constbuffer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/constbuffer.c	(revision 398)
@@ -0,0 +1,240 @@
+// 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 "azure_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/gballoc.h"
+#include "azure_c_shared_utility/constbuffer.h"
+#include "azure_c_shared_utility/xlogging.h"
+#include "azure_c_shared_utility/refcount.h"
+
+#define CONSTBUFFER_TYPE_VALUES \
+    CONSTBUFFER_TYPE_COPIED, \
+    CONSTBUFFER_TYPE_MEMORY_MOVED, \
+    CONSTBUFFER_TYPE_WITH_CUSTOM_FREE
+
+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_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)malloc(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 = (void*)(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;
+}
+
+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*/
+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;
+}
+
+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)malloc(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;
+}
+
+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)malloc(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;
+}
+
+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);
+    }
+}
+
+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;
+}
+
+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
+    {
+        /*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_017: [If the refcount reaches zero, then CONSTBUFFER_DecRef shall deallocate all resources used by the CONSTBUFFER_HANDLE.]*/
+            free(constbufferHandle);
+        }
+    }
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/constmap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/constmap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/constmap.c	(revision 398)
@@ -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 <stddef.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 = %s", MU_ENUM_TO_STRING(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_mbedtls/trunk/azure_iothub/c-utility/src/crt_abstractions.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/crt_abstractions.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/crt_abstractions.c	(revision 398)
@@ -0,0 +1,838 @@
+// 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 <stddef.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)) || \
+        (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_mbedtls/trunk/azure_iothub/c-utility/src/doublylinkedlist.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/doublylinkedlist.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/doublylinkedlist.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/gb_rand.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/gb_rand.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/gb_rand.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/gb_stdio.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/gb_stdio.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/gb_stdio.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/gb_time.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/gb_time.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/gb_time.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/gballoc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/gballoc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/gballoc.c	(revision 398)
@@ -0,0 +1,446 @@
+// 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 <stddef.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*)malloc(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*)malloc(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*)malloc(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_mbedtls/trunk/azure_iothub/c-utility/src/hmac.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/hmac.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/hmac.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/hmacsha256.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/hmacsha256.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/hmacsha256.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/http_proxy_io.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/http_proxy_io.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/http_proxy_io.c	(revision 398)
@@ -0,0 +1,967 @@
+// 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 <stddef.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"
+
+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*)malloc(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 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 = __LINE__;
+    }
+    else
+    {
+        HTTP_PROXY_IO_INSTANCE* http_proxy_io_instance = (HTTP_PROXY_IO_INSTANCE*)http_proxy_io;
+
+        /* Codes_SRS_HTTP_PROXY_IO_01_045: [ None. ]*/
+
+        /* 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. ]*/
+        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");
+            result = __LINE__;
+        }
+        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;
+}
+
+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;
+
+        /* 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. ]*/
+        result = xio_retrieveoptions(http_proxy_io_instance->underlying_io);
+        if (result == NULL)
+        {
+            /* Codes_SRS_HTTP_PROXY_IO_01_048: [ If xio_retrieveoptions fails, http_proxy_io_retrieve_options shall return NULL. ]*/
+            LogError("unable to create option handler");
+        }
+    }
+    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_mbedtls/trunk/azure_iothub/c-utility/src/httpapiex.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/httpapiex.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/httpapiex.c	(revision 398)
@@ -0,0 +1,657 @@
+// 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/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 = %s", MU_ENUM_TO_STRING(HTTPAPIEX_RESULT, result))
+
+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*)malloc(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 (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:
+                        {
+                            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);
+            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_mbedtls/trunk/azure_iothub/c-utility/src/httpapiexsas.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/httpapiexsas.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/httpapiexsas.c	(revision 398)
@@ -0,0 +1,187 @@
+// 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 <time.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_mbedtls/trunk/azure_iothub/c-utility/src/httpheaders.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/httpheaders.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/httpheaders.c	(revision 398)
@@ -0,0 +1,335 @@
+// 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/map.h"
+#include "azure_c_shared_utility/httpheaders.h"
+#include <string.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= %s", MU_ENUM_TO_STRING(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 = %s)", MU_ENUM_TO_STRING(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= %s", MU_ENUM_TO_STRING(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= %s", MU_ENUM_TO_STRING(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= %s", MU_ENUM_TO_STRING(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 = %s)", MU_ENUM_TO_STRING(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= %s", MU_ENUM_TO_STRING(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= %s", MU_ENUM_TO_STRING(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= %s", MU_ENUM_TO_STRING(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= %s", MU_ENUM_TO_STRING(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= %s", MU_ENUM_TO_STRING(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_mbedtls/trunk/azure_iothub/c-utility/src/map.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/map.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/map.c	(revision 398)
@@ -0,0 +1,677 @@
+// 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/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 = %s", MU_ENUM_TO_STRING(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*)malloc(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*)malloc(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_mbedtls/trunk/azure_iothub/c-utility/src/optionhandler.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/optionhandler.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/optionhandler.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/sastoken.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/sastoken.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/sastoken.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/sha1.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/sha1.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/sha1.c	(revision 398)
@@ -0,0 +1,440 @@
+// 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 length)
+{
+    uint32_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 (!SHA1AddLength(context, 8) &&
+            (context->Message_Block_Index == SHA1_Message_Block_Size))
+            SHA1ProcessMessageBlock(context);
+
+        message_array++;
+    }
+
+    return shaSuccess;
+}
+
+/*
+* 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_mbedtls/trunk/azure_iothub/c-utility/src/sha224.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/sha224.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/sha224.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/sha384-512.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/sha384-512.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/sha384-512.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/singlylinkedlist.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/singlylinkedlist.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/singlylinkedlist.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/string_token.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/string_token.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/string_token.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/string_tokenizer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/string_tokenizer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/string_tokenizer.c	(revision 398)
@@ -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 "azure_c_shared_utility/gballoc.h"
+#include <stdbool.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*)malloc(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_mbedtls/trunk/azure_iothub/c-utility/src/strings.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/strings.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/strings.c	(revision 398)
@@ -0,0 +1,859 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+//
+// PUT NO INCLUDES BEFORE HERE
+//
+#include <stdlib.h>
+#include "azure_c_shared_utility/gballoc.h"
+#include <stddef.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+//
+// PUT NO CLIENT LIBRARY INCLUDES BEFORE HERE
+//
+
+#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_mbedtls/trunk/azure_iothub/c-utility/src/urlencode.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/urlencode.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/urlencode.c	(revision 398)
@@ -0,0 +1,351 @@
+// 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 <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_mbedtls/trunk/azure_iothub/c-utility/src/usha.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/usha.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/usha.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/utf8_checker.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/utf8_checker.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/utf8_checker.c	(revision 398)
@@ -0,0 +1,177 @@
+ // 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 <cstddef>
+#include <cstdint>
+#else
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stddef.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_mbedtls/trunk/azure_iothub/c-utility/src/uuid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/uuid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/uuid.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/c-utility/src/uws_client.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/uws_client.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/uws_client.c	(revision 398)
@@ -0,0 +1,2224 @@
+ // 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"
+
+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
+                            {
+                                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
+                            {
+                                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;
+    if (uws_client->on_ws_error != NULL) {
+        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 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)
+        {
+        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_mbedtls/trunk/azure_iothub/c-utility/src/uws_frame_encoder.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/uws_frame_encoder.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/uws_frame_encoder.c	(revision 398)
@@ -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.
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stddef.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_mbedtls/trunk/azure_iothub/c-utility/src/vector.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/vector.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/vector.c	(revision 398)
@@ -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"
+
+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;
+}
+
+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);
+    }
+}
+
+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 */
+
+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 */
+
+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;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+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 */
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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 */
+
+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_mbedtls/trunk/azure_iothub/c-utility/src/wsio.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/wsio.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/wsio.c	(revision 398)
@@ -0,0 +1,826 @@
+ // 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 <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*)malloc(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_mbedtls/trunk/azure_iothub/c-utility/src/xio.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/xio.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/xio.c	(revision 398)
@@ -0,0 +1,303 @@
+// 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 "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_mbedtls/trunk/azure_iothub/c-utility/src/xlogging.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/xlogging.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/c-utility/src/xlogging.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/certs/certs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/certs/certs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/certs/certs.c	(revision 398)
@@ -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.
+
+/* This file contains certs needed to communicate with Azure (IoT) */
+
+#include "certs.h"
+
+const char certificates[] =
+/* DigiCert Baltimore Root */
+"-----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"
+/*DigiCert Global Root CA*/
+"-----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"
+/*D-TRUST Root Class 3 CA 2 2009*/
+"-----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"
+;
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/certs/certs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/certs/certs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/certs/certs.h	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/deps/parson/parson.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/deps/parson/parson.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/deps/parson/parson.c	(revision 398)
@@ -0,0 +1,2048 @@
+/*
+ Parson ( http://kgabis.github.com/parson/ )
+ Copyright (c) 2012 - 2017 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 <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))
+
+#ifndef __c2__
+#undef malloc
+#undef free
+#endif // !_MSC_VER
+
+#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;
+
+#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 '/':  APPEND_STRING("\\/"); break; /* to make json embeddable in xml\/html */
+            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;
+            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;
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/deps/parson/parson.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/deps/parson/parson.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/deps/parson/parson.h	(revision 398)
@@ -0,0 +1,234 @@
+/*
+ Parson ( http://kgabis.github.com/parson/ )
+ Copyright (c) 2012 - 2017 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);
+
+/* 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_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/blob.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/blob.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/blob.h	(revision 398)
@@ -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_c_shared_utility/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 "azure_c_shared_utility/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(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_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_authorization.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_authorization.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_authorization.h	(revision 398)
@@ -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_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/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(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(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_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_diagnostic.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_diagnostic.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_diagnostic.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_ll_uploadtoblob.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_ll_uploadtoblob.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_ll_uploadtoblob.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_private.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_private.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_private.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_retry_control.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_retry_control.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_client_retry_control.h	(revision 398)
@@ -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 IOTHUB_CLIENT_RETRY_CONTROL
+#define IOTHUB_CLIENT_RETRY_CONTROL
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include "azure_c_shared_utility/optionhandler.h"
+#include "azure_c_shared_utility/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_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_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_transport_ll_private.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_transport_ll_private.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothub_transport_ll_private.h	(revision 398)
@@ -0,0 +1,129 @@
+// 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 "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);
+
+    /** @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;
+    } 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);
+
+#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     /*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_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothubtransport.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothubtransport.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothubtransport.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothubtransport_mqtt_common.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothubtransport_mqtt_common.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/internal/iothubtransport_mqtt_common.h	(revision 398)
@@ -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 IOTHUBTRANSPORT_MQTT_COMMON_H
+#define IOTHUBTRANSPORT_MQTT_COMMON_H
+
+#include "internal/iothub_transport_ll_private.h"
+#include "azure_c_shared_utility/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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOTHUBTRANSPORT_MQTT_COMMON_H */
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client.h	(revision 398)
@@ -0,0 +1,392 @@
+// 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.
+*
+*    @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 "azure_c_shared_utility/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.
+    *
+    * @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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_core.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_core.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_core.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_core_common.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_core_common.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_core_common.h	(revision 398)
@@ -0,0 +1,240 @@
+// 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_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/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(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(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(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(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(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(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(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(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(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(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                            \
+
+    /** @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(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(TRANSPORT_TYPE, TRANSPORT_TYPE_VALUES);
+
+#define DEVICE_TWIN_UPDATE_STATE_VALUES \
+    DEVICE_TWIN_UPDATE_COMPLETE, \
+    DEVICE_TWIN_UPDATE_PARTIAL
+
+    MU_DEFINE_ENUM(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(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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_core_ll.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_core_ll.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_core_ll.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_ll.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_ll.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_ll.h	(revision 398)
@@ -0,0 +1,404 @@
+// 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 "azure_c_shared_utility/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.
+    *
+    * @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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_options.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_options.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_options.h	(revision 398)
@@ -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 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_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    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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_version.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_version.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_client_version.h	(revision 398)
@@ -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.1"
+
+#include "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_device_client_ll.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_device_client_ll.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_device_client_ll.h	(revision 398)
@@ -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_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_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/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.
+    *
+    * @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.
+    *
+    * @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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_message.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_message.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_message.h	(revision 398)
@@ -0,0 +1,362 @@
+// 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_c_shared_utility/macro_utils.h"
+#include "azure_c_shared_utility/map.h"
+#include "azure_c_shared_utility/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(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(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.
+*
+* @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.
+*
+* @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.
+*
+* @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.
+*
+* @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.
+*
+* @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.
+*
+* @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.
+*
+* @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.
+*
+* @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.
+*
+* @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.
+*
+* @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   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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_transport_ll.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_transport_ll.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothub_transport_ll.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothubtransporthttp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothubtransporthttp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothubtransporthttp.h	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothubtransportmqtt.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothubtransportmqtt.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothubtransportmqtt.h	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/iothub_client/inc/iothubtransportmqtt_websockets.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothubtransportmqtt_websockets.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/inc/iothubtransportmqtt_websockets.h	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/iothub_client/src/blob.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/blob.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/blob.c	(revision 398)
@@ -0,0 +1,381 @@
+// 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
+    {
+        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_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client.c	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_authorization.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_authorization.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_authorization.c	(revision 398)
@@ -0,0 +1,705 @@
+// 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/macro_utils.h"
+#include "azure_c_shared_utility/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"
+
+#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;
+    /* Codes_SRS_IoTHub_Authorization_07_001: [if device_id is NULL IoTHubClient_Auth_Create, shall return NULL. ] */
+    if (device_id == NULL)
+    {
+        LogError("Invalid Parameter device_id: %p", device_id);
+        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_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_core_ll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_core_ll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_core_ll.c	(revision 398)
@@ -0,0 +1,2989 @@
+// 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))
+
+MU_DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_FILE_UPLOAD_RESULT, IOTHUB_CLIENT_FILE_UPLOAD_RESULT_VALUES);
+MU_DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_RESULT, IOTHUB_CLIENT_RESULT_VALUES);
+MU_DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_RETRY_POLICY, IOTHUB_CLIENT_RETRY_POLICY_VALUES);
+MU_DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_STATUS, IOTHUB_CLIENT_STATUS_VALUES);
+MU_DEFINE_ENUM_STRINGS(IOTHUB_IDENTITY_TYPE, IOTHUB_IDENTITY_TYPE_VALUE);
+MU_DEFINE_ENUM_STRINGS(IOTHUB_PROCESS_ITEM_RESULT, IOTHUB_PROCESS_ITEM_RESULT_VALUE);
+MU_DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_IOTHUB_METHOD_STATUS, IOTHUB_CLIENT_IOTHUB_METHOD_STATUS_VALUES);
+MU_DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_CONFIRMATION_RESULT, IOTHUB_CLIENT_CONFIRMATION_RESULT_VALUES);
+MU_DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_CONNECTION_STATUS, IOTHUB_CLIENT_CONNECTION_STATUS_VALUES);
+MU_DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_CONNECTION_STATUS_REASON, IOTHUB_CLIENT_CONNECTION_STATUS_REASON_VALUES);
+MU_DEFINE_ENUM_STRINGS(TRANSPORT_TYPE, TRANSPORT_TYPE_VALUES);
+MU_DEFINE_ENUM_STRINGS(DEVICE_TWIN_UPDATE_STATE, DEVICE_TWIN_UPDATE_STATE_VALUES);
+#ifndef DONT_USE_UPLOADTOBLOB
+MU_DEFINE_ENUM_STRINGS(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(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
+}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;
+}
+
+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)
+{
+    STRING_HANDLE result;
+    STRING_HANDLE pfi = platform_get_platform_info(PLATFORM_INFO_OPTION_DEFAULT);
+    if (pfi == NULL)
+    {
+        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 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)time(NULL));
+    STRING_HANDLE product_info = make_product_info(NULL);
+    if (product_info == NULL)
+    {
+        LogError("failed to initialize product info");
+        result = NULL;
+    }
+    else
+    {
+        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");
+            STRING_delete(product_info);
+        }
+        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);
+                    STRING_delete(product_info);
+                    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);
+                    STRING_delete(product_info);
+                    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;
+
+                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);
+                        STRING_delete(product_info);
+                        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);
+                        STRING_delete(product_info);
+                        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);
+                        STRING_delete(product_info);
+                        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);
+                            STRING_delete(product_info);
+                            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);
+                                STRING_delete(product_info);
+                                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);
+                                STRING_delete(product_info);
+                                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);
+                    STRING_delete(product_info);
+                    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);
+                    STRING_delete(product_info);
+                    free(result);
+                    result = NULL;
+                }
+                else
+                {
+                    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);
+                        STRING_delete(product_info);
+                        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->lastMessageReceiveTime = INDEFINITE_TIME;
+                        result->data_msg_id = 1;
+                        result->product_info = product_info;
+
+                        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(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(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);
+            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);
+            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);
+        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;
+            }
+
+            /*Codes_SRS_IOTHUBCLIENT_LL_10_035: [If string concatenation fails, `IoTHubClientCore_LL_SetOption` shall return `IOTHUB_CLIENT_ERRROR`. Otherwise, `IOTHUB_CLIENT_OK` shall be returned. ]*/
+            handleData->product_info = make_product_info((const char*)value);
+            if (handleData->product_info == 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
+        {
+            // 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;
+        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_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_diagnostic.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_diagnostic.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_diagnostic.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_ll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_ll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_ll.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_ll_uploadtoblob.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_ll_uploadtoblob.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_ll_uploadtoblob.c	(revision 398)
@@ -0,0 +1,1145 @@
+// 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: ]*/
+#define FILE_UPLOAD_FAILED_BODY "{ \"isSuccess\":false, \"statusCode\":-1,\"statusDescription\" : \"client not able to connect with the server\" }"
+#define FILE_UPLOAD_ABORTED_BODY "{ \"isSuccess\":false, \"statusCode\":-1,\"statusDescription\" : \"file upload aborted\" }"
+#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, STRING_HANDLE correlationId, 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%s", upload_data->deviceId, STRING_c_str(correlationId), 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");
+
+                                            if (BUFFER_build(responseToIoTHub, (const unsigned char*)FILE_UPLOAD_ABORTED_BODY, sizeof(FILE_UPLOAD_ABORTED_BODY) / sizeof(FILE_UPLOAD_ABORTED_BODY[0])) == 0)
+                                            {
+                                                if (IoTHubClient_LL_UploadToBlob_step3(upload_data, correlationId, 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;
+                                            }
+                                        }
+                                        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: ]*/
+                                            if (BUFFER_build(responseToIoTHub, (const unsigned char*)FILE_UPLOAD_FAILED_BODY, sizeof(FILE_UPLOAD_FAILED_BODY) / sizeof(FILE_UPLOAD_FAILED_BODY[0])) == 0)
+                                            {
+                                                if (IoTHubClient_LL_UploadToBlob_step3(upload_data, correlationId, iotHubHttpApiExHandle, requestHttpHeaders, responseToIoTHub) != 0)
+                                                {
+                                                    LogError("IoTHubClient_LL_UploadToBlob_step3 failed");
+                                                }
+                                            }
+                                            result = IOTHUB_CLIENT_ERROR;
+                                        }
+                                        else
+                                        {
+                                            /*must make a json*/
+                                            unsigned char * response = BUFFER_u_char(responseToIoTHub);
+                                            STRING_HANDLE req_string;
+                                            if(response == NULL)
+                                            {
+                                                req_string = STRING_construct_sprintf("{\"isSuccess\":%s, \"statusCode\":%d, \"statusDescription\":""}", ((httpResponse < 300) ? "true" : "false"), httpResponse);
+                                            }
+                                            else
+                                            {
+                                                req_string = STRING_construct_sprintf("{\"isSuccess\":%s, \"statusCode\":%d, \"statusDescription\":\"%s\"}", ((httpResponse < 300) ? "true" : "false"), httpResponse, 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, correlationId, 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_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_retry_control.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_retry_control.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_client_retry_control.c	(revision 398)
@@ -0,0 +1,514 @@
+// 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)
+
+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 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)
+    {
+        result = retry_control->initial_wait_time_in_secs * (retry_control->retry_count);
+    }
+    // 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)
+    {
+        result = (unsigned int)(pow(2, retry_control->retry_count - 1) * retry_control->initial_wait_time_in_secs);
+    }
+    // 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));
+
+        result = (unsigned int)(pow(2, retry_control->retry_count - 1) * retry_control->initial_wait_time_in_secs * (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;
+
+        // 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_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_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_message.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_message.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_message.c	(revision 398)
@@ -0,0 +1,1027 @@
+// 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(IOTHUB_MESSAGE_RESULT, IOTHUB_MESSAGE_RESULT_VALUES);
+MU_DEFINE_ENUM_STRINGS(IOTHUBMESSAGE_CONTENT_TYPE, IOTHUBMESSAGE_CONTENT_TYPE_VALUES);
+
+#define LOG_IOTHUB_MESSAGE_ERROR() \
+    LogError("(result = %s)", MU_ENUM_TO_STRING(IOTHUB_MESSAGE_RESULT, result));
+
+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;
+}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 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;
+
+            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
+    {
+        IOTHUB_MESSAGE_HANDLE_DATA* handleData = (IOTHUB_MESSAGE_HANDLE_DATA*)iotHubMessageHandle;
+
+        // 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 = NULL;
+        }
+
+        if (mallocAndStrcpy_s(&handleData->contentEncoding, 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;
+}
+
+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_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_transport_ll_private.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_transport_ll_private.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothub_transport_ll_private.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransport.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransport.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransport.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransport_mqtt_common.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransport_mqtt_common.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransport_mqtt_common.c	(revision 398)
@@ -0,0 +1,3594 @@
+// 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 "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
+
+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* IOTHUB_API_VERSION = "2017-11-08-preview";
+
+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";
+
+#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(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;
+    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 isProductInfoSet;
+    int disconnect_recv_flag;
+} MQTTTRANSPORT_HANDLE_DATA, *PMQTTTRANSPORT_HANDLE_DATA;
+
+typedef struct MQTT_DEVICE_TWIN_ITEM_TAG
+{
+    tickcounter_ms_t msgEnqueueTime;
+    tickcounter_ms_t msgPublishTime;
+    size_t retryCount;
+    IOTHUB_IDENTITY_TYPE iothub_type;
+    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;
+    }
+}
+
+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);
+
+    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)
+{
+    (void)urlencode;
+    int result = 0;
+    size_t index = *index_ptr;
+
+    /* 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)
+        {
+            result = addSystemPropertyToTopicString(topic_string, index, CONTENT_ENCODING_PROPERTY, content_encoding, urlencode);
+            index++;
+        }
+    }
+    *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_get_message(MQTTTRANSPORT_HANDLE_DATA* transport_data)
+{
+    MQTT_DEVICE_TWIN_ITEM* result;
+
+    if ((result = (MQTT_DEVICE_TWIN_ITEM*)malloc(sizeof(MQTT_DEVICE_TWIN_ITEM))) == NULL)
+    {
+        LogError("Failed allocating device twin data.");
+    }
+    else
+    {
+        result->packet_id = get_next_packet_id(transport_data);
+        result->iothub_msg_id = 0;
+        result->device_twin_msg_type = RETRIEVE_PROPERTIES;
+        result->retryCount = 0;
+        result->msgPublishTime = 0;
+        result->msgEnqueueTime = 0;
+        result->iothub_type = IOTHUB_TYPE_DEVICE_TWIN;
+        result->device_twin_data = NULL;
+        result->userCallback = NULL;
+        result->userContext = NULL;
+    }
+
+    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 removeExpiredPendingGetTwinRequests(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    tickcounter_ms_t current_ms;
+
+    if (tickcounter_get_current_ms(transport_data->msgTickCounter, &current_ms) == 0)
+    {
+        PDLIST_ENTRY listItem = transport_data->pending_get_twin_queue.Flink;
+
+        while (listItem != &transport_data->pending_get_twin_queue)
+        {
+            DLIST_ENTRY nextListItem;
+            nextListItem.Flink = listItem->Flink;
+            MQTT_DEVICE_TWIN_ITEM* msg_entry = containingRecord(listItem, MQTT_DEVICE_TWIN_ITEM, entry);
+
+            if (((current_ms - msg_entry->msgEnqueueTime) / 1000) >= ON_DEMAND_GET_TWIN_REQUEST_TIMEOUT_SECS)
+            {
+                (void)DList_RemoveEntryList(listItem);
+                msg_entry->userCallback(DEVICE_TWIN_UPDATE_COMPLETE, NULL, 0, msg_entry->userContext);
+                destroy_device_twin_get_message(msg_entry);
+            }
+
+            listItem = nextListItem.Flink;
+        }
+    }
+}
+
+static void removeExpiredGetTwinRequestsPendingAck(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+    tickcounter_ms_t current_ms;
+
+    if (tickcounter_get_current_ms(transport_data->msgTickCounter, &current_ms) == 0)
+    {
+        PDLIST_ENTRY listItem = transport_data->ack_waiting_queue.Flink;
+
+        while (listItem != &transport_data->ack_waiting_queue)
+        {
+            DLIST_ENTRY nextListItem;
+            nextListItem.Flink = listItem->Flink;
+            MQTT_DEVICE_TWIN_ITEM* msg_entry = containingRecord(listItem, MQTT_DEVICE_TWIN_ITEM, entry);
+
+            // Check if it is a on-demand get-twin request.
+            if (msg_entry->device_twin_msg_type == RETRIEVE_PROPERTIES && msg_entry->userCallback != NULL)
+            {
+                if (((current_ms - msg_entry->msgEnqueueTime) / 1000) >= ON_DEMAND_GET_TWIN_REQUEST_TIMEOUT_SECS)
+                {
+                    (void)DList_RemoveEntryList(listItem);
+                    msg_entry->userCallback(DEVICE_TWIN_UPDATE_COMPLETE, NULL, 0, msg_entry->userContext);
+                    destroy_device_twin_get_message(msg_entry);
+                }
+            }
+
+            listItem = nextListItem.Flink;
+        }
+    }
+}
+
+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;
+    mqtt_info->packet_id = get_next_packet_id(transport_data);
+    mqtt_info->device_twin_msg_type = REPORTED_STATE;
+
+    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_DEVICE_DISABLED, 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);
+
+        xio_destroy(transport_data->xioTransport);
+        transport_data->xioTransport = NULL;
+    }
+}
+
+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));
+        }
+        xio_destroy(transport_data->xioTransport);
+        transport_data->xioTransport = NULL;
+
+        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...");
+                break;
+            }
+            case MQTT_CLIENT_PARSE_ERROR:
+            case MQTT_CLIENT_MEMORY_ERROR:
+            case MQTT_CLIENT_UNKNOWN_ERROR:
+            {
+                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 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)
+    {
+        if (!transport_data->isProductInfoSet)
+        {
+            // This requires the iothubClientHandle, which sadly the MQTT transport only gets on DoWork, so this code still needs to remain here.
+            // The correct place for this would be in the Create method, but we don't get the client handle there.
+            // Also, when device multiplexing is used, the customer creates the transport directly and explicitly, when the client is still not created.
+            // This will be a major hurdle when we add device multiplexing to MQTT transport.
+
+            STRING_HANDLE clone;
+            const char* product_info = transport_data->transport_callbacks.prod_info_cb(transport_data->transport_ctx);
+            if (product_info == NULL)
+            {
+                clone = STRING_construct_sprintf("%s%%2F%s", CLIENT_DEVICE_TYPE_PREFIX, IOTHUB_SDK_VERSION);
+            }
+            else
+            {
+                clone = URL_EncodeString(product_info);
+            }
+
+            if (clone == NULL)
+            {
+                LogError("Failed obtaining the product info");
+            }
+            else
+            {
+                if (STRING_concat_with_STRING(transport_data->configPassedThroughUsername, clone) != 0)
+                {
+                    LogError("Failed concatenating the product info");
+                }
+                else
+                {
+                    transport_data->isProductInfoSet = true;
+                }
+
+                STRING_delete(clone);
+            }
+        }
+
+        STRING_HANDLE clientId;
+
+        clientId = buildClientId(STRING_c_str(transport_data->device_id), STRING_c_str(transport_data->module_id));
+        if (NULL == clientId)
+        {
+            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 (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;
+}
+
+static STRING_HANDLE buildConfigForUsername(const IOTHUB_CLIENT_CONFIG* upperConfig, const char* moduleId)
+{
+    if (moduleId == NULL)
+    {
+        return STRING_construct_sprintf("%s.%s/%s/?api-version=%s&DeviceClientType=", upperConfig->iotHubName, upperConfig->iotHubSuffix, upperConfig->deviceId, IOTHUB_API_VERSION);
+    }
+    else
+    {
+        return STRING_construct_sprintf("%s.%s/%s/%s/?api-version=%s&DeviceClientType=", upperConfig->iotHubName, upperConfig->iotHubSuffix, upperConfig->deviceId, moduleId, IOTHUB_API_VERSION);
+    }
+}
+
+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 the 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 = buildConfigForUsername(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->isProductInfoSet = 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_get_message(transport_data)) == 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->msgEnqueueTime) != 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 = (MQTT_DEVICE_TWIN_ITEM*)malloc(sizeof(MQTT_DEVICE_TWIN_ITEM));
+                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.]*/
+                    mqtt_info->iothub_type = item_type;
+                    mqtt_info->iothub_msg_id = iothub_item->device_twin->item_id;
+                    mqtt_info->retryCount = 0;
+                    mqtt_info->userCallback = NULL;
+                    mqtt_info->userContext = NULL;
+                    mqtt_info->msgEnqueueTime = 0;
+
+                    /* 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_get_message(transport_data)) == 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;
+                }
+
+                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);
+        removeExpiredPendingGetTwinRequests(transport_data);
+        removeExpiredGetTwinRequestsPendingAck(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_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;
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransporthttp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransporthttp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransporthttp.c	(revision 398)
@@ -0,0 +1,2540 @@
+// 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 "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(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 = __LINE__;
+    }
+    else if ((corrId = IoTHubMessage_GetCorrelationId(message->messageHandle)) != NULL && HTTPHeaders_ReplaceHeaderNameValuePair(headers, IOTHUB_CORRELATION_ID, corrId) != HTTP_HEADERS_OK)
+    {
+        LogError("unable to HTTPHeaders_ReplaceHeaderNameValuePair");
+        result = __LINE__;
+    }
+    // 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 = __LINE__;
+    }
+    // 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 = __LINE__;
+    }
+    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
+        {
+            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);
+
+                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);
+        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;
+}
+
+/*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;*/
+};
+
+const TRANSPORT_PROVIDER* HTTP_Protocol(void)
+{
+    return &thisTransportProvider;
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransportmqtt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransportmqtt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransportmqtt.c	(revision 398)
@@ -0,0 +1,207 @@
+// 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 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;*/
+};
+
+/* 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_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransportmqtt_websockets.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransportmqtt_websockets.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/iothubtransportmqtt_websockets.c	(revision 398)
@@ -0,0 +1,275 @@
+// 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);
+}
+
+/* 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 ] */
+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
+};
+
+const TRANSPORT_PROVIDER* MQTT_WebSocket_Protocol(void)
+{
+    return &thisTransportProvider_WebSocketsOverTls;
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/version.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/version.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/iothub_client/src/version.c	(revision 398)
@@ -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_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqtt_client.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqtt_client.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqtt_client.h	(revision 398)
@@ -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_c_shared_utility/macro_utils.h"
+#include "azure_umqtt_c/mqttconst.h"
+#include "azure_umqtt_c/mqtt_message.h"
+#include "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqtt_codec.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqtt_codec.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqtt_codec.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqtt_message.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqtt_message.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqtt_message.h	(revision 398)
@@ -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 "azure_c_shared_utility/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_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqttconst.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqttconst.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/inc/azure_umqtt_c/mqttconst.h	(revision 398)
@@ -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_c_shared_utility/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, \
+    UNKNOWN_TYPE
+
+MU_DEFINE_ENUM(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(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_mbedtls/trunk/azure_iothub/umqtt/src/mqtt_client.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/src/mqtt_client.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/src/mqtt_client.c	(revision 398)
@@ -0,0 +1,1319 @@
+// 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/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_c_shared_utility/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_c_shared_utility/macro_utils.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);
+
+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;
+    bool clientConnected;
+    bool socketConnected;
+    bool logTrace;
+    bool rawBytesTrace;
+    tickcounter_ms_t timeSincePing;
+    uint16_t maxPingRespTime;
+} MQTT_CLIENT;
+
+static void on_connection_closed(void* context)
+{
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)context;
+    if (mqtt_client != NULL)
+    {
+        mqtt_client->socketConnected = false;
+        mqtt_client->clientConnected = false;
+        if (mqtt_client->disconnect_cb)
+        {
+            mqtt_client->disconnect_cb(mqtt_client->disconnect_ctx);
+        }
+    }
+}
+
+static void close_connection(MQTT_CLIENT* mqtt_client)
+{
+    if (mqtt_client->socketConnected)
+    {
+        (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->clientConnected && counter < MAX_CLOSE_RETRIES);
+        }
+        // Clear the handle because we don't use it anymore
+        mqtt_client->xioHandle = NULL;
+    }
+    else
+    {
+        if (mqtt_client->disconnect_cb)
+        {
+            mqtt_client->disconnect_cb(mqtt_client->disconnect_ctx);
+        }
+    }
+    mqtt_client->xioHandle = NULL;
+}
+
+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)
+{
+#ifndef NO_LOGGING
+    STRING_HANDLE trace_log;
+    if (mqtt_client->logTrace)
+    {
+        trace_log = STRING_new();
+    }
+    else
+    {
+        trace_log = NULL;
+    }
+    return trace_log;
+#else
+    return NULL;
+#endif
+}
+
+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);
+                }
+                // close the xio
+                close_connection(mqtt_client);
+            }
+        }
+        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 && mqtt_client->rawBytesTrace)
+    {
+        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 && mqtt_client->rawBytesTrace)
+    {
+        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 && mqtt_client->logTrace && 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 && mqtt_client->logTrace && 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("%d: Failure sending control packet data", result);
+            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->socketConnected)
+        {
+            mqtt_client->packetState = CONNECT_TYPE;
+            mqtt_client->socketConnected = true;
+
+            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: mqtt_codec_connect failed");
+                }
+                else
+                {
+                    log_outgoing_trace(mqtt_client, trace_log);
+                }
+                BUFFER_delete(connPacket);
+            }
+            if (trace_log != NULL)
+            {
+                STRING_delete(trace_log);
+            }
+        }
+        else
+        {
+            if (mqtt_client->socketConnected == false && mqtt_client->fnOnErrorCallBack)
+            {
+                mqtt_client->fnOnErrorCallBack(mqtt_client, MQTT_CLIENT_CONNECTION_ERROR, mqtt_client->errorCBCtx);
+            }
+            close_connection(mqtt_client);
+        }
+    }
+    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 (mqtt_client->logTrace)
+        {
+            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 (mqtt_client->logTrace)
+            {
+                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 (mqtt_client->logTrace)
+                {
+                    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);
+                    (void)sendPacketItem(mqtt_client, BUFFER_u_char(pubRel), size);
+                    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 (mqtt_client->logTrace)
+                    {
+                        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->clientConnected = true;
+                    }
+                    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 (mqtt_client->logTrace)
+                    {
+                        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);
+                        (void)sendPacketItem(mqtt_client, BUFFER_u_char(pubRel), size);
+                        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 (mqtt_client->logTrace)
+                    {
+                        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 (mqtt_client->logTrace)
+                            {
+                                STRING_sprintf(trace_log, " | RETURN_CODE: %"PRIu16, suback.qosReturn[suback.qosCount-1]);
+                            }
+#endif
+                        }
+
+#ifndef NO_LOGGING
+                        if (mqtt_client->logTrace)
+                        {
+                            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 (mqtt_client->logTrace)
+                    {
+                        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 (mqtt_client->logTrace)
+                    {
+                        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->clientConnected)
+        {
+            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
+                {
+#ifndef NO_LOGGING
+                    if (mqtt_client->logTrace)
+                    {
+                        STRING_HANDLE trace_log = STRING_construct("DISCONNECT");
+                        log_outgoing_trace(mqtt_client, trace_log);
+                        STRING_delete(trace_log);
+                    }
+#endif
+                    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)
+    {
+        /*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->socketConnected && mqtt_client->clientConnected && 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);
+#ifndef NO_LOGGING
+                        if (mqtt_client->logTrace)
+                        {
+                            STRING_HANDLE trace_log = STRING_construct("PINGREQ");
+                            log_outgoing_trace(mqtt_client, trace_log);
+                            STRING_delete(trace_log);
+                        }
+#endif
+                    }
+                }
+            }
+        }
+    }
+}
+
+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
+    MQTT_CLIENT* mqtt_client = (MQTT_CLIENT*)handle;
+    if (mqtt_client != NULL)
+    {
+        mqtt_client->logTrace = traceOn;
+#ifdef ENABLE_RAW_TRACE
+        mqtt_client->rawBytesTrace = rawBytesOn;
+#endif
+    }
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/src/mqtt_codec.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/src/mqtt_codec.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/src/mqtt_codec.c	(revision 398)
@@ -0,0 +1,1163 @@
+// 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_c_shared_utility/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;
+    if (payloadList == NULL || ctrlPacket == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        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;
+    if (payloadList == NULL || ctrlPacket == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        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;
+    if (ctrlPacket == NULL)
+    {
+        return MU_FAILURE;
+    }
+    else
+    {
+        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;
+    if (mqttOptions == NULL || ctrlPacket == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        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");
+                        //(void)STRING_sprintf(connect_payload_trace, " | PWD: %s", mqttOptions->password);
+                    }
+                }
+                // 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;
+    if (codecData == NULL)
+    {
+        result = MU_FAILURE;
+    }
+    else
+    {
+        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)
+    {
+        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_mbedtls/trunk/azure_iothub/umqtt/src/mqtt_message.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/src/mqtt_message.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/azure_iothub/umqtt/src/mqtt_message.c	(revision 398)
@@ -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_c_shared_utility/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_mbedtls/trunk/mbedtls-2.16.1/.cproject
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/.cproject	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/.cproject	(revision 398)
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1614323811">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1614323811" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings>
+					<externalSetting>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/mbedtls"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/mbedtls-2.16.1"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/mbedtls/Debug"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/mbedtls-2.16.1/Debug"/>
+						<entry flags="RESOLVED" kind="libraryFile" name="mbedtls" srcPrefixMapping="" srcRootPath=""/>
+					</externalSetting>
+				</externalSettings>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="com.renesas.cdt.managedbuild.core.toolchainInfo">
+				<option id="toolchain.id" value="RENESAS_GCC_RX"/>
+				<option id="toolchain.version" value="4.8.4.201803"/>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="mbedtls" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1614323811" name="Debug" parent="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib">
+					<folderInfo id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1614323811." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib.927939148" name="GCC for Renesas RX" superClass="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib">
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.1093188156" name="Optimization Level" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.debug" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections.1608051900" name="Data sections (-fdata-sections)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.1646183555" name="Debug format" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.Default" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.651942453" name="Architecture" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture" useByScannerDiscovery="false" value="com.renesas.cdt.managedbuild.gcc.rx.architecture.v1" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability.645857267" name="Architecture Applicability" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability" useByScannerDiscovery="false" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName.1251084734" name="DeviceName" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName" useByScannerDiscovery="false" value="R5F563NBDxFP" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand.548645922" name="DeviceCommand" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand" useByScannerDiscovery="false" value="R5F563NB" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.functionsections.84131791" name="Function sections (-ffunction-sections)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.64bitdouble.242319505" name="Make the double data type be 64 bits in size" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.64bitdouble" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize.702835400" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize" useByScannerDiscovery="false" value="100" valueType="string"/>
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.renesas.cdt.managedbuild.gcc.core.targetPlatform.1248066055" isAbstract="false" osList="all" superClass="com.renesas.cdt.managedbuild.gcc.core.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/mbedtls}/Debug" id="com.renesas.cdt.managedbuild.gcc.core.builder.1266732649" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GCC for Renesas Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.managedbuild.gcc.core.builder"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen.226548557" name="Library Generator" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen">
+								<option id="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary.865398905" name="Select Library" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.selectLibrary.newLib" valueType="enumerated"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.rx.option.libraryType.216679067" name="Library type" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.libraryType" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType.preBuilt" valueType="enumerated"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.70306465" name="Compiler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.49029144" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" useByScannerDiscovery="false" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
+								</option>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.source.nostdinc.2054355064" name="Do not search system directories (nostdinc)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.source.nostdinc" useByScannerDiscovery="false" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.source.std.542807724" name="Language standard" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.source.std" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.compiler.common.gnu99" valueType="enumerated"/>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.569721306" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler.711034921" name="Compiler CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.1966727795" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" useByScannerDiscovery="false" valueType="includePath"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler.1903436803" name="Assembler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler">
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor.1925801388" name="Use preprocessor" superClass="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor" useByScannerDiscovery="false"/>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler.998398703" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.linker.1181333402" name="Linker" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.linker">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.rx.option.linker.archives.archiveSearchDirectories.1832128205" name="Standard archive search directories" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.linker.archives.archiveSearchDirectories" useByScannerDiscovery="false" valueType="stringList"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker.903075734" name="Linker CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.rx.option.linker.cpp.archives.archiveSearchDirectories.1560358494" name="Standard archive search directories" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.linker.cpp.archives.archiveSearchDirectories" useByScannerDiscovery="false" valueType="stringList"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy.1033771960" name="Objcopy" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver.461296592" name="Archiver" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="library"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="mbedtls.com.renesas.cdt.managedbuild.gcc.rx.ui.projectType.lib.989287343" name="static ã©ã¤ãã©ãªã¼" projectType="com.renesas.cdt.managedbuild.gcc.rx.ui.projectType.lib"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<scannerConfigBuildInfo instanceId="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1614323811;com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.1614323811.;com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.70306465;com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.569721306">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.release.lib.1188671550;com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.release.lib.1188671550.;com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.1285801259;com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.1471946580">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/mbedtls-2.16.1"/>
+		</configuration>
+	</storageModule>
+</cproject>
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/.project
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/.project	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/.project	(revision 398)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>mbedtls</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/LICENSE
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/LICENSE	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/LICENSE	(revision 398)
@@ -0,0 +1,2 @@
+Unless specifically indicated otherwise in a file, files are licensed
+under the Apache 2.0 license, as can be found in: apache-2.0.txt
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/README.md
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/README.md	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/README.md	(revision 398)
@@ -0,0 +1,187 @@
+README for Mbed TLS
+===================
+
+Configuration
+-------------
+
+Mbed TLS should build out of the box on most systems. Some platform specific options are available in the fully documented configuration file `include/mbedtls/config.h`, which is also the place where features can be selected. This file can be edited manually, or in a more programmatic way using the Perl script `scripts/config.pl` (use `--help` for usage instructions).
+
+Compiler options can be set using conventional environment variables such as `CC` and `CFLAGS` when using the Make and CMake build system (see below).
+
+Compiling
+---------
+
+There are currently three active build systems used within Mbed TLS releases:
+
+-   GNU Make
+-   CMake
+-   Microsoft Visual Studio (Microsoft Visual Studio 2010 or later)
+
+The main systems used for development are CMake and GNU Make. Those systems are always complete and up-to-date. The others should reflect all changes present in the CMake and Make build system, although features may not be ported there automatically.
+
+The Make and CMake build systems create three libraries: libmbedcrypto, libmbedx509, and libmbedtls. Note that libmbedtls depends on libmbedx509 and libmbedcrypto, and libmbedx509 depends on libmbedcrypto. As a result, some linkers will expect flags to be in a specific order, for example the GNU linker wants `-lmbedtls -lmbedx509 -lmbedcrypto`. Also, when loading shared libraries using dlopen(), you'll need to load libmbedcrypto first, then libmbedx509, before you can load libmbedtls.
+
+### Make
+
+We require GNU Make. To build the library and the sample programs, GNU Make and a C compiler are sufficient. Some of the more advanced build targets require some Unix/Linux tools.
+
+We intentionally only use a minimum of functionality in the makefiles in order to keep them as simple and independent of different toolchains as possible, to allow users to more easily move between different platforms. Users who need more features are recommended to use CMake.
+
+In order to build from the source code using GNU Make, just enter at the command line:
+
+    make
+
+In order to run the tests, enter:
+
+    make check
+
+The tests need Perl to be built and run. If you don't have Perl installed, you can skip building the tests with:
+
+    make no_test
+
+You'll still be able to run a much smaller set of tests with:
+
+    programs/test/selftest
+
+In order to build for a Windows platform, you should use `WINDOWS_BUILD=1` if the target is Windows but the build environment is Unix-like (for instance when cross-compiling, or compiling from an MSYS shell), and `WINDOWS=1` if the build environment is a Windows shell (for instance using mingw32-make) (in that case some targets will not be available).
+
+Setting the variable `SHARED` in your environment will build shared libraries in addition to the static libraries. Setting `DEBUG` gives you a debug build. You can override `CFLAGS` and `LDFLAGS` by setting them in your environment or on the make command line; compiler warning options may be overridden separately using `WARNING_CFLAGS`. Some directory-specific options (for example, `-I` directives) are still preserved.
+
+Please note that setting `CFLAGS` overrides its default value of `-O2` and setting `WARNING_CFLAGS` overrides its default value (starting with `-Wall -W`), so if you just want to add some warning options to the default ones, you can do so by setting `CFLAGS=-O2 -Werror` for example. Setting `WARNING_CFLAGS` is useful when you want to get rid of its default content (for example because your compiler doesn't accept `-Wall` as an option). Directory-specific options cannot be overriden from the command line.
+
+Depending on your platform, you might run into some issues. Please check the Makefiles in `library/`, `programs/` and `tests/` for options to manually add or remove for specific platforms. You can also check [the Mbed TLS Knowledge Base](https://tls.mbed.org/kb) for articles on your platform or issue.
+
+In case you find that you need to do something else as well, please let us know what, so we can add it to the [Mbed TLS Knowledge Base](https://tls.mbed.org/kb).
+
+### CMake
+
+In order to build the source using CMake in a separate directory (recommended), just enter at the command line:
+
+    mkdir /path/to/build_dir && cd /path/to/build_dir
+    cmake /path/to/mbedtls_source
+    make
+
+In order to run the tests, enter:
+
+    make test
+
+The test suites need Perl to be built. If you don't have Perl installed, you'll want to disable the test suites with:
+
+    cmake -DENABLE_TESTING=Off /path/to/mbedtls_source
+
+If you disabled the test suites, but kept the programs enabled, you can still run a much smaller set of tests with:
+
+    programs/test/selftest
+
+To configure CMake for building shared libraries, use:
+
+    cmake -DUSE_SHARED_MBEDTLS_LIBRARY=On /path/to/mbedtls_source
+
+There are many different build modes available within the CMake buildsystem. Most of them are available for gcc and clang, though some are compiler-specific:
+
+-   `Release`. This generates the default code without any unnecessary information in the binary files.
+-   `Debug`. This generates debug information and disables optimization of the code.
+-   `Coverage`. This generates code coverage information in addition to debug information.
+-   `ASan`. This instruments the code with AddressSanitizer to check for memory errors. (This includes LeakSanitizer, with recent version of gcc and clang.) (With recent version of clang, this mode also instruments the code with UndefinedSanitizer to check for undefined behaviour.)
+-   `ASanDbg`. Same as ASan but slower, with debug information and better stack traces.
+-   `MemSan`. This instruments the code with MemorySanitizer to check for uninitialised memory reads. Experimental, needs recent clang on Linux/x86\_64.
+-   `MemSanDbg`. Same as MemSan but slower, with debug information, better stack traces and origin tracking.
+-   `Check`. This activates the compiler warnings that depend on optimization and treats all warnings as errors.
+
+Switching build modes in CMake is simple. For debug mode, enter at the command line:
+
+    cmake -D CMAKE_BUILD_TYPE=Debug /path/to/mbedtls_source
+
+To list other available CMake options, use:
+
+    cmake -LH
+
+Note that, with CMake, you can't adjust the compiler or its flags after the
+initial invocation of cmake. This means that `CC=your_cc make` and `make
+CC=your_cc` will *not* work (similarly with `CFLAGS` and other variables).
+These variables need to be adjusted when invoking cmake for the first time,
+for example:
+
+    CC=your_cc cmake /path/to/mbedtls_source
+
+If you already invoked cmake and want to change those settings, you need to
+remove the build directory and create it again.
+
+Note that it is possible to build in-place; this will however overwrite the
+provided Makefiles (see `scripts/tmp_ignore_makefiles.sh` if you want to
+prevent `git status` from showing them as modified). In order to do so, from
+the Mbed TLS source directory, use:
+
+    cmake .
+    make
+
+If you want to change `CC` or `CFLAGS` afterwards, you will need to remove the
+CMake cache. This can be done with the following command using GNU find:
+
+    find . -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} +
+
+You can now make the desired change:
+
+    CC=your_cc cmake .
+    make
+
+Regarding variables, also note that if you set CFLAGS when invoking cmake,
+your value of CFLAGS doesn't override the content provided by cmake (depending
+on the build mode as seen above), it's merely prepended to it.
+
+### Microsoft Visual Studio
+
+The build files for Microsoft Visual Studio are generated for Visual Studio 2010.
+
+The solution file `mbedTLS.sln` contains all the basic projects needed to build the library and all the programs. The files in tests are not generated and compiled, as these need a perl environment as well. However, the selftest program in `programs/test/` is still available.
+
+Example programs
+----------------
+
+We've included example programs for a lot of different features and uses in [`programs/`](programs/README.md). Most programs only focus on a single feature or usage scenario, so keep that in mind when copying parts of the code.
+
+Tests
+-----
+
+Mbed TLS includes an elaborate test suite in `tests/` that initially requires Perl to generate the tests files (e.g. `test\_suite\_mpi.c`). These files are generated from a `function file` (e.g. `suites/test\_suite\_mpi.function`) and a `data file` (e.g. `suites/test\_suite\_mpi.data`). The `function file` contains the test functions. The `data file` contains the test cases, specified as parameters that will be passed to the test function.
+
+For machines with a Unix shell and OpenSSL (and optionally GnuTLS) installed, additional test scripts are available:
+
+-   `tests/ssl-opt.sh` runs integration tests for various TLS options (renegotiation, resumption, etc.) and tests interoperability of these options with other implementations.
+-   `tests/compat.sh` tests interoperability of every ciphersuite with other implementations.
+-   `tests/scripts/test-ref-configs.pl` test builds in various reduced configurations.
+-   `tests/scripts/key-exchanges.pl` test builds in configurations with a single key exchange enabled
+-   `tests/scripts/all.sh` runs a combination of the above tests, plus some more, with various build options (such as ASan, full `config.h`, etc).
+
+Configurations
+--------------
+
+We provide some non-standard configurations focused on specific use cases in the `configs/` directory. You can read more about those in `configs/README.txt`
+
+Porting Mbed TLS
+----------------
+
+Mbed TLS can be ported to many different architectures, OS's and platforms. Before starting a port, you may find the following Knowledge Base articles useful:
+
+-   [Porting Mbed TLS to a new environment or OS](https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS)
+-   [What external dependencies does Mbed TLS rely on?](https://tls.mbed.org/kb/development/what-external-dependencies-does-mbedtls-rely-on)
+-   [How do I configure Mbed TLS](https://tls.mbed.org/kb/compiling-and-building/how-do-i-configure-mbedtls)
+
+Contributing
+------------
+
+We gratefully accept bug reports and contributions from the community. There are some requirements we need to fulfill in order to be able to integrate contributions:
+
+-   All contributions, whether large or small require a Contributor's License Agreement (CLA) to be accepted. This is because source code can possibly fall under copyright law and we need your consent to share in the ownership of the copyright.
+-   We would ask that contributions conform to [our coding standards](https://tls.mbed.org/kb/development/mbedtls-coding-standards), and that contributions should be fully tested before submission.
+-   As with any open source project, contributions will be reviewed by the project team and community and may need some modifications to be accepted.
+
+To accept the Contributor’s Licence Agreement (CLA), individual contributors can do this by creating an Mbed account and [accepting the online agreement here with a click through](https://os.mbed.com/contributor_agreement/). Alternatively, for contributions from corporations, or those that do not wish to create an Mbed account, a slightly different agreement can be found [here](https://www.mbed.com/en/about-mbed/contributor-license-agreements/). This agreement should be signed and returned to Arm as described in the instructions given.
+
+### Making a Contribution
+
+1.  [Check for open issues](https://github.com/ARMmbed/mbedtls/issues) or [start a discussion](https://forums.mbed.com/c/mbed-tls) around a feature idea or a bug.
+2.  Fork the [Mbed TLS repository on GitHub](https://github.com/ARMmbed/mbedtls) to start making your changes. As a general rule, you should use the "development" branch as a basis.
+3.  Write a test which shows that the bug was fixed or that the feature works as expected.
+4.  Send a pull request and bug us until it gets merged and published. Contributions may need some modifications, so work with us to get your change accepted. We will include your name in the ChangeLog :)
+
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/apache-2.0.txt
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/apache-2.0.txt	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/apache-2.0.txt	(revision 398)
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/aes.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/aes.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/aes.h	(revision 398)
@@ -0,0 +1,674 @@
+/**
+ * \file aes.h
+ *
+ * \brief   This file contains AES definitions and functions.
+ *
+ *          The Advanced Encryption Standard (AES) specifies a FIPS-approved
+ *          cryptographic algorithm that can be used to protect electronic
+ *          data.
+ *
+ *          The AES algorithm is a symmetric block cipher that can
+ *          encrypt and decrypt information. For more information, see
+ *          <em>FIPS Publication 197: Advanced Encryption Standard</em> and
+ *          <em>ISO/IEC 18033-2:2006: Information technology -- Security
+ *          techniques -- Encryption algorithms -- Part 2: Asymmetric
+ *          ciphers</em>.
+ *
+ *          The AES-XTS block mode is standardized by NIST SP 800-38E
+ *          <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf>
+ *          and described in detail by IEEE P1619
+ *          <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>.
+ */
+
+/*  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_AES_H
+#define MBEDTLS_AES_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* padlock.c and aesni.c rely on these values! */
+#define MBEDTLS_AES_ENCRYPT     1 /**< AES encryption. */
+#define MBEDTLS_AES_DECRYPT     0 /**< AES decryption. */
+
+/* Error codes in range 0x0020-0x0022 */
+#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH                -0x0020  /**< Invalid key length. */
+#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH              -0x0022  /**< Invalid data input length. */
+
+/* Error codes in range 0x0021-0x0025 */
+#define MBEDTLS_ERR_AES_BAD_INPUT_DATA                    -0x0021  /**< Invalid input data. */
+
+/* MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE is deprecated and should not be used. */
+#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE               -0x0023  /**< Feature not available. For example, an unsupported AES key size. */
+
+/* MBEDTLS_ERR_AES_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED                   -0x0025  /**< AES hardware accelerator failed. */
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_AES_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief The AES context-type definition.
+ */
+typedef struct mbedtls_aes_context
+{
+    int nr;                     /*!< The number of rounds. */
+    uint32_t *rk;               /*!< AES round keys. */
+    uint32_t buf[68];           /*!< Unaligned data buffer. This buffer can
+                                     hold 32 extra Bytes, which can be used for
+                                     one of the following purposes:
+                                     <ul><li>Alignment if VIA padlock is
+                                             used.</li>
+                                     <li>Simplifying key expansion in the 256-bit
+                                         case by generating an extra round key.
+                                         </li></ul> */
+}
+mbedtls_aes_context;
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief The AES XTS context-type definition.
+ */
+typedef struct mbedtls_aes_xts_context
+{
+    mbedtls_aes_context crypt; /*!< The AES context to use for AES block
+                                        encryption or decryption. */
+    mbedtls_aes_context tweak; /*!< The AES context used for tweak
+                                        computation. */
+} mbedtls_aes_xts_context;
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#else  /* MBEDTLS_AES_ALT */
+#include "aes_alt.h"
+#endif /* MBEDTLS_AES_ALT */
+
+/**
+ * \brief          This function initializes the specified AES context.
+ *
+ *                 It must be the first API called before using
+ *                 the context.
+ *
+ * \param ctx      The AES context to initialize. This must not be \c NULL.
+ */
+void mbedtls_aes_init( mbedtls_aes_context *ctx );
+
+/**
+ * \brief          This function releases and clears the specified AES context.
+ *
+ * \param ctx      The AES context to clear.
+ *                 If this is \c NULL, this function does nothing.
+ *                 Otherwise, the context must have been at least initialized.
+ */
+void mbedtls_aes_free( mbedtls_aes_context *ctx );
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief          This function initializes the specified AES XTS context.
+ *
+ *                 It must be the first API called before using
+ *                 the context.
+ *
+ * \param ctx      The AES XTS context to initialize. This must not be \c NULL.
+ */
+void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx );
+
+/**
+ * \brief          This function releases and clears the specified AES XTS context.
+ *
+ * \param ctx      The AES XTS context to clear.
+ *                 If this is \c NULL, this function does nothing.
+ *                 Otherwise, the context must have been at least initialized.
+ */
+void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+/**
+ * \brief          This function sets the encryption key.
+ *
+ * \param ctx      The AES context to which the key should be bound.
+ *                 It must be initialized.
+ * \param key      The encryption key.
+ *                 This must be a readable buffer of size \p keybits bits.
+ * \param keybits  The size of data passed in bits. Valid options are:
+ *                 <ul><li>128 bits</li>
+ *                 <li>192 bits</li>
+ *                 <li>256 bits</li></ul>
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
+                    unsigned int keybits );
+
+/**
+ * \brief          This function sets the decryption key.
+ *
+ * \param ctx      The AES context to which the key should be bound.
+ *                 It must be initialized.
+ * \param key      The decryption key.
+ *                 This must be a readable buffer of size \p keybits bits.
+ * \param keybits  The size of data passed. Valid options are:
+ *                 <ul><li>128 bits</li>
+ *                 <li>192 bits</li>
+ *                 <li>256 bits</li></ul>
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
+                    unsigned int keybits );
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief          This function prepares an XTS context for encryption and
+ *                 sets the encryption key.
+ *
+ * \param ctx      The AES XTS context to which the key should be bound.
+ *                 It must be initialized.
+ * \param key      The encryption key. This is comprised of the XTS key1
+ *                 concatenated with the XTS key2.
+ *                 This must be a readable buffer of size \p keybits bits.
+ * \param keybits  The size of \p key passed in bits. Valid options are:
+ *                 <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
+ *                 <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits );
+
+/**
+ * \brief          This function prepares an XTS context for decryption and
+ *                 sets the decryption key.
+ *
+ * \param ctx      The AES XTS context to which the key should be bound.
+ *                 It must be initialized.
+ * \param key      The decryption key. This is comprised of the XTS key1
+ *                 concatenated with the XTS key2.
+ *                 This must be a readable buffer of size \p keybits bits.
+ * \param keybits  The size of \p key passed in bits. Valid options are:
+ *                 <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li>
+ *                 <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul>
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
+ */
+int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+/**
+ * \brief          This function performs an AES single-block encryption or
+ *                 decryption operation.
+ *
+ *                 It performs the operation defined in the \p mode parameter
+ *                 (encrypt or decrypt), on the input data buffer defined in
+ *                 the \p input parameter.
+ *
+ *                 mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or
+ *                 mbedtls_aes_setkey_dec() must be called before the first
+ *                 call to this API with the same context.
+ *
+ * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
+ * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
+ *                 #MBEDTLS_AES_DECRYPT.
+ * \param input    The buffer holding the input data.
+ *                 It must be readable and at least \c 16 Bytes long.
+ * \param output   The buffer where the output data will be written.
+ *                 It must be writeable and at least \c 16 Bytes long.
+
+ * \return         \c 0 on success.
+ */
+int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
+                    int mode,
+                    const unsigned char input[16],
+                    unsigned char output[16] );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/**
+ * \brief  This function performs an AES-CBC encryption or decryption operation
+ *         on full blocks.
+ *
+ *         It performs the operation defined in the \p mode
+ *         parameter (encrypt/decrypt), on the input data buffer defined in
+ *         the \p input parameter.
+ *
+ *         It can be called as many times as needed, until all the input
+ *         data is processed. mbedtls_aes_init(), and either
+ *         mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called
+ *         before the first call to this API with the same context.
+ *
+ * \note   This function operates on full blocks, that is, the input size
+ *         must be a multiple of the AES block size of \c 16 Bytes.
+ *
+ * \note   Upon exit, the content of the IV is updated so that you can
+ *         call the same function again on the next
+ *         block(s) of data and get the same result as if it was
+ *         encrypted in one call. This allows a "streaming" usage.
+ *         If you need to retain the contents of the IV, you should
+ *         either save it manually or use the cipher module instead.
+ *
+ *
+ * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
+ * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
+ *                 #MBEDTLS_AES_DECRYPT.
+ * \param length   The length of the input data in Bytes. This must be a
+ *                 multiple of the block size (\c 16 Bytes).
+ * \param iv       Initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
+ * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
+ * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+ *                 on failure.
+ */
+int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[16],
+                    const unsigned char *input,
+                    unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief      This function performs an AES-XTS encryption or decryption
+ *             operation for an entire XTS data unit.
+ *
+ *             AES-XTS encrypts or decrypts blocks based on their location as
+ *             defined by a data unit number. The data unit number must be
+ *             provided by \p data_unit.
+ *
+ *             NIST SP 800-38E limits the maximum size of a data unit to 2^20
+ *             AES blocks. If the data unit is larger than this, this function
+ *             returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH.
+ *
+ * \param ctx          The AES XTS context to use for AES XTS operations.
+ *                     It must be initialized and bound to a key.
+ * \param mode         The AES operation: #MBEDTLS_AES_ENCRYPT or
+ *                     #MBEDTLS_AES_DECRYPT.
+ * \param length       The length of a data unit in Bytes. This can be any
+ *                     length between 16 bytes and 2^24 bytes inclusive
+ *                     (between 1 and 2^20 block cipher blocks).
+ * \param data_unit    The address of the data unit encoded as an array of 16
+ *                     bytes in little-endian format. For disk encryption, this
+ *                     is typically the index of the block device sector that
+ *                     contains the data.
+ * \param input        The buffer holding the input data (which is an entire
+ *                     data unit). This function reads \p length Bytes from \p
+ *                     input.
+ * \param output       The buffer holding the output data (which is an entire
+ *                     data unit). This function writes \p length Bytes to \p
+ *                     output.
+ *
+ * \return             \c 0 on success.
+ * \return             #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is
+ *                     smaller than an AES block in size (16 Bytes) or if \p
+ *                     length is larger than 2^20 blocks (16 MiB).
+ */
+int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
+                           int mode,
+                           size_t length,
+                           const unsigned char data_unit[16],
+                           const unsigned char *input,
+                           unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/**
+ * \brief This function performs an AES-CFB128 encryption or decryption
+ *        operation.
+ *
+ *        It performs the operation defined in the \p mode
+ *        parameter (encrypt or decrypt), on the input data buffer
+ *        defined in the \p input parameter.
+ *
+ *        For CFB, you must set up the context with mbedtls_aes_setkey_enc(),
+ *        regardless of whether you are performing an encryption or decryption
+ *        operation, that is, regardless of the \p mode parameter. This is
+ *        because CFB mode uses the same key schedule for encryption and
+ *        decryption.
+ *
+ * \note  Upon exit, the content of the IV is updated so that you can
+ *        call the same function again on the next
+ *        block(s) of data and get the same result as if it was
+ *        encrypted in one call. This allows a "streaming" usage.
+ *        If you need to retain the contents of the
+ *        IV, you must either save it manually or use the cipher
+ *        module instead.
+ *
+ *
+ * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
+ * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
+ *                 #MBEDTLS_AES_DECRYPT.
+ * \param length   The length of the input data in Bytes.
+ * \param iv_off   The offset in IV (updated after use).
+ *                 It must point to a valid \c size_t.
+ * \param iv       The initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
+ * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
+ * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
+ *
+ * \return         \c 0 on success.
+ */
+int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output );
+
+/**
+ * \brief This function performs an AES-CFB8 encryption or decryption
+ *        operation.
+ *
+ *        It performs the operation defined in the \p mode
+ *        parameter (encrypt/decrypt), on the input data buffer defined
+ *        in the \p input parameter.
+ *
+ *        Due to the nature of CFB, you must use the same key schedule for
+ *        both encryption and decryption operations. Therefore, you must
+ *        use the context initialized with mbedtls_aes_setkey_enc() for
+ *        both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
+ *
+ * \note  Upon exit, the content of the IV is updated so that you can
+ *        call the same function again on the next
+ *        block(s) of data and get the same result as if it was
+ *        encrypted in one call. This allows a "streaming" usage.
+ *        If you need to retain the contents of the
+ *        IV, you should either save it manually or use the cipher
+ *        module instead.
+ *
+ *
+ * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
+ * \param mode     The AES operation: #MBEDTLS_AES_ENCRYPT or
+ *                 #MBEDTLS_AES_DECRYPT
+ * \param length   The length of the input data.
+ * \param iv       The initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
+ * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
+ * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
+ *
+ * \return         \c 0 on success.
+ */
+int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[16],
+                    const unsigned char *input,
+                    unsigned char *output );
+#endif /*MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/**
+ * \brief       This function performs an AES-OFB (Output Feedback Mode)
+ *              encryption or decryption operation.
+ *
+ *              For OFB, you must set up the context with
+ *              mbedtls_aes_setkey_enc(), regardless of whether you are
+ *              performing an encryption or decryption operation. This is
+ *              because OFB mode uses the same key schedule for encryption and
+ *              decryption.
+ *
+ *              The OFB operation is identical for encryption or decryption,
+ *              therefore no operation mode needs to be specified.
+ *
+ * \note        Upon exit, the content of iv, the Initialisation Vector, is
+ *              updated so that you can call the same function again on the next
+ *              block(s) of data and get the same result as if it was encrypted
+ *              in one call. This allows a "streaming" usage, by initialising
+ *              iv_off to 0 before the first call, and preserving its value
+ *              between calls.
+ *
+ *              For non-streaming use, the iv should be initialised on each call
+ *              to a unique value, and iv_off set to 0 on each call.
+ *
+ *              If you need to retain the contents of the initialisation vector,
+ *              you must either save it manually or use the cipher module
+ *              instead.
+ *
+ * \warning     For the OFB mode, the initialisation vector must be unique
+ *              every encryption operation. Reuse of an initialisation vector
+ *              will compromise security.
+ *
+ * \param ctx      The AES context to use for encryption or decryption.
+ *                 It must be initialized and bound to a key.
+ * \param length   The length of the input data.
+ * \param iv_off   The offset in IV (updated after use).
+ *                 It must point to a valid \c size_t.
+ * \param iv       The initialization vector (updated after use).
+ *                 It must be a readable and writeable buffer of \c 16 Bytes.
+ * \param input    The buffer holding the input data.
+ *                 It must be readable and of size \p length Bytes.
+ * \param output   The buffer holding the output data.
+ *                 It must be writeable and of size \p length Bytes.
+ *
+ * \return         \c 0 on success.
+ */
+int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output );
+
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/**
+ * \brief      This function performs an AES-CTR encryption or decryption
+ *             operation.
+ *
+ *             This function performs the operation defined in the \p mode
+ *             parameter (encrypt/decrypt), on the input data buffer
+ *             defined in the \p input parameter.
+ *
+ *             Due to the nature of CTR, you must use the same key schedule
+ *             for both encryption and decryption operations. Therefore, you
+ *             must use the context initialized with mbedtls_aes_setkey_enc()
+ *             for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT.
+ *
+ * \warning    You must never reuse a nonce value with the same key. Doing so
+ *             would void the encryption for the two messages encrypted with
+ *             the same nonce and key.
+ *
+ *             There are two common strategies for managing nonces with CTR:
+ *
+ *             1. You can handle everything as a single message processed over
+ *             successive calls to this function. In that case, you want to
+ *             set \p nonce_counter and \p nc_off to 0 for the first call, and
+ *             then preserve the values of \p nonce_counter, \p nc_off and \p
+ *             stream_block across calls to this function as they will be
+ *             updated by this function.
+ *
+ *             With this strategy, you must not encrypt more than 2**128
+ *             blocks of data with the same key.
+ *
+ *             2. You can encrypt separate messages by dividing the \p
+ *             nonce_counter buffer in two areas: the first one used for a
+ *             per-message nonce, handled by yourself, and the second one
+ *             updated by this function internally.
+ *
+ *             For example, you might reserve the first 12 bytes for the
+ *             per-message nonce, and the last 4 bytes for internal use. In that
+ *             case, before calling this function on a new message you need to
+ *             set the first 12 bytes of \p nonce_counter to your chosen nonce
+ *             value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
+ *             stream_block to be ignored). That way, you can encrypt at most
+ *             2**96 messages of up to 2**32 blocks each with the same key.
+ *
+ *             The per-message nonce (or information sufficient to reconstruct
+ *             it) needs to be communicated with the ciphertext and must be unique.
+ *             The recommended way to ensure uniqueness is to use a message
+ *             counter. An alternative is to generate random nonces, but this
+ *             limits the number of messages that can be securely encrypted:
+ *             for example, with 96-bit random nonces, you should not encrypt
+ *             more than 2**32 messages with the same key.
+ *
+ *             Note that for both stategies, sizes are measured in blocks and
+ *             that an AES block is 16 bytes.
+ *
+ * \warning    Upon return, \p stream_block contains sensitive data. Its
+ *             content must not be written to insecure storage and should be
+ *             securely discarded as soon as it's no longer needed.
+ *
+ * \param ctx              The AES context to use for encryption or decryption.
+ *                         It must be initialized and bound to a key.
+ * \param length           The length of the input data.
+ * \param nc_off           The offset in the current \p stream_block, for
+ *                         resuming within the current cipher stream. The
+ *                         offset pointer should be 0 at the start of a stream.
+ *                         It must point to a valid \c size_t.
+ * \param nonce_counter    The 128-bit nonce and counter.
+ *                         It must be a readable-writeable buffer of \c 16 Bytes.
+ * \param stream_block     The saved stream block for resuming. This is
+ *                         overwritten by the function.
+ *                         It must be a readable-writeable buffer of \c 16 Bytes.
+ * \param input            The buffer holding the input data.
+ *                         It must be readable and of size \p length Bytes.
+ * \param output           The buffer holding the output data.
+ *                         It must be writeable and of size \p length Bytes.
+ *
+ * \return                 \c 0 on success.
+ */
+int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
+                       size_t length,
+                       size_t *nc_off,
+                       unsigned char nonce_counter[16],
+                       unsigned char stream_block[16],
+                       const unsigned char *input,
+                       unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+/**
+ * \brief           Internal AES block encryption function. This is only
+ *                  exposed to allow overriding it using
+ *                  \c MBEDTLS_AES_ENCRYPT_ALT.
+ *
+ * \param ctx       The AES context to use for encryption.
+ * \param input     The plaintext block.
+ * \param output    The output (ciphertext) block.
+ *
+ * \return          \c 0 on success.
+ */
+int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
+                                  const unsigned char input[16],
+                                  unsigned char output[16] );
+
+/**
+ * \brief           Internal AES block decryption function. This is only
+ *                  exposed to allow overriding it using see
+ *                  \c MBEDTLS_AES_DECRYPT_ALT.
+ *
+ * \param ctx       The AES context to use for decryption.
+ * \param input     The ciphertext block.
+ * \param output    The output (plaintext) block.
+ *
+ * \return          \c 0 on success.
+ */
+int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
+                                  const unsigned char input[16],
+                                  unsigned char output[16] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief           Deprecated internal AES block encryption function
+ *                  without return value.
+ *
+ * \deprecated      Superseded by mbedtls_internal_aes_encrypt()
+ *
+ * \param ctx       The AES context to use for encryption.
+ * \param input     Plaintext block.
+ * \param output    Output (ciphertext) block.
+ */
+MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
+                                             const unsigned char input[16],
+                                             unsigned char output[16] );
+
+/**
+ * \brief           Deprecated internal AES block decryption function
+ *                  without return value.
+ *
+ * \deprecated      Superseded by mbedtls_internal_aes_decrypt()
+ *
+ * \param ctx       The AES context to use for decryption.
+ * \param input     Ciphertext block.
+ * \param output    Output (plaintext) block.
+ */
+MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
+                                             const unsigned char input[16],
+                                             unsigned char output[16] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief          Checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_aes_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* aes.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/aesni.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/aesni.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/aesni.h	(revision 398)
@@ -0,0 +1,138 @@
+/**
+ * \file aesni.h
+ *
+ * \brief AES-NI for hardware AES acceleration on some Intel processors
+ *
+ * \warning These functions are only for internal use by other library
+ *          functions; you must not call them directly.
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_AESNI_H
+#define MBEDTLS_AESNI_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "aes.h"
+
+#define MBEDTLS_AESNI_AES      0x02000000u
+#define MBEDTLS_AESNI_CLMUL    0x00000002u
+
+#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) &&  \
+    ( defined(__amd64__) || defined(__x86_64__) )   &&  \
+    ! defined(MBEDTLS_HAVE_X86_64)
+#define MBEDTLS_HAVE_X86_64
+#endif
+
+#if defined(MBEDTLS_HAVE_X86_64)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          Internal function to detect the AES-NI feature in CPUs.
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
+ *
+ * \param what     The feature to detect
+ *                 (MBEDTLS_AESNI_AES or MBEDTLS_AESNI_CLMUL)
+ *
+ * \return         1 if CPU has support for the feature, 0 otherwise
+ */
+int mbedtls_aesni_has_support( unsigned int what );
+
+/**
+ * \brief          Internal AES-NI AES-ECB block encryption and decryption
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
+ *
+ * \param ctx      AES context
+ * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
+ * \param input    16-byte input block
+ * \param output   16-byte output block
+ *
+ * \return         0 on success (cannot fail)
+ */
+int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
+                             int mode,
+                             const unsigned char input[16],
+                             unsigned char output[16] );
+
+/**
+ * \brief          Internal GCM multiplication: c = a * b in GF(2^128)
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
+ *
+ * \param c        Result
+ * \param a        First operand
+ * \param b        Second operand
+ *
+ * \note           Both operands and result are bit strings interpreted as
+ *                 elements of GF(2^128) as per the GCM spec.
+ */
+void mbedtls_aesni_gcm_mult( unsigned char c[16],
+                             const unsigned char a[16],
+                             const unsigned char b[16] );
+
+/**
+ * \brief           Internal round key inversion. This function computes
+ *                  decryption round keys from the encryption round keys.
+ *
+ * \note            This function is only for internal use by other library
+ *                  functions; you must not call it directly.
+ *
+ * \param invkey    Round keys for the equivalent inverse cipher
+ * \param fwdkey    Original round keys (for encryption)
+ * \param nr        Number of rounds (that is, number of round keys minus one)
+ */
+void mbedtls_aesni_inverse_key( unsigned char *invkey,
+                                const unsigned char *fwdkey,
+                                int nr );
+
+/**
+ * \brief           Internal key expansion for encryption
+ *
+ * \note            This function is only for internal use by other library
+ *                  functions; you must not call it directly.
+ *
+ * \param rk        Destination buffer where the round keys are written
+ * \param key       Encryption key
+ * \param bits      Key size in bits (must be 128, 192 or 256)
+ *
+ * \return          0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
+ */
+int mbedtls_aesni_setkey_enc( unsigned char *rk,
+                              const unsigned char *key,
+                              size_t bits );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_HAVE_X86_64 */
+
+#endif /* MBEDTLS_AESNI_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/arc4.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/arc4.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/arc4.h	(revision 398)
@@ -0,0 +1,146 @@
+/**
+ * \file arc4.h
+ *
+ * \brief The ARCFOUR stream cipher
+ *
+ * \warning   ARC4 is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
+ */
+#ifndef MBEDTLS_ARC4_H
+#define MBEDTLS_ARC4_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+/* MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED                  -0x0019  /**< ARC4 hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_ARC4_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief     ARC4 context structure
+ *
+ * \warning   ARC4 is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ *
+ */
+typedef struct mbedtls_arc4_context
+{
+    int x;                      /*!< permutation index */
+    int y;                      /*!< permutation index */
+    unsigned char m[256];       /*!< permutation table */
+}
+mbedtls_arc4_context;
+
+#else  /* MBEDTLS_ARC4_ALT */
+#include "arc4_alt.h"
+#endif /* MBEDTLS_ARC4_ALT */
+
+/**
+ * \brief          Initialize ARC4 context
+ *
+ * \param ctx      ARC4 context to be initialized
+ *
+ * \warning        ARC4 is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ *
+ */
+void mbedtls_arc4_init( mbedtls_arc4_context *ctx );
+
+/**
+ * \brief          Clear ARC4 context
+ *
+ * \param ctx      ARC4 context to be cleared
+ *
+ * \warning        ARC4 is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ *
+ */
+void mbedtls_arc4_free( mbedtls_arc4_context *ctx );
+
+/**
+ * \brief          ARC4 key schedule
+ *
+ * \param ctx      ARC4 context to be setup
+ * \param key      the secret key
+ * \param keylen   length of the key, in bytes
+ *
+ * \warning        ARC4 is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ *
+ */
+void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
+                 unsigned int keylen );
+
+/**
+ * \brief          ARC4 cipher function
+ *
+ * \param ctx      ARC4 context
+ * \param length   length of the input data
+ * \param input    buffer holding the input data
+ * \param output   buffer for the output data
+ *
+ * \return         0 if successful
+ *
+ * \warning        ARC4 is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ *
+ */
+int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
+                unsigned char *output );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ *
+ * \warning        ARC4 is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ *
+ */
+int mbedtls_arc4_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* arc4.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/aria.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/aria.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/aria.h	(revision 398)
@@ -0,0 +1,370 @@
+/**
+ * \file aria.h
+ *
+ * \brief ARIA block cipher
+ *
+ *        The ARIA algorithm is a symmetric block cipher that can encrypt and
+ *        decrypt information. It is defined by the Korean Agency for
+ *        Technology and Standards (KATS) in <em>KS X 1213:2004</em> (in
+ *        Korean, but see http://210.104.33.10/ARIA/index-e.html in English)
+ *        and also described by the IETF in <em>RFC 5794</em>.
+ */
+/*  Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_ARIA_H
+#define MBEDTLS_ARIA_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "platform_util.h"
+
+#define MBEDTLS_ARIA_ENCRYPT     1 /**< ARIA encryption. */
+#define MBEDTLS_ARIA_DECRYPT     0 /**< ARIA decryption. */
+
+#define MBEDTLS_ARIA_BLOCKSIZE   16 /**< ARIA block size in bytes. */
+#define MBEDTLS_ARIA_MAX_ROUNDS  16 /**< Maxiumum number of rounds in ARIA. */
+#define MBEDTLS_ARIA_MAX_KEYSIZE 32 /**< Maximum size of an ARIA key in bytes. */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#define MBEDTLS_ERR_ARIA_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x005C )
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#define MBEDTLS_ERR_ARIA_BAD_INPUT_DATA -0x005C /**< Bad input data. */
+
+#define MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH -0x005E /**< Invalid data input length. */
+
+/* MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE  -0x005A  /**< Feature not available. For example, an unsupported ARIA key size. */
+
+/* MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED      -0x0058  /**< ARIA hardware accelerator failed. */
+
+#if !defined(MBEDTLS_ARIA_ALT)
+// Regular implementation
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief The ARIA context-type definition.
+ */
+typedef struct mbedtls_aria_context
+{
+    unsigned char nr;           /*!< The number of rounds (12, 14 or 16) */
+    /*! The ARIA round keys. */
+    uint32_t rk[MBEDTLS_ARIA_MAX_ROUNDS + 1][MBEDTLS_ARIA_BLOCKSIZE / 4];
+}
+mbedtls_aria_context;
+
+#else  /* MBEDTLS_ARIA_ALT */
+#include "aria_alt.h"
+#endif /* MBEDTLS_ARIA_ALT */
+
+/**
+ * \brief          This function initializes the specified ARIA context.
+ *
+ *                 It must be the first API called before using
+ *                 the context.
+ *
+ * \param ctx      The ARIA context to initialize. This must not be \c NULL.
+ */
+void mbedtls_aria_init( mbedtls_aria_context *ctx );
+
+/**
+ * \brief          This function releases and clears the specified ARIA context.
+ *
+ * \param ctx      The ARIA context to clear. This may be \c NULL, in which
+ *                 case this function returns immediately. If it is not \c NULL,
+ *                 it must point to an initialized ARIA context.
+ */
+void mbedtls_aria_free( mbedtls_aria_context *ctx );
+
+/**
+ * \brief          This function sets the encryption key.
+ *
+ * \param ctx      The ARIA context to which the key should be bound.
+ *                 This must be initialized.
+ * \param key      The encryption key. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The size of \p key in Bits. Valid options are:
+ *                 <ul><li>128 bits</li>
+ *                 <li>192 bits</li>
+ *                 <li>256 bits</li></ul>
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
+                             const unsigned char *key,
+                             unsigned int keybits );
+
+/**
+ * \brief          This function sets the decryption key.
+ *
+ * \param ctx      The ARIA context to which the key should be bound.
+ *                 This must be initialized.
+ * \param key      The decryption key. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The size of data passed. Valid options are:
+ *                 <ul><li>128 bits</li>
+ *                 <li>192 bits</li>
+ *                 <li>256 bits</li></ul>
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
+                             const unsigned char *key,
+                             unsigned int keybits );
+
+/**
+ * \brief          This function performs an ARIA single-block encryption or
+ *                 decryption operation.
+ *
+ *                 It performs encryption or decryption (depending on whether
+ *                 the key was set for encryption on decryption) on the input
+ *                 data buffer defined in the \p input parameter.
+ *
+ *                 mbedtls_aria_init(), and either mbedtls_aria_setkey_enc() or
+ *                 mbedtls_aria_setkey_dec() must be called before the first
+ *                 call to this API with the same context.
+ *
+ * \param ctx      The ARIA context to use for encryption or decryption.
+ *                 This must be initialized and bound to a key.
+ * \param input    The 16-Byte buffer holding the input data.
+ * \param output   The 16-Byte buffer holding the output data.
+
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
+                            const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
+                            unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/**
+ * \brief  This function performs an ARIA-CBC encryption or decryption operation
+ *         on full blocks.
+ *
+ *         It performs the operation defined in the \p mode
+ *         parameter (encrypt/decrypt), on the input data buffer defined in
+ *         the \p input parameter.
+ *
+ *         It can be called as many times as needed, until all the input
+ *         data is processed. mbedtls_aria_init(), and either
+ *         mbedtls_aria_setkey_enc() or mbedtls_aria_setkey_dec() must be called
+ *         before the first call to this API with the same context.
+ *
+ * \note   This function operates on aligned blocks, that is, the input size
+ *         must be a multiple of the ARIA block size of 16 Bytes.
+ *
+ * \note   Upon exit, the content of the IV is updated so that you can
+ *         call the same function again on the next
+ *         block(s) of data and get the same result as if it was
+ *         encrypted in one call. This allows a "streaming" usage.
+ *         If you need to retain the contents of the IV, you should
+ *         either save it manually or use the cipher module instead.
+ *
+ *
+ * \param ctx      The ARIA context to use for encryption or decryption.
+ *                 This must be initialized and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_ARIA_ENCRYPT for encryption, or
+ *                 #MBEDTLS_ARIA_DECRYPT for decryption.
+ * \param length   The length of the input data in Bytes. This must be a
+ *                 multiple of the block size (16 Bytes).
+ * \param iv       Initialization vector (updated after use).
+ *                 This must be a readable buffer of size 16 Bytes.
+ * \param input    The buffer holding the input data. This must
+ *                 be a readable buffer of length \p length Bytes.
+ * \param output   The buffer holding the output data. This must
+ *                 be a writable buffer of length \p length Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
+                            int mode,
+                            size_t length,
+                            unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
+                            const unsigned char *input,
+                            unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/**
+ * \brief This function performs an ARIA-CFB128 encryption or decryption
+ *        operation.
+ *
+ *        It performs the operation defined in the \p mode
+ *        parameter (encrypt or decrypt), on the input data buffer
+ *        defined in the \p input parameter.
+ *
+ *        For CFB, you must set up the context with mbedtls_aria_setkey_enc(),
+ *        regardless of whether you are performing an encryption or decryption
+ *        operation, that is, regardless of the \p mode parameter. This is
+ *        because CFB mode uses the same key schedule for encryption and
+ *        decryption.
+ *
+ * \note  Upon exit, the content of the IV is updated so that you can
+ *        call the same function again on the next
+ *        block(s) of data and get the same result as if it was
+ *        encrypted in one call. This allows a "streaming" usage.
+ *        If you need to retain the contents of the
+ *        IV, you must either save it manually or use the cipher
+ *        module instead.
+ *
+ *
+ * \param ctx      The ARIA context to use for encryption or decryption.
+ *                 This must be initialized and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_ARIA_ENCRYPT for encryption, or
+ *                 #MBEDTLS_ARIA_DECRYPT for decryption.
+ * \param length   The length of the input data \p input in Bytes.
+ * \param iv_off   The offset in IV (updated after use).
+ *                 This must not be larger than 15.
+ * \param iv       The initialization vector (updated after use).
+ *                 This must be a readable buffer of size 16 Bytes.
+ * \param input    The buffer holding the input data. This must
+ *                 be a readable buffer of length \p length Bytes.
+ * \param output   The buffer holding the output data. This must
+ *                 be a writable buffer of length \p length Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
+                               int mode,
+                               size_t length,
+                               size_t *iv_off,
+                               unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
+                               const unsigned char *input,
+                               unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/**
+ * \brief      This function performs an ARIA-CTR encryption or decryption
+ *             operation.
+ *
+ *             This function performs the operation defined in the \p mode
+ *             parameter (encrypt/decrypt), on the input data buffer
+ *             defined in the \p input parameter.
+ *
+ *             Due to the nature of CTR, you must use the same key schedule
+ *             for both encryption and decryption operations. Therefore, you
+ *             must use the context initialized with mbedtls_aria_setkey_enc()
+ *             for both #MBEDTLS_ARIA_ENCRYPT and #MBEDTLS_ARIA_DECRYPT.
+ *
+ * \warning    You must never reuse a nonce value with the same key. Doing so
+ *             would void the encryption for the two messages encrypted with
+ *             the same nonce and key.
+ *
+ *             There are two common strategies for managing nonces with CTR:
+ *
+ *             1. You can handle everything as a single message processed over
+ *             successive calls to this function. In that case, you want to
+ *             set \p nonce_counter and \p nc_off to 0 for the first call, and
+ *             then preserve the values of \p nonce_counter, \p nc_off and \p
+ *             stream_block across calls to this function as they will be
+ *             updated by this function.
+ *
+ *             With this strategy, you must not encrypt more than 2**128
+ *             blocks of data with the same key.
+ *
+ *             2. You can encrypt separate messages by dividing the \p
+ *             nonce_counter buffer in two areas: the first one used for a
+ *             per-message nonce, handled by yourself, and the second one
+ *             updated by this function internally.
+ *
+ *             For example, you might reserve the first 12 bytes for the
+ *             per-message nonce, and the last 4 bytes for internal use. In that
+ *             case, before calling this function on a new message you need to
+ *             set the first 12 bytes of \p nonce_counter to your chosen nonce
+ *             value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
+ *             stream_block to be ignored). That way, you can encrypt at most
+ *             2**96 messages of up to 2**32 blocks each with the same key.
+ *
+ *             The per-message nonce (or information sufficient to reconstruct
+ *             it) needs to be communicated with the ciphertext and must be unique.
+ *             The recommended way to ensure uniqueness is to use a message
+ *             counter. An alternative is to generate random nonces, but this
+ *             limits the number of messages that can be securely encrypted:
+ *             for example, with 96-bit random nonces, you should not encrypt
+ *             more than 2**32 messages with the same key.
+ *
+ *             Note that for both stategies, sizes are measured in blocks and
+ *             that an ARIA block is 16 bytes.
+ *
+ * \warning    Upon return, \p stream_block contains sensitive data. Its
+ *             content must not be written to insecure storage and should be
+ *             securely discarded as soon as it's no longer needed.
+ *
+ * \param ctx              The ARIA context to use for encryption or decryption.
+ *                         This must be initialized and bound to a key.
+ * \param length           The length of the input data \p input in Bytes.
+ * \param nc_off           The offset in Bytes in the current \p stream_block,
+ *                         for resuming within the current cipher stream. The
+ *                         offset pointer should be \c 0 at the start of a
+ *                         stream. This must not be larger than \c 15 Bytes.
+ * \param nonce_counter    The 128-bit nonce and counter. This must point to
+ *                         a read/write buffer of length \c 16 bytes.
+ * \param stream_block     The saved stream block for resuming. This must
+ *                         point to a read/write buffer of length \c 16 bytes.
+ *                         This is overwritten by the function.
+ * \param input            The buffer holding the input data. This must
+ *                         be a readable buffer of length \p length Bytes.
+ * \param output           The buffer holding the output data. This must
+ *                         be a writable buffer of length \p length Bytes.
+ *
+ * \return                 \c 0 on success.
+ * \return                 A negative error code on failure.
+ */
+int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
+                            size_t length,
+                            size_t *nc_off,
+                            unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
+                            unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
+                            const unsigned char *input,
+                            unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief          Checkup routine.
+ *
+ * \return         \c 0 on success, or \c 1 on failure.
+ */
+int mbedtls_aria_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* aria.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/asn1.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/asn1.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/asn1.h	(revision 398)
@@ -0,0 +1,358 @@
+/**
+ * \file asn1.h
+ *
+ * \brief Generic ASN.1 parsing
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_ASN1_H
+#define MBEDTLS_ASN1_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "bignum.h"
+#endif
+
+/**
+ * \addtogroup asn1_module
+ * \{
+ */
+
+/**
+ * \name ASN1 Error codes
+ * These error codes are OR'ed to X509 error codes for
+ * higher error granularity.
+ * ASN1 is a standard to specify data structures.
+ * \{
+ */
+#define MBEDTLS_ERR_ASN1_OUT_OF_DATA                      -0x0060  /**< Out of data when parsing an ASN1 data structure. */
+#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG                   -0x0062  /**< ASN1 tag was of an unexpected value. */
+#define MBEDTLS_ERR_ASN1_INVALID_LENGTH                   -0x0064  /**< Error when trying to determine the length or invalid length. */
+#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH                  -0x0066  /**< Actual length differs from expected length. */
+#define MBEDTLS_ERR_ASN1_INVALID_DATA                     -0x0068  /**< Data is invalid. (not used) */
+#define MBEDTLS_ERR_ASN1_ALLOC_FAILED                     -0x006A  /**< Memory allocation failed */
+#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL                    -0x006C  /**< Buffer too small when writing ASN.1 data structure. */
+
+/* \} name */
+
+/**
+ * \name DER constants
+ * These constants comply with the DER encoded ASN.1 type tags.
+ * DER encoding uses hexadecimal representation.
+ * An example DER sequence is:\n
+ * - 0x02 -- tag indicating INTEGER
+ * - 0x01 -- length in octets
+ * - 0x05 -- value
+ * Such sequences are typically read into \c ::mbedtls_x509_buf.
+ * \{
+ */
+#define MBEDTLS_ASN1_BOOLEAN                 0x01
+#define MBEDTLS_ASN1_INTEGER                 0x02
+#define MBEDTLS_ASN1_BIT_STRING              0x03
+#define MBEDTLS_ASN1_OCTET_STRING            0x04
+#define MBEDTLS_ASN1_NULL                    0x05
+#define MBEDTLS_ASN1_OID                     0x06
+#define MBEDTLS_ASN1_UTF8_STRING             0x0C
+#define MBEDTLS_ASN1_SEQUENCE                0x10
+#define MBEDTLS_ASN1_SET                     0x11
+#define MBEDTLS_ASN1_PRINTABLE_STRING        0x13
+#define MBEDTLS_ASN1_T61_STRING              0x14
+#define MBEDTLS_ASN1_IA5_STRING              0x16
+#define MBEDTLS_ASN1_UTC_TIME                0x17
+#define MBEDTLS_ASN1_GENERALIZED_TIME        0x18
+#define MBEDTLS_ASN1_UNIVERSAL_STRING        0x1C
+#define MBEDTLS_ASN1_BMP_STRING              0x1E
+#define MBEDTLS_ASN1_PRIMITIVE               0x00
+#define MBEDTLS_ASN1_CONSTRUCTED             0x20
+#define MBEDTLS_ASN1_CONTEXT_SPECIFIC        0x80
+
+/*
+ * Bit masks for each of the components of an ASN.1 tag as specified in
+ * ITU X.690 (08/2015), section 8.1 "General rules for encoding",
+ * paragraph 8.1.2.2:
+ *
+ * Bit  8     7   6   5          1
+ *     +-------+-----+------------+
+ *     | Class | P/C | Tag number |
+ *     +-------+-----+------------+
+ */
+#define MBEDTLS_ASN1_TAG_CLASS_MASK          0xC0
+#define MBEDTLS_ASN1_TAG_PC_MASK             0x20
+#define MBEDTLS_ASN1_TAG_VALUE_MASK          0x1F
+
+/* \} name */
+/* \} addtogroup asn1_module */
+
+/** Returns the size of the binary string, without the trailing \\0 */
+#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1)
+
+/**
+ * Compares an mbedtls_asn1_buf structure to a reference OID.
+ *
+ * Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a
+ * 'unsigned char *oid' here!
+ */
+#define MBEDTLS_OID_CMP(oid_str, oid_buf)                                   \
+        ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) ||                \
+          memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \name Functions to parse ASN.1 data structures
+ * \{
+ */
+
+/**
+ * Type-length-value structure that allows for ASN1 using DER.
+ */
+typedef struct mbedtls_asn1_buf
+{
+    int tag;                /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
+    size_t len;             /**< ASN1 length, in octets. */
+    unsigned char *p;       /**< ASN1 data, e.g. in ASCII. */
+}
+mbedtls_asn1_buf;
+
+/**
+ * Container for ASN1 bit strings.
+ */
+typedef struct mbedtls_asn1_bitstring
+{
+    size_t len;                 /**< ASN1 length, in octets. */
+    unsigned char unused_bits;  /**< Number of unused bits at the end of the string */
+    unsigned char *p;           /**< Raw ASN1 data for the bit string */
+}
+mbedtls_asn1_bitstring;
+
+/**
+ * Container for a sequence of ASN.1 items
+ */
+typedef struct mbedtls_asn1_sequence
+{
+    mbedtls_asn1_buf buf;                   /**< Buffer containing the given ASN.1 item. */
+    struct mbedtls_asn1_sequence *next;    /**< The next entry in the sequence. */
+}
+mbedtls_asn1_sequence;
+
+/**
+ * Container for a sequence or list of 'named' ASN.1 data items
+ */
+typedef struct mbedtls_asn1_named_data
+{
+    mbedtls_asn1_buf oid;                   /**< The object identifier. */
+    mbedtls_asn1_buf val;                   /**< The named value. */
+    struct mbedtls_asn1_named_data *next;  /**< The next entry in the sequence. */
+    unsigned char next_merged;      /**< Merge next item into the current one? */
+}
+mbedtls_asn1_named_data;
+
+/**
+ * \brief       Get the length of an ASN.1 element.
+ *              Updates the pointer to immediately behind the length.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param len   The variable that will receive the value
+ *
+ * \return      0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching
+ *              end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is
+ *              unparseable.
+ */
+int mbedtls_asn1_get_len( unsigned char **p,
+                  const unsigned char *end,
+                  size_t *len );
+
+/**
+ * \brief       Get the tag and length of the tag. Check for the requested tag.
+ *              Updates the pointer to immediately behind the tag and length.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param len   The variable that will receive the length
+ * \param tag   The expected tag
+ *
+ * \return      0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did
+ *              not match requested tag, or another specific ASN.1 error code.
+ */
+int mbedtls_asn1_get_tag( unsigned char **p,
+                  const unsigned char *end,
+                  size_t *len, int tag );
+
+/**
+ * \brief       Retrieve a boolean ASN.1 tag and its value.
+ *              Updates the pointer to immediately behind the full tag.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param val   The variable that will receive the value
+ *
+ * \return      0 if successful or a specific ASN.1 error code.
+ */
+int mbedtls_asn1_get_bool( unsigned char **p,
+                   const unsigned char *end,
+                   int *val );
+
+/**
+ * \brief       Retrieve an integer ASN.1 tag and its value.
+ *              Updates the pointer to immediately behind the full tag.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param val   The variable that will receive the value
+ *
+ * \return      0 if successful or a specific ASN.1 error code.
+ */
+int mbedtls_asn1_get_int( unsigned char **p,
+                  const unsigned char *end,
+                  int *val );
+
+/**
+ * \brief       Retrieve a bitstring ASN.1 tag and its value.
+ *              Updates the pointer to immediately behind the full tag.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param bs    The variable that will receive the value
+ *
+ * \return      0 if successful or a specific ASN.1 error code.
+ */
+int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
+                        mbedtls_asn1_bitstring *bs);
+
+/**
+ * \brief       Retrieve a bitstring ASN.1 tag without unused bits and its
+ *              value.
+ *              Updates the pointer to the beginning of the bit/octet string.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param len   Length of the actual bit/octect string in bytes
+ *
+ * \return      0 if successful or a specific ASN.1 error code.
+ */
+int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
+                             size_t *len );
+
+/**
+ * \brief       Parses and splits an ASN.1 "SEQUENCE OF <tag>"
+ *              Updated the pointer to immediately behind the full sequence tag.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param cur   First variable in the chain to fill
+ * \param tag   Type of sequence
+ *
+ * \return      0 if successful or a specific ASN.1 error code.
+ */
+int mbedtls_asn1_get_sequence_of( unsigned char **p,
+                          const unsigned char *end,
+                          mbedtls_asn1_sequence *cur,
+                          int tag);
+
+#if defined(MBEDTLS_BIGNUM_C)
+/**
+ * \brief       Retrieve a MPI value from an integer ASN.1 tag.
+ *              Updates the pointer to immediately behind the full tag.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param X     The MPI that will receive the value
+ *
+ * \return      0 if successful or a specific ASN.1 or MPI error code.
+ */
+int mbedtls_asn1_get_mpi( unsigned char **p,
+                  const unsigned char *end,
+                  mbedtls_mpi *X );
+#endif /* MBEDTLS_BIGNUM_C */
+
+/**
+ * \brief       Retrieve an AlgorithmIdentifier ASN.1 sequence.
+ *              Updates the pointer to immediately behind the full
+ *              AlgorithmIdentifier.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param alg   The buffer to receive the OID
+ * \param params The buffer to receive the params (if any)
+ *
+ * \return      0 if successful or a specific ASN.1 or MPI error code.
+ */
+int mbedtls_asn1_get_alg( unsigned char **p,
+                  const unsigned char *end,
+                  mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params );
+
+/**
+ * \brief       Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
+ *              params.
+ *              Updates the pointer to immediately behind the full
+ *              AlgorithmIdentifier.
+ *
+ * \param p     The position in the ASN.1 data
+ * \param end   End of data
+ * \param alg   The buffer to receive the OID
+ *
+ * \return      0 if successful or a specific ASN.1 or MPI error code.
+ */
+int mbedtls_asn1_get_alg_null( unsigned char **p,
+                       const unsigned char *end,
+                       mbedtls_asn1_buf *alg );
+
+/**
+ * \brief       Find a specific named_data entry in a sequence or list based on
+ *              the OID.
+ *
+ * \param list  The list to seek through
+ * \param oid   The OID to look for
+ * \param len   Size of the OID
+ *
+ * \return      NULL if not found, or a pointer to the existing entry.
+ */
+mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
+                                       const char *oid, size_t len );
+
+/**
+ * \brief       Free a mbedtls_asn1_named_data entry
+ *
+ * \param entry The named data entry to free
+ */
+void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
+
+/**
+ * \brief       Free all entries in a mbedtls_asn1_named_data list
+ *              Head will be set to NULL
+ *
+ * \param head  Pointer to the head of the list of named data entries to free
+ */
+void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* asn1.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/asn1write.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/asn1write.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/asn1write.h	(revision 398)
@@ -0,0 +1,328 @@
+/**
+ * \file asn1write.h
+ *
+ * \brief ASN.1 buffer writing functionality
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_ASN1_WRITE_H
+#define MBEDTLS_ASN1_WRITE_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "asn1.h"
+
+#define MBEDTLS_ASN1_CHK_ADD(g, f)                      \
+    do {                                                \
+        if( ( ret = f ) < 0 )                           \
+            return( ret );                              \
+        else                                            \
+            g += ret;                                   \
+    } while( 0 )
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief           Write a length field in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param len       The length value to write.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start,
+                            size_t len );
+/**
+ * \brief           Write an ASN.1 tag in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param tag       The tag to write.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start,
+                            unsigned char tag );
+
+/**
+ * \brief           Write raw buffer data.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param buf       The data buffer to write.
+ * \param size      The length of the data buffer.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
+                                   const unsigned char *buf, size_t size );
+
+#if defined(MBEDTLS_BIGNUM_C)
+/**
+ * \brief           Write a arbitrary-precision number (#MBEDTLS_ASN1_INTEGER)
+ *                  in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param X         The MPI to write.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start,
+                            const mbedtls_mpi *X );
+#endif /* MBEDTLS_BIGNUM_C */
+
+/**
+ * \brief           Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data
+ *                  in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start );
+
+/**
+ * \brief           Write an OID tag (#MBEDTLS_ASN1_OID) and data
+ *                  in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param oid       The OID to write.
+ * \param oid_len   The length of the OID.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
+                            const char *oid, size_t oid_len );
+
+/**
+ * \brief           Write an AlgorithmIdentifier sequence in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param oid       The OID of the algorithm to write.
+ * \param oid_len   The length of the algorithm's OID.
+ * \param par_len   The length of the parameters, which must be already written.
+ *                  If 0, NULL parameters are added
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_asn1_write_algorithm_identifier( unsigned char **p,
+                                             unsigned char *start,
+                                             const char *oid, size_t oid_len,
+                                             size_t par_len );
+
+/**
+ * \brief           Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value
+ *                  in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param boolean   The boolean value to write, either \c 0 or \c 1.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start,
+                             int boolean );
+
+/**
+ * \brief           Write an int tag (#MBEDTLS_ASN1_INTEGER) and value
+ *                  in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param val       The integer value to write.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val );
+
+/**
+ * \brief           Write a string in ASN.1 format using a specific
+ *                  string encoding tag.
+
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param tag       The string encoding tag to write, e.g.
+ *                  #MBEDTLS_ASN1_UTF8_STRING.
+ * \param text      The string to write.
+ * \param text_len  The length of \p text in bytes (which might
+ *                  be strictly larger than the number of characters).
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start,
+                                      int tag, const char *text,
+                                      size_t text_len );
+
+/**
+ * \brief           Write a string in ASN.1 format using the PrintableString
+ *                  string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param text      The string to write.
+ * \param text_len  The length of \p text in bytes (which might
+ *                  be strictly larger than the number of characters).
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_asn1_write_printable_string( unsigned char **p,
+                                         unsigned char *start,
+                                         const char *text, size_t text_len );
+
+/**
+ * \brief           Write a UTF8 string in ASN.1 format using the UTF8String
+ *                  string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param text      The string to write.
+ * \param text_len  The length of \p text in bytes (which might
+ *                  be strictly larger than the number of characters).
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
+                                    const char *text, size_t text_len );
+
+/**
+ * \brief           Write a string in ASN.1 format using the IA5String
+ *                  string encoding tag (#MBEDTLS_ASN1_IA5_STRING).
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param text      The string to write.
+ * \param text_len  The length of \p text in bytes (which might
+ *                  be strictly larger than the number of characters).
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
+                                   const char *text, size_t text_len );
+
+/**
+ * \brief           Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and
+ *                  value in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param buf       The bitstring to write.
+ * \param bits      The total number of bits in the bitstring.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
+                                  const unsigned char *buf, size_t bits );
+
+/**
+ * \brief           Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING)
+ *                  and value in ASN.1 format.
+ *
+ * \note            This function works backwards in data buffer.
+ *
+ * \param p         The reference to the current position pointer.
+ * \param start     The start of the buffer, for bounds-checking.
+ * \param buf       The buffer holding the data to write.
+ * \param size      The length of the data buffer \p buf.
+ *
+ * \return          The number of bytes written to \p p on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
+                                     const unsigned char *buf, size_t size );
+
+/**
+ * \brief           Create or find a specific named_data entry for writing in a
+ *                  sequence or list based on the OID. If not already in there,
+ *                  a new entry is added to the head of the list.
+ *                  Warning: Destructive behaviour for the val data!
+ *
+ * \param list      The pointer to the location of the head of the list to seek
+ *                  through (will be updated in case of a new entry).
+ * \param oid       The OID to look for.
+ * \param oid_len   The size of the OID.
+ * \param val       The data to store (can be \c NULL if you want to fill
+ *                  it by hand).
+ * \param val_len   The minimum length of the data buffer needed.
+ *
+ * \return          A pointer to the new / existing entry on success.
+ * \return          \c NULL if if there was a memory allocation error.
+ */
+mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **list,
+                                        const char *oid, size_t oid_len,
+                                        const unsigned char *val,
+                                        size_t val_len );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_ASN1_WRITE_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/base64.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/base64.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/base64.h	(revision 398)
@@ -0,0 +1,98 @@
+/**
+ * \file base64.h
+ *
+ * \brief RFC 1521 base64 encoding/decoding
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_BASE64_H
+#define MBEDTLS_BASE64_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL               -0x002A  /**< Output buffer too small. */
+#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER              -0x002C  /**< Invalid character in input. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          Encode a buffer into base64 format
+ *
+ * \param dst      destination buffer
+ * \param dlen     size of the destination buffer
+ * \param olen     number of bytes written
+ * \param src      source buffer
+ * \param slen     amount of data to be encoded
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL.
+ *                 *olen is always updated to reflect the amount
+ *                 of data that has (or would have) been written.
+ *                 If that length cannot be represented, then no data is
+ *                 written to the buffer and *olen is set to the maximum
+ *                 length representable as a size_t.
+ *
+ * \note           Call this function with dlen = 0 to obtain the
+ *                 required buffer size in *olen
+ */
+int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
+                   const unsigned char *src, size_t slen );
+
+/**
+ * \brief          Decode a base64-formatted buffer
+ *
+ * \param dst      destination buffer (can be NULL for checking size)
+ * \param dlen     size of the destination buffer
+ * \param olen     number of bytes written
+ * \param src      source buffer
+ * \param slen     amount of data to be decoded
+ *
+ * \return         0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or
+ *                 MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is
+ *                 not correct. *olen is always updated to reflect the amount
+ *                 of data that has (or would have) been written.
+ *
+ * \note           Call this function with *dst = NULL or dlen = 0 to obtain
+ *                 the required buffer size in *olen
+ */
+int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
+                   const unsigned char *src, size_t slen );
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int mbedtls_base64_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* base64.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/bignum.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/bignum.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/bignum.h	(revision 398)
@@ -0,0 +1,961 @@
+/**
+ * \file bignum.h
+ *
+ * \brief Multi-precision integer library
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_BIGNUM_H
+#define MBEDTLS_BIGNUM_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined(MBEDTLS_FS_IO)
+#include <stdio.h>
+#endif
+
+#define MBEDTLS_ERR_MPI_FILE_IO_ERROR                     -0x0002  /**< An error occurred while reading from or writing to a file. */
+#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA                    -0x0004  /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_MPI_INVALID_CHARACTER                 -0x0006  /**< There is an invalid character in the digit string. */
+#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL                  -0x0008  /**< The buffer is too small to write to. */
+#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE                    -0x000A  /**< The input arguments are negative or result in illegal output. */
+#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO                  -0x000C  /**< The input argument for division is zero, which is not allowed. */
+#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE                    -0x000E  /**< The input arguments are not acceptable. */
+#define MBEDTLS_ERR_MPI_ALLOC_FAILED                      -0x0010  /**< Memory allocation failed. */
+
+#define MBEDTLS_MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 )
+
+/*
+ * Maximum size MPIs are allowed to grow to in number of limbs.
+ */
+#define MBEDTLS_MPI_MAX_LIMBS                             10000
+
+#if !defined(MBEDTLS_MPI_WINDOW_SIZE)
+/*
+ * Maximum window size used for modular exponentiation. Default: 6
+ * Minimum value: 1. Maximum value: 6.
+ *
+ * Result is an array of ( 2 << MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
+ * for the sliding window calculation. (So 64 by default)
+ *
+ * Reduction in size, reduces speed.
+ */
+#define MBEDTLS_MPI_WINDOW_SIZE                           6        /**< Maximum windows size used. */
+#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
+
+#if !defined(MBEDTLS_MPI_MAX_SIZE)
+/*
+ * Maximum size of MPIs allowed in bits and bytes for user-MPIs.
+ * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
+ *
+ * Note: Calculations can temporarily result in larger MPIs. So the number
+ * of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher.
+ */
+#define MBEDTLS_MPI_MAX_SIZE                              1024     /**< Maximum number of bytes for usable MPIs. */
+#endif /* !MBEDTLS_MPI_MAX_SIZE */
+
+#define MBEDTLS_MPI_MAX_BITS                              ( 8 * MBEDTLS_MPI_MAX_SIZE )    /**< Maximum number of bits for usable MPIs. */
+
+/*
+ * When reading from files with mbedtls_mpi_read_file() and writing to files with
+ * mbedtls_mpi_write_file() the buffer should have space
+ * for a (short) label, the MPI (in the provided radix), the newline
+ * characters and the '\0'.
+ *
+ * By default we assume at least a 10 char label, a minimum radix of 10
+ * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars).
+ * Autosized at compile time for at least a 10 char label, a minimum radix
+ * of 10 (decimal) for a number of MBEDTLS_MPI_MAX_BITS size.
+ *
+ * This used to be statically sized to 1250 for a maximum of 4096 bit
+ * numbers (1234 decimal chars).
+ *
+ * Calculate using the formula:
+ *  MBEDTLS_MPI_RW_BUFFER_SIZE = ceil(MBEDTLS_MPI_MAX_BITS / ln(10) * ln(2)) +
+ *                                LabelSize + 6
+ */
+#define MBEDTLS_MPI_MAX_BITS_SCALE100          ( 100 * MBEDTLS_MPI_MAX_BITS )
+#define MBEDTLS_LN_2_DIV_LN_10_SCALE100                 332
+#define MBEDTLS_MPI_RW_BUFFER_SIZE             ( ((MBEDTLS_MPI_MAX_BITS_SCALE100 + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
+
+/*
+ * Define the base integer type, architecture-wise.
+ *
+ * 32 or 64-bit integer types can be forced regardless of the underlying
+ * architecture by defining MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64
+ * respectively and undefining MBEDTLS_HAVE_ASM.
+ *
+ * Double-width integers (e.g. 128-bit in 64-bit architectures) can be
+ * disabled by defining MBEDTLS_NO_UDBL_DIVISION.
+ */
+#if !defined(MBEDTLS_HAVE_INT32)
+    #if defined(_MSC_VER) && defined(_M_AMD64)
+        /* Always choose 64-bit when using MSC */
+        #if !defined(MBEDTLS_HAVE_INT64)
+            #define MBEDTLS_HAVE_INT64
+        #endif /* !MBEDTLS_HAVE_INT64 */
+        typedef  int64_t mbedtls_mpi_sint;
+        typedef uint64_t mbedtls_mpi_uint;
+    #elif defined(__GNUC__) && (                         \
+        defined(__amd64__) || defined(__x86_64__)     || \
+        defined(__ppc64__) || defined(__powerpc64__)  || \
+        defined(__ia64__)  || defined(__alpha__)      || \
+        ( defined(__sparc__) && defined(__arch64__) ) || \
+        defined(__s390x__) || defined(__mips64) )
+        #if !defined(MBEDTLS_HAVE_INT64)
+            #define MBEDTLS_HAVE_INT64
+        #endif /* MBEDTLS_HAVE_INT64 */
+        typedef  int64_t mbedtls_mpi_sint;
+        typedef uint64_t mbedtls_mpi_uint;
+        #if !defined(MBEDTLS_NO_UDBL_DIVISION)
+            /* mbedtls_t_udbl defined as 128-bit unsigned int */
+            typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI)));
+            #define MBEDTLS_HAVE_UDBL
+        #endif /* !MBEDTLS_NO_UDBL_DIVISION */
+    #elif defined(__ARMCC_VERSION) && defined(__aarch64__)
+        /*
+         * __ARMCC_VERSION is defined for both armcc and armclang and
+         * __aarch64__ is only defined by armclang when compiling 64-bit code
+         */
+        #if !defined(MBEDTLS_HAVE_INT64)
+            #define MBEDTLS_HAVE_INT64
+        #endif /* !MBEDTLS_HAVE_INT64 */
+        typedef  int64_t mbedtls_mpi_sint;
+        typedef uint64_t mbedtls_mpi_uint;
+        #if !defined(MBEDTLS_NO_UDBL_DIVISION)
+            /* mbedtls_t_udbl defined as 128-bit unsigned int */
+            typedef __uint128_t mbedtls_t_udbl;
+            #define MBEDTLS_HAVE_UDBL
+        #endif /* !MBEDTLS_NO_UDBL_DIVISION */
+    #elif defined(MBEDTLS_HAVE_INT64)
+        /* Force 64-bit integers with unknown compiler */
+        typedef  int64_t mbedtls_mpi_sint;
+        typedef uint64_t mbedtls_mpi_uint;
+    #endif
+#endif /* !MBEDTLS_HAVE_INT32 */
+
+#if !defined(MBEDTLS_HAVE_INT64)
+    /* Default to 32-bit compilation */
+    #if !defined(MBEDTLS_HAVE_INT32)
+        #define MBEDTLS_HAVE_INT32
+    #endif /* !MBEDTLS_HAVE_INT32 */
+    typedef  int32_t mbedtls_mpi_sint;
+    typedef uint32_t mbedtls_mpi_uint;
+    #if !defined(MBEDTLS_NO_UDBL_DIVISION)
+        typedef uint64_t mbedtls_t_udbl;
+        #define MBEDTLS_HAVE_UDBL
+    #endif /* !MBEDTLS_NO_UDBL_DIVISION */
+#endif /* !MBEDTLS_HAVE_INT64 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          MPI structure
+ */
+typedef struct mbedtls_mpi
+{
+    int s;              /*!<  integer sign      */
+    size_t n;           /*!<  total # of limbs  */
+    mbedtls_mpi_uint *p;          /*!<  pointer to limbs  */
+}
+mbedtls_mpi;
+
+/**
+ * \brief           Initialize an MPI context.
+ *
+ *                  This makes the MPI ready to be set or freed,
+ *                  but does not define a value for the MPI.
+ *
+ * \param X         The MPI context to initialize. This must not be \c NULL.
+ */
+void mbedtls_mpi_init( mbedtls_mpi *X );
+
+/**
+ * \brief          This function frees the components of an MPI context.
+ *
+ * \param X        The MPI context to be cleared. This may be \c NULL,
+ *                 in which case this function is a no-op. If it is
+ *                 not \c NULL, it must point to an initialized MPI.
+ */
+void mbedtls_mpi_free( mbedtls_mpi *X );
+
+/**
+ * \brief          Enlarge an MPI to the specified number of limbs.
+ *
+ * \note           This function does nothing if the MPI is
+ *                 already large enough.
+ *
+ * \param X        The MPI to grow. It must be initialized.
+ * \param nblimbs  The target number of limbs.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
+ */
+int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs );
+
+/**
+ * \brief          This function resizes an MPI downwards, keeping at least the
+ *                 specified number of limbs.
+ *
+ *                 If \c X is smaller than \c nblimbs, it is resized up
+ *                 instead.
+ *
+ * \param X        The MPI to shrink. This must point to an initialized MPI.
+ * \param nblimbs  The minimum number of limbs to keep.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
+ *                 (this can only happen when resizing up).
+ * \return         Another negative error code on other kinds of failure.
+ */
+int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs );
+
+/**
+ * \brief          Make a copy of an MPI.
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param Y        The source MPI. This must point to an initialized MPI.
+ *
+ * \note           The limb-buffer in the destination MPI is enlarged
+ *                 if necessary to hold the value in the source MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
+ */
+int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y );
+
+/**
+ * \brief          Swap the contents of two MPIs.
+ *
+ * \param X        The first MPI. It must be initialized.
+ * \param Y        The second MPI. It must be initialized.
+ */
+void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y );
+
+/**
+ * \brief          Perform a safe conditional copy of MPI which doesn't
+ *                 reveal whether the condition was true or not.
+ *
+ * \param X        The MPI to conditionally assign to. This must point
+ *                 to an initialized MPI.
+ * \param Y        The MPI to be assigned from. This must point to an
+ *                 initialized MPI.
+ * \param assign   The condition deciding whether to perform the
+ *                 assignment or not. Possible values:
+ *                 * \c 1: Perform the assignment `X = Y`.
+ *                 * \c 0: Keep the original value of \p X.
+ *
+ * \note           This function is equivalent to
+ *                      `if( assign ) mbedtls_mpi_copy( X, Y );`
+ *                 except that it avoids leaking any information about whether
+ *                 the assignment was done or not (the above code may leak
+ *                 information through branch prediction and/or memory access
+ *                 patterns analysis).
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
+ */
+int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign );
+
+/**
+ * \brief          Perform a safe conditional swap which doesn't
+ *                 reveal whether the condition was true or not.
+ *
+ * \param X        The first MPI. This must be initialized.
+ * \param Y        The second MPI. This must be initialized.
+ * \param assign   The condition deciding whether to perform
+ *                 the swap or not. Possible values:
+ *                 * \c 1: Swap the values of \p X and \p Y.
+ *                 * \c 0: Keep the original values of \p X and \p Y.
+ *
+ * \note           This function is equivalent to
+ *                      if( assign ) mbedtls_mpi_swap( X, Y );
+ *                 except that it avoids leaking any information about whether
+ *                 the assignment was done or not (the above code may leak
+ *                 information through branch prediction and/or memory access
+ *                 patterns analysis).
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
+ *
+ */
+int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign );
+
+/**
+ * \brief          Store integer value in MPI.
+ *
+ * \param X        The MPI to set. This must be initialized.
+ * \param z        The value to use.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
+ */
+int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z );
+
+/**
+ * \brief          Get a specific bit from an MPI.
+ *
+ * \param X        The MPI to query. This must be initialized.
+ * \param pos      Zero-based index of the bit to query.
+ *
+ * \return         \c 0 or \c 1 on success, depending on whether bit \c pos
+ *                 of \c X is unset or set.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos );
+
+/**
+ * \brief          Modify a specific bit in an MPI.
+ *
+ * \note           This function will grow the target MPI if necessary to set a
+ *                 bit to \c 1 in a not yet existing limb. It will not grow if
+ *                 the bit should be set to \c 0.
+ *
+ * \param X        The MPI to modify. This must be initialized.
+ * \param pos      Zero-based index of the bit to modify.
+ * \param val      The desired value of bit \c pos: \c 0 or \c 1.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on other kinds of failure.
+ */
+int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val );
+
+/**
+ * \brief          Return the number of bits of value \c 0 before the
+ *                 least significant bit of value \c 1.
+ *
+ * \note           This is the same as the zero-based index of
+ *                 the least significant bit of value \c 1.
+ *
+ * \param X        The MPI to query.
+ *
+ * \return         The number of bits of value \c 0 before the least significant
+ *                 bit of value \c 1 in \p X.
+ */
+size_t mbedtls_mpi_lsb( const mbedtls_mpi *X );
+
+/**
+ * \brief          Return the number of bits up to and including the most
+ *                 significant bit of value \c 1.
+ *
+ * * \note         This is same as the one-based index of the most
+ *                 significant bit of value \c 1.
+ *
+ * \param X        The MPI to query. This must point to an initialized MPI.
+ *
+ * \return         The number of bits up to and including the most
+ *                 significant bit of value \c 1.
+ */
+size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X );
+
+/**
+ * \brief          Return the total size of an MPI value in bytes.
+ *
+ * \param X        The MPI to use. This must point to an initialized MPI.
+ *
+ * \note           The value returned by this function may be less than
+ *                 the number of bytes used to store \p X internally.
+ *                 This happens if and only if there are trailing bytes
+ *                 of value zero.
+ *
+ * \return         The least number of bytes capable of storing
+ *                 the absolute value of \p X.
+ */
+size_t mbedtls_mpi_size( const mbedtls_mpi *X );
+
+/**
+ * \brief          Import an MPI from an ASCII string.
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param radix    The numeric base of the input string.
+ * \param s        Null-terminated string buffer.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s );
+
+/**
+ * \brief          Export an MPI to an ASCII string.
+ *
+ * \param X        The source MPI. This must point to an initialized MPI.
+ * \param radix    The numeric base of the output string.
+ * \param buf      The buffer to write the string to. This must be writable
+ *                 buffer of length \p buflen Bytes.
+ * \param buflen   The available size in Bytes of \p buf.
+ * \param olen     The address at which to store the length of the string
+ *                 written, including the  final \c NULL byte. This must
+ *                 not be \c NULL.
+ *
+ * \note           You can call this function with `buflen == 0` to obtain the
+ *                 minimum required buffer size in `*olen`.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the target buffer \p buf
+ *                 is too small to hold the value of \p X in the desired base.
+ *                 In this case, `*olen` is nonetheless updated to contain the
+ *                 size of \p buf required for a successful call.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
+                              char *buf, size_t buflen, size_t *olen );
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief          Read an MPI from a line in an opened file.
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param radix    The numeric base of the string representation used
+ *                 in the source line.
+ * \param fin      The input file handle to use. This must not be \c NULL.
+ *
+ * \note           On success, this function advances the file stream
+ *                 to the end of the current line or to EOF.
+ *
+ *                 The function returns \c 0 on an empty line.
+ *
+ *                 Leading whitespaces are ignored, as is a
+ *                 '0x' prefix for radix \c 16.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the file read buffer
+ *                 is too small.
+ * \return         Another negative error code on failure.
+ */
+int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin );
+
+/**
+ * \brief          Export an MPI into an opened file.
+ *
+ * \param p        A string prefix to emit prior to the MPI data.
+ *                 For example, this might be a label, or "0x" when
+ *                 printing in base \c 16. This may be \c NULL if no prefix
+ *                 is needed.
+ * \param X        The source MPI. This must point to an initialized MPI.
+ * \param radix    The numeric base to be used in the emitted string.
+ * \param fout     The output file handle. This may be \c NULL, in which case
+ *                 the output is written to \c stdout.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X,
+                            int radix, FILE *fout );
+#endif /* MBEDTLS_FS_IO */
+
+/**
+ * \brief          Import an MPI from unsigned big endian binary data.
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param buf      The input buffer. This must be a readable buffer of length
+ *                 \p buflen Bytes.
+ * \param buflen   The length of the input buffer \p p in Bytes.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf,
+                             size_t buflen );
+
+/**
+ * \brief          Export an MPI into unsigned big endian binary data
+ *                 of fixed size.
+ *
+ * \param X        The source MPI. This must point to an initialized MPI.
+ * \param buf      The output buffer. This must be a writable buffer of length
+ *                 \p buflen Bytes.
+ * \param buflen   The size of the output buffer \p buf in Bytes.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't
+ *                 large enough to hold the value of \p X.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf,
+                              size_t buflen );
+
+/**
+ * \brief          Perform a left-shift on an MPI: X <<= count
+ *
+ * \param X        The MPI to shift. This must point to an initialized MPI.
+ * \param count    The number of bits to shift by.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count );
+
+/**
+ * \brief          Perform a right-shift on an MPI: X >>= count
+ *
+ * \param X        The MPI to shift. This must point to an initialized MPI.
+ * \param count    The number of bits to shift by.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count );
+
+/**
+ * \brief          Compare the absolute values of two MPIs.
+ *
+ * \param X        The left-hand MPI. This must point to an initialized MPI.
+ * \param Y        The right-hand MPI. This must point to an initialized MPI.
+ *
+ * \return         \c 1 if `|X|` is greater than `|Y|`.
+ * \return         \c -1 if `|X|` is lesser than `|Y|`.
+ * \return         \c 0 if `|X|` is equal to `|Y|`.
+ */
+int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y );
+
+/**
+ * \brief          Compare two MPIs.
+ *
+ * \param X        The left-hand MPI. This must point to an initialized MPI.
+ * \param Y        The right-hand MPI. This must point to an initialized MPI.
+ *
+ * \return         \c 1 if \p X is greater than \p Y.
+ * \return         \c -1 if \p X is lesser than \p Y.
+ * \return         \c 0 if \p X is equal to \p Y.
+ */
+int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y );
+
+/**
+ * \brief          Compare an MPI with an integer.
+ *
+ * \param X        The left-hand MPI. This must point to an initialized MPI.
+ * \param z        The integer value to compare \p X to.
+ *
+ * \return         \c 1 if \p X is greater than \p z.
+ * \return         \c -1 if \p X is lesser than \p z.
+ * \return         \c 0 if \p X is equal to \p z.
+ */
+int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z );
+
+/**
+ * \brief          Perform an unsigned addition of MPIs: X = |A| + |B|
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first summand. This must point to an initialized MPI.
+ * \param B        The second summand. This must point to an initialized MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
+
+/**
+ * \brief          Perform an unsigned subtraction of MPIs: X = |A| - |B|
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The minuend. This must point to an initialized MPI.
+ * \param B        The subtrahend. This must point to an initialized MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is greater than \p A.
+ * \return         Another negative error code on different kinds of failure.
+ *
+ */
+int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
+
+/**
+ * \brief          Perform a signed addition of MPIs: X = A + B
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first summand. This must point to an initialized MPI.
+ * \param B        The second summand. This must point to an initialized MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
+
+/**
+ * \brief          Perform a signed subtraction of MPIs: X = A - B
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The minuend. This must point to an initialized MPI.
+ * \param B        The subtrahend. This must point to an initialized MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
+
+/**
+ * \brief          Perform a signed addition of an MPI and an integer: X = A + b
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first summand. This must point to an initialized MPI.
+ * \param b        The second summand.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b );
+
+/**
+ * \brief          Perform a signed subtraction of an MPI and an integer:
+ *                 X = A - b
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The minuend. This must point to an initialized MPI.
+ * \param b        The subtrahend.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b );
+
+/**
+ * \brief          Perform a multiplication of two MPIs: X = A * B
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first factor. This must point to an initialized MPI.
+ * \param B        The second factor. This must point to an initialized MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ *
+ */
+int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
+
+/**
+ * \brief          Perform a multiplication of an MPI with an unsigned integer:
+ *                 X = A * b
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first factor. This must point to an initialized MPI.
+ * \param b        The second factor.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ *
+ */
+int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         mbedtls_mpi_uint b );
+
+/**
+ * \brief          Perform a division with remainder of two MPIs:
+ *                 A = Q * B + R
+ *
+ * \param Q        The destination MPI for the quotient.
+ *                 This may be \c NULL if the value of the
+ *                 quotient is not needed.
+ * \param R        The destination MPI for the remainder value.
+ *                 This may be \c NULL if the value of the
+ *                 remainder is not needed.
+ * \param A        The dividend. This must point to an initialized MPi.
+ * \param B        The divisor. This must point to an initialized MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
+
+/**
+ * \brief          Perform a division with remainder of an MPI by an integer:
+ *                 A = Q * b + R
+ *
+ * \param Q        The destination MPI for the quotient.
+ *                 This may be \c NULL if the value of the
+ *                 quotient is not needed.
+ * \param R        The destination MPI for the remainder value.
+ *                 This may be \c NULL if the value of the
+ *                 remainder is not needed.
+ * \param A        The dividend. This must point to an initialized MPi.
+ * \param b        The divisor.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b );
+
+/**
+ * \brief          Perform a modular reduction. R = A mod B
+ *
+ * \param R        The destination MPI for the residue value.
+ *                 This must point to an initialized MPI.
+ * \param A        The MPI to compute the residue of.
+ *                 This must point to an initialized MPI.
+ * \param B        The base of the modular reduction.
+ *                 This must point to an initialized MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero.
+ * \return         #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is negative.
+ * \return         Another negative error code on different kinds of failure.
+ *
+ */
+int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B );
+
+/**
+ * \brief          Perform a modular reduction with respect to an integer.
+ *                 r = A mod b
+ *
+ * \param r        The address at which to store the residue.
+ *                 This must not be \c NULL.
+ * \param A        The MPI to compute the residue of.
+ *                 This must point to an initialized MPi.
+ * \param b        The integer base of the modular reduction.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero.
+ * \return         #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p b is negative.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b );
+
+/**
+ * \brief          Perform a sliding-window exponentiation: X = A^E mod N
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The base of the exponentiation.
+ *                 This must point to an initialized MPI.
+ * \param E        The exponent MPI. This must point to an initialized MPI.
+ * \param N        The base for the modular reduction. This must point to an
+ *                 initialized MPI.
+ * \param _RR      A helper MPI depending solely on \p N which can be used to
+ *                 speed-up multiple modular exponentiations for the same value
+ *                 of \p N. This may be \c NULL. If it is not \c NULL, it must
+ *                 point to an initialized MPI. If it hasn't been used after
+ *                 the call to mbedtls_mpi_init(), this function will compute
+ *                 the helper value and store it in \p _RR for reuse on
+ *                 subsequent calls to this function. Otherwise, the function
+ *                 will assume that \p _RR holds the helper value set by a
+ *                 previous call to mbedtls_mpi_exp_mod(), and reuse it.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or
+ *                 even, or if \c E is negative.
+ * \return         Another negative error code on different kinds of failures.
+ *
+ */
+int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *E, const mbedtls_mpi *N,
+                         mbedtls_mpi *_RR );
+
+/**
+ * \brief          Fill an MPI with a number of random bytes.
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param size     The number of random bytes to generate.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG parameter to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng doesn't need a context argument.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on failure.
+ *
+ * \note           The bytes obtained from the RNG are interpreted
+ *                 as a big-endian representation of an MPI; this can
+ *                 be relevant in applications like deterministic ECDSA.
+ */
+int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng );
+
+/**
+ * \brief          Compute the greatest common divisor: G = gcd(A, B)
+ *
+ * \param G        The destination MPI. This must point to an initialized MPI.
+ * \param A        The first operand. This must point to an initialized MPI.
+ * \param B        The second operand. This must point to an initialized MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A,
+                     const mbedtls_mpi *B );
+
+/**
+ * \brief          Compute the modular inverse: X = A^-1 mod N
+ *
+ * \param X        The destination MPI. This must point to an initialized MPI.
+ * \param A        The MPI to calculate the modular inverse of. This must point
+ *                 to an initialized MPI.
+ * \param N        The base of the modular inversion. This must point to an
+ *                 initialized MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than
+ *                 or equal to one.
+ * \return         #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p has no modular inverse
+ *                 with respect to \p N.
+ */
+int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *N );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          Perform a Miller-Rabin primality test with error
+ *                 probability of 2<sup>-80</sup>.
+ *
+ * \deprecated     Superseded by mbedtls_mpi_is_prime_ext() which allows
+ *                 specifying the number of Miller-Rabin rounds.
+ *
+ * \param X        The MPI to check for primality.
+ *                 This must point to an initialized MPI.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG parameter to be passed to \p f_rng.
+ *                 This may be \c NULL if \p f_rng doesn't use a
+ *                 context parameter.
+ *
+ * \return         \c 0 if successful, i.e. \p X is probably prime.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime.
+ * \return         Another negative error code on other kinds of failure.
+ */
+MBEDTLS_DEPRECATED int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
+                          int (*f_rng)(void *, unsigned char *, size_t),
+                          void *p_rng );
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          Miller-Rabin primality test.
+ *
+ * \warning        If \p X is potentially generated by an adversary, for example
+ *                 when validating cryptographic parameters that you didn't
+ *                 generate yourself and that are supposed to be prime, then
+ *                 \p rounds should be at least the half of the security
+ *                 strength of the cryptographic algorithm. On the other hand,
+ *                 if \p X is chosen uniformly or non-adversially (as is the
+ *                 case when mbedtls_mpi_gen_prime calls this function), then
+ *                 \p rounds can be much lower.
+ *
+ * \param X        The MPI to check for primality.
+ *                 This must point to an initialized MPI.
+ * \param rounds   The number of bases to perform the Miller-Rabin primality
+ *                 test for. The probability of returning 0 on a composite is
+ *                 at most 2<sup>-2*\p rounds</sup>.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG parameter to be passed to \p f_rng.
+ *                 This may be \c NULL if \p f_rng doesn't use
+ *                 a context parameter.
+ *
+ * \return         \c 0 if successful, i.e. \p X is probably prime.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime.
+ * \return         Another negative error code on other kinds of failure.
+ */
+int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng );
+/**
+ * \brief Flags for mbedtls_mpi_gen_prime()
+ *
+ * Each of these flags is a constraint on the result X returned by
+ * mbedtls_mpi_gen_prime().
+ */
+typedef enum {
+    MBEDTLS_MPI_GEN_PRIME_FLAG_DH =      0x0001, /**< (X-1)/2 is prime too */
+    MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR = 0x0002, /**< lower error rate from 2<sup>-80</sup> to 2<sup>-128</sup> */
+} mbedtls_mpi_gen_prime_flag_t;
+
+/**
+ * \brief          Generate a prime number.
+ *
+ * \param X        The destination MPI to store the generated prime in.
+ *                 This must point to an initialized MPi.
+ * \param nbits    The required size of the destination MPI in bits.
+ *                 This must be between \c 3 and #MBEDTLS_MPI_MAX_BITS.
+ * \param flags    A mask of flags of type #mbedtls_mpi_gen_prime_flag_t.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG parameter to be passed to \p f_rng.
+ *                 This may be \c NULL if \p f_rng doesn't use
+ *                 a context parameter.
+ *
+ * \return         \c 0 if successful, in which case \p X holds a
+ *                 probably prime number.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return         #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if `nbits` is not between
+ *                 \c 3 and #MBEDTLS_MPI_MAX_BITS.
+ */
+int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
+                   int (*f_rng)(void *, unsigned char *, size_t),
+                   void *p_rng );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int mbedtls_mpi_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* bignum.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/blowfish.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/blowfish.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/blowfish.h	(revision 398)
@@ -0,0 +1,287 @@
+/**
+ * \file blowfish.h
+ *
+ * \brief Blowfish block cipher
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_BLOWFISH_H
+#define MBEDTLS_BLOWFISH_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "platform_util.h"
+
+#define MBEDTLS_BLOWFISH_ENCRYPT     1
+#define MBEDTLS_BLOWFISH_DECRYPT     0
+#define MBEDTLS_BLOWFISH_MAX_KEY_BITS     448
+#define MBEDTLS_BLOWFISH_MIN_KEY_BITS     32
+#define MBEDTLS_BLOWFISH_ROUNDS      16         /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */
+#define MBEDTLS_BLOWFISH_BLOCKSIZE   8          /* Blowfish uses 64 bit blocks */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#define MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0016 )
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#define MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA -0x0016 /**< Bad input data. */
+
+#define MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */
+
+/* MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED                   -0x0017  /**< Blowfish hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_BLOWFISH_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          Blowfish context structure
+ */
+typedef struct mbedtls_blowfish_context
+{
+    uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2];    /*!<  Blowfish round keys    */
+    uint32_t S[4][256];                 /*!<  key dependent S-boxes  */
+}
+mbedtls_blowfish_context;
+
+#else  /* MBEDTLS_BLOWFISH_ALT */
+#include "blowfish_alt.h"
+#endif /* MBEDTLS_BLOWFISH_ALT */
+
+/**
+ * \brief          Initialize a Blowfish context.
+ *
+ * \param ctx      The Blowfish context to be initialized.
+ *                 This must not be \c NULL.
+ */
+void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx );
+
+/**
+ * \brief          Clear a Blowfish context.
+ *
+ * \param ctx      The Blowfish context to be cleared.
+ *                 This may be \c NULL, in which case this function
+ *                 returns immediately. If it is not \c NULL, it must
+ *                 point to an initialized Blowfish context.
+ */
+void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx );
+
+/**
+ * \brief          Perform a Blowfish key schedule operation.
+ *
+ * \param ctx      The Blowfish context to perform the key schedule on.
+ * \param key      The encryption key. This must be a readable buffer of
+ *                 length \p keybits Bits.
+ * \param keybits  The length of \p key in Bits. This must be between
+ *                 \c 32 and \c 448 and a multiple of \c 8.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key,
+                     unsigned int keybits );
+
+/**
+ * \brief          Perform a Blowfish-ECB block encryption/decryption operation.
+ *
+ * \param ctx      The Blowfish context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. Possible values are
+ *                 #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
+ *                 #MBEDTLS_BLOWFISH_DECRYPT for decryption.
+ * \param input    The input block. This must be a readable buffer
+ *                 of size \c 8 Bytes.
+ * \param output   The output block. This must be a writable buffer
+ *                 of size \c 8 Bytes.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
+                        int mode,
+                        const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
+                        unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/**
+ * \brief          Perform a Blowfish-CBC buffer encryption/decryption operation.
+ *
+ * \note           Upon exit, the content of the IV is updated so that you can
+ *                 call the function same function again on the following
+ *                 block(s) of data and get the same result as if it was
+ *                 encrypted in one call. This allows a "streaming" usage.
+ *                 If on the other hand you need to retain the contents of the
+ *                 IV, you should either save it manually or use the cipher
+ *                 module instead.
+ *
+ * \param ctx      The Blowfish context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. Possible values are
+ *                 #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
+ *                 #MBEDTLS_BLOWFISH_DECRYPT for decryption.
+ * \param length   The length of the input data in Bytes. This must be
+ *                 multiple of \c 8.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of length \c 8 Bytes. It is updated by this function.
+ * \param input    The input data. This must be a readable buffer of length
+ *                 \p length Bytes.
+ * \param output   The output data. This must be a writable buffer of length
+ *                 \p length Bytes.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
+                        int mode,
+                        size_t length,
+                        unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
+                        const unsigned char *input,
+                        unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/**
+ * \brief          Perform a Blowfish CFB buffer encryption/decryption operation.
+ *
+ * \note           Upon exit, the content of the IV is updated so that you can
+ *                 call the function same function again on the following
+ *                 block(s) of data and get the same result as if it was
+ *                 encrypted in one call. This allows a "streaming" usage.
+ *                 If on the other hand you need to retain the contents of the
+ *                 IV, you should either save it manually or use the cipher
+ *                 module instead.
+ *
+ * \param ctx      The Blowfish context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. Possible values are
+ *                 #MBEDTLS_BLOWFISH_ENCRYPT for encryption, or
+ *                 #MBEDTLS_BLOWFISH_DECRYPT for decryption.
+ * \param length   The length of the input data in Bytes.
+ * \param iv_off   The offset in the initialiation vector.
+ *                 The value pointed to must be smaller than \c 8 Bytes.
+ *                 It is updated by this function to support the aforementioned
+ *                 streaming usage.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of size \c 8 Bytes. It is updated after use.
+ * \param input    The input data. This must be a readable buffer of length
+ *                 \p length Bytes.
+ * \param output   The output data. This must be a writable buffer of length
+ *                 \p length Bytes.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
+                          int mode,
+                          size_t length,
+                          size_t *iv_off,
+                          unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
+                          const unsigned char *input,
+                          unsigned char *output );
+#endif /*MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/**
+ * \brief      Perform a Blowfish-CTR buffer encryption/decryption operation.
+ *
+ * \warning    You must never reuse a nonce value with the same key. Doing so
+ *             would void the encryption for the two messages encrypted with
+ *             the same nonce and key.
+ *
+ *             There are two common strategies for managing nonces with CTR:
+ *
+ *             1. You can handle everything as a single message processed over
+ *             successive calls to this function. In that case, you want to
+ *             set \p nonce_counter and \p nc_off to 0 for the first call, and
+ *             then preserve the values of \p nonce_counter, \p nc_off and \p
+ *             stream_block across calls to this function as they will be
+ *             updated by this function.
+ *
+ *             With this strategy, you must not encrypt more than 2**64
+ *             blocks of data with the same key.
+ *
+ *             2. You can encrypt separate messages by dividing the \p
+ *             nonce_counter buffer in two areas: the first one used for a
+ *             per-message nonce, handled by yourself, and the second one
+ *             updated by this function internally.
+ *
+ *             For example, you might reserve the first 4 bytes for the
+ *             per-message nonce, and the last 4 bytes for internal use. In that
+ *             case, before calling this function on a new message you need to
+ *             set the first 4 bytes of \p nonce_counter to your chosen nonce
+ *             value, the last 4 to 0, and \p nc_off to 0 (which will cause \p
+ *             stream_block to be ignored). That way, you can encrypt at most
+ *             2**32 messages of up to 2**32 blocks each with the same key.
+ *
+ *             The per-message nonce (or information sufficient to reconstruct
+ *             it) needs to be communicated with the ciphertext and must be unique.
+ *             The recommended way to ensure uniqueness is to use a message
+ *             counter.
+ *
+ *             Note that for both stategies, sizes are measured in blocks and
+ *             that a Blowfish block is 8 bytes.
+ *
+ * \warning    Upon return, \p stream_block contains sensitive data. Its
+ *             content must not be written to insecure storage and should be
+ *             securely discarded as soon as it's no longer needed.
+ *
+ * \param ctx           The Blowfish context to use. This must be initialized
+ *                      and bound to a key.
+ * \param length        The length of the input data in Bytes.
+ * \param nc_off        The offset in the current stream_block (for resuming
+ *                      within current cipher stream). The offset pointer
+ *                      should be \c 0 at the start of a stream and must be
+ *                      smaller than \c 8. It is updated by this function.
+ * \param nonce_counter The 64-bit nonce and counter. This must point to a
+ *                      read/write buffer of length \c 8 Bytes.
+ * \param stream_block  The saved stream-block for resuming. This must point to
+ *                      a read/write buffer of length \c 8 Bytes.
+ * \param input         The input data. This must be a readable buffer of
+ *                      length \p length Bytes.
+ * \param output        The output data. This must be a writable buffer of
+ *                      length \p length Bytes.
+ *
+ * \return              \c 0 if successful.
+ * \return              A negative error code on failure.
+ */
+int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
+                        size_t length,
+                        size_t *nc_off,
+                        unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
+                        unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
+                        const unsigned char *input,
+                        unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* blowfish.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/bn_mul.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/bn_mul.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/bn_mul.h	(revision 398)
@@ -0,0 +1,915 @@
+/**
+ * \file bn_mul.h
+ *
+ * \brief Multi-precision integer library
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *      Multiply source vector [s] with b, add result
+ *       to destination vector [d] and set carry c.
+ *
+ *      Currently supports:
+ *
+ *         . IA-32 (386+)         . AMD64 / EM64T
+ *         . IA-32 (SSE2)         . Motorola 68000
+ *         . PowerPC, 32-bit      . MicroBlaze
+ *         . PowerPC, 64-bit      . TriCore
+ *         . SPARC v8             . ARM v3+
+ *         . Alpha                . MIPS32
+ *         . C, longlong          . C, generic
+ */
+#ifndef MBEDTLS_BN_MUL_H
+#define MBEDTLS_BN_MUL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "bignum.h"
+
+#if defined(MBEDTLS_HAVE_ASM)
+
+#ifndef asm
+#define asm __asm
+#endif
+
+/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
+#if defined(__GNUC__) && \
+    ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
+
+/*
+ * Disable use of the i386 assembly code below if option -O0, to disable all
+ * compiler optimisations, is passed, detected with __OPTIMIZE__
+ * This is done as the number of registers used in the assembly code doesn't
+ * work with the -O0 option.
+ */
+#if defined(__i386__) && defined(__OPTIMIZE__)
+
+#define MULADDC_INIT                        \
+    asm(                                    \
+        "movl   %%ebx, %0           \n\t"   \
+        "movl   %5, %%esi           \n\t"   \
+        "movl   %6, %%edi           \n\t"   \
+        "movl   %7, %%ecx           \n\t"   \
+        "movl   %8, %%ebx           \n\t"
+
+#define MULADDC_CORE                        \
+        "lodsl                      \n\t"   \
+        "mull   %%ebx               \n\t"   \
+        "addl   %%ecx,   %%eax      \n\t"   \
+        "adcl   $0,      %%edx      \n\t"   \
+        "addl   (%%edi), %%eax      \n\t"   \
+        "adcl   $0,      %%edx      \n\t"   \
+        "movl   %%edx,   %%ecx      \n\t"   \
+        "stosl                      \n\t"
+
+#if defined(MBEDTLS_HAVE_SSE2)
+
+#define MULADDC_HUIT                            \
+        "movd     %%ecx,     %%mm1      \n\t"   \
+        "movd     %%ebx,     %%mm0      \n\t"   \
+        "movd     (%%edi),   %%mm3      \n\t"   \
+        "paddq    %%mm3,     %%mm1      \n\t"   \
+        "movd     (%%esi),   %%mm2      \n\t"   \
+        "pmuludq  %%mm0,     %%mm2      \n\t"   \
+        "movd     4(%%esi),  %%mm4      \n\t"   \
+        "pmuludq  %%mm0,     %%mm4      \n\t"   \
+        "movd     8(%%esi),  %%mm6      \n\t"   \
+        "pmuludq  %%mm0,     %%mm6      \n\t"   \
+        "movd     12(%%esi), %%mm7      \n\t"   \
+        "pmuludq  %%mm0,     %%mm7      \n\t"   \
+        "paddq    %%mm2,     %%mm1      \n\t"   \
+        "movd     4(%%edi),  %%mm3      \n\t"   \
+        "paddq    %%mm4,     %%mm3      \n\t"   \
+        "movd     8(%%edi),  %%mm5      \n\t"   \
+        "paddq    %%mm6,     %%mm5      \n\t"   \
+        "movd     12(%%edi), %%mm4      \n\t"   \
+        "paddq    %%mm4,     %%mm7      \n\t"   \
+        "movd     %%mm1,     (%%edi)    \n\t"   \
+        "movd     16(%%esi), %%mm2      \n\t"   \
+        "pmuludq  %%mm0,     %%mm2      \n\t"   \
+        "psrlq    $32,       %%mm1      \n\t"   \
+        "movd     20(%%esi), %%mm4      \n\t"   \
+        "pmuludq  %%mm0,     %%mm4      \n\t"   \
+        "paddq    %%mm3,     %%mm1      \n\t"   \
+        "movd     24(%%esi), %%mm6      \n\t"   \
+        "pmuludq  %%mm0,     %%mm6      \n\t"   \
+        "movd     %%mm1,     4(%%edi)   \n\t"   \
+        "psrlq    $32,       %%mm1      \n\t"   \
+        "movd     28(%%esi), %%mm3      \n\t"   \
+        "pmuludq  %%mm0,     %%mm3      \n\t"   \
+        "paddq    %%mm5,     %%mm1      \n\t"   \
+        "movd     16(%%edi), %%mm5      \n\t"   \
+        "paddq    %%mm5,     %%mm2      \n\t"   \
+        "movd     %%mm1,     8(%%edi)   \n\t"   \
+        "psrlq    $32,       %%mm1      \n\t"   \
+        "paddq    %%mm7,     %%mm1      \n\t"   \
+        "movd     20(%%edi), %%mm5      \n\t"   \
+        "paddq    %%mm5,     %%mm4      \n\t"   \
+        "movd     %%mm1,     12(%%edi)  \n\t"   \
+        "psrlq    $32,       %%mm1      \n\t"   \
+        "paddq    %%mm2,     %%mm1      \n\t"   \
+        "movd     24(%%edi), %%mm5      \n\t"   \
+        "paddq    %%mm5,     %%mm6      \n\t"   \
+        "movd     %%mm1,     16(%%edi)  \n\t"   \
+        "psrlq    $32,       %%mm1      \n\t"   \
+        "paddq    %%mm4,     %%mm1      \n\t"   \
+        "movd     28(%%edi), %%mm5      \n\t"   \
+        "paddq    %%mm5,     %%mm3      \n\t"   \
+        "movd     %%mm1,     20(%%edi)  \n\t"   \
+        "psrlq    $32,       %%mm1      \n\t"   \
+        "paddq    %%mm6,     %%mm1      \n\t"   \
+        "movd     %%mm1,     24(%%edi)  \n\t"   \
+        "psrlq    $32,       %%mm1      \n\t"   \
+        "paddq    %%mm3,     %%mm1      \n\t"   \
+        "movd     %%mm1,     28(%%edi)  \n\t"   \
+        "addl     $32,       %%edi      \n\t"   \
+        "addl     $32,       %%esi      \n\t"   \
+        "psrlq    $32,       %%mm1      \n\t"   \
+        "movd     %%mm1,     %%ecx      \n\t"
+
+#define MULADDC_STOP                    \
+        "emms                   \n\t"   \
+        "movl   %4, %%ebx       \n\t"   \
+        "movl   %%ecx, %1       \n\t"   \
+        "movl   %%edi, %2       \n\t"   \
+        "movl   %%esi, %3       \n\t"   \
+        : "=m" (t), "=m" (c), "=m" (d), "=m" (s)        \
+        : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b)   \
+        : "eax", "ebx", "ecx", "edx", "esi", "edi"      \
+    );
+
+#else
+
+#define MULADDC_STOP                    \
+        "movl   %4, %%ebx       \n\t"   \
+        "movl   %%ecx, %1       \n\t"   \
+        "movl   %%edi, %2       \n\t"   \
+        "movl   %%esi, %3       \n\t"   \
+        : "=m" (t), "=m" (c), "=m" (d), "=m" (s)        \
+        : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b)   \
+        : "eax", "ebx", "ecx", "edx", "esi", "edi"      \
+    );
+#endif /* SSE2 */
+#endif /* i386 */
+
+#if defined(__amd64__) || defined (__x86_64__)
+
+#define MULADDC_INIT                        \
+    asm(                                    \
+        "xorq   %%r8, %%r8\n"
+
+#define MULADDC_CORE                        \
+        "movq   (%%rsi), %%rax\n"           \
+        "mulq   %%rbx\n"                    \
+        "addq   $8, %%rsi\n"                \
+        "addq   %%rcx, %%rax\n"             \
+        "movq   %%r8, %%rcx\n"              \
+        "adcq   $0, %%rdx\n"                \
+        "nop    \n"                         \
+        "addq   %%rax, (%%rdi)\n"           \
+        "adcq   %%rdx, %%rcx\n"             \
+        "addq   $8, %%rdi\n"
+
+#define MULADDC_STOP                        \
+        : "+c" (c), "+D" (d), "+S" (s)      \
+        : "b" (b)                           \
+        : "rax", "rdx", "r8"                \
+    );
+
+#endif /* AMD64 */
+
+#if defined(__mc68020__) || defined(__mcpu32__)
+
+#define MULADDC_INIT                    \
+    asm(                                \
+        "movl   %3, %%a2        \n\t"   \
+        "movl   %4, %%a3        \n\t"   \
+        "movl   %5, %%d3        \n\t"   \
+        "movl   %6, %%d2        \n\t"   \
+        "moveq  #0, %%d0        \n\t"
+
+#define MULADDC_CORE                    \
+        "movel  %%a2@+, %%d1    \n\t"   \
+        "mulul  %%d2, %%d4:%%d1 \n\t"   \
+        "addl   %%d3, %%d1      \n\t"   \
+        "addxl  %%d0, %%d4      \n\t"   \
+        "moveq  #0,   %%d3      \n\t"   \
+        "addl   %%d1, %%a3@+    \n\t"   \
+        "addxl  %%d4, %%d3      \n\t"
+
+#define MULADDC_STOP                    \
+        "movl   %%d3, %0        \n\t"   \
+        "movl   %%a3, %1        \n\t"   \
+        "movl   %%a2, %2        \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)              \
+        : "m" (s), "m" (d), "m" (c), "m" (b)        \
+        : "d0", "d1", "d2", "d3", "d4", "a2", "a3"  \
+    );
+
+#define MULADDC_HUIT                        \
+        "movel  %%a2@+,  %%d1       \n\t"   \
+        "mulul  %%d2,    %%d4:%%d1  \n\t"   \
+        "addxl  %%d3,    %%d1       \n\t"   \
+        "addxl  %%d0,    %%d4       \n\t"   \
+        "addl   %%d1,    %%a3@+     \n\t"   \
+        "movel  %%a2@+,  %%d1       \n\t"   \
+        "mulul  %%d2,    %%d3:%%d1  \n\t"   \
+        "addxl  %%d4,    %%d1       \n\t"   \
+        "addxl  %%d0,    %%d3       \n\t"   \
+        "addl   %%d1,    %%a3@+     \n\t"   \
+        "movel  %%a2@+,  %%d1       \n\t"   \
+        "mulul  %%d2,    %%d4:%%d1  \n\t"   \
+        "addxl  %%d3,    %%d1       \n\t"   \
+        "addxl  %%d0,    %%d4       \n\t"   \
+        "addl   %%d1,    %%a3@+     \n\t"   \
+        "movel  %%a2@+,  %%d1       \n\t"   \
+        "mulul  %%d2,    %%d3:%%d1  \n\t"   \
+        "addxl  %%d4,    %%d1       \n\t"   \
+        "addxl  %%d0,    %%d3       \n\t"   \
+        "addl   %%d1,    %%a3@+     \n\t"   \
+        "movel  %%a2@+,  %%d1       \n\t"   \
+        "mulul  %%d2,    %%d4:%%d1  \n\t"   \
+        "addxl  %%d3,    %%d1       \n\t"   \
+        "addxl  %%d0,    %%d4       \n\t"   \
+        "addl   %%d1,    %%a3@+     \n\t"   \
+        "movel  %%a2@+,  %%d1       \n\t"   \
+        "mulul  %%d2,    %%d3:%%d1  \n\t"   \
+        "addxl  %%d4,    %%d1       \n\t"   \
+        "addxl  %%d0,    %%d3       \n\t"   \
+        "addl   %%d1,    %%a3@+     \n\t"   \
+        "movel  %%a2@+,  %%d1       \n\t"   \
+        "mulul  %%d2,    %%d4:%%d1  \n\t"   \
+        "addxl  %%d3,    %%d1       \n\t"   \
+        "addxl  %%d0,    %%d4       \n\t"   \
+        "addl   %%d1,    %%a3@+     \n\t"   \
+        "movel  %%a2@+,  %%d1       \n\t"   \
+        "mulul  %%d2,    %%d3:%%d1  \n\t"   \
+        "addxl  %%d4,    %%d1       \n\t"   \
+        "addxl  %%d0,    %%d3       \n\t"   \
+        "addl   %%d1,    %%a3@+     \n\t"   \
+        "addxl  %%d0,    %%d3       \n\t"
+
+#endif /* MC68000 */
+
+#if defined(__powerpc64__) || defined(__ppc64__)
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT                        \
+    asm(                                    \
+        "ld     r3, %3              \n\t"   \
+        "ld     r4, %4              \n\t"   \
+        "ld     r5, %5              \n\t"   \
+        "ld     r6, %6              \n\t"   \
+        "addi   r3, r3, -8          \n\t"   \
+        "addi   r4, r4, -8          \n\t"   \
+        "addic  r5, r5,  0          \n\t"
+
+#define MULADDC_CORE                        \
+        "ldu    r7, 8(r3)           \n\t"   \
+        "mulld  r8, r7, r6          \n\t"   \
+        "mulhdu r9, r7, r6          \n\t"   \
+        "adde   r8, r8, r5          \n\t"   \
+        "ld     r7, 8(r4)           \n\t"   \
+        "addze  r5, r9              \n\t"   \
+        "addc   r8, r8, r7          \n\t"   \
+        "stdu   r8, 8(r4)           \n\t"
+
+#define MULADDC_STOP                        \
+        "addze  r5, r5              \n\t"   \
+        "addi   r4, r4, 8           \n\t"   \
+        "addi   r3, r3, 8           \n\t"   \
+        "std    r5, %0              \n\t"   \
+        "std    r4, %1              \n\t"   \
+        "std    r3, %2              \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)              \
+        : "m" (s), "m" (d), "m" (c), "m" (b)        \
+        : "r3", "r4", "r5", "r6", "r7", "r8", "r9"  \
+    );
+
+
+#else /* __MACH__ && __APPLE__ */
+
+#define MULADDC_INIT                        \
+    asm(                                    \
+        "ld     %%r3, %3            \n\t"   \
+        "ld     %%r4, %4            \n\t"   \
+        "ld     %%r5, %5            \n\t"   \
+        "ld     %%r6, %6            \n\t"   \
+        "addi   %%r3, %%r3, -8      \n\t"   \
+        "addi   %%r4, %%r4, -8      \n\t"   \
+        "addic  %%r5, %%r5,  0      \n\t"
+
+#define MULADDC_CORE                        \
+        "ldu    %%r7, 8(%%r3)       \n\t"   \
+        "mulld  %%r8, %%r7, %%r6    \n\t"   \
+        "mulhdu %%r9, %%r7, %%r6    \n\t"   \
+        "adde   %%r8, %%r8, %%r5    \n\t"   \
+        "ld     %%r7, 8(%%r4)       \n\t"   \
+        "addze  %%r5, %%r9          \n\t"   \
+        "addc   %%r8, %%r8, %%r7    \n\t"   \
+        "stdu   %%r8, 8(%%r4)       \n\t"
+
+#define MULADDC_STOP                        \
+        "addze  %%r5, %%r5          \n\t"   \
+        "addi   %%r4, %%r4, 8       \n\t"   \
+        "addi   %%r3, %%r3, 8       \n\t"   \
+        "std    %%r5, %0            \n\t"   \
+        "std    %%r4, %1            \n\t"   \
+        "std    %%r3, %2            \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)              \
+        : "m" (s), "m" (d), "m" (c), "m" (b)        \
+        : "r3", "r4", "r5", "r6", "r7", "r8", "r9"  \
+    );
+
+#endif /* __MACH__ && __APPLE__ */
+
+#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32  */
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT                    \
+    asm(                                \
+        "lwz    r3, %3          \n\t"   \
+        "lwz    r4, %4          \n\t"   \
+        "lwz    r5, %5          \n\t"   \
+        "lwz    r6, %6          \n\t"   \
+        "addi   r3, r3, -4      \n\t"   \
+        "addi   r4, r4, -4      \n\t"   \
+        "addic  r5, r5,  0      \n\t"
+
+#define MULADDC_CORE                    \
+        "lwzu   r7, 4(r3)       \n\t"   \
+        "mullw  r8, r7, r6      \n\t"   \
+        "mulhwu r9, r7, r6      \n\t"   \
+        "adde   r8, r8, r5      \n\t"   \
+        "lwz    r7, 4(r4)       \n\t"   \
+        "addze  r5, r9          \n\t"   \
+        "addc   r8, r8, r7      \n\t"   \
+        "stwu   r8, 4(r4)       \n\t"
+
+#define MULADDC_STOP                    \
+        "addze  r5, r5          \n\t"   \
+        "addi   r4, r4, 4       \n\t"   \
+        "addi   r3, r3, 4       \n\t"   \
+        "stw    r5, %0          \n\t"   \
+        "stw    r4, %1          \n\t"   \
+        "stw    r3, %2          \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)              \
+        : "m" (s), "m" (d), "m" (c), "m" (b)        \
+        : "r3", "r4", "r5", "r6", "r7", "r8", "r9"  \
+    );
+
+#else /* __MACH__ && __APPLE__ */
+
+#define MULADDC_INIT                        \
+    asm(                                    \
+        "lwz    %%r3, %3            \n\t"   \
+        "lwz    %%r4, %4            \n\t"   \
+        "lwz    %%r5, %5            \n\t"   \
+        "lwz    %%r6, %6            \n\t"   \
+        "addi   %%r3, %%r3, -4      \n\t"   \
+        "addi   %%r4, %%r4, -4      \n\t"   \
+        "addic  %%r5, %%r5,  0      \n\t"
+
+#define MULADDC_CORE                        \
+        "lwzu   %%r7, 4(%%r3)       \n\t"   \
+        "mullw  %%r8, %%r7, %%r6    \n\t"   \
+        "mulhwu %%r9, %%r7, %%r6    \n\t"   \
+        "adde   %%r8, %%r8, %%r5    \n\t"   \
+        "lwz    %%r7, 4(%%r4)       \n\t"   \
+        "addze  %%r5, %%r9          \n\t"   \
+        "addc   %%r8, %%r8, %%r7    \n\t"   \
+        "stwu   %%r8, 4(%%r4)       \n\t"
+
+#define MULADDC_STOP                        \
+        "addze  %%r5, %%r5          \n\t"   \
+        "addi   %%r4, %%r4, 4       \n\t"   \
+        "addi   %%r3, %%r3, 4       \n\t"   \
+        "stw    %%r5, %0            \n\t"   \
+        "stw    %%r4, %1            \n\t"   \
+        "stw    %%r3, %2            \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)              \
+        : "m" (s), "m" (d), "m" (c), "m" (b)        \
+        : "r3", "r4", "r5", "r6", "r7", "r8", "r9"  \
+    );
+
+#endif /* __MACH__ && __APPLE__ */
+
+#endif /* PPC32 */
+
+/*
+ * The Sparc(64) assembly is reported to be broken.
+ * Disable it for now, until we're able to fix it.
+ */
+#if 0 && defined(__sparc__)
+#if defined(__sparc64__)
+
+#define MULADDC_INIT                                    \
+    asm(                                                \
+                "ldx     %3, %%o0               \n\t"   \
+                "ldx     %4, %%o1               \n\t"   \
+                "ld      %5, %%o2               \n\t"   \
+                "ld      %6, %%o3               \n\t"
+
+#define MULADDC_CORE                                    \
+                "ld      [%%o0], %%o4           \n\t"   \
+                "inc     4, %%o0                \n\t"   \
+                "ld      [%%o1], %%o5           \n\t"   \
+                "umul    %%o3, %%o4, %%o4       \n\t"   \
+                "addcc   %%o4, %%o2, %%o4       \n\t"   \
+                "rd      %%y, %%g1              \n\t"   \
+                "addx    %%g1, 0, %%g1          \n\t"   \
+                "addcc   %%o4, %%o5, %%o4       \n\t"   \
+                "st      %%o4, [%%o1]           \n\t"   \
+                "addx    %%g1, 0, %%o2          \n\t"   \
+                "inc     4, %%o1                \n\t"
+
+        #define MULADDC_STOP                            \
+                "st      %%o2, %0               \n\t"   \
+                "stx     %%o1, %1               \n\t"   \
+                "stx     %%o0, %2               \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)          \
+        : "m" (s), "m" (d), "m" (c), "m" (b)    \
+        : "g1", "o0", "o1", "o2", "o3", "o4",   \
+          "o5"                                  \
+        );
+
+#else /* __sparc64__ */
+
+#define MULADDC_INIT                                    \
+    asm(                                                \
+                "ld      %3, %%o0               \n\t"   \
+                "ld      %4, %%o1               \n\t"   \
+                "ld      %5, %%o2               \n\t"   \
+                "ld      %6, %%o3               \n\t"
+
+#define MULADDC_CORE                                    \
+                "ld      [%%o0], %%o4           \n\t"   \
+                "inc     4, %%o0                \n\t"   \
+                "ld      [%%o1], %%o5           \n\t"   \
+                "umul    %%o3, %%o4, %%o4       \n\t"   \
+                "addcc   %%o4, %%o2, %%o4       \n\t"   \
+                "rd      %%y, %%g1              \n\t"   \
+                "addx    %%g1, 0, %%g1          \n\t"   \
+                "addcc   %%o4, %%o5, %%o4       \n\t"   \
+                "st      %%o4, [%%o1]           \n\t"   \
+                "addx    %%g1, 0, %%o2          \n\t"   \
+                "inc     4, %%o1                \n\t"
+
+#define MULADDC_STOP                                    \
+                "st      %%o2, %0               \n\t"   \
+                "st      %%o1, %1               \n\t"   \
+                "st      %%o0, %2               \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)          \
+        : "m" (s), "m" (d), "m" (c), "m" (b)    \
+        : "g1", "o0", "o1", "o2", "o3", "o4",   \
+          "o5"                                  \
+        );
+
+#endif /* __sparc64__ */
+#endif /* __sparc__ */
+
+#if defined(__microblaze__) || defined(microblaze)
+
+#define MULADDC_INIT                    \
+    asm(                                \
+        "lwi   r3,   %3         \n\t"   \
+        "lwi   r4,   %4         \n\t"   \
+        "lwi   r5,   %5         \n\t"   \
+        "lwi   r6,   %6         \n\t"   \
+        "andi  r7,   r6, 0xffff \n\t"   \
+        "bsrli r6,   r6, 16     \n\t"
+
+#define MULADDC_CORE                    \
+        "lhui  r8,   r3,   0    \n\t"   \
+        "addi  r3,   r3,   2    \n\t"   \
+        "lhui  r9,   r3,   0    \n\t"   \
+        "addi  r3,   r3,   2    \n\t"   \
+        "mul   r10,  r9,  r6    \n\t"   \
+        "mul   r11,  r8,  r7    \n\t"   \
+        "mul   r12,  r9,  r7    \n\t"   \
+        "mul   r13,  r8,  r6    \n\t"   \
+        "bsrli  r8, r10,  16    \n\t"   \
+        "bsrli  r9, r11,  16    \n\t"   \
+        "add   r13, r13,  r8    \n\t"   \
+        "add   r13, r13,  r9    \n\t"   \
+        "bslli r10, r10,  16    \n\t"   \
+        "bslli r11, r11,  16    \n\t"   \
+        "add   r12, r12, r10    \n\t"   \
+        "addc  r13, r13,  r0    \n\t"   \
+        "add   r12, r12, r11    \n\t"   \
+        "addc  r13, r13,  r0    \n\t"   \
+        "lwi   r10,  r4,   0    \n\t"   \
+        "add   r12, r12, r10    \n\t"   \
+        "addc  r13, r13,  r0    \n\t"   \
+        "add   r12, r12,  r5    \n\t"   \
+        "addc   r5, r13,  r0    \n\t"   \
+        "swi   r12,  r4,   0    \n\t"   \
+        "addi   r4,  r4,   4    \n\t"
+
+#define MULADDC_STOP                    \
+        "swi   r5,   %0         \n\t"   \
+        "swi   r4,   %1         \n\t"   \
+        "swi   r3,   %2         \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)              \
+        : "m" (s), "m" (d), "m" (c), "m" (b)        \
+        : "r3", "r4", "r5", "r6", "r7", "r8",       \
+          "r9", "r10", "r11", "r12", "r13"          \
+    );
+
+#endif /* MicroBlaze */
+
+#if defined(__tricore__)
+
+#define MULADDC_INIT                            \
+    asm(                                        \
+        "ld.a   %%a2, %3                \n\t"   \
+        "ld.a   %%a3, %4                \n\t"   \
+        "ld.w   %%d4, %5                \n\t"   \
+        "ld.w   %%d1, %6                \n\t"   \
+        "xor    %%d5, %%d5              \n\t"
+
+#define MULADDC_CORE                            \
+        "ld.w   %%d0,   [%%a2+]         \n\t"   \
+        "madd.u %%e2, %%e4, %%d0, %%d1  \n\t"   \
+        "ld.w   %%d0,   [%%a3]          \n\t"   \
+        "addx   %%d2,    %%d2,  %%d0    \n\t"   \
+        "addc   %%d3,    %%d3,    0     \n\t"   \
+        "mov    %%d4,    %%d3           \n\t"   \
+        "st.w  [%%a3+],  %%d2           \n\t"
+
+#define MULADDC_STOP                            \
+        "st.w   %0, %%d4                \n\t"   \
+        "st.a   %1, %%a3                \n\t"   \
+        "st.a   %2, %%a2                \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)          \
+        : "m" (s), "m" (d), "m" (c), "m" (b)    \
+        : "d0", "d1", "e2", "d4", "a2", "a3"    \
+    );
+
+#endif /* TriCore */
+
+/*
+ * Note, gcc -O0 by default uses r7 for the frame pointer, so it complains about
+ * our use of r7 below, unless -fomit-frame-pointer is passed.
+ *
+ * On the other hand, -fomit-frame-pointer is implied by any -Ox options with
+ * x !=0, which we can detect using __OPTIMIZE__ (which is also defined by
+ * clang and armcc5 under the same conditions).
+ *
+ * So, only use the optimized assembly below for optimized build, which avoids
+ * the build error and is pretty reasonable anyway.
+ */
+#if defined(__GNUC__) && !defined(__OPTIMIZE__)
+#define MULADDC_CANNOT_USE_R7
+#endif
+
+#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7)
+
+#if defined(__thumb__) && !defined(__thumb2__)
+
+#define MULADDC_INIT                                    \
+    asm(                                                \
+            "ldr    r0, %3                      \n\t"   \
+            "ldr    r1, %4                      \n\t"   \
+            "ldr    r2, %5                      \n\t"   \
+            "ldr    r3, %6                      \n\t"   \
+            "lsr    r7, r3, #16                 \n\t"   \
+            "mov    r9, r7                      \n\t"   \
+            "lsl    r7, r3, #16                 \n\t"   \
+            "lsr    r7, r7, #16                 \n\t"   \
+            "mov    r8, r7                      \n\t"
+
+#define MULADDC_CORE                                    \
+            "ldmia  r0!, {r6}                   \n\t"   \
+            "lsr    r7, r6, #16                 \n\t"   \
+            "lsl    r6, r6, #16                 \n\t"   \
+            "lsr    r6, r6, #16                 \n\t"   \
+            "mov    r4, r8                      \n\t"   \
+            "mul    r4, r6                      \n\t"   \
+            "mov    r3, r9                      \n\t"   \
+            "mul    r6, r3                      \n\t"   \
+            "mov    r5, r9                      \n\t"   \
+            "mul    r5, r7                      \n\t"   \
+            "mov    r3, r8                      \n\t"   \
+            "mul    r7, r3                      \n\t"   \
+            "lsr    r3, r6, #16                 \n\t"   \
+            "add    r5, r5, r3                  \n\t"   \
+            "lsr    r3, r7, #16                 \n\t"   \
+            "add    r5, r5, r3                  \n\t"   \
+            "add    r4, r4, r2                  \n\t"   \
+            "mov    r2, #0                      \n\t"   \
+            "adc    r5, r2                      \n\t"   \
+            "lsl    r3, r6, #16                 \n\t"   \
+            "add    r4, r4, r3                  \n\t"   \
+            "adc    r5, r2                      \n\t"   \
+            "lsl    r3, r7, #16                 \n\t"   \
+            "add    r4, r4, r3                  \n\t"   \
+            "adc    r5, r2                      \n\t"   \
+            "ldr    r3, [r1]                    \n\t"   \
+            "add    r4, r4, r3                  \n\t"   \
+            "adc    r2, r5                      \n\t"   \
+            "stmia  r1!, {r4}                   \n\t"
+
+#define MULADDC_STOP                                    \
+            "str    r2, %0                      \n\t"   \
+            "str    r1, %1                      \n\t"   \
+            "str    r0, %2                      \n\t"   \
+         : "=m" (c),  "=m" (d), "=m" (s)        \
+         : "m" (s), "m" (d), "m" (c), "m" (b)   \
+         : "r0", "r1", "r2", "r3", "r4", "r5",  \
+           "r6", "r7", "r8", "r9", "cc"         \
+         );
+
+#elif defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
+
+#define MULADDC_INIT                            \
+    asm(
+
+#define MULADDC_CORE                            \
+            "ldr    r0, [%0], #4        \n\t"   \
+            "ldr    r1, [%1]            \n\t"   \
+            "umaal  r1, %2, %3, r0      \n\t"   \
+            "str    r1, [%1], #4        \n\t"
+
+#define MULADDC_STOP                            \
+         : "=r" (s),  "=r" (d), "=r" (c)        \
+         : "r" (b), "0" (s), "1" (d), "2" (c)   \
+         : "r0", "r1", "memory"                 \
+         );
+
+#else
+
+#define MULADDC_INIT                                    \
+    asm(                                                \
+            "ldr    r0, %3                      \n\t"   \
+            "ldr    r1, %4                      \n\t"   \
+            "ldr    r2, %5                      \n\t"   \
+            "ldr    r3, %6                      \n\t"
+
+#define MULADDC_CORE                                    \
+            "ldr    r4, [r0], #4                \n\t"   \
+            "mov    r5, #0                      \n\t"   \
+            "ldr    r6, [r1]                    \n\t"   \
+            "umlal  r2, r5, r3, r4              \n\t"   \
+            "adds   r7, r6, r2                  \n\t"   \
+            "adc    r2, r5, #0                  \n\t"   \
+            "str    r7, [r1], #4                \n\t"
+
+#define MULADDC_STOP                                    \
+            "str    r2, %0                      \n\t"   \
+            "str    r1, %1                      \n\t"   \
+            "str    r0, %2                      \n\t"   \
+         : "=m" (c),  "=m" (d), "=m" (s)        \
+         : "m" (s), "m" (d), "m" (c), "m" (b)   \
+         : "r0", "r1", "r2", "r3", "r4", "r5",  \
+           "r6", "r7", "cc"                     \
+         );
+
+#endif /* Thumb */
+
+#endif /* ARMv3 */
+
+#if defined(__alpha__)
+
+#define MULADDC_INIT                    \
+    asm(                                \
+        "ldq    $1, %3          \n\t"   \
+        "ldq    $2, %4          \n\t"   \
+        "ldq    $3, %5          \n\t"   \
+        "ldq    $4, %6          \n\t"
+
+#define MULADDC_CORE                    \
+        "ldq    $6,  0($1)      \n\t"   \
+        "addq   $1,  8, $1      \n\t"   \
+        "mulq   $6, $4, $7      \n\t"   \
+        "umulh  $6, $4, $6      \n\t"   \
+        "addq   $7, $3, $7      \n\t"   \
+        "cmpult $7, $3, $3      \n\t"   \
+        "ldq    $5,  0($2)      \n\t"   \
+        "addq   $7, $5, $7      \n\t"   \
+        "cmpult $7, $5, $5      \n\t"   \
+        "stq    $7,  0($2)      \n\t"   \
+        "addq   $2,  8, $2      \n\t"   \
+        "addq   $6, $3, $3      \n\t"   \
+        "addq   $5, $3, $3      \n\t"
+
+#define MULADDC_STOP                                    \
+        "stq    $3, %0          \n\t"   \
+        "stq    $2, %1          \n\t"   \
+        "stq    $1, %2          \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)              \
+        : "m" (s), "m" (d), "m" (c), "m" (b)        \
+        : "$1", "$2", "$3", "$4", "$5", "$6", "$7"  \
+    );
+#endif /* Alpha */
+
+#if defined(__mips__) && !defined(__mips64)
+
+#define MULADDC_INIT                    \
+    asm(                                \
+        "lw     $10, %3         \n\t"   \
+        "lw     $11, %4         \n\t"   \
+        "lw     $12, %5         \n\t"   \
+        "lw     $13, %6         \n\t"
+
+#define MULADDC_CORE                    \
+        "lw     $14, 0($10)     \n\t"   \
+        "multu  $13, $14        \n\t"   \
+        "addi   $10, $10, 4     \n\t"   \
+        "mflo   $14             \n\t"   \
+        "mfhi   $9              \n\t"   \
+        "addu   $14, $12, $14   \n\t"   \
+        "lw     $15, 0($11)     \n\t"   \
+        "sltu   $12, $14, $12   \n\t"   \
+        "addu   $15, $14, $15   \n\t"   \
+        "sltu   $14, $15, $14   \n\t"   \
+        "addu   $12, $12, $9    \n\t"   \
+        "sw     $15, 0($11)     \n\t"   \
+        "addu   $12, $12, $14   \n\t"   \
+        "addi   $11, $11, 4     \n\t"
+
+#define MULADDC_STOP                    \
+        "sw     $12, %0         \n\t"   \
+        "sw     $11, %1         \n\t"   \
+        "sw     $10, %2         \n\t"   \
+        : "=m" (c), "=m" (d), "=m" (s)                      \
+        : "m" (s), "m" (d), "m" (c), "m" (b)                \
+        : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "lo", "hi" \
+    );
+
+#endif /* MIPS */
+#endif /* GNUC */
+
+#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
+
+#define MULADDC_INIT                            \
+    __asm   mov     esi, s                      \
+    __asm   mov     edi, d                      \
+    __asm   mov     ecx, c                      \
+    __asm   mov     ebx, b
+
+#define MULADDC_CORE                            \
+    __asm   lodsd                               \
+    __asm   mul     ebx                         \
+    __asm   add     eax, ecx                    \
+    __asm   adc     edx, 0                      \
+    __asm   add     eax, [edi]                  \
+    __asm   adc     edx, 0                      \
+    __asm   mov     ecx, edx                    \
+    __asm   stosd
+
+#if defined(MBEDTLS_HAVE_SSE2)
+
+#define EMIT __asm _emit
+
+#define MULADDC_HUIT                            \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0xC9             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0xC3             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x1F             \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCB             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x16             \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xD0             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x66  EMIT 0x04  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xE0             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x76  EMIT 0x08  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xF0             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x7E  EMIT 0x0C  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xF8             \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCA             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x5F  EMIT 0x04  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xDC             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x6F  EMIT 0x08  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xEE             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x67  EMIT 0x0C  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xFC             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x0F             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x56  EMIT 0x10  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xD0             \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x66  EMIT 0x14  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xE0             \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCB             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x76  EMIT 0x18  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xF0             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x04  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x5E  EMIT 0x1C  \
+    EMIT 0x0F  EMIT 0xF4  EMIT 0xD8             \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCD             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x6F  EMIT 0x10  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xD5             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x08  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCF             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x6F  EMIT 0x14  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xE5             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x0C  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCA             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x6F  EMIT 0x18  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xF5             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x10  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCC             \
+    EMIT 0x0F  EMIT 0x6E  EMIT 0x6F  EMIT 0x1C  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xDD             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x14  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCE             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x18  \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0xD4  EMIT 0xCB             \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0x4F  EMIT 0x1C  \
+    EMIT 0x83  EMIT 0xC7  EMIT 0x20             \
+    EMIT 0x83  EMIT 0xC6  EMIT 0x20             \
+    EMIT 0x0F  EMIT 0x73  EMIT 0xD1  EMIT 0x20  \
+    EMIT 0x0F  EMIT 0x7E  EMIT 0xC9
+
+#define MULADDC_STOP                            \
+    EMIT 0x0F  EMIT 0x77                        \
+    __asm   mov     c, ecx                      \
+    __asm   mov     d, edi                      \
+    __asm   mov     s, esi                      \
+
+#else
+
+#define MULADDC_STOP                            \
+    __asm   mov     c, ecx                      \
+    __asm   mov     d, edi                      \
+    __asm   mov     s, esi                      \
+
+#endif /* SSE2 */
+#endif /* MSVC */
+
+#endif /* MBEDTLS_HAVE_ASM */
+
+#if !defined(MULADDC_CORE)
+#if defined(MBEDTLS_HAVE_UDBL)
+
+#define MULADDC_INIT                    \
+{                                       \
+    mbedtls_t_udbl r;                           \
+    mbedtls_mpi_uint r0, r1;
+
+#define MULADDC_CORE                    \
+    r   = *(s++) * (mbedtls_t_udbl) b;          \
+    r0  = (mbedtls_mpi_uint) r;                   \
+    r1  = (mbedtls_mpi_uint)( r >> biL );         \
+    r0 += c;  r1 += (r0 <  c);          \
+    r0 += *d; r1 += (r0 < *d);          \
+    c = r1; *(d++) = r0;
+
+#define MULADDC_STOP                    \
+}
+
+#else
+#define MULADDC_INIT                    \
+{                                       \
+    mbedtls_mpi_uint s0, s1, b0, b1;              \
+    mbedtls_mpi_uint r0, r1, rx, ry;              \
+    b0 = ( b << biH ) >> biH;           \
+    b1 = ( b >> biH );
+
+#define MULADDC_CORE                    \
+    s0 = ( *s << biH ) >> biH;          \
+    s1 = ( *s >> biH ); s++;            \
+    rx = s0 * b1; r0 = s0 * b0;         \
+    ry = s1 * b0; r1 = s1 * b1;         \
+    r1 += ( rx >> biH );                \
+    r1 += ( ry >> biH );                \
+    rx <<= biH; ry <<= biH;             \
+    r0 += rx; r1 += (r0 < rx);          \
+    r0 += ry; r1 += (r0 < ry);          \
+    r0 +=  c; r1 += (r0 <  c);          \
+    r0 += *d; r1 += (r0 < *d);          \
+    c = r1; *(d++) = r0;
+
+#define MULADDC_STOP                    \
+}
+
+#endif /* C (generic)  */
+#endif /* C (longlong) */
+
+#endif /* bn_mul.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/camellia.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/camellia.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/camellia.h	(revision 398)
@@ -0,0 +1,326 @@
+/**
+ * \file camellia.h
+ *
+ * \brief Camellia block cipher
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_CAMELLIA_H
+#define MBEDTLS_CAMELLIA_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "platform_util.h"
+
+#define MBEDTLS_CAMELLIA_ENCRYPT     1
+#define MBEDTLS_CAMELLIA_DECRYPT     0
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#define MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH   MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( -0x0024 )
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+#define MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA -0x0024 /**< Bad input data. */
+
+#define MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */
+
+/* MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED              -0x0027  /**< Camellia hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_CAMELLIA_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          CAMELLIA context structure
+ */
+typedef struct mbedtls_camellia_context
+{
+    int nr;                     /*!<  number of rounds  */
+    uint32_t rk[68];            /*!<  CAMELLIA round keys    */
+}
+mbedtls_camellia_context;
+
+#else  /* MBEDTLS_CAMELLIA_ALT */
+#include "camellia_alt.h"
+#endif /* MBEDTLS_CAMELLIA_ALT */
+
+/**
+ * \brief          Initialize a CAMELLIA context.
+ *
+ * \param ctx      The CAMELLIA context to be initialized.
+ *                 This must not be \c NULL.
+ */
+void mbedtls_camellia_init( mbedtls_camellia_context *ctx );
+
+/**
+ * \brief          Clear a CAMELLIA context.
+ *
+ * \param ctx      The CAMELLIA context to be cleared. This may be \c NULL,
+ *                 in which case this function returns immediately. If it is not
+ *                 \c NULL, it must be initialized.
+ */
+void mbedtls_camellia_free( mbedtls_camellia_context *ctx );
+
+/**
+ * \brief          Perform a CAMELLIA key schedule operation for encryption.
+ *
+ * \param ctx      The CAMELLIA context to use. This must be initialized.
+ * \param key      The encryption key to use. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The length of \p key in Bits. This must be either \c 128,
+ *                 \c 192 or \c 256.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits );
+
+/**
+ * \brief          Perform a CAMELLIA key schedule operation for decryption.
+ *
+ * \param ctx      The CAMELLIA context to use. This must be initialized.
+ * \param key      The decryption key. This must be a readable buffer
+ *                 of size \p keybits Bits.
+ * \param keybits  The length of \p key in Bits. This must be either \c 128,
+ *                 \c 192 or \c 256.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits );
+
+/**
+ * \brief          Perform a CAMELLIA-ECB block encryption/decryption operation.
+ *
+ * \param ctx      The CAMELLIA context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ * \param input    The input block. This must be a readable buffer
+ *                 of size \c 16 Bytes.
+ * \param output   The output block. This must be a writable buffer
+ *                 of size \c 16 Bytes.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
+                    int mode,
+                    const unsigned char input[16],
+                    unsigned char output[16] );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/**
+ * \brief          Perform a CAMELLIA-CBC buffer encryption/decryption operation.
+ *
+ * \note           Upon exit, the content of the IV is updated so that you can
+ *                 call the function same function again on the following
+ *                 block(s) of data and get the same result as if it was
+ *                 encrypted in one call. This allows a "streaming" usage.
+ *                 If on the other hand you need to retain the contents of the
+ *                 IV, you should either save it manually or use the cipher
+ *                 module instead.
+ *
+ * \param ctx      The CAMELLIA context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ * \param length   The length in Bytes of the input data \p input.
+ *                 This must be a multiple of \c 16 Bytes.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of length \c 16 Bytes. It is updated to allow streaming
+ *                 use as explained above.
+ * \param input    The buffer holding the input data. This must point to a
+ *                 readable buffer of length \p length Bytes.
+ * \param output   The buffer holding the output data. This must point to a
+ *                 writable buffer of length \p length Bytes.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[16],
+                    const unsigned char *input,
+                    unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/**
+ * \brief          Perform a CAMELLIA-CFB128 buffer encryption/decryption
+ *                 operation.
+ *
+ * \note           Due to the nature of CFB mode, you should use the same
+ *                 key for both encryption and decryption. In particular, calls
+ *                 to this function should be preceded by a key-schedule via
+ *                 mbedtls_camellia_setkey_enc() regardless of whether \p mode
+ *                 is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ *
+ * \note           Upon exit, the content of the IV is updated so that you can
+ *                 call the function same function again on the following
+ *                 block(s) of data and get the same result as if it was
+ *                 encrypted in one call. This allows a "streaming" usage.
+ *                 If on the other hand you need to retain the contents of the
+ *                 IV, you should either save it manually or use the cipher
+ *                 module instead.
+ *
+ * \param ctx      The CAMELLIA context to use. This must be initialized
+ *                 and bound to a key.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ * \param length   The length of the input data \p input. Any value is allowed.
+ * \param iv_off   The current offset in the IV. This must be smaller
+ *                 than \c 16 Bytes. It is updated after this call to allow
+ *                 the aforementioned streaming usage.
+ * \param iv       The initialization vector. This must be a read/write buffer
+ *                 of length \c 16 Bytes. It is updated after this call to
+ *                 allow the aforementioned streaming usage.
+ * \param input    The buffer holding the input data. This must be a readable
+ *                 buffer of size \p length Bytes.
+ * \param output   The buffer to hold the output data. This must be a writable
+ *                 buffer of length \p length Bytes.
+ *
+ * \return         \c 0 if successful.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
+                       int mode,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/**
+ * \brief      Perform a CAMELLIA-CTR buffer encryption/decryption operation.
+ *
+ * *note       Due to the nature of CTR mode, you should use the same
+ *             key for both encryption and decryption. In particular, calls
+ *             to this function should be preceded by a key-schedule via
+ *             mbedtls_camellia_setkey_enc() regardless of whether \p mode
+ *             is #MBEDTLS_CAMELLIA_ENCRYPT or #MBEDTLS_CAMELLIA_DECRYPT.
+ *
+ * \warning    You must never reuse a nonce value with the same key. Doing so
+ *             would void the encryption for the two messages encrypted with
+ *             the same nonce and key.
+ *
+ *             There are two common strategies for managing nonces with CTR:
+ *
+ *             1. You can handle everything as a single message processed over
+ *             successive calls to this function. In that case, you want to
+ *             set \p nonce_counter and \p nc_off to 0 for the first call, and
+ *             then preserve the values of \p nonce_counter, \p nc_off and \p
+ *             stream_block across calls to this function as they will be
+ *             updated by this function.
+ *
+ *             With this strategy, you must not encrypt more than 2**128
+ *             blocks of data with the same key.
+ *
+ *             2. You can encrypt separate messages by dividing the \p
+ *             nonce_counter buffer in two areas: the first one used for a
+ *             per-message nonce, handled by yourself, and the second one
+ *             updated by this function internally.
+ *
+ *             For example, you might reserve the first \c 12 Bytes for the
+ *             per-message nonce, and the last \c 4 Bytes for internal use.
+ *             In that case, before calling this function on a new message you
+ *             need to set the first \c 12 Bytes of \p nonce_counter to your
+ *             chosen nonce value, the last four to \c 0, and \p nc_off to \c 0
+ *             (which will cause \p stream_block to be ignored). That way, you
+ *             can encrypt at most \c 2**96 messages of up to \c 2**32 blocks
+ *             each  with the same key.
+ *
+ *             The per-message nonce (or information sufficient to reconstruct
+ *             it) needs to be communicated with the ciphertext and must be
+ *             unique. The recommended way to ensure uniqueness is to use a
+ *             message counter. An alternative is to generate random nonces,
+ *             but this limits the number of messages that can be securely
+ *             encrypted: for example, with 96-bit random nonces, you should
+ *             not encrypt more than 2**32 messages with the same key.
+ *
+ *             Note that for both stategies, sizes are measured in blocks and
+ *             that a CAMELLIA block is \c 16 Bytes.
+ *
+ * \warning    Upon return, \p stream_block contains sensitive data. Its
+ *             content must not be written to insecure storage and should be
+ *             securely discarded as soon as it's no longer needed.
+ *
+ * \param ctx           The CAMELLIA context to use. This must be initialized
+ *                      and bound to a key.
+ * \param length        The length of the input data \p input in Bytes.
+ *                      Any value is allowed.
+ * \param nc_off        The offset in the current \p stream_block (for resuming
+ *                      within current cipher stream). The offset pointer to
+ *                      should be \c 0 at the start of a stream. It is updated
+ *                      at the end of this call.
+ * \param nonce_counter The 128-bit nonce and counter. This must be a read/write
+ *                      buffer of length \c 16 Bytes.
+ * \param stream_block  The saved stream-block for resuming. This must be a
+ *                      read/write buffer of length \c 16 Bytes.
+ * \param input         The input data stream. This must be a readable buffer of
+ *                      size \p length Bytes.
+ * \param output        The output data stream. This must be a writable buffer
+ *                      of size \p length Bytes.
+ *
+ * \return              \c 0 if successful.
+ * \return              A negative error code on failure.
+ */
+int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
+                       size_t length,
+                       size_t *nc_off,
+                       unsigned char nonce_counter[16],
+                       unsigned char stream_block[16],
+                       const unsigned char *input,
+                       unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int mbedtls_camellia_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* camellia.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ccm.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ccm.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ccm.h	(revision 398)
@@ -0,0 +1,310 @@
+/**
+ * \file ccm.h
+ *
+ * \brief This file provides an API for the CCM authenticated encryption
+ *        mode for block ciphers.
+ *
+ * CCM combines Counter mode encryption with CBC-MAC authentication
+ * for 128-bit block ciphers.
+ *
+ * Input to CCM includes the following elements:
+ * <ul><li>Payload - data that is both authenticated and encrypted.</li>
+ * <li>Associated data (Adata) - data that is authenticated but not
+ * encrypted, For example, a header.</li>
+ * <li>Nonce - A unique value that is assigned to the payload and the
+ * associated data.</li></ul>
+ *
+ * Definition of CCM:
+ * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
+ * RFC 3610 "Counter with CBC-MAC (CCM)"
+ *
+ * Related:
+ * RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
+ *
+ * Definition of CCM*:
+ * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks
+ * Integer representation is fixed most-significant-octet-first order and
+ * the representation of octets is most-significant-bit-first order. This is
+ * consistent with RFC 3610.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_CCM_H
+#define MBEDTLS_CCM_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "cipher.h"
+
+#define MBEDTLS_ERR_CCM_BAD_INPUT       -0x000D /**< Bad input parameters to the function. */
+#define MBEDTLS_ERR_CCM_AUTH_FAILED     -0x000F /**< Authenticated decryption failed. */
+
+/* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_CCM_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief    The CCM context-type definition. The CCM context is passed
+ *           to the APIs called.
+ */
+typedef struct mbedtls_ccm_context
+{
+    mbedtls_cipher_context_t cipher_ctx;    /*!< The cipher context used. */
+}
+mbedtls_ccm_context;
+
+#else  /* MBEDTLS_CCM_ALT */
+#include "ccm_alt.h"
+#endif /* MBEDTLS_CCM_ALT */
+
+/**
+ * \brief           This function initializes the specified CCM context,
+ *                  to make references valid, and prepare the context
+ *                  for mbedtls_ccm_setkey() or mbedtls_ccm_free().
+ *
+ * \param ctx       The CCM context to initialize. This must not be \c NULL.
+ */
+void mbedtls_ccm_init( mbedtls_ccm_context *ctx );
+
+/**
+ * \brief           This function initializes the CCM context set in the
+ *                  \p ctx parameter and sets the encryption key.
+ *
+ * \param ctx       The CCM context to initialize. This must be an initialized
+ *                  context.
+ * \param cipher    The 128-bit block cipher to use.
+ * \param key       The encryption key. This must not be \c NULL.
+ * \param keybits   The key size in bits. This must be acceptable by the cipher.
+ *
+ * \return          \c 0 on success.
+ * \return          A CCM or cipher-specific error code on failure.
+ */
+int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
+                        mbedtls_cipher_id_t cipher,
+                        const unsigned char *key,
+                        unsigned int keybits );
+
+/**
+ * \brief   This function releases and clears the specified CCM context
+ *          and underlying cipher sub-context.
+ *
+ * \param ctx       The CCM context to clear. If this is \c NULL, the function
+ *                  has no effect. Otherwise, this must be initialized.
+ */
+void mbedtls_ccm_free( mbedtls_ccm_context *ctx );
+
+/**
+ * \brief           This function encrypts a buffer using CCM.
+ *
+ * \note            The tag is written to a separate buffer. To concatenate
+ *                  the \p tag with the \p output, as done in <em>RFC-3610:
+ *                  Counter with CBC-MAC (CCM)</em>, use
+ *                  \p tag = \p output + \p length, and make sure that the
+ *                  output buffer is at least \p length + \p tag_len wide.
+ *
+ * \param ctx       The CCM context to use for encryption. This must be
+ *                  initialized and bound to a key.
+ * \param length    The length of the input data in Bytes.
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
+ * \param add       The additional data field. If \p add_len is greater than
+ *                  zero, \p add must be a readable buffer of at least that
+ *                  length.
+ * \param add_len   The length of additional data in Bytes.
+ *                  This must be less than `2^16 - 2^8`.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the authentication field to generate in Bytes:
+ *                  4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \return          \c 0 on success.
+ * \return          A CCM or cipher-specific error code on failure.
+ */
+int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *add, size_t add_len,
+                         const unsigned char *input, unsigned char *output,
+                         unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief           This function encrypts a buffer using CCM*.
+ *
+ * \note            The tag is written to a separate buffer. To concatenate
+ *                  the \p tag with the \p output, as done in <em>RFC-3610:
+ *                  Counter with CBC-MAC (CCM)</em>, use
+ *                  \p tag = \p output + \p length, and make sure that the
+ *                  output buffer is at least \p length + \p tag_len wide.
+ *
+ * \note            When using this function in a variable tag length context,
+ *                  the tag length has to be encoded into the \p iv passed to
+ *                  this function.
+ *
+ * \param ctx       The CCM context to use for encryption. This must be
+ *                  initialized and bound to a key.
+ * \param length    The length of the input data in Bytes.
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
+ * \param add       The additional data field. This must be a readable buffer of
+ *                  at least \p add_len Bytes.
+ * \param add_len   The length of additional data in Bytes.
+ *                  This must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the authentication field to generate in Bytes:
+ *                  0, 4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \warning         Passing \c 0 as \p tag_len means that the message is no
+ *                  longer authenticated.
+ *
+ * \return          \c 0 on success.
+ * \return          A CCM or cipher-specific error code on failure.
+ */
+int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *add, size_t add_len,
+                         const unsigned char *input, unsigned char *output,
+                         unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief           This function performs a CCM authenticated decryption of a
+ *                  buffer.
+ *
+ * \param ctx       The CCM context to use for decryption. This must be
+ *                  initialized and bound to a key.
+ * \param length    The length of the input data in Bytes.
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
+ * \param add       The additional data field. This must be a readable buffer
+ *                  of at least that \p add_len Bytes..
+ * \param add_len   The length of additional data in Bytes.
+ *                  This must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the authentication field to generate in Bytes:
+ *                  4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \return          \c 0 on success. This indicates that the message is authentic.
+ * \return          #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
+ * \return          A cipher-specific error code on calculation failure.
+ */
+int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
+                      const unsigned char *iv, size_t iv_len,
+                      const unsigned char *add, size_t add_len,
+                      const unsigned char *input, unsigned char *output,
+                      const unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief           This function performs a CCM* authenticated decryption of a
+ *                  buffer.
+ *
+ * \note            When using this function in a variable tag length context,
+ *                  the tag length has to be decoded from \p iv and passed to
+ *                  this function as \p tag_len. (\p tag needs to be adjusted
+ *                  accordingly.)
+ *
+ * \param ctx       The CCM context to use for decryption. This must be
+ *                  initialized and bound to a key.
+ * \param length    The length of the input data in Bytes.
+ * \param iv        The initialization vector (nonce). This must be a readable
+ *                  buffer of at least \p iv_len Bytes.
+ * \param iv_len    The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
+ *                  or 13. The length L of the message length field is
+ *                  15 - \p iv_len.
+ * \param add       The additional data field. This must be a readable buffer of
+ *                  at least that \p add_len Bytes.
+ * \param add_len   The length of additional data in Bytes.
+ *                  This must be less than 2^16 - 2^8.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, \p input must be a readable buffer of at least
+ *                  that length.
+ * \param output    The buffer holding the output data. If \p length is greater
+ *                  than zero, \p output must be a writable buffer of at least
+ *                  that length.
+ * \param tag       The buffer holding the authentication field. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the authentication field in Bytes.
+ *                  0, 4, 6, 8, 10, 12, 14 or 16.
+ *
+ * \warning         Passing \c 0 as \p tag_len means that the message is nos
+ *                  longer authenticated.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match.
+ * \return          A cipher-specific error code on calculation failure.
+ */
+int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
+                      const unsigned char *iv, size_t iv_len,
+                      const unsigned char *add, size_t add_len,
+                      const unsigned char *input, unsigned char *output,
+                      const unsigned char *tag, size_t tag_len );
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+/**
+ * \brief          The CCM checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_ccm_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CCM_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/certs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/certs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/certs.h	(revision 398)
@@ -0,0 +1,106 @@
+/**
+ * \file certs.h
+ *
+ * \brief Sample certificates and DHM parameters for testing
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_CERTS_H
+#define MBEDTLS_CERTS_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+/* Concatenation of all CA certificates in PEM format if available */
+extern const char   mbedtls_test_cas_pem[];
+extern const size_t mbedtls_test_cas_pem_len;
+#endif
+
+/* List of all CA certificates, terminated by NULL */
+extern const char * mbedtls_test_cas[];
+extern const size_t mbedtls_test_cas_len[];
+
+/*
+ * Convenience for users who just want a certificate:
+ * RSA by default, or ECDSA if RSA is not available
+ */
+extern const char * mbedtls_test_ca_crt;
+extern const size_t mbedtls_test_ca_crt_len;
+extern const char * mbedtls_test_ca_key;
+extern const size_t mbedtls_test_ca_key_len;
+extern const char * mbedtls_test_ca_pwd;
+extern const size_t mbedtls_test_ca_pwd_len;
+extern const char * mbedtls_test_srv_crt;
+extern const size_t mbedtls_test_srv_crt_len;
+extern const char * mbedtls_test_srv_key;
+extern const size_t mbedtls_test_srv_key_len;
+extern const char * mbedtls_test_cli_crt;
+extern const size_t mbedtls_test_cli_crt_len;
+extern const char * mbedtls_test_cli_key;
+extern const size_t mbedtls_test_cli_key_len;
+
+#if defined(MBEDTLS_ECDSA_C)
+extern const char   mbedtls_test_ca_crt_ec[];
+extern const size_t mbedtls_test_ca_crt_ec_len;
+extern const char   mbedtls_test_ca_key_ec[];
+extern const size_t mbedtls_test_ca_key_ec_len;
+extern const char   mbedtls_test_ca_pwd_ec[];
+extern const size_t mbedtls_test_ca_pwd_ec_len;
+extern const char   mbedtls_test_srv_crt_ec[];
+extern const size_t mbedtls_test_srv_crt_ec_len;
+extern const char   mbedtls_test_srv_key_ec[];
+extern const size_t mbedtls_test_srv_key_ec_len;
+extern const char   mbedtls_test_cli_crt_ec[];
+extern const size_t mbedtls_test_cli_crt_ec_len;
+extern const char   mbedtls_test_cli_key_ec[];
+extern const size_t mbedtls_test_cli_key_ec_len;
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+extern const char   mbedtls_test_ca_crt_rsa[];
+extern const size_t mbedtls_test_ca_crt_rsa_len;
+extern const char   mbedtls_test_ca_key_rsa[];
+extern const size_t mbedtls_test_ca_key_rsa_len;
+extern const char   mbedtls_test_ca_pwd_rsa[];
+extern const size_t mbedtls_test_ca_pwd_rsa_len;
+extern const char   mbedtls_test_srv_crt_rsa[];
+extern const size_t mbedtls_test_srv_crt_rsa_len;
+extern const char   mbedtls_test_srv_key_rsa[];
+extern const size_t mbedtls_test_srv_key_rsa_len;
+extern const char   mbedtls_test_cli_crt_rsa[];
+extern const size_t mbedtls_test_cli_crt_rsa_len;
+extern const char   mbedtls_test_cli_key_rsa[];
+extern const size_t mbedtls_test_cli_key_rsa_len;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* certs.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/chacha20.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/chacha20.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/chacha20.h	(revision 398)
@@ -0,0 +1,226 @@
+/**
+ * \file chacha20.h
+ *
+ * \brief   This file contains ChaCha20 definitions and functions.
+ *
+ *          ChaCha20 is a stream cipher that can encrypt and decrypt
+ *          information. ChaCha was created by Daniel Bernstein as a variant of
+ *          its Salsa cipher https://cr.yp.to/chacha/chacha-20080128.pdf
+ *          ChaCha20 is the variant with 20 rounds, that was also standardized
+ *          in RFC 7539.
+ *
+ * \author Daniel King <damaki.gh@gmail.com>
+ */
+
+/*  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_CHACHA20_H
+#define MBEDTLS_CHACHA20_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA         -0x0051 /**< Invalid input parameter(s). */
+
+/* MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE is deprecated and should not be
+ * used. */
+#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE    -0x0053 /**< Feature not available. For example, s part of the API is not implemented. */
+
+/* MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED        -0x0055  /**< Chacha20 hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_CHACHA20_ALT)
+
+typedef struct mbedtls_chacha20_context
+{
+    uint32_t state[16];          /*! The state (before round operations). */
+    uint8_t  keystream8[64];     /*! Leftover keystream bytes. */
+    size_t keystream_bytes_used; /*! Number of keystream bytes already used. */
+}
+mbedtls_chacha20_context;
+
+#else  /* MBEDTLS_CHACHA20_ALT */
+#include "chacha20_alt.h"
+#endif /* MBEDTLS_CHACHA20_ALT */
+
+/**
+ * \brief           This function initializes the specified ChaCha20 context.
+ *
+ *                  It must be the first API called before using
+ *                  the context.
+ *
+ *                  It is usually followed by calls to
+ *                  \c mbedtls_chacha20_setkey() and
+ *                  \c mbedtls_chacha20_starts(), then one or more calls to
+ *                  to \c mbedtls_chacha20_update(), and finally to
+ *                  \c mbedtls_chacha20_free().
+ *
+ * \param ctx       The ChaCha20 context to initialize.
+ *                  This must not be \c NULL.
+ */
+void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx );
+
+/**
+ * \brief           This function releases and clears the specified
+ *                  ChaCha20 context.
+ *
+ * \param ctx       The ChaCha20 context to clear. This may be \c NULL,
+ *                  in which case this function is a no-op. If it is not
+ *                  \c NULL, it must point to an initialized context.
+ *
+ */
+void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx );
+
+/**
+ * \brief           This function sets the encryption/decryption key.
+ *
+ * \note            After using this function, you must also call
+ *                  \c mbedtls_chacha20_starts() to set a nonce before you
+ *                  start encrypting/decrypting data with
+ *                  \c mbedtls_chacha_update().
+ *
+ * \param ctx       The ChaCha20 context to which the key should be bound.
+ *                  It must be initialized.
+ * \param key       The encryption/decryption key. This must be \c 32 Bytes
+ *                  in length.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL.
+ */
+int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
+                             const unsigned char key[32] );
+
+/**
+ * \brief           This function sets the nonce and initial counter value.
+ *
+ * \note            A ChaCha20 context can be re-used with the same key by
+ *                  calling this function to change the nonce.
+ *
+ * \warning         You must never use the same nonce twice with the same key.
+ *                  This would void any confidentiality guarantees for the
+ *                  messages encrypted with the same nonce and key.
+ *
+ * \param ctx       The ChaCha20 context to which the nonce should be bound.
+ *                  It must be initialized and bound to a key.
+ * \param nonce     The nonce. This must be \c 12 Bytes in size.
+ * \param counter   The initial counter value. This is usually \c 0.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is
+ *                  NULL.
+ */
+int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
+                             const unsigned char nonce[12],
+                             uint32_t counter );
+
+/**
+ * \brief           This function encrypts or decrypts data.
+ *
+ *                  Since ChaCha20 is a stream cipher, the same operation is
+ *                  used for encrypting and decrypting data.
+ *
+ * \note            The \p input and \p output pointers must either be equal or
+ *                  point to non-overlapping buffers.
+ *
+ * \note            \c mbedtls_chacha20_setkey() and
+ *                  \c mbedtls_chacha20_starts() must be called at least once
+ *                  to setup the context before this function can be called.
+ *
+ * \note            This function can be called multiple times in a row in
+ *                  order to encrypt of decrypt data piecewise with the same
+ *                  key and nonce.
+ *
+ * \param ctx       The ChaCha20 context to use for encryption or decryption.
+ *                  It must be initialized and bound to a key and nonce.
+ * \param size      The length of the input data in Bytes.
+ * \param input     The buffer holding the input data.
+ *                  This pointer can be \c NULL if `size == 0`.
+ * \param output    The buffer holding the output data.
+ *                  This must be able to hold \p size Bytes.
+ *                  This pointer can be \c NULL if `size == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
+                             size_t size,
+                             const unsigned char *input,
+                             unsigned char *output );
+
+/**
+ * \brief           This function encrypts or decrypts data with ChaCha20 and
+ *                  the given key and nonce.
+ *
+ *                  Since ChaCha20 is a stream cipher, the same operation is
+ *                  used for encrypting and decrypting data.
+ *
+ * \warning         You must never use the same (key, nonce) pair more than
+ *                  once. This would void any confidentiality guarantees for
+ *                  the messages encrypted with the same nonce and key.
+ *
+ * \note            The \p input and \p output pointers must either be equal or
+ *                  point to non-overlapping buffers.
+ *
+ * \param key       The encryption/decryption key.
+ *                  This must be \c 32 Bytes in length.
+ * \param nonce     The nonce. This must be \c 12 Bytes in size.
+ * \param counter   The initial counter value. This is usually \c 0.
+ * \param size      The length of the input data in Bytes.
+ * \param input     The buffer holding the input data.
+ *                  This pointer can be \c NULL if `size == 0`.
+ * \param output    The buffer holding the output data.
+ *                  This must be able to hold \p size Bytes.
+ *                  This pointer can be \c NULL if `size == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_chacha20_crypt( const unsigned char key[32],
+                            const unsigned char nonce[12],
+                            uint32_t counter,
+                            size_t size,
+                            const unsigned char* input,
+                            unsigned char* output );
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief           The ChaCha20 checkup routine.
+ *
+ * \return          \c 0 on success.
+ * \return          \c 1 on failure.
+ */
+int mbedtls_chacha20_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CHACHA20_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/chachapoly.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/chachapoly.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/chachapoly.h	(revision 398)
@@ -0,0 +1,358 @@
+/**
+ * \file chachapoly.h
+ *
+ * \brief   This file contains the AEAD-ChaCha20-Poly1305 definitions and
+ *          functions.
+ *
+ *          ChaCha20-Poly1305 is an algorithm for Authenticated Encryption
+ *          with Associated Data (AEAD) that can be used to encrypt and
+ *          authenticate data. It is based on ChaCha20 and Poly1305 by Daniel
+ *          Bernstein and was standardized in RFC 7539.
+ *
+ * \author Daniel King <damaki.gh@gmail.com>
+ */
+
+/*  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_CHACHAPOLY_H
+#define MBEDTLS_CHACHAPOLY_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+/* for shared error codes */
+#include "poly1305.h"
+
+#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE            -0x0054 /**< The requested operation is not permitted in the current state. */
+#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED          -0x0056 /**< Authenticated decryption failed: data was not authentic. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+    MBEDTLS_CHACHAPOLY_ENCRYPT,     /**< The mode value for performing encryption. */
+    MBEDTLS_CHACHAPOLY_DECRYPT      /**< The mode value for performing decryption. */
+}
+mbedtls_chachapoly_mode_t;
+
+#if !defined(MBEDTLS_CHACHAPOLY_ALT)
+
+#include "chacha20.h"
+
+typedef struct mbedtls_chachapoly_context
+{
+    mbedtls_chacha20_context chacha20_ctx;  /**< The ChaCha20 context. */
+    mbedtls_poly1305_context poly1305_ctx;  /**< The Poly1305 context. */
+    uint64_t aad_len;                       /**< The length (bytes) of the Additional Authenticated Data. */
+    uint64_t ciphertext_len;                /**< The length (bytes) of the ciphertext. */
+    int state;                              /**< The current state of the context. */
+    mbedtls_chachapoly_mode_t mode;         /**< Cipher mode (encrypt or decrypt). */
+}
+mbedtls_chachapoly_context;
+
+#else /* !MBEDTLS_CHACHAPOLY_ALT */
+#include "chachapoly_alt.h"
+#endif /* !MBEDTLS_CHACHAPOLY_ALT */
+
+/**
+ * \brief           This function initializes the specified ChaCha20-Poly1305 context.
+ *
+ *                  It must be the first API called before using
+ *                  the context. It must be followed by a call to
+ *                  \c mbedtls_chachapoly_setkey() before any operation can be
+ *                  done, and to \c mbedtls_chachapoly_free() once all
+ *                  operations with that context have been finished.
+ *
+ *                  In order to encrypt or decrypt full messages at once, for
+ *                  each message you should make a single call to
+ *                  \c mbedtls_chachapoly_crypt_and_tag() or
+ *                  \c mbedtls_chachapoly_auth_decrypt().
+ *
+ *                  In order to encrypt messages piecewise, for each
+ *                  message you should make a call to
+ *                  \c mbedtls_chachapoly_starts(), then 0 or more calls to
+ *                  \c mbedtls_chachapoly_update_aad(), then 0 or more calls to
+ *                  \c mbedtls_chachapoly_update(), then one call to
+ *                  \c mbedtls_chachapoly_finish().
+ *
+ * \warning         Decryption with the piecewise API is discouraged! Always
+ *                  use \c mbedtls_chachapoly_auth_decrypt() when possible!
+ *
+ *                  If however this is not possible because the data is too
+ *                  large to fit in memory, you need to:
+ *
+ *                  - call \c mbedtls_chachapoly_starts() and (if needed)
+ *                  \c mbedtls_chachapoly_update_aad() as above,
+ *                  - call \c mbedtls_chachapoly_update() multiple times and
+ *                  ensure its output (the plaintext) is NOT used in any other
+ *                  way than placing it in temporary storage at this point,
+ *                  - call \c mbedtls_chachapoly_finish() to compute the
+ *                  authentication tag and compared it in constant time to the
+ *                  tag received with the ciphertext.
+ *
+ *                  If the tags are not equal, you must immediately discard
+ *                  all previous outputs of \c mbedtls_chachapoly_update(),
+ *                  otherwise you can now safely use the plaintext.
+ *
+ * \param ctx       The ChachaPoly context to initialize. Must not be \c NULL.
+ */
+void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx );
+
+/**
+ * \brief           This function releases and clears the specified
+ *                  ChaCha20-Poly1305 context.
+ *
+ * \param ctx       The ChachaPoly context to clear. This may be \c NULL, in which
+ *                  case this function is a no-op.
+ */
+void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx );
+
+/**
+ * \brief           This function sets the ChaCha20-Poly1305
+ *                  symmetric encryption key.
+ *
+ * \param ctx       The ChaCha20-Poly1305 context to which the key should be
+ *                  bound. This must be initialized.
+ * \param key       The \c 256 Bit (\c 32 Bytes) key.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
+                               const unsigned char key[32] );
+
+/**
+ * \brief           This function starts a ChaCha20-Poly1305 encryption or
+ *                  decryption operation.
+ *
+ * \warning         You must never use the same nonce twice with the same key.
+ *                  This would void any confidentiality and authenticity
+ *                  guarantees for the messages encrypted with the same nonce
+ *                  and key.
+ *
+ * \note            If the context is being used for AAD only (no data to
+ *                  encrypt or decrypt) then \p mode can be set to any value.
+ *
+ * \warning         Decryption with the piecewise API is discouraged, see the
+ *                  warning on \c mbedtls_chachapoly_init().
+ *
+ * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
+ *                  and bound to a key.
+ * \param nonce     The nonce/IV to use for the message.
+ *                  This must be a redable buffer of length \c 12 Bytes.
+ * \param mode      The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
+ *                  #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
+                               const unsigned char nonce[12],
+                               mbedtls_chachapoly_mode_t mode );
+
+/**
+ * \brief           This function feeds additional data to be authenticated
+ *                  into an ongoing ChaCha20-Poly1305 operation.
+ *
+ *                  The Additional Authenticated Data (AAD), also called
+ *                  Associated Data (AD) is only authenticated but not
+ *                  encrypted nor included in the encrypted output. It is
+ *                  usually transmitted separately from the ciphertext or
+ *                  computed locally by each party.
+ *
+ * \note            This function is called before data is encrypted/decrypted.
+ *                  I.e. call this function to process the AAD before calling
+ *                  \c mbedtls_chachapoly_update().
+ *
+ *                  You may call this function multiple times to process
+ *                  an arbitrary amount of AAD. It is permitted to call
+ *                  this function 0 times, if no AAD is used.
+ *
+ *                  This function cannot be called any more if data has
+ *                  been processed by \c mbedtls_chachapoly_update(),
+ *                  or if the context has been finished.
+ *
+ * \warning         Decryption with the piecewise API is discouraged, see the
+ *                  warning on \c mbedtls_chachapoly_init().
+ *
+ * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
+ *                  and bound to a key.
+ * \param aad_len   The length in Bytes of the AAD. The length has no
+ *                  restrictions.
+ * \param aad       Buffer containing the AAD.
+ *                  This pointer can be \c NULL if `aad_len == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
+ *                  if \p ctx or \p aad are NULL.
+ * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
+ *                  if the operations has not been started or has been
+ *                  finished, or if the AAD has been finished.
+ */
+int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
+                                   const unsigned char *aad,
+                                   size_t aad_len );
+
+/**
+ * \brief           Thus function feeds data to be encrypted or decrypted
+ *                  into an on-going ChaCha20-Poly1305
+ *                  operation.
+ *
+ *                  The direction (encryption or decryption) depends on the
+ *                  mode that was given when calling
+ *                  \c mbedtls_chachapoly_starts().
+ *
+ *                  You may call this function multiple times to process
+ *                  an arbitrary amount of data. It is permitted to call
+ *                  this function 0 times, if no data is to be encrypted
+ *                  or decrypted.
+ *
+ * \warning         Decryption with the piecewise API is discouraged, see the
+ *                  warning on \c mbedtls_chachapoly_init().
+ *
+ * \param ctx       The ChaCha20-Poly1305 context to use. This must be initialized.
+ * \param len       The length (in bytes) of the data to encrypt or decrypt.
+ * \param input     The buffer containing the data to encrypt or decrypt.
+ *                  This pointer can be \c NULL if `len == 0`.
+ * \param output    The buffer to where the encrypted or decrypted data is
+ *                  written. This must be able to hold \p len bytes.
+ *                  This pointer can be \c NULL if `len == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
+ *                  if the operation has not been started or has been
+ *                  finished.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
+                               size_t len,
+                               const unsigned char *input,
+                               unsigned char *output );
+
+/**
+ * \brief           This function finished the ChaCha20-Poly1305 operation and
+ *                  generates the MAC (authentication tag).
+ *
+ * \param ctx       The ChaCha20-Poly1305 context to use. This must be initialized.
+ * \param mac       The buffer to where the 128-bit (16 bytes) MAC is written.
+ *
+ * \warning         Decryption with the piecewise API is discouraged, see the
+ *                  warning on \c mbedtls_chachapoly_init().
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
+ *                  if the operation has not been started or has been
+ *                  finished.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
+                               unsigned char mac[16] );
+
+/**
+ * \brief           This function performs a complete ChaCha20-Poly1305
+ *                  authenticated encryption with the previously-set key.
+ *
+ * \note            Before using this function, you must set the key with
+ *                  \c mbedtls_chachapoly_setkey().
+ *
+ * \warning         You must never use the same nonce twice with the same key.
+ *                  This would void any confidentiality and authenticity
+ *                  guarantees for the messages encrypted with the same nonce
+ *                  and key.
+ *
+ * \param ctx       The ChaCha20-Poly1305 context to use (holds the key).
+ *                  This must be initialized.
+ * \param length    The length (in bytes) of the data to encrypt or decrypt.
+ * \param nonce     The 96-bit (12 bytes) nonce/IV to use.
+ * \param aad       The buffer containing the additional authenticated
+ *                  data (AAD). This pointer can be \c NULL if `aad_len == 0`.
+ * \param aad_len   The length (in bytes) of the AAD data to process.
+ * \param input     The buffer containing the data to encrypt or decrypt.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ * \param output    The buffer to where the encrypted or decrypted data
+ *                  is written. This pointer can be \c NULL if `ilen == 0`.
+ * \param tag       The buffer to where the computed 128-bit (16 bytes) MAC
+ *                  is written. This must not be \c NULL.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
+                                        size_t length,
+                                        const unsigned char nonce[12],
+                                        const unsigned char *aad,
+                                        size_t aad_len,
+                                        const unsigned char *input,
+                                        unsigned char *output,
+                                        unsigned char tag[16] );
+
+/**
+ * \brief           This function performs a complete ChaCha20-Poly1305
+ *                  authenticated decryption with the previously-set key.
+ *
+ * \note            Before using this function, you must set the key with
+ *                  \c mbedtls_chachapoly_setkey().
+ *
+ * \param ctx       The ChaCha20-Poly1305 context to use (holds the key).
+ * \param length    The length (in Bytes) of the data to decrypt.
+ * \param nonce     The \c 96 Bit (\c 12 bytes) nonce/IV to use.
+ * \param aad       The buffer containing the additional authenticated data (AAD).
+ *                  This pointer can be \c NULL if `aad_len == 0`.
+ * \param aad_len   The length (in bytes) of the AAD data to process.
+ * \param tag       The buffer holding the authentication tag.
+ *                  This must be a readable buffer of length \c 16 Bytes.
+ * \param input     The buffer containing the data to decrypt.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ * \param output    The buffer to where the decrypted data is written.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED
+ *                  if the data was not authentic.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
+                                     size_t length,
+                                     const unsigned char nonce[12],
+                                     const unsigned char *aad,
+                                     size_t aad_len,
+                                     const unsigned char tag[16],
+                                     const unsigned char *input,
+                                     unsigned char *output );
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief           The ChaCha20-Poly1305 checkup routine.
+ *
+ * \return          \c 0 on success.
+ * \return          \c 1 on failure.
+ */
+int mbedtls_chachapoly_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CHACHAPOLY_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/check_config.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/check_config.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/check_config.h	(revision 398)
@@ -0,0 +1,698 @@
+/**
+ * \file check_config.h
+ *
+ * \brief Consistency checks for configuration options
+ */
+/*
+ *  Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * It is recommended to include this file from your config.h
+ * in order to catch dependency issues early.
+ */
+
+#ifndef MBEDTLS_CHECK_CONFIG_H
+#define MBEDTLS_CHECK_CONFIG_H
+
+/*
+ * We assume CHAR_BIT is 8 in many places. In practice, this is true on our
+ * target platforms, so not an issue, but let's just be extra sure.
+ */
+#include <limits.h>
+#if CHAR_BIT != 8
+#error "mbed TLS requires a platform with 8-bit chars"
+#endif
+
+#if defined(_WIN32)
+#if !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_C is required on Windows"
+#endif
+
+/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
+ * it would confuse config.pl. */
+#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
+    !defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
+#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+#endif
+#endif /* _WIN32 */
+
+#if defined(TARGET_LIKE_MBED) && \
+    ( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) )
+#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS"
+#endif
+
+#if defined(MBEDTLS_DEPRECATED_WARNING) && \
+    !defined(__GNUC__) && !defined(__clang__)
+#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang"
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME)
+#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense"
+#endif
+
+#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM)
+#error "MBEDTLS_AESNI_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C)
+#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C)
+#error "MBEDTLS_DHM_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) && !defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_CMAC_C) && \
+    !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C)
+#error "MBEDTLS_CMAC_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_NIST_KW_C) && \
+    ( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) )
+#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
+#error "MBEDTLS_ECDH_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECDSA_C) &&            \
+    ( !defined(MBEDTLS_ECP_C) ||           \
+      !defined(MBEDTLS_ASN1_PARSE_C) ||    \
+      !defined(MBEDTLS_ASN1_WRITE_C) )
+#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECJPAKE_C) &&           \
+    ( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) )
+#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)           && \
+    ( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
+      defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)     || \
+      defined(MBEDTLS_ECDSA_SIGN_ALT)          || \
+      defined(MBEDTLS_ECDSA_VERIFY_ALT)        || \
+      defined(MBEDTLS_ECDSA_GENKEY_ALT)        || \
+      defined(MBEDTLS_ECP_INTERNAL_ALT)        || \
+      defined(MBEDTLS_ECP_ALT) )
+#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation"
+#endif
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
+#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || (   \
+    !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) &&                  \
+    !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) &&                  \
+    !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) &&                  \
+    !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) &&                  \
+    !defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) &&                  \
+    !defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)   &&                  \
+    !defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)   &&                  \
+    !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)   &&                  \
+    !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) &&                  \
+    !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) &&                  \
+    !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) )
+#error "MBEDTLS_ECP_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
+#error "MBEDTLS_PK_PARSE_C defined, but not all prerequesites"
+#endif
+
+#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) &&      \
+                                    !defined(MBEDTLS_SHA256_C))
+#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites"
+#endif
+#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) &&         \
+    defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64)
+#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
+#endif
+#if defined(MBEDTLS_ENTROPY_C) &&                                            \
+    ( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \
+    && defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32)
+#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high"
+#endif
+#if defined(MBEDTLS_ENTROPY_C) && \
+    defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C)
+#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
+    ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
+#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"
+#endif
+#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
+     ( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \
+    defined(MBEDTLS_HAVEGE_C) )
+#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too"
+#endif
+
+#if defined(MBEDTLS_GCM_C) && (                                        \
+        !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
+#error "MBEDTLS_GCM_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
+#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
+#error "MBEDTLS_ECP_ADD_MIXED_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
+#error "MBEDTLS_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
+#error "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
+#error "MBEDTLS_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
+#error "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
+#error "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
+#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C)
+#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C)
+#error "MBEDTLS_HKDF_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C)
+#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) &&                 \
+    ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
+#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) &&                 \
+    ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
+#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C)
+#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) &&                     \
+    !defined(MBEDTLS_ECDH_C)
+#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) &&                   \
+    ( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) ||           \
+      !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
+#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) &&                 \
+    ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) ||          \
+      !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) )
+#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) &&                 \
+    ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) ||          \
+      !defined(MBEDTLS_X509_CRT_PARSE_C) )
+#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) &&                   \
+    ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
+      !defined(MBEDTLS_PKCS1_V15) )
+#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) &&                       \
+    ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
+      !defined(MBEDTLS_PKCS1_V15) )
+#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) &&                    \
+    ( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) ||      \
+      !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
+#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) &&                          \
+    ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
+#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
+#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C)
+#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C)
+#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PK_C) && \
+    ( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) )
+#error "MBEDTLS_PK_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C)
+#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C)
+#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C)
+#error "MBEDTLS_PKCS11_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\
+        defined(MBEDTLS_PLATFORM_EXIT_ALT) )
+#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\
+    ( !defined(MBEDTLS_PLATFORM_C) ||\
+        !defined(MBEDTLS_HAVE_TIME) )
+#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\
+    ( !defined(MBEDTLS_PLATFORM_C) ||\
+        !defined(MBEDTLS_HAVE_TIME) )
+#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
+    ( !defined(MBEDTLS_PLATFORM_C) ||\
+        !defined(MBEDTLS_HAVE_TIME) )
+#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\
+        defined(MBEDTLS_PLATFORM_TIME_ALT) )
+#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\
+        defined(MBEDTLS_PLATFORM_TIME_ALT) )
+#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\
+        defined(MBEDTLS_PLATFORM_FPRINTF_ALT) )
+#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
+    ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
+#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\
+    defined(MBEDTLS_PLATFORM_STD_FREE)
+#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
+#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
+    ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
+#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\
+    defined(MBEDTLS_PLATFORM_STD_CALLOC)
+#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO)
+#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\
+        defined(MBEDTLS_PLATFORM_PRINTF_ALT) )
+#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C)
+#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\
+        defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) )
+#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\
+    !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
+#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
+#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY)
+#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY)
+#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\
+    !defined(MBEDTLS_PLATFORM_EXIT_ALT)
+#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\
+    ( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\
+        !defined(MBEDTLS_HAVE_TIME) )
+#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\
+    !defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
+#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\
+    !defined(MBEDTLS_PLATFORM_PRINTF_ALT)
+#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\
+    !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
+#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\
+    ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) )
+#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\
+    !defined(MBEDTLS_ENTROPY_NV_SEED)
+#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\
+    !defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\
+    !defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\
+      defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
+#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\
+    ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\
+      defined(MBEDTLS_PLATFORM_NV_SEED_ALT) )
+#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
+#endif
+
+#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) ||         \
+    !defined(MBEDTLS_OID_C) )
+#error "MBEDTLS_RSA_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) &&         \
+    !defined(MBEDTLS_PKCS1_V15) )
+#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled"
+#endif
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) &&                        \
+    ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) )
+#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) ||     \
+    !defined(MBEDTLS_SHA1_C) )
+#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) ||     \
+    !defined(MBEDTLS_SHA1_C) )
+#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) ||     \
+    !defined(MBEDTLS_SHA1_C) )
+#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) &&     \
+    !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) )
+#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)     && \
+    !defined(MBEDTLS_SSL_PROTO_TLS1_1)  && \
+    !defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C)
+#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) ||     \
+    !defined(MBEDTLS_MD_C) )
+#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C)
+#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \
+    !defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
+    !defined(MBEDTLS_SSL_PROTO_TLS1_2))
+#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1))
+#error "Illegal protocol selection"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1))
+#error "Illegal protocol selection"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    !defined(MBEDTLS_SSL_PROTO_TLS1_1)))
+#error "Illegal protocol selection"
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS)
+#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY  defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \
+    !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
+#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE  defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) &&                              \
+    ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
+#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY  defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) &&                              \
+    ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
+#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT  defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) &&   \
+    !defined(MBEDTLS_SSL_PROTO_TLS1)   &&      \
+    !defined(MBEDTLS_SSL_PROTO_TLS1_1) &&      \
+    !defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites"
+#endif
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
+    !defined(MBEDTLS_SSL_PROTO_TLS1)   &&          \
+    !defined(MBEDTLS_SSL_PROTO_TLS1_1) &&          \
+    !defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites"
+#endif
+
+#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C)
+#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \
+    !defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1)
+#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \
+        !defined(MBEDTLS_X509_CRT_PARSE_C)
+#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
+#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites"
+#endif
+#define MBEDTLS_THREADING_IMPL
+#endif
+
+#if defined(MBEDTLS_THREADING_ALT)
+#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
+#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
+#endif
+#define MBEDTLS_THREADING_IMPL
+#endif
+
+#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL)
+#error "MBEDTLS_THREADING_C defined, single threading implementation required"
+#endif
+#undef MBEDTLS_THREADING_IMPL
+
+#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
+#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) ||  \
+    !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) ||      \
+    !defined(MBEDTLS_PK_PARSE_C) )
+#error "MBEDTLS_X509_USE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) ||  \
+    !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) ||       \
+    !defined(MBEDTLS_PK_WRITE_C) )
+#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
+#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
+#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
+#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
+#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) )
+#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64)
+#error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously"
+#endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */
+
+#if ( defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64) ) && \
+    defined(MBEDTLS_HAVE_ASM)
+#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously"
+#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */
+
+/*
+ * Avoid warning from -pedantic. This is a convenient place for this
+ * workaround since this is included by every single file before the
+ * #if defined(MBEDTLS_xxx_C) that results in emtpy translation units.
+ */
+typedef int mbedtls_iso_c_forbids_empty_translation_units;
+
+#endif /* MBEDTLS_CHECK_CONFIG_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/cipher.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/cipher.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/cipher.h	(revision 398)
@@ -0,0 +1,872 @@
+/**
+ * \file cipher.h
+ *
+ * \brief This file contains an abstraction interface for use with the cipher
+ * primitives provided by the library. It provides a common interface to all of
+ * the available cipher operations.
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_CIPHER_H
+#define MBEDTLS_CIPHER_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include "platform_util.h"
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+#define MBEDTLS_CIPHER_MODE_AEAD
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#define MBEDTLS_CIPHER_MODE_WITH_PADDING
+#endif
+
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
+    defined(MBEDTLS_CHACHA20_C)
+#define MBEDTLS_CIPHER_MODE_STREAM
+#endif
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE  -0x6080  /**< The selected feature is not available. */
+#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA       -0x6100  /**< Bad input parameters. */
+#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED         -0x6180  /**< Failed to allocate memory. */
+#define MBEDTLS_ERR_CIPHER_INVALID_PADDING      -0x6200  /**< Input data contains invalid padding and is rejected. */
+#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED  -0x6280  /**< Decryption of block requires a full block. */
+#define MBEDTLS_ERR_CIPHER_AUTH_FAILED          -0x6300  /**< Authentication failed (for AEAD modes). */
+#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT      -0x6380  /**< The context is invalid. For example, because it was freed. */
+
+/* MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED      -0x6400  /**< Cipher hardware accelerator failed. */
+
+#define MBEDTLS_CIPHER_VARIABLE_IV_LEN     0x01    /**< Cipher accepts IVs of variable length. */
+#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN    0x02    /**< Cipher accepts keys of variable length. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief     Supported cipher types.
+ *
+ * \warning   RC4 and DES are considered weak ciphers and their use
+ *            constitutes a security risk. Arm recommends considering stronger
+ *            ciphers instead.
+ */
+typedef enum {
+    MBEDTLS_CIPHER_ID_NONE = 0,  /**< Placeholder to mark the end of cipher ID lists. */
+    MBEDTLS_CIPHER_ID_NULL,      /**< The identity cipher, treated as a stream cipher. */
+    MBEDTLS_CIPHER_ID_AES,       /**< The AES cipher. */
+    MBEDTLS_CIPHER_ID_DES,       /**< The DES cipher. */
+    MBEDTLS_CIPHER_ID_3DES,      /**< The Triple DES cipher. */
+    MBEDTLS_CIPHER_ID_CAMELLIA,  /**< The Camellia cipher. */
+    MBEDTLS_CIPHER_ID_BLOWFISH,  /**< The Blowfish cipher. */
+    MBEDTLS_CIPHER_ID_ARC4,      /**< The RC4 cipher. */
+    MBEDTLS_CIPHER_ID_ARIA,      /**< The Aria cipher. */
+    MBEDTLS_CIPHER_ID_CHACHA20,  /**< The ChaCha20 cipher. */
+} mbedtls_cipher_id_t;
+
+/**
+ * \brief     Supported {cipher type, cipher mode} pairs.
+ *
+ * \warning   RC4 and DES are considered weak ciphers and their use
+ *            constitutes a security risk. Arm recommends considering stronger
+ *            ciphers instead.
+ */
+typedef enum {
+    MBEDTLS_CIPHER_NONE = 0,             /**< Placeholder to mark the end of cipher-pair lists. */
+    MBEDTLS_CIPHER_NULL,                 /**< The identity stream cipher. */
+    MBEDTLS_CIPHER_AES_128_ECB,          /**< AES cipher with 128-bit ECB mode. */
+    MBEDTLS_CIPHER_AES_192_ECB,          /**< AES cipher with 192-bit ECB mode. */
+    MBEDTLS_CIPHER_AES_256_ECB,          /**< AES cipher with 256-bit ECB mode. */
+    MBEDTLS_CIPHER_AES_128_CBC,          /**< AES cipher with 128-bit CBC mode. */
+    MBEDTLS_CIPHER_AES_192_CBC,          /**< AES cipher with 192-bit CBC mode. */
+    MBEDTLS_CIPHER_AES_256_CBC,          /**< AES cipher with 256-bit CBC mode. */
+    MBEDTLS_CIPHER_AES_128_CFB128,       /**< AES cipher with 128-bit CFB128 mode. */
+    MBEDTLS_CIPHER_AES_192_CFB128,       /**< AES cipher with 192-bit CFB128 mode. */
+    MBEDTLS_CIPHER_AES_256_CFB128,       /**< AES cipher with 256-bit CFB128 mode. */
+    MBEDTLS_CIPHER_AES_128_CTR,          /**< AES cipher with 128-bit CTR mode. */
+    MBEDTLS_CIPHER_AES_192_CTR,          /**< AES cipher with 192-bit CTR mode. */
+    MBEDTLS_CIPHER_AES_256_CTR,          /**< AES cipher with 256-bit CTR mode. */
+    MBEDTLS_CIPHER_AES_128_GCM,          /**< AES cipher with 128-bit GCM mode. */
+    MBEDTLS_CIPHER_AES_192_GCM,          /**< AES cipher with 192-bit GCM mode. */
+    MBEDTLS_CIPHER_AES_256_GCM,          /**< AES cipher with 256-bit GCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_ECB,     /**< Camellia cipher with 128-bit ECB mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_ECB,     /**< Camellia cipher with 192-bit ECB mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_ECB,     /**< Camellia cipher with 256-bit ECB mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CBC,     /**< Camellia cipher with 128-bit CBC mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CBC,     /**< Camellia cipher with 192-bit CBC mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CBC,     /**< Camellia cipher with 256-bit CBC mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CFB128,  /**< Camellia cipher with 128-bit CFB128 mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CFB128,  /**< Camellia cipher with 192-bit CFB128 mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CFB128,  /**< Camellia cipher with 256-bit CFB128 mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CTR,     /**< Camellia cipher with 128-bit CTR mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CTR,     /**< Camellia cipher with 192-bit CTR mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CTR,     /**< Camellia cipher with 256-bit CTR mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_GCM,     /**< Camellia cipher with 128-bit GCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_GCM,     /**< Camellia cipher with 192-bit GCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_GCM,     /**< Camellia cipher with 256-bit GCM mode. */
+    MBEDTLS_CIPHER_DES_ECB,              /**< DES cipher with ECB mode. */
+    MBEDTLS_CIPHER_DES_CBC,              /**< DES cipher with CBC mode. */
+    MBEDTLS_CIPHER_DES_EDE_ECB,          /**< DES cipher with EDE ECB mode. */
+    MBEDTLS_CIPHER_DES_EDE_CBC,          /**< DES cipher with EDE CBC mode. */
+    MBEDTLS_CIPHER_DES_EDE3_ECB,         /**< DES cipher with EDE3 ECB mode. */
+    MBEDTLS_CIPHER_DES_EDE3_CBC,         /**< DES cipher with EDE3 CBC mode. */
+    MBEDTLS_CIPHER_BLOWFISH_ECB,         /**< Blowfish cipher with ECB mode. */
+    MBEDTLS_CIPHER_BLOWFISH_CBC,         /**< Blowfish cipher with CBC mode. */
+    MBEDTLS_CIPHER_BLOWFISH_CFB64,       /**< Blowfish cipher with CFB64 mode. */
+    MBEDTLS_CIPHER_BLOWFISH_CTR,         /**< Blowfish cipher with CTR mode. */
+    MBEDTLS_CIPHER_ARC4_128,             /**< RC4 cipher with 128-bit mode. */
+    MBEDTLS_CIPHER_AES_128_CCM,          /**< AES cipher with 128-bit CCM mode. */
+    MBEDTLS_CIPHER_AES_192_CCM,          /**< AES cipher with 192-bit CCM mode. */
+    MBEDTLS_CIPHER_AES_256_CCM,          /**< AES cipher with 256-bit CCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_128_CCM,     /**< Camellia cipher with 128-bit CCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_192_CCM,     /**< Camellia cipher with 192-bit CCM mode. */
+    MBEDTLS_CIPHER_CAMELLIA_256_CCM,     /**< Camellia cipher with 256-bit CCM mode. */
+    MBEDTLS_CIPHER_ARIA_128_ECB,         /**< Aria cipher with 128-bit key and ECB mode. */
+    MBEDTLS_CIPHER_ARIA_192_ECB,         /**< Aria cipher with 192-bit key and ECB mode. */
+    MBEDTLS_CIPHER_ARIA_256_ECB,         /**< Aria cipher with 256-bit key and ECB mode. */
+    MBEDTLS_CIPHER_ARIA_128_CBC,         /**< Aria cipher with 128-bit key and CBC mode. */
+    MBEDTLS_CIPHER_ARIA_192_CBC,         /**< Aria cipher with 192-bit key and CBC mode. */
+    MBEDTLS_CIPHER_ARIA_256_CBC,         /**< Aria cipher with 256-bit key and CBC mode. */
+    MBEDTLS_CIPHER_ARIA_128_CFB128,      /**< Aria cipher with 128-bit key and CFB-128 mode. */
+    MBEDTLS_CIPHER_ARIA_192_CFB128,      /**< Aria cipher with 192-bit key and CFB-128 mode. */
+    MBEDTLS_CIPHER_ARIA_256_CFB128,      /**< Aria cipher with 256-bit key and CFB-128 mode. */
+    MBEDTLS_CIPHER_ARIA_128_CTR,         /**< Aria cipher with 128-bit key and CTR mode. */
+    MBEDTLS_CIPHER_ARIA_192_CTR,         /**< Aria cipher with 192-bit key and CTR mode. */
+    MBEDTLS_CIPHER_ARIA_256_CTR,         /**< Aria cipher with 256-bit key and CTR mode. */
+    MBEDTLS_CIPHER_ARIA_128_GCM,         /**< Aria cipher with 128-bit key and GCM mode. */
+    MBEDTLS_CIPHER_ARIA_192_GCM,         /**< Aria cipher with 192-bit key and GCM mode. */
+    MBEDTLS_CIPHER_ARIA_256_GCM,         /**< Aria cipher with 256-bit key and GCM mode. */
+    MBEDTLS_CIPHER_ARIA_128_CCM,         /**< Aria cipher with 128-bit key and CCM mode. */
+    MBEDTLS_CIPHER_ARIA_192_CCM,         /**< Aria cipher with 192-bit key and CCM mode. */
+    MBEDTLS_CIPHER_ARIA_256_CCM,         /**< Aria cipher with 256-bit key and CCM mode. */
+    MBEDTLS_CIPHER_AES_128_OFB,          /**< AES 128-bit cipher in OFB mode. */
+    MBEDTLS_CIPHER_AES_192_OFB,          /**< AES 192-bit cipher in OFB mode. */
+    MBEDTLS_CIPHER_AES_256_OFB,          /**< AES 256-bit cipher in OFB mode. */
+    MBEDTLS_CIPHER_AES_128_XTS,          /**< AES 128-bit cipher in XTS block mode. */
+    MBEDTLS_CIPHER_AES_256_XTS,          /**< AES 256-bit cipher in XTS block mode. */
+    MBEDTLS_CIPHER_CHACHA20,             /**< ChaCha20 stream cipher. */
+    MBEDTLS_CIPHER_CHACHA20_POLY1305,    /**< ChaCha20-Poly1305 AEAD cipher. */
+} mbedtls_cipher_type_t;
+
+/** Supported cipher modes. */
+typedef enum {
+    MBEDTLS_MODE_NONE = 0,               /**< None. */
+    MBEDTLS_MODE_ECB,                    /**< The ECB cipher mode. */
+    MBEDTLS_MODE_CBC,                    /**< The CBC cipher mode. */
+    MBEDTLS_MODE_CFB,                    /**< The CFB cipher mode. */
+    MBEDTLS_MODE_OFB,                    /**< The OFB cipher mode. */
+    MBEDTLS_MODE_CTR,                    /**< The CTR cipher mode. */
+    MBEDTLS_MODE_GCM,                    /**< The GCM cipher mode. */
+    MBEDTLS_MODE_STREAM,                 /**< The stream cipher mode. */
+    MBEDTLS_MODE_CCM,                    /**< The CCM cipher mode. */
+    MBEDTLS_MODE_XTS,                    /**< The XTS cipher mode. */
+    MBEDTLS_MODE_CHACHAPOLY,             /**< The ChaCha-Poly cipher mode. */
+} mbedtls_cipher_mode_t;
+
+/** Supported cipher padding types. */
+typedef enum {
+    MBEDTLS_PADDING_PKCS7 = 0,     /**< PKCS7 padding (default).        */
+    MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding.         */
+    MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding.             */
+    MBEDTLS_PADDING_ZEROS,         /**< Zero padding (not reversible). */
+    MBEDTLS_PADDING_NONE,          /**< Never pad (full blocks only).   */
+} mbedtls_cipher_padding_t;
+
+/** Type of operation. */
+typedef enum {
+    MBEDTLS_OPERATION_NONE = -1,
+    MBEDTLS_DECRYPT = 0,
+    MBEDTLS_ENCRYPT,
+} mbedtls_operation_t;
+
+enum {
+    /** Undefined key length. */
+    MBEDTLS_KEY_LENGTH_NONE = 0,
+    /** Key length, in bits (including parity), for DES keys. */
+    MBEDTLS_KEY_LENGTH_DES  = 64,
+    /** Key length in bits, including parity, for DES in two-key EDE. */
+    MBEDTLS_KEY_LENGTH_DES_EDE = 128,
+    /** Key length in bits, including parity, for DES in three-key EDE. */
+    MBEDTLS_KEY_LENGTH_DES_EDE3 = 192,
+};
+
+/** Maximum length of any IV, in Bytes. */
+#define MBEDTLS_MAX_IV_LENGTH      16
+/** Maximum block size of any cipher, in Bytes. */
+#define MBEDTLS_MAX_BLOCK_LENGTH   16
+
+/**
+ * Base cipher information (opaque struct).
+ */
+typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t;
+
+/**
+ * CMAC context (opaque struct).
+ */
+typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t;
+
+/**
+ * Cipher information. Allows calling cipher functions
+ * in a generic way.
+ */
+typedef struct mbedtls_cipher_info_t
+{
+    /** Full cipher identifier. For example,
+     * MBEDTLS_CIPHER_AES_256_CBC.
+     */
+    mbedtls_cipher_type_t type;
+
+    /** The cipher mode. For example, MBEDTLS_MODE_CBC. */
+    mbedtls_cipher_mode_t mode;
+
+    /** The cipher key length, in bits. This is the
+     * default length for variable sized ciphers.
+     * Includes parity bits for ciphers like DES.
+     */
+    unsigned int key_bitlen;
+
+    /** Name of the cipher. */
+    const char * name;
+
+    /** IV or nonce size, in Bytes.
+     * For ciphers that accept variable IV sizes,
+     * this is the recommended size.
+     */
+    unsigned int iv_size;
+
+    /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and
+     *  MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the
+     *  cipher supports variable IV or variable key sizes, respectively.
+     */
+    int flags;
+
+    /** The block size, in Bytes. */
+    unsigned int block_size;
+
+    /** Struct for base cipher information and functions. */
+    const mbedtls_cipher_base_t *base;
+
+} mbedtls_cipher_info_t;
+
+/**
+ * Generic cipher context.
+ */
+typedef struct mbedtls_cipher_context_t
+{
+    /** Information about the associated cipher. */
+    const mbedtls_cipher_info_t *cipher_info;
+
+    /** Key length to use. */
+    int key_bitlen;
+
+    /** Operation that the key of the context has been
+     * initialized for.
+     */
+    mbedtls_operation_t operation;
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+    /** Padding functions to use, if relevant for
+     * the specific cipher mode.
+     */
+    void (*add_padding)( unsigned char *output, size_t olen, size_t data_len );
+    int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len );
+#endif
+
+    /** Buffer for input that has not been processed yet. */
+    unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH];
+
+    /** Number of Bytes that have not been processed yet. */
+    size_t unprocessed_len;
+
+    /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number
+     * for XTS-mode. */
+    unsigned char iv[MBEDTLS_MAX_IV_LENGTH];
+
+    /** IV size in Bytes, for ciphers with variable-length IVs. */
+    size_t iv_size;
+
+    /** The cipher-specific context. */
+    void *cipher_ctx;
+
+#if defined(MBEDTLS_CMAC_C)
+    /** CMAC-specific context. */
+    mbedtls_cmac_context_t *cmac_ctx;
+#endif
+} mbedtls_cipher_context_t;
+
+/**
+ * \brief This function retrieves the list of ciphers supported by the generic
+ * cipher module.
+ *
+ * \return      A statically-allocated array of ciphers. The last entry
+ *              is zero.
+ */
+const int *mbedtls_cipher_list( void );
+
+/**
+ * \brief               This function retrieves the cipher-information
+ *                      structure associated with the given cipher name.
+ *
+ * \param cipher_name   Name of the cipher to search for. This must not be
+ *                      \c NULL.
+ *
+ * \return              The cipher information structure associated with the
+ *                      given \p cipher_name.
+ * \return              \c NULL if the associated cipher information is not found.
+ */
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name );
+
+/**
+ * \brief               This function retrieves the cipher-information
+ *                      structure associated with the given cipher type.
+ *
+ * \param cipher_type   Type of the cipher to search for.
+ *
+ * \return              The cipher information structure associated with the
+ *                      given \p cipher_type.
+ * \return              \c NULL if the associated cipher information is not found.
+ */
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
+
+/**
+ * \brief               This function retrieves the cipher-information
+ *                      structure associated with the given cipher ID,
+ *                      key size and mode.
+ *
+ * \param cipher_id     The ID of the cipher to search for. For example,
+ *                      #MBEDTLS_CIPHER_ID_AES.
+ * \param key_bitlen    The length of the key in bits.
+ * \param mode          The cipher mode. For example, #MBEDTLS_MODE_CBC.
+ *
+ * \return              The cipher information structure associated with the
+ *                      given \p cipher_id.
+ * \return              \c NULL if the associated cipher information is not found.
+ */
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
+                                              int key_bitlen,
+                                              const mbedtls_cipher_mode_t mode );
+
+/**
+ * \brief               This function initializes a \p cipher_context as NONE.
+ *
+ * \param ctx           The context to be initialized. This must not be \c NULL.
+ */
+void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
+
+/**
+ * \brief               This function frees and clears the cipher-specific
+ *                      context of \p ctx. Freeing \p ctx itself remains the
+ *                      responsibility of the caller.
+ *
+ * \param ctx           The context to be freed. If this is \c NULL, the
+ *                      function has no effect, otherwise this must point to an
+ *                      initialized context.
+ */
+void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
+
+
+/**
+ * \brief               This function initializes and fills the cipher-context
+ *                      structure with the appropriate values. It also clears
+ *                      the structure.
+ *
+ * \param ctx           The context to initialize. This must be initialized.
+ * \param cipher_info   The cipher to use.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
+ *                      cipher-specific context fails.
+ *
+ * \internal Currently, the function also clears the structure.
+ * In future versions, the caller will be required to call
+ * mbedtls_cipher_init() on the structure first.
+ */
+int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
+                          const mbedtls_cipher_info_t *cipher_info );
+
+/**
+ * \brief        This function returns the block size of the given cipher.
+ *
+ * \param ctx    The context of the cipher. This must be initialized.
+ *
+ * \return       The block size of the underlying cipher.
+ * \return       \c 0 if \p ctx has not been initialized.
+ */
+static inline unsigned int mbedtls_cipher_get_block_size(
+    const mbedtls_cipher_context_t *ctx )
+{
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+    if( ctx->cipher_info == NULL )
+        return 0;
+
+    return ctx->cipher_info->block_size;
+}
+
+/**
+ * \brief        This function returns the mode of operation for
+ *               the cipher. For example, MBEDTLS_MODE_CBC.
+ *
+ * \param ctx    The context of the cipher. This must be initialized.
+ *
+ * \return       The mode of operation.
+ * \return       #MBEDTLS_MODE_NONE if \p ctx has not been initialized.
+ */
+static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode(
+    const mbedtls_cipher_context_t *ctx )
+{
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, MBEDTLS_MODE_NONE );
+    if( ctx->cipher_info == NULL )
+        return MBEDTLS_MODE_NONE;
+
+    return ctx->cipher_info->mode;
+}
+
+/**
+ * \brief       This function returns the size of the IV or nonce
+ *              of the cipher, in Bytes.
+ *
+ * \param ctx   The context of the cipher. This must be initialized.
+ *
+ * \return      The recommended IV size if no IV has been set.
+ * \return      \c 0 for ciphers not using an IV or a nonce.
+ * \return      The actual size if an IV has been set.
+ */
+static inline int mbedtls_cipher_get_iv_size(
+    const mbedtls_cipher_context_t *ctx )
+{
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+    if( ctx->cipher_info == NULL )
+        return 0;
+
+    if( ctx->iv_size != 0 )
+        return (int) ctx->iv_size;
+
+    return (int) ctx->cipher_info->iv_size;
+}
+
+/**
+ * \brief               This function returns the type of the given cipher.
+ *
+ * \param ctx           The context of the cipher. This must be initialized.
+ *
+ * \return              The type of the cipher.
+ * \return              #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized.
+ */
+static inline mbedtls_cipher_type_t mbedtls_cipher_get_type(
+    const mbedtls_cipher_context_t *ctx )
+{
+    MBEDTLS_INTERNAL_VALIDATE_RET(
+        ctx != NULL, MBEDTLS_CIPHER_NONE );
+    if( ctx->cipher_info == NULL )
+        return MBEDTLS_CIPHER_NONE;
+
+    return ctx->cipher_info->type;
+}
+
+/**
+ * \brief               This function returns the name of the given cipher
+ *                      as a string.
+ *
+ * \param ctx           The context of the cipher. This must be initialized.
+ *
+ * \return              The name of the cipher.
+ * \return              NULL if \p ctx has not been not initialized.
+ */
+static inline const char *mbedtls_cipher_get_name(
+    const mbedtls_cipher_context_t *ctx )
+{
+    MBEDTLS_INTERNAL_VALIDATE_RET( ctx != NULL, 0 );
+    if( ctx->cipher_info == NULL )
+        return 0;
+
+    return ctx->cipher_info->name;
+}
+
+/**
+ * \brief               This function returns the key length of the cipher.
+ *
+ * \param ctx           The context of the cipher. This must be initialized.
+ *
+ * \return              The key length of the cipher in bits.
+ * \return              #MBEDTLS_KEY_LENGTH_NONE if ctx \p has not been
+ *                      initialized.
+ */
+static inline int mbedtls_cipher_get_key_bitlen(
+    const mbedtls_cipher_context_t *ctx )
+{
+    MBEDTLS_INTERNAL_VALIDATE_RET(
+        ctx != NULL, MBEDTLS_KEY_LENGTH_NONE );
+    if( ctx->cipher_info == NULL )
+        return MBEDTLS_KEY_LENGTH_NONE;
+
+    return (int) ctx->cipher_info->key_bitlen;
+}
+
+/**
+ * \brief          This function returns the operation of the given cipher.
+ *
+ * \param ctx      The context of the cipher. This must be initialized.
+ *
+ * \return         The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
+ * \return         #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized.
+ */
+static inline mbedtls_operation_t mbedtls_cipher_get_operation(
+    const mbedtls_cipher_context_t *ctx )
+{
+    MBEDTLS_INTERNAL_VALIDATE_RET(
+        ctx != NULL, MBEDTLS_OPERATION_NONE );
+    if( ctx->cipher_info == NULL )
+        return MBEDTLS_OPERATION_NONE;
+
+    return ctx->operation;
+}
+
+/**
+ * \brief               This function sets the key to use with the given context.
+ *
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a cipher information structure.
+ * \param key           The key to use. This must be a readable buffer of at
+ *                      least \p key_bitlen Bits.
+ * \param key_bitlen    The key length to use, in Bits.
+ * \param operation     The operation that the key will be used for:
+ *                      #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
+                           const unsigned char *key,
+                           int key_bitlen,
+                           const mbedtls_operation_t operation );
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+/**
+ * \brief               This function sets the padding mode, for cipher modes
+ *                      that use padding.
+ *
+ *                      The default passing mode is PKCS7 padding.
+ *
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a cipher information structure.
+ * \param mode          The padding mode.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
+ *                      if the selected padding mode is not supported.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode
+ *                      does not support padding.
+ */
+int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
+                                     mbedtls_cipher_padding_t mode );
+#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
+
+/**
+ * \brief           This function sets the initialization vector (IV)
+ *                  or nonce.
+ *
+ * \note            Some ciphers do not use IVs nor nonce. For these
+ *                  ciphers, this function has no effect.
+ *
+ * \param ctx       The generic cipher context. This must be initialized and
+ *                  bound to a cipher information structure.
+ * \param iv        The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This
+ *                  must be a readable buffer of at least \p iv_len Bytes.
+ * \param iv_len    The IV length for ciphers with variable-size IV.
+ *                  This parameter is discarded by ciphers with fixed-size IV.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                  parameter-verification failure.
+ */
+int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
+                           const unsigned char *iv,
+                           size_t iv_len );
+
+/**
+ * \brief         This function resets the cipher state.
+ *
+ * \param ctx     The generic cipher context. This must be initialized.
+ *
+ * \return        \c 0 on success.
+ * \return        #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                parameter-verification failure.
+ */
+int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+/**
+ * \brief               This function adds additional data for AEAD ciphers.
+ *                      Currently supported with GCM and ChaCha20+Poly1305.
+ *                      This must be called exactly once, after
+ *                      mbedtls_cipher_reset().
+ *
+ * \param ctx           The generic cipher context. This must be initialized.
+ * \param ad            The additional data to use. This must be a readable
+ *                      buffer of at least \p ad_len Bytes.
+ * \param ad_len        the Length of \p ad Bytes.
+ *
+ * \return              \c 0 on success.
+ * \return              A specific error code on failure.
+ */
+int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
+                      const unsigned char *ad, size_t ad_len );
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
+
+/**
+ * \brief               The generic cipher update function. It encrypts or
+ *                      decrypts using the given cipher context. Writes as
+ *                      many block-sized blocks of data as possible to output.
+ *                      Any data that cannot be written immediately is either
+ *                      added to the next block, or flushed when
+ *                      mbedtls_cipher_finish() is called.
+ *                      Exception: For MBEDTLS_MODE_ECB, expects a single block
+ *                      in size. For example, 16 Bytes for AES.
+ *
+ * \note                If the underlying cipher is used in GCM mode, all calls
+ *                      to this function, except for the last one before
+ *                      mbedtls_cipher_finish(), must have \p ilen as a
+ *                      multiple of the block size of the cipher.
+ *
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a key.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
+ * \param ilen          The length of the input data.
+ * \param output        The buffer for the output data. This must be able to
+ *                      hold at least `ilen + block_size`. This must not be the
+ *                      same buffer as \p input.
+ * \param olen          The length of the output data, to be updated with the
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an
+ *                      unsupported mode for a cipher.
+ * \return              A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
+                   size_t ilen, unsigned char *output, size_t *olen );
+
+/**
+ * \brief               The generic cipher finalization function. If data still
+ *                      needs to be flushed from an incomplete block, the data
+ *                      contained in it is padded to the size of
+ *                      the last block, and written to the \p output buffer.
+ *
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a key.
+ * \param output        The buffer to write data to. This needs to be a writable
+ *                      buffer of at least \p block_size Bytes.
+ * \param olen          The length of the data written to the \p output buffer.
+ *                      This may not be \c NULL.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ *                      expecting a full block but not receiving one.
+ * \return              #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
+ *                      while decrypting.
+ * \return              A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
+                   unsigned char *output, size_t *olen );
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+/**
+ * \brief               This function writes a tag for AEAD ciphers.
+ *                      Currently supported with GCM and ChaCha20+Poly1305.
+ *                      This must be called after mbedtls_cipher_finish().
+ *
+ * \param ctx           The generic cipher context. This must be initialized,
+ *                      bound to a key, and have just completed a cipher
+ *                      operation through mbedtls_cipher_finish() the tag for
+ *                      which should be written.
+ * \param tag           The buffer to write the tag to. This must be a writable
+ *                      buffer of at least \p tag_len Bytes.
+ * \param tag_len       The length of the tag to write.
+ *
+ * \return              \c 0 on success.
+ * \return              A specific error code on failure.
+ */
+int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
+                      unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief               This function checks the tag for AEAD ciphers.
+ *                      Currently supported with GCM and ChaCha20+Poly1305.
+ *                      This must be called after mbedtls_cipher_finish().
+ *
+ * \param ctx           The generic cipher context. This must be initialized.
+ * \param tag           The buffer holding the tag. This must be a readable
+ *                      buffer of at least \p tag_len Bytes.
+ * \param tag_len       The length of the tag to check.
+ *
+ * \return              \c 0 on success.
+ * \return              A specific error code on failure.
+ */
+int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
+                      const unsigned char *tag, size_t tag_len );
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
+
+/**
+ * \brief               The generic all-in-one encryption/decryption function,
+ *                      for all ciphers except AEAD constructs.
+ *
+ * \param ctx           The generic cipher context. This must be initialized.
+ * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ *                      This must be a readable buffer of at least \p iv_len
+ *                      Bytes.
+ * \param iv_len        The IV length for ciphers with variable-size IV.
+ *                      This parameter is discarded by ciphers with fixed-size
+ *                      IV.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
+ * \param ilen          The length of the input data in Bytes.
+ * \param output        The buffer for the output data. This must be able to
+ *                      hold at least `ilen + block_size`. This must not be the
+ *                      same buffer as \p input.
+ * \param olen          The length of the output data, to be updated with the
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
+ *
+ * \note                Some ciphers do not use IVs nor nonce. For these
+ *                      ciphers, use \p iv = NULL and \p iv_len = 0.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption
+ *                      expecting a full block but not receiving one.
+ * \return              #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding
+ *                      while decrypting.
+ * \return              A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
+                  const unsigned char *iv, size_t iv_len,
+                  const unsigned char *input, size_t ilen,
+                  unsigned char *output, size_t *olen );
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+/**
+ * \brief               The generic autenticated encryption (AEAD) function.
+ *
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      bound to a key.
+ * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ *                      This must be a readable buffer of at least \p iv_len
+ *                      Bytes.
+ * \param iv_len        The IV length for ciphers with variable-size IV.
+ *                      This parameter is discarded by ciphers with fixed-size IV.
+ * \param ad            The additional data to authenticate. This must be a
+ *                      readable buffer of at least \p ad_len Bytes.
+ * \param ad_len        The length of \p ad.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
+ * \param ilen          The length of the input data.
+ * \param output        The buffer for the output data. This must be able to
+ *                      hold at least \p ilen Bytes.
+ * \param olen          The length of the output data, to be updated with the
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
+ * \param tag           The buffer for the authentication tag. This must be a
+ *                      writable buffer of at least \p tag_len Bytes.
+ * \param tag_len       The desired length of the authentication tag.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *ad, size_t ad_len,
+                         const unsigned char *input, size_t ilen,
+                         unsigned char *output, size_t *olen,
+                         unsigned char *tag, size_t tag_len );
+
+/**
+ * \brief               The generic autenticated decryption (AEAD) function.
+ *
+ * \note                If the data is not authentic, then the output buffer
+ *                      is zeroed out to prevent the unauthentic plaintext being
+ *                      used, making this interface safer.
+ *
+ * \param ctx           The generic cipher context. This must be initialized and
+ *                      and bound to a key.
+ * \param iv            The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
+ *                      This must be a readable buffer of at least \p iv_len
+ *                      Bytes.
+ * \param iv_len        The IV length for ciphers with variable-size IV.
+ *                      This parameter is discarded by ciphers with fixed-size IV.
+ * \param ad            The additional data to be authenticated. This must be a
+ *                      readable buffer of at least \p ad_len Bytes.
+ * \param ad_len        The length of \p ad.
+ * \param input         The buffer holding the input data. This must be a
+ *                      readable buffer of at least \p ilen Bytes.
+ * \param ilen          The length of the input data.
+ * \param output        The buffer for the output data.
+ *                      This must be able to hold at least \p ilen Bytes.
+ * \param olen          The length of the output data, to be updated with the
+ *                      actual number of Bytes written. This must not be
+ *                      \c NULL.
+ * \param tag           The buffer holding the authentication tag. This must be
+ *                      a readable buffer of at least \p tag_len Bytes.
+ * \param tag_len       The length of the authentication tag.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ *                      parameter-verification failure.
+ * \return              #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
+ * \return              A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *ad, size_t ad_len,
+                         const unsigned char *input, size_t ilen,
+                         unsigned char *output, size_t *olen,
+                         const unsigned char *tag, size_t tag_len );
+#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CIPHER_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/cipher_internal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/cipher_internal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/cipher_internal.h	(revision 398)
@@ -0,0 +1,125 @@
+/**
+ * \file cipher_internal.h
+ *
+ * \brief Cipher wrappers.
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_CIPHER_WRAP_H
+#define MBEDTLS_CIPHER_WRAP_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "cipher.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Base cipher information. The non-mode specific functions and values.
+ */
+struct mbedtls_cipher_base_t
+{
+    /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */
+    mbedtls_cipher_id_t cipher;
+
+    /** Encrypt using ECB */
+    int (*ecb_func)( void *ctx, mbedtls_operation_t mode,
+                     const unsigned char *input, unsigned char *output );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    /** Encrypt using CBC */
+    int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length,
+                     unsigned char *iv, const unsigned char *input,
+                     unsigned char *output );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    /** Encrypt using CFB (Full length) */
+    int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off,
+                     unsigned char *iv, const unsigned char *input,
+                     unsigned char *output );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    /** Encrypt using OFB (Full length) */
+    int (*ofb_func)( void *ctx, size_t length, size_t *iv_off,
+                     unsigned char *iv,
+                     const unsigned char *input,
+                     unsigned char *output );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    /** Encrypt using CTR */
+    int (*ctr_func)( void *ctx, size_t length, size_t *nc_off,
+                     unsigned char *nonce_counter, unsigned char *stream_block,
+                     const unsigned char *input, unsigned char *output );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    /** Encrypt or decrypt using XTS. */
+    int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length,
+                     const unsigned char data_unit[16],
+                     const unsigned char *input, unsigned char *output );
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    /** Encrypt using STREAM */
+    int (*stream_func)( void *ctx, size_t length,
+                        const unsigned char *input, unsigned char *output );
+#endif
+
+    /** Set key for encryption purposes */
+    int (*setkey_enc_func)( void *ctx, const unsigned char *key,
+                            unsigned int key_bitlen );
+
+    /** Set key for decryption purposes */
+    int (*setkey_dec_func)( void *ctx, const unsigned char *key,
+                            unsigned int key_bitlen);
+
+    /** Allocate a new context */
+    void * (*ctx_alloc_func)( void );
+
+    /** Free the given context */
+    void (*ctx_free_func)( void *ctx );
+
+};
+
+typedef struct
+{
+    mbedtls_cipher_type_t type;
+    const mbedtls_cipher_info_t *info;
+} mbedtls_cipher_definition_t;
+
+extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
+
+extern int mbedtls_cipher_supported[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CIPHER_WRAP_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/cmac.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/cmac.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/cmac.h	(revision 398)
@@ -0,0 +1,213 @@
+/**
+ * \file cmac.h
+ *
+ * \brief This file contains CMAC definitions and functions.
+ *
+ * The Cipher-based Message Authentication Code (CMAC) Mode for
+ * Authentication is defined in <em>RFC-4493: The AES-CMAC Algorithm</em>.
+ */
+/*
+ *  Copyright (C) 2015-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_CMAC_H
+#define MBEDTLS_CMAC_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "cipher.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED -0x007A  /**< CMAC hardware accelerator failed. */
+
+#define MBEDTLS_AES_BLOCK_SIZE          16
+#define MBEDTLS_DES3_BLOCK_SIZE         8
+
+#if defined(MBEDTLS_AES_C)
+#define MBEDTLS_CIPHER_BLKSIZE_MAX      16  /**< The longest block used by CMAC is that of AES. */
+#else
+#define MBEDTLS_CIPHER_BLKSIZE_MAX      8   /**< The longest block used by CMAC is that of 3DES. */
+#endif
+
+#if !defined(MBEDTLS_CMAC_ALT)
+
+/**
+ * The CMAC context structure.
+ */
+struct mbedtls_cmac_context_t
+{
+    /** The internal state of the CMAC algorithm.  */
+    unsigned char       state[MBEDTLS_CIPHER_BLKSIZE_MAX];
+
+    /** Unprocessed data - either data that was not block aligned and is still
+     *  pending processing, or the final block. */
+    unsigned char       unprocessed_block[MBEDTLS_CIPHER_BLKSIZE_MAX];
+
+    /** The length of data pending processing. */
+    size_t              unprocessed_len;
+};
+
+#else  /* !MBEDTLS_CMAC_ALT */
+#include "cmac_alt.h"
+#endif /* !MBEDTLS_CMAC_ALT */
+
+/**
+ * \brief               This function sets the CMAC key, and prepares to authenticate
+ *                      the input data.
+ *                      Must be called with an initialized cipher context.
+ *
+ * \param ctx           The cipher context used for the CMAC operation, initialized
+ *                      as one of the following types: MBEDTLS_CIPHER_AES_128_ECB,
+ *                      MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB,
+ *                      or MBEDTLS_CIPHER_DES_EDE3_ECB.
+ * \param key           The CMAC key.
+ * \param keybits       The length of the CMAC key in bits.
+ *                      Must be supported by the cipher.
+ *
+ * \return              \c 0 on success.
+ * \return              A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
+                                const unsigned char *key, size_t keybits );
+
+/**
+ * \brief               This function feeds an input buffer into an ongoing CMAC
+ *                      computation.
+ *
+ *                      It is called between mbedtls_cipher_cmac_starts() or
+ *                      mbedtls_cipher_cmac_reset(), and mbedtls_cipher_cmac_finish().
+ *                      Can be called repeatedly.
+ *
+ * \param ctx           The cipher context used for the CMAC operation.
+ * \param input         The buffer holding the input data.
+ * \param ilen          The length of the input data.
+ *
+ * \return             \c 0 on success.
+ * \return             #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ *                     if parameter verification fails.
+ */
+int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
+                                const unsigned char *input, size_t ilen );
+
+/**
+ * \brief               This function finishes the CMAC operation, and writes
+ *                      the result to the output buffer.
+ *
+ *                      It is called after mbedtls_cipher_cmac_update().
+ *                      It can be followed by mbedtls_cipher_cmac_reset() and
+ *                      mbedtls_cipher_cmac_update(), or mbedtls_cipher_free().
+ *
+ * \param ctx           The cipher context used for the CMAC operation.
+ * \param output        The output buffer for the CMAC checksum result.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ *                      if parameter verification fails.
+ */
+int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
+                                unsigned char *output );
+
+/**
+ * \brief               This function prepares the authentication of another
+ *                      message with the same key as the previous CMAC
+ *                      operation.
+ *
+ *                      It is called after mbedtls_cipher_cmac_finish()
+ *                      and before mbedtls_cipher_cmac_update().
+ *
+ * \param ctx           The cipher context used for the CMAC operation.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ *                      if parameter verification fails.
+ */
+int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
+
+/**
+ * \brief               This function calculates the full generic CMAC
+ *                      on the input buffer with the provided key.
+ *
+ *                      The function allocates the context, performs the
+ *                      calculation, and frees the context.
+ *
+ *                      The CMAC result is calculated as
+ *                      output = generic CMAC(cmac key, input buffer).
+ *
+ *
+ * \param cipher_info   The cipher information.
+ * \param key           The CMAC key.
+ * \param keylen        The length of the CMAC key in bits.
+ * \param input         The buffer holding the input data.
+ * \param ilen          The length of the input data.
+ * \param output        The buffer for the generic CMAC result.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_MD_BAD_INPUT_DATA
+ *                      if parameter verification fails.
+ */
+int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
+                         const unsigned char *key, size_t keylen,
+                         const unsigned char *input, size_t ilen,
+                         unsigned char *output );
+
+#if defined(MBEDTLS_AES_C)
+/**
+ * \brief           This function implements the AES-CMAC-PRF-128 pseudorandom
+ *                  function, as defined in
+ *                  <em>RFC-4615: The Advanced Encryption Standard-Cipher-based
+ *                  Message Authentication Code-Pseudo-Random Function-128
+ *                  (AES-CMAC-PRF-128) Algorithm for the Internet Key
+ *                  Exchange Protocol (IKE).</em>
+ *
+ * \param key       The key to use.
+ * \param key_len   The key length in Bytes.
+ * \param input     The buffer holding the input data.
+ * \param in_len    The length of the input data in Bytes.
+ * \param output    The buffer holding the generated 16 Bytes of
+ *                  pseudorandom output.
+ *
+ * \return          \c 0 on success.
+ */
+int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
+                              const unsigned char *input, size_t in_len,
+                              unsigned char output[16] );
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) )
+/**
+ * \brief          The CMAC checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_cmac_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CMAC_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/compat-1.3.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/compat-1.3.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/compat-1.3.h	(revision 398)
@@ -0,0 +1,2531 @@
+/**
+ * \file compat-1.3.h
+ *
+ * \brief Compatibility definitions for using mbed TLS with client code written
+ *  for the PolarSSL naming conventions.
+ *
+ * \deprecated Use the new names directly instead
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "Including compat-1.3.h is deprecated"
+#endif
+
+#ifndef MBEDTLS_COMPAT13_H
+#define MBEDTLS_COMPAT13_H
+
+/*
+ * config.h options
+ */
+#if defined MBEDTLS_AESNI_C
+#define POLARSSL_AESNI_C MBEDTLS_AESNI_C
+#endif
+#if defined MBEDTLS_AES_ALT
+#define POLARSSL_AES_ALT MBEDTLS_AES_ALT
+#endif
+#if defined MBEDTLS_AES_C
+#define POLARSSL_AES_C MBEDTLS_AES_C
+#endif
+#if defined MBEDTLS_AES_ROM_TABLES
+#define POLARSSL_AES_ROM_TABLES MBEDTLS_AES_ROM_TABLES
+#endif
+#if defined MBEDTLS_ARC4_ALT
+#define POLARSSL_ARC4_ALT MBEDTLS_ARC4_ALT
+#endif
+#if defined MBEDTLS_ARC4_C
+#define POLARSSL_ARC4_C MBEDTLS_ARC4_C
+#endif
+#if defined MBEDTLS_ASN1_PARSE_C
+#define POLARSSL_ASN1_PARSE_C MBEDTLS_ASN1_PARSE_C
+#endif
+#if defined MBEDTLS_ASN1_WRITE_C
+#define POLARSSL_ASN1_WRITE_C MBEDTLS_ASN1_WRITE_C
+#endif
+#if defined MBEDTLS_BASE64_C
+#define POLARSSL_BASE64_C MBEDTLS_BASE64_C
+#endif
+#if defined MBEDTLS_BIGNUM_C
+#define POLARSSL_BIGNUM_C MBEDTLS_BIGNUM_C
+#endif
+#if defined MBEDTLS_BLOWFISH_ALT
+#define POLARSSL_BLOWFISH_ALT MBEDTLS_BLOWFISH_ALT
+#endif
+#if defined MBEDTLS_BLOWFISH_C
+#define POLARSSL_BLOWFISH_C MBEDTLS_BLOWFISH_C
+#endif
+#if defined MBEDTLS_CAMELLIA_ALT
+#define POLARSSL_CAMELLIA_ALT MBEDTLS_CAMELLIA_ALT
+#endif
+#if defined MBEDTLS_CAMELLIA_C
+#define POLARSSL_CAMELLIA_C MBEDTLS_CAMELLIA_C
+#endif
+#if defined MBEDTLS_CAMELLIA_SMALL_MEMORY
+#define POLARSSL_CAMELLIA_SMALL_MEMORY MBEDTLS_CAMELLIA_SMALL_MEMORY
+#endif
+#if defined MBEDTLS_CCM_C
+#define POLARSSL_CCM_C MBEDTLS_CCM_C
+#endif
+#if defined MBEDTLS_CERTS_C
+#define POLARSSL_CERTS_C MBEDTLS_CERTS_C
+#endif
+#if defined MBEDTLS_CIPHER_C
+#define POLARSSL_CIPHER_C MBEDTLS_CIPHER_C
+#endif
+#if defined MBEDTLS_CIPHER_MODE_CBC
+#define POLARSSL_CIPHER_MODE_CBC MBEDTLS_CIPHER_MODE_CBC
+#endif
+#if defined MBEDTLS_CIPHER_MODE_CFB
+#define POLARSSL_CIPHER_MODE_CFB MBEDTLS_CIPHER_MODE_CFB
+#endif
+#if defined MBEDTLS_CIPHER_MODE_CTR
+#define POLARSSL_CIPHER_MODE_CTR MBEDTLS_CIPHER_MODE_CTR
+#endif
+#if defined MBEDTLS_CIPHER_NULL_CIPHER
+#define POLARSSL_CIPHER_NULL_CIPHER MBEDTLS_CIPHER_NULL_CIPHER
+#endif
+#if defined MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
+#define POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
+#endif
+#if defined MBEDTLS_CIPHER_PADDING_PKCS7
+#define POLARSSL_CIPHER_PADDING_PKCS7 MBEDTLS_CIPHER_PADDING_PKCS7
+#endif
+#if defined MBEDTLS_CIPHER_PADDING_ZEROS
+#define POLARSSL_CIPHER_PADDING_ZEROS MBEDTLS_CIPHER_PADDING_ZEROS
+#endif
+#if defined MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
+#define POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
+#endif
+#if defined MBEDTLS_CTR_DRBG_C
+#define POLARSSL_CTR_DRBG_C MBEDTLS_CTR_DRBG_C
+#endif
+#if defined MBEDTLS_DEBUG_C
+#define POLARSSL_DEBUG_C MBEDTLS_DEBUG_C
+#endif
+#if defined MBEDTLS_DEPRECATED_REMOVED
+#define POLARSSL_DEPRECATED_REMOVED MBEDTLS_DEPRECATED_REMOVED
+#endif
+#if defined MBEDTLS_DEPRECATED_WARNING
+#define POLARSSL_DEPRECATED_WARNING MBEDTLS_DEPRECATED_WARNING
+#endif
+#if defined MBEDTLS_DES_ALT
+#define POLARSSL_DES_ALT MBEDTLS_DES_ALT
+#endif
+#if defined MBEDTLS_DES_C
+#define POLARSSL_DES_C MBEDTLS_DES_C
+#endif
+#if defined MBEDTLS_DHM_C
+#define POLARSSL_DHM_C MBEDTLS_DHM_C
+#endif
+#if defined MBEDTLS_ECDH_C
+#define POLARSSL_ECDH_C MBEDTLS_ECDH_C
+#endif
+#if defined MBEDTLS_ECDSA_C
+#define POLARSSL_ECDSA_C MBEDTLS_ECDSA_C
+#endif
+#if defined MBEDTLS_ECDSA_DETERMINISTIC
+#define POLARSSL_ECDSA_DETERMINISTIC MBEDTLS_ECDSA_DETERMINISTIC
+#endif
+#if defined MBEDTLS_ECP_C
+#define POLARSSL_ECP_C MBEDTLS_ECP_C
+#endif
+#if defined MBEDTLS_ECP_DP_BP256R1_ENABLED
+#define POLARSSL_ECP_DP_BP256R1_ENABLED MBEDTLS_ECP_DP_BP256R1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_BP384R1_ENABLED
+#define POLARSSL_ECP_DP_BP384R1_ENABLED MBEDTLS_ECP_DP_BP384R1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_BP512R1_ENABLED
+#define POLARSSL_ECP_DP_BP512R1_ENABLED MBEDTLS_ECP_DP_BP512R1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_CURVE25519_ENABLED
+#define POLARSSL_ECP_DP_M255_ENABLED MBEDTLS_ECP_DP_CURVE25519_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_SECP192K1_ENABLED
+#define POLARSSL_ECP_DP_SECP192K1_ENABLED MBEDTLS_ECP_DP_SECP192K1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_SECP192R1_ENABLED
+#define POLARSSL_ECP_DP_SECP192R1_ENABLED MBEDTLS_ECP_DP_SECP192R1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_SECP224K1_ENABLED
+#define POLARSSL_ECP_DP_SECP224K1_ENABLED MBEDTLS_ECP_DP_SECP224K1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_SECP224R1_ENABLED
+#define POLARSSL_ECP_DP_SECP224R1_ENABLED MBEDTLS_ECP_DP_SECP224R1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_SECP256K1_ENABLED
+#define POLARSSL_ECP_DP_SECP256K1_ENABLED MBEDTLS_ECP_DP_SECP256K1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define POLARSSL_ECP_DP_SECP256R1_ENABLED MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#define POLARSSL_ECP_DP_SECP384R1_ENABLED MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#define POLARSSL_ECP_DP_SECP521R1_ENABLED MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#endif
+#if defined MBEDTLS_ECP_FIXED_POINT_OPTIM
+#define POLARSSL_ECP_FIXED_POINT_OPTIM MBEDTLS_ECP_FIXED_POINT_OPTIM
+#endif
+#if defined MBEDTLS_ECP_MAX_BITS
+#define POLARSSL_ECP_MAX_BITS MBEDTLS_ECP_MAX_BITS
+#endif
+#if defined MBEDTLS_ECP_NIST_OPTIM
+#define POLARSSL_ECP_NIST_OPTIM MBEDTLS_ECP_NIST_OPTIM
+#endif
+#if defined MBEDTLS_ECP_WINDOW_SIZE
+#define POLARSSL_ECP_WINDOW_SIZE MBEDTLS_ECP_WINDOW_SIZE
+#endif
+#if defined MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+#define POLARSSL_ENABLE_WEAK_CIPHERSUITES MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+#endif
+#if defined MBEDTLS_ENTROPY_C
+#define POLARSSL_ENTROPY_C MBEDTLS_ENTROPY_C
+#endif
+#if defined MBEDTLS_ENTROPY_FORCE_SHA256
+#define POLARSSL_ENTROPY_FORCE_SHA256 MBEDTLS_ENTROPY_FORCE_SHA256
+#endif
+#if defined MBEDTLS_ERROR_C
+#define POLARSSL_ERROR_C MBEDTLS_ERROR_C
+#endif
+#if defined MBEDTLS_ERROR_STRERROR_DUMMY
+#define POLARSSL_ERROR_STRERROR_DUMMY MBEDTLS_ERROR_STRERROR_DUMMY
+#endif
+#if defined MBEDTLS_FS_IO
+#define POLARSSL_FS_IO MBEDTLS_FS_IO
+#endif
+#if defined MBEDTLS_GCM_C
+#define POLARSSL_GCM_C MBEDTLS_GCM_C
+#endif
+#if defined MBEDTLS_GENPRIME
+#define POLARSSL_GENPRIME MBEDTLS_GENPRIME
+#endif
+#if defined MBEDTLS_HAVEGE_C
+#define POLARSSL_HAVEGE_C MBEDTLS_HAVEGE_C
+#endif
+#if defined MBEDTLS_HAVE_ASM
+#define POLARSSL_HAVE_ASM MBEDTLS_HAVE_ASM
+#endif
+#if defined MBEDTLS_HAVE_SSE2
+#define POLARSSL_HAVE_SSE2 MBEDTLS_HAVE_SSE2
+#endif
+#if defined MBEDTLS_HAVE_TIME
+#define POLARSSL_HAVE_TIME MBEDTLS_HAVE_TIME
+#endif
+#if defined MBEDTLS_HMAC_DRBG_C
+#define POLARSSL_HMAC_DRBG_C MBEDTLS_HMAC_DRBG_C
+#endif
+#if defined MBEDTLS_HMAC_DRBG_MAX_INPUT
+#define POLARSSL_HMAC_DRBG_MAX_INPUT MBEDTLS_HMAC_DRBG_MAX_INPUT
+#endif
+#if defined MBEDTLS_HMAC_DRBG_MAX_REQUEST
+#define POLARSSL_HMAC_DRBG_MAX_REQUEST MBEDTLS_HMAC_DRBG_MAX_REQUEST
+#endif
+#if defined MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT
+#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT
+#endif
+#if defined MBEDTLS_HMAC_DRBG_RESEED_INTERVAL
+#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL MBEDTLS_HMAC_DRBG_RESEED_INTERVAL
+#endif
+#if defined MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+#endif
+#if defined MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+#endif
+#if defined MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+#endif
+#if defined MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+#endif
+#if defined MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+#endif
+#if defined MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+#endif
+#if defined MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+#endif
+#if defined MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+#endif
+#if defined MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+#define POLARSSL_KEY_EXCHANGE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+#endif
+#if defined MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+#endif
+#if defined MBEDTLS_MD2_ALT
+#define POLARSSL_MD2_ALT MBEDTLS_MD2_ALT
+#endif
+#if defined MBEDTLS_MD2_C
+#define POLARSSL_MD2_C MBEDTLS_MD2_C
+#endif
+#if defined MBEDTLS_MD2_PROCESS_ALT
+#define POLARSSL_MD2_PROCESS_ALT MBEDTLS_MD2_PROCESS_ALT
+#endif
+#if defined MBEDTLS_MD4_ALT
+#define POLARSSL_MD4_ALT MBEDTLS_MD4_ALT
+#endif
+#if defined MBEDTLS_MD4_C
+#define POLARSSL_MD4_C MBEDTLS_MD4_C
+#endif
+#if defined MBEDTLS_MD4_PROCESS_ALT
+#define POLARSSL_MD4_PROCESS_ALT MBEDTLS_MD4_PROCESS_ALT
+#endif
+#if defined MBEDTLS_MD5_ALT
+#define POLARSSL_MD5_ALT MBEDTLS_MD5_ALT
+#endif
+#if defined MBEDTLS_MD5_C
+#define POLARSSL_MD5_C MBEDTLS_MD5_C
+#endif
+#if defined MBEDTLS_MD5_PROCESS_ALT
+#define POLARSSL_MD5_PROCESS_ALT MBEDTLS_MD5_PROCESS_ALT
+#endif
+#if defined MBEDTLS_MD_C
+#define POLARSSL_MD_C MBEDTLS_MD_C
+#endif
+#if defined MBEDTLS_MEMORY_ALIGN_MULTIPLE
+#define POLARSSL_MEMORY_ALIGN_MULTIPLE MBEDTLS_MEMORY_ALIGN_MULTIPLE
+#endif
+#if defined MBEDTLS_MEMORY_BACKTRACE
+#define POLARSSL_MEMORY_BACKTRACE MBEDTLS_MEMORY_BACKTRACE
+#endif
+#if defined MBEDTLS_MEMORY_BUFFER_ALLOC_C
+#define POLARSSL_MEMORY_BUFFER_ALLOC_C MBEDTLS_MEMORY_BUFFER_ALLOC_C
+#endif
+#if defined MBEDTLS_MEMORY_DEBUG
+#define POLARSSL_MEMORY_DEBUG MBEDTLS_MEMORY_DEBUG
+#endif
+#if defined MBEDTLS_MPI_MAX_SIZE
+#define POLARSSL_MPI_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
+#endif
+#if defined MBEDTLS_MPI_WINDOW_SIZE
+#define POLARSSL_MPI_WINDOW_SIZE MBEDTLS_MPI_WINDOW_SIZE
+#endif
+#if defined MBEDTLS_NET_C
+#define POLARSSL_NET_C MBEDTLS_NET_C
+#endif
+#if defined MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+#endif
+#if defined MBEDTLS_NO_PLATFORM_ENTROPY
+#define POLARSSL_NO_PLATFORM_ENTROPY MBEDTLS_NO_PLATFORM_ENTROPY
+#endif
+#if defined MBEDTLS_OID_C
+#define POLARSSL_OID_C MBEDTLS_OID_C
+#endif
+#if defined MBEDTLS_PADLOCK_C
+#define POLARSSL_PADLOCK_C MBEDTLS_PADLOCK_C
+#endif
+#if defined MBEDTLS_PEM_PARSE_C
+#define POLARSSL_PEM_PARSE_C MBEDTLS_PEM_PARSE_C
+#endif
+#if defined MBEDTLS_PEM_WRITE_C
+#define POLARSSL_PEM_WRITE_C MBEDTLS_PEM_WRITE_C
+#endif
+#if defined MBEDTLS_PKCS11_C
+#define POLARSSL_PKCS11_C MBEDTLS_PKCS11_C
+#endif
+#if defined MBEDTLS_PKCS12_C
+#define POLARSSL_PKCS12_C MBEDTLS_PKCS12_C
+#endif
+#if defined MBEDTLS_PKCS1_V15
+#define POLARSSL_PKCS1_V15 MBEDTLS_PKCS1_V15
+#endif
+#if defined MBEDTLS_PKCS1_V21
+#define POLARSSL_PKCS1_V21 MBEDTLS_PKCS1_V21
+#endif
+#if defined MBEDTLS_PKCS5_C
+#define POLARSSL_PKCS5_C MBEDTLS_PKCS5_C
+#endif
+#if defined MBEDTLS_PK_C
+#define POLARSSL_PK_C MBEDTLS_PK_C
+#endif
+#if defined MBEDTLS_PK_PARSE_C
+#define POLARSSL_PK_PARSE_C MBEDTLS_PK_PARSE_C
+#endif
+#if defined MBEDTLS_PK_PARSE_EC_EXTENDED
+#define POLARSSL_PK_PARSE_EC_EXTENDED MBEDTLS_PK_PARSE_EC_EXTENDED
+#endif
+#if defined MBEDTLS_PK_RSA_ALT_SUPPORT
+#define POLARSSL_PK_RSA_ALT_SUPPORT MBEDTLS_PK_RSA_ALT_SUPPORT
+#endif
+#if defined MBEDTLS_PK_WRITE_C
+#define POLARSSL_PK_WRITE_C MBEDTLS_PK_WRITE_C
+#endif
+#if defined MBEDTLS_PLATFORM_C
+#define POLARSSL_PLATFORM_C MBEDTLS_PLATFORM_C
+#endif
+#if defined MBEDTLS_PLATFORM_EXIT_ALT
+#define POLARSSL_PLATFORM_EXIT_ALT MBEDTLS_PLATFORM_EXIT_ALT
+#endif
+#if defined MBEDTLS_PLATFORM_EXIT_MACRO
+#define POLARSSL_PLATFORM_EXIT_MACRO MBEDTLS_PLATFORM_EXIT_MACRO
+#endif
+#if defined MBEDTLS_PLATFORM_FPRINTF_ALT
+#define POLARSSL_PLATFORM_FPRINTF_ALT MBEDTLS_PLATFORM_FPRINTF_ALT
+#endif
+#if defined MBEDTLS_PLATFORM_FPRINTF_MACRO
+#define POLARSSL_PLATFORM_FPRINTF_MACRO MBEDTLS_PLATFORM_FPRINTF_MACRO
+#endif
+#if defined MBEDTLS_PLATFORM_FREE_MACRO
+#define POLARSSL_PLATFORM_FREE_MACRO MBEDTLS_PLATFORM_FREE_MACRO
+#endif
+#if defined MBEDTLS_PLATFORM_MEMORY
+#define POLARSSL_PLATFORM_MEMORY MBEDTLS_PLATFORM_MEMORY
+#endif
+#if defined MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+#endif
+#if defined MBEDTLS_PLATFORM_PRINTF_ALT
+#define POLARSSL_PLATFORM_PRINTF_ALT MBEDTLS_PLATFORM_PRINTF_ALT
+#endif
+#if defined MBEDTLS_PLATFORM_PRINTF_MACRO
+#define POLARSSL_PLATFORM_PRINTF_MACRO MBEDTLS_PLATFORM_PRINTF_MACRO
+#endif
+#if defined MBEDTLS_PLATFORM_SNPRINTF_ALT
+#define POLARSSL_PLATFORM_SNPRINTF_ALT MBEDTLS_PLATFORM_SNPRINTF_ALT
+#endif
+#if defined MBEDTLS_PLATFORM_SNPRINTF_MACRO
+#define POLARSSL_PLATFORM_SNPRINTF_MACRO MBEDTLS_PLATFORM_SNPRINTF_MACRO
+#endif
+#if defined MBEDTLS_PLATFORM_STD_EXIT
+#define POLARSSL_PLATFORM_STD_EXIT MBEDTLS_PLATFORM_STD_EXIT
+#endif
+#if defined MBEDTLS_PLATFORM_STD_FPRINTF
+#define POLARSSL_PLATFORM_STD_FPRINTF MBEDTLS_PLATFORM_STD_FPRINTF
+#endif
+#if defined MBEDTLS_PLATFORM_STD_FREE
+#define POLARSSL_PLATFORM_STD_FREE MBEDTLS_PLATFORM_STD_FREE
+#endif
+#if defined MBEDTLS_PLATFORM_STD_MEM_HDR
+#define POLARSSL_PLATFORM_STD_MEM_HDR MBEDTLS_PLATFORM_STD_MEM_HDR
+#endif
+#if defined MBEDTLS_PLATFORM_STD_PRINTF
+#define POLARSSL_PLATFORM_STD_PRINTF MBEDTLS_PLATFORM_STD_PRINTF
+#endif
+#if defined MBEDTLS_PLATFORM_STD_SNPRINTF
+#define POLARSSL_PLATFORM_STD_SNPRINTF MBEDTLS_PLATFORM_STD_SNPRINTF
+#endif
+#if defined MBEDTLS_PSK_MAX_LEN
+#define POLARSSL_PSK_MAX_LEN MBEDTLS_PSK_MAX_LEN
+#endif
+#if defined MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+#define POLARSSL_REMOVE_ARC4_CIPHERSUITES MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+#endif
+#if defined MBEDTLS_RIPEMD160_ALT
+#define POLARSSL_RIPEMD160_ALT MBEDTLS_RIPEMD160_ALT
+#endif
+#if defined MBEDTLS_RIPEMD160_C
+#define POLARSSL_RIPEMD160_C MBEDTLS_RIPEMD160_C
+#endif
+#if defined MBEDTLS_RIPEMD160_PROCESS_ALT
+#define POLARSSL_RIPEMD160_PROCESS_ALT MBEDTLS_RIPEMD160_PROCESS_ALT
+#endif
+#if defined MBEDTLS_RSA_C
+#define POLARSSL_RSA_C MBEDTLS_RSA_C
+#endif
+#if defined MBEDTLS_RSA_NO_CRT
+#define POLARSSL_RSA_NO_CRT MBEDTLS_RSA_NO_CRT
+#endif
+#if defined MBEDTLS_SELF_TEST
+#define POLARSSL_SELF_TEST MBEDTLS_SELF_TEST
+#endif
+#if defined MBEDTLS_SHA1_ALT
+#define POLARSSL_SHA1_ALT MBEDTLS_SHA1_ALT
+#endif
+#if defined MBEDTLS_SHA1_C
+#define POLARSSL_SHA1_C MBEDTLS_SHA1_C
+#endif
+#if defined MBEDTLS_SHA1_PROCESS_ALT
+#define POLARSSL_SHA1_PROCESS_ALT MBEDTLS_SHA1_PROCESS_ALT
+#endif
+#if defined MBEDTLS_SHA256_ALT
+#define POLARSSL_SHA256_ALT MBEDTLS_SHA256_ALT
+#endif
+#if defined MBEDTLS_SHA256_C
+#define POLARSSL_SHA256_C MBEDTLS_SHA256_C
+#endif
+#if defined MBEDTLS_SHA256_PROCESS_ALT
+#define POLARSSL_SHA256_PROCESS_ALT MBEDTLS_SHA256_PROCESS_ALT
+#endif
+#if defined MBEDTLS_SHA512_ALT
+#define POLARSSL_SHA512_ALT MBEDTLS_SHA512_ALT
+#endif
+#if defined MBEDTLS_SHA512_C
+#define POLARSSL_SHA512_C MBEDTLS_SHA512_C
+#endif
+#if defined MBEDTLS_SHA512_PROCESS_ALT
+#define POLARSSL_SHA512_PROCESS_ALT MBEDTLS_SHA512_PROCESS_ALT
+#endif
+#if defined MBEDTLS_SSL_ALL_ALERT_MESSAGES
+#define POLARSSL_SSL_ALL_ALERT_MESSAGES MBEDTLS_SSL_ALL_ALERT_MESSAGES
+#endif
+#if defined MBEDTLS_SSL_ALPN
+#define POLARSSL_SSL_ALPN MBEDTLS_SSL_ALPN
+#endif
+#if defined MBEDTLS_SSL_CACHE_C
+#define POLARSSL_SSL_CACHE_C MBEDTLS_SSL_CACHE_C
+#endif
+#if defined MBEDTLS_SSL_CBC_RECORD_SPLITTING
+#define POLARSSL_SSL_CBC_RECORD_SPLITTING MBEDTLS_SSL_CBC_RECORD_SPLITTING
+#endif
+#if defined MBEDTLS_SSL_CLI_C
+#define POLARSSL_SSL_CLI_C MBEDTLS_SSL_CLI_C
+#endif
+#if defined MBEDTLS_SSL_COOKIE_C
+#define POLARSSL_SSL_COOKIE_C MBEDTLS_SSL_COOKIE_C
+#endif
+#if defined MBEDTLS_SSL_COOKIE_TIMEOUT
+#define POLARSSL_SSL_COOKIE_TIMEOUT MBEDTLS_SSL_COOKIE_TIMEOUT
+#endif
+#if defined MBEDTLS_SSL_DEBUG_ALL
+#define POLARSSL_SSL_DEBUG_ALL MBEDTLS_SSL_DEBUG_ALL
+#endif
+#if defined MBEDTLS_SSL_DTLS_ANTI_REPLAY
+#define POLARSSL_SSL_DTLS_ANTI_REPLAY MBEDTLS_SSL_DTLS_ANTI_REPLAY
+#endif
+#if defined MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+#define POLARSSL_SSL_DTLS_BADMAC_LIMIT MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+#endif
+#if defined MBEDTLS_SSL_DTLS_HELLO_VERIFY
+#define POLARSSL_SSL_DTLS_HELLO_VERIFY MBEDTLS_SSL_DTLS_HELLO_VERIFY
+#endif
+#if defined MBEDTLS_SSL_ENCRYPT_THEN_MAC
+#define POLARSSL_SSL_ENCRYPT_THEN_MAC MBEDTLS_SSL_ENCRYPT_THEN_MAC
+#endif
+#if defined MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+#define POLARSSL_SSL_EXTENDED_MASTER_SECRET MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+#endif
+#if defined MBEDTLS_SSL_FALLBACK_SCSV
+#define POLARSSL_SSL_FALLBACK_SCSV MBEDTLS_SSL_FALLBACK_SCSV
+#endif
+#if defined MBEDTLS_SSL_HW_RECORD_ACCEL
+#define POLARSSL_SSL_HW_RECORD_ACCEL MBEDTLS_SSL_HW_RECORD_ACCEL
+#endif
+#if defined MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+#endif
+#if defined MBEDTLS_SSL_PROTO_DTLS
+#define POLARSSL_SSL_PROTO_DTLS MBEDTLS_SSL_PROTO_DTLS
+#endif
+#if defined MBEDTLS_SSL_PROTO_SSL3
+#define POLARSSL_SSL_PROTO_SSL3 MBEDTLS_SSL_PROTO_SSL3
+#endif
+#if defined MBEDTLS_SSL_PROTO_TLS1
+#define POLARSSL_SSL_PROTO_TLS1 MBEDTLS_SSL_PROTO_TLS1
+#endif
+#if defined MBEDTLS_SSL_PROTO_TLS1_1
+#define POLARSSL_SSL_PROTO_TLS1_1 MBEDTLS_SSL_PROTO_TLS1_1
+#endif
+#if defined MBEDTLS_SSL_PROTO_TLS1_2
+#define POLARSSL_SSL_PROTO_TLS1_2 MBEDTLS_SSL_PROTO_TLS1_2
+#endif
+#if defined MBEDTLS_SSL_RENEGOTIATION
+#define POLARSSL_SSL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION
+#endif
+#if defined MBEDTLS_SSL_SERVER_NAME_INDICATION
+#define POLARSSL_SSL_SERVER_NAME_INDICATION MBEDTLS_SSL_SERVER_NAME_INDICATION
+#endif
+#if defined MBEDTLS_SSL_SESSION_TICKETS
+#define POLARSSL_SSL_SESSION_TICKETS MBEDTLS_SSL_SESSION_TICKETS
+#endif
+#if defined MBEDTLS_SSL_SRV_C
+#define POLARSSL_SSL_SRV_C MBEDTLS_SSL_SRV_C
+#endif
+#if defined MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+#define POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+#endif
+#if defined MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+#endif
+#if defined MBEDTLS_SSL_TLS_C
+#define POLARSSL_SSL_TLS_C MBEDTLS_SSL_TLS_C
+#endif
+#if defined MBEDTLS_SSL_TRUNCATED_HMAC
+#define POLARSSL_SSL_TRUNCATED_HMAC MBEDTLS_SSL_TRUNCATED_HMAC
+#endif
+#if defined MBEDTLS_THREADING_ALT
+#define POLARSSL_THREADING_ALT MBEDTLS_THREADING_ALT
+#endif
+#if defined MBEDTLS_THREADING_C
+#define POLARSSL_THREADING_C MBEDTLS_THREADING_C
+#endif
+#if defined MBEDTLS_THREADING_PTHREAD
+#define POLARSSL_THREADING_PTHREAD MBEDTLS_THREADING_PTHREAD
+#endif
+#if defined MBEDTLS_TIMING_ALT
+#define POLARSSL_TIMING_ALT MBEDTLS_TIMING_ALT
+#endif
+#if defined MBEDTLS_TIMING_C
+#define POLARSSL_TIMING_C MBEDTLS_TIMING_C
+#endif
+#if defined MBEDTLS_VERSION_C
+#define POLARSSL_VERSION_C MBEDTLS_VERSION_C
+#endif
+#if defined MBEDTLS_VERSION_FEATURES
+#define POLARSSL_VERSION_FEATURES MBEDTLS_VERSION_FEATURES
+#endif
+#if defined MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+#define POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+#endif
+#if defined MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+#endif
+#if defined MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+#endif
+#if defined MBEDTLS_X509_CHECK_KEY_USAGE
+#define POLARSSL_X509_CHECK_KEY_USAGE MBEDTLS_X509_CHECK_KEY_USAGE
+#endif
+#if defined MBEDTLS_X509_CREATE_C
+#define POLARSSL_X509_CREATE_C MBEDTLS_X509_CREATE_C
+#endif
+#if defined MBEDTLS_X509_CRL_PARSE_C
+#define POLARSSL_X509_CRL_PARSE_C MBEDTLS_X509_CRL_PARSE_C
+#endif
+#if defined MBEDTLS_X509_CRT_PARSE_C
+#define POLARSSL_X509_CRT_PARSE_C MBEDTLS_X509_CRT_PARSE_C
+#endif
+#if defined MBEDTLS_X509_CRT_WRITE_C
+#define POLARSSL_X509_CRT_WRITE_C MBEDTLS_X509_CRT_WRITE_C
+#endif
+#if defined MBEDTLS_X509_CSR_PARSE_C
+#define POLARSSL_X509_CSR_PARSE_C MBEDTLS_X509_CSR_PARSE_C
+#endif
+#if defined MBEDTLS_X509_CSR_WRITE_C
+#define POLARSSL_X509_CSR_WRITE_C MBEDTLS_X509_CSR_WRITE_C
+#endif
+#if defined MBEDTLS_X509_MAX_INTERMEDIATE_CA
+#define POLARSSL_X509_MAX_INTERMEDIATE_CA MBEDTLS_X509_MAX_INTERMEDIATE_CA
+#endif
+#if defined MBEDTLS_X509_RSASSA_PSS_SUPPORT
+#define POLARSSL_X509_RSASSA_PSS_SUPPORT MBEDTLS_X509_RSASSA_PSS_SUPPORT
+#endif
+#if defined MBEDTLS_X509_USE_C
+#define POLARSSL_X509_USE_C MBEDTLS_X509_USE_C
+#endif
+#if defined MBEDTLS_XTEA_ALT
+#define POLARSSL_XTEA_ALT MBEDTLS_XTEA_ALT
+#endif
+#if defined MBEDTLS_XTEA_C
+#define POLARSSL_XTEA_C MBEDTLS_XTEA_C
+#endif
+#if defined MBEDTLS_ZLIB_SUPPORT
+#define POLARSSL_ZLIB_SUPPORT MBEDTLS_ZLIB_SUPPORT
+#endif
+
+/*
+ * Misc names (macros, types, functions, enum constants...)
+ */
+#define AES_DECRYPT MBEDTLS_AES_DECRYPT
+#define AES_ENCRYPT MBEDTLS_AES_ENCRYPT
+#define ASN1_BIT_STRING MBEDTLS_ASN1_BIT_STRING
+#define ASN1_BMP_STRING MBEDTLS_ASN1_BMP_STRING
+#define ASN1_BOOLEAN MBEDTLS_ASN1_BOOLEAN
+#define ASN1_CHK_ADD MBEDTLS_ASN1_CHK_ADD
+#define ASN1_CONSTRUCTED MBEDTLS_ASN1_CONSTRUCTED
+#define ASN1_CONTEXT_SPECIFIC MBEDTLS_ASN1_CONTEXT_SPECIFIC
+#define ASN1_GENERALIZED_TIME MBEDTLS_ASN1_GENERALIZED_TIME
+#define ASN1_IA5_STRING MBEDTLS_ASN1_IA5_STRING
+#define ASN1_INTEGER MBEDTLS_ASN1_INTEGER
+#define ASN1_NULL MBEDTLS_ASN1_NULL
+#define ASN1_OCTET_STRING MBEDTLS_ASN1_OCTET_STRING
+#define ASN1_OID MBEDTLS_ASN1_OID
+#define ASN1_PRIMITIVE MBEDTLS_ASN1_PRIMITIVE
+#define ASN1_PRINTABLE_STRING MBEDTLS_ASN1_PRINTABLE_STRING
+#define ASN1_SEQUENCE MBEDTLS_ASN1_SEQUENCE
+#define ASN1_SET MBEDTLS_ASN1_SET
+#define ASN1_T61_STRING MBEDTLS_ASN1_T61_STRING
+#define ASN1_UNIVERSAL_STRING MBEDTLS_ASN1_UNIVERSAL_STRING
+#define ASN1_UTC_TIME MBEDTLS_ASN1_UTC_TIME
+#define ASN1_UTF8_STRING MBEDTLS_ASN1_UTF8_STRING
+#define BADCERT_CN_MISMATCH MBEDTLS_X509_BADCERT_CN_MISMATCH
+#define BADCERT_EXPIRED MBEDTLS_X509_BADCERT_EXPIRED
+#define BADCERT_FUTURE MBEDTLS_X509_BADCERT_FUTURE
+#define BADCERT_MISSING MBEDTLS_X509_BADCERT_MISSING
+#define BADCERT_NOT_TRUSTED MBEDTLS_X509_BADCERT_NOT_TRUSTED
+#define BADCERT_OTHER MBEDTLS_X509_BADCERT_OTHER
+#define BADCERT_REVOKED MBEDTLS_X509_BADCERT_REVOKED
+#define BADCERT_SKIP_VERIFY MBEDTLS_X509_BADCERT_SKIP_VERIFY
+#define BADCRL_EXPIRED MBEDTLS_X509_BADCRL_EXPIRED
+#define BADCRL_FUTURE MBEDTLS_X509_BADCRL_FUTURE
+#define BADCRL_NOT_TRUSTED MBEDTLS_X509_BADCRL_NOT_TRUSTED
+#define BLOWFISH_BLOCKSIZE MBEDTLS_BLOWFISH_BLOCKSIZE
+#define BLOWFISH_DECRYPT MBEDTLS_BLOWFISH_DECRYPT
+#define BLOWFISH_ENCRYPT MBEDTLS_BLOWFISH_ENCRYPT
+#define BLOWFISH_MAX_KEY MBEDTLS_BLOWFISH_MAX_KEY_BITS
+#define BLOWFISH_MIN_KEY MBEDTLS_BLOWFISH_MIN_KEY_BITS
+#define BLOWFISH_ROUNDS MBEDTLS_BLOWFISH_ROUNDS
+#define CAMELLIA_DECRYPT MBEDTLS_CAMELLIA_DECRYPT
+#define CAMELLIA_ENCRYPT MBEDTLS_CAMELLIA_ENCRYPT
+#define COLLECT_SIZE MBEDTLS_HAVEGE_COLLECT_SIZE
+#define CTR_DRBG_BLOCKSIZE MBEDTLS_CTR_DRBG_BLOCKSIZE
+#define CTR_DRBG_ENTROPY_LEN MBEDTLS_CTR_DRBG_ENTROPY_LEN
+#define CTR_DRBG_KEYBITS MBEDTLS_CTR_DRBG_KEYBITS
+#define CTR_DRBG_KEYSIZE MBEDTLS_CTR_DRBG_KEYSIZE
+#define CTR_DRBG_MAX_INPUT MBEDTLS_CTR_DRBG_MAX_INPUT
+#define CTR_DRBG_MAX_REQUEST MBEDTLS_CTR_DRBG_MAX_REQUEST
+#define CTR_DRBG_MAX_SEED_INPUT MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
+#define CTR_DRBG_PR_OFF MBEDTLS_CTR_DRBG_PR_OFF
+#define CTR_DRBG_PR_ON MBEDTLS_CTR_DRBG_PR_ON
+#define CTR_DRBG_RESEED_INTERVAL MBEDTLS_CTR_DRBG_RESEED_INTERVAL
+#define CTR_DRBG_SEEDLEN MBEDTLS_CTR_DRBG_SEEDLEN
+#define DEPRECATED MBEDTLS_DEPRECATED
+#define DES_DECRYPT MBEDTLS_DES_DECRYPT
+#define DES_ENCRYPT MBEDTLS_DES_ENCRYPT
+#define DES_KEY_SIZE MBEDTLS_DES_KEY_SIZE
+#define ENTROPY_BLOCK_SIZE MBEDTLS_ENTROPY_BLOCK_SIZE
+#define ENTROPY_MAX_GATHER MBEDTLS_ENTROPY_MAX_GATHER
+#define ENTROPY_MAX_SEED_SIZE MBEDTLS_ENTROPY_MAX_SEED_SIZE
+#define ENTROPY_MAX_SOURCES MBEDTLS_ENTROPY_MAX_SOURCES
+#define ENTROPY_MIN_HARDCLOCK MBEDTLS_ENTROPY_MIN_HARDCLOCK
+#define ENTROPY_MIN_HAVEGE MBEDTLS_ENTROPY_MIN_HAVEGE
+#define ENTROPY_MIN_PLATFORM MBEDTLS_ENTROPY_MIN_PLATFORM
+#define ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_SOURCE_MANUAL
+#define EXT_AUTHORITY_KEY_IDENTIFIER MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER
+#define EXT_BASIC_CONSTRAINTS MBEDTLS_X509_EXT_BASIC_CONSTRAINTS
+#define EXT_CERTIFICATE_POLICIES MBEDTLS_X509_EXT_CERTIFICATE_POLICIES
+#define EXT_CRL_DISTRIBUTION_POINTS MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS
+#define EXT_EXTENDED_KEY_USAGE MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE
+#define EXT_FRESHEST_CRL MBEDTLS_X509_EXT_FRESHEST_CRL
+#define EXT_INIHIBIT_ANYPOLICY MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY
+#define EXT_ISSUER_ALT_NAME MBEDTLS_X509_EXT_ISSUER_ALT_NAME
+#define EXT_KEY_USAGE MBEDTLS_X509_EXT_KEY_USAGE
+#define EXT_NAME_CONSTRAINTS MBEDTLS_X509_EXT_NAME_CONSTRAINTS
+#define EXT_NS_CERT_TYPE MBEDTLS_X509_EXT_NS_CERT_TYPE
+#define EXT_POLICY_CONSTRAINTS MBEDTLS_X509_EXT_POLICY_CONSTRAINTS
+#define EXT_POLICY_MAPPINGS MBEDTLS_X509_EXT_POLICY_MAPPINGS
+#define EXT_SUBJECT_ALT_NAME MBEDTLS_X509_EXT_SUBJECT_ALT_NAME
+#define EXT_SUBJECT_DIRECTORY_ATTRS MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS
+#define EXT_SUBJECT_KEY_IDENTIFIER MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER
+#define GCM_DECRYPT MBEDTLS_GCM_DECRYPT
+#define GCM_ENCRYPT MBEDTLS_GCM_ENCRYPT
+#define KU_CRL_SIGN MBEDTLS_X509_KU_CRL_SIGN
+#define KU_DATA_ENCIPHERMENT MBEDTLS_X509_KU_DATA_ENCIPHERMENT
+#define KU_DIGITAL_SIGNATURE MBEDTLS_X509_KU_DIGITAL_SIGNATURE
+#define KU_KEY_AGREEMENT MBEDTLS_X509_KU_KEY_AGREEMENT
+#define KU_KEY_CERT_SIGN MBEDTLS_X509_KU_KEY_CERT_SIGN
+#define KU_KEY_ENCIPHERMENT MBEDTLS_X509_KU_KEY_ENCIPHERMENT
+#define KU_NON_REPUDIATION MBEDTLS_X509_KU_NON_REPUDIATION
+#define LN_2_DIV_LN_10_SCALE100 MBEDTLS_LN_2_DIV_LN_10_SCALE100
+#define MEMORY_VERIFY_ALLOC MBEDTLS_MEMORY_VERIFY_ALLOC
+#define MEMORY_VERIFY_ALWAYS MBEDTLS_MEMORY_VERIFY_ALWAYS
+#define MEMORY_VERIFY_FREE MBEDTLS_MEMORY_VERIFY_FREE
+#define MEMORY_VERIFY_NONE MBEDTLS_MEMORY_VERIFY_NONE
+#define MPI_CHK MBEDTLS_MPI_CHK
+#define NET_PROTO_TCP MBEDTLS_NET_PROTO_TCP
+#define NET_PROTO_UDP MBEDTLS_NET_PROTO_UDP
+#define NS_CERT_TYPE_EMAIL MBEDTLS_X509_NS_CERT_TYPE_EMAIL
+#define NS_CERT_TYPE_EMAIL_CA MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA
+#define NS_CERT_TYPE_OBJECT_SIGNING MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING
+#define NS_CERT_TYPE_OBJECT_SIGNING_CA MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA
+#define NS_CERT_TYPE_RESERVED MBEDTLS_X509_NS_CERT_TYPE_RESERVED
+#define NS_CERT_TYPE_SSL_CA MBEDTLS_X509_NS_CERT_TYPE_SSL_CA
+#define NS_CERT_TYPE_SSL_CLIENT MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT
+#define NS_CERT_TYPE_SSL_SERVER MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER
+#define OID_ANSI_X9_62 MBEDTLS_OID_ANSI_X9_62
+#define OID_ANSI_X9_62_FIELD_TYPE MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE
+#define OID_ANSI_X9_62_PRIME_FIELD MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD
+#define OID_ANSI_X9_62_SIG MBEDTLS_OID_ANSI_X9_62_SIG
+#define OID_ANSI_X9_62_SIG_SHA2 MBEDTLS_OID_ANSI_X9_62_SIG_SHA2
+#define OID_ANY_EXTENDED_KEY_USAGE MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE
+#define OID_AT MBEDTLS_OID_AT
+#define OID_AT_CN MBEDTLS_OID_AT_CN
+#define OID_AT_COUNTRY MBEDTLS_OID_AT_COUNTRY
+#define OID_AT_DN_QUALIFIER MBEDTLS_OID_AT_DN_QUALIFIER
+#define OID_AT_GENERATION_QUALIFIER MBEDTLS_OID_AT_GENERATION_QUALIFIER
+#define OID_AT_GIVEN_NAME MBEDTLS_OID_AT_GIVEN_NAME
+#define OID_AT_INITIALS MBEDTLS_OID_AT_INITIALS
+#define OID_AT_LOCALITY MBEDTLS_OID_AT_LOCALITY
+#define OID_AT_ORGANIZATION MBEDTLS_OID_AT_ORGANIZATION
+#define OID_AT_ORG_UNIT MBEDTLS_OID_AT_ORG_UNIT
+#define OID_AT_POSTAL_ADDRESS MBEDTLS_OID_AT_POSTAL_ADDRESS
+#define OID_AT_POSTAL_CODE MBEDTLS_OID_AT_POSTAL_CODE
+#define OID_AT_PSEUDONYM MBEDTLS_OID_AT_PSEUDONYM
+#define OID_AT_SERIAL_NUMBER MBEDTLS_OID_AT_SERIAL_NUMBER
+#define OID_AT_STATE MBEDTLS_OID_AT_STATE
+#define OID_AT_SUR_NAME MBEDTLS_OID_AT_SUR_NAME
+#define OID_AT_TITLE MBEDTLS_OID_AT_TITLE
+#define OID_AT_UNIQUE_IDENTIFIER MBEDTLS_OID_AT_UNIQUE_IDENTIFIER
+#define OID_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER
+#define OID_BASIC_CONSTRAINTS MBEDTLS_OID_BASIC_CONSTRAINTS
+#define OID_CERTICOM MBEDTLS_OID_CERTICOM
+#define OID_CERTIFICATE_POLICIES MBEDTLS_OID_CERTIFICATE_POLICIES
+#define OID_CLIENT_AUTH MBEDTLS_OID_CLIENT_AUTH
+#define OID_CMP MBEDTLS_OID_CMP
+#define OID_CODE_SIGNING MBEDTLS_OID_CODE_SIGNING
+#define OID_COUNTRY_US MBEDTLS_OID_COUNTRY_US
+#define OID_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_CRL_DISTRIBUTION_POINTS
+#define OID_CRL_NUMBER MBEDTLS_OID_CRL_NUMBER
+#define OID_DES_CBC MBEDTLS_OID_DES_CBC
+#define OID_DES_EDE3_CBC MBEDTLS_OID_DES_EDE3_CBC
+#define OID_DIGEST_ALG_MD2 MBEDTLS_OID_DIGEST_ALG_MD2
+#define OID_DIGEST_ALG_MD4 MBEDTLS_OID_DIGEST_ALG_MD4
+#define OID_DIGEST_ALG_MD5 MBEDTLS_OID_DIGEST_ALG_MD5
+#define OID_DIGEST_ALG_SHA1 MBEDTLS_OID_DIGEST_ALG_SHA1
+#define OID_DIGEST_ALG_SHA224 MBEDTLS_OID_DIGEST_ALG_SHA224
+#define OID_DIGEST_ALG_SHA256 MBEDTLS_OID_DIGEST_ALG_SHA256
+#define OID_DIGEST_ALG_SHA384 MBEDTLS_OID_DIGEST_ALG_SHA384
+#define OID_DIGEST_ALG_SHA512 MBEDTLS_OID_DIGEST_ALG_SHA512
+#define OID_DOMAIN_COMPONENT MBEDTLS_OID_DOMAIN_COMPONENT
+#define OID_ECDSA_SHA1 MBEDTLS_OID_ECDSA_SHA1
+#define OID_ECDSA_SHA224 MBEDTLS_OID_ECDSA_SHA224
+#define OID_ECDSA_SHA256 MBEDTLS_OID_ECDSA_SHA256
+#define OID_ECDSA_SHA384 MBEDTLS_OID_ECDSA_SHA384
+#define OID_ECDSA_SHA512 MBEDTLS_OID_ECDSA_SHA512
+#define OID_EC_ALG_ECDH MBEDTLS_OID_EC_ALG_ECDH
+#define OID_EC_ALG_UNRESTRICTED MBEDTLS_OID_EC_ALG_UNRESTRICTED
+#define OID_EC_BRAINPOOL_V1 MBEDTLS_OID_EC_BRAINPOOL_V1
+#define OID_EC_GRP_BP256R1 MBEDTLS_OID_EC_GRP_BP256R1
+#define OID_EC_GRP_BP384R1 MBEDTLS_OID_EC_GRP_BP384R1
+#define OID_EC_GRP_BP512R1 MBEDTLS_OID_EC_GRP_BP512R1
+#define OID_EC_GRP_SECP192K1 MBEDTLS_OID_EC_GRP_SECP192K1
+#define OID_EC_GRP_SECP192R1 MBEDTLS_OID_EC_GRP_SECP192R1
+#define OID_EC_GRP_SECP224K1 MBEDTLS_OID_EC_GRP_SECP224K1
+#define OID_EC_GRP_SECP224R1 MBEDTLS_OID_EC_GRP_SECP224R1
+#define OID_EC_GRP_SECP256K1 MBEDTLS_OID_EC_GRP_SECP256K1
+#define OID_EC_GRP_SECP256R1 MBEDTLS_OID_EC_GRP_SECP256R1
+#define OID_EC_GRP_SECP384R1 MBEDTLS_OID_EC_GRP_SECP384R1
+#define OID_EC_GRP_SECP521R1 MBEDTLS_OID_EC_GRP_SECP521R1
+#define OID_EMAIL_PROTECTION MBEDTLS_OID_EMAIL_PROTECTION
+#define OID_EXTENDED_KEY_USAGE MBEDTLS_OID_EXTENDED_KEY_USAGE
+#define OID_FRESHEST_CRL MBEDTLS_OID_FRESHEST_CRL
+#define OID_GOV MBEDTLS_OID_GOV
+#define OID_HMAC_SHA1 MBEDTLS_OID_HMAC_SHA1
+#define OID_ID_CE MBEDTLS_OID_ID_CE
+#define OID_INIHIBIT_ANYPOLICY MBEDTLS_OID_INIHIBIT_ANYPOLICY
+#define OID_ISO_CCITT_DS MBEDTLS_OID_ISO_CCITT_DS
+#define OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ISO_IDENTIFIED_ORG
+#define OID_ISO_ITU_COUNTRY MBEDTLS_OID_ISO_ITU_COUNTRY
+#define OID_ISO_ITU_US_ORG MBEDTLS_OID_ISO_ITU_US_ORG
+#define OID_ISO_MEMBER_BODIES MBEDTLS_OID_ISO_MEMBER_BODIES
+#define OID_ISSUER_ALT_NAME MBEDTLS_OID_ISSUER_ALT_NAME
+#define OID_KEY_USAGE MBEDTLS_OID_KEY_USAGE
+#define OID_KP MBEDTLS_OID_KP
+#define OID_MGF1 MBEDTLS_OID_MGF1
+#define OID_NAME_CONSTRAINTS MBEDTLS_OID_NAME_CONSTRAINTS
+#define OID_NETSCAPE MBEDTLS_OID_NETSCAPE
+#define OID_NS_BASE_URL MBEDTLS_OID_NS_BASE_URL
+#define OID_NS_CA_POLICY_URL MBEDTLS_OID_NS_CA_POLICY_URL
+#define OID_NS_CA_REVOCATION_URL MBEDTLS_OID_NS_CA_REVOCATION_URL
+#define OID_NS_CERT MBEDTLS_OID_NS_CERT
+#define OID_NS_CERT_SEQUENCE MBEDTLS_OID_NS_CERT_SEQUENCE
+#define OID_NS_CERT_TYPE MBEDTLS_OID_NS_CERT_TYPE
+#define OID_NS_COMMENT MBEDTLS_OID_NS_COMMENT
+#define OID_NS_DATA_TYPE MBEDTLS_OID_NS_DATA_TYPE
+#define OID_NS_RENEWAL_URL MBEDTLS_OID_NS_RENEWAL_URL
+#define OID_NS_REVOCATION_URL MBEDTLS_OID_NS_REVOCATION_URL
+#define OID_NS_SSL_SERVER_NAME MBEDTLS_OID_NS_SSL_SERVER_NAME
+#define OID_OCSP_SIGNING MBEDTLS_OID_OCSP_SIGNING
+#define OID_OIW_SECSIG MBEDTLS_OID_OIW_SECSIG
+#define OID_OIW_SECSIG_ALG MBEDTLS_OID_OIW_SECSIG_ALG
+#define OID_OIW_SECSIG_SHA1 MBEDTLS_OID_OIW_SECSIG_SHA1
+#define OID_ORGANIZATION MBEDTLS_OID_ORGANIZATION
+#define OID_ORG_ANSI_X9_62 MBEDTLS_OID_ORG_ANSI_X9_62
+#define OID_ORG_CERTICOM MBEDTLS_OID_ORG_CERTICOM
+#define OID_ORG_DOD MBEDTLS_OID_ORG_DOD
+#define OID_ORG_GOV MBEDTLS_OID_ORG_GOV
+#define OID_ORG_NETSCAPE MBEDTLS_OID_ORG_NETSCAPE
+#define OID_ORG_OIW MBEDTLS_OID_ORG_OIW
+#define OID_ORG_RSA_DATA_SECURITY MBEDTLS_OID_ORG_RSA_DATA_SECURITY
+#define OID_ORG_TELETRUST MBEDTLS_OID_ORG_TELETRUST
+#define OID_PKCS MBEDTLS_OID_PKCS
+#define OID_PKCS1 MBEDTLS_OID_PKCS1
+#define OID_PKCS12 MBEDTLS_OID_PKCS12
+#define OID_PKCS12_PBE MBEDTLS_OID_PKCS12_PBE
+#define OID_PKCS12_PBE_SHA1_DES2_EDE_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC
+#define OID_PKCS12_PBE_SHA1_DES3_EDE_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC
+#define OID_PKCS12_PBE_SHA1_RC2_128_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC
+#define OID_PKCS12_PBE_SHA1_RC2_40_CBC MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_40_CBC
+#define OID_PKCS12_PBE_SHA1_RC4_128 MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128
+#define OID_PKCS12_PBE_SHA1_RC4_40 MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_40
+#define OID_PKCS1_MD2 MBEDTLS_OID_PKCS1_MD2
+#define OID_PKCS1_MD4 MBEDTLS_OID_PKCS1_MD4
+#define OID_PKCS1_MD5 MBEDTLS_OID_PKCS1_MD5
+#define OID_PKCS1_RSA MBEDTLS_OID_PKCS1_RSA
+#define OID_PKCS1_SHA1 MBEDTLS_OID_PKCS1_SHA1
+#define OID_PKCS1_SHA224 MBEDTLS_OID_PKCS1_SHA224
+#define OID_PKCS1_SHA256 MBEDTLS_OID_PKCS1_SHA256
+#define OID_PKCS1_SHA384 MBEDTLS_OID_PKCS1_SHA384
+#define OID_PKCS1_SHA512 MBEDTLS_OID_PKCS1_SHA512
+#define OID_PKCS5 MBEDTLS_OID_PKCS5
+#define OID_PKCS5_PBES2 MBEDTLS_OID_PKCS5_PBES2
+#define OID_PKCS5_PBE_MD2_DES_CBC MBEDTLS_OID_PKCS5_PBE_MD2_DES_CBC
+#define OID_PKCS5_PBE_MD2_RC2_CBC MBEDTLS_OID_PKCS5_PBE_MD2_RC2_CBC
+#define OID_PKCS5_PBE_MD5_DES_CBC MBEDTLS_OID_PKCS5_PBE_MD5_DES_CBC
+#define OID_PKCS5_PBE_MD5_RC2_CBC MBEDTLS_OID_PKCS5_PBE_MD5_RC2_CBC
+#define OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC
+#define OID_PKCS5_PBE_SHA1_RC2_CBC MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC
+#define OID_PKCS5_PBKDF2 MBEDTLS_OID_PKCS5_PBKDF2
+#define OID_PKCS5_PBMAC1 MBEDTLS_OID_PKCS5_PBMAC1
+#define OID_PKCS9 MBEDTLS_OID_PKCS9
+#define OID_PKCS9_CSR_EXT_REQ MBEDTLS_OID_PKCS9_CSR_EXT_REQ
+#define OID_PKCS9_EMAIL MBEDTLS_OID_PKCS9_EMAIL
+#define OID_PKIX MBEDTLS_OID_PKIX
+#define OID_POLICY_CONSTRAINTS MBEDTLS_OID_POLICY_CONSTRAINTS
+#define OID_POLICY_MAPPINGS MBEDTLS_OID_POLICY_MAPPINGS
+#define OID_PRIVATE_KEY_USAGE_PERIOD MBEDTLS_OID_PRIVATE_KEY_USAGE_PERIOD
+#define OID_RSASSA_PSS MBEDTLS_OID_RSASSA_PSS
+#define OID_RSA_COMPANY MBEDTLS_OID_RSA_COMPANY
+#define OID_RSA_SHA_OBS MBEDTLS_OID_RSA_SHA_OBS
+#define OID_SERVER_AUTH MBEDTLS_OID_SERVER_AUTH
+#define OID_SIZE MBEDTLS_OID_SIZE
+#define OID_SUBJECT_ALT_NAME MBEDTLS_OID_SUBJECT_ALT_NAME
+#define OID_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_SUBJECT_DIRECTORY_ATTRS
+#define OID_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER
+#define OID_TELETRUST MBEDTLS_OID_TELETRUST
+#define OID_TIME_STAMPING MBEDTLS_OID_TIME_STAMPING
+#define PADLOCK_ACE MBEDTLS_PADLOCK_ACE
+#define PADLOCK_ALIGN16 MBEDTLS_PADLOCK_ALIGN16
+#define PADLOCK_PHE MBEDTLS_PADLOCK_PHE
+#define PADLOCK_PMM MBEDTLS_PADLOCK_PMM
+#define PADLOCK_RNG MBEDTLS_PADLOCK_RNG
+#define PKCS12_DERIVE_IV MBEDTLS_PKCS12_DERIVE_IV
+#define PKCS12_DERIVE_KEY MBEDTLS_PKCS12_DERIVE_KEY
+#define PKCS12_DERIVE_MAC_KEY MBEDTLS_PKCS12_DERIVE_MAC_KEY
+#define PKCS12_PBE_DECRYPT MBEDTLS_PKCS12_PBE_DECRYPT
+#define PKCS12_PBE_ENCRYPT MBEDTLS_PKCS12_PBE_ENCRYPT
+#define PKCS5_DECRYPT MBEDTLS_PKCS5_DECRYPT
+#define PKCS5_ENCRYPT MBEDTLS_PKCS5_ENCRYPT
+#define POLARSSL_AESNI_AES MBEDTLS_AESNI_AES
+#define POLARSSL_AESNI_CLMUL MBEDTLS_AESNI_CLMUL
+#define POLARSSL_AESNI_H MBEDTLS_AESNI_H
+#define POLARSSL_AES_H MBEDTLS_AES_H
+#define POLARSSL_ARC4_H MBEDTLS_ARC4_H
+#define POLARSSL_ASN1_H MBEDTLS_ASN1_H
+#define POLARSSL_ASN1_WRITE_H MBEDTLS_ASN1_WRITE_H
+#define POLARSSL_BASE64_H MBEDTLS_BASE64_H
+#define POLARSSL_BIGNUM_H MBEDTLS_BIGNUM_H
+#define POLARSSL_BLOWFISH_H MBEDTLS_BLOWFISH_H
+#define POLARSSL_BN_MUL_H MBEDTLS_BN_MUL_H
+#define POLARSSL_CAMELLIA_H MBEDTLS_CAMELLIA_H
+#define POLARSSL_CCM_H MBEDTLS_CCM_H
+#define POLARSSL_CERTS_H MBEDTLS_CERTS_H
+#define POLARSSL_CHECK_CONFIG_H MBEDTLS_CHECK_CONFIG_H
+#define POLARSSL_CIPHERSUITE_NODTLS MBEDTLS_CIPHERSUITE_NODTLS
+#define POLARSSL_CIPHERSUITE_SHORT_TAG MBEDTLS_CIPHERSUITE_SHORT_TAG
+#define POLARSSL_CIPHERSUITE_WEAK MBEDTLS_CIPHERSUITE_WEAK
+#define POLARSSL_CIPHER_AES_128_CBC MBEDTLS_CIPHER_AES_128_CBC
+#define POLARSSL_CIPHER_AES_128_CCM MBEDTLS_CIPHER_AES_128_CCM
+#define POLARSSL_CIPHER_AES_128_CFB128 MBEDTLS_CIPHER_AES_128_CFB128
+#define POLARSSL_CIPHER_AES_128_CTR MBEDTLS_CIPHER_AES_128_CTR
+#define POLARSSL_CIPHER_AES_128_ECB MBEDTLS_CIPHER_AES_128_ECB
+#define POLARSSL_CIPHER_AES_128_GCM MBEDTLS_CIPHER_AES_128_GCM
+#define POLARSSL_CIPHER_AES_192_CBC MBEDTLS_CIPHER_AES_192_CBC
+#define POLARSSL_CIPHER_AES_192_CCM MBEDTLS_CIPHER_AES_192_CCM
+#define POLARSSL_CIPHER_AES_192_CFB128 MBEDTLS_CIPHER_AES_192_CFB128
+#define POLARSSL_CIPHER_AES_192_CTR MBEDTLS_CIPHER_AES_192_CTR
+#define POLARSSL_CIPHER_AES_192_ECB MBEDTLS_CIPHER_AES_192_ECB
+#define POLARSSL_CIPHER_AES_192_GCM MBEDTLS_CIPHER_AES_192_GCM
+#define POLARSSL_CIPHER_AES_256_CBC MBEDTLS_CIPHER_AES_256_CBC
+#define POLARSSL_CIPHER_AES_256_CCM MBEDTLS_CIPHER_AES_256_CCM
+#define POLARSSL_CIPHER_AES_256_CFB128 MBEDTLS_CIPHER_AES_256_CFB128
+#define POLARSSL_CIPHER_AES_256_CTR MBEDTLS_CIPHER_AES_256_CTR
+#define POLARSSL_CIPHER_AES_256_ECB MBEDTLS_CIPHER_AES_256_ECB
+#define POLARSSL_CIPHER_AES_256_GCM MBEDTLS_CIPHER_AES_256_GCM
+#define POLARSSL_CIPHER_ARC4_128 MBEDTLS_CIPHER_ARC4_128
+#define POLARSSL_CIPHER_BLOWFISH_CBC MBEDTLS_CIPHER_BLOWFISH_CBC
+#define POLARSSL_CIPHER_BLOWFISH_CFB64 MBEDTLS_CIPHER_BLOWFISH_CFB64
+#define POLARSSL_CIPHER_BLOWFISH_CTR MBEDTLS_CIPHER_BLOWFISH_CTR
+#define POLARSSL_CIPHER_BLOWFISH_ECB MBEDTLS_CIPHER_BLOWFISH_ECB
+#define POLARSSL_CIPHER_CAMELLIA_128_CBC MBEDTLS_CIPHER_CAMELLIA_128_CBC
+#define POLARSSL_CIPHER_CAMELLIA_128_CCM MBEDTLS_CIPHER_CAMELLIA_128_CCM
+#define POLARSSL_CIPHER_CAMELLIA_128_CFB128 MBEDTLS_CIPHER_CAMELLIA_128_CFB128
+#define POLARSSL_CIPHER_CAMELLIA_128_CTR MBEDTLS_CIPHER_CAMELLIA_128_CTR
+#define POLARSSL_CIPHER_CAMELLIA_128_ECB MBEDTLS_CIPHER_CAMELLIA_128_ECB
+#define POLARSSL_CIPHER_CAMELLIA_128_GCM MBEDTLS_CIPHER_CAMELLIA_128_GCM
+#define POLARSSL_CIPHER_CAMELLIA_192_CBC MBEDTLS_CIPHER_CAMELLIA_192_CBC
+#define POLARSSL_CIPHER_CAMELLIA_192_CCM MBEDTLS_CIPHER_CAMELLIA_192_CCM
+#define POLARSSL_CIPHER_CAMELLIA_192_CFB128 MBEDTLS_CIPHER_CAMELLIA_192_CFB128
+#define POLARSSL_CIPHER_CAMELLIA_192_CTR MBEDTLS_CIPHER_CAMELLIA_192_CTR
+#define POLARSSL_CIPHER_CAMELLIA_192_ECB MBEDTLS_CIPHER_CAMELLIA_192_ECB
+#define POLARSSL_CIPHER_CAMELLIA_192_GCM MBEDTLS_CIPHER_CAMELLIA_192_GCM
+#define POLARSSL_CIPHER_CAMELLIA_256_CBC MBEDTLS_CIPHER_CAMELLIA_256_CBC
+#define POLARSSL_CIPHER_CAMELLIA_256_CCM MBEDTLS_CIPHER_CAMELLIA_256_CCM
+#define POLARSSL_CIPHER_CAMELLIA_256_CFB128 MBEDTLS_CIPHER_CAMELLIA_256_CFB128
+#define POLARSSL_CIPHER_CAMELLIA_256_CTR MBEDTLS_CIPHER_CAMELLIA_256_CTR
+#define POLARSSL_CIPHER_CAMELLIA_256_ECB MBEDTLS_CIPHER_CAMELLIA_256_ECB
+#define POLARSSL_CIPHER_CAMELLIA_256_GCM MBEDTLS_CIPHER_CAMELLIA_256_GCM
+#define POLARSSL_CIPHER_DES_CBC MBEDTLS_CIPHER_DES_CBC
+#define POLARSSL_CIPHER_DES_ECB MBEDTLS_CIPHER_DES_ECB
+#define POLARSSL_CIPHER_DES_EDE3_CBC MBEDTLS_CIPHER_DES_EDE3_CBC
+#define POLARSSL_CIPHER_DES_EDE3_ECB MBEDTLS_CIPHER_DES_EDE3_ECB
+#define POLARSSL_CIPHER_DES_EDE_CBC MBEDTLS_CIPHER_DES_EDE_CBC
+#define POLARSSL_CIPHER_DES_EDE_ECB MBEDTLS_CIPHER_DES_EDE_ECB
+#define POLARSSL_CIPHER_H MBEDTLS_CIPHER_H
+#define POLARSSL_CIPHER_ID_3DES MBEDTLS_CIPHER_ID_3DES
+#define POLARSSL_CIPHER_ID_AES MBEDTLS_CIPHER_ID_AES
+#define POLARSSL_CIPHER_ID_ARC4 MBEDTLS_CIPHER_ID_ARC4
+#define POLARSSL_CIPHER_ID_BLOWFISH MBEDTLS_CIPHER_ID_BLOWFISH
+#define POLARSSL_CIPHER_ID_CAMELLIA MBEDTLS_CIPHER_ID_CAMELLIA
+#define POLARSSL_CIPHER_ID_DES MBEDTLS_CIPHER_ID_DES
+#define POLARSSL_CIPHER_ID_NONE MBEDTLS_CIPHER_ID_NONE
+#define POLARSSL_CIPHER_ID_NULL MBEDTLS_CIPHER_ID_NULL
+#define POLARSSL_CIPHER_MODE_AEAD MBEDTLS_CIPHER_MODE_AEAD
+#define POLARSSL_CIPHER_MODE_STREAM MBEDTLS_CIPHER_MODE_STREAM
+#define POLARSSL_CIPHER_MODE_WITH_PADDING MBEDTLS_CIPHER_MODE_WITH_PADDING
+#define POLARSSL_CIPHER_NONE MBEDTLS_CIPHER_NONE
+#define POLARSSL_CIPHER_NULL MBEDTLS_CIPHER_NULL
+#define POLARSSL_CIPHER_VARIABLE_IV_LEN MBEDTLS_CIPHER_VARIABLE_IV_LEN
+#define POLARSSL_CIPHER_VARIABLE_KEY_LEN MBEDTLS_CIPHER_VARIABLE_KEY_LEN
+#define POLARSSL_CIPHER_WRAP_H MBEDTLS_CIPHER_WRAP_H
+#define POLARSSL_CONFIG_H MBEDTLS_CONFIG_H
+#define POLARSSL_CTR_DRBG_H MBEDTLS_CTR_DRBG_H
+#define POLARSSL_DEBUG_H MBEDTLS_DEBUG_H
+#define POLARSSL_DECRYPT MBEDTLS_DECRYPT
+#define POLARSSL_DES_H MBEDTLS_DES_H
+#define POLARSSL_DHM_H MBEDTLS_DHM_H
+#define POLARSSL_DHM_RFC3526_MODP_2048_G MBEDTLS_DHM_RFC3526_MODP_2048_G
+#define POLARSSL_DHM_RFC3526_MODP_2048_P MBEDTLS_DHM_RFC3526_MODP_2048_P
+#define POLARSSL_DHM_RFC3526_MODP_3072_G MBEDTLS_DHM_RFC3526_MODP_3072_G
+#define POLARSSL_DHM_RFC3526_MODP_3072_P MBEDTLS_DHM_RFC3526_MODP_3072_P
+#define POLARSSL_DHM_RFC5114_MODP_2048_G MBEDTLS_DHM_RFC5114_MODP_2048_G
+#define POLARSSL_DHM_RFC5114_MODP_2048_P MBEDTLS_DHM_RFC5114_MODP_2048_P
+#define POLARSSL_ECDH_H MBEDTLS_ECDH_H
+#define POLARSSL_ECDH_OURS MBEDTLS_ECDH_OURS
+#define POLARSSL_ECDH_THEIRS MBEDTLS_ECDH_THEIRS
+#define POLARSSL_ECDSA_H MBEDTLS_ECDSA_H
+#define POLARSSL_ECP_DP_BP256R1 MBEDTLS_ECP_DP_BP256R1
+#define POLARSSL_ECP_DP_BP384R1 MBEDTLS_ECP_DP_BP384R1
+#define POLARSSL_ECP_DP_BP512R1 MBEDTLS_ECP_DP_BP512R1
+#define POLARSSL_ECP_DP_M255 MBEDTLS_ECP_DP_CURVE25519
+#define POLARSSL_ECP_DP_MAX MBEDTLS_ECP_DP_MAX
+#define POLARSSL_ECP_DP_NONE MBEDTLS_ECP_DP_NONE
+#define POLARSSL_ECP_DP_SECP192K1 MBEDTLS_ECP_DP_SECP192K1
+#define POLARSSL_ECP_DP_SECP192R1 MBEDTLS_ECP_DP_SECP192R1
+#define POLARSSL_ECP_DP_SECP224K1 MBEDTLS_ECP_DP_SECP224K1
+#define POLARSSL_ECP_DP_SECP224R1 MBEDTLS_ECP_DP_SECP224R1
+#define POLARSSL_ECP_DP_SECP256K1 MBEDTLS_ECP_DP_SECP256K1
+#define POLARSSL_ECP_DP_SECP256R1 MBEDTLS_ECP_DP_SECP256R1
+#define POLARSSL_ECP_DP_SECP384R1 MBEDTLS_ECP_DP_SECP384R1
+#define POLARSSL_ECP_DP_SECP521R1 MBEDTLS_ECP_DP_SECP521R1
+#define POLARSSL_ECP_H MBEDTLS_ECP_H
+#define POLARSSL_ECP_MAX_BYTES MBEDTLS_ECP_MAX_BYTES
+#define POLARSSL_ECP_MAX_PT_LEN MBEDTLS_ECP_MAX_PT_LEN
+#define POLARSSL_ECP_PF_COMPRESSED MBEDTLS_ECP_PF_COMPRESSED
+#define POLARSSL_ECP_PF_UNCOMPRESSED MBEDTLS_ECP_PF_UNCOMPRESSED
+#define POLARSSL_ECP_TLS_NAMED_CURVE MBEDTLS_ECP_TLS_NAMED_CURVE
+#define POLARSSL_ENCRYPT MBEDTLS_ENCRYPT
+#define POLARSSL_ENTROPY_H MBEDTLS_ENTROPY_H
+#define POLARSSL_ENTROPY_POLL_H MBEDTLS_ENTROPY_POLL_H
+#define POLARSSL_ENTROPY_SHA256_ACCUMULATOR MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
+#define POLARSSL_ENTROPY_SHA512_ACCUMULATOR MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
+#define POLARSSL_ERROR_H MBEDTLS_ERROR_H
+#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH MBEDTLS_ERR_AES_INVALID_KEY_LENGTH
+#define POLARSSL_ERR_ASN1_BUF_TOO_SMALL MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+#define POLARSSL_ERR_ASN1_INVALID_DATA MBEDTLS_ERR_ASN1_INVALID_DATA
+#define POLARSSL_ERR_ASN1_INVALID_LENGTH MBEDTLS_ERR_ASN1_INVALID_LENGTH
+#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
+#define POLARSSL_ERR_ASN1_MALLOC_FAILED MBEDTLS_ERR_ASN1_ALLOC_FAILED
+#define POLARSSL_ERR_ASN1_OUT_OF_DATA MBEDTLS_ERR_ASN1_OUT_OF_DATA
+#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
+#define POLARSSL_ERR_BASE64_INVALID_CHARACTER MBEDTLS_ERR_BASE64_INVALID_CHARACTER
+#define POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH
+#define POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH
+#define POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH
+#define POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH
+#define POLARSSL_ERR_CCM_AUTH_FAILED MBEDTLS_ERR_CCM_AUTH_FAILED
+#define POLARSSL_ERR_CCM_BAD_INPUT MBEDTLS_ERR_CCM_BAD_INPUT
+#define POLARSSL_ERR_CIPHER_ALLOC_FAILED MBEDTLS_ERR_CIPHER_ALLOC_FAILED
+#define POLARSSL_ERR_CIPHER_AUTH_FAILED MBEDTLS_ERR_CIPHER_AUTH_FAILED
+#define POLARSSL_ERR_CIPHER_BAD_INPUT_DATA MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
+#define POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
+#define POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED
+#define POLARSSL_ERR_CIPHER_INVALID_PADDING MBEDTLS_ERR_CIPHER_INVALID_PADDING
+#define POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
+#define POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR
+#define POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG
+#define POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG
+#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
+#define POLARSSL_ERR_DHM_BAD_INPUT_DATA MBEDTLS_ERR_DHM_BAD_INPUT_DATA
+#define POLARSSL_ERR_DHM_CALC_SECRET_FAILED MBEDTLS_ERR_DHM_CALC_SECRET_FAILED
+#define POLARSSL_ERR_DHM_FILE_IO_ERROR MBEDTLS_ERR_DHM_FILE_IO_ERROR
+#define POLARSSL_ERR_DHM_INVALID_FORMAT MBEDTLS_ERR_DHM_INVALID_FORMAT
+#define POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED
+#define POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED
+#define POLARSSL_ERR_DHM_MALLOC_FAILED MBEDTLS_ERR_DHM_ALLOC_FAILED
+#define POLARSSL_ERR_DHM_READ_PARAMS_FAILED MBEDTLS_ERR_DHM_READ_PARAMS_FAILED
+#define POLARSSL_ERR_DHM_READ_PUBLIC_FAILED MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED
+#define POLARSSL_ERR_ECP_BAD_INPUT_DATA MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+#define POLARSSL_ERR_ECP_BUFFER_TOO_SMALL MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+#define POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
+#define POLARSSL_ERR_ECP_INVALID_KEY MBEDTLS_ERR_ECP_INVALID_KEY
+#define POLARSSL_ERR_ECP_MALLOC_FAILED MBEDTLS_ERR_ECP_ALLOC_FAILED
+#define POLARSSL_ERR_ECP_RANDOM_FAILED MBEDTLS_ERR_ECP_RANDOM_FAILED
+#define POLARSSL_ERR_ECP_SIG_LEN_MISMATCH MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH
+#define POLARSSL_ERR_ECP_VERIFY_FAILED MBEDTLS_ERR_ECP_VERIFY_FAILED
+#define POLARSSL_ERR_ENTROPY_FILE_IO_ERROR MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR
+#define POLARSSL_ERR_ENTROPY_MAX_SOURCES MBEDTLS_ERR_ENTROPY_MAX_SOURCES
+#define POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED
+#define POLARSSL_ERR_ENTROPY_SOURCE_FAILED MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+#define POLARSSL_ERR_GCM_AUTH_FAILED MBEDTLS_ERR_GCM_AUTH_FAILED
+#define POLARSSL_ERR_GCM_BAD_INPUT MBEDTLS_ERR_GCM_BAD_INPUT
+#define POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+#define POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR
+#define POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG
+#define POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG
+#define POLARSSL_ERR_MD_ALLOC_FAILED MBEDTLS_ERR_MD_ALLOC_FAILED
+#define POLARSSL_ERR_MD_BAD_INPUT_DATA MBEDTLS_ERR_MD_BAD_INPUT_DATA
+#define POLARSSL_ERR_MD_FEATURE_UNAVAILABLE MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE
+#define POLARSSL_ERR_MD_FILE_IO_ERROR MBEDTLS_ERR_MD_FILE_IO_ERROR
+#define POLARSSL_ERR_MPI_BAD_INPUT_DATA MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO MBEDTLS_ERR_MPI_DIVISION_BY_ZERO
+#define POLARSSL_ERR_MPI_FILE_IO_ERROR MBEDTLS_ERR_MPI_FILE_IO_ERROR
+#define POLARSSL_ERR_MPI_INVALID_CHARACTER MBEDTLS_ERR_MPI_INVALID_CHARACTER
+#define POLARSSL_ERR_MPI_MALLOC_FAILED MBEDTLS_ERR_MPI_ALLOC_FAILED
+#define POLARSSL_ERR_MPI_NEGATIVE_VALUE MBEDTLS_ERR_MPI_NEGATIVE_VALUE
+#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE MBEDTLS_ERR_MPI_NOT_ACCEPTABLE
+#define POLARSSL_ERR_NET_ACCEPT_FAILED MBEDTLS_ERR_NET_ACCEPT_FAILED
+#define POLARSSL_ERR_NET_BIND_FAILED MBEDTLS_ERR_NET_BIND_FAILED
+#define POLARSSL_ERR_NET_CONNECT_FAILED MBEDTLS_ERR_NET_CONNECT_FAILED
+#define POLARSSL_ERR_NET_CONN_RESET MBEDTLS_ERR_NET_CONN_RESET
+#define POLARSSL_ERR_NET_LISTEN_FAILED MBEDTLS_ERR_NET_LISTEN_FAILED
+#define POLARSSL_ERR_NET_RECV_FAILED MBEDTLS_ERR_NET_RECV_FAILED
+#define POLARSSL_ERR_NET_SEND_FAILED MBEDTLS_ERR_NET_SEND_FAILED
+#define POLARSSL_ERR_NET_SOCKET_FAILED MBEDTLS_ERR_NET_SOCKET_FAILED
+#define POLARSSL_ERR_NET_TIMEOUT MBEDTLS_ERR_SSL_TIMEOUT
+#define POLARSSL_ERR_NET_UNKNOWN_HOST MBEDTLS_ERR_NET_UNKNOWN_HOST
+#define POLARSSL_ERR_NET_WANT_READ MBEDTLS_ERR_SSL_WANT_READ
+#define POLARSSL_ERR_NET_WANT_WRITE MBEDTLS_ERR_SSL_WANT_WRITE
+#define POLARSSL_ERR_OID_BUF_TOO_SMALL MBEDTLS_ERR_OID_BUF_TOO_SMALL
+#define POLARSSL_ERR_OID_NOT_FOUND MBEDTLS_ERR_OID_NOT_FOUND
+#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED
+#define POLARSSL_ERR_PEM_BAD_INPUT_DATA MBEDTLS_ERR_PEM_BAD_INPUT_DATA
+#define POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE
+#define POLARSSL_ERR_PEM_INVALID_DATA MBEDTLS_ERR_PEM_INVALID_DATA
+#define POLARSSL_ERR_PEM_INVALID_ENC_IV MBEDTLS_ERR_PEM_INVALID_ENC_IV
+#define POLARSSL_ERR_PEM_MALLOC_FAILED MBEDTLS_ERR_PEM_ALLOC_FAILED
+#define POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
+#define POLARSSL_ERR_PEM_PASSWORD_MISMATCH MBEDTLS_ERR_PEM_PASSWORD_MISMATCH
+#define POLARSSL_ERR_PEM_PASSWORD_REQUIRED MBEDTLS_ERR_PEM_PASSWORD_REQUIRED
+#define POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG
+#define POLARSSL_ERR_PKCS12_BAD_INPUT_DATA MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA
+#define POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE
+#define POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH
+#define POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT
+#define POLARSSL_ERR_PKCS5_BAD_INPUT_DATA MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA
+#define POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE
+#define POLARSSL_ERR_PKCS5_INVALID_FORMAT MBEDTLS_ERR_PKCS5_INVALID_FORMAT
+#define POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH
+#define POLARSSL_ERR_PK_BAD_INPUT_DATA MBEDTLS_ERR_PK_BAD_INPUT_DATA
+#define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE
+#define POLARSSL_ERR_PK_FILE_IO_ERROR MBEDTLS_ERR_PK_FILE_IO_ERROR
+#define POLARSSL_ERR_PK_INVALID_ALG MBEDTLS_ERR_PK_INVALID_ALG
+#define POLARSSL_ERR_PK_INVALID_PUBKEY MBEDTLS_ERR_PK_INVALID_PUBKEY
+#define POLARSSL_ERR_PK_KEY_INVALID_FORMAT MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+#define POLARSSL_ERR_PK_KEY_INVALID_VERSION MBEDTLS_ERR_PK_KEY_INVALID_VERSION
+#define POLARSSL_ERR_PK_MALLOC_FAILED MBEDTLS_ERR_PK_ALLOC_FAILED
+#define POLARSSL_ERR_PK_PASSWORD_MISMATCH MBEDTLS_ERR_PK_PASSWORD_MISMATCH
+#define POLARSSL_ERR_PK_PASSWORD_REQUIRED MBEDTLS_ERR_PK_PASSWORD_REQUIRED
+#define POLARSSL_ERR_PK_SIG_LEN_MISMATCH MBEDTLS_ERR_PK_SIG_LEN_MISMATCH
+#define POLARSSL_ERR_PK_TYPE_MISMATCH MBEDTLS_ERR_PK_TYPE_MISMATCH
+#define POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE
+#define POLARSSL_ERR_PK_UNKNOWN_PK_ALG MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
+#define POLARSSL_ERR_RSA_BAD_INPUT_DATA MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+#define POLARSSL_ERR_RSA_INVALID_PADDING MBEDTLS_ERR_RSA_INVALID_PADDING
+#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED MBEDTLS_ERR_RSA_KEY_CHECK_FAILED
+#define POLARSSL_ERR_RSA_KEY_GEN_FAILED MBEDTLS_ERR_RSA_KEY_GEN_FAILED
+#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
+#define POLARSSL_ERR_RSA_PRIVATE_FAILED MBEDTLS_ERR_RSA_PRIVATE_FAILED
+#define POLARSSL_ERR_RSA_PUBLIC_FAILED MBEDTLS_ERR_RSA_PUBLIC_FAILED
+#define POLARSSL_ERR_RSA_RNG_FAILED MBEDTLS_ERR_RSA_RNG_FAILED
+#define POLARSSL_ERR_RSA_VERIFY_FAILED MBEDTLS_ERR_RSA_VERIFY_FAILED
+#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE
+#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST
+#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY
+#define POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC
+#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO
+#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE
+#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS
+#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP
+#define POLARSSL_ERR_SSL_BAD_HS_FINISHED MBEDTLS_ERR_SSL_BAD_HS_FINISHED
+#define POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET
+#define POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION
+#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO
+#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE
+#define POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE
+#define POLARSSL_ERR_SSL_BAD_INPUT_DATA MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+#define POLARSSL_ERR_SSL_BUFFER_TOO_SMALL MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL
+#define POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED
+#define POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED
+#define POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE
+#define POLARSSL_ERR_SSL_COMPRESSION_FAILED MBEDTLS_ERR_SSL_COMPRESSION_FAILED
+#define POLARSSL_ERR_SSL_CONN_EOF MBEDTLS_ERR_SSL_CONN_EOF
+#define POLARSSL_ERR_SSL_COUNTER_WRAPPING MBEDTLS_ERR_SSL_COUNTER_WRAPPING
+#define POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE
+#define POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
+#define POLARSSL_ERR_SSL_HELLO_VERIFY_REQUIRED MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
+#define POLARSSL_ERR_SSL_HW_ACCEL_FAILED MBEDTLS_ERR_SSL_HW_ACCEL_FAILED
+#define POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH
+#define POLARSSL_ERR_SSL_INTERNAL_ERROR MBEDTLS_ERR_SSL_INTERNAL_ERROR
+#define POLARSSL_ERR_SSL_INVALID_MAC MBEDTLS_ERR_SSL_INVALID_MAC
+#define POLARSSL_ERR_SSL_INVALID_RECORD MBEDTLS_ERR_SSL_INVALID_RECORD
+#define POLARSSL_ERR_SSL_MALLOC_FAILED MBEDTLS_ERR_SSL_ALLOC_FAILED
+#define POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN
+#define POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE
+#define POLARSSL_ERR_SSL_NO_RNG MBEDTLS_ERR_SSL_NO_RNG
+#define POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE
+#define POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY
+#define POLARSSL_ERR_SSL_PEER_VERIFY_FAILED MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED
+#define POLARSSL_ERR_SSL_PK_TYPE_MISMATCH MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH
+#define POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED
+#define POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED
+#define POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE
+#define POLARSSL_ERR_SSL_UNKNOWN_CIPHER MBEDTLS_ERR_SSL_UNKNOWN_CIPHER
+#define POLARSSL_ERR_SSL_UNKNOWN_IDENTITY MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY
+#define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO
+#define POLARSSL_ERR_THREADING_BAD_INPUT_DATA MBEDTLS_ERR_THREADING_BAD_INPUT_DATA
+#define POLARSSL_ERR_THREADING_FEATURE_UNAVAILABLE MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE
+#define POLARSSL_ERR_THREADING_MUTEX_ERROR MBEDTLS_ERR_THREADING_MUTEX_ERROR
+#define POLARSSL_ERR_X509_BAD_INPUT_DATA MBEDTLS_ERR_X509_BAD_INPUT_DATA
+#define POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT
+#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED MBEDTLS_ERR_X509_CERT_VERIFY_FAILED
+#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE
+#define POLARSSL_ERR_X509_FILE_IO_ERROR MBEDTLS_ERR_X509_FILE_IO_ERROR
+#define POLARSSL_ERR_X509_INVALID_ALG MBEDTLS_ERR_X509_INVALID_ALG
+#define POLARSSL_ERR_X509_INVALID_DATE MBEDTLS_ERR_X509_INVALID_DATE
+#define POLARSSL_ERR_X509_INVALID_EXTENSIONS MBEDTLS_ERR_X509_INVALID_EXTENSIONS
+#define POLARSSL_ERR_X509_INVALID_FORMAT MBEDTLS_ERR_X509_INVALID_FORMAT
+#define POLARSSL_ERR_X509_INVALID_NAME MBEDTLS_ERR_X509_INVALID_NAME
+#define POLARSSL_ERR_X509_INVALID_SERIAL MBEDTLS_ERR_X509_INVALID_SERIAL
+#define POLARSSL_ERR_X509_INVALID_SIGNATURE MBEDTLS_ERR_X509_INVALID_SIGNATURE
+#define POLARSSL_ERR_X509_INVALID_VERSION MBEDTLS_ERR_X509_INVALID_VERSION
+#define POLARSSL_ERR_X509_MALLOC_FAILED MBEDTLS_ERR_X509_ALLOC_FAILED
+#define POLARSSL_ERR_X509_SIG_MISMATCH MBEDTLS_ERR_X509_SIG_MISMATCH
+#define POLARSSL_ERR_X509_UNKNOWN_OID MBEDTLS_ERR_X509_UNKNOWN_OID
+#define POLARSSL_ERR_X509_UNKNOWN_SIG_ALG MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG
+#define POLARSSL_ERR_X509_UNKNOWN_VERSION MBEDTLS_ERR_X509_UNKNOWN_VERSION
+#define POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH
+#define POLARSSL_GCM_H MBEDTLS_GCM_H
+#define POLARSSL_HAVEGE_H MBEDTLS_HAVEGE_H
+#define POLARSSL_HAVE_INT32 MBEDTLS_HAVE_INT32
+#define POLARSSL_HAVE_INT64 MBEDTLS_HAVE_INT64
+#define POLARSSL_HAVE_UDBL MBEDTLS_HAVE_UDBL
+#define POLARSSL_HAVE_X86 MBEDTLS_HAVE_X86
+#define POLARSSL_HAVE_X86_64 MBEDTLS_HAVE_X86_64
+#define POLARSSL_HMAC_DRBG_H MBEDTLS_HMAC_DRBG_H
+#define POLARSSL_HMAC_DRBG_PR_OFF MBEDTLS_HMAC_DRBG_PR_OFF
+#define POLARSSL_HMAC_DRBG_PR_ON MBEDTLS_HMAC_DRBG_PR_ON
+#define POLARSSL_KEY_EXCHANGE_DHE_PSK MBEDTLS_KEY_EXCHANGE_DHE_PSK
+#define POLARSSL_KEY_EXCHANGE_DHE_RSA MBEDTLS_KEY_EXCHANGE_DHE_RSA
+#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
+#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK MBEDTLS_KEY_EXCHANGE_ECDHE_PSK
+#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA MBEDTLS_KEY_EXCHANGE_ECDHE_RSA
+#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA
+#define POLARSSL_KEY_EXCHANGE_ECDH_RSA MBEDTLS_KEY_EXCHANGE_ECDH_RSA
+#define POLARSSL_KEY_EXCHANGE_NONE MBEDTLS_KEY_EXCHANGE_NONE
+#define POLARSSL_KEY_EXCHANGE_PSK MBEDTLS_KEY_EXCHANGE_PSK
+#define POLARSSL_KEY_EXCHANGE_RSA MBEDTLS_KEY_EXCHANGE_RSA
+#define POLARSSL_KEY_EXCHANGE_RSA_PSK MBEDTLS_KEY_EXCHANGE_RSA_PSK
+#define POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED
+#define POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED
+#define POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED
+#define POLARSSL_KEY_LENGTH_DES MBEDTLS_KEY_LENGTH_DES
+#define POLARSSL_KEY_LENGTH_DES_EDE MBEDTLS_KEY_LENGTH_DES_EDE
+#define POLARSSL_KEY_LENGTH_DES_EDE3 MBEDTLS_KEY_LENGTH_DES_EDE3
+#define POLARSSL_KEY_LENGTH_NONE MBEDTLS_KEY_LENGTH_NONE
+#define POLARSSL_MAX_BLOCK_LENGTH MBEDTLS_MAX_BLOCK_LENGTH
+#define POLARSSL_MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH
+#define POLARSSL_MD2_H MBEDTLS_MD2_H
+#define POLARSSL_MD4_H MBEDTLS_MD4_H
+#define POLARSSL_MD5_H MBEDTLS_MD5_H
+#define POLARSSL_MD_H MBEDTLS_MD_H
+#define POLARSSL_MD_MAX_SIZE MBEDTLS_MD_MAX_SIZE
+#define POLARSSL_MD_MD2 MBEDTLS_MD_MD2
+#define POLARSSL_MD_MD4 MBEDTLS_MD_MD4
+#define POLARSSL_MD_MD5 MBEDTLS_MD_MD5
+#define POLARSSL_MD_NONE MBEDTLS_MD_NONE
+#define POLARSSL_MD_RIPEMD160 MBEDTLS_MD_RIPEMD160
+#define POLARSSL_MD_SHA1 MBEDTLS_MD_SHA1
+#define POLARSSL_MD_SHA224 MBEDTLS_MD_SHA224
+#define POLARSSL_MD_SHA256 MBEDTLS_MD_SHA256
+#define POLARSSL_MD_SHA384 MBEDTLS_MD_SHA384
+#define POLARSSL_MD_SHA512 MBEDTLS_MD_SHA512
+#define POLARSSL_MD_WRAP_H MBEDTLS_MD_WRAP_H
+#define POLARSSL_MEMORY_BUFFER_ALLOC_H MBEDTLS_MEMORY_BUFFER_ALLOC_H
+#define POLARSSL_MODE_CBC MBEDTLS_MODE_CBC
+#define POLARSSL_MODE_CCM MBEDTLS_MODE_CCM
+#define POLARSSL_MODE_CFB MBEDTLS_MODE_CFB
+#define POLARSSL_MODE_CTR MBEDTLS_MODE_CTR
+#define POLARSSL_MODE_ECB MBEDTLS_MODE_ECB
+#define POLARSSL_MODE_GCM MBEDTLS_MODE_GCM
+#define POLARSSL_MODE_NONE MBEDTLS_MODE_NONE
+#define POLARSSL_MODE_OFB MBEDTLS_MODE_OFB
+#define POLARSSL_MODE_STREAM MBEDTLS_MODE_STREAM
+#define POLARSSL_MPI_MAX_BITS MBEDTLS_MPI_MAX_BITS
+#define POLARSSL_MPI_MAX_BITS_SCALE100 MBEDTLS_MPI_MAX_BITS_SCALE100
+#define POLARSSL_MPI_MAX_LIMBS MBEDTLS_MPI_MAX_LIMBS
+#define POLARSSL_MPI_RW_BUFFER_SIZE MBEDTLS_MPI_RW_BUFFER_SIZE
+#define POLARSSL_NET_H MBEDTLS_NET_SOCKETS_H
+#define POLARSSL_NET_LISTEN_BACKLOG MBEDTLS_NET_LISTEN_BACKLOG
+#define POLARSSL_OID_H MBEDTLS_OID_H
+#define POLARSSL_OPERATION_NONE MBEDTLS_OPERATION_NONE
+#define POLARSSL_PADDING_NONE MBEDTLS_PADDING_NONE
+#define POLARSSL_PADDING_ONE_AND_ZEROS MBEDTLS_PADDING_ONE_AND_ZEROS
+#define POLARSSL_PADDING_PKCS7 MBEDTLS_PADDING_PKCS7
+#define POLARSSL_PADDING_ZEROS MBEDTLS_PADDING_ZEROS
+#define POLARSSL_PADDING_ZEROS_AND_LEN MBEDTLS_PADDING_ZEROS_AND_LEN
+#define POLARSSL_PADLOCK_H MBEDTLS_PADLOCK_H
+#define POLARSSL_PEM_H MBEDTLS_PEM_H
+#define POLARSSL_PKCS11_H MBEDTLS_PKCS11_H
+#define POLARSSL_PKCS12_H MBEDTLS_PKCS12_H
+#define POLARSSL_PKCS5_H MBEDTLS_PKCS5_H
+#define POLARSSL_PK_DEBUG_ECP MBEDTLS_PK_DEBUG_ECP
+#define POLARSSL_PK_DEBUG_MAX_ITEMS MBEDTLS_PK_DEBUG_MAX_ITEMS
+#define POLARSSL_PK_DEBUG_MPI MBEDTLS_PK_DEBUG_MPI
+#define POLARSSL_PK_DEBUG_NONE MBEDTLS_PK_DEBUG_NONE
+#define POLARSSL_PK_ECDSA MBEDTLS_PK_ECDSA
+#define POLARSSL_PK_ECKEY MBEDTLS_PK_ECKEY
+#define POLARSSL_PK_ECKEY_DH MBEDTLS_PK_ECKEY_DH
+#define POLARSSL_PK_H MBEDTLS_PK_H
+#define POLARSSL_PK_NONE MBEDTLS_PK_NONE
+#define POLARSSL_PK_RSA MBEDTLS_PK_RSA
+#define POLARSSL_PK_RSASSA_PSS MBEDTLS_PK_RSASSA_PSS
+#define POLARSSL_PK_RSA_ALT MBEDTLS_PK_RSA_ALT
+#define POLARSSL_PK_WRAP_H MBEDTLS_PK_WRAP_H
+#define POLARSSL_PLATFORM_H MBEDTLS_PLATFORM_H
+#define POLARSSL_PREMASTER_SIZE MBEDTLS_PREMASTER_SIZE
+#define POLARSSL_RIPEMD160_H MBEDTLS_RIPEMD160_H
+#define POLARSSL_RSA_H MBEDTLS_RSA_H
+#define POLARSSL_SHA1_H MBEDTLS_SHA1_H
+#define POLARSSL_SHA256_H MBEDTLS_SHA256_H
+#define POLARSSL_SHA512_H MBEDTLS_SHA512_H
+#define POLARSSL_SSL_CACHE_H MBEDTLS_SSL_CACHE_H
+#define POLARSSL_SSL_CIPHERSUITES_H MBEDTLS_SSL_CIPHERSUITES_H
+#define POLARSSL_SSL_COOKIE_H MBEDTLS_SSL_COOKIE_H
+#define POLARSSL_SSL_H MBEDTLS_SSL_H
+#define POLARSSL_THREADING_H MBEDTLS_THREADING_H
+#define POLARSSL_THREADING_IMPL MBEDTLS_THREADING_IMPL
+#define POLARSSL_TIMING_H MBEDTLS_TIMING_H
+#define POLARSSL_VERSION_H MBEDTLS_VERSION_H
+#define POLARSSL_VERSION_MAJOR MBEDTLS_VERSION_MAJOR
+#define POLARSSL_VERSION_MINOR MBEDTLS_VERSION_MINOR
+#define POLARSSL_VERSION_NUMBER MBEDTLS_VERSION_NUMBER
+#define POLARSSL_VERSION_PATCH MBEDTLS_VERSION_PATCH
+#define POLARSSL_VERSION_STRING MBEDTLS_VERSION_STRING
+#define POLARSSL_VERSION_STRING_FULL MBEDTLS_VERSION_STRING_FULL
+#define POLARSSL_X509_CRL_H MBEDTLS_X509_CRL_H
+#define POLARSSL_X509_CRT_H MBEDTLS_X509_CRT_H
+#define POLARSSL_X509_CSR_H MBEDTLS_X509_CSR_H
+#define POLARSSL_X509_H MBEDTLS_X509_H
+#define POLARSSL_XTEA_H MBEDTLS_XTEA_H
+#define RSA_CRYPT MBEDTLS_RSA_CRYPT
+#define RSA_PKCS_V15 MBEDTLS_RSA_PKCS_V15
+#define RSA_PKCS_V21 MBEDTLS_RSA_PKCS_V21
+#define RSA_PRIVATE MBEDTLS_RSA_PRIVATE
+#define RSA_PUBLIC MBEDTLS_RSA_PUBLIC
+#define RSA_SALT_LEN_ANY MBEDTLS_RSA_SALT_LEN_ANY
+#define RSA_SIGN MBEDTLS_RSA_SIGN
+#define SSL_ALERT_LEVEL_FATAL MBEDTLS_SSL_ALERT_LEVEL_FATAL
+#define SSL_ALERT_LEVEL_WARNING MBEDTLS_SSL_ALERT_LEVEL_WARNING
+#define SSL_ALERT_MSG_ACCESS_DENIED MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED
+#define SSL_ALERT_MSG_BAD_CERT MBEDTLS_SSL_ALERT_MSG_BAD_CERT
+#define SSL_ALERT_MSG_BAD_RECORD_MAC MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC
+#define SSL_ALERT_MSG_CERT_EXPIRED MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED
+#define SSL_ALERT_MSG_CERT_REVOKED MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED
+#define SSL_ALERT_MSG_CERT_UNKNOWN MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN
+#define SSL_ALERT_MSG_CLOSE_NOTIFY MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY
+#define SSL_ALERT_MSG_DECODE_ERROR MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR
+#define SSL_ALERT_MSG_DECOMPRESSION_FAILURE MBEDTLS_SSL_ALERT_MSG_DECOMPRESSION_FAILURE
+#define SSL_ALERT_MSG_DECRYPTION_FAILED MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED
+#define SSL_ALERT_MSG_DECRYPT_ERROR MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR
+#define SSL_ALERT_MSG_EXPORT_RESTRICTION MBEDTLS_SSL_ALERT_MSG_EXPORT_RESTRICTION
+#define SSL_ALERT_MSG_HANDSHAKE_FAILURE MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE
+#define SSL_ALERT_MSG_ILLEGAL_PARAMETER MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER
+#define SSL_ALERT_MSG_INAPROPRIATE_FALLBACK MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK
+#define SSL_ALERT_MSG_INSUFFICIENT_SECURITY MBEDTLS_SSL_ALERT_MSG_INSUFFICIENT_SECURITY
+#define SSL_ALERT_MSG_INTERNAL_ERROR MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR
+#define SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL
+#define SSL_ALERT_MSG_NO_CERT MBEDTLS_SSL_ALERT_MSG_NO_CERT
+#define SSL_ALERT_MSG_NO_RENEGOTIATION MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION
+#define SSL_ALERT_MSG_PROTOCOL_VERSION MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION
+#define SSL_ALERT_MSG_RECORD_OVERFLOW MBEDTLS_SSL_ALERT_MSG_RECORD_OVERFLOW
+#define SSL_ALERT_MSG_UNEXPECTED_MESSAGE MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE
+#define SSL_ALERT_MSG_UNKNOWN_CA MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA
+#define SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY
+#define SSL_ALERT_MSG_UNRECOGNIZED_NAME MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME
+#define SSL_ALERT_MSG_UNSUPPORTED_CERT MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT
+#define SSL_ALERT_MSG_UNSUPPORTED_EXT MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT
+#define SSL_ALERT_MSG_USER_CANCELED MBEDTLS_SSL_ALERT_MSG_USER_CANCELED
+#define SSL_ANTI_REPLAY_DISABLED MBEDTLS_SSL_ANTI_REPLAY_DISABLED
+#define SSL_ANTI_REPLAY_ENABLED MBEDTLS_SSL_ANTI_REPLAY_ENABLED
+#define SSL_ARC4_DISABLED MBEDTLS_SSL_ARC4_DISABLED
+#define SSL_ARC4_ENABLED MBEDTLS_SSL_ARC4_ENABLED
+#define SSL_BUFFER_LEN ( ( ( MBEDTLS_SSL_IN_BUFFER_LEN ) < ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) \
+                         ? ( MBEDTLS_SSL_IN_BUFFER_LEN ) : ( MBEDTLS_SSL_OUT_BUFFER_LEN ) )
+#define SSL_CACHE_DEFAULT_MAX_ENTRIES MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES
+#define SSL_CACHE_DEFAULT_TIMEOUT MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT
+#define SSL_CBC_RECORD_SPLITTING_DISABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED
+#define SSL_CBC_RECORD_SPLITTING_ENABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED
+#define SSL_CERTIFICATE_REQUEST MBEDTLS_SSL_CERTIFICATE_REQUEST
+#define SSL_CERTIFICATE_VERIFY MBEDTLS_SSL_CERTIFICATE_VERIFY
+#define SSL_CERT_TYPE_ECDSA_SIGN MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN
+#define SSL_CERT_TYPE_RSA_SIGN MBEDTLS_SSL_CERT_TYPE_RSA_SIGN
+#define SSL_CHANNEL_INBOUND MBEDTLS_SSL_CHANNEL_INBOUND
+#define SSL_CHANNEL_OUTBOUND MBEDTLS_SSL_CHANNEL_OUTBOUND
+#define SSL_CIPHERSUITES MBEDTLS_SSL_CIPHERSUITES
+#define SSL_CLIENT_CERTIFICATE MBEDTLS_SSL_CLIENT_CERTIFICATE
+#define SSL_CLIENT_CHANGE_CIPHER_SPEC MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC
+#define SSL_CLIENT_FINISHED MBEDTLS_SSL_CLIENT_FINISHED
+#define SSL_CLIENT_HELLO MBEDTLS_SSL_CLIENT_HELLO
+#define SSL_CLIENT_KEY_EXCHANGE MBEDTLS_SSL_CLIENT_KEY_EXCHANGE
+#define SSL_COMPRESSION_ADD MBEDTLS_SSL_COMPRESSION_ADD
+#define SSL_COMPRESS_DEFLATE MBEDTLS_SSL_COMPRESS_DEFLATE
+#define SSL_COMPRESS_NULL MBEDTLS_SSL_COMPRESS_NULL
+#define SSL_DEBUG_BUF MBEDTLS_SSL_DEBUG_BUF
+#define SSL_DEBUG_CRT MBEDTLS_SSL_DEBUG_CRT
+#define SSL_DEBUG_ECP MBEDTLS_SSL_DEBUG_ECP
+#define SSL_DEBUG_MPI MBEDTLS_SSL_DEBUG_MPI
+#define SSL_DEBUG_MSG MBEDTLS_SSL_DEBUG_MSG
+#define SSL_DEBUG_RET MBEDTLS_SSL_DEBUG_RET
+#define SSL_DEFAULT_TICKET_LIFETIME MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME
+#define SSL_DTLS_TIMEOUT_DFL_MAX MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX
+#define SSL_DTLS_TIMEOUT_DFL_MIN MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN
+#define SSL_EMPTY_RENEGOTIATION_INFO MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO
+#define SSL_ETM_DISABLED MBEDTLS_SSL_ETM_DISABLED
+#define SSL_ETM_ENABLED MBEDTLS_SSL_ETM_ENABLED
+#define SSL_EXTENDED_MS_DISABLED MBEDTLS_SSL_EXTENDED_MS_DISABLED
+#define SSL_EXTENDED_MS_ENABLED MBEDTLS_SSL_EXTENDED_MS_ENABLED
+#define SSL_FALLBACK_SCSV MBEDTLS_SSL_FALLBACK_SCSV
+#define SSL_FLUSH_BUFFERS MBEDTLS_SSL_FLUSH_BUFFERS
+#define SSL_HANDSHAKE_OVER MBEDTLS_SSL_HANDSHAKE_OVER
+#define SSL_HANDSHAKE_WRAPUP MBEDTLS_SSL_HANDSHAKE_WRAPUP
+#define SSL_HASH_MD5 MBEDTLS_SSL_HASH_MD5
+#define SSL_HASH_NONE MBEDTLS_SSL_HASH_NONE
+#define SSL_HASH_SHA1 MBEDTLS_SSL_HASH_SHA1
+#define SSL_HASH_SHA224 MBEDTLS_SSL_HASH_SHA224
+#define SSL_HASH_SHA256 MBEDTLS_SSL_HASH_SHA256
+#define SSL_HASH_SHA384 MBEDTLS_SSL_HASH_SHA384
+#define SSL_HASH_SHA512 MBEDTLS_SSL_HASH_SHA512
+#define SSL_HELLO_REQUEST MBEDTLS_SSL_HELLO_REQUEST
+#define SSL_HS_CERTIFICATE MBEDTLS_SSL_HS_CERTIFICATE
+#define SSL_HS_CERTIFICATE_REQUEST MBEDTLS_SSL_HS_CERTIFICATE_REQUEST
+#define SSL_HS_CERTIFICATE_VERIFY MBEDTLS_SSL_HS_CERTIFICATE_VERIFY
+#define SSL_HS_CLIENT_HELLO MBEDTLS_SSL_HS_CLIENT_HELLO
+#define SSL_HS_CLIENT_KEY_EXCHANGE MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE
+#define SSL_HS_FINISHED MBEDTLS_SSL_HS_FINISHED
+#define SSL_HS_HELLO_REQUEST MBEDTLS_SSL_HS_HELLO_REQUEST
+#define SSL_HS_HELLO_VERIFY_REQUEST MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST
+#define SSL_HS_NEW_SESSION_TICKET MBEDTLS_SSL_HS_NEW_SESSION_TICKET
+#define SSL_HS_SERVER_HELLO MBEDTLS_SSL_HS_SERVER_HELLO
+#define SSL_HS_SERVER_HELLO_DONE MBEDTLS_SSL_HS_SERVER_HELLO_DONE
+#define SSL_HS_SERVER_KEY_EXCHANGE MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE
+#define SSL_INITIAL_HANDSHAKE MBEDTLS_SSL_INITIAL_HANDSHAKE
+#define SSL_IS_CLIENT MBEDTLS_SSL_IS_CLIENT
+#define SSL_IS_FALLBACK MBEDTLS_SSL_IS_FALLBACK
+#define SSL_IS_NOT_FALLBACK MBEDTLS_SSL_IS_NOT_FALLBACK
+#define SSL_IS_SERVER MBEDTLS_SSL_IS_SERVER
+#define SSL_LEGACY_ALLOW_RENEGOTIATION MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION
+#define SSL_LEGACY_BREAK_HANDSHAKE MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE
+#define SSL_LEGACY_NO_RENEGOTIATION MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION
+#define SSL_LEGACY_RENEGOTIATION MBEDTLS_SSL_LEGACY_RENEGOTIATION
+#define SSL_MAC_ADD MBEDTLS_SSL_MAC_ADD
+#define SSL_MAJOR_VERSION_3 MBEDTLS_SSL_MAJOR_VERSION_3
+#define SSL_MAX_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN
+#define SSL_MAX_FRAG_LEN_1024 MBEDTLS_SSL_MAX_FRAG_LEN_1024
+#define SSL_MAX_FRAG_LEN_2048 MBEDTLS_SSL_MAX_FRAG_LEN_2048
+#define SSL_MAX_FRAG_LEN_4096 MBEDTLS_SSL_MAX_FRAG_LEN_4096
+#define SSL_MAX_FRAG_LEN_512 MBEDTLS_SSL_MAX_FRAG_LEN_512
+#define SSL_MAX_FRAG_LEN_INVALID MBEDTLS_SSL_MAX_FRAG_LEN_INVALID
+#define SSL_MAX_FRAG_LEN_NONE MBEDTLS_SSL_MAX_FRAG_LEN_NONE
+#define SSL_MAX_MAJOR_VERSION MBEDTLS_SSL_MAX_MAJOR_VERSION
+#define SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MAX_MINOR_VERSION
+#define SSL_MINOR_VERSION_0 MBEDTLS_SSL_MINOR_VERSION_0
+#define SSL_MINOR_VERSION_1 MBEDTLS_SSL_MINOR_VERSION_1
+#define SSL_MINOR_VERSION_2 MBEDTLS_SSL_MINOR_VERSION_2
+#define SSL_MINOR_VERSION_3 MBEDTLS_SSL_MINOR_VERSION_3
+#define SSL_MIN_MAJOR_VERSION MBEDTLS_SSL_MIN_MAJOR_VERSION
+#define SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MIN_MINOR_VERSION
+#define SSL_MSG_ALERT MBEDTLS_SSL_MSG_ALERT
+#define SSL_MSG_APPLICATION_DATA MBEDTLS_SSL_MSG_APPLICATION_DATA
+#define SSL_MSG_CHANGE_CIPHER_SPEC MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC
+#define SSL_MSG_HANDSHAKE MBEDTLS_SSL_MSG_HANDSHAKE
+#define SSL_PADDING_ADD MBEDTLS_SSL_PADDING_ADD
+#define SSL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION
+#define SSL_RENEGOTIATION_DISABLED MBEDTLS_SSL_RENEGOTIATION_DISABLED
+#define SSL_RENEGOTIATION_DONE MBEDTLS_SSL_RENEGOTIATION_DONE
+#define SSL_RENEGOTIATION_ENABLED MBEDTLS_SSL_RENEGOTIATION_ENABLED
+#define SSL_RENEGOTIATION_NOT_ENFORCED MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED
+#define SSL_RENEGOTIATION_PENDING MBEDTLS_SSL_RENEGOTIATION_PENDING
+#define SSL_RENEGO_MAX_RECORDS_DEFAULT MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT
+#define SSL_RETRANS_FINISHED MBEDTLS_SSL_RETRANS_FINISHED
+#define SSL_RETRANS_PREPARING MBEDTLS_SSL_RETRANS_PREPARING
+#define SSL_RETRANS_SENDING MBEDTLS_SSL_RETRANS_SENDING
+#define SSL_RETRANS_WAITING MBEDTLS_SSL_RETRANS_WAITING
+#define SSL_SECURE_RENEGOTIATION MBEDTLS_SSL_SECURE_RENEGOTIATION
+#define SSL_SERVER_CERTIFICATE MBEDTLS_SSL_SERVER_CERTIFICATE
+#define SSL_SERVER_CHANGE_CIPHER_SPEC MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC
+#define SSL_SERVER_FINISHED MBEDTLS_SSL_SERVER_FINISHED
+#define SSL_SERVER_HELLO MBEDTLS_SSL_SERVER_HELLO
+#define SSL_SERVER_HELLO_DONE MBEDTLS_SSL_SERVER_HELLO_DONE
+#define SSL_SERVER_HELLO_VERIFY_REQUEST_SENT MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT
+#define SSL_SERVER_KEY_EXCHANGE MBEDTLS_SSL_SERVER_KEY_EXCHANGE
+#define SSL_SERVER_NEW_SESSION_TICKET MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET
+#define SSL_SESSION_TICKETS_DISABLED MBEDTLS_SSL_SESSION_TICKETS_DISABLED
+#define SSL_SESSION_TICKETS_ENABLED MBEDTLS_SSL_SESSION_TICKETS_ENABLED
+#define SSL_SIG_ANON MBEDTLS_SSL_SIG_ANON
+#define SSL_SIG_ECDSA MBEDTLS_SSL_SIG_ECDSA
+#define SSL_SIG_RSA MBEDTLS_SSL_SIG_RSA
+#define SSL_TRANSPORT_DATAGRAM MBEDTLS_SSL_TRANSPORT_DATAGRAM
+#define SSL_TRANSPORT_STREAM MBEDTLS_SSL_TRANSPORT_STREAM
+#define SSL_TRUNCATED_HMAC_LEN MBEDTLS_SSL_TRUNCATED_HMAC_LEN
+#define SSL_TRUNC_HMAC_DISABLED MBEDTLS_SSL_TRUNC_HMAC_DISABLED
+#define SSL_TRUNC_HMAC_ENABLED MBEDTLS_SSL_TRUNC_HMAC_ENABLED
+#define SSL_VERIFY_DATA_MAX_LEN MBEDTLS_SSL_VERIFY_DATA_MAX_LEN
+#define SSL_VERIFY_NONE MBEDTLS_SSL_VERIFY_NONE
+#define SSL_VERIFY_OPTIONAL MBEDTLS_SSL_VERIFY_OPTIONAL
+#define SSL_VERIFY_REQUIRED MBEDTLS_SSL_VERIFY_REQUIRED
+#define TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+#define TLS_DHE_PSK_WITH_AES_128_CCM MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM
+#define TLS_DHE_PSK_WITH_AES_128_CCM_8 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8
+#define TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+#define TLS_DHE_PSK_WITH_AES_256_CCM MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM
+#define TLS_DHE_PSK_WITH_AES_256_CCM_8 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8
+#define TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+#define TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+#define TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+#define TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+#define TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+#define TLS_DHE_PSK_WITH_NULL_SHA MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA
+#define TLS_DHE_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256
+#define TLS_DHE_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384
+#define TLS_DHE_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+#define TLS_DHE_RSA_WITH_AES_128_CCM MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM
+#define TLS_DHE_RSA_WITH_AES_128_CCM_8 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8
+#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+#define TLS_DHE_RSA_WITH_AES_256_CCM MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM
+#define TLS_DHE_RSA_WITH_AES_256_CCM_8 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8
+#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+#define TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+#define TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+#define TLS_DHE_RSA_WITH_DES_CBC_SHA MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA
+#define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM
+#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+#define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM
+#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
+#define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+#define TLS_ECDHE_ECDSA_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA
+#define TLS_ECDHE_ECDSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+#define TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+#define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+#define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+#define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+#define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+#define TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+#define TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+#define TLS_ECDHE_PSK_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA
+#define TLS_ECDHE_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256
+#define TLS_ECDHE_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384
+#define TLS_ECDHE_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+#define TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+#define TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+#define TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+#define TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+#define TLS_ECDHE_RSA_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA
+#define TLS_ECDHE_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+#define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+#define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+#define TLS_ECDH_ECDSA_WITH_NULL_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA
+#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+#define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+#define TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+#define TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+#define TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+#define TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+#define TLS_ECDH_RSA_WITH_NULL_SHA MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA
+#define TLS_ECDH_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+#define TLS_EXT_ALPN MBEDTLS_TLS_EXT_ALPN
+#define TLS_EXT_ENCRYPT_THEN_MAC MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC
+#define TLS_EXT_EXTENDED_MASTER_SECRET MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET
+#define TLS_EXT_MAX_FRAGMENT_LENGTH MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH
+#define TLS_EXT_RENEGOTIATION_INFO MBEDTLS_TLS_EXT_RENEGOTIATION_INFO
+#define TLS_EXT_SERVERNAME MBEDTLS_TLS_EXT_SERVERNAME
+#define TLS_EXT_SERVERNAME_HOSTNAME MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME
+#define TLS_EXT_SESSION_TICKET MBEDTLS_TLS_EXT_SESSION_TICKET
+#define TLS_EXT_SIG_ALG MBEDTLS_TLS_EXT_SIG_ALG
+#define TLS_EXT_SUPPORTED_ELLIPTIC_CURVES MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES
+#define TLS_EXT_SUPPORTED_POINT_FORMATS MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS
+#define TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT
+#define TLS_EXT_TRUNCATED_HMAC MBEDTLS_TLS_EXT_TRUNCATED_HMAC
+#define TLS_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+#define TLS_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+#define TLS_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+#define TLS_PSK_WITH_AES_128_CCM MBEDTLS_TLS_PSK_WITH_AES_128_CCM
+#define TLS_PSK_WITH_AES_128_CCM_8 MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8
+#define TLS_PSK_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+#define TLS_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+#define TLS_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+#define TLS_PSK_WITH_AES_256_CCM MBEDTLS_TLS_PSK_WITH_AES_256_CCM
+#define TLS_PSK_WITH_AES_256_CCM_8 MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8
+#define TLS_PSK_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+#define TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+#define TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+#define TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+#define TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+#define TLS_PSK_WITH_NULL_SHA MBEDTLS_TLS_PSK_WITH_NULL_SHA
+#define TLS_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_PSK_WITH_NULL_SHA256
+#define TLS_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_PSK_WITH_NULL_SHA384
+#define TLS_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+#define TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+#define TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+#define TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+#define TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+#define TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+#define TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+#define TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+#define TLS_RSA_PSK_WITH_NULL_SHA MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA
+#define TLS_RSA_PSK_WITH_NULL_SHA256 MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256
+#define TLS_RSA_PSK_WITH_NULL_SHA384 MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384
+#define TLS_RSA_PSK_WITH_RC4_128_SHA MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+#define TLS_RSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+#define TLS_RSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+#define TLS_RSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+#define TLS_RSA_WITH_AES_128_CCM MBEDTLS_TLS_RSA_WITH_AES_128_CCM
+#define TLS_RSA_WITH_AES_128_CCM_8 MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8
+#define TLS_RSA_WITH_AES_128_GCM_SHA256 MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+#define TLS_RSA_WITH_AES_256_CBC_SHA MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+#define TLS_RSA_WITH_AES_256_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+#define TLS_RSA_WITH_AES_256_CCM MBEDTLS_TLS_RSA_WITH_AES_256_CCM
+#define TLS_RSA_WITH_AES_256_CCM_8 MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8
+#define TLS_RSA_WITH_AES_256_GCM_SHA384 MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+#define TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+#define TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+#define TLS_RSA_WITH_DES_CBC_SHA MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA
+#define TLS_RSA_WITH_NULL_MD5 MBEDTLS_TLS_RSA_WITH_NULL_MD5
+#define TLS_RSA_WITH_NULL_SHA MBEDTLS_TLS_RSA_WITH_NULL_SHA
+#define TLS_RSA_WITH_NULL_SHA256 MBEDTLS_TLS_RSA_WITH_NULL_SHA256
+#define TLS_RSA_WITH_RC4_128_MD5 MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+#define TLS_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+#define X509_CRT_VERSION_1 MBEDTLS_X509_CRT_VERSION_1
+#define X509_CRT_VERSION_2 MBEDTLS_X509_CRT_VERSION_2
+#define X509_CRT_VERSION_3 MBEDTLS_X509_CRT_VERSION_3
+#define X509_FORMAT_DER MBEDTLS_X509_FORMAT_DER
+#define X509_FORMAT_PEM MBEDTLS_X509_FORMAT_PEM
+#define X509_MAX_DN_NAME_SIZE MBEDTLS_X509_MAX_DN_NAME_SIZE
+#define X509_RFC5280_MAX_SERIAL_LEN MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN
+#define X509_RFC5280_UTC_TIME_LEN MBEDTLS_X509_RFC5280_UTC_TIME_LEN
+#define XTEA_DECRYPT MBEDTLS_XTEA_DECRYPT
+#define XTEA_ENCRYPT MBEDTLS_XTEA_ENCRYPT
+#define _asn1_bitstring mbedtls_asn1_bitstring
+#define _asn1_buf mbedtls_asn1_buf
+#define _asn1_named_data mbedtls_asn1_named_data
+#define _asn1_sequence mbedtls_asn1_sequence
+#define _ssl_cache_context mbedtls_ssl_cache_context
+#define _ssl_cache_entry mbedtls_ssl_cache_entry
+#define _ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t
+#define _ssl_context mbedtls_ssl_context
+#define _ssl_flight_item mbedtls_ssl_flight_item
+#define _ssl_handshake_params mbedtls_ssl_handshake_params
+#define _ssl_key_cert mbedtls_ssl_key_cert
+#define _ssl_premaster_secret mbedtls_ssl_premaster_secret
+#define _ssl_session mbedtls_ssl_session
+#define _ssl_transform mbedtls_ssl_transform
+#define _x509_crl mbedtls_x509_crl
+#define _x509_crl_entry mbedtls_x509_crl_entry
+#define _x509_crt mbedtls_x509_crt
+#define _x509_csr mbedtls_x509_csr
+#define _x509_time mbedtls_x509_time
+#define _x509write_cert mbedtls_x509write_cert
+#define _x509write_csr mbedtls_x509write_csr
+#define aes_context mbedtls_aes_context
+#define aes_crypt_cbc mbedtls_aes_crypt_cbc
+#define aes_crypt_cfb128 mbedtls_aes_crypt_cfb128
+#define aes_crypt_cfb8 mbedtls_aes_crypt_cfb8
+#define aes_crypt_ctr mbedtls_aes_crypt_ctr
+#define aes_crypt_ecb mbedtls_aes_crypt_ecb
+#define aes_free mbedtls_aes_free
+#define aes_init mbedtls_aes_init
+#define aes_self_test mbedtls_aes_self_test
+#define aes_setkey_dec mbedtls_aes_setkey_dec
+#define aes_setkey_enc mbedtls_aes_setkey_enc
+#define aesni_crypt_ecb mbedtls_aesni_crypt_ecb
+#define aesni_gcm_mult mbedtls_aesni_gcm_mult
+#define aesni_inverse_key mbedtls_aesni_inverse_key
+#define aesni_setkey_enc mbedtls_aesni_setkey_enc
+#define aesni_supports mbedtls_aesni_has_support
+#define alarmed mbedtls_timing_alarmed
+#define arc4_context mbedtls_arc4_context
+#define arc4_crypt mbedtls_arc4_crypt
+#define arc4_free mbedtls_arc4_free
+#define arc4_init mbedtls_arc4_init
+#define arc4_self_test mbedtls_arc4_self_test
+#define arc4_setup mbedtls_arc4_setup
+#define asn1_bitstring mbedtls_asn1_bitstring
+#define asn1_buf mbedtls_asn1_buf
+#define asn1_find_named_data mbedtls_asn1_find_named_data
+#define asn1_free_named_data mbedtls_asn1_free_named_data
+#define asn1_free_named_data_list mbedtls_asn1_free_named_data_list
+#define asn1_get_alg mbedtls_asn1_get_alg
+#define asn1_get_alg_null mbedtls_asn1_get_alg_null
+#define asn1_get_bitstring mbedtls_asn1_get_bitstring
+#define asn1_get_bitstring_null mbedtls_asn1_get_bitstring_null
+#define asn1_get_bool mbedtls_asn1_get_bool
+#define asn1_get_int mbedtls_asn1_get_int
+#define asn1_get_len mbedtls_asn1_get_len
+#define asn1_get_mpi mbedtls_asn1_get_mpi
+#define asn1_get_sequence_of mbedtls_asn1_get_sequence_of
+#define asn1_get_tag mbedtls_asn1_get_tag
+#define asn1_named_data mbedtls_asn1_named_data
+#define asn1_sequence mbedtls_asn1_sequence
+#define asn1_store_named_data mbedtls_asn1_store_named_data
+#define asn1_write_algorithm_identifier mbedtls_asn1_write_algorithm_identifier
+#define asn1_write_bitstring mbedtls_asn1_write_bitstring
+#define asn1_write_bool mbedtls_asn1_write_bool
+#define asn1_write_ia5_string mbedtls_asn1_write_ia5_string
+#define asn1_write_int mbedtls_asn1_write_int
+#define asn1_write_len mbedtls_asn1_write_len
+#define asn1_write_mpi mbedtls_asn1_write_mpi
+#define asn1_write_null mbedtls_asn1_write_null
+#define asn1_write_octet_string mbedtls_asn1_write_octet_string
+#define asn1_write_oid mbedtls_asn1_write_oid
+#define asn1_write_printable_string mbedtls_asn1_write_printable_string
+#define asn1_write_raw_buffer mbedtls_asn1_write_raw_buffer
+#define asn1_write_tag mbedtls_asn1_write_tag
+#define base64_decode mbedtls_base64_decode
+#define base64_encode mbedtls_base64_encode
+#define base64_self_test mbedtls_base64_self_test
+#define blowfish_context mbedtls_blowfish_context
+#define blowfish_crypt_cbc mbedtls_blowfish_crypt_cbc
+#define blowfish_crypt_cfb64 mbedtls_blowfish_crypt_cfb64
+#define blowfish_crypt_ctr mbedtls_blowfish_crypt_ctr
+#define blowfish_crypt_ecb mbedtls_blowfish_crypt_ecb
+#define blowfish_free mbedtls_blowfish_free
+#define blowfish_init mbedtls_blowfish_init
+#define blowfish_setkey mbedtls_blowfish_setkey
+#define camellia_context mbedtls_camellia_context
+#define camellia_crypt_cbc mbedtls_camellia_crypt_cbc
+#define camellia_crypt_cfb128 mbedtls_camellia_crypt_cfb128
+#define camellia_crypt_ctr mbedtls_camellia_crypt_ctr
+#define camellia_crypt_ecb mbedtls_camellia_crypt_ecb
+#define camellia_free mbedtls_camellia_free
+#define camellia_init mbedtls_camellia_init
+#define camellia_self_test mbedtls_camellia_self_test
+#define camellia_setkey_dec mbedtls_camellia_setkey_dec
+#define camellia_setkey_enc mbedtls_camellia_setkey_enc
+#define ccm_auth_decrypt mbedtls_ccm_auth_decrypt
+#define ccm_context mbedtls_ccm_context
+#define ccm_encrypt_and_tag mbedtls_ccm_encrypt_and_tag
+#define ccm_free mbedtls_ccm_free
+#define ccm_init mbedtls_ccm_init
+#define ccm_self_test mbedtls_ccm_self_test
+#define cipher_auth_decrypt mbedtls_cipher_auth_decrypt
+#define cipher_auth_encrypt mbedtls_cipher_auth_encrypt
+#define cipher_base_t mbedtls_cipher_base_t
+#define cipher_check_tag mbedtls_cipher_check_tag
+#define cipher_context_t mbedtls_cipher_context_t
+#define cipher_crypt mbedtls_cipher_crypt
+#define cipher_definition_t mbedtls_cipher_definition_t
+#define cipher_definitions mbedtls_cipher_definitions
+#define cipher_finish mbedtls_cipher_finish
+#define cipher_free mbedtls_cipher_free
+#define cipher_get_block_size mbedtls_cipher_get_block_size
+#define cipher_get_cipher_mode mbedtls_cipher_get_cipher_mode
+#define cipher_get_iv_size mbedtls_cipher_get_iv_size
+#define cipher_get_key_size mbedtls_cipher_get_key_bitlen
+#define cipher_get_name mbedtls_cipher_get_name
+#define cipher_get_operation mbedtls_cipher_get_operation
+#define cipher_get_type mbedtls_cipher_get_type
+#define cipher_id_t mbedtls_cipher_id_t
+#define cipher_info_from_string mbedtls_cipher_info_from_string
+#define cipher_info_from_type mbedtls_cipher_info_from_type
+#define cipher_info_from_values mbedtls_cipher_info_from_values
+#define cipher_info_t mbedtls_cipher_info_t
+#define cipher_init mbedtls_cipher_init
+#define cipher_init_ctx mbedtls_cipher_setup
+#define cipher_list mbedtls_cipher_list
+#define cipher_mode_t mbedtls_cipher_mode_t
+#define cipher_padding_t mbedtls_cipher_padding_t
+#define cipher_reset mbedtls_cipher_reset
+#define cipher_set_iv mbedtls_cipher_set_iv
+#define cipher_set_padding_mode mbedtls_cipher_set_padding_mode
+#define cipher_setkey mbedtls_cipher_setkey
+#define cipher_type_t mbedtls_cipher_type_t
+#define cipher_update mbedtls_cipher_update
+#define cipher_update_ad mbedtls_cipher_update_ad
+#define cipher_write_tag mbedtls_cipher_write_tag
+#define ctr_drbg_context mbedtls_ctr_drbg_context
+#define ctr_drbg_free mbedtls_ctr_drbg_free
+#define ctr_drbg_init mbedtls_ctr_drbg_init
+#define ctr_drbg_random mbedtls_ctr_drbg_random
+#define ctr_drbg_random_with_add mbedtls_ctr_drbg_random_with_add
+#define ctr_drbg_reseed mbedtls_ctr_drbg_reseed
+#define ctr_drbg_self_test mbedtls_ctr_drbg_self_test
+#define ctr_drbg_set_entropy_len mbedtls_ctr_drbg_set_entropy_len
+#define ctr_drbg_set_prediction_resistance mbedtls_ctr_drbg_set_prediction_resistance
+#define ctr_drbg_set_reseed_interval mbedtls_ctr_drbg_set_reseed_interval
+#define ctr_drbg_update mbedtls_ctr_drbg_update
+#define ctr_drbg_update_seed_file mbedtls_ctr_drbg_update_seed_file
+#define ctr_drbg_write_seed_file mbedtls_ctr_drbg_write_seed_file
+#define debug_print_buf mbedtls_debug_print_buf
+#define debug_print_crt mbedtls_debug_print_crt
+#define debug_print_ecp mbedtls_debug_print_ecp
+#define debug_print_mpi mbedtls_debug_print_mpi
+#define debug_print_msg mbedtls_debug_print_msg
+#define debug_print_ret mbedtls_debug_print_ret
+#define debug_set_threshold mbedtls_debug_set_threshold
+#define des3_context mbedtls_des3_context
+#define des3_crypt_cbc mbedtls_des3_crypt_cbc
+#define des3_crypt_ecb mbedtls_des3_crypt_ecb
+#define des3_free mbedtls_des3_free
+#define des3_init mbedtls_des3_init
+#define des3_set2key_dec mbedtls_des3_set2key_dec
+#define des3_set2key_enc mbedtls_des3_set2key_enc
+#define des3_set3key_dec mbedtls_des3_set3key_dec
+#define des3_set3key_enc mbedtls_des3_set3key_enc
+#define des_context mbedtls_des_context
+#define des_crypt_cbc mbedtls_des_crypt_cbc
+#define des_crypt_ecb mbedtls_des_crypt_ecb
+#define des_free mbedtls_des_free
+#define des_init mbedtls_des_init
+#define des_key_check_key_parity mbedtls_des_key_check_key_parity
+#define des_key_check_weak mbedtls_des_key_check_weak
+#define des_key_set_parity mbedtls_des_key_set_parity
+#define des_self_test mbedtls_des_self_test
+#define des_setkey_dec mbedtls_des_setkey_dec
+#define des_setkey_enc mbedtls_des_setkey_enc
+#define dhm_calc_secret mbedtls_dhm_calc_secret
+#define dhm_context mbedtls_dhm_context
+#define dhm_free mbedtls_dhm_free
+#define dhm_init mbedtls_dhm_init
+#define dhm_make_params mbedtls_dhm_make_params
+#define dhm_make_public mbedtls_dhm_make_public
+#define dhm_parse_dhm mbedtls_dhm_parse_dhm
+#define dhm_parse_dhmfile mbedtls_dhm_parse_dhmfile
+#define dhm_read_params mbedtls_dhm_read_params
+#define dhm_read_public mbedtls_dhm_read_public
+#define dhm_self_test mbedtls_dhm_self_test
+#define ecdh_calc_secret mbedtls_ecdh_calc_secret
+#define ecdh_compute_shared mbedtls_ecdh_compute_shared
+#define ecdh_context mbedtls_ecdh_context
+#define ecdh_free mbedtls_ecdh_free
+#define ecdh_gen_public mbedtls_ecdh_gen_public
+#define ecdh_get_params mbedtls_ecdh_get_params
+#define ecdh_init mbedtls_ecdh_init
+#define ecdh_make_params mbedtls_ecdh_make_params
+#define ecdh_make_public mbedtls_ecdh_make_public
+#define ecdh_read_params mbedtls_ecdh_read_params
+#define ecdh_read_public mbedtls_ecdh_read_public
+#define ecdh_side mbedtls_ecdh_side
+#define ecdsa_context mbedtls_ecdsa_context
+#define ecdsa_free mbedtls_ecdsa_free
+#define ecdsa_from_keypair mbedtls_ecdsa_from_keypair
+#define ecdsa_genkey mbedtls_ecdsa_genkey
+#define ecdsa_info mbedtls_ecdsa_info
+#define ecdsa_init mbedtls_ecdsa_init
+#define ecdsa_read_signature mbedtls_ecdsa_read_signature
+#define ecdsa_sign mbedtls_ecdsa_sign
+#define ecdsa_sign_det mbedtls_ecdsa_sign_det
+#define ecdsa_verify mbedtls_ecdsa_verify
+#define ecdsa_write_signature mbedtls_ecdsa_write_signature
+#define ecdsa_write_signature_det mbedtls_ecdsa_write_signature_det
+#define eckey_info mbedtls_eckey_info
+#define eckeydh_info mbedtls_eckeydh_info
+#define ecp_check_privkey mbedtls_ecp_check_privkey
+#define ecp_check_pub_priv mbedtls_ecp_check_pub_priv
+#define ecp_check_pubkey mbedtls_ecp_check_pubkey
+#define ecp_copy mbedtls_ecp_copy
+#define ecp_curve_info mbedtls_ecp_curve_info
+#define ecp_curve_info_from_grp_id mbedtls_ecp_curve_info_from_grp_id
+#define ecp_curve_info_from_name mbedtls_ecp_curve_info_from_name
+#define ecp_curve_info_from_tls_id mbedtls_ecp_curve_info_from_tls_id
+#define ecp_curve_list mbedtls_ecp_curve_list
+#define ecp_gen_key mbedtls_ecp_gen_key
+#define ecp_gen_keypair mbedtls_ecp_gen_keypair
+#define ecp_group mbedtls_ecp_group
+#define ecp_group_copy mbedtls_ecp_group_copy
+#define ecp_group_free mbedtls_ecp_group_free
+#define ecp_group_id mbedtls_ecp_group_id
+#define ecp_group_init mbedtls_ecp_group_init
+#define ecp_grp_id_list mbedtls_ecp_grp_id_list
+#define ecp_is_zero mbedtls_ecp_is_zero
+#define ecp_keypair mbedtls_ecp_keypair
+#define ecp_keypair_free mbedtls_ecp_keypair_free
+#define ecp_keypair_init mbedtls_ecp_keypair_init
+#define ecp_mul mbedtls_ecp_mul
+#define ecp_point mbedtls_ecp_point
+#define ecp_point_free mbedtls_ecp_point_free
+#define ecp_point_init mbedtls_ecp_point_init
+#define ecp_point_read_binary mbedtls_ecp_point_read_binary
+#define ecp_point_read_string mbedtls_ecp_point_read_string
+#define ecp_point_write_binary mbedtls_ecp_point_write_binary
+#define ecp_self_test mbedtls_ecp_self_test
+#define ecp_set_zero mbedtls_ecp_set_zero
+#define ecp_tls_read_group mbedtls_ecp_tls_read_group
+#define ecp_tls_read_point mbedtls_ecp_tls_read_point
+#define ecp_tls_write_group mbedtls_ecp_tls_write_group
+#define ecp_tls_write_point mbedtls_ecp_tls_write_point
+#define ecp_use_known_dp mbedtls_ecp_group_load
+#define entropy_add_source mbedtls_entropy_add_source
+#define entropy_context mbedtls_entropy_context
+#define entropy_free mbedtls_entropy_free
+#define entropy_func mbedtls_entropy_func
+#define entropy_gather mbedtls_entropy_gather
+#define entropy_init mbedtls_entropy_init
+#define entropy_self_test mbedtls_entropy_self_test
+#define entropy_update_manual mbedtls_entropy_update_manual
+#define entropy_update_seed_file mbedtls_entropy_update_seed_file
+#define entropy_write_seed_file mbedtls_entropy_write_seed_file
+#define error_strerror mbedtls_strerror
+#define f_source_ptr mbedtls_entropy_f_source_ptr
+#define gcm_auth_decrypt mbedtls_gcm_auth_decrypt
+#define gcm_context mbedtls_gcm_context
+#define gcm_crypt_and_tag mbedtls_gcm_crypt_and_tag
+#define gcm_finish mbedtls_gcm_finish
+#define gcm_free mbedtls_gcm_free
+#define gcm_init mbedtls_gcm_init
+#define gcm_self_test mbedtls_gcm_self_test
+#define gcm_starts mbedtls_gcm_starts
+#define gcm_update mbedtls_gcm_update
+#define get_timer mbedtls_timing_get_timer
+#define hardclock mbedtls_timing_hardclock
+#define hardclock_poll mbedtls_hardclock_poll
+#define havege_free mbedtls_havege_free
+#define havege_init mbedtls_havege_init
+#define havege_poll mbedtls_havege_poll
+#define havege_random mbedtls_havege_random
+#define havege_state mbedtls_havege_state
+#define hmac_drbg_context mbedtls_hmac_drbg_context
+#define hmac_drbg_free mbedtls_hmac_drbg_free
+#define hmac_drbg_init mbedtls_hmac_drbg_init
+#define hmac_drbg_random mbedtls_hmac_drbg_random
+#define hmac_drbg_random_with_add mbedtls_hmac_drbg_random_with_add
+#define hmac_drbg_reseed mbedtls_hmac_drbg_reseed
+#define hmac_drbg_self_test mbedtls_hmac_drbg_self_test
+#define hmac_drbg_set_entropy_len mbedtls_hmac_drbg_set_entropy_len
+#define hmac_drbg_set_prediction_resistance mbedtls_hmac_drbg_set_prediction_resistance
+#define hmac_drbg_set_reseed_interval mbedtls_hmac_drbg_set_reseed_interval
+#define hmac_drbg_update mbedtls_hmac_drbg_update
+#define hmac_drbg_update_seed_file mbedtls_hmac_drbg_update_seed_file
+#define hmac_drbg_write_seed_file mbedtls_hmac_drbg_write_seed_file
+#define hr_time mbedtls_timing_hr_time
+#define key_exchange_type_t mbedtls_key_exchange_type_t
+#define md mbedtls_md
+#define md2 mbedtls_md2
+#define md2_context mbedtls_md2_context
+#define md2_finish mbedtls_md2_finish
+#define md2_free mbedtls_md2_free
+#define md2_info mbedtls_md2_info
+#define md2_init mbedtls_md2_init
+#define md2_process mbedtls_md2_process
+#define md2_self_test mbedtls_md2_self_test
+#define md2_starts mbedtls_md2_starts
+#define md2_update mbedtls_md2_update
+#define md4 mbedtls_md4
+#define md4_context mbedtls_md4_context
+#define md4_finish mbedtls_md4_finish
+#define md4_free mbedtls_md4_free
+#define md4_info mbedtls_md4_info
+#define md4_init mbedtls_md4_init
+#define md4_process mbedtls_md4_process
+#define md4_self_test mbedtls_md4_self_test
+#define md4_starts mbedtls_md4_starts
+#define md4_update mbedtls_md4_update
+#define md5 mbedtls_md5
+#define md5_context mbedtls_md5_context
+#define md5_finish mbedtls_md5_finish
+#define md5_free mbedtls_md5_free
+#define md5_info mbedtls_md5_info
+#define md5_init mbedtls_md5_init
+#define md5_process mbedtls_md5_process
+#define md5_self_test mbedtls_md5_self_test
+#define md5_starts mbedtls_md5_starts
+#define md5_update mbedtls_md5_update
+#define md_context_t mbedtls_md_context_t
+#define md_file mbedtls_md_file
+#define md_finish mbedtls_md_finish
+#define md_free mbedtls_md_free
+#define md_get_name mbedtls_md_get_name
+#define md_get_size mbedtls_md_get_size
+#define md_get_type mbedtls_md_get_type
+#define md_hmac mbedtls_md_hmac
+#define md_hmac_finish mbedtls_md_hmac_finish
+#define md_hmac_reset mbedtls_md_hmac_reset
+#define md_hmac_starts mbedtls_md_hmac_starts
+#define md_hmac_update mbedtls_md_hmac_update
+#define md_info_from_string mbedtls_md_info_from_string
+#define md_info_from_type mbedtls_md_info_from_type
+#define md_info_t mbedtls_md_info_t
+#define md_init mbedtls_md_init
+#define md_init_ctx mbedtls_md_init_ctx
+#define md_list mbedtls_md_list
+#define md_process mbedtls_md_process
+#define md_starts mbedtls_md_starts
+#define md_type_t mbedtls_md_type_t
+#define md_update mbedtls_md_update
+#define memory_buffer_alloc_cur_get mbedtls_memory_buffer_alloc_cur_get
+#define memory_buffer_alloc_free mbedtls_memory_buffer_alloc_free
+#define memory_buffer_alloc_init mbedtls_memory_buffer_alloc_init
+#define memory_buffer_alloc_max_get mbedtls_memory_buffer_alloc_max_get
+#define memory_buffer_alloc_max_reset mbedtls_memory_buffer_alloc_max_reset
+#define memory_buffer_alloc_self_test mbedtls_memory_buffer_alloc_self_test
+#define memory_buffer_alloc_status mbedtls_memory_buffer_alloc_status
+#define memory_buffer_alloc_verify mbedtls_memory_buffer_alloc_verify
+#define memory_buffer_set_verify mbedtls_memory_buffer_set_verify
+#define mpi mbedtls_mpi
+#define mpi_add_abs mbedtls_mpi_add_abs
+#define mpi_add_int mbedtls_mpi_add_int
+#define mpi_add_mpi mbedtls_mpi_add_mpi
+#define mpi_cmp_abs mbedtls_mpi_cmp_abs
+#define mpi_cmp_int mbedtls_mpi_cmp_int
+#define mpi_cmp_mpi mbedtls_mpi_cmp_mpi
+#define mpi_copy mbedtls_mpi_copy
+#define mpi_div_int mbedtls_mpi_div_int
+#define mpi_div_mpi mbedtls_mpi_div_mpi
+#define mpi_exp_mod mbedtls_mpi_exp_mod
+#define mpi_fill_random mbedtls_mpi_fill_random
+#define mpi_free mbedtls_mpi_free
+#define mpi_gcd mbedtls_mpi_gcd
+#define mpi_gen_prime mbedtls_mpi_gen_prime
+#define mpi_get_bit mbedtls_mpi_get_bit
+#define mpi_grow mbedtls_mpi_grow
+#define mpi_init mbedtls_mpi_init
+#define mpi_inv_mod mbedtls_mpi_inv_mod
+#define mpi_is_prime mbedtls_mpi_is_prime
+#define mpi_lsb mbedtls_mpi_lsb
+#define mpi_lset mbedtls_mpi_lset
+#define mpi_mod_int mbedtls_mpi_mod_int
+#define mpi_mod_mpi mbedtls_mpi_mod_mpi
+#define mpi_msb mbedtls_mpi_bitlen
+#define mpi_mul_int mbedtls_mpi_mul_int
+#define mpi_mul_mpi mbedtls_mpi_mul_mpi
+#define mpi_read_binary mbedtls_mpi_read_binary
+#define mpi_read_file mbedtls_mpi_read_file
+#define mpi_read_string mbedtls_mpi_read_string
+#define mpi_safe_cond_assign mbedtls_mpi_safe_cond_assign
+#define mpi_safe_cond_swap mbedtls_mpi_safe_cond_swap
+#define mpi_self_test mbedtls_mpi_self_test
+#define mpi_set_bit mbedtls_mpi_set_bit
+#define mpi_shift_l mbedtls_mpi_shift_l
+#define mpi_shift_r mbedtls_mpi_shift_r
+#define mpi_shrink mbedtls_mpi_shrink
+#define mpi_size mbedtls_mpi_size
+#define mpi_sub_abs mbedtls_mpi_sub_abs
+#define mpi_sub_int mbedtls_mpi_sub_int
+#define mpi_sub_mpi mbedtls_mpi_sub_mpi
+#define mpi_swap mbedtls_mpi_swap
+#define mpi_write_binary mbedtls_mpi_write_binary
+#define mpi_write_file mbedtls_mpi_write_file
+#define mpi_write_string mbedtls_mpi_write_string
+#define net_accept mbedtls_net_accept
+#define net_bind mbedtls_net_bind
+#define net_close mbedtls_net_free
+#define net_connect mbedtls_net_connect
+#define net_recv mbedtls_net_recv
+#define net_recv_timeout mbedtls_net_recv_timeout
+#define net_send mbedtls_net_send
+#define net_set_block mbedtls_net_set_block
+#define net_set_nonblock mbedtls_net_set_nonblock
+#define net_usleep mbedtls_net_usleep
+#define oid_descriptor_t mbedtls_oid_descriptor_t
+#define oid_get_attr_short_name mbedtls_oid_get_attr_short_name
+#define oid_get_cipher_alg mbedtls_oid_get_cipher_alg
+#define oid_get_ec_grp mbedtls_oid_get_ec_grp
+#define oid_get_extended_key_usage mbedtls_oid_get_extended_key_usage
+#define oid_get_md_alg mbedtls_oid_get_md_alg
+#define oid_get_numeric_string mbedtls_oid_get_numeric_string
+#define oid_get_oid_by_ec_grp mbedtls_oid_get_oid_by_ec_grp
+#define oid_get_oid_by_md mbedtls_oid_get_oid_by_md
+#define oid_get_oid_by_pk_alg mbedtls_oid_get_oid_by_pk_alg
+#define oid_get_oid_by_sig_alg mbedtls_oid_get_oid_by_sig_alg
+#define oid_get_pk_alg mbedtls_oid_get_pk_alg
+#define oid_get_pkcs12_pbe_alg mbedtls_oid_get_pkcs12_pbe_alg
+#define oid_get_sig_alg mbedtls_oid_get_sig_alg
+#define oid_get_sig_alg_desc mbedtls_oid_get_sig_alg_desc
+#define oid_get_x509_ext_type mbedtls_oid_get_x509_ext_type
+#define operation_t mbedtls_operation_t
+#define padlock_supports mbedtls_padlock_has_support
+#define padlock_xcryptcbc mbedtls_padlock_xcryptcbc
+#define padlock_xcryptecb mbedtls_padlock_xcryptecb
+#define pem_context mbedtls_pem_context
+#define pem_free mbedtls_pem_free
+#define pem_init mbedtls_pem_init
+#define pem_read_buffer mbedtls_pem_read_buffer
+#define pem_write_buffer mbedtls_pem_write_buffer
+#define pk_can_do mbedtls_pk_can_do
+#define pk_check_pair mbedtls_pk_check_pair
+#define pk_context mbedtls_pk_context
+#define pk_debug mbedtls_pk_debug
+#define pk_debug_item mbedtls_pk_debug_item
+#define pk_debug_type mbedtls_pk_debug_type
+#define pk_decrypt mbedtls_pk_decrypt
+#define pk_ec mbedtls_pk_ec
+#define pk_encrypt mbedtls_pk_encrypt
+#define pk_free mbedtls_pk_free
+#define pk_get_len mbedtls_pk_get_len
+#define pk_get_name mbedtls_pk_get_name
+#define pk_get_size mbedtls_pk_get_bitlen
+#define pk_get_type mbedtls_pk_get_type
+#define pk_info_from_type mbedtls_pk_info_from_type
+#define pk_info_t mbedtls_pk_info_t
+#define pk_init mbedtls_pk_init
+#define pk_init_ctx mbedtls_pk_setup
+#define pk_init_ctx_rsa_alt mbedtls_pk_setup_rsa_alt
+#define pk_load_file mbedtls_pk_load_file
+#define pk_parse_key mbedtls_pk_parse_key
+#define pk_parse_keyfile mbedtls_pk_parse_keyfile
+#define pk_parse_public_key mbedtls_pk_parse_public_key
+#define pk_parse_public_keyfile mbedtls_pk_parse_public_keyfile
+#define pk_parse_subpubkey mbedtls_pk_parse_subpubkey
+#define pk_rsa mbedtls_pk_rsa
+#define pk_rsa_alt_decrypt_func mbedtls_pk_rsa_alt_decrypt_func
+#define pk_rsa_alt_key_len_func mbedtls_pk_rsa_alt_key_len_func
+#define pk_rsa_alt_sign_func mbedtls_pk_rsa_alt_sign_func
+#define pk_rsassa_pss_options mbedtls_pk_rsassa_pss_options
+#define pk_sign mbedtls_pk_sign
+#define pk_type_t mbedtls_pk_type_t
+#define pk_verify mbedtls_pk_verify
+#define pk_verify_ext mbedtls_pk_verify_ext
+#define pk_write_key_der mbedtls_pk_write_key_der
+#define pk_write_key_pem mbedtls_pk_write_key_pem
+#define pk_write_pubkey mbedtls_pk_write_pubkey
+#define pk_write_pubkey_der mbedtls_pk_write_pubkey_der
+#define pk_write_pubkey_pem mbedtls_pk_write_pubkey_pem
+#define pkcs11_context mbedtls_pkcs11_context
+#define pkcs11_decrypt mbedtls_pkcs11_decrypt
+#define pkcs11_priv_key_free mbedtls_pkcs11_priv_key_free
+#define pkcs11_priv_key_init mbedtls_pkcs11_priv_key_bind
+#define pkcs11_sign mbedtls_pkcs11_sign
+#define pkcs11_x509_cert_init mbedtls_pkcs11_x509_cert_bind
+#define pkcs12_derivation mbedtls_pkcs12_derivation
+#define pkcs12_pbe mbedtls_pkcs12_pbe
+#define pkcs12_pbe_sha1_rc4_128 mbedtls_pkcs12_pbe_sha1_rc4_128
+#define pkcs5_pbes2 mbedtls_pkcs5_pbes2
+#define pkcs5_pbkdf2_hmac mbedtls_pkcs5_pbkdf2_hmac
+#define pkcs5_self_test mbedtls_pkcs5_self_test
+#define platform_entropy_poll mbedtls_platform_entropy_poll
+#define platform_set_exit mbedtls_platform_set_exit
+#define platform_set_fprintf mbedtls_platform_set_fprintf
+#define platform_set_printf mbedtls_platform_set_printf
+#define platform_set_snprintf mbedtls_platform_set_snprintf
+#define polarssl_exit mbedtls_exit
+#define polarssl_fprintf mbedtls_fprintf
+#define polarssl_free mbedtls_free
+#define polarssl_mutex_free mbedtls_mutex_free
+#define polarssl_mutex_init mbedtls_mutex_init
+#define polarssl_mutex_lock mbedtls_mutex_lock
+#define polarssl_mutex_unlock mbedtls_mutex_unlock
+#define polarssl_printf mbedtls_printf
+#define polarssl_snprintf mbedtls_snprintf
+#define polarssl_strerror mbedtls_strerror
+#define ripemd160 mbedtls_ripemd160
+#define ripemd160_context mbedtls_ripemd160_context
+#define ripemd160_finish mbedtls_ripemd160_finish
+#define ripemd160_free mbedtls_ripemd160_free
+#define ripemd160_info mbedtls_ripemd160_info
+#define ripemd160_init mbedtls_ripemd160_init
+#define ripemd160_process mbedtls_ripemd160_process
+#define ripemd160_self_test mbedtls_ripemd160_self_test
+#define ripemd160_starts mbedtls_ripemd160_starts
+#define ripemd160_update mbedtls_ripemd160_update
+#define rsa_alt_context mbedtls_rsa_alt_context
+#define rsa_alt_info mbedtls_rsa_alt_info
+#define rsa_check_privkey mbedtls_rsa_check_privkey
+#define rsa_check_pub_priv mbedtls_rsa_check_pub_priv
+#define rsa_check_pubkey mbedtls_rsa_check_pubkey
+#define rsa_context mbedtls_rsa_context
+#define rsa_copy mbedtls_rsa_copy
+#define rsa_free mbedtls_rsa_free
+#define rsa_gen_key mbedtls_rsa_gen_key
+#define rsa_info mbedtls_rsa_info
+#define rsa_init mbedtls_rsa_init
+#define rsa_pkcs1_decrypt mbedtls_rsa_pkcs1_decrypt
+#define rsa_pkcs1_encrypt mbedtls_rsa_pkcs1_encrypt
+#define rsa_pkcs1_sign mbedtls_rsa_pkcs1_sign
+#define rsa_pkcs1_verify mbedtls_rsa_pkcs1_verify
+#define rsa_private mbedtls_rsa_private
+#define rsa_public mbedtls_rsa_public
+#define rsa_rsaes_oaep_decrypt mbedtls_rsa_rsaes_oaep_decrypt
+#define rsa_rsaes_oaep_encrypt mbedtls_rsa_rsaes_oaep_encrypt
+#define rsa_rsaes_pkcs1_v15_decrypt mbedtls_rsa_rsaes_pkcs1_v15_decrypt
+#define rsa_rsaes_pkcs1_v15_encrypt mbedtls_rsa_rsaes_pkcs1_v15_encrypt
+#define rsa_rsassa_pkcs1_v15_sign mbedtls_rsa_rsassa_pkcs1_v15_sign
+#define rsa_rsassa_pkcs1_v15_verify mbedtls_rsa_rsassa_pkcs1_v15_verify
+#define rsa_rsassa_pss_sign mbedtls_rsa_rsassa_pss_sign
+#define rsa_rsassa_pss_verify mbedtls_rsa_rsassa_pss_verify
+#define rsa_rsassa_pss_verify_ext mbedtls_rsa_rsassa_pss_verify_ext
+#define rsa_self_test mbedtls_rsa_self_test
+#define rsa_set_padding mbedtls_rsa_set_padding
+#define safer_memcmp mbedtls_ssl_safer_memcmp
+#define set_alarm mbedtls_set_alarm
+#define sha1 mbedtls_sha1
+#define sha1_context mbedtls_sha1_context
+#define sha1_finish mbedtls_sha1_finish
+#define sha1_free mbedtls_sha1_free
+#define sha1_info mbedtls_sha1_info
+#define sha1_init mbedtls_sha1_init
+#define sha1_process mbedtls_sha1_process
+#define sha1_self_test mbedtls_sha1_self_test
+#define sha1_starts mbedtls_sha1_starts
+#define sha1_update mbedtls_sha1_update
+#define sha224_info mbedtls_sha224_info
+#define sha256 mbedtls_sha256
+#define sha256_context mbedtls_sha256_context
+#define sha256_finish mbedtls_sha256_finish
+#define sha256_free mbedtls_sha256_free
+#define sha256_info mbedtls_sha256_info
+#define sha256_init mbedtls_sha256_init
+#define sha256_process mbedtls_sha256_process
+#define sha256_self_test mbedtls_sha256_self_test
+#define sha256_starts mbedtls_sha256_starts
+#define sha256_update mbedtls_sha256_update
+#define sha384_info mbedtls_sha384_info
+#define sha512 mbedtls_sha512
+#define sha512_context mbedtls_sha512_context
+#define sha512_finish mbedtls_sha512_finish
+#define sha512_free mbedtls_sha512_free
+#define sha512_info mbedtls_sha512_info
+#define sha512_init mbedtls_sha512_init
+#define sha512_process mbedtls_sha512_process
+#define sha512_self_test mbedtls_sha512_self_test
+#define sha512_starts mbedtls_sha512_starts
+#define sha512_update mbedtls_sha512_update
+#define source_state mbedtls_entropy_source_state
+#define ssl_cache_context mbedtls_ssl_cache_context
+#define ssl_cache_entry mbedtls_ssl_cache_entry
+#define ssl_cache_free mbedtls_ssl_cache_free
+#define ssl_cache_get mbedtls_ssl_cache_get
+#define ssl_cache_init mbedtls_ssl_cache_init
+#define ssl_cache_set mbedtls_ssl_cache_set
+#define ssl_cache_set_max_entries mbedtls_ssl_cache_set_max_entries
+#define ssl_cache_set_timeout mbedtls_ssl_cache_set_timeout
+#define ssl_check_cert_usage mbedtls_ssl_check_cert_usage
+#define ssl_ciphersuite_from_id mbedtls_ssl_ciphersuite_from_id
+#define ssl_ciphersuite_from_string mbedtls_ssl_ciphersuite_from_string
+#define ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t
+#define ssl_ciphersuite_uses_ec mbedtls_ssl_ciphersuite_uses_ec
+#define ssl_ciphersuite_uses_psk mbedtls_ssl_ciphersuite_uses_psk
+#define ssl_close_notify mbedtls_ssl_close_notify
+#define ssl_context mbedtls_ssl_context
+#define ssl_cookie_check mbedtls_ssl_cookie_check
+#define ssl_cookie_check_t mbedtls_ssl_cookie_check_t
+#define ssl_cookie_ctx mbedtls_ssl_cookie_ctx
+#define ssl_cookie_free mbedtls_ssl_cookie_free
+#define ssl_cookie_init mbedtls_ssl_cookie_init
+#define ssl_cookie_set_timeout mbedtls_ssl_cookie_set_timeout
+#define ssl_cookie_setup mbedtls_ssl_cookie_setup
+#define ssl_cookie_write mbedtls_ssl_cookie_write
+#define ssl_cookie_write_t mbedtls_ssl_cookie_write_t
+#define ssl_derive_keys mbedtls_ssl_derive_keys
+#define ssl_dtls_replay_check mbedtls_ssl_dtls_replay_check
+#define ssl_dtls_replay_update mbedtls_ssl_dtls_replay_update
+#define ssl_fetch_input mbedtls_ssl_fetch_input
+#define ssl_flight_item mbedtls_ssl_flight_item
+#define ssl_flush_output mbedtls_ssl_flush_output
+#define ssl_free mbedtls_ssl_free
+#define ssl_get_alpn_protocol mbedtls_ssl_get_alpn_protocol
+#define ssl_get_bytes_avail mbedtls_ssl_get_bytes_avail
+#define ssl_get_ciphersuite mbedtls_ssl_get_ciphersuite
+#define ssl_get_ciphersuite_id mbedtls_ssl_get_ciphersuite_id
+#define ssl_get_ciphersuite_name mbedtls_ssl_get_ciphersuite_name
+#define ssl_get_ciphersuite_sig_pk_alg mbedtls_ssl_get_ciphersuite_sig_pk_alg
+#define ssl_get_peer_cert mbedtls_ssl_get_peer_cert
+#define ssl_get_record_expansion mbedtls_ssl_get_record_expansion
+#define ssl_get_session mbedtls_ssl_get_session
+#define ssl_get_verify_result mbedtls_ssl_get_verify_result
+#define ssl_get_version mbedtls_ssl_get_version
+#define ssl_handshake mbedtls_ssl_handshake
+#define ssl_handshake_client_step mbedtls_ssl_handshake_client_step
+#define ssl_handshake_free mbedtls_ssl_handshake_free
+#define ssl_handshake_params mbedtls_ssl_handshake_params
+#define ssl_handshake_server_step mbedtls_ssl_handshake_server_step
+#define ssl_handshake_step mbedtls_ssl_handshake_step
+#define ssl_handshake_wrapup mbedtls_ssl_handshake_wrapup
+#define ssl_hdr_len mbedtls_ssl_hdr_len
+#define ssl_hs_hdr_len mbedtls_ssl_hs_hdr_len
+#define ssl_hw_record_activate mbedtls_ssl_hw_record_activate
+#define ssl_hw_record_finish mbedtls_ssl_hw_record_finish
+#define ssl_hw_record_init mbedtls_ssl_hw_record_init
+#define ssl_hw_record_read mbedtls_ssl_hw_record_read
+#define ssl_hw_record_reset mbedtls_ssl_hw_record_reset
+#define ssl_hw_record_write mbedtls_ssl_hw_record_write
+#define ssl_init mbedtls_ssl_init
+#define ssl_key_cert mbedtls_ssl_key_cert
+#define ssl_legacy_renegotiation mbedtls_ssl_conf_legacy_renegotiation
+#define ssl_list_ciphersuites mbedtls_ssl_list_ciphersuites
+#define ssl_md_alg_from_hash mbedtls_ssl_md_alg_from_hash
+#define ssl_optimize_checksum mbedtls_ssl_optimize_checksum
+#define ssl_own_cert mbedtls_ssl_own_cert
+#define ssl_own_key mbedtls_ssl_own_key
+#define ssl_parse_certificate mbedtls_ssl_parse_certificate
+#define ssl_parse_change_cipher_spec mbedtls_ssl_parse_change_cipher_spec
+#define ssl_parse_finished mbedtls_ssl_parse_finished
+#define ssl_pk_alg_from_sig mbedtls_ssl_pk_alg_from_sig
+#define ssl_pkcs11_decrypt mbedtls_ssl_pkcs11_decrypt
+#define ssl_pkcs11_key_len mbedtls_ssl_pkcs11_key_len
+#define ssl_pkcs11_sign mbedtls_ssl_pkcs11_sign
+#define ssl_psk_derive_premaster mbedtls_ssl_psk_derive_premaster
+#define ssl_read mbedtls_ssl_read
+#define ssl_read_record mbedtls_ssl_read_record
+#define ssl_read_version mbedtls_ssl_read_version
+#define ssl_recv_flight_completed mbedtls_ssl_recv_flight_completed
+#define ssl_renegotiate mbedtls_ssl_renegotiate
+#define ssl_resend mbedtls_ssl_resend
+#define ssl_reset_checksum mbedtls_ssl_reset_checksum
+#define ssl_send_alert_message mbedtls_ssl_send_alert_message
+#define ssl_send_fatal_handshake_failure mbedtls_ssl_send_fatal_handshake_failure
+#define ssl_send_flight_completed mbedtls_ssl_send_flight_completed
+#define ssl_session mbedtls_ssl_session
+#define ssl_session_free mbedtls_ssl_session_free
+#define ssl_session_init mbedtls_ssl_session_init
+#define ssl_session_reset mbedtls_ssl_session_reset
+#define ssl_set_alpn_protocols mbedtls_ssl_conf_alpn_protocols
+#define ssl_set_arc4_support mbedtls_ssl_conf_arc4_support
+#define ssl_set_authmode mbedtls_ssl_conf_authmode
+#define ssl_set_bio mbedtls_ssl_set_bio
+#define ssl_set_ca_chain mbedtls_ssl_conf_ca_chain
+#define ssl_set_cbc_record_splitting mbedtls_ssl_conf_cbc_record_splitting
+#define ssl_set_ciphersuites mbedtls_ssl_conf_ciphersuites
+#define ssl_set_ciphersuites_for_version mbedtls_ssl_conf_ciphersuites_for_version
+#define ssl_set_client_transport_id mbedtls_ssl_set_client_transport_id
+#define ssl_set_curves mbedtls_ssl_conf_curves
+#define ssl_set_dbg mbedtls_ssl_conf_dbg
+#define ssl_set_dh_param mbedtls_ssl_conf_dh_param
+#define ssl_set_dh_param_ctx mbedtls_ssl_conf_dh_param_ctx
+#define ssl_set_dtls_anti_replay mbedtls_ssl_conf_dtls_anti_replay
+#define ssl_set_dtls_badmac_limit mbedtls_ssl_conf_dtls_badmac_limit
+#define ssl_set_dtls_cookies mbedtls_ssl_conf_dtls_cookies
+#define ssl_set_encrypt_then_mac mbedtls_ssl_conf_encrypt_then_mac
+#define ssl_set_endpoint mbedtls_ssl_conf_endpoint
+#define ssl_set_extended_master_secret mbedtls_ssl_conf_extended_master_secret
+#define ssl_set_fallback mbedtls_ssl_conf_fallback
+#define ssl_set_handshake_timeout mbedtls_ssl_conf_handshake_timeout
+#define ssl_set_hostname mbedtls_ssl_set_hostname
+#define ssl_set_max_frag_len mbedtls_ssl_conf_max_frag_len
+#define ssl_set_max_version mbedtls_ssl_conf_max_version
+#define ssl_set_min_version mbedtls_ssl_conf_min_version
+#define ssl_set_own_cert mbedtls_ssl_conf_own_cert
+#define ssl_set_psk mbedtls_ssl_conf_psk
+#define ssl_set_psk_cb mbedtls_ssl_conf_psk_cb
+#define ssl_set_renegotiation mbedtls_ssl_conf_renegotiation
+#define ssl_set_renegotiation_enforced mbedtls_ssl_conf_renegotiation_enforced
+#define ssl_set_renegotiation_period mbedtls_ssl_conf_renegotiation_period
+#define ssl_set_rng mbedtls_ssl_conf_rng
+#define ssl_set_session mbedtls_ssl_set_session
+#define ssl_set_session_cache mbedtls_ssl_conf_session_cache
+#define ssl_set_session_tickets mbedtls_ssl_conf_session_tickets
+#define ssl_set_sni mbedtls_ssl_conf_sni
+#define ssl_set_transport mbedtls_ssl_conf_transport
+#define ssl_set_truncated_hmac mbedtls_ssl_conf_truncated_hmac
+#define ssl_set_verify mbedtls_ssl_conf_verify
+#define ssl_sig_from_pk mbedtls_ssl_sig_from_pk
+#define ssl_states mbedtls_ssl_states
+#define ssl_transform mbedtls_ssl_transform
+#define ssl_transform_free mbedtls_ssl_transform_free
+#define ssl_write mbedtls_ssl_write
+#define ssl_write_certificate mbedtls_ssl_write_certificate
+#define ssl_write_change_cipher_spec mbedtls_ssl_write_change_cipher_spec
+#define ssl_write_finished mbedtls_ssl_write_finished
+#define ssl_write_record mbedtls_ssl_write_record
+#define ssl_write_version mbedtls_ssl_write_version
+#define supported_ciphers mbedtls_cipher_supported
+#define t_sint mbedtls_mpi_sint
+#define t_udbl mbedtls_t_udbl
+#define t_uint mbedtls_mpi_uint
+#define test_ca_crt mbedtls_test_ca_crt
+#define test_ca_crt_ec mbedtls_test_ca_crt_ec
+#define test_ca_crt_rsa mbedtls_test_ca_crt_rsa
+#define test_ca_key mbedtls_test_ca_key
+#define test_ca_key_ec mbedtls_test_ca_key_ec
+#define test_ca_key_rsa mbedtls_test_ca_key_rsa
+#define test_ca_list mbedtls_test_cas_pem
+#define test_ca_pwd mbedtls_test_ca_pwd
+#define test_ca_pwd_ec mbedtls_test_ca_pwd_ec
+#define test_ca_pwd_rsa mbedtls_test_ca_pwd_rsa
+#define test_cli_crt mbedtls_test_cli_crt
+#define test_cli_crt_ec mbedtls_test_cli_crt_ec
+#define test_cli_crt_rsa mbedtls_test_cli_crt_rsa
+#define test_cli_key mbedtls_test_cli_key
+#define test_cli_key_ec mbedtls_test_cli_key_ec
+#define test_cli_key_rsa mbedtls_test_cli_key_rsa
+#define test_srv_crt mbedtls_test_srv_crt
+#define test_srv_crt_ec mbedtls_test_srv_crt_ec
+#define test_srv_crt_rsa mbedtls_test_srv_crt_rsa
+#define test_srv_key mbedtls_test_srv_key
+#define test_srv_key_ec mbedtls_test_srv_key_ec
+#define test_srv_key_rsa mbedtls_test_srv_key_rsa
+#define threading_mutex_t mbedtls_threading_mutex_t
+#define threading_set_alt mbedtls_threading_set_alt
+#define timing_self_test mbedtls_timing_self_test
+#define version_check_feature mbedtls_version_check_feature
+#define version_get_number mbedtls_version_get_number
+#define version_get_string mbedtls_version_get_string
+#define version_get_string_full mbedtls_version_get_string_full
+#define x509_bitstring mbedtls_x509_bitstring
+#define x509_buf mbedtls_x509_buf
+#define x509_crl mbedtls_x509_crl
+#define x509_crl_entry mbedtls_x509_crl_entry
+#define x509_crl_free mbedtls_x509_crl_free
+#define x509_crl_info mbedtls_x509_crl_info
+#define x509_crl_init mbedtls_x509_crl_init
+#define x509_crl_parse mbedtls_x509_crl_parse
+#define x509_crl_parse_der mbedtls_x509_crl_parse_der
+#define x509_crl_parse_file mbedtls_x509_crl_parse_file
+#define x509_crt mbedtls_x509_crt
+#define x509_crt_check_extended_key_usage mbedtls_x509_crt_check_extended_key_usage
+#define x509_crt_check_key_usage mbedtls_x509_crt_check_key_usage
+#define x509_crt_free mbedtls_x509_crt_free
+#define x509_crt_info mbedtls_x509_crt_info
+#define x509_crt_init mbedtls_x509_crt_init
+#define x509_crt_parse mbedtls_x509_crt_parse
+#define x509_crt_parse_der mbedtls_x509_crt_parse_der
+#define x509_crt_parse_file mbedtls_x509_crt_parse_file
+#define x509_crt_parse_path mbedtls_x509_crt_parse_path
+#define x509_crt_revoked mbedtls_x509_crt_is_revoked
+#define x509_crt_verify mbedtls_x509_crt_verify
+#define x509_csr mbedtls_x509_csr
+#define x509_csr_free mbedtls_x509_csr_free
+#define x509_csr_info mbedtls_x509_csr_info
+#define x509_csr_init mbedtls_x509_csr_init
+#define x509_csr_parse mbedtls_x509_csr_parse
+#define x509_csr_parse_der mbedtls_x509_csr_parse_der
+#define x509_csr_parse_file mbedtls_x509_csr_parse_file
+#define x509_dn_gets mbedtls_x509_dn_gets
+#define x509_get_alg mbedtls_x509_get_alg
+#define x509_get_alg_null mbedtls_x509_get_alg_null
+#define x509_get_ext mbedtls_x509_get_ext
+#define x509_get_name mbedtls_x509_get_name
+#define x509_get_rsassa_pss_params mbedtls_x509_get_rsassa_pss_params
+#define x509_get_serial mbedtls_x509_get_serial
+#define x509_get_sig mbedtls_x509_get_sig
+#define x509_get_sig_alg mbedtls_x509_get_sig_alg
+#define x509_get_time mbedtls_x509_get_time
+#define x509_key_size_helper mbedtls_x509_key_size_helper
+#define x509_name mbedtls_x509_name
+#define x509_self_test mbedtls_x509_self_test
+#define x509_sequence mbedtls_x509_sequence
+#define x509_serial_gets mbedtls_x509_serial_gets
+#define x509_set_extension mbedtls_x509_set_extension
+#define x509_sig_alg_gets mbedtls_x509_sig_alg_gets
+#define x509_string_to_names mbedtls_x509_string_to_names
+#define x509_time mbedtls_x509_time
+#define x509_time_expired mbedtls_x509_time_is_past
+#define x509_time_future mbedtls_x509_time_is_future
+#define x509_write_extensions mbedtls_x509_write_extensions
+#define x509_write_names mbedtls_x509_write_names
+#define x509_write_sig mbedtls_x509_write_sig
+#define x509write_cert mbedtls_x509write_cert
+#define x509write_crt_der mbedtls_x509write_crt_der
+#define x509write_crt_free mbedtls_x509write_crt_free
+#define x509write_crt_init mbedtls_x509write_crt_init
+#define x509write_crt_pem mbedtls_x509write_crt_pem
+#define x509write_crt_set_authority_key_identifier mbedtls_x509write_crt_set_authority_key_identifier
+#define x509write_crt_set_basic_constraints mbedtls_x509write_crt_set_basic_constraints
+#define x509write_crt_set_extension mbedtls_x509write_crt_set_extension
+#define x509write_crt_set_issuer_key mbedtls_x509write_crt_set_issuer_key
+#define x509write_crt_set_issuer_name mbedtls_x509write_crt_set_issuer_name
+#define x509write_crt_set_key_usage mbedtls_x509write_crt_set_key_usage
+#define x509write_crt_set_md_alg mbedtls_x509write_crt_set_md_alg
+#define x509write_crt_set_ns_cert_type mbedtls_x509write_crt_set_ns_cert_type
+#define x509write_crt_set_serial mbedtls_x509write_crt_set_serial
+#define x509write_crt_set_subject_key mbedtls_x509write_crt_set_subject_key
+#define x509write_crt_set_subject_key_identifier mbedtls_x509write_crt_set_subject_key_identifier
+#define x509write_crt_set_subject_name mbedtls_x509write_crt_set_subject_name
+#define x509write_crt_set_validity mbedtls_x509write_crt_set_validity
+#define x509write_crt_set_version mbedtls_x509write_crt_set_version
+#define x509write_csr mbedtls_x509write_csr
+#define x509write_csr_der mbedtls_x509write_csr_der
+#define x509write_csr_free mbedtls_x509write_csr_free
+#define x509write_csr_init mbedtls_x509write_csr_init
+#define x509write_csr_pem mbedtls_x509write_csr_pem
+#define x509write_csr_set_extension mbedtls_x509write_csr_set_extension
+#define x509write_csr_set_key mbedtls_x509write_csr_set_key
+#define x509write_csr_set_key_usage mbedtls_x509write_csr_set_key_usage
+#define x509write_csr_set_md_alg mbedtls_x509write_csr_set_md_alg
+#define x509write_csr_set_ns_cert_type mbedtls_x509write_csr_set_ns_cert_type
+#define x509write_csr_set_subject_name mbedtls_x509write_csr_set_subject_name
+#define xtea_context mbedtls_xtea_context
+#define xtea_crypt_cbc mbedtls_xtea_crypt_cbc
+#define xtea_crypt_ecb mbedtls_xtea_crypt_ecb
+#define xtea_free mbedtls_xtea_free
+#define xtea_init mbedtls_xtea_init
+#define xtea_self_test mbedtls_xtea_self_test
+#define xtea_setup mbedtls_xtea_setup
+
+#endif /* compat-1.3.h */
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/config.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/config.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/config.h	(revision 398)
@@ -0,0 +1,154 @@
+/**
+ * \file config-suite-b.h
+ *
+ * \brief Minimal configuration for TLS NSA Suite B Profile (RFC 6460)
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * Minimal configuration for TLS NSA Suite B Profile (RFC 6460)
+ *
+ * Distinguishing features:
+ * - no RSA or classic DH, fully based on ECC
+ * - optimized for low RAM usage
+ *
+ * Possible improvements:
+ * - if 128-bit security is enough, disable secp384r1 and SHA-512
+ * - use embedded certs in DER format and disable PEM_PARSE_C and BASE64_C
+ *
+ * See README.txt for usage instructions.
+ */
+
+#ifndef MBEDTLS_CONFIG_H
+#define MBEDTLS_CONFIG_H
+
+//#define MBEDTLS_PLATFORM_C
+#define unix
+#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+#define MBEDTLS_SHA1_C
+#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+#define MBEDTLS_SSL_RENEGOTIATION
+
+#define MBEDTLS_DEBUG_C
+
+#define MBEDTLS_RSA_C
+#define MBEDTLS_PKCS1_V15
+
+/* System support */
+#define MBEDTLS_HAVE_ASM
+#define MBEDTLS_HAVE_TIME
+
+/* mbed TLS feature support */
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+#define MBEDTLS_SSL_PROTO_TLS1_2
+
+/* mbed TLS modules */
+#define MBEDTLS_AES_C
+#define MBEDTLS_ASN1_PARSE_C
+#define MBEDTLS_ASN1_WRITE_C
+#define MBEDTLS_BIGNUM_C
+#define MBEDTLS_CIPHER_C
+#define MBEDTLS_CTR_DRBG_C
+#define MBEDTLS_ECDH_C
+#define MBEDTLS_ECDSA_C
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_GCM_C
+#define MBEDTLS_MD_C
+#define MBEDTLS_NET_C
+#define MBEDTLS_OID_C
+#define MBEDTLS_PK_C
+#define MBEDTLS_PK_PARSE_C
+#define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA512_C
+#define MBEDTLS_SSL_CLI_C
+#define MBEDTLS_SSL_SRV_C
+#define MBEDTLS_SSL_TLS_C
+#define MBEDTLS_X509_CRT_PARSE_C
+#define MBEDTLS_X509_USE_C
+#define MBEDTLS_DHM_C
+
+/* For test certificates */
+#define MBEDTLS_BASE64_C
+#define MBEDTLS_CERTS_C
+#define MBEDTLS_PEM_PARSE_C
+
+/* Save RAM at the expense of ROM */
+#define MBEDTLS_AES_ROM_TABLES
+
+/* Save RAM by adjusting to our exact needs */
+#define MBEDTLS_ECP_MAX_BITS   384
+#define MBEDTLS_MPI_MAX_SIZE   512
+
+/* Save RAM at the expense of speed, see ecp.h */
+#define MBEDTLS_ECP_WINDOW_SIZE        2
+#define MBEDTLS_ECP_FIXED_POINT_OPTIM  0
+
+/* Significant speed benefit at the expense of some ROM */
+#define MBEDTLS_ECP_NIST_OPTIM
+
+/*
+ * You should adjust this to the exact number of sources you're using: default
+ * is the "mbedtls_platform_entropy_poll" source, but you may want to add other ones.
+ * Minimum is 2 for the entropy test suite.
+ */
+#define MBEDTLS_ENTROPY_MAX_SOURCES 2
+
+/* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
+#define MBEDTLS_SSL_CIPHERSUITES                        \
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,    \
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,    \
+    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,      \
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,        \
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,        \
+    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,      \
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,    \
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,       \
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,       \
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,           \
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,      \
+    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,         \
+    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,         \
+    MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA,             \
+    MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,        \
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,        \
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,        \
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,           \
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,           \
+    MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,          \
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,        \
+    MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+
+/*
+ * Save RAM at the expense of interoperability: do this only if you control
+ * both ends of the connection!  (See coments in "mbedtls/ssl.h".)
+ * The minimum size here depends on the certificate chain used as well as the
+ * typical size of records.
+ */
+#define MBEDTLS_SSL_MAX_CONTENT_LEN             5120
+
+#include "mbedtls/check_config.h"
+
+#endif /* MBEDTLS_CONFIG_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ctr_drbg.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ctr_drbg.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ctr_drbg.h	(revision 398)
@@ -0,0 +1,380 @@
+/**
+ * \file ctr_drbg.h
+ *
+ * \brief    This file contains CTR_DRBG definitions and functions.
+ *
+ * CTR_DRBG is a standardized way of building a PRNG from a block-cipher
+ * in counter mode operation, as defined in <em>NIST SP 800-90A:
+ * Recommendation for Random Number Generation Using Deterministic Random
+ * Bit Generators</em>.
+ *
+ * The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
+ * as the underlying block cipher.
+ *
+ *  \warning Using 128-bit keys for CTR_DRBG limits the security of generated
+ *  keys and operations that use random values generated to 128-bit security.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_CTR_DRBG_H
+#define MBEDTLS_CTR_DRBG_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "aes.h"
+
+#if defined(MBEDTLS_THREADING_C)
+#include "threading.h"
+#endif
+
+#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED        -0x0034  /**< The entropy source failed. */
+#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG              -0x0036  /**< The requested random buffer length is too big. */
+#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG                -0x0038  /**< The input (entropy + additional data) is too large. */
+#define MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR                -0x003A  /**< Read or write error in file. */
+
+#define MBEDTLS_CTR_DRBG_BLOCKSIZE          16 /**< The block size used by the cipher. */
+
+#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
+#define MBEDTLS_CTR_DRBG_KEYSIZE            16 /**< The key size used by the cipher (compile-time choice: 128 bits). */
+#else
+#define MBEDTLS_CTR_DRBG_KEYSIZE            32 /**< The key size used by the cipher (compile-time choice: 256 bits). */
+#endif
+
+#define MBEDTLS_CTR_DRBG_KEYBITS            ( MBEDTLS_CTR_DRBG_KEYSIZE * 8 ) /**< The key size for the DRBG operation, in bits. */
+#define MBEDTLS_CTR_DRBG_SEEDLEN            ( MBEDTLS_CTR_DRBG_KEYSIZE + MBEDTLS_CTR_DRBG_BLOCKSIZE ) /**< The seed length, calculated as (counter + AES key). */
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them using the compiler command
+ * line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
+#define MBEDTLS_CTR_DRBG_ENTROPY_LEN        48
+/**< The amount of entropy used per seed by default:
+ * <ul><li>48 with SHA-512.</li>
+ * <li>32 with SHA-256.</li></ul>
+ */
+#else
+#define MBEDTLS_CTR_DRBG_ENTROPY_LEN        32
+/**< Amount of entropy used per seed by default:
+ * <ul><li>48 with SHA-512.</li>
+ * <li>32 with SHA-256.</li></ul>
+ */
+#endif
+#endif
+
+#if !defined(MBEDTLS_CTR_DRBG_RESEED_INTERVAL)
+#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL    10000
+/**< The interval before reseed is performed by default. */
+#endif
+
+#if !defined(MBEDTLS_CTR_DRBG_MAX_INPUT)
+#define MBEDTLS_CTR_DRBG_MAX_INPUT          256
+/**< The maximum number of additional input Bytes. */
+#endif
+
+#if !defined(MBEDTLS_CTR_DRBG_MAX_REQUEST)
+#define MBEDTLS_CTR_DRBG_MAX_REQUEST        1024
+/**< The maximum number of requested Bytes per call. */
+#endif
+
+#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
+#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT     384
+/**< The maximum size of seed or reseed buffer. */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#define MBEDTLS_CTR_DRBG_PR_OFF             0
+/**< Prediction resistance is disabled. */
+#define MBEDTLS_CTR_DRBG_PR_ON              1
+/**< Prediction resistance is enabled. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          The CTR_DRBG context structure.
+ */
+typedef struct mbedtls_ctr_drbg_context
+{
+    unsigned char counter[16];  /*!< The counter (V). */
+    int reseed_counter;         /*!< The reseed counter. */
+    int prediction_resistance;  /*!< This determines whether prediction
+                                     resistance is enabled, that is
+                                     whether to systematically reseed before
+                                     each random generation. */
+    size_t entropy_len;         /*!< The amount of entropy grabbed on each
+                                     seed or reseed operation. */
+    int reseed_interval;        /*!< The reseed interval. */
+
+    mbedtls_aes_context aes_ctx;        /*!< The AES context. */
+
+    /*
+     * Callbacks (Entropy)
+     */
+    int (*f_entropy)(void *, unsigned char *, size_t);
+                                /*!< The entropy callback function. */
+
+    void *p_entropy;            /*!< The context for the entropy function. */
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+#endif
+}
+mbedtls_ctr_drbg_context;
+
+/**
+ * \brief               This function initializes the CTR_DRBG context,
+ *                      and prepares it for mbedtls_ctr_drbg_seed()
+ *                      or mbedtls_ctr_drbg_free().
+ *
+ * \param ctx           The CTR_DRBG context to initialize.
+ */
+void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
+
+/**
+ * \brief               This function seeds and sets up the CTR_DRBG
+ *                      entropy source for future reseeds.
+ *
+ * \note Personalization data can be provided in addition to the more generic
+ *       entropy source, to make this instantiation as unique as possible.
+ *
+ * \param ctx           The CTR_DRBG context to seed.
+ * \param f_entropy     The entropy callback, taking as arguments the
+ *                      \p p_entropy context, the buffer to fill, and the
+                        length of the buffer.
+ * \param p_entropy     The entropy context.
+ * \param custom        Personalization data, that is device-specific
+                        identifiers. Can be NULL.
+ * \param len           The length of the personalization data.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
+ */
+int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
+                   int (*f_entropy)(void *, unsigned char *, size_t),
+                   void *p_entropy,
+                   const unsigned char *custom,
+                   size_t len );
+
+/**
+ * \brief               This function clears CTR_CRBG context data.
+ *
+ * \param ctx           The CTR_DRBG context to clear.
+ */
+void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx );
+
+/**
+ * \brief               This function turns prediction resistance on or off.
+ *                      The default value is off.
+ *
+ * \note                If enabled, entropy is gathered at the beginning of
+ *                      every call to mbedtls_ctr_drbg_random_with_add().
+ *                      Only use this if your entropy source has sufficient
+ *                      throughput.
+ *
+ * \param ctx           The CTR_DRBG context.
+ * \param resistance    #MBEDTLS_CTR_DRBG_PR_ON or #MBEDTLS_CTR_DRBG_PR_OFF.
+ */
+void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
+                                         int resistance );
+
+/**
+ * \brief               This function sets the amount of entropy grabbed on each
+ *                      seed or reseed. The default value is
+ *                      #MBEDTLS_CTR_DRBG_ENTROPY_LEN.
+ *
+ * \param ctx           The CTR_DRBG context.
+ * \param len           The amount of entropy to grab.
+ */
+void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
+                               size_t len );
+
+/**
+ * \brief               This function sets the reseed interval.
+ *                      The default value is #MBEDTLS_CTR_DRBG_RESEED_INTERVAL.
+ *
+ * \param ctx           The CTR_DRBG context.
+ * \param interval      The reseed interval.
+ */
+void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
+                                   int interval );
+
+/**
+ * \brief               This function reseeds the CTR_DRBG context, that is
+ *                      extracts data from the entropy source.
+ *
+ * \param ctx           The CTR_DRBG context.
+ * \param additional    Additional data to add to the state. Can be NULL.
+ * \param len           The length of the additional data.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on failure.
+ */
+int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
+                     const unsigned char *additional, size_t len );
+
+/**
+ * \brief              This function updates the state of the CTR_DRBG context.
+ *
+ * \param ctx          The CTR_DRBG context.
+ * \param additional   The data to update the state with.
+ * \param add_len      Length of \p additional in bytes. This must be at
+ *                     most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
+ *
+ * \return             \c 0 on success.
+ * \return             #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if
+ *                     \p add_len is more than
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
+ * \return             An error from the underlying AES cipher on failure.
+ */
+int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
+                                 const unsigned char *additional,
+                                 size_t add_len );
+
+/**
+ * \brief   This function updates a CTR_DRBG instance with additional
+ *          data and uses it to generate random data.
+ *
+ * \note    The function automatically reseeds if the reseed counter is exceeded.
+ *
+ * \param p_rng         The CTR_DRBG context. This must be a pointer to a
+ *                      #mbedtls_ctr_drbg_context structure.
+ * \param output        The buffer to fill.
+ * \param output_len    The length of the buffer.
+ * \param additional    Additional data to update. Can be NULL.
+ * \param add_len       The length of the additional data.
+ *
+ * \return    \c 0 on success.
+ * \return    #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ *            #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
+ */
+int mbedtls_ctr_drbg_random_with_add( void *p_rng,
+                              unsigned char *output, size_t output_len,
+                              const unsigned char *additional, size_t add_len );
+
+/**
+ * \brief   This function uses CTR_DRBG to generate random data.
+ *
+ * \note    The function automatically reseeds if the reseed counter is exceeded.
+ *
+ * \param p_rng         The CTR_DRBG context. This must be a pointer to a
+ *                      #mbedtls_ctr_drbg_context structure.
+ * \param output        The buffer to fill.
+ * \param output_len    The length of the buffer.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ *                      #MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG on failure.
+ */
+int mbedtls_ctr_drbg_random( void *p_rng,
+                     unsigned char *output, size_t output_len );
+
+
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief              This function updates the state of the CTR_DRBG context.
+ *
+ * \deprecated         Superseded by mbedtls_ctr_drbg_update_ret()
+ *                     in 2.16.0.
+ *
+ * \note               If \p add_len is greater than
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first
+ *                     #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used.
+ *                     The remaining Bytes are silently discarded.
+ *
+ * \param ctx          The CTR_DRBG context.
+ * \param additional   The data to update the state with.
+ * \param add_len      Length of \p additional data.
+ */
+MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update(
+    mbedtls_ctr_drbg_context *ctx,
+    const unsigned char *additional,
+    size_t add_len );
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief               This function writes a seed file.
+ *
+ * \param ctx           The CTR_DRBG context.
+ * \param path          The name of the file.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED on
+ *                      failure.
+ */
+int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
+
+/**
+ * \brief               This function reads and updates a seed file. The seed
+ *                      is added to this instance.
+ *
+ * \param ctx           The CTR_DRBG context.
+ * \param path          The name of the file.
+ *
+ * \return              \c 0 on success.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR on file error.
+ * \return              #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ *                      #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG on failure.
+ */
+int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path );
+#endif /* MBEDTLS_FS_IO */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief               The CTR_DRBG checkup routine.
+ *
+ * \return              \c 0 on success.
+ * \return              \c 1 on failure.
+ */
+int mbedtls_ctr_drbg_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+/* Internal functions (do not call directly) */
+int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *,
+                               int (*)(void *, unsigned char *, size_t), void *,
+                               const unsigned char *, size_t, size_t );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ctr_drbg.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/debug.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/debug.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/debug.h	(revision 398)
@@ -0,0 +1,265 @@
+/**
+ * \file debug.h
+ *
+ * \brief Functions for controlling and providing debug output from the library.
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_DEBUG_H
+#define MBEDTLS_DEBUG_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "ssl.h"
+
+#if defined(MBEDTLS_ECP_C)
+#include "ecp.h"
+#endif
+
+#if defined(MBEDTLS_DEBUG_C)
+
+#define MBEDTLS_DEBUG_STRIP_PARENS( ... )   __VA_ARGS__
+
+#define MBEDTLS_SSL_DEBUG_MSG( level, args )                    \
+    mbedtls_debug_print_msg( ssl, level, __FILE__, __LINE__,    \
+                             MBEDTLS_DEBUG_STRIP_PARENS args )
+
+#define MBEDTLS_SSL_DEBUG_RET( level, text, ret )                \
+    mbedtls_debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret )
+
+#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len )           \
+    mbedtls_debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len )
+
+#if defined(MBEDTLS_BIGNUM_C)
+#define MBEDTLS_SSL_DEBUG_MPI( level, text, X )                  \
+    mbedtls_debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X )
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+#define MBEDTLS_SSL_DEBUG_ECP( level, text, X )                  \
+    mbedtls_debug_print_ecp( ssl, level, __FILE__, __LINE__, text, X )
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt )                \
+    mbedtls_debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt )
+#endif
+
+#if defined(MBEDTLS_ECDH_C)
+#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr )               \
+    mbedtls_debug_printf_ecdh( ssl, level, __FILE__, __LINE__, ecdh, attr )
+#endif
+
+#else /* MBEDTLS_DEBUG_C */
+
+#define MBEDTLS_SSL_DEBUG_MSG( level, args )            do { } while( 0 )
+#define MBEDTLS_SSL_DEBUG_RET( level, text, ret )       do { } while( 0 )
+#define MBEDTLS_SSL_DEBUG_BUF( level, text, buf, len )  do { } while( 0 )
+#define MBEDTLS_SSL_DEBUG_MPI( level, text, X )         do { } while( 0 )
+#define MBEDTLS_SSL_DEBUG_ECP( level, text, X )         do { } while( 0 )
+#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt )       do { } while( 0 )
+#define MBEDTLS_SSL_DEBUG_ECDH( level, ecdh, attr )     do { } while( 0 )
+
+#endif /* MBEDTLS_DEBUG_C */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief   Set the threshold error level to handle globally all debug output.
+ *          Debug messages that have a level over the threshold value are
+ *          discarded.
+ *          (Default value: 0 = No debug )
+ *
+ * \param threshold     theshold level of messages to filter on. Messages at a
+ *                      higher level will be discarded.
+ *                          - Debug levels
+ *                              - 0 No debug
+ *                              - 1 Error
+ *                              - 2 State change
+ *                              - 3 Informational
+ *                              - 4 Verbose
+ */
+void mbedtls_debug_set_threshold( int threshold );
+
+/**
+ * \brief    Print a message to the debug output. This function is always used
+ *          through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl
+ *          context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the message has occurred in
+ * \param line      line number the message has occurred at
+ * \param format    format specifier, in printf format
+ * \param ...       variables used by the format specifier
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
+void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
+                              const char *file, int line,
+                              const char *format, ... );
+
+/**
+ * \brief   Print the return value of a function to the debug output. This
+ *          function is always used through the MBEDTLS_SSL_DEBUG_RET() macro,
+ *          which supplies the ssl context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param text      the name of the function that returned the error
+ * \param ret       the return code value
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
+void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
+                      const char *file, int line,
+                      const char *text, int ret );
+
+/**
+ * \brief   Output a buffer of size len bytes to the debug output. This function
+ *          is always used through the MBEDTLS_SSL_DEBUG_BUF() macro,
+ *          which supplies the ssl context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param text      a name or label for the buffer being dumped. Normally the
+ *                  variable or buffer name
+ * \param buf       the buffer to be outputted
+ * \param len       length of the buffer
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
+void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
+                      const char *file, int line, const char *text,
+                      const unsigned char *buf, size_t len );
+
+#if defined(MBEDTLS_BIGNUM_C)
+/**
+ * \brief   Print a MPI variable to the debug output. This function is always
+ *          used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the
+ *          ssl context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param text      a name or label for the MPI being output. Normally the
+ *                  variable name
+ * \param X         the MPI variable
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
+void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
+                      const char *file, int line,
+                      const char *text, const mbedtls_mpi *X );
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+/**
+ * \brief   Print an ECP point to the debug output. This function is always
+ *          used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the
+ *          ssl context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param text      a name or label for the ECP point being output. Normally the
+ *                  variable name
+ * \param X         the ECP point
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
+void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
+                      const char *file, int line,
+                      const char *text, const mbedtls_ecp_point *X );
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief   Print a X.509 certificate structure to the debug output. This
+ *          function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro,
+ *          which supplies the ssl context, file and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param text      a name or label for the certificate being output
+ * \param crt       X.509 certificate structure
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
+void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
+                      const char *file, int line,
+                      const char *text, const mbedtls_x509_crt *crt );
+#endif
+
+#if defined(MBEDTLS_ECDH_C)
+typedef enum
+{
+    MBEDTLS_DEBUG_ECDH_Q,
+    MBEDTLS_DEBUG_ECDH_QP,
+    MBEDTLS_DEBUG_ECDH_Z,
+} mbedtls_debug_ecdh_attr;
+
+/**
+ * \brief   Print a field of the ECDH structure in the SSL context to the debug
+ *          output. This function is always used through the
+ *          MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file
+ *          and line number parameters.
+ *
+ * \param ssl       SSL context
+ * \param level     error level of the debug message
+ * \param file      file the error has occurred in
+ * \param line      line number the error has occurred in
+ * \param ecdh      the ECDH context
+ * \param attr      the identifier of the attribute being output
+ *
+ * \attention       This function is intended for INTERNAL usage within the
+ *                  library only.
+ */
+void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level,
+                                const char *file, int line,
+                                const mbedtls_ecdh_context *ecdh,
+                                mbedtls_debug_ecdh_attr attr );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* debug.h */
+
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/des.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/des.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/des.h	(revision 398)
@@ -0,0 +1,356 @@
+/**
+ * \file des.h
+ *
+ * \brief DES block cipher
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers
+ *            instead.
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
+ */
+#ifndef MBEDTLS_DES_H
+#define MBEDTLS_DES_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDTLS_DES_ENCRYPT     1
+#define MBEDTLS_DES_DECRYPT     0
+
+#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH              -0x0032  /**< The data input has an invalid length. */
+
+/* MBEDTLS_ERR_DES_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_DES_HW_ACCEL_FAILED                   -0x0033  /**< DES hardware accelerator failed. */
+
+#define MBEDTLS_DES_KEY_SIZE    8
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_DES_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          DES context structure
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+typedef struct mbedtls_des_context
+{
+    uint32_t sk[32];            /*!<  DES subkeys       */
+}
+mbedtls_des_context;
+
+/**
+ * \brief          Triple-DES context structure
+ */
+typedef struct mbedtls_des3_context
+{
+    uint32_t sk[96];            /*!<  3DES subkeys      */
+}
+mbedtls_des3_context;
+
+#else  /* MBEDTLS_DES_ALT */
+#include "des_alt.h"
+#endif /* MBEDTLS_DES_ALT */
+
+/**
+ * \brief          Initialize DES context
+ *
+ * \param ctx      DES context to be initialized
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+void mbedtls_des_init( mbedtls_des_context *ctx );
+
+/**
+ * \brief          Clear DES context
+ *
+ * \param ctx      DES context to be cleared
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+void mbedtls_des_free( mbedtls_des_context *ctx );
+
+/**
+ * \brief          Initialize Triple-DES context
+ *
+ * \param ctx      DES3 context to be initialized
+ */
+void mbedtls_des3_init( mbedtls_des3_context *ctx );
+
+/**
+ * \brief          Clear Triple-DES context
+ *
+ * \param ctx      DES3 context to be cleared
+ */
+void mbedtls_des3_free( mbedtls_des3_context *ctx );
+
+/**
+ * \brief          Set key parity on the given key to odd.
+ *
+ *                 DES keys are 56 bits long, but each byte is padded with
+ *                 a parity bit to allow verification.
+ *
+ * \param key      8-byte secret key
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
+
+/**
+ * \brief          Check that key parity on the given key is odd.
+ *
+ *                 DES keys are 56 bits long, but each byte is padded with
+ *                 a parity bit to allow verification.
+ *
+ * \param key      8-byte secret key
+ *
+ * \return         0 is parity was ok, 1 if parity was not correct.
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
+
+/**
+ * \brief          Check that key is not a weak or semi-weak DES key
+ *
+ * \param key      8-byte secret key
+ *
+ * \return         0 if no weak key was found, 1 if a weak key was identified.
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
+
+/**
+ * \brief          DES key schedule (56-bit, encryption)
+ *
+ * \param ctx      DES context to be initialized
+ * \param key      8-byte secret key
+ *
+ * \return         0
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
+
+/**
+ * \brief          DES key schedule (56-bit, decryption)
+ *
+ * \param ctx      DES context to be initialized
+ * \param key      8-byte secret key
+ *
+ * \return         0
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
+
+/**
+ * \brief          Triple-DES key schedule (112-bit, encryption)
+ *
+ * \param ctx      3DES context to be initialized
+ * \param key      16-byte secret key
+ *
+ * \return         0
+ */
+int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
+                      const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
+
+/**
+ * \brief          Triple-DES key schedule (112-bit, decryption)
+ *
+ * \param ctx      3DES context to be initialized
+ * \param key      16-byte secret key
+ *
+ * \return         0
+ */
+int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
+                      const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
+
+/**
+ * \brief          Triple-DES key schedule (168-bit, encryption)
+ *
+ * \param ctx      3DES context to be initialized
+ * \param key      24-byte secret key
+ *
+ * \return         0
+ */
+int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
+                      const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
+
+/**
+ * \brief          Triple-DES key schedule (168-bit, decryption)
+ *
+ * \param ctx      3DES context to be initialized
+ * \param key      24-byte secret key
+ *
+ * \return         0
+ */
+int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
+                      const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
+
+/**
+ * \brief          DES-ECB block encryption/decryption
+ *
+ * \param ctx      DES context
+ * \param input    64-bit input block
+ * \param output   64-bit output block
+ *
+ * \return         0 if successful
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
+                    const unsigned char input[8],
+                    unsigned char output[8] );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/**
+ * \brief          DES-CBC buffer encryption/decryption
+ *
+ * \note           Upon exit, the content of the IV is updated so that you can
+ *                 call the function same function again on the following
+ *                 block(s) of data and get the same result as if it was
+ *                 encrypted in one call. This allows a "streaming" usage.
+ *                 If on the other hand you need to retain the contents of the
+ *                 IV, you should either save it manually or use the cipher
+ *                 module instead.
+ *
+ * \param ctx      DES context
+ * \param mode     MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
+ * \param length   length of the input data
+ * \param iv       initialization vector (updated after use)
+ * \param input    buffer holding the input data
+ * \param output   buffer holding the output data
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[8],
+                    const unsigned char *input,
+                    unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+/**
+ * \brief          3DES-ECB block encryption/decryption
+ *
+ * \param ctx      3DES context
+ * \param input    64-bit input block
+ * \param output   64-bit output block
+ *
+ * \return         0 if successful
+ */
+int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
+                     const unsigned char input[8],
+                     unsigned char output[8] );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/**
+ * \brief          3DES-CBC buffer encryption/decryption
+ *
+ * \note           Upon exit, the content of the IV is updated so that you can
+ *                 call the function same function again on the following
+ *                 block(s) of data and get the same result as if it was
+ *                 encrypted in one call. This allows a "streaming" usage.
+ *                 If on the other hand you need to retain the contents of the
+ *                 IV, you should either save it manually or use the cipher
+ *                 module instead.
+ *
+ * \param ctx      3DES context
+ * \param mode     MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT
+ * \param length   length of the input data
+ * \param iv       initialization vector (updated after use)
+ * \param input    buffer holding the input data
+ * \param output   buffer holding the output data
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
+ */
+int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
+                     int mode,
+                     size_t length,
+                     unsigned char iv[8],
+                     const unsigned char *input,
+                     unsigned char *output );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+/**
+ * \brief          Internal function for key expansion.
+ *                 (Only exposed to allow overriding it,
+ *                 see MBEDTLS_DES_SETKEY_ALT)
+ *
+ * \param SK       Round keys
+ * \param key      Base key
+ *
+ * \warning        DES is considered a weak cipher and its use constitutes a
+ *                 security risk. We recommend considering stronger ciphers
+ *                 instead.
+ */
+void mbedtls_des_setkey( uint32_t SK[32],
+                         const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int mbedtls_des_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* des.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/dhm.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/dhm.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/dhm.h	(revision 398)
@@ -0,0 +1,1096 @@
+/**
+ * \file dhm.h
+ *
+ * \brief   This file contains Diffie-Hellman-Merkle (DHM) key exchange
+ *          definitions and functions.
+ *
+ * Diffie-Hellman-Merkle (DHM) key exchange is defined in
+ * <em>RFC-2631: Diffie-Hellman Key Agreement Method</em> and
+ * <em>Public-Key Cryptography Standards (PKCS) #3: Diffie
+ * Hellman Key Agreement Standard</em>.
+ *
+ * <em>RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups for
+ * Internet Key Exchange (IKE)</em> defines a number of standardized
+ * Diffie-Hellman groups for IKE.
+ *
+ * <em>RFC-5114: Additional Diffie-Hellman Groups for Use with IETF
+ * Standards</em> defines a number of standardized Diffie-Hellman
+ * groups that can be used.
+ *
+ * \warning  The security of the DHM key exchange relies on the proper choice
+ *           of prime modulus - optimally, it should be a safe prime. The usage
+ *           of non-safe primes both decreases the difficulty of the underlying
+ *           discrete logarithm problem and can lead to small subgroup attacks
+ *           leaking private exponent bits when invalid public keys are used
+ *           and not detected. This is especially relevant if the same DHM
+ *           parameters are reused for multiple key exchanges as in static DHM,
+ *           while the criticality of small-subgroup attacks is lower for
+ *           ephemeral DHM.
+ *
+ * \warning  For performance reasons, the code does neither perform primality
+ *           nor safe primality tests, nor the expensive checks for invalid
+ *           subgroups. Moreover, even if these were performed, non-standardized
+ *           primes cannot be trusted because of the possibility of backdoors
+ *           that can't be effectively checked for.
+ *
+ * \warning  Diffie-Hellman-Merkle is therefore a security risk when not using
+ *           standardized primes generated using a trustworthy ("nothing up
+ *           my sleeve") method, such as the RFC 3526 / 7919 primes. In the TLS
+ *           protocol, DH parameters need to be negotiated, so using the default
+ *           primes systematically is not always an option. If possible, use
+ *           Elliptic Curve Diffie-Hellman (ECDH), which has better performance,
+ *           and for which the TLS protocol mandates the use of standard
+ *           parameters.
+ *
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_DHM_H
+#define MBEDTLS_DHM_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+#include "bignum.h"
+
+/*
+ * DHM Error codes
+ */
+#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA                    -0x3080  /**< Bad input parameters. */
+#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED                -0x3100  /**< Reading of the DHM parameters failed. */
+#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED                -0x3180  /**< Making of the DHM parameters failed. */
+#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED                -0x3200  /**< Reading of the public values failed. */
+#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED                -0x3280  /**< Making of the public value failed. */
+#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED                -0x3300  /**< Calculation of the DHM secret failed. */
+#define MBEDTLS_ERR_DHM_INVALID_FORMAT                    -0x3380  /**< The ASN.1 data is not formatted correctly. */
+#define MBEDTLS_ERR_DHM_ALLOC_FAILED                      -0x3400  /**< Allocation of memory failed. */
+#define MBEDTLS_ERR_DHM_FILE_IO_ERROR                     -0x3480  /**< Read or write of file failed. */
+
+/* MBEDTLS_ERR_DHM_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED                   -0x3500  /**< DHM hardware accelerator failed. */
+
+#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED                  -0x3580  /**< Setting the modulus and generator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_DHM_ALT)
+
+/**
+ * \brief          The DHM context structure.
+ */
+typedef struct mbedtls_dhm_context
+{
+    size_t len;         /*!<  The size of \p P in Bytes. */
+    mbedtls_mpi P;      /*!<  The prime modulus. */
+    mbedtls_mpi G;      /*!<  The generator. */
+    mbedtls_mpi X;      /*!<  Our secret value. */
+    mbedtls_mpi GX;     /*!<  Our public key = \c G^X mod \c P. */
+    mbedtls_mpi GY;     /*!<  The public key of the peer = \c G^Y mod \c P. */
+    mbedtls_mpi K;      /*!<  The shared secret = \c G^(XY) mod \c P. */
+    mbedtls_mpi RP;     /*!<  The cached value = \c R^2 mod \c P. */
+    mbedtls_mpi Vi;     /*!<  The blinding value. */
+    mbedtls_mpi Vf;     /*!<  The unblinding value. */
+    mbedtls_mpi pX;     /*!<  The previous \c X. */
+}
+mbedtls_dhm_context;
+
+#else /* MBEDTLS_DHM_ALT */
+#include "dhm_alt.h"
+#endif /* MBEDTLS_DHM_ALT */
+
+/**
+ * \brief          This function initializes the DHM context.
+ *
+ * \param ctx      The DHM context to initialize.
+ */
+void mbedtls_dhm_init( mbedtls_dhm_context *ctx );
+
+/**
+ * \brief          This function parses the DHM parameters in a
+ *                 TLS ServerKeyExchange handshake message
+ *                 (DHM modulus, generator, and public key).
+ *
+ * \note           In a TLS handshake, this is the how the client
+ *                 sets up its DHM context from the server's public
+ *                 DHM key material.
+ *
+ * \param ctx      The DHM context to use. This must be initialized.
+ * \param p        On input, *p must be the start of the input buffer.
+ *                 On output, *p is updated to point to the end of the data
+ *                 that has been read. On success, this is the first byte
+ *                 past the end of the ServerKeyExchange parameters.
+ *                 On error, this is the point at which an error has been
+ *                 detected, which is usually not useful except to debug
+ *                 failures.
+ * \param end      The end of the input buffer.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
+ */
+int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
+                             unsigned char **p,
+                             const unsigned char *end );
+
+/**
+ * \brief          This function generates a DHM key pair and exports its
+ *                 public part together with the DHM parameters in the format
+ *                 used in a TLS ServerKeyExchange handshake message.
+ *
+ * \note           This function assumes that the DHM parameters \c ctx->P
+ *                 and \c ctx->G have already been properly set. For that, use
+ *                 mbedtls_dhm_set_group() below in conjunction with
+ *                 mbedtls_mpi_read_binary() and mbedtls_mpi_read_string().
+ *
+ * \note           In a TLS handshake, this is the how the server generates
+ *                 and exports its DHM key material.
+ *
+ * \param ctx      The DHM context to use. This must be initialized
+ *                 and have the DHM parameters set. It may or may not
+ *                 already have imported the peer's public key.
+ * \param x_size   The private key size in Bytes.
+ * \param olen     The address at which to store the number of Bytes
+ *                 written on success. This must not be \c NULL.
+ * \param output   The destination buffer. This must be a writable buffer of
+ *                 sufficient size to hold the reduced binary presentation of
+ *                 the modulus, the generator and the public key, each wrapped
+ *                 with a 2-byte length field. It is the responsibility of the
+ *                 caller to ensure that enough space is available. Refer to
+ *                 mbedtls_mpi_size() to computing the byte-size of an MPI.
+ * \param f_rng    The RNG function. Must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng doesn't need a context parameter.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
+ */
+int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
+                     unsigned char *output, size_t *olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng );
+
+/**
+ * \brief          This function sets the prime modulus and generator.
+ *
+ * \note           This function can be used to set \c ctx->P, \c ctx->G
+ *                 in preparation for mbedtls_dhm_make_params().
+ *
+ * \param ctx      The DHM context to configure. This must be initialized.
+ * \param P        The MPI holding the DHM prime modulus. This must be
+ *                 an initialized MPI.
+ * \param G        The MPI holding the DHM generator. This must be an
+ *                 initialized MPI.
+ *
+ * \return         \c 0 if successful.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
+ */
+int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
+                           const mbedtls_mpi *P,
+                           const mbedtls_mpi *G );
+
+/**
+ * \brief          This function imports the raw public value of the peer.
+ *
+ * \note           In a TLS handshake, this is the how the server imports
+ *                 the Client's public DHM key.
+ *
+ * \param ctx      The DHM context to use. This must be initialized and have
+ *                 its DHM parameters set, e.g. via mbedtls_dhm_set_group().
+ *                 It may or may not already have generated its own private key.
+ * \param input    The input buffer containing the \c G^Y value of the peer.
+ *                 This must be a readable buffer of size \p ilen Bytes.
+ * \param ilen     The size of the input buffer \p input in Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
+ */
+int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
+                     const unsigned char *input, size_t ilen );
+
+/**
+ * \brief          This function creates a DHM key pair and exports
+ *                 the raw public key in big-endian format.
+ *
+ * \note           The destination buffer is always fully written
+ *                 so as to contain a big-endian representation of G^X mod P.
+ *                 If it is larger than \c ctx->len, it is padded accordingly
+ *                 with zero-bytes at the beginning.
+ *
+ * \param ctx      The DHM context to use. This must be initialized and
+ *                 have the DHM parameters set. It may or may not already
+ *                 have imported the peer's public key.
+ * \param x_size   The private key size in Bytes.
+ * \param output   The destination buffer. This must be a writable buffer of
+ *                 size \p olen Bytes.
+ * \param olen     The length of the destination buffer. This must be at least
+ *                 equal to `ctx->len` (the size of \c P).
+ * \param f_rng    The RNG function. This must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be \c NULL
+ *                 if \p f_rng doesn't need a context argument.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX error code on failure.
+ */
+int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
+                     unsigned char *output, size_t olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng );
+
+/**
+ * \brief          This function derives and exports the shared secret
+ *                 \c (G^Y)^X mod \c P.
+ *
+ * \note           If \p f_rng is not \c NULL, it is used to blind the input as
+ *                 a countermeasure against timing attacks. Blinding is used
+ *                 only if our private key \c X is re-used, and not used
+ *                 otherwise. We recommend always passing a non-NULL
+ *                 \p f_rng argument.
+ *
+ * \param ctx           The DHM context to use. This must be initialized
+ *                      and have its own private key generated and the peer's
+ *                      public key imported.
+ * \param output        The buffer to write the generated shared key to. This
+ *                      must be a writable buffer of size \p output_size Bytes.
+ * \param output_size   The size of the destination buffer. This must be at
+ *                      least the size of \c ctx->len (the size of \c P).
+ * \param olen          On exit, holds the actual number of Bytes written.
+ * \param f_rng         The RNG function, for blinding purposes. This may
+ *                      b \c NULL if blinding isn't needed.
+ * \param p_rng         The RNG context. This may be \c NULL if \p f_rng
+ *                      doesn't need a context argument.
+ *
+ * \return              \c 0 on success.
+ * \return              An \c MBEDTLS_ERR_DHM_XXX error code on failure.
+ */
+int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
+                     unsigned char *output, size_t output_size, size_t *olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng );
+
+/**
+ * \brief          This function frees and clears the components
+ *                 of a DHM context.
+ *
+ * \param ctx      The DHM context to free and clear. This may be \c NULL,
+ *                 in which case this function is a no-op. If it is not \c NULL,
+ *                 it must point to an initialized DHM context.
+ */
+void mbedtls_dhm_free( mbedtls_dhm_context *ctx );
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+/** \ingroup x509_module */
+/**
+ * \brief             This function parses DHM parameters in PEM or DER format.
+ *
+ * \param dhm         The DHM context to import the DHM parameters into.
+ *                    This must be initialized.
+ * \param dhmin       The input buffer. This must be a readable buffer of
+ *                    length \p dhminlen Bytes.
+ * \param dhminlen    The size of the input buffer \p dhmin, including the
+ *                    terminating \c NULL Byte for PEM data.
+ *
+ * \return            \c 0 on success.
+ * \return            An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX error
+ *                    code on failure.
+ */
+int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
+                           size_t dhminlen );
+
+#if defined(MBEDTLS_FS_IO)
+/** \ingroup x509_module */
+/**
+ * \brief          This function loads and parses DHM parameters from a file.
+ *
+ * \param dhm      The DHM context to load the parameters to.
+ *                 This must be initialized.
+ * \param path     The filename to read the DHM parameters from.
+ *                 This must not be \c NULL.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_DHM_XXX or \c MBEDTLS_ERR_PEM_XXX
+ *                 error code on failure.
+ */
+int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path );
+#endif /* MBEDTLS_FS_IO */
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          The DMH checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_dhm_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * RFC 3526, RFC 5114 and RFC 7919 standardize a number of
+ * Diffie-Hellman groups, some of which are included here
+ * for use within the SSL/TLS module and the user's convenience
+ * when configuring the Diffie-Hellman parameters by hand
+ * through \c mbedtls_ssl_conf_dh_param.
+ *
+ * The following lists the source of the above groups in the standards:
+ * - RFC 5114 section 2.2:  2048-bit MODP Group with 224-bit Prime Order Subgroup
+ * - RFC 3526 section 3:    2048-bit MODP Group
+ * - RFC 3526 section 4:    3072-bit MODP Group
+ * - RFC 3526 section 5:    4096-bit MODP Group
+ * - RFC 7919 section A.1:  ffdhe2048
+ * - RFC 7919 section A.2:  ffdhe3072
+ * - RFC 7919 section A.3:  ffdhe4096
+ * - RFC 7919 section A.4:  ffdhe6144
+ * - RFC 7919 section A.5:  ffdhe8192
+ *
+ * The constants with suffix "_p" denote the chosen prime moduli, while
+ * the constants with suffix "_g" denote the chosen generator
+ * of the associated prime field.
+ *
+ * The constants further suffixed with "_bin" are provided in binary format,
+ * while all other constants represent null-terminated strings holding the
+ * hexadecimal presentation of the respective numbers.
+ *
+ * The primes from RFC 3526 and RFC 7919 have been generating by the following
+ * trust-worthy procedure:
+ * - Fix N in { 2048, 3072, 4096, 6144, 8192 } and consider the N-bit number
+ *   the first and last 64 bits are all 1, and the remaining N - 128 bits of
+ *   which are 0x7ff...ff.
+ * - Add the smallest multiple of the first N - 129 bits of the binary expansion
+ *   of pi (for RFC 5236) or e (for RFC 7919) to this intermediate bit-string
+ *   such that the resulting integer is a safe-prime.
+ * - The result is the respective RFC 3526 / 7919 prime, and the corresponding
+ *   generator is always chosen to be 2 (which is a square for these prime,
+ *   hence the corresponding subgroup has order (p-1)/2 and avoids leaking a
+ *   bit in the private exponent).
+ *
+ */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+
+/**
+ * \warning The origin of the primes in RFC 5114 is not documented and
+ *          their use therefore constitutes a security risk!
+ *
+ * \deprecated The hex-encoded primes from RFC 5114 are deprecated and are
+ *             likely to be removed in a future version of the library without
+ *             replacement.
+ */
+
+/**
+ * The hexadecimal presentation of the prime underlying the
+ * 2048-bit MODP Group with 224-bit Prime Order Subgroup, as defined
+ * in <em>RFC-5114: Additional Diffie-Hellman Groups for Use with
+ * IETF Standards</em>.
+ */
+#define MBEDTLS_DHM_RFC5114_MODP_2048_P                         \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT(                         \
+        "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1"      \
+        "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15"      \
+        "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212"      \
+        "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207"      \
+        "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708"      \
+        "B3BF8A317091883681286130BC8985DB1602E714415D9330"      \
+        "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D"      \
+        "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8"      \
+        "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763"      \
+        "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71"      \
+        "CF9DE5384E71B81C0AC4DFFE0C10E64F" )
+
+/**
+ * The hexadecimal presentation of the chosen generator of the 2048-bit MODP
+ * Group with 224-bit Prime Order Subgroup, as defined in <em>RFC-5114:
+ * Additional Diffie-Hellman Groups for Use with IETF Standards</em>.
+ */
+#define MBEDTLS_DHM_RFC5114_MODP_2048_G                         \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT(                         \
+        "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"      \
+        "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"      \
+        "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"      \
+        "C17669101999024AF4D027275AC1348BB8A762D0521BC98A"      \
+        "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"      \
+        "F180EB34118E98D119529A45D6F834566E3025E316A330EF"      \
+        "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"      \
+        "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"      \
+        "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"      \
+        "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"      \
+        "81BC087F2A7065B384B890D3191F2BFA" )
+
+/**
+ * The hexadecimal presentation of the prime underlying the 2048-bit MODP
+ * Group, as defined in <em>RFC-3526: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ *
+ * \deprecated The hex-encoded primes from RFC 3625 are deprecated and
+ *             superseded by the corresponding macros providing them as
+ *             binary constants. Their hex-encoded constants are likely
+ *             to be removed in a future version of the library.
+ *
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_2048_P                         \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT(                         \
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"      \
+        "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"      \
+        "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"      \
+        "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"      \
+        "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"      \
+        "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"      \
+        "83655D23DCA3AD961C62F356208552BB9ED529077096966D"      \
+        "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"      \
+        "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"      \
+        "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"      \
+        "15728E5A8AACAA68FFFFFFFFFFFFFFFF" )
+
+/**
+ * The hexadecimal presentation of the chosen generator of the 2048-bit MODP
+ * Group, as defined in <em>RFC-3526: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_2048_G                         \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" )
+
+/**
+ * The hexadecimal presentation of the prime underlying the 3072-bit MODP
+ * Group, as defined in <em>RFC-3072: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_3072_P                         \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT(                         \
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"      \
+        "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"      \
+        "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"      \
+        "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"      \
+        "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"      \
+        "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"      \
+        "83655D23DCA3AD961C62F356208552BB9ED529077096966D"      \
+        "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"      \
+        "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"      \
+        "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"      \
+        "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"      \
+        "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"      \
+        "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"      \
+        "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"      \
+        "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"      \
+        "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" )
+
+/**
+ * The hexadecimal presentation of the chosen generator of the 3072-bit MODP
+ * Group, as defined in <em>RFC-3526: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_3072_G                      \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" )
+
+/**
+ * The hexadecimal presentation of the prime underlying the 4096-bit MODP
+ * Group, as defined in <em>RFC-3526: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_4096_P                      \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT(                      \
+        "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"   \
+        "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"   \
+        "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"   \
+        "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"   \
+        "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"   \
+        "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"   \
+        "83655D23DCA3AD961C62F356208552BB9ED529077096966D"   \
+        "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"   \
+        "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"   \
+        "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"   \
+        "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"   \
+        "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"   \
+        "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"   \
+        "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"   \
+        "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"   \
+        "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"   \
+        "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"   \
+        "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"   \
+        "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"   \
+        "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"   \
+        "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"   \
+        "FFFFFFFFFFFFFFFF" )
+
+/**
+ * The hexadecimal presentation of the chosen generator of the 4096-bit MODP
+ * Group, as defined in <em>RFC-3526: More Modular Exponential (MODP)
+ * Diffie-Hellman groups for Internet Key Exchange (IKE)</em>.
+ */
+#define MBEDTLS_DHM_RFC3526_MODP_4096_G                      \
+    MBEDTLS_DEPRECATED_STRING_CONSTANT( "02" )
+
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * Trustworthy DHM parameters in binary form
+ */
+
+#define MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN {        \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+     0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \
+     0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \
+     0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \
+     0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \
+     0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \
+     0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \
+     0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \
+     0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \
+     0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \
+     0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \
+     0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \
+     0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \
+     0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \
+     0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \
+     0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \
+     0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \
+     0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \
+     0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \
+     0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \
+     0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \
+     0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \
+     0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \
+     0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \
+     0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \
+     0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \
+     0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \
+     0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \
+     0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \
+     0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \
+     0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, \
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC3526_MODP_3072_P_BIN {       \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, \
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, \
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, \
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, \
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, \
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, \
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, \
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, \
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, \
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, \
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, \
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, \
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, \
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, \
+    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, \
+    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, \
+    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, \
+    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, \
+    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, \
+    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, \
+    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, \
+    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, \
+    0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, \
+    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, \
+    0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, \
+    0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, \
+    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, \
+    0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, \
+    0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, \
+    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, \
+    0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, \
+    0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, \
+    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, \
+    0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, \
+    0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, \
+    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, \
+    0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, \
+    0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, \
+    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, \
+    0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, \
+    0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, \
+    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, \
+    0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, \
+    0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, \
+    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, \
+    0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define MBEDTLS_DHM_RFC3526_MODP_3072_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC3526_MODP_4096_P_BIN  {       \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  \
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,  \
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,  \
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,  \
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,  \
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,  \
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,  \
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,  \
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,  \
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,  \
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,  \
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,  \
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,  \
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,  \
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,  \
+    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,  \
+    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,  \
+    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,  \
+    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,  \
+    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,  \
+    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,  \
+    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,  \
+    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,  \
+    0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,  \
+    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,  \
+    0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,  \
+    0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,  \
+    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,  \
+    0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,  \
+    0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,  \
+    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,  \
+    0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,  \
+    0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,  \
+    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,  \
+    0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,  \
+    0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,  \
+    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,  \
+    0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,  \
+    0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,  \
+    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,  \
+    0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,  \
+    0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,  \
+    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,  \
+    0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,  \
+    0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,  \
+    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,  \
+    0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,  \
+    0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,  \
+    0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,  \
+    0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,  \
+    0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,  \
+    0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,  \
+    0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,  \
+    0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,  \
+    0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,  \
+    0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,  \
+    0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,  \
+    0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,  \
+    0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,  \
+    0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,  \
+    0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,  \
+    0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,  \
+    0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,  \
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
+
+#define MBEDTLS_DHM_RFC3526_MODP_4096_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN {        \
+     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, }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN { \
+     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 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN {        \
+     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 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN {        \
+     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 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN { 0x02 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN {        \
+     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 }
+
+#define MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN { 0x02 }
+
+#endif /* dhm.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecdh.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecdh.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecdh.h	(revision 398)
@@ -0,0 +1,440 @@
+/**
+ * \file ecdh.h
+ *
+ * \brief This file contains ECDH definitions and functions.
+ *
+ * The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous
+ * key agreement protocol allowing two parties to establish a shared
+ * secret over an insecure channel. Each party must have an
+ * elliptic-curve public–private key pair.
+ *
+ * For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation for
+ * Pair-Wise Key Establishment Schemes Using Discrete Logarithm
+ * Cryptography</em>.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_ECDH_H
+#define MBEDTLS_ECDH_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "ecp.h"
+
+/*
+ * Use a backward compatible ECDH context.
+ *
+ * This flag is always enabled for now and future versions might add a
+ * configuration option that conditionally undefines this flag.
+ * The configuration option in question may have a different name.
+ *
+ * Features undefining this flag, must have a warning in their description in
+ * config.h stating that the feature breaks backward compatibility.
+ */
+#define MBEDTLS_ECDH_LEGACY_CONTEXT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Defines the source of the imported EC key.
+ */
+typedef enum
+{
+    MBEDTLS_ECDH_OURS,   /**< Our key. */
+    MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */
+} mbedtls_ecdh_side;
+
+#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+/**
+ * Defines the ECDH implementation used.
+ *
+ * Later versions of the library may add new variants, therefore users should
+ * not make any assumptions about them.
+ */
+typedef enum
+{
+    MBEDTLS_ECDH_VARIANT_NONE = 0,   /*!< Implementation not defined. */
+    MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */
+} mbedtls_ecdh_variant;
+
+/**
+ * The context used by the default ECDH implementation.
+ *
+ * Later versions might change the structure of this context, therefore users
+ * should not make any assumptions about the structure of
+ * mbedtls_ecdh_context_mbed.
+ */
+typedef struct mbedtls_ecdh_context_mbed
+{
+    mbedtls_ecp_group grp;   /*!< The elliptic curve used. */
+    mbedtls_mpi d;           /*!< The private key. */
+    mbedtls_ecp_point Q;     /*!< The public key. */
+    mbedtls_ecp_point Qp;    /*!< The value of the public key of the peer. */
+    mbedtls_mpi z;           /*!< The shared secret. */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
+#endif
+} mbedtls_ecdh_context_mbed;
+#endif
+
+/**
+ *
+ * \warning         Performing multiple operations concurrently on the same
+ *                  ECDSA context is not supported; objects of this type
+ *                  should not be shared between multiple threads.
+ * \brief           The ECDH context structure.
+ */
+typedef struct mbedtls_ecdh_context
+{
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    mbedtls_ecp_group grp;   /*!< The elliptic curve used. */
+    mbedtls_mpi d;           /*!< The private key. */
+    mbedtls_ecp_point Q;     /*!< The public key. */
+    mbedtls_ecp_point Qp;    /*!< The value of the public key of the peer. */
+    mbedtls_mpi z;           /*!< The shared secret. */
+    int point_format;        /*!< The format of point export in TLS messages. */
+    mbedtls_ecp_point Vi;    /*!< The blinding value. */
+    mbedtls_ecp_point Vf;    /*!< The unblinding value. */
+    mbedtls_mpi _d;          /*!< The previous \p d. */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    int restart_enabled;        /*!< The flag for restartable mode. */
+    mbedtls_ecp_restart_ctx rs; /*!< The restart context for EC computations. */
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+#else
+    uint8_t point_format;       /*!< The format of point export in TLS messages
+                                  as defined in RFC 4492. */
+    mbedtls_ecp_group_id grp_id;/*!< The elliptic curve used. */
+    mbedtls_ecdh_variant var;   /*!< The ECDH implementation/structure used. */
+    union
+    {
+        mbedtls_ecdh_context_mbed   mbed_ecdh;
+    } ctx;                      /*!< Implementation-specific context. The
+                                  context in use is specified by the \c var
+                                  field. */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    uint8_t restart_enabled;    /*!< The flag for restartable mode. Functions of
+                                  an alternative implementation not supporting
+                                  restartable mode must return
+                                  MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error
+                                  if this flag is set. */
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
+}
+mbedtls_ecdh_context;
+
+/**
+ * \brief           This function generates an ECDH keypair on an elliptic
+ *                  curve.
+ *
+ *                  This function performs the first of two core computations
+ *                  implemented during the ECDH key exchange. The second core
+ *                  computation is performed by mbedtls_ecdh_compute_shared().
+ *
+ * \see             ecp.h
+ *
+ * \param grp       The ECP group to use. This must be initialized and have
+ *                  domain parameters loaded, for example through
+ *                  mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
+ * \param d         The destination MPI (private key).
+ *                  This must be initialized.
+ * \param Q         The destination point (public key).
+ *                  This must be initialized.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL in case \p f_rng doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX or
+ *                  \c MBEDTLS_MPI_XXX error code on failure.
+ */
+int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng );
+
+/**
+ * \brief           This function computes the shared secret.
+ *
+ *                  This function performs the second of two core computations
+ *                  implemented during the ECDH key exchange. The first core
+ *                  computation is performed by mbedtls_ecdh_gen_public().
+ *
+ * \see             ecp.h
+ *
+ * \note            If \p f_rng is not NULL, it is used to implement
+ *                  countermeasures against side-channel attacks.
+ *                  For more information, see mbedtls_ecp_mul().
+ *
+ * \param grp       The ECP group to use. This must be initialized and have
+ *                  domain parameters loaded, for example through
+ *                  mbedtls_ecp_load() or mbedtls_ecp_tls_read_group().
+ * \param z         The destination MPI (shared secret).
+ *                  This must be initialized.
+ * \param Q         The public key from another party.
+ *                  This must be initialized.
+ * \param d         Our secret exponent (private key).
+ *                  This must be initialized.
+ * \param f_rng     The RNG function. This may be \c NULL if randomization
+ *                  of intermediate results during the ECP computations is
+ *                  not needed (discouraged). See the documentation of
+ *                  mbedtls_ecp_mul() for more.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng is \c NULL or doesn't need a
+ *                  context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX or
+ *                  \c MBEDTLS_MPI_XXX error code on failure.
+ */
+int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
+                         const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng );
+
+/**
+ * \brief           This function initializes an ECDH context.
+ *
+ * \param ctx       The ECDH context to initialize. This must not be \c NULL.
+ */
+void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx );
+
+/**
+ * \brief           This function sets up the ECDH context with the information
+ *                  given.
+ *
+ *                  This function should be called after mbedtls_ecdh_init() but
+ *                  before mbedtls_ecdh_make_params(). There is no need to call
+ *                  this function before mbedtls_ecdh_read_params().
+ *
+ *                  This is the first function used by a TLS server for ECDHE
+ *                  ciphersuites.
+ *
+ * \param ctx       The ECDH context to set up. This must be initialized.
+ * \param grp_id    The group id of the group to set up the context for.
+ *
+ * \return          \c 0 on success.
+ */
+int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx,
+                        mbedtls_ecp_group_id grp_id );
+
+/**
+ * \brief           This function frees a context.
+ *
+ * \param ctx       The context to free. This may be \c NULL, in which
+ *                  case this function does nothing. If it is not \c NULL,
+ *                  it must point to an initialized ECDH context.
+ */
+void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx );
+
+/**
+ * \brief           This function generates an EC key pair and exports its
+ *                  in the format used in a TLS ServerKeyExchange handshake
+ *                  message.
+ *
+ *                  This is the second function used by a TLS server for ECDHE
+ *                  ciphersuites. (It is called after mbedtls_ecdh_setup().)
+ *
+ * \see             ecp.h
+ *
+ * \param ctx       The ECDH context to use. This must be initialized
+ *                  and bound to a group, for example via mbedtls_ecdh_setup().
+ * \param olen      The address at which to store the number of Bytes written.
+ * \param buf       The destination buffer. This must be a writable buffer of
+ *                  length \p blen Bytes.
+ * \param blen      The length of the destination buffer \p buf in Bytes.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL in case \p f_rng doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
+ */
+int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
+                      unsigned char *buf, size_t blen,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng );
+
+/**
+ * \brief           This function parses the ECDHE parameters in a
+ *                  TLS ServerKeyExchange handshake message.
+ *
+ * \note            In a TLS handshake, this is the how the client
+ *                  sets up its ECDHE context from the server's public
+ *                  ECDHE key material.
+ *
+ * \see             ecp.h
+ *
+ * \param ctx       The ECDHE context to use. This must be initialized.
+ * \param buf       On input, \c *buf must be the start of the input buffer.
+ *                  On output, \c *buf is updated to point to the end of the
+ *                  data that has been read. On success, this is the first byte
+ *                  past the end of the ServerKeyExchange parameters.
+ *                  On error, this is the point at which an error has been
+ *                  detected, which is usually not useful except to debug
+ *                  failures.
+ * \param end       The end of the input buffer.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX error code on failure.
+ *
+ */
+int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
+                              const unsigned char **buf,
+                              const unsigned char *end );
+
+/**
+ * \brief           This function sets up an ECDH context from an EC key.
+ *
+ *                  It is used by clients and servers in place of the
+ *                  ServerKeyEchange for static ECDH, and imports ECDH
+ *                  parameters from the EC key information of a certificate.
+ *
+ * \see             ecp.h
+ *
+ * \param ctx       The ECDH context to set up. This must be initialized.
+ * \param key       The EC key to use. This must be initialized.
+ * \param side      Defines the source of the key. Possible values are:
+ *                  - #MBEDTLS_ECDH_OURS: The key is ours.
+ *                  - #MBEDTLS_ECDH_THEIRS: The key is that of the peer.
+ *
+ * \return          \c 0 on success.
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
+ *
+ */
+int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
+                             const mbedtls_ecp_keypair *key,
+                             mbedtls_ecdh_side side );
+
+/**
+ * \brief           This function generates a public key and exports it
+ *                  as a TLS ClientKeyExchange payload.
+ *
+ *                  This is the second function used by a TLS client for ECDH(E)
+ *                  ciphersuites.
+ *
+ * \see             ecp.h
+ *
+ * \param ctx       The ECDH context to use. This must be initialized
+ *                  and bound to a group, the latter usually by
+ *                  mbedtls_ecdh_read_params().
+ * \param olen      The address at which to store the number of Bytes written.
+ *                  This must not be \c NULL.
+ * \param buf       The destination buffer. This must be a writable buffer
+ *                  of length \p blen Bytes.
+ * \param blen      The size of the destination buffer \p buf in Bytes.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL in case \p f_rng doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
+ */
+int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
+                      unsigned char *buf, size_t blen,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng );
+
+/**
+ * \brief       This function parses and processes the ECDHE payload of a
+ *              TLS ClientKeyExchange message.
+ *
+ *              This is the third function used by a TLS server for ECDH(E)
+ *              ciphersuites. (It is called after mbedtls_ecdh_setup() and
+ *              mbedtls_ecdh_make_params().)
+ *
+ * \see         ecp.h
+ *
+ * \param ctx   The ECDH context to use. This must be initialized
+ *              and bound to a group, for example via mbedtls_ecdh_setup().
+ * \param buf   The pointer to the ClientKeyExchange payload. This must
+ *              be a readable buffer of length \p blen Bytes.
+ * \param blen  The length of the input buffer \p buf in Bytes.
+ *
+ * \return      \c 0 on success.
+ * \return      An \c MBEDTLS_ERR_ECP_XXX error code on failure.
+ */
+int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
+                              const unsigned char *buf, size_t blen );
+
+/**
+ * \brief           This function derives and exports the shared secret.
+ *
+ *                  This is the last function used by both TLS client
+ *                  and servers.
+ *
+ * \note            If \p f_rng is not NULL, it is used to implement
+ *                  countermeasures against side-channel attacks.
+ *                  For more information, see mbedtls_ecp_mul().
+ *
+ * \see             ecp.h
+
+ * \param ctx       The ECDH context to use. This must be initialized
+ *                  and have its own private key generated and the peer's
+ *                  public key imported.
+ * \param olen      The address at which to store the total number of
+ *                  Bytes written on success. This must not be \c NULL.
+ * \param buf       The buffer to write the generated shared key to. This
+ *                  must be a writable buffer of size \p blen Bytes.
+ * \param blen      The length of the destination buffer \p buf in Bytes.
+ * \param f_rng     The RNG function, for blinding purposes. This may
+ *                  b \c NULL if blinding isn't needed.
+ * \param p_rng     The RNG context. This may be \c NULL if \p f_rng
+ *                  doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX error code on failure.
+ */
+int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
+                      unsigned char *buf, size_t blen,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           This function enables restartable EC computations for this
+ *                  context.  (Default: disabled.)
+ *
+ * \see             \c mbedtls_ecp_set_max_ops()
+ *
+ * \note            It is not possible to safely disable restartable
+ *                  computations once enabled, except by free-ing the context,
+ *                  which cancels possible in-progress operations.
+ *
+ * \param ctx       The ECDH context to use. This must be initialized.
+ */
+void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ecdh.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecdsa.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecdsa.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecdsa.h	(revision 398)
@@ -0,0 +1,545 @@
+/**
+ * \file ecdsa.h
+ *
+ * \brief This file contains ECDSA definitions and functions.
+ *
+ * The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in
+ * <em>Standards for Efficient Cryptography Group (SECG):
+ * SEC1 Elliptic Curve Cryptography</em>.
+ * The use of ECDSA for TLS is defined in <em>RFC-4492: Elliptic Curve
+ * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
+ *
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_ECDSA_H
+#define MBEDTLS_ECDSA_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "ecp.h"
+#include "md.h"
+
+/*
+ * RFC-4492 page 20:
+ *
+ *     Ecdsa-Sig-Value ::= SEQUENCE {
+ *         r       INTEGER,
+ *         s       INTEGER
+ *     }
+ *
+ * Size is at most
+ *    1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s,
+ *    twice that + 1 (tag) + 2 (len) for the sequence
+ * (assuming ECP_MAX_BYTES is less than 126 for r and s,
+ * and less than 124 (total len <= 255) for the sequence)
+ */
+#if MBEDTLS_ECP_MAX_BYTES > 124
+#error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN"
+#endif
+/** The maximal size of an ECDSA signature in Bytes. */
+#define MBEDTLS_ECDSA_MAX_LEN  ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief           The ECDSA context structure.
+ *
+ * \warning         Performing multiple operations concurrently on the same
+ *                  ECDSA context is not supported; objects of this type
+ *                  should not be shared between multiple threads.
+ */
+typedef mbedtls_ecp_keypair mbedtls_ecdsa_context;
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+
+/**
+ * \brief           Internal restart context for ecdsa_verify()
+ *
+ * \note            Opaque struct, defined in ecdsa.c
+ */
+typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx;
+
+/**
+ * \brief           Internal restart context for ecdsa_sign()
+ *
+ * \note            Opaque struct, defined in ecdsa.c
+ */
+typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx;
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+/**
+ * \brief           Internal restart context for ecdsa_sign_det()
+ *
+ * \note            Opaque struct, defined in ecdsa.c
+ */
+typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx;
+#endif
+
+/**
+ * \brief           General context for resuming ECDSA operations
+ */
+typedef struct
+{
+    mbedtls_ecp_restart_ctx ecp;        /*!<  base context for ECP restart and
+                                              shared administrative info    */
+    mbedtls_ecdsa_restart_ver_ctx *ver; /*!<  ecdsa_verify() sub-context    */
+    mbedtls_ecdsa_restart_sig_ctx *sig; /*!<  ecdsa_sign() sub-context      */
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+    mbedtls_ecdsa_restart_det_ctx *det; /*!<  ecdsa_sign_det() sub-context  */
+#endif
+} mbedtls_ecdsa_restart_ctx;
+
+#else /* MBEDTLS_ECP_RESTARTABLE */
+
+/* Now we can declare functions that take a pointer to that */
+typedef void mbedtls_ecdsa_restart_ctx;
+
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+/**
+ * \brief           This function computes the ECDSA signature of a
+ *                  previously-hashed message.
+ *
+ * \note            The deterministic version implemented in
+ *                  mbedtls_ecdsa_sign_det() is usually preferred.
+ *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated
+ *                  as defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \see             ecp.h
+ *
+ * \param grp       The context for the elliptic curve to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param r         The MPI context in which to store the first part
+ *                  the signature. This must be initialized.
+ * \param s         The MPI context in which to store the second part
+ *                  the signature. This must be initialized.
+ * \param d         The private signing key. This must be initialized.
+ * \param buf       The content to be signed. This is usually the hash of
+ *                  the original data to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes. It may be \c NULL if
+ *                  \p blen is zero.
+ * \param blen      The length of \p buf in Bytes.
+ * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng doesn't need a context parameter.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX
+ *                  or \c MBEDTLS_MPI_XXX error code on failure.
+ */
+int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
+                const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+/**
+ * \brief           This function computes the ECDSA signature of a
+ *                  previously-hashed message, deterministic version.
+ *
+ *                  For more information, see <em>RFC-6979: Deterministic
+ *                  Usage of the Digital Signature Algorithm (DSA) and Elliptic
+ *                  Curve Digital Signature Algorithm (ECDSA)</em>.
+ *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \see             ecp.h
+ *
+ * \param grp       The context for the elliptic curve to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param r         The MPI context in which to store the first part
+ *                  the signature. This must be initialized.
+ * \param s         The MPI context in which to store the second part
+ *                  the signature. This must be initialized.
+ * \param d         The private signing key. This must be initialized
+ *                  and setup, for example through mbedtls_ecp_gen_privkey().
+ * \param buf       The hashed content to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes. It may be \c NULL if
+ *                  \p blen is zero.
+ * \param blen      The length of \p buf in Bytes.
+ * \param md_alg    The hash algorithm used to hash the original data.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
+ *                  error code on failure.
+ */
+int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
+                            mbedtls_mpi *s, const mbedtls_mpi *d,
+                            const unsigned char *buf, size_t blen,
+                            mbedtls_md_type_t md_alg );
+#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
+
+/**
+ * \brief           This function verifies the ECDSA signature of a
+ *                  previously-hashed message.
+ *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.4, step 3.
+ *
+ * \see             ecp.h
+ *
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param buf       The hashed content that was signed. This must be a readable
+ *                  buffer of length \p blen Bytes. It may be \c NULL if
+ *                  \p blen is zero.
+ * \param blen      The length of \p buf in Bytes.
+ * \param Q         The public key to use for verification. This must be
+ *                  initialized and setup.
+ * \param r         The first integer of the signature.
+ *                  This must be initialized.
+ * \param s         The second integer of the signature.
+ *                  This must be initialized.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
+ *                  is invalid.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
+ *                  error code on failure for any other reason.
+ */
+int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
+                          const unsigned char *buf, size_t blen,
+                          const mbedtls_ecp_point *Q, const mbedtls_mpi *r,
+                          const mbedtls_mpi *s);
+
+/**
+ * \brief           This function computes the ECDSA signature and writes it
+ *                  to a buffer, serialized as defined in <em>RFC-4492:
+ *                  Elliptic Curve Cryptography (ECC) Cipher Suites for
+ *                  Transport Layer Security (TLS)</em>.
+ *
+ * \warning         It is not thread-safe to use the same context in
+ *                  multiple threads.
+ *
+ * \note            The deterministic version is used if
+ *                  #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more
+ *                  information, see <em>RFC-6979: Deterministic Usage
+ *                  of the Digital Signature Algorithm (DSA) and Elliptic
+ *                  Curve Digital Signature Algorithm (ECDSA)</em>.
+ *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \see             ecp.h
+ *
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and private key bound to it, for example
+ *                  via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
+ * \param md_alg    The message digest that was used to hash the message.
+ * \param hash      The message hash to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes.
+ * \param hlen      The length of the hash \p hash in Bytes.
+ * \param sig       The buffer to which to write the signature. This must be a
+ *                  writable buffer of length at least twice as large as the
+ *                  size of the curve used, plus 9. For example, 73 Bytes if
+ *                  a 256-bit curve is used. A buffer length of
+ *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param slen      The address at which to store the actual length of
+ *                  the signature written. Must not be \c NULL.
+ * \param f_rng     The RNG function. This must not be \c NULL if
+ *                  #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
+ *                  it is unused and may be set to \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng is \c NULL or doesn't use a context.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
+ *                  \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
+                                   mbedtls_md_type_t md_alg,
+                           const unsigned char *hash, size_t hlen,
+                           unsigned char *sig, size_t *slen,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng );
+
+/**
+ * \brief           This function computes the ECDSA signature and writes it
+ *                  to a buffer, in a restartable way.
+ *
+ * \see             \c mbedtls_ecdsa_write_signature()
+ *
+ * \note            This function is like \c mbedtls_ecdsa_write_signature()
+ *                  but it can return early and restart according to the limit
+ *                  set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
+ *
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and private key bound to it, for example
+ *                  via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
+ * \param md_alg    The message digest that was used to hash the message.
+ * \param hash      The message hash to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes.
+ * \param hlen      The length of the hash \p hash in Bytes.
+ * \param sig       The buffer to which to write the signature. This must be a
+ *                  writable buffer of length at least twice as large as the
+ *                  size of the curve used, plus 9. For example, 73 Bytes if
+ *                  a 256-bit curve is used. A buffer length of
+ *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param slen      The address at which to store the actual length of
+ *                  the signature written. Must not be \c NULL.
+ * \param f_rng     The RNG function. This must not be \c NULL if
+ *                  #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
+ *                  it is unused and may be set to \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng is \c NULL or doesn't use a context.
+ * \param rs_ctx    The restart context to use. This may be \c NULL to disable
+ *                  restarting. If it is not \c NULL, it must point to an
+ *                  initialized restart context.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
+ *                  \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
+                           mbedtls_md_type_t md_alg,
+                           const unsigned char *hash, size_t hlen,
+                           unsigned char *sig, size_t *slen,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng,
+                           mbedtls_ecdsa_restart_ctx *rs_ctx );
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief           This function computes an ECDSA signature and writes
+ *                  it to a buffer, serialized as defined in <em>RFC-4492:
+ *                  Elliptic Curve Cryptography (ECC) Cipher Suites for
+ *                  Transport Layer Security (TLS)</em>.
+ *
+ *                  The deterministic version is defined in <em>RFC-6979:
+ *                  Deterministic Usage of the Digital Signature Algorithm (DSA)
+ *                  and Elliptic Curve Digital Signature Algorithm (ECDSA)</em>.
+ *
+ * \warning         It is not thread-safe to use the same context in
+ *                  multiple threads.
+ *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.3, step 5.
+ *
+ * \see             ecp.h
+ *
+ * \deprecated      Superseded by mbedtls_ecdsa_write_signature() in
+ *                  Mbed TLS version 2.0 and later.
+ *
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and private key bound to it, for example
+ *                  via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
+ * \param hash      The message hash to be signed. This must be a readable
+ *                  buffer of length \p blen Bytes.
+ * \param hlen      The length of the hash \p hash in Bytes.
+ * \param sig       The buffer to which to write the signature. This must be a
+ *                  writable buffer of length at least twice as large as the
+ *                  size of the curve used, plus 9. For example, 73 Bytes if
+ *                  a 256-bit curve is used. A buffer length of
+ *                  #MBEDTLS_ECDSA_MAX_LEN is always safe.
+ * \param slen      The address at which to store the actual length of
+ *                  the signature written. Must not be \c NULL.
+ * \param md_alg    The message digest that was used to hash the message.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
+ *                  \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
+                               const unsigned char *hash, size_t hlen,
+                               unsigned char *sig, size_t *slen,
+                               mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED;
+#undef MBEDTLS_DEPRECATED
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
+
+/**
+ * \brief           This function reads and verifies an ECDSA signature.
+ *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  defined in <em>Standards for Efficient Cryptography Group
+ *                  (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+ *                  4.1.4, step 3.
+ *
+ * \see             ecp.h
+ *
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and public key bound to it.
+ * \param hash      The message hash that was signed. This must be a readable
+ *                  buffer of length \p size Bytes.
+ * \param hlen      The size of the hash \p hash.
+ * \param sig       The signature to read and verify. This must be a readable
+ *                  buffer of length \p slen Bytes.
+ * \param slen      The size of \p sig in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
+ * \return          #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
+ *                  signature in \p sig, but its length is less than \p siglen.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
+ *                  error code on failure for any other reason.
+ */
+int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
+                          const unsigned char *hash, size_t hlen,
+                          const unsigned char *sig, size_t slen );
+
+/**
+ * \brief           This function reads and verifies an ECDSA signature,
+ *                  in a restartable way.
+ *
+ * \see             \c mbedtls_ecdsa_read_signature()
+ *
+ * \note            This function is like \c mbedtls_ecdsa_read_signature()
+ *                  but it can return early and restart according to the limit
+ *                  set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
+ *
+ * \param ctx       The ECDSA context to use. This must be initialized
+ *                  and have a group and public key bound to it.
+ * \param hash      The message hash that was signed. This must be a readable
+ *                  buffer of length \p size Bytes.
+ * \param hlen      The size of the hash \p hash.
+ * \param sig       The signature to read and verify. This must be a readable
+ *                  buffer of length \p slen Bytes.
+ * \param slen      The size of \p sig in Bytes.
+ * \param rs_ctx    The restart context to use. This may be \c NULL to disable
+ *                  restarting. If it is not \c NULL, it must point to an
+ *                  initialized restart context.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
+ * \return          #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid
+ *                  signature in \p sig, but its length is less than \p siglen.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX
+ *                  error code on failure for any other reason.
+ */
+int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
+                          const unsigned char *hash, size_t hlen,
+                          const unsigned char *sig, size_t slen,
+                          mbedtls_ecdsa_restart_ctx *rs_ctx );
+
+/**
+ * \brief          This function generates an ECDSA keypair on the given curve.
+ *
+ * \see            ecp.h
+ *
+ * \param ctx      The ECDSA context to store the keypair in.
+ *                 This must be initialized.
+ * \param gid      The elliptic curve to use. One of the various
+ *                 \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
+ * \param f_rng    The RNG function to use. This must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng doesn't need a context argument.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_ECP_XXX code on failure.
+ */
+int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
+                  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief           This function sets up an ECDSA context from an EC key pair.
+ *
+ * \see             ecp.h
+ *
+ * \param ctx       The ECDSA context to setup. This must be initialized.
+ * \param key       The EC key to use. This must be initialized and hold
+ *                  a private-public key pair or a public key. In the former
+ *                  case, the ECDSA context may be used for signature creation
+ *                  and verification after this call. In the latter case, it
+ *                  may be used for signature verification.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX code on failure.
+ */
+int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx,
+                                const mbedtls_ecp_keypair *key );
+
+/**
+ * \brief           This function initializes an ECDSA context.
+ *
+ * \param ctx       The ECDSA context to initialize.
+ *                  This must not be \c NULL.
+ */
+void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
+
+/**
+ * \brief           This function frees an ECDSA context.
+ *
+ * \param ctx       The ECDSA context to free. This may be \c NULL,
+ *                  in which case this function does nothing. If it
+ *                  is not \c NULL, it must be initialized.
+ */
+void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Initialize a restart context.
+ *
+ * \param ctx       The restart context to initialize.
+ *                  This must not be \c NULL.
+ */
+void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx );
+
+/**
+ * \brief           Free the components of a restart context.
+ *
+ * \param ctx       The restart context to free. This may be \c NULL,
+ *                  in which case this function does nothing. If it
+ *                  is not \c NULL, it must be initialized.
+ */
+void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ecdsa.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecjpake.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecjpake.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecjpake.h	(revision 398)
@@ -0,0 +1,277 @@
+/**
+ * \file ecjpake.h
+ *
+ * \brief Elliptic curve J-PAKE
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_ECJPAKE_H
+#define MBEDTLS_ECJPAKE_H
+
+/*
+ * J-PAKE is a password-authenticated key exchange that allows deriving a
+ * strong shared secret from a (potentially low entropy) pre-shared
+ * passphrase, with forward secrecy and mutual authentication.
+ * https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling
+ *
+ * This file implements the Elliptic Curve variant of J-PAKE,
+ * as defined in Chapter 7.4 of the Thread v1.0 Specification,
+ * available to members of the Thread Group http://threadgroup.org/
+ *
+ * As the J-PAKE algorithm is inherently symmetric, so is our API.
+ * Each party needs to send its first round message, in any order, to the
+ * other party, then each sends its second round message, in any order.
+ * The payloads are serialized in a way suitable for use in TLS, but could
+ * also be use outside TLS.
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "ecp.h"
+#include "md.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Roles in the EC J-PAKE exchange
+ */
+typedef enum {
+    MBEDTLS_ECJPAKE_CLIENT = 0,         /**< Client                         */
+    MBEDTLS_ECJPAKE_SERVER,             /**< Server                         */
+} mbedtls_ecjpake_role;
+
+#if !defined(MBEDTLS_ECJPAKE_ALT)
+/**
+ * EC J-PAKE context structure.
+ *
+ * J-PAKE is a symmetric protocol, except for the identifiers used in
+ * Zero-Knowledge Proofs, and the serialization of the second message
+ * (KeyExchange) as defined by the Thread spec.
+ *
+ * In order to benefit from this symmetry, we choose a different naming
+ * convetion from the Thread v1.0 spec. Correspondance is indicated in the
+ * description as a pair C: client name, S: server name
+ */
+typedef struct mbedtls_ecjpake_context
+{
+    const mbedtls_md_info_t *md_info;   /**< Hash to use                    */
+    mbedtls_ecp_group grp;              /**< Elliptic curve                 */
+    mbedtls_ecjpake_role role;          /**< Are we client or server?       */
+    int point_format;                   /**< Format for point export        */
+
+    mbedtls_ecp_point Xm1;              /**< My public key 1   C: X1, S: X3 */
+    mbedtls_ecp_point Xm2;              /**< My public key 2   C: X2, S: X4 */
+    mbedtls_ecp_point Xp1;              /**< Peer public key 1 C: X3, S: X1 */
+    mbedtls_ecp_point Xp2;              /**< Peer public key 2 C: X4, S: X2 */
+    mbedtls_ecp_point Xp;               /**< Peer public key   C: Xs, S: Xc */
+
+    mbedtls_mpi xm1;                    /**< My private key 1  C: x1, S: x3 */
+    mbedtls_mpi xm2;                    /**< My private key 2  C: x2, S: x4 */
+
+    mbedtls_mpi s;                      /**< Pre-shared secret (passphrase) */
+} mbedtls_ecjpake_context;
+
+#else  /* MBEDTLS_ECJPAKE_ALT */
+#include "ecjpake_alt.h"
+#endif /* MBEDTLS_ECJPAKE_ALT */
+
+/**
+ * \brief           Initialize an ECJPAKE context.
+ *
+ * \param ctx       The ECJPAKE context to initialize.
+ *                  This must not be \c NULL.
+ */
+void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
+
+/**
+ * \brief           Set up an ECJPAKE context for use.
+ *
+ * \note            Currently the only values for hash/curve allowed by the
+ *                  standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1.
+ *
+ * \param ctx       The ECJPAKE context to set up. This must be initialized.
+ * \param role      The role of the caller. This must be either
+ *                  #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER.
+ * \param hash      The identifier of the hash function to use,
+ *                  for example #MBEDTLS_MD_SHA256.
+ * \param curve     The identifier of the elliptic curve to use,
+ *                  for example #MBEDTLS_ECP_DP_SECP256R1.
+ * \param secret    The pre-shared secret (passphrase). This must be
+ *                  a readable buffer of length \p len Bytes. It need
+ *                  only be valid for the duration of this call.
+ * \param len       The length of the pre-shared secret \p secret.
+ *
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
+                           mbedtls_ecjpake_role role,
+                           mbedtls_md_type_t hash,
+                           mbedtls_ecp_group_id curve,
+                           const unsigned char *secret,
+                           size_t len );
+
+/**
+ * \brief           Check if an ECJPAKE context is ready for use.
+ *
+ * \param ctx       The ECJPAKE context to check. This must be
+ *                  initialized.
+ *
+ * \return          \c 0 if the context is ready for use.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise.
+ */
+int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx );
+
+/**
+ * \brief           Generate and write the first round message
+ *                  (TLS: contents of the Client/ServerHello extension,
+ *                  excluding extension type and length bytes).
+ *
+ * \param ctx       The ECJPAKE context to use. This must be
+ *                  initialized and set up.
+ * \param buf       The buffer to write the contents to. This must be a
+ *                  writable buffer of length \p len Bytes.
+ * \param len       The length of \p buf in Bytes.
+ * \param olen      The address at which to store the total number
+ *                  of Bytes written to \p buf. This must not be \c NULL.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This
+ *                  may be \c NULL if \p f_rng doesn't use a context.
+ *
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
+                            unsigned char *buf, size_t len, size_t *olen,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng );
+
+/**
+ * \brief           Read and process the first round message
+ *                  (TLS: contents of the Client/ServerHello extension,
+ *                  excluding extension type and length bytes).
+ *
+ * \param ctx       The ECJPAKE context to use. This must be initialized
+ *                  and set up.
+ * \param buf       The buffer holding the first round message. This must
+ *                  be a readable buffer of length \p len Bytes.
+ * \param len       The length in Bytes of \p buf.
+ *
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
+                                    const unsigned char *buf,
+                                    size_t len );
+
+/**
+ * \brief           Generate and write the second round message
+ *                  (TLS: contents of the Client/ServerKeyExchange).
+ *
+ * \param ctx       The ECJPAKE context to use. This must be initialized,
+ *                  set up, and already have performed round one.
+ * \param buf       The buffer to write the round two contents to.
+ *                  This must be a writable buffer of length \p len Bytes.
+ * \param len       The size of \p buf in Bytes.
+ * \param olen      The address at which to store the total number of Bytes
+ *                  written to \p buf. This must not be \c NULL.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This
+ *                  may be \c NULL if \p f_rng doesn't use a context.
+ *
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
+                            unsigned char *buf, size_t len, size_t *olen,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng );
+
+/**
+ * \brief           Read and process the second round message
+ *                  (TLS: contents of the Client/ServerKeyExchange).
+ *
+ * \param ctx       The ECJPAKE context to use. This must be initialized
+ *                  and set up and already have performed round one.
+ * \param buf       The buffer holding the second round message. This must
+ *                  be a readable buffer of length \p len Bytes.
+ * \param len       The length in Bytes of \p buf.
+ *
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
+                                    const unsigned char *buf,
+                                    size_t len );
+
+/**
+ * \brief           Derive the shared secret
+ *                  (TLS: Pre-Master Secret).
+ *
+ * \param ctx       The ECJPAKE context to use. This must be initialized,
+ *                  set up and have performed both round one and two.
+ * \param buf       The buffer to write the derived secret to. This must
+ *                  be a writable buffer of length \p len Bytes.
+ * \param len       The length of \p buf in Bytes.
+ * \param olen      The address at which to store the total number of Bytes
+ *                  written to \p buf. This must not be \c NULL.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This
+ *                  may be \c NULL if \p f_rng doesn't use a context.
+ *
+ * \return          \c 0 if successful.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
+                            unsigned char *buf, size_t len, size_t *olen,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng );
+
+/**
+ * \brief           This clears an ECJPAKE context and frees any
+ *                  embedded data structure.
+ *
+ * \param ctx       The ECJPAKE context to free. This may be \c NULL,
+ *                  in which case this function does nothing. If it is not
+ *                  \c NULL, it must point to an initialized ECJPAKE context.
+ */
+void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if a test failed
+ */
+int mbedtls_ecjpake_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* ecjpake.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecp.h	(revision 398)
@@ -0,0 +1,1132 @@
+/**
+ * \file ecp.h
+ *
+ * \brief This file provides an API for Elliptic Curves over GF(P) (ECP).
+ *
+ * The use of ECP in cryptography and TLS is defined in
+ * <em>Standards for Efficient Cryptography Group (SECG): SEC1
+ * Elliptic Curve Cryptography</em> and
+ * <em>RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites
+ * for Transport Layer Security (TLS)</em>.
+ *
+ * <em>RFC-2409: The Internet Key Exchange (IKE)</em> defines ECP
+ * group types.
+ *
+ */
+
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_ECP_H
+#define MBEDTLS_ECP_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "bignum.h"
+
+/*
+ * ECP error codes
+ */
+#define MBEDTLS_ERR_ECP_BAD_INPUT_DATA                    -0x4F80  /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL                  -0x4F00  /**< The buffer is too small to write to. */
+#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE               -0x4E80  /**< The requested feature is not available, for example, the requested curve is not supported. */
+#define MBEDTLS_ERR_ECP_VERIFY_FAILED                     -0x4E00  /**< The signature is not valid. */
+#define MBEDTLS_ERR_ECP_ALLOC_FAILED                      -0x4D80  /**< Memory allocation failed. */
+#define MBEDTLS_ERR_ECP_RANDOM_FAILED                     -0x4D00  /**< Generation of random value, such as ephemeral key, failed. */
+#define MBEDTLS_ERR_ECP_INVALID_KEY                       -0x4C80  /**< Invalid private or public key. */
+#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH                  -0x4C00  /**< The buffer contains a valid signature followed by more data. */
+
+/* MBEDTLS_ERR_ECP_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_ECP_HW_ACCEL_FAILED                   -0x4B80  /**< The ECP hardware accelerator failed. */
+
+#define MBEDTLS_ERR_ECP_IN_PROGRESS                       -0x4B00  /**< Operation in progress, call again with the same parameters to continue. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Domain-parameter identifiers: curve, subgroup, and generator.
+ *
+ * \note Only curves over prime fields are supported.
+ *
+ * \warning This library does not support validation of arbitrary domain
+ * parameters. Therefore, only standardized domain parameters from trusted
+ * sources should be used. See mbedtls_ecp_group_load().
+ */
+typedef enum
+{
+    MBEDTLS_ECP_DP_NONE = 0,       /*!< Curve not defined. */
+    MBEDTLS_ECP_DP_SECP192R1,      /*!< Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP224R1,      /*!< Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP256R1,      /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP384R1,      /*!< Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_SECP521R1,      /*!< Domain parameters for the 521-bit curve defined by FIPS 186-4 and SEC1. */
+    MBEDTLS_ECP_DP_BP256R1,        /*!< Domain parameters for 256-bit Brainpool curve. */
+    MBEDTLS_ECP_DP_BP384R1,        /*!< Domain parameters for 384-bit Brainpool curve. */
+    MBEDTLS_ECP_DP_BP512R1,        /*!< Domain parameters for 512-bit Brainpool curve. */
+    MBEDTLS_ECP_DP_CURVE25519,     /*!< Domain parameters for Curve25519. */
+    MBEDTLS_ECP_DP_SECP192K1,      /*!< Domain parameters for 192-bit "Koblitz" curve. */
+    MBEDTLS_ECP_DP_SECP224K1,      /*!< Domain parameters for 224-bit "Koblitz" curve. */
+    MBEDTLS_ECP_DP_SECP256K1,      /*!< Domain parameters for 256-bit "Koblitz" curve. */
+    MBEDTLS_ECP_DP_CURVE448,       /*!< Domain parameters for Curve448. */
+} mbedtls_ecp_group_id;
+
+/**
+ * The number of supported curves, plus one for #MBEDTLS_ECP_DP_NONE.
+ *
+ * \note Montgomery curves are currently excluded.
+ */
+#define MBEDTLS_ECP_DP_MAX     12
+
+/**
+ * Curve information, for use by other modules.
+ */
+typedef struct mbedtls_ecp_curve_info
+{
+    mbedtls_ecp_group_id grp_id;    /*!< An internal identifier. */
+    uint16_t tls_id;                /*!< The TLS NamedCurve identifier. */
+    uint16_t bit_size;              /*!< The curve size in bits. */
+    const char *name;               /*!< A human-friendly name. */
+} mbedtls_ecp_curve_info;
+
+/**
+ * \brief           The ECP point structure, in Jacobian coordinates.
+ *
+ * \note            All functions expect and return points satisfying
+ *                  the following condition: <code>Z == 0</code> or
+ *                  <code>Z == 1</code>. Other values of \p Z are
+ *                  used only by internal functions.
+ *                  The point is zero, or "at infinity", if <code>Z == 0</code>.
+ *                  Otherwise, \p X and \p Y are its standard (affine)
+ *                  coordinates.
+ */
+typedef struct mbedtls_ecp_point
+{
+    mbedtls_mpi X;          /*!< The X coordinate of the ECP point. */
+    mbedtls_mpi Y;          /*!< The Y coordinate of the ECP point. */
+    mbedtls_mpi Z;          /*!< The Z coordinate of the ECP point. */
+}
+mbedtls_ecp_point;
+
+#if !defined(MBEDTLS_ECP_ALT)
+/*
+ * default mbed TLS elliptic curve arithmetic implementation
+ *
+ * (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an
+ * alternative implementation for the whole module and it will replace this
+ * one.)
+ */
+
+/**
+ * \brief           The ECP group structure.
+ *
+ * We consider two types of curve equations:
+ * <ul><li>Short Weierstrass: <code>y^2 = x^3 + A x + B mod P</code>
+ * (SEC1 + RFC-4492)</li>
+ * <li>Montgomery: <code>y^2 = x^3 + A x^2 + x mod P</code> (Curve25519,
+ * Curve448)</li></ul>
+ * In both cases, the generator (\p G) for a prime-order subgroup is fixed.
+ *
+ * For Short Weierstrass, this subgroup is the whole curve, and its
+ * cardinality is denoted by \p N. Our code requires that \p N is an
+ * odd prime as mbedtls_ecp_mul() requires an odd number, and
+ * mbedtls_ecdsa_sign() requires that it is prime for blinding purposes.
+ *
+ * For Montgomery curves, we do not store \p A, but <code>(A + 2) / 4</code>,
+ * which is the quantity used in the formulas. Additionally, \p nbits is
+ * not the size of \p N but the required size for private keys.
+ *
+ * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm.
+ * Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the
+ * range of <code>0..2^(2*pbits)-1</code>, and transforms it in-place to an integer
+ * which is congruent mod \p P to the given MPI, and is close enough to \p pbits
+ * in size, so that it may be efficiently brought in the 0..P-1 range by a few
+ * additions or subtractions. Therefore, it is only an approximative modular
+ * reduction. It must return 0 on success and non-zero on failure.
+ *
+ * \note        Alternative implementations must keep the group IDs distinct. If
+ *              two group structures have the same ID, then they must be
+ *              identical.
+ *
+ */
+typedef struct mbedtls_ecp_group
+{
+    mbedtls_ecp_group_id id;    /*!< An internal group identifier. */
+    mbedtls_mpi P;              /*!< The prime modulus of the base field. */
+    mbedtls_mpi A;              /*!< For Short Weierstrass: \p A in the equation. For
+                                     Montgomery curves: <code>(A + 2) / 4</code>. */
+    mbedtls_mpi B;              /*!< For Short Weierstrass: \p B in the equation.
+                                     For Montgomery curves: unused. */
+    mbedtls_ecp_point G;        /*!< The generator of the subgroup used. */
+    mbedtls_mpi N;              /*!< The order of \p G. */
+    size_t pbits;               /*!< The number of bits in \p P.*/
+    size_t nbits;               /*!< For Short Weierstrass: The number of bits in \p P.
+                                     For Montgomery curves: the number of bits in the
+                                     private keys. */
+    unsigned int h;             /*!< \internal 1 if the constants are static. */
+    int (*modp)(mbedtls_mpi *); /*!< The function for fast pseudo-reduction
+                                     mod \p P (see above).*/
+    int (*t_pre)(mbedtls_ecp_point *, void *);  /*!< Unused. */
+    int (*t_post)(mbedtls_ecp_point *, void *); /*!< Unused. */
+    void *t_data;               /*!< Unused. */
+    mbedtls_ecp_point *T;       /*!< Pre-computed points for ecp_mul_comb(). */
+    size_t T_size;              /*!< The number of pre-computed points. */
+}
+mbedtls_ecp_group;
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h, or define them using the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_ECP_MAX_BITS)
+/**
+ * The maximum size of the groups, that is, of \c N and \c P.
+ */
+#define MBEDTLS_ECP_MAX_BITS     521   /**< The maximum size of groups, in bits. */
+#endif
+
+#define MBEDTLS_ECP_MAX_BYTES    ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 )
+#define MBEDTLS_ECP_MAX_PT_LEN   ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 )
+
+#if !defined(MBEDTLS_ECP_WINDOW_SIZE)
+/*
+ * Maximum "window" size used for point multiplication.
+ * Default: 6.
+ * Minimum value: 2. Maximum value: 7.
+ *
+ * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
+ * points used for point multiplication. This value is directly tied to EC
+ * peak memory usage, so decreasing it by one should roughly cut memory usage
+ * by two (if large curves are in use).
+ *
+ * Reduction in size may reduce speed, but larger curves are impacted first.
+ * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1):
+ *      w-size:     6       5       4       3       2
+ *      521       145     141     135     120      97
+ *      384       214     209     198     177     146
+ *      256       320     320     303     262     226
+ *      224       475     475     453     398     342
+ *      192       640     640     633     587     476
+ */
+#define MBEDTLS_ECP_WINDOW_SIZE    6   /**< The maximum window size used. */
+#endif /* MBEDTLS_ECP_WINDOW_SIZE */
+
+#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
+/*
+ * Trade memory for speed on fixed-point multiplication.
+ *
+ * This speeds up repeated multiplication of the generator (that is, the
+ * multiplication in ECDSA signatures, and half of the multiplications in
+ * ECDSA verification and ECDHE) by a factor roughly 3 to 4.
+ *
+ * The cost is increasing EC peak memory usage by a factor roughly 2.
+ *
+ * Change this value to 0 to reduce peak memory usage.
+ */
+#define MBEDTLS_ECP_FIXED_POINT_OPTIM  1   /**< Enable fixed-point speed-up. */
+#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */
+
+/* \} name SECTION: Module settings */
+
+#else  /* MBEDTLS_ECP_ALT */
+#include "ecp_alt.h"
+#endif /* MBEDTLS_ECP_ALT */
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+
+/**
+ * \brief           Internal restart context for multiplication
+ *
+ * \note            Opaque struct
+ */
+typedef struct mbedtls_ecp_restart_mul mbedtls_ecp_restart_mul_ctx;
+
+/**
+ * \brief           Internal restart context for ecp_muladd()
+ *
+ * \note            Opaque struct
+ */
+typedef struct mbedtls_ecp_restart_muladd mbedtls_ecp_restart_muladd_ctx;
+
+/**
+ * \brief           General context for resuming ECC operations
+ */
+typedef struct
+{
+    unsigned ops_done;                  /*!<  current ops count             */
+    unsigned depth;                     /*!<  call depth (0 = top-level)    */
+    mbedtls_ecp_restart_mul_ctx *rsm;   /*!<  ecp_mul_comb() sub-context    */
+    mbedtls_ecp_restart_muladd_ctx *ma; /*!<  ecp_muladd() sub-context      */
+} mbedtls_ecp_restart_ctx;
+
+/*
+ * Operation counts for restartable functions
+ */
+#define MBEDTLS_ECP_OPS_CHK   3 /*!< basic ops count for ecp_check_pubkey()  */
+#define MBEDTLS_ECP_OPS_DBL   8 /*!< basic ops count for ecp_double_jac()    */
+#define MBEDTLS_ECP_OPS_ADD  11 /*!< basic ops count for see ecp_add_mixed() */
+#define MBEDTLS_ECP_OPS_INV 120 /*!< empirical equivalent for mpi_mod_inv()  */
+
+/**
+ * \brief           Internal; for restartable functions in other modules.
+ *                  Check and update basic ops budget.
+ *
+ * \param grp       Group structure
+ * \param rs_ctx    Restart context
+ * \param ops       Number of basic ops to do
+ *
+ * \return          \c 0 if doing \p ops basic ops is still allowed,
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS otherwise.
+ */
+int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp,
+                              mbedtls_ecp_restart_ctx *rs_ctx,
+                              unsigned ops );
+
+/* Utility macro for checking and updating ops budget */
+#define MBEDTLS_ECP_BUDGET( ops )   \
+    MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, rs_ctx, \
+                                               (unsigned) (ops) ) );
+
+#else /* MBEDTLS_ECP_RESTARTABLE */
+
+#define MBEDTLS_ECP_BUDGET( ops )   /* no-op; for compatibility */
+
+/* We want to declare restartable versions of existing functions anyway */
+typedef void mbedtls_ecp_restart_ctx;
+
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+/**
+ * \brief    The ECP key-pair structure.
+ *
+ * A generic key-pair that may be used for ECDSA and fixed ECDH, for example.
+ *
+ * \note    Members are deliberately in the same order as in the
+ *          ::mbedtls_ecdsa_context structure.
+ */
+typedef struct mbedtls_ecp_keypair
+{
+    mbedtls_ecp_group grp;      /*!<  Elliptic curve and base point     */
+    mbedtls_mpi d;              /*!<  our secret value                  */
+    mbedtls_ecp_point Q;        /*!<  our public value                  */
+}
+mbedtls_ecp_keypair;
+
+/*
+ * Point formats, from RFC 4492's enum ECPointFormat
+ */
+#define MBEDTLS_ECP_PF_UNCOMPRESSED    0   /**< Uncompressed point format. */
+#define MBEDTLS_ECP_PF_COMPRESSED      1   /**< Compressed point format. */
+
+/*
+ * Some other constants from RFC 4492
+ */
+#define MBEDTLS_ECP_TLS_NAMED_CURVE    3   /**< The named_curve of ECCurveType. */
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Set the maximum number of basic operations done in a row.
+ *
+ *                  If more operations are needed to complete a computation,
+ *                  #MBEDTLS_ERR_ECP_IN_PROGRESS will be returned by the
+ *                  function performing the computation. It is then the
+ *                  caller's responsibility to either call again with the same
+ *                  parameters until it returns 0 or an error code; or to free
+ *                  the restart context if the operation is to be aborted.
+ *
+ *                  It is strictly required that all input parameters and the
+ *                  restart context be the same on successive calls for the
+ *                  same operation, but output parameters need not be the
+ *                  same; they must not be used until the function finally
+ *                  returns 0.
+ *
+ *                  This only applies to functions whose documentation
+ *                  mentions they may return #MBEDTLS_ERR_ECP_IN_PROGRESS (or
+ *                  #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS for functions in the
+ *                  SSL module). For functions that accept a "restart context"
+ *                  argument, passing NULL disables restart and makes the
+ *                  function equivalent to the function with the same name
+ *                  with \c _restartable removed. For functions in the ECDH
+ *                  module, restart is disabled unless the function accepts
+ *                  an "ECDH context" argument and
+ *                  mbedtls_ecdh_enable_restart() was previously called on
+ *                  that context. For function in the SSL module, restart is
+ *                  only enabled for specific sides and key exchanges
+ *                  (currently only for clients and ECDHE-ECDSA).
+ *
+ * \param max_ops   Maximum number of basic operations done in a row.
+ *                  Default: 0 (unlimited).
+ *                  Lower (non-zero) values mean ECC functions will block for
+ *                  a lesser maximum amount of time.
+ *
+ * \note            A "basic operation" is defined as a rough equivalent of a
+ *                  multiplication in GF(p) for the NIST P-256 curve.
+ *                  As an indication, with default settings, a scalar
+ *                  multiplication (full run of \c mbedtls_ecp_mul()) is:
+ *                  - about 3300 basic operations for P-256
+ *                  - about 9400 basic operations for P-384
+ *
+ * \note            Very low values are not always respected: sometimes
+ *                  functions need to block for a minimum number of
+ *                  operations, and will do so even if max_ops is set to a
+ *                  lower value.  That minimum depends on the curve size, and
+ *                  can be made lower by decreasing the value of
+ *                  \c MBEDTLS_ECP_WINDOW_SIZE.  As an indication, here is the
+ *                  lowest effective value for various curves and values of
+ *                  that parameter (w for short):
+ *                          w=6     w=5     w=4     w=3     w=2
+ *                  P-256   208     208     160     136     124
+ *                  P-384   682     416     320     272     248
+ *                  P-521  1364     832     640     544     496
+ *
+ * \note            This setting is currently ignored by Curve25519.
+ */
+void mbedtls_ecp_set_max_ops( unsigned max_ops );
+
+/**
+ * \brief           Check if restart is enabled (max_ops != 0)
+ *
+ * \return          \c 0 if \c max_ops == 0 (restart disabled)
+ * \return          \c 1 otherwise (restart enabled)
+ */
+int mbedtls_ecp_restart_is_enabled( void );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+/**
+ * \brief           This function retrieves the information defined in
+ *                  mbedtls_ecp_curve_info() for all supported curves in order
+ *                  of preference.
+ *
+ * \return          A statically allocated array. The last entry is 0.
+ */
+const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void );
+
+/**
+ * \brief           This function retrieves the list of internal group
+ *                  identifiers of all supported curves in the order of
+ *                  preference.
+ *
+ * \return          A statically allocated array,
+ *                  terminated with MBEDTLS_ECP_DP_NONE.
+ */
+const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void );
+
+/**
+ * \brief           This function retrieves curve information from an internal
+ *                  group identifier.
+ *
+ * \param grp_id    An \c MBEDTLS_ECP_DP_XXX value.
+ *
+ * \return          The associated curve information on success.
+ * \return          NULL on failure.
+ */
+const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id );
+
+/**
+ * \brief           This function retrieves curve information from a TLS
+ *                  NamedCurve value.
+ *
+ * \param tls_id    An \c MBEDTLS_ECP_DP_XXX value.
+ *
+ * \return          The associated curve information on success.
+ * \return          NULL on failure.
+ */
+const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id );
+
+/**
+ * \brief           This function retrieves curve information from a
+ *                  human-readable name.
+ *
+ * \param name      The human-readable name.
+ *
+ * \return          The associated curve information on success.
+ * \return          NULL on failure.
+ */
+const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name );
+
+/**
+ * \brief           This function initializes a point as zero.
+ *
+ * \param pt        The point to initialize.
+ */
+void mbedtls_ecp_point_init( mbedtls_ecp_point *pt );
+
+/**
+ * \brief           This function initializes an ECP group context
+ *                  without loading any domain parameters.
+ *
+ * \note            After this function is called, domain parameters
+ *                  for various ECP groups can be loaded through the
+ *                  mbedtls_ecp_load() or mbedtls_ecp_tls_read_group()
+ *                  functions.
+ */
+void mbedtls_ecp_group_init( mbedtls_ecp_group *grp );
+
+/**
+ * \brief           This function initializes a key pair as an invalid one.
+ *
+ * \param key       The key pair to initialize.
+ */
+void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key );
+
+/**
+ * \brief           This function frees the components of a point.
+ *
+ * \param pt        The point to free.
+ */
+void mbedtls_ecp_point_free( mbedtls_ecp_point *pt );
+
+/**
+ * \brief           This function frees the components of an ECP group.
+ *
+ * \param grp       The group to free. This may be \c NULL, in which
+ *                  case this function returns immediately. If it is not
+ *                  \c NULL, it must point to an initialized ECP group.
+ */
+void mbedtls_ecp_group_free( mbedtls_ecp_group *grp );
+
+/**
+ * \brief           This function frees the components of a key pair.
+ *
+ * \param key       The key pair to free. This may be \c NULL, in which
+ *                  case this function returns immediately. If it is not
+ *                  \c NULL, it must point to an initialized ECP key pair.
+ */
+void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Initialize a restart context.
+ *
+ * \param ctx       The restart context to initialize. This must
+ *                  not be \c NULL.
+ */
+void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx );
+
+/**
+ * \brief           Free the components of a restart context.
+ *
+ * \param ctx       The restart context to free. This may be \c NULL, in which
+ *                  case this function returns immediately. If it is not
+ *                  \c NULL, it must point to an initialized restart context.
+ */
+void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+/**
+ * \brief           This function copies the contents of point \p Q into
+ *                  point \p P.
+ *
+ * \param P         The destination point. This must be initialized.
+ * \param Q         The source point. This must be initialized.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          Another negative error code for other kinds of failure.
+ */
+int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q );
+
+/**
+ * \brief           This function copies the contents of group \p src into
+ *                  group \p dst.
+ *
+ * \param dst       The destination group. This must be initialized.
+ * \param src       The source group. This must be initialized.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst,
+                            const mbedtls_ecp_group *src );
+
+/**
+ * \brief           This function sets a point to the point at infinity.
+ *
+ * \param pt        The point to set. This must be initialized.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt );
+
+/**
+ * \brief           This function checks if a point is the point at infinity.
+ *
+ * \param pt        The point to test. This must be initialized.
+ *
+ * \return          \c 1 if the point is zero.
+ * \return          \c 0 if the point is non-zero.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt );
+
+/**
+ * \brief           This function compares two points.
+ *
+ * \note            This assumes that the points are normalized. Otherwise,
+ *                  they may compare as "not equal" even if they are.
+ *
+ * \param P         The first point to compare. This must be initialized.
+ * \param Q         The second point to compare. This must be initialized.
+ *
+ * \return          \c 0 if the points are equal.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal.
+ */
+int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
+                           const mbedtls_ecp_point *Q );
+
+/**
+ * \brief           This function imports a non-zero point from two ASCII
+ *                  strings.
+ *
+ * \param P         The destination point. This must be initialized.
+ * \param radix     The numeric base of the input.
+ * \param x         The first affine coordinate, as a null-terminated string.
+ * \param y         The second affine coordinate, as a null-terminated string.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_MPI_XXX error code on failure.
+ */
+int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
+                           const char *x, const char *y );
+
+/**
+ * \brief           This function exports a point into unsigned binary data.
+ *
+ * \param grp       The group to which the point should belong.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param P         The point to export. This must be initialized.
+ * \param format    The point format. This must be either
+ *                  #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
+ * \param olen      The address at which to store the length of
+ *                  the output in Bytes. This must not be \c NULL.
+ * \param buf       The output buffer. This must be a writable buffer
+ *                  of length \p buflen Bytes.
+ * \param buflen    The length of the output buffer \p buf in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer
+ *                  is too small to hold the point.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
+                            int format, size_t *olen,
+                            unsigned char *buf, size_t buflen );
+
+/**
+ * \brief           This function imports a point from unsigned binary data.
+ *
+ * \note            This function does not check that the point actually
+ *                  belongs to the given group, see mbedtls_ecp_check_pubkey()
+ *                  for that.
+ *
+ * \param grp       The group to which the point should belong.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param P         The destination context to import the point to.
+ *                  This must be initialized.
+ * \param buf       The input buffer. This must be a readable buffer
+ *                  of length \p ilen Bytes.
+ * \param ilen      The length of the input buffer \p buf in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
+ *                  is not implemented.
+ */
+int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
+                                   mbedtls_ecp_point *P,
+                                   const unsigned char *buf, size_t ilen );
+
+/**
+ * \brief           This function imports a point from a TLS ECPoint record.
+ *
+ * \note            On function return, \p *buf is updated to point immediately
+ *                  after the ECPoint record.
+ *
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param pt        The destination point.
+ * \param buf       The address of the pointer to the start of the input buffer.
+ * \param len       The length of the buffer.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_MPI_XXX error code on initialization
+ *                  failure.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ */
+int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp,
+                                mbedtls_ecp_point *pt,
+                                const unsigned char **buf, size_t len );
+
+/**
+ * \brief           This function exports a point as a TLS ECPoint record
+ *                  defined in RFC 4492, Section 5.4.
+ *
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param pt        The point to be exported. This must be initialized.
+ * \param format    The point format to use. This must be either
+ *                  #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
+ * \param olen      The address at which to store the length in Bytes
+ *                  of the data written.
+ * \param buf       The target buffer. This must be a writable buffer of
+ *                  length \p blen Bytes.
+ * \param blen      The length of the target buffer \p buf in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid.
+ * \return          #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the target buffer
+ *                  is too small to hold the exported point.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp,
+                                 const mbedtls_ecp_point *pt,
+                                 int format, size_t *olen,
+                                 unsigned char *buf, size_t blen );
+
+/**
+ * \brief           This function sets up an ECP group context
+ *                  from a standardized set of domain parameters.
+ *
+ * \note            The index should be a value of the NamedCurve enum,
+ *                  as defined in <em>RFC-4492: Elliptic Curve Cryptography
+ *                  (ECC) Cipher Suites for Transport Layer Security (TLS)</em>,
+ *                  usually in the form of an \c MBEDTLS_ECP_DP_XXX macro.
+ *
+ * \param grp       The group context to setup. This must be initialized.
+ * \param id        The identifier of the domain parameter set to load.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't
+ *                  correspond to a known group.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id );
+
+/**
+ * \brief           This function sets up an ECP group context from a TLS
+ *                  ECParameters record as defined in RFC 4492, Section 5.4.
+ *
+ * \note            The read pointer \p buf is updated to point right after
+ *                  the ECParameters record on exit.
+ *
+ * \param grp       The group context to setup. This must be initialized.
+ * \param buf       The address of the pointer to the start of the input buffer.
+ * \param len       The length of the input buffer \c *buf in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not
+ *                  recognized.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp,
+                                const unsigned char **buf, size_t len );
+
+/**
+ * \brief           This function extracts an elliptic curve group ID from a
+ *                  TLS ECParameters record as defined in RFC 4492, Section 5.4.
+ *
+ * \note            The read pointer \p buf is updated to point right after
+ *                  the ECParameters record on exit.
+ *
+ * \param grp       The address at which to store the group id.
+ *                  This must not be \c NULL.
+ * \param buf       The address of the pointer to the start of the input buffer.
+ * \param len       The length of the input buffer \c *buf in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid.
+ * \return          #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not
+ *                  recognized.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp,
+                                   const unsigned char **buf,
+                                   size_t len );
+/**
+ * \brief           This function exports an elliptic curve as a TLS
+ *                  ECParameters record as defined in RFC 4492, Section 5.4.
+ *
+ * \param grp       The ECP group to be exported.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param olen      The address at which to store the number of Bytes written.
+ *                  This must not be \c NULL.
+ * \param buf       The buffer to write to. This must be a writable buffer
+ *                  of length \p blen Bytes.
+ * \param blen      The length of the output buffer \p buf in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output
+ *                  buffer is too small to hold the exported group.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp,
+                                 size_t *olen,
+                                 unsigned char *buf, size_t blen );
+
+/**
+ * \brief           This function performs a scalar multiplication of a point
+ *                  by an integer: \p R = \p m * \p P.
+ *
+ *                  It is not thread-safe to use same group in multiple threads.
+ *
+ * \note            To prevent timing attacks, this function
+ *                  executes the exact same sequence of base-field
+ *                  operations for any valid \p m. It avoids any if-branch or
+ *                  array index depending on the value of \p m.
+ *
+ * \note            If \p f_rng is not NULL, it is used to randomize
+ *                  intermediate results to prevent potential timing attacks
+ *                  targeting these results. We recommend always providing
+ *                  a non-NULL \p f_rng. The overhead is negligible.
+ *
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param R         The point in which to store the result of the calculation.
+ *                  This must be initialized.
+ * \param m         The integer by which to multiply. This must be initialized.
+ * \param P         The point to multiply. This must be initialized.
+ * \param f_rng     The RNG function. This may be \c NULL if randomization
+ *                  of intermediate results isn't desired (discouraged).
+ * \param p_rng     The RNG context to be passed to \p p_rng.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private
+ *                  key, or \p P is not a valid public key.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief           This function performs multiplication of a point by
+ *                  an integer: \p R = \p m * \p P in a restartable way.
+ *
+ * \see             mbedtls_ecp_mul()
+ *
+ * \note            This function does the same as \c mbedtls_ecp_mul(), but
+ *                  it can return early and restart according to the limit set
+ *                  with \c mbedtls_ecp_set_max_ops() to reduce blocking.
+ *
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param R         The point in which to store the result of the calculation.
+ *                  This must be initialized.
+ * \param m         The integer by which to multiply. This must be initialized.
+ * \param P         The point to multiply. This must be initialized.
+ * \param f_rng     The RNG function. This may be \c NULL if randomization
+ *                  of intermediate results isn't desired (discouraged).
+ * \param p_rng     The RNG context to be passed to \p p_rng.
+ * \param rs_ctx    The restart context (NULL disables restart).
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private
+ *                  key, or \p P is not a valid public key.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+             mbedtls_ecp_restart_ctx *rs_ctx );
+
+/**
+ * \brief           This function performs multiplication and addition of two
+ *                  points by integers: \p R = \p m * \p P + \p n * \p Q
+ *
+ *                  It is not thread-safe to use same group in multiple threads.
+ *
+ * \note            In contrast to mbedtls_ecp_mul(), this function does not
+ *                  guarantee a constant execution flow and timing.
+ *
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param R         The point in which to store the result of the calculation.
+ *                  This must be initialized.
+ * \param m         The integer by which to multiply \p P.
+ *                  This must be initialized.
+ * \param P         The point to multiply by \p m. This must be initialized.
+ * \param n         The integer by which to multiply \p Q.
+ *                  This must be initialized.
+ * \param Q         The point to be multiplied by \p n.
+ *                  This must be initialized.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not
+ *                  valid private keys, or \p P or \p Q are not valid public
+ *                  keys.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             const mbedtls_mpi *n, const mbedtls_ecp_point *Q );
+
+/**
+ * \brief           This function performs multiplication and addition of two
+ *                  points by integers: \p R = \p m * \p P + \p n * \p Q in a
+ *                  restartable way.
+ *
+ * \see             \c mbedtls_ecp_muladd()
+ *
+ * \note            This function works the same as \c mbedtls_ecp_muladd(),
+ *                  but it can return early and restart according to the limit
+ *                  set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
+ *
+ * \param grp       The ECP group to use.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param R         The point in which to store the result of the calculation.
+ *                  This must be initialized.
+ * \param m         The integer by which to multiply \p P.
+ *                  This must be initialized.
+ * \param P         The point to multiply by \p m. This must be initialized.
+ * \param n         The integer by which to multiply \p Q.
+ *                  This must be initialized.
+ * \param Q         The point to be multiplied by \p n.
+ *                  This must be initialized.
+ * \param rs_ctx    The restart context (NULL disables restart).
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not
+ *                  valid private keys, or \p P or \p Q are not valid public
+ *                  keys.
+ * \return          #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_muladd_restartable(
+             mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
+             mbedtls_ecp_restart_ctx *rs_ctx );
+
+/**
+ * \brief           This function checks that a point is a valid public key
+ *                  on this curve.
+ *
+ *                  It only checks that the point is non-zero, has
+ *                  valid coordinates and lies on the curve. It does not verify
+ *                  that it is indeed a multiple of \p G. This additional
+ *                  check is computationally more expensive, is not required
+ *                  by standards, and should not be necessary if the group
+ *                  used has a small cofactor. In particular, it is useless for
+ *                  the NIST groups which all have a cofactor of 1.
+ *
+ * \note            This function uses bare components rather than an
+ *                  ::mbedtls_ecp_keypair structure, to ease use with other
+ *                  structures, such as ::mbedtls_ecdh_context or
+ *                  ::mbedtls_ecdsa_context.
+ *
+ * \param grp       The ECP group the point should belong to.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param pt        The point to check. This must be initialized.
+ *
+ * \return          \c 0 if the point is a valid public key.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not
+ *                  a valid public key for the given curve.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
+                              const mbedtls_ecp_point *pt );
+
+/**
+ * \brief           This function checks that an \p mbedtls_mpi is a
+ *                  valid private key for this curve.
+ *
+ * \note            This function uses bare components rather than an
+ *                  ::mbedtls_ecp_keypair structure to ease use with other
+ *                  structures, such as ::mbedtls_ecdh_context or
+ *                  ::mbedtls_ecdsa_context.
+ *
+ * \param grp       The ECP group the private key should belong to.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param d         The integer to check. This must be initialized.
+ *
+ * \return          \c 0 if the point is a valid private key.
+ * \return          #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not a valid
+ *                  private key for the given curve.
+ * \return          Another negative error code on other kinds of failure.
+ */
+int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
+                               const mbedtls_mpi *d );
+
+/**
+ * \brief           This function generates a private key.
+ *
+ * \param grp       The ECP group to generate a private key for.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param d         The destination MPI (secret part). This must be initialized.
+ * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param p_rng     The RNG parameter to be passed to \p f_rng. This may be
+ *                  \c NULL if \p f_rng doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
+ *                  on failure.
+ */
+int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
+                     mbedtls_mpi *d,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng );
+
+/**
+ * \brief           This function generates a keypair with a configurable base
+ *                  point.
+ *
+ * \note            This function uses bare components rather than an
+ *                  ::mbedtls_ecp_keypair structure to ease use with other
+ *                  structures, such as ::mbedtls_ecdh_context or
+ *                  ::mbedtls_ecdsa_context.
+ *
+ * \param grp       The ECP group to generate a key pair for.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param G         The base point to use. This must be initialized
+ *                  and belong to \p grp. It replaces the default base
+ *                  point \c grp->G used by mbedtls_ecp_gen_keypair().
+ * \param d         The destination MPI (secret part).
+ *                  This must be initialized.
+ * \param Q         The destination point (public part).
+ *                  This must be initialized.
+ * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may
+ *                  be \c NULL if \p f_rng doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
+ *                  on failure.
+ */
+int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
+                                  const mbedtls_ecp_point *G,
+                                  mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                                  int (*f_rng)(void *, unsigned char *, size_t),
+                                  void *p_rng );
+
+/**
+ * \brief           This function generates an ECP keypair.
+ *
+ * \note            This function uses bare components rather than an
+ *                  ::mbedtls_ecp_keypair structure to ease use with other
+ *                  structures, such as ::mbedtls_ecdh_context or
+ *                  ::mbedtls_ecdsa_context.
+ *
+ * \param grp       The ECP group to generate a key pair for.
+ *                  This must be initialized and have group parameters
+ *                  set, for example through mbedtls_ecp_group_load().
+ * \param d         The destination MPI (secret part).
+ *                  This must be initialized.
+ * \param Q         The destination point (public part).
+ *                  This must be initialized.
+ * \param f_rng     The RNG function. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may
+ *                  be \c NULL if \p f_rng doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
+ *                  on failure.
+ */
+int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d,
+                             mbedtls_ecp_point *Q,
+                             int (*f_rng)(void *, unsigned char *, size_t),
+                             void *p_rng );
+
+/**
+ * \brief           This function generates an ECP key.
+ *
+ * \param grp_id    The ECP group identifier.
+ * \param key       The destination key. This must be initialized.
+ * \param f_rng     The RNG function to use. This must not be \c NULL.
+ * \param p_rng     The RNG context to be passed to \p f_rng. This may
+ *                  be \c NULL if \p f_rng doesn't need a context argument.
+ *
+ * \return          \c 0 on success.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
+ *                  on failure.
+ */
+int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng );
+
+/**
+ * \brief           This function checks that the keypair objects
+ *                  \p pub and \p prv have the same group and the
+ *                  same public point, and that the private key in
+ *                  \p prv is consistent with the public key.
+ *
+ * \param pub       The keypair structure holding the public key. This
+ *                  must be initialized. If it contains a private key, that
+ *                  part is ignored.
+ * \param prv       The keypair structure holding the full keypair.
+ *                  This must be initialized.
+ *
+ * \return          \c 0 on success, meaning that the keys are valid and match.
+ * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match.
+ * \return          An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX
+ *                  error code on calculation failure.
+ */
+int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub,
+                                const mbedtls_ecp_keypair *prv );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          The ECP checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_ecp_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ecp.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecp_internal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecp_internal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ecp_internal.h	(revision 398)
@@ -0,0 +1,299 @@
+/**
+ * \file ecp_internal.h
+ *
+ * \brief Function declarations for alternative implementation of elliptic curve
+ * point arithmetic.
+ */
+/*
+ *  Copyright (C) 2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * References:
+ *
+ * [1] BERNSTEIN, Daniel J. Curve25519: new Diffie-Hellman speed records.
+ *     <http://cr.yp.to/ecdh/curve25519-20060209.pdf>
+ *
+ * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
+ *     for elliptic curve cryptosystems. In : Cryptographic Hardware and
+ *     Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
+ *     <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
+ *
+ * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
+ *     render ECC resistant against Side Channel Attacks. IACR Cryptology
+ *     ePrint Archive, 2004, vol. 2004, p. 342.
+ *     <http://eprint.iacr.org/2004/342.pdf>
+ *
+ * [4] Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters.
+ *     <http://www.secg.org/sec2-v2.pdf>
+ *
+ * [5] HANKERSON, Darrel, MENEZES, Alfred J., VANSTONE, Scott. Guide to Elliptic
+ *     Curve Cryptography.
+ *
+ * [6] Digital Signature Standard (DSS), FIPS 186-4.
+ *     <http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf>
+ *
+ * [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
+ *     Security (TLS), RFC 4492.
+ *     <https://tools.ietf.org/search/rfc4492>
+ *
+ * [8] <http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html>
+ *
+ * [9] COHEN, Henri. A Course in Computational Algebraic Number Theory.
+ *     Springer Science & Business Media, 1 Aug 2000
+ */
+
+#ifndef MBEDTLS_ECP_INTERNAL_H
+#define MBEDTLS_ECP_INTERNAL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+
+/**
+ * \brief           Indicate if the Elliptic Curve Point module extension can
+ *                  handle the group.
+ *
+ * \param grp       The pointer to the elliptic curve group that will be the
+ *                  basis of the cryptographic computations.
+ *
+ * \return          Non-zero if successful.
+ */
+unsigned char mbedtls_internal_ecp_grp_capable( const mbedtls_ecp_group *grp );
+
+/**
+ * \brief           Initialise the Elliptic Curve Point module extension.
+ *
+ *                  If mbedtls_internal_ecp_grp_capable returns true for a
+ *                  group, this function has to be able to initialise the
+ *                  module for it.
+ *
+ *                  This module can be a driver to a crypto hardware
+ *                  accelerator, for which this could be an initialise function.
+ *
+ * \param grp       The pointer to the group the module needs to be
+ *                  initialised for.
+ *
+ * \return          0 if successful.
+ */
+int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp );
+
+/**
+ * \brief           Frees and deallocates the Elliptic Curve Point module
+ *                  extension.
+ *
+ * \param grp       The pointer to the group the module was initialised for.
+ */
+void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp );
+
+#if defined(ECP_SHORTWEIERSTRASS)
+
+#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
+/**
+ * \brief           Randomize jacobian coordinates:
+ *                  (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l.
+ *
+ * \param grp       Pointer to the group representing the curve.
+ *
+ * \param pt        The point on the curve to be randomised, given with Jacobian
+ *                  coordinates.
+ *
+ * \param f_rng     A function pointer to the random number generator.
+ *
+ * \param p_rng     A pointer to the random number generator state.
+ *
+ * \return          0 if successful.
+ */
+int mbedtls_internal_ecp_randomize_jac( const mbedtls_ecp_group *grp,
+        mbedtls_ecp_point *pt, int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng );
+#endif
+
+#if defined(MBEDTLS_ECP_ADD_MIXED_ALT)
+/**
+ * \brief           Addition: R = P + Q, mixed affine-Jacobian coordinates.
+ *
+ *                  The coordinates of Q must be normalized (= affine),
+ *                  but those of P don't need to. R is not normalized.
+ *
+ *                  This function is used only as a subrutine of
+ *                  ecp_mul_comb().
+ *
+ *                  Special cases: (1) P or Q is zero, (2) R is zero,
+ *                      (3) P == Q.
+ *                  None of these cases can happen as intermediate step in
+ *                  ecp_mul_comb():
+ *                      - at each step, P, Q and R are multiples of the base
+ *                      point, the factor being less than its order, so none of
+ *                      them is zero;
+ *                      - Q is an odd multiple of the base point, P an even
+ *                      multiple, due to the choice of precomputed points in the
+ *                      modified comb method.
+ *                  So branches for these cases do not leak secret information.
+ *
+ *                  We accept Q->Z being unset (saving memory in tables) as
+ *                  meaning 1.
+ *
+ *                  Cost in field operations if done by [5] 3.22:
+ *                      1A := 8M + 3S
+ *
+ * \param grp       Pointer to the group representing the curve.
+ *
+ * \param R         Pointer to a point structure to hold the result.
+ *
+ * \param P         Pointer to the first summand, given with Jacobian
+ *                  coordinates
+ *
+ * \param Q         Pointer to the second summand, given with affine
+ *                  coordinates.
+ *
+ * \return          0 if successful.
+ */
+int mbedtls_internal_ecp_add_mixed( const mbedtls_ecp_group *grp,
+        mbedtls_ecp_point *R, const mbedtls_ecp_point *P,
+        const mbedtls_ecp_point *Q );
+#endif
+
+/**
+ * \brief           Point doubling R = 2 P, Jacobian coordinates.
+ *
+ *                  Cost:   1D := 3M + 4S    (A ==  0)
+ *                          4M + 4S          (A == -3)
+ *                          3M + 6S + 1a     otherwise
+ *                  when the implementation is based on the "dbl-1998-cmo-2"
+ *                  doubling formulas in [8] and standard optimizations are
+ *                  applied when curve parameter A is one of { 0, -3 }.
+ *
+ * \param grp       Pointer to the group representing the curve.
+ *
+ * \param R         Pointer to a point structure to hold the result.
+ *
+ * \param P         Pointer to the point that has to be doubled, given with
+ *                  Jacobian coordinates.
+ *
+ * \return          0 if successful.
+ */
+#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
+int mbedtls_internal_ecp_double_jac( const mbedtls_ecp_group *grp,
+        mbedtls_ecp_point *R, const mbedtls_ecp_point *P );
+#endif
+
+/**
+ * \brief           Normalize jacobian coordinates of an array of (pointers to)
+ *                  points.
+ *
+ *                  Using Montgomery's trick to perform only one inversion mod P
+ *                  the cost is:
+ *                      1N(t) := 1I + (6t - 3)M + 1S
+ *                  (See for example Algorithm 10.3.4. in [9])
+ *
+ *                  This function is used only as a subrutine of
+ *                  ecp_mul_comb().
+ *
+ *                  Warning: fails (returning an error) if one of the points is
+ *                  zero!
+ *                  This should never happen, see choice of w in ecp_mul_comb().
+ *
+ * \param grp       Pointer to the group representing the curve.
+ *
+ * \param T         Array of pointers to the points to normalise.
+ *
+ * \param t_len     Number of elements in the array.
+ *
+ * \return          0 if successful,
+ *                      an error if one of the points is zero.
+ */
+#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
+int mbedtls_internal_ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
+        mbedtls_ecp_point *T[], size_t t_len );
+#endif
+
+/**
+ * \brief           Normalize jacobian coordinates so that Z == 0 || Z == 1.
+ *
+ *                  Cost in field operations if done by [5] 3.2.1:
+ *                      1N := 1I + 3M + 1S
+ *
+ * \param grp       Pointer to the group representing the curve.
+ *
+ * \param pt        pointer to the point to be normalised. This is an
+ *                  input/output parameter.
+ *
+ * \return          0 if successful.
+ */
+#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
+int mbedtls_internal_ecp_normalize_jac( const mbedtls_ecp_group *grp,
+        mbedtls_ecp_point *pt );
+#endif
+
+#endif /* ECP_SHORTWEIERSTRASS */
+
+#if defined(ECP_MONTGOMERY)
+
+#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
+int mbedtls_internal_ecp_double_add_mxz( const mbedtls_ecp_group *grp,
+        mbedtls_ecp_point *R, mbedtls_ecp_point *S, const mbedtls_ecp_point *P,
+        const mbedtls_ecp_point *Q, const mbedtls_mpi *d );
+#endif
+
+/**
+ * \brief           Randomize projective x/z coordinates:
+ *                      (X, Z) -> (l X, l Z) for random l
+ *
+ * \param grp       pointer to the group representing the curve
+ *
+ * \param P         the point on the curve to be randomised given with
+ *                  projective coordinates. This is an input/output parameter.
+ *
+ * \param f_rng     a function pointer to the random number generator
+ *
+ * \param p_rng     a pointer to the random number generator state
+ *
+ * \return          0 if successful
+ */
+#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
+int mbedtls_internal_ecp_randomize_mxz( const mbedtls_ecp_group *grp,
+        mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng );
+#endif
+
+/**
+ * \brief           Normalize Montgomery x/z coordinates: X = X/Z, Z = 1.
+ *
+ * \param grp       pointer to the group representing the curve
+ *
+ * \param P         pointer to the point to be normalised. This is an
+ *                  input/output parameter.
+ *
+ * \return          0 if successful
+ */
+#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
+int mbedtls_internal_ecp_normalize_mxz( const mbedtls_ecp_group *grp,
+        mbedtls_ecp_point *P );
+#endif
+
+#endif /* ECP_MONTGOMERY */
+
+#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+
+#endif /* ecp_internal.h */
+
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/entropy.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/entropy.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/entropy.h	(revision 398)
@@ -0,0 +1,289 @@
+/**
+ * \file entropy.h
+ *
+ * \brief Entropy accumulator implementation
+ */
+/*
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_ENTROPY_H
+#define MBEDTLS_ENTROPY_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
+#include "sha512.h"
+#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
+#else
+#if defined(MBEDTLS_SHA256_C)
+#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
+#include "sha256.h"
+#endif
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+#include "threading.h"
+#endif
+
+#if defined(MBEDTLS_HAVEGE_C)
+#include "havege.h"
+#endif
+
+#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED                 -0x003C  /**< Critical entropy source failure. */
+#define MBEDTLS_ERR_ENTROPY_MAX_SOURCES                   -0x003E  /**< No more sources can be added. */
+#define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED            -0x0040  /**< No sources have been added to poll. */
+#define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE              -0x003D  /**< No strong sources have been added to poll. */
+#define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR                 -0x003F  /**< Read/write error in file. */
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_ENTROPY_MAX_SOURCES)
+#define MBEDTLS_ENTROPY_MAX_SOURCES     20      /**< Maximum number of sources supported */
+#endif
+
+#if !defined(MBEDTLS_ENTROPY_MAX_GATHER)
+#define MBEDTLS_ENTROPY_MAX_GATHER      128     /**< Maximum amount requested from entropy sources */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
+#define MBEDTLS_ENTROPY_BLOCK_SIZE      64      /**< Block size of entropy accumulator (SHA-512) */
+#else
+#define MBEDTLS_ENTROPY_BLOCK_SIZE      32      /**< Block size of entropy accumulator (SHA-256) */
+#endif
+
+#define MBEDTLS_ENTROPY_MAX_SEED_SIZE   1024    /**< Maximum size of seed we read from seed file */
+#define MBEDTLS_ENTROPY_SOURCE_MANUAL   MBEDTLS_ENTROPY_MAX_SOURCES
+
+#define MBEDTLS_ENTROPY_SOURCE_STRONG   1       /**< Entropy source is strong   */
+#define MBEDTLS_ENTROPY_SOURCE_WEAK     0       /**< Entropy source is weak     */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief           Entropy poll callback pointer
+ *
+ * \param data      Callback-specific data pointer
+ * \param output    Data to fill
+ * \param len       Maximum size to provide
+ * \param olen      The actual amount of bytes put into the buffer (Can be 0)
+ *
+ * \return          0 if no critical failures occurred,
+ *                  MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise
+ */
+typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len,
+                            size_t *olen);
+
+/**
+ * \brief           Entropy source state
+ */
+typedef struct mbedtls_entropy_source_state
+{
+    mbedtls_entropy_f_source_ptr    f_source;   /**< The entropy source callback */
+    void *          p_source;   /**< The callback data pointer */
+    size_t          size;       /**< Amount received in bytes */
+    size_t          threshold;  /**< Minimum bytes required before release */
+    int             strong;     /**< Is the source strong? */
+}
+mbedtls_entropy_source_state;
+
+/**
+ * \brief           Entropy context structure
+ */
+typedef struct mbedtls_entropy_context
+{
+    int accumulator_started;
+#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
+    mbedtls_sha512_context  accumulator;
+#else
+    mbedtls_sha256_context  accumulator;
+#endif
+    int             source_count;
+    mbedtls_entropy_source_state    source[MBEDTLS_ENTROPY_MAX_SOURCES];
+#if defined(MBEDTLS_HAVEGE_C)
+    mbedtls_havege_state    havege_data;
+#endif
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;    /*!< mutex                  */
+#endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    int initial_entropy_run;
+#endif
+}
+mbedtls_entropy_context;
+
+/**
+ * \brief           Initialize the context
+ *
+ * \param ctx       Entropy context to initialize
+ */
+void mbedtls_entropy_init( mbedtls_entropy_context *ctx );
+
+/**
+ * \brief           Free the data in the context
+ *
+ * \param ctx       Entropy context to free
+ */
+void mbedtls_entropy_free( mbedtls_entropy_context *ctx );
+
+/**
+ * \brief           Adds an entropy source to poll
+ *                  (Thread-safe if MBEDTLS_THREADING_C is enabled)
+ *
+ * \param ctx       Entropy context
+ * \param f_source  Entropy function
+ * \param p_source  Function data
+ * \param threshold Minimum required from source before entropy is released
+ *                  ( with mbedtls_entropy_func() ) (in bytes)
+ * \param strong    MBEDTLS_ENTROPY_SOURCE_STRONG or
+ *                  MBEDTLS_ENTROPY_SOURCE_WEAK.
+ *                  At least one strong source needs to be added.
+ *                  Weaker sources (such as the cycle counter) can be used as
+ *                  a complement.
+ *
+ * \return          0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES
+ */
+int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
+                        mbedtls_entropy_f_source_ptr f_source, void *p_source,
+                        size_t threshold, int strong );
+
+/**
+ * \brief           Trigger an extra gather poll for the accumulator
+ *                  (Thread-safe if MBEDTLS_THREADING_C is enabled)
+ *
+ * \param ctx       Entropy context
+ *
+ * \return          0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+ */
+int mbedtls_entropy_gather( mbedtls_entropy_context *ctx );
+
+/**
+ * \brief           Retrieve entropy from the accumulator
+ *                  (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE)
+ *                  (Thread-safe if MBEDTLS_THREADING_C is enabled)
+ *
+ * \param data      Entropy context
+ * \param output    Buffer to fill
+ * \param len       Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE
+ *
+ * \return          0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+ */
+int mbedtls_entropy_func( void *data, unsigned char *output, size_t len );
+
+/**
+ * \brief           Add data to the accumulator manually
+ *                  (Thread-safe if MBEDTLS_THREADING_C is enabled)
+ *
+ * \param ctx       Entropy context
+ * \param data      Data to add
+ * \param len       Length of data
+ *
+ * \return          0 if successful
+ */
+int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
+                           const unsigned char *data, size_t len );
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+/**
+ * \brief           Trigger an update of the seed file in NV by using the
+ *                  current entropy pool.
+ *
+ * \param ctx       Entropy context
+ *
+ * \return          0 if successful
+ */
+int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx );
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief               Write a seed file
+ *
+ * \param ctx           Entropy context
+ * \param path          Name of the file
+ *
+ * \return              0 if successful,
+ *                      MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or
+ *                      MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+ */
+int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path );
+
+/**
+ * \brief               Read and update a seed file. Seed is added to this
+ *                      instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are
+ *                      read from the seed file. The rest is ignored.
+ *
+ * \param ctx           Entropy context
+ * \param path          Name of the file
+ *
+ * \return              0 if successful,
+ *                      MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error,
+ *                      MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
+ */
+int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path );
+#endif /* MBEDTLS_FS_IO */
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief          Checkup routine
+ *
+ *                 This module self-test also calls the entropy self-test,
+ *                 mbedtls_entropy_source_self_test();
+ *
+ * \return         0 if successful, or 1 if a test failed
+ */
+int mbedtls_entropy_self_test( int verbose );
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+/**
+ * \brief          Checkup routine
+ *
+ *                 Verifies the integrity of the hardware entropy source
+ *                 provided by the function 'mbedtls_hardware_poll()'.
+ *
+ *                 Note this is the only hardware entropy source that is known
+ *                 at link time, and other entropy sources configured
+ *                 dynamically at runtime by the function
+ *                 mbedtls_entropy_add_source() will not be tested.
+ *
+ * \return         0 if successful, or 1 if a test failed
+ */
+int mbedtls_entropy_source_self_test( int verbose );
+#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* entropy.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/entropy_poll.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/entropy_poll.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/entropy_poll.h	(revision 398)
@@ -0,0 +1,110 @@
+/**
+ * \file entropy_poll.h
+ *
+ * \brief Platform-specific and custom entropy polling functions
+ */
+/*
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_ENTROPY_POLL_H
+#define MBEDTLS_ENTROPY_POLL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Default thresholds for built-in sources, in bytes
+ */
+#define MBEDTLS_ENTROPY_MIN_PLATFORM     32     /**< Minimum for platform source    */
+#define MBEDTLS_ENTROPY_MIN_HAVEGE       32     /**< Minimum for HAVEGE             */
+#define MBEDTLS_ENTROPY_MIN_HARDCLOCK     4     /**< Minimum for mbedtls_timing_hardclock()        */
+#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE)
+#define MBEDTLS_ENTROPY_MIN_HARDWARE     32     /**< Minimum for the hardware source */
+#endif
+
+/**
+ * \brief           Entropy poll callback that provides 0 entropy.
+ */
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+    int mbedtls_null_entropy_poll( void *data,
+                                unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
+/**
+ * \brief           Platform-specific entropy poll callback
+ */
+int mbedtls_platform_entropy_poll( void *data,
+                           unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#if defined(MBEDTLS_HAVEGE_C)
+/**
+ * \brief           HAVEGE based entropy poll callback
+ *
+ * Requires an HAVEGE state as its data pointer.
+ */
+int mbedtls_havege_poll( void *data,
+                 unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#if defined(MBEDTLS_TIMING_C)
+/**
+ * \brief           mbedtls_timing_hardclock-based entropy poll callback
+ */
+int mbedtls_hardclock_poll( void *data,
+                    unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+/**
+ * \brief           Entropy poll callback for a hardware source
+ *
+ * \warning         This is not provided by mbed TLS!
+ *                  See \c MBEDTLS_ENTROPY_HARDWARE_ALT in config.h.
+ *
+ * \note            This must accept NULL as its first argument.
+ */
+int mbedtls_hardware_poll( void *data,
+                           unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+/**
+ * \brief           Entropy poll callback for a non-volatile seed file
+ *
+ * \note            This must accept NULL as its first argument.
+ */
+int mbedtls_nv_seed_poll( void *data,
+                          unsigned char *output, size_t len, size_t *olen );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* entropy_poll.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/error.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/error.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/error.h	(revision 398)
@@ -0,0 +1,129 @@
+/**
+ * \file error.h
+ *
+ * \brief Error to string translation
+ */
+/*
+ *  Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_ERROR_H
+#define MBEDTLS_ERROR_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+/**
+ * Error code layout.
+ *
+ * Currently we try to keep all error codes within the negative space of 16
+ * bits signed integers to support all platforms (-0x0001 - -0x7FFF). In
+ * addition we'd like to give two layers of information on the error if
+ * possible.
+ *
+ * For that purpose the error codes are segmented in the following manner:
+ *
+ * 16 bit error code bit-segmentation
+ *
+ * 1 bit  - Unused (sign bit)
+ * 3 bits - High level module ID
+ * 5 bits - Module-dependent error code
+ * 7 bits - Low level module errors
+ *
+ * For historical reasons, low-level error codes are divided in even and odd,
+ * even codes were assigned first, and -1 is reserved for other errors.
+ *
+ * Low-level module errors (0x0002-0x007E, 0x0003-0x007F)
+ *
+ * Module   Nr  Codes assigned
+ * MPI       7  0x0002-0x0010
+ * GCM       3  0x0012-0x0014   0x0013-0x0013
+ * BLOWFISH  3  0x0016-0x0018   0x0017-0x0017
+ * THREADING 3  0x001A-0x001E
+ * AES       5  0x0020-0x0022   0x0021-0x0025
+ * CAMELLIA  3  0x0024-0x0026   0x0027-0x0027
+ * XTEA      2  0x0028-0x0028   0x0029-0x0029
+ * BASE64    2  0x002A-0x002C
+ * OID       1  0x002E-0x002E   0x000B-0x000B
+ * PADLOCK   1  0x0030-0x0030
+ * DES       2  0x0032-0x0032   0x0033-0x0033
+ * CTR_DBRG  4  0x0034-0x003A
+ * ENTROPY   3  0x003C-0x0040   0x003D-0x003F
+ * NET      13  0x0042-0x0052   0x0043-0x0049
+ * ARIA      4  0x0058-0x005E
+ * ASN1      7  0x0060-0x006C
+ * CMAC      1  0x007A-0x007A
+ * PBKDF2    1  0x007C-0x007C
+ * HMAC_DRBG 4                  0x0003-0x0009
+ * CCM       3                  0x000D-0x0011
+ * ARC4      1                  0x0019-0x0019
+ * MD2       1                  0x002B-0x002B
+ * MD4       1                  0x002D-0x002D
+ * MD5       1                  0x002F-0x002F
+ * RIPEMD160 1                  0x0031-0x0031
+ * SHA1      1                  0x0035-0x0035 0x0073-0x0073
+ * SHA256    1                  0x0037-0x0037 0x0074-0x0074
+ * SHA512    1                  0x0039-0x0039 0x0075-0x0075
+ * CHACHA20  3                  0x0051-0x0055
+ * POLY1305  3                  0x0057-0x005B
+ * CHACHAPOLY 2 0x0054-0x0056
+ * PLATFORM  1  0x0070-0x0072
+ *
+ * High-level module nr (3 bits - 0x0...-0x7...)
+ * Name      ID  Nr of Errors
+ * PEM       1   9
+ * PKCS#12   1   4 (Started from top)
+ * X509      2   20
+ * PKCS5     2   4 (Started from top)
+ * DHM       3   11
+ * PK        3   15 (Started from top)
+ * RSA       4   11
+ * ECP       4   10 (Started from top)
+ * MD        5   5
+ * HKDF      5   1 (Started from top)
+ * CIPHER    6   8
+ * SSL       6   23 (Started from top)
+ * SSL       7   32
+ *
+ * Module dependent error code (5 bits 0x.00.-0x.F8.)
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Translate a mbed TLS error code into a string representation,
+ *        Result is truncated if necessary and always includes a terminating
+ *        null byte.
+ *
+ * \param errnum    error code
+ * \param buffer    buffer to place representation in
+ * \param buflen    length of the buffer
+ */
+void mbedtls_strerror( int errnum, char *buffer, size_t buflen );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* error.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/gcm.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/gcm.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/gcm.h	(revision 398)
@@ -0,0 +1,326 @@
+/**
+ * \file gcm.h
+ *
+ * \brief This file contains GCM definitions and functions.
+ *
+ * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined
+ * in <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
+ * (GCM), Natl. Inst. Stand. Technol.</em>
+ *
+ * For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
+ * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
+ *
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_GCM_H
+#define MBEDTLS_GCM_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "cipher.h"
+
+#include <stdint.h>
+
+#define MBEDTLS_GCM_ENCRYPT     1
+#define MBEDTLS_GCM_DECRYPT     0
+
+#define MBEDTLS_ERR_GCM_AUTH_FAILED                       -0x0012  /**< Authenticated decryption failed. */
+
+/* MBEDTLS_ERR_GCM_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_GCM_HW_ACCEL_FAILED                   -0x0013  /**< GCM hardware accelerator failed. */
+
+#define MBEDTLS_ERR_GCM_BAD_INPUT                         -0x0014  /**< Bad input parameters to function. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_GCM_ALT)
+
+/**
+ * \brief          The GCM context structure.
+ */
+typedef struct mbedtls_gcm_context
+{
+    mbedtls_cipher_context_t cipher_ctx;  /*!< The cipher context used. */
+    uint64_t HL[16];                      /*!< Precalculated HTable low. */
+    uint64_t HH[16];                      /*!< Precalculated HTable high. */
+    uint64_t len;                         /*!< The total length of the encrypted data. */
+    uint64_t add_len;                     /*!< The total length of the additional data. */
+    unsigned char base_ectr[16];          /*!< The first ECTR for tag. */
+    unsigned char y[16];                  /*!< The Y working value. */
+    unsigned char buf[16];                /*!< The buf working value. */
+    int mode;                             /*!< The operation to perform:
+                                               #MBEDTLS_GCM_ENCRYPT or
+                                               #MBEDTLS_GCM_DECRYPT. */
+}
+mbedtls_gcm_context;
+
+#else  /* !MBEDTLS_GCM_ALT */
+#include "gcm_alt.h"
+#endif /* !MBEDTLS_GCM_ALT */
+
+/**
+ * \brief           This function initializes the specified GCM context,
+ *                  to make references valid, and prepares the context
+ *                  for mbedtls_gcm_setkey() or mbedtls_gcm_free().
+ *
+ *                  The function does not bind the GCM context to a particular
+ *                  cipher, nor set the key. For this purpose, use
+ *                  mbedtls_gcm_setkey().
+ *
+ * \param ctx       The GCM context to initialize. This must not be \c NULL.
+ */
+void mbedtls_gcm_init( mbedtls_gcm_context *ctx );
+
+/**
+ * \brief           This function associates a GCM context with a
+ *                  cipher algorithm and a key.
+ *
+ * \param ctx       The GCM context. This must be initialized.
+ * \param cipher    The 128-bit block cipher to use.
+ * \param key       The encryption key. This must be a readable buffer of at
+ *                  least \p keybits bits.
+ * \param keybits   The key size in bits. Valid options are:
+ *                  <ul><li>128 bits</li>
+ *                  <li>192 bits</li>
+ *                  <li>256 bits</li></ul>
+ *
+ * \return          \c 0 on success.
+ * \return          A cipher-specific error code on failure.
+ */
+int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
+                        mbedtls_cipher_id_t cipher,
+                        const unsigned char *key,
+                        unsigned int keybits );
+
+/**
+ * \brief           This function performs GCM encryption or decryption of a buffer.
+ *
+ * \note            For encryption, the output buffer can be the same as the
+ *                  input buffer. For decryption, the output buffer cannot be
+ *                  the same as input buffer. If the buffers overlap, the output
+ *                  buffer must trail at least 8 Bytes behind the input buffer.
+ *
+ * \warning         When this function performs a decryption, it outputs the
+ *                  authentication tag and does not verify that the data is
+ *                  authentic. You should use this function to perform encryption
+ *                  only. For decryption, use mbedtls_gcm_auth_decrypt() instead.
+ *
+ * \param ctx       The GCM context to use for encryption or decryption. This
+ *                  must be initialized.
+ * \param mode      The operation to perform:
+ *                  - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption.
+ *                    The ciphertext is written to \p output and the
+ *                    authentication tag is written to \p tag.
+ *                  - #MBEDTLS_GCM_DECRYPT to perform decryption.
+ *                    The plaintext is written to \p output and the
+ *                    authentication tag is written to \p tag.
+ *                    Note that this mode is not recommended, because it does
+ *                    not verify the authenticity of the data. For this reason,
+ *                    you should use mbedtls_gcm_auth_decrypt() instead of
+ *                    calling this function in decryption mode.
+ * \param length    The length of the input data, which is equal to the length
+ *                  of the output data.
+ * \param iv        The initialization vector. This must be a readable buffer of
+ *                  at least \p iv_len Bytes.
+ * \param iv_len    The length of the IV.
+ * \param add       The buffer holding the additional data. This must be of at
+ *                  least that size in Bytes.
+ * \param add_len   The length of the additional data.
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, this must be a readable buffer of at least that
+ *                  size in Bytes.
+ * \param output    The buffer for holding the output data. If \p length is greater
+ *                  than zero, this must be a writable buffer of at least that
+ *                  size in Bytes.
+ * \param tag_len   The length of the tag to generate.
+ * \param tag       The buffer for holding the tag. This must be a readable
+ *                  buffer of at least \p tag_len Bytes.
+ *
+ * \return          \c 0 if the encryption or decryption was performed
+ *                  successfully. Note that in #MBEDTLS_GCM_DECRYPT mode,
+ *                  this does not indicate that the data is authentic.
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
+ *                  not valid or a cipher-specific error code if the encryption
+ *                  or decryption failed.
+ */
+int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
+                       int mode,
+                       size_t length,
+                       const unsigned char *iv,
+                       size_t iv_len,
+                       const unsigned char *add,
+                       size_t add_len,
+                       const unsigned char *input,
+                       unsigned char *output,
+                       size_t tag_len,
+                       unsigned char *tag );
+
+/**
+ * \brief           This function performs a GCM authenticated decryption of a
+ *                  buffer.
+ *
+ * \note            For decryption, the output buffer cannot be the same as
+ *                  input buffer. If the buffers overlap, the output buffer
+ *                  must trail at least 8 Bytes behind the input buffer.
+ *
+ * \param ctx       The GCM context. This must be initialized.
+ * \param length    The length of the ciphertext to decrypt, which is also
+ *                  the length of the decrypted plaintext.
+ * \param iv        The initialization vector. This must be a readable buffer
+ *                  of at least \p iv_len Bytes.
+ * \param iv_len    The length of the IV.
+ * \param add       The buffer holding the additional data. This must be of at
+ *                  least that size in Bytes.
+ * \param add_len   The length of the additional data.
+ * \param tag       The buffer holding the tag to verify. This must be a
+ *                  readable buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the tag to verify.
+ * \param input     The buffer holding the ciphertext. If \p length is greater
+ *                  than zero, this must be a readable buffer of at least that
+ *                  size.
+ * \param output    The buffer for holding the decrypted plaintext. If \p length
+ *                  is greater than zero, this must be a writable buffer of at
+ *                  least that size.
+ *
+ * \return          \c 0 if successful and authenticated.
+ * \return          #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match.
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are
+ *                  not valid or a cipher-specific error code if the decryption
+ *                  failed.
+ */
+int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
+                      size_t length,
+                      const unsigned char *iv,
+                      size_t iv_len,
+                      const unsigned char *add,
+                      size_t add_len,
+                      const unsigned char *tag,
+                      size_t tag_len,
+                      const unsigned char *input,
+                      unsigned char *output );
+
+/**
+ * \brief           This function starts a GCM encryption or decryption
+ *                  operation.
+ *
+ * \param ctx       The GCM context. This must be initialized.
+ * \param mode      The operation to perform: #MBEDTLS_GCM_ENCRYPT or
+ *                  #MBEDTLS_GCM_DECRYPT.
+ * \param iv        The initialization vector. This must be a readable buffer of
+ *                  at least \p iv_len Bytes.
+ * \param iv_len    The length of the IV.
+ * \param add       The buffer holding the additional data, or \c NULL
+ *                  if \p add_len is \c 0.
+ * \param add_len   The length of the additional data. If \c 0,
+ *                  \p add may be \c NULL.
+ *
+ * \return          \c 0 on success.
+ */
+int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
+                int mode,
+                const unsigned char *iv,
+                size_t iv_len,
+                const unsigned char *add,
+                size_t add_len );
+
+/**
+ * \brief           This function feeds an input buffer into an ongoing GCM
+ *                  encryption or decryption operation.
+ *
+ *    `             The function expects input to be a multiple of 16
+ *                  Bytes. Only the last call before calling
+ *                  mbedtls_gcm_finish() can be less than 16 Bytes.
+ *
+ * \note            For decryption, the output buffer cannot be the same as
+ *                  input buffer. If the buffers overlap, the output buffer
+ *                  must trail at least 8 Bytes behind the input buffer.
+ *
+ * \param ctx       The GCM context. This must be initialized.
+ * \param length    The length of the input data. This must be a multiple of
+ *                  16 except in the last call before mbedtls_gcm_finish().
+ * \param input     The buffer holding the input data. If \p length is greater
+ *                  than zero, this must be a readable buffer of at least that
+ *                  size in Bytes.
+ * \param output    The buffer for holding the output data. If \p length is
+ *                  greater than zero, this must be a writable buffer of at
+ *                  least that size in Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
+ */
+int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
+                size_t length,
+                const unsigned char *input,
+                unsigned char *output );
+
+/**
+ * \brief           This function finishes the GCM operation and generates
+ *                  the authentication tag.
+ *
+ *                  It wraps up the GCM stream, and generates the
+ *                  tag. The tag can have a maximum length of 16 Bytes.
+ *
+ * \param ctx       The GCM context. This must be initialized.
+ * \param tag       The buffer for holding the tag. This must be a readable
+ *                  buffer of at least \p tag_len Bytes.
+ * \param tag_len   The length of the tag to generate. This must be at least
+ *                  four.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_GCM_BAD_INPUT on failure.
+ */
+int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
+                unsigned char *tag,
+                size_t tag_len );
+
+/**
+ * \brief           This function clears a GCM context and the underlying
+ *                  cipher sub-context.
+ *
+ * \param ctx       The GCM context to clear. If this is \c NULL, the call has
+ *                  no effect. Otherwise, this must be initialized.
+ */
+void mbedtls_gcm_free( mbedtls_gcm_context *ctx );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          The GCM checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_gcm_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* gcm.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/havege.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/havege.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/havege.h	(revision 398)
@@ -0,0 +1,81 @@
+/**
+ * \file havege.h
+ *
+ * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_HAVEGE_H
+#define MBEDTLS_HAVEGE_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+#define MBEDTLS_HAVEGE_COLLECT_SIZE 1024
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          HAVEGE state structure
+ */
+typedef struct mbedtls_havege_state
+{
+    int PT1, PT2, offset[2];
+    int pool[MBEDTLS_HAVEGE_COLLECT_SIZE];
+    int WALK[8192];
+}
+mbedtls_havege_state;
+
+/**
+ * \brief          HAVEGE initialization
+ *
+ * \param hs       HAVEGE state to be initialized
+ */
+void mbedtls_havege_init( mbedtls_havege_state *hs );
+
+/**
+ * \brief          Clear HAVEGE state
+ *
+ * \param hs       HAVEGE state to be cleared
+ */
+void mbedtls_havege_free( mbedtls_havege_state *hs );
+
+/**
+ * \brief          HAVEGE rand function
+ *
+ * \param p_rng    A HAVEGE state
+ * \param output   Buffer to fill
+ * \param len      Length of buffer
+ *
+ * \return         0
+ */
+int mbedtls_havege_random( void *p_rng, unsigned char *output, size_t len );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* havege.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/hkdf.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/hkdf.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/hkdf.h	(revision 398)
@@ -0,0 +1,141 @@
+/**
+ * \file hkdf.h
+ *
+ * \brief   This file contains the HKDF interface.
+ *
+ *          The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is
+ *          specified by RFC 5869.
+ */
+/*
+ * Copyright (C) 2016-2018, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_HKDF_H
+#define MBEDTLS_HKDF_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "md.h"
+
+/**
+ *  \name HKDF Error codes
+ *  \{
+ */
+#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA  -0x5F80  /**< Bad input parameters to function. */
+/* \} name */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ *  \brief  This is the HMAC-based Extract-and-Expand Key Derivation Function
+ *          (HKDF).
+ *
+ *  \param  md        A hash function; md.size denotes the length of the hash
+ *                    function output in bytes.
+ *  \param  salt      An optional salt value (a non-secret random value);
+ *                    if the salt is not provided, a string of all zeros of
+ *                    md.size length is used as the salt.
+ *  \param  salt_len  The length in bytes of the optional \p salt.
+ *  \param  ikm       The input keying material.
+ *  \param  ikm_len   The length in bytes of \p ikm.
+ *  \param  info      An optional context and application specific information
+ *                    string. This can be a zero-length string.
+ *  \param  info_len  The length of \p info in bytes.
+ *  \param  okm       The output keying material of \p okm_len bytes.
+ *  \param  okm_len   The length of the output keying material in bytes. This
+ *                    must be less than or equal to 255 * md.size bytes.
+ *
+ *  \return 0 on success.
+ *  \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
+ *  \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
+ *          MD layer.
+ */
+int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
+                  size_t salt_len, const unsigned char *ikm, size_t ikm_len,
+                  const unsigned char *info, size_t info_len,
+                  unsigned char *okm, size_t okm_len );
+
+/**
+ *  \brief  Take the input keying material \p ikm and extract from it a
+ *          fixed-length pseudorandom key \p prk.
+ *
+ *  \warning    This function should only be used if the security of it has been
+ *              studied and established in that particular context (eg. TLS 1.3
+ *              key schedule). For standard HKDF security guarantees use
+ *              \c mbedtls_hkdf instead.
+ *
+ *  \param       md        A hash function; md.size denotes the length of the
+ *                         hash function output in bytes.
+ *  \param       salt      An optional salt value (a non-secret random value);
+ *                         if the salt is not provided, a string of all zeros
+ *                         of md.size length is used as the salt.
+ *  \param       salt_len  The length in bytes of the optional \p salt.
+ *  \param       ikm       The input keying material.
+ *  \param       ikm_len   The length in bytes of \p ikm.
+ *  \param[out]  prk       A pseudorandom key of at least md.size bytes.
+ *
+ *  \return 0 on success.
+ *  \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
+ *  \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
+ *          MD layer.
+ */
+int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
+                          const unsigned char *salt, size_t salt_len,
+                          const unsigned char *ikm, size_t ikm_len,
+                          unsigned char *prk );
+
+/**
+ *  \brief  Expand the supplied \p prk into several additional pseudorandom
+ *          keys, which is the output of the HKDF.
+ *
+ *  \warning    This function should only be used if the security of it has been
+ *              studied and established in that particular context (eg. TLS 1.3
+ *              key schedule). For standard HKDF security guarantees use
+ *              \c mbedtls_hkdf instead.
+ *
+ *  \param  md        A hash function; md.size denotes the length of the hash
+ *                    function output in bytes.
+ *  \param  prk       A pseudorandom key of at least md.size bytes. \p prk is
+ *                    usually the output from the HKDF extract step.
+ *  \param  prk_len   The length in bytes of \p prk.
+ *  \param  info      An optional context and application specific information
+ *                    string. This can be a zero-length string.
+ *  \param  info_len  The length of \p info in bytes.
+ *  \param  okm       The output keying material of \p okm_len bytes.
+ *  \param  okm_len   The length of the output keying material in bytes. This
+ *                    must be less than or equal to 255 * md.size bytes.
+ *
+ *  \return 0 on success.
+ *  \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid.
+ *  \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying
+ *          MD layer.
+ */
+int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
+                         size_t prk_len, const unsigned char *info,
+                         size_t info_len, unsigned char *okm, size_t okm_len );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* hkdf.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/hmac_drbg.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/hmac_drbg.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/hmac_drbg.h	(revision 398)
@@ -0,0 +1,334 @@
+/**
+ * \file hmac_drbg.h
+ *
+ * \brief HMAC_DRBG (NIST SP 800-90A)
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_HMAC_DRBG_H
+#define MBEDTLS_HMAC_DRBG_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "md.h"
+
+#if defined(MBEDTLS_THREADING_C)
+#include "threading.h"
+#endif
+
+/*
+ * Error codes
+ */
+#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG              -0x0003  /**< Too many random requested in single call. */
+#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG                -0x0005  /**< Input too large (Entropy + additional). */
+#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR                -0x0007  /**< Read/write error in file. */
+#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED        -0x0009  /**< The entropy source failed. */
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
+#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL   10000   /**< Interval before reseed is performed by default */
+#endif
+
+#if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT)
+#define MBEDTLS_HMAC_DRBG_MAX_INPUT         256     /**< Maximum number of additional input bytes */
+#endif
+
+#if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST)
+#define MBEDTLS_HMAC_DRBG_MAX_REQUEST       1024    /**< Maximum number of requested bytes per call */
+#endif
+
+#if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT)
+#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT    384     /**< Maximum size of (re)seed buffer */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#define MBEDTLS_HMAC_DRBG_PR_OFF   0   /**< No prediction resistance       */
+#define MBEDTLS_HMAC_DRBG_PR_ON    1   /**< Prediction resistance enabled  */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * HMAC_DRBG context.
+ */
+typedef struct mbedtls_hmac_drbg_context
+{
+    /* Working state: the key K is not stored explicitely,
+     * but is implied by the HMAC context */
+    mbedtls_md_context_t md_ctx;                    /*!< HMAC context (inc. K)  */
+    unsigned char V[MBEDTLS_MD_MAX_SIZE];  /*!< V in the spec          */
+    int reseed_counter;                     /*!< reseed counter         */
+
+    /* Administrative state */
+    size_t entropy_len;         /*!< entropy bytes grabbed on each (re)seed */
+    int prediction_resistance;  /*!< enable prediction resistance (Automatic
+                                     reseed before every random generation) */
+    int reseed_interval;        /*!< reseed interval   */
+
+    /* Callbacks */
+    int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */
+    void *p_entropy;            /*!< context for the entropy function        */
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+#endif
+} mbedtls_hmac_drbg_context;
+
+/**
+ * \brief               HMAC_DRBG context initialization
+ *                      Makes the context ready for mbedtls_hmac_drbg_seed(),
+ *                      mbedtls_hmac_drbg_seed_buf() or
+ *                      mbedtls_hmac_drbg_free().
+ *
+ * \param ctx           HMAC_DRBG context to be initialized
+ */
+void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
+
+/**
+ * \brief               HMAC_DRBG initial seeding
+ *                      Seed and setup entropy source for future reseeds.
+ *
+ * \param ctx           HMAC_DRBG context to be seeded
+ * \param md_info       MD algorithm to use for HMAC_DRBG
+ * \param f_entropy     Entropy callback (p_entropy, buffer to fill, buffer
+ *                      length)
+ * \param p_entropy     Entropy context
+ * \param custom        Personalization data (Device specific identifiers)
+ *                      (Can be NULL)
+ * \param len           Length of personalization data
+ *
+ * \note                The "security strength" as defined by NIST is set to:
+ *                      128 bits if md_alg is SHA-1,
+ *                      192 bits if md_alg is SHA-224,
+ *                      256 bits if md_alg is SHA-256 or higher.
+ *                      Note that SHA-256 is just as efficient as SHA-224.
+ *
+ * \return              0 if successful, or
+ *                      MBEDTLS_ERR_MD_BAD_INPUT_DATA, or
+ *                      MBEDTLS_ERR_MD_ALLOC_FAILED, or
+ *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED.
+ */
+int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
+                    const mbedtls_md_info_t * md_info,
+                    int (*f_entropy)(void *, unsigned char *, size_t),
+                    void *p_entropy,
+                    const unsigned char *custom,
+                    size_t len );
+
+/**
+ * \brief               Initilisation of simpified HMAC_DRBG (never reseeds).
+ *                      (For use with deterministic ECDSA.)
+ *
+ * \param ctx           HMAC_DRBG context to be initialised
+ * \param md_info       MD algorithm to use for HMAC_DRBG
+ * \param data          Concatenation of entropy string and additional data
+ * \param data_len      Length of data in bytes
+ *
+ * \return              0 if successful, or
+ *                      MBEDTLS_ERR_MD_BAD_INPUT_DATA, or
+ *                      MBEDTLS_ERR_MD_ALLOC_FAILED.
+ */
+int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
+                        const mbedtls_md_info_t * md_info,
+                        const unsigned char *data, size_t data_len );
+
+/**
+ * \brief               Enable / disable prediction resistance (Default: Off)
+ *
+ * Note: If enabled, entropy is used for ctx->entropy_len before each call!
+ *       Only use this if you have ample supply of good entropy!
+ *
+ * \param ctx           HMAC_DRBG context
+ * \param resistance    MBEDTLS_HMAC_DRBG_PR_ON or MBEDTLS_HMAC_DRBG_PR_OFF
+ */
+void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
+                                          int resistance );
+
+/**
+ * \brief               Set the amount of entropy grabbed on each reseed
+ *                      (Default: given by the security strength, which
+ *                      depends on the hash used, see \c mbedtls_hmac_drbg_init() )
+ *
+ * \param ctx           HMAC_DRBG context
+ * \param len           Amount of entropy to grab, in bytes
+ */
+void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
+                                size_t len );
+
+/**
+ * \brief               Set the reseed interval
+ *                      (Default: MBEDTLS_HMAC_DRBG_RESEED_INTERVAL)
+ *
+ * \param ctx           HMAC_DRBG context
+ * \param interval      Reseed interval
+ */
+void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
+                                    int interval );
+
+/**
+ * \brief               HMAC_DRBG update state
+ *
+ * \param ctx           HMAC_DRBG context
+ * \param additional    Additional data to update state with, or NULL
+ * \param add_len       Length of additional data, or 0
+ *
+ * \return              \c 0 on success, or an error from the underlying
+ *                      hash calculation.
+ *
+ * \note                Additional data is optional, pass NULL and 0 as second
+ *                      third argument if no additional data is being used.
+ */
+int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
+                       const unsigned char *additional, size_t add_len );
+
+/**
+ * \brief               HMAC_DRBG reseeding (extracts data from entropy source)
+ *
+ * \param ctx           HMAC_DRBG context
+ * \param additional    Additional data to add to state (Can be NULL)
+ * \param len           Length of additional data
+ *
+ * \return              0 if successful, or
+ *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ */
+int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
+                      const unsigned char *additional, size_t len );
+
+/**
+ * \brief               HMAC_DRBG generate random with additional update input
+ *
+ * Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
+ *
+ * \param p_rng         HMAC_DRBG context
+ * \param output        Buffer to fill
+ * \param output_len    Length of the buffer
+ * \param additional    Additional data to update with (can be NULL)
+ * \param add_len       Length of additional data (can be 0)
+ *
+ * \return              0 if successful, or
+ *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
+ *                      MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or
+ *                      MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG.
+ */
+int mbedtls_hmac_drbg_random_with_add( void *p_rng,
+                               unsigned char *output, size_t output_len,
+                               const unsigned char *additional,
+                               size_t add_len );
+
+/**
+ * \brief               HMAC_DRBG generate random
+ *
+ * Note: Automatically reseeds if reseed_counter is reached or PR is enabled.
+ *
+ * \param p_rng         HMAC_DRBG context
+ * \param output        Buffer to fill
+ * \param out_len       Length of the buffer
+ *
+ * \return              0 if successful, or
+ *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or
+ *                      MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG
+ */
+int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len );
+
+/**
+ * \brief               Free an HMAC_DRBG context
+ *
+ * \param ctx           HMAC_DRBG context to free.
+ */
+void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx );
+
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief               HMAC_DRBG update state
+ *
+ * \deprecated          Superseded by mbedtls_hmac_drbg_update_ret()
+ *                      in 2.16.0.
+ *
+ * \param ctx           HMAC_DRBG context
+ * \param additional    Additional data to update state with, or NULL
+ * \param add_len       Length of additional data, or 0
+ *
+ * \note                Additional data is optional, pass NULL and 0 as second
+ *                      third argument if no additional data is being used.
+ */
+MBEDTLS_DEPRECATED void mbedtls_hmac_drbg_update(
+    mbedtls_hmac_drbg_context *ctx,
+    const unsigned char *additional, size_t add_len );
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief               Write a seed file
+ *
+ * \param ctx           HMAC_DRBG context
+ * \param path          Name of the file
+ *
+ * \return              0 if successful, 1 on file error, or
+ *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED
+ */
+int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
+
+/**
+ * \brief               Read and update a seed file. Seed is added to this
+ *                      instance
+ *
+ * \param ctx           HMAC_DRBG context
+ * \param path          Name of the file
+ *
+ * \return              0 if successful, 1 on file error,
+ *                      MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or
+ *                      MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG
+ */
+int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path );
+#endif /* MBEDTLS_FS_IO */
+
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief               Checkup routine
+ *
+ * \return              0 if successful, or 1 if the test failed
+ */
+int mbedtls_hmac_drbg_self_test( int verbose );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* hmac_drbg.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md.h	(revision 398)
@@ -0,0 +1,468 @@
+ /**
+ * \file md.h
+ *
+ * \brief This file contains the generic message-digest wrapper.
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_MD_H
+#define MBEDTLS_MD_H
+
+#include <stddef.h>
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE                -0x5080  /**< The selected feature is not available. */
+#define MBEDTLS_ERR_MD_BAD_INPUT_DATA                     -0x5100  /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_MD_ALLOC_FAILED                       -0x5180  /**< Failed to allocate memory. */
+#define MBEDTLS_ERR_MD_FILE_IO_ERROR                      -0x5200  /**< Opening or reading of file failed. */
+
+/* MBEDTLS_ERR_MD_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_MD_HW_ACCEL_FAILED                    -0x5280  /**< MD hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief     Supported message digests.
+ *
+ * \warning   MD2, MD4, MD5 and SHA-1 are considered weak message digests and
+ *            their use constitutes a security risk. We recommend considering
+ *            stronger message digests instead.
+ *
+ */
+typedef enum {
+    MBEDTLS_MD_NONE=0,    /**< None. */
+    MBEDTLS_MD_MD2,       /**< The MD2 message digest. */
+    MBEDTLS_MD_MD4,       /**< The MD4 message digest. */
+    MBEDTLS_MD_MD5,       /**< The MD5 message digest. */
+    MBEDTLS_MD_SHA1,      /**< The SHA-1 message digest. */
+    MBEDTLS_MD_SHA224,    /**< The SHA-224 message digest. */
+    MBEDTLS_MD_SHA256,    /**< The SHA-256 message digest. */
+    MBEDTLS_MD_SHA384,    /**< The SHA-384 message digest. */
+    MBEDTLS_MD_SHA512,    /**< The SHA-512 message digest. */
+    MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */
+} mbedtls_md_type_t;
+
+#if defined(MBEDTLS_SHA512_C)
+#define MBEDTLS_MD_MAX_SIZE         64  /* longest known is SHA512 */
+#else
+#define MBEDTLS_MD_MAX_SIZE         32  /* longest known is SHA256 or less */
+#endif
+
+/**
+ * Opaque struct defined in md_internal.h.
+ */
+typedef struct mbedtls_md_info_t mbedtls_md_info_t;
+
+/**
+ * The generic message-digest context.
+ */
+typedef struct mbedtls_md_context_t
+{
+    /** Information about the associated message digest. */
+    const mbedtls_md_info_t *md_info;
+
+    /** The digest-specific context. */
+    void *md_ctx;
+
+    /** The HMAC part of the context. */
+    void *hmac_ctx;
+} mbedtls_md_context_t;
+
+/**
+ * \brief           This function returns the list of digests supported by the
+ *                  generic digest module.
+ *
+ * \return          A statically allocated array of digests. Each element
+ *                  in the returned list is an integer belonging to the
+ *                  message-digest enumeration #mbedtls_md_type_t.
+ *                  The last entry is 0.
+ */
+const int *mbedtls_md_list( void );
+
+/**
+ * \brief           This function returns the message-digest information
+ *                  associated with the given digest name.
+ *
+ * \param md_name   The name of the digest to search for.
+ *
+ * \return          The message-digest information associated with \p md_name.
+ * \return          NULL if the associated message-digest information is not found.
+ */
+const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name );
+
+/**
+ * \brief           This function returns the message-digest information
+ *                  associated with the given digest type.
+ *
+ * \param md_type   The type of digest to search for.
+ *
+ * \return          The message-digest information associated with \p md_type.
+ * \return          NULL if the associated message-digest information is not found.
+ */
+const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type );
+
+/**
+ * \brief           This function initializes a message-digest context without
+ *                  binding it to a particular message-digest algorithm.
+ *
+ *                  This function should always be called first. It prepares the
+ *                  context for mbedtls_md_setup() for binding it to a
+ *                  message-digest algorithm.
+ */
+void mbedtls_md_init( mbedtls_md_context_t *ctx );
+
+/**
+ * \brief           This function clears the internal structure of \p ctx and
+ *                  frees any embedded internal structure, but does not free
+ *                  \p ctx itself.
+ *
+ *                  If you have called mbedtls_md_setup() on \p ctx, you must
+ *                  call mbedtls_md_free() when you are no longer using the
+ *                  context.
+ *                  Calling this function if you have previously
+ *                  called mbedtls_md_init() and nothing else is optional.
+ *                  You must not call this function if you have not called
+ *                  mbedtls_md_init().
+ */
+void mbedtls_md_free( mbedtls_md_context_t *ctx );
+
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief           This function selects the message digest algorithm to use,
+ *                  and allocates internal structures.
+ *
+ *                  It should be called after mbedtls_md_init() or mbedtls_md_free().
+ *                  Makes it necessary to call mbedtls_md_free() later.
+ *
+ * \deprecated      Superseded by mbedtls_md_setup() in 2.0.0
+ *
+ * \param ctx       The context to set up.
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ * \return          #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
+ */
+int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) MBEDTLS_DEPRECATED;
+#undef MBEDTLS_DEPRECATED
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief           This function selects the message digest algorithm to use,
+ *                  and allocates internal structures.
+ *
+ *                  It should be called after mbedtls_md_init() or
+ *                  mbedtls_md_free(). Makes it necessary to call
+ *                  mbedtls_md_free() later.
+ *
+ * \param ctx       The context to set up.
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
+ * \param hmac      Defines if HMAC is used. 0: HMAC is not used (saves some memory),
+ *                  or non-zero: HMAC is used with this context.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ * \return          #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
+ */
+int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
+
+/**
+ * \brief           This function clones the state of an message-digest
+ *                  context.
+ *
+ * \note            You must call mbedtls_md_setup() on \c dst before calling
+ *                  this function.
+ *
+ * \note            The two contexts must have the same type,
+ *                  for example, both are SHA-256.
+ *
+ * \warning         This function clones the message-digest state, not the
+ *                  HMAC state.
+ *
+ * \param dst       The destination context.
+ * \param src       The context to be cloned.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
+ */
+int mbedtls_md_clone( mbedtls_md_context_t *dst,
+                      const mbedtls_md_context_t *src );
+
+/**
+ * \brief           This function extracts the message-digest size from the
+ *                  message-digest information structure.
+ *
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
+ *
+ * \return          The size of the message-digest output in Bytes.
+ */
+unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info );
+
+/**
+ * \brief           This function extracts the message-digest type from the
+ *                  message-digest information structure.
+ *
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
+ *
+ * \return          The type of the message digest.
+ */
+mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info );
+
+/**
+ * \brief           This function extracts the message-digest name from the
+ *                  message-digest information structure.
+ *
+ * \param md_info   The information structure of the message-digest algorithm
+ *                  to use.
+ *
+ * \return          The name of the message digest.
+ */
+const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
+
+/**
+ * \brief           This function starts a message-digest computation.
+ *
+ *                  You must call this function after setting up the context
+ *                  with mbedtls_md_setup(), and before passing data with
+ *                  mbedtls_md_update().
+ *
+ * \param ctx       The generic message-digest context.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ */
+int mbedtls_md_starts( mbedtls_md_context_t *ctx );
+
+/**
+ * \brief           This function feeds an input buffer into an ongoing
+ *                  message-digest computation.
+ *
+ *                  You must call mbedtls_md_starts() before calling this
+ *                  function. You may call this function multiple times.
+ *                  Afterwards, call mbedtls_md_finish().
+ *
+ * \param ctx       The generic message-digest context.
+ * \param input     The buffer holding the input data.
+ * \param ilen      The length of the input data.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ */
+int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
+
+/**
+ * \brief           This function finishes the digest operation,
+ *                  and writes the result to the output buffer.
+ *
+ *                  Call this function after a call to mbedtls_md_starts(),
+ *                  followed by any number of calls to mbedtls_md_update().
+ *                  Afterwards, you may either clear the context with
+ *                  mbedtls_md_free(), or call mbedtls_md_starts() to reuse
+ *                  the context for another digest operation with the same
+ *                  algorithm.
+ *
+ * \param ctx       The generic message-digest context.
+ * \param output    The buffer for the generic message-digest checksum result.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ */
+int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
+
+/**
+ * \brief          This function calculates the message-digest of a buffer,
+ *                 with respect to a configurable message-digest algorithm
+ *                 in a single call.
+ *
+ *                 The result is calculated as
+ *                 Output = message_digest(input buffer).
+ *
+ * \param md_info  The information structure of the message-digest algorithm
+ *                 to use.
+ * \param input    The buffer holding the data.
+ * \param ilen     The length of the input data.
+ * \param output   The generic message-digest checksum result.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                 failure.
+ */
+int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
+        unsigned char *output );
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief          This function calculates the message-digest checksum
+ *                 result of the contents of the provided file.
+ *
+ *                 The result is calculated as
+ *                 Output = message_digest(file contents).
+ *
+ * \param md_info  The information structure of the message-digest algorithm
+ *                 to use.
+ * \param path     The input file name.
+ * \param output   The generic message-digest checksum result.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing
+ *                 the file pointed by \p path.
+ * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
+ */
+int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
+                     unsigned char *output );
+#endif /* MBEDTLS_FS_IO */
+
+/**
+ * \brief           This function sets the HMAC key and prepares to
+ *                  authenticate a new message.
+ *
+ *                  Call this function after mbedtls_md_setup(), to use
+ *                  the MD context for an HMAC calculation, then call
+ *                  mbedtls_md_hmac_update() to provide the input data, and
+ *                  mbedtls_md_hmac_finish() to get the HMAC value.
+ *
+ * \param ctx       The message digest context containing an embedded HMAC
+ *                  context.
+ * \param key       The HMAC secret key.
+ * \param keylen    The length of the HMAC key in Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ */
+int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
+                    size_t keylen );
+
+/**
+ * \brief           This function feeds an input buffer into an ongoing HMAC
+ *                  computation.
+ *
+ *                  Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset()
+ *                  before calling this function.
+ *                  You may call this function multiple times to pass the
+ *                  input piecewise.
+ *                  Afterwards, call mbedtls_md_hmac_finish().
+ *
+ * \param ctx       The message digest context containing an embedded HMAC
+ *                  context.
+ * \param input     The buffer holding the input data.
+ * \param ilen      The length of the input data.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ */
+int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
+                    size_t ilen );
+
+/**
+ * \brief           This function finishes the HMAC operation, and writes
+ *                  the result to the output buffer.
+ *
+ *                  Call this function after mbedtls_md_hmac_starts() and
+ *                  mbedtls_md_hmac_update() to get the HMAC value. Afterwards
+ *                  you may either call mbedtls_md_free() to clear the context,
+ *                  or call mbedtls_md_hmac_reset() to reuse the context with
+ *                  the same HMAC key.
+ *
+ * \param ctx       The message digest context containing an embedded HMAC
+ *                  context.
+ * \param output    The generic HMAC checksum result.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ */
+int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
+
+/**
+ * \brief           This function prepares to authenticate a new message with
+ *                  the same key as the previous HMAC operation.
+ *
+ *                  You may call this function after mbedtls_md_hmac_finish().
+ *                  Afterwards call mbedtls_md_hmac_update() to pass the new
+ *                  input.
+ *
+ * \param ctx       The message digest context containing an embedded HMAC
+ *                  context.
+ *
+ * \return          \c 0 on success.
+ * \return          #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                  failure.
+ */
+int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
+
+/**
+ * \brief          This function calculates the full generic HMAC
+ *                 on the input buffer with the provided key.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The HMAC result is calculated as
+ *                 output = generic HMAC(hmac key, input buffer).
+ *
+ * \param md_info  The information structure of the message-digest algorithm
+ *                 to use.
+ * \param key      The HMAC secret key.
+ * \param keylen   The length of the HMAC secret key in Bytes.
+ * \param input    The buffer holding the input data.
+ * \param ilen     The length of the input data.
+ * \param output   The generic HMAC result.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
+ *                 failure.
+ */
+int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
+                const unsigned char *input, size_t ilen,
+                unsigned char *output );
+
+/* Internal use */
+int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_MD_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md2.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md2.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md2.h	(revision 398)
@@ -0,0 +1,306 @@
+/**
+ * \file md2.h
+ *
+ * \brief MD2 message digest algorithm (hash function)
+ *
+ * \warning MD2 is considered a weak message digest and its use constitutes a
+ *          security risk. We recommend considering stronger message digests
+ *          instead.
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
+ */
+#ifndef MBEDTLS_MD2_H
+#define MBEDTLS_MD2_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+/* MBEDTLS_ERR_MD2_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_MD2_HW_ACCEL_FAILED                   -0x002B  /**< MD2 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_MD2_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          MD2 context structure
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+typedef struct mbedtls_md2_context
+{
+    unsigned char cksum[16];    /*!< checksum of the data block */
+    unsigned char state[48];    /*!< intermediate digest state  */
+    unsigned char buffer[16];   /*!< data block being processed */
+    size_t left;                /*!< amount of data in buffer   */
+}
+mbedtls_md2_context;
+
+#else  /* MBEDTLS_MD2_ALT */
+#include "md2_alt.h"
+#endif /* MBEDTLS_MD2_ALT */
+
+/**
+ * \brief          Initialize MD2 context
+ *
+ * \param ctx      MD2 context to be initialized
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+void mbedtls_md2_init( mbedtls_md2_context *ctx );
+
+/**
+ * \brief          Clear MD2 context
+ *
+ * \param ctx      MD2 context to be cleared
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+void mbedtls_md2_free( mbedtls_md2_context *ctx );
+
+/**
+ * \brief          Clone (the state of) an MD2 context
+ *
+ * \param dst      The destination context
+ * \param src      The context to be cloned
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+void mbedtls_md2_clone( mbedtls_md2_context *dst,
+                        const mbedtls_md2_context *src );
+
+/**
+ * \brief          MD2 context setup
+ *
+ * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx );
+
+/**
+ * \brief          MD2 process buffer
+ *
+ * \param ctx      MD2 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen );
+
+/**
+ * \brief          MD2 final digest
+ *
+ * \param ctx      MD2 context
+ * \param output   MD2 checksum result
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
+                            unsigned char output[16] );
+
+/**
+ * \brief          MD2 process data block (internal use only)
+ *
+ * \param ctx      MD2 context
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_internal_md2_process( mbedtls_md2_context *ctx );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          MD2 context setup
+ *
+ * \deprecated     Superseded by mbedtls_md2_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md2_starts( mbedtls_md2_context *ctx );
+
+/**
+ * \brief          MD2 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_md2_update_ret() in 2.7.0
+ *
+ * \param ctx      MD2 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md2_update( mbedtls_md2_context *ctx,
+                                            const unsigned char *input,
+                                            size_t ilen );
+
+/**
+ * \brief          MD2 final digest
+ *
+ * \deprecated     Superseded by mbedtls_md2_finish_ret() in 2.7.0
+ *
+ * \param ctx      MD2 context
+ * \param output   MD2 checksum result
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md2_finish( mbedtls_md2_context *ctx,
+                                            unsigned char output[16] );
+
+/**
+ * \brief          MD2 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_md2_process() in 2.7.0
+ *
+ * \param ctx      MD2 context
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md2_process( mbedtls_md2_context *ctx );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          Output = MD2( input buffer )
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   MD2 checksum result
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md2_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          Output = MD2( input buffer )
+ *
+ * \deprecated     Superseded by mbedtls_md2_ret() in 2.7.0
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   MD2 checksum result
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input,
+                                     size_t ilen,
+                                     unsigned char output[16] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ *
+ * \warning        MD2 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md2_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_md2.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md4.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md4.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md4.h	(revision 398)
@@ -0,0 +1,311 @@
+/**
+ * \file md4.h
+ *
+ * \brief MD4 message digest algorithm (hash function)
+ *
+ * \warning MD4 is considered a weak message digest and its use constitutes a
+ *          security risk. We recommend considering stronger message digests
+ *          instead.
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
+ */
+#ifndef MBEDTLS_MD4_H
+#define MBEDTLS_MD4_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* MBEDTLS_ERR_MD4_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_MD4_HW_ACCEL_FAILED                   -0x002D  /**< MD4 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_MD4_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          MD4 context structure
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+typedef struct mbedtls_md4_context
+{
+    uint32_t total[2];          /*!< number of bytes processed  */
+    uint32_t state[4];          /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+}
+mbedtls_md4_context;
+
+#else  /* MBEDTLS_MD4_ALT */
+#include "md4_alt.h"
+#endif /* MBEDTLS_MD4_ALT */
+
+/**
+ * \brief          Initialize MD4 context
+ *
+ * \param ctx      MD4 context to be initialized
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+void mbedtls_md4_init( mbedtls_md4_context *ctx );
+
+/**
+ * \brief          Clear MD4 context
+ *
+ * \param ctx      MD4 context to be cleared
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+void mbedtls_md4_free( mbedtls_md4_context *ctx );
+
+/**
+ * \brief          Clone (the state of) an MD4 context
+ *
+ * \param dst      The destination context
+ * \param src      The context to be cloned
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+void mbedtls_md4_clone( mbedtls_md4_context *dst,
+                        const mbedtls_md4_context *src );
+
+/**
+ * \brief          MD4 context setup
+ *
+ * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ */
+int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx );
+
+/**
+ * \brief          MD4 process buffer
+ *
+ * \param ctx      MD4 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen );
+
+/**
+ * \brief          MD4 final digest
+ *
+ * \param ctx      MD4 context
+ * \param output   MD4 checksum result
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
+                            unsigned char output[16] );
+
+/**
+ * \brief          MD4 process data block (internal use only)
+ *
+ * \param ctx      MD4 context
+ * \param data     buffer holding one block of data
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
+                                  const unsigned char data[64] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          MD4 context setup
+ *
+ * \deprecated     Superseded by mbedtls_md4_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md4_starts( mbedtls_md4_context *ctx );
+
+/**
+ * \brief          MD4 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_md4_update_ret() in 2.7.0
+ *
+ * \param ctx      MD4 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md4_update( mbedtls_md4_context *ctx,
+                                            const unsigned char *input,
+                                            size_t ilen );
+
+/**
+ * \brief          MD4 final digest
+ *
+ * \deprecated     Superseded by mbedtls_md4_finish_ret() in 2.7.0
+ *
+ * \param ctx      MD4 context
+ * \param output   MD4 checksum result
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md4_finish( mbedtls_md4_context *ctx,
+                                            unsigned char output[16] );
+
+/**
+ * \brief          MD4 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_md4_process() in 2.7.0
+ *
+ * \param ctx      MD4 context
+ * \param data     buffer holding one block of data
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md4_process( mbedtls_md4_context *ctx,
+                                             const unsigned char data[64] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          Output = MD4( input buffer )
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   MD4 checksum result
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md4_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          Output = MD4( input buffer )
+ *
+ * \deprecated     Superseded by mbedtls_md4_ret() in 2.7.0
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   MD4 checksum result
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input,
+                                     size_t ilen,
+                                     unsigned char output[16] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ *
+ * \warning        MD4 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md4_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_md4.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md5.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md5.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md5.h	(revision 398)
@@ -0,0 +1,311 @@
+/**
+ * \file md5.h
+ *
+ * \brief MD5 message digest algorithm (hash function)
+ *
+ * \warning   MD5 is considered a weak message digest and its use constitutes a
+ *            security risk. We recommend considering stronger message
+ *            digests instead.
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_MD5_H
+#define MBEDTLS_MD5_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* MBEDTLS_ERR_MD5_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_MD5_HW_ACCEL_FAILED                   -0x002F  /**< MD5 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_MD5_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          MD5 context structure
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+typedef struct mbedtls_md5_context
+{
+    uint32_t total[2];          /*!< number of bytes processed  */
+    uint32_t state[4];          /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+}
+mbedtls_md5_context;
+
+#else  /* MBEDTLS_MD5_ALT */
+#include "md5_alt.h"
+#endif /* MBEDTLS_MD5_ALT */
+
+/**
+ * \brief          Initialize MD5 context
+ *
+ * \param ctx      MD5 context to be initialized
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+void mbedtls_md5_init( mbedtls_md5_context *ctx );
+
+/**
+ * \brief          Clear MD5 context
+ *
+ * \param ctx      MD5 context to be cleared
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+void mbedtls_md5_free( mbedtls_md5_context *ctx );
+
+/**
+ * \brief          Clone (the state of) an MD5 context
+ *
+ * \param dst      The destination context
+ * \param src      The context to be cloned
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+void mbedtls_md5_clone( mbedtls_md5_context *dst,
+                        const mbedtls_md5_context *src );
+
+/**
+ * \brief          MD5 context setup
+ *
+ * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx );
+
+/**
+ * \brief          MD5 process buffer
+ *
+ * \param ctx      MD5 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen );
+
+/**
+ * \brief          MD5 final digest
+ *
+ * \param ctx      MD5 context
+ * \param output   MD5 checksum result
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
+                            unsigned char output[16] );
+
+/**
+ * \brief          MD5 process data block (internal use only)
+ *
+ * \param ctx      MD5 context
+ * \param data     buffer holding one block of data
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
+                                  const unsigned char data[64] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          MD5 context setup
+ *
+ * \deprecated     Superseded by mbedtls_md5_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md5_starts( mbedtls_md5_context *ctx );
+
+/**
+ * \brief          MD5 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_md5_update_ret() in 2.7.0
+ *
+ * \param ctx      MD5 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md5_update( mbedtls_md5_context *ctx,
+                                            const unsigned char *input,
+                                            size_t ilen );
+
+/**
+ * \brief          MD5 final digest
+ *
+ * \deprecated     Superseded by mbedtls_md5_finish_ret() in 2.7.0
+ *
+ * \param ctx      MD5 context
+ * \param output   MD5 checksum result
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md5_finish( mbedtls_md5_context *ctx,
+                                            unsigned char output[16] );
+
+/**
+ * \brief          MD5 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_md5_process() in 2.7.0
+ *
+ * \param ctx      MD5 context
+ * \param data     buffer holding one block of data
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md5_process( mbedtls_md5_context *ctx,
+                                             const unsigned char data[64] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          Output = MD5( input buffer )
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   MD5 checksum result
+ *
+ * \return         0 if successful
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md5_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          Output = MD5( input buffer )
+ *
+ * \deprecated     Superseded by mbedtls_md5_ret() in 2.7.0
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   MD5 checksum result
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input,
+                                     size_t ilen,
+                                     unsigned char output[16] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ *
+ * \warning        MD5 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+int mbedtls_md5_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_md5.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md_internal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md_internal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/md_internal.h	(revision 398)
@@ -0,0 +1,115 @@
+/**
+ * \file md_internal.h
+ *
+ * \brief Message digest wrappers.
+ *
+ * \warning This in an internal header. Do not include directly.
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_MD_WRAP_H
+#define MBEDTLS_MD_WRAP_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "md.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Message digest information.
+ * Allows message digest functions to be called in a generic way.
+ */
+struct mbedtls_md_info_t
+{
+    /** Digest identifier */
+    mbedtls_md_type_t type;
+
+    /** Name of the message digest */
+    const char * name;
+
+    /** Output length of the digest function in bytes */
+    int size;
+
+    /** Block length of the digest function in bytes */
+    int block_size;
+
+    /** Digest initialisation function */
+    int (*starts_func)( void *ctx );
+
+    /** Digest update function */
+    int (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
+
+    /** Digest finalisation function */
+    int (*finish_func)( void *ctx, unsigned char *output );
+
+    /** Generic digest function */
+    int (*digest_func)( const unsigned char *input, size_t ilen,
+                        unsigned char *output );
+
+    /** Allocate a new context */
+    void * (*ctx_alloc_func)( void );
+
+    /** Free the given context */
+    void (*ctx_free_func)( void *ctx );
+
+    /** Clone state from a context */
+    void (*clone_func)( void *dst, const void *src );
+
+    /** Internal use only */
+    int (*process_func)( void *ctx, const unsigned char *input );
+};
+
+#if defined(MBEDTLS_MD2_C)
+extern const mbedtls_md_info_t mbedtls_md2_info;
+#endif
+#if defined(MBEDTLS_MD4_C)
+extern const mbedtls_md_info_t mbedtls_md4_info;
+#endif
+#if defined(MBEDTLS_MD5_C)
+extern const mbedtls_md_info_t mbedtls_md5_info;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+extern const mbedtls_md_info_t mbedtls_ripemd160_info;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+extern const mbedtls_md_info_t mbedtls_sha1_info;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+extern const mbedtls_md_info_t mbedtls_sha224_info;
+extern const mbedtls_md_info_t mbedtls_sha256_info;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+extern const mbedtls_md_info_t mbedtls_sha384_info;
+extern const mbedtls_md_info_t mbedtls_sha512_info;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_MD_WRAP_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/memory_buffer_alloc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/memory_buffer_alloc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/memory_buffer_alloc.h	(revision 398)
@@ -0,0 +1,151 @@
+/**
+ * \file memory_buffer_alloc.h
+ *
+ * \brief Buffer-based memory allocator
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H
+#define MBEDTLS_MEMORY_BUFFER_ALLOC_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_MEMORY_ALIGN_MULTIPLE)
+#define MBEDTLS_MEMORY_ALIGN_MULTIPLE       4 /**< Align on multiples of this value */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#define MBEDTLS_MEMORY_VERIFY_NONE         0
+#define MBEDTLS_MEMORY_VERIFY_ALLOC        (1 << 0)
+#define MBEDTLS_MEMORY_VERIFY_FREE         (1 << 1)
+#define MBEDTLS_MEMORY_VERIFY_ALWAYS       (MBEDTLS_MEMORY_VERIFY_ALLOC | MBEDTLS_MEMORY_VERIFY_FREE)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief   Initialize use of stack-based memory allocator.
+ *          The stack-based allocator does memory management inside the
+ *          presented buffer and does not call calloc() and free().
+ *          It sets the global mbedtls_calloc() and mbedtls_free() pointers
+ *          to its own functions.
+ *          (Provided mbedtls_calloc() and mbedtls_free() are thread-safe if
+ *           MBEDTLS_THREADING_C is defined)
+ *
+ * \note    This code is not optimized and provides a straight-forward
+ *          implementation of a stack-based memory allocator.
+ *
+ * \param buf   buffer to use as heap
+ * \param len   size of the buffer
+ */
+void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len );
+
+/**
+ * \brief   Free the mutex for thread-safety and clear remaining memory
+ */
+void mbedtls_memory_buffer_alloc_free( void );
+
+/**
+ * \brief   Determine when the allocator should automatically verify the state
+ *          of the entire chain of headers / meta-data.
+ *          (Default: MBEDTLS_MEMORY_VERIFY_NONE)
+ *
+ * \param verify    One of MBEDTLS_MEMORY_VERIFY_NONE, MBEDTLS_MEMORY_VERIFY_ALLOC,
+ *                  MBEDTLS_MEMORY_VERIFY_FREE or MBEDTLS_MEMORY_VERIFY_ALWAYS
+ */
+void mbedtls_memory_buffer_set_verify( int verify );
+
+#if defined(MBEDTLS_MEMORY_DEBUG)
+/**
+ * \brief   Print out the status of the allocated memory (primarily for use
+ *          after a program should have de-allocated all memory)
+ *          Prints out a list of 'still allocated' blocks and their stack
+ *          trace if MBEDTLS_MEMORY_BACKTRACE is defined.
+ */
+void mbedtls_memory_buffer_alloc_status( void );
+
+/**
+ * \brief   Get the peak heap usage so far
+ *
+ * \param max_used      Peak number of bytes in use or committed. This
+ *                      includes bytes in allocated blocks too small to split
+ *                      into smaller blocks but larger than the requested size.
+ * \param max_blocks    Peak number of blocks in use, including free and used
+ */
+void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks );
+
+/**
+ * \brief   Reset peak statistics
+ */
+void mbedtls_memory_buffer_alloc_max_reset( void );
+
+/**
+ * \brief   Get the current heap usage
+ *
+ * \param cur_used      Current number of bytes in use or committed. This
+ *                      includes bytes in allocated blocks too small to split
+ *                      into smaller blocks but larger than the requested size.
+ * \param cur_blocks    Current number of blocks in use, including free and used
+ */
+void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks );
+#endif /* MBEDTLS_MEMORY_DEBUG */
+
+/**
+ * \brief   Verifies that all headers in the memory buffer are correct
+ *          and contain sane values. Helps debug buffer-overflow errors.
+ *
+ *          Prints out first failure if MBEDTLS_MEMORY_DEBUG is defined.
+ *          Prints out full header information if MBEDTLS_MEMORY_DEBUG
+ *          is defined. (Includes stack trace information for each block if
+ *          MBEDTLS_MEMORY_BACKTRACE is defined as well).
+ *
+ * \return             0 if verified, 1 otherwise
+ */
+int mbedtls_memory_buffer_alloc_verify( void );
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if a test failed
+ */
+int mbedtls_memory_buffer_alloc_self_test( int verbose );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* memory_buffer_alloc.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/net.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/net.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/net.h	(revision 398)
@@ -0,0 +1,37 @@
+/**
+ * \file net.h
+ *
+ * \brief Deprecated header file that includes net_sockets.h
+ *
+ * \deprecated Superseded by mbedtls/net_sockets.h
+ */
+/*
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#include "net_sockets.h"
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h"
+#endif /* MBEDTLS_DEPRECATED_WARNING */
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/net_sockets.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/net_sockets.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/net_sockets.h	(revision 398)
@@ -0,0 +1,271 @@
+/**
+ * \file net_sockets.h
+ *
+ * \brief   Network sockets abstraction layer to integrate Mbed TLS into a
+ *          BSD-style sockets API.
+ *
+ *          The network sockets module provides an example integration of the
+ *          Mbed TLS library into a BSD sockets implementation. The module is
+ *          intended to be an example of how Mbed TLS can be integrated into a
+ *          networking stack, as well as to be Mbed TLS's network integration
+ *          for its supported platforms.
+ *
+ *          The module is intended only to be used with the Mbed TLS library and
+ *          is not intended to be used by third party application software
+ *          directly.
+ *
+ *          The supported platforms are as follows:
+ *              * Microsoft Windows and Windows CE
+ *              * POSIX/Unix platforms including Linux, OS X
+ *
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_NET_SOCKETS_H
+#define MBEDTLS_NET_SOCKETS_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "ssl.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDTLS_ERR_NET_SOCKET_FAILED                     -0x0042  /**< Failed to open a socket. */
+#define MBEDTLS_ERR_NET_CONNECT_FAILED                    -0x0044  /**< The connection to the given server / port failed. */
+#define MBEDTLS_ERR_NET_BIND_FAILED                       -0x0046  /**< Binding of the socket failed. */
+#define MBEDTLS_ERR_NET_LISTEN_FAILED                     -0x0048  /**< Could not listen on the socket. */
+#define MBEDTLS_ERR_NET_ACCEPT_FAILED                     -0x004A  /**< Could not accept the incoming connection. */
+#define MBEDTLS_ERR_NET_RECV_FAILED                       -0x004C  /**< Reading information from the socket failed. */
+#define MBEDTLS_ERR_NET_SEND_FAILED                       -0x004E  /**< Sending information through the socket failed. */
+#define MBEDTLS_ERR_NET_CONN_RESET                        -0x0050  /**< Connection was reset by peer. */
+#define MBEDTLS_ERR_NET_UNKNOWN_HOST                      -0x0052  /**< Failed to get an IP address for the given hostname. */
+#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL                  -0x0043  /**< Buffer is too small to hold the data. */
+#define MBEDTLS_ERR_NET_INVALID_CONTEXT                   -0x0045  /**< The context is invalid, eg because it was free()ed. */
+#define MBEDTLS_ERR_NET_POLL_FAILED                       -0x0047  /**< Polling the net context failed. */
+#define MBEDTLS_ERR_NET_BAD_INPUT_DATA                    -0x0049  /**< Input invalid. */
+
+#define MBEDTLS_NET_LISTEN_BACKLOG         10 /**< The backlog that listen() should use. */
+
+#define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */
+#define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */
+
+#define MBEDTLS_NET_POLL_READ  1 /**< Used in \c mbedtls_net_poll to check for pending data  */
+#define MBEDTLS_NET_POLL_WRITE 2 /**< Used in \c mbedtls_net_poll to check if write possible */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Wrapper type for sockets.
+ *
+ * Currently backed by just a file descriptor, but might be more in the future
+ * (eg two file descriptors for combined IPv4 + IPv6 support, or additional
+ * structures for hand-made UDP demultiplexing).
+ */
+typedef struct mbedtls_net_context
+{
+    int fd;             /**< The underlying file descriptor                 */
+}
+mbedtls_net_context;
+
+/**
+ * \brief          Initialize a context
+ *                 Just makes the context ready to be used or freed safely.
+ *
+ * \param ctx      Context to initialize
+ */
+void mbedtls_net_init( mbedtls_net_context *ctx );
+
+/**
+ * \brief          Initiate a connection with host:port in the given protocol
+ *
+ * \param ctx      Socket to use
+ * \param host     Host to connect to
+ * \param port     Port to connect to
+ * \param proto    Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP
+ *
+ * \return         0 if successful, or one of:
+ *                      MBEDTLS_ERR_NET_SOCKET_FAILED,
+ *                      MBEDTLS_ERR_NET_UNKNOWN_HOST,
+ *                      MBEDTLS_ERR_NET_CONNECT_FAILED
+ *
+ * \note           Sets the socket in connected mode even with UDP.
+ */
+int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto );
+
+/**
+ * \brief          Create a receiving socket on bind_ip:port in the chosen
+ *                 protocol. If bind_ip == NULL, all interfaces are bound.
+ *
+ * \param ctx      Socket to use
+ * \param bind_ip  IP to bind to, can be NULL
+ * \param port     Port number to use
+ * \param proto    Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP
+ *
+ * \return         0 if successful, or one of:
+ *                      MBEDTLS_ERR_NET_SOCKET_FAILED,
+ *                      MBEDTLS_ERR_NET_BIND_FAILED,
+ *                      MBEDTLS_ERR_NET_LISTEN_FAILED
+ *
+ * \note           Regardless of the protocol, opens the sockets and binds it.
+ *                 In addition, make the socket listening if protocol is TCP.
+ */
+int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto );
+
+/**
+ * \brief           Accept a connection from a remote client
+ *
+ * \param bind_ctx  Relevant socket
+ * \param client_ctx Will contain the connected client socket
+ * \param client_ip Will contain the client IP address, can be NULL
+ * \param buf_size  Size of the client_ip buffer
+ * \param ip_len    Will receive the size of the client IP written,
+ *                  can be NULL if client_ip is null
+ *
+ * \return          0 if successful, or
+ *                  MBEDTLS_ERR_NET_ACCEPT_FAILED, or
+ *                  MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small,
+ *                  MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to
+ *                  non-blocking and accept() would block.
+ */
+int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
+                        mbedtls_net_context *client_ctx,
+                        void *client_ip, size_t buf_size, size_t *ip_len );
+
+/**
+ * \brief          Check and wait for the context to be ready for read/write
+ *
+ * \param ctx      Socket to check
+ * \param rw       Bitflag composed of MBEDTLS_NET_POLL_READ and
+ *                 MBEDTLS_NET_POLL_WRITE specifying the events
+ *                 to wait for:
+ *                 - If MBEDTLS_NET_POLL_READ is set, the function
+ *                   will return as soon as the net context is available
+ *                   for reading.
+ *                 - If MBEDTLS_NET_POLL_WRITE is set, the function
+ *                   will return as soon as the net context is available
+ *                   for writing.
+ * \param timeout  Maximal amount of time to wait before returning,
+ *                 in milliseconds. If \c timeout is zero, the
+ *                 function returns immediately. If \c timeout is
+ *                 -1u, the function blocks potentially indefinitely.
+ *
+ * \return         Bitmask composed of MBEDTLS_NET_POLL_READ/WRITE
+ *                 on success or timeout, or a negative return code otherwise.
+ */
+int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout );
+
+/**
+ * \brief          Set the socket blocking
+ *
+ * \param ctx      Socket to set
+ *
+ * \return         0 if successful, or a non-zero error code
+ */
+int mbedtls_net_set_block( mbedtls_net_context *ctx );
+
+/**
+ * \brief          Set the socket non-blocking
+ *
+ * \param ctx      Socket to set
+ *
+ * \return         0 if successful, or a non-zero error code
+ */
+int mbedtls_net_set_nonblock( mbedtls_net_context *ctx );
+
+/**
+ * \brief          Portable usleep helper
+ *
+ * \param usec     Amount of microseconds to sleep
+ *
+ * \note           Real amount of time slept will not be less than
+ *                 select()'s timeout granularity (typically, 10ms).
+ */
+void mbedtls_net_usleep( unsigned long usec );
+
+/**
+ * \brief          Read at most 'len' characters. If no error occurs,
+ *                 the actual amount read is returned.
+ *
+ * \param ctx      Socket
+ * \param buf      The buffer to write to
+ * \param len      Maximum length of the buffer
+ *
+ * \return         the number of bytes received,
+ *                 or a non-zero error code; with a non-blocking socket,
+ *                 MBEDTLS_ERR_SSL_WANT_READ indicates read() would block.
+ */
+int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len );
+
+/**
+ * \brief          Write at most 'len' characters. If no error occurs,
+ *                 the actual amount read is returned.
+ *
+ * \param ctx      Socket
+ * \param buf      The buffer to read from
+ * \param len      The length of the buffer
+ *
+ * \return         the number of bytes sent,
+ *                 or a non-zero error code; with a non-blocking socket,
+ *                 MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block.
+ */
+int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len );
+
+/**
+ * \brief          Read at most 'len' characters, blocking for at most
+ *                 'timeout' seconds. If no error occurs, the actual amount
+ *                 read is returned.
+ *
+ * \param ctx      Socket
+ * \param buf      The buffer to write to
+ * \param len      Maximum length of the buffer
+ * \param timeout  Maximum number of milliseconds to wait for data
+ *                 0 means no timeout (wait forever)
+ *
+ * \return         the number of bytes received,
+ *                 or a non-zero error code:
+ *                 MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
+ *                 MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
+ *
+ * \note           This function will block (until data becomes available or
+ *                 timeout is reached) even if the socket is set to
+ *                 non-blocking. Handling timeouts with non-blocking reads
+ *                 requires a different strategy.
+ */
+int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
+                      uint32_t timeout );
+
+/**
+ * \brief          Gracefully shutdown the connection and free associated data
+ *
+ * \param ctx      The context to free
+ */
+void mbedtls_net_free( mbedtls_net_context *ctx );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* net_sockets.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/nist_kw.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/nist_kw.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/nist_kw.h	(revision 398)
@@ -0,0 +1,184 @@
+/**
+ * \file nist_kw.h
+ *
+ * \brief This file provides an API for key wrapping (KW) and key wrapping with
+ *        padding (KWP) as defined in NIST SP 800-38F.
+ *        https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
+ *
+ *        Key wrapping specifies a deterministic authenticated-encryption mode
+ *        of operation, according to <em>NIST SP 800-38F: Recommendation for
+ *        Block Cipher Modes of Operation: Methods for Key Wrapping</em>. Its
+ *        purpose is to protect cryptographic keys.
+ *
+ *        Its equivalent is RFC 3394 for KW, and RFC 5649 for KWP.
+ *        https://tools.ietf.org/html/rfc3394
+ *        https://tools.ietf.org/html/rfc5649
+ *
+ */
+/*
+ *  Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_NIST_KW_H
+#define MBEDTLS_NIST_KW_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "cipher.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+    MBEDTLS_KW_MODE_KW = 0,
+    MBEDTLS_KW_MODE_KWP = 1
+} mbedtls_nist_kw_mode_t;
+
+#if !defined(MBEDTLS_NIST_KW_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief    The key wrapping context-type definition. The key wrapping context is passed
+ *           to the APIs called.
+ *
+ * \note     The definition of this type may change in future library versions.
+ *           Don't make any assumptions on this context!
+ */
+typedef struct {
+    mbedtls_cipher_context_t cipher_ctx;    /*!< The cipher context used. */
+} mbedtls_nist_kw_context;
+
+#else  /* MBEDTLS_NIST_key wrapping_ALT */
+#include "nist_kw_alt.h"
+#endif /* MBEDTLS_NIST_KW_ALT */
+
+/**
+ * \brief           This function initializes the specified key wrapping context
+ *                  to make references valid and prepare the context
+ *                  for mbedtls_nist_kw_setkey() or mbedtls_nist_kw_free().
+ *
+ * \param ctx       The key wrapping context to initialize.
+ *
+ */
+void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx );
+
+/**
+ * \brief           This function initializes the key wrapping context set in the
+ *                  \p ctx parameter and sets the encryption key.
+ *
+ * \param ctx       The key wrapping context.
+ * \param cipher    The 128-bit block cipher to use. Only AES is supported.
+ * \param key       The Key Encryption Key (KEK).
+ * \param keybits   The KEK size in bits. This must be acceptable by the cipher.
+ * \param is_wrap   Specify whether the operation within the context is wrapping or unwrapping
+ *
+ * \return          \c 0 on success.
+ * \return          \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for any invalid input.
+ * \return          \c MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE for 128-bit block ciphers
+ *                  which are not supported.
+ * \return          cipher-specific error code on failure of the underlying cipher.
+ */
+int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx,
+                            mbedtls_cipher_id_t cipher,
+                            const unsigned char *key,
+                            unsigned int keybits,
+                            const int is_wrap );
+
+/**
+ * \brief   This function releases and clears the specified key wrapping context
+ *          and underlying cipher sub-context.
+ *
+ * \param ctx       The key wrapping context to clear.
+ */
+void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx );
+
+/**
+ * \brief           This function encrypts a buffer using key wrapping.
+ *
+ * \param ctx       The key wrapping context to use for encryption.
+ * \param mode      The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP)
+ * \param input     The buffer holding the input data.
+ * \param in_len    The length of the input data in Bytes.
+ *                  The input uses units of 8 Bytes called semiblocks.
+ *                  <ul><li>For KW mode: a multiple of 8 bytes between 16 and 2^57-8 inclusive. </li>
+ *                  <li>For KWP mode: any length between 1 and 2^32-1 inclusive.</li></ul>
+ * \param[out] output    The buffer holding the output data.
+ *                  <ul><li>For KW mode: Must be at least 8 bytes larger than \p in_len.</li>
+ *                  <li>For KWP mode: Must be at least 8 bytes larger rounded up to a multiple of
+ *                  8 bytes for KWP (15 bytes at most).</li></ul>
+ * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure.
+ * \param[in] out_size The capacity of the output buffer.
+ *
+ * \return          \c 0 on success.
+ * \return          \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length.
+ * \return          cipher-specific error code on failure of the underlying cipher.
+ */
+int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode,
+                          const unsigned char *input, size_t in_len,
+                          unsigned char *output, size_t* out_len, size_t out_size );
+
+/**
+ * \brief           This function decrypts a buffer using key wrapping.
+ *
+ * \param ctx       The key wrapping context to use for decryption.
+ * \param mode      The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP)
+ * \param input     The buffer holding the input data.
+ * \param in_len    The length of the input data in Bytes.
+ *                  The input uses units of 8 Bytes called semiblocks.
+ *                  The input must be a multiple of semiblocks.
+ *                  <ul><li>For KW mode: a multiple of 8 bytes between 24 and 2^57 inclusive. </li>
+ *                  <li>For KWP mode: a multiple of 8 bytes between 16 and 2^32 inclusive.</li></ul>
+ * \param[out] output    The buffer holding the output data.
+ *                  The output buffer's minimal length is 8 bytes shorter than \p in_len.
+ * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure.
+ *                  For KWP mode, the length could be up to 15 bytes shorter than \p in_len,
+ *                  depending on how much padding was added to the data.
+ * \param[in] out_size The capacity of the output buffer.
+ *
+ * \return          \c 0 on success.
+ * \return          \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length.
+ * \return          \c MBEDTLS_ERR_CIPHER_AUTH_FAILED for verification failure of the ciphertext.
+ * \return          cipher-specific error code on failure of the underlying cipher.
+ */
+int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode,
+                            const unsigned char *input, size_t in_len,
+                            unsigned char *output, size_t* out_len, size_t out_size);
+
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+/**
+ * \brief          The key wrapping checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_nist_kw_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_NIST_KW_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/oid.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/oid.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/oid.h	(revision 398)
@@ -0,0 +1,605 @@
+/**
+ * \file oid.h
+ *
+ * \brief Object Identifier (OID) database
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_OID_H
+#define MBEDTLS_OID_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "asn1.h"
+#include "pk.h"
+
+#include <stddef.h>
+
+#if defined(MBEDTLS_CIPHER_C)
+#include "cipher.h"
+#endif
+
+#if defined(MBEDTLS_MD_C)
+#include "md.h"
+#endif
+
+#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
+#include "x509.h"
+#endif
+
+#define MBEDTLS_ERR_OID_NOT_FOUND                         -0x002E  /**< OID is not found. */
+#define MBEDTLS_ERR_OID_BUF_TOO_SMALL                     -0x000B  /**< output buffer is too small */
+
+/*
+ * Top level OID tuples
+ */
+#define MBEDTLS_OID_ISO_MEMBER_BODIES           "\x2a"          /* {iso(1) member-body(2)} */
+#define MBEDTLS_OID_ISO_IDENTIFIED_ORG          "\x2b"          /* {iso(1) identified-organization(3)} */
+#define MBEDTLS_OID_ISO_CCITT_DS                "\x55"          /* {joint-iso-ccitt(2) ds(5)} */
+#define MBEDTLS_OID_ISO_ITU_COUNTRY             "\x60"          /* {joint-iso-itu-t(2) country(16)} */
+
+/*
+ * ISO Member bodies OID parts
+ */
+#define MBEDTLS_OID_COUNTRY_US                  "\x86\x48"      /* {us(840)} */
+#define MBEDTLS_OID_ORG_RSA_DATA_SECURITY       "\x86\xf7\x0d"  /* {rsadsi(113549)} */
+#define MBEDTLS_OID_RSA_COMPANY                 MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \
+                                        MBEDTLS_OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */
+#define MBEDTLS_OID_ORG_ANSI_X9_62              "\xce\x3d" /* ansi-X9-62(10045) */
+#define MBEDTLS_OID_ANSI_X9_62                  MBEDTLS_OID_ISO_MEMBER_BODIES MBEDTLS_OID_COUNTRY_US \
+                                        MBEDTLS_OID_ORG_ANSI_X9_62
+
+/*
+ * ISO Identified organization OID parts
+ */
+#define MBEDTLS_OID_ORG_DOD                     "\x06"          /* {dod(6)} */
+#define MBEDTLS_OID_ORG_OIW                     "\x0e"
+#define MBEDTLS_OID_OIW_SECSIG                  MBEDTLS_OID_ORG_OIW "\x03"
+#define MBEDTLS_OID_OIW_SECSIG_ALG              MBEDTLS_OID_OIW_SECSIG "\x02"
+#define MBEDTLS_OID_OIW_SECSIG_SHA1             MBEDTLS_OID_OIW_SECSIG_ALG "\x1a"
+#define MBEDTLS_OID_ORG_CERTICOM                "\x81\x04"  /* certicom(132) */
+#define MBEDTLS_OID_CERTICOM                    MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_CERTICOM
+#define MBEDTLS_OID_ORG_TELETRUST               "\x24" /* teletrust(36) */
+#define MBEDTLS_OID_TELETRUST                   MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_TELETRUST
+
+/*
+ * ISO ITU OID parts
+ */
+#define MBEDTLS_OID_ORGANIZATION                "\x01"          /* {organization(1)} */
+#define MBEDTLS_OID_ISO_ITU_US_ORG              MBEDTLS_OID_ISO_ITU_COUNTRY MBEDTLS_OID_COUNTRY_US MBEDTLS_OID_ORGANIZATION /* {joint-iso-itu-t(2) country(16) us(840) organization(1)} */
+
+#define MBEDTLS_OID_ORG_GOV                     "\x65"          /* {gov(101)} */
+#define MBEDTLS_OID_GOV                         MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_GOV /* {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)} */
+
+#define MBEDTLS_OID_ORG_NETSCAPE                "\x86\xF8\x42"  /* {netscape(113730)} */
+#define MBEDTLS_OID_NETSCAPE                    MBEDTLS_OID_ISO_ITU_US_ORG MBEDTLS_OID_ORG_NETSCAPE /* Netscape OID {joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730)} */
+
+/* ISO arc for standard certificate and CRL extensions */
+#define MBEDTLS_OID_ID_CE                       MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER  ::=  {joint-iso-ccitt(2) ds(5) 29} */
+
+#define MBEDTLS_OID_NIST_ALG                    MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */
+
+/**
+ * Private Internet Extensions
+ * { iso(1) identified-organization(3) dod(6) internet(1)
+ *                      security(5) mechanisms(5) pkix(7) }
+ */
+#define MBEDTLS_OID_PKIX                        MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x05\x05\x07"
+
+/*
+ * Arc for standard naming attributes
+ */
+#define MBEDTLS_OID_AT                          MBEDTLS_OID_ISO_CCITT_DS "\x04" /**< id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} */
+#define MBEDTLS_OID_AT_CN                       MBEDTLS_OID_AT "\x03" /**< id-at-commonName AttributeType:= {id-at 3} */
+#define MBEDTLS_OID_AT_SUR_NAME                 MBEDTLS_OID_AT "\x04" /**< id-at-surName AttributeType:= {id-at 4} */
+#define MBEDTLS_OID_AT_SERIAL_NUMBER            MBEDTLS_OID_AT "\x05" /**< id-at-serialNumber AttributeType:= {id-at 5} */
+#define MBEDTLS_OID_AT_COUNTRY                  MBEDTLS_OID_AT "\x06" /**< id-at-countryName AttributeType:= {id-at 6} */
+#define MBEDTLS_OID_AT_LOCALITY                 MBEDTLS_OID_AT "\x07" /**< id-at-locality AttributeType:= {id-at 7} */
+#define MBEDTLS_OID_AT_STATE                    MBEDTLS_OID_AT "\x08" /**< id-at-state AttributeType:= {id-at 8} */
+#define MBEDTLS_OID_AT_ORGANIZATION             MBEDTLS_OID_AT "\x0A" /**< id-at-organizationName AttributeType:= {id-at 10} */
+#define MBEDTLS_OID_AT_ORG_UNIT                 MBEDTLS_OID_AT "\x0B" /**< id-at-organizationalUnitName AttributeType:= {id-at 11} */
+#define MBEDTLS_OID_AT_TITLE                    MBEDTLS_OID_AT "\x0C" /**< id-at-title AttributeType:= {id-at 12} */
+#define MBEDTLS_OID_AT_POSTAL_ADDRESS           MBEDTLS_OID_AT "\x10" /**< id-at-postalAddress AttributeType:= {id-at 16} */
+#define MBEDTLS_OID_AT_POSTAL_CODE              MBEDTLS_OID_AT "\x11" /**< id-at-postalCode AttributeType:= {id-at 17} */
+#define MBEDTLS_OID_AT_GIVEN_NAME               MBEDTLS_OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */
+#define MBEDTLS_OID_AT_INITIALS                 MBEDTLS_OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */
+#define MBEDTLS_OID_AT_GENERATION_QUALIFIER     MBEDTLS_OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */
+#define MBEDTLS_OID_AT_UNIQUE_IDENTIFIER        MBEDTLS_OID_AT "\x2D" /**< id-at-uniqueIdentifier AttributType:= {id-at 45} */
+#define MBEDTLS_OID_AT_DN_QUALIFIER             MBEDTLS_OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */
+#define MBEDTLS_OID_AT_PSEUDONYM                MBEDTLS_OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */
+
+#define MBEDTLS_OID_DOMAIN_COMPONENT            "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */
+
+/*
+ * OIDs for standard certificate extensions
+ */
+#define MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER    MBEDTLS_OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 } */
+#define MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER      MBEDTLS_OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 } */
+#define MBEDTLS_OID_KEY_USAGE                   MBEDTLS_OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 } */
+#define MBEDTLS_OID_CERTIFICATE_POLICIES        MBEDTLS_OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 } */
+#define MBEDTLS_OID_POLICY_MAPPINGS             MBEDTLS_OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::=  { id-ce 33 } */
+#define MBEDTLS_OID_SUBJECT_ALT_NAME            MBEDTLS_OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 } */
+#define MBEDTLS_OID_ISSUER_ALT_NAME             MBEDTLS_OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::=  { id-ce 18 } */
+#define MBEDTLS_OID_SUBJECT_DIRECTORY_ATTRS     MBEDTLS_OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::=  { id-ce 9 } */
+#define MBEDTLS_OID_BASIC_CONSTRAINTS           MBEDTLS_OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 } */
+#define MBEDTLS_OID_NAME_CONSTRAINTS            MBEDTLS_OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::=  { id-ce 30 } */
+#define MBEDTLS_OID_POLICY_CONSTRAINTS          MBEDTLS_OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::=  { id-ce 36 } */
+#define MBEDTLS_OID_EXTENDED_KEY_USAGE          MBEDTLS_OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */
+#define MBEDTLS_OID_CRL_DISTRIBUTION_POINTS     MBEDTLS_OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::=  { id-ce 31 } */
+#define MBEDTLS_OID_INIHIBIT_ANYPOLICY          MBEDTLS_OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::=  { id-ce 54 } */
+#define MBEDTLS_OID_FRESHEST_CRL                MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::=  { id-ce 46 } */
+
+/*
+ * Netscape certificate extensions
+ */
+#define MBEDTLS_OID_NS_CERT                 MBEDTLS_OID_NETSCAPE "\x01"
+#define MBEDTLS_OID_NS_CERT_TYPE            MBEDTLS_OID_NS_CERT  "\x01"
+#define MBEDTLS_OID_NS_BASE_URL             MBEDTLS_OID_NS_CERT  "\x02"
+#define MBEDTLS_OID_NS_REVOCATION_URL       MBEDTLS_OID_NS_CERT  "\x03"
+#define MBEDTLS_OID_NS_CA_REVOCATION_URL    MBEDTLS_OID_NS_CERT  "\x04"
+#define MBEDTLS_OID_NS_RENEWAL_URL          MBEDTLS_OID_NS_CERT  "\x07"
+#define MBEDTLS_OID_NS_CA_POLICY_URL        MBEDTLS_OID_NS_CERT  "\x08"
+#define MBEDTLS_OID_NS_SSL_SERVER_NAME      MBEDTLS_OID_NS_CERT  "\x0C"
+#define MBEDTLS_OID_NS_COMMENT              MBEDTLS_OID_NS_CERT  "\x0D"
+#define MBEDTLS_OID_NS_DATA_TYPE            MBEDTLS_OID_NETSCAPE "\x02"
+#define MBEDTLS_OID_NS_CERT_SEQUENCE        MBEDTLS_OID_NS_DATA_TYPE "\x05"
+
+/*
+ * OIDs for CRL extensions
+ */
+#define MBEDTLS_OID_PRIVATE_KEY_USAGE_PERIOD    MBEDTLS_OID_ID_CE "\x10"
+#define MBEDTLS_OID_CRL_NUMBER                  MBEDTLS_OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */
+
+/*
+ * X.509 v3 Extended key usage OIDs
+ */
+#define MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE      MBEDTLS_OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */
+
+#define MBEDTLS_OID_KP                          MBEDTLS_OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */
+#define MBEDTLS_OID_SERVER_AUTH                 MBEDTLS_OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */
+#define MBEDTLS_OID_CLIENT_AUTH                 MBEDTLS_OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */
+#define MBEDTLS_OID_CODE_SIGNING                MBEDTLS_OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */
+#define MBEDTLS_OID_EMAIL_PROTECTION            MBEDTLS_OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */
+#define MBEDTLS_OID_TIME_STAMPING               MBEDTLS_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
+#define MBEDTLS_OID_OCSP_SIGNING                MBEDTLS_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
+
+/*
+ * PKCS definition OIDs
+ */
+
+#define MBEDTLS_OID_PKCS                MBEDTLS_OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */
+#define MBEDTLS_OID_PKCS1               MBEDTLS_OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */
+#define MBEDTLS_OID_PKCS5               MBEDTLS_OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */
+#define MBEDTLS_OID_PKCS9               MBEDTLS_OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */
+#define MBEDTLS_OID_PKCS12              MBEDTLS_OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */
+
+/*
+ * PKCS#1 OIDs
+ */
+#define MBEDTLS_OID_PKCS1_RSA           MBEDTLS_OID_PKCS1 "\x01" /**< rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */
+#define MBEDTLS_OID_PKCS1_MD2           MBEDTLS_OID_PKCS1 "\x02" /**< md2WithRSAEncryption ::= { pkcs-1 2 } */
+#define MBEDTLS_OID_PKCS1_MD4           MBEDTLS_OID_PKCS1 "\x03" /**< md4WithRSAEncryption ::= { pkcs-1 3 } */
+#define MBEDTLS_OID_PKCS1_MD5           MBEDTLS_OID_PKCS1 "\x04" /**< md5WithRSAEncryption ::= { pkcs-1 4 } */
+#define MBEDTLS_OID_PKCS1_SHA1          MBEDTLS_OID_PKCS1 "\x05" /**< sha1WithRSAEncryption ::= { pkcs-1 5 } */
+#define MBEDTLS_OID_PKCS1_SHA224        MBEDTLS_OID_PKCS1 "\x0e" /**< sha224WithRSAEncryption ::= { pkcs-1 14 } */
+#define MBEDTLS_OID_PKCS1_SHA256        MBEDTLS_OID_PKCS1 "\x0b" /**< sha256WithRSAEncryption ::= { pkcs-1 11 } */
+#define MBEDTLS_OID_PKCS1_SHA384        MBEDTLS_OID_PKCS1 "\x0c" /**< sha384WithRSAEncryption ::= { pkcs-1 12 } */
+#define MBEDTLS_OID_PKCS1_SHA512        MBEDTLS_OID_PKCS1 "\x0d" /**< sha512WithRSAEncryption ::= { pkcs-1 13 } */
+
+#define MBEDTLS_OID_RSA_SHA_OBS         "\x2B\x0E\x03\x02\x1D"
+
+#define MBEDTLS_OID_PKCS9_EMAIL         MBEDTLS_OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */
+
+/* RFC 4055 */
+#define MBEDTLS_OID_RSASSA_PSS          MBEDTLS_OID_PKCS1 "\x0a" /**< id-RSASSA-PSS ::= { pkcs-1 10 } */
+#define MBEDTLS_OID_MGF1                MBEDTLS_OID_PKCS1 "\x08" /**< id-mgf1 ::= { pkcs-1 8 } */
+
+/*
+ * Digest algorithms
+ */
+#define MBEDTLS_OID_DIGEST_ALG_MD2              MBEDTLS_OID_RSA_COMPANY "\x02\x02" /**< id-mbedtls_md2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 } */
+#define MBEDTLS_OID_DIGEST_ALG_MD4              MBEDTLS_OID_RSA_COMPANY "\x02\x04" /**< id-mbedtls_md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */
+#define MBEDTLS_OID_DIGEST_ALG_MD5              MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA1             MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA224           MBEDTLS_OID_NIST_ALG "\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */
+#define MBEDTLS_OID_DIGEST_ALG_SHA256           MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */
+
+#define MBEDTLS_OID_DIGEST_ALG_SHA384           MBEDTLS_OID_NIST_ALG "\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */
+
+#define MBEDTLS_OID_DIGEST_ALG_SHA512           MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
+
+#define MBEDTLS_OID_HMAC_SHA1                   MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
+
+#define MBEDTLS_OID_HMAC_SHA224                 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
+
+#define MBEDTLS_OID_HMAC_SHA256                 MBEDTLS_OID_RSA_COMPANY "\x02\x09" /**< id-hmacWithSHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 } */
+
+#define MBEDTLS_OID_HMAC_SHA384                 MBEDTLS_OID_RSA_COMPANY "\x02\x0A" /**< id-hmacWithSHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 } */
+
+#define MBEDTLS_OID_HMAC_SHA512                 MBEDTLS_OID_RSA_COMPANY "\x02\x0B" /**< id-hmacWithSHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 } */
+
+/*
+ * Encryption algorithms
+ */
+#define MBEDTLS_OID_DES_CBC                     MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
+#define MBEDTLS_OID_DES_EDE3_CBC                MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
+#define MBEDTLS_OID_AES                         MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */
+
+/*
+ * Key Wrapping algorithms
+ */
+/*
+ * RFC 5649
+ */
+#define MBEDTLS_OID_AES128_KW                   MBEDTLS_OID_AES "\x05" /** id-aes128-wrap     OBJECT IDENTIFIER ::= { aes 5 } */
+#define MBEDTLS_OID_AES128_KWP                  MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */
+#define MBEDTLS_OID_AES192_KW                   MBEDTLS_OID_AES "\x19" /** id-aes192-wrap     OBJECT IDENTIFIER ::= { aes 25 } */
+#define MBEDTLS_OID_AES192_KWP                  MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */
+#define MBEDTLS_OID_AES256_KW                   MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap     OBJECT IDENTIFIER ::= { aes 45 } */
+#define MBEDTLS_OID_AES256_KWP                  MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */
+/*
+ * PKCS#5 OIDs
+ */
+#define MBEDTLS_OID_PKCS5_PBKDF2                MBEDTLS_OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */
+#define MBEDTLS_OID_PKCS5_PBES2                 MBEDTLS_OID_PKCS5 "\x0d" /**< id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} */
+#define MBEDTLS_OID_PKCS5_PBMAC1                MBEDTLS_OID_PKCS5 "\x0e" /**< id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14} */
+
+/*
+ * PKCS#5 PBES1 algorithms
+ */
+#define MBEDTLS_OID_PKCS5_PBE_MD2_DES_CBC       MBEDTLS_OID_PKCS5 "\x01" /**< pbeWithMD2AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 1} */
+#define MBEDTLS_OID_PKCS5_PBE_MD2_RC2_CBC       MBEDTLS_OID_PKCS5 "\x04" /**< pbeWithMD2AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 4} */
+#define MBEDTLS_OID_PKCS5_PBE_MD5_DES_CBC       MBEDTLS_OID_PKCS5 "\x03" /**< pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3} */
+#define MBEDTLS_OID_PKCS5_PBE_MD5_RC2_CBC       MBEDTLS_OID_PKCS5 "\x06" /**< pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6} */
+#define MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC      MBEDTLS_OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */
+#define MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC      MBEDTLS_OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */
+
+/*
+ * PKCS#8 OIDs
+ */
+#define MBEDTLS_OID_PKCS9_CSR_EXT_REQ           MBEDTLS_OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */
+
+/*
+ * PKCS#12 PBE OIDs
+ */
+#define MBEDTLS_OID_PKCS12_PBE                      MBEDTLS_OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */
+
+#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128         MBEDTLS_OID_PKCS12_PBE "\x01" /**< pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 1} */
+#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_40          MBEDTLS_OID_PKCS12_PBE "\x02" /**< pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 2} */
+#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC    MBEDTLS_OID_PKCS12_PBE "\x03" /**< pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} */
+#define MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC    MBEDTLS_OID_PKCS12_PBE "\x04" /**< pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4} */
+#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_128_CBC     MBEDTLS_OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */
+#define MBEDTLS_OID_PKCS12_PBE_SHA1_RC2_40_CBC      MBEDTLS_OID_PKCS12_PBE "\x06" /**< pbeWithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} */
+
+/*
+ * EC key algorithms from RFC 5480
+ */
+
+/* id-ecPublicKey OBJECT IDENTIFIER ::= {
+ *       iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } */
+#define MBEDTLS_OID_EC_ALG_UNRESTRICTED         MBEDTLS_OID_ANSI_X9_62 "\x02\01"
+
+/*   id-ecDH OBJECT IDENTIFIER ::= {
+ *     iso(1) identified-organization(3) certicom(132)
+ *     schemes(1) ecdh(12) } */
+#define MBEDTLS_OID_EC_ALG_ECDH                 MBEDTLS_OID_CERTICOM "\x01\x0c"
+
+/*
+ * ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2
+ */
+
+/* secp192r1 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 1 } */
+#define MBEDTLS_OID_EC_GRP_SECP192R1        MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x01"
+
+/* secp224r1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 33 } */
+#define MBEDTLS_OID_EC_GRP_SECP224R1        MBEDTLS_OID_CERTICOM "\x00\x21"
+
+/* secp256r1 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 } */
+#define MBEDTLS_OID_EC_GRP_SECP256R1        MBEDTLS_OID_ANSI_X9_62 "\x03\x01\x07"
+
+/* secp384r1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 34 } */
+#define MBEDTLS_OID_EC_GRP_SECP384R1        MBEDTLS_OID_CERTICOM "\x00\x22"
+
+/* secp521r1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 35 } */
+#define MBEDTLS_OID_EC_GRP_SECP521R1        MBEDTLS_OID_CERTICOM "\x00\x23"
+
+/* secp192k1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 31 } */
+#define MBEDTLS_OID_EC_GRP_SECP192K1        MBEDTLS_OID_CERTICOM "\x00\x1f"
+
+/* secp224k1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 32 } */
+#define MBEDTLS_OID_EC_GRP_SECP224K1        MBEDTLS_OID_CERTICOM "\x00\x20"
+
+/* secp256k1 OBJECT IDENTIFIER ::= {
+ *   iso(1) identified-organization(3) certicom(132) curve(0) 10 } */
+#define MBEDTLS_OID_EC_GRP_SECP256K1        MBEDTLS_OID_CERTICOM "\x00\x0a"
+
+/* RFC 5639 4.1
+ * ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1)
+ * identified-organization(3) teletrust(36) algorithm(3) signature-
+ * algorithm(3) ecSign(2) 8}
+ * ellipticCurve OBJECT IDENTIFIER ::= {ecStdCurvesAndGeneration 1}
+ * versionOne OBJECT IDENTIFIER ::= {ellipticCurve 1} */
+#define MBEDTLS_OID_EC_BRAINPOOL_V1         MBEDTLS_OID_TELETRUST "\x03\x03\x02\x08\x01\x01"
+
+/* brainpoolP256r1 OBJECT IDENTIFIER ::= {versionOne 7} */
+#define MBEDTLS_OID_EC_GRP_BP256R1          MBEDTLS_OID_EC_BRAINPOOL_V1 "\x07"
+
+/* brainpoolP384r1 OBJECT IDENTIFIER ::= {versionOne 11} */
+#define MBEDTLS_OID_EC_GRP_BP384R1          MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0B"
+
+/* brainpoolP512r1 OBJECT IDENTIFIER ::= {versionOne 13} */
+#define MBEDTLS_OID_EC_GRP_BP512R1          MBEDTLS_OID_EC_BRAINPOOL_V1 "\x0D"
+
+/*
+ * SEC1 C.1
+ *
+ * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
+ * id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1)}
+ */
+#define MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE   MBEDTLS_OID_ANSI_X9_62 "\x01"
+#define MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD  MBEDTLS_OID_ANSI_X9_62_FIELD_TYPE "\x01"
+
+/*
+ * ECDSA signature identifiers, from RFC 5480
+ */
+#define MBEDTLS_OID_ANSI_X9_62_SIG          MBEDTLS_OID_ANSI_X9_62 "\x04" /* signatures(4) */
+#define MBEDTLS_OID_ANSI_X9_62_SIG_SHA2     MBEDTLS_OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */
+
+/* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 } */
+#define MBEDTLS_OID_ECDSA_SHA1              MBEDTLS_OID_ANSI_X9_62_SIG "\x01"
+
+/* ecdsa-with-SHA224 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ *   ecdsa-with-SHA2(3) 1 } */
+#define MBEDTLS_OID_ECDSA_SHA224            MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x01"
+
+/* ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ *   ecdsa-with-SHA2(3) 2 } */
+#define MBEDTLS_OID_ECDSA_SHA256            MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x02"
+
+/* ecdsa-with-SHA384 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ *   ecdsa-with-SHA2(3) 3 } */
+#define MBEDTLS_OID_ECDSA_SHA384            MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x03"
+
+/* ecdsa-with-SHA512 OBJECT IDENTIFIER ::= {
+ *   iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
+ *   ecdsa-with-SHA2(3) 4 } */
+#define MBEDTLS_OID_ECDSA_SHA512            MBEDTLS_OID_ANSI_X9_62_SIG_SHA2 "\x04"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Base OID descriptor structure
+ */
+typedef struct mbedtls_oid_descriptor_t
+{
+    const char *asn1;               /*!< OID ASN.1 representation       */
+    size_t asn1_len;                /*!< length of asn1                 */
+    const char *name;               /*!< official name (e.g. from RFC)  */
+    const char *description;        /*!< human friendly description     */
+} mbedtls_oid_descriptor_t;
+
+/**
+ * \brief           Translate an ASN.1 OID into its numeric representation
+ *                  (e.g. "\x2A\x86\x48\x86\xF7\x0D" into "1.2.840.113549")
+ *
+ * \param buf       buffer to put representation in
+ * \param size      size of the buffer
+ * \param oid       OID to translate
+ *
+ * \return          Length of the string written (excluding final NULL) or
+ *                  MBEDTLS_ERR_OID_BUF_TOO_SMALL in case of error
+ */
+int mbedtls_oid_get_numeric_string( char *buf, size_t size, const mbedtls_asn1_buf *oid );
+
+#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
+/**
+ * \brief          Translate an X.509 extension OID into local values
+ *
+ * \param oid      OID to use
+ * \param ext_type place to store the extension type
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_x509_ext_type( const mbedtls_asn1_buf *oid, int *ext_type );
+#endif
+
+/**
+ * \brief          Translate an X.509 attribute type OID into the short name
+ *                 (e.g. the OID for an X520 Common Name into "CN")
+ *
+ * \param oid      OID to use
+ * \param short_name    place to store the string pointer
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_attr_short_name( const mbedtls_asn1_buf *oid, const char **short_name );
+
+/**
+ * \brief          Translate PublicKeyAlgorithm OID into pk_type
+ *
+ * \param oid      OID to use
+ * \param pk_alg   place to store public key algorithm
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_pk_alg( const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_alg );
+
+/**
+ * \brief          Translate pk_type into PublicKeyAlgorithm OID
+ *
+ * \param pk_alg   Public key type to look for
+ * \param oid      place to store ASN.1 OID string pointer
+ * \param olen     length of the OID
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_type_t pk_alg,
+                           const char **oid, size_t *olen );
+
+#if defined(MBEDTLS_ECP_C)
+/**
+ * \brief          Translate NamedCurve OID into an EC group identifier
+ *
+ * \param oid      OID to use
+ * \param grp_id   place to store group id
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_ec_grp( const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id );
+
+/**
+ * \brief          Translate EC group identifier into NamedCurve OID
+ *
+ * \param grp_id   EC group identifier
+ * \param oid      place to store ASN.1 OID string pointer
+ * \param olen     length of the OID
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_oid_by_ec_grp( mbedtls_ecp_group_id grp_id,
+                           const char **oid, size_t *olen );
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_MD_C)
+/**
+ * \brief          Translate SignatureAlgorithm OID into md_type and pk_type
+ *
+ * \param oid      OID to use
+ * \param md_alg   place to store message digest algorithm
+ * \param pk_alg   place to store public key algorithm
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_sig_alg( const mbedtls_asn1_buf *oid,
+                     mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg );
+
+/**
+ * \brief          Translate SignatureAlgorithm OID into description
+ *
+ * \param oid      OID to use
+ * \param desc     place to store string pointer
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_sig_alg_desc( const mbedtls_asn1_buf *oid, const char **desc );
+
+/**
+ * \brief          Translate md_type and pk_type into SignatureAlgorithm OID
+ *
+ * \param md_alg   message digest algorithm
+ * \param pk_alg   public key algorithm
+ * \param oid      place to store ASN.1 OID string pointer
+ * \param olen     length of the OID
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_oid_by_sig_alg( mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
+                            const char **oid, size_t *olen );
+
+/**
+ * \brief          Translate hash algorithm OID into md_type
+ *
+ * \param oid      OID to use
+ * \param md_alg   place to store message digest algorithm
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_md_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg );
+
+/**
+ * \brief          Translate hmac algorithm OID into md_type
+ *
+ * \param oid      OID to use
+ * \param md_hmac  place to store message hmac algorithm
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac );
+#endif /* MBEDTLS_MD_C */
+
+/**
+ * \brief          Translate Extended Key Usage OID into description
+ *
+ * \param oid      OID to use
+ * \param desc     place to store string pointer
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_extended_key_usage( const mbedtls_asn1_buf *oid, const char **desc );
+
+/**
+ * \brief          Translate md_type into hash algorithm OID
+ *
+ * \param md_alg   message digest algorithm
+ * \param oid      place to store ASN.1 OID string pointer
+ * \param olen     length of the OID
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_oid_by_md( mbedtls_md_type_t md_alg, const char **oid, size_t *olen );
+
+#if defined(MBEDTLS_CIPHER_C)
+/**
+ * \brief          Translate encryption algorithm OID into cipher_type
+ *
+ * \param oid           OID to use
+ * \param cipher_alg    place to store cipher algorithm
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_cipher_alg( const mbedtls_asn1_buf *oid, mbedtls_cipher_type_t *cipher_alg );
+#endif /* MBEDTLS_CIPHER_C */
+
+#if defined(MBEDTLS_PKCS12_C)
+/**
+ * \brief          Translate PKCS#12 PBE algorithm OID into md_type and
+ *                 cipher_type
+ *
+ * \param oid           OID to use
+ * \param md_alg        place to store message digest algorithm
+ * \param cipher_alg    place to store cipher algorithm
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_pkcs12_pbe_alg( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg,
+                            mbedtls_cipher_type_t *cipher_alg );
+#endif /* MBEDTLS_PKCS12_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* oid.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/padlock.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/padlock.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/padlock.h	(revision 398)
@@ -0,0 +1,126 @@
+/**
+ * \file padlock.h
+ *
+ * \brief VIA PadLock ACE for HW encryption/decryption supported by some
+ *        processors
+ *
+ * \warning These functions are only for internal use by other library
+ *          functions; you must not call them directly.
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PADLOCK_H
+#define MBEDTLS_PADLOCK_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "aes.h"
+
+#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED               -0x0030  /**< Input data should be aligned. */
+
+#if defined(__has_feature)
+#if __has_feature(address_sanitizer)
+#define MBEDTLS_HAVE_ASAN
+#endif
+#endif
+
+/* Some versions of ASan result in errors about not enough registers */
+#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) && \
+    !defined(MBEDTLS_HAVE_ASAN)
+
+#ifndef MBEDTLS_HAVE_X86
+#define MBEDTLS_HAVE_X86
+#endif
+
+#include <stdint.h>
+
+#define MBEDTLS_PADLOCK_RNG 0x000C
+#define MBEDTLS_PADLOCK_ACE 0x00C0
+#define MBEDTLS_PADLOCK_PHE 0x0C00
+#define MBEDTLS_PADLOCK_PMM 0x3000
+
+#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) x & ~15))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          Internal PadLock detection routine
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
+ *
+ * \param feature  The feature to detect
+ *
+ * \return         1 if CPU has support for the feature, 0 otherwise
+ */
+int mbedtls_padlock_has_support( int feature );
+
+/**
+ * \brief          Internal PadLock AES-ECB block en(de)cryption
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
+ *
+ * \param ctx      AES context
+ * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
+ * \param input    16-byte input block
+ * \param output   16-byte output block
+ *
+ * \return         0 if success, 1 if operation failed
+ */
+int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx,
+                               int mode,
+                               const unsigned char input[16],
+                               unsigned char output[16] );
+
+/**
+ * \brief          Internal PadLock AES-CBC buffer en(de)cryption
+ *
+ * \note           This function is only for internal use by other library
+ *                 functions; you must not call it directly.
+ *
+ * \param ctx      AES context
+ * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
+ * \param length   length of the input data
+ * \param iv       initialization vector (updated after use)
+ * \param input    buffer holding the input data
+ * \param output   buffer holding the output data
+ *
+ * \return         0 if success, 1 if operation failed
+ */
+int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx,
+                               int mode,
+                               size_t length,
+                               unsigned char iv[16],
+                               const unsigned char *input,
+                               unsigned char *output );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAVE_X86  */
+
+#endif /* padlock.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pem.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pem.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pem.h	(revision 398)
@@ -0,0 +1,136 @@
+/**
+ * \file pem.h
+ *
+ * \brief Privacy Enhanced Mail (PEM) decoding
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PEM_H
+#define MBEDTLS_PEM_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+/**
+ * \name PEM Error codes
+ * These error codes are returned in case of errors reading the
+ * PEM data.
+ * \{
+ */
+#define MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT          -0x1080  /**< No PEM header or footer found. */
+#define MBEDTLS_ERR_PEM_INVALID_DATA                      -0x1100  /**< PEM string is not as expected. */
+#define MBEDTLS_ERR_PEM_ALLOC_FAILED                      -0x1180  /**< Failed to allocate memory. */
+#define MBEDTLS_ERR_PEM_INVALID_ENC_IV                    -0x1200  /**< RSA IV is not in hex-format. */
+#define MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG                   -0x1280  /**< Unsupported key encryption algorithm. */
+#define MBEDTLS_ERR_PEM_PASSWORD_REQUIRED                 -0x1300  /**< Private key password can't be empty. */
+#define MBEDTLS_ERR_PEM_PASSWORD_MISMATCH                 -0x1380  /**< Given private key password does not allow for correct decryption. */
+#define MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE               -0x1400  /**< Unavailable feature, e.g. hashing/encryption combination. */
+#define MBEDTLS_ERR_PEM_BAD_INPUT_DATA                    -0x1480  /**< Bad input parameters to function. */
+/* \} name */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+/**
+ * \brief       PEM context structure
+ */
+typedef struct mbedtls_pem_context
+{
+    unsigned char *buf;     /*!< buffer for decoded data             */
+    size_t buflen;          /*!< length of the buffer                */
+    unsigned char *info;    /*!< buffer for extra header information */
+}
+mbedtls_pem_context;
+
+/**
+ * \brief       PEM context setup
+ *
+ * \param ctx   context to be initialized
+ */
+void mbedtls_pem_init( mbedtls_pem_context *ctx );
+
+/**
+ * \brief       Read a buffer for PEM information and store the resulting
+ *              data into the specified context buffers.
+ *
+ * \param ctx       context to use
+ * \param header    header string to seek and expect
+ * \param footer    footer string to seek and expect
+ * \param data      source data to look in (must be nul-terminated)
+ * \param pwd       password for decryption (can be NULL)
+ * \param pwdlen    length of password
+ * \param use_len   destination for total length used (set after header is
+ *                  correctly read, so unless you get
+ *                  MBEDTLS_ERR_PEM_BAD_INPUT_DATA or
+ *                  MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is
+ *                  the length to skip)
+ *
+ * \note            Attempts to check password correctness by verifying if
+ *                  the decrypted text starts with an ASN.1 sequence of
+ *                  appropriate length
+ *
+ * \return          0 on success, or a specific PEM error code
+ */
+int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer,
+                     const unsigned char *data,
+                     const unsigned char *pwd,
+                     size_t pwdlen, size_t *use_len );
+
+/**
+ * \brief       PEM context memory freeing
+ *
+ * \param ctx   context to be freed
+ */
+void mbedtls_pem_free( mbedtls_pem_context *ctx );
+#endif /* MBEDTLS_PEM_PARSE_C */
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+/**
+ * \brief           Write a buffer of PEM information from a DER encoded
+ *                  buffer.
+ *
+ * \param header    header string to write
+ * \param footer    footer string to write
+ * \param der_data  DER data to write
+ * \param der_len   length of the DER data
+ * \param buf       buffer to write to
+ * \param buf_len   length of output buffer
+ * \param olen      total length written / required (if buf_len is not enough)
+ *
+ * \return          0 on success, or a specific PEM or BASE64 error code. On
+ *                  MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL olen is the required
+ *                  size.
+ */
+int mbedtls_pem_write_buffer( const char *header, const char *footer,
+                      const unsigned char *der_data, size_t der_len,
+                      unsigned char *buf, size_t buf_len, size_t *olen );
+#endif /* MBEDTLS_PEM_WRITE_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pem.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pk.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pk.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pk.h	(revision 398)
@@ -0,0 +1,747 @@
+/**
+ * \file pk.h
+ *
+ * \brief Public Key abstraction layer
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_PK_H
+#define MBEDTLS_PK_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "md.h"
+
+#if defined(MBEDTLS_RSA_C)
+#include "rsa.h"
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+#include "ecp.h"
+#endif
+
+#if defined(MBEDTLS_ECDSA_C)
+#include "ecdsa.h"
+#endif
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#define MBEDTLS_ERR_PK_ALLOC_FAILED        -0x3F80  /**< Memory allocation failed. */
+#define MBEDTLS_ERR_PK_TYPE_MISMATCH       -0x3F00  /**< Type mismatch, eg attempt to encrypt with an ECDSA key */
+#define MBEDTLS_ERR_PK_BAD_INPUT_DATA      -0x3E80  /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_PK_FILE_IO_ERROR       -0x3E00  /**< Read/write of file failed. */
+#define MBEDTLS_ERR_PK_KEY_INVALID_VERSION -0x3D80  /**< Unsupported key version */
+#define MBEDTLS_ERR_PK_KEY_INVALID_FORMAT  -0x3D00  /**< Invalid key tag or value. */
+#define MBEDTLS_ERR_PK_UNKNOWN_PK_ALG      -0x3C80  /**< Key algorithm is unsupported (only RSA and EC are supported). */
+#define MBEDTLS_ERR_PK_PASSWORD_REQUIRED   -0x3C00  /**< Private key password can't be empty. */
+#define MBEDTLS_ERR_PK_PASSWORD_MISMATCH   -0x3B80  /**< Given private key password does not allow for correct decryption. */
+#define MBEDTLS_ERR_PK_INVALID_PUBKEY      -0x3B00  /**< The pubkey tag or value is invalid (only RSA and EC are supported). */
+#define MBEDTLS_ERR_PK_INVALID_ALG         -0x3A80  /**< The algorithm tag or value is invalid. */
+#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00  /**< Elliptic curve is unsupported (only NIST curves are supported). */
+#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980  /**< Unavailable feature, e.g. RSA disabled for RSA key. */
+#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH    -0x3900  /**< The buffer contains a valid signature followed by more data. */
+
+/* MBEDTLS_ERR_PK_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_PK_HW_ACCEL_FAILED     -0x3880  /**< PK hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          Public key types
+ */
+typedef enum {
+    MBEDTLS_PK_NONE=0,
+    MBEDTLS_PK_RSA,
+    MBEDTLS_PK_ECKEY,
+    MBEDTLS_PK_ECKEY_DH,
+    MBEDTLS_PK_ECDSA,
+    MBEDTLS_PK_RSA_ALT,
+    MBEDTLS_PK_RSASSA_PSS,
+} mbedtls_pk_type_t;
+
+/**
+ * \brief           Options for RSASSA-PSS signature verification.
+ *                  See \c mbedtls_rsa_rsassa_pss_verify_ext()
+ */
+typedef struct mbedtls_pk_rsassa_pss_options
+{
+    mbedtls_md_type_t mgf1_hash_id;
+    int expected_salt_len;
+
+} mbedtls_pk_rsassa_pss_options;
+
+/**
+ * \brief           Types for interfacing with the debug module
+ */
+typedef enum
+{
+    MBEDTLS_PK_DEBUG_NONE = 0,
+    MBEDTLS_PK_DEBUG_MPI,
+    MBEDTLS_PK_DEBUG_ECP,
+} mbedtls_pk_debug_type;
+
+/**
+ * \brief           Item to send to the debug module
+ */
+typedef struct mbedtls_pk_debug_item
+{
+    mbedtls_pk_debug_type type;
+    const char *name;
+    void *value;
+} mbedtls_pk_debug_item;
+
+/** Maximum number of item send for debugging, plus 1 */
+#define MBEDTLS_PK_DEBUG_MAX_ITEMS 3
+
+/**
+ * \brief           Public key information and operations
+ */
+typedef struct mbedtls_pk_info_t mbedtls_pk_info_t;
+
+/**
+ * \brief           Public key container
+ */
+typedef struct mbedtls_pk_context
+{
+    const mbedtls_pk_info_t *   pk_info; /**< Public key information         */
+    void *                      pk_ctx;  /**< Underlying public key context  */
+} mbedtls_pk_context;
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Context for resuming operations
+ */
+typedef struct
+{
+    const mbedtls_pk_info_t *   pk_info; /**< Public key information         */
+    void *                      rs_ctx;  /**< Underlying restart context     */
+} mbedtls_pk_restart_ctx;
+#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+/* Now we can declare functions that take a pointer to that */
+typedef void mbedtls_pk_restart_ctx;
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+#if defined(MBEDTLS_RSA_C)
+/**
+ * Quick access to an RSA context inside a PK context.
+ *
+ * \warning You must make sure the PK context actually holds an RSA context
+ * before using this function!
+ */
+static inline mbedtls_rsa_context *mbedtls_pk_rsa( const mbedtls_pk_context pk )
+{
+    return( (mbedtls_rsa_context *) (pk).pk_ctx );
+}
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_ECP_C)
+/**
+ * Quick access to an EC context inside a PK context.
+ *
+ * \warning You must make sure the PK context actually holds an EC context
+ * before using this function!
+ */
+static inline mbedtls_ecp_keypair *mbedtls_pk_ec( const mbedtls_pk_context pk )
+{
+    return( (mbedtls_ecp_keypair *) (pk).pk_ctx );
+}
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+/**
+ * \brief           Types for RSA-alt abstraction
+ */
+typedef int (*mbedtls_pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen,
+                    const unsigned char *input, unsigned char *output,
+                    size_t output_max_len );
+typedef int (*mbedtls_pk_rsa_alt_sign_func)( void *ctx,
+                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                    int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
+                    const unsigned char *hash, unsigned char *sig );
+typedef size_t (*mbedtls_pk_rsa_alt_key_len_func)( void *ctx );
+#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
+
+/**
+ * \brief           Return information associated with the given PK type
+ *
+ * \param pk_type   PK type to search for.
+ *
+ * \return          The PK info associated with the type or NULL if not found.
+ */
+const mbedtls_pk_info_t *mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type );
+
+/**
+ * \brief           Initialize a #mbedtls_pk_context (as NONE).
+ *
+ * \param ctx       The context to initialize.
+ *                  This must not be \c NULL.
+ */
+void mbedtls_pk_init( mbedtls_pk_context *ctx );
+
+/**
+ * \brief           Free the components of a #mbedtls_pk_context.
+ *
+ * \param ctx       The context to clear. It must have been initialized.
+ *                  If this is \c NULL, this function does nothing.
+ */
+void mbedtls_pk_free( mbedtls_pk_context *ctx );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Initialize a restart context
+ *
+ * \param ctx       The context to initialize.
+ *                  This must not be \c NULL.
+ */
+void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx );
+
+/**
+ * \brief           Free the components of a restart context
+ *
+ * \param ctx       The context to clear. It must have been initialized.
+ *                  If this is \c NULL, this function does nothing.
+ */
+void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx );
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+/**
+ * \brief           Initialize a PK context with the information given
+ *                  and allocates the type-specific PK subcontext.
+ *
+ * \param ctx       Context to initialize. It must not have been set
+ *                  up yet (type #MBEDTLS_PK_NONE).
+ * \param info      Information to use
+ *
+ * \return          0 on success,
+ *                  MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input,
+ *                  MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
+ *
+ * \note            For contexts holding an RSA-alt key, use
+ *                  \c mbedtls_pk_setup_rsa_alt() instead.
+ */
+int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+/**
+ * \brief           Initialize an RSA-alt context
+ *
+ * \param ctx       Context to initialize. It must not have been set
+ *                  up yet (type #MBEDTLS_PK_NONE).
+ * \param key       RSA key pointer
+ * \param decrypt_func  Decryption function
+ * \param sign_func     Signing function
+ * \param key_len_func  Function returning key length in bytes
+ *
+ * \return          0 on success, or MBEDTLS_ERR_PK_BAD_INPUT_DATA if the
+ *                  context wasn't already initialized as RSA_ALT.
+ *
+ * \note            This function replaces \c mbedtls_pk_setup() for RSA-alt.
+ */
+int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
+                         mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
+                         mbedtls_pk_rsa_alt_sign_func sign_func,
+                         mbedtls_pk_rsa_alt_key_len_func key_len_func );
+#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
+
+/**
+ * \brief           Get the size in bits of the underlying key
+ *
+ * \param ctx       The context to query. It must have been initialized.
+ *
+ * \return          Key size in bits, or 0 on error
+ */
+size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx );
+
+/**
+ * \brief           Get the length in bytes of the underlying key
+ *
+ * \param ctx       The context to query. It must have been initialized.
+ *
+ * \return          Key length in bytes, or 0 on error
+ */
+static inline size_t mbedtls_pk_get_len( const mbedtls_pk_context *ctx )
+{
+    return( ( mbedtls_pk_get_bitlen( ctx ) + 7 ) / 8 );
+}
+
+/**
+ * \brief           Tell if a context can do the operation given by type
+ *
+ * \param ctx       The context to query. It must have been initialized.
+ * \param type      The desired type.
+ *
+ * \return          1 if the context can do operations on the given type.
+ * \return          0 if the context cannot do the operations on the given
+ *                  type. This is always the case for a context that has
+ *                  been initialized but not set up, or that has been
+ *                  cleared with mbedtls_pk_free().
+ */
+int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type );
+
+/**
+ * \brief           Verify signature (including padding if relevant).
+ *
+ * \param ctx       The PK context to use. It must have been set up.
+ * \param md_alg    Hash algorithm used (see notes)
+ * \param hash      Hash of the message to sign
+ * \param hash_len  Hash length or 0 (see notes)
+ * \param sig       Signature to verify
+ * \param sig_len   Signature length
+ *
+ * \return          0 on success (signature is valid),
+ *                  #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
+ *                  signature in sig but its length is less than \p siglen,
+ *                  or a specific error code.
+ *
+ * \note            For RSA keys, the default padding type is PKCS#1 v1.5.
+ *                  Use \c mbedtls_pk_verify_ext( MBEDTLS_PK_RSASSA_PSS, ... )
+ *                  to verify RSASSA_PSS signatures.
+ *
+ * \note            If hash_len is 0, then the length associated with md_alg
+ *                  is used instead, or an error returned if it is invalid.
+ *
+ * \note            md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0
+ */
+int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+               const unsigned char *hash, size_t hash_len,
+               const unsigned char *sig, size_t sig_len );
+
+/**
+ * \brief           Restartable version of \c mbedtls_pk_verify()
+ *
+ * \note            Performs the same job as \c mbedtls_pk_verify(), but can
+ *                  return early and restart according to the limit set with
+ *                  \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
+ *                  operations. For RSA, same as \c mbedtls_pk_verify().
+ *
+ * \param ctx       The PK context to use. It must have been set up.
+ * \param md_alg    Hash algorithm used (see notes)
+ * \param hash      Hash of the message to sign
+ * \param hash_len  Hash length or 0 (see notes)
+ * \param sig       Signature to verify
+ * \param sig_len   Signature length
+ * \param rs_ctx    Restart context (NULL to disable restart)
+ *
+ * \return          See \c mbedtls_pk_verify(), or
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ */
+int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
+               mbedtls_md_type_t md_alg,
+               const unsigned char *hash, size_t hash_len,
+               const unsigned char *sig, size_t sig_len,
+               mbedtls_pk_restart_ctx *rs_ctx );
+
+/**
+ * \brief           Verify signature, with options.
+ *                  (Includes verification of the padding depending on type.)
+ *
+ * \param type      Signature type (inc. possible padding type) to verify
+ * \param options   Pointer to type-specific options, or NULL
+ * \param ctx       The PK context to use. It must have been set up.
+ * \param md_alg    Hash algorithm used (see notes)
+ * \param hash      Hash of the message to sign
+ * \param hash_len  Hash length or 0 (see notes)
+ * \param sig       Signature to verify
+ * \param sig_len   Signature length
+ *
+ * \return          0 on success (signature is valid),
+ *                  #MBEDTLS_ERR_PK_TYPE_MISMATCH if the PK context can't be
+ *                  used for this type of signatures,
+ *                  #MBEDTLS_ERR_PK_SIG_LEN_MISMATCH if there is a valid
+ *                  signature in sig but its length is less than \p siglen,
+ *                  or a specific error code.
+ *
+ * \note            If hash_len is 0, then the length associated with md_alg
+ *                  is used instead, or an error returned if it is invalid.
+ *
+ * \note            md_alg may be MBEDTLS_MD_NONE, only if hash_len != 0
+ *
+ * \note            If type is MBEDTLS_PK_RSASSA_PSS, then options must point
+ *                  to a mbedtls_pk_rsassa_pss_options structure,
+ *                  otherwise it must be NULL.
+ */
+int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
+                   mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   const unsigned char *sig, size_t sig_len );
+
+/**
+ * \brief           Make signature, including padding if relevant.
+ *
+ * \param ctx       The PK context to use. It must have been set up
+ *                  with a private key.
+ * \param md_alg    Hash algorithm used (see notes)
+ * \param hash      Hash of the message to sign
+ * \param hash_len  Hash length or 0 (see notes)
+ * \param sig       Place to write the signature
+ * \param sig_len   Number of bytes written
+ * \param f_rng     RNG function
+ * \param p_rng     RNG parameter
+ *
+ * \return          0 on success, or a specific error code.
+ *
+ * \note            For RSA keys, the default padding type is PKCS#1 v1.5.
+ *                  There is no interface in the PK module to make RSASSA-PSS
+ *                  signatures yet.
+ *
+ * \note            If hash_len is 0, then the length associated with md_alg
+ *                  is used instead, or an error returned if it is invalid.
+ *
+ * \note            For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
+ *                  For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
+ */
+int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+             const unsigned char *hash, size_t hash_len,
+             unsigned char *sig, size_t *sig_len,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief           Restartable version of \c mbedtls_pk_sign()
+ *
+ * \note            Performs the same job as \c mbedtls_pk_sign(), but can
+ *                  return early and restart according to the limit set with
+ *                  \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
+ *                  operations. For RSA, same as \c mbedtls_pk_sign().
+ *
+ * \param ctx       The PK context to use. It must have been set up
+ *                  with a private key.
+ * \param md_alg    Hash algorithm used (see notes)
+ * \param hash      Hash of the message to sign
+ * \param hash_len  Hash length or 0 (see notes)
+ * \param sig       Place to write the signature
+ * \param sig_len   Number of bytes written
+ * \param f_rng     RNG function
+ * \param p_rng     RNG parameter
+ * \param rs_ctx    Restart context (NULL to disable restart)
+ *
+ * \return          See \c mbedtls_pk_sign(), or
+ * \return          #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                  operations was reached: see \c mbedtls_ecp_set_max_ops().
+ */
+int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
+             mbedtls_md_type_t md_alg,
+             const unsigned char *hash, size_t hash_len,
+             unsigned char *sig, size_t *sig_len,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+             mbedtls_pk_restart_ctx *rs_ctx );
+
+/**
+ * \brief           Decrypt message (including padding if relevant).
+ *
+ * \param ctx       The PK context to use. It must have been set up
+ *                  with a private key.
+ * \param input     Input to decrypt
+ * \param ilen      Input size
+ * \param output    Decrypted output
+ * \param olen      Decrypted message length
+ * \param osize     Size of the output buffer
+ * \param f_rng     RNG function
+ * \param p_rng     RNG parameter
+ *
+ * \note            For RSA keys, the default padding type is PKCS#1 v1.5.
+ *
+ * \return          0 on success, or a specific error code.
+ */
+int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
+                const unsigned char *input, size_t ilen,
+                unsigned char *output, size_t *olen, size_t osize,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief           Encrypt message (including padding if relevant).
+ *
+ * \param ctx       The PK context to use. It must have been set up.
+ * \param input     Message to encrypt
+ * \param ilen      Message size
+ * \param output    Encrypted output
+ * \param olen      Encrypted output length
+ * \param osize     Size of the output buffer
+ * \param f_rng     RNG function
+ * \param p_rng     RNG parameter
+ *
+ * \note            For RSA keys, the default padding type is PKCS#1 v1.5.
+ *
+ * \return          0 on success, or a specific error code.
+ */
+int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
+                const unsigned char *input, size_t ilen,
+                unsigned char *output, size_t *olen, size_t osize,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+/**
+ * \brief           Check if a public-private pair of keys matches.
+ *
+ * \param pub       Context holding a public key.
+ * \param prv       Context holding a private (and public) key.
+ *
+ * \return          0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
+ */
+int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv );
+
+/**
+ * \brief           Export debug information
+ *
+ * \param ctx       The PK context to use. It must have been initialized.
+ * \param items     Place to write debug items
+ *
+ * \return          0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
+ */
+int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items );
+
+/**
+ * \brief           Access the type name
+ *
+ * \param ctx       The PK context to use. It must have been initialized.
+ *
+ * \return          Type name on success, or "invalid PK"
+ */
+const char * mbedtls_pk_get_name( const mbedtls_pk_context *ctx );
+
+/**
+ * \brief           Get the key type
+ *
+ * \param ctx       The PK context to use. It must have been initialized.
+ *
+ * \return          Type on success.
+ * \return          #MBEDTLS_PK_NONE for a context that has not been set up.
+ */
+mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx );
+
+#if defined(MBEDTLS_PK_PARSE_C)
+/** \ingroup pk_module */
+/**
+ * \brief           Parse a private key in PEM or DER format
+ *
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
+ * \param key       Input buffer to parse.
+ *                  The buffer must contain the input exactly, with no
+ *                  extra trailing material. For PEM, the buffer must
+ *                  contain a null-terminated string.
+ * \param keylen    Size of \b key in bytes.
+ *                  For PEM data, this includes the terminating null byte,
+ *                  so \p keylen must be equal to `strlen(key) + 1`.
+ * \param pwd       Optional password for decryption.
+ *                  Pass \c NULL if expecting a non-encrypted key.
+ *                  Pass a string of \p pwdlen bytes if expecting an encrypted
+ *                  key; a non-encrypted key will also be accepted.
+ *                  The empty password is not supported.
+ * \param pwdlen    Size of the password in bytes.
+ *                  Ignored if \p pwd is \c NULL.
+ *
+ * \note            On entry, ctx must be empty, either freshly initialised
+ *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
+ *                  specific key type, check the result with mbedtls_pk_can_do().
+ *
+ * \note            The key is also checked for correctness.
+ *
+ * \return          0 if successful, or a specific PK or PEM error code
+ */
+int mbedtls_pk_parse_key( mbedtls_pk_context *ctx,
+                  const unsigned char *key, size_t keylen,
+                  const unsigned char *pwd, size_t pwdlen );
+
+/** \ingroup pk_module */
+/**
+ * \brief           Parse a public key in PEM or DER format
+ *
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
+ * \param key       Input buffer to parse.
+ *                  The buffer must contain the input exactly, with no
+ *                  extra trailing material. For PEM, the buffer must
+ *                  contain a null-terminated string.
+ * \param keylen    Size of \b key in bytes.
+ *                  For PEM data, this includes the terminating null byte,
+ *                  so \p keylen must be equal to `strlen(key) + 1`.
+ *
+ * \note            On entry, ctx must be empty, either freshly initialised
+ *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
+ *                  specific key type, check the result with mbedtls_pk_can_do().
+ *
+ * \note            The key is also checked for correctness.
+ *
+ * \return          0 if successful, or a specific PK or PEM error code
+ */
+int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
+                         const unsigned char *key, size_t keylen );
+
+#if defined(MBEDTLS_FS_IO)
+/** \ingroup pk_module */
+/**
+ * \brief           Load and parse a private key
+ *
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
+ * \param path      filename to read the private key from
+ * \param password  Optional password to decrypt the file.
+ *                  Pass \c NULL if expecting a non-encrypted key.
+ *                  Pass a null-terminated string if expecting an encrypted
+ *                  key; a non-encrypted key will also be accepted.
+ *                  The empty password is not supported.
+ *
+ * \note            On entry, ctx must be empty, either freshly initialised
+ *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a
+ *                  specific key type, check the result with mbedtls_pk_can_do().
+ *
+ * \note            The key is also checked for correctness.
+ *
+ * \return          0 if successful, or a specific PK or PEM error code
+ */
+int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
+                      const char *path, const char *password );
+
+/** \ingroup pk_module */
+/**
+ * \brief           Load and parse a public key
+ *
+ * \param ctx       The PK context to fill. It must have been initialized
+ *                  but not set up.
+ * \param path      filename to read the public key from
+ *
+ * \note            On entry, ctx must be empty, either freshly initialised
+ *                  with mbedtls_pk_init() or reset with mbedtls_pk_free(). If
+ *                  you need a specific key type, check the result with
+ *                  mbedtls_pk_can_do().
+ *
+ * \note            The key is also checked for correctness.
+ *
+ * \return          0 if successful, or a specific PK or PEM error code
+ */
+int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path );
+#endif /* MBEDTLS_FS_IO */
+#endif /* MBEDTLS_PK_PARSE_C */
+
+#if defined(MBEDTLS_PK_WRITE_C)
+/**
+ * \brief           Write a private key to a PKCS#1 or SEC1 DER structure
+ *                  Note: data is written at the end of the buffer! Use the
+ *                        return value to determine where you should start
+ *                        using the buffer
+ *
+ * \param ctx       PK context which must contain a valid private key.
+ * \param buf       buffer to write to
+ * \param size      size of the buffer
+ *
+ * \return          length of data written if successful, or a specific
+ *                  error code
+ */
+int mbedtls_pk_write_key_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
+
+/**
+ * \brief           Write a public key to a SubjectPublicKeyInfo DER structure
+ *                  Note: data is written at the end of the buffer! Use the
+ *                        return value to determine where you should start
+ *                        using the buffer
+ *
+ * \param ctx       PK context which must contain a valid public or private key.
+ * \param buf       buffer to write to
+ * \param size      size of the buffer
+ *
+ * \return          length of data written if successful, or a specific
+ *                  error code
+ */
+int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+/**
+ * \brief           Write a public key to a PEM string
+ *
+ * \param ctx       PK context which must contain a valid public or private key.
+ * \param buf       Buffer to write to. The output includes a
+ *                  terminating null byte.
+ * \param size      Size of the buffer in bytes.
+ *
+ * \return          0 if successful, or a specific error code
+ */
+int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
+
+/**
+ * \brief           Write a private key to a PKCS#1 or SEC1 PEM string
+ *
+ * \param ctx       PK context which must contain a valid private key.
+ * \param buf       Buffer to write to. The output includes a
+ *                  terminating null byte.
+ * \param size      Size of the buffer in bytes.
+ *
+ * \return          0 if successful, or a specific error code
+ */
+int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
+#endif /* MBEDTLS_PEM_WRITE_C */
+#endif /* MBEDTLS_PK_WRITE_C */
+
+/*
+ * WARNING: Low-level functions. You probably do not want to use these unless
+ *          you are certain you do ;)
+ */
+
+#if defined(MBEDTLS_PK_PARSE_C)
+/**
+ * \brief           Parse a SubjectPublicKeyInfo DER structure
+ *
+ * \param p         the position in the ASN.1 data
+ * \param end       end of the buffer
+ * \param pk        The PK context to fill. It must have been initialized
+ *                  but not set up.
+ *
+ * \return          0 if successful, or a specific PK error code
+ */
+int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
+                        mbedtls_pk_context *pk );
+#endif /* MBEDTLS_PK_PARSE_C */
+
+#if defined(MBEDTLS_PK_WRITE_C)
+/**
+ * \brief           Write a subjectPublicKey to ASN.1 data
+ *                  Note: function works backwards in data buffer
+ *
+ * \param p         reference to current position pointer
+ * \param start     start of the buffer (for bounds-checking)
+ * \param key       PK context which must contain a valid public or private key.
+ *
+ * \return          the length written or a negative error code
+ */
+int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
+                     const mbedtls_pk_context *key );
+#endif /* MBEDTLS_PK_WRITE_C */
+
+/*
+ * Internal module functions. You probably do not want to use these unless you
+ * know you do.
+ */
+#if defined(MBEDTLS_FS_IO)
+int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_PK_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pk_internal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pk_internal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pk_internal.h	(revision 398)
@@ -0,0 +1,138 @@
+/**
+ * \file pk_internal.h
+ *
+ * \brief Public Key abstraction layer: wrapper functions
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_PK_WRAP_H
+#define MBEDTLS_PK_WRAP_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "pk.h"
+
+struct mbedtls_pk_info_t
+{
+    /** Public key type */
+    mbedtls_pk_type_t type;
+
+    /** Type name */
+    const char *name;
+
+    /** Get key size in bits */
+    size_t (*get_bitlen)( const void * );
+
+    /** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */
+    int (*can_do)( mbedtls_pk_type_t type );
+
+    /** Verify signature */
+    int (*verify_func)( void *ctx, mbedtls_md_type_t md_alg,
+                        const unsigned char *hash, size_t hash_len,
+                        const unsigned char *sig, size_t sig_len );
+
+    /** Make signature */
+    int (*sign_func)( void *ctx, mbedtls_md_type_t md_alg,
+                      const unsigned char *hash, size_t hash_len,
+                      unsigned char *sig, size_t *sig_len,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    /** Verify signature (restartable) */
+    int (*verify_rs_func)( void *ctx, mbedtls_md_type_t md_alg,
+                           const unsigned char *hash, size_t hash_len,
+                           const unsigned char *sig, size_t sig_len,
+                           void *rs_ctx );
+
+    /** Make signature (restartable) */
+    int (*sign_rs_func)( void *ctx, mbedtls_md_type_t md_alg,
+                         const unsigned char *hash, size_t hash_len,
+                         unsigned char *sig, size_t *sig_len,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng, void *rs_ctx );
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+    /** Decrypt message */
+    int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
+                         unsigned char *output, size_t *olen, size_t osize,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng );
+
+    /** Encrypt message */
+    int (*encrypt_func)( void *ctx, const unsigned char *input, size_t ilen,
+                         unsigned char *output, size_t *olen, size_t osize,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng );
+
+    /** Check public-private key pair */
+    int (*check_pair_func)( const void *pub, const void *prv );
+
+    /** Allocate a new context */
+    void * (*ctx_alloc_func)( void );
+
+    /** Free the given context */
+    void (*ctx_free_func)( void *ctx );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    /** Allocate the restart context */
+    void * (*rs_alloc_func)( void );
+
+    /** Free the restart context */
+    void (*rs_free_func)( void *rs_ctx );
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+    /** Interface with the debug module */
+    void (*debug_func)( const void *ctx, mbedtls_pk_debug_item *items );
+
+};
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+/* Container for RSA-alt */
+typedef struct
+{
+    void *key;
+    mbedtls_pk_rsa_alt_decrypt_func decrypt_func;
+    mbedtls_pk_rsa_alt_sign_func sign_func;
+    mbedtls_pk_rsa_alt_key_len_func key_len_func;
+} mbedtls_rsa_alt_context;
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+extern const mbedtls_pk_info_t mbedtls_rsa_info;
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+extern const mbedtls_pk_info_t mbedtls_eckey_info;
+extern const mbedtls_pk_info_t mbedtls_eckeydh_info;
+#endif
+
+#if defined(MBEDTLS_ECDSA_C)
+extern const mbedtls_pk_info_t mbedtls_ecdsa_info;
+#endif
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+extern const mbedtls_pk_info_t mbedtls_rsa_alt_info;
+#endif
+
+#endif /* MBEDTLS_PK_WRAP_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pkcs11.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pkcs11.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pkcs11.h	(revision 398)
@@ -0,0 +1,175 @@
+/**
+ * \file pkcs11.h
+ *
+ * \brief Wrapper for PKCS#11 library libpkcs11-helper
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PKCS11_H
+#define MBEDTLS_PKCS11_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PKCS11_C)
+
+#include "x509_crt.h"
+
+#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Context for PKCS #11 private keys.
+ */
+typedef struct mbedtls_pkcs11_context
+{
+        pkcs11h_certificate_t pkcs11h_cert;
+        int len;
+} mbedtls_pkcs11_context;
+
+/**
+ * Initialize a mbedtls_pkcs11_context.
+ * (Just making memory references valid.)
+ */
+void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx );
+
+/**
+ * Fill in a mbed TLS certificate, based on the given PKCS11 helper certificate.
+ *
+ * \param cert          X.509 certificate to fill
+ * \param pkcs11h_cert  PKCS #11 helper certificate
+ *
+ * \return              0 on success.
+ */
+int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11h_cert );
+
+/**
+ * Set up a mbedtls_pkcs11_context storing the given certificate. Note that the
+ * mbedtls_pkcs11_context will take over control of the certificate, freeing it when
+ * done.
+ *
+ * \param priv_key      Private key structure to fill.
+ * \param pkcs11_cert   PKCS #11 helper certificate
+ *
+ * \return              0 on success
+ */
+int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key,
+        pkcs11h_certificate_t pkcs11_cert );
+
+/**
+ * Free the contents of the given private key context. Note that the structure
+ * itself is not freed.
+ *
+ * \param priv_key      Private key structure to cleanup
+ */
+void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key );
+
+/**
+ * \brief          Do an RSA private key decrypt, then remove the message
+ *                 padding
+ *
+ * \param ctx      PKCS #11 context
+ * \param mode     must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature
+ * \param input    buffer holding the encrypted data
+ * \param output   buffer that will hold the plaintext
+ * \param olen     will contain the plaintext length
+ * \param output_max_len    maximum length of the output buffer
+ *
+ * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
+ *
+ * \note           The output buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ *                 an error is thrown.
+ */
+int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
+                       int mode, size_t *olen,
+                       const unsigned char *input,
+                       unsigned char *output,
+                       size_t output_max_len );
+
+/**
+ * \brief          Do a private RSA to sign a message digest
+ *
+ * \param ctx      PKCS #11 context
+ * \param mode     must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature
+ * \param md_alg   a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data)
+ * \param hashlen  message digest length (for MBEDTLS_MD_NONE only)
+ * \param hash     buffer holding the message digest
+ * \param sig      buffer that will hold the ciphertext
+ *
+ * \return         0 if the signing operation was successful,
+ *                 or an MBEDTLS_ERR_RSA_XXX error code
+ *
+ * \note           The "sig" buffer must be as large as the size
+ *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx,
+                    int mode,
+                    mbedtls_md_type_t md_alg,
+                    unsigned int hashlen,
+                    const unsigned char *hash,
+                    unsigned char *sig );
+
+/**
+ * SSL/TLS wrappers for PKCS#11 functions
+ */
+static inline int mbedtls_ssl_pkcs11_decrypt( void *ctx, int mode, size_t *olen,
+                        const unsigned char *input, unsigned char *output,
+                        size_t output_max_len )
+{
+    return mbedtls_pkcs11_decrypt( (mbedtls_pkcs11_context *) ctx, mode, olen, input, output,
+                           output_max_len );
+}
+
+static inline int mbedtls_ssl_pkcs11_sign( void *ctx,
+                     int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                     int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
+                     const unsigned char *hash, unsigned char *sig )
+{
+    ((void) f_rng);
+    ((void) p_rng);
+    return mbedtls_pkcs11_sign( (mbedtls_pkcs11_context *) ctx, mode, md_alg,
+                        hashlen, hash, sig );
+}
+
+static inline size_t mbedtls_ssl_pkcs11_key_len( void *ctx )
+{
+    return ( (mbedtls_pkcs11_context *) ctx )->len;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_PKCS11_C */
+
+#endif /* MBEDTLS_PKCS11_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pkcs12.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pkcs12.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pkcs12.h	(revision 398)
@@ -0,0 +1,130 @@
+/**
+ * \file pkcs12.h
+ *
+ * \brief PKCS#12 Personal Information Exchange Syntax
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PKCS12_H
+#define MBEDTLS_PKCS12_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "md.h"
+#include "cipher.h"
+#include "asn1.h"
+
+#include <stddef.h>
+
+#define MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA                 -0x1F80  /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE            -0x1F00  /**< Feature not available, e.g. unsupported encryption scheme. */
+#define MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT             -0x1E80  /**< PBE ASN.1 data not as expected. */
+#define MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH              -0x1E00  /**< Given private key password does not allow for correct decryption. */
+
+#define MBEDTLS_PKCS12_DERIVE_KEY       1   /**< encryption/decryption key */
+#define MBEDTLS_PKCS12_DERIVE_IV        2   /**< initialization vector     */
+#define MBEDTLS_PKCS12_DERIVE_MAC_KEY   3   /**< integrity / MAC key       */
+
+#define MBEDTLS_PKCS12_PBE_DECRYPT      0
+#define MBEDTLS_PKCS12_PBE_ENCRYPT      1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+
+/**
+ * \brief            PKCS12 Password Based function (encryption / decryption)
+ *                   for pbeWithSHAAnd128BitRC4
+ *
+ * \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure
+ * \param mode       either MBEDTLS_PKCS12_PBE_ENCRYPT or MBEDTLS_PKCS12_PBE_DECRYPT
+ * \param pwd        the password used (may be NULL if no password is used)
+ * \param pwdlen     length of the password (may be 0)
+ * \param input      the input data
+ * \param len        data length
+ * \param output     the output buffer
+ *
+ * \return           0 if successful, or a MBEDTLS_ERR_XXX code
+ */
+int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
+                             const unsigned char *pwd,  size_t pwdlen,
+                             const unsigned char *input, size_t len,
+                             unsigned char *output );
+
+/**
+ * \brief            PKCS12 Password Based function (encryption / decryption)
+ *                   for cipher-based and mbedtls_md-based PBE's
+ *
+ * \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure
+ * \param mode       either MBEDTLS_PKCS12_PBE_ENCRYPT or MBEDTLS_PKCS12_PBE_DECRYPT
+ * \param cipher_type the cipher used
+ * \param md_type     the mbedtls_md used
+ * \param pwd        the password used (may be NULL if no password is used)
+ * \param pwdlen     length of the password (may be 0)
+ * \param input      the input data
+ * \param len        data length
+ * \param output     the output buffer
+ *
+ * \return           0 if successful, or a MBEDTLS_ERR_XXX code
+ */
+int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
+                mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
+                const unsigned char *pwd,  size_t pwdlen,
+                const unsigned char *input, size_t len,
+                unsigned char *output );
+
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
+/**
+ * \brief            The PKCS#12 derivation function uses a password and a salt
+ *                   to produce pseudo-random bits for a particular "purpose".
+ *
+ *                   Depending on the given id, this function can produce an
+ *                   encryption/decryption key, an nitialization vector or an
+ *                   integrity key.
+ *
+ * \param data       buffer to store the derived data in
+ * \param datalen    length to fill
+ * \param pwd        password to use (may be NULL if no password is used)
+ * \param pwdlen     length of the password (may be 0)
+ * \param salt       salt buffer to use
+ * \param saltlen    length of the salt
+ * \param mbedtls_md         mbedtls_md type to use during the derivation
+ * \param id         id that describes the purpose (can be MBEDTLS_PKCS12_DERIVE_KEY,
+ *                   MBEDTLS_PKCS12_DERIVE_IV or MBEDTLS_PKCS12_DERIVE_MAC_KEY)
+ * \param iterations number of iterations
+ *
+ * \return          0 if successful, or a MD, BIGNUM type error.
+ */
+int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
+                       const unsigned char *pwd, size_t pwdlen,
+                       const unsigned char *salt, size_t saltlen,
+                       mbedtls_md_type_t mbedtls_md, int id, int iterations );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pkcs12.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pkcs5.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pkcs5.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/pkcs5.h	(revision 398)
@@ -0,0 +1,109 @@
+/**
+ * \file pkcs5.h
+ *
+ * \brief PKCS#5 functions
+ *
+ * \author Mathias Olsson <mathias@kompetensum.com>
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PKCS5_H
+#define MBEDTLS_PKCS5_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "asn1.h"
+#include "md.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA                  -0x2f80  /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_PKCS5_INVALID_FORMAT                  -0x2f00  /**< Unexpected ASN.1 data. */
+#define MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE             -0x2e80  /**< Requested encryption or digest alg not available. */
+#define MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH               -0x2e00  /**< Given private key password does not allow for correct decryption. */
+
+#define MBEDTLS_PKCS5_DECRYPT      0
+#define MBEDTLS_PKCS5_ENCRYPT      1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+
+/**
+ * \brief          PKCS#5 PBES2 function
+ *
+ * \param pbe_params the ASN.1 algorithm parameters
+ * \param mode       either MBEDTLS_PKCS5_DECRYPT or MBEDTLS_PKCS5_ENCRYPT
+ * \param pwd        password to use when generating key
+ * \param pwdlen     length of password
+ * \param data       data to process
+ * \param datalen    length of data
+ * \param output     output buffer
+ *
+ * \returns        0 on success, or a MBEDTLS_ERR_XXX code if verification fails.
+ */
+int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
+                 const unsigned char *pwd,  size_t pwdlen,
+                 const unsigned char *data, size_t datalen,
+                 unsigned char *output );
+
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
+/**
+ * \brief          PKCS#5 PBKDF2 using HMAC
+ *
+ * \param ctx      Generic HMAC context
+ * \param password Password to use when generating key
+ * \param plen     Length of password
+ * \param salt     Salt to use when generating key
+ * \param slen     Length of salt
+ * \param iteration_count       Iteration count
+ * \param key_length            Length of generated key in bytes
+ * \param output   Generated key. Must be at least as big as key_length
+ *
+ * \returns        0 on success, or a MBEDTLS_ERR_XXX code if verification fails.
+ */
+int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
+                       size_t plen, const unsigned char *salt, size_t slen,
+                       unsigned int iteration_count,
+                       uint32_t key_length, unsigned char *output );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int mbedtls_pkcs5_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* pkcs5.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/platform.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/platform.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/platform.h	(revision 398)
@@ -0,0 +1,367 @@
+/**
+ * \file platform.h
+ *
+ * \brief This file contains the definitions and functions of the
+ *        Mbed TLS platform abstraction layer.
+ *
+ *        The platform abstraction layer removes the need for the library
+ *        to directly link to standard C library functions or operating
+ *        system services, making the library easier to port and embed.
+ *        Application developers and users of the library can provide their own
+ *        implementations of these functions, or implementations specific to
+ *        their platform, which can be statically linked to the library or
+ *        dynamically configured at runtime.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PLATFORM_H
+#define MBEDTLS_PLATFORM_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME)
+#include "platform_time.h"
+#endif
+
+#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED     -0x0070 /**< Hardware accelerator failed */
+#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 /**< The requested feature is not supported by the platform */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
+#if defined(_WIN32)
+#define MBEDTLS_PLATFORM_STD_SNPRINTF   mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use.  */
+#else
+#define MBEDTLS_PLATFORM_STD_SNPRINTF   snprintf /**< The default \c snprintf function to use.  */
+#endif
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
+#define MBEDTLS_PLATFORM_STD_PRINTF   printf /**< The default \c printf function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
+#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
+#define MBEDTLS_PLATFORM_STD_CALLOC   calloc /**< The default \c calloc function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_FREE)
+#define MBEDTLS_PLATFORM_STD_FREE       free /**< The default \c free function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
+#define MBEDTLS_PLATFORM_STD_EXIT      exit /**< The default \c exit function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_TIME)
+#define MBEDTLS_PLATFORM_STD_TIME       time    /**< The default \c time function to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
+#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS  EXIT_SUCCESS /**< The default exit value to use. */
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
+#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE  EXIT_FAILURE /**< The default exit value to use. */
+#endif
+#if defined(MBEDTLS_FS_IO)
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write
+#endif
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE)
+#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE   "seedfile"
+#endif
+#endif /* MBEDTLS_FS_IO */
+#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
+#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
+#include MBEDTLS_PLATFORM_STD_MEM_HDR
+#endif
+#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
+
+
+/* \} name SECTION: Module settings */
+
+/*
+ * The function pointers for calloc and free.
+ */
+#if defined(MBEDTLS_PLATFORM_MEMORY)
+#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \
+    defined(MBEDTLS_PLATFORM_CALLOC_MACRO)
+#define mbedtls_free       MBEDTLS_PLATFORM_FREE_MACRO
+#define mbedtls_calloc     MBEDTLS_PLATFORM_CALLOC_MACRO
+#else
+/* For size_t */
+#include <stddef.h>
+extern void *mbedtls_calloc( size_t n, size_t size );
+extern void mbedtls_free( void *ptr );
+
+/**
+ * \brief               This function dynamically sets the memory-management
+ *                      functions used by the library, during runtime.
+ *
+ * \param calloc_func   The \c calloc function implementation.
+ * \param free_func     The \c free function implementation.
+ *
+ * \return              \c 0.
+ */
+int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
+                              void (*free_func)( void * ) );
+#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */
+#else /* !MBEDTLS_PLATFORM_MEMORY */
+#define mbedtls_free       free
+#define mbedtls_calloc     calloc
+#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */
+
+/*
+ * The function pointers for fprintf
+ */
+#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
+/* We need FILE * */
+#include <stdio.h>
+extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... );
+
+/**
+ * \brief                This function dynamically configures the fprintf
+ *                       function that is called when the
+ *                       mbedtls_fprintf() function is invoked by the library.
+ *
+ * \param fprintf_func   The \c fprintf function implementation.
+ *
+ * \return               \c 0.
+ */
+int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *,
+                                               ... ) );
+#else
+#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO)
+#define mbedtls_fprintf    MBEDTLS_PLATFORM_FPRINTF_MACRO
+#else
+#define mbedtls_fprintf    fprintf
+#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */
+#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
+
+/*
+ * The function pointers for printf
+ */
+#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
+extern int (*mbedtls_printf)( const char *format, ... );
+
+/**
+ * \brief               This function dynamically configures the snprintf
+ *                      function that is called when the mbedtls_snprintf()
+ *                      function is invoked by the library.
+ *
+ * \param printf_func   The \c printf function implementation.
+ *
+ * \return              \c 0 on success.
+ */
+int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) );
+#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO)
+#define mbedtls_printf     MBEDTLS_PLATFORM_PRINTF_MACRO
+#else
+#define mbedtls_printf     printf
+#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */
+#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
+
+/*
+ * The function pointers for snprintf
+ *
+ * The snprintf implementation should conform to C99:
+ * - it *must* always correctly zero-terminate the buffer
+ *   (except when n == 0, then it must leave the buffer untouched)
+ * - however it is acceptable to return -1 instead of the required length when
+ *   the destination buffer is too short.
+ */
+#if defined(_WIN32)
+/* For Windows (inc. MSYS2), we provide our own fixed implementation */
+int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
+#endif
+
+#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
+extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... );
+
+/**
+ * \brief                 This function allows configuring a custom
+ *                        \c snprintf function pointer.
+ *
+ * \param snprintf_func   The \c snprintf function implementation.
+ *
+ * \return                \c 0 on success.
+ */
+int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
+                                                 const char * format, ... ) );
+#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
+#define mbedtls_snprintf   MBEDTLS_PLATFORM_SNPRINTF_MACRO
+#else
+#define mbedtls_snprintf   MBEDTLS_PLATFORM_STD_SNPRINTF
+#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */
+#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+
+/*
+ * The function pointers for exit
+ */
+#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
+extern void (*mbedtls_exit)( int status );
+
+/**
+ * \brief             This function dynamically configures the exit
+ *                    function that is called when the mbedtls_exit()
+ *                    function is invoked by the library.
+ *
+ * \param exit_func   The \c exit function implementation.
+ *
+ * \return            \c 0 on success.
+ */
+int mbedtls_platform_set_exit( void (*exit_func)( int status ) );
+#else
+#if defined(MBEDTLS_PLATFORM_EXIT_MACRO)
+#define mbedtls_exit   MBEDTLS_PLATFORM_EXIT_MACRO
+#else
+#define mbedtls_exit   exit
+#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */
+#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
+
+/*
+ * The default exit values
+ */
+#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS)
+#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS
+#else
+#define MBEDTLS_EXIT_SUCCESS 0
+#endif
+#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE)
+#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE
+#else
+#define MBEDTLS_EXIT_FAILURE 1
+#endif
+
+/*
+ * The function pointers for reading from and writing a seed file to
+ * Non-Volatile storage (NV) in a platform-independent way
+ *
+ * Only enabled when the NV seed entropy source is enabled
+ */
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
+/* Internal standard platform definitions */
+int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len );
+int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len );
+#endif
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len );
+extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len );
+
+/**
+ * \brief   This function allows configuring custom seed file writing and
+ *          reading functions.
+ *
+ * \param   nv_seed_read_func   The seed reading function implementation.
+ * \param   nv_seed_write_func  The seed writing function implementation.
+ *
+ * \return  \c 0 on success.
+ */
+int mbedtls_platform_set_nv_seed(
+            int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
+            int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len )
+            );
+#else
+#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \
+    defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO)
+#define mbedtls_nv_seed_read    MBEDTLS_PLATFORM_NV_SEED_READ_MACRO
+#define mbedtls_nv_seed_write   MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO
+#else
+#define mbedtls_nv_seed_read    mbedtls_platform_std_nv_seed_read
+#define mbedtls_nv_seed_write   mbedtls_platform_std_nv_seed_write
+#endif
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
+#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
+
+/**
+ * \brief   The platform context structure.
+ *
+ * \note    This structure may be used to assist platform-specific
+ *          setup or teardown operations.
+ */
+typedef struct mbedtls_platform_context
+{
+    char dummy; /**< A placeholder member, as empty structs are not portable. */
+}
+mbedtls_platform_context;
+
+#else
+#include "platform_alt.h"
+#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
+
+/**
+ * \brief   This function performs any platform-specific initialization
+ *          operations.
+ *
+ * \note    This function should be called before any other library functions.
+ *
+ *          Its implementation is platform-specific, and unless
+ *          platform-specific code is provided, it does nothing.
+ *
+ * \note    The usage and necessity of this function is dependent on the platform.
+ *
+ * \param   ctx     The platform context.
+ *
+ * \return  \c 0 on success.
+ */
+int mbedtls_platform_setup( mbedtls_platform_context *ctx );
+/**
+ * \brief   This function performs any platform teardown operations.
+ *
+ * \note    This function should be called after every other Mbed TLS module
+ *          has been correctly freed using the appropriate free function.
+ *
+ *          Its implementation is platform-specific, and unless
+ *          platform-specific code is provided, it does nothing.
+ *
+ * \note    The usage and necessity of this function is dependent on the platform.
+ *
+ * \param   ctx     The platform context.
+ *
+ */
+void mbedtls_platform_teardown( mbedtls_platform_context *ctx );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* platform.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/platform_time.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/platform_time.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/platform_time.h	(revision 398)
@@ -0,0 +1,82 @@
+/**
+ * \file platform_time.h
+ *
+ * \brief mbed TLS Platform time abstraction
+ */
+/*
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PLATFORM_TIME_H
+#define MBEDTLS_PLATFORM_TIME_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+/*
+ * The time_t datatype
+ */
+#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO)
+typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t;
+#else
+/* For time_t */
+#include <time.h>
+typedef time_t mbedtls_time_t;
+#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */
+
+/*
+ * The function pointers for time
+ */
+#if defined(MBEDTLS_PLATFORM_TIME_ALT)
+extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time );
+
+/**
+ * \brief   Set your own time function pointer
+ *
+ * \param   time_func   the time function implementation
+ *
+ * \return              0
+ */
+int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) );
+#else
+#if defined(MBEDTLS_PLATFORM_TIME_MACRO)
+#define mbedtls_time    MBEDTLS_PLATFORM_TIME_MACRO
+#else
+#define mbedtls_time   time
+#endif /* MBEDTLS_PLATFORM_TIME_MACRO */
+#endif /* MBEDTLS_PLATFORM_TIME_ALT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* platform_time.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/platform_util.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/platform_util.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/platform_util.h	(revision 398)
@@ -0,0 +1,185 @@
+/**
+ * \file platform_util.h
+ *
+ * \brief Common and shared functions used by multiple modules in the Mbed TLS
+ *        library.
+ */
+/*
+ *  Copyright (C) 2018, Arm Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_PLATFORM_UTIL_H
+#define MBEDTLS_PLATFORM_UTIL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#if defined(MBEDTLS_HAVE_TIME_DATE)
+#include "platform_time.h"
+#include <time.h>
+#endif /* MBEDTLS_HAVE_TIME_DATE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_CHECK_PARAMS)
+
+#if defined(MBEDTLS_PARAM_FAILED)
+/** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h.
+ *
+ * This flag can be used to check whether it is safe to assume that
+ * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed().
+ */
+#define MBEDTLS_PARAM_FAILED_ALT
+#else /* MBEDTLS_PARAM_FAILED */
+#define MBEDTLS_PARAM_FAILED( cond ) \
+    mbedtls_param_failed( #cond, __FILE__, __LINE__ )
+
+/**
+ * \brief       User supplied callback function for parameter validation failure.
+ *              See #MBEDTLS_CHECK_PARAMS for context.
+ *
+ *              This function will be called unless an alternative treatement
+ *              is defined through the #MBEDTLS_PARAM_FAILED macro.
+ *
+ *              This function can return, and the operation will be aborted, or
+ *              alternatively, through use of setjmp()/longjmp() can resume
+ *              execution in the application code.
+ *
+ * \param failure_condition The assertion that didn't hold.
+ * \param file  The file where the assertion failed.
+ * \param line  The line in the file where the assertion failed.
+ */
+void mbedtls_param_failed( const char *failure_condition,
+                           const char *file,
+                           int line );
+#endif /* MBEDTLS_PARAM_FAILED */
+
+/* Internal macro meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret )  \
+    do {                                            \
+        if( !(cond) )                               \
+        {                                           \
+            MBEDTLS_PARAM_FAILED( cond );           \
+            return( ret );                          \
+        }                                           \
+    } while( 0 )
+
+/* Internal macro meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE( cond )           \
+    do {                                            \
+        if( !(cond) )                               \
+        {                                           \
+            MBEDTLS_PARAM_FAILED( cond );           \
+            return;                                 \
+        }                                           \
+    } while( 0 )
+
+#else /* MBEDTLS_CHECK_PARAMS */
+
+/* Internal macros meant to be called only from within the library. */
+#define MBEDTLS_INTERNAL_VALIDATE_RET( cond, ret )  do { } while( 0 )
+#define MBEDTLS_INTERNAL_VALIDATE( cond )           do { } while( 0 )
+
+#endif /* MBEDTLS_CHECK_PARAMS */
+
+/* Internal helper macros for deprecating API constants. */
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+/* Deliberately don't (yet) export MBEDTLS_DEPRECATED here
+ * to avoid conflict with other headers which define and use
+ * it, too. We might want to move all these definitions here at
+ * some point for uniformity. */
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+MBEDTLS_DEPRECATED typedef char const * mbedtls_deprecated_string_constant_t;
+#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL )       \
+    ( (mbedtls_deprecated_string_constant_t) ( VAL ) )
+MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
+#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL )       \
+    ( (mbedtls_deprecated_numeric_constant_t) ( VAL ) )
+#undef MBEDTLS_DEPRECATED
+#else /* MBEDTLS_DEPRECATED_WARNING */
+#define MBEDTLS_DEPRECATED_STRING_CONSTANT( VAL ) VAL
+#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( VAL ) VAL
+#endif /* MBEDTLS_DEPRECATED_WARNING */
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief       Securely zeroize a buffer
+ *
+ *              The function is meant to wipe the data contained in a buffer so
+ *              that it can no longer be recovered even if the program memory
+ *              is later compromised. Call this function on sensitive data
+ *              stored on the stack before returning from a function, and on
+ *              sensitive data stored on the heap before freeing the heap
+ *              object.
+ *
+ *              It is extremely difficult to guarantee that calls to
+ *              mbedtls_platform_zeroize() are not removed by aggressive
+ *              compiler optimizations in a portable way. For this reason, Mbed
+ *              TLS provides the configuration option
+ *              MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
+ *              mbedtls_platform_zeroize() to use a suitable implementation for
+ *              their platform and needs
+ *
+ * \param buf   Buffer to be zeroized
+ * \param len   Length of the buffer in bytes
+ *
+ */
+void mbedtls_platform_zeroize( void *buf, size_t len );
+
+#if defined(MBEDTLS_HAVE_TIME_DATE)
+/**
+ * \brief      Platform-specific implementation of gmtime_r()
+ *
+ *             The function is a thread-safe abstraction that behaves
+ *             similarly to the gmtime_r() function from Unix/POSIX.
+ *
+ *             Mbed TLS will try to identify the underlying platform and
+ *             make use of an appropriate underlying implementation (e.g.
+ *             gmtime_r() for POSIX and gmtime_s() for Windows). If this is
+ *             not possible, then gmtime() will be used. In this case, calls
+ *             from the library to gmtime() will be guarded by the mutex
+ *             mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is
+ *             enabled. It is recommended that calls from outside the library
+ *             are also guarded by this mutex.
+ *
+ *             If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will
+ *             unconditionally use the alternative implementation for
+ *             mbedtls_platform_gmtime_r() supplied by the user at compile time.
+ *
+ * \param tt     Pointer to an object containing time (in seconds) since the
+ *               epoch to be converted
+ * \param tm_buf Pointer to an object where the results will be stored
+ *
+ * \return      Pointer to an object of type struct tm on success, otherwise
+ *              NULL
+ */
+struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
+                                      struct tm *tm_buf );
+#endif /* MBEDTLS_HAVE_TIME_DATE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_PLATFORM_UTIL_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/poly1305.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/poly1305.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/poly1305.h	(revision 398)
@@ -0,0 +1,192 @@
+/**
+ * \file poly1305.h
+ *
+ * \brief   This file contains Poly1305 definitions and functions.
+ *
+ *          Poly1305 is a one-time message authenticator that can be used to
+ *          authenticate messages. Poly1305-AES was created by Daniel
+ *          Bernstein https://cr.yp.to/mac/poly1305-20050329.pdf The generic
+ *          Poly1305 algorithm (not tied to AES) was also standardized in RFC
+ *          7539.
+ *
+ * \author Daniel King <damaki.gh@gmail.com>
+ */
+
+/*  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_POLY1305_H
+#define MBEDTLS_POLY1305_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA         -0x0057 /**< Invalid input parameter(s). */
+
+/* MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE is deprecated and should not be
+ * used. */
+#define MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE    -0x0059 /**< Feature not available. For example, s part of the API is not implemented. */
+
+/* MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED        -0x005B  /**< Poly1305 hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_POLY1305_ALT)
+
+typedef struct mbedtls_poly1305_context
+{
+    uint32_t r[4];      /** The value for 'r' (low 128 bits of the key). */
+    uint32_t s[4];      /** The value for 's' (high 128 bits of the key). */
+    uint32_t acc[5];    /** The accumulator number. */
+    uint8_t queue[16];  /** The current partial block of data. */
+    size_t queue_len;   /** The number of bytes stored in 'queue'. */
+}
+mbedtls_poly1305_context;
+
+#else  /* MBEDTLS_POLY1305_ALT */
+#include "poly1305_alt.h"
+#endif /* MBEDTLS_POLY1305_ALT */
+
+/**
+ * \brief           This function initializes the specified Poly1305 context.
+ *
+ *                  It must be the first API called before using
+ *                  the context.
+ *
+ *                  It is usually followed by a call to
+ *                  \c mbedtls_poly1305_starts(), then one or more calls to
+ *                  \c mbedtls_poly1305_update(), then one call to
+ *                  \c mbedtls_poly1305_finish(), then finally
+ *                  \c mbedtls_poly1305_free().
+ *
+ * \param ctx       The Poly1305 context to initialize. This must
+ *                  not be \c NULL.
+ */
+void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx );
+
+/**
+ * \brief           This function releases and clears the specified
+ *                  Poly1305 context.
+ *
+ * \param ctx       The Poly1305 context to clear. This may be \c NULL, in which
+ *                  case this function is a no-op. If it is not \c NULL, it must
+ *                  point to an initialized Poly1305 context.
+ */
+void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx );
+
+/**
+ * \brief           This function sets the one-time authentication key.
+ *
+ * \warning         The key must be unique and unpredictable for each
+ *                  invocation of Poly1305.
+ *
+ * \param ctx       The Poly1305 context to which the key should be bound.
+ *                  This must be initialized.
+ * \param key       The buffer containing the \c 32 Byte (\c 256 Bit) key.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
+                             const unsigned char key[32] );
+
+/**
+ * \brief           This functions feeds an input buffer into an ongoing
+ *                  Poly1305 computation.
+ *
+ *                  It is called between \c mbedtls_cipher_poly1305_starts() and
+ *                  \c mbedtls_cipher_poly1305_finish().
+ *                  It can be called repeatedly to process a stream of data.
+ *
+ * \param ctx       The Poly1305 context to use for the Poly1305 operation.
+ *                  This must be initialized and bound to a key.
+ * \param ilen      The length of the input data in Bytes.
+ *                  Any value is accepted.
+ * \param input     The buffer holding the input data.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
+                             const unsigned char *input,
+                             size_t ilen );
+
+/**
+ * \brief           This function generates the Poly1305 Message
+ *                  Authentication Code (MAC).
+ *
+ * \param ctx       The Poly1305 context to use for the Poly1305 operation.
+ *                  This must be initialized and bound to a key.
+ * \param mac       The buffer to where the MAC is written. This must
+ *                  be a writable buffer of length \c 16 Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
+                             unsigned char mac[16] );
+
+/**
+ * \brief           This function calculates the Poly1305 MAC of the input
+ *                  buffer with the provided key.
+ *
+ * \warning         The key must be unique and unpredictable for each
+ *                  invocation of Poly1305.
+ *
+ * \param key       The buffer containing the \c 32 Byte (\c 256 Bit) key.
+ * \param ilen      The length of the input data in Bytes.
+ *                  Any value is accepted.
+ * \param input     The buffer holding the input data.
+ *                  This pointer can be \c NULL if `ilen == 0`.
+ * \param mac       The buffer to where the MAC is written. This must be
+ *                  a writable buffer of length \c 16 Bytes.
+ *
+ * \return          \c 0 on success.
+ * \return          A negative error code on failure.
+ */
+int mbedtls_poly1305_mac( const unsigned char key[32],
+                          const unsigned char *input,
+                          size_t ilen,
+                          unsigned char mac[16] );
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief           The Poly1305 checkup routine.
+ *
+ * \return          \c 0 on success.
+ * \return          \c 1 on failure.
+ */
+int mbedtls_poly1305_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_POLY1305_H */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ripemd160.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ripemd160.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ripemd160.h	(revision 398)
@@ -0,0 +1,237 @@
+/**
+ * \file ripemd160.h
+ *
+ * \brief RIPE MD-160 message digest
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_RIPEMD160_H
+#define MBEDTLS_RIPEMD160_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED             -0x0031  /**< RIPEMD160 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_RIPEMD160_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          RIPEMD-160 context structure
+ */
+typedef struct mbedtls_ripemd160_context
+{
+    uint32_t total[2];          /*!< number of bytes processed  */
+    uint32_t state[5];          /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+}
+mbedtls_ripemd160_context;
+
+#else  /* MBEDTLS_RIPEMD160_ALT */
+#include "ripemd160.h"
+#endif /* MBEDTLS_RIPEMD160_ALT */
+
+/**
+ * \brief          Initialize RIPEMD-160 context
+ *
+ * \param ctx      RIPEMD-160 context to be initialized
+ */
+void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx );
+
+/**
+ * \brief          Clear RIPEMD-160 context
+ *
+ * \param ctx      RIPEMD-160 context to be cleared
+ */
+void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx );
+
+/**
+ * \brief          Clone (the state of) an RIPEMD-160 context
+ *
+ * \param dst      The destination context
+ * \param src      The context to be cloned
+ */
+void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
+                        const mbedtls_ripemd160_context *src );
+
+/**
+ * \brief          RIPEMD-160 context setup
+ *
+ * \param ctx      context to be initialized
+ *
+ * \return         0 if successful
+ */
+int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_context *ctx );
+
+/**
+ * \brief          RIPEMD-160 process buffer
+ *
+ * \param ctx      RIPEMD-160 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ *
+ * \return         0 if successful
+ */
+int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
+                                  const unsigned char *input,
+                                  size_t ilen );
+
+/**
+ * \brief          RIPEMD-160 final digest
+ *
+ * \param ctx      RIPEMD-160 context
+ * \param output   RIPEMD-160 checksum result
+ *
+ * \return         0 if successful
+ */
+int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
+                                  unsigned char output[20] );
+
+/**
+ * \brief          RIPEMD-160 process data block (internal use only)
+ *
+ * \param ctx      RIPEMD-160 context
+ * \param data     buffer holding one block of data
+ *
+ * \return         0 if successful
+ */
+int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
+                                        const unsigned char data[64] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          RIPEMD-160 context setup
+ *
+ * \deprecated     Superseded by mbedtls_ripemd160_starts_ret() in 2.7.0
+ *
+ * \param ctx      context to be initialized
+ */
+MBEDTLS_DEPRECATED void mbedtls_ripemd160_starts(
+                                            mbedtls_ripemd160_context *ctx );
+
+/**
+ * \brief          RIPEMD-160 process buffer
+ *
+ * \deprecated     Superseded by mbedtls_ripemd160_update_ret() in 2.7.0
+ *
+ * \param ctx      RIPEMD-160 context
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ */
+MBEDTLS_DEPRECATED void mbedtls_ripemd160_update(
+                                                mbedtls_ripemd160_context *ctx,
+                                                const unsigned char *input,
+                                                size_t ilen );
+
+/**
+ * \brief          RIPEMD-160 final digest
+ *
+ * \deprecated     Superseded by mbedtls_ripemd160_finish_ret() in 2.7.0
+ *
+ * \param ctx      RIPEMD-160 context
+ * \param output   RIPEMD-160 checksum result
+ */
+MBEDTLS_DEPRECATED void mbedtls_ripemd160_finish(
+                                                mbedtls_ripemd160_context *ctx,
+                                                unsigned char output[20] );
+
+/**
+ * \brief          RIPEMD-160 process data block (internal use only)
+ *
+ * \deprecated     Superseded by mbedtls_internal_ripemd160_process() in 2.7.0
+ *
+ * \param ctx      RIPEMD-160 context
+ * \param data     buffer holding one block of data
+ */
+MBEDTLS_DEPRECATED void mbedtls_ripemd160_process(
+                                            mbedtls_ripemd160_context *ctx,
+                                            const unsigned char data[64] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          Output = RIPEMD-160( input buffer )
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   RIPEMD-160 checksum result
+ *
+ * \return         0 if successful
+ */
+int mbedtls_ripemd160_ret( const unsigned char *input,
+                           size_t ilen,
+                           unsigned char output[20] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          Output = RIPEMD-160( input buffer )
+ *
+ * \deprecated     Superseded by mbedtls_ripemd160_ret() in 2.7.0
+ *
+ * \param input    buffer holding the data
+ * \param ilen     length of the input data
+ * \param output   RIPEMD-160 checksum result
+ */
+MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input,
+                                           size_t ilen,
+                                           unsigned char output[20] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int mbedtls_ripemd160_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_ripemd160.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/rsa.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/rsa.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/rsa.h	(revision 398)
@@ -0,0 +1,1271 @@
+/**
+ * \file rsa.h
+ *
+ * \brief This file provides an API for the RSA public-key cryptosystem.
+ *
+ * The RSA public-key cryptosystem is defined in <em>Public-Key
+ * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption</em>
+ * and <em>Public-Key Cryptography Standards (PKCS) #1 v2.1:
+ * RSA Cryptography Specifications</em>.
+ *
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_RSA_H
+#define MBEDTLS_RSA_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "bignum.h"
+#include "md.h"
+
+#if defined(MBEDTLS_THREADING_C)
+#include "threading.h"
+#endif
+
+/*
+ * RSA Error codes
+ */
+#define MBEDTLS_ERR_RSA_BAD_INPUT_DATA                    -0x4080  /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_RSA_INVALID_PADDING                   -0x4100  /**< Input data contains invalid padding and is rejected. */
+#define MBEDTLS_ERR_RSA_KEY_GEN_FAILED                    -0x4180  /**< Something failed during generation of a key. */
+#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED                  -0x4200  /**< Key failed to pass the validity check of the library. */
+#define MBEDTLS_ERR_RSA_PUBLIC_FAILED                     -0x4280  /**< The public key operation failed. */
+#define MBEDTLS_ERR_RSA_PRIVATE_FAILED                    -0x4300  /**< The private key operation failed. */
+#define MBEDTLS_ERR_RSA_VERIFY_FAILED                     -0x4380  /**< The PKCS#1 verification failed. */
+#define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE                  -0x4400  /**< The output buffer for decryption is not large enough. */
+#define MBEDTLS_ERR_RSA_RNG_FAILED                        -0x4480  /**< The random generator failed to generate non-zeros. */
+
+/* MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION is deprecated and should not be used.
+ */
+#define MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION             -0x4500  /**< The implementation does not offer the requested operation, for example, because of security violations or lack of functionality. */
+
+/* MBEDTLS_ERR_RSA_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_RSA_HW_ACCEL_FAILED                   -0x4580  /**< RSA hardware accelerator failed. */
+
+/*
+ * RSA constants
+ */
+#define MBEDTLS_RSA_PUBLIC      0 /**< Request private key operation. */
+#define MBEDTLS_RSA_PRIVATE     1 /**< Request public key operation. */
+
+#define MBEDTLS_RSA_PKCS_V15    0 /**< Use PKCS#1 v1.5 encoding. */
+#define MBEDTLS_RSA_PKCS_V21    1 /**< Use PKCS#1 v2.1 encoding. */
+
+#define MBEDTLS_RSA_SIGN        1 /**< Identifier for RSA signature operations. */
+#define MBEDTLS_RSA_CRYPT       2 /**< Identifier for RSA encryption and decryption operations. */
+
+#define MBEDTLS_RSA_SALT_LEN_ANY    -1
+
+/*
+ * The above constants may be used even if the RSA module is compile out,
+ * eg for alternative (PKCS#11) RSA implemenations in the PK layers.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_RSA_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief   The RSA context structure.
+ *
+ * \note    Direct manipulation of the members of this structure
+ *          is deprecated. All manipulation should instead be done through
+ *          the public interface functions.
+ */
+typedef struct mbedtls_rsa_context
+{
+    int ver;                    /*!<  Always 0.*/
+    size_t len;                 /*!<  The size of \p N in Bytes. */
+
+    mbedtls_mpi N;              /*!<  The public modulus. */
+    mbedtls_mpi E;              /*!<  The public exponent. */
+
+    mbedtls_mpi D;              /*!<  The private exponent. */
+    mbedtls_mpi P;              /*!<  The first prime factor. */
+    mbedtls_mpi Q;              /*!<  The second prime factor. */
+
+    mbedtls_mpi DP;             /*!<  <code>D % (P - 1)</code>. */
+    mbedtls_mpi DQ;             /*!<  <code>D % (Q - 1)</code>. */
+    mbedtls_mpi QP;             /*!<  <code>1 / (Q % P)</code>. */
+
+    mbedtls_mpi RN;             /*!<  cached <code>R^2 mod N</code>. */
+
+    mbedtls_mpi RP;             /*!<  cached <code>R^2 mod P</code>. */
+    mbedtls_mpi RQ;             /*!<  cached <code>R^2 mod Q</code>. */
+
+    mbedtls_mpi Vi;             /*!<  The cached blinding value. */
+    mbedtls_mpi Vf;             /*!<  The cached un-blinding value. */
+
+    int padding;                /*!< Selects padding mode:
+                                     #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and
+                                     #MBEDTLS_RSA_PKCS_V21 for OAEP or PSS. */
+    int hash_id;                /*!< Hash identifier of mbedtls_md_type_t type,
+                                     as specified in md.h for use in the MGF
+                                     mask generating function used in the
+                                     EME-OAEP and EMSA-PSS encodings. */
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;    /*!<  Thread-safety mutex. */
+#endif
+}
+mbedtls_rsa_context;
+
+#else  /* MBEDTLS_RSA_ALT */
+#include "rsa_alt.h"
+#endif /* MBEDTLS_RSA_ALT */
+
+/**
+ * \brief          This function initializes an RSA context.
+ *
+ * \note           Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP
+ *                 encryption scheme and the RSASSA-PSS signature scheme.
+ *
+ * \note           The \p hash_id parameter is ignored when using
+ *                 #MBEDTLS_RSA_PKCS_V15 padding.
+ *
+ * \note           The choice of padding mode is strictly enforced for private key
+ *                 operations, since there might be security concerns in
+ *                 mixing padding modes. For public key operations it is
+ *                 a default value, which can be overriden by calling specific
+ *                 \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions.
+ *
+ * \note           The hash selected in \p hash_id is always used for OEAP
+ *                 encryption. For PSS signatures, it is always used for
+ *                 making signatures, but can be overriden for verifying them.
+ *                 If set to #MBEDTLS_MD_NONE, it is always overriden.
+ *
+ * \param ctx      The RSA context to initialize. This must not be \c NULL.
+ * \param padding  The padding mode to use. This must be either
+ *                 #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21.
+ * \param hash_id  The hash identifier of ::mbedtls_md_type_t type, if
+ *                 \p padding is #MBEDTLS_RSA_PKCS_V21. It is unused
+ *                 otherwise.
+ */
+void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
+                       int padding,
+                       int hash_id );
+
+/**
+ * \brief          This function imports a set of core parameters into an
+ *                 RSA context.
+ *
+ * \note           This function can be called multiple times for successive
+ *                 imports, if the parameters are not simultaneously present.
+ *
+ *                 Any sequence of calls to this function should be followed
+ *                 by a call to mbedtls_rsa_complete(), which checks and
+ *                 completes the provided information to a ready-for-use
+ *                 public or private RSA key.
+ *
+ * \note           See mbedtls_rsa_complete() for more information on which
+ *                 parameters are necessary to set up a private or public
+ *                 RSA key.
+ *
+ * \note           The imported parameters are copied and need not be preserved
+ *                 for the lifetime of the RSA context being set up.
+ *
+ * \param ctx      The initialized RSA context to store the parameters in.
+ * \param N        The RSA modulus. This may be \c NULL.
+ * \param P        The first prime factor of \p N. This may be \c NULL.
+ * \param Q        The second prime factor of \p N. This may be \c NULL.
+ * \param D        The private exponent. This may be \c NULL.
+ * \param E        The public exponent. This may be \c NULL.
+ *
+ * \return         \c 0 on success.
+ * \return         A non-zero error code on failure.
+ */
+int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
+                        const mbedtls_mpi *N,
+                        const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                        const mbedtls_mpi *D, const mbedtls_mpi *E );
+
+/**
+ * \brief          This function imports core RSA parameters, in raw big-endian
+ *                 binary format, into an RSA context.
+ *
+ * \note           This function can be called multiple times for successive
+ *                 imports, if the parameters are not simultaneously present.
+ *
+ *                 Any sequence of calls to this function should be followed
+ *                 by a call to mbedtls_rsa_complete(), which checks and
+ *                 completes the provided information to a ready-for-use
+ *                 public or private RSA key.
+ *
+ * \note           See mbedtls_rsa_complete() for more information on which
+ *                 parameters are necessary to set up a private or public
+ *                 RSA key.
+ *
+ * \note           The imported parameters are copied and need not be preserved
+ *                 for the lifetime of the RSA context being set up.
+ *
+ * \param ctx      The initialized RSA context to store the parameters in.
+ * \param N        The RSA modulus. This may be \c NULL.
+ * \param N_len    The Byte length of \p N; it is ignored if \p N == NULL.
+ * \param P        The first prime factor of \p N. This may be \c NULL.
+ * \param P_len    The Byte length of \p P; it ns ignored if \p P == NULL.
+ * \param Q        The second prime factor of \p N. This may be \c NULL.
+ * \param Q_len    The Byte length of \p Q; it is ignored if \p Q == NULL.
+ * \param D        The private exponent. This may be \c NULL.
+ * \param D_len    The Byte length of \p D; it is ignored if \p D == NULL.
+ * \param E        The public exponent. This may be \c NULL.
+ * \param E_len    The Byte length of \p E; it is ignored if \p E == NULL.
+ *
+ * \return         \c 0 on success.
+ * \return         A non-zero error code on failure.
+ */
+int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
+                            unsigned char const *N, size_t N_len,
+                            unsigned char const *P, size_t P_len,
+                            unsigned char const *Q, size_t Q_len,
+                            unsigned char const *D, size_t D_len,
+                            unsigned char const *E, size_t E_len );
+
+/**
+ * \brief          This function completes an RSA context from
+ *                 a set of imported core parameters.
+ *
+ *                 To setup an RSA public key, precisely \p N and \p E
+ *                 must have been imported.
+ *
+ *                 To setup an RSA private key, sufficient information must
+ *                 be present for the other parameters to be derivable.
+ *
+ *                 The default implementation supports the following:
+ *                 <ul><li>Derive \p P, \p Q from \p N, \p D, \p E.</li>
+ *                 <li>Derive \p N, \p D from \p P, \p Q, \p E.</li></ul>
+ *                 Alternative implementations need not support these.
+ *
+ *                 If this function runs successfully, it guarantees that
+ *                 the RSA context can be used for RSA operations without
+ *                 the risk of failure or crash.
+ *
+ * \warning        This function need not perform consistency checks
+ *                 for the imported parameters. In particular, parameters that
+ *                 are not needed by the implementation might be silently
+ *                 discarded and left unchecked. To check the consistency
+ *                 of the key material, see mbedtls_rsa_check_privkey().
+ *
+ * \param ctx      The initialized RSA context holding imported parameters.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted derivations
+ *                 failed.
+ *
+ */
+int mbedtls_rsa_complete( mbedtls_rsa_context *ctx );
+
+/**
+ * \brief          This function exports the core parameters of an RSA key.
+ *
+ *                 If this function runs successfully, the non-NULL buffers
+ *                 pointed to by \p N, \p P, \p Q, \p D, and \p E are fully
+ *                 written, with additional unused space filled leading by
+ *                 zero Bytes.
+ *
+ *                 Possible reasons for returning
+ *                 #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:<ul>
+ *                 <li>An alternative RSA implementation is in use, which
+ *                 stores the key externally, and either cannot or should
+ *                 not export it into RAM.</li>
+ *                 <li>A SW or HW implementation might not support a certain
+ *                 deduction. For example, \p P, \p Q from \p N, \p D,
+ *                 and \p E if the former are not part of the
+ *                 implementation.</li></ul>
+ *
+ *                 If the function fails due to an unsupported operation,
+ *                 the RSA context stays intact and remains usable.
+ *
+ * \param ctx      The initialized RSA context.
+ * \param N        The MPI to hold the RSA modulus.
+ *                 This may be \c NULL if this field need not be exported.
+ * \param P        The MPI to hold the first prime factor of \p N.
+ *                 This may be \c NULL if this field need not be exported.
+ * \param Q        The MPI to hold the second prime factor of \p N.
+ *                 This may be \c NULL if this field need not be exported.
+ * \param D        The MPI to hold the private exponent.
+ *                 This may be \c NULL if this field need not be exported.
+ * \param E        The MPI to hold the public exponent.
+ *                 This may be \c NULL if this field need not be exported.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the
+ *                 requested parameters cannot be done due to missing
+ *                 functionality or because of security policies.
+ * \return         A non-zero return code on any other failure.
+ *
+ */
+int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
+                        mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
+                        mbedtls_mpi *D, mbedtls_mpi *E );
+
+/**
+ * \brief          This function exports core parameters of an RSA key
+ *                 in raw big-endian binary format.
+ *
+ *                 If this function runs successfully, the non-NULL buffers
+ *                 pointed to by \p N, \p P, \p Q, \p D, and \p E are fully
+ *                 written, with additional unused space filled leading by
+ *                 zero Bytes.
+ *
+ *                 Possible reasons for returning
+ *                 #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:<ul>
+ *                 <li>An alternative RSA implementation is in use, which
+ *                 stores the key externally, and either cannot or should
+ *                 not export it into RAM.</li>
+ *                 <li>A SW or HW implementation might not support a certain
+ *                 deduction. For example, \p P, \p Q from \p N, \p D,
+ *                 and \p E if the former are not part of the
+ *                 implementation.</li></ul>
+ *                 If the function fails due to an unsupported operation,
+ *                 the RSA context stays intact and remains usable.
+ *
+ * \note           The length parameters are ignored if the corresponding
+ *                 buffer pointers are NULL.
+ *
+ * \param ctx      The initialized RSA context.
+ * \param N        The Byte array to store the RSA modulus,
+ *                 or \c NULL if this field need not be exported.
+ * \param N_len    The size of the buffer for the modulus.
+ * \param P        The Byte array to hold the first prime factor of \p N,
+ *                 or \c NULL if this field need not be exported.
+ * \param P_len    The size of the buffer for the first prime factor.
+ * \param Q        The Byte array to hold the second prime factor of \p N,
+ *                 or \c NULL if this field need not be exported.
+ * \param Q_len    The size of the buffer for the second prime factor.
+ * \param D        The Byte array to hold the private exponent,
+ *                 or \c NULL if this field need not be exported.
+ * \param D_len    The size of the buffer for the private exponent.
+ * \param E        The Byte array to hold the public exponent,
+ *                 or \c NULL if this field need not be exported.
+ * \param E_len    The size of the buffer for the public exponent.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the
+ *                 requested parameters cannot be done due to missing
+ *                 functionality or because of security policies.
+ * \return         A non-zero return code on any other failure.
+ */
+int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
+                            unsigned char *N, size_t N_len,
+                            unsigned char *P, size_t P_len,
+                            unsigned char *Q, size_t Q_len,
+                            unsigned char *D, size_t D_len,
+                            unsigned char *E, size_t E_len );
+
+/**
+ * \brief          This function exports CRT parameters of a private RSA key.
+ *
+ * \note           Alternative RSA implementations not using CRT-parameters
+ *                 internally can implement this function based on
+ *                 mbedtls_rsa_deduce_opt().
+ *
+ * \param ctx      The initialized RSA context.
+ * \param DP       The MPI to hold \c D modulo `P-1`,
+ *                 or \c NULL if it need not be exported.
+ * \param DQ       The MPI to hold \c D modulo `Q-1`,
+ *                 or \c NULL if it need not be exported.
+ * \param QP       The MPI to hold modular inverse of \c Q modulo \c P,
+ *                 or \c NULL if it need not be exported.
+ *
+ * \return         \c 0 on success.
+ * \return         A non-zero error code on failure.
+ *
+ */
+int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
+                            mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP );
+
+/**
+ * \brief          This function sets padding for an already initialized RSA
+ *                 context. See mbedtls_rsa_init() for details.
+ *
+ * \param ctx      The initialized RSA context to be configured.
+ * \param padding  The padding mode to use. This must be either
+ *                 #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21.
+ * \param hash_id  The #MBEDTLS_RSA_PKCS_V21 hash identifier.
+ */
+void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
+                              int hash_id );
+
+/**
+ * \brief          This function retrieves the length of RSA modulus in Bytes.
+ *
+ * \param ctx      The initialized RSA context.
+ *
+ * \return         The length of the RSA modulus in Bytes.
+ *
+ */
+size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx );
+
+/**
+ * \brief          This function generates an RSA keypair.
+ *
+ * \note           mbedtls_rsa_init() must be called before this function,
+ *                 to set up the RSA context.
+ *
+ * \param ctx      The initialized RSA context used to hold the key.
+ * \param f_rng    The RNG function to be used for key generation.
+ *                 This must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng.
+ *                 This may be \c NULL if \p f_rng doesn't need a context.
+ * \param nbits    The size of the public key in bits.
+ * \param exponent The public exponent to use. For example, \c 65537.
+ *                 This must be odd and greater than \c 1.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng,
+                         unsigned int nbits, int exponent );
+
+/**
+ * \brief          This function checks if a context contains at least an RSA
+ *                 public key.
+ *
+ *                 If the function runs successfully, it is guaranteed that
+ *                 enough information is present to perform an RSA public key
+ *                 operation using mbedtls_rsa_public().
+ *
+ * \param ctx      The initialized RSA context to check.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ *
+ */
+int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx );
+
+/**
+ * \brief      This function checks if a context contains an RSA private key
+ *             and perform basic consistency checks.
+ *
+ * \note       The consistency checks performed by this function not only
+ *             ensure that mbedtls_rsa_private() can be called successfully
+ *             on the given context, but that the various parameters are
+ *             mutually consistent with high probability, in the sense that
+ *             mbedtls_rsa_public() and mbedtls_rsa_private() are inverses.
+ *
+ * \warning    This function should catch accidental misconfigurations
+ *             like swapping of parameters, but it cannot establish full
+ *             trust in neither the quality nor the consistency of the key
+ *             material that was used to setup the given RSA context:
+ *             <ul><li>Consistency: Imported parameters that are irrelevant
+ *             for the implementation might be silently dropped. If dropped,
+ *             the current function does not have access to them,
+ *             and therefore cannot check them. See mbedtls_rsa_complete().
+ *             If you want to check the consistency of the entire
+ *             content of an PKCS1-encoded RSA private key, for example, you
+ *             should use mbedtls_rsa_validate_params() before setting
+ *             up the RSA context.
+ *             Additionally, if the implementation performs empirical checks,
+ *             these checks substantiate but do not guarantee consistency.</li>
+ *             <li>Quality: This function is not expected to perform
+ *             extended quality assessments like checking that the prime
+ *             factors are safe. Additionally, it is the responsibility of the
+ *             user to ensure the trustworthiness of the source of his RSA
+ *             parameters, which goes beyond what is effectively checkable
+ *             by the library.</li></ul>
+ *
+ * \param ctx  The initialized RSA context to check.
+ *
+ * \return     \c 0 on success.
+ * \return     An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx );
+
+/**
+ * \brief          This function checks a public-private RSA key pair.
+ *
+ *                 It checks each of the contexts, and makes sure they match.
+ *
+ * \param pub      The initialized RSA context holding the public key.
+ * \param prv      The initialized RSA context holding the private key.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
+                                const mbedtls_rsa_context *prv );
+
+/**
+ * \brief          This function performs an RSA public key operation.
+ *
+ * \param ctx      The initialized RSA context to use.
+ * \param input    The input buffer. This must be a readable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ * \param output   The output buffer. This must be a writable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \note           This function does not handle message padding.
+ *
+ * \note           Make sure to set \p input[0] = 0 or ensure that
+ *                 input is smaller than \p N.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
+                const unsigned char *input,
+                unsigned char *output );
+
+/**
+ * \brief          This function performs an RSA private key operation.
+ *
+ * \note           Blinding is used if and only if a PRNG is provided.
+ *
+ * \note           If blinding is used, both the base of exponentation
+ *                 and the exponent are blinded, providing protection
+ *                 against some side-channel attacks.
+ *
+ * \warning        It is deprecated and a security risk to not provide
+ *                 a PRNG here and thereby prevent the use of blinding.
+ *                 Future versions of the library may enforce the presence
+ *                 of a PRNG.
+ *
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function, used for blinding. It is discouraged
+ *                 and deprecated to pass \c NULL here, in which case
+ *                 blinding will be omitted.
+ * \param p_rng    The RNG context to pass to \p f_rng. This may be \c NULL
+ *                 if \p f_rng is \c NULL or if \p f_rng doesn't need a context.
+ * \param input    The input buffer. This must be a readable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ * \param output   The output buffer. This must be a writable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ *
+ */
+int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng,
+                 const unsigned char *input,
+                 unsigned char *output );
+
+/**
+ * \brief          This function adds the message padding, then performs an RSA
+ *                 operation.
+ *
+ *                 It is the generic wrapper for performing a PKCS#1 encryption
+ *                 operation using the \p mode from the context.
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 implicitly set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG to use. It is mandatory for PKCS#1 v2.1 padding
+ *                 encoding, and for PKCS#1 v1.5 padding encoding when used
+ *                 with \p mode set to #MBEDTLS_RSA_PUBLIC. For PKCS#1 v1.5
+ *                 padding encoding and \p mode set to #MBEDTLS_RSA_PRIVATE,
+ *                 it is used for blinding and should be provided in this
+ *                 case; see mbedtls_rsa_private() for more.
+ * \param p_rng    The RNG context to be passed to \p f_rng. May be
+ *                 \c NULL if \p f_rng is \c NULL or if \p f_rng doesn't
+ *                 need a context argument.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
+ * \param ilen     The length of the plaintext in Bytes.
+ * \param input    The input data to encrypt. This must be a readable
+ *                 buffer of size \p ilen Bytes. This must not be \c NULL.
+ * \param output   The output buffer. This must be a writable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng,
+                       int mode, size_t ilen,
+                       const unsigned char *input,
+                       unsigned char *output );
+
+/**
+ * \brief          This function performs a PKCS#1 v1.5 encryption operation
+ *                 (RSAES-PKCS1-v1_5-ENCRYPT).
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 implicitly set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function to use. It is needed for padding generation
+ *                 if \p mode is #MBEDTLS_RSA_PUBLIC. If \p mode is
+ *                 #MBEDTLS_RSA_PRIVATE (discouraged), it is used for
+ *                 blinding and should be provided; see mbedtls_rsa_private().
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may
+ *                 be \c NULL if \p f_rng is \c NULL or if \p f_rng
+ *                 doesn't need a context argument.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
+ * \param ilen     The length of the plaintext in Bytes.
+ * \param input    The input data to encrypt. This must be a readable
+ *                 buffer of size \p ilen Bytes. This must not be \c NULL.
+ * \param output   The output buffer. This must be a writable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode, size_t ilen,
+                                 const unsigned char *input,
+                                 unsigned char *output );
+
+/**
+ * \brief            This function performs a PKCS#1 v2.1 OAEP encryption
+ *                   operation (RSAES-OAEP-ENCRYPT).
+ *
+ * \note             The output buffer must be as large as the size
+ *                   of ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \deprecated       It is deprecated and discouraged to call this function
+ *                   in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
+ *                   are likely to remove the \p mode argument and have it
+ *                   implicitly set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note             Alternative implementations of RSA need not support
+ *                   mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                   return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx        The initnialized RSA context to use.
+ * \param f_rng      The RNG function to use. This is needed for padding
+ *                   generation and must be provided.
+ * \param p_rng      The RNG context to be passed to \p f_rng. This may
+ *                   be \c NULL if \p f_rng doesn't need a context argument.
+ * \param mode       The mode of operation. This must be either
+ *                   #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
+ * \param label      The buffer holding the custom label to use.
+ *                   This must be a readable buffer of length \p label_len
+ *                   Bytes. It may be \c NULL if \p label_len is \c 0.
+ * \param label_len  The length of the label in Bytes.
+ * \param ilen       The length of the plaintext buffer \p input in Bytes.
+ * \param input      The input data to encrypt. This must be a readable
+ *                   buffer of size \p ilen Bytes. This must not be \c NULL.
+ * \param output     The output buffer. This must be a writable buffer
+ *                   of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                   for an 2048-bit RSA modulus.
+ *
+ * \return           \c 0 on success.
+ * \return           An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng,
+                            int mode,
+                            const unsigned char *label, size_t label_len,
+                            size_t ilen,
+                            const unsigned char *input,
+                            unsigned char *output );
+
+/**
+ * \brief          This function performs an RSA operation, then removes the
+ *                 message padding.
+ *
+ *                 It is the generic wrapper for performing a PKCS#1 decryption
+ *                 operation using the \p mode from the context.
+ *
+ * \note           The output buffer length \c output_max_len should be
+ *                 as large as the size \p ctx->len of \p ctx->N (for example,
+ *                 128 Bytes if RSA-1024 is used) to be able to hold an
+ *                 arbitrary decrypted message. If it is not large enough to
+ *                 hold the decryption of the particular ciphertext provided,
+ *                 the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. If \p mode is
+ *                 #MBEDTLS_RSA_PUBLIC, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param olen     The address at which to store the length of
+ *                 the plaintext. This must not be \c NULL.
+ * \param input    The ciphertext buffer. This must be a readable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ * \param output   The buffer used to hold the plaintext. This must
+ *                 be a writable buffer of length \p output_max_len Bytes.
+ * \param output_max_len The length in Bytes of the output buffer \p output.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng,
+                       int mode, size_t *olen,
+                       const unsigned char *input,
+                       unsigned char *output,
+                       size_t output_max_len );
+
+/**
+ * \brief          This function performs a PKCS#1 v1.5 decryption
+ *                 operation (RSAES-PKCS1-v1_5-DECRYPT).
+ *
+ * \note           The output buffer length \c output_max_len should be
+ *                 as large as the size \p ctx->len of \p ctx->N, for example,
+ *                 128 Bytes if RSA-1024 is used, to be able to hold an
+ *                 arbitrary decrypted message. If it is not large enough to
+ *                 hold the decryption of the particular ciphertext provided,
+ *                 the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. If \p mode is
+ *                 #MBEDTLS_RSA_PUBLIC, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param olen     The address at which to store the length of
+ *                 the plaintext. This must not be \c NULL.
+ * \param input    The ciphertext buffer. This must be a readable buffer
+ *                 of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ * \param output   The buffer used to hold the plaintext. This must
+ *                 be a writable buffer of length \p output_max_len Bytes.
+ * \param output_max_len The length in Bytes of the output buffer \p output.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ *
+ */
+int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode, size_t *olen,
+                                 const unsigned char *input,
+                                 unsigned char *output,
+                                 size_t output_max_len );
+
+/**
+ * \brief            This function performs a PKCS#1 v2.1 OAEP decryption
+ *                   operation (RSAES-OAEP-DECRYPT).
+ *
+ * \note             The output buffer length \c output_max_len should be
+ *                   as large as the size \p ctx->len of \p ctx->N, for
+ *                   example, 128 Bytes if RSA-1024 is used, to be able to
+ *                   hold an arbitrary decrypted message. If it is not
+ *                   large enough to hold the decryption of the particular
+ *                   ciphertext provided, the function returns
+ *                   #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
+ *
+ * \deprecated       It is deprecated and discouraged to call this function
+ *                   in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
+ *                   are likely to remove the \p mode argument and have it
+ *                   implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note             Alternative implementations of RSA need not support
+ *                   mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                   return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx        The initialized RSA context to use.
+ * \param f_rng      The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                   this is used for blinding and should be provided; see
+ *                   mbedtls_rsa_private() for more. If \p mode is
+ *                   #MBEDTLS_RSA_PUBLIC, it is ignored.
+ * \param p_rng      The RNG context to be passed to \p f_rng. This may be
+ *                   \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode       The mode of operation. This must be either
+ *                   #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param label      The buffer holding the custom label to use.
+ *                   This must be a readable buffer of length \p label_len
+ *                   Bytes. It may be \c NULL if \p label_len is \c 0.
+ * \param label_len  The length of the label in Bytes.
+ * \param olen       The address at which to store the length of
+ *                   the plaintext. This must not be \c NULL.
+ * \param input      The ciphertext buffer. This must be a readable buffer
+ *                   of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                   for an 2048-bit RSA modulus.
+ * \param output     The buffer used to hold the plaintext. This must
+ *                   be a writable buffer of length \p output_max_len Bytes.
+ * \param output_max_len The length in Bytes of the output buffer \p output.
+ *
+ * \return         \c 0 on success.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng,
+                            int mode,
+                            const unsigned char *label, size_t label_len,
+                            size_t *olen,
+                            const unsigned char *input,
+                            unsigned char *output,
+                            size_t output_max_len );
+
+/**
+ * \brief          This function performs a private RSA operation to sign
+ *                 a message digest using PKCS#1.
+ *
+ *                 It is the generic wrapper for performing a PKCS#1
+ *                 signature using the \p mode from the context.
+ *
+ * \note           The \p sig buffer must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note           For PKCS#1 v2.1 encoding, see comments on
+ *                 mbedtls_rsa_rsassa_pss_sign() for details on
+ *                 \p md_alg and \p hash_id.
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function to use. If the padding mode is PKCS#1 v2.1,
+ *                 this must be provided. If the padding mode is PKCS#1 v1.5 and
+ *                 \p mode is #MBEDTLS_RSA_PRIVATE, it is used for blinding
+ *                 and should be provided; see mbedtls_rsa_private() for more
+ *                 more. It is ignored otherwise.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be \c NULL
+ *                 if \p f_rng is \c NULL or doesn't need a context argument.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest.
+ *                 Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer to hold the signature. This must be a writable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \return         \c 0 if the signing operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
+                    int (*f_rng)(void *, unsigned char *, size_t),
+                    void *p_rng,
+                    int mode,
+                    mbedtls_md_type_t md_alg,
+                    unsigned int hashlen,
+                    const unsigned char *hash,
+                    unsigned char *sig );
+
+/**
+ * \brief          This function performs a PKCS#1 v1.5 signature
+ *                 operation (RSASSA-PKCS1-v1_5-SIGN).
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. If \p mode is
+ *                 #MBEDTLS_RSA_PUBLIC, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be \c NULL
+ *                 if \p f_rng is \c NULL or doesn't need a context argument.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest.
+ *                 Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer to hold the signature. This must be a writable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \return         \c 0 if the signing operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng,
+                               int mode,
+                               mbedtls_md_type_t md_alg,
+                               unsigned int hashlen,
+                               const unsigned char *hash,
+                               unsigned char *sig );
+
+/**
+ * \brief          This function performs a PKCS#1 v2.1 PSS signature
+ *                 operation (RSASSA-PSS-SIGN).
+ *
+ * \note           The \p hash_id in the RSA context is the one used for the
+ *                 encoding. \p md_alg in the function call is the type of hash
+ *                 that is encoded. According to <em>RFC-3447: Public-Key
+ *                 Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ *                 Specifications</em> it is advised to keep both hashes the
+ *                 same.
+ *
+ * \note           This function always uses the maximum possible salt size,
+ *                 up to the length of the payload hash. This choice of salt
+ *                 size complies with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1
+ *                 v2.2) §9.1.1 step 3. Furthermore this function enforces a
+ *                 minimum salt size which is the hash size minus 2 bytes. If
+ *                 this minimum size is too large given the key size (the salt
+ *                 size, plus the hash size, plus 2 bytes must be no more than
+ *                 the key size in bytes), this function returns
+ *                 #MBEDTLS_ERR_RSA_BAD_INPUT_DATA.
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 implicitly set to #MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PUBLIC and might instead
+ *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx      The initialized RSA context to use.
+ * \param f_rng    The RNG function. It must not be \c NULL.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be \c NULL
+ *                 if \p f_rng doesn't need a context argument.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest.
+ *                 Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer to hold the signature. This must be a writable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \return         \c 0 if the signing operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng,
+                         int mode,
+                         mbedtls_md_type_t md_alg,
+                         unsigned int hashlen,
+                         const unsigned char *hash,
+                         unsigned char *sig );
+
+/**
+ * \brief          This function performs a public RSA operation and checks
+ *                 the message digest.
+ *
+ *                 This is the generic wrapper for performing a PKCS#1
+ *                 verification using the mode from the context.
+ *
+ * \note           For PKCS#1 v2.1 encoding, see comments on
+ *                 mbedtls_rsa_rsassa_pss_verify() about \p md_alg and
+ *                 \p hash_id.
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx      The initialized RSA public key context to use.
+ * \param f_rng    The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. Otherwise, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest.
+ *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer holding the signature. This must be a readable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng,
+                      int mode,
+                      mbedtls_md_type_t md_alg,
+                      unsigned int hashlen,
+                      const unsigned char *hash,
+                      const unsigned char *sig );
+
+/**
+ * \brief          This function performs a PKCS#1 v1.5 verification
+ *                 operation (RSASSA-PKCS1-v1_5-VERIFY).
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx      The initialized RSA public key context to use.
+ * \param f_rng    The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. Otherwise, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest.
+ *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer holding the signature. This must be a readable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode,
+                                 mbedtls_md_type_t md_alg,
+                                 unsigned int hashlen,
+                                 const unsigned char *hash,
+                                 const unsigned char *sig );
+
+/**
+ * \brief          This function performs a PKCS#1 v2.1 PSS verification
+ *                 operation (RSASSA-PSS-VERIFY).
+ *
+ *                 The hash function for the MGF mask generating function
+ *                 is that specified in the RSA context.
+ *
+ * \note           The \p hash_id in the RSA context is the one used for the
+ *                 verification. \p md_alg in the function call is the type of
+ *                 hash that is verified. According to <em>RFC-3447: Public-Key
+ *                 Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ *                 Specifications</em> it is advised to keep both hashes the
+ *                 same. If \p hash_id in the RSA context is unset,
+ *                 the \p md_alg from the function call is used.
+ *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
+ *                 are likely to remove the \p mode argument and have it
+ *                 implicitly set to #MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to #MBEDTLS_RSA_PRIVATE and might instead
+ *                 return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED.
+ *
+ * \param ctx      The initialized RSA public key context to use.
+ * \param f_rng    The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. Otherwise, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest.
+ *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param sig      The buffer holding the signature. This must be a readable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng,
+                           int mode,
+                           mbedtls_md_type_t md_alg,
+                           unsigned int hashlen,
+                           const unsigned char *hash,
+                           const unsigned char *sig );
+
+/**
+ * \brief          This function performs a PKCS#1 v2.1 PSS verification
+ *                 operation (RSASSA-PSS-VERIFY).
+ *
+ *                 The hash function for the MGF mask generating function
+ *                 is that specified in \p mgf1_hash_id.
+ *
+ * \note           The \p sig buffer must be as large as the size
+ *                 of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
+ *
+ * \note           The \p hash_id in the RSA context is ignored.
+ *
+ * \param ctx      The initialized RSA public key context to use.
+ * \param f_rng    The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE,
+ *                 this is used for blinding and should be provided; see
+ *                 mbedtls_rsa_private() for more. Otherwise, it is ignored.
+ * \param p_rng    The RNG context to be passed to \p f_rng. This may be
+ *                 \c NULL if \p f_rng is \c NULL or doesn't need a context.
+ * \param mode     The mode of operation. This must be either
+ *                 #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE.
+ * \param md_alg   The message-digest algorithm used to hash the original data.
+ *                 Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen  The length of the message digest.
+ *                 This is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash     The buffer holding the message digest or raw data.
+ *                 If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ *                 buffer of length \p hashlen Bytes. If \p md_alg is not
+ *                 #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ *                 the size of the hash corresponding to \p md_alg.
+ * \param mgf1_hash_id      The message digest used for mask generation.
+ * \param expected_salt_len The length of the salt used in padding. Use
+ *                          #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length.
+ * \param sig      The buffer holding the signature. This must be a readable
+ *                 buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ *                 for an 2048-bit RSA modulus.
+ *
+ * \return         \c 0 if the verify operation was successful.
+ * \return         An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng,
+                               int mode,
+                               mbedtls_md_type_t md_alg,
+                               unsigned int hashlen,
+                               const unsigned char *hash,
+                               mbedtls_md_type_t mgf1_hash_id,
+                               int expected_salt_len,
+                               const unsigned char *sig );
+
+/**
+ * \brief          This function copies the components of an RSA context.
+ *
+ * \param dst      The destination context. This must be initialized.
+ * \param src      The source context. This must be initialized.
+ *
+ * \return         \c 0 on success.
+ * \return         #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure.
+ */
+int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src );
+
+/**
+ * \brief          This function frees the components of an RSA key.
+ *
+ * \param ctx      The RSA context to free. May be \c NULL, in which case
+ *                 this function is a no-op. If it is not \c NULL, it must
+ *                 point to an initialized RSA context.
+ */
+void mbedtls_rsa_free( mbedtls_rsa_context *ctx );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          The RSA checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_rsa_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* rsa.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/rsa_internal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/rsa_internal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/rsa_internal.h	(revision 398)
@@ -0,0 +1,226 @@
+/**
+ * \file rsa_internal.h
+ *
+ * \brief Context-independent RSA helper functions
+ *
+ *  This module declares some RSA-related helper functions useful when
+ *  implementing the RSA interface. These functions are provided in a separate
+ *  compilation unit in order to make it easy for designers of alternative RSA
+ *  implementations to use them in their own code, as it is conceived that the
+ *  functionality they provide will be necessary for most complete
+ *  implementations.
+ *
+ *  End-users of Mbed TLS who are not providing their own alternative RSA
+ *  implementations should not use these functions directly, and should instead
+ *  use only the functions declared in rsa.h.
+ *
+ *  The interface provided by this module will be maintained through LTS (Long
+ *  Term Support) branches of Mbed TLS, but may otherwise be subject to change,
+ *  and must be considered an internal interface of the library.
+ *
+ *  There are two classes of helper functions:
+ *
+ *  (1) Parameter-generating helpers. These are:
+ *      - mbedtls_rsa_deduce_primes
+ *      - mbedtls_rsa_deduce_private_exponent
+ *      - mbedtls_rsa_deduce_crt
+ *       Each of these functions takes a set of core RSA parameters and
+ *       generates some other, or CRT related parameters.
+ *
+ *  (2) Parameter-checking helpers. These are:
+ *      - mbedtls_rsa_validate_params
+ *      - mbedtls_rsa_validate_crt
+ *      They take a set of core or CRT related RSA parameters and check their
+ *      validity.
+ *
+ */
+/*
+ *  Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
+ */
+
+#ifndef MBEDTLS_RSA_INTERNAL_H
+#define MBEDTLS_RSA_INTERNAL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "bignum.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * \brief          Compute RSA prime moduli P, Q from public modulus N=PQ
+ *                 and a pair of private and public key.
+ *
+ * \note           This is a 'static' helper function not operating on
+ *                 an RSA context. Alternative implementations need not
+ *                 overwrite it.
+ *
+ * \param N        RSA modulus N = PQ, with P, Q to be found
+ * \param E        RSA public exponent
+ * \param D        RSA private exponent
+ * \param P        Pointer to MPI holding first prime factor of N on success
+ * \param Q        Pointer to MPI holding second prime factor of N on success
+ *
+ * \return
+ *                 - 0 if successful. In this case, P and Q constitute a
+ *                   factorization of N.
+ *                 - A non-zero error code otherwise.
+ *
+ * \note           It is neither checked that P, Q are prime nor that
+ *                 D, E are modular inverses wrt. P-1 and Q-1. For that,
+ *                 use the helper function \c mbedtls_rsa_validate_params.
+ *
+ */
+int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N, mbedtls_mpi const *E,
+                               mbedtls_mpi const *D,
+                               mbedtls_mpi *P, mbedtls_mpi *Q );
+
+/**
+ * \brief          Compute RSA private exponent from
+ *                 prime moduli and public key.
+ *
+ * \note           This is a 'static' helper function not operating on
+ *                 an RSA context. Alternative implementations need not
+ *                 overwrite it.
+ *
+ * \param P        First prime factor of RSA modulus
+ * \param Q        Second prime factor of RSA modulus
+ * \param E        RSA public exponent
+ * \param D        Pointer to MPI holding the private exponent on success.
+ *
+ * \return
+ *                 - 0 if successful. In this case, D is set to a simultaneous
+ *                   modular inverse of E modulo both P-1 and Q-1.
+ *                 - A non-zero error code otherwise.
+ *
+ * \note           This function does not check whether P and Q are primes.
+ *
+ */
+int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P,
+                                         mbedtls_mpi const *Q,
+                                         mbedtls_mpi const *E,
+                                         mbedtls_mpi *D );
+
+
+/**
+ * \brief          Generate RSA-CRT parameters
+ *
+ * \note           This is a 'static' helper function not operating on
+ *                 an RSA context. Alternative implementations need not
+ *                 overwrite it.
+ *
+ * \param P        First prime factor of N
+ * \param Q        Second prime factor of N
+ * \param D        RSA private exponent
+ * \param DP       Output variable for D modulo P-1
+ * \param DQ       Output variable for D modulo Q-1
+ * \param QP       Output variable for the modular inverse of Q modulo P.
+ *
+ * \return         0 on success, non-zero error code otherwise.
+ *
+ * \note           This function does not check whether P, Q are
+ *                 prime and whether D is a valid private exponent.
+ *
+ */
+int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                            const mbedtls_mpi *D, mbedtls_mpi *DP,
+                            mbedtls_mpi *DQ, mbedtls_mpi *QP );
+
+
+/**
+ * \brief          Check validity of core RSA parameters
+ *
+ * \note           This is a 'static' helper function not operating on
+ *                 an RSA context. Alternative implementations need not
+ *                 overwrite it.
+ *
+ * \param N        RSA modulus N = PQ
+ * \param P        First prime factor of N
+ * \param Q        Second prime factor of N
+ * \param D        RSA private exponent
+ * \param E        RSA public exponent
+ * \param f_rng    PRNG to be used for primality check, or NULL
+ * \param p_rng    PRNG context for f_rng, or NULL
+ *
+ * \return
+ *                 - 0 if the following conditions are satisfied
+ *                   if all relevant parameters are provided:
+ *                    - P prime if f_rng != NULL (%)
+ *                    - Q prime if f_rng != NULL (%)
+ *                    - 1 < N = P * Q
+ *                    - 1 < D, E < N
+ *                    - D and E are modular inverses modulo P-1 and Q-1
+ *                   (%) This is only done if MBEDTLS_GENPRIME is defined.
+ *                 - A non-zero error code otherwise.
+ *
+ * \note           The function can be used with a restricted set of arguments
+ *                 to perform specific checks only. E.g., calling it with
+ *                 (-,P,-,-,-) and a PRNG amounts to a primality check for P.
+ */
+int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P,
+                                 const mbedtls_mpi *Q, const mbedtls_mpi *D,
+                                 const mbedtls_mpi *E,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng );
+
+/**
+ * \brief          Check validity of RSA CRT parameters
+ *
+ * \note           This is a 'static' helper function not operating on
+ *                 an RSA context. Alternative implementations need not
+ *                 overwrite it.
+ *
+ * \param P        First prime factor of RSA modulus
+ * \param Q        Second prime factor of RSA modulus
+ * \param D        RSA private exponent
+ * \param DP       MPI to check for D modulo P-1
+ * \param DQ       MPI to check for D modulo P-1
+ * \param QP       MPI to check for the modular inverse of Q modulo P.
+ *
+ * \return
+ *                 - 0 if the following conditions are satisfied:
+ *                    - D = DP mod P-1 if P, D, DP != NULL
+ *                    - Q = DQ mod P-1 if P, D, DQ != NULL
+ *                    - QP = Q^-1 mod P if P, Q, QP != NULL
+ *                 - \c MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if check failed,
+ *                   potentially including \c MBEDTLS_ERR_MPI_XXX if some
+ *                   MPI calculations failed.
+ *                 - \c MBEDTLS_ERR_RSA_BAD_INPUT_DATA if insufficient
+ *                   data was provided to check DP, DQ or QP.
+ *
+ * \note           The function can be used with a restricted set of arguments
+ *                 to perform specific checks only. E.g., calling it with the
+ *                 parameters (P, -, D, DP, -, -) will check DP = D mod P-1.
+ */
+int mbedtls_rsa_validate_crt( const mbedtls_mpi *P,  const mbedtls_mpi *Q,
+                              const mbedtls_mpi *D,  const mbedtls_mpi *DP,
+                              const mbedtls_mpi *DQ, const mbedtls_mpi *QP );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* rsa_internal.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/sha1.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/sha1.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/sha1.h	(revision 398)
@@ -0,0 +1,352 @@
+/**
+ * \file sha1.h
+ *
+ * \brief This file contains SHA-1 definitions and functions.
+ *
+ * The Secure Hash Algorithm 1 (SHA-1) cryptographic hash function is defined in
+ * <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. We recommend considering stronger message
+ *            digests instead.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SHA1_H
+#define MBEDTLS_SHA1_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED                  -0x0035  /**< SHA-1 hardware accelerator failed */
+#define MBEDTLS_ERR_SHA1_BAD_INPUT_DATA                   -0x0073  /**< SHA-1 input data was malformed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_SHA1_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          The SHA-1 context structure.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ */
+typedef struct mbedtls_sha1_context
+{
+    uint32_t total[2];          /*!< The number of Bytes processed.  */
+    uint32_t state[5];          /*!< The intermediate digest state.  */
+    unsigned char buffer[64];   /*!< The data block being processed. */
+}
+mbedtls_sha1_context;
+
+#else  /* MBEDTLS_SHA1_ALT */
+#include "sha1_alt.h"
+#endif /* MBEDTLS_SHA1_ALT */
+
+/**
+ * \brief          This function initializes a SHA-1 context.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param ctx      The SHA-1 context to initialize.
+ *                 This must not be \c NULL.
+ *
+ */
+void mbedtls_sha1_init( mbedtls_sha1_context *ctx );
+
+/**
+ * \brief          This function clears a SHA-1 context.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param ctx      The SHA-1 context to clear. This may be \c NULL,
+ *                 in which case this function does nothing. If it is
+ *                 not \c NULL, it must point to an initialized
+ *                 SHA-1 context.
+ *
+ */
+void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
+
+/**
+ * \brief          This function clones the state of a SHA-1 context.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param dst      The SHA-1 context to clone to. This must be initialized.
+ * \param src      The SHA-1 context to clone from. This must be initialized.
+ *
+ */
+void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
+                         const mbedtls_sha1_context *src );
+
+/**
+ * \brief          This function starts a SHA-1 checksum calculation.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param ctx      The SHA-1 context to initialize. This must be initialized.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ *
+ */
+int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx );
+
+/**
+ * \brief          This function feeds an input buffer into an ongoing SHA-1
+ *                 checksum calculation.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param ctx      The SHA-1 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
+                             const unsigned char *input,
+                             size_t ilen );
+
+/**
+ * \brief          This function finishes the SHA-1 operation, and writes
+ *                 the result to the output buffer.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param ctx      The SHA-1 context to use. This must be initialized and
+ *                 have a hash operation started.
+ * \param output   The SHA-1 checksum result. This must be a writable
+ *                 buffer of length \c 20 Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
+                             unsigned char output[20] );
+
+/**
+ * \brief          SHA-1 process data block (internal use only).
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param ctx      The SHA-1 context to use. This must be initialized.
+ * \param data     The data block being processed. This must be a
+ *                 readable buffer of length \c 64 Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ *
+ */
+int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
+                                   const unsigned char data[64] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          This function starts a SHA-1 checksum calculation.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \deprecated     Superseded by mbedtls_sha1_starts_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context to initialize. This must be initialized.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
+
+/**
+ * \brief          This function feeds an input buffer into an ongoing SHA-1
+ *                 checksum calculation.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \deprecated     Superseded by mbedtls_sha1_update_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context. This must be initialized and
+ *                 have a hash operation started.
+ * \param input    The buffer holding the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
+                                             const unsigned char *input,
+                                             size_t ilen );
+
+/**
+ * \brief          This function finishes the SHA-1 operation, and writes
+ *                 the result to the output buffer.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \deprecated     Superseded by mbedtls_sha1_finish_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context. This must be initialized and
+ *                 have a hash operation started.
+ * \param output   The SHA-1 checksum result.
+ *                 This must be a writable buffer of length \c 20 Bytes.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
+                                             unsigned char output[20] );
+
+/**
+ * \brief          SHA-1 process data block (internal use only).
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \deprecated     Superseded by mbedtls_internal_sha1_process() in 2.7.0.
+ *
+ * \param ctx      The SHA-1 context. This must be initialized.
+ * \param data     The data block being processed.
+ *                 This must be a readable buffer of length \c 64 bytes.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
+                                              const unsigned char data[64] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          This function calculates the SHA-1 checksum of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The SHA-1 result is calculated as
+ *                 output = SHA-1(input buffer).
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \param input    The buffer holding the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
+ * \param output   The SHA-1 checksum result.
+ *                 This must be a writable buffer of length \c 20 Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ *
+ */
+int mbedtls_sha1_ret( const unsigned char *input,
+                      size_t ilen,
+                      unsigned char output[20] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          This function calculates the SHA-1 checksum of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The SHA-1 result is calculated as
+ *                 output = SHA-1(input buffer).
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \deprecated     Superseded by mbedtls_sha1_ret() in 2.7.0
+ *
+ * \param input    The buffer holding the input data.
+ *                 This must be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data \p input in Bytes.
+ * \param output   The SHA-1 checksum result. This must be a writable
+ *                 buffer of size \c 20 Bytes.
+ *
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input,
+                                      size_t ilen,
+                                      unsigned char output[20] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          The SHA-1 checkup routine.
+ *
+ * \warning        SHA-1 is considered a weak message digest and its use
+ *                 constitutes a security risk. We recommend considering
+ *                 stronger message digests instead.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ *
+ */
+int mbedtls_sha1_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_sha1.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/sha256.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/sha256.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/sha256.h	(revision 398)
@@ -0,0 +1,297 @@
+/**
+ * \file sha256.h
+ *
+ * \brief This file contains SHA-224 and SHA-256 definitions and functions.
+ *
+ * The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic
+ * hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SHA256_H
+#define MBEDTLS_SHA256_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED                -0x0037  /**< SHA-256 hardware accelerator failed */
+#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA                 -0x0074  /**< SHA-256 input data was malformed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_SHA256_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          The SHA-256 context structure.
+ *
+ *                 The structure is used both for SHA-256 and for SHA-224
+ *                 checksum calculations. The choice between these two is
+ *                 made in the call to mbedtls_sha256_starts_ret().
+ */
+typedef struct mbedtls_sha256_context
+{
+    uint32_t total[2];          /*!< The number of Bytes processed.  */
+    uint32_t state[8];          /*!< The intermediate digest state.  */
+    unsigned char buffer[64];   /*!< The data block being processed. */
+    int is224;                  /*!< Determines which function to use:
+                                     0: Use SHA-256, or 1: Use SHA-224. */
+}
+mbedtls_sha256_context;
+
+#else  /* MBEDTLS_SHA256_ALT */
+#include "sha256_alt.h"
+#endif /* MBEDTLS_SHA256_ALT */
+
+/**
+ * \brief          This function initializes a SHA-256 context.
+ *
+ * \param ctx      The SHA-256 context to initialize. This must not be \c NULL.
+ */
+void mbedtls_sha256_init( mbedtls_sha256_context *ctx );
+
+/**
+ * \brief          This function clears a SHA-256 context.
+ *
+ * \param ctx      The SHA-256 context to clear. This may be \c NULL, in which
+ *                 case this function returns immediately. If it is not \c NULL,
+ *                 it must point to an initialized SHA-256 context.
+ */
+void mbedtls_sha256_free( mbedtls_sha256_context *ctx );
+
+/**
+ * \brief          This function clones the state of a SHA-256 context.
+ *
+ * \param dst      The destination context. This must be initialized.
+ * \param src      The context to clone. This must be initialized.
+ */
+void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
+                           const mbedtls_sha256_context *src );
+
+/**
+ * \brief          This function starts a SHA-224 or SHA-256 checksum
+ *                 calculation.
+ *
+ * \param ctx      The context to use. This must be initialized.
+ * \param is224    This determines which function to use. This must be
+ *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 );
+
+/**
+ * \brief          This function feeds an input buffer into an ongoing
+ *                 SHA-256 checksum calculation.
+ *
+ * \param ctx      The SHA-256 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
+                               const unsigned char *input,
+                               size_t ilen );
+
+/**
+ * \brief          This function finishes the SHA-256 operation, and writes
+ *                 the result to the output buffer.
+ *
+ * \param ctx      The SHA-256 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param output   The SHA-224 or SHA-256 checksum result.
+ *                 This must be a writable buffer of length \c 32 Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
+                               unsigned char output[32] );
+
+/**
+ * \brief          This function processes a single data block within
+ *                 the ongoing SHA-256 computation. This function is for
+ *                 internal use only.
+ *
+ * \param ctx      The SHA-256 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This must
+ *                 be a readable buffer of length \c 64 Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
+                                     const unsigned char data[64] );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          This function starts a SHA-224 or SHA-256 checksum
+ *                 calculation.
+ *
+ * \deprecated     Superseded by mbedtls_sha256_starts_ret() in 2.7.0.
+ *
+ * \param ctx      The context to use. This must be initialized.
+ * \param is224    Determines which function to use. This must be
+ *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
+                                               int is224 );
+
+/**
+ * \brief          This function feeds an input buffer into an ongoing
+ *                 SHA-256 checksum calculation.
+ *
+ * \deprecated     Superseded by mbedtls_sha256_update_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-256 context to use. This must be
+ *                 initialized and have a hash operation started.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
+                                               const unsigned char *input,
+                                               size_t ilen );
+
+/**
+ * \brief          This function finishes the SHA-256 operation, and writes
+ *                 the result to the output buffer.
+ *
+ * \deprecated     Superseded by mbedtls_sha256_finish_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-256 context. This must be initialized and
+ *                 have a hash operation started.
+ * \param output   The SHA-224 or SHA-256 checksum result. This must be
+ *                 a writable buffer of length \c 32 Bytes.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
+                                               unsigned char output[32] );
+
+/**
+ * \brief          This function processes a single data block within
+ *                 the ongoing SHA-256 computation. This function is for
+ *                 internal use only.
+ *
+ * \deprecated     Superseded by mbedtls_internal_sha256_process() in 2.7.0.
+ *
+ * \param ctx      The SHA-256 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This must be
+ *                 a readable buffer of size \c 64 Bytes.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
+                                                const unsigned char data[64] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          This function calculates the SHA-224 or SHA-256
+ *                 checksum of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The SHA-256 result is calculated as
+ *                 output = SHA-256(input buffer).
+ *
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ * \param output   The SHA-224 or SHA-256 checksum result. This must
+ *                 be a writable buffer of length \c 32 Bytes.
+ * \param is224    Determines which function to use. This must be
+ *                 either \c 0 for SHA-256, or \c 1 for SHA-224.
+ */
+int mbedtls_sha256_ret( const unsigned char *input,
+                        size_t ilen,
+                        unsigned char output[32],
+                        int is224 );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+
+/**
+ * \brief          This function calculates the SHA-224 or SHA-256 checksum
+ *                 of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The SHA-256 result is calculated as
+ *                 output = SHA-256(input buffer).
+ *
+ * \deprecated     Superseded by mbedtls_sha256_ret() in 2.7.0.
+ *
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ * \param output   The SHA-224 or SHA-256 checksum result. This must be
+ *                 a writable buffer of length \c 32 Bytes.
+ * \param is224    Determines which function to use. This must be either
+ *                 \c 0 for SHA-256, or \c 1 for SHA-224.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input,
+                                        size_t ilen,
+                                        unsigned char output[32],
+                                        int is224 );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          The SHA-224 and SHA-256 checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_sha256_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_sha256.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/sha512.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/sha512.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/sha512.h	(revision 398)
@@ -0,0 +1,300 @@
+/**
+ * \file sha512.h
+ * \brief This file contains SHA-384 and SHA-512 definitions and functions.
+ *
+ * The Secure Hash Algorithms 384 and 512 (SHA-384 and SHA-512) cryptographic
+ * hash functions are defined in <em>FIPS 180-4: Secure Hash Standard (SHS)</em>.
+ */
+/*
+ *  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SHA512_H
+#define MBEDTLS_SHA512_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED                -0x0039  /**< SHA-512 hardware accelerator failed */
+#define MBEDTLS_ERR_SHA512_BAD_INPUT_DATA                 -0x0075  /**< SHA-512 input data was malformed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_SHA512_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          The SHA-512 context structure.
+ *
+ *                 The structure is used both for SHA-384 and for SHA-512
+ *                 checksum calculations. The choice between these two is
+ *                 made in the call to mbedtls_sha512_starts_ret().
+ */
+typedef struct mbedtls_sha512_context
+{
+    uint64_t total[2];          /*!< The number of Bytes processed. */
+    uint64_t state[8];          /*!< The intermediate digest state. */
+    unsigned char buffer[128];  /*!< The data block being processed. */
+    int is384;                  /*!< Determines which function to use:
+                                     0: Use SHA-512, or 1: Use SHA-384. */
+}
+mbedtls_sha512_context;
+
+#else  /* MBEDTLS_SHA512_ALT */
+#include "sha512_alt.h"
+#endif /* MBEDTLS_SHA512_ALT */
+
+/**
+ * \brief          This function initializes a SHA-512 context.
+ *
+ * \param ctx      The SHA-512 context to initialize. This must
+ *                 not be \c NULL.
+ */
+void mbedtls_sha512_init( mbedtls_sha512_context *ctx );
+
+/**
+ * \brief          This function clears a SHA-512 context.
+ *
+ * \param ctx      The SHA-512 context to clear. This may be \c NULL,
+ *                 in which case this function does nothing. If it
+ *                 is not \c NULL, it must point to an initialized
+ *                 SHA-512 context.
+ */
+void mbedtls_sha512_free( mbedtls_sha512_context *ctx );
+
+/**
+ * \brief          This function clones the state of a SHA-512 context.
+ *
+ * \param dst      The destination context. This must be initialized.
+ * \param src      The context to clone. This must be initialized.
+ */
+void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
+                           const mbedtls_sha512_context *src );
+
+/**
+ * \brief          This function starts a SHA-384 or SHA-512 checksum
+ *                 calculation.
+ *
+ * \param ctx      The SHA-512 context to use. This must be initialized.
+ * \param is384    Determines which function to use. This must be
+ *                 either \c for SHA-512, or \c 1 for SHA-384.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 );
+
+/**
+ * \brief          This function feeds an input buffer into an ongoing
+ *                 SHA-512 checksum calculation.
+ *
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the input data. This must
+ *                 be a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
+                    const unsigned char *input,
+                    size_t ilen );
+
+/**
+ * \brief          This function finishes the SHA-512 operation, and writes
+ *                 the result to the output buffer. This function is for
+ *                 internal use only.
+ *
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param output   The SHA-384 or SHA-512 checksum result.
+ *                 This must be a writable buffer of length \c 64 Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
+                               unsigned char output[64] );
+
+/**
+ * \brief          This function processes a single data block within
+ *                 the ongoing SHA-512 computation.
+ *
+ * \param ctx      The SHA-512 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This
+ *                 must be a readable buffer of length \c 128 Bytes.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
+                                     const unsigned char data[128] );
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+/**
+ * \brief          This function starts a SHA-384 or SHA-512 checksum
+ *                 calculation.
+ *
+ * \deprecated     Superseded by mbedtls_sha512_starts_ret() in 2.7.0
+ *
+ * \param ctx      The SHA-512 context to use. This must be initialized.
+ * \param is384    Determines which function to use. This must be either
+ *                 \c 0 for SHA-512 or \c 1 for SHA-384.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
+                                               int is384 );
+
+/**
+ * \brief          This function feeds an input buffer into an ongoing
+ *                 SHA-512 checksum calculation.
+ *
+ * \deprecated     Superseded by mbedtls_sha512_update_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param input    The buffer holding the data. This must be a readable
+ *                 buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
+                                               const unsigned char *input,
+                                               size_t ilen );
+
+/**
+ * \brief          This function finishes the SHA-512 operation, and writes
+ *                 the result to the output buffer.
+ *
+ * \deprecated     Superseded by mbedtls_sha512_finish_ret() in 2.7.0.
+ *
+ * \param ctx      The SHA-512 context. This must be initialized
+ *                 and have a hash operation started.
+ * \param output   The SHA-384 or SHA-512 checksum result. This must
+ *                 be a writable buffer of size \c 64 Bytes.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
+                                               unsigned char output[64] );
+
+/**
+ * \brief          This function processes a single data block within
+ *                 the ongoing SHA-512 computation. This function is for
+ *                 internal use only.
+ *
+ * \deprecated     Superseded by mbedtls_internal_sha512_process() in 2.7.0.
+ *
+ * \param ctx      The SHA-512 context. This must be initialized.
+ * \param data     The buffer holding one block of data. This must be
+ *                 a readable buffer of length \c 128 Bytes.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha512_process(
+                                            mbedtls_sha512_context *ctx,
+                                            const unsigned char data[128] );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          This function calculates the SHA-512 or SHA-384
+ *                 checksum of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The SHA-512 result is calculated as
+ *                 output = SHA-512(input buffer).
+ *
+ * \param input    The buffer holding the input data. This must be
+ *                 a readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ * \param output   The SHA-384 or SHA-512 checksum result.
+ *                 This must be a writable buffer of length \c 64 Bytes.
+ * \param is384    Determines which function to use. This must be either
+ *                 \c 0 for SHA-512, or \c 1 for SHA-384.
+ *
+ * \return         \c 0 on success.
+ * \return         A negative error code on failure.
+ */
+int mbedtls_sha512_ret( const unsigned char *input,
+                        size_t ilen,
+                        unsigned char output[64],
+                        int is384 );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED      __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+
+/**
+ * \brief          This function calculates the SHA-512 or SHA-384
+ *                 checksum of a buffer.
+ *
+ *                 The function allocates the context, performs the
+ *                 calculation, and frees the context.
+ *
+ *                 The SHA-512 result is calculated as
+ *                 output = SHA-512(input buffer).
+ *
+ * \deprecated     Superseded by mbedtls_sha512_ret() in 2.7.0
+ *
+ * \param input    The buffer holding the data. This must be a
+ *                 readable buffer of length \p ilen Bytes.
+ * \param ilen     The length of the input data in Bytes.
+ * \param output   The SHA-384 or SHA-512 checksum result. This must
+ *                 be a writable buffer of length \c 64 Bytes.
+ * \param is384    Determines which function to use. This must be either
+ *                 \c 0 for SHA-512, or \c 1 for SHA-384.
+ */
+MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input,
+                                        size_t ilen,
+                                        unsigned char output[64],
+                                        int is384 );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+ /**
+ * \brief          The SHA-384 or SHA-512 checkup routine.
+ *
+ * \return         \c 0 on success.
+ * \return         \c 1 on failure.
+ */
+int mbedtls_sha512_self_test( int verbose );
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_sha512.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl.h	(revision 398)
@@ -0,0 +1,3256 @@
+/**
+ * \file ssl.h
+ *
+ * \brief SSL/TLS functions.
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SSL_H
+#define MBEDTLS_SSL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "bignum.h"
+#include "ecp.h"
+
+#include "ssl_ciphersuites.h"
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#include "x509_crt.h"
+#include "x509_crl.h"
+#endif
+
+#if defined(MBEDTLS_DHM_C)
+#include "dhm.h"
+#endif
+
+#if defined(MBEDTLS_ECDH_C)
+#include "ecdh.h"
+#endif
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and will be removed in the next major revision of the library"
+#endif
+
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+#error "Record compression support via MBEDTLS_ZLIB_SUPPORT is deprecated and cannot be used if MBEDTLS_DEPRECATED_REMOVED is set"
+#endif
+
+#include "zlib.h"
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME)
+#include "platform_time.h"
+#endif
+
+/*
+ * SSL Error codes
+ */
+#define MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE               -0x7080  /**< The requested feature is not available. */
+#define MBEDTLS_ERR_SSL_BAD_INPUT_DATA                    -0x7100  /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_SSL_INVALID_MAC                       -0x7180  /**< Verification of the message MAC failed. */
+#define MBEDTLS_ERR_SSL_INVALID_RECORD                    -0x7200  /**< An invalid SSL record was received. */
+#define MBEDTLS_ERR_SSL_CONN_EOF                          -0x7280  /**< The connection indicated an EOF. */
+#define MBEDTLS_ERR_SSL_UNKNOWN_CIPHER                    -0x7300  /**< An unknown cipher was received. */
+#define MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN                  -0x7380  /**< The server has no ciphersuites in common with the client. */
+#define MBEDTLS_ERR_SSL_NO_RNG                            -0x7400  /**< No RNG was provided to the SSL module. */
+#define MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE             -0x7480  /**< No client certification received from the client, but required by the authentication mode. */
+#define MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE             -0x7500  /**< Our own certificate(s) is/are too large to send in an SSL message. */
+#define MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED              -0x7580  /**< The own certificate is not set, but needed by the server. */
+#define MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED              -0x7600  /**< The own private key or pre-shared key is not set, but needed. */
+#define MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED                 -0x7680  /**< No CA Chain is set, but required to operate. */
+#define MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE                -0x7700  /**< An unexpected message was received from our peer. */
+#define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE               -0x7780  /**< A fatal alert message was received from our peer. */
+#define MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED                -0x7800  /**< Verification of our peer failed. */
+#define MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY                 -0x7880  /**< The peer notified us that the connection is going to be closed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO               -0x7900  /**< Processing of the ClientHello handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO               -0x7980  /**< Processing of the ServerHello handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE                -0x7A00  /**< Processing of the Certificate handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST        -0x7A80  /**< Processing of the CertificateRequest handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE        -0x7B00  /**< Processing of the ServerKeyExchange handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE          -0x7B80  /**< Processing of the ServerHelloDone handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE        -0x7C00  /**< Processing of the ClientKeyExchange handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP     -0x7C80  /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS     -0x7D00  /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY         -0x7D80  /**< Processing of the CertificateVerify handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC         -0x7E00  /**< Processing of the ChangeCipherSpec handshake message failed. */
+#define MBEDTLS_ERR_SSL_BAD_HS_FINISHED                   -0x7E80  /**< Processing of the Finished handshake message failed. */
+#define MBEDTLS_ERR_SSL_ALLOC_FAILED                      -0x7F00  /**< Memory allocation failed */
+#define MBEDTLS_ERR_SSL_HW_ACCEL_FAILED                   -0x7F80  /**< Hardware acceleration function returned with error */
+#define MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH              -0x6F80  /**< Hardware acceleration function skipped / left alone data */
+#define MBEDTLS_ERR_SSL_COMPRESSION_FAILED                -0x6F00  /**< Processing of the compression / decompression failed */
+#define MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION           -0x6E80  /**< Handshake protocol not within min/max boundaries */
+#define MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET         -0x6E00  /**< Processing of the NewSessionTicket handshake message failed. */
+#define MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED            -0x6D80  /**< Session ticket has expired. */
+#define MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH                  -0x6D00  /**< Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */
+#define MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY                  -0x6C80  /**< Unknown identity received (eg, PSK identity) */
+#define MBEDTLS_ERR_SSL_INTERNAL_ERROR                    -0x6C00  /**< Internal error (eg, unexpected failure in lower-level module) */
+#define MBEDTLS_ERR_SSL_COUNTER_WRAPPING                  -0x6B80  /**< A counter would wrap (eg, too many messages exchanged). */
+#define MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO       -0x6B00  /**< Unexpected message at ServerHello in renegotiation. */
+#define MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED             -0x6A80  /**< DTLS client must retry for hello verification */
+#define MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL                  -0x6A00  /**< A buffer is too small to receive or write a message */
+#define MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE             -0x6980  /**< None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages). */
+#define MBEDTLS_ERR_SSL_WANT_READ                         -0x6900  /**< No data of requested type currently available on underlying transport. */
+#define MBEDTLS_ERR_SSL_WANT_WRITE                        -0x6880  /**< Connection requires a write call. */
+#define MBEDTLS_ERR_SSL_TIMEOUT                           -0x6800  /**< The operation timed out. */
+#define MBEDTLS_ERR_SSL_CLIENT_RECONNECT                  -0x6780  /**< The client initiated a reconnect from the same port. */
+#define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD                 -0x6700  /**< Record header looks valid but is not expected. */
+#define MBEDTLS_ERR_SSL_NON_FATAL                         -0x6680  /**< The alert message received indicates a non-fatal error. */
+#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH               -0x6600  /**< Couldn't set the hash for verifying CertificateVerify */
+#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING               -0x6580  /**< Internal-only message signaling that further message-processing should be done */
+#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS                 -0x6500  /**< The asynchronous operation is not completed yet. */
+#define MBEDTLS_ERR_SSL_EARLY_MESSAGE                     -0x6480  /**< Internal-only message signaling that a message arrived early. */
+#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS                -0x7000  /**< A cryptographic operation is in progress. Try again later. */
+
+/*
+ * Various constants
+ */
+#define MBEDTLS_SSL_MAJOR_VERSION_3             3
+#define MBEDTLS_SSL_MINOR_VERSION_0             0   /*!< SSL v3.0 */
+#define MBEDTLS_SSL_MINOR_VERSION_1             1   /*!< TLS v1.0 */
+#define MBEDTLS_SSL_MINOR_VERSION_2             2   /*!< TLS v1.1 */
+#define MBEDTLS_SSL_MINOR_VERSION_3             3   /*!< TLS v1.2 */
+
+#define MBEDTLS_SSL_TRANSPORT_STREAM            0   /*!< TLS      */
+#define MBEDTLS_SSL_TRANSPORT_DATAGRAM          1   /*!< DTLS     */
+
+#define MBEDTLS_SSL_MAX_HOST_NAME_LEN           255 /*!< Maximum host name defined in RFC 1035 */
+
+/* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c
+ * NONE must be zero so that memset()ing structure to zero works */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_NONE           0   /*!< don't use this extension   */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_512            1   /*!< MaxFragmentLength 2^9      */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_1024           2   /*!< MaxFragmentLength 2^10     */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_2048           3   /*!< MaxFragmentLength 2^11     */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_4096           4   /*!< MaxFragmentLength 2^12     */
+#define MBEDTLS_SSL_MAX_FRAG_LEN_INVALID        5   /*!< first invalid value        */
+
+#define MBEDTLS_SSL_IS_CLIENT                   0
+#define MBEDTLS_SSL_IS_SERVER                   1
+
+#define MBEDTLS_SSL_IS_NOT_FALLBACK             0
+#define MBEDTLS_SSL_IS_FALLBACK                 1
+
+#define MBEDTLS_SSL_EXTENDED_MS_DISABLED        0
+#define MBEDTLS_SSL_EXTENDED_MS_ENABLED         1
+
+#define MBEDTLS_SSL_ETM_DISABLED                0
+#define MBEDTLS_SSL_ETM_ENABLED                 1
+
+#define MBEDTLS_SSL_COMPRESS_NULL               0
+#define MBEDTLS_SSL_COMPRESS_DEFLATE            1
+
+#define MBEDTLS_SSL_VERIFY_NONE                 0
+#define MBEDTLS_SSL_VERIFY_OPTIONAL             1
+#define MBEDTLS_SSL_VERIFY_REQUIRED             2
+#define MBEDTLS_SSL_VERIFY_UNSET                3 /* Used only for sni_authmode */
+
+#define MBEDTLS_SSL_LEGACY_RENEGOTIATION        0
+#define MBEDTLS_SSL_SECURE_RENEGOTIATION        1
+
+#define MBEDTLS_SSL_RENEGOTIATION_DISABLED      0
+#define MBEDTLS_SSL_RENEGOTIATION_ENABLED       1
+
+#define MBEDTLS_SSL_ANTI_REPLAY_DISABLED        0
+#define MBEDTLS_SSL_ANTI_REPLAY_ENABLED         1
+
+#define MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED  -1
+#define MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT  16
+
+#define MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION     0
+#define MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION  1
+#define MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE      2
+
+#define MBEDTLS_SSL_TRUNC_HMAC_DISABLED         0
+#define MBEDTLS_SSL_TRUNC_HMAC_ENABLED          1
+#define MBEDTLS_SSL_TRUNCATED_HMAC_LEN          10  /* 80 bits, rfc 6066 section 7 */
+
+#define MBEDTLS_SSL_SESSION_TICKETS_DISABLED     0
+#define MBEDTLS_SSL_SESSION_TICKETS_ENABLED      1
+
+#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED    0
+#define MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED     1
+
+#define MBEDTLS_SSL_ARC4_ENABLED                0
+#define MBEDTLS_SSL_ARC4_DISABLED               1
+
+#define MBEDTLS_SSL_PRESET_DEFAULT              0
+#define MBEDTLS_SSL_PRESET_SUITEB               2
+
+#define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED       1
+#define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED      0
+
+/*
+ * Default range for DTLS retransmission timer value, in milliseconds.
+ * RFC 6347 4.2.4.1 says from 1 second to 60 seconds.
+ */
+#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN    1000
+#define MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX   60000
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME)
+#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME     86400 /**< Lifetime of session tickets (if enabled) */
+#endif
+
+/*
+ * Maximum fragment length in bytes,
+ * determines the size of each of the two internal I/O buffers.
+ *
+ * Note: the RFC defines the default size of SSL / TLS messages. If you
+ * change the value here, other clients / servers may not be able to
+ * communicate with you anymore. Only change this value if you control
+ * both sides of the connection and have it reduced at both sides, or
+ * if you're using the Max Fragment Length extension and you know all your
+ * peers are using it too!
+ */
+#if !defined(MBEDTLS_SSL_MAX_CONTENT_LEN)
+#define MBEDTLS_SSL_MAX_CONTENT_LEN         16384   /**< Size of the input / output buffer */
+#endif
+
+#if !defined(MBEDTLS_SSL_IN_CONTENT_LEN)
+#define MBEDTLS_SSL_IN_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN
+#endif
+
+#if !defined(MBEDTLS_SSL_OUT_CONTENT_LEN)
+#define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN
+#endif
+
+/*
+ * Maximum number of heap-allocated bytes for the purpose of
+ * DTLS handshake message reassembly and future message buffering.
+ */
+#if !defined(MBEDTLS_SSL_DTLS_MAX_BUFFERING)
+#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768
+#endif
+
+/* \} name SECTION: Module settings */
+
+/*
+ * Length of the verify data for secure renegotiation
+ */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 36
+#else
+#define MBEDTLS_SSL_VERIFY_DATA_MAX_LEN 12
+#endif
+
+/*
+ * Signaling ciphersuite values (SCSV)
+ */
+#define MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO    0xFF   /**< renegotiation info ext */
+#define MBEDTLS_SSL_FALLBACK_SCSV_VALUE         0x5600 /**< RFC 7507 section 2 */
+
+/*
+ * Supported Signature and Hash algorithms (For TLS 1.2)
+ * RFC 5246 section 7.4.1.4.1
+ */
+#define MBEDTLS_SSL_HASH_NONE                0
+#define MBEDTLS_SSL_HASH_MD5                 1
+#define MBEDTLS_SSL_HASH_SHA1                2
+#define MBEDTLS_SSL_HASH_SHA224              3
+#define MBEDTLS_SSL_HASH_SHA256              4
+#define MBEDTLS_SSL_HASH_SHA384              5
+#define MBEDTLS_SSL_HASH_SHA512              6
+
+#define MBEDTLS_SSL_SIG_ANON                 0
+#define MBEDTLS_SSL_SIG_RSA                  1
+#define MBEDTLS_SSL_SIG_ECDSA                3
+
+/*
+ * Client Certificate Types
+ * RFC 5246 section 7.4.4 plus RFC 4492 section 5.5
+ */
+#define MBEDTLS_SSL_CERT_TYPE_RSA_SIGN       1
+#define MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN    64
+
+/*
+ * Message, alert and handshake types
+ */
+#define MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC     20
+#define MBEDTLS_SSL_MSG_ALERT                  21
+#define MBEDTLS_SSL_MSG_HANDSHAKE              22
+#define MBEDTLS_SSL_MSG_APPLICATION_DATA       23
+
+#define MBEDTLS_SSL_ALERT_LEVEL_WARNING         1
+#define MBEDTLS_SSL_ALERT_LEVEL_FATAL           2
+
+#define MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY           0  /* 0x00 */
+#define MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE    10  /* 0x0A */
+#define MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC        20  /* 0x14 */
+#define MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED     21  /* 0x15 */
+#define MBEDTLS_SSL_ALERT_MSG_RECORD_OVERFLOW       22  /* 0x16 */
+#define MBEDTLS_SSL_ALERT_MSG_DECOMPRESSION_FAILURE 30  /* 0x1E */
+#define MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE     40  /* 0x28 */
+#define MBEDTLS_SSL_ALERT_MSG_NO_CERT               41  /* 0x29 */
+#define MBEDTLS_SSL_ALERT_MSG_BAD_CERT              42  /* 0x2A */
+#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT      43  /* 0x2B */
+#define MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED          44  /* 0x2C */
+#define MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED          45  /* 0x2D */
+#define MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN          46  /* 0x2E */
+#define MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER     47  /* 0x2F */
+#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA            48  /* 0x30 */
+#define MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED         49  /* 0x31 */
+#define MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR          50  /* 0x32 */
+#define MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR         51  /* 0x33 */
+#define MBEDTLS_SSL_ALERT_MSG_EXPORT_RESTRICTION    60  /* 0x3C */
+#define MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION      70  /* 0x46 */
+#define MBEDTLS_SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71  /* 0x47 */
+#define MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR        80  /* 0x50 */
+#define MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK 86  /* 0x56 */
+#define MBEDTLS_SSL_ALERT_MSG_USER_CANCELED         90  /* 0x5A */
+#define MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION     100  /* 0x64 */
+#define MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT      110  /* 0x6E */
+#define MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME    112  /* 0x70 */
+#define MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115  /* 0x73 */
+#define MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */
+
+#define MBEDTLS_SSL_HS_HELLO_REQUEST            0
+#define MBEDTLS_SSL_HS_CLIENT_HELLO             1
+#define MBEDTLS_SSL_HS_SERVER_HELLO             2
+#define MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST     3
+#define MBEDTLS_SSL_HS_NEW_SESSION_TICKET       4
+#define MBEDTLS_SSL_HS_CERTIFICATE             11
+#define MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE     12
+#define MBEDTLS_SSL_HS_CERTIFICATE_REQUEST     13
+#define MBEDTLS_SSL_HS_SERVER_HELLO_DONE       14
+#define MBEDTLS_SSL_HS_CERTIFICATE_VERIFY      15
+#define MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE     16
+#define MBEDTLS_SSL_HS_FINISHED                20
+
+/*
+ * TLS extensions
+ */
+#define MBEDTLS_TLS_EXT_SERVERNAME                   0
+#define MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME          0
+
+#define MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH          1
+
+#define MBEDTLS_TLS_EXT_TRUNCATED_HMAC               4
+
+#define MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES   10
+#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS     11
+
+#define MBEDTLS_TLS_EXT_SIG_ALG                     13
+
+#define MBEDTLS_TLS_EXT_ALPN                        16
+
+#define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC            22 /* 0x16 */
+#define MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET  0x0017 /* 23 */
+
+#define MBEDTLS_TLS_EXT_SESSION_TICKET              35
+
+#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP               256 /* experimental */
+
+#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO      0xFF01
+
+/*
+ * Size defines
+ */
+#if !defined(MBEDTLS_PSK_MAX_LEN)
+#define MBEDTLS_PSK_MAX_LEN            32 /* 256 bits */
+#endif
+
+/* Dummy type used only for its size */
+union mbedtls_ssl_premaster_secret
+{
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+    unsigned char _pms_rsa[48];                         /* RFC 5246 8.1.1 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
+    unsigned char _pms_dhm[MBEDTLS_MPI_MAX_SIZE];      /* RFC 5246 8.1.2 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)    || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)  || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)     || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+    unsigned char _pms_ecdh[MBEDTLS_ECP_MAX_BYTES];    /* RFC 4492 5.10 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+    unsigned char _pms_psk[4 + 2 * MBEDTLS_PSK_MAX_LEN];       /* RFC 4279 2 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+    unsigned char _pms_dhe_psk[4 + MBEDTLS_MPI_MAX_SIZE
+                                 + MBEDTLS_PSK_MAX_LEN];       /* RFC 4279 3 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+    unsigned char _pms_rsa_psk[52 + MBEDTLS_PSK_MAX_LEN];      /* RFC 4279 4 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+    unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES
+                                   + MBEDTLS_PSK_MAX_LEN];     /* RFC 5489 2 */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    unsigned char _pms_ecjpake[32];     /* Thread spec: SHA-256 output */
+#endif
+};
+
+#define MBEDTLS_PREMASTER_SIZE     sizeof( union mbedtls_ssl_premaster_secret )
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * SSL state machine
+ */
+typedef enum
+{
+    MBEDTLS_SSL_HELLO_REQUEST,
+    MBEDTLS_SSL_CLIENT_HELLO,
+    MBEDTLS_SSL_SERVER_HELLO,
+    MBEDTLS_SSL_SERVER_CERTIFICATE,
+    MBEDTLS_SSL_SERVER_KEY_EXCHANGE,
+    MBEDTLS_SSL_CERTIFICATE_REQUEST,
+    MBEDTLS_SSL_SERVER_HELLO_DONE,
+    MBEDTLS_SSL_CLIENT_CERTIFICATE,
+    MBEDTLS_SSL_CLIENT_KEY_EXCHANGE,
+    MBEDTLS_SSL_CERTIFICATE_VERIFY,
+    MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC,
+    MBEDTLS_SSL_CLIENT_FINISHED,
+    MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC,
+    MBEDTLS_SSL_SERVER_FINISHED,
+    MBEDTLS_SSL_FLUSH_BUFFERS,
+    MBEDTLS_SSL_HANDSHAKE_WRAPUP,
+    MBEDTLS_SSL_HANDSHAKE_OVER,
+    MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET,
+    MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT,
+}
+mbedtls_ssl_states;
+
+/**
+ * \brief          Callback type: send data on the network.
+ *
+ * \note           That callback may be either blocking or non-blocking.
+ *
+ * \param ctx      Context for the send callback (typically a file descriptor)
+ * \param buf      Buffer holding the data to send
+ * \param len      Length of the data to send
+ *
+ * \return         The callback must return the number of bytes sent if any,
+ *                 or a non-zero error code.
+ *                 If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_WRITE
+ *                 must be returned when the operation would block.
+ *
+ * \note           The callback is allowed to send fewer bytes than requested.
+ *                 It must always return the number of bytes actually sent.
+ */
+typedef int mbedtls_ssl_send_t( void *ctx,
+                                const unsigned char *buf,
+                                size_t len );
+
+/**
+ * \brief          Callback type: receive data from the network.
+ *
+ * \note           That callback may be either blocking or non-blocking.
+ *
+ * \param ctx      Context for the receive callback (typically a file
+ *                 descriptor)
+ * \param buf      Buffer to write the received data to
+ * \param len      Length of the receive buffer
+ *
+ * \return         The callback must return the number of bytes received,
+ *                 or a non-zero error code.
+ *                 If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ
+ *                 must be returned when the operation would block.
+ *
+ * \note           The callback may receive fewer bytes than the length of the
+ *                 buffer. It must always return the number of bytes actually
+ *                 received and written to the buffer.
+ */
+typedef int mbedtls_ssl_recv_t( void *ctx,
+                                unsigned char *buf,
+                                size_t len );
+
+/**
+ * \brief          Callback type: receive data from the network, with timeout
+ *
+ * \note           That callback must block until data is received, or the
+ *                 timeout delay expires, or the operation is interrupted by a
+ *                 signal.
+ *
+ * \param ctx      Context for the receive callback (typically a file descriptor)
+ * \param buf      Buffer to write the received data to
+ * \param len      Length of the receive buffer
+ * \param timeout  Maximum nomber of millisecondes to wait for data
+ *                 0 means no timeout (potentially waiting forever)
+ *
+ * \return         The callback must return the number of bytes received,
+ *                 or a non-zero error code:
+ *                 \c MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out,
+ *                 \c MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal.
+ *
+ * \note           The callback may receive fewer bytes than the length of the
+ *                 buffer. It must always return the number of bytes actually
+ *                 received and written to the buffer.
+ */
+typedef int mbedtls_ssl_recv_timeout_t( void *ctx,
+                                        unsigned char *buf,
+                                        size_t len,
+                                        uint32_t timeout );
+/**
+ * \brief          Callback type: set a pair of timers/delays to watch
+ *
+ * \param ctx      Context pointer
+ * \param int_ms   Intermediate delay in milliseconds
+ * \param fin_ms   Final delay in milliseconds
+ *                 0 cancels the current timer.
+ *
+ * \note           This callback must at least store the necessary information
+ *                 for the associated \c mbedtls_ssl_get_timer_t callback to
+ *                 return correct information.
+ *
+ * \note           If using a event-driven style of programming, an event must
+ *                 be generated when the final delay is passed. The event must
+ *                 cause a call to \c mbedtls_ssl_handshake() with the proper
+ *                 SSL context to be scheduled. Care must be taken to ensure
+ *                 that at most one such call happens at a time.
+ *
+ * \note           Only one timer at a time must be running. Calling this
+ *                 function while a timer is running must cancel it. Cancelled
+ *                 timers must not generate any event.
+ */
+typedef void mbedtls_ssl_set_timer_t( void * ctx,
+                                      uint32_t int_ms,
+                                      uint32_t fin_ms );
+
+/**
+ * \brief          Callback type: get status of timers/delays
+ *
+ * \param ctx      Context pointer
+ *
+ * \return         This callback must return:
+ *                 -1 if cancelled (fin_ms == 0),
+ *                  0 if none of the delays have passed,
+ *                  1 if only the intermediate delay has passed,
+ *                  2 if the final delay has passed.
+ */
+typedef int mbedtls_ssl_get_timer_t( void * ctx );
+
+/* Defined below */
+typedef struct mbedtls_ssl_session mbedtls_ssl_session;
+typedef struct mbedtls_ssl_context mbedtls_ssl_context;
+typedef struct mbedtls_ssl_config  mbedtls_ssl_config;
+
+/* Defined in ssl_internal.h */
+typedef struct mbedtls_ssl_transform mbedtls_ssl_transform;
+typedef struct mbedtls_ssl_handshake_params mbedtls_ssl_handshake_params;
+typedef struct mbedtls_ssl_sig_hash_set_t mbedtls_ssl_sig_hash_set_t;
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert;
+#endif
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item;
+#endif
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief           Callback type: start external signature operation.
+ *
+ *                  This callback is called during an SSL handshake to start
+ *                  a signature decryption operation using an
+ *                  external processor. The parameter \p cert contains
+ *                  the public key; it is up to the callback function to
+ *                  determine how to access the associated private key.
+ *
+ *                  This function typically sends or enqueues a request, and
+ *                  does not wait for the operation to complete. This allows
+ *                  the handshake step to be non-blocking.
+ *
+ *                  The parameters \p ssl and \p cert are guaranteed to remain
+ *                  valid throughout the handshake. On the other hand, this
+ *                  function must save the contents of \p hash if the value
+ *                  is needed for later processing, because the \p hash buffer
+ *                  is no longer valid after this function returns.
+ *
+ *                  This function may call mbedtls_ssl_set_async_operation_data()
+ *                  to store an operation context for later retrieval
+ *                  by the resume or cancel callback.
+ *
+ * \note            For RSA signatures, this function must produce output
+ *                  that is consistent with PKCS#1 v1.5 in the same way as
+ *                  mbedtls_rsa_pkcs1_sign(). Before the private key operation,
+ *                  apply the padding steps described in RFC 8017, section 9.2
+ *                  "EMSA-PKCS1-v1_5" as follows.
+ *                  - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5
+ *                    encoding, treating \p hash as the DigestInfo to be
+ *                    padded. In other words, apply EMSA-PKCS1-v1_5 starting
+ *                    from step 3, with `T = hash` and `tLen = hash_len`.
+ *                  - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5
+ *                    encoding, treating \p hash as the hash to be encoded and
+ *                    padded. In other words, apply EMSA-PKCS1-v1_5 starting
+ *                    from step 2, with `digestAlgorithm` obtained by calling
+ *                    mbedtls_oid_get_oid_by_md() on \p md_alg.
+ *
+ * \note            For ECDSA signatures, the output format is the DER encoding
+ *                  `Ecdsa-Sig-Value` defined in
+ *                  [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4).
+ *
+ * \param ssl             The SSL connection instance. It should not be
+ *                        modified other than via
+ *                        mbedtls_ssl_set_async_operation_data().
+ * \param cert            Certificate containing the public key.
+ *                        In simple cases, this is one of the pointers passed to
+ *                        mbedtls_ssl_conf_own_cert() when configuring the SSL
+ *                        connection. However, if other callbacks are used, this
+ *                        property may not hold. For example, if an SNI callback
+ *                        is registered with mbedtls_ssl_conf_sni(), then
+ *                        this callback determines what certificate is used.
+ * \param md_alg          Hash algorithm.
+ * \param hash            Buffer containing the hash. This buffer is
+ *                        no longer valid when the function returns.
+ * \param hash_len        Size of the \c hash buffer in bytes.
+ *
+ * \return          0 if the operation was started successfully and the SSL
+ *                  stack should call the resume callback immediately.
+ * \return          #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
+ *                  was started successfully and the SSL stack should return
+ *                  immediately without calling the resume callback yet.
+ * \return          #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external
+ *                  processor does not support this key. The SSL stack will
+ *                  use the private key object instead.
+ * \return          Any other error indicates a fatal failure and is
+ *                  propagated up the call chain. The callback should
+ *                  use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
+ *                  use \c MBEDTLS_ERR_SSL_xxx error codes except as
+ *                  directed in the documentation of this callback.
+ */
+typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl,
+                                      mbedtls_x509_crt *cert,
+                                      mbedtls_md_type_t md_alg,
+                                      const unsigned char *hash,
+                                      size_t hash_len );
+
+/**
+ * \brief           Callback type: start external decryption operation.
+ *
+ *                  This callback is called during an SSL handshake to start
+ *                  an RSA decryption operation using an
+ *                  external processor. The parameter \p cert contains
+ *                  the public key; it is up to the callback function to
+ *                  determine how to access the associated private key.
+ *
+ *                  This function typically sends or enqueues a request, and
+ *                  does not wait for the operation to complete. This allows
+ *                  the handshake step to be non-blocking.
+ *
+ *                  The parameters \p ssl and \p cert are guaranteed to remain
+ *                  valid throughout the handshake. On the other hand, this
+ *                  function must save the contents of \p input if the value
+ *                  is needed for later processing, because the \p input buffer
+ *                  is no longer valid after this function returns.
+ *
+ *                  This function may call mbedtls_ssl_set_async_operation_data()
+ *                  to store an operation context for later retrieval
+ *                  by the resume or cancel callback.
+ *
+ * \warning         RSA decryption as used in TLS is subject to a potential
+ *                  timing side channel attack first discovered by Bleichenbacher
+ *                  in 1998. This attack can be remotely exploitable
+ *                  in practice. To avoid this attack, you must ensure that
+ *                  if the callback performs an RSA decryption, the time it
+ *                  takes to execute and return the result does not depend
+ *                  on whether the RSA decryption succeeded or reported
+ *                  invalid padding.
+ *
+ * \param ssl             The SSL connection instance. It should not be
+ *                        modified other than via
+ *                        mbedtls_ssl_set_async_operation_data().
+ * \param cert            Certificate containing the public key.
+ *                        In simple cases, this is one of the pointers passed to
+ *                        mbedtls_ssl_conf_own_cert() when configuring the SSL
+ *                        connection. However, if other callbacks are used, this
+ *                        property may not hold. For example, if an SNI callback
+ *                        is registered with mbedtls_ssl_conf_sni(), then
+ *                        this callback determines what certificate is used.
+ * \param input           Buffer containing the input ciphertext. This buffer
+ *                        is no longer valid when the function returns.
+ * \param input_len       Size of the \p input buffer in bytes.
+ *
+ * \return          0 if the operation was started successfully and the SSL
+ *                  stack should call the resume callback immediately.
+ * \return          #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
+ *                  was started successfully and the SSL stack should return
+ *                  immediately without calling the resume callback yet.
+ * \return          #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external
+ *                  processor does not support this key. The SSL stack will
+ *                  use the private key object instead.
+ * \return          Any other error indicates a fatal failure and is
+ *                  propagated up the call chain. The callback should
+ *                  use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
+ *                  use \c MBEDTLS_ERR_SSL_xxx error codes except as
+ *                  directed in the documentation of this callback.
+ */
+typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl,
+                                         mbedtls_x509_crt *cert,
+                                         const unsigned char *input,
+                                         size_t input_len );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+/**
+ * \brief           Callback type: resume external operation.
+ *
+ *                  This callback is called during an SSL handshake to resume
+ *                  an external operation started by the
+ *                  ::mbedtls_ssl_async_sign_t or
+ *                  ::mbedtls_ssl_async_decrypt_t callback.
+ *
+ *                  This function typically checks the status of a pending
+ *                  request or causes the request queue to make progress, and
+ *                  does not wait for the operation to complete. This allows
+ *                  the handshake step to be non-blocking.
+ *
+ *                  This function may call mbedtls_ssl_get_async_operation_data()
+ *                  to retrieve an operation context set by the start callback.
+ *                  It may call mbedtls_ssl_set_async_operation_data() to modify
+ *                  this context.
+ *
+ *                  Note that when this function returns a status other than
+ *                  #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any
+ *                  resources associated with the operation.
+ *
+ * \param ssl             The SSL connection instance. It should not be
+ *                        modified other than via
+ *                        mbedtls_ssl_set_async_operation_data().
+ * \param output          Buffer containing the output (signature or decrypted
+ *                        data) on success.
+ * \param output_len      On success, number of bytes written to \p output.
+ * \param output_size     Size of the \p output buffer in bytes.
+ *
+ * \return          0 if output of the operation is available in the
+ *                  \p output buffer.
+ * \return          #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
+ *                  is still in progress. Subsequent requests for progress
+ *                  on the SSL connection will call the resume callback
+ *                  again.
+ * \return          Any other error means that the operation is aborted.
+ *                  The SSL handshake is aborted. The callback should
+ *                  use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
+ *                  use \c MBEDTLS_ERR_SSL_xxx error codes except as
+ *                  directed in the documentation of this callback.
+ */
+typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl,
+                                        unsigned char *output,
+                                        size_t *output_len,
+                                        size_t output_size );
+
+/**
+ * \brief           Callback type: cancel external operation.
+ *
+ *                  This callback is called if an SSL connection is closed
+ *                  while an asynchronous operation is in progress. Note that
+ *                  this callback is not called if the
+ *                  ::mbedtls_ssl_async_resume_t callback has run and has
+ *                  returned a value other than
+ *                  #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case
+ *                  the asynchronous operation has already completed.
+ *
+ *                  This function may call mbedtls_ssl_get_async_operation_data()
+ *                  to retrieve an operation context set by the start callback.
+ *
+ * \param ssl             The SSL connection instance. It should not be
+ *                        modified.
+ */
+typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+/*
+ * This structure is used for storing current session data.
+ */
+struct mbedtls_ssl_session
+{
+#if defined(MBEDTLS_HAVE_TIME)
+    mbedtls_time_t start;       /*!< starting time      */
+#endif
+    int ciphersuite;            /*!< chosen ciphersuite */
+    int compression;            /*!< chosen compression */
+    size_t id_len;              /*!< session id length  */
+    unsigned char id[32];       /*!< session identifier */
+    unsigned char master[48];   /*!< the master secret  */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    mbedtls_x509_crt *peer_cert;        /*!< peer X.509 cert chain */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+    uint32_t verify_result;          /*!<  verification result     */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+    unsigned char *ticket;      /*!< RFC 5077 session ticket */
+    size_t ticket_len;          /*!< session ticket length   */
+    uint32_t ticket_lifetime;   /*!< ticket lifetime hint    */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    unsigned char mfl_code;     /*!< MaxFragmentLength negotiated by peer */
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+    int trunc_hmac;             /*!< flag for truncated hmac activation   */
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    int encrypt_then_mac;       /*!< flag for EtM activation                */
+#endif
+};
+
+/**
+ * SSL/TLS configuration to be shared between mbedtls_ssl_context structures.
+ */
+struct mbedtls_ssl_config
+{
+    /* Group items by size (largest first) to minimize padding overhead */
+
+    /*
+     * Pointers
+     */
+
+    const int *ciphersuite_list[4]; /*!< allowed ciphersuites per version   */
+
+    /** Callback for printing debug output                                  */
+    void (*f_dbg)(void *, int, const char *, int, const char *);
+    void *p_dbg;                    /*!< context for the debug function     */
+
+    /** Callback for getting (pseudo-)random numbers                        */
+    int  (*f_rng)(void *, unsigned char *, size_t);
+    void *p_rng;                    /*!< context for the RNG function       */
+
+    /** Callback to retrieve a session from the cache                       */
+    int (*f_get_cache)(void *, mbedtls_ssl_session *);
+    /** Callback to store a session into the cache                          */
+    int (*f_set_cache)(void *, const mbedtls_ssl_session *);
+    void *p_cache;                  /*!< context for cache callbacks        */
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    /** Callback for setting cert according to SNI extension                */
+    int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *, size_t);
+    void *p_sni;                    /*!< context for SNI callback           */
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    /** Callback to customize X.509 certificate chain verification          */
+    int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
+    void *p_vrfy;                   /*!< context for X.509 verify calllback */
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    /** Callback to retrieve PSK key from identity                          */
+    int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, size_t);
+    void *p_psk;                    /*!< context for PSK callback           */
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+    /** Callback to create & write a cookie for ClientHello veirifcation    */
+    int (*f_cookie_write)( void *, unsigned char **, unsigned char *,
+                           const unsigned char *, size_t );
+    /** Callback to verify validity of a ClientHello cookie                 */
+    int (*f_cookie_check)( void *, const unsigned char *, size_t,
+                           const unsigned char *, size_t );
+    void *p_cookie;                 /*!< context for the cookie callbacks   */
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C)
+    /** Callback to create & write a session ticket                         */
+    int (*f_ticket_write)( void *, const mbedtls_ssl_session *,
+            unsigned char *, const unsigned char *, size_t *, uint32_t * );
+    /** Callback to parse a session ticket into a session structure         */
+    int (*f_ticket_parse)( void *, mbedtls_ssl_session *, unsigned char *, size_t);
+    void *p_ticket;                 /*!< context for the ticket callbacks   */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+    /** Callback to export key block and master secret                      */
+    int (*f_export_keys)( void *, const unsigned char *,
+            const unsigned char *, size_t, size_t, size_t );
+    void *p_export_keys;            /*!< context for key export callback    */
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */
+    mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s)        */
+    mbedtls_x509_crt *ca_chain;     /*!< trusted CAs                        */
+    mbedtls_x509_crl *ca_crl;       /*!< trusted CAs CRLs                   */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */
+    mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+    mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */
+    mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */
+    void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+    const int *sig_hashes;          /*!< allowed signature hashes           */
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+    const mbedtls_ecp_group_id *curve_list; /*!< allowed curves             */
+#endif
+
+#if defined(MBEDTLS_DHM_C)
+    mbedtls_mpi dhm_P;              /*!< prime modulus for DHM              */
+    mbedtls_mpi dhm_G;              /*!< generator for DHM                  */
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    unsigned char *psk;             /*!< pre-shared key. This field should
+                                         only be set via
+                                         mbedtls_ssl_conf_psk() */
+    size_t         psk_len;         /*!< length of the pre-shared key. This
+                                         field should only be set via
+                                         mbedtls_ssl_conf_psk() */
+    unsigned char *psk_identity;    /*!< identity for PSK negotiation. This
+                                         field should only be set via
+                                         mbedtls_ssl_conf_psk() */
+    size_t         psk_identity_len;/*!< length of identity. This field should
+                                         only be set via
+                                         mbedtls_ssl_conf_psk() */
+#endif
+
+#if defined(MBEDTLS_SSL_ALPN)
+    const char **alpn_list;         /*!< ordered list of protocols          */
+#endif
+
+    /*
+     * Numerical settings (int then char)
+     */
+
+    uint32_t read_timeout;          /*!< timeout for mbedtls_ssl_read (ms)  */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    uint32_t hs_timeout_min;        /*!< initial value of the handshake
+                                         retransmission timeout (ms)        */
+    uint32_t hs_timeout_max;        /*!< maximum value of the handshake
+                                         retransmission timeout (ms)        */
+#endif
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    int renego_max_records;         /*!< grace period for renegotiation     */
+    unsigned char renego_period[8]; /*!< value of the record counters
+                                         that triggers renegotiation        */
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+    unsigned int badmac_limit;      /*!< limit of records with a bad MAC    */
+#endif
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
+    unsigned int dhm_min_bitlen;    /*!< min. bit length of the DHM prime   */
+#endif
+
+    unsigned char max_major_ver;    /*!< max. major version used            */
+    unsigned char max_minor_ver;    /*!< max. minor version used            */
+    unsigned char min_major_ver;    /*!< min. major version used            */
+    unsigned char min_minor_ver;    /*!< min. minor version used            */
+
+    /*
+     * Flags (bitfields)
+     */
+
+    unsigned int endpoint : 1;      /*!< 0: client, 1: server               */
+    unsigned int transport : 1;     /*!< stream (TLS) or datagram (DTLS)    */
+    unsigned int authmode : 2;      /*!< MBEDTLS_SSL_VERIFY_XXX             */
+    /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE          */
+    unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX   */
+#if defined(MBEDTLS_ARC4_C)
+    unsigned int arc4_disabled : 1; /*!< blacklist RC4 ciphersuites?        */
+#endif
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    unsigned int mfl_code : 3;      /*!< desired fragment length            */
+#endif
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    unsigned int encrypt_then_mac : 1 ; /*!< negotiate encrypt-then-mac?    */
+#endif
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    unsigned int extended_ms : 1;   /*!< negotiate extended master secret?  */
+#endif
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+    unsigned int anti_replay : 1;   /*!< detect and prevent replay?         */
+#endif
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+    unsigned int cbc_record_splitting : 1;  /*!< do cbc record splitting    */
+#endif
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    unsigned int disable_renegotiation : 1; /*!< disable renegotiation?     */
+#endif
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+    unsigned int trunc_hmac : 1;    /*!< negotiate truncated hmac?          */
+#endif
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    unsigned int session_tickets : 1;   /*!< use session tickets?           */
+#endif
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
+    unsigned int fallback : 1;      /*!< is this a fallback?                */
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+    unsigned int cert_req_ca_list : 1;  /*!< enable sending CA list in
+                                          Certificate Request messages?     */
+#endif
+};
+
+
+struct mbedtls_ssl_context
+{
+    const mbedtls_ssl_config *conf; /*!< configuration information          */
+
+    /*
+     * Miscellaneous
+     */
+    int state;                  /*!< SSL handshake: current state     */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    int renego_status;          /*!< Initial, in progress, pending?   */
+    int renego_records_seen;    /*!< Records since renego request, or with DTLS,
+                                  number of retransmissions of request if
+                                  renego_max_records is < 0           */
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+    int major_ver;              /*!< equal to  MBEDTLS_SSL_MAJOR_VERSION_3    */
+    int minor_ver;              /*!< either 0 (SSL3) or 1 (TLS1.0)    */
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+    unsigned badmac_seen;       /*!< records with a bad MAC received    */
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
+
+    mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
+    mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
+    mbedtls_ssl_recv_timeout_t *f_recv_timeout;
+                                /*!< Callback for network receive with timeout */
+
+    void *p_bio;                /*!< context for I/O operations   */
+
+    /*
+     * Session layer
+     */
+    mbedtls_ssl_session *session_in;            /*!<  current session data (in)   */
+    mbedtls_ssl_session *session_out;           /*!<  current session data (out)  */
+    mbedtls_ssl_session *session;               /*!<  negotiated session data     */
+    mbedtls_ssl_session *session_negotiate;     /*!<  session data in negotiation */
+
+    mbedtls_ssl_handshake_params *handshake;    /*!<  params required only during
+                                              the handshake process        */
+
+    /*
+     * Record layer transformations
+     */
+    mbedtls_ssl_transform *transform_in;        /*!<  current transform params (in)   */
+    mbedtls_ssl_transform *transform_out;       /*!<  current transform params (in)   */
+    mbedtls_ssl_transform *transform;           /*!<  negotiated transform params     */
+    mbedtls_ssl_transform *transform_negotiate; /*!<  transform params in negotiation */
+
+    /*
+     * Timers
+     */
+    void *p_timer;              /*!< context for the timer callbacks */
+
+    mbedtls_ssl_set_timer_t *f_set_timer;       /*!< set timer callback */
+    mbedtls_ssl_get_timer_t *f_get_timer;       /*!< get timer callback */
+
+    /*
+     * Record layer (incoming data)
+     */
+    unsigned char *in_buf;      /*!< input buffer                     */
+    unsigned char *in_ctr;      /*!< 64-bit incoming message counter
+                                     TLS: maintained by us
+                                     DTLS: read from peer             */
+    unsigned char *in_hdr;      /*!< start of record header           */
+    unsigned char *in_len;      /*!< two-bytes message length field   */
+    unsigned char *in_iv;       /*!< ivlen-byte IV                    */
+    unsigned char *in_msg;      /*!< message contents (in_iv+ivlen)   */
+    unsigned char *in_offt;     /*!< read offset in application data  */
+
+    int in_msgtype;             /*!< record header: message type      */
+    size_t in_msglen;           /*!< record header: message length    */
+    size_t in_left;             /*!< amount of data read so far       */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    uint16_t in_epoch;          /*!< DTLS epoch for incoming records  */
+    size_t next_record_offset;  /*!< offset of the next record in datagram
+                                     (equal to in_left if none)       */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+    uint64_t in_window_top;     /*!< last validated record seq_num    */
+    uint64_t in_window;         /*!< bitmask for replay detection     */
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
+
+    size_t in_hslen;            /*!< current handshake message length,
+                                     including the handshake header   */
+    int nb_zero;                /*!< # of 0-length encrypted messages */
+
+    int keep_current_message;   /*!< drop or reuse current message
+                                     on next call to record layer? */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    uint8_t disable_datagram_packing;  /*!< Disable packing multiple records
+                                        *   within a single datagram.  */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    /*
+     * Record layer (outgoing data)
+     */
+    unsigned char *out_buf;     /*!< output buffer                    */
+    unsigned char *out_ctr;     /*!< 64-bit outgoing message counter  */
+    unsigned char *out_hdr;     /*!< start of record header           */
+    unsigned char *out_len;     /*!< two-bytes message length field   */
+    unsigned char *out_iv;      /*!< ivlen-byte IV                    */
+    unsigned char *out_msg;     /*!< message contents (out_iv+ivlen)  */
+
+    int out_msgtype;            /*!< record header: message type      */
+    size_t out_msglen;          /*!< record header: message length    */
+    size_t out_left;            /*!< amount of data not yet written   */
+
+    unsigned char cur_out_ctr[8]; /*!<  Outgoing record sequence  number. */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    uint16_t mtu;               /*!< path mtu, used to fragment outgoing messages */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    unsigned char *compress_buf;        /*!<  zlib data buffer        */
+#endif /* MBEDTLS_ZLIB_SUPPORT */
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+    signed char split_done;     /*!< current record already splitted? */
+#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
+
+    /*
+     * PKI layer
+     */
+    int client_auth;                    /*!<  flag for client auth.   */
+
+    /*
+     * User settings
+     */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    char *hostname;             /*!< expected peer CN for verification
+                                     (and SNI if available)                 */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_ALPN)
+    const char *alpn_chosen;    /*!<  negotiated protocol                   */
+#endif /* MBEDTLS_SSL_ALPN */
+
+    /*
+     * Information for DTLS hello verify
+     */
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+    unsigned char  *cli_id;         /*!<  transport-level ID of the client  */
+    size_t          cli_id_len;     /*!<  length of cli_id                  */
+#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
+
+    /*
+     * Secure renegotiation
+     */
+    /* needed to know when to send extension on server */
+    int secure_renegotiation;           /*!<  does peer support legacy or
+                                              secure renegotiation           */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    size_t verify_data_len;             /*!<  length of verify data stored   */
+    char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!<  previous handshake verify data */
+    char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!<  previous handshake verify data */
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+};
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+
+#define MBEDTLS_SSL_CHANNEL_OUTBOUND    0
+#define MBEDTLS_SSL_CHANNEL_INBOUND     1
+
+extern int (*mbedtls_ssl_hw_record_init)(mbedtls_ssl_context *ssl,
+                const unsigned char *key_enc, const unsigned char *key_dec,
+                size_t keylen,
+                const unsigned char *iv_enc,  const unsigned char *iv_dec,
+                size_t ivlen,
+                const unsigned char *mac_enc, const unsigned char *mac_dec,
+                size_t maclen);
+extern int (*mbedtls_ssl_hw_record_activate)(mbedtls_ssl_context *ssl, int direction);
+extern int (*mbedtls_ssl_hw_record_reset)(mbedtls_ssl_context *ssl);
+extern int (*mbedtls_ssl_hw_record_write)(mbedtls_ssl_context *ssl);
+extern int (*mbedtls_ssl_hw_record_read)(mbedtls_ssl_context *ssl);
+extern int (*mbedtls_ssl_hw_record_finish)(mbedtls_ssl_context *ssl);
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
+/**
+ * \brief               Return the name of the ciphersuite associated with the
+ *                      given ID
+ *
+ * \param ciphersuite_id SSL ciphersuite ID
+ *
+ * \return              a string containing the ciphersuite name
+ */
+const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id );
+
+/**
+ * \brief               Return the ID of the ciphersuite associated with the
+ *                      given name
+ *
+ * \param ciphersuite_name SSL ciphersuite name
+ *
+ * \return              the ID with the ciphersuite or 0 if not found
+ */
+int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name );
+
+/**
+ * \brief          Initialize an SSL context
+ *                 Just makes the context ready for mbedtls_ssl_setup() or
+ *                 mbedtls_ssl_free()
+ *
+ * \param ssl      SSL context
+ */
+void mbedtls_ssl_init( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Set up an SSL context for use
+ *
+ * \note           No copy of the configuration context is made, it can be
+ *                 shared by many mbedtls_ssl_context structures.
+ *
+ * \warning        The conf structure will be accessed during the session.
+ *                 It must not be modified or freed as long as the session
+ *                 is active.
+ *
+ * \warning        This function must be called exactly once per context.
+ *                 Calling mbedtls_ssl_setup again is not supported, even
+ *                 if no session is active.
+ *
+ * \param ssl      SSL context
+ * \param conf     SSL configuration to use
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED if
+ *                 memory allocation failed
+ */
+int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
+                       const mbedtls_ssl_config *conf );
+
+/**
+ * \brief          Reset an already initialized SSL context for re-use
+ *                 while retaining application-set variables, function
+ *                 pointers and data.
+ *
+ * \param ssl      SSL context
+ * \return         0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED,
+                   MBEDTLS_ERR_SSL_HW_ACCEL_FAILED or
+ *                 MBEDTLS_ERR_SSL_COMPRESSION_FAILED
+ */
+int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Set the current endpoint type
+ *
+ * \param conf     SSL configuration
+ * \param endpoint must be MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER
+ */
+void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint );
+
+/**
+ * \brief           Set the transport type (TLS or DTLS).
+ *                  Default: TLS
+ *
+ * \note            For DTLS, you must either provide a recv callback that
+ *                  doesn't block, or one that handles timeouts, see
+ *                  \c mbedtls_ssl_set_bio(). You also need to provide timer
+ *                  callbacks with \c mbedtls_ssl_set_timer_cb().
+ *
+ * \param conf      SSL configuration
+ * \param transport transport type:
+ *                  MBEDTLS_SSL_TRANSPORT_STREAM for TLS,
+ *                  MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS.
+ */
+void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport );
+
+/**
+ * \brief          Set the certificate verification mode
+ *                 Default: NONE on server, REQUIRED on client
+ *
+ * \param conf     SSL configuration
+ * \param authmode can be:
+ *
+ *  MBEDTLS_SSL_VERIFY_NONE:      peer certificate is not checked
+ *                        (default on server)
+ *                        (insecure on client)
+ *
+ *  MBEDTLS_SSL_VERIFY_OPTIONAL:  peer certificate is checked, however the
+ *                        handshake continues even if verification failed;
+ *                        mbedtls_ssl_get_verify_result() can be called after the
+ *                        handshake is complete.
+ *
+ *  MBEDTLS_SSL_VERIFY_REQUIRED:  peer *must* present a valid certificate,
+ *                        handshake is aborted if verification failed.
+ *                        (default on client)
+ *
+ * \note On client, MBEDTLS_SSL_VERIFY_REQUIRED is the recommended mode.
+ * With MBEDTLS_SSL_VERIFY_OPTIONAL, the user needs to call mbedtls_ssl_get_verify_result() at
+ * the right time(s), which may not be obvious, while REQUIRED always perform
+ * the verification as soon as possible. For example, REQUIRED was protecting
+ * against the "triple handshake" attack even before it was found.
+ */
+void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief          Set the verification callback (Optional).
+ *
+ *                 If set, the verify callback is called for each
+ *                 certificate in the chain. For implementation
+ *                 information, please see \c mbedtls_x509_crt_verify()
+ *
+ * \param conf     SSL configuration
+ * \param f_vrfy   verification function
+ * \param p_vrfy   verification parameter
+ */
+void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+                     void *p_vrfy );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+/**
+ * \brief          Set the random number generator callback
+ *
+ * \param conf     SSL configuration
+ * \param f_rng    RNG function
+ * \param p_rng    RNG parameter
+ */
+void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
+                  int (*f_rng)(void *, unsigned char *, size_t),
+                  void *p_rng );
+
+/**
+ * \brief          Set the debug callback
+ *
+ *                 The callback has the following argument:
+ *                 void *           opaque context for the callback
+ *                 int              debug level
+ *                 const char *     file name
+ *                 int              line number
+ *                 const char *     message
+ *
+ * \param conf     SSL configuration
+ * \param f_dbg    debug function
+ * \param p_dbg    debug parameter
+ */
+void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
+                  void (*f_dbg)(void *, int, const char *, int, const char *),
+                  void  *p_dbg );
+
+/**
+ * \brief          Set the underlying BIO callbacks for write, read and
+ *                 read-with-timeout.
+ *
+ * \param ssl      SSL context
+ * \param p_bio    parameter (context) shared by BIO callbacks
+ * \param f_send   write callback
+ * \param f_recv   read callback
+ * \param f_recv_timeout blocking read callback with timeout.
+ *
+ * \note           One of f_recv or f_recv_timeout can be NULL, in which case
+ *                 the other is used. If both are non-NULL, f_recv_timeout is
+ *                 used and f_recv is ignored (as if it were NULL).
+ *
+ * \note           The two most common use cases are:
+ *                 - non-blocking I/O, f_recv != NULL, f_recv_timeout == NULL
+ *                 - blocking I/O, f_recv == NULL, f_recv_timout != NULL
+ *
+ * \note           For DTLS, you need to provide either a non-NULL
+ *                 f_recv_timeout callback, or a f_recv that doesn't block.
+ *
+ * \note           See the documentations of \c mbedtls_ssl_sent_t,
+ *                 \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for
+ *                 the conventions those callbacks must follow.
+ *
+ * \note           On some platforms, net_sockets.c provides
+ *                 \c mbedtls_net_send(), \c mbedtls_net_recv() and
+ *                 \c mbedtls_net_recv_timeout() that are suitable to be used
+ *                 here.
+ */
+void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
+                          void *p_bio,
+                          mbedtls_ssl_send_t *f_send,
+                          mbedtls_ssl_recv_t *f_recv,
+                          mbedtls_ssl_recv_timeout_t *f_recv_timeout );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+/**
+ * \brief          Set the Maximum Tranport Unit (MTU).
+ *                 Special value: 0 means unset (no limit).
+ *                 This represents the maximum size of a datagram payload
+ *                 handled by the transport layer (usually UDP) as determined
+ *                 by the network link and stack. In practice, this controls
+ *                 the maximum size datagram the DTLS layer will pass to the
+ *                 \c f_send() callback set using \c mbedtls_ssl_set_bio().
+ *
+ * \note           The limit on datagram size is converted to a limit on
+ *                 record payload by subtracting the current overhead of
+ *                 encapsulation and encryption/authentication if any.
+ *
+ * \note           This can be called at any point during the connection, for
+ *                 example when a Path Maximum Transfer Unit (PMTU)
+ *                 estimate becomes available from other sources,
+ *                 such as lower (or higher) protocol layers.
+ *
+ * \note           This setting only controls the size of the packets we send,
+ *                 and does not restrict the size of the datagrams we're
+ *                 willing to receive. Client-side, you can request the
+ *                 server to use smaller records with \c
+ *                 mbedtls_ssl_conf_max_frag_len().
+ *
+ * \note           If both a MTU and a maximum fragment length have been
+ *                 configured (or negotiated with the peer), the resulting
+ *                 lower limit on record payload (see first note) is used.
+ *
+ * \note           This can only be used to decrease the maximum size
+ *                 of datagrams (hence records, see first note) sent. It
+ *                 cannot be used to increase the maximum size of records over
+ *                 the limit set by #MBEDTLS_SSL_OUT_CONTENT_LEN.
+ *
+ * \note           Values lower than the current record layer expansion will
+ *                 result in an error when trying to send data.
+ *
+ * \note           Using record compression together with a non-zero MTU value
+ *                 will result in an error when trying to send data.
+ *
+ * \param ssl      SSL context
+ * \param mtu      Value of the path MTU in bytes
+ */
+void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+/**
+ * \brief          Set the timeout period for mbedtls_ssl_read()
+ *                 (Default: no timeout.)
+ *
+ * \param conf     SSL configuration context
+ * \param timeout  Timeout value in milliseconds.
+ *                 Use 0 for no timeout (default).
+ *
+ * \note           With blocking I/O, this will only work if a non-NULL
+ *                 \c f_recv_timeout was set with \c mbedtls_ssl_set_bio().
+ *                 With non-blocking I/O, this will only work if timer
+ *                 callbacks were set with \c mbedtls_ssl_set_timer_cb().
+ *
+ * \note           With non-blocking I/O, you may also skip this function
+ *                 altogether and handle timeouts at the application layer.
+ */
+void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout );
+
+/**
+ * \brief          Set the timer callbacks (Mandatory for DTLS.)
+ *
+ * \param ssl      SSL context
+ * \param p_timer  parameter (context) shared by timer callbacks
+ * \param f_set_timer   set timer callback
+ * \param f_get_timer   get timer callback. Must return:
+ *
+ * \note           See the documentation of \c mbedtls_ssl_set_timer_t and
+ *                 \c mbedtls_ssl_get_timer_t for the conventions this pair of
+ *                 callbacks must follow.
+ *
+ * \note           On some platforms, timing.c provides
+ *                 \c mbedtls_timing_set_delay() and
+ *                 \c mbedtls_timing_get_delay() that are suitable for using
+ *                 here, except if using an event-driven style.
+ *
+ * \note           See also the "DTLS tutorial" article in our knowledge base.
+ *                 https://tls.mbed.org/kb/how-to/dtls-tutorial
+ */
+void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
+                               void *p_timer,
+                               mbedtls_ssl_set_timer_t *f_set_timer,
+                               mbedtls_ssl_get_timer_t *f_get_timer );
+
+/**
+ * \brief           Callback type: generate and write session ticket
+ *
+ * \note            This describes what a callback implementation should do.
+ *                  This callback should generate an encrypted and
+ *                  authenticated ticket for the session and write it to the
+ *                  output buffer. Here, ticket means the opaque ticket part
+ *                  of the NewSessionTicket structure of RFC 5077.
+ *
+ * \param p_ticket  Context for the callback
+ * \param session   SSL session to be written in the ticket
+ * \param start     Start of the output buffer
+ * \param end       End of the output buffer
+ * \param tlen      On exit, holds the length written
+ * \param lifetime  On exit, holds the lifetime of the ticket in seconds
+ *
+ * \return          0 if successful, or
+ *                  a specific MBEDTLS_ERR_XXX code.
+ */
+typedef int mbedtls_ssl_ticket_write_t( void *p_ticket,
+                                        const mbedtls_ssl_session *session,
+                                        unsigned char *start,
+                                        const unsigned char *end,
+                                        size_t *tlen,
+                                        uint32_t *lifetime );
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+/**
+ * \brief           Callback type: Export key block and master secret
+ *
+ * \note            This is required for certain uses of TLS, e.g. EAP-TLS
+ *                  (RFC 5216) and Thread. The key pointers are ephemeral and
+ *                  therefore must not be stored. The master secret and keys
+ *                  should not be used directly except as an input to a key
+ *                  derivation function.
+ *
+ * \param p_expkey  Context for the callback
+ * \param ms        Pointer to master secret (fixed length: 48 bytes)
+ * \param kb        Pointer to key block, see RFC 5246 section 6.3
+ *                  (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
+ * \param maclen    MAC length
+ * \param keylen    Key length
+ * \param ivlen     IV length
+ *
+ * \return          0 if successful, or
+ *                  a specific MBEDTLS_ERR_XXX code.
+ */
+typedef int mbedtls_ssl_export_keys_t( void *p_expkey,
+                                const unsigned char *ms,
+                                const unsigned char *kb,
+                                size_t maclen,
+                                size_t keylen,
+                                size_t ivlen );
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
+
+/**
+ * \brief           Callback type: parse and load session ticket
+ *
+ * \note            This describes what a callback implementation should do.
+ *                  This callback should parse a session ticket as generated
+ *                  by the corresponding mbedtls_ssl_ticket_write_t function,
+ *                  and, if the ticket is authentic and valid, load the
+ *                  session.
+ *
+ * \note            The implementation is allowed to modify the first len
+ *                  bytes of the input buffer, eg to use it as a temporary
+ *                  area for the decrypted ticket contents.
+ *
+ * \param p_ticket  Context for the callback
+ * \param session   SSL session to be loaded
+ * \param buf       Start of the buffer containing the ticket
+ * \param len       Length of the ticket.
+ *
+ * \return          0 if successful, or
+ *                  MBEDTLS_ERR_SSL_INVALID_MAC if not authentic, or
+ *                  MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED if expired, or
+ *                  any other non-zero code for other failures.
+ */
+typedef int mbedtls_ssl_ticket_parse_t( void *p_ticket,
+                                        mbedtls_ssl_session *session,
+                                        unsigned char *buf,
+                                        size_t len );
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_SRV_C)
+/**
+ * \brief           Configure SSL session ticket callbacks (server only).
+ *                  (Default: none.)
+ *
+ * \note            On server, session tickets are enabled by providing
+ *                  non-NULL callbacks.
+ *
+ * \note            On client, use \c mbedtls_ssl_conf_session_tickets().
+ *
+ * \param conf      SSL configuration context
+ * \param f_ticket_write    Callback for writing a ticket
+ * \param f_ticket_parse    Callback for parsing a ticket
+ * \param p_ticket          Context shared by the two callbacks
+ */
+void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
+        mbedtls_ssl_ticket_write_t *f_ticket_write,
+        mbedtls_ssl_ticket_parse_t *f_ticket_parse,
+        void *p_ticket );
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+/**
+ * \brief           Configure key export callback.
+ *                  (Default: none.)
+ *
+ * \note            See \c mbedtls_ssl_export_keys_t.
+ *
+ * \param conf      SSL configuration context
+ * \param f_export_keys     Callback for exporting keys
+ * \param p_export_keys     Context for the callback
+ */
+void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
+        mbedtls_ssl_export_keys_t *f_export_keys,
+        void *p_export_keys );
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+/**
+ * \brief           Configure asynchronous private key operation callbacks.
+ *
+ * \param conf              SSL configuration context
+ * \param f_async_sign      Callback to start a signature operation. See
+ *                          the description of ::mbedtls_ssl_async_sign_t
+ *                          for more information. This may be \c NULL if the
+ *                          external processor does not support any signature
+ *                          operation; in this case the private key object
+ *                          associated with the certificate will be used.
+ * \param f_async_decrypt   Callback to start a decryption operation. See
+ *                          the description of ::mbedtls_ssl_async_decrypt_t
+ *                          for more information. This may be \c NULL if the
+ *                          external processor does not support any decryption
+ *                          operation; in this case the private key object
+ *                          associated with the certificate will be used.
+ * \param f_async_resume    Callback to resume an asynchronous operation. See
+ *                          the description of ::mbedtls_ssl_async_resume_t
+ *                          for more information. This may not be \c NULL unless
+ *                          \p f_async_sign and \p f_async_decrypt are both
+ *                          \c NULL.
+ * \param f_async_cancel    Callback to cancel an asynchronous operation. See
+ *                          the description of ::mbedtls_ssl_async_cancel_t
+ *                          for more information. This may be \c NULL if
+ *                          no cleanup is needed.
+ * \param config_data       A pointer to configuration data which can be
+ *                          retrieved with
+ *                          mbedtls_ssl_conf_get_async_config_data(). The
+ *                          library stores this value without dereferencing it.
+ */
+void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf,
+                                        mbedtls_ssl_async_sign_t *f_async_sign,
+                                        mbedtls_ssl_async_decrypt_t *f_async_decrypt,
+                                        mbedtls_ssl_async_resume_t *f_async_resume,
+                                        mbedtls_ssl_async_cancel_t *f_async_cancel,
+                                        void *config_data );
+
+/**
+ * \brief           Retrieve the configuration data set by
+ *                  mbedtls_ssl_conf_async_private_cb().
+ *
+ * \param conf      SSL configuration context
+ * \return          The configuration data set by
+ *                  mbedtls_ssl_conf_async_private_cb().
+ */
+void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf );
+
+/**
+ * \brief           Retrieve the asynchronous operation user context.
+ *
+ * \note            This function may only be called while a handshake
+ *                  is in progress.
+ *
+ * \param ssl       The SSL context to access.
+ *
+ * \return          The asynchronous operation user context that was last
+ *                  set during the current handshake. If
+ *                  mbedtls_ssl_set_async_operation_data() has not yet been
+ *                  called during the current handshake, this function returns
+ *                  \c NULL.
+ */
+void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief           Retrieve the asynchronous operation user context.
+ *
+ * \note            This function may only be called while a handshake
+ *                  is in progress.
+ *
+ * \param ssl       The SSL context to access.
+ * \param ctx       The new value of the asynchronous operation user context.
+ *                  Call mbedtls_ssl_get_async_operation_data() later during the
+ *                  same handshake to retrieve this value.
+ */
+void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
+                                 void *ctx );
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+/**
+ * \brief          Callback type: generate a cookie
+ *
+ * \param ctx      Context for the callback
+ * \param p        Buffer to write to,
+ *                 must be updated to point right after the cookie
+ * \param end      Pointer to one past the end of the output buffer
+ * \param info     Client ID info that was passed to
+ *                 \c mbedtls_ssl_set_client_transport_id()
+ * \param ilen     Length of info in bytes
+ *
+ * \return         The callback must return 0 on success,
+ *                 or a negative error code.
+ */
+typedef int mbedtls_ssl_cookie_write_t( void *ctx,
+                                unsigned char **p, unsigned char *end,
+                                const unsigned char *info, size_t ilen );
+
+/**
+ * \brief          Callback type: verify a cookie
+ *
+ * \param ctx      Context for the callback
+ * \param cookie   Cookie to verify
+ * \param clen     Length of cookie
+ * \param info     Client ID info that was passed to
+ *                 \c mbedtls_ssl_set_client_transport_id()
+ * \param ilen     Length of info in bytes
+ *
+ * \return         The callback must return 0 if cookie is valid,
+ *                 or a negative error code.
+ */
+typedef int mbedtls_ssl_cookie_check_t( void *ctx,
+                                const unsigned char *cookie, size_t clen,
+                                const unsigned char *info, size_t ilen );
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+/**
+ * \brief           Register callbacks for DTLS cookies
+ *                  (Server only. DTLS only.)
+ *
+ *                  Default: dummy callbacks that fail, in order to force you to
+ *                  register working callbacks (and initialize their context).
+ *
+ *                  To disable HelloVerifyRequest, register NULL callbacks.
+ *
+ * \warning         Disabling hello verification allows your server to be used
+ *                  for amplification in DoS attacks against other hosts.
+ *                  Only disable if you known this can't happen in your
+ *                  particular environment.
+ *
+ * \note            See comments on \c mbedtls_ssl_handshake() about handling
+ *                  the MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED that is expected
+ *                  on the first handshake attempt when this is enabled.
+ *
+ * \note            This is also necessary to handle client reconnection from
+ *                  the same port as described in RFC 6347 section 4.2.8 (only
+ *                  the variant with cookies is supported currently). See
+ *                  comments on \c mbedtls_ssl_read() for details.
+ *
+ * \param conf              SSL configuration
+ * \param f_cookie_write    Cookie write callback
+ * \param f_cookie_check    Cookie check callback
+ * \param p_cookie          Context for both callbacks
+ */
+void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf,
+                           mbedtls_ssl_cookie_write_t *f_cookie_write,
+                           mbedtls_ssl_cookie_check_t *f_cookie_check,
+                           void *p_cookie );
+
+/**
+ * \brief          Set client's transport-level identification info.
+ *                 (Server only. DTLS only.)
+ *
+ *                 This is usually the IP address (and port), but could be
+ *                 anything identify the client depending on the underlying
+ *                 network stack. Used for HelloVerifyRequest with DTLS.
+ *                 This is *not* used to route the actual packets.
+ *
+ * \param ssl      SSL context
+ * \param info     Transport-level info identifying the client (eg IP + port)
+ * \param ilen     Length of info in bytes
+ *
+ * \note           An internal copy is made, so the info buffer can be reused.
+ *
+ * \return         0 on success,
+ *                 MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used on client,
+ *                 MBEDTLS_ERR_SSL_ALLOC_FAILED if out of memory.
+ */
+int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl,
+                                 const unsigned char *info,
+                                 size_t ilen );
+
+#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+/**
+ * \brief          Enable or disable anti-replay protection for DTLS.
+ *                 (DTLS only, no effect on TLS.)
+ *                 Default: enabled.
+ *
+ * \param conf     SSL configuration
+ * \param mode     MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED.
+ *
+ * \warning        Disabling this is a security risk unless the application
+ *                 protocol handles duplicated packets in a safe way. You
+ *                 should not disable this without careful consideration.
+ *                 However, if your application already detects duplicated
+ *                 packets and needs information about them to adjust its
+ *                 transmission strategy, then you'll want to disable this.
+ */
+void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode );
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+/**
+ * \brief          Set a limit on the number of records with a bad MAC
+ *                 before terminating the connection.
+ *                 (DTLS only, no effect on TLS.)
+ *                 Default: 0 (disabled).
+ *
+ * \param conf     SSL configuration
+ * \param limit    Limit, or 0 to disable.
+ *
+ * \note           If the limit is N, then the connection is terminated when
+ *                 the Nth non-authentic record is seen.
+ *
+ * \note           Records with an invalid header are not counted, only the
+ *                 ones going through the authentication-decryption phase.
+ *
+ * \note           This is a security trade-off related to the fact that it's
+ *                 often relatively easy for an active attacker ot inject UDP
+ *                 datagrams. On one hand, setting a low limit here makes it
+ *                 easier for such an attacker to forcibly terminated a
+ *                 connection. On the other hand, a high limit or no limit
+ *                 might make us waste resources checking authentication on
+ *                 many bogus packets.
+ */
+void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit );
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+/**
+ * \brief          Allow or disallow packing of multiple handshake records
+ *                 within a single datagram.
+ *
+ * \param ssl           The SSL context to configure.
+ * \param allow_packing This determines whether datagram packing may
+ *                      be used or not. A value of \c 0 means that every
+ *                      record will be sent in a separate datagram; a
+ *                      value of \c 1 means that, if space permits,
+ *                      multiple handshake messages (including CCS) belonging to
+ *                      a single flight may be packed within a single datagram.
+ *
+ * \note           This is enabled by default and should only be disabled
+ *                 for test purposes, or if datagram packing causes
+ *                 interoperability issues with peers that don't support it.
+ *
+ * \note           Allowing datagram packing reduces the network load since
+ *                 there's less overhead if multiple messages share the same
+ *                 datagram. Also, it increases the handshake efficiency
+ *                 since messages belonging to a single datagram will not
+ *                 be reordered in transit, and so future message buffering
+ *                 or flight retransmission (if no buffering is used) as
+ *                 means to deal with reordering are needed less frequently.
+ *
+ * \note           Application records are not affected by this option and
+ *                 are currently always sent in separate datagrams.
+ *
+ */
+void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl,
+                                       unsigned allow_packing );
+
+/**
+ * \brief          Set retransmit timeout values for the DTLS handshake.
+ *                 (DTLS only, no effect on TLS.)
+ *
+ * \param conf     SSL configuration
+ * \param min      Initial timeout value in milliseconds.
+ *                 Default: 1000 (1 second).
+ * \param max      Maximum timeout value in milliseconds.
+ *                 Default: 60000 (60 seconds).
+ *
+ * \note           Default values are from RFC 6347 section 4.2.4.1.
+ *
+ * \note           The 'min' value should typically be slightly above the
+ *                 expected round-trip time to your peer, plus whatever time
+ *                 it takes for the peer to process the message. For example,
+ *                 if your RTT is about 600ms and you peer needs up to 1s to
+ *                 do the cryptographic operations in the handshake, then you
+ *                 should set 'min' slightly above 1600. Lower values of 'min'
+ *                 might cause spurious resends which waste network resources,
+ *                 while larger value of 'min' will increase overall latency
+ *                 on unreliable network links.
+ *
+ * \note           The more unreliable your network connection is, the larger
+ *                 your max / min ratio needs to be in order to achieve
+ *                 reliable handshakes.
+ *
+ * \note           Messages are retransmitted up to log2(ceil(max/min)) times.
+ *                 For example, if min = 1s and max = 5s, the retransmit plan
+ *                 goes: send ... 1s -> resend ... 2s -> resend ... 4s ->
+ *                 resend ... 5s -> give up and return a timeout error.
+ */
+void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_SRV_C)
+/**
+ * \brief          Set the session cache callbacks (server-side only)
+ *                 If not set, no session resuming is done (except if session
+ *                 tickets are enabled too).
+ *
+ *                 The session cache has the responsibility to check for stale
+ *                 entries based on timeout. See RFC 5246 for recommendations.
+ *
+ *                 Warning: session.peer_cert is cleared by the SSL/TLS layer on
+ *                 connection shutdown, so do not cache the pointer! Either set
+ *                 it to NULL or make a full copy of the certificate.
+ *
+ *                 The get callback is called once during the initial handshake
+ *                 to enable session resuming. The get function has the
+ *                 following parameters: (void *parameter, mbedtls_ssl_session *session)
+ *                 If a valid entry is found, it should fill the master of
+ *                 the session object with the cached values and return 0,
+ *                 return 1 otherwise. Optionally peer_cert can be set as well
+ *                 if it is properly present in cache entry.
+ *
+ *                 The set callback is called once during the initial handshake
+ *                 to enable session resuming after the entire handshake has
+ *                 been finished. The set function has the following parameters:
+ *                 (void *parameter, const mbedtls_ssl_session *session). The function
+ *                 should create a cache entry for future retrieval based on
+ *                 the data in the session structure and should keep in mind
+ *                 that the mbedtls_ssl_session object presented (and all its referenced
+ *                 data) is cleared by the SSL/TLS layer when the connection is
+ *                 terminated. It is recommended to add metadata to determine if
+ *                 an entry is still valid in the future. Return 0 if
+ *                 successfully cached, return 1 otherwise.
+ *
+ * \param conf           SSL configuration
+ * \param p_cache        parmater (context) for both callbacks
+ * \param f_get_cache    session get callback
+ * \param f_set_cache    session set callback
+ */
+void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
+        void *p_cache,
+        int (*f_get_cache)(void *, mbedtls_ssl_session *),
+        int (*f_set_cache)(void *, const mbedtls_ssl_session *) );
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+/**
+ * \brief          Request resumption of session (client-side only)
+ *                 Session data is copied from presented session structure.
+ *
+ * \param ssl      SSL context
+ * \param session  session context
+ *
+ * \return         0 if successful,
+ *                 MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed,
+ *                 MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or
+ *                 arguments are otherwise invalid
+ *
+ * \sa             mbedtls_ssl_get_session()
+ */
+int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session );
+#endif /* MBEDTLS_SSL_CLI_C */
+
+/**
+ * \brief               Set the list of allowed ciphersuites and the preference
+ *                      order. First in the list has the highest preference.
+ *                      (Overrides all version-specific lists)
+ *
+ *                      The ciphersuites array is not copied, and must remain
+ *                      valid for the lifetime of the ssl_config.
+ *
+ *                      Note: The server uses its own preferences
+ *                      over the preference of the client unless
+ *                      MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined!
+ *
+ * \param conf          SSL configuration
+ * \param ciphersuites  0-terminated list of allowed ciphersuites
+ */
+void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
+                                   const int *ciphersuites );
+
+/**
+ * \brief               Set the list of allowed ciphersuites and the
+ *                      preference order for a specific version of the protocol.
+ *                      (Only useful on the server side)
+ *
+ *                      The ciphersuites array is not copied, and must remain
+ *                      valid for the lifetime of the ssl_config.
+ *
+ * \param conf          SSL configuration
+ * \param ciphersuites  0-terminated list of allowed ciphersuites
+ * \param major         Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3
+ *                      supported)
+ * \param minor         Minor version number (MBEDTLS_SSL_MINOR_VERSION_0,
+ *                      MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
+ *                      MBEDTLS_SSL_MINOR_VERSION_3 supported)
+ *
+ * \note                With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0
+ *                      and MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
+ */
+void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
+                                       const int *ciphersuites,
+                                       int major, int minor );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief          Set the X.509 security profile used for verification
+ *
+ * \note           The restrictions are enforced for all certificates in the
+ *                 chain. However, signatures in the handshake are not covered
+ *                 by this setting but by \b mbedtls_ssl_conf_sig_hashes().
+ *
+ * \param conf     SSL configuration
+ * \param profile  Profile to use
+ */
+void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf,
+                                    const mbedtls_x509_crt_profile *profile );
+
+/**
+ * \brief          Set the data required to verify peer certificate
+ *
+ * \note           See \c mbedtls_x509_crt_verify() for notes regarding the
+ *                 parameters ca_chain (maps to trust_ca for that function)
+ *                 and ca_crl.
+ *
+ * \param conf     SSL configuration
+ * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs)
+ * \param ca_crl   trusted CA CRLs
+ */
+void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
+                               mbedtls_x509_crt *ca_chain,
+                               mbedtls_x509_crl *ca_crl );
+
+/**
+ * \brief          Set own certificate chain and private key
+ *
+ * \note           own_cert should contain in order from the bottom up your
+ *                 certificate chain. The top certificate (self-signed)
+ *                 can be omitted.
+ *
+ * \note           On server, this function can be called multiple times to
+ *                 provision more than one cert/key pair (eg one ECDSA, one
+ *                 RSA with SHA-256, one RSA with SHA-1). An adequate
+ *                 certificate will be selected according to the client's
+ *                 advertised capabilities. In case mutliple certificates are
+ *                 adequate, preference is given to the one set by the first
+ *                 call to this function, then second, etc.
+ *
+ * \note           On client, only the first call has any effect. That is,
+ *                 only one client certificate can be provisioned. The
+ *                 server's preferences in its CertficateRequest message will
+ *                 be ignored and our only cert will be sent regardless of
+ *                 whether it matches those preferences - the server can then
+ *                 decide what it wants to do with it.
+ *
+ * \note           The provided \p pk_key needs to match the public key in the
+ *                 first certificate in \p own_cert, or all handshakes using
+ *                 that certificate will fail. It is your responsibility
+ *                 to ensure that; this function will not perform any check.
+ *                 You may use mbedtls_pk_check_pair() in order to perform
+ *                 this check yourself, but be aware that this function can
+ *                 be computationally expensive on some key types.
+ *
+ * \param conf     SSL configuration
+ * \param own_cert own public certificate chain
+ * \param pk_key   own private key
+ *
+ * \return         0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED
+ */
+int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
+                              mbedtls_x509_crt *own_cert,
+                              mbedtls_pk_context *pk_key );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+/**
+ * \brief          Set the Pre Shared Key (PSK) and the expected identity name
+ *
+ * \note           This is mainly useful for clients. Servers will usually
+ *                 want to use \c mbedtls_ssl_conf_psk_cb() instead.
+ *
+ * \note           Currently clients can only register one pre-shared key.
+ *                 In other words, the servers' identity hint is ignored.
+ *                 Support for setting multiple PSKs on clients and selecting
+ *                 one based on the identity hint is not a planned feature but
+ *                 feedback is welcomed.
+ *
+ * \param conf     SSL configuration
+ * \param psk      pointer to the pre-shared key
+ * \param psk_len  pre-shared key length
+ * \param psk_identity      pointer to the pre-shared key identity
+ * \param psk_identity_len  identity key length
+ *
+ * \return         0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED
+ */
+int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
+                const unsigned char *psk, size_t psk_len,
+                const unsigned char *psk_identity, size_t psk_identity_len );
+
+
+/**
+ * \brief          Set the Pre Shared Key (PSK) for the current handshake
+ *
+ * \note           This should only be called inside the PSK callback,
+ *                 ie the function passed to \c mbedtls_ssl_conf_psk_cb().
+ *
+ * \param ssl      SSL context
+ * \param psk      pointer to the pre-shared key
+ * \param psk_len  pre-shared key length
+ *
+ * \return         0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED
+ */
+int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
+                            const unsigned char *psk, size_t psk_len );
+
+/**
+ * \brief          Set the PSK callback (server-side only).
+ *
+ *                 If set, the PSK callback is called for each
+ *                 handshake where a PSK ciphersuite was negotiated.
+ *                 The caller provides the identity received and wants to
+ *                 receive the actual PSK data and length.
+ *
+ *                 The callback has the following parameters: (void *parameter,
+ *                 mbedtls_ssl_context *ssl, const unsigned char *psk_identity,
+ *                 size_t identity_len)
+ *                 If a valid PSK identity is found, the callback should use
+ *                 \c mbedtls_ssl_set_hs_psk() on the ssl context to set the
+ *                 correct PSK and return 0.
+ *                 Any other return value will result in a denied PSK identity.
+ *
+ * \note           If you set a PSK callback using this function, then you
+ *                 don't need to set a PSK key and identity using
+ *                 \c mbedtls_ssl_conf_psk().
+ *
+ * \param conf     SSL configuration
+ * \param f_psk    PSK identity function
+ * \param p_psk    PSK identity parameter
+ */
+void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
+                     int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
+                                  size_t),
+                     void *p_psk );
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED    __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+
+/**
+ * \brief          Set the Diffie-Hellman public P and G values,
+ *                 read as hexadecimal strings (server-side only)
+ *                 (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG])
+ *
+ * \param conf     SSL configuration
+ * \param dhm_P    Diffie-Hellman-Merkle modulus
+ * \param dhm_G    Diffie-Hellman-Merkle generator
+ *
+ * \deprecated     Superseded by \c mbedtls_ssl_conf_dh_param_bin.
+ *
+ * \return         0 if successful
+ */
+MBEDTLS_DEPRECATED int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf,
+                                                  const char *dhm_P,
+                                                  const char *dhm_G );
+
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/**
+ * \brief          Set the Diffie-Hellman public P and G values
+ *                 from big-endian binary presentations.
+ *                 (Default values: MBEDTLS_DHM_RFC3526_MODP_2048_[PG]_BIN)
+ *
+ * \param conf     SSL configuration
+ * \param dhm_P    Diffie-Hellman-Merkle modulus in big-endian binary form
+ * \param P_len    Length of DHM modulus
+ * \param dhm_G    Diffie-Hellman-Merkle generator in big-endian binary form
+ * \param G_len    Length of DHM generator
+ *
+ * \return         0 if successful
+ */
+int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
+                                   const unsigned char *dhm_P, size_t P_len,
+                                   const unsigned char *dhm_G,  size_t G_len );
+
+/**
+ * \brief          Set the Diffie-Hellman public P and G values,
+ *                 read from existing context (server-side only)
+ *
+ * \param conf     SSL configuration
+ * \param dhm_ctx  Diffie-Hellman-Merkle context
+ *
+ * \return         0 if successful
+ */
+int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx );
+#endif /* MBEDTLS_DHM_C && defined(MBEDTLS_SSL_SRV_C) */
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
+/**
+ * \brief          Set the minimum length for Diffie-Hellman parameters.
+ *                 (Client-side only.)
+ *                 (Default: 1024 bits.)
+ *
+ * \param conf     SSL configuration
+ * \param bitlen   Minimum bit length of the DHM prime
+ */
+void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
+                                      unsigned int bitlen );
+#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_ECP_C)
+/**
+ * \brief          Set the allowed curves in order of preference.
+ *                 (Default: all defined curves.)
+ *
+ *                 On server: this only affects selection of the ECDHE curve;
+ *                 the curves used for ECDH and ECDSA are determined by the
+ *                 list of available certificates instead.
+ *
+ *                 On client: this affects the list of curves offered for any
+ *                 use. The server can override our preference order.
+ *
+ *                 Both sides: limits the set of curves accepted for use in
+ *                 ECDHE and in the peer's end-entity certificate.
+ *
+ * \note           This has no influence on which curves are allowed inside the
+ *                 certificate chains, see \c mbedtls_ssl_conf_cert_profile()
+ *                 for that. For the end-entity certificate however, the key
+ *                 will be accepted only if it is allowed both by this list
+ *                 and by the cert profile.
+ *
+ * \note           This list should be ordered by decreasing preference
+ *                 (preferred curve first).
+ *
+ * \param conf     SSL configuration
+ * \param curves   Ordered list of allowed curves,
+ *                 terminated by MBEDTLS_ECP_DP_NONE.
+ */
+void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
+                              const mbedtls_ecp_group_id *curves );
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+/**
+ * \brief          Set the allowed hashes for signatures during the handshake.
+ *                 (Default: all available hashes except MD5.)
+ *
+ * \note           This only affects which hashes are offered and can be used
+ *                 for signatures during the handshake. Hashes for message
+ *                 authentication and the TLS PRF are controlled by the
+ *                 ciphersuite, see \c mbedtls_ssl_conf_ciphersuites(). Hashes
+ *                 used for certificate signature are controlled by the
+ *                 verification profile, see \c mbedtls_ssl_conf_cert_profile().
+ *
+ * \note           This list should be ordered by decreasing preference
+ *                 (preferred hash first).
+ *
+ * \param conf     SSL configuration
+ * \param hashes   Ordered list of allowed signature hashes,
+ *                 terminated by \c MBEDTLS_MD_NONE.
+ */
+void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
+                                  const int *hashes );
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief          Set or reset the hostname to check against the received
+ *                 server certificate. It sets the ServerName TLS extension,
+ *                 too, if that extension is enabled. (client-side only)
+ *
+ * \param ssl      SSL context
+ * \param hostname the server hostname, may be NULL to clear hostname
+
+ * \note           Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN.
+ *
+ * \return         0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on
+ *                 allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on
+ *                 too long input hostname.
+ *
+ *                 Hostname set to the one provided on success (cleared
+ *                 when NULL). On allocation failure hostname is cleared.
+ *                 On too long input failure, old hostname is unchanged.
+ */
+int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+/**
+ * \brief          Set own certificate and key for the current handshake
+ *
+ * \note           Same as \c mbedtls_ssl_conf_own_cert() but for use within
+ *                 the SNI callback.
+ *
+ * \param ssl      SSL context
+ * \param own_cert own public certificate chain
+ * \param pk_key   own private key
+ *
+ * \return         0 on success or MBEDTLS_ERR_SSL_ALLOC_FAILED
+ */
+int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl,
+                                 mbedtls_x509_crt *own_cert,
+                                 mbedtls_pk_context *pk_key );
+
+/**
+ * \brief          Set the data required to verify peer certificate for the
+ *                 current handshake
+ *
+ * \note           Same as \c mbedtls_ssl_conf_ca_chain() but for use within
+ *                 the SNI callback.
+ *
+ * \param ssl      SSL context
+ * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs)
+ * \param ca_crl   trusted CA CRLs
+ */
+void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl,
+                                  mbedtls_x509_crt *ca_chain,
+                                  mbedtls_x509_crl *ca_crl );
+
+/**
+ * \brief          Set authmode for the current handshake.
+ *
+ * \note           Same as \c mbedtls_ssl_conf_authmode() but for use within
+ *                 the SNI callback.
+ *
+ * \param ssl      SSL context
+ * \param authmode MBEDTLS_SSL_VERIFY_NONE, MBEDTLS_SSL_VERIFY_OPTIONAL or
+ *                 MBEDTLS_SSL_VERIFY_REQUIRED
+ */
+void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
+                                  int authmode );
+
+/**
+ * \brief          Set server side ServerName TLS extension callback
+ *                 (optional, server-side only).
+ *
+ *                 If set, the ServerName callback is called whenever the
+ *                 server receives a ServerName TLS extension from the client
+ *                 during a handshake. The ServerName callback has the
+ *                 following parameters: (void *parameter, mbedtls_ssl_context *ssl,
+ *                 const unsigned char *hostname, size_t len). If a suitable
+ *                 certificate is found, the callback must set the
+ *                 certificate(s) and key(s) to use with \c
+ *                 mbedtls_ssl_set_hs_own_cert() (can be called repeatedly),
+ *                 and may optionally adjust the CA and associated CRL with \c
+ *                 mbedtls_ssl_set_hs_ca_chain() as well as the client
+ *                 authentication mode with \c mbedtls_ssl_set_hs_authmode(),
+ *                 then must return 0. If no matching name is found, the
+ *                 callback must either set a default cert, or
+ *                 return non-zero to abort the handshake at this point.
+ *
+ * \param conf     SSL configuration
+ * \param f_sni    verification function
+ * \param p_sni    verification parameter
+ */
+void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
+                  int (*f_sni)(void *, mbedtls_ssl_context *, const unsigned char *,
+                               size_t),
+                  void *p_sni );
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+/**
+ * \brief          Set the EC J-PAKE password for current handshake.
+ *
+ * \note           An internal copy is made, and destroyed as soon as the
+ *                 handshake is completed, or when the SSL context is reset or
+ *                 freed.
+ *
+ * \note           The SSL context needs to be already set up. The right place
+ *                 to call this function is between \c mbedtls_ssl_setup() or
+ *                 \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake().
+ *
+ * \param ssl      SSL context
+ * \param pw       EC J-PAKE password (pre-shared secret)
+ * \param pw_len   length of pw in bytes
+ *
+ * \return         0 on success, or a negative error code.
+ */
+int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
+                                         const unsigned char *pw,
+                                         size_t pw_len );
+#endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_SSL_ALPN)
+/**
+ * \brief          Set the supported Application Layer Protocols.
+ *
+ * \param conf     SSL configuration
+ * \param protos   Pointer to a NULL-terminated list of supported protocols,
+ *                 in decreasing preference order. The pointer to the list is
+ *                 recorded by the library for later reference as required, so
+ *                 the lifetime of the table must be atleast as long as the
+ *                 lifetime of the SSL configuration structure.
+ *
+ * \return         0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
+ */
+int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos );
+
+/**
+ * \brief          Get the name of the negotiated Application Layer Protocol.
+ *                 This function should be called after the handshake is
+ *                 completed.
+ *
+ * \param ssl      SSL context
+ *
+ * \return         Protcol name, or NULL if no protocol was negotiated.
+ */
+const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_ALPN */
+
+/**
+ * \brief          Set the maximum supported version sent from the client side
+ *                 and/or accepted at the server side
+ *                 (Default: MBEDTLS_SSL_MAX_MAJOR_VERSION, MBEDTLS_SSL_MAX_MINOR_VERSION)
+ *
+ * \note           This ignores ciphersuites from higher versions.
+ *
+ * \note           With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and
+ *                 MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
+ *
+ * \param conf     SSL configuration
+ * \param major    Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported)
+ * \param minor    Minor version number (MBEDTLS_SSL_MINOR_VERSION_0,
+ *                 MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
+ *                 MBEDTLS_SSL_MINOR_VERSION_3 supported)
+ */
+void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor );
+
+/**
+ * \brief          Set the minimum accepted SSL/TLS protocol version
+ *                 (Default: TLS 1.0)
+ *
+ * \note           Input outside of the SSL_MAX_XXXXX_VERSION and
+ *                 SSL_MIN_XXXXX_VERSION range is ignored.
+ *
+ * \note           MBEDTLS_SSL_MINOR_VERSION_0 (SSL v3) should be avoided.
+ *
+ * \note           With DTLS, use MBEDTLS_SSL_MINOR_VERSION_2 for DTLS 1.0 and
+ *                 MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
+ *
+ * \param conf     SSL configuration
+ * \param major    Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported)
+ * \param minor    Minor version number (MBEDTLS_SSL_MINOR_VERSION_0,
+ *                 MBEDTLS_SSL_MINOR_VERSION_1 and MBEDTLS_SSL_MINOR_VERSION_2,
+ *                 MBEDTLS_SSL_MINOR_VERSION_3 supported)
+ */
+void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor );
+
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
+/**
+ * \brief          Set the fallback flag (client-side only).
+ *                 (Default: MBEDTLS_SSL_IS_NOT_FALLBACK).
+ *
+ * \note           Set to MBEDTLS_SSL_IS_FALLBACK when preparing a fallback
+ *                 connection, that is a connection with max_version set to a
+ *                 lower value than the value you're willing to use. Such
+ *                 fallback connections are not recommended but are sometimes
+ *                 necessary to interoperate with buggy (version-intolerant)
+ *                 servers.
+ *
+ * \warning        You should NOT set this to MBEDTLS_SSL_IS_FALLBACK for
+ *                 non-fallback connections! This would appear to work for a
+ *                 while, then cause failures when the server is upgraded to
+ *                 support a newer TLS version.
+ *
+ * \param conf     SSL configuration
+ * \param fallback MBEDTLS_SSL_IS_NOT_FALLBACK or MBEDTLS_SSL_IS_FALLBACK
+ */
+void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback );
+#endif /* MBEDTLS_SSL_FALLBACK_SCSV && MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+/**
+ * \brief           Enable or disable Encrypt-then-MAC
+ *                  (Default: MBEDTLS_SSL_ETM_ENABLED)
+ *
+ * \note            This should always be enabled, it is a security
+ *                  improvement, and should not cause any interoperability
+ *                  issue (used only if the peer supports it too).
+ *
+ * \param conf      SSL configuration
+ * \param etm       MBEDTLS_SSL_ETM_ENABLED or MBEDTLS_SSL_ETM_DISABLED
+ */
+void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm );
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+/**
+ * \brief           Enable or disable Extended Master Secret negotiation.
+ *                  (Default: MBEDTLS_SSL_EXTENDED_MS_ENABLED)
+ *
+ * \note            This should always be enabled, it is a security fix to the
+ *                  protocol, and should not cause any interoperability issue
+ *                  (used only if the peer supports it too).
+ *
+ * \param conf      SSL configuration
+ * \param ems       MBEDTLS_SSL_EXTENDED_MS_ENABLED or MBEDTLS_SSL_EXTENDED_MS_DISABLED
+ */
+void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems );
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+#if defined(MBEDTLS_ARC4_C)
+/**
+ * \brief          Disable or enable support for RC4
+ *                 (Default: MBEDTLS_SSL_ARC4_DISABLED)
+ *
+ * \warning        Use of RC4 in DTLS/TLS has been prohibited by RFC 7465
+ *                 for security reasons. Use at your own risk.
+ *
+ * \note           This function is deprecated and will likely be removed in
+ *                 a future version of the library.
+ *                 RC4 is disabled by default at compile time and needs to be
+ *                 actively enabled for use with legacy systems.
+ *
+ * \param conf     SSL configuration
+ * \param arc4     MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED
+ */
+void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 );
+#endif /* MBEDTLS_ARC4_C */
+
+#if defined(MBEDTLS_SSL_SRV_C)
+/**
+ * \brief          Whether to send a list of acceptable CAs in
+ *                 CertificateRequest messages.
+ *                 (Default: do send)
+ *
+ * \param conf     SSL configuration
+ * \param cert_req_ca_list   MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED or
+ *                          MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED
+ */
+void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf,
+                                          char cert_req_ca_list );
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+/**
+ * \brief          Set the maximum fragment length to emit and/or negotiate
+ *                 (Default: the smaller of MBEDTLS_SSL_IN_CONTENT_LEN and
+ *                 MBEDTLS_SSL_OUT_CONTENT_LEN, usually 2^14 bytes)
+ *                 (Server: set maximum fragment length to emit,
+ *                 usually negotiated by the client during handshake
+ *                 (Client: set maximum fragment length to emit *and*
+ *                 negotiate with the server during handshake)
+ *
+ * \note           With TLS, this currently only affects ApplicationData (sent
+ *                 with \c mbedtls_ssl_read()), not handshake messages.
+ *                 With DTLS, this affects both ApplicationData and handshake.
+ *
+ * \note           This sets the maximum length for a record's payload,
+ *                 excluding record overhead that will be added to it, see
+ *                 \c mbedtls_ssl_get_record_expansion().
+ *
+ * \note           For DTLS, it is also possible to set a limit for the total
+ *                 size of daragrams passed to the transport layer, including
+ *                 record overhead, see \c mbedtls_ssl_set_mtu().
+ *
+ * \param conf     SSL configuration
+ * \param mfl_code Code for maximum fragment length (allowed values:
+ *                 MBEDTLS_SSL_MAX_FRAG_LEN_512,  MBEDTLS_SSL_MAX_FRAG_LEN_1024,
+ *                 MBEDTLS_SSL_MAX_FRAG_LEN_2048, MBEDTLS_SSL_MAX_FRAG_LEN_4096)
+ *
+ * \return         0 if successful or MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+ */
+int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code );
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+/**
+ * \brief          Activate negotiation of truncated HMAC
+ *                 (Default: MBEDTLS_SSL_TRUNC_HMAC_DISABLED)
+ *
+ * \param conf     SSL configuration
+ * \param truncate Enable or disable (MBEDTLS_SSL_TRUNC_HMAC_ENABLED or
+ *                                    MBEDTLS_SSL_TRUNC_HMAC_DISABLED)
+ */
+void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate );
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+/**
+ * \brief          Enable / Disable 1/n-1 record splitting
+ *                 (Default: MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED)
+ *
+ * \note           Only affects SSLv3 and TLS 1.0, not higher versions.
+ *                 Does not affect non-CBC ciphersuites in any version.
+ *
+ * \param conf     SSL configuration
+ * \param split    MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED or
+ *                 MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED
+ */
+void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split );
+#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+/**
+ * \brief          Enable / Disable session tickets (client only).
+ *                 (Default: MBEDTLS_SSL_SESSION_TICKETS_ENABLED.)
+ *
+ * \note           On server, use \c mbedtls_ssl_conf_session_tickets_cb().
+ *
+ * \param conf     SSL configuration
+ * \param use_tickets   Enable or disable (MBEDTLS_SSL_SESSION_TICKETS_ENABLED or
+ *                                         MBEDTLS_SSL_SESSION_TICKETS_DISABLED)
+ */
+void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets );
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+/**
+ * \brief          Enable / Disable renegotiation support for connection when
+ *                 initiated by peer
+ *                 (Default: MBEDTLS_SSL_RENEGOTIATION_DISABLED)
+ *
+ * \warning        It is recommended to always disable renegotation unless you
+ *                 know you need it and you know what you're doing. In the
+ *                 past, there have been several issues associated with
+ *                 renegotiation or a poor understanding of its properties.
+ *
+ * \note           Server-side, enabling renegotiation also makes the server
+ *                 susceptible to a resource DoS by a malicious client.
+ *
+ * \param conf    SSL configuration
+ * \param renegotiation     Enable or disable (MBEDTLS_SSL_RENEGOTIATION_ENABLED or
+ *                                             MBEDTLS_SSL_RENEGOTIATION_DISABLED)
+ */
+void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation );
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+/**
+ * \brief          Prevent or allow legacy renegotiation.
+ *                 (Default: MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION)
+ *
+ *                 MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION allows connections to
+ *                 be established even if the peer does not support
+ *                 secure renegotiation, but does not allow renegotiation
+ *                 to take place if not secure.
+ *                 (Interoperable and secure option)
+ *
+ *                 MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION allows renegotiations
+ *                 with non-upgraded peers. Allowing legacy renegotiation
+ *                 makes the connection vulnerable to specific man in the
+ *                 middle attacks. (See RFC 5746)
+ *                 (Most interoperable and least secure option)
+ *
+ *                 MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE breaks off connections
+ *                 if peer does not support secure renegotiation. Results
+ *                 in interoperability issues with non-upgraded peers
+ *                 that do not support renegotiation altogether.
+ *                 (Most secure option, interoperability issues)
+ *
+ * \param conf     SSL configuration
+ * \param allow_legacy  Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION,
+ *                                        SSL_ALLOW_LEGACY_RENEGOTIATION or
+ *                                        MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE)
+ */
+void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+/**
+ * \brief          Enforce renegotiation requests.
+ *                 (Default: enforced, max_records = 16)
+ *
+ *                 When we request a renegotiation, the peer can comply or
+ *                 ignore the request. This function allows us to decide
+ *                 whether to enforce our renegotiation requests by closing
+ *                 the connection if the peer doesn't comply.
+ *
+ *                 However, records could already be in transit from the peer
+ *                 when the request is emitted. In order to increase
+ *                 reliability, we can accept a number of records before the
+ *                 expected handshake records.
+ *
+ *                 The optimal value is highly dependent on the specific usage
+ *                 scenario.
+ *
+ * \note           With DTLS and server-initiated renegotiation, the
+ *                 HelloRequest is retransmited every time mbedtls_ssl_read() times
+ *                 out or receives Application Data, until:
+ *                 - max_records records have beens seen, if it is >= 0, or
+ *                 - the number of retransmits that would happen during an
+ *                 actual handshake has been reached.
+ *                 Please remember the request might be lost a few times
+ *                 if you consider setting max_records to a really low value.
+ *
+ * \warning        On client, the grace period can only happen during
+ *                 mbedtls_ssl_read(), as opposed to mbedtls_ssl_write() and mbedtls_ssl_renegotiate()
+ *                 which always behave as if max_record was 0. The reason is,
+ *                 if we receive application data from the server, we need a
+ *                 place to write it, which only happens during mbedtls_ssl_read().
+ *
+ * \param conf     SSL configuration
+ * \param max_records Use MBEDTLS_SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to
+ *                 enforce renegotiation, or a non-negative value to enforce
+ *                 it but allow for a grace period of max_records records.
+ */
+void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records );
+
+/**
+ * \brief          Set record counter threshold for periodic renegotiation.
+ *                 (Default: 2^48 - 1)
+ *
+ *                 Renegotiation is automatically triggered when a record
+ *                 counter (outgoing or ingoing) crosses the defined
+ *                 threshold. The default value is meant to prevent the
+ *                 connection from being closed when the counter is about to
+ *                 reached its maximal value (it is not allowed to wrap).
+ *
+ *                 Lower values can be used to enforce policies such as "keys
+ *                 must be refreshed every N packets with cipher X".
+ *
+ *                 The renegotiation period can be disabled by setting
+ *                 conf->disable_renegotiation to
+ *                 MBEDTLS_SSL_RENEGOTIATION_DISABLED.
+ *
+ * \note           When the configured transport is
+ *                 MBEDTLS_SSL_TRANSPORT_DATAGRAM the maximum renegotiation
+ *                 period is 2^48 - 1, and for MBEDTLS_SSL_TRANSPORT_STREAM,
+ *                 the maximum renegotiation period is 2^64 - 1.
+ *
+ * \param conf     SSL configuration
+ * \param period   The threshold value: a big-endian 64-bit number.
+ */
+void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
+                                   const unsigned char period[8] );
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+/**
+ * \brief          Check if there is data already read from the
+ *                 underlying transport but not yet processed.
+ *
+ * \param ssl      SSL context
+ *
+ * \return         0 if nothing's pending, 1 otherwise.
+ *
+ * \note           This is different in purpose and behaviour from
+ *                 \c mbedtls_ssl_get_bytes_avail in that it considers
+ *                 any kind of unprocessed data, not only unread
+ *                 application data. If \c mbedtls_ssl_get_bytes
+ *                 returns a non-zero value, this function will
+ *                 also signal pending data, but the converse does
+ *                 not hold. For example, in DTLS there might be
+ *                 further records waiting to be processed from
+ *                 the current underlying transport's datagram.
+ *
+ * \note           If this function returns 1 (data pending), this
+ *                 does not imply that a subsequent call to
+ *                 \c mbedtls_ssl_read will provide any data;
+ *                 e.g., the unprocessed data might turn out
+ *                 to be an alert or a handshake message.
+ *
+ * \note           This function is useful in the following situation:
+ *                 If the SSL/TLS module successfully returns from an
+ *                 operation - e.g. a handshake or an application record
+ *                 read - and you're awaiting incoming data next, you
+ *                 must not immediately idle on the underlying transport
+ *                 to have data ready, but you need to check the value
+ *                 of this function first. The reason is that the desired
+ *                 data might already be read but not yet processed.
+ *                 If, in contrast, a previous call to the SSL/TLS module
+ *                 returned MBEDTLS_ERR_SSL_WANT_READ, it is not necessary
+ *                 to call this function, as the latter error code entails
+ *                 that all internal data has been processed.
+ *
+ */
+int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Return the number of application data bytes
+ *                 remaining to be read from the current record.
+ *
+ * \param ssl      SSL context
+ *
+ * \return         How many bytes are available in the application
+ *                 data record read buffer.
+ *
+ * \note           When working over a datagram transport, this is
+ *                 useful to detect the current datagram's boundary
+ *                 in case \c mbedtls_ssl_read has written the maximal
+ *                 amount of data fitting into the input buffer.
+ *
+ */
+size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Return the result of the certificate verification
+ *
+ * \param ssl      The SSL context to use.
+ *
+ * \return         \c 0 if the certificate verification was successful.
+ * \return         \c -1u if the result is not available. This may happen
+ *                 e.g. if the handshake aborts early, or a verification
+ *                 callback returned a fatal error.
+ * \return         A bitwise combination of \c MBEDTLS_X509_BADCERT_XXX
+ *                 and \c MBEDTLS_X509_BADCRL_XXX failure flags; see x509.h.
+ */
+uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Return the name of the current ciphersuite
+ *
+ * \param ssl      SSL context
+ *
+ * \return         a string containing the ciphersuite name
+ */
+const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Return the current SSL version (SSLv3/TLSv1/etc)
+ *
+ * \param ssl      SSL context
+ *
+ * \return         a string containing the SSL version
+ */
+const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Return the (maximum) number of bytes added by the record
+ *                 layer: header + encryption/MAC overhead (inc. padding)
+ *
+ * \note           This function is not available (always returns an error)
+ *                 when record compression is enabled.
+ *
+ * \param ssl      SSL context
+ *
+ * \return         Current maximum record expansion in bytes, or
+ *                 MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE if compression is
+ *                 enabled, which makes expansion much less predictable
+ */
+int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl );
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+/**
+ * \brief          Return the maximum fragment length (payload, in bytes).
+ *                 This is the value negotiated with peer if any,
+ *                 or the locally configured value.
+ *
+ * \sa             mbedtls_ssl_conf_max_frag_len()
+ * \sa             mbedtls_ssl_get_max_record_payload()
+ *
+ * \param ssl      SSL context
+ *
+ * \return         Current maximum fragment length.
+ */
+size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+/**
+ * \brief          Return the current maximum outgoing record payload in bytes.
+ *                 This takes into account the config.h setting \c
+ *                 MBEDTLS_SSL_OUT_CONTENT_LEN, the configured and negotiated
+ *                 max fragment length extension if used, and for DTLS the
+ *                 path MTU as configured and current record expansion.
+ *
+ * \note           With DTLS, \c mbedtls_ssl_write() will return an error if
+ *                 called with a larger length value.
+ *                 With TLS, \c mbedtls_ssl_write() will fragment the input if
+ *                 necessary and return the number of bytes written; it is up
+ *                 to the caller to call \c mbedtls_ssl_write() again in
+ *                 order to send the remaining bytes if any.
+ *
+ * \note           This function is not available (always returns an error)
+ *                 when record compression is enabled.
+ *
+ * \sa             mbedtls_ssl_set_mtu()
+ * \sa             mbedtls_ssl_get_max_frag_len()
+ * \sa             mbedtls_ssl_get_record_expansion()
+ *
+ * \param ssl      SSL context
+ *
+ * \return         Current maximum payload for an outgoing record,
+ *                 or a negative error code.
+ */
+int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief          Return the peer certificate from the current connection
+ *
+ *                 Note: Can be NULL in case no certificate was sent during
+ *                 the handshake. Different calls for the same connection can
+ *                 return the same or different pointers for the same
+ *                 certificate and even a different certificate altogether.
+ *                 The peer cert CAN change in a single connection if
+ *                 renegotiation is performed.
+ *
+ * \param ssl      SSL context
+ *
+ * \return         the current peer certificate
+ */
+const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+/**
+ * \brief          Save session in order to resume it later (client-side only)
+ *                 Session data is copied to presented session structure.
+ *
+ *
+ * \param ssl      SSL context
+ * \param session  session context
+ *
+ * \return         0 if successful,
+ *                 MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed,
+ *                 MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or
+ *                 arguments are otherwise invalid.
+ *
+ * \note           Only the server certificate is copied, and not the full chain,
+ *                 so you should not attempt to validate the certificate again
+ *                 by calling \c mbedtls_x509_crt_verify() on it.
+ *                 Instead, you should use the results from the verification
+ *                 in the original handshake by calling \c mbedtls_ssl_get_verify_result()
+ *                 after loading the session again into a new SSL context
+ *                 using \c mbedtls_ssl_set_session().
+ *
+ * \note           Once the session object is not needed anymore, you should
+ *                 free it by calling \c mbedtls_ssl_session_free().
+ *
+ * \sa             mbedtls_ssl_set_session()
+ */
+int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *session );
+#endif /* MBEDTLS_SSL_CLI_C */
+
+/**
+ * \brief          Perform the SSL handshake
+ *
+ * \param ssl      SSL context
+ *
+ * \return         \c 0 if successful.
+ * \return         #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE
+ *                 if the handshake is incomplete and waiting for data to
+ *                 be available for reading from or writing to the underlying
+ *                 transport - in this case you must call this function again
+ *                 when the underlying transport is ready for the operation.
+ * \return         #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous
+ *                 operation is in progress (see
+ *                 mbedtls_ssl_conf_async_private_cb()) - in this case you
+ *                 must call this function again when the operation is ready.
+ * \return         #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic
+ *                 operation is in progress (see mbedtls_ecp_set_max_ops()) -
+ *                 in this case you must call this function again to complete
+ *                 the handshake when you're done attending other tasks.
+ * \return         #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED if DTLS is in use
+ *                 and the client did not demonstrate reachability yet - in
+ *                 this case you must stop using the context (see below).
+ * \return         Another SSL error code - in this case you must stop using
+ *                 the context (see below).
+ *
+ * \warning        If this function returns something other than
+ *                 \c 0,
+ *                 #MBEDTLS_ERR_SSL_WANT_READ,
+ *                 #MBEDTLS_ERR_SSL_WANT_WRITE,
+ *                 #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
+ *                 #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
+ *                 you must stop using the SSL context for reading or writing,
+ *                 and either free it or call \c mbedtls_ssl_session_reset()
+ *                 on it before re-using it for a new connection; the current
+ *                 connection must be closed.
+ *
+ * \note           If DTLS is in use, then you may choose to handle
+ *                 #MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging
+ *                 purposes, as it is an expected return value rather than an
+ *                 actual error, but you still need to reset/free the context.
+ *
+ * \note           Remarks regarding event-driven DTLS:
+ *                 If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram
+ *                 from the underlying transport layer is currently being processed,
+ *                 and it is safe to idle until the timer or the underlying transport
+ *                 signal a new event. This is not true for a successful handshake,
+ *                 in which case the datagram of the underlying transport that is
+ *                 currently being processed might or might not contain further
+ *                 DTLS records.
+ */
+int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Perform a single step of the SSL handshake
+ *
+ * \note           The state of the context (ssl->state) will be at
+ *                 the next state after this function returns \c 0. Do not
+ *                 call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER.
+ *
+ * \param ssl      SSL context
+ *
+ * \return         See mbedtls_ssl_handshake().
+ *
+ * \warning        If this function returns something other than \c 0,
+ *                 #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
+ *                 #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
+ *                 #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using
+ *                 the SSL context for reading or writing, and either free it
+ *                 or call \c mbedtls_ssl_session_reset() on it before
+ *                 re-using it for a new connection; the current connection
+ *                 must be closed.
+ */
+int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+/**
+ * \brief          Initiate an SSL renegotiation on the running connection.
+ *                 Client: perform the renegotiation right now.
+ *                 Server: request renegotiation, which will be performed
+ *                 during the next call to mbedtls_ssl_read() if honored by
+ *                 client.
+ *
+ * \param ssl      SSL context
+ *
+ * \return         0 if successful, or any mbedtls_ssl_handshake() return
+ *                 value except #MBEDTLS_ERR_SSL_CLIENT_RECONNECT that can't
+ *                 happen during a renegotiation.
+ *
+ * \warning        If this function returns something other than \c 0,
+ *                 #MBEDTLS_ERR_SSL_WANT_READ, #MBEDTLS_ERR_SSL_WANT_WRITE,
+ *                 #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
+ *                 #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS, you must stop using
+ *                 the SSL context for reading or writing, and either free it
+ *                 or call \c mbedtls_ssl_session_reset() on it before
+ *                 re-using it for a new connection; the current connection
+ *                 must be closed.
+ *
+ */
+int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+/**
+ * \brief          Read at most 'len' application data bytes
+ *
+ * \param ssl      SSL context
+ * \param buf      buffer that will hold the data
+ * \param len      maximum number of bytes to read
+ *
+ * \return         The (positive) number of bytes read if successful.
+ * \return         \c 0 if the read end of the underlying transport was closed
+ *                 - in this case you must stop using the context (see below).
+ * \return         #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE
+ *                 if the handshake is incomplete and waiting for data to
+ *                 be available for reading from or writing to the underlying
+ *                 transport - in this case you must call this function again
+ *                 when the underlying transport is ready for the operation.
+ * \return         #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous
+ *                 operation is in progress (see
+ *                 mbedtls_ssl_conf_async_private_cb()) - in this case you
+ *                 must call this function again when the operation is ready.
+ * \return         #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic
+ *                 operation is in progress (see mbedtls_ecp_set_max_ops()) -
+ *                 in this case you must call this function again to complete
+ *                 the handshake when you're done attending other tasks.
+ * \return         #MBEDTLS_ERR_SSL_CLIENT_RECONNECT if we're at the server
+ *                 side of a DTLS connection and the client is initiating a
+ *                 new connection using the same source port. See below.
+ * \return         Another SSL error code - in this case you must stop using
+ *                 the context (see below).
+ *
+ * \warning        If this function returns something other than
+ *                 a positive value,
+ *                 #MBEDTLS_ERR_SSL_WANT_READ,
+ *                 #MBEDTLS_ERR_SSL_WANT_WRITE,
+ *                 #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS,
+ *                 #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS or
+ *                 #MBEDTLS_ERR_SSL_CLIENT_RECONNECT,
+ *                 you must stop using the SSL context for reading or writing,
+ *                 and either free it or call \c mbedtls_ssl_session_reset()
+ *                 on it before re-using it for a new connection; the current
+ *                 connection must be closed.
+ *
+ * \note           When this function returns #MBEDTLS_ERR_SSL_CLIENT_RECONNECT
+ *                 (which can only happen server-side), it means that a client
+ *                 is initiating a new connection using the same source port.
+ *                 You can either treat that as a connection close and wait
+ *                 for the client to resend a ClientHello, or directly
+ *                 continue with \c mbedtls_ssl_handshake() with the same
+ *                 context (as it has been reset internally). Either way, you
+ *                 must make sure this is seen by the application as a new
+ *                 connection: application state, if any, should be reset, and
+ *                 most importantly the identity of the client must be checked
+ *                 again. WARNING: not validating the identity of the client
+ *                 again, or not transmitting the new identity to the
+ *                 application layer, would allow authentication bypass!
+ *
+ * \note           Remarks regarding event-driven DTLS:
+ *                 - If the function returns #MBEDTLS_ERR_SSL_WANT_READ, no datagram
+ *                   from the underlying transport layer is currently being processed,
+ *                   and it is safe to idle until the timer or the underlying transport
+ *                   signal a new event.
+ *                 - This function may return MBEDTLS_ERR_SSL_WANT_READ even if data was
+ *                   initially available on the underlying transport, as this data may have
+ *                   been only e.g. duplicated messages or a renegotiation request.
+ *                   Therefore, you must be prepared to receive MBEDTLS_ERR_SSL_WANT_READ even
+ *                   when reacting to an incoming-data event from the underlying transport.
+ *                 - On success, the datagram of the underlying transport that is currently
+ *                   being processed may contain further DTLS records. You should call
+ *                   \c mbedtls_ssl_check_pending to check for remaining records.
+ *
+ */
+int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len );
+
+/**
+ * \brief          Try to write exactly 'len' application data bytes
+ *
+ * \warning        This function will do partial writes in some cases. If the
+ *                 return value is non-negative but less than length, the
+ *                 function must be called again with updated arguments:
+ *                 buf + ret, len - ret (if ret is the return value) until
+ *                 it returns a value equal to the last 'len' argument.
+ *
+ * \param ssl      SSL context
+ * \param buf      buffer holding the data
+ * \param len      how many bytes must be written
+ *
+ * \return         The (non-negative) number of bytes actually written if
+ *                 successful (may be less than \p len).
+ * \return         #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE
+ *                 if the handshake is incomplete and waiting for data to
+ *                 be available for reading from or writing to the underlying
+ *                 transport - in this case you must call this function again
+ *                 when the underlying transport is ready for the operation.
+ * \return         #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if an asynchronous
+ *                 operation is in progress (see
+ *                 mbedtls_ssl_conf_async_private_cb()) - in this case you
+ *                 must call this function again when the operation is ready.
+ * \return         #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS if a cryptographic
+ *                 operation is in progress (see mbedtls_ecp_set_max_ops()) -
+ *                 in this case you must call this function again to complete
+ *                 the handshake when you're done attending other tasks.
+ * \return         Another SSL error code - in this case you must stop using
+ *                 the context (see below).
+ *
+ * \warning        If this function returns something other than
+ *                 a non-negative value,
+ *                 #MBEDTLS_ERR_SSL_WANT_READ,
+ *                 #MBEDTLS_ERR_SSL_WANT_WRITE,
+ *                 #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS or
+ *                 #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS,
+ *                 you must stop using the SSL context for reading or writing,
+ *                 and either free it or call \c mbedtls_ssl_session_reset()
+ *                 on it before re-using it for a new connection; the current
+ *                 connection must be closed.
+ *
+ * \note           When this function returns #MBEDTLS_ERR_SSL_WANT_WRITE/READ,
+ *                 it must be called later with the *same* arguments,
+ *                 until it returns a value greater that or equal to 0. When
+ *                 the function returns #MBEDTLS_ERR_SSL_WANT_WRITE there may be
+ *                 some partial data in the output buffer, however this is not
+ *                 yet sent.
+ *
+ * \note           If the requested length is greater than the maximum
+ *                 fragment length (either the built-in limit or the one set
+ *                 or negotiated with the peer), then:
+ *                 - with TLS, less bytes than requested are written.
+ *                 - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned.
+ *                 \c mbedtls_ssl_get_max_frag_len() may be used to query the
+ *                 active maximum fragment length.
+ *
+ * \note           Attempting to write 0 bytes will result in an empty TLS
+ *                 application record being sent.
+ */
+int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len );
+
+/**
+ * \brief           Send an alert message
+ *
+ * \param ssl       SSL context
+ * \param level     The alert level of the message
+ *                  (MBEDTLS_SSL_ALERT_LEVEL_WARNING or MBEDTLS_SSL_ALERT_LEVEL_FATAL)
+ * \param message   The alert message (SSL_ALERT_MSG_*)
+ *
+ * \return          0 if successful, or a specific SSL error code.
+ *
+ * \note           If this function returns something other than 0 or
+ *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
+ *                 the SSL context for reading or writing, and either free it or
+ *                 call \c mbedtls_ssl_session_reset() on it before re-using it
+ *                 for a new connection; the current connection must be closed.
+ */
+int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
+                            unsigned char level,
+                            unsigned char message );
+/**
+ * \brief          Notify the peer that the connection is being closed
+ *
+ * \param ssl      SSL context
+ *
+ * \return          0 if successful, or a specific SSL error code.
+ *
+ * \note           If this function returns something other than 0 or
+ *                 MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using
+ *                 the SSL context for reading or writing, and either free it or
+ *                 call \c mbedtls_ssl_session_reset() on it before re-using it
+ *                 for a new connection; the current connection must be closed.
+ */
+int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Free referenced items in an SSL context and clear memory
+ *
+ * \param ssl      SSL context
+ */
+void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief          Initialize an SSL configuration context
+ *                 Just makes the context ready for
+ *                 mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free().
+ *
+ * \note           You need to call mbedtls_ssl_config_defaults() unless you
+ *                 manually set all of the relevent fields yourself.
+ *
+ * \param conf     SSL configuration context
+ */
+void mbedtls_ssl_config_init( mbedtls_ssl_config *conf );
+
+/**
+ * \brief          Load reasonnable default SSL configuration values.
+ *                 (You need to call mbedtls_ssl_config_init() first.)
+ *
+ * \param conf     SSL configuration context
+ * \param endpoint MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER
+ * \param transport MBEDTLS_SSL_TRANSPORT_STREAM for TLS, or
+ *                  MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS
+ * \param preset   a MBEDTLS_SSL_PRESET_XXX value
+ *
+ * \note           See \c mbedtls_ssl_conf_transport() for notes on DTLS.
+ *
+ * \return         0 if successful, or
+ *                 MBEDTLS_ERR_XXX_ALLOC_FAILED on memory allocation error.
+ */
+int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
+                                 int endpoint, int transport, int preset );
+
+/**
+ * \brief          Free an SSL configuration context
+ *
+ * \param conf     SSL configuration context
+ */
+void mbedtls_ssl_config_free( mbedtls_ssl_config *conf );
+
+/**
+ * \brief          Initialize SSL session structure
+ *
+ * \param session  SSL session
+ */
+void mbedtls_ssl_session_init( mbedtls_ssl_session *session );
+
+/**
+ * \brief          Free referenced items in an SSL session including the
+ *                 peer certificate and clear memory
+ *
+ * \note           A session object can be freed even if the SSL context
+ *                 that was used to retrieve the session is still in use.
+ *
+ * \param session  SSL session
+ */
+void mbedtls_ssl_session_free( mbedtls_ssl_session *session );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_cache.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_cache.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_cache.h	(revision 398)
@@ -0,0 +1,150 @@
+/**
+ * \file ssl_cache.h
+ *
+ * \brief SSL session cache implementation
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SSL_CACHE_H
+#define MBEDTLS_SSL_CACHE_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "ssl.h"
+
+#if defined(MBEDTLS_THREADING_C)
+#include "threading.h"
+#endif
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+
+#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT)
+#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT       86400   /*!< 1 day  */
+#endif
+
+#if !defined(MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES)
+#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50   /*!< Maximum entries in cache */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct mbedtls_ssl_cache_context mbedtls_ssl_cache_context;
+typedef struct mbedtls_ssl_cache_entry mbedtls_ssl_cache_entry;
+
+/**
+ * \brief   This structure is used for storing cache entries
+ */
+struct mbedtls_ssl_cache_entry
+{
+#if defined(MBEDTLS_HAVE_TIME)
+    mbedtls_time_t timestamp;           /*!< entry timestamp    */
+#endif
+    mbedtls_ssl_session session;        /*!< entry session      */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    mbedtls_x509_buf peer_cert;         /*!< entry peer_cert    */
+#endif
+    mbedtls_ssl_cache_entry *next;      /*!< chain pointer      */
+};
+
+/**
+ * \brief Cache context
+ */
+struct mbedtls_ssl_cache_context
+{
+    mbedtls_ssl_cache_entry *chain;     /*!< start of the chain     */
+    int timeout;                /*!< cache entry timeout    */
+    int max_entries;            /*!< maximum entries        */
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;    /*!< mutex                  */
+#endif
+};
+
+/**
+ * \brief          Initialize an SSL cache context
+ *
+ * \param cache    SSL cache context
+ */
+void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache );
+
+/**
+ * \brief          Cache get callback implementation
+ *                 (Thread-safe if MBEDTLS_THREADING_C is enabled)
+ *
+ * \param data     SSL cache context
+ * \param session  session to retrieve entry for
+ */
+int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session );
+
+/**
+ * \brief          Cache set callback implementation
+ *                 (Thread-safe if MBEDTLS_THREADING_C is enabled)
+ *
+ * \param data     SSL cache context
+ * \param session  session to store entry for
+ */
+int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session );
+
+#if defined(MBEDTLS_HAVE_TIME)
+/**
+ * \brief          Set the cache timeout
+ *                 (Default: MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT (1 day))
+ *
+ *                 A timeout of 0 indicates no timeout.
+ *
+ * \param cache    SSL cache context
+ * \param timeout  cache entry timeout in seconds
+ */
+void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout );
+#endif /* MBEDTLS_HAVE_TIME */
+
+/**
+ * \brief          Set the maximum number of cache entries
+ *                 (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50))
+ *
+ * \param cache    SSL cache context
+ * \param max      cache entry maximum
+ */
+void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max );
+
+/**
+ * \brief          Free referenced items in a cache context and clear memory
+ *
+ * \param cache    SSL cache context
+ */
+void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_cache.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_ciphersuites.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_ciphersuites.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_ciphersuites.h	(revision 398)
@@ -0,0 +1,540 @@
+/**
+ * \file ssl_ciphersuites.h
+ *
+ * \brief SSL Ciphersuites for mbed TLS
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SSL_CIPHERSUITES_H
+#define MBEDTLS_SSL_CIPHERSUITES_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "pk.h"
+#include "cipher.h"
+#include "md.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Supported ciphersuites (Official IANA names)
+ */
+#define MBEDTLS_TLS_RSA_WITH_NULL_MD5                    0x01   /**< Weak! */
+#define MBEDTLS_TLS_RSA_WITH_NULL_SHA                    0x02   /**< Weak! */
+
+#define MBEDTLS_TLS_RSA_WITH_RC4_128_MD5                 0x04
+#define MBEDTLS_TLS_RSA_WITH_RC4_128_SHA                 0x05
+#define MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA                 0x09   /**< Weak! Not in TLS 1.2 */
+
+#define MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA            0x0A
+
+#define MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA             0x15   /**< Weak! Not in TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA        0x16
+
+#define MBEDTLS_TLS_PSK_WITH_NULL_SHA                    0x2C   /**< Weak! */
+#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA                0x2D   /**< Weak! */
+#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA                0x2E   /**< Weak! */
+#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA             0x2F
+
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA         0x33
+#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA             0x35
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA         0x39
+
+#define MBEDTLS_TLS_RSA_WITH_NULL_SHA256                 0x3B   /**< Weak! */
+#define MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256          0x3C   /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256          0x3D   /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA        0x41
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA    0x45
+
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256      0x67   /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256      0x6B   /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA        0x84
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA    0x88
+
+#define MBEDTLS_TLS_PSK_WITH_RC4_128_SHA                 0x8A
+#define MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA            0x8B
+#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA             0x8C
+#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA             0x8D
+
+#define MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA             0x8E
+#define MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA        0x8F
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA         0x90
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA         0x91
+
+#define MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA             0x92
+#define MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA        0x93
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA         0x94
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA         0x95
+
+#define MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256          0x9C   /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384          0x9D   /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256      0x9E   /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384      0x9F   /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256          0xA8   /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384          0xA9   /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256      0xAA   /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384      0xAB   /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256      0xAC   /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384      0xAD   /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256          0xAE
+#define MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384          0xAF
+#define MBEDTLS_TLS_PSK_WITH_NULL_SHA256                 0xB0   /**< Weak! */
+#define MBEDTLS_TLS_PSK_WITH_NULL_SHA384                 0xB1   /**< Weak! */
+
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256      0xB2
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384      0xB3
+#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256             0xB4   /**< Weak! */
+#define MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384             0xB5   /**< Weak! */
+
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256      0xB6
+#define MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384      0xB7
+#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256             0xB8   /**< Weak! */
+#define MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384             0xB9   /**< Weak! */
+
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256     0xBA   /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE   /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256     0xC0   /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4   /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA             0xC001 /**< Weak! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA          0xC002 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA     0xC003 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA      0xC004 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA      0xC005 /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA            0xC006 /**< Weak! */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA         0xC007 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA    0xC008 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA     0xC009 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA     0xC00A /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA               0xC00B /**< Weak! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA            0xC00C /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA       0xC00D /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA        0xC00E /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA        0xC00F /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA              0xC010 /**< Weak! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA           0xC011 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA      0xC012 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA       0xC013 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA       0xC014 /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256  0xC023 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384  0xC024 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256   0xC025 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384   0xC026 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256    0xC027 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384    0xC028 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256     0xC029 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384     0xC02A /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256  0xC02B /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384  0xC02C /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256   0xC02D /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384   0xC02E /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256    0xC02F /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384    0xC030 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256     0xC031 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384     0xC032 /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA           0xC033 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA      0xC034 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA       0xC035 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA       0xC036 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256    0xC037 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384    0xC038 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA              0xC039 /**< Weak! No SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256           0xC03A /**< Weak! No SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384           0xC03B /**< Weak! No SSL3! */
+
+#define MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256         0xC03C /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384         0xC03D /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256     0xC044 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384     0xC045 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 0xC048 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 0xC049 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256  0xC04A /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384  0xC04B /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256   0xC04C /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384   0xC04D /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256    0xC04E /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384    0xC04F /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256         0xC050 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384         0xC051 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256     0xC052 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384     0xC053 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0xC05C /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0xC05D /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256  0xC05E /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384  0xC05F /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256   0xC060 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384   0xC061 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256    0xC062 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384    0xC063 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256         0xC064 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384         0xC065 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256     0xC066 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384     0xC067 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256     0xC068 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384     0xC069 /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256         0xC06A /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384         0xC06B /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256     0xC06C /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384     0xC06D /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256     0xC06E /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384     0xC06F /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256   0xC070 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384   0xC071 /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256  0xC074 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384  0xC075 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256   0xC076 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384   0xC077 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256    0xC078 /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384    0xC079 /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256         0xC07A /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384         0xC07B /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256     0xC07C /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384     0xC07D /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256  0xC088 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384  0xC089 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256   0xC08A /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384   0xC08B /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256    0xC08C /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384    0xC08D /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256       0xC08E /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384       0xC08F /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256   0xC090 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384   0xC091 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256   0xC092 /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384   0xC093 /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256       0xC094
+#define MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384       0xC095
+#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256   0xC096
+#define MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384   0xC097
+#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256   0xC098
+#define MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384   0xC099
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A /**< Not in SSL3! */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B /**< Not in SSL3! */
+
+#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM                0xC09C  /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM                0xC09D  /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM            0xC09E  /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM            0xC09F  /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8              0xC0A0  /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8              0xC0A1  /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8          0xC0A2  /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8          0xC0A3  /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM                0xC0A4  /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM                0xC0A5  /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM            0xC0A6  /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM            0xC0A7  /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8              0xC0A8  /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8              0xC0A9  /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8          0xC0AA  /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8          0xC0AB  /**< TLS 1.2 */
+/* The last two are named with PSK_DHE in the RFC, which looks like a typo */
+
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM        0xC0AC  /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM        0xC0AD  /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8      0xC0AE  /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8      0xC0AF  /**< TLS 1.2 */
+
+#define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8          0xC0FF  /**< experimental */
+
+/* RFC 7905 */
+#define MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   0xCCA8 /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256     0xCCAA /**< TLS 1.2 */
+#define MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256         0xCCAB /**< TLS 1.2 */
+#define MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256   0xCCAC /**< TLS 1.2 */
+#define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256     0xCCAD /**< TLS 1.2 */
+#define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256     0xCCAE /**< TLS 1.2 */
+
+/* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange.
+ * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below
+ */
+typedef enum {
+    MBEDTLS_KEY_EXCHANGE_NONE = 0,
+    MBEDTLS_KEY_EXCHANGE_RSA,
+    MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+    MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+    MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+    MBEDTLS_KEY_EXCHANGE_PSK,
+    MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+    MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+    MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+    MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+    MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+    MBEDTLS_KEY_EXCHANGE_ECJPAKE,
+} mbedtls_key_exchange_type_t;
+
+/* Key exchanges using a certificate */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)           || \
+    defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)       || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)     || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)   || \
+    defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)       || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)      || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED
+#endif
+
+/* Key exchanges allowing client certificate requests */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)           ||       \
+    defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)       ||       \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)      ||       \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)     ||       \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)    ||       \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED
+#endif
+
+/* Key exchanges involving server signature in ServerKeyExchange */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)       || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)     || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED
+#endif
+
+/* Key exchanges using ECDH */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)      || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED
+#endif
+
+/* Key exchanges that don't involve ephemeral keys */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)           || \
+    defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)           || \
+    defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)       || \
+    defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED
+#endif
+
+/* Key exchanges that involve ephemeral keys */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)       || \
+    defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)       || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)     || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)     || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)   || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED
+#endif
+
+/* Key exchanges using a PSK */
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)           || \
+    defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)       || \
+    defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)       || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED
+#endif
+
+/* Key exchanges using DHE */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)       || \
+    defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED
+#endif
+
+/* Key exchanges using ECDHE */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)     || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)   || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED
+#endif
+
+typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t;
+
+#define MBEDTLS_CIPHERSUITE_WEAK       0x01    /**< Weak ciphersuite flag  */
+#define MBEDTLS_CIPHERSUITE_SHORT_TAG  0x02    /**< Short authentication tag,
+                                                     eg for CCM_8 */
+#define MBEDTLS_CIPHERSUITE_NODTLS     0x04    /**< Can't be used with DTLS */
+
+/**
+ * \brief   This structure is used for storing ciphersuite information
+ */
+struct mbedtls_ssl_ciphersuite_t
+{
+    int id;
+    const char * name;
+
+    mbedtls_cipher_type_t cipher;
+    mbedtls_md_type_t mac;
+    mbedtls_key_exchange_type_t key_exchange;
+
+    int min_major_ver;
+    int min_minor_ver;
+    int max_major_ver;
+    int max_minor_ver;
+
+    unsigned char flags;
+};
+
+const int *mbedtls_ssl_list_ciphersuites( void );
+
+const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( const char *ciphersuite_name );
+const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite_id );
+
+#if defined(MBEDTLS_PK_C)
+mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info );
+mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info );
+#endif
+
+int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info );
+int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info );
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
+static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+        case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
+            return( 1 );
+
+        default:
+            return( 0 );
+    }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+        case MBEDTLS_KEY_EXCHANGE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_PSK:
+        case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
+            return( 1 );
+
+        default:
+            return( 0 );
+    }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
+static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+            return( 1 );
+
+        default:
+            return( 0 );
+    }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
+
+static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+            return( 1 );
+
+        default:
+            return( 0 );
+    }
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
+static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
+            return( 1 );
+
+        default:
+            return( 0 );
+    }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
+static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
+            return( 1 );
+
+        default:
+            return( 0 );
+    }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+static inline int mbedtls_ssl_ciphersuite_uses_server_signature( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+            return( 1 );
+
+        default:
+            return( 0 );
+    }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_ciphersuites.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_cookie.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_cookie.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_cookie.h	(revision 398)
@@ -0,0 +1,115 @@
+/**
+ * \file ssl_cookie.h
+ *
+ * \brief DTLS cookie callbacks implementation
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SSL_COOKIE_H
+#define MBEDTLS_SSL_COOKIE_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "ssl.h"
+
+#if defined(MBEDTLS_THREADING_C)
+#include "threading.h"
+#endif
+
+/**
+ * \name SECTION: Module settings
+ *
+ * The configuration options you can set for this module are in this section.
+ * Either change them in config.h or define them on the compiler command line.
+ * \{
+ */
+#ifndef MBEDTLS_SSL_COOKIE_TIMEOUT
+#define MBEDTLS_SSL_COOKIE_TIMEOUT     60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
+#endif
+
+/* \} name SECTION: Module settings */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          Context for the default cookie functions.
+ */
+typedef struct mbedtls_ssl_cookie_ctx
+{
+    mbedtls_md_context_t    hmac_ctx;   /*!< context for the HMAC portion   */
+#if !defined(MBEDTLS_HAVE_TIME)
+    unsigned long   serial;     /*!< serial number for expiration   */
+#endif
+    unsigned long   timeout;    /*!< timeout delay, in seconds if HAVE_TIME,
+                                     or in number of tickets issued */
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+#endif
+} mbedtls_ssl_cookie_ctx;
+
+/**
+ * \brief          Initialize cookie context
+ */
+void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx );
+
+/**
+ * \brief          Setup cookie context (generate keys)
+ */
+int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng );
+
+/**
+ * \brief          Set expiration delay for cookies
+ *                 (Default MBEDTLS_SSL_COOKIE_TIMEOUT)
+ *
+ * \param ctx      Cookie contex
+ * \param delay    Delay, in seconds if HAVE_TIME, or in number of cookies
+ *                 issued in the meantime.
+ *                 0 to disable expiration (NOT recommended)
+ */
+void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay );
+
+/**
+ * \brief          Free cookie context
+ */
+void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx );
+
+/**
+ * \brief          Generate cookie, see \c mbedtls_ssl_cookie_write_t
+ */
+mbedtls_ssl_cookie_write_t mbedtls_ssl_cookie_write;
+
+/**
+ * \brief          Verify cookie, see \c mbedtls_ssl_cookie_write_t
+ */
+mbedtls_ssl_cookie_check_t mbedtls_ssl_cookie_check;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_cookie.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_internal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_internal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_internal.h	(revision 398)
@@ -0,0 +1,782 @@
+/**
+ * \file ssl_internal.h
+ *
+ * \brief Internal functions shared by the SSL modules
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SSL_INTERNAL_H
+#define MBEDTLS_SSL_INTERNAL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "ssl.h"
+#include "cipher.h"
+
+#if defined(MBEDTLS_MD5_C)
+#include "md5.h"
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+#include "sha1.h"
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+#include "sha256.h"
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+#include "sha512.h"
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+#include "ecjpake.h"
+#endif
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+/* Determine minimum supported version */
+#define MBEDTLS_SSL_MIN_MAJOR_VERSION           MBEDTLS_SSL_MAJOR_VERSION_3
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+#define MBEDTLS_SSL_MIN_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_0
+#else
+#if defined(MBEDTLS_SSL_PROTO_TLS1)
+#define MBEDTLS_SSL_MIN_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_1
+#else
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1)
+#define MBEDTLS_SSL_MIN_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_2
+#else
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#define MBEDTLS_SSL_MIN_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_3
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */
+#endif /* MBEDTLS_SSL_PROTO_TLS1   */
+#endif /* MBEDTLS_SSL_PROTO_SSL3   */
+
+#define MBEDTLS_SSL_MIN_VALID_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1
+#define MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3
+
+/* Determine maximum supported version */
+#define MBEDTLS_SSL_MAX_MAJOR_VERSION           MBEDTLS_SSL_MAJOR_VERSION_3
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#define MBEDTLS_SSL_MAX_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_3
+#else
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1)
+#define MBEDTLS_SSL_MAX_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_2
+#else
+#if defined(MBEDTLS_SSL_PROTO_TLS1)
+#define MBEDTLS_SSL_MAX_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_1
+#else
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+#define MBEDTLS_SSL_MAX_MINOR_VERSION           MBEDTLS_SSL_MINOR_VERSION_0
+#endif /* MBEDTLS_SSL_PROTO_SSL3   */
+#endif /* MBEDTLS_SSL_PROTO_TLS1   */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+/* Shorthand for restartable ECC */
+#if defined(MBEDTLS_ECP_RESTARTABLE) && \
+    defined(MBEDTLS_SSL_CLI_C) && \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#define MBEDTLS_SSL__ECP_RESTARTABLE
+#endif
+
+#define MBEDTLS_SSL_INITIAL_HANDSHAKE           0
+#define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS   1   /* In progress */
+#define MBEDTLS_SSL_RENEGOTIATION_DONE          2   /* Done or aborted */
+#define MBEDTLS_SSL_RENEGOTIATION_PENDING       3   /* Requested (server only) */
+
+/*
+ * DTLS retransmission states, see RFC 6347 4.2.4
+ *
+ * The SENDING state is merged in PREPARING for initial sends,
+ * but is distinct for resends.
+ *
+ * Note: initial state is wrong for server, but is not used anyway.
+ */
+#define MBEDTLS_SSL_RETRANS_PREPARING       0
+#define MBEDTLS_SSL_RETRANS_SENDING         1
+#define MBEDTLS_SSL_RETRANS_WAITING         2
+#define MBEDTLS_SSL_RETRANS_FINISHED        3
+
+/*
+ * Allow extra bytes for record, authentication and encryption overhead:
+ * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256)
+ * and allow for a maximum of 1024 of compression expansion if
+ * enabled.
+ */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+#define MBEDTLS_SSL_COMPRESSION_ADD          1024
+#else
+#define MBEDTLS_SSL_COMPRESSION_ADD             0
+#endif
+
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_MODE_CBC)
+/* Ciphersuites using HMAC */
+#if defined(MBEDTLS_SHA512_C)
+#define MBEDTLS_SSL_MAC_ADD                 48  /* SHA-384 used for HMAC */
+#elif defined(MBEDTLS_SHA256_C)
+#define MBEDTLS_SSL_MAC_ADD                 32  /* SHA-256 used for HMAC */
+#else
+#define MBEDTLS_SSL_MAC_ADD                 20  /* SHA-1   used for HMAC */
+#endif
+#else
+/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */
+#define MBEDTLS_SSL_MAC_ADD                 16
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#define MBEDTLS_SSL_PADDING_ADD            256
+#else
+#define MBEDTLS_SSL_PADDING_ADD              0
+#endif
+
+#define MBEDTLS_SSL_PAYLOAD_OVERHEAD ( MBEDTLS_SSL_COMPRESSION_ADD +    \
+                                       MBEDTLS_MAX_IV_LENGTH +          \
+                                       MBEDTLS_SSL_MAC_ADD +            \
+                                       MBEDTLS_SSL_PADDING_ADD          \
+                                       )
+
+#define MBEDTLS_SSL_IN_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \
+                                     ( MBEDTLS_SSL_IN_CONTENT_LEN ) )
+
+#define MBEDTLS_SSL_OUT_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \
+                                      ( MBEDTLS_SSL_OUT_CONTENT_LEN ) )
+
+/* The maximum number of buffered handshake messages. */
+#define MBEDTLS_SSL_MAX_BUFFERED_HS 4
+
+/* Maximum length we can advertise as our max content length for
+   RFC 6066 max_fragment_length extension negotiation purposes
+   (the lesser of both sizes, if they are unequal.)
+ */
+#define MBEDTLS_TLS_EXT_ADV_CONTENT_LEN (                            \
+        (MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_OUT_CONTENT_LEN)   \
+        ? ( MBEDTLS_SSL_OUT_CONTENT_LEN )                            \
+        : ( MBEDTLS_SSL_IN_CONTENT_LEN )                             \
+        )
+
+/*
+ * Check that we obey the standard's message size bounds
+ */
+
+#if MBEDTLS_SSL_MAX_CONTENT_LEN > 16384
+#error "Bad configuration - record content too large."
+#endif
+
+#if MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN
+#error "Bad configuration - incoming record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN."
+#endif
+
+#if MBEDTLS_SSL_OUT_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN
+#error "Bad configuration - outgoing record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN."
+#endif
+
+#if MBEDTLS_SSL_IN_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048
+#error "Bad configuration - incoming protected record payload too large."
+#endif
+
+#if MBEDTLS_SSL_OUT_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048
+#error "Bad configuration - outgoing protected record payload too large."
+#endif
+
+/* Calculate buffer sizes */
+
+/* Note: Even though the TLS record header is only 5 bytes
+   long, we're internally using 8 bytes to store the
+   implicit sequence number. */
+#define MBEDTLS_SSL_HEADER_LEN 13
+
+#define MBEDTLS_SSL_IN_BUFFER_LEN  \
+    ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) )
+
+#define MBEDTLS_SSL_OUT_BUFFER_LEN  \
+    ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) )
+
+#ifdef MBEDTLS_ZLIB_SUPPORT
+/* Compression buffer holds both IN and OUT buffers, so should be size of the larger */
+#define MBEDTLS_SSL_COMPRESS_BUFFER_LEN (                               \
+        ( MBEDTLS_SSL_IN_BUFFER_LEN > MBEDTLS_SSL_OUT_BUFFER_LEN )      \
+        ? MBEDTLS_SSL_IN_BUFFER_LEN                                     \
+        : MBEDTLS_SSL_OUT_BUFFER_LEN                                    \
+        )
+#endif
+
+/*
+ * TLS extension flags (for extensions with outgoing ServerHello content
+ * that need it (e.g. for RENEGOTIATION_INFO the server already knows because
+ * of state of the renegotiation flag, so no indicator is required)
+ */
+#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0)
+#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK                 (1 << 1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+/*
+ * Abstraction for a grid of allowed signature-hash-algorithm pairs.
+ */
+struct mbedtls_ssl_sig_hash_set_t
+{
+    /* At the moment, we only need to remember a single suitable
+     * hash algorithm per signature algorithm. As long as that's
+     * the case - and we don't need a general lookup function -
+     * we can implement the sig-hash-set as a map from signatures
+     * to hash algorithms. */
+    mbedtls_md_type_t rsa;
+    mbedtls_md_type_t ecdsa;
+};
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
+          MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+/*
+ * This structure contains the parameters only needed during handshake.
+ */
+struct mbedtls_ssl_handshake_params
+{
+    /*
+     * Handshake specific crypto variables
+     */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+    mbedtls_ssl_sig_hash_set_t hash_algs;             /*!<  Set of suitable sig-hash pairs */
+#endif
+#if defined(MBEDTLS_DHM_C)
+    mbedtls_dhm_context dhm_ctx;                /*!<  DHM key exchange        */
+#endif
+#if defined(MBEDTLS_ECDH_C)
+    mbedtls_ecdh_context ecdh_ctx;              /*!<  ECDH key exchange       */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    mbedtls_ecjpake_context ecjpake_ctx;        /*!< EC J-PAKE key exchange */
+#if defined(MBEDTLS_SSL_CLI_C)
+    unsigned char *ecjpake_cache;               /*!< Cache for ClientHello ext */
+    size_t ecjpake_cache_len;                   /*!< Length of cached data */
+#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    const mbedtls_ecp_curve_info **curves;      /*!<  Supported elliptic curves */
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    unsigned char *psk;                 /*!<  PSK from the callback         */
+    size_t psk_len;                     /*!<  Length of PSK from callback   */
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    mbedtls_ssl_key_cert *key_cert;     /*!< chosen key/cert pair (server)  */
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    int sni_authmode;                   /*!< authmode from SNI callback     */
+    mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI         */
+    mbedtls_x509_crt *sni_ca_chain;     /*!< trusted CAs from SNI callback  */
+    mbedtls_x509_crl *sni_ca_crl;       /*!< trusted CAs CRLs from SNI      */
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    int ecrs_enabled;                   /*!< Handshake supports EC restart? */
+    mbedtls_x509_crt_restart_ctx ecrs_ctx;  /*!< restart context            */
+    enum { /* this complements ssl->state with info on intra-state operations */
+        ssl_ecrs_none = 0,              /*!< nothing going on (yet)         */
+        ssl_ecrs_crt_verify,            /*!< Certificate: crt_verify()      */
+        ssl_ecrs_ske_start_processing,  /*!< ServerKeyExchange: pk_verify() */
+        ssl_ecrs_cke_ecdh_calc_secret,  /*!< ClientKeyExchange: ECDH step 2 */
+        ssl_ecrs_crt_vrfy_sign,         /*!< CertificateVerify: pk_sign()   */
+    } ecrs_state;                       /*!< current (or last) operation    */
+    size_t ecrs_n;                      /*!< place for saving a length      */
+#endif
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    unsigned int out_msg_seq;           /*!<  Outgoing handshake sequence number */
+    unsigned int in_msg_seq;            /*!<  Incoming handshake sequence number */
+
+    unsigned char *verify_cookie;       /*!<  Cli: HelloVerifyRequest cookie
+                                              Srv: unused                    */
+    unsigned char verify_cookie_len;    /*!<  Cli: cookie length
+                                              Srv: flag for sending a cookie */
+
+    uint32_t retransmit_timeout;        /*!<  Current value of timeout       */
+    unsigned char retransmit_state;     /*!<  Retransmission state           */
+    mbedtls_ssl_flight_item *flight;    /*!<  Current outgoing flight        */
+    mbedtls_ssl_flight_item *cur_msg;   /*!<  Current message in flight      */
+    unsigned char *cur_msg_p;           /*!<  Position in current message    */
+    unsigned int in_flight_start_seq;   /*!<  Minimum message sequence in the
+                                              flight being received          */
+    mbedtls_ssl_transform *alt_transform_out;   /*!<  Alternative transform for
+                                              resending messages             */
+    unsigned char alt_out_ctr[8];       /*!<  Alternative record epoch/counter
+                                              for resending messages         */
+
+    struct
+    {
+        size_t total_bytes_buffered; /*!< Cumulative size of heap allocated
+                                      *   buffers used for message buffering. */
+
+        uint8_t seen_ccs;               /*!< Indicates if a CCS message has
+                                         *   been seen in the current flight. */
+
+        struct mbedtls_ssl_hs_buffer
+        {
+            unsigned is_valid      : 1;
+            unsigned is_fragmented : 1;
+            unsigned is_complete   : 1;
+            unsigned char *data;
+            size_t data_len;
+        } hs[MBEDTLS_SSL_MAX_BUFFERED_HS];
+
+        struct
+        {
+            unsigned char *data;
+            size_t len;
+            unsigned epoch;
+        } future_record;
+
+    } buffering;
+
+    uint16_t mtu;                       /*!<  Handshake mtu, used to fragment outgoing messages */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    /*
+     * Checksum contexts
+     */
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+       mbedtls_md5_context fin_md5;
+      mbedtls_sha1_context fin_sha1;
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+    mbedtls_sha256_context fin_sha256;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+    mbedtls_sha512_context fin_sha512;
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+    void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
+    void (*calc_verify)(mbedtls_ssl_context *, unsigned char *);
+    void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
+    int  (*tls_prf)(const unsigned char *, size_t, const char *,
+                    const unsigned char *, size_t,
+                    unsigned char *, size_t);
+
+    size_t pmslen;                      /*!<  premaster length        */
+
+    unsigned char randbytes[64];        /*!<  random bytes            */
+    unsigned char premaster[MBEDTLS_PREMASTER_SIZE];
+                                        /*!<  premaster secret        */
+
+    int resume;                         /*!<  session resume indicator*/
+    int max_major_ver;                  /*!< max. major version client*/
+    int max_minor_ver;                  /*!< max. minor version client*/
+    int cli_exts;                       /*!< client extension presence*/
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    int new_session_ticket;             /*!< use NewSessionTicket?    */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    int extended_ms;                    /*!< use Extended Master Secret? */
+#endif
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+    unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+    /** Asynchronous operation context. This field is meant for use by the
+     * asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start,
+     * mbedtls_ssl_config::f_async_decrypt_start,
+     * mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel).
+     * The library does not use it internally. */
+    void *user_async_ctx;
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+};
+
+typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer;
+
+/*
+ * This structure contains a full set of runtime transform parameters
+ * either in negotiation or active.
+ */
+struct mbedtls_ssl_transform
+{
+    /*
+     * Session specific crypto layer
+     */
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+                                        /*!<  Chosen cipersuite_info  */
+    unsigned int keylen;                /*!<  symmetric key length (bytes)  */
+    size_t minlen;                      /*!<  min. ciphertext length  */
+    size_t ivlen;                       /*!<  IV length               */
+    size_t fixed_ivlen;                 /*!<  Fixed part of IV (AEAD) */
+    size_t maclen;                      /*!<  MAC length              */
+
+    unsigned char iv_enc[16];           /*!<  IV (encryption)         */
+    unsigned char iv_dec[16];           /*!<  IV (decryption)         */
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    /* Needed only for SSL v3.0 secret */
+    unsigned char mac_enc[20];          /*!<  SSL v3.0 secret (enc)   */
+    unsigned char mac_dec[20];          /*!<  SSL v3.0 secret (dec)   */
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+    mbedtls_md_context_t md_ctx_enc;            /*!<  MAC (encryption)        */
+    mbedtls_md_context_t md_ctx_dec;            /*!<  MAC (decryption)        */
+
+    mbedtls_cipher_context_t cipher_ctx_enc;    /*!<  encryption context      */
+    mbedtls_cipher_context_t cipher_ctx_dec;    /*!<  decryption context      */
+
+    /*
+     * Session specific compression layer
+     */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    z_stream ctx_deflate;               /*!<  compression context     */
+    z_stream ctx_inflate;               /*!<  decompression context   */
+#endif
+};
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/*
+ * List of certificate + private key pairs
+ */
+struct mbedtls_ssl_key_cert
+{
+    mbedtls_x509_crt *cert;                 /*!< cert                       */
+    mbedtls_pk_context *key;                /*!< private key                */
+    mbedtls_ssl_key_cert *next;             /*!< next key/cert pair         */
+};
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+/*
+ * List of handshake messages kept around for resending
+ */
+struct mbedtls_ssl_flight_item
+{
+    unsigned char *p;       /*!< message, including handshake headers   */
+    size_t len;             /*!< length of p                            */
+    unsigned char type;     /*!< type of the message: handshake or CCS  */
+    mbedtls_ssl_flight_item *next;  /*!< next handshake message(s)              */
+};
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+
+/* Find an entry in a signature-hash set matching a given hash algorithm. */
+mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
+                                                 mbedtls_pk_type_t sig_alg );
+/* Add a signature-hash-pair to a signature-hash set */
+void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
+                                   mbedtls_pk_type_t sig_alg,
+                                   mbedtls_md_type_t md_alg );
+/* Allow exactly one hash algorithm for each signature. */
+void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
+                                          mbedtls_md_type_t md_alg );
+
+/* Setup an empty signature-hash set */
+static inline void mbedtls_ssl_sig_hash_set_init( mbedtls_ssl_sig_hash_set_t *set )
+{
+    mbedtls_ssl_sig_hash_set_const_hash( set, MBEDTLS_MD_NONE );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
+          MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+/**
+ * \brief           Free referenced items in an SSL transform context and clear
+ *                  memory
+ *
+ * \param transform SSL transform context
+ */
+void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform );
+
+/**
+ * \brief           Free referenced items in an SSL handshake context and clear
+ *                  memory
+ *
+ * \param ssl       SSL context
+ */
+void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
+void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl );
+
+void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl );
+void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl );
+
+/**
+ * \brief       Update record layer
+ *
+ *              This function roughly separates the implementation
+ *              of the logic of (D)TLS from the implementation
+ *              of the secure transport.
+ *
+ * \param  ssl              The SSL context to use.
+ * \param  update_hs_digest This indicates if the handshake digest
+ *                          should be automatically updated in case
+ *                          a handshake message is found.
+ *
+ * \return      0 or non-zero error code.
+ *
+ * \note        A clarification on what is called 'record layer' here
+ *              is in order, as many sensible definitions are possible:
+ *
+ *              The record layer takes as input an untrusted underlying
+ *              transport (stream or datagram) and transforms it into
+ *              a serially multiplexed, secure transport, which
+ *              conceptually provides the following:
+ *
+ *              (1) Three datagram based, content-agnostic transports
+ *                  for handshake, alert and CCS messages.
+ *              (2) One stream- or datagram-based transport
+ *                  for application data.
+ *              (3) Functionality for changing the underlying transform
+ *                  securing the contents.
+ *
+ *              The interface to this functionality is given as follows:
+ *
+ *              a Updating
+ *                [Currently implemented by mbedtls_ssl_read_record]
+ *
+ *                Check if and on which of the four 'ports' data is pending:
+ *                Nothing, a controlling datagram of type (1), or application
+ *                data (2). In any case data is present, internal buffers
+ *                provide access to the data for the user to process it.
+ *                Consumption of type (1) datagrams is done automatically
+ *                on the next update, invalidating that the internal buffers
+ *                for previous datagrams, while consumption of application
+ *                data (2) is user-controlled.
+ *
+ *              b Reading of application data
+ *                [Currently manual adaption of ssl->in_offt pointer]
+ *
+ *                As mentioned in the last paragraph, consumption of data
+ *                is different from the automatic consumption of control
+ *                datagrams (1) because application data is treated as a stream.
+ *
+ *              c Tracking availability of application data
+ *                [Currently manually through decreasing ssl->in_msglen]
+ *
+ *                For efficiency and to retain datagram semantics for
+ *                application data in case of DTLS, the record layer
+ *                provides functionality for checking how much application
+ *                data is still available in the internal buffer.
+ *
+ *              d Changing the transformation securing the communication.
+ *
+ *              Given an opaque implementation of the record layer in the
+ *              above sense, it should be possible to implement the logic
+ *              of (D)TLS on top of it without the need to know anything
+ *              about the record layer's internals. This is done e.g.
+ *              in all the handshake handling functions, and in the
+ *              application data reading function mbedtls_ssl_read.
+ *
+ * \note        The above tries to give a conceptual picture of the
+ *              record layer, but the current implementation deviates
+ *              from it in some places. For example, our implementation of
+ *              the update functionality through mbedtls_ssl_read_record
+ *              discards datagrams depending on the current state, which
+ *              wouldn't fall under the record layer's responsibility
+ *              following the above definition.
+ *
+ */
+int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
+                             unsigned update_hs_digest );
+int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want );
+
+int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush );
+int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl );
+
+void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
+                            const mbedtls_ssl_ciphersuite_t *ciphersuite_info );
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex );
+#endif
+
+#if defined(MBEDTLS_PK_C)
+unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk );
+unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type );
+mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig );
+#endif
+
+mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash );
+unsigned char mbedtls_ssl_hash_from_md_alg( int md );
+int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md );
+
+#if defined(MBEDTLS_ECP_C)
+int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id );
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
+                                mbedtls_md_type_t md );
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl )
+{
+    mbedtls_ssl_key_cert *key_cert;
+
+    if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL )
+        key_cert = ssl->handshake->key_cert;
+    else
+        key_cert = ssl->conf->key_cert;
+
+    return( key_cert == NULL ? NULL : key_cert->key );
+}
+
+static inline mbedtls_x509_crt *mbedtls_ssl_own_cert( mbedtls_ssl_context *ssl )
+{
+    mbedtls_ssl_key_cert *key_cert;
+
+    if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL )
+        key_cert = ssl->handshake->key_cert;
+    else
+        key_cert = ssl->conf->key_cert;
+
+    return( key_cert == NULL ? NULL : key_cert->cert );
+}
+
+/*
+ * Check usage of a certificate wrt extensions:
+ * keyUsage, extendedKeyUsage (later), and nSCertType (later).
+ *
+ * Warning: cert_endpoint is the endpoint of the cert (ie, of our peer when we
+ * check a cert we received from them)!
+ *
+ * Return 0 if everything is OK, -1 if not.
+ */
+int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
+                          const mbedtls_ssl_ciphersuite_t *ciphersuite,
+                          int cert_endpoint,
+                          uint32_t *flags );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+void mbedtls_ssl_write_version( int major, int minor, int transport,
+                        unsigned char ver[2] );
+void mbedtls_ssl_read_version( int *major, int *minor, int transport,
+                       const unsigned char ver[2] );
+
+static inline size_t mbedtls_ssl_hdr_len( const mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        return( 13 );
+#else
+    ((void) ssl);
+#endif
+    return( 5 );
+}
+
+static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        return( 12 );
+#else
+    ((void) ssl);
+#endif
+    return( 4 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl );
+void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_resend( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl );
+#endif
+
+/* Visible for testing purposes only */
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl );
+void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl );
+#endif
+
+/* constant-time buffer comparison */
+static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n )
+{
+    size_t i;
+    volatile const unsigned char *A = (volatile const unsigned char *) a;
+    volatile const unsigned char *B = (volatile const unsigned char *) b;
+    volatile unsigned char diff = 0;
+
+    for( i = 0; i < n; i++ )
+    {
+        /* Read volatile data in order before computing diff.
+         * This avoids IAR compiler warning:
+         * 'the order of volatile accesses is undefined ..' */
+        unsigned char x = A[i], y = B[i];
+        diff |= x ^ y;
+    }
+
+    return( diff );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
+                                        unsigned char *output,
+                                        unsigned char *data, size_t data_len );
+#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
+          MBEDTLS_SSL_PROTO_TLS1_1 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
+                                            unsigned char *hash, size_t *hashlen,
+                                            unsigned char *data, size_t data_len,
+                                            mbedtls_md_type_t md_alg );
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+          MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_internal.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_ticket.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_ticket.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/ssl_ticket.h	(revision 398)
@@ -0,0 +1,142 @@
+/**
+ * \file ssl_ticket.h
+ *
+ * \brief TLS server ticket callbacks implementation
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_SSL_TICKET_H
+#define MBEDTLS_SSL_TICKET_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+/*
+ * This implementation of the session ticket callbacks includes key
+ * management, rotating the keys periodically in order to preserve forward
+ * secrecy, when MBEDTLS_HAVE_TIME is defined.
+ */
+
+#include "ssl.h"
+#include "cipher.h"
+
+#if defined(MBEDTLS_THREADING_C)
+#include "threading.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief   Information for session ticket protection
+ */
+typedef struct mbedtls_ssl_ticket_key
+{
+    unsigned char name[4];          /*!< random key identifier              */
+    uint32_t generation_time;       /*!< key generation timestamp (seconds) */
+    mbedtls_cipher_context_t ctx;   /*!< context for auth enc/decryption    */
+}
+mbedtls_ssl_ticket_key;
+
+/**
+ * \brief   Context for session ticket handling functions
+ */
+typedef struct mbedtls_ssl_ticket_context
+{
+    mbedtls_ssl_ticket_key keys[2]; /*!< ticket protection keys             */
+    unsigned char active;           /*!< index of the currently active key  */
+
+    uint32_t ticket_lifetime;       /*!< lifetime of tickets in seconds     */
+
+    /** Callback for getting (pseudo-)random numbers                        */
+    int  (*f_rng)(void *, unsigned char *, size_t);
+    void *p_rng;                    /*!< context for the RNG function       */
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;
+#endif
+}
+mbedtls_ssl_ticket_context;
+
+/**
+ * \brief           Initialize a ticket context.
+ *                  (Just make it ready for mbedtls_ssl_ticket_setup()
+ *                  or mbedtls_ssl_ticket_free().)
+ *
+ * \param ctx       Context to be initialized
+ */
+void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx );
+
+/**
+ * \brief           Prepare context to be actually used
+ *
+ * \param ctx       Context to be set up
+ * \param f_rng     RNG callback function
+ * \param p_rng     RNG callback context
+ * \param cipher    AEAD cipher to use for ticket protection.
+ *                  Recommended value: MBEDTLS_CIPHER_AES_256_GCM.
+ * \param lifetime  Tickets lifetime in seconds
+ *                  Recommended value: 86400 (one day).
+ *
+ * \note            It is highly recommended to select a cipher that is at
+ *                  least as strong as the the strongest ciphersuite
+ *                  supported. Usually that means a 256-bit key.
+ *
+ * \note            The lifetime of the keys is twice the lifetime of tickets.
+ *                  It is recommended to pick a reasonnable lifetime so as not
+ *                  to negate the benefits of forward secrecy.
+ *
+ * \return          0 if successful,
+ *                  or a specific MBEDTLS_ERR_XXX error code
+ */
+int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
+    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+    mbedtls_cipher_type_t cipher,
+    uint32_t lifetime );
+
+/**
+ * \brief           Implementation of the ticket write callback
+ *
+ * \note            See \c mbedlts_ssl_ticket_write_t for description
+ */
+mbedtls_ssl_ticket_write_t mbedtls_ssl_ticket_write;
+
+/**
+ * \brief           Implementation of the ticket parse callback
+ *
+ * \note            See \c mbedlts_ssl_ticket_parse_t for description
+ */
+mbedtls_ssl_ticket_parse_t mbedtls_ssl_ticket_parse;
+
+/**
+ * \brief           Free a context's content and zeroize it.
+ *
+ * \param ctx       Context to be cleaned up
+ */
+void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ssl_ticket.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/threading.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/threading.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/threading.h	(revision 398)
@@ -0,0 +1,122 @@
+/**
+ * \file threading.h
+ *
+ * \brief Threading abstraction layer
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_THREADING_H
+#define MBEDTLS_THREADING_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE is deprecated and should not be
+ * used. */
+#define MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE         -0x001A  /**< The selected feature is not available. */
+
+#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA              -0x001C  /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_THREADING_MUTEX_ERROR                 -0x001E  /**< Locking / unlocking / free failed with error code. */
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+#include <pthread.h>
+typedef struct mbedtls_threading_mutex_t
+{
+    pthread_mutex_t mutex;
+    char is_valid;
+} mbedtls_threading_mutex_t;
+#endif
+
+#if defined(MBEDTLS_THREADING_ALT)
+/* You should define the mbedtls_threading_mutex_t type in your header */
+#include "threading_alt.h"
+
+/**
+ * \brief           Set your alternate threading implementation function
+ *                  pointers and initialize global mutexes. If used, this
+ *                  function must be called once in the main thread before any
+ *                  other mbed TLS function is called, and
+ *                  mbedtls_threading_free_alt() must be called once in the main
+ *                  thread after all other mbed TLS functions.
+ *
+ * \note            mutex_init() and mutex_free() don't return a status code.
+ *                  If mutex_init() fails, it should leave its argument (the
+ *                  mutex) in a state such that mutex_lock() will fail when
+ *                  called with this argument.
+ *
+ * \param mutex_init    the init function implementation
+ * \param mutex_free    the free function implementation
+ * \param mutex_lock    the lock function implementation
+ * \param mutex_unlock  the unlock function implementation
+ */
+void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ),
+                       void (*mutex_free)( mbedtls_threading_mutex_t * ),
+                       int (*mutex_lock)( mbedtls_threading_mutex_t * ),
+                       int (*mutex_unlock)( mbedtls_threading_mutex_t * ) );
+
+/**
+ * \brief               Free global mutexes.
+ */
+void mbedtls_threading_free_alt( void );
+#endif /* MBEDTLS_THREADING_ALT */
+
+#if defined(MBEDTLS_THREADING_C)
+/*
+ * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock
+ *
+ * All these functions are expected to work or the result will be undefined.
+ */
+extern void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t *mutex );
+extern void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t *mutex );
+extern int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t *mutex );
+extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex );
+
+/*
+ * Global mutexes
+ */
+#if defined(MBEDTLS_FS_IO)
+extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex;
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
+/* This mutex may or may not be used in the default definition of
+ * mbedtls_platform_gmtime_r(), but in order to determine that,
+ * we need to check POSIX features, hence modify _POSIX_C_SOURCE.
+ * With the current approach, this declaration is orphaned, lacking
+ * an accompanying definition, in case mbedtls_platform_gmtime_r()
+ * doesn't need it, but that's not a problem. */
+extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
+#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
+
+#endif /* MBEDTLS_THREADING_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* threading.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/timing.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/timing.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/timing.h	(revision 398)
@@ -0,0 +1,153 @@
+/**
+ * \file timing.h
+ *
+ * \brief Portable interface to timeouts and to the CPU cycle counter
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_TIMING_H
+#define MBEDTLS_TIMING_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_TIMING_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          timer structure
+ */
+struct mbedtls_timing_hr_time
+{
+    unsigned char opaque[32];
+};
+
+/**
+ * \brief          Context for mbedtls_timing_set/get_delay()
+ */
+typedef struct mbedtls_timing_delay_context
+{
+    struct mbedtls_timing_hr_time   timer;
+    uint32_t                        int_ms;
+    uint32_t                        fin_ms;
+} mbedtls_timing_delay_context;
+
+#else  /* MBEDTLS_TIMING_ALT */
+#include "timing_alt.h"
+#endif /* MBEDTLS_TIMING_ALT */
+
+extern volatile int mbedtls_timing_alarmed;
+
+/**
+ * \brief          Return the CPU cycle counter value
+ *
+ * \warning        This is only a best effort! Do not rely on this!
+ *                 In particular, it is known to be unreliable on virtual
+ *                 machines.
+ *
+ * \note           This value starts at an unspecified origin and
+ *                 may wrap around.
+ */
+unsigned long mbedtls_timing_hardclock( void );
+
+/**
+ * \brief          Return the elapsed time in milliseconds
+ *
+ * \param val      points to a timer structure
+ * \param reset    If 0, query the elapsed time. Otherwise (re)start the timer.
+ *
+ * \return         Elapsed time since the previous reset in ms. When
+ *                 restarting, this is always 0.
+ *
+ * \note           To initialize a timer, call this function with reset=1.
+ *
+ *                 Determining the elapsed time and resetting the timer is not
+ *                 atomic on all platforms, so after the sequence
+ *                 `{ get_timer(1); ...; time1 = get_timer(1); ...; time2 =
+ *                 get_timer(0) }` the value time1+time2 is only approximately
+ *                 the delay since the first reset.
+ */
+unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset );
+
+/**
+ * \brief          Setup an alarm clock
+ *
+ * \param seconds  delay before the "mbedtls_timing_alarmed" flag is set
+ *                 (must be >=0)
+ *
+ * \warning        Only one alarm at a time  is supported. In a threaded
+ *                 context, this means one for the whole process, not one per
+ *                 thread.
+ */
+void mbedtls_set_alarm( int seconds );
+
+/**
+ * \brief          Set a pair of delays to watch
+ *                 (See \c mbedtls_timing_get_delay().)
+ *
+ * \param data     Pointer to timing data.
+ *                 Must point to a valid \c mbedtls_timing_delay_context struct.
+ * \param int_ms   First (intermediate) delay in milliseconds.
+ *                 The effect if int_ms > fin_ms is unspecified.
+ * \param fin_ms   Second (final) delay in milliseconds.
+ *                 Pass 0 to cancel the current delay.
+ *
+ * \note           To set a single delay, either use \c mbedtls_timing_set_timer
+ *                 directly or use this function with int_ms == fin_ms.
+ */
+void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
+
+/**
+ * \brief          Get the status of delays
+ *                 (Memory helper: number of delays passed.)
+ *
+ * \param data     Pointer to timing data
+ *                 Must point to a valid \c mbedtls_timing_delay_context struct.
+ *
+ * \return         -1 if cancelled (fin_ms = 0),
+ *                  0 if none of the delays are passed,
+ *                  1 if only the intermediate delay is passed,
+ *                  2 if the final delay is passed.
+ */
+int mbedtls_timing_get_delay( void *data );
+
+#if defined(MBEDTLS_SELF_TEST)
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if a test failed
+ */
+int mbedtls_timing_self_test( int verbose );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* timing.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/version.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/version.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/version.h	(revision 398)
@@ -0,0 +1,112 @@
+/**
+ * \file version.h
+ *
+ * \brief Run-time version information
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * This set of compile-time defines and run-time variables can be used to
+ * determine the version number of the mbed TLS library used.
+ */
+#ifndef MBEDTLS_VERSION_H
+#define MBEDTLS_VERSION_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+/**
+ * The version number x.y.z is split into three parts.
+ * Major, Minor, Patchlevel
+ */
+#define MBEDTLS_VERSION_MAJOR  2
+#define MBEDTLS_VERSION_MINOR  16
+#define MBEDTLS_VERSION_PATCH  1
+
+/**
+ * The single version number has the following structure:
+ *    MMNNPP00
+ *    Major version | Minor version | Patch version
+ */
+#define MBEDTLS_VERSION_NUMBER         0x02100100
+#define MBEDTLS_VERSION_STRING         "2.16.1"
+#define MBEDTLS_VERSION_STRING_FULL    "mbed TLS 2.16.1"
+
+#if defined(MBEDTLS_VERSION_C)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Get the version number.
+ *
+ * \return          The constructed version number in the format
+ *                  MMNNPP00 (Major, Minor, Patch).
+ */
+unsigned int mbedtls_version_get_number( void );
+
+/**
+ * Get the version string ("x.y.z").
+ *
+ * \param string    The string that will receive the value.
+ *                  (Should be at least 9 bytes in size)
+ */
+void mbedtls_version_get_string( char *string );
+
+/**
+ * Get the full version string ("mbed TLS x.y.z").
+ *
+ * \param string    The string that will receive the value. The mbed TLS version
+ *                  string will use 18 bytes AT MOST including a terminating
+ *                  null byte.
+ *                  (So the buffer should be at least 18 bytes to receive this
+ *                  version string).
+ */
+void mbedtls_version_get_string_full( char *string );
+
+/**
+ * \brief           Check if support for a feature was compiled into this
+ *                  mbed TLS binary. This allows you to see at runtime if the
+ *                  library was for instance compiled with or without
+ *                  Multi-threading support.
+ *
+ * \note            only checks against defines in the sections "System
+ *                  support", "mbed TLS modules" and "mbed TLS feature
+ *                  support" in config.h
+ *
+ * \param feature   The string for the define to check (e.g. "MBEDTLS_AES_C")
+ *
+ * \return          0 if the feature is present,
+ *                  -1 if the feature is not present and
+ *                  -2 if support for feature checking as a whole was not
+ *                  compiled in.
+ */
+int mbedtls_version_check_feature( const char *feature );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_VERSION_C */
+
+#endif /* version.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509.h	(revision 398)
@@ -0,0 +1,337 @@
+/**
+ * \file x509.h
+ *
+ * \brief X.509 generic defines and structures
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_X509_H
+#define MBEDTLS_X509_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "asn1.h"
+#include "pk.h"
+
+#if defined(MBEDTLS_RSA_C)
+#include "rsa.h"
+#endif
+
+/**
+ * \addtogroup x509_module
+ * \{
+ */
+
+#if !defined(MBEDTLS_X509_MAX_INTERMEDIATE_CA)
+/**
+ * Maximum number of intermediate CAs in a verification chain.
+ * That is, maximum length of the chain, excluding the end-entity certificate
+ * and the trusted root certificate.
+ *
+ * Set this to a low value to prevent an adversary from making you waste
+ * resources verifying an overlong certificate chain.
+ */
+#define MBEDTLS_X509_MAX_INTERMEDIATE_CA   8
+#endif
+
+/**
+ * \name X509 Error codes
+ * \{
+ */
+#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE              -0x2080  /**< Unavailable feature, e.g. RSA hashing/encryption combination. */
+#define MBEDTLS_ERR_X509_UNKNOWN_OID                      -0x2100  /**< Requested OID is unknown. */
+#define MBEDTLS_ERR_X509_INVALID_FORMAT                   -0x2180  /**< The CRT/CRL/CSR format is invalid, e.g. different type expected. */
+#define MBEDTLS_ERR_X509_INVALID_VERSION                  -0x2200  /**< The CRT/CRL/CSR version element is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_SERIAL                   -0x2280  /**< The serial tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_ALG                      -0x2300  /**< The algorithm tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_NAME                     -0x2380  /**< The name tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_DATE                     -0x2400  /**< The date tag or value is invalid. */
+#define MBEDTLS_ERR_X509_INVALID_SIGNATURE                -0x2480  /**< The signature tag or value invalid. */
+#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS               -0x2500  /**< The extension tag or value is invalid. */
+#define MBEDTLS_ERR_X509_UNKNOWN_VERSION                  -0x2580  /**< CRT/CRL/CSR has an unsupported version number. */
+#define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG                  -0x2600  /**< Signature algorithm (oid) is unsupported. */
+#define MBEDTLS_ERR_X509_SIG_MISMATCH                     -0x2680  /**< Signature algorithms do not match. (see \c ::mbedtls_x509_crt sig_oid) */
+#define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED               -0x2700  /**< Certificate verification failed, e.g. CRL, CA or signature check failed. */
+#define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT              -0x2780  /**< Format not recognized as DER or PEM. */
+#define MBEDTLS_ERR_X509_BAD_INPUT_DATA                   -0x2800  /**< Input invalid. */
+#define MBEDTLS_ERR_X509_ALLOC_FAILED                     -0x2880  /**< Allocation of memory failed. */
+#define MBEDTLS_ERR_X509_FILE_IO_ERROR                    -0x2900  /**< Read/write of file failed. */
+#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL                 -0x2980  /**< Destination buffer is too small. */
+#define MBEDTLS_ERR_X509_FATAL_ERROR                      -0x3000  /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */
+/* \} name */
+
+/**
+ * \name X509 Verify codes
+ * \{
+ */
+/* Reminder: update x509_crt_verify_strings[] in library/x509_crt.c */
+#define MBEDTLS_X509_BADCERT_EXPIRED             0x01  /**< The certificate validity has expired. */
+#define MBEDTLS_X509_BADCERT_REVOKED             0x02  /**< The certificate has been revoked (is on a CRL). */
+#define MBEDTLS_X509_BADCERT_CN_MISMATCH         0x04  /**< The certificate Common Name (CN) does not match with the expected CN. */
+#define MBEDTLS_X509_BADCERT_NOT_TRUSTED         0x08  /**< The certificate is not correctly signed by the trusted CA. */
+#define MBEDTLS_X509_BADCRL_NOT_TRUSTED          0x10  /**< The CRL is not correctly signed by the trusted CA. */
+#define MBEDTLS_X509_BADCRL_EXPIRED              0x20  /**< The CRL is expired. */
+#define MBEDTLS_X509_BADCERT_MISSING             0x40  /**< Certificate was missing. */
+#define MBEDTLS_X509_BADCERT_SKIP_VERIFY         0x80  /**< Certificate verification was skipped. */
+#define MBEDTLS_X509_BADCERT_OTHER             0x0100  /**< Other reason (can be used by verify callback) */
+#define MBEDTLS_X509_BADCERT_FUTURE            0x0200  /**< The certificate validity starts in the future. */
+#define MBEDTLS_X509_BADCRL_FUTURE             0x0400  /**< The CRL is from the future */
+#define MBEDTLS_X509_BADCERT_KEY_USAGE         0x0800  /**< Usage does not match the keyUsage extension. */
+#define MBEDTLS_X509_BADCERT_EXT_KEY_USAGE     0x1000  /**< Usage does not match the extendedKeyUsage extension. */
+#define MBEDTLS_X509_BADCERT_NS_CERT_TYPE      0x2000  /**< Usage does not match the nsCertType extension. */
+#define MBEDTLS_X509_BADCERT_BAD_MD            0x4000  /**< The certificate is signed with an unacceptable hash. */
+#define MBEDTLS_X509_BADCERT_BAD_PK            0x8000  /**< The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA). */
+#define MBEDTLS_X509_BADCERT_BAD_KEY         0x010000  /**< The certificate is signed with an unacceptable key (eg bad curve, RSA too short). */
+#define MBEDTLS_X509_BADCRL_BAD_MD           0x020000  /**< The CRL is signed with an unacceptable hash. */
+#define MBEDTLS_X509_BADCRL_BAD_PK           0x040000  /**< The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA). */
+#define MBEDTLS_X509_BADCRL_BAD_KEY          0x080000  /**< The CRL is signed with an unacceptable key (eg bad curve, RSA too short). */
+
+/* \} name */
+/* \} addtogroup x509_module */
+
+/*
+ * X.509 v3 Key Usage Extension flags
+ * Reminder: update x509_info_key_usage() when adding new flags.
+ */
+#define MBEDTLS_X509_KU_DIGITAL_SIGNATURE            (0x80)  /* bit 0 */
+#define MBEDTLS_X509_KU_NON_REPUDIATION              (0x40)  /* bit 1 */
+#define MBEDTLS_X509_KU_KEY_ENCIPHERMENT             (0x20)  /* bit 2 */
+#define MBEDTLS_X509_KU_DATA_ENCIPHERMENT            (0x10)  /* bit 3 */
+#define MBEDTLS_X509_KU_KEY_AGREEMENT                (0x08)  /* bit 4 */
+#define MBEDTLS_X509_KU_KEY_CERT_SIGN                (0x04)  /* bit 5 */
+#define MBEDTLS_X509_KU_CRL_SIGN                     (0x02)  /* bit 6 */
+#define MBEDTLS_X509_KU_ENCIPHER_ONLY                (0x01)  /* bit 7 */
+#define MBEDTLS_X509_KU_DECIPHER_ONLY              (0x8000)  /* bit 8 */
+
+/*
+ * Netscape certificate types
+ * (http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html)
+ */
+
+#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT         (0x80)  /* bit 0 */
+#define MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER         (0x40)  /* bit 1 */
+#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL              (0x20)  /* bit 2 */
+#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING     (0x10)  /* bit 3 */
+#define MBEDTLS_X509_NS_CERT_TYPE_RESERVED           (0x08)  /* bit 4 */
+#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CA             (0x04)  /* bit 5 */
+#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA           (0x02)  /* bit 6 */
+#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA  (0x01)  /* bit 7 */
+
+/*
+ * X.509 extension types
+ *
+ * Comments refer to the status for using certificates. Status can be
+ * different for writing certificates or reading CRLs or CSRs.
+ */
+#define MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER    (1 << 0)
+#define MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER      (1 << 1)
+#define MBEDTLS_X509_EXT_KEY_USAGE                   (1 << 2)
+#define MBEDTLS_X509_EXT_CERTIFICATE_POLICIES        (1 << 3)
+#define MBEDTLS_X509_EXT_POLICY_MAPPINGS             (1 << 4)
+#define MBEDTLS_X509_EXT_SUBJECT_ALT_NAME            (1 << 5)    /* Supported (DNS) */
+#define MBEDTLS_X509_EXT_ISSUER_ALT_NAME             (1 << 6)
+#define MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS     (1 << 7)
+#define MBEDTLS_X509_EXT_BASIC_CONSTRAINTS           (1 << 8)    /* Supported */
+#define MBEDTLS_X509_EXT_NAME_CONSTRAINTS            (1 << 9)
+#define MBEDTLS_X509_EXT_POLICY_CONSTRAINTS          (1 << 10)
+#define MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE          (1 << 11)
+#define MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS     (1 << 12)
+#define MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY          (1 << 13)
+#define MBEDTLS_X509_EXT_FRESHEST_CRL                (1 << 14)
+
+#define MBEDTLS_X509_EXT_NS_CERT_TYPE                (1 << 16)
+
+/*
+ * Storage format identifiers
+ * Recognized formats: PEM and DER
+ */
+#define MBEDTLS_X509_FORMAT_DER                 1
+#define MBEDTLS_X509_FORMAT_PEM                 2
+
+#define MBEDTLS_X509_MAX_DN_NAME_SIZE         256 /**< Maximum value size of a DN entry */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup x509_module
+ * \{ */
+
+/**
+ * \name Structures for parsing X.509 certificates, CRLs and CSRs
+ * \{
+ */
+
+/**
+ * Type-length-value structure that allows for ASN1 using DER.
+ */
+typedef mbedtls_asn1_buf mbedtls_x509_buf;
+
+/**
+ * Container for ASN1 bit strings.
+ */
+typedef mbedtls_asn1_bitstring mbedtls_x509_bitstring;
+
+/**
+ * Container for ASN1 named information objects.
+ * It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.).
+ */
+typedef mbedtls_asn1_named_data mbedtls_x509_name;
+
+/**
+ * Container for a sequence of ASN.1 items
+ */
+typedef mbedtls_asn1_sequence mbedtls_x509_sequence;
+
+/** Container for date and time (precision in seconds). */
+typedef struct mbedtls_x509_time
+{
+    int year, mon, day;         /**< Date. */
+    int hour, min, sec;         /**< Time. */
+}
+mbedtls_x509_time;
+
+/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */
+/** \} addtogroup x509_module */
+
+/**
+ * \brief          Store the certificate DN in printable form into buf;
+ *                 no more than size characters will be written.
+ *
+ * \param buf      Buffer to write to
+ * \param size     Maximum size of buffer
+ * \param dn       The X509 name to represent
+ *
+ * \return         The length of the string written (not including the
+ *                 terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn );
+
+/**
+ * \brief          Store the certificate serial in printable form into buf;
+ *                 no more than size characters will be written.
+ *
+ * \param buf      Buffer to write to
+ * \param size     Maximum size of buffer
+ * \param serial   The X509 serial to represent
+ *
+ * \return         The length of the string written (not including the
+ *                 terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial );
+
+/**
+ * \brief          Check a given mbedtls_x509_time against the system time
+ *                 and tell if it's in the past.
+ *
+ * \note           Intended usage is "if( is_past( valid_to ) ) ERROR".
+ *                 Hence the return value of 1 if on internal errors.
+ *
+ * \param to       mbedtls_x509_time to check
+ *
+ * \return         1 if the given time is in the past or an error occured,
+ *                 0 otherwise.
+ */
+int mbedtls_x509_time_is_past( const mbedtls_x509_time *to );
+
+/**
+ * \brief          Check a given mbedtls_x509_time against the system time
+ *                 and tell if it's in the future.
+ *
+ * \note           Intended usage is "if( is_future( valid_from ) ) ERROR".
+ *                 Hence the return value of 1 if on internal errors.
+ *
+ * \param from     mbedtls_x509_time to check
+ *
+ * \return         1 if the given time is in the future or an error occured,
+ *                 0 otherwise.
+ */
+int mbedtls_x509_time_is_future( const mbedtls_x509_time *from );
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int mbedtls_x509_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+/*
+ * Internal module functions. You probably do not want to use these unless you
+ * know you do.
+ */
+int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
+                   mbedtls_x509_name *cur );
+int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
+                       mbedtls_x509_buf *alg );
+int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
+                  mbedtls_x509_buf *alg, mbedtls_x509_buf *params );
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
+                                mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
+                                int *salt_len );
+#endif
+int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig );
+int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
+                      mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
+                      void **sig_opts );
+int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
+                   mbedtls_x509_time *t );
+int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
+                     mbedtls_x509_buf *serial );
+int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
+                  mbedtls_x509_buf *ext, int tag );
+int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
+                       mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
+                       const void *sig_opts );
+int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name );
+int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name );
+int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
+                        int critical, const unsigned char *val,
+                        size_t val_len );
+int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
+                           mbedtls_asn1_named_data *first );
+int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
+                      mbedtls_asn1_named_data *first );
+int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
+                    const char *oid, size_t oid_len,
+                    unsigned char *sig, size_t size );
+
+#define MBEDTLS_X509_SAFE_SNPRINTF                          \
+    do {                                                    \
+        if( ret < 0 || (size_t) ret >= n )                  \
+            return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );    \
+                                                            \
+        n -= (size_t) ret;                                  \
+        p += (size_t) ret;                                  \
+    } while( 0 )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* x509.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509_crl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509_crl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509_crl.h	(revision 398)
@@ -0,0 +1,174 @@
+/**
+ * \file x509_crl.h
+ *
+ * \brief X.509 certificate revocation list parsing
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_X509_CRL_H
+#define MBEDTLS_X509_CRL_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "x509.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup x509_module
+ * \{ */
+
+/**
+ * \name Structures and functions for parsing CRLs
+ * \{
+ */
+
+/**
+ * Certificate revocation list entry.
+ * Contains the CA-specific serial numbers and revocation dates.
+ */
+typedef struct mbedtls_x509_crl_entry
+{
+    mbedtls_x509_buf raw;
+
+    mbedtls_x509_buf serial;
+
+    mbedtls_x509_time revocation_date;
+
+    mbedtls_x509_buf entry_ext;
+
+    struct mbedtls_x509_crl_entry *next;
+}
+mbedtls_x509_crl_entry;
+
+/**
+ * Certificate revocation list structure.
+ * Every CRL may have multiple entries.
+ */
+typedef struct mbedtls_x509_crl
+{
+    mbedtls_x509_buf raw;           /**< The raw certificate data (DER). */
+    mbedtls_x509_buf tbs;           /**< The raw certificate body (DER). The part that is To Be Signed. */
+
+    int version;            /**< CRL version (1=v1, 2=v2) */
+    mbedtls_x509_buf sig_oid;       /**< CRL signature type identifier */
+
+    mbedtls_x509_buf issuer_raw;    /**< The raw issuer data (DER). */
+
+    mbedtls_x509_name issuer;       /**< The parsed issuer data (named information object). */
+
+    mbedtls_x509_time this_update;
+    mbedtls_x509_time next_update;
+
+    mbedtls_x509_crl_entry entry;   /**< The CRL entries containing the certificate revocation times for this CA. */
+
+    mbedtls_x509_buf crl_ext;
+
+    mbedtls_x509_buf sig_oid2;
+    mbedtls_x509_buf sig;
+    mbedtls_md_type_t sig_md;           /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
+    mbedtls_pk_type_t sig_pk;           /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
+    void *sig_opts;             /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
+
+    struct mbedtls_x509_crl *next;
+}
+mbedtls_x509_crl;
+
+/**
+ * \brief          Parse a DER-encoded CRL and append it to the chained list
+ *
+ * \param chain    points to the start of the chain
+ * \param buf      buffer holding the CRL data in DER format
+ * \param buflen   size of the buffer
+ *                 (including the terminating null byte for PEM data)
+ *
+ * \return         0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
+                        const unsigned char *buf, size_t buflen );
+/**
+ * \brief          Parse one or more CRLs and append them to the chained list
+ *
+ * \note           Mutliple CRLs are accepted only if using PEM format
+ *
+ * \param chain    points to the start of the chain
+ * \param buf      buffer holding the CRL data in PEM or DER format
+ * \param buflen   size of the buffer
+ *                 (including the terminating null byte for PEM data)
+ *
+ * \return         0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen );
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief          Load one or more CRLs and append them to the chained list
+ *
+ * \note           Mutliple CRLs are accepted only if using PEM format
+ *
+ * \param chain    points to the start of the chain
+ * \param path     filename to read the CRLs from (in PEM or DER encoding)
+ *
+ * \return         0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path );
+#endif /* MBEDTLS_FS_IO */
+
+/**
+ * \brief          Returns an informational string about the CRL.
+ *
+ * \param buf      Buffer to write to
+ * \param size     Maximum size of buffer
+ * \param prefix   A line prefix
+ * \param crl      The X509 CRL to represent
+ *
+ * \return         The length of the string written (not including the
+ *                 terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
+                   const mbedtls_x509_crl *crl );
+
+/**
+ * \brief          Initialize a CRL (chain)
+ *
+ * \param crl      CRL chain to initialize
+ */
+void mbedtls_x509_crl_init( mbedtls_x509_crl *crl );
+
+/**
+ * \brief          Unallocate all CRL data
+ *
+ * \param crl      CRL chain to free
+ */
+void mbedtls_x509_crl_free( mbedtls_x509_crl *crl );
+
+/* \} name */
+/* \} addtogroup x509_module */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_x509_crl.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509_crt.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509_crt.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509_crt.h	(revision 398)
@@ -0,0 +1,785 @@
+/**
+ * \file x509_crt.h
+ *
+ * \brief X.509 certificate parsing and writing
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_X509_CRT_H
+#define MBEDTLS_X509_CRT_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "x509.h"
+#include "x509_crl.h"
+
+/**
+ * \addtogroup x509_module
+ * \{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \name Structures and functions for parsing and writing X.509 certificates
+ * \{
+ */
+
+/**
+ * Container for an X.509 certificate. The certificate may be chained.
+ */
+typedef struct mbedtls_x509_crt
+{
+    mbedtls_x509_buf raw;               /**< The raw certificate data (DER). */
+    mbedtls_x509_buf tbs;               /**< The raw certificate body (DER). The part that is To Be Signed. */
+
+    int version;                /**< The X.509 version. (1=v1, 2=v2, 3=v3) */
+    mbedtls_x509_buf serial;            /**< Unique id for certificate issued by a specific CA. */
+    mbedtls_x509_buf sig_oid;           /**< Signature algorithm, e.g. sha1RSA */
+
+    mbedtls_x509_buf issuer_raw;        /**< The raw issuer data (DER). Used for quick comparison. */
+    mbedtls_x509_buf subject_raw;       /**< The raw subject data (DER). Used for quick comparison. */
+
+    mbedtls_x509_name issuer;           /**< The parsed issuer data (named information object). */
+    mbedtls_x509_name subject;          /**< The parsed subject data (named information object). */
+
+    mbedtls_x509_time valid_from;       /**< Start time of certificate validity. */
+    mbedtls_x509_time valid_to;         /**< End time of certificate validity. */
+
+    mbedtls_pk_context pk;              /**< Container for the public key context. */
+
+    mbedtls_x509_buf issuer_id;         /**< Optional X.509 v2/v3 issuer unique identifier. */
+    mbedtls_x509_buf subject_id;        /**< Optional X.509 v2/v3 subject unique identifier. */
+    mbedtls_x509_buf v3_ext;            /**< Optional X.509 v3 extensions.  */
+    mbedtls_x509_sequence subject_alt_names;    /**< Optional list of Subject Alternative Names (Only dNSName supported). */
+
+    int ext_types;              /**< Bit string containing detected and parsed extensions */
+    int ca_istrue;              /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
+    int max_pathlen;            /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */
+
+    unsigned int key_usage;     /**< Optional key usage extension value: See the values in x509.h */
+
+    mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */
+
+    unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */
+
+    mbedtls_x509_buf sig;               /**< Signature: hash of the tbs part signed with the private key. */
+    mbedtls_md_type_t sig_md;           /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
+    mbedtls_pk_type_t sig_pk;           /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
+    void *sig_opts;             /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
+
+    struct mbedtls_x509_crt *next;     /**< Next certificate in the CA-chain. */
+}
+mbedtls_x509_crt;
+
+/**
+ * Build flag from an algorithm/curve identifier (pk, md, ecp)
+ * Since 0 is always XXX_NONE, ignore it.
+ */
+#define MBEDTLS_X509_ID_FLAG( id )   ( 1 << ( id - 1 ) )
+
+/**
+ * Security profile for certificate verification.
+ *
+ * All lists are bitfields, built by ORing flags from MBEDTLS_X509_ID_FLAG().
+ */
+typedef struct mbedtls_x509_crt_profile
+{
+    uint32_t allowed_mds;       /**< MDs for signatures         */
+    uint32_t allowed_pks;       /**< PK algs for signatures     */
+    uint32_t allowed_curves;    /**< Elliptic curves for ECDSA  */
+    uint32_t rsa_min_bitlen;    /**< Minimum size for RSA keys  */
+}
+mbedtls_x509_crt_profile;
+
+#define MBEDTLS_X509_CRT_VERSION_1              0
+#define MBEDTLS_X509_CRT_VERSION_2              1
+#define MBEDTLS_X509_CRT_VERSION_3              2
+
+#define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32
+#define MBEDTLS_X509_RFC5280_UTC_TIME_LEN   15
+
+#if !defined( MBEDTLS_X509_MAX_FILE_PATH_LEN )
+#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512
+#endif
+
+/**
+ * Container for writing a certificate (CRT)
+ */
+typedef struct mbedtls_x509write_cert
+{
+    int version;
+    mbedtls_mpi serial;
+    mbedtls_pk_context *subject_key;
+    mbedtls_pk_context *issuer_key;
+    mbedtls_asn1_named_data *subject;
+    mbedtls_asn1_named_data *issuer;
+    mbedtls_md_type_t md_alg;
+    char not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1];
+    char not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN + 1];
+    mbedtls_asn1_named_data *extensions;
+}
+mbedtls_x509write_cert;
+
+/**
+ * Item in a verification chain: cert and flags for it
+ */
+typedef struct {
+    mbedtls_x509_crt *crt;
+    uint32_t flags;
+} mbedtls_x509_crt_verify_chain_item;
+
+/**
+ * Max size of verification chain: end-entity + intermediates + trusted root
+ */
+#define MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE  ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 )
+
+/**
+ * Verification chain as built by \c mbedtls_crt_verify_chain()
+ */
+typedef struct
+{
+    mbedtls_x509_crt_verify_chain_item items[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE];
+    unsigned len;
+} mbedtls_x509_crt_verify_chain;
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+
+/**
+ * \brief       Context for resuming X.509 verify operations
+ */
+typedef struct
+{
+    /* for check_signature() */
+    mbedtls_pk_restart_ctx pk;
+
+    /* for find_parent_in() */
+    mbedtls_x509_crt *parent; /* non-null iff parent_in in progress */
+    mbedtls_x509_crt *fallback_parent;
+    int fallback_signature_is_good;
+
+    /* for find_parent() */
+    int parent_is_trusted; /* -1 if find_parent is not in progress */
+
+    /* for verify_chain() */
+    enum {
+        x509_crt_rs_none,
+        x509_crt_rs_find_parent,
+    } in_progress;  /* none if no operation is in progress */
+    int self_cnt;
+    mbedtls_x509_crt_verify_chain ver_chain;
+
+} mbedtls_x509_crt_restart_ctx;
+
+#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+/* Now we can declare functions that take a pointer to that */
+typedef void mbedtls_x509_crt_restart_ctx;
+
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * Default security profile. Should provide a good balance between security
+ * and compatibility with current deployments.
+ */
+extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default;
+
+/**
+ * Expected next default profile. Recommended for new deployments.
+ * Currently targets a 128-bit security level, except for RSA-2048.
+ */
+extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next;
+
+/**
+ * NSA Suite B profile.
+ */
+extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb;
+
+/**
+ * \brief          Parse a single DER formatted certificate and add it
+ *                 to the chained list.
+ *
+ * \param chain    points to the start of the chain
+ * \param buf      buffer holding the certificate DER data
+ * \param buflen   size of the buffer
+ *
+ * \return         0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
+                        size_t buflen );
+
+/**
+ * \brief          Parse one DER-encoded or one or more concatenated PEM-encoded
+ *                 certificates and add them to the chained list.
+ *
+ *                 For CRTs in PEM encoding, the function parses permissively:
+ *                 if at least one certificate can be parsed, the function
+ *                 returns the number of certificates for which parsing failed
+ *                 (hence \c 0 if all certificates were parsed successfully).
+ *                 If no certificate could be parsed, the function returns
+ *                 the first (negative) error encountered during parsing.
+ *
+ *                 PEM encoded certificates may be interleaved by other data
+ *                 such as human readable descriptions of their content, as
+ *                 long as the certificates are enclosed in the PEM specific
+ *                 '-----{BEGIN/END} CERTIFICATE-----' delimiters.
+ *
+ * \param chain    The chain to which to add the parsed certificates.
+ * \param buf      The buffer holding the certificate data in PEM or DER format.
+ *                 For certificates in PEM encoding, this may be a concatenation
+ *                 of multiple certificates; for DER encoding, the buffer must
+ *                 comprise exactly one certificate.
+ * \param buflen   The size of \p buf, including the terminating \c NULL byte
+ *                 in case of PEM encoded data.
+ *
+ * \return         \c 0 if all certificates were parsed successfully.
+ * \return         The (positive) number of certificates that couldn't
+ *                 be parsed if parsing was partly successful (see above).
+ * \return         A negative X509 or PEM error code otherwise.
+ *
+ */
+int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen );
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief          Load one or more certificates and add them
+ *                 to the chained list. Parses permissively. If some
+ *                 certificates can be parsed, the result is the number
+ *                 of failed certificates it encountered. If none complete
+ *                 correctly, the first error is returned.
+ *
+ * \param chain    points to the start of the chain
+ * \param path     filename to read the certificates from
+ *
+ * \return         0 if all certificates parsed successfully, a positive number
+ *                 if partly successful or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path );
+
+/**
+ * \brief          Load one or more certificate files from a path and add them
+ *                 to the chained list. Parses permissively. If some
+ *                 certificates can be parsed, the result is the number
+ *                 of failed certificates it encountered. If none complete
+ *                 correctly, the first error is returned.
+ *
+ * \param chain    points to the start of the chain
+ * \param path     directory / folder to read the certificate files from
+ *
+ * \return         0 if all certificates parsed successfully, a positive number
+ *                 if partly successful or a specific X509 or PEM error code
+ */
+int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path );
+#endif /* MBEDTLS_FS_IO */
+
+/**
+ * \brief          Returns an informational string about the
+ *                 certificate.
+ *
+ * \param buf      Buffer to write to
+ * \param size     Maximum size of buffer
+ * \param prefix   A line prefix
+ * \param crt      The X509 certificate to represent
+ *
+ * \return         The length of the string written (not including the
+ *                 terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
+                   const mbedtls_x509_crt *crt );
+
+/**
+ * \brief          Returns an informational string about the
+ *                 verification status of a certificate.
+ *
+ * \param buf      Buffer to write to
+ * \param size     Maximum size of buffer
+ * \param prefix   A line prefix
+ * \param flags    Verification flags created by mbedtls_x509_crt_verify()
+ *
+ * \return         The length of the string written (not including the
+ *                 terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
+                          uint32_t flags );
+
+/**
+ * \brief          Verify the certificate signature
+ *
+ *                 The verify callback is a user-supplied callback that
+ *                 can clear / modify / add flags for a certificate. If set,
+ *                 the verification callback is called for each
+ *                 certificate in the chain (from the trust-ca down to the
+ *                 presented crt). The parameters for the callback are:
+ *                 (void *parameter, mbedtls_x509_crt *crt, int certificate_depth,
+ *                 int *flags). With the flags representing current flags for
+ *                 that specific certificate and the certificate depth from
+ *                 the bottom (Peer cert depth = 0).
+ *
+ *                 All flags left after returning from the callback
+ *                 are also returned to the application. The function should
+ *                 return 0 for anything (including invalid certificates)
+ *                 other than fatal error, as a non-zero return code
+ *                 immediately aborts the verification process. For fatal
+ *                 errors, a specific error code should be used (different
+ *                 from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not
+ *                 be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR
+ *                 can be used if no better code is available.
+ *
+ * \note           In case verification failed, the results can be displayed
+ *                 using \c mbedtls_x509_crt_verify_info()
+ *
+ * \note           Same as \c mbedtls_x509_crt_verify_with_profile() with the
+ *                 default security profile.
+ *
+ * \note           It is your responsibility to provide up-to-date CRLs for
+ *                 all trusted CAs. If no CRL is provided for the CA that was
+ *                 used to sign the certificate, CRL verification is skipped
+ *                 silently, that is *without* setting any flag.
+ *
+ * \note           The \c trust_ca list can contain two types of certificates:
+ *                 (1) those of trusted root CAs, so that certificates
+ *                 chaining up to those CAs will be trusted, and (2)
+ *                 self-signed end-entity certificates to be trusted (for
+ *                 specific peers you know) - in that case, the self-signed
+ *                 certificate doesn't need to have the CA bit set.
+ *
+ * \param crt      a certificate (chain) to be verified
+ * \param trust_ca the list of trusted CAs (see note above)
+ * \param ca_crl   the list of CRLs for trusted CAs (see note above)
+ * \param cn       expected Common Name (can be set to
+ *                 NULL if the CN must not be verified)
+ * \param flags    result of the verification
+ * \param f_vrfy   verification function
+ * \param p_vrfy   verification parameter
+ *
+ * \return         0 (and flags set to 0) if the chain was verified and valid,
+ *                 MBEDTLS_ERR_X509_CERT_VERIFY_FAILED if the chain was verified
+ *                 but found to be invalid, in which case *flags will have one
+ *                 or more MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX
+ *                 flags set, or another error (and flags set to 0xffffffff)
+ *                 in case of a fatal error encountered during the
+ *                 verification process.
+ */
+int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
+                     mbedtls_x509_crt *trust_ca,
+                     mbedtls_x509_crl *ca_crl,
+                     const char *cn, uint32_t *flags,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+                     void *p_vrfy );
+
+/**
+ * \brief          Verify the certificate signature according to profile
+ *
+ * \note           Same as \c mbedtls_x509_crt_verify(), but with explicit
+ *                 security profile.
+ *
+ * \note           The restrictions on keys (RSA minimum size, allowed curves
+ *                 for ECDSA) apply to all certificates: trusted root,
+ *                 intermediate CAs if any, and end entity certificate.
+ *
+ * \param crt      a certificate (chain) to be verified
+ * \param trust_ca the list of trusted CAs
+ * \param ca_crl   the list of CRLs for trusted CAs
+ * \param profile  security profile for verification
+ * \param cn       expected Common Name (can be set to
+ *                 NULL if the CN must not be verified)
+ * \param flags    result of the verification
+ * \param f_vrfy   verification function
+ * \param p_vrfy   verification parameter
+ *
+ * \return         0 if successful or MBEDTLS_ERR_X509_CERT_VERIFY_FAILED
+ *                 in which case *flags will have one or more
+ *                 MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX flags
+ *                 set,
+ *                 or another error in case of a fatal error encountered
+ *                 during the verification process.
+ */
+int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
+                     mbedtls_x509_crt *trust_ca,
+                     mbedtls_x509_crl *ca_crl,
+                     const mbedtls_x509_crt_profile *profile,
+                     const char *cn, uint32_t *flags,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+                     void *p_vrfy );
+
+/**
+ * \brief          Restartable version of \c mbedtls_crt_verify_with_profile()
+ *
+ * \note           Performs the same job as \c mbedtls_crt_verify_with_profile()
+ *                 but can return early and restart according to the limit
+ *                 set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
+ *
+ * \param crt      a certificate (chain) to be verified
+ * \param trust_ca the list of trusted CAs
+ * \param ca_crl   the list of CRLs for trusted CAs
+ * \param profile  security profile for verification
+ * \param cn       expected Common Name (can be set to
+ *                 NULL if the CN must not be verified)
+ * \param flags    result of the verification
+ * \param f_vrfy   verification function
+ * \param p_vrfy   verification parameter
+ * \param rs_ctx   restart context (NULL to disable restart)
+ *
+ * \return         See \c mbedtls_crt_verify_with_profile(), or
+ * \return         #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
+ *                 operations was reached: see \c mbedtls_ecp_set_max_ops().
+ */
+int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
+                     mbedtls_x509_crt *trust_ca,
+                     mbedtls_x509_crl *ca_crl,
+                     const mbedtls_x509_crt_profile *profile,
+                     const char *cn, uint32_t *flags,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+                     void *p_vrfy,
+                     mbedtls_x509_crt_restart_ctx *rs_ctx );
+
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
+/**
+ * \brief          Check usage of certificate against keyUsage extension.
+ *
+ * \param crt      Leaf certificate used.
+ * \param usage    Intended usage(s) (eg MBEDTLS_X509_KU_KEY_ENCIPHERMENT
+ *                 before using the certificate to perform an RSA key
+ *                 exchange).
+ *
+ * \note           Except for decipherOnly and encipherOnly, a bit set in the
+ *                 usage argument means this bit MUST be set in the
+ *                 certificate. For decipherOnly and encipherOnly, it means
+ *                 that bit MAY be set.
+ *
+ * \return         0 is these uses of the certificate are allowed,
+ *                 MBEDTLS_ERR_X509_BAD_INPUT_DATA if the keyUsage extension
+ *                 is present but does not match the usage argument.
+ *
+ * \note           You should only call this function on leaf certificates, on
+ *                 (intermediate) CAs the keyUsage extension is automatically
+ *                 checked by \c mbedtls_x509_crt_verify().
+ */
+int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
+                                      unsigned int usage );
+#endif /* MBEDTLS_X509_CHECK_KEY_USAGE) */
+
+#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
+/**
+ * \brief           Check usage of certificate against extendedKeyUsage.
+ *
+ * \param crt       Leaf certificate used.
+ * \param usage_oid Intended usage (eg MBEDTLS_OID_SERVER_AUTH or
+ *                  MBEDTLS_OID_CLIENT_AUTH).
+ * \param usage_len Length of usage_oid (eg given by MBEDTLS_OID_SIZE()).
+ *
+ * \return          0 if this use of the certificate is allowed,
+ *                  MBEDTLS_ERR_X509_BAD_INPUT_DATA if not.
+ *
+ * \note            Usually only makes sense on leaf certificates.
+ */
+int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
+                                               const char *usage_oid,
+                                               size_t usage_len );
+#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
+
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
+/**
+ * \brief          Verify the certificate revocation status
+ *
+ * \param crt      a certificate to be verified
+ * \param crl      the CRL to verify against
+ *
+ * \return         1 if the certificate is revoked, 0 otherwise
+ *
+ */
+int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl );
+#endif /* MBEDTLS_X509_CRL_PARSE_C */
+
+/**
+ * \brief          Initialize a certificate (chain)
+ *
+ * \param crt      Certificate chain to initialize
+ */
+void mbedtls_x509_crt_init( mbedtls_x509_crt *crt );
+
+/**
+ * \brief          Unallocate all certificate data
+ *
+ * \param crt      Certificate chain to free
+ */
+void mbedtls_x509_crt_free( mbedtls_x509_crt *crt );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+/**
+ * \brief           Initialize a restart context
+ */
+void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx );
+
+/**
+ * \brief           Free the components of a restart context
+ */
+void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx );
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+/* \} name */
+/* \} addtogroup x509_module */
+
+#if defined(MBEDTLS_X509_CRT_WRITE_C)
+/**
+ * \brief           Initialize a CRT writing context
+ *
+ * \param ctx       CRT context to initialize
+ */
+void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx );
+
+/**
+ * \brief           Set the verion for a Certificate
+ *                  Default: MBEDTLS_X509_CRT_VERSION_3
+ *
+ * \param ctx       CRT context to use
+ * \param version   version to set (MBEDTLS_X509_CRT_VERSION_1, MBEDTLS_X509_CRT_VERSION_2 or
+ *                                  MBEDTLS_X509_CRT_VERSION_3)
+ */
+void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version );
+
+/**
+ * \brief           Set the serial number for a Certificate.
+ *
+ * \param ctx       CRT context to use
+ * \param serial    serial number to set
+ *
+ * \return          0 if successful
+ */
+int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial );
+
+/**
+ * \brief           Set the validity period for a Certificate
+ *                  Timestamps should be in string format for UTC timezone
+ *                  i.e. "YYYYMMDDhhmmss"
+ *                  e.g. "20131231235959" for December 31st 2013
+ *                       at 23:59:59
+ *
+ * \param ctx       CRT context to use
+ * \param not_before    not_before timestamp
+ * \param not_after     not_after timestamp
+ *
+ * \return          0 if timestamp was parsed successfully, or
+ *                  a specific error code
+ */
+int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before,
+                                const char *not_after );
+
+/**
+ * \brief           Set the issuer name for a Certificate
+ *                  Issuer names should contain a comma-separated list
+ *                  of OID types and values:
+ *                  e.g. "C=UK,O=ARM,CN=mbed TLS CA"
+ *
+ * \param ctx           CRT context to use
+ * \param issuer_name   issuer name to set
+ *
+ * \return          0 if issuer name was parsed successfully, or
+ *                  a specific error code
+ */
+int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx,
+                                   const char *issuer_name );
+
+/**
+ * \brief           Set the subject name for a Certificate
+ *                  Subject names should contain a comma-separated list
+ *                  of OID types and values:
+ *                  e.g. "C=UK,O=ARM,CN=mbed TLS Server 1"
+ *
+ * \param ctx           CRT context to use
+ * \param subject_name  subject name to set
+ *
+ * \return          0 if subject name was parsed successfully, or
+ *                  a specific error code
+ */
+int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx,
+                                    const char *subject_name );
+
+/**
+ * \brief           Set the subject public key for the certificate
+ *
+ * \param ctx       CRT context to use
+ * \param key       public key to include
+ */
+void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key );
+
+/**
+ * \brief           Set the issuer key used for signing the certificate
+ *
+ * \param ctx       CRT context to use
+ * \param key       private key to sign with
+ */
+void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key );
+
+/**
+ * \brief           Set the MD algorithm to use for the signature
+ *                  (e.g. MBEDTLS_MD_SHA1)
+ *
+ * \param ctx       CRT context to use
+ * \param md_alg    MD algorithm to use
+ */
+void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg );
+
+/**
+ * \brief           Generic function to add to or replace an extension in the
+ *                  CRT
+ *
+ * \param ctx       CRT context to use
+ * \param oid       OID of the extension
+ * \param oid_len   length of the OID
+ * \param critical  if the extension is critical (per the RFC's definition)
+ * \param val       value of the extension OCTET STRING
+ * \param val_len   length of the value data
+ *
+ * \return          0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx,
+                                 const char *oid, size_t oid_len,
+                                 int critical,
+                                 const unsigned char *val, size_t val_len );
+
+/**
+ * \brief           Set the basicConstraints extension for a CRT
+ *
+ * \param ctx       CRT context to use
+ * \param is_ca     is this a CA certificate
+ * \param max_pathlen   maximum length of certificate chains below this
+ *                      certificate (only for CA certificates, -1 is
+ *                      inlimited)
+ *
+ * \return          0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
+                                         int is_ca, int max_pathlen );
+
+#if defined(MBEDTLS_SHA1_C)
+/**
+ * \brief           Set the subjectKeyIdentifier extension for a CRT
+ *                  Requires that mbedtls_x509write_crt_set_subject_key() has been
+ *                  called before
+ *
+ * \param ctx       CRT context to use
+ *
+ * \return          0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx );
+
+/**
+ * \brief           Set the authorityKeyIdentifier extension for a CRT
+ *                  Requires that mbedtls_x509write_crt_set_issuer_key() has been
+ *                  called before
+ *
+ * \param ctx       CRT context to use
+ *
+ * \return          0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx );
+#endif /* MBEDTLS_SHA1_C */
+
+/**
+ * \brief           Set the Key Usage Extension flags
+ *                  (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN)
+ *
+ * \param ctx       CRT context to use
+ * \param key_usage key usage flags to set
+ *
+ * \return          0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
+                                         unsigned int key_usage );
+
+/**
+ * \brief           Set the Netscape Cert Type flags
+ *                  (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL)
+ *
+ * \param ctx           CRT context to use
+ * \param ns_cert_type  Netscape Cert Type flags to set
+ *
+ * \return          0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
+                                    unsigned char ns_cert_type );
+
+/**
+ * \brief           Free the contents of a CRT write context
+ *
+ * \param ctx       CRT context to free
+ */
+void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx );
+
+/**
+ * \brief           Write a built up certificate to a X509 DER structure
+ *                  Note: data is written at the end of the buffer! Use the
+ *                        return value to determine where you should start
+ *                        using the buffer
+ *
+ * \param ctx       certificate to write away
+ * \param buf       buffer to write to
+ * \param size      size of the buffer
+ * \param f_rng     RNG function (for signature, see note)
+ * \param p_rng     RNG parameter
+ *
+ * \return          length of data written if successful, or a specific
+ *                  error code
+ *
+ * \note            f_rng may be NULL if RSA is used for signature and the
+ *                  signature is made offline (otherwise f_rng is desirable
+ *                  for countermeasures against timing attacks).
+ *                  ECDSA signatures always require a non-NULL f_rng.
+ */
+int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng );
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+/**
+ * \brief           Write a built up certificate to a X509 PEM string
+ *
+ * \param ctx       certificate to write away
+ * \param buf       buffer to write to
+ * \param size      size of the buffer
+ * \param f_rng     RNG function (for signature, see note)
+ * \param p_rng     RNG parameter
+ *
+ * \return          0 if successful, or a specific error code
+ *
+ * \note            f_rng may be NULL if RSA is used for signature and the
+ *                  signature is made offline (otherwise f_rng is desirable
+ *                  for countermeasures against timing attacks).
+ *                  ECDSA signatures always require a non-NULL f_rng.
+ */
+int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng );
+#endif /* MBEDTLS_PEM_WRITE_C */
+#endif /* MBEDTLS_X509_CRT_WRITE_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_x509_crt.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509_csr.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509_csr.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/x509_csr.h	(revision 398)
@@ -0,0 +1,307 @@
+/**
+ * \file x509_csr.h
+ *
+ * \brief X.509 certificate signing request parsing and writing
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_X509_CSR_H
+#define MBEDTLS_X509_CSR_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "x509.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup x509_module
+ * \{ */
+
+/**
+ * \name Structures and functions for X.509 Certificate Signing Requests (CSR)
+ * \{
+ */
+
+/**
+ * Certificate Signing Request (CSR) structure.
+ */
+typedef struct mbedtls_x509_csr
+{
+    mbedtls_x509_buf raw;           /**< The raw CSR data (DER). */
+    mbedtls_x509_buf cri;           /**< The raw CertificateRequestInfo body (DER). */
+
+    int version;            /**< CSR version (1=v1). */
+
+    mbedtls_x509_buf  subject_raw;  /**< The raw subject data (DER). */
+    mbedtls_x509_name subject;      /**< The parsed subject data (named information object). */
+
+    mbedtls_pk_context pk;          /**< Container for the public key context. */
+
+    mbedtls_x509_buf sig_oid;
+    mbedtls_x509_buf sig;
+    mbedtls_md_type_t sig_md;       /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */
+    mbedtls_pk_type_t sig_pk;       /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */
+    void *sig_opts;         /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */
+}
+mbedtls_x509_csr;
+
+/**
+ * Container for writing a CSR
+ */
+typedef struct mbedtls_x509write_csr
+{
+    mbedtls_pk_context *key;
+    mbedtls_asn1_named_data *subject;
+    mbedtls_md_type_t md_alg;
+    mbedtls_asn1_named_data *extensions;
+}
+mbedtls_x509write_csr;
+
+#if defined(MBEDTLS_X509_CSR_PARSE_C)
+/**
+ * \brief          Load a Certificate Signing Request (CSR) in DER format
+ *
+ * \note           CSR attributes (if any) are currently silently ignored.
+ *
+ * \param csr      CSR context to fill
+ * \param buf      buffer holding the CRL data
+ * \param buflen   size of the buffer
+ *
+ * \return         0 if successful, or a specific X509 error code
+ */
+int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
+                        const unsigned char *buf, size_t buflen );
+
+/**
+ * \brief          Load a Certificate Signing Request (CSR), DER or PEM format
+ *
+ * \note           See notes for \c mbedtls_x509_csr_parse_der()
+ *
+ * \param csr      CSR context to fill
+ * \param buf      buffer holding the CRL data
+ * \param buflen   size of the buffer
+ *                 (including the terminating null byte for PEM data)
+ *
+ * \return         0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen );
+
+#if defined(MBEDTLS_FS_IO)
+/**
+ * \brief          Load a Certificate Signing Request (CSR)
+ *
+ * \note           See notes for \c mbedtls_x509_csr_parse()
+ *
+ * \param csr      CSR context to fill
+ * \param path     filename to read the CSR from
+ *
+ * \return         0 if successful, or a specific X509 or PEM error code
+ */
+int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path );
+#endif /* MBEDTLS_FS_IO */
+
+/**
+ * \brief          Returns an informational string about the
+ *                 CSR.
+ *
+ * \param buf      Buffer to write to
+ * \param size     Maximum size of buffer
+ * \param prefix   A line prefix
+ * \param csr      The X509 CSR to represent
+ *
+ * \return         The length of the string written (not including the
+ *                 terminated nul byte), or a negative error code.
+ */
+int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
+                   const mbedtls_x509_csr *csr );
+
+/**
+ * \brief          Initialize a CSR
+ *
+ * \param csr      CSR to initialize
+ */
+void mbedtls_x509_csr_init( mbedtls_x509_csr *csr );
+
+/**
+ * \brief          Unallocate all CSR data
+ *
+ * \param csr      CSR to free
+ */
+void mbedtls_x509_csr_free( mbedtls_x509_csr *csr );
+#endif /* MBEDTLS_X509_CSR_PARSE_C */
+
+/* \} name */
+/* \} addtogroup x509_module */
+
+#if defined(MBEDTLS_X509_CSR_WRITE_C)
+/**
+ * \brief           Initialize a CSR context
+ *
+ * \param ctx       CSR context to initialize
+ */
+void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx );
+
+/**
+ * \brief           Set the subject name for a CSR
+ *                  Subject names should contain a comma-separated list
+ *                  of OID types and values:
+ *                  e.g. "C=UK,O=ARM,CN=mbed TLS Server 1"
+ *
+ * \param ctx           CSR context to use
+ * \param subject_name  subject name to set
+ *
+ * \return          0 if subject name was parsed successfully, or
+ *                  a specific error code
+ */
+int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx,
+                                    const char *subject_name );
+
+/**
+ * \brief           Set the key for a CSR (public key will be included,
+ *                  private key used to sign the CSR when writing it)
+ *
+ * \param ctx       CSR context to use
+ * \param key       Asymetric key to include
+ */
+void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key );
+
+/**
+ * \brief           Set the MD algorithm to use for the signature
+ *                  (e.g. MBEDTLS_MD_SHA1)
+ *
+ * \param ctx       CSR context to use
+ * \param md_alg    MD algorithm to use
+ */
+void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg );
+
+/**
+ * \brief           Set the Key Usage Extension flags
+ *                  (e.g. MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN)
+ *
+ * \param ctx       CSR context to use
+ * \param key_usage key usage flags to set
+ *
+ * \return          0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED
+ *
+ * \note            The <code>decipherOnly</code> flag from the Key Usage
+ *                  extension is represented by bit 8 (i.e.
+ *                  <code>0x8000</code>), which cannot typically be represented
+ *                  in an unsigned char. Therefore, the flag
+ *                  <code>decipherOnly</code> (i.e.
+ *                  #MBEDTLS_X509_KU_DECIPHER_ONLY) cannot be set using this
+ *                  function.
+ */
+int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage );
+
+/**
+ * \brief           Set the Netscape Cert Type flags
+ *                  (e.g. MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT | MBEDTLS_X509_NS_CERT_TYPE_EMAIL)
+ *
+ * \param ctx           CSR context to use
+ * \param ns_cert_type  Netscape Cert Type flags to set
+ *
+ * \return          0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
+                                    unsigned char ns_cert_type );
+
+/**
+ * \brief           Generic function to add to or replace an extension in the
+ *                  CSR
+ *
+ * \param ctx       CSR context to use
+ * \param oid       OID of the extension
+ * \param oid_len   length of the OID
+ * \param val       value of the extension OCTET STRING
+ * \param val_len   length of the value data
+ *
+ * \return          0 if successful, or a MBEDTLS_ERR_X509_ALLOC_FAILED
+ */
+int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
+                                 const char *oid, size_t oid_len,
+                                 const unsigned char *val, size_t val_len );
+
+/**
+ * \brief           Free the contents of a CSR context
+ *
+ * \param ctx       CSR context to free
+ */
+void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx );
+
+/**
+ * \brief           Write a CSR (Certificate Signing Request) to a
+ *                  DER structure
+ *                  Note: data is written at the end of the buffer! Use the
+ *                        return value to determine where you should start
+ *                        using the buffer
+ *
+ * \param ctx       CSR to write away
+ * \param buf       buffer to write to
+ * \param size      size of the buffer
+ * \param f_rng     RNG function (for signature, see note)
+ * \param p_rng     RNG parameter
+ *
+ * \return          length of data written if successful, or a specific
+ *                  error code
+ *
+ * \note            f_rng may be NULL if RSA is used for signature and the
+ *                  signature is made offline (otherwise f_rng is desirable
+ *                  for countermeasures against timing attacks).
+ *                  ECDSA signatures always require a non-NULL f_rng.
+ */
+int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng );
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+/**
+ * \brief           Write a CSR (Certificate Signing Request) to a
+ *                  PEM string
+ *
+ * \param ctx       CSR to write away
+ * \param buf       buffer to write to
+ * \param size      size of the buffer
+ * \param f_rng     RNG function (for signature, see note)
+ * \param p_rng     RNG parameter
+ *
+ * \return          0 if successful, or a specific error code
+ *
+ * \note            f_rng may be NULL if RSA is used for signature and the
+ *                  signature is made offline (otherwise f_rng is desirable
+ *                  for countermeasures against timing attacks).
+ *                  ECDSA signatures always require a non-NULL f_rng.
+ */
+int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng );
+#endif /* MBEDTLS_PEM_WRITE_C */
+#endif /* MBEDTLS_X509_CSR_WRITE_C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* mbedtls_x509_csr.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/xtea.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/xtea.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/include/mbedtls/xtea.h	(revision 398)
@@ -0,0 +1,139 @@
+/**
+ * \file xtea.h
+ *
+ * \brief XTEA block cipher (32-bit)
+ */
+/*
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#ifndef MBEDTLS_XTEA_H
+#define MBEDTLS_XTEA_H
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MBEDTLS_XTEA_ENCRYPT     1
+#define MBEDTLS_XTEA_DECRYPT     0
+
+#define MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH             -0x0028  /**< The data input has an invalid length. */
+
+/* MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED is deprecated and should not be used. */
+#define MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED                  -0x0029  /**< XTEA hardware accelerator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MBEDTLS_XTEA_ALT)
+// Regular implementation
+//
+
+/**
+ * \brief          XTEA context structure
+ */
+typedef struct mbedtls_xtea_context
+{
+    uint32_t k[4];       /*!< key */
+}
+mbedtls_xtea_context;
+
+#else  /* MBEDTLS_XTEA_ALT */
+#include "xtea_alt.h"
+#endif /* MBEDTLS_XTEA_ALT */
+
+/**
+ * \brief          Initialize XTEA context
+ *
+ * \param ctx      XTEA context to be initialized
+ */
+void mbedtls_xtea_init( mbedtls_xtea_context *ctx );
+
+/**
+ * \brief          Clear XTEA context
+ *
+ * \param ctx      XTEA context to be cleared
+ */
+void mbedtls_xtea_free( mbedtls_xtea_context *ctx );
+
+/**
+ * \brief          XTEA key schedule
+ *
+ * \param ctx      XTEA context to be initialized
+ * \param key      the secret key
+ */
+void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] );
+
+/**
+ * \brief          XTEA cipher function
+ *
+ * \param ctx      XTEA context
+ * \param mode     MBEDTLS_XTEA_ENCRYPT or MBEDTLS_XTEA_DECRYPT
+ * \param input    8-byte input block
+ * \param output   8-byte output block
+ *
+ * \return         0 if successful
+ */
+int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx,
+                    int mode,
+                    const unsigned char input[8],
+                    unsigned char output[8] );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/**
+ * \brief          XTEA CBC cipher function
+ *
+ * \param ctx      XTEA context
+ * \param mode     MBEDTLS_XTEA_ENCRYPT or MBEDTLS_XTEA_DECRYPT
+ * \param length   the length of input, multiple of 8
+ * \param iv       initialization vector for CBC mode
+ * \param input    input block
+ * \param output   output block
+ *
+ * \return         0 if successful,
+ *                 MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH if the length % 8 != 0
+ */
+int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[8],
+                    const unsigned char *input,
+                    unsigned char *output);
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int mbedtls_xtea_self_test( int verbose );
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* xtea.h */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/aes.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/aes.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/aes.c	(revision 398)
@@ -0,0 +1,2207 @@
+/*
+ *  FIPS-197 compliant AES implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
+ *
+ *  http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
+ *  http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_AES_C)
+
+#include <string.h>
+
+#include "mbedtls/aes.h"
+#include "mbedtls/platform.h"
+#include "mbedtls/platform_util.h"
+#if defined(MBEDTLS_PADLOCK_C)
+#include "mbedtls/padlock.h"
+#endif
+#if defined(MBEDTLS_AESNI_C)
+#include "mbedtls/aesni.h"
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_AES_ALT)
+
+/* Parameter validation macros based on platform_util.h */
+#define AES_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
+#define AES_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT32_LE
+#define GET_UINT32_LE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ]       )             \
+        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
+}
+#endif
+
+#ifndef PUT_UINT32_LE
+#define PUT_UINT32_LE(n,b,i)                                    \
+{                                                               \
+    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
+    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
+    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
+    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
+}
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) &&                      \
+    ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
+static int aes_padlock_ace = -1;
+#endif
+
+#if defined(MBEDTLS_AES_ROM_TABLES)
+/*
+ * Forward S-box
+ */
+static const unsigned char FSb[256] =
+{
+    0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
+    0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+    0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+    0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+    0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
+    0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+    0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
+    0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+    0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+    0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+    0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
+    0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+    0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
+    0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+    0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+    0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+    0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
+    0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+    0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
+    0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+    0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+    0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+    0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
+    0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+    0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
+    0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+    0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+    0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+    0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
+    0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+    0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
+    0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+};
+
+/*
+ * Forward tables
+ */
+#define FT \
+\
+    V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
+    V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
+    V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
+    V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
+    V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
+    V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
+    V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
+    V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
+    V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
+    V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
+    V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
+    V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
+    V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
+    V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
+    V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
+    V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
+    V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
+    V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
+    V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
+    V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
+    V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
+    V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
+    V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
+    V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
+    V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
+    V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
+    V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
+    V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
+    V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
+    V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
+    V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
+    V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
+    V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
+    V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
+    V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
+    V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
+    V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
+    V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
+    V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
+    V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
+    V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
+    V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
+    V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
+    V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
+    V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
+    V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
+    V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
+    V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
+    V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
+    V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
+    V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
+    V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
+    V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
+    V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
+    V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
+    V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
+    V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
+    V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
+    V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
+    V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
+    V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
+    V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
+    V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
+    V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static const uint32_t FT0[256] = { FT };
+#undef V
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static const uint32_t FT1[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static const uint32_t FT2[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static const uint32_t FT3[256] = { FT };
+#undef V
+
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+#undef FT
+
+/*
+ * Reverse S-box
+ */
+static const unsigned char RSb[256] =
+{
+    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
+    0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+    0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
+    0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
+    0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+    0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
+    0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
+    0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+    0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
+    0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
+    0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+    0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
+    0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
+    0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+    0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
+    0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
+    0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+};
+
+/*
+ * Reverse tables
+ */
+#define RT \
+\
+    V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
+    V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
+    V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
+    V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
+    V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
+    V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
+    V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
+    V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
+    V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
+    V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
+    V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
+    V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
+    V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
+    V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
+    V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
+    V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
+    V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
+    V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
+    V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
+    V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
+    V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
+    V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
+    V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
+    V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
+    V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
+    V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
+    V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
+    V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
+    V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
+    V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
+    V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
+    V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
+    V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
+    V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
+    V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
+    V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
+    V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
+    V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
+    V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
+    V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
+    V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
+    V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
+    V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
+    V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
+    V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
+    V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
+    V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
+    V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
+    V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
+    V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
+    V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
+    V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
+    V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
+    V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
+    V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
+    V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
+    V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
+    V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
+    V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
+    V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
+    V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
+    V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
+    V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
+    V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static const uint32_t RT0[256] = { RT };
+#undef V
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static const uint32_t RT1[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static const uint32_t RT2[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static const uint32_t RT3[256] = { RT };
+#undef V
+
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+#undef RT
+
+/*
+ * Round constants
+ */
+static const uint32_t RCON[10] =
+{
+    0x00000001, 0x00000002, 0x00000004, 0x00000008,
+    0x00000010, 0x00000020, 0x00000040, 0x00000080,
+    0x0000001B, 0x00000036
+};
+
+#else /* MBEDTLS_AES_ROM_TABLES */
+
+/*
+ * Forward S-box & tables
+ */
+static unsigned char FSb[256];
+static uint32_t FT0[256];
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+static uint32_t FT1[256];
+static uint32_t FT2[256];
+static uint32_t FT3[256];
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+/*
+ * Reverse S-box & tables
+ */
+static unsigned char RSb[256];
+static uint32_t RT0[256];
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+static uint32_t RT1[256];
+static uint32_t RT2[256];
+static uint32_t RT3[256];
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+/*
+ * Round constants
+ */
+static uint32_t RCON[10];
+
+/*
+ * Tables generation code
+ */
+#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
+#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
+#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
+
+static int aes_init_done = 0;
+
+static void aes_gen_tables( void )
+{
+    int i, x, y, z;
+    int pow[256];
+    int log[256];
+
+    /*
+     * compute pow and log tables over GF(2^8)
+     */
+    for( i = 0, x = 1; i < 256; i++ )
+    {
+        pow[i] = x;
+        log[x] = i;
+        x = ( x ^ XTIME( x ) ) & 0xFF;
+    }
+
+    /*
+     * calculate the round constants
+     */
+    for( i = 0, x = 1; i < 10; i++ )
+    {
+        RCON[i] = (uint32_t) x;
+        x = XTIME( x ) & 0xFF;
+    }
+
+    /*
+     * generate the forward and reverse S-boxes
+     */
+    FSb[0x00] = 0x63;
+    RSb[0x63] = 0x00;
+
+    for( i = 1; i < 256; i++ )
+    {
+        x = pow[255 - log[i]];
+
+        y  = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+        x ^= y ^ 0x63;
+
+        FSb[i] = (unsigned char) x;
+        RSb[x] = (unsigned char) i;
+    }
+
+    /*
+     * generate the forward and reverse tables
+     */
+    for( i = 0; i < 256; i++ )
+    {
+        x = FSb[i];
+        y = XTIME( x ) & 0xFF;
+        z =  ( y ^ x ) & 0xFF;
+
+        FT0[i] = ( (uint32_t) y       ) ^
+                 ( (uint32_t) x <<  8 ) ^
+                 ( (uint32_t) x << 16 ) ^
+                 ( (uint32_t) z << 24 );
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+        FT1[i] = ROTL8( FT0[i] );
+        FT2[i] = ROTL8( FT1[i] );
+        FT3[i] = ROTL8( FT2[i] );
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+
+        x = RSb[i];
+
+        RT0[i] = ( (uint32_t) MUL( 0x0E, x )       ) ^
+                 ( (uint32_t) MUL( 0x09, x ) <<  8 ) ^
+                 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
+                 ( (uint32_t) MUL( 0x0B, x ) << 24 );
+
+#if !defined(MBEDTLS_AES_FEWER_TABLES)
+        RT1[i] = ROTL8( RT0[i] );
+        RT2[i] = ROTL8( RT1[i] );
+        RT3[i] = ROTL8( RT2[i] );
+#endif /* !MBEDTLS_AES_FEWER_TABLES */
+    }
+}
+
+#undef ROTL8
+
+#endif /* MBEDTLS_AES_ROM_TABLES */
+
+#if defined(MBEDTLS_AES_FEWER_TABLES)
+
+#define ROTL8(x)  ( (uint32_t)( ( x ) <<  8 ) + (uint32_t)( ( x ) >> 24 ) )
+#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
+#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >>  8 ) )
+
+#define AES_RT0(idx) RT0[idx]
+#define AES_RT1(idx) ROTL8(  RT0[idx] )
+#define AES_RT2(idx) ROTL16( RT0[idx] )
+#define AES_RT3(idx) ROTL24( RT0[idx] )
+
+#define AES_FT0(idx) FT0[idx]
+#define AES_FT1(idx) ROTL8(  FT0[idx] )
+#define AES_FT2(idx) ROTL16( FT0[idx] )
+#define AES_FT3(idx) ROTL24( FT0[idx] )
+
+#else /* MBEDTLS_AES_FEWER_TABLES */
+
+#define AES_RT0(idx) RT0[idx]
+#define AES_RT1(idx) RT1[idx]
+#define AES_RT2(idx) RT2[idx]
+#define AES_RT3(idx) RT3[idx]
+
+#define AES_FT0(idx) FT0[idx]
+#define AES_FT1(idx) FT1[idx]
+#define AES_FT2(idx) FT2[idx]
+#define AES_FT3(idx) FT3[idx]
+
+#endif /* MBEDTLS_AES_FEWER_TABLES */
+
+void mbedtls_aes_init( mbedtls_aes_context *ctx )
+{
+    AES_VALIDATE( ctx != NULL );
+
+    memset( ctx, 0, sizeof( mbedtls_aes_context ) );
+}
+
+void mbedtls_aes_free( mbedtls_aes_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
+{
+    AES_VALIDATE( ctx != NULL );
+
+    mbedtls_aes_init( &ctx->crypt );
+    mbedtls_aes_init( &ctx->tweak );
+}
+
+void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_aes_free( &ctx->crypt );
+    mbedtls_aes_free( &ctx->tweak );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+/*
+ * AES key schedule (encryption)
+ */
+#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
+int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
+                    unsigned int keybits )
+{
+    unsigned int i;
+    uint32_t *RK;
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( key != NULL );
+
+    switch( keybits )
+    {
+        case 128: ctx->nr = 10; break;
+        case 192: ctx->nr = 12; break;
+        case 256: ctx->nr = 14; break;
+        default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
+    }
+
+#if !defined(MBEDTLS_AES_ROM_TABLES)
+    if( aes_init_done == 0 )
+    {
+        aes_gen_tables();
+        aes_init_done = 1;
+    }
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
+    if( aes_padlock_ace == -1 )
+        aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
+
+    if( aes_padlock_ace )
+        ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
+    else
+#endif
+    ctx->rk = RK = ctx->buf;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+        return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
+#endif
+
+    for( i = 0; i < ( keybits >> 5 ); i++ )
+    {
+        GET_UINT32_LE( RK[i], key, i << 2 );
+    }
+
+    switch( ctx->nr )
+    {
+        case 10:
+
+            for( i = 0; i < 10; i++, RK += 4 )
+            {
+                RK[4]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[3] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[3]       ) & 0xFF ] << 24 );
+
+                RK[5]  = RK[1] ^ RK[4];
+                RK[6]  = RK[2] ^ RK[5];
+                RK[7]  = RK[3] ^ RK[6];
+            }
+            break;
+
+        case 12:
+
+            for( i = 0; i < 8; i++, RK += 6 )
+            {
+                RK[6]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[5] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[5]       ) & 0xFF ] << 24 );
+
+                RK[7]  = RK[1] ^ RK[6];
+                RK[8]  = RK[2] ^ RK[7];
+                RK[9]  = RK[3] ^ RK[8];
+                RK[10] = RK[4] ^ RK[9];
+                RK[11] = RK[5] ^ RK[10];
+            }
+            break;
+
+        case 14:
+
+            for( i = 0; i < 7; i++, RK += 8 )
+            {
+                RK[8]  = RK[0] ^ RCON[i] ^
+                ( (uint32_t) FSb[ ( RK[7] >>  8 ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[7]       ) & 0xFF ] << 24 );
+
+                RK[9]  = RK[1] ^ RK[8];
+                RK[10] = RK[2] ^ RK[9];
+                RK[11] = RK[3] ^ RK[10];
+
+                RK[12] = RK[4] ^
+                ( (uint32_t) FSb[ ( RK[11]       ) & 0xFF ]       ) ^
+                ( (uint32_t) FSb[ ( RK[11] >>  8 ) & 0xFF ] <<  8 ) ^
+                ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
+                ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
+
+                RK[13] = RK[5] ^ RK[12];
+                RK[14] = RK[6] ^ RK[13];
+                RK[15] = RK[7] ^ RK[14];
+            }
+            break;
+    }
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
+
+/*
+ * AES key schedule (decryption)
+ */
+#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
+int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
+                    unsigned int keybits )
+{
+    int i, j, ret;
+    mbedtls_aes_context cty;
+    uint32_t *RK;
+    uint32_t *SK;
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( key != NULL );
+
+    mbedtls_aes_init( &cty );
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
+    if( aes_padlock_ace == -1 )
+        aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
+
+    if( aes_padlock_ace )
+        ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
+    else
+#endif
+    ctx->rk = RK = ctx->buf;
+
+    /* Also checks keybits */
+    if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
+        goto exit;
+
+    ctx->nr = cty.nr;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+    {
+        mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
+                           (const unsigned char *) cty.rk, ctx->nr );
+        goto exit;
+    }
+#endif
+
+    SK = cty.rk + cty.nr * 4;
+
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+
+    for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
+    {
+        for( j = 0; j < 4; j++, SK++ )
+        {
+            *RK++ = AES_RT0( FSb[ ( *SK       ) & 0xFF ] ) ^
+                    AES_RT1( FSb[ ( *SK >>  8 ) & 0xFF ] ) ^
+                    AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
+                    AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
+        }
+    }
+
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+
+exit:
+    mbedtls_aes_free( &cty );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
+                                        unsigned int keybits,
+                                        const unsigned char **key1,
+                                        unsigned int *key1bits,
+                                        const unsigned char **key2,
+                                        unsigned int *key2bits )
+{
+    const unsigned int half_keybits = keybits / 2;
+    const unsigned int half_keybytes = half_keybits / 8;
+
+    switch( keybits )
+    {
+        case 256: break;
+        case 512: break;
+        default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
+    }
+
+    *key1bits = half_keybits;
+    *key2bits = half_keybits;
+    *key1 = &key[0];
+    *key2 = &key[half_keybytes];
+
+    return 0;
+}
+
+int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits)
+{
+    int ret;
+    const unsigned char *key1, *key2;
+    unsigned int key1bits, key2bits;
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( key != NULL );
+
+    ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
+                                       &key2, &key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set the tweak key. Always set tweak key for the encryption mode. */
+    ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set crypt key for encryption. */
+    return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
+}
+
+int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits)
+{
+    int ret;
+    const unsigned char *key1, *key2;
+    unsigned int key1bits, key2bits;
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( key != NULL );
+
+    ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
+                                       &key2, &key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set the tweak key. Always set tweak key for encryption. */
+    ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
+    if( ret != 0 )
+        return( ret );
+
+    /* Set crypt key for decryption. */
+    return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
+
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)         \
+{                                                   \
+    X0 = *RK++ ^ AES_FT0( ( Y0       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y1 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y2 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y3 >> 24 ) & 0xFF );    \
+                                                    \
+    X1 = *RK++ ^ AES_FT0( ( Y1       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y2 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y3 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y0 >> 24 ) & 0xFF );    \
+                                                    \
+    X2 = *RK++ ^ AES_FT0( ( Y2       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y3 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y0 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y1 >> 24 ) & 0xFF );    \
+                                                    \
+    X3 = *RK++ ^ AES_FT0( ( Y3       ) & 0xFF ) ^   \
+                 AES_FT1( ( Y0 >>  8 ) & 0xFF ) ^   \
+                 AES_FT2( ( Y1 >> 16 ) & 0xFF ) ^   \
+                 AES_FT3( ( Y2 >> 24 ) & 0xFF );    \
+}
+
+#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)         \
+{                                                   \
+    X0 = *RK++ ^ AES_RT0( ( Y0       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y3 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y2 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y1 >> 24 ) & 0xFF );    \
+                                                    \
+    X1 = *RK++ ^ AES_RT0( ( Y1       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y0 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y3 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y2 >> 24 ) & 0xFF );    \
+                                                    \
+    X2 = *RK++ ^ AES_RT0( ( Y2       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y1 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y0 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y3 >> 24 ) & 0xFF );    \
+                                                    \
+    X3 = *RK++ ^ AES_RT0( ( Y3       ) & 0xFF ) ^   \
+                 AES_RT1( ( Y2 >>  8 ) & 0xFF ) ^   \
+                 AES_RT2( ( Y1 >> 16 ) & 0xFF ) ^   \
+                 AES_RT3( ( Y0 >> 24 ) & 0xFF );    \
+}
+
+/*
+ * AES-ECB block encryption
+ */
+#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
+int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
+                                  const unsigned char input[16],
+                                  unsigned char output[16] )
+{
+    int i;
+    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+    RK = ctx->rk;
+
+    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;
+    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;
+    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;
+    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+
+    for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
+    {
+        AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+        AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+    }
+
+    AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+    X0 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y0       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+    X1 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y1       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+
+    X2 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y2       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+    X3 = *RK++ ^ \
+            ( (uint32_t) FSb[ ( Y3       ) & 0xFF ]       ) ^
+            ( (uint32_t) FSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+    PUT_UINT32_LE( X0, output,  0 );
+    PUT_UINT32_LE( X1, output,  4 );
+    PUT_UINT32_LE( X2, output,  8 );
+    PUT_UINT32_LE( X3, output, 12 );
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
+                          const unsigned char input[16],
+                          unsigned char output[16] )
+{
+    mbedtls_internal_aes_encrypt( ctx, input, output );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * AES-ECB block decryption
+ */
+#if !defined(MBEDTLS_AES_DECRYPT_ALT)
+int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
+                                  const unsigned char input[16],
+                                  unsigned char output[16] )
+{
+    int i;
+    uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+    RK = ctx->rk;
+
+    GET_UINT32_LE( X0, input,  0 ); X0 ^= *RK++;
+    GET_UINT32_LE( X1, input,  4 ); X1 ^= *RK++;
+    GET_UINT32_LE( X2, input,  8 ); X2 ^= *RK++;
+    GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+
+    for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
+    {
+        AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+        AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+    }
+
+    AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+    X0 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y0       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y3 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+    X1 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y1       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y0 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+    X2 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y2       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y1 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+    X3 = *RK++ ^ \
+            ( (uint32_t) RSb[ ( Y3       ) & 0xFF ]       ) ^
+            ( (uint32_t) RSb[ ( Y2 >>  8 ) & 0xFF ] <<  8 ) ^
+            ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+            ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+
+    PUT_UINT32_LE( X0, output,  0 );
+    PUT_UINT32_LE( X1, output,  4 );
+    PUT_UINT32_LE( X2, output,  8 );
+    PUT_UINT32_LE( X3, output, 12 );
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_AES_DECRYPT_ALT */
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
+                          const unsigned char input[16],
+                          unsigned char output[16] )
+{
+    mbedtls_internal_aes_decrypt( ctx, input, output );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * AES-ECB block encryption/decryption
+ */
+int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
+                           int mode,
+                           const unsigned char input[16],
+                           unsigned char output[16] )
+{
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+    AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+                      mode == MBEDTLS_AES_DECRYPT );
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
+        return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
+    if( aes_padlock_ace )
+    {
+        if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
+            return( 0 );
+
+        // If padlock data misaligned, we just fall back to
+        // unaccelerated mode
+        //
+    }
+#endif
+
+    if( mode == MBEDTLS_AES_ENCRYPT )
+        return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
+    else
+        return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[16],
+                    const unsigned char *input,
+                    unsigned char *output )
+{
+    int i;
+    unsigned char temp[16];
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+                      mode == MBEDTLS_AES_DECRYPT );
+    AES_VALIDATE_RET( iv != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+
+    if( length % 16 )
+        return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
+
+#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
+    if( aes_padlock_ace )
+    {
+        if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
+            return( 0 );
+
+        // If padlock data misaligned, we just fall back to
+        // unaccelerated mode
+        //
+    }
+#endif
+
+    if( mode == MBEDTLS_AES_DECRYPT )
+    {
+        while( length > 0 )
+        {
+            memcpy( temp, input, 16 );
+            mbedtls_aes_crypt_ecb( ctx, mode, input, output );
+
+            for( i = 0; i < 16; i++ )
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+            memcpy( iv, temp, 16 );
+
+            input  += 16;
+            output += 16;
+            length -= 16;
+        }
+    }
+    else
+    {
+        while( length > 0 )
+        {
+            for( i = 0; i < 16; i++ )
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+            mbedtls_aes_crypt_ecb( ctx, mode, output, output );
+            memcpy( iv, output, 16 );
+
+            input  += 16;
+            output += 16;
+            length -= 16;
+        }
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+
+/* Endianess with 64 bits values */
+#ifndef GET_UINT64_LE
+#define GET_UINT64_LE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint64_t) (b)[(i) + 7] << 56 )             \
+        | ( (uint64_t) (b)[(i) + 6] << 48 )             \
+        | ( (uint64_t) (b)[(i) + 5] << 40 )             \
+        | ( (uint64_t) (b)[(i) + 4] << 32 )             \
+        | ( (uint64_t) (b)[(i) + 3] << 24 )             \
+        | ( (uint64_t) (b)[(i) + 2] << 16 )             \
+        | ( (uint64_t) (b)[(i) + 1] <<  8 )             \
+        | ( (uint64_t) (b)[(i)    ]       );            \
+}
+#endif
+
+#ifndef PUT_UINT64_LE
+#define PUT_UINT64_LE(n,b,i)                            \
+{                                                       \
+    (b)[(i) + 7] = (unsigned char) ( (n) >> 56 );       \
+    (b)[(i) + 6] = (unsigned char) ( (n) >> 48 );       \
+    (b)[(i) + 5] = (unsigned char) ( (n) >> 40 );       \
+    (b)[(i) + 4] = (unsigned char) ( (n) >> 32 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i)    ] = (unsigned char) ( (n)       );       \
+}
+#endif
+
+typedef unsigned char mbedtls_be128[16];
+
+/*
+ * GF(2^128) multiplication function
+ *
+ * This function multiplies a field element by x in the polynomial field
+ * representation. It uses 64-bit word operations to gain speed but compensates
+ * for machine endianess and hence works correctly on both big and little
+ * endian machines.
+ */
+static void mbedtls_gf128mul_x_ble( unsigned char r[16],
+                                    const unsigned char x[16] )
+{
+    uint64_t a, b, ra, rb;
+
+    GET_UINT64_LE( a, x, 0 );
+    GET_UINT64_LE( b, x, 8 );
+
+    ra = ( a << 1 )  ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
+    rb = ( a >> 63 ) | ( b << 1 );
+
+    PUT_UINT64_LE( ra, r, 0 );
+    PUT_UINT64_LE( rb, r, 8 );
+}
+
+/*
+ * AES-XTS buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
+                           int mode,
+                           size_t length,
+                           const unsigned char data_unit[16],
+                           const unsigned char *input,
+                           unsigned char *output )
+{
+    int ret;
+    size_t blocks = length / 16;
+    size_t leftover = length % 16;
+    unsigned char tweak[16];
+    unsigned char prev_tweak[16];
+    unsigned char tmp[16];
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+                      mode == MBEDTLS_AES_DECRYPT );
+    AES_VALIDATE_RET( data_unit != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+
+    /* Data units must be at least 16 bytes long. */
+    if( length < 16 )
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+
+    /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
+    if( length > ( 1 << 20 ) * 16 )
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+
+    /* Compute the tweak. */
+    ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
+                                 data_unit, tweak );
+    if( ret != 0 )
+        return( ret );
+
+    while( blocks-- )
+    {
+        size_t i;
+
+        if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
+        {
+            /* We are on the last block in a decrypt operation that has
+             * leftover bytes, so we need to use the next tweak for this block,
+             * and this tweak for the lefover bytes. Save the current tweak for
+             * the leftovers and then update the current tweak for use on this,
+             * the last full block. */
+            memcpy( prev_tweak, tweak, sizeof( tweak ) );
+            mbedtls_gf128mul_x_ble( tweak, tweak );
+        }
+
+        for( i = 0; i < 16; i++ )
+            tmp[i] = input[i] ^ tweak[i];
+
+        ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
+        if( ret != 0 )
+            return( ret );
+
+        for( i = 0; i < 16; i++ )
+            output[i] = tmp[i] ^ tweak[i];
+
+        /* Update the tweak for the next block. */
+        mbedtls_gf128mul_x_ble( tweak, tweak );
+
+        output += 16;
+        input += 16;
+    }
+
+    if( leftover )
+    {
+        /* If we are on the leftover bytes in a decrypt operation, we need to
+         * use the previous tweak for these bytes (as saved in prev_tweak). */
+        unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
+
+        /* We are now on the final part of the data unit, which doesn't divide
+         * evenly by 16. It's time for ciphertext stealing. */
+        size_t i;
+        unsigned char *prev_output = output - 16;
+
+        /* Copy ciphertext bytes from the previous block to our output for each
+         * byte of cyphertext we won't steal. At the same time, copy the
+         * remainder of the input for this final round (since the loop bounds
+         * are the same). */
+        for( i = 0; i < leftover; i++ )
+        {
+            output[i] = prev_output[i];
+            tmp[i] = input[i] ^ t[i];
+        }
+
+        /* Copy ciphertext bytes from the previous block for input in this
+         * round. */
+        for( ; i < 16; i++ )
+            tmp[i] = prev_output[i] ^ t[i];
+
+        ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
+        if( ret != 0 )
+            return ret;
+
+        /* Write the result back to the previous block, overriding the previous
+         * output we copied. */
+        for( i = 0; i < 16; i++ )
+            prev_output[i] = tmp[i] ^ t[i];
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * AES-CFB128 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c;
+    size_t n;
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+                      mode == MBEDTLS_AES_DECRYPT );
+    AES_VALIDATE_RET( iv_off != NULL );
+    AES_VALIDATE_RET( iv != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+
+    n = *iv_off;
+
+    if( n > 15 )
+        return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+
+    if( mode == MBEDTLS_AES_DECRYPT )
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+            c = *input++;
+            *output++ = (unsigned char)( c ^ iv[n] );
+            iv[n] = (unsigned char) c;
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+    else
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+            iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+
+    *iv_off = n;
+
+    return( 0 );
+}
+
+/*
+ * AES-CFB8 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
+                            int mode,
+                            size_t length,
+                            unsigned char iv[16],
+                            const unsigned char *input,
+                            unsigned char *output )
+{
+    unsigned char c;
+    unsigned char ov[17];
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
+                      mode == MBEDTLS_AES_DECRYPT );
+    AES_VALIDATE_RET( iv != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+    while( length-- )
+    {
+        memcpy( ov, iv, 16 );
+        mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+
+        if( mode == MBEDTLS_AES_DECRYPT )
+            ov[16] = *input;
+
+        c = *output++ = (unsigned char)( iv[0] ^ *input++ );
+
+        if( mode == MBEDTLS_AES_ENCRYPT )
+            ov[16] = c;
+
+        memcpy( iv, ov + 1, 16 );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/*
+ * AES-OFB (Output Feedback Mode) buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
+                           size_t length,
+                           size_t *iv_off,
+                           unsigned char iv[16],
+                           const unsigned char *input,
+                           unsigned char *output )
+{
+    int ret = 0;
+    size_t n;
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( iv_off != NULL );
+    AES_VALIDATE_RET( iv != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+
+    n = *iv_off;
+
+    if( n > 15 )
+        return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+
+    while( length-- )
+    {
+        if( n == 0 )
+        {
+            ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
+            if( ret != 0 )
+                goto exit;
+        }
+        *output++ =  *input++ ^ iv[n];
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *iv_off = n;
+
+exit:
+    return( ret );
+}
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
+                       size_t length,
+                       size_t *nc_off,
+                       unsigned char nonce_counter[16],
+                       unsigned char stream_block[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c, i;
+    size_t n;
+
+    AES_VALIDATE_RET( ctx != NULL );
+    AES_VALIDATE_RET( nc_off != NULL );
+    AES_VALIDATE_RET( nonce_counter != NULL );
+    AES_VALIDATE_RET( stream_block != NULL );
+    AES_VALIDATE_RET( input != NULL );
+    AES_VALIDATE_RET( output != NULL );
+
+    n = *nc_off;
+
+    if ( n > 0x0F )
+        return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
+
+    while( length-- )
+    {
+        if( n == 0 ) {
+            mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
+
+            for( i = 16; i > 0; i-- )
+                if( ++nonce_counter[i - 1] != 0 )
+                    break;
+        }
+        c = *input++;
+        *output++ = (unsigned char)( c ^ stream_block[n] );
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *nc_off = n;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#endif /* !MBEDTLS_AES_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+/*
+ * AES test vectors from:
+ *
+ * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
+ */
+static const unsigned char aes_test_ecb_dec[3][16] =
+{
+    { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
+      0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
+    { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
+      0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
+    { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
+      0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
+};
+
+static const unsigned char aes_test_ecb_enc[3][16] =
+{
+    { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
+      0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
+    { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
+      0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
+    { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
+      0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const unsigned char aes_test_cbc_dec[3][16] =
+{
+    { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
+      0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
+    { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
+      0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
+    { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
+      0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
+};
+
+static const unsigned char aes_test_cbc_enc[3][16] =
+{
+    { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
+      0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
+    { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
+      0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
+    { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
+      0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * AES-CFB128 test vectors from:
+ *
+ * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ */
+static const unsigned char aes_test_cfb128_key[3][32] =
+{
+    { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
+      0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
+    { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
+      0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
+      0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
+    { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
+      0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
+      0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
+      0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
+};
+
+static const unsigned char aes_test_cfb128_iv[16] =
+{
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+};
+
+static const unsigned char aes_test_cfb128_pt[64] =
+{
+    0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
+    0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
+    0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
+    0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
+    0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
+    0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
+    0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
+    0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
+};
+
+static const unsigned char aes_test_cfb128_ct[3][64] =
+{
+    { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
+      0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
+      0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
+      0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
+      0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
+      0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
+      0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
+      0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
+    { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
+      0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
+      0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
+      0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
+      0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
+      0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
+      0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
+      0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
+    { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
+      0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
+      0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
+      0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
+      0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
+      0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
+      0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
+      0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/*
+ * AES-OFB test vectors from:
+ *
+ * https://csrc.nist.gov/publications/detail/sp/800-38a/final
+ */
+static const unsigned char aes_test_ofb_key[3][32] =
+{
+    { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
+      0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
+    { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
+      0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
+      0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
+    { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
+      0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
+      0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
+      0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
+};
+
+static const unsigned char aes_test_ofb_iv[16] =
+{
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+};
+
+static const unsigned char aes_test_ofb_pt[64] =
+{
+    0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
+    0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
+    0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
+    0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
+    0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
+    0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
+    0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
+    0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
+};
+
+static const unsigned char aes_test_ofb_ct[3][64] =
+{
+    { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
+      0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
+      0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
+      0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
+      0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
+      0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
+      0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
+      0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
+    { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
+      0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
+      0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
+      0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
+      0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
+      0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
+      0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
+      0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
+    { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
+      0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
+      0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
+      0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
+      0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
+      0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
+      0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
+      0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR test vectors from:
+ *
+ * http://www.faqs.org/rfcs/rfc3686.html
+ */
+
+static const unsigned char aes_test_ctr_key[3][16] =
+{
+    { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
+      0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
+    { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
+      0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
+    { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
+      0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
+};
+
+static const unsigned char aes_test_ctr_nonce_counter[3][16] =
+{
+    { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
+    { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
+      0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
+    { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
+      0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
+};
+
+static const unsigned char aes_test_ctr_pt[3][48] =
+{
+    { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
+      0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
+
+    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+      0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+      0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+      0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
+
+    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+      0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+      0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+      0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+      0x20, 0x21, 0x22, 0x23 }
+};
+
+static const unsigned char aes_test_ctr_ct[3][48] =
+{
+    { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
+      0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
+    { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
+      0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
+      0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
+      0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
+    { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
+      0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
+      0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
+      0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
+      0x25, 0xB2, 0x07, 0x2F }
+};
+
+static const int aes_test_ctr_len[3] =
+    { 16, 32, 36 };
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/*
+ * AES-XTS test vectors from:
+ *
+ * IEEE P1619/D16 Annex B
+ * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
+ * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
+ */
+static const unsigned char aes_test_xts_key[][32] =
+{
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+    { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+      0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+      0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+      0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
+    { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
+      0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+      0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+      0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
+};
+
+static const unsigned char aes_test_xts_pt32[][32] =
+{
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+    { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+      0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+      0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+      0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
+    { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+      0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+      0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+      0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
+};
+
+static const unsigned char aes_test_xts_ct32[][32] =
+{
+    { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
+      0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
+      0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
+      0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
+    { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
+      0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
+      0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
+      0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
+    { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
+      0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
+      0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
+      0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
+};
+
+static const unsigned char aes_test_xts_data_unit[][16] =
+{
+   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+   { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+   { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+};
+
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+/*
+ * Checkup routine
+ */
+int mbedtls_aes_self_test( int verbose )
+{
+    int ret = 0, i, j, u, mode;
+    unsigned int keybits;
+    unsigned char key[32];
+    unsigned char buf[64];
+    const unsigned char *aes_tests;
+#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
+    unsigned char iv[16];
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    unsigned char prv[16];
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
+    defined(MBEDTLS_CIPHER_MODE_OFB)
+    size_t offset;
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
+    int len;
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    unsigned char nonce_counter[16];
+    unsigned char stream_block[16];
+#endif
+    mbedtls_aes_context ctx;
+
+    memset( key, 0, 32 );
+    mbedtls_aes_init( &ctx );
+
+    /*
+     * ECB mode
+     */
+    for( i = 0; i < 6; i++ )
+    {
+        u = i >> 1;
+        keybits = 128 + u * 64;
+        mode = i & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  AES-ECB-%3d (%s): ", keybits,
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+        memset( buf, 0, 16 );
+
+        if( mode == MBEDTLS_AES_DECRYPT )
+        {
+            ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
+            aes_tests = aes_test_ecb_dec[u];
+        }
+        else
+        {
+            ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+            aes_tests = aes_test_ecb_enc[u];
+        }
+
+        /*
+         * AES-192 is an optional feature that may be unavailable when
+         * there is an alternative underlying implementation i.e. when
+         * MBEDTLS_AES_ALT is defined.
+         */
+        if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
+        {
+            mbedtls_printf( "skipped\n" );
+            continue;
+        }
+        else if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        for( j = 0; j < 10000; j++ )
+        {
+            ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
+            if( ret != 0 )
+                goto exit;
+        }
+
+        if( memcmp( buf, aes_tests, 16 ) != 0 )
+        {
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    /*
+     * CBC mode
+     */
+    for( i = 0; i < 6; i++ )
+    {
+        u = i >> 1;
+        keybits = 128 + u * 64;
+        mode = i & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  AES-CBC-%3d (%s): ", keybits,
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+        memset( iv , 0, 16 );
+        memset( prv, 0, 16 );
+        memset( buf, 0, 16 );
+
+        if( mode == MBEDTLS_AES_DECRYPT )
+        {
+            ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
+            aes_tests = aes_test_cbc_dec[u];
+        }
+        else
+        {
+            ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+            aes_tests = aes_test_cbc_enc[u];
+        }
+
+        /*
+         * AES-192 is an optional feature that may be unavailable when
+         * there is an alternative underlying implementation i.e. when
+         * MBEDTLS_AES_ALT is defined.
+         */
+        if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
+        {
+            mbedtls_printf( "skipped\n" );
+            continue;
+        }
+        else if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        for( j = 0; j < 10000; j++ )
+        {
+            if( mode == MBEDTLS_AES_ENCRYPT )
+            {
+                unsigned char tmp[16];
+
+                memcpy( tmp, prv, 16 );
+                memcpy( prv, buf, 16 );
+                memcpy( buf, tmp, 16 );
+            }
+
+            ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
+            if( ret != 0 )
+                goto exit;
+
+        }
+
+        if( memcmp( buf, aes_tests, 16 ) != 0 )
+        {
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    /*
+     * CFB128 mode
+     */
+    for( i = 0; i < 6; i++ )
+    {
+        u = i >> 1;
+        keybits = 128 + u * 64;
+        mode = i & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  AES-CFB128-%3d (%s): ", keybits,
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+        memcpy( iv,  aes_test_cfb128_iv, 16 );
+        memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
+
+        offset = 0;
+        ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+        /*
+         * AES-192 is an optional feature that may be unavailable when
+         * there is an alternative underlying implementation i.e. when
+         * MBEDTLS_AES_ALT is defined.
+         */
+        if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
+        {
+            mbedtls_printf( "skipped\n" );
+            continue;
+        }
+        else if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        if( mode == MBEDTLS_AES_DECRYPT )
+        {
+            memcpy( buf, aes_test_cfb128_ct[u], 64 );
+            aes_tests = aes_test_cfb128_pt;
+        }
+        else
+        {
+            memcpy( buf, aes_test_cfb128_pt, 64 );
+            aes_tests = aes_test_cfb128_ct[u];
+        }
+
+        ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
+        if( ret != 0 )
+            goto exit;
+
+        if( memcmp( buf, aes_tests, 64 ) != 0 )
+        {
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    /*
+     * OFB mode
+     */
+    for( i = 0; i < 6; i++ )
+    {
+        u = i >> 1;
+        keybits = 128 + u * 64;
+        mode = i & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  AES-OFB-%3d (%s): ", keybits,
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+        memcpy( iv,  aes_test_ofb_iv, 16 );
+        memcpy( key, aes_test_ofb_key[u], keybits / 8 );
+
+        offset = 0;
+        ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
+        /*
+         * AES-192 is an optional feature that may be unavailable when
+         * there is an alternative underlying implementation i.e. when
+         * MBEDTLS_AES_ALT is defined.
+         */
+        if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
+        {
+            mbedtls_printf( "skipped\n" );
+            continue;
+        }
+        else if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        if( mode == MBEDTLS_AES_DECRYPT )
+        {
+            memcpy( buf, aes_test_ofb_ct[u], 64 );
+            aes_tests = aes_test_ofb_pt;
+        }
+        else
+        {
+            memcpy( buf, aes_test_ofb_pt, 64 );
+            aes_tests = aes_test_ofb_ct[u];
+        }
+
+        ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
+        if( ret != 0 )
+            goto exit;
+
+        if( memcmp( buf, aes_tests, 64 ) != 0 )
+        {
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    /*
+     * CTR mode
+     */
+    for( i = 0; i < 6; i++ )
+    {
+        u = i >> 1;
+        mode = i & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  AES-CTR-128 (%s): ",
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+        memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
+        memcpy( key, aes_test_ctr_key[u], 16 );
+
+        offset = 0;
+        if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
+            goto exit;
+
+        len = aes_test_ctr_len[u];
+
+        if( mode == MBEDTLS_AES_DECRYPT )
+        {
+            memcpy( buf, aes_test_ctr_ct[u], len );
+            aes_tests = aes_test_ctr_pt[u];
+        }
+        else
+        {
+            memcpy( buf, aes_test_ctr_pt[u], len );
+            aes_tests = aes_test_ctr_ct[u];
+        }
+
+        ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
+                                     stream_block, buf, buf );
+        if( ret != 0 )
+            goto exit;
+
+        if( memcmp( buf, aes_tests, len ) != 0 )
+        {
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    {
+    static const int num_tests =
+        sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
+    mbedtls_aes_xts_context ctx_xts;
+
+    /*
+     * XTS mode
+     */
+    mbedtls_aes_xts_init( &ctx_xts );
+
+    for( i = 0; i < num_tests << 1; i++ )
+    {
+        const unsigned char *data_unit;
+        u = i >> 1;
+        mode = i & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  AES-XTS-128 (%s): ",
+                            ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
+
+        memset( key, 0, sizeof( key ) );
+        memcpy( key, aes_test_xts_key[u], 32 );
+        data_unit = aes_test_xts_data_unit[u];
+
+        len = sizeof( *aes_test_xts_ct32 );
+
+        if( mode == MBEDTLS_AES_DECRYPT )
+        {
+            ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
+            if( ret != 0)
+                goto exit;
+            memcpy( buf, aes_test_xts_ct32[u], len );
+            aes_tests = aes_test_xts_pt32[u];
+        }
+        else
+        {
+            ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
+            if( ret != 0)
+                goto exit;
+            memcpy( buf, aes_test_xts_pt32[u], len );
+            aes_tests = aes_test_xts_ct32[u];
+        }
+
+
+        ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
+                                     buf, buf );
+        if( ret != 0 )
+            goto exit;
+
+        if( memcmp( buf, aes_tests, len ) != 0 )
+        {
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    mbedtls_aes_xts_free( &ctx_xts );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+    ret = 0;
+
+exit:
+    if( ret != 0 && verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    mbedtls_aes_free( &ctx );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_AES_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/aesni.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/aesni.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/aesni.c	(revision 398)
@@ -0,0 +1,470 @@
+/*
+ *  AES-NI support functions
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set
+ * [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_AESNI_C)
+
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+#warning "MBEDTLS_AESNI_C is known to cause spurious error reports with some memory sanitizers as they do not understand the assembly code."
+#endif
+#endif
+
+#include "mbedtls/aesni.h"
+
+#include <string.h>
+
+#ifndef asm
+#define asm __asm
+#endif
+
+#if defined(MBEDTLS_HAVE_X86_64)
+
+/*
+ * AES-NI support detection routine
+ */
+int mbedtls_aesni_has_support( unsigned int what )
+{
+    static int done = 0;
+    static unsigned int c = 0;
+
+    if( ! done )
+    {
+        asm( "movl  $1, %%eax   \n\t"
+             "cpuid             \n\t"
+             : "=c" (c)
+             :
+             : "eax", "ebx", "edx" );
+        done = 1;
+    }
+
+    return( ( c & what ) != 0 );
+}
+
+/*
+ * Binutils needs to be at least 2.19 to support AES-NI instructions.
+ * Unfortunately, a lot of users have a lower version now (2014-04).
+ * Emit bytecode directly in order to support "old" version of gas.
+ *
+ * Opcodes from the Intel architecture reference manual, vol. 3.
+ * We always use registers, so we don't need prefixes for memory operands.
+ * Operand macros are in gas order (src, dst) as opposed to Intel order
+ * (dst, src) in order to blend better into the surrounding assembly code.
+ */
+#define AESDEC      ".byte 0x66,0x0F,0x38,0xDE,"
+#define AESDECLAST  ".byte 0x66,0x0F,0x38,0xDF,"
+#define AESENC      ".byte 0x66,0x0F,0x38,0xDC,"
+#define AESENCLAST  ".byte 0x66,0x0F,0x38,0xDD,"
+#define AESIMC      ".byte 0x66,0x0F,0x38,0xDB,"
+#define AESKEYGENA  ".byte 0x66,0x0F,0x3A,0xDF,"
+#define PCLMULQDQ   ".byte 0x66,0x0F,0x3A,0x44,"
+
+#define xmm0_xmm0   "0xC0"
+#define xmm0_xmm1   "0xC8"
+#define xmm0_xmm2   "0xD0"
+#define xmm0_xmm3   "0xD8"
+#define xmm0_xmm4   "0xE0"
+#define xmm1_xmm0   "0xC1"
+#define xmm1_xmm2   "0xD1"
+
+/*
+ * AES-NI AES-ECB block en(de)cryption
+ */
+int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
+                     int mode,
+                     const unsigned char input[16],
+                     unsigned char output[16] )
+{
+    asm( "movdqu    (%3), %%xmm0    \n\t" // load input
+         "movdqu    (%1), %%xmm1    \n\t" // load round key 0
+         "pxor      %%xmm1, %%xmm0  \n\t" // round 0
+         "add       $16, %1         \n\t" // point to next round key
+         "subl      $1, %0          \n\t" // normal rounds = nr - 1
+         "test      %2, %2          \n\t" // mode?
+         "jz        2f              \n\t" // 0 = decrypt
+
+         "1:                        \n\t" // encryption loop
+         "movdqu    (%1), %%xmm1    \n\t" // load round key
+         AESENC     xmm1_xmm0      "\n\t" // do round
+         "add       $16, %1         \n\t" // point to next round key
+         "subl      $1, %0          \n\t" // loop
+         "jnz       1b              \n\t"
+         "movdqu    (%1), %%xmm1    \n\t" // load round key
+         AESENCLAST xmm1_xmm0      "\n\t" // last round
+         "jmp       3f              \n\t"
+
+         "2:                        \n\t" // decryption loop
+         "movdqu    (%1), %%xmm1    \n\t"
+         AESDEC     xmm1_xmm0      "\n\t" // do round
+         "add       $16, %1         \n\t"
+         "subl      $1, %0          \n\t"
+         "jnz       2b              \n\t"
+         "movdqu    (%1), %%xmm1    \n\t" // load round key
+         AESDECLAST xmm1_xmm0      "\n\t" // last round
+
+         "3:                        \n\t"
+         "movdqu    %%xmm0, (%4)    \n\t" // export output
+         :
+         : "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output)
+         : "memory", "cc", "xmm0", "xmm1" );
+
+
+    return( 0 );
+}
+
+/*
+ * GCM multiplication: c = a times b in GF(2^128)
+ * Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5.
+ */
+void mbedtls_aesni_gcm_mult( unsigned char c[16],
+                     const unsigned char a[16],
+                     const unsigned char b[16] )
+{
+    unsigned char aa[16], bb[16], cc[16];
+    size_t i;
+
+    /* The inputs are in big-endian order, so byte-reverse them */
+    for( i = 0; i < 16; i++ )
+    {
+        aa[i] = a[15 - i];
+        bb[i] = b[15 - i];
+    }
+
+    asm( "movdqu (%0), %%xmm0               \n\t" // a1:a0
+         "movdqu (%1), %%xmm1               \n\t" // b1:b0
+
+         /*
+          * Caryless multiplication xmm2:xmm1 = xmm0 * xmm1
+          * using [CLMUL-WP] algorithm 1 (p. 13).
+          */
+         "movdqa %%xmm1, %%xmm2             \n\t" // copy of b1:b0
+         "movdqa %%xmm1, %%xmm3             \n\t" // same
+         "movdqa %%xmm1, %%xmm4             \n\t" // same
+         PCLMULQDQ xmm0_xmm1 ",0x00         \n\t" // a0*b0 = c1:c0
+         PCLMULQDQ xmm0_xmm2 ",0x11         \n\t" // a1*b1 = d1:d0
+         PCLMULQDQ xmm0_xmm3 ",0x10         \n\t" // a0*b1 = e1:e0
+         PCLMULQDQ xmm0_xmm4 ",0x01         \n\t" // a1*b0 = f1:f0
+         "pxor %%xmm3, %%xmm4               \n\t" // e1+f1:e0+f0
+         "movdqa %%xmm4, %%xmm3             \n\t" // same
+         "psrldq $8, %%xmm4                 \n\t" // 0:e1+f1
+         "pslldq $8, %%xmm3                 \n\t" // e0+f0:0
+         "pxor %%xmm4, %%xmm2               \n\t" // d1:d0+e1+f1
+         "pxor %%xmm3, %%xmm1               \n\t" // c1+e0+f1:c0
+
+         /*
+          * Now shift the result one bit to the left,
+          * taking advantage of [CLMUL-WP] eq 27 (p. 20)
+          */
+         "movdqa %%xmm1, %%xmm3             \n\t" // r1:r0
+         "movdqa %%xmm2, %%xmm4             \n\t" // r3:r2
+         "psllq $1, %%xmm1                  \n\t" // r1<<1:r0<<1
+         "psllq $1, %%xmm2                  \n\t" // r3<<1:r2<<1
+         "psrlq $63, %%xmm3                 \n\t" // r1>>63:r0>>63
+         "psrlq $63, %%xmm4                 \n\t" // r3>>63:r2>>63
+         "movdqa %%xmm3, %%xmm5             \n\t" // r1>>63:r0>>63
+         "pslldq $8, %%xmm3                 \n\t" // r0>>63:0
+         "pslldq $8, %%xmm4                 \n\t" // r2>>63:0
+         "psrldq $8, %%xmm5                 \n\t" // 0:r1>>63
+         "por %%xmm3, %%xmm1                \n\t" // r1<<1|r0>>63:r0<<1
+         "por %%xmm4, %%xmm2                \n\t" // r3<<1|r2>>62:r2<<1
+         "por %%xmm5, %%xmm2                \n\t" // r3<<1|r2>>62:r2<<1|r1>>63
+
+         /*
+          * Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1
+          * using [CLMUL-WP] algorithm 5 (p. 20).
+          * Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted).
+          */
+         /* Step 2 (1) */
+         "movdqa %%xmm1, %%xmm3             \n\t" // x1:x0
+         "movdqa %%xmm1, %%xmm4             \n\t" // same
+         "movdqa %%xmm1, %%xmm5             \n\t" // same
+         "psllq $63, %%xmm3                 \n\t" // x1<<63:x0<<63 = stuff:a
+         "psllq $62, %%xmm4                 \n\t" // x1<<62:x0<<62 = stuff:b
+         "psllq $57, %%xmm5                 \n\t" // x1<<57:x0<<57 = stuff:c
+
+         /* Step 2 (2) */
+         "pxor %%xmm4, %%xmm3               \n\t" // stuff:a+b
+         "pxor %%xmm5, %%xmm3               \n\t" // stuff:a+b+c
+         "pslldq $8, %%xmm3                 \n\t" // a+b+c:0
+         "pxor %%xmm3, %%xmm1               \n\t" // x1+a+b+c:x0 = d:x0
+
+         /* Steps 3 and 4 */
+         "movdqa %%xmm1,%%xmm0              \n\t" // d:x0
+         "movdqa %%xmm1,%%xmm4              \n\t" // same
+         "movdqa %%xmm1,%%xmm5              \n\t" // same
+         "psrlq $1, %%xmm0                  \n\t" // e1:x0>>1 = e1:e0'
+         "psrlq $2, %%xmm4                  \n\t" // f1:x0>>2 = f1:f0'
+         "psrlq $7, %%xmm5                  \n\t" // g1:x0>>7 = g1:g0'
+         "pxor %%xmm4, %%xmm0               \n\t" // e1+f1:e0'+f0'
+         "pxor %%xmm5, %%xmm0               \n\t" // e1+f1+g1:e0'+f0'+g0'
+         // e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing
+         // bits carried from d. Now get those\t bits back in.
+         "movdqa %%xmm1,%%xmm3              \n\t" // d:x0
+         "movdqa %%xmm1,%%xmm4              \n\t" // same
+         "movdqa %%xmm1,%%xmm5              \n\t" // same
+         "psllq $63, %%xmm3                 \n\t" // d<<63:stuff
+         "psllq $62, %%xmm4                 \n\t" // d<<62:stuff
+         "psllq $57, %%xmm5                 \n\t" // d<<57:stuff
+         "pxor %%xmm4, %%xmm3               \n\t" // d<<63+d<<62:stuff
+         "pxor %%xmm5, %%xmm3               \n\t" // missing bits of d:stuff
+         "psrldq $8, %%xmm3                 \n\t" // 0:missing bits of d
+         "pxor %%xmm3, %%xmm0               \n\t" // e1+f1+g1:e0+f0+g0
+         "pxor %%xmm1, %%xmm0               \n\t" // h1:h0
+         "pxor %%xmm2, %%xmm0               \n\t" // x3+h1:x2+h0
+
+         "movdqu %%xmm0, (%2)               \n\t" // done
+         :
+         : "r" (aa), "r" (bb), "r" (cc)
+         : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" );
+
+    /* Now byte-reverse the outputs */
+    for( i = 0; i < 16; i++ )
+        c[i] = cc[15 - i];
+
+    return;
+}
+
+/*
+ * Compute decryption round keys from encryption round keys
+ */
+void mbedtls_aesni_inverse_key( unsigned char *invkey,
+                        const unsigned char *fwdkey, int nr )
+{
+    unsigned char *ik = invkey;
+    const unsigned char *fk = fwdkey + 16 * nr;
+
+    memcpy( ik, fk, 16 );
+
+    for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 )
+        asm( "movdqu (%0), %%xmm0       \n\t"
+             AESIMC  xmm0_xmm0         "\n\t"
+             "movdqu %%xmm0, (%1)       \n\t"
+             :
+             : "r" (fk), "r" (ik)
+             : "memory", "xmm0" );
+
+    memcpy( ik, fk, 16 );
+}
+
+/*
+ * Key expansion, 128-bit case
+ */
+static void aesni_setkey_enc_128( unsigned char *rk,
+                                  const unsigned char *key )
+{
+    asm( "movdqu (%1), %%xmm0               \n\t" // copy the original key
+         "movdqu %%xmm0, (%0)               \n\t" // as round key 0
+         "jmp 2f                            \n\t" // skip auxiliary routine
+
+         /*
+          * Finish generating the next round key.
+          *
+          * On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff
+          * with X = rot( sub( r3 ) ) ^ RCON.
+          *
+          * On exit, xmm0 is r7:r6:r5:r4
+          * with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3
+          * and those are written to the round key buffer.
+          */
+         "1:                                \n\t"
+         "pshufd $0xff, %%xmm1, %%xmm1      \n\t" // X:X:X:X
+         "pxor %%xmm0, %%xmm1               \n\t" // X+r3:X+r2:X+r1:r4
+         "pslldq $4, %%xmm0                 \n\t" // r2:r1:r0:0
+         "pxor %%xmm0, %%xmm1               \n\t" // X+r3+r2:X+r2+r1:r5:r4
+         "pslldq $4, %%xmm0                 \n\t" // etc
+         "pxor %%xmm0, %%xmm1               \n\t"
+         "pslldq $4, %%xmm0                 \n\t"
+         "pxor %%xmm1, %%xmm0               \n\t" // update xmm0 for next time!
+         "add $16, %0                       \n\t" // point to next round key
+         "movdqu %%xmm0, (%0)               \n\t" // write it
+         "ret                               \n\t"
+
+         /* Main "loop" */
+         "2:                                \n\t"
+         AESKEYGENA xmm0_xmm1 ",0x01        \n\tcall 1b \n\t"
+         AESKEYGENA xmm0_xmm1 ",0x02        \n\tcall 1b \n\t"
+         AESKEYGENA xmm0_xmm1 ",0x04        \n\tcall 1b \n\t"
+         AESKEYGENA xmm0_xmm1 ",0x08        \n\tcall 1b \n\t"
+         AESKEYGENA xmm0_xmm1 ",0x10        \n\tcall 1b \n\t"
+         AESKEYGENA xmm0_xmm1 ",0x20        \n\tcall 1b \n\t"
+         AESKEYGENA xmm0_xmm1 ",0x40        \n\tcall 1b \n\t"
+         AESKEYGENA xmm0_xmm1 ",0x80        \n\tcall 1b \n\t"
+         AESKEYGENA xmm0_xmm1 ",0x1B        \n\tcall 1b \n\t"
+         AESKEYGENA xmm0_xmm1 ",0x36        \n\tcall 1b \n\t"
+         :
+         : "r" (rk), "r" (key)
+         : "memory", "cc", "0" );
+}
+
+/*
+ * Key expansion, 192-bit case
+ */
+static void aesni_setkey_enc_192( unsigned char *rk,
+                                  const unsigned char *key )
+{
+    asm( "movdqu (%1), %%xmm0   \n\t" // copy original round key
+         "movdqu %%xmm0, (%0)   \n\t"
+         "add $16, %0           \n\t"
+         "movq 16(%1), %%xmm1   \n\t"
+         "movq %%xmm1, (%0)     \n\t"
+         "add $8, %0            \n\t"
+         "jmp 2f                \n\t" // skip auxiliary routine
+
+         /*
+          * Finish generating the next 6 quarter-keys.
+          *
+          * On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4
+          * and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON.
+          *
+          * On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10
+          * and those are written to the round key buffer.
+          */
+         "1:                            \n\t"
+         "pshufd $0x55, %%xmm2, %%xmm2  \n\t" // X:X:X:X
+         "pxor %%xmm0, %%xmm2           \n\t" // X+r3:X+r2:X+r1:r4
+         "pslldq $4, %%xmm0             \n\t" // etc
+         "pxor %%xmm0, %%xmm2           \n\t"
+         "pslldq $4, %%xmm0             \n\t"
+         "pxor %%xmm0, %%xmm2           \n\t"
+         "pslldq $4, %%xmm0             \n\t"
+         "pxor %%xmm2, %%xmm0           \n\t" // update xmm0 = r9:r8:r7:r6
+         "movdqu %%xmm0, (%0)           \n\t"
+         "add $16, %0                   \n\t"
+         "pshufd $0xff, %%xmm0, %%xmm2  \n\t" // r9:r9:r9:r9
+         "pxor %%xmm1, %%xmm2           \n\t" // stuff:stuff:r9+r5:r10
+         "pslldq $4, %%xmm1             \n\t" // r2:r1:r0:0
+         "pxor %%xmm2, %%xmm1           \n\t" // xmm1 = stuff:stuff:r11:r10
+         "movq %%xmm1, (%0)             \n\t"
+         "add $8, %0                    \n\t"
+         "ret                           \n\t"
+
+         "2:                            \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x01    \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x02    \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x04    \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x08    \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x10    \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x20    \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x40    \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x80    \n\tcall 1b \n\t"
+
+         :
+         : "r" (rk), "r" (key)
+         : "memory", "cc", "0" );
+}
+
+/*
+ * Key expansion, 256-bit case
+ */
+static void aesni_setkey_enc_256( unsigned char *rk,
+                                  const unsigned char *key )
+{
+    asm( "movdqu (%1), %%xmm0           \n\t"
+         "movdqu %%xmm0, (%0)           \n\t"
+         "add $16, %0                   \n\t"
+         "movdqu 16(%1), %%xmm1         \n\t"
+         "movdqu %%xmm1, (%0)           \n\t"
+         "jmp 2f                        \n\t" // skip auxiliary routine
+
+         /*
+          * Finish generating the next two round keys.
+          *
+          * On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and
+          * xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON
+          *
+          * On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12
+          * and those have been written to the output buffer.
+          */
+         "1:                                \n\t"
+         "pshufd $0xff, %%xmm2, %%xmm2      \n\t"
+         "pxor %%xmm0, %%xmm2               \n\t"
+         "pslldq $4, %%xmm0                 \n\t"
+         "pxor %%xmm0, %%xmm2               \n\t"
+         "pslldq $4, %%xmm0                 \n\t"
+         "pxor %%xmm0, %%xmm2               \n\t"
+         "pslldq $4, %%xmm0                 \n\t"
+         "pxor %%xmm2, %%xmm0               \n\t"
+         "add $16, %0                       \n\t"
+         "movdqu %%xmm0, (%0)               \n\t"
+
+         /* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 )
+          * and proceed to generate next round key from there */
+         AESKEYGENA xmm0_xmm2 ",0x00        \n\t"
+         "pshufd $0xaa, %%xmm2, %%xmm2      \n\t"
+         "pxor %%xmm1, %%xmm2               \n\t"
+         "pslldq $4, %%xmm1                 \n\t"
+         "pxor %%xmm1, %%xmm2               \n\t"
+         "pslldq $4, %%xmm1                 \n\t"
+         "pxor %%xmm1, %%xmm2               \n\t"
+         "pslldq $4, %%xmm1                 \n\t"
+         "pxor %%xmm2, %%xmm1               \n\t"
+         "add $16, %0                       \n\t"
+         "movdqu %%xmm1, (%0)               \n\t"
+         "ret                               \n\t"
+
+         /*
+          * Main "loop" - Generating one more key than necessary,
+          * see definition of mbedtls_aes_context.buf
+          */
+         "2:                                \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x01        \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x02        \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x04        \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x08        \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x10        \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x20        \n\tcall 1b \n\t"
+         AESKEYGENA xmm1_xmm2 ",0x40        \n\tcall 1b \n\t"
+         :
+         : "r" (rk), "r" (key)
+         : "memory", "cc", "0" );
+}
+
+/*
+ * Key expansion, wrapper
+ */
+int mbedtls_aesni_setkey_enc( unsigned char *rk,
+                      const unsigned char *key,
+                      size_t bits )
+{
+    switch( bits )
+    {
+        case 128: aesni_setkey_enc_128( rk, key ); break;
+        case 192: aesni_setkey_enc_192( rk, key ); break;
+        case 256: aesni_setkey_enc_256( rk, key ); break;
+        default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
+    }
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_HAVE_X86_64 */
+
+#endif /* MBEDTLS_AESNI_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/arc4.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/arc4.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/arc4.c	(revision 398)
@@ -0,0 +1,201 @@
+/*
+ *  An implementation of the ARCFOUR algorithm
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The ARCFOUR algorithm was publicly disclosed on 94/09.
+ *
+ *  http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ARC4_C)
+
+#include "mbedtls/arc4.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_ARC4_ALT)
+
+void mbedtls_arc4_init( mbedtls_arc4_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_arc4_context ) );
+}
+
+void mbedtls_arc4_free( mbedtls_arc4_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_arc4_context ) );
+}
+
+/*
+ * ARC4 key schedule
+ */
+void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
+                 unsigned int keylen )
+{
+    int i, j, a;
+    unsigned int k;
+    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
+ */
+int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
+                unsigned char *output )
+{
+    int x, y, a, b;
+    size_t i;
+    unsigned char *m;
+
+    x = ctx->x;
+    y = ctx->y;
+    m = ctx->m;
+
+    for( i = 0; i < length; 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;
+
+        output[i] = (unsigned char)
+            ( input[i] ^ m[(unsigned char)( a + b )] );
+    }
+
+    ctx->x = x;
+    ctx->y = y;
+
+    return( 0 );
+}
+
+#endif /* !MBEDTLS_ARC4_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+/*
+ * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
+ *
+ * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
+ */
+static const unsigned char arc4_test_key[3][8] =
+{
+    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
+    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+};
+
+static const unsigned char arc4_test_pt[3][8] =
+{
+    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+};
+
+static const unsigned char arc4_test_ct[3][8] =
+{
+    { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
+    { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
+    { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
+};
+
+/*
+ * Checkup routine
+ */
+int mbedtls_arc4_self_test( int verbose )
+{
+    int i, ret = 0;
+    unsigned char ibuf[8];
+    unsigned char obuf[8];
+    mbedtls_arc4_context ctx;
+
+    mbedtls_arc4_init( &ctx );
+
+    for( i = 0; i < 3; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  ARC4 test #%d: ", i + 1 );
+
+        memcpy( ibuf, arc4_test_pt[i], 8 );
+
+        mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 );
+        mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf );
+
+        if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+exit:
+    mbedtls_arc4_free( &ctx );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_ARC4_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/aria.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/aria.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/aria.c	(revision 398)
@@ -0,0 +1,1079 @@
+/*
+ *  ARIA implementation
+ *
+ *  Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * This implementation is based on the following standards:
+ * [1] http://210.104.33.10/ARIA/doc/ARIA-specification-e.pdf
+ * [2] https://tools.ietf.org/html/rfc5794
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ARIA_C)
+
+#include "mbedtls/aria.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_ARIA_ALT)
+
+#include "mbedtls/platform_util.h"
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+/* Parameter validation macros */
+#define ARIA_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ARIA_BAD_INPUT_DATA )
+#define ARIA_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT32_LE
+#define GET_UINT32_LE( n, b, i )                \
+{                                               \
+    (n) = ( (uint32_t) (b)[(i)    ]       )     \
+        | ( (uint32_t) (b)[(i) + 1] <<  8 )     \
+        | ( (uint32_t) (b)[(i) + 2] << 16 )     \
+        | ( (uint32_t) (b)[(i) + 3] << 24 );    \
+}
+#endif
+
+#ifndef PUT_UINT32_LE
+#define PUT_UINT32_LE( n, b, i )                                \
+{                                                               \
+    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
+    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
+    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
+    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
+}
+#endif
+
+/*
+ * modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
+ *
+ * This is submatrix P1 in [1] Appendix B.1
+ *
+ * Common compilers fail to translate this to minimal number of instructions,
+ * so let's provide asm versions for common platforms with C fallback.
+ */
+#if defined(MBEDTLS_HAVE_ASM)
+#if defined(__arm__) /* rev16 available from v6 up */
+/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
+#if defined(__GNUC__) && \
+    ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \
+    __ARM_ARCH >= 6
+static inline uint32_t aria_p1( uint32_t x )
+{
+    uint32_t r;
+    __asm( "rev16 %0, %1" : "=l" (r) : "l" (x) );
+    return( r );
+}
+#define ARIA_P1 aria_p1
+#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \
+    ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 )
+static inline uint32_t aria_p1( uint32_t x )
+{
+    uint32_t r;
+    __asm( "rev16 r, x" );
+    return( r );
+}
+#define ARIA_P1 aria_p1
+#endif
+#endif /* arm */
+#if defined(__GNUC__) && \
+    defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
+/* I couldn't find an Intel equivalent of rev16, so two instructions */
+#define ARIA_P1(x) ARIA_P2( ARIA_P3( x ) )
+#endif /* x86 gnuc */
+#endif /* MBEDTLS_HAVE_ASM && GNUC */
+#if !defined(ARIA_P1)
+#define ARIA_P1(x) ((((x) >> 8) & 0x00FF00FF) ^ (((x) & 0x00FF00FF) << 8))
+#endif
+
+/*
+ * modify byte order: ( A B C D ) -> ( C D A B ), i.e. rotate by 16 bits
+ *
+ * This is submatrix P2 in [1] Appendix B.1
+ *
+ * Common compilers will translate this to a single instruction.
+ */
+#define ARIA_P2(x) (((x) >> 16) ^ ((x) << 16))
+
+/*
+ * modify byte order: ( A B C D ) -> ( D C B A ), i.e. change endianness
+ *
+ * This is submatrix P3 in [1] Appendix B.1
+ *
+ * Some compilers fail to translate this to a single instruction,
+ * so let's provide asm versions for common platforms with C fallback.
+ */
+#if defined(MBEDTLS_HAVE_ASM)
+#if defined(__arm__) /* rev available from v6 up */
+/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
+#if defined(__GNUC__) && \
+    ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) && \
+    __ARM_ARCH >= 6
+static inline uint32_t aria_p3( uint32_t x )
+{
+    uint32_t r;
+    __asm( "rev %0, %1" : "=l" (r) : "l" (x) );
+    return( r );
+}
+#define ARIA_P3 aria_p3
+#elif defined(__ARMCC_VERSION) && __ARMCC_VERSION < 6000000 && \
+    ( __TARGET_ARCH_ARM >= 6 || __TARGET_ARCH_THUMB >= 3 )
+static inline uint32_t aria_p3( uint32_t x )
+{
+    uint32_t r;
+    __asm( "rev r, x" );
+    return( r );
+}
+#define ARIA_P3 aria_p3
+#endif
+#endif /* arm */
+#if defined(__GNUC__) && \
+    defined(__i386__) || defined(__amd64__) || defined( __x86_64__)
+static inline uint32_t aria_p3( uint32_t x )
+{
+    __asm( "bswap %0" : "=r" (x) : "0" (x) );
+    return( x );
+}
+#define ARIA_P3 aria_p3
+#endif /* x86 gnuc */
+#endif /* MBEDTLS_HAVE_ASM && GNUC */
+#if !defined(ARIA_P3)
+#define ARIA_P3(x) ARIA_P2( ARIA_P1 ( x ) )
+#endif
+
+/*
+ * ARIA Affine Transform
+ * (a, b, c, d) = state in/out
+ *
+ * If we denote the first byte of input by 0, ..., the last byte by f,
+ * then inputs are: a = 0123, b = 4567, c = 89ab, d = cdef.
+ *
+ * Reading [1] 2.4 or [2] 2.4.3 in columns and performing simple
+ * rearrangements on adjacent pairs, output is:
+ *
+ * a = 3210 + 4545 + 6767 + 88aa + 99bb + dccd + effe
+ *   = 3210 + 4567 + 6745 + 89ab + 98ba + dcfe + efcd
+ * b = 0101 + 2323 + 5476 + 8998 + baab + eecc + ffdd
+ *   = 0123 + 2301 + 5476 + 89ab + ba98 + efcd + fedc
+ * c = 0022 + 1133 + 4554 + 7667 + ab89 + dcdc + fefe
+ *   = 0123 + 1032 + 4567 + 7654 + ab89 + dcfe + fedc
+ * d = 1001 + 2332 + 6644 + 7755 + 9898 + baba + cdef
+ *   = 1032 + 2301 + 6745 + 7654 + 98ba + ba98 + cdef
+ *
+ * Note: another presentation of the A transform can be found as the first
+ * half of App. B.1 in [1] in terms of 4-byte operators P1, P2, P3 and P4.
+ * The implementation below uses only P1 and P2 as they are sufficient.
+ */
+static inline void aria_a( uint32_t *a, uint32_t *b,
+                           uint32_t *c, uint32_t *d )
+{
+    uint32_t ta, tb, tc;
+    ta  =  *b;                      // 4567
+    *b  =  *a;                      // 0123
+    *a  =  ARIA_P2( ta );           // 6745
+    tb  =  ARIA_P2( *d );           // efcd
+    *d  =  ARIA_P1( *c );           // 98ba
+    *c  =  ARIA_P1( tb );           // fedc
+    ta  ^= *d;                      // 4567+98ba
+    tc  =  ARIA_P2( *b );           // 2301
+    ta  =  ARIA_P1( ta ) ^ tc ^ *c; // 2301+5476+89ab+fedc
+    tb  ^= ARIA_P2( *d );           // ba98+efcd
+    tc  ^= ARIA_P1( *a );           // 2301+7654
+    *b  ^= ta ^ tb;                 // 0123+2301+5476+89ab+ba98+efcd+fedc OUT
+    tb  =  ARIA_P2( tb ) ^ ta;      // 2301+5476+89ab+98ba+cdef+fedc
+    *a  ^= ARIA_P1( tb );           // 3210+4567+6745+89ab+98ba+dcfe+efcd OUT
+    ta  =  ARIA_P2( ta );           // 0123+7654+ab89+dcfe
+    *d  ^= ARIA_P1( ta ) ^ tc;      // 1032+2301+6745+7654+98ba+ba98+cdef OUT
+    tc  =  ARIA_P2( tc );           // 0123+5476
+    *c  ^= ARIA_P1( tc ) ^ ta;      // 0123+1032+4567+7654+ab89+dcfe+fedc OUT
+}
+
+/*
+ * ARIA Substitution Layer SL1 / SL2
+ * (a, b, c, d) = state in/out
+ * (sa, sb, sc, sd) = 256 8-bit S-Boxes (see below)
+ *
+ * By passing sb1, sb2, is1, is2 as S-Boxes you get SL1
+ * By passing is1, is2, sb1, sb2 as S-Boxes you get SL2
+ */
+static inline void aria_sl( uint32_t *a, uint32_t *b,
+                            uint32_t *c, uint32_t *d,
+                            const uint8_t sa[256], const uint8_t sb[256],
+                            const uint8_t sc[256], const uint8_t sd[256] )
+{
+    *a = ( (uint32_t) sa[ *a        & 0xFF]       ) ^
+         (((uint32_t) sb[(*a >>  8) & 0xFF]) <<  8) ^
+         (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^
+         (((uint32_t) sd[ *a >> 24        ]) << 24);
+    *b = ( (uint32_t) sa[ *b        & 0xFF]       ) ^
+         (((uint32_t) sb[(*b >>  8) & 0xFF]) <<  8) ^
+         (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^
+         (((uint32_t) sd[ *b >> 24        ]) << 24);
+    *c = ( (uint32_t) sa[ *c        & 0xFF]       ) ^
+         (((uint32_t) sb[(*c >>  8) & 0xFF]) <<  8) ^
+         (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^
+         (((uint32_t) sd[ *c >> 24        ]) << 24);
+    *d = ( (uint32_t) sa[ *d        & 0xFF]       ) ^
+         (((uint32_t) sb[(*d >>  8) & 0xFF]) <<  8) ^
+         (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^
+         (((uint32_t) sd[ *d >> 24        ]) << 24);
+}
+
+/*
+ * S-Boxes
+ */
+static const uint8_t aria_sb1[256] =
+{
+    0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
+    0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+    0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
+    0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+    0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
+    0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+    0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
+    0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+    0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
+    0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+    0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
+    0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+    0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
+    0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+    0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
+    0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+    0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
+    0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+    0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
+    0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+    0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
+    0xB0, 0x54, 0xBB, 0x16
+};
+
+static const uint8_t aria_sb2[256] =
+{
+    0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A, 0x46,
+    0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97, 0xBE, 0x2B,
+    0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D, 0x06, 0x41, 0x6B,
+    0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE, 0x63, 0xDF, 0xE7, 0xBB,
+    0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85, 0xE4, 0x3A, 0x09, 0x45, 0xAA,
+    0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F, 0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91,
+    0x8D, 0x78, 0xC8, 0x95, 0xF9, 0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38,
+    0x5C, 0x83, 0x2A, 0x28, 0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53,
+    0xFF, 0x87, 0x0E, 0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74,
+    0x32, 0xCA, 0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26,
+    0x07, 0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD,
+    0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13, 0xDC,
+    0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02, 0x8F, 0x3E,
+    0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9, 0xBF, 0xD4, 0x9A,
+    0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43, 0xA7, 0xE1, 0xD0, 0xF5,
+    0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3, 0x8A, 0xD5, 0x79, 0x86, 0xA8,
+    0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6, 0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24,
+    0x16, 0x82, 0x5F, 0xDA, 0xE6, 0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F,
+    0x5D, 0x6F, 0x80, 0x0A, 0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33,
+    0x7D, 0x5A, 0x52, 0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D,
+    0xED, 0x14, 0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A,
+    0xAF, 0xBA, 0xB5, 0x81
+};
+
+static const uint8_t aria_is1[256] =
+{
+    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
+    0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+    0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
+    0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
+    0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+    0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
+    0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
+    0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+    0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
+    0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
+    0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+    0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
+    0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
+    0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+    0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
+    0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
+    0x55, 0x21, 0x0C, 0x7D
+};
+
+static const uint8_t aria_is2[256] =
+{
+    0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB, 0xE1,
+    0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0, 0xCC, 0xA3,
+    0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81, 0x65, 0xF5, 0x89,
+    0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17, 0xD4, 0x40, 0x1A, 0x4D,
+    0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64, 0x6A, 0x53, 0xAA, 0x38, 0x98,
+    0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22, 0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58,
+    0x67, 0x88, 0x06, 0xC3, 0x35, 0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F,
+    0x02, 0x24, 0x75, 0x93, 0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE,
+    0x7A, 0xE8, 0x08, 0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23,
+    0xDF, 0xEF, 0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19,
+    0x49, 0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55,
+    0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69, 0x9A,
+    0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26, 0xA7, 0xDE,
+    0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D, 0xF3, 0xC5, 0xB0,
+    0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC, 0xEB, 0x6F, 0xD5, 0xF6,
+    0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD, 0x2F, 0x18, 0x83, 0x16, 0xA5,
+    0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9, 0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13,
+    0x07, 0x4F, 0x4E, 0x45, 0xB2, 0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73,
+    0x90, 0x7B, 0xCF, 0x59, 0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94,
+    0x37, 0x9F, 0xD0, 0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3,
+    0x25, 0x8A, 0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33,
+    0x03, 0xA2, 0xAC, 0x60
+};
+
+/*
+ * Helper for key schedule: r = FO( p, k ) ^ x
+ */
+static void aria_fo_xor( uint32_t r[4], const uint32_t p[4],
+                         const uint32_t k[4], const uint32_t x[4] )
+{
+    uint32_t a, b, c, d;
+
+    a = p[0] ^ k[0];
+    b = p[1] ^ k[1];
+    c = p[2] ^ k[2];
+    d = p[3] ^ k[3];
+
+    aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
+    aria_a( &a, &b, &c, &d );
+
+    r[0] = a ^ x[0];
+    r[1] = b ^ x[1];
+    r[2] = c ^ x[2];
+    r[3] = d ^ x[3];
+}
+
+/*
+ * Helper for key schedule: r = FE( p, k ) ^ x
+ */
+static void aria_fe_xor( uint32_t r[4], const uint32_t p[4],
+                         const uint32_t k[4], const uint32_t x[4] )
+{
+    uint32_t a, b, c, d;
+
+    a = p[0] ^ k[0];
+    b = p[1] ^ k[1];
+    c = p[2] ^ k[2];
+    d = p[3] ^ k[3];
+
+    aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
+    aria_a( &a, &b, &c, &d );
+
+    r[0] = a ^ x[0];
+    r[1] = b ^ x[1];
+    r[2] = c ^ x[2];
+    r[3] = d ^ x[3];
+}
+
+/*
+ * Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
+ *
+ * We chose to store bytes into 32-bit words in little-endian format (see
+ * GET/PUT_UINT32_LE) so we need to reverse bytes here.
+ */
+static void aria_rot128( uint32_t r[4], const uint32_t a[4],
+                         const uint32_t b[4], uint8_t n )
+{
+    uint8_t i, j;
+    uint32_t t, u;
+
+    const uint8_t n1 = n % 32;              // bit offset
+    const uint8_t n2 = n1 ? 32 - n1 : 0;    // reverse bit offset
+
+    j = ( n / 32 ) % 4;                     // initial word offset
+    t = ARIA_P3( b[j] );                    // big endian
+    for( i = 0; i < 4; i++ )
+    {
+        j = ( j + 1 ) % 4;                  // get next word, big endian
+        u = ARIA_P3( b[j] );
+        t <<= n1;                           // rotate
+        t |= u >> n2;
+        t = ARIA_P3( t );                   // back to little endian
+        r[i] = a[i] ^ t;                    // store
+        t = u;                              // move to next word
+    }
+}
+
+/*
+ * Set encryption key
+ */
+int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
+                             const unsigned char *key, unsigned int keybits )
+{
+    /* round constant masks */
+    const uint32_t rc[3][4] =
+    {
+        {   0xB7C17C51, 0x940A2227, 0xE8AB13FE, 0xE06E9AFA  },
+        {   0xCC4AB16D, 0x20C8219E, 0xD5B128FF, 0xB0E25DEF  },
+        {   0x1D3792DB, 0x70E92621, 0x75972403, 0x0EC9E804  }
+    };
+
+    int i;
+    uint32_t w[4][4], *w2;
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( key != NULL );
+
+    if( keybits != 128 && keybits != 192 && keybits != 256 )
+        return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
+
+    /* Copy key to W0 (and potential remainder to W1) */
+    GET_UINT32_LE( w[0][0], key,  0 );
+    GET_UINT32_LE( w[0][1], key,  4 );
+    GET_UINT32_LE( w[0][2], key,  8 );
+    GET_UINT32_LE( w[0][3], key, 12 );
+
+    memset( w[1], 0, 16 );
+    if( keybits >= 192 )
+    {
+        GET_UINT32_LE( w[1][0], key, 16 );  // 192 bit key
+        GET_UINT32_LE( w[1][1], key, 20 );
+    }
+    if( keybits == 256 )
+    {
+        GET_UINT32_LE( w[1][2], key, 24 );  // 256 bit key
+        GET_UINT32_LE( w[1][3], key, 28 );
+    }
+
+    i = ( keybits - 128 ) >> 6;             // index: 0, 1, 2
+    ctx->nr = 12 + 2 * i;                   // no. rounds: 12, 14, 16
+
+    aria_fo_xor( w[1], w[0], rc[i], w[1] ); // W1 = FO(W0, CK1) ^ KR
+    i = i < 2 ? i + 1 : 0;
+    aria_fe_xor( w[2], w[1], rc[i], w[0] ); // W2 = FE(W1, CK2) ^ W0
+    i = i < 2 ? i + 1 : 0;
+    aria_fo_xor( w[3], w[2], rc[i], w[1] ); // W3 = FO(W2, CK3) ^ W1
+
+    for( i = 0; i < 4; i++ )                // create round keys
+    {
+        w2 = w[(i + 1) & 3];
+        aria_rot128( ctx->rk[i     ], w[i], w2, 128 - 19 );
+        aria_rot128( ctx->rk[i +  4], w[i], w2, 128 - 31 );
+        aria_rot128( ctx->rk[i +  8], w[i], w2,       61 );
+        aria_rot128( ctx->rk[i + 12], w[i], w2,       31 );
+    }
+    aria_rot128( ctx->rk[16], w[0], w[1], 19 );
+
+    /* w holds enough info to reconstruct the round keys */
+    mbedtls_platform_zeroize( w, sizeof( w ) );
+
+    return( 0 );
+}
+
+/*
+ * Set decryption key
+ */
+int mbedtls_aria_setkey_dec( mbedtls_aria_context *ctx,
+                             const unsigned char *key, unsigned int keybits )
+{
+    int i, j, k, ret;
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( key != NULL );
+
+    ret = mbedtls_aria_setkey_enc( ctx, key, keybits );
+    if( ret != 0 )
+        return( ret );
+
+    /* flip the order of round keys */
+    for( i = 0, j = ctx->nr; i < j; i++, j-- )
+    {
+        for( k = 0; k < 4; k++ )
+        {
+            uint32_t t = ctx->rk[i][k];
+            ctx->rk[i][k] = ctx->rk[j][k];
+            ctx->rk[j][k] = t;
+        }
+    }
+
+    /* apply affine transform to middle keys */
+    for( i = 1; i < ctx->nr; i++ )
+    {
+        aria_a( &ctx->rk[i][0], &ctx->rk[i][1],
+                &ctx->rk[i][2], &ctx->rk[i][3] );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Encrypt a block
+ */
+int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
+                            const unsigned char input[MBEDTLS_ARIA_BLOCKSIZE],
+                            unsigned char output[MBEDTLS_ARIA_BLOCKSIZE] )
+{
+    int i;
+
+    uint32_t a, b, c, d;
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( input != NULL );
+    ARIA_VALIDATE_RET( output != NULL );
+
+    GET_UINT32_LE( a, input,  0 );
+    GET_UINT32_LE( b, input,  4 );
+    GET_UINT32_LE( c, input,  8 );
+    GET_UINT32_LE( d, input, 12 );
+
+    i = 0;
+    while( 1 )
+    {
+        a ^= ctx->rk[i][0];
+        b ^= ctx->rk[i][1];
+        c ^= ctx->rk[i][2];
+        d ^= ctx->rk[i][3];
+        i++;
+
+        aria_sl( &a, &b, &c, &d, aria_sb1, aria_sb2, aria_is1, aria_is2 );
+        aria_a( &a, &b, &c, &d );
+
+        a ^= ctx->rk[i][0];
+        b ^= ctx->rk[i][1];
+        c ^= ctx->rk[i][2];
+        d ^= ctx->rk[i][3];
+        i++;
+
+        aria_sl( &a, &b, &c, &d, aria_is1, aria_is2, aria_sb1, aria_sb2 );
+        if( i >= ctx->nr )
+            break;
+        aria_a( &a, &b, &c, &d );
+    }
+
+    /* final key mixing */
+    a ^= ctx->rk[i][0];
+    b ^= ctx->rk[i][1];
+    c ^= ctx->rk[i][2];
+    d ^= ctx->rk[i][3];
+
+    PUT_UINT32_LE( a, output,  0 );
+    PUT_UINT32_LE( b, output,  4 );
+    PUT_UINT32_LE( c, output,  8 );
+    PUT_UINT32_LE( d, output, 12 );
+
+    return( 0 );
+}
+
+/* Initialize context */
+void mbedtls_aria_init( mbedtls_aria_context *ctx )
+{
+    ARIA_VALIDATE( ctx != NULL );
+    memset( ctx, 0, sizeof( mbedtls_aria_context ) );
+}
+
+/* Clear context */
+void mbedtls_aria_free( mbedtls_aria_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aria_context ) );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * ARIA-CBC buffer encryption/decryption
+ */
+int mbedtls_aria_crypt_cbc( mbedtls_aria_context *ctx,
+                            int mode,
+                            size_t length,
+                            unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
+                            const unsigned char *input,
+                            unsigned char *output )
+{
+    int i;
+    unsigned char temp[MBEDTLS_ARIA_BLOCKSIZE];
+
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT ||
+                       mode == MBEDTLS_ARIA_DECRYPT );
+    ARIA_VALIDATE_RET( length == 0 || input  != NULL );
+    ARIA_VALIDATE_RET( length == 0 || output != NULL );
+    ARIA_VALIDATE_RET( iv != NULL );
+
+    if( length % MBEDTLS_ARIA_BLOCKSIZE )
+        return( MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH );
+
+    if( mode == MBEDTLS_ARIA_DECRYPT )
+    {
+        while( length > 0 )
+        {
+            memcpy( temp, input, MBEDTLS_ARIA_BLOCKSIZE );
+            mbedtls_aria_crypt_ecb( ctx, input, output );
+
+            for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ )
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+            memcpy( iv, temp, MBEDTLS_ARIA_BLOCKSIZE );
+
+            input  += MBEDTLS_ARIA_BLOCKSIZE;
+            output += MBEDTLS_ARIA_BLOCKSIZE;
+            length -= MBEDTLS_ARIA_BLOCKSIZE;
+        }
+    }
+    else
+    {
+        while( length > 0 )
+        {
+            for( i = 0; i < MBEDTLS_ARIA_BLOCKSIZE; i++ )
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+            mbedtls_aria_crypt_ecb( ctx, output, output );
+            memcpy( iv, output, MBEDTLS_ARIA_BLOCKSIZE );
+
+            input  += MBEDTLS_ARIA_BLOCKSIZE;
+            output += MBEDTLS_ARIA_BLOCKSIZE;
+            length -= MBEDTLS_ARIA_BLOCKSIZE;
+        }
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * ARIA-CFB128 buffer encryption/decryption
+ */
+int mbedtls_aria_crypt_cfb128( mbedtls_aria_context *ctx,
+                               int mode,
+                               size_t length,
+                               size_t *iv_off,
+                               unsigned char iv[MBEDTLS_ARIA_BLOCKSIZE],
+                               const unsigned char *input,
+                               unsigned char *output )
+{
+    unsigned char c;
+    size_t n;
+
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( mode == MBEDTLS_ARIA_ENCRYPT ||
+                       mode == MBEDTLS_ARIA_DECRYPT );
+    ARIA_VALIDATE_RET( length == 0 || input  != NULL );
+    ARIA_VALIDATE_RET( length == 0 || output != NULL );
+    ARIA_VALIDATE_RET( iv != NULL );
+    ARIA_VALIDATE_RET( iv_off != NULL );
+
+    n = *iv_off;
+
+    /* An overly large value of n can lead to an unlimited
+     * buffer overflow. Therefore, guard against this
+     * outside of parameter validation. */
+    if( n >= MBEDTLS_ARIA_BLOCKSIZE )
+        return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
+
+    if( mode == MBEDTLS_ARIA_DECRYPT )
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_aria_crypt_ecb( ctx, iv, iv );
+
+            c = *input++;
+            *output++ = c ^ iv[n];
+            iv[n] = c;
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+    else
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_aria_crypt_ecb( ctx, iv, iv );
+
+            iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+
+    *iv_off = n;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * ARIA-CTR buffer encryption/decryption
+ */
+int mbedtls_aria_crypt_ctr( mbedtls_aria_context *ctx,
+                            size_t length,
+                            size_t *nc_off,
+                            unsigned char nonce_counter[MBEDTLS_ARIA_BLOCKSIZE],
+                            unsigned char stream_block[MBEDTLS_ARIA_BLOCKSIZE],
+                            const unsigned char *input,
+                            unsigned char *output )
+{
+    int c, i;
+    size_t n;
+
+    ARIA_VALIDATE_RET( ctx != NULL );
+    ARIA_VALIDATE_RET( length == 0 || input  != NULL );
+    ARIA_VALIDATE_RET( length == 0 || output != NULL );
+    ARIA_VALIDATE_RET( nonce_counter != NULL );
+    ARIA_VALIDATE_RET( stream_block  != NULL );
+    ARIA_VALIDATE_RET( nc_off != NULL );
+
+    n = *nc_off;
+    /* An overly large value of n can lead to an unlimited
+     * buffer overflow. Therefore, guard against this
+     * outside of parameter validation. */
+    if( n >= MBEDTLS_ARIA_BLOCKSIZE )
+        return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
+
+    while( length-- )
+    {
+        if( n == 0 ) {
+            mbedtls_aria_crypt_ecb( ctx, nonce_counter,
+                                stream_block );
+
+            for( i = MBEDTLS_ARIA_BLOCKSIZE; i > 0; i-- )
+                if( ++nonce_counter[i - 1] != 0 )
+                    break;
+        }
+        c = *input++;
+        *output++ = (unsigned char)( c ^ stream_block[n] );
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *nc_off = n;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+#endif /* !MBEDTLS_ARIA_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/*
+ * Basic ARIA ECB test vectors from RFC 5794
+ */
+static const uint8_t aria_test1_ecb_key[32] =           // test key
+{
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,     // 128 bit
+    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,     // 192 bit
+    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F      // 256 bit
+};
+
+static const uint8_t aria_test1_ecb_pt[MBEDTLS_ARIA_BLOCKSIZE] =            // plaintext
+{
+    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // same for all
+    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF      // key sizes
+};
+
+static const uint8_t aria_test1_ecb_ct[3][MBEDTLS_ARIA_BLOCKSIZE] =         // ciphertext
+{
+    { 0xD7, 0x18, 0xFB, 0xD6, 0xAB, 0x64, 0x4C, 0x73,   // 128 bit
+      0x9D, 0xA9, 0x5F, 0x3B, 0xE6, 0x45, 0x17, 0x78 },
+    { 0x26, 0x44, 0x9C, 0x18, 0x05, 0xDB, 0xE7, 0xAA,   // 192 bit
+      0x25, 0xA4, 0x68, 0xCE, 0x26, 0x3A, 0x9E, 0x79 },
+    { 0xF9, 0x2B, 0xD7, 0xC7, 0x9F, 0xB7, 0x2E, 0x2F,   // 256 bit
+      0x2B, 0x8F, 0x80, 0xC1, 0x97, 0x2D, 0x24, 0xFC }
+};
+
+/*
+ * Mode tests from "Test Vectors for ARIA"  Version 1.0
+ * http://210.104.33.10/ARIA/doc/ARIA-testvector-e.pdf
+ */
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
+    defined(MBEDTLS_CIPHER_MODE_CTR))
+static const uint8_t aria_test2_key[32] =
+{
+    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // 128 bit
+    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,     // 192 bit
+    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff      // 256 bit
+};
+
+static const uint8_t aria_test2_pt[48] =
+{
+    0x11, 0x11, 0x11, 0x11, 0xaa, 0xaa, 0xaa, 0xaa,     // same for all
+    0x11, 0x11, 0x11, 0x11, 0xbb, 0xbb, 0xbb, 0xbb,
+    0x11, 0x11, 0x11, 0x11, 0xcc, 0xcc, 0xcc, 0xcc,
+    0x11, 0x11, 0x11, 0x11, 0xdd, 0xdd, 0xdd, 0xdd,
+    0x22, 0x22, 0x22, 0x22, 0xaa, 0xaa, 0xaa, 0xaa,
+    0x22, 0x22, 0x22, 0x22, 0xbb, 0xbb, 0xbb, 0xbb,
+};
+#endif
+
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB))
+static const uint8_t aria_test2_iv[MBEDTLS_ARIA_BLOCKSIZE] =
+{
+    0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78,     // same for CBC, CFB
+    0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0      // CTR has zero IV
+};
+#endif
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const uint8_t aria_test2_cbc_ct[3][48] =         // CBC ciphertext
+{
+    { 0x49, 0xd6, 0x18, 0x60, 0xb1, 0x49, 0x09, 0x10,   // 128-bit key
+      0x9c, 0xef, 0x0d, 0x22, 0xa9, 0x26, 0x81, 0x34,
+      0xfa, 0xdf, 0x9f, 0xb2, 0x31, 0x51, 0xe9, 0x64,
+      0x5f, 0xba, 0x75, 0x01, 0x8b, 0xdb, 0x15, 0x38,
+      0xb5, 0x33, 0x34, 0x63, 0x4b, 0xbf, 0x7d, 0x4c,
+      0xd4, 0xb5, 0x37, 0x70, 0x33, 0x06, 0x0c, 0x15 },
+    { 0xaf, 0xe6, 0xcf, 0x23, 0x97, 0x4b, 0x53, 0x3c,   // 192-bit key
+      0x67, 0x2a, 0x82, 0x62, 0x64, 0xea, 0x78, 0x5f,
+      0x4e, 0x4f, 0x7f, 0x78, 0x0d, 0xc7, 0xf3, 0xf1,
+      0xe0, 0x96, 0x2b, 0x80, 0x90, 0x23, 0x86, 0xd5,
+      0x14, 0xe9, 0xc3, 0xe7, 0x72, 0x59, 0xde, 0x92,
+      0xdd, 0x11, 0x02, 0xff, 0xab, 0x08, 0x6c, 0x1e },
+    { 0x52, 0x3a, 0x8a, 0x80, 0x6a, 0xe6, 0x21, 0xf1,   // 256-bit key
+      0x55, 0xfd, 0xd2, 0x8d, 0xbc, 0x34, 0xe1, 0xab,
+      0x7b, 0x9b, 0x42, 0x43, 0x2a, 0xd8, 0xb2, 0xef,
+      0xb9, 0x6e, 0x23, 0xb1, 0x3f, 0x0a, 0x6e, 0x52,
+      0xf3, 0x61, 0x85, 0xd5, 0x0a, 0xd0, 0x02, 0xc5,
+      0xf6, 0x01, 0xbe, 0xe5, 0x49, 0x3f, 0x11, 0x8b }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const uint8_t aria_test2_cfb_ct[3][48] =         // CFB ciphertext
+{
+    { 0x37, 0x20, 0xe5, 0x3b, 0xa7, 0xd6, 0x15, 0x38,   // 128-bit key
+      0x34, 0x06, 0xb0, 0x9f, 0x0a, 0x05, 0xa2, 0x00,
+      0xc0, 0x7c, 0x21, 0xe6, 0x37, 0x0f, 0x41, 0x3a,
+      0x5d, 0x13, 0x25, 0x00, 0xa6, 0x82, 0x85, 0x01,
+      0x7c, 0x61, 0xb4, 0x34, 0xc7, 0xb7, 0xca, 0x96,
+      0x85, 0xa5, 0x10, 0x71, 0x86, 0x1e, 0x4d, 0x4b },
+    { 0x41, 0x71, 0xf7, 0x19, 0x2b, 0xf4, 0x49, 0x54,   // 192-bit key
+      0x94, 0xd2, 0x73, 0x61, 0x29, 0x64, 0x0f, 0x5c,
+      0x4d, 0x87, 0xa9, 0xa2, 0x13, 0x66, 0x4c, 0x94,
+      0x48, 0x47, 0x7c, 0x6e, 0xcc, 0x20, 0x13, 0x59,
+      0x8d, 0x97, 0x66, 0x95, 0x2d, 0xd8, 0xc3, 0x86,
+      0x8f, 0x17, 0xe3, 0x6e, 0xf6, 0x6f, 0xd8, 0x4b },
+    { 0x26, 0x83, 0x47, 0x05, 0xb0, 0xf2, 0xc0, 0xe2,   // 256-bit key
+      0x58, 0x8d, 0x4a, 0x7f, 0x09, 0x00, 0x96, 0x35,
+      0xf2, 0x8b, 0xb9, 0x3d, 0x8c, 0x31, 0xf8, 0x70,
+      0xec, 0x1e, 0x0b, 0xdb, 0x08, 0x2b, 0x66, 0xfa,
+      0x40, 0x2d, 0xd9, 0xc2, 0x02, 0xbe, 0x30, 0x0c,
+      0x45, 0x17, 0xd1, 0x96, 0xb1, 0x4d, 0x4c, 0xe1 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const uint8_t aria_test2_ctr_ct[3][48] =         // CTR ciphertext
+{
+    { 0xac, 0x5d, 0x7d, 0xe8, 0x05, 0xa0, 0xbf, 0x1c,   // 128-bit key
+      0x57, 0xc8, 0x54, 0x50, 0x1a, 0xf6, 0x0f, 0xa1,
+      0x14, 0x97, 0xe2, 0xa3, 0x45, 0x19, 0xde, 0xa1,
+      0x56, 0x9e, 0x91, 0xe5, 0xb5, 0xcc, 0xae, 0x2f,
+      0xf3, 0xbf, 0xa1, 0xbf, 0x97, 0x5f, 0x45, 0x71,
+      0xf4, 0x8b, 0xe1, 0x91, 0x61, 0x35, 0x46, 0xc3 },
+    { 0x08, 0x62, 0x5c, 0xa8, 0xfe, 0x56, 0x9c, 0x19,   // 192-bit key
+      0xba, 0x7a, 0xf3, 0x76, 0x0a, 0x6e, 0xd1, 0xce,
+      0xf4, 0xd1, 0x99, 0x26, 0x3e, 0x99, 0x9d, 0xde,
+      0x14, 0x08, 0x2d, 0xbb, 0xa7, 0x56, 0x0b, 0x79,
+      0xa4, 0xc6, 0xb4, 0x56, 0xb8, 0x70, 0x7d, 0xce,
+      0x75, 0x1f, 0x98, 0x54, 0xf1, 0x88, 0x93, 0xdf },
+    { 0x30, 0x02, 0x6c, 0x32, 0x96, 0x66, 0x14, 0x17,   // 256-bit key
+      0x21, 0x17, 0x8b, 0x99, 0xc0, 0xa1, 0xf1, 0xb2,
+      0xf0, 0x69, 0x40, 0x25, 0x3f, 0x7b, 0x30, 0x89,
+      0xe2, 0xa3, 0x0e, 0xa8, 0x6a, 0xa3, 0xc8, 0x8f,
+      0x59, 0x40, 0xf0, 0x5a, 0xd7, 0xee, 0x41, 0xd7,
+      0x13, 0x47, 0xbb, 0x72, 0x61, 0xe3, 0x48, 0xf1 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#define ARIA_SELF_TEST_IF_FAIL              \
+        {                                   \
+            if( verbose )                   \
+                mbedtls_printf( "failed\n" );       \
+            return( 1 );                    \
+        } else {                            \
+            if( verbose )                   \
+                mbedtls_printf( "passed\n" );       \
+        }
+
+/*
+ * Checkup routine
+ */
+int mbedtls_aria_self_test( int verbose )
+{
+    int i;
+    uint8_t blk[MBEDTLS_ARIA_BLOCKSIZE];
+    mbedtls_aria_context ctx;
+
+#if (defined(MBEDTLS_CIPHER_MODE_CFB) || defined(MBEDTLS_CIPHER_MODE_CTR))
+    size_t j;
+#endif
+
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) || \
+     defined(MBEDTLS_CIPHER_MODE_CFB) || \
+     defined(MBEDTLS_CIPHER_MODE_CTR))
+    uint8_t buf[48], iv[MBEDTLS_ARIA_BLOCKSIZE];
+#endif
+
+    /*
+     * Test set 1
+     */
+    for( i = 0; i < 3; i++ )
+    {
+        /* test ECB encryption */
+        if( verbose )
+            mbedtls_printf( "  ARIA-ECB-%d (enc): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test1_ecb_key, 128 + 64 * i );
+        mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_pt, blk );
+        if( memcmp( blk, aria_test1_ecb_ct[i], MBEDTLS_ARIA_BLOCKSIZE ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+
+        /* test ECB decryption */
+        if( verbose )
+            mbedtls_printf( "  ARIA-ECB-%d (dec): ", 128 + 64 * i );
+        mbedtls_aria_setkey_dec( &ctx, aria_test1_ecb_key, 128 + 64 * i );
+        mbedtls_aria_crypt_ecb( &ctx, aria_test1_ecb_ct[i], blk );
+        if( memcmp( blk, aria_test1_ecb_pt, MBEDTLS_ARIA_BLOCKSIZE ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+    }
+    if( verbose )
+        mbedtls_printf( "\n" );
+
+    /*
+     * Test set 2
+     */
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    for( i = 0; i < 3; i++ )
+    {
+        /* Test CBC encryption */
+        if( verbose )
+            mbedtls_printf( "  ARIA-CBC-%d (enc): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
+        memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
+        memset( buf, 0x55, sizeof( buf ) );
+        mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, iv,
+            aria_test2_pt, buf );
+        if( memcmp( buf, aria_test2_cbc_ct[i], 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+
+        /* Test CBC decryption */
+        if( verbose )
+            mbedtls_printf( "  ARIA-CBC-%d (dec): ", 128 + 64 * i );
+        mbedtls_aria_setkey_dec( &ctx, aria_test2_key, 128 + 64 * i );
+        memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
+        memset( buf, 0xAA, sizeof( buf ) );
+        mbedtls_aria_crypt_cbc( &ctx, MBEDTLS_ARIA_DECRYPT, 48, iv,
+            aria_test2_cbc_ct[i], buf );
+        if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+    }
+    if( verbose )
+        mbedtls_printf( "\n" );
+
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    for( i = 0; i < 3; i++ )
+    {
+        /* Test CFB encryption */
+        if( verbose )
+            mbedtls_printf( "  ARIA-CFB-%d (enc): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
+        memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
+        memset( buf, 0x55, sizeof( buf ) );
+        j = 0;
+        mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_ENCRYPT, 48, &j, iv,
+            aria_test2_pt, buf );
+        if( memcmp( buf, aria_test2_cfb_ct[i], 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+
+        /* Test CFB decryption */
+        if( verbose )
+            mbedtls_printf( "  ARIA-CFB-%d (dec): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
+        memcpy( iv, aria_test2_iv, MBEDTLS_ARIA_BLOCKSIZE );
+        memset( buf, 0xAA, sizeof( buf ) );
+        j = 0;
+        mbedtls_aria_crypt_cfb128( &ctx, MBEDTLS_ARIA_DECRYPT, 48, &j,
+            iv, aria_test2_cfb_ct[i], buf );
+        if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+    }
+    if( verbose )
+        mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    for( i = 0; i < 3; i++ )
+    {
+        /* Test CTR encryption */
+        if( verbose )
+            mbedtls_printf( "  ARIA-CTR-%d (enc): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
+        memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE );                    // IV = 0
+        memset( buf, 0x55, sizeof( buf ) );
+        j = 0;
+        mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
+            aria_test2_pt, buf );
+        if( memcmp( buf, aria_test2_ctr_ct[i], 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+
+        /* Test CTR decryption */
+        if( verbose )
+            mbedtls_printf( "  ARIA-CTR-%d (dec): ", 128 + 64 * i );
+        mbedtls_aria_setkey_enc( &ctx, aria_test2_key, 128 + 64 * i );
+        memset( iv, 0, MBEDTLS_ARIA_BLOCKSIZE );                    // IV = 0
+        memset( buf, 0xAA, sizeof( buf ) );
+        j = 0;
+        mbedtls_aria_crypt_ctr( &ctx, 48, &j, iv, blk,
+            aria_test2_ctr_ct[i], buf );
+        if( memcmp( buf, aria_test2_pt, 48 ) != 0 )
+            ARIA_SELF_TEST_IF_FAIL;
+    }
+    if( verbose )
+        mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_ARIA_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/asn1parse.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/asn1parse.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/asn1parse.c	(revision 398)
@@ -0,0 +1,389 @@
+/*
+ *  Generic ASN.1 parsing
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+
+#include "mbedtls/asn1.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+/*
+ * ASN.1 DER decoding routines
+ */
+int mbedtls_asn1_get_len( unsigned char **p,
+                  const unsigned char *end,
+                  size_t *len )
+{
+    if( ( end - *p ) < 1 )
+        return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    if( ( **p & 0x80 ) == 0 )
+        *len = *(*p)++;
+    else
+    {
+        switch( **p & 0x7F )
+        {
+        case 1:
+            if( ( end - *p ) < 2 )
+                return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+            *len = (*p)[1];
+            (*p) += 2;
+            break;
+
+        case 2:
+            if( ( end - *p ) < 3 )
+                return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+            *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2];
+            (*p) += 3;
+            break;
+
+        case 3:
+            if( ( end - *p ) < 4 )
+                return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+            *len = ( (size_t)(*p)[1] << 16 ) |
+                   ( (size_t)(*p)[2] << 8  ) | (*p)[3];
+            (*p) += 4;
+            break;
+
+        case 4:
+            if( ( end - *p ) < 5 )
+                return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+            *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) |
+                   ( (size_t)(*p)[3] << 8  ) |           (*p)[4];
+            (*p) += 5;
+            break;
+
+        default:
+            return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+        }
+    }
+
+    if( *len > (size_t) ( end - *p ) )
+        return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    return( 0 );
+}
+
+int mbedtls_asn1_get_tag( unsigned char **p,
+                  const unsigned char *end,
+                  size_t *len, int tag )
+{
+    if( ( end - *p ) < 1 )
+        return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    if( **p != tag )
+        return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+    (*p)++;
+
+    return( mbedtls_asn1_get_len( p, end, len ) );
+}
+
+int mbedtls_asn1_get_bool( unsigned char **p,
+                   const unsigned char *end,
+                   int *val )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
+        return( ret );
+
+    if( len != 1 )
+        return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+
+    *val = ( **p != 0 ) ? 1 : 0;
+    (*p)++;
+
+    return( 0 );
+}
+
+int mbedtls_asn1_get_int( unsigned char **p,
+                  const unsigned char *end,
+                  int *val )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
+        return( ret );
+
+    if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 )
+        return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+
+    *val = 0;
+
+    while( len-- > 0 )
+    {
+        *val = ( *val << 8 ) | **p;
+        (*p)++;
+    }
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_BIGNUM_C)
+int mbedtls_asn1_get_mpi( unsigned char **p,
+                  const unsigned char *end,
+                  mbedtls_mpi *X )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
+        return( ret );
+
+    ret = mbedtls_mpi_read_binary( X, *p, len );
+
+    *p += len;
+
+    return( ret );
+}
+#endif /* MBEDTLS_BIGNUM_C */
+
+int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
+                        mbedtls_asn1_bitstring *bs)
+{
+    int ret;
+
+    /* Certificate type is a single byte bitstring */
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
+        return( ret );
+
+    /* Check length, subtract one for actual bit string length */
+    if( bs->len < 1 )
+        return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+    bs->len -= 1;
+
+    /* Get number of unused bits, ensure unused bits <= 7 */
+    bs->unused_bits = **p;
+    if( bs->unused_bits > 7 )
+        return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+    (*p)++;
+
+    /* Get actual bitstring */
+    bs->p = *p;
+    *p += bs->len;
+
+    if( *p != end )
+        return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+/*
+ * Get a bit string without unused bits
+ */
+int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
+                             size_t *len )
+{
+    int ret;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
+        return( ret );
+
+    if( (*len)-- < 2 || *(*p)++ != 0 )
+        return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+
+    return( 0 );
+}
+
+
+
+/*
+ *  Parses and splits an ASN.1 "SEQUENCE OF <tag>"
+ */
+int mbedtls_asn1_get_sequence_of( unsigned char **p,
+                          const unsigned char *end,
+                          mbedtls_asn1_sequence *cur,
+                          int tag)
+{
+    int ret;
+    size_t len;
+    mbedtls_asn1_buf *buf;
+
+    /* Get main sequence tag */
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( ret );
+
+    if( *p + len != end )
+        return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    while( *p < end )
+    {
+        buf = &(cur->buf);
+        buf->tag = **p;
+
+        if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
+            return( ret );
+
+        buf->p = *p;
+        *p += buf->len;
+
+        /* Allocate and assign next pointer */
+        if( *p < end )
+        {
+            cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1,
+                                            sizeof( mbedtls_asn1_sequence ) );
+
+            if( cur->next == NULL )
+                return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
+
+            cur = cur->next;
+        }
+    }
+
+    /* Set final sequence entry's next pointer to NULL */
+    cur->next = NULL;
+
+    if( *p != end )
+        return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+int mbedtls_asn1_get_alg( unsigned char **p,
+                  const unsigned char *end,
+                  mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( ret );
+
+    if( ( end - *p ) < 1 )
+        return( MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    alg->tag = **p;
+    end = *p + len;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 )
+        return( ret );
+
+    alg->p = *p;
+    *p += alg->len;
+
+    if( *p == end )
+    {
+        mbedtls_platform_zeroize( params, sizeof(mbedtls_asn1_buf) );
+        return( 0 );
+    }
+
+    params->tag = **p;
+    (*p)++;
+
+    if( ( ret = mbedtls_asn1_get_len( p, end, &params->len ) ) != 0 )
+        return( ret );
+
+    params->p = *p;
+    *p += params->len;
+
+    if( *p != end )
+        return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+int mbedtls_asn1_get_alg_null( unsigned char **p,
+                       const unsigned char *end,
+                       mbedtls_asn1_buf *alg )
+{
+    int ret;
+    mbedtls_asn1_buf params;
+
+    memset( &params, 0, sizeof(mbedtls_asn1_buf) );
+
+    if( ( ret = mbedtls_asn1_get_alg( p, end, alg, &params ) ) != 0 )
+        return( ret );
+
+    if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 )
+        return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+
+    return( 0 );
+}
+
+void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur )
+{
+    if( cur == NULL )
+        return;
+
+    mbedtls_free( cur->oid.p );
+    mbedtls_free( cur->val.p );
+
+    mbedtls_platform_zeroize( cur, sizeof( mbedtls_asn1_named_data ) );
+}
+
+void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head )
+{
+    mbedtls_asn1_named_data *cur;
+
+    while( ( cur = *head ) != NULL )
+    {
+        *head = cur->next;
+        mbedtls_asn1_free_named_data( cur );
+        mbedtls_free( cur );
+    }
+}
+
+mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
+                                       const char *oid, size_t len )
+{
+    while( list != NULL )
+    {
+        if( list->oid.len == len &&
+            memcmp( list->oid.p, oid, len ) == 0 )
+        {
+            break;
+        }
+
+        list = list->next;
+    }
+
+    return( list );
+}
+
+#endif /* MBEDTLS_ASN1_PARSE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/asn1write.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/asn1write.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/asn1write.c	(revision 398)
@@ -0,0 +1,421 @@
+/*
+ * ASN.1 buffer writing functionality
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ASN1_WRITE_C)
+
+#include "mbedtls/asn1write.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
+{
+    if( len < 0x80 )
+    {
+        if( *p - start < 1 )
+            return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+        *--(*p) = (unsigned char) len;
+        return( 1 );
+    }
+
+    if( len <= 0xFF )
+    {
+        if( *p - start < 2 )
+            return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+        *--(*p) = (unsigned char) len;
+        *--(*p) = 0x81;
+        return( 2 );
+    }
+
+    if( len <= 0xFFFF )
+    {
+        if( *p - start < 3 )
+            return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+        *--(*p) = ( len       ) & 0xFF;
+        *--(*p) = ( len >>  8 ) & 0xFF;
+        *--(*p) = 0x82;
+        return( 3 );
+    }
+
+    if( len <= 0xFFFFFF )
+    {
+        if( *p - start < 4 )
+            return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+        *--(*p) = ( len       ) & 0xFF;
+        *--(*p) = ( len >>  8 ) & 0xFF;
+        *--(*p) = ( len >> 16 ) & 0xFF;
+        *--(*p) = 0x83;
+        return( 4 );
+    }
+
+#if SIZE_MAX > 0xFFFFFFFF
+    if( len <= 0xFFFFFFFF )
+#endif
+    {
+        if( *p - start < 5 )
+            return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+        *--(*p) = ( len       ) & 0xFF;
+        *--(*p) = ( len >>  8 ) & 0xFF;
+        *--(*p) = ( len >> 16 ) & 0xFF;
+        *--(*p) = ( len >> 24 ) & 0xFF;
+        *--(*p) = 0x84;
+        return( 5 );
+    }
+
+#if SIZE_MAX > 0xFFFFFFFF
+    return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+#endif
+}
+
+int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
+{
+    if( *p - start < 1 )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    *--(*p) = tag;
+
+    return( 1 );
+}
+
+int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
+                           const unsigned char *buf, size_t size )
+{
+    size_t len = 0;
+
+    if( *p < start || (size_t)( *p - start ) < size )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    len = size;
+    (*p) -= len;
+    memcpy( *p, buf, len );
+
+    return( (int) len );
+}
+
+#if defined(MBEDTLS_BIGNUM_C)
+int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X )
+{
+    int ret;
+    size_t len = 0;
+
+    // Write the MPI
+    //
+    len = mbedtls_mpi_size( X );
+
+    if( *p < start || (size_t)( *p - start ) < len )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    (*p) -= len;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) );
+
+    // DER format assumes 2s complement for numbers, so the leftmost bit
+    // should be 0 for positive numbers and 1 for negative numbers.
+    //
+    if( X->s ==1 && **p & 0x80 )
+    {
+        if( *p - start < 1 )
+            return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+        *--(*p) = 0x00;
+        len += 1;
+    }
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
+
+    ret = (int) len;
+
+cleanup:
+    return( ret );
+}
+#endif /* MBEDTLS_BIGNUM_C */
+
+int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start )
+{
+    int ret;
+    size_t len = 0;
+
+    // Write NULL
+    //
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) );
+
+    return( (int) len );
+}
+
+int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
+                    const char *oid, size_t oid_len )
+{
+    int ret;
+    size_t len = 0;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
+                                  (const unsigned char *) oid, oid_len ) );
+    MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
+
+    return( (int) len );
+}
+
+int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
+                                     const char *oid, size_t oid_len,
+                                     size_t par_len )
+{
+    int ret;
+    size_t len = 0;
+
+    if( par_len == 0 )
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) );
+    else
+        len += par_len;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
+                                       MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
+
+    return( (int) len );
+}
+
+int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean )
+{
+    int ret;
+    size_t len = 0;
+
+    if( *p - start < 1 )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    *--(*p) = (boolean) ? 255 : 0;
+    len++;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) );
+
+    return( (int) len );
+}
+
+int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
+{
+    int ret;
+    size_t len = 0;
+
+    if( *p - start < 1 )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    len += 1;
+    *--(*p) = val;
+
+    if( val > 0 && **p & 0x80 )
+    {
+        if( *p - start < 1 )
+            return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+        *--(*p) = 0x00;
+        len += 1;
+    }
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) );
+
+    return( (int) len );
+}
+
+int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag,
+    const char *text, size_t text_len )
+{
+    int ret;
+    size_t len = 0;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
+        (const unsigned char *) text, text_len ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) );
+
+    return( (int) len );
+}
+
+int mbedtls_asn1_write_utf8_string( unsigned char **p, unsigned char *start,
+    const char *text, size_t text_len )
+{
+    return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len) );
+}
+
+int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start,
+                                 const char *text, size_t text_len )
+{
+    return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, text_len) );
+}
+
+int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
+                           const char *text, size_t text_len )
+{
+    return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) );
+}
+
+int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
+                          const unsigned char *buf, size_t bits )
+{
+    int ret;
+    size_t len = 0;
+    size_t unused_bits, byte_len;
+
+    byte_len = ( bits + 7 ) / 8;
+    unused_bits = ( byte_len * 8 ) - bits;
+
+    if( *p < start || (size_t)( *p - start ) < byte_len + 1 )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    len = byte_len + 1;
+
+    /* Write the bitstring. Ensure the unused bits are zeroed */
+    if( byte_len > 0 )
+    {
+        byte_len--;
+        *--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 );
+        ( *p ) -= byte_len;
+        memcpy( *p, buf, byte_len );
+    }
+
+    /* Write unused bits */
+    *--( *p ) = (unsigned char)unused_bits;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );
+
+    return( (int) len );
+}
+
+int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
+                             const unsigned char *buf, size_t size )
+{
+    int ret;
+    size_t len = 0;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
+
+    return( (int) len );
+}
+
+
+/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(),
+ * which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */
+static mbedtls_asn1_named_data *asn1_find_named_data(
+                                               mbedtls_asn1_named_data *list,
+                                               const char *oid, size_t len )
+{
+    while( list != NULL )
+    {
+        if( list->oid.len == len &&
+            memcmp( list->oid.p, oid, len ) == 0 )
+        {
+            break;
+        }
+
+        list = list->next;
+    }
+
+    return( list );
+}
+
+mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
+                                        mbedtls_asn1_named_data **head,
+                                        const char *oid, size_t oid_len,
+                                        const unsigned char *val,
+                                        size_t val_len )
+{
+    mbedtls_asn1_named_data *cur;
+
+    if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
+    {
+        // Add new entry if not present yet based on OID
+        //
+        cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1,
+                                            sizeof(mbedtls_asn1_named_data) );
+        if( cur == NULL )
+            return( NULL );
+
+        cur->oid.len = oid_len;
+        cur->oid.p = mbedtls_calloc( 1, oid_len );
+        if( cur->oid.p == NULL )
+        {
+            mbedtls_free( cur );
+            return( NULL );
+        }
+
+        memcpy( cur->oid.p, oid, oid_len );
+
+        cur->val.len = val_len;
+        cur->val.p = mbedtls_calloc( 1, val_len );
+        if( cur->val.p == NULL )
+        {
+            mbedtls_free( cur->oid.p );
+            mbedtls_free( cur );
+            return( NULL );
+        }
+
+        cur->next = *head;
+        *head = cur;
+    }
+    else if( cur->val.len < val_len )
+    {
+        /*
+         * Enlarge existing value buffer if needed
+         * Preserve old data until the allocation succeeded, to leave list in
+         * a consistent state in case allocation fails.
+         */
+        void *p = mbedtls_calloc( 1, val_len );
+        if( p == NULL )
+            return( NULL );
+
+        mbedtls_free( cur->val.p );
+        cur->val.p = p;
+        cur->val.len = val_len;
+    }
+
+    if( val != NULL )
+        memcpy( cur->val.p, val, val_len );
+
+    return( cur );
+}
+#endif /* MBEDTLS_ASN1_WRITE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/base64.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/base64.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/base64.c	(revision 398)
@@ -0,0 +1,293 @@
+/*
+ *  RFC 1521 base64 encoding/decoding
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_BASE64_C)
+
+#include "mbedtls/base64.h"
+
+#include <stdint.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#include <string.h>
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+static const unsigned char base64_enc_map[64] =
+{
+    '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', '+', '/'
+};
+
+static const unsigned char base64_dec_map[128] =
+{
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+    127, 127, 127,  62, 127, 127, 127,  63,  52,  53,
+     54,  55,  56,  57,  58,  59,  60,  61, 127, 127,
+    127,  64, 127, 127, 127,   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, 127, 127, 127, 127, 127, 127,  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, 127, 127, 127, 127, 127
+};
+
+#define BASE64_SIZE_T_MAX   ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
+
+/*
+ * Encode a buffer into base64 format
+ */
+int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
+                   const unsigned char *src, size_t slen )
+{
+    size_t i, n;
+    int C1, C2, C3;
+    unsigned char *p;
+
+    if( slen == 0 )
+    {
+        *olen = 0;
+        return( 0 );
+    }
+
+    n = slen / 3 + ( slen % 3 != 0 );
+
+    if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
+    {
+        *olen = BASE64_SIZE_T_MAX;
+        return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
+    }
+
+    n *= 4;
+
+    if( ( dlen < n + 1 ) || ( NULL == dst ) )
+    {
+        *olen = n + 1;
+        return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
+    }
+
+    n = ( slen / 3 ) * 3;
+
+    for( i = 0, p = dst; i < n; i += 3 )
+    {
+        C1 = *src++;
+        C2 = *src++;
+        C3 = *src++;
+
+        *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
+        *p++ = base64_enc_map[(((C1 &  3) << 4) + (C2 >> 4)) & 0x3F];
+        *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
+        *p++ = base64_enc_map[C3 & 0x3F];
+    }
+
+    if( i < slen )
+    {
+        C1 = *src++;
+        C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
+
+        *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
+        *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
+
+        if( ( i + 1 ) < slen )
+             *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
+        else *p++ = '=';
+
+        *p++ = '=';
+    }
+
+    *olen = p - dst;
+    *p = 0;
+
+    return( 0 );
+}
+
+/*
+ * Decode a base64-formatted buffer
+ */
+int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
+                   const unsigned char *src, size_t slen )
+{
+    size_t i, n;
+    uint32_t j, x;
+    unsigned char *p;
+
+    /* First pass: check for validity and get output length */
+    for( i = n = j = 0; i < slen; i++ )
+    {
+        /* Skip spaces before checking for EOL */
+        x = 0;
+        while( i < slen && src[i] == ' ' )
+        {
+            ++i;
+            ++x;
+        }
+
+        /* Spaces at end of buffer are OK */
+        if( i == slen )
+            break;
+
+        if( ( slen - i ) >= 2 &&
+            src[i] == '\r' && src[i + 1] == '\n' )
+            continue;
+
+        if( src[i] == '\n' )
+            continue;
+
+        /* Space inside a line is an error */
+        if( x != 0 )
+            return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
+
+        if( src[i] == '=' && ++j > 2 )
+            return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
+
+        if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
+            return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
+
+        if( base64_dec_map[src[i]] < 64 && j != 0 )
+            return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
+
+        n++;
+    }
+
+    if( n == 0 )
+    {
+        *olen = 0;
+        return( 0 );
+    }
+
+    /* The following expression is to calculate the following formula without
+     * risk of integer overflow in n:
+     *     n = ( ( n * 6 ) + 7 ) >> 3;
+     */
+    n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
+    n -= j;
+
+    if( dst == NULL || dlen < n )
+    {
+        *olen = n;
+        return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
+    }
+
+   for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
+   {
+        if( *src == '\r' || *src == '\n' || *src == ' ' )
+            continue;
+
+        j -= ( base64_dec_map[*src] == 64 );
+        x  = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
+
+        if( ++n == 4 )
+        {
+            n = 0;
+            if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
+            if( j > 1 ) *p++ = (unsigned char)( x >>  8 );
+            if( j > 2 ) *p++ = (unsigned char)( x       );
+        }
+    }
+
+    *olen = p - dst;
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SELF_TEST)
+
+static const unsigned char base64_test_dec[64] =
+{
+    0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
+    0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
+    0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
+    0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
+    0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
+    0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
+    0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
+    0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
+};
+
+static const unsigned char base64_test_enc[] =
+    "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
+    "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
+
+/*
+ * Checkup routine
+ */
+int mbedtls_base64_self_test( int verbose )
+{
+    size_t len;
+    const unsigned char *src;
+    unsigned char buffer[128];
+
+    if( verbose != 0 )
+        mbedtls_printf( "  Base64 encoding test: " );
+
+    src = base64_test_dec;
+
+    if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
+         memcmp( base64_test_enc, buffer, 88 ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        return( 1 );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n  Base64 decoding test: " );
+
+    src = base64_test_enc;
+
+    if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
+         memcmp( base64_test_dec, buffer, 64 ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        return( 1 );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n\n" );
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_BASE64_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/bignum.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/bignum.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/bignum.c	(revision 398)
@@ -0,0 +1,2750 @@
+/*
+ *  Multi-precision integer library
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ *  The following sources were referenced in the design of this Multi-precision
+ *  Integer library:
+ *
+ *  [1] Handbook of Applied Cryptography - 1997
+ *      Menezes, van Oorschot and Vanstone
+ *
+ *  [2] Multi-Precision Math
+ *      Tom St Denis
+ *      https://github.com/libtom/libtommath/blob/develop/tommath.pdf
+ *
+ *  [3] GNU Multi-Precision Arithmetic Library
+ *      https://gmplib.org/manual/index.html
+ *
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#include "mbedtls/bignum.h"
+#include "mbedtls/bn_mul.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_printf     printf
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#define MPI_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
+#define MPI_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#define ciL    (sizeof(mbedtls_mpi_uint))         /* chars in limb  */
+#define biL    (ciL << 3)               /* bits  in limb  */
+#define biH    (ciL << 2)               /* half limb size */
+
+#define MPI_SIZE_T_MAX  ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
+
+/*
+ * Convert between bits/chars and number of limbs
+ * Divide first in order to avoid potential overflows
+ */
+#define BITS_TO_LIMBS(i)  ( (i) / biL + ( (i) % biL != 0 ) )
+#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
+
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n )
+{
+    mbedtls_platform_zeroize( v, ciL * n );
+}
+
+/*
+ * Initialize one MPI
+ */
+void mbedtls_mpi_init( mbedtls_mpi *X )
+{
+    MPI_VALIDATE( X != NULL );
+
+    X->s = 1;
+    X->n = 0;
+    X->p = NULL;
+}
+
+/*
+ * Unallocate one MPI
+ */
+void mbedtls_mpi_free( mbedtls_mpi *X )
+{
+    if( X == NULL )
+        return;
+
+    if( X->p != NULL )
+    {
+        mbedtls_mpi_zeroize( X->p, X->n );
+        mbedtls_free( X->p );
+    }
+
+    X->s = 1;
+    X->n = 0;
+    X->p = NULL;
+}
+
+/*
+ * Enlarge to the specified number of limbs
+ */
+int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
+{
+    mbedtls_mpi_uint *p;
+    MPI_VALIDATE_RET( X != NULL );
+
+    if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
+        return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
+
+    if( X->n < nblimbs )
+    {
+        if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL )
+            return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
+
+        if( X->p != NULL )
+        {
+            memcpy( p, X->p, X->n * ciL );
+            mbedtls_mpi_zeroize( X->p, X->n );
+            mbedtls_free( X->p );
+        }
+
+        X->n = nblimbs;
+        X->p = p;
+    }
+
+    return( 0 );
+}
+
+/*
+ * Resize down as much as possible,
+ * while keeping at least the specified number of limbs
+ */
+int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
+{
+    mbedtls_mpi_uint *p;
+    size_t i;
+    MPI_VALIDATE_RET( X != NULL );
+
+    if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
+        return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
+
+    /* Actually resize up in this case */
+    if( X->n <= nblimbs )
+        return( mbedtls_mpi_grow( X, nblimbs ) );
+
+    for( i = X->n - 1; i > 0; i-- )
+        if( X->p[i] != 0 )
+            break;
+    i++;
+
+    if( i < nblimbs )
+        i = nblimbs;
+
+    if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL )
+        return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
+
+    if( X->p != NULL )
+    {
+        memcpy( p, X->p, i * ciL );
+        mbedtls_mpi_zeroize( X->p, X->n );
+        mbedtls_free( X->p );
+    }
+
+    X->n = i;
+    X->p = p;
+
+    return( 0 );
+}
+
+/*
+ * Copy the contents of Y into X
+ */
+int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
+{
+    int ret = 0;
+    size_t i;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+
+    if( X == Y )
+        return( 0 );
+
+    if( Y->p == NULL )
+    {
+        mbedtls_mpi_free( X );
+        return( 0 );
+    }
+
+    for( i = Y->n - 1; i > 0; i-- )
+        if( Y->p[i] != 0 )
+            break;
+    i++;
+
+    X->s = Y->s;
+
+    if( X->n < i )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
+    }
+    else
+    {
+        memset( X->p + i, 0, ( X->n - i ) * ciL );
+    }
+
+    memcpy( X->p, Y->p, i * ciL );
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Swap the contents of X and Y
+ */
+void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
+{
+    mbedtls_mpi T;
+    MPI_VALIDATE( X != NULL );
+    MPI_VALIDATE( Y != NULL );
+
+    memcpy( &T,  X, sizeof( mbedtls_mpi ) );
+    memcpy(  X,  Y, sizeof( mbedtls_mpi ) );
+    memcpy(  Y, &T, sizeof( mbedtls_mpi ) );
+}
+
+/*
+ * Conditionally assign X = Y, without leaking information
+ * about whether the assignment was made or not.
+ * (Leaking information about the respective sizes of X and Y is ok however.)
+ */
+int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
+{
+    int ret = 0;
+    size_t i;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+
+    /* make sure assign is 0 or 1 in a time-constant manner */
+    assign = (assign | (unsigned char)-assign) >> 7;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
+
+    X->s = X->s * ( 1 - assign ) + Y->s * assign;
+
+    for( i = 0; i < Y->n; i++ )
+        X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
+
+    for( ; i < X->n; i++ )
+        X->p[i] *= ( 1 - assign );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Conditionally swap X and Y, without leaking information
+ * about whether the swap was made or not.
+ * Here it is not ok to simply swap the pointers, which whould lead to
+ * different memory access patterns when X and Y are used afterwards.
+ */
+int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
+{
+    int ret, s;
+    size_t i;
+    mbedtls_mpi_uint tmp;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+
+    if( X == Y )
+        return( 0 );
+
+    /* make sure swap is 0 or 1 in a time-constant manner */
+    swap = (swap | (unsigned char)-swap) >> 7;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
+
+    s = X->s;
+    X->s = X->s * ( 1 - swap ) + Y->s * swap;
+    Y->s = Y->s * ( 1 - swap ) +    s * swap;
+
+
+    for( i = 0; i < X->n; i++ )
+    {
+        tmp = X->p[i];
+        X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
+        Y->p[i] = Y->p[i] * ( 1 - swap ) +     tmp * swap;
+    }
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Set value from integer
+ */
+int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
+{
+    int ret;
+    MPI_VALIDATE_RET( X != NULL );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
+    memset( X->p, 0, X->n * ciL );
+
+    X->p[0] = ( z < 0 ) ? -z : z;
+    X->s    = ( z < 0 ) ? -1 : 1;
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Get a specific bit
+ */
+int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
+{
+    MPI_VALIDATE_RET( X != NULL );
+
+    if( X->n * biL <= pos )
+        return( 0 );
+
+    return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
+}
+
+/* Get a specific byte, without range checks. */
+#define GET_BYTE( X, i )                                \
+    ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
+
+/*
+ * Set a bit to a specific value of 0 or 1
+ */
+int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val )
+{
+    int ret = 0;
+    size_t off = pos / biL;
+    size_t idx = pos % biL;
+    MPI_VALIDATE_RET( X != NULL );
+
+    if( val != 0 && val != 1 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    if( X->n * biL <= pos )
+    {
+        if( val == 0 )
+            return( 0 );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) );
+    }
+
+    X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx );
+    X->p[off] |= (mbedtls_mpi_uint) val << idx;
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Return the number of less significant zero-bits
+ */
+size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
+{
+    size_t i, j, count = 0;
+    MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 );
+
+    for( i = 0; i < X->n; i++ )
+        for( j = 0; j < biL; j++, count++ )
+            if( ( ( X->p[i] >> j ) & 1 ) != 0 )
+                return( count );
+
+    return( 0 );
+}
+
+/*
+ * Count leading zero bits in a given integer
+ */
+static size_t mbedtls_clz( const mbedtls_mpi_uint x )
+{
+    size_t j;
+    mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
+
+    for( j = 0; j < biL; j++ )
+    {
+        if( x & mask ) break;
+
+        mask >>= 1;
+    }
+
+    return j;
+}
+
+/*
+ * Return the number of bits
+ */
+size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
+{
+    size_t i, j;
+
+    if( X->n == 0 )
+        return( 0 );
+
+    for( i = X->n - 1; i > 0; i-- )
+        if( X->p[i] != 0 )
+            break;
+
+    j = biL - mbedtls_clz( X->p[i] );
+
+    return( ( i * biL ) + j );
+}
+
+/*
+ * Return the total size in bytes
+ */
+size_t mbedtls_mpi_size( const mbedtls_mpi *X )
+{
+    return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 );
+}
+
+/*
+ * Convert an ASCII character to digit value
+ */
+static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c )
+{
+    *d = 255;
+
+    if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
+    if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
+    if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
+
+    if( *d >= (mbedtls_mpi_uint) radix )
+        return( MBEDTLS_ERR_MPI_INVALID_CHARACTER );
+
+    return( 0 );
+}
+
+/*
+ * Import from an ASCII string
+ */
+int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
+{
+    int ret;
+    size_t i, j, slen, n;
+    mbedtls_mpi_uint d;
+    mbedtls_mpi T;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( s != NULL );
+
+    if( radix < 2 || radix > 16 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    mbedtls_mpi_init( &T );
+
+    slen = strlen( s );
+
+    if( radix == 16 )
+    {
+        if( slen > MPI_SIZE_T_MAX >> 2 )
+            return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+        n = BITS_TO_LIMBS( slen << 2 );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+
+        for( i = slen, j = 0; i > 0; i--, j++ )
+        {
+            if( i == 1 && s[i - 1] == '-' )
+            {
+                X->s = -1;
+                break;
+            }
+
+            MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
+            X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
+        }
+    }
+    else
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+
+        for( i = 0; i < slen; i++ )
+        {
+            if( i == 0 && s[i] == '-' )
+            {
+                X->s = -1;
+                continue;
+            }
+
+            MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) );
+
+            if( X->s == 1 )
+            {
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
+            }
+            else
+            {
+                MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, &T, d ) );
+            }
+        }
+    }
+
+cleanup:
+
+    mbedtls_mpi_free( &T );
+
+    return( ret );
+}
+
+/*
+ * Helper to write the digits high-order first.
+ */
+static int mpi_write_hlp( mbedtls_mpi *X, int radix,
+                          char **p, const size_t buflen )
+{
+    int ret;
+    mbedtls_mpi_uint r;
+    size_t length = 0;
+    char *p_end = *p + buflen;
+
+    do
+    {
+        if( length >= buflen )
+        {
+            return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+        }
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
+        /*
+         * Write the residue in the current position, as an ASCII character.
+         */
+        if( r < 0xA )
+            *(--p_end) = (char)( '0' + r );
+        else
+            *(--p_end) = (char)( 'A' + ( r - 0xA ) );
+
+        length++;
+    } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 );
+
+    memmove( *p, p_end, length );
+    *p += length;
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Export into an ASCII string
+ */
+int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
+                              char *buf, size_t buflen, size_t *olen )
+{
+    int ret = 0;
+    size_t n;
+    char *p;
+    mbedtls_mpi T;
+    MPI_VALIDATE_RET( X    != NULL );
+    MPI_VALIDATE_RET( olen != NULL );
+    MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
+
+    if( radix < 2 || radix > 16 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    n = mbedtls_mpi_bitlen( X );
+    if( radix >=  4 ) n >>= 1;
+    if( radix >= 16 ) n >>= 1;
+    /*
+     * Round up the buffer length to an even value to ensure that there is
+     * enough room for hexadecimal values that can be represented in an odd
+     * number of digits.
+     */
+    n += 3 + ( ( n + 1 ) & 1 );
+
+    if( buflen < n )
+    {
+        *olen = n;
+        return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+    }
+
+    p = buf;
+    mbedtls_mpi_init( &T );
+
+    if( X->s == -1 )
+        *p++ = '-';
+
+    if( radix == 16 )
+    {
+        int c;
+        size_t i, j, k;
+
+        for( i = X->n, k = 0; i > 0; i-- )
+        {
+            for( j = ciL; j > 0; j-- )
+            {
+                c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
+
+                if( c == 0 && k == 0 && ( i + j ) != 2 )
+                    continue;
+
+                *(p++) = "0123456789ABCDEF" [c / 16];
+                *(p++) = "0123456789ABCDEF" [c % 16];
+                k = 1;
+            }
+        }
+    }
+    else
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) );
+
+        if( T.s == -1 )
+            T.s = 1;
+
+        MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) );
+    }
+
+    *p++ = '\0';
+    *olen = p - buf;
+
+cleanup:
+
+    mbedtls_mpi_free( &T );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_FS_IO)
+/*
+ * Read X from an opened file
+ */
+int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
+{
+    mbedtls_mpi_uint d;
+    size_t slen;
+    char *p;
+    /*
+     * Buffer should have space for (short) label and decimal formatted MPI,
+     * newline characters and '\0'
+     */
+    char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
+
+    MPI_VALIDATE_RET( X   != NULL );
+    MPI_VALIDATE_RET( fin != NULL );
+
+    if( radix < 2 || radix > 16 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    memset( s, 0, sizeof( s ) );
+    if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
+        return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
+
+    slen = strlen( s );
+    if( slen == sizeof( s ) - 2 )
+        return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+
+    if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
+    if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
+
+    p = s + slen;
+    while( p-- > s )
+        if( mpi_get_digit( &d, radix, *p ) != 0 )
+            break;
+
+    return( mbedtls_mpi_read_string( X, radix, p + 1 ) );
+}
+
+/*
+ * Write X into an opened file (or stdout if fout == NULL)
+ */
+int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
+{
+    int ret;
+    size_t n, slen, plen;
+    /*
+     * Buffer should have space for (short) label and decimal formatted MPI,
+     * newline characters and '\0'
+     */
+    char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
+    MPI_VALIDATE_RET( X != NULL );
+
+    if( radix < 2 || radix > 16 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    memset( s, 0, sizeof( s ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) );
+
+    if( p == NULL ) p = "";
+
+    plen = strlen( p );
+    slen = strlen( s );
+    s[slen++] = '\r';
+    s[slen++] = '\n';
+
+    if( fout != NULL )
+    {
+        if( fwrite( p, 1, plen, fout ) != plen ||
+            fwrite( s, 1, slen, fout ) != slen )
+            return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
+    }
+    else
+        mbedtls_printf( "%s%s", p, s );
+
+cleanup:
+
+    return( ret );
+}
+#endif /* MBEDTLS_FS_IO */
+
+
+/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
+ * into the storage form used by mbedtls_mpi. */
+
+static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x )
+{
+    uint8_t i;
+    mbedtls_mpi_uint tmp = 0;
+    /* This works regardless of the endianness. */
+    for( i = 0; i < ciL; i++, x >>= 8 )
+        tmp |= ( x & 0xFF ) << ( ( ciL - 1 - i ) << 3 );
+    return( tmp );
+}
+
+static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x )
+{
+#if defined(__BYTE_ORDER__)
+
+/* Nothing to do on bigendian systems. */
+#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
+    return( x );
+#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
+
+#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
+
+/* For GCC and Clang, have builtins for byte swapping. */
+#if defined(__GNUC__) && defined(__GNUC_PREREQ)
+#if __GNUC_PREREQ(4,3)
+#define have_bswap
+#endif
+#endif
+
+#if defined(__clang__) && defined(__has_builtin)
+#if __has_builtin(__builtin_bswap32)  &&                 \
+    __has_builtin(__builtin_bswap64)
+#define have_bswap
+#endif
+#endif
+
+#if defined(have_bswap)
+    /* The compiler is hopefully able to statically evaluate this! */
+    switch( sizeof(mbedtls_mpi_uint) )
+    {
+        case 4:
+            return( __builtin_bswap32(x) );
+        case 8:
+            return( __builtin_bswap64(x) );
+    }
+#endif
+#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
+#endif /* __BYTE_ORDER__ */
+
+    /* Fall back to C-based reordering if we don't know the byte order
+     * or we couldn't use a compiler-specific builtin. */
+    return( mpi_uint_bigendian_to_host_c( x ) );
+}
+
+static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
+{
+    mbedtls_mpi_uint *cur_limb_left;
+    mbedtls_mpi_uint *cur_limb_right;
+    if( limbs == 0 )
+        return;
+
+    /*
+     * Traverse limbs and
+     * - adapt byte-order in each limb
+     * - swap the limbs themselves.
+     * For that, simultaneously traverse the limbs from left to right
+     * and from right to left, as long as the left index is not bigger
+     * than the right index (it's not a problem if limbs is odd and the
+     * indices coincide in the last iteration).
+     */
+    for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 );
+         cur_limb_left <= cur_limb_right;
+         cur_limb_left++, cur_limb_right-- )
+    {
+        mbedtls_mpi_uint tmp;
+        /* Note that if cur_limb_left == cur_limb_right,
+         * this code effectively swaps the bytes only once. */
+        tmp             = mpi_uint_bigendian_to_host( *cur_limb_left  );
+        *cur_limb_left  = mpi_uint_bigendian_to_host( *cur_limb_right );
+        *cur_limb_right = tmp;
+    }
+}
+
+/*
+ * Import X from unsigned binary data, big endian
+ */
+int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
+{
+    int ret;
+    size_t const limbs    = CHARS_TO_LIMBS( buflen );
+    size_t const overhead = ( limbs * ciL ) - buflen;
+    unsigned char *Xp;
+
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
+
+    /* Ensure that target MPI has exactly the necessary number of limbs */
+    if( X->n != limbs )
+    {
+        mbedtls_mpi_free( X );
+        mbedtls_mpi_init( X );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
+    }
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+
+    /* Avoid calling `memcpy` with NULL source argument,
+     * even if buflen is 0. */
+    if( buf != NULL )
+    {
+        Xp = (unsigned char*) X->p;
+        memcpy( Xp + overhead, buf, buflen );
+
+        mpi_bigendian_to_host( X->p, limbs );
+    }
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Export X into unsigned binary data, big endian
+ */
+int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
+                              unsigned char *buf, size_t buflen )
+{
+    size_t stored_bytes;
+    size_t bytes_to_copy;
+    unsigned char *p;
+    size_t i;
+
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
+
+    stored_bytes = X->n * ciL;
+
+    if( stored_bytes < buflen )
+    {
+        /* There is enough space in the output buffer. Write initial
+         * null bytes and record the position at which to start
+         * writing the significant bytes. In this case, the execution
+         * trace of this function does not depend on the value of the
+         * number. */
+        bytes_to_copy = stored_bytes;
+        p = buf + buflen - stored_bytes;
+        memset( buf, 0, buflen - stored_bytes );
+    }
+    else
+    {
+        /* The output buffer is smaller than the allocated size of X.
+         * However X may fit if its leading bytes are zero. */
+        bytes_to_copy = buflen;
+        p = buf;
+        for( i = bytes_to_copy; i < stored_bytes; i++ )
+        {
+            if( GET_BYTE( X, i ) != 0 )
+                return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+        }
+    }
+
+    for( i = 0; i < bytes_to_copy; i++ )
+        p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
+
+    return( 0 );
+}
+
+/*
+ * Left-shift: X <<= count
+ */
+int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
+{
+    int ret;
+    size_t i, v0, t1;
+    mbedtls_mpi_uint r0 = 0, r1;
+    MPI_VALIDATE_RET( X != NULL );
+
+    v0 = count / (biL    );
+    t1 = count & (biL - 1);
+
+    i = mbedtls_mpi_bitlen( X ) + count;
+
+    if( X->n * biL < i )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) );
+
+    ret = 0;
+
+    /*
+     * shift by count / limb_size
+     */
+    if( v0 > 0 )
+    {
+        for( i = X->n; i > v0; i-- )
+            X->p[i - 1] = X->p[i - v0 - 1];
+
+        for( ; i > 0; i-- )
+            X->p[i - 1] = 0;
+    }
+
+    /*
+     * shift by count % limb_size
+     */
+    if( t1 > 0 )
+    {
+        for( i = v0; i < X->n; i++ )
+        {
+            r1 = X->p[i] >> (biL - t1);
+            X->p[i] <<= t1;
+            X->p[i] |= r0;
+            r0 = r1;
+        }
+    }
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Right-shift: X >>= count
+ */
+int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
+{
+    size_t i, v0, v1;
+    mbedtls_mpi_uint r0 = 0, r1;
+    MPI_VALIDATE_RET( X != NULL );
+
+    v0 = count /  biL;
+    v1 = count & (biL - 1);
+
+    if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
+        return mbedtls_mpi_lset( X, 0 );
+
+    /*
+     * shift by count / limb_size
+     */
+    if( v0 > 0 )
+    {
+        for( i = 0; i < X->n - v0; i++ )
+            X->p[i] = X->p[i + v0];
+
+        for( ; i < X->n; i++ )
+            X->p[i] = 0;
+    }
+
+    /*
+     * shift by count % limb_size
+     */
+    if( v1 > 0 )
+    {
+        for( i = X->n; i > 0; i-- )
+        {
+            r1 = X->p[i - 1] << (biL - v1);
+            X->p[i - 1] >>= v1;
+            X->p[i - 1] |= r0;
+            r0 = r1;
+        }
+    }
+
+    return( 0 );
+}
+
+/*
+ * Compare unsigned values
+ */
+int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
+{
+    size_t i, j;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+
+    for( i = X->n; i > 0; i-- )
+        if( X->p[i - 1] != 0 )
+            break;
+
+    for( j = Y->n; j > 0; j-- )
+        if( Y->p[j - 1] != 0 )
+            break;
+
+    if( i == 0 && j == 0 )
+        return( 0 );
+
+    if( i > j ) return(  1 );
+    if( j > i ) return( -1 );
+
+    for( ; i > 0; i-- )
+    {
+        if( X->p[i - 1] > Y->p[i - 1] ) return(  1 );
+        if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Compare signed values
+ */
+int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
+{
+    size_t i, j;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( Y != NULL );
+
+    for( i = X->n; i > 0; i-- )
+        if( X->p[i - 1] != 0 )
+            break;
+
+    for( j = Y->n; j > 0; j-- )
+        if( Y->p[j - 1] != 0 )
+            break;
+
+    if( i == 0 && j == 0 )
+        return( 0 );
+
+    if( i > j ) return(  X->s );
+    if( j > i ) return( -Y->s );
+
+    if( X->s > 0 && Y->s < 0 ) return(  1 );
+    if( Y->s > 0 && X->s < 0 ) return( -1 );
+
+    for( ; i > 0; i-- )
+    {
+        if( X->p[i - 1] > Y->p[i - 1] ) return(  X->s );
+        if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Compare signed values
+ */
+int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
+{
+    mbedtls_mpi Y;
+    mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
+
+    *p  = ( z < 0 ) ? -z : z;
+    Y.s = ( z < 0 ) ? -1 : 1;
+    Y.n = 1;
+    Y.p = p;
+
+    return( mbedtls_mpi_cmp_mpi( X, &Y ) );
+}
+
+/*
+ * Unsigned addition: X = |A| + |B|  (HAC 14.7)
+ */
+int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
+{
+    int ret;
+    size_t i, j;
+    mbedtls_mpi_uint *o, *p, c, tmp;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
+
+    if( X == B )
+    {
+        const mbedtls_mpi *T = A; A = X; B = T;
+    }
+
+    if( X != A )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
+
+    /*
+     * X should always be positive as a result of unsigned additions.
+     */
+    X->s = 1;
+
+    for( j = B->n; j > 0; j-- )
+        if( B->p[j - 1] != 0 )
+            break;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
+
+    o = B->p; p = X->p; c = 0;
+
+    /*
+     * tmp is used because it might happen that p == o
+     */
+    for( i = 0; i < j; i++, o++, p++ )
+    {
+        tmp= *o;
+        *p +=  c; c  = ( *p <  c );
+        *p += tmp; c += ( *p < tmp );
+    }
+
+    while( c != 0 )
+    {
+        if( i >= X->n )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) );
+            p = X->p + i;
+        }
+
+        *p += c; c = ( *p < c ); i++; p++;
+    }
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Helper for mbedtls_mpi subtraction
+ */
+static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d )
+{
+    size_t i;
+    mbedtls_mpi_uint c, z;
+
+    for( i = c = 0; i < n; i++, s++, d++ )
+    {
+        z = ( *d <  c );     *d -=  c;
+        c = ( *d < *s ) + z; *d -= *s;
+    }
+
+    while( c != 0 )
+    {
+        z = ( *d < c ); *d -= c;
+        c = z; d++;
+    }
+}
+
+/*
+ * Unsigned subtraction: X = |A| - |B|  (HAC 14.9)
+ */
+int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
+{
+    mbedtls_mpi TB;
+    int ret;
+    size_t n;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
+
+    if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
+        return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
+
+    mbedtls_mpi_init( &TB );
+
+    if( X == B )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
+        B = &TB;
+    }
+
+    if( X != A )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
+
+    /*
+     * X should always be positive as a result of unsigned subtractions.
+     */
+    X->s = 1;
+
+    ret = 0;
+
+    for( n = B->n; n > 0; n-- )
+        if( B->p[n - 1] != 0 )
+            break;
+
+    mpi_sub_hlp( n, B->p, X->p );
+
+cleanup:
+
+    mbedtls_mpi_free( &TB );
+
+    return( ret );
+}
+
+/*
+ * Signed addition: X = A + B
+ */
+int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
+{
+    int ret, s;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
+
+    s = A->s;
+    if( A->s * B->s < 0 )
+    {
+        if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
+            X->s =  s;
+        }
+        else
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
+            X->s = -s;
+        }
+    }
+    else
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
+        X->s = s;
+    }
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Signed subtraction: X = A - B
+ */
+int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
+{
+    int ret, s;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
+
+    s = A->s;
+    if( A->s * B->s > 0 )
+    {
+        if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
+            X->s =  s;
+        }
+        else
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
+            X->s = -s;
+        }
+    }
+    else
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
+        X->s = s;
+    }
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Signed addition: X = A + b
+ */
+int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
+{
+    mbedtls_mpi _B;
+    mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+
+    p[0] = ( b < 0 ) ? -b : b;
+    _B.s = ( b < 0 ) ? -1 : 1;
+    _B.n = 1;
+    _B.p = p;
+
+    return( mbedtls_mpi_add_mpi( X, A, &_B ) );
+}
+
+/*
+ * Signed subtraction: X = A - b
+ */
+int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
+{
+    mbedtls_mpi _B;
+    mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+
+    p[0] = ( b < 0 ) ? -b : b;
+    _B.s = ( b < 0 ) ? -1 : 1;
+    _B.n = 1;
+    _B.p = p;
+
+    return( mbedtls_mpi_sub_mpi( X, A, &_B ) );
+}
+
+/*
+ * Helper for mbedtls_mpi multiplication
+ */
+static
+#if defined(__APPLE__) && defined(__arm__)
+/*
+ * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
+ * appears to need this to prevent bad ARM code generation at -O3.
+ */
+__attribute__ ((noinline))
+#endif
+void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b )
+{
+    mbedtls_mpi_uint c = 0, t = 0;
+
+#if defined(MULADDC_HUIT)
+    for( ; i >= 8; i -= 8 )
+    {
+        MULADDC_INIT
+        MULADDC_HUIT
+        MULADDC_STOP
+    }
+
+    for( ; i > 0; i-- )
+    {
+        MULADDC_INIT
+        MULADDC_CORE
+        MULADDC_STOP
+    }
+#else /* MULADDC_HUIT */
+    for( ; i >= 16; i -= 16 )
+    {
+        MULADDC_INIT
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_STOP
+    }
+
+    for( ; i >= 8; i -= 8 )
+    {
+        MULADDC_INIT
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_CORE   MULADDC_CORE
+        MULADDC_STOP
+    }
+
+    for( ; i > 0; i-- )
+    {
+        MULADDC_INIT
+        MULADDC_CORE
+        MULADDC_STOP
+    }
+#endif /* MULADDC_HUIT */
+
+    t++;
+
+    do {
+        *d += c; c = ( *d < c ); d++;
+    }
+    while( c != 0 );
+}
+
+/*
+ * Baseline multiplication: X = A * B  (HAC 14.12)
+ */
+int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
+{
+    int ret;
+    size_t i, j;
+    mbedtls_mpi TA, TB;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
+
+    mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
+
+    if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; }
+    if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; }
+
+    for( i = A->n; i > 0; i-- )
+        if( A->p[i - 1] != 0 )
+            break;
+
+    for( j = B->n; j > 0; j-- )
+        if( B->p[j - 1] != 0 )
+            break;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+
+    for( ; j > 0; j-- )
+        mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
+
+    X->s = A->s * B->s;
+
+cleanup:
+
+    mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA );
+
+    return( ret );
+}
+
+/*
+ * Baseline multiplication: X = A * b
+ */
+int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
+{
+    mbedtls_mpi _B;
+    mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+
+    _B.s = 1;
+    _B.n = 1;
+    _B.p = p;
+    p[0] = b;
+
+    return( mbedtls_mpi_mul_mpi( X, A, &_B ) );
+}
+
+/*
+ * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
+ * mbedtls_mpi_uint divisor, d
+ */
+static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
+            mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r )
+{
+#if defined(MBEDTLS_HAVE_UDBL)
+    mbedtls_t_udbl dividend, quotient;
+#else
+    const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
+    const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1;
+    mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
+    mbedtls_mpi_uint u0_msw, u0_lsw;
+    size_t s;
+#endif
+
+    /*
+     * Check for overflow
+     */
+    if( 0 == d || u1 >= d )
+    {
+        if (r != NULL) *r = ~0;
+
+        return ( ~0 );
+    }
+
+#if defined(MBEDTLS_HAVE_UDBL)
+    dividend  = (mbedtls_t_udbl) u1 << biL;
+    dividend |= (mbedtls_t_udbl) u0;
+    quotient = dividend / d;
+    if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 )
+        quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1;
+
+    if( r != NULL )
+        *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) );
+
+    return (mbedtls_mpi_uint) quotient;
+#else
+
+    /*
+     * Algorithm D, Section 4.3.1 - The Art of Computer Programming
+     *   Vol. 2 - Seminumerical Algorithms, Knuth
+     */
+
+    /*
+     * Normalize the divisor, d, and dividend, u0, u1
+     */
+    s = mbedtls_clz( d );
+    d = d << s;
+
+    u1 = u1 << s;
+    u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) );
+    u0 =  u0 << s;
+
+    d1 = d >> biH;
+    d0 = d & uint_halfword_mask;
+
+    u0_msw = u0 >> biH;
+    u0_lsw = u0 & uint_halfword_mask;
+
+    /*
+     * Find the first quotient and remainder
+     */
+    q1 = u1 / d1;
+    r0 = u1 - d1 * q1;
+
+    while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
+    {
+        q1 -= 1;
+        r0 += d1;
+
+        if ( r0 >= radix ) break;
+    }
+
+    rAX = ( u1 * radix ) + ( u0_msw - q1 * d );
+    q0 = rAX / d1;
+    r0 = rAX - q0 * d1;
+
+    while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
+    {
+        q0 -= 1;
+        r0 += d1;
+
+        if ( r0 >= radix ) break;
+    }
+
+    if (r != NULL)
+        *r = ( rAX * radix + u0_lsw - q0 * d ) >> s;
+
+    quotient = q1 * radix + q0;
+
+    return quotient;
+#endif
+}
+
+/*
+ * Division by mbedtls_mpi: A = Q * B + R  (HAC 14.20)
+ */
+int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
+                         const mbedtls_mpi *B )
+{
+    int ret;
+    size_t i, n, t, k;
+    mbedtls_mpi X, Y, Z, T1, T2;
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
+
+    if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
+        return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
+
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
+    mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
+
+    if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
+    {
+        if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) );
+        if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) );
+        return( 0 );
+    }
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) );
+    X.s = Y.s = 1;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z,  0 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) );
+
+    k = mbedtls_mpi_bitlen( &Y ) % biL;
+    if( k < biL - 1 )
+    {
+        k = biL - 1 - k;
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) );
+    }
+    else k = 0;
+
+    n = X.n - 1;
+    t = Y.n - 1;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) );
+
+    while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 )
+    {
+        Z.p[n - t]++;
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) );
+    }
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) );
+
+    for( i = n; i > t ; i-- )
+    {
+        if( X.p[i] >= Y.p[t] )
+            Z.p[i - t - 1] = ~0;
+        else
+        {
+            Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1],
+                                                            Y.p[t], NULL);
+        }
+
+        Z.p[i - t - 1]++;
+        do
+        {
+            Z.p[i - t - 1]--;
+
+            MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) );
+            T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
+            T1.p[1] = Y.p[t];
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
+
+            MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) );
+            T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
+            T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
+            T2.p[2] = X.p[i];
+        }
+        while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1,  biL * ( i - t - 1 ) ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) );
+
+        if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) );
+            Z.p[i - t - 1]--;
+        }
+    }
+
+    if( Q != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) );
+        Q->s = A->s * B->s;
+    }
+
+    if( R != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) );
+        X.s = A->s;
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) );
+
+        if( mbedtls_mpi_cmp_int( R, 0 ) == 0 )
+            R->s = 1;
+    }
+
+cleanup:
+
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
+    mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
+
+    return( ret );
+}
+
+/*
+ * Division by int: A = Q * b + R
+ */
+int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
+                         const mbedtls_mpi *A,
+                         mbedtls_mpi_sint b )
+{
+    mbedtls_mpi _B;
+    mbedtls_mpi_uint p[1];
+    MPI_VALIDATE_RET( A != NULL );
+
+    p[0] = ( b < 0 ) ? -b : b;
+    _B.s = ( b < 0 ) ? -1 : 1;
+    _B.n = 1;
+    _B.p = p;
+
+    return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) );
+}
+
+/*
+ * Modulo: R = A mod B
+ */
+int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
+{
+    int ret;
+    MPI_VALIDATE_RET( R != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
+
+    if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
+        return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) );
+
+    while( mbedtls_mpi_cmp_int( R, 0 ) < 0 )
+      MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) );
+
+    while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 )
+      MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) );
+
+cleanup:
+
+    return( ret );
+}
+
+/*
+ * Modulo: r = A mod b
+ */
+int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b )
+{
+    size_t i;
+    mbedtls_mpi_uint x, y, z;
+    MPI_VALIDATE_RET( r != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+
+    if( b == 0 )
+        return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
+
+    if( b < 0 )
+        return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
+
+    /*
+     * handle trivial cases
+     */
+    if( b == 1 )
+    {
+        *r = 0;
+        return( 0 );
+    }
+
+    if( b == 2 )
+    {
+        *r = A->p[0] & 1;
+        return( 0 );
+    }
+
+    /*
+     * general case
+     */
+    for( i = A->n, y = 0; i > 0; i-- )
+    {
+        x  = A->p[i - 1];
+        y  = ( y << biH ) | ( x >> biH );
+        z  = y / b;
+        y -= z * b;
+
+        x <<= biH;
+        y  = ( y << biH ) | ( x >> biH );
+        z  = y / b;
+        y -= z * b;
+    }
+
+    /*
+     * If A is negative, then the current y represents a negative value.
+     * Flipping it to the positive side.
+     */
+    if( A->s < 0 && y != 0 )
+        y = b - y;
+
+    *r = y;
+
+    return( 0 );
+}
+
+/*
+ * Fast Montgomery initialization (thanks to Tom St Denis)
+ */
+static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
+{
+    mbedtls_mpi_uint x, m0 = N->p[0];
+    unsigned int i;
+
+    x  = m0;
+    x += ( ( m0 + 2 ) & 4 ) << 1;
+
+    for( i = biL; i >= 8; i /= 2 )
+        x *= ( 2 - ( m0 * x ) );
+
+    *mm = ~x + 1;
+}
+
+/*
+ * Montgomery multiplication: A = A * B * R^-1 mod N  (HAC 14.36)
+ */
+static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
+                         const mbedtls_mpi *T )
+{
+    size_t i, n, m;
+    mbedtls_mpi_uint u0, u1, *d;
+
+    if( T->n < N->n + 1 || T->p == NULL )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    memset( T->p, 0, T->n * ciL );
+
+    d = T->p;
+    n = N->n;
+    m = ( B->n < n ) ? B->n : n;
+
+    for( i = 0; i < n; i++ )
+    {
+        /*
+         * T = (T + u0*B + u1*N) / 2^biL
+         */
+        u0 = A->p[i];
+        u1 = ( d[0] + u0 * B->p[0] ) * mm;
+
+        mpi_mul_hlp( m, B->p, d, u0 );
+        mpi_mul_hlp( n, N->p, d, u1 );
+
+        *d++ = u0; d[n + 1] = 0;
+    }
+
+    memcpy( A->p, d, ( n + 1 ) * ciL );
+
+    if( mbedtls_mpi_cmp_abs( A, N ) >= 0 )
+        mpi_sub_hlp( n, N->p, A->p );
+    else
+        /* prevent timing attacks */
+        mpi_sub_hlp( n, A->p, T->p );
+
+    return( 0 );
+}
+
+/*
+ * Montgomery reduction: A = A * R^-1 mod N
+ */
+static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
+                        mbedtls_mpi_uint mm, const mbedtls_mpi *T )
+{
+    mbedtls_mpi_uint z = 1;
+    mbedtls_mpi U;
+
+    U.n = U.s = (int) z;
+    U.p = &z;
+
+    return( mpi_montmul( A, &U, N, mm, T ) );
+}
+
+/*
+ * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
+ */
+int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
+                         const mbedtls_mpi *E, const mbedtls_mpi *N,
+                         mbedtls_mpi *_RR )
+{
+    int ret;
+    size_t wbits, wsize, one = 1;
+    size_t i, j, nblimbs;
+    size_t bufsize, nbits;
+    mbedtls_mpi_uint ei, mm, state;
+    mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
+    int neg;
+
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( E != NULL );
+    MPI_VALIDATE_RET( N != NULL );
+
+    if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    /*
+     * Init temps and window size
+     */
+    mpi_montg_init( &mm, N );
+    mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
+    mbedtls_mpi_init( &Apos );
+    memset( W, 0, sizeof( W ) );
+
+    i = mbedtls_mpi_bitlen( E );
+
+    wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
+            ( i >  79 ) ? 4 : ( i >  23 ) ? 3 : 1;
+
+    if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
+        wsize = MBEDTLS_MPI_WINDOW_SIZE;
+
+    j = N->n + 1;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1],  j ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
+
+    /*
+     * Compensate for negative A (and correct at the end)
+     */
+    neg = ( A->s == -1 );
+    if( neg )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) );
+        Apos.s = 1;
+        A = &Apos;
+    }
+
+    /*
+     * If 1st call, pre-compute R^2 mod N
+     */
+    if( _RR == NULL || _RR->p == NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
+
+        if( _RR != NULL )
+            memcpy( _RR, &RR, sizeof( mbedtls_mpi ) );
+    }
+    else
+        memcpy( &RR, _RR, sizeof( mbedtls_mpi ) );
+
+    /*
+     * W[1] = A * R^2 * R^-1 mod N = A * R mod N
+     */
+    if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
+    else
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
+
+    MBEDTLS_MPI_CHK( mpi_montmul( &W[1], &RR, N, mm, &T ) );
+
+    /*
+     * X = R^2 * R^-1 mod N = R mod N
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
+    MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) );
+
+    if( wsize > 1 )
+    {
+        /*
+         * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
+         */
+        j =  one << ( wsize - 1 );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1]    ) );
+
+        for( i = 0; i < wsize - 1; i++ )
+            MBEDTLS_MPI_CHK( mpi_montmul( &W[j], &W[j], N, mm, &T ) );
+
+        /*
+         * W[i] = W[i - 1] * W[1]
+         */
+        for( i = j + 1; i < ( one << wsize ); i++ )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
+
+            MBEDTLS_MPI_CHK( mpi_montmul( &W[i], &W[1], N, mm, &T ) );
+        }
+    }
+
+    nblimbs = E->n;
+    bufsize = 0;
+    nbits   = 0;
+    wbits   = 0;
+    state   = 0;
+
+    while( 1 )
+    {
+        if( bufsize == 0 )
+        {
+            if( nblimbs == 0 )
+                break;
+
+            nblimbs--;
+
+            bufsize = sizeof( mbedtls_mpi_uint ) << 3;
+        }
+
+        bufsize--;
+
+        ei = (E->p[nblimbs] >> bufsize) & 1;
+
+        /*
+         * skip leading 0s
+         */
+        if( ei == 0 && state == 0 )
+            continue;
+
+        if( ei == 0 && state == 1 )
+        {
+            /*
+             * out of window, square X
+             */
+            MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
+            continue;
+        }
+
+        /*
+         * add ei to current window
+         */
+        state = 2;
+
+        nbits++;
+        wbits |= ( ei << ( wsize - nbits ) );
+
+        if( nbits == wsize )
+        {
+            /*
+             * X = X^wsize R^-1 mod N
+             */
+            for( i = 0; i < wsize; i++ )
+                MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
+
+            /*
+             * X = X * W[wbits] R^-1 mod N
+             */
+            MBEDTLS_MPI_CHK( mpi_montmul( X, &W[wbits], N, mm, &T ) );
+
+            state--;
+            nbits = 0;
+            wbits = 0;
+        }
+    }
+
+    /*
+     * process the remaining bits
+     */
+    for( i = 0; i < nbits; i++ )
+    {
+        MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
+
+        wbits <<= 1;
+
+        if( ( wbits & ( one << wsize ) ) != 0 )
+            MBEDTLS_MPI_CHK( mpi_montmul( X, &W[1], N, mm, &T ) );
+    }
+
+    /*
+     * X = A^E * R * R^-1 mod N = A^E mod N
+     */
+    MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) );
+
+    if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 )
+    {
+        X->s = -1;
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
+    }
+
+cleanup:
+
+    for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
+        mbedtls_mpi_free( &W[i] );
+
+    mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
+
+    if( _RR == NULL || _RR->p == NULL )
+        mbedtls_mpi_free( &RR );
+
+    return( ret );
+}
+
+/*
+ * Greatest common divisor: G = gcd(A, B)  (HAC 14.54)
+ */
+int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
+{
+    int ret;
+    size_t lz, lzt;
+    mbedtls_mpi TG, TA, TB;
+
+    MPI_VALIDATE_RET( G != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( B != NULL );
+
+    mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
+
+    lz = mbedtls_mpi_lsb( &TA );
+    lzt = mbedtls_mpi_lsb( &TB );
+
+    if( lzt < lz )
+        lz = lzt;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) );
+
+    TA.s = TB.s = 1;
+
+    while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
+
+        if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) );
+        }
+        else
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
+        }
+    }
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
+
+cleanup:
+
+    mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
+
+    return( ret );
+}
+
+/*
+ * Fill X with size bytes of random.
+ *
+ * Use a temporary bytes representation to make sure the result is the same
+ * regardless of the platform endianness (useful when f_rng is actually
+ * deterministic, eg for tests).
+ */
+int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret;
+    size_t const limbs = CHARS_TO_LIMBS( size );
+    size_t const overhead = ( limbs * ciL ) - size;
+    unsigned char *Xp;
+
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
+    /* Ensure that target MPI has exactly the necessary number of limbs */
+    if( X->n != limbs )
+    {
+        mbedtls_mpi_free( X );
+        mbedtls_mpi_init( X );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
+    }
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+
+    Xp = (unsigned char*) X->p;
+    f_rng( p_rng, Xp + overhead, size );
+
+    mpi_bigendian_to_host( X->p, limbs );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Modular inverse: X = A^-1 mod N  (HAC 14.61 / 14.64)
+ */
+int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
+{
+    int ret;
+    mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
+    MPI_VALIDATE_RET( X != NULL );
+    MPI_VALIDATE_RET( A != NULL );
+    MPI_VALIDATE_RET( N != NULL );
+
+    if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 );
+    mbedtls_mpi_init( &G ); mbedtls_mpi_init( &TB ); mbedtls_mpi_init( &TV );
+    mbedtls_mpi_init( &V1 ); mbedtls_mpi_init( &V2 );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) );
+
+    if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
+    {
+        ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+        goto cleanup;
+    }
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) );
+
+    do
+    {
+        while( ( TU.p[0] & 1 ) == 0 )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) );
+
+            if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
+            {
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) );
+                MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) );
+            }
+
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) );
+        }
+
+        while( ( TV.p[0] & 1 ) == 0 )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) );
+
+            if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
+            {
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) );
+                MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) );
+            }
+
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) );
+        }
+
+        if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) );
+        }
+        else
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) );
+        }
+    }
+    while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 );
+
+    while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) );
+
+    while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) );
+
+cleanup:
+
+    mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 );
+    mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV );
+    mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_GENPRIME)
+
+static const int small_prime[] =
+{
+        3,    5,    7,   11,   13,   17,   19,   23,
+       29,   31,   37,   41,   43,   47,   53,   59,
+       61,   67,   71,   73,   79,   83,   89,   97,
+      101,  103,  107,  109,  113,  127,  131,  137,
+      139,  149,  151,  157,  163,  167,  173,  179,
+      181,  191,  193,  197,  199,  211,  223,  227,
+      229,  233,  239,  241,  251,  257,  263,  269,
+      271,  277,  281,  283,  293,  307,  311,  313,
+      317,  331,  337,  347,  349,  353,  359,  367,
+      373,  379,  383,  389,  397,  401,  409,  419,
+      421,  431,  433,  439,  443,  449,  457,  461,
+      463,  467,  479,  487,  491,  499,  503,  509,
+      521,  523,  541,  547,  557,  563,  569,  571,
+      577,  587,  593,  599,  601,  607,  613,  617,
+      619,  631,  641,  643,  647,  653,  659,  661,
+      673,  677,  683,  691,  701,  709,  719,  727,
+      733,  739,  743,  751,  757,  761,  769,  773,
+      787,  797,  809,  811,  821,  823,  827,  829,
+      839,  853,  857,  859,  863,  877,  881,  883,
+      887,  907,  911,  919,  929,  937,  941,  947,
+      953,  967,  971,  977,  983,  991,  997, -103
+};
+
+/*
+ * Small divisors test (X must be positive)
+ *
+ * Return values:
+ * 0: no small factor (possible prime, more tests needed)
+ * 1: certain prime
+ * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
+ * other negative: error
+ */
+static int mpi_check_small_factors( const mbedtls_mpi *X )
+{
+    int ret = 0;
+    size_t i;
+    mbedtls_mpi_uint r;
+
+    if( ( X->p[0] & 1 ) == 0 )
+        return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+
+    for( i = 0; small_prime[i] > 0; i++ )
+    {
+        if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 )
+            return( 1 );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) );
+
+        if( r == 0 )
+            return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+    }
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Miller-Rabin pseudo-primality test  (HAC 4.24)
+ */
+static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
+                             int (*f_rng)(void *, unsigned char *, size_t),
+                             void *p_rng )
+{
+    int ret, count;
+    size_t i, j, k, s;
+    mbedtls_mpi W, R, T, A, RR;
+
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
+    mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R );
+    mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
+    mbedtls_mpi_init( &RR );
+
+    /*
+     * W = |X| - 1
+     * R = W >> lsb( W )
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) );
+    s = mbedtls_mpi_lsb( &W );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
+
+    i = mbedtls_mpi_bitlen( X );
+
+    for( i = 0; i < rounds; i++ )
+    {
+        /*
+         * pick a random A, 1 < A < |X| - 1
+         */
+        count = 0;
+        do {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
+
+            j = mbedtls_mpi_bitlen( &A );
+            k = mbedtls_mpi_bitlen( &W );
+            if (j > k) {
+                A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) * biL - 1 ) ) - 1;
+            }
+
+            if (count++ > 30) {
+                return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+            }
+
+        } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ||
+                  mbedtls_mpi_cmp_int( &A, 1 )  <= 0    );
+
+        /*
+         * A = A^R mod |X|
+         */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) );
+
+        if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 ||
+            mbedtls_mpi_cmp_int( &A,  1 ) == 0 )
+            continue;
+
+        j = 1;
+        while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 )
+        {
+            /*
+             * A = A * A mod |X|
+             */
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X  ) );
+
+            if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
+                break;
+
+            j++;
+        }
+
+        /*
+         * not prime if A != |X| - 1 or A == 1
+         */
+        if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ||
+            mbedtls_mpi_cmp_int( &A,  1 ) == 0 )
+        {
+            ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+            break;
+        }
+    }
+
+cleanup:
+    mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R );
+    mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
+    mbedtls_mpi_free( &RR );
+
+    return( ret );
+}
+
+/*
+ * Pseudo-primality test: small factors, then Miller-Rabin
+ */
+int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng )
+{
+    int ret;
+    mbedtls_mpi XX;
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
+    XX.s = 1;
+    XX.n = X->n;
+    XX.p = X->p;
+
+    if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 ||
+        mbedtls_mpi_cmp_int( &XX, 1 ) == 0 )
+        return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+
+    if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 )
+        return( 0 );
+
+    if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
+    {
+        if( ret == 1 )
+            return( 0 );
+
+        return( ret );
+    }
+
+    return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+/*
+ * Pseudo-primality test, error probability 2^-80
+ */
+int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
+                  int (*f_rng)(void *, unsigned char *, size_t),
+                  void *p_rng )
+{
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
+    /*
+     * In the past our key generation aimed for an error rate of at most
+     * 2^-80. Since this function is deprecated, aim for the same certainty
+     * here as well.
+     */
+    return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) );
+}
+#endif
+
+/*
+ * Prime number generation
+ *
+ * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
+ * be either 1024 bits or 1536 bits long, and flags must contain
+ * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
+ */
+int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
+                   int (*f_rng)(void *, unsigned char *, size_t),
+                   void *p_rng )
+{
+#ifdef MBEDTLS_HAVE_INT64
+// ceil(2^63.5)
+#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
+#else
+// ceil(2^31.5)
+#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
+#endif
+    int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+    size_t k, n;
+    int rounds;
+    mbedtls_mpi_uint r;
+    mbedtls_mpi Y;
+
+    MPI_VALIDATE_RET( X     != NULL );
+    MPI_VALIDATE_RET( f_rng != NULL );
+
+    if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    mbedtls_mpi_init( &Y );
+
+    n = BITS_TO_LIMBS( nbits );
+
+    if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 )
+    {
+        /*
+         * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
+         */
+        rounds = ( ( nbits >= 1300 ) ?  2 : ( nbits >=  850 ) ?  3 :
+                   ( nbits >=  650 ) ?  4 : ( nbits >=  350 ) ?  8 :
+                   ( nbits >=  250 ) ? 12 : ( nbits >=  150 ) ? 18 : 27 );
+    }
+    else
+    {
+        /*
+         * 2^-100 error probability, number of rounds computed based on HAC,
+         * fact 4.48
+         */
+        rounds = ( ( nbits >= 1450 ) ?  4 : ( nbits >=  1150 ) ?  5 :
+                   ( nbits >= 1000 ) ?  6 : ( nbits >=   850 ) ?  7 :
+                   ( nbits >=  750 ) ?  8 : ( nbits >=   500 ) ? 13 :
+                   ( nbits >=  250 ) ? 28 : ( nbits >=   150 ) ? 40 : 51 );
+    }
+
+    while( 1 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
+        /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
+        if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
+
+        k = n * biL;
+        if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
+        X->p[0] |= 1;
+
+        if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 )
+        {
+            ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng );
+
+            if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+                goto cleanup;
+        }
+        else
+        {
+            /*
+             * An necessary condition for Y and X = 2Y + 1 to be prime
+             * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
+             * Make sure it is satisfied, while keeping X = 3 mod 4
+             */
+
+            X->p[0] |= 2;
+
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
+            if( r == 0 )
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
+            else if( r == 1 )
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
+
+            /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
+            MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
+
+            while( 1 )
+            {
+                /*
+                 * First, check small factors for X and Y
+                 * before doing Miller-Rabin on any of them
+                 */
+                if( ( ret = mpi_check_small_factors(  X         ) ) == 0 &&
+                    ( ret = mpi_check_small_factors( &Y         ) ) == 0 &&
+                    ( ret = mpi_miller_rabin(  X, rounds, f_rng, p_rng  ) )
+                                                                    == 0 &&
+                    ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng  ) )
+                                                                    == 0 )
+                    goto cleanup;
+
+                if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+                    goto cleanup;
+
+                /*
+                 * Next candidates. We want to preserve Y = (X-1) / 2 and
+                 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
+                 * so up Y by 6 and X by 12.
+                 */
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(  X,  X, 12 ) );
+                MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6  ) );
+            }
+        }
+    }
+
+cleanup:
+
+    mbedtls_mpi_free( &Y );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_GENPRIME */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+#define GCD_PAIR_COUNT  3
+
+static const int gcd_pairs[GCD_PAIR_COUNT][3] =
+{
+    { 693, 609, 21 },
+    { 1764, 868, 28 },
+    { 768454923, 542167814, 1 }
+};
+
+/*
+ * Checkup routine
+ */
+int mbedtls_mpi_self_test( int verbose )
+{
+    int ret, i;
+    mbedtls_mpi A, E, N, X, Y, U, V;
+
+    mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &X );
+    mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &V );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16,
+        "EFE021C2645FD1DC586E69184AF4A31E" \
+        "D5F53E93B5F123FA41680867BA110131" \
+        "944FE7952E2517337780CB0DB80E61AA" \
+        "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16,
+        "B2E7EFD37075B9F03FF989C7C5051C20" \
+        "34D2A323810251127E7BF8625A4F49A5" \
+        "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
+        "5B5C25763222FEFCCFC38B832366C29E" ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16,
+        "0066A198186C18C10B2F5ED9B522752A" \
+        "9830B69916E535C8F047518A889A43A5" \
+        "94B6BED27A168D31D4A52F88925AA8F5" ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
+        "602AB7ECA597A3D6B56FF9829A5E8B85" \
+        "9E857EA95A03512E2BAE7391688D264A" \
+        "A5663B0341DB9CCFD2C4C5F421FEC814" \
+        "8001B72E848A38CAE1C65F78E56ABDEF" \
+        "E12D3C039B8A02D6BE593F0BBBDA56F1" \
+        "ECF677152EF804370C1A305CAF3B5BF1" \
+        "30879B56C61DE584A0F53A2447A51E" ) );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  MPI test #1 (mul_mpi): " );
+
+    if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
+        "256567336059E52CAE22925474705F39A94" ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16,
+        "6613F26162223DF488E9CD48CC132C7A" \
+        "0AC93C701B001B092E4E5B9F73BCD27B" \
+        "9EE50D0657C77F374E903CDFA4C642" ) );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  MPI test #2 (div_mpi): " );
+
+    if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ||
+        mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
+        "36E139AEA55215609D2816998ED020BB" \
+        "BD96C37890F65171D948E9BC7CBAA4D9" \
+        "325D24D6A3C12710F10A09FA08AB87" ) );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  MPI test #3 (exp_mod): " );
+
+    if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
+        "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
+        "C3DBA76456363A10869622EAC2DD84EC" \
+        "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  MPI test #4 (inv_mod): " );
+
+    if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  MPI test #5 (simple gcd): " );
+
+    for( i = 0; i < GCD_PAIR_COUNT; i++ )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) );
+
+        if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed at %d\n", i );
+
+            ret = 1;
+            goto cleanup;
+        }
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+cleanup:
+
+    if( ret != 0 && verbose != 0 )
+        mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
+
+    mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X );
+    mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V );
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_BIGNUM_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/blowfish.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/blowfish.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/blowfish.c	(revision 398)
@@ -0,0 +1,696 @@
+/*
+ *  Blowfish implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The Blowfish block cipher was designed by Bruce Schneier in 1993.
+ *  http://www.schneier.com/blowfish.html
+ *  http://en.wikipedia.org/wiki/Blowfish_%28cipher%29
+ *
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_BLOWFISH_C)
+
+#include "mbedtls/blowfish.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if !defined(MBEDTLS_BLOWFISH_ALT)
+
+/* Parameter validation macros */
+#define BLOWFISH_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA )
+#define BLOWFISH_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_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
+
+static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = {
+        0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
+        0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
+        0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
+        0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
+        0x9216D5D9L, 0x8979FB1BL
+};
+
+/* declarations of data at the end of this file */
+static const uint32_t S[4][256];
+
+static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x )
+{
+   unsigned short a, b, c, d;
+   uint32_t  y;
+
+   d = (unsigned short)(x & 0xFF);
+   x >>= 8;
+   c = (unsigned short)(x & 0xFF);
+   x >>= 8;
+   b = (unsigned short)(x & 0xFF);
+   x >>= 8;
+   a = (unsigned short)(x & 0xFF);
+   y = ctx->S[0][a] + ctx->S[1][b];
+   y = y ^ ctx->S[2][c];
+   y = y + ctx->S[3][d];
+
+   return( y );
+}
+
+static void blowfish_enc( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr )
+{
+    uint32_t  Xl, Xr, temp;
+    short i;
+
+    Xl = *xl;
+    Xr = *xr;
+
+    for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i )
+    {
+        Xl = Xl ^ ctx->P[i];
+        Xr = F( ctx, Xl ) ^ Xr;
+
+        temp = Xl;
+        Xl = Xr;
+        Xr = temp;
+    }
+
+    temp = Xl;
+    Xl = Xr;
+    Xr = temp;
+
+    Xr = Xr ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS];
+    Xl = Xl ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS + 1];
+
+    *xl = Xl;
+    *xr = Xr;
+}
+
+static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr )
+{
+    uint32_t  Xl, Xr, temp;
+    short i;
+
+    Xl = *xl;
+    Xr = *xr;
+
+    for( i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i )
+    {
+        Xl = Xl ^ ctx->P[i];
+        Xr = F( ctx, Xl ) ^ Xr;
+
+        temp = Xl;
+        Xl = Xr;
+        Xr = temp;
+    }
+
+    temp = Xl;
+    Xl = Xr;
+    Xr = temp;
+
+    Xr = Xr ^ ctx->P[1];
+    Xl = Xl ^ ctx->P[0];
+
+    *xl = Xl;
+    *xr = Xr;
+}
+
+void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx )
+{
+    BLOWFISH_VALIDATE( ctx != NULL );
+    memset( ctx, 0, sizeof( mbedtls_blowfish_context ) );
+}
+
+void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_blowfish_context ) );
+}
+
+/*
+ * Blowfish key schedule
+ */
+int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx,
+                             const unsigned char *key,
+                             unsigned int keybits )
+{
+    unsigned int i, j, k;
+    uint32_t data, datal, datar;
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( key != NULL );
+
+    if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS    ||
+        keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS    ||
+        keybits % 8 != 0 )
+    {
+        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
+    }
+
+    keybits >>= 3;
+
+    for( i = 0; i < 4; i++ )
+    {
+        for( j = 0; j < 256; j++ )
+            ctx->S[i][j] = S[i][j];
+    }
+
+    j = 0;
+    for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i )
+    {
+        data = 0x00000000;
+        for( k = 0; k < 4; ++k )
+        {
+            data = ( data << 8 ) | key[j++];
+            if( j >= keybits )
+                j = 0;
+        }
+        ctx->P[i] = P[i] ^ data;
+    }
+
+    datal = 0x00000000;
+    datar = 0x00000000;
+
+    for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2 )
+    {
+        blowfish_enc( ctx, &datal, &datar );
+        ctx->P[i] = datal;
+        ctx->P[i + 1] = datar;
+    }
+
+    for( i = 0; i < 4; i++ )
+    {
+       for( j = 0; j < 256; j += 2 )
+       {
+            blowfish_enc( ctx, &datal, &datar );
+            ctx->S[i][j] = datal;
+            ctx->S[i][j + 1] = datar;
+        }
+    }
+    return( 0 );
+}
+
+/*
+ * Blowfish-ECB block encryption/decryption
+ */
+int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
+                    int mode,
+                    const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE],
+                    unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] )
+{
+    uint32_t X0, X1;
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+                           mode == MBEDTLS_BLOWFISH_DECRYPT );
+    BLOWFISH_VALIDATE_RET( input  != NULL );
+    BLOWFISH_VALIDATE_RET( output != NULL );
+
+    GET_UINT32_BE( X0, input,  0 );
+    GET_UINT32_BE( X1, input,  4 );
+
+    if( mode == MBEDTLS_BLOWFISH_DECRYPT )
+    {
+        blowfish_dec( ctx, &X0, &X1 );
+    }
+    else /* MBEDTLS_BLOWFISH_ENCRYPT */
+    {
+        blowfish_enc( ctx, &X0, &X1 );
+    }
+
+    PUT_UINT32_BE( X0, output,  0 );
+    PUT_UINT32_BE( X1, output,  4 );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * Blowfish-CBC buffer encryption/decryption
+ */
+int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
+                    const unsigned char *input,
+                    unsigned char *output )
+{
+    int i;
+    unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE];
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+                           mode == MBEDTLS_BLOWFISH_DECRYPT );
+    BLOWFISH_VALIDATE_RET( iv != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
+
+    if( length % MBEDTLS_BLOWFISH_BLOCKSIZE )
+        return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH );
+
+    if( mode == MBEDTLS_BLOWFISH_DECRYPT )
+    {
+        while( length > 0 )
+        {
+            memcpy( temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE );
+            mbedtls_blowfish_crypt_ecb( ctx, mode, input, output );
+
+            for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE;i++ )
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+            memcpy( iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE );
+
+            input  += MBEDTLS_BLOWFISH_BLOCKSIZE;
+            output += MBEDTLS_BLOWFISH_BLOCKSIZE;
+            length -= MBEDTLS_BLOWFISH_BLOCKSIZE;
+        }
+    }
+    else
+    {
+        while( length > 0 )
+        {
+            for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++ )
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+            mbedtls_blowfish_crypt_ecb( ctx, mode, output, output );
+            memcpy( iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE );
+
+            input  += MBEDTLS_BLOWFISH_BLOCKSIZE;
+            output += MBEDTLS_BLOWFISH_BLOCKSIZE;
+            length -= MBEDTLS_BLOWFISH_BLOCKSIZE;
+        }
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * Blowfish CFB buffer encryption/decryption
+ */
+int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx,
+                       int mode,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c;
+    size_t n;
+
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( mode == MBEDTLS_BLOWFISH_ENCRYPT ||
+                           mode == MBEDTLS_BLOWFISH_DECRYPT );
+    BLOWFISH_VALIDATE_RET( iv     != NULL );
+    BLOWFISH_VALIDATE_RET( iv_off != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *iv_off;
+    if( n >= 8 )
+        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
+
+    if( mode == MBEDTLS_BLOWFISH_DECRYPT )
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv );
+
+            c = *input++;
+            *output++ = (unsigned char)( c ^ iv[n] );
+            iv[n] = (unsigned char) c;
+
+            n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
+        }
+    }
+    else
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv );
+
+            iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
+
+            n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
+        }
+    }
+
+    *iv_off = n;
+
+    return( 0 );
+}
+#endif /*MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * Blowfish CTR buffer encryption/decryption
+ */
+int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx,
+                       size_t length,
+                       size_t *nc_off,
+                       unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE],
+                       unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c, i;
+    size_t n;
+    BLOWFISH_VALIDATE_RET( ctx != NULL );
+    BLOWFISH_VALIDATE_RET( nonce_counter != NULL );
+    BLOWFISH_VALIDATE_RET( stream_block  != NULL );
+    BLOWFISH_VALIDATE_RET( nc_off != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || input  != NULL );
+    BLOWFISH_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *nc_off;
+    if( n >= 8 )
+        return( MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA );
+
+    while( length-- )
+    {
+        if( n == 0 ) {
+            mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, nonce_counter,
+                                stream_block );
+
+            for( i = MBEDTLS_BLOWFISH_BLOCKSIZE; i > 0; i-- )
+                if( ++nonce_counter[i - 1] != 0 )
+                    break;
+        }
+        c = *input++;
+        *output++ = (unsigned char)( c ^ stream_block[n] );
+
+        n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE;
+    }
+
+    *nc_off = n;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+static const uint32_t S[4][256] = {
+    {   0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
+        0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
+        0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
+        0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
+        0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
+        0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
+        0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
+        0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
+        0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
+        0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
+        0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
+        0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
+        0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
+        0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
+        0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
+        0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
+        0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
+        0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
+        0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
+        0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
+        0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
+        0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
+        0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
+        0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
+        0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
+        0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
+        0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
+        0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
+        0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
+        0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
+        0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
+        0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
+        0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
+        0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
+        0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
+        0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
+        0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
+        0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
+        0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
+        0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
+        0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
+        0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
+        0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
+        0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
+        0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
+        0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
+        0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
+        0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
+        0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
+        0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
+        0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
+        0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
+        0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
+        0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
+        0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
+        0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
+        0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
+        0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
+        0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
+        0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
+        0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
+        0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
+        0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
+        0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL   },
+    {   0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
+        0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
+        0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
+        0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
+        0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
+        0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
+        0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
+        0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
+        0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
+        0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
+        0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
+        0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
+        0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
+        0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
+        0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
+        0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
+        0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
+        0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
+        0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
+        0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
+        0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
+        0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
+        0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
+        0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
+        0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
+        0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
+        0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
+        0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
+        0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
+        0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
+        0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
+        0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
+        0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
+        0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
+        0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
+        0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
+        0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
+        0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
+        0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
+        0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
+        0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
+        0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
+        0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
+        0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
+        0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
+        0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
+        0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
+        0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
+        0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
+        0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
+        0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
+        0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
+        0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
+        0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
+        0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
+        0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
+        0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
+        0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
+        0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
+        0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
+        0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
+        0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
+        0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
+        0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L   },
+    {   0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
+        0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
+        0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
+        0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
+        0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
+        0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
+        0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
+        0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
+        0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
+        0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
+        0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
+        0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
+        0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
+        0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
+        0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
+        0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
+        0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
+        0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
+        0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
+        0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
+        0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
+        0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
+        0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
+        0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
+        0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
+        0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
+        0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
+        0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
+        0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
+        0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
+        0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
+        0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
+        0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
+        0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
+        0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
+        0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
+        0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
+        0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
+        0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
+        0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
+        0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
+        0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
+        0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
+        0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
+        0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
+        0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
+        0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
+        0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
+        0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
+        0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
+        0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
+        0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
+        0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
+        0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
+        0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
+        0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
+        0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
+        0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
+        0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
+        0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
+        0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
+        0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
+        0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
+        0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L  },
+    {   0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
+        0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
+        0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
+        0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
+        0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
+        0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
+        0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
+        0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
+        0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
+        0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
+        0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
+        0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
+        0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
+        0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
+        0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
+        0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
+        0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
+        0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
+        0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
+        0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
+        0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
+        0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
+        0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
+        0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
+        0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
+        0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
+        0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
+        0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
+        0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
+        0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
+        0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
+        0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
+        0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
+        0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
+        0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
+        0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
+        0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
+        0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
+        0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
+        0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
+        0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
+        0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
+        0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
+        0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
+        0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
+        0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
+        0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
+        0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
+        0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
+        0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
+        0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
+        0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
+        0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
+        0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
+        0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
+        0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
+        0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
+        0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
+        0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
+        0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
+        0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
+        0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
+        0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
+        0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L  }
+};
+
+#endif /* !MBEDTLS_BLOWFISH_ALT */
+#endif /* MBEDTLS_BLOWFISH_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/camellia.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/camellia.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/camellia.c	(revision 398)
@@ -0,0 +1,1114 @@
+/*
+ *  Camellia implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The Camellia block cipher was designed by NTT and Mitsubishi Electric
+ *  Corporation.
+ *
+ *  http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CAMELLIA_C)
+
+#include "mbedtls/camellia.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_CAMELLIA_ALT)
+
+/* Parameter validation macros */
+#define CAMELLIA_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA )
+#define CAMELLIA_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_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
+
+static const unsigned char SIGMA_CHARS[6][8] =
+{
+    { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
+    { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 },
+    { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe },
+    { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c },
+    { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d },
+    { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd }
+};
+
+#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
+
+static const unsigned char FSb[256] =
+{
+    112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
+     35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
+    134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
+    166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77,
+    139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
+    223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215,
+     20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
+    254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80,
+    170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
+     16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
+    135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226,
+     82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
+    233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
+    120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
+    114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
+     64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158
+};
+
+#define SBOX1(n) FSb[(n)]
+#define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff)
+#define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff)
+#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff]
+
+#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
+
+static const unsigned char FSb[256] =
+{
+ 112, 130,  44, 236, 179,  39, 192, 229, 228, 133,  87,  53, 234,  12, 174,  65,
+  35, 239, 107, 147,  69,  25, 165,  33, 237,  14,  79,  78,  29, 101, 146, 189,
+ 134, 184, 175, 143, 124, 235,  31, 206,  62,  48, 220,  95,  94, 197,  11,  26,
+ 166, 225,  57, 202, 213,  71,  93,  61, 217,   1,  90, 214,  81,  86, 108,  77,
+ 139,  13, 154, 102, 251, 204, 176,  45, 116,  18,  43,  32, 240, 177, 132, 153,
+ 223,  76, 203, 194,  52, 126, 118,   5, 109, 183, 169,  49, 209,  23,   4, 215,
+  20,  88,  58,  97, 222,  27,  17,  28,  50,  15, 156,  22,  83,  24, 242,  34,
+ 254,  68, 207, 178, 195, 181, 122, 145,  36,   8, 232, 168,  96, 252, 105,  80,
+ 170, 208, 160, 125, 161, 137,  98, 151,  84,  91,  30, 149, 224, 255, 100, 210,
+  16, 196,   0,  72, 163, 247, 117, 219, 138,   3, 230, 218,   9,  63, 221, 148,
+ 135,  92, 131,   2, 205,  74, 144,  51, 115, 103, 246, 243, 157, 127, 191, 226,
+  82, 155, 216,  38, 200,  55, 198,  59, 129, 150, 111,  75,  19, 190,  99,  46,
+ 233, 121, 167, 140, 159, 110, 188, 142,  41, 245, 249, 182,  47, 253, 180,  89,
+ 120, 152,   6, 106, 231,  70, 113, 186, 212,  37, 171,  66, 136, 162, 141, 250,
+ 114,   7, 185,  85, 248, 238, 172,  10,  54,  73,  42, 104,  60,  56, 241, 164,
+ 64,  40, 211, 123, 187, 201,  67, 193,  21, 227, 173, 244, 119, 199, 128, 158
+};
+
+static const unsigned char FSb2[256] =
+{
+ 224,   5,  88, 217, 103,  78, 129, 203, 201,  11, 174, 106, 213,  24,  93, 130,
+  70, 223, 214,  39, 138,  50,  75,  66, 219,  28, 158, 156,  58, 202,  37, 123,
+  13, 113,  95,  31, 248, 215,  62, 157, 124,  96, 185, 190, 188, 139,  22,  52,
+  77, 195, 114, 149, 171, 142, 186, 122, 179,   2, 180, 173, 162, 172, 216, 154,
+  23,  26,  53, 204, 247, 153,  97,  90, 232,  36,  86,  64, 225,  99,   9,  51,
+ 191, 152, 151, 133, 104, 252, 236,  10, 218, 111,  83,  98, 163,  46,   8, 175,
+  40, 176, 116, 194, 189,  54,  34,  56, 100,  30,  57,  44, 166,  48, 229,  68,
+ 253, 136, 159, 101, 135, 107, 244,  35,  72,  16, 209,  81, 192, 249, 210, 160,
+  85, 161,  65, 250,  67,  19, 196,  47, 168, 182,  60,  43, 193, 255, 200, 165,
+  32, 137,   0, 144,  71, 239, 234, 183,  21,   6, 205, 181,  18, 126, 187,  41,
+  15, 184,   7,   4, 155, 148,  33, 102, 230, 206, 237, 231,  59, 254, 127, 197,
+ 164,  55, 177,  76, 145, 110, 141, 118,   3,  45, 222, 150,  38, 125, 198,  92,
+ 211, 242,  79,  25,  63, 220, 121,  29,  82, 235, 243, 109,  94, 251, 105, 178,
+ 240,  49,  12, 212, 207, 140, 226, 117, 169,  74,  87, 132,  17,  69,  27, 245,
+ 228,  14, 115, 170, 241, 221,  89,  20, 108, 146,  84, 208, 120, 112, 227,  73,
+ 128,  80, 167, 246, 119, 147, 134, 131,  42, 199,  91, 233, 238, 143,   1,  61
+};
+
+static const unsigned char FSb3[256] =
+{
+  56,  65,  22, 118, 217, 147,  96, 242, 114, 194, 171, 154, 117,   6,  87, 160,
+ 145, 247, 181, 201, 162, 140, 210, 144, 246,   7, 167,  39, 142, 178,  73, 222,
+  67,  92, 215, 199,  62, 245, 143, 103,  31,  24, 110, 175,  47, 226, 133,  13,
+  83, 240, 156, 101, 234, 163, 174, 158, 236, 128,  45, 107, 168,  43,  54, 166,
+ 197, 134,  77,  51, 253, 102,  88, 150,  58,   9, 149,  16, 120, 216,  66, 204,
+ 239,  38, 229,  97,  26,  63,  59, 130, 182, 219, 212, 152, 232, 139,   2, 235,
+  10,  44,  29, 176, 111, 141, 136,  14,  25, 135,  78,  11, 169,  12, 121,  17,
+ 127,  34, 231,  89, 225, 218,  61, 200,  18,   4, 116,  84,  48, 126, 180,  40,
+  85, 104,  80, 190, 208, 196,  49, 203,  42, 173,  15, 202, 112, 255,  50, 105,
+   8,  98,   0,  36, 209, 251, 186, 237,  69, 129, 115, 109, 132, 159, 238,  74,
+ 195,  46, 193,   1, 230,  37,  72, 153, 185, 179, 123, 249, 206, 191, 223, 113,
+  41, 205, 108,  19, 100, 155,  99, 157, 192,  75, 183, 165, 137,  95, 177,  23,
+ 244, 188, 211,  70, 207,  55,  94,  71, 148, 250, 252,  91, 151, 254,  90, 172,
+  60,  76,   3,  53, 243,  35, 184,  93, 106, 146, 213,  33,  68,  81, 198, 125,
+  57, 131, 220, 170, 124, 119,  86,   5,  27, 164,  21,  52,  30,  28, 248,  82,
+  32,  20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227,  64,  79
+};
+
+static const unsigned char FSb4[256] =
+{
+ 112,  44, 179, 192, 228,  87, 234, 174,  35, 107,  69, 165, 237,  79,  29, 146,
+ 134, 175, 124,  31,  62, 220,  94,  11, 166,  57, 213,  93, 217,  90,  81, 108,
+ 139, 154, 251, 176, 116,  43, 240, 132, 223, 203,  52, 118, 109, 169, 209,   4,
+  20,  58, 222,  17,  50, 156,  83, 242, 254, 207, 195, 122,  36, 232,  96, 105,
+ 170, 160, 161,  98,  84,  30, 224, 100,  16,   0, 163, 117, 138, 230,   9, 221,
+ 135, 131, 205, 144, 115, 246, 157, 191,  82, 216, 200, 198, 129, 111,  19,  99,
+ 233, 167, 159, 188,  41, 249,  47, 180, 120,   6, 231, 113, 212, 171, 136, 141,
+ 114, 185, 248, 172,  54,  42,  60, 241,  64, 211, 187,  67,  21, 173, 119, 128,
+ 130, 236,  39, 229, 133,  53,  12,  65, 239, 147,  25,  33,  14,  78, 101, 189,
+ 184, 143, 235, 206,  48,  95, 197,  26, 225, 202,  71,  61,   1, 214,  86,  77,
+  13, 102, 204,  45,  18,  32, 177, 153,  76, 194, 126,   5, 183,  49,  23, 215,
+  88,  97,  27,  28,  15,  22,  24,  34,  68, 178, 181, 145,   8, 168, 252,  80,
+ 208, 125, 137, 151,  91, 149, 255, 210, 196,  72, 247, 219,   3, 218,  63, 148,
+  92,   2,  74,  51, 103, 243, 127, 226, 155,  38,  55,  59, 150,  75, 190,  46,
+ 121, 140, 110, 142, 245, 182, 253,  89, 152, 106,  70, 186,  37,  66, 162, 250,
+  7,  85, 238,  10,  73, 104,  56, 164,  40, 123, 201, 193, 227, 244, 199, 158
+};
+
+#define SBOX1(n) FSb[(n)]
+#define SBOX2(n) FSb2[(n)]
+#define SBOX3(n) FSb3[(n)]
+#define SBOX4(n) FSb4[(n)]
+
+#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
+
+static const unsigned char shifts[2][4][4] =
+{
+    {
+        { 1, 1, 1, 1 }, /* KL */
+        { 0, 0, 0, 0 }, /* KR */
+        { 1, 1, 1, 1 }, /* KA */
+        { 0, 0, 0, 0 }  /* KB */
+    },
+    {
+        { 1, 0, 1, 1 }, /* KL */
+        { 1, 1, 0, 1 }, /* KR */
+        { 1, 1, 1, 0 }, /* KA */
+        { 1, 1, 0, 1 }  /* KB */
+    }
+};
+
+static const signed char indexes[2][4][20] =
+{
+    {
+        {  0,  1,  2,  3,  8,  9, 10, 11, 38, 39,
+          36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */
+        { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */
+        {  4,  5,  6,  7, 12, 13, 14, 15, 16, 17,
+          18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */
+        { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }  /* KB -> RK */
+    },
+    {
+        {  0,  1,  2,  3, 61, 62, 63, 60, -1, -1,
+          -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */
+        { -1, -1, -1, -1,  8,  9, 10, 11, 16, 17,
+          18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */
+        { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59,
+          56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */
+        {  4,  5,  6,  7, 65, 66, 67, 64, 20, 21,
+          22, 23, -1, -1, -1, -1, 43, 40, 41, 42 }  /* KB -> RK */
+    }
+};
+
+static const signed char transposes[2][20] =
+{
+    {
+        21, 22, 23, 20,
+        -1, -1, -1, -1,
+        18, 19, 16, 17,
+        11,  8,  9, 10,
+        15, 12, 13, 14
+    },
+    {
+        25, 26, 27, 24,
+        29, 30, 31, 28,
+        18, 19, 16, 17,
+        -1, -1, -1, -1,
+        -1, -1, -1, -1
+    }
+};
+
+/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */
+#define ROTL(DEST, SRC, SHIFT)                                      \
+{                                                                   \
+    (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT));   \
+    (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT));   \
+    (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT));   \
+    (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT));   \
+}
+
+#define FL(XL, XR, KL, KR)                                          \
+{                                                                   \
+    (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR);   \
+    (XL) = ((XR) | (KR)) ^ (XL);                                    \
+}
+
+#define FLInv(YL, YR, KL, KR)                                       \
+{                                                                   \
+    (YL) = ((YR) | (KR)) ^ (YL);                                    \
+    (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR);   \
+}
+
+#define SHIFT_AND_PLACE(INDEX, OFFSET)                      \
+{                                                           \
+    TK[0] = KC[(OFFSET) * 4 + 0];                           \
+    TK[1] = KC[(OFFSET) * 4 + 1];                           \
+    TK[2] = KC[(OFFSET) * 4 + 2];                           \
+    TK[3] = KC[(OFFSET) * 4 + 3];                           \
+                                                            \
+    for( i = 1; i <= 4; i++ )                               \
+        if( shifts[(INDEX)][(OFFSET)][i -1] )               \
+            ROTL(TK + i * 4, TK, ( 15 * i ) % 32);          \
+                                                            \
+    for( i = 0; i < 20; i++ )                               \
+        if( indexes[(INDEX)][(OFFSET)][i] != -1 ) {         \
+            RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ];    \
+        }                                                   \
+}
+
+static void camellia_feistel( const uint32_t x[2], const uint32_t k[2],
+                              uint32_t z[2])
+{
+    uint32_t I0, I1;
+    I0 = x[0] ^ k[0];
+    I1 = x[1] ^ k[1];
+
+    I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) |
+         ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) |
+         ((uint32_t) SBOX3((I0 >>  8) & 0xFF) <<  8) |
+         ((uint32_t) SBOX4((I0      ) & 0xFF)      );
+    I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) |
+         ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) |
+         ((uint32_t) SBOX4((I1 >>  8) & 0xFF) <<  8) |
+         ((uint32_t) SBOX1((I1      ) & 0xFF)      );
+
+    I0 ^= (I1 << 8) | (I1 >> 24);
+    I1 ^= (I0 << 16) | (I0 >> 16);
+    I0 ^= (I1 >> 8) | (I1 << 24);
+    I1 ^= (I0 >> 8) | (I0 << 24);
+
+    z[0] ^= I1;
+    z[1] ^= I0;
+}
+
+void mbedtls_camellia_init( mbedtls_camellia_context *ctx )
+{
+    CAMELLIA_VALIDATE( ctx != NULL );
+    memset( ctx, 0, sizeof( mbedtls_camellia_context ) );
+}
+
+void mbedtls_camellia_free( mbedtls_camellia_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_camellia_context ) );
+}
+
+/*
+ * Camellia key schedule (encryption)
+ */
+int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits )
+{
+    int idx;
+    size_t i;
+    uint32_t *RK;
+    unsigned char t[64];
+    uint32_t SIGMA[6][2];
+    uint32_t KC[16];
+    uint32_t TK[20];
+
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( key != NULL );
+
+    RK = ctx->rk;
+
+    memset( t, 0, 64 );
+    memset( RK, 0, sizeof(ctx->rk) );
+
+    switch( keybits )
+    {
+        case 128: ctx->nr = 3; idx = 0; break;
+        case 192:
+        case 256: ctx->nr = 4; idx = 1; break;
+        default : return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
+    }
+
+    for( i = 0; i < keybits / 8; ++i )
+        t[i] = key[i];
+
+    if( keybits == 192 ) {
+        for( i = 0; i < 8; i++ )
+            t[24 + i] = ~t[16 + i];
+    }
+
+    /*
+     * Prepare SIGMA values
+     */
+    for( i = 0; i < 6; i++ ) {
+        GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 );
+        GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 );
+    }
+
+    /*
+     * Key storage in KC
+     * Order: KL, KR, KA, KB
+     */
+    memset( KC, 0, sizeof(KC) );
+
+    /* Store KL, KR */
+    for( i = 0; i < 8; i++ )
+        GET_UINT32_BE( KC[i], t, i * 4 );
+
+    /* Generate KA */
+    for( i = 0; i < 4; ++i )
+        KC[8 + i] = KC[i] ^ KC[4 + i];
+
+    camellia_feistel( KC + 8, SIGMA[0], KC + 10 );
+    camellia_feistel( KC + 10, SIGMA[1], KC + 8 );
+
+    for( i = 0; i < 4; ++i )
+        KC[8 + i] ^= KC[i];
+
+    camellia_feistel( KC + 8, SIGMA[2], KC + 10 );
+    camellia_feistel( KC + 10, SIGMA[3], KC + 8 );
+
+    if( keybits > 128 ) {
+        /* Generate KB */
+        for( i = 0; i < 4; ++i )
+            KC[12 + i] = KC[4 + i] ^ KC[8 + i];
+
+        camellia_feistel( KC + 12, SIGMA[4], KC + 14 );
+        camellia_feistel( KC + 14, SIGMA[5], KC + 12 );
+    }
+
+    /*
+     * Generating subkeys
+     */
+
+    /* Manipulating KL */
+    SHIFT_AND_PLACE( idx, 0 );
+
+    /* Manipulating KR */
+    if( keybits > 128 ) {
+        SHIFT_AND_PLACE( idx, 1 );
+    }
+
+    /* Manipulating KA */
+    SHIFT_AND_PLACE( idx, 2 );
+
+    /* Manipulating KB */
+    if( keybits > 128 ) {
+        SHIFT_AND_PLACE( idx, 3 );
+    }
+
+    /* Do transpositions */
+    for( i = 0; i < 20; i++ ) {
+        if( transposes[idx][i] != -1 ) {
+            RK[32 + 12 * idx + i] = RK[transposes[idx][i]];
+        }
+    }
+
+    return( 0 );
+}
+
+/*
+ * Camellia key schedule (decryption)
+ */
+int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx,
+                                 const unsigned char *key,
+                                 unsigned int keybits )
+{
+    int idx, ret;
+    size_t i;
+    mbedtls_camellia_context cty;
+    uint32_t *RK;
+    uint32_t *SK;
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( key != NULL );
+
+    mbedtls_camellia_init( &cty );
+
+    /* Also checks keybits */
+    if( ( ret = mbedtls_camellia_setkey_enc( &cty, key, keybits ) ) != 0 )
+        goto exit;
+
+    ctx->nr = cty.nr;
+    idx = ( ctx->nr == 4 );
+
+    RK = ctx->rk;
+    SK = cty.rk + 24 * 2 + 8 * idx * 2;
+
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+
+    for( i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4 )
+    {
+        *RK++ = *SK++;
+        *RK++ = *SK++;
+    }
+
+    SK -= 2;
+
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+    *RK++ = *SK++;
+
+exit:
+    mbedtls_camellia_free( &cty );
+
+    return( ret );
+}
+
+/*
+ * Camellia-ECB block encryption/decryption
+ */
+int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
+                    int mode,
+                    const unsigned char input[16],
+                    unsigned char output[16] )
+{
+    int NR;
+    uint32_t *RK, X[4];
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+                           mode == MBEDTLS_CAMELLIA_DECRYPT );
+    CAMELLIA_VALIDATE_RET( input  != NULL );
+    CAMELLIA_VALIDATE_RET( output != NULL );
+
+    ( (void) mode );
+
+    NR = ctx->nr;
+    RK = ctx->rk;
+
+    GET_UINT32_BE( X[0], input,  0 );
+    GET_UINT32_BE( X[1], input,  4 );
+    GET_UINT32_BE( X[2], input,  8 );
+    GET_UINT32_BE( X[3], input, 12 );
+
+    X[0] ^= *RK++;
+    X[1] ^= *RK++;
+    X[2] ^= *RK++;
+    X[3] ^= *RK++;
+
+    while( NR ) {
+        --NR;
+        camellia_feistel( X, RK, X + 2 );
+        RK += 2;
+        camellia_feistel( X + 2, RK, X );
+        RK += 2;
+        camellia_feistel( X, RK, X + 2 );
+        RK += 2;
+        camellia_feistel( X + 2, RK, X );
+        RK += 2;
+        camellia_feistel( X, RK, X + 2 );
+        RK += 2;
+        camellia_feistel( X + 2, RK, X );
+        RK += 2;
+
+        if( NR ) {
+            FL(X[0], X[1], RK[0], RK[1]);
+            RK += 2;
+            FLInv(X[2], X[3], RK[0], RK[1]);
+            RK += 2;
+        }
+    }
+
+    X[2] ^= *RK++;
+    X[3] ^= *RK++;
+    X[0] ^= *RK++;
+    X[1] ^= *RK++;
+
+    PUT_UINT32_BE( X[2], output,  0 );
+    PUT_UINT32_BE( X[3], output,  4 );
+    PUT_UINT32_BE( X[0], output,  8 );
+    PUT_UINT32_BE( X[1], output, 12 );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * Camellia-CBC buffer encryption/decryption
+ */
+int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx,
+                                int mode,
+                                size_t length,
+                                unsigned char iv[16],
+                                const unsigned char *input,
+                                unsigned char *output )
+{
+    int i;
+    unsigned char temp[16];
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+                           mode == MBEDTLS_CAMELLIA_DECRYPT );
+    CAMELLIA_VALIDATE_RET( iv != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || input  != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
+
+    if( length % 16 )
+        return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH );
+
+    if( mode == MBEDTLS_CAMELLIA_DECRYPT )
+    {
+        while( length > 0 )
+        {
+            memcpy( temp, input, 16 );
+            mbedtls_camellia_crypt_ecb( ctx, mode, input, output );
+
+            for( i = 0; i < 16; i++ )
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+            memcpy( iv, temp, 16 );
+
+            input  += 16;
+            output += 16;
+            length -= 16;
+        }
+    }
+    else
+    {
+        while( length > 0 )
+        {
+            for( i = 0; i < 16; i++ )
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+            mbedtls_camellia_crypt_ecb( ctx, mode, output, output );
+            memcpy( iv, output, 16 );
+
+            input  += 16;
+            output += 16;
+            length -= 16;
+        }
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * Camellia-CFB128 buffer encryption/decryption
+ */
+int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx,
+                       int mode,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c;
+    size_t n;
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( mode == MBEDTLS_CAMELLIA_ENCRYPT ||
+                           mode == MBEDTLS_CAMELLIA_DECRYPT );
+    CAMELLIA_VALIDATE_RET( iv     != NULL );
+    CAMELLIA_VALIDATE_RET( iv_off != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || input  != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *iv_off;
+    if( n >= 16 )
+        return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
+
+    if( mode == MBEDTLS_CAMELLIA_DECRYPT )
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv );
+
+            c = *input++;
+            *output++ = (unsigned char)( c ^ iv[n] );
+            iv[n] = (unsigned char) c;
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+    else
+    {
+        while( length-- )
+        {
+            if( n == 0 )
+                mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv );
+
+            iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
+
+            n = ( n + 1 ) & 0x0F;
+        }
+    }
+
+    *iv_off = n;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * Camellia-CTR buffer encryption/decryption
+ */
+int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx,
+                       size_t length,
+                       size_t *nc_off,
+                       unsigned char nonce_counter[16],
+                       unsigned char stream_block[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int c, i;
+    size_t n;
+    CAMELLIA_VALIDATE_RET( ctx != NULL );
+    CAMELLIA_VALIDATE_RET( nonce_counter != NULL );
+    CAMELLIA_VALIDATE_RET( stream_block  != NULL );
+    CAMELLIA_VALIDATE_RET( nc_off != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || input  != NULL );
+    CAMELLIA_VALIDATE_RET( length == 0 || output != NULL );
+
+    n = *nc_off;
+    if( n >= 16 )
+        return( MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA );
+
+    while( length-- )
+    {
+        if( n == 0 ) {
+            mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter,
+                                stream_block );
+
+            for( i = 16; i > 0; i-- )
+                if( ++nonce_counter[i - 1] != 0 )
+                    break;
+        }
+        c = *input++;
+        *output++ = (unsigned char)( c ^ stream_block[n] );
+
+        n = ( n + 1 ) & 0x0F;
+    }
+
+    *nc_off = n;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+#endif /* !MBEDTLS_CAMELLIA_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/*
+ * Camellia test vectors from:
+ *
+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html:
+ *   http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt
+ *   http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt
+ *                      (For each bitlength: Key 0, Nr 39)
+ */
+#define CAMELLIA_TESTS_ECB  2
+
+static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] =
+{
+    {
+        { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+          0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
+        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+    },
+    {
+        { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+          0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
+          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
+        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+    },
+    {
+        { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+          0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
+          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+          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 unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] =
+{
+    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+      0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
+    { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+};
+
+static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] =
+{
+    {
+        { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
+          0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 },
+        { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE,
+          0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 }
+    },
+    {
+        { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
+          0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 },
+        { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9,
+          0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 }
+    },
+    {
+        { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
+          0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 },
+        { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C,
+          0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 }
+    }
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#define CAMELLIA_TESTS_CBC  3
+
+static const unsigned char camellia_test_cbc_key[3][32] =
+{
+        { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
+          0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
+    ,
+        { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
+          0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
+          0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }
+    ,
+        { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
+          0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
+          0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
+          0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
+};
+
+static const unsigned char camellia_test_cbc_iv[16] =
+
+    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+      0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }
+;
+
+static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] =
+{
+    { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
+      0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A },
+    { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
+      0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 },
+    { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
+      0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF }
+
+};
+
+static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] =
+{
+    {
+        { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0,
+          0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB },
+        { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78,
+          0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 },
+        { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B,
+          0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 }
+    },
+    {
+        { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2,
+          0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 },
+        { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42,
+          0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 },
+        { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8,
+          0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 }
+    },
+    {
+        { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A,
+          0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA },
+        { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40,
+          0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 },
+        { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA,
+          0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 }
+    }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * Camellia-CTR test vectors from:
+ *
+ * http://www.faqs.org/rfcs/rfc5528.html
+ */
+
+static const unsigned char camellia_test_ctr_key[3][16] =
+{
+    { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
+      0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
+    { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
+      0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
+    { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
+      0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
+};
+
+static const unsigned char camellia_test_ctr_nonce_counter[3][16] =
+{
+    { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
+    { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
+      0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
+    { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
+      0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
+};
+
+static const unsigned char camellia_test_ctr_pt[3][48] =
+{
+    { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
+      0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
+
+    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+      0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+      0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+      0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
+
+    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+      0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+      0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+      0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+      0x20, 0x21, 0x22, 0x23 }
+};
+
+static const unsigned char camellia_test_ctr_ct[3][48] =
+{
+    { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A,
+      0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F },
+    { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4,
+      0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44,
+      0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7,
+      0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 },
+    { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88,
+      0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73,
+      0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1,
+      0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD,
+      0xDF, 0x50, 0x86, 0x96 }
+};
+
+static const int camellia_test_ctr_len[3] =
+    { 16, 32, 36 };
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+/*
+ * Checkup routine
+ */
+int mbedtls_camellia_self_test( int verbose )
+{
+    int i, j, u, v;
+    unsigned char key[32];
+    unsigned char buf[64];
+    unsigned char src[16];
+    unsigned char dst[16];
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    unsigned char iv[16];
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    size_t offset, len;
+    unsigned char nonce_counter[16];
+    unsigned char stream_block[16];
+#endif
+
+    mbedtls_camellia_context ctx;
+
+    memset( key, 0, 32 );
+
+    for( j = 0; j < 6; j++ ) {
+        u = j >> 1;
+    v = j & 1;
+
+    if( verbose != 0 )
+        mbedtls_printf( "  CAMELLIA-ECB-%3d (%s): ", 128 + u * 64,
+                         (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc");
+
+    for( i = 0; i < CAMELLIA_TESTS_ECB; i++ ) {
+        memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u );
+
+        if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
+            mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
+            memcpy( src, camellia_test_ecb_cipher[u][i], 16 );
+            memcpy( dst, camellia_test_ecb_plain[i], 16 );
+        } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
+            mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
+            memcpy( src, camellia_test_ecb_plain[i], 16 );
+            memcpy( dst, camellia_test_ecb_cipher[u][i], 16 );
+        }
+
+        mbedtls_camellia_crypt_ecb( &ctx, v, src, buf );
+
+        if( memcmp( buf, dst, 16 ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            return( 1 );
+        }
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    /*
+     * CBC mode
+     */
+    for( j = 0; j < 6; j++ )
+    {
+        u = j >> 1;
+        v = j  & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
+                             ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
+
+        memcpy( src, camellia_test_cbc_iv, 16 );
+        memcpy( dst, camellia_test_cbc_iv, 16 );
+        memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u );
+
+        if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
+            mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
+        } else {
+            mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
+        }
+
+        for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
+
+            if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
+                memcpy( iv , src, 16 );
+                memcpy( src, camellia_test_cbc_cipher[u][i], 16 );
+                memcpy( dst, camellia_test_cbc_plain[i], 16 );
+            } else { /* MBEDTLS_CAMELLIA_ENCRYPT */
+                memcpy( iv , dst, 16 );
+                memcpy( src, camellia_test_cbc_plain[i], 16 );
+                memcpy( dst, camellia_test_cbc_cipher[u][i], 16 );
+            }
+
+            mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf );
+
+            if( memcmp( buf, dst, 16 ) != 0 )
+            {
+                if( verbose != 0 )
+                    mbedtls_printf( "failed\n" );
+
+                return( 1 );
+            }
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    /*
+     * CTR mode
+     */
+    for( i = 0; i < 6; i++ )
+    {
+        u = i >> 1;
+        v = i  & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  CAMELLIA-CTR-128 (%s): ",
+                             ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
+
+        memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 );
+        memcpy( key, camellia_test_ctr_key[u], 16 );
+
+        offset = 0;
+        mbedtls_camellia_setkey_enc( &ctx, key, 128 );
+
+        if( v == MBEDTLS_CAMELLIA_DECRYPT )
+        {
+            len = camellia_test_ctr_len[u];
+            memcpy( buf, camellia_test_ctr_ct[u], len );
+
+            mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
+                                buf, buf );
+
+            if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 )
+            {
+                if( verbose != 0 )
+                    mbedtls_printf( "failed\n" );
+
+                return( 1 );
+            }
+        }
+        else
+        {
+            len = camellia_test_ctr_len[u];
+            memcpy( buf, camellia_test_ctr_pt[u], len );
+
+            mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
+                                buf, buf );
+
+            if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 )
+            {
+                if( verbose != 0 )
+                    mbedtls_printf( "failed\n" );
+
+                return( 1 );
+            }
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_CAMELLIA_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ccm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ccm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ccm.c	(revision 398)
@@ -0,0 +1,539 @@
+/*
+ *  NIST SP800-38C compliant CCM implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * Definition of CCM:
+ * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
+ * RFC 3610 "Counter with CBC-MAC (CCM)"
+ *
+ * Related:
+ * RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CCM_C)
+
+#include "mbedtls/ccm.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#if !defined(MBEDTLS_CCM_ALT)
+
+#define CCM_VALIDATE_RET( cond ) \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT )
+#define CCM_VALIDATE( cond ) \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#define CCM_ENCRYPT 0
+#define CCM_DECRYPT 1
+
+/*
+ * Initialize context
+ */
+void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
+{
+    CCM_VALIDATE( ctx != NULL );
+    memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
+}
+
+int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
+                        mbedtls_cipher_id_t cipher,
+                        const unsigned char *key,
+                        unsigned int keybits )
+{
+    int ret;
+    const mbedtls_cipher_info_t *cipher_info;
+
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( key != NULL );
+
+    cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
+    if( cipher_info == NULL )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    if( cipher_info->block_size != 16 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    mbedtls_cipher_free( &ctx->cipher_ctx );
+
+    if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
+                               MBEDTLS_ENCRYPT ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Free context
+ */
+void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+    mbedtls_cipher_free( &ctx->cipher_ctx );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
+}
+
+/*
+ * Macros for common operations.
+ * Results in smaller compiled code than static inline functions.
+ */
+
+/*
+ * Update the CBC-MAC state in y using a block in b
+ * (Always using b as the source helps the compiler optimise a bit better.)
+ */
+#define UPDATE_CBC_MAC                                                      \
+    for( i = 0; i < 16; i++ )                                               \
+        y[i] ^= b[i];                                                       \
+                                                                            \
+    if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \
+        return( ret );
+
+/*
+ * Encrypt or decrypt a partial block with CTR
+ * Warning: using b for temporary storage! src and dst must not be b!
+ * This avoids allocating one more 16 bytes buffer while allowing src == dst.
+ */
+#define CTR_CRYPT( dst, src, len  )                                            \
+    if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 )  \
+        return( ret );                                                         \
+                                                                               \
+    for( i = 0; i < len; i++ )                                                 \
+        dst[i] = src[i] ^ b[i];
+
+/*
+ * Authenticated encryption or decryption
+ */
+static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
+                           const unsigned char *iv, size_t iv_len,
+                           const unsigned char *add, size_t add_len,
+                           const unsigned char *input, unsigned char *output,
+                           unsigned char *tag, size_t tag_len )
+{
+    int ret;
+    unsigned char i;
+    unsigned char q;
+    size_t len_left, olen;
+    unsigned char b[16];
+    unsigned char y[16];
+    unsigned char ctr[16];
+    const unsigned char *src;
+    unsigned char *dst;
+
+    /*
+     * Check length requirements: SP800-38C A.1
+     * Additional requirement: a < 2^16 - 2^8 to simplify the code.
+     * 'length' checked later (when writing it to the first block)
+     *
+     * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4).
+     */
+    if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    /* Also implies q is within bounds */
+    if( iv_len < 7 || iv_len > 13 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    if( add_len > 0xFF00 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    q = 16 - 1 - (unsigned char) iv_len;
+
+    /*
+     * First block B_0:
+     * 0        .. 0        flags
+     * 1        .. iv_len   nonce (aka iv)
+     * iv_len+1 .. 15       length
+     *
+     * With flags as (bits):
+     * 7        0
+     * 6        add present?
+     * 5 .. 3   (t - 2) / 2
+     * 2 .. 0   q - 1
+     */
+    b[0] = 0;
+    b[0] |= ( add_len > 0 ) << 6;
+    b[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
+    b[0] |= q - 1;
+
+    memcpy( b + 1, iv, iv_len );
+
+    for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
+        b[15-i] = (unsigned char)( len_left & 0xFF );
+
+    if( len_left > 0 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+
+    /* Start CBC-MAC with first block */
+    memset( y, 0, 16 );
+    UPDATE_CBC_MAC;
+
+    /*
+     * If there is additional data, update CBC-MAC with
+     * add_len, add, 0 (padding to a block boundary)
+     */
+    if( add_len > 0 )
+    {
+        size_t use_len;
+        len_left = add_len;
+        src = add;
+
+        memset( b, 0, 16 );
+        b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
+        b[1] = (unsigned char)( ( add_len      ) & 0xFF );
+
+        use_len = len_left < 16 - 2 ? len_left : 16 - 2;
+        memcpy( b + 2, src, use_len );
+        len_left -= use_len;
+        src += use_len;
+
+        UPDATE_CBC_MAC;
+
+        while( len_left > 0 )
+        {
+            use_len = len_left > 16 ? 16 : len_left;
+
+            memset( b, 0, 16 );
+            memcpy( b, src, use_len );
+            UPDATE_CBC_MAC;
+
+            len_left -= use_len;
+            src += use_len;
+        }
+    }
+
+    /*
+     * Prepare counter block for encryption:
+     * 0        .. 0        flags
+     * 1        .. iv_len   nonce (aka iv)
+     * iv_len+1 .. 15       counter (initially 1)
+     *
+     * With flags as (bits):
+     * 7 .. 3   0
+     * 2 .. 0   q - 1
+     */
+    ctr[0] = q - 1;
+    memcpy( ctr + 1, iv, iv_len );
+    memset( ctr + 1 + iv_len, 0, q );
+    ctr[15] = 1;
+
+    /*
+     * Authenticate and {en,de}crypt the message.
+     *
+     * The only difference between encryption and decryption is
+     * the respective order of authentication and {en,de}cryption.
+     */
+    len_left = length;
+    src = input;
+    dst = output;
+
+    while( len_left > 0 )
+    {
+        size_t use_len = len_left > 16 ? 16 : len_left;
+
+        if( mode == CCM_ENCRYPT )
+        {
+            memset( b, 0, 16 );
+            memcpy( b, src, use_len );
+            UPDATE_CBC_MAC;
+        }
+
+        CTR_CRYPT( dst, src, use_len );
+
+        if( mode == CCM_DECRYPT )
+        {
+            memset( b, 0, 16 );
+            memcpy( b, dst, use_len );
+            UPDATE_CBC_MAC;
+        }
+
+        dst += use_len;
+        src += use_len;
+        len_left -= use_len;
+
+        /*
+         * Increment counter.
+         * No need to check for overflow thanks to the length check above.
+         */
+        for( i = 0; i < q; i++ )
+            if( ++ctr[15-i] != 0 )
+                break;
+    }
+
+    /*
+     * Authentication: reset counter and crypt/mask internal tag
+     */
+    for( i = 0; i < q; i++ )
+        ctr[15-i] = 0;
+
+    CTR_CRYPT( y, y, 16 );
+    memcpy( tag, y, tag_len );
+
+    return( 0 );
+}
+
+/*
+ * Authenticated encryption
+ */
+int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *add, size_t add_len,
+                         const unsigned char *input, unsigned char *output,
+                         unsigned char *tag, size_t tag_len )
+{
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+    return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len,
+                            add, add_len, input, output, tag, tag_len ) );
+}
+
+int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *add, size_t add_len,
+                         const unsigned char *input, unsigned char *output,
+                         unsigned char *tag, size_t tag_len )
+{
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+    if( tag_len == 0 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add,
+                add_len, input, output, tag, tag_len ) );
+}
+
+/*
+ * Authenticated decryption
+ */
+int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
+                      const unsigned char *iv, size_t iv_len,
+                      const unsigned char *add, size_t add_len,
+                      const unsigned char *input, unsigned char *output,
+                      const unsigned char *tag, size_t tag_len )
+{
+    int ret;
+    unsigned char check_tag[16];
+    unsigned char i;
+    int diff;
+
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+    if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length,
+                                iv, iv_len, add, add_len,
+                                input, output, check_tag, tag_len ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /* Check tag in "constant-time" */
+    for( diff = 0, i = 0; i < tag_len; i++ )
+        diff |= tag[i] ^ check_tag[i];
+
+    if( diff != 0 )
+    {
+        mbedtls_platform_zeroize( output, length );
+        return( MBEDTLS_ERR_CCM_AUTH_FAILED );
+    }
+
+    return( 0 );
+}
+
+int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
+                      const unsigned char *iv, size_t iv_len,
+                      const unsigned char *add, size_t add_len,
+                      const unsigned char *input, unsigned char *output,
+                      const unsigned char *tag, size_t tag_len )
+{
+    CCM_VALIDATE_RET( ctx != NULL );
+    CCM_VALIDATE_RET( iv != NULL );
+    CCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    CCM_VALIDATE_RET( length == 0 || input != NULL );
+    CCM_VALIDATE_RET( length == 0 || output != NULL );
+    CCM_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+    if( tag_len == 0 )
+        return( MBEDTLS_ERR_CCM_BAD_INPUT );
+
+    return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add,
+                add_len, input, output, tag, tag_len ) );
+}
+#endif /* !MBEDTLS_CCM_ALT */
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+/*
+ * Examples 1 to 3 from SP800-38C Appendix C
+ */
+
+#define NB_TESTS 3
+#define CCM_SELFTEST_PT_MAX_LEN 24
+#define CCM_SELFTEST_CT_MAX_LEN 32
+/*
+ * The data is the same for all tests, only the used length changes
+ */
+static const unsigned char key[] = {
+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
+};
+
+static const unsigned char iv[] = {
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b
+};
+
+static const unsigned char ad[] = {
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13
+};
+
+static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = {
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+};
+
+static const size_t iv_len [NB_TESTS] = { 7, 8,  12 };
+static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
+static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
+static const size_t tag_len[NB_TESTS] = { 4, 6,  8  };
+
+static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
+    {   0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
+    {   0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
+        0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
+        0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd },
+    {   0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a,
+        0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b,
+        0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5,
+        0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 }
+};
+
+int mbedtls_ccm_self_test( int verbose )
+{
+    mbedtls_ccm_context ctx;
+    /*
+     * Some hardware accelerators require the input and output buffers
+     * would be in RAM, because the flash is not accessible.
+     * Use buffers on the stack to hold the test vectors data.
+     */
+    unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN];
+    unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN];
+    size_t i;
+    int ret;
+
+    mbedtls_ccm_init( &ctx );
+
+    if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  CCM: setup failed" );
+
+        return( 1 );
+    }
+
+    for( i = 0; i < NB_TESTS; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  CCM-AES #%u: ", (unsigned int) i + 1 );
+
+        memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
+        memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
+        memcpy( plaintext, msg, msg_len[i] );
+
+        ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i],
+                                           iv, iv_len[i], ad, add_len[i],
+                                           plaintext, ciphertext,
+                                           ciphertext + msg_len[i], tag_len[i] );
+
+        if( ret != 0 ||
+            memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            return( 1 );
+        }
+        memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
+
+        ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i],
+                                        iv, iv_len[i], ad, add_len[i],
+                                        ciphertext, plaintext,
+                                        ciphertext + msg_len[i], tag_len[i] );
+
+        if( ret != 0 ||
+            memcmp( plaintext, msg, msg_len[i] ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            return( 1 );
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    mbedtls_ccm_free( &ctx );
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#endif /* MBEDTLS_CCM_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/certs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/certs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/certs.c	(revision 398)
@@ -0,0 +1,406 @@
+/*
+ *  X.509 test certificates
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "mbedtls/certs.h"
+
+#if defined(MBEDTLS_CERTS_C)
+
+#if defined(MBEDTLS_ECDSA_C)
+#define TEST_CA_CRT_EC                                                  \
+"-----BEGIN CERTIFICATE-----\r\n"                                       \
+"MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT\r\n"  \
+"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n"  \
+"QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT\r\n"  \
+"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n"  \
+"QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu\r\n"  \
+"ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy\r\n"  \
+"aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g\r\n"  \
+"JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7\r\n"  \
+"NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE\r\n"  \
+"AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w\r\n"  \
+"CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56\r\n"  \
+"t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv\r\n"  \
+"uCjn8pwUOkABXK8Mss90fzCfCEOtIA==\r\n"                                  \
+"-----END CERTIFICATE-----\r\n"
+const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC;
+const size_t mbedtls_test_ca_crt_ec_len = sizeof( mbedtls_test_ca_crt_ec );
+
+const char mbedtls_test_ca_key_ec[] =
+"-----BEGIN EC PRIVATE KEY-----\r\n"
+"Proc-Type: 4,ENCRYPTED\r\n"
+"DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n"
+"\r\n"
+"IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n"
+"ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n"
+"UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n"
+"a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n"
+"-----END EC PRIVATE KEY-----\r\n";
+const size_t mbedtls_test_ca_key_ec_len = sizeof( mbedtls_test_ca_key_ec );
+
+const char mbedtls_test_ca_pwd_ec[] = "PolarSSLTest";
+const size_t mbedtls_test_ca_pwd_ec_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1;
+
+const char mbedtls_test_srv_crt_ec[] =
+"-----BEGIN CERTIFICATE-----\r\n"
+"MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n"
+"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n"
+"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n"
+"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n"
+"CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n"
+"2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n"
+"BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n"
+"PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n"
+"clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n"
+"CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n"
+"C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n"
+"fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n"
+"-----END CERTIFICATE-----\r\n";
+const size_t mbedtls_test_srv_crt_ec_len = sizeof( mbedtls_test_srv_crt_ec );
+
+const char mbedtls_test_srv_key_ec[] =
+"-----BEGIN EC PRIVATE KEY-----\r\n"
+"MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n"
+"AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n"
+"6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n"
+"-----END EC PRIVATE KEY-----\r\n";
+const size_t mbedtls_test_srv_key_ec_len = sizeof( mbedtls_test_srv_key_ec );
+
+const char mbedtls_test_cli_crt_ec[] =
+"-----BEGIN CERTIFICATE-----\r\n"
+"MIICLDCCAbKgAwIBAgIBDTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n"
+"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n"
+"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjBBMQswCQYDVQQGEwJOTDERMA8G\r\n"
+"A1UEChMIUG9sYXJTU0wxHzAdBgNVBAMTFlBvbGFyU1NMIFRlc3QgQ2xpZW50IDIw\r\n"
+"WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARX5a6xc9/TrLuTuIH/Eq7u5lOszlVT\r\n"
+"9jQOzC7jYyUL35ji81xgNpbA1RgUcOV/n9VLRRjlsGzVXPiWj4dwo+THo4GdMIGa\r\n"
+"MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMG4GA1Ud\r\n"
+"IwRnMGWAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8oUKkQDA+MQswCQYDVQQGEwJOTDER\r\n"
+"MA8GA1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0GC\r\n"
+"CQDBQ+J+YkPM6DAKBggqhkjOPQQDAgNoADBlAjBKZQ17IIOimbmoD/yN7o89u3BM\r\n"
+"lgOsjnhw3fIOoLIWy2WOGsk/LGF++DzvrRzuNiACMQCd8iem1XS4JK7haj8xocpU\r\n"
+"LwjQje5PDGHfd3h9tP38Qknu5bJqws0md2KOKHyeV0U=\r\n"
+"-----END CERTIFICATE-----\r\n";
+const size_t mbedtls_test_cli_crt_ec_len = sizeof( mbedtls_test_cli_crt_ec );
+
+const char mbedtls_test_cli_key_ec[] =
+"-----BEGIN EC PRIVATE KEY-----\r\n"
+"MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n"
+"AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n"
+"wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n"
+"-----END EC PRIVATE KEY-----\r\n";
+const size_t mbedtls_test_cli_key_ec_len = sizeof( mbedtls_test_cli_key_ec );
+#endif /* MBEDTLS_ECDSA_C */
+
+#if defined(MBEDTLS_RSA_C)
+
+#if defined(MBEDTLS_SHA256_C)
+#define TEST_CA_CRT_RSA_SHA256                                          \
+"-----BEGIN CERTIFICATE-----\r\n"                                       \
+"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n"  \
+"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"  \
+"MTcwNTA0MTY1NzAxWhcNMjcwNTA1MTY1NzAxWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n"  \
+"A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n"  \
+"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n"  \
+"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n"  \
+"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n"  \
+"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n"  \
+"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n"  \
+"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n"  \
+"gZUwgZIwHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/MGMGA1UdIwRcMFqA\r\n"  \
+"FLRa5KWz3tJS9rnVppUP6z68x/3/oT+kPTA7MQswCQYDVQQGEwJOTDERMA8GA1UE\r\n"  \
+"CgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0GCAQAwDAYDVR0T\r\n"  \
+"BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAHK/HHrTZMnnVMpde1io+voAtql7j\r\n"  \
+"4sRhLrjD7o3THtwRbDa2diCvpq0Sq23Ng2LMYoXsOxoL/RQK3iN7UKxV3MKPEr0w\r\n"  \
+"XQS+kKQqiT2bsfrjnWMVHZtUOMpm6FNqcdGm/Rss3vKda2lcKl8kUnq/ylc1+QbB\r\n"  \
+"G6A6tUvQcr2ZyWfVg+mM5XkhTrOOXus2OLikb4WwEtJTJRNE0f+yPODSUz0/vT57\r\n"  \
+"ApH0CnB80bYJshYHPHHymOtleAB8KSYtqm75g/YNobjnjB6cm4HkW3OZRVIl6fYY\r\n"  \
+"n20NRVA1Vjs6GAROr4NqW4k/+LofY9y0LLDE+p0oIEKXIsIvhPr39swxSA==\r\n"      \
+"-----END CERTIFICATE-----\r\n"
+
+const char   mbedtls_test_ca_crt_rsa[]   = TEST_CA_CRT_RSA_SHA256;
+const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa );
+#define TEST_CA_CRT_RSA_SOME
+
+static const char mbedtls_test_ca_crt_rsa_sha256[] = TEST_CA_CRT_RSA_SHA256;
+
+#endif
+
+#if !defined(TEST_CA_CRT_RSA_SOME) || defined(MBEDTLS_SHA1_C)
+#define TEST_CA_CRT_RSA_SHA1                                            \
+"-----BEGIN CERTIFICATE-----\r\n"                                       \
+"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"  \
+"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"  \
+"MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n"  \
+"A1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n"  \
+"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n"  \
+"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n"  \
+"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n"  \
+"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n"  \
+"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n"  \
+"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n"  \
+"gZUwgZIwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUtFrkpbPe0lL2udWmlQ/rPrzH\r\n"  \
+"/f8wYwYDVR0jBFwwWoAUtFrkpbPe0lL2udWmlQ/rPrzH/f+hP6Q9MDsxCzAJBgNV\r\n"  \
+"BAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEZMBcGA1UEAxMQUG9sYXJTU0wgVGVz\r\n"  \
+"dCBDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAuP1U2ABUkIslsCfdlc2i94QHHYeJ\r\n"  \
+"SsR4EdgHtdciUI5I62J6Mom+Y0dT/7a+8S6MVMCZP6C5NyNyXw1GWY/YR82XTJ8H\r\n"  \
+"DBJiCTok5DbZ6SzaONBzdWHXwWwmi5vg1dxn7YxrM9d0IjxM27WNKs4sDQhZBQkF\r\n"  \
+"pjmfs2cb4oPl4Y9T9meTx/lvdkRYEug61Jfn6cA+qHpyPYdTH+UshITnmp5/Ztkf\r\n"  \
+"m/UTSLBNFNHesiTZeH31NcxYGdHSme9Nc/gfidRa0FLOCfWxRlFqAI47zG9jAQCZ\r\n"  \
+"7Z2mCGDNMhjQc+BYcdnl0lPXjdDK6V0qCg1dVewhUBcW5gZKzV7e9+DpVA==\r\n"      \
+"-----END CERTIFICATE-----\r\n"
+
+#if !defined (TEST_CA_CRT_RSA_SOME)
+const char   mbedtls_test_ca_crt_rsa[]   = TEST_CA_CRT_RSA_SHA1;
+const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa );
+#endif
+
+static const char mbedtls_test_ca_crt_rsa_sha1[] = TEST_CA_CRT_RSA_SHA1;
+
+#endif
+
+const char mbedtls_test_ca_key_rsa[] =
+"-----BEGIN RSA PRIVATE KEY-----\r\n"
+"Proc-Type: 4,ENCRYPTED\r\n"
+"DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n"
+"\r\n"
+"9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n"
+"7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n"
+"Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n"
+"PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n"
+"GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n"
+"gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n"
+"QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n"
+"PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n"
+"vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n"
+"WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n"
+"JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n"
+"KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n"
+"Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n"
+"9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n"
+"iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n"
+"tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n"
+"P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n"
+"1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n"
+"nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n"
+"X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n"
+"rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n"
+"L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n"
+"I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n"
+"wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n"
+"P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n"
+"-----END RSA PRIVATE KEY-----\r\n";
+const size_t mbedtls_test_ca_key_rsa_len = sizeof( mbedtls_test_ca_key_rsa );
+
+const char mbedtls_test_ca_pwd_rsa[] = "PolarSSLTest";
+const size_t mbedtls_test_ca_pwd_rsa_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1;
+
+/* tests/data_files/server2.crt */
+const char mbedtls_test_srv_crt_rsa[] =
+"-----BEGIN CERTIFICATE-----\r\n"
+"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n"
+"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
+"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n"
+"A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n"
+"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n"
+"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n"
+"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n"
+"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n"
+"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n"
+"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n"
+"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n"
+"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAAFzC0rF\r\n"
+"y6De8WMcdgQrEw3AhBHFjzqnxZw1ene4IBSC7lTw8rBSy3jOWQdPUWn+0y/pCeeF\r\n"
+"kti6sevFdl1hLemGtd4q+T9TKEKGg3ND4ARfB5AUZZ9uEHq8WBkiwus5clGS17Qd\r\n"
+"dS/TOisB59tQruLx1E1bPLtBKyqk4koC5WAULJwfpswGSyWJTpYwIpxcWE3D2tBu\r\n"
+"UB6MZfXZFzWmWEOyKbeoXjXe8GBCGgHLywvYDsGQ36HSGtEsAvR2QaTLSxWYcfk1\r\n"
+"fbDn4jSWkb4yZy1r01UEigFQtONieGwRFaUqEcFJHJvEEGVgh9keaVlOj2vrwf5r\r\n"
+"4mN4lW7gLdenN6g=\r\n"
+"-----END CERTIFICATE-----\r\n";
+const size_t mbedtls_test_srv_crt_rsa_len = sizeof( mbedtls_test_srv_crt_rsa );
+
+/* tests/data_files/server2.key */
+const char mbedtls_test_srv_key_rsa[] =
+"-----BEGIN RSA PRIVATE KEY-----\r\n"
+"MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n"
+"lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n"
+"2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n"
+"Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n"
+"GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n"
+"y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n"
+"++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n"
+"Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n"
+"/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n"
+"WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n"
+"GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n"
+"TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n"
+"CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n"
+"nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n"
+"AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n"
+"sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n"
+"mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n"
+"BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n"
+"whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n"
+"vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n"
+"3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n"
+"3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n"
+"ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n"
+"4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n"
+"TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n"
+"-----END RSA PRIVATE KEY-----\r\n";
+const size_t mbedtls_test_srv_key_rsa_len = sizeof( mbedtls_test_srv_key_rsa );
+
+/* tests/data_files/cli-rsa-sha256.crt */
+const char mbedtls_test_cli_crt_rsa[] =
+"-----BEGIN CERTIFICATE-----\r\n"
+"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n"
+"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n"
+"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n"
+"A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n"
+"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n"
+"M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n"
+"1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n"
+"MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n"
+"4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n"
+"/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n"
+"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n"
+"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQsFAAOC\r\n"
+"AQEAlHabem2Tu69VUN7EipwnQn1dIHdgvT5i+iQHpSxY1crPnBbAeSdAXwsVEqLQ\r\n"
+"gOOIAQD5VIITNuoGgo4i+4OpNh9u7ZkpRHla+/swsfrFWRRbBNP5Bcu74AGLstwU\r\n"
+"zM8gIkBiyfM1Q1qDQISV9trlCG6O8vh8dp/rbI3rfzo99BOHXgFCrzXjCuW4vDsF\r\n"
+"r+Dao26bX3sJ6UnEWg1H3o2x6PpUcvQ36h71/bz4TEbbUUEpe02V4QWuL+wrhHJL\r\n"
+"U7o3SVE3Og7jPF8sat0a50YUWhwEFI256m02KAXLg89ueUyYKEr6rNwhcvXJpvU9\r\n"
+"giIVvd0Sbjjnn7NC4VDbcXV8vw==\r\n"
+"-----END CERTIFICATE-----\r\n";
+const size_t mbedtls_test_cli_crt_rsa_len = sizeof( mbedtls_test_cli_crt_rsa );
+
+/* tests/data_files/cli-rsa.key */
+const char mbedtls_test_cli_key_rsa[] =
+"-----BEGIN RSA PRIVATE KEY-----\r\n"
+"MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n"
+"B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n"
+"bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n"
+"Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n"
+"7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n"
+"dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n"
+"yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n"
+"4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n"
+"ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n"
+"zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n"
+"l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n"
+"DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n"
+"VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n"
+"Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n"
+"wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n"
+"c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n"
+"33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n"
+"ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n"
+"BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n"
+"KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n"
+"UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n"
+"7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n"
+"gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n"
+"bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n"
+"8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n"
+"-----END RSA PRIVATE KEY-----\r\n";
+const size_t mbedtls_test_cli_key_rsa_len = sizeof( mbedtls_test_cli_key_rsa );
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+/* Concatenation of all available CA certificates */
+const char mbedtls_test_cas_pem[] =
+#ifdef TEST_CA_CRT_RSA_SHA1
+    TEST_CA_CRT_RSA_SHA1
+#endif
+#ifdef TEST_CA_CRT_RSA_SHA256
+    TEST_CA_CRT_RSA_SHA256
+#endif
+#ifdef TEST_CA_CRT_EC
+    TEST_CA_CRT_EC
+#endif
+    "";
+const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem );
+#endif
+
+/* List of all available CA certificates */
+const char * mbedtls_test_cas[] = {
+#if defined(TEST_CA_CRT_RSA_SHA1)
+    mbedtls_test_ca_crt_rsa_sha1,
+#endif
+#if defined(TEST_CA_CRT_RSA_SHA256)
+    mbedtls_test_ca_crt_rsa_sha256,
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+    mbedtls_test_ca_crt_ec,
+#endif
+    NULL
+};
+const size_t mbedtls_test_cas_len[] = {
+#if defined(TEST_CA_CRT_RSA_SHA1)
+    sizeof( mbedtls_test_ca_crt_rsa_sha1 ),
+#endif
+#if defined(TEST_CA_CRT_RSA_SHA256)
+    sizeof( mbedtls_test_ca_crt_rsa_sha256 ),
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+    sizeof( mbedtls_test_ca_crt_ec ),
+#endif
+    0
+};
+
+#if defined(MBEDTLS_RSA_C)
+const char *mbedtls_test_ca_crt  = mbedtls_test_ca_crt_rsa; /* SHA1 or SHA256 */
+const char *mbedtls_test_ca_key  = mbedtls_test_ca_key_rsa;
+const char *mbedtls_test_ca_pwd  = mbedtls_test_ca_pwd_rsa;
+const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_rsa;
+const char *mbedtls_test_srv_key = mbedtls_test_srv_key_rsa;
+const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_rsa;
+const char *mbedtls_test_cli_key = mbedtls_test_cli_key_rsa;
+const size_t mbedtls_test_ca_crt_len  = sizeof( mbedtls_test_ca_crt_rsa );
+const size_t mbedtls_test_ca_key_len  = sizeof( mbedtls_test_ca_key_rsa );
+const size_t mbedtls_test_ca_pwd_len  = sizeof( mbedtls_test_ca_pwd_rsa ) - 1;
+const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_rsa );
+const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_rsa );
+const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_rsa );
+const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_rsa );
+#else /* ! MBEDTLS_RSA_C, so MBEDTLS_ECDSA_C */
+const char *mbedtls_test_ca_crt  = mbedtls_test_ca_crt_ec;
+const char *mbedtls_test_ca_key  = mbedtls_test_ca_key_ec;
+const char *mbedtls_test_ca_pwd  = mbedtls_test_ca_pwd_ec;
+const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_ec;
+const char *mbedtls_test_srv_key = mbedtls_test_srv_key_ec;
+const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_ec;
+const char *mbedtls_test_cli_key = mbedtls_test_cli_key_ec;
+const size_t mbedtls_test_ca_crt_len  = sizeof( mbedtls_test_ca_crt_ec );
+const size_t mbedtls_test_ca_key_len  = sizeof( mbedtls_test_ca_key_ec );
+const size_t mbedtls_test_ca_pwd_len  = sizeof( mbedtls_test_ca_pwd_ec ) - 1;
+const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_ec );
+const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_ec );
+const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_ec );
+const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_ec );
+#endif /* MBEDTLS_RSA_C */
+
+#endif /* MBEDTLS_CERTS_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/chacha20.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/chacha20.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/chacha20.c	(revision 398)
@@ -0,0 +1,570 @@
+/**
+ * \file chacha20.c
+ *
+ * \brief ChaCha20 cipher.
+ *
+ * \author Daniel King <damaki.gh@gmail.com>
+ *
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CHACHA20_C)
+
+#include "mbedtls/chacha20.h"
+#include "mbedtls/platform_util.h"
+
+#include <stddef.h>
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_CHACHA20_ALT)
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+/* Parameter validation macros */
+#define CHACHA20_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
+#define CHACHA20_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#define BYTES_TO_U32_LE( data, offset )                           \
+    ( (uint32_t) data[offset]                                     \
+          | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 )   \
+          | (uint32_t) ( (uint32_t) data[( offset ) + 2] << 16 )  \
+          | (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 )  \
+    )
+
+#define ROTL32( value, amount ) \
+        ( (uint32_t) ( value << amount ) | ( value >> ( 32 - amount ) ) )
+
+#define CHACHA20_CTR_INDEX ( 12U )
+
+#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U )
+
+/**
+ * \brief           ChaCha20 quarter round operation.
+ *
+ *                  The quarter round is defined as follows (from RFC 7539):
+ *                      1.  a += b; d ^= a; d <<<= 16;
+ *                      2.  c += d; b ^= c; b <<<= 12;
+ *                      3.  a += b; d ^= a; d <<<= 8;
+ *                      4.  c += d; b ^= c; b <<<= 7;
+ *
+ * \param state     ChaCha20 state to modify.
+ * \param a         The index of 'a' in the state.
+ * \param b         The index of 'b' in the state.
+ * \param c         The index of 'c' in the state.
+ * \param d         The index of 'd' in the state.
+ */
+static inline void chacha20_quarter_round( uint32_t state[16],
+                                           size_t a,
+                                           size_t b,
+                                           size_t c,
+                                           size_t d )
+{
+    /* a += b; d ^= a; d <<<= 16; */
+    state[a] += state[b];
+    state[d] ^= state[a];
+    state[d] = ROTL32( state[d], 16 );
+
+    /* c += d; b ^= c; b <<<= 12 */
+    state[c] += state[d];
+    state[b] ^= state[c];
+    state[b] = ROTL32( state[b], 12 );
+
+    /* a += b; d ^= a; d <<<= 8; */
+    state[a] += state[b];
+    state[d] ^= state[a];
+    state[d] = ROTL32( state[d], 8 );
+
+    /* c += d; b ^= c; b <<<= 7; */
+    state[c] += state[d];
+    state[b] ^= state[c];
+    state[b] = ROTL32( state[b], 7 );
+}
+
+/**
+ * \brief           Perform the ChaCha20 inner block operation.
+ *
+ *                  This function performs two rounds: the column round and the
+ *                  diagonal round.
+ *
+ * \param state     The ChaCha20 state to update.
+ */
+static void chacha20_inner_block( uint32_t state[16] )
+{
+    chacha20_quarter_round( state, 0, 4, 8,  12 );
+    chacha20_quarter_round( state, 1, 5, 9,  13 );
+    chacha20_quarter_round( state, 2, 6, 10, 14 );
+    chacha20_quarter_round( state, 3, 7, 11, 15 );
+
+    chacha20_quarter_round( state, 0, 5, 10, 15 );
+    chacha20_quarter_round( state, 1, 6, 11, 12 );
+    chacha20_quarter_round( state, 2, 7, 8,  13 );
+    chacha20_quarter_round( state, 3, 4, 9,  14 );
+}
+
+/**
+ * \brief               Generates a keystream block.
+ *
+ * \param initial_state The initial ChaCha20 state (key, nonce, counter).
+ * \param keystream     Generated keystream bytes are written to this buffer.
+ */
+static void chacha20_block( const uint32_t initial_state[16],
+                            unsigned char keystream[64] )
+{
+    uint32_t working_state[16];
+    size_t i;
+
+    memcpy( working_state,
+            initial_state,
+            CHACHA20_BLOCK_SIZE_BYTES );
+
+    for( i = 0U; i < 10U; i++ )
+        chacha20_inner_block( working_state );
+
+    working_state[ 0] += initial_state[ 0];
+    working_state[ 1] += initial_state[ 1];
+    working_state[ 2] += initial_state[ 2];
+    working_state[ 3] += initial_state[ 3];
+    working_state[ 4] += initial_state[ 4];
+    working_state[ 5] += initial_state[ 5];
+    working_state[ 6] += initial_state[ 6];
+    working_state[ 7] += initial_state[ 7];
+    working_state[ 8] += initial_state[ 8];
+    working_state[ 9] += initial_state[ 9];
+    working_state[10] += initial_state[10];
+    working_state[11] += initial_state[11];
+    working_state[12] += initial_state[12];
+    working_state[13] += initial_state[13];
+    working_state[14] += initial_state[14];
+    working_state[15] += initial_state[15];
+
+    for( i = 0U; i < 16; i++ )
+    {
+        size_t offset = i * 4U;
+
+        keystream[offset     ] = (unsigned char)( working_state[i]       );
+        keystream[offset + 1U] = (unsigned char)( working_state[i] >>  8 );
+        keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
+        keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
+    }
+
+    mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
+}
+
+void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
+{
+    CHACHA20_VALIDATE( ctx != NULL );
+
+    mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) );
+    mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
+
+    /* Initially, there's no keystream bytes available */
+    ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
+}
+
+void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
+{
+    if( ctx != NULL )
+    {
+        mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
+    }
+}
+
+int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
+                            const unsigned char key[32] )
+{
+    CHACHA20_VALIDATE_RET( ctx != NULL );
+    CHACHA20_VALIDATE_RET( key != NULL );
+
+    /* ChaCha20 constants - the string "expand 32-byte k" */
+    ctx->state[0] = 0x61707865;
+    ctx->state[1] = 0x3320646e;
+    ctx->state[2] = 0x79622d32;
+    ctx->state[3] = 0x6b206574;
+
+    /* Set key */
+    ctx->state[4]  = BYTES_TO_U32_LE( key, 0 );
+    ctx->state[5]  = BYTES_TO_U32_LE( key, 4 );
+    ctx->state[6]  = BYTES_TO_U32_LE( key, 8 );
+    ctx->state[7]  = BYTES_TO_U32_LE( key, 12 );
+    ctx->state[8]  = BYTES_TO_U32_LE( key, 16 );
+    ctx->state[9]  = BYTES_TO_U32_LE( key, 20 );
+    ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
+    ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
+
+    return( 0 );
+}
+
+int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
+                             const unsigned char nonce[12],
+                             uint32_t counter )
+{
+    CHACHA20_VALIDATE_RET( ctx != NULL );
+    CHACHA20_VALIDATE_RET( nonce != NULL );
+
+    /* Counter */
+    ctx->state[12] = counter;
+
+    /* Nonce */
+    ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
+    ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
+    ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
+
+    mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
+
+    /* Initially, there's no keystream bytes available */
+    ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES;
+
+    return( 0 );
+}
+
+int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
+                              size_t size,
+                              const unsigned char *input,
+                              unsigned char *output )
+{
+    size_t offset = 0U;
+    size_t i;
+
+    CHACHA20_VALIDATE_RET( ctx != NULL );
+    CHACHA20_VALIDATE_RET( size == 0 || input  != NULL );
+    CHACHA20_VALIDATE_RET( size == 0 || output != NULL );
+
+    /* Use leftover keystream bytes, if available */
+    while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES )
+    {
+        output[offset] = input[offset]
+                       ^ ctx->keystream8[ctx->keystream_bytes_used];
+
+        ctx->keystream_bytes_used++;
+        offset++;
+        size--;
+    }
+
+    /* Process full blocks */
+    while( size >= CHACHA20_BLOCK_SIZE_BYTES )
+    {
+        /* Generate new keystream block and increment counter */
+        chacha20_block( ctx->state, ctx->keystream8 );
+        ctx->state[CHACHA20_CTR_INDEX]++;
+
+        for( i = 0U; i < 64U; i += 8U )
+        {
+            output[offset + i  ] = input[offset + i  ] ^ ctx->keystream8[i  ];
+            output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1];
+            output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2];
+            output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3];
+            output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4];
+            output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5];
+            output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6];
+            output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7];
+        }
+
+        offset += CHACHA20_BLOCK_SIZE_BYTES;
+        size   -= CHACHA20_BLOCK_SIZE_BYTES;
+    }
+
+    /* Last (partial) block */
+    if( size > 0U )
+    {
+        /* Generate new keystream block and increment counter */
+        chacha20_block( ctx->state, ctx->keystream8 );
+        ctx->state[CHACHA20_CTR_INDEX]++;
+
+        for( i = 0U; i < size; i++)
+        {
+            output[offset + i] = input[offset + i] ^ ctx->keystream8[i];
+        }
+
+        ctx->keystream_bytes_used = size;
+
+    }
+
+    return( 0 );
+}
+
+int mbedtls_chacha20_crypt( const unsigned char key[32],
+                            const unsigned char nonce[12],
+                            uint32_t counter,
+                            size_t data_len,
+                            const unsigned char* input,
+                            unsigned char* output )
+{
+    mbedtls_chacha20_context ctx;
+    int ret;
+
+    CHACHA20_VALIDATE_RET( key != NULL );
+    CHACHA20_VALIDATE_RET( nonce != NULL );
+    CHACHA20_VALIDATE_RET( data_len == 0 || input  != NULL );
+    CHACHA20_VALIDATE_RET( data_len == 0 || output != NULL );
+
+    mbedtls_chacha20_init( &ctx );
+
+    ret = mbedtls_chacha20_setkey( &ctx, key );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
+
+cleanup:
+    mbedtls_chacha20_free( &ctx );
+    return( ret );
+}
+
+#endif /* !MBEDTLS_CHACHA20_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+static const unsigned char test_keys[2][32] =
+{
+    {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
+    }
+};
+
+static const unsigned char test_nonces[2][12] =
+{
+    {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00
+    },
+    {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x02
+    }
+};
+
+static const uint32_t test_counters[2] =
+{
+    0U,
+    1U
+};
+
+static const unsigned char test_input[2][375] =
+{
+    {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    },
+    {
+        0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d,
+        0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74,
+        0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45,
+        0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e,
+        0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74,
+        0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72,
+        0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66,
+        0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
+        0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
+        0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72,
+        0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66,
+        0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46,
+        0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
+        0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20,
+        0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61,
+        0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73,
+        0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+        0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69,
+        0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
+        0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
+        0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49,
+        0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69,
+        0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20,
+        0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72,
+        0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49,
+        0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74,
+        0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+        0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20,
+        0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
+        0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75,
+        0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20,
+        0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e,
+        0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45,
+        0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69,
+        0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20,
+        0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20,
+        0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20,
+        0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63,
+        0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63,
+        0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61,
+        0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61,
+        0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e,
+        0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f,
+        0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c,
+        0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61,
+        0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65,
+        0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f
+    }
+};
+
+static const unsigned char test_output[2][375] =
+{
+    {
+        0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
+        0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
+        0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
+        0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
+        0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
+        0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
+        0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
+        0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86
+    },
+    {
+        0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde,
+        0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70,
+        0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd,
+        0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec,
+        0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15,
+        0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05,
+        0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f,
+        0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d,
+        0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa,
+        0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e,
+        0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7,
+        0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50,
+        0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05,
+        0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c,
+        0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05,
+        0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a,
+        0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0,
+        0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66,
+        0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4,
+        0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d,
+        0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91,
+        0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28,
+        0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87,
+        0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b,
+        0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2,
+        0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f,
+        0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76,
+        0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c,
+        0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b,
+        0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84,
+        0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd,
+        0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b,
+        0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe,
+        0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0,
+        0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80,
+        0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f,
+        0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3,
+        0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62,
+        0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91,
+        0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6,
+        0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64,
+        0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85,
+        0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41,
+        0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab,
+        0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba,
+        0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd,
+        0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21
+    }
+};
+
+static const size_t test_lengths[2] =
+{
+    64U,
+    375U
+};
+
+#define ASSERT( cond, args )            \
+    do                                  \
+    {                                   \
+        if( ! ( cond ) )                \
+        {                               \
+            if( verbose != 0 )          \
+                mbedtls_printf args;    \
+                                        \
+            return( -1 );               \
+        }                               \
+    }                                   \
+    while( 0 )
+
+int mbedtls_chacha20_self_test( int verbose )
+{
+    unsigned char output[381];
+    unsigned i;
+    int ret;
+
+    for( i = 0U; i < 2U; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  ChaCha20 test %u ", i );
+
+        ret = mbedtls_chacha20_crypt( test_keys[i],
+                                      test_nonces[i],
+                                      test_counters[i],
+                                      test_lengths[i],
+                                      test_input[i],
+                                      output );
+
+        ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
+
+        ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ),
+                ( "failed (output)\n" ) );
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* !MBEDTLS_CHACHA20_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/chachapoly.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/chachapoly.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/chachapoly.c	(revision 398)
@@ -0,0 +1,540 @@
+/**
+ * \file chachapoly.c
+ *
+ * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539.
+ *
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+
+#include "mbedtls/chachapoly.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_CHACHAPOLY_ALT)
+
+/* Parameter validation macros */
+#define CHACHAPOLY_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
+#define CHACHAPOLY_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#define CHACHAPOLY_STATE_INIT       ( 0 )
+#define CHACHAPOLY_STATE_AAD        ( 1 )
+#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */
+#define CHACHAPOLY_STATE_FINISHED   ( 3 )
+
+/**
+ * \brief           Adds nul bytes to pad the AAD for Poly1305.
+ *
+ * \param ctx       The ChaCha20-Poly1305 context.
+ */
+static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx )
+{
+    uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U );
+    unsigned char zeroes[15];
+
+    if( partial_block_len == 0U )
+        return( 0 );
+
+    memset( zeroes, 0, sizeof( zeroes ) );
+
+    return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
+                                     zeroes,
+                                     16U - partial_block_len ) );
+}
+
+/**
+ * \brief           Adds nul bytes to pad the ciphertext for Poly1305.
+ *
+ * \param ctx       The ChaCha20-Poly1305 context.
+ */
+static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx )
+{
+    uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U );
+    unsigned char zeroes[15];
+
+    if( partial_block_len == 0U )
+        return( 0 );
+
+    memset( zeroes, 0, sizeof( zeroes ) );
+    return( mbedtls_poly1305_update( &ctx->poly1305_ctx,
+                                     zeroes,
+                                     16U - partial_block_len ) );
+}
+
+void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )
+{
+    CHACHAPOLY_VALIDATE( ctx != NULL );
+
+    mbedtls_chacha20_init( &ctx->chacha20_ctx );
+    mbedtls_poly1305_init( &ctx->poly1305_ctx );
+    ctx->aad_len        = 0U;
+    ctx->ciphertext_len = 0U;
+    ctx->state          = CHACHAPOLY_STATE_INIT;
+    ctx->mode           = MBEDTLS_CHACHAPOLY_ENCRYPT;
+}
+
+void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_chacha20_free( &ctx->chacha20_ctx );
+    mbedtls_poly1305_free( &ctx->poly1305_ctx );
+    ctx->aad_len        = 0U;
+    ctx->ciphertext_len = 0U;
+    ctx->state          = CHACHAPOLY_STATE_INIT;
+    ctx->mode           = MBEDTLS_CHACHAPOLY_ENCRYPT;
+}
+
+int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
+                               const unsigned char key[32] )
+{
+    int ret;
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( key != NULL );
+
+    ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key );
+
+    return( ret );
+}
+
+int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
+                               const unsigned char nonce[12],
+                               mbedtls_chachapoly_mode_t mode  )
+{
+    int ret;
+    unsigned char poly1305_key[64];
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( nonce != NULL );
+
+    /* Set counter = 0, will be update to 1 when generating Poly1305 key */
+    ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U );
+    if( ret != 0 )
+        goto cleanup;
+
+    /* Generate the Poly1305 key by getting the ChaCha20 keystream output with
+     * counter = 0.  This is the same as encrypting a buffer of zeroes.
+     * Only the first 256-bits (32 bytes) of the key is used for Poly1305.
+     * The other 256 bits are discarded.
+     */
+    memset( poly1305_key, 0, sizeof( poly1305_key ) );
+    ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ),
+                                      poly1305_key, poly1305_key );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key );
+
+    if( ret == 0 )
+    {
+        ctx->aad_len        = 0U;
+        ctx->ciphertext_len = 0U;
+        ctx->state          = CHACHAPOLY_STATE_AAD;
+        ctx->mode           = mode;
+    }
+
+cleanup:
+    mbedtls_platform_zeroize( poly1305_key, 64U );
+    return( ret );
+}
+
+int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
+                                   const unsigned char *aad,
+                                   size_t aad_len )
+{
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad != NULL );
+
+    if( ctx->state != CHACHAPOLY_STATE_AAD )
+        return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
+
+    ctx->aad_len += aad_len;
+
+    return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) );
+}
+
+int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
+                               size_t len,
+                               const unsigned char *input,
+                               unsigned char *output )
+{
+    int ret;
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL );
+    CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL );
+
+    if( ( ctx->state != CHACHAPOLY_STATE_AAD ) &&
+        ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) )
+    {
+        return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
+    }
+
+    if( ctx->state == CHACHAPOLY_STATE_AAD )
+    {
+        ctx->state = CHACHAPOLY_STATE_CIPHERTEXT;
+
+        ret = chachapoly_pad_aad( ctx );
+        if( ret != 0 )
+            return( ret );
+    }
+
+    ctx->ciphertext_len += len;
+
+    if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT )
+    {
+        ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
+        if( ret != 0 )
+            return( ret );
+
+        ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len );
+        if( ret != 0 )
+            return( ret );
+    }
+    else /* DECRYPT */
+    {
+        ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len );
+        if( ret != 0 )
+            return( ret );
+
+        ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output );
+        if( ret != 0 )
+            return( ret );
+    }
+
+    return( 0 );
+}
+
+int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
+                               unsigned char mac[16] )
+{
+    int ret;
+    unsigned char len_block[16];
+    CHACHAPOLY_VALIDATE_RET( ctx != NULL );
+    CHACHAPOLY_VALIDATE_RET( mac != NULL );
+
+    if( ctx->state == CHACHAPOLY_STATE_INIT )
+    {
+        return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE );
+    }
+
+    if( ctx->state == CHACHAPOLY_STATE_AAD )
+    {
+        ret = chachapoly_pad_aad( ctx );
+        if( ret != 0 )
+            return( ret );
+    }
+    else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT )
+    {
+        ret = chachapoly_pad_ciphertext( ctx );
+        if( ret != 0 )
+            return( ret );
+    }
+
+    ctx->state = CHACHAPOLY_STATE_FINISHED;
+
+    /* The lengths of the AAD and ciphertext are processed by
+     * Poly1305 as the final 128-bit block, encoded as little-endian integers.
+     */
+    len_block[ 0] = (unsigned char)( ctx->aad_len       );
+    len_block[ 1] = (unsigned char)( ctx->aad_len >>  8 );
+    len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 );
+    len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 );
+    len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 );
+    len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 );
+    len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 );
+    len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 );
+    len_block[ 8] = (unsigned char)( ctx->ciphertext_len       );
+    len_block[ 9] = (unsigned char)( ctx->ciphertext_len >>  8 );
+    len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 );
+    len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 );
+    len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 );
+    len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 );
+    len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 );
+    len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 );
+
+    ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U );
+    if( ret != 0 )
+        return( ret );
+
+    ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac );
+
+    return( ret );
+}
+
+static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,
+                                     mbedtls_chachapoly_mode_t mode,
+                                     size_t length,
+                                     const unsigned char nonce[12],
+                                     const unsigned char *aad,
+                                     size_t aad_len,
+                                     const unsigned char *input,
+                                     unsigned char *output,
+                                     unsigned char tag[16] )
+{
+    int ret;
+
+    ret = mbedtls_chachapoly_starts( ctx, nonce, mode );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chachapoly_update( ctx, length, input, output );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chachapoly_finish( ctx, tag );
+
+cleanup:
+    return( ret );
+}
+
+int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
+                                        size_t length,
+                                        const unsigned char nonce[12],
+                                        const unsigned char *aad,
+                                        size_t aad_len,
+                                        const unsigned char *input,
+                                        unsigned char *output,
+                                        unsigned char tag[16] )
+{
+    CHACHAPOLY_VALIDATE_RET( ctx   != NULL );
+    CHACHAPOLY_VALIDATE_RET( nonce != NULL );
+    CHACHAPOLY_VALIDATE_RET( tag   != NULL );
+    CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad    != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || input  != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || output != NULL );
+
+    return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT,
+                                      length, nonce, aad, aad_len,
+                                      input, output, tag ) );
+}
+
+int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
+                                     size_t length,
+                                     const unsigned char nonce[12],
+                                     const unsigned char *aad,
+                                     size_t aad_len,
+                                     const unsigned char tag[16],
+                                     const unsigned char *input,
+                                     unsigned char *output )
+{
+    int ret;
+    unsigned char check_tag[16];
+    size_t i;
+    int diff;
+    CHACHAPOLY_VALIDATE_RET( ctx   != NULL );
+    CHACHAPOLY_VALIDATE_RET( nonce != NULL );
+    CHACHAPOLY_VALIDATE_RET( tag   != NULL );
+    CHACHAPOLY_VALIDATE_RET( aad_len == 0 || aad    != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || input  != NULL );
+    CHACHAPOLY_VALIDATE_RET( length  == 0 || output != NULL );
+
+    if( ( ret = chachapoly_crypt_and_tag( ctx,
+                        MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce,
+                        aad, aad_len, input, output, check_tag ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /* Check tag in "constant-time" */
+    for( diff = 0, i = 0; i < sizeof( check_tag ); i++ )
+        diff |= tag[i] ^ check_tag[i];
+
+    if( diff != 0 )
+    {
+        mbedtls_platform_zeroize( output, length );
+        return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED );
+    }
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_CHACHAPOLY_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+static const unsigned char test_key[1][32] =
+{
+    {
+        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, 0x9f
+    }
+};
+
+static const unsigned char test_nonce[1][12] =
+{
+    {
+        0x07, 0x00, 0x00, 0x00,                         /* 32-bit common part */
+        0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47  /* 64-bit IV */
+    }
+};
+
+static const unsigned char test_aad[1][12] =
+{
+    {
+        0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
+        0xc4, 0xc5, 0xc6, 0xc7
+    }
+};
+
+static const size_t test_aad_len[1] =
+{
+    12U
+};
+
+static const unsigned char test_input[1][114] =
+{
+    {
+        0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61,
+        0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
+        0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
+        0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
+        0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39,
+        0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
+        0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66,
+        0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
+        0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
+        0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
+        0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75,
+        0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
+        0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,
+        0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
+        0x74, 0x2e
+    }
+};
+
+static const unsigned char test_output[1][114] =
+{
+    {
+        0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb,
+        0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2,
+        0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe,
+        0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6,
+        0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12,
+        0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b,
+        0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29,
+        0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36,
+        0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c,
+        0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58,
+        0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94,
+        0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc,
+        0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d,
+        0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b,
+        0x61, 0x16
+    }
+};
+
+static const size_t test_input_len[1] =
+{
+    114U
+};
+
+static const unsigned char test_mac[1][16] =
+{
+    {
+        0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a,
+        0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
+    }
+};
+
+#define ASSERT( cond, args )            \
+    do                                  \
+    {                                   \
+        if( ! ( cond ) )                \
+        {                               \
+            if( verbose != 0 )          \
+                mbedtls_printf args;    \
+                                        \
+            return( -1 );               \
+        }                               \
+    }                                   \
+    while( 0 )
+
+int mbedtls_chachapoly_self_test( int verbose )
+{
+    mbedtls_chachapoly_context ctx;
+    unsigned i;
+    int ret;
+    unsigned char output[200];
+    unsigned char mac[16];
+
+    for( i = 0U; i < 1U; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  ChaCha20-Poly1305 test %u ", i );
+
+        mbedtls_chachapoly_init( &ctx );
+
+        ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] );
+        ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) );
+
+        ret = mbedtls_chachapoly_encrypt_and_tag( &ctx,
+                                                  test_input_len[i],
+                                                  test_nonce[i],
+                                                  test_aad[i],
+                                                  test_aad_len[i],
+                                                  test_input[i],
+                                                  output,
+                                                  mac );
+
+        ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) );
+
+        ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ),
+                ( "failure (wrong output)\n" ) );
+
+        ASSERT( 0 == memcmp( mac, test_mac[i], 16U ),
+                ( "failure (wrong MAC)\n" ) );
+
+        mbedtls_chachapoly_free( &ctx );
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_CHACHAPOLY_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/cipher.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/cipher.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/cipher.c	(revision 398)
@@ -0,0 +1,1164 @@
+/**
+ * \file cipher.c
+ *
+ * \brief Generic cipher wrapper for mbed TLS
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CIPHER_C)
+
+#include "mbedtls/cipher.h"
+#include "mbedtls/cipher_internal.h"
+#include "mbedtls/platform_util.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+#include "mbedtls/chachapoly.h"
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+#include "mbedtls/gcm.h"
+#endif
+
+#if defined(MBEDTLS_CCM_C)
+#include "mbedtls/ccm.h"
+#endif
+
+#if defined(MBEDTLS_CHACHA20_C)
+#include "mbedtls/chacha20.h"
+#endif
+
+#if defined(MBEDTLS_CMAC_C)
+#include "mbedtls/cmac.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#define mbedtls_calloc calloc
+#define mbedtls_free   free
+#endif
+
+#define CIPHER_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA )
+#define CIPHER_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+/* Compare the contents of two buffers in constant time.
+ * Returns 0 if the contents are bitwise identical, otherwise returns
+ * a non-zero value.
+ * This is currently only used by GCM and ChaCha20+Poly1305.
+ */
+static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len )
+{
+    const unsigned char *p1 = (const unsigned char*) v1;
+    const unsigned char *p2 = (const unsigned char*) v2;
+    size_t i;
+    unsigned char diff;
+
+    for( diff = 0, i = 0; i < len; i++ )
+        diff |= p1[i] ^ p2[i];
+
+    return( (int)diff );
+}
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
+
+static int supported_init = 0;
+
+const int *mbedtls_cipher_list( void )
+{
+    const mbedtls_cipher_definition_t *def;
+    int *type;
+
+    if( ! supported_init )
+    {
+        def = mbedtls_cipher_definitions;
+        type = mbedtls_cipher_supported;
+
+        while( def->type != 0 )
+            *type++ = (*def++).type;
+
+        *type = 0;
+
+        supported_init = 1;
+    }
+
+    return( mbedtls_cipher_supported );
+}
+
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type )
+{
+    const mbedtls_cipher_definition_t *def;
+
+    for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
+        if( def->type == cipher_type )
+            return( def->info );
+
+    return( NULL );
+}
+
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name )
+{
+    const mbedtls_cipher_definition_t *def;
+
+    if( NULL == cipher_name )
+        return( NULL );
+
+    for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
+        if( !  strcmp( def->info->name, cipher_name ) )
+            return( def->info );
+
+    return( NULL );
+}
+
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
+                                              int key_bitlen,
+                                              const mbedtls_cipher_mode_t mode )
+{
+    const mbedtls_cipher_definition_t *def;
+
+    for( def = mbedtls_cipher_definitions; def->info != NULL; def++ )
+        if( def->info->base->cipher == cipher_id &&
+            def->info->key_bitlen == (unsigned) key_bitlen &&
+            def->info->mode == mode )
+            return( def->info );
+
+    return( NULL );
+}
+
+void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx )
+{
+    CIPHER_VALIDATE( ctx != NULL );
+    memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
+}
+
+void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+#if defined(MBEDTLS_CMAC_C)
+    if( ctx->cmac_ctx )
+    {
+       mbedtls_platform_zeroize( ctx->cmac_ctx,
+                                 sizeof( mbedtls_cmac_context_t ) );
+       mbedtls_free( ctx->cmac_ctx );
+    }
+#endif
+
+    if( ctx->cipher_ctx )
+        ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx );
+
+    mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
+}
+
+int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
+{
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    if( cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
+
+    if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
+        return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
+
+    ctx->cipher_info = cipher_info;
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+    /*
+     * Ignore possible errors caused by a cipher mode that doesn't use padding
+     */
+#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
+    (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 );
+#else
+    (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE );
+#endif
+#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
+
+    return( 0 );
+}
+
+int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
+                           const unsigned char *key,
+                           int key_bitlen,
+                           const mbedtls_operation_t operation )
+{
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( key != NULL );
+    CIPHER_VALIDATE_RET( operation == MBEDTLS_ENCRYPT ||
+                         operation == MBEDTLS_DECRYPT );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
+        (int) ctx->cipher_info->key_bitlen != key_bitlen )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    ctx->key_bitlen = key_bitlen;
+    ctx->operation = operation;
+
+    /*
+     * For OFB, CFB and CTR mode always use the encryption key schedule
+     */
+    if( MBEDTLS_ENCRYPT == operation ||
+        MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
+        MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
+        MBEDTLS_MODE_CTR == ctx->cipher_info->mode )
+    {
+        return( ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key,
+                                                         ctx->key_bitlen ) );
+    }
+
+    if( MBEDTLS_DECRYPT == operation )
+        return( ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key,
+                                                         ctx->key_bitlen ) );
+
+    return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+}
+
+int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
+                           const unsigned char *iv,
+                           size_t iv_len )
+{
+    size_t actual_iv_size;
+
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    /* avoid buffer overflow in ctx->iv */
+    if( iv_len > MBEDTLS_MAX_IV_LENGTH )
+        return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+    if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 )
+        actual_iv_size = iv_len;
+    else
+    {
+        actual_iv_size = ctx->cipher_info->iv_size;
+
+        /* avoid reading past the end of input buffer */
+        if( actual_iv_size > iv_len )
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+#if defined(MBEDTLS_CHACHA20_C)
+    if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 )
+    {
+        if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx,
+                                           iv,
+                                           0U ) ) /* Initial counter value */
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+    }
+#endif
+
+    if ( actual_iv_size != 0 )
+    {
+        memcpy( ctx->iv, iv, actual_iv_size );
+        ctx->iv_size = actual_iv_size;
+    }
+
+    return( 0 );
+}
+
+int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
+{
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    ctx->unprocessed_len = 0;
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
+                      const unsigned char *ad, size_t ad_len )
+{
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_GCM_C)
+    if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+    {
+        return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
+                                    ctx->iv, ctx->iv_size, ad, ad_len ) );
+    }
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+    {
+        int result;
+        mbedtls_chachapoly_mode_t mode;
+
+        mode = ( ctx->operation == MBEDTLS_ENCRYPT )
+                ? MBEDTLS_CHACHAPOLY_ENCRYPT
+                : MBEDTLS_CHACHAPOLY_DECRYPT;
+
+        result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                                        ctx->iv,
+                                                        mode );
+        if ( result != 0 )
+            return( result );
+
+        return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                               ad, ad_len ) );
+    }
+#endif
+
+    return( 0 );
+}
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
+
+int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
+                   size_t ilen, unsigned char *output, size_t *olen )
+{
+    int ret;
+    size_t block_size;
+
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    *olen = 0;
+    block_size = mbedtls_cipher_get_block_size( ctx );
+
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB )
+    {
+        if( ilen != block_size )
+            return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
+
+        *olen = ilen;
+
+        if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
+                    ctx->operation, input, output ) ) )
+        {
+            return( ret );
+        }
+
+        return( 0 );
+    }
+
+#if defined(MBEDTLS_GCM_C)
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM )
+    {
+        *olen = ilen;
+        return( mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input,
+                                    output ) );
+    }
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 )
+    {
+        *olen = ilen;
+        return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                           ilen, input, output ) );
+    }
+#endif
+
+    if ( 0 == block_size )
+    {
+        return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
+    }
+
+    if( input == output &&
+       ( ctx->unprocessed_len != 0 || ilen % block_size ) )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC )
+    {
+        size_t copy_len = 0;
+
+        /*
+         * If there is not enough data for a full block, cache it.
+         */
+        if( ( ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding &&
+                ilen <= block_size - ctx->unprocessed_len ) ||
+            ( ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding &&
+                ilen < block_size - ctx->unprocessed_len ) ||
+             ( ctx->operation == MBEDTLS_ENCRYPT &&
+                ilen < block_size - ctx->unprocessed_len ) )
+        {
+            memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
+                    ilen );
+
+            ctx->unprocessed_len += ilen;
+            return( 0 );
+        }
+
+        /*
+         * Process cached data first
+         */
+        if( 0 != ctx->unprocessed_len )
+        {
+            copy_len = block_size - ctx->unprocessed_len;
+
+            memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
+                    copy_len );
+
+            if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
+                    ctx->operation, block_size, ctx->iv,
+                    ctx->unprocessed_data, output ) ) )
+            {
+                return( ret );
+            }
+
+            *olen += block_size;
+            output += block_size;
+            ctx->unprocessed_len = 0;
+
+            input += copy_len;
+            ilen -= copy_len;
+        }
+
+        /*
+         * Cache final, incomplete block
+         */
+        if( 0 != ilen )
+        {
+            if( 0 == block_size )
+            {
+                return( MBEDTLS_ERR_CIPHER_INVALID_CONTEXT );
+            }
+
+            /* Encryption: only cache partial blocks
+             * Decryption w/ padding: always keep at least one whole block
+             * Decryption w/o padding: only cache partial blocks
+             */
+            copy_len = ilen % block_size;
+            if( copy_len == 0 &&
+                ctx->operation == MBEDTLS_DECRYPT &&
+                NULL != ctx->add_padding)
+            {
+                copy_len = block_size;
+            }
+
+            memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
+                    copy_len );
+
+            ctx->unprocessed_len += copy_len;
+            ilen -= copy_len;
+        }
+
+        /*
+         * Process remaining full blocks
+         */
+        if( ilen )
+        {
+            if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
+                    ctx->operation, ilen, ctx->iv, input, output ) ) )
+            {
+                return( ret );
+            }
+
+            *olen += ilen;
+        }
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB )
+    {
+        if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
+                ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
+                input, output ) ) )
+        {
+            return( ret );
+        }
+
+        *olen = ilen;
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB )
+    {
+        if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx,
+                ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) )
+        {
+            return( ret );
+        }
+
+        *olen = ilen;
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR )
+    {
+        if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
+                ilen, &ctx->unprocessed_len, ctx->iv,
+                ctx->unprocessed_data, input, output ) ) )
+        {
+            return( ret );
+        }
+
+        *olen = ilen;
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS )
+    {
+        if( ctx->unprocessed_len > 0 ) {
+            /* We can only process an entire data unit at a time. */
+            return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+        }
+
+        ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx,
+                ctx->operation, ilen, ctx->iv, input, output );
+        if( ret != 0 )
+        {
+            return( ret );
+        }
+
+        *olen = ilen;
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM )
+    {
+        if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
+                                                    ilen, input, output ) ) )
+        {
+            return( ret );
+        }
+
+        *olen = ilen;
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_STREAM */
+
+    return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
+/*
+ * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len
+ */
+static void add_pkcs_padding( unsigned char *output, size_t output_len,
+        size_t data_len )
+{
+    size_t padding_len = output_len - data_len;
+    unsigned char i;
+
+    for( i = 0; i < padding_len; i++ )
+        output[data_len + i] = (unsigned char) padding_len;
+}
+
+static int get_pkcs_padding( unsigned char *input, size_t input_len,
+        size_t *data_len )
+{
+    size_t i, pad_idx;
+    unsigned char padding_len, bad = 0;
+
+    if( NULL == input || NULL == data_len )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    padding_len = input[input_len - 1];
+    *data_len = input_len - padding_len;
+
+    /* Avoid logical || since it results in a branch */
+    bad |= padding_len > input_len;
+    bad |= padding_len == 0;
+
+    /* The number of bytes checked must be independent of padding_len,
+     * so pick input_len, which is usually 8 or 16 (one block) */
+    pad_idx = input_len - padding_len;
+    for( i = 0; i < input_len; i++ )
+        bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
+
+    return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
+}
+#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
+
+#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
+/*
+ * One and zeros padding: fill with 80 00 ... 00
+ */
+static void add_one_and_zeros_padding( unsigned char *output,
+                                       size_t output_len, size_t data_len )
+{
+    size_t padding_len = output_len - data_len;
+    unsigned char i = 0;
+
+    output[data_len] = 0x80;
+    for( i = 1; i < padding_len; i++ )
+        output[data_len + i] = 0x00;
+}
+
+static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
+                                      size_t *data_len )
+{
+    size_t i;
+    unsigned char done = 0, prev_done, bad;
+
+    if( NULL == input || NULL == data_len )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    bad = 0x80;
+    *data_len = 0;
+    for( i = input_len; i > 0; i-- )
+    {
+        prev_done = done;
+        done |= ( input[i - 1] != 0 );
+        *data_len |= ( i - 1 ) * ( done != prev_done );
+        bad ^= input[i - 1] * ( done != prev_done );
+    }
+
+    return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
+
+}
+#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
+
+#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
+/*
+ * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length
+ */
+static void add_zeros_and_len_padding( unsigned char *output,
+                                       size_t output_len, size_t data_len )
+{
+    size_t padding_len = output_len - data_len;
+    unsigned char i = 0;
+
+    for( i = 1; i < padding_len; i++ )
+        output[data_len + i - 1] = 0x00;
+    output[output_len - 1] = (unsigned char) padding_len;
+}
+
+static int get_zeros_and_len_padding( unsigned char *input, size_t input_len,
+                                      size_t *data_len )
+{
+    size_t i, pad_idx;
+    unsigned char padding_len, bad = 0;
+
+    if( NULL == input || NULL == data_len )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    padding_len = input[input_len - 1];
+    *data_len = input_len - padding_len;
+
+    /* Avoid logical || since it results in a branch */
+    bad |= padding_len > input_len;
+    bad |= padding_len == 0;
+
+    /* The number of bytes checked must be independent of padding_len */
+    pad_idx = input_len - padding_len;
+    for( i = 0; i < input_len - 1; i++ )
+        bad |= input[i] * ( i >= pad_idx );
+
+    return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
+}
+#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
+
+#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
+/*
+ * Zero padding: fill with 00 ... 00
+ */
+static void add_zeros_padding( unsigned char *output,
+                               size_t output_len, size_t data_len )
+{
+    size_t i;
+
+    for( i = data_len; i < output_len; i++ )
+        output[i] = 0x00;
+}
+
+static int get_zeros_padding( unsigned char *input, size_t input_len,
+                              size_t *data_len )
+{
+    size_t i;
+    unsigned char done = 0, prev_done;
+
+    if( NULL == input || NULL == data_len )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    *data_len = 0;
+    for( i = input_len; i > 0; i-- )
+    {
+        prev_done = done;
+        done |= ( input[i-1] != 0 );
+        *data_len |= i * ( done != prev_done );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
+
+/*
+ * No padding: don't pad :)
+ *
+ * There is no add_padding function (check for NULL in mbedtls_cipher_finish)
+ * but a trivial get_padding function
+ */
+static int get_no_padding( unsigned char *input, size_t input_len,
+                              size_t *data_len )
+{
+    if( NULL == input || NULL == data_len )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    *data_len = input_len;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
+
+int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
+                   unsigned char *output, size_t *olen )
+{
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    *olen = 0;
+
+    if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
+        MBEDTLS_MODE_OFB == ctx->cipher_info->mode ||
+        MBEDTLS_MODE_CTR == ctx->cipher_info->mode ||
+        MBEDTLS_MODE_GCM == ctx->cipher_info->mode ||
+        MBEDTLS_MODE_XTS == ctx->cipher_info->mode ||
+        MBEDTLS_MODE_STREAM == ctx->cipher_info->mode )
+    {
+        return( 0 );
+    }
+
+    if ( ( MBEDTLS_CIPHER_CHACHA20          == ctx->cipher_info->type ) ||
+         ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) )
+    {
+        return( 0 );
+    }
+
+    if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode )
+    {
+        if( ctx->unprocessed_len != 0 )
+            return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
+
+        return( 0 );
+    }
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode )
+    {
+        int ret = 0;
+
+        if( MBEDTLS_ENCRYPT == ctx->operation )
+        {
+            /* check for 'no padding' mode */
+            if( NULL == ctx->add_padding )
+            {
+                if( 0 != ctx->unprocessed_len )
+                    return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
+
+                return( 0 );
+            }
+
+            ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ),
+                    ctx->unprocessed_len );
+        }
+        else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len )
+        {
+            /*
+             * For decrypt operations, expect a full block,
+             * or an empty block if no padding
+             */
+            if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
+                return( 0 );
+
+            return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
+        }
+
+        /* cipher block */
+        if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
+                ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv,
+                ctx->unprocessed_data, output ) ) )
+        {
+            return( ret );
+        }
+
+        /* Set output size for decryption */
+        if( MBEDTLS_DECRYPT == ctx->operation )
+            return( ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ),
+                                      olen ) );
+
+        /* Set output size for encryption */
+        *olen = mbedtls_cipher_get_block_size( ctx );
+        return( 0 );
+    }
+#else
+    ((void) output);
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+    return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
+int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
+                                     mbedtls_cipher_padding_t mode )
+{
+    CIPHER_VALIDATE_RET( ctx != NULL );
+
+    if( NULL == ctx->cipher_info || MBEDTLS_MODE_CBC != ctx->cipher_info->mode )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    switch( mode )
+    {
+#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
+    case MBEDTLS_PADDING_PKCS7:
+        ctx->add_padding = add_pkcs_padding;
+        ctx->get_padding = get_pkcs_padding;
+        break;
+#endif
+#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
+    case MBEDTLS_PADDING_ONE_AND_ZEROS:
+        ctx->add_padding = add_one_and_zeros_padding;
+        ctx->get_padding = get_one_and_zeros_padding;
+        break;
+#endif
+#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
+    case MBEDTLS_PADDING_ZEROS_AND_LEN:
+        ctx->add_padding = add_zeros_and_len_padding;
+        ctx->get_padding = get_zeros_and_len_padding;
+        break;
+#endif
+#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
+    case MBEDTLS_PADDING_ZEROS:
+        ctx->add_padding = add_zeros_padding;
+        ctx->get_padding = get_zeros_padding;
+        break;
+#endif
+    case MBEDTLS_PADDING_NONE:
+        ctx->add_padding = NULL;
+        ctx->get_padding = get_no_padding;
+        break;
+
+    default:
+        return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */
+
+#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
+int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
+                      unsigned char *tag, size_t tag_len )
+{
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    if( MBEDTLS_ENCRYPT != ctx->operation )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_GCM_C)
+    if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+        return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
+                                    tag, tag_len ) );
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+    {
+        /* Don't allow truncated MAC for Poly1305 */
+        if ( tag_len != 16U )
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+        return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                           tag ) );
+    }
+#endif
+
+    return( 0 );
+}
+
+int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
+                      const unsigned char *tag, size_t tag_len )
+{
+    unsigned char check_tag[16];
+    int ret;
+
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+    if( ctx->cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    if( MBEDTLS_DECRYPT != ctx->operation )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+#if defined(MBEDTLS_GCM_C)
+    if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+    {
+        if( tag_len > sizeof( check_tag ) )
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+        if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
+                                     check_tag, tag_len ) ) )
+        {
+            return( ret );
+        }
+
+        /* Check the tag in "constant-time" */
+        if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+            return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+    {
+        /* Don't allow truncated MAC for Poly1305 */
+        if ( tag_len != sizeof( check_tag ) )
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+        ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
+                                                     check_tag );
+        if ( ret != 0 )
+        {
+            return( ret );
+        }
+
+        /* Check the tag in "constant-time" */
+        if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+            return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
+
+        return( 0 );
+    }
+#endif /* MBEDTLS_CHACHAPOLY_C */
+
+    return( 0 );
+}
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
+
+/*
+ * Packet-oriented wrapper for non-AEAD modes
+ */
+int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
+                  const unsigned char *iv, size_t iv_len,
+                  const unsigned char *input, size_t ilen,
+                  unsigned char *output, size_t *olen )
+{
+    int ret;
+    size_t finish_olen;
+
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+
+    if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 )
+        return( ret );
+
+    *olen += finish_olen;
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+/*
+ * Packet-oriented encryption for AEAD modes
+ */
+int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *ad, size_t ad_len,
+                         const unsigned char *input, size_t ilen,
+                         unsigned char *output, size_t *olen,
+                         unsigned char *tag, size_t tag_len )
+{
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv != NULL );
+    CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+#if defined(MBEDTLS_GCM_C)
+    if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+    {
+        *olen = ilen;
+        return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen,
+                                   iv, iv_len, ad, ad_len, input, output,
+                                   tag_len, tag ) );
+    }
+#endif /* MBEDTLS_GCM_C */
+#if defined(MBEDTLS_CCM_C)
+    if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
+    {
+        *olen = ilen;
+        return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen,
+                                     iv, iv_len, ad, ad_len, input, output,
+                                     tag, tag_len ) );
+    }
+#endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+    {
+        /* ChachaPoly has fixed length nonce and MAC (tag) */
+        if ( ( iv_len != ctx->cipher_info->iv_size ) ||
+             ( tag_len != 16U ) )
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+
+        *olen = ilen;
+        return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx,
+                                ilen, iv, ad, ad_len, input, output, tag ) );
+    }
+#endif /* MBEDTLS_CHACHAPOLY_C */
+
+    return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+}
+
+/*
+ * Packet-oriented decryption for AEAD modes
+ */
+int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
+                         const unsigned char *iv, size_t iv_len,
+                         const unsigned char *ad, size_t ad_len,
+                         const unsigned char *input, size_t ilen,
+                         unsigned char *output, size_t *olen,
+                         const unsigned char *tag, size_t tag_len )
+{
+    CIPHER_VALIDATE_RET( ctx != NULL );
+    CIPHER_VALIDATE_RET( iv != NULL );
+    CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+    CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+    CIPHER_VALIDATE_RET( output != NULL );
+    CIPHER_VALIDATE_RET( olen != NULL );
+    CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+#if defined(MBEDTLS_GCM_C)
+    if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+    {
+        int ret;
+
+        *olen = ilen;
+        ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
+                                iv, iv_len, ad, ad_len,
+                                tag, tag_len, input, output );
+
+        if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED )
+            ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+
+        return( ret );
+    }
+#endif /* MBEDTLS_GCM_C */
+#if defined(MBEDTLS_CCM_C)
+    if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
+    {
+        int ret;
+
+        *olen = ilen;
+        ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
+                                iv, iv_len, ad, ad_len,
+                                input, output, tag, tag_len );
+
+        if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
+            ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+
+        return( ret );
+    }
+#endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
+    {
+        int ret;
+
+        /* ChachaPoly has fixed length nonce and MAC (tag) */
+        if ( ( iv_len != ctx->cipher_info->iv_size ) ||
+             ( tag_len != 16U ) )
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+
+        *olen = ilen;
+        ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen,
+                                iv, ad, ad_len, tag, input, output );
+
+        if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED )
+            ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+
+        return( ret );
+    }
+#endif /* MBEDTLS_CHACHAPOLY_C */
+
+    return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+}
+#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+
+#endif /* MBEDTLS_CIPHER_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/cipher_wrap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/cipher_wrap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/cipher_wrap.c	(revision 398)
@@ -0,0 +1,2272 @@
+/**
+ * \file cipher_wrap.c
+ *
+ * \brief Generic cipher wrapper for mbed TLS
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CIPHER_C)
+
+#include "mbedtls/cipher_internal.h"
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+#include "mbedtls/chachapoly.h"
+#endif
+
+#if defined(MBEDTLS_AES_C)
+#include "mbedtls/aes.h"
+#endif
+
+#if defined(MBEDTLS_ARC4_C)
+#include "mbedtls/arc4.h"
+#endif
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#include "mbedtls/camellia.h"
+#endif
+
+#if defined(MBEDTLS_ARIA_C)
+#include "mbedtls/aria.h"
+#endif
+
+#if defined(MBEDTLS_DES_C)
+#include "mbedtls/des.h"
+#endif
+
+#if defined(MBEDTLS_BLOWFISH_C)
+#include "mbedtls/blowfish.h"
+#endif
+
+#if defined(MBEDTLS_CHACHA20_C)
+#include "mbedtls/chacha20.h"
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+#include "mbedtls/gcm.h"
+#endif
+
+#if defined(MBEDTLS_CCM_C)
+#include "mbedtls/ccm.h"
+#endif
+
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+#include <string.h>
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+/* shared by all GCM ciphers */
+static void *gcm_ctx_alloc( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) );
+
+    if( ctx != NULL )
+        mbedtls_gcm_init( (mbedtls_gcm_context *) ctx );
+
+    return( ctx );
+}
+
+static void gcm_ctx_free( void *ctx )
+{
+    mbedtls_gcm_free( ctx );
+    mbedtls_free( ctx );
+}
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CCM_C)
+/* shared by all CCM ciphers */
+static void *ccm_ctx_alloc( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) );
+
+    if( ctx != NULL )
+        mbedtls_ccm_init( (mbedtls_ccm_context *) ctx );
+
+    return( ctx );
+}
+
+static void ccm_ctx_free( void *ctx )
+{
+    mbedtls_ccm_free( ctx );
+    mbedtls_free( ctx );
+}
+#endif /* MBEDTLS_CCM_C */
+
+#if defined(MBEDTLS_AES_C)
+
+static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
+        unsigned char *iv, const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input,
+                          output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
+        size_t length, size_t *iv_off, unsigned char *iv,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv,
+                             input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+static int aes_crypt_ofb_wrap( void *ctx, size_t length, size_t *iv_off,
+        unsigned char *iv, const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aes_crypt_ofb( (mbedtls_aes_context *) ctx, length, iv_off,
+                                    iv, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
+        unsigned char *nonce_counter, unsigned char *stream_block,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter,
+                          stream_block, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+static int aes_crypt_xts_wrap( void *ctx, mbedtls_operation_t operation,
+                               size_t length,
+                               const unsigned char data_unit[16],
+                               const unsigned char *input,
+                               unsigned char *output )
+{
+    mbedtls_aes_xts_context *xts_ctx = ctx;
+    int mode;
+
+    switch( operation )
+    {
+        case MBEDTLS_ENCRYPT:
+            mode = MBEDTLS_AES_ENCRYPT;
+            break;
+        case MBEDTLS_DECRYPT:
+            mode = MBEDTLS_AES_DECRYPT;
+            break;
+        default:
+            return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+    }
+
+    return mbedtls_aes_crypt_xts( xts_ctx, mode, length,
+                                  data_unit, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key,
+                                unsigned int key_bitlen )
+{
+    return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen );
+}
+
+static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key,
+                                unsigned int key_bitlen )
+{
+    return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen );
+}
+
+static void * aes_ctx_alloc( void )
+{
+    mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) );
+
+    if( aes == NULL )
+        return( NULL );
+
+    mbedtls_aes_init( aes );
+
+    return( aes );
+}
+
+static void aes_ctx_free( void *ctx )
+{
+    mbedtls_aes_free( (mbedtls_aes_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t aes_info = {
+    MBEDTLS_CIPHER_ID_AES,
+    aes_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    aes_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    aes_crypt_cfb128_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    aes_crypt_ofb_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    aes_crypt_ctr_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    aes_setkey_enc_wrap,
+    aes_setkey_dec_wrap,
+    aes_ctx_alloc,
+    aes_ctx_free
+};
+
+static const mbedtls_cipher_info_t aes_128_ecb_info = {
+    MBEDTLS_CIPHER_AES_128_ECB,
+    MBEDTLS_MODE_ECB,
+    128,
+    "AES-128-ECB",
+    0,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_ecb_info = {
+    MBEDTLS_CIPHER_AES_192_ECB,
+    MBEDTLS_MODE_ECB,
+    192,
+    "AES-192-ECB",
+    0,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_ecb_info = {
+    MBEDTLS_CIPHER_AES_256_ECB,
+    MBEDTLS_MODE_ECB,
+    256,
+    "AES-256-ECB",
+    0,
+    0,
+    16,
+    &aes_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t aes_128_cbc_info = {
+    MBEDTLS_CIPHER_AES_128_CBC,
+    MBEDTLS_MODE_CBC,
+    128,
+    "AES-128-CBC",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_cbc_info = {
+    MBEDTLS_CIPHER_AES_192_CBC,
+    MBEDTLS_MODE_CBC,
+    192,
+    "AES-192-CBC",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_cbc_info = {
+    MBEDTLS_CIPHER_AES_256_CBC,
+    MBEDTLS_MODE_CBC,
+    256,
+    "AES-256-CBC",
+    16,
+    0,
+    16,
+    &aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const mbedtls_cipher_info_t aes_128_cfb128_info = {
+    MBEDTLS_CIPHER_AES_128_CFB128,
+    MBEDTLS_MODE_CFB,
+    128,
+    "AES-128-CFB128",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_cfb128_info = {
+    MBEDTLS_CIPHER_AES_192_CFB128,
+    MBEDTLS_MODE_CFB,
+    192,
+    "AES-192-CFB128",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_cfb128_info = {
+    MBEDTLS_CIPHER_AES_256_CFB128,
+    MBEDTLS_MODE_CFB,
+    256,
+    "AES-256-CFB128",
+    16,
+    0,
+    16,
+    &aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+static const mbedtls_cipher_info_t aes_128_ofb_info = {
+    MBEDTLS_CIPHER_AES_128_OFB,
+    MBEDTLS_MODE_OFB,
+    128,
+    "AES-128-OFB",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_ofb_info = {
+    MBEDTLS_CIPHER_AES_192_OFB,
+    MBEDTLS_MODE_OFB,
+    192,
+    "AES-192-OFB",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_ofb_info = {
+    MBEDTLS_CIPHER_AES_256_OFB,
+    MBEDTLS_MODE_OFB,
+    256,
+    "AES-256-OFB",
+    16,
+    0,
+    16,
+    &aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const mbedtls_cipher_info_t aes_128_ctr_info = {
+    MBEDTLS_CIPHER_AES_128_CTR,
+    MBEDTLS_MODE_CTR,
+    128,
+    "AES-128-CTR",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_ctr_info = {
+    MBEDTLS_CIPHER_AES_192_CTR,
+    MBEDTLS_MODE_CTR,
+    192,
+    "AES-192-CTR",
+    16,
+    0,
+    16,
+    &aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_ctr_info = {
+    MBEDTLS_CIPHER_AES_256_CTR,
+    MBEDTLS_MODE_CTR,
+    256,
+    "AES-256-CTR",
+    16,
+    0,
+    16,
+    &aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+static int xts_aes_setkey_enc_wrap( void *ctx, const unsigned char *key,
+                                    unsigned int key_bitlen )
+{
+    mbedtls_aes_xts_context *xts_ctx = ctx;
+    return( mbedtls_aes_xts_setkey_enc( xts_ctx, key, key_bitlen ) );
+}
+
+static int xts_aes_setkey_dec_wrap( void *ctx, const unsigned char *key,
+                                    unsigned int key_bitlen )
+{
+    mbedtls_aes_xts_context *xts_ctx = ctx;
+    return( mbedtls_aes_xts_setkey_dec( xts_ctx, key, key_bitlen ) );
+}
+
+static void *xts_aes_ctx_alloc( void )
+{
+    mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc( 1, sizeof( *xts_ctx ) );
+
+    if( xts_ctx != NULL )
+        mbedtls_aes_xts_init( xts_ctx );
+
+    return( xts_ctx );
+}
+
+static void xts_aes_ctx_free( void *ctx )
+{
+    mbedtls_aes_xts_context *xts_ctx = ctx;
+
+    if( xts_ctx == NULL )
+        return;
+
+    mbedtls_aes_xts_free( xts_ctx );
+    mbedtls_free( xts_ctx );
+}
+
+static const mbedtls_cipher_base_t xts_aes_info = {
+    MBEDTLS_CIPHER_ID_AES,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    aes_crypt_xts_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    xts_aes_setkey_enc_wrap,
+    xts_aes_setkey_dec_wrap,
+    xts_aes_ctx_alloc,
+    xts_aes_ctx_free
+};
+
+static const mbedtls_cipher_info_t aes_128_xts_info = {
+    MBEDTLS_CIPHER_AES_128_XTS,
+    MBEDTLS_MODE_XTS,
+    256,
+    "AES-128-XTS",
+    16,
+    0,
+    16,
+    &xts_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_xts_info = {
+    MBEDTLS_CIPHER_AES_256_XTS,
+    MBEDTLS_MODE_XTS,
+    512,
+    "AES-256-XTS",
+    16,
+    0,
+    16,
+    &xts_aes_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#if defined(MBEDTLS_GCM_C)
+static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key,
+                                unsigned int key_bitlen )
+{
+    return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES,
+                     key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t gcm_aes_info = {
+    MBEDTLS_CIPHER_ID_AES,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    gcm_aes_setkey_wrap,
+    gcm_aes_setkey_wrap,
+    gcm_ctx_alloc,
+    gcm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aes_128_gcm_info = {
+    MBEDTLS_CIPHER_AES_128_GCM,
+    MBEDTLS_MODE_GCM,
+    128,
+    "AES-128-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_gcm_info = {
+    MBEDTLS_CIPHER_AES_192_GCM,
+    MBEDTLS_MODE_GCM,
+    192,
+    "AES-192-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_gcm_info = {
+    MBEDTLS_CIPHER_AES_256_GCM,
+    MBEDTLS_MODE_GCM,
+    256,
+    "AES-256-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_aes_info
+};
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CCM_C)
+static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key,
+                                unsigned int key_bitlen )
+{
+    return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES,
+                     key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t ccm_aes_info = {
+    MBEDTLS_CIPHER_ID_AES,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    ccm_aes_setkey_wrap,
+    ccm_aes_setkey_wrap,
+    ccm_ctx_alloc,
+    ccm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aes_128_ccm_info = {
+    MBEDTLS_CIPHER_AES_128_CCM,
+    MBEDTLS_MODE_CCM,
+    128,
+    "AES-128-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_ccm_info = {
+    MBEDTLS_CIPHER_AES_192_CCM,
+    MBEDTLS_MODE_CCM,
+    192,
+    "AES-192-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_ccm_info = {
+    MBEDTLS_CIPHER_AES_256_CCM,
+    MBEDTLS_MODE_CCM,
+    256,
+    "AES-256-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aes_info
+};
+#endif /* MBEDTLS_CCM_C */
+
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+
+static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input,
+                               output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
+        size_t length, unsigned char *iv,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv,
+                               input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
+        size_t length, size_t *iv_off, unsigned char *iv,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length,
+                                  iv_off, iv, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
+        unsigned char *nonce_counter, unsigned char *stream_block,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off,
+                               nonce_counter, stream_block, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen );
+}
+
+static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen );
+}
+
+static void * camellia_ctx_alloc( void )
+{
+    mbedtls_camellia_context *ctx;
+    ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) );
+
+    if( ctx == NULL )
+        return( NULL );
+
+    mbedtls_camellia_init( ctx );
+
+    return( ctx );
+}
+
+static void camellia_ctx_free( void *ctx )
+{
+    mbedtls_camellia_free( (mbedtls_camellia_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t camellia_info = {
+    MBEDTLS_CIPHER_ID_CAMELLIA,
+    camellia_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    camellia_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    camellia_crypt_cfb128_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    camellia_crypt_ctr_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    camellia_setkey_enc_wrap,
+    camellia_setkey_dec_wrap,
+    camellia_ctx_alloc,
+    camellia_ctx_free
+};
+
+static const mbedtls_cipher_info_t camellia_128_ecb_info = {
+    MBEDTLS_CIPHER_CAMELLIA_128_ECB,
+    MBEDTLS_MODE_ECB,
+    128,
+    "CAMELLIA-128-ECB",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_ecb_info = {
+    MBEDTLS_CIPHER_CAMELLIA_192_ECB,
+    MBEDTLS_MODE_ECB,
+    192,
+    "CAMELLIA-192-ECB",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_ecb_info = {
+    MBEDTLS_CIPHER_CAMELLIA_256_ECB,
+    MBEDTLS_MODE_ECB,
+    256,
+    "CAMELLIA-256-ECB",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t camellia_128_cbc_info = {
+    MBEDTLS_CIPHER_CAMELLIA_128_CBC,
+    MBEDTLS_MODE_CBC,
+    128,
+    "CAMELLIA-128-CBC",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_cbc_info = {
+    MBEDTLS_CIPHER_CAMELLIA_192_CBC,
+    MBEDTLS_MODE_CBC,
+    192,
+    "CAMELLIA-192-CBC",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_cbc_info = {
+    MBEDTLS_CIPHER_CAMELLIA_256_CBC,
+    MBEDTLS_MODE_CBC,
+    256,
+    "CAMELLIA-256-CBC",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const mbedtls_cipher_info_t camellia_128_cfb128_info = {
+    MBEDTLS_CIPHER_CAMELLIA_128_CFB128,
+    MBEDTLS_MODE_CFB,
+    128,
+    "CAMELLIA-128-CFB128",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_cfb128_info = {
+    MBEDTLS_CIPHER_CAMELLIA_192_CFB128,
+    MBEDTLS_MODE_CFB,
+    192,
+    "CAMELLIA-192-CFB128",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_cfb128_info = {
+    MBEDTLS_CIPHER_CAMELLIA_256_CFB128,
+    MBEDTLS_MODE_CFB,
+    256,
+    "CAMELLIA-256-CFB128",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const mbedtls_cipher_info_t camellia_128_ctr_info = {
+    MBEDTLS_CIPHER_CAMELLIA_128_CTR,
+    MBEDTLS_MODE_CTR,
+    128,
+    "CAMELLIA-128-CTR",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_ctr_info = {
+    MBEDTLS_CIPHER_CAMELLIA_192_CTR,
+    MBEDTLS_MODE_CTR,
+    192,
+    "CAMELLIA-192-CTR",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_ctr_info = {
+    MBEDTLS_CIPHER_CAMELLIA_256_CTR,
+    MBEDTLS_MODE_CTR,
+    256,
+    "CAMELLIA-256-CTR",
+    16,
+    0,
+    16,
+    &camellia_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_GCM_C)
+static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA,
+                     key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t gcm_camellia_info = {
+    MBEDTLS_CIPHER_ID_CAMELLIA,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    gcm_camellia_setkey_wrap,
+    gcm_camellia_setkey_wrap,
+    gcm_ctx_alloc,
+    gcm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t camellia_128_gcm_info = {
+    MBEDTLS_CIPHER_CAMELLIA_128_GCM,
+    MBEDTLS_MODE_GCM,
+    128,
+    "CAMELLIA-128-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_gcm_info = {
+    MBEDTLS_CIPHER_CAMELLIA_192_GCM,
+    MBEDTLS_MODE_GCM,
+    192,
+    "CAMELLIA-192-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_gcm_info = {
+    MBEDTLS_CIPHER_CAMELLIA_256_GCM,
+    MBEDTLS_MODE_GCM,
+    256,
+    "CAMELLIA-256-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_camellia_info
+};
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CCM_C)
+static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA,
+                     key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t ccm_camellia_info = {
+    MBEDTLS_CIPHER_ID_CAMELLIA,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    ccm_camellia_setkey_wrap,
+    ccm_camellia_setkey_wrap,
+    ccm_ctx_alloc,
+    ccm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t camellia_128_ccm_info = {
+    MBEDTLS_CIPHER_CAMELLIA_128_CCM,
+    MBEDTLS_MODE_CCM,
+    128,
+    "CAMELLIA-128-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_192_ccm_info = {
+    MBEDTLS_CIPHER_CAMELLIA_192_CCM,
+    MBEDTLS_MODE_CCM,
+    192,
+    "CAMELLIA-192-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_camellia_info
+};
+
+static const mbedtls_cipher_info_t camellia_256_ccm_info = {
+    MBEDTLS_CIPHER_CAMELLIA_256_CCM,
+    MBEDTLS_MODE_CCM,
+    256,
+    "CAMELLIA-256-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_camellia_info
+};
+#endif /* MBEDTLS_CCM_C */
+
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_ARIA_C)
+
+static int aria_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    (void) operation;
+    return mbedtls_aria_crypt_ecb( (mbedtls_aria_context *) ctx, input,
+                               output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int aria_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
+        size_t length, unsigned char *iv,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aria_crypt_cbc( (mbedtls_aria_context *) ctx, operation, length, iv,
+                               input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static int aria_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation,
+        size_t length, size_t *iv_off, unsigned char *iv,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aria_crypt_cfb128( (mbedtls_aria_context *) ctx, operation, length,
+                                  iv_off, iv, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static int aria_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
+        unsigned char *nonce_counter, unsigned char *stream_block,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_aria_crypt_ctr( (mbedtls_aria_context *) ctx, length, nc_off,
+                               nonce_counter, stream_block, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+static int aria_setkey_dec_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_aria_setkey_dec( (mbedtls_aria_context *) ctx, key, key_bitlen );
+}
+
+static int aria_setkey_enc_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_aria_setkey_enc( (mbedtls_aria_context *) ctx, key, key_bitlen );
+}
+
+static void * aria_ctx_alloc( void )
+{
+    mbedtls_aria_context *ctx;
+    ctx = mbedtls_calloc( 1, sizeof( mbedtls_aria_context ) );
+
+    if( ctx == NULL )
+        return( NULL );
+
+    mbedtls_aria_init( ctx );
+
+    return( ctx );
+}
+
+static void aria_ctx_free( void *ctx )
+{
+    mbedtls_aria_free( (mbedtls_aria_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t aria_info = {
+    MBEDTLS_CIPHER_ID_ARIA,
+    aria_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    aria_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    aria_crypt_cfb128_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    aria_crypt_ctr_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    aria_setkey_enc_wrap,
+    aria_setkey_dec_wrap,
+    aria_ctx_alloc,
+    aria_ctx_free
+};
+
+static const mbedtls_cipher_info_t aria_128_ecb_info = {
+    MBEDTLS_CIPHER_ARIA_128_ECB,
+    MBEDTLS_MODE_ECB,
+    128,
+    "ARIA-128-ECB",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_ecb_info = {
+    MBEDTLS_CIPHER_ARIA_192_ECB,
+    MBEDTLS_MODE_ECB,
+    192,
+    "ARIA-192-ECB",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_ecb_info = {
+    MBEDTLS_CIPHER_ARIA_256_ECB,
+    MBEDTLS_MODE_ECB,
+    256,
+    "ARIA-256-ECB",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t aria_128_cbc_info = {
+    MBEDTLS_CIPHER_ARIA_128_CBC,
+    MBEDTLS_MODE_CBC,
+    128,
+    "ARIA-128-CBC",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_cbc_info = {
+    MBEDTLS_CIPHER_ARIA_192_CBC,
+    MBEDTLS_MODE_CBC,
+    192,
+    "ARIA-192-CBC",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_cbc_info = {
+    MBEDTLS_CIPHER_ARIA_256_CBC,
+    MBEDTLS_MODE_CBC,
+    256,
+    "ARIA-256-CBC",
+    16,
+    0,
+    16,
+    &aria_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const mbedtls_cipher_info_t aria_128_cfb128_info = {
+    MBEDTLS_CIPHER_ARIA_128_CFB128,
+    MBEDTLS_MODE_CFB,
+    128,
+    "ARIA-128-CFB128",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_cfb128_info = {
+    MBEDTLS_CIPHER_ARIA_192_CFB128,
+    MBEDTLS_MODE_CFB,
+    192,
+    "ARIA-192-CFB128",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_cfb128_info = {
+    MBEDTLS_CIPHER_ARIA_256_CFB128,
+    MBEDTLS_MODE_CFB,
+    256,
+    "ARIA-256-CFB128",
+    16,
+    0,
+    16,
+    &aria_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const mbedtls_cipher_info_t aria_128_ctr_info = {
+    MBEDTLS_CIPHER_ARIA_128_CTR,
+    MBEDTLS_MODE_CTR,
+    128,
+    "ARIA-128-CTR",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_ctr_info = {
+    MBEDTLS_CIPHER_ARIA_192_CTR,
+    MBEDTLS_MODE_CTR,
+    192,
+    "ARIA-192-CTR",
+    16,
+    0,
+    16,
+    &aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_ctr_info = {
+    MBEDTLS_CIPHER_ARIA_256_CTR,
+    MBEDTLS_MODE_CTR,
+    256,
+    "ARIA-256-CTR",
+    16,
+    0,
+    16,
+    &aria_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_GCM_C)
+static int gcm_aria_setkey_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA,
+                     key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t gcm_aria_info = {
+    MBEDTLS_CIPHER_ID_ARIA,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    gcm_aria_setkey_wrap,
+    gcm_aria_setkey_wrap,
+    gcm_ctx_alloc,
+    gcm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aria_128_gcm_info = {
+    MBEDTLS_CIPHER_ARIA_128_GCM,
+    MBEDTLS_MODE_GCM,
+    128,
+    "ARIA-128-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_gcm_info = {
+    MBEDTLS_CIPHER_ARIA_192_GCM,
+    MBEDTLS_MODE_GCM,
+    192,
+    "ARIA-192-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_gcm_info = {
+    MBEDTLS_CIPHER_ARIA_256_GCM,
+    MBEDTLS_MODE_GCM,
+    256,
+    "ARIA-256-GCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &gcm_aria_info
+};
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CCM_C)
+static int ccm_aria_setkey_wrap( void *ctx, const unsigned char *key,
+                                     unsigned int key_bitlen )
+{
+    return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA,
+                     key, key_bitlen );
+}
+
+static const mbedtls_cipher_base_t ccm_aria_info = {
+    MBEDTLS_CIPHER_ID_ARIA,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    ccm_aria_setkey_wrap,
+    ccm_aria_setkey_wrap,
+    ccm_ctx_alloc,
+    ccm_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aria_128_ccm_info = {
+    MBEDTLS_CIPHER_ARIA_128_CCM,
+    MBEDTLS_MODE_CCM,
+    128,
+    "ARIA-128-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_192_ccm_info = {
+    MBEDTLS_CIPHER_ARIA_192_CCM,
+    MBEDTLS_MODE_CCM,
+    192,
+    "ARIA-192-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aria_info
+};
+
+static const mbedtls_cipher_info_t aria_256_ccm_info = {
+    MBEDTLS_CIPHER_ARIA_256_CCM,
+    MBEDTLS_MODE_CCM,
+    256,
+    "ARIA-256-CCM",
+    12,
+    MBEDTLS_CIPHER_VARIABLE_IV_LEN,
+    16,
+    &ccm_aria_info
+};
+#endif /* MBEDTLS_CCM_C */
+
+#endif /* MBEDTLS_ARIA_C */
+
+#if defined(MBEDTLS_DES_C)
+
+static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    ((void) operation);
+    return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output );
+}
+
+static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    ((void) operation);
+    return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
+        unsigned char *iv, const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input,
+                          output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length,
+        unsigned char *iv, const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input,
+                           output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+static int des_setkey_dec_wrap( void *ctx, const unsigned char *key,
+                                unsigned int key_bitlen )
+{
+    ((void) key_bitlen);
+
+    return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key );
+}
+
+static int des_setkey_enc_wrap( void *ctx, const unsigned char *key,
+                                unsigned int key_bitlen )
+{
+    ((void) key_bitlen);
+
+    return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key );
+}
+
+static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key,
+                                  unsigned int key_bitlen )
+{
+    ((void) key_bitlen);
+
+    return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key );
+}
+
+static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key,
+                                  unsigned int key_bitlen )
+{
+    ((void) key_bitlen);
+
+    return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key );
+}
+
+static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key,
+                                  unsigned int key_bitlen )
+{
+    ((void) key_bitlen);
+
+    return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key );
+}
+
+static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key,
+                                  unsigned int key_bitlen )
+{
+    ((void) key_bitlen);
+
+    return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key );
+}
+
+static void * des_ctx_alloc( void )
+{
+    mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) );
+
+    if( des == NULL )
+        return( NULL );
+
+    mbedtls_des_init( des );
+
+    return( des );
+}
+
+static void des_ctx_free( void *ctx )
+{
+    mbedtls_des_free( (mbedtls_des_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static void * des3_ctx_alloc( void )
+{
+    mbedtls_des3_context *des3;
+    des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) );
+
+    if( des3 == NULL )
+        return( NULL );
+
+    mbedtls_des3_init( des3 );
+
+    return( des3 );
+}
+
+static void des3_ctx_free( void *ctx )
+{
+    mbedtls_des3_free( (mbedtls_des3_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t des_info = {
+    MBEDTLS_CIPHER_ID_DES,
+    des_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    des_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    des_setkey_enc_wrap,
+    des_setkey_dec_wrap,
+    des_ctx_alloc,
+    des_ctx_free
+};
+
+static const mbedtls_cipher_info_t des_ecb_info = {
+    MBEDTLS_CIPHER_DES_ECB,
+    MBEDTLS_MODE_ECB,
+    MBEDTLS_KEY_LENGTH_DES,
+    "DES-ECB",
+    8,
+    0,
+    8,
+    &des_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t des_cbc_info = {
+    MBEDTLS_CIPHER_DES_CBC,
+    MBEDTLS_MODE_CBC,
+    MBEDTLS_KEY_LENGTH_DES,
+    "DES-CBC",
+    8,
+    0,
+    8,
+    &des_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+static const mbedtls_cipher_base_t des_ede_info = {
+    MBEDTLS_CIPHER_ID_DES,
+    des3_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    des3_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    des3_set2key_enc_wrap,
+    des3_set2key_dec_wrap,
+    des3_ctx_alloc,
+    des3_ctx_free
+};
+
+static const mbedtls_cipher_info_t des_ede_ecb_info = {
+    MBEDTLS_CIPHER_DES_EDE_ECB,
+    MBEDTLS_MODE_ECB,
+    MBEDTLS_KEY_LENGTH_DES_EDE,
+    "DES-EDE-ECB",
+    8,
+    0,
+    8,
+    &des_ede_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t des_ede_cbc_info = {
+    MBEDTLS_CIPHER_DES_EDE_CBC,
+    MBEDTLS_MODE_CBC,
+    MBEDTLS_KEY_LENGTH_DES_EDE,
+    "DES-EDE-CBC",
+    8,
+    0,
+    8,
+    &des_ede_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+static const mbedtls_cipher_base_t des_ede3_info = {
+    MBEDTLS_CIPHER_ID_3DES,
+    des3_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    des3_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    des3_set3key_enc_wrap,
+    des3_set3key_dec_wrap,
+    des3_ctx_alloc,
+    des3_ctx_free
+};
+
+static const mbedtls_cipher_info_t des_ede3_ecb_info = {
+    MBEDTLS_CIPHER_DES_EDE3_ECB,
+    MBEDTLS_MODE_ECB,
+    MBEDTLS_KEY_LENGTH_DES_EDE3,
+    "DES-EDE3-ECB",
+    8,
+    0,
+    8,
+    &des_ede3_info
+};
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t des_ede3_cbc_info = {
+    MBEDTLS_CIPHER_DES_EDE3_CBC,
+    MBEDTLS_MODE_CBC,
+    MBEDTLS_KEY_LENGTH_DES_EDE3,
+    "DES-EDE3-CBC",
+    8,
+    0,
+    8,
+    &des_ede3_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_BLOWFISH_C)
+
+static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input,
+                               output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation,
+        size_t length, unsigned char *iv, const unsigned char *input,
+        unsigned char *output )
+{
+    return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv,
+                               input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation,
+        size_t length, size_t *iv_off, unsigned char *iv,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length,
+                                 iv_off, iv, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off,
+        unsigned char *nonce_counter, unsigned char *stream_block,
+        const unsigned char *input, unsigned char *output )
+{
+    return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off,
+                               nonce_counter, stream_block, input, output );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+static int blowfish_setkey_wrap( void *ctx, const unsigned char *key,
+                                 unsigned int key_bitlen )
+{
+    return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen );
+}
+
+static void * blowfish_ctx_alloc( void )
+{
+    mbedtls_blowfish_context *ctx;
+    ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) );
+
+    if( ctx == NULL )
+        return( NULL );
+
+    mbedtls_blowfish_init( ctx );
+
+    return( ctx );
+}
+
+static void blowfish_ctx_free( void *ctx )
+{
+    mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t blowfish_info = {
+    MBEDTLS_CIPHER_ID_BLOWFISH,
+    blowfish_crypt_ecb_wrap,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    blowfish_crypt_cbc_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    blowfish_crypt_cfb64_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    blowfish_crypt_ctr_wrap,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    blowfish_setkey_wrap,
+    blowfish_setkey_wrap,
+    blowfish_ctx_alloc,
+    blowfish_ctx_free
+};
+
+static const mbedtls_cipher_info_t blowfish_ecb_info = {
+    MBEDTLS_CIPHER_BLOWFISH_ECB,
+    MBEDTLS_MODE_ECB,
+    128,
+    "BLOWFISH-ECB",
+    8,
+    MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
+    8,
+    &blowfish_info
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const mbedtls_cipher_info_t blowfish_cbc_info = {
+    MBEDTLS_CIPHER_BLOWFISH_CBC,
+    MBEDTLS_MODE_CBC,
+    128,
+    "BLOWFISH-CBC",
+    8,
+    MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
+    8,
+    &blowfish_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+static const mbedtls_cipher_info_t blowfish_cfb64_info = {
+    MBEDTLS_CIPHER_BLOWFISH_CFB64,
+    MBEDTLS_MODE_CFB,
+    128,
+    "BLOWFISH-CFB64",
+    8,
+    MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
+    8,
+    &blowfish_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+static const mbedtls_cipher_info_t blowfish_ctr_info = {
+    MBEDTLS_CIPHER_BLOWFISH_CTR,
+    MBEDTLS_MODE_CTR,
+    128,
+    "BLOWFISH-CTR",
+    8,
+    MBEDTLS_CIPHER_VARIABLE_KEY_LEN,
+    8,
+    &blowfish_info
+};
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+#endif /* MBEDTLS_BLOWFISH_C */
+
+#if defined(MBEDTLS_ARC4_C)
+static int arc4_crypt_stream_wrap( void *ctx, size_t length,
+                                   const unsigned char *input,
+                                   unsigned char *output )
+{
+    return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) );
+}
+
+static int arc4_setkey_wrap( void *ctx, const unsigned char *key,
+                             unsigned int key_bitlen )
+{
+    /* we get key_bitlen in bits, arc4 expects it in bytes */
+    if( key_bitlen % 8 != 0 )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 );
+    return( 0 );
+}
+
+static void * arc4_ctx_alloc( void )
+{
+    mbedtls_arc4_context *ctx;
+    ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) );
+
+    if( ctx == NULL )
+        return( NULL );
+
+    mbedtls_arc4_init( ctx );
+
+    return( ctx );
+}
+
+static void arc4_ctx_free( void *ctx )
+{
+    mbedtls_arc4_free( (mbedtls_arc4_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t arc4_base_info = {
+    MBEDTLS_CIPHER_ID_ARC4,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    arc4_crypt_stream_wrap,
+#endif
+    arc4_setkey_wrap,
+    arc4_setkey_wrap,
+    arc4_ctx_alloc,
+    arc4_ctx_free
+};
+
+static const mbedtls_cipher_info_t arc4_128_info = {
+    MBEDTLS_CIPHER_ARC4_128,
+    MBEDTLS_MODE_STREAM,
+    128,
+    "ARC4-128",
+    0,
+    0,
+    1,
+    &arc4_base_info
+};
+#endif /* MBEDTLS_ARC4_C */
+
+#if defined(MBEDTLS_CHACHA20_C)
+
+static int chacha20_setkey_wrap( void *ctx, const unsigned char *key,
+                                 unsigned int key_bitlen )
+{
+    if( key_bitlen != 256U )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    if ( 0 != mbedtls_chacha20_setkey( (mbedtls_chacha20_context*)ctx, key ) )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    return( 0 );
+}
+
+static int chacha20_stream_wrap( void *ctx,  size_t length,
+                                 const unsigned char *input,
+                                 unsigned char *output )
+{
+    int ret;
+
+    ret = mbedtls_chacha20_update( ctx, length, input, output );
+    if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    return( ret );
+}
+
+static void * chacha20_ctx_alloc( void )
+{
+    mbedtls_chacha20_context *ctx;
+    ctx = mbedtls_calloc( 1, sizeof( mbedtls_chacha20_context ) );
+
+    if( ctx == NULL )
+        return( NULL );
+
+    mbedtls_chacha20_init( ctx );
+
+    return( ctx );
+}
+
+static void chacha20_ctx_free( void *ctx )
+{
+    mbedtls_chacha20_free( (mbedtls_chacha20_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t chacha20_base_info = {
+    MBEDTLS_CIPHER_ID_CHACHA20,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    chacha20_stream_wrap,
+#endif
+    chacha20_setkey_wrap,
+    chacha20_setkey_wrap,
+    chacha20_ctx_alloc,
+    chacha20_ctx_free
+};
+static const mbedtls_cipher_info_t chacha20_info = {
+    MBEDTLS_CIPHER_CHACHA20,
+    MBEDTLS_MODE_STREAM,
+    256,
+    "CHACHA20",
+    12,
+    0,
+    1,
+    &chacha20_base_info
+};
+#endif /* MBEDTLS_CHACHA20_C */
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+
+static int chachapoly_setkey_wrap( void *ctx,
+                                   const unsigned char *key,
+                                   unsigned int key_bitlen )
+{
+    if( key_bitlen != 256U )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    return( 0 );
+}
+
+static void * chachapoly_ctx_alloc( void )
+{
+    mbedtls_chachapoly_context *ctx;
+    ctx = mbedtls_calloc( 1, sizeof( mbedtls_chachapoly_context ) );
+
+    if( ctx == NULL )
+        return( NULL );
+
+    mbedtls_chachapoly_init( ctx );
+
+    return( ctx );
+}
+
+static void chachapoly_ctx_free( void *ctx )
+{
+    mbedtls_chachapoly_free( (mbedtls_chachapoly_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static const mbedtls_cipher_base_t chachapoly_base_info = {
+    MBEDTLS_CIPHER_ID_CHACHA20,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    NULL,
+#endif
+    chachapoly_setkey_wrap,
+    chachapoly_setkey_wrap,
+    chachapoly_ctx_alloc,
+    chachapoly_ctx_free
+};
+static const mbedtls_cipher_info_t chachapoly_info = {
+    MBEDTLS_CIPHER_CHACHA20_POLY1305,
+    MBEDTLS_MODE_CHACHAPOLY,
+    256,
+    "CHACHA20-POLY1305",
+    12,
+    0,
+    1,
+    &chachapoly_base_info
+};
+#endif /* MBEDTLS_CHACHAPOLY_C */
+
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+static int null_crypt_stream( void *ctx, size_t length,
+                              const unsigned char *input,
+                              unsigned char *output )
+{
+    ((void) ctx);
+    memmove( output, input, length );
+    return( 0 );
+}
+
+static int null_setkey( void *ctx, const unsigned char *key,
+                        unsigned int key_bitlen )
+{
+    ((void) ctx);
+    ((void) key);
+    ((void) key_bitlen);
+
+    return( 0 );
+}
+
+static void * null_ctx_alloc( void )
+{
+    return( (void *) 1 );
+}
+
+static void null_ctx_free( void *ctx )
+{
+    ((void) ctx);
+}
+
+static const mbedtls_cipher_base_t null_base_info = {
+    MBEDTLS_CIPHER_ID_NULL,
+    NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+    null_crypt_stream,
+#endif
+    null_setkey,
+    null_setkey,
+    null_ctx_alloc,
+    null_ctx_free
+};
+
+static const mbedtls_cipher_info_t null_cipher_info = {
+    MBEDTLS_CIPHER_NULL,
+    MBEDTLS_MODE_STREAM,
+    0,
+    "NULL",
+    0,
+    0,
+    1,
+    &null_base_info
+};
+#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */
+
+const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
+{
+#if defined(MBEDTLS_AES_C)
+    { MBEDTLS_CIPHER_AES_128_ECB,          &aes_128_ecb_info },
+    { MBEDTLS_CIPHER_AES_192_ECB,          &aes_192_ecb_info },
+    { MBEDTLS_CIPHER_AES_256_ECB,          &aes_256_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_CIPHER_AES_128_CBC,          &aes_128_cbc_info },
+    { MBEDTLS_CIPHER_AES_192_CBC,          &aes_192_cbc_info },
+    { MBEDTLS_CIPHER_AES_256_CBC,          &aes_256_cbc_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    { MBEDTLS_CIPHER_AES_128_CFB128,       &aes_128_cfb128_info },
+    { MBEDTLS_CIPHER_AES_192_CFB128,       &aes_192_cfb128_info },
+    { MBEDTLS_CIPHER_AES_256_CFB128,       &aes_256_cfb128_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    { MBEDTLS_CIPHER_AES_128_OFB,          &aes_128_ofb_info },
+    { MBEDTLS_CIPHER_AES_192_OFB,          &aes_192_ofb_info },
+    { MBEDTLS_CIPHER_AES_256_OFB,          &aes_256_ofb_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    { MBEDTLS_CIPHER_AES_128_CTR,          &aes_128_ctr_info },
+    { MBEDTLS_CIPHER_AES_192_CTR,          &aes_192_ctr_info },
+    { MBEDTLS_CIPHER_AES_256_CTR,          &aes_256_ctr_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    { MBEDTLS_CIPHER_AES_128_XTS,          &aes_128_xts_info },
+    { MBEDTLS_CIPHER_AES_256_XTS,          &aes_256_xts_info },
+#endif
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_CIPHER_AES_128_GCM,          &aes_128_gcm_info },
+    { MBEDTLS_CIPHER_AES_192_GCM,          &aes_192_gcm_info },
+    { MBEDTLS_CIPHER_AES_256_GCM,          &aes_256_gcm_info },
+#endif
+#if defined(MBEDTLS_CCM_C)
+    { MBEDTLS_CIPHER_AES_128_CCM,          &aes_128_ccm_info },
+    { MBEDTLS_CIPHER_AES_192_CCM,          &aes_192_ccm_info },
+    { MBEDTLS_CIPHER_AES_256_CCM,          &aes_256_ccm_info },
+#endif
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+    { MBEDTLS_CIPHER_ARC4_128,             &arc4_128_info },
+#endif
+
+#if defined(MBEDTLS_BLOWFISH_C)
+    { MBEDTLS_CIPHER_BLOWFISH_ECB,         &blowfish_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_CIPHER_BLOWFISH_CBC,         &blowfish_cbc_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    { MBEDTLS_CIPHER_BLOWFISH_CFB64,       &blowfish_cfb64_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    { MBEDTLS_CIPHER_BLOWFISH_CTR,         &blowfish_ctr_info },
+#endif
+#endif /* MBEDTLS_BLOWFISH_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+    { MBEDTLS_CIPHER_CAMELLIA_128_ECB,     &camellia_128_ecb_info },
+    { MBEDTLS_CIPHER_CAMELLIA_192_ECB,     &camellia_192_ecb_info },
+    { MBEDTLS_CIPHER_CAMELLIA_256_ECB,     &camellia_256_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_CIPHER_CAMELLIA_128_CBC,     &camellia_128_cbc_info },
+    { MBEDTLS_CIPHER_CAMELLIA_192_CBC,     &camellia_192_cbc_info },
+    { MBEDTLS_CIPHER_CAMELLIA_256_CBC,     &camellia_256_cbc_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    { MBEDTLS_CIPHER_CAMELLIA_128_CFB128,  &camellia_128_cfb128_info },
+    { MBEDTLS_CIPHER_CAMELLIA_192_CFB128,  &camellia_192_cfb128_info },
+    { MBEDTLS_CIPHER_CAMELLIA_256_CFB128,  &camellia_256_cfb128_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    { MBEDTLS_CIPHER_CAMELLIA_128_CTR,     &camellia_128_ctr_info },
+    { MBEDTLS_CIPHER_CAMELLIA_192_CTR,     &camellia_192_ctr_info },
+    { MBEDTLS_CIPHER_CAMELLIA_256_CTR,     &camellia_256_ctr_info },
+#endif
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_CIPHER_CAMELLIA_128_GCM,     &camellia_128_gcm_info },
+    { MBEDTLS_CIPHER_CAMELLIA_192_GCM,     &camellia_192_gcm_info },
+    { MBEDTLS_CIPHER_CAMELLIA_256_GCM,     &camellia_256_gcm_info },
+#endif
+#if defined(MBEDTLS_CCM_C)
+    { MBEDTLS_CIPHER_CAMELLIA_128_CCM,     &camellia_128_ccm_info },
+    { MBEDTLS_CIPHER_CAMELLIA_192_CCM,     &camellia_192_ccm_info },
+    { MBEDTLS_CIPHER_CAMELLIA_256_CCM,     &camellia_256_ccm_info },
+#endif
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_ARIA_C)
+    { MBEDTLS_CIPHER_ARIA_128_ECB,     &aria_128_ecb_info },
+    { MBEDTLS_CIPHER_ARIA_192_ECB,     &aria_192_ecb_info },
+    { MBEDTLS_CIPHER_ARIA_256_ECB,     &aria_256_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_CIPHER_ARIA_128_CBC,     &aria_128_cbc_info },
+    { MBEDTLS_CIPHER_ARIA_192_CBC,     &aria_192_cbc_info },
+    { MBEDTLS_CIPHER_ARIA_256_CBC,     &aria_256_cbc_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    { MBEDTLS_CIPHER_ARIA_128_CFB128,  &aria_128_cfb128_info },
+    { MBEDTLS_CIPHER_ARIA_192_CFB128,  &aria_192_cfb128_info },
+    { MBEDTLS_CIPHER_ARIA_256_CFB128,  &aria_256_cfb128_info },
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    { MBEDTLS_CIPHER_ARIA_128_CTR,     &aria_128_ctr_info },
+    { MBEDTLS_CIPHER_ARIA_192_CTR,     &aria_192_ctr_info },
+    { MBEDTLS_CIPHER_ARIA_256_CTR,     &aria_256_ctr_info },
+#endif
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_CIPHER_ARIA_128_GCM,     &aria_128_gcm_info },
+    { MBEDTLS_CIPHER_ARIA_192_GCM,     &aria_192_gcm_info },
+    { MBEDTLS_CIPHER_ARIA_256_GCM,     &aria_256_gcm_info },
+#endif
+#if defined(MBEDTLS_CCM_C)
+    { MBEDTLS_CIPHER_ARIA_128_CCM,     &aria_128_ccm_info },
+    { MBEDTLS_CIPHER_ARIA_192_CCM,     &aria_192_ccm_info },
+    { MBEDTLS_CIPHER_ARIA_256_CCM,     &aria_256_ccm_info },
+#endif
+#endif /* MBEDTLS_ARIA_C */
+
+#if defined(MBEDTLS_DES_C)
+    { MBEDTLS_CIPHER_DES_ECB,              &des_ecb_info },
+    { MBEDTLS_CIPHER_DES_EDE_ECB,          &des_ede_ecb_info },
+    { MBEDTLS_CIPHER_DES_EDE3_ECB,         &des_ede3_ecb_info },
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_CIPHER_DES_CBC,              &des_cbc_info },
+    { MBEDTLS_CIPHER_DES_EDE_CBC,          &des_ede_cbc_info },
+    { MBEDTLS_CIPHER_DES_EDE3_CBC,         &des_ede3_cbc_info },
+#endif
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_CHACHA20_C)
+    { MBEDTLS_CIPHER_CHACHA20,             &chacha20_info },
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    { MBEDTLS_CIPHER_CHACHA20_POLY1305,    &chachapoly_info },
+#endif
+
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+    { MBEDTLS_CIPHER_NULL,                 &null_cipher_info },
+#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
+
+    { MBEDTLS_CIPHER_NONE, NULL }
+};
+
+#define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0]
+int mbedtls_cipher_supported[NUM_CIPHERS];
+
+#endif /* MBEDTLS_CIPHER_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/cmac.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/cmac.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/cmac.c	(revision 398)
@@ -0,0 +1,1078 @@
+/**
+ * \file cmac.c
+ *
+ * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES
+ *
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * References:
+ *
+ * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
+ *      CMAC Mode for Authentication
+ *   http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
+ *
+ * - RFC 4493 - The AES-CMAC Algorithm
+ *   https://tools.ietf.org/html/rfc4493
+ *
+ * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
+ *      Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
+ *      Algorithm for the Internet Key Exchange Protocol (IKE)
+ *   https://tools.ietf.org/html/rfc4615
+ *
+ *   Additional test vectors: ISO/IEC 9797-1
+ *
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CMAC_C)
+
+#include "mbedtls/cmac.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc     calloc
+#define mbedtls_free       free
+#if defined(MBEDTLS_SELF_TEST)
+#include <stdio.h>
+#define mbedtls_printf     printf
+#endif /* MBEDTLS_SELF_TEST */
+#endif /* MBEDTLS_PLATFORM_C */
+
+#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
+
+/*
+ * Multiplication by u in the Galois field of GF(2^n)
+ *
+ * As explained in NIST SP 800-38B, this can be computed:
+ *
+ *   If MSB(p) = 0, then p = (p << 1)
+ *   If MSB(p) = 1, then p = (p << 1) ^ R_n
+ *   with R_64 = 0x1B and  R_128 = 0x87
+ *
+ * Input and output MUST NOT point to the same buffer
+ * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES.
+ */
+static int cmac_multiply_by_u( unsigned char *output,
+                               const unsigned char *input,
+                               size_t blocksize )
+{
+    const unsigned char R_128 = 0x87;
+    const unsigned char R_64 = 0x1B;
+    unsigned char R_n, mask;
+    unsigned char overflow = 0x00;
+    int i;
+
+    if( blocksize == MBEDTLS_AES_BLOCK_SIZE )
+    {
+        R_n = R_128;
+    }
+    else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE )
+    {
+        R_n = R_64;
+    }
+    else
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    for( i = (int)blocksize - 1; i >= 0; i-- )
+    {
+        output[i] = input[i] << 1 | overflow;
+        overflow = input[i] >> 7;
+    }
+
+    /* mask = ( input[0] >> 7 ) ? 0xff : 0x00
+     * using bit operations to avoid branches */
+
+    /* MSVC has a warning about unary minus on unsigned, but this is
+     * well-defined and precisely what we want to do here */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    mask = - ( input[0] >> 7 );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    output[ blocksize - 1 ] ^= R_n & mask;
+
+    return( 0 );
+}
+
+/*
+ * Generate subkeys
+ *
+ * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm
+ */
+static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
+                                  unsigned char* K1, unsigned char* K2 )
+{
+    int ret;
+    unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
+    size_t olen, block_size;
+
+    mbedtls_platform_zeroize( L, sizeof( L ) );
+
+    block_size = ctx->cipher_info->block_size;
+
+    /* Calculate Ek(0) */
+    if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 )
+        goto exit;
+
+    /*
+     * Generate K1 and K2
+     */
+    if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 )
+        goto exit;
+
+    if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_platform_zeroize( L, sizeof( L ) );
+
+    return( ret );
+}
+#endif /* !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST) */
+
+#if !defined(MBEDTLS_CMAC_ALT)
+static void cmac_xor_block( unsigned char *output, const unsigned char *input1,
+                            const unsigned char *input2,
+                            const size_t block_size )
+{
+    size_t idx;
+
+    for( idx = 0; idx < block_size; idx++ )
+        output[ idx ] = input1[ idx ] ^ input2[ idx ];
+}
+
+/*
+ * Create padded last block from (partial) last block.
+ *
+ * We can't use the padding option from the cipher layer, as it only works for
+ * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition.
+ */
+static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX],
+                      size_t padded_block_len,
+                      const unsigned char *last_block,
+                      size_t last_block_len )
+{
+    size_t j;
+
+    for( j = 0; j < padded_block_len; j++ )
+    {
+        if( j < last_block_len )
+            padded_block[j] = last_block[j];
+        else if( j == last_block_len )
+            padded_block[j] = 0x80;
+        else
+            padded_block[j] = 0x00;
+    }
+}
+
+int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx,
+                                const unsigned char *key, size_t keybits )
+{
+    mbedtls_cipher_type_t type;
+    mbedtls_cmac_context_t *cmac_ctx;
+    int retval;
+
+    if( ctx == NULL || ctx->cipher_info == NULL || key == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits,
+                                          MBEDTLS_ENCRYPT ) ) != 0 )
+        return( retval );
+
+    type = ctx->cipher_info->type;
+
+    switch( type )
+    {
+        case MBEDTLS_CIPHER_AES_128_ECB:
+        case MBEDTLS_CIPHER_AES_192_ECB:
+        case MBEDTLS_CIPHER_AES_256_ECB:
+        case MBEDTLS_CIPHER_DES_EDE3_ECB:
+            break;
+        default:
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    /* Allocated and initialise in the cipher context memory for the CMAC
+     * context */
+    cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) );
+    if( cmac_ctx == NULL )
+        return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
+
+    ctx->cmac_ctx = cmac_ctx;
+
+    mbedtls_platform_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) );
+
+    return 0;
+}
+
+int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx,
+                                const unsigned char *input, size_t ilen )
+{
+    mbedtls_cmac_context_t* cmac_ctx;
+    unsigned char *state;
+    int ret = 0;
+    size_t n, j, olen, block_size;
+
+    if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
+        ctx->cmac_ctx == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    cmac_ctx = ctx->cmac_ctx;
+    block_size = ctx->cipher_info->block_size;
+    state = ctx->cmac_ctx->state;
+
+    /* Is there data still to process from the last call, that's greater in
+     * size than a block? */
+    if( cmac_ctx->unprocessed_len > 0 &&
+        ilen > block_size - cmac_ctx->unprocessed_len )
+    {
+        memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
+                input,
+                block_size - cmac_ctx->unprocessed_len );
+
+        cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size );
+
+        if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
+                                           &olen ) ) != 0 )
+        {
+           goto exit;
+        }
+
+        input += block_size - cmac_ctx->unprocessed_len;
+        ilen -= block_size - cmac_ctx->unprocessed_len;
+        cmac_ctx->unprocessed_len = 0;
+    }
+
+    /* n is the number of blocks including any final partial block */
+    n = ( ilen + block_size - 1 ) / block_size;
+
+    /* Iterate across the input data in block sized chunks, excluding any
+     * final partial or complete block */
+    for( j = 1; j < n; j++ )
+    {
+        cmac_xor_block( state, input, state, block_size );
+
+        if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
+                                           &olen ) ) != 0 )
+           goto exit;
+
+        ilen -= block_size;
+        input += block_size;
+    }
+
+    /* If there is data left over that wasn't aligned to a block */
+    if( ilen > 0 )
+    {
+        memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len],
+                input,
+                ilen );
+        cmac_ctx->unprocessed_len += ilen;
+    }
+
+exit:
+    return( ret );
+}
+
+int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
+                                unsigned char *output )
+{
+    mbedtls_cmac_context_t* cmac_ctx;
+    unsigned char *state, *last_block;
+    unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
+    unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
+    unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
+    int ret;
+    size_t olen, block_size;
+
+    if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
+        output == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    cmac_ctx = ctx->cmac_ctx;
+    block_size = ctx->cipher_info->block_size;
+    state = cmac_ctx->state;
+
+    mbedtls_platform_zeroize( K1, sizeof( K1 ) );
+    mbedtls_platform_zeroize( K2, sizeof( K2 ) );
+    cmac_generate_subkeys( ctx, K1, K2 );
+
+    last_block = cmac_ctx->unprocessed_block;
+
+    /* Calculate last block */
+    if( cmac_ctx->unprocessed_len < block_size )
+    {
+        cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len );
+        cmac_xor_block( M_last, M_last, K2, block_size );
+    }
+    else
+    {
+        /* Last block is complete block */
+        cmac_xor_block( M_last, last_block, K1, block_size );
+    }
+
+
+    cmac_xor_block( state, M_last, state, block_size );
+    if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state,
+                                       &olen ) ) != 0 )
+    {
+        goto exit;
+    }
+
+    memcpy( output, state, block_size );
+
+exit:
+    /* Wipe the generated keys on the stack, and any other transients to avoid
+     * side channel leakage */
+    mbedtls_platform_zeroize( K1, sizeof( K1 ) );
+    mbedtls_platform_zeroize( K2, sizeof( K2 ) );
+
+    cmac_ctx->unprocessed_len = 0;
+    mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
+                              sizeof( cmac_ctx->unprocessed_block ) );
+
+    mbedtls_platform_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX );
+    return( ret );
+}
+
+int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
+{
+    mbedtls_cmac_context_t* cmac_ctx;
+
+    if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    cmac_ctx = ctx->cmac_ctx;
+
+    /* Reset the internal state */
+    cmac_ctx->unprocessed_len = 0;
+    mbedtls_platform_zeroize( cmac_ctx->unprocessed_block,
+                              sizeof( cmac_ctx->unprocessed_block ) );
+    mbedtls_platform_zeroize( cmac_ctx->state,
+                              sizeof( cmac_ctx->state ) );
+
+    return( 0 );
+}
+
+int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
+                         const unsigned char *key, size_t keylen,
+                         const unsigned char *input, size_t ilen,
+                         unsigned char *output )
+{
+    mbedtls_cipher_context_t ctx;
+    int ret;
+
+    if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    mbedtls_cipher_init( &ctx );
+
+    if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
+        goto exit;
+
+    ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
+    if( ret != 0 )
+        goto exit;
+
+    ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
+    if( ret != 0 )
+        goto exit;
+
+    ret = mbedtls_cipher_cmac_finish( &ctx, output );
+
+exit:
+    mbedtls_cipher_free( &ctx );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_AES_C)
+/*
+ * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
+ */
+int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
+                              const unsigned char *input, size_t in_len,
+                              unsigned char *output )
+{
+    int ret;
+    const mbedtls_cipher_info_t *cipher_info;
+    unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
+    unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
+
+    if( key == NULL || input == NULL || output == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
+    if( cipher_info == NULL )
+    {
+        /* Failing at this point must be due to a build issue */
+        ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+        goto exit;
+    }
+
+    if( key_length == MBEDTLS_AES_BLOCK_SIZE )
+    {
+        /* Use key as is */
+        memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE );
+    }
+    else
+    {
+        memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE );
+
+        ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
+                                   key_length, int_key );
+        if( ret != 0 )
+            goto exit;
+    }
+
+    ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
+                               output );
+
+exit:
+    mbedtls_platform_zeroize( int_key, sizeof( int_key ) );
+
+    return( ret );
+}
+#endif /* MBEDTLS_AES_C */
+
+#endif /* !MBEDTLS_CMAC_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+/*
+ * CMAC test data for SP800-38B
+ * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf
+ * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf
+ *
+ * AES-CMAC-PRF-128 test data from RFC 4615
+ * https://tools.ietf.org/html/rfc4615#page-4
+ */
+
+#define NB_CMAC_TESTS_PER_KEY 4
+#define NB_PRF_TESTS 3
+
+#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)
+/* All CMAC test inputs are truncated from the same 64 byte buffer. */
+static const unsigned char test_message[] = {
+    /* PT */
+    0x6b, 0xc1, 0xbe, 0xe2,     0x2e, 0x40, 0x9f, 0x96,
+    0xe9, 0x3d, 0x7e, 0x11,     0x73, 0x93, 0x17, 0x2a,
+    0xae, 0x2d, 0x8a, 0x57,     0x1e, 0x03, 0xac, 0x9c,
+    0x9e, 0xb7, 0x6f, 0xac,     0x45, 0xaf, 0x8e, 0x51,
+    0x30, 0xc8, 0x1c, 0x46,     0xa3, 0x5c, 0xe4, 0x11,
+    0xe5, 0xfb, 0xc1, 0x19,     0x1a, 0x0a, 0x52, 0xef,
+    0xf6, 0x9f, 0x24, 0x45,     0xdf, 0x4f, 0x9b, 0x17,
+    0xad, 0x2b, 0x41, 0x7b,     0xe6, 0x6c, 0x37, 0x10
+};
+#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_AES_C)
+/* Truncation point of message for AES CMAC tests  */
+static const  unsigned int  aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
+    /* Mlen */
+    0,
+    16,
+    20,
+    64
+};
+
+/* CMAC-AES128 Test Data */
+static const unsigned char aes_128_key[16] = {
+    0x2b, 0x7e, 0x15, 0x16,     0x28, 0xae, 0xd2, 0xa6,
+    0xab, 0xf7, 0x15, 0x88,     0x09, 0xcf, 0x4f, 0x3c
+};
+static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
+    {
+        /* K1 */
+        0xfb, 0xee, 0xd6, 0x18,     0x35, 0x71, 0x33, 0x66,
+        0x7c, 0x85, 0xe0, 0x8f,     0x72, 0x36, 0xa8, 0xde
+    },
+    {
+        /* K2 */
+        0xf7, 0xdd, 0xac, 0x30,     0x6a, 0xe2, 0x66, 0xcc,
+        0xf9, 0x0b, 0xc1, 0x1e,     0xe4, 0x6d, 0x51, 0x3b
+    }
+};
+static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
+    {
+        /* Example #1 */
+        0xbb, 0x1d, 0x69, 0x29,     0xe9, 0x59, 0x37, 0x28,
+        0x7f, 0xa3, 0x7d, 0x12,     0x9b, 0x75, 0x67, 0x46
+    },
+    {
+        /* Example #2 */
+        0x07, 0x0a, 0x16, 0xb4,     0x6b, 0x4d, 0x41, 0x44,
+        0xf7, 0x9b, 0xdd, 0x9d,     0xd0, 0x4a, 0x28, 0x7c
+    },
+    {
+        /* Example #3 */
+        0x7d, 0x85, 0x44, 0x9e,     0xa6, 0xea, 0x19, 0xc8,
+        0x23, 0xa7, 0xbf, 0x78,     0x83, 0x7d, 0xfa, 0xde
+    },
+    {
+        /* Example #4 */
+        0x51, 0xf0, 0xbe, 0xbf,     0x7e, 0x3b, 0x9d, 0x92,
+        0xfc, 0x49, 0x74, 0x17,     0x79, 0x36, 0x3c, 0xfe
+    }
+};
+
+/* CMAC-AES192 Test Data */
+static const unsigned char aes_192_key[24] = {
+    0x8e, 0x73, 0xb0, 0xf7,     0xda, 0x0e, 0x64, 0x52,
+    0xc8, 0x10, 0xf3, 0x2b,     0x80, 0x90, 0x79, 0xe5,
+    0x62, 0xf8, 0xea, 0xd2,     0x52, 0x2c, 0x6b, 0x7b
+};
+static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
+    {
+        /* K1 */
+        0x44, 0x8a, 0x5b, 0x1c,     0x93, 0x51, 0x4b, 0x27,
+        0x3e, 0xe6, 0x43, 0x9d,     0xd4, 0xda, 0xa2, 0x96
+    },
+    {
+        /* K2 */
+        0x89, 0x14, 0xb6, 0x39,     0x26, 0xa2, 0x96, 0x4e,
+        0x7d, 0xcc, 0x87, 0x3b,     0xa9, 0xb5, 0x45, 0x2c
+    }
+};
+static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
+    {
+        /* Example #1 */
+        0xd1, 0x7d, 0xdf, 0x46,     0xad, 0xaa, 0xcd, 0xe5,
+        0x31, 0xca, 0xc4, 0x83,     0xde, 0x7a, 0x93, 0x67
+    },
+    {
+        /* Example #2 */
+        0x9e, 0x99, 0xa7, 0xbf,     0x31, 0xe7, 0x10, 0x90,
+        0x06, 0x62, 0xf6, 0x5e,     0x61, 0x7c, 0x51, 0x84
+    },
+    {
+        /* Example #3 */
+        0x3d, 0x75, 0xc1, 0x94,     0xed, 0x96, 0x07, 0x04,
+        0x44, 0xa9, 0xfa, 0x7e,     0xc7, 0x40, 0xec, 0xf8
+    },
+    {
+        /* Example #4 */
+        0xa1, 0xd5, 0xdf, 0x0e,     0xed, 0x79, 0x0f, 0x79,
+        0x4d, 0x77, 0x58, 0x96,     0x59, 0xf3, 0x9a, 0x11
+    }
+};
+
+/* CMAC-AES256 Test Data */
+static const unsigned char aes_256_key[32] = {
+    0x60, 0x3d, 0xeb, 0x10,     0x15, 0xca, 0x71, 0xbe,
+    0x2b, 0x73, 0xae, 0xf0,     0x85, 0x7d, 0x77, 0x81,
+    0x1f, 0x35, 0x2c, 0x07,     0x3b, 0x61, 0x08, 0xd7,
+    0x2d, 0x98, 0x10, 0xa3,     0x09, 0x14, 0xdf, 0xf4
+};
+static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = {
+    {
+        /* K1 */
+        0xca, 0xd1, 0xed, 0x03,     0x29, 0x9e, 0xed, 0xac,
+        0x2e, 0x9a, 0x99, 0x80,     0x86, 0x21, 0x50, 0x2f
+    },
+    {
+        /* K2 */
+        0x95, 0xa3, 0xda, 0x06,     0x53, 0x3d, 0xdb, 0x58,
+        0x5d, 0x35, 0x33, 0x01,     0x0c, 0x42, 0xa0, 0xd9
+    }
+};
+static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = {
+    {
+        /* Example #1 */
+        0x02, 0x89, 0x62, 0xf6,     0x1b, 0x7b, 0xf8, 0x9e,
+        0xfc, 0x6b, 0x55, 0x1f,     0x46, 0x67, 0xd9, 0x83
+    },
+    {
+        /* Example #2 */
+        0x28, 0xa7, 0x02, 0x3f,     0x45, 0x2e, 0x8f, 0x82,
+        0xbd, 0x4b, 0xf2, 0x8d,     0x8c, 0x37, 0xc3, 0x5c
+    },
+    {
+        /* Example #3 */
+        0x15, 0x67, 0x27, 0xdc,     0x08, 0x78, 0x94, 0x4a,
+        0x02, 0x3c, 0x1f, 0xe0,     0x3b, 0xad, 0x6d, 0x93
+    },
+    {
+        /* Example #4 */
+        0xe1, 0x99, 0x21, 0x90,     0x54, 0x9f, 0x6e, 0xd5,
+        0x69, 0x6a, 0x2c, 0x05,     0x6c, 0x31, 0x54, 0x10
+    }
+};
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_DES_C)
+/* Truncation point of message for 3DES CMAC tests  */
+static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = {
+    0,
+    16,
+    20,
+    32
+};
+
+/* CMAC-TDES (Generation) - 2 Key Test Data */
+static const unsigned char des3_2key_key[24] = {
+    /* Key1 */
+    0x01, 0x23, 0x45, 0x67,     0x89, 0xab, 0xcd, 0xef,
+    /* Key2 */
+    0x23, 0x45, 0x67, 0x89,     0xab, 0xcd, 0xEF, 0x01,
+    /* Key3 */
+    0x01, 0x23, 0x45, 0x67,     0x89, 0xab, 0xcd, 0xef
+};
+static const unsigned char des3_2key_subkeys[2][8] = {
+    {
+        /* K1 */
+        0x0d, 0xd2, 0xcb, 0x7a,     0x3d, 0x88, 0x88, 0xd9
+    },
+    {
+        /* K2 */
+        0x1b, 0xa5, 0x96, 0xf4,     0x7b, 0x11, 0x11, 0xb2
+    }
+};
+static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
+    {
+        /* Sample #1 */
+        0x79, 0xce, 0x52, 0xa7,     0xf7, 0x86, 0xa9, 0x60
+    },
+    {
+        /* Sample #2 */
+        0xcc, 0x18, 0xa0, 0xb7,     0x9a, 0xf2, 0x41, 0x3b
+    },
+    {
+        /* Sample #3 */
+        0xc0, 0x6d, 0x37, 0x7e,     0xcd, 0x10, 0x19, 0x69
+    },
+    {
+        /* Sample #4 */
+        0x9c, 0xd3, 0x35, 0x80,     0xf9, 0xb6, 0x4d, 0xfb
+    }
+};
+
+/* CMAC-TDES (Generation) - 3 Key Test Data */
+static const unsigned char des3_3key_key[24] = {
+    /* Key1 */
+    0x01, 0x23, 0x45, 0x67,     0x89, 0xaa, 0xcd, 0xef,
+    /* Key2 */
+    0x23, 0x45, 0x67, 0x89,     0xab, 0xcd, 0xef, 0x01,
+    /* Key3 */
+    0x45, 0x67, 0x89, 0xab,     0xcd, 0xef, 0x01, 0x23
+};
+static const unsigned char des3_3key_subkeys[2][8] = {
+    {
+        /* K1 */
+        0x9d, 0x74, 0xe7, 0x39,     0x33, 0x17, 0x96, 0xc0
+    },
+    {
+        /* K2 */
+        0x3a, 0xe9, 0xce, 0x72,     0x66, 0x2f, 0x2d, 0x9b
+    }
+};
+static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = {
+    {
+        /* Sample #1 */
+        0x7d, 0xb0, 0xd3, 0x7d,     0xf9, 0x36, 0xc5, 0x50
+    },
+    {
+        /* Sample #2 */
+        0x30, 0x23, 0x9c, 0xf1,     0xf5, 0x2e, 0x66, 0x09
+    },
+    {
+        /* Sample #3 */
+        0x6c, 0x9f, 0x3e, 0xe4,     0x92, 0x3f, 0x6b, 0xe2
+    },
+    {
+        /* Sample #4 */
+        0x99, 0x42, 0x9b, 0xd0,     0xbF, 0x79, 0x04, 0xe5
+    }
+};
+
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_AES_C)
+/* AES AES-CMAC-PRF-128 Test Data */
+static const unsigned char PRFK[] = {
+    /* Key */
+    0x00, 0x01, 0x02, 0x03,     0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b,     0x0c, 0x0d, 0x0e, 0x0f,
+    0xed, 0xcb
+};
+
+/* Sizes in bytes */
+static const size_t PRFKlen[NB_PRF_TESTS] = {
+    18,
+    16,
+    10
+};
+
+/* Message */
+static const unsigned char PRFM[] = {
+    0x00, 0x01, 0x02, 0x03,     0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b,     0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13
+};
+
+static const unsigned char PRFT[NB_PRF_TESTS][16] = {
+    {
+        0x84, 0xa3, 0x48, 0xa4,     0xa4, 0x5d, 0x23, 0x5b,
+        0xab, 0xff, 0xfc, 0x0d,     0x2b, 0x4d, 0xa0, 0x9a
+    },
+    {
+        0x98, 0x0a, 0xe8, 0x7b,     0x5f, 0x4c, 0x9c, 0x52,
+        0x14, 0xf5, 0xb6, 0xa8,     0x45, 0x5e, 0x4c, 0x2d
+    },
+    {
+        0x29, 0x0d, 0x9e, 0x11,     0x2e, 0xdb, 0x09, 0xee,
+        0x14, 0x1f, 0xcf, 0x64,     0xc0, 0xb7, 0x2f, 0x3d
+    }
+};
+#endif /* MBEDTLS_AES_C */
+
+static int cmac_test_subkeys( int verbose,
+                              const char* testname,
+                              const unsigned char* key,
+                              int keybits,
+                              const unsigned char* subkeys,
+                              mbedtls_cipher_type_t cipher_type,
+                              int block_size,
+                              int num_tests )
+{
+    int i, ret = 0;
+    mbedtls_cipher_context_t ctx;
+    const mbedtls_cipher_info_t *cipher_info;
+    unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
+    unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
+
+    cipher_info = mbedtls_cipher_info_from_type( cipher_type );
+    if( cipher_info == NULL )
+    {
+        /* Failing at this point must be due to a build issue */
+        return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+    }
+
+    for( i = 0; i < num_tests; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  %s CMAC subkey #%u: ", testname, i + 1 );
+
+        mbedtls_cipher_init( &ctx );
+
+        if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "test execution failed\n" );
+
+            goto cleanup;
+        }
+
+        if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
+                                       MBEDTLS_ENCRYPT ) ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "test execution failed\n" );
+
+            goto cleanup;
+        }
+
+        ret = cmac_generate_subkeys( &ctx, K1, K2 );
+        if( ret != 0 )
+        {
+           if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            goto cleanup;
+        }
+
+        if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0  ||
+            ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            goto cleanup;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+
+        mbedtls_cipher_free( &ctx );
+    }
+
+    ret = 0;
+    goto exit;
+
+cleanup:
+    mbedtls_cipher_free( &ctx );
+
+exit:
+    return( ret );
+}
+
+static int cmac_test_wth_cipher( int verbose,
+                                 const char* testname,
+                                 const unsigned char* key,
+                                 int keybits,
+                                 const unsigned char* messages,
+                                 const unsigned int message_lengths[4],
+                                 const unsigned char* expected_result,
+                                 mbedtls_cipher_type_t cipher_type,
+                                 int block_size,
+                                 int num_tests )
+{
+    const mbedtls_cipher_info_t *cipher_info;
+    int i, ret = 0;
+    unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX];
+
+    cipher_info = mbedtls_cipher_info_from_type( cipher_type );
+    if( cipher_info == NULL )
+    {
+        /* Failing at this point must be due to a build issue */
+        ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+        goto exit;
+    }
+
+    for( i = 0; i < num_tests; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  %s CMAC #%u: ", testname, i + 1 );
+
+        if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
+                                         message_lengths[i], output ) ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+            goto exit;
+        }
+
+        if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+    ret = 0;
+
+exit:
+    return( ret );
+}
+
+#if defined(MBEDTLS_AES_C)
+static int test_aes128_cmac_prf( int verbose )
+{
+    int i;
+    int ret;
+    unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
+
+    for( i = 0; i < NB_PRF_TESTS; i++ )
+    {
+        mbedtls_printf( "  AES CMAC 128 PRF #%u: ", i );
+        ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
+        if( ret != 0 ||
+            memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
+        {
+
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            return( ret );
+        }
+        else if( verbose != 0 )
+        {
+            mbedtls_printf( "passed\n" );
+        }
+    }
+    return( ret );
+}
+#endif /* MBEDTLS_AES_C */
+
+int mbedtls_cmac_self_test( int verbose )
+{
+    int ret;
+
+#if defined(MBEDTLS_AES_C)
+    /* AES-128 */
+    if( ( ret = cmac_test_subkeys( verbose,
+                                   "AES 128",
+                                   aes_128_key,
+                                   128,
+                                   (const unsigned char*)aes_128_subkeys,
+                                   MBEDTLS_CIPHER_AES_128_ECB,
+                                   MBEDTLS_AES_BLOCK_SIZE,
+                                   NB_CMAC_TESTS_PER_KEY ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = cmac_test_wth_cipher( verbose,
+                                      "AES 128",
+                                      aes_128_key,
+                                      128,
+                                      test_message,
+                                      aes_message_lengths,
+                                      (const unsigned char*)aes_128_expected_result,
+                                      MBEDTLS_CIPHER_AES_128_ECB,
+                                      MBEDTLS_AES_BLOCK_SIZE,
+                                      NB_CMAC_TESTS_PER_KEY ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /* AES-192 */
+    if( ( ret = cmac_test_subkeys( verbose,
+                                   "AES 192",
+                                   aes_192_key,
+                                   192,
+                                   (const unsigned char*)aes_192_subkeys,
+                                   MBEDTLS_CIPHER_AES_192_ECB,
+                                   MBEDTLS_AES_BLOCK_SIZE,
+                                   NB_CMAC_TESTS_PER_KEY ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = cmac_test_wth_cipher( verbose,
+                                      "AES 192",
+                                      aes_192_key,
+                                      192,
+                                      test_message,
+                                      aes_message_lengths,
+                                      (const unsigned char*)aes_192_expected_result,
+                                      MBEDTLS_CIPHER_AES_192_ECB,
+                                      MBEDTLS_AES_BLOCK_SIZE,
+                                      NB_CMAC_TESTS_PER_KEY ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /* AES-256 */
+    if( ( ret = cmac_test_subkeys( verbose,
+                                   "AES 256",
+                                   aes_256_key,
+                                   256,
+                                   (const unsigned char*)aes_256_subkeys,
+                                   MBEDTLS_CIPHER_AES_256_ECB,
+                                   MBEDTLS_AES_BLOCK_SIZE,
+                                   NB_CMAC_TESTS_PER_KEY ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = cmac_test_wth_cipher ( verbose,
+                                       "AES 256",
+                                       aes_256_key,
+                                       256,
+                                       test_message,
+                                       aes_message_lengths,
+                                       (const unsigned char*)aes_256_expected_result,
+                                       MBEDTLS_CIPHER_AES_256_ECB,
+                                       MBEDTLS_AES_BLOCK_SIZE,
+                                       NB_CMAC_TESTS_PER_KEY ) ) != 0 )
+    {
+        return( ret );
+    }
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_DES_C)
+    /* 3DES 2 key */
+    if( ( ret = cmac_test_subkeys( verbose,
+                                   "3DES 2 key",
+                                   des3_2key_key,
+                                   192,
+                                   (const unsigned char*)des3_2key_subkeys,
+                                   MBEDTLS_CIPHER_DES_EDE3_ECB,
+                                   MBEDTLS_DES3_BLOCK_SIZE,
+                                   NB_CMAC_TESTS_PER_KEY ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = cmac_test_wth_cipher( verbose,
+                                      "3DES 2 key",
+                                      des3_2key_key,
+                                      192,
+                                      test_message,
+                                      des3_message_lengths,
+                                      (const unsigned char*)des3_2key_expected_result,
+                                      MBEDTLS_CIPHER_DES_EDE3_ECB,
+                                      MBEDTLS_DES3_BLOCK_SIZE,
+                                      NB_CMAC_TESTS_PER_KEY ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /* 3DES 3 key */
+    if( ( ret = cmac_test_subkeys( verbose,
+                                   "3DES 3 key",
+                                   des3_3key_key,
+                                   192,
+                                   (const unsigned char*)des3_3key_subkeys,
+                                   MBEDTLS_CIPHER_DES_EDE3_ECB,
+                                   MBEDTLS_DES3_BLOCK_SIZE,
+                                   NB_CMAC_TESTS_PER_KEY ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = cmac_test_wth_cipher( verbose,
+                                      "3DES 3 key",
+                                      des3_3key_key,
+                                      192,
+                                      test_message,
+                                      des3_message_lengths,
+                                      (const unsigned char*)des3_3key_expected_result,
+                                      MBEDTLS_CIPHER_DES_EDE3_ECB,
+                                      MBEDTLS_DES3_BLOCK_SIZE,
+                                      NB_CMAC_TESTS_PER_KEY ) ) != 0 )
+    {
+        return( ret );
+    }
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_AES_C)
+    if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 )
+        return( ret );
+#endif /* MBEDTLS_AES_C */
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_CMAC_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ctr_drbg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ctr_drbg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ctr_drbg.c	(revision 398)
@@ -0,0 +1,721 @@
+/*
+ *  CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The NIST SP 800-90 DRBGs are described in the following publication.
+ *
+ *  http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CTR_DRBG_C)
+
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_FS_IO)
+#include <stdio.h>
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+/*
+ * CTR_DRBG context initialization
+ */
+void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+}
+
+/*
+ * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
+ * NIST tests to succeed (which require known length fixed entropy)
+ */
+/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
+ * mbedtls_ctr_drbg_seed_entropy_len(ctx, f_entropy, p_entropy,
+ *                                   custom, len, entropy_len)
+ * implements
+ * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
+ *                      security_strength) -> initial_working_state
+ * with inputs
+ *   custom[:len] = nonce || personalization_string
+ * where entropy_input comes from f_entropy for entropy_len bytes
+ * and with outputs
+ *   ctx = initial_working_state
+ */
+int mbedtls_ctr_drbg_seed_entropy_len(
+                   mbedtls_ctr_drbg_context *ctx,
+                   int (*f_entropy)(void *, unsigned char *, size_t),
+                   void *p_entropy,
+                   const unsigned char *custom,
+                   size_t len,
+                   size_t entropy_len )
+{
+    int ret;
+    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
+
+    memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
+
+    mbedtls_aes_init( &ctx->aes_ctx );
+
+    ctx->f_entropy = f_entropy;
+    ctx->p_entropy = p_entropy;
+
+    ctx->entropy_len = entropy_len;
+    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
+
+    /*
+     * Initialize with an empty key
+     */
+    if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
+    {
+        return( ret );
+    }
+    return( 0 );
+}
+
+int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
+                   int (*f_entropy)(void *, unsigned char *, size_t),
+                   void *p_entropy,
+                   const unsigned char *custom,
+                   size_t len )
+{
+    return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
+                                       MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
+}
+
+void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_free( &ctx->mutex );
+#endif
+    mbedtls_aes_free( &ctx->aes_ctx );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
+}
+
+void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
+{
+    ctx->prediction_resistance = resistance;
+}
+
+void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len )
+{
+    ctx->entropy_len = len;
+}
+
+void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval )
+{
+    ctx->reseed_interval = interval;
+}
+
+static int block_cipher_df( unsigned char *output,
+                            const unsigned char *data, size_t data_len )
+{
+    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
+    unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
+    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
+    unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
+    unsigned char *p, *iv;
+    mbedtls_aes_context aes_ctx;
+    int ret = 0;
+
+    int i, j;
+    size_t buf_len, use_len;
+
+    if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
+        return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+
+    memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
+    mbedtls_aes_init( &aes_ctx );
+
+    /*
+     * Construct IV (16 bytes) and S in buffer
+     * IV = Counter (in 32-bits) padded to 16 with zeroes
+     * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
+     *     data || 0x80
+     *     (Total is padded to a multiple of 16-bytes with zeroes)
+     */
+    p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
+    *p++ = ( data_len >> 24 ) & 0xff;
+    *p++ = ( data_len >> 16 ) & 0xff;
+    *p++ = ( data_len >> 8  ) & 0xff;
+    *p++ = ( data_len       ) & 0xff;
+    p += 3;
+    *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
+    memcpy( p, data, data_len );
+    p[data_len] = 0x80;
+
+    buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
+
+    for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
+        key[i] = i;
+
+    if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+    {
+        goto exit;
+    }
+
+    /*
+     * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
+     */
+    for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
+    {
+        p = buf;
+        memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
+        use_len = buf_len;
+
+        while( use_len > 0 )
+        {
+            for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ )
+                chain[i] ^= p[i];
+            p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
+            use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
+                       MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
+
+            if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 )
+            {
+                goto exit;
+            }
+        }
+
+        memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
+
+        /*
+         * Update IV
+         */
+        buf[3]++;
+    }
+
+    /*
+     * Do final encryption with reduced data
+     */
+    if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+    {
+        goto exit;
+    }
+    iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
+    p = output;
+
+    for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
+    {
+        if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 )
+        {
+            goto exit;
+        }
+        memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
+        p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
+    }
+exit:
+    mbedtls_aes_free( &aes_ctx );
+    /*
+    * tidy up the stack
+    */
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_platform_zeroize( key, sizeof( key ) );
+    mbedtls_platform_zeroize( chain, sizeof( chain ) );
+    if( 0 != ret )
+    {
+        /*
+        * wipe partial seed from memory
+        */
+        mbedtls_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
+    }
+
+    return( ret );
+}
+
+/* CTR_DRBG_Update (SP 800-90A &sect;10.2.1.2)
+ * ctr_drbg_update_internal(ctx, provided_data)
+ * implements
+ * CTR_DRBG_Update(provided_data, Key, V)
+ * with inputs and outputs
+ *   ctx->aes_ctx = Key
+ *   ctx->counter = V
+ */
+static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
+                              const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
+{
+    unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
+    unsigned char *p = tmp;
+    int i, j;
+    int ret = 0;
+
+    memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
+
+    for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
+    {
+        /*
+         * Increase counter
+         */
+        for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
+            if( ++ctx->counter[i - 1] != 0 )
+                break;
+
+        /*
+         * Crypt counter block
+         */
+        if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
+            goto exit;
+
+        p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
+    }
+
+    for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ )
+        tmp[i] ^= data[i];
+
+    /*
+     * Update key and counter
+     */
+    if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+        goto exit;
+    memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
+
+exit:
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    return( ret );
+}
+
+/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
+ * mbedtls_ctr_drbg_update(ctx, additional, add_len)
+ * implements
+ * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
+ *                      security_strength) -> initial_working_state
+ * with inputs
+ *   ctx->counter = all-bits-0
+ *   ctx->aes_ctx = context from all-bits-0 key
+ *   additional[:add_len] = entropy_input || nonce || personalization_string
+ * and with outputs
+ *   ctx = initial_working_state
+ */
+int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
+                                 const unsigned char *additional,
+                                 size_t add_len )
+{
+    unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
+    int ret;
+
+    if( add_len == 0 )
+        return( 0 );
+
+    if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
+        goto exit;
+    if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
+                              const unsigned char *additional,
+                              size_t add_len )
+{
+    /* MAX_INPUT would be more logical here, but we have to match
+     * block_cipher_df()'s limits since we can't propagate errors */
+    if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
+        add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
+    (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len );
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
+ * mbedtls_ctr_drbg_reseed(ctx, additional, len)
+ * implements
+ * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
+ *                -> new_working_state
+ * with inputs
+ *   ctx contains working_state
+ *   additional[:len] = additional_input
+ * and entropy_input comes from calling ctx->f_entropy
+ * and with output
+ *   ctx contains new_working_state
+ */
+int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
+                     const unsigned char *additional, size_t len )
+{
+    unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
+    size_t seedlen = 0;
+    int ret;
+
+    if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
+        len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
+        return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+
+    memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
+
+    /*
+     * Gather entropy_len bytes of entropy to seed state
+     */
+    if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
+                             ctx->entropy_len ) )
+    {
+        return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
+    }
+
+    seedlen += ctx->entropy_len;
+
+    /*
+     * Add additional data
+     */
+    if( additional && len )
+    {
+        memcpy( seed + seedlen, additional, len );
+        seedlen += len;
+    }
+
+    /*
+     * Reduce to 384 bits
+     */
+    if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
+        goto exit;
+
+    /*
+     * Update state
+     */
+    if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
+        goto exit;
+    ctx->reseed_counter = 1;
+
+exit:
+    mbedtls_platform_zeroize( seed, sizeof( seed ) );
+    return( ret );
+}
+
+/* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
+ * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
+ * implements
+ * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
+ *                -> working_state_after_reseed
+ *                if required, then
+ * CTR_DRBG_Generate(working_state_after_reseed,
+ *                   requested_number_of_bits, additional_input)
+ *                -> status, returned_bits, new_working_state
+ * with inputs
+ *   ctx contains working_state
+ *   requested_number_of_bits = 8 * output_len
+ *   additional[:add_len] = additional_input
+ * and entropy_input comes from calling ctx->f_entropy
+ * and with outputs
+ *   status = SUCCESS (this function does the reseed internally)
+ *   returned_bits = output[:output_len]
+ *   ctx contains new_working_state
+ */
+int mbedtls_ctr_drbg_random_with_add( void *p_rng,
+                              unsigned char *output, size_t output_len,
+                              const unsigned char *additional, size_t add_len )
+{
+    int ret = 0;
+    mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
+    unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
+    unsigned char *p = output;
+    unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
+    int i;
+    size_t use_len;
+
+    if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
+        return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
+
+    if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
+        return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+
+    memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
+
+    if( ctx->reseed_counter > ctx->reseed_interval ||
+        ctx->prediction_resistance )
+    {
+        if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
+        {
+            return( ret );
+        }
+        add_len = 0;
+    }
+
+    if( add_len > 0 )
+    {
+        if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
+            goto exit;
+        if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
+            goto exit;
+    }
+
+    while( output_len > 0 )
+    {
+        /*
+         * Increase counter
+         */
+        for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
+            if( ++ctx->counter[i - 1] != 0 )
+                break;
+
+        /*
+         * Crypt counter block
+         */
+        if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
+            goto exit;
+
+        use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
+                                                       output_len;
+        /*
+         * Copy random block to destination
+         */
+        memcpy( p, tmp, use_len );
+        p += use_len;
+        output_len -= use_len;
+    }
+
+    if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
+        goto exit;
+
+    ctx->reseed_counter++;
+
+exit:
+    mbedtls_platform_zeroize( add_input, sizeof( add_input ) );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    return( 0 );
+}
+
+int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
+{
+    int ret;
+    mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_FS_IO)
+int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
+{
+    int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
+    FILE *f;
+    unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
+
+    if( ( f = fopen( path, "wb" ) ) == NULL )
+        return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
+
+    if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
+        goto exit;
+
+    if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
+        ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
+    else
+        ret = 0;
+
+exit:
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+
+    fclose( f );
+    return( ret );
+}
+
+int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
+{
+    int ret = 0;
+    FILE *f = NULL;
+    size_t n;
+    unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
+    unsigned char c;
+
+    if( ( f = fopen( path, "rb" ) ) == NULL )
+        return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
+
+    n = fread( buf, 1, sizeof( buf ), f );
+    if( fread( &c, 1, 1, f ) != 0 )
+    {
+        ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
+        goto exit;
+    }
+    if( n == 0 || ferror( f ) )
+    {
+        ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
+        goto exit;
+    }
+    fclose( f );
+    f = NULL;
+
+    ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n );
+
+exit:
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+    if( f != NULL )
+        fclose( f );
+    if( ret != 0 )
+        return( ret );
+    return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
+}
+#endif /* MBEDTLS_FS_IO */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+static const unsigned char entropy_source_pr[96] =
+    { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
+      0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
+      0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
+      0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
+      0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
+      0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
+      0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
+      0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
+      0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
+      0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
+      0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
+      0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
+
+static const unsigned char entropy_source_nopr[64] =
+    { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
+      0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
+      0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
+      0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
+      0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
+      0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
+      0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
+      0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
+
+static const unsigned char nonce_pers_pr[16] =
+    { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
+      0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
+
+static const unsigned char nonce_pers_nopr[16] =
+    { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
+      0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
+
+static const unsigned char result_pr[16] =
+    { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
+      0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
+
+static const unsigned char result_nopr[16] =
+    { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
+      0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
+
+static size_t test_offset;
+static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
+                                       size_t len )
+{
+    const unsigned char *p = data;
+    memcpy( buf, p + test_offset, len );
+    test_offset += len;
+    return( 0 );
+}
+
+#define CHK( c )    if( (c) != 0 )                          \
+                    {                                       \
+                        if( verbose != 0 )                  \
+                            mbedtls_printf( "failed\n" );  \
+                        return( 1 );                        \
+                    }
+
+/*
+ * Checkup routine
+ */
+int mbedtls_ctr_drbg_self_test( int verbose )
+{
+    mbedtls_ctr_drbg_context ctx;
+    unsigned char buf[16];
+
+    mbedtls_ctr_drbg_init( &ctx );
+
+    /*
+     * Based on a NIST CTR_DRBG test vector (PR = True)
+     */
+    if( verbose != 0 )
+        mbedtls_printf( "  CTR_DRBG (PR = TRUE) : " );
+
+    test_offset = 0;
+    CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
+                                (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
+    mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
+    CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
+    CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
+    CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
+
+    mbedtls_ctr_drbg_free( &ctx );
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    /*
+     * Based on a NIST CTR_DRBG test vector (PR = FALSE)
+     */
+    if( verbose != 0 )
+        mbedtls_printf( "  CTR_DRBG (PR = FALSE): " );
+
+    mbedtls_ctr_drbg_init( &ctx );
+
+    test_offset = 0;
+    CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
+                            (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
+    CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
+    CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
+    CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
+    CHK( memcmp( buf, result_nopr, 16 ) );
+
+    mbedtls_ctr_drbg_free( &ctx );
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    if( verbose != 0 )
+            mbedtls_printf( "\n" );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_CTR_DRBG_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/debug.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/debug.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/debug.c	(revision 398)
@@ -0,0 +1,418 @@
+/*
+ *  Debugging routines
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_DEBUG_C)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc      calloc
+#define mbedtls_free        free
+#define mbedtls_time_t      time_t
+#define mbedtls_snprintf    snprintf
+#endif
+
+#include "mbedtls/debug.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#define DEBUG_BUF_SIZE      512
+
+static int debug_threshold = 0;
+
+void mbedtls_debug_set_threshold( int threshold )
+{
+    debug_threshold = threshold;
+}
+
+/*
+ * All calls to f_dbg must be made via this function
+ */
+static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level,
+                                    const char *file, int line,
+                                    const char *str )
+{
+    /*
+     * If in a threaded environment, we need a thread identifier.
+     * Since there is no portable way to get one, use the address of the ssl
+     * context instead, as it shouldn't be shared between threads.
+     */
+#if defined(MBEDTLS_THREADING_C)
+    char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */
+    mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void*)ssl, str );
+    ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr );
+#else
+    ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str );
+#endif
+}
+
+void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
+                              const char *file, int line,
+                              const char *format, ... )
+{
+    va_list argp;
+    char str[DEBUG_BUF_SIZE];
+    int ret;
+
+    if( NULL == ssl || NULL == ssl->conf || NULL == ssl->conf->f_dbg || level > debug_threshold )
+        return;
+
+    va_start( argp, format );
+#if defined(_WIN32)
+#if defined(_TRUNCATE) && !defined(__MINGW32__)
+    ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp );
+#else
+    ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
+    if( ret < 0 || (size_t) ret == DEBUG_BUF_SIZE )
+    {
+        str[DEBUG_BUF_SIZE-1] = '\0';
+        ret = -1;
+    }
+#endif
+#else
+    ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
+#endif
+    va_end( argp );
+
+    if( ret >= 0 && ret < DEBUG_BUF_SIZE - 1 )
+    {
+        str[ret]     = '\n';
+        str[ret + 1] = '\0';
+    }
+
+    debug_send_line( ssl, level, file, line, str );
+}
+
+void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
+                      const char *file, int line,
+                      const char *text, int ret )
+{
+    char str[DEBUG_BUF_SIZE];
+
+    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
+        return;
+
+    /*
+     * With non-blocking I/O and examples that just retry immediately,
+     * the logs would be quickly flooded with WANT_READ, so ignore that.
+     * Don't ignore WANT_WRITE however, since is is usually rare.
+     */
+    if( ret == MBEDTLS_ERR_SSL_WANT_READ )
+        return;
+
+    mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n",
+              text, ret, -ret );
+
+    debug_send_line( ssl, level, file, line, str );
+}
+
+void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
+                      const char *file, int line, const char *text,
+                      const unsigned char *buf, size_t len )
+{
+    char str[DEBUG_BUF_SIZE];
+    char txt[17];
+    size_t i, idx = 0;
+
+    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
+        return;
+
+    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "dumping '%s' (%u bytes)\n",
+              text, (unsigned int) len );
+
+    debug_send_line( ssl, level, file, line, str );
+
+    idx = 0;
+    memset( txt, 0, sizeof( txt ) );
+    for( i = 0; i < len; i++ )
+    {
+        if( i >= 4096 )
+            break;
+
+        if( i % 16 == 0 )
+        {
+            if( i > 0 )
+            {
+                mbedtls_snprintf( str + idx, sizeof( str ) - idx, "  %s\n", txt );
+                debug_send_line( ssl, level, file, line, str );
+
+                idx = 0;
+                memset( txt, 0, sizeof( txt ) );
+            }
+
+            idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, "%04x: ",
+                             (unsigned int) i );
+
+        }
+
+        idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x",
+                         (unsigned int) buf[i] );
+        txt[i % 16] = ( buf[i] > 31 && buf[i] < 127 ) ? buf[i] : '.' ;
+    }
+
+    if( len > 0 )
+    {
+        for( /* i = i */; i % 16 != 0; i++ )
+            idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, "   " );
+
+        mbedtls_snprintf( str + idx, sizeof( str ) - idx, "  %s\n", txt );
+        debug_send_line( ssl, level, file, line, str );
+    }
+}
+
+#if defined(MBEDTLS_ECP_C)
+void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
+                      const char *file, int line,
+                      const char *text, const mbedtls_ecp_point *X )
+{
+    char str[DEBUG_BUF_SIZE];
+
+    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
+        return;
+
+    mbedtls_snprintf( str, sizeof( str ), "%s(X)", text );
+    mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X );
+
+    mbedtls_snprintf( str, sizeof( str ), "%s(Y)", text );
+    mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->Y );
+}
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_BIGNUM_C)
+void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
+                      const char *file, int line,
+                      const char *text, const mbedtls_mpi *X )
+{
+    char str[DEBUG_BUF_SIZE];
+    int j, k, zeros = 1;
+    size_t i, n, idx = 0;
+
+    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || X == NULL || level > debug_threshold )
+        return;
+
+    for( n = X->n - 1; n > 0; n-- )
+        if( X->p[n] != 0 )
+            break;
+
+    for( j = ( sizeof(mbedtls_mpi_uint) << 3 ) - 1; j >= 0; j-- )
+        if( ( ( X->p[n] >> j ) & 1 ) != 0 )
+            break;
+
+    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "value of '%s' (%d bits) is:\n",
+              text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) );
+
+    debug_send_line( ssl, level, file, line, str );
+
+    idx = 0;
+    for( i = n + 1, j = 0; i > 0; i-- )
+    {
+        if( zeros && X->p[i - 1] == 0 )
+            continue;
+
+        for( k = sizeof( mbedtls_mpi_uint ) - 1; k >= 0; k-- )
+        {
+            if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 )
+                continue;
+            else
+                zeros = 0;
+
+            if( j % 16 == 0 )
+            {
+                if( j > 0 )
+                {
+                    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
+                    debug_send_line( ssl, level, file, line, str );
+                    idx = 0;
+                }
+            }
+
+            idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", (unsigned int)
+                             ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF );
+
+            j++;
+        }
+
+    }
+
+    if( zeros == 1 )
+        idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " 00" );
+
+    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
+    debug_send_line( ssl, level, file, line, str );
+}
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+static void debug_print_pk( const mbedtls_ssl_context *ssl, int level,
+                            const char *file, int line,
+                            const char *text, const mbedtls_pk_context *pk )
+{
+    size_t i;
+    mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS];
+    char name[16];
+
+    memset( items, 0, sizeof( items ) );
+
+    if( mbedtls_pk_debug( pk, items ) != 0 )
+    {
+        debug_send_line( ssl, level, file, line,
+                          "invalid PK context\n" );
+        return;
+    }
+
+    for( i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++ )
+    {
+        if( items[i].type == MBEDTLS_PK_DEBUG_NONE )
+            return;
+
+        mbedtls_snprintf( name, sizeof( name ), "%s%s", text, items[i].name );
+        name[sizeof( name ) - 1] = '\0';
+
+        if( items[i].type == MBEDTLS_PK_DEBUG_MPI )
+            mbedtls_debug_print_mpi( ssl, level, file, line, name, items[i].value );
+        else
+#if defined(MBEDTLS_ECP_C)
+        if( items[i].type == MBEDTLS_PK_DEBUG_ECP )
+            mbedtls_debug_print_ecp( ssl, level, file, line, name, items[i].value );
+        else
+#endif
+            debug_send_line( ssl, level, file, line,
+                              "should not happen\n" );
+    }
+}
+
+static void debug_print_line_by_line( const mbedtls_ssl_context *ssl, int level,
+                                      const char *file, int line, const char *text )
+{
+    char str[DEBUG_BUF_SIZE];
+    const char *start, *cur;
+
+    start = text;
+    for( cur = text; *cur != '\0'; cur++ )
+    {
+        if( *cur == '\n' )
+        {
+            size_t len = cur - start + 1;
+            if( len > DEBUG_BUF_SIZE - 1 )
+                len = DEBUG_BUF_SIZE - 1;
+
+            memcpy( str, start, len );
+            str[len] = '\0';
+
+            debug_send_line( ssl, level, file, line, str );
+
+            start = cur + 1;
+        }
+    }
+}
+
+void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
+                      const char *file, int line,
+                      const char *text, const mbedtls_x509_crt *crt )
+{
+    char str[DEBUG_BUF_SIZE];
+    int i = 0;
+
+    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || crt == NULL || level > debug_threshold )
+        return;
+
+    while( crt != NULL )
+    {
+        char buf[1024];
+
+        mbedtls_snprintf( str, sizeof( str ), "%s #%d:\n", text, ++i );
+        debug_send_line( ssl, level, file, line, str );
+
+        mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
+        debug_print_line_by_line( ssl, level, file, line, buf );
+
+        debug_print_pk( ssl, level, file, line, "crt->", &crt->pk );
+
+        crt = crt->next;
+    }
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_ECDH_C)
+static void mbedtls_debug_printf_ecdh_internal( const mbedtls_ssl_context *ssl,
+                                                int level, const char *file,
+                                                int line,
+                                                const mbedtls_ecdh_context *ecdh,
+                                                mbedtls_debug_ecdh_attr attr )
+{
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    const mbedtls_ecdh_context* ctx = ecdh;
+#else
+    const mbedtls_ecdh_context_mbed* ctx = &ecdh->ctx.mbed_ecdh;
+#endif
+
+    switch( attr )
+    {
+        case MBEDTLS_DEBUG_ECDH_Q:
+            mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Q",
+                                     &ctx->Q );
+            break;
+        case MBEDTLS_DEBUG_ECDH_QP:
+            mbedtls_debug_print_ecp( ssl, level, file, line, "ECDH: Qp",
+                                     &ctx->Qp );
+            break;
+        case MBEDTLS_DEBUG_ECDH_Z:
+            mbedtls_debug_print_mpi( ssl, level, file, line, "ECDH: z",
+                                     &ctx->z );
+            break;
+        default:
+            break;
+    }
+}
+
+void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level,
+                                const char *file, int line,
+                                const mbedtls_ecdh_context *ecdh,
+                                mbedtls_debug_ecdh_attr attr )
+{
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh, attr );
+#else
+    switch( ecdh->var )
+    {
+        default:
+            mbedtls_debug_printf_ecdh_internal( ssl, level, file, line, ecdh,
+                                                attr );
+    }
+#endif
+}
+#endif /* MBEDTLS_ECDH_C */
+
+#endif /* MBEDTLS_DEBUG_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/des.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/des.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/des.c	(revision 398)
@@ -0,0 +1,1057 @@
+/*
+ *  FIPS-46-3 compliant Triple-DES implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  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
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_DES_C)
+
+#include "mbedtls/des.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_DES_ALT)
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t LHs[16] =
+{
+    0x00000000, 0x00000001, 0x00000100, 0x00000101,
+    0x00010000, 0x00010001, 0x00010100, 0x00010101,
+    0x01000000, 0x01000001, 0x01000100, 0x01000101,
+    0x01010000, 0x01010001, 0x01010100, 0x01010101
+};
+
+static const uint32_t 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) { uint32_t t = a; a = b; b = t; t = 0; }
+
+void mbedtls_des_init( mbedtls_des_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_des_context ) );
+}
+
+void mbedtls_des_free( mbedtls_des_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des_context ) );
+}
+
+void mbedtls_des3_init( mbedtls_des3_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_des3_context ) );
+}
+
+void mbedtls_des3_free( mbedtls_des3_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_des3_context ) );
+}
+
+static const unsigned char odd_parity_table[128] = { 1,  2,  4,  7,  8,
+        11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
+        47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
+        82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
+        115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
+        143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
+        171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
+        199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
+        227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
+        254 };
+
+void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] )
+{
+    int i;
+
+    for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
+        key[i] = odd_parity_table[key[i] / 2];
+}
+
+/*
+ * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
+ */
+int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
+{
+    int i;
+
+    for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ )
+        if( key[i] != odd_parity_table[key[i] / 2] )
+            return( 1 );
+
+    return( 0 );
+}
+
+/*
+ * Table of weak and semi-weak keys
+ *
+ * Source: http://en.wikipedia.org/wiki/Weak_key
+ *
+ * Weak:
+ * Alternating ones + zeros (0x0101010101010101)
+ * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
+ * '0xE0E0E0E0F1F1F1F1'
+ * '0x1F1F1F1F0E0E0E0E'
+ *
+ * Semi-weak:
+ * 0x011F011F010E010E and 0x1F011F010E010E01
+ * 0x01E001E001F101F1 and 0xE001E001F101F101
+ * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
+ * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
+ * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
+ * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
+ *
+ */
+
+#define WEAK_KEY_COUNT 16
+
+static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] =
+{
+    { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
+    { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
+    { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
+    { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
+
+    { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
+    { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
+    { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
+    { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
+    { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
+    { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
+    { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
+    { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
+    { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
+    { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
+    { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
+    { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
+};
+
+int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
+{
+    int i;
+
+    for( i = 0; i < WEAK_KEY_COUNT; i++ )
+        if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
+            return( 1 );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DES_SETKEY_ALT)
+void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
+{
+    int i;
+    uint32_t X, Y, T;
+
+    GET_UINT32_BE( X, key, 0 );
+    GET_UINT32_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);
+    }
+}
+#endif /* !MBEDTLS_DES_SETKEY_ALT */
+
+/*
+ * DES key schedule (56-bit, encryption)
+ */
+int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
+{
+    mbedtls_des_setkey( ctx->sk, key );
+
+    return( 0 );
+}
+
+/*
+ * DES key schedule (56-bit, decryption)
+ */
+int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] )
+{
+    int i;
+
+    mbedtls_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] );
+    }
+
+    return( 0 );
+}
+
+static void des3_set2key( uint32_t esk[96],
+                          uint32_t dsk[96],
+                          const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] )
+{
+    int i;
+
+    mbedtls_des_setkey( esk, key );
+    mbedtls_des_setkey( dsk + 32, key + 8 );
+
+    for( i = 0; i < 32; i += 2 )
+    {
+        dsk[i     ] = esk[30 - i];
+        dsk[i +  1] = esk[31 - i];
+
+        esk[i + 32] = dsk[62 - i];
+        esk[i + 33] = dsk[63 - i];
+
+        esk[i + 64] = esk[i    ];
+        esk[i + 65] = esk[i + 1];
+
+        dsk[i + 64] = dsk[i    ];
+        dsk[i + 65] = dsk[i + 1];
+    }
+}
+
+/*
+ * Triple-DES key schedule (112-bit, encryption)
+ */
+int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
+                      const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
+{
+    uint32_t sk[96];
+
+    des3_set2key( ctx->sk, sk, key );
+    mbedtls_platform_zeroize( sk,  sizeof( sk ) );
+
+    return( 0 );
+}
+
+/*
+ * Triple-DES key schedule (112-bit, decryption)
+ */
+int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
+                      const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] )
+{
+    uint32_t sk[96];
+
+    des3_set2key( sk, ctx->sk, key );
+    mbedtls_platform_zeroize( sk,  sizeof( sk ) );
+
+    return( 0 );
+}
+
+static void des3_set3key( uint32_t esk[96],
+                          uint32_t dsk[96],
+                          const unsigned char key[24] )
+{
+    int i;
+
+    mbedtls_des_setkey( esk, key );
+    mbedtls_des_setkey( dsk + 32, key +  8 );
+    mbedtls_des_setkey( esk + 64, key + 16 );
+
+    for( i = 0; i < 32; i += 2 )
+    {
+        dsk[i     ] = esk[94 - i];
+        dsk[i +  1] = esk[95 - i];
+
+        esk[i + 32] = dsk[62 - i];
+        esk[i + 33] = dsk[63 - i];
+
+        dsk[i + 64] = esk[30 - i];
+        dsk[i + 65] = esk[31 - i];
+    }
+}
+
+/*
+ * Triple-DES key schedule (168-bit, encryption)
+ */
+int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
+                      const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
+{
+    uint32_t sk[96];
+
+    des3_set3key( ctx->sk, sk, key );
+    mbedtls_platform_zeroize( sk,  sizeof( sk ) );
+
+    return( 0 );
+}
+
+/*
+ * Triple-DES key schedule (168-bit, decryption)
+ */
+int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
+                      const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] )
+{
+    uint32_t sk[96];
+
+    des3_set3key( sk, ctx->sk, key );
+    mbedtls_platform_zeroize( sk,  sizeof( sk ) );
+
+    return( 0 );
+}
+
+/*
+ * DES-ECB block encryption/decryption
+ */
+#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT)
+int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
+                    const unsigned char input[8],
+                    unsigned char output[8] )
+{
+    int i;
+    uint32_t X, Y, T, *SK;
+
+    SK = ctx->sk;
+
+    GET_UINT32_BE( X, input, 0 );
+    GET_UINT32_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_UINT32_BE( Y, output, 0 );
+    PUT_UINT32_BE( X, output, 4 );
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * DES-CBC buffer encryption/decryption
+ */
+int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[8],
+                    const unsigned char *input,
+                    unsigned char *output )
+{
+    int i;
+    unsigned char temp[8];
+
+    if( length % 8 )
+        return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
+
+    if( mode == MBEDTLS_DES_ENCRYPT )
+    {
+        while( length > 0 )
+        {
+            for( i = 0; i < 8; i++ )
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+            mbedtls_des_crypt_ecb( ctx, output, output );
+            memcpy( iv, output, 8 );
+
+            input  += 8;
+            output += 8;
+            length -= 8;
+        }
+    }
+    else /* MBEDTLS_DES_DECRYPT */
+    {
+        while( length > 0 )
+        {
+            memcpy( temp, input, 8 );
+            mbedtls_des_crypt_ecb( ctx, input, output );
+
+            for( i = 0; i < 8; i++ )
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+            memcpy( iv, temp, 8 );
+
+            input  += 8;
+            output += 8;
+            length -= 8;
+        }
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+/*
+ * 3DES-ECB block encryption/decryption
+ */
+#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
+int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
+                     const unsigned char input[8],
+                     unsigned char output[8] )
+{
+    int i;
+    uint32_t X, Y, T, *SK;
+
+    SK = ctx->sk;
+
+    GET_UINT32_BE( X, input, 0 );
+    GET_UINT32_BE( Y, input, 4 );
+
+    DES_IP( X, Y );
+
+    for( i = 0; i < 8; i++ )
+    {
+        DES_ROUND( Y, X );
+        DES_ROUND( X, Y );
+    }
+
+    for( i = 0; i < 8; i++ )
+    {
+        DES_ROUND( X, Y );
+        DES_ROUND( Y, X );
+    }
+
+    for( i = 0; i < 8; i++ )
+    {
+        DES_ROUND( Y, X );
+        DES_ROUND( X, Y );
+    }
+
+    DES_FP( Y, X );
+
+    PUT_UINT32_BE( Y, output, 0 );
+    PUT_UINT32_BE( X, output, 4 );
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * 3DES-CBC buffer encryption/decryption
+ */
+int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
+                     int mode,
+                     size_t length,
+                     unsigned char iv[8],
+                     const unsigned char *input,
+                     unsigned char *output )
+{
+    int i;
+    unsigned char temp[8];
+
+    if( length % 8 )
+        return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH );
+
+    if( mode == MBEDTLS_DES_ENCRYPT )
+    {
+        while( length > 0 )
+        {
+            for( i = 0; i < 8; i++ )
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+            mbedtls_des3_crypt_ecb( ctx, output, output );
+            memcpy( iv, output, 8 );
+
+            input  += 8;
+            output += 8;
+            length -= 8;
+        }
+    }
+    else /* MBEDTLS_DES_DECRYPT */
+    {
+        while( length > 0 )
+        {
+            memcpy( temp, input, 8 );
+            mbedtls_des3_crypt_ecb( ctx, input, output );
+
+            for( i = 0; i < 8; i++ )
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+            memcpy( iv, temp, 8 );
+
+            input  += 8;
+            output += 8;
+            length -= 8;
+        }
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#endif /* !MBEDTLS_DES_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+/*
+ * DES and 3DES test vectors from:
+ *
+ * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
+ */
+static const unsigned char des3_test_keys[24] =
+{
+    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+    0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
+    0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
+};
+
+static const unsigned char des3_test_buf[8] =
+{
+    0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
+};
+
+static const unsigned char des3_test_ecb_dec[3][8] =
+{
+    { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
+    { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
+    { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
+};
+
+static const unsigned char des3_test_ecb_enc[3][8] =
+{
+    { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
+    { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
+    { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
+};
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+static const unsigned char des3_test_iv[8] =
+{
+    0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
+};
+
+static const unsigned char des3_test_cbc_dec[3][8] =
+{
+    { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
+    { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
+    { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
+};
+
+static const unsigned char des3_test_cbc_enc[3][8] =
+{
+    { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
+    { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
+    { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
+};
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+/*
+ * Checkup routine
+ */
+int mbedtls_des_self_test( int verbose )
+{
+    int i, j, u, v, ret = 0;
+    mbedtls_des_context ctx;
+    mbedtls_des3_context ctx3;
+    unsigned char buf[8];
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    unsigned char prv[8];
+    unsigned char iv[8];
+#endif
+
+    mbedtls_des_init( &ctx );
+    mbedtls_des3_init( &ctx3 );
+    /*
+     * ECB mode
+     */
+    for( i = 0; i < 6; i++ )
+    {
+        u = i >> 1;
+        v = i  & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  DES%c-ECB-%3d (%s): ",
+                             ( u == 0 ) ? ' ' : '3', 56 + u * 56,
+                             ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
+
+        memcpy( buf, des3_test_buf, 8 );
+
+        switch( i )
+        {
+        case 0:
+            mbedtls_des_setkey_dec( &ctx, des3_test_keys );
+            break;
+
+        case 1:
+            mbedtls_des_setkey_enc( &ctx, des3_test_keys );
+            break;
+
+        case 2:
+            mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
+            break;
+
+        case 3:
+            mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
+            break;
+
+        case 4:
+            mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
+            break;
+
+        case 5:
+            mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
+            break;
+
+        default:
+            return( 1 );
+        }
+
+        for( j = 0; j < 10000; j++ )
+        {
+            if( u == 0 )
+                mbedtls_des_crypt_ecb( &ctx, buf, buf );
+            else
+                mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
+        }
+
+        if( ( v == MBEDTLS_DES_DECRYPT &&
+                memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
+            ( v != MBEDTLS_DES_DECRYPT &&
+                memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    /*
+     * CBC mode
+     */
+    for( i = 0; i < 6; i++ )
+    {
+        u = i >> 1;
+        v = i  & 1;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  DES%c-CBC-%3d (%s): ",
+                             ( u == 0 ) ? ' ' : '3', 56 + u * 56,
+                             ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" );
+
+        memcpy( iv,  des3_test_iv,  8 );
+        memcpy( prv, des3_test_iv,  8 );
+        memcpy( buf, des3_test_buf, 8 );
+
+        switch( i )
+        {
+        case 0:
+            mbedtls_des_setkey_dec( &ctx, des3_test_keys );
+            break;
+
+        case 1:
+            mbedtls_des_setkey_enc( &ctx, des3_test_keys );
+            break;
+
+        case 2:
+            mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
+            break;
+
+        case 3:
+            mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
+            break;
+
+        case 4:
+            mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
+            break;
+
+        case 5:
+            mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
+            break;
+
+        default:
+            return( 1 );
+        }
+
+        if( v == MBEDTLS_DES_DECRYPT )
+        {
+            for( j = 0; j < 10000; j++ )
+            {
+                if( u == 0 )
+                    mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
+                else
+                    mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+            }
+        }
+        else
+        {
+            for( j = 0; j < 10000; j++ )
+            {
+                unsigned char tmp[8];
+
+                if( u == 0 )
+                    mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
+                else
+                    mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
+
+                memcpy( tmp, prv, 8 );
+                memcpy( prv, buf, 8 );
+                memcpy( buf, tmp, 8 );
+            }
+
+            memcpy( buf, prv, 8 );
+        }
+
+        if( ( v == MBEDTLS_DES_DECRYPT &&
+                memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
+            ( v != MBEDTLS_DES_DECRYPT &&
+                memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+exit:
+    mbedtls_des_free( &ctx );
+    mbedtls_des3_free( &ctx3 );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_DES_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/dhm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/dhm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/dhm.c	(revision 398)
@@ -0,0 +1,696 @@
+/*
+ *  Diffie-Hellman-Merkle key exchange
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The following sources were referenced in the design of this implementation
+ *  of the Diffie-Hellman-Merkle algorithm:
+ *
+ *  [1] Handbook of Applied Cryptography - 1997, Chapter 12
+ *      Menezes, van Oorschot and Vanstone
+ *
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_DHM_C)
+
+#include "mbedtls/dhm.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+#include "mbedtls/pem.h"
+#endif
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+#include "mbedtls/asn1.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#define mbedtls_printf     printf
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#if !defined(MBEDTLS_DHM_ALT)
+
+#define DHM_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA )
+#define DHM_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * helper to validate the mbedtls_mpi size and import it
+ */
+static int dhm_read_bignum( mbedtls_mpi *X,
+                            unsigned char **p,
+                            const unsigned char *end )
+{
+    int ret, n;
+
+    if( end - *p < 2 )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    n = ( (*p)[0] << 8 ) | (*p)[1];
+    (*p) += 2;
+
+    if( (int)( end - *p ) < n )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
+        return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );
+
+    (*p) += n;
+
+    return( 0 );
+}
+
+/*
+ * Verify sanity of parameter with regards to P
+ *
+ * Parameter should be: 2 <= public_param <= P - 2
+ *
+ * This means that we need to return an error if
+ *              public_param < 2 or public_param > P-2
+ *
+ * For more information on the attack, see:
+ *  http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
+ *  http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
+ */
+static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
+{
+    mbedtls_mpi L, U;
+    int ret = 0;
+
+    mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
+
+    if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 ||
+        mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
+    {
+        ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
+    }
+
+cleanup:
+    mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
+    return( ret );
+}
+
+void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
+{
+    DHM_VALIDATE( ctx != NULL );
+    memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
+}
+
+/*
+ * Parse the ServerKeyExchange parameters
+ */
+int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
+                     unsigned char **p,
+                     const unsigned char *end )
+{
+    int ret;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( p != NULL && *p != NULL );
+    DHM_VALIDATE_RET( end != NULL );
+
+    if( ( ret = dhm_read_bignum( &ctx->P,  p, end ) ) != 0 ||
+        ( ret = dhm_read_bignum( &ctx->G,  p, end ) ) != 0 ||
+        ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
+        return( ret );
+
+    if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
+        return( ret );
+
+    ctx->len = mbedtls_mpi_size( &ctx->P );
+
+    return( 0 );
+}
+
+/*
+ * Setup and write the ServerKeyExchange parameters
+ */
+int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
+                     unsigned char *output, size_t *olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret, count = 0;
+    size_t n1, n2, n3;
+    unsigned char *p;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( output != NULL );
+    DHM_VALIDATE_RET( olen != NULL );
+    DHM_VALIDATE_RET( f_rng != NULL );
+
+    if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    /*
+     * Generate X as large as possible ( < P )
+     */
+    do
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
+
+        while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
+
+        if( count++ > 10 )
+            return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
+    }
+    while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
+
+    /*
+     * Calculate GX = G^X mod P
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
+                          &ctx->P , &ctx->RP ) );
+
+    if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
+        return( ret );
+
+    /*
+     * export P, G, GX
+     */
+#define DHM_MPI_EXPORT( X, n )                                          \
+    do {                                                                \
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ),               \
+                                                   p + 2,               \
+                                                   ( n ) ) );           \
+        *p++ = (unsigned char)( ( n ) >> 8 );                           \
+        *p++ = (unsigned char)( ( n )      );                           \
+        p += ( n );                                                     \
+    } while( 0 )
+
+    n1 = mbedtls_mpi_size( &ctx->P  );
+    n2 = mbedtls_mpi_size( &ctx->G  );
+    n3 = mbedtls_mpi_size( &ctx->GX );
+
+    p = output;
+    DHM_MPI_EXPORT( &ctx->P , n1 );
+    DHM_MPI_EXPORT( &ctx->G , n2 );
+    DHM_MPI_EXPORT( &ctx->GX, n3 );
+
+    *olen = p - output;
+
+    ctx->len = n1;
+
+cleanup:
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
+
+    return( 0 );
+}
+
+/*
+ * Set prime modulus and generator
+ */
+int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
+                           const mbedtls_mpi *P,
+                           const mbedtls_mpi *G )
+{
+    int ret;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( P != NULL );
+    DHM_VALIDATE_RET( G != NULL );
+
+    if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
+        ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret );
+    }
+
+    ctx->len = mbedtls_mpi_size( &ctx->P );
+    return( 0 );
+}
+
+/*
+ * Import the peer's public value G^Y
+ */
+int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
+                     const unsigned char *input, size_t ilen )
+{
+    int ret;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( input != NULL );
+
+    if( ilen < 1 || ilen > ctx->len )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
+        return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );
+
+    return( 0 );
+}
+
+/*
+ * Create own private value X and export G^X
+ */
+int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
+                     unsigned char *output, size_t olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret, count = 0;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( output != NULL );
+    DHM_VALIDATE_RET( f_rng != NULL );
+
+    if( olen < 1 || olen > ctx->len )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    /*
+     * generate X and calculate GX = G^X mod P
+     */
+    do
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
+
+        while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
+
+        if( count++ > 10 )
+            return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
+    }
+    while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
+                          &ctx->P , &ctx->RP ) );
+
+    if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
+        return( ret );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
+
+cleanup:
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
+
+    return( 0 );
+}
+
+/*
+ * Use the blinding method and optimisation suggested in section 10 of:
+ *  KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
+ *  DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
+ *  Berlin Heidelberg, 1996. p. 104-113.
+ */
+static int dhm_update_blinding( mbedtls_dhm_context *ctx,
+                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret, count;
+
+    /*
+     * Don't use any blinding the first time a particular X is used,
+     * but remember it to use blinding next time.
+     */
+    if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
+
+        return( 0 );
+    }
+
+    /*
+     * Ok, we need blinding. Can we re-use existing values?
+     * If yes, just update them by squaring them.
+     */
+    if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
+
+        return( 0 );
+    }
+
+    /*
+     * We need to generate blinding values from scratch
+     */
+
+    /* Vi = random( 2, P-1 ) */
+    count = 0;
+    do
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) );
+
+        while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) );
+
+        if( count++ > 10 )
+            return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+    }
+    while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
+
+    /* Vf = Vi^-X mod P */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Derive and export the shared secret (G^Y)^X mod P
+ */
+int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
+                     unsigned char *output, size_t output_size, size_t *olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret;
+    mbedtls_mpi GYb;
+    DHM_VALIDATE_RET( ctx != NULL );
+    DHM_VALIDATE_RET( output != NULL );
+    DHM_VALIDATE_RET( olen != NULL );
+
+    if( output_size < ctx->len )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
+        return( ret );
+
+    mbedtls_mpi_init( &GYb );
+
+    /* Blind peer's value */
+    if( f_rng != NULL )
+    {
+        MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
+    }
+    else
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
+
+    /* Do modular exponentiation */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
+                          &ctx->P, &ctx->RP ) );
+
+    /* Unblind secret value */
+    if( f_rng != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
+    }
+
+    *olen = mbedtls_mpi_size( &ctx->K );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
+
+cleanup:
+    mbedtls_mpi_free( &GYb );
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret );
+
+    return( 0 );
+}
+
+/*
+ * Free the components of a DHM key
+ */
+void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_mpi_free( &ctx->pX );
+    mbedtls_mpi_free( &ctx->Vf );
+    mbedtls_mpi_free( &ctx->Vi );
+    mbedtls_mpi_free( &ctx->RP );
+    mbedtls_mpi_free( &ctx->K  );
+    mbedtls_mpi_free( &ctx->GY );
+    mbedtls_mpi_free( &ctx->GX );
+    mbedtls_mpi_free( &ctx->X  );
+    mbedtls_mpi_free( &ctx->G  );
+    mbedtls_mpi_free( &ctx->P  );
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
+}
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+/*
+ * Parse DHM parameters
+ */
+int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
+                   size_t dhminlen )
+{
+    int ret;
+    size_t len;
+    unsigned char *p, *end;
+#if defined(MBEDTLS_PEM_PARSE_C)
+    mbedtls_pem_context pem;
+#endif /* MBEDTLS_PEM_PARSE_C */
+
+    DHM_VALIDATE_RET( dhm != NULL );
+    DHM_VALIDATE_RET( dhmin != NULL );
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+    mbedtls_pem_init( &pem );
+
+    /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
+    if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
+        ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+    else
+        ret = mbedtls_pem_read_buffer( &pem,
+                               "-----BEGIN DH PARAMETERS-----",
+                               "-----END DH PARAMETERS-----",
+                               dhmin, NULL, 0, &dhminlen );
+
+    if( ret == 0 )
+    {
+        /*
+         * Was PEM encoded
+         */
+        dhminlen = pem.buflen;
+    }
+    else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+        goto exit;
+
+    p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
+#else
+    p = (unsigned char *) dhmin;
+#endif /* MBEDTLS_PEM_PARSE_C */
+    end = p + dhminlen;
+
+    /*
+     *  DHParams ::= SEQUENCE {
+     *      prime              INTEGER,  -- P
+     *      generator          INTEGER,  -- g
+     *      privateValueLength INTEGER OPTIONAL
+     *  }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+        goto exit;
+    }
+
+    end = p + len;
+
+    if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P  ) ) != 0 ||
+        ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
+    {
+        ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+        goto exit;
+    }
+
+    if( p != end )
+    {
+        /* This might be the optional privateValueLength.
+         * If so, we can cleanly discard it */
+        mbedtls_mpi rec;
+        mbedtls_mpi_init( &rec );
+        ret = mbedtls_asn1_get_mpi( &p, end, &rec );
+        mbedtls_mpi_free( &rec );
+        if ( ret != 0 )
+        {
+            ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+            goto exit;
+        }
+        if ( p != end )
+        {
+            ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+            goto exit;
+        }
+    }
+
+    ret = 0;
+
+    dhm->len = mbedtls_mpi_size( &dhm->P );
+
+exit:
+#if defined(MBEDTLS_PEM_PARSE_C)
+    mbedtls_pem_free( &pem );
+#endif
+    if( ret != 0 )
+        mbedtls_dhm_free( dhm );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_FS_IO)
+/*
+ * Load all data from a file into a given buffer.
+ *
+ * The file is expected to contain either PEM or DER encoded data.
+ * A terminating null byte is always appended. It is included in the announced
+ * length only if the data looks like it is PEM encoded.
+ */
+static int load_file( const char *path, unsigned char **buf, size_t *n )
+{
+    FILE *f;
+    long size;
+
+    if( ( f = fopen( path, "rb" ) ) == NULL )
+        return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
+
+    fseek( f, 0, SEEK_END );
+    if( ( size = ftell( f ) ) == -1 )
+    {
+        fclose( f );
+        return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
+    }
+    fseek( f, 0, SEEK_SET );
+
+    *n = (size_t) size;
+
+    if( *n + 1 == 0 ||
+        ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
+    {
+        fclose( f );
+        return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
+    }
+
+    if( fread( *buf, 1, *n, f ) != *n )
+    {
+        fclose( f );
+
+        mbedtls_platform_zeroize( *buf, *n + 1 );
+        mbedtls_free( *buf );
+
+        return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
+    }
+
+    fclose( f );
+
+    (*buf)[*n] = '\0';
+
+    if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
+        ++*n;
+
+    return( 0 );
+}
+
+/*
+ * Load and parse DHM parameters
+ */
+int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
+{
+    int ret;
+    size_t n;
+    unsigned char *buf;
+    DHM_VALIDATE_RET( dhm != NULL );
+    DHM_VALIDATE_RET( path != NULL );
+
+    if( ( ret = load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
+
+    ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
+
+    mbedtls_platform_zeroize( buf, n );
+    mbedtls_free( buf );
+
+    return( ret );
+}
+#endif /* MBEDTLS_FS_IO */
+#endif /* MBEDTLS_ASN1_PARSE_C */
+#endif /* MBEDTLS_DHM_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+static const char mbedtls_test_dhm_params[] =
+"-----BEGIN DH PARAMETERS-----\r\n"
+"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
+"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
+"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
+"-----END DH PARAMETERS-----\r\n";
+
+static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
+
+/*
+ * Checkup routine
+ */
+int mbedtls_dhm_self_test( int verbose )
+{
+    int ret;
+    mbedtls_dhm_context dhm;
+
+    mbedtls_dhm_init( &dhm );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  DHM parameter load: " );
+
+    if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
+                    (const unsigned char *) mbedtls_test_dhm_params,
+                    mbedtls_test_dhm_params_len ) ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto exit;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n\n" );
+
+exit:
+    mbedtls_dhm_free( &dhm );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_DHM_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecdh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecdh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecdh.c	(revision 398)
@@ -0,0 +1,653 @@
+/*
+ *  Elliptic curve Diffie-Hellman
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * References:
+ *
+ * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
+ * RFC 4492
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ECDH_C)
+
+#include "mbedtls/ecdh.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+/* Parameter validation macros based on platform_util.h */
+#define ECDH_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECDH_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed;
+#endif
+
+#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
+/*
+ * Generate public key (restartable version)
+ *
+ * Note: this internal function relies on its caller preserving the value of
+ * the output parameter 'd' across continuation calls. This would not be
+ * acceptable for a public function but is OK here as we control call sites.
+ */
+static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp,
+                    mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                    int (*f_rng)(void *, unsigned char *, size_t),
+                    void *p_rng,
+                    mbedtls_ecp_restart_ctx *rs_ctx )
+{
+    int ret;
+
+    /* If multiplication is in progress, we already generated a privkey */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx == NULL || rs_ctx->rsm == NULL )
+#endif
+        MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, Q, d, &grp->G,
+                                                  f_rng, p_rng, rs_ctx ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Generate public key
+ */
+int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    ECDH_VALIDATE_RET( grp != NULL );
+    ECDH_VALIDATE_RET( d != NULL );
+    ECDH_VALIDATE_RET( Q != NULL );
+    ECDH_VALIDATE_RET( f_rng != NULL );
+    return( ecdh_gen_public_restartable( grp, d, Q, f_rng, p_rng, NULL ) );
+}
+#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */
+
+#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
+/*
+ * Compute shared secret (SEC1 3.3.1)
+ */
+static int ecdh_compute_shared_restartable( mbedtls_ecp_group *grp,
+                         mbedtls_mpi *z,
+                         const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng,
+                         mbedtls_ecp_restart_ctx *rs_ctx )
+{
+    int ret;
+    mbedtls_ecp_point P;
+
+    mbedtls_ecp_point_init( &P );
+
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &P, d, Q,
+                                                  f_rng, p_rng, rs_ctx ) );
+
+    if( mbedtls_ecp_is_zero( &P ) )
+    {
+        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) );
+
+cleanup:
+    mbedtls_ecp_point_free( &P );
+
+    return( ret );
+}
+
+/*
+ * Compute shared secret (SEC1 3.3.1)
+ */
+int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
+                         const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng )
+{
+    ECDH_VALIDATE_RET( grp != NULL );
+    ECDH_VALIDATE_RET( Q != NULL );
+    ECDH_VALIDATE_RET( d != NULL );
+    ECDH_VALIDATE_RET( z != NULL );
+    return( ecdh_compute_shared_restartable( grp, z, Q, d,
+                                             f_rng, p_rng, NULL ) );
+}
+#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
+
+static void ecdh_init_internal( mbedtls_ecdh_context_mbed *ctx )
+{
+    mbedtls_ecp_group_init( &ctx->grp );
+    mbedtls_mpi_init( &ctx->d  );
+    mbedtls_ecp_point_init( &ctx->Q   );
+    mbedtls_ecp_point_init( &ctx->Qp  );
+    mbedtls_mpi_init( &ctx->z  );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    mbedtls_ecp_restart_init( &ctx->rs );
+#endif
+}
+
+/*
+ * Initialize context
+ */
+void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
+{
+    ECDH_VALIDATE( ctx != NULL );
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    ecdh_init_internal( ctx );
+    mbedtls_ecp_point_init( &ctx->Vi  );
+    mbedtls_ecp_point_init( &ctx->Vf  );
+    mbedtls_mpi_init( &ctx->_d );
+#else
+    memset( ctx, 0, sizeof( mbedtls_ecdh_context ) );
+
+    ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
+#endif
+    ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    ctx->restart_enabled = 0;
+#endif
+}
+
+static int ecdh_setup_internal( mbedtls_ecdh_context_mbed *ctx,
+                                mbedtls_ecp_group_id grp_id )
+{
+    int ret;
+
+    ret = mbedtls_ecp_group_load( &ctx->grp, grp_id );
+    if( ret != 0 )
+    {
+        return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Setup context
+ */
+int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id )
+{
+    ECDH_VALIDATE_RET( ctx != NULL );
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_setup_internal( ctx, grp_id ) );
+#else
+    switch( grp_id )
+    {
+        default:
+            ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
+            ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
+            ctx->grp_id = grp_id;
+            ecdh_init_internal( &ctx->ctx.mbed_ecdh );
+            return( ecdh_setup_internal( &ctx->ctx.mbed_ecdh, grp_id ) );
+    }
+#endif
+}
+
+static void ecdh_free_internal( mbedtls_ecdh_context_mbed *ctx )
+{
+    mbedtls_ecp_group_free( &ctx->grp );
+    mbedtls_mpi_free( &ctx->d  );
+    mbedtls_ecp_point_free( &ctx->Q   );
+    mbedtls_ecp_point_free( &ctx->Qp  );
+    mbedtls_mpi_free( &ctx->z  );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    mbedtls_ecp_restart_free( &ctx->rs );
+#endif
+}
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/*
+ * Enable restartable operations for context
+ */
+void mbedtls_ecdh_enable_restart( mbedtls_ecdh_context *ctx )
+{
+    ECDH_VALIDATE( ctx != NULL );
+
+    ctx->restart_enabled = 1;
+}
+#endif
+
+/*
+ * Free context
+ */
+void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    mbedtls_ecp_point_free( &ctx->Vi );
+    mbedtls_ecp_point_free( &ctx->Vf );
+    mbedtls_mpi_free( &ctx->_d );
+    ecdh_free_internal( ctx );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            ecdh_free_internal( &ctx->ctx.mbed_ecdh );
+            break;
+        default:
+            break;
+    }
+
+    ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
+    ctx->var = MBEDTLS_ECDH_VARIANT_NONE;
+    ctx->grp_id = MBEDTLS_ECP_DP_NONE;
+#endif
+}
+
+static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
+                                      size_t *olen, int point_format,
+                                      unsigned char *buf, size_t blen,
+                                      int (*f_rng)(void *,
+                                                   unsigned char *,
+                                                   size_t),
+                                      void *p_rng,
+                                      int restart_enabled )
+{
+    int ret;
+    size_t grp_len, pt_len;
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    mbedtls_ecp_restart_ctx *rs_ctx = NULL;
+#endif
+
+    if( ctx->grp.pbits == 0 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( restart_enabled )
+        rs_ctx = &ctx->rs;
+#else
+    (void) restart_enabled;
+#endif
+
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
+                                             f_rng, p_rng, rs_ctx ) ) != 0 )
+        return( ret );
+#else
+    if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
+                                         f_rng, p_rng ) ) != 0 )
+        return( ret );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+    if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf,
+                                             blen ) ) != 0 )
+        return( ret );
+
+    buf += grp_len;
+    blen -= grp_len;
+
+    if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format,
+                                             &pt_len, buf, blen ) ) != 0 )
+        return( ret );
+
+    *olen = grp_len + pt_len;
+    return( 0 );
+}
+
+/*
+ * Setup and write the ServerKeyExhange parameters (RFC 4492)
+ *      struct {
+ *          ECParameters    curve_params;
+ *          ECPoint         public;
+ *      } ServerECDHParams;
+ */
+int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
+                              unsigned char *buf, size_t blen,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng )
+{
+    int restart_enabled = 0;
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( olen != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+    ECDH_VALIDATE_RET( f_rng != NULL );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    restart_enabled = ctx->restart_enabled;
+#else
+    (void) restart_enabled;
+#endif
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_make_params_internal( ctx, olen, ctx->point_format, buf, blen,
+                                       f_rng, p_rng, restart_enabled ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen,
+                                               ctx->point_format, buf, blen,
+                                               f_rng, p_rng,
+                                               restart_enabled ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
+}
+
+static int ecdh_read_params_internal( mbedtls_ecdh_context_mbed *ctx,
+                                      const unsigned char **buf,
+                                      const unsigned char *end )
+{
+    return( mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf,
+                                        end - *buf ) );
+}
+
+/*
+ * Read the ServerKeyExhange parameters (RFC 4492)
+ *      struct {
+ *          ECParameters    curve_params;
+ *          ECPoint         public;
+ *      } ServerECDHParams;
+ */
+int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
+                              const unsigned char **buf,
+                              const unsigned char *end )
+{
+    int ret;
+    mbedtls_ecp_group_id grp_id;
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+    ECDH_VALIDATE_RET( *buf != NULL );
+    ECDH_VALIDATE_RET( end != NULL );
+
+    if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, end - *buf ) )
+            != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_ecdh_setup( ctx, grp_id ) ) != 0 )
+        return( ret );
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_read_params_internal( ctx, buf, end ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh,
+                                               buf, end ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
+}
+
+static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx,
+                                     const mbedtls_ecp_keypair *key,
+                                     mbedtls_ecdh_side side )
+{
+    int ret;
+
+    /* If it's not our key, just import the public part as Qp */
+    if( side == MBEDTLS_ECDH_THEIRS )
+        return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) );
+
+    /* Our key: import public (as Q) and private parts */
+    if( side != MBEDTLS_ECDH_OURS )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ||
+        ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+/*
+ * Get parameters from a keypair
+ */
+int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
+                             const mbedtls_ecp_keypair *key,
+                             mbedtls_ecdh_side side )
+{
+    int ret;
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( key != NULL );
+    ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS ||
+                       side == MBEDTLS_ECDH_THEIRS );
+
+    if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 )
+        return( ret );
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_get_params_internal( ctx, key, side ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh,
+                                              key, side ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
+}
+
+static int ecdh_make_public_internal( mbedtls_ecdh_context_mbed *ctx,
+                                      size_t *olen, int point_format,
+                                      unsigned char *buf, size_t blen,
+                                      int (*f_rng)(void *,
+                                                   unsigned char *,
+                                                   size_t),
+                                      void *p_rng,
+                                      int restart_enabled )
+{
+    int ret;
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    mbedtls_ecp_restart_ctx *rs_ctx = NULL;
+#endif
+
+    if( ctx->grp.pbits == 0 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( restart_enabled )
+        rs_ctx = &ctx->rs;
+#else
+    (void) restart_enabled;
+#endif
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( ( ret = ecdh_gen_public_restartable( &ctx->grp, &ctx->d, &ctx->Q,
+                                             f_rng, p_rng, rs_ctx ) ) != 0 )
+        return( ret );
+#else
+    if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q,
+                                         f_rng, p_rng ) ) != 0 )
+        return( ret );
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+    return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, point_format, olen,
+                                        buf, blen );
+}
+
+/*
+ * Setup and export the client public value
+ */
+int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
+                              unsigned char *buf, size_t blen,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng )
+{
+    int restart_enabled = 0;
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( olen != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+    ECDH_VALIDATE_RET( f_rng != NULL );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    restart_enabled = ctx->restart_enabled;
+#endif
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_make_public_internal( ctx, olen, ctx->point_format, buf, blen,
+                                       f_rng, p_rng, restart_enabled ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen,
+                                               ctx->point_format, buf, blen,
+                                               f_rng, p_rng,
+                                               restart_enabled ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
+}
+
+static int ecdh_read_public_internal( mbedtls_ecdh_context_mbed *ctx,
+                                      const unsigned char *buf, size_t blen )
+{
+    int ret;
+    const unsigned char *p = buf;
+
+    if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p,
+                                            blen ) ) != 0 )
+        return( ret );
+
+    if( (size_t)( p - buf ) != blen )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    return( 0 );
+}
+
+/*
+ * Parse and import the client's public value
+ */
+int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
+                              const unsigned char *buf, size_t blen )
+{
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_read_public_internal( ctx, buf, blen ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh,
+                                                       buf, blen ) );
+        default:
+            return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+#endif
+}
+
+static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
+                                      size_t *olen, unsigned char *buf,
+                                      size_t blen,
+                                      int (*f_rng)(void *,
+                                                   unsigned char *,
+                                                   size_t),
+                                      void *p_rng,
+                                      int restart_enabled )
+{
+    int ret;
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    mbedtls_ecp_restart_ctx *rs_ctx = NULL;
+#endif
+
+    if( ctx == NULL || ctx->grp.pbits == 0 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( restart_enabled )
+        rs_ctx = &ctx->rs;
+#else
+    (void) restart_enabled;
+#endif
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( ( ret = ecdh_compute_shared_restartable( &ctx->grp, &ctx->z, &ctx->Qp,
+                                                 &ctx->d, f_rng, p_rng,
+                                                 rs_ctx ) ) != 0 )
+    {
+        return( ret );
+    }
+#else
+    if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp,
+                                             &ctx->d, f_rng, p_rng ) ) != 0 )
+    {
+        return( ret );
+    }
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+    if( mbedtls_mpi_size( &ctx->z ) > blen )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
+    return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
+}
+
+/*
+ * Derive and export the shared secret
+ */
+int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
+                              unsigned char *buf, size_t blen,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng )
+{
+    int restart_enabled = 0;
+    ECDH_VALIDATE_RET( ctx != NULL );
+    ECDH_VALIDATE_RET( olen != NULL );
+    ECDH_VALIDATE_RET( buf != NULL );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    restart_enabled = ctx->restart_enabled;
+#endif
+
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    return( ecdh_calc_secret_internal( ctx, olen, buf, blen, f_rng, p_rng,
+                                       restart_enabled ) );
+#else
+    switch( ctx->var )
+    {
+        case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
+            return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf,
+                                               blen, f_rng, p_rng,
+                                               restart_enabled ) );
+        default:
+            return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+#endif
+}
+
+#endif /* MBEDTLS_ECDH_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecdsa.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecdsa.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecdsa.c	(revision 398)
@@ -0,0 +1,899 @@
+/*
+ *  Elliptic curve DSA
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * References:
+ *
+ * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ECDSA_C)
+
+#include "mbedtls/ecdsa.h"
+#include "mbedtls/asn1write.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+#include "mbedtls/hmac_drbg.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#include "mbedtls/platform_util.h"
+
+/* Parameter validation macros based on platform_util.h */
+#define ECDSA_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECDSA_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+
+/*
+ * Sub-context for ecdsa_verify()
+ */
+struct mbedtls_ecdsa_restart_ver
+{
+    mbedtls_mpi u1, u2;     /* intermediate values  */
+    enum {                  /* what to do next?     */
+        ecdsa_ver_init = 0, /* getting started      */
+        ecdsa_ver_muladd,   /* muladd step          */
+    } state;
+};
+
+/*
+ * Init verify restart sub-context
+ */
+static void ecdsa_restart_ver_init( mbedtls_ecdsa_restart_ver_ctx *ctx )
+{
+    mbedtls_mpi_init( &ctx->u1 );
+    mbedtls_mpi_init( &ctx->u2 );
+    ctx->state = ecdsa_ver_init;
+}
+
+/*
+ * Free the components of a verify restart sub-context
+ */
+static void ecdsa_restart_ver_free( mbedtls_ecdsa_restart_ver_ctx *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_mpi_free( &ctx->u1 );
+    mbedtls_mpi_free( &ctx->u2 );
+
+    ecdsa_restart_ver_init( ctx );
+}
+
+/*
+ * Sub-context for ecdsa_sign()
+ */
+struct mbedtls_ecdsa_restart_sig
+{
+    int sign_tries;
+    int key_tries;
+    mbedtls_mpi k;          /* per-signature random */
+    mbedtls_mpi r;          /* r value              */
+    enum {                  /* what to do next?     */
+        ecdsa_sig_init = 0, /* getting started      */
+        ecdsa_sig_mul,      /* doing ecp_mul()      */
+        ecdsa_sig_modn,     /* mod N computations   */
+    } state;
+};
+
+/*
+ * Init verify sign sub-context
+ */
+static void ecdsa_restart_sig_init( mbedtls_ecdsa_restart_sig_ctx *ctx )
+{
+    ctx->sign_tries = 0;
+    ctx->key_tries = 0;
+    mbedtls_mpi_init( &ctx->k );
+    mbedtls_mpi_init( &ctx->r );
+    ctx->state = ecdsa_sig_init;
+}
+
+/*
+ * Free the components of a sign restart sub-context
+ */
+static void ecdsa_restart_sig_free( mbedtls_ecdsa_restart_sig_ctx *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_mpi_free( &ctx->k );
+    mbedtls_mpi_free( &ctx->r );
+}
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+/*
+ * Sub-context for ecdsa_sign_det()
+ */
+struct mbedtls_ecdsa_restart_det
+{
+    mbedtls_hmac_drbg_context rng_ctx;  /* DRBG state   */
+    enum {                      /* what to do next?     */
+        ecdsa_det_init = 0,     /* getting started      */
+        ecdsa_det_sign,         /* make signature       */
+    } state;
+};
+
+/*
+ * Init verify sign_det sub-context
+ */
+static void ecdsa_restart_det_init( mbedtls_ecdsa_restart_det_ctx *ctx )
+{
+    mbedtls_hmac_drbg_init( &ctx->rng_ctx );
+    ctx->state = ecdsa_det_init;
+}
+
+/*
+ * Free the components of a sign_det restart sub-context
+ */
+static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_hmac_drbg_free( &ctx->rng_ctx );
+
+    ecdsa_restart_det_init( ctx );
+}
+#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
+
+#define ECDSA_RS_ECP    &rs_ctx->ecp
+
+/* Utility macro for checking and updating ops budget */
+#define ECDSA_BUDGET( ops )   \
+    MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, &rs_ctx->ecp, ops ) );
+
+/* Call this when entering a function that needs its own sub-context */
+#define ECDSA_RS_ENTER( SUB )   do {                                 \
+    /* reset ops count for this call if top-level */                 \
+    if( rs_ctx != NULL && rs_ctx->ecp.depth++ == 0 )                 \
+        rs_ctx->ecp.ops_done = 0;                                    \
+                                                                     \
+    /* set up our own sub-context if needed */                       \
+    if( mbedtls_ecp_restart_is_enabled() &&                          \
+        rs_ctx != NULL && rs_ctx->SUB == NULL )                      \
+    {                                                                \
+        rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) );   \
+        if( rs_ctx->SUB == NULL )                                    \
+            return( MBEDTLS_ERR_ECP_ALLOC_FAILED );                  \
+                                                                     \
+        ecdsa_restart_## SUB ##_init( rs_ctx->SUB );                 \
+    }                                                                \
+} while( 0 )
+
+/* Call this when leaving a function that needs its own sub-context */
+#define ECDSA_RS_LEAVE( SUB )   do {                                 \
+    /* clear our sub-context when not in progress (done or error) */ \
+    if( rs_ctx != NULL && rs_ctx->SUB != NULL &&                     \
+        ret != MBEDTLS_ERR_ECP_IN_PROGRESS )                         \
+    {                                                                \
+        ecdsa_restart_## SUB ##_free( rs_ctx->SUB );                 \
+        mbedtls_free( rs_ctx->SUB );                                 \
+        rs_ctx->SUB = NULL;                                          \
+    }                                                                \
+                                                                     \
+    if( rs_ctx != NULL )                                             \
+        rs_ctx->ecp.depth--;                                         \
+} while( 0 )
+
+#else /* MBEDTLS_ECP_RESTARTABLE */
+
+#define ECDSA_RS_ECP    NULL
+
+#define ECDSA_BUDGET( ops )   /* no-op; for compatibility */
+
+#define ECDSA_RS_ENTER( SUB )   (void) rs_ctx
+#define ECDSA_RS_LEAVE( SUB )   (void) rs_ctx
+
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+/*
+ * Derive a suitable integer for group grp from a buffer of length len
+ * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
+ */
+static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
+                       const unsigned char *buf, size_t blen )
+{
+    int ret;
+    size_t n_size = ( grp->nbits + 7 ) / 8;
+    size_t use_size = blen > n_size ? n_size : blen;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) );
+    if( use_size * 8 > grp->nbits )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) );
+
+    /* While at it, reduce modulo N */
+    if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) );
+
+cleanup:
+    return( ret );
+}
+
+#if !defined(MBEDTLS_ECDSA_SIGN_ALT)
+/*
+ * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
+ * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
+ */
+static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
+                mbedtls_mpi *r, mbedtls_mpi *s,
+                const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                mbedtls_ecdsa_restart_ctx *rs_ctx )
+{
+    int ret, key_tries, sign_tries;
+    int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries;
+    mbedtls_ecp_point R;
+    mbedtls_mpi k, e, t;
+    mbedtls_mpi *pk = &k, *pr = r;
+
+    /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
+    if( grp->N.p == NULL )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    /* Make sure d is in range 1..n-1 */
+    if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
+        return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
+    mbedtls_ecp_point_init( &R );
+    mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t );
+
+    ECDSA_RS_ENTER( sig );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->sig != NULL )
+    {
+        /* redirect to our context */
+        p_sign_tries = &rs_ctx->sig->sign_tries;
+        p_key_tries = &rs_ctx->sig->key_tries;
+        pk = &rs_ctx->sig->k;
+        pr = &rs_ctx->sig->r;
+
+        /* jump to current step */
+        if( rs_ctx->sig->state == ecdsa_sig_mul )
+            goto mul;
+        if( rs_ctx->sig->state == ecdsa_sig_modn )
+            goto modn;
+    }
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+    *p_sign_tries = 0;
+    do
+    {
+        if( *p_sign_tries++ > 10 )
+        {
+            ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
+            goto cleanup;
+        }
+
+        /*
+         * Steps 1-3: generate a suitable ephemeral keypair
+         * and set r = xR mod n
+         */
+        *p_key_tries = 0;
+        do
+        {
+            if( *p_key_tries++ > 10 )
+            {
+                ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
+                goto cleanup;
+            }
+
+            MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, pk, f_rng, p_rng ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+            if( rs_ctx != NULL && rs_ctx->sig != NULL )
+                rs_ctx->sig->state = ecdsa_sig_mul;
+
+mul:
+#endif
+            MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, &R, pk, &grp->G,
+                                                  f_rng, p_rng, ECDSA_RS_ECP ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pr, &R.X, &grp->N ) );
+        }
+        while( mbedtls_mpi_cmp_int( pr, 0 ) == 0 );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+        if( rs_ctx != NULL && rs_ctx->sig != NULL )
+            rs_ctx->sig->state = ecdsa_sig_modn;
+
+modn:
+#endif
+        /*
+         * Accounting for everything up to the end of the loop
+         * (step 6, but checking now avoids saving e and t)
+         */
+        ECDSA_BUDGET( MBEDTLS_ECP_OPS_INV + 4 );
+
+        /*
+         * Step 5: derive MPI from hashed message
+         */
+        MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
+
+        /*
+         * Generate a random value to blind inv_mod in next step,
+         * avoiding a potential timing leak.
+         */
+        MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, &t, f_rng, p_rng ) );
+
+        /*
+         * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n
+         */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, pr, d ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pk, pk, &t ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, pk, &grp->N ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) );
+    }
+    while( mbedtls_mpi_cmp_int( s, 0 ) == 0 );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->sig != NULL )
+        mbedtls_mpi_copy( r, pr );
+#endif
+
+cleanup:
+    mbedtls_ecp_point_free( &R );
+    mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t );
+
+    ECDSA_RS_LEAVE( sig );
+
+    return( ret );
+}
+
+/*
+ * Compute ECDSA signature of a hashed message
+ */
+int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
+                const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    ECDSA_VALIDATE_RET( grp   != NULL );
+    ECDSA_VALIDATE_RET( r     != NULL );
+    ECDSA_VALIDATE_RET( s     != NULL );
+    ECDSA_VALIDATE_RET( d     != NULL );
+    ECDSA_VALIDATE_RET( f_rng != NULL );
+    ECDSA_VALIDATE_RET( buf   != NULL || blen == 0 );
+
+    return( ecdsa_sign_restartable( grp, r, s, d, buf, blen,
+                                    f_rng, p_rng, NULL ) );
+}
+#endif /* !MBEDTLS_ECDSA_SIGN_ALT */
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+/*
+ * Deterministic signature wrapper
+ */
+static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
+                    mbedtls_mpi *r, mbedtls_mpi *s,
+                    const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
+                    mbedtls_md_type_t md_alg,
+                    mbedtls_ecdsa_restart_ctx *rs_ctx )
+{
+    int ret;
+    mbedtls_hmac_drbg_context rng_ctx;
+    mbedtls_hmac_drbg_context *p_rng = &rng_ctx;
+    unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
+    size_t grp_len = ( grp->nbits + 7 ) / 8;
+    const mbedtls_md_info_t *md_info;
+    mbedtls_mpi h;
+
+    if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    mbedtls_mpi_init( &h );
+    mbedtls_hmac_drbg_init( &rng_ctx );
+
+    ECDSA_RS_ENTER( det );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->det != NULL )
+    {
+        /* redirect to our context */
+        p_rng = &rs_ctx->det->rng_ctx;
+
+        /* jump to current step */
+        if( rs_ctx->det->state == ecdsa_det_sign )
+            goto sign;
+    }
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+    /* Use private key and message hash (reduced) to initialize HMAC_DRBG */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) );
+    MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) );
+    mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->det != NULL )
+        rs_ctx->det->state = ecdsa_det_sign;
+
+sign:
+#endif
+#if defined(MBEDTLS_ECDSA_SIGN_ALT)
+    ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
+                              mbedtls_hmac_drbg_random, p_rng );
+#else
+    ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen,
+                      mbedtls_hmac_drbg_random, p_rng, rs_ctx );
+#endif /* MBEDTLS_ECDSA_SIGN_ALT */
+
+cleanup:
+    mbedtls_hmac_drbg_free( &rng_ctx );
+    mbedtls_mpi_free( &h );
+
+    ECDSA_RS_LEAVE( det );
+
+    return( ret );
+}
+
+/*
+ * Deterministic signature wrapper
+ */
+int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
+                    const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
+                    mbedtls_md_type_t md_alg )
+{
+    ECDSA_VALIDATE_RET( grp   != NULL );
+    ECDSA_VALIDATE_RET( r     != NULL );
+    ECDSA_VALIDATE_RET( s     != NULL );
+    ECDSA_VALIDATE_RET( d     != NULL );
+    ECDSA_VALIDATE_RET( buf   != NULL || blen == 0 );
+
+    return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, NULL ) );
+}
+#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
+
+#if !defined(MBEDTLS_ECDSA_VERIFY_ALT)
+/*
+ * Verify ECDSA signature of hashed message (SEC1 4.1.4)
+ * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
+ */
+static int ecdsa_verify_restartable( mbedtls_ecp_group *grp,
+                                     const unsigned char *buf, size_t blen,
+                                     const mbedtls_ecp_point *Q,
+                                     const mbedtls_mpi *r, const mbedtls_mpi *s,
+                                     mbedtls_ecdsa_restart_ctx *rs_ctx )
+{
+    int ret;
+    mbedtls_mpi e, s_inv, u1, u2;
+    mbedtls_ecp_point R;
+    mbedtls_mpi *pu1 = &u1, *pu2 = &u2;
+
+    mbedtls_ecp_point_init( &R );
+    mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv );
+    mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
+
+    /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
+    if( grp->N.p == NULL )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    ECDSA_RS_ENTER( ver );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->ver != NULL )
+    {
+        /* redirect to our context */
+        pu1 = &rs_ctx->ver->u1;
+        pu2 = &rs_ctx->ver->u2;
+
+        /* jump to current step */
+        if( rs_ctx->ver->state == ecdsa_ver_muladd )
+            goto muladd;
+    }
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+    /*
+     * Step 1: make sure r and s are in range 1..n-1
+     */
+    if( mbedtls_mpi_cmp_int( r, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r, &grp->N ) >= 0 ||
+        mbedtls_mpi_cmp_int( s, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s, &grp->N ) >= 0 )
+    {
+        ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
+        goto cleanup;
+    }
+
+    /*
+     * Step 3: derive MPI from hashed message
+     */
+    MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) );
+
+    /*
+     * Step 4: u1 = e / s mod n, u2 = r / s mod n
+     */
+    ECDSA_BUDGET( MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2 );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu1, &e, &s_inv ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu1, pu1, &grp->N ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu2, r, &s_inv ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu2, pu2, &grp->N ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->ver != NULL )
+        rs_ctx->ver->state = ecdsa_ver_muladd;
+
+muladd:
+#endif
+    /*
+     * Step 5: R = u1 G + u2 Q
+     */
+    MBEDTLS_MPI_CHK( mbedtls_ecp_muladd_restartable( grp,
+                     &R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP ) );
+
+    if( mbedtls_ecp_is_zero( &R ) )
+    {
+        ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
+        goto cleanup;
+    }
+
+    /*
+     * Step 6: convert xR to an integer (no-op)
+     * Step 7: reduce xR mod n (gives v)
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R.X, &R.X, &grp->N ) );
+
+    /*
+     * Step 8: check if v (that is, R.X) is equal to r
+     */
+    if( mbedtls_mpi_cmp_mpi( &R.X, r ) != 0 )
+    {
+        ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
+        goto cleanup;
+    }
+
+cleanup:
+    mbedtls_ecp_point_free( &R );
+    mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv );
+    mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 );
+
+    ECDSA_RS_LEAVE( ver );
+
+    return( ret );
+}
+
+/*
+ * Verify ECDSA signature of hashed message
+ */
+int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
+                          const unsigned char *buf, size_t blen,
+                          const mbedtls_ecp_point *Q,
+                          const mbedtls_mpi *r,
+                          const mbedtls_mpi *s)
+{
+    ECDSA_VALIDATE_RET( grp != NULL );
+    ECDSA_VALIDATE_RET( Q   != NULL );
+    ECDSA_VALIDATE_RET( r   != NULL );
+    ECDSA_VALIDATE_RET( s   != NULL );
+    ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
+
+    return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) );
+}
+#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
+
+/*
+ * Convert a signature (given by context) to ASN.1
+ */
+static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
+                                    unsigned char *sig, size_t *slen )
+{
+    int ret;
+    unsigned char buf[MBEDTLS_ECDSA_MAX_LEN];
+    unsigned char *p = buf + sizeof( buf );
+    size_t len = 0;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf,
+                                       MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
+
+    memcpy( sig, p, len );
+    *slen = len;
+
+    return( 0 );
+}
+
+/*
+ * Compute and write signature
+ */
+int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
+                           mbedtls_md_type_t md_alg,
+                           const unsigned char *hash, size_t hlen,
+                           unsigned char *sig, size_t *slen,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng,
+                           mbedtls_ecdsa_restart_ctx *rs_ctx )
+{
+    int ret;
+    mbedtls_mpi r, s;
+    ECDSA_VALIDATE_RET( ctx  != NULL );
+    ECDSA_VALIDATE_RET( hash != NULL );
+    ECDSA_VALIDATE_RET( sig  != NULL );
+    ECDSA_VALIDATE_RET( slen != NULL );
+
+    mbedtls_mpi_init( &r );
+    mbedtls_mpi_init( &s );
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+    (void) f_rng;
+    (void) p_rng;
+
+    MBEDTLS_MPI_CHK( ecdsa_sign_det_restartable( &ctx->grp, &r, &s, &ctx->d,
+                             hash, hlen, md_alg, rs_ctx ) );
+#else
+    (void) md_alg;
+
+#if defined(MBEDTLS_ECDSA_SIGN_ALT)
+    MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d,
+                         hash, hlen, f_rng, p_rng ) );
+#else
+    MBEDTLS_MPI_CHK( ecdsa_sign_restartable( &ctx->grp, &r, &s, &ctx->d,
+                         hash, hlen, f_rng, p_rng, rs_ctx ) );
+#endif /* MBEDTLS_ECDSA_SIGN_ALT */
+#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
+
+    MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) );
+
+cleanup:
+    mbedtls_mpi_free( &r );
+    mbedtls_mpi_free( &s );
+
+    return( ret );
+}
+
+/*
+ * Compute and write signature
+ */
+int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
+                                 mbedtls_md_type_t md_alg,
+                                 const unsigned char *hash, size_t hlen,
+                                 unsigned char *sig, size_t *slen,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng )
+{
+    ECDSA_VALIDATE_RET( ctx  != NULL );
+    ECDSA_VALIDATE_RET( hash != NULL );
+    ECDSA_VALIDATE_RET( sig  != NULL );
+    ECDSA_VALIDATE_RET( slen != NULL );
+    return( mbedtls_ecdsa_write_signature_restartable(
+                ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED) && \
+    defined(MBEDTLS_ECDSA_DETERMINISTIC)
+int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
+                               const unsigned char *hash, size_t hlen,
+                               unsigned char *sig, size_t *slen,
+                               mbedtls_md_type_t md_alg )
+{
+    ECDSA_VALIDATE_RET( ctx  != NULL );
+    ECDSA_VALIDATE_RET( hash != NULL );
+    ECDSA_VALIDATE_RET( sig  != NULL );
+    ECDSA_VALIDATE_RET( slen != NULL );
+    return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen,
+                                   NULL, NULL ) );
+}
+#endif
+
+/*
+ * Read and check signature
+ */
+int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
+                          const unsigned char *hash, size_t hlen,
+                          const unsigned char *sig, size_t slen )
+{
+    ECDSA_VALIDATE_RET( ctx  != NULL );
+    ECDSA_VALIDATE_RET( hash != NULL );
+    ECDSA_VALIDATE_RET( sig  != NULL );
+    return( mbedtls_ecdsa_read_signature_restartable(
+                ctx, hash, hlen, sig, slen, NULL ) );
+}
+
+/*
+ * Restartable read and check signature
+ */
+int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
+                          const unsigned char *hash, size_t hlen,
+                          const unsigned char *sig, size_t slen,
+                          mbedtls_ecdsa_restart_ctx *rs_ctx )
+{
+    int ret;
+    unsigned char *p = (unsigned char *) sig;
+    const unsigned char *end = sig + slen;
+    size_t len;
+    mbedtls_mpi r, s;
+    ECDSA_VALIDATE_RET( ctx  != NULL );
+    ECDSA_VALIDATE_RET( hash != NULL );
+    ECDSA_VALIDATE_RET( sig  != NULL );
+
+    mbedtls_mpi_init( &r );
+    mbedtls_mpi_init( &s );
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    if( p + len != end )
+    {
+        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA +
+              MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+        goto cleanup;
+    }
+
+    if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 ||
+        ( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 )
+    {
+        ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+#if defined(MBEDTLS_ECDSA_VERIFY_ALT)
+    if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen,
+                                      &ctx->Q, &r, &s ) ) != 0 )
+        goto cleanup;
+#else
+    if( ( ret = ecdsa_verify_restartable( &ctx->grp, hash, hlen,
+                              &ctx->Q, &r, &s, rs_ctx ) ) != 0 )
+        goto cleanup;
+#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
+
+    /* At this point we know that the buffer starts with a valid signature.
+     * Return 0 if the buffer just contains the signature, and a specific
+     * error code if the valid signature is followed by more data. */
+    if( p != end )
+        ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH;
+
+cleanup:
+    mbedtls_mpi_free( &r );
+    mbedtls_mpi_free( &s );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_ECDSA_GENKEY_ALT)
+/*
+ * Generate key pair
+ */
+int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
+                  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret = 0;
+    ECDSA_VALIDATE_RET( ctx   != NULL );
+    ECDSA_VALIDATE_RET( f_rng != NULL );
+
+    ret = mbedtls_ecp_group_load( &ctx->grp, gid );
+    if( ret != 0 )
+        return( ret );
+
+   return( mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d,
+                                    &ctx->Q, f_rng, p_rng ) );
+}
+#endif /* !MBEDTLS_ECDSA_GENKEY_ALT */
+
+/*
+ * Set context from an mbedtls_ecp_keypair
+ */
+int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key )
+{
+    int ret;
+    ECDSA_VALIDATE_RET( ctx != NULL );
+    ECDSA_VALIDATE_RET( key != NULL );
+
+    if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ||
+        ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ||
+        ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 )
+    {
+        mbedtls_ecdsa_free( ctx );
+    }
+
+    return( ret );
+}
+
+/*
+ * Initialize context
+ */
+void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx )
+{
+    ECDSA_VALIDATE( ctx != NULL );
+
+    mbedtls_ecp_keypair_init( ctx );
+}
+
+/*
+ * Free context
+ */
+void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_ecp_keypair_free( ctx );
+}
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/*
+ * Initialize a restart context
+ */
+void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx )
+{
+    ECDSA_VALIDATE( ctx != NULL );
+
+    mbedtls_ecp_restart_init( &ctx->ecp );
+
+    ctx->ver = NULL;
+    ctx->sig = NULL;
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+    ctx->det = NULL;
+#endif
+}
+
+/*
+ * Free the components of a restart context
+ */
+void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_ecp_restart_free( &ctx->ecp );
+
+    ecdsa_restart_ver_free( ctx->ver );
+    mbedtls_free( ctx->ver );
+    ctx->ver = NULL;
+
+    ecdsa_restart_sig_free( ctx->sig );
+    mbedtls_free( ctx->sig );
+    ctx->sig = NULL;
+
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+    ecdsa_restart_det_free( ctx->det );
+    mbedtls_free( ctx->det );
+    ctx->det = NULL;
+#endif
+}
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+#endif /* MBEDTLS_ECDSA_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecjpake.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecjpake.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecjpake.c	(revision 398)
@@ -0,0 +1,1140 @@
+/*
+ *  Elliptic curve J-PAKE
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * References in the code are to the Thread v1.0 Specification,
+ * available to members of the Thread Group http://threadgroup.org/
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ECJPAKE_C)
+
+#include "mbedtls/ecjpake.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if !defined(MBEDTLS_ECJPAKE_ALT)
+
+/* Parameter validation macros based on platform_util.h */
+#define ECJPAKE_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECJPAKE_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * Convert a mbedtls_ecjpake_role to identifier string
+ */
+static const char * const ecjpake_id[] = {
+    "client",
+    "server"
+};
+
+#define ID_MINE     ( ecjpake_id[ ctx->role ] )
+#define ID_PEER     ( ecjpake_id[ 1 - ctx->role ] )
+
+/*
+ * Initialize context
+ */
+void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx )
+{
+    ECJPAKE_VALIDATE( ctx != NULL );
+
+    ctx->md_info = NULL;
+    mbedtls_ecp_group_init( &ctx->grp );
+    ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
+
+    mbedtls_ecp_point_init( &ctx->Xm1 );
+    mbedtls_ecp_point_init( &ctx->Xm2 );
+    mbedtls_ecp_point_init( &ctx->Xp1 );
+    mbedtls_ecp_point_init( &ctx->Xp2 );
+    mbedtls_ecp_point_init( &ctx->Xp  );
+
+    mbedtls_mpi_init( &ctx->xm1 );
+    mbedtls_mpi_init( &ctx->xm2 );
+    mbedtls_mpi_init( &ctx->s   );
+}
+
+/*
+ * Free context
+ */
+void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    ctx->md_info = NULL;
+    mbedtls_ecp_group_free( &ctx->grp );
+
+    mbedtls_ecp_point_free( &ctx->Xm1 );
+    mbedtls_ecp_point_free( &ctx->Xm2 );
+    mbedtls_ecp_point_free( &ctx->Xp1 );
+    mbedtls_ecp_point_free( &ctx->Xp2 );
+    mbedtls_ecp_point_free( &ctx->Xp  );
+
+    mbedtls_mpi_free( &ctx->xm1 );
+    mbedtls_mpi_free( &ctx->xm2 );
+    mbedtls_mpi_free( &ctx->s   );
+}
+
+/*
+ * Setup context
+ */
+int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
+                           mbedtls_ecjpake_role role,
+                           mbedtls_md_type_t hash,
+                           mbedtls_ecp_group_id curve,
+                           const unsigned char *secret,
+                           size_t len )
+{
+    int ret;
+
+    ECJPAKE_VALIDATE_RET( ctx != NULL );
+    ECJPAKE_VALIDATE_RET( role == MBEDTLS_ECJPAKE_CLIENT ||
+                          role == MBEDTLS_ECJPAKE_SERVER );
+    ECJPAKE_VALIDATE_RET( secret != NULL || len == 0 );
+
+    ctx->role = role;
+
+    if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL )
+        return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
+
+    MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) );
+
+cleanup:
+    if( ret != 0 )
+        mbedtls_ecjpake_free( ctx );
+
+    return( ret );
+}
+
+/*
+ * Check if context is ready for use
+ */
+int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx )
+{
+    ECJPAKE_VALIDATE_RET( ctx != NULL );
+
+    if( ctx->md_info == NULL ||
+        ctx->grp.id == MBEDTLS_ECP_DP_NONE ||
+        ctx->s.p == NULL )
+    {
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Write a point plus its length to a buffer
+ */
+static int ecjpake_write_len_point( unsigned char **p,
+                                    const unsigned char *end,
+                                    const mbedtls_ecp_group *grp,
+                                    const int pf,
+                                    const mbedtls_ecp_point *P )
+{
+    int ret;
+    size_t len;
+
+    /* Need at least 4 for length plus 1 for point */
+    if( end < *p || end - *p < 5 )
+        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+    ret = mbedtls_ecp_point_write_binary( grp, P, pf,
+                                          &len, *p + 4, end - ( *p + 4 ) );
+    if( ret != 0 )
+        return( ret );
+
+    (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
+    (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
+    (*p)[2] = (unsigned char)( ( len >>  8 ) & 0xFF );
+    (*p)[3] = (unsigned char)( ( len       ) & 0xFF );
+
+    *p += 4 + len;
+
+    return( 0 );
+}
+
+/*
+ * Size of the temporary buffer for ecjpake_hash:
+ * 3 EC points plus their length, plus ID and its length (4 + 6 bytes)
+ */
+#define ECJPAKE_HASH_BUF_LEN    ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 )
+
+/*
+ * Compute hash for ZKP (7.4.2.2.2.1)
+ */
+static int ecjpake_hash( const mbedtls_md_info_t *md_info,
+                         const mbedtls_ecp_group *grp,
+                         const int pf,
+                         const mbedtls_ecp_point *G,
+                         const mbedtls_ecp_point *V,
+                         const mbedtls_ecp_point *X,
+                         const char *id,
+                         mbedtls_mpi *h )
+{
+    int ret;
+    unsigned char buf[ECJPAKE_HASH_BUF_LEN];
+    unsigned char *p = buf;
+    const unsigned char *end = buf + sizeof( buf );
+    const size_t id_len = strlen( id );
+    unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+
+    /* Write things to temporary buffer */
+    MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) );
+    MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) );
+    MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) );
+
+    if( end - p < 4 )
+        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+    *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
+    *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
+    *p++ = (unsigned char)( ( id_len >>  8 ) & 0xFF );
+    *p++ = (unsigned char)( ( id_len       ) & 0xFF );
+
+    if( end < p || (size_t)( end - p ) < id_len )
+        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+    memcpy( p, id, id_len );
+    p += id_len;
+
+    /* Compute hash */
+    mbedtls_md( md_info, buf, p - buf, hash );
+
+    /* Turn it into an integer mod n */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
+                                        mbedtls_md_get_size( md_info ) ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
+ */
+static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
+                             const mbedtls_ecp_group *grp,
+                             const int pf,
+                             const mbedtls_ecp_point *G,
+                             const mbedtls_ecp_point *X,
+                             const char *id,
+                             const unsigned char **p,
+                             const unsigned char *end )
+{
+    int ret;
+    mbedtls_ecp_point V, VV;
+    mbedtls_mpi r, h;
+    size_t r_len;
+
+    mbedtls_ecp_point_init( &V );
+    mbedtls_ecp_point_init( &VV );
+    mbedtls_mpi_init( &r );
+    mbedtls_mpi_init( &h );
+
+    /*
+     * struct {
+     *     ECPoint V;
+     *     opaque r<1..2^8-1>;
+     * } ECSchnorrZKP;
+     */
+    if( end < *p )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) );
+
+    if( end < *p || (size_t)( end - *p ) < 1 )
+    {
+        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    r_len = *(*p)++;
+
+    if( end < *p || (size_t)( end - *p ) < r_len )
+    {
+        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) );
+    *p += r_len;
+
+    /*
+     * Verification
+     */
+    MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp,
+                     &VV, &h, X, &r, G ) );
+
+    if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 )
+    {
+        ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
+        goto cleanup;
+    }
+
+cleanup:
+    mbedtls_ecp_point_free( &V );
+    mbedtls_ecp_point_free( &VV );
+    mbedtls_mpi_free( &r );
+    mbedtls_mpi_free( &h );
+
+    return( ret );
+}
+
+/*
+ * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
+ */
+static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
+                              const mbedtls_ecp_group *grp,
+                              const int pf,
+                              const mbedtls_ecp_point *G,
+                              const mbedtls_mpi *x,
+                              const mbedtls_ecp_point *X,
+                              const char *id,
+                              unsigned char **p,
+                              const unsigned char *end,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng )
+{
+    int ret;
+    mbedtls_ecp_point V;
+    mbedtls_mpi v;
+    mbedtls_mpi h; /* later recycled to hold r */
+    size_t len;
+
+    if( end < *p )
+        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+    mbedtls_ecp_point_init( &V );
+    mbedtls_mpi_init( &v );
+    mbedtls_mpi_init( &h );
+
+    /* Compute signature */
+    MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp,
+                                                   G, &v, &V, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */
+
+    /* Write it out */
+    MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V,
+                pf, &len, *p, end - *p ) );
+    *p += len;
+
+    len = mbedtls_mpi_size( &h ); /* actually r */
+    if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 )
+    {
+        ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
+        goto cleanup;
+    }
+
+    *(*p)++ = (unsigned char)( len & 0xFF );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
+    *p += len;
+
+cleanup:
+    mbedtls_ecp_point_free( &V );
+    mbedtls_mpi_free( &v );
+    mbedtls_mpi_free( &h );
+
+    return( ret );
+}
+
+/*
+ * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
+ * Output: verified public key X
+ */
+static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
+                             const mbedtls_ecp_group *grp,
+                             const int pf,
+                             const mbedtls_ecp_point *G,
+                             mbedtls_ecp_point *X,
+                             const char *id,
+                             const unsigned char **p,
+                             const unsigned char *end )
+{
+    int ret;
+
+    if( end < *p )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    /*
+     * struct {
+     *     ECPoint X;
+     *     ECSchnorrZKP zkp;
+     * } ECJPAKEKeyKP;
+     */
+    MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) );
+    if( mbedtls_ecp_is_zero( X ) )
+    {
+        ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+        goto cleanup;
+    }
+
+    MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Generate an ECJPAKEKeyKP
+ * Output: the serialized structure, plus private/public key pair
+ */
+static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
+                              const mbedtls_ecp_group *grp,
+                              const int pf,
+                              const mbedtls_ecp_point *G,
+                              mbedtls_mpi *x,
+                              mbedtls_ecp_point *X,
+                              const char *id,
+                              unsigned char **p,
+                              const unsigned char *end,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng )
+{
+    int ret;
+    size_t len;
+
+    if( end < *p )
+        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+    /* Generate key (7.4.2.3.1) and write it out */
+    MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X,
+                                                   f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X,
+                pf, &len, *p, end - *p ) );
+    *p += len;
+
+    /* Generate and write proof */
+    MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id,
+                                        p, end, f_rng, p_rng ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
+ * Ouputs: verified peer public keys Xa, Xb
+ */
+static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
+                              const mbedtls_ecp_group *grp,
+                              const int pf,
+                              const mbedtls_ecp_point *G,
+                              mbedtls_ecp_point *Xa,
+                              mbedtls_ecp_point *Xb,
+                              const char *id,
+                              const unsigned char *buf,
+                              size_t len )
+{
+    int ret;
+    const unsigned char *p = buf;
+    const unsigned char *end = buf + len;
+
+    /*
+     * struct {
+     *     ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
+     * } ECJPAKEKeyKPPairList;
+     */
+    MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) );
+    MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) );
+
+    if( p != end )
+        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Generate a ECJPAKEKeyKPPairList
+ * Outputs: the serialized structure, plus two private/public key pairs
+ */
+static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
+                               const mbedtls_ecp_group *grp,
+                               const int pf,
+                               const mbedtls_ecp_point *G,
+                               mbedtls_mpi *xm1,
+                               mbedtls_ecp_point *Xa,
+                               mbedtls_mpi *xm2,
+                               mbedtls_ecp_point *Xb,
+                               const char *id,
+                               unsigned char *buf,
+                               size_t len,
+                               size_t *olen,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng )
+{
+    int ret;
+    unsigned char *p = buf;
+    const unsigned char *end = buf + len;
+
+    MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id,
+                &p, end, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id,
+                &p, end, f_rng, p_rng ) );
+
+    *olen = p - buf;
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Read and process the first round message
+ */
+int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
+                                    const unsigned char *buf,
+                                    size_t len )
+{
+    ECJPAKE_VALIDATE_RET( ctx != NULL );
+    ECJPAKE_VALIDATE_RET( buf != NULL );
+
+    return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format,
+                               &ctx->grp.G,
+                               &ctx->Xp1, &ctx->Xp2, ID_PEER,
+                               buf, len ) );
+}
+
+/*
+ * Generate and write the first round message
+ */
+int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
+                            unsigned char *buf, size_t len, size_t *olen,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng )
+{
+    ECJPAKE_VALIDATE_RET( ctx   != NULL );
+    ECJPAKE_VALIDATE_RET( buf   != NULL );
+    ECJPAKE_VALIDATE_RET( olen  != NULL );
+    ECJPAKE_VALIDATE_RET( f_rng != NULL );
+
+    return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format,
+                                &ctx->grp.G,
+                                &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2,
+                                ID_MINE, buf, len, olen, f_rng, p_rng ) );
+}
+
+/*
+ * Compute the sum of three points R = A + B + C
+ */
+static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+                             const mbedtls_ecp_point *A,
+                             const mbedtls_ecp_point *B,
+                             const mbedtls_ecp_point *C )
+{
+    int ret;
+    mbedtls_mpi one;
+
+    mbedtls_mpi_init( &one );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) );
+
+cleanup:
+    mbedtls_mpi_free( &one );
+
+    return( ret );
+}
+
+/*
+ * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6)
+ */
+int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
+                                            const unsigned char *buf,
+                                            size_t len )
+{
+    int ret;
+    const unsigned char *p = buf;
+    const unsigned char *end = buf + len;
+    mbedtls_ecp_group grp;
+    mbedtls_ecp_point G;    /* C: GB, S: GA */
+
+    ECJPAKE_VALIDATE_RET( ctx != NULL );
+    ECJPAKE_VALIDATE_RET( buf != NULL );
+
+    mbedtls_ecp_group_init( &grp );
+    mbedtls_ecp_point_init( &G );
+
+    /*
+     * Server: GA = X3  + X4  + X1      (7.4.2.6.1)
+     * Client: GB = X1  + X2  + X3      (7.4.2.5.1)
+     * Unified: G = Xm1 + Xm2 + Xp1
+     * We need that before parsing in order to check Xp as we read it
+     */
+    MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
+                                       &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) );
+
+    /*
+     * struct {
+     *     ECParameters curve_params;   // only client reading server msg
+     *     ECJPAKEKeyKP ecjpake_key_kp;
+     * } Client/ServerECJPAKEParams;
+     */
+    if( ctx->role == MBEDTLS_ECJPAKE_CLIENT )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) );
+        if( grp.id != ctx->grp.id )
+        {
+            ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+            goto cleanup;
+        }
+    }
+
+    MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp,
+                            ctx->point_format,
+                            &G, &ctx->Xp, ID_PEER, &p, end ) );
+
+    if( p != end )
+    {
+        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+cleanup:
+    mbedtls_ecp_group_free( &grp );
+    mbedtls_ecp_point_free( &G );
+
+    return( ret );
+}
+
+/*
+ * Compute R = +/- X * S mod N, taking care not to leak S
+ */
+static int ecjpake_mul_secret( mbedtls_mpi *R, int sign,
+                               const mbedtls_mpi *X,
+                               const mbedtls_mpi *S,
+                               const mbedtls_mpi *N,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng )
+{
+    int ret;
+    mbedtls_mpi b; /* Blinding value, then s + N * blinding */
+
+    mbedtls_mpi_init( &b );
+
+    /* b = s + rnd-128-bit * N */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) );
+
+    /* R = sign * X * b mod N */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) );
+    R->s *= sign;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) );
+
+cleanup:
+    mbedtls_mpi_free( &b );
+
+    return( ret );
+}
+
+/*
+ * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6)
+ */
+int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
+                            unsigned char *buf, size_t len, size_t *olen,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng )
+{
+    int ret;
+    mbedtls_ecp_point G;    /* C: GA, S: GB */
+    mbedtls_ecp_point Xm;   /* C: Xc, S: Xs */
+    mbedtls_mpi xm;         /* C: xc, S: xs */
+    unsigned char *p = buf;
+    const unsigned char *end = buf + len;
+    size_t ec_len;
+
+    ECJPAKE_VALIDATE_RET( ctx   != NULL );
+    ECJPAKE_VALIDATE_RET( buf   != NULL );
+    ECJPAKE_VALIDATE_RET( olen  != NULL );
+    ECJPAKE_VALIDATE_RET( f_rng != NULL );
+
+    mbedtls_ecp_point_init( &G );
+    mbedtls_ecp_point_init( &Xm );
+    mbedtls_mpi_init( &xm );
+
+    /*
+     * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1)
+     *
+     * Client:  GA = X1  + X3  + X4  | xs = x2  * s | Xc = xc * GA
+     * Server:  GB = X3  + X1  + X2  | xs = x4  * s | Xs = xs * GB
+     * Unified: G  = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G
+     */
+    MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
+                                       &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) );
+    MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s,
+                                         &ctx->grp.N, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) );
+
+    /*
+     * Now write things out
+     *
+     * struct {
+     *     ECParameters curve_params;   // only server writing its message
+     *     ECJPAKEKeyKP ecjpake_key_kp;
+     * } Client/ServerECJPAKEParams;
+     */
+    if( ctx->role == MBEDTLS_ECJPAKE_SERVER )
+    {
+        if( end < p )
+        {
+            ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
+            goto cleanup;
+        }
+        MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len,
+                                                      p, end - p ) );
+        p += ec_len;
+    }
+
+    if( end < p )
+    {
+        ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
+        goto cleanup;
+    }
+    MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm,
+                     ctx->point_format, &ec_len, p, end - p ) );
+    p += ec_len;
+
+    MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp,
+                                        ctx->point_format,
+                                        &G, &xm, &Xm, ID_MINE,
+                                        &p, end, f_rng, p_rng ) );
+
+    *olen = p - buf;
+
+cleanup:
+    mbedtls_ecp_point_free( &G );
+    mbedtls_ecp_point_free( &Xm );
+    mbedtls_mpi_free( &xm );
+
+    return( ret );
+}
+
+/*
+ * Derive PMS (7.4.2.7 / 7.4.2.8)
+ */
+int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
+                            unsigned char *buf, size_t len, size_t *olen,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng )
+{
+    int ret;
+    mbedtls_ecp_point K;
+    mbedtls_mpi m_xm2_s, one;
+    unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
+    size_t x_bytes;
+
+    ECJPAKE_VALIDATE_RET( ctx   != NULL );
+    ECJPAKE_VALIDATE_RET( buf   != NULL );
+    ECJPAKE_VALIDATE_RET( olen  != NULL );
+    ECJPAKE_VALIDATE_RET( f_rng != NULL );
+
+    *olen = mbedtls_md_get_size( ctx->md_info );
+    if( len < *olen )
+        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+    mbedtls_ecp_point_init( &K );
+    mbedtls_mpi_init( &m_xm2_s );
+    mbedtls_mpi_init( &one );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
+
+    /*
+     * Client:  K = ( Xs - X4  * x2  * s ) * x2
+     * Server:  K = ( Xc - X2  * x4  * s ) * x4
+     * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2
+     */
+    MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s,
+                                         &ctx->grp.N, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K,
+                                         &one, &ctx->Xp,
+                                         &m_xm2_s, &ctx->Xp2 ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K,
+                                      f_rng, p_rng ) );
+
+    /* PMS = SHA-256( K.X ) */
+    x_bytes = ( ctx->grp.pbits + 7 ) / 8;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) );
+    MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) );
+
+cleanup:
+    mbedtls_ecp_point_free( &K );
+    mbedtls_mpi_free( &m_xm2_s );
+    mbedtls_mpi_free( &one );
+
+    return( ret );
+}
+
+#undef ID_MINE
+#undef ID_PEER
+
+#endif /* ! MBEDTLS_ECJPAKE_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf     printf
+#endif
+
+#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+    !defined(MBEDTLS_SHA256_C)
+int mbedtls_ecjpake_self_test( int verbose )
+{
+    (void) verbose;
+    return( 0 );
+}
+#else
+
+static const unsigned char ecjpake_test_password[] = {
+    0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74,
+    0x65, 0x73, 0x74
+};
+
+static const unsigned char ecjpake_test_x1[] = {
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
+    0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+    0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
+};
+
+static const unsigned char ecjpake_test_x2[] = {
+    0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
+    0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+    0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
+};
+
+static const unsigned char ecjpake_test_x3[] = {
+    0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
+    0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+    0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
+};
+
+static const unsigned char ecjpake_test_x4[] = {
+    0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
+    0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
+    0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
+};
+
+static const unsigned char ecjpake_test_cli_one[] = {
+    0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
+    0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
+    0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
+    0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
+    0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
+    0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
+    0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
+    0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
+    0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
+    0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
+    0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
+    0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
+    0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
+    0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
+    0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
+    0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
+    0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
+    0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
+    0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
+    0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
+    0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
+    0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
+    0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
+    0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
+    0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
+    0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
+    0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
+    0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
+};
+
+static const unsigned char ecjpake_test_srv_one[] = {
+    0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb,
+    0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18,
+    0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47,
+    0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f,
+    0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7,
+    0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d,
+    0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64,
+    0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36,
+    0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2,
+    0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec,
+    0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16,
+    0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96,
+    0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3,
+    0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19,
+    0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f,
+    0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8,
+    0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7,
+    0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea,
+    0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5,
+    0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6,
+    0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31,
+    0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d,
+    0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8,
+    0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee,
+    0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84,
+    0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f,
+    0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80,
+    0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12
+};
+
+static const unsigned char ecjpake_test_srv_two[] = {
+    0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23,
+    0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c,
+    0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f,
+    0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca,
+    0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26,
+    0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55,
+    0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38,
+    0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6,
+    0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9,
+    0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4,
+    0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2,
+    0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8,
+    0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd,
+    0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
+};
+
+static const unsigned char ecjpake_test_cli_two[] = {
+    0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46,
+    0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb,
+    0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72,
+    0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce,
+    0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98,
+    0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31,
+    0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15,
+    0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36,
+    0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8,
+    0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45,
+    0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d,
+    0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58,
+    0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82,
+    0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
+};
+
+static const unsigned char ecjpake_test_pms[] = {
+    0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7,
+    0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9,
+    0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
+};
+
+/* Load my private keys and generate the correponding public keys */
+static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
+                              const unsigned char *xm1, size_t len1,
+                              const unsigned char *xm2, size_t len2 )
+{
+    int ret;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
+                                      &ctx->grp.G, NULL, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
+                                      &ctx->grp.G, NULL, NULL ) );
+
+cleanup:
+    return( ret );
+}
+
+/* For tests we don't need a secure RNG;
+ * use the LGC from Numerical Recipes for simplicity */
+static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
+{
+    static uint32_t x = 42;
+    (void) p;
+
+    while( len > 0 )
+    {
+        size_t use_len = len > 4 ? 4 : len;
+        x = 1664525 * x + 1013904223;
+        memcpy( out, &x, use_len );
+        out += use_len;
+        len -= use_len;
+    }
+
+    return( 0 );
+}
+
+#define TEST_ASSERT( x )    \
+    do {                    \
+        if( x )             \
+            ret = 0;        \
+        else                \
+        {                   \
+            ret = 1;        \
+            goto cleanup;   \
+        }                   \
+    } while( 0 )
+
+/*
+ * Checkup routine
+ */
+int mbedtls_ecjpake_self_test( int verbose )
+{
+    int ret;
+    mbedtls_ecjpake_context cli;
+    mbedtls_ecjpake_context srv;
+    unsigned char buf[512], pms[32];
+    size_t len, pmslen;
+
+    mbedtls_ecjpake_init( &cli );
+    mbedtls_ecjpake_init( &srv );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  ECJPAKE test #0 (setup): " );
+
+    TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT,
+                    MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
+                    ecjpake_test_password,
+            sizeof( ecjpake_test_password ) ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER,
+                    MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
+                    ecjpake_test_password,
+            sizeof( ecjpake_test_password ) ) == 0 );
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  ECJPAKE test #1 (random handshake): " );
+
+    TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli,
+                 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv,
+                 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv,
+                 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
+                 pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli,
+                 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
+                 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
+
+    TEST_ASSERT( len == pmslen );
+    TEST_ASSERT( memcmp( buf, pms, len ) == 0 );
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  ECJPAKE test #2 (reference handshake): " );
+
+    /* Simulate generation of round one */
+    MBEDTLS_MPI_CHK( ecjpake_test_load( &cli,
+                ecjpake_test_x1, sizeof( ecjpake_test_x1 ),
+                ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) );
+
+    MBEDTLS_MPI_CHK( ecjpake_test_load( &srv,
+                ecjpake_test_x3, sizeof( ecjpake_test_x3 ),
+                ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) );
+
+    /* Read round one */
+    TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv,
+                                    ecjpake_test_cli_one,
+                            sizeof( ecjpake_test_cli_one ) ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli,
+                                    ecjpake_test_srv_one,
+                            sizeof( ecjpake_test_srv_one ) ) == 0 );
+
+    /* Skip generation of round two, read round two */
+    TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli,
+                                    ecjpake_test_srv_two,
+                            sizeof( ecjpake_test_srv_two ) ) == 0 );
+
+    TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv,
+                                    ecjpake_test_cli_two,
+                            sizeof( ecjpake_test_cli_two ) ) == 0 );
+
+    /* Server derives PMS */
+    TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
+                 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
+
+    TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
+    TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
+
+    memset( buf, 0, len ); /* Avoid interferences with next step */
+
+    /* Client derives PMS */
+    TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
+                 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
+
+    TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
+    TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+cleanup:
+    mbedtls_ecjpake_free( &cli );
+    mbedtls_ecjpake_free( &srv );
+
+    if( ret != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( ret );
+}
+
+#undef TEST_ASSERT
+
+#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_ECJPAKE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecp.c	(revision 398)
@@ -0,0 +1,2989 @@
+/*
+ *  Elliptic curves over GF(p): generic functions
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * References:
+ *
+ * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
+ * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
+ * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
+ * RFC 4492 for the related TLS structures and constants
+ * RFC 7748 for the Curve448 and Curve25519 curve definitions
+ *
+ * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
+ *
+ * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
+ *     for elliptic curve cryptosystems. In : Cryptographic Hardware and
+ *     Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
+ *     <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
+ *
+ * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
+ *     render ECC resistant against Side Channel Attacks. IACR Cryptology
+ *     ePrint Archive, 2004, vol. 2004, p. 342.
+ *     <http://eprint.iacr.org/2004/342.pdf>
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+/**
+ * \brief Function level alternative implementation.
+ *
+ * The MBEDTLS_ECP_INTERNAL_ALT macro enables alternative implementations to
+ * replace certain functions in this module. The alternative implementations are
+ * typically hardware accelerators and need to activate the hardware before the
+ * computation starts and deactivate it after it finishes. The
+ * mbedtls_internal_ecp_init() and mbedtls_internal_ecp_free() functions serve
+ * this purpose.
+ *
+ * To preserve the correct functionality the following conditions must hold:
+ *
+ * - The alternative implementation must be activated by
+ *   mbedtls_internal_ecp_init() before any of the replaceable functions is
+ *   called.
+ * - mbedtls_internal_ecp_free() must \b only be called when the alternative
+ *   implementation is activated.
+ * - mbedtls_internal_ecp_init() must \b not be called when the alternative
+ *   implementation is activated.
+ * - Public functions must not return while the alternative implementation is
+ *   activated.
+ * - Replaceable functions are guarded by \c MBEDTLS_ECP_XXX_ALT macros and
+ *   before calling them an \code if( mbedtls_internal_ecp_grp_capable( grp ) )
+ *   \endcode ensures that the alternative implementation supports the current
+ *   group.
+ */
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+
+#include "mbedtls/ecp.h"
+#include "mbedtls/threading.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if !defined(MBEDTLS_ECP_ALT)
+
+/* Parameter validation macros based on platform_util.h */
+#define ECP_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECP_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#define mbedtls_printf     printf
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#include "mbedtls/ecp_internal.h"
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+/*
+ * Counts of point addition and doubling, and field multiplications.
+ * Used to test resistance of point multiplication to simple timing attacks.
+ */
+static unsigned long add_count, dbl_count, mul_count;
+#endif
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/*
+ * Maximum number of "basic operations" to be done in a row.
+ *
+ * Default value 0 means that ECC operations will not yield.
+ * Note that regardless of the value of ecp_max_ops, always at
+ * least one step is performed before yielding.
+ *
+ * Setting ecp_max_ops=1 can be suitable for testing purposes
+ * as it will interrupt computation at all possible points.
+ */
+static unsigned ecp_max_ops = 0;
+
+/*
+ * Set ecp_max_ops
+ */
+void mbedtls_ecp_set_max_ops( unsigned max_ops )
+{
+    ecp_max_ops = max_ops;
+}
+
+/*
+ * Check if restart is enabled
+ */
+int mbedtls_ecp_restart_is_enabled( void )
+{
+    return( ecp_max_ops != 0 );
+}
+
+/*
+ * Restart sub-context for ecp_mul_comb()
+ */
+struct mbedtls_ecp_restart_mul
+{
+    mbedtls_ecp_point R;    /* current intermediate result                  */
+    size_t i;               /* current index in various loops, 0 outside    */
+    mbedtls_ecp_point *T;   /* table for precomputed points                 */
+    unsigned char T_size;   /* number of points in table T                  */
+    enum {                  /* what were we doing last time we returned?    */
+        ecp_rsm_init = 0,       /* nothing so far, dummy initial state      */
+        ecp_rsm_pre_dbl,        /* precompute 2^n multiples                 */
+        ecp_rsm_pre_norm_dbl,   /* normalize precomputed 2^n multiples      */
+        ecp_rsm_pre_add,        /* precompute remaining points by adding    */
+        ecp_rsm_pre_norm_add,   /* normalize all precomputed points         */
+        ecp_rsm_comb_core,      /* ecp_mul_comb_core()                      */
+        ecp_rsm_final_norm,     /* do the final normalization               */
+    } state;
+};
+
+/*
+ * Init restart_mul sub-context
+ */
+static void ecp_restart_rsm_init( mbedtls_ecp_restart_mul_ctx *ctx )
+{
+    mbedtls_ecp_point_init( &ctx->R );
+    ctx->i = 0;
+    ctx->T = NULL;
+    ctx->T_size = 0;
+    ctx->state = ecp_rsm_init;
+}
+
+/*
+ * Free the components of a restart_mul sub-context
+ */
+static void ecp_restart_rsm_free( mbedtls_ecp_restart_mul_ctx *ctx )
+{
+    unsigned char i;
+
+    if( ctx == NULL )
+        return;
+
+    mbedtls_ecp_point_free( &ctx->R );
+
+    if( ctx->T != NULL )
+    {
+        for( i = 0; i < ctx->T_size; i++ )
+            mbedtls_ecp_point_free( ctx->T + i );
+        mbedtls_free( ctx->T );
+    }
+
+    ecp_restart_rsm_init( ctx );
+}
+
+/*
+ * Restart context for ecp_muladd()
+ */
+struct mbedtls_ecp_restart_muladd
+{
+    mbedtls_ecp_point mP;       /* mP value                             */
+    mbedtls_ecp_point R;        /* R intermediate result                */
+    enum {                      /* what should we do next?              */
+        ecp_rsma_mul1 = 0,      /* first multiplication                 */
+        ecp_rsma_mul2,          /* second multiplication                */
+        ecp_rsma_add,           /* addition                             */
+        ecp_rsma_norm,          /* normalization                        */
+    } state;
+};
+
+/*
+ * Init restart_muladd sub-context
+ */
+static void ecp_restart_ma_init( mbedtls_ecp_restart_muladd_ctx *ctx )
+{
+    mbedtls_ecp_point_init( &ctx->mP );
+    mbedtls_ecp_point_init( &ctx->R );
+    ctx->state = ecp_rsma_mul1;
+}
+
+/*
+ * Free the components of a restart_muladd sub-context
+ */
+static void ecp_restart_ma_free( mbedtls_ecp_restart_muladd_ctx *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_ecp_point_free( &ctx->mP );
+    mbedtls_ecp_point_free( &ctx->R );
+
+    ecp_restart_ma_init( ctx );
+}
+
+/*
+ * Initialize a restart context
+ */
+void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx )
+{
+    ECP_VALIDATE( ctx != NULL );
+    ctx->ops_done = 0;
+    ctx->depth = 0;
+    ctx->rsm = NULL;
+    ctx->ma = NULL;
+}
+
+/*
+ * Free the components of a restart context
+ */
+void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    ecp_restart_rsm_free( ctx->rsm );
+    mbedtls_free( ctx->rsm );
+
+    ecp_restart_ma_free( ctx->ma );
+    mbedtls_free( ctx->ma );
+
+    mbedtls_ecp_restart_init( ctx );
+}
+
+/*
+ * Check if we can do the next step
+ */
+int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp,
+                              mbedtls_ecp_restart_ctx *rs_ctx,
+                              unsigned ops )
+{
+    ECP_VALIDATE_RET( grp != NULL );
+
+    if( rs_ctx != NULL && ecp_max_ops != 0 )
+    {
+        /* scale depending on curve size: the chosen reference is 256-bit,
+         * and multiplication is quadratic. Round to the closest integer. */
+        if( grp->pbits >= 512 )
+            ops *= 4;
+        else if( grp->pbits >= 384 )
+            ops *= 2;
+
+        /* Avoid infinite loops: always allow first step.
+         * Because of that, however, it's not generally true
+         * that ops_done <= ecp_max_ops, so the check
+         * ops_done > ecp_max_ops below is mandatory. */
+        if( ( rs_ctx->ops_done != 0 ) &&
+            ( rs_ctx->ops_done > ecp_max_ops ||
+              ops > ecp_max_ops - rs_ctx->ops_done ) )
+        {
+            return( MBEDTLS_ERR_ECP_IN_PROGRESS );
+        }
+
+        /* update running count */
+        rs_ctx->ops_done += ops;
+    }
+
+    return( 0 );
+}
+
+/* Call this when entering a function that needs its own sub-context */
+#define ECP_RS_ENTER( SUB )   do {                                      \
+    /* reset ops count for this call if top-level */                    \
+    if( rs_ctx != NULL && rs_ctx->depth++ == 0 )                        \
+        rs_ctx->ops_done = 0;                                           \
+                                                                        \
+    /* set up our own sub-context if needed */                          \
+    if( mbedtls_ecp_restart_is_enabled() &&                             \
+        rs_ctx != NULL && rs_ctx->SUB == NULL )                         \
+    {                                                                   \
+        rs_ctx->SUB = mbedtls_calloc( 1, sizeof( *rs_ctx->SUB ) );      \
+        if( rs_ctx->SUB == NULL )                                       \
+            return( MBEDTLS_ERR_ECP_ALLOC_FAILED );                     \
+                                                                        \
+        ecp_restart_## SUB ##_init( rs_ctx->SUB );                      \
+    }                                                                   \
+} while( 0 )
+
+/* Call this when leaving a function that needs its own sub-context */
+#define ECP_RS_LEAVE( SUB )   do {                                      \
+    /* clear our sub-context when not in progress (done or error) */    \
+    if( rs_ctx != NULL && rs_ctx->SUB != NULL &&                        \
+        ret != MBEDTLS_ERR_ECP_IN_PROGRESS )                            \
+    {                                                                   \
+        ecp_restart_## SUB ##_free( rs_ctx->SUB );                      \
+        mbedtls_free( rs_ctx->SUB );                                    \
+        rs_ctx->SUB = NULL;                                             \
+    }                                                                   \
+                                                                        \
+    if( rs_ctx != NULL )                                                \
+        rs_ctx->depth--;                                                \
+} while( 0 )
+
+#else /* MBEDTLS_ECP_RESTARTABLE */
+
+#define ECP_RS_ENTER( sub )     (void) rs_ctx;
+#define ECP_RS_LEAVE( sub )     (void) rs_ctx;
+
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)   ||   \
+    defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)   ||   \
+    defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)   ||   \
+    defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+#define ECP_SHORTWEIERSTRASS
+#endif
+
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
+    defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+#define ECP_MONTGOMERY
+#endif
+
+/*
+ * Curve types: internal for now, might be exposed later
+ */
+typedef enum
+{
+    ECP_TYPE_NONE = 0,
+    ECP_TYPE_SHORT_WEIERSTRASS,    /* y^2 = x^3 + a x + b      */
+    ECP_TYPE_MONTGOMERY,           /* y^2 = x^3 + a x^2 + x    */
+} ecp_curve_type;
+
+/*
+ * List of supported curves:
+ *  - internal ID
+ *  - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2)
+ *  - size in bits
+ *  - readable name
+ *
+ * Curves are listed in order: largest curves first, and for a given size,
+ * fastest curves first. This provides the default order for the SSL module.
+ *
+ * Reminder: update profiles in x509_crt.c when adding a new curves!
+ */
+static const mbedtls_ecp_curve_info ecp_supported_curves[] =
+{
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+    { MBEDTLS_ECP_DP_SECP521R1,    25,     521,    "secp521r1"         },
+#endif
+#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+    { MBEDTLS_ECP_DP_BP512R1,      28,     512,    "brainpoolP512r1"   },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+    { MBEDTLS_ECP_DP_SECP384R1,    24,     384,    "secp384r1"         },
+#endif
+#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+    { MBEDTLS_ECP_DP_BP384R1,      27,     384,    "brainpoolP384r1"   },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+    { MBEDTLS_ECP_DP_SECP256R1,    23,     256,    "secp256r1"         },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+    { MBEDTLS_ECP_DP_SECP256K1,    22,     256,    "secp256k1"         },
+#endif
+#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+    { MBEDTLS_ECP_DP_BP256R1,      26,     256,    "brainpoolP256r1"   },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+    { MBEDTLS_ECP_DP_SECP224R1,    21,     224,    "secp224r1"         },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+    { MBEDTLS_ECP_DP_SECP224K1,    20,     224,    "secp224k1"         },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+    { MBEDTLS_ECP_DP_SECP192R1,    19,     192,    "secp192r1"         },
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+    { MBEDTLS_ECP_DP_SECP192K1,    18,     192,    "secp192k1"         },
+#endif
+    { MBEDTLS_ECP_DP_NONE,          0,     0,      NULL                },
+};
+
+#define ECP_NB_CURVES   sizeof( ecp_supported_curves ) /    \
+                        sizeof( ecp_supported_curves[0] )
+
+static mbedtls_ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES];
+
+/*
+ * List of supported curves and associated info
+ */
+const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void )
+{
+    return( ecp_supported_curves );
+}
+
+/*
+ * List of supported curves, group ID only
+ */
+const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void )
+{
+    static int init_done = 0;
+
+    if( ! init_done )
+    {
+        size_t i = 0;
+        const mbedtls_ecp_curve_info *curve_info;
+
+        for( curve_info = mbedtls_ecp_curve_list();
+             curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
+             curve_info++ )
+        {
+            ecp_supported_grp_id[i++] = curve_info->grp_id;
+        }
+        ecp_supported_grp_id[i] = MBEDTLS_ECP_DP_NONE;
+
+        init_done = 1;
+    }
+
+    return( ecp_supported_grp_id );
+}
+
+/*
+ * Get the curve info for the internal identifier
+ */
+const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id )
+{
+    const mbedtls_ecp_curve_info *curve_info;
+
+    for( curve_info = mbedtls_ecp_curve_list();
+         curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
+         curve_info++ )
+    {
+        if( curve_info->grp_id == grp_id )
+            return( curve_info );
+    }
+
+    return( NULL );
+}
+
+/*
+ * Get the curve info from the TLS identifier
+ */
+const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id )
+{
+    const mbedtls_ecp_curve_info *curve_info;
+
+    for( curve_info = mbedtls_ecp_curve_list();
+         curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
+         curve_info++ )
+    {
+        if( curve_info->tls_id == tls_id )
+            return( curve_info );
+    }
+
+    return( NULL );
+}
+
+/*
+ * Get the curve info from the name
+ */
+const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name )
+{
+    const mbedtls_ecp_curve_info *curve_info;
+
+    if( name == NULL )
+        return( NULL );
+
+    for( curve_info = mbedtls_ecp_curve_list();
+         curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
+         curve_info++ )
+    {
+        if( strcmp( curve_info->name, name ) == 0 )
+            return( curve_info );
+    }
+
+    return( NULL );
+}
+
+/*
+ * Get the type of a curve
+ */
+static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp )
+{
+    if( grp->G.X.p == NULL )
+        return( ECP_TYPE_NONE );
+
+    if( grp->G.Y.p == NULL )
+        return( ECP_TYPE_MONTGOMERY );
+    else
+        return( ECP_TYPE_SHORT_WEIERSTRASS );
+}
+
+/*
+ * Initialize (the components of) a point
+ */
+void mbedtls_ecp_point_init( mbedtls_ecp_point *pt )
+{
+    ECP_VALIDATE( pt != NULL );
+
+    mbedtls_mpi_init( &pt->X );
+    mbedtls_mpi_init( &pt->Y );
+    mbedtls_mpi_init( &pt->Z );
+}
+
+/*
+ * Initialize (the components of) a group
+ */
+void mbedtls_ecp_group_init( mbedtls_ecp_group *grp )
+{
+    ECP_VALIDATE( grp != NULL );
+
+    grp->id = MBEDTLS_ECP_DP_NONE;
+    mbedtls_mpi_init( &grp->P );
+    mbedtls_mpi_init( &grp->A );
+    mbedtls_mpi_init( &grp->B );
+    mbedtls_ecp_point_init( &grp->G );
+    mbedtls_mpi_init( &grp->N );
+    grp->pbits = 0;
+    grp->nbits = 0;
+    grp->h = 0;
+    grp->modp = NULL;
+    grp->t_pre = NULL;
+    grp->t_post = NULL;
+    grp->t_data = NULL;
+    grp->T = NULL;
+    grp->T_size = 0;
+}
+
+/*
+ * Initialize (the components of) a key pair
+ */
+void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key )
+{
+    ECP_VALIDATE( key != NULL );
+
+    mbedtls_ecp_group_init( &key->grp );
+    mbedtls_mpi_init( &key->d );
+    mbedtls_ecp_point_init( &key->Q );
+}
+
+/*
+ * Unallocate (the components of) a point
+ */
+void mbedtls_ecp_point_free( mbedtls_ecp_point *pt )
+{
+    if( pt == NULL )
+        return;
+
+    mbedtls_mpi_free( &( pt->X ) );
+    mbedtls_mpi_free( &( pt->Y ) );
+    mbedtls_mpi_free( &( pt->Z ) );
+}
+
+/*
+ * Unallocate (the components of) a group
+ */
+void mbedtls_ecp_group_free( mbedtls_ecp_group *grp )
+{
+    size_t i;
+
+    if( grp == NULL )
+        return;
+
+    if( grp->h != 1 )
+    {
+        mbedtls_mpi_free( &grp->P );
+        mbedtls_mpi_free( &grp->A );
+        mbedtls_mpi_free( &grp->B );
+        mbedtls_ecp_point_free( &grp->G );
+        mbedtls_mpi_free( &grp->N );
+    }
+
+    if( grp->T != NULL )
+    {
+        for( i = 0; i < grp->T_size; i++ )
+            mbedtls_ecp_point_free( &grp->T[i] );
+        mbedtls_free( grp->T );
+    }
+
+    mbedtls_platform_zeroize( grp, sizeof( mbedtls_ecp_group ) );
+}
+
+/*
+ * Unallocate (the components of) a key pair
+ */
+void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key )
+{
+    if( key == NULL )
+        return;
+
+    mbedtls_ecp_group_free( &key->grp );
+    mbedtls_mpi_free( &key->d );
+    mbedtls_ecp_point_free( &key->Q );
+}
+
+/*
+ * Copy the contents of a point
+ */
+int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
+{
+    int ret;
+    ECP_VALIDATE_RET( P != NULL );
+    ECP_VALIDATE_RET( Q != NULL );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Z, &Q->Z ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Copy the contents of a group object
+ */
+int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src )
+{
+    ECP_VALIDATE_RET( dst != NULL );
+    ECP_VALIDATE_RET( src != NULL );
+
+    return( mbedtls_ecp_group_load( dst, src->id ) );
+}
+
+/*
+ * Set point to zero
+ */
+int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt )
+{
+    int ret;
+    ECP_VALIDATE_RET( pt != NULL );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z , 0 ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Tell if a point is zero
+ */
+int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt )
+{
+    ECP_VALIDATE_RET( pt != NULL );
+
+    return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 );
+}
+
+/*
+ * Compare two points lazily
+ */
+int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
+                           const mbedtls_ecp_point *Q )
+{
+    ECP_VALIDATE_RET( P != NULL );
+    ECP_VALIDATE_RET( Q != NULL );
+
+    if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 &&
+        mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 &&
+        mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 )
+    {
+        return( 0 );
+    }
+
+    return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+}
+
+/*
+ * Import a non-zero point from ASCII strings
+ */
+int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
+                           const char *x, const char *y )
+{
+    int ret;
+    ECP_VALIDATE_RET( P != NULL );
+    ECP_VALIDATE_RET( x != NULL );
+    ECP_VALIDATE_RET( y != NULL );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Export a point into unsigned binary data (SEC1 2.3.3)
+ */
+int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
+                                    const mbedtls_ecp_point *P,
+                                    int format, size_t *olen,
+                                    unsigned char *buf, size_t buflen )
+{
+    int ret = 0;
+    size_t plen;
+    ECP_VALIDATE_RET( grp  != NULL );
+    ECP_VALIDATE_RET( P    != NULL );
+    ECP_VALIDATE_RET( olen != NULL );
+    ECP_VALIDATE_RET( buf  != NULL );
+    ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED ||
+                      format == MBEDTLS_ECP_PF_COMPRESSED );
+
+    /*
+     * Common case: P == 0
+     */
+    if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
+    {
+        if( buflen < 1 )
+            return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+        buf[0] = 0x00;
+        *olen = 1;
+
+        return( 0 );
+    }
+
+    plen = mbedtls_mpi_size( &grp->P );
+
+    if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
+    {
+        *olen = 2 * plen + 1;
+
+        if( buflen < *olen )
+            return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+        buf[0] = 0x04;
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
+    }
+    else if( format == MBEDTLS_ECP_PF_COMPRESSED )
+    {
+        *olen = plen + 1;
+
+        if( buflen < *olen )
+            return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+        buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+    }
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Import a point from unsigned binary data (SEC1 2.3.4)
+ */
+int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
+                                   mbedtls_ecp_point *pt,
+                                   const unsigned char *buf, size_t ilen )
+{
+    int ret;
+    size_t plen;
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( pt  != NULL );
+    ECP_VALIDATE_RET( buf != NULL );
+
+    if( ilen < 1 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    if( buf[0] == 0x00 )
+    {
+        if( ilen == 1 )
+            return( mbedtls_ecp_set_zero( pt ) );
+        else
+            return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+
+    plen = mbedtls_mpi_size( &grp->P );
+
+    if( buf[0] != 0x04 )
+        return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+
+    if( ilen != 2 * plen + 1 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Import a point from a TLS ECPoint record (RFC 4492)
+ *      struct {
+ *          opaque point <1..2^8-1>;
+ *      } ECPoint;
+ */
+int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp,
+                                mbedtls_ecp_point *pt,
+                                const unsigned char **buf, size_t buf_len )
+{
+    unsigned char data_len;
+    const unsigned char *buf_start;
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( pt  != NULL );
+    ECP_VALIDATE_RET( buf != NULL );
+    ECP_VALIDATE_RET( *buf != NULL );
+
+    /*
+     * We must have at least two bytes (1 for length, at least one for data)
+     */
+    if( buf_len < 2 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    data_len = *(*buf)++;
+    if( data_len < 1 || data_len > buf_len - 1 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    /*
+     * Save buffer start for read_binary and update buf
+     */
+    buf_start = *buf;
+    *buf += data_len;
+
+    return( mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ) );
+}
+
+/*
+ * Export a point as a TLS ECPoint record (RFC 4492)
+ *      struct {
+ *          opaque point <1..2^8-1>;
+ *      } ECPoint;
+ */
+int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt,
+                         int format, size_t *olen,
+                         unsigned char *buf, size_t blen )
+{
+    int ret;
+    ECP_VALIDATE_RET( grp  != NULL );
+    ECP_VALIDATE_RET( pt   != NULL );
+    ECP_VALIDATE_RET( olen != NULL );
+    ECP_VALIDATE_RET( buf  != NULL );
+    ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED ||
+                      format == MBEDTLS_ECP_PF_COMPRESSED );
+
+    /*
+     * buffer length must be at least one, for our length byte
+     */
+    if( blen < 1 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    if( ( ret = mbedtls_ecp_point_write_binary( grp, pt, format,
+                    olen, buf + 1, blen - 1) ) != 0 )
+        return( ret );
+
+    /*
+     * write length to the first byte and update total length
+     */
+    buf[0] = (unsigned char) *olen;
+    ++*olen;
+
+    return( 0 );
+}
+
+/*
+ * Set a group from an ECParameters record (RFC 4492)
+ */
+int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp,
+                                const unsigned char **buf, size_t len )
+{
+    int ret;
+    mbedtls_ecp_group_id grp_id;
+    ECP_VALIDATE_RET( grp  != NULL );
+    ECP_VALIDATE_RET( buf  != NULL );
+    ECP_VALIDATE_RET( *buf != NULL );
+
+    if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, len ) ) != 0 )
+        return( ret );
+
+    return( mbedtls_ecp_group_load( grp, grp_id ) );
+}
+
+/*
+ * Read a group id from an ECParameters record (RFC 4492) and convert it to
+ * mbedtls_ecp_group_id.
+ */
+int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp,
+                                   const unsigned char **buf, size_t len )
+{
+    uint16_t tls_id;
+    const mbedtls_ecp_curve_info *curve_info;
+    ECP_VALIDATE_RET( grp  != NULL );
+    ECP_VALIDATE_RET( buf  != NULL );
+    ECP_VALIDATE_RET( *buf != NULL );
+
+    /*
+     * We expect at least three bytes (see below)
+     */
+    if( len < 3 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    /*
+     * First byte is curve_type; only named_curve is handled
+     */
+    if( *(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    /*
+     * Next two bytes are the namedcurve value
+     */
+    tls_id = *(*buf)++;
+    tls_id <<= 8;
+    tls_id |= *(*buf)++;
+
+    if( ( curve_info = mbedtls_ecp_curve_info_from_tls_id( tls_id ) ) == NULL )
+        return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+
+    *grp = curve_info->grp_id;
+
+    return( 0 );
+}
+
+/*
+ * Write the ECParameters record corresponding to a group (RFC 4492)
+ */
+int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
+                         unsigned char *buf, size_t blen )
+{
+    const mbedtls_ecp_curve_info *curve_info;
+    ECP_VALIDATE_RET( grp  != NULL );
+    ECP_VALIDATE_RET( buf  != NULL );
+    ECP_VALIDATE_RET( olen != NULL );
+
+    if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    /*
+     * We are going to write 3 bytes (see below)
+     */
+    *olen = 3;
+    if( blen < *olen )
+        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+    /*
+     * First byte is curve_type, always named_curve
+     */
+    *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
+
+    /*
+     * Next two bytes are the namedcurve value
+     */
+    buf[0] = curve_info->tls_id >> 8;
+    buf[1] = curve_info->tls_id & 0xFF;
+
+    return( 0 );
+}
+
+/*
+ * Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi.
+ * See the documentation of struct mbedtls_ecp_group.
+ *
+ * This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf.
+ */
+static int ecp_modp( mbedtls_mpi *N, const mbedtls_ecp_group *grp )
+{
+    int ret;
+
+    if( grp->modp == NULL )
+        return( mbedtls_mpi_mod_mpi( N, N, &grp->P ) );
+
+    /* N->s < 0 is a much faster test, which fails only if N is 0 */
+    if( ( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) ||
+        mbedtls_mpi_bitlen( N ) > 2 * grp->pbits )
+    {
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+
+    MBEDTLS_MPI_CHK( grp->modp( N ) );
+
+    /* N->s < 0 is a much faster test, which fails only if N is 0 */
+    while( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &grp->P ) );
+
+    while( mbedtls_mpi_cmp_mpi( N, &grp->P ) >= 0 )
+        /* we known P, N and the result are positive */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, N, &grp->P ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Fast mod-p functions expect their argument to be in the 0..p^2 range.
+ *
+ * In order to guarantee that, we need to ensure that operands of
+ * mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will
+ * bring the result back to this range.
+ *
+ * The following macros are shortcuts for doing that.
+ */
+
+/*
+ * Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi
+ */
+#if defined(MBEDTLS_SELF_TEST)
+#define INC_MUL_COUNT   mul_count++;
+#else
+#define INC_MUL_COUNT
+#endif
+
+#define MOD_MUL( N )    do { MBEDTLS_MPI_CHK( ecp_modp( &N, grp ) ); INC_MUL_COUNT } \
+                        while( 0 )
+
+/*
+ * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi
+ * N->s < 0 is a very fast test, which fails only if N is 0
+ */
+#define MOD_SUB( N )                                \
+    while( N.s < 0 && mbedtls_mpi_cmp_int( &N, 0 ) != 0 )   \
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &N, &N, &grp->P ) )
+
+/*
+ * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int.
+ * We known P, N and the result are positive, so sub_abs is correct, and
+ * a bit faster.
+ */
+#define MOD_ADD( N )                                \
+    while( mbedtls_mpi_cmp_mpi( &N, &grp->P ) >= 0 )        \
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &N, &N, &grp->P ) )
+
+#if defined(ECP_SHORTWEIERSTRASS)
+/*
+ * For curves in short Weierstrass form, we do all the internal operations in
+ * Jacobian coordinates.
+ *
+ * For multiplication, we'll use a comb method with coutermeasueres against
+ * SPA, hence timing attacks.
+ */
+
+/*
+ * Normalize jacobian coordinates so that Z == 0 || Z == 1  (GECC 3.2.1)
+ * Cost: 1N := 1I + 3M + 1S
+ */
+static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt )
+{
+    int ret;
+    mbedtls_mpi Zi, ZZi;
+
+    if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 )
+        return( 0 );
+
+#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
+    if( mbedtls_internal_ecp_grp_capable( grp ) )
+        return( mbedtls_internal_ecp_normalize_jac( grp, pt ) );
+#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */
+
+    mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
+
+    /*
+     * X = X / Z^2  mod p
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi,      &pt->Z,     &grp->P ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi,     &Zi,        &Zi     ) ); MOD_MUL( ZZi );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X,   &pt->X,     &ZZi    ) ); MOD_MUL( pt->X );
+
+    /*
+     * Y = Y / Z^3  mod p
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y,   &pt->Y,     &ZZi    ) ); MOD_MUL( pt->Y );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y,   &pt->Y,     &Zi     ) ); MOD_MUL( pt->Y );
+
+    /*
+     * Z = 1
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+
+cleanup:
+
+    mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
+
+    return( ret );
+}
+
+/*
+ * Normalize jacobian coordinates of an array of (pointers to) points,
+ * using Montgomery's trick to perform only one inversion mod P.
+ * (See for example Cohen's "A Course in Computational Algebraic Number
+ * Theory", Algorithm 10.3.4.)
+ *
+ * Warning: fails (returning an error) if one of the points is zero!
+ * This should never happen, see choice of w in ecp_mul_comb().
+ *
+ * Cost: 1N(t) := 1I + (6t - 3)M + 1S
+ */
+static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
+                                   mbedtls_ecp_point *T[], size_t T_size )
+{
+    int ret;
+    size_t i;
+    mbedtls_mpi *c, u, Zi, ZZi;
+
+    if( T_size < 2 )
+        return( ecp_normalize_jac( grp, *T ) );
+
+#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
+    if( mbedtls_internal_ecp_grp_capable( grp ) )
+        return( mbedtls_internal_ecp_normalize_jac_many( grp, T, T_size ) );
+#endif
+
+    if( ( c = mbedtls_calloc( T_size, sizeof( mbedtls_mpi ) ) ) == NULL )
+        return( MBEDTLS_ERR_ECP_ALLOC_FAILED );
+
+    for( i = 0; i < T_size; i++ )
+        mbedtls_mpi_init( &c[i] );
+
+    mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
+
+    /*
+     * c[i] = Z_0 * ... * Z_i
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) );
+    for( i = 1; i < T_size; i++ )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) );
+        MOD_MUL( c[i] );
+    }
+
+    /*
+     * u = 1 / (Z_0 * ... * Z_n) mod P
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[T_size-1], &grp->P ) );
+
+    for( i = T_size - 1; ; i-- )
+    {
+        /*
+         * Zi = 1 / Z_i mod p
+         * u = 1 / (Z_0 * ... * Z_i) mod P
+         */
+        if( i == 0 ) {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Zi, &u ) );
+        }
+        else
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Zi, &u, &c[i-1]  ) ); MOD_MUL( Zi );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u,  &u, &T[i]->Z ) ); MOD_MUL( u );
+        }
+
+        /*
+         * proceed as in normalize()
+         */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi,     &Zi,      &Zi  ) ); MOD_MUL( ZZi );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi  ) ); MOD_MUL( T[i]->Y );
+
+        /*
+         * Post-precessing: reclaim some memory by shrinking coordinates
+         * - not storing Z (always 1)
+         * - shrinking other coordinates, but still keeping the same number of
+         *   limbs as P, as otherwise it will too likely be regrown too fast.
+         */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->X, grp->P.n ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->Y, grp->P.n ) );
+        mbedtls_mpi_free( &T[i]->Z );
+
+        if( i == 0 )
+            break;
+    }
+
+cleanup:
+
+    mbedtls_mpi_free( &u ); mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
+    for( i = 0; i < T_size; i++ )
+        mbedtls_mpi_free( &c[i] );
+    mbedtls_free( c );
+
+    return( ret );
+}
+
+/*
+ * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak.
+ * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid
+ */
+static int ecp_safe_invert_jac( const mbedtls_ecp_group *grp,
+                            mbedtls_ecp_point *Q,
+                            unsigned char inv )
+{
+    int ret;
+    unsigned char nonzero;
+    mbedtls_mpi mQY;
+
+    mbedtls_mpi_init( &mQY );
+
+    /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) );
+    nonzero = mbedtls_mpi_cmp_int( &Q->Y, 0 ) != 0;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) );
+
+cleanup:
+    mbedtls_mpi_free( &mQY );
+
+    return( ret );
+}
+
+/*
+ * Point doubling R = 2 P, Jacobian coordinates
+ *
+ * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 .
+ *
+ * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR
+ * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring.
+ *
+ * Standard optimizations are applied when curve parameter A is one of { 0, -3 }.
+ *
+ * Cost: 1D := 3M + 4S          (A ==  0)
+ *             4M + 4S          (A == -3)
+ *             3M + 6S + 1a     otherwise
+ */
+static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+                           const mbedtls_ecp_point *P )
+{
+    int ret;
+    mbedtls_mpi M, S, T, U;
+
+#if defined(MBEDTLS_SELF_TEST)
+    dbl_count++;
+#endif
+
+#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
+    if( mbedtls_internal_ecp_grp_capable( grp ) )
+        return( mbedtls_internal_ecp_double_jac( grp, R, P ) );
+#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */
+
+    mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U );
+
+    /* Special case for A = -3 */
+    if( grp->A.p == NULL )
+    {
+        /* M = 3(X + Z^2)(X - Z^2) */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S,  &P->Z,  &P->Z   ) ); MOD_MUL( S );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T,  &P->X,  &S      ) ); MOD_ADD( T );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U,  &P->X,  &S      ) ); MOD_SUB( U );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S,  &T,     &U      ) ); MOD_MUL( S );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M,  &S,     3       ) ); MOD_ADD( M );
+    }
+    else
+    {
+        /* M = 3.X^2 */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S,  &P->X,  &P->X   ) ); MOD_MUL( S );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M,  &S,     3       ) ); MOD_ADD( M );
+
+        /* Optimize away for "koblitz" curves with A = 0 */
+        if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 )
+        {
+            /* M += A.Z^4 */
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S,  &P->Z,  &P->Z   ) ); MOD_MUL( S );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T,  &S,     &S      ) ); MOD_MUL( T );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S,  &T,     &grp->A ) ); MOD_MUL( S );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M,  &M,     &S      ) ); MOD_ADD( M );
+        }
+    }
+
+    /* S = 4.X.Y^2 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T,  &P->Y,  &P->Y   ) ); MOD_MUL( T );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T,  1               ) ); MOD_ADD( T );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S,  &P->X,  &T      ) ); MOD_MUL( S );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &S,  1               ) ); MOD_ADD( S );
+
+    /* U = 8.Y^4 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U,  &T,     &T      ) ); MOD_MUL( U );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U,  1               ) ); MOD_ADD( U );
+
+    /* T = M^2 - 2.S */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T,  &M,     &M      ) ); MOD_MUL( T );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T,  &T,     &S      ) ); MOD_SUB( T );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T,  &T,     &S      ) ); MOD_SUB( T );
+
+    /* S = M(S - T) - U */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S,  &S,     &T      ) ); MOD_SUB( S );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S,  &S,     &M      ) ); MOD_MUL( S );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S,  &S,     &U      ) ); MOD_SUB( S );
+
+    /* U = 2.Y.Z */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U,  &P->Y,  &P->Z   ) ); MOD_MUL( U );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U,  1               ) ); MOD_ADD( U );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &U ) );
+
+cleanup:
+    mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U );
+
+    return( ret );
+}
+
+/*
+ * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22)
+ *
+ * The coordinates of Q must be normalized (= affine),
+ * but those of P don't need to. R is not normalized.
+ *
+ * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q.
+ * None of these cases can happen as intermediate step in ecp_mul_comb():
+ * - at each step, P, Q and R are multiples of the base point, the factor
+ *   being less than its order, so none of them is zero;
+ * - Q is an odd multiple of the base point, P an even multiple,
+ *   due to the choice of precomputed points in the modified comb method.
+ * So branches for these cases do not leak secret information.
+ *
+ * We accept Q->Z being unset (saving memory in tables) as meaning 1.
+ *
+ * Cost: 1A := 8M + 3S
+ */
+static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+                          const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
+{
+    int ret;
+    mbedtls_mpi T1, T2, T3, T4, X, Y, Z;
+
+#if defined(MBEDTLS_SELF_TEST)
+    add_count++;
+#endif
+
+#if defined(MBEDTLS_ECP_ADD_MIXED_ALT)
+    if( mbedtls_internal_ecp_grp_capable( grp ) )
+        return( mbedtls_internal_ecp_add_mixed( grp, R, P, Q ) );
+#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */
+
+    /*
+     * Trivial cases: P == 0 or Q == 0 (case 1)
+     */
+    if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
+        return( mbedtls_ecp_copy( R, Q ) );
+
+    if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 0 ) == 0 )
+        return( mbedtls_ecp_copy( R, P ) );
+
+    /*
+     * Make sure Q coordinates are normalized
+     */
+    if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 1 ) != 0 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 );
+    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1,  &P->Z,  &P->Z ) );  MOD_MUL( T1 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2,  &T1,    &P->Z ) );  MOD_MUL( T2 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1,  &T1,    &Q->X ) );  MOD_MUL( T1 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2,  &T2,    &Q->Y ) );  MOD_MUL( T2 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T1,  &T1,    &P->X ) );  MOD_SUB( T1 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T2,  &T2,    &P->Y ) );  MOD_SUB( T2 );
+
+    /* Special cases (2) and (3) */
+    if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 )
+    {
+        if( mbedtls_mpi_cmp_int( &T2, 0 ) == 0 )
+        {
+            ret = ecp_double_jac( grp, R, P );
+            goto cleanup;
+        }
+        else
+        {
+            ret = mbedtls_ecp_set_zero( R );
+            goto cleanup;
+        }
+    }
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Z,   &P->Z,  &T1   ) );  MOD_MUL( Z  );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3,  &T1,    &T1   ) );  MOD_MUL( T3 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4,  &T3,    &T1   ) );  MOD_MUL( T4 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3,  &T3,    &P->X ) );  MOD_MUL( T3 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1,  &T3,    2     ) );  MOD_ADD( T1 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X,   &T2,    &T2   ) );  MOD_MUL( X  );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X,   &X,     &T1   ) );  MOD_SUB( X  );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X,   &X,     &T4   ) );  MOD_SUB( X  );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T3,  &T3,    &X    ) );  MOD_SUB( T3 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3,  &T3,    &T2   ) );  MOD_MUL( T3 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4,  &T4,    &P->Y ) );  MOD_MUL( T4 );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &Y,   &T3,    &T4   ) );  MOD_SUB( Y  );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &Z ) );
+
+cleanup:
+
+    mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &T3 ); mbedtls_mpi_free( &T4 );
+    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
+
+    return( ret );
+}
+
+/*
+ * Randomize jacobian coordinates:
+ * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l
+ * This is sort of the reverse operation of ecp_normalize_jac().
+ *
+ * This countermeasure was first suggested in [2].
+ */
+static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret;
+    mbedtls_mpi l, ll;
+    size_t p_size;
+    int count = 0;
+
+#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
+    if( mbedtls_internal_ecp_grp_capable( grp ) )
+        return( mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ) );
+#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */
+
+    p_size = ( grp->pbits + 7 ) / 8;
+    mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll );
+
+    /* Generate l such that 1 < l < p */
+    do
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
+
+        while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 )
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) );
+
+        if( count++ > 10 )
+            return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
+    }
+    while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
+
+    /* Z = l * Z */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z,   &pt->Z,     &l  ) ); MOD_MUL( pt->Z );
+
+    /* X = l^2 * X */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll,      &l,         &l  ) ); MOD_MUL( ll );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X,   &pt->X,     &ll ) ); MOD_MUL( pt->X );
+
+    /* Y = l^3 * Y */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll,      &ll,        &l  ) ); MOD_MUL( ll );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y,   &pt->Y,     &ll ) ); MOD_MUL( pt->Y );
+
+cleanup:
+    mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll );
+
+    return( ret );
+}
+
+/*
+ * Check and define parameters used by the comb method (see below for details)
+ */
+#if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7
+#error "MBEDTLS_ECP_WINDOW_SIZE out of bounds"
+#endif
+
+/* d = ceil( n / w ) */
+#define COMB_MAX_D      ( MBEDTLS_ECP_MAX_BITS + 1 ) / 2
+
+/* number of precomputed points */
+#define COMB_MAX_PRE    ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
+
+/*
+ * Compute the representation of m that will be used with our comb method.
+ *
+ * The basic comb method is described in GECC 3.44 for example. We use a
+ * modified version that provides resistance to SPA by avoiding zero
+ * digits in the representation as in [3]. We modify the method further by
+ * requiring that all K_i be odd, which has the small cost that our
+ * representation uses one more K_i, due to carries, but saves on the size of
+ * the precomputed table.
+ *
+ * Summary of the comb method and its modifications:
+ *
+ * - The goal is to compute m*P for some w*d-bit integer m.
+ *
+ * - The basic comb method splits m into the w-bit integers
+ *   x[0] .. x[d-1] where x[i] consists of the bits in m whose
+ *   index has residue i modulo d, and computes m * P as
+ *   S[x[0]] + 2 * S[x[1]] + .. + 2^(d-1) S[x[d-1]], where
+ *   S[i_{w-1} .. i_0] := i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + i_0 P.
+ *
+ * - If it happens that, say, x[i+1]=0 (=> S[x[i+1]]=0), one can replace the sum by
+ *    .. + 2^{i-1} S[x[i-1]] - 2^i S[x[i]] + 2^{i+1} S[x[i]] + 2^{i+2} S[x[i+2]] ..,
+ *   thereby successively converting it into a form where all summands
+ *   are nonzero, at the cost of negative summands. This is the basic idea of [3].
+ *
+ * - More generally, even if x[i+1] != 0, we can first transform the sum as
+ *   .. - 2^i S[x[i]] + 2^{i+1} ( S[x[i]] + S[x[i+1]] ) + 2^{i+2} S[x[i+2]] ..,
+ *   and then replace S[x[i]] + S[x[i+1]] = S[x[i] ^ x[i+1]] + 2 S[x[i] & x[i+1]].
+ *   Performing and iterating this procedure for those x[i] that are even
+ *   (keeping track of carry), we can transform the original sum into one of the form
+ *   S[x'[0]] +- 2 S[x'[1]] +- .. +- 2^{d-1} S[x'[d-1]] + 2^d S[x'[d]]
+ *   with all x'[i] odd. It is therefore only necessary to know S at odd indices,
+ *   which is why we are only computing half of it in the first place in
+ *   ecp_precompute_comb and accessing it with index abs(i) / 2 in ecp_select_comb.
+ *
+ * - For the sake of compactness, only the seven low-order bits of x[i]
+ *   are used to represent its absolute value (K_i in the paper), and the msb
+ *   of x[i] encodes the sign (s_i in the paper): it is set if and only if
+ *   if s_i == -1;
+ *
+ * Calling conventions:
+ * - x is an array of size d + 1
+ * - w is the size, ie number of teeth, of the comb, and must be between
+ *   2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE)
+ * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d
+ *   (the result will be incorrect if these assumptions are not satisfied)
+ */
+static void ecp_comb_recode_core( unsigned char x[], size_t d,
+                                  unsigned char w, const mbedtls_mpi *m )
+{
+    size_t i, j;
+    unsigned char c, cc, adjust;
+
+    memset( x, 0, d+1 );
+
+    /* First get the classical comb values (except for x_d = 0) */
+    for( i = 0; i < d; i++ )
+        for( j = 0; j < w; j++ )
+            x[i] |= mbedtls_mpi_get_bit( m, i + d * j ) << j;
+
+    /* Now make sure x_1 .. x_d are odd */
+    c = 0;
+    for( i = 1; i <= d; i++ )
+    {
+        /* Add carry and update it */
+        cc   = x[i] & c;
+        x[i] = x[i] ^ c;
+        c = cc;
+
+        /* Adjust if needed, avoiding branches */
+        adjust = 1 - ( x[i] & 0x01 );
+        c   |= x[i] & ( x[i-1] * adjust );
+        x[i] = x[i] ^ ( x[i-1] * adjust );
+        x[i-1] |= adjust << 7;
+    }
+}
+
+/*
+ * Precompute points for the adapted comb method
+ *
+ * Assumption: T must be able to hold 2^{w - 1} elements.
+ *
+ * Operation: If i = i_{w-1} ... i_1 is the binary representation of i,
+ *            sets T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P.
+ *
+ * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1)
+ *
+ * Note: Even comb values (those where P would be omitted from the
+ *       sum defining T[i] above) are not needed in our adaption
+ *       the comb method. See ecp_comb_recode_core().
+ *
+ * This function currently works in four steps:
+ * (1) [dbl]      Computation of intermediate T[i] for 2-power values of i
+ * (2) [norm_dbl] Normalization of coordinates of these T[i]
+ * (3) [add]      Computation of all T[i]
+ * (4) [norm_add] Normalization of all T[i]
+ *
+ * Step 1 can be interrupted but not the others; together with the final
+ * coordinate normalization they are the largest steps done at once, depending
+ * on the window size. Here are operation counts for P-256:
+ *
+ * step     (2)     (3)     (4)
+ * w = 5    142     165     208
+ * w = 4    136      77     160
+ * w = 3    130      33     136
+ * w = 2    124      11     124
+ *
+ * So if ECC operations are blocking for too long even with a low max_ops
+ * value, it's useful to set MBEDTLS_ECP_WINDOW_SIZE to a lower value in order
+ * to minimize maximum blocking time.
+ */
+static int ecp_precompute_comb( const mbedtls_ecp_group *grp,
+                                mbedtls_ecp_point T[], const mbedtls_ecp_point *P,
+                                unsigned char w, size_t d,
+                                mbedtls_ecp_restart_ctx *rs_ctx )
+{
+    int ret;
+    unsigned char i;
+    size_t j = 0;
+    const unsigned char T_size = 1U << ( w - 1 );
+    mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1];
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL )
+    {
+        if( rs_ctx->rsm->state == ecp_rsm_pre_dbl )
+            goto dbl;
+        if( rs_ctx->rsm->state == ecp_rsm_pre_norm_dbl )
+            goto norm_dbl;
+        if( rs_ctx->rsm->state == ecp_rsm_pre_add )
+            goto add;
+        if( rs_ctx->rsm->state == ecp_rsm_pre_norm_add )
+            goto norm_add;
+    }
+#else
+    (void) rs_ctx;
+#endif
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL )
+    {
+        rs_ctx->rsm->state = ecp_rsm_pre_dbl;
+
+        /* initial state for the loop */
+        rs_ctx->rsm->i = 0;
+    }
+
+dbl:
+#endif
+    /*
+     * Set T[0] = P and
+     * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value)
+     */
+    MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &T[0], P ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 )
+        j = rs_ctx->rsm->i;
+    else
+#endif
+        j = 0;
+
+    for( ; j < d * ( w - 1 ); j++ )
+    {
+        MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL );
+
+        i = 1U << ( j / d );
+        cur = T + i;
+
+        if( j % d == 0 )
+            MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) );
+
+        MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) );
+    }
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL )
+        rs_ctx->rsm->state = ecp_rsm_pre_norm_dbl;
+
+norm_dbl:
+#endif
+    /*
+     * Normalize current elements in T. As T has holes,
+     * use an auxiliary array of pointers to elements in T.
+     */
+    j = 0;
+    for( i = 1; i < T_size; i <<= 1 )
+        TT[j++] = T + i;
+
+    MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 );
+
+    MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL )
+        rs_ctx->rsm->state = ecp_rsm_pre_add;
+
+add:
+#endif
+    /*
+     * Compute the remaining ones using the minimal number of additions
+     * Be careful to update T[2^l] only after using it!
+     */
+    MBEDTLS_ECP_BUDGET( ( T_size - 1 ) * MBEDTLS_ECP_OPS_ADD );
+
+    for( i = 1; i < T_size; i <<= 1 )
+    {
+        j = i;
+        while( j-- )
+            MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) );
+    }
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL )
+        rs_ctx->rsm->state = ecp_rsm_pre_norm_add;
+
+norm_add:
+#endif
+    /*
+     * Normalize final elements in T. Even though there are no holes now, we
+     * still need the auxiliary array for homogeneity with the previous
+     * call. Also, skip T[0] which is already normalised, being a copy of P.
+     */
+    for( j = 0; j + 1 < T_size; j++ )
+        TT[j] = T + j + 1;
+
+    MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV + 6 * j - 2 );
+
+    MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, j ) );
+
+cleanup:
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL &&
+        ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+    {
+        if( rs_ctx->rsm->state == ecp_rsm_pre_dbl )
+            rs_ctx->rsm->i = j;
+    }
+#endif
+
+    return( ret );
+}
+
+/*
+ * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ]
+ *
+ * See ecp_comb_recode_core() for background
+ */
+static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+                            const mbedtls_ecp_point T[], unsigned char T_size,
+                            unsigned char i )
+{
+    int ret;
+    unsigned char ii, j;
+
+    /* Ignore the "sign" bit and scale down */
+    ii =  ( i & 0x7Fu ) >> 1;
+
+    /* Read the whole table to thwart cache-based timing attacks */
+    for( j = 0; j < T_size; j++ )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) );
+    }
+
+    /* Safely invert result if i is "negative" */
+    MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Core multiplication algorithm for the (modified) comb method.
+ * This part is actually common with the basic comb method (GECC 3.44)
+ *
+ * Cost: d A + d D + 1 R
+ */
+static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+                              const mbedtls_ecp_point T[], unsigned char T_size,
+                              const unsigned char x[], size_t d,
+                              int (*f_rng)(void *, unsigned char *, size_t),
+                              void *p_rng,
+                              mbedtls_ecp_restart_ctx *rs_ctx )
+{
+    int ret;
+    mbedtls_ecp_point Txi;
+    size_t i;
+
+    mbedtls_ecp_point_init( &Txi );
+
+#if !defined(MBEDTLS_ECP_RESTARTABLE)
+    (void) rs_ctx;
+#endif
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL &&
+        rs_ctx->rsm->state != ecp_rsm_comb_core )
+    {
+        rs_ctx->rsm->i = 0;
+        rs_ctx->rsm->state = ecp_rsm_comb_core;
+    }
+
+    /* new 'if' instead of nested for the sake of the 'else' branch */
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0 )
+    {
+        /* restore current index (R already pointing to rs_ctx->rsm->R) */
+        i = rs_ctx->rsm->i;
+    }
+    else
+#endif
+    {
+        /* Start with a non-zero point and randomize its coordinates */
+        i = d;
+        MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, T_size, x[i] ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) );
+        if( f_rng != 0 )
+            MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) );
+    }
+
+    while( i != 0 )
+    {
+        MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_DBL + MBEDTLS_ECP_OPS_ADD );
+        --i;
+
+        MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R ) );
+        MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, T_size, x[i] ) );
+        MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) );
+    }
+
+cleanup:
+
+    mbedtls_ecp_point_free( &Txi );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL &&
+        ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+    {
+        rs_ctx->rsm->i = i;
+        /* no need to save R, already pointing to rs_ctx->rsm->R */
+    }
+#endif
+
+    return( ret );
+}
+
+/*
+ * Recode the scalar to get constant-time comb multiplication
+ *
+ * As the actual scalar recoding needs an odd scalar as a starting point,
+ * this wrapper ensures that by replacing m by N - m if necessary, and
+ * informs the caller that the result of multiplication will be negated.
+ *
+ * This works because we only support large prime order for Short Weierstrass
+ * curves, so N is always odd hence either m or N - m is.
+ *
+ * See ecp_comb_recode_core() for background.
+ */
+static int ecp_comb_recode_scalar( const mbedtls_ecp_group *grp,
+                                   const mbedtls_mpi *m,
+                                   unsigned char k[COMB_MAX_D + 1],
+                                   size_t d,
+                                   unsigned char w,
+                                   unsigned char *parity_trick )
+{
+    int ret;
+    mbedtls_mpi M, mm;
+
+    mbedtls_mpi_init( &M );
+    mbedtls_mpi_init( &mm );
+
+    /* N is always odd (see above), just make extra sure */
+    if( mbedtls_mpi_get_bit( &grp->N, 0 ) != 1 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    /* do we need the parity trick? */
+    *parity_trick = ( mbedtls_mpi_get_bit( m, 0 ) == 0 );
+
+    /* execute parity fix in constant time */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &M, m ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mm, &grp->N, m ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &M, &mm, *parity_trick ) );
+
+    /* actual scalar recoding */
+    ecp_comb_recode_core( k, d, w, &M );
+
+cleanup:
+    mbedtls_mpi_free( &mm );
+    mbedtls_mpi_free( &M );
+
+    return( ret );
+}
+
+/*
+ * Perform comb multiplication (for short Weierstrass curves)
+ * once the auxiliary table has been pre-computed.
+ *
+ * Scalar recoding may use a parity trick that makes us compute -m * P,
+ * if that is the case we'll need to recover m * P at the end.
+ */
+static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp,
+                                mbedtls_ecp_point *R,
+                                const mbedtls_mpi *m,
+                                const mbedtls_ecp_point *T,
+                                unsigned char T_size,
+                                unsigned char w,
+                                size_t d,
+                                int (*f_rng)(void *, unsigned char *, size_t),
+                                void *p_rng,
+                                mbedtls_ecp_restart_ctx *rs_ctx )
+{
+    int ret;
+    unsigned char parity_trick;
+    unsigned char k[COMB_MAX_D + 1];
+    mbedtls_ecp_point *RR = R;
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL )
+    {
+        RR = &rs_ctx->rsm->R;
+
+        if( rs_ctx->rsm->state == ecp_rsm_final_norm )
+            goto final_norm;
+    }
+#endif
+
+    MBEDTLS_MPI_CHK( ecp_comb_recode_scalar( grp, m, k, d, w,
+                                            &parity_trick ) );
+    MBEDTLS_MPI_CHK( ecp_mul_comb_core( grp, RR, T, T_size, k, d,
+                                        f_rng, p_rng, rs_ctx ) );
+    MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, RR, parity_trick ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL )
+        rs_ctx->rsm->state = ecp_rsm_final_norm;
+
+final_norm:
+#endif
+    MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV );
+    MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, RR ) );
+#endif
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Pick window size based on curve size and whether we optimize for base point
+ */
+static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp,
+                                           unsigned char p_eq_g )
+{
+    unsigned char w;
+
+    /*
+     * Minimize the number of multiplications, that is minimize
+     * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w )
+     * (see costs of the various parts, with 1S = 1M)
+     */
+    w = grp->nbits >= 384 ? 5 : 4;
+
+    /*
+     * If P == G, pre-compute a bit more, since this may be re-used later.
+     * Just adding one avoids upping the cost of the first mul too much,
+     * and the memory cost too.
+     */
+    if( p_eq_g )
+        w++;
+
+    /*
+     * Make sure w is within bounds.
+     * (The last test is useful only for very small curves in the test suite.)
+     */
+    if( w > MBEDTLS_ECP_WINDOW_SIZE )
+        w = MBEDTLS_ECP_WINDOW_SIZE;
+    if( w >= grp->nbits )
+        w = 2;
+
+    return( w );
+}
+
+/*
+ * Multiplication using the comb method - for curves in short Weierstrass form
+ *
+ * This function is mainly responsible for administrative work:
+ * - managing the restart context if enabled
+ * - managing the table of precomputed points (passed between the below two
+ *   functions): allocation, computation, ownership tranfer, freeing.
+ *
+ * It delegates the actual arithmetic work to:
+ *      ecp_precompute_comb() and ecp_mul_comb_with_precomp()
+ *
+ * See comments on ecp_comb_recode_core() regarding the computation strategy.
+ */
+static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+                         const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng,
+                         mbedtls_ecp_restart_ctx *rs_ctx )
+{
+    int ret;
+    unsigned char w, p_eq_g, i;
+    size_t d;
+    unsigned char T_size, T_ok;
+    mbedtls_ecp_point *T;
+
+    ECP_RS_ENTER( rsm );
+
+    /* Is P the base point ? */
+#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
+    p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
+               mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 );
+#else
+    p_eq_g = 0;
+#endif
+
+    /* Pick window size and deduce related sizes */
+    w = ecp_pick_window_size( grp, p_eq_g );
+    T_size = 1U << ( w - 1 );
+    d = ( grp->nbits + w - 1 ) / w;
+
+    /* Pre-computed table: do we have it already for the base point? */
+    if( p_eq_g && grp->T != NULL )
+    {
+        /* second pointer to the same table, will be deleted on exit */
+        T = grp->T;
+        T_ok = 1;
+    }
+    else
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    /* Pre-computed table: do we have one in progress? complete? */
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->T != NULL )
+    {
+        /* transfer ownership of T from rsm to local function */
+        T = rs_ctx->rsm->T;
+        rs_ctx->rsm->T = NULL;
+        rs_ctx->rsm->T_size = 0;
+
+        /* This effectively jumps to the call to mul_comb_after_precomp() */
+        T_ok = rs_ctx->rsm->state >= ecp_rsm_comb_core;
+    }
+    else
+#endif
+    /* Allocate table if we didn't have any */
+    {
+        T = mbedtls_calloc( T_size, sizeof( mbedtls_ecp_point ) );
+        if( T == NULL )
+        {
+            ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
+            goto cleanup;
+        }
+
+        for( i = 0; i < T_size; i++ )
+            mbedtls_ecp_point_init( &T[i] );
+
+        T_ok = 0;
+    }
+
+    /* Compute table (or finish computing it) if not done already */
+    if( !T_ok )
+    {
+        MBEDTLS_MPI_CHK( ecp_precompute_comb( grp, T, P, w, d, rs_ctx ) );
+
+        if( p_eq_g )
+        {
+            /* almost transfer ownership of T to the group, but keep a copy of
+             * the pointer to use for calling the next function more easily */
+            grp->T = T;
+            grp->T_size = T_size;
+        }
+    }
+
+    /* Actual comb multiplication using precomputed points */
+    MBEDTLS_MPI_CHK( ecp_mul_comb_after_precomp( grp, R, m,
+                                                 T, T_size, w, d,
+                                                 f_rng, p_rng, rs_ctx ) );
+
+cleanup:
+
+    /* does T belong to the group? */
+    if( T == grp->T )
+        T = NULL;
+
+    /* does T belong to the restart context? */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->rsm != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS && T != NULL )
+    {
+        /* transfer ownership of T from local function to rsm */
+        rs_ctx->rsm->T_size = T_size;
+        rs_ctx->rsm->T = T;
+        T = NULL;
+    }
+#endif
+
+    /* did T belong to us? then let's destroy it! */
+    if( T != NULL )
+    {
+        for( i = 0; i < T_size; i++ )
+            mbedtls_ecp_point_free( &T[i] );
+        mbedtls_free( T );
+    }
+
+    /* don't free R while in progress in case R == P */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
+#endif
+    /* prevent caller from using invalid value */
+    if( ret != 0 )
+        mbedtls_ecp_point_free( R );
+
+    ECP_RS_LEAVE( rsm );
+
+    return( ret );
+}
+
+#endif /* ECP_SHORTWEIERSTRASS */
+
+#if defined(ECP_MONTGOMERY)
+/*
+ * For Montgomery curves, we do all the internal arithmetic in projective
+ * coordinates. Import/export of points uses only the x coordinates, which is
+ * internaly represented as X / Z.
+ *
+ * For scalar multiplication, we'll use a Montgomery ladder.
+ */
+
+/*
+ * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1
+ * Cost: 1M + 1I
+ */
+static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P )
+{
+    int ret;
+
+#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
+    if( mbedtls_internal_ecp_grp_capable( grp ) )
+        return( mbedtls_internal_ecp_normalize_mxz( grp, P ) );
+#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Randomize projective x/z coordinates:
+ * (X, Z) -> (l X, l Z) for random l
+ * This is sort of the reverse operation of ecp_normalize_mxz().
+ *
+ * This countermeasure was first suggested in [2].
+ * Cost: 2M
+ */
+static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret;
+    mbedtls_mpi l;
+    size_t p_size;
+    int count = 0;
+
+#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
+    if( mbedtls_internal_ecp_grp_capable( grp ) )
+        return( mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng );
+#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */
+
+    p_size = ( grp->pbits + 7 ) / 8;
+    mbedtls_mpi_init( &l );
+
+    /* Generate l such that 1 < l < p */
+    do
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
+
+        while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 )
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) );
+
+        if( count++ > 10 )
+            return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
+    }
+    while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z );
+
+cleanup:
+    mbedtls_mpi_free( &l );
+
+    return( ret );
+}
+
+/*
+ * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q),
+ * for Montgomery curves in x/z coordinates.
+ *
+ * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3
+ * with
+ * d =  X1
+ * P = (X2, Z2)
+ * Q = (X3, Z3)
+ * R = (X4, Z4)
+ * S = (X5, Z5)
+ * and eliminating temporary variables tO, ..., t4.
+ *
+ * Cost: 5M + 4S
+ */
+static int ecp_double_add_mxz( const mbedtls_ecp_group *grp,
+                               mbedtls_ecp_point *R, mbedtls_ecp_point *S,
+                               const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q,
+                               const mbedtls_mpi *d )
+{
+    int ret;
+    mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB;
+
+#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
+    if( mbedtls_internal_ecp_grp_capable( grp ) )
+        return( mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ) );
+#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */
+
+    mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B );
+    mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C );
+    mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &A,    &P->X,   &P->Z ) ); MOD_ADD( A    );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &AA,   &A,      &A    ) ); MOD_MUL( AA   );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &B,    &P->X,   &P->Z ) ); MOD_SUB( B    );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &BB,   &B,      &B    ) ); MOD_MUL( BB   );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &E,    &AA,     &BB   ) ); MOD_SUB( E    );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &C,    &Q->X,   &Q->Z ) ); MOD_ADD( C    );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &D,    &Q->X,   &Q->Z ) ); MOD_SUB( D    );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DA,   &D,      &A    ) ); MOD_MUL( DA   );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &CB,   &C,      &B    ) ); MOD_MUL( CB   );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &S->X, &DA,     &CB   ) ); MOD_MUL( S->X );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->X, &S->X,   &S->X ) ); MOD_MUL( S->X );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S->Z, &DA,     &CB   ) ); MOD_SUB( S->Z );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, &S->Z,   &S->Z ) ); MOD_MUL( S->Z );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, d,       &S->Z ) ); MOD_MUL( S->Z );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->X, &AA,     &BB   ) ); MOD_MUL( R->X );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &grp->A, &E    ) ); MOD_MUL( R->Z );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &R->Z, &BB,     &R->Z ) ); MOD_ADD( R->Z );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &E,      &R->Z ) ); MOD_MUL( R->Z );
+
+cleanup:
+    mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B );
+    mbedtls_mpi_free( &BB ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &C );
+    mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB );
+
+    return( ret );
+}
+
+/*
+ * Multiplication with Montgomery ladder in x/z coordinates,
+ * for curves in Montgomery form
+ */
+static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+                        const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+                        int (*f_rng)(void *, unsigned char *, size_t),
+                        void *p_rng )
+{
+    int ret;
+    size_t i;
+    unsigned char b;
+    mbedtls_ecp_point RP;
+    mbedtls_mpi PX;
+
+    mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX );
+
+    /* Save PX and read from P before writing to R, in case P == R */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &RP, P ) );
+
+    /* Set R to zero in modified x/z coordinates */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->X, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) );
+    mbedtls_mpi_free( &R->Y );
+
+    /* RP.X might be sligtly larger than P, so reduce it */
+    MOD_ADD( RP.X );
+
+    /* Randomize coordinates of the starting point */
+    if( f_rng != NULL )
+        MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
+
+    /* Loop invariant: R = result so far, RP = R + P */
+    i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */
+    while( i-- > 0 )
+    {
+        b = mbedtls_mpi_get_bit( m, i );
+        /*
+         *  if (b) R = 2R + P else R = 2R,
+         * which is:
+         *  if (b) double_add( RP, R, RP, R )
+         *  else   double_add( R, RP, R, RP )
+         * but using safe conditional swaps to avoid leaks
+         */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
+        MBEDTLS_MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
+    }
+
+    MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
+
+cleanup:
+    mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX );
+
+    return( ret );
+}
+
+#endif /* ECP_MONTGOMERY */
+
+/*
+ * Restartable multiplication R = m * P
+ */
+int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+             mbedtls_ecp_restart_ctx *rs_ctx )
+{
+    int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+    char is_grp_capable = 0;
+#endif
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( R   != NULL );
+    ECP_VALIDATE_RET( m   != NULL );
+    ECP_VALIDATE_RET( P   != NULL );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    /* reset ops count for this call if top-level */
+    if( rs_ctx != NULL && rs_ctx->depth++ == 0 )
+        rs_ctx->ops_done = 0;
+#endif
+
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+    if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) )
+        MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
+#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    /* skip argument check when restarting */
+    if( rs_ctx == NULL || rs_ctx->rsm == NULL )
+#endif
+    {
+        /* check_privkey is free */
+        MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_CHK );
+
+        /* Common sanity checks */
+        MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( grp, m ) );
+        MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) );
+    }
+
+    ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+#if defined(ECP_MONTGOMERY)
+    if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+        MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) );
+#endif
+#if defined(ECP_SHORTWEIERSTRASS)
+    if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+        MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) );
+#endif
+
+cleanup:
+
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+    if( is_grp_capable )
+        mbedtls_internal_ecp_free( grp );
+#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL )
+        rs_ctx->depth--;
+#endif
+
+    return( ret );
+}
+
+/*
+ * Multiplication R = m * P
+ */
+int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( R   != NULL );
+    ECP_VALIDATE_RET( m   != NULL );
+    ECP_VALIDATE_RET( P   != NULL );
+    return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) );
+}
+
+#if defined(ECP_SHORTWEIERSTRASS)
+/*
+ * Check that an affine point is valid as a public key,
+ * short weierstrass curves (SEC1 3.2.3.1)
+ */
+static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
+{
+    int ret;
+    mbedtls_mpi YY, RHS;
+
+    /* pt coordinates must be normalized for our checks */
+    if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 ||
+        mbedtls_mpi_cmp_int( &pt->Y, 0 ) < 0 ||
+        mbedtls_mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 ||
+        mbedtls_mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 )
+        return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
+    mbedtls_mpi_init( &YY ); mbedtls_mpi_init( &RHS );
+
+    /*
+     * YY = Y^2
+     * RHS = X (X^2 + A) + B = X^3 + A X + B
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &YY,  &pt->Y,   &pt->Y  ) );  MOD_MUL( YY  );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &pt->X,   &pt->X  ) );  MOD_MUL( RHS );
+
+    /* Special case for A = -3 */
+    if( grp->A.p == NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &RHS, &RHS, 3       ) );  MOD_SUB( RHS );
+    }
+    else
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->A ) );  MOD_ADD( RHS );
+    }
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &RHS,     &pt->X  ) );  MOD_MUL( RHS );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS,     &grp->B ) );  MOD_ADD( RHS );
+
+    if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 )
+        ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+
+cleanup:
+
+    mbedtls_mpi_free( &YY ); mbedtls_mpi_free( &RHS );
+
+    return( ret );
+}
+#endif /* ECP_SHORTWEIERSTRASS */
+
+/*
+ * R = m * P with shortcuts for m == 1 and m == -1
+ * NOT constant-time - ONLY for short Weierstrass!
+ */
+static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
+                                      mbedtls_ecp_point *R,
+                                      const mbedtls_mpi *m,
+                                      const mbedtls_ecp_point *P,
+                                      mbedtls_ecp_restart_ctx *rs_ctx )
+{
+    int ret;
+
+    if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
+    }
+    else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
+        if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 )
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) );
+    }
+    else
+    {
+        MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, R, m, P,
+                                                      NULL, NULL, rs_ctx ) );
+    }
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Restartable linear combination
+ * NOT constant-time
+ */
+int mbedtls_ecp_muladd_restartable(
+             mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
+             mbedtls_ecp_restart_ctx *rs_ctx )
+{
+    int ret;
+    mbedtls_ecp_point mP;
+    mbedtls_ecp_point *pmP = &mP;
+    mbedtls_ecp_point *pR = R;
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+    char is_grp_capable = 0;
+#endif
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( R   != NULL );
+    ECP_VALIDATE_RET( m   != NULL );
+    ECP_VALIDATE_RET( P   != NULL );
+    ECP_VALIDATE_RET( n   != NULL );
+    ECP_VALIDATE_RET( Q   != NULL );
+
+    if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
+        return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+
+    mbedtls_ecp_point_init( &mP );
+
+    ECP_RS_ENTER( ma );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->ma != NULL )
+    {
+        /* redirect intermediate results to restart context */
+        pmP = &rs_ctx->ma->mP;
+        pR  = &rs_ctx->ma->R;
+
+        /* jump to next operation */
+        if( rs_ctx->ma->state == ecp_rsma_mul2 )
+            goto mul2;
+        if( rs_ctx->ma->state == ecp_rsma_add )
+            goto add;
+        if( rs_ctx->ma->state == ecp_rsma_norm )
+            goto norm;
+    }
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pmP, m, P, rs_ctx ) );
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->ma != NULL )
+        rs_ctx->ma->state = ecp_rsma_mul2;
+
+mul2:
+#endif
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pR,  n, Q, rs_ctx ) );
+
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+    if( ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) )
+        MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
+#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->ma != NULL )
+        rs_ctx->ma->state = ecp_rsma_add;
+
+add:
+#endif
+    MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_ADD );
+    MBEDTLS_MPI_CHK( ecp_add_mixed( grp, pR, pmP, pR ) );
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->ma != NULL )
+        rs_ctx->ma->state = ecp_rsma_norm;
+
+norm:
+#endif
+    MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV );
+    MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, pR ) );
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->ma != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, pR ) );
+#endif
+
+cleanup:
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+    if( is_grp_capable )
+        mbedtls_internal_ecp_free( grp );
+#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+
+    mbedtls_ecp_point_free( &mP );
+
+    ECP_RS_LEAVE( ma );
+
+    return( ret );
+}
+
+/*
+ * Linear combination
+ * NOT constant-time
+ */
+int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             const mbedtls_mpi *n, const mbedtls_ecp_point *Q )
+{
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( R   != NULL );
+    ECP_VALIDATE_RET( m   != NULL );
+    ECP_VALIDATE_RET( P   != NULL );
+    ECP_VALIDATE_RET( n   != NULL );
+    ECP_VALIDATE_RET( Q   != NULL );
+    return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) );
+}
+
+#if defined(ECP_MONTGOMERY)
+/*
+ * Check validity of a public key for Montgomery curves with x-only schemes
+ */
+static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
+{
+    /* [Curve25519 p. 5] Just check X is the correct number of bytes */
+    /* Allow any public value, if it's too big then we'll just reduce it mod p
+     * (RFC 7748 sec. 5 para. 3). */
+    if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 )
+        return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
+    return( 0 );
+}
+#endif /* ECP_MONTGOMERY */
+
+/*
+ * Check that a point is valid as a public key
+ */
+int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
+                              const mbedtls_ecp_point *pt )
+{
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( pt  != NULL );
+
+    /* Must use affine coordinates */
+    if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 )
+        return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
+#if defined(ECP_MONTGOMERY)
+    if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+        return( ecp_check_pubkey_mx( grp, pt ) );
+#endif
+#if defined(ECP_SHORTWEIERSTRASS)
+    if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+        return( ecp_check_pubkey_sw( grp, pt ) );
+#endif
+    return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+}
+
+/*
+ * Check that an mbedtls_mpi is valid as a private key
+ */
+int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
+                               const mbedtls_mpi *d )
+{
+    ECP_VALIDATE_RET( grp != NULL );
+    ECP_VALIDATE_RET( d   != NULL );
+
+#if defined(ECP_MONTGOMERY)
+    if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+    {
+        /* see RFC 7748 sec. 5 para. 5 */
+        if( mbedtls_mpi_get_bit( d, 0 ) != 0 ||
+            mbedtls_mpi_get_bit( d, 1 ) != 0 ||
+            mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */
+            return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
+        /* see [Curve25519] page 5 */
+        if( grp->nbits == 254 && mbedtls_mpi_get_bit( d, 2 ) != 0 )
+            return( MBEDTLS_ERR_ECP_INVALID_KEY );
+
+        return( 0 );
+    }
+#endif /* ECP_MONTGOMERY */
+#if defined(ECP_SHORTWEIERSTRASS)
+    if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+    {
+        /* see SEC1 3.2 */
+        if( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
+            mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
+            return( MBEDTLS_ERR_ECP_INVALID_KEY );
+        else
+            return( 0 );
+    }
+#endif /* ECP_SHORTWEIERSTRASS */
+
+    return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+}
+
+/*
+ * Generate a private key
+ */
+int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
+                     mbedtls_mpi *d,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    size_t n_size;
+
+    ECP_VALIDATE_RET( grp   != NULL );
+    ECP_VALIDATE_RET( d     != NULL );
+    ECP_VALIDATE_RET( f_rng != NULL );
+
+    n_size = ( grp->nbits + 7 ) / 8;
+
+#if defined(ECP_MONTGOMERY)
+    if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+    {
+        /* [M225] page 5 */
+        size_t b;
+
+        do {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
+        } while( mbedtls_mpi_bitlen( d ) == 0);
+
+        /* Make sure the most significant bit is nbits */
+        b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
+        if( b > grp->nbits )
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) );
+        else
+            MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) );
+
+        /* Make sure the last two bits are unset for Curve448, three bits for
+           Curve25519 */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
+        if( grp->nbits == 254 )
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
+        }
+    }
+#endif /* ECP_MONTGOMERY */
+
+#if defined(ECP_SHORTWEIERSTRASS)
+    if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+    {
+        /* SEC1 3.2.1: Generate d such that 1 <= n < N */
+        int count = 0;
+
+        /*
+         * Match the procedure given in RFC 6979 (deterministic ECDSA):
+         * - use the same byte ordering;
+         * - keep the leftmost nbits bits of the generated octet string;
+         * - try until result is in the desired range.
+         * This also avoids any biais, which is especially important for ECDSA.
+         */
+        do
+        {
+            MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
+
+            /*
+             * Each try has at worst a probability 1/2 of failing (the msb has
+             * a probability 1/2 of being 0, and then the result will be < N),
+             * so after 30 tries failure probability is a most 2**(-30).
+             *
+             * For most curves, 1 try is enough with overwhelming probability,
+             * since N starts with a lot of 1s in binary, but some curves
+             * such as secp224k1 are actually very close to the worst case.
+             */
+            if( ++count > 30 )
+                return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
+        }
+        while( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
+               mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 );
+    }
+#endif /* ECP_SHORTWEIERSTRASS */
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Generate a keypair with configurable base point
+ */
+int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
+                     const mbedtls_ecp_point *G,
+                     mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret;
+    ECP_VALIDATE_RET( grp   != NULL );
+    ECP_VALIDATE_RET( d     != NULL );
+    ECP_VALIDATE_RET( G     != NULL );
+    ECP_VALIDATE_RET( Q     != NULL );
+    ECP_VALIDATE_RET( f_rng != NULL );
+
+    MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Generate key pair, wrapper for conventional base point
+ */
+int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp,
+                             mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                             int (*f_rng)(void *, unsigned char *, size_t),
+                             void *p_rng )
+{
+    ECP_VALIDATE_RET( grp   != NULL );
+    ECP_VALIDATE_RET( d     != NULL );
+    ECP_VALIDATE_RET( Q     != NULL );
+    ECP_VALIDATE_RET( f_rng != NULL );
+
+    return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) );
+}
+
+/*
+ * Generate a keypair, prettier wrapper
+ */
+int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret;
+    ECP_VALIDATE_RET( key   != NULL );
+    ECP_VALIDATE_RET( f_rng != NULL );
+
+    if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
+        return( ret );
+
+    return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) );
+}
+
+/*
+ * Check a public-private key pair
+ */
+int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv )
+{
+    int ret;
+    mbedtls_ecp_point Q;
+    mbedtls_ecp_group grp;
+    ECP_VALIDATE_RET( pub != NULL );
+    ECP_VALIDATE_RET( prv != NULL );
+
+    if( pub->grp.id == MBEDTLS_ECP_DP_NONE ||
+        pub->grp.id != prv->grp.id ||
+        mbedtls_mpi_cmp_mpi( &pub->Q.X, &prv->Q.X ) ||
+        mbedtls_mpi_cmp_mpi( &pub->Q.Y, &prv->Q.Y ) ||
+        mbedtls_mpi_cmp_mpi( &pub->Q.Z, &prv->Q.Z ) )
+    {
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+
+    mbedtls_ecp_point_init( &Q );
+    mbedtls_ecp_group_init( &grp );
+
+    /* mbedtls_ecp_mul() needs a non-const group... */
+    mbedtls_ecp_group_copy( &grp, &prv->grp );
+
+    /* Also checks d is valid */
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) );
+
+    if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) ||
+        mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) ||
+        mbedtls_mpi_cmp_mpi( &Q.Z, &prv->Q.Z ) )
+    {
+        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+cleanup:
+    mbedtls_ecp_point_free( &Q );
+    mbedtls_ecp_group_free( &grp );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/*
+ * Checkup routine
+ */
+int mbedtls_ecp_self_test( int verbose )
+{
+    int ret;
+    size_t i;
+    mbedtls_ecp_group grp;
+    mbedtls_ecp_point R, P;
+    mbedtls_mpi m;
+    unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
+    /* exponents especially adapted for secp192r1 */
+    const char *exponents[] =
+    {
+        "000000000000000000000000000000000000000000000001", /* one */
+        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */
+        "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */
+        "400000000000000000000000000000000000000000000000", /* one and zeros */
+        "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */
+        "555555555555555555555555555555555555555555555555", /* 101010... */
+    };
+
+    mbedtls_ecp_group_init( &grp );
+    mbedtls_ecp_point_init( &R );
+    mbedtls_ecp_point_init( &P );
+    mbedtls_mpi_init( &m );
+
+    /* Use secp192r1 if available, or any available curve */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+    MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) );
+#else
+    MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, mbedtls_ecp_curve_list()->grp_id ) );
+#endif
+
+    if( verbose != 0 )
+        mbedtls_printf( "  ECP test #1 (constant op_count, base point G): " );
+
+    /* Do a dummy multiplication first to trigger precomputation */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
+
+    add_count = 0;
+    dbl_count = 0;
+    mul_count = 0;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
+
+    for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
+    {
+        add_c_prev = add_count;
+        dbl_c_prev = dbl_count;
+        mul_c_prev = mul_count;
+        add_count = 0;
+        dbl_count = 0;
+        mul_count = 0;
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
+        MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
+
+        if( add_count != add_c_prev ||
+            dbl_count != dbl_c_prev ||
+            mul_count != mul_c_prev )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed (%u)\n", (unsigned int) i );
+
+            ret = 1;
+            goto cleanup;
+        }
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  ECP test #2 (constant op_count, other point): " );
+    /* We computed P = 2G last time, use it */
+
+    add_count = 0;
+    dbl_count = 0;
+    mul_count = 0;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
+    MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
+
+    for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
+    {
+        add_c_prev = add_count;
+        dbl_c_prev = dbl_count;
+        mul_c_prev = mul_count;
+        add_count = 0;
+        dbl_count = 0;
+        mul_count = 0;
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
+        MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
+
+        if( add_count != add_c_prev ||
+            dbl_count != dbl_c_prev ||
+            mul_count != mul_c_prev )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed (%u)\n", (unsigned int) i );
+
+            ret = 1;
+            goto cleanup;
+        }
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+cleanup:
+
+    if( ret < 0 && verbose != 0 )
+        mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
+
+    mbedtls_ecp_group_free( &grp );
+    mbedtls_ecp_point_free( &R );
+    mbedtls_ecp_point_free( &P );
+    mbedtls_mpi_free( &m );
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* !MBEDTLS_ECP_ALT */
+
+#endif /* MBEDTLS_ECP_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecp_curves.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecp_curves.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ecp_curves.c	(revision 398)
@@ -0,0 +1,1468 @@
+/*
+ *  Elliptic curves over GF(p): curve-specific data and functions
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+
+#include "mbedtls/ecp.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if !defined(MBEDTLS_ECP_ALT)
+
+/* Parameter validation macros based on platform_util.h */
+#define ECP_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
+#define ECP_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+/*
+ * Conversion macros for embedded constants:
+ * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
+ */
+#if defined(MBEDTLS_HAVE_INT32)
+
+#define BYTES_TO_T_UINT_4( a, b, c, d )             \
+    ( (mbedtls_mpi_uint) a <<  0 ) |                          \
+    ( (mbedtls_mpi_uint) b <<  8 ) |                          \
+    ( (mbedtls_mpi_uint) c << 16 ) |                          \
+    ( (mbedtls_mpi_uint) d << 24 )
+
+#define BYTES_TO_T_UINT_2( a, b )                   \
+    BYTES_TO_T_UINT_4( a, b, 0, 0 )
+
+#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
+    BYTES_TO_T_UINT_4( a, b, c, d ),                \
+    BYTES_TO_T_UINT_4( e, f, g, h )
+
+#else /* 64-bits */
+
+#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
+    ( (mbedtls_mpi_uint) a <<  0 ) |                          \
+    ( (mbedtls_mpi_uint) b <<  8 ) |                          \
+    ( (mbedtls_mpi_uint) c << 16 ) |                          \
+    ( (mbedtls_mpi_uint) d << 24 ) |                          \
+    ( (mbedtls_mpi_uint) e << 32 ) |                          \
+    ( (mbedtls_mpi_uint) f << 40 ) |                          \
+    ( (mbedtls_mpi_uint) g << 48 ) |                          \
+    ( (mbedtls_mpi_uint) h << 56 )
+
+#define BYTES_TO_T_UINT_4( a, b, c, d )             \
+    BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
+
+#define BYTES_TO_T_UINT_2( a, b )                   \
+    BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
+
+#endif /* bits in mbedtls_mpi_uint */
+
+/*
+ * Note: the constants are in little-endian order
+ * to be directly usable in MPIs
+ */
+
+/*
+ * Domain parameters for secp192r1
+ */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+static const mbedtls_mpi_uint secp192r1_p[] = {
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp192r1_b[] = {
+    BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
+    BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
+    BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
+};
+static const mbedtls_mpi_uint secp192r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
+    BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
+};
+static const mbedtls_mpi_uint secp192r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
+    BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
+    BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
+};
+static const mbedtls_mpi_uint secp192r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
+    BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
+
+/*
+ * Domain parameters for secp224r1
+ */
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+static const mbedtls_mpi_uint secp224r1_p[] = {
+    BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224r1_b[] = {
+    BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
+    BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
+    BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
+    BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
+};
+static const mbedtls_mpi_uint secp224r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
+    BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
+    BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
+    BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
+};
+static const mbedtls_mpi_uint secp224r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
+    BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
+    BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
+    BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
+};
+static const mbedtls_mpi_uint secp224r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
+    BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
+
+/*
+ * Domain parameters for secp256r1
+ */
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+static const mbedtls_mpi_uint secp256r1_p[] = {
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp256r1_b[] = {
+    BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
+    BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
+    BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
+    BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
+};
+static const mbedtls_mpi_uint secp256r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
+    BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
+    BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
+    BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
+};
+static const mbedtls_mpi_uint secp256r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
+    BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
+    BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
+    BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
+};
+static const mbedtls_mpi_uint secp256r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
+    BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+
+/*
+ * Domain parameters for secp384r1
+ */
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+static const mbedtls_mpi_uint secp384r1_p[] = {
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp384r1_b[] = {
+    BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
+    BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
+    BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
+    BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
+    BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
+    BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
+};
+static const mbedtls_mpi_uint secp384r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
+    BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
+    BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
+    BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
+    BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
+    BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
+};
+static const mbedtls_mpi_uint secp384r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
+    BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
+    BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
+    BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
+    BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
+    BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
+};
+static const mbedtls_mpi_uint secp384r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
+    BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
+    BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
+/*
+ * Domain parameters for secp521r1
+ */
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+static const mbedtls_mpi_uint secp521r1_p[] = {
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
+};
+static const mbedtls_mpi_uint secp521r1_b[] = {
+    BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
+    BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
+    BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
+    BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
+    BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
+    BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
+    BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
+    BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
+    BYTES_TO_T_UINT_2( 0x51, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
+    BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
+    BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
+    BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
+    BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
+    BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
+    BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
+    BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
+    BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
+};
+static const mbedtls_mpi_uint secp521r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
+    BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
+    BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
+    BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
+    BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
+    BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
+    BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
+    BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
+    BYTES_TO_T_UINT_2( 0x18, 0x01 ),
+};
+static const mbedtls_mpi_uint secp521r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
+    BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
+    BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
+    BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
+    BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
+};
+#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+static const mbedtls_mpi_uint secp192k1_p[] = {
+    BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp192k1_a[] = {
+    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp192k1_b[] = {
+    BYTES_TO_T_UINT_2( 0x03, 0x00 ),
+};
+static const mbedtls_mpi_uint secp192k1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
+    BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
+    BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
+};
+static const mbedtls_mpi_uint secp192k1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
+    BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
+    BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
+};
+static const mbedtls_mpi_uint secp192k1_n[] = {
+    BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
+    BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+static const mbedtls_mpi_uint secp224k1_p[] = {
+    BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp224k1_a[] = {
+    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_b[] = {
+    BYTES_TO_T_UINT_2( 0x05, 0x00 ),
+};
+static const mbedtls_mpi_uint secp224k1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
+    BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
+    BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
+    BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
+};
+static const mbedtls_mpi_uint secp224k1_gy[] = {
+    BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
+    BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
+    BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
+    BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
+};
+static const mbedtls_mpi_uint secp224k1_n[] = {
+    BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
+    BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
+    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
+};
+#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+static const mbedtls_mpi_uint secp256k1_p[] = {
+    BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+static const mbedtls_mpi_uint secp256k1_a[] = {
+    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
+};
+static const mbedtls_mpi_uint secp256k1_b[] = {
+    BYTES_TO_T_UINT_2( 0x07, 0x00 ),
+};
+static const mbedtls_mpi_uint secp256k1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
+    BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
+    BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
+    BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
+};
+static const mbedtls_mpi_uint secp256k1_gy[] = {
+    BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
+    BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
+    BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
+    BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
+};
+static const mbedtls_mpi_uint secp256k1_n[] = {
+    BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
+    BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
+    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
+};
+#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
+
+/*
+ * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
+ */
+#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
+    BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
+    BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
+    BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
+    BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
+    BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
+    BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
+    BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
+    BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
+    BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
+    BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
+    BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
+    BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
+    BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
+    BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
+    BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
+    BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
+    BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
+    BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
+};
+static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
+    BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
+    BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
+    BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
+    BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
+};
+#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
+
+/*
+ * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
+ */
+#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
+    BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
+    BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
+    BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
+    BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
+    BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
+    BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
+    BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
+    BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
+    BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
+    BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
+    BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
+    BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
+    BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
+    BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
+    BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
+    BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
+    BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
+    BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
+    BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
+    BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
+    BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
+    BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
+    BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
+    BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
+    BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
+    BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
+    BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
+    BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
+};
+static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
+    BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
+    BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
+    BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
+    BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
+    BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
+};
+#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
+
+/*
+ * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
+ */
+#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
+    BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
+    BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
+    BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
+    BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
+    BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
+    BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
+    BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
+    BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
+    BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
+    BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
+    BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
+    BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
+    BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
+    BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
+    BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
+    BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
+    BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
+    BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
+    BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
+    BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
+    BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
+    BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
+    BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
+    BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
+    BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
+    BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
+    BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
+    BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
+    BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
+    BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
+    BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
+    BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
+    BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
+    BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
+    BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
+    BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
+    BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
+    BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
+    BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
+    BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
+};
+static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
+    BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
+    BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
+    BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
+    BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
+    BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
+    BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
+    BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
+    BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
+};
+#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
+
+/*
+ * Create an MPI from embedded constants
+ * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
+ */
+static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len )
+{
+    X->s = 1;
+    X->n = len / sizeof( mbedtls_mpi_uint );
+    X->p = (mbedtls_mpi_uint *) p;
+}
+
+/*
+ * Set an MPI to static value 1
+ */
+static inline void ecp_mpi_set1( mbedtls_mpi *X )
+{
+    static mbedtls_mpi_uint one[] = { 1 };
+    X->s = 1;
+    X->n = 1;
+    X->p = one;
+}
+
+/*
+ * Make group available from embedded constants
+ */
+static int ecp_group_load( mbedtls_ecp_group *grp,
+                           const mbedtls_mpi_uint *p,  size_t plen,
+                           const mbedtls_mpi_uint *a,  size_t alen,
+                           const mbedtls_mpi_uint *b,  size_t blen,
+                           const mbedtls_mpi_uint *gx, size_t gxlen,
+                           const mbedtls_mpi_uint *gy, size_t gylen,
+                           const mbedtls_mpi_uint *n,  size_t nlen)
+{
+    ecp_mpi_load( &grp->P, p, plen );
+    if( a != NULL )
+        ecp_mpi_load( &grp->A, a, alen );
+    ecp_mpi_load( &grp->B, b, blen );
+    ecp_mpi_load( &grp->N, n, nlen );
+
+    ecp_mpi_load( &grp->G.X, gx, gxlen );
+    ecp_mpi_load( &grp->G.Y, gy, gylen );
+    ecp_mpi_set1( &grp->G.Z );
+
+    grp->pbits = mbedtls_mpi_bitlen( &grp->P );
+    grp->nbits = mbedtls_mpi_bitlen( &grp->N );
+
+    grp->h = 1;
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_ECP_NIST_OPTIM)
+/* Forward declarations */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+static int ecp_mod_p192( mbedtls_mpi * );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+static int ecp_mod_p224( mbedtls_mpi * );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+static int ecp_mod_p256( mbedtls_mpi * );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+static int ecp_mod_p384( mbedtls_mpi * );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+static int ecp_mod_p521( mbedtls_mpi * );
+#endif
+
+#define NIST_MODP( P )      grp->modp = ecp_mod_ ## P;
+#else
+#define NIST_MODP( P )
+#endif /* MBEDTLS_ECP_NIST_OPTIM */
+
+/* Additional forward declarations */
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+static int ecp_mod_p255( mbedtls_mpi * );
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+static int ecp_mod_p448( mbedtls_mpi * );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+static int ecp_mod_p192k1( mbedtls_mpi * );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+static int ecp_mod_p224k1( mbedtls_mpi * );
+#endif
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+static int ecp_mod_p256k1( mbedtls_mpi * );
+#endif
+
+#define LOAD_GROUP_A( G )   ecp_group_load( grp,            \
+                            G ## _p,  sizeof( G ## _p  ),   \
+                            G ## _a,  sizeof( G ## _a  ),   \
+                            G ## _b,  sizeof( G ## _b  ),   \
+                            G ## _gx, sizeof( G ## _gx ),   \
+                            G ## _gy, sizeof( G ## _gy ),   \
+                            G ## _n,  sizeof( G ## _n  ) )
+
+#define LOAD_GROUP( G )     ecp_group_load( grp,            \
+                            G ## _p,  sizeof( G ## _p  ),   \
+                            NULL,     0,                    \
+                            G ## _b,  sizeof( G ## _b  ),   \
+                            G ## _gx, sizeof( G ## _gx ),   \
+                            G ## _gy, sizeof( G ## _gy ),   \
+                            G ## _n,  sizeof( G ## _n  ) )
+
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+/*
+ * Specialized function for creating the Curve25519 group
+ */
+static int ecp_use_curve25519( mbedtls_ecp_group *grp )
+{
+    int ret;
+
+    /* Actually ( A + 2 ) / 4 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "01DB42" ) );
+
+    /* P = 2^255 - 19 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) );
+    grp->pbits = mbedtls_mpi_bitlen( &grp->P );
+
+    /* N = 2^252 + 27742317777372353535851937790883648493 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->N, 16,
+                                              "14DEF9DEA2F79CD65812631A5CF5D3ED" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) );
+
+    /* Y intentionally not set, since we use x/z coordinates.
+     * This is used as a marker to identify Montgomery curves! */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
+    mbedtls_mpi_free( &grp->G.Y );
+
+    /* Actually, the required msb for private keys */
+    grp->nbits = 254;
+
+cleanup:
+    if( ret != 0 )
+        mbedtls_ecp_group_free( grp );
+
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+/*
+ * Specialized function for creating the Curve448 group
+ */
+static int ecp_use_curve448( mbedtls_ecp_group *grp )
+{
+    mbedtls_mpi Ns;
+    int ret;
+
+    mbedtls_mpi_init( &Ns );
+
+    /* Actually ( A + 2 ) / 4 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "98AA" ) );
+
+    /* P = 2^448 - 2^224 - 1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
+    grp->pbits = mbedtls_mpi_bitlen( &grp->P );
+
+    /* Y intentionally not set, since we use x/z coordinates.
+     * This is used as a marker to identify Montgomery curves! */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
+    mbedtls_mpi_free( &grp->G.Y );
+
+    /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &Ns, 16,
+                                              "8335DC163BB124B65129C96FDE933D8D723A70AADC873D6D54A7BB0D" ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
+
+    /* Actually, the required msb for private keys */
+    grp->nbits = 447;
+
+cleanup:
+    mbedtls_mpi_free( &Ns );
+    if( ret != 0 )
+        mbedtls_ecp_group_free( grp );
+
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
+
+/*
+ * Set a group using well-known domain parameters
+ */
+int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
+{
+    ECP_VALIDATE_RET( grp != NULL );
+    mbedtls_ecp_group_free( grp );
+
+    grp->id = id;
+
+    switch( id )
+    {
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP192R1:
+            NIST_MODP( p192 );
+            return( LOAD_GROUP( secp192r1 ) );
+#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP224R1:
+            NIST_MODP( p224 );
+            return( LOAD_GROUP( secp224r1 ) );
+#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP256R1:
+            NIST_MODP( p256 );
+            return( LOAD_GROUP( secp256r1 ) );
+#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP384R1:
+            NIST_MODP( p384 );
+            return( LOAD_GROUP( secp384r1 ) );
+#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP521R1:
+            NIST_MODP( p521 );
+            return( LOAD_GROUP( secp521r1 ) );
+#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP192K1:
+            grp->modp = ecp_mod_p192k1;
+            return( LOAD_GROUP_A( secp192k1 ) );
+#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP224K1:
+            grp->modp = ecp_mod_p224k1;
+            return( LOAD_GROUP_A( secp224k1 ) );
+#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+        case MBEDTLS_ECP_DP_SECP256K1:
+            grp->modp = ecp_mod_p256k1;
+            return( LOAD_GROUP_A( secp256k1 ) );
+#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+        case MBEDTLS_ECP_DP_BP256R1:
+            return( LOAD_GROUP_A( brainpoolP256r1 ) );
+#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+        case MBEDTLS_ECP_DP_BP384R1:
+            return( LOAD_GROUP_A( brainpoolP384r1 ) );
+#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+        case MBEDTLS_ECP_DP_BP512R1:
+            return( LOAD_GROUP_A( brainpoolP512r1 ) );
+#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+        case MBEDTLS_ECP_DP_CURVE25519:
+            grp->modp = ecp_mod_p255;
+            return( ecp_use_curve25519( grp ) );
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+        case MBEDTLS_ECP_DP_CURVE448:
+            grp->modp = ecp_mod_p448;
+            return( ecp_use_curve448( grp ) );
+#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
+
+        default:
+            mbedtls_ecp_group_free( grp );
+            return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+    }
+}
+
+#if defined(MBEDTLS_ECP_NIST_OPTIM)
+/*
+ * Fast reduction modulo the primes used by the NIST curves.
+ *
+ * These functions are critical for speed, but not needed for correct
+ * operations. So, we make the choice to heavily rely on the internals of our
+ * bignum library, which creates a tight coupling between these functions and
+ * our MPI implementation.  However, the coupling between the ECP module and
+ * MPI remains loose, since these functions can be deactivated at will.
+ */
+
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+/*
+ * Compared to the way things are presented in FIPS 186-3 D.2,
+ * we proceed in columns, from right (least significant chunk) to left,
+ * adding chunks to N in place, and keeping a carry for the next chunk.
+ * This avoids moving things around in memory, and uselessly adding zeros,
+ * compared to the more straightforward, line-oriented approach.
+ *
+ * For this prime we need to handle data in chunks of 64 bits.
+ * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
+ * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it.
+ */
+
+/* Add 64-bit chunks (dst += src) and update carry */
+static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
+{
+    unsigned char i;
+    mbedtls_mpi_uint c = 0;
+    for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
+    {
+        *dst += c;      c  = ( *dst < c );
+        *dst += *src;   c += ( *dst < *src );
+    }
+    *carry += c;
+}
+
+/* Add carry to a 64-bit chunk and update carry */
+static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
+{
+    unsigned char i;
+    for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
+    {
+        *dst += *carry;
+        *carry  = ( *dst < *carry );
+    }
+}
+
+#define WIDTH       8 / sizeof( mbedtls_mpi_uint )
+#define A( i )      N->p + i * WIDTH
+#define ADD( i )    add64( p, A( i ), &c )
+#define NEXT        p += WIDTH; carry64( p, &c )
+#define LAST        p += WIDTH; *p = c; while( ++p < end ) *p = 0
+
+/*
+ * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
+ */
+static int ecp_mod_p192( mbedtls_mpi *N )
+{
+    int ret;
+    mbedtls_mpi_uint c = 0;
+    mbedtls_mpi_uint *p, *end;
+
+    /* Make sure we have enough blocks so that A(5) is legal */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
+
+    p = N->p;
+    end = p + N->n;
+
+    ADD( 3 ); ADD( 5 );             NEXT; // A0 += A3 + A5
+    ADD( 3 ); ADD( 4 ); ADD( 5 );   NEXT; // A1 += A3 + A4 + A5
+    ADD( 4 ); ADD( 5 );             LAST; // A2 += A4 + A5
+
+cleanup:
+    return( ret );
+}
+
+#undef WIDTH
+#undef A
+#undef ADD
+#undef NEXT
+#undef LAST
+#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+/*
+ * The reader is advised to first understand ecp_mod_p192() since the same
+ * general structure is used here, but with additional complications:
+ * (1) chunks of 32 bits, and (2) subtractions.
+ */
+
+/*
+ * For these primes, we need to handle data in chunks of 32 bits.
+ * This makes it more complicated if we use 64 bits limbs in MPI,
+ * which prevents us from using a uniform access method as for p192.
+ *
+ * So, we define a mini abstraction layer to access 32 bit chunks,
+ * load them in 'cur' for work, and store them back from 'cur' when done.
+ *
+ * While at it, also define the size of N in terms of 32-bit chunks.
+ */
+#define LOAD32      cur = A( i );
+
+#if defined(MBEDTLS_HAVE_INT32)  /* 32 bit */
+
+#define MAX32       N->n
+#define A( j )      N->p[j]
+#define STORE32     N->p[i] = cur;
+
+#else                               /* 64-bit */
+
+#define MAX32       N->n * 2
+#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] )
+#define STORE32                                   \
+    if( i % 2 ) {                                 \
+        N->p[i/2] &= 0x00000000FFFFFFFF;          \
+        N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32;        \
+    } else {                                      \
+        N->p[i/2] &= 0xFFFFFFFF00000000;          \
+        N->p[i/2] |= (mbedtls_mpi_uint) cur;                \
+    }
+
+#endif /* sizeof( mbedtls_mpi_uint ) */
+
+/*
+ * Helpers for addition and subtraction of chunks, with signed carry.
+ */
+static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
+{
+    *dst += src;
+    *carry += ( *dst < src );
+}
+
+static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
+{
+    *carry -= ( *dst < src );
+    *dst -= src;
+}
+
+#define ADD( j )    add32( &cur, A( j ), &c );
+#define SUB( j )    sub32( &cur, A( j ), &c );
+
+/*
+ * Helpers for the main 'loop'
+ * (see fix_negative for the motivation of C)
+ */
+#define INIT( b )                                           \
+    int ret;                                                \
+    signed char c = 0, cc;                                  \
+    uint32_t cur;                                           \
+    size_t i = 0, bits = b;                                 \
+    mbedtls_mpi C;                                                  \
+    mbedtls_mpi_uint Cp[ b / 8 / sizeof( mbedtls_mpi_uint) + 1 ];               \
+                                                            \
+    C.s = 1;                                                \
+    C.n = b / 8 / sizeof( mbedtls_mpi_uint) + 1;                      \
+    C.p = Cp;                                               \
+    memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) );                \
+                                                            \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, b * 2 / 8 / sizeof( mbedtls_mpi_uint ) ) ); \
+    LOAD32;
+
+#define NEXT                    \
+    STORE32; i++; LOAD32;       \
+    cc = c; c = 0;              \
+    if( cc < 0 )                \
+        sub32( &cur, -cc, &c ); \
+    else                        \
+        add32( &cur, cc, &c );  \
+
+#define LAST                                    \
+    STORE32; i++;                               \
+    cur = c > 0 ? c : 0; STORE32;               \
+    cur = 0; while( ++i < MAX32 ) { STORE32; }  \
+    if( c < 0 ) fix_negative( N, c, &C, bits );
+
+/*
+ * If the result is negative, we get it in the form
+ * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits'
+ */
+static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits )
+{
+    int ret;
+
+    /* C = - c * 2^(bits + 32) */
+#if !defined(MBEDTLS_HAVE_INT64)
+    ((void) bits);
+#else
+    if( bits == 224 )
+        C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32;
+    else
+#endif
+        C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c;
+
+    /* N = - ( C - N ) */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) );
+    N->s = -1;
+
+cleanup:
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+/*
+ * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
+ */
+static int ecp_mod_p224( mbedtls_mpi *N )
+{
+    INIT( 224 );
+
+    SUB(  7 ); SUB( 11 );               NEXT; // A0 += -A7 - A11
+    SUB(  8 ); SUB( 12 );               NEXT; // A1 += -A8 - A12
+    SUB(  9 ); SUB( 13 );               NEXT; // A2 += -A9 - A13
+    SUB( 10 ); ADD(  7 ); ADD( 11 );    NEXT; // A3 += -A10 + A7 + A11
+    SUB( 11 ); ADD(  8 ); ADD( 12 );    NEXT; // A4 += -A11 + A8 + A12
+    SUB( 12 ); ADD(  9 ); ADD( 13 );    NEXT; // A5 += -A12 + A9 + A13
+    SUB( 13 ); ADD( 10 );               LAST; // A6 += -A13 + A10
+
+cleanup:
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+/*
+ * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
+ */
+static int ecp_mod_p256( mbedtls_mpi *N )
+{
+    INIT( 256 );
+
+    ADD(  8 ); ADD(  9 );
+    SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 );             NEXT; // A0
+
+    ADD(  9 ); ADD( 10 );
+    SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 );             NEXT; // A1
+
+    ADD( 10 ); ADD( 11 );
+    SUB( 13 ); SUB( 14 ); SUB( 15 );                        NEXT; // A2
+
+    ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
+    SUB( 15 ); SUB(  8 ); SUB(  9 );                        NEXT; // A3
+
+    ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
+    SUB(  9 ); SUB( 10 );                                   NEXT; // A4
+
+    ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
+    SUB( 10 ); SUB( 11 );                                   NEXT; // A5
+
+    ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
+    SUB(  8 ); SUB(  9 );                                   NEXT; // A6
+
+    ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
+    SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 );             LAST; // A7
+
+cleanup:
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+/*
+ * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
+ */
+static int ecp_mod_p384( mbedtls_mpi *N )
+{
+    INIT( 384 );
+
+    ADD( 12 ); ADD( 21 ); ADD( 20 );
+    SUB( 23 );                                              NEXT; // A0
+
+    ADD( 13 ); ADD( 22 ); ADD( 23 );
+    SUB( 12 ); SUB( 20 );                                   NEXT; // A2
+
+    ADD( 14 ); ADD( 23 );
+    SUB( 13 ); SUB( 21 );                                   NEXT; // A2
+
+    ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
+    SUB( 14 ); SUB( 22 ); SUB( 23 );                        NEXT; // A3
+
+    ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
+    SUB( 15 ); SUB( 23 ); SUB( 23 );                        NEXT; // A4
+
+    ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
+    SUB( 16 );                                              NEXT; // A5
+
+    ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
+    SUB( 17 );                                              NEXT; // A6
+
+    ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
+    SUB( 18 );                                              NEXT; // A7
+
+    ADD( 20 ); ADD( 17 ); ADD( 16 );
+    SUB( 19 );                                              NEXT; // A8
+
+    ADD( 21 ); ADD( 18 ); ADD( 17 );
+    SUB( 20 );                                              NEXT; // A9
+
+    ADD( 22 ); ADD( 19 ); ADD( 18 );
+    SUB( 21 );                                              NEXT; // A10
+
+    ADD( 23 ); ADD( 20 ); ADD( 19 );
+    SUB( 22 );                                              LAST; // A11
+
+cleanup:
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
+#undef A
+#undef LOAD32
+#undef STORE32
+#undef MAX32
+#undef INIT
+#undef NEXT
+#undef LAST
+
+#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
+          MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
+          MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+/*
+ * Here we have an actual Mersenne prime, so things are more straightforward.
+ * However, chunks are aligned on a 'weird' boundary (521 bits).
+ */
+
+/* Size of p521 in terms of mbedtls_mpi_uint */
+#define P521_WIDTH      ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
+
+/* Bits to keep in the most significant mbedtls_mpi_uint */
+#define P521_MASK       0x01FF
+
+/*
+ * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
+ * Write N as A1 + 2^521 A0, return A0 + A1
+ */
+static int ecp_mod_p521( mbedtls_mpi *N )
+{
+    int ret;
+    size_t i;
+    mbedtls_mpi M;
+    mbedtls_mpi_uint Mp[P521_WIDTH + 1];
+    /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
+     * we need to hold bits 513 to 1056, which is 34 limbs, that is
+     * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
+
+    if( N->n < P521_WIDTH )
+        return( 0 );
+
+    /* M = A1 */
+    M.s = 1;
+    M.n = N->n - ( P521_WIDTH - 1 );
+    if( M.n > P521_WIDTH + 1 )
+        M.n = P521_WIDTH + 1;
+    M.p = Mp;
+    memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
+
+    /* N = A0 */
+    N->p[P521_WIDTH - 1] &= P521_MASK;
+    for( i = P521_WIDTH; i < N->n; i++ )
+        N->p[i] = 0;
+
+    /* N = A0 + A1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
+
+cleanup:
+    return( ret );
+}
+
+#undef P521_WIDTH
+#undef P521_MASK
+#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
+
+#endif /* MBEDTLS_ECP_NIST_OPTIM */
+
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+
+/* Size of p255 in terms of mbedtls_mpi_uint */
+#define P255_WIDTH      ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
+
+/*
+ * Fast quasi-reduction modulo p255 = 2^255 - 19
+ * Write N as A0 + 2^255 A1, return A0 + 19 * A1
+ */
+static int ecp_mod_p255( mbedtls_mpi *N )
+{
+    int ret;
+    size_t i;
+    mbedtls_mpi M;
+    mbedtls_mpi_uint Mp[P255_WIDTH + 2];
+
+    if( N->n < P255_WIDTH )
+        return( 0 );
+
+    /* M = A1 */
+    M.s = 1;
+    M.n = N->n - ( P255_WIDTH - 1 );
+    if( M.n > P255_WIDTH + 1 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    M.p = Mp;
+    memset( Mp, 0, sizeof Mp );
+    memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
+    M.n++; /* Make room for multiplication by 19 */
+
+    /* N = A0 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
+    for( i = P255_WIDTH; i < N->n; i++ )
+        N->p[i] = 0;
+
+    /* N = A0 + 19 * A1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
+
+cleanup:
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+
+/* Size of p448 in terms of mbedtls_mpi_uint */
+#define P448_WIDTH      ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
+
+/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
+#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
+#define P224_WIDTH_MIN   ( 28 / sizeof( mbedtls_mpi_uint ) )
+#define P224_WIDTH_MAX   DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
+#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
+
+/*
+ * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
+ * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
+ * A0 + A1 + B1 + (B0 + B1) * 2^224.  This is different to the reference
+ * implementation of Curve448, which uses its own special 56-bit limbs rather
+ * than a generic bignum library.  We could squeeze some extra speed out on
+ * 32-bit machines by splitting N up into 32-bit limbs and doing the
+ * arithmetic using the limbs directly as we do for the NIST primes above,
+ * but for 64-bit targets it should use half the number of operations if we do
+ * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
+ */
+static int ecp_mod_p448( mbedtls_mpi *N )
+{
+    int ret;
+    size_t i;
+    mbedtls_mpi M, Q;
+    mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
+
+    if( N->n <= P448_WIDTH )
+        return( 0 );
+
+    /* M = A1 */
+    M.s = 1;
+    M.n = N->n - ( P448_WIDTH );
+    if( M.n > P448_WIDTH )
+        /* Shouldn't be called with N larger than 2^896! */
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    M.p = Mp;
+    memset( Mp, 0, sizeof( Mp ) );
+    memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
+
+    /* N = A0 */
+    for( i = P448_WIDTH; i < N->n; i++ )
+        N->p[i] = 0;
+
+    /* N += A1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
+
+    /* Q = B1, N += B1 */
+    Q = M;
+    Q.p = Qp;
+    memcpy( Qp, Mp, sizeof( Qp ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
+
+    /* M = (B0 + B1) * 2^224, N += M */
+    if( sizeof( mbedtls_mpi_uint ) > 4 )
+        Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
+    for( i = P224_WIDTH_MAX; i < M.n; ++i )
+        Mp[i] = 0;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
+    M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
+
+cleanup:
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+/*
+ * Fast quasi-reduction modulo P = 2^s - R,
+ * with R about 33 bits, used by the Koblitz curves.
+ *
+ * Write N as A0 + 2^224 A1, return A0 + R * A1.
+ * Actually do two passes, since R is big.
+ */
+#define P_KOBLITZ_MAX   ( 256 / 8 / sizeof( mbedtls_mpi_uint ) )  // Max limbs in P
+#define P_KOBLITZ_R     ( 8 / sizeof( mbedtls_mpi_uint ) )        // Limbs in R
+static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
+                                   size_t adjust, size_t shift, mbedtls_mpi_uint mask )
+{
+    int ret;
+    size_t i;
+    mbedtls_mpi M, R;
+    mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
+
+    if( N->n < p_limbs )
+        return( 0 );
+
+    /* Init R */
+    R.s = 1;
+    R.p = Rp;
+    R.n = P_KOBLITZ_R;
+
+    /* Common setup for M */
+    M.s = 1;
+    M.p = Mp;
+
+    /* M = A1 */
+    M.n = N->n - ( p_limbs - adjust );
+    if( M.n > p_limbs + adjust )
+        M.n = p_limbs + adjust;
+    memset( Mp, 0, sizeof Mp );
+    memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
+    if( shift != 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
+    M.n += R.n; /* Make room for multiplication by R */
+
+    /* N = A0 */
+    if( mask != 0 )
+        N->p[p_limbs - 1] &= mask;
+    for( i = p_limbs; i < N->n; i++ )
+        N->p[i] = 0;
+
+    /* N = A0 + R * A1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
+
+    /* Second pass */
+
+    /* M = A1 */
+    M.n = N->n - ( p_limbs - adjust );
+    if( M.n > p_limbs + adjust )
+        M.n = p_limbs + adjust;
+    memset( Mp, 0, sizeof Mp );
+    memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
+    if( shift != 0 )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
+    M.n += R.n; /* Make room for multiplication by R */
+
+    /* N = A0 */
+    if( mask != 0 )
+        N->p[p_limbs - 1] &= mask;
+    for( i = p_limbs; i < N->n; i++ )
+        N->p[i] = 0;
+
+    /* N = A0 + R * A1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
+
+cleanup:
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
+          MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
+          MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
+
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+/*
+ * Fast quasi-reduction modulo p192k1 = 2^192 - R,
+ * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
+ */
+static int ecp_mod_p192k1( mbedtls_mpi *N )
+{
+    static mbedtls_mpi_uint Rp[] = {
+        BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
+
+    return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
+}
+#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+/*
+ * Fast quasi-reduction modulo p224k1 = 2^224 - R,
+ * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
+ */
+static int ecp_mod_p224k1( mbedtls_mpi *N )
+{
+    static mbedtls_mpi_uint Rp[] = {
+        BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
+
+#if defined(MBEDTLS_HAVE_INT64)
+    return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
+#else
+    return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
+#endif
+}
+
+#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
+
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+/*
+ * Fast quasi-reduction modulo p256k1 = 2^256 - R,
+ * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
+ */
+static int ecp_mod_p256k1( mbedtls_mpi *N )
+{
+    static mbedtls_mpi_uint Rp[] = {
+        BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
+    return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
+}
+#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
+
+#endif /* !MBEDTLS_ECP_ALT */
+
+#endif /* MBEDTLS_ECP_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/entropy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/entropy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/entropy.c	(revision 398)
@@ -0,0 +1,721 @@
+/*
+ *  Entropy accumulator implementation
+ *
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ENTROPY_C)
+
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+#warning "**** WARNING!  MBEDTLS_TEST_NULL_ENTROPY defined! "
+#warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES "
+#warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE "
+#endif
+
+#include "mbedtls/entropy.h"
+#include "mbedtls/entropy_poll.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_FS_IO)
+#include <stdio.h>
+#endif
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#include "mbedtls/platform.h"
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf     printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if defined(MBEDTLS_HAVEGE_C)
+#include "mbedtls/havege.h"
+#endif
+
+#define ENTROPY_MAX_LOOP    256     /**< Maximum amount to loop before error */
+
+void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
+{
+    ctx->source_count = 0;
+    memset( ctx->source, 0, sizeof( ctx->source ) );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+
+    ctx->accumulator_started = 0;
+#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
+    mbedtls_sha512_init( &ctx->accumulator );
+#else
+    mbedtls_sha256_init( &ctx->accumulator );
+#endif
+#if defined(MBEDTLS_HAVEGE_C)
+    mbedtls_havege_init( &ctx->havege_data );
+#endif
+
+    /* Reminder: Update ENTROPY_HAVE_STRONG in the test files
+     *           when adding more strong entropy sources here. */
+
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+    mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL,
+                                1, MBEDTLS_ENTROPY_SOURCE_STRONG );
+#endif
+
+#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
+#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
+    mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL,
+                                MBEDTLS_ENTROPY_MIN_PLATFORM,
+                                MBEDTLS_ENTROPY_SOURCE_STRONG );
+#endif
+#if defined(MBEDTLS_TIMING_C)
+    mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL,
+                                MBEDTLS_ENTROPY_MIN_HARDCLOCK,
+                                MBEDTLS_ENTROPY_SOURCE_WEAK );
+#endif
+#if defined(MBEDTLS_HAVEGE_C)
+    mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data,
+                                MBEDTLS_ENTROPY_MIN_HAVEGE,
+                                MBEDTLS_ENTROPY_SOURCE_STRONG );
+#endif
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+    mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL,
+                                MBEDTLS_ENTROPY_MIN_HARDWARE,
+                                MBEDTLS_ENTROPY_SOURCE_STRONG );
+#endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL,
+                                MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                MBEDTLS_ENTROPY_SOURCE_STRONG );
+    ctx->initial_entropy_run = 0;
+#endif
+#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
+}
+
+void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
+{
+#if defined(MBEDTLS_HAVEGE_C)
+    mbedtls_havege_free( &ctx->havege_data );
+#endif
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_free( &ctx->mutex );
+#endif
+#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
+    mbedtls_sha512_free( &ctx->accumulator );
+#else
+    mbedtls_sha256_free( &ctx->accumulator );
+#endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    ctx->initial_entropy_run = 0;
+#endif
+    ctx->source_count = 0;
+    mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) );
+    ctx->accumulator_started = 0;
+}
+
+int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
+                        mbedtls_entropy_f_source_ptr f_source, void *p_source,
+                        size_t threshold, int strong )
+{
+    int idx, ret = 0;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    idx = ctx->source_count;
+    if( idx >= MBEDTLS_ENTROPY_MAX_SOURCES )
+    {
+        ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES;
+        goto exit;
+    }
+
+    ctx->source[idx].f_source  = f_source;
+    ctx->source[idx].p_source  = p_source;
+    ctx->source[idx].threshold = threshold;
+    ctx->source[idx].strong    = strong;
+
+    ctx->source_count++;
+
+exit:
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
+}
+
+/*
+ * Entropy accumulator update
+ */
+static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id,
+                           const unsigned char *data, size_t len )
+{
+    unsigned char header[2];
+    unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    size_t use_len = len;
+    const unsigned char *p = data;
+    int ret = 0;
+
+    if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE )
+    {
+#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
+        if( ( ret = mbedtls_sha512_ret( data, len, tmp, 0 ) ) != 0 )
+            goto cleanup;
+#else
+        if( ( ret = mbedtls_sha256_ret( data, len, tmp, 0 ) ) != 0 )
+            goto cleanup;
+#endif
+        p = tmp;
+        use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
+    }
+
+    header[0] = source_id;
+    header[1] = use_len & 0xFF;
+
+    /*
+     * Start the accumulator if this has not already happened. Note that
+     * it is sufficient to start the accumulator here only because all calls to
+     * gather entropy eventually execute this code.
+     */
+#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
+    if( ctx->accumulator_started == 0 &&
+        ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+        goto cleanup;
+    else
+        ctx->accumulator_started = 1;
+    if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
+        goto cleanup;
+    ret = mbedtls_sha512_update_ret( &ctx->accumulator, p, use_len );
+#else
+    if( ctx->accumulator_started == 0 &&
+        ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+        goto cleanup;
+    else
+        ctx->accumulator_started = 1;
+    if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, header, 2 ) ) != 0 )
+        goto cleanup;
+    ret = mbedtls_sha256_update_ret( &ctx->accumulator, p, use_len );
+#endif
+
+cleanup:
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+
+    return( ret );
+}
+
+int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
+                           const unsigned char *data, size_t len )
+{
+    int ret;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
+}
+
+/*
+ * Run through the different sources to add entropy to our accumulator
+ */
+static int entropy_gather_internal( mbedtls_entropy_context *ctx )
+{
+    int ret, i, have_one_strong = 0;
+    unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
+    size_t olen;
+
+    if( ctx->source_count == 0 )
+        return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED );
+
+    /*
+     * Run through our entropy sources
+     */
+    for( i = 0; i < ctx->source_count; i++ )
+    {
+        if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
+            have_one_strong = 1;
+
+        olen = 0;
+        if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
+                        buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 )
+        {
+            goto cleanup;
+        }
+
+        /*
+         * Add if we actually gathered something
+         */
+        if( olen > 0 )
+        {
+            if( ( ret = entropy_update( ctx, (unsigned char) i,
+                                        buf, olen ) ) != 0 )
+                return( ret );
+            ctx->source[i].size += olen;
+        }
+    }
+
+    if( have_one_strong == 0 )
+        ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
+
+cleanup:
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+
+    return( ret );
+}
+
+/*
+ * Thread-safe wrapper for entropy_gather_internal()
+ */
+int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
+{
+    int ret;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    ret = entropy_gather_internal( ctx );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
+}
+
+int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
+{
+    int ret, count = 0, i, done;
+    mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+    if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
+        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    /* Update the NV entropy seed before generating any entropy for outside
+     * use.
+     */
+    if( ctx->initial_entropy_run == 0 )
+    {
+        ctx->initial_entropy_run = 1;
+        if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 )
+            return( ret );
+    }
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    /*
+     * Always gather extra entropy before a call
+     */
+    do
+    {
+        if( count++ > ENTROPY_MAX_LOOP )
+        {
+            ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+            goto exit;
+        }
+
+        if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
+            goto exit;
+
+        done = 1;
+        for( i = 0; i < ctx->source_count; i++ )
+            if( ctx->source[i].size < ctx->source[i].threshold )
+                done = 0;
+    }
+    while( ! done );
+
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
+    /*
+     * Note that at this stage it is assumed that the accumulator was started
+     * in a previous call to entropy_update(). If this is not guaranteed, the
+     * code below will fail.
+     */
+    if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 )
+        goto exit;
+
+    /*
+     * Reset accumulator and counters and recycle existing entropy
+     */
+    mbedtls_sha512_free( &ctx->accumulator );
+    mbedtls_sha512_init( &ctx->accumulator );
+    if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf,
+                                           MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
+        goto exit;
+
+    /*
+     * Perform second SHA-512 on entropy
+     */
+    if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                    buf, 0 ) ) != 0 )
+        goto exit;
+#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
+    if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 )
+        goto exit;
+
+    /*
+     * Reset accumulator and counters and recycle existing entropy
+     */
+    mbedtls_sha256_free( &ctx->accumulator );
+    mbedtls_sha256_init( &ctx->accumulator );
+    if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf,
+                                           MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
+        goto exit;
+
+    /*
+     * Perform second SHA-256 on entropy
+     */
+    if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
+                                    buf, 0 ) ) != 0 )
+        goto exit;
+#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
+
+    for( i = 0; i < ctx->source_count; i++ )
+        ctx->source[i].size = 0;
+
+    memcpy( output, buf, len );
+
+    ret = 0;
+
+exit:
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
+{
+    int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+    /* Read new seed  and write it to NV */
+    if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
+        return( ret );
+
+    if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
+        return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
+
+    /* Manually update the remaining stream with a separator value to diverge */
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+    ret = mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    return( ret );
+}
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
+#if defined(MBEDTLS_FS_IO)
+int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
+{
+    int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
+    FILE *f;
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
+
+    if( ( f = fopen( path, "wb" ) ) == NULL )
+        return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
+
+    if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
+        goto exit;
+
+    if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE )
+    {
+        ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
+        goto exit;
+    }
+
+    ret = 0;
+
+exit:
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+
+    fclose( f );
+    return( ret );
+}
+
+int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path )
+{
+    int ret = 0;
+    FILE *f;
+    size_t n;
+    unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
+
+    if( ( f = fopen( path, "rb" ) ) == NULL )
+        return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
+
+    fseek( f, 0, SEEK_END );
+    n = (size_t) ftell( f );
+    fseek( f, 0, SEEK_SET );
+
+    if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE )
+        n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
+
+    if( fread( buf, 1, n, f ) != n )
+        ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
+    else
+        ret = mbedtls_entropy_update_manual( ctx, buf, n );
+
+    fclose( f );
+
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+
+    if( ret != 0 )
+        return( ret );
+
+    return( mbedtls_entropy_write_seed_file( ctx, path ) );
+}
+#endif /* MBEDTLS_FS_IO */
+
+#if defined(MBEDTLS_SELF_TEST)
+#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
+/*
+ * Dummy source function
+ */
+static int entropy_dummy_source( void *data, unsigned char *output,
+                                 size_t len, size_t *olen )
+{
+    ((void) data);
+
+    memset( output, 0x2a, len );
+    *olen = len;
+
+    return( 0 );
+}
+#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+
+static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len )
+{
+    int ret = 0;
+    size_t entropy_len = 0;
+    size_t olen = 0;
+    size_t attempts = buf_len;
+
+    while( attempts > 0 && entropy_len < buf_len )
+    {
+        if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len,
+            buf_len - entropy_len, &olen ) ) != 0 )
+            return( ret );
+
+        entropy_len += olen;
+        attempts--;
+    }
+
+    if( entropy_len < buf_len )
+    {
+        ret = 1;
+    }
+
+    return( ret );
+}
+
+
+static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf,
+                                                        size_t buf_len )
+{
+    unsigned char set= 0xFF;
+    unsigned char unset = 0x00;
+    size_t i;
+
+    for( i = 0; i < buf_len; i++ )
+    {
+        set &= buf[i];
+        unset |= buf[i];
+    }
+
+    return( set == 0xFF || unset == 0x00 );
+}
+
+/*
+ * A test to ensure hat the entropy sources are functioning correctly
+ * and there is no obvious failure. The test performs the following checks:
+ *  - The entropy source is not providing only 0s (all bits unset) or 1s (all
+ *    bits set).
+ *  - The entropy source is not providing values in a pattern. Because the
+ *    hardware could be providing data in an arbitrary length, this check polls
+ *    the hardware entropy source twice and compares the result to ensure they
+ *    are not equal.
+ *  - The error code returned by the entropy source is not an error.
+ */
+int mbedtls_entropy_source_self_test( int verbose )
+{
+    int ret = 0;
+    unsigned char buf0[2 * sizeof( unsigned long long int )];
+    unsigned char buf1[2 * sizeof( unsigned long long int )];
+
+    if( verbose != 0 )
+        mbedtls_printf( "  ENTROPY_BIAS test: " );
+
+    memset( buf0, 0x00, sizeof( buf0 ) );
+    memset( buf1, 0x00, sizeof( buf1 ) );
+
+    if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 )
+        goto cleanup;
+    if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 )
+        goto cleanup;
+
+    /* Make sure that the returned values are not all 0 or 1 */
+    if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 )
+        goto cleanup;
+    if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 )
+        goto cleanup;
+
+    /* Make sure that the entropy source is not returning values in a
+     * pattern */
+    ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0;
+
+cleanup:
+    if( verbose != 0 )
+    {
+        if( ret != 0 )
+            mbedtls_printf( "failed\n" );
+        else
+            mbedtls_printf( "passed\n" );
+
+        mbedtls_printf( "\n" );
+    }
+
+    return( ret != 0 );
+}
+
+#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
+
+/*
+ * The actual entropy quality is hard to test, but we can at least
+ * test that the functions don't cause errors and write the correct
+ * amount of data to buffers.
+ */
+int mbedtls_entropy_self_test( int verbose )
+{
+    int ret = 1;
+#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
+    mbedtls_entropy_context ctx;
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
+    unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
+    size_t i, j;
+#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
+
+    if( verbose != 0 )
+        mbedtls_printf( "  ENTROPY test: " );
+
+#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
+    mbedtls_entropy_init( &ctx );
+
+    /* First do a gather to make sure we have default sources */
+    if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 )
+        goto cleanup;
+
+    ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16,
+                                      MBEDTLS_ENTROPY_SOURCE_WEAK );
+    if( ret != 0 )
+        goto cleanup;
+
+    if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 )
+        goto cleanup;
+
+    /*
+     * To test that mbedtls_entropy_func writes correct number of bytes:
+     * - use the whole buffer and rely on ASan to detect overruns
+     * - collect entropy 8 times and OR the result in an accumulator:
+     *   any byte should then be 0 with probably 2^(-64), so requiring
+     *   each of the 32 or 64 bytes to be non-zero has a false failure rate
+     *   of at most 2^(-58) which is acceptable.
+     */
+    for( i = 0; i < 8; i++ )
+    {
+        if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 )
+            goto cleanup;
+
+        for( j = 0; j < sizeof( buf ); j++ )
+            acc[j] |= buf[j];
+    }
+
+    for( j = 0; j < sizeof( buf ); j++ )
+    {
+        if( acc[j] == 0 )
+        {
+            ret = 1;
+            goto cleanup;
+        }
+    }
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+    if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 )
+        goto cleanup;
+#endif
+
+cleanup:
+    mbedtls_entropy_free( &ctx );
+#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
+
+    if( verbose != 0 )
+    {
+        if( ret != 0 )
+            mbedtls_printf( "failed\n" );
+        else
+            mbedtls_printf( "passed\n" );
+
+        mbedtls_printf( "\n" );
+    }
+
+    return( ret != 0 );
+}
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_ENTROPY_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/entropy_poll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/entropy_poll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/entropy_poll.c	(revision 398)
@@ -0,0 +1,236 @@
+/*
+ *  Platform-specific and custom entropy polling functions
+ *
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if defined(__linux__)
+/* Ensure that syscall() is available even when compiling with -std=c99 */
+#define _GNU_SOURCE
+#endif
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <string.h>
+
+#if defined(MBEDTLS_ENTROPY_C)
+
+#include "mbedtls/entropy.h"
+#include "mbedtls/entropy_poll.h"
+
+#if defined(MBEDTLS_TIMING_C)
+#include "mbedtls/timing.h"
+#endif
+#if defined(MBEDTLS_HAVEGE_C)
+#include "mbedtls/havege.h"
+#endif
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#include "mbedtls/platform.h"
+#endif
+
+#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
+
+#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
+    !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
+    !defined(__HAIKU__)
+#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
+#endif
+
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+
+#if !defined(_WIN32_WINNT)
+#define _WIN32_WINNT 0x0400
+#endif
+#include <windows.h>
+#include <wincrypt.h>
+
+int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
+                           size_t *olen )
+{
+    HCRYPTPROV provider;
+    ((void) data);
+    *olen = 0;
+
+    if( CryptAcquireContext( &provider, NULL, NULL,
+                              PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
+    {
+        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+    }
+
+    if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
+    {
+        CryptReleaseContext( provider, 0 );
+        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+    }
+
+    CryptReleaseContext( provider, 0 );
+    *olen = len;
+
+    return( 0 );
+}
+#else /* _WIN32 && !EFIX64 && !EFI32 */
+
+/*
+ * Test for Linux getrandom() support.
+ * Since there is no wrapper in the libc yet, use the generic syscall wrapper
+ * available in GNU libc and compatible libc's (eg uClibc).
+ */
+#if defined(__linux__) && defined(__GLIBC__)
+#include <unistd.h>
+#include <sys/syscall.h>
+#if defined(SYS_getrandom)
+#define HAVE_GETRANDOM
+#include <errno.h>
+
+static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
+{
+    /* MemSan cannot understand that the syscall writes to the buffer */
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+    memset( buf, 0, buflen );
+#endif
+#endif
+    return( syscall( SYS_getrandom, buf, buflen, flags ) );
+}
+#endif /* SYS_getrandom */
+#endif /* __linux__ */
+
+#include <stdio.h>
+
+int mbedtls_platform_entropy_poll( void *data,
+                           unsigned char *output, size_t len, size_t *olen )
+{
+    FILE *file;
+    size_t read_len;
+    int ret;
+    ((void) data);
+
+#if defined(HAVE_GETRANDOM)
+    ret = getrandom_wrapper( output, len, 0 );
+    if( ret >= 0 )
+    {
+        *olen = ret;
+        return( 0 );
+    }
+    else if( errno != ENOSYS )
+        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+    /* Fall through if the system call isn't known. */
+#else
+    ((void) ret);
+#endif /* HAVE_GETRANDOM */
+
+    *olen = 0;
+
+    file = fopen( "/dev/urandom", "rb" );
+    if( file == NULL )
+        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+
+    read_len = fread( output, 1, len, file );
+    if( read_len != len )
+    {
+        fclose( file );
+        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+    }
+
+    fclose( file );
+    *olen = len;
+
+    return( 0 );
+}
+#endif /* _WIN32 && !EFIX64 && !EFI32 */
+#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
+
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+int mbedtls_null_entropy_poll( void *data,
+                    unsigned char *output, size_t len, size_t *olen )
+{
+    ((void) data);
+    ((void) output);
+    *olen = 0;
+
+    if( len < sizeof(unsigned char) )
+        return( 0 );
+
+    *olen = sizeof(unsigned char);
+
+    return( 0 );
+}
+#endif
+
+#if defined(MBEDTLS_TIMING_C)
+int mbedtls_hardclock_poll( void *data,
+                    unsigned char *output, size_t len, size_t *olen )
+{
+    unsigned long timer = mbedtls_timing_hardclock();
+    ((void) data);
+    *olen = 0;
+
+    if( len < sizeof(unsigned long) )
+        return( 0 );
+
+    memcpy( output, &timer, sizeof(unsigned long) );
+    *olen = sizeof(unsigned long);
+
+    return( 0 );
+}
+#endif /* MBEDTLS_TIMING_C */
+
+#if defined(MBEDTLS_HAVEGE_C)
+int mbedtls_havege_poll( void *data,
+                 unsigned char *output, size_t len, size_t *olen )
+{
+    mbedtls_havege_state *hs = (mbedtls_havege_state *) data;
+    *olen = 0;
+
+    if( mbedtls_havege_random( hs, output, len ) != 0 )
+        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+
+    *olen = len;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_HAVEGE_C */
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+int mbedtls_nv_seed_poll( void *data,
+                          unsigned char *output, size_t len, size_t *olen )
+{
+    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
+    size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
+    ((void) data);
+
+    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
+
+    if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
+      return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+
+    if( len < use_len )
+      use_len = len;
+
+    memcpy( output, buf, use_len );
+    *olen = use_len;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
+#endif /* MBEDTLS_ENTROPY_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/error.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/error.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/error.c	(revision 398)
@@ -0,0 +1,916 @@
+/*
+ *  Error message information
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+#include "mbedtls/error.h"
+#include <string.h>
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#define mbedtls_snprintf snprintf
+#define mbedtls_time_t   time_t
+#endif
+
+#if defined(MBEDTLS_ERROR_C)
+
+#include <stdio.h>
+
+#if defined(MBEDTLS_AES_C)
+#include "mbedtls/aes.h"
+#endif
+
+#if defined(MBEDTLS_ARC4_C)
+#include "mbedtls/arc4.h"
+#endif
+
+#if defined(MBEDTLS_ARIA_C)
+#include "mbedtls/aria.h"
+#endif
+
+#if defined(MBEDTLS_BASE64_C)
+#include "mbedtls/base64.h"
+#endif
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_BLOWFISH_C)
+#include "mbedtls/blowfish.h"
+#endif
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#include "mbedtls/camellia.h"
+#endif
+
+#if defined(MBEDTLS_CCM_C)
+#include "mbedtls/ccm.h"
+#endif
+
+#if defined(MBEDTLS_CHACHA20_C)
+#include "mbedtls/chacha20.h"
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+#include "mbedtls/chachapoly.h"
+#endif
+
+#if defined(MBEDTLS_CIPHER_C)
+#include "mbedtls/cipher.h"
+#endif
+
+#if defined(MBEDTLS_CMAC_C)
+#include "mbedtls/cmac.h"
+#endif
+
+#if defined(MBEDTLS_CTR_DRBG_C)
+#include "mbedtls/ctr_drbg.h"
+#endif
+
+#if defined(MBEDTLS_DES_C)
+#include "mbedtls/des.h"
+#endif
+
+#if defined(MBEDTLS_DHM_C)
+#include "mbedtls/dhm.h"
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+#include "mbedtls/ecp.h"
+#endif
+
+#if defined(MBEDTLS_ENTROPY_C)
+#include "mbedtls/entropy.h"
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+#include "mbedtls/gcm.h"
+#endif
+
+#if defined(MBEDTLS_HKDF_C)
+#include "mbedtls/hkdf.h"
+#endif
+
+#if defined(MBEDTLS_HMAC_DRBG_C)
+#include "mbedtls/hmac_drbg.h"
+#endif
+
+#if defined(MBEDTLS_MD_C)
+#include "mbedtls/md.h"
+#endif
+
+#if defined(MBEDTLS_MD2_C)
+#include "mbedtls/md2.h"
+#endif
+
+#if defined(MBEDTLS_MD4_C)
+#include "mbedtls/md4.h"
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+#include "mbedtls/md5.h"
+#endif
+
+#if defined(MBEDTLS_NET_C)
+#include "mbedtls/net_sockets.h"
+#endif
+
+#if defined(MBEDTLS_OID_C)
+#include "mbedtls/oid.h"
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C)
+#include "mbedtls/padlock.h"
+#endif
+
+#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
+#include "mbedtls/pem.h"
+#endif
+
+#if defined(MBEDTLS_PK_C)
+#include "mbedtls/pk.h"
+#endif
+
+#if defined(MBEDTLS_PKCS12_C)
+#include "mbedtls/pkcs12.h"
+#endif
+
+#if defined(MBEDTLS_PKCS5_C)
+#include "mbedtls/pkcs5.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#endif
+
+#if defined(MBEDTLS_POLY1305_C)
+#include "mbedtls/poly1305.h"
+#endif
+
+#if defined(MBEDTLS_RIPEMD160_C)
+#include "mbedtls/ripemd160.h"
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+#include "mbedtls/rsa.h"
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+#include "mbedtls/sha1.h"
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+#include "mbedtls/sha256.h"
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+#include "mbedtls/sha512.h"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+#include "mbedtls/ssl.h"
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+#include "mbedtls/threading.h"
+#endif
+
+#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
+#include "mbedtls/x509.h"
+#endif
+
+#if defined(MBEDTLS_XTEA_C)
+#include "mbedtls/xtea.h"
+#endif
+
+
+void mbedtls_strerror( int ret, char *buf, size_t buflen )
+{
+    size_t len;
+    int use_ret;
+
+    if( buflen == 0 )
+        return;
+
+    memset( buf, 0x00, buflen );
+
+    if( ret < 0 )
+        ret = -ret;
+
+    if( ret & 0xFF80 )
+    {
+        use_ret = ret & 0xFF80;
+
+        // High level error codes
+        //
+        // BEGIN generated code
+#if defined(MBEDTLS_CIPHER_C)
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters" );
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" );
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid. For example, because it was freed" );
+        if( use_ret == -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "CIPHER - Cipher hardware accelerator failed" );
+#endif /* MBEDTLS_CIPHER_C */
+
+#if defined(MBEDTLS_DHM_C)
+        if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) )
+            mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) )
+            mbedtls_snprintf( buf, buflen, "DHM - Read or write of file failed" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" );
+        if( use_ret == -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED) )
+            mbedtls_snprintf( buf, buflen, "DHM - Setting the modulus and generator failed" );
+#endif /* MBEDTLS_DHM_C */
+
+#if defined(MBEDTLS_ECP_C)
+        if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) )
+            mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) )
+            mbedtls_snprintf( buf, buflen, "ECP - The requested feature is not available, for example, the requested curve is not supported" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) )
+            mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) )
+            mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as ephemeral key, failed" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
+            mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
+            mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "ECP - The ECP hardware accelerator failed" );
+        if( use_ret == -(MBEDTLS_ERR_ECP_IN_PROGRESS) )
+            mbedtls_snprintf( buf, buflen, "ECP - Operation in progress, call again with the same parameters to continue" );
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_MD_C)
+        if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) )
+            mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" );
+        if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" );
+        if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" );
+        if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) )
+            mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" );
+        if( use_ret == -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "MD - MD hardware accelerator failed" );
+#endif /* MBEDTLS_MD_C */
+
+#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
+        if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) )
+            mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" );
+        if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) )
+            mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" );
+        if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" );
+        if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) )
+            mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" );
+        if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) )
+            mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" );
+        if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) )
+            mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" );
+        if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) )
+            mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" );
+        if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) )
+            mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" );
+        if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" );
+#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
+
+#if defined(MBEDTLS_PK_C)
+        if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" );
+        if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) )
+            mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" );
+        if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" );
+        if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) )
+            mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" );
+        if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) )
+            mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" );
+        if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) )
+            mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" );
+        if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) )
+            mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" );
+        if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) )
+            mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" );
+        if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) )
+            mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" );
+        if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) )
+            mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" );
+        if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) )
+            mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" );
+        if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) )
+            mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" );
+        if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) )
+            mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
+        if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) )
+            mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" );
+        if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" );
+#endif /* MBEDTLS_PK_C */
+
+#if defined(MBEDTLS_PKCS12_C)
+        if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" );
+        if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) )
+            mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
+        if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) )
+            mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" );
+        if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) )
+            mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" );
+#endif /* MBEDTLS_PKCS12_C */
+
+#if defined(MBEDTLS_PKCS5_C)
+        if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" );
+        if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) )
+            mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" );
+        if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) )
+            mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" );
+        if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) )
+            mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" );
+#endif /* MBEDTLS_PKCS5_C */
+
+#if defined(MBEDTLS_RSA_C)
+        if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) )
+            mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) )
+            mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) )
+            mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the validity check of the library" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) )
+            mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) )
+            mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) )
+            mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) )
+            mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) )
+            mbedtls_snprintf( buf, buflen, "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" );
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_SSL_TLS_C)
+        if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) )
+            mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) )
+            mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) )
+            mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) )
+            mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) )
+            mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) )
+            mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) )
+            mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) )
+            mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) )
+            mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) )
+            mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) )
+            mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) )
+            mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) )
+            mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) )
+        {
+            mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" );
+            return;
+        }
+        if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) )
+            mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) )
+            mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) )
+            mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) )
+            mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) )
+            mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) )
+            mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) )
+            mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) )
+            mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) )
+            mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) )
+            mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) )
+            mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )
+            mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) )
+            mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) )
+            mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) )
+            mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) )
+            mbedtls_snprintf( buf, buflen, "SSL - No data of requested type currently available on underlying transport" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) )
+            mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) )
+            mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) )
+            mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) )
+            mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) )
+            mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) )
+            mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) )
+            mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) )
+            mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_EARLY_MESSAGE) )
+            mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that a message arrived early" );
+        if( use_ret == -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) )
+            mbedtls_snprintf( buf, buflen, "SSL - A cryptographic operation is in progress. Try again later" );
+#endif /* MBEDTLS_SSL_TLS_C */
+
+#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
+        if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) )
+            mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
+        if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) )
+            mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" );
+        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) )
+            mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" );
+        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) )
+            mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" );
+        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) )
+            mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" );
+        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) )
+            mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" );
+        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) )
+            mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" );
+        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) )
+            mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" );
+        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) )
+            mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" );
+        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) )
+            mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" );
+        if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) )
+            mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" );
+        if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) )
+            mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" );
+        if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) )
+            mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" );
+        if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) )
+            mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
+        if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) )
+            mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" );
+        if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) )
+            mbedtls_snprintf( buf, buflen, "X509 - Input invalid" );
+        if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) )
+            mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" );
+        if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) )
+            mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" );
+        if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) )
+            mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" );
+        if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) )
+            mbedtls_snprintf( buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed" );
+#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
+        // END generated code
+
+        if( strlen( buf ) == 0 )
+            mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
+    }
+
+    use_ret = ret & ~0xFF80;
+
+    if( use_ret == 0 )
+        return;
+
+    // If high level code is present, make a concatenation between both
+    // error strings.
+    //
+    len = strlen( buf );
+
+    if( len > 0 )
+    {
+        if( buflen - len < 5 )
+            return;
+
+        mbedtls_snprintf( buf + len, buflen - len, " : " );
+
+        buf += len + 3;
+        buflen -= len + 3;
+    }
+
+    // Low level error codes
+    //
+    // BEGIN generated code
+#if defined(MBEDTLS_AES_C)
+    if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) )
+        mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
+    if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
+        mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
+    if( use_ret == -(MBEDTLS_ERR_AES_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "AES - Invalid input data" );
+    if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) )
+        mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" );
+    if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "AES - AES hardware accelerator failed" );
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+    if( use_ret == -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" );
+#endif /* MBEDTLS_ARC4_C */
+
+#if defined(MBEDTLS_ARIA_C)
+    if( use_ret == -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "ARIA - Bad input data" );
+    if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH) )
+        mbedtls_snprintf( buf, buflen, "ARIA - Invalid data input length" );
+    if( use_ret == -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE) )
+        mbedtls_snprintf( buf, buflen, "ARIA - Feature not available. For example, an unsupported ARIA key size" );
+    if( use_ret == -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "ARIA - ARIA hardware accelerator failed" );
+#endif /* MBEDTLS_ARIA_C */
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+    if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) )
+        mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
+    if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) )
+        mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" );
+    if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) )
+        mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" );
+    if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) )
+        mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
+    if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) )
+        mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
+    if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) )
+        mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
+    if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) )
+        mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" );
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
+#if defined(MBEDTLS_BASE64_C)
+    if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) )
+        mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" );
+    if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) )
+        mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" );
+#endif /* MBEDTLS_BASE64_C */
+
+#if defined(MBEDTLS_BIGNUM_C)
+    if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) )
+        mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" );
+    if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" );
+    if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) )
+        mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" );
+    if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) )
+        mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" );
+    if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) )
+        mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" );
+    if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) )
+        mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" );
+    if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) )
+        mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" );
+    if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) )
+        mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" );
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_BLOWFISH_C)
+    if( use_ret == -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "BLOWFISH - Bad input data" );
+    if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
+        mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
+    if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" );
+#endif /* MBEDTLS_BLOWFISH_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+    if( use_ret == -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "CAMELLIA - Bad input data" );
+    if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
+        mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
+    if( use_ret == -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "CAMELLIA - Camellia hardware accelerator failed" );
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_CCM_C)
+    if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) )
+        mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to the function" );
+    if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) )
+        mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" );
+    if( use_ret == -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" );
+#endif /* MBEDTLS_CCM_C */
+
+#if defined(MBEDTLS_CHACHA20_C)
+    if( use_ret == -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "CHACHA20 - Invalid input parameter(s)" );
+    if( use_ret == -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE) )
+        mbedtls_snprintf( buf, buflen, "CHACHA20 - Feature not available. For example, s part of the API is not implemented" );
+    if( use_ret == -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "CHACHA20 - Chacha20 hardware accelerator failed" );
+#endif /* MBEDTLS_CHACHA20_C */
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE) )
+        mbedtls_snprintf( buf, buflen, "CHACHAPOLY - The requested operation is not permitted in the current state" );
+    if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) )
+        mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Authenticated decryption failed: data was not authentic" );
+#endif /* MBEDTLS_CHACHAPOLY_C */
+
+#if defined(MBEDTLS_CMAC_C)
+    if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" );
+#endif /* MBEDTLS_CMAC_C */
+
+#if defined(MBEDTLS_CTR_DRBG_C)
+    if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
+        mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
+    if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
+        mbedtls_snprintf( buf, buflen, "CTR_DRBG - The requested random buffer length is too big" );
+    if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) )
+        mbedtls_snprintf( buf, buflen, "CTR_DRBG - The input (entropy + additional data) is too large" );
+    if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) )
+        mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read or write error in file" );
+#endif /* MBEDTLS_CTR_DRBG_C */
+
+#if defined(MBEDTLS_DES_C)
+    if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) )
+        mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" );
+    if( use_ret == -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "DES - DES hardware accelerator failed" );
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_ENTROPY_C)
+    if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) )
+        mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" );
+    if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) )
+        mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" );
+    if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) )
+        mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" );
+    if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) )
+        mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" );
+    if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) )
+        mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" );
+#endif /* MBEDTLS_ENTROPY_C */
+
+#if defined(MBEDTLS_GCM_C)
+    if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) )
+        mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
+    if( use_ret == -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "GCM - GCM hardware accelerator failed" );
+    if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) )
+        mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_HKDF_C)
+    if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" );
+#endif /* MBEDTLS_HKDF_C */
+
+#if defined(MBEDTLS_HMAC_DRBG_C)
+    if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) )
+        mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" );
+    if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) )
+        mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" );
+    if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) )
+        mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" );
+    if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) )
+        mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" );
+#endif /* MBEDTLS_HMAC_DRBG_C */
+
+#if defined(MBEDTLS_MD2_C)
+    if( use_ret == -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "MD2 - MD2 hardware accelerator failed" );
+#endif /* MBEDTLS_MD2_C */
+
+#if defined(MBEDTLS_MD4_C)
+    if( use_ret == -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "MD4 - MD4 hardware accelerator failed" );
+#endif /* MBEDTLS_MD4_C */
+
+#if defined(MBEDTLS_MD5_C)
+    if( use_ret == -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "MD5 - MD5 hardware accelerator failed" );
+#endif /* MBEDTLS_MD5_C */
+
+#if defined(MBEDTLS_NET_C)
+    if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) )
+        mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" );
+    if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) )
+        mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" );
+    if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) )
+        mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" );
+    if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) )
+        mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" );
+    if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) )
+        mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" );
+    if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) )
+        mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" );
+    if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) )
+        mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" );
+    if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) )
+        mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" );
+    if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) )
+        mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
+    if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) )
+        mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" );
+    if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) )
+        mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" );
+    if( use_ret == -(MBEDTLS_ERR_NET_POLL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "NET - Polling the net context failed" );
+    if( use_ret == -(MBEDTLS_ERR_NET_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "NET - Input invalid" );
+#endif /* MBEDTLS_NET_C */
+
+#if defined(MBEDTLS_OID_C)
+    if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) )
+        mbedtls_snprintf( buf, buflen, "OID - OID is not found" );
+    if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) )
+        mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" );
+#endif /* MBEDTLS_OID_C */
+
+#if defined(MBEDTLS_PADLOCK_C)
+    if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) )
+        mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
+#endif /* MBEDTLS_PADLOCK_C */
+
+#if defined(MBEDTLS_PLATFORM_C)
+    if( use_ret == -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "PLATFORM - Hardware accelerator failed" );
+    if( use_ret == -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED) )
+        mbedtls_snprintf( buf, buflen, "PLATFORM - The requested feature is not supported by the platform" );
+#endif /* MBEDTLS_PLATFORM_C */
+
+#if defined(MBEDTLS_POLY1305_C)
+    if( use_ret == -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "POLY1305 - Invalid input parameter(s)" );
+    if( use_ret == -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE) )
+        mbedtls_snprintf( buf, buflen, "POLY1305 - Feature not available. For example, s part of the API is not implemented" );
+    if( use_ret == -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "POLY1305 - Poly1305 hardware accelerator failed" );
+#endif /* MBEDTLS_POLY1305_C */
+
+#if defined(MBEDTLS_RIPEMD160_C)
+    if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" );
+#endif /* MBEDTLS_RIPEMD160_C */
+
+#if defined(MBEDTLS_SHA1_C)
+    if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" );
+    if( use_ret == -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 input data was malformed" );
+#endif /* MBEDTLS_SHA1_C */
+
+#if defined(MBEDTLS_SHA256_C)
+    if( use_ret == -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 hardware accelerator failed" );
+    if( use_ret == -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 input data was malformed" );
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    if( use_ret == -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 hardware accelerator failed" );
+    if( use_ret == -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 input data was malformed" );
+#endif /* MBEDTLS_SHA512_C */
+
+#if defined(MBEDTLS_THREADING_C)
+    if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) )
+        mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" );
+    if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) )
+        mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" );
+    if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) )
+        mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" );
+#endif /* MBEDTLS_THREADING_C */
+
+#if defined(MBEDTLS_XTEA_C)
+    if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) )
+        mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
+    if( use_ret == -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED) )
+        mbedtls_snprintf( buf, buflen, "XTEA - XTEA hardware accelerator failed" );
+#endif /* MBEDTLS_XTEA_C */
+    // END generated code
+
+    if( strlen( buf ) != 0 )
+        return;
+
+    mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
+}
+
+#else /* MBEDTLS_ERROR_C */
+
+#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+
+/*
+ * Provide an non-function in case MBEDTLS_ERROR_C is not defined
+ */
+void mbedtls_strerror( int ret, char *buf, size_t buflen )
+{
+    ((void) ret);
+
+    if( buflen > 0 )
+        buf[0] = '\0';
+}
+
+#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
+
+#endif /* MBEDTLS_ERROR_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/gcm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/gcm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/gcm.c	(revision 398)
@@ -0,0 +1,994 @@
+/*
+ *  NIST SP800-38D compliant GCM implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+ *
+ * See also:
+ * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
+ *
+ * We use the algorithm described as Shoup's method with 4-bit tables in
+ * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+
+#include "mbedtls/gcm.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_AESNI_C)
+#include "mbedtls/aesni.h"
+#endif
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+#include "mbedtls/aes.h"
+#include "mbedtls/platform.h"
+#if !defined(MBEDTLS_PLATFORM_C)
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#if !defined(MBEDTLS_GCM_ALT)
+
+/* Parameter validation macros */
+#define GCM_VALIDATE_RET( cond ) \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_GCM_BAD_INPUT )
+#define GCM_VALIDATE( cond ) \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_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
+
+/*
+ * Initialize a context
+ */
+void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
+{
+    GCM_VALIDATE( ctx != NULL );
+    memset( ctx, 0, sizeof( mbedtls_gcm_context ) );
+}
+
+/*
+ * Precompute small multiples of H, that is set
+ *      HH[i] || HL[i] = H times i,
+ * where i is seen as a field element as in [MGV], ie high-order bits
+ * correspond to low powers of P. The result is stored in the same way, that
+ * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL
+ * corresponds to P^127.
+ */
+static int gcm_gen_table( mbedtls_gcm_context *ctx )
+{
+    int ret, i, j;
+    uint64_t hi, lo;
+    uint64_t vl, vh;
+    unsigned char h[16];
+    size_t olen = 0;
+
+    memset( h, 0, 16 );
+    if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 )
+        return( ret );
+
+    /* pack h as two 64-bits ints, big-endian */
+    GET_UINT32_BE( hi, h,  0  );
+    GET_UINT32_BE( lo, h,  4  );
+    vh = (uint64_t) hi << 32 | lo;
+
+    GET_UINT32_BE( hi, h,  8  );
+    GET_UINT32_BE( lo, h,  12 );
+    vl = (uint64_t) hi << 32 | lo;
+
+    /* 8 = 1000 corresponds to 1 in GF(2^128) */
+    ctx->HL[8] = vl;
+    ctx->HH[8] = vh;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    /* With CLMUL support, we need only h, not the rest of the table */
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) )
+        return( 0 );
+#endif
+
+    /* 0 corresponds to 0 in GF(2^128) */
+    ctx->HH[0] = 0;
+    ctx->HL[0] = 0;
+
+    for( i = 4; i > 0; i >>= 1 )
+    {
+        uint32_t T = ( vl & 1 ) * 0xe1000000U;
+        vl  = ( vh << 63 ) | ( vl >> 1 );
+        vh  = ( vh >> 1 ) ^ ( (uint64_t) T << 32);
+
+        ctx->HL[i] = vl;
+        ctx->HH[i] = vh;
+    }
+
+    for( i = 2; i <= 8; i *= 2 )
+    {
+        uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i;
+        vh = *HiH;
+        vl = *HiL;
+        for( j = 1; j < i; j++ )
+        {
+            HiH[j] = vh ^ ctx->HH[j];
+            HiL[j] = vl ^ ctx->HL[j];
+        }
+    }
+
+    return( 0 );
+}
+
+int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
+                        mbedtls_cipher_id_t cipher,
+                        const unsigned char *key,
+                        unsigned int keybits )
+{
+    int ret;
+    const mbedtls_cipher_info_t *cipher_info;
+
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( key != NULL );
+    GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
+
+    cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
+    if( cipher_info == NULL )
+        return( MBEDTLS_ERR_GCM_BAD_INPUT );
+
+    if( cipher_info->block_size != 16 )
+        return( MBEDTLS_ERR_GCM_BAD_INPUT );
+
+    mbedtls_cipher_free( &ctx->cipher_ctx );
+
+    if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
+                               MBEDTLS_ENCRYPT ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = gcm_gen_table( ctx ) ) != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+/*
+ * Shoup's method for multiplication use this table with
+ *      last4[x] = x times P^128
+ * where x and last4[x] are seen as elements of GF(2^128) as in [MGV]
+ */
+static const uint64_t last4[16] =
+{
+    0x0000, 0x1c20, 0x3840, 0x2460,
+    0x7080, 0x6ca0, 0x48c0, 0x54e0,
+    0xe100, 0xfd20, 0xd940, 0xc560,
+    0x9180, 0x8da0, 0xa9c0, 0xb5e0
+};
+
+/*
+ * Sets output to x times H using the precomputed tables.
+ * x and output are seen as elements of GF(2^128) as in [MGV].
+ */
+static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
+                      unsigned char output[16] )
+{
+    int i = 0;
+    unsigned char lo, hi, rem;
+    uint64_t zh, zl;
+
+#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
+    if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
+        unsigned char h[16];
+
+        PUT_UINT32_BE( ctx->HH[8] >> 32, h,  0 );
+        PUT_UINT32_BE( ctx->HH[8],       h,  4 );
+        PUT_UINT32_BE( ctx->HL[8] >> 32, h,  8 );
+        PUT_UINT32_BE( ctx->HL[8],       h, 12 );
+
+        mbedtls_aesni_gcm_mult( output, x, h );
+        return;
+    }
+#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */
+
+    lo = x[15] & 0xf;
+
+    zh = ctx->HH[lo];
+    zl = ctx->HL[lo];
+
+    for( i = 15; i >= 0; i-- )
+    {
+        lo = x[i] & 0xf;
+        hi = x[i] >> 4;
+
+        if( i != 15 )
+        {
+            rem = (unsigned char) zl & 0xf;
+            zl = ( zh << 60 ) | ( zl >> 4 );
+            zh = ( zh >> 4 );
+            zh ^= (uint64_t) last4[rem] << 48;
+            zh ^= ctx->HH[lo];
+            zl ^= ctx->HL[lo];
+
+        }
+
+        rem = (unsigned char) zl & 0xf;
+        zl = ( zh << 60 ) | ( zl >> 4 );
+        zh = ( zh >> 4 );
+        zh ^= (uint64_t) last4[rem] << 48;
+        zh ^= ctx->HH[hi];
+        zl ^= ctx->HL[hi];
+    }
+
+    PUT_UINT32_BE( zh >> 32, output, 0 );
+    PUT_UINT32_BE( zh, output, 4 );
+    PUT_UINT32_BE( zl >> 32, output, 8 );
+    PUT_UINT32_BE( zl, output, 12 );
+}
+
+int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
+                int mode,
+                const unsigned char *iv,
+                size_t iv_len,
+                const unsigned char *add,
+                size_t add_len )
+{
+    int ret;
+    unsigned char work_buf[16];
+    size_t i;
+    const unsigned char *p;
+    size_t use_len, olen = 0;
+
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( iv != NULL );
+    GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+
+    /* IV and AD are limited to 2^64 bits, so 2^61 bytes */
+    /* IV is not allowed to be zero length */
+    if( iv_len == 0 ||
+      ( (uint64_t) iv_len  ) >> 61 != 0 ||
+      ( (uint64_t) add_len ) >> 61 != 0 )
+    {
+        return( MBEDTLS_ERR_GCM_BAD_INPUT );
+    }
+
+    memset( ctx->y, 0x00, sizeof(ctx->y) );
+    memset( ctx->buf, 0x00, sizeof(ctx->buf) );
+
+    ctx->mode = mode;
+    ctx->len = 0;
+    ctx->add_len = 0;
+
+    if( iv_len == 12 )
+    {
+        memcpy( ctx->y, iv, iv_len );
+        ctx->y[15] = 1;
+    }
+    else
+    {
+        memset( work_buf, 0x00, 16 );
+        PUT_UINT32_BE( iv_len * 8, work_buf, 12 );
+
+        p = iv;
+        while( iv_len > 0 )
+        {
+            use_len = ( iv_len < 16 ) ? iv_len : 16;
+
+            for( i = 0; i < use_len; i++ )
+                ctx->y[i] ^= p[i];
+
+            gcm_mult( ctx, ctx->y, ctx->y );
+
+            iv_len -= use_len;
+            p += use_len;
+        }
+
+        for( i = 0; i < 16; i++ )
+            ctx->y[i] ^= work_buf[i];
+
+        gcm_mult( ctx, ctx->y, ctx->y );
+    }
+
+    if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
+                             &olen ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    ctx->add_len = add_len;
+    p = add;
+    while( add_len > 0 )
+    {
+        use_len = ( add_len < 16 ) ? add_len : 16;
+
+        for( i = 0; i < use_len; i++ )
+            ctx->buf[i] ^= p[i];
+
+        gcm_mult( ctx, ctx->buf, ctx->buf );
+
+        add_len -= use_len;
+        p += use_len;
+    }
+
+    return( 0 );
+}
+
+int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
+                size_t length,
+                const unsigned char *input,
+                unsigned char *output )
+{
+    int ret;
+    unsigned char ectr[16];
+    size_t i;
+    const unsigned char *p;
+    unsigned char *out_p = output;
+    size_t use_len, olen = 0;
+
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( length == 0 || input != NULL );
+    GCM_VALIDATE_RET( length == 0 || output != NULL );
+
+    if( output > input && (size_t) ( output - input ) < length )
+        return( MBEDTLS_ERR_GCM_BAD_INPUT );
+
+    /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
+     * Also check for possible overflow */
+    if( ctx->len + length < ctx->len ||
+        (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
+    {
+        return( MBEDTLS_ERR_GCM_BAD_INPUT );
+    }
+
+    ctx->len += length;
+
+    p = input;
+    while( length > 0 )
+    {
+        use_len = ( length < 16 ) ? length : 16;
+
+        for( i = 16; i > 12; i-- )
+            if( ++ctx->y[i - 1] != 0 )
+                break;
+
+        if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr,
+                                   &olen ) ) != 0 )
+        {
+            return( ret );
+        }
+
+        for( i = 0; i < use_len; i++ )
+        {
+            if( ctx->mode == MBEDTLS_GCM_DECRYPT )
+                ctx->buf[i] ^= p[i];
+            out_p[i] = ectr[i] ^ p[i];
+            if( ctx->mode == MBEDTLS_GCM_ENCRYPT )
+                ctx->buf[i] ^= out_p[i];
+        }
+
+        gcm_mult( ctx, ctx->buf, ctx->buf );
+
+        length -= use_len;
+        p += use_len;
+        out_p += use_len;
+    }
+
+    return( 0 );
+}
+
+int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
+                unsigned char *tag,
+                size_t tag_len )
+{
+    unsigned char work_buf[16];
+    size_t i;
+    uint64_t orig_len;
+    uint64_t orig_add_len;
+
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( tag != NULL );
+
+    orig_len = ctx->len * 8;
+    orig_add_len = ctx->add_len * 8;
+
+    if( tag_len > 16 || tag_len < 4 )
+        return( MBEDTLS_ERR_GCM_BAD_INPUT );
+
+    memcpy( tag, ctx->base_ectr, tag_len );
+
+    if( orig_len || orig_add_len )
+    {
+        memset( work_buf, 0x00, 16 );
+
+        PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0  );
+        PUT_UINT32_BE( ( orig_add_len       ), work_buf, 4  );
+        PUT_UINT32_BE( ( orig_len     >> 32 ), work_buf, 8  );
+        PUT_UINT32_BE( ( orig_len           ), work_buf, 12 );
+
+        for( i = 0; i < 16; i++ )
+            ctx->buf[i] ^= work_buf[i];
+
+        gcm_mult( ctx, ctx->buf, ctx->buf );
+
+        for( i = 0; i < tag_len; i++ )
+            tag[i] ^= ctx->buf[i];
+    }
+
+    return( 0 );
+}
+
+int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
+                       int mode,
+                       size_t length,
+                       const unsigned char *iv,
+                       size_t iv_len,
+                       const unsigned char *add,
+                       size_t add_len,
+                       const unsigned char *input,
+                       unsigned char *output,
+                       size_t tag_len,
+                       unsigned char *tag )
+{
+    int ret;
+
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( iv != NULL );
+    GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    GCM_VALIDATE_RET( length == 0 || input != NULL );
+    GCM_VALIDATE_RET( length == 0 || output != NULL );
+    GCM_VALIDATE_RET( tag != NULL );
+
+    if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
+                      size_t length,
+                      const unsigned char *iv,
+                      size_t iv_len,
+                      const unsigned char *add,
+                      size_t add_len,
+                      const unsigned char *tag,
+                      size_t tag_len,
+                      const unsigned char *input,
+                      unsigned char *output )
+{
+    int ret;
+    unsigned char check_tag[16];
+    size_t i;
+    int diff;
+
+    GCM_VALIDATE_RET( ctx != NULL );
+    GCM_VALIDATE_RET( iv != NULL );
+    GCM_VALIDATE_RET( add_len == 0 || add != NULL );
+    GCM_VALIDATE_RET( tag != NULL );
+    GCM_VALIDATE_RET( length == 0 || input != NULL );
+    GCM_VALIDATE_RET( length == 0 || output != NULL );
+
+    if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length,
+                                   iv, iv_len, add, add_len,
+                                   input, output, tag_len, check_tag ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /* Check tag in "constant-time" */
+    for( diff = 0, i = 0; i < tag_len; i++ )
+        diff |= tag[i] ^ check_tag[i];
+
+    if( diff != 0 )
+    {
+        mbedtls_platform_zeroize( output, length );
+        return( MBEDTLS_ERR_GCM_AUTH_FAILED );
+    }
+
+    return( 0 );
+}
+
+void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+    mbedtls_cipher_free( &ctx->cipher_ctx );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_gcm_context ) );
+}
+
+#endif /* !MBEDTLS_GCM_ALT */
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+/*
+ * AES-GCM test vectors from:
+ *
+ * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
+ */
+#define MAX_TESTS   6
+
+static const int key_index[MAX_TESTS] =
+    { 0, 0, 1, 1, 1, 1 };
+
+static const unsigned char key[MAX_TESTS][32] =
+{
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+    { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+      0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+      0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+      0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
+};
+
+static const size_t iv_len[MAX_TESTS] =
+    { 12, 12, 12, 12, 8, 60 };
+
+static const int iv_index[MAX_TESTS] =
+    { 0, 0, 1, 1, 1, 2 };
+
+static const unsigned char iv[MAX_TESTS][64] =
+{
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00 },
+    { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+      0xde, 0xca, 0xf8, 0x88 },
+    { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
+      0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
+      0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
+      0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
+      0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
+      0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
+      0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
+      0xa6, 0x37, 0xb3, 0x9b },
+};
+
+static const size_t add_len[MAX_TESTS] =
+    { 0, 0, 0, 20, 20, 20 };
+
+static const int add_index[MAX_TESTS] =
+    { 0, 0, 0, 1, 1, 1 };
+
+static const unsigned char additional[MAX_TESTS][64] =
+{
+    { 0x00 },
+    { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+      0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+      0xab, 0xad, 0xda, 0xd2 },
+};
+
+static const size_t pt_len[MAX_TESTS] =
+    { 0, 16, 64, 60, 60, 60 };
+
+static const int pt_index[MAX_TESTS] =
+    { 0, 0, 1, 1, 1, 1 };
+
+static const unsigned char pt[MAX_TESTS][64] =
+{
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+    { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+      0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+      0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+      0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+      0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+      0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+      0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+      0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
+};
+
+static const unsigned char ct[MAX_TESTS * 3][64] =
+{
+    { 0x00 },
+    { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
+      0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
+    { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+      0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+      0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+      0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+      0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+      0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+      0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+      0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 },
+    { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+      0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+      0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+      0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+      0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+      0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+      0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+      0x3d, 0x58, 0xe0, 0x91 },
+    { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
+      0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
+      0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
+      0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
+      0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
+      0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
+      0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
+      0xc2, 0x3f, 0x45, 0x98 },
+    { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
+      0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
+      0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
+      0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
+      0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
+      0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
+      0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
+      0x4c, 0x34, 0xae, 0xe5 },
+    { 0x00 },
+    { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
+      0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 },
+    { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+      0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+      0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+      0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+      0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+      0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+      0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+      0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 },
+    { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+      0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+      0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+      0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+      0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+      0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+      0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+      0xcc, 0xda, 0x27, 0x10 },
+    { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
+      0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
+      0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
+      0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
+      0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
+      0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
+      0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
+      0xa0, 0xf0, 0x62, 0xf7 },
+    { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
+      0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
+      0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
+      0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
+      0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
+      0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
+      0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
+      0xe9, 0xb7, 0x37, 0x3b },
+    { 0x00 },
+    { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
+      0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 },
+    { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+      0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+      0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+      0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+      0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+      0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+      0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+      0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad },
+    { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+      0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+      0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+      0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+      0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+      0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+      0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+      0xbc, 0xc9, 0xf6, 0x62 },
+    { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
+      0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
+      0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
+      0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
+      0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
+      0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
+      0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
+      0xf4, 0x7c, 0x9b, 0x1f },
+    { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
+      0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
+      0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
+      0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
+      0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
+      0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
+      0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
+      0x44, 0xae, 0x7e, 0x3f },
+};
+
+static const unsigned char tag[MAX_TESTS * 3][16] =
+{
+    { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
+      0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
+    { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
+      0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf },
+    { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
+      0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 },
+    { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+      0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 },
+    { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
+      0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb },
+    { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
+      0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 },
+    { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
+      0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 },
+    { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
+      0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb },
+    { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
+      0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 },
+    { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
+      0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c },
+    { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
+      0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 },
+    { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
+      0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 },
+    { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
+      0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b },
+    { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
+      0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 },
+    { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
+      0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c },
+    { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
+      0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b },
+    { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
+      0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 },
+    { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
+      0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a },
+};
+
+int mbedtls_gcm_self_test( int verbose )
+{
+    mbedtls_gcm_context ctx;
+    unsigned char buf[64];
+    unsigned char tag_buf[16];
+    int i, j, ret;
+    mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
+
+    for( j = 0; j < 3; j++ )
+    {
+        int key_len = 128 + 64 * j;
+
+        for( i = 0; i < MAX_TESTS; i++ )
+        {
+            mbedtls_gcm_init( &ctx );
+
+            if( verbose != 0 )
+                mbedtls_printf( "  AES-GCM-%3d #%d (%s): ",
+                                key_len, i, "enc" );
+
+            ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+                                      key_len );
+            /*
+             * AES-192 is an optional feature that may be unavailable when
+             * there is an alternative underlying implementation i.e. when
+             * MBEDTLS_AES_ALT is defined.
+             */
+            if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192 )
+            {
+                mbedtls_printf( "skipped\n" );
+                break;
+            }
+            else if( ret != 0 )
+            {
+                goto exit;
+            }
+
+            ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
+                                        pt_len[i],
+                                        iv[iv_index[i]], iv_len[i],
+                                        additional[add_index[i]], add_len[i],
+                                        pt[pt_index[i]], buf, 16, tag_buf );
+            if( ret != 0 )
+                goto exit;
+
+            if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
+                 memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+            {
+                ret = 1;
+                goto exit;
+            }
+
+            mbedtls_gcm_free( &ctx );
+
+            if( verbose != 0 )
+                mbedtls_printf( "passed\n" );
+
+            mbedtls_gcm_init( &ctx );
+
+            if( verbose != 0 )
+                mbedtls_printf( "  AES-GCM-%3d #%d (%s): ",
+                                key_len, i, "dec" );
+
+            ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+                                      key_len );
+            if( ret != 0 )
+                goto exit;
+
+            ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
+                                        pt_len[i],
+                                        iv[iv_index[i]], iv_len[i],
+                                        additional[add_index[i]], add_len[i],
+                                        ct[j * 6 + i], buf, 16, tag_buf );
+
+            if( ret != 0 )
+                goto exit;
+
+            if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
+                memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+            {
+                ret = 1;
+                goto exit;
+            }
+
+            mbedtls_gcm_free( &ctx );
+
+            if( verbose != 0 )
+                mbedtls_printf( "passed\n" );
+
+            mbedtls_gcm_init( &ctx );
+
+            if( verbose != 0 )
+                mbedtls_printf( "  AES-GCM-%3d #%d split (%s): ",
+                                key_len, i, "enc" );
+
+            ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+                                      key_len );
+            if( ret != 0 )
+                goto exit;
+
+            ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
+                                      iv[iv_index[i]], iv_len[i],
+                                      additional[add_index[i]], add_len[i] );
+            if( ret != 0 )
+                goto exit;
+
+            if( pt_len[i] > 32 )
+            {
+                size_t rest_len = pt_len[i] - 32;
+                ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
+                if( ret != 0 )
+                    goto exit;
+
+                ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
+                                  buf + 32 );
+                if( ret != 0 )
+                    goto exit;
+            }
+            else
+            {
+                ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
+                if( ret != 0 )
+                    goto exit;
+            }
+
+            ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
+            if( ret != 0 )
+                goto exit;
+
+            if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
+                memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+            {
+                ret = 1;
+                goto exit;
+            }
+
+            mbedtls_gcm_free( &ctx );
+
+            if( verbose != 0 )
+                mbedtls_printf( "passed\n" );
+
+            mbedtls_gcm_init( &ctx );
+
+            if( verbose != 0 )
+                mbedtls_printf( "  AES-GCM-%3d #%d split (%s): ",
+                                key_len, i, "dec" );
+
+            ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+                                      key_len );
+            if( ret != 0 )
+                goto exit;
+
+            ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
+                              iv[iv_index[i]], iv_len[i],
+                              additional[add_index[i]], add_len[i] );
+            if( ret != 0 )
+                goto exit;
+
+            if( pt_len[i] > 32 )
+            {
+                size_t rest_len = pt_len[i] - 32;
+                ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
+                if( ret != 0 )
+                    goto exit;
+
+                ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
+                                          buf + 32 );
+                if( ret != 0 )
+                    goto exit;
+            }
+            else
+            {
+                ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
+                                          buf );
+                if( ret != 0 )
+                    goto exit;
+            }
+
+            ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 );
+            if( ret != 0 )
+                goto exit;
+
+            if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
+                memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+            {
+                ret = 1;
+                goto exit;
+            }
+
+            mbedtls_gcm_free( &ctx );
+
+            if( verbose != 0 )
+                mbedtls_printf( "passed\n" );
+        }
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    ret = 0;
+
+exit:
+    if( ret != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+        mbedtls_gcm_free( &ctx );
+    }
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#endif /* MBEDTLS_GCM_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/havege.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/havege.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/havege.c	(revision 398)
@@ -0,0 +1,241 @@
+/**
+ *  \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The HAVEGE RNG was designed by Andre Seznec in 2002.
+ *
+ *  http://www.irisa.fr/caps/projects/hipsor/publi.php
+ *
+ *  Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_HAVEGE_C)
+
+#include "mbedtls/havege.h"
+#include "mbedtls/timing.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+/* ------------------------------------------------------------------------
+ * On average, one iteration accesses two 8-word blocks in the havege WALK
+ * table, and generates 16 words in the RES array.
+ *
+ * The data read in the WALK table is updated and permuted after each use.
+ * The result of the hardware clock counter read is used  for this update.
+ *
+ * 25 conditional tests are present.  The conditional tests are grouped in
+ * two nested  groups of 12 conditional tests and 1 test that controls the
+ * permutation; on average, there should be 6 tests executed and 3 of them
+ * should be mispredicted.
+ * ------------------------------------------------------------------------
+ */
+
+#define SWAP(X,Y) { int *T = X; X = Y; Y = T; }
+
+#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
+#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
+
+#define TST1_LEAVE U1++; }
+#define TST2_LEAVE U2++; }
+
+#define ONE_ITERATION                                   \
+                                                        \
+    PTEST = PT1 >> 20;                                  \
+                                                        \
+    TST1_ENTER  TST1_ENTER  TST1_ENTER  TST1_ENTER      \
+    TST1_ENTER  TST1_ENTER  TST1_ENTER  TST1_ENTER      \
+    TST1_ENTER  TST1_ENTER  TST1_ENTER  TST1_ENTER      \
+                                                        \
+    TST1_LEAVE  TST1_LEAVE  TST1_LEAVE  TST1_LEAVE      \
+    TST1_LEAVE  TST1_LEAVE  TST1_LEAVE  TST1_LEAVE      \
+    TST1_LEAVE  TST1_LEAVE  TST1_LEAVE  TST1_LEAVE      \
+                                                        \
+    PTX = (PT1 >> 18) & 7;                              \
+    PT1 &= 0x1FFF;                                      \
+    PT2 &= 0x1FFF;                                      \
+    CLK = (int) mbedtls_timing_hardclock();                            \
+                                                        \
+    i = 0;                                              \
+    A = &WALK[PT1    ]; RES[i++] ^= *A;                 \
+    B = &WALK[PT2    ]; RES[i++] ^= *B;                 \
+    C = &WALK[PT1 ^ 1]; RES[i++] ^= *C;                 \
+    D = &WALK[PT2 ^ 4]; RES[i++] ^= *D;                 \
+                                                        \
+    IN = (*A >> (1)) ^ (*A << (31)) ^ CLK;              \
+    *A = (*B >> (2)) ^ (*B << (30)) ^ CLK;              \
+    *B = IN ^ U1;                                       \
+    *C = (*C >> (3)) ^ (*C << (29)) ^ CLK;              \
+    *D = (*D >> (4)) ^ (*D << (28)) ^ CLK;              \
+                                                        \
+    A = &WALK[PT1 ^ 2]; RES[i++] ^= *A;                 \
+    B = &WALK[PT2 ^ 2]; RES[i++] ^= *B;                 \
+    C = &WALK[PT1 ^ 3]; RES[i++] ^= *C;                 \
+    D = &WALK[PT2 ^ 6]; RES[i++] ^= *D;                 \
+                                                        \
+    if( PTEST & 1 ) SWAP( A, C );                       \
+                                                        \
+    IN = (*A >> (5)) ^ (*A << (27)) ^ CLK;              \
+    *A = (*B >> (6)) ^ (*B << (26)) ^ CLK;              \
+    *B = IN; CLK = (int) mbedtls_timing_hardclock();                   \
+    *C = (*C >> (7)) ^ (*C << (25)) ^ CLK;              \
+    *D = (*D >> (8)) ^ (*D << (24)) ^ CLK;              \
+                                                        \
+    A = &WALK[PT1 ^ 4];                                 \
+    B = &WALK[PT2 ^ 1];                                 \
+                                                        \
+    PTEST = PT2 >> 1;                                   \
+                                                        \
+    PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]);   \
+    PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8);  \
+    PTY = (PT2 >> 10) & 7;                              \
+                                                        \
+    TST2_ENTER  TST2_ENTER  TST2_ENTER  TST2_ENTER      \
+    TST2_ENTER  TST2_ENTER  TST2_ENTER  TST2_ENTER      \
+    TST2_ENTER  TST2_ENTER  TST2_ENTER  TST2_ENTER      \
+                                                        \
+    TST2_LEAVE  TST2_LEAVE  TST2_LEAVE  TST2_LEAVE      \
+    TST2_LEAVE  TST2_LEAVE  TST2_LEAVE  TST2_LEAVE      \
+    TST2_LEAVE  TST2_LEAVE  TST2_LEAVE  TST2_LEAVE      \
+                                                        \
+    C = &WALK[PT1 ^ 5];                                 \
+    D = &WALK[PT2 ^ 5];                                 \
+                                                        \
+    RES[i++] ^= *A;                                     \
+    RES[i++] ^= *B;                                     \
+    RES[i++] ^= *C;                                     \
+    RES[i++] ^= *D;                                     \
+                                                        \
+    IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK;             \
+    *A = (*B >> (10)) ^ (*B << (22)) ^ CLK;             \
+    *B = IN ^ U2;                                       \
+    *C = (*C >> (11)) ^ (*C << (21)) ^ CLK;             \
+    *D = (*D >> (12)) ^ (*D << (20)) ^ CLK;             \
+                                                        \
+    A = &WALK[PT1 ^ 6]; RES[i++] ^= *A;                 \
+    B = &WALK[PT2 ^ 3]; RES[i++] ^= *B;                 \
+    C = &WALK[PT1 ^ 7]; RES[i++] ^= *C;                 \
+    D = &WALK[PT2 ^ 7]; RES[i++] ^= *D;                 \
+                                                        \
+    IN = (*A >> (13)) ^ (*A << (19)) ^ CLK;             \
+    *A = (*B >> (14)) ^ (*B << (18)) ^ CLK;             \
+    *B = IN;                                            \
+    *C = (*C >> (15)) ^ (*C << (17)) ^ CLK;             \
+    *D = (*D >> (16)) ^ (*D << (16)) ^ CLK;             \
+                                                        \
+    PT1 = ( RES[( i - 8 ) ^ PTX] ^                      \
+            WALK[PT1 ^ PTX ^ 7] ) & (~1);               \
+    PT1 ^= (PT2 ^ 0x10) & 0x10;                         \
+                                                        \
+    for( n++, i = 0; i < 16; i++ )                      \
+        hs->pool[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i];
+
+/*
+ * Entropy gathering function
+ */
+static void havege_fill( mbedtls_havege_state *hs )
+{
+    int i, n = 0;
+    int  U1,  U2, *A, *B, *C, *D;
+    int PT1, PT2, *WALK, RES[16];
+    int PTX, PTY, CLK, PTEST, IN;
+
+    WALK = hs->WALK;
+    PT1  = hs->PT1;
+    PT2  = hs->PT2;
+
+    PTX  = U1 = 0;
+    PTY  = U2 = 0;
+
+    (void)PTX;
+
+    memset( RES, 0, sizeof( RES ) );
+
+    while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 )
+    {
+        ONE_ITERATION
+        ONE_ITERATION
+        ONE_ITERATION
+        ONE_ITERATION
+    }
+
+    hs->PT1 = PT1;
+    hs->PT2 = PT2;
+
+    hs->offset[0] = 0;
+    hs->offset[1] = MBEDTLS_HAVEGE_COLLECT_SIZE / 2;
+}
+
+/*
+ * HAVEGE initialization
+ */
+void mbedtls_havege_init( mbedtls_havege_state *hs )
+{
+    memset( hs, 0, sizeof( mbedtls_havege_state ) );
+
+    havege_fill( hs );
+}
+
+void mbedtls_havege_free( mbedtls_havege_state *hs )
+{
+    if( hs == NULL )
+        return;
+
+    mbedtls_platform_zeroize( hs, sizeof( mbedtls_havege_state ) );
+}
+
+/*
+ * HAVEGE rand function
+ */
+int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
+{
+    int val;
+    size_t use_len;
+    mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng;
+    unsigned char *p = buf;
+
+    while( len > 0 )
+    {
+        use_len = len;
+        if( use_len > sizeof(int) )
+            use_len = sizeof(int);
+
+        if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE )
+            havege_fill( hs );
+
+        val  = hs->pool[hs->offset[0]++];
+        val ^= hs->pool[hs->offset[1]++];
+
+        memcpy( p, &val, use_len );
+
+        len -= use_len;
+        p += use_len;
+    }
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_HAVEGE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/hkdf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/hkdf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/hkdf.c	(revision 398)
@@ -0,0 +1,192 @@
+/*
+ *  HKDF implementation -- RFC 5869
+ *
+ *  Copyright (C) 2016-2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_HKDF_C)
+
+#include <string.h>
+#include "mbedtls/hkdf.h"
+#include "mbedtls/platform_util.h"
+
+int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
+                  size_t salt_len, const unsigned char *ikm, size_t ikm_len,
+                  const unsigned char *info, size_t info_len,
+                  unsigned char *okm, size_t okm_len )
+{
+    int ret;
+    unsigned char prk[MBEDTLS_MD_MAX_SIZE];
+
+    ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk );
+
+    if( ret == 0 )
+    {
+        ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ),
+                                   info, info_len, okm, okm_len );
+    }
+
+    mbedtls_platform_zeroize( prk, sizeof( prk ) );
+
+    return( ret );
+}
+
+int mbedtls_hkdf_extract( const mbedtls_md_info_t *md,
+                          const unsigned char *salt, size_t salt_len,
+                          const unsigned char *ikm, size_t ikm_len,
+                          unsigned char *prk )
+{
+    unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' };
+
+    if( salt == NULL )
+    {
+        size_t hash_len;
+
+        if( salt_len != 0 )
+        {
+            return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
+        }
+
+        hash_len = mbedtls_md_get_size( md );
+
+        if( hash_len == 0 )
+        {
+            return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA;
+        }
+
+        salt = null_salt;
+        salt_len = hash_len;
+    }
+
+    return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) );
+}
+
+int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
+                         size_t prk_len, const unsigned char *info,
+                         size_t info_len, unsigned char *okm, size_t okm_len )
+{
+    size_t hash_len;
+    size_t where = 0;
+    size_t n;
+    size_t t_len = 0;
+    size_t i;
+    int ret = 0;
+    mbedtls_md_context_t ctx;
+    unsigned char t[MBEDTLS_MD_MAX_SIZE];
+
+    if( okm == NULL )
+    {
+        return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
+    }
+
+    hash_len = mbedtls_md_get_size( md );
+
+    if( prk_len < hash_len || hash_len == 0 )
+    {
+        return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
+    }
+
+    if( info == NULL )
+    {
+        info = (const unsigned char *) "";
+        info_len = 0;
+    }
+
+    n = okm_len / hash_len;
+
+    if( (okm_len % hash_len) != 0 )
+    {
+        n++;
+    }
+
+    /*
+     * Per RFC 5869 Section 2.3, okm_len must not exceed
+     * 255 times the hash length
+     */
+    if( n > 255 )
+    {
+        return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA );
+    }
+
+    mbedtls_md_init( &ctx );
+
+    if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 )
+    {
+        goto exit;
+    }
+
+    /*
+     * Compute T = T(1) | T(2) | T(3) | ... | T(N)
+     * Where T(N) is defined in RFC 5869 Section 2.3
+     */
+    for( i = 1; i <= n; i++ )
+    {
+        size_t num_to_copy;
+        unsigned char c = i & 0xff;
+
+        ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len );
+        if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        ret = mbedtls_md_hmac_update( &ctx, t, t_len );
+        if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        ret = mbedtls_md_hmac_update( &ctx, info, info_len );
+        if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        /* The constant concatenated to the end of each T(n) is a single octet.
+         * */
+        ret = mbedtls_md_hmac_update( &ctx, &c, 1 );
+        if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        ret = mbedtls_md_hmac_finish( &ctx, t );
+        if( ret != 0 )
+        {
+            goto exit;
+        }
+
+        num_to_copy = i != n ? hash_len : okm_len - where;
+        memcpy( okm + where, t, num_to_copy );
+        where += hash_len;
+        t_len = hash_len;
+    }
+
+exit:
+    mbedtls_md_free( &ctx );
+    mbedtls_platform_zeroize( t, sizeof( t ) );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_HKDF_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/hmac_drbg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/hmac_drbg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/hmac_drbg.c	(revision 398)
@@ -0,0 +1,580 @@
+/*
+ *  HMAC_DRBG implementation (NIST SP 800-90)
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ *  The NIST SP 800-90A DRBGs are described in the following publication.
+ *  http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
+ *  References below are based on rev. 1 (January 2012).
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_HMAC_DRBG_C)
+
+#include "mbedtls/hmac_drbg.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_FS_IO)
+#include <stdio.h>
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_SELF_TEST */
+#endif /* MBEDTLS_PLATFORM_C */
+
+/*
+ * HMAC_DRBG context initialization
+ */
+void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+}
+
+/*
+ * HMAC_DRBG update, using optional additional data (10.1.2.2)
+ */
+int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
+                                  const unsigned char *additional,
+                                  size_t add_len )
+{
+    size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
+    unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
+    unsigned char sep[1];
+    unsigned char K[MBEDTLS_MD_MAX_SIZE];
+    int ret;
+
+    for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
+    {
+        /* Step 1 or 4 */
+        if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+                                            ctx->V, md_len ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+                                            sep, 1 ) ) != 0 )
+            goto exit;
+        if( rounds == 2 )
+        {
+            if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+                                                additional, add_len ) ) != 0 )
+            goto exit;
+        }
+        if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
+            goto exit;
+
+        /* Step 2 or 5 */
+        if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+                                            ctx->V, md_len ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
+            goto exit;
+    }
+
+exit:
+    mbedtls_platform_zeroize( K, sizeof( K ) );
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
+                               const unsigned char *additional,
+                               size_t add_len )
+{
+    (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+/*
+ * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
+ */
+int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
+                        const mbedtls_md_info_t * md_info,
+                        const unsigned char *data, size_t data_len )
+{
+    int ret;
+
+    if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
+        return( ret );
+
+    /*
+     * Set initial working state.
+     * Use the V memory location, which is currently all 0, to initialize the
+     * MD context with an all-zero key. Then set V to its initial value.
+     */
+    if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
+                                        mbedtls_md_get_size( md_info ) ) ) != 0 )
+        return( ret );
+    memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
+
+    if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+/*
+ * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
+ */
+int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
+                      const unsigned char *additional, size_t len )
+{
+    unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
+    size_t seedlen;
+    int ret;
+
+    /* III. Check input length */
+    if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
+        ctx->entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
+    {
+        return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
+    }
+
+    memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
+
+    /* IV. Gather entropy_len bytes of entropy for the seed */
+    if( ( ret = ctx->f_entropy( ctx->p_entropy,
+                                seed, ctx->entropy_len ) ) != 0 )
+        return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
+
+    seedlen = ctx->entropy_len;
+
+    /* 1. Concatenate entropy and additional data if any */
+    if( additional != NULL && len != 0 )
+    {
+        memcpy( seed + seedlen, additional, len );
+        seedlen += len;
+    }
+
+    /* 2. Update state */
+    if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
+        goto exit;
+
+    /* 3. Reset reseed_counter */
+    ctx->reseed_counter = 1;
+
+exit:
+    /* 4. Done */
+    mbedtls_platform_zeroize( seed, seedlen );
+    return( ret );
+}
+
+/*
+ * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
+ */
+int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
+                    const mbedtls_md_info_t * md_info,
+                    int (*f_entropy)(void *, unsigned char *, size_t),
+                    void *p_entropy,
+                    const unsigned char *custom,
+                    size_t len )
+{
+    int ret;
+    size_t entropy_len, md_size;
+
+    if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
+        return( ret );
+
+    md_size = mbedtls_md_get_size( md_info );
+
+    /*
+     * Set initial working state.
+     * Use the V memory location, which is currently all 0, to initialize the
+     * MD context with an all-zero key. Then set V to its initial value.
+     */
+    if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
+        return( ret );
+    memset( ctx->V, 0x01, md_size );
+
+    ctx->f_entropy = f_entropy;
+    ctx->p_entropy = p_entropy;
+
+    ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
+
+    /*
+     * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
+     * each hash function, then according to SP800-90A rev1 10.1 table 2,
+     * min_entropy_len (in bits) is security_strength.
+     *
+     * (This also matches the sizes used in the NIST test vectors.)
+     */
+    entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
+                  md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
+                                  32;  /* better (256+) -> 256 bits */
+
+    /*
+     * For initialisation, use more entropy to emulate a nonce
+     * (Again, matches test vectors.)
+     */
+    ctx->entropy_len = entropy_len * 3 / 2;
+
+    if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 )
+        return( ret );
+
+    ctx->entropy_len = entropy_len;
+
+    return( 0 );
+}
+
+/*
+ * Set prediction resistance
+ */
+void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
+                                          int resistance )
+{
+    ctx->prediction_resistance = resistance;
+}
+
+/*
+ * Set entropy length grabbed for reseeds
+ */
+void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
+{
+    ctx->entropy_len = len;
+}
+
+/*
+ * Set reseed interval
+ */
+void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
+{
+    ctx->reseed_interval = interval;
+}
+
+/*
+ * HMAC_DRBG random function with optional additional data:
+ * 10.1.2.5 (arabic) + 9.3 (Roman)
+ */
+int mbedtls_hmac_drbg_random_with_add( void *p_rng,
+                               unsigned char *output, size_t out_len,
+                               const unsigned char *additional, size_t add_len )
+{
+    int ret;
+    mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
+    size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
+    size_t left = out_len;
+    unsigned char *out = output;
+
+    /* II. Check request length */
+    if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
+        return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
+
+    /* III. Check input length */
+    if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
+        return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
+
+    /* 1. (aka VII and IX) Check reseed counter and PR */
+    if( ctx->f_entropy != NULL && /* For no-reseeding instances */
+        ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
+          ctx->reseed_counter > ctx->reseed_interval ) )
+    {
+        if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
+            return( ret );
+
+        add_len = 0; /* VII.4 */
+    }
+
+    /* 2. Use additional data if any */
+    if( additional != NULL && add_len != 0 )
+    {
+        if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
+                                                  additional, add_len ) ) != 0 )
+            goto exit;
+    }
+
+    /* 3, 4, 5. Generate bytes */
+    while( left != 0 )
+    {
+        size_t use_len = left > md_len ? md_len : left;
+
+        if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
+                                            ctx->V, md_len ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
+            goto exit;
+
+        memcpy( out, ctx->V, use_len );
+        out += use_len;
+        left -= use_len;
+    }
+
+    /* 6. Update */
+    if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
+                                              additional, add_len ) ) != 0 )
+        goto exit;
+
+    /* 7. Update reseed counter */
+    ctx->reseed_counter++;
+
+exit:
+    /* 8. Done */
+    return( ret );
+}
+
+/*
+ * HMAC_DRBG random function
+ */
+int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
+{
+    int ret;
+    mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
+}
+
+/*
+ * Free an HMAC_DRBG context
+ */
+void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_free( &ctx->mutex );
+#endif
+    mbedtls_md_free( &ctx->md_ctx );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
+}
+
+#if defined(MBEDTLS_FS_IO)
+int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
+{
+    int ret;
+    FILE *f;
+    unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
+
+    if( ( f = fopen( path, "wb" ) ) == NULL )
+        return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
+
+    if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
+        goto exit;
+
+    if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
+    {
+        ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
+        goto exit;
+    }
+
+    ret = 0;
+
+exit:
+    fclose( f );
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+
+    return( ret );
+}
+
+int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
+{
+    int ret = 0;
+    FILE *f = NULL;
+    size_t n;
+    unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
+    unsigned char c;
+
+    if( ( f = fopen( path, "rb" ) ) == NULL )
+        return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
+
+    n = fread( buf, 1, sizeof( buf ), f );
+    if( fread( &c, 1, 1, f ) != 0 )
+    {
+        ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
+        goto exit;
+    }
+    if( n == 0 || ferror( f ) )
+    {
+        ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
+        goto exit;
+    }
+    fclose( f );
+    f = NULL;
+
+    ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
+
+exit:
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+    if( f != NULL )
+        fclose( f );
+    if( ret != 0 )
+        return( ret );
+    return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
+}
+#endif /* MBEDTLS_FS_IO */
+
+
+#if defined(MBEDTLS_SELF_TEST)
+
+#if !defined(MBEDTLS_SHA1_C)
+/* Dummy checkup routine */
+int mbedtls_hmac_drbg_self_test( int verbose )
+{
+    (void) verbose;
+    return( 0 );
+}
+#else
+
+#define OUTPUT_LEN  80
+
+/* From a NIST PR=true test vector */
+static const unsigned char entropy_pr[] = {
+    0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
+    0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
+    0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
+    0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
+    0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
+static const unsigned char result_pr[OUTPUT_LEN] = {
+    0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
+    0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
+    0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
+    0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
+    0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
+    0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
+    0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
+
+/* From a NIST PR=false test vector */
+static const unsigned char entropy_nopr[] = {
+    0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
+    0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
+    0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
+    0xe9, 0x9d, 0xfe, 0xdf };
+static const unsigned char result_nopr[OUTPUT_LEN] = {
+    0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
+    0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
+    0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
+    0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
+    0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
+    0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
+    0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
+
+/* "Entropy" from buffer */
+static size_t test_offset;
+static int hmac_drbg_self_test_entropy( void *data,
+                                        unsigned char *buf, size_t len )
+{
+    const unsigned char *p = data;
+    memcpy( buf, p + test_offset, len );
+    test_offset += len;
+    return( 0 );
+}
+
+#define CHK( c )    if( (c) != 0 )                          \
+                    {                                       \
+                        if( verbose != 0 )                  \
+                            mbedtls_printf( "failed\n" );  \
+                        return( 1 );                        \
+                    }
+
+/*
+ * Checkup routine for HMAC_DRBG with SHA-1
+ */
+int mbedtls_hmac_drbg_self_test( int verbose )
+{
+    mbedtls_hmac_drbg_context ctx;
+    unsigned char buf[OUTPUT_LEN];
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
+
+    mbedtls_hmac_drbg_init( &ctx );
+
+    /*
+     * PR = True
+     */
+    if( verbose != 0 )
+        mbedtls_printf( "  HMAC_DRBG (PR = True) : " );
+
+    test_offset = 0;
+    CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
+                         hmac_drbg_self_test_entropy, (void *) entropy_pr,
+                         NULL, 0 ) );
+    mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
+    CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
+    CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
+    CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
+    mbedtls_hmac_drbg_free( &ctx );
+
+    mbedtls_hmac_drbg_free( &ctx );
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    /*
+     * PR = False
+     */
+    if( verbose != 0 )
+        mbedtls_printf( "  HMAC_DRBG (PR = False) : " );
+
+    mbedtls_hmac_drbg_init( &ctx );
+
+    test_offset = 0;
+    CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
+                         hmac_drbg_self_test_entropy, (void *) entropy_nopr,
+                         NULL, 0 ) );
+    CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
+    CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
+    CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
+    CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
+    mbedtls_hmac_drbg_free( &ctx );
+
+    mbedtls_hmac_drbg_free( &ctx );
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_HMAC_DRBG_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md.c	(revision 398)
@@ -0,0 +1,475 @@
+/**
+ * \file mbedtls_md.c
+ *
+ * \brief Generic message digest wrapper for mbed TLS
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_MD_C)
+
+#include "mbedtls/md.h"
+#include "mbedtls/md_internal.h"
+#include "mbedtls/platform_util.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#include <string.h>
+
+#if defined(MBEDTLS_FS_IO)
+#include <stdio.h>
+#endif
+
+/*
+ * Reminder: update profiles in x509_crt.c when adding a new hash!
+ */
+static const int supported_digests[] = {
+
+#if defined(MBEDTLS_SHA512_C)
+        MBEDTLS_MD_SHA512,
+        MBEDTLS_MD_SHA384,
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+        MBEDTLS_MD_SHA256,
+        MBEDTLS_MD_SHA224,
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+        MBEDTLS_MD_SHA1,
+#endif
+
+#if defined(MBEDTLS_RIPEMD160_C)
+        MBEDTLS_MD_RIPEMD160,
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+        MBEDTLS_MD_MD5,
+#endif
+
+#if defined(MBEDTLS_MD4_C)
+        MBEDTLS_MD_MD4,
+#endif
+
+#if defined(MBEDTLS_MD2_C)
+        MBEDTLS_MD_MD2,
+#endif
+
+        MBEDTLS_MD_NONE
+};
+
+const int *mbedtls_md_list( void )
+{
+    return( supported_digests );
+}
+
+const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
+{
+    if( NULL == md_name )
+        return( NULL );
+
+    /* Get the appropriate digest information */
+#if defined(MBEDTLS_MD2_C)
+    if( !strcmp( "MD2", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
+#endif
+#if defined(MBEDTLS_MD4_C)
+    if( !strcmp( "MD4", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
+#endif
+#if defined(MBEDTLS_MD5_C)
+    if( !strcmp( "MD5", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+    if( !strcmp( "RIPEMD160", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+    if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    if( !strcmp( "SHA224", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
+    if( !strcmp( "SHA256", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+    if( !strcmp( "SHA384", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
+    if( !strcmp( "SHA512", md_name ) )
+        return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
+#endif
+    return( NULL );
+}
+
+const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
+{
+    switch( md_type )
+    {
+#if defined(MBEDTLS_MD2_C)
+        case MBEDTLS_MD_MD2:
+            return( &mbedtls_md2_info );
+#endif
+#if defined(MBEDTLS_MD4_C)
+        case MBEDTLS_MD_MD4:
+            return( &mbedtls_md4_info );
+#endif
+#if defined(MBEDTLS_MD5_C)
+        case MBEDTLS_MD_MD5:
+            return( &mbedtls_md5_info );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+        case MBEDTLS_MD_RIPEMD160:
+            return( &mbedtls_ripemd160_info );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+        case MBEDTLS_MD_SHA1:
+            return( &mbedtls_sha1_info );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+        case MBEDTLS_MD_SHA224:
+            return( &mbedtls_sha224_info );
+        case MBEDTLS_MD_SHA256:
+            return( &mbedtls_sha256_info );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+        case MBEDTLS_MD_SHA384:
+            return( &mbedtls_sha384_info );
+        case MBEDTLS_MD_SHA512:
+            return( &mbedtls_sha512_info );
+#endif
+        default:
+            return( NULL );
+    }
+}
+
+void mbedtls_md_init( mbedtls_md_context_t *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
+}
+
+void mbedtls_md_free( mbedtls_md_context_t *ctx )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return;
+
+    if( ctx->md_ctx != NULL )
+        ctx->md_info->ctx_free_func( ctx->md_ctx );
+
+    if( ctx->hmac_ctx != NULL )
+    {
+        mbedtls_platform_zeroize( ctx->hmac_ctx,
+                                  2 * ctx->md_info->block_size );
+        mbedtls_free( ctx->hmac_ctx );
+    }
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
+}
+
+int mbedtls_md_clone( mbedtls_md_context_t *dst,
+                      const mbedtls_md_context_t *src )
+{
+    if( dst == NULL || dst->md_info == NULL ||
+        src == NULL || src->md_info == NULL ||
+        dst->md_info != src->md_info )
+    {
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+    }
+
+    dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
+
+    return( 0 );
+}
+
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info )
+{
+    return mbedtls_md_setup( ctx, md_info, 1 );
+}
+#endif
+
+int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
+{
+    if( md_info == NULL || ctx == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
+        return( MBEDTLS_ERR_MD_ALLOC_FAILED );
+
+    if( hmac != 0 )
+    {
+        ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
+        if( ctx->hmac_ctx == NULL )
+        {
+            md_info->ctx_free_func( ctx->md_ctx );
+            return( MBEDTLS_ERR_MD_ALLOC_FAILED );
+        }
+    }
+
+    ctx->md_info = md_info;
+
+    return( 0 );
+}
+
+int mbedtls_md_starts( mbedtls_md_context_t *ctx )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    return( ctx->md_info->starts_func( ctx->md_ctx ) );
+}
+
+int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
+}
+
+int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
+}
+
+int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
+            unsigned char *output )
+{
+    if( md_info == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    return( md_info->digest_func( input, ilen, output ) );
+}
+
+#if defined(MBEDTLS_FS_IO)
+int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
+{
+    int ret;
+    FILE *f;
+    size_t n;
+    mbedtls_md_context_t ctx;
+    unsigned char buf[1024];
+
+    if( md_info == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    if( ( f = fopen( path, "rb" ) ) == NULL )
+        return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
+
+    mbedtls_md_init( &ctx );
+
+    if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
+        goto cleanup;
+
+    if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
+        goto cleanup;
+
+    while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
+        if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
+            goto cleanup;
+
+    if( ferror( f ) != 0 )
+        ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
+    else
+        ret = md_info->finish_func( ctx.md_ctx, output );
+
+cleanup:
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+    fclose( f );
+    mbedtls_md_free( &ctx );
+
+    return( ret );
+}
+#endif /* MBEDTLS_FS_IO */
+
+int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
+{
+    int ret;
+    unsigned char sum[MBEDTLS_MD_MAX_SIZE];
+    unsigned char *ipad, *opad;
+    size_t i;
+
+    if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    if( keylen > (size_t) ctx->md_info->block_size )
+    {
+        if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+            goto cleanup;
+        if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )
+            goto cleanup;
+        if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )
+            goto cleanup;
+
+        keylen = ctx->md_info->size;
+        key = sum;
+    }
+
+    ipad = (unsigned char *) ctx->hmac_ctx;
+    opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
+
+    memset( ipad, 0x36, ctx->md_info->block_size );
+    memset( opad, 0x5C, ctx->md_info->block_size );
+
+    for( i = 0; i < keylen; i++ )
+    {
+        ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
+        opad[i] = (unsigned char)( opad[i] ^ key[i] );
+    }
+
+    if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+        goto cleanup;
+    if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
+                                           ctx->md_info->block_size ) ) != 0 )
+        goto cleanup;
+
+cleanup:
+    mbedtls_platform_zeroize( sum, sizeof( sum ) );
+
+    return( ret );
+}
+
+int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
+{
+    if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
+}
+
+int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
+{
+    int ret;
+    unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
+    unsigned char *opad;
+
+    if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
+
+    if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )
+        return( ret );
+    if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+        return( ret );
+    if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,
+                                           ctx->md_info->block_size ) ) != 0 )
+        return( ret );
+    if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,
+                                           ctx->md_info->size ) ) != 0 )
+        return( ret );
+    return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
+}
+
+int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
+{
+    int ret;
+    unsigned char *ipad;
+
+    if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    ipad = (unsigned char *) ctx->hmac_ctx;
+
+    if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+        return( ret );
+    return( ctx->md_info->update_func( ctx->md_ctx, ipad,
+                                       ctx->md_info->block_size ) );
+}
+
+int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
+                     const unsigned char *key, size_t keylen,
+                     const unsigned char *input, size_t ilen,
+                     unsigned char *output )
+{
+    mbedtls_md_context_t ctx;
+    int ret;
+
+    if( md_info == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    mbedtls_md_init( &ctx );
+
+    if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
+        goto cleanup;
+
+    if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
+        goto cleanup;
+    if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
+        goto cleanup;
+    if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
+        goto cleanup;
+
+cleanup:
+    mbedtls_md_free( &ctx );
+
+    return( ret );
+}
+
+int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
+{
+    if( ctx == NULL || ctx->md_info == NULL )
+        return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+
+    return( ctx->md_info->process_func( ctx->md_ctx, data ) );
+}
+
+unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
+{
+    if( md_info == NULL )
+        return( 0 );
+
+    return md_info->size;
+}
+
+mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
+{
+    if( md_info == NULL )
+        return( MBEDTLS_MD_NONE );
+
+    return md_info->type;
+}
+
+const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
+{
+    if( md_info == NULL )
+        return( NULL );
+
+    return md_info->name;
+}
+
+#endif /* MBEDTLS_MD_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md2.c	(revision 398)
@@ -0,0 +1,363 @@
+/*
+ *  RFC 1115/1319 compliant MD2 implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The MD2 algorithm was designed by Ron Rivest in 1989.
+ *
+ *  http://www.ietf.org/rfc/rfc1115.txt
+ *  http://www.ietf.org/rfc/rfc1319.txt
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_MD2_C)
+
+#include "mbedtls/md2.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_MD2_ALT)
+
+static const unsigned char PI_SUBST[256] =
+{
+    0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
+    0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
+    0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
+    0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
+    0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
+    0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
+    0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
+    0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
+    0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
+    0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
+    0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
+    0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
+    0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
+    0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
+    0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
+    0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
+    0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
+    0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
+    0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
+    0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
+    0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
+    0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
+    0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
+    0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
+    0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
+    0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
+};
+
+void mbedtls_md2_init( mbedtls_md2_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_md2_context ) );
+}
+
+void mbedtls_md2_free( mbedtls_md2_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md2_context ) );
+}
+
+void mbedtls_md2_clone( mbedtls_md2_context *dst,
+                        const mbedtls_md2_context *src )
+{
+    *dst = *src;
+}
+
+/*
+ * MD2 context setup
+ */
+int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx )
+{
+    memset( ctx->cksum, 0, 16 );
+    memset( ctx->state, 0, 46 );
+    memset( ctx->buffer, 0, 16 );
+    ctx->left = 0;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md2_starts( mbedtls_md2_context *ctx )
+{
+    mbedtls_md2_starts_ret( ctx );
+}
+#endif
+
+#if !defined(MBEDTLS_MD2_PROCESS_ALT)
+int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
+{
+    int i, j;
+    unsigned char t = 0;
+
+    for( i = 0; i < 16; i++ )
+    {
+        ctx->state[i + 16] = ctx->buffer[i];
+        ctx->state[i + 32] =
+            (unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
+    }
+
+    for( i = 0; i < 18; i++ )
+    {
+        for( j = 0; j < 48; j++ )
+        {
+            ctx->state[j] = (unsigned char)
+               ( ctx->state[j] ^ PI_SUBST[t] );
+            t  = ctx->state[j];
+        }
+
+        t = (unsigned char)( t + i );
+    }
+
+    t = ctx->cksum[15];
+
+    for( i = 0; i < 16; i++ )
+    {
+        ctx->cksum[i] = (unsigned char)
+           ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
+        t  = ctx->cksum[i];
+    }
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md2_process( mbedtls_md2_context *ctx )
+{
+    mbedtls_internal_md2_process( ctx );
+}
+#endif
+#endif /* !MBEDTLS_MD2_PROCESS_ALT */
+
+/*
+ * MD2 process buffer
+ */
+int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen )
+{
+    int ret;
+    size_t fill;
+
+    while( ilen > 0 )
+    {
+        if( ilen > 16 - ctx->left )
+            fill = 16 - ctx->left;
+        else
+            fill = ilen;
+
+        memcpy( ctx->buffer + ctx->left, input, fill );
+
+        ctx->left += fill;
+        input += fill;
+        ilen  -= fill;
+
+        if( ctx->left == 16 )
+        {
+            ctx->left = 0;
+            if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
+                return( ret );
+        }
+    }
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md2_update( mbedtls_md2_context *ctx,
+                         const unsigned char *input,
+                         size_t ilen )
+{
+    mbedtls_md2_update_ret( ctx, input, ilen );
+}
+#endif
+
+/*
+ * MD2 final digest
+ */
+int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
+                            unsigned char output[16] )
+{
+    int ret;
+    size_t i;
+    unsigned char x;
+
+    x = (unsigned char)( 16 - ctx->left );
+
+    for( i = ctx->left; i < 16; i++ )
+        ctx->buffer[i] = x;
+
+    if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
+        return( ret );
+
+    memcpy( ctx->buffer, ctx->cksum, 16 );
+    if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
+        return( ret );
+
+    memcpy( output, ctx->state, 16 );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md2_finish( mbedtls_md2_context *ctx,
+                         unsigned char output[16] )
+{
+    mbedtls_md2_finish_ret( ctx, output );
+}
+#endif
+
+#endif /* !MBEDTLS_MD2_ALT */
+
+/*
+ * output = MD2( input buffer )
+ */
+int mbedtls_md2_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] )
+{
+    int ret;
+    mbedtls_md2_context ctx;
+
+    mbedtls_md2_init( &ctx );
+
+    if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md2_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md2_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_md2_free( &ctx );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md2( const unsigned char *input,
+                  size_t ilen,
+                  unsigned char output[16] )
+{
+    mbedtls_md2_ret( input, ilen, output );
+}
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/*
+ * RFC 1319 test vectors
+ */
+static const unsigned char md2_test_str[7][81] =
+{
+    { "" },
+    { "a" },
+    { "abc" },
+    { "message digest" },
+    { "abcdefghijklmnopqrstuvwxyz" },
+    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
+    { "12345678901234567890123456789012345678901234567890123456789012"
+      "345678901234567890" }
+};
+
+static const size_t md2_test_strlen[7] =
+{
+    0, 1, 3, 14, 26, 62, 80
+};
+
+static const unsigned char md2_test_sum[7][16] =
+{
+    { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
+      0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
+    { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
+      0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
+    { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
+      0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
+    { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
+      0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
+    { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
+      0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
+    { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
+      0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
+    { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
+      0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
+};
+
+/*
+ * Checkup routine
+ */
+int mbedtls_md2_self_test( int verbose )
+{
+    int i, ret = 0;
+    unsigned char md2sum[16];
+
+    for( i = 0; i < 7; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  MD2 test #%d: ", i + 1 );
+
+        ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum );
+        if( ret != 0 )
+            goto fail;
+
+        if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
+        {
+            ret = 1;
+            goto fail;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_MD2_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md4.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md4.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md4.c	(revision 398)
@@ -0,0 +1,468 @@
+/*
+ *  RFC 1186/1320 compliant MD4 implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The MD4 algorithm was designed by Ron Rivest in 1990.
+ *
+ *  http://www.ietf.org/rfc/rfc1186.txt
+ *  http://www.ietf.org/rfc/rfc1320.txt
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_MD4_C)
+
+#include "mbedtls/md4.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_MD4_ALT)
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT32_LE
+#define GET_UINT32_LE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ]       )             \
+        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
+}
+#endif
+
+#ifndef PUT_UINT32_LE
+#define PUT_UINT32_LE(n,b,i)                                    \
+{                                                               \
+    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
+    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
+    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
+    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
+}
+#endif
+
+void mbedtls_md4_init( mbedtls_md4_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_md4_context ) );
+}
+
+void mbedtls_md4_free( mbedtls_md4_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
+}
+
+void mbedtls_md4_clone( mbedtls_md4_context *dst,
+                        const mbedtls_md4_context *src )
+{
+    *dst = *src;
+}
+
+/*
+ * MD4 context setup
+ */
+int mbedtls_md4_starts_ret( mbedtls_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;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md4_starts( mbedtls_md4_context *ctx )
+{
+    mbedtls_md4_starts_ret( ctx );
+}
+#endif
+
+#if !defined(MBEDTLS_MD4_PROCESS_ALT)
+int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
+                                  const unsigned char data[64] )
+{
+    uint32_t X[16], A, B, C, D;
+
+    GET_UINT32_LE( X[ 0], data,  0 );
+    GET_UINT32_LE( X[ 1], data,  4 );
+    GET_UINT32_LE( X[ 2], data,  8 );
+    GET_UINT32_LE( X[ 3], data, 12 );
+    GET_UINT32_LE( X[ 4], data, 16 );
+    GET_UINT32_LE( X[ 5], data, 20 );
+    GET_UINT32_LE( X[ 6], data, 24 );
+    GET_UINT32_LE( X[ 7], data, 28 );
+    GET_UINT32_LE( X[ 8], data, 32 );
+    GET_UINT32_LE( X[ 9], data, 36 );
+    GET_UINT32_LE( X[10], data, 40 );
+    GET_UINT32_LE( X[11], data, 44 );
+    GET_UINT32_LE( X[12], data, 48 );
+    GET_UINT32_LE( X[13], data, 52 );
+    GET_UINT32_LE( X[14], data, 56 );
+    GET_UINT32_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;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md4_process( mbedtls_md4_context *ctx,
+                          const unsigned char data[64] )
+{
+    mbedtls_internal_md4_process( ctx, data );
+}
+#endif
+#endif /* !MBEDTLS_MD4_PROCESS_ALT */
+
+/*
+ * MD4 process buffer
+ */
+int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen )
+{
+    int ret;
+    size_t fill;
+    uint32_t left;
+
+    if( ilen == 0 )
+        return( 0 );
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += (uint32_t) ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (uint32_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left),
+                (void *) input, fill );
+
+        if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
+            return( ret );
+
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+    {
+        memcpy( (void *) (ctx->buffer + left),
+                (void *) input, ilen );
+    }
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md4_update( mbedtls_md4_context *ctx,
+                         const unsigned char *input,
+                         size_t ilen )
+{
+    mbedtls_md4_update_ret( ctx, input, ilen );
+}
+#endif
+
+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
+ */
+int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
+                            unsigned char output[16] )
+{
+    int ret;
+    uint32_t last, padn;
+    uint32_t high, low;
+    unsigned char msglen[8];
+
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT32_LE( low,  msglen, 0 );
+    PUT_UINT32_LE( high, msglen, 4 );
+
+    last = ctx->total[0] & 0x3F;
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+    ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
+    if( ret != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
+        return( ret );
+
+
+    PUT_UINT32_LE( ctx->state[0], output,  0 );
+    PUT_UINT32_LE( ctx->state[1], output,  4 );
+    PUT_UINT32_LE( ctx->state[2], output,  8 );
+    PUT_UINT32_LE( ctx->state[3], output, 12 );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md4_finish( mbedtls_md4_context *ctx,
+                         unsigned char output[16] )
+{
+    mbedtls_md4_finish_ret( ctx, output );
+}
+#endif
+
+#endif /* !MBEDTLS_MD4_ALT */
+
+/*
+ * output = MD4( input buffer )
+ */
+int mbedtls_md4_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] )
+{
+    int ret;
+    mbedtls_md4_context ctx;
+
+    mbedtls_md4_init( &ctx );
+
+    if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_md4_free( &ctx );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md4( const unsigned char *input,
+                  size_t ilen,
+                  unsigned char output[16] )
+{
+    mbedtls_md4_ret( input, ilen, output );
+}
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/*
+ * RFC 1320 test vectors
+ */
+static const unsigned char md4_test_str[7][81] =
+{
+    { "" },
+    { "a" },
+    { "abc" },
+    { "message digest" },
+    { "abcdefghijklmnopqrstuvwxyz" },
+    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
+    { "12345678901234567890123456789012345678901234567890123456789012"
+      "345678901234567890" }
+};
+
+static const size_t md4_test_strlen[7] =
+{
+    0, 1, 3, 14, 26, 62, 80
+};
+
+static const unsigned char md4_test_sum[7][16] =
+{
+    { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
+      0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
+    { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
+      0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
+    { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
+      0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
+    { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
+      0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
+    { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
+      0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
+    { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
+      0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
+    { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
+      0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
+};
+
+/*
+ * Checkup routine
+ */
+int mbedtls_md4_self_test( int verbose )
+{
+    int i, ret = 0;
+    unsigned char md4sum[16];
+
+    for( i = 0; i < 7; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  MD4 test #%d: ", i + 1 );
+
+        ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
+        if( ret != 0 )
+            goto fail;
+
+        if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
+        {
+            ret = 1;
+            goto fail;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_MD4_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md5.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md5.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md5.c	(revision 398)
@@ -0,0 +1,495 @@
+/*
+ *  RFC 1321 compliant MD5 implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The MD5 algorithm was designed by Ron Rivest in 1991.
+ *
+ *  http://www.ietf.org/rfc/rfc1321.txt
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+
+#include "mbedtls/md5.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_MD5_ALT)
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT32_LE
+#define GET_UINT32_LE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ]       )             \
+        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
+}
+#endif
+
+#ifndef PUT_UINT32_LE
+#define PUT_UINT32_LE(n,b,i)                                    \
+{                                                               \
+    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
+    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
+    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
+    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
+}
+#endif
+
+void mbedtls_md5_init( mbedtls_md5_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_md5_context ) );
+}
+
+void mbedtls_md5_free( mbedtls_md5_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md5_context ) );
+}
+
+void mbedtls_md5_clone( mbedtls_md5_context *dst,
+                        const mbedtls_md5_context *src )
+{
+    *dst = *src;
+}
+
+/*
+ * MD5 context setup
+ */
+int mbedtls_md5_starts_ret( mbedtls_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;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md5_starts( mbedtls_md5_context *ctx )
+{
+    mbedtls_md5_starts_ret( ctx );
+}
+#endif
+
+#if !defined(MBEDTLS_MD5_PROCESS_ALT)
+int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
+                                  const unsigned char data[64] )
+{
+    uint32_t X[16], A, B, C, D;
+
+    GET_UINT32_LE( X[ 0], data,  0 );
+    GET_UINT32_LE( X[ 1], data,  4 );
+    GET_UINT32_LE( X[ 2], data,  8 );
+    GET_UINT32_LE( X[ 3], data, 12 );
+    GET_UINT32_LE( X[ 4], data, 16 );
+    GET_UINT32_LE( X[ 5], data, 20 );
+    GET_UINT32_LE( X[ 6], data, 24 );
+    GET_UINT32_LE( X[ 7], data, 28 );
+    GET_UINT32_LE( X[ 8], data, 32 );
+    GET_UINT32_LE( X[ 9], data, 36 );
+    GET_UINT32_LE( X[10], data, 40 );
+    GET_UINT32_LE( X[11], data, 44 );
+    GET_UINT32_LE( X[12], data, 48 );
+    GET_UINT32_LE( X[13], data, 52 );
+    GET_UINT32_LE( X[14], data, 56 );
+    GET_UINT32_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;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md5_process( mbedtls_md5_context *ctx,
+                          const unsigned char data[64] )
+{
+    mbedtls_internal_md5_process( ctx, data );
+}
+#endif
+#endif /* !MBEDTLS_MD5_PROCESS_ALT */
+
+/*
+ * MD5 process buffer
+ */
+int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen )
+{
+    int ret;
+    size_t fill;
+    uint32_t left;
+
+    if( ilen == 0 )
+        return( 0 );
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += (uint32_t) ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (uint32_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, fill );
+        if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 )
+            return( ret );
+
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, ilen );
+    }
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md5_update( mbedtls_md5_context *ctx,
+                         const unsigned char *input,
+                         size_t ilen )
+{
+    mbedtls_md5_update_ret( ctx, input, ilen );
+}
+#endif
+
+/*
+ * MD5 final digest
+ */
+int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
+                            unsigned char output[16] )
+{
+    int ret;
+    uint32_t used;
+    uint32_t high, low;
+
+    /*
+     * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
+     */
+    used = ctx->total[0] & 0x3F;
+
+    ctx->buffer[used++] = 0x80;
+
+    if( used <= 56 )
+    {
+        /* Enough room for padding + length in current block */
+        memset( ctx->buffer + used, 0, 56 - used );
+    }
+    else
+    {
+        /* We'll need an extra block */
+        memset( ctx->buffer + used, 0, 64 - used );
+
+        if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
+        memset( ctx->buffer, 0, 56 );
+    }
+
+    /*
+     * Add message length
+     */
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT32_LE( low,  ctx->buffer, 56 );
+    PUT_UINT32_LE( high, ctx->buffer, 60 );
+
+    if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
+        return( ret );
+
+    /*
+     * Output final state
+     */
+    PUT_UINT32_LE( ctx->state[0], output,  0 );
+    PUT_UINT32_LE( ctx->state[1], output,  4 );
+    PUT_UINT32_LE( ctx->state[2], output,  8 );
+    PUT_UINT32_LE( ctx->state[3], output, 12 );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md5_finish( mbedtls_md5_context *ctx,
+                         unsigned char output[16] )
+{
+    mbedtls_md5_finish_ret( ctx, output );
+}
+#endif
+
+#endif /* !MBEDTLS_MD5_ALT */
+
+/*
+ * output = MD5( input buffer )
+ */
+int mbedtls_md5_ret( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[16] )
+{
+    int ret;
+    mbedtls_md5_context ctx;
+
+    mbedtls_md5_init( &ctx );
+
+    if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_md5_free( &ctx );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_md5( const unsigned char *input,
+                  size_t ilen,
+                  unsigned char output[16] )
+{
+    mbedtls_md5_ret( input, ilen, output );
+}
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+/*
+ * RFC 1321 test vectors
+ */
+static const unsigned char md5_test_buf[7][81] =
+{
+    { "" },
+    { "a" },
+    { "abc" },
+    { "message digest" },
+    { "abcdefghijklmnopqrstuvwxyz" },
+    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
+    { "12345678901234567890123456789012345678901234567890123456789012"
+      "345678901234567890" }
+};
+
+static const size_t md5_test_buflen[7] =
+{
+    0, 1, 3, 14, 26, 62, 80
+};
+
+static const unsigned char md5_test_sum[7][16] =
+{
+    { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
+      0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
+    { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
+      0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
+    { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
+      0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
+    { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
+      0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
+    { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
+      0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
+    { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
+      0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
+    { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
+      0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
+};
+
+/*
+ * Checkup routine
+ */
+int mbedtls_md5_self_test( int verbose )
+{
+    int i, ret = 0;
+    unsigned char md5sum[16];
+
+    for( i = 0; i < 7; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  MD5 test #%d: ", i + 1 );
+
+        ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum );
+        if( ret != 0 )
+            goto fail;
+
+        if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
+        {
+            ret = 1;
+            goto fail;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_MD5_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md_wrap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md_wrap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/md_wrap.c	(revision 398)
@@ -0,0 +1,586 @@
+/**
+ * \file md_wrap.c
+ *
+ * \brief Generic message digest wrapper for mbed TLS
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_MD_C)
+
+#include "mbedtls/md_internal.h"
+
+#if defined(MBEDTLS_MD2_C)
+#include "mbedtls/md2.h"
+#endif
+
+#if defined(MBEDTLS_MD4_C)
+#include "mbedtls/md4.h"
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+#include "mbedtls/md5.h"
+#endif
+
+#if defined(MBEDTLS_RIPEMD160_C)
+#include "mbedtls/ripemd160.h"
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+#include "mbedtls/sha1.h"
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+#include "mbedtls/sha256.h"
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+#include "mbedtls/sha512.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#if defined(MBEDTLS_MD2_C)
+
+static int md2_starts_wrap( void *ctx )
+{
+    return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) );
+}
+
+static int md2_update_wrap( void *ctx, const unsigned char *input,
+                             size_t ilen )
+{
+    return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) );
+}
+
+static int md2_finish_wrap( void *ctx, unsigned char *output )
+{
+    return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) );
+}
+
+static void *md2_ctx_alloc( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) );
+
+    if( ctx != NULL )
+        mbedtls_md2_init( (mbedtls_md2_context *) ctx );
+
+    return( ctx );
+}
+
+static void md2_ctx_free( void *ctx )
+{
+    mbedtls_md2_free( (mbedtls_md2_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static void md2_clone_wrap( void *dst, const void *src )
+{
+    mbedtls_md2_clone( (mbedtls_md2_context *) dst,
+                 (const mbedtls_md2_context *) src );
+}
+
+static int md2_process_wrap( void *ctx, const unsigned char *data )
+{
+    ((void) data);
+
+    return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
+}
+
+const mbedtls_md_info_t mbedtls_md2_info = {
+    MBEDTLS_MD_MD2,
+    "MD2",
+    16,
+    16,
+    md2_starts_wrap,
+    md2_update_wrap,
+    md2_finish_wrap,
+    mbedtls_md2_ret,
+    md2_ctx_alloc,
+    md2_ctx_free,
+    md2_clone_wrap,
+    md2_process_wrap,
+};
+
+#endif /* MBEDTLS_MD2_C */
+
+#if defined(MBEDTLS_MD4_C)
+
+static int md4_starts_wrap( void *ctx )
+{
+    return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) );
+}
+
+static int md4_update_wrap( void *ctx, const unsigned char *input,
+                             size_t ilen )
+{
+    return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) );
+}
+
+static int md4_finish_wrap( void *ctx, unsigned char *output )
+{
+    return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) );
+}
+
+static void *md4_ctx_alloc( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) );
+
+    if( ctx != NULL )
+        mbedtls_md4_init( (mbedtls_md4_context *) ctx );
+
+    return( ctx );
+}
+
+static void md4_ctx_free( void *ctx )
+{
+    mbedtls_md4_free( (mbedtls_md4_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static void md4_clone_wrap( void *dst, const void *src )
+{
+    mbedtls_md4_clone( (mbedtls_md4_context *) dst,
+                       (const mbedtls_md4_context *) src );
+}
+
+static int md4_process_wrap( void *ctx, const unsigned char *data )
+{
+    return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
+}
+
+const mbedtls_md_info_t mbedtls_md4_info = {
+    MBEDTLS_MD_MD4,
+    "MD4",
+    16,
+    64,
+    md4_starts_wrap,
+    md4_update_wrap,
+    md4_finish_wrap,
+    mbedtls_md4_ret,
+    md4_ctx_alloc,
+    md4_ctx_free,
+    md4_clone_wrap,
+    md4_process_wrap,
+};
+
+#endif /* MBEDTLS_MD4_C */
+
+#if defined(MBEDTLS_MD5_C)
+
+static int md5_starts_wrap( void *ctx )
+{
+    return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) );
+}
+
+static int md5_update_wrap( void *ctx, const unsigned char *input,
+                             size_t ilen )
+{
+    return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) );
+}
+
+static int md5_finish_wrap( void *ctx, unsigned char *output )
+{
+    return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) );
+}
+
+static void *md5_ctx_alloc( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) );
+
+    if( ctx != NULL )
+        mbedtls_md5_init( (mbedtls_md5_context *) ctx );
+
+    return( ctx );
+}
+
+static void md5_ctx_free( void *ctx )
+{
+    mbedtls_md5_free( (mbedtls_md5_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static void md5_clone_wrap( void *dst, const void *src )
+{
+    mbedtls_md5_clone( (mbedtls_md5_context *) dst,
+                       (const mbedtls_md5_context *) src );
+}
+
+static int md5_process_wrap( void *ctx, const unsigned char *data )
+{
+    return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
+}
+
+const mbedtls_md_info_t mbedtls_md5_info = {
+    MBEDTLS_MD_MD5,
+    "MD5",
+    16,
+    64,
+    md5_starts_wrap,
+    md5_update_wrap,
+    md5_finish_wrap,
+    mbedtls_md5_ret,
+    md5_ctx_alloc,
+    md5_ctx_free,
+    md5_clone_wrap,
+    md5_process_wrap,
+};
+
+#endif /* MBEDTLS_MD5_C */
+
+#if defined(MBEDTLS_RIPEMD160_C)
+
+static int ripemd160_starts_wrap( void *ctx )
+{
+    return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) );
+}
+
+static int ripemd160_update_wrap( void *ctx, const unsigned char *input,
+                                   size_t ilen )
+{
+    return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx,
+                                          input, ilen ) );
+}
+
+static int ripemd160_finish_wrap( void *ctx, unsigned char *output )
+{
+    return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx,
+                                          output ) );
+}
+
+static void *ripemd160_ctx_alloc( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) );
+
+    if( ctx != NULL )
+        mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx );
+
+    return( ctx );
+}
+
+static void ripemd160_ctx_free( void *ctx )
+{
+    mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static void ripemd160_clone_wrap( void *dst, const void *src )
+{
+    mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst,
+                       (const mbedtls_ripemd160_context *) src );
+}
+
+static int ripemd160_process_wrap( void *ctx, const unsigned char *data )
+{
+    return( mbedtls_internal_ripemd160_process(
+                                (mbedtls_ripemd160_context *) ctx, data ) );
+}
+
+const mbedtls_md_info_t mbedtls_ripemd160_info = {
+    MBEDTLS_MD_RIPEMD160,
+    "RIPEMD160",
+    20,
+    64,
+    ripemd160_starts_wrap,
+    ripemd160_update_wrap,
+    ripemd160_finish_wrap,
+    mbedtls_ripemd160_ret,
+    ripemd160_ctx_alloc,
+    ripemd160_ctx_free,
+    ripemd160_clone_wrap,
+    ripemd160_process_wrap,
+};
+
+#endif /* MBEDTLS_RIPEMD160_C */
+
+#if defined(MBEDTLS_SHA1_C)
+
+static int sha1_starts_wrap( void *ctx )
+{
+    return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) );
+}
+
+static int sha1_update_wrap( void *ctx, const unsigned char *input,
+                              size_t ilen )
+{
+    return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx,
+                                     input, ilen ) );
+}
+
+static int sha1_finish_wrap( void *ctx, unsigned char *output )
+{
+    return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) );
+}
+
+static void *sha1_ctx_alloc( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) );
+
+    if( ctx != NULL )
+        mbedtls_sha1_init( (mbedtls_sha1_context *) ctx );
+
+    return( ctx );
+}
+
+static void sha1_clone_wrap( void *dst, const void *src )
+{
+    mbedtls_sha1_clone( (mbedtls_sha1_context *) dst,
+                  (const mbedtls_sha1_context *) src );
+}
+
+static void sha1_ctx_free( void *ctx )
+{
+    mbedtls_sha1_free( (mbedtls_sha1_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static int sha1_process_wrap( void *ctx, const unsigned char *data )
+{
+    return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx,
+                                           data ) );
+}
+
+const mbedtls_md_info_t mbedtls_sha1_info = {
+    MBEDTLS_MD_SHA1,
+    "SHA1",
+    20,
+    64,
+    sha1_starts_wrap,
+    sha1_update_wrap,
+    sha1_finish_wrap,
+    mbedtls_sha1_ret,
+    sha1_ctx_alloc,
+    sha1_ctx_free,
+    sha1_clone_wrap,
+    sha1_process_wrap,
+};
+
+#endif /* MBEDTLS_SHA1_C */
+
+/*
+ * Wrappers for generic message digests
+ */
+#if defined(MBEDTLS_SHA256_C)
+
+static int sha224_starts_wrap( void *ctx )
+{
+    return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) );
+}
+
+static int sha224_update_wrap( void *ctx, const unsigned char *input,
+                                size_t ilen )
+{
+    return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx,
+                                       input, ilen ) );
+}
+
+static int sha224_finish_wrap( void *ctx, unsigned char *output )
+{
+    return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx,
+                                       output ) );
+}
+
+static int sha224_wrap( const unsigned char *input, size_t ilen,
+                        unsigned char *output )
+{
+    return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
+}
+
+static void *sha224_ctx_alloc( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) );
+
+    if( ctx != NULL )
+        mbedtls_sha256_init( (mbedtls_sha256_context *) ctx );
+
+    return( ctx );
+}
+
+static void sha224_ctx_free( void *ctx )
+{
+    mbedtls_sha256_free( (mbedtls_sha256_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static void sha224_clone_wrap( void *dst, const void *src )
+{
+    mbedtls_sha256_clone( (mbedtls_sha256_context *) dst,
+                    (const mbedtls_sha256_context *) src );
+}
+
+static int sha224_process_wrap( void *ctx, const unsigned char *data )
+{
+    return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx,
+                                             data ) );
+}
+
+const mbedtls_md_info_t mbedtls_sha224_info = {
+    MBEDTLS_MD_SHA224,
+    "SHA224",
+    28,
+    64,
+    sha224_starts_wrap,
+    sha224_update_wrap,
+    sha224_finish_wrap,
+    sha224_wrap,
+    sha224_ctx_alloc,
+    sha224_ctx_free,
+    sha224_clone_wrap,
+    sha224_process_wrap,
+};
+
+static int sha256_starts_wrap( void *ctx )
+{
+    return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) );
+}
+
+static int sha256_wrap( const unsigned char *input, size_t ilen,
+                        unsigned char *output )
+{
+    return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
+}
+
+const mbedtls_md_info_t mbedtls_sha256_info = {
+    MBEDTLS_MD_SHA256,
+    "SHA256",
+    32,
+    64,
+    sha256_starts_wrap,
+    sha224_update_wrap,
+    sha224_finish_wrap,
+    sha256_wrap,
+    sha224_ctx_alloc,
+    sha224_ctx_free,
+    sha224_clone_wrap,
+    sha224_process_wrap,
+};
+
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+
+static int sha384_starts_wrap( void *ctx )
+{
+    return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) );
+}
+
+static int sha384_update_wrap( void *ctx, const unsigned char *input,
+                               size_t ilen )
+{
+    return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx,
+                                       input, ilen ) );
+}
+
+static int sha384_finish_wrap( void *ctx, unsigned char *output )
+{
+    return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx,
+                                       output ) );
+}
+
+static int sha384_wrap( const unsigned char *input, size_t ilen,
+                        unsigned char *output )
+{
+    return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
+}
+
+static void *sha384_ctx_alloc( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) );
+
+    if( ctx != NULL )
+        mbedtls_sha512_init( (mbedtls_sha512_context *) ctx );
+
+    return( ctx );
+}
+
+static void sha384_ctx_free( void *ctx )
+{
+    mbedtls_sha512_free( (mbedtls_sha512_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static void sha384_clone_wrap( void *dst, const void *src )
+{
+    mbedtls_sha512_clone( (mbedtls_sha512_context *) dst,
+                    (const mbedtls_sha512_context *) src );
+}
+
+static int sha384_process_wrap( void *ctx, const unsigned char *data )
+{
+    return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx,
+                                             data ) );
+}
+
+const mbedtls_md_info_t mbedtls_sha384_info = {
+    MBEDTLS_MD_SHA384,
+    "SHA384",
+    48,
+    128,
+    sha384_starts_wrap,
+    sha384_update_wrap,
+    sha384_finish_wrap,
+    sha384_wrap,
+    sha384_ctx_alloc,
+    sha384_ctx_free,
+    sha384_clone_wrap,
+    sha384_process_wrap,
+};
+
+static int sha512_starts_wrap( void *ctx )
+{
+    return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) );
+}
+
+static int sha512_wrap( const unsigned char *input, size_t ilen,
+                        unsigned char *output )
+{
+    return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
+}
+
+const mbedtls_md_info_t mbedtls_sha512_info = {
+    MBEDTLS_MD_SHA512,
+    "SHA512",
+    64,
+    128,
+    sha512_starts_wrap,
+    sha384_update_wrap,
+    sha384_finish_wrap,
+    sha512_wrap,
+    sha384_ctx_alloc,
+    sha384_ctx_free,
+    sha384_clone_wrap,
+    sha384_process_wrap,
+};
+
+#endif /* MBEDTLS_SHA512_C */
+
+#endif /* MBEDTLS_MD_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/memory_buffer_alloc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/memory_buffer_alloc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/memory_buffer_alloc.c	(revision 398)
@@ -0,0 +1,750 @@
+/*
+ *  Buffer-based memory allocator
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+#include "mbedtls/memory_buffer_alloc.h"
+
+/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C
+   is dependent upon MBEDTLS_PLATFORM_C */
+#include "mbedtls/platform.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+#include <execinfo.h>
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+#include "mbedtls/threading.h"
+#endif
+
+#define MAGIC1       0xFF00AA55
+#define MAGIC2       0xEE119966
+#define MAX_BT 20
+
+typedef struct _memory_header memory_header;
+struct _memory_header
+{
+    size_t          magic1;
+    size_t          size;
+    size_t          alloc;
+    memory_header   *prev;
+    memory_header   *next;
+    memory_header   *prev_free;
+    memory_header   *next_free;
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+    char            **trace;
+    size_t          trace_count;
+#endif
+    size_t          magic2;
+};
+
+typedef struct
+{
+    unsigned char   *buf;
+    size_t          len;
+    memory_header   *first;
+    memory_header   *first_free;
+    int             verify;
+#if defined(MBEDTLS_MEMORY_DEBUG)
+    size_t          alloc_count;
+    size_t          free_count;
+    size_t          total_used;
+    size_t          maximum_used;
+    size_t          header_count;
+    size_t          maximum_header_count;
+#endif
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t   mutex;
+#endif
+}
+buffer_alloc_ctx;
+
+static buffer_alloc_ctx heap;
+
+#if defined(MBEDTLS_MEMORY_DEBUG)
+static void debug_header( memory_header *hdr )
+{
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+    size_t i;
+#endif
+
+    mbedtls_fprintf( stderr, "HDR:  PTR(%10zu), PREV(%10zu), NEXT(%10zu), "
+                              "ALLOC(%zu), SIZE(%10zu)\n",
+                      (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next,
+                      hdr->alloc, hdr->size );
+    mbedtls_fprintf( stderr, "      FPREV(%10zu), FNEXT(%10zu)\n",
+                      (size_t) hdr->prev_free, (size_t) hdr->next_free );
+
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+    mbedtls_fprintf( stderr, "TRACE: \n" );
+    for( i = 0; i < hdr->trace_count; i++ )
+        mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] );
+    mbedtls_fprintf( stderr, "\n" );
+#endif
+}
+
+static void debug_chain( void )
+{
+    memory_header *cur = heap.first;
+
+    mbedtls_fprintf( stderr, "\nBlock list\n" );
+    while( cur != NULL )
+    {
+        debug_header( cur );
+        cur = cur->next;
+    }
+
+    mbedtls_fprintf( stderr, "Free list\n" );
+    cur = heap.first_free;
+
+    while( cur != NULL )
+    {
+        debug_header( cur );
+        cur = cur->next_free;
+    }
+}
+#endif /* MBEDTLS_MEMORY_DEBUG */
+
+static int verify_header( memory_header *hdr )
+{
+    if( hdr->magic1 != MAGIC1 )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" );
+#endif
+        return( 1 );
+    }
+
+    if( hdr->magic2 != MAGIC2 )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" );
+#endif
+        return( 1 );
+    }
+
+    if( hdr->alloc > 1 )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" );
+#endif
+        return( 1 );
+    }
+
+    if( hdr->prev != NULL && hdr->prev == hdr->next )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        mbedtls_fprintf( stderr, "FATAL: prev == next\n" );
+#endif
+        return( 1 );
+    }
+
+    if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" );
+#endif
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+static int verify_chain( void )
+{
+    memory_header *prv = heap.first, *cur;
+
+    if( prv == NULL || verify_header( prv ) != 0 )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        mbedtls_fprintf( stderr, "FATAL: verification of first header "
+                                  "failed\n" );
+#endif
+        return( 1 );
+    }
+
+    if( heap.first->prev != NULL )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        mbedtls_fprintf( stderr, "FATAL: verification failed: "
+                                  "first->prev != NULL\n" );
+#endif
+        return( 1 );
+    }
+
+    cur = heap.first->next;
+
+    while( cur != NULL )
+    {
+        if( verify_header( cur ) != 0 )
+        {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+            mbedtls_fprintf( stderr, "FATAL: verification of header "
+                                      "failed\n" );
+#endif
+            return( 1 );
+        }
+
+        if( cur->prev != prv )
+        {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+            mbedtls_fprintf( stderr, "FATAL: verification failed: "
+                                      "cur->prev != prv\n" );
+#endif
+            return( 1 );
+        }
+
+        prv = cur;
+        cur = cur->next;
+    }
+
+    return( 0 );
+}
+
+static void *buffer_alloc_calloc( size_t n, size_t size )
+{
+    memory_header *new, *cur = heap.first_free;
+    unsigned char *p;
+    void *ret;
+    size_t original_len, len;
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+    void *trace_buffer[MAX_BT];
+    size_t trace_cnt;
+#endif
+
+    if( heap.buf == NULL || heap.first == NULL )
+        return( NULL );
+
+    original_len = len = n * size;
+
+    if( n == 0 || size == 0 || len / n != size )
+        return( NULL );
+    else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE )
+        return( NULL );
+
+    if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
+    {
+        len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
+        len += MBEDTLS_MEMORY_ALIGN_MULTIPLE;
+    }
+
+    // Find block that fits
+    //
+    while( cur != NULL )
+    {
+        if( cur->size >= len )
+            break;
+
+        cur = cur->next_free;
+    }
+
+    if( cur == NULL )
+        return( NULL );
+
+    if( cur->alloc != 0 )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated "
+                                  "data\n" );
+#endif
+        mbedtls_exit( 1 );
+    }
+
+#if defined(MBEDTLS_MEMORY_DEBUG)
+    heap.alloc_count++;
+#endif
+
+    // Found location, split block if > memory_header + 4 room left
+    //
+    if( cur->size - len < sizeof(memory_header) +
+                          MBEDTLS_MEMORY_ALIGN_MULTIPLE )
+    {
+        cur->alloc = 1;
+
+        // Remove from free_list
+        //
+        if( cur->prev_free != NULL )
+            cur->prev_free->next_free = cur->next_free;
+        else
+            heap.first_free = cur->next_free;
+
+        if( cur->next_free != NULL )
+            cur->next_free->prev_free = cur->prev_free;
+
+        cur->prev_free = NULL;
+        cur->next_free = NULL;
+
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        heap.total_used += cur->size;
+        if( heap.total_used > heap.maximum_used )
+            heap.maximum_used = heap.total_used;
+#endif
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+        trace_cnt = backtrace( trace_buffer, MAX_BT );
+        cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
+        cur->trace_count = trace_cnt;
+#endif
+
+        if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
+            mbedtls_exit( 1 );
+
+        ret = (unsigned char *) cur + sizeof( memory_header );
+        memset( ret, 0, original_len );
+
+        return( ret );
+    }
+
+    p = ( (unsigned char *) cur ) + sizeof(memory_header) + len;
+    new = (memory_header *) p;
+
+    new->size = cur->size - len - sizeof(memory_header);
+    new->alloc = 0;
+    new->prev = cur;
+    new->next = cur->next;
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+    new->trace = NULL;
+    new->trace_count = 0;
+#endif
+    new->magic1 = MAGIC1;
+    new->magic2 = MAGIC2;
+
+    if( new->next != NULL )
+        new->next->prev = new;
+
+    // Replace cur with new in free_list
+    //
+    new->prev_free = cur->prev_free;
+    new->next_free = cur->next_free;
+    if( new->prev_free != NULL )
+        new->prev_free->next_free = new;
+    else
+        heap.first_free = new;
+
+    if( new->next_free != NULL )
+        new->next_free->prev_free = new;
+
+    cur->alloc = 1;
+    cur->size = len;
+    cur->next = new;
+    cur->prev_free = NULL;
+    cur->next_free = NULL;
+
+#if defined(MBEDTLS_MEMORY_DEBUG)
+    heap.header_count++;
+    if( heap.header_count > heap.maximum_header_count )
+        heap.maximum_header_count = heap.header_count;
+    heap.total_used += cur->size;
+    if( heap.total_used > heap.maximum_used )
+        heap.maximum_used = heap.total_used;
+#endif
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+    trace_cnt = backtrace( trace_buffer, MAX_BT );
+    cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
+    cur->trace_count = trace_cnt;
+#endif
+
+    if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
+        mbedtls_exit( 1 );
+
+    ret = (unsigned char *) cur + sizeof( memory_header );
+    memset( ret, 0, original_len );
+
+    return( ret );
+}
+
+static void buffer_alloc_free( void *ptr )
+{
+    memory_header *hdr, *old = NULL;
+    unsigned char *p = (unsigned char *) ptr;
+
+    if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
+        return;
+
+    if( p < heap.buf || p >= heap.buf + heap.len )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed "
+                                  "space\n" );
+#endif
+        mbedtls_exit( 1 );
+    }
+
+    p -= sizeof(memory_header);
+    hdr = (memory_header *) p;
+
+    if( verify_header( hdr ) != 0 )
+        mbedtls_exit( 1 );
+
+    if( hdr->alloc != 1 )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated "
+                                  "data\n" );
+#endif
+        mbedtls_exit( 1 );
+    }
+
+    hdr->alloc = 0;
+
+#if defined(MBEDTLS_MEMORY_DEBUG)
+    heap.free_count++;
+    heap.total_used -= hdr->size;
+#endif
+
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+    free( hdr->trace );
+    hdr->trace = NULL;
+    hdr->trace_count = 0;
+#endif
+
+    // Regroup with block before
+    //
+    if( hdr->prev != NULL && hdr->prev->alloc == 0 )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        heap.header_count--;
+#endif
+        hdr->prev->size += sizeof(memory_header) + hdr->size;
+        hdr->prev->next = hdr->next;
+        old = hdr;
+        hdr = hdr->prev;
+
+        if( hdr->next != NULL )
+            hdr->next->prev = hdr;
+
+        memset( old, 0, sizeof(memory_header) );
+    }
+
+    // Regroup with block after
+    //
+    if( hdr->next != NULL && hdr->next->alloc == 0 )
+    {
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        heap.header_count--;
+#endif
+        hdr->size += sizeof(memory_header) + hdr->next->size;
+        old = hdr->next;
+        hdr->next = hdr->next->next;
+
+        if( hdr->prev_free != NULL || hdr->next_free != NULL )
+        {
+            if( hdr->prev_free != NULL )
+                hdr->prev_free->next_free = hdr->next_free;
+            else
+                heap.first_free = hdr->next_free;
+
+            if( hdr->next_free != NULL )
+                hdr->next_free->prev_free = hdr->prev_free;
+        }
+
+        hdr->prev_free = old->prev_free;
+        hdr->next_free = old->next_free;
+
+        if( hdr->prev_free != NULL )
+            hdr->prev_free->next_free = hdr;
+        else
+            heap.first_free = hdr;
+
+        if( hdr->next_free != NULL )
+            hdr->next_free->prev_free = hdr;
+
+        if( hdr->next != NULL )
+            hdr->next->prev = hdr;
+
+        memset( old, 0, sizeof(memory_header) );
+    }
+
+    // Prepend to free_list if we have not merged
+    // (Does not have to stay in same order as prev / next list)
+    //
+    if( old == NULL )
+    {
+        hdr->next_free = heap.first_free;
+        if( heap.first_free != NULL )
+            heap.first_free->prev_free = hdr;
+        heap.first_free = hdr;
+    }
+
+    if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 )
+        mbedtls_exit( 1 );
+}
+
+void mbedtls_memory_buffer_set_verify( int verify )
+{
+    heap.verify = verify;
+}
+
+int mbedtls_memory_buffer_alloc_verify( void )
+{
+    return verify_chain();
+}
+
+#if defined(MBEDTLS_MEMORY_DEBUG)
+void mbedtls_memory_buffer_alloc_status( void )
+{
+    mbedtls_fprintf( stderr,
+                      "Current use: %zu blocks / %zu bytes, max: %zu blocks / "
+                      "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n",
+                      heap.header_count, heap.total_used,
+                      heap.maximum_header_count, heap.maximum_used,
+                      heap.maximum_header_count * sizeof( memory_header )
+                      + heap.maximum_used,
+                      heap.alloc_count, heap.free_count );
+
+    if( heap.first->next == NULL )
+    {
+        mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" );
+    }
+    else
+    {
+        mbedtls_fprintf( stderr, "Memory currently allocated:\n" );
+        debug_chain();
+    }
+}
+
+void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks )
+{
+    *max_used   = heap.maximum_used;
+    *max_blocks = heap.maximum_header_count;
+}
+
+void mbedtls_memory_buffer_alloc_max_reset( void )
+{
+    heap.maximum_used = 0;
+    heap.maximum_header_count = 0;
+}
+
+void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks )
+{
+    *cur_used   = heap.total_used;
+    *cur_blocks = heap.header_count;
+}
+#endif /* MBEDTLS_MEMORY_DEBUG */
+
+#if defined(MBEDTLS_THREADING_C)
+static void *buffer_alloc_calloc_mutexed( size_t n, size_t size )
+{
+    void *buf;
+    if( mbedtls_mutex_lock( &heap.mutex ) != 0 )
+        return( NULL );
+    buf = buffer_alloc_calloc( n, size );
+    if( mbedtls_mutex_unlock( &heap.mutex ) )
+        return( NULL );
+    return( buf );
+}
+
+static void buffer_alloc_free_mutexed( void *ptr )
+{
+    /* We have to good option here, but corrupting the heap seems
+     * worse than loosing memory. */
+    if( mbedtls_mutex_lock( &heap.mutex ) )
+        return;
+    buffer_alloc_free( ptr );
+    (void) mbedtls_mutex_unlock( &heap.mutex );
+}
+#endif /* MBEDTLS_THREADING_C */
+
+void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
+{
+    memset( &heap, 0, sizeof( buffer_alloc_ctx ) );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &heap.mutex );
+    mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed,
+                              buffer_alloc_free_mutexed );
+#else
+    mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
+#endif
+
+    if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE )
+        return;
+    else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
+    {
+        /* Adjust len first since buf is used in the computation */
+        len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE
+             - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
+        buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE
+             - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
+    }
+
+    memset( buf, 0, len );
+
+    heap.buf = buf;
+    heap.len = len;
+
+    heap.first = (memory_header *)buf;
+    heap.first->size = len - sizeof( memory_header );
+    heap.first->magic1 = MAGIC1;
+    heap.first->magic2 = MAGIC2;
+    heap.first_free = heap.first;
+}
+
+void mbedtls_memory_buffer_alloc_free( void )
+{
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_free( &heap.mutex );
+#endif
+    mbedtls_platform_zeroize( &heap, sizeof(buffer_alloc_ctx) );
+}
+
+#if defined(MBEDTLS_SELF_TEST)
+static int check_pointer( void *p )
+{
+    if( p == NULL )
+        return( -1 );
+
+    if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 )
+        return( -1 );
+
+    return( 0 );
+}
+
+static int check_all_free( void )
+{
+    if(
+#if defined(MBEDTLS_MEMORY_DEBUG)
+        heap.total_used != 0 ||
+#endif
+        heap.first != heap.first_free ||
+        (void *) heap.first != (void *) heap.buf )
+    {
+        return( -1 );
+    }
+
+    return( 0 );
+}
+
+#define TEST_ASSERT( condition )            \
+    if( ! (condition) )                     \
+    {                                       \
+        if( verbose != 0 )                  \
+            mbedtls_printf( "failed\n" );  \
+                                            \
+        ret = 1;                            \
+        goto cleanup;                       \
+    }
+
+int mbedtls_memory_buffer_alloc_self_test( int verbose )
+{
+    unsigned char buf[1024];
+    unsigned char *p, *q, *r, *end;
+    int ret = 0;
+
+    if( verbose != 0 )
+        mbedtls_printf( "  MBA test #1 (basic alloc-free cycle): " );
+
+    mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
+
+    p = mbedtls_calloc( 1, 1 );
+    q = mbedtls_calloc( 1, 128 );
+    r = mbedtls_calloc( 1, 16 );
+
+    TEST_ASSERT( check_pointer( p ) == 0 &&
+                 check_pointer( q ) == 0 &&
+                 check_pointer( r ) == 0 );
+
+    mbedtls_free( r );
+    mbedtls_free( q );
+    mbedtls_free( p );
+
+    TEST_ASSERT( check_all_free( ) == 0 );
+
+    /* Memorize end to compare with the next test */
+    end = heap.buf + heap.len;
+
+    mbedtls_memory_buffer_alloc_free( );
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  MBA test #2 (buf not aligned): " );
+
+    mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 );
+
+    TEST_ASSERT( heap.buf + heap.len == end );
+
+    p = mbedtls_calloc( 1, 1 );
+    q = mbedtls_calloc( 1, 128 );
+    r = mbedtls_calloc( 1, 16 );
+
+    TEST_ASSERT( check_pointer( p ) == 0 &&
+                 check_pointer( q ) == 0 &&
+                 check_pointer( r ) == 0 );
+
+    mbedtls_free( r );
+    mbedtls_free( q );
+    mbedtls_free( p );
+
+    TEST_ASSERT( check_all_free( ) == 0 );
+
+    mbedtls_memory_buffer_alloc_free( );
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  MBA test #3 (full): " );
+
+    mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
+
+    p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) );
+
+    TEST_ASSERT( check_pointer( p ) == 0 );
+    TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
+
+    mbedtls_free( p );
+
+    p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 );
+    q = mbedtls_calloc( 1, 16 );
+
+    TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 );
+    TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
+
+    mbedtls_free( q );
+
+    TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL );
+
+    mbedtls_free( p );
+
+    TEST_ASSERT( check_all_free( ) == 0 );
+
+    mbedtls_memory_buffer_alloc_free( );
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+cleanup:
+    mbedtls_memory_buffer_alloc_free( );
+
+    return( ret );
+}
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/net_sockets.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/net_sockets.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/net_sockets.c	(revision 398)
@@ -0,0 +1,668 @@
+/*
+ *  TCP/IP or UDP/IP networking functions
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must
+ * be set before config.h, which pulls in glibc's features.h indirectly.
+ * Harmless on other platforms. */
+#define _POSIX_C_SOURCE 200112L
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_NET_C)
+
+#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
+    !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
+    !defined(__HAIKU__)
+#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#endif
+
+#include "mbedtls/net_sockets.h"
+
+#include <string.h>
+
+#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
+    !defined(EFI32)
+
+#define IS_EINTR( ret ) ( ( ret ) == WSAEINTR )
+
+#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
+#undef _WIN32_WINNT
+/* Enables getaddrinfo() & Co */
+#define _WIN32_WINNT 0x0501
+#endif
+
+#include <ws2tcpip.h>
+
+#include <winsock2.h>
+#include <windows.h>
+
+#if defined(_MSC_VER)
+#if defined(_WIN32_WCE)
+#pragma comment( lib, "ws2.lib" )
+#else
+#pragma comment( lib, "ws2_32.lib" )
+#endif
+#endif /* _MSC_VER */
+
+#define read(fd,buf,len)        recv( fd, (char*)( buf ), (int)( len ), 0 )
+#define write(fd,buf,len)       send( fd, (char*)( buf ), (int)( len ), 0 )
+#define close(fd)               closesocket(fd)
+
+static int wsa_init_done = 0;
+
+#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <errno.h>
+
+#define IS_EINTR( ret ) ( ( ret ) == EINTR )
+
+#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
+
+/* Some MS functions want int and MSVC warns if we pass size_t,
+ * but the standard functions use socklen_t, so cast only for MSVC */
+#if defined(_MSC_VER)
+#define MSVC_INT_CAST   (int)
+#else
+#define MSVC_INT_CAST
+#endif
+
+#include <stdio.h>
+
+#include <time.h>
+
+#include <stdint.h>
+
+/*
+ * Prepare for using the sockets interface
+ */
+static int net_prepare( void )
+{
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+    WSADATA wsaData;
+
+    if( wsa_init_done == 0 )
+    {
+        if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
+            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
+
+        wsa_init_done = 1;
+    }
+#else
+#if !defined(EFIX64) && !defined(EFI32)
+    signal( SIGPIPE, SIG_IGN );
+#endif
+#endif
+    return( 0 );
+}
+
+/*
+ * Initialize a context
+ */
+void mbedtls_net_init( mbedtls_net_context *ctx )
+{
+    ctx->fd = -1;
+}
+
+/*
+ * Initiate a TCP connection with host:port and the given protocol
+ */
+int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host,
+                         const char *port, int proto )
+{
+    int ret;
+    struct addrinfo hints, *addr_list, *cur;
+
+    if( ( ret = net_prepare() ) != 0 )
+        return( ret );
+
+    /* Do name resolution with both IPv6 and IPv4 */
+    memset( &hints, 0, sizeof( hints ) );
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
+    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
+
+    if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
+        return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
+
+    /* Try the sockaddrs until a connection succeeds */
+    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
+    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
+    {
+        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
+                            cur->ai_protocol );
+        if( ctx->fd < 0 )
+        {
+            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
+            continue;
+        }
+
+        if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 )
+        {
+            ret = 0;
+            break;
+        }
+
+        close( ctx->fd );
+        ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
+    }
+
+    freeaddrinfo( addr_list );
+
+    return( ret );
+}
+
+/*
+ * Create a listening socket on bind_ip:port
+ */
+int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
+{
+    int n, ret;
+    struct addrinfo hints, *addr_list, *cur;
+
+    if( ( ret = net_prepare() ) != 0 )
+        return( ret );
+
+    /* Bind to IPv6 and/or IPv4, but only in the desired protocol */
+    memset( &hints, 0, sizeof( hints ) );
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
+    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
+    if( bind_ip == NULL )
+        hints.ai_flags = AI_PASSIVE;
+
+    if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
+        return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
+
+    /* Try the sockaddrs until a binding succeeds */
+    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
+    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
+    {
+        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
+                            cur->ai_protocol );
+        if( ctx->fd < 0 )
+        {
+            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
+            continue;
+        }
+
+        n = 1;
+        if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
+                        (const char *) &n, sizeof( n ) ) != 0 )
+        {
+            close( ctx->fd );
+            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
+            continue;
+        }
+
+        if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 )
+        {
+            close( ctx->fd );
+            ret = MBEDTLS_ERR_NET_BIND_FAILED;
+            continue;
+        }
+
+        /* Listen only makes sense for TCP */
+        if( proto == MBEDTLS_NET_PROTO_TCP )
+        {
+            if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 )
+            {
+                close( ctx->fd );
+                ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
+                continue;
+            }
+        }
+
+        /* Bind was successful */
+        ret = 0;
+        break;
+    }
+
+    freeaddrinfo( addr_list );
+
+    return( ret );
+
+}
+
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+/*
+ * Check if the requested operation would be blocking on a non-blocking socket
+ * and thus 'failed' with a negative return value.
+ */
+static int net_would_block( const mbedtls_net_context *ctx )
+{
+    ((void) ctx);
+    return( WSAGetLastError() == WSAEWOULDBLOCK );
+}
+#else
+/*
+ * Check if the requested operation would be blocking on a non-blocking socket
+ * and thus 'failed' with a negative return value.
+ *
+ * Note: on a blocking socket this function always returns 0!
+ */
+static int net_would_block( const mbedtls_net_context *ctx )
+{
+    int err = errno;
+
+    /*
+     * Never return 'WOULD BLOCK' on a non-blocking socket
+     */
+    if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK )
+    {
+        errno = err;
+        return( 0 );
+    }
+
+    switch( errno = err )
+    {
+#if defined EAGAIN
+        case EAGAIN:
+#endif
+#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
+        case EWOULDBLOCK:
+#endif
+            return( 1 );
+    }
+    return( 0 );
+}
+#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
+
+/*
+ * Accept a connection from a remote client
+ */
+int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
+                        mbedtls_net_context *client_ctx,
+                        void *client_ip, size_t buf_size, size_t *ip_len )
+{
+    int ret;
+    int type;
+
+    struct sockaddr_storage client_addr;
+
+#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) ||  \
+    defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
+    socklen_t n = (socklen_t) sizeof( client_addr );
+    socklen_t type_len = (socklen_t) sizeof( type );
+#else
+    int n = (int) sizeof( client_addr );
+    int type_len = (int) sizeof( type );
+#endif
+
+    /* Is this a TCP or UDP socket? */
+    if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
+                    (void *) &type, &type_len ) != 0 ||
+        ( type != SOCK_STREAM && type != SOCK_DGRAM ) )
+    {
+        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
+    }
+
+    if( type == SOCK_STREAM )
+    {
+        /* TCP: actual accept() */
+        ret = client_ctx->fd = (int) accept( bind_ctx->fd,
+                                             (struct sockaddr *) &client_addr, &n );
+    }
+    else
+    {
+        /* UDP: wait for a message, but keep it in the queue */
+        char buf[1] = { 0 };
+
+        ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
+                        (struct sockaddr *) &client_addr, &n );
+
+#if defined(_WIN32)
+        if( ret == SOCKET_ERROR &&
+            WSAGetLastError() == WSAEMSGSIZE )
+        {
+            /* We know buf is too small, thanks, just peeking here */
+            ret = 0;
+        }
+#endif
+    }
+
+    if( ret < 0 )
+    {
+        if( net_would_block( bind_ctx ) != 0 )
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+
+        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
+    }
+
+    /* UDP: hijack the listening socket to communicate with the client,
+     * then bind a new socket to accept new connections */
+    if( type != SOCK_STREAM )
+    {
+        struct sockaddr_storage local_addr;
+        int one = 1;
+
+        if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
+            return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
+
+        client_ctx->fd = bind_ctx->fd;
+        bind_ctx->fd   = -1; /* In case we exit early */
+
+        n = sizeof( struct sockaddr_storage );
+        if( getsockname( client_ctx->fd,
+                         (struct sockaddr *) &local_addr, &n ) != 0 ||
+            ( bind_ctx->fd = (int) socket( local_addr.ss_family,
+                                           SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
+            setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
+                        (const char *) &one, sizeof( one ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
+        }
+
+        if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
+        {
+            return( MBEDTLS_ERR_NET_BIND_FAILED );
+        }
+    }
+
+    if( client_ip != NULL )
+    {
+        if( client_addr.ss_family == AF_INET )
+        {
+            struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
+            *ip_len = sizeof( addr4->sin_addr.s_addr );
+
+            if( buf_size < *ip_len )
+                return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
+
+            memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
+        }
+        else
+        {
+            struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
+            *ip_len = sizeof( addr6->sin6_addr.s6_addr );
+
+            if( buf_size < *ip_len )
+                return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
+
+            memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len);
+        }
+    }
+
+    return( 0 );
+}
+
+/*
+ * Set the socket blocking or non-blocking
+ */
+int mbedtls_net_set_block( mbedtls_net_context *ctx )
+{
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+    u_long n = 0;
+    return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
+#else
+    return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) );
+#endif
+}
+
+int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
+{
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+    u_long n = 1;
+    return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
+#else
+    return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) );
+#endif
+}
+
+/*
+ * Check if data is available on the socket
+ */
+
+int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout )
+{
+    int ret;
+    struct timeval tv;
+
+    fd_set read_fds;
+    fd_set write_fds;
+
+    int fd = ctx->fd;
+
+    if( fd < 0 )
+        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+    /* Ensure that memory sanitizers consider read_fds and write_fds as
+     * initialized even on platforms such as Glibc/x86_64 where FD_ZERO
+     * is implemented in assembly. */
+    memset( &read_fds, 0, sizeof( read_fds ) );
+    memset( &write_fds, 0, sizeof( write_fds ) );
+#endif
+#endif
+
+    FD_ZERO( &read_fds );
+    if( rw & MBEDTLS_NET_POLL_READ )
+    {
+        rw &= ~MBEDTLS_NET_POLL_READ;
+        FD_SET( fd, &read_fds );
+    }
+
+    FD_ZERO( &write_fds );
+    if( rw & MBEDTLS_NET_POLL_WRITE )
+    {
+        rw &= ~MBEDTLS_NET_POLL_WRITE;
+        FD_SET( fd, &write_fds );
+    }
+
+    if( rw != 0 )
+        return( MBEDTLS_ERR_NET_BAD_INPUT_DATA );
+
+    tv.tv_sec  = timeout / 1000;
+    tv.tv_usec = ( timeout % 1000 ) * 1000;
+
+    do
+    {
+        ret = select( fd + 1, &read_fds, &write_fds, NULL,
+                      timeout == (uint32_t) -1 ? NULL : &tv );
+    }
+    while( IS_EINTR( ret ) );
+
+    if( ret < 0 )
+        return( MBEDTLS_ERR_NET_POLL_FAILED );
+
+    ret = 0;
+    if( FD_ISSET( fd, &read_fds ) )
+        ret |= MBEDTLS_NET_POLL_READ;
+    if( FD_ISSET( fd, &write_fds ) )
+        ret |= MBEDTLS_NET_POLL_WRITE;
+
+    return( ret );
+}
+
+/*
+ * Portable usleep helper
+ */
+void mbedtls_net_usleep( unsigned long usec )
+{
+#if defined(_WIN32)
+    Sleep( ( usec + 999 ) / 1000 );
+#else
+    struct timeval tv;
+    tv.tv_sec  = usec / 1000000;
+#if defined(__unix__) || defined(__unix) || \
+    ( defined(__APPLE__) && defined(__MACH__) )
+    tv.tv_usec = (suseconds_t) usec % 1000000;
+#else
+    tv.tv_usec = usec % 1000000;
+#endif
+    select( 0, NULL, NULL, NULL, &tv );
+#endif
+}
+
+/*
+ * Read at most 'len' characters
+ */
+int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
+{
+    int ret;
+    int fd = ((mbedtls_net_context *) ctx)->fd;
+
+    if( fd < 0 )
+        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+    ret = (int) read( fd, buf, len );
+
+    if( ret < 0 )
+    {
+        if( net_would_block( ctx ) != 0 )
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+        if( WSAGetLastError() == WSAECONNRESET )
+            return( MBEDTLS_ERR_NET_CONN_RESET );
+#else
+        if( errno == EPIPE || errno == ECONNRESET )
+            return( MBEDTLS_ERR_NET_CONN_RESET );
+
+        if( errno == EINTR )
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+#endif
+
+        return( MBEDTLS_ERR_NET_RECV_FAILED );
+    }
+
+    return( ret );
+}
+
+/*
+ * Read at most 'len' characters, blocking for at most 'timeout' ms
+ */
+int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
+                              size_t len, uint32_t timeout )
+{
+    int ret;
+    struct timeval tv;
+    fd_set read_fds;
+    int fd = ((mbedtls_net_context *) ctx)->fd;
+
+    if( fd < 0 )
+        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+    FD_ZERO( &read_fds );
+    FD_SET( fd, &read_fds );
+
+    tv.tv_sec  = timeout / 1000;
+    tv.tv_usec = ( timeout % 1000 ) * 1000;
+
+    ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
+
+    /* Zero fds ready means we timed out */
+    if( ret == 0 )
+        return( MBEDTLS_ERR_SSL_TIMEOUT );
+
+    if( ret < 0 )
+    {
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+        if( WSAGetLastError() == WSAEINTR )
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+#else
+        if( errno == EINTR )
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+#endif
+
+        return( MBEDTLS_ERR_NET_RECV_FAILED );
+    }
+
+    /* This call will not block */
+    return( mbedtls_net_recv( ctx, buf, len ) );
+}
+
+/*
+ * Write at most 'len' characters
+ */
+int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
+{
+    int ret;
+    int fd = ((mbedtls_net_context *) ctx)->fd;
+
+    if( fd < 0 )
+        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+    ret = (int) write( fd, buf, len );
+
+    if( ret < 0 )
+    {
+        if( net_would_block( ctx ) != 0 )
+            return( MBEDTLS_ERR_SSL_WANT_WRITE );
+
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+        if( WSAGetLastError() == WSAECONNRESET )
+            return( MBEDTLS_ERR_NET_CONN_RESET );
+#else
+        if( errno == EPIPE || errno == ECONNRESET )
+            return( MBEDTLS_ERR_NET_CONN_RESET );
+
+        if( errno == EINTR )
+            return( MBEDTLS_ERR_SSL_WANT_WRITE );
+#endif
+
+        return( MBEDTLS_ERR_NET_SEND_FAILED );
+    }
+
+    return( ret );
+}
+
+/*
+ * Gracefully close the connection
+ */
+void mbedtls_net_free( mbedtls_net_context *ctx )
+{
+    if( ctx->fd == -1 )
+        return;
+
+    shutdown( ctx->fd, 2 );
+    close( ctx->fd );
+
+    ctx->fd = -1;
+}
+
+#endif /* MBEDTLS_NET_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/nist_kw.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/nist_kw.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/nist_kw.c	(revision 398)
@@ -0,0 +1,755 @@
+/*
+ *  Implementation of NIST SP 800-38F key wrapping, supporting KW and KWP modes
+ *  only
+ *
+ *  Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * Definition of Key Wrapping:
+ * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf
+ * RFC 3394 "Advanced Encryption Standard (AES) Key Wrap Algorithm"
+ * RFC 5649 "Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm"
+ *
+ * Note: RFC 3394 defines different methodology for intermediate operations for
+ * the wrapping and unwrapping operation than the definition in NIST SP 800-38F.
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_NIST_KW_C)
+
+#include "mbedtls/nist_kw.h"
+#include "mbedtls/platform_util.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#if !defined(MBEDTLS_NIST_KW_ALT)
+
+#define KW_SEMIBLOCK_LENGTH    8
+#define MIN_SEMIBLOCKS_COUNT   3
+
+/* constant-time buffer comparison */
+static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n )
+{
+    size_t i;
+    volatile const unsigned char *A = (volatile const unsigned char *) a;
+    volatile const unsigned char *B = (volatile const unsigned char *) b;
+    volatile unsigned char diff = 0;
+
+    for( i = 0; i < n; i++ )
+    {
+        /* Read volatile data in order before computing diff.
+         * This avoids IAR compiler warning:
+         * 'the order of volatile accesses is undefined ..' */
+        unsigned char x = A[i], y = B[i];
+        diff |= x ^ y;
+    }
+
+    return( diff );
+}
+
+/*! The 64-bit default integrity check value (ICV) for KW mode. */
+static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6};
+/*! The 32-bit default integrity check value (ICV) for KWP mode. */
+static const  unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6};
+
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+do {                                                    \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+} while( 0 )
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i)                            \
+do {                                                    \
+    (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)       );       \
+} while( 0 )
+#endif
+
+/*
+ * Initialize context
+ */
+void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_nist_kw_context ) );
+}
+
+int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx,
+                            mbedtls_cipher_id_t cipher,
+                            const unsigned char *key,
+                            unsigned int keybits,
+                            const int is_wrap )
+{
+    int ret;
+    const mbedtls_cipher_info_t *cipher_info;
+
+    cipher_info = mbedtls_cipher_info_from_values( cipher,
+                                                   keybits,
+                                                   MBEDTLS_MODE_ECB );
+    if( cipher_info == NULL )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    if( cipher_info->block_size != 16 )
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+    /*
+     * SP 800-38F currently defines AES cipher as the only block cipher allowed:
+     * "For KW and KWP, the underlying block cipher shall be approved, and the
+     *  block size shall be 128 bits. Currently, the AES block cipher, with key
+     *  lengths of 128, 192, or 256 bits, is the only block cipher that fits
+     *  this profile."
+     *  Currently we don't support other 128 bit block ciphers for key wrapping,
+     *  such as Camellia and Aria.
+     */
+    if( cipher != MBEDTLS_CIPHER_ID_AES )
+        return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+    mbedtls_cipher_free( &ctx->cipher_ctx );
+
+    if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
+                                       is_wrap ? MBEDTLS_ENCRYPT :
+                                                 MBEDTLS_DECRYPT )
+                                                                   ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Free context
+ */
+void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx )
+{
+    mbedtls_cipher_free( &ctx->cipher_ctx );
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_nist_kw_context ) );
+}
+
+/*
+ * Helper function for Xoring the uint64_t "t" with the encrypted A.
+ * Defined in NIST SP 800-38F section 6.1
+ */
+static void calc_a_xor_t( unsigned char A[KW_SEMIBLOCK_LENGTH], uint64_t t )
+{
+    size_t i = 0;
+    for( i = 0; i < sizeof( t ); i++ )
+    {
+        A[i] ^= ( t >> ( ( sizeof( t ) - 1 - i ) * 8 ) ) & 0xff;
+    }
+}
+
+/*
+ * KW-AE as defined in SP 800-38F section 6.2
+ * KWP-AE as defined in SP 800-38F section 6.3
+ */
+int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx,
+                          mbedtls_nist_kw_mode_t mode,
+                          const unsigned char *input, size_t in_len,
+                          unsigned char *output, size_t *out_len, size_t out_size )
+{
+    int ret = 0;
+    size_t semiblocks = 0;
+    size_t s;
+    size_t olen, padlen = 0;
+    uint64_t t = 0;
+    unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
+    unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
+    unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH;
+    unsigned char *A = output;
+
+    *out_len = 0;
+    /*
+     * Generate the String to work on
+     */
+    if( mode == MBEDTLS_KW_MODE_KW )
+    {
+        if( out_size < in_len + KW_SEMIBLOCK_LENGTH )
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+
+        /*
+         * According to SP 800-38F Table 1, the plaintext length for KW
+         * must be between 2 to 2^54-1 semiblocks inclusive.
+         */
+        if( in_len < 16 ||
+#if SIZE_MAX > 0x1FFFFFFFFFFFFF8
+            in_len > 0x1FFFFFFFFFFFFF8 ||
+#endif
+            in_len % KW_SEMIBLOCK_LENGTH != 0 )
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+
+        memcpy( output, NIST_KW_ICV1, KW_SEMIBLOCK_LENGTH );
+        memmove( output + KW_SEMIBLOCK_LENGTH, input, in_len );
+    }
+    else
+    {
+        if( in_len % 8 != 0 )
+        {
+            padlen = ( 8 - ( in_len % 8 ) );
+        }
+
+        if( out_size < in_len + KW_SEMIBLOCK_LENGTH + padlen )
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+
+        /*
+         * According to SP 800-38F Table 1, the plaintext length for KWP
+         * must be between 1 and 2^32-1 octets inclusive.
+         */
+        if( in_len < 1
+#if SIZE_MAX > 0xFFFFFFFF
+            || in_len > 0xFFFFFFFF
+#endif
+          )
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+
+        memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 );
+        PUT_UINT32_BE( ( in_len & 0xffffffff ), output,
+                       KW_SEMIBLOCK_LENGTH / 2 );
+
+        memcpy( output + KW_SEMIBLOCK_LENGTH, input, in_len );
+        memset( output + KW_SEMIBLOCK_LENGTH + in_len, 0, padlen );
+    }
+    semiblocks = ( ( in_len + padlen ) / KW_SEMIBLOCK_LENGTH ) + 1;
+
+    s = 6 * ( semiblocks - 1 );
+
+    if( mode == MBEDTLS_KW_MODE_KWP
+        && in_len <= KW_SEMIBLOCK_LENGTH )
+    {
+        memcpy( inbuff, output, 16 );
+        ret = mbedtls_cipher_update( &ctx->cipher_ctx,
+                                     inbuff, 16, output, &olen );
+        if( ret != 0 )
+            goto cleanup;
+    }
+    else
+    {
+        /*
+         * Do the wrapping function W, as defined in RFC 3394 section 2.2.1
+         */
+        if( semiblocks < MIN_SEMIBLOCKS_COUNT )
+        {
+            ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+            goto cleanup;
+        }
+
+        /* Calculate intermediate values */
+        for( t = 1; t <= s; t++ )
+        {
+            memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH );
+            memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R2, KW_SEMIBLOCK_LENGTH );
+
+            ret = mbedtls_cipher_update( &ctx->cipher_ctx,
+                                         inbuff, 16, outbuff, &olen );
+            if( ret != 0 )
+                goto cleanup;
+
+            memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH );
+            calc_a_xor_t( A, t );
+
+            memcpy( R2, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
+            R2 += KW_SEMIBLOCK_LENGTH;
+            if( R2 >= output + ( semiblocks * KW_SEMIBLOCK_LENGTH ) )
+                R2 = output + KW_SEMIBLOCK_LENGTH;
+        }
+    }
+
+    *out_len = semiblocks * KW_SEMIBLOCK_LENGTH;
+
+cleanup:
+
+    if( ret != 0)
+    {
+        memset( output, 0, semiblocks * KW_SEMIBLOCK_LENGTH );
+    }
+    mbedtls_platform_zeroize( inbuff, KW_SEMIBLOCK_LENGTH * 2 );
+    mbedtls_platform_zeroize( outbuff, KW_SEMIBLOCK_LENGTH * 2 );
+
+    return( ret );
+}
+
+/*
+ * W-1 function as defined in RFC 3394 section 2.2.2
+ * This function assumes the following:
+ * 1. Output buffer is at least of size ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH.
+ * 2. The input buffer is of size semiblocks * KW_SEMIBLOCK_LENGTH.
+ * 3. Minimal number of semiblocks is 3.
+ * 4. A is a buffer to hold the first semiblock of the input buffer.
+ */
+static int unwrap( mbedtls_nist_kw_context *ctx,
+                   const unsigned char *input, size_t semiblocks,
+                   unsigned char A[KW_SEMIBLOCK_LENGTH],
+                   unsigned char *output, size_t* out_len )
+{
+    int ret = 0;
+    const size_t s = 6 * ( semiblocks - 1 );
+    size_t olen;
+    uint64_t t = 0;
+    unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
+    unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
+    unsigned char *R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
+    *out_len = 0;
+
+    if( semiblocks < MIN_SEMIBLOCKS_COUNT )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    memcpy( A, input, KW_SEMIBLOCK_LENGTH );
+    memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
+
+    /* Calculate intermediate values */
+    for( t = s; t >= 1; t-- )
+    {
+        calc_a_xor_t( A, t );
+
+        memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH );
+        memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R, KW_SEMIBLOCK_LENGTH );
+
+        ret = mbedtls_cipher_update( &ctx->cipher_ctx,
+                                     inbuff, 16, outbuff, &olen );
+        if( ret != 0 )
+            goto cleanup;
+
+        memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH );
+
+        /* Set R as LSB64 of outbuff */
+        memcpy( R, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
+
+        if( R == output )
+            R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
+        else
+            R -= KW_SEMIBLOCK_LENGTH;
+    }
+
+    *out_len = ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH;
+
+cleanup:
+    if( ret != 0)
+        memset( output, 0, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
+    mbedtls_platform_zeroize( inbuff, sizeof( inbuff )  );
+    mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) );
+
+    return( ret );
+}
+
+/*
+ * KW-AD as defined in SP 800-38F section 6.2
+ * KWP-AD as defined in SP 800-38F section 6.3
+ */
+int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx,
+                            mbedtls_nist_kw_mode_t mode,
+                            const unsigned char *input, size_t in_len,
+                            unsigned char *output, size_t *out_len, size_t out_size )
+{
+    int ret = 0;
+    size_t i, olen;
+    unsigned char A[KW_SEMIBLOCK_LENGTH];
+    unsigned char diff, bad_padding = 0;
+
+    *out_len = 0;
+    if( out_size < in_len - KW_SEMIBLOCK_LENGTH )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    if( mode == MBEDTLS_KW_MODE_KW )
+    {
+        /*
+         * According to SP 800-38F Table 1, the ciphertext length for KW
+         * must be between 3 to 2^54 semiblocks inclusive.
+         */
+        if( in_len < 24 ||
+#if SIZE_MAX > 0x200000000000000
+            in_len > 0x200000000000000 ||
+#endif
+            in_len % KW_SEMIBLOCK_LENGTH != 0 )
+        {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+
+        ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH,
+                      A, output, out_len );
+        if( ret != 0 )
+            goto cleanup;
+
+        /* Check ICV in "constant-time" */
+        diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
+
+        if( diff != 0 )
+        {
+            ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+            goto cleanup;
+        }
+
+    }
+    else if( mode == MBEDTLS_KW_MODE_KWP )
+    {
+        size_t padlen = 0;
+        uint32_t Plen;
+        /*
+         * According to SP 800-38F Table 1, the ciphertext length for KWP
+         * must be between 2 to 2^29 semiblocks inclusive.
+         */
+        if( in_len < KW_SEMIBLOCK_LENGTH * 2 ||
+#if SIZE_MAX > 0x100000000
+            in_len > 0x100000000 ||
+#endif
+            in_len % KW_SEMIBLOCK_LENGTH != 0 )
+        {
+            return(  MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+        }
+
+        if( in_len == KW_SEMIBLOCK_LENGTH * 2 )
+        {
+            unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
+            ret = mbedtls_cipher_update( &ctx->cipher_ctx,
+                                         input, 16, outbuff, &olen );
+            if( ret != 0 )
+                goto cleanup;
+
+            memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH );
+            memcpy( output, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
+            mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) );
+            *out_len = KW_SEMIBLOCK_LENGTH;
+        }
+        else
+        {
+            /* in_len >=  KW_SEMIBLOCK_LENGTH * 3 */
+            ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH,
+                          A, output, out_len );
+            if( ret != 0 )
+                goto cleanup;
+        }
+
+        /* Check ICV in "constant-time" */
+        diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
+
+        if( diff != 0 )
+        {
+            ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+        }
+
+        GET_UINT32_BE( Plen, A, KW_SEMIBLOCK_LENGTH / 2 );
+
+        /*
+         * Plen is the length of the plaintext, when the input is valid.
+         * If Plen is larger than the plaintext and padding, padlen will be
+         * larger than 8, because of the type wrap around.
+         */
+        padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen;
+        if ( padlen > 7 )
+        {
+            padlen &= 7;
+            ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+        }
+
+        /* Check padding in "constant-time" */
+        for( diff = 0, i = 0; i < KW_SEMIBLOCK_LENGTH; i++ )
+        {
+             if( i >= KW_SEMIBLOCK_LENGTH - padlen )
+                 diff |= output[*out_len - KW_SEMIBLOCK_LENGTH + i];
+             else
+                 bad_padding |= output[*out_len - KW_SEMIBLOCK_LENGTH + i];
+        }
+
+        if( diff != 0 )
+        {
+            ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+        }
+
+        if( ret != 0 )
+        {
+            goto cleanup;
+        }
+        memset( output + Plen, 0, padlen );
+        *out_len = Plen;
+    }
+    else
+    {
+        ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+        goto cleanup;
+    }
+
+cleanup:
+    if( ret != 0 )
+    {
+        memset( output, 0, *out_len );
+        *out_len = 0;
+    }
+
+    mbedtls_platform_zeroize( &bad_padding, sizeof( bad_padding) );
+    mbedtls_platform_zeroize( &diff, sizeof( diff ) );
+    mbedtls_platform_zeroize( A, sizeof( A ) );
+
+    return( ret );
+}
+
+#endif /* !MBEDTLS_NIST_KW_ALT */
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
+
+#define KW_TESTS 3
+
+/*
+ * Test vectors taken from NIST
+ * https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#KW
+ */
+static const unsigned int key_len[KW_TESTS] = { 16, 24, 32 };
+
+static const unsigned char kw_key[KW_TESTS][32] = {
+    { 0x75, 0x75, 0xda, 0x3a, 0x93, 0x60, 0x7c, 0xc2,
+      0xbf, 0xd8, 0xce, 0xc7, 0xaa, 0xdf, 0xd9, 0xa6 },
+    { 0x2d, 0x85, 0x26, 0x08, 0x1d, 0x02, 0xfb, 0x5b,
+      0x85, 0xf6, 0x9a, 0xc2, 0x86, 0xec, 0xd5, 0x7d,
+      0x40, 0xdf, 0x5d, 0xf3, 0x49, 0x47, 0x44, 0xd3 },
+    { 0x11, 0x2a, 0xd4, 0x1b, 0x48, 0x56, 0xc7, 0x25,
+      0x4a, 0x98, 0x48, 0xd3, 0x0f, 0xdd, 0x78, 0x33,
+      0x5b, 0x03, 0x9a, 0x48, 0xa8, 0x96, 0x2c, 0x4d,
+      0x1c, 0xb7, 0x8e, 0xab, 0xd5, 0xda, 0xd7, 0x88 }
+};
+
+static const unsigned char kw_msg[KW_TESTS][40] = {
+    { 0x42, 0x13, 0x6d, 0x3c, 0x38, 0x4a, 0x3e, 0xea,
+      0xc9, 0x5a, 0x06, 0x6f, 0xd2, 0x8f, 0xed, 0x3f },
+    { 0x95, 0xc1, 0x1b, 0xf5, 0x35, 0x3a, 0xfe, 0xdb,
+      0x98, 0xfd, 0xd6, 0xc8, 0xca, 0x6f, 0xdb, 0x6d,
+      0xa5, 0x4b, 0x74, 0xb4, 0x99, 0x0f, 0xdc, 0x45,
+      0xc0, 0x9d, 0x15, 0x8f, 0x51, 0xce, 0x62, 0x9d,
+      0xe2, 0xaf, 0x26, 0xe3, 0x25, 0x0e, 0x6b, 0x4c },
+    { 0x1b, 0x20, 0xbf, 0x19, 0x90, 0xb0, 0x65, 0xd7,
+      0x98, 0xe1, 0xb3, 0x22, 0x64, 0xad, 0x50, 0xa8,
+      0x74, 0x74, 0x92, 0xba, 0x09, 0xa0, 0x4d, 0xd1 }
+};
+
+static const size_t kw_msg_len[KW_TESTS] = { 16, 40, 24 };
+static const size_t kw_out_len[KW_TESTS] = { 24, 48, 32 };
+static const unsigned char kw_res[KW_TESTS][48] = {
+    { 0x03, 0x1f, 0x6b, 0xd7, 0xe6, 0x1e, 0x64, 0x3d,
+      0xf6, 0x85, 0x94, 0x81, 0x6f, 0x64, 0xca, 0xa3,
+      0xf5, 0x6f, 0xab, 0xea, 0x25, 0x48, 0xf5, 0xfb },
+    { 0x44, 0x3c, 0x6f, 0x15, 0x09, 0x83, 0x71, 0x91,
+      0x3e, 0x5c, 0x81, 0x4c, 0xa1, 0xa0, 0x42, 0xec,
+      0x68, 0x2f, 0x7b, 0x13, 0x6d, 0x24, 0x3a, 0x4d,
+      0x6c, 0x42, 0x6f, 0xc6, 0x97, 0x15, 0x63, 0xe8,
+      0xa1, 0x4a, 0x55, 0x8e, 0x09, 0x64, 0x16, 0x19,
+      0xbf, 0x03, 0xfc, 0xaf, 0x90, 0xb1, 0xfc, 0x2d },
+    { 0xba, 0x8a, 0x25, 0x9a, 0x47, 0x1b, 0x78, 0x7d,
+      0xd5, 0xd5, 0x40, 0xec, 0x25, 0xd4, 0x3d, 0x87,
+      0x20, 0x0f, 0xda, 0xdc, 0x6d, 0x1f, 0x05, 0xd9,
+      0x16, 0x58, 0x4f, 0xa9, 0xf6, 0xcb, 0xf5, 0x12 }
+};
+
+static const unsigned char kwp_key[KW_TESTS][32] = {
+    { 0x78, 0x65, 0xe2, 0x0f, 0x3c, 0x21, 0x65, 0x9a,
+      0xb4, 0x69, 0x0b, 0x62, 0x9c, 0xdf, 0x3c, 0xc4 },
+    { 0xf5, 0xf8, 0x96, 0xa3, 0xbd, 0x2f, 0x4a, 0x98,
+      0x23, 0xef, 0x16, 0x2b, 0x00, 0xb8, 0x05, 0xd7,
+      0xde, 0x1e, 0xa4, 0x66, 0x26, 0x96, 0xa2, 0x58 },
+    { 0x95, 0xda, 0x27, 0x00, 0xca, 0x6f, 0xd9, 0xa5,
+      0x25, 0x54, 0xee, 0x2a, 0x8d, 0xf1, 0x38, 0x6f,
+      0x5b, 0x94, 0xa1, 0xa6, 0x0e, 0xd8, 0xa4, 0xae,
+      0xf6, 0x0a, 0x8d, 0x61, 0xab, 0x5f, 0x22, 0x5a }
+};
+
+static const unsigned char kwp_msg[KW_TESTS][31] = {
+    { 0xbd, 0x68, 0x43, 0xd4, 0x20, 0x37, 0x8d, 0xc8,
+      0x96 },
+    { 0x6c, 0xcd, 0xd5, 0x85, 0x18, 0x40, 0x97, 0xeb,
+      0xd5, 0xc3, 0xaf, 0x3e, 0x47, 0xd0, 0x2c, 0x19,
+      0x14, 0x7b, 0x4d, 0x99, 0x5f, 0x96, 0x43, 0x66,
+      0x91, 0x56, 0x75, 0x8c, 0x13, 0x16, 0x8f },
+    { 0xd1 }
+};
+static const size_t kwp_msg_len[KW_TESTS] = { 9, 31, 1 };
+
+static const unsigned char kwp_res[KW_TESTS][48] = {
+    { 0x41, 0xec, 0xa9, 0x56, 0xd4, 0xaa, 0x04, 0x7e,
+      0xb5, 0xcf, 0x4e, 0xfe, 0x65, 0x96, 0x61, 0xe7,
+      0x4d, 0xb6, 0xf8, 0xc5, 0x64, 0xe2, 0x35, 0x00 },
+    { 0x4e, 0x9b, 0xc2, 0xbc, 0xbc, 0x6c, 0x1e, 0x13,
+      0xd3, 0x35, 0xbc, 0xc0, 0xf7, 0x73, 0x6a, 0x88,
+      0xfa, 0x87, 0x53, 0x66, 0x15, 0xbb, 0x8e, 0x63,
+      0x8b, 0xcc, 0x81, 0x66, 0x84, 0x68, 0x17, 0x90,
+      0x67, 0xcf, 0xa9, 0x8a, 0x9d, 0x0e, 0x33, 0x26 },
+    { 0x06, 0xba, 0x7a, 0xe6, 0xf3, 0x24, 0x8c, 0xfd,
+      0xcf, 0x26, 0x75, 0x07, 0xfa, 0x00, 0x1b, 0xc4  }
+};
+static const size_t kwp_out_len[KW_TESTS] = { 24, 40, 16 };
+
+int mbedtls_nist_kw_self_test( int verbose )
+{
+    mbedtls_nist_kw_context ctx;
+    unsigned char out[48];
+    size_t olen;
+    int i;
+    int ret = 0;
+    mbedtls_nist_kw_init( &ctx );
+
+    for( i = 0; i < KW_TESTS; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  KW-AES-%u ", (unsigned int) key_len[i] * 8 );
+
+        ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
+                                      kw_key[i], key_len[i] * 8, 1 );
+        if( ret != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "  KW: setup failed " );
+
+            goto end;
+        }
+
+        ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KW, kw_msg[i],
+                                    kw_msg_len[i], out, &olen, sizeof( out ) );
+        if( ret != 0 || kw_out_len[i] != olen ||
+            memcmp( out, kw_res[i], kw_out_len[i] ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed. ");
+
+            ret = 1;
+            goto end;
+        }
+
+        if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
+                                            kw_key[i], key_len[i] * 8, 0 ) )
+              != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "  KW: setup failed ");
+
+            goto end;
+        }
+
+        ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KW,
+                                      out, olen, out, &olen, sizeof( out ) );
+
+        if( ret != 0 || olen != kw_msg_len[i] ||
+            memcmp( out, kw_msg[i], kw_msg_len[i] ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            ret = 1;
+            goto end;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( " passed\n" );
+    }
+
+    for( i = 0; i < KW_TESTS; i++ )
+    {
+        olen = sizeof( out );
+        if( verbose != 0 )
+            mbedtls_printf( "  KWP-AES-%u ", (unsigned int) key_len[i] * 8 );
+
+        ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, kwp_key[i],
+                                      key_len[i] * 8, 1 );
+        if( ret  != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "  KWP: setup failed " );
+
+            goto end;
+        }
+        ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KWP, kwp_msg[i],
+                                    kwp_msg_len[i], out, &olen, sizeof( out ) );
+
+        if( ret != 0 || kwp_out_len[i] != olen ||
+            memcmp( out, kwp_res[i], kwp_out_len[i] ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed. ");
+
+            ret = 1;
+            goto end;
+        }
+
+        if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES,
+                                            kwp_key[i], key_len[i] * 8, 0 ) )
+              != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "  KWP: setup failed ");
+
+            goto end;
+        }
+
+        ret = mbedtls_nist_kw_unwrap(  &ctx, MBEDTLS_KW_MODE_KWP, out,
+                                       olen, out, &olen, sizeof( out ) );
+
+        if( ret != 0 || olen != kwp_msg_len[i] ||
+            memcmp( out, kwp_msg[i], kwp_msg_len[i] ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed. ");
+
+            ret = 1;
+            goto end;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( " passed\n" );
+    }
+end:
+    mbedtls_nist_kw_free( &ctx );
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
+
+#endif /* MBEDTLS_NIST_KW_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/oid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/oid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/oid.c	(revision 398)
@@ -0,0 +1,755 @@
+/**
+ * \file oid.c
+ *
+ * \brief Object Identifier (OID) database
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_OID_C)
+
+#include "mbedtls/oid.h"
+#include "mbedtls/rsa.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#define mbedtls_snprintf snprintf
+#endif
+
+#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
+#include "mbedtls/x509.h"
+#endif
+
+/*
+ * Macro to automatically add the size of #define'd OIDs
+ */
+#define ADD_LEN(s)      s, MBEDTLS_OID_SIZE(s)
+
+/*
+ * Macro to generate an internal function for oid_XXX_from_asn1() (used by
+ * the other functions)
+ */
+#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST )                        \
+static const TYPE_T * oid_ ## NAME ## _from_asn1( const mbedtls_asn1_buf *oid )     \
+{                                                                           \
+    const TYPE_T *p = LIST;                                                 \
+    const mbedtls_oid_descriptor_t *cur = (const mbedtls_oid_descriptor_t *) p;             \
+    if( p == NULL || oid == NULL ) return( NULL );                          \
+    while( cur->asn1 != NULL ) {                                            \
+        if( cur->asn1_len == oid->len &&                                    \
+            memcmp( cur->asn1, oid->p, oid->len ) == 0 ) {                  \
+            return( p );                                                    \
+        }                                                                   \
+        p++;                                                                \
+        cur = (const mbedtls_oid_descriptor_t *) p;                                 \
+    }                                                                       \
+    return( NULL );                                                         \
+}
+
+/*
+ * Macro to generate a function for retrieving a single attribute from the
+ * descriptor of an mbedtls_oid_descriptor_t wrapper.
+ */
+#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
+int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 )                  \
+{                                                                       \
+    const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid );        \
+    if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND );            \
+    *ATTR1 = data->descriptor.ATTR1;                                    \
+    return( 0 );                                                        \
+}
+
+/*
+ * Macro to generate a function for retrieving a single attribute from an
+ * mbedtls_oid_descriptor_t wrapper.
+ */
+#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \
+int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 )                  \
+{                                                                       \
+    const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid );        \
+    if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND );            \
+    *ATTR1 = data->ATTR1;                                               \
+    return( 0 );                                                        \
+}
+
+/*
+ * Macro to generate a function for retrieving two attributes from an
+ * mbedtls_oid_descriptor_t wrapper.
+ */
+#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1,     \
+                         ATTR2_TYPE, ATTR2)                                 \
+int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 )  \
+{                                                                           \
+    const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid );            \
+    if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND );                \
+    *ATTR1 = data->ATTR1;                                                   \
+    *ATTR2 = data->ATTR2;                                                   \
+    return( 0 );                                                            \
+}
+
+/*
+ * Macro to generate a function for retrieving the OID based on a single
+ * attribute from a mbedtls_oid_descriptor_t wrapper.
+ */
+#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1)   \
+int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen )             \
+{                                                                           \
+    const TYPE_T *cur = LIST;                                               \
+    while( cur->descriptor.asn1 != NULL ) {                                 \
+        if( cur->ATTR1 == ATTR1 ) {                                         \
+            *oid = cur->descriptor.asn1;                                    \
+            *olen = cur->descriptor.asn1_len;                               \
+            return( 0 );                                                    \
+        }                                                                   \
+        cur++;                                                              \
+    }                                                                       \
+    return( MBEDTLS_ERR_OID_NOT_FOUND );                                   \
+}
+
+/*
+ * Macro to generate a function for retrieving the OID based on two
+ * attributes from a mbedtls_oid_descriptor_t wrapper.
+ */
+#define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1,   \
+                                ATTR2_TYPE, ATTR2)                          \
+int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid ,         \
+             size_t *olen )                                                 \
+{                                                                           \
+    const TYPE_T *cur = LIST;                                               \
+    while( cur->descriptor.asn1 != NULL ) {                                 \
+        if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) {                  \
+            *oid = cur->descriptor.asn1;                                    \
+            *olen = cur->descriptor.asn1_len;                               \
+            return( 0 );                                                    \
+        }                                                                   \
+        cur++;                                                              \
+    }                                                                       \
+    return( MBEDTLS_ERR_OID_NOT_FOUND );                                   \
+}
+
+#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
+/*
+ * For X520 attribute types
+ */
+typedef struct {
+    mbedtls_oid_descriptor_t    descriptor;
+    const char          *short_name;
+} oid_x520_attr_t;
+
+static const oid_x520_attr_t oid_x520_attr_type[] =
+{
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_CN ),          "id-at-commonName",               "Common Name" },
+        "CN",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_COUNTRY ),     "id-at-countryName",              "Country" },
+        "C",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_LOCALITY ),    "id-at-locality",                 "Locality" },
+        "L",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_STATE ),       "id-at-state",                    "State" },
+        "ST",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_ORGANIZATION ),"id-at-organizationName",         "Organization" },
+        "O",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_ORG_UNIT ),    "id-at-organizationalUnitName",   "Org Unit" },
+        "OU",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS9_EMAIL ),    "emailAddress",                   "E-mail address" },
+        "emailAddress",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_SERIAL_NUMBER ),"id-at-serialNumber",            "Serial number" },
+        "serialNumber",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress",          "Postal address" },
+        "postalAddress",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_POSTAL_CODE ), "id-at-postalCode",               "Postal code" },
+        "postalCode",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_SUR_NAME ),    "id-at-surName",                  "Surname" },
+        "SN",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_GIVEN_NAME ),  "id-at-givenName",                "Given name" },
+        "GN",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_INITIALS ),    "id-at-initials",                 "Initials" },
+        "initials",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" },
+        "generationQualifier",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_TITLE ),       "id-at-title",                    "Title" },
+        "title",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_DN_QUALIFIER ),"id-at-dnQualifier",              "Distinguished Name qualifier" },
+        "dnQualifier",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_PSEUDONYM ),   "id-at-pseudonym",                "Pseudonym" },
+        "pseudonym",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_DOMAIN_COMPONENT ), "id-domainComponent",           "Domain component" },
+        "DC",
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER ), "id-at-uniqueIdentifier",    "Unique Identifier" },
+        "uniqueIdentifier",
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        NULL,
+    }
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type)
+FN_OID_GET_ATTR1(mbedtls_oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name)
+
+/*
+ * For X509 extensions
+ */
+typedef struct {
+    mbedtls_oid_descriptor_t    descriptor;
+    int                 ext_type;
+} oid_x509_ext_t;
+
+static const oid_x509_ext_t oid_x509_ext[] =
+{
+    {
+        { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ),    "id-ce-basicConstraints",   "Basic Constraints" },
+        MBEDTLS_X509_EXT_BASIC_CONSTRAINTS,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_KEY_USAGE ),            "id-ce-keyUsage",           "Key Usage" },
+        MBEDTLS_X509_EXT_KEY_USAGE,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ),   "id-ce-extKeyUsage",        "Extended Key Usage" },
+        MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ),     "id-ce-subjectAltName",     "Subject Alt Name" },
+        MBEDTLS_X509_EXT_SUBJECT_ALT_NAME,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ),         "id-netscape-certtype",     "Netscape Certificate Type" },
+        MBEDTLS_X509_EXT_NS_CERT_TYPE,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        0,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext)
+FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type)
+
+static const mbedtls_oid_descriptor_t oid_ext_key_usage[] =
+{
+    { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ),      "id-kp-serverAuth",      "TLS Web Server Authentication" },
+    { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ),      "id-kp-clientAuth",      "TLS Web Client Authentication" },
+    { ADD_LEN( MBEDTLS_OID_CODE_SIGNING ),     "id-kp-codeSigning",     "Code Signing" },
+    { ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
+    { ADD_LEN( MBEDTLS_OID_TIME_STAMPING ),    "id-kp-timeStamping",    "Time Stamping" },
+    { ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ),     "id-kp-OCSPSigning",     "OCSP Signing" },
+    { NULL, 0, NULL, NULL },
+};
+
+FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage)
+FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description)
+#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
+
+#if defined(MBEDTLS_MD_C)
+/*
+ * For SignatureAlgorithmIdentifier
+ */
+typedef struct {
+    mbedtls_oid_descriptor_t    descriptor;
+    mbedtls_md_type_t           md_alg;
+    mbedtls_pk_type_t           pk_alg;
+} oid_sig_alg_t;
+
+static const oid_sig_alg_t oid_sig_alg[] =
+{
+#if defined(MBEDTLS_RSA_C)
+#if defined(MBEDTLS_MD2_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ),        "md2WithRSAEncryption",     "RSA with MD2" },
+        MBEDTLS_MD_MD2,      MBEDTLS_PK_RSA,
+    },
+#endif /* MBEDTLS_MD2_C */
+#if defined(MBEDTLS_MD4_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ),        "md4WithRSAEncryption",     "RSA with MD4" },
+        MBEDTLS_MD_MD4,      MBEDTLS_PK_RSA,
+    },
+#endif /* MBEDTLS_MD4_C */
+#if defined(MBEDTLS_MD5_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ),        "md5WithRSAEncryption",     "RSA with MD5" },
+        MBEDTLS_MD_MD5,      MBEDTLS_PK_RSA,
+    },
+#endif /* MBEDTLS_MD5_C */
+#if defined(MBEDTLS_SHA1_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ),       "sha-1WithRSAEncryption",   "RSA with SHA1" },
+        MBEDTLS_MD_SHA1,     MBEDTLS_PK_RSA,
+    },
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ),     "sha224WithRSAEncryption",  "RSA with SHA-224" },
+        MBEDTLS_MD_SHA224,   MBEDTLS_PK_RSA,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ),     "sha256WithRSAEncryption",  "RSA with SHA-256" },
+        MBEDTLS_MD_SHA256,   MBEDTLS_PK_RSA,
+    },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ),     "sha384WithRSAEncryption",  "RSA with SHA-384" },
+        MBEDTLS_MD_SHA384,   MBEDTLS_PK_RSA,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ),     "sha512WithRSAEncryption",  "RSA with SHA-512" },
+        MBEDTLS_MD_SHA512,   MBEDTLS_PK_RSA,
+    },
+#endif /* MBEDTLS_SHA512_C */
+#if defined(MBEDTLS_SHA1_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ),      "sha-1WithRSAEncryption",   "RSA with SHA1" },
+        MBEDTLS_MD_SHA1,     MBEDTLS_PK_RSA,
+    },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_RSA_C */
+#if defined(MBEDTLS_ECDSA_C)
+#if defined(MBEDTLS_SHA1_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ),       "ecdsa-with-SHA1",      "ECDSA with SHA1" },
+        MBEDTLS_MD_SHA1,     MBEDTLS_PK_ECDSA,
+    },
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ),     "ecdsa-with-SHA224",    "ECDSA with SHA224" },
+        MBEDTLS_MD_SHA224,   MBEDTLS_PK_ECDSA,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ),     "ecdsa-with-SHA256",    "ECDSA with SHA256" },
+        MBEDTLS_MD_SHA256,   MBEDTLS_PK_ECDSA,
+    },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ),     "ecdsa-with-SHA384",    "ECDSA with SHA384" },
+        MBEDTLS_MD_SHA384,   MBEDTLS_PK_ECDSA,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ),     "ecdsa-with-SHA512",    "ECDSA with SHA512" },
+        MBEDTLS_MD_SHA512,   MBEDTLS_PK_ECDSA,
+    },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_ECDSA_C */
+#if defined(MBEDTLS_RSA_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_RSASSA_PSS ),        "RSASSA-PSS",           "RSASSA-PSS" },
+        MBEDTLS_MD_NONE,     MBEDTLS_PK_RSASSA_PSS,
+    },
+#endif /* MBEDTLS_RSA_C */
+    {
+        { NULL, 0, NULL, NULL },
+        MBEDTLS_MD_NONE, MBEDTLS_PK_NONE,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg)
+FN_OID_GET_DESCRIPTOR_ATTR1(mbedtls_oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description)
+FN_OID_GET_ATTR2(mbedtls_oid_get_sig_alg, oid_sig_alg_t, sig_alg, mbedtls_md_type_t, md_alg, mbedtls_pk_type_t, pk_alg)
+FN_OID_GET_OID_BY_ATTR2(mbedtls_oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, mbedtls_pk_type_t, pk_alg, mbedtls_md_type_t, md_alg)
+#endif /* MBEDTLS_MD_C */
+
+/*
+ * For PublicKeyInfo (PKCS1, RFC 5480)
+ */
+typedef struct {
+    mbedtls_oid_descriptor_t    descriptor;
+    mbedtls_pk_type_t           pk_alg;
+} oid_pk_alg_t;
+
+static const oid_pk_alg_t oid_pk_alg[] =
+{
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS1_RSA ),      "rsaEncryption",   "RSA" },
+        MBEDTLS_PK_RSA,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_ALG_UNRESTRICTED ),  "id-ecPublicKey",   "Generic EC key" },
+        MBEDTLS_PK_ECKEY,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_ALG_ECDH ),          "id-ecDH",          "EC key for ECDH" },
+        MBEDTLS_PK_ECKEY_DH,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        MBEDTLS_PK_NONE,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg)
+FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg)
+FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, mbedtls_pk_type_t, pk_alg)
+
+#if defined(MBEDTLS_ECP_C)
+/*
+ * For namedCurve (RFC 5480)
+ */
+typedef struct {
+    mbedtls_oid_descriptor_t    descriptor;
+    mbedtls_ecp_group_id        grp_id;
+} oid_ecp_grp_t;
+
+static const oid_ecp_grp_t oid_ecp_grp[] =
+{
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1",    "secp192r1" },
+        MBEDTLS_ECP_DP_SECP192R1,
+    },
+#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1",    "secp224r1" },
+        MBEDTLS_ECP_DP_SECP224R1,
+    },
+#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1",    "secp256r1" },
+        MBEDTLS_ECP_DP_SECP256R1,
+    },
+#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1",    "secp384r1" },
+        MBEDTLS_ECP_DP_SECP384R1,
+    },
+#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1",    "secp521r1" },
+        MBEDTLS_ECP_DP_SECP521R1,
+    },
+#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1",    "secp192k1" },
+        MBEDTLS_ECP_DP_SECP192K1,
+    },
+#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1",    "secp224k1" },
+        MBEDTLS_ECP_DP_SECP224K1,
+    },
+#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1",    "secp256k1" },
+        MBEDTLS_ECP_DP_SECP256K1,
+    },
+#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ),   "brainpoolP256r1","brainpool256r1" },
+        MBEDTLS_ECP_DP_BP256R1,
+    },
+#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ),   "brainpoolP384r1","brainpool384r1" },
+        MBEDTLS_ECP_DP_BP384R1,
+    },
+#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+    {
+        { ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ),   "brainpoolP512r1","brainpool512r1" },
+        MBEDTLS_ECP_DP_BP512R1,
+    },
+#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
+    {
+        { NULL, 0, NULL, NULL },
+        MBEDTLS_ECP_DP_NONE,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp)
+FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id)
+FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_ecp_group_id, grp_id)
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_CIPHER_C)
+/*
+ * For PKCS#5 PBES2 encryption algorithm
+ */
+typedef struct {
+    mbedtls_oid_descriptor_t    descriptor;
+    mbedtls_cipher_type_t       cipher_alg;
+} oid_cipher_alg_t;
+
+static const oid_cipher_alg_t oid_cipher_alg[] =
+{
+    {
+        { ADD_LEN( MBEDTLS_OID_DES_CBC ),              "desCBC",       "DES-CBC" },
+        MBEDTLS_CIPHER_DES_CBC,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_DES_EDE3_CBC ),         "des-ede3-cbc", "DES-EDE3-CBC" },
+        MBEDTLS_CIPHER_DES_EDE3_CBC,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        MBEDTLS_CIPHER_NONE,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg)
+FN_OID_GET_ATTR1(mbedtls_oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, mbedtls_cipher_type_t, cipher_alg)
+#endif /* MBEDTLS_CIPHER_C */
+
+#if defined(MBEDTLS_MD_C)
+/*
+ * For digestAlgorithm
+ */
+typedef struct {
+    mbedtls_oid_descriptor_t    descriptor;
+    mbedtls_md_type_t           md_alg;
+} oid_md_alg_t;
+
+static const oid_md_alg_t oid_md_alg[] =
+{
+#if defined(MBEDTLS_MD2_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ),       "id-md2",       "MD2" },
+        MBEDTLS_MD_MD2,
+    },
+#endif /* MBEDTLS_MD2_C */
+#if defined(MBEDTLS_MD4_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ),       "id-md4",       "MD4" },
+        MBEDTLS_MD_MD4,
+    },
+#endif /* MBEDTLS_MD4_C */
+#if defined(MBEDTLS_MD5_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ),       "id-md5",       "MD5" },
+        MBEDTLS_MD_MD5,
+    },
+#endif /* MBEDTLS_MD5_C */
+#if defined(MBEDTLS_SHA1_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ),      "id-sha1",      "SHA-1" },
+        MBEDTLS_MD_SHA1,
+    },
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ),    "id-sha224",    "SHA-224" },
+        MBEDTLS_MD_SHA224,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ),    "id-sha256",    "SHA-256" },
+        MBEDTLS_MD_SHA256,
+    },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ),    "id-sha384",    "SHA-384" },
+        MBEDTLS_MD_SHA384,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ),    "id-sha512",    "SHA-512" },
+        MBEDTLS_MD_SHA512,
+    },
+#endif /* MBEDTLS_SHA512_C */
+    {
+        { NULL, 0, NULL, NULL },
+        MBEDTLS_MD_NONE,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg)
+FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg)
+FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg)
+
+/*
+ * For HMAC digestAlgorithm
+ */
+typedef struct {
+    mbedtls_oid_descriptor_t    descriptor;
+    mbedtls_md_type_t           md_hmac;
+} oid_md_hmac_t;
+
+static const oid_md_hmac_t oid_md_hmac[] =
+{
+#if defined(MBEDTLS_SHA1_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_HMAC_SHA1 ),      "hmacSHA1",      "HMAC-SHA-1" },
+        MBEDTLS_MD_SHA1,
+    },
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_HMAC_SHA224 ),    "hmacSHA224",    "HMAC-SHA-224" },
+        MBEDTLS_MD_SHA224,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_HMAC_SHA256 ),    "hmacSHA256",    "HMAC-SHA-256" },
+        MBEDTLS_MD_SHA256,
+    },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    {
+        { ADD_LEN( MBEDTLS_OID_HMAC_SHA384 ),    "hmacSHA384",    "HMAC-SHA-384" },
+        MBEDTLS_MD_SHA384,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_HMAC_SHA512 ),    "hmacSHA512",    "HMAC-SHA-512" },
+        MBEDTLS_MD_SHA512,
+    },
+#endif /* MBEDTLS_SHA512_C */
+    {
+        { NULL, 0, NULL, NULL },
+        MBEDTLS_MD_NONE,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_md_hmac_t, md_hmac, oid_md_hmac)
+FN_OID_GET_ATTR1(mbedtls_oid_get_md_hmac, oid_md_hmac_t, md_hmac, mbedtls_md_type_t, md_hmac)
+#endif /* MBEDTLS_MD_C */
+
+#if defined(MBEDTLS_PKCS12_C)
+/*
+ * For PKCS#12 PBEs
+ */
+typedef struct {
+    mbedtls_oid_descriptor_t    descriptor;
+    mbedtls_md_type_t           md_alg;
+    mbedtls_cipher_type_t       cipher_alg;
+} oid_pkcs12_pbe_alg_t;
+
+static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] =
+{
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" },
+        MBEDTLS_MD_SHA1,      MBEDTLS_CIPHER_DES_EDE3_CBC,
+    },
+    {
+        { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" },
+        MBEDTLS_MD_SHA1,      MBEDTLS_CIPHER_DES_EDE_CBC,
+    },
+    {
+        { NULL, 0, NULL, NULL },
+        MBEDTLS_MD_NONE, MBEDTLS_CIPHER_NONE,
+    },
+};
+
+FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg)
+FN_OID_GET_ATTR2(mbedtls_oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, mbedtls_md_type_t, md_alg, mbedtls_cipher_type_t, cipher_alg)
+#endif /* MBEDTLS_PKCS12_C */
+
+#define OID_SAFE_SNPRINTF                               \
+    do {                                                \
+        if( ret < 0 || (size_t) ret >= n )              \
+            return( MBEDTLS_ERR_OID_BUF_TOO_SMALL );    \
+                                                        \
+        n -= (size_t) ret;                              \
+        p += (size_t) ret;                              \
+    } while( 0 )
+
+/* Return the x.y.z.... style numeric string for the given OID */
+int mbedtls_oid_get_numeric_string( char *buf, size_t size,
+                            const mbedtls_asn1_buf *oid )
+{
+    int ret;
+    size_t i, n;
+    unsigned int value;
+    char *p;
+
+    p = buf;
+    n = size;
+
+    /* First byte contains first two dots */
+    if( oid->len > 0 )
+    {
+        ret = mbedtls_snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 );
+        OID_SAFE_SNPRINTF;
+    }
+
+    value = 0;
+    for( i = 1; i < oid->len; i++ )
+    {
+        /* Prevent overflow in value. */
+        if( ( ( value << 7 ) >> 7 ) != value )
+            return( MBEDTLS_ERR_OID_BUF_TOO_SMALL );
+
+        value <<= 7;
+        value += oid->p[i] & 0x7F;
+
+        if( !( oid->p[i] & 0x80 ) )
+        {
+            /* Last byte */
+            ret = mbedtls_snprintf( p, n, ".%d", value );
+            OID_SAFE_SNPRINTF;
+            value = 0;
+        }
+    }
+
+    return( (int) ( size - n ) );
+}
+
+#endif /* MBEDTLS_OID_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/padlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/padlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/padlock.c	(revision 398)
@@ -0,0 +1,170 @@
+/*
+ *  VIA PadLock support functions
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  This implementation is based on the VIA PadLock Programming Guide:
+ *
+ *  http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/
+ *  programming_guide.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PADLOCK_C)
+
+#include "mbedtls/padlock.h"
+
+#include <string.h>
+
+#ifndef asm
+#define asm __asm
+#endif
+
+#if defined(MBEDTLS_HAVE_X86)
+
+/*
+ * PadLock detection routine
+ */
+int mbedtls_padlock_has_support( int feature )
+{
+    static int flags = -1;
+    int ebx = 0, edx = 0;
+
+    if( flags == -1 )
+    {
+        asm( "movl  %%ebx, %0           \n\t"
+             "movl  $0xC0000000, %%eax  \n\t"
+             "cpuid                     \n\t"
+             "cmpl  $0xC0000001, %%eax  \n\t"
+             "movl  $0, %%edx           \n\t"
+             "jb    unsupported         \n\t"
+             "movl  $0xC0000001, %%eax  \n\t"
+             "cpuid                     \n\t"
+             "unsupported:              \n\t"
+             "movl  %%edx, %1           \n\t"
+             "movl  %2, %%ebx           \n\t"
+             : "=m" (ebx), "=m" (edx)
+             :  "m" (ebx)
+             : "eax", "ecx", "edx" );
+
+        flags = edx;
+    }
+
+    return( flags & feature );
+}
+
+/*
+ * PadLock AES-ECB block en(de)cryption
+ */
+int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx,
+                       int mode,
+                       const unsigned char input[16],
+                       unsigned char output[16] )
+{
+    int ebx = 0;
+    uint32_t *rk;
+    uint32_t *blk;
+    uint32_t *ctrl;
+    unsigned char buf[256];
+
+    rk  = ctx->rk;
+    blk = MBEDTLS_PADLOCK_ALIGN16( buf );
+    memcpy( blk, input, 16 );
+
+     ctrl = blk + 4;
+    *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 );
+
+    asm( "pushfl                        \n\t"
+         "popfl                         \n\t"
+         "movl    %%ebx, %0             \n\t"
+         "movl    $1, %%ecx             \n\t"
+         "movl    %2, %%edx             \n\t"
+         "movl    %3, %%ebx             \n\t"
+         "movl    %4, %%esi             \n\t"
+         "movl    %4, %%edi             \n\t"
+         ".byte  0xf3,0x0f,0xa7,0xc8    \n\t"
+         "movl    %1, %%ebx             \n\t"
+         : "=m" (ebx)
+         :  "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk)
+         : "memory", "ecx", "edx", "esi", "edi" );
+
+    memcpy( output, blk, 16 );
+
+    return( 0 );
+}
+
+/*
+ * PadLock AES-CBC buffer en(de)cryption
+ */
+int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       unsigned char iv[16],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    int ebx = 0;
+    size_t count;
+    uint32_t *rk;
+    uint32_t *iw;
+    uint32_t *ctrl;
+    unsigned char buf[256];
+
+    if( ( (long) input  & 15 ) != 0 ||
+        ( (long) output & 15 ) != 0 )
+        return( MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED );
+
+    rk = ctx->rk;
+    iw = MBEDTLS_PADLOCK_ALIGN16( buf );
+    memcpy( iw, iv, 16 );
+
+     ctrl = iw + 4;
+    *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 );
+
+    count = ( length + 15 ) >> 4;
+
+    asm( "pushfl                        \n\t"
+         "popfl                         \n\t"
+         "movl    %%ebx, %0             \n\t"
+         "movl    %2, %%ecx             \n\t"
+         "movl    %3, %%edx             \n\t"
+         "movl    %4, %%ebx             \n\t"
+         "movl    %5, %%esi             \n\t"
+         "movl    %6, %%edi             \n\t"
+         "movl    %7, %%eax             \n\t"
+         ".byte  0xf3,0x0f,0xa7,0xd0    \n\t"
+         "movl    %1, %%ebx             \n\t"
+         : "=m" (ebx)
+         :  "m" (ebx), "m" (count), "m" (ctrl),
+            "m"  (rk), "m" (input), "m" (output), "m" (iw)
+         : "memory", "eax", "ecx", "edx", "esi", "edi" );
+
+    memcpy( iv, iw, 16 );
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_HAVE_X86 */
+
+#endif /* MBEDTLS_PADLOCK_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pem.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pem.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pem.c	(revision 398)
@@ -0,0 +1,490 @@
+/*
+ *  Privacy Enhanced Mail (PEM) decoding
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
+
+#include "mbedtls/pem.h"
+#include "mbedtls/base64.h"
+#include "mbedtls/des.h"
+#include "mbedtls/aes.h"
+#include "mbedtls/md5.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+void mbedtls_pem_init( mbedtls_pem_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_pem_context ) );
+}
+
+#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) &&         \
+    ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
+/*
+ * Read a 16-byte hex string and convert it to binary
+ */
+static int pem_get_iv( const unsigned char *s, unsigned char *iv,
+                       size_t iv_len )
+{
+    size_t i, j, k;
+
+    memset( iv, 0, iv_len );
+
+    for( i = 0; i < iv_len * 2; i++, s++ )
+    {
+        if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
+        if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
+        if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
+            return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
+
+        k = ( ( i & 1 ) != 0 ) ? j : j << 4;
+
+        iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
+    }
+
+    return( 0 );
+}
+
+static int pem_pbkdf1( unsigned char *key, size_t keylen,
+                       unsigned char *iv,
+                       const unsigned char *pwd, size_t pwdlen )
+{
+    mbedtls_md5_context md5_ctx;
+    unsigned char md5sum[16];
+    size_t use_len;
+    int ret;
+
+    mbedtls_md5_init( &md5_ctx );
+
+    /*
+     * key[ 0..15] = MD5(pwd || IV)
+     */
+    if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv,  8 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 )
+        goto exit;
+
+    if( keylen <= 16 )
+    {
+        memcpy( key, md5sum, keylen );
+        goto exit;
+    }
+
+    memcpy( key, md5sum, 16 );
+
+    /*
+     * key[16..23] = MD5(key[ 0..15] || pwd || IV])
+     */
+    if( ( ret = mbedtls_md5_starts_ret( &md5_ctx ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, md5sum, 16 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, pwd, pwdlen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_update_ret( &md5_ctx, iv, 8 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md5_finish_ret( &md5_ctx, md5sum ) ) != 0 )
+        goto exit;
+
+    use_len = 16;
+    if( keylen < 32 )
+        use_len = keylen - 16;
+
+    memcpy( key + 16, md5sum, use_len );
+
+exit:
+    mbedtls_md5_free( &md5_ctx );
+    mbedtls_platform_zeroize( md5sum, 16 );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_DES_C)
+/*
+ * Decrypt with DES-CBC, using PBKDF1 for key derivation
+ */
+static int pem_des_decrypt( unsigned char des_iv[8],
+                            unsigned char *buf, size_t buflen,
+                            const unsigned char *pwd, size_t pwdlen )
+{
+    mbedtls_des_context des_ctx;
+    unsigned char des_key[8];
+    int ret;
+
+    mbedtls_des_init( &des_ctx );
+
+    if( ( ret = pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_des_setkey_dec( &des_ctx, des_key ) ) != 0 )
+        goto exit;
+    ret = mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen,
+                     des_iv, buf, buf );
+
+exit:
+    mbedtls_des_free( &des_ctx );
+    mbedtls_platform_zeroize( des_key, 8 );
+
+    return( ret );
+}
+
+/*
+ * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
+ */
+static int pem_des3_decrypt( unsigned char des3_iv[8],
+                             unsigned char *buf, size_t buflen,
+                             const unsigned char *pwd, size_t pwdlen )
+{
+    mbedtls_des3_context des3_ctx;
+    unsigned char des3_key[24];
+    int ret;
+
+    mbedtls_des3_init( &des3_ctx );
+
+    if( ( ret = pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_des3_set3key_dec( &des3_ctx, des3_key ) ) != 0 )
+        goto exit;
+    ret = mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen,
+                     des3_iv, buf, buf );
+
+exit:
+    mbedtls_des3_free( &des3_ctx );
+    mbedtls_platform_zeroize( des3_key, 24 );
+
+    return( ret );
+}
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_AES_C)
+/*
+ * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation
+ */
+static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
+                            unsigned char *buf, size_t buflen,
+                            const unsigned char *pwd, size_t pwdlen )
+{
+    mbedtls_aes_context aes_ctx;
+    unsigned char aes_key[32];
+    int ret;
+
+    mbedtls_aes_init( &aes_ctx );
+
+    if( ( ret = pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ) ) != 0 )
+        goto exit;
+    ret = mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen,
+                     aes_iv, buf, buf );
+
+exit:
+    mbedtls_aes_free( &aes_ctx );
+    mbedtls_platform_zeroize( aes_key, keylen );
+
+    return( ret );
+}
+#endif /* MBEDTLS_AES_C */
+
+#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
+          ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
+
+int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer,
+                     const unsigned char *data, const unsigned char *pwd,
+                     size_t pwdlen, size_t *use_len )
+{
+    int ret, enc;
+    size_t len;
+    unsigned char *buf;
+    const unsigned char *s1, *s2, *end;
+#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) &&         \
+    ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
+    unsigned char pem_iv[16];
+    mbedtls_cipher_type_t enc_alg = MBEDTLS_CIPHER_NONE;
+#else
+    ((void) pwd);
+    ((void) pwdlen);
+#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
+          ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
+
+    if( ctx == NULL )
+        return( MBEDTLS_ERR_PEM_BAD_INPUT_DATA );
+
+    s1 = (unsigned char *) strstr( (const char *) data, header );
+
+    if( s1 == NULL )
+        return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
+
+    s2 = (unsigned char *) strstr( (const char *) data, footer );
+
+    if( s2 == NULL || s2 <= s1 )
+        return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
+
+    s1 += strlen( header );
+    if( *s1 == ' '  ) s1++;
+    if( *s1 == '\r' ) s1++;
+    if( *s1 == '\n' ) s1++;
+    else return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
+
+    end = s2;
+    end += strlen( footer );
+    if( *end == ' '  ) end++;
+    if( *end == '\r' ) end++;
+    if( *end == '\n' ) end++;
+    *use_len = end - data;
+
+    enc = 0;
+
+    if( s2 - s1 >= 22 && memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
+    {
+#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) &&         \
+    ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
+        enc++;
+
+        s1 += 22;
+        if( *s1 == '\r' ) s1++;
+        if( *s1 == '\n' ) s1++;
+        else return( MBEDTLS_ERR_PEM_INVALID_DATA );
+
+
+#if defined(MBEDTLS_DES_C)
+        if( s2 - s1 >= 23 && memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
+        {
+            enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC;
+
+            s1 += 23;
+            if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8 ) != 0 )
+                return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
+
+            s1 += 16;
+        }
+        else if( s2 - s1 >= 18 && memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
+        {
+            enc_alg = MBEDTLS_CIPHER_DES_CBC;
+
+            s1 += 18;
+            if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8) != 0 )
+                return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
+
+            s1 += 16;
+        }
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_AES_C)
+        if( s2 - s1 >= 14 && memcmp( s1, "DEK-Info: AES-", 14 ) == 0 )
+        {
+            if( s2 - s1 < 22 )
+                return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
+            else if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
+                enc_alg = MBEDTLS_CIPHER_AES_128_CBC;
+            else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
+                enc_alg = MBEDTLS_CIPHER_AES_192_CBC;
+            else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 )
+                enc_alg = MBEDTLS_CIPHER_AES_256_CBC;
+            else
+                return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
+
+            s1 += 22;
+            if( s2 - s1 < 32 || pem_get_iv( s1, pem_iv, 16 ) != 0 )
+                return( MBEDTLS_ERR_PEM_INVALID_ENC_IV );
+
+            s1 += 32;
+        }
+#endif /* MBEDTLS_AES_C */
+
+        if( enc_alg == MBEDTLS_CIPHER_NONE )
+            return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
+
+        if( *s1 == '\r' ) s1++;
+        if( *s1 == '\n' ) s1++;
+        else return( MBEDTLS_ERR_PEM_INVALID_DATA );
+#else
+        return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
+          ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
+    }
+
+    if( s1 >= s2 )
+        return( MBEDTLS_ERR_PEM_INVALID_DATA );
+
+    ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 );
+
+    if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )
+        return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
+
+    if( ( buf = mbedtls_calloc( 1, len ) ) == NULL )
+        return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
+
+    if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 )
+    {
+        mbedtls_platform_zeroize( buf, len );
+        mbedtls_free( buf );
+        return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
+    }
+
+    if( enc != 0 )
+    {
+#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) &&         \
+    ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
+        if( pwd == NULL )
+        {
+            mbedtls_platform_zeroize( buf, len );
+            mbedtls_free( buf );
+            return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED );
+        }
+
+        ret = 0;
+
+#if defined(MBEDTLS_DES_C)
+        if( enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC )
+            ret = pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen );
+        else if( enc_alg == MBEDTLS_CIPHER_DES_CBC )
+            ret = pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen );
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_AES_C)
+        if( enc_alg == MBEDTLS_CIPHER_AES_128_CBC )
+            ret = pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen );
+        else if( enc_alg == MBEDTLS_CIPHER_AES_192_CBC )
+            ret = pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen );
+        else if( enc_alg == MBEDTLS_CIPHER_AES_256_CBC )
+            ret = pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen );
+#endif /* MBEDTLS_AES_C */
+
+        if( ret != 0 )
+        {
+            mbedtls_free( buf );
+            return( ret );
+        }
+
+        /*
+         * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3
+         * length bytes (allow 4 to be sure) in all known use cases.
+         *
+         * Use that as a heuristic to try to detect password mismatches.
+         */
+        if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
+        {
+            mbedtls_platform_zeroize( buf, len );
+            mbedtls_free( buf );
+            return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH );
+        }
+#else
+        mbedtls_platform_zeroize( buf, len );
+        mbedtls_free( buf );
+        return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC &&
+          ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
+    }
+
+    ctx->buf = buf;
+    ctx->buflen = len;
+
+    return( 0 );
+}
+
+void mbedtls_pem_free( mbedtls_pem_context *ctx )
+{
+    if ( ctx->buf != NULL )
+    {
+        mbedtls_platform_zeroize( ctx->buf, ctx->buflen );
+        mbedtls_free( ctx->buf );
+    }
+    mbedtls_free( ctx->info );
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pem_context ) );
+}
+#endif /* MBEDTLS_PEM_PARSE_C */
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+int mbedtls_pem_write_buffer( const char *header, const char *footer,
+                      const unsigned char *der_data, size_t der_len,
+                      unsigned char *buf, size_t buf_len, size_t *olen )
+{
+    int ret;
+    unsigned char *encode_buf = NULL, *c, *p = buf;
+    size_t len = 0, use_len, add_len = 0;
+
+    mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len );
+    add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1;
+
+    if( use_len + add_len > buf_len )
+    {
+        *olen = use_len + add_len;
+        return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
+    }
+
+    if( use_len != 0 &&
+        ( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) )
+        return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
+
+    if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data,
+                               der_len ) ) != 0 )
+    {
+        mbedtls_free( encode_buf );
+        return( ret );
+    }
+
+    memcpy( p, header, strlen( header ) );
+    p += strlen( header );
+    c = encode_buf;
+
+    while( use_len )
+    {
+        len = ( use_len > 64 ) ? 64 : use_len;
+        memcpy( p, c, len );
+        use_len -= len;
+        p += len;
+        c += len;
+        *p++ = '\n';
+    }
+
+    memcpy( p, footer, strlen( footer ) );
+    p += strlen( footer );
+
+    *p++ = '\0';
+    *olen = p - buf;
+
+    mbedtls_free( encode_buf );
+    return( 0 );
+}
+#endif /* MBEDTLS_PEM_WRITE_C */
+#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pk.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pk.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pk.c	(revision 398)
@@ -0,0 +1,546 @@
+/*
+ *  Public Key abstraction layer
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PK_C)
+#include "mbedtls/pk.h"
+#include "mbedtls/pk_internal.h"
+
+#include "mbedtls/platform_util.h"
+
+#if defined(MBEDTLS_RSA_C)
+#include "mbedtls/rsa.h"
+#endif
+#if defined(MBEDTLS_ECP_C)
+#include "mbedtls/ecp.h"
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+#include "mbedtls/ecdsa.h"
+#endif
+
+#include <limits.h>
+#include <stdint.h>
+
+/* Parameter validation macros based on platform_util.h */
+#define PK_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
+#define PK_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+/*
+ * Initialise a mbedtls_pk_context
+ */
+void mbedtls_pk_init( mbedtls_pk_context *ctx )
+{
+    PK_VALIDATE( ctx != NULL );
+
+    ctx->pk_info = NULL;
+    ctx->pk_ctx = NULL;
+}
+
+/*
+ * Free (the components of) a mbedtls_pk_context
+ */
+void mbedtls_pk_free( mbedtls_pk_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    if ( ctx->pk_info != NULL )
+        ctx->pk_info->ctx_free_func( ctx->pk_ctx );
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_pk_context ) );
+}
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+/*
+ * Initialize a restart context
+ */
+void mbedtls_pk_restart_init( mbedtls_pk_restart_ctx *ctx )
+{
+    PK_VALIDATE( ctx != NULL );
+    ctx->pk_info = NULL;
+    ctx->rs_ctx = NULL;
+}
+
+/*
+ * Free the components of a restart context
+ */
+void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx )
+{
+    if( ctx == NULL || ctx->pk_info == NULL ||
+        ctx->pk_info->rs_free_func == NULL )
+    {
+        return;
+    }
+
+    ctx->pk_info->rs_free_func( ctx->rs_ctx );
+
+    ctx->pk_info = NULL;
+    ctx->rs_ctx = NULL;
+}
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+/*
+ * Get pk_info structure from type
+ */
+const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type )
+{
+    switch( pk_type ) {
+#if defined(MBEDTLS_RSA_C)
+        case MBEDTLS_PK_RSA:
+            return( &mbedtls_rsa_info );
+#endif
+#if defined(MBEDTLS_ECP_C)
+        case MBEDTLS_PK_ECKEY:
+            return( &mbedtls_eckey_info );
+        case MBEDTLS_PK_ECKEY_DH:
+            return( &mbedtls_eckeydh_info );
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+        case MBEDTLS_PK_ECDSA:
+            return( &mbedtls_ecdsa_info );
+#endif
+        /* MBEDTLS_PK_RSA_ALT omitted on purpose */
+        default:
+            return( NULL );
+    }
+}
+
+/*
+ * Initialise context
+ */
+int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
+{
+    PK_VALIDATE_RET( ctx != NULL );
+    if( info == NULL || ctx->pk_info != NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
+        return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+
+    ctx->pk_info = info;
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+/*
+ * Initialize an RSA-alt context
+ */
+int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key,
+                         mbedtls_pk_rsa_alt_decrypt_func decrypt_func,
+                         mbedtls_pk_rsa_alt_sign_func sign_func,
+                         mbedtls_pk_rsa_alt_key_len_func key_len_func )
+{
+    mbedtls_rsa_alt_context *rsa_alt;
+    const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info;
+
+    PK_VALIDATE_RET( ctx != NULL );
+    if( ctx->pk_info != NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
+        return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+
+    ctx->pk_info = info;
+
+    rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx;
+
+    rsa_alt->key = key;
+    rsa_alt->decrypt_func = decrypt_func;
+    rsa_alt->sign_func = sign_func;
+    rsa_alt->key_len_func = key_len_func;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
+
+/*
+ * Tell if a PK can do the operations of the given type
+ */
+int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type )
+{
+    /* A context with null pk_info is not set up yet and can't do anything.
+     * For backward compatibility, also accept NULL instead of a context
+     * pointer. */
+    if( ctx == NULL || ctx->pk_info == NULL )
+        return( 0 );
+
+    return( ctx->pk_info->can_do( type ) );
+}
+
+/*
+ * Helper for mbedtls_pk_sign and mbedtls_pk_verify
+ */
+static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len )
+{
+    const mbedtls_md_info_t *md_info;
+
+    if( *hash_len != 0 )
+        return( 0 );
+
+    if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
+        return( -1 );
+
+    *hash_len = mbedtls_md_get_size( md_info );
+    return( 0 );
+}
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+/*
+ * Helper to set up a restart context if needed
+ */
+static int pk_restart_setup( mbedtls_pk_restart_ctx *ctx,
+                             const mbedtls_pk_info_t *info )
+{
+    /* Don't do anything if already set up or invalid */
+    if( ctx == NULL || ctx->pk_info != NULL )
+        return( 0 );
+
+    /* Should never happen when we're called */
+    if( info->rs_alloc_func == NULL || info->rs_free_func == NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    if( ( ctx->rs_ctx = info->rs_alloc_func() ) == NULL )
+        return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+
+    ctx->pk_info = info;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+/*
+ * Verify a signature (restartable)
+ */
+int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
+               mbedtls_md_type_t md_alg,
+               const unsigned char *hash, size_t hash_len,
+               const unsigned char *sig, size_t sig_len,
+               mbedtls_pk_restart_ctx *rs_ctx )
+{
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+                     hash != NULL );
+    PK_VALIDATE_RET( sig != NULL );
+
+    if( ctx->pk_info == NULL ||
+        pk_hashlen_helper( md_alg, &hash_len ) != 0 )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    /* optimization: use non-restartable version if restart disabled */
+    if( rs_ctx != NULL &&
+        mbedtls_ecp_restart_is_enabled() &&
+        ctx->pk_info->verify_rs_func != NULL )
+    {
+        int ret;
+
+        if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
+            return( ret );
+
+        ret = ctx->pk_info->verify_rs_func( ctx->pk_ctx,
+                   md_alg, hash, hash_len, sig, sig_len, rs_ctx->rs_ctx );
+
+        if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
+            mbedtls_pk_restart_free( rs_ctx );
+
+        return( ret );
+    }
+#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+    (void) rs_ctx;
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+    if( ctx->pk_info->verify_func == NULL )
+        return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+    return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
+                                       sig, sig_len ) );
+}
+
+/*
+ * Verify a signature
+ */
+int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+               const unsigned char *hash, size_t hash_len,
+               const unsigned char *sig, size_t sig_len )
+{
+    return( mbedtls_pk_verify_restartable( ctx, md_alg, hash, hash_len,
+                                           sig, sig_len, NULL ) );
+}
+
+/*
+ * Verify a signature with options
+ */
+int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
+                   mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   const unsigned char *sig, size_t sig_len )
+{
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+                     hash != NULL );
+    PK_VALIDATE_RET( sig != NULL );
+
+    if( ctx->pk_info == NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    if( ! mbedtls_pk_can_do( ctx, type ) )
+        return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+    if( type == MBEDTLS_PK_RSASSA_PSS )
+    {
+#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
+        int ret;
+        const mbedtls_pk_rsassa_pss_options *pss_opts;
+
+#if SIZE_MAX > UINT_MAX
+        if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
+            return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+#endif /* SIZE_MAX > UINT_MAX */
+
+        if( options == NULL )
+            return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+        pss_opts = (const mbedtls_pk_rsassa_pss_options *) options;
+
+        if( sig_len < mbedtls_pk_get_len( ctx ) )
+            return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
+
+        ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ),
+                NULL, NULL, MBEDTLS_RSA_PUBLIC,
+                md_alg, (unsigned int) hash_len, hash,
+                pss_opts->mgf1_hash_id,
+                pss_opts->expected_salt_len,
+                sig );
+        if( ret != 0 )
+            return( ret );
+
+        if( sig_len > mbedtls_pk_get_len( ctx ) )
+            return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
+
+        return( 0 );
+#else
+        return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */
+    }
+
+    /* General case: no options */
+    if( options != NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
+}
+
+/*
+ * Make a signature (restartable)
+ */
+int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
+             mbedtls_md_type_t md_alg,
+             const unsigned char *hash, size_t hash_len,
+             unsigned char *sig, size_t *sig_len,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+             mbedtls_pk_restart_ctx *rs_ctx )
+{
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( ( md_alg == MBEDTLS_MD_NONE && hash_len == 0 ) ||
+                     hash != NULL );
+    PK_VALIDATE_RET( sig != NULL );
+
+    if( ctx->pk_info == NULL ||
+        pk_hashlen_helper( md_alg, &hash_len ) != 0 )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    /* optimization: use non-restartable version if restart disabled */
+    if( rs_ctx != NULL &&
+        mbedtls_ecp_restart_is_enabled() &&
+        ctx->pk_info->sign_rs_func != NULL )
+    {
+        int ret;
+
+        if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
+            return( ret );
+
+        ret = ctx->pk_info->sign_rs_func( ctx->pk_ctx, md_alg,
+                hash, hash_len, sig, sig_len, f_rng, p_rng, rs_ctx->rs_ctx );
+
+        if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
+            mbedtls_pk_restart_free( rs_ctx );
+
+        return( ret );
+    }
+#else /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+    (void) rs_ctx;
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+    if( ctx->pk_info->sign_func == NULL )
+        return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+    return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
+                                     sig, sig_len, f_rng, p_rng ) );
+}
+
+/*
+ * Make a signature
+ */
+int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
+             const unsigned char *hash, size_t hash_len,
+             unsigned char *sig, size_t *sig_len,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    return( mbedtls_pk_sign_restartable( ctx, md_alg, hash, hash_len,
+                                         sig, sig_len, f_rng, p_rng, NULL ) );
+}
+
+/*
+ * Decrypt message
+ */
+int mbedtls_pk_decrypt( mbedtls_pk_context *ctx,
+                const unsigned char *input, size_t ilen,
+                unsigned char *output, size_t *olen, size_t osize,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( input != NULL || ilen == 0 );
+    PK_VALIDATE_RET( output != NULL || osize == 0 );
+    PK_VALIDATE_RET( olen != NULL );
+
+    if( ctx->pk_info == NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    if( ctx->pk_info->decrypt_func == NULL )
+        return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+    return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
+                output, olen, osize, f_rng, p_rng ) );
+}
+
+/*
+ * Encrypt message
+ */
+int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
+                const unsigned char *input, size_t ilen,
+                unsigned char *output, size_t *olen, size_t osize,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( input != NULL || ilen == 0 );
+    PK_VALIDATE_RET( output != NULL || osize == 0 );
+    PK_VALIDATE_RET( olen != NULL );
+
+    if( ctx->pk_info == NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    if( ctx->pk_info->encrypt_func == NULL )
+        return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+    return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
+                output, olen, osize, f_rng, p_rng ) );
+}
+
+/*
+ * Check public-private key pair
+ */
+int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv )
+{
+    PK_VALIDATE_RET( pub != NULL );
+    PK_VALIDATE_RET( prv != NULL );
+
+    if( pub->pk_info == NULL ||
+        prv->pk_info == NULL ||
+        prv->pk_info->check_pair_func == NULL )
+    {
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+    }
+
+    if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
+    {
+        if( pub->pk_info->type != MBEDTLS_PK_RSA )
+            return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+    }
+    else
+    {
+        if( pub->pk_info != prv->pk_info )
+            return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+    }
+
+    return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) );
+}
+
+/*
+ * Get key size in bits
+ */
+size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx )
+{
+    /* For backward compatibility, accept NULL or a context that
+     * isn't set up yet, and return a fake value that should be safe. */
+    if( ctx == NULL || ctx->pk_info == NULL )
+        return( 0 );
+
+    return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) );
+}
+
+/*
+ * Export debug information
+ */
+int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
+{
+    PK_VALIDATE_RET( ctx != NULL );
+    if( ctx->pk_info == NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    if( ctx->pk_info->debug_func == NULL )
+        return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+    ctx->pk_info->debug_func( ctx->pk_ctx, items );
+    return( 0 );
+}
+
+/*
+ * Access the PK type name
+ */
+const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx )
+{
+    if( ctx == NULL || ctx->pk_info == NULL )
+        return( "invalid PK" );
+
+    return( ctx->pk_info->name );
+}
+
+/*
+ * Access the PK type
+ */
+mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
+{
+    if( ctx == NULL || ctx->pk_info == NULL )
+        return( MBEDTLS_PK_NONE );
+
+    return( ctx->pk_info->type );
+}
+
+#endif /* MBEDTLS_PK_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pk_wrap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pk_wrap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pk_wrap.c	(revision 398)
@@ -0,0 +1,719 @@
+/*
+ *  Public Key abstraction layer: wrapper functions
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PK_C)
+#include "mbedtls/pk_internal.h"
+
+/* Even if RSA not activated, for the sake of RSA-alt */
+#include "mbedtls/rsa.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_ECP_C)
+#include "mbedtls/ecp.h"
+#endif
+
+#if defined(MBEDTLS_ECDSA_C)
+#include "mbedtls/ecdsa.h"
+#endif
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+#include "mbedtls/platform_util.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#include <limits.h>
+#include <stdint.h>
+
+#if defined(MBEDTLS_RSA_C)
+static int rsa_can_do( mbedtls_pk_type_t type )
+{
+    return( type == MBEDTLS_PK_RSA ||
+            type == MBEDTLS_PK_RSASSA_PSS );
+}
+
+static size_t rsa_get_bitlen( const void *ctx )
+{
+    const mbedtls_rsa_context * rsa = (const mbedtls_rsa_context *) ctx;
+    return( 8 * mbedtls_rsa_get_len( rsa ) );
+}
+
+static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   const unsigned char *sig, size_t sig_len )
+{
+    int ret;
+    mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
+    size_t rsa_len = mbedtls_rsa_get_len( rsa );
+
+#if SIZE_MAX > UINT_MAX
+    if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+#endif /* SIZE_MAX > UINT_MAX */
+
+    if( sig_len < rsa_len )
+        return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
+
+    if( ( ret = mbedtls_rsa_pkcs1_verify( rsa, NULL, NULL,
+                                  MBEDTLS_RSA_PUBLIC, md_alg,
+                                  (unsigned int) hash_len, hash, sig ) ) != 0 )
+        return( ret );
+
+    /* The buffer contains a valid signature followed by extra data.
+     * We have a special error code for that so that so that callers can
+     * use mbedtls_pk_verify() to check "Does the buffer start with a
+     * valid signature?" and not just "Does the buffer contain a valid
+     * signature?". */
+    if( sig_len > rsa_len )
+        return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
+
+    return( 0 );
+}
+
+static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   unsigned char *sig, size_t *sig_len,
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
+
+#if SIZE_MAX > UINT_MAX
+    if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+#endif /* SIZE_MAX > UINT_MAX */
+
+    *sig_len = mbedtls_rsa_get_len( rsa );
+
+    return( mbedtls_rsa_pkcs1_sign( rsa, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
+                md_alg, (unsigned int) hash_len, hash, sig ) );
+}
+
+static int rsa_decrypt_wrap( void *ctx,
+                    const unsigned char *input, size_t ilen,
+                    unsigned char *output, size_t *olen, size_t osize,
+                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
+
+    if( ilen != mbedtls_rsa_get_len( rsa ) )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    return( mbedtls_rsa_pkcs1_decrypt( rsa, f_rng, p_rng,
+                MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
+}
+
+static int rsa_encrypt_wrap( void *ctx,
+                    const unsigned char *input, size_t ilen,
+                    unsigned char *output, size_t *olen, size_t osize,
+                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
+    *olen = mbedtls_rsa_get_len( rsa );
+
+    if( *olen > osize )
+        return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
+
+    return( mbedtls_rsa_pkcs1_encrypt( rsa, f_rng, p_rng, MBEDTLS_RSA_PUBLIC,
+                                       ilen, input, output ) );
+}
+
+static int rsa_check_pair_wrap( const void *pub, const void *prv )
+{
+    return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub,
+                                (const mbedtls_rsa_context *) prv ) );
+}
+
+static void *rsa_alloc_wrap( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) );
+
+    if( ctx != NULL )
+        mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 );
+
+    return( ctx );
+}
+
+static void rsa_free_wrap( void *ctx )
+{
+    mbedtls_rsa_free( (mbedtls_rsa_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items )
+{
+    items->type = MBEDTLS_PK_DEBUG_MPI;
+    items->name = "rsa.N";
+    items->value = &( ((mbedtls_rsa_context *) ctx)->N );
+
+    items++;
+
+    items->type = MBEDTLS_PK_DEBUG_MPI;
+    items->name = "rsa.E";
+    items->value = &( ((mbedtls_rsa_context *) ctx)->E );
+}
+
+const mbedtls_pk_info_t mbedtls_rsa_info = {
+    MBEDTLS_PK_RSA,
+    "RSA",
+    rsa_get_bitlen,
+    rsa_can_do,
+    rsa_verify_wrap,
+    rsa_sign_wrap,
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    NULL,
+    NULL,
+#endif
+    rsa_decrypt_wrap,
+    rsa_encrypt_wrap,
+    rsa_check_pair_wrap,
+    rsa_alloc_wrap,
+    rsa_free_wrap,
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    NULL,
+    NULL,
+#endif
+    rsa_debug,
+};
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_ECP_C)
+/*
+ * Generic EC key
+ */
+static int eckey_can_do( mbedtls_pk_type_t type )
+{
+    return( type == MBEDTLS_PK_ECKEY ||
+            type == MBEDTLS_PK_ECKEY_DH ||
+            type == MBEDTLS_PK_ECDSA );
+}
+
+static size_t eckey_get_bitlen( const void *ctx )
+{
+    return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits );
+}
+
+#if defined(MBEDTLS_ECDSA_C)
+/* Forward declarations */
+static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                       const unsigned char *hash, size_t hash_len,
+                       const unsigned char *sig, size_t sig_len );
+
+static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   unsigned char *sig, size_t *sig_len,
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                       const unsigned char *hash, size_t hash_len,
+                       const unsigned char *sig, size_t sig_len )
+{
+    int ret;
+    mbedtls_ecdsa_context ecdsa;
+
+    mbedtls_ecdsa_init( &ecdsa );
+
+    if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
+        ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );
+
+    mbedtls_ecdsa_free( &ecdsa );
+
+    return( ret );
+}
+
+static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   unsigned char *sig, size_t *sig_len,
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret;
+    mbedtls_ecdsa_context ecdsa;
+
+    mbedtls_ecdsa_init( &ecdsa );
+
+    if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
+        ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
+                               f_rng, p_rng );
+
+    mbedtls_ecdsa_free( &ecdsa );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+/* Forward declarations */
+static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                       const unsigned char *hash, size_t hash_len,
+                       const unsigned char *sig, size_t sig_len,
+                       void *rs_ctx );
+
+static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   unsigned char *sig, size_t *sig_len,
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                   void *rs_ctx );
+
+/*
+ * Restart context for ECDSA operations with ECKEY context
+ *
+ * We need to store an actual ECDSA context, as we need to pass the same to
+ * the underlying ecdsa function, so we can't create it on the fly every time.
+ */
+typedef struct
+{
+    mbedtls_ecdsa_restart_ctx ecdsa_rs;
+    mbedtls_ecdsa_context ecdsa_ctx;
+} eckey_restart_ctx;
+
+static void *eckey_rs_alloc( void )
+{
+    eckey_restart_ctx *rs_ctx;
+
+    void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) );
+
+    if( ctx != NULL )
+    {
+        rs_ctx = ctx;
+        mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs );
+        mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx );
+    }
+
+    return( ctx );
+}
+
+static void eckey_rs_free( void *ctx )
+{
+    eckey_restart_ctx *rs_ctx;
+
+    if( ctx == NULL)
+        return;
+
+    rs_ctx = ctx;
+    mbedtls_ecdsa_restart_free( &rs_ctx->ecdsa_rs );
+    mbedtls_ecdsa_free( &rs_ctx->ecdsa_ctx );
+
+    mbedtls_free( ctx );
+}
+
+static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                       const unsigned char *hash, size_t hash_len,
+                       const unsigned char *sig, size_t sig_len,
+                       void *rs_ctx )
+{
+    int ret;
+    eckey_restart_ctx *rs = rs_ctx;
+
+    /* Should never happen */
+    if( rs == NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    /* set up our own sub-context if needed (that is, on first run) */
+    if( rs->ecdsa_ctx.grp.pbits == 0 )
+        MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
+
+    MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx,
+                                           md_alg, hash, hash_len,
+                                           sig, sig_len, &rs->ecdsa_rs ) );
+
+cleanup:
+    return( ret );
+}
+
+static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   unsigned char *sig, size_t *sig_len,
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                       void *rs_ctx )
+{
+    int ret;
+    eckey_restart_ctx *rs = rs_ctx;
+
+    /* Should never happen */
+    if( rs == NULL )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+    /* set up our own sub-context if needed (that is, on first run) */
+    if( rs->ecdsa_ctx.grp.pbits == 0 )
+        MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) );
+
+    MBEDTLS_MPI_CHK( ecdsa_sign_rs_wrap( &rs->ecdsa_ctx, md_alg,
+                                         hash, hash_len, sig, sig_len,
+                                         f_rng, p_rng, &rs->ecdsa_rs ) );
+
+cleanup:
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+#endif /* MBEDTLS_ECDSA_C */
+
+static int eckey_check_pair( const void *pub, const void *prv )
+{
+    return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub,
+                                (const mbedtls_ecp_keypair *) prv ) );
+}
+
+static void *eckey_alloc_wrap( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
+
+    if( ctx != NULL )
+        mbedtls_ecp_keypair_init( ctx );
+
+    return( ctx );
+}
+
+static void eckey_free_wrap( void *ctx )
+{
+    mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx );
+    mbedtls_free( ctx );
+}
+
+static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items )
+{
+    items->type = MBEDTLS_PK_DEBUG_ECP;
+    items->name = "eckey.Q";
+    items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q );
+}
+
+const mbedtls_pk_info_t mbedtls_eckey_info = {
+    MBEDTLS_PK_ECKEY,
+    "EC",
+    eckey_get_bitlen,
+    eckey_can_do,
+#if defined(MBEDTLS_ECDSA_C)
+    eckey_verify_wrap,
+    eckey_sign_wrap,
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    eckey_verify_rs_wrap,
+    eckey_sign_rs_wrap,
+#endif
+#else /* MBEDTLS_ECDSA_C */
+    NULL,
+    NULL,
+#endif /* MBEDTLS_ECDSA_C */
+    NULL,
+    NULL,
+    eckey_check_pair,
+    eckey_alloc_wrap,
+    eckey_free_wrap,
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    eckey_rs_alloc,
+    eckey_rs_free,
+#endif
+    eckey_debug,
+};
+
+/*
+ * EC key restricted to ECDH
+ */
+static int eckeydh_can_do( mbedtls_pk_type_t type )
+{
+    return( type == MBEDTLS_PK_ECKEY ||
+            type == MBEDTLS_PK_ECKEY_DH );
+}
+
+const mbedtls_pk_info_t mbedtls_eckeydh_info = {
+    MBEDTLS_PK_ECKEY_DH,
+    "EC_DH",
+    eckey_get_bitlen,         /* Same underlying key structure */
+    eckeydh_can_do,
+    NULL,
+    NULL,
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    NULL,
+    NULL,
+#endif
+    NULL,
+    NULL,
+    eckey_check_pair,
+    eckey_alloc_wrap,       /* Same underlying key structure */
+    eckey_free_wrap,        /* Same underlying key structure */
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    NULL,
+    NULL,
+#endif
+    eckey_debug,            /* Same underlying key structure */
+};
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_ECDSA_C)
+static int ecdsa_can_do( mbedtls_pk_type_t type )
+{
+    return( type == MBEDTLS_PK_ECDSA );
+}
+
+static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                       const unsigned char *hash, size_t hash_len,
+                       const unsigned char *sig, size_t sig_len )
+{
+    int ret;
+    ((void) md_alg);
+
+    ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
+                                hash, hash_len, sig, sig_len );
+
+    if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
+        return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
+
+    return( ret );
+}
+
+static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   unsigned char *sig, size_t *sig_len,
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx,
+                md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) );
+}
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                       const unsigned char *hash, size_t hash_len,
+                       const unsigned char *sig, size_t sig_len,
+                       void *rs_ctx )
+{
+    int ret;
+    ((void) md_alg);
+
+    ret = mbedtls_ecdsa_read_signature_restartable(
+            (mbedtls_ecdsa_context *) ctx,
+            hash, hash_len, sig, sig_len,
+            (mbedtls_ecdsa_restart_ctx *) rs_ctx );
+
+    if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH )
+        return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH );
+
+    return( ret );
+}
+
+static int ecdsa_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   unsigned char *sig, size_t *sig_len,
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+                   void *rs_ctx )
+{
+    return( mbedtls_ecdsa_write_signature_restartable(
+                (mbedtls_ecdsa_context *) ctx,
+                md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng,
+                (mbedtls_ecdsa_restart_ctx *) rs_ctx ) );
+
+}
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+static void *ecdsa_alloc_wrap( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );
+
+    if( ctx != NULL )
+        mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );
+
+    return( ctx );
+}
+
+static void ecdsa_free_wrap( void *ctx )
+{
+    mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx );
+    mbedtls_free( ctx );
+}
+
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+static void *ecdsa_rs_alloc( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_restart_ctx ) );
+
+    if( ctx != NULL )
+        mbedtls_ecdsa_restart_init( ctx );
+
+    return( ctx );
+}
+
+static void ecdsa_rs_free( void *ctx )
+{
+    mbedtls_ecdsa_restart_free( ctx );
+    mbedtls_free( ctx );
+}
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+
+const mbedtls_pk_info_t mbedtls_ecdsa_info = {
+    MBEDTLS_PK_ECDSA,
+    "ECDSA",
+    eckey_get_bitlen,     /* Compatible key structures */
+    ecdsa_can_do,
+    ecdsa_verify_wrap,
+    ecdsa_sign_wrap,
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    ecdsa_verify_rs_wrap,
+    ecdsa_sign_rs_wrap,
+#endif
+    NULL,
+    NULL,
+    eckey_check_pair,   /* Compatible key structures */
+    ecdsa_alloc_wrap,
+    ecdsa_free_wrap,
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    ecdsa_rs_alloc,
+    ecdsa_rs_free,
+#endif
+    eckey_debug,        /* Compatible key structures */
+};
+#endif /* MBEDTLS_ECDSA_C */
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+/*
+ * Support for alternative RSA-private implementations
+ */
+
+static int rsa_alt_can_do( mbedtls_pk_type_t type )
+{
+    return( type == MBEDTLS_PK_RSA );
+}
+
+static size_t rsa_alt_get_bitlen( const void *ctx )
+{
+    const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx;
+
+    return( 8 * rsa_alt->key_len_func( rsa_alt->key ) );
+}
+
+static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
+                   const unsigned char *hash, size_t hash_len,
+                   unsigned char *sig, size_t *sig_len,
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
+
+#if SIZE_MAX > UINT_MAX
+    if( UINT_MAX < hash_len )
+        return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+#endif /* SIZE_MAX > UINT_MAX */
+
+    *sig_len = rsa_alt->key_len_func( rsa_alt->key );
+
+    return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
+                md_alg, (unsigned int) hash_len, hash, sig ) );
+}
+
+static int rsa_alt_decrypt_wrap( void *ctx,
+                    const unsigned char *input, size_t ilen,
+                    unsigned char *output, size_t *olen, size_t osize,
+                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx;
+
+    ((void) f_rng);
+    ((void) p_rng);
+
+    if( ilen != rsa_alt->key_len_func( rsa_alt->key ) )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    return( rsa_alt->decrypt_func( rsa_alt->key,
+                MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) );
+}
+
+#if defined(MBEDTLS_RSA_C)
+static int rsa_alt_check_pair( const void *pub, const void *prv )
+{
+    unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
+    unsigned char hash[32];
+    size_t sig_len = 0;
+    int ret;
+
+    if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+
+    memset( hash, 0x2a, sizeof( hash ) );
+
+    if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE,
+                                   hash, sizeof( hash ),
+                                   sig, &sig_len, NULL, NULL ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE,
+                         hash, sizeof( hash ), sig, sig_len ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_RSA_C */
+
+static void *rsa_alt_alloc_wrap( void )
+{
+    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) );
+
+    if( ctx != NULL )
+        memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) );
+
+    return( ctx );
+}
+
+static void rsa_alt_free_wrap( void *ctx )
+{
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) );
+    mbedtls_free( ctx );
+}
+
+const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
+    MBEDTLS_PK_RSA_ALT,
+    "RSA-alt",
+    rsa_alt_get_bitlen,
+    rsa_alt_can_do,
+    NULL,
+    rsa_alt_sign_wrap,
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    NULL,
+    NULL,
+#endif
+    rsa_alt_decrypt_wrap,
+    NULL,
+#if defined(MBEDTLS_RSA_C)
+    rsa_alt_check_pair,
+#else
+    NULL,
+#endif
+    rsa_alt_alloc_wrap,
+    rsa_alt_free_wrap,
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    NULL,
+    NULL,
+#endif
+    NULL,
+};
+
+#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
+
+#endif /* MBEDTLS_PK_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkcs11.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkcs11.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkcs11.c	(revision 398)
@@ -0,0 +1,240 @@
+/**
+ * \file pkcs11.c
+ *
+ * \brief Wrapper for PKCS#11 library libpkcs11-helper
+ *
+ * \author Adriaan de Jong <dejong@fox-it.com>
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#include "mbedtls/pkcs11.h"
+
+#if defined(MBEDTLS_PKCS11_C)
+
+#include "mbedtls/md.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/x509_crt.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#include <string.h>
+
+void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) );
+}
+
+int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
+{
+    int ret = 1;
+    unsigned char *cert_blob = NULL;
+    size_t cert_blob_size = 0;
+
+    if( cert == NULL )
+    {
+        ret = 2;
+        goto cleanup;
+    }
+
+    if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL,
+                                                &cert_blob_size ) != CKR_OK )
+    {
+        ret = 3;
+        goto cleanup;
+    }
+
+    cert_blob = mbedtls_calloc( 1, cert_blob_size );
+    if( NULL == cert_blob )
+    {
+        ret = 4;
+        goto cleanup;
+    }
+
+    if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob,
+                                                &cert_blob_size ) != CKR_OK )
+    {
+        ret = 5;
+        goto cleanup;
+    }
+
+    if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) )
+    {
+        ret = 6;
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    if( NULL != cert_blob )
+        mbedtls_free( cert_blob );
+
+    return( ret );
+}
+
+
+int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key,
+        pkcs11h_certificate_t pkcs11_cert )
+{
+    int ret = 1;
+    mbedtls_x509_crt cert;
+
+    mbedtls_x509_crt_init( &cert );
+
+    if( priv_key == NULL )
+        goto cleanup;
+
+    if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) )
+        goto cleanup;
+
+    priv_key->len = mbedtls_pk_get_len( &cert.pk );
+    priv_key->pkcs11h_cert = pkcs11_cert;
+
+    ret = 0;
+
+cleanup:
+    mbedtls_x509_crt_free( &cert );
+
+    return( ret );
+}
+
+void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key )
+{
+    if( NULL != priv_key )
+        pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
+}
+
+int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
+                       int mode, size_t *olen,
+                       const unsigned char *input,
+                       unsigned char *output,
+                       size_t output_max_len )
+{
+    size_t input_len, output_len;
+
+    if( NULL == ctx )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    if( MBEDTLS_RSA_PRIVATE != mode )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    output_len = input_len = ctx->len;
+
+    if( input_len < 16 || input_len > output_max_len )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    /* Determine size of output buffer */
+    if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
+            input_len, NULL, &output_len ) != CKR_OK )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    if( output_len > output_max_len )
+        return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE );
+
+    if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
+            input_len, output, &output_len ) != CKR_OK )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+    *olen = output_len;
+    return( 0 );
+}
+
+int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx,
+                    int mode,
+                    mbedtls_md_type_t md_alg,
+                    unsigned int hashlen,
+                    const unsigned char *hash,
+                    unsigned char *sig )
+{
+    size_t sig_len = 0, asn_len = 0, oid_size = 0;
+    unsigned char *p = sig;
+    const char *oid;
+
+    if( NULL == ctx )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    if( MBEDTLS_RSA_PRIVATE != mode )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    if( md_alg != MBEDTLS_MD_NONE )
+    {
+        const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
+        if( md_info == NULL )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+        if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+        hashlen = mbedtls_md_get_size( md_info );
+        asn_len = 10 + oid_size;
+    }
+
+    sig_len = ctx->len;
+    if( hashlen > sig_len || asn_len > sig_len ||
+        hashlen + asn_len > sig_len )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    if( md_alg != MBEDTLS_MD_NONE )
+    {
+        /*
+         * DigestInfo ::= SEQUENCE {
+         *   digestAlgorithm DigestAlgorithmIdentifier,
+         *   digest Digest }
+         *
+         * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+         *
+         * Digest ::= OCTET STRING
+         */
+        *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
+        *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
+        *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
+        *p++ = (unsigned char) ( 0x04 + oid_size );
+        *p++ = MBEDTLS_ASN1_OID;
+        *p++ = oid_size & 0xFF;
+        memcpy( p, oid, oid_size );
+        p += oid_size;
+        *p++ = MBEDTLS_ASN1_NULL;
+        *p++ = 0x00;
+        *p++ = MBEDTLS_ASN1_OCTET_STRING;
+        *p++ = hashlen;
+    }
+
+    memcpy( p, hash, hashlen );
+
+    if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
+            asn_len + hashlen, sig, &sig_len ) != CKR_OK )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    return( 0 );
+}
+
+#endif /* defined(MBEDTLS_PKCS11_C) */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkcs12.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkcs12.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkcs12.c	(revision 398)
@@ -0,0 +1,365 @@
+/*
+ *  PKCS#12 Personal Information Exchange Syntax
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The PKCS #12 Personal Information Exchange Syntax Standard v1.1
+ *
+ *  http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf
+ *  ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PKCS12_C)
+
+#include "mbedtls/pkcs12.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_ARC4_C)
+#include "mbedtls/arc4.h"
+#endif
+
+#if defined(MBEDTLS_DES_C)
+#include "mbedtls/des.h"
+#endif
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+
+static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
+                                    mbedtls_asn1_buf *salt, int *iterations )
+{
+    int ret;
+    unsigned char **p = &params->p;
+    const unsigned char *end = params->p + params->len;
+
+    /*
+     *  pkcs-12PbeParams ::= SEQUENCE {
+     *    salt          OCTET STRING,
+     *    iterations    INTEGER
+     *  }
+     *
+     */
+    if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+        return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+        return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
+
+    salt->p = *p;
+    *p += salt->len;
+
+    if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 )
+        return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
+
+    if( *p != end )
+        return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+#define PKCS12_MAX_PWDLEN 128
+
+static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type,
+                                     const unsigned char *pwd,  size_t pwdlen,
+                                     unsigned char *key, size_t keylen,
+                                     unsigned char *iv,  size_t ivlen )
+{
+    int ret, iterations = 0;
+    mbedtls_asn1_buf salt;
+    size_t i;
+    unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2];
+
+    if( pwdlen > PKCS12_MAX_PWDLEN )
+        return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
+
+    memset( &salt, 0, sizeof(mbedtls_asn1_buf) );
+    memset( &unipwd, 0, sizeof(unipwd) );
+
+    if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt,
+                                         &iterations ) ) != 0 )
+        return( ret );
+
+    for( i = 0; i < pwdlen; i++ )
+        unipwd[i * 2 + 1] = pwd[i];
+
+    if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2,
+                                   salt.p, salt.len, md_type,
+                                   MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( iv == NULL || ivlen == 0 )
+        return( 0 );
+
+    if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2,
+                                   salt.p, salt.len, md_type,
+                                   MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 )
+    {
+        return( ret );
+    }
+    return( 0 );
+}
+
+#undef PKCS12_MAX_PWDLEN
+
+int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
+                             const unsigned char *pwd,  size_t pwdlen,
+                             const unsigned char *data, size_t len,
+                             unsigned char *output )
+{
+#if !defined(MBEDTLS_ARC4_C)
+    ((void) pbe_params);
+    ((void) mode);
+    ((void) pwd);
+    ((void) pwdlen);
+    ((void) data);
+    ((void) len);
+    ((void) output);
+    return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
+#else
+    int ret;
+    unsigned char key[16];
+    mbedtls_arc4_context ctx;
+    ((void) mode);
+
+    mbedtls_arc4_init( &ctx );
+
+    if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1,
+                                          pwd, pwdlen,
+                                          key, 16, NULL, 0 ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    mbedtls_arc4_setup( &ctx, key, 16 );
+    if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_platform_zeroize( key, sizeof( key ) );
+    mbedtls_arc4_free( &ctx );
+
+    return( ret );
+#endif /* MBEDTLS_ARC4_C */
+}
+
+int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode,
+                mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type,
+                const unsigned char *pwd,  size_t pwdlen,
+                const unsigned char *data, size_t len,
+                unsigned char *output )
+{
+    int ret, keylen = 0;
+    unsigned char key[32];
+    unsigned char iv[16];
+    const mbedtls_cipher_info_t *cipher_info;
+    mbedtls_cipher_context_t cipher_ctx;
+    size_t olen = 0;
+
+    cipher_info = mbedtls_cipher_info_from_type( cipher_type );
+    if( cipher_info == NULL )
+        return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
+
+    keylen = cipher_info->key_bitlen / 8;
+
+    if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen,
+                                          key, keylen,
+                                          iv, cipher_info->iv_size ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    mbedtls_cipher_init( &cipher_ctx );
+
+    if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len,
+                                output, &olen ) ) != 0 )
+    {
+        goto exit;
+    }
+
+    if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
+        ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH;
+
+exit:
+    mbedtls_platform_zeroize( key, sizeof( key ) );
+    mbedtls_platform_zeroize( iv,  sizeof( iv  ) );
+    mbedtls_cipher_free( &cipher_ctx );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
+static void pkcs12_fill_buffer( unsigned char *data, size_t data_len,
+                                const unsigned char *filler, size_t fill_len )
+{
+    unsigned char *p = data;
+    size_t use_len;
+
+    while( data_len > 0 )
+    {
+        use_len = ( data_len > fill_len ) ? fill_len : data_len;
+        memcpy( p, filler, use_len );
+        p += use_len;
+        data_len -= use_len;
+    }
+}
+
+int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
+                       const unsigned char *pwd, size_t pwdlen,
+                       const unsigned char *salt, size_t saltlen,
+                       mbedtls_md_type_t md_type, int id, int iterations )
+{
+    int ret;
+    unsigned int j;
+
+    unsigned char diversifier[128];
+    unsigned char salt_block[128], pwd_block[128], hash_block[128];
+    unsigned char hash_output[MBEDTLS_MD_MAX_SIZE];
+    unsigned char *p;
+    unsigned char c;
+
+    size_t hlen, use_len, v, i;
+
+    const mbedtls_md_info_t *md_info;
+    mbedtls_md_context_t md_ctx;
+
+    // This version only allows max of 64 bytes of password or salt
+    if( datalen > 128 || pwdlen > 64 || saltlen > 64 )
+        return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
+
+    md_info = mbedtls_md_info_from_type( md_type );
+    if( md_info == NULL )
+        return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
+
+    mbedtls_md_init( &md_ctx );
+
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+        return( ret );
+    hlen = mbedtls_md_get_size( md_info );
+
+    if( hlen <= 32 )
+        v = 64;
+    else
+        v = 128;
+
+    memset( diversifier, (unsigned char) id, v );
+
+    pkcs12_fill_buffer( salt_block, v, salt, saltlen );
+    pkcs12_fill_buffer( pwd_block,  v, pwd,  pwdlen  );
+
+    p = data;
+    while( datalen > 0 )
+    {
+        // Calculate hash( diversifier || salt_block || pwd_block )
+        if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
+            goto exit;
+
+        if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 )
+            goto exit;
+
+        if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 )
+            goto exit;
+
+        if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 )
+            goto exit;
+
+        if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 )
+            goto exit;
+
+        // Perform remaining ( iterations - 1 ) recursive hash calculations
+        for( i = 1; i < (size_t) iterations; i++ )
+        {
+            if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 )
+                goto exit;
+        }
+
+        use_len = ( datalen > hlen ) ? hlen : datalen;
+        memcpy( p, hash_output, use_len );
+        datalen -= use_len;
+        p += use_len;
+
+        if( datalen == 0 )
+            break;
+
+        // Concatenating copies of hash_output into hash_block (B)
+        pkcs12_fill_buffer( hash_block, v, hash_output, hlen );
+
+        // B += 1
+        for( i = v; i > 0; i-- )
+            if( ++hash_block[i - 1] != 0 )
+                break;
+
+        // salt_block += B
+        c = 0;
+        for( i = v; i > 0; i-- )
+        {
+            j = salt_block[i - 1] + hash_block[i - 1] + c;
+            c = (unsigned char) (j >> 8);
+            salt_block[i - 1] = j & 0xFF;
+        }
+
+        // pwd_block  += B
+        c = 0;
+        for( i = v; i > 0; i-- )
+        {
+            j = pwd_block[i - 1] + hash_block[i - 1] + c;
+            c = (unsigned char) (j >> 8);
+            pwd_block[i - 1] = j & 0xFF;
+        }
+    }
+
+    ret = 0;
+
+exit:
+    mbedtls_platform_zeroize( salt_block, sizeof( salt_block ) );
+    mbedtls_platform_zeroize( pwd_block, sizeof( pwd_block ) );
+    mbedtls_platform_zeroize( hash_block, sizeof( hash_block ) );
+    mbedtls_platform_zeroize( hash_output, sizeof( hash_output ) );
+
+    mbedtls_md_free( &md_ctx );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_PKCS12_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkcs5.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkcs5.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkcs5.c	(revision 398)
@@ -0,0 +1,411 @@
+/**
+ * \file pkcs5.c
+ *
+ * \brief PKCS#5 functions
+ *
+ * \author Mathias Olsson <mathias@kompetensum.com>
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * PKCS#5 includes PBKDF2 and more
+ *
+ * http://tools.ietf.org/html/rfc2898 (Specification)
+ * http://tools.ietf.org/html/rfc6070 (Test vectors)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PKCS5_C)
+
+#include "mbedtls/pkcs5.h"
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+#include "mbedtls/asn1.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/oid.h"
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
+#include <string.h>
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
+                                      mbedtls_asn1_buf *salt, int *iterations,
+                                      int *keylen, mbedtls_md_type_t *md_type )
+{
+    int ret;
+    mbedtls_asn1_buf prf_alg_oid;
+    unsigned char *p = params->p;
+    const unsigned char *end = params->p + params->len;
+
+    if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+        return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+    /*
+     *  PBKDF2-params ::= SEQUENCE {
+     *    salt              OCTET STRING,
+     *    iterationCount    INTEGER,
+     *    keyLength         INTEGER OPTIONAL
+     *    prf               AlgorithmIdentifier DEFAULT algid-hmacWithSHA1
+     *  }
+     *
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+        return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+
+    salt->p = p;
+    p += salt->len;
+
+    if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 )
+        return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+
+    if( p == end )
+        return( 0 );
+
+    if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 )
+    {
+        if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+            return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+    }
+
+    if( p == end )
+        return( 0 );
+
+    if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
+        return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+
+    if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 )
+        return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
+
+    if( p != end )
+        return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
+                 const unsigned char *pwd,  size_t pwdlen,
+                 const unsigned char *data, size_t datalen,
+                 unsigned char *output )
+{
+    int ret, iterations = 0, keylen = 0;
+    unsigned char *p, *end;
+    mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params;
+    mbedtls_asn1_buf salt;
+    mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
+    unsigned char key[32], iv[32];
+    size_t olen = 0;
+    const mbedtls_md_info_t *md_info;
+    const mbedtls_cipher_info_t *cipher_info;
+    mbedtls_md_context_t md_ctx;
+    mbedtls_cipher_type_t cipher_alg;
+    mbedtls_cipher_context_t cipher_ctx;
+
+    p = pbe_params->p;
+    end = p + pbe_params->len;
+
+    /*
+     *  PBES2-params ::= SEQUENCE {
+     *    keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
+     *    encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
+     *  }
+     */
+    if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+        return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+    if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 )
+        return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+
+    // Only PBKDF2 supported at the moment
+    //
+    if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid ) != 0 )
+        return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
+
+    if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params,
+                                           &salt, &iterations, &keylen,
+                                           &md_type ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    md_info = mbedtls_md_info_from_type( md_type );
+    if( md_info == NULL )
+        return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
+
+    if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid,
+                              &enc_scheme_params ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+    }
+
+    if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 )
+        return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
+
+    cipher_info = mbedtls_cipher_info_from_type( cipher_alg );
+    if( cipher_info == NULL )
+        return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
+
+    /*
+     * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored
+     * since it is optional and we don't know if it was set or not
+     */
+    keylen = cipher_info->key_bitlen / 8;
+
+    if( enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING ||
+        enc_scheme_params.len != cipher_info->iv_size )
+    {
+        return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT );
+    }
+
+    mbedtls_md_init( &md_ctx );
+    mbedtls_cipher_init( &cipher_ctx );
+
+    memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
+
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
+                                   iterations, keylen, key ) ) != 0 )
+    {
+        goto exit;
+    }
+
+    if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len,
+                              data, datalen, output, &olen ) ) != 0 )
+        ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH;
+
+exit:
+    mbedtls_md_free( &md_ctx );
+    mbedtls_cipher_free( &cipher_ctx );
+
+    return( ret );
+}
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
+int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
+                       size_t plen, const unsigned char *salt, size_t slen,
+                       unsigned int iteration_count,
+                       uint32_t key_length, unsigned char *output )
+{
+    int ret, j;
+    unsigned int i;
+    unsigned char md1[MBEDTLS_MD_MAX_SIZE];
+    unsigned char work[MBEDTLS_MD_MAX_SIZE];
+    unsigned char md_size = mbedtls_md_get_size( ctx->md_info );
+    size_t use_len;
+    unsigned char *out_p = output;
+    unsigned char counter[4];
+
+    memset( counter, 0, 4 );
+    counter[3] = 1;
+
+#if UINT_MAX > 0xFFFFFFFF
+    if( iteration_count > 0xFFFFFFFF )
+        return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
+#endif
+
+    while( key_length )
+    {
+        // U1 ends up in work
+        //
+        if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
+            return( ret );
+
+        if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 )
+            return( ret );
+
+        if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 )
+            return( ret );
+
+        if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
+            return( ret );
+
+        memcpy( md1, work, md_size );
+
+        for( i = 1; i < iteration_count; i++ )
+        {
+            // U2 ends up in md1
+            //
+            if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
+                return( ret );
+
+            if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 )
+                return( ret );
+
+            if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 )
+                return( ret );
+
+            // U1 xor U2
+            //
+            for( j = 0; j < md_size; j++ )
+                work[j] ^= md1[j];
+        }
+
+        use_len = ( key_length < md_size ) ? key_length : md_size;
+        memcpy( out_p, work, use_len );
+
+        key_length -= (uint32_t) use_len;
+        out_p += use_len;
+
+        for( i = 4; i > 0; i-- )
+            if( ++counter[i - 1] != 0 )
+                break;
+    }
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SELF_TEST)
+
+#if !defined(MBEDTLS_SHA1_C)
+int mbedtls_pkcs5_self_test( int verbose )
+{
+    if( verbose != 0 )
+        mbedtls_printf( "  PBKDF2 (SHA1): skipped\n\n" );
+
+    return( 0 );
+}
+#else
+
+#define MAX_TESTS   6
+
+static const size_t plen[MAX_TESTS] =
+    { 8, 8, 8, 24, 9 };
+
+static const unsigned char password[MAX_TESTS][32] =
+{
+    "password",
+    "password",
+    "password",
+    "passwordPASSWORDpassword",
+    "pass\0word",
+};
+
+static const size_t slen[MAX_TESTS] =
+    { 4, 4, 4, 36, 5 };
+
+static const unsigned char salt[MAX_TESTS][40] =
+{
+    "salt",
+    "salt",
+    "salt",
+    "saltSALTsaltSALTsaltSALTsaltSALTsalt",
+    "sa\0lt",
+};
+
+static const uint32_t it_cnt[MAX_TESTS] =
+    { 1, 2, 4096, 4096, 4096 };
+
+static const uint32_t key_len[MAX_TESTS] =
+    { 20, 20, 20, 25, 16 };
+
+static const unsigned char result_key[MAX_TESTS][32] =
+{
+    { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
+      0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
+      0x2f, 0xe0, 0x37, 0xa6 },
+    { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
+      0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
+      0xd8, 0xde, 0x89, 0x57 },
+    { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
+      0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
+      0x65, 0xa4, 0x29, 0xc1 },
+    { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
+      0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
+      0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
+      0x38 },
+    { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
+      0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 },
+};
+
+int mbedtls_pkcs5_self_test( int verbose )
+{
+    mbedtls_md_context_t sha1_ctx;
+    const mbedtls_md_info_t *info_sha1;
+    int ret, i;
+    unsigned char key[64];
+
+    mbedtls_md_init( &sha1_ctx );
+
+    info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
+    if( info_sha1 == NULL )
+    {
+        ret = 1;
+        goto exit;
+    }
+
+    if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 )
+    {
+        ret = 1;
+        goto exit;
+    }
+
+    for( i = 0; i < MAX_TESTS; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  PBKDF2 (SHA1) #%d: ", i );
+
+        ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
+                                  slen[i], it_cnt[i], key_len[i], key );
+        if( ret != 0 ||
+            memcmp( result_key[i], key, key_len[i] ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+exit:
+    mbedtls_md_free( &sha1_ctx );
+
+    return( ret );
+}
+#endif /* MBEDTLS_SHA1_C */
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_PKCS5_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkparse.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkparse.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkparse.c	(revision 398)
@@ -0,0 +1,1482 @@
+/*
+ *  Public Key layer for parsing key files and structures
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PK_PARSE_C)
+
+#include "mbedtls/pk.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_RSA_C)
+#include "mbedtls/rsa.h"
+#endif
+#if defined(MBEDTLS_ECP_C)
+#include "mbedtls/ecp.h"
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+#include "mbedtls/ecdsa.h"
+#endif
+#if defined(MBEDTLS_PEM_PARSE_C)
+#include "mbedtls/pem.h"
+#endif
+#if defined(MBEDTLS_PKCS5_C)
+#include "mbedtls/pkcs5.h"
+#endif
+#if defined(MBEDTLS_PKCS12_C)
+#include "mbedtls/pkcs12.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+/* Parameter validation macros based on platform_util.h */
+#define PK_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
+#define PK_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if defined(MBEDTLS_FS_IO)
+/*
+ * Load all data from a file into a given buffer.
+ *
+ * The file is expected to contain either PEM or DER encoded data.
+ * A terminating null byte is always appended. It is included in the announced
+ * length only if the data looks like it is PEM encoded.
+ */
+int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
+{
+    FILE *f;
+    long size;
+
+    PK_VALIDATE_RET( path != NULL );
+    PK_VALIDATE_RET( buf != NULL );
+    PK_VALIDATE_RET( n != NULL );
+
+    if( ( f = fopen( path, "rb" ) ) == NULL )
+        return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
+
+    fseek( f, 0, SEEK_END );
+    if( ( size = ftell( f ) ) == -1 )
+    {
+        fclose( f );
+        return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
+    }
+    fseek( f, 0, SEEK_SET );
+
+    *n = (size_t) size;
+
+    if( *n + 1 == 0 ||
+        ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
+    {
+        fclose( f );
+        return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+    }
+
+    if( fread( *buf, 1, *n, f ) != *n )
+    {
+        fclose( f );
+
+        mbedtls_platform_zeroize( *buf, *n );
+        mbedtls_free( *buf );
+
+        return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
+    }
+
+    fclose( f );
+
+    (*buf)[*n] = '\0';
+
+    if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
+        ++*n;
+
+    return( 0 );
+}
+
+/*
+ * Load and parse a private key
+ */
+int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
+                      const char *path, const char *pwd )
+{
+    int ret;
+    size_t n;
+    unsigned char *buf;
+
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( path != NULL );
+
+    if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
+
+    if( pwd == NULL )
+        ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 );
+    else
+        ret = mbedtls_pk_parse_key( ctx, buf, n,
+                (const unsigned char *) pwd, strlen( pwd ) );
+
+    mbedtls_platform_zeroize( buf, n );
+    mbedtls_free( buf );
+
+    return( ret );
+}
+
+/*
+ * Load and parse a public key
+ */
+int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
+{
+    int ret;
+    size_t n;
+    unsigned char *buf;
+
+    PK_VALIDATE_RET( ctx != NULL );
+    PK_VALIDATE_RET( path != NULL );
+
+    if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
+
+    ret = mbedtls_pk_parse_public_key( ctx, buf, n );
+
+    mbedtls_platform_zeroize( buf, n );
+    mbedtls_free( buf );
+
+    return( ret );
+}
+#endif /* MBEDTLS_FS_IO */
+
+#if defined(MBEDTLS_ECP_C)
+/* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf
+ *
+ * ECParameters ::= CHOICE {
+ *   namedCurve         OBJECT IDENTIFIER
+ *   specifiedCurve     SpecifiedECDomain -- = SEQUENCE { ... }
+ *   -- implicitCurve   NULL
+ * }
+ */
+static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
+                            mbedtls_asn1_buf *params )
+{
+    int ret;
+
+    if ( end - *p < 1 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    /* Tag may be either OID or SEQUENCE */
+    params->tag = **p;
+    if( params->tag != MBEDTLS_ASN1_OID
+#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
+            && params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE )
+#endif
+            )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+    }
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &params->len, params->tag ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    params->p = *p;
+    *p += params->len;
+
+    if( *p != end )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
+/*
+ * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
+ * WARNING: the resulting group should only be used with
+ * pk_group_id_from_specified(), since its base point may not be set correctly
+ * if it was encoded compressed.
+ *
+ *  SpecifiedECDomain ::= SEQUENCE {
+ *      version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
+ *      fieldID FieldID {{FieldTypes}},
+ *      curve Curve,
+ *      base ECPoint,
+ *      order INTEGER,
+ *      cofactor INTEGER OPTIONAL,
+ *      hash HashAlgorithm OPTIONAL,
+ *      ...
+ *  }
+ *
+ * We only support prime-field as field type, and ignore hash and cofactor.
+ */
+static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
+{
+    int ret;
+    unsigned char *p = params->p;
+    const unsigned char * const end = params->p + params->len;
+    const unsigned char *end_field, *end_curve;
+    size_t len;
+    int ver;
+
+    /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
+    if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    if( ver < 1 || ver > 3 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+
+    /*
+     * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
+     *       fieldType FIELD-ID.&id({IOSet}),
+     *       parameters FIELD-ID.&Type({IOSet}{@fieldType})
+     * }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( ret );
+
+    end_field = p + len;
+
+    /*
+     * FIELD-ID ::= TYPE-IDENTIFIER
+     * FieldTypes FIELD-ID ::= {
+     *       { Prime-p IDENTIFIED BY prime-field } |
+     *       { Characteristic-two IDENTIFIED BY characteristic-two-field }
+     * }
+     * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 )
+        return( ret );
+
+    if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) ||
+        memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+    }
+
+    p += len;
+
+    /* Prime-p ::= INTEGER -- Field of size p. */
+    if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    grp->pbits = mbedtls_mpi_bitlen( &grp->P );
+
+    if( p != end_field )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    /*
+     * Curve ::= SEQUENCE {
+     *       a FieldElement,
+     *       b FieldElement,
+     *       seed BIT STRING OPTIONAL
+     *       -- Shall be present if used in SpecifiedECDomain
+     *       -- with version equal to ecdpVer2 or ecdpVer3
+     * }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( ret );
+
+    end_curve = p + len;
+
+    /*
+     * FieldElement ::= OCTET STRING
+     * containing an integer in the case of a prime field
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
+        ( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    p += len;
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
+        ( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    p += len;
+
+    /* Ignore seed BIT STRING OPTIONAL */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 )
+        p += len;
+
+    if( p != end_curve )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    /*
+     * ECPoint ::= OCTET STRING
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G,
+                                      ( const unsigned char *) p, len ) ) != 0 )
+    {
+        /*
+         * If we can't read the point because it's compressed, cheat by
+         * reading only the X coordinate and the parity bit of Y.
+         */
+        if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ||
+            ( p[0] != 0x02 && p[0] != 0x03 ) ||
+            len != mbedtls_mpi_size( &grp->P ) + 1 ||
+            mbedtls_mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 ||
+            mbedtls_mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 ||
+            mbedtls_mpi_lset( &grp->G.Z, 1 ) != 0 )
+        {
+            return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+        }
+    }
+
+    p += len;
+
+    /*
+     * order INTEGER
+     */
+    if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    grp->nbits = mbedtls_mpi_bitlen( &grp->N );
+
+    /*
+     * Allow optional elements by purposefully not enforcing p == end here.
+     */
+
+    return( 0 );
+}
+
+/*
+ * Find the group id associated with an (almost filled) group as generated by
+ * pk_group_from_specified(), or return an error if unknown.
+ */
+static int pk_group_id_from_group( const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id )
+{
+    int ret = 0;
+    mbedtls_ecp_group ref;
+    const mbedtls_ecp_group_id *id;
+
+    mbedtls_ecp_group_init( &ref );
+
+    for( id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++ )
+    {
+        /* Load the group associated to that id */
+        mbedtls_ecp_group_free( &ref );
+        MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ref, *id ) );
+
+        /* Compare to the group we were given, starting with easy tests */
+        if( grp->pbits == ref.pbits && grp->nbits == ref.nbits &&
+            mbedtls_mpi_cmp_mpi( &grp->P, &ref.P ) == 0 &&
+            mbedtls_mpi_cmp_mpi( &grp->A, &ref.A ) == 0 &&
+            mbedtls_mpi_cmp_mpi( &grp->B, &ref.B ) == 0 &&
+            mbedtls_mpi_cmp_mpi( &grp->N, &ref.N ) == 0 &&
+            mbedtls_mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 &&
+            mbedtls_mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 &&
+            /* For Y we may only know the parity bit, so compare only that */
+            mbedtls_mpi_get_bit( &grp->G.Y, 0 ) == mbedtls_mpi_get_bit( &ref.G.Y, 0 ) )
+        {
+            break;
+        }
+
+    }
+
+cleanup:
+    mbedtls_ecp_group_free( &ref );
+
+    *grp_id = *id;
+
+    if( ret == 0 && *id == MBEDTLS_ECP_DP_NONE )
+        ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+
+    return( ret );
+}
+
+/*
+ * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
+ */
+static int pk_group_id_from_specified( const mbedtls_asn1_buf *params,
+                                       mbedtls_ecp_group_id *grp_id )
+{
+    int ret;
+    mbedtls_ecp_group grp;
+
+    mbedtls_ecp_group_init( &grp );
+
+    if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 )
+        goto cleanup;
+
+    ret = pk_group_id_from_group( &grp, grp_id );
+
+cleanup:
+    mbedtls_ecp_group_free( &grp );
+
+    return( ret );
+}
+#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
+
+/*
+ * Use EC parameters to initialise an EC group
+ *
+ * ECParameters ::= CHOICE {
+ *   namedCurve         OBJECT IDENTIFIER
+ *   specifiedCurve     SpecifiedECDomain -- = SEQUENCE { ... }
+ *   -- implicitCurve   NULL
+ */
+static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
+{
+    int ret;
+    mbedtls_ecp_group_id grp_id;
+
+    if( params->tag == MBEDTLS_ASN1_OID )
+    {
+        if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 )
+            return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE );
+    }
+    else
+    {
+#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
+        if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 )
+            return( ret );
+#else
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+#endif
+    }
+
+    /*
+     * grp may already be initilialized; if so, make sure IDs match
+     */
+    if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+
+    if( ( ret = mbedtls_ecp_group_load( grp, grp_id ) ) != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+/*
+ * EC public key is an EC point
+ *
+ * The caller is responsible for clearing the structure upon failure if
+ * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
+ * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state.
+ */
+static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
+                            mbedtls_ecp_keypair *key )
+{
+    int ret;
+
+    if( ( ret = mbedtls_ecp_point_read_binary( &key->grp, &key->Q,
+                    (const unsigned char *) *p, end - *p ) ) == 0 )
+    {
+        ret = mbedtls_ecp_check_pubkey( &key->grp, &key->Q );
+    }
+
+    /*
+     * We know mbedtls_ecp_point_read_binary consumed all bytes or failed
+     */
+    *p = (unsigned char *) end;
+
+    return( ret );
+}
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_RSA_C)
+/*
+ *  RSAPublicKey ::= SEQUENCE {
+ *      modulus           INTEGER,  -- n
+ *      publicExponent    INTEGER   -- e
+ *  }
+ */
+static int pk_get_rsapubkey( unsigned char **p,
+                             const unsigned char *end,
+                             mbedtls_rsa_context *rsa )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+
+    if( *p + len != end )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    /* Import N */
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+
+    if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0,
+                                        NULL, 0, NULL, 0 ) ) != 0 )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
+
+    *p += len;
+
+    /* Import E */
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+
+    if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
+                                        NULL, 0, *p, len ) ) != 0 )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
+
+    *p += len;
+
+    if( mbedtls_rsa_complete( rsa ) != 0 ||
+        mbedtls_rsa_check_pubkey( rsa ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
+    }
+
+    if( *p != end )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_RSA_C */
+
+/* Get a PK algorithm identifier
+ *
+ *  AlgorithmIdentifier  ::=  SEQUENCE  {
+ *       algorithm               OBJECT IDENTIFIER,
+ *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
+ */
+static int pk_get_pk_alg( unsigned char **p,
+                          const unsigned char *end,
+                          mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params )
+{
+    int ret;
+    mbedtls_asn1_buf alg_oid;
+
+    memset( params, 0, sizeof(mbedtls_asn1_buf) );
+
+    if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
+        return( MBEDTLS_ERR_PK_INVALID_ALG + ret );
+
+    if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
+        return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+
+    /*
+     * No parameters with RSA (only for EC)
+     */
+    if( *pk_alg == MBEDTLS_PK_RSA &&
+            ( ( params->tag != MBEDTLS_ASN1_NULL && params->tag != 0 ) ||
+                params->len != 0 ) )
+    {
+        return( MBEDTLS_ERR_PK_INVALID_ALG );
+    }
+
+    return( 0 );
+}
+
+/*
+ *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
+ *       algorithm            AlgorithmIdentifier,
+ *       subjectPublicKey     BIT STRING }
+ */
+int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
+                        mbedtls_pk_context *pk )
+{
+    int ret;
+    size_t len;
+    mbedtls_asn1_buf alg_params;
+    mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
+    const mbedtls_pk_info_t *pk_info;
+
+    PK_VALIDATE_RET( p != NULL );
+    PK_VALIDATE_RET( *p != NULL );
+    PK_VALIDATE_RET( end != NULL );
+    PK_VALIDATE_RET( pk != NULL );
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    end = *p + len;
+
+    if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+
+    if( *p + len != end )
+        return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
+        return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+
+    if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 )
+        return( ret );
+
+#if defined(MBEDTLS_RSA_C)
+    if( pk_alg == MBEDTLS_PK_RSA )
+    {
+        ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) );
+    } else
+#endif /* MBEDTLS_RSA_C */
+#if defined(MBEDTLS_ECP_C)
+    if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY )
+    {
+        ret = pk_use_ecparams( &alg_params, &mbedtls_pk_ec( *pk )->grp );
+        if( ret == 0 )
+            ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) );
+    } else
+#endif /* MBEDTLS_ECP_C */
+        ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
+
+    if( ret == 0 && *p != end )
+        ret = MBEDTLS_ERR_PK_INVALID_PUBKEY
+              MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+
+    if( ret != 0 )
+        mbedtls_pk_free( pk );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_RSA_C)
+/*
+ * Parse a PKCS#1 encoded private RSA key
+ */
+static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
+                                   const unsigned char *key,
+                                   size_t keylen )
+{
+    int ret, version;
+    size_t len;
+    unsigned char *p, *end;
+
+    mbedtls_mpi T;
+    mbedtls_mpi_init( &T );
+
+    p = (unsigned char *) key;
+    end = p + keylen;
+
+    /*
+     * This function parses the RSAPrivateKey (PKCS#1)
+     *
+     *  RSAPrivateKey ::= SEQUENCE {
+     *      version           Version,
+     *      modulus           INTEGER,  -- n
+     *      publicExponent    INTEGER,  -- e
+     *      privateExponent   INTEGER,  -- d
+     *      prime1            INTEGER,  -- p
+     *      prime2            INTEGER,  -- q
+     *      exponent1         INTEGER,  -- d mod (p-1)
+     *      exponent2         INTEGER,  -- d mod (q-1)
+     *      coefficient       INTEGER,  -- (inverse of q) mod p
+     *      otherPrimeInfos   OtherPrimeInfos OPTIONAL
+     *  }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    end = p + len;
+
+    if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    if( version != 0 )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
+    }
+
+    /* Import N */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
+        ( ret = mbedtls_rsa_import_raw( rsa, p, len, NULL, 0, NULL, 0,
+                                        NULL, 0, NULL, 0 ) ) != 0 )
+        goto cleanup;
+    p += len;
+
+    /* Import E */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
+        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
+                                        NULL, 0, p, len ) ) != 0 )
+        goto cleanup;
+    p += len;
+
+    /* Import D */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
+        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
+                                        p, len, NULL, 0 ) ) != 0 )
+        goto cleanup;
+    p += len;
+
+    /* Import P */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
+        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, p, len, NULL, 0,
+                                        NULL, 0, NULL, 0 ) ) != 0 )
+        goto cleanup;
+    p += len;
+
+    /* Import Q */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ) ) != 0 ||
+        ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, p, len,
+                                        NULL, 0, NULL, 0 ) ) != 0 )
+        goto cleanup;
+    p += len;
+
+    /* Complete the RSA private key */
+    if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 )
+        goto cleanup;
+
+    /* Check optional parameters */
+    if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
+        ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 )
+        goto cleanup;
+
+    if( p != end )
+    {
+        ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
+              MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ;
+    }
+
+cleanup:
+
+    mbedtls_mpi_free( &T );
+
+    if( ret != 0 )
+    {
+        /* Wrap error code if it's coming from a lower level */
+        if( ( ret & 0xff80 ) == 0 )
+            ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret;
+        else
+            ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
+
+        mbedtls_rsa_free( rsa );
+    }
+
+    return( ret );
+}
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_ECP_C)
+/*
+ * Parse a SEC1 encoded private EC key
+ */
+static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
+                                  const unsigned char *key,
+                                  size_t keylen )
+{
+    int ret;
+    int version, pubkey_done;
+    size_t len;
+    mbedtls_asn1_buf params;
+    unsigned char *p = (unsigned char *) key;
+    unsigned char *end = p + keylen;
+    unsigned char *end2;
+
+    /*
+     * RFC 5915, or SEC1 Appendix C.4
+     *
+     * ECPrivateKey ::= SEQUENCE {
+     *      version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
+     *      privateKey     OCTET STRING,
+     *      parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
+     *      publicKey  [1] BIT STRING OPTIONAL
+     *    }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    end = p + len;
+
+    if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    if( version != 1 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 )
+    {
+        mbedtls_ecp_keypair_free( eck );
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    p += len;
+
+    pubkey_done = 0;
+    if( p != end )
+    {
+        /*
+         * Is 'parameters' present?
+         */
+        if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                        MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
+        {
+            if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
+                ( ret = pk_use_ecparams( &params, &eck->grp )  ) != 0 )
+            {
+                mbedtls_ecp_keypair_free( eck );
+                return( ret );
+            }
+        }
+        else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+        {
+            mbedtls_ecp_keypair_free( eck );
+            return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+        }
+    }
+
+    if( p != end )
+    {
+        /*
+         * Is 'publickey' present? If not, or if we can't read it (eg because it
+         * is compressed), create it from the private key.
+         */
+        if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                        MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
+        {
+            end2 = p + len;
+
+            if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
+                return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+            if( p + len != end2 )
+                return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
+                        MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+            if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
+                pubkey_done = 1;
+            else
+            {
+                /*
+                 * The only acceptable failure mode of pk_get_ecpubkey() above
+                 * is if the point format is not recognized.
+                 */
+                if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE )
+                    return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+            }
+        }
+        else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+        {
+            mbedtls_ecp_keypair_free( eck );
+            return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+        }
+    }
+
+    if( ! pubkey_done &&
+        ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
+                                                      NULL, NULL ) ) != 0 )
+    {
+        mbedtls_ecp_keypair_free( eck );
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
+    {
+        mbedtls_ecp_keypair_free( eck );
+        return( ret );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ECP_C */
+
+/*
+ * Parse an unencrypted PKCS#8 encoded private key
+ *
+ * Notes:
+ *
+ * - This function does not own the key buffer. It is the
+ *   responsibility of the caller to take care of zeroizing
+ *   and freeing it after use.
+ *
+ * - The function is responsible for freeing the provided
+ *   PK context on failure.
+ *
+ */
+static int pk_parse_key_pkcs8_unencrypted_der(
+                                    mbedtls_pk_context *pk,
+                                    const unsigned char* key,
+                                    size_t keylen )
+{
+    int ret, version;
+    size_t len;
+    mbedtls_asn1_buf params;
+    unsigned char *p = (unsigned char *) key;
+    unsigned char *end = p + keylen;
+    mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
+    const mbedtls_pk_info_t *pk_info;
+
+    /*
+     * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208)
+     *
+     *    PrivateKeyInfo ::= SEQUENCE {
+     *      version                   Version,
+     *      privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
+     *      privateKey                PrivateKey,
+     *      attributes           [0]  IMPLICIT Attributes OPTIONAL }
+     *
+     *    Version ::= INTEGER
+     *    PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+     *    PrivateKey ::= OCTET STRING
+     *
+     *  The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
+     */
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    end = p + len;
+
+    if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    if( version != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret );
+
+    if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    if( len < 1 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
+        return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+
+    if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 )
+        return( ret );
+
+#if defined(MBEDTLS_RSA_C)
+    if( pk_alg == MBEDTLS_PK_RSA )
+    {
+        if( ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), p, len ) ) != 0 )
+        {
+            mbedtls_pk_free( pk );
+            return( ret );
+        }
+    } else
+#endif /* MBEDTLS_RSA_C */
+#if defined(MBEDTLS_ECP_C)
+    if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH )
+    {
+        if( ( ret = pk_use_ecparams( &params, &mbedtls_pk_ec( *pk )->grp ) ) != 0 ||
+            ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len )  ) != 0 )
+        {
+            mbedtls_pk_free( pk );
+            return( ret );
+        }
+    } else
+#endif /* MBEDTLS_ECP_C */
+        return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+
+    return( 0 );
+}
+
+/*
+ * Parse an encrypted PKCS#8 encoded private key
+ *
+ * To save space, the decryption happens in-place on the given key buffer.
+ * Also, while this function may modify the keybuffer, it doesn't own it,
+ * and instead it is the responsibility of the caller to zeroize and properly
+ * free it after use.
+ *
+ */
+#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
+static int pk_parse_key_pkcs8_encrypted_der(
+                                    mbedtls_pk_context *pk,
+                                    unsigned char *key, size_t keylen,
+                                    const unsigned char *pwd, size_t pwdlen )
+{
+    int ret, decrypted = 0;
+    size_t len;
+    unsigned char *buf;
+    unsigned char *p, *end;
+    mbedtls_asn1_buf pbe_alg_oid, pbe_params;
+#if defined(MBEDTLS_PKCS12_C)
+    mbedtls_cipher_type_t cipher_alg;
+    mbedtls_md_type_t md_alg;
+#endif
+
+    p = key;
+    end = p + keylen;
+
+    if( pwdlen == 0 )
+        return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
+
+    /*
+     * This function parses the EncryptedPrivateKeyInfo object (PKCS#8)
+     *
+     *  EncryptedPrivateKeyInfo ::= SEQUENCE {
+     *    encryptionAlgorithm  EncryptionAlgorithmIdentifier,
+     *    encryptedData        EncryptedData
+     *  }
+     *
+     *  EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+     *
+     *  EncryptedData ::= OCTET STRING
+     *
+     *  The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
+     *
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+    }
+
+    end = p + len;
+
+    if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+
+    buf = p;
+
+    /*
+     * Decrypt EncryptedData with appropriate PBE
+     */
+#if defined(MBEDTLS_PKCS12_C)
+    if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
+    {
+        if( ( ret = mbedtls_pkcs12_pbe( &pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT,
+                                cipher_alg, md_alg,
+                                pwd, pwdlen, p, len, buf ) ) != 0 )
+        {
+            if( ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH )
+                return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
+
+            return( ret );
+        }
+
+        decrypted = 1;
+    }
+    else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) == 0 )
+    {
+        if( ( ret = mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params,
+                                             MBEDTLS_PKCS12_PBE_DECRYPT,
+                                             pwd, pwdlen,
+                                             p, len, buf ) ) != 0 )
+        {
+            return( ret );
+        }
+
+        // Best guess for password mismatch when using RC4. If first tag is
+        // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
+        //
+        if( *buf != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+            return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
+
+        decrypted = 1;
+    }
+    else
+#endif /* MBEDTLS_PKCS12_C */
+#if defined(MBEDTLS_PKCS5_C)
+    if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid ) == 0 )
+    {
+        if( ( ret = mbedtls_pkcs5_pbes2( &pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen,
+                                  p, len, buf ) ) != 0 )
+        {
+            if( ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH )
+                return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
+
+            return( ret );
+        }
+
+        decrypted = 1;
+    }
+    else
+#endif /* MBEDTLS_PKCS5_C */
+    {
+        ((void) pwd);
+    }
+
+    if( decrypted == 0 )
+        return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
+    return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
+}
+#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
+
+/*
+ * Parse a private key
+ */
+int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
+                  const unsigned char *key, size_t keylen,
+                  const unsigned char *pwd, size_t pwdlen )
+{
+    int ret;
+    const mbedtls_pk_info_t *pk_info;
+#if defined(MBEDTLS_PEM_PARSE_C)
+    size_t len;
+    mbedtls_pem_context pem;
+#endif
+
+    PK_VALIDATE_RET( pk != NULL );
+    if( keylen == 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+    PK_VALIDATE_RET( key != NULL );
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+   mbedtls_pem_init( &pem );
+
+#if defined(MBEDTLS_RSA_C)
+    /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
+    if( key[keylen - 1] != '\0' )
+        ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+    else
+        ret = mbedtls_pem_read_buffer( &pem,
+                               "-----BEGIN RSA PRIVATE KEY-----",
+                               "-----END RSA PRIVATE KEY-----",
+                               key, pwd, pwdlen, &len );
+
+    if( ret == 0 )
+    {
+        pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
+        if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
+            ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ),
+                                            pem.buf, pem.buflen ) ) != 0 )
+        {
+            mbedtls_pk_free( pk );
+        }
+
+        mbedtls_pem_free( &pem );
+        return( ret );
+    }
+    else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH )
+        return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
+    else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED )
+        return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
+    else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+        return( ret );
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_ECP_C)
+    /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
+    if( key[keylen - 1] != '\0' )
+        ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+    else
+        ret = mbedtls_pem_read_buffer( &pem,
+                               "-----BEGIN EC PRIVATE KEY-----",
+                               "-----END EC PRIVATE KEY-----",
+                               key, pwd, pwdlen, &len );
+    if( ret == 0 )
+    {
+        pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
+
+        if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
+            ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
+                                           pem.buf, pem.buflen ) ) != 0 )
+        {
+            mbedtls_pk_free( pk );
+        }
+
+        mbedtls_pem_free( &pem );
+        return( ret );
+    }
+    else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH )
+        return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
+    else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED )
+        return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
+    else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+        return( ret );
+#endif /* MBEDTLS_ECP_C */
+
+    /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
+    if( key[keylen - 1] != '\0' )
+        ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+    else
+        ret = mbedtls_pem_read_buffer( &pem,
+                               "-----BEGIN PRIVATE KEY-----",
+                               "-----END PRIVATE KEY-----",
+                               key, NULL, 0, &len );
+    if( ret == 0 )
+    {
+        if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
+                                                pem.buf, pem.buflen ) ) != 0 )
+        {
+            mbedtls_pk_free( pk );
+        }
+
+        mbedtls_pem_free( &pem );
+        return( ret );
+    }
+    else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+        return( ret );
+
+#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
+    /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
+    if( key[keylen - 1] != '\0' )
+        ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+    else
+        ret = mbedtls_pem_read_buffer( &pem,
+                               "-----BEGIN ENCRYPTED PRIVATE KEY-----",
+                               "-----END ENCRYPTED PRIVATE KEY-----",
+                               key, NULL, 0, &len );
+    if( ret == 0 )
+    {
+        if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
+                                                      pem.buf, pem.buflen,
+                                                      pwd, pwdlen ) ) != 0 )
+        {
+            mbedtls_pk_free( pk );
+        }
+
+        mbedtls_pem_free( &pem );
+        return( ret );
+    }
+    else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+        return( ret );
+#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
+#else
+    ((void) pwd);
+    ((void) pwdlen);
+#endif /* MBEDTLS_PEM_PARSE_C */
+
+    /*
+     * At this point we only know it's not a PEM formatted key. Could be any
+     * of the known DER encoded private key formats
+     *
+     * We try the different DER format parsers to see if one passes without
+     * error
+     */
+#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
+    {
+        unsigned char *key_copy;
+
+        if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL )
+            return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+
+        memcpy( key_copy, key, keylen );
+
+        ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
+                                                pwd, pwdlen );
+
+        mbedtls_platform_zeroize( key_copy, keylen );
+        mbedtls_free( key_copy );
+    }
+
+    if( ret == 0 )
+        return( 0 );
+
+    mbedtls_pk_free( pk );
+    mbedtls_pk_init( pk );
+
+    if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH )
+    {
+        return( ret );
+    }
+#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
+
+    if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
+        return( 0 );
+
+    mbedtls_pk_free( pk );
+    mbedtls_pk_init( pk );
+
+#if defined(MBEDTLS_RSA_C)
+
+    pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
+    if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
+        pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) == 0 )
+    {
+        return( 0 );
+    }
+
+    mbedtls_pk_free( pk );
+    mbedtls_pk_init( pk );
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_ECP_C)
+    pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
+    if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
+        pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
+                               key, keylen ) == 0 )
+    {
+        return( 0 );
+    }
+    mbedtls_pk_free( pk );
+#endif /* MBEDTLS_ECP_C */
+
+    /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
+     * it is ok to leave the PK context initialized but not
+     * freed: It is the caller's responsibility to call pk_init()
+     * before calling this function, and to call pk_free()
+     * when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C
+     * isn't, this leads to mbedtls_pk_free() being called
+     * twice, once here and once by the caller, but this is
+     * also ok and in line with the mbedtls_pk_free() calls
+     * on failed PEM parsing attempts. */
+
+    return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+}
+
+/*
+ * Parse a public key
+ */
+int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
+                         const unsigned char *key, size_t keylen )
+{
+    int ret;
+    unsigned char *p;
+#if defined(MBEDTLS_RSA_C)
+    const mbedtls_pk_info_t *pk_info;
+#endif
+#if defined(MBEDTLS_PEM_PARSE_C)
+    size_t len;
+    mbedtls_pem_context pem;
+#endif
+
+    PK_VALIDATE_RET( ctx != NULL );
+    if( keylen == 0 )
+        return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
+    PK_VALIDATE_RET( key != NULL || keylen == 0 );
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+    mbedtls_pem_init( &pem );
+#if defined(MBEDTLS_RSA_C)
+    /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
+    if( key[keylen - 1] != '\0' )
+        ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+    else
+        ret = mbedtls_pem_read_buffer( &pem,
+                               "-----BEGIN RSA PUBLIC KEY-----",
+                               "-----END RSA PUBLIC KEY-----",
+                               key, NULL, 0, &len );
+
+    if( ret == 0 )
+    {
+        p = pem.buf;
+        if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
+            return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+
+        if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
+            return( ret );
+
+        if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 )
+            mbedtls_pk_free( ctx );
+
+        mbedtls_pem_free( &pem );
+        return( ret );
+    }
+    else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+    {
+        mbedtls_pem_free( &pem );
+        return( ret );
+    }
+#endif /* MBEDTLS_RSA_C */
+
+    /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
+    if( key[keylen - 1] != '\0' )
+        ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+    else
+        ret = mbedtls_pem_read_buffer( &pem,
+                "-----BEGIN PUBLIC KEY-----",
+                "-----END PUBLIC KEY-----",
+                key, NULL, 0, &len );
+
+    if( ret == 0 )
+    {
+        /*
+         * Was PEM encoded
+         */
+        p = pem.buf;
+
+        ret = mbedtls_pk_parse_subpubkey( &p,  p + pem.buflen, ctx );
+        mbedtls_pem_free( &pem );
+        return( ret );
+    }
+    else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+    {
+        mbedtls_pem_free( &pem );
+        return( ret );
+    }
+    mbedtls_pem_free( &pem );
+#endif /* MBEDTLS_PEM_PARSE_C */
+
+#if defined(MBEDTLS_RSA_C)
+    if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
+        return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
+
+    if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
+        return( ret );
+
+    p = (unsigned char *)key;
+    ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) );
+    if( ret == 0 )
+    {
+        return( ret );
+    }
+    mbedtls_pk_free( ctx );
+    if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
+    {
+        return( ret );
+    }
+#endif /* MBEDTLS_RSA_C */
+    p = (unsigned char *) key;
+
+    ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_PK_PARSE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkwrite.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkwrite.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/pkwrite.c	(revision 398)
@@ -0,0 +1,545 @@
+/*
+ *  Public Key layer for writing key files and structures
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PK_WRITE_C)
+
+#include "mbedtls/pk.h"
+#include "mbedtls/asn1write.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_RSA_C)
+#include "mbedtls/rsa.h"
+#endif
+#if defined(MBEDTLS_ECP_C)
+#include "mbedtls/ecp.h"
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+#include "mbedtls/ecdsa.h"
+#endif
+#if defined(MBEDTLS_PEM_WRITE_C)
+#include "mbedtls/pem.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+/* Parameter validation macros based on platform_util.h */
+#define PK_VALIDATE_RET( cond )    \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
+#define PK_VALIDATE( cond )        \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if defined(MBEDTLS_RSA_C)
+/*
+ *  RSAPublicKey ::= SEQUENCE {
+ *      modulus           INTEGER,  -- n
+ *      publicExponent    INTEGER   -- e
+ *  }
+ */
+static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
+                                mbedtls_rsa_context *rsa )
+{
+    int ret;
+    size_t len = 0;
+    mbedtls_mpi T;
+
+    mbedtls_mpi_init( &T );
+
+    /* Export E */
+    if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &T ) ) != 0 ||
+         ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 )
+        goto end_of_export;
+    len += ret;
+
+    /* Export N */
+    if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, NULL, NULL, NULL ) ) != 0 ||
+         ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 )
+        goto end_of_export;
+    len += ret;
+
+end_of_export:
+
+    mbedtls_mpi_free( &T );
+    if( ret < 0 )
+        return( ret );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
+                                                 MBEDTLS_ASN1_SEQUENCE ) );
+
+    return( (int) len );
+}
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_ECP_C)
+/*
+ * EC public key is an EC point
+ */
+static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
+                               mbedtls_ecp_keypair *ec )
+{
+    int ret;
+    size_t len = 0;
+    unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
+
+    if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q,
+                                        MBEDTLS_ECP_PF_UNCOMPRESSED,
+                                        &len, buf, sizeof( buf ) ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( *p < start || (size_t)( *p - start ) < len )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    *p -= len;
+    memcpy( *p, buf, len );
+
+    return( (int) len );
+}
+
+/*
+ * ECParameters ::= CHOICE {
+ *   namedCurve         OBJECT IDENTIFIER
+ * }
+ */
+static int pk_write_ec_param( unsigned char **p, unsigned char *start,
+                              mbedtls_ecp_keypair *ec )
+{
+    int ret;
+    size_t len = 0;
+    const char *oid;
+    size_t oid_len;
+
+    if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
+        return( ret );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
+
+    return( (int) len );
+}
+#endif /* MBEDTLS_ECP_C */
+
+int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
+                             const mbedtls_pk_context *key )
+{
+    int ret;
+    size_t len = 0;
+
+    PK_VALIDATE_RET( p != NULL );
+    PK_VALIDATE_RET( *p != NULL );
+    PK_VALIDATE_RET( start != NULL );
+    PK_VALIDATE_RET( key != NULL );
+
+#if defined(MBEDTLS_RSA_C)
+    if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
+        MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) );
+    else
+#endif
+#if defined(MBEDTLS_ECP_C)
+    if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
+        MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) );
+    else
+#endif
+        return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
+    return( (int) len );
+}
+
+int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
+{
+    int ret;
+    unsigned char *c;
+    size_t len = 0, par_len = 0, oid_len;
+    const char *oid;
+
+    PK_VALIDATE_RET( key != NULL );
+    if( size == 0 )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+    PK_VALIDATE_RET( buf != NULL );
+
+    c = buf + size;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
+
+    if( c - buf < 1 )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    /*
+     *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
+     *       algorithm            AlgorithmIdentifier,
+     *       subjectPublicKey     BIT STRING }
+     */
+    *--c = 0;
+    len += 1;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
+
+    if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ),
+                                       &oid, &oid_len ) ) != 0 )
+    {
+        return( ret );
+    }
+
+#if defined(MBEDTLS_ECP_C)
+    if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
+    {
+        MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) );
+    }
+#endif
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
+                                                        par_len ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                MBEDTLS_ASN1_SEQUENCE ) );
+
+    return( (int) len );
+}
+
+int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
+{
+    int ret;
+    unsigned char *c;
+    size_t len = 0;
+
+    PK_VALIDATE_RET( key != NULL );
+    if( size == 0 )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+    PK_VALIDATE_RET( buf != NULL );
+
+    c = buf + size;
+
+#if defined(MBEDTLS_RSA_C)
+    if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
+    {
+        mbedtls_mpi T; /* Temporary holding the exported parameters */
+        mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key );
+
+        /*
+         * Export the parameters one after another to avoid simultaneous copies.
+         */
+
+        mbedtls_mpi_init( &T );
+
+        /* Export QP */
+        if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, NULL, &T ) ) != 0 ||
+            ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export DQ */
+        if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, &T, NULL ) ) != 0 ||
+            ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export DP */
+        if( ( ret = mbedtls_rsa_export_crt( rsa, &T, NULL, NULL ) ) != 0 ||
+            ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export Q */
+        if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
+                                         &T, NULL, NULL ) ) != 0 ||
+             ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export P */
+        if ( ( ret = mbedtls_rsa_export( rsa, NULL, &T,
+                                         NULL, NULL, NULL ) ) != 0 ||
+             ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export D */
+        if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
+                                         NULL, &T, NULL ) ) != 0 ||
+             ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export E */
+        if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
+                                         NULL, NULL, &T ) ) != 0 ||
+             ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+        /* Export N */
+        if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL,
+                                         NULL, NULL, NULL ) ) != 0 ||
+             ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
+            goto end_of_export;
+        len += ret;
+
+    end_of_export:
+
+        mbedtls_mpi_free( &T );
+        if( ret < 0 )
+            return( ret );
+
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c,
+                                               buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                               MBEDTLS_ASN1_SEQUENCE ) );
+    }
+    else
+#endif /* MBEDTLS_RSA_C */
+#if defined(MBEDTLS_ECP_C)
+    if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
+    {
+        mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key );
+        size_t pub_len = 0, par_len = 0;
+
+        /*
+         * RFC 5915, or SEC1 Appendix C.4
+         *
+         * ECPrivateKey ::= SEQUENCE {
+         *      version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
+         *      privateKey     OCTET STRING,
+         *      parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
+         *      publicKey  [1] BIT STRING OPTIONAL
+         *    }
+         */
+
+        /* publicKey */
+        MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) );
+
+        if( c - buf < 1 )
+            return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+        *--c = 0;
+        pub_len += 1;
+
+        MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) );
+        MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
+
+        MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) );
+        MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf,
+                            MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) );
+        len += pub_len;
+
+        /* parameters */
+        MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) );
+
+        MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) );
+        MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf,
+                            MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
+        len += par_len;
+
+        /* privateKey: write as MPI then fix tag */
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) );
+        *c = MBEDTLS_ASN1_OCTET_STRING;
+
+        /* version */
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) );
+
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                    MBEDTLS_ASN1_SEQUENCE ) );
+    }
+    else
+#endif /* MBEDTLS_ECP_C */
+        return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
+    return( (int) len );
+}
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+
+#define PEM_BEGIN_PUBLIC_KEY    "-----BEGIN PUBLIC KEY-----\n"
+#define PEM_END_PUBLIC_KEY      "-----END PUBLIC KEY-----\n"
+
+#define PEM_BEGIN_PRIVATE_KEY_RSA   "-----BEGIN RSA PRIVATE KEY-----\n"
+#define PEM_END_PRIVATE_KEY_RSA     "-----END RSA PRIVATE KEY-----\n"
+#define PEM_BEGIN_PRIVATE_KEY_EC    "-----BEGIN EC PRIVATE KEY-----\n"
+#define PEM_END_PRIVATE_KEY_EC      "-----END EC PRIVATE KEY-----\n"
+
+/*
+ * Max sizes of key per types. Shown as tag + len (+ content).
+ */
+
+#if defined(MBEDTLS_RSA_C)
+/*
+ * RSA public keys:
+ *  SubjectPublicKeyInfo  ::=  SEQUENCE  {          1 + 3
+ *       algorithm            AlgorithmIdentifier,  1 + 1 (sequence)
+ *                                                + 1 + 1 + 9 (rsa oid)
+ *                                                + 1 + 1 (params null)
+ *       subjectPublicKey     BIT STRING }          1 + 3 + (1 + below)
+ *  RSAPublicKey ::= SEQUENCE {                     1 + 3
+ *      modulus           INTEGER,  -- n            1 + 3 + MPI_MAX + 1
+ *      publicExponent    INTEGER   -- e            1 + 3 + MPI_MAX + 1
+ *  }
+ */
+#define RSA_PUB_DER_MAX_BYTES   38 + 2 * MBEDTLS_MPI_MAX_SIZE
+
+/*
+ * RSA private keys:
+ *  RSAPrivateKey ::= SEQUENCE {                    1 + 3
+ *      version           Version,                  1 + 1 + 1
+ *      modulus           INTEGER,                  1 + 3 + MPI_MAX + 1
+ *      publicExponent    INTEGER,                  1 + 3 + MPI_MAX + 1
+ *      privateExponent   INTEGER,                  1 + 3 + MPI_MAX + 1
+ *      prime1            INTEGER,                  1 + 3 + MPI_MAX / 2 + 1
+ *      prime2            INTEGER,                  1 + 3 + MPI_MAX / 2 + 1
+ *      exponent1         INTEGER,                  1 + 3 + MPI_MAX / 2 + 1
+ *      exponent2         INTEGER,                  1 + 3 + MPI_MAX / 2 + 1
+ *      coefficient       INTEGER,                  1 + 3 + MPI_MAX / 2 + 1
+ *      otherPrimeInfos   OtherPrimeInfos OPTIONAL  0 (not supported)
+ *  }
+ */
+#define MPI_MAX_SIZE_2          MBEDTLS_MPI_MAX_SIZE / 2 + \
+                                MBEDTLS_MPI_MAX_SIZE % 2
+#define RSA_PRV_DER_MAX_BYTES   47 + 3 * MBEDTLS_MPI_MAX_SIZE \
+                                   + 5 * MPI_MAX_SIZE_2
+
+#else /* MBEDTLS_RSA_C */
+
+#define RSA_PUB_DER_MAX_BYTES   0
+#define RSA_PRV_DER_MAX_BYTES   0
+
+#endif /* MBEDTLS_RSA_C */
+
+#if defined(MBEDTLS_ECP_C)
+/*
+ * EC public keys:
+ *  SubjectPublicKeyInfo  ::=  SEQUENCE  {      1 + 2
+ *    algorithm         AlgorithmIdentifier,    1 + 1 (sequence)
+ *                                            + 1 + 1 + 7 (ec oid)
+ *                                            + 1 + 1 + 9 (namedCurve oid)
+ *    subjectPublicKey  BIT STRING              1 + 2 + 1               [1]
+ *                                            + 1 (point format)        [1]
+ *                                            + 2 * ECP_MAX (coords)    [1]
+ *  }
+ */
+#define ECP_PUB_DER_MAX_BYTES   30 + 2 * MBEDTLS_ECP_MAX_BYTES
+
+/*
+ * EC private keys:
+ * ECPrivateKey ::= SEQUENCE {                  1 + 2
+ *      version        INTEGER ,                1 + 1 + 1
+ *      privateKey     OCTET STRING,            1 + 1 + ECP_MAX
+ *      parameters [0] ECParameters OPTIONAL,   1 + 1 + (1 + 1 + 9)
+ *      publicKey  [1] BIT STRING OPTIONAL      1 + 2 + [1] above
+ *    }
+ */
+#define ECP_PRV_DER_MAX_BYTES   29 + 3 * MBEDTLS_ECP_MAX_BYTES
+
+#else /* MBEDTLS_ECP_C */
+
+#define ECP_PUB_DER_MAX_BYTES   0
+#define ECP_PRV_DER_MAX_BYTES   0
+
+#endif /* MBEDTLS_ECP_C */
+
+#define PUB_DER_MAX_BYTES   RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
+                            RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
+#define PRV_DER_MAX_BYTES   RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
+                            RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
+
+int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
+{
+    int ret;
+    unsigned char output_buf[PUB_DER_MAX_BYTES];
+    size_t olen = 0;
+
+    PK_VALIDATE_RET( key != NULL );
+    PK_VALIDATE_RET( buf != NULL || size == 0 );
+
+    if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf,
+                                     sizeof(output_buf) ) ) < 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
+                                  output_buf + sizeof(output_buf) - ret,
+                                  ret, buf, size, &olen ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
+{
+    int ret;
+    unsigned char output_buf[PRV_DER_MAX_BYTES];
+    const char *begin, *end;
+    size_t olen = 0;
+
+    PK_VALIDATE_RET( key != NULL );
+    PK_VALIDATE_RET( buf != NULL || size == 0 );
+
+    if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
+        return( ret );
+
+#if defined(MBEDTLS_RSA_C)
+    if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
+    {
+        begin = PEM_BEGIN_PRIVATE_KEY_RSA;
+        end = PEM_END_PRIVATE_KEY_RSA;
+    }
+    else
+#endif
+#if defined(MBEDTLS_ECP_C)
+    if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
+    {
+        begin = PEM_BEGIN_PRIVATE_KEY_EC;
+        end = PEM_END_PRIVATE_KEY_EC;
+    }
+    else
+#endif
+        return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
+    if( ( ret = mbedtls_pem_write_buffer( begin, end,
+                                  output_buf + sizeof(output_buf) - ret,
+                                  ret, buf, size, &olen ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_PEM_WRITE_C */
+
+#endif /* MBEDTLS_PK_WRITE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/platform.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/platform.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/platform.c	(revision 398)
@@ -0,0 +1,348 @@
+/*
+ *  Platform abstraction layer
+ *
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+
+#include "mbedtls/platform.h"
+#include "mbedtls/platform_util.h"
+
+/* The compile time configuration of memory allocation via the macros
+ * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime
+ * configuration via mbedtls_platform_set_calloc_free(). So, omit everything
+ * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */
+#if defined(MBEDTLS_PLATFORM_MEMORY) &&                 \
+    !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&        \
+       defined(MBEDTLS_PLATFORM_FREE_MACRO) )
+
+#if !defined(MBEDTLS_PLATFORM_STD_CALLOC)
+static void *platform_calloc_uninit( size_t n, size_t size )
+{
+    ((void) n);
+    ((void) size);
+    return( NULL );
+}
+
+#define MBEDTLS_PLATFORM_STD_CALLOC   platform_calloc_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */
+
+#if !defined(MBEDTLS_PLATFORM_STD_FREE)
+static void platform_free_uninit( void *ptr )
+{
+    ((void) ptr);
+}
+
+#define MBEDTLS_PLATFORM_STD_FREE     platform_free_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_FREE */
+
+static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC;
+static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE;
+
+void * mbedtls_calloc( size_t nmemb, size_t size )
+{
+    return (*mbedtls_calloc_func)( nmemb, size );
+}
+
+void mbedtls_free( void * ptr )
+{
+    (*mbedtls_free_func)( ptr );
+}
+
+int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
+                              void (*free_func)( void * ) )
+{
+    mbedtls_calloc_func = calloc_func;
+    mbedtls_free_func = free_func;
+    return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_MEMORY &&
+          !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&
+             defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */
+
+#if defined(_WIN32)
+#include <stdarg.h>
+int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... )
+{
+    int ret;
+    va_list argp;
+
+    /* Avoid calling the invalid parameter handler by checking ourselves */
+    if( s == NULL || n == 0 || fmt == NULL )
+        return( -1 );
+
+    va_start( argp, fmt );
+#if defined(_TRUNCATE) && !defined(__MINGW32__)
+    ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp );
+#else
+    ret = _vsnprintf( s, n, fmt, argp );
+    if( ret < 0 || (size_t) ret == n )
+    {
+        s[n-1] = '\0';
+        ret = -1;
+    }
+#endif
+    va_end( argp );
+
+    return( ret );
+}
+#endif
+
+#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_snprintf_uninit( char * s, size_t n,
+                                     const char * format, ... )
+{
+    ((void) s);
+    ((void) n);
+    ((void) format);
+    return( 0 );
+}
+
+#define MBEDTLS_PLATFORM_STD_SNPRINTF    platform_snprintf_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */
+
+int (*mbedtls_snprintf)( char * s, size_t n,
+                          const char * format,
+                          ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF;
+
+int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
+                                                 const char * format,
+                                                 ... ) )
+{
+    mbedtls_snprintf = snprintf_func;
+    return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+
+#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_printf_uninit( const char *format, ... )
+{
+    ((void) format);
+    return( 0 );
+}
+
+#define MBEDTLS_PLATFORM_STD_PRINTF    platform_printf_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */
+
+int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF;
+
+int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) )
+{
+    mbedtls_printf = printf_func;
+    return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
+
+#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_fprintf_uninit( FILE *stream, const char *format, ... )
+{
+    ((void) stream);
+    ((void) format);
+    return( 0 );
+}
+
+#define MBEDTLS_PLATFORM_STD_FPRINTF   platform_fprintf_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */
+
+int (*mbedtls_fprintf)( FILE *, const char *, ... ) =
+                                        MBEDTLS_PLATFORM_STD_FPRINTF;
+
+int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) )
+{
+    mbedtls_fprintf = fprintf_func;
+    return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
+
+#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_EXIT)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static void platform_exit_uninit( int status )
+{
+    ((void) status);
+}
+
+#define MBEDTLS_PLATFORM_STD_EXIT   platform_exit_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_EXIT */
+
+void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT;
+
+int mbedtls_platform_set_exit( void (*exit_func)( int status ) )
+{
+    mbedtls_exit = exit_func;
+    return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
+
+#if defined(MBEDTLS_HAVE_TIME)
+
+#if defined(MBEDTLS_PLATFORM_TIME_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_TIME)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer )
+{
+    ((void) timer);
+    return( 0 );
+}
+
+#define MBEDTLS_PLATFORM_STD_TIME   platform_time_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_TIME */
+
+mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME;
+
+int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) )
+{
+    mbedtls_time = time_func;
+    return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_TIME_ALT */
+
+#endif /* MBEDTLS_HAVE_TIME */
+
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO)
+/* Default implementations for the platform independent seed functions use
+ * standard libc file functions to read from and write to a pre-defined filename
+ */
+int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len )
+{
+    FILE *file;
+    size_t n;
+
+    if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
+        return( -1 );
+
+    if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len )
+    {
+        fclose( file );
+        mbedtls_platform_zeroize( buf, buf_len );
+        return( -1 );
+    }
+
+    fclose( file );
+    return( (int)n );
+}
+
+int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len )
+{
+    FILE *file;
+    size_t n;
+
+    if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
+        return -1;
+
+    if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len )
+    {
+        fclose( file );
+        return -1;
+    }
+
+    fclose( file );
+    return( (int)n );
+}
+#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
+
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len )
+{
+    ((void) buf);
+    ((void) buf_len);
+    return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   platform_nv_seed_read_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */
+
+#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len )
+{
+    ((void) buf);
+    ((void) buf_len);
+    return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE   platform_nv_seed_write_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */
+
+int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) =
+            MBEDTLS_PLATFORM_STD_NV_SEED_READ;
+int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) =
+            MBEDTLS_PLATFORM_STD_NV_SEED_WRITE;
+
+int mbedtls_platform_set_nv_seed(
+        int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ),
+        int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) )
+{
+    mbedtls_nv_seed_read = nv_seed_read_func;
+    mbedtls_nv_seed_write = nv_seed_write_func;
+    return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+
+#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
+/*
+ * Placeholder platform setup that does nothing by default
+ */
+int mbedtls_platform_setup( mbedtls_platform_context *ctx )
+{
+    (void)ctx;
+
+    return( 0 );
+}
+
+/*
+ * Placeholder platform teardown that does nothing by default
+ */
+void mbedtls_platform_teardown( mbedtls_platform_context *ctx )
+{
+    (void)ctx;
+}
+#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
+
+#endif /* MBEDTLS_PLATFORM_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/platform_util.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/platform_util.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/platform_util.c	(revision 398)
@@ -0,0 +1,136 @@
+/*
+ * Common and shared functions used by multiple modules in the Mbed TLS
+ * library.
+ *
+ *  Copyright (C) 2018, Arm Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * Ensure gmtime_r is available even with -std=c99; must be defined before
+ * config.h, which pulls in glibc's features.h. Harmless on other platforms.
+ */
+#if !defined(_POSIX_C_SOURCE)
+#define _POSIX_C_SOURCE 200112L
+#endif
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "mbedtls/platform_util.h"
+#include "mbedtls/platform.h"
+#include "mbedtls/threading.h"
+
+#include <stddef.h>
+#include <string.h>
+
+#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
+/*
+ * This implementation should never be optimized out by the compiler
+ *
+ * This implementation for mbedtls_platform_zeroize() was inspired from Colin
+ * Percival's blog article at:
+ *
+ * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
+ *
+ * It uses a volatile function pointer to the standard memset(). Because the
+ * pointer is volatile the compiler expects it to change at
+ * any time and will not optimize out the call that could potentially perform
+ * other operations on the input buffer instead of just setting it to 0.
+ * Nevertheless, as pointed out by davidtgoldblatt on Hacker News
+ * (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for
+ * details), optimizations of the following form are still possible:
+ *
+ * if( memset_func != memset )
+ *     memset_func( buf, 0, len );
+ *
+ * Note that it is extremely difficult to guarantee that
+ * mbedtls_platform_zeroize() will not be optimized out by aggressive compilers
+ * in a portable way. For this reason, Mbed TLS also provides the configuration
+ * option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
+ * mbedtls_platform_zeroize() to use a suitable implementation for their
+ * platform and needs.
+ */
+static void * (* const volatile memset_func)( void *, int, size_t ) = memset;
+
+void mbedtls_platform_zeroize( void *buf, size_t len )
+{
+    memset_func( buf, 0, len );
+}
+#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
+
+#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
+#include <time.h>
+#if !defined(_WIN32) && (defined(unix) || \
+    defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
+    defined(__MACH__)))
+#include <unistd.h>
+#endif /* !_WIN32 && (unix || __unix || __unix__ ||
+        * (__APPLE__ && __MACH__)) */
+
+#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
+       ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
+         _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
+/*
+ * This is a convenience shorthand macro to avoid checking the long
+ * preprocessor conditions above. Ideally, we could expose this macro in
+ * platform_util.h and simply use it in platform_util.c, threading.c and
+ * threading.h. However, this macro is not part of the Mbed TLS public API, so
+ * we keep it private by only defining it in this file
+ */
+#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) )
+#define PLATFORM_UTIL_USE_GMTIME
+#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */
+
+#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
+             ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
+                _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
+
+struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
+                                      struct tm *tm_buf )
+{
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+    return( ( gmtime_s( tm_buf, tt ) == 0 ) ? tm_buf : NULL );
+#elif !defined(PLATFORM_UTIL_USE_GMTIME)
+    return( gmtime_r( tt, tm_buf ) );
+#else
+    struct tm *lt;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 )
+        return( NULL );
+#endif /* MBEDTLS_THREADING_C */
+
+    lt = gmtime( tt );
+
+    if( lt != NULL )
+    {
+        memcpy( tm_buf, lt, sizeof( struct tm ) );
+    }
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 )
+        return( NULL );
+#endif /* MBEDTLS_THREADING_C */
+
+    return( ( lt == NULL ) ? NULL : tm_buf );
+#endif /* _WIN32 && !EFIX64 && !EFI32 */
+}
+#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/poly1305.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/poly1305.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/poly1305.c	(revision 398)
@@ -0,0 +1,559 @@
+/**
+ * \file poly1305.c
+ *
+ * \brief Poly1305 authentication algorithm.
+ *
+ *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_POLY1305_C)
+
+#include "mbedtls/poly1305.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_POLY1305_ALT)
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+    !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+/* Parameter validation macros */
+#define POLY1305_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA )
+#define POLY1305_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
+
+#define BYTES_TO_U32_LE( data, offset )                           \
+    ( (uint32_t) data[offset]                                     \
+          | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 )   \
+          | (uint32_t) ( (uint32_t) data[( offset ) + 2] << 16 )  \
+          | (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 )  \
+    )
+
+/*
+ * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
+ * However we provided an alternative for platforms without such a multiplier.
+ */
+#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
+static uint64_t mul64( uint32_t a, uint32_t b )
+{
+    /* a = al + 2**16 ah, b = bl + 2**16 bh */
+    const uint16_t al = (uint16_t) a;
+    const uint16_t bl = (uint16_t) b;
+    const uint16_t ah = a >> 16;
+    const uint16_t bh = b >> 16;
+
+    /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */
+    const uint32_t lo = (uint32_t) al * bl;
+    const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh;
+    const uint32_t hi = (uint32_t) ah * bh;
+
+    return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) );
+}
+#else
+static inline uint64_t mul64( uint32_t a, uint32_t b )
+{
+    return( (uint64_t) a * b );
+}
+#endif
+
+
+/**
+ * \brief                   Process blocks with Poly1305.
+ *
+ * \param ctx               The Poly1305 context.
+ * \param nblocks           Number of blocks to process. Note that this
+ *                          function only processes full blocks.
+ * \param input             Buffer containing the input block(s).
+ * \param needs_padding     Set to 0 if the padding bit has already been
+ *                          applied to the input data before calling this
+ *                          function.  Otherwise, set this parameter to 1.
+ */
+static void poly1305_process( mbedtls_poly1305_context *ctx,
+                              size_t nblocks,
+                              const unsigned char *input,
+                              uint32_t needs_padding )
+{
+    uint64_t d0, d1, d2, d3;
+    uint32_t acc0, acc1, acc2, acc3, acc4;
+    uint32_t r0, r1, r2, r3;
+    uint32_t rs1, rs2, rs3;
+    size_t offset  = 0U;
+    size_t i;
+
+    r0 = ctx->r[0];
+    r1 = ctx->r[1];
+    r2 = ctx->r[2];
+    r3 = ctx->r[3];
+
+    rs1 = r1 + ( r1 >> 2U );
+    rs2 = r2 + ( r2 >> 2U );
+    rs3 = r3 + ( r3 >> 2U );
+
+    acc0 = ctx->acc[0];
+    acc1 = ctx->acc[1];
+    acc2 = ctx->acc[2];
+    acc3 = ctx->acc[3];
+    acc4 = ctx->acc[4];
+
+    /* Process full blocks */
+    for( i = 0U; i < nblocks; i++ )
+    {
+        /* The input block is treated as a 128-bit little-endian integer */
+        d0   = BYTES_TO_U32_LE( input, offset + 0  );
+        d1   = BYTES_TO_U32_LE( input, offset + 4  );
+        d2   = BYTES_TO_U32_LE( input, offset + 8  );
+        d3   = BYTES_TO_U32_LE( input, offset + 12 );
+
+        /* Compute: acc += (padded) block as a 130-bit integer */
+        d0  += (uint64_t) acc0;
+        d1  += (uint64_t) acc1 + ( d0 >> 32U );
+        d2  += (uint64_t) acc2 + ( d1 >> 32U );
+        d3  += (uint64_t) acc3 + ( d2 >> 32U );
+        acc0 = (uint32_t) d0;
+        acc1 = (uint32_t) d1;
+        acc2 = (uint32_t) d2;
+        acc3 = (uint32_t) d3;
+        acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding;
+
+        /* Compute: acc *= r */
+        d0 = mul64( acc0, r0  ) +
+             mul64( acc1, rs3 ) +
+             mul64( acc2, rs2 ) +
+             mul64( acc3, rs1 );
+        d1 = mul64( acc0, r1  ) +
+             mul64( acc1, r0  ) +
+             mul64( acc2, rs3 ) +
+             mul64( acc3, rs2 ) +
+             mul64( acc4, rs1 );
+        d2 = mul64( acc0, r2  ) +
+             mul64( acc1, r1  ) +
+             mul64( acc2, r0  ) +
+             mul64( acc3, rs3 ) +
+             mul64( acc4, rs2 );
+        d3 = mul64( acc0, r3  ) +
+             mul64( acc1, r2  ) +
+             mul64( acc2, r1  ) +
+             mul64( acc3, r0  ) +
+             mul64( acc4, rs3 );
+        acc4 *= r0;
+
+        /* Compute: acc %= (2^130 - 5) (partial remainder) */
+        d1 += ( d0 >> 32 );
+        d2 += ( d1 >> 32 );
+        d3 += ( d2 >> 32 );
+        acc0 = (uint32_t) d0;
+        acc1 = (uint32_t) d1;
+        acc2 = (uint32_t) d2;
+        acc3 = (uint32_t) d3;
+        acc4 = (uint32_t) ( d3 >> 32 ) + acc4;
+
+        d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU );
+        acc4 &= 3U;
+        acc0 = (uint32_t) d0;
+        d0 = (uint64_t) acc1 + ( d0 >> 32U );
+        acc1 = (uint32_t) d0;
+        d0 = (uint64_t) acc2 + ( d0 >> 32U );
+        acc2 = (uint32_t) d0;
+        d0 = (uint64_t) acc3 + ( d0 >> 32U );
+        acc3 = (uint32_t) d0;
+        d0 = (uint64_t) acc4 + ( d0 >> 32U );
+        acc4 = (uint32_t) d0;
+
+        offset    += POLY1305_BLOCK_SIZE_BYTES;
+    }
+
+    ctx->acc[0] = acc0;
+    ctx->acc[1] = acc1;
+    ctx->acc[2] = acc2;
+    ctx->acc[3] = acc3;
+    ctx->acc[4] = acc4;
+}
+
+/**
+ * \brief                   Compute the Poly1305 MAC
+ *
+ * \param ctx               The Poly1305 context.
+ * \param mac               The buffer to where the MAC is written. Must be
+ *                          big enough to contain the 16-byte MAC.
+ */
+static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
+                                  unsigned char mac[16] )
+{
+    uint64_t d;
+    uint32_t g0, g1, g2, g3, g4;
+    uint32_t acc0, acc1, acc2, acc3, acc4;
+    uint32_t mask;
+    uint32_t mask_inv;
+
+    acc0 = ctx->acc[0];
+    acc1 = ctx->acc[1];
+    acc2 = ctx->acc[2];
+    acc3 = ctx->acc[3];
+    acc4 = ctx->acc[4];
+
+    /* Before adding 's' we ensure that the accumulator is mod 2^130 - 5.
+     * We do this by calculating acc - (2^130 - 5), then checking if
+     * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5)
+     */
+
+    /* Calculate acc + -(2^130 - 5) */
+    d  = ( (uint64_t) acc0 + 5U );
+    g0 = (uint32_t) d;
+    d  = ( (uint64_t) acc1 + ( d >> 32 ) );
+    g1 = (uint32_t) d;
+    d  = ( (uint64_t) acc2 + ( d >> 32 ) );
+    g2 = (uint32_t) d;
+    d  = ( (uint64_t) acc3 + ( d >> 32 ) );
+    g3 = (uint32_t) d;
+    g4 = acc4 + (uint32_t) ( d >> 32U );
+
+    /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */
+    mask = (uint32_t) 0U - ( g4 >> 2U );
+    mask_inv = ~mask;
+
+    /* If 131st bit is set then acc=g, otherwise, acc is unmodified */
+    acc0 = ( acc0 & mask_inv ) | ( g0 & mask );
+    acc1 = ( acc1 & mask_inv ) | ( g1 & mask );
+    acc2 = ( acc2 & mask_inv ) | ( g2 & mask );
+    acc3 = ( acc3 & mask_inv ) | ( g3 & mask );
+
+    /* Add 's' */
+    d = (uint64_t) acc0 + ctx->s[0];
+    acc0 = (uint32_t) d;
+    d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U );
+    acc1 = (uint32_t) d;
+    d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U );
+    acc2 = (uint32_t) d;
+    acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
+
+    /* Compute MAC (128 least significant bits of the accumulator) */
+    mac[ 0] = (unsigned char)( acc0       );
+    mac[ 1] = (unsigned char)( acc0 >>  8 );
+    mac[ 2] = (unsigned char)( acc0 >> 16 );
+    mac[ 3] = (unsigned char)( acc0 >> 24 );
+    mac[ 4] = (unsigned char)( acc1       );
+    mac[ 5] = (unsigned char)( acc1 >>  8 );
+    mac[ 6] = (unsigned char)( acc1 >> 16 );
+    mac[ 7] = (unsigned char)( acc1 >> 24 );
+    mac[ 8] = (unsigned char)( acc2       );
+    mac[ 9] = (unsigned char)( acc2 >>  8 );
+    mac[10] = (unsigned char)( acc2 >> 16 );
+    mac[11] = (unsigned char)( acc2 >> 24 );
+    mac[12] = (unsigned char)( acc3       );
+    mac[13] = (unsigned char)( acc3 >>  8 );
+    mac[14] = (unsigned char)( acc3 >> 16 );
+    mac[15] = (unsigned char)( acc3 >> 24 );
+}
+
+void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
+{
+    POLY1305_VALIDATE( ctx != NULL );
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
+}
+
+void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) );
+}
+
+int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
+                             const unsigned char key[32] )
+{
+    POLY1305_VALIDATE_RET( ctx != NULL );
+    POLY1305_VALIDATE_RET( key != NULL );
+
+    /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
+    ctx->r[0] = BYTES_TO_U32_LE( key, 0 )  & 0x0FFFFFFFU;
+    ctx->r[1] = BYTES_TO_U32_LE( key, 4 )  & 0x0FFFFFFCU;
+    ctx->r[2] = BYTES_TO_U32_LE( key, 8 )  & 0x0FFFFFFCU;
+    ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
+
+    ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
+    ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
+    ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
+    ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
+
+    /* Initial accumulator state */
+    ctx->acc[0] = 0U;
+    ctx->acc[1] = 0U;
+    ctx->acc[2] = 0U;
+    ctx->acc[3] = 0U;
+    ctx->acc[4] = 0U;
+
+    /* Queue initially empty */
+    mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) );
+    ctx->queue_len = 0U;
+
+    return( 0 );
+}
+
+int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
+                             const unsigned char *input,
+                             size_t ilen )
+{
+    size_t offset    = 0U;
+    size_t remaining = ilen;
+    size_t queue_free_len;
+    size_t nblocks;
+    POLY1305_VALIDATE_RET( ctx != NULL );
+    POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
+
+    if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) )
+    {
+        queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
+
+        if( ilen < queue_free_len )
+        {
+            /* Not enough data to complete the block.
+             * Store this data with the other leftovers.
+             */
+            memcpy( &ctx->queue[ctx->queue_len],
+                    input,
+                    ilen );
+
+            ctx->queue_len += ilen;
+
+            remaining = 0U;
+        }
+        else
+        {
+            /* Enough data to produce a complete block */
+            memcpy( &ctx->queue[ctx->queue_len],
+                    input,
+                    queue_free_len );
+
+            ctx->queue_len = 0U;
+
+            poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */
+
+            offset    += queue_free_len;
+            remaining -= queue_free_len;
+        }
+    }
+
+    if( remaining >= POLY1305_BLOCK_SIZE_BYTES )
+    {
+        nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES;
+
+        poly1305_process( ctx, nblocks, &input[offset], 1U );
+
+        offset += nblocks * POLY1305_BLOCK_SIZE_BYTES;
+        remaining %= POLY1305_BLOCK_SIZE_BYTES;
+    }
+
+    if( remaining > 0U )
+    {
+        /* Store partial block */
+        ctx->queue_len = remaining;
+        memcpy( ctx->queue, &input[offset], remaining );
+    }
+
+    return( 0 );
+}
+
+int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
+                             unsigned char mac[16] )
+{
+    POLY1305_VALIDATE_RET( ctx != NULL );
+    POLY1305_VALIDATE_RET( mac != NULL );
+
+    /* Process any leftover data */
+    if( ctx->queue_len > 0U )
+    {
+        /* Add padding bit */
+        ctx->queue[ctx->queue_len] = 1U;
+        ctx->queue_len++;
+
+        /* Pad with zeroes */
+        memset( &ctx->queue[ctx->queue_len],
+                0,
+                POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len );
+
+        poly1305_process( ctx, 1U,          /* Process 1 block */
+                          ctx->queue, 0U ); /* Already padded above */
+    }
+
+    poly1305_compute_mac( ctx, mac );
+
+    return( 0 );
+}
+
+int mbedtls_poly1305_mac( const unsigned char key[32],
+                          const unsigned char *input,
+                          size_t ilen,
+                          unsigned char mac[16] )
+{
+    mbedtls_poly1305_context ctx;
+    int ret;
+    POLY1305_VALIDATE_RET( key != NULL );
+    POLY1305_VALIDATE_RET( mac != NULL );
+    POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
+
+    mbedtls_poly1305_init( &ctx );
+
+    ret = mbedtls_poly1305_starts( &ctx, key );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_poly1305_update( &ctx, input, ilen );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_poly1305_finish( &ctx, mac );
+
+cleanup:
+    mbedtls_poly1305_free( &ctx );
+    return( ret );
+}
+
+#endif /* MBEDTLS_POLY1305_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+static const unsigned char test_keys[2][32] =
+{
+    {
+        0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33,
+        0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8,
+        0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd,
+        0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b
+    },
+    {
+        0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a,
+        0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
+        0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09,
+        0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
+    }
+};
+
+static const unsigned char test_data[2][127] =
+{
+    {
+        0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72,
+        0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f,
+        0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65,
+        0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f,
+        0x75, 0x70
+    },
+    {
+        0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72,
+        0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61,
+        0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
+        0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f,
+        0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20,
+        0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64,
+        0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20,
+        0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77,
+        0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c,
+        0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77,
+        0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20,
+        0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65,
+        0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74,
+        0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20,
+        0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75,
+        0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e
+    }
+};
+
+static const size_t test_data_len[2] =
+{
+    34U,
+    127U
+};
+
+static const unsigned char test_mac[2][16] =
+{
+    {
+        0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6,
+        0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9
+    },
+    {
+        0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61,
+        0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62
+    }
+};
+
+#define ASSERT( cond, args )            \
+    do                                  \
+    {                                   \
+        if( ! ( cond ) )                \
+        {                               \
+            if( verbose != 0 )          \
+                mbedtls_printf args;    \
+                                        \
+            return( -1 );               \
+        }                               \
+    }                                   \
+    while( 0 )
+
+int mbedtls_poly1305_self_test( int verbose )
+{
+    unsigned char mac[16];
+    unsigned i;
+    int ret;
+
+    for( i = 0U; i < 2U; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  Poly1305 test %u ", i );
+
+        ret = mbedtls_poly1305_mac( test_keys[i],
+                                    test_data[i],
+                                    test_data_len[i],
+                                    mac );
+        ASSERT( 0 == ret, ( "error code: %i\n", ret ) );
+
+        ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) );
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_POLY1305_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ripemd160.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ripemd160.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ripemd160.c	(revision 398)
@@ -0,0 +1,552 @@
+/*
+ *  RIPE MD-160 implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ *  The RIPEMD-160 algorithm was designed by RIPE in 1996
+ *  http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html
+ *  http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_RIPEMD160_C)
+
+#include "mbedtls/ripemd160.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_RIPEMD160_ALT)
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT32_LE
+#define GET_UINT32_LE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ]       )             \
+        | ( (uint32_t) (b)[(i) + 1] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 2] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 3] << 24 );            \
+}
+#endif
+
+#ifndef PUT_UINT32_LE
+#define PUT_UINT32_LE(n,b,i)                                    \
+{                                                               \
+    (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \
+    (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \
+    (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \
+    (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \
+}
+#endif
+
+void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
+}
+
+void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) );
+}
+
+void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst,
+                        const mbedtls_ripemd160_context *src )
+{
+    *dst = *src;
+}
+
+/*
+ * RIPEMD-160 context setup
+ */
+int mbedtls_ripemd160_starts_ret( mbedtls_ripemd160_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;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx )
+{
+    mbedtls_ripemd160_starts_ret( ctx );
+}
+#endif
+
+#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
+/*
+ * Process one block
+ */
+int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
+                                        const unsigned char data[64] )
+{
+    uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
+
+    GET_UINT32_LE( X[ 0], data,  0 );
+    GET_UINT32_LE( X[ 1], data,  4 );
+    GET_UINT32_LE( X[ 2], data,  8 );
+    GET_UINT32_LE( X[ 3], data, 12 );
+    GET_UINT32_LE( X[ 4], data, 16 );
+    GET_UINT32_LE( X[ 5], data, 20 );
+    GET_UINT32_LE( X[ 6], data, 24 );
+    GET_UINT32_LE( X[ 7], data, 28 );
+    GET_UINT32_LE( X[ 8], data, 32 );
+    GET_UINT32_LE( X[ 9], data, 36 );
+    GET_UINT32_LE( X[10], data, 40 );
+    GET_UINT32_LE( X[11], data, 44 );
+    GET_UINT32_LE( X[12], data, 48 );
+    GET_UINT32_LE( X[13], data, 52 );
+    GET_UINT32_LE( X[14], data, 56 );
+    GET_UINT32_LE( X[15], data, 60 );
+
+    A = Ap = ctx->state[0];
+    B = Bp = ctx->state[1];
+    C = Cp = ctx->state[2];
+    D = Dp = ctx->state[3];
+    E = Ep = ctx->state[4];
+
+#define F1( x, y, z )   ( x ^ y ^ z )
+#define F2( x, y, z )   ( ( x & y ) | ( ~x & z ) )
+#define F3( x, y, z )   ( ( x | ~y ) ^ z )
+#define F4( x, y, z )   ( ( x & z ) | ( y & ~z ) )
+#define F5( x, y, z )   ( x ^ ( y | ~z ) )
+
+#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) )
+
+#define P( a, b, c, d, e, r, s, f, k )      \
+    a += f( b, c, d ) + X[r] + k;           \
+    a = S( a, s ) + e;                      \
+    c = S( c, 10 );
+
+#define P2( a, b, c, d, e, r, s, rp, sp )   \
+    P( a, b, c, d, e, r, s, F, K );         \
+    P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp );
+
+#define F   F1
+#define K   0x00000000
+#define Fp  F5
+#define Kp  0x50A28BE6
+    P2( A, B, C, D, E,  0, 11,  5,  8 );
+    P2( E, A, B, C, D,  1, 14, 14,  9 );
+    P2( D, E, A, B, C,  2, 15,  7,  9 );
+    P2( C, D, E, A, B,  3, 12,  0, 11 );
+    P2( B, C, D, E, A,  4,  5,  9, 13 );
+    P2( A, B, C, D, E,  5,  8,  2, 15 );
+    P2( E, A, B, C, D,  6,  7, 11, 15 );
+    P2( D, E, A, B, C,  7,  9,  4,  5 );
+    P2( C, D, E, A, B,  8, 11, 13,  7 );
+    P2( B, C, D, E, A,  9, 13,  6,  7 );
+    P2( A, B, C, D, E, 10, 14, 15,  8 );
+    P2( E, A, B, C, D, 11, 15,  8, 11 );
+    P2( D, E, A, B, C, 12,  6,  1, 14 );
+    P2( C, D, E, A, B, 13,  7, 10, 14 );
+    P2( B, C, D, E, A, 14,  9,  3, 12 );
+    P2( A, B, C, D, E, 15,  8, 12,  6 );
+#undef F
+#undef K
+#undef Fp
+#undef Kp
+
+#define F   F2
+#define K   0x5A827999
+#define Fp  F4
+#define Kp  0x5C4DD124
+    P2( E, A, B, C, D,  7,  7,  6,  9 );
+    P2( D, E, A, B, C,  4,  6, 11, 13 );
+    P2( C, D, E, A, B, 13,  8,  3, 15 );
+    P2( B, C, D, E, A,  1, 13,  7,  7 );
+    P2( A, B, C, D, E, 10, 11,  0, 12 );
+    P2( E, A, B, C, D,  6,  9, 13,  8 );
+    P2( D, E, A, B, C, 15,  7,  5,  9 );
+    P2( C, D, E, A, B,  3, 15, 10, 11 );
+    P2( B, C, D, E, A, 12,  7, 14,  7 );
+    P2( A, B, C, D, E,  0, 12, 15,  7 );
+    P2( E, A, B, C, D,  9, 15,  8, 12 );
+    P2( D, E, A, B, C,  5,  9, 12,  7 );
+    P2( C, D, E, A, B,  2, 11,  4,  6 );
+    P2( B, C, D, E, A, 14,  7,  9, 15 );
+    P2( A, B, C, D, E, 11, 13,  1, 13 );
+    P2( E, A, B, C, D,  8, 12,  2, 11 );
+#undef F
+#undef K
+#undef Fp
+#undef Kp
+
+#define F   F3
+#define K   0x6ED9EBA1
+#define Fp  F3
+#define Kp  0x6D703EF3
+    P2( D, E, A, B, C,  3, 11, 15,  9 );
+    P2( C, D, E, A, B, 10, 13,  5,  7 );
+    P2( B, C, D, E, A, 14,  6,  1, 15 );
+    P2( A, B, C, D, E,  4,  7,  3, 11 );
+    P2( E, A, B, C, D,  9, 14,  7,  8 );
+    P2( D, E, A, B, C, 15,  9, 14,  6 );
+    P2( C, D, E, A, B,  8, 13,  6,  6 );
+    P2( B, C, D, E, A,  1, 15,  9, 14 );
+    P2( A, B, C, D, E,  2, 14, 11, 12 );
+    P2( E, A, B, C, D,  7,  8,  8, 13 );
+    P2( D, E, A, B, C,  0, 13, 12,  5 );
+    P2( C, D, E, A, B,  6,  6,  2, 14 );
+    P2( B, C, D, E, A, 13,  5, 10, 13 );
+    P2( A, B, C, D, E, 11, 12,  0, 13 );
+    P2( E, A, B, C, D,  5,  7,  4,  7 );
+    P2( D, E, A, B, C, 12,  5, 13,  5 );
+#undef F
+#undef K
+#undef Fp
+#undef Kp
+
+#define F   F4
+#define K   0x8F1BBCDC
+#define Fp  F2
+#define Kp  0x7A6D76E9
+    P2( C, D, E, A, B,  1, 11,  8, 15 );
+    P2( B, C, D, E, A,  9, 12,  6,  5 );
+    P2( A, B, C, D, E, 11, 14,  4,  8 );
+    P2( E, A, B, C, D, 10, 15,  1, 11 );
+    P2( D, E, A, B, C,  0, 14,  3, 14 );
+    P2( C, D, E, A, B,  8, 15, 11, 14 );
+    P2( B, C, D, E, A, 12,  9, 15,  6 );
+    P2( A, B, C, D, E,  4,  8,  0, 14 );
+    P2( E, A, B, C, D, 13,  9,  5,  6 );
+    P2( D, E, A, B, C,  3, 14, 12,  9 );
+    P2( C, D, E, A, B,  7,  5,  2, 12 );
+    P2( B, C, D, E, A, 15,  6, 13,  9 );
+    P2( A, B, C, D, E, 14,  8,  9, 12 );
+    P2( E, A, B, C, D,  5,  6,  7,  5 );
+    P2( D, E, A, B, C,  6,  5, 10, 15 );
+    P2( C, D, E, A, B,  2, 12, 14,  8 );
+#undef F
+#undef K
+#undef Fp
+#undef Kp
+
+#define F   F5
+#define K   0xA953FD4E
+#define Fp  F1
+#define Kp  0x00000000
+    P2( B, C, D, E, A,  4,  9, 12,  8 );
+    P2( A, B, C, D, E,  0, 15, 15,  5 );
+    P2( E, A, B, C, D,  5,  5, 10, 12 );
+    P2( D, E, A, B, C,  9, 11,  4,  9 );
+    P2( C, D, E, A, B,  7,  6,  1, 12 );
+    P2( B, C, D, E, A, 12,  8,  5,  5 );
+    P2( A, B, C, D, E,  2, 13,  8, 14 );
+    P2( E, A, B, C, D, 10, 12,  7,  6 );
+    P2( D, E, A, B, C, 14,  5,  6,  8 );
+    P2( C, D, E, A, B,  1, 12,  2, 13 );
+    P2( B, C, D, E, A,  3, 13, 13,  6 );
+    P2( A, B, C, D, E,  8, 14, 14,  5 );
+    P2( E, A, B, C, D, 11, 11,  0, 15 );
+    P2( D, E, A, B, C,  6,  8,  3, 13 );
+    P2( C, D, E, A, B, 15,  5,  9, 11 );
+    P2( B, C, D, E, A, 13,  6, 11, 11 );
+#undef F
+#undef K
+#undef Fp
+#undef Kp
+
+    C             = ctx->state[1] + C + Dp;
+    ctx->state[1] = ctx->state[2] + D + Ep;
+    ctx->state[2] = ctx->state[3] + E + Ap;
+    ctx->state[3] = ctx->state[4] + A + Bp;
+    ctx->state[4] = ctx->state[0] + B + Cp;
+    ctx->state[0] = C;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx,
+                                const unsigned char data[64] )
+{
+    mbedtls_internal_ripemd160_process( ctx, data );
+}
+#endif
+#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */
+
+/*
+ * RIPEMD-160 process buffer
+ */
+int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
+                                  const unsigned char *input,
+                                  size_t ilen )
+{
+    int ret;
+    size_t fill;
+    uint32_t left;
+
+    if( ilen == 0 )
+        return( 0 );
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += (uint32_t) ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (uint32_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, fill );
+
+        if( ( ret = mbedtls_internal_ripemd160_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        if( ( ret = mbedtls_internal_ripemd160_process( ctx, input ) ) != 0 )
+            return( ret );
+
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, ilen );
+    }
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx,
+                               const unsigned char *input,
+                               size_t ilen )
+{
+    mbedtls_ripemd160_update_ret( ctx, input, ilen );
+}
+#endif
+
+static const unsigned char ripemd160_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
+};
+
+/*
+ * RIPEMD-160 final digest
+ */
+int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
+                                  unsigned char output[20] )
+{
+    int ret;
+    uint32_t last, padn;
+    uint32_t high, low;
+    unsigned char msglen[8];
+
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT32_LE( low,  msglen, 0 );
+    PUT_UINT32_LE( high, msglen, 4 );
+
+    last = ctx->total[0] & 0x3F;
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+    ret = mbedtls_ripemd160_update_ret( ctx, ripemd160_padding, padn );
+    if( ret != 0 )
+        return( ret );
+
+    ret = mbedtls_ripemd160_update_ret( ctx, msglen, 8 );
+    if( ret != 0 )
+        return( ret );
+
+    PUT_UINT32_LE( ctx->state[0], output,  0 );
+    PUT_UINT32_LE( ctx->state[1], output,  4 );
+    PUT_UINT32_LE( ctx->state[2], output,  8 );
+    PUT_UINT32_LE( ctx->state[3], output, 12 );
+    PUT_UINT32_LE( ctx->state[4], output, 16 );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx,
+                               unsigned char output[20] )
+{
+    mbedtls_ripemd160_finish_ret( ctx, output );
+}
+#endif
+
+#endif /* ! MBEDTLS_RIPEMD160_ALT */
+
+/*
+ * output = RIPEMD-160( input buffer )
+ */
+int mbedtls_ripemd160_ret( const unsigned char *input,
+                           size_t ilen,
+                           unsigned char output[20] )
+{
+    int ret;
+    mbedtls_ripemd160_context ctx;
+
+    mbedtls_ripemd160_init( &ctx );
+
+    if( ( ret = mbedtls_ripemd160_starts_ret( &ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_ripemd160_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_ripemd160_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_ripemd160_free( &ctx );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_ripemd160( const unsigned char *input,
+                        size_t ilen,
+                        unsigned char output[20] )
+{
+    mbedtls_ripemd160_ret( input, ilen, output );
+}
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+/*
+ * Test vectors from the RIPEMD-160 paper and
+ * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC
+ */
+#define TESTS   8
+static const unsigned char ripemd160_test_str[TESTS][81] =
+{
+    { "" },
+    { "a" },
+    { "abc" },
+    { "message digest" },
+    { "abcdefghijklmnopqrstuvwxyz" },
+    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
+    { "12345678901234567890123456789012345678901234567890123456789012"
+      "345678901234567890" },
+};
+
+static const size_t ripemd160_test_strlen[TESTS] =
+{
+    0, 1, 3, 14, 26, 56, 62, 80
+};
+
+static const unsigned char ripemd160_test_md[TESTS][20] =
+{
+    { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
+      0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 },
+    { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
+      0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe },
+    { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
+      0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc },
+    { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
+      0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 },
+    { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
+      0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc },
+    { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
+      0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b },
+    { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed,
+      0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 },
+    { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb,
+      0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb },
+};
+
+/*
+ * Checkup routine
+ */
+int mbedtls_ripemd160_self_test( int verbose )
+{
+    int i, ret = 0;
+    unsigned char output[20];
+
+    memset( output, 0, sizeof output );
+
+    for( i = 0; i < TESTS; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  RIPEMD-160 test #%d: ", i + 1 );
+
+        ret = mbedtls_ripemd160_ret( ripemd160_test_str[i],
+                                     ripemd160_test_strlen[i], output );
+        if( ret != 0 )
+            goto fail;
+
+        if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 )
+        {
+            ret = 1;
+            goto fail;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_RIPEMD160_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/rsa.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/rsa.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/rsa.c	(revision 398)
@@ -0,0 +1,2720 @@
+/*
+ *  The RSA public-key cryptosystem
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ *  The following sources were referenced in the design of this implementation
+ *  of the RSA algorithm:
+ *
+ *  [1] A method for obtaining digital signatures and public-key cryptosystems
+ *      R Rivest, A Shamir, and L Adleman
+ *      http://people.csail.mit.edu/rivest/pubs.html#RSA78
+ *
+ *  [2] Handbook of Applied Cryptography - 1997, Chapter 8
+ *      Menezes, van Oorschot and Vanstone
+ *
+ *  [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks
+ *      Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and
+ *      Stefan Mangard
+ *      https://arxiv.org/abs/1702.08719v2
+ *
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+
+#include "mbedtls/rsa.h"
+#include "mbedtls/rsa_internal.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PKCS1_V21)
+#include "mbedtls/md.h"
+#endif
+
+#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__)
+#include <stdlib.h>
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#define mbedtls_calloc calloc
+#define mbedtls_free   free
+#endif
+
+#if !defined(MBEDTLS_RSA_ALT)
+
+/* Parameter validation macros */
+#define RSA_VALIDATE_RET( cond )                                       \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
+#define RSA_VALIDATE( cond )                                           \
+    MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if defined(MBEDTLS_PKCS1_V15)
+/* constant-time buffer comparison */
+static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
+{
+    size_t i;
+    const unsigned char *A = (const unsigned char *) a;
+    const unsigned char *B = (const unsigned char *) b;
+    unsigned char diff = 0;
+
+    for( i = 0; i < n; i++ )
+        diff |= A[i] ^ B[i];
+
+    return( diff );
+}
+#endif /* MBEDTLS_PKCS1_V15 */
+
+int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
+                        const mbedtls_mpi *N,
+                        const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                        const mbedtls_mpi *D, const mbedtls_mpi *E )
+{
+    int ret;
+    RSA_VALIDATE_RET( ctx != NULL );
+
+    if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
+        ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
+        ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
+        ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
+        ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+
+    if( N != NULL )
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+
+    return( 0 );
+}
+
+int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
+                            unsigned char const *N, size_t N_len,
+                            unsigned char const *P, size_t P_len,
+                            unsigned char const *Q, size_t Q_len,
+                            unsigned char const *D, size_t D_len,
+                            unsigned char const *E, size_t E_len )
+{
+    int ret = 0;
+    RSA_VALIDATE_RET( ctx != NULL );
+
+    if( N != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+    }
+
+    if( P != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
+
+    if( Q != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
+
+    if( D != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
+
+    if( E != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
+
+cleanup:
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+
+    return( 0 );
+}
+
+/*
+ * Checks whether the context fields are set in such a way
+ * that the RSA primitives will be able to execute without error.
+ * It does *not* make guarantees for consistency of the parameters.
+ */
+static int rsa_check_context( mbedtls_rsa_context const *ctx, int is_priv,
+                              int blinding_needed )
+{
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    /* blinding_needed is only used for NO_CRT to decide whether
+     * P,Q need to be present or not. */
+    ((void) blinding_needed);
+#endif
+
+    if( ctx->len != mbedtls_mpi_size( &ctx->N ) ||
+        ctx->len > MBEDTLS_MPI_MAX_SIZE )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    /*
+     * 1. Modular exponentiation needs positive, odd moduli.
+     */
+
+    /* Modular exponentiation wrt. N is always used for
+     * RSA public key operations. */
+    if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 ||
+        mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0  )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    /* Modular exponentiation for P and Q is only
+     * used for private key operations and if CRT
+     * is used. */
+    if( is_priv &&
+        ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
+          mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 ||
+          mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ||
+          mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0  ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif /* !MBEDTLS_RSA_NO_CRT */
+
+    /*
+     * 2. Exponents must be positive
+     */
+
+    /* Always need E for public key operations */
+    if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_RSA_NO_CRT)
+    /* For private key operations, use D or DP & DQ
+     * as (unblinded) exponents. */
+    if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+#else
+    if( is_priv &&
+        ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 ||
+          mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0  ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif /* MBEDTLS_RSA_NO_CRT */
+
+    /* Blinding shouldn't make exponents negative either,
+     * so check that P, Q >= 1 if that hasn't yet been
+     * done as part of 1. */
+#if defined(MBEDTLS_RSA_NO_CRT)
+    if( is_priv && blinding_needed &&
+        ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
+          mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif
+
+    /* It wouldn't lead to an error if it wasn't satisfied,
+     * but check for QP >= 1 nonetheless. */
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    if( is_priv &&
+        mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif
+
+    return( 0 );
+}
+
+int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
+{
+    int ret = 0;
+    int have_N, have_P, have_Q, have_D, have_E;
+    int n_missing, pq_missing, d_missing, is_pub, is_priv;
+
+    RSA_VALIDATE_RET( ctx != NULL );
+
+    have_N = ( mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 );
+    have_P = ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 );
+    have_Q = ( mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 );
+    have_D = ( mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 );
+    have_E = ( mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0 );
+
+    /*
+     * Check whether provided parameters are enough
+     * to deduce all others. The following incomplete
+     * parameter sets for private keys are supported:
+     *
+     * (1) P, Q missing.
+     * (2) D and potentially N missing.
+     *
+     */
+
+    n_missing  =              have_P &&  have_Q &&  have_D && have_E;
+    pq_missing =   have_N && !have_P && !have_Q &&  have_D && have_E;
+    d_missing  =              have_P &&  have_Q && !have_D && have_E;
+    is_pub     =   have_N && !have_P && !have_Q && !have_D && have_E;
+
+    /* These three alternatives are mutually exclusive */
+    is_priv = n_missing || pq_missing || d_missing;
+
+    if( !is_priv && !is_pub )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * Step 1: Deduce N if P, Q are provided.
+     */
+
+    if( !have_N && have_P && have_Q )
+    {
+        if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
+                                         &ctx->Q ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+        }
+
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+    }
+
+    /*
+     * Step 2: Deduce and verify all remaining core parameters.
+     */
+
+    if( pq_missing )
+    {
+        ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
+                                         &ctx->P, &ctx->Q );
+        if( ret != 0 )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+
+    }
+    else if( d_missing )
+    {
+        if( ( ret = mbedtls_rsa_deduce_private_exponent( &ctx->P,
+                                                         &ctx->Q,
+                                                         &ctx->E,
+                                                         &ctx->D ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+        }
+    }
+
+    /*
+     * Step 3: Deduce all additional parameters specific
+     *         to our current RSA implementation.
+     */
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    if( is_priv )
+    {
+        ret = mbedtls_rsa_deduce_crt( &ctx->P,  &ctx->Q,  &ctx->D,
+                                      &ctx->DP, &ctx->DQ, &ctx->QP );
+        if( ret != 0 )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+#endif /* MBEDTLS_RSA_NO_CRT */
+
+    /*
+     * Step 3: Basic sanity checks
+     */
+
+    return( rsa_check_context( ctx, is_priv, 1 ) );
+}
+
+int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
+                            unsigned char *N, size_t N_len,
+                            unsigned char *P, size_t P_len,
+                            unsigned char *Q, size_t Q_len,
+                            unsigned char *D, size_t D_len,
+                            unsigned char *E, size_t E_len )
+{
+    int ret = 0;
+    int is_priv;
+    RSA_VALIDATE_RET( ctx != NULL );
+
+    /* Check if key is private or public */
+    is_priv =
+        mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
+
+    if( !is_priv )
+    {
+        /* If we're trying to export private parameters for a public key,
+         * something must be wrong. */
+        if( P != NULL || Q != NULL || D != NULL )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    }
+
+    if( N != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
+
+    if( P != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
+
+    if( Q != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
+
+    if( D != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
+
+    if( E != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
+
+cleanup:
+
+    return( ret );
+}
+
+int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
+                        mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
+                        mbedtls_mpi *D, mbedtls_mpi *E )
+{
+    int ret;
+    int is_priv;
+    RSA_VALIDATE_RET( ctx != NULL );
+
+    /* Check if key is private or public */
+    is_priv =
+        mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
+
+    if( !is_priv )
+    {
+        /* If we're trying to export private parameters for a public key,
+         * something must be wrong. */
+        if( P != NULL || Q != NULL || D != NULL )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    }
+
+    /* Export all requested core parameters. */
+
+    if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
+        ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
+        ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
+        ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
+        ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Export CRT parameters
+ * This must also be implemented if CRT is not used, for being able to
+ * write DER encoded RSA keys. The helper function mbedtls_rsa_deduce_crt
+ * can be used in this case.
+ */
+int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
+                            mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
+{
+    int ret;
+    int is_priv;
+    RSA_VALIDATE_RET( ctx != NULL );
+
+    /* Check if key is private or public */
+    is_priv =
+        mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
+
+    if( !is_priv )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    /* Export all requested blinding parameters. */
+    if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
+        ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
+        ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+#else
+    if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
+                                        DP, DQ, QP ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+#endif
+
+    return( 0 );
+}
+
+/*
+ * Initialize an RSA context
+ */
+void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
+               int padding,
+               int hash_id )
+{
+    RSA_VALIDATE( ctx != NULL );
+    RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
+                  padding == MBEDTLS_RSA_PKCS_V21 );
+
+    memset( ctx, 0, sizeof( mbedtls_rsa_context ) );
+
+    mbedtls_rsa_set_padding( ctx, padding, hash_id );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+}
+
+/*
+ * Set padding for an existing RSA context
+ */
+void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding,
+                              int hash_id )
+{
+    RSA_VALIDATE( ctx != NULL );
+    RSA_VALIDATE( padding == MBEDTLS_RSA_PKCS_V15 ||
+                  padding == MBEDTLS_RSA_PKCS_V21 );
+
+    ctx->padding = padding;
+    ctx->hash_id = hash_id;
+}
+
+/*
+ * Get length in bytes of RSA modulus
+ */
+
+size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
+{
+    return( ctx->len );
+}
+
+
+#if defined(MBEDTLS_GENPRIME)
+
+/*
+ * Generate an RSA keypair
+ *
+ * This generation method follows the RSA key pair generation procedure of
+ * FIPS 186-4 if 2^16 < exponent < 2^256 and nbits = 2048 or nbits = 3072.
+ */
+int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng,
+                 unsigned int nbits, int exponent )
+{
+    int ret;
+    mbedtls_mpi H, G, L;
+    int prime_quality = 0;
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( f_rng != NULL );
+
+    if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * If the modulus is 1024 bit long or shorter, then the security strength of
+     * the RSA algorithm is less than or equal to 80 bits and therefore an error
+     * rate of 2^-80 is sufficient.
+     */
+    if( nbits > 1024 )
+        prime_quality = MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR;
+
+    mbedtls_mpi_init( &H );
+    mbedtls_mpi_init( &G );
+    mbedtls_mpi_init( &L );
+
+    /*
+     * find primes P and Q with Q < P so that:
+     * 1.  |P-Q| > 2^( nbits / 2 - 100 )
+     * 2.  GCD( E, (P-1)*(Q-1) ) == 1
+     * 3.  E^-1 mod LCM(P-1, Q-1) > 2^( nbits / 2 )
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) );
+
+    do
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1,
+                                                prime_quality, f_rng, p_rng ) );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1,
+                                                prime_quality, f_rng, p_rng ) );
+
+        /* make sure the difference between p and q is not too small (FIPS 186-4 §B.3.3 step 5.4) */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &H, &ctx->P, &ctx->Q ) );
+        if( mbedtls_mpi_bitlen( &H ) <= ( ( nbits >= 200 ) ? ( ( nbits >> 1 ) - 99 ) : 0 ) )
+            continue;
+
+        /* not required by any standards, but some users rely on the fact that P > Q */
+        if( H.s < 0 )
+            mbedtls_mpi_swap( &ctx->P, &ctx->Q );
+
+        /* Temporarily replace P,Q by P-1, Q-1 */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->P, &ctx->P, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &ctx->Q, &ctx->Q, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &ctx->P, &ctx->Q ) );
+
+        /* check GCD( E, (P-1)*(Q-1) ) == 1 (FIPS 186-4 §B.3.1 criterion 2(a)) */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H  ) );
+        if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
+            continue;
+
+        /* compute smallest possible D = E^-1 mod LCM(P-1, Q-1) (FIPS 186-4 §B.3.1 criterion 3(b)) */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->P, &ctx->Q ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L, NULL, &H, &G ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D, &ctx->E, &L ) );
+
+        if( mbedtls_mpi_bitlen( &ctx->D ) <= ( ( nbits + 1 ) / 2 ) ) // (FIPS 186-4 §B.3.1 criterion 3(a))
+            continue;
+
+        break;
+    }
+    while( 1 );
+
+    /* Restore P,Q */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->P,  &ctx->P, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &ctx->Q,  &ctx->Q, 1 ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
+
+    ctx->len = mbedtls_mpi_size( &ctx->N );
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    /*
+     * DP = D mod (P - 1)
+     * DQ = D mod (Q - 1)
+     * QP = Q^-1 mod P
+     */
+    MBEDTLS_MPI_CHK( mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
+                                             &ctx->DP, &ctx->DQ, &ctx->QP ) );
+#endif /* MBEDTLS_RSA_NO_CRT */
+
+    /* Double-check */
+    MBEDTLS_MPI_CHK( mbedtls_rsa_check_privkey( ctx ) );
+
+cleanup:
+
+    mbedtls_mpi_free( &H );
+    mbedtls_mpi_free( &G );
+    mbedtls_mpi_free( &L );
+
+    if( ret != 0 )
+    {
+        mbedtls_rsa_free( ctx );
+        return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
+    }
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_GENPRIME */
+
+/*
+ * Check a public RSA key
+ */
+int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
+{
+    RSA_VALIDATE_RET( ctx != NULL );
+
+    if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) != 0 )
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+
+    if( mbedtls_mpi_bitlen( &ctx->N ) < 128 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    if( mbedtls_mpi_get_bit( &ctx->E, 0 ) == 0 ||
+        mbedtls_mpi_bitlen( &ctx->E )     < 2  ||
+        mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Check for the consistency of all fields in an RSA private key context
+ */
+int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
+{
+    RSA_VALIDATE_RET( ctx != NULL );
+
+    if( mbedtls_rsa_check_pubkey( ctx ) != 0 ||
+        rsa_check_context( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    if( mbedtls_rsa_validate_params( &ctx->N, &ctx->P, &ctx->Q,
+                                     &ctx->D, &ctx->E, NULL, NULL ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    else if( mbedtls_rsa_validate_crt( &ctx->P, &ctx->Q, &ctx->D,
+                                       &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+#endif
+
+    return( 0 );
+}
+
+/*
+ * Check if contexts holding a public and private key match
+ */
+int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub,
+                                const mbedtls_rsa_context *prv )
+{
+    RSA_VALIDATE_RET( pub != NULL );
+    RSA_VALIDATE_RET( prv != NULL );
+
+    if( mbedtls_rsa_check_pubkey( pub )  != 0 ||
+        mbedtls_rsa_check_privkey( prv ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
+        mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Do an RSA public key operation
+ */
+int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
+                const unsigned char *input,
+                unsigned char *output )
+{
+    int ret;
+    size_t olen;
+    mbedtls_mpi T;
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+    RSA_VALIDATE_RET( output != NULL );
+
+    if( rsa_check_context( ctx, 0 /* public */, 0 /* no blinding */ ) )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    mbedtls_mpi_init( &T );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
+
+    if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+    {
+        ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    olen = ctx->len;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    mbedtls_mpi_free( &T );
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
+
+    return( 0 );
+}
+
+/*
+ * Generate or update blinding values, see section 10 of:
+ *  KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
+ *  DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
+ *  Berlin Heidelberg, 1996. p. 104-113.
+ */
+static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret, count = 0;
+
+    if( ctx->Vf.p != NULL )
+    {
+        /* We already have blinding values, just update them by squaring */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );
+
+        goto cleanup;
+    }
+
+    /* Unblinding value: Vf = random number, invertible mod N */
+    do {
+        if( count++ > 10 )
+            return( MBEDTLS_ERR_RSA_RNG_FAILED );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
+    } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
+
+    /* Blinding value: Vi =  Vf^(-e) mod N */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
+
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Exponent blinding supposed to prevent side-channel attacks using multiple
+ * traces of measurements to recover the RSA key. The more collisions are there,
+ * the more bits of the key can be recovered. See [3].
+ *
+ * Collecting n collisions with m bit long blinding value requires 2^(m-m/n)
+ * observations on avarage.
+ *
+ * For example with 28 byte blinding to achieve 2 collisions the adversary has
+ * to make 2^112 observations on avarage.
+ *
+ * (With the currently (as of 2017 April) known best algorithms breaking 2048
+ * bit RSA requires approximately as much time as trying out 2^112 random keys.
+ * Thus in this sense with 28 byte blinding the security is not reduced by
+ * side-channel attacks like the one in [3])
+ *
+ * This countermeasure does not help if the key recovery is possible with a
+ * single trace.
+ */
+#define RSA_EXPONENT_BLINDING 28
+
+/*
+ * Do an RSA private key operation
+ */
+int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
+                 int (*f_rng)(void *, unsigned char *, size_t),
+                 void *p_rng,
+                 const unsigned char *input,
+                 unsigned char *output )
+{
+    int ret;
+    size_t olen;
+
+    /* Temporary holding the result */
+    mbedtls_mpi T;
+
+    /* Temporaries holding P-1, Q-1 and the
+     * exponent blinding factor, respectively. */
+    mbedtls_mpi P1, Q1, R;
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    /* Temporaries holding the results mod p resp. mod q. */
+    mbedtls_mpi TP, TQ;
+
+    /* Temporaries holding the blinded exponents for
+     * the mod p resp. mod q computation (if used). */
+    mbedtls_mpi DP_blind, DQ_blind;
+
+    /* Pointers to actual exponents to be used - either the unblinded
+     * or the blinded ones, depending on the presence of a PRNG. */
+    mbedtls_mpi *DP = &ctx->DP;
+    mbedtls_mpi *DQ = &ctx->DQ;
+#else
+    /* Temporary holding the blinded exponent (if used). */
+    mbedtls_mpi D_blind;
+
+    /* Pointer to actual exponent to be used - either the unblinded
+     * or the blinded one, depending on the presence of a PRNG. */
+    mbedtls_mpi *D = &ctx->D;
+#endif /* MBEDTLS_RSA_NO_CRT */
+
+    /* Temporaries holding the initial input and the double
+     * checked result; should be the same in the end. */
+    mbedtls_mpi I, C;
+
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( input  != NULL );
+    RSA_VALIDATE_RET( output != NULL );
+
+    if( rsa_check_context( ctx, 1             /* private key checks */,
+                                f_rng != NULL /* blinding y/n       */ ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    /* MPI Initialization */
+    mbedtls_mpi_init( &T );
+
+    mbedtls_mpi_init( &P1 );
+    mbedtls_mpi_init( &Q1 );
+    mbedtls_mpi_init( &R );
+
+    if( f_rng != NULL )
+    {
+#if defined(MBEDTLS_RSA_NO_CRT)
+        mbedtls_mpi_init( &D_blind );
+#else
+        mbedtls_mpi_init( &DP_blind );
+        mbedtls_mpi_init( &DQ_blind );
+#endif
+    }
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    mbedtls_mpi_init( &TP ); mbedtls_mpi_init( &TQ );
+#endif
+
+    mbedtls_mpi_init( &I );
+    mbedtls_mpi_init( &C );
+
+    /* End of MPI initialization */
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) );
+    if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+    {
+        ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &I, &T ) );
+
+    if( f_rng != NULL )
+    {
+        /*
+         * Blinding
+         * T = T * Vi mod N
+         */
+        MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
+
+        /*
+         * Exponent blinding
+         */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
+
+#if defined(MBEDTLS_RSA_NO_CRT)
+        /*
+         * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D
+         */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                         f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) );
+
+        D = &D_blind;
+#else
+        /*
+         * DP_blind = ( P - 1 ) * R + DP
+         */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                         f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind,
+                    &ctx->DP ) );
+
+        DP = &DP_blind;
+
+        /*
+         * DQ_blind = ( Q - 1 ) * R + DQ
+         */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING,
+                         f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind,
+                    &ctx->DQ ) );
+
+        DQ = &DQ_blind;
+#endif /* MBEDTLS_RSA_NO_CRT */
+    }
+
+#if defined(MBEDTLS_RSA_NO_CRT)
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) );
+#else
+    /*
+     * Faster decryption using the CRT
+     *
+     * TP = input ^ dP mod P
+     * TQ = input ^ dQ mod Q
+     */
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TP, &T, DP, &ctx->P, &ctx->RP ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &TQ, &T, DQ, &ctx->Q, &ctx->RQ ) );
+
+    /*
+     * T = (TP - TQ) * (Q^-1 mod P) mod P
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &TP, &TQ ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->QP ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &TP, &ctx->P ) );
+
+    /*
+     * T = TQ + T * Q
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &TP, &T, &ctx->Q ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &TQ, &TP ) );
+#endif /* MBEDTLS_RSA_NO_CRT */
+
+    if( f_rng != NULL )
+    {
+        /*
+         * Unblind
+         * T = T * Vf mod N
+         */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) );
+    }
+
+    /* Verify the result to prevent glitching attacks. */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &C, &T, &ctx->E,
+                                          &ctx->N, &ctx->RN ) );
+    if( mbedtls_mpi_cmp_mpi( &C, &I ) != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
+        goto cleanup;
+    }
+
+    olen = ctx->len;
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    mbedtls_mpi_free( &P1 );
+    mbedtls_mpi_free( &Q1 );
+    mbedtls_mpi_free( &R );
+
+    if( f_rng != NULL )
+    {
+#if defined(MBEDTLS_RSA_NO_CRT)
+        mbedtls_mpi_free( &D_blind );
+#else
+        mbedtls_mpi_free( &DP_blind );
+        mbedtls_mpi_free( &DQ_blind );
+#endif
+    }
+
+    mbedtls_mpi_free( &T );
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    mbedtls_mpi_free( &TP ); mbedtls_mpi_free( &TQ );
+#endif
+
+    mbedtls_mpi_free( &C );
+    mbedtls_mpi_free( &I );
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_PKCS1_V21)
+/**
+ * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
+ *
+ * \param dst       buffer to mask
+ * \param dlen      length of destination buffer
+ * \param src       source of the mask generation
+ * \param slen      length of the source buffer
+ * \param md_ctx    message digest context to use
+ */
+static int mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
+                      size_t slen, mbedtls_md_context_t *md_ctx )
+{
+    unsigned char mask[MBEDTLS_MD_MAX_SIZE];
+    unsigned char counter[4];
+    unsigned char *p;
+    unsigned int hlen;
+    size_t i, use_len;
+    int ret = 0;
+
+    memset( mask, 0, MBEDTLS_MD_MAX_SIZE );
+    memset( counter, 0, 4 );
+
+    hlen = mbedtls_md_get_size( md_ctx->md_info );
+
+    /* Generate and apply dbMask */
+    p = dst;
+
+    while( dlen > 0 )
+    {
+        use_len = hlen;
+        if( dlen < hlen )
+            use_len = dlen;
+
+        if( ( ret = mbedtls_md_starts( md_ctx ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_update( md_ctx, src, slen ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_update( md_ctx, counter, 4 ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md_finish( md_ctx, mask ) ) != 0 )
+            goto exit;
+
+        for( i = 0; i < use_len; ++i )
+            *p++ ^= mask[i];
+
+        counter[3]++;
+
+        dlen -= use_len;
+    }
+
+exit:
+    mbedtls_platform_zeroize( mask, sizeof( mask ) );
+
+    return( ret );
+}
+#endif /* MBEDTLS_PKCS1_V21 */
+
+#if defined(MBEDTLS_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
+ */
+int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng,
+                            int mode,
+                            const unsigned char *label, size_t label_len,
+                            size_t ilen,
+                            const unsigned char *input,
+                            unsigned char *output )
+{
+    size_t olen;
+    int ret;
+    unsigned char *p = output;
+    unsigned int hlen;
+    const mbedtls_md_info_t *md_info;
+    mbedtls_md_context_t md_ctx;
+
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+    RSA_VALIDATE_RET( label_len == 0 || label != NULL );
+
+    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    if( f_rng == NULL )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
+    if( md_info == NULL )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    olen = ctx->len;
+    hlen = mbedtls_md_get_size( md_info );
+
+    /* first comparison checks for overflow */
+    if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    memset( output, 0, olen );
+
+    *p++ = 0;
+
+    /* Generate a random octet string seed */
+    if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
+        return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
+
+    p += hlen;
+
+    /* Construct DB */
+    if( ( ret = mbedtls_md( md_info, label, label_len, p ) ) != 0 )
+        return( ret );
+    p += hlen;
+    p += olen - 2 * hlen - 2 - ilen;
+    *p++ = 1;
+    memcpy( p, input, ilen );
+
+    mbedtls_md_init( &md_ctx );
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+        goto exit;
+
+    /* maskedDB: Apply dbMask to DB */
+    if( ( ret = mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
+                          &md_ctx ) ) != 0 )
+        goto exit;
+
+    /* maskedSeed: Apply seedMask to seed */
+    if( ( ret = mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
+                          &md_ctx ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_md_free( &md_ctx );
+
+    if( ret != 0 )
+        return( ret );
+
+    return( ( mode == MBEDTLS_RSA_PUBLIC )
+            ? mbedtls_rsa_public(  ctx, output, output )
+            : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
+}
+#endif /* MBEDTLS_PKCS1_V21 */
+
+#if defined(MBEDTLS_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
+ */
+int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode, size_t ilen,
+                                 const unsigned char *input,
+                                 unsigned char *output )
+{
+    size_t nb_pad, olen;
+    int ret;
+    unsigned char *p = output;
+
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+
+    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    olen = ctx->len;
+
+    /* first comparison checks for overflow */
+    if( ilen + 11 < ilen || olen < ilen + 11 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    nb_pad = olen - 3 - ilen;
+
+    *p++ = 0;
+    if( mode == MBEDTLS_RSA_PUBLIC )
+    {
+        if( f_rng == NULL )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+        *p++ = MBEDTLS_RSA_CRYPT;
+
+        while( nb_pad-- > 0 )
+        {
+            int rng_dl = 100;
+
+            do {
+                ret = f_rng( p_rng, p, 1 );
+            } while( *p == 0 && --rng_dl && ret == 0 );
+
+            /* Check if RNG failed to generate data */
+            if( rng_dl == 0 || ret != 0 )
+                return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
+
+            p++;
+        }
+    }
+    else
+    {
+        *p++ = MBEDTLS_RSA_SIGN;
+
+        while( nb_pad-- > 0 )
+            *p++ = 0xFF;
+    }
+
+    *p++ = 0;
+    memcpy( p, input, ilen );
+
+    return( ( mode == MBEDTLS_RSA_PUBLIC )
+            ? mbedtls_rsa_public(  ctx, output, output )
+            : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) );
+}
+#endif /* MBEDTLS_PKCS1_V15 */
+
+/*
+ * Add the message padding, then do an RSA operation
+ */
+int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng,
+                       int mode, size_t ilen,
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+
+    switch( ctx->padding )
+    {
+#if defined(MBEDTLS_PKCS1_V15)
+        case MBEDTLS_RSA_PKCS_V15:
+            return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
+                                                input, output );
+#endif
+
+#if defined(MBEDTLS_PKCS1_V21)
+        case MBEDTLS_RSA_PKCS_V21:
+            return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
+                                           ilen, input, output );
+#endif
+
+        default:
+            return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(MBEDTLS_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
+ */
+int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
+                            int (*f_rng)(void *, unsigned char *, size_t),
+                            void *p_rng,
+                            int mode,
+                            const unsigned char *label, size_t label_len,
+                            size_t *olen,
+                            const unsigned char *input,
+                            unsigned char *output,
+                            size_t output_max_len )
+{
+    int ret;
+    size_t ilen, i, pad_len;
+    unsigned char *p, bad, pad_done;
+    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+    unsigned char lhash[MBEDTLS_MD_MAX_SIZE];
+    unsigned int hlen;
+    const mbedtls_md_info_t *md_info;
+    mbedtls_md_context_t md_ctx;
+
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
+    RSA_VALIDATE_RET( label_len == 0 || label != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+    RSA_VALIDATE_RET( olen != NULL );
+
+    /*
+     * Parameters sanity checks
+     */
+    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    ilen = ctx->len;
+
+    if( ilen < 16 || ilen > sizeof( buf ) )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
+    if( md_info == NULL )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    hlen = mbedtls_md_get_size( md_info );
+
+    // checking for integer underflow
+    if( 2 * hlen + 2 > ilen )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * RSA operation
+     */
+    ret = ( mode == MBEDTLS_RSA_PUBLIC )
+          ? mbedtls_rsa_public(  ctx, input, buf )
+          : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
+
+    if( ret != 0 )
+        goto cleanup;
+
+    /*
+     * Unmask data and generate lHash
+     */
+    mbedtls_md_init( &md_ctx );
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+    {
+        mbedtls_md_free( &md_ctx );
+        goto cleanup;
+    }
+
+    /* seed: Apply seedMask to maskedSeed */
+    if( ( ret = mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
+                          &md_ctx ) ) != 0 ||
+    /* DB: Apply dbMask to maskedDB */
+        ( ret = mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
+                          &md_ctx ) ) != 0 )
+    {
+        mbedtls_md_free( &md_ctx );
+        goto cleanup;
+    }
+
+    mbedtls_md_free( &md_ctx );
+
+    /* Generate lHash */
+    if( ( ret = mbedtls_md( md_info, label, label_len, lhash ) ) != 0 )
+        goto cleanup;
+
+    /*
+     * Check contents, in "constant-time"
+     */
+    p = buf;
+    bad = 0;
+
+    bad |= *p++; /* First byte must be 0 */
+
+    p += hlen; /* Skip seed */
+
+    /* Check lHash */
+    for( i = 0; i < hlen; i++ )
+        bad |= lhash[i] ^ *p++;
+
+    /* Get zero-padding len, but always read till end of buffer
+     * (minus one, for the 01 byte) */
+    pad_len = 0;
+    pad_done = 0;
+    for( i = 0; i < ilen - 2 * hlen - 2; i++ )
+    {
+        pad_done |= p[i];
+        pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
+    }
+
+    p += pad_len;
+    bad |= *p++ ^ 0x01;
+
+    /*
+     * The only information "leaked" is whether the padding was correct or not
+     * (eg, no data is copied if it was not correct). This meets the
+     * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between
+     * the different error conditions.
+     */
+    if( bad != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
+        goto cleanup;
+    }
+
+    if( ilen - ( p - buf ) > output_max_len )
+    {
+        ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
+        goto cleanup;
+    }
+
+    *olen = ilen - (p - buf);
+    memcpy( output, p, *olen );
+    ret = 0;
+
+cleanup:
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+    mbedtls_platform_zeroize( lhash, sizeof( lhash ) );
+
+    return( ret );
+}
+#endif /* MBEDTLS_PKCS1_V21 */
+
+#if defined(MBEDTLS_PKCS1_V15)
+/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches.
+ *
+ * \param value     The value to analyze.
+ * \return          Zero if \p value is zero, otherwise all-bits-one.
+ */
+static unsigned all_or_nothing_int( unsigned value )
+{
+    /* MSVC has a warning about unary minus on unsigned, but this is
+     * well-defined and precisely what we want to do here */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+/** Check whether a size is out of bounds, without branches.
+ *
+ * This is equivalent to `size > max`, but is likely to be compiled to
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param size      Size to check.
+ * \param max       Maximum desired value for \p size.
+ * \return          \c 0 if `size <= max`.
+ * \return          \c 1 if `size > max`.
+ */
+static unsigned size_greater_than( size_t size, size_t max )
+{
+    /* Return the sign bit (1 for negative) of (max - size). */
+    return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) );
+}
+
+/** Choose between two integer values, without branches.
+ *
+ * This is equivalent to `cond ? if1 : if0`, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param cond      Condition to test.
+ * \param if1       Value to use if \p cond is nonzero.
+ * \param if0       Value to use if \p cond is zero.
+ * \return          \c if1 if \p cond is nonzero, otherwise \c if0.
+ */
+static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 )
+{
+    unsigned mask = all_or_nothing_int( cond );
+    return( ( mask & if1 ) | (~mask & if0 ) );
+}
+
+/** Shift some data towards the left inside a buffer without leaking
+ * the length of the data through side channels.
+ *
+ * `mem_move_to_left(start, total, offset)` is functionally equivalent to
+ * ```
+ * memmove(start, start + offset, total - offset);
+ * memset(start + offset, 0, total - offset);
+ * ```
+ * but it strives to use a memory access pattern (and thus total timing)
+ * that does not depend on \p offset. This timing independence comes at
+ * the expense of performance.
+ *
+ * \param start     Pointer to the start of the buffer.
+ * \param total     Total size of the buffer.
+ * \param offset    Offset from which to copy \p total - \p offset bytes.
+ */
+static void mem_move_to_left( void *start,
+                              size_t total,
+                              size_t offset )
+{
+    volatile unsigned char *buf = start;
+    size_t i, n;
+    if( total == 0 )
+        return;
+    for( i = 0; i < total; i++ )
+    {
+        unsigned no_op = size_greater_than( total - offset, i );
+        /* The first `total - offset` passes are a no-op. The last
+         * `offset` passes shift the data one byte to the left and
+         * zero out the last byte. */
+        for( n = 0; n < total - 1; n++ )
+        {
+            unsigned char current = buf[n];
+            unsigned char next = buf[n+1];
+            buf[n] = if_int( no_op, current, next );
+        }
+        buf[total-1] = if_int( no_op, buf[total-1], 0 );
+    }
+}
+
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
+ */
+int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode, size_t *olen,
+                                 const unsigned char *input,
+                                 unsigned char *output,
+                                 size_t output_max_len )
+{
+    int ret;
+    size_t ilen, i, plaintext_max_size;
+    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+    /* The following variables take sensitive values: their value must
+     * not leak into the observable behavior of the function other than
+     * the designated outputs (output, olen, return value). Otherwise
+     * this would open the execution of the function to
+     * side-channel-based variants of the Bleichenbacher padding oracle
+     * attack. Potential side channels include overall timing, memory
+     * access patterns (especially visible to an adversary who has access
+     * to a shared memory cache), and branches (especially visible to
+     * an adversary who has access to a shared code cache or to a shared
+     * branch predictor). */
+    size_t pad_count = 0;
+    unsigned bad = 0;
+    unsigned char pad_done = 0;
+    size_t plaintext_size = 0;
+    unsigned output_too_large;
+
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+    RSA_VALIDATE_RET( olen != NULL );
+
+    ilen = ctx->len;
+    plaintext_max_size = ( output_max_len > ilen - 11 ?
+                           ilen - 11 :
+                           output_max_len );
+
+    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    if( ilen < 16 || ilen > sizeof( buf ) )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    ret = ( mode == MBEDTLS_RSA_PUBLIC )
+          ? mbedtls_rsa_public(  ctx, input, buf )
+          : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf );
+
+    if( ret != 0 )
+        goto cleanup;
+
+    /* Check and get padding length in constant time and constant
+     * memory trace. The first byte must be 0. */
+    bad |= buf[0];
+
+    if( mode == MBEDTLS_RSA_PRIVATE )
+    {
+        /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
+         * where PS must be at least 8 nonzero bytes. */
+        bad |= buf[1] ^ MBEDTLS_RSA_CRYPT;
+
+        /* Read the whole buffer. Set pad_done to nonzero if we find
+         * the 0x00 byte and remember the padding length in pad_count. */
+        for( i = 2; i < ilen; i++ )
+        {
+            pad_done  |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
+            pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
+        }
+    }
+    else
+    {
+        /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
+         * where PS must be at least 8 bytes with the value 0xFF. */
+        bad |= buf[1] ^ MBEDTLS_RSA_SIGN;
+
+        /* Read the whole buffer. Set pad_done to nonzero if we find
+         * the 0x00 byte and remember the padding length in pad_count.
+         * If there's a non-0xff byte in the padding, the padding is bad. */
+        for( i = 2; i < ilen; i++ )
+        {
+            pad_done |= if_int( buf[i], 0, 1 );
+            pad_count += if_int( pad_done, 0, 1 );
+            bad |= if_int( pad_done, 0, buf[i] ^ 0xFF );
+        }
+    }
+
+    /* If pad_done is still zero, there's no data, only unfinished padding. */
+    bad |= if_int( pad_done, 0, 1 );
+
+    /* There must be at least 8 bytes of padding. */
+    bad |= size_greater_than( 8, pad_count );
+
+    /* If the padding is valid, set plaintext_size to the number of
+     * remaining bytes after stripping the padding. If the padding
+     * is invalid, avoid leaking this fact through the size of the
+     * output: use the maximum message size that fits in the output
+     * buffer. Do it without branches to avoid leaking the padding
+     * validity through timing. RSA keys are small enough that all the
+     * size_t values involved fit in unsigned int. */
+    plaintext_size = if_int( bad,
+                             (unsigned) plaintext_max_size,
+                             (unsigned) ( ilen - pad_count - 3 ) );
+
+    /* Set output_too_large to 0 if the plaintext fits in the output
+     * buffer and to 1 otherwise. */
+    output_too_large = size_greater_than( plaintext_size,
+                                          plaintext_max_size );
+
+    /* Set ret without branches to avoid timing attacks. Return:
+     * - INVALID_PADDING if the padding is bad (bad != 0).
+     * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
+     *   plaintext does not fit in the output buffer.
+     * - 0 if the padding is correct. */
+    ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
+                  if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
+                          0 ) );
+
+    /* If the padding is bad or the plaintext is too large, zero the
+     * data that we're about to copy to the output buffer.
+     * We need to copy the same amount of data
+     * from the same buffer whether the padding is good or not to
+     * avoid leaking the padding validity through overall timing or
+     * through memory or cache access patterns. */
+    bad = all_or_nothing_int( bad | output_too_large );
+    for( i = 11; i < ilen; i++ )
+        buf[i] &= ~bad;
+
+    /* If the plaintext is too large, truncate it to the buffer size.
+     * Copy anyway to avoid revealing the length through timing, because
+     * revealing the length is as bad as revealing the padding validity
+     * for a Bleichenbacher attack. */
+    plaintext_size = if_int( output_too_large,
+                             (unsigned) plaintext_max_size,
+                             (unsigned) plaintext_size );
+
+    /* Move the plaintext to the leftmost position where it can start in
+     * the working buffer, i.e. make it start plaintext_max_size from
+     * the end of the buffer. Do this with a memory access trace that
+     * does not depend on the plaintext size. After this move, the
+     * starting location of the plaintext is no longer sensitive
+     * information. */
+    mem_move_to_left( buf + ilen - plaintext_max_size,
+                      plaintext_max_size,
+                      plaintext_max_size - plaintext_size );
+
+    /* Finally copy the decrypted plaintext plus trailing zeros
+     * into the output buffer. */
+    memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size );
+
+    /* Report the amount of data we copied to the output buffer. In case
+     * of errors (bad padding or output too large), the value of *olen
+     * when this function returns is not specified. Making it equivalent
+     * to the good case limits the risks of leaking the padding validity. */
+    *olen = plaintext_size;
+
+cleanup:
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+
+    return( ret );
+}
+#endif /* MBEDTLS_PKCS1_V15 */
+
+/*
+ * Do an RSA operation, then remove the message padding
+ */
+int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng,
+                       int mode, size_t *olen,
+                       const unsigned char *input,
+                       unsigned char *output,
+                       size_t output_max_len)
+{
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( output_max_len == 0 || output != NULL );
+    RSA_VALIDATE_RET( input != NULL );
+    RSA_VALIDATE_RET( olen != NULL );
+
+    switch( ctx->padding )
+    {
+#if defined(MBEDTLS_PKCS1_V15)
+        case MBEDTLS_RSA_PKCS_V15:
+            return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
+                                                input, output, output_max_len );
+#endif
+
+#if defined(MBEDTLS_PKCS1_V21)
+        case MBEDTLS_RSA_PKCS_V21:
+            return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
+                                           olen, input, output,
+                                           output_max_len );
+#endif
+
+        default:
+            return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(MBEDTLS_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
+ */
+int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng,
+                         int mode,
+                         mbedtls_md_type_t md_alg,
+                         unsigned int hashlen,
+                         const unsigned char *hash,
+                         unsigned char *sig )
+{
+    size_t olen;
+    unsigned char *p = sig;
+    unsigned char salt[MBEDTLS_MD_MAX_SIZE];
+    size_t slen, min_slen, hlen, offset = 0;
+    int ret;
+    size_t msb;
+    const mbedtls_md_info_t *md_info;
+    mbedtls_md_context_t md_ctx;
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+    RSA_VALIDATE_RET( sig != NULL );
+
+    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    if( f_rng == NULL )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    olen = ctx->len;
+
+    if( md_alg != MBEDTLS_MD_NONE )
+    {
+        /* Gather length of hash to sign */
+        md_info = mbedtls_md_info_from_type( md_alg );
+        if( md_info == NULL )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+        hashlen = mbedtls_md_get_size( md_info );
+    }
+
+    md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
+    if( md_info == NULL )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    hlen = mbedtls_md_get_size( md_info );
+
+    /* Calculate the largest possible salt length. Normally this is the hash
+     * length, which is the maximum length the salt can have. If there is not
+     * enough room, use the maximum salt length that fits. The constraint is
+     * that the hash length plus the salt length plus 2 bytes must be at most
+     * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
+     * (PKCS#1 v2.2) §9.1.1 step 3. */
+    min_slen = hlen - 2;
+    if( olen < hlen + min_slen + 2 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    else if( olen >= hlen + hlen + 2 )
+        slen = hlen;
+    else
+        slen = olen - hlen - 2;
+
+    memset( sig, 0, olen );
+
+    /* Generate salt of length slen */
+    if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
+        return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
+
+    /* Note: EMSA-PSS encoding is over the length of N - 1 bits */
+    msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
+    p += olen - hlen - slen - 2;
+    *p++ = 0x01;
+    memcpy( p, salt, slen );
+    p += slen;
+
+    mbedtls_md_init( &md_ctx );
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+        goto exit;
+
+    /* Generate H = Hash( M' ) */
+    if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_update( &md_ctx, p, 8 ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_update( &md_ctx, hash, hashlen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_update( &md_ctx, salt, slen ) ) != 0 )
+        goto exit;
+    if( ( ret = mbedtls_md_finish( &md_ctx, p ) ) != 0 )
+        goto exit;
+
+    /* Compensate for boundary condition when applying mask */
+    if( msb % 8 == 0 )
+        offset = 1;
+
+    /* maskedDB: Apply dbMask to DB */
+    if( ( ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen,
+                          &md_ctx ) ) != 0 )
+        goto exit;
+
+    msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
+    sig[0] &= 0xFF >> ( olen * 8 - msb );
+
+    p += hlen;
+    *p++ = 0xBC;
+
+    mbedtls_platform_zeroize( salt, sizeof( salt ) );
+
+exit:
+    mbedtls_md_free( &md_ctx );
+
+    if( ret != 0 )
+        return( ret );
+
+    return( ( mode == MBEDTLS_RSA_PUBLIC )
+            ? mbedtls_rsa_public(  ctx, sig, sig )
+            : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
+}
+#endif /* MBEDTLS_PKCS1_V21 */
+
+#if defined(MBEDTLS_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
+ */
+
+/* Construct a PKCS v1.5 encoding of a hashed message
+ *
+ * This is used both for signature generation and verification.
+ *
+ * Parameters:
+ * - md_alg:  Identifies the hash algorithm used to generate the given hash;
+ *            MBEDTLS_MD_NONE if raw data is signed.
+ * - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE.
+ * - hash:    Buffer containing the hashed message or the raw data.
+ * - dst_len: Length of the encoded message.
+ * - dst:     Buffer to hold the encoded message.
+ *
+ * Assumptions:
+ * - hash has size hashlen if md_alg == MBEDTLS_MD_NONE.
+ * - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE.
+ * - dst points to a buffer of size at least dst_len.
+ *
+ */
+static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg,
+                                        unsigned int hashlen,
+                                        const unsigned char *hash,
+                                        size_t dst_len,
+                                        unsigned char *dst )
+{
+    size_t oid_size  = 0;
+    size_t nb_pad    = dst_len;
+    unsigned char *p = dst;
+    const char *oid  = NULL;
+
+    /* Are we signing hashed or raw data? */
+    if( md_alg != MBEDTLS_MD_NONE )
+    {
+        const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
+        if( md_info == NULL )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+        if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+        hashlen = mbedtls_md_get_size( md_info );
+
+        /* Double-check that 8 + hashlen + oid_size can be used as a
+         * 1-byte ASN.1 length encoding and that there's no overflow. */
+        if( 8 + hashlen + oid_size  >= 0x80         ||
+            10 + hashlen            <  hashlen      ||
+            10 + hashlen + oid_size <  10 + hashlen )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+        /*
+         * Static bounds check:
+         * - Need 10 bytes for five tag-length pairs.
+         *   (Insist on 1-byte length encodings to protect against variants of
+         *    Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification)
+         * - Need hashlen bytes for hash
+         * - Need oid_size bytes for hash alg OID.
+         */
+        if( nb_pad < 10 + hashlen + oid_size )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+        nb_pad -= 10 + hashlen + oid_size;
+    }
+    else
+    {
+        if( nb_pad < hashlen )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+        nb_pad -= hashlen;
+    }
+
+    /* Need space for signature header and padding delimiter (3 bytes),
+     * and 8 bytes for the minimal padding */
+    if( nb_pad < 3 + 8 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    nb_pad -= 3;
+
+    /* Now nb_pad is the amount of memory to be filled
+     * with padding, and at least 8 bytes long. */
+
+    /* Write signature header and padding */
+    *p++ = 0;
+    *p++ = MBEDTLS_RSA_SIGN;
+    memset( p, 0xFF, nb_pad );
+    p += nb_pad;
+    *p++ = 0;
+
+    /* Are we signing raw data? */
+    if( md_alg == MBEDTLS_MD_NONE )
+    {
+        memcpy( p, hash, hashlen );
+        return( 0 );
+    }
+
+    /* Signing hashed data, add corresponding ASN.1 structure
+     *
+     * DigestInfo ::= SEQUENCE {
+     *   digestAlgorithm DigestAlgorithmIdentifier,
+     *   digest Digest }
+     * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+     * Digest ::= OCTET STRING
+     *
+     * Schematic:
+     * TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID  + LEN [ OID  ]
+     *                                 TAG-NULL + LEN [ NULL ] ]
+     *                 TAG-OCTET + LEN [ HASH ] ]
+     */
+    *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
+    *p++ = (unsigned char)( 0x08 + oid_size + hashlen );
+    *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
+    *p++ = (unsigned char)( 0x04 + oid_size );
+    *p++ = MBEDTLS_ASN1_OID;
+    *p++ = (unsigned char) oid_size;
+    memcpy( p, oid, oid_size );
+    p += oid_size;
+    *p++ = MBEDTLS_ASN1_NULL;
+    *p++ = 0x00;
+    *p++ = MBEDTLS_ASN1_OCTET_STRING;
+    *p++ = (unsigned char) hashlen;
+    memcpy( p, hash, hashlen );
+    p += hashlen;
+
+    /* Just a sanity-check, should be automatic
+     * after the initial bounds check. */
+    if( p != dst + dst_len )
+    {
+        mbedtls_platform_zeroize( dst, dst_len );
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng,
+                               int mode,
+                               mbedtls_md_type_t md_alg,
+                               unsigned int hashlen,
+                               const unsigned char *hash,
+                               unsigned char *sig )
+{
+    int ret;
+    unsigned char *sig_try = NULL, *verif = NULL;
+
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+    RSA_VALIDATE_RET( sig != NULL );
+
+    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * Prepare PKCS1-v1.5 encoding (padding and hash identifier)
+     */
+
+    if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash,
+                                             ctx->len, sig ) ) != 0 )
+        return( ret );
+
+    /*
+     * Call respective RSA primitive
+     */
+
+    if( mode == MBEDTLS_RSA_PUBLIC )
+    {
+        /* Skip verification on a public key operation */
+        return( mbedtls_rsa_public( ctx, sig, sig ) );
+    }
+
+    /* Private key operation
+     *
+     * In order to prevent Lenstra's attack, make the signature in a
+     * temporary buffer and check it before returning it.
+     */
+
+    sig_try = mbedtls_calloc( 1, ctx->len );
+    if( sig_try == NULL )
+        return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
+
+    verif = mbedtls_calloc( 1, ctx->len );
+    if( verif == NULL )
+    {
+        mbedtls_free( sig_try );
+        return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
+    }
+
+    MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
+    MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
+
+    if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
+        goto cleanup;
+    }
+
+    memcpy( sig, sig_try, ctx->len );
+
+cleanup:
+    mbedtls_free( sig_try );
+    mbedtls_free( verif );
+
+    return( ret );
+}
+#endif /* MBEDTLS_PKCS1_V15 */
+
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
+                    int (*f_rng)(void *, unsigned char *, size_t),
+                    void *p_rng,
+                    int mode,
+                    mbedtls_md_type_t md_alg,
+                    unsigned int hashlen,
+                    const unsigned char *hash,
+                    unsigned char *sig )
+{
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+    RSA_VALIDATE_RET( sig != NULL );
+
+    switch( ctx->padding )
+    {
+#if defined(MBEDTLS_PKCS1_V15)
+        case MBEDTLS_RSA_PKCS_V15:
+            return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
+                                              hashlen, hash, sig );
+#endif
+
+#if defined(MBEDTLS_PKCS1_V21)
+        case MBEDTLS_RSA_PKCS_V21:
+            return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
+                                        hashlen, hash, sig );
+#endif
+
+        default:
+            return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(MBEDTLS_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
+ */
+int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng,
+                               int mode,
+                               mbedtls_md_type_t md_alg,
+                               unsigned int hashlen,
+                               const unsigned char *hash,
+                               mbedtls_md_type_t mgf1_hash_id,
+                               int expected_salt_len,
+                               const unsigned char *sig )
+{
+    int ret;
+    size_t siglen;
+    unsigned char *p;
+    unsigned char *hash_start;
+    unsigned char result[MBEDTLS_MD_MAX_SIZE];
+    unsigned char zeros[8];
+    unsigned int hlen;
+    size_t observed_salt_len, msb;
+    const mbedtls_md_info_t *md_info;
+    mbedtls_md_context_t md_ctx;
+    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( sig != NULL );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+
+    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    siglen = ctx->len;
+
+    if( siglen < 16 || siglen > sizeof( buf ) )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    ret = ( mode == MBEDTLS_RSA_PUBLIC )
+          ? mbedtls_rsa_public(  ctx, sig, buf )
+          : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );
+
+    if( ret != 0 )
+        return( ret );
+
+    p = buf;
+
+    if( buf[siglen - 1] != 0xBC )
+        return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+
+    if( md_alg != MBEDTLS_MD_NONE )
+    {
+        /* Gather length of hash to sign */
+        md_info = mbedtls_md_info_from_type( md_alg );
+        if( md_info == NULL )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+        hashlen = mbedtls_md_get_size( md_info );
+    }
+
+    md_info = mbedtls_md_info_from_type( mgf1_hash_id );
+    if( md_info == NULL )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    hlen = mbedtls_md_get_size( md_info );
+
+    memset( zeros, 0, 8 );
+
+    /*
+     * Note: EMSA-PSS verification is over the length of N - 1 bits
+     */
+    msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
+
+    if( buf[0] >> ( 8 - siglen * 8 + msb ) )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    /* Compensate for boundary condition when applying mask */
+    if( msb % 8 == 0 )
+    {
+        p++;
+        siglen -= 1;
+    }
+
+    if( siglen < hlen + 2 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    hash_start = p + siglen - hlen - 1;
+
+    mbedtls_md_init( &md_ctx );
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
+        goto exit;
+
+    ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx );
+    if( ret != 0 )
+        goto exit;
+
+    buf[0] &= 0xFF >> ( siglen * 8 - msb );
+
+    while( p < hash_start - 1 && *p == 0 )
+        p++;
+
+    if( *p++ != 0x01 )
+    {
+        ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
+        goto exit;
+    }
+
+    observed_salt_len = hash_start - p;
+
+    if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&
+        observed_salt_len != (size_t) expected_salt_len )
+    {
+        ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
+        goto exit;
+    }
+
+    /*
+     * Generate H = Hash( M' )
+     */
+    ret = mbedtls_md_starts( &md_ctx );
+    if ( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_update( &md_ctx, zeros, 8 );
+    if ( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_update( &md_ctx, hash, hashlen );
+    if ( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_update( &md_ctx, p, observed_salt_len );
+    if ( ret != 0 )
+        goto exit;
+    ret = mbedtls_md_finish( &md_ctx, result );
+    if ( ret != 0 )
+        goto exit;
+
+    if( memcmp( hash_start, result, hlen ) != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
+        goto exit;
+    }
+
+exit:
+    mbedtls_md_free( &md_ctx );
+
+    return( ret );
+}
+
+/*
+ * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
+ */
+int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng,
+                           int mode,
+                           mbedtls_md_type_t md_alg,
+                           unsigned int hashlen,
+                           const unsigned char *hash,
+                           const unsigned char *sig )
+{
+    mbedtls_md_type_t mgf1_hash_id;
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( sig != NULL );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+
+    mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )
+                             ? (mbedtls_md_type_t) ctx->hash_id
+                             : md_alg;
+
+    return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
+                                       md_alg, hashlen, hash,
+                                       mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,
+                                       sig ) );
+
+}
+#endif /* MBEDTLS_PKCS1_V21 */
+
+#if defined(MBEDTLS_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
+ */
+int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng,
+                                 int mode,
+                                 mbedtls_md_type_t md_alg,
+                                 unsigned int hashlen,
+                                 const unsigned char *hash,
+                                 const unsigned char *sig )
+{
+    int ret = 0;
+    size_t sig_len;
+    unsigned char *encoded = NULL, *encoded_expected = NULL;
+
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( sig != NULL );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+
+    sig_len = ctx->len;
+
+    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    /*
+     * Prepare expected PKCS1 v1.5 encoding of hash.
+     */
+
+    if( ( encoded          = mbedtls_calloc( 1, sig_len ) ) == NULL ||
+        ( encoded_expected = mbedtls_calloc( 1, sig_len ) ) == NULL )
+    {
+        ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
+        goto cleanup;
+    }
+
+    if( ( ret = rsa_rsassa_pkcs1_v15_encode( md_alg, hashlen, hash, sig_len,
+                                             encoded_expected ) ) != 0 )
+        goto cleanup;
+
+    /*
+     * Apply RSA primitive to get what should be PKCS1 encoded hash.
+     */
+
+    ret = ( mode == MBEDTLS_RSA_PUBLIC )
+          ? mbedtls_rsa_public(  ctx, sig, encoded )
+          : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, encoded );
+    if( ret != 0 )
+        goto cleanup;
+
+    /*
+     * Compare
+     */
+
+    if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected,
+                                      sig_len ) ) != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
+        goto cleanup;
+    }
+
+cleanup:
+
+    if( encoded != NULL )
+    {
+        mbedtls_platform_zeroize( encoded, sig_len );
+        mbedtls_free( encoded );
+    }
+
+    if( encoded_expected != NULL )
+    {
+        mbedtls_platform_zeroize( encoded_expected, sig_len );
+        mbedtls_free( encoded_expected );
+    }
+
+    return( ret );
+}
+#endif /* MBEDTLS_PKCS1_V15 */
+
+/*
+ * Do an RSA operation and check the message digest
+ */
+int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng,
+                      int mode,
+                      mbedtls_md_type_t md_alg,
+                      unsigned int hashlen,
+                      const unsigned char *hash,
+                      const unsigned char *sig )
+{
+    RSA_VALIDATE_RET( ctx != NULL );
+    RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
+                      mode == MBEDTLS_RSA_PUBLIC );
+    RSA_VALIDATE_RET( sig != NULL );
+    RSA_VALIDATE_RET( ( md_alg  == MBEDTLS_MD_NONE &&
+                        hashlen == 0 ) ||
+                      hash != NULL );
+
+    switch( ctx->padding )
+    {
+#if defined(MBEDTLS_PKCS1_V15)
+        case MBEDTLS_RSA_PKCS_V15:
+            return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
+                                                hashlen, hash, sig );
+#endif
+
+#if defined(MBEDTLS_PKCS1_V21)
+        case MBEDTLS_RSA_PKCS_V21:
+            return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
+                                          hashlen, hash, sig );
+#endif
+
+        default:
+            return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+/*
+ * Copy the components of an RSA key
+ */
+int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
+{
+    int ret;
+    RSA_VALIDATE_RET( dst != NULL );
+    RSA_VALIDATE_RET( src != NULL );
+
+    dst->ver = src->ver;
+    dst->len = src->len;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
+#endif
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
+
+    dst->padding = src->padding;
+    dst->hash_id = src->hash_id;
+
+cleanup:
+    if( ret != 0 )
+        mbedtls_rsa_free( dst );
+
+    return( ret );
+}
+
+/*
+ * Free the components of an RSA key
+ */
+void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_mpi_free( &ctx->Vi );
+    mbedtls_mpi_free( &ctx->Vf );
+    mbedtls_mpi_free( &ctx->RN );
+    mbedtls_mpi_free( &ctx->D  );
+    mbedtls_mpi_free( &ctx->Q  );
+    mbedtls_mpi_free( &ctx->P  );
+    mbedtls_mpi_free( &ctx->E  );
+    mbedtls_mpi_free( &ctx->N  );
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    mbedtls_mpi_free( &ctx->RQ );
+    mbedtls_mpi_free( &ctx->RP );
+    mbedtls_mpi_free( &ctx->QP );
+    mbedtls_mpi_free( &ctx->DQ );
+    mbedtls_mpi_free( &ctx->DP );
+#endif /* MBEDTLS_RSA_NO_CRT */
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_free( &ctx->mutex );
+#endif
+}
+
+#endif /* !MBEDTLS_RSA_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+#include "mbedtls/sha1.h"
+
+/*
+ * Example RSA-1024 keypair, for test purposes
+ */
+#define KEY_LEN 128
+
+#define RSA_N   "9292758453063D803DD603D5E777D788" \
+                "8ED1D5BF35786190FA2F23EBC0848AEA" \
+                "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
+                "7130B9CED7ACDF54CFC7555AC14EEBAB" \
+                "93A89813FBF3C4F8066D2D800F7C38A8" \
+                "1AE31942917403FF4946B0A83D3D3E05" \
+                "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
+                "5E94BB77B07507233A0BC7BAC8F90F79"
+
+#define RSA_E   "10001"
+
+#define RSA_D   "24BF6185468786FDD303083D25E64EFC" \
+                "66CA472BC44D253102F8B4A9D3BFA750" \
+                "91386C0077937FE33FA3252D28855837" \
+                "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
+                "DF79C5CE07EE72C7F123142198164234" \
+                "CABB724CF78B8173B9F880FC86322407" \
+                "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
+                "071513A1E85B5DFA031F21ECAE91A34D"
+
+#define RSA_P   "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
+                "2C01CAD19EA484A87EA4377637E75500" \
+                "FCB2005C5C7DD6EC4AC023CDA285D796" \
+                "C3D9E75E1EFC42488BB4F1D13AC30A57"
+
+#define RSA_Q   "C000DF51A7C77AE8D7C7370C1FF55B69" \
+                "E211C2B9E5DB1ED0BF61D0D9899620F4" \
+                "910E4168387E3C30AA1E00C339A79508" \
+                "8452DD96A9A5EA5D9DCA68DA636032AF"
+
+#define PT_LEN  24
+#define RSA_PT  "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
+                "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
+
+#if defined(MBEDTLS_PKCS1_V15)
+static int myrand( void *rng_state, unsigned char *output, size_t len )
+{
+#if !defined(__OpenBSD__)
+    size_t i;
+
+    if( rng_state != NULL )
+        rng_state  = NULL;
+
+    for( i = 0; i < len; ++i )
+        output[i] = rand();
+#else
+    if( rng_state != NULL )
+        rng_state = NULL;
+
+    arc4random_buf( output, len );
+#endif /* !OpenBSD */
+
+    return( 0 );
+}
+#endif /* MBEDTLS_PKCS1_V15 */
+
+/*
+ * Checkup routine
+ */
+int mbedtls_rsa_self_test( int verbose )
+{
+    int ret = 0;
+#if defined(MBEDTLS_PKCS1_V15)
+    size_t len;
+    mbedtls_rsa_context rsa;
+    unsigned char rsa_plaintext[PT_LEN];
+    unsigned char rsa_decrypted[PT_LEN];
+    unsigned char rsa_ciphertext[KEY_LEN];
+#if defined(MBEDTLS_SHA1_C)
+    unsigned char sha1sum[20];
+#endif
+
+    mbedtls_mpi K;
+
+    mbedtls_mpi_init( &K );
+    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_N  ) );
+    MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, &K, NULL, NULL, NULL, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_P  ) );
+    MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, &K, NULL, NULL, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_Q  ) );
+    MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, &K, NULL, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_D  ) );
+    MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, &K, NULL ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &K, 16, RSA_E  ) );
+    MBEDTLS_MPI_CHK( mbedtls_rsa_import( &rsa, NULL, NULL, NULL, NULL, &K ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_rsa_complete( &rsa ) );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  RSA key validation: " );
+
+    if( mbedtls_rsa_check_pubkey(  &rsa ) != 0 ||
+        mbedtls_rsa_check_privkey( &rsa ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n  PKCS#1 encryption : " );
+
+    memcpy( rsa_plaintext, RSA_PT, PT_LEN );
+
+    if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC,
+                                   PT_LEN, rsa_plaintext,
+                                   rsa_ciphertext ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n  PKCS#1 decryption : " );
+
+    if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE,
+                                   &len, rsa_ciphertext, rsa_decrypted,
+                                   sizeof(rsa_decrypted) ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+#if defined(MBEDTLS_SHA1_C)
+    if( verbose != 0 )
+        mbedtls_printf( "  PKCS#1 data sign  : " );
+
+    if( mbedtls_sha1_ret( rsa_plaintext, PT_LEN, sha1sum ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        return( 1 );
+    }
+
+    if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL,
+                                MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0,
+                                sha1sum, rsa_ciphertext ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n  PKCS#1 sig. verify: " );
+
+    if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL,
+                                  MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0,
+                                  sha1sum, rsa_ciphertext ) != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        ret = 1;
+        goto cleanup;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+#endif /* MBEDTLS_SHA1_C */
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+cleanup:
+    mbedtls_mpi_free( &K );
+    mbedtls_rsa_free( &rsa );
+#else /* MBEDTLS_PKCS1_V15 */
+    ((void) verbose);
+#endif /* MBEDTLS_PKCS1_V15 */
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_RSA_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/rsa_internal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/rsa_internal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/rsa_internal.c	(revision 398)
@@ -0,0 +1,492 @@
+/*
+ *  Helper functions for the RSA module
+ *
+ *  Copyright (C) 2006-2017, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ *
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+
+#include "mbedtls/rsa.h"
+#include "mbedtls/bignum.h"
+#include "mbedtls/rsa_internal.h"
+
+/*
+ * Compute RSA prime factors from public and private exponents
+ *
+ * Summary of algorithm:
+ * Setting F := lcm(P-1,Q-1), the idea is as follows:
+ *
+ * (a) For any 1 <= X < N with gcd(X,N)=1, we have X^F = 1 modulo N, so X^(F/2)
+ *     is a square root of 1 in Z/NZ. Since Z/NZ ~= Z/PZ x Z/QZ by CRT and the
+ *     square roots of 1 in Z/PZ and Z/QZ are +1 and -1, this leaves the four
+ *     possibilities X^(F/2) = (+-1, +-1). If it happens that X^(F/2) = (-1,+1)
+ *     or (+1,-1), then gcd(X^(F/2) + 1, N) will be equal to one of the prime
+ *     factors of N.
+ *
+ * (b) If we don't know F/2 but (F/2) * K for some odd (!) K, then the same
+ *     construction still applies since (-)^K is the identity on the set of
+ *     roots of 1 in Z/NZ.
+ *
+ * The public and private key primitives (-)^E and (-)^D are mutually inverse
+ * bijections on Z/NZ if and only if (-)^(DE) is the identity on Z/NZ, i.e.
+ * if and only if DE - 1 is a multiple of F, say DE - 1 = F * L.
+ * Splitting L = 2^t * K with K odd, we have
+ *
+ *   DE - 1 = FL = (F/2) * (2^(t+1)) * K,
+ *
+ * so (F / 2) * K is among the numbers
+ *
+ *   (DE - 1) >> 1, (DE - 1) >> 2, ..., (DE - 1) >> ord
+ *
+ * where ord is the order of 2 in (DE - 1).
+ * We can therefore iterate through these numbers apply the construction
+ * of (a) and (b) above to attempt to factor N.
+ *
+ */
+int mbedtls_rsa_deduce_primes( mbedtls_mpi const *N,
+                     mbedtls_mpi const *E, mbedtls_mpi const *D,
+                     mbedtls_mpi *P, mbedtls_mpi *Q )
+{
+    int ret = 0;
+
+    uint16_t attempt;  /* Number of current attempt  */
+    uint16_t iter;     /* Number of squares computed in the current attempt */
+
+    uint16_t order;    /* Order of 2 in DE - 1 */
+
+    mbedtls_mpi T;  /* Holds largest odd divisor of DE - 1     */
+    mbedtls_mpi K;  /* Temporary holding the current candidate */
+
+    const unsigned char primes[] = { 2,
+           3,    5,    7,   11,   13,   17,   19,   23,
+          29,   31,   37,   41,   43,   47,   53,   59,
+          61,   67,   71,   73,   79,   83,   89,   97,
+         101,  103,  107,  109,  113,  127,  131,  137,
+         139,  149,  151,  157,  163,  167,  173,  179,
+         181,  191,  193,  197,  199,  211,  223,  227,
+         229,  233,  239,  241,  251
+    };
+
+    const size_t num_primes = sizeof( primes ) / sizeof( *primes );
+
+    if( P == NULL || Q == NULL || P->p != NULL || Q->p != NULL )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 ||
+        mbedtls_mpi_cmp_int( D, 1 ) <= 0 ||
+        mbedtls_mpi_cmp_mpi( D, N ) >= 0 ||
+        mbedtls_mpi_cmp_int( E, 1 ) <= 0 ||
+        mbedtls_mpi_cmp_mpi( E, N ) >= 0 )
+    {
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+    }
+
+    /*
+     * Initializations and temporary changes
+     */
+
+    mbedtls_mpi_init( &K );
+    mbedtls_mpi_init( &T );
+
+    /* T := DE - 1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, D,  E ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &T, &T, 1 ) );
+
+    if( ( order = (uint16_t) mbedtls_mpi_lsb( &T ) ) == 0 )
+    {
+        ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    /* After this operation, T holds the largest odd divisor of DE - 1. */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &T, order ) );
+
+    /*
+     * Actual work
+     */
+
+    /* Skip trying 2 if N == 1 mod 8 */
+    attempt = 0;
+    if( N->p[0] % 8 == 1 )
+        attempt = 1;
+
+    for( ; attempt < num_primes; ++attempt )
+    {
+        mbedtls_mpi_lset( &K, primes[attempt] );
+
+        /* Check if gcd(K,N) = 1 */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) );
+        if( mbedtls_mpi_cmp_int( P, 1 ) != 0 )
+            continue;
+
+        /* Go through K^T + 1, K^(2T) + 1, K^(4T) + 1, ...
+         * and check whether they have nontrivial GCD with N. */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &K, &K, &T, N,
+                             Q /* temporarily use Q for storing Montgomery
+                                * multiplication helper values */ ) );
+
+        for( iter = 1; iter <= order; ++iter )
+        {
+            /* If we reach 1 prematurely, there's no point
+             * in continuing to square K */
+            if( mbedtls_mpi_cmp_int( &K, 1 ) == 0 )
+                break;
+
+            MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &K, &K, 1 ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( P, &K, N ) );
+
+            if( mbedtls_mpi_cmp_int( P, 1 ) ==  1 &&
+                mbedtls_mpi_cmp_mpi( P, N ) == -1 )
+            {
+                /*
+                 * Have found a nontrivial divisor P of N.
+                 * Set Q := N / P.
+                 */
+
+                MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( Q, NULL, N, P ) );
+                goto cleanup;
+            }
+
+            MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &K ) );
+            MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, N ) );
+        }
+
+        /*
+         * If we get here, then either we prematurely aborted the loop because
+         * we reached 1, or K holds primes[attempt]^(DE - 1) mod N, which must
+         * be 1 if D,E,N were consistent.
+         * Check if that's the case and abort if not, to avoid very long,
+         * yet eventually failing, computations if N,D,E were not sane.
+         */
+        if( mbedtls_mpi_cmp_int( &K, 1 ) != 0 )
+        {
+            break;
+        }
+    }
+
+    ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+
+cleanup:
+
+    mbedtls_mpi_free( &K );
+    mbedtls_mpi_free( &T );
+    return( ret );
+}
+
+/*
+ * Given P, Q and the public exponent E, deduce D.
+ * This is essentially a modular inversion.
+ */
+int mbedtls_rsa_deduce_private_exponent( mbedtls_mpi const *P,
+                                         mbedtls_mpi const *Q,
+                                         mbedtls_mpi const *E,
+                                         mbedtls_mpi *D )
+{
+    int ret = 0;
+    mbedtls_mpi K, L;
+
+    if( D == NULL || mbedtls_mpi_cmp_int( D, 0 ) != 0 )
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+    if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 ||
+        mbedtls_mpi_cmp_int( Q, 1 ) <= 0 ||
+        mbedtls_mpi_cmp_int( E, 0 ) == 0 )
+    {
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+    }
+
+    mbedtls_mpi_init( &K );
+    mbedtls_mpi_init( &L );
+
+    /* Temporarily put K := P-1 and L := Q-1 */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) );
+
+    /* Temporarily put D := gcd(P-1, Q-1) */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( D, &K, &L ) );
+
+    /* K := LCM(P-1, Q-1) */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, &K, &L ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &K, NULL, &K, D ) );
+
+    /* Compute modular inverse of E in LCM(P-1, Q-1) */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( D, E, &K ) );
+
+cleanup:
+
+    mbedtls_mpi_free( &K );
+    mbedtls_mpi_free( &L );
+
+    return( ret );
+}
+
+/*
+ * Check that RSA CRT parameters are in accordance with core parameters.
+ */
+int mbedtls_rsa_validate_crt( const mbedtls_mpi *P,  const mbedtls_mpi *Q,
+                              const mbedtls_mpi *D,  const mbedtls_mpi *DP,
+                              const mbedtls_mpi *DQ, const mbedtls_mpi *QP )
+{
+    int ret = 0;
+
+    mbedtls_mpi K, L;
+    mbedtls_mpi_init( &K );
+    mbedtls_mpi_init( &L );
+
+    /* Check that DP - D == 0 mod P - 1 */
+    if( DP != NULL )
+    {
+        if( P == NULL )
+        {
+            ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+            goto cleanup;
+        }
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DP, D ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) );
+
+        if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+    /* Check that DQ - D == 0 mod Q - 1 */
+    if( DQ != NULL )
+    {
+        if( Q == NULL )
+        {
+            ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+            goto cleanup;
+        }
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DQ, D ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) );
+
+        if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+    /* Check that QP * Q - 1 == 0 mod P */
+    if( QP != NULL )
+    {
+        if( P == NULL || Q == NULL )
+        {
+            ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+            goto cleanup;
+        }
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, QP, Q ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, P ) );
+        if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+cleanup:
+
+    /* Wrap MPI error codes by RSA check failure error code */
+    if( ret != 0 &&
+        ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED &&
+        ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
+    {
+        ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+    }
+
+    mbedtls_mpi_free( &K );
+    mbedtls_mpi_free( &L );
+
+    return( ret );
+}
+
+/*
+ * Check that core RSA parameters are sane.
+ */
+int mbedtls_rsa_validate_params( const mbedtls_mpi *N, const mbedtls_mpi *P,
+                                 const mbedtls_mpi *Q, const mbedtls_mpi *D,
+                                 const mbedtls_mpi *E,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng )
+{
+    int ret = 0;
+    mbedtls_mpi K, L;
+
+    mbedtls_mpi_init( &K );
+    mbedtls_mpi_init( &L );
+
+    /*
+     * Step 1: If PRNG provided, check that P and Q are prime
+     */
+
+#if defined(MBEDTLS_GENPRIME)
+    /*
+     * When generating keys, the strongest security we support aims for an error
+     * rate of at most 2^-100 and we are aiming for the same certainty here as
+     * well.
+     */
+    if( f_rng != NULL && P != NULL &&
+        ( ret = mbedtls_mpi_is_prime_ext( P, 50, f_rng, p_rng ) ) != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+        goto cleanup;
+    }
+
+    if( f_rng != NULL && Q != NULL &&
+        ( ret = mbedtls_mpi_is_prime_ext( Q, 50, f_rng, p_rng ) ) != 0 )
+    {
+        ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+        goto cleanup;
+    }
+#else
+    ((void) f_rng);
+    ((void) p_rng);
+#endif /* MBEDTLS_GENPRIME */
+
+    /*
+     * Step 2: Check that 1 < N = P * Q
+     */
+
+    if( P != NULL && Q != NULL && N != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, P, Q ) );
+        if( mbedtls_mpi_cmp_int( N, 1 )  <= 0 ||
+            mbedtls_mpi_cmp_mpi( &K, N ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+    /*
+     * Step 3: Check and 1 < D, E < N if present.
+     */
+
+    if( N != NULL && D != NULL && E != NULL )
+    {
+        if ( mbedtls_mpi_cmp_int( D, 1 ) <= 0 ||
+             mbedtls_mpi_cmp_int( E, 1 ) <= 0 ||
+             mbedtls_mpi_cmp_mpi( D, N ) >= 0 ||
+             mbedtls_mpi_cmp_mpi( E, N ) >= 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+    /*
+     * Step 4: Check that D, E are inverse modulo P-1 and Q-1
+     */
+
+    if( P != NULL && Q != NULL && D != NULL && E != NULL )
+    {
+        if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 ||
+            mbedtls_mpi_cmp_int( Q, 1 ) <= 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+
+        /* Compute DE-1 mod P-1 */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, P, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) );
+        if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+
+        /* Compute DE-1 mod Q-1 */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) );
+        if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+cleanup:
+
+    mbedtls_mpi_free( &K );
+    mbedtls_mpi_free( &L );
+
+    /* Wrap MPI error codes by RSA check failure error code */
+    if( ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED )
+    {
+        ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+    }
+
+    return( ret );
+}
+
+int mbedtls_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                            const mbedtls_mpi *D, mbedtls_mpi *DP,
+                            mbedtls_mpi *DQ, mbedtls_mpi *QP )
+{
+    int ret = 0;
+    mbedtls_mpi K;
+    mbedtls_mpi_init( &K );
+
+    /* DP = D mod P-1 */
+    if( DP != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1  ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DP, D, &K ) );
+    }
+
+    /* DQ = D mod Q-1 */
+    if( DQ != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1  ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( DQ, D, &K ) );
+    }
+
+    /* QP = Q^{-1} mod P */
+    if( QP != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( QP, Q, P ) );
+    }
+
+cleanup:
+    mbedtls_mpi_free( &K );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_RSA_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/sha1.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/sha1.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/sha1.c	(revision 398)
@@ -0,0 +1,571 @@
+/*
+ *  FIPS-180-1 compliant SHA-1 implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The SHA-1 standard was published by NIST in 1993.
+ *
+ *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+
+#include "mbedtls/sha1.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#define SHA1_VALIDATE_RET(cond)                             \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA1_BAD_INPUT_DATA )
+
+#define SHA1_VALIDATE(cond)  MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if !defined(MBEDTLS_SHA1_ALT)
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_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
+
+void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
+{
+    SHA1_VALIDATE( ctx != NULL );
+
+    memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
+}
+
+void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
+}
+
+void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
+                         const mbedtls_sha1_context *src )
+{
+    SHA1_VALIDATE( dst != NULL );
+    SHA1_VALIDATE( src != NULL );
+
+    *dst = *src;
+}
+
+/*
+ * SHA-1 context setup
+ */
+int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
+{
+    SHA1_VALIDATE_RET( ctx != NULL );
+
+    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;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
+{
+    mbedtls_sha1_starts_ret( ctx );
+}
+#endif
+
+#if !defined(MBEDTLS_SHA1_PROCESS_ALT)
+int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
+                                   const unsigned char data[64] )
+{
+    uint32_t temp, W[16], A, B, C, D, E;
+
+    SHA1_VALIDATE_RET( ctx != NULL );
+    SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
+
+    GET_UINT32_BE( W[ 0], data,  0 );
+    GET_UINT32_BE( W[ 1], data,  4 );
+    GET_UINT32_BE( W[ 2], data,  8 );
+    GET_UINT32_BE( W[ 3], data, 12 );
+    GET_UINT32_BE( W[ 4], data, 16 );
+    GET_UINT32_BE( W[ 5], data, 20 );
+    GET_UINT32_BE( W[ 6], data, 24 );
+    GET_UINT32_BE( W[ 7], data, 28 );
+    GET_UINT32_BE( W[ 8], data, 32 );
+    GET_UINT32_BE( W[ 9], data, 36 );
+    GET_UINT32_BE( W[10], data, 40 );
+    GET_UINT32_BE( W[11], data, 44 );
+    GET_UINT32_BE( W[12], data, 48 );
+    GET_UINT32_BE( W[13], data, 52 );
+    GET_UINT32_BE( W[14], data, 56 );
+    GET_UINT32_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;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha1_process( mbedtls_sha1_context *ctx,
+                           const unsigned char data[64] )
+{
+    mbedtls_internal_sha1_process( ctx, data );
+}
+#endif
+#endif /* !MBEDTLS_SHA1_PROCESS_ALT */
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
+                             const unsigned char *input,
+                             size_t ilen )
+{
+    int ret;
+    size_t fill;
+    uint32_t left;
+
+    SHA1_VALIDATE_RET( ctx != NULL );
+    SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
+
+    if( ilen == 0 )
+        return( 0 );
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += (uint32_t) ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (uint32_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, fill );
+
+        if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        if( ( ret = mbedtls_internal_sha1_process( ctx, input ) ) != 0 )
+            return( ret );
+
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+        memcpy( (void *) (ctx->buffer + left), input, ilen );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
+                          const unsigned char *input,
+                          size_t ilen )
+{
+    mbedtls_sha1_update_ret( ctx, input, ilen );
+}
+#endif
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
+                             unsigned char output[20] )
+{
+    int ret;
+    uint32_t used;
+    uint32_t high, low;
+
+    SHA1_VALIDATE_RET( ctx != NULL );
+    SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
+
+    /*
+     * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
+     */
+    used = ctx->total[0] & 0x3F;
+
+    ctx->buffer[used++] = 0x80;
+
+    if( used <= 56 )
+    {
+        /* Enough room for padding + length in current block */
+        memset( ctx->buffer + used, 0, 56 - used );
+    }
+    else
+    {
+        /* We'll need an extra block */
+        memset( ctx->buffer + used, 0, 64 - used );
+
+        if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
+        memset( ctx->buffer, 0, 56 );
+    }
+
+    /*
+     * Add message length
+     */
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT32_BE( high, ctx->buffer, 56 );
+    PUT_UINT32_BE( low,  ctx->buffer, 60 );
+
+    if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 )
+        return( ret );
+
+    /*
+     * Output final state
+     */
+    PUT_UINT32_BE( ctx->state[0], output,  0 );
+    PUT_UINT32_BE( ctx->state[1], output,  4 );
+    PUT_UINT32_BE( ctx->state[2], output,  8 );
+    PUT_UINT32_BE( ctx->state[3], output, 12 );
+    PUT_UINT32_BE( ctx->state[4], output, 16 );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha1_finish( mbedtls_sha1_context *ctx,
+                          unsigned char output[20] )
+{
+    mbedtls_sha1_finish_ret( ctx, output );
+}
+#endif
+
+#endif /* !MBEDTLS_SHA1_ALT */
+
+/*
+ * output = SHA-1( input buffer )
+ */
+int mbedtls_sha1_ret( const unsigned char *input,
+                      size_t ilen,
+                      unsigned char output[20] )
+{
+    int ret;
+    mbedtls_sha1_context ctx;
+
+    SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
+    SHA1_VALIDATE_RET( (unsigned char *)output != NULL );
+
+    mbedtls_sha1_init( &ctx );
+
+    if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha1_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha1_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_sha1_free( &ctx );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha1( const unsigned char *input,
+                   size_t ilen,
+                   unsigned char output[20] )
+{
+    mbedtls_sha1_ret( input, ilen, output );
+}
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+/*
+ * FIPS-180-1 test vectors
+ */
+static const unsigned char sha1_test_buf[3][57] =
+{
+    { "abc" },
+    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+    { "" }
+};
+
+static const size_t sha1_test_buflen[3] =
+{
+    3, 56, 1000
+};
+
+static const unsigned char sha1_test_sum[3][20] =
+{
+    { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
+      0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
+    { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
+      0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
+    { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
+      0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
+};
+
+/*
+ * Checkup routine
+ */
+int mbedtls_sha1_self_test( int verbose )
+{
+    int i, j, buflen, ret = 0;
+    unsigned char buf[1024];
+    unsigned char sha1sum[20];
+    mbedtls_sha1_context ctx;
+
+    mbedtls_sha1_init( &ctx );
+
+    /*
+     * SHA-1
+     */
+    for( i = 0; i < 3; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  SHA-1 test #%d: ", i + 1 );
+
+        if( ( ret = mbedtls_sha1_starts_ret( &ctx ) ) != 0 )
+            goto fail;
+
+        if( i == 2 )
+        {
+            memset( buf, 'a', buflen = 1000 );
+
+            for( j = 0; j < 1000; j++ )
+            {
+                ret = mbedtls_sha1_update_ret( &ctx, buf, buflen );
+                if( ret != 0 )
+                    goto fail;
+            }
+        }
+        else
+        {
+            ret = mbedtls_sha1_update_ret( &ctx, sha1_test_buf[i],
+                                           sha1_test_buflen[i] );
+            if( ret != 0 )
+                goto fail;
+        }
+
+        if( ( ret = mbedtls_sha1_finish_ret( &ctx, sha1sum ) ) != 0 )
+            goto fail;
+
+        if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
+        {
+            ret = 1;
+            goto fail;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    goto exit;
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+exit:
+    mbedtls_sha1_free( &ctx );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_SHA1_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/sha256.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/sha256.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/sha256.c	(revision 398)
@@ -0,0 +1,585 @@
+/*
+ *  FIPS-180-2 compliant SHA-256 implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The SHA-256 Secure Hash Standard was published by NIST in 2002.
+ *
+ *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+
+#include "mbedtls/sha256.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_printf printf
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#define SHA256_VALIDATE_RET(cond)                           \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA256_BAD_INPUT_DATA )
+#define SHA256_VALIDATE(cond)  MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if !defined(MBEDTLS_SHA256_ALT)
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+do {                                                    \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+} while( 0 )
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i)                            \
+do {                                                    \
+    (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)       );       \
+} while( 0 )
+#endif
+
+void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
+{
+    SHA256_VALIDATE( ctx != NULL );
+
+    memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
+}
+
+void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
+}
+
+void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
+                           const mbedtls_sha256_context *src )
+{
+    SHA256_VALIDATE( dst != NULL );
+    SHA256_VALIDATE( src != NULL );
+
+    *dst = *src;
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
+{
+    SHA256_VALIDATE_RET( ctx != NULL );
+    SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
+
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    if( is224 == 0 )
+    {
+        /* SHA-256 */
+        ctx->state[0] = 0x6A09E667;
+        ctx->state[1] = 0xBB67AE85;
+        ctx->state[2] = 0x3C6EF372;
+        ctx->state[3] = 0xA54FF53A;
+        ctx->state[4] = 0x510E527F;
+        ctx->state[5] = 0x9B05688C;
+        ctx->state[6] = 0x1F83D9AB;
+        ctx->state[7] = 0x5BE0CD19;
+    }
+    else
+    {
+        /* SHA-224 */
+        ctx->state[0] = 0xC1059ED8;
+        ctx->state[1] = 0x367CD507;
+        ctx->state[2] = 0x3070DD17;
+        ctx->state[3] = 0xF70E5939;
+        ctx->state[4] = 0xFFC00B31;
+        ctx->state[5] = 0x68581511;
+        ctx->state[6] = 0x64F98FA7;
+        ctx->state[7] = 0xBEFA4FA4;
+    }
+
+    ctx->is224 = is224;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha256_starts( mbedtls_sha256_context *ctx,
+                            int is224 )
+{
+    mbedtls_sha256_starts_ret( ctx, is224 );
+}
+#endif
+
+#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
+static const uint32_t K[] =
+{
+    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,
+};
+
+#define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
+
+#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))
+#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))
+
+#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
+#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
+
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+
+#define R(t)                                    \
+(                                               \
+    W[t] = S1(W[t -  2]) + W[t -  7] +          \
+           S0(W[t - 15]) + W[t - 16]            \
+)
+
+#define P(a,b,c,d,e,f,g,h,x,K)                  \
+{                                               \
+    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
+    temp2 = S2(a) + F0(a,b,c);                  \
+    d += temp1; h = temp1 + temp2;              \
+}
+
+int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
+                                const unsigned char data[64] )
+{
+    uint32_t temp1, temp2, W[64];
+    uint32_t A[8];
+    unsigned int i;
+
+    SHA256_VALIDATE_RET( ctx != NULL );
+    SHA256_VALIDATE_RET( (const unsigned char *)data != NULL );
+
+    for( i = 0; i < 8; i++ )
+        A[i] = ctx->state[i];
+
+#if defined(MBEDTLS_SHA256_SMALLER)
+    for( i = 0; i < 64; i++ )
+    {
+        if( i < 16 )
+            GET_UINT32_BE( W[i], data, 4 * i );
+        else
+            R( i );
+
+        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
+
+        temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
+        A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
+    }
+#else /* MBEDTLS_SHA256_SMALLER */
+    for( i = 0; i < 16; i++ )
+        GET_UINT32_BE( W[i], data, 4 * i );
+
+    for( i = 0; i < 16; i += 8 )
+    {
+        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
+        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
+        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
+        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
+        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
+        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
+        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
+        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
+    }
+
+    for( i = 16; i < 64; i += 8 )
+    {
+        P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
+        P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
+        P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
+        P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
+        P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
+        P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
+        P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
+        P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
+    }
+#endif /* MBEDTLS_SHA256_SMALLER */
+
+    for( i = 0; i < 8; i++ )
+        ctx->state[i] += A[i];
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha256_process( mbedtls_sha256_context *ctx,
+                             const unsigned char data[64] )
+{
+    mbedtls_internal_sha256_process( ctx, data );
+}
+#endif
+#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
+
+/*
+ * SHA-256 process buffer
+ */
+int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
+                               const unsigned char *input,
+                               size_t ilen )
+{
+    int ret;
+    size_t fill;
+    uint32_t left;
+
+    SHA256_VALIDATE_RET( ctx != NULL );
+    SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
+
+    if( ilen == 0 )
+        return( 0 );
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += (uint32_t) ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (uint32_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, fill );
+
+        if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        if( ( ret = mbedtls_internal_sha256_process( ctx, input ) ) != 0 )
+            return( ret );
+
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+        memcpy( (void *) (ctx->buffer + left), input, ilen );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen )
+{
+    mbedtls_sha256_update_ret( ctx, input, ilen );
+}
+#endif
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
+                               unsigned char output[32] )
+{
+    int ret;
+    uint32_t used;
+    uint32_t high, low;
+
+    SHA256_VALIDATE_RET( ctx != NULL );
+    SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
+
+    /*
+     * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
+     */
+    used = ctx->total[0] & 0x3F;
+
+    ctx->buffer[used++] = 0x80;
+
+    if( used <= 56 )
+    {
+        /* Enough room for padding + length in current block */
+        memset( ctx->buffer + used, 0, 56 - used );
+    }
+    else
+    {
+        /* We'll need an extra block */
+        memset( ctx->buffer + used, 0, 64 - used );
+
+        if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
+        memset( ctx->buffer, 0, 56 );
+    }
+
+    /*
+     * Add message length
+     */
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT32_BE( high, ctx->buffer, 56 );
+    PUT_UINT32_BE( low,  ctx->buffer, 60 );
+
+    if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
+        return( ret );
+
+    /*
+     * Output final state
+     */
+    PUT_UINT32_BE( ctx->state[0], output,  0 );
+    PUT_UINT32_BE( ctx->state[1], output,  4 );
+    PUT_UINT32_BE( ctx->state[2], output,  8 );
+    PUT_UINT32_BE( ctx->state[3], output, 12 );
+    PUT_UINT32_BE( ctx->state[4], output, 16 );
+    PUT_UINT32_BE( ctx->state[5], output, 20 );
+    PUT_UINT32_BE( ctx->state[6], output, 24 );
+
+    if( ctx->is224 == 0 )
+        PUT_UINT32_BE( ctx->state[7], output, 28 );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha256_finish( mbedtls_sha256_context *ctx,
+                            unsigned char output[32] )
+{
+    mbedtls_sha256_finish_ret( ctx, output );
+}
+#endif
+
+#endif /* !MBEDTLS_SHA256_ALT */
+
+/*
+ * output = SHA-256( input buffer )
+ */
+int mbedtls_sha256_ret( const unsigned char *input,
+                        size_t ilen,
+                        unsigned char output[32],
+                        int is224 )
+{
+    int ret;
+    mbedtls_sha256_context ctx;
+
+    SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
+    SHA256_VALIDATE_RET( ilen == 0 || input != NULL );
+    SHA256_VALIDATE_RET( (unsigned char *)output != NULL );
+
+    mbedtls_sha256_init( &ctx );
+
+    if( ( ret = mbedtls_sha256_starts_ret( &ctx, is224 ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha256_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha256_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_sha256_free( &ctx );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha256( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[32],
+                     int is224 )
+{
+    mbedtls_sha256_ret( input, ilen, output, is224 );
+}
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+/*
+ * FIPS-180-2 test vectors
+ */
+static const unsigned char sha256_test_buf[3][57] =
+{
+    { "abc" },
+    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+    { "" }
+};
+
+static const size_t sha256_test_buflen[3] =
+{
+    3, 56, 1000
+};
+
+static const unsigned char sha256_test_sum[6][32] =
+{
+    /*
+     * SHA-224 test vectors
+     */
+    { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
+      0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
+      0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
+      0xE3, 0x6C, 0x9D, 0xA7 },
+    { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
+      0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
+      0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
+      0x52, 0x52, 0x25, 0x25 },
+    { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
+      0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
+      0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
+      0x4E, 0xE7, 0xAD, 0x67 },
+
+    /*
+     * SHA-256 test vectors
+     */
+    { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
+      0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
+      0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
+      0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
+    { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
+      0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
+      0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
+      0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
+    { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
+      0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
+      0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
+      0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
+};
+
+/*
+ * Checkup routine
+ */
+int mbedtls_sha256_self_test( int verbose )
+{
+    int i, j, k, buflen, ret = 0;
+    unsigned char *buf;
+    unsigned char sha256sum[32];
+    mbedtls_sha256_context ctx;
+
+    buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
+    if( NULL == buf )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "Buffer allocation failed\n" );
+
+        return( 1 );
+    }
+
+    mbedtls_sha256_init( &ctx );
+
+    for( i = 0; i < 6; i++ )
+    {
+        j = i % 3;
+        k = i < 3;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  SHA-%d test #%d: ", 256 - k * 32, j + 1 );
+
+        if( ( ret = mbedtls_sha256_starts_ret( &ctx, k ) ) != 0 )
+            goto fail;
+
+        if( j == 2 )
+        {
+            memset( buf, 'a', buflen = 1000 );
+
+            for( j = 0; j < 1000; j++ )
+            {
+                ret = mbedtls_sha256_update_ret( &ctx, buf, buflen );
+                if( ret != 0 )
+                    goto fail;
+            }
+
+        }
+        else
+        {
+            ret = mbedtls_sha256_update_ret( &ctx, sha256_test_buf[j],
+                                             sha256_test_buflen[j] );
+            if( ret != 0 )
+                 goto fail;
+        }
+
+        if( ( ret = mbedtls_sha256_finish_ret( &ctx, sha256sum ) ) != 0 )
+            goto fail;
+
+
+        if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 )
+        {
+            ret = 1;
+            goto fail;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    goto exit;
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+exit:
+    mbedtls_sha256_free( &ctx );
+    mbedtls_free( buf );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_SHA256_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/sha512.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/sha512.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/sha512.c	(revision 398)
@@ -0,0 +1,635 @@
+/*
+ *  FIPS-180-2 compliant SHA-384/512 implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The SHA-512 Secure Hash Standard was published by NIST in 2002.
+ *
+ *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+
+#include "mbedtls/sha512.h"
+#include "mbedtls/platform_util.h"
+
+#if defined(_MSC_VER) || defined(__WATCOMC__)
+  #define UL64(x) x##ui64
+#else
+  #define UL64(x) x##ULL
+#endif
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_printf printf
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#define SHA512_VALIDATE_RET(cond)                           \
+    MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_SHA512_BAD_INPUT_DATA )
+#define SHA512_VALIDATE(cond)  MBEDTLS_INTERNAL_VALIDATE( cond )
+
+#if !defined(MBEDTLS_SHA512_ALT)
+
+/*
+ * 64-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT64_BE
+#define GET_UINT64_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \
+        | ( (uint64_t) (b)[(i) + 1] << 48 )       \
+        | ( (uint64_t) (b)[(i) + 2] << 40 )       \
+        | ( (uint64_t) (b)[(i) + 3] << 32 )       \
+        | ( (uint64_t) (b)[(i) + 4] << 24 )       \
+        | ( (uint64_t) (b)[(i) + 5] << 16 )       \
+        | ( (uint64_t) (b)[(i) + 6] <<  8 )       \
+        | ( (uint64_t) (b)[(i) + 7]       );      \
+}
+#endif /* GET_UINT64_BE */
+
+#ifndef PUT_UINT64_BE
+#define PUT_UINT64_BE(n,b,i)                            \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 56 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 48 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >> 40 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n) >> 32 );       \
+    (b)[(i) + 4] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 5] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 6] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 7] = (unsigned char) ( (n)       );       \
+}
+#endif /* PUT_UINT64_BE */
+
+void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
+{
+    SHA512_VALIDATE( ctx != NULL );
+
+    memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
+}
+
+void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
+}
+
+void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
+                           const mbedtls_sha512_context *src )
+{
+    SHA512_VALIDATE( dst != NULL );
+    SHA512_VALIDATE( src != NULL );
+
+    *dst = *src;
+}
+
+/*
+ * SHA-512 context setup
+ */
+int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
+{
+    SHA512_VALIDATE_RET( ctx != NULL );
+    SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
+
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    if( is384 == 0 )
+    {
+        /* SHA-512 */
+        ctx->state[0] = UL64(0x6A09E667F3BCC908);
+        ctx->state[1] = UL64(0xBB67AE8584CAA73B);
+        ctx->state[2] = UL64(0x3C6EF372FE94F82B);
+        ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
+        ctx->state[4] = UL64(0x510E527FADE682D1);
+        ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
+        ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
+        ctx->state[7] = UL64(0x5BE0CD19137E2179);
+    }
+    else
+    {
+        /* SHA-384 */
+        ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
+        ctx->state[1] = UL64(0x629A292A367CD507);
+        ctx->state[2] = UL64(0x9159015A3070DD17);
+        ctx->state[3] = UL64(0x152FECD8F70E5939);
+        ctx->state[4] = UL64(0x67332667FFC00B31);
+        ctx->state[5] = UL64(0x8EB44A8768581511);
+        ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
+        ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
+    }
+
+    ctx->is384 = is384;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
+                            int is384 )
+{
+    mbedtls_sha512_starts_ret( ctx, is384 );
+}
+#endif
+
+#if !defined(MBEDTLS_SHA512_PROCESS_ALT)
+
+/*
+ * Round constants
+ */
+static const uint64_t K[80] =
+{
+    UL64(0x428A2F98D728AE22),  UL64(0x7137449123EF65CD),
+    UL64(0xB5C0FBCFEC4D3B2F),  UL64(0xE9B5DBA58189DBBC),
+    UL64(0x3956C25BF348B538),  UL64(0x59F111F1B605D019),
+    UL64(0x923F82A4AF194F9B),  UL64(0xAB1C5ED5DA6D8118),
+    UL64(0xD807AA98A3030242),  UL64(0x12835B0145706FBE),
+    UL64(0x243185BE4EE4B28C),  UL64(0x550C7DC3D5FFB4E2),
+    UL64(0x72BE5D74F27B896F),  UL64(0x80DEB1FE3B1696B1),
+    UL64(0x9BDC06A725C71235),  UL64(0xC19BF174CF692694),
+    UL64(0xE49B69C19EF14AD2),  UL64(0xEFBE4786384F25E3),
+    UL64(0x0FC19DC68B8CD5B5),  UL64(0x240CA1CC77AC9C65),
+    UL64(0x2DE92C6F592B0275),  UL64(0x4A7484AA6EA6E483),
+    UL64(0x5CB0A9DCBD41FBD4),  UL64(0x76F988DA831153B5),
+    UL64(0x983E5152EE66DFAB),  UL64(0xA831C66D2DB43210),
+    UL64(0xB00327C898FB213F),  UL64(0xBF597FC7BEEF0EE4),
+    UL64(0xC6E00BF33DA88FC2),  UL64(0xD5A79147930AA725),
+    UL64(0x06CA6351E003826F),  UL64(0x142929670A0E6E70),
+    UL64(0x27B70A8546D22FFC),  UL64(0x2E1B21385C26C926),
+    UL64(0x4D2C6DFC5AC42AED),  UL64(0x53380D139D95B3DF),
+    UL64(0x650A73548BAF63DE),  UL64(0x766A0ABB3C77B2A8),
+    UL64(0x81C2C92E47EDAEE6),  UL64(0x92722C851482353B),
+    UL64(0xA2BFE8A14CF10364),  UL64(0xA81A664BBC423001),
+    UL64(0xC24B8B70D0F89791),  UL64(0xC76C51A30654BE30),
+    UL64(0xD192E819D6EF5218),  UL64(0xD69906245565A910),
+    UL64(0xF40E35855771202A),  UL64(0x106AA07032BBD1B8),
+    UL64(0x19A4C116B8D2D0C8),  UL64(0x1E376C085141AB53),
+    UL64(0x2748774CDF8EEB99),  UL64(0x34B0BCB5E19B48A8),
+    UL64(0x391C0CB3C5C95A63),  UL64(0x4ED8AA4AE3418ACB),
+    UL64(0x5B9CCA4F7763E373),  UL64(0x682E6FF3D6B2B8A3),
+    UL64(0x748F82EE5DEFB2FC),  UL64(0x78A5636F43172F60),
+    UL64(0x84C87814A1F0AB72),  UL64(0x8CC702081A6439EC),
+    UL64(0x90BEFFFA23631E28),  UL64(0xA4506CEBDE82BDE9),
+    UL64(0xBEF9A3F7B2C67915),  UL64(0xC67178F2E372532B),
+    UL64(0xCA273ECEEA26619C),  UL64(0xD186B8C721C0C207),
+    UL64(0xEADA7DD6CDE0EB1E),  UL64(0xF57D4F7FEE6ED178),
+    UL64(0x06F067AA72176FBA),  UL64(0x0A637DC5A2C898A6),
+    UL64(0x113F9804BEF90DAE),  UL64(0x1B710B35131C471B),
+    UL64(0x28DB77F523047D84),  UL64(0x32CAAB7B40C72493),
+    UL64(0x3C9EBE0A15C9BEBC),  UL64(0x431D67C49C100D4C),
+    UL64(0x4CC5D4BECB3E42B6),  UL64(0x597F299CFC657E2A),
+    UL64(0x5FCB6FAB3AD6FAEC),  UL64(0x6C44198C4A475817)
+};
+
+int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
+                                     const unsigned char data[128] )
+{
+    int i;
+    uint64_t temp1, temp2, W[80];
+    uint64_t A, B, C, D, E, F, G, H;
+
+    SHA512_VALIDATE_RET( ctx != NULL );
+    SHA512_VALIDATE_RET( (const unsigned char *)data != NULL );
+
+#define  SHR(x,n) (x >> n)
+#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
+
+#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^  SHR(x, 7))
+#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^  SHR(x, 6))
+
+#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
+#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
+
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+
+#define P(a,b,c,d,e,f,g,h,x,K)                  \
+{                                               \
+    temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
+    temp2 = S2(a) + F0(a,b,c);                  \
+    d += temp1; h = temp1 + temp2;              \
+}
+
+    for( i = 0; i < 16; i++ )
+    {
+        GET_UINT64_BE( W[i], data, i << 3 );
+    }
+
+    for( ; i < 80; i++ )
+    {
+        W[i] = S1(W[i -  2]) + W[i -  7] +
+               S0(W[i - 15]) + W[i - 16];
+    }
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+    E = ctx->state[4];
+    F = ctx->state[5];
+    G = ctx->state[6];
+    H = ctx->state[7];
+    i = 0;
+
+    do
+    {
+        P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
+        P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
+        P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
+        P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
+        P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
+        P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
+        P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
+        P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
+    }
+    while( i < 80 );
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+    ctx->state[4] += E;
+    ctx->state[5] += F;
+    ctx->state[6] += G;
+    ctx->state[7] += H;
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha512_process( mbedtls_sha512_context *ctx,
+                             const unsigned char data[128] )
+{
+    mbedtls_internal_sha512_process( ctx, data );
+}
+#endif
+#endif /* !MBEDTLS_SHA512_PROCESS_ALT */
+
+/*
+ * SHA-512 process buffer
+ */
+int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
+                               const unsigned char *input,
+                               size_t ilen )
+{
+    int ret;
+    size_t fill;
+    unsigned int left;
+
+    SHA512_VALIDATE_RET( ctx != NULL );
+    SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
+
+    if( ilen == 0 )
+        return( 0 );
+
+    left = (unsigned int) (ctx->total[0] & 0x7F);
+    fill = 128 - left;
+
+    ctx->total[0] += (uint64_t) ilen;
+
+    if( ctx->total[0] < (uint64_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, fill );
+
+        if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 128 )
+    {
+        if( ( ret = mbedtls_internal_sha512_process( ctx, input ) ) != 0 )
+            return( ret );
+
+        input += 128;
+        ilen  -= 128;
+    }
+
+    if( ilen > 0 )
+        memcpy( (void *) (ctx->buffer + left), input, ilen );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
+                            const unsigned char *input,
+                            size_t ilen )
+{
+    mbedtls_sha512_update_ret( ctx, input, ilen );
+}
+#endif
+
+/*
+ * SHA-512 final digest
+ */
+int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
+                               unsigned char output[64] )
+{
+    int ret;
+    unsigned used;
+    uint64_t high, low;
+
+    SHA512_VALIDATE_RET( ctx != NULL );
+    SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
+
+    /*
+     * Add padding: 0x80 then 0x00 until 16 bytes remain for the length
+     */
+    used = ctx->total[0] & 0x7F;
+
+    ctx->buffer[used++] = 0x80;
+
+    if( used <= 112 )
+    {
+        /* Enough room for padding + length in current block */
+        memset( ctx->buffer + used, 0, 112 - used );
+    }
+    else
+    {
+        /* We'll need an extra block */
+        memset( ctx->buffer + used, 0, 128 - used );
+
+        if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
+            return( ret );
+
+        memset( ctx->buffer, 0, 112 );
+    }
+
+    /*
+     * Add message length
+     */
+    high = ( ctx->total[0] >> 61 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT64_BE( high, ctx->buffer, 112 );
+    PUT_UINT64_BE( low,  ctx->buffer, 120 );
+
+    if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
+        return( ret );
+
+    /*
+     * Output final state
+     */
+    PUT_UINT64_BE( ctx->state[0], output,  0 );
+    PUT_UINT64_BE( ctx->state[1], output,  8 );
+    PUT_UINT64_BE( ctx->state[2], output, 16 );
+    PUT_UINT64_BE( ctx->state[3], output, 24 );
+    PUT_UINT64_BE( ctx->state[4], output, 32 );
+    PUT_UINT64_BE( ctx->state[5], output, 40 );
+
+    if( ctx->is384 == 0 )
+    {
+        PUT_UINT64_BE( ctx->state[6], output, 48 );
+        PUT_UINT64_BE( ctx->state[7], output, 56 );
+    }
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha512_finish( mbedtls_sha512_context *ctx,
+                            unsigned char output[64] )
+{
+    mbedtls_sha512_finish_ret( ctx, output );
+}
+#endif
+
+#endif /* !MBEDTLS_SHA512_ALT */
+
+/*
+ * output = SHA-512( input buffer )
+ */
+int mbedtls_sha512_ret( const unsigned char *input,
+                    size_t ilen,
+                    unsigned char output[64],
+                    int is384 )
+{
+    int ret;
+    mbedtls_sha512_context ctx;
+
+    SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
+    SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
+    SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
+
+    mbedtls_sha512_init( &ctx );
+
+    if( ( ret = mbedtls_sha512_starts_ret( &ctx, is384 ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha512_update_ret( &ctx, input, ilen ) ) != 0 )
+        goto exit;
+
+    if( ( ret = mbedtls_sha512_finish_ret( &ctx, output ) ) != 0 )
+        goto exit;
+
+exit:
+    mbedtls_sha512_free( &ctx );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+void mbedtls_sha512( const unsigned char *input,
+                     size_t ilen,
+                     unsigned char output[64],
+                     int is384 )
+{
+    mbedtls_sha512_ret( input, ilen, output, is384 );
+}
+#endif
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/*
+ * FIPS-180-2 test vectors
+ */
+static const unsigned char sha512_test_buf[3][113] =
+{
+    { "abc" },
+    { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+      "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" },
+    { "" }
+};
+
+static const size_t sha512_test_buflen[3] =
+{
+    3, 112, 1000
+};
+
+static const unsigned char sha512_test_sum[6][64] =
+{
+    /*
+     * SHA-384 test vectors
+     */
+    { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B,
+      0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07,
+      0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63,
+      0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED,
+      0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23,
+      0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 },
+    { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8,
+      0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47,
+      0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2,
+      0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12,
+      0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9,
+      0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 },
+    { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB,
+      0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C,
+      0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52,
+      0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
+      0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
+      0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
+
+    /*
+     * SHA-512 test vectors
+     */
+    { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA,
+      0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31,
+      0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2,
+      0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A,
+      0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8,
+      0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD,
+      0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E,
+      0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F },
+    { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA,
+      0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F,
+      0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1,
+      0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18,
+      0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4,
+      0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A,
+      0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54,
+      0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 },
+    { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64,
+      0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63,
+      0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28,
+      0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB,
+      0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A,
+      0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B,
+      0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E,
+      0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
+};
+
+/*
+ * Checkup routine
+ */
+int mbedtls_sha512_self_test( int verbose )
+{
+    int i, j, k, buflen, ret = 0;
+    unsigned char *buf;
+    unsigned char sha512sum[64];
+    mbedtls_sha512_context ctx;
+
+    buf = mbedtls_calloc( 1024, sizeof(unsigned char) );
+    if( NULL == buf )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "Buffer allocation failed\n" );
+
+        return( 1 );
+    }
+
+    mbedtls_sha512_init( &ctx );
+
+    for( i = 0; i < 6; i++ )
+    {
+        j = i % 3;
+        k = i < 3;
+
+        if( verbose != 0 )
+            mbedtls_printf( "  SHA-%d test #%d: ", 512 - k * 128, j + 1 );
+
+        if( ( ret = mbedtls_sha512_starts_ret( &ctx, k ) ) != 0 )
+            goto fail;
+
+        if( j == 2 )
+        {
+            memset( buf, 'a', buflen = 1000 );
+
+            for( j = 0; j < 1000; j++ )
+            {
+                ret = mbedtls_sha512_update_ret( &ctx, buf, buflen );
+                if( ret != 0 )
+                    goto fail;
+            }
+        }
+        else
+        {
+            ret = mbedtls_sha512_update_ret( &ctx, sha512_test_buf[j],
+                                             sha512_test_buflen[j] );
+            if( ret != 0 )
+                goto fail;
+        }
+
+        if( ( ret = mbedtls_sha512_finish_ret( &ctx, sha512sum ) ) != 0 )
+            goto fail;
+
+        if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 )
+        {
+            ret = 1;
+            goto fail;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    goto exit;
+
+fail:
+    if( verbose != 0 )
+        mbedtls_printf( "failed\n" );
+
+exit:
+    mbedtls_sha512_free( &ctx );
+    mbedtls_free( buf );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_SHA512_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_cache.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_cache.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_cache.c	(revision 398)
@@ -0,0 +1,327 @@
+/*
+ *  SSL session cache implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * These session callbacks use a simple chained list
+ * to store and retrieve the session information.
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SSL_CACHE_C)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free      free
+#endif
+
+#include "mbedtls/ssl_cache.h"
+
+#include <string.h>
+
+void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache )
+{
+    memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) );
+
+    cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT;
+    cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES;
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &cache->mutex );
+#endif
+}
+
+int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
+{
+    int ret = 1;
+#if defined(MBEDTLS_HAVE_TIME)
+    mbedtls_time_t t = mbedtls_time( NULL );
+#endif
+    mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
+    mbedtls_ssl_cache_entry *cur, *entry;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_lock( &cache->mutex ) != 0 )
+        return( 1 );
+#endif
+
+    cur = cache->chain;
+    entry = NULL;
+
+    while( cur != NULL )
+    {
+        entry = cur;
+        cur = cur->next;
+
+#if defined(MBEDTLS_HAVE_TIME)
+        if( cache->timeout != 0 &&
+            (int) ( t - entry->timestamp ) > cache->timeout )
+            continue;
+#endif
+
+        if( session->ciphersuite != entry->session.ciphersuite ||
+            session->compression != entry->session.compression ||
+            session->id_len != entry->session.id_len )
+            continue;
+
+        if( memcmp( session->id, entry->session.id,
+                    entry->session.id_len ) != 0 )
+            continue;
+
+        memcpy( session->master, entry->session.master, 48 );
+
+        session->verify_result = entry->session.verify_result;
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+        /*
+         * Restore peer certificate (without rest of the original chain)
+         */
+        if( entry->peer_cert.p != NULL )
+        {
+            if( ( session->peer_cert = mbedtls_calloc( 1,
+                                 sizeof(mbedtls_x509_crt) ) ) == NULL )
+            {
+                ret = 1;
+                goto exit;
+            }
+
+            mbedtls_x509_crt_init( session->peer_cert );
+            if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p,
+                                entry->peer_cert.len ) != 0 )
+            {
+                mbedtls_free( session->peer_cert );
+                session->peer_cert = NULL;
+                ret = 1;
+                goto exit;
+            }
+        }
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+        ret = 0;
+        goto exit;
+    }
+
+exit:
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &cache->mutex ) != 0 )
+        ret = 1;
+#endif
+
+    return( ret );
+}
+
+int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
+{
+    int ret = 1;
+#if defined(MBEDTLS_HAVE_TIME)
+    mbedtls_time_t t = mbedtls_time( NULL ), oldest = 0;
+    mbedtls_ssl_cache_entry *old = NULL;
+#endif
+    mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
+    mbedtls_ssl_cache_entry *cur, *prv;
+    int count = 0;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &cache->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    cur = cache->chain;
+    prv = NULL;
+
+    while( cur != NULL )
+    {
+        count++;
+
+#if defined(MBEDTLS_HAVE_TIME)
+        if( cache->timeout != 0 &&
+            (int) ( t - cur->timestamp ) > cache->timeout )
+        {
+            cur->timestamp = t;
+            break; /* expired, reuse this slot, update timestamp */
+        }
+#endif
+
+        if( memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 )
+            break; /* client reconnected, keep timestamp for session id */
+
+#if defined(MBEDTLS_HAVE_TIME)
+        if( oldest == 0 || cur->timestamp < oldest )
+        {
+            oldest = cur->timestamp;
+            old = cur;
+        }
+#endif
+
+        prv = cur;
+        cur = cur->next;
+    }
+
+    if( cur == NULL )
+    {
+#if defined(MBEDTLS_HAVE_TIME)
+        /*
+         * Reuse oldest entry if max_entries reached
+         */
+        if( count >= cache->max_entries )
+        {
+            if( old == NULL )
+            {
+                ret = 1;
+                goto exit;
+            }
+
+            cur = old;
+        }
+#else /* MBEDTLS_HAVE_TIME */
+        /*
+         * Reuse first entry in chain if max_entries reached,
+         * but move to last place
+         */
+        if( count >= cache->max_entries )
+        {
+            if( cache->chain == NULL )
+            {
+                ret = 1;
+                goto exit;
+            }
+
+            cur = cache->chain;
+            cache->chain = cur->next;
+            cur->next = NULL;
+            prv->next = cur;
+        }
+#endif /* MBEDTLS_HAVE_TIME */
+        else
+        {
+            /*
+             * max_entries not reached, create new entry
+             */
+            cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) );
+            if( cur == NULL )
+            {
+                ret = 1;
+                goto exit;
+            }
+
+            if( prv == NULL )
+                cache->chain = cur;
+            else
+                prv->next = cur;
+        }
+
+#if defined(MBEDTLS_HAVE_TIME)
+        cur->timestamp = t;
+#endif
+    }
+
+    memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    /*
+     * If we're reusing an entry, free its certificate first
+     */
+    if( cur->peer_cert.p != NULL )
+    {
+        mbedtls_free( cur->peer_cert.p );
+        memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) );
+    }
+
+    /*
+     * Store peer certificate
+     */
+    if( session->peer_cert != NULL )
+    {
+        cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len );
+        if( cur->peer_cert.p == NULL )
+        {
+            ret = 1;
+            goto exit;
+        }
+
+        memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
+                session->peer_cert->raw.len );
+        cur->peer_cert.len = session->peer_cert->raw.len;
+
+        cur->session.peer_cert = NULL;
+    }
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+    ret = 0;
+
+exit:
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &cache->mutex ) != 0 )
+        ret = 1;
+#endif
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_HAVE_TIME)
+void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout )
+{
+    if( timeout < 0 ) timeout = 0;
+
+    cache->timeout = timeout;
+}
+#endif /* MBEDTLS_HAVE_TIME */
+
+void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max )
+{
+    if( max < 0 ) max = 0;
+
+    cache->max_entries = max;
+}
+
+void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache )
+{
+    mbedtls_ssl_cache_entry *cur, *prv;
+
+    cur = cache->chain;
+
+    while( cur != NULL )
+    {
+        prv = cur;
+        cur = cur->next;
+
+        mbedtls_ssl_session_free( &prv->session );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+        mbedtls_free( prv->peer_cert.p );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+        mbedtls_free( prv );
+    }
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_free( &cache->mutex );
+#endif
+    cache->chain = NULL;
+}
+
+#endif /* MBEDTLS_SSL_CACHE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_ciphersuites.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_ciphersuites.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_ciphersuites.c	(revision 398)
@@ -0,0 +1,2373 @@
+/**
+ * \file ssl_ciphersuites.c
+ *
+ * \brief SSL ciphersuites for mbed TLS
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#endif
+
+#include "mbedtls/ssl_ciphersuites.h"
+#include "mbedtls/ssl.h"
+
+#include <string.h>
+
+/*
+ * Ordered from most preferred to least preferred in terms of security.
+ *
+ * Current rule (except RC4 and 3DES, weak and null which come last):
+ * 1. By key exchange:
+ *    Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK
+ * 2. By key length and cipher:
+ *    ChaCha > AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128
+ * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8
+ * 4. By hash function used when relevant
+ * 5. By key exchange/auth again: EC > non-EC
+ */
+static const int ciphersuite_preference[] =
+{
+#if defined(MBEDTLS_SSL_CIPHERSUITES)
+    MBEDTLS_SSL_CIPHERSUITES,
+#else
+    /* Chacha-Poly ephemeral suites */
+    MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+
+    /* All AES-256 ephemeral suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8,
+
+    /* All CAMELLIA-256 ephemeral suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
+    MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
+    MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
+
+    /* All ARIA-256 ephemeral suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
+    MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
+
+    /* All AES-128 ephemeral suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
+    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8,
+
+    /* All CAMELLIA-128 ephemeral suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
+
+    /* All ARIA-128 ephemeral suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
+    MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
+
+    /* The PSK ephemeral suites */
+    MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
+    MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
+    MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+    MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8,
+    MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
+    MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
+
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
+    MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256,
+    MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+    MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8,
+    MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
+    MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
+
+    /* The ECJPAKE suite */
+    MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8,
+
+    /* All AES-256 suites */
+    MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
+    MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
+    MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256,
+    MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
+    MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
+    MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+    MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8,
+
+    /* All CAMELLIA-256 suites */
+    MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
+    MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+    MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
+    MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
+
+    /* All ARIA-256 suites */
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
+    MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
+    MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
+
+    /* All AES-128 suites */
+    MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
+    MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
+    MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
+    MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
+    MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+    MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8,
+
+    /* All CAMELLIA-128 suites */
+    MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
+    MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+    MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
+    MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
+
+    /* All ARIA-128 suites */
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
+    MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
+    MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
+
+    /* The RSA PSK suites */
+    MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
+    MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
+    MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
+    MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
+    MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
+    MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+    MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
+
+    MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
+    MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
+    MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
+    MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
+    MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+    MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
+
+    /* The PSK suites */
+    MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
+    MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
+    MBEDTLS_TLS_PSK_WITH_AES_256_CCM,
+    MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
+    MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA,
+    MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
+    MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+    MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
+    MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
+    MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
+
+    MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
+    MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
+    MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
+    MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA,
+    MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
+    MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+    MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
+    MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
+    MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
+
+    /* 3DES suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+    MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
+    MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
+    MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+    MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+    MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
+    MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
+
+    /* RC4 suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA,
+    MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA,
+    MBEDTLS_TLS_RSA_WITH_RC4_128_SHA,
+    MBEDTLS_TLS_RSA_WITH_RC4_128_MD5,
+    MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
+    MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA,
+    MBEDTLS_TLS_PSK_WITH_RC4_128_SHA,
+
+    /* Weak suites */
+    MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA,
+    MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA,
+
+    /* NULL suites */
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
+    MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256,
+    MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA,
+    MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384,
+    MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256,
+    MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA,
+
+    MBEDTLS_TLS_RSA_WITH_NULL_SHA256,
+    MBEDTLS_TLS_RSA_WITH_NULL_SHA,
+    MBEDTLS_TLS_RSA_WITH_NULL_MD5,
+    MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA,
+    MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA,
+    MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384,
+    MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256,
+    MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA,
+    MBEDTLS_TLS_PSK_WITH_NULL_SHA384,
+    MBEDTLS_TLS_PSK_WITH_NULL_SHA256,
+    MBEDTLS_TLS_PSK_WITH_NULL_SHA,
+
+#endif /* MBEDTLS_SSL_CIPHERSUITES */
+    0
+};
+
+static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
+{
+#if defined(MBEDTLS_CHACHAPOLY_C) && \
+    defined(MBEDTLS_SHA256_C) && \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+      "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+      MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
+      MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+      "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
+      MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
+      MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
+    { MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+      "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+      MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
+      MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+    { MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
+      "TLS-PSK-WITH-CHACHA20-POLY1305-SHA256",
+      MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
+      MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
+      "TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256",
+      MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
+      MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+    { MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
+      "TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256",
+      MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
+      MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+    { MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
+      "TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256",
+      MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256,
+      MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#endif /* MBEDTLS_CHACHAPOLY_C &&
+          MBEDTLS_SHA256_C &&
+          MBEDTLS_SSL_PROTO_TLS1_2 */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_SHA1_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
+      MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
+      MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_SHA512_C */
+#if defined(MBEDTLS_CCM_C)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM",
+      MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8",
+      MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+#endif /* MBEDTLS_CCM_C */
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA",
+      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA",
+      MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_NODTLS },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_ARC4_C */
+
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS-ECDHE-ECDSA-WITH-NULL-SHA",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_SHA1_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256",
+      MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384",
+      MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
+      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS-ECDHE-RSA-WITH-RC4-128-SHA",
+      MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_NODTLS },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_ARC4_C */
+
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
+      MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256",
+      MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_CCM_C)
+    { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, "TLS-DHE-RSA-WITH-AES-256-CCM",
+      MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, "TLS-DHE-RSA-WITH-AES-256-CCM-8",
+      MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+    { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, "TLS-DHE-RSA-WITH-AES-128-CCM",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, "TLS-DHE-RSA-WITH-AES-128-CCM-8",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+#endif /* MBEDTLS_CCM_C */
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
+      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384",
+      MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS-RSA-WITH-AES-128-GCM-SHA256",
+      MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS-RSA-WITH-AES-128-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS-RSA-WITH-AES-256-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA1_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_CCM_C)
+    { MBEDTLS_TLS_RSA_WITH_AES_256_CCM, "TLS-RSA-WITH-AES-256-CCM",
+      MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, "TLS-RSA-WITH-AES-256-CCM-8",
+      MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+    { MBEDTLS_TLS_RSA_WITH_AES_128_CCM, "TLS-RSA-WITH-AES-128-CCM",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, "TLS-RSA-WITH-AES-128-CCM-8",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+#endif /* MBEDTLS_CCM_C */
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
+      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+#if defined(MBEDTLS_MD5_C)
+    { MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, "TLS-RSA-WITH-RC4-128-MD5",
+      MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_NODTLS },
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, "TLS-RSA-WITH-RC4-128-SHA",
+      MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_NODTLS },
+#endif
+#endif /* MBEDTLS_ARC4_C */
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_SHA1_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256",
+      MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384",
+      MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA",
+      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS-ECDH-RSA-WITH-RC4-128-SHA",
+      MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_NODTLS },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_ARC4_C */
+
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_SHA1_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256",
+      MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_GCM_C)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384",
+      MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA",
+      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS-ECDH-ECDSA-WITH-RC4-128-SHA",
+      MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_NODTLS },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_ARC4_C */
+
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, "TLS-PSK-WITH-AES-128-GCM-SHA256",
+      MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384",
+      MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_CCM_C)
+    { MBEDTLS_TLS_PSK_WITH_AES_256_CCM, "TLS-PSK-WITH-AES-256-CCM",
+      MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, "TLS-PSK-WITH-AES-256-CCM-8",
+      MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+    { MBEDTLS_TLS_PSK_WITH_AES_128_CCM, "TLS-PSK-WITH-AES-128-CCM",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, "TLS-PSK-WITH-AES-128-CCM-8",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+#endif /* MBEDTLS_CCM_C */
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-PSK-WITH-3DES-EDE-CBC-SHA",
+      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, "TLS-PSK-WITH-RC4-128-SHA",
+      MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_NODTLS },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_ARC4_C */
+#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256",
+      MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384",
+      MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_CCM_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, "TLS-DHE-PSK-WITH-AES-256-CCM",
+      MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, "TLS-DHE-PSK-WITH-AES-256-CCM-8",
+      MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+    { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, "TLS-DHE-PSK-WITH-AES-128-CCM",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+    { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, "TLS-DHE-PSK-WITH-AES-128-CCM-8",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+#endif /* MBEDTLS_CCM_C */
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA",
+      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, "TLS-DHE-PSK-WITH-RC4-128-SHA",
+      MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_NODTLS },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_ARC4_C */
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(MBEDTLS_AES_C)
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA",
+      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, "TLS-ECDHE-PSK-WITH-RC4-128-SHA",
+      MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_NODTLS },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_ARC4_C */
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256",
+      MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384",
+      MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA",
+      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+
+    { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA",
+      MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_AES_C */
+
+#if defined(MBEDTLS_CAMELLIA_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_GCM_C)
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_CAMELLIA_C */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA",
+      MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+
+#if defined(MBEDTLS_ARC4_C)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, "TLS-RSA-PSK-WITH-RC4-128-SHA",
+      MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_NODTLS },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_ARC4_C */
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+#if defined(MBEDTLS_AES_C)
+#if defined(MBEDTLS_CCM_C)
+    { MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, "TLS-ECJPAKE-WITH-AES-128-CCM-8",
+      MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECJPAKE,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_SHORT_TAG },
+#endif /* MBEDTLS_CCM_C */
+#endif /* MBEDTLS_AES_C */
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES)
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+#if defined(MBEDTLS_MD5_C)
+    { MBEDTLS_TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif /* MBEDTLS_SHA1_C */
+
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, "TLS-DHE-PSK-WITH-NULL-SHA",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif /* MBEDTLS_SHA1_C */
+
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif /* MBEDTLS_SHA1_C */
+
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif /* MBEDTLS_SHA1_C */
+
+#if defined(MBEDTLS_SHA256_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+    { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384",
+      MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
+
+#if defined(MBEDTLS_DES_C)
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS-DHE-RSA-WITH-DES-CBC-SHA",
+      MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+#if defined(MBEDTLS_SHA1_C)
+    { MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, "TLS-RSA-WITH-DES-CBC-SHA",
+      MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_CIPHERSUITE_WEAK },
+#endif /* MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* MBEDTLS_DES_C */
+#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */
+
+#if defined(MBEDTLS_ARIA_C)
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-RSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-RSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-RSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-RSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
+             "TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
+             "TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
+             "TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
+             "TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
+             "TLS-PSK-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384,MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
+             "TLS-PSK-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
+             "TLS-PSK-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
+             "TLS-PSK-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-ECDH-RSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-ECDH-RSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
+             "TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
+             "TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
+             "TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
+             "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
+             "TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
+             "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
+             "TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+    { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
+             "TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384",
+      MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
+             "TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA256_C))
+    { MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
+             "TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256",
+      MBEDTLS_CIPHER_ARIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
+      0 },
+#endif
+
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+
+#endif /* MBEDTLS_ARIA_C */
+
+
+    { 0, "",
+      MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE,
+      0, 0, 0, 0, 0 }
+};
+
+#if defined(MBEDTLS_SSL_CIPHERSUITES)
+const int *mbedtls_ssl_list_ciphersuites( void )
+{
+    return( ciphersuite_preference );
+}
+#else
+#define MAX_CIPHERSUITES    sizeof( ciphersuite_definitions     ) /         \
+                            sizeof( ciphersuite_definitions[0]  )
+static int supported_ciphersuites[MAX_CIPHERSUITES];
+static int supported_init = 0;
+
+static int ciphersuite_is_removed( const mbedtls_ssl_ciphersuite_t *cs_info )
+{
+    (void)cs_info;
+
+#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES)
+    if( cs_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
+        return( 1 );
+#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */
+
+#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES)
+    if( cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_ECB ||
+        cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_CBC )
+    {
+        return( 1 );
+    }
+#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */
+
+    return( 0 );
+}
+
+const int *mbedtls_ssl_list_ciphersuites( void )
+{
+    /*
+     * On initial call filter out all ciphersuites not supported by current
+     * build based on presence in the ciphersuite_definitions.
+     */
+    if( supported_init == 0 )
+    {
+        const int *p;
+        int *q;
+
+        for( p = ciphersuite_preference, q = supported_ciphersuites;
+             *p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1;
+             p++ )
+        {
+            const mbedtls_ssl_ciphersuite_t *cs_info;
+            if( ( cs_info = mbedtls_ssl_ciphersuite_from_id( *p ) ) != NULL &&
+                !ciphersuite_is_removed( cs_info ) )
+            {
+                *(q++) = *p;
+            }
+        }
+        *q = 0;
+
+        supported_init = 1;
+    }
+
+    return( supported_ciphersuites );
+}
+#endif /* MBEDTLS_SSL_CIPHERSUITES */
+
+const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string(
+                                                const char *ciphersuite_name )
+{
+    const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions;
+
+    if( NULL == ciphersuite_name )
+        return( NULL );
+
+    while( cur->id != 0 )
+    {
+        if( 0 == strcmp( cur->name, ciphersuite_name ) )
+            return( cur );
+
+        cur++;
+    }
+
+    return( NULL );
+}
+
+const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite )
+{
+    const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions;
+
+    while( cur->id != 0 )
+    {
+        if( cur->id == ciphersuite )
+            return( cur );
+
+        cur++;
+    }
+
+    return( NULL );
+}
+
+const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id )
+{
+    const mbedtls_ssl_ciphersuite_t *cur;
+
+    cur = mbedtls_ssl_ciphersuite_from_id( ciphersuite_id );
+
+    if( cur == NULL )
+        return( "unknown" );
+
+    return( cur->name );
+}
+
+int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name )
+{
+    const mbedtls_ssl_ciphersuite_t *cur;
+
+    cur = mbedtls_ssl_ciphersuite_from_string( ciphersuite_name );
+
+    if( cur == NULL )
+        return( 0 );
+
+    return( cur->id );
+}
+
+#if defined(MBEDTLS_PK_C)
+mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
+            return( MBEDTLS_PK_RSA );
+
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+            return( MBEDTLS_PK_ECDSA );
+
+        case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+            return( MBEDTLS_PK_ECKEY );
+
+        default:
+            return( MBEDTLS_PK_NONE );
+    }
+}
+
+mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+            return( MBEDTLS_PK_RSA );
+
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+            return( MBEDTLS_PK_ECDSA );
+
+        default:
+            return( MBEDTLS_PK_NONE );
+    }
+}
+
+#endif /* MBEDTLS_PK_C */
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
+        case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+        case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+        case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
+            return( 1 );
+
+        default:
+            return( 0 );
+    }
+}
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info )
+{
+    switch( info->key_exchange )
+    {
+        case MBEDTLS_KEY_EXCHANGE_PSK:
+        case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
+        case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
+        case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
+            return( 1 );
+
+        default:
+            return( 0 );
+    }
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+#endif /* MBEDTLS_SSL_TLS_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_cli.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_cli.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_cli.c	(revision 398)
@@ -0,0 +1,3636 @@
+/*
+ *  SSLv3/TLSv1 client-side functions
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SSL_CLI_C)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free      free
+#endif
+
+#include "mbedtls/debug.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/ssl_internal.h"
+
+#include <string.h>
+
+#include <stdint.h>
+
+#if defined(MBEDTLS_HAVE_TIME)
+#include "mbedtls/platform_time.h"
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+#include "mbedtls/platform_util.h"
+#endif
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
+                                    unsigned char *buf,
+                                    size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+    size_t hostname_len;
+
+    *olen = 0;
+
+    if( ssl->hostname == NULL )
+        return;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s",
+                   ssl->hostname ) );
+
+    hostname_len = strlen( ssl->hostname );
+
+    if( end < p || (size_t)( end - p ) < hostname_len + 9 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    /*
+     * Sect. 3, RFC 6066 (TLS Extensions Definitions)
+     *
+     * In order to provide any of the server names, clients MAY include an
+     * extension of type "server_name" in the (extended) client hello. The
+     * "extension_data" field of this extension SHALL contain
+     * "ServerNameList" where:
+     *
+     * struct {
+     *     NameType name_type;
+     *     select (name_type) {
+     *         case host_name: HostName;
+     *     } name;
+     * } ServerName;
+     *
+     * enum {
+     *     host_name(0), (255)
+     * } NameType;
+     *
+     * opaque HostName<1..2^16-1>;
+     *
+     * struct {
+     *     ServerName server_name_list<1..2^16-1>
+     * } ServerNameList;
+     *
+     */
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME      ) & 0xFF );
+
+    *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( (hostname_len + 5)      ) & 0xFF );
+
+    *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( (hostname_len + 3)      ) & 0xFF );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
+    *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( hostname_len      ) & 0xFF );
+
+    memcpy( p, ssl->hostname, hostname_len );
+
+    *olen = hostname_len + 9;
+}
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
+                                         unsigned char *buf,
+                                         size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+    *olen = 0;
+
+    /* We're always including an TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the
+     * initial ClientHello, in which case also adding the renegotiation
+     * info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */
+    if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+        return;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
+
+    if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    /*
+     * Secure renegotiation
+     */
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
+    *p++ = ssl->verify_data_len & 0xFF;
+
+    memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
+
+    *olen = 5 + ssl->verify_data_len;
+}
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+/*
+ * Only if we handle at least one key exchange that needs signatures.
+ */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
+                                                unsigned char *buf,
+                                                size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+    size_t sig_alg_len = 0;
+    const int *md;
+#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
+    unsigned char *sig_alg_list = buf + 6;
+#endif
+
+    *olen = 0;
+
+    if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
+        return;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
+
+    for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
+    {
+#if defined(MBEDTLS_ECDSA_C)
+        sig_alg_len += 2;
+#endif
+#if defined(MBEDTLS_RSA_C)
+        sig_alg_len += 2;
+#endif
+    }
+
+    if( end < p || (size_t)( end - p ) < sig_alg_len + 6 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    /*
+     * Prepare signature_algorithms extension (TLS 1.2)
+     */
+    sig_alg_len = 0;
+
+    for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
+    {
+#if defined(MBEDTLS_ECDSA_C)
+        sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
+        sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA;
+#endif
+#if defined(MBEDTLS_RSA_C)
+        sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md );
+        sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA;
+#endif
+    }
+
+    /*
+     * enum {
+     *     none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
+     *     sha512(6), (255)
+     * } HashAlgorithm;
+     *
+     * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
+     *   SignatureAlgorithm;
+     *
+     * struct {
+     *     HashAlgorithm hash;
+     *     SignatureAlgorithm signature;
+     * } SignatureAndHashAlgorithm;
+     *
+     * SignatureAndHashAlgorithm
+     *   supported_signature_algorithms<2..2^16-2>;
+     */
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG      ) & 0xFF );
+
+    *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( ( sig_alg_len + 2 )      ) & 0xFF );
+
+    *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( sig_alg_len      ) & 0xFF );
+
+    *olen = 6 + sig_alg_len;
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
+          MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
+                                                     unsigned char *buf,
+                                                     size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+    unsigned char *elliptic_curve_list = p + 6;
+    size_t elliptic_curve_len = 0;
+    const mbedtls_ecp_curve_info *info;
+#if defined(MBEDTLS_ECP_C)
+    const mbedtls_ecp_group_id *grp_id;
+#else
+    ((void) ssl);
+#endif
+
+    *olen = 0;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
+
+#if defined(MBEDTLS_ECP_C)
+    for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
+#else
+    for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
+#endif
+    {
+#if defined(MBEDTLS_ECP_C)
+        info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
+#endif
+        if( info == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) );
+            return;
+        }
+
+        elliptic_curve_len += 2;
+    }
+
+    if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    elliptic_curve_len = 0;
+
+#if defined(MBEDTLS_ECP_C)
+    for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ )
+#else
+    for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
+#endif
+    {
+#if defined(MBEDTLS_ECP_C)
+        info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
+#endif
+        elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
+        elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
+    }
+
+    if( elliptic_curve_len == 0 )
+        return;
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES      ) & 0xFF );
+
+    *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 )      ) & 0xFF );
+
+    *p++ = (unsigned char)( ( ( elliptic_curve_len     ) >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( ( elliptic_curve_len     )      ) & 0xFF );
+
+    *olen = 6 + elliptic_curve_len;
+}
+
+static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
+                                                   unsigned char *buf,
+                                                   size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+    *olen = 0;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
+
+    if( end < p || (size_t)( end - p ) < 6 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 2;
+
+    *p++ = 1;
+    *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
+
+    *olen = 6;
+}
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+          MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
+                                        unsigned char *buf,
+                                        size_t *olen )
+{
+    int ret;
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+    size_t kkpp_len;
+
+    *olen = 0;
+
+    /* Skip costly extension if we can't use EC J-PAKE anyway */
+    if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
+        return;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) );
+
+    if( end - p < 4 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP      ) & 0xFF );
+
+    /*
+     * We may need to send ClientHello multiple times for Hello verification.
+     * We don't want to compute fresh values every time (both for performance
+     * and consistency reasons), so cache the extension content.
+     */
+    if( ssl->handshake->ecjpake_cache == NULL ||
+        ssl->handshake->ecjpake_cache_len == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) );
+
+        ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
+                                        p + 2, end - p - 2, &kkpp_len,
+                                        ssl->conf->f_rng, ssl->conf->p_rng );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
+            return;
+        }
+
+        ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len );
+        if( ssl->handshake->ecjpake_cache == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) );
+            return;
+        }
+
+        memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len );
+        ssl->handshake->ecjpake_cache_len = kkpp_len;
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) );
+
+        kkpp_len = ssl->handshake->ecjpake_cache_len;
+
+        if( (size_t)( end - p - 2 ) < kkpp_len )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+            return;
+        }
+
+        memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
+    }
+
+    *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( kkpp_len      ) & 0xFF );
+
+    *olen = kkpp_len + 4;
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
+                                               unsigned char *buf,
+                                               size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+    *olen = 0;
+
+    if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
+
+    if( end < p || (size_t)( end - p ) < 5 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 1;
+
+    *p++ = ssl->conf->mfl_code;
+
+    *olen = 5;
+}
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
+                                          unsigned char *buf, size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+    *olen = 0;
+
+    if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
+    {
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
+
+    if( end < p || (size_t)( end - p ) < 4 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 0x00;
+
+    *olen = 4;
+}
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
+                                       unsigned char *buf, size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+    *olen = 0;
+
+    if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
+        ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
+                        "extension" ) );
+
+    if( end < p || (size_t)( end - p ) < 4 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 0x00;
+
+    *olen = 4;
+}
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
+                                       unsigned char *buf, size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+    *olen = 0;
+
+    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
+        ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
+                        "extension" ) );
+
+    if( end < p || (size_t)( end - p ) < 4 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 0x00;
+
+    *olen = 4;
+}
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
+                                          unsigned char *buf, size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+    size_t tlen = ssl->session_negotiate->ticket_len;
+
+    *olen = 0;
+
+    if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
+    {
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
+
+    if( end < p || (size_t)( end - p ) < 4 + tlen )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET      ) & 0xFF );
+
+    *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( tlen      ) & 0xFF );
+
+    *olen = 4;
+
+    if( ssl->session_negotiate->ticket == NULL || tlen == 0 )
+    {
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) );
+
+    memcpy( p, ssl->session_negotiate->ticket, tlen );
+
+    *olen += tlen;
+}
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+#if defined(MBEDTLS_SSL_ALPN)
+static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
+                                unsigned char *buf, size_t *olen )
+{
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+    size_t alpnlen = 0;
+    const char **cur;
+
+    *olen = 0;
+
+    if( ssl->conf->alpn_list == NULL )
+    {
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
+
+    for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
+        alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1;
+
+    if( end < p || (size_t)( end - p ) < 6 + alpnlen )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN      ) & 0xFF );
+
+    /*
+     * opaque ProtocolName<1..2^8-1>;
+     *
+     * struct {
+     *     ProtocolName protocol_name_list<2..2^16-1>
+     * } ProtocolNameList;
+     */
+
+    /* Skip writing extension and list length for now */
+    p += 4;
+
+    for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
+    {
+        *p = (unsigned char)( strlen( *cur ) & 0xFF );
+        memcpy( p + 1, *cur, *p );
+        p += 1 + *p;
+    }
+
+    *olen = p - buf;
+
+    /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
+    buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
+    buf[5] = (unsigned char)( ( ( *olen - 6 )      ) & 0xFF );
+
+    /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
+    buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
+    buf[3] = (unsigned char)( ( ( *olen - 4 )      ) & 0xFF );
+}
+#endif /* MBEDTLS_SSL_ALPN */
+
+/*
+ * Generate random bytes for ClientHello
+ */
+static int ssl_generate_random( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    unsigned char *p = ssl->handshake->randbytes;
+#if defined(MBEDTLS_HAVE_TIME)
+    mbedtls_time_t t;
+#endif
+
+    /*
+     * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1)
+     */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->handshake->verify_cookie != NULL )
+    {
+        return( 0 );
+    }
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME)
+    t = mbedtls_time( NULL );
+    *p++ = (unsigned char)( t >> 24 );
+    *p++ = (unsigned char)( t >> 16 );
+    *p++ = (unsigned char)( t >>  8 );
+    *p++ = (unsigned char)( t       );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
+#else
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
+        return( ret );
+
+    p += 4;
+#endif /* MBEDTLS_HAVE_TIME */
+
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+/**
+ * \brief           Validate cipher suite against config in SSL context.
+ *
+ * \param suite_info    cipher suite to validate
+ * \param ssl           SSL context
+ * \param min_minor_ver Minimal minor version to accept a cipher suite
+ * \param max_minor_ver Maximal minor version to accept a cipher suite
+ *
+ * \return          0 if valid, else 1
+ */
+static int ssl_validate_ciphersuite( const mbedtls_ssl_ciphersuite_t * suite_info,
+                                     const mbedtls_ssl_context * ssl,
+                                     int min_minor_ver, int max_minor_ver )
+{
+    (void) ssl;
+    if( suite_info == NULL )
+        return( 1 );
+
+    if( suite_info->min_minor_ver > max_minor_ver ||
+            suite_info->max_minor_ver < min_minor_ver )
+        return( 1 );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+            ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
+        return( 1 );
+#endif
+
+#if defined(MBEDTLS_ARC4_C)
+    if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
+            suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
+        return( 1 );
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
+            mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
+        return( 1 );
+#endif
+
+    return( 0 );
+}
+
+static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    size_t i, n, olen, ext_len = 0;
+    unsigned char *buf;
+    unsigned char *p, *q;
+    unsigned char offer_compress;
+    const int *ciphersuites;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    int uses_ec = 0;
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
+
+    if( ssl->conf->f_rng == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
+        return( MBEDTLS_ERR_SSL_NO_RNG );
+    }
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
+#endif
+    {
+        ssl->major_ver = ssl->conf->min_major_ver;
+        ssl->minor_ver = ssl->conf->min_minor_ver;
+    }
+
+    if( ssl->conf->max_major_ver == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, "
+                            "consider using mbedtls_ssl_config_defaults()" ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    /*
+     *     0  .   0   handshake type
+     *     1  .   3   handshake length
+     *     4  .   5   highest version supported
+     *     6  .   9   current UNIX time
+     *    10  .  37   random bytes
+     */
+    buf = ssl->out_msg;
+    p = buf + 4;
+
+    mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
+                       ssl->conf->transport, p );
+    p += 2;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
+                   buf[4], buf[5] ) );
+
+    if( ( ret = ssl_generate_random( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret );
+        return( ret );
+    }
+
+    memcpy( p, ssl->handshake->randbytes, 32 );
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 );
+    p += 32;
+
+    /*
+     *    38  .  38   session id length
+     *    39  . 39+n  session id
+     *   39+n . 39+n  DTLS only: cookie length (1 byte)
+     *   40+n .  ..   DTSL only: cookie
+     *   ..   . ..    ciphersuitelist length (2 bytes)
+     *   ..   . ..    ciphersuitelist
+     *   ..   . ..    compression methods length (1 byte)
+     *   ..   . ..    compression methods
+     *   ..   . ..    extensions length (2 bytes)
+     *   ..   . ..    extensions
+     */
+    n = ssl->session_negotiate->id_len;
+
+    if( n < 16 || n > 32 ||
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+        ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
+#endif
+        ssl->handshake->resume == 0 )
+    {
+        n = 0;
+    }
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    /*
+     * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
+     * generate and include a Session ID in the TLS ClientHello."
+     */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
+#endif
+    {
+        if( ssl->session_negotiate->ticket != NULL &&
+                ssl->session_negotiate->ticket_len != 0 )
+        {
+            ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 );
+
+            if( ret != 0 )
+                return( ret );
+
+            ssl->session_negotiate->id_len = n = 32;
+        }
+    }
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+    *p++ = (unsigned char) n;
+
+    for( i = 0; i < n; i++ )
+        *p++ = ssl->session_negotiate->id[i];
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
+    MBEDTLS_SSL_DEBUG_BUF( 3,   "client hello, session id", buf + 39, n );
+
+    /*
+     * DTLS cookie
+     */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        if( ssl->handshake->verify_cookie == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) );
+            *p++ = 0;
+        }
+        else
+        {
+            MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
+                              ssl->handshake->verify_cookie,
+                              ssl->handshake->verify_cookie_len );
+
+            *p++ = ssl->handshake->verify_cookie_len;
+            memcpy( p, ssl->handshake->verify_cookie,
+                       ssl->handshake->verify_cookie_len );
+            p += ssl->handshake->verify_cookie_len;
+        }
+    }
+#endif
+
+    /*
+     * Ciphersuite list
+     */
+    ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
+
+    /* Skip writing ciphersuite length for now */
+    n = 0;
+    q = p;
+    p += 2;
+
+    for( i = 0; ciphersuites[i] != 0; i++ )
+    {
+        ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
+
+        if( ssl_validate_ciphersuite( ciphersuite_info, ssl,
+                                      ssl->conf->min_minor_ver,
+                                      ssl->conf->max_minor_ver ) != 0 )
+            continue;
+
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
+                                    ciphersuites[i] ) );
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+        uses_ec |= mbedtls_ssl_ciphersuite_uses_ec( ciphersuite_info );
+#endif
+
+        n++;
+        *p++ = (unsigned char)( ciphersuites[i] >> 8 );
+        *p++ = (unsigned char)( ciphersuites[i]      );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) );
+
+    /*
+     * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
+     */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
+#endif
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) );
+        *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
+        *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO      );
+        n++;
+    }
+
+    /* Some versions of OpenSSL don't handle it correctly if not at end */
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
+    if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
+        *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
+        *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE      );
+        n++;
+    }
+#endif
+
+    *q++ = (unsigned char)( n >> 7 );
+    *q++ = (unsigned char)( n << 1 );
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    offer_compress = 1;
+#else
+    offer_compress = 0;
+#endif
+
+    /*
+     * We don't support compression with DTLS right now: if many records come
+     * in the same datagram, uncompressing one could overwrite the next one.
+     * We don't want to add complexity for handling that case unless there is
+     * an actual need for it.
+     */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        offer_compress = 0;
+#endif
+
+    if( offer_compress )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) );
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d",
+                            MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) );
+
+        *p++ = 2;
+        *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE;
+        *p++ = MBEDTLS_SSL_COMPRESS_NULL;
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d",
+                            MBEDTLS_SSL_COMPRESS_NULL ) );
+
+        *p++ = 1;
+        *p++ = MBEDTLS_SSL_COMPRESS_NULL;
+    }
+
+    // First write extensions, then the total length
+    //
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+    /* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added
+     * even if MBEDTLS_SSL_RENEGOTIATION is not defined. */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+    ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    if( uses_ec )
+    {
+        ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
+        ext_len += olen;
+
+        ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
+        ext_len += olen;
+    }
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+    ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_ALPN)
+    ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+    /* olen unused if all extensions are disabled */
+    ((void) olen);
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
+                   ext_len ) );
+
+    if( ext_len > 0 )
+    {
+        *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
+        *p++ = (unsigned char)( ( ext_len      ) & 0xFF );
+        p += ext_len;
+    }
+
+    ssl->out_msglen  = p - buf;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_CLIENT_HELLO;
+
+    ssl->state++;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        mbedtls_ssl_send_flight_completed( ssl );
+#endif
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+        return( ret );
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
+
+    return( 0 );
+}
+
+static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
+                                         const unsigned char *buf,
+                                         size_t len )
+{
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
+    {
+        /* Check verify-data in constant-time. The length OTOH is no secret */
+        if( len    != 1 + ssl->verify_data_len * 2 ||
+            buf[0] !=     ssl->verify_data_len * 2 ||
+            mbedtls_ssl_safer_memcmp( buf + 1,
+                          ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
+            mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
+                          ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        }
+    }
+    else
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+    {
+        if( len != 1 || buf[0] != 0x00 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        }
+
+        ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
+    }
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
+                                              const unsigned char *buf,
+                                              size_t len )
+{
+    /*
+     * server should use the extension only if we did,
+     * and if so the server's value should match ours (and len is always 1)
+     */
+    if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
+        len != 1 ||
+        buf[0] != ssl->conf->mfl_code )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching max fragment length extension" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
+                                         const unsigned char *buf,
+                                         size_t len )
+{
+    if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ||
+        len != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching truncated HMAC extension" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    ((void) buf);
+
+    ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
+                                         const unsigned char *buf,
+                                         size_t len )
+{
+    if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
+        ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
+        len != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching encrypt-then-MAC extension" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    ((void) buf);
+
+    ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
+                                         const unsigned char *buf,
+                                         size_t len )
+{
+    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
+        ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
+        len != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching extended master secret extension" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    ((void) buf);
+
+    ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
+                                         const unsigned char *buf,
+                                         size_t len )
+{
+    if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
+        len != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching session ticket extension" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    ((void) buf);
+
+    ssl->handshake->new_session_ticket = 1;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
+                                                  const unsigned char *buf,
+                                                  size_t len )
+{
+    size_t list_size;
+    const unsigned char *p;
+
+    if( len == 0 || (size_t)( buf[0] + 1 ) != len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+    list_size = buf[0];
+
+    p = buf + 1;
+    while( list_size > 0 )
+    {
+        if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
+            p[0] == MBEDTLS_ECP_PF_COMPRESSED )
+        {
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
+            ssl->handshake->ecdh_ctx.point_format = p[0];
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+            ssl->handshake->ecjpake_ctx.point_format = p[0];
+#endif
+            MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
+            return( 0 );
+        }
+
+        list_size--;
+        p++;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
+    mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+    return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+}
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+          MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
+                                   const unsigned char *buf,
+                                   size_t len )
+{
+    int ret;
+
+    if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
+        MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
+        return( 0 );
+    }
+
+    /* If we got here, we no longer need our cached extension */
+    mbedtls_free( ssl->handshake->ecjpake_cache );
+    ssl->handshake->ecjpake_cache = NULL;
+    ssl->handshake->ecjpake_cache_len = 0;
+
+    if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
+                                                buf, len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( ret );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_SSL_ALPN)
+static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
+                               const unsigned char *buf, size_t len )
+{
+    size_t list_len, name_len;
+    const char **p;
+
+    /* If we didn't send it, the server shouldn't send it */
+    if( ssl->conf->alpn_list == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    /*
+     * opaque ProtocolName<1..2^8-1>;
+     *
+     * struct {
+     *     ProtocolName protocol_name_list<2..2^16-1>
+     * } ProtocolNameList;
+     *
+     * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
+     */
+
+    /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
+    if( len < 4 )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    list_len = ( buf[0] << 8 ) | buf[1];
+    if( list_len != len - 2 )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    name_len = buf[2];
+    if( name_len != list_len - 1 )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    /* Check that the server chosen protocol was in our list and save it */
+    for( p = ssl->conf->alpn_list; *p != NULL; p++ )
+    {
+        if( name_len == strlen( *p ) &&
+            memcmp( buf + 3, *p, name_len ) == 0 )
+        {
+            ssl->alpn_chosen = *p;
+            return( 0 );
+        }
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) );
+    mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+    return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+}
+#endif /* MBEDTLS_SSL_ALPN */
+
+/*
+ * Parse HelloVerifyRequest.  Only called after verifying the HS type.
+ */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
+{
+    const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
+    int major_ver, minor_ver;
+    unsigned char cookie_len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
+
+    /*
+     * struct {
+     *   ProtocolVersion server_version;
+     *   opaque cookie<0..2^8-1>;
+     * } HelloVerifyRequest;
+     */
+    MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
+    mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p );
+    p += 2;
+
+    /*
+     * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1)
+     * even is lower than our min version.
+     */
+    if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
+        minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ||
+        major_ver > ssl->conf->max_major_ver  ||
+        minor_ver > ssl->conf->max_minor_ver  )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) );
+
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                     MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
+
+        return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+    }
+
+    cookie_len = *p++;
+    MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
+
+    if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1,
+            ( "cookie length does not match incoming message size" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                    MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    mbedtls_free( ssl->handshake->verify_cookie );
+
+    ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len );
+    if( ssl->handshake->verify_cookie  == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", cookie_len ) );
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+    }
+
+    memcpy( ssl->handshake->verify_cookie, p, cookie_len );
+    ssl->handshake->verify_cookie_len = cookie_len;
+
+    /* Start over at ClientHello */
+    ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
+    mbedtls_ssl_reset_checksum( ssl );
+
+    mbedtls_ssl_recv_flight_completed( ssl );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
+{
+    int ret, i;
+    size_t n;
+    size_t ext_len;
+    unsigned char *buf, *ext;
+    unsigned char comp;
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    int accept_comp;
+#endif
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    int renegotiation_info_seen = 0;
+#endif
+    int handshake_failure = 0;
+    const mbedtls_ssl_ciphersuite_t *suite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
+
+    buf = ssl->in_msg;
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        /* No alert on a read error. */
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        return( ret );
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+        if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+        {
+            ssl->renego_records_seen++;
+
+            if( ssl->conf->renego_max_records >= 0 &&
+                ssl->renego_records_seen > ssl->conf->renego_max_records )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
+                                    "but not honored by server" ) );
+                return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+            }
+
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) );
+
+            ssl->keep_current_message = 1;
+            return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO );
+        }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) );
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
+            return( ssl_parse_hello_verify_request( ssl ) );
+        }
+        else
+        {
+            /* We made it through the verification process */
+            mbedtls_free( ssl->handshake->verify_cookie );
+            ssl->handshake->verify_cookie = NULL;
+            ssl->handshake->verify_cookie_len = 0;
+        }
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) ||
+        buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    /*
+     *  0   .  1    server_version
+     *  2   . 33    random (maybe including 4 bytes of Unix time)
+     * 34   . 34    session_id length = n
+     * 35   . 34+n  session_id
+     * 35+n . 36+n  cipher_suite
+     * 37+n . 37+n  compression_method
+     *
+     * 38+n . 39+n  extensions length (optional)
+     * 40+n .  ..   extensions
+     */
+    buf += mbedtls_ssl_hs_hdr_len( ssl );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
+    mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
+                      ssl->conf->transport, buf + 0 );
+
+    if( ssl->major_ver < ssl->conf->min_major_ver ||
+        ssl->minor_ver < ssl->conf->min_minor_ver ||
+        ssl->major_ver > ssl->conf->max_major_ver ||
+        ssl->minor_ver > ssl->conf->max_minor_ver )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - "
+                            " min: [%d:%d], server: [%d:%d], max: [%d:%d]",
+                            ssl->conf->min_major_ver, ssl->conf->min_minor_ver,
+                            ssl->major_ver, ssl->minor_ver,
+                            ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) );
+
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                     MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
+
+        return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu",
+                           ( (uint32_t) buf[2] << 24 ) |
+                           ( (uint32_t) buf[3] << 16 ) |
+                           ( (uint32_t) buf[4] <<  8 ) |
+                           ( (uint32_t) buf[5]       ) ) );
+
+    memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
+
+    n = buf[34];
+
+    MBEDTLS_SSL_DEBUG_BUF( 3,   "server hello, random bytes", buf + 2, 32 );
+
+    if( n > 32 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n )
+    {
+        ext_len = ( ( buf[38 + n] <<  8 )
+                  | ( buf[39 + n]       ) );
+
+        if( ( ext_len > 0 && ext_len < 4 ) ||
+            ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        }
+    }
+    else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n )
+    {
+        ext_len = 0;
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    /* ciphersuite (used later) */
+    i = ( buf[35 + n] << 8 ) | buf[36 + n];
+
+    /*
+     * Read and check compression
+     */
+    comp = buf[37 + n];
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    /* See comments in ssl_write_client_hello() */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        accept_comp = 0;
+    else
+#endif
+        accept_comp = 1;
+
+    if( comp != MBEDTLS_SSL_COMPRESS_NULL &&
+        ( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) )
+#else /* MBEDTLS_ZLIB_SUPPORT */
+    if( comp != MBEDTLS_SSL_COMPRESS_NULL )
+#endif/* MBEDTLS_ZLIB_SUPPORT */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+    }
+
+    /*
+     * Initialize update checksum functions
+     */
+    ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
+
+    if( ssl->transform_negotiate->ciphersuite_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
+    MBEDTLS_SSL_DEBUG_BUF( 3,   "server hello, session id", buf + 35, n );
+
+    /*
+     * Check if the session can be resumed
+     */
+    if( ssl->handshake->resume == 0 || n == 0 ||
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+        ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
+#endif
+        ssl->session_negotiate->ciphersuite != i ||
+        ssl->session_negotiate->compression != comp ||
+        ssl->session_negotiate->id_len != n ||
+        memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 )
+    {
+        ssl->state++;
+        ssl->handshake->resume = 0;
+#if defined(MBEDTLS_HAVE_TIME)
+        ssl->session_negotiate->start = mbedtls_time( NULL );
+#endif
+        ssl->session_negotiate->ciphersuite = i;
+        ssl->session_negotiate->compression = comp;
+        ssl->session_negotiate->id_len = n;
+        memcpy( ssl->session_negotiate->id, buf + 35, n );
+    }
+    else
+    {
+        ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
+
+        if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+            return( ret );
+        }
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
+                   ssl->handshake->resume ? "a" : "no" ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
+
+    /*
+     * Perform cipher suite validation in same way as in ssl_write_client_hello.
+     */
+    i = 0;
+    while( 1 )
+    {
+        if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        }
+
+        if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] ==
+            ssl->session_negotiate->ciphersuite )
+        {
+            break;
+        }
+    }
+
+    suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
+    if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver, ssl->minor_ver ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA &&
+        ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        ssl->handshake->ecrs_enabled = 1;
+    }
+#endif
+
+    if( comp != MBEDTLS_SSL_COMPRESS_NULL
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+        && comp != MBEDTLS_SSL_COMPRESS_DEFLATE
+#endif
+      )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+    ssl->session_negotiate->compression = comp;
+
+    ext = buf + 40 + n;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) );
+
+    while( ext_len )
+    {
+        unsigned int ext_id   = ( ( ext[0] <<  8 )
+                                | ( ext[1]       ) );
+        unsigned int ext_size = ( ( ext[2] <<  8 )
+                                | ( ext[3]       ) );
+
+        if( ext_size + 4 > ext_len )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        }
+
+        switch( ext_id )
+        {
+        case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+            renegotiation_info_seen = 1;
+#endif
+
+            if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4,
+                                                      ext_size ) ) != 0 )
+                return( ret );
+
+            break;
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+        case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) );
+
+            if( ( ret = ssl_parse_max_fragment_length_ext( ssl,
+                            ext + 4, ext_size ) ) != 0 )
+            {
+                return( ret );
+            }
+
+            break;
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+        case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) );
+
+            if( ( ret = ssl_parse_truncated_hmac_ext( ssl,
+                            ext + 4, ext_size ) ) != 0 )
+            {
+                return( ret );
+            }
+
+            break;
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+        case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
+
+            if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl,
+                            ext + 4, ext_size ) ) != 0 )
+            {
+                return( ret );
+            }
+
+            break;
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+        case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) );
+
+            if( ( ret = ssl_parse_extended_ms_ext( ssl,
+                            ext + 4, ext_size ) ) != 0 )
+            {
+                return( ret );
+            }
+
+            break;
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+        case MBEDTLS_TLS_EXT_SESSION_TICKET:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) );
+
+            if( ( ret = ssl_parse_session_ticket_ext( ssl,
+                            ext + 4, ext_size ) ) != 0 )
+            {
+                return( ret );
+            }
+
+            break;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+        case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
+
+            if( ( ret = ssl_parse_supported_point_formats_ext( ssl,
+                            ext + 4, ext_size ) ) != 0 )
+            {
+                return( ret );
+            }
+
+            break;
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+          MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+        case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) );
+
+            if( ( ret = ssl_parse_ecjpake_kkpp( ssl,
+                            ext + 4, ext_size ) ) != 0 )
+            {
+                return( ret );
+            }
+
+            break;
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_SSL_ALPN)
+        case MBEDTLS_TLS_EXT_ALPN:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
+
+            if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 )
+                return( ret );
+
+            break;
+#endif /* MBEDTLS_SSL_ALPN */
+
+        default:
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
+                           ext_id ) );
+        }
+
+        ext_len -= 4 + ext_size;
+        ext += 4 + ext_size;
+
+        if( ext_len > 0 && ext_len < 4 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+        }
+    }
+
+    /*
+     * Renegotiation security checks
+     */
+    if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
+        ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
+        handshake_failure = 1;
+    }
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
+             ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
+             renegotiation_info_seen == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
+        handshake_failure = 1;
+    }
+    else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
+             ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
+             ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
+        handshake_failure = 1;
+    }
+    else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
+             ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
+             renegotiation_info_seen == 1 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
+        handshake_failure = 1;
+    }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+    if( handshake_failure == 1 )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
+    defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p,
+                                       unsigned char *end )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+
+    /*
+     * Ephemeral DH parameters:
+     *
+     * struct {
+     *     opaque dh_p<1..2^16-1>;
+     *     opaque dh_g<1..2^16-1>;
+     *     opaque dh_Ys<1..2^16-1>;
+     * } ServerDHParams;
+     */
+    if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret );
+        return( ret );
+    }
+
+    if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d",
+                                    ssl->handshake->dhm_ctx.len * 8,
+                                    ssl->conf->dhm_min_bitlen ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+
+    MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P  );
+    MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G  );
+    MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
+
+    return( ret );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
+{
+    const mbedtls_ecp_curve_info *curve_info;
+    mbedtls_ecp_group_id grp_id;
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+    grp_id = ssl->handshake->ecdh_ctx.grp.id;
+#else
+    grp_id = ssl->handshake->ecdh_ctx.grp_id;
+#endif
+
+    curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id );
+    if( curve_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) );
+
+#if defined(MBEDTLS_ECP_C)
+    if( mbedtls_ssl_check_curve( ssl, grp_id ) != 0 )
+#else
+    if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
+        ssl->handshake->ecdh_ctx.grp.nbits > 521 )
+#endif
+        return( -1 );
+
+    MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                            MBEDTLS_DEBUG_ECDH_QP );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
+                                         unsigned char **p,
+                                         unsigned char *end )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+
+    /*
+     * Ephemeral ECDH parameters:
+     *
+     * struct {
+     *     ECParameters curve_params;
+     *     ECPoint      public;
+     * } ServerECDHParams;
+     */
+    if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx,
+                                  (const unsigned char **) p, end ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+        if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+            ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
+#endif
+        return( ret );
+    }
+
+    if( ssl_check_server_ecdh_params( ssl ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+
+    return( ret );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
+                                      unsigned char **p,
+                                      unsigned char *end )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    size_t  len;
+    ((void) ssl);
+
+    /*
+     * PSK parameters:
+     *
+     * opaque psk_identity_hint<0..2^16-1>;
+     */
+    if( end - (*p) < 2 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
+                                    "(psk_identity_hint length)" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+    len = (*p)[0] << 8 | (*p)[1];
+    *p += 2;
+
+    if( end - (*p) < (int) len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message "
+                                    "(psk_identity_hint length)" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+
+    /*
+     * Note: we currently ignore the PKS identity hint, as we only allow one
+     * PSK to be provisionned on the client. This could be changed later if
+     * someone needs that feature.
+     */
+    *p += len;
+    ret = 0;
+
+    return( ret );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) ||                           \
+    defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+/*
+ * Generate a pre-master secret and encrypt it with the server's RSA key
+ */
+static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
+                                    size_t offset, size_t *olen,
+                                    size_t pms_offset )
+{
+    int ret;
+    size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
+    unsigned char *p = ssl->handshake->premaster + pms_offset;
+
+    if( offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) );
+        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+    }
+
+    /*
+     * Generate (part of) the pre-master as
+     *  struct {
+     *      ProtocolVersion client_version;
+     *      opaque random[46];
+     *  } PreMasterSecret;
+     */
+    mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver,
+                       ssl->conf->transport, p );
+
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret );
+        return( ret );
+    }
+
+    ssl->handshake->pmslen = 48;
+
+    if( ssl->session_negotiate->peer_cert == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    /*
+     * Now write it out, encrypted
+     */
+    if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
+                MBEDTLS_PK_RSA ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
+        return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
+    }
+
+    if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
+                            p, ssl->handshake->pmslen,
+                            ssl->out_msg + offset + len_bytes, olen,
+                            MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes,
+                            ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret );
+        return( ret );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( len_bytes == 2 )
+    {
+        ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
+        ssl->out_msg[offset+1] = (unsigned char)( *olen      );
+        *olen += 2;
+    }
+#endif
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
+                                          unsigned char **p,
+                                          unsigned char *end,
+                                          mbedtls_md_type_t *md_alg,
+                                          mbedtls_pk_type_t *pk_alg )
+{
+    ((void) ssl);
+    *md_alg = MBEDTLS_MD_NONE;
+    *pk_alg = MBEDTLS_PK_NONE;
+
+    /* Only in TLS 1.2 */
+    if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        return( 0 );
+    }
+
+    if( (*p) + 2 > end )
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+
+    /*
+     * Get hash algorithm
+     */
+    if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported "
+                            "HashAlgorithm %d", *(p)[0] ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+
+    /*
+     * Get signature algorithm
+     */
+    if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported "
+                            "SignatureAlgorithm %d", (*p)[1] ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+
+    /*
+     * Check if the hash is acceptable
+     */
+    if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm %d that was not offered",
+                                    *(p)[0] ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) );
+    *p += 2;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    const mbedtls_ecp_keypair *peer_key;
+
+    if( ssl->session_negotiate->peer_cert == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
+                     MBEDTLS_PK_ECKEY ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
+        return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
+    }
+
+    peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
+
+    if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
+                                 MBEDTLS_ECDH_THEIRS ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
+        return( ret );
+    }
+
+    if( ssl_check_server_ecdh_params( ssl ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+    }
+
+    return( ret );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
+          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
+static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->transform_negotiate->ciphersuite_info;
+    unsigned char *p = NULL, *end = NULL;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
+        ssl->state++;
+        return( 0 );
+    }
+    ((void) p);
+    ((void) end);
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
+    {
+        if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            return( ret );
+        }
+
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
+        ssl->state++;
+        return( 0 );
+    }
+    ((void) p);
+    ((void) end);
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    if( ssl->handshake->ecrs_enabled &&
+        ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing )
+    {
+        goto start_processing;
+    }
+#endif
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        return( ret );
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    /*
+     * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
+     * doesn't use a psk_identity_hint
+     */
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE )
+    {
+        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+            ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+        {
+            /* Current message is probably either
+             * CertificateRequest or ServerHelloDone */
+            ssl->keep_current_message = 1;
+            goto exit;
+        }
+
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key exchange message must "
+                                    "not be skipped" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    if( ssl->handshake->ecrs_enabled )
+        ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing;
+
+start_processing:
+#endif
+    p   = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
+    end = ssl->in_msg + ssl->in_hslen;
+    MBEDTLS_SSL_DEBUG_BUF( 3,   "server key exchange", p, end - p );
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
+    {
+        if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        }
+    } /* FALLTROUGH */
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) ||                       \
+    defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+        ; /* nothing more to do */
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
+    defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
+    {
+        if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
+    {
+        if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
+                                              p, end - p );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+    if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
+    {
+        size_t sig_len, hashlen;
+        unsigned char hash[64];
+        mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
+        mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
+        unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
+        size_t params_len = p - params;
+        void *rs_ctx = NULL;
+
+        /*
+         * Handle the digitally-signed structure
+         */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+        {
+            if( ssl_parse_signature_algorithm( ssl, &p, end,
+                                               &md_alg, &pk_alg ) != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+                return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            }
+
+            if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+                return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+            }
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+        if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
+        {
+            pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
+
+            /* Default hash for ECDSA is SHA-1 */
+            if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE )
+                md_alg = MBEDTLS_MD_SHA1;
+        }
+        else
+#endif
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        /*
+         * Read signature
+         */
+
+        if( p > end - 2 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        }
+        sig_len = ( p[0] << 8 ) | p[1];
+        p += 2;
+
+        if( p != end - sig_len )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        }
+
+        MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len );
+
+        /*
+         * Compute the hash that has been signed
+         */
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+        if( md_alg == MBEDTLS_MD_NONE )
+        {
+            hashlen = 36;
+            ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash, params,
+                                                           params_len );
+            if( ret != 0 )
+                return( ret );
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
+          MBEDTLS_SSL_PROTO_TLS1_1 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( md_alg != MBEDTLS_MD_NONE )
+        {
+            ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
+                                                          params, params_len,
+                                                          md_alg );
+            if( ret != 0 )
+                return( ret );
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+          MBEDTLS_SSL_PROTO_TLS1_2 */
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
+
+        if( ssl->session_negotiate->peer_cert == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+        }
+
+        /*
+         * Verify signature
+         */
+        if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
+        }
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+        if( ssl->handshake->ecrs_enabled )
+            rs_ctx = &ssl->handshake->ecrs_ctx.pk;
+#endif
+
+        if( ( ret = mbedtls_pk_verify_restartable(
+                        &ssl->session_negotiate->peer_cert->pk,
+                        md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 )
+        {
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+            if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
+#endif
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+            if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+                ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
+#endif
+            return( ret );
+        }
+    }
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+
+exit:
+    ssl->state++;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
+
+    return( 0 );
+}
+
+#if ! defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED)
+static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
+{
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->transform_negotiate->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
+
+    if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+#else /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
+static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    unsigned char *buf;
+    size_t n = 0;
+    size_t cert_type_len = 0, dn_len = 0;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->transform_negotiate->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
+
+    if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        return( ret );
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    ssl->state++;
+    ssl->client_auth = ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",
+                        ssl->client_auth ? "a" : "no" ) );
+
+    if( ssl->client_auth == 0 )
+    {
+        /* Current message is probably the ServerHelloDone */
+        ssl->keep_current_message = 1;
+        goto exit;
+    }
+
+    /*
+     *  struct {
+     *      ClientCertificateType certificate_types<1..2^8-1>;
+     *      SignatureAndHashAlgorithm
+     *        supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
+     *      DistinguishedName certificate_authorities<0..2^16-1>;
+     *  } CertificateRequest;
+     *
+     *  Since we only support a single certificate on clients, let's just
+     *  ignore all the information that's supposed to help us pick a
+     *  certificate.
+     *
+     *  We could check that our certificate matches the request, and bail out
+     *  if it doesn't, but it's simpler to just send the certificate anyway,
+     *  and give the server the opportunity to decide if it should terminate
+     *  the connection when it doesn't like our certificate.
+     *
+     *  Same goes for the hash in TLS 1.2's signature_algorithms: at this
+     *  point we only have one hash available (see comments in
+     *  write_certificate_verify), so let's just use what we have.
+     *
+     *  However, we still minimally parse the message to check it is at least
+     *  superficially sane.
+     */
+    buf = ssl->in_msg;
+
+    /* certificate_types */
+    if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+    }
+    cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
+    n = cert_type_len;
+
+    /*
+     * In the subsequent code there are two paths that read from buf:
+     *     * the length of the signature algorithms field (if minor version of
+     *       SSL is 3),
+     *     * distinguished name length otherwise.
+     * Both reach at most the index:
+     *    ...hdr_len + 2 + n,
+     * therefore the buffer length at this point must be greater than that
+     * regardless of the actual code path.
+     */
+    if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+    }
+
+    /* supported_signature_algorithms */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] <<  8 )
+                             | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n]       ) );
+#if defined(MBEDTLS_DEBUG_C)
+        unsigned char* sig_alg;
+        size_t i;
+#endif
+
+        /*
+         * The furthest access in buf is in the loop few lines below:
+         *     sig_alg[i + 1],
+         * where:
+         *     sig_alg = buf + ...hdr_len + 3 + n,
+         *     max(i) = sig_alg_len - 1.
+         * Therefore the furthest access is:
+         *     buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1],
+         * which reduces to:
+         *     buf[...hdr_len + 3 + n + sig_alg_len],
+         * which is one less than we need the buf to be.
+         */
+        if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n + sig_alg_len )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+        }
+
+#if defined(MBEDTLS_DEBUG_C)
+        sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
+        for( i = 0; i < sig_alg_len; i += 2 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d"
+                                        ",%d", sig_alg[i], sig_alg[i + 1]  ) );
+        }
+#endif
+
+        n += 2 + sig_alg_len;
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+    /* certificate_authorities */
+    dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] <<  8 )
+             | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n]       ) );
+
+    n += dn_len;
+    if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+    }
+
+exit:
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
+
+static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        return( ret );
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    if( ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) ||
+        ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
+    }
+
+    ssl->state++;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        mbedtls_ssl_recv_flight_completed( ssl );
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
+
+    return( 0 );
+}
+
+static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    size_t i, n;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->transform_negotiate->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
+    {
+        /*
+         * DHM key exchange -- send G^X mod P
+         */
+        n = ssl->handshake->dhm_ctx.len;
+
+        ssl->out_msg[4] = (unsigned char)( n >> 8 );
+        ssl->out_msg[5] = (unsigned char)( n      );
+        i = 6;
+
+        ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
+                                (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
+                               &ssl->out_msg[i], n,
+                                ssl->conf->f_rng, ssl->conf->p_rng );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
+            return( ret );
+        }
+
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X  );
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
+
+        if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
+                                      ssl->handshake->premaster,
+                                      MBEDTLS_PREMASTER_SIZE,
+                                     &ssl->handshake->pmslen,
+                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
+            return( ret );
+        }
+
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
+    {
+        /*
+         * ECDH key exchange -- send client public value
+         */
+        i = 4;
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+        if( ssl->handshake->ecrs_enabled )
+        {
+            if( ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret )
+                goto ecdh_calc_secret;
+
+            mbedtls_ecdh_enable_restart( &ssl->handshake->ecdh_ctx );
+        }
+#endif
+
+        ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
+                                &n,
+                                &ssl->out_msg[i], 1000,
+                                ssl->conf->f_rng, ssl->conf->p_rng );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+            if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+                ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
+#endif
+            return( ret );
+        }
+
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Q );
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+        if( ssl->handshake->ecrs_enabled )
+        {
+            ssl->handshake->ecrs_n = n;
+            ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret;
+        }
+
+ecdh_calc_secret:
+        if( ssl->handshake->ecrs_enabled )
+            n = ssl->handshake->ecrs_n;
+#endif
+        if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
+                                      &ssl->handshake->pmslen,
+                                       ssl->handshake->premaster,
+                                       MBEDTLS_MPI_MAX_SIZE,
+                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+            if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+                ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
+#endif
+            return( ret );
+        }
+
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Z );
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) )
+    {
+        /*
+         * opaque psk_identity<0..2^16-1>;
+         */
+        if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) );
+            return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+        }
+
+        i = 4;
+        n = ssl->conf->psk_identity_len;
+
+        if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or "
+                                        "SSL buffer too short" ) );
+            return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+        }
+
+        ssl->out_msg[i++] = (unsigned char)( n >> 8 );
+        ssl->out_msg[i++] = (unsigned char)( n      );
+
+        memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len );
+        i += ssl->conf->psk_identity_len;
+
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
+        {
+            n = 0;
+        }
+        else
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+        {
+            if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
+                return( ret );
+        }
+        else
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
+        {
+            /*
+             * ClientDiffieHellmanPublic public (DHM send G^X mod P)
+             */
+            n = ssl->handshake->dhm_ctx.len;
+
+            if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long"
+                                            " or SSL buffer too short" ) );
+                return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+            }
+
+            ssl->out_msg[i++] = (unsigned char)( n >> 8 );
+            ssl->out_msg[i++] = (unsigned char)( n      );
+
+            ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
+                    (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
+                    &ssl->out_msg[i], n,
+                    ssl->conf->f_rng, ssl->conf->p_rng );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret );
+                return( ret );
+            }
+        }
+        else
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
+        {
+            /*
+             * ClientECDiffieHellmanPublic public;
+             */
+            ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
+                    &ssl->out_msg[i], MBEDTLS_SSL_OUT_CONTENT_LEN - i,
+                    ssl->conf->f_rng, ssl->conf->p_rng );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
+                return( ret );
+            }
+
+            MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                    MBEDTLS_DEBUG_ECDH_Q );
+        }
+        else
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
+                        ciphersuite_info->key_exchange ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
+            return( ret );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
+    {
+        i = 4;
+        if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
+            return( ret );
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        i = 4;
+
+        ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
+                ssl->out_msg + i, MBEDTLS_SSL_OUT_CONTENT_LEN - i, &n,
+                ssl->conf->f_rng, ssl->conf->p_rng );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
+            return( ret );
+        }
+
+        ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
+                ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
+                ssl->conf->f_rng, ssl->conf->p_rng );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
+            return( ret );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
+    {
+        ((void) ciphersuite_info);
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    ssl->out_msglen  = i + n;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
+
+    ssl->state++;
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)       && \
+    !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)   && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)  && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
+{
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->transform_negotiate->ciphersuite_info;
+    int ret;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
+
+    if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
+        return( ret );
+    }
+
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+#else
+static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->transform_negotiate->ciphersuite_info;
+    size_t n = 0, offset = 0;
+    unsigned char hash[48];
+    unsigned char *hash_start = hash;
+    mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
+    unsigned int hashlen;
+    void *rs_ctx = NULL;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    if( ssl->handshake->ecrs_enabled &&
+        ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign )
+    {
+        goto sign;
+    }
+#endif
+
+    if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
+        return( ret );
+    }
+
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    if( mbedtls_ssl_own_key( ssl ) == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for certificate" ) );
+        return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+    }
+
+    /*
+     * Make a signature of the handshake digests
+     */
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    if( ssl->handshake->ecrs_enabled )
+        ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign;
+
+sign:
+#endif
+
+    ssl->handshake->calc_verify( ssl, hash );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+    if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        /*
+         * digitally-signed struct {
+         *     opaque md5_hash[16];
+         *     opaque sha_hash[20];
+         * };
+         *
+         * md5_hash
+         *     MD5(handshake_messages);
+         *
+         * sha_hash
+         *     SHA(handshake_messages);
+         */
+        hashlen = 36;
+        md_alg = MBEDTLS_MD_NONE;
+
+        /*
+         * For ECDSA, default hash is SHA-1 only
+         */
+        if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) )
+        {
+            hash_start += 16;
+            hashlen -= 16;
+            md_alg = MBEDTLS_MD_SHA1;
+        }
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
+          MBEDTLS_SSL_PROTO_TLS1_1 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        /*
+         * digitally-signed struct {
+         *     opaque handshake_messages[handshake_messages_length];
+         * };
+         *
+         * Taking shortcut here. We assume that the server always allows the
+         * PRF Hash function and has sent it in the allowed signature
+         * algorithms list received in the Certificate Request message.
+         *
+         * Until we encounter a server that does not, we will take this
+         * shortcut.
+         *
+         * Reason: Otherwise we should have running hashes for SHA512 and SHA224
+         *         in order to satisfy 'weird' needs from the server side.
+         */
+        if( ssl->transform_negotiate->ciphersuite_info->mac ==
+            MBEDTLS_MD_SHA384 )
+        {
+            md_alg = MBEDTLS_MD_SHA384;
+            ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
+        }
+        else
+        {
+            md_alg = MBEDTLS_MD_SHA256;
+            ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256;
+        }
+        ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) );
+
+        /* Info from md_alg will be used instead */
+        hashlen = 0;
+        offset = 2;
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    if( ssl->handshake->ecrs_enabled )
+        rs_ctx = &ssl->handshake->ecrs_ctx.pk;
+#endif
+
+    if( ( ret = mbedtls_pk_sign_restartable( mbedtls_ssl_own_key( ssl ),
+                         md_alg, hash_start, hashlen,
+                         ssl->out_msg + 6 + offset, &n,
+                         ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+        if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+            ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
+#endif
+        return( ret );
+    }
+
+    ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
+    ssl->out_msg[5 + offset] = (unsigned char)( n      );
+
+    ssl->out_msglen  = 6 + n + offset;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
+
+    ssl->state++;
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
+
+    return( ret );
+}
+#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    uint32_t lifetime;
+    size_t ticket_len;
+    unsigned char *ticket;
+    const unsigned char *msg;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) );
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        return( ret );
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    /*
+     * struct {
+     *     uint32 ticket_lifetime_hint;
+     *     opaque ticket<0..2^16-1>;
+     * } NewSessionTicket;
+     *
+     * 0  .  3   ticket_lifetime_hint
+     * 4  .  5   ticket_len (n)
+     * 6  .  5+n ticket content
+     */
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET ||
+        ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
+    }
+
+    msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
+
+    lifetime = ( ((uint32_t) msg[0]) << 24 ) | ( msg[1] << 16 ) |
+               ( msg[2] << 8 ) | ( msg[3] );
+
+    ticket_len = ( msg[4] << 8 ) | ( msg[5] );
+
+    if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
+
+    /* We're not waiting for a NewSessionTicket message any more */
+    ssl->handshake->new_session_ticket = 0;
+    ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
+
+    /*
+     * Zero-length ticket means the server changed his mind and doesn't want
+     * to send a ticket after all, so just forget it
+     */
+    if( ticket_len == 0 )
+        return( 0 );
+
+    mbedtls_platform_zeroize( ssl->session_negotiate->ticket,
+                              ssl->session_negotiate->ticket_len );
+    mbedtls_free( ssl->session_negotiate->ticket );
+    ssl->session_negotiate->ticket = NULL;
+    ssl->session_negotiate->ticket_len = 0;
+
+    if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+    }
+
+    memcpy( ticket, msg + 6, ticket_len );
+
+    ssl->session_negotiate->ticket = ticket;
+    ssl->session_negotiate->ticket_len = ticket_len;
+    ssl->session_negotiate->ticket_lifetime = lifetime;
+
+    /*
+     * RFC 5077 section 3.4:
+     * "If the client receives a session ticket from the server, then it
+     * discards any Session ID that was sent in the ServerHello."
+     */
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) );
+    ssl->session_negotiate->id_len = 0;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+/*
+ * SSL handshake -- client side -- single step
+ */
+int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
+{
+    int ret = 0;
+
+    if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
+
+    if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+        return( ret );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
+    {
+        if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+            return( ret );
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
+     * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
+        ssl->handshake->new_session_ticket != 0 )
+    {
+        ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET;
+    }
+#endif
+
+    switch( ssl->state )
+    {
+        case MBEDTLS_SSL_HELLO_REQUEST:
+            ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
+            break;
+
+       /*
+        *  ==>   ClientHello
+        */
+       case MBEDTLS_SSL_CLIENT_HELLO:
+           ret = ssl_write_client_hello( ssl );
+           break;
+
+       /*
+        *  <==   ServerHello
+        *        Certificate
+        *      ( ServerKeyExchange  )
+        *      ( CertificateRequest )
+        *        ServerHelloDone
+        */
+       case MBEDTLS_SSL_SERVER_HELLO:
+           ret = ssl_parse_server_hello( ssl );
+           break;
+
+       case MBEDTLS_SSL_SERVER_CERTIFICATE:
+           ret = mbedtls_ssl_parse_certificate( ssl );
+           break;
+
+       case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
+           ret = ssl_parse_server_key_exchange( ssl );
+           break;
+
+       case MBEDTLS_SSL_CERTIFICATE_REQUEST:
+           ret = ssl_parse_certificate_request( ssl );
+           break;
+
+       case MBEDTLS_SSL_SERVER_HELLO_DONE:
+           ret = ssl_parse_server_hello_done( ssl );
+           break;
+
+       /*
+        *  ==> ( Certificate/Alert  )
+        *        ClientKeyExchange
+        *      ( CertificateVerify  )
+        *        ChangeCipherSpec
+        *        Finished
+        */
+       case MBEDTLS_SSL_CLIENT_CERTIFICATE:
+           ret = mbedtls_ssl_write_certificate( ssl );
+           break;
+
+       case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
+           ret = ssl_write_client_key_exchange( ssl );
+           break;
+
+       case MBEDTLS_SSL_CERTIFICATE_VERIFY:
+           ret = ssl_write_certificate_verify( ssl );
+           break;
+
+       case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
+           ret = mbedtls_ssl_write_change_cipher_spec( ssl );
+           break;
+
+       case MBEDTLS_SSL_CLIENT_FINISHED:
+           ret = mbedtls_ssl_write_finished( ssl );
+           break;
+
+       /*
+        *  <==   ( NewSessionTicket )
+        *        ChangeCipherSpec
+        *        Finished
+        */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+       case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
+           ret = ssl_parse_new_session_ticket( ssl );
+           break;
+#endif
+
+       case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
+           ret = mbedtls_ssl_parse_change_cipher_spec( ssl );
+           break;
+
+       case MBEDTLS_SSL_SERVER_FINISHED:
+           ret = mbedtls_ssl_parse_finished( ssl );
+           break;
+
+       case MBEDTLS_SSL_FLUSH_BUFFERS:
+           MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
+           ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
+           break;
+
+       case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
+           mbedtls_ssl_handshake_wrapup( ssl );
+           break;
+
+       default:
+           MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
+           return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+   }
+
+    return( ret );
+}
+#endif /* MBEDTLS_SSL_CLI_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_cookie.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_cookie.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_cookie.c	(revision 398)
@@ -0,0 +1,256 @@
+/*
+ *  DTLS cookie callbacks implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * These session callbacks use a simple chained list
+ * to store and retrieve the session information.
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SSL_COOKIE_C)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#define mbedtls_calloc    calloc
+#define mbedtls_free      free
+#endif
+
+#include "mbedtls/ssl_cookie.h"
+#include "mbedtls/ssl_internal.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+/*
+ * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is
+ * available. Try SHA-256 first, 512 wastes resources since we need to stay
+ * with max 32 bytes of cookie for DTLS 1.0
+ */
+#if defined(MBEDTLS_SHA256_C)
+#define COOKIE_MD           MBEDTLS_MD_SHA224
+#define COOKIE_MD_OUTLEN    32
+#define COOKIE_HMAC_LEN     28
+#elif defined(MBEDTLS_SHA512_C)
+#define COOKIE_MD           MBEDTLS_MD_SHA384
+#define COOKIE_MD_OUTLEN    48
+#define COOKIE_HMAC_LEN     28
+#elif defined(MBEDTLS_SHA1_C)
+#define COOKIE_MD           MBEDTLS_MD_SHA1
+#define COOKIE_MD_OUTLEN    20
+#define COOKIE_HMAC_LEN     20
+#else
+#error "DTLS hello verify needs SHA-1 or SHA-2"
+#endif
+
+/*
+ * Cookies are formed of a 4-bytes timestamp (or serial number) and
+ * an HMAC of timestemp and client ID.
+ */
+#define COOKIE_LEN      ( 4 + COOKIE_HMAC_LEN )
+
+void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx )
+{
+    mbedtls_md_init( &ctx->hmac_ctx );
+#if !defined(MBEDTLS_HAVE_TIME)
+    ctx->serial = 0;
+#endif
+    ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT;
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+}
+
+void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay )
+{
+    ctx->timeout = delay;
+}
+
+void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx )
+{
+    mbedtls_md_free( &ctx->hmac_ctx );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_free( &ctx->mutex );
+#endif
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) );
+}
+
+int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng )
+{
+    int ret;
+    unsigned char key[COOKIE_MD_OUTLEN];
+
+    if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 )
+        return( ret );
+
+    ret = mbedtls_md_setup( &ctx->hmac_ctx, mbedtls_md_info_from_type( COOKIE_MD ), 1 );
+    if( ret != 0 )
+        return( ret );
+
+    ret = mbedtls_md_hmac_starts( &ctx->hmac_ctx, key, sizeof( key ) );
+    if( ret != 0 )
+        return( ret );
+
+    mbedtls_platform_zeroize( key, sizeof( key ) );
+
+    return( 0 );
+}
+
+/*
+ * Generate the HMAC part of a cookie
+ */
+static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx,
+                            const unsigned char time[4],
+                            unsigned char **p, unsigned char *end,
+                            const unsigned char *cli_id, size_t cli_id_len )
+{
+    unsigned char hmac_out[COOKIE_MD_OUTLEN];
+
+    if( (size_t)( end - *p ) < COOKIE_HMAC_LEN )
+        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+    if( mbedtls_md_hmac_reset(  hmac_ctx ) != 0 ||
+        mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 ||
+        mbedtls_md_hmac_update( hmac_ctx, cli_id, cli_id_len ) != 0 ||
+        mbedtls_md_hmac_finish( hmac_ctx, hmac_out ) != 0 )
+    {
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    memcpy( *p, hmac_out, COOKIE_HMAC_LEN );
+    *p += COOKIE_HMAC_LEN;
+
+    return( 0 );
+}
+
+/*
+ * Generate cookie for DTLS ClientHello verification
+ */
+int mbedtls_ssl_cookie_write( void *p_ctx,
+                      unsigned char **p, unsigned char *end,
+                      const unsigned char *cli_id, size_t cli_id_len )
+{
+    int ret;
+    mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
+    unsigned long t;
+
+    if( ctx == NULL || cli_id == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    if( (size_t)( end - *p ) < COOKIE_LEN )
+        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+#if defined(MBEDTLS_HAVE_TIME)
+    t = (unsigned long) mbedtls_time( NULL );
+#else
+    t = ctx->serial++;
+#endif
+
+    (*p)[0] = (unsigned char)( t >> 24 );
+    (*p)[1] = (unsigned char)( t >> 16 );
+    (*p)[2] = (unsigned char)( t >>  8 );
+    (*p)[3] = (unsigned char)( t       );
+    *p += 4;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
+#endif
+
+    ret = ssl_cookie_hmac( &ctx->hmac_ctx, *p - 4,
+                           p, end, cli_id, cli_id_len );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
+                MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
+}
+
+/*
+ * Check a cookie
+ */
+int mbedtls_ssl_cookie_check( void *p_ctx,
+                      const unsigned char *cookie, size_t cookie_len,
+                      const unsigned char *cli_id, size_t cli_id_len )
+{
+    unsigned char ref_hmac[COOKIE_HMAC_LEN];
+    int ret = 0;
+    unsigned char *p = ref_hmac;
+    mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
+    unsigned long cur_time, cookie_time;
+
+    if( ctx == NULL || cli_id == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    if( cookie_len != COOKIE_LEN )
+        return( -1 );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
+#endif
+
+    if( ssl_cookie_hmac( &ctx->hmac_ctx, cookie,
+                         &p, p + sizeof( ref_hmac ),
+                         cli_id, cli_id_len ) != 0 )
+        ret = -1;
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
+                MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    if( ret != 0 )
+        return( ret );
+
+    if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
+        return( -1 );
+
+#if defined(MBEDTLS_HAVE_TIME)
+    cur_time = (unsigned long) mbedtls_time( NULL );
+#else
+    cur_time = ctx->serial;
+#endif
+
+    cookie_time = ( (unsigned long) cookie[0] << 24 ) |
+                  ( (unsigned long) cookie[1] << 16 ) |
+                  ( (unsigned long) cookie[2] <<  8 ) |
+                  ( (unsigned long) cookie[3]       );
+
+    if( ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout )
+        return( -1 );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_COOKIE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_srv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_srv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_srv.c	(revision 398)
@@ -0,0 +1,4379 @@
+/*
+ *  SSLv3/TLSv1 server-side functions
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SSL_SRV_C)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free      free
+#endif
+
+#include "mbedtls/debug.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/ssl_internal.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_ECP_C)
+#include "mbedtls/ecp.h"
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME)
+#include "mbedtls/platform_time.h"
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
+int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl,
+                                 const unsigned char *info,
+                                 size_t ilen )
+{
+    if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    mbedtls_free( ssl->cli_id );
+
+    if( ( ssl->cli_id = mbedtls_calloc( 1, ilen ) ) == NULL )
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+    memcpy( ssl->cli_id, info, ilen );
+    ssl->cli_id_len = ilen;
+
+    return( 0 );
+}
+
+void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf,
+                           mbedtls_ssl_cookie_write_t *f_cookie_write,
+                           mbedtls_ssl_cookie_check_t *f_cookie_check,
+                           void *p_cookie )
+{
+    conf->f_cookie_write = f_cookie_write;
+    conf->f_cookie_check = f_cookie_check;
+    conf->p_cookie       = p_cookie;
+}
+#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
+                                     const unsigned char *buf,
+                                     size_t len )
+{
+    int ret;
+    size_t servername_list_size, hostname_len;
+    const unsigned char *p;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) );
+
+    if( len < 2 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                       MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+    servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
+    if( servername_list_size + 2 != len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    p = buf + 2;
+    while( servername_list_size > 2 )
+    {
+        hostname_len = ( ( p[1] << 8 ) | p[2] );
+        if( hostname_len + 3 > servername_list_size )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        }
+
+        if( p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME )
+        {
+            ret = ssl->conf->f_sni( ssl->conf->p_sni,
+                                    ssl, p + 3, hostname_len );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret );
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                        MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+            return( 0 );
+        }
+
+        servername_list_size -= hostname_len + 3;
+        p += hostname_len + 3;
+    }
+
+    if( servername_list_size != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
+                                         const unsigned char *buf,
+                                         size_t len )
+{
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
+    {
+        /* Check verify-data in constant-time. The length OTOH is no secret */
+        if( len    != 1 + ssl->verify_data_len ||
+            buf[0] !=     ssl->verify_data_len ||
+            mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data,
+                          ssl->verify_data_len ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        }
+    }
+    else
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+    {
+        if( len != 1 || buf[0] != 0x0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        }
+
+        ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
+    }
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+
+/*
+ * Status of the implementation of signature-algorithms extension:
+ *
+ * Currently, we are only considering the signature-algorithm extension
+ * to pick a ciphersuite which allows us to send the ServerKeyExchange
+ * message with a signature-hash combination that the user allows.
+ *
+ * We do *not* check whether all certificates in our certificate
+ * chain are signed with an allowed signature-hash pair.
+ * This needs to be done at a later stage.
+ *
+ */
+static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
+                                               const unsigned char *buf,
+                                               size_t len )
+{
+    size_t sig_alg_list_size;
+
+    const unsigned char *p;
+    const unsigned char *end = buf + len;
+
+    mbedtls_md_type_t md_cur;
+    mbedtls_pk_type_t sig_cur;
+
+    if ( len < 2 ) {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                       MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+    sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
+    if( sig_alg_list_size + 2 != len ||
+        sig_alg_list_size % 2 != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    /* Currently we only guarantee signing the ServerKeyExchange message according
+     * to the constraints specified in this extension (see above), so it suffices
+     * to remember only one suitable hash for each possible signature algorithm.
+     *
+     * This will change when we also consider certificate signatures,
+     * in which case we will need to remember the whole signature-hash
+     * pair list from the extension.
+     */
+
+    for( p = buf + 2; p < end; p += 2 )
+    {
+        /* Silently ignore unknown signature or hash algorithms. */
+
+        if( ( sig_cur = mbedtls_ssl_pk_alg_from_sig( p[1] ) ) == MBEDTLS_PK_NONE )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext"
+                                        " unknown sig alg encoding %d", p[1] ) );
+            continue;
+        }
+
+        /* Check if we support the hash the user proposes */
+        md_cur = mbedtls_ssl_md_alg_from_hash( p[0] );
+        if( md_cur == MBEDTLS_MD_NONE )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:"
+                                        " unknown hash alg encoding %d", p[0] ) );
+            continue;
+        }
+
+        if( mbedtls_ssl_check_sig_hash( ssl, md_cur ) == 0 )
+        {
+            mbedtls_ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur );
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:"
+                                        " match sig %d and hash %d",
+                                        sig_cur, md_cur ) );
+        }
+        else
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: "
+                                        "hash alg %d not supported", md_cur ) );
+        }
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
+          MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
+                                                const unsigned char *buf,
+                                                size_t len )
+{
+    size_t list_size, our_size;
+    const unsigned char *p;
+    const mbedtls_ecp_curve_info *curve_info, **curves;
+
+    if ( len < 2 ) {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                       MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+    list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
+    if( list_size + 2 != len ||
+        list_size % 2 != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    /* Should never happen unless client duplicates the extension */
+    if( ssl->handshake->curves != NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    /* Don't allow our peer to make us allocate too much memory,
+     * and leave room for a final 0 */
+    our_size = list_size / 2 + 1;
+    if( our_size > MBEDTLS_ECP_DP_MAX )
+        our_size = MBEDTLS_ECP_DP_MAX;
+
+    if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+    }
+
+    ssl->handshake->curves = curves;
+
+    p = buf + 2;
+    while( list_size > 0 && our_size > 1 )
+    {
+        curve_info = mbedtls_ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] );
+
+        if( curve_info != NULL )
+        {
+            *curves++ = curve_info;
+            our_size--;
+        }
+
+        list_size -= 2;
+        p += 2;
+    }
+
+    return( 0 );
+}
+
+static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
+                                              const unsigned char *buf,
+                                              size_t len )
+{
+    size_t list_size;
+    const unsigned char *p;
+
+    if( len == 0 || (size_t)( buf[0] + 1 ) != len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+    list_size = buf[0];
+
+    p = buf + 1;
+    while( list_size > 0 )
+    {
+        if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
+            p[0] == MBEDTLS_ECP_PF_COMPRESSED )
+        {
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
+            ssl->handshake->ecdh_ctx.point_format = p[0];
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+            ssl->handshake->ecjpake_ctx.point_format = p[0];
+#endif
+            MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
+            return( 0 );
+        }
+
+        list_size--;
+        p++;
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+          MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
+                                   const unsigned char *buf,
+                                   size_t len )
+{
+    int ret;
+
+    if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
+        return( 0 );
+    }
+
+    if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
+                                                buf, len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( ret );
+    }
+
+    /* Only mark the extension as OK when we're sure it is */
+    ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
+                                              const unsigned char *buf,
+                                              size_t len )
+{
+    if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    ssl->session_negotiate->mfl_code = buf[0];
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
+                                         const unsigned char *buf,
+                                         size_t len )
+{
+    if( len != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    ((void) buf);
+
+    if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
+        ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
+                                      const unsigned char *buf,
+                                      size_t len )
+{
+    if( len != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    ((void) buf);
+
+    if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED &&
+        ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
+                                      const unsigned char *buf,
+                                      size_t len )
+{
+    if( len != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    ((void) buf);
+
+    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED &&
+        ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
+                                         unsigned char *buf,
+                                         size_t len )
+{
+    int ret;
+    mbedtls_ssl_session session;
+
+    mbedtls_ssl_session_init( &session );
+
+    if( ssl->conf->f_ticket_parse == NULL ||
+        ssl->conf->f_ticket_write == NULL )
+    {
+        return( 0 );
+    }
+
+    /* Remember the client asked us to send a new ticket */
+    ssl->handshake->new_session_ticket = 1;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) );
+
+    if( len == 0 )
+        return( 0 );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) );
+        return( 0 );
+    }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+    /*
+     * Failures are ok: just ignore the ticket and proceed.
+     */
+    if( ( ret = ssl->conf->f_ticket_parse( ssl->conf->p_ticket, &session,
+                                           buf, len ) ) != 0 )
+    {
+        mbedtls_ssl_session_free( &session );
+
+        if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is not authentic" ) );
+        else if( ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED )
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is expired" ) );
+        else
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_parse", ret );
+
+        return( 0 );
+    }
+
+    /*
+     * Keep the session ID sent by the client, since we MUST send it back to
+     * inform them we're accepting the ticket  (RFC 5077 section 3.4)
+     */
+    session.id_len = ssl->session_negotiate->id_len;
+    memcpy( &session.id, ssl->session_negotiate->id, session.id_len );
+
+    mbedtls_ssl_session_free( ssl->session_negotiate );
+    memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) );
+
+    /* Zeroize instead of free as we copied the content */
+    mbedtls_platform_zeroize( &session, sizeof( mbedtls_ssl_session ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) );
+
+    ssl->handshake->resume = 1;
+
+    /* Don't send a new ticket after all, this one is OK */
+    ssl->handshake->new_session_ticket = 0;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+#if defined(MBEDTLS_SSL_ALPN)
+static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
+                               const unsigned char *buf, size_t len )
+{
+    size_t list_len, cur_len, ours_len;
+    const unsigned char *theirs, *start, *end;
+    const char **ours;
+
+    /* If ALPN not configured, just ignore the extension */
+    if( ssl->conf->alpn_list == NULL )
+        return( 0 );
+
+    /*
+     * opaque ProtocolName<1..2^8-1>;
+     *
+     * struct {
+     *     ProtocolName protocol_name_list<2..2^16-1>
+     * } ProtocolNameList;
+     */
+
+    /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
+    if( len < 4 )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    list_len = ( buf[0] << 8 ) | buf[1];
+    if( list_len != len - 2 )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    /*
+     * Validate peer's list (lengths)
+     */
+    start = buf + 2;
+    end = buf + len;
+    for( theirs = start; theirs != end; theirs += cur_len )
+    {
+        cur_len = *theirs++;
+
+        /* Current identifier must fit in list */
+        if( cur_len > (size_t)( end - theirs ) )
+        {
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        }
+
+        /* Empty strings MUST NOT be included */
+        if( cur_len == 0 )
+        {
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        }
+    }
+
+    /*
+     * Use our order of preference
+     */
+    for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ )
+    {
+        ours_len = strlen( *ours );
+        for( theirs = start; theirs != end; theirs += cur_len )
+        {
+            cur_len = *theirs++;
+
+            if( cur_len == ours_len &&
+                memcmp( theirs, *ours, cur_len ) == 0 )
+            {
+                ssl->alpn_chosen = *ours;
+                return( 0 );
+            }
+        }
+    }
+
+    /* If we get there, no match was found */
+    mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                            MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL );
+    return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+}
+#endif /* MBEDTLS_SSL_ALPN */
+
+/*
+ * Auxiliary functions for ServerHello parsing and related actions
+ */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/*
+ * Return 0 if the given key uses one of the acceptable curves, -1 otherwise
+ */
+#if defined(MBEDTLS_ECDSA_C)
+static int ssl_check_key_curve( mbedtls_pk_context *pk,
+                                const mbedtls_ecp_curve_info **curves )
+{
+    const mbedtls_ecp_curve_info **crv = curves;
+    mbedtls_ecp_group_id grp_id = mbedtls_pk_ec( *pk )->grp.id;
+
+    while( *crv != NULL )
+    {
+        if( (*crv)->grp_id == grp_id )
+            return( 0 );
+        crv++;
+    }
+
+    return( -1 );
+}
+#endif /* MBEDTLS_ECDSA_C */
+
+/*
+ * Try picking a certificate for this ciphersuite,
+ * return 0 on success and -1 on failure.
+ */
+static int ssl_pick_cert( mbedtls_ssl_context *ssl,
+                          const mbedtls_ssl_ciphersuite_t * ciphersuite_info )
+{
+    mbedtls_ssl_key_cert *cur, *list, *fallback = NULL;
+    mbedtls_pk_type_t pk_alg =
+        mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
+    uint32_t flags;
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    if( ssl->handshake->sni_key_cert != NULL )
+        list = ssl->handshake->sni_key_cert;
+    else
+#endif
+        list = ssl->conf->key_cert;
+
+    if( pk_alg == MBEDTLS_PK_NONE )
+        return( 0 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite requires certificate" ) );
+
+    if( list == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "server has no certificate" ) );
+        return( -1 );
+    }
+
+    for( cur = list; cur != NULL; cur = cur->next )
+    {
+        MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
+                          cur->cert );
+
+        if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
+            continue;
+        }
+
+        /*
+         * This avoids sending the client a cert it'll reject based on
+         * keyUsage or other extensions.
+         *
+         * It also allows the user to provision different certificates for
+         * different uses based on keyUsage, eg if they want to avoid signing
+         * and decrypting with the same RSA key.
+         */
+        if( mbedtls_ssl_check_cert_usage( cur->cert, ciphersuite_info,
+                                  MBEDTLS_SSL_IS_SERVER, &flags ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: "
+                                "(extended) key usage extension" ) );
+            continue;
+        }
+
+#if defined(MBEDTLS_ECDSA_C)
+        if( pk_alg == MBEDTLS_PK_ECDSA &&
+            ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
+            continue;
+        }
+#endif
+
+        /*
+         * Try to select a SHA-1 certificate for pre-1.2 clients, but still
+         * present them a SHA-higher cert rather than failing if it's the only
+         * one we got that satisfies the other conditions.
+         */
+        if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 &&
+            cur->cert->sig_md != MBEDTLS_MD_SHA1 )
+        {
+            if( fallback == NULL )
+                fallback = cur;
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate not preferred: "
+                                    "sha-2 with pre-TLS 1.2 client" ) );
+            continue;
+            }
+        }
+
+        /* If we get there, we got a winner */
+        break;
+    }
+
+    if( cur == NULL )
+        cur = fallback;
+
+    /* Do not update ssl->handshake->key_cert unless there is a match */
+    if( cur != NULL )
+    {
+        ssl->handshake->key_cert = cur;
+        MBEDTLS_SSL_DEBUG_CRT( 3, "selected certificate chain, certificate",
+                          ssl->handshake->key_cert->cert );
+        return( 0 );
+    }
+
+    return( -1 );
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+/*
+ * Check if a given ciphersuite is suitable for use with our config/keys/etc
+ * Sets ciphersuite_info only if the suite matches.
+ */
+static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
+                                  const mbedtls_ssl_ciphersuite_t **ciphersuite_info )
+{
+    const mbedtls_ssl_ciphersuite_t *suite_info;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+    mbedtls_pk_type_t sig_type;
+#endif
+
+    suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id );
+    if( suite_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) );
+
+    if( suite_info->min_minor_ver > ssl->minor_ver ||
+        suite_info->max_minor_ver < ssl->minor_ver )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: version" ) );
+        return( 0 );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
+        return( 0 );
+#endif
+
+#if defined(MBEDTLS_ARC4_C)
+    if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
+            suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: rc4" ) );
+        return( 0 );
+    }
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
+        ( ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK ) == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: ecjpake "
+                                    "not configured or ext missing" ) );
+        return( 0 );
+    }
+#endif
+
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
+    if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) &&
+        ( ssl->handshake->curves == NULL ||
+          ssl->handshake->curves[0] == NULL ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: "
+                            "no common elliptic curve" ) );
+        return( 0 );
+    }
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    /* If the ciphersuite requires a pre-shared key and we don't
+     * have one, skip it now rather than failing later */
+    if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) &&
+        ssl->conf->f_psk == NULL &&
+        ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
+          ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) );
+        return( 0 );
+    }
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+    /* If the ciphersuite requires signing, check whether
+     * a suitable hash algorithm is present. */
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        sig_type = mbedtls_ssl_get_ciphersuite_sig_alg( suite_info );
+        if( sig_type != MBEDTLS_PK_NONE &&
+            mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == MBEDTLS_MD_NONE )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm "
+                                        "for signature algorithm %d", sig_type ) );
+            return( 0 );
+        }
+    }
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
+          MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    /*
+     * Final check: if ciphersuite requires us to have a
+     * certificate/key of a particular type:
+     * - select the appropriate certificate if we have one, or
+     * - try the next ciphersuite if we don't
+     * This must be done last since we modify the key_cert list.
+     */
+    if( ssl_pick_cert( ssl, suite_info ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: "
+                            "no suitable certificate" ) );
+        return( 0 );
+    }
+#endif
+
+    *ciphersuite_info = suite_info;
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
+static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
+{
+    int ret, got_common_suite;
+    unsigned int i, j;
+    size_t n;
+    unsigned int ciph_len, sess_len, chal_len;
+    unsigned char *buf, *p;
+    const int *ciphersuites;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+    buf = ssl->in_hdr;
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, 5 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d",
+                   buf[2] ) );
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d",
+                   ( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) );
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, max. version: [%d:%d]",
+                   buf[3], buf[4] ) );
+
+    /*
+     * SSLv2 Client Hello
+     *
+     * Record layer:
+     *     0  .   1   message length
+     *
+     * SSL layer:
+     *     2  .   2   message type
+     *     3  .   4   protocol version
+     */
+    if( buf[2] != MBEDTLS_SSL_HS_CLIENT_HELLO ||
+        buf[3] != MBEDTLS_SSL_MAJOR_VERSION_3 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF;
+
+    if( n < 17 || n > 512 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
+    ssl->minor_ver = ( buf[4] <= ssl->conf->max_minor_ver )
+                     ? buf[4]  : ssl->conf->max_minor_ver;
+
+    if( ssl->minor_ver < ssl->conf->min_minor_ver )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum"
+                            " [%d:%d] < [%d:%d]",
+                            ssl->major_ver, ssl->minor_ver,
+                            ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) );
+
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                     MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
+        return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+    }
+
+    ssl->handshake->max_major_ver = buf[3];
+    ssl->handshake->max_minor_ver = buf[4];
+
+    if( ( ret = mbedtls_ssl_fetch_input( ssl, 2 + n ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
+        return( ret );
+    }
+
+    ssl->handshake->update_checksum( ssl, buf + 2, n );
+
+    buf = ssl->in_msg;
+    n = ssl->in_left - 5;
+
+    /*
+     *    0  .   1   ciphersuitelist length
+     *    2  .   3   session id length
+     *    4  .   5   challenge length
+     *    6  .  ..   ciphersuitelist
+     *   ..  .  ..   session id
+     *   ..  .  ..   challenge
+     */
+    MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, n );
+
+    ciph_len = ( buf[0] << 8 ) | buf[1];
+    sess_len = ( buf[2] << 8 ) | buf[3];
+    chal_len = ( buf[4] << 8 ) | buf[5];
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d",
+                   ciph_len, sess_len, chal_len ) );
+
+    /*
+     * Make sure each parameter length is valid
+     */
+    if( ciph_len < 3 || ( ciph_len % 3 ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    if( sess_len > 32 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    if( chal_len < 8 || chal_len > 32 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    if( n != 6 + ciph_len + sess_len + chal_len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist",
+                   buf + 6, ciph_len );
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id",
+                   buf + 6 + ciph_len, sess_len );
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, challenge",
+                   buf + 6 + ciph_len + sess_len, chal_len );
+
+    p = buf + 6 + ciph_len;
+    ssl->session_negotiate->id_len = sess_len;
+    memset( ssl->session_negotiate->id, 0,
+            sizeof( ssl->session_negotiate->id ) );
+    memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->id_len );
+
+    p += sess_len;
+    memset( ssl->handshake->randbytes, 0, 64 );
+    memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len );
+
+    /*
+     * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
+     */
+    for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 )
+    {
+        if( p[0] == 0 && p[1] == 0 && p[2] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) );
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+            if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV "
+                                    "during renegotiation" ) );
+
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+            ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
+            break;
+        }
+    }
+
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
+    for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 )
+    {
+        if( p[0] == 0 &&
+            p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) &&
+            p[2] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE      ) & 0xff ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) );
+
+            if( ssl->minor_ver < ssl->conf->max_minor_ver )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) );
+
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK );
+
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+
+            break;
+        }
+    }
+#endif /* MBEDTLS_SSL_FALLBACK_SCSV */
+
+    got_common_suite = 0;
+    ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
+    ciphersuite_info = NULL;
+#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
+    for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
+        for( i = 0; ciphersuites[i] != 0; i++ )
+#else
+    for( i = 0; ciphersuites[i] != 0; i++ )
+        for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
+#endif
+        {
+            if( p[0] != 0 ||
+                p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
+                p[2] != ( ( ciphersuites[i]      ) & 0xFF ) )
+                continue;
+
+            got_common_suite = 1;
+
+            if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
+                                               &ciphersuite_info ) ) != 0 )
+                return( ret );
+
+            if( ciphersuite_info != NULL )
+                goto have_ciphersuite_v2;
+        }
+
+    if( got_common_suite )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, "
+                            "but none of them usable" ) );
+        return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE );
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
+        return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
+    }
+
+have_ciphersuite_v2:
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) );
+
+    ssl->session_negotiate->ciphersuite = ciphersuites[i];
+    ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
+
+    /*
+     * SSLv2 Client Hello relevant renegotiation security checks
+     */
+    if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
+        ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    ssl->in_left = 0;
+    ssl->state++;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
+
+/* This function doesn't alert on errors that happen early during
+   ClientHello parsing because they might indicate that the client is
+   not talking SSL/TLS at all and would not understand our alert. */
+static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
+{
+    int ret, got_common_suite;
+    size_t i, j;
+    size_t ciph_offset, comp_offset, ext_offset;
+    size_t msg_len, ciph_len, sess_len, comp_len, ext_len;
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    size_t cookie_offset, cookie_len;
+#endif
+    unsigned char *buf, *p, *ext;
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    int renegotiation_info_seen = 0;
+#endif
+    int handshake_failure = 0;
+    const int *ciphersuites;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+    int major, minor;
+
+    /* If there is no signature-algorithm extension present,
+     * we need to fall back to the default values for allowed
+     * signature-hash pairs. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+    int sig_hash_alg_ext_present = 0;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
+          MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+read_record_header:
+#endif
+    /*
+     * If renegotiating, then the input was read with mbedtls_ssl_read_record(),
+     * otherwise read it ourselves manually in order to support SSLv2
+     * ClientHello, which doesn't use the same record layer format.
+     */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
+#endif
+    {
+        if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 )
+        {
+            /* No alert on a read error. */
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
+            return( ret );
+        }
+    }
+
+    buf = ssl->in_hdr;
+
+#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
+#endif
+        if( ( buf[0] & 0x80 ) != 0 )
+            return( ssl_parse_client_hello_v2( ssl ) );
+#endif
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) );
+
+    /*
+     * SSLv3/TLS Client Hello
+     *
+     * Record layer:
+     *     0  .   0   message type
+     *     1  .   2   protocol version
+     *     3  .   11  DTLS: epoch + record sequence number
+     *     3  .   4   message length
+     */
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d",
+                   buf[0] ) );
+
+    if( buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d",
+                   ( ssl->in_len[0] << 8 ) | ssl->in_len[1] ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, protocol version: [%d:%d]",
+                   buf[1], buf[2] ) );
+
+    mbedtls_ssl_read_version( &major, &minor, ssl->conf->transport, buf + 1 );
+
+    /* According to RFC 5246 Appendix E.1, the version here is typically
+     * "{03,00}, the lowest version number supported by the client, [or] the
+     * value of ClientHello.client_version", so the only meaningful check here
+     * is the major version shouldn't be less than 3 */
+    if( major < MBEDTLS_SSL_MAJOR_VERSION_3 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    /* For DTLS if this is the initial handshake, remember the client sequence
+     * number to use it in our next message (RFC 6347 4.2.1) */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+        && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
+#endif
+        )
+    {
+        /* Epoch should be 0 for initial handshakes */
+        if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        }
+
+        memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 );
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+        if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record, discarding" ) );
+            ssl->next_record_offset = 0;
+            ssl->in_left = 0;
+            goto read_record_header;
+        }
+
+        /* No MAC to check yet, so we can update right now */
+        mbedtls_ssl_dtls_replay_update( ssl );
+#endif
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
+    {
+        /* Set by mbedtls_ssl_read_record() */
+        msg_len = ssl->in_hslen;
+    }
+    else
+#endif
+    {
+        if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        }
+
+        if( ( ret = mbedtls_ssl_fetch_input( ssl,
+                       mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
+            return( ret );
+        }
+
+    /* Done reading this record, get ready for the next one */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+            ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl );
+        else
+#endif
+            ssl->in_left = 0;
+    }
+
+    buf = ssl->in_msg;
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, msg_len );
+
+    ssl->handshake->update_checksum( ssl, buf, msg_len );
+
+    /*
+     * Handshake layer:
+     *     0  .   0   handshake type
+     *     1  .   3   handshake length
+     *     4  .   5   DTLS only: message seqence number
+     *     6  .   8   DTLS only: fragment offset
+     *     9  .  11   DTLS only: fragment length
+     */
+    if( msg_len < mbedtls_ssl_hs_hdr_len( ssl ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", buf[0] ) );
+
+    if( buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d",
+                   ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) );
+
+    /* We don't support fragmentation of ClientHello (yet?) */
+    if( buf[1] != 0 ||
+        msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        /*
+         * Copy the client's handshake message_seq on initial handshakes,
+         * check sequence number on renego.
+         */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+        if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+        {
+            /* This couldn't be done in ssl_prepare_handshake_record() */
+            unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) |
+                                         ssl->in_msg[5];
+
+            if( cli_msg_seq != ssl->handshake->in_msg_seq )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: "
+                                    "%d (expected %d)", cli_msg_seq,
+                                    ssl->handshake->in_msg_seq ) );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+
+            ssl->handshake->in_msg_seq++;
+        }
+        else
+#endif
+        {
+            unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) |
+                                         ssl->in_msg[5];
+            ssl->handshake->out_msg_seq = cli_msg_seq;
+            ssl->handshake->in_msg_seq  = cli_msg_seq + 1;
+        }
+
+        /*
+         * For now we don't support fragmentation, so make sure
+         * fragment_offset == 0 and fragment_length == length
+         */
+        if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 ||
+            memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) );
+            return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+        }
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    buf += mbedtls_ssl_hs_hdr_len( ssl );
+    msg_len -= mbedtls_ssl_hs_hdr_len( ssl );
+
+    /*
+     * ClientHello layer:
+     *     0  .   1   protocol version
+     *     2  .  33   random bytes (starting with 4 bytes of Unix time)
+     *    34  .  35   session id length (1 byte)
+     *    35  . 34+x  session id
+     *   35+x . 35+x  DTLS only: cookie length (1 byte)
+     *   36+x .  ..   DTLS only: cookie
+     *    ..  .  ..   ciphersuite list length (2 bytes)
+     *    ..  .  ..   ciphersuite list
+     *    ..  .  ..   compression alg. list length (1 byte)
+     *    ..  .  ..   compression alg. list
+     *    ..  .  ..   extensions length (2 bytes, optional)
+     *    ..  .  ..   extensions (optional)
+     */
+
+    /*
+     * Minimal length (with everything empty and extensions ommitted) is
+     * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can
+     * read at least up to session id length without worrying.
+     */
+    if( msg_len < 38 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    /*
+     * Check and save the protocol version
+     */
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, version", buf, 2 );
+
+    mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver,
+                      ssl->conf->transport, buf );
+
+    ssl->handshake->max_major_ver = ssl->major_ver;
+    ssl->handshake->max_minor_ver = ssl->minor_ver;
+
+    if( ssl->major_ver < ssl->conf->min_major_ver ||
+        ssl->minor_ver < ssl->conf->min_minor_ver )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum"
+                            " [%d:%d] < [%d:%d]",
+                            ssl->major_ver, ssl->minor_ver,
+                            ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                     MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
+        return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION );
+    }
+
+    if( ssl->major_ver > ssl->conf->max_major_ver )
+    {
+        ssl->major_ver = ssl->conf->max_major_ver;
+        ssl->minor_ver = ssl->conf->max_minor_ver;
+    }
+    else if( ssl->minor_ver > ssl->conf->max_minor_ver )
+        ssl->minor_ver = ssl->conf->max_minor_ver;
+
+    /*
+     * Save client random (inc. Unix time)
+     */
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 2, 32 );
+
+    memcpy( ssl->handshake->randbytes, buf + 2, 32 );
+
+    /*
+     * Check the session ID length and save session ID
+     */
+    sess_len = buf[34];
+
+    if( sess_len > sizeof( ssl->session_negotiate->id ) ||
+        sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 35, sess_len );
+
+    ssl->session_negotiate->id_len = sess_len;
+    memset( ssl->session_negotiate->id, 0,
+            sizeof( ssl->session_negotiate->id ) );
+    memcpy( ssl->session_negotiate->id, buf + 35,
+            ssl->session_negotiate->id_len );
+
+    /*
+     * Check the cookie length and content
+     */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        cookie_offset = 35 + sess_len;
+        cookie_len = buf[cookie_offset];
+
+        if( cookie_offset + 1 + cookie_len + 2 > msg_len )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+        }
+
+        MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie",
+                       buf + cookie_offset + 1, cookie_len );
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
+        if( ssl->conf->f_cookie_check != NULL
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+            && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
+#endif
+            )
+        {
+            if( ssl->conf->f_cookie_check( ssl->conf->p_cookie,
+                                     buf + cookie_offset + 1, cookie_len,
+                                     ssl->cli_id, ssl->cli_id_len ) != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification failed" ) );
+                ssl->handshake->verify_cookie_len = 1;
+            }
+            else
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification passed" ) );
+                ssl->handshake->verify_cookie_len = 0;
+            }
+        }
+        else
+#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+        {
+            /* We know we didn't send a cookie, so it should be empty */
+            if( cookie_len != 0 )
+            {
+                /* This may be an attacker's probe, so don't send an alert */
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification skipped" ) );
+        }
+
+    /*
+     * Check the ciphersuitelist length (will be parsed later)
+     */
+        ciph_offset = cookie_offset + 1 + cookie_len;
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+        ciph_offset = 35 + sess_len;
+
+    ciph_len = ( buf[ciph_offset + 0] << 8 )
+             | ( buf[ciph_offset + 1]      );
+
+    if( ciph_len < 2 ||
+        ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */
+        ( ciph_len % 2 ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist",
+                   buf + ciph_offset + 2,  ciph_len );
+
+    /*
+     * Check the compression algorithms length and pick one
+     */
+    comp_offset = ciph_offset + 2 + ciph_len;
+
+    comp_len = buf[comp_offset];
+
+    if( comp_len < 1 ||
+        comp_len > 16 ||
+        comp_len + comp_offset + 1 > msg_len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, compression",
+                      buf + comp_offset + 1, comp_len );
+
+    ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL;
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    for( i = 0; i < comp_len; ++i )
+    {
+        if( buf[comp_offset + 1 + i] == MBEDTLS_SSL_COMPRESS_DEFLATE )
+        {
+            ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_DEFLATE;
+            break;
+        }
+    }
+#endif
+
+    /* See comments in ssl_write_client_hello() */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL;
+#endif
+
+    /* Do not parse the extensions if the protocol is SSLv3 */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) )
+    {
+#endif
+        /*
+         * Check the extension length
+         */
+        ext_offset = comp_offset + 1 + comp_len;
+        if( msg_len > ext_offset )
+        {
+            if( msg_len < ext_offset + 2 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+
+            ext_len = ( buf[ext_offset + 0] << 8 )
+                    | ( buf[ext_offset + 1]      );
+
+            if( ( ext_len > 0 && ext_len < 4 ) ||
+                msg_len != ext_offset + 2 + ext_len )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+        }
+        else
+            ext_len = 0;
+
+        ext = buf + ext_offset + 2;
+        MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len );
+
+        while( ext_len != 0 )
+        {
+            unsigned int ext_id;
+            unsigned int ext_size;
+            if ( ext_len < 4 ) {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                               MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+            ext_id   = ( ( ext[0] <<  8 ) | ( ext[1] ) );
+            ext_size = ( ( ext[2] <<  8 ) | ( ext[3] ) );
+
+            if( ext_size + 4 > ext_len )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+            switch( ext_id )
+            {
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+            case MBEDTLS_TLS_EXT_SERVERNAME:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) );
+                if( ssl->conf->f_sni == NULL )
+                    break;
+
+                ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+            case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+                renegotiation_info_seen = 1;
+#endif
+
+                ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+            case MBEDTLS_TLS_EXT_SIG_ALG:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
+
+                ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+
+                sig_hash_alg_ext_present = 1;
+                break;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
+          MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+            case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
+
+                ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+
+            case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) );
+                ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
+
+                ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+          MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+            case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) );
+
+                ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+            case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) );
+
+                ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+            case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) );
+
+                ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+            case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) );
+
+                ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+            case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) );
+
+                ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+            case MBEDTLS_TLS_EXT_SESSION_TICKET:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) );
+
+                ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+#if defined(MBEDTLS_SSL_ALPN)
+            case MBEDTLS_TLS_EXT_ALPN:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
+
+                ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size );
+                if( ret != 0 )
+                    return( ret );
+                break;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+            default:
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
+                               ext_id ) );
+            }
+
+            ext_len -= 4 + ext_size;
+            ext += 4 + ext_size;
+
+            if( ext_len > 0 && ext_len < 4 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+        }
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    }
+#endif
+
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
+    for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 )
+    {
+        if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) &&
+            p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE      ) & 0xff ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) );
+
+            if( ssl->minor_ver < ssl->conf->max_minor_ver )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) );
+
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK );
+
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+
+            break;
+        }
+    }
+#endif /* MBEDTLS_SSL_FALLBACK_SCSV */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+
+    /*
+     * Try to fall back to default hash SHA1 if the client
+     * hasn't provided any preferred signature-hash combinations.
+     */
+    if( sig_hash_alg_ext_present == 0 )
+    {
+        mbedtls_md_type_t md_default = MBEDTLS_MD_SHA1;
+
+        if( mbedtls_ssl_check_sig_hash( ssl, md_default ) != 0 )
+            md_default = MBEDTLS_MD_NONE;
+
+        mbedtls_ssl_sig_hash_set_const_hash( &ssl->handshake->hash_algs, md_default );
+    }
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
+          MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+    /*
+     * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
+     */
+    for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 )
+    {
+        if( p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) );
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+            if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV "
+                                            "during renegotiation" ) );
+                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+            }
+#endif
+            ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
+            break;
+        }
+    }
+
+    /*
+     * Renegotiation security checks
+     */
+    if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION &&
+        ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) );
+        handshake_failure = 1;
+    }
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
+             ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
+             renegotiation_info_seen == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) );
+        handshake_failure = 1;
+    }
+    else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
+             ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
+             ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) );
+        handshake_failure = 1;
+    }
+    else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
+             ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
+             renegotiation_info_seen == 1 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) );
+        handshake_failure = 1;
+    }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+    if( handshake_failure == 1 )
+    {
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    /*
+     * Search for a matching ciphersuite
+     * (At the end because we need information from the EC-based extensions
+     * and certificate from the SNI callback triggered by the SNI extension.)
+     */
+    got_common_suite = 0;
+    ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver];
+    ciphersuite_info = NULL;
+#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
+    for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
+        for( i = 0; ciphersuites[i] != 0; i++ )
+#else
+    for( i = 0; ciphersuites[i] != 0; i++ )
+        for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
+#endif
+        {
+            if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
+                p[1] != ( ( ciphersuites[i]      ) & 0xFF ) )
+                continue;
+
+            got_common_suite = 1;
+
+            if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],
+                                               &ciphersuite_info ) ) != 0 )
+                return( ret );
+
+            if( ciphersuite_info != NULL )
+                goto have_ciphersuite;
+        }
+
+    if( got_common_suite )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, "
+                            "but none of them usable" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE );
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+        return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
+    }
+
+have_ciphersuite:
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) );
+
+    ssl->session_negotiate->ciphersuite = ciphersuites[i];
+    ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
+
+    ssl->state++;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        mbedtls_ssl_recv_flight_completed( ssl );
+#endif
+
+    /* Debugging-only output for testsuite */
+#if defined(MBEDTLS_DEBUG_C)                         && \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)                && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info );
+        if( sig_alg != MBEDTLS_PK_NONE )
+        {
+            mbedtls_md_type_t md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs,
+                                                                  sig_alg );
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d",
+                                        mbedtls_ssl_hash_from_md_alg( md_alg ) ) );
+        }
+        else
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "no hash algorithm for signature algorithm "
+                                        "%d - should not happen", sig_alg ) );
+        }
+    }
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
+                                          unsigned char *buf,
+                                          size_t *olen )
+{
+    unsigned char *p = buf;
+
+    if( ssl->session_negotiate->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
+    {
+        *olen = 0;
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 0x00;
+
+    *olen = 4;
+}
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
+                                            unsigned char *buf,
+                                            size_t *olen )
+{
+    unsigned char *p = buf;
+    const mbedtls_ssl_ciphersuite_t *suite = NULL;
+    const mbedtls_cipher_info_t *cipher = NULL;
+
+    if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
+        ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        *olen = 0;
+        return;
+    }
+
+    /*
+     * RFC 7366: "If a server receives an encrypt-then-MAC request extension
+     * from a client and then selects a stream or Authenticated Encryption
+     * with Associated Data (AEAD) ciphersuite, it MUST NOT send an
+     * encrypt-then-MAC response extension back to the client."
+     */
+    if( ( suite = mbedtls_ssl_ciphersuite_from_id(
+                    ssl->session_negotiate->ciphersuite ) ) == NULL ||
+        ( cipher = mbedtls_cipher_info_from_type( suite->cipher ) ) == NULL ||
+        cipher->mode != MBEDTLS_MODE_CBC )
+    {
+        *olen = 0;
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 0x00;
+
+    *olen = 4;
+}
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
+                                       unsigned char *buf,
+                                       size_t *olen )
+{
+    unsigned char *p = buf;
+
+    if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
+        ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        *olen = 0;
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret "
+                        "extension" ) );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 0x00;
+
+    *olen = 4;
+}
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
+                                          unsigned char *buf,
+                                          size_t *olen )
+{
+    unsigned char *p = buf;
+
+    if( ssl->handshake->new_session_ticket == 0 )
+    {
+        *olen = 0;
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 0x00;
+
+    *olen = 4;
+}
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
+                                         unsigned char *buf,
+                                         size_t *olen )
+{
+    unsigned char *p = buf;
+
+    if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION )
+    {
+        *olen = 0;
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO      ) & 0xFF );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
+    {
+        *p++ = 0x00;
+        *p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF;
+        *p++ = ssl->verify_data_len * 2 & 0xFF;
+
+        memcpy( p, ssl->peer_verify_data, ssl->verify_data_len );
+        p += ssl->verify_data_len;
+        memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
+        p += ssl->verify_data_len;
+    }
+    else
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+    {
+        *p++ = 0x00;
+        *p++ = 0x01;
+        *p++ = 0x00;
+    }
+
+    *olen = p - buf;
+}
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
+                                               unsigned char *buf,
+                                               size_t *olen )
+{
+    unsigned char *p = buf;
+
+    if( ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE )
+    {
+        *olen = 0;
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 1;
+
+    *p++ = ssl->session_negotiate->mfl_code;
+
+    *olen = 5;
+}
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
+                                                   unsigned char *buf,
+                                                   size_t *olen )
+{
+    unsigned char *p = buf;
+    ((void) ssl);
+
+    if( ( ssl->handshake->cli_exts &
+          MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT ) == 0 )
+    {
+        *olen = 0;
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) );
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS      ) & 0xFF );
+
+    *p++ = 0x00;
+    *p++ = 2;
+
+    *p++ = 1;
+    *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
+
+    *olen = 6;
+}
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
+                                        unsigned char *buf,
+                                        size_t *olen )
+{
+    int ret;
+    unsigned char *p = buf;
+    const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+    size_t kkpp_len;
+
+    *olen = 0;
+
+    /* Skip costly computation if not needed */
+    if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
+        MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+        return;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, ecjpake kkpp extension" ) );
+
+    if( end - p < 4 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+        return;
+    }
+
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP      ) & 0xFF );
+
+    ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
+                                        p + 2, end - p - 2, &kkpp_len,
+                                        ssl->conf->f_rng, ssl->conf->p_rng );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
+        return;
+    }
+
+    *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
+    *p++ = (unsigned char)( ( kkpp_len      ) & 0xFF );
+
+    *olen = kkpp_len + 4;
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_SSL_ALPN )
+static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
+                                unsigned char *buf, size_t *olen )
+{
+    if( ssl->alpn_chosen == NULL )
+    {
+        *olen = 0;
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding alpn extension" ) );
+
+    /*
+     * 0 . 1    ext identifier
+     * 2 . 3    ext length
+     * 4 . 5    protocol list length
+     * 6 . 6    protocol name length
+     * 7 . 7+n  protocol name
+     */
+    buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
+    buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN      ) & 0xFF );
+
+    *olen = 7 + strlen( ssl->alpn_chosen );
+
+    buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
+    buf[3] = (unsigned char)( ( ( *olen - 4 )      ) & 0xFF );
+
+    buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
+    buf[5] = (unsigned char)( ( ( *olen - 6 )      ) & 0xFF );
+
+    buf[6] = (unsigned char)( ( ( *olen - 7 )      ) & 0xFF );
+
+    memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 );
+}
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
+static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    unsigned char *p = ssl->out_msg + 4;
+    unsigned char *cookie_len_byte;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello verify request" ) );
+
+    /*
+     * struct {
+     *   ProtocolVersion server_version;
+     *   opaque cookie<0..2^8-1>;
+     * } HelloVerifyRequest;
+     */
+
+    /* The RFC is not clear on this point, but sending the actual negotiated
+     * version looks like the most interoperable thing to do. */
+    mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
+                       ssl->conf->transport, p );
+    MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
+    p += 2;
+
+    /* If we get here, f_cookie_check is not null */
+    if( ssl->conf->f_cookie_write == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "inconsistent cookie callbacks" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    /* Skip length byte until we know the length */
+    cookie_len_byte = p++;
+
+    if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie,
+                                     &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN,
+                                     ssl->cli_id, ssl->cli_id_len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "f_cookie_write", ret );
+        return( ret );
+    }
+
+    *cookie_len_byte = (unsigned char)( p - ( cookie_len_byte + 1 ) );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte );
+
+    ssl->out_msglen  = p - ssl->out_msg;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
+
+    ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT;
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+        return( ret );
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+
+static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_HAVE_TIME)
+    mbedtls_time_t t;
+#endif
+    int ret;
+    size_t olen, ext_len = 0, n;
+    unsigned char *buf, *p;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello" ) );
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->handshake->verify_cookie_len != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) );
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) );
+
+        return( ssl_write_hello_verify_request( ssl ) );
+    }
+#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+
+    if( ssl->conf->f_rng == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") );
+        return( MBEDTLS_ERR_SSL_NO_RNG );
+    }
+
+    /*
+     *     0  .   0   handshake type
+     *     1  .   3   handshake length
+     *     4  .   5   protocol version
+     *     6  .   9   UNIX time()
+     *    10  .  37   random bytes
+     */
+    buf = ssl->out_msg;
+    p = buf + 4;
+
+    mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
+                       ssl->conf->transport, p );
+    p += 2;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
+                        buf[4], buf[5] ) );
+
+#if defined(MBEDTLS_HAVE_TIME)
+    t = mbedtls_time( NULL );
+    *p++ = (unsigned char)( t >> 24 );
+    *p++ = (unsigned char)( t >> 16 );
+    *p++ = (unsigned char)( t >>  8 );
+    *p++ = (unsigned char)( t       );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
+#else
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
+        return( ret );
+
+    p += 4;
+#endif /* MBEDTLS_HAVE_TIME */
+
+    if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 )
+        return( ret );
+
+    p += 28;
+
+    memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
+
+    /*
+     * Resume is 0  by default, see ssl_handshake_init().
+     * It may be already set to 1 by ssl_parse_session_ticket_ext().
+     * If not, try looking up session ID in our cache.
+     */
+    if( ssl->handshake->resume == 0 &&
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+        ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE &&
+#endif
+        ssl->session_negotiate->id_len != 0 &&
+        ssl->conf->f_get_cache != NULL &&
+        ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
+        ssl->handshake->resume = 1;
+    }
+
+    if( ssl->handshake->resume == 0 )
+    {
+        /*
+         * New session, create a new session id,
+         * unless we're about to issue a session ticket
+         */
+        ssl->state++;
+
+#if defined(MBEDTLS_HAVE_TIME)
+        ssl->session_negotiate->start = mbedtls_time( NULL );
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+        if( ssl->handshake->new_session_ticket != 0 )
+        {
+            ssl->session_negotiate->id_len = n = 0;
+            memset( ssl->session_negotiate->id, 0, 32 );
+        }
+        else
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+        {
+            ssl->session_negotiate->id_len = n = 32;
+            if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id,
+                                    n ) ) != 0 )
+                return( ret );
+        }
+    }
+    else
+    {
+        /*
+         * Resuming a session
+         */
+        n = ssl->session_negotiate->id_len;
+        ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
+
+        if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
+            return( ret );
+        }
+    }
+
+    /*
+     *    38  .  38     session id length
+     *    39  . 38+n    session id
+     *   39+n . 40+n    chosen ciphersuite
+     *   41+n . 41+n    chosen compression alg.
+     *   42+n . 43+n    extensions length
+     *   44+n . 43+n+m  extensions
+     */
+    *p++ = (unsigned char) ssl->session_negotiate->id_len;
+    memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->id_len );
+    p += ssl->session_negotiate->id_len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
+    MBEDTLS_SSL_DEBUG_BUF( 3,   "server hello, session id", buf + 39, n );
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
+                   ssl->handshake->resume ? "a" : "no" ) );
+
+    *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 );
+    *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite      );
+    *p++ = (unsigned char)( ssl->session_negotiate->compression      );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s",
+           mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) );
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X",
+                   ssl->session_negotiate->compression ) );
+
+    /* Do not write the extensions if the protocol is SSLv3 */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) )
+    {
+#endif
+
+    /*
+     *  First write extensions, then the total length
+     */
+    ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+    ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    if ( mbedtls_ssl_ciphersuite_uses_ec(
+         mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ) ) )
+    {
+        ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
+        ext_len += olen;
+    }
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+#if defined(MBEDTLS_SSL_ALPN)
+    ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
+    ext_len += olen;
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) );
+
+    if( ext_len > 0 )
+    {
+        *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
+        *p++ = (unsigned char)( ( ext_len      ) & 0xFF );
+        p += ext_len;
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    }
+#endif
+
+    ssl->out_msglen  = p - buf;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO;
+
+    ret = mbedtls_ssl_write_handshake_msg( ssl );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) );
+
+    return( ret );
+}
+
+#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)       && \
+    !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)   && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)  && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
+{
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->transform_negotiate->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
+
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+#else
+static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->transform_negotiate->ciphersuite_info;
+    size_t dn_size, total_dn_size; /* excluding length bytes */
+    size_t ct_len, sa_len; /* including length bytes */
+    unsigned char *buf, *p;
+    const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+    const mbedtls_x509_crt *crt;
+    int authmode;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
+
+    ssl->state++;
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET )
+        authmode = ssl->handshake->sni_authmode;
+    else
+#endif
+        authmode = ssl->conf->authmode;
+
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
+        authmode == MBEDTLS_SSL_VERIFY_NONE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
+        return( 0 );
+    }
+
+    /*
+     *     0  .   0   handshake type
+     *     1  .   3   handshake length
+     *     4  .   4   cert type count
+     *     5  .. m-1  cert types
+     *     m  .. m+1  sig alg length (TLS 1.2 only)
+     *    m+1 .. n-1  SignatureAndHashAlgorithms (TLS 1.2 only)
+     *     n  .. n+1  length of all DNs
+     *    n+2 .. n+3  length of DN 1
+     *    n+4 .. ...  Distinguished Name #1
+     *    ... .. ...  length of DN 2, etc.
+     */
+    buf = ssl->out_msg;
+    p = buf + 4;
+
+    /*
+     * Supported certificate types
+     *
+     *     ClientCertificateType certificate_types<1..2^8-1>;
+     *     enum { (255) } ClientCertificateType;
+     */
+    ct_len = 0;
+
+#if defined(MBEDTLS_RSA_C)
+    p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+    p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
+#endif
+
+    p[0] = (unsigned char) ct_len++;
+    p += ct_len;
+
+    sa_len = 0;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    /*
+     * Add signature_algorithms for verify (TLS 1.2)
+     *
+     *     SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>;
+     *
+     *     struct {
+     *           HashAlgorithm hash;
+     *           SignatureAlgorithm signature;
+     *     } SignatureAndHashAlgorithm;
+     *
+     *     enum { (255) } HashAlgorithm;
+     *     enum { (255) } SignatureAlgorithm;
+     */
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        const int *cur;
+
+        /*
+         * Supported signature algorithms
+         */
+        for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ )
+        {
+            unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur );
+
+            if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) )
+                continue;
+
+#if defined(MBEDTLS_RSA_C)
+            p[2 + sa_len++] = hash;
+            p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA;
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+            p[2 + sa_len++] = hash;
+            p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA;
+#endif
+        }
+
+        p[0] = (unsigned char)( sa_len >> 8 );
+        p[1] = (unsigned char)( sa_len      );
+        sa_len += 2;
+        p += sa_len;
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+    /*
+     * DistinguishedName certificate_authorities<0..2^16-1>;
+     * opaque DistinguishedName<1..2^16-1>;
+     */
+    p += 2;
+
+    total_dn_size = 0;
+
+    if( ssl->conf->cert_req_ca_list ==  MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED )
+    {
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+        if( ssl->handshake->sni_ca_chain != NULL )
+            crt = ssl->handshake->sni_ca_chain;
+        else
+#endif
+            crt = ssl->conf->ca_chain;
+
+        while( crt != NULL && crt->version != 0 )
+        {
+            dn_size = crt->subject_raw.len;
+
+            if( end < p ||
+                (size_t)( end - p ) < dn_size ||
+                (size_t)( end - p ) < 2 + dn_size )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) );
+                break;
+            }
+
+            *p++ = (unsigned char)( dn_size >> 8 );
+            *p++ = (unsigned char)( dn_size      );
+            memcpy( p, crt->subject_raw.p, dn_size );
+            p += dn_size;
+
+            MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size );
+
+            total_dn_size += 2 + dn_size;
+            crt = crt->next;
+        }
+    }
+
+    ssl->out_msglen  = p - buf;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST;
+    ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size  >> 8 );
+    ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size       );
+
+    ret = mbedtls_ssl_write_handshake_msg( ssl );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) );
+
+    return( ret );
+}
+#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
+        return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
+    }
+
+    if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx,
+                                 mbedtls_pk_ec( *mbedtls_ssl_own_key( ssl ) ),
+                                 MBEDTLS_ECDH_OURS ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret );
+        return( ret );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
+          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
+    defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
+                                           size_t *signature_len )
+{
+    /* Append the signature to ssl->out_msg, leaving 2 bytes for the
+     * signature length which will be added in ssl_write_server_key_exchange
+     * after the call to ssl_prepare_server_key_exchange.
+     * ssl_write_server_key_exchange also takes care of incrementing
+     * ssl->out_msglen. */
+    unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2;
+    size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN
+                           - sig_start );
+    int ret = ssl->conf->f_async_resume( ssl,
+                                         sig_start, signature_len, sig_max_len );
+    if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
+    {
+        ssl->handshake->async_in_progress = 0;
+        mbedtls_ssl_set_async_operation_data( ssl, NULL );
+    }
+    MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret );
+    return( ret );
+}
+#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
+          defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
+
+/* Prepare the ServerKeyExchange message, up to and including
+ * calculating the signature if any, but excluding formatting the
+ * signature and sending the message. */
+static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
+                                            size_t *signature_len )
+{
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+                            ssl->transform_negotiate->ciphersuite_info;
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+    unsigned char *dig_signed = NULL;
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
+
+    (void) ciphersuite_info; /* unused in some configurations */
+#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+    (void) signature_len;
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+
+    ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
+
+    /*
+     *
+     * Part 1: Provide key exchange parameters for chosen ciphersuite.
+     *
+     */
+
+    /*
+     * - ECJPAKE key exchanges
+     */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        int ret;
+        size_t len = 0;
+
+        ret = mbedtls_ecjpake_write_round_two(
+            &ssl->handshake->ecjpake_ctx,
+            ssl->out_msg + ssl->out_msglen,
+            MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len,
+            ssl->conf->f_rng, ssl->conf->p_rng );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
+            return( ret );
+        }
+
+        ssl->out_msglen += len;
+    }
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+    /*
+     * For (EC)DHE key exchanges with PSK, parameters are prefixed by support
+     * identity hint (RFC 4279, Sec. 3). Until someone needs this feature,
+     * we use empty support identity hints here.
+     **/
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)   || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
+    {
+        ssl->out_msg[ssl->out_msglen++] = 0x00;
+        ssl->out_msg[ssl->out_msglen++] = 0x00;
+    }
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+
+    /*
+     * - DHE key exchanges
+     */
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
+    if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) )
+    {
+        int ret;
+        size_t len = 0;
+
+        if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) );
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+        }
+
+        /*
+         * Ephemeral DH parameters:
+         *
+         * struct {
+         *     opaque dh_p<1..2^16-1>;
+         *     opaque dh_g<1..2^16-1>;
+         *     opaque dh_Ys<1..2^16-1>;
+         * } ServerDHParams;
+         */
+        if( ( ret = mbedtls_dhm_set_group( &ssl->handshake->dhm_ctx,
+                                           &ssl->conf->dhm_P,
+                                           &ssl->conf->dhm_G ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_set_group", ret );
+            return( ret );
+        }
+
+        if( ( ret = mbedtls_dhm_make_params(
+                  &ssl->handshake->dhm_ctx,
+                  (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
+                  ssl->out_msg + ssl->out_msglen, &len,
+                  ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret );
+            return( ret );
+        }
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+        dig_signed = ssl->out_msg + ssl->out_msglen;
+#endif
+
+        ssl->out_msglen += len;
+
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X  );
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P  );
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G  );
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
+    }
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED */
+
+    /*
+     * - ECDHE key exchanges
+     */
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
+    if( mbedtls_ssl_ciphersuite_uses_ecdhe( ciphersuite_info ) )
+    {
+        /*
+         * Ephemeral ECDH parameters:
+         *
+         * struct {
+         *     ECParameters curve_params;
+         *     ECPoint      public;
+         * } ServerECDHParams;
+         */
+        const mbedtls_ecp_curve_info **curve = NULL;
+        const mbedtls_ecp_group_id *gid;
+        int ret;
+        size_t len = 0;
+
+        /* Match our preference list against the offered curves */
+        for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
+            for( curve = ssl->handshake->curves; *curve != NULL; curve++ )
+                if( (*curve)->grp_id == *gid )
+                    goto curve_matching_done;
+
+curve_matching_done:
+        if( curve == NULL || *curve == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) );
+            return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN );
+        }
+
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) );
+
+        if( ( ret = mbedtls_ecdh_setup( &ssl->handshake->ecdh_ctx,
+                                        (*curve)->grp_id ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret );
+            return( ret );
+        }
+
+        if( ( ret = mbedtls_ecdh_make_params(
+                  &ssl->handshake->ecdh_ctx, &len,
+                  ssl->out_msg + ssl->out_msglen,
+                  MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen,
+                  ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
+            return( ret );
+        }
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+        dig_signed = ssl->out_msg + ssl->out_msglen;
+#endif
+
+        ssl->out_msglen += len;
+
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Q );
+    }
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
+
+    /*
+     *
+     * Part 2: For key exchanges involving the server signing the
+     *         exchange parameters, compute and add the signature here.
+     *
+     */
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+    if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
+    {
+        size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
+        size_t hashlen = 0;
+        unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+        int ret;
+
+        /*
+         * 2.1: Choose hash algorithm:
+         * A: For TLS 1.2, obey signature-hash-algorithm extension
+         *    to choose appropriate hash.
+         * B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1
+         *    (RFC 4492, Sec. 5.4)
+         * C: Otherwise, use MD5 + SHA1 (RFC 4346, Sec. 7.4.3)
+         */
+
+        mbedtls_md_type_t md_alg;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        mbedtls_pk_type_t sig_alg =
+            mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
+        if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+        {
+            /* A: For TLS 1.2, obey signature-hash-algorithm extension
+             *    (RFC 5246, Sec. 7.4.1.4.1). */
+            if( sig_alg == MBEDTLS_PK_NONE ||
+                ( md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs,
+                                                          sig_alg ) ) == MBEDTLS_MD_NONE )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                /* (... because we choose a cipher suite
+                 *      only if there is a matching hash.) */
+                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+            }
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
+        {
+            /* B: Default hash SHA1 */
+            md_alg = MBEDTLS_MD_SHA1;
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
+          MBEDTLS_SSL_PROTO_TLS1_1 */
+        {
+            /* C: MD5 + SHA1 */
+            md_alg = MBEDTLS_MD_NONE;
+        }
+
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) );
+
+        /*
+         * 2.2: Compute the hash to be signed
+         */
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+        if( md_alg == MBEDTLS_MD_NONE )
+        {
+            hashlen = 36;
+            ret = mbedtls_ssl_get_key_exchange_md_ssl_tls( ssl, hash,
+                                                           dig_signed,
+                                                           dig_signed_len );
+            if( ret != 0 )
+                return( ret );
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
+          MBEDTLS_SSL_PROTO_TLS1_1 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( md_alg != MBEDTLS_MD_NONE )
+        {
+            ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
+                                                          dig_signed,
+                                                          dig_signed_len,
+                                                          md_alg );
+            if( ret != 0 )
+                return( ret );
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+          MBEDTLS_SSL_PROTO_TLS1_2 */
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
+
+        /*
+         * 2.3: Compute and add the signature
+         */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+        {
+            /*
+             * For TLS 1.2, we need to specify signature and hash algorithm
+             * explicitly through a prefix to the signature.
+             *
+             * struct {
+             *    HashAlgorithm hash;
+             *    SignatureAlgorithm signature;
+             * } SignatureAndHashAlgorithm;
+             *
+             * struct {
+             *    SignatureAndHashAlgorithm algorithm;
+             *    opaque signature<0..2^16-1>;
+             * } DigitallySigned;
+             *
+             */
+
+            ssl->out_msg[ssl->out_msglen++] =
+                mbedtls_ssl_hash_from_md_alg( md_alg );
+            ssl->out_msg[ssl->out_msglen++] =
+                mbedtls_ssl_sig_from_pk_alg( sig_alg );
+        }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+        if( ssl->conf->f_async_sign_start != NULL )
+        {
+            ret = ssl->conf->f_async_sign_start( ssl,
+                                                 mbedtls_ssl_own_cert( ssl ),
+                                                 md_alg, hash, hashlen );
+            switch( ret )
+            {
+            case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
+                /* act as if f_async_sign was null */
+                break;
+            case 0:
+                ssl->handshake->async_in_progress = 1;
+                return( ssl_resume_server_key_exchange( ssl, signature_len ) );
+            case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
+                ssl->handshake->async_in_progress = 1;
+                return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
+            default:
+                MBEDTLS_SSL_DEBUG_RET( 1, "f_async_sign_start", ret );
+                return( ret );
+            }
+        }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+        if( mbedtls_ssl_own_key( ssl ) == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) );
+            return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+        }
+
+        /* Append the signature to ssl->out_msg, leaving 2 bytes for the
+         * signature length which will be added in ssl_write_server_key_exchange
+         * after the call to ssl_prepare_server_key_exchange.
+         * ssl_write_server_key_exchange also takes care of incrementing
+         * ssl->out_msglen. */
+        if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ),
+                                     md_alg, hash, hashlen,
+                                     ssl->out_msg + ssl->out_msglen + 2,
+                                     signature_len,
+                                     ssl->conf->f_rng,
+                                     ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
+            return( ret );
+        }
+    }
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+
+    return( 0 );
+}
+
+/* Prepare the ServerKeyExchange message and send it. For ciphersuites
+ * that do not include a ServerKeyExchange message, do nothing. Either
+ * way, if successful, move on to the next step in the SSL state
+ * machine. */
+static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    size_t signature_len = 0;
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+                            ssl->transform_negotiate->ciphersuite_info;
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+    /* Extract static ECDH parameters and abort if ServerKeyExchange
+     * is not needed. */
+    if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
+    {
+        /* For suites involving ECDH, extract DH parameters
+         * from certificate at this point. */
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
+        if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
+        {
+            ssl_get_ecdh_params_from_cert( ssl );
+        }
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
+
+        /* Key exchanges not involving ephemeral keys don't use
+         * ServerKeyExchange, so end here. */
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
+        ssl->state++;
+        return( 0 );
+    }
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
+    defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+    /* If we have already prepared the message and there is an ongoing
+     * signature operation, resume signing. */
+    if( ssl->handshake->async_in_progress != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) );
+        ret = ssl_resume_server_key_exchange( ssl, &signature_len );
+    }
+    else
+#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
+          defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
+    {
+        /* ServerKeyExchange is needed. Prepare the message. */
+        ret = ssl_prepare_server_key_exchange( ssl, &signature_len );
+    }
+
+    if( ret != 0 )
+    {
+        /* If we're starting to write a new message, set ssl->out_msglen
+         * to 0. But if we're resuming after an asynchronous message,
+         * out_msglen is the amount of data written so far and mst be
+         * preserved. */
+        if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) );
+        else
+            ssl->out_msglen = 0;
+        return( ret );
+    }
+
+    /* If there is a signature, write its length.
+     * ssl_prepare_server_key_exchange already wrote the signature
+     * itself at its proper place in the output buffer. */
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+    if( signature_len != 0 )
+    {
+        ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 );
+        ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len      );
+
+        MBEDTLS_SSL_DEBUG_BUF( 3, "my signature",
+                               ssl->out_msg + ssl->out_msglen,
+                               signature_len );
+
+        /* Skip over the already-written signature */
+        ssl->out_msglen += signature_len;
+    }
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+
+    /* Add header and send. */
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
+
+    ssl->state++;
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
+    return( 0 );
+}
+
+static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) );
+
+    ssl->out_msglen  = 4;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO_DONE;
+
+    ssl->state++;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        mbedtls_ssl_send_flight_completed( ssl );
+#endif
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+        return( ret );
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
+    defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char **p,
+                                       const unsigned char *end )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    size_t n;
+
+    /*
+     * Receive G^Y mod P, premaster = (G^Y)^X mod P
+     */
+    if( *p + 2 > end )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+    }
+
+    n = ( (*p)[0] << 8 ) | (*p)[1];
+    *p += 2;
+
+    if( *p + n > end )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+    }
+
+    if( ( ret = mbedtls_dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_read_public", ret );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
+    }
+
+    *p += n;
+
+    MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
+
+    return( ret );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) ||                           \
+    defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl,
+                                   unsigned char *peer_pms,
+                                   size_t *peer_pmslen,
+                                   size_t peer_pmssize )
+{
+    int ret = ssl->conf->f_async_resume( ssl,
+                                         peer_pms, peer_pmslen, peer_pmssize );
+    if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
+    {
+        ssl->handshake->async_in_progress = 0;
+        mbedtls_ssl_set_async_operation_data( ssl, NULL );
+    }
+    MBEDTLS_SSL_DEBUG_RET( 2, "ssl_decrypt_encrypted_pms", ret );
+    return( ret );
+}
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
+                                      const unsigned char *p,
+                                      const unsigned char *end,
+                                      unsigned char *peer_pms,
+                                      size_t *peer_pmslen,
+                                      size_t peer_pmssize )
+{
+    int ret;
+    mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl );
+    mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk;
+    size_t len = mbedtls_pk_get_len( public_key );
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+    /* If we have already started decoding the message and there is an ongoing
+     * decryption operation, resume signing. */
+    if( ssl->handshake->async_in_progress != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming decryption operation" ) );
+        return( ssl_resume_decrypt_pms( ssl,
+                                        peer_pms, peer_pmslen, peer_pmssize ) );
+    }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+    /*
+     * Prepare to decrypt the premaster using own private RSA key
+     */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        if ( p + 2 > end ) {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        }
+        if( *p++ != ( ( len >> 8 ) & 0xFF ) ||
+            *p++ != ( ( len      ) & 0xFF ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        }
+    }
+#endif
+
+    if( p + len != end )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+    }
+
+    /*
+     * Decrypt the premaster secret
+     */
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+    if( ssl->conf->f_async_decrypt_start != NULL )
+    {
+        ret = ssl->conf->f_async_decrypt_start( ssl,
+                                                mbedtls_ssl_own_cert( ssl ),
+                                                p, len );
+        switch( ret )
+        {
+        case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
+            /* act as if f_async_decrypt_start was null */
+            break;
+        case 0:
+            ssl->handshake->async_in_progress = 1;
+            return( ssl_resume_decrypt_pms( ssl,
+                                            peer_pms,
+                                            peer_pmslen,
+                                            peer_pmssize ) );
+        case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
+            ssl->handshake->async_in_progress = 1;
+            return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
+        default:
+            MBEDTLS_SSL_DEBUG_RET( 1, "f_async_decrypt_start", ret );
+            return( ret );
+        }
+    }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+    if( ! mbedtls_pk_can_do( private_key, MBEDTLS_PK_RSA ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) );
+        return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+    }
+
+    ret = mbedtls_pk_decrypt( private_key, p, len,
+                              peer_pms, peer_pmslen, peer_pmssize,
+                              ssl->conf->f_rng, ssl->conf->p_rng );
+    return( ret );
+}
+
+static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
+                                    const unsigned char *p,
+                                    const unsigned char *end,
+                                    size_t pms_offset )
+{
+    int ret;
+    unsigned char *pms = ssl->handshake->premaster + pms_offset;
+    unsigned char ver[2];
+    unsigned char fake_pms[48], peer_pms[48];
+    unsigned char mask;
+    size_t i, peer_pmslen;
+    unsigned int diff;
+
+    /* In case of a failure in decryption, the decryption may write less than
+     * 2 bytes of output, but we always read the first two bytes. It doesn't
+     * matter in the end because diff will be nonzero in that case due to
+     * peer_pmslen being less than 48, and we only care whether diff is 0.
+     * But do initialize peer_pms for robustness anyway. This also makes
+     * memory analyzers happy (don't access uninitialized memory, even
+     * if it's an unsigned char). */
+    peer_pms[0] = peer_pms[1] = ~0;
+
+    ret = ssl_decrypt_encrypted_pms( ssl, p, end,
+                                     peer_pms,
+                                     &peer_pmslen,
+                                     sizeof( peer_pms ) );
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+    if ( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
+        return( ret );
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+    mbedtls_ssl_write_version( ssl->handshake->max_major_ver,
+                               ssl->handshake->max_minor_ver,
+                               ssl->conf->transport, ver );
+
+    /* Avoid data-dependent branches while checking for invalid
+     * padding, to protect against timing-based Bleichenbacher-type
+     * attacks. */
+    diff  = (unsigned int) ret;
+    diff |= peer_pmslen ^ 48;
+    diff |= peer_pms[0] ^ ver[0];
+    diff |= peer_pms[1] ^ ver[1];
+
+    /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
+    /* MSVC has a warning about unary minus on unsigned, but this is
+     * well-defined and precisely what we want to do here */
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4146 )
+#endif
+    mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+    /*
+     * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
+     * must not cause the connection to end immediately; instead, send a
+     * bad_record_mac later in the handshake.
+     * To protect against timing-based variants of the attack, we must
+     * not have any branch that depends on whether the decryption was
+     * successful. In particular, always generate the fake premaster secret,
+     * regardless of whether it will ultimately influence the output or not.
+     */
+    ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) );
+    if( ret != 0 )
+    {
+        /* It's ok to abort on an RNG failure, since this does not reveal
+         * anything about the RSA decryption. */
+        return( ret );
+    }
+
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+    if( diff != 0 )
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
+#endif
+
+    if( sizeof( ssl->handshake->premaster ) < pms_offset ||
+        sizeof( ssl->handshake->premaster ) - pms_offset < 48 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+    ssl->handshake->pmslen = 48;
+
+    /* Set pms to either the true or the fake PMS, without
+     * data-dependent branches. */
+    for( i = 0; i < ssl->handshake->pmslen; i++ )
+        pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p,
+                                          const unsigned char *end )
+{
+    int ret = 0;
+    size_t n;
+
+    if( ssl->conf->f_psk == NULL &&
+        ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
+          ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) );
+        return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+    }
+
+    /*
+     * Receive client pre-shared key identity name
+     */
+    if( end - *p < 2 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+    }
+
+    n = ( (*p)[0] << 8 ) | (*p)[1];
+    *p += 2;
+
+    if( n < 1 || n > 65535 || n > (size_t) ( end - *p ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+    }
+
+    if( ssl->conf->f_psk != NULL )
+    {
+        if( ssl->conf->f_psk( ssl->conf->p_psk, ssl, *p, n ) != 0 )
+            ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
+    }
+    else
+    {
+        /* Identity is not a big secret since clients send it in the clear,
+         * but treat it carefully anyway, just in case */
+        if( n != ssl->conf->psk_identity_len ||
+            mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
+        {
+            ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
+        }
+    }
+
+    if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY )
+    {
+        MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY );
+        return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY );
+    }
+
+    *p += n;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+    unsigned char *p, *end;
+
+    ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \
+    ( defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
+      defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) )
+    if( ( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
+          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) &&
+        ( ssl->handshake->async_in_progress != 0 ) )
+    {
+        /* We've already read a record and there is an asynchronous
+         * operation in progress to decrypt it. So skip reading the
+         * record. */
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "will resume decryption of previously-read record" ) );
+    }
+    else
+#endif
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        return( ret );
+    }
+
+    p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
+    end = ssl->in_msg + ssl->in_hslen;
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+    }
+
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+    }
+
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA )
+    {
+        if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret );
+            return( ret );
+        }
+
+        if( p != end )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        }
+
+        if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
+                                      ssl->handshake->premaster,
+                                      MBEDTLS_PREMASTER_SIZE,
+                                     &ssl->handshake->pmslen,
+                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
+        }
+
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
+    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
+    {
+        if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx,
+                                      p, end - p) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
+        }
+
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_QP );
+
+        if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
+                                      &ssl->handshake->pmslen,
+                                       ssl->handshake->premaster,
+                                       MBEDTLS_MPI_MAX_SIZE,
+                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
+        }
+
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Z );
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
+          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
+    {
+        if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
+            return( ret );
+        }
+
+        if( p != end )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        }
+
+        if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
+                        ciphersuite_info->key_exchange ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
+            return( ret );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+    {
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+        if ( ssl->handshake->async_in_progress != 0 )
+        {
+            /* There is an asynchronous operation in progress to
+             * decrypt the encrypted premaster secret, so skip
+             * directly to resuming this operation. */
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK identity already parsed" ) );
+            /* Update p to skip the PSK identity. ssl_parse_encrypted_pms
+             * won't actually use it, but maintain p anyway for robustness. */
+            p += ssl->conf->psk_identity_len + 2;
+        }
+        else
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+        if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
+            return( ret );
+        }
+
+        if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret );
+            return( ret );
+        }
+
+        if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
+                        ciphersuite_info->key_exchange ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
+            return( ret );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
+    {
+        if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
+            return( ret );
+        }
+        if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret );
+            return( ret );
+        }
+
+        if( p != end )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
+        }
+
+        if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
+                        ciphersuite_info->key_exchange ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
+            return( ret );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
+    {
+        if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
+            return( ret );
+        }
+
+        if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx,
+                                       p, end - p ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
+        }
+
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_QP );
+
+        if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
+                        ciphersuite_info->key_exchange ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret );
+            return( ret );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
+    {
+        if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 0 ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_parse_encrypted_pms_secret" ), ret );
+            return( ret );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
+                                              p, end - p );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
+            return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        }
+
+        ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
+                ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
+                ssl->conf->f_rng, ssl->conf->p_rng );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
+            return( ret );
+        }
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret );
+        return( ret );
+    }
+
+    ssl->state++;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client key exchange" ) );
+
+    return( 0 );
+}
+
+#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)       && \
+    !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)   && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)  && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
+{
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->transform_negotiate->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
+
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+#else
+static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    size_t i, sig_len;
+    unsigned char hash[48];
+    unsigned char *hash_start = hash;
+    size_t hashlen;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    mbedtls_pk_type_t pk_alg;
+#endif
+    mbedtls_md_type_t md_alg;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+        ssl->transform_negotiate->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
+
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
+        ssl->session_negotiate->peer_cert == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    /* Read the message without adding it to the checksum */
+    ret = mbedtls_ssl_read_record( ssl, 0 /* no checksum update */ );
+    if( 0 != ret )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record" ), ret );
+        return( ret );
+    }
+
+    ssl->state++;
+
+    /* Process the message contents */
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
+        ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+    }
+
+    i = mbedtls_ssl_hs_hdr_len( ssl );
+
+    /*
+     *  struct {
+     *     SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only
+     *     opaque signature<0..2^16-1>;
+     *  } DigitallySigned;
+     */
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+    if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        md_alg = MBEDTLS_MD_NONE;
+        hashlen = 36;
+
+        /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */
+        if( mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
+                        MBEDTLS_PK_ECDSA ) )
+        {
+            hash_start += 16;
+            hashlen -= 16;
+            md_alg = MBEDTLS_MD_SHA1;
+        }
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 ||
+          MBEDTLS_SSL_PROTO_TLS1_1 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        if( i + 2 > ssl->in_hslen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+        }
+
+        /*
+         * Hash
+         */
+        md_alg = mbedtls_ssl_md_alg_from_hash( ssl->in_msg[i] );
+
+        if( md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md( ssl, ssl->in_msg[i] ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
+                                " for verify message" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+        }
+
+#if !defined(MBEDTLS_MD_SHA1)
+        if( MBEDTLS_MD_SHA1 == md_alg )
+            hash_start += 16;
+#endif
+
+        /* Info from md_alg will be used instead */
+        hashlen = 0;
+
+        i++;
+
+        /*
+         * Signature
+         */
+        if( ( pk_alg = mbedtls_ssl_pk_alg_from_sig( ssl->in_msg[i] ) )
+                        == MBEDTLS_PK_NONE )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
+                                " for verify message" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+        }
+
+        /*
+         * Check the certificate's key type matches the signature alg
+         */
+        if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+        }
+
+        i++;
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    if( i + 2 > ssl->in_hslen )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+    }
+
+    sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1];
+    i += 2;
+
+    if( i + sig_len != ssl->in_hslen )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
+    }
+
+    /* Calculate hash and verify signature */
+    ssl->handshake->calc_verify( ssl, hash );
+
+    if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
+                           md_alg, hash_start, hashlen,
+                           ssl->in_msg + i, sig_len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
+        return( ret );
+    }
+
+    mbedtls_ssl_update_handshake_status( ssl );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) );
+
+    return( ret );
+}
+#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
+          !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    size_t tlen;
+    uint32_t lifetime;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write new session ticket" ) );
+
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_NEW_SESSION_TICKET;
+
+    /*
+     * struct {
+     *     uint32 ticket_lifetime_hint;
+     *     opaque ticket<0..2^16-1>;
+     * } NewSessionTicket;
+     *
+     * 4  .  7   ticket_lifetime_hint (0 = unspecified)
+     * 8  .  9   ticket_len (n)
+     * 10 .  9+n ticket content
+     */
+
+    if( ( ret = ssl->conf->f_ticket_write( ssl->conf->p_ticket,
+                                ssl->session_negotiate,
+                                ssl->out_msg + 10,
+                                ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN,
+                                &tlen, &lifetime ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_write", ret );
+        tlen = 0;
+    }
+
+    ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF;
+    ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF;
+    ssl->out_msg[6] = ( lifetime >>  8 ) & 0xFF;
+    ssl->out_msg[7] = ( lifetime       ) & 0xFF;
+
+    ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF );
+    ssl->out_msg[9] = (unsigned char)( ( tlen      ) & 0xFF );
+
+    ssl->out_msglen = 10 + tlen;
+
+    /*
+     * Morally equivalent to updating ssl->state, but NewSessionTicket and
+     * ChangeCipherSpec share the same state.
+     */
+    ssl->handshake->new_session_ticket = 0;
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+/*
+ * SSL handshake -- server side -- single step
+ */
+int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl )
+{
+    int ret = 0;
+
+    if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) );
+
+    if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+        return( ret );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
+    {
+        if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+            return( ret );
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    switch( ssl->state )
+    {
+        case MBEDTLS_SSL_HELLO_REQUEST:
+            ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
+            break;
+
+        /*
+         *  <==   ClientHello
+         */
+        case MBEDTLS_SSL_CLIENT_HELLO:
+            ret = ssl_parse_client_hello( ssl );
+            break;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+        case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:
+            return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
+#endif
+
+        /*
+         *  ==>   ServerHello
+         *        Certificate
+         *      ( ServerKeyExchange  )
+         *      ( CertificateRequest )
+         *        ServerHelloDone
+         */
+        case MBEDTLS_SSL_SERVER_HELLO:
+            ret = ssl_write_server_hello( ssl );
+            break;
+
+        case MBEDTLS_SSL_SERVER_CERTIFICATE:
+            ret = mbedtls_ssl_write_certificate( ssl );
+            break;
+
+        case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
+            ret = ssl_write_server_key_exchange( ssl );
+            break;
+
+        case MBEDTLS_SSL_CERTIFICATE_REQUEST:
+            ret = ssl_write_certificate_request( ssl );
+            break;
+
+        case MBEDTLS_SSL_SERVER_HELLO_DONE:
+            ret = ssl_write_server_hello_done( ssl );
+            break;
+
+        /*
+         *  <== ( Certificate/Alert  )
+         *        ClientKeyExchange
+         *      ( CertificateVerify  )
+         *        ChangeCipherSpec
+         *        Finished
+         */
+        case MBEDTLS_SSL_CLIENT_CERTIFICATE:
+            ret = mbedtls_ssl_parse_certificate( ssl );
+            break;
+
+        case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
+            ret = ssl_parse_client_key_exchange( ssl );
+            break;
+
+        case MBEDTLS_SSL_CERTIFICATE_VERIFY:
+            ret = ssl_parse_certificate_verify( ssl );
+            break;
+
+        case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
+            ret = mbedtls_ssl_parse_change_cipher_spec( ssl );
+            break;
+
+        case MBEDTLS_SSL_CLIENT_FINISHED:
+            ret = mbedtls_ssl_parse_finished( ssl );
+            break;
+
+        /*
+         *  ==> ( NewSessionTicket )
+         *        ChangeCipherSpec
+         *        Finished
+         */
+        case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+            if( ssl->handshake->new_session_ticket != 0 )
+                ret = ssl_write_new_session_ticket( ssl );
+            else
+#endif
+                ret = mbedtls_ssl_write_change_cipher_spec( ssl );
+            break;
+
+        case MBEDTLS_SSL_SERVER_FINISHED:
+            ret = mbedtls_ssl_write_finished( ssl );
+            break;
+
+        case MBEDTLS_SSL_FLUSH_BUFFERS:
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
+            ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
+            break;
+
+        case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
+            mbedtls_ssl_handshake_wrapup( ssl );
+            break;
+
+        default:
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    return( ret );
+}
+#endif /* MBEDTLS_SSL_SRV_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_ticket.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_ticket.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_ticket.c	(revision 398)
@@ -0,0 +1,485 @@
+/*
+ *  TLS server tickets callbacks implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SSL_TICKET_C)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free      free
+#endif
+
+#include "mbedtls/ssl_ticket.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+/*
+ * Initialze context
+ */
+void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_ssl_ticket_context ) );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+}
+
+#define MAX_KEY_BYTES 32    /* 256 bits */
+
+/*
+ * Generate/update a key
+ */
+static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx,
+                               unsigned char index )
+{
+    int ret;
+    unsigned char buf[MAX_KEY_BYTES];
+    mbedtls_ssl_ticket_key *key = ctx->keys + index;
+
+#if defined(MBEDTLS_HAVE_TIME)
+    key->generation_time = (uint32_t) mbedtls_time( NULL );
+#endif
+
+    if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 )
+        return( ret );
+
+    if( ( ret = ctx->f_rng( ctx->p_rng, buf, sizeof( buf ) ) ) != 0 )
+        return( ret );
+
+    /* With GCM and CCM, same context can encrypt & decrypt */
+    ret = mbedtls_cipher_setkey( &key->ctx, buf,
+                                 mbedtls_cipher_get_key_bitlen( &key->ctx ),
+                                 MBEDTLS_ENCRYPT );
+
+    mbedtls_platform_zeroize( buf, sizeof( buf ) );
+
+    return( ret );
+}
+
+/*
+ * Rotate/generate keys if necessary
+ */
+static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx )
+{
+#if !defined(MBEDTLS_HAVE_TIME)
+    ((void) ctx);
+#else
+    if( ctx->ticket_lifetime != 0 )
+    {
+        uint32_t current_time = (uint32_t) mbedtls_time( NULL );
+        uint32_t key_time = ctx->keys[ctx->active].generation_time;
+
+        if( current_time >= key_time &&
+            current_time - key_time < ctx->ticket_lifetime )
+        {
+            return( 0 );
+        }
+
+        ctx->active = 1 - ctx->active;
+
+        return( ssl_ticket_gen_key( ctx, ctx->active ) );
+    }
+    else
+#endif /* MBEDTLS_HAVE_TIME */
+        return( 0 );
+}
+
+/*
+ * Setup context for actual use
+ */
+int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
+    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+    mbedtls_cipher_type_t cipher,
+    uint32_t lifetime )
+{
+    int ret;
+    const mbedtls_cipher_info_t *cipher_info;
+
+    ctx->f_rng = f_rng;
+    ctx->p_rng = p_rng;
+
+    ctx->ticket_lifetime = lifetime;
+
+    cipher_info = mbedtls_cipher_info_from_type( cipher);
+    if( cipher_info == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    if( cipher_info->mode != MBEDTLS_MODE_GCM &&
+        cipher_info->mode != MBEDTLS_MODE_CCM )
+    {
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 ||
+        ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 ||
+        ( ret = ssl_ticket_gen_key( ctx, 1 ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Serialize a session in the following format:
+ *  0   .   n-1     session structure, n = sizeof(mbedtls_ssl_session)
+ *  n   .   n+2     peer_cert length = m (0 if no certificate)
+ *  n+3 .   n+2+m   peer cert ASN.1
+ */
+static int ssl_save_session( const mbedtls_ssl_session *session,
+                             unsigned char *buf, size_t buf_len,
+                             size_t *olen )
+{
+    unsigned char *p = buf;
+    size_t left = buf_len;
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    size_t cert_len;
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+    if( left < sizeof( mbedtls_ssl_session ) )
+        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+    memcpy( p, session, sizeof( mbedtls_ssl_session ) );
+    p += sizeof( mbedtls_ssl_session );
+    left -= sizeof( mbedtls_ssl_session );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    if( session->peer_cert == NULL )
+        cert_len = 0;
+    else
+        cert_len = session->peer_cert->raw.len;
+
+    if( left < 3 + cert_len )
+        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+    *p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF );
+    *p++ = (unsigned char)( ( cert_len >>  8 ) & 0xFF );
+    *p++ = (unsigned char)( ( cert_len       ) & 0xFF );
+
+    if( session->peer_cert != NULL )
+        memcpy( p, session->peer_cert->raw.p, cert_len );
+
+    p += cert_len;
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+    *olen = p - buf;
+
+    return( 0 );
+}
+
+/*
+ * Unserialise session, see ssl_save_session()
+ */
+static int ssl_load_session( mbedtls_ssl_session *session,
+                             const unsigned char *buf, size_t len )
+{
+    const unsigned char *p = buf;
+    const unsigned char * const end = buf + len;
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    size_t cert_len;
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+    if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    memcpy( session, p, sizeof( mbedtls_ssl_session ) );
+    p += sizeof( mbedtls_ssl_session );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    if( 3 > (size_t)( end - p ) )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
+    p += 3;
+
+    if( cert_len == 0 )
+    {
+        session->peer_cert = NULL;
+    }
+    else
+    {
+        int ret;
+
+        if( cert_len > (size_t)( end - p ) )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
+
+        if( session->peer_cert == NULL )
+            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+        mbedtls_x509_crt_init( session->peer_cert );
+
+        if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
+                                                p, cert_len ) ) != 0 )
+        {
+            mbedtls_x509_crt_free( session->peer_cert );
+            mbedtls_free( session->peer_cert );
+            session->peer_cert = NULL;
+            return( ret );
+        }
+
+        p += cert_len;
+    }
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+    if( p != end )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    return( 0 );
+}
+
+/*
+ * Create session ticket, with the following structure:
+ *
+ *    struct {
+ *        opaque key_name[4];
+ *        opaque iv[12];
+ *        opaque encrypted_state<0..2^16-1>;
+ *        opaque tag[16];
+ *    } ticket;
+ *
+ * The key_name, iv, and length of encrypted_state are the additional
+ * authenticated data.
+ */
+int mbedtls_ssl_ticket_write( void *p_ticket,
+                              const mbedtls_ssl_session *session,
+                              unsigned char *start,
+                              const unsigned char *end,
+                              size_t *tlen,
+                              uint32_t *ticket_lifetime )
+{
+    int ret;
+    mbedtls_ssl_ticket_context *ctx = p_ticket;
+    mbedtls_ssl_ticket_key *key;
+    unsigned char *key_name = start;
+    unsigned char *iv = start + 4;
+    unsigned char *state_len_bytes = iv + 12;
+    unsigned char *state = state_len_bytes + 2;
+    unsigned char *tag;
+    size_t clear_len, ciph_len;
+
+    *tlen = 0;
+
+    if( ctx == NULL || ctx->f_rng == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    /* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag,
+     * in addition to session itself, that will be checked when writing it. */
+    if( end - start < 4 + 12 + 2 + 16 )
+        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 )
+        goto cleanup;
+
+    key = &ctx->keys[ctx->active];
+
+    *ticket_lifetime = ctx->ticket_lifetime;
+
+    memcpy( key_name, key->name, 4 );
+
+    if( ( ret = ctx->f_rng( ctx->p_rng, iv, 12 ) ) != 0 )
+        goto cleanup;
+
+    /* Dump session state */
+    if( ( ret = ssl_save_session( session,
+                                  state, end - state, &clear_len ) ) != 0 ||
+        (unsigned long) clear_len > 65535 )
+    {
+         goto cleanup;
+    }
+    state_len_bytes[0] = ( clear_len >> 8 ) & 0xff;
+    state_len_bytes[1] = ( clear_len      ) & 0xff;
+
+    /* Encrypt and authenticate */
+    tag = state + clear_len;
+    if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx,
+                    iv, 12, key_name, 4 + 12 + 2,
+                    state, clear_len, state, &ciph_len, tag, 16 ) ) != 0 )
+    {
+        goto cleanup;
+    }
+    if( ciph_len != clear_len )
+    {
+        ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+        goto cleanup;
+    }
+
+    *tlen = 4 + 12 + 2 + 16 + ciph_len;
+
+cleanup:
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
+}
+
+/*
+ * Select key based on name
+ */
+static mbedtls_ssl_ticket_key *ssl_ticket_select_key(
+        mbedtls_ssl_ticket_context *ctx,
+        const unsigned char name[4] )
+{
+    unsigned char i;
+
+    for( i = 0; i < sizeof( ctx->keys ) / sizeof( *ctx->keys ); i++ )
+        if( memcmp( name, ctx->keys[i].name, 4 ) == 0 )
+            return( &ctx->keys[i] );
+
+    return( NULL );
+}
+
+/*
+ * Load session ticket (see mbedtls_ssl_ticket_write for structure)
+ */
+int mbedtls_ssl_ticket_parse( void *p_ticket,
+                              mbedtls_ssl_session *session,
+                              unsigned char *buf,
+                              size_t len )
+{
+    int ret;
+    mbedtls_ssl_ticket_context *ctx = p_ticket;
+    mbedtls_ssl_ticket_key *key;
+    unsigned char *key_name = buf;
+    unsigned char *iv = buf + 4;
+    unsigned char *enc_len_p = iv + 12;
+    unsigned char *ticket = enc_len_p + 2;
+    unsigned char *tag;
+    size_t enc_len, clear_len;
+
+    if( ctx == NULL || ctx->f_rng == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    /* See mbedtls_ssl_ticket_write() */
+    if( len < 4 + 12 + 2 + 16 )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 )
+        goto cleanup;
+
+    enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1];
+    tag = ticket + enc_len;
+
+    if( len != 4 + 12 + 2 + enc_len + 16 )
+    {
+        ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    /* Select key */
+    if( ( key = ssl_ticket_select_key( ctx, key_name ) ) == NULL )
+    {
+        /* We can't know for sure but this is a likely option unless we're
+         * under attack - this is only informative anyway */
+        ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
+        goto cleanup;
+    }
+
+    /* Decrypt and authenticate */
+    if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx, iv, 12,
+                    key_name, 4 + 12 + 2, ticket, enc_len,
+                    ticket, &clear_len, tag, 16 ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
+            ret = MBEDTLS_ERR_SSL_INVALID_MAC;
+
+        goto cleanup;
+    }
+    if( clear_len != enc_len )
+    {
+        ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+        goto cleanup;
+    }
+
+    /* Actually load session */
+    if( ( ret = ssl_load_session( session, ticket, clear_len ) ) != 0 )
+        goto cleanup;
+
+#if defined(MBEDTLS_HAVE_TIME)
+    {
+        /* Check for expiration */
+        mbedtls_time_t current_time = mbedtls_time( NULL );
+
+        if( current_time < session->start ||
+            (uint32_t)( current_time - session->start ) > ctx->ticket_lifetime )
+        {
+            ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
+            goto cleanup;
+        }
+    }
+#endif
+
+cleanup:
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return( ret );
+}
+
+/*
+ * Free context
+ */
+void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx )
+{
+    mbedtls_cipher_free( &ctx->keys[0].ctx );
+    mbedtls_cipher_free( &ctx->keys[1].ctx );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_free( &ctx->mutex );
+#endif
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ssl_ticket_context ) );
+}
+
+#endif /* MBEDTLS_SSL_TICKET_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_tls.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_tls.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/ssl_tls.c	(revision 398)
@@ -0,0 +1,9799 @@
+/*
+ *  SSLv3/TLSv1 shared functions
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The SSL 3.0 specification was drafted by Netscape in 1996,
+ *  and became an IETF standard in 1999.
+ *
+ *  http://wp.netscape.com/eng/ssl3/
+ *  http://www.ietf.org/rfc/rfc2246.txt
+ *  http://www.ietf.org/rfc/rfc4346.txt
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc    calloc
+#define mbedtls_free      free
+#endif
+
+#include "mbedtls/debug.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/ssl_internal.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#include "mbedtls/oid.h"
+#endif
+
+static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl );
+static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl );
+
+/* Length of the "epoch" field in the record header */
+static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        return( 2 );
+#else
+    ((void) ssl);
+#endif
+    return( 0 );
+}
+
+/*
+ * Start a timer.
+ * Passing millisecs = 0 cancels a running timer.
+ */
+static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
+{
+    if( ssl->f_set_timer == NULL )
+        return;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
+    ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
+}
+
+/*
+ * Return -1 is timer is expired, 0 if it isn't.
+ */
+static int ssl_check_timer( mbedtls_ssl_context *ssl )
+{
+    if( ssl->f_get_timer == NULL )
+        return( 0 );
+
+    if( ssl->f_get_timer( ssl->p_timer ) == 2 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
+        return( -1 );
+    }
+
+    return( 0 );
+}
+
+static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
+                                     mbedtls_ssl_transform *transform );
+static void ssl_update_in_pointers( mbedtls_ssl_context *ssl,
+                                    mbedtls_ssl_transform *transform );
+
+#define SSL_DONT_FORCE_FLUSH 0
+#define SSL_FORCE_FLUSH      1
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+/* Forward declarations for functions related to message buffering. */
+static void ssl_buffering_free( mbedtls_ssl_context *ssl );
+static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
+                                     uint8_t slot );
+static void ssl_free_buffered_record( mbedtls_ssl_context *ssl );
+static int ssl_load_buffered_message( mbedtls_ssl_context *ssl );
+static int ssl_load_buffered_record( mbedtls_ssl_context *ssl );
+static int ssl_buffer_message( mbedtls_ssl_context *ssl );
+static int ssl_buffer_future_record( mbedtls_ssl_context *ssl );
+static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl );
+
+static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl );
+static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
+{
+    size_t mtu = ssl_get_current_mtu( ssl );
+
+    if( mtu != 0 && mtu < MBEDTLS_SSL_OUT_BUFFER_LEN )
+        return( mtu );
+
+    return( MBEDTLS_SSL_OUT_BUFFER_LEN );
+}
+
+static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
+{
+    size_t const bytes_written = ssl->out_left;
+    size_t const mtu           = ssl_get_maximum_datagram_size( ssl );
+
+    /* Double-check that the write-index hasn't gone
+     * past what we can transmit in a single datagram. */
+    if( bytes_written > mtu )
+    {
+        /* Should never happen... */
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    return( (int) ( mtu - bytes_written ) );
+}
+
+static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
+{
+    int ret;
+    size_t remaining, expansion;
+    size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
+
+    if( max_len > mfl )
+        max_len = mfl;
+
+    /* By the standard (RFC 6066 Sect. 4), the MFL extension
+     * only limits the maximum record payload size, so in theory
+     * we would be allowed to pack multiple records of payload size
+     * MFL into a single datagram. However, this would mean that there's
+     * no way to explicitly communicate MTU restrictions to the peer.
+     *
+     * The following reduction of max_len makes sure that we never
+     * write datagrams larger than MFL + Record Expansion Overhead.
+     */
+    if( max_len <= ssl->out_left )
+        return( 0 );
+
+    max_len -= ssl->out_left;
+#endif
+
+    ret = ssl_get_remaining_space_in_datagram( ssl );
+    if( ret < 0 )
+        return( ret );
+    remaining = (size_t) ret;
+
+    ret = mbedtls_ssl_get_record_expansion( ssl );
+    if( ret < 0 )
+        return( ret );
+    expansion = (size_t) ret;
+
+    if( remaining <= expansion )
+        return( 0 );
+
+    remaining -= expansion;
+    if( remaining >= max_len )
+        remaining = max_len;
+
+    return( (int) remaining );
+}
+
+/*
+ * Double the retransmit timeout value, within the allowed range,
+ * returning -1 if the maximum value has already been reached.
+ */
+static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
+{
+    uint32_t new_timeout;
+
+    if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
+        return( -1 );
+
+    /* Implement the final paragraph of RFC 6347 section 4.1.1.1
+     * in the following way: after the initial transmission and a first
+     * retransmission, back off to a temporary estimated MTU of 508 bytes.
+     * This value is guaranteed to be deliverable (if not guaranteed to be
+     * delivered) of any compliant IPv4 (and IPv6) network, and should work
+     * on most non-IP stacks too. */
+    if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min )
+    {
+        ssl->handshake->mtu = 508;
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) );
+    }
+
+    new_timeout = 2 * ssl->handshake->retransmit_timeout;
+
+    /* Avoid arithmetic overflow and range overflow */
+    if( new_timeout < ssl->handshake->retransmit_timeout ||
+        new_timeout > ssl->conf->hs_timeout_max )
+    {
+        new_timeout = ssl->conf->hs_timeout_max;
+    }
+
+    ssl->handshake->retransmit_timeout = new_timeout;
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
+                        ssl->handshake->retransmit_timeout ) );
+
+    return( 0 );
+}
+
+static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
+{
+    ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
+                        ssl->handshake->retransmit_timeout ) );
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+/*
+ * Convert max_fragment_length codes to length.
+ * RFC 6066 says:
+ *    enum{
+ *        2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
+ *    } MaxFragmentLength;
+ * and we add 0 -> extension unused
+ */
+static unsigned int ssl_mfl_code_to_length( int mfl )
+{
+    switch( mfl )
+    {
+    case MBEDTLS_SSL_MAX_FRAG_LEN_NONE:
+        return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN );
+    case MBEDTLS_SSL_MAX_FRAG_LEN_512:
+        return 512;
+    case MBEDTLS_SSL_MAX_FRAG_LEN_1024:
+        return 1024;
+    case MBEDTLS_SSL_MAX_FRAG_LEN_2048:
+        return 2048;
+    case MBEDTLS_SSL_MAX_FRAG_LEN_4096:
+        return 4096;
+    default:
+        return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN );
+    }
+}
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session *src )
+{
+    mbedtls_ssl_session_free( dst );
+    memcpy( dst, src, sizeof( mbedtls_ssl_session ) );
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    if( src->peer_cert != NULL )
+    {
+        int ret;
+
+        dst->peer_cert = mbedtls_calloc( 1, sizeof(mbedtls_x509_crt) );
+        if( dst->peer_cert == NULL )
+            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+        mbedtls_x509_crt_init( dst->peer_cert );
+
+        if( ( ret = mbedtls_x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p,
+                                        src->peer_cert->raw.len ) ) != 0 )
+        {
+            mbedtls_free( dst->peer_cert );
+            dst->peer_cert = NULL;
+            return( ret );
+        }
+    }
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+    if( src->ticket != NULL )
+    {
+        dst->ticket = mbedtls_calloc( 1, src->ticket_len );
+        if( dst->ticket == NULL )
+            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+        memcpy( dst->ticket, src->ticket, src->ticket_len );
+    }
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
+                     const unsigned char *key_enc, const unsigned char *key_dec,
+                     size_t keylen,
+                     const unsigned char *iv_enc,  const unsigned char *iv_dec,
+                     size_t ivlen,
+                     const unsigned char *mac_enc, const unsigned char *mac_dec,
+                     size_t maclen ) = NULL;
+int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL;
+int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL;
+int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL;
+int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL;
+int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL;
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
+/*
+ * Key material generation
+ */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+static int ssl3_prf( const unsigned char *secret, size_t slen,
+                     const char *label,
+                     const unsigned char *random, size_t rlen,
+                     unsigned char *dstbuf, size_t dlen )
+{
+    int ret = 0;
+    size_t i;
+    mbedtls_md5_context md5;
+    mbedtls_sha1_context sha1;
+    unsigned char padding[16];
+    unsigned char sha1sum[20];
+    ((void)label);
+
+    mbedtls_md5_init(  &md5  );
+    mbedtls_sha1_init( &sha1 );
+
+    /*
+     *  SSLv3:
+     *    block =
+     *      MD5( secret + SHA1( 'A'    + secret + random ) ) +
+     *      MD5( secret + SHA1( 'BB'   + secret + random ) ) +
+     *      MD5( secret + SHA1( 'CCC'  + secret + random ) ) +
+     *      ...
+     */
+    for( i = 0; i < dlen / 16; i++ )
+    {
+        memset( padding, (unsigned char) ('A' + i), 1 + i );
+
+        if( ( ret = mbedtls_sha1_starts_ret( &sha1 ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_sha1_update_ret( &sha1, padding, 1 + i ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_sha1_update_ret( &sha1, secret, slen ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_sha1_update_ret( &sha1, random, rlen ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_sha1_finish_ret( &sha1, sha1sum ) ) != 0 )
+            goto exit;
+
+        if( ( ret = mbedtls_md5_starts_ret( &md5 ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md5_update_ret( &md5, secret, slen ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md5_update_ret( &md5, sha1sum, 20 ) ) != 0 )
+            goto exit;
+        if( ( ret = mbedtls_md5_finish_ret( &md5, dstbuf + i * 16 ) ) != 0 )
+            goto exit;
+    }
+
+exit:
+    mbedtls_md5_free(  &md5  );
+    mbedtls_sha1_free( &sha1 );
+
+    mbedtls_platform_zeroize( padding, sizeof( padding ) );
+    mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) );
+
+    return( ret );
+}
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+static int tls1_prf( const unsigned char *secret, size_t slen,
+                     const char *label,
+                     const unsigned char *random, size_t rlen,
+                     unsigned char *dstbuf, size_t dlen )
+{
+    size_t nb, hs;
+    size_t i, j, k;
+    const unsigned char *S1, *S2;
+    unsigned char tmp[128];
+    unsigned char h_i[20];
+    const mbedtls_md_info_t *md_info;
+    mbedtls_md_context_t md_ctx;
+    int ret;
+
+    mbedtls_md_init( &md_ctx );
+
+    if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    hs = ( slen + 1 ) / 2;
+    S1 = secret;
+    S2 = secret + slen - hs;
+
+    nb = strlen( label );
+    memcpy( tmp + 20, label, nb );
+    memcpy( tmp + 20 + nb, random, rlen );
+    nb += rlen;
+
+    /*
+     * First compute P_md5(secret,label+random)[0..dlen]
+     */
+    if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == NULL )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+        return( ret );
+
+    mbedtls_md_hmac_starts( &md_ctx, S1, hs );
+    mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
+    mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
+
+    for( i = 0; i < dlen; i += 16 )
+    {
+        mbedtls_md_hmac_reset ( &md_ctx );
+        mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb );
+        mbedtls_md_hmac_finish( &md_ctx, h_i );
+
+        mbedtls_md_hmac_reset ( &md_ctx );
+        mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 );
+        mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
+
+        k = ( i + 16 > dlen ) ? dlen % 16 : 16;
+
+        for( j = 0; j < k; j++ )
+            dstbuf[i + j]  = h_i[j];
+    }
+
+    mbedtls_md_free( &md_ctx );
+
+    /*
+     * XOR out with P_sha1(secret,label+random)[0..dlen]
+     */
+    if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+        return( ret );
+
+    mbedtls_md_hmac_starts( &md_ctx, S2, hs );
+    mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
+    mbedtls_md_hmac_finish( &md_ctx, tmp );
+
+    for( i = 0; i < dlen; i += 20 )
+    {
+        mbedtls_md_hmac_reset ( &md_ctx );
+        mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb );
+        mbedtls_md_hmac_finish( &md_ctx, h_i );
+
+        mbedtls_md_hmac_reset ( &md_ctx );
+        mbedtls_md_hmac_update( &md_ctx, tmp, 20 );
+        mbedtls_md_hmac_finish( &md_ctx, tmp );
+
+        k = ( i + 20 > dlen ) ? dlen % 20 : 20;
+
+        for( j = 0; j < k; j++ )
+            dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] );
+    }
+
+    mbedtls_md_free( &md_ctx );
+
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+static int tls_prf_generic( mbedtls_md_type_t md_type,
+                            const unsigned char *secret, size_t slen,
+                            const char *label,
+                            const unsigned char *random, size_t rlen,
+                            unsigned char *dstbuf, size_t dlen )
+{
+    size_t nb;
+    size_t i, j, k, md_len;
+    unsigned char tmp[128];
+    unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info;
+    mbedtls_md_context_t md_ctx;
+    int ret;
+
+    mbedtls_md_init( &md_ctx );
+
+    if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL )
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+
+    md_len = mbedtls_md_get_size( md_info );
+
+    if( sizeof( tmp ) < md_len + strlen( label ) + rlen )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    nb = strlen( label );
+    memcpy( tmp + md_len, label, nb );
+    memcpy( tmp + md_len + nb, random, rlen );
+    nb += rlen;
+
+    /*
+     * Compute P_<hash>(secret, label + random)[0..dlen]
+     */
+    if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+        return( ret );
+
+    mbedtls_md_hmac_starts( &md_ctx, secret, slen );
+    mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb );
+    mbedtls_md_hmac_finish( &md_ctx, tmp );
+
+    for( i = 0; i < dlen; i += md_len )
+    {
+        mbedtls_md_hmac_reset ( &md_ctx );
+        mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb );
+        mbedtls_md_hmac_finish( &md_ctx, h_i );
+
+        mbedtls_md_hmac_reset ( &md_ctx );
+        mbedtls_md_hmac_update( &md_ctx, tmp, md_len );
+        mbedtls_md_hmac_finish( &md_ctx, tmp );
+
+        k = ( i + md_len > dlen ) ? dlen % md_len : md_len;
+
+        for( j = 0; j < k; j++ )
+            dstbuf[i + j]  = h_i[j];
+    }
+
+    mbedtls_md_free( &md_ctx );
+
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+    mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SHA256_C)
+static int tls_prf_sha256( const unsigned char *secret, size_t slen,
+                           const char *label,
+                           const unsigned char *random, size_t rlen,
+                           unsigned char *dstbuf, size_t dlen )
+{
+    return( tls_prf_generic( MBEDTLS_MD_SHA256, secret, slen,
+                             label, random, rlen, dstbuf, dlen ) );
+}
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+static int tls_prf_sha384( const unsigned char *secret, size_t slen,
+                           const char *label,
+                           const unsigned char *random, size_t rlen,
+                           unsigned char *dstbuf, size_t dlen )
+{
+    return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen,
+                             label, random, rlen, dstbuf, dlen ) );
+}
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t );
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int );
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int );
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t );
+static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *,unsigned char * );
+static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t );
+static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int );
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
+{
+    int ret = 0;
+    unsigned char tmp[64];
+    unsigned char keyblk[256];
+    unsigned char *key1;
+    unsigned char *key2;
+    unsigned char *mac_enc;
+    unsigned char *mac_dec;
+    size_t mac_key_len;
+    size_t iv_copy_len;
+    const mbedtls_cipher_info_t *cipher_info;
+    const mbedtls_md_info_t *md_info;
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    mbedtls_ssl_transform *transform = ssl->transform_negotiate;
+    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
+
+    cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher );
+    if( cipher_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found",
+                            transform->ciphersuite_info->cipher ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac );
+    if( md_info == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found",
+                            transform->ciphersuite_info->mac ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    /*
+     * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions
+     */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        handshake->tls_prf = ssl3_prf;
+        handshake->calc_verify = ssl_calc_verify_ssl;
+        handshake->calc_finished = ssl_calc_finished_ssl;
+    }
+    else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+    if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        handshake->tls_prf = tls1_prf;
+        handshake->calc_verify = ssl_calc_verify_tls;
+        handshake->calc_finished = ssl_calc_finished_tls;
+    }
+    else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA512_C)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+        transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
+    {
+        handshake->tls_prf = tls_prf_sha384;
+        handshake->calc_verify = ssl_calc_verify_tls_sha384;
+        handshake->calc_finished = ssl_calc_finished_tls_sha384;
+    }
+    else
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+    {
+        handshake->tls_prf = tls_prf_sha256;
+        handshake->calc_verify = ssl_calc_verify_tls_sha256;
+        handshake->calc_finished = ssl_calc_finished_tls_sha256;
+    }
+    else
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    /*
+     * SSLv3:
+     *   master =
+     *     MD5( premaster + SHA1( 'A'   + premaster + randbytes ) ) +
+     *     MD5( premaster + SHA1( 'BB'  + premaster + randbytes ) ) +
+     *     MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
+     *
+     * TLSv1+:
+     *   master = PRF( premaster, "master secret", randbytes )[0..47]
+     */
+    if( handshake->resume == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster,
+                       handshake->pmslen );
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+        if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
+        {
+            unsigned char session_hash[48];
+            size_t hash_len;
+
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) );
+
+            ssl->handshake->calc_verify( ssl, session_hash );
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+            if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+            {
+#if defined(MBEDTLS_SHA512_C)
+                if( ssl->transform_negotiate->ciphersuite_info->mac ==
+                    MBEDTLS_MD_SHA384 )
+                {
+                    hash_len = 48;
+                }
+                else
+#endif
+                    hash_len = 32;
+            }
+            else
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+                hash_len = 36;
+
+            MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len );
+
+            ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
+                                      "extended master secret",
+                                      session_hash, hash_len,
+                                      session->master, 48 );
+            if( ret != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
+                return( ret );
+            }
+
+        }
+        else
+#endif
+        ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
+                                  "master secret",
+                                  handshake->randbytes, 64,
+                                  session->master, 48 );
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
+            return( ret );
+        }
+
+        mbedtls_platform_zeroize( handshake->premaster,
+                                  sizeof(handshake->premaster) );
+    }
+    else
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
+
+    /*
+     * Swap the client and server random values.
+     */
+    memcpy( tmp, handshake->randbytes, 64 );
+    memcpy( handshake->randbytes, tmp + 32, 32 );
+    memcpy( handshake->randbytes + 32, tmp, 32 );
+    mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+
+    /*
+     *  SSLv3:
+     *    key block =
+     *      MD5( master + SHA1( 'A'    + master + randbytes ) ) +
+     *      MD5( master + SHA1( 'BB'   + master + randbytes ) ) +
+     *      MD5( master + SHA1( 'CCC'  + master + randbytes ) ) +
+     *      MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
+     *      ...
+     *
+     *  TLSv1:
+     *    key block = PRF( master, "key expansion", randbytes )
+     */
+    ret = handshake->tls_prf( session->master, 48, "key expansion",
+                              handshake->randbytes, 64, keyblk, 256 );
+    if( ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
+                   mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) );
+    MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 );
+    MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
+    MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
+
+    mbedtls_platform_zeroize( handshake->randbytes,
+                              sizeof( handshake->randbytes ) );
+
+    /*
+     * Determine the appropriate key, IV and MAC length.
+     */
+
+    transform->keylen = cipher_info->key_bitlen / 8;
+
+    if( cipher_info->mode == MBEDTLS_MODE_GCM ||
+        cipher_info->mode == MBEDTLS_MODE_CCM ||
+        cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
+    {
+        size_t taglen, explicit_ivlen;
+
+        transform->maclen = 0;
+        mac_key_len = 0;
+
+        /* All modes haves 96-bit IVs;
+         * GCM and CCM has 4 implicit and 8 explicit bytes
+         * ChachaPoly has all 12 bytes implicit
+         */
+        transform->ivlen = 12;
+        if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
+            transform->fixed_ivlen = 12;
+        else
+            transform->fixed_ivlen = 4;
+
+        /* All modes have 128-bit tags, except CCM_8 (ciphersuite flag) */
+        taglen = transform->ciphersuite_info->flags &
+                  MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
+
+
+        /* Minimum length of encrypted record */
+        explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
+        transform->minlen = explicit_ivlen + taglen;
+    }
+    else
+    {
+        /* Initialize HMAC contexts */
+        if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
+            ( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
+            return( ret );
+        }
+
+        /* Get MAC length */
+        mac_key_len = mbedtls_md_get_size( md_info );
+        transform->maclen = mac_key_len;
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+        /*
+         * If HMAC is to be truncated, we shall keep the leftmost bytes,
+         * (rfc 6066 page 13 or rfc 2104 section 4),
+         * so we only need to adjust the length here.
+         */
+        if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
+        {
+            transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
+            /* Fall back to old, non-compliant version of the truncated
+             * HMAC implementation which also truncates the key
+             * (Mbed TLS versions from 1.3 to 2.6.0) */
+            mac_key_len = transform->maclen;
+#endif
+        }
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+        /* IV length */
+        transform->ivlen = cipher_info->iv_size;
+
+        /* Minimum length */
+        if( cipher_info->mode == MBEDTLS_MODE_STREAM )
+            transform->minlen = transform->maclen;
+        else
+        {
+            /*
+             * GenericBlockCipher:
+             * 1. if EtM is in use: one block plus MAC
+             *    otherwise: * first multiple of blocklen greater than maclen
+             * 2. IV except for SSL3 and TLS 1.0
+             */
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+            if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
+            {
+                transform->minlen = transform->maclen
+                                  + cipher_info->block_size;
+            }
+            else
+#endif
+            {
+                transform->minlen = transform->maclen
+                                  + cipher_info->block_size
+                                  - transform->maclen % cipher_info->block_size;
+            }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
+            if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
+                ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 )
+                ; /* No need to adjust minlen */
+            else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+            if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 ||
+                ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+            {
+                transform->minlen += transform->ivlen;
+            }
+            else
+#endif
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+            }
+        }
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d",
+                   transform->keylen, transform->minlen, transform->ivlen,
+                   transform->maclen ) );
+
+    /*
+     * Finally setup the cipher contexts, IVs and MAC secrets.
+     */
+#if defined(MBEDTLS_SSL_CLI_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+    {
+        key1 = keyblk + mac_key_len * 2;
+        key2 = keyblk + mac_key_len * 2 + transform->keylen;
+
+        mac_enc = keyblk;
+        mac_dec = keyblk + mac_key_len;
+
+        /*
+         * This is not used in TLS v1.1.
+         */
+        iv_copy_len = ( transform->fixed_ivlen ) ?
+                            transform->fixed_ivlen : transform->ivlen;
+        memcpy( transform->iv_enc, key2 + transform->keylen,  iv_copy_len );
+        memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len,
+                iv_copy_len );
+    }
+    else
+#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_SRV_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        key1 = keyblk + mac_key_len * 2 + transform->keylen;
+        key2 = keyblk + mac_key_len * 2;
+
+        mac_enc = keyblk + mac_key_len;
+        mac_dec = keyblk;
+
+        /*
+         * This is not used in TLS v1.1.
+         */
+        iv_copy_len = ( transform->fixed_ivlen ) ?
+                            transform->fixed_ivlen : transform->ivlen;
+        memcpy( transform->iv_dec, key1 + transform->keylen,  iv_copy_len );
+        memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len,
+                iv_copy_len );
+    }
+    else
+#endif /* MBEDTLS_SSL_SRV_C */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        if( mac_key_len > sizeof transform->mac_enc )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        memcpy( transform->mac_enc, mac_enc, mac_key_len );
+        memcpy( transform->mac_dec, mac_dec, mac_key_len );
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+    {
+        /* For HMAC-based ciphersuites, initialize the HMAC transforms.
+           For AEAD-based ciphersuites, there is nothing to do here. */
+        if( mac_key_len != 0 )
+        {
+            mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len );
+            mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len );
+        }
+    }
+    else
+#endif
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+    if( mbedtls_ssl_hw_record_init != NULL )
+    {
+        int ret = 0;
+
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) );
+
+        if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen,
+                                        transform->iv_enc, transform->iv_dec,
+                                        iv_copy_len,
+                                        mac_enc, mac_dec,
+                                        mac_key_len ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+    }
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+    if( ssl->conf->f_export_keys != NULL )
+    {
+        ssl->conf->f_export_keys( ssl->conf->p_export_keys,
+                                  session->master, keyblk,
+                                  mac_key_len, transform->keylen,
+                                  iv_copy_len );
+    }
+#endif
+
+    if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
+                                 cipher_info ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec,
+                                 cipher_info ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
+                               cipher_info->key_bitlen,
+                               MBEDTLS_ENCRYPT ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
+                               cipher_info->key_bitlen,
+                               MBEDTLS_DECRYPT ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
+        return( ret );
+    }
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    if( cipher_info->mode == MBEDTLS_MODE_CBC )
+    {
+        if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc,
+                                             MBEDTLS_PADDING_NONE ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
+            return( ret );
+        }
+
+        if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec,
+                                             MBEDTLS_PADDING_NONE ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
+            return( ret );
+        }
+    }
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+    mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    // Initialize compression
+    //
+    if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
+    {
+        if( ssl->compress_buf == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
+            ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN );
+            if( ssl->compress_buf == NULL )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
+                                    MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) );
+                return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+            }
+        }
+
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) );
+
+        memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) );
+        memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) );
+
+        if( deflateInit( &transform->ctx_deflate,
+                         Z_DEFAULT_COMPRESSION )   != Z_OK ||
+            inflateInit( &transform->ctx_inflate ) != Z_OK )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) );
+            return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
+        }
+    }
+#endif /* MBEDTLS_ZLIB_SUPPORT */
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] )
+{
+    mbedtls_md5_context md5;
+    mbedtls_sha1_context sha1;
+    unsigned char pad_1[48];
+    unsigned char pad_2[48];
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) );
+
+    mbedtls_md5_init( &md5 );
+    mbedtls_sha1_init( &sha1 );
+
+    mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
+    mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
+
+    memset( pad_1, 0x36, 48 );
+    memset( pad_2, 0x5C, 48 );
+
+    mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 );
+    mbedtls_md5_update_ret( &md5, pad_1, 48 );
+    mbedtls_md5_finish_ret( &md5, hash );
+
+    mbedtls_md5_starts_ret( &md5 );
+    mbedtls_md5_update_ret( &md5, ssl->session_negotiate->master, 48 );
+    mbedtls_md5_update_ret( &md5, pad_2, 48 );
+    mbedtls_md5_update_ret( &md5, hash,  16 );
+    mbedtls_md5_finish_ret( &md5, hash );
+
+    mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 );
+    mbedtls_sha1_update_ret( &sha1, pad_1, 40 );
+    mbedtls_sha1_finish_ret( &sha1, hash + 16 );
+
+    mbedtls_sha1_starts_ret( &sha1 );
+    mbedtls_sha1_update_ret( &sha1, ssl->session_negotiate->master, 48 );
+    mbedtls_sha1_update_ret( &sha1, pad_2, 40 );
+    mbedtls_sha1_update_ret( &sha1, hash + 16, 20 );
+    mbedtls_sha1_finish_ret( &sha1, hash + 16 );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
+
+    mbedtls_md5_free(  &md5  );
+    mbedtls_sha1_free( &sha1 );
+
+    return;
+}
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] )
+{
+    mbedtls_md5_context md5;
+    mbedtls_sha1_context sha1;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) );
+
+    mbedtls_md5_init( &md5 );
+    mbedtls_sha1_init( &sha1 );
+
+    mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
+    mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
+
+     mbedtls_md5_finish_ret( &md5,  hash );
+    mbedtls_sha1_finish_ret( &sha1, hash + 16 );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
+
+    mbedtls_md5_free(  &md5  );
+    mbedtls_sha1_free( &sha1 );
+
+    return;
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] )
+{
+    mbedtls_sha256_context sha256;
+
+    mbedtls_sha256_init( &sha256 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) );
+
+    mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
+    mbedtls_sha256_finish_ret( &sha256, hash );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
+
+    mbedtls_sha256_free( &sha256 );
+
+    return;
+}
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] )
+{
+    mbedtls_sha512_context sha512;
+
+    mbedtls_sha512_init( &sha512 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) );
+
+    mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
+    mbedtls_sha512_finish_ret( &sha512, hash );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 );
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
+
+    mbedtls_sha512_free( &sha512 );
+
+    return;
+}
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex )
+{
+    unsigned char *p = ssl->handshake->premaster;
+    unsigned char *end = p + sizeof( ssl->handshake->premaster );
+    const unsigned char *psk = ssl->conf->psk;
+    size_t psk_len = ssl->conf->psk_len;
+
+    /* If the psk callback was called, use its result */
+    if( ssl->handshake->psk != NULL )
+    {
+        psk = ssl->handshake->psk;
+        psk_len = ssl->handshake->psk_len;
+    }
+
+    /*
+     * PMS = struct {
+     *     opaque other_secret<0..2^16-1>;
+     *     opaque psk<0..2^16-1>;
+     * };
+     * with "other_secret" depending on the particular key exchange
+     */
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+    if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK )
+    {
+        if( end - p < 2 )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        *(p++) = (unsigned char)( psk_len >> 8 );
+        *(p++) = (unsigned char)( psk_len      );
+
+        if( end < p || (size_t)( end - p ) < psk_len )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        memset( p, 0, psk_len );
+        p += psk_len;
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+    if( key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+    {
+        /*
+         * other_secret already set by the ClientKeyExchange message,
+         * and is 48 bytes long
+         */
+        if( end - p < 2 )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        *p++ = 0;
+        *p++ = 48;
+        p += 48;
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+    if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
+    {
+        int ret;
+        size_t len;
+
+        /* Write length only when we know the actual value */
+        if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx,
+                                      p + 2, end - ( p + 2 ), &len,
+                                      ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
+            return( ret );
+        }
+        *(p++) = (unsigned char)( len >> 8 );
+        *(p++) = (unsigned char)( len );
+        p += len;
+
+        MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K  );
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+    if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
+    {
+        int ret;
+        size_t zlen;
+
+        if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
+                                       p + 2, end - ( p + 2 ),
+                                       ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
+            return( ret );
+        }
+
+        *(p++) = (unsigned char)( zlen >> 8 );
+        *(p++) = (unsigned char)( zlen      );
+        p += zlen;
+
+        MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
+                                MBEDTLS_DEBUG_ECDH_Z );
+    }
+    else
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    /* opaque psk<0..2^16-1>; */
+    if( end - p < 2 )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    *(p++) = (unsigned char)( psk_len >> 8 );
+    *(p++) = (unsigned char)( psk_len      );
+
+    if( end < p || (size_t)( end - p ) < psk_len )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    memcpy( p, psk, psk_len );
+    p += psk_len;
+
+    ssl->handshake->pmslen = p - ssl->handshake->premaster;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+/*
+ * SSLv3.0 MAC functions
+ */
+#define SSL_MAC_MAX_BYTES   20  /* MD-5 or SHA-1 */
+static void ssl_mac( mbedtls_md_context_t *md_ctx,
+                     const unsigned char *secret,
+                     const unsigned char *buf, size_t len,
+                     const unsigned char *ctr, int type,
+                     unsigned char out[SSL_MAC_MAX_BYTES] )
+{
+    unsigned char header[11];
+    unsigned char padding[48];
+    int padlen;
+    int md_size = mbedtls_md_get_size( md_ctx->md_info );
+    int md_type = mbedtls_md_get_type( md_ctx->md_info );
+
+    /* Only MD5 and SHA-1 supported */
+    if( md_type == MBEDTLS_MD_MD5 )
+        padlen = 48;
+    else
+        padlen = 40;
+
+    memcpy( header, ctr, 8 );
+    header[ 8] = (unsigned char)  type;
+    header[ 9] = (unsigned char)( len >> 8 );
+    header[10] = (unsigned char)( len      );
+
+    memset( padding, 0x36, padlen );
+    mbedtls_md_starts( md_ctx );
+    mbedtls_md_update( md_ctx, secret,  md_size );
+    mbedtls_md_update( md_ctx, padding, padlen  );
+    mbedtls_md_update( md_ctx, header,  11      );
+    mbedtls_md_update( md_ctx, buf,     len     );
+    mbedtls_md_finish( md_ctx, out              );
+
+    memset( padding, 0x5C, padlen );
+    mbedtls_md_starts( md_ctx );
+    mbedtls_md_update( md_ctx, secret,    md_size );
+    mbedtls_md_update( md_ctx, padding,   padlen  );
+    mbedtls_md_update( md_ctx, out,       md_size );
+    mbedtls_md_finish( md_ctx, out                );
+}
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) ||     \
+    ( defined(MBEDTLS_CIPHER_MODE_CBC) &&                                  \
+      ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C)) )
+#define SSL_SOME_MODES_USE_MAC
+#endif
+
+/* The function below is only used in the Lucky 13 counter-measure in
+ * ssl_decrypt_buf(). These are the defines that guard the call site. */
+#if defined(SSL_SOME_MODES_USE_MAC) && \
+    ( defined(MBEDTLS_SSL_PROTO_TLS1) || \
+      defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+      defined(MBEDTLS_SSL_PROTO_TLS1_2) )
+/* This function makes sure every byte in the memory region is accessed
+ * (in ascending addresses order) */
+static void ssl_read_memory( unsigned char *p, size_t len )
+{
+    unsigned char acc = 0;
+    volatile unsigned char force;
+
+    for( ; len != 0; p++, len-- )
+        acc ^= *p;
+
+    force = acc;
+    (void) force;
+}
+#endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */
+
+/*
+ * Encryption/decryption functions
+ */
+static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
+{
+    mbedtls_cipher_mode_t mode;
+    int auth_done = 0;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
+
+    if( ssl->session_out == NULL || ssl->transform_out == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc );
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
+                      ssl->out_msg, ssl->out_msglen );
+
+    /*
+     * Add MAC before if needed
+     */
+#if defined(SSL_SOME_MODES_USE_MAC)
+    if( mode == MBEDTLS_MODE_STREAM ||
+        ( mode == MBEDTLS_MODE_CBC
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+          && ssl->session_out->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
+#endif
+        ) )
+    {
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+        if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+        {
+            unsigned char mac[SSL_MAC_MAX_BYTES];
+
+            ssl_mac( &ssl->transform_out->md_ctx_enc,
+                      ssl->transform_out->mac_enc,
+                      ssl->out_msg, ssl->out_msglen,
+                      ssl->out_ctr, ssl->out_msgtype,
+                      mac );
+
+            memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen );
+        }
+        else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+        defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+        {
+            unsigned char mac[MBEDTLS_SSL_MAC_ADD];
+
+            mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 );
+            mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 );
+            mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 );
+            mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
+                             ssl->out_msg, ssl->out_msglen );
+            mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac );
+            mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
+
+            memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen );
+        }
+        else
+#endif
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac",
+                       ssl->out_msg + ssl->out_msglen,
+                       ssl->transform_out->maclen );
+
+        ssl->out_msglen += ssl->transform_out->maclen;
+        auth_done++;
+    }
+#endif /* AEAD not the only option */
+
+    /*
+     * Encrypt
+     */
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
+    if( mode == MBEDTLS_MODE_STREAM )
+    {
+        int ret;
+        size_t olen = 0;
+
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
+                            "including %d bytes of padding",
+                       ssl->out_msglen, 0 ) );
+
+        if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
+                                   ssl->transform_out->iv_enc,
+                                   ssl->transform_out->ivlen,
+                                   ssl->out_msg, ssl->out_msglen,
+                                   ssl->out_msg, &olen ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+            return( ret );
+        }
+
+        if( ssl->out_msglen != olen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+    }
+    else
+#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
+#if defined(MBEDTLS_GCM_C) || \
+    defined(MBEDTLS_CCM_C) || \
+    defined(MBEDTLS_CHACHAPOLY_C)
+    if( mode == MBEDTLS_MODE_GCM ||
+        mode == MBEDTLS_MODE_CCM ||
+        mode == MBEDTLS_MODE_CHACHAPOLY )
+    {
+        int ret;
+        size_t enc_msglen, olen;
+        unsigned char *enc_msg;
+        unsigned char add_data[13];
+        unsigned char iv[12];
+        mbedtls_ssl_transform *transform = ssl->transform_out;
+        unsigned char taglen = transform->ciphersuite_info->flags &
+                               MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
+        size_t explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
+
+        /*
+         * Prepare additional authenticated data
+         */
+        memcpy( add_data, ssl->out_ctr, 8 );
+        add_data[8]  = ssl->out_msgtype;
+        mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
+                           ssl->conf->transport, add_data + 9 );
+        add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF;
+        add_data[12] = ssl->out_msglen & 0xFF;
+
+        MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 );
+
+        /*
+         * Generate IV
+         */
+        if( transform->ivlen == 12 && transform->fixed_ivlen == 4 )
+        {
+            /* GCM and CCM: fixed || explicit (=seqnum) */
+            memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
+            memcpy( iv + transform->fixed_ivlen, ssl->out_ctr, 8 );
+            memcpy( ssl->out_iv, ssl->out_ctr, 8 );
+
+        }
+        else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
+        {
+            /* ChachaPoly: fixed XOR sequence number */
+            unsigned char i;
+
+            memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
+
+            for( i = 0; i < 8; i++ )
+                iv[i+4] ^= ssl->out_ctr[i];
+        }
+        else
+        {
+            /* Reminder if we ever add an AEAD mode with a different size */
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)",
+                                  iv, transform->ivlen );
+        MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)",
+                                  ssl->out_iv, explicit_ivlen );
+
+        /*
+         * Fix message length with added IV
+         */
+        enc_msg = ssl->out_msg;
+        enc_msglen = ssl->out_msglen;
+        ssl->out_msglen += explicit_ivlen;
+
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
+                                    "including 0 bytes of padding",
+                                    ssl->out_msglen ) );
+
+        /*
+         * Encrypt and authenticate
+         */
+        if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc,
+                                         iv, transform->ivlen,
+                                         add_data, 13,
+                                         enc_msg, enc_msglen,
+                                         enc_msg, &olen,
+                                         enc_msg + enc_msglen, taglen ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
+            return( ret );
+        }
+
+        if( olen != enc_msglen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        ssl->out_msglen += taglen;
+        auth_done++;
+
+        MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen );
+    }
+    else
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CIPHER_MODE_CBC) &&                                    \
+    ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
+    if( mode == MBEDTLS_MODE_CBC )
+    {
+        int ret;
+        unsigned char *enc_msg;
+        size_t enc_msglen, padlen, olen = 0, i;
+
+        padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) %
+                 ssl->transform_out->ivlen;
+        if( padlen == ssl->transform_out->ivlen )
+            padlen = 0;
+
+        for( i = 0; i <= padlen; i++ )
+            ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen;
+
+        ssl->out_msglen += padlen + 1;
+
+        enc_msglen = ssl->out_msglen;
+        enc_msg = ssl->out_msg;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        /*
+         * Prepend per-record IV for block cipher in TLS v1.1 and up as per
+         * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
+         */
+        if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+        {
+            /*
+             * Generate IV
+             */
+            ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc,
+                                  ssl->transform_out->ivlen );
+            if( ret != 0 )
+                return( ret );
+
+            memcpy( ssl->out_iv, ssl->transform_out->iv_enc,
+                    ssl->transform_out->ivlen );
+
+            /*
+             * Fix pointer positions and message length with added IV
+             */
+            enc_msg = ssl->out_msg;
+            enc_msglen = ssl->out_msglen;
+            ssl->out_msglen += ssl->transform_out->ivlen;
+        }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
+                            "including %d bytes of IV and %d bytes of padding",
+                            ssl->out_msglen, ssl->transform_out->ivlen,
+                            padlen + 1 ) );
+
+        if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
+                                   ssl->transform_out->iv_enc,
+                                   ssl->transform_out->ivlen,
+                                   enc_msg, enc_msglen,
+                                   enc_msg, &olen ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+            return( ret );
+        }
+
+        if( enc_msglen != olen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
+        if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
+        {
+            /*
+             * Save IV in SSL3 and TLS1
+             */
+            memcpy( ssl->transform_out->iv_enc,
+                    ssl->transform_out->cipher_ctx_enc.iv,
+                    ssl->transform_out->ivlen );
+        }
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+        if( auth_done == 0 )
+        {
+            unsigned char mac[MBEDTLS_SSL_MAC_ADD];
+
+            /*
+             * MAC(MAC_write_key, seq_num +
+             *     TLSCipherText.type +
+             *     TLSCipherText.version +
+             *     length_of( (IV +) ENC(...) ) +
+             *     IV + // except for TLS 1.0
+             *     ENC(content + padding + padding_length));
+             */
+            unsigned char pseudo_hdr[13];
+
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
+
+            memcpy( pseudo_hdr +  0, ssl->out_ctr, 8 );
+            memcpy( pseudo_hdr +  8, ssl->out_hdr, 3 );
+            pseudo_hdr[11] = (unsigned char)( ( ssl->out_msglen >> 8 ) & 0xFF );
+            pseudo_hdr[12] = (unsigned char)( ( ssl->out_msglen      ) & 0xFF );
+
+            MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 );
+
+            mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 );
+            mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
+                             ssl->out_iv, ssl->out_msglen );
+            mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac );
+            mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
+
+            memcpy( ssl->out_iv + ssl->out_msglen, mac,
+                    ssl->transform_out->maclen );
+
+            ssl->out_msglen += ssl->transform_out->maclen;
+            auth_done++;
+        }
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+    }
+    else
+#endif /* MBEDTLS_CIPHER_MODE_CBC &&
+          ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    /* Make extra sure authentication was performed, exactly once */
+    if( auth_done != 1 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
+
+    return( 0 );
+}
+
+static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
+{
+    mbedtls_cipher_mode_t mode;
+    int auth_done = 0;
+#if defined(SSL_SOME_MODES_USE_MAC)
+    size_t padlen = 0, correct = 1;
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
+
+    if( ssl->session_in == NULL || ssl->transform_in == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_in->cipher_ctx_dec );
+
+    if( ssl->in_msglen < ssl->transform_in->minlen )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)",
+                       ssl->in_msglen, ssl->transform_in->minlen ) );
+        return( MBEDTLS_ERR_SSL_INVALID_MAC );
+    }
+
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
+    if( mode == MBEDTLS_MODE_STREAM )
+    {
+        int ret;
+        size_t olen = 0;
+
+        padlen = 0;
+
+        if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec,
+                                   ssl->transform_in->iv_dec,
+                                   ssl->transform_in->ivlen,
+                                   ssl->in_msg, ssl->in_msglen,
+                                   ssl->in_msg, &olen ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+            return( ret );
+        }
+
+        if( ssl->in_msglen != olen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+    }
+    else
+#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
+#if defined(MBEDTLS_GCM_C) || \
+    defined(MBEDTLS_CCM_C) || \
+    defined(MBEDTLS_CHACHAPOLY_C)
+    if( mode == MBEDTLS_MODE_GCM ||
+        mode == MBEDTLS_MODE_CCM ||
+        mode == MBEDTLS_MODE_CHACHAPOLY )
+    {
+        int ret;
+        size_t dec_msglen, olen;
+        unsigned char *dec_msg;
+        unsigned char *dec_msg_result;
+        unsigned char add_data[13];
+        unsigned char iv[12];
+        mbedtls_ssl_transform *transform = ssl->transform_in;
+        unsigned char taglen = transform->ciphersuite_info->flags &
+                               MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
+        size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen;
+
+        /*
+         * Compute and update sizes
+         */
+        if( ssl->in_msglen < explicit_iv_len + taglen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) "
+                                "+ taglen (%d)", ssl->in_msglen,
+                                explicit_iv_len, taglen ) );
+            return( MBEDTLS_ERR_SSL_INVALID_MAC );
+        }
+        dec_msglen = ssl->in_msglen - explicit_iv_len - taglen;
+
+        dec_msg = ssl->in_msg;
+        dec_msg_result = ssl->in_msg;
+        ssl->in_msglen = dec_msglen;
+
+        /*
+         * Prepare additional authenticated data
+         */
+        memcpy( add_data, ssl->in_ctr, 8 );
+        add_data[8]  = ssl->in_msgtype;
+        mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
+                           ssl->conf->transport, add_data + 9 );
+        add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF;
+        add_data[12] = ssl->in_msglen & 0xFF;
+
+        MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 );
+
+        /*
+         * Prepare IV
+         */
+        if( transform->ivlen == 12 && transform->fixed_ivlen == 4 )
+        {
+            /* GCM and CCM: fixed || explicit (transmitted) */
+            memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
+            memcpy( iv + transform->fixed_ivlen, ssl->in_iv, 8 );
+
+        }
+        else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
+        {
+            /* ChachaPoly: fixed XOR sequence number */
+            unsigned char i;
+
+            memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
+
+            for( i = 0; i < 8; i++ )
+                iv[i+4] ^= ssl->in_ctr[i];
+        }
+        else
+        {
+            /* Reminder if we ever add an AEAD mode with a different size */
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen );
+        MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen );
+
+        /*
+         * Decrypt and authenticate
+         */
+        if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec,
+                                         iv, transform->ivlen,
+                                         add_data, 13,
+                                         dec_msg, dec_msglen,
+                                         dec_msg_result, &olen,
+                                         dec_msg + dec_msglen, taglen ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
+
+            if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
+                return( MBEDTLS_ERR_SSL_INVALID_MAC );
+
+            return( ret );
+        }
+        auth_done++;
+
+        if( olen != dec_msglen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+    }
+    else
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CIPHER_MODE_CBC) &&                                    \
+    ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
+    if( mode == MBEDTLS_MODE_CBC )
+    {
+        /*
+         * Decrypt and check the padding
+         */
+        int ret;
+        unsigned char *dec_msg;
+        unsigned char *dec_msg_result;
+        size_t dec_msglen;
+        size_t minlen = 0;
+        size_t olen = 0;
+
+        /*
+         * Check immediate ciphertext sanity
+         */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+            minlen += ssl->transform_in->ivlen;
+#endif
+
+        if( ssl->in_msglen < minlen + ssl->transform_in->ivlen ||
+            ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) "
+                                "+ 1 ) ( + expl IV )", ssl->in_msglen,
+                                ssl->transform_in->ivlen,
+                                ssl->transform_in->maclen ) );
+            return( MBEDTLS_ERR_SSL_INVALID_MAC );
+        }
+
+        dec_msglen = ssl->in_msglen;
+        dec_msg = ssl->in_msg;
+        dec_msg_result = ssl->in_msg;
+
+        /*
+         * Authenticate before decrypt if enabled
+         */
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+        if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
+        {
+            unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
+            unsigned char pseudo_hdr[13];
+
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
+
+            dec_msglen -= ssl->transform_in->maclen;
+            ssl->in_msglen -= ssl->transform_in->maclen;
+
+            memcpy( pseudo_hdr +  0, ssl->in_ctr, 8 );
+            memcpy( pseudo_hdr +  8, ssl->in_hdr, 3 );
+            pseudo_hdr[11] = (unsigned char)( ( ssl->in_msglen >> 8 ) & 0xFF );
+            pseudo_hdr[12] = (unsigned char)( ( ssl->in_msglen      ) & 0xFF );
+
+            MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 );
+
+            mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 );
+            mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec,
+                             ssl->in_iv, ssl->in_msglen );
+            mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
+            mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
+
+            MBEDTLS_SSL_DEBUG_BUF( 4, "message  mac", ssl->in_iv + ssl->in_msglen,
+                                              ssl->transform_in->maclen );
+            MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect,
+                                              ssl->transform_in->maclen );
+
+            if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, mac_expect,
+                                          ssl->transform_in->maclen ) != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
+
+                return( MBEDTLS_ERR_SSL_INVALID_MAC );
+            }
+            auth_done++;
+        }
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+        /*
+         * Check length sanity
+         */
+        if( ssl->in_msglen % ssl->transform_in->ivlen != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0",
+                           ssl->in_msglen, ssl->transform_in->ivlen ) );
+            return( MBEDTLS_ERR_SSL_INVALID_MAC );
+        }
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        /*
+         * Initialize for prepended IV for block cipher in TLS v1.1 and up
+         */
+        if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+        {
+            unsigned char i;
+            dec_msglen -= ssl->transform_in->ivlen;
+            ssl->in_msglen -= ssl->transform_in->ivlen;
+
+            for( i = 0; i < ssl->transform_in->ivlen; i++ )
+                ssl->transform_in->iv_dec[i] = ssl->in_iv[i];
+        }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
+        if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec,
+                                   ssl->transform_in->iv_dec,
+                                   ssl->transform_in->ivlen,
+                                   dec_msg, dec_msglen,
+                                   dec_msg_result, &olen ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+            return( ret );
+        }
+
+        if( dec_msglen != olen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
+        if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
+        {
+            /*
+             * Save IV in SSL3 and TLS1
+             */
+            memcpy( ssl->transform_in->iv_dec,
+                    ssl->transform_in->cipher_ctx_dec.iv,
+                    ssl->transform_in->ivlen );
+        }
+#endif
+
+        padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];
+
+        if( ssl->in_msglen < ssl->transform_in->maclen + padlen &&
+            auth_done == 0 )
+        {
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
+                        ssl->in_msglen, ssl->transform_in->maclen, padlen ) );
+#endif
+            padlen = 0;
+            correct = 0;
+        }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+        if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+        {
+            if( padlen > ssl->transform_in->ivlen )
+            {
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, "
+                                    "should be no more than %d",
+                               padlen, ssl->transform_in->ivlen ) );
+#endif
+                correct = 0;
+            }
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
+        {
+            /*
+             * TLSv1+: always check the padding up to the first failure
+             * and fake check up to 256 bytes of padding
+             */
+            size_t pad_count = 0, real_count = 1;
+            size_t padding_idx = ssl->in_msglen - padlen;
+            size_t i;
+
+            /*
+             * Padding is guaranteed to be incorrect if:
+             *   1. padlen > ssl->in_msglen
+             *
+             *   2. padding_idx > MBEDTLS_SSL_IN_CONTENT_LEN +
+             *                     ssl->transform_in->maclen
+             *
+             * In both cases we reset padding_idx to a safe value (0) to
+             * prevent out-of-buffer reads.
+             */
+            correct &= ( padlen <= ssl->in_msglen );
+            correct &= ( padding_idx <= MBEDTLS_SSL_IN_CONTENT_LEN +
+                                       ssl->transform_in->maclen );
+
+            padding_idx *= correct;
+
+            for( i = 0; i < 256; i++ )
+            {
+                real_count &= ( i < padlen );
+                pad_count += real_count *
+                             ( ssl->in_msg[padding_idx + i] == padlen - 1 );
+            }
+
+            correct &= ( pad_count == padlen ); /* Only 1 on correct padding */
+
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+            if( padlen > 0 && correct == 0 )
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
+#endif
+            padlen &= correct * 0x1FF;
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+          MBEDTLS_SSL_PROTO_TLS1_2 */
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        ssl->in_msglen -= padlen;
+    }
+    else
+#endif /* MBEDTLS_CIPHER_MODE_CBC &&
+          ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
+                   ssl->in_msg, ssl->in_msglen );
+#endif
+
+    /*
+     * Authenticate if not done yet.
+     * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
+     */
+#if defined(SSL_SOME_MODES_USE_MAC)
+    if( auth_done == 0 )
+    {
+        unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
+
+        ssl->in_msglen -= ssl->transform_in->maclen;
+
+        ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 );
+        ssl->in_len[1] = (unsigned char)( ssl->in_msglen      );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+        if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+        {
+            ssl_mac( &ssl->transform_in->md_ctx_dec,
+                      ssl->transform_in->mac_dec,
+                      ssl->in_msg, ssl->in_msglen,
+                      ssl->in_ctr, ssl->in_msgtype,
+                      mac_expect );
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+        defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
+        {
+            /*
+             * Process MAC and always update for padlen afterwards to make
+             * total time independent of padlen.
+             *
+             * Known timing attacks:
+             *  - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
+             *
+             * To compensate for different timings for the MAC calculation
+             * depending on how much padding was removed (which is determined
+             * by padlen), process extra_run more blocks through the hash
+             * function.
+             *
+             * The formula in the paper is
+             *   extra_run = ceil( (L1-55) / 64 ) - ceil( (L2-55) / 64 )
+             * where L1 is the size of the header plus the decrypted message
+             * plus CBC padding and L2 is the size of the header plus the
+             * decrypted message. This is for an underlying hash function
+             * with 64-byte blocks.
+             * We use ( (Lx+8) / 64 ) to handle 'negative Lx' values
+             * correctly. We round down instead of up, so -56 is the correct
+             * value for our calculations instead of -55.
+             *
+             * Repeat the formula rather than defining a block_size variable.
+             * This avoids requiring division by a variable at runtime
+             * (which would be marginally less efficient and would require
+             * linking an extra division function in some builds).
+             */
+            size_t j, extra_run = 0;
+
+            /*
+             * The next two sizes are the minimum and maximum values of
+             * in_msglen over all padlen values.
+             *
+             * They're independent of padlen, since we previously did
+             * in_msglen -= padlen.
+             *
+             * Note that max_len + maclen is never more than the buffer
+             * length, as we previously did in_msglen -= maclen too.
+             */
+            const size_t max_len = ssl->in_msglen + padlen;
+            const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
+
+            switch( ssl->transform_in->ciphersuite_info->mac )
+            {
+#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \
+    defined(MBEDTLS_SHA256_C)
+                case MBEDTLS_MD_MD5:
+                case MBEDTLS_MD_SHA1:
+                case MBEDTLS_MD_SHA256:
+                    /* 8 bytes of message size, 64-byte compression blocks */
+                    extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
+                                ( 13 + ssl->in_msglen          + 8 ) / 64;
+                    break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+                case MBEDTLS_MD_SHA384:
+                    /* 16 bytes of message size, 128-byte compression blocks */
+                    extra_run = ( 13 + ssl->in_msglen + padlen + 16 ) / 128 -
+                                ( 13 + ssl->in_msglen          + 16 ) / 128;
+                    break;
+#endif
+                default:
+                    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+            }
+
+            extra_run &= correct * 0xFF;
+
+            mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 8 );
+            mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_hdr, 3 );
+            mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 );
+            mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
+                             ssl->in_msglen );
+            /* Make sure we access everything even when padlen > 0. This
+             * makes the synchronisation requirements for just-in-time
+             * Prime+Probe attacks much tighter and hopefully impractical. */
+            ssl_read_memory( ssl->in_msg + ssl->in_msglen, padlen );
+            mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
+
+            /* Call mbedtls_md_process at least once due to cache attacks
+             * that observe whether md_process() was called of not */
+            for( j = 0; j < extra_run + 1; j++ )
+                mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
+
+            mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
+
+            /* Make sure we access all the memory that could contain the MAC,
+             * before we check it in the next code block. This makes the
+             * synchronisation requirements for just-in-time Prime+Probe
+             * attacks much tighter and hopefully impractical. */
+            ssl_read_memory( ssl->in_msg + min_len,
+                                 max_len - min_len + ssl->transform_in->maclen );
+        }
+        else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+              MBEDTLS_SSL_PROTO_TLS1_2 */
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+        MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen );
+        MBEDTLS_SSL_DEBUG_BUF( 4, "message  mac", ssl->in_msg + ssl->in_msglen,
+                               ssl->transform_in->maclen );
+#endif
+
+        if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect,
+                                      ssl->transform_in->maclen ) != 0 )
+        {
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
+#endif
+            correct = 0;
+        }
+        auth_done++;
+    }
+
+    /*
+     * Finally check the correct flag
+     */
+    if( correct == 0 )
+        return( MBEDTLS_ERR_SSL_INVALID_MAC );
+#endif /* SSL_SOME_MODES_USE_MAC */
+
+    /* Make extra sure authentication was performed, exactly once */
+    if( auth_done != 1 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    if( ssl->in_msglen == 0 )
+    {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3
+            && ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
+        {
+            /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) );
+            return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+        }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+        ssl->nb_zero++;
+
+        /*
+         * Three or more empty messages may be a DoS attack
+         * (excessive CPU consumption).
+         */
+        if( ssl->nb_zero > 3 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
+                                "messages, possible DoS attack" ) );
+            return( MBEDTLS_ERR_SSL_INVALID_MAC );
+        }
+    }
+    else
+        ssl->nb_zero = 0;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ; /* in_ctr read from peer, not maintained internally */
+    }
+    else
+#endif
+    {
+        unsigned char i;
+        for( i = 8; i > ssl_ep_len( ssl ); i-- )
+            if( ++ssl->in_ctr[i - 1] != 0 )
+                break;
+
+        /* The loop goes to its end iff the counter is wrapping */
+        if( i == ssl_ep_len( ssl ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
+            return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+        }
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
+
+    return( 0 );
+}
+
+#undef MAC_NONE
+#undef MAC_PLAINTEXT
+#undef MAC_CIPHERTEXT
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+/*
+ * Compression/decompression functions
+ */
+static int ssl_compress_buf( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    unsigned char *msg_post = ssl->out_msg;
+    ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
+    size_t len_pre = ssl->out_msglen;
+    unsigned char *msg_pre = ssl->compress_buf;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
+
+    if( len_pre == 0 )
+        return( 0 );
+
+    memcpy( msg_pre, ssl->out_msg, len_pre );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ",
+                   ssl->out_msglen ) );
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload",
+                   ssl->out_msg, ssl->out_msglen );
+
+    ssl->transform_out->ctx_deflate.next_in = msg_pre;
+    ssl->transform_out->ctx_deflate.avail_in = len_pre;
+    ssl->transform_out->ctx_deflate.next_out = msg_post;
+    ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_OUT_BUFFER_LEN - bytes_written;
+
+    ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
+    if( ret != Z_OK )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
+        return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
+    }
+
+    ssl->out_msglen = MBEDTLS_SSL_OUT_BUFFER_LEN -
+                      ssl->transform_out->ctx_deflate.avail_out - bytes_written;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
+                   ssl->out_msglen ) );
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload",
+                   ssl->out_msg, ssl->out_msglen );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
+
+    return( 0 );
+}
+
+static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    unsigned char *msg_post = ssl->in_msg;
+    ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
+    size_t len_pre = ssl->in_msglen;
+    unsigned char *msg_pre = ssl->compress_buf;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
+
+    if( len_pre == 0 )
+        return( 0 );
+
+    memcpy( msg_pre, ssl->in_msg, len_pre );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ",
+                   ssl->in_msglen ) );
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload",
+                   ssl->in_msg, ssl->in_msglen );
+
+    ssl->transform_in->ctx_inflate.next_in = msg_pre;
+    ssl->transform_in->ctx_inflate.avail_in = len_pre;
+    ssl->transform_in->ctx_inflate.next_out = msg_post;
+    ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_IN_BUFFER_LEN -
+                                               header_bytes;
+
+    ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
+    if( ret != Z_OK )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
+        return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
+    }
+
+    ssl->in_msglen = MBEDTLS_SSL_IN_BUFFER_LEN -
+                     ssl->transform_in->ctx_inflate.avail_out - header_bytes;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
+                   ssl->in_msglen ) );
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload",
+                   ssl->in_msg, ssl->in_msglen );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_ZLIB_SUPPORT */
+
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
+static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+static int ssl_resend_hello_request( mbedtls_ssl_context *ssl )
+{
+    /* If renegotiation is not enforced, retransmit until we would reach max
+     * timeout if we were using the usual handshake doubling scheme */
+    if( ssl->conf->renego_max_records < 0 )
+    {
+        uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1;
+        unsigned char doublings = 1;
+
+        while( ratio != 0 )
+        {
+            ++doublings;
+            ratio >>= 1;
+        }
+
+        if( ++ssl->renego_records_seen > doublings )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "no longer retransmitting hello request" ) );
+            return( 0 );
+        }
+    }
+
+    return( ssl_write_hello_request( ssl ) );
+}
+#endif
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
+
+/*
+ * Fill the input message buffer by appending data to it.
+ * The amount of data already fetched is in ssl->in_left.
+ *
+ * If we return 0, is it guaranteed that (at least) nb_want bytes are
+ * available (from this read and/or a previous one). Otherwise, an error code
+ * is returned (possibly EOF or WANT_READ).
+ *
+ * With stream transport (TLS) on success ssl->in_left == nb_want, but
+ * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
+ * since we always read a whole datagram at once.
+ *
+ * For DTLS, it is up to the caller to set ssl->next_record_offset when
+ * they're done reading a record.
+ */
+int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
+{
+    int ret;
+    size_t len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
+
+    if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
+                            "or mbedtls_ssl_set_bio()" ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    if( nb_want > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        uint32_t timeout;
+
+        /* Just to be sure */
+        if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
+                        "mbedtls_ssl_set_timer_cb() for DTLS" ) );
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+        }
+
+        /*
+         * The point is, we need to always read a full datagram at once, so we
+         * sometimes read more then requested, and handle the additional data.
+         * It could be the rest of the current record (while fetching the
+         * header) and/or some other records in the same datagram.
+         */
+
+        /*
+         * Move to the next record in the already read datagram if applicable
+         */
+        if( ssl->next_record_offset != 0 )
+        {
+            if( ssl->in_left < ssl->next_record_offset )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+            }
+
+            ssl->in_left -= ssl->next_record_offset;
+
+            if( ssl->in_left != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d",
+                                    ssl->next_record_offset ) );
+                memmove( ssl->in_hdr,
+                         ssl->in_hdr + ssl->next_record_offset,
+                         ssl->in_left );
+            }
+
+            ssl->next_record_offset = 0;
+        }
+
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
+                       ssl->in_left, nb_want ) );
+
+        /*
+         * Done if we already have enough data.
+         */
+        if( nb_want <= ssl->in_left)
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
+            return( 0 );
+        }
+
+        /*
+         * A record can't be split accross datagrams. If we need to read but
+         * are not at the beginning of a new record, the caller did something
+         * wrong.
+         */
+        if( ssl->in_left != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        /*
+         * Don't even try to read if time's out already.
+         * This avoids by-passing the timer when repeatedly receiving messages
+         * that will end up being dropped.
+         */
+        if( ssl_check_timer( ssl ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) );
+            ret = MBEDTLS_ERR_SSL_TIMEOUT;
+        }
+        else
+        {
+            len = MBEDTLS_SSL_IN_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf );
+
+            if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+                timeout = ssl->handshake->retransmit_timeout;
+            else
+                timeout = ssl->conf->read_timeout;
+
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) );
+
+            if( ssl->f_recv_timeout != NULL )
+                ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
+                                                                    timeout );
+            else
+                ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
+
+            MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
+
+            if( ret == 0 )
+                return( MBEDTLS_ERR_SSL_CONN_EOF );
+        }
+
+        if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
+            ssl_set_timer( ssl, 0 );
+
+            if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+            {
+                if( ssl_double_retransmit_timeout( ssl ) != 0 )
+                {
+                    MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
+                    return( MBEDTLS_ERR_SSL_TIMEOUT );
+                }
+
+                if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
+                {
+                    MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
+                    return( ret );
+                }
+
+                return( MBEDTLS_ERR_SSL_WANT_READ );
+            }
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
+            else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+                     ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
+            {
+                if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
+                {
+                    MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
+                    return( ret );
+                }
+
+                return( MBEDTLS_ERR_SSL_WANT_READ );
+            }
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
+        }
+
+        if( ret < 0 )
+            return( ret );
+
+        ssl->in_left = ret;
+    }
+    else
+#endif
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
+                       ssl->in_left, nb_want ) );
+
+        while( ssl->in_left < nb_want )
+        {
+            len = nb_want - ssl->in_left;
+
+            if( ssl_check_timer( ssl ) != 0 )
+                ret = MBEDTLS_ERR_SSL_TIMEOUT;
+            else
+            {
+                if( ssl->f_recv_timeout != NULL )
+                {
+                    ret = ssl->f_recv_timeout( ssl->p_bio,
+                                               ssl->in_hdr + ssl->in_left, len,
+                                               ssl->conf->read_timeout );
+                }
+                else
+                {
+                    ret = ssl->f_recv( ssl->p_bio,
+                                       ssl->in_hdr + ssl->in_left, len );
+                }
+            }
+
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
+                                        ssl->in_left, nb_want ) );
+            MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
+
+            if( ret == 0 )
+                return( MBEDTLS_ERR_SSL_CONN_EOF );
+
+            if( ret < 0 )
+                return( ret );
+
+            if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1,
+                    ( "f_recv returned %d bytes but only %lu were requested",
+                    ret, (unsigned long)len ) );
+                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+            }
+
+            ssl->in_left += ret;
+        }
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
+
+    return( 0 );
+}
+
+/*
+ * Flush any data not yet written
+ */
+int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    unsigned char *buf;
+	static int count = 0;
+
+	if (count > 0)
+		return 0;
+
+	count++;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
+
+    if( ssl->f_send == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
+                            "or mbedtls_ssl_set_bio()" ) );
+        count--;
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    /* Avoid incrementing counter if data is flushed */
+    if( ssl->out_left == 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
+        count--;
+        return( 0 );
+    }
+
+    while( ssl->out_left > 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
+                       mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
+
+        buf = ssl->out_hdr - ssl->out_left;
+        ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
+
+        MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
+
+        if( ret <= 0 ) {
+            count--;
+            return( ret );
+        }
+
+        if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1,
+                ( "f_send returned %d bytes but only %lu bytes were sent",
+                ret, (unsigned long)ssl->out_left ) );
+            count--;
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        ssl->out_left -= ret;
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl->out_hdr = ssl->out_buf;
+    }
+    else
+#endif
+    {
+        ssl->out_hdr = ssl->out_buf + 8;
+    }
+    ssl_update_out_pointers( ssl, ssl->transform_out );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
+
+    count--;
+    return( 0 );
+}
+
+/*
+ * Functions to handle the DTLS retransmission state machine
+ */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+/*
+ * Append current handshake message to current outgoing flight
+ */
+static int ssl_flight_append( mbedtls_ssl_context *ssl )
+{
+    mbedtls_ssl_flight_item *msg;
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) );
+    MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight",
+                           ssl->out_msg, ssl->out_msglen );
+
+    /* Allocate space for current message */
+    if( ( msg = mbedtls_calloc( 1, sizeof(  mbedtls_ssl_flight_item ) ) ) == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed",
+                            sizeof( mbedtls_ssl_flight_item ) ) );
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+    }
+
+    if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) );
+        mbedtls_free( msg );
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+    }
+
+    /* Copy current handshake message with headers */
+    memcpy( msg->p, ssl->out_msg, ssl->out_msglen );
+    msg->len = ssl->out_msglen;
+    msg->type = ssl->out_msgtype;
+    msg->next = NULL;
+
+    /* Append to the current flight */
+    if( ssl->handshake->flight == NULL )
+        ssl->handshake->flight = msg;
+    else
+    {
+        mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
+        while( cur->next != NULL )
+            cur = cur->next;
+        cur->next = msg;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
+    return( 0 );
+}
+
+/*
+ * Free the current flight of handshake messages
+ */
+static void ssl_flight_free( mbedtls_ssl_flight_item *flight )
+{
+    mbedtls_ssl_flight_item *cur = flight;
+    mbedtls_ssl_flight_item *next;
+
+    while( cur != NULL )
+    {
+        next = cur->next;
+
+        mbedtls_free( cur->p );
+        mbedtls_free( cur );
+
+        cur = next;
+    }
+}
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
+#endif
+
+/*
+ * Swap transform_out and out_ctr with the alternative ones
+ */
+static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
+{
+    mbedtls_ssl_transform *tmp_transform;
+    unsigned char tmp_out_ctr[8];
+
+    if( ssl->transform_out == ssl->handshake->alt_transform_out )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
+        return;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
+
+    /* Swap transforms */
+    tmp_transform                     = ssl->transform_out;
+    ssl->transform_out                = ssl->handshake->alt_transform_out;
+    ssl->handshake->alt_transform_out = tmp_transform;
+
+    /* Swap epoch + sequence_number */
+    memcpy( tmp_out_ctr,                 ssl->cur_out_ctr,            8 );
+    memcpy( ssl->cur_out_ctr,            ssl->handshake->alt_out_ctr, 8 );
+    memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr,                 8 );
+
+    /* Adjust to the newly activated transform */
+    ssl_update_out_pointers( ssl, ssl->transform_out );
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+    if( mbedtls_ssl_hw_record_activate != NULL )
+    {
+        if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+    }
+#endif
+}
+
+/*
+ * Retransmit the current flight of messages.
+ */
+int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
+{
+    int ret = 0;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
+
+    ret = mbedtls_ssl_flight_transmit( ssl );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
+
+    return( ret );
+}
+
+/*
+ * Transmit or retransmit the current flight of messages.
+ *
+ * Need to remember the current message in case flush_output returns
+ * WANT_WRITE, causing us to exit this function and come back later.
+ * This function must be called until state is no longer SENDING.
+ */
+int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
+
+    if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) );
+
+        ssl->handshake->cur_msg = ssl->handshake->flight;
+        ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
+        ssl_swap_epochs( ssl );
+
+        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
+    }
+
+    while( ssl->handshake->cur_msg != NULL )
+    {
+        size_t max_frag_len;
+        const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
+
+        int const is_finished =
+            ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
+              cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
+
+        uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
+            SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
+
+        /* Swap epochs before sending Finished: we can't do it after
+         * sending ChangeCipherSpec, in case write returns WANT_READ.
+         * Must be done before copying, may change out_msg pointer */
+        if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
+            ssl_swap_epochs( ssl );
+        }
+
+        ret = ssl_get_remaining_payload_in_datagram( ssl );
+        if( ret < 0 )
+            return( ret );
+        max_frag_len = (size_t) ret;
+
+        /* CCS is copied as is, while HS messages may need fragmentation */
+        if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+        {
+            if( max_frag_len == 0 )
+            {
+                if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+                    return( ret );
+
+                continue;
+            }
+
+            memcpy( ssl->out_msg, cur->p, cur->len );
+            ssl->out_msglen  = cur->len;
+            ssl->out_msgtype = cur->type;
+
+            /* Update position inside current message */
+            ssl->handshake->cur_msg_p += cur->len;
+        }
+        else
+        {
+            const unsigned char * const p = ssl->handshake->cur_msg_p;
+            const size_t hs_len = cur->len - 12;
+            const size_t frag_off = p - ( cur->p + 12 );
+            const size_t rem_len = hs_len - frag_off;
+            size_t cur_hs_frag_len, max_hs_frag_len;
+
+            if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
+            {
+                if( is_finished )
+                    ssl_swap_epochs( ssl );
+
+                if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+                    return( ret );
+
+                continue;
+            }
+            max_hs_frag_len = max_frag_len - 12;
+
+            cur_hs_frag_len = rem_len > max_hs_frag_len ?
+                max_hs_frag_len : rem_len;
+
+            if( frag_off == 0 && cur_hs_frag_len != hs_len )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
+                                            (unsigned) cur_hs_frag_len,
+                                            (unsigned) max_hs_frag_len ) );
+            }
+
+            /* Messages are stored with handshake headers as if not fragmented,
+             * copy beginning of headers then fill fragmentation fields.
+             * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
+            memcpy( ssl->out_msg, cur->p, 6 );
+
+            ssl->out_msg[6] = ( ( frag_off >> 16 ) & 0xff );
+            ssl->out_msg[7] = ( ( frag_off >>  8 ) & 0xff );
+            ssl->out_msg[8] = ( ( frag_off       ) & 0xff );
+
+            ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff );
+            ssl->out_msg[10] = ( ( cur_hs_frag_len >>  8 ) & 0xff );
+            ssl->out_msg[11] = ( ( cur_hs_frag_len       ) & 0xff );
+
+            MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
+
+            /* Copy the handshake message content and set records fields */
+            memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
+            ssl->out_msglen = cur_hs_frag_len + 12;
+            ssl->out_msgtype = cur->type;
+
+            /* Update position inside current message */
+            ssl->handshake->cur_msg_p += cur_hs_frag_len;
+        }
+
+        /* If done with the current message move to the next one if any */
+        if( ssl->handshake->cur_msg_p >= cur->p + cur->len )
+        {
+            if( cur->next != NULL )
+            {
+                ssl->handshake->cur_msg = cur->next;
+                ssl->handshake->cur_msg_p = cur->next->p + 12;
+            }
+            else
+            {
+                ssl->handshake->cur_msg = NULL;
+                ssl->handshake->cur_msg_p = NULL;
+            }
+        }
+
+        /* Actually send the message out */
+        if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+            return( ret );
+        }
+    }
+
+    if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+        return( ret );
+
+    /* Update state and set timer */
+    if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
+    else
+    {
+        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+        ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) );
+
+    return( 0 );
+}
+
+/*
+ * To be called when the last message of an incoming flight is received.
+ */
+void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl )
+{
+    /* We won't need to resend that one any more */
+    ssl_flight_free( ssl->handshake->flight );
+    ssl->handshake->flight = NULL;
+    ssl->handshake->cur_msg = NULL;
+
+    /* The next incoming flight will start with this msg_seq */
+    ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
+
+    /* We don't want to remember CCS's across flight boundaries. */
+    ssl->handshake->buffering.seen_ccs = 0;
+
+    /* Clear future message buffering structure. */
+    ssl_buffering_free( ssl );
+
+    /* Cancel timer */
+    ssl_set_timer( ssl, 0 );
+
+    if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+        ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
+    {
+        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
+    }
+    else
+        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
+}
+
+/*
+ * To be called when the last message of an outgoing flight is send.
+ */
+void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
+{
+    ssl_reset_retransmit_timeout( ssl );
+    ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
+
+    if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+        ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
+    {
+        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
+    }
+    else
+        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+/*
+ * Handshake layer functions
+ */
+
+/*
+ * Write (DTLS: or queue) current handshake (including CCS) message.
+ *
+ *  - fill in handshake headers
+ *  - update handshake checksum
+ *  - DTLS: save message for resending
+ *  - then pass to the record layer
+ *
+ * DTLS: except for HelloRequest, messages are only queued, and will only be
+ * actually sent when calling flight_transmit() or resend().
+ *
+ * Inputs:
+ *  - ssl->out_msglen: 4 + actual handshake message len
+ *      (4 is the size of handshake headers for TLS)
+ *  - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
+ *  - ssl->out_msg + 4: the handshake message body
+ *
+ * Outputs, ie state before passing to flight_append() or write_record():
+ *   - ssl->out_msglen: the length of the record contents
+ *      (including handshake headers but excluding record headers)
+ *   - ssl->out_msg: the record contents (handshake headers + content)
+ */
+int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    const size_t hs_len = ssl->out_msglen - 4;
+    const unsigned char hs_type = ssl->out_msg[0];
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) );
+
+    /*
+     * Sanity checks
+     */
+    if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE          &&
+        ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+    {
+        /* In SSLv3, the client might send a NoCertificate alert. */
+#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
+        if( ! ( ssl->minor_ver      == MBEDTLS_SSL_MINOR_VERSION_0 &&
+                ssl->out_msgtype    == MBEDTLS_SSL_MSG_ALERT       &&
+                ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) )
+#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+    }
+
+    /* Whenever we send anything different from a
+     * HelloRequest we should be in a handshake - double check. */
+    if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+            hs_type          == MBEDTLS_SSL_HS_HELLO_REQUEST ) &&
+        ssl->handshake == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->handshake != NULL &&
+        ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+#endif
+
+    /* Double-check that we did not exceed the bounds
+     * of the outgoing record buffer.
+     * This should never fail as the various message
+     * writing functions must obey the bounds of the
+     * outgoing record buffer, but better be safe.
+     *
+     * Note: We deliberately do not check for the MTU or MFL here.
+     */
+    if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: "
+                                    "size %u, maximum %u",
+                                    (unsigned) ssl->out_msglen,
+                                    (unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    /*
+     * Fill handshake headers
+     */
+    if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        ssl->out_msg[1] = (unsigned char)( hs_len >> 16 );
+        ssl->out_msg[2] = (unsigned char)( hs_len >>  8 );
+        ssl->out_msg[3] = (unsigned char)( hs_len       );
+
+        /*
+         * DTLS has additional fields in the Handshake layer,
+         * between the length field and the actual payload:
+         *      uint16 message_seq;
+         *      uint24 fragment_offset;
+         *      uint24 fragment_length;
+         */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        {
+            /* Make room for the additional DTLS fields */
+            if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: "
+                              "size %u, maximum %u",
+                               (unsigned) ( hs_len ),
+                               (unsigned) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) );
+                return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+            }
+
+            memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len );
+            ssl->out_msglen += 8;
+
+            /* Write message_seq and update it, except for HelloRequest */
+            if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
+            {
+                ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF;
+                ssl->out_msg[5] = ( ssl->handshake->out_msg_seq      ) & 0xFF;
+                ++( ssl->handshake->out_msg_seq );
+            }
+            else
+            {
+                ssl->out_msg[4] = 0;
+                ssl->out_msg[5] = 0;
+            }
+
+            /* Handshake hashes are computed without fragmentation,
+             * so set frag_offset = 0 and frag_len = hs_len for now */
+            memset( ssl->out_msg + 6, 0x00, 3 );
+            memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
+        }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+        /* Update running hashes of handshake messages seen */
+        if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
+            ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
+    }
+
+    /* Either send now, or just save to be sent (and resent) later */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+            hs_type          == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
+    {
+        if( ( ret = ssl_flight_append( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret );
+            return( ret );
+        }
+    }
+    else
+#endif
+    {
+        if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
+            return( ret );
+        }
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) );
+
+    return( 0 );
+}
+
+/*
+ * Record layer functions
+ */
+
+/*
+ * Write current record.
+ *
+ * Uses:
+ *  - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
+ *  - ssl->out_msglen: length of the record content (excl headers)
+ *  - ssl->out_msg: record content
+ */
+int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
+{
+    int ret, done = 0;
+    size_t len = ssl->out_msglen;
+    uint8_t flush = force_flush;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    if( ssl->transform_out != NULL &&
+        ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
+    {
+        if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
+            return( ret );
+        }
+
+        len = ssl->out_msglen;
+    }
+#endif /*MBEDTLS_ZLIB_SUPPORT */
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+    if( mbedtls_ssl_hw_record_write != NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) );
+
+        ret = mbedtls_ssl_hw_record_write( ssl );
+        if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+
+        if( ret == 0 )
+            done = 1;
+    }
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+    if( !done )
+    {
+        unsigned i;
+        size_t protected_record_size;
+
+        ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
+        mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
+                           ssl->conf->transport, ssl->out_hdr + 1 );
+
+        memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
+        ssl->out_len[0] = (unsigned char)( len >> 8 );
+        ssl->out_len[1] = (unsigned char)( len      );
+
+        if( ssl->transform_out != NULL )
+        {
+            if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
+                return( ret );
+            }
+
+            len = ssl->out_msglen;
+            ssl->out_len[0] = (unsigned char)( len >> 8 );
+            ssl->out_len[1] = (unsigned char)( len      );
+        }
+
+        protected_record_size = len + mbedtls_ssl_hdr_len( ssl );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+        /* In case of DTLS, double-check that we don't exceed
+         * the remaining space in the datagram. */
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        {
+            ret = ssl_get_remaining_space_in_datagram( ssl );
+            if( ret < 0 )
+                return( ret );
+
+            if( protected_record_size > (size_t) ret )
+            {
+                /* Should never happen */
+                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+            }
+        }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, "
+                                    "version = [%d:%d], msglen = %d",
+                                    ssl->out_hdr[0], ssl->out_hdr[1],
+                                    ssl->out_hdr[2], len ) );
+
+        MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
+                               ssl->out_hdr, protected_record_size );
+
+        ssl->out_left += protected_record_size;
+        ssl->out_hdr  += protected_record_size;
+        ssl_update_out_pointers( ssl, ssl->transform_out );
+
+        for( i = 8; i > ssl_ep_len( ssl ); i-- )
+            if( ++ssl->cur_out_ctr[i - 1] != 0 )
+                break;
+
+        /* The loop goes to its end iff the counter is wrapping */
+        if( i == ssl_ep_len( ssl ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
+            return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+        }
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        flush == SSL_DONT_FORCE_FLUSH )
+    {
+        size_t remaining;
+        ret = ssl_get_remaining_payload_in_datagram( ssl );
+        if( ret < 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram",
+                                   ret );
+            return( ret );
+        }
+
+        remaining = (size_t) ret;
+        if( remaining == 0 )
+        {
+            flush = SSL_FORCE_FLUSH;
+        }
+        else
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) );
+        }
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    if( ( flush == SSL_FORCE_FLUSH ) &&
+        ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
+{
+    if( ssl->in_msglen < ssl->in_hslen ||
+        memcmp( ssl->in_msg + 6, "\0\0\0",        3 ) != 0 ||
+        memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
+    {
+        return( 1 );
+    }
+    return( 0 );
+}
+
+static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl )
+{
+    return( ( ssl->in_msg[9] << 16  ) |
+            ( ssl->in_msg[10] << 8  ) |
+              ssl->in_msg[11] );
+}
+
+static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl )
+{
+    return( ( ssl->in_msg[6] << 16 ) |
+            ( ssl->in_msg[7] << 8  ) |
+              ssl->in_msg[8] );
+}
+
+static int ssl_check_hs_header( mbedtls_ssl_context const *ssl )
+{
+    uint32_t msg_len, frag_off, frag_len;
+
+    msg_len  = ssl_get_hs_total_len( ssl );
+    frag_off = ssl_get_hs_frag_off( ssl );
+    frag_len = ssl_get_hs_frag_len( ssl );
+
+    if( frag_off > msg_len )
+        return( -1 );
+
+    if( frag_len > msg_len - frag_off )
+        return( -1 );
+
+    if( frag_len + 12 > ssl->in_msglen )
+        return( -1 );
+
+    return( 0 );
+}
+
+/*
+ * Mark bits in bitmask (used for DTLS HS reassembly)
+ */
+static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
+{
+    unsigned int start_bits, end_bits;
+
+    start_bits = 8 - ( offset % 8 );
+    if( start_bits != 8 )
+    {
+        size_t first_byte_idx = offset / 8;
+
+        /* Special case */
+        if( len <= start_bits )
+        {
+            for( ; len != 0; len-- )
+                mask[first_byte_idx] |= 1 << ( start_bits - len );
+
+            /* Avoid potential issues with offset or len becoming invalid */
+            return;
+        }
+
+        offset += start_bits; /* Now offset % 8 == 0 */
+        len -= start_bits;
+
+        for( ; start_bits != 0; start_bits-- )
+            mask[first_byte_idx] |= 1 << ( start_bits - 1 );
+    }
+
+    end_bits = len % 8;
+    if( end_bits != 0 )
+    {
+        size_t last_byte_idx = ( offset + len ) / 8;
+
+        len -= end_bits; /* Now len % 8 == 0 */
+
+        for( ; end_bits != 0; end_bits-- )
+            mask[last_byte_idx] |= 1 << ( 8 - end_bits );
+    }
+
+    memset( mask + offset / 8, 0xFF, len / 8 );
+}
+
+/*
+ * Check that bitmask is full
+ */
+static int ssl_bitmask_check( unsigned char *mask, size_t len )
+{
+    size_t i;
+
+    for( i = 0; i < len / 8; i++ )
+        if( mask[i] != 0xFF )
+            return( -1 );
+
+    for( i = 0; i < len % 8; i++ )
+        if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
+            return( -1 );
+
+    return( 0 );
+}
+
+/* msg_len does not include the handshake header */
+static size_t ssl_get_reassembly_buffer_size( size_t msg_len,
+                                              unsigned add_bitmap )
+{
+    size_t alloc_len;
+
+    alloc_len  = 12;                                 /* Handshake header */
+    alloc_len += msg_len;                            /* Content buffer   */
+
+    if( add_bitmap )
+        alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap       */
+
+    return( alloc_len );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl )
+{
+    return( ( ssl->in_msg[1] << 16 ) |
+            ( ssl->in_msg[2] << 8  ) |
+              ssl->in_msg[3] );
+}
+
+int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
+{
+    if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d",
+                            ssl->in_msglen ) );
+        return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+    }
+
+    ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
+                        " %d, type = %d, hslen = %d",
+                        ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        int ret;
+        unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
+
+        if( ssl_check_hs_header( ssl ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) );
+            return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+        }
+
+        if( ssl->handshake != NULL &&
+            ( ( ssl->state   != MBEDTLS_SSL_HANDSHAKE_OVER &&
+                recv_msg_seq != ssl->handshake->in_msg_seq ) ||
+              ( ssl->state  == MBEDTLS_SSL_HANDSHAKE_OVER &&
+                ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) )
+        {
+            if( recv_msg_seq > ssl->handshake->in_msg_seq )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)",
+                                            recv_msg_seq,
+                                            ssl->handshake->in_msg_seq ) );
+                return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+            }
+
+            /* Retransmit only on last message from previous flight, to avoid
+             * too many retransmissions.
+             * Besides, No sane server ever retransmits HelloVerifyRequest */
+            if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
+                ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, "
+                                    "message_seq = %d, start_of_flight = %d",
+                                    recv_msg_seq,
+                                    ssl->handshake->in_flight_start_seq ) );
+
+                if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
+                {
+                    MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
+                    return( ret );
+                }
+            }
+            else
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: "
+                                    "message_seq = %d, expected = %d",
+                                    recv_msg_seq,
+                                    ssl->handshake->in_msg_seq ) );
+            }
+
+            return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
+        }
+        /* Wait until message completion to increment in_msg_seq */
+
+        /* Message reassembly is handled alongside buffering of future
+         * messages; the commonality is that both handshake fragments and
+         * future messages cannot be forwarded immediately to the
+         * handshake logic layer. */
+        if( ssl_hs_is_proper_fragment( ssl ) == 1 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) );
+            return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+        }
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+    /* With TLS we don't handle fragmentation (for now) */
+    if( ssl->in_msglen < ssl->in_hslen )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+    }
+
+    return( 0 );
+}
+
+void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl )
+{
+    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+    if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL )
+    {
+        ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
+    }
+
+    /* Handshake message is complete, increment counter */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->handshake != NULL )
+    {
+        unsigned offset;
+        mbedtls_ssl_hs_buffer *hs_buf;
+
+        /* Increment handshake sequence number */
+        hs->in_msg_seq++;
+
+        /*
+         * Clear up handshake buffering and reassembly structure.
+         */
+
+        /* Free first entry */
+        ssl_buffering_free_slot( ssl, 0 );
+
+        /* Shift all other entries */
+        for( offset = 0, hs_buf = &hs->buffering.hs[0];
+             offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
+             offset++, hs_buf++ )
+        {
+            *hs_buf = *(hs_buf + 1);
+        }
+
+        /* Create a fresh last entry */
+        memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
+    }
+#endif
+}
+
+/*
+ * DTLS anti-replay: RFC 6347 4.1.2.6
+ *
+ * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
+ * Bit n is set iff record number in_window_top - n has been seen.
+ *
+ * Usually, in_window_top is the last record number seen and the lsb of
+ * in_window is set. The only exception is the initial state (record number 0
+ * not seen yet).
+ */
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl )
+{
+    ssl->in_window_top = 0;
+    ssl->in_window = 0;
+}
+
+static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
+{
+    return( ( (uint64_t) buf[0] << 40 ) |
+            ( (uint64_t) buf[1] << 32 ) |
+            ( (uint64_t) buf[2] << 24 ) |
+            ( (uint64_t) buf[3] << 16 ) |
+            ( (uint64_t) buf[4] <<  8 ) |
+            ( (uint64_t) buf[5]       ) );
+}
+
+/*
+ * Return 0 if sequence number is acceptable, -1 otherwise
+ */
+int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl )
+{
+    uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
+    uint64_t bit;
+
+    if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
+        return( 0 );
+
+    if( rec_seqnum > ssl->in_window_top )
+        return( 0 );
+
+    bit = ssl->in_window_top - rec_seqnum;
+
+    if( bit >= 64 )
+        return( -1 );
+
+    if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
+        return( -1 );
+
+    return( 0 );
+}
+
+/*
+ * Update replay window on new validated record
+ */
+void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
+{
+    uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
+
+    if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
+        return;
+
+    if( rec_seqnum > ssl->in_window_top )
+    {
+        /* Update window_top and the contents of the window */
+        uint64_t shift = rec_seqnum - ssl->in_window_top;
+
+        if( shift >= 64 )
+            ssl->in_window = 1;
+        else
+        {
+            ssl->in_window <<= shift;
+            ssl->in_window |= 1;
+        }
+
+        ssl->in_window_top = rec_seqnum;
+    }
+    else
+    {
+        /* Mark that number as seen in the current window */
+        uint64_t bit = ssl->in_window_top - rec_seqnum;
+
+        if( bit < 64 ) /* Always true, but be extra sure */
+            ssl->in_window |= (uint64_t) 1 << bit;
+    }
+}
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
+
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+/* Forward declaration */
+static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
+
+/*
+ * Without any SSL context, check if a datagram looks like a ClientHello with
+ * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
+ * Both input and output include full DTLS headers.
+ *
+ * - if cookie is valid, return 0
+ * - if ClientHello looks superficially valid but cookie is not,
+ *   fill obuf and set olen, then
+ *   return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
+ * - otherwise return a specific error code
+ */
+static int ssl_check_dtls_clihlo_cookie(
+                           mbedtls_ssl_cookie_write_t *f_cookie_write,
+                           mbedtls_ssl_cookie_check_t *f_cookie_check,
+                           void *p_cookie,
+                           const unsigned char *cli_id, size_t cli_id_len,
+                           const unsigned char *in, size_t in_len,
+                           unsigned char *obuf, size_t buf_len, size_t *olen )
+{
+    size_t sid_len, cookie_len;
+    unsigned char *p;
+
+    if( f_cookie_write == NULL || f_cookie_check == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    /*
+     * Structure of ClientHello with record and handshake headers,
+     * and expected values. We don't need to check a lot, more checks will be
+     * done when actually parsing the ClientHello - skipping those checks
+     * avoids code duplication and does not make cookie forging any easier.
+     *
+     *  0-0  ContentType type;                  copied, must be handshake
+     *  1-2  ProtocolVersion version;           copied
+     *  3-4  uint16 epoch;                      copied, must be 0
+     *  5-10 uint48 sequence_number;            copied
+     * 11-12 uint16 length;                     (ignored)
+     *
+     * 13-13 HandshakeType msg_type;            (ignored)
+     * 14-16 uint24 length;                     (ignored)
+     * 17-18 uint16 message_seq;                copied
+     * 19-21 uint24 fragment_offset;            copied, must be 0
+     * 22-24 uint24 fragment_length;            (ignored)
+     *
+     * 25-26 ProtocolVersion client_version;    (ignored)
+     * 27-58 Random random;                     (ignored)
+     * 59-xx SessionID session_id;              1 byte len + sid_len content
+     * 60+   opaque cookie<0..2^8-1>;           1 byte len + content
+     *       ...
+     *
+     * Minimum length is 61 bytes.
+     */
+    if( in_len < 61 ||
+        in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
+        in[3] != 0 || in[4] != 0 ||
+        in[19] != 0 || in[20] != 0 || in[21] != 0 )
+    {
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+    }
+
+    sid_len = in[59];
+    if( sid_len > in_len - 61 )
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+
+    cookie_len = in[60 + sid_len];
+    if( cookie_len > in_len - 60 )
+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+
+    if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
+                        cli_id, cli_id_len ) == 0 )
+    {
+        /* Valid cookie */
+        return( 0 );
+    }
+
+    /*
+     * If we get here, we've got an invalid cookie, let's prepare HVR.
+     *
+     *  0-0  ContentType type;                  copied
+     *  1-2  ProtocolVersion version;           copied
+     *  3-4  uint16 epoch;                      copied
+     *  5-10 uint48 sequence_number;            copied
+     * 11-12 uint16 length;                     olen - 13
+     *
+     * 13-13 HandshakeType msg_type;            hello_verify_request
+     * 14-16 uint24 length;                     olen - 25
+     * 17-18 uint16 message_seq;                copied
+     * 19-21 uint24 fragment_offset;            copied
+     * 22-24 uint24 fragment_length;            olen - 25
+     *
+     * 25-26 ProtocolVersion server_version;    0xfe 0xff
+     * 27-27 opaque cookie<0..2^8-1>;           cookie_len = olen - 27, cookie
+     *
+     * Minimum length is 28.
+     */
+    if( buf_len < 28 )
+        return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+    /* Copy most fields and adapt others */
+    memcpy( obuf, in, 25 );
+    obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
+    obuf[25] = 0xfe;
+    obuf[26] = 0xff;
+
+    /* Generate and write actual cookie */
+    p = obuf + 28;
+    if( f_cookie_write( p_cookie,
+                        &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
+    {
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    *olen = p - obuf;
+
+    /* Go back and fill length fields */
+    obuf[27] = (unsigned char)( *olen - 28 );
+
+    obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 );
+    obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >>  8 );
+    obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 )       );
+
+    obuf[11] = (unsigned char)( ( *olen - 13 ) >>  8 );
+    obuf[12] = (unsigned char)( ( *olen - 13 )       );
+
+    return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
+}
+
+/*
+ * Handle possible client reconnect with the same UDP quadruplet
+ * (RFC 6347 Section 4.2.8).
+ *
+ * Called by ssl_parse_record_header() in case we receive an epoch 0 record
+ * that looks like a ClientHello.
+ *
+ * - if the input looks like a ClientHello without cookies,
+ *   send back HelloVerifyRequest, then
+ *   return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
+ * - if the input looks like a ClientHello with a valid cookie,
+ *   reset the session of the current context, and
+ *   return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
+ * - if anything goes wrong, return a specific error code
+ *
+ * mbedtls_ssl_read_record() will ignore the record if anything else than
+ * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function
+ * cannot not return 0.
+ */
+static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    size_t len;
+
+    ret = ssl_check_dtls_clihlo_cookie(
+            ssl->conf->f_cookie_write,
+            ssl->conf->f_cookie_check,
+            ssl->conf->p_cookie,
+            ssl->cli_id, ssl->cli_id_len,
+            ssl->in_buf, ssl->in_left,
+            ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len );
+
+    MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
+
+    if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
+    {
+        /* Don't check write errors as we can't do anything here.
+         * If the error is permanent we'll catch it later,
+         * if it's not, then hopefully it'll work next time. */
+        (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+
+        return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
+    }
+
+    if( ret == 0 )
+    {
+        /* Got a valid cookie, partially reset context */
+        if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
+            return( ret );
+        }
+
+        return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT );
+    }
+
+    return( ret );
+}
+#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
+
+/*
+ * ContentType type;
+ * ProtocolVersion version;
+ * uint16 epoch;            // DTLS only
+ * uint48 sequence_number;  // DTLS only
+ * uint16 length;
+ *
+ * Return 0 if header looks sane (and, for DTLS, the record is expected)
+ * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
+ * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
+ *
+ * With DTLS, mbedtls_ssl_read_record() will:
+ * 1. proceed with the record if this function returns 0
+ * 2. drop only the current record if this function returns UNEXPECTED_RECORD
+ * 3. return CLIENT_RECONNECT if this function return that value
+ * 4. drop the whole datagram if this function returns anything else.
+ * Point 2 is needed when the peer is resending, and we have already received
+ * the first record from a datagram but are still waiting for the others.
+ */
+static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
+{
+    int major_ver, minor_ver;
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) );
+
+    ssl->in_msgtype =  ssl->in_hdr[0];
+    ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
+    mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, "
+                        "version = [%d:%d], msglen = %d",
+                        ssl->in_msgtype,
+                        major_ver, minor_ver, ssl->in_msglen ) );
+
+    /* Check record type */
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
+        ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT &&
+        ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
+        ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+        /* Silently ignore invalid DTLS records as recommended by RFC 6347
+         * Section 4.1.2.7 */
+        if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                    MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+
+        return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+    }
+
+    /* Check version */
+    if( major_ver != ssl->major_ver )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
+        return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+    }
+
+    if( minor_ver > ssl->conf->max_minor_ver )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
+        return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+    }
+
+    /* Check length against the size of our buffer */
+    if( ssl->in_msglen > MBEDTLS_SSL_IN_BUFFER_LEN
+                         - (size_t)( ssl->in_msg - ssl->in_buf ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
+        return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+    }
+
+    /*
+     * DTLS-related tests.
+     * Check epoch before checking length constraint because
+     * the latter varies with the epoch. E.g., if a ChangeCipherSpec
+     * message gets duplicated before the corresponding Finished message,
+     * the second ChangeCipherSpec should be discarded because it belongs
+     * to an old epoch, but not because its length is shorter than
+     * the minimum record length for packets using the new record transform.
+     * Note that these two kinds of failures are handled differently,
+     * as an unexpected record is silently skipped but an invalid
+     * record leads to the entire datagram being dropped.
+     */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
+
+        /* Check epoch (and sequence number) with DTLS */
+        if( rec_epoch != ssl->in_epoch )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
+                                        "expected %d, received %d",
+                                        ssl->in_epoch, rec_epoch ) );
+
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+            /*
+             * Check for an epoch 0 ClientHello. We can't use in_msg here to
+             * access the first byte of record content (handshake type), as we
+             * have an active transform (possibly iv_len != 0), so use the
+             * fact that the record header len is 13 instead.
+             */
+            if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+                ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
+                rec_epoch == 0 &&
+                ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+                ssl->in_left > 13 &&
+                ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
+                                            "from the same port" ) );
+                return( ssl_handle_possible_reconnect( ssl ) );
+            }
+            else
+#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
+            {
+                /* Consider buffering the record. */
+                if( rec_epoch == (unsigned int) ssl->in_epoch + 1 )
+                {
+                    MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) );
+                    return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+                }
+
+                return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
+            }
+        }
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+        /* Replay detection only works for the current epoch */
+        if( rec_epoch == ssl->in_epoch &&
+            mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
+            return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
+        }
+#endif
+
+        /* Drop unexpected ApplicationData records,
+         * except at the beginning of renegotiations */
+        if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
+            ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+            && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
+                   ssl->state == MBEDTLS_SSL_SERVER_HELLO )
+#endif
+            )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
+            return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
+        }
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+
+    /* Check length against bounds of the current transform and version */
+    if( ssl->transform_in == NULL )
+    {
+        if( ssl->in_msglen < 1 ||
+            ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
+            return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+        }
+    }
+    else
+    {
+        if( ssl->in_msglen < ssl->transform_in->minlen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
+            return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+        }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+        if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
+            ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_IN_CONTENT_LEN )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
+            return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+        }
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+        /*
+         * TLS encrypted messages can have up to 256 bytes of padding
+         */
+        if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 &&
+            ssl->in_msglen > ssl->transform_in->minlen +
+                             MBEDTLS_SSL_IN_CONTENT_LEN + 256 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
+            return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+        }
+#endif
+    }
+
+    return( 0 );
+}
+
+/*
+ * If applicable, decrypt (and decompress) record content
+ */
+static int ssl_prepare_record_content( mbedtls_ssl_context *ssl )
+{
+    int ret, done = 0;
+
+    MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network",
+                   ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen );
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+    if( mbedtls_ssl_hw_record_read != NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) );
+
+        ret = mbedtls_ssl_hw_record_read( ssl );
+        if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+
+        if( ret == 0 )
+            done = 1;
+    }
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+    if( !done && ssl->transform_in != NULL )
+    {
+        if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
+            return( ret );
+        }
+
+        MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt",
+                       ssl->in_msg, ssl->in_msglen );
+
+        if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
+            return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+        }
+    }
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    if( ssl->transform_in != NULL &&
+        ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
+    {
+        if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
+            return( ret );
+        }
+    }
+#endif /* MBEDTLS_ZLIB_SUPPORT */
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        mbedtls_ssl_dtls_replay_update( ssl );
+    }
+#endif
+
+    return( 0 );
+}
+
+static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl );
+
+/*
+ * Read a record.
+ *
+ * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
+ * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
+ *
+ */
+
+/* Helper functions for mbedtls_ssl_read_record(). */
+static int ssl_consume_current_message( mbedtls_ssl_context *ssl );
+static int ssl_get_next_record( mbedtls_ssl_context *ssl );
+static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
+                             unsigned update_hs_digest )
+{
+    int ret;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
+
+    if( ssl->keep_current_message == 0 )
+    {
+        do {
+
+            ret = ssl_consume_current_message( ssl );
+            if( ret != 0 )
+                return( ret );
+
+            if( ssl_record_is_in_progress( ssl ) == 0 )
+            {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+                int have_buffered = 0;
+
+                /* We only check for buffered messages if the
+                 * current datagram is fully consumed. */
+                if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+                    ssl_next_record_is_in_datagram( ssl ) == 0 )
+                {
+                    if( ssl_load_buffered_message( ssl ) == 0 )
+                        have_buffered = 1;
+                }
+
+                if( have_buffered == 0 )
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+                {
+                    ret = ssl_get_next_record( ssl );
+                    if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING )
+                        continue;
+
+                    if( ret != 0 )
+                    {
+                        MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret );
+                        return( ret );
+                    }
+                }
+            }
+
+            ret = mbedtls_ssl_handle_message_type( ssl );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+            if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
+            {
+                /* Buffer future message */
+                ret = ssl_buffer_message( ssl );
+                if( ret != 0 )
+                    return( ret );
+
+                ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
+            }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+        } while( MBEDTLS_ERR_SSL_NON_FATAL           == ret  ||
+                 MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret );
+
+        if( 0 != ret )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret );
+            return( ret );
+        }
+
+        if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+            update_hs_digest == 1 )
+        {
+            mbedtls_ssl_update_handshake_status( ssl );
+        }
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) );
+        ssl->keep_current_message = 0;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
+{
+    if( ssl->in_left > ssl->next_record_offset )
+        return( 1 );
+
+    return( 0 );
+}
+
+static int ssl_load_buffered_message( mbedtls_ssl_context *ssl )
+{
+    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+    mbedtls_ssl_hs_buffer * hs_buf;
+    int ret = 0;
+
+    if( hs == NULL )
+        return( -1 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) );
+
+    if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
+        ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
+    {
+        /* Check if we have seen a ChangeCipherSpec before.
+         * If yes, synthesize a CCS record. */
+        if( !hs->buffering.seen_ccs )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) );
+            ret = -1;
+            goto exit;
+        }
+
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) );
+        ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
+        ssl->in_msglen = 1;
+        ssl->in_msg[0] = 1;
+
+        /* As long as they are equal, the exact value doesn't matter. */
+        ssl->in_left            = 0;
+        ssl->next_record_offset = 0;
+
+        hs->buffering.seen_ccs = 0;
+        goto exit;
+    }
+
+#if defined(MBEDTLS_DEBUG_C)
+    /* Debug only */
+    {
+        unsigned offset;
+        for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
+        {
+            hs_buf = &hs->buffering.hs[offset];
+            if( hs_buf->is_valid == 1 )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.",
+                            hs->in_msg_seq + offset,
+                            hs_buf->is_complete ? "fully" : "partially" ) );
+            }
+        }
+    }
+#endif /* MBEDTLS_DEBUG_C */
+
+    /* Check if we have buffered and/or fully reassembled the
+     * next handshake message. */
+    hs_buf = &hs->buffering.hs[0];
+    if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) )
+    {
+        /* Synthesize a record containing the buffered HS message. */
+        size_t msg_len = ( hs_buf->data[1] << 16 ) |
+                         ( hs_buf->data[2] << 8  ) |
+                           hs_buf->data[3];
+
+        /* Double-check that we haven't accidentally buffered
+         * a message that doesn't fit into the input buffer. */
+        if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) );
+        MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)",
+                               hs_buf->data, msg_len + 12 );
+
+        ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+        ssl->in_hslen   = msg_len + 12;
+        ssl->in_msglen  = msg_len + 12;
+        memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen );
+
+        ret = 0;
+        goto exit;
+    }
+    else
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered",
+                                    hs->in_msg_seq ) );
+    }
+
+    ret = -1;
+
+exit:
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) );
+    return( ret );
+}
+
+static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
+                                  size_t desired )
+{
+    int offset;
+    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available",
+                                (unsigned) desired ) );
+
+    /* Get rid of future records epoch first, if such exist. */
+    ssl_free_buffered_record( ssl );
+
+    /* Check if we have enough space available now. */
+    if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+                     hs->buffering.total_bytes_buffered ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) );
+        return( 0 );
+    }
+
+    /* We don't have enough space to buffer the next expected handshake
+     * message. Remove buffers used for future messages to gain space,
+     * starting with the most distant one. */
+    for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
+         offset >= 0; offset-- )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message",
+                                    offset ) );
+
+        ssl_buffering_free_slot( ssl, (uint8_t) offset );
+
+        /* Check if we have enough space available now. */
+        if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+                         hs->buffering.total_bytes_buffered ) )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) );
+            return( 0 );
+        }
+    }
+
+    return( -1 );
+}
+
+static int ssl_buffer_message( mbedtls_ssl_context *ssl )
+{
+    int ret = 0;
+    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+    if( hs == NULL )
+        return( 0 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) );
+
+    switch( ssl->in_msgtype )
+    {
+        case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) );
+
+            hs->buffering.seen_ccs = 1;
+            break;
+
+        case MBEDTLS_SSL_MSG_HANDSHAKE:
+        {
+            unsigned recv_msg_seq_offset;
+            unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
+            mbedtls_ssl_hs_buffer *hs_buf;
+            size_t msg_len = ssl->in_hslen - 12;
+
+            /* We should never receive an old handshake
+             * message - double-check nonetheless. */
+            if( recv_msg_seq < ssl->handshake->in_msg_seq )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+            }
+
+            recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
+            if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS )
+            {
+                /* Silently ignore -- message too far in the future */
+                MBEDTLS_SSL_DEBUG_MSG( 2,
+                 ( "Ignore future HS message with sequence number %u, "
+                   "buffering window %u - %u",
+                   recv_msg_seq, ssl->handshake->in_msg_seq,
+                   ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) );
+
+                goto exit;
+            }
+
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ",
+                                        recv_msg_seq, recv_msg_seq_offset ) );
+
+            hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ];
+
+            /* Check if the buffering for this seq nr has already commenced. */
+            if( !hs_buf->is_valid )
+            {
+                size_t reassembly_buf_sz;
+
+                hs_buf->is_fragmented =
+                    ( ssl_hs_is_proper_fragment( ssl ) == 1 );
+
+                /* We copy the message back into the input buffer
+                 * after reassembly, so check that it's not too large.
+                 * This is an implementation-specific limitation
+                 * and not one from the standard, hence it is not
+                 * checked in ssl_check_hs_header(). */
+                if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
+                {
+                    /* Ignore message */
+                    goto exit;
+                }
+
+                /* Check if we have enough space to buffer the message. */
+                if( hs->buffering.total_bytes_buffered >
+                    MBEDTLS_SSL_DTLS_MAX_BUFFERING )
+                {
+                    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+                }
+
+                reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len,
+                                                       hs_buf->is_fragmented );
+
+                if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+                                          hs->buffering.total_bytes_buffered ) )
+                {
+                    if( recv_msg_seq_offset > 0 )
+                    {
+                        /* If we can't buffer a future message because
+                         * of space limitations -- ignore. */
+                        MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n",
+                             (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+                             (unsigned) hs->buffering.total_bytes_buffered ) );
+                        goto exit;
+                    }
+                    else
+                    {
+                        MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- attempt to make space by freeing buffered future messages\n",
+                             (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+                             (unsigned) hs->buffering.total_bytes_buffered ) );
+                    }
+
+                    if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 )
+                    {
+                        MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %u (%u with bitmap) would exceed the compile-time limit %u (already %u bytes buffered) -- fail\n",
+                             (unsigned) msg_len,
+                             (unsigned) reassembly_buf_sz,
+                             MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+                             (unsigned) hs->buffering.total_bytes_buffered ) );
+                        ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
+                        goto exit;
+                    }
+                }
+
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d",
+                                            msg_len ) );
+
+                hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz );
+                if( hs_buf->data == NULL )
+                {
+                    ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+                    goto exit;
+                }
+                hs_buf->data_len = reassembly_buf_sz;
+
+                /* Prepare final header: copy msg_type, length and message_seq,
+                 * then add standardised fragment_offset and fragment_length */
+                memcpy( hs_buf->data, ssl->in_msg, 6 );
+                memset( hs_buf->data + 6, 0, 3 );
+                memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 );
+
+                hs_buf->is_valid = 1;
+
+                hs->buffering.total_bytes_buffered += reassembly_buf_sz;
+            }
+            else
+            {
+                /* Make sure msg_type and length are consistent */
+                if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 )
+                {
+                    MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) );
+                    /* Ignore */
+                    goto exit;
+                }
+            }
+
+            if( !hs_buf->is_complete )
+            {
+                size_t frag_len, frag_off;
+                unsigned char * const msg = hs_buf->data + 12;
+
+                /*
+                 * Check and copy current fragment
+                 */
+
+                /* Validation of header fields already done in
+                 * mbedtls_ssl_prepare_handshake_record(). */
+                frag_off = ssl_get_hs_frag_off( ssl );
+                frag_len = ssl_get_hs_frag_len( ssl );
+
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d",
+                                            frag_off, frag_len ) );
+                memcpy( msg + frag_off, ssl->in_msg + 12, frag_len );
+
+                if( hs_buf->is_fragmented )
+                {
+                    unsigned char * const bitmask = msg + msg_len;
+                    ssl_bitmask_set( bitmask, frag_off, frag_len );
+                    hs_buf->is_complete = ( ssl_bitmask_check( bitmask,
+                                                               msg_len ) == 0 );
+                }
+                else
+                {
+                    hs_buf->is_complete = 1;
+                }
+
+                MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete",
+                                   hs_buf->is_complete ? "" : "not yet " ) );
+            }
+
+            break;
+        }
+
+        default:
+            /* We don't buffer other types of messages. */
+            break;
+    }
+
+exit:
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) );
+    return( ret );
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
+{
+    /*
+     * Consume last content-layer message and potentially
+     * update in_msglen which keeps track of the contents'
+     * consumption state.
+     *
+     * (1) Handshake messages:
+     *     Remove last handshake message, move content
+     *     and adapt in_msglen.
+     *
+     * (2) Alert messages:
+     *     Consume whole record content, in_msglen = 0.
+     *
+     * (3) Change cipher spec:
+     *     Consume whole record content, in_msglen = 0.
+     *
+     * (4) Application data:
+     *     Don't do anything - the record layer provides
+     *     the application data as a stream transport
+     *     and consumes through mbedtls_ssl_read only.
+     *
+     */
+
+    /* Case (1): Handshake messages */
+    if( ssl->in_hslen != 0 )
+    {
+        /* Hard assertion to be sure that no application data
+         * is in flight, as corrupting ssl->in_msglen during
+         * ssl->in_offt != NULL is fatal. */
+        if( ssl->in_offt != NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+        }
+
+        /*
+         * Get next Handshake message in the current record
+         */
+
+        /* Notes:
+         * (1) in_hslen is not necessarily the size of the
+         *     current handshake content: If DTLS handshake
+         *     fragmentation is used, that's the fragment
+         *     size instead. Using the total handshake message
+         *     size here is faulty and should be changed at
+         *     some point.
+         * (2) While it doesn't seem to cause problems, one
+         *     has to be very careful not to assume that in_hslen
+         *     is always <= in_msglen in a sensible communication.
+         *     Again, it's wrong for DTLS handshake fragmentation.
+         *     The following check is therefore mandatory, and
+         *     should not be treated as a silently corrected assertion.
+         *     Additionally, ssl->in_hslen might be arbitrarily out of
+         *     bounds after handling a DTLS message with an unexpected
+         *     sequence number, see mbedtls_ssl_prepare_handshake_record.
+         */
+        if( ssl->in_hslen < ssl->in_msglen )
+        {
+            ssl->in_msglen -= ssl->in_hslen;
+            memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
+                     ssl->in_msglen );
+
+            MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
+                                   ssl->in_msg, ssl->in_msglen );
+        }
+        else
+        {
+            ssl->in_msglen = 0;
+        }
+
+        ssl->in_hslen   = 0;
+    }
+    /* Case (4): Application data */
+    else if( ssl->in_offt != NULL )
+    {
+        return( 0 );
+    }
+    /* Everything else (CCS & Alerts) */
+    else
+    {
+        ssl->in_msglen = 0;
+    }
+
+    return( 0 );
+}
+
+static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl )
+{
+    if( ssl->in_msglen > 0 )
+        return( 1 );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+static void ssl_free_buffered_record( mbedtls_ssl_context *ssl )
+{
+    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+    if( hs == NULL )
+        return;
+
+    if( hs->buffering.future_record.data != NULL )
+    {
+        hs->buffering.total_bytes_buffered -=
+            hs->buffering.future_record.len;
+
+        mbedtls_free( hs->buffering.future_record.data );
+        hs->buffering.future_record.data = NULL;
+    }
+}
+
+static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
+{
+    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+    unsigned char * rec;
+    size_t rec_len;
+    unsigned rec_epoch;
+
+    if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        return( 0 );
+
+    if( hs == NULL )
+        return( 0 );
+
+    rec       = hs->buffering.future_record.data;
+    rec_len   = hs->buffering.future_record.len;
+    rec_epoch = hs->buffering.future_record.epoch;
+
+    if( rec == NULL )
+        return( 0 );
+
+    /* Only consider loading future records if the
+     * input buffer is empty. */
+    if( ssl_next_record_is_in_datagram( ssl ) == 1 )
+        return( 0 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) );
+
+    if( rec_epoch != ssl->in_epoch )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) );
+        goto exit;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) );
+
+    /* Double-check that the record is not too large */
+    if( rec_len > MBEDTLS_SSL_IN_BUFFER_LEN -
+        (size_t)( ssl->in_hdr - ssl->in_buf ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    memcpy( ssl->in_hdr, rec, rec_len );
+    ssl->in_left = rec_len;
+    ssl->next_record_offset = 0;
+
+    ssl_free_buffered_record( ssl );
+
+exit:
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) );
+    return( 0 );
+}
+
+static int ssl_buffer_future_record( mbedtls_ssl_context *ssl )
+{
+    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+    size_t const rec_hdr_len = 13;
+    size_t const total_buf_sz = rec_hdr_len + ssl->in_msglen;
+
+    /* Don't buffer future records outside handshakes. */
+    if( hs == NULL )
+        return( 0 );
+
+    /* Only buffer handshake records (we are only interested
+     * in Finished messages). */
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+        return( 0 );
+
+    /* Don't buffer more than one future epoch record. */
+    if( hs->buffering.future_record.data != NULL )
+        return( 0 );
+
+    /* Don't buffer record if there's not enough buffering space remaining. */
+    if( total_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+                         hs->buffering.total_bytes_buffered ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n",
+                        (unsigned) total_buf_sz, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+                        (unsigned) hs->buffering.total_bytes_buffered ) );
+        return( 0 );
+    }
+
+    /* Buffer record */
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u",
+                                ssl->in_epoch + 1 ) );
+    MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", ssl->in_hdr,
+                           rec_hdr_len + ssl->in_msglen );
+
+    /* ssl_parse_record_header() only considers records
+     * of the next epoch as candidates for buffering. */
+    hs->buffering.future_record.epoch = ssl->in_epoch + 1;
+    hs->buffering.future_record.len   = total_buf_sz;
+
+    hs->buffering.future_record.data =
+        mbedtls_calloc( 1, hs->buffering.future_record.len );
+    if( hs->buffering.future_record.data == NULL )
+    {
+        /* If we run out of RAM trying to buffer a
+         * record from the next epoch, just ignore. */
+        return( 0 );
+    }
+
+    memcpy( hs->buffering.future_record.data, ssl->in_hdr, total_buf_sz );
+
+    hs->buffering.total_bytes_buffered += total_buf_sz;
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+static int ssl_get_next_record( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    /* We might have buffered a future record; if so,
+     * and if the epoch matches now, load it.
+     * On success, this call will set ssl->in_left to
+     * the length of the buffered record, so that
+     * the calls to ssl_fetch_input() below will
+     * essentially be no-ops. */
+    ret = ssl_load_buffered_record( ssl );
+    if( ret != 0 )
+        return( ret );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
+        return( ret );
+    }
+
+    if( ( ret = ssl_parse_record_header( ssl ) ) != 0 )
+    {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+            ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT )
+        {
+            if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
+            {
+                ret = ssl_buffer_future_record( ssl );
+                if( ret != 0 )
+                    return( ret );
+
+                /* Fall through to handling of unexpected records */
+                ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
+            }
+
+            if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
+            {
+                /* Skip unexpected record (but not whole datagram) */
+                ssl->next_record_offset = ssl->in_msglen
+                                        + mbedtls_ssl_hdr_len( ssl );
+
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
+                                            "(header)" ) );
+            }
+            else
+            {
+                /* Skip invalid record and the rest of the datagram */
+                ssl->next_record_offset = 0;
+                ssl->in_left = 0;
+
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
+                                            "(header)" ) );
+            }
+
+            /* Get next record */
+            return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
+        }
+#endif
+        return( ret );
+    }
+
+    /*
+     * Read and optionally decrypt the message contents
+     */
+    if( ( ret = mbedtls_ssl_fetch_input( ssl,
+                                 mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
+        return( ret );
+    }
+
+    /* Done reading this record, get ready for the next one */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl );
+        if( ssl->next_record_offset < ssl->in_left )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) );
+        }
+    }
+    else
+#endif
+        ssl->in_left = 0;
+
+    if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 )
+    {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        {
+            /* Silently discard invalid records */
+            if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD ||
+                ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+            {
+                /* Except when waiting for Finished as a bad mac here
+                 * probably means something went wrong in the handshake
+                 * (eg wrong psk used, mitm downgrade attempt, etc.) */
+                if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
+                    ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
+                {
+#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
+                    if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+                    {
+                        mbedtls_ssl_send_alert_message( ssl,
+                                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
+                    }
+#endif
+                    return( ret );
+                }
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+                if( ssl->conf->badmac_limit != 0 &&
+                    ++ssl->badmac_seen >= ssl->conf->badmac_limit )
+                {
+                    MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
+                    return( MBEDTLS_ERR_SSL_INVALID_MAC );
+                }
+#endif
+
+                /* As above, invalid records cause
+                 * dismissal of the whole datagram. */
+
+                ssl->next_record_offset = 0;
+                ssl->in_left = 0;
+
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) );
+                return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
+            }
+
+            return( ret );
+        }
+        else
+#endif
+        {
+            /* Error out (and send alert) on invalid records */
+#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
+            if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+            {
+                mbedtls_ssl_send_alert_message( ssl,
+                        MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                        MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
+            }
+#endif
+            return( ret );
+        }
+    }
+
+    return( 0 );
+}
+
+int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    /*
+     * Handle particular types of records
+     */
+    if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 )
+        {
+            return( ret );
+        }
+    }
+
+    if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+    {
+        if( ssl->in_msglen != 1 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %d",
+                           ssl->in_msglen ) );
+            return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+        }
+
+        if( ssl->in_msg[0] != 1 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x",
+                                        ssl->in_msg[0] ) );
+            return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+        }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+            ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC    &&
+            ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
+        {
+            if( ssl->handshake == NULL )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) );
+                return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
+            }
+
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) );
+            return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+        }
+#endif
+    }
+
+    if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
+    {
+        if( ssl->in_msglen != 2 )
+        {
+            /* Note: Standard allows for more than one 2 byte alert
+               to be packed in a single message, but Mbed TLS doesn't
+               currently support this. */
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %d",
+                           ssl->in_msglen ) );
+            return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+        }
+
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]",
+                       ssl->in_msg[0], ssl->in_msg[1] ) );
+
+        /*
+         * Ignore non-fatal alerts, except close_notify and no_renegotiation
+         */
+        if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
+                           ssl->in_msg[1] ) );
+            return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
+        }
+
+        if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+            ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
+            return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
+        }
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
+        if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+            ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) );
+            /* Will be handled when trying to parse ServerHello */
+            return( 0 );
+        }
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
+        if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
+            ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+            ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+            ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
+            /* Will be handled in mbedtls_ssl_parse_certificate() */
+            return( 0 );
+        }
+#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
+
+        /* Silently ignore: fetch new message */
+        return MBEDTLS_ERR_SSL_NON_FATAL;
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->handshake != NULL &&
+        ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER  )
+    {
+        ssl_handshake_wrapup_free_hs_transform( ssl );
+    }
+#endif
+
+    return( 0 );
+}
+
+int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    if( ( ret = mbedtls_ssl_send_alert_message( ssl,
+                    MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
+                            unsigned char level,
+                            unsigned char message )
+{
+    int ret;
+
+    if( ssl == NULL || ssl->conf == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
+
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
+    ssl->out_msglen = 2;
+    ssl->out_msg[0] = level;
+    ssl->out_msg[1] = message;
+
+    if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+        return( ret );
+    }
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
+
+    return( 0 );
+}
+
+/*
+ * Handshake functions
+ */
+#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)         && \
+    !defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)     && \
+    !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)     && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)    && \
+    !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+/* No certificate support -> dummy functions */
+int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
+{
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
+
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+
+int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
+{
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
+
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+}
+
+#else
+/* Some certificate support -> implement write and parse */
+
+int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    size_t i, n;
+    const mbedtls_x509_crt *crt;
+    const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
+
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+#if defined(MBEDTLS_SSL_CLI_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+    {
+        if( ssl->client_auth == 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
+            ssl->state++;
+            return( 0 );
+        }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+        /*
+         * If using SSLv3 and got no cert, send an Alert message
+         * (otherwise an empty Certificate message will be sent).
+         */
+        if( mbedtls_ssl_own_cert( ssl )  == NULL &&
+            ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+        {
+            ssl->out_msglen  = 2;
+            ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
+            ssl->out_msg[0]  = MBEDTLS_SSL_ALERT_LEVEL_WARNING;
+            ssl->out_msg[1]  = MBEDTLS_SSL_ALERT_MSG_NO_CERT;
+
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) );
+            goto write_msg;
+        }
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+    }
+#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_SRV_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        if( mbedtls_ssl_own_cert( ssl ) == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no certificate to send" ) );
+            return( MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED );
+        }
+    }
+#endif
+
+    MBEDTLS_SSL_DEBUG_CRT( 3, "own certificate", mbedtls_ssl_own_cert( ssl ) );
+
+    /*
+     *     0  .  0    handshake type
+     *     1  .  3    handshake length
+     *     4  .  6    length of all certs
+     *     7  .  9    length of cert. 1
+     *    10  . n-1   peer certificate
+     *     n  . n+2   length of cert. 2
+     *    n+3 . ...   upper level cert, etc.
+     */
+    i = 7;
+    crt = mbedtls_ssl_own_cert( ssl );
+
+    while( crt != NULL )
+    {
+        n = crt->raw.len;
+        if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d",
+                           i + 3 + n, MBEDTLS_SSL_OUT_CONTENT_LEN ) );
+            return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE );
+        }
+
+        ssl->out_msg[i    ] = (unsigned char)( n >> 16 );
+        ssl->out_msg[i + 1] = (unsigned char)( n >>  8 );
+        ssl->out_msg[i + 2] = (unsigned char)( n       );
+
+        i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
+        i += n; crt = crt->next;
+    }
+
+    ssl->out_msg[4]  = (unsigned char)( ( i - 7 ) >> 16 );
+    ssl->out_msg[5]  = (unsigned char)( ( i - 7 ) >>  8 );
+    ssl->out_msg[6]  = (unsigned char)( ( i - 7 )       );
+
+    ssl->out_msglen  = i;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE;
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
+write_msg:
+#endif
+
+    ssl->state++;
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate" ) );
+
+    return( ret );
+}
+
+/*
+ * Once the certificate message is read, parse it into a cert chain and
+ * perform basic checks, but leave actual verification to the caller
+ */
+static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    size_t i, n;
+    uint8_t alert;
+
+#if defined(MBEDTLS_SSL_SRV_C)
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    /*
+     * Check if the client sent an empty certificate
+     */
+    if( ssl->conf->endpoint  == MBEDTLS_SSL_IS_SERVER &&
+        ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        if( ssl->in_msglen  == 2                        &&
+            ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT            &&
+            ssl->in_msg[0]  == MBEDTLS_SSL_ALERT_LEVEL_WARNING  &&
+            ssl->in_msg[1]  == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
+
+            /* The client was asked for a certificate but didn't send
+               one. The client should know what's going on, so we
+               don't send an alert. */
+            ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
+            return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
+        }
+    }
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( ssl->conf->endpoint  == MBEDTLS_SSL_IS_SERVER &&
+        ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
+    {
+        if( ssl->in_hslen   == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
+            ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE    &&
+            ssl->in_msg[0]  == MBEDTLS_SSL_HS_CERTIFICATE   &&
+            memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
+
+            /* The client was asked for a certificate but didn't send
+               one. The client should know what's going on, so we
+               don't send an alert. */
+            ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
+            return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
+        }
+    }
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+          MBEDTLS_SSL_PROTO_TLS1_2 */
+#endif /* MBEDTLS_SSL_SRV_C */
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE ||
+        ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+    }
+
+    i = mbedtls_ssl_hs_hdr_len( ssl );
+
+    /*
+     * Same message structure as in mbedtls_ssl_write_certificate()
+     */
+    n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2];
+
+    if( ssl->in_msg[i] != 0 ||
+        ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+    }
+
+    /* In case we tried to reuse a session but it failed */
+    if( ssl->session_negotiate->peer_cert != NULL )
+    {
+        mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert );
+        mbedtls_free( ssl->session_negotiate->peer_cert );
+    }
+
+    if( ( ssl->session_negotiate->peer_cert = mbedtls_calloc( 1,
+                    sizeof( mbedtls_x509_crt ) ) ) == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
+                       sizeof( mbedtls_x509_crt ) ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+    }
+
+    mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert );
+
+    i += 3;
+
+    while( i < ssl->in_hslen )
+    {
+        if ( i + 3 > ssl->in_hslen ) {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                           MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        }
+        if( ssl->in_msg[i] != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        }
+
+        n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
+            | (unsigned int) ssl->in_msg[i + 2];
+        i += 3;
+
+        if( n < 128 || i + n > ssl->in_hslen )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        }
+
+        ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert,
+                                  ssl->in_msg + i, n );
+        switch( ret )
+        {
+        case 0: /*ok*/
+        case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
+            /* Ignore certificate with an unknown algorithm: maybe a
+               prior certificate was already trusted. */
+            break;
+
+        case MBEDTLS_ERR_X509_ALLOC_FAILED:
+            alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
+            goto crt_parse_der_failed;
+
+        case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
+            alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+            goto crt_parse_der_failed;
+
+        default:
+            alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
+        crt_parse_der_failed:
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
+            MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
+            return( ret );
+        }
+
+        i += n;
+    }
+
+    MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert );
+
+    /*
+     * On client, make sure the server cert doesn't change during renego to
+     * avoid "triple handshake" attack: https://secure-resumption.com/
+     */
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+        ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+    {
+        if( ssl->session->peer_cert == NULL )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        }
+
+        if( ssl->session->peer_cert->raw.len !=
+            ssl->session_negotiate->peer_cert->raw.len ||
+            memcmp( ssl->session->peer_cert->raw.p,
+                    ssl->session_negotiate->peer_cert->raw.p,
+                    ssl->session->peer_cert->raw.len ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
+            return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+        }
+    }
+#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+
+    return( 0 );
+}
+
+int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
+          ssl->transform_negotiate->ciphersuite_info;
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
+                       ? ssl->handshake->sni_authmode
+                       : ssl->conf->authmode;
+#else
+    const int authmode = ssl->conf->authmode;
+#endif
+    void *rs_ctx = NULL;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
+
+    if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+#if defined(MBEDTLS_SSL_SRV_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+        ssl->state++;
+        return( 0 );
+    }
+
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+        authmode == MBEDTLS_SSL_VERIFY_NONE )
+    {
+        ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY;
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+
+        ssl->state++;
+        return( 0 );
+    }
+#endif
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    if( ssl->handshake->ecrs_enabled &&
+        ssl->handshake->ecrs_state == ssl_ecrs_crt_verify )
+    {
+        goto crt_verify;
+    }
+#endif
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        /* mbedtls_ssl_read_record may have sent an alert already. We
+           let it decide whether to alert. */
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        return( ret );
+    }
+
+    if( ( ret = ssl_parse_certificate_chain( ssl ) ) != 0 )
+    {
+#if defined(MBEDTLS_SSL_SRV_C)
+        if( ret == MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE &&
+            authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
+        {
+            ret = 0;
+        }
+#endif
+
+        ssl->state++;
+        return( ret );
+    }
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    if( ssl->handshake->ecrs_enabled)
+        ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
+
+crt_verify:
+    if( ssl->handshake->ecrs_enabled)
+        rs_ctx = &ssl->handshake->ecrs_ctx;
+#endif
+
+    if( authmode != MBEDTLS_SSL_VERIFY_NONE )
+    {
+        mbedtls_x509_crt *ca_chain;
+        mbedtls_x509_crl *ca_crl;
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+        if( ssl->handshake->sni_ca_chain != NULL )
+        {
+            ca_chain = ssl->handshake->sni_ca_chain;
+            ca_crl   = ssl->handshake->sni_ca_crl;
+        }
+        else
+#endif
+        {
+            ca_chain = ssl->conf->ca_chain;
+            ca_crl   = ssl->conf->ca_crl;
+        }
+
+        /*
+         * Main check: verify certificate
+         */
+        ret = mbedtls_x509_crt_verify_restartable(
+                                ssl->session_negotiate->peer_cert,
+                                ca_chain, ca_crl,
+                                ssl->conf->cert_profile,
+                                ssl->hostname,
+                               &ssl->session_negotiate->verify_result,
+                                ssl->conf->f_vrfy, ssl->conf->p_vrfy, rs_ctx );
+
+        if( ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
+        }
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+        if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+            return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS );
+#endif
+
+        /*
+         * Secondary checks: always done, but change 'ret' only if it was 0
+         */
+
+#if defined(MBEDTLS_ECP_C)
+        {
+            const mbedtls_pk_context *pk = &ssl->session_negotiate->peer_cert->pk;
+
+            /* If certificate uses an EC key, make sure the curve is OK */
+            if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
+                mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
+            {
+                ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
+
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
+                if( ret == 0 )
+                    ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
+            }
+        }
+#endif /* MBEDTLS_ECP_C */
+
+        if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert,
+                                 ciphersuite_info,
+                                 ! ssl->conf->endpoint,
+                                 &ssl->session_negotiate->verify_result ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
+            if( ret == 0 )
+                ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
+        }
+
+        /* mbedtls_x509_crt_verify_with_profile is supposed to report a
+         * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
+         * with details encoded in the verification flags. All other kinds
+         * of error codes, including those from the user provided f_vrfy
+         * functions, are treated as fatal and lead to a failure of
+         * ssl_parse_certificate even if verification was optional. */
+        if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
+            ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
+              ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
+        {
+            ret = 0;
+        }
+
+        if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
+            ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
+        }
+
+        if( ret != 0 )
+        {
+            uint8_t alert;
+
+            /* The certificate may have been rejected for several reasons.
+               Pick one and send the corresponding alert. Which alert to send
+               may be a subject of debate in some cases. */
+            if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER )
+                alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
+            else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH )
+                alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
+            else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE )
+                alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+            else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE )
+                alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+            else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE )
+                alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+            else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK )
+                alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+            else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY )
+                alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+            else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED )
+                alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
+            else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED )
+                alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
+            else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED )
+                alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
+            else
+                alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            alert );
+        }
+
+#if defined(MBEDTLS_DEBUG_C)
+        if( ssl->session_negotiate->verify_result != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x",
+                                        ssl->session_negotiate->verify_result ) );
+        }
+        else
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) );
+        }
+#endif /* MBEDTLS_DEBUG_C */
+    }
+
+    ssl->state++;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
+
+    return( ret );
+}
+#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+          !MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+          !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+          !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+          !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+          !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+          !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+
+int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
+
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
+    ssl->out_msglen  = 1;
+    ssl->out_msg[0]  = 1;
+
+    ssl->state++;
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
+
+    return( 0 );
+}
+
+int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        return( ret );
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    /* CCS records are only accepted if they have length 1 and content '1',
+     * so we don't need to check this here. */
+
+    /*
+     * Switch to our negotiated transform and session parameters for inbound
+     * data.
+     */
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
+    ssl->transform_in = ssl->transform_negotiate;
+    ssl->session_in = ssl->session_negotiate;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+        ssl_dtls_replay_reset( ssl );
+#endif
+
+        /* Increment epoch */
+        if( ++ssl->in_epoch == 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
+            /* This is highly unlikely to happen for legitimate reasons, so
+               treat it as an attack and don't send an alert. */
+            return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+        }
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+    memset( ssl->in_ctr, 0, 8 );
+
+    ssl_update_in_pointers( ssl, ssl->transform_negotiate );
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+    if( mbedtls_ssl_hw_record_activate != NULL )
+    {
+        if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
+            mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                            MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+    }
+#endif
+
+    ssl->state++;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
+
+    return( 0 );
+}
+
+void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
+                            const mbedtls_ssl_ciphersuite_t *ciphersuite_info )
+{
+    ((void) ciphersuite_info);
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+    if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
+        ssl->handshake->update_checksum = ssl_update_checksum_md5sha1;
+    else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA512_C)
+    if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
+        ssl->handshake->update_checksum = ssl_update_checksum_sha384;
+    else
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    if( ciphersuite_info->mac != MBEDTLS_MD_SHA384 )
+        ssl->handshake->update_checksum = ssl_update_checksum_sha256;
+    else
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+        return;
+    }
+}
+
+void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+     mbedtls_md5_starts_ret( &ssl->handshake->fin_md5  );
+    mbedtls_sha1_starts_ret( &ssl->handshake->fin_sha1 );
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+    mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+    mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 );
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+}
+
+static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
+                                       const unsigned char *buf, size_t len )
+{
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+     mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
+    mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+    mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+    mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+}
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl,
+                                         const unsigned char *buf, size_t len )
+{
+     mbedtls_md5_update_ret( &ssl->handshake->fin_md5 , buf, len );
+    mbedtls_sha1_update_ret( &ssl->handshake->fin_sha1, buf, len );
+}
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
+                                        const unsigned char *buf, size_t len )
+{
+    mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
+}
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl,
+                                        const unsigned char *buf, size_t len )
+{
+    mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
+}
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+static void ssl_calc_finished_ssl(
+                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
+{
+    const char *sender;
+    mbedtls_md5_context  md5;
+    mbedtls_sha1_context sha1;
+
+    unsigned char padbuf[48];
+    unsigned char md5sum[16];
+    unsigned char sha1sum[20];
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    if( !session )
+        session = ssl->session;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished ssl" ) );
+
+    mbedtls_md5_init( &md5 );
+    mbedtls_sha1_init( &sha1 );
+
+    mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
+    mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
+
+    /*
+     * SSLv3:
+     *   hash =
+     *      MD5( master + pad2 +
+     *          MD5( handshake + sender + master + pad1 ) )
+     *   + SHA1( master + pad2 +
+     *         SHA1( handshake + sender + master + pad1 ) )
+     */
+
+#if !defined(MBEDTLS_MD5_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished  md5 state", (unsigned char *)
+                    md5.state, sizeof(  md5.state ) );
+#endif
+
+#if !defined(MBEDTLS_SHA1_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
+                   sha1.state, sizeof( sha1.state ) );
+#endif
+
+    sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT"
+                                       : "SRVR";
+
+    memset( padbuf, 0x36, 48 );
+
+    mbedtls_md5_update_ret( &md5, (const unsigned char *) sender, 4 );
+    mbedtls_md5_update_ret( &md5, session->master, 48 );
+    mbedtls_md5_update_ret( &md5, padbuf, 48 );
+    mbedtls_md5_finish_ret( &md5, md5sum );
+
+    mbedtls_sha1_update_ret( &sha1, (const unsigned char *) sender, 4 );
+    mbedtls_sha1_update_ret( &sha1, session->master, 48 );
+    mbedtls_sha1_update_ret( &sha1, padbuf, 40 );
+    mbedtls_sha1_finish_ret( &sha1, sha1sum );
+
+    memset( padbuf, 0x5C, 48 );
+
+    mbedtls_md5_starts_ret( &md5 );
+    mbedtls_md5_update_ret( &md5, session->master, 48 );
+    mbedtls_md5_update_ret( &md5, padbuf, 48 );
+    mbedtls_md5_update_ret( &md5, md5sum, 16 );
+    mbedtls_md5_finish_ret( &md5, buf );
+
+    mbedtls_sha1_starts_ret( &sha1 );
+    mbedtls_sha1_update_ret( &sha1, session->master, 48 );
+    mbedtls_sha1_update_ret( &sha1, padbuf , 40 );
+    mbedtls_sha1_update_ret( &sha1, sha1sum, 20 );
+    mbedtls_sha1_finish_ret( &sha1, buf + 16 );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 );
+
+    mbedtls_md5_free(  &md5  );
+    mbedtls_sha1_free( &sha1 );
+
+    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
+    mbedtls_platform_zeroize(  md5sum, sizeof(  md5sum ) );
+    mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
+}
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+static void ssl_calc_finished_tls(
+                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
+{
+    int len = 12;
+    const char *sender;
+    mbedtls_md5_context  md5;
+    mbedtls_sha1_context sha1;
+    unsigned char padbuf[36];
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    if( !session )
+        session = ssl->session;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls" ) );
+
+    mbedtls_md5_init( &md5 );
+    mbedtls_sha1_init( &sha1 );
+
+    mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
+    mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
+
+    /*
+     * TLSv1:
+     *   hash = PRF( master, finished_label,
+     *               MD5( handshake ) + SHA1( handshake ) )[0..11]
+     */
+
+#if !defined(MBEDTLS_MD5_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished  md5 state", (unsigned char *)
+                    md5.state, sizeof(  md5.state ) );
+#endif
+
+#if !defined(MBEDTLS_SHA1_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
+                   sha1.state, sizeof( sha1.state ) );
+#endif
+
+    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+             ? "client finished"
+             : "server finished";
+
+    mbedtls_md5_finish_ret(  &md5, padbuf );
+    mbedtls_sha1_finish_ret( &sha1, padbuf + 16 );
+
+    ssl->handshake->tls_prf( session->master, 48, sender,
+                             padbuf, 36, buf, len );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
+
+    mbedtls_md5_free(  &md5  );
+    mbedtls_sha1_free( &sha1 );
+
+    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+static void ssl_calc_finished_tls_sha256(
+                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
+{
+    int len = 12;
+    const char *sender;
+    mbedtls_sha256_context sha256;
+    unsigned char padbuf[32];
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    if( !session )
+        session = ssl->session;
+
+    mbedtls_sha256_init( &sha256 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls sha256" ) );
+
+    mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
+
+    /*
+     * TLSv1.2:
+     *   hash = PRF( master, finished_label,
+     *               Hash( handshake ) )[0.11]
+     */
+
+#if !defined(MBEDTLS_SHA256_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
+                   sha256.state, sizeof( sha256.state ) );
+#endif
+
+    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+             ? "client finished"
+             : "server finished";
+
+    mbedtls_sha256_finish_ret( &sha256, padbuf );
+
+    ssl->handshake->tls_prf( session->master, 48, sender,
+                             padbuf, 32, buf, len );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
+
+    mbedtls_sha256_free( &sha256 );
+
+    mbedtls_platform_zeroize(  padbuf, sizeof(  padbuf ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
+}
+#endif /* MBEDTLS_SHA256_C */
+
+#if defined(MBEDTLS_SHA512_C)
+static void ssl_calc_finished_tls_sha384(
+                mbedtls_ssl_context *ssl, unsigned char *buf, int from )
+{
+    int len = 12;
+    const char *sender;
+    mbedtls_sha512_context sha512;
+    unsigned char padbuf[48];
+
+    mbedtls_ssl_session *session = ssl->session_negotiate;
+    if( !session )
+        session = ssl->session;
+
+    mbedtls_sha512_init( &sha512 );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc  finished tls sha384" ) );
+
+    mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
+
+    /*
+     * TLSv1.2:
+     *   hash = PRF( master, finished_label,
+     *               Hash( handshake ) )[0.11]
+     */
+
+#if !defined(MBEDTLS_SHA512_ALT)
+    MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
+                   sha512.state, sizeof( sha512.state ) );
+#endif
+
+    sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+             ? "client finished"
+             : "server finished";
+
+    mbedtls_sha512_finish_ret( &sha512, padbuf );
+
+    ssl->handshake->tls_prf( session->master, 48, sender,
+                             padbuf, 48, buf, len );
+
+    MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
+
+    mbedtls_sha512_free( &sha512 );
+
+    mbedtls_platform_zeroize(  padbuf, sizeof( padbuf ) );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc  finished" ) );
+}
+#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
+{
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) );
+
+    /*
+     * Free our handshake params
+     */
+    mbedtls_ssl_handshake_free( ssl );
+    mbedtls_free( ssl->handshake );
+    ssl->handshake = NULL;
+
+    /*
+     * Free the previous transform and swith in the current one
+     */
+    if( ssl->transform )
+    {
+        mbedtls_ssl_transform_free( ssl->transform );
+        mbedtls_free( ssl->transform );
+    }
+    ssl->transform = ssl->transform_negotiate;
+    ssl->transform_negotiate = NULL;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) );
+}
+
+void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
+{
+    int resume = ssl->handshake->resume;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+    {
+        ssl->renego_status =  MBEDTLS_SSL_RENEGOTIATION_DONE;
+        ssl->renego_records_seen = 0;
+    }
+#endif
+
+    /*
+     * Free the previous session and switch in the current one
+     */
+    if( ssl->session )
+    {
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+        /* RFC 7366 3.1: keep the EtM state */
+        ssl->session_negotiate->encrypt_then_mac =
+                  ssl->session->encrypt_then_mac;
+#endif
+
+        mbedtls_ssl_session_free( ssl->session );
+        mbedtls_free( ssl->session );
+    }
+    ssl->session = ssl->session_negotiate;
+    ssl->session_negotiate = NULL;
+
+    /*
+     * Add cache entry
+     */
+    if( ssl->conf->f_set_cache != NULL &&
+        ssl->session->id_len != 0 &&
+        resume == 0 )
+    {
+        if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 )
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->handshake->flight != NULL )
+    {
+        /* Cancel handshake timer */
+        ssl_set_timer( ssl, 0 );
+
+        /* Keep last flight around in case we need to resend it:
+         * we need the handshake and transform structures for that */
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip freeing handshake and transform" ) );
+    }
+    else
+#endif
+        ssl_handshake_wrapup_free_hs_transform( ssl );
+
+    ssl->state++;
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) );
+}
+
+int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
+{
+    int ret, hash_len;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
+
+    ssl_update_out_pointers( ssl, ssl->transform_negotiate );
+
+    ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
+
+    /*
+     * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites
+     * may define some other value. Currently (early 2016), no defined
+     * ciphersuite does this (and this is unlikely to change as activity has
+     * moved to TLS 1.3 now) so we can keep the hardcoded 12 here.
+     */
+    hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12;
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    ssl->verify_data_len = hash_len;
+    memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len );
+#endif
+
+    ssl->out_msglen  = 4 + hash_len;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_FINISHED;
+
+    /*
+     * In case of session resuming, invert the client and server
+     * ChangeCipherSpec messages order.
+     */
+    if( ssl->handshake->resume != 0 )
+    {
+#if defined(MBEDTLS_SSL_CLI_C)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+            ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+            ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
+#endif
+    }
+    else
+        ssl->state++;
+
+    /*
+     * Switch to our negotiated transform and session parameters for outbound
+     * data.
+     */
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        unsigned char i;
+
+        /* Remember current epoch settings for resending */
+        ssl->handshake->alt_transform_out = ssl->transform_out;
+        memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 );
+
+        /* Set sequence_number to zero */
+        memset( ssl->cur_out_ctr + 2, 0, 6 );
+
+        /* Increment epoch */
+        for( i = 2; i > 0; i-- )
+            if( ++ssl->cur_out_ctr[i - 1] != 0 )
+                break;
+
+        /* The loop goes to its end iff the counter is wrapping */
+        if( i == 0 )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
+            return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+        }
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+    memset( ssl->cur_out_ctr, 0, 8 );
+
+    ssl->transform_out = ssl->transform_negotiate;
+    ssl->session_out = ssl->session_negotiate;
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+    if( mbedtls_ssl_hw_record_activate != NULL )
+    {
+        if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+    }
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        mbedtls_ssl_send_flight_completed( ssl );
+#endif
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+        return( ret );
+    }
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+#define SSL_MAX_HASH_LEN 36
+#else
+#define SSL_MAX_HASH_LEN 12
+#endif
+
+int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
+{
+    int ret;
+    unsigned int hash_len;
+    unsigned char buf[SSL_MAX_HASH_LEN];
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) );
+
+    ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 );
+
+    if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+        return( ret );
+    }
+
+    if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+        return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+    }
+
+    /* There is currently no ciphersuite using another length with TLS 1.2 */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+        hash_len = 36;
+    else
+#endif
+        hash_len = 12;
+
+    if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED ||
+        ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
+    }
+
+    if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
+                      buf, hash_len ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+        return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
+    }
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    ssl->verify_data_len = hash_len;
+    memcpy( ssl->peer_verify_data, buf, hash_len );
+#endif
+
+    if( ssl->handshake->resume != 0 )
+    {
+#if defined(MBEDTLS_SSL_CLI_C)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+            ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC;
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+            ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
+#endif
+    }
+    else
+        ssl->state++;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        mbedtls_ssl_recv_flight_completed( ssl );
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) );
+
+    return( 0 );
+}
+
+static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
+{
+    memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+     mbedtls_md5_init(   &handshake->fin_md5  );
+    mbedtls_sha1_init(   &handshake->fin_sha1 );
+     mbedtls_md5_starts_ret( &handshake->fin_md5  );
+    mbedtls_sha1_starts_ret( &handshake->fin_sha1 );
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+    mbedtls_sha256_init(   &handshake->fin_sha256    );
+    mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+    mbedtls_sha512_init(   &handshake->fin_sha512    );
+    mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 );
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+    handshake->update_checksum = ssl_update_checksum_start;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+    mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs );
+#endif
+
+#if defined(MBEDTLS_DHM_C)
+    mbedtls_dhm_init( &handshake->dhm_ctx );
+#endif
+#if defined(MBEDTLS_ECDH_C)
+    mbedtls_ecdh_init( &handshake->ecdh_ctx );
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    mbedtls_ecjpake_init( &handshake->ecjpake_ctx );
+#if defined(MBEDTLS_SSL_CLI_C)
+    handshake->ecjpake_cache = NULL;
+    handshake->ecjpake_cache_len = 0;
+#endif
+#endif
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    mbedtls_x509_crt_restart_init( &handshake->ecrs_ctx );
+#endif
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
+#endif
+}
+
+static void ssl_transform_init( mbedtls_ssl_transform *transform )
+{
+    memset( transform, 0, sizeof(mbedtls_ssl_transform) );
+
+    mbedtls_cipher_init( &transform->cipher_ctx_enc );
+    mbedtls_cipher_init( &transform->cipher_ctx_dec );
+
+    mbedtls_md_init( &transform->md_ctx_enc );
+    mbedtls_md_init( &transform->md_ctx_dec );
+}
+
+void mbedtls_ssl_session_init( mbedtls_ssl_session *session )
+{
+    memset( session, 0, sizeof(mbedtls_ssl_session) );
+}
+
+static int ssl_handshake_init( mbedtls_ssl_context *ssl )
+{
+    /* Clear old handshake information if present */
+    if( ssl->transform_negotiate )
+        mbedtls_ssl_transform_free( ssl->transform_negotiate );
+    if( ssl->session_negotiate )
+        mbedtls_ssl_session_free( ssl->session_negotiate );
+    if( ssl->handshake )
+        mbedtls_ssl_handshake_free( ssl );
+
+    /*
+     * Either the pointers are now NULL or cleared properly and can be freed.
+     * Now allocate missing structures.
+     */
+    if( ssl->transform_negotiate == NULL )
+    {
+        ssl->transform_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_transform) );
+    }
+
+    if( ssl->session_negotiate == NULL )
+    {
+        ssl->session_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_session) );
+    }
+
+    if( ssl->handshake == NULL )
+    {
+        ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) );
+    }
+
+    /* All pointers should exist and can be directly freed without issue */
+    if( ssl->handshake == NULL ||
+        ssl->transform_negotiate == NULL ||
+        ssl->session_negotiate == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc() of ssl sub-contexts failed" ) );
+
+        mbedtls_free( ssl->handshake );
+        mbedtls_free( ssl->transform_negotiate );
+        mbedtls_free( ssl->session_negotiate );
+
+        ssl->handshake = NULL;
+        ssl->transform_negotiate = NULL;
+        ssl->session_negotiate = NULL;
+
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+    }
+
+    /* Initialize structures */
+    mbedtls_ssl_session_init( ssl->session_negotiate );
+    ssl_transform_init( ssl->transform_negotiate );
+    ssl_handshake_params_init( ssl->handshake );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl->handshake->alt_transform_out = ssl->transform_out;
+
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+            ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
+        else
+            ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+
+        ssl_set_timer( ssl, 0 );
+    }
+#endif
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+/* Dummy cookie callbacks for defaults */
+static int ssl_cookie_write_dummy( void *ctx,
+                      unsigned char **p, unsigned char *end,
+                      const unsigned char *cli_id, size_t cli_id_len )
+{
+    ((void) ctx);
+    ((void) p);
+    ((void) end);
+    ((void) cli_id);
+    ((void) cli_id_len);
+
+    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+}
+
+static int ssl_cookie_check_dummy( void *ctx,
+                      const unsigned char *cookie, size_t cookie_len,
+                      const unsigned char *cli_id, size_t cli_id_len )
+{
+    ((void) ctx);
+    ((void) cookie);
+    ((void) cookie_len);
+    ((void) cli_id);
+    ((void) cli_id_len);
+
+    return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+}
+#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
+
+/* Once ssl->out_hdr as the address of the beginning of the
+ * next outgoing record is set, deduce the other pointers.
+ *
+ * Note: For TLS, we save the implicit record sequence number
+ *       (entering MAC computation) in the 8 bytes before ssl->out_hdr,
+ *       and the caller has to make sure there's space for this.
+ */
+
+static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
+                                     mbedtls_ssl_transform *transform )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl->out_ctr = ssl->out_hdr +  3;
+        ssl->out_len = ssl->out_hdr + 11;
+        ssl->out_iv  = ssl->out_hdr + 13;
+    }
+    else
+#endif
+    {
+        ssl->out_ctr = ssl->out_hdr - 8;
+        ssl->out_len = ssl->out_hdr + 3;
+        ssl->out_iv  = ssl->out_hdr + 5;
+    }
+
+    /* Adjust out_msg to make space for explicit IV, if used. */
+    if( transform != NULL &&
+        ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+    {
+        ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen;
+    }
+    else
+        ssl->out_msg = ssl->out_iv;
+}
+
+/* Once ssl->in_hdr as the address of the beginning of the
+ * next incoming record is set, deduce the other pointers.
+ *
+ * Note: For TLS, we save the implicit record sequence number
+ *       (entering MAC computation) in the 8 bytes before ssl->in_hdr,
+ *       and the caller has to make sure there's space for this.
+ */
+
+static void ssl_update_in_pointers( mbedtls_ssl_context *ssl,
+                                    mbedtls_ssl_transform *transform )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl->in_ctr = ssl->in_hdr +  3;
+        ssl->in_len = ssl->in_hdr + 11;
+        ssl->in_iv  = ssl->in_hdr + 13;
+    }
+    else
+#endif
+    {
+        ssl->in_ctr = ssl->in_hdr - 8;
+        ssl->in_len = ssl->in_hdr + 3;
+        ssl->in_iv  = ssl->in_hdr + 5;
+    }
+
+    /* Offset in_msg from in_iv to allow space for explicit IV, if used. */
+    if( transform != NULL &&
+        ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+    {
+        ssl->in_msg = ssl->in_iv + transform->ivlen - transform->fixed_ivlen;
+    }
+    else
+        ssl->in_msg = ssl->in_iv;
+}
+
+/*
+ * Initialize an SSL context
+ */
+void mbedtls_ssl_init( mbedtls_ssl_context *ssl )
+{
+    memset( ssl, 0, sizeof( mbedtls_ssl_context ) );
+}
+
+/*
+ * Setup an SSL context
+ */
+
+static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl )
+{
+    /* Set the incoming and outgoing record pointers. */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        ssl->out_hdr = ssl->out_buf;
+        ssl->in_hdr  = ssl->in_buf;
+    }
+    else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+    {
+        ssl->out_hdr = ssl->out_buf + 8;
+        ssl->in_hdr  = ssl->in_buf  + 8;
+    }
+
+    /* Derive other internal pointers. */
+    ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
+    ssl_update_in_pointers ( ssl, NULL /* no transform enabled */ );
+}
+
+int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
+                       const mbedtls_ssl_config *conf )
+{
+    int ret;
+
+    ssl->conf = conf;
+
+    /*
+     * Prepare base structures
+     */
+
+    /* Set to NULL in case of an error condition */
+    ssl->out_buf = NULL;
+
+    ssl->in_buf = mbedtls_calloc( 1, MBEDTLS_SSL_IN_BUFFER_LEN );
+    if( ssl->in_buf == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN) );
+        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+        goto error;
+    }
+
+    ssl->out_buf = mbedtls_calloc( 1, MBEDTLS_SSL_OUT_BUFFER_LEN );
+    if( ssl->out_buf == NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_OUT_BUFFER_LEN) );
+        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+        goto error;
+    }
+
+    ssl_reset_in_out_pointers( ssl );
+
+    if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
+        goto error;
+
+    return( 0 );
+
+error:
+    mbedtls_free( ssl->in_buf );
+    mbedtls_free( ssl->out_buf );
+
+    ssl->conf = NULL;
+
+    ssl->in_buf = NULL;
+    ssl->out_buf = NULL;
+
+    ssl->in_hdr = NULL;
+    ssl->in_ctr = NULL;
+    ssl->in_len = NULL;
+    ssl->in_iv = NULL;
+    ssl->in_msg = NULL;
+
+    ssl->out_hdr = NULL;
+    ssl->out_ctr = NULL;
+    ssl->out_len = NULL;
+    ssl->out_iv = NULL;
+    ssl->out_msg = NULL;
+
+    return( ret );
+}
+
+/*
+ * Reset an initialized and used SSL context for re-use while retaining
+ * all application-set variables, function pointers and data.
+ *
+ * If partial is non-zero, keep data in the input buffer and client ID.
+ * (Use when a DTLS client reconnects from the same port.)
+ */
+static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
+{
+    int ret;
+
+#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) ||     \
+    !defined(MBEDTLS_SSL_SRV_C)
+    ((void) partial);
+#endif
+
+    ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
+
+    /* Cancel any possibly running timer */
+    ssl_set_timer( ssl, 0 );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE;
+    ssl->renego_records_seen = 0;
+
+    ssl->verify_data_len = 0;
+    memset( ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN );
+    memset( ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN );
+#endif
+    ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
+
+    ssl->in_offt = NULL;
+    ssl_reset_in_out_pointers( ssl );
+
+    ssl->in_msgtype = 0;
+    ssl->in_msglen = 0;
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    ssl->next_record_offset = 0;
+    ssl->in_epoch = 0;
+#endif
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+    ssl_dtls_replay_reset( ssl );
+#endif
+
+    ssl->in_hslen = 0;
+    ssl->nb_zero = 0;
+
+    ssl->keep_current_message = 0;
+
+    ssl->out_msgtype = 0;
+    ssl->out_msglen = 0;
+    ssl->out_left = 0;
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+    if( ssl->split_done != MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED )
+        ssl->split_done = 0;
+#endif
+
+    memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
+
+    ssl->transform_in = NULL;
+    ssl->transform_out = NULL;
+
+    ssl->session_in = NULL;
+    ssl->session_out = NULL;
+
+    memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN );
+
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+    if( partial == 0 )
+#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
+    {
+        ssl->in_left = 0;
+        memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN );
+    }
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+    if( mbedtls_ssl_hw_record_reset != NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_reset()" ) );
+        if( ( ret = mbedtls_ssl_hw_record_reset( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_reset", ret );
+            return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+        }
+    }
+#endif
+
+    if( ssl->transform )
+    {
+        mbedtls_ssl_transform_free( ssl->transform );
+        mbedtls_free( ssl->transform );
+        ssl->transform = NULL;
+    }
+
+    if( ssl->session )
+    {
+        mbedtls_ssl_session_free( ssl->session );
+        mbedtls_free( ssl->session );
+        ssl->session = NULL;
+    }
+
+#if defined(MBEDTLS_SSL_ALPN)
+    ssl->alpn_chosen = NULL;
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
+    if( partial == 0 )
+#endif
+    {
+        mbedtls_free( ssl->cli_id );
+        ssl->cli_id = NULL;
+        ssl->cli_id_len = 0;
+    }
+#endif
+
+    if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+/*
+ * Reset an initialized and used SSL context for re-use while retaining
+ * all application-set variables, function pointers and data.
+ */
+int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl )
+{
+    return( ssl_session_reset_int( ssl, 0 ) );
+}
+
+/*
+ * SSL set accessors
+ */
+void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint )
+{
+    conf->endpoint   = endpoint;
+}
+
+void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport )
+{
+    conf->transport = transport;
+}
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode )
+{
+    conf->anti_replay = mode;
+}
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit )
+{
+    conf->badmac_limit = limit;
+}
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl,
+                                       unsigned allow_packing )
+{
+    ssl->disable_datagram_packing = !allow_packing;
+}
+
+void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf,
+                                         uint32_t min, uint32_t max )
+{
+    conf->hs_timeout_min = min;
+    conf->hs_timeout_max = max;
+}
+#endif
+
+void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode )
+{
+    conf->authmode   = authmode;
+}
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+                     void *p_vrfy )
+{
+    conf->f_vrfy      = f_vrfy;
+    conf->p_vrfy      = p_vrfy;
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf,
+                  int (*f_rng)(void *, unsigned char *, size_t),
+                  void *p_rng )
+{
+    conf->f_rng      = f_rng;
+    conf->p_rng      = p_rng;
+}
+
+void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
+                  void (*f_dbg)(void *, int, const char *, int, const char *),
+                  void  *p_dbg )
+{
+    conf->f_dbg      = f_dbg;
+    conf->p_dbg      = p_dbg;
+}
+
+void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
+        void *p_bio,
+        mbedtls_ssl_send_t *f_send,
+        mbedtls_ssl_recv_t *f_recv,
+        mbedtls_ssl_recv_timeout_t *f_recv_timeout )
+{
+    ssl->p_bio          = p_bio;
+    ssl->f_send         = f_send;
+    ssl->f_recv         = f_recv;
+    ssl->f_recv_timeout = f_recv_timeout;
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu )
+{
+    ssl->mtu = mtu;
+}
+#endif
+
+void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout )
+{
+    conf->read_timeout   = timeout;
+}
+
+void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
+                               void *p_timer,
+                               mbedtls_ssl_set_timer_t *f_set_timer,
+                               mbedtls_ssl_get_timer_t *f_get_timer )
+{
+    ssl->p_timer        = p_timer;
+    ssl->f_set_timer    = f_set_timer;
+    ssl->f_get_timer    = f_get_timer;
+
+    /* Make sure we start with no timer running */
+    ssl_set_timer( ssl, 0 );
+}
+
+#if defined(MBEDTLS_SSL_SRV_C)
+void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
+        void *p_cache,
+        int (*f_get_cache)(void *, mbedtls_ssl_session *),
+        int (*f_set_cache)(void *, const mbedtls_ssl_session *) )
+{
+    conf->p_cache = p_cache;
+    conf->f_get_cache = f_get_cache;
+    conf->f_set_cache = f_set_cache;
+}
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session )
+{
+    int ret;
+
+    if( ssl == NULL ||
+        session == NULL ||
+        ssl->session_negotiate == NULL ||
+        ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT )
+    {
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 )
+        return( ret );
+
+    ssl->handshake->resume = 1;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_CLI_C */
+
+void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
+                                   const int *ciphersuites )
+{
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites;
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites;
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites;
+    conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites;
+}
+
+void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
+                                       const int *ciphersuites,
+                                       int major, int minor )
+{
+    if( major != MBEDTLS_SSL_MAJOR_VERSION_3 )
+        return;
+
+    if( minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3 )
+        return;
+
+    conf->ciphersuite_list[minor] = ciphersuites;
+}
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf,
+                                    const mbedtls_x509_crt_profile *profile )
+{
+    conf->cert_profile = profile;
+}
+
+/* Append a new keycert entry to a (possibly empty) list */
+static int ssl_append_key_cert( mbedtls_ssl_key_cert **head,
+                                mbedtls_x509_crt *cert,
+                                mbedtls_pk_context *key )
+{
+    mbedtls_ssl_key_cert *new_cert;
+
+    new_cert = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) );
+    if( new_cert == NULL )
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+    new_cert->cert = cert;
+    new_cert->key  = key;
+    new_cert->next = NULL;
+
+    /* Update head is the list was null, else add to the end */
+    if( *head == NULL )
+    {
+        *head = new_cert;
+    }
+    else
+    {
+        mbedtls_ssl_key_cert *cur = *head;
+        while( cur->next != NULL )
+            cur = cur->next;
+        cur->next = new_cert;
+    }
+
+    return( 0 );
+}
+
+int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
+                              mbedtls_x509_crt *own_cert,
+                              mbedtls_pk_context *pk_key )
+{
+    return( ssl_append_key_cert( &conf->key_cert, own_cert, pk_key ) );
+}
+
+void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
+                               mbedtls_x509_crt *ca_chain,
+                               mbedtls_x509_crl *ca_crl )
+{
+    conf->ca_chain   = ca_chain;
+    conf->ca_crl     = ca_crl;
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl,
+                                 mbedtls_x509_crt *own_cert,
+                                 mbedtls_pk_context *pk_key )
+{
+    return( ssl_append_key_cert( &ssl->handshake->sni_key_cert,
+                                 own_cert, pk_key ) );
+}
+
+void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl,
+                                  mbedtls_x509_crt *ca_chain,
+                                  mbedtls_x509_crl *ca_crl )
+{
+    ssl->handshake->sni_ca_chain   = ca_chain;
+    ssl->handshake->sni_ca_crl     = ca_crl;
+}
+
+void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
+                                  int authmode )
+{
+    ssl->handshake->sni_authmode = authmode;
+}
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+/*
+ * Set EC J-PAKE password for current handshake
+ */
+int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
+                                         const unsigned char *pw,
+                                         size_t pw_len )
+{
+    mbedtls_ecjpake_role role;
+
+    if( ssl->handshake == NULL || ssl->conf == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+        role = MBEDTLS_ECJPAKE_SERVER;
+    else
+        role = MBEDTLS_ECJPAKE_CLIENT;
+
+    return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx,
+                                   role,
+                                   MBEDTLS_MD_SHA256,
+                                   MBEDTLS_ECP_DP_SECP256R1,
+                                   pw, pw_len ) );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
+                const unsigned char *psk, size_t psk_len,
+                const unsigned char *psk_identity, size_t psk_identity_len )
+{
+    if( psk == NULL || psk_identity == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    if( psk_len > MBEDTLS_PSK_MAX_LEN )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    /* Identity len will be encoded on two bytes */
+    if( ( psk_identity_len >> 16 ) != 0 ||
+        psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
+    {
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    if( conf->psk != NULL )
+    {
+        mbedtls_platform_zeroize( conf->psk, conf->psk_len );
+
+        mbedtls_free( conf->psk );
+        conf->psk = NULL;
+        conf->psk_len = 0;
+    }
+    if( conf->psk_identity != NULL )
+    {
+        mbedtls_free( conf->psk_identity );
+        conf->psk_identity = NULL;
+        conf->psk_identity_len = 0;
+    }
+
+    if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ||
+        ( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL )
+    {
+        mbedtls_free( conf->psk );
+        mbedtls_free( conf->psk_identity );
+        conf->psk = NULL;
+        conf->psk_identity = NULL;
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+    }
+
+    conf->psk_len = psk_len;
+    conf->psk_identity_len = psk_identity_len;
+
+    memcpy( conf->psk, psk, conf->psk_len );
+    memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len );
+
+    return( 0 );
+}
+
+int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
+                            const unsigned char *psk, size_t psk_len )
+{
+    if( psk == NULL || ssl->handshake == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    if( psk_len > MBEDTLS_PSK_MAX_LEN )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    if( ssl->handshake->psk != NULL )
+    {
+        mbedtls_platform_zeroize( ssl->handshake->psk,
+                                  ssl->handshake->psk_len );
+        mbedtls_free( ssl->handshake->psk );
+        ssl->handshake->psk_len = 0;
+    }
+
+    if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
+        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+    ssl->handshake->psk_len = psk_len;
+    memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len );
+
+    return( 0 );
+}
+
+void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
+                     int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
+                     size_t),
+                     void *p_psk )
+{
+    conf->f_psk = f_psk;
+    conf->p_psk = p_psk;
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G )
+{
+    int ret;
+
+    if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 ||
+        ( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 )
+    {
+        mbedtls_mpi_free( &conf->dhm_P );
+        mbedtls_mpi_free( &conf->dhm_G );
+        return( ret );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
+int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
+                                   const unsigned char *dhm_P, size_t P_len,
+                                   const unsigned char *dhm_G, size_t G_len )
+{
+    int ret;
+
+    if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 ||
+        ( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 )
+    {
+        mbedtls_mpi_free( &conf->dhm_P );
+        mbedtls_mpi_free( &conf->dhm_G );
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx )
+{
+    int ret;
+
+    if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 ||
+        ( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 )
+    {
+        mbedtls_mpi_free( &conf->dhm_P );
+        mbedtls_mpi_free( &conf->dhm_G );
+        return( ret );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
+/*
+ * Set the minimum length for Diffie-Hellman parameters
+ */
+void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
+                                      unsigned int bitlen )
+{
+    conf->dhm_min_bitlen = bitlen;
+}
+#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+/*
+ * Set allowed/preferred hashes for handshake signatures
+ */
+void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
+                                  const int *hashes )
+{
+    conf->sig_hashes = hashes;
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+#if defined(MBEDTLS_ECP_C)
+/*
+ * Set the allowed elliptic curves
+ */
+void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
+                             const mbedtls_ecp_group_id *curve_list )
+{
+    conf->curve_list = curve_list;
+}
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname )
+{
+    /* Initialize to suppress unnecessary compiler warning */
+    size_t hostname_len = 0;
+
+    /* Check if new hostname is valid before
+     * making any change to current one */
+    if( hostname != NULL )
+    {
+        hostname_len = strlen( hostname );
+
+        if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    /* Now it's clear that we will overwrite the old hostname,
+     * so we can free it safely */
+
+    if( ssl->hostname != NULL )
+    {
+        mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) );
+        mbedtls_free( ssl->hostname );
+    }
+
+    /* Passing NULL as hostname shall clear the old one */
+
+    if( hostname == NULL )
+    {
+        ssl->hostname = NULL;
+    }
+    else
+    {
+        ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 );
+        if( ssl->hostname == NULL )
+            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+        memcpy( ssl->hostname, hostname, hostname_len );
+
+        ssl->hostname[hostname_len] = '\0';
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
+                  int (*f_sni)(void *, mbedtls_ssl_context *,
+                                const unsigned char *, size_t),
+                  void *p_sni )
+{
+    conf->f_sni = f_sni;
+    conf->p_sni = p_sni;
+}
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_SSL_ALPN)
+int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos )
+{
+    size_t cur_len, tot_len;
+    const char **p;
+
+    /*
+     * RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings
+     * MUST NOT be truncated."
+     * We check lengths now rather than later.
+     */
+    tot_len = 0;
+    for( p = protos; *p != NULL; p++ )
+    {
+        cur_len = strlen( *p );
+        tot_len += cur_len;
+
+        if( cur_len == 0 || cur_len > 255 || tot_len > 65535 )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    conf->alpn_list = protos;
+
+    return( 0 );
+}
+
+const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
+{
+    return( ssl->alpn_chosen );
+}
+#endif /* MBEDTLS_SSL_ALPN */
+
+void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor )
+{
+    conf->max_major_ver = major;
+    conf->max_minor_ver = minor;
+}
+
+void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor )
+{
+    conf->min_major_ver = major;
+    conf->min_minor_ver = minor;
+}
+
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
+void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback )
+{
+    conf->fallback = fallback;
+}
+#endif
+
+#if defined(MBEDTLS_SSL_SRV_C)
+void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf,
+                                          char cert_req_ca_list )
+{
+    conf->cert_req_ca_list = cert_req_ca_list;
+}
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm )
+{
+    conf->encrypt_then_mac = etm;
+}
+#endif
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems )
+{
+    conf->extended_ms = ems;
+}
+#endif
+
+#if defined(MBEDTLS_ARC4_C)
+void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 )
+{
+    conf->arc4_disabled = arc4;
+}
+#endif
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code )
+{
+    if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ||
+        ssl_mfl_code_to_length( mfl_code ) > MBEDTLS_TLS_EXT_ADV_CONTENT_LEN )
+    {
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    conf->mfl_code = mfl_code;
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate )
+{
+    conf->trunc_hmac = truncate;
+}
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split )
+{
+    conf->cbc_record_splitting = split;
+}
+#endif
+
+void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy )
+{
+    conf->allow_legacy_renegotiation = allow_legacy;
+}
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation )
+{
+    conf->disable_renegotiation = renegotiation;
+}
+
+void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records )
+{
+    conf->renego_max_records = max_records;
+}
+
+void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf,
+                                   const unsigned char period[8] )
+{
+    memcpy( conf->renego_period, period, 8 );
+}
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+#if defined(MBEDTLS_SSL_CLI_C)
+void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets )
+{
+    conf->session_tickets = use_tickets;
+}
+#endif
+
+#if defined(MBEDTLS_SSL_SRV_C)
+void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
+        mbedtls_ssl_ticket_write_t *f_ticket_write,
+        mbedtls_ssl_ticket_parse_t *f_ticket_parse,
+        void *p_ticket )
+{
+    conf->f_ticket_write = f_ticket_write;
+    conf->f_ticket_parse = f_ticket_parse;
+    conf->p_ticket       = p_ticket;
+}
+#endif
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
+        mbedtls_ssl_export_keys_t *f_export_keys,
+        void *p_export_keys )
+{
+    conf->f_export_keys = f_export_keys;
+    conf->p_export_keys = p_export_keys;
+}
+#endif
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+void mbedtls_ssl_conf_async_private_cb(
+    mbedtls_ssl_config *conf,
+    mbedtls_ssl_async_sign_t *f_async_sign,
+    mbedtls_ssl_async_decrypt_t *f_async_decrypt,
+    mbedtls_ssl_async_resume_t *f_async_resume,
+    mbedtls_ssl_async_cancel_t *f_async_cancel,
+    void *async_config_data )
+{
+    conf->f_async_sign_start = f_async_sign;
+    conf->f_async_decrypt_start = f_async_decrypt;
+    conf->f_async_resume = f_async_resume;
+    conf->f_async_cancel = f_async_cancel;
+    conf->p_async_config_data = async_config_data;
+}
+
+void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf )
+{
+    return( conf->p_async_config_data );
+}
+
+void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl )
+{
+    if( ssl->handshake == NULL )
+        return( NULL );
+    else
+        return( ssl->handshake->user_async_ctx );
+}
+
+void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
+                                 void *ctx )
+{
+    if( ssl->handshake != NULL )
+        ssl->handshake->user_async_ctx = ctx;
+}
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+/*
+ * SSL get accessors
+ */
+size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
+{
+    return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
+}
+
+int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl )
+{
+    /*
+     * Case A: We're currently holding back
+     * a message for further processing.
+     */
+
+    if( ssl->keep_current_message == 1 )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) );
+        return( 1 );
+    }
+
+    /*
+     * Case B: Further records are pending in the current datagram.
+     */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->in_left > ssl->next_record_offset )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) );
+        return( 1 );
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+    /*
+     * Case C: A handshake message is being processed.
+     */
+
+    if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) );
+        return( 1 );
+    }
+
+    /*
+     * Case D: An application data message is being processed
+     */
+    if( ssl->in_offt != NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) );
+        return( 1 );
+    }
+
+    /*
+     * In all other cases, the rest of the message can be dropped.
+     * As in ssl_get_next_record, this needs to be adapted if
+     * we implement support for multiple alerts in single records.
+     */
+
+    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) );
+    return( 0 );
+}
+
+uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl )
+{
+    if( ssl->session != NULL )
+        return( ssl->session->verify_result );
+
+    if( ssl->session_negotiate != NULL )
+        return( ssl->session_negotiate->verify_result );
+
+    return( 0xFFFFFFFF );
+}
+
+const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl )
+{
+    if( ssl == NULL || ssl->session == NULL )
+        return( NULL );
+
+    return mbedtls_ssl_get_ciphersuite_name( ssl->session->ciphersuite );
+}
+
+const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        switch( ssl->minor_ver )
+        {
+            case MBEDTLS_SSL_MINOR_VERSION_2:
+                return( "DTLSv1.0" );
+
+            case MBEDTLS_SSL_MINOR_VERSION_3:
+                return( "DTLSv1.2" );
+
+            default:
+                return( "unknown (DTLS)" );
+        }
+    }
+#endif
+
+    switch( ssl->minor_ver )
+    {
+        case MBEDTLS_SSL_MINOR_VERSION_0:
+            return( "SSLv3.0" );
+
+        case MBEDTLS_SSL_MINOR_VERSION_1:
+            return( "TLSv1.0" );
+
+        case MBEDTLS_SSL_MINOR_VERSION_2:
+            return( "TLSv1.1" );
+
+        case MBEDTLS_SSL_MINOR_VERSION_3:
+            return( "TLSv1.2" );
+
+        default:
+            return( "unknown" );
+    }
+}
+
+int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
+{
+    size_t transform_expansion = 0;
+    const mbedtls_ssl_transform *transform = ssl->transform_out;
+    unsigned block_size;
+
+    if( transform == NULL )
+        return( (int) mbedtls_ssl_hdr_len( ssl ) );
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
+        return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif
+
+    switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
+    {
+        case MBEDTLS_MODE_GCM:
+        case MBEDTLS_MODE_CCM:
+        case MBEDTLS_MODE_CHACHAPOLY:
+        case MBEDTLS_MODE_STREAM:
+            transform_expansion = transform->minlen;
+            break;
+
+        case MBEDTLS_MODE_CBC:
+
+            block_size = mbedtls_cipher_get_block_size(
+                &transform->cipher_ctx_enc );
+
+            /* Expansion due to the addition of the MAC. */
+            transform_expansion += transform->maclen;
+
+            /* Expansion due to the addition of CBC padding;
+             * Theoretically up to 256 bytes, but we never use
+             * more than the block size of the underlying cipher. */
+            transform_expansion += block_size;
+
+            /* For TLS 1.1 or higher, an explicit IV is added
+             * after the record header. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+            if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+                transform_expansion += block_size;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
+            break;
+
+        default:
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+            return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+    }
+
+    return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) );
+}
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
+{
+    size_t max_len;
+
+    /*
+     * Assume mfl_code is correct since it was checked when set
+     */
+    max_len = ssl_mfl_code_to_length( ssl->conf->mfl_code );
+
+    /* Check if a smaller max length was negotiated */
+    if( ssl->session_out != NULL &&
+        ssl_mfl_code_to_length( ssl->session_out->mfl_code ) < max_len )
+    {
+        max_len = ssl_mfl_code_to_length( ssl->session_out->mfl_code );
+    }
+
+    /* During a handshake, use the value being negotiated */
+    if( ssl->session_negotiate != NULL &&
+        ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code ) < max_len )
+    {
+        max_len = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code );
+    }
+
+    return( max_len );
+}
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl )
+{
+    /* Return unlimited mtu for client hello messages to avoid fragmentation. */
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+        ( ssl->state == MBEDTLS_SSL_CLIENT_HELLO ||
+          ssl->state == MBEDTLS_SSL_SERVER_HELLO ) )
+        return ( 0 );
+
+    if( ssl->handshake == NULL || ssl->handshake->mtu == 0 )
+        return( ssl->mtu );
+
+    if( ssl->mtu == 0 )
+        return( ssl->handshake->mtu );
+
+    return( ssl->mtu < ssl->handshake->mtu ?
+            ssl->mtu : ssl->handshake->mtu );
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
+{
+    size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) && \
+    !defined(MBEDTLS_SSL_PROTO_DTLS)
+    (void) ssl;
+#endif
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
+
+    if( max_len > mfl )
+        max_len = mfl;
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl_get_current_mtu( ssl ) != 0 )
+    {
+        const size_t mtu = ssl_get_current_mtu( ssl );
+        const int ret = mbedtls_ssl_get_record_expansion( ssl );
+        const size_t overhead = (size_t) ret;
+
+        if( ret < 0 )
+            return( ret );
+
+        if( mtu <= overhead )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "MTU too low for record expansion" ) );
+            return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+        }
+
+        if( max_len > mtu - overhead )
+            max_len = mtu - overhead;
+    }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) &&        \
+    !defined(MBEDTLS_SSL_PROTO_DTLS)
+    ((void) ssl);
+#endif
+
+    return( (int) max_len );
+}
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl )
+{
+    if( ssl == NULL || ssl->session == NULL )
+        return( NULL );
+
+    return( ssl->session->peer_cert );
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *dst )
+{
+    if( ssl == NULL ||
+        dst == NULL ||
+        ssl->session == NULL ||
+        ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT )
+    {
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+    }
+
+    return( ssl_session_copy( dst, ssl->session ) );
+}
+#endif /* MBEDTLS_SSL_CLI_C */
+
+/*
+ * Perform a single step of the SSL handshake
+ */
+int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+
+    if( ssl == NULL || ssl->conf == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_SSL_CLI_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+        ret = mbedtls_ssl_handshake_client_step( ssl );
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+        ret = mbedtls_ssl_handshake_server_step( ssl );
+#endif
+
+    return( ret );
+}
+
+/*
+ * Perform the SSL handshake
+ */
+int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl )
+{
+    int ret = 0;
+
+    if( ssl == NULL || ssl->conf == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
+
+    while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+    {
+        ret = mbedtls_ssl_handshake_step( ssl );
+
+        if( ret != 0 )
+            break;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= handshake" ) );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+#if defined(MBEDTLS_SSL_SRV_C)
+/*
+ * Write HelloRequest to request renegotiation on server
+ */
+static int ssl_write_hello_request( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello request" ) );
+
+    ssl->out_msglen  = 4;
+    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+    ssl->out_msg[0]  = MBEDTLS_SSL_HS_HELLO_REQUEST;
+
+    if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello request" ) );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_SSL_SRV_C */
+
+/*
+ * Actually renegotiate current connection, triggered by either:
+ * - any side: calling mbedtls_ssl_renegotiate(),
+ * - client: receiving a HelloRequest during mbedtls_ssl_read(),
+ * - server: receiving any handshake message on server during mbedtls_ssl_read() after
+ *   the initial handshake is completed.
+ * If the handshake doesn't complete due to waiting for I/O, it will continue
+ * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively.
+ */
+static int ssl_start_renegotiation( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) );
+
+    if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
+        return( ret );
+
+    /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and
+     * the ServerHello will have message_seq = 1" */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+        ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
+    {
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+            ssl->handshake->out_msg_seq = 1;
+        else
+            ssl->handshake->in_msg_seq = 1;
+    }
+#endif
+
+    ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
+    ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS;
+
+    if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
+        return( ret );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= renegotiate" ) );
+
+    return( 0 );
+}
+
+/*
+ * Renegotiate current connection on client,
+ * or request renegotiation on server
+ */
+int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl )
+{
+    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+
+    if( ssl == NULL || ssl->conf == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_SSL_SRV_C)
+    /* On server, just send the request */
+    if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
+
+        /* Did we already try/start sending HelloRequest? */
+        if( ssl->out_left != 0 )
+            return( mbedtls_ssl_flush_output( ssl ) );
+
+        return( ssl_write_hello_request( ssl ) );
+    }
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+    /*
+     * On client, either start the renegotiation process or,
+     * if already in progress, continue the handshake
+     */
+    if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+    {
+        if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+        if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
+            return( ret );
+        }
+    }
+    else
+    {
+        if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
+            return( ret );
+        }
+    }
+#endif /* MBEDTLS_SSL_CLI_C */
+
+    return( ret );
+}
+
+/*
+ * Check record counters and renegotiate if they're above the limit.
+ */
+static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
+{
+    size_t ep_len = ssl_ep_len( ssl );
+    int in_ctr_cmp;
+    int out_ctr_cmp;
+
+    if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
+        ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
+        ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
+    {
+        return( 0 );
+    }
+
+    in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
+                        ssl->conf->renego_period + ep_len, 8 - ep_len );
+    out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
+                          ssl->conf->renego_period + ep_len, 8 - ep_len );
+
+    if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
+    {
+        return( 0 );
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) );
+    return( mbedtls_ssl_renegotiate( ssl ) );
+}
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+/*
+ * Receive application data decrypted from the SSL layer
+ */
+int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
+{
+    int ret;
+    size_t n;
+
+    if( ssl == NULL || ssl->conf == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+            return( ret );
+
+        if( ssl->handshake != NULL &&
+            ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
+        {
+            if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+                return( ret );
+        }
+    }
+#endif
+
+    /*
+     * Check if renegotiation is necessary and/or handshake is
+     * in process. If yes, perform/continue, and fall through
+     * if an unexpected packet is received while the client
+     * is waiting for the ServerHello.
+     *
+     * (There is no equivalent to the last condition on
+     *  the server-side as it is not treated as within
+     *  a handshake while waiting for the ClientHello
+     *  after a renegotiation request.)
+     */
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    ret = ssl_check_ctr_renegotiate( ssl );
+    if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+        ret != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+        return( ret );
+    }
+#endif
+
+    if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+    {
+        ret = mbedtls_ssl_handshake( ssl );
+        if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+            ret != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
+            return( ret );
+        }
+    }
+
+    /* Loop as long as no application data record is available */
+    while( ssl->in_offt == NULL )
+    {
+        /* Start timer if not already running */
+        if( ssl->f_get_timer != NULL &&
+            ssl->f_get_timer( ssl->p_timer ) == -1 )
+        {
+            ssl_set_timer( ssl, ssl->conf->read_timeout );
+        }
+
+        if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+        {
+            if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
+                return( 0 );
+
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+            return( ret );
+        }
+
+        if( ssl->in_msglen  == 0 &&
+            ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA )
+        {
+            /*
+             * OpenSSL sends empty messages to randomize the IV
+             */
+            if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+            {
+                if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
+                    return( 0 );
+
+                MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+                return( ret );
+            }
+        }
+
+        if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
+
+            /*
+             * - For client-side, expect SERVER_HELLO_REQUEST.
+             * - For server-side, expect CLIENT_HELLO.
+             * - Fail (TLS) or silently drop record (DTLS) in other cases.
+             */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+            if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+                ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
+                  ssl->in_hslen  != mbedtls_ssl_hs_hdr_len( ssl ) ) )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
+
+                /* With DTLS, drop the packet (probably from last handshake) */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+                if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+                {
+                    continue;
+                }
+#endif
+                return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+            }
+#endif /* MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_SSL_SRV_C)
+            if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+                ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
+            {
+                MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
+
+                /* With DTLS, drop the packet (probably from last handshake) */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+                if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+                {
+                    continue;
+                }
+#endif
+                return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+            }
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+            /* Determine whether renegotiation attempt should be accepted */
+            if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
+                    ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
+                      ssl->conf->allow_legacy_renegotiation ==
+                                                   MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) )
+            {
+                /*
+                 * Accept renegotiation request
+                 */
+
+                /* DTLS clients need to know renego is server-initiated */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+                if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+                    ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+                {
+                    ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
+                }
+#endif
+                ret = ssl_start_renegotiation( ssl );
+                if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+                    ret != 0 )
+                {
+                    MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
+                    return( ret );
+                }
+            }
+            else
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+            {
+                /*
+                 * Refuse renegotiation
+                 */
+
+                MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+                if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+                {
+                    /* SSLv3 does not have a "no_renegotiation" warning, so
+                       we send a fatal alert and abort the connection. */
+                    mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                                    MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+                    return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+                }
+                else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+                if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+                {
+                    if( ( ret = mbedtls_ssl_send_alert_message( ssl,
+                                    MBEDTLS_SSL_ALERT_LEVEL_WARNING,
+                                    MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
+                    {
+                        return( ret );
+                    }
+                }
+                else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
+          MBEDTLS_SSL_PROTO_TLS1_2 */
+                {
+                    MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+                    return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+                }
+            }
+
+            /* At this point, we don't know whether the renegotiation has been
+             * completed or not. The cases to consider are the following:
+             * 1) The renegotiation is complete. In this case, no new record
+             *    has been read yet.
+             * 2) The renegotiation is incomplete because the client received
+             *    an application data record while awaiting the ServerHello.
+             * 3) The renegotiation is incomplete because the client received
+             *    a non-handshake, non-application data message while awaiting
+             *    the ServerHello.
+             * In each of these case, looping will be the proper action:
+             * - For 1), the next iteration will read a new record and check
+             *   if it's application data.
+             * - For 2), the loop condition isn't satisfied as application data
+             *   is present, hence continue is the same as break
+             * - For 3), the loop condition is satisfied and read_record
+             *   will re-deliver the message that was held back by the client
+             *   when expecting the ServerHello.
+             */
+            continue;
+        }
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+        else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
+        {
+            if( ssl->conf->renego_max_records >= 0 )
+            {
+                if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
+                {
+                    MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
+                                        "but not honored by client" ) );
+                    return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+                }
+            }
+        }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+        /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
+        if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+        }
+
+        if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
+            return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+        }
+
+        ssl->in_offt = ssl->in_msg;
+
+        /* We're going to return something now, cancel timer,
+         * except if handshake (renegotiation) is in progress */
+        if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+            ssl_set_timer( ssl, 0 );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+        /* If we requested renego but received AppData, resend HelloRequest.
+         * Do it now, after setting in_offt, to avoid taking this branch
+         * again if ssl_write_hello_request() returns WANT_WRITE */
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
+        if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+            ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
+        {
+            if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
+            {
+                MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
+                return( ret );
+            }
+        }
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+    }
+
+    n = ( len < ssl->in_msglen )
+        ? len : ssl->in_msglen;
+
+    memcpy( buf, ssl->in_offt, n );
+    ssl->in_msglen -= n;
+
+    if( ssl->in_msglen == 0 )
+    {
+        /* all bytes consumed */
+        ssl->in_offt = NULL;
+        ssl->keep_current_message = 0;
+    }
+    else
+    {
+        /* more data available */
+        ssl->in_offt += n;
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
+
+    return( (int) n );
+}
+
+/*
+ * Send application data to be encrypted by the SSL layer, taking care of max
+ * fragment length and buffer size.
+ *
+ * According to RFC 5246 Section 6.2.1:
+ *
+ *      Zero-length fragments of Application data MAY be sent as they are
+ *      potentially useful as a traffic analysis countermeasure.
+ *
+ * Therefore, it is possible that the input message length is 0 and the
+ * corresponding return code is 0 on success.
+ */
+static int ssl_write_real( mbedtls_ssl_context *ssl,
+                           const unsigned char *buf, size_t len )
+{
+    int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
+    const size_t max_len = (size_t) ret;
+
+    if( ret < 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret );
+        return( ret );
+    }
+
+    if( len > max_len )
+    {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+        if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+        {
+            MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
+                                "maximum fragment length: %d > %d",
+                                len, max_len ) );
+            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+        }
+        else
+#endif
+            len = max_len;
+    }
+
+    if( ssl->out_left != 0 )
+    {
+        /*
+         * The user has previously tried to send the data and
+         * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
+         * written. In this case, we expect the high-level write function
+         * (e.g. mbedtls_ssl_write()) to be called with the same parameters
+         */
+        if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
+            return( ret );
+        }
+    }
+    else
+    {
+        /*
+         * The user is trying to send a message the first time, so we need to
+         * copy the data into the internal buffers and setup the data structure
+         * to keep track of partial writes
+         */
+        ssl->out_msglen  = len;
+        ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
+        memcpy( ssl->out_msg, buf, len );
+
+        if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+            return( ret );
+        }
+    }
+
+    return( (int) len );
+}
+
+/*
+ * Write application data, doing 1/n-1 splitting if necessary.
+ *
+ * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
+ * then the caller will call us again with the same arguments, so
+ * remember whether we already did the split or not.
+ */
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+static int ssl_write_split( mbedtls_ssl_context *ssl,
+                            const unsigned char *buf, size_t len )
+{
+    int ret;
+
+    if( ssl->conf->cbc_record_splitting ==
+            MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
+        len <= 1 ||
+        ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
+        mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
+                                != MBEDTLS_MODE_CBC )
+    {
+        return( ssl_write_real( ssl, buf, len ) );
+    }
+
+    if( ssl->split_done == 0 )
+    {
+        if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 )
+            return( ret );
+        ssl->split_done = 1;
+    }
+
+    if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 )
+        return( ret );
+    ssl->split_done = 0;
+
+    return( ret + 1 );
+}
+#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
+
+/*
+ * Write application data (public-facing wrapper)
+ */
+int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
+{
+    int ret;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
+
+    if( ssl == NULL || ssl->conf == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+        return( ret );
+    }
+#endif
+
+    if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+    {
+        if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
+            return( ret );
+        }
+    }
+
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+    ret = ssl_write_split( ssl, buf, len );
+#else
+    ret = ssl_write_real( ssl, buf, len );
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
+
+    return( ret );
+}
+
+/*
+ * Notify the peer that the connection is being closed
+ */
+int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
+{
+    int ret;
+
+    if( ssl == NULL || ssl->conf == NULL )
+        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
+
+    if( ssl->out_left != 0 )
+        return( mbedtls_ssl_flush_output( ssl ) );
+
+    if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+    {
+        if( ( ret = mbedtls_ssl_send_alert_message( ssl,
+                        MBEDTLS_SSL_ALERT_LEVEL_WARNING,
+                        MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
+        {
+            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret );
+            return( ret );
+        }
+    }
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
+
+    return( 0 );
+}
+
+void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
+{
+    if( transform == NULL )
+        return;
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    deflateEnd( &transform->ctx_deflate );
+    inflateEnd( &transform->ctx_inflate );
+#endif
+
+    mbedtls_cipher_free( &transform->cipher_ctx_enc );
+    mbedtls_cipher_free( &transform->cipher_ctx_dec );
+
+    mbedtls_md_free( &transform->md_ctx_enc );
+    mbedtls_md_free( &transform->md_ctx_dec );
+
+    mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
+}
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert )
+{
+    mbedtls_ssl_key_cert *cur = key_cert, *next;
+
+    while( cur != NULL )
+    {
+        next = cur->next;
+        mbedtls_free( cur );
+        cur = next;
+    }
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+static void ssl_buffering_free( mbedtls_ssl_context *ssl )
+{
+    unsigned offset;
+    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+    if( hs == NULL )
+        return;
+
+    ssl_free_buffered_record( ssl );
+
+    for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
+        ssl_buffering_free_slot( ssl, offset );
+}
+
+static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
+                                     uint8_t slot )
+{
+    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+    mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
+
+    if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS )
+        return;
+
+    if( hs_buf->is_valid == 1 )
+    {
+        hs->buffering.total_bytes_buffered -= hs_buf->data_len;
+        mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len );
+        mbedtls_free( hs_buf->data );
+        memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
+    }
+}
+
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
+{
+    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+    if( handshake == NULL )
+        return;
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+    if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 )
+    {
+        ssl->conf->f_async_cancel( ssl );
+        handshake->async_in_progress = 0;
+    }
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+    mbedtls_md5_free(    &handshake->fin_md5  );
+    mbedtls_sha1_free(   &handshake->fin_sha1 );
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+    mbedtls_sha256_free(   &handshake->fin_sha256    );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+    mbedtls_sha512_free(   &handshake->fin_sha512    );
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#if defined(MBEDTLS_DHM_C)
+    mbedtls_dhm_free( &handshake->dhm_ctx );
+#endif
+#if defined(MBEDTLS_ECDH_C)
+    mbedtls_ecdh_free( &handshake->ecdh_ctx );
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
+#if defined(MBEDTLS_SSL_CLI_C)
+    mbedtls_free( handshake->ecjpake_cache );
+    handshake->ecjpake_cache = NULL;
+    handshake->ecjpake_cache_len = 0;
+#endif
+#endif
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    /* explicit void pointer cast for buggy MS compiler */
+    mbedtls_free( (void *) handshake->curves );
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    if( handshake->psk != NULL )
+    {
+        mbedtls_platform_zeroize( handshake->psk, handshake->psk_len );
+        mbedtls_free( handshake->psk );
+    }
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+    defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    /*
+     * Free only the linked list wrapper, not the keys themselves
+     * since the belong to the SNI callback
+     */
+    if( handshake->sni_key_cert != NULL )
+    {
+        mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next;
+
+        while( cur != NULL )
+        {
+            next = cur->next;
+            mbedtls_free( cur );
+            cur = next;
+        }
+    }
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */
+
+#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+    mbedtls_x509_crt_restart_free( &handshake->ecrs_ctx );
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    mbedtls_free( handshake->verify_cookie );
+    ssl_flight_free( handshake->flight );
+    ssl_buffering_free( ssl );
+#endif
+
+    mbedtls_platform_zeroize( handshake,
+                              sizeof( mbedtls_ssl_handshake_params ) );
+}
+
+void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
+{
+    if( session == NULL )
+        return;
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    if( session->peer_cert != NULL )
+    {
+        mbedtls_x509_crt_free( session->peer_cert );
+        mbedtls_free( session->peer_cert );
+    }
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+    mbedtls_free( session->ticket );
+#endif
+
+    mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) );
+}
+
+/*
+ * Free an SSL context
+ */
+void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
+{
+    if( ssl == NULL )
+        return;
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> free" ) );
+
+    if( ssl->out_buf != NULL )
+    {
+        mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN );
+        mbedtls_free( ssl->out_buf );
+    }
+
+    if( ssl->in_buf != NULL )
+    {
+        mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN );
+        mbedtls_free( ssl->in_buf );
+    }
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    if( ssl->compress_buf != NULL )
+    {
+        mbedtls_platform_zeroize( ssl->compress_buf, MBEDTLS_SSL_COMPRESS_BUFFER_LEN );
+        mbedtls_free( ssl->compress_buf );
+    }
+#endif
+
+    if( ssl->transform )
+    {
+        mbedtls_ssl_transform_free( ssl->transform );
+        mbedtls_free( ssl->transform );
+    }
+
+    if( ssl->handshake )
+    {
+        mbedtls_ssl_handshake_free( ssl );
+        mbedtls_ssl_transform_free( ssl->transform_negotiate );
+        mbedtls_ssl_session_free( ssl->session_negotiate );
+
+        mbedtls_free( ssl->handshake );
+        mbedtls_free( ssl->transform_negotiate );
+        mbedtls_free( ssl->session_negotiate );
+    }
+
+    if( ssl->session )
+    {
+        mbedtls_ssl_session_free( ssl->session );
+        mbedtls_free( ssl->session );
+    }
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    if( ssl->hostname != NULL )
+    {
+        mbedtls_platform_zeroize( ssl->hostname, strlen( ssl->hostname ) );
+        mbedtls_free( ssl->hostname );
+    }
+#endif
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+    if( mbedtls_ssl_hw_record_finish != NULL )
+    {
+        MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_finish()" ) );
+        mbedtls_ssl_hw_record_finish( ssl );
+    }
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+    mbedtls_free( ssl->cli_id );
+#endif
+
+    MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) );
+
+    /* Actually clear after last debug message */
+    mbedtls_platform_zeroize( ssl, sizeof( mbedtls_ssl_context ) );
+}
+
+/*
+ * Initialze mbedtls_ssl_config
+ */
+void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
+{
+    memset( conf, 0, sizeof( mbedtls_ssl_config ) );
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+static int ssl_preset_default_hashes[] = {
+#if defined(MBEDTLS_SHA512_C)
+    MBEDTLS_MD_SHA512,
+    MBEDTLS_MD_SHA384,
+#endif
+#if defined(MBEDTLS_SHA256_C)
+    MBEDTLS_MD_SHA256,
+    MBEDTLS_MD_SHA224,
+#endif
+#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE)
+    MBEDTLS_MD_SHA1,
+#endif
+    MBEDTLS_MD_NONE
+};
+#endif
+
+static int ssl_preset_suiteb_ciphersuites[] = {
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+    0
+};
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+static int ssl_preset_suiteb_hashes[] = {
+    MBEDTLS_MD_SHA256,
+    MBEDTLS_MD_SHA384,
+    MBEDTLS_MD_NONE
+};
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = {
+    MBEDTLS_ECP_DP_SECP256R1,
+    MBEDTLS_ECP_DP_SECP384R1,
+    MBEDTLS_ECP_DP_NONE
+};
+#endif
+
+/*
+ * Load default in mbedtls_ssl_config
+ */
+int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
+                                 int endpoint, int transport, int preset )
+{
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
+    int ret;
+#endif
+
+    /* Use the functions here so that they are covered in tests,
+     * but otherwise access member directly for efficiency */
+    mbedtls_ssl_conf_endpoint( conf, endpoint );
+    mbedtls_ssl_conf_transport( conf, transport );
+
+    /*
+     * Things that are common to all presets
+     */
+#if defined(MBEDTLS_SSL_CLI_C)
+    if( endpoint == MBEDTLS_SSL_IS_CLIENT )
+    {
+        conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+        conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED;
+#endif
+    }
+#endif
+
+#if defined(MBEDTLS_ARC4_C)
+    conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED;
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
+#endif
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
+#endif
+
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+    conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED;
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C)
+    conf->f_cookie_write = ssl_cookie_write_dummy;
+    conf->f_cookie_check = ssl_cookie_check_dummy;
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+    conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED;
+#endif
+
+#if defined(MBEDTLS_SSL_SRV_C)
+    conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED;
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN;
+    conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX;
+#endif
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT;
+    memset( conf->renego_period,     0x00, 2 );
+    memset( conf->renego_period + 2, 0xFF, 6 );
+#endif
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
+            if( endpoint == MBEDTLS_SSL_IS_SERVER )
+            {
+                const unsigned char dhm_p[] =
+                    MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN;
+                const unsigned char dhm_g[] =
+                    MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN;
+
+                if ( ( ret = mbedtls_ssl_conf_dh_param_bin( conf,
+                                               dhm_p, sizeof( dhm_p ),
+                                               dhm_g, sizeof( dhm_g ) ) ) != 0 )
+                {
+                    return( ret );
+                }
+            }
+#endif
+
+    /*
+     * Preset-specific defaults
+     */
+    switch( preset )
+    {
+        /*
+         * NSA Suite B
+         */
+        case MBEDTLS_SSL_PRESET_SUITEB:
+            conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
+            conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */
+            conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
+            conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
+
+            conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
+            conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
+            conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
+            conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
+                                   ssl_preset_suiteb_ciphersuites;
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+            conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+            conf->sig_hashes = ssl_preset_suiteb_hashes;
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+            conf->curve_list = ssl_preset_suiteb_curves;
+#endif
+            break;
+
+        /*
+         * Default
+         */
+        default:
+            conf->min_major_ver = ( MBEDTLS_SSL_MIN_MAJOR_VERSION >
+                                    MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION ) ?
+                                    MBEDTLS_SSL_MIN_MAJOR_VERSION :
+                                    MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION;
+            conf->min_minor_ver = ( MBEDTLS_SSL_MIN_MINOR_VERSION >
+                                    MBEDTLS_SSL_MIN_VALID_MINOR_VERSION ) ?
+                                    MBEDTLS_SSL_MIN_MINOR_VERSION :
+                                    MBEDTLS_SSL_MIN_VALID_MINOR_VERSION;
+            conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
+            conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+            if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+                conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2;
+#endif
+
+            conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] =
+            conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] =
+            conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] =
+            conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] =
+                                   mbedtls_ssl_list_ciphersuites();
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+            conf->cert_profile = &mbedtls_x509_crt_profile_default;
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+            conf->sig_hashes = ssl_preset_default_hashes;
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+            conf->curve_list = mbedtls_ecp_grp_id_list();
+#endif
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
+            conf->dhm_min_bitlen = 1024;
+#endif
+    }
+
+    return( 0 );
+}
+
+/*
+ * Free mbedtls_ssl_config
+ */
+void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
+{
+#if defined(MBEDTLS_DHM_C)
+    mbedtls_mpi_free( &conf->dhm_P );
+    mbedtls_mpi_free( &conf->dhm_G );
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    if( conf->psk != NULL )
+    {
+        mbedtls_platform_zeroize( conf->psk, conf->psk_len );
+        mbedtls_free( conf->psk );
+        conf->psk = NULL;
+        conf->psk_len = 0;
+    }
+
+    if( conf->psk_identity != NULL )
+    {
+        mbedtls_platform_zeroize( conf->psk_identity, conf->psk_identity_len );
+        mbedtls_free( conf->psk_identity );
+        conf->psk_identity = NULL;
+        conf->psk_identity_len = 0;
+    }
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    ssl_key_cert_free( conf->key_cert );
+#endif
+
+    mbedtls_platform_zeroize( conf, sizeof( mbedtls_ssl_config ) );
+}
+
+#if defined(MBEDTLS_PK_C) && \
+    ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) )
+/*
+ * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX
+ */
+unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk )
+{
+#if defined(MBEDTLS_RSA_C)
+    if( mbedtls_pk_can_do( pk, MBEDTLS_PK_RSA ) )
+        return( MBEDTLS_SSL_SIG_RSA );
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+    if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECDSA ) )
+        return( MBEDTLS_SSL_SIG_ECDSA );
+#endif
+    return( MBEDTLS_SSL_SIG_ANON );
+}
+
+unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type )
+{
+    switch( type ) {
+        case MBEDTLS_PK_RSA:
+            return( MBEDTLS_SSL_SIG_RSA );
+        case MBEDTLS_PK_ECDSA:
+        case MBEDTLS_PK_ECKEY:
+            return( MBEDTLS_SSL_SIG_ECDSA );
+        default:
+            return( MBEDTLS_SSL_SIG_ANON );
+    }
+}
+
+mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig )
+{
+    switch( sig )
+    {
+#if defined(MBEDTLS_RSA_C)
+        case MBEDTLS_SSL_SIG_RSA:
+            return( MBEDTLS_PK_RSA );
+#endif
+#if defined(MBEDTLS_ECDSA_C)
+        case MBEDTLS_SSL_SIG_ECDSA:
+            return( MBEDTLS_PK_ECDSA );
+#endif
+        default:
+            return( MBEDTLS_PK_NONE );
+    }
+}
+#endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+
+/* Find an entry in a signature-hash set matching a given hash algorithm. */
+mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
+                                                 mbedtls_pk_type_t sig_alg )
+{
+    switch( sig_alg )
+    {
+        case MBEDTLS_PK_RSA:
+            return( set->rsa );
+        case MBEDTLS_PK_ECDSA:
+            return( set->ecdsa );
+        default:
+            return( MBEDTLS_MD_NONE );
+    }
+}
+
+/* Add a signature-hash-pair to a signature-hash set */
+void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set,
+                                   mbedtls_pk_type_t sig_alg,
+                                   mbedtls_md_type_t md_alg )
+{
+    switch( sig_alg )
+    {
+        case MBEDTLS_PK_RSA:
+            if( set->rsa == MBEDTLS_MD_NONE )
+                set->rsa = md_alg;
+            break;
+
+        case MBEDTLS_PK_ECDSA:
+            if( set->ecdsa == MBEDTLS_MD_NONE )
+                set->ecdsa = md_alg;
+            break;
+
+        default:
+            break;
+    }
+}
+
+/* Allow exactly one hash algorithm for each signature. */
+void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
+                                          mbedtls_md_type_t md_alg )
+{
+    set->rsa   = md_alg;
+    set->ecdsa = md_alg;
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
+          MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+/*
+ * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
+ */
+mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash )
+{
+    switch( hash )
+    {
+#if defined(MBEDTLS_MD5_C)
+        case MBEDTLS_SSL_HASH_MD5:
+            return( MBEDTLS_MD_MD5 );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+        case MBEDTLS_SSL_HASH_SHA1:
+            return( MBEDTLS_MD_SHA1 );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+        case MBEDTLS_SSL_HASH_SHA224:
+            return( MBEDTLS_MD_SHA224 );
+        case MBEDTLS_SSL_HASH_SHA256:
+            return( MBEDTLS_MD_SHA256 );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+        case MBEDTLS_SSL_HASH_SHA384:
+            return( MBEDTLS_MD_SHA384 );
+        case MBEDTLS_SSL_HASH_SHA512:
+            return( MBEDTLS_MD_SHA512 );
+#endif
+        default:
+            return( MBEDTLS_MD_NONE );
+    }
+}
+
+/*
+ * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX
+ */
+unsigned char mbedtls_ssl_hash_from_md_alg( int md )
+{
+    switch( md )
+    {
+#if defined(MBEDTLS_MD5_C)
+        case MBEDTLS_MD_MD5:
+            return( MBEDTLS_SSL_HASH_MD5 );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+        case MBEDTLS_MD_SHA1:
+            return( MBEDTLS_SSL_HASH_SHA1 );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+        case MBEDTLS_MD_SHA224:
+            return( MBEDTLS_SSL_HASH_SHA224 );
+        case MBEDTLS_MD_SHA256:
+            return( MBEDTLS_SSL_HASH_SHA256 );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+        case MBEDTLS_MD_SHA384:
+            return( MBEDTLS_SSL_HASH_SHA384 );
+        case MBEDTLS_MD_SHA512:
+            return( MBEDTLS_SSL_HASH_SHA512 );
+#endif
+        default:
+            return( MBEDTLS_SSL_HASH_NONE );
+    }
+}
+
+#if defined(MBEDTLS_ECP_C)
+/*
+ * Check if a curve proposed by the peer is in our list.
+ * Return 0 if we're willing to use it, -1 otherwise.
+ */
+int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id )
+{
+    const mbedtls_ecp_group_id *gid;
+
+    if( ssl->conf->curve_list == NULL )
+        return( -1 );
+
+    for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
+        if( *gid == grp_id )
+            return( 0 );
+
+    return( -1 );
+}
+#endif /* MBEDTLS_ECP_C */
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+/*
+ * Check if a hash proposed by the peer is in our list.
+ * Return 0 if we're willing to use it, -1 otherwise.
+ */
+int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
+                                mbedtls_md_type_t md )
+{
+    const int *cur;
+
+    if( ssl->conf->sig_hashes == NULL )
+        return( -1 );
+
+    for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ )
+        if( *cur == (int) md )
+            return( 0 );
+
+    return( -1 );
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
+                          const mbedtls_ssl_ciphersuite_t *ciphersuite,
+                          int cert_endpoint,
+                          uint32_t *flags )
+{
+    int ret = 0;
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
+    int usage = 0;
+#endif
+#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
+    const char *ext_oid;
+    size_t ext_len;
+#endif
+
+#if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) &&          \
+    !defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
+    ((void) cert);
+    ((void) cert_endpoint);
+    ((void) flags);
+#endif
+
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
+    if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        /* Server part of the key exchange */
+        switch( ciphersuite->key_exchange )
+        {
+            case MBEDTLS_KEY_EXCHANGE_RSA:
+            case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
+                usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT;
+                break;
+
+            case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+            case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+            case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+                usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
+                break;
+
+            case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+            case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+                usage = MBEDTLS_X509_KU_KEY_AGREEMENT;
+                break;
+
+            /* Don't use default: we want warnings when adding new values */
+            case MBEDTLS_KEY_EXCHANGE_NONE:
+            case MBEDTLS_KEY_EXCHANGE_PSK:
+            case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
+            case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
+            case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
+                usage = 0;
+        }
+    }
+    else
+    {
+        /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */
+        usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
+    }
+
+    if( mbedtls_x509_crt_check_key_usage( cert, usage ) != 0 )
+    {
+        *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE;
+        ret = -1;
+    }
+#else
+    ((void) ciphersuite);
+#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
+
+#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
+    if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
+    {
+        ext_oid = MBEDTLS_OID_SERVER_AUTH;
+        ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH );
+    }
+    else
+    {
+        ext_oid = MBEDTLS_OID_CLIENT_AUTH;
+        ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH );
+    }
+
+    if( mbedtls_x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 )
+    {
+        *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE;
+        ret = -1;
+    }
+#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
+
+    return( ret );
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+/*
+ * Convert version numbers to/from wire format
+ * and, for DTLS, to/from TLS equivalent.
+ *
+ * For TLS this is the identity.
+ * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
+ * 1.0 <-> 3.2      (DTLS 1.0 is based on TLS 1.1)
+ * 1.x <-> 3.x+1    for x != 0 (DTLS 1.2 based on TLS 1.2)
+ */
+void mbedtls_ssl_write_version( int major, int minor, int transport,
+                        unsigned char ver[2] )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
+            --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
+
+        ver[0] = (unsigned char)( 255 - ( major - 2 ) );
+        ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
+    }
+    else
+#else
+    ((void) transport);
+#endif
+    {
+        ver[0] = (unsigned char) major;
+        ver[1] = (unsigned char) minor;
+    }
+}
+
+void mbedtls_ssl_read_version( int *major, int *minor, int transport,
+                       const unsigned char ver[2] )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        *major = 255 - ver[0] + 2;
+        *minor = 255 - ver[1] + 1;
+
+        if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
+            ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
+    }
+    else
+#else
+    ((void) transport);
+#endif
+    {
+        *major = ver[0];
+        *minor = ver[1];
+    }
+}
+
+int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
+{
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
+        return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
+
+    switch( md )
+    {
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+#if defined(MBEDTLS_MD5_C)
+        case MBEDTLS_SSL_HASH_MD5:
+            return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+        case MBEDTLS_SSL_HASH_SHA1:
+            ssl->handshake->calc_verify = ssl_calc_verify_tls;
+            break;
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
+#if defined(MBEDTLS_SHA512_C)
+        case MBEDTLS_SSL_HASH_SHA384:
+            ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384;
+            break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+        case MBEDTLS_SSL_HASH_SHA256:
+            ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256;
+            break;
+#endif
+        default:
+            return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
+    }
+
+    return 0;
+#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */
+    (void) ssl;
+    (void) md;
+
+    return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+}
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_1)
+int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
+                                        unsigned char *output,
+                                        unsigned char *data, size_t data_len )
+{
+    int ret = 0;
+    mbedtls_md5_context mbedtls_md5;
+    mbedtls_sha1_context mbedtls_sha1;
+
+    mbedtls_md5_init( &mbedtls_md5 );
+    mbedtls_sha1_init( &mbedtls_sha1 );
+
+    /*
+     * digitally-signed struct {
+     *     opaque md5_hash[16];
+     *     opaque sha_hash[20];
+     * };
+     *
+     * md5_hash
+     *     MD5(ClientHello.random + ServerHello.random
+     *                            + ServerParams);
+     * sha_hash
+     *     SHA(ClientHello.random + ServerHello.random
+     *                            + ServerParams);
+     */
+    if( ( ret = mbedtls_md5_starts_ret( &mbedtls_md5 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_starts_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5,
+                                        ssl->handshake->randbytes, 64 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md5_update_ret( &mbedtls_md5, data, data_len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_update_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md5_finish_ret( &mbedtls_md5, output ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md5_finish_ret", ret );
+        goto exit;
+    }
+
+    if( ( ret = mbedtls_sha1_starts_ret( &mbedtls_sha1 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_starts_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1,
+                                         ssl->handshake->randbytes, 64 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_sha1_update_ret( &mbedtls_sha1, data,
+                                         data_len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_update_ret", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_sha1_finish_ret( &mbedtls_sha1,
+                                         output + 16 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_sha1_finish_ret", ret );
+        goto exit;
+    }
+
+exit:
+    mbedtls_md5_free( &mbedtls_md5 );
+    mbedtls_sha1_free( &mbedtls_sha1 );
+
+    if( ret != 0 )
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+    return( ret );
+
+}
+#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \
+          MBEDTLS_SSL_PROTO_TLS1_1 */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+    defined(MBEDTLS_SSL_PROTO_TLS1_2)
+int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
+                                            unsigned char *hash, size_t *hashlen,
+                                            unsigned char *data, size_t data_len,
+                                            mbedtls_md_type_t md_alg )
+{
+    int ret = 0;
+    mbedtls_md_context_t ctx;
+    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
+    *hashlen = mbedtls_md_get_size( md_info );
+
+    mbedtls_md_init( &ctx );
+
+    /*
+     * digitally-signed struct {
+     *     opaque client_random[32];
+     *     opaque server_random[32];
+     *     ServerDHParams params;
+     * };
+     */
+    if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_starts", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_update( &ctx, data, data_len ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
+        goto exit;
+    }
+    if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 )
+    {
+        MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret );
+        goto exit;
+    }
+
+exit:
+    mbedtls_md_free( &ctx );
+
+    if( ret != 0 )
+        mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+    return( ret );
+}
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+          MBEDTLS_SSL_PROTO_TLS1_2 */
+
+#endif /* MBEDTLS_SSL_TLS_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/threading.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/threading.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/threading.c	(revision 398)
@@ -0,0 +1,187 @@
+/*
+ *  Threading abstraction layer
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ * Ensure gmtime_r is available even with -std=c99; must be defined before
+ * config.h, which pulls in glibc's features.h. Harmless on other platforms.
+ */
+#if !defined(_POSIX_C_SOURCE)
+#define _POSIX_C_SOURCE 200112L
+#endif
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+
+#include "mbedtls/threading.h"
+
+#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
+
+#if !defined(_WIN32) && (defined(unix) || \
+    defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
+    defined(__MACH__)))
+#include <unistd.h>
+#endif /* !_WIN32 && (unix || __unix || __unix__ ||
+        * (__APPLE__ && __MACH__)) */
+
+#if !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
+       ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
+         _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) )
+/*
+ * This is a convenience shorthand macro to avoid checking the long
+ * preprocessor conditions above. Ideally, we could expose this macro in
+ * platform_util.h and simply use it in platform_util.c, threading.c and
+ * threading.h. However, this macro is not part of the Mbed TLS public API, so
+ * we keep it private by only defining it in this file
+ */
+
+#if ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) )
+#define THREADING_USE_GMTIME
+#endif /* ! ( defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) ) */
+
+#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) ||     \
+             ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) &&                     \
+                _POSIX_THREAD_SAFE_FUNCTIONS >= 20112L ) ) */
+
+#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
+{
+    if( mutex == NULL )
+        return;
+
+    mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
+}
+
+static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex )
+{
+    if( mutex == NULL || !mutex->is_valid )
+        return;
+
+    (void) pthread_mutex_destroy( &mutex->mutex );
+    mutex->is_valid = 0;
+}
+
+static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex )
+{
+    if( mutex == NULL || ! mutex->is_valid )
+        return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
+
+    if( pthread_mutex_lock( &mutex->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+
+    return( 0 );
+}
+
+static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex )
+{
+    if( mutex == NULL || ! mutex->is_valid )
+        return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
+
+    if( pthread_mutex_unlock( &mutex->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+
+    return( 0 );
+}
+
+void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread;
+void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread;
+int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread;
+int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread;
+
+/*
+ * With phtreads we can statically initialize mutexes
+ */
+#define MUTEX_INIT  = { PTHREAD_MUTEX_INITIALIZER, 1 }
+
+#endif /* MBEDTLS_THREADING_PTHREAD */
+
+#if defined(MBEDTLS_THREADING_ALT)
+static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex )
+{
+    ((void) mutex );
+    return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
+}
+static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex )
+{
+    ((void) mutex );
+    return;
+}
+
+void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy;
+void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy;
+int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail;
+int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail;
+
+/*
+ * Set functions pointers and initialize global mutexes
+ */
+void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ),
+                       void (*mutex_free)( mbedtls_threading_mutex_t * ),
+                       int (*mutex_lock)( mbedtls_threading_mutex_t * ),
+                       int (*mutex_unlock)( mbedtls_threading_mutex_t * ) )
+{
+    mbedtls_mutex_init = mutex_init;
+    mbedtls_mutex_free = mutex_free;
+    mbedtls_mutex_lock = mutex_lock;
+    mbedtls_mutex_unlock = mutex_unlock;
+
+#if defined(MBEDTLS_FS_IO)
+    mbedtls_mutex_init( &mbedtls_threading_readdir_mutex );
+#endif
+#if defined(THREADING_USE_GMTIME)
+    mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex );
+#endif
+}
+
+/*
+ * Free global mutexes
+ */
+void mbedtls_threading_free_alt( void )
+{
+#if defined(MBEDTLS_FS_IO)
+    mbedtls_mutex_free( &mbedtls_threading_readdir_mutex );
+#endif
+#if defined(THREADING_USE_GMTIME)
+    mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex );
+#endif
+}
+#endif /* MBEDTLS_THREADING_ALT */
+
+/*
+ * Define global mutexes
+ */
+#ifndef MUTEX_INIT
+#define MUTEX_INIT
+#endif
+#if defined(MBEDTLS_FS_IO)
+mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT;
+#endif
+#if defined(THREADING_USE_GMTIME)
+mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT;
+#endif
+
+#endif /* MBEDTLS_THREADING_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/timing.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/timing.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/timing.c	(revision 398)
@@ -0,0 +1,537 @@
+/*
+ *  Portable interface to the CPU cycle counter
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf     printf
+#endif
+
+#if defined(MBEDTLS_TIMING_C)
+
+#include "mbedtls/timing.h"
+
+#if !defined(MBEDTLS_TIMING_ALT)
+
+#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
+    !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
+    !defined(__HAIKU__)
+#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h"
+#endif
+
+#ifndef asm
+#define asm __asm
+#endif
+
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+
+#include <windows.h>
+#include <winbase.h>
+#include <process.h>
+
+struct _hr_time
+{
+    LARGE_INTEGER start;
+};
+
+#else
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <time.h>
+
+struct _hr_time
+{
+    struct timeval start;
+};
+
+#endif /* _WIN32 && !EFIX64 && !EFI32 */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__)
+
+#define HAVE_HARDCLOCK
+
+unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long tsc;
+    __asm   rdtsc
+    __asm   mov  [tsc], eax
+    return( tsc );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */
+
+/* some versions of mingw-64 have 32-bit longs even on x84_64 */
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    defined(__GNUC__) && ( defined(__i386__) || (                       \
+    ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) )
+
+#define HAVE_HARDCLOCK
+
+unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long lo, hi;
+    asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
+    return( lo );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && __i386__ */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) )
+
+#define HAVE_HARDCLOCK
+
+unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long lo, hi;
+    asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) );
+    return( lo | ( hi << 32 ) );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && ( __amd64__ || __x86_64__ ) */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) )
+
+#define HAVE_HARDCLOCK
+
+unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long tbl, tbu0, tbu1;
+
+    do
+    {
+        asm volatile( "mftbu %0" : "=r" (tbu0) );
+        asm volatile( "mftb  %0" : "=r" (tbl ) );
+        asm volatile( "mftbu %0" : "=r" (tbu1) );
+    }
+    while( tbu0 != tbu1 );
+
+    return( tbl );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && ( __powerpc__ || __ppc__ ) */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    defined(__GNUC__) && defined(__sparc64__)
+
+#if defined(__OpenBSD__)
+#warning OpenBSD does not allow access to tick register using software version instead
+#else
+#define HAVE_HARDCLOCK
+
+unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long tick;
+    asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) );
+    return( tick );
+}
+#endif /* __OpenBSD__ */
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && __sparc64__ */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
+    defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__)
+
+#define HAVE_HARDCLOCK
+
+unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long tick;
+    asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" );
+    asm volatile( "mov   %%g1, %0" : "=r" (tick) );
+    return( tick );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && __sparc__ && !__sparc64__ */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&      \
+    defined(__GNUC__) && defined(__alpha__)
+
+#define HAVE_HARDCLOCK
+
+unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long cc;
+    asm volatile( "rpcc %0" : "=r" (cc) );
+    return( cc & 0xFFFFFFFF );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && __alpha__ */
+
+#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&      \
+    defined(__GNUC__) && defined(__ia64__)
+
+#define HAVE_HARDCLOCK
+
+unsigned long mbedtls_timing_hardclock( void )
+{
+    unsigned long itc;
+    asm volatile( "mov %0 = ar.itc" : "=r" (itc) );
+    return( itc );
+}
+#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
+          __GNUC__ && __ia64__ */
+
+#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \
+    !defined(EFIX64) && !defined(EFI32)
+
+#define HAVE_HARDCLOCK
+
+unsigned long mbedtls_timing_hardclock( void )
+{
+    LARGE_INTEGER offset;
+
+    QueryPerformanceCounter( &offset );
+
+    return( (unsigned long)( offset.QuadPart ) );
+}
+#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */
+
+#if !defined(HAVE_HARDCLOCK)
+
+#define HAVE_HARDCLOCK
+
+static int hardclock_init = 0;
+static struct timeval tv_init;
+
+unsigned long mbedtls_timing_hardclock( void )
+{
+    struct timeval tv_cur;
+
+    if( hardclock_init == 0 )
+    {
+        gettimeofday( &tv_init, NULL );
+        hardclock_init = 1;
+    }
+
+    gettimeofday( &tv_cur, NULL );
+    return( ( tv_cur.tv_sec  - tv_init.tv_sec  ) * 1000000
+          + ( tv_cur.tv_usec - tv_init.tv_usec ) );
+}
+#endif /* !HAVE_HARDCLOCK */
+
+volatile int mbedtls_timing_alarmed = 0;
+
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+
+unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
+{
+    struct _hr_time *t = (struct _hr_time *) val;
+
+    if( reset )
+    {
+        QueryPerformanceCounter( &t->start );
+        return( 0 );
+    }
+    else
+    {
+        unsigned long delta;
+        LARGE_INTEGER now, hfreq;
+        QueryPerformanceCounter(  &now );
+        QueryPerformanceFrequency( &hfreq );
+        delta = (unsigned long)( ( now.QuadPart - t->start.QuadPart ) * 1000ul
+                                 / hfreq.QuadPart );
+        return( delta );
+    }
+}
+
+/* It's OK to use a global because alarm() is supposed to be global anyway */
+static DWORD alarmMs;
+
+static void TimerProc( void *TimerContext )
+{
+    (void) TimerContext;
+    Sleep( alarmMs );
+    mbedtls_timing_alarmed = 1;
+    /* _endthread will be called implicitly on return
+     * That ensures execution of thread funcition's epilogue */
+}
+
+void mbedtls_set_alarm( int seconds )
+{
+    if( seconds == 0 )
+    {
+        /* No need to create a thread for this simple case.
+         * Also, this shorcut is more reliable at least on MinGW32 */
+        mbedtls_timing_alarmed = 1;
+        return;
+    }
+
+    mbedtls_timing_alarmed = 0;
+    alarmMs = seconds * 1000;
+    (void) _beginthread( TimerProc, 0, NULL );
+}
+
+#else /* _WIN32 && !EFIX64 && !EFI32 */
+
+unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset )
+{
+    struct _hr_time *t = (struct _hr_time *) val;
+
+    if( reset )
+    {
+        gettimeofday( &t->start, NULL );
+        return( 0 );
+    }
+    else
+    {
+        unsigned long delta;
+        struct timeval now;
+        gettimeofday( &now, NULL );
+        delta = ( now.tv_sec  - t->start.tv_sec  ) * 1000ul
+              + ( now.tv_usec - t->start.tv_usec ) / 1000;
+        return( delta );
+    }
+}
+
+static void sighandler( int signum )
+{
+    mbedtls_timing_alarmed = 1;
+    signal( signum, sighandler );
+}
+
+void mbedtls_set_alarm( int seconds )
+{
+    mbedtls_timing_alarmed = 0;
+    signal( SIGALRM, sighandler );
+    alarm( seconds );
+    if( seconds == 0 )
+    {
+        /* alarm(0) cancelled any previous pending alarm, but the
+           handler won't fire, so raise the flag straight away. */
+        mbedtls_timing_alarmed = 1;
+    }
+}
+
+#endif /* _WIN32 && !EFIX64 && !EFI32 */
+
+/*
+ * Set delays to watch
+ */
+void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms )
+{
+    mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
+
+    ctx->int_ms = int_ms;
+    ctx->fin_ms = fin_ms;
+
+    if( fin_ms != 0 )
+        (void) mbedtls_timing_get_timer( &ctx->timer, 1 );
+}
+
+/*
+ * Get number of delays expired
+ */
+int mbedtls_timing_get_delay( void *data )
+{
+    mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data;
+    unsigned long elapsed_ms;
+
+    if( ctx->fin_ms == 0 )
+        return( -1 );
+
+    elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 );
+
+    if( elapsed_ms >= ctx->fin_ms )
+        return( 2 );
+
+    if( elapsed_ms >= ctx->int_ms )
+        return( 1 );
+
+    return( 0 );
+}
+
+#endif /* !MBEDTLS_TIMING_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/*
+ * Busy-waits for the given number of milliseconds.
+ * Used for testing mbedtls_timing_hardclock.
+ */
+static void busy_msleep( unsigned long msec )
+{
+    struct mbedtls_timing_hr_time hires;
+    unsigned long i = 0; /* for busy-waiting */
+    volatile unsigned long j; /* to prevent optimisation */
+
+    (void) mbedtls_timing_get_timer( &hires, 1 );
+
+    while( mbedtls_timing_get_timer( &hires, 0 ) < msec )
+        i++;
+
+    j = i;
+    (void) j;
+}
+
+#define FAIL    do                                                      \
+    {                                                                   \
+        if( verbose != 0 )                                              \
+        {                                                               \
+            mbedtls_printf( "failed at line %d\n", __LINE__ );          \
+            mbedtls_printf( " cycles=%lu ratio=%lu millisecs=%lu secs=%lu hardfail=%d a=%lu b=%lu\n", \
+                            cycles, ratio, millisecs, secs, hardfail,   \
+                            (unsigned long) a, (unsigned long) b );     \
+            mbedtls_printf( " elapsed(hires)=%lu elapsed(ctx)=%lu status(ctx)=%d\n", \
+                            mbedtls_timing_get_timer( &hires, 0 ),      \
+                            mbedtls_timing_get_timer( &ctx.timer, 0 ),  \
+                            mbedtls_timing_get_delay( &ctx ) );         \
+        }                                                               \
+        return( 1 );                                                    \
+    } while( 0 )
+
+/*
+ * Checkup routine
+ *
+ * Warning: this is work in progress, some tests may not be reliable enough
+ * yet! False positives may happen.
+ */
+int mbedtls_timing_self_test( int verbose )
+{
+    unsigned long cycles = 0, ratio = 0;
+    unsigned long millisecs = 0, secs = 0;
+    int hardfail = 0;
+    struct mbedtls_timing_hr_time hires;
+    uint32_t a = 0, b = 0;
+    mbedtls_timing_delay_context ctx;
+
+    if( verbose != 0 )
+        mbedtls_printf( "  TIMING tests note: will take some time!\n" );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  TIMING test #1 (set_alarm / get_timer): " );
+
+    {
+        secs = 1;
+
+        (void) mbedtls_timing_get_timer( &hires, 1 );
+
+        mbedtls_set_alarm( (int) secs );
+        while( !mbedtls_timing_alarmed )
+            ;
+
+        millisecs = mbedtls_timing_get_timer( &hires, 0 );
+
+        /* For some reason on Windows it looks like alarm has an extra delay
+         * (maybe related to creating a new thread). Allow some room here. */
+        if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 )
+            FAIL;
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  TIMING test #2 (set/get_delay        ): " );
+
+    {
+        a = 800;
+        b = 400;
+        mbedtls_timing_set_delay( &ctx, a, a + b );          /* T = 0 */
+
+        busy_msleep( a - a / 4 );                      /* T = a - a/4 */
+        if( mbedtls_timing_get_delay( &ctx ) != 0 )
+            FAIL;
+
+        busy_msleep( a / 4 + b / 4 );                  /* T = a + b/4 */
+        if( mbedtls_timing_get_delay( &ctx ) != 1 )
+            FAIL;
+
+        busy_msleep( b );                          /* T = a + b + b/4 */
+        if( mbedtls_timing_get_delay( &ctx ) != 2 )
+            FAIL;
+    }
+
+    mbedtls_timing_set_delay( &ctx, 0, 0 );
+    busy_msleep( 200 );
+    if( mbedtls_timing_get_delay( &ctx ) != -1 )
+        FAIL;
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+    if( verbose != 0 )
+        mbedtls_printf( "  TIMING test #3 (hardclock / get_timer): " );
+
+    /*
+     * Allow one failure for possible counter wrapping.
+     * On a 4Ghz 32-bit machine the cycle counter wraps about once per second;
+     * since the whole test is about 10ms, it shouldn't happen twice in a row.
+     */
+
+hard_test:
+    if( hardfail > 1 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed (ignored)\n" );
+
+        goto hard_test_done;
+    }
+
+    /* Get a reference ratio cycles/ms */
+    millisecs = 1;
+    cycles = mbedtls_timing_hardclock();
+    busy_msleep( millisecs );
+    cycles = mbedtls_timing_hardclock() - cycles;
+    ratio = cycles / millisecs;
+
+    /* Check that the ratio is mostly constant */
+    for( millisecs = 2; millisecs <= 4; millisecs++ )
+    {
+        cycles = mbedtls_timing_hardclock();
+        busy_msleep( millisecs );
+        cycles = mbedtls_timing_hardclock() - cycles;
+
+        /* Allow variation up to 20% */
+        if( cycles / millisecs < ratio - ratio / 5 ||
+            cycles / millisecs > ratio + ratio / 5 )
+        {
+            hardfail++;
+            goto hard_test;
+        }
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n" );
+
+hard_test_done:
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+    return( 0 );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_TIMING_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/version.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/version.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/version.c	(revision 398)
@@ -0,0 +1,50 @@
+/*
+ *  Version information
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_VERSION_C)
+
+#include "mbedtls/version.h"
+#include <string.h>
+
+unsigned int mbedtls_version_get_number( void )
+{
+    return( MBEDTLS_VERSION_NUMBER );
+}
+
+void mbedtls_version_get_string( char *string )
+{
+    memcpy( string, MBEDTLS_VERSION_STRING,
+            sizeof( MBEDTLS_VERSION_STRING ) );
+}
+
+void mbedtls_version_get_string_full( char *string )
+{
+    memcpy( string, MBEDTLS_VERSION_STRING_FULL,
+            sizeof( MBEDTLS_VERSION_STRING_FULL ) );
+}
+
+#endif /* MBEDTLS_VERSION_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/version_features.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/version_features.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/version_features.c	(revision 398)
@@ -0,0 +1,779 @@
+/*
+ *  Version feature information
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_VERSION_C)
+
+#include "mbedtls/version.h"
+
+#include <string.h>
+
+static const char *features[] = {
+#if defined(MBEDTLS_VERSION_FEATURES)
+#if defined(MBEDTLS_HAVE_ASM)
+    "MBEDTLS_HAVE_ASM",
+#endif /* MBEDTLS_HAVE_ASM */
+#if defined(MBEDTLS_NO_UDBL_DIVISION)
+    "MBEDTLS_NO_UDBL_DIVISION",
+#endif /* MBEDTLS_NO_UDBL_DIVISION */
+#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION)
+    "MBEDTLS_NO_64BIT_MULTIPLICATION",
+#endif /* MBEDTLS_NO_64BIT_MULTIPLICATION */
+#if defined(MBEDTLS_HAVE_SSE2)
+    "MBEDTLS_HAVE_SSE2",
+#endif /* MBEDTLS_HAVE_SSE2 */
+#if defined(MBEDTLS_HAVE_TIME)
+    "MBEDTLS_HAVE_TIME",
+#endif /* MBEDTLS_HAVE_TIME */
+#if defined(MBEDTLS_HAVE_TIME_DATE)
+    "MBEDTLS_HAVE_TIME_DATE",
+#endif /* MBEDTLS_HAVE_TIME_DATE */
+#if defined(MBEDTLS_PLATFORM_MEMORY)
+    "MBEDTLS_PLATFORM_MEMORY",
+#endif /* MBEDTLS_PLATFORM_MEMORY */
+#if defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
+    "MBEDTLS_PLATFORM_NO_STD_FUNCTIONS",
+#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
+#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
+    "MBEDTLS_PLATFORM_EXIT_ALT",
+#endif /* MBEDTLS_PLATFORM_EXIT_ALT */
+#if defined(MBEDTLS_PLATFORM_TIME_ALT)
+    "MBEDTLS_PLATFORM_TIME_ALT",
+#endif /* MBEDTLS_PLATFORM_TIME_ALT */
+#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
+    "MBEDTLS_PLATFORM_FPRINTF_ALT",
+#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
+    "MBEDTLS_PLATFORM_PRINTF_ALT",
+#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
+    "MBEDTLS_PLATFORM_SNPRINTF_ALT",
+#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
+    "MBEDTLS_PLATFORM_NV_SEED_ALT",
+#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
+#if defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT)
+    "MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT",
+#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+    "MBEDTLS_DEPRECATED_WARNING",
+#endif /* MBEDTLS_DEPRECATED_WARNING */
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+    "MBEDTLS_DEPRECATED_REMOVED",
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#if defined(MBEDTLS_CHECK_PARAMS)
+    "MBEDTLS_CHECK_PARAMS",
+#endif /* MBEDTLS_CHECK_PARAMS */
+#if defined(MBEDTLS_TIMING_ALT)
+    "MBEDTLS_TIMING_ALT",
+#endif /* MBEDTLS_TIMING_ALT */
+#if defined(MBEDTLS_AES_ALT)
+    "MBEDTLS_AES_ALT",
+#endif /* MBEDTLS_AES_ALT */
+#if defined(MBEDTLS_ARC4_ALT)
+    "MBEDTLS_ARC4_ALT",
+#endif /* MBEDTLS_ARC4_ALT */
+#if defined(MBEDTLS_ARIA_ALT)
+    "MBEDTLS_ARIA_ALT",
+#endif /* MBEDTLS_ARIA_ALT */
+#if defined(MBEDTLS_BLOWFISH_ALT)
+    "MBEDTLS_BLOWFISH_ALT",
+#endif /* MBEDTLS_BLOWFISH_ALT */
+#if defined(MBEDTLS_CAMELLIA_ALT)
+    "MBEDTLS_CAMELLIA_ALT",
+#endif /* MBEDTLS_CAMELLIA_ALT */
+#if defined(MBEDTLS_CCM_ALT)
+    "MBEDTLS_CCM_ALT",
+#endif /* MBEDTLS_CCM_ALT */
+#if defined(MBEDTLS_CHACHA20_ALT)
+    "MBEDTLS_CHACHA20_ALT",
+#endif /* MBEDTLS_CHACHA20_ALT */
+#if defined(MBEDTLS_CHACHAPOLY_ALT)
+    "MBEDTLS_CHACHAPOLY_ALT",
+#endif /* MBEDTLS_CHACHAPOLY_ALT */
+#if defined(MBEDTLS_CMAC_ALT)
+    "MBEDTLS_CMAC_ALT",
+#endif /* MBEDTLS_CMAC_ALT */
+#if defined(MBEDTLS_DES_ALT)
+    "MBEDTLS_DES_ALT",
+#endif /* MBEDTLS_DES_ALT */
+#if defined(MBEDTLS_DHM_ALT)
+    "MBEDTLS_DHM_ALT",
+#endif /* MBEDTLS_DHM_ALT */
+#if defined(MBEDTLS_ECJPAKE_ALT)
+    "MBEDTLS_ECJPAKE_ALT",
+#endif /* MBEDTLS_ECJPAKE_ALT */
+#if defined(MBEDTLS_GCM_ALT)
+    "MBEDTLS_GCM_ALT",
+#endif /* MBEDTLS_GCM_ALT */
+#if defined(MBEDTLS_NIST_KW_ALT)
+    "MBEDTLS_NIST_KW_ALT",
+#endif /* MBEDTLS_NIST_KW_ALT */
+#if defined(MBEDTLS_MD2_ALT)
+    "MBEDTLS_MD2_ALT",
+#endif /* MBEDTLS_MD2_ALT */
+#if defined(MBEDTLS_MD4_ALT)
+    "MBEDTLS_MD4_ALT",
+#endif /* MBEDTLS_MD4_ALT */
+#if defined(MBEDTLS_MD5_ALT)
+    "MBEDTLS_MD5_ALT",
+#endif /* MBEDTLS_MD5_ALT */
+#if defined(MBEDTLS_POLY1305_ALT)
+    "MBEDTLS_POLY1305_ALT",
+#endif /* MBEDTLS_POLY1305_ALT */
+#if defined(MBEDTLS_RIPEMD160_ALT)
+    "MBEDTLS_RIPEMD160_ALT",
+#endif /* MBEDTLS_RIPEMD160_ALT */
+#if defined(MBEDTLS_RSA_ALT)
+    "MBEDTLS_RSA_ALT",
+#endif /* MBEDTLS_RSA_ALT */
+#if defined(MBEDTLS_SHA1_ALT)
+    "MBEDTLS_SHA1_ALT",
+#endif /* MBEDTLS_SHA1_ALT */
+#if defined(MBEDTLS_SHA256_ALT)
+    "MBEDTLS_SHA256_ALT",
+#endif /* MBEDTLS_SHA256_ALT */
+#if defined(MBEDTLS_SHA512_ALT)
+    "MBEDTLS_SHA512_ALT",
+#endif /* MBEDTLS_SHA512_ALT */
+#if defined(MBEDTLS_XTEA_ALT)
+    "MBEDTLS_XTEA_ALT",
+#endif /* MBEDTLS_XTEA_ALT */
+#if defined(MBEDTLS_ECP_ALT)
+    "MBEDTLS_ECP_ALT",
+#endif /* MBEDTLS_ECP_ALT */
+#if defined(MBEDTLS_MD2_PROCESS_ALT)
+    "MBEDTLS_MD2_PROCESS_ALT",
+#endif /* MBEDTLS_MD2_PROCESS_ALT */
+#if defined(MBEDTLS_MD4_PROCESS_ALT)
+    "MBEDTLS_MD4_PROCESS_ALT",
+#endif /* MBEDTLS_MD4_PROCESS_ALT */
+#if defined(MBEDTLS_MD5_PROCESS_ALT)
+    "MBEDTLS_MD5_PROCESS_ALT",
+#endif /* MBEDTLS_MD5_PROCESS_ALT */
+#if defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
+    "MBEDTLS_RIPEMD160_PROCESS_ALT",
+#endif /* MBEDTLS_RIPEMD160_PROCESS_ALT */
+#if defined(MBEDTLS_SHA1_PROCESS_ALT)
+    "MBEDTLS_SHA1_PROCESS_ALT",
+#endif /* MBEDTLS_SHA1_PROCESS_ALT */
+#if defined(MBEDTLS_SHA256_PROCESS_ALT)
+    "MBEDTLS_SHA256_PROCESS_ALT",
+#endif /* MBEDTLS_SHA256_PROCESS_ALT */
+#if defined(MBEDTLS_SHA512_PROCESS_ALT)
+    "MBEDTLS_SHA512_PROCESS_ALT",
+#endif /* MBEDTLS_SHA512_PROCESS_ALT */
+#if defined(MBEDTLS_DES_SETKEY_ALT)
+    "MBEDTLS_DES_SETKEY_ALT",
+#endif /* MBEDTLS_DES_SETKEY_ALT */
+#if defined(MBEDTLS_DES_CRYPT_ECB_ALT)
+    "MBEDTLS_DES_CRYPT_ECB_ALT",
+#endif /* MBEDTLS_DES_CRYPT_ECB_ALT */
+#if defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
+    "MBEDTLS_DES3_CRYPT_ECB_ALT",
+#endif /* MBEDTLS_DES3_CRYPT_ECB_ALT */
+#if defined(MBEDTLS_AES_SETKEY_ENC_ALT)
+    "MBEDTLS_AES_SETKEY_ENC_ALT",
+#endif /* MBEDTLS_AES_SETKEY_ENC_ALT */
+#if defined(MBEDTLS_AES_SETKEY_DEC_ALT)
+    "MBEDTLS_AES_SETKEY_DEC_ALT",
+#endif /* MBEDTLS_AES_SETKEY_DEC_ALT */
+#if defined(MBEDTLS_AES_ENCRYPT_ALT)
+    "MBEDTLS_AES_ENCRYPT_ALT",
+#endif /* MBEDTLS_AES_ENCRYPT_ALT */
+#if defined(MBEDTLS_AES_DECRYPT_ALT)
+    "MBEDTLS_AES_DECRYPT_ALT",
+#endif /* MBEDTLS_AES_DECRYPT_ALT */
+#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
+    "MBEDTLS_ECDH_GEN_PUBLIC_ALT",
+#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
+#if defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
+    "MBEDTLS_ECDH_COMPUTE_SHARED_ALT",
+#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
+#if defined(MBEDTLS_ECDSA_VERIFY_ALT)
+    "MBEDTLS_ECDSA_VERIFY_ALT",
+#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
+#if defined(MBEDTLS_ECDSA_SIGN_ALT)
+    "MBEDTLS_ECDSA_SIGN_ALT",
+#endif /* MBEDTLS_ECDSA_SIGN_ALT */
+#if defined(MBEDTLS_ECDSA_GENKEY_ALT)
+    "MBEDTLS_ECDSA_GENKEY_ALT",
+#endif /* MBEDTLS_ECDSA_GENKEY_ALT */
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+    "MBEDTLS_ECP_INTERNAL_ALT",
+#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
+    "MBEDTLS_ECP_RANDOMIZE_JAC_ALT",
+#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */
+#if defined(MBEDTLS_ECP_ADD_MIXED_ALT)
+    "MBEDTLS_ECP_ADD_MIXED_ALT",
+#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */
+#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
+    "MBEDTLS_ECP_DOUBLE_JAC_ALT",
+#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */
+#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
+    "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT",
+#endif /* MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT */
+#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
+    "MBEDTLS_ECP_NORMALIZE_JAC_ALT",
+#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */
+#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
+    "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT",
+#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */
+#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
+    "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT",
+#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */
+#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
+    "MBEDTLS_ECP_NORMALIZE_MXZ_ALT",
+#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
+#if defined(MBEDTLS_TEST_NULL_ENTROPY)
+    "MBEDTLS_TEST_NULL_ENTROPY",
+#endif /* MBEDTLS_TEST_NULL_ENTROPY */
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+    "MBEDTLS_ENTROPY_HARDWARE_ALT",
+#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
+#if defined(MBEDTLS_AES_ROM_TABLES)
+    "MBEDTLS_AES_ROM_TABLES",
+#endif /* MBEDTLS_AES_ROM_TABLES */
+#if defined(MBEDTLS_AES_FEWER_TABLES)
+    "MBEDTLS_AES_FEWER_TABLES",
+#endif /* MBEDTLS_AES_FEWER_TABLES */
+#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
+    "MBEDTLS_CAMELLIA_SMALL_MEMORY",
+#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+    "MBEDTLS_CIPHER_MODE_CBC",
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+    "MBEDTLS_CIPHER_MODE_CFB",
+#endif /* MBEDTLS_CIPHER_MODE_CFB */
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    "MBEDTLS_CIPHER_MODE_CTR",
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+    "MBEDTLS_CIPHER_MODE_OFB",
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+    "MBEDTLS_CIPHER_MODE_XTS",
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
+    "MBEDTLS_CIPHER_NULL_CIPHER",
+#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
+#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
+    "MBEDTLS_CIPHER_PADDING_PKCS7",
+#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */
+#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS)
+    "MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS",
+#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */
+#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
+    "MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN",
+#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */
+#if defined(MBEDTLS_CIPHER_PADDING_ZEROS)
+    "MBEDTLS_CIPHER_PADDING_ZEROS",
+#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */
+#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES)
+    "MBEDTLS_ENABLE_WEAK_CIPHERSUITES",
+#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */
+#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES)
+    "MBEDTLS_REMOVE_ARC4_CIPHERSUITES",
+#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */
+#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES)
+    "MBEDTLS_REMOVE_3DES_CIPHERSUITES",
+#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
+    "MBEDTLS_ECP_DP_SECP192R1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
+    "MBEDTLS_ECP_DP_SECP224R1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+    "MBEDTLS_ECP_DP_SECP256R1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+    "MBEDTLS_ECP_DP_SECP384R1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
+    "MBEDTLS_ECP_DP_SECP521R1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
+    "MBEDTLS_ECP_DP_SECP192K1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
+    "MBEDTLS_ECP_DP_SECP224K1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+    "MBEDTLS_ECP_DP_SECP256K1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
+    "MBEDTLS_ECP_DP_BP256R1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
+    "MBEDTLS_ECP_DP_BP384R1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
+    "MBEDTLS_ECP_DP_BP512R1_ENABLED",
+#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+    "MBEDTLS_ECP_DP_CURVE25519_ENABLED",
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+    "MBEDTLS_ECP_DP_CURVE448_ENABLED",
+#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
+#if defined(MBEDTLS_ECP_NIST_OPTIM)
+    "MBEDTLS_ECP_NIST_OPTIM",
+#endif /* MBEDTLS_ECP_NIST_OPTIM */
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    "MBEDTLS_ECP_RESTARTABLE",
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+    "MBEDTLS_ECDSA_DETERMINISTIC",
+#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_PSK_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+    "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED",
+#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
+    "MBEDTLS_PK_PARSE_EC_EXTENDED",
+#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
+#if defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+    "MBEDTLS_ERROR_STRERROR_DUMMY",
+#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */
+#if defined(MBEDTLS_GENPRIME)
+    "MBEDTLS_GENPRIME",
+#endif /* MBEDTLS_GENPRIME */
+#if defined(MBEDTLS_FS_IO)
+    "MBEDTLS_FS_IO",
+#endif /* MBEDTLS_FS_IO */
+#if defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
+    "MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES",
+#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
+#if defined(MBEDTLS_NO_PLATFORM_ENTROPY)
+    "MBEDTLS_NO_PLATFORM_ENTROPY",
+#endif /* MBEDTLS_NO_PLATFORM_ENTROPY */
+#if defined(MBEDTLS_ENTROPY_FORCE_SHA256)
+    "MBEDTLS_ENTROPY_FORCE_SHA256",
+#endif /* MBEDTLS_ENTROPY_FORCE_SHA256 */
+#if defined(MBEDTLS_ENTROPY_NV_SEED)
+    "MBEDTLS_ENTROPY_NV_SEED",
+#endif /* MBEDTLS_ENTROPY_NV_SEED */
+#if defined(MBEDTLS_MEMORY_DEBUG)
+    "MBEDTLS_MEMORY_DEBUG",
+#endif /* MBEDTLS_MEMORY_DEBUG */
+#if defined(MBEDTLS_MEMORY_BACKTRACE)
+    "MBEDTLS_MEMORY_BACKTRACE",
+#endif /* MBEDTLS_MEMORY_BACKTRACE */
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+    "MBEDTLS_PK_RSA_ALT_SUPPORT",
+#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
+#if defined(MBEDTLS_PKCS1_V15)
+    "MBEDTLS_PKCS1_V15",
+#endif /* MBEDTLS_PKCS1_V15 */
+#if defined(MBEDTLS_PKCS1_V21)
+    "MBEDTLS_PKCS1_V21",
+#endif /* MBEDTLS_PKCS1_V21 */
+#if defined(MBEDTLS_RSA_NO_CRT)
+    "MBEDTLS_RSA_NO_CRT",
+#endif /* MBEDTLS_RSA_NO_CRT */
+#if defined(MBEDTLS_SELF_TEST)
+    "MBEDTLS_SELF_TEST",
+#endif /* MBEDTLS_SELF_TEST */
+#if defined(MBEDTLS_SHA256_SMALLER)
+    "MBEDTLS_SHA256_SMALLER",
+#endif /* MBEDTLS_SHA256_SMALLER */
+#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
+    "MBEDTLS_SSL_ALL_ALERT_MESSAGES",
+#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+    "MBEDTLS_SSL_ASYNC_PRIVATE",
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+    "MBEDTLS_SSL_DEBUG_ALL",
+#endif /* MBEDTLS_SSL_DEBUG_ALL */
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+    "MBEDTLS_SSL_ENCRYPT_THEN_MAC",
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+    "MBEDTLS_SSL_EXTENDED_MASTER_SECRET",
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
+    "MBEDTLS_SSL_FALLBACK_SCSV",
+#endif /* MBEDTLS_SSL_FALLBACK_SCSV */
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+    "MBEDTLS_SSL_HW_RECORD_ACCEL",
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+    "MBEDTLS_SSL_CBC_RECORD_SPLITTING",
+#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+    "MBEDTLS_SSL_RENEGOTIATION",
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
+    "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO",
+#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
+#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE)
+    "MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE",
+#endif /* MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+    "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH",
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+    "MBEDTLS_SSL_PROTO_SSL3",
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1)
+    "MBEDTLS_SSL_PROTO_TLS1",
+#endif /* MBEDTLS_SSL_PROTO_TLS1 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1)
+    "MBEDTLS_SSL_PROTO_TLS1_1",
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+    "MBEDTLS_SSL_PROTO_TLS1_2",
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+    "MBEDTLS_SSL_PROTO_DTLS",
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_ALPN)
+    "MBEDTLS_SSL_ALPN",
+#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+    "MBEDTLS_SSL_DTLS_ANTI_REPLAY",
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
+#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
+    "MBEDTLS_SSL_DTLS_HELLO_VERIFY",
+#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
+    "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE",
+#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+    "MBEDTLS_SSL_DTLS_BADMAC_LIMIT",
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+    "MBEDTLS_SSL_SESSION_TICKETS",
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+    "MBEDTLS_SSL_EXPORT_KEYS",
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+    "MBEDTLS_SSL_SERVER_NAME_INDICATION",
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+    "MBEDTLS_SSL_TRUNCATED_HMAC",
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
+    "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT",
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
+#if defined(MBEDTLS_THREADING_ALT)
+    "MBEDTLS_THREADING_ALT",
+#endif /* MBEDTLS_THREADING_ALT */
+#if defined(MBEDTLS_THREADING_PTHREAD)
+    "MBEDTLS_THREADING_PTHREAD",
+#endif /* MBEDTLS_THREADING_PTHREAD */
+#if defined(MBEDTLS_VERSION_FEATURES)
+    "MBEDTLS_VERSION_FEATURES",
+#endif /* MBEDTLS_VERSION_FEATURES */
+#if defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
+    "MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3",
+#endif /* MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 */
+#if defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
+    "MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION",
+#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
+    "MBEDTLS_X509_CHECK_KEY_USAGE",
+#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
+#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
+    "MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE",
+#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+    "MBEDTLS_X509_RSASSA_PSS_SUPPORT",
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+    "MBEDTLS_ZLIB_SUPPORT",
+#endif /* MBEDTLS_ZLIB_SUPPORT */
+#if defined(MBEDTLS_AESNI_C)
+    "MBEDTLS_AESNI_C",
+#endif /* MBEDTLS_AESNI_C */
+#if defined(MBEDTLS_AES_C)
+    "MBEDTLS_AES_C",
+#endif /* MBEDTLS_AES_C */
+#if defined(MBEDTLS_ARC4_C)
+    "MBEDTLS_ARC4_C",
+#endif /* MBEDTLS_ARC4_C */
+#if defined(MBEDTLS_ASN1_PARSE_C)
+    "MBEDTLS_ASN1_PARSE_C",
+#endif /* MBEDTLS_ASN1_PARSE_C */
+#if defined(MBEDTLS_ASN1_WRITE_C)
+    "MBEDTLS_ASN1_WRITE_C",
+#endif /* MBEDTLS_ASN1_WRITE_C */
+#if defined(MBEDTLS_BASE64_C)
+    "MBEDTLS_BASE64_C",
+#endif /* MBEDTLS_BASE64_C */
+#if defined(MBEDTLS_BIGNUM_C)
+    "MBEDTLS_BIGNUM_C",
+#endif /* MBEDTLS_BIGNUM_C */
+#if defined(MBEDTLS_BLOWFISH_C)
+    "MBEDTLS_BLOWFISH_C",
+#endif /* MBEDTLS_BLOWFISH_C */
+#if defined(MBEDTLS_CAMELLIA_C)
+    "MBEDTLS_CAMELLIA_C",
+#endif /* MBEDTLS_CAMELLIA_C */
+#if defined(MBEDTLS_ARIA_C)
+    "MBEDTLS_ARIA_C",
+#endif /* MBEDTLS_ARIA_C */
+#if defined(MBEDTLS_CCM_C)
+    "MBEDTLS_CCM_C",
+#endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CERTS_C)
+    "MBEDTLS_CERTS_C",
+#endif /* MBEDTLS_CERTS_C */
+#if defined(MBEDTLS_CHACHA20_C)
+    "MBEDTLS_CHACHA20_C",
+#endif /* MBEDTLS_CHACHA20_C */
+#if defined(MBEDTLS_CHACHAPOLY_C)
+    "MBEDTLS_CHACHAPOLY_C",
+#endif /* MBEDTLS_CHACHAPOLY_C */
+#if defined(MBEDTLS_CIPHER_C)
+    "MBEDTLS_CIPHER_C",
+#endif /* MBEDTLS_CIPHER_C */
+#if defined(MBEDTLS_CMAC_C)
+    "MBEDTLS_CMAC_C",
+#endif /* MBEDTLS_CMAC_C */
+#if defined(MBEDTLS_CTR_DRBG_C)
+    "MBEDTLS_CTR_DRBG_C",
+#endif /* MBEDTLS_CTR_DRBG_C */
+#if defined(MBEDTLS_DEBUG_C)
+    "MBEDTLS_DEBUG_C",
+#endif /* MBEDTLS_DEBUG_C */
+#if defined(MBEDTLS_DES_C)
+    "MBEDTLS_DES_C",
+#endif /* MBEDTLS_DES_C */
+#if defined(MBEDTLS_DHM_C)
+    "MBEDTLS_DHM_C",
+#endif /* MBEDTLS_DHM_C */
+#if defined(MBEDTLS_ECDH_C)
+    "MBEDTLS_ECDH_C",
+#endif /* MBEDTLS_ECDH_C */
+#if defined(MBEDTLS_ECDSA_C)
+    "MBEDTLS_ECDSA_C",
+#endif /* MBEDTLS_ECDSA_C */
+#if defined(MBEDTLS_ECJPAKE_C)
+    "MBEDTLS_ECJPAKE_C",
+#endif /* MBEDTLS_ECJPAKE_C */
+#if defined(MBEDTLS_ECP_C)
+    "MBEDTLS_ECP_C",
+#endif /* MBEDTLS_ECP_C */
+#if defined(MBEDTLS_ENTROPY_C)
+    "MBEDTLS_ENTROPY_C",
+#endif /* MBEDTLS_ENTROPY_C */
+#if defined(MBEDTLS_ERROR_C)
+    "MBEDTLS_ERROR_C",
+#endif /* MBEDTLS_ERROR_C */
+#if defined(MBEDTLS_GCM_C)
+    "MBEDTLS_GCM_C",
+#endif /* MBEDTLS_GCM_C */
+#if defined(MBEDTLS_HAVEGE_C)
+    "MBEDTLS_HAVEGE_C",
+#endif /* MBEDTLS_HAVEGE_C */
+#if defined(MBEDTLS_HKDF_C)
+    "MBEDTLS_HKDF_C",
+#endif /* MBEDTLS_HKDF_C */
+#if defined(MBEDTLS_HMAC_DRBG_C)
+    "MBEDTLS_HMAC_DRBG_C",
+#endif /* MBEDTLS_HMAC_DRBG_C */
+#if defined(MBEDTLS_NIST_KW_C)
+    "MBEDTLS_NIST_KW_C",
+#endif /* MBEDTLS_NIST_KW_C */
+#if defined(MBEDTLS_MD_C)
+    "MBEDTLS_MD_C",
+#endif /* MBEDTLS_MD_C */
+#if defined(MBEDTLS_MD2_C)
+    "MBEDTLS_MD2_C",
+#endif /* MBEDTLS_MD2_C */
+#if defined(MBEDTLS_MD4_C)
+    "MBEDTLS_MD4_C",
+#endif /* MBEDTLS_MD4_C */
+#if defined(MBEDTLS_MD5_C)
+    "MBEDTLS_MD5_C",
+#endif /* MBEDTLS_MD5_C */
+#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+    "MBEDTLS_MEMORY_BUFFER_ALLOC_C",
+#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
+#if defined(MBEDTLS_NET_C)
+    "MBEDTLS_NET_C",
+#endif /* MBEDTLS_NET_C */
+#if defined(MBEDTLS_OID_C)
+    "MBEDTLS_OID_C",
+#endif /* MBEDTLS_OID_C */
+#if defined(MBEDTLS_PADLOCK_C)
+    "MBEDTLS_PADLOCK_C",
+#endif /* MBEDTLS_PADLOCK_C */
+#if defined(MBEDTLS_PEM_PARSE_C)
+    "MBEDTLS_PEM_PARSE_C",
+#endif /* MBEDTLS_PEM_PARSE_C */
+#if defined(MBEDTLS_PEM_WRITE_C)
+    "MBEDTLS_PEM_WRITE_C",
+#endif /* MBEDTLS_PEM_WRITE_C */
+#if defined(MBEDTLS_PK_C)
+    "MBEDTLS_PK_C",
+#endif /* MBEDTLS_PK_C */
+#if defined(MBEDTLS_PK_PARSE_C)
+    "MBEDTLS_PK_PARSE_C",
+#endif /* MBEDTLS_PK_PARSE_C */
+#if defined(MBEDTLS_PK_WRITE_C)
+    "MBEDTLS_PK_WRITE_C",
+#endif /* MBEDTLS_PK_WRITE_C */
+#if defined(MBEDTLS_PKCS5_C)
+    "MBEDTLS_PKCS5_C",
+#endif /* MBEDTLS_PKCS5_C */
+#if defined(MBEDTLS_PKCS11_C)
+    "MBEDTLS_PKCS11_C",
+#endif /* MBEDTLS_PKCS11_C */
+#if defined(MBEDTLS_PKCS12_C)
+    "MBEDTLS_PKCS12_C",
+#endif /* MBEDTLS_PKCS12_C */
+#if defined(MBEDTLS_PLATFORM_C)
+    "MBEDTLS_PLATFORM_C",
+#endif /* MBEDTLS_PLATFORM_C */
+#if defined(MBEDTLS_POLY1305_C)
+    "MBEDTLS_POLY1305_C",
+#endif /* MBEDTLS_POLY1305_C */
+#if defined(MBEDTLS_RIPEMD160_C)
+    "MBEDTLS_RIPEMD160_C",
+#endif /* MBEDTLS_RIPEMD160_C */
+#if defined(MBEDTLS_RSA_C)
+    "MBEDTLS_RSA_C",
+#endif /* MBEDTLS_RSA_C */
+#if defined(MBEDTLS_SHA1_C)
+    "MBEDTLS_SHA1_C",
+#endif /* MBEDTLS_SHA1_C */
+#if defined(MBEDTLS_SHA256_C)
+    "MBEDTLS_SHA256_C",
+#endif /* MBEDTLS_SHA256_C */
+#if defined(MBEDTLS_SHA512_C)
+    "MBEDTLS_SHA512_C",
+#endif /* MBEDTLS_SHA512_C */
+#if defined(MBEDTLS_SSL_CACHE_C)
+    "MBEDTLS_SSL_CACHE_C",
+#endif /* MBEDTLS_SSL_CACHE_C */
+#if defined(MBEDTLS_SSL_COOKIE_C)
+    "MBEDTLS_SSL_COOKIE_C",
+#endif /* MBEDTLS_SSL_COOKIE_C */
+#if defined(MBEDTLS_SSL_TICKET_C)
+    "MBEDTLS_SSL_TICKET_C",
+#endif /* MBEDTLS_SSL_TICKET_C */
+#if defined(MBEDTLS_SSL_CLI_C)
+    "MBEDTLS_SSL_CLI_C",
+#endif /* MBEDTLS_SSL_CLI_C */
+#if defined(MBEDTLS_SSL_SRV_C)
+    "MBEDTLS_SSL_SRV_C",
+#endif /* MBEDTLS_SSL_SRV_C */
+#if defined(MBEDTLS_SSL_TLS_C)
+    "MBEDTLS_SSL_TLS_C",
+#endif /* MBEDTLS_SSL_TLS_C */
+#if defined(MBEDTLS_THREADING_C)
+    "MBEDTLS_THREADING_C",
+#endif /* MBEDTLS_THREADING_C */
+#if defined(MBEDTLS_TIMING_C)
+    "MBEDTLS_TIMING_C",
+#endif /* MBEDTLS_TIMING_C */
+#if defined(MBEDTLS_VERSION_C)
+    "MBEDTLS_VERSION_C",
+#endif /* MBEDTLS_VERSION_C */
+#if defined(MBEDTLS_X509_USE_C)
+    "MBEDTLS_X509_USE_C",
+#endif /* MBEDTLS_X509_USE_C */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+    "MBEDTLS_X509_CRT_PARSE_C",
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
+    "MBEDTLS_X509_CRL_PARSE_C",
+#endif /* MBEDTLS_X509_CRL_PARSE_C */
+#if defined(MBEDTLS_X509_CSR_PARSE_C)
+    "MBEDTLS_X509_CSR_PARSE_C",
+#endif /* MBEDTLS_X509_CSR_PARSE_C */
+#if defined(MBEDTLS_X509_CREATE_C)
+    "MBEDTLS_X509_CREATE_C",
+#endif /* MBEDTLS_X509_CREATE_C */
+#if defined(MBEDTLS_X509_CRT_WRITE_C)
+    "MBEDTLS_X509_CRT_WRITE_C",
+#endif /* MBEDTLS_X509_CRT_WRITE_C */
+#if defined(MBEDTLS_X509_CSR_WRITE_C)
+    "MBEDTLS_X509_CSR_WRITE_C",
+#endif /* MBEDTLS_X509_CSR_WRITE_C */
+#if defined(MBEDTLS_XTEA_C)
+    "MBEDTLS_XTEA_C",
+#endif /* MBEDTLS_XTEA_C */
+#endif /* MBEDTLS_VERSION_FEATURES */
+    NULL
+};
+
+int mbedtls_version_check_feature( const char *feature )
+{
+    const char **idx = features;
+
+    if( *idx == NULL )
+        return( -2 );
+
+    if( feature == NULL )
+        return( -1 );
+
+    while( *idx != NULL )
+    {
+        if( !strcmp( *idx, feature ) )
+            return( 0 );
+        idx++;
+    }
+    return( -1 );
+}
+
+#endif /* MBEDTLS_VERSION_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509.c	(revision 398)
@@ -0,0 +1,1064 @@
+/*
+ *  X.509 common functions for parsing and verification
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The ITU-T X.509 standard defines a certificate format for PKI.
+ *
+ *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
+ *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
+ *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
+ *
+ *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
+ *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_X509_USE_C)
+
+#include "mbedtls/x509.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/oid.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+#include "mbedtls/pem.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_free      free
+#define mbedtls_calloc    calloc
+#define mbedtls_printf    printf
+#define mbedtls_snprintf  snprintf
+#endif
+
+#if defined(MBEDTLS_HAVE_TIME)
+#include "mbedtls/platform_time.h"
+#endif
+#if defined(MBEDTLS_HAVE_TIME_DATE)
+#include "mbedtls/platform_util.h"
+#include <time.h>
+#endif
+
+#define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); }
+#define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); }
+
+/*
+ *  CertificateSerialNumber  ::=  INTEGER
+ */
+int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
+                     mbedtls_x509_buf *serial )
+{
+    int ret;
+
+    if( ( end - *p ) < 1 )
+        return( MBEDTLS_ERR_X509_INVALID_SERIAL +
+                MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) &&
+        **p !=   MBEDTLS_ASN1_INTEGER )
+        return( MBEDTLS_ERR_X509_INVALID_SERIAL +
+                MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+    serial->tag = *(*p)++;
+
+    if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret );
+
+    serial->p = *p;
+    *p += serial->len;
+
+    return( 0 );
+}
+
+/* Get an algorithm identifier without parameters (eg for signatures)
+ *
+ *  AlgorithmIdentifier  ::=  SEQUENCE  {
+ *       algorithm               OBJECT IDENTIFIER,
+ *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
+ */
+int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
+                       mbedtls_x509_buf *alg )
+{
+    int ret;
+
+    if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+    return( 0 );
+}
+
+/*
+ * Parse an algorithm identifier with (optional) paramaters
+ */
+int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
+                  mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
+{
+    int ret;
+
+    if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+/*
+ * HashAlgorithm ::= AlgorithmIdentifier
+ *
+ * AlgorithmIdentifier  ::=  SEQUENCE  {
+ *      algorithm               OBJECT IDENTIFIER,
+ *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
+ *
+ * For HashAlgorithm, parameters MUST be NULL or absent.
+ */
+static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg )
+{
+    int ret;
+    unsigned char *p;
+    const unsigned char *end;
+    mbedtls_x509_buf md_oid;
+    size_t len;
+
+    /* Make sure we got a SEQUENCE and setup bounds */
+    if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+        return( MBEDTLS_ERR_X509_INVALID_ALG +
+                MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+    p = (unsigned char *) alg->p;
+    end = p + alg->len;
+
+    if( p >= end )
+        return( MBEDTLS_ERR_X509_INVALID_ALG +
+                MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    /* Parse md_oid */
+    md_oid.tag = *p;
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+    md_oid.p = p;
+    p += md_oid.len;
+
+    /* Get md_alg from md_oid */
+    if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+    /* Make sure params is absent of NULL */
+    if( p == end )
+        return( 0 );
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+    if( p != end )
+        return( MBEDTLS_ERR_X509_INVALID_ALG +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+/*
+ *    RSASSA-PSS-params  ::=  SEQUENCE  {
+ *       hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
+ *       maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
+ *       saltLength        [2] INTEGER DEFAULT 20,
+ *       trailerField      [3] INTEGER DEFAULT 1  }
+ *    -- Note that the tags in this Sequence are explicit.
+ *
+ * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
+ * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
+ * option. Enfore this at parsing time.
+ */
+int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
+                                mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
+                                int *salt_len )
+{
+    int ret;
+    unsigned char *p;
+    const unsigned char *end, *end2;
+    size_t len;
+    mbedtls_x509_buf alg_id, alg_params;
+
+    /* First set everything to defaults */
+    *md_alg = MBEDTLS_MD_SHA1;
+    *mgf_md = MBEDTLS_MD_SHA1;
+    *salt_len = 20;
+
+    /* Make sure params is a SEQUENCE and setup bounds */
+    if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
+        return( MBEDTLS_ERR_X509_INVALID_ALG +
+                MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+    p = (unsigned char *) params->p;
+    end = p + params->len;
+
+    if( p == end )
+        return( 0 );
+
+    /*
+     * HashAlgorithm
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
+    {
+        end2 = p + len;
+
+        /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
+        if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 )
+            return( ret );
+
+        if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+        if( p != end2 )
+            return( MBEDTLS_ERR_X509_INVALID_ALG +
+                    MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+    else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+    if( p == end )
+        return( 0 );
+
+    /*
+     * MaskGenAlgorithm
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
+    {
+        end2 = p + len;
+
+        /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
+        if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 )
+            return( ret );
+
+        /* Only MFG1 is recognised for now */
+        if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 )
+            return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE +
+                    MBEDTLS_ERR_OID_NOT_FOUND );
+
+        /* Parse HashAlgorithm */
+        if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
+            return( ret );
+
+        if( p != end2 )
+            return( MBEDTLS_ERR_X509_INVALID_ALG +
+                    MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+    else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+    if( p == end )
+        return( 0 );
+
+    /*
+     * salt_len
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 )
+    {
+        end2 = p + len;
+
+        if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+        if( p != end2 )
+            return( MBEDTLS_ERR_X509_INVALID_ALG +
+                    MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+    else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+    if( p == end )
+        return( 0 );
+
+    /*
+     * trailer_field (if present, must be 1)
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 )
+    {
+        int trailer_field;
+
+        end2 = p + len;
+
+        if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+        if( p != end2 )
+            return( MBEDTLS_ERR_X509_INVALID_ALG +
+                    MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+        if( trailer_field != 1 )
+            return( MBEDTLS_ERR_X509_INVALID_ALG );
+    }
+    else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+        return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+
+    if( p != end )
+        return( MBEDTLS_ERR_X509_INVALID_ALG +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+
+/*
+ *  AttributeTypeAndValue ::= SEQUENCE {
+ *    type     AttributeType,
+ *    value    AttributeValue }
+ *
+ *  AttributeType ::= OBJECT IDENTIFIER
+ *
+ *  AttributeValue ::= ANY DEFINED BY AttributeType
+ */
+static int x509_get_attr_type_value( unsigned char **p,
+                                     const unsigned char *end,
+                                     mbedtls_x509_name *cur )
+{
+    int ret;
+    size_t len;
+    mbedtls_x509_buf *oid;
+    mbedtls_x509_buf *val;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+
+    if( ( end - *p ) < 1 )
+        return( MBEDTLS_ERR_X509_INVALID_NAME +
+                MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    oid = &cur->oid;
+    oid->tag = **p;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+
+    oid->p = *p;
+    *p += oid->len;
+
+    if( ( end - *p ) < 1 )
+        return( MBEDTLS_ERR_X509_INVALID_NAME +
+                MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING      &&
+        **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
+        **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
+        **p != MBEDTLS_ASN1_BIT_STRING )
+        return( MBEDTLS_ERR_X509_INVALID_NAME +
+                MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+    val = &cur->val;
+    val->tag = *(*p)++;
+
+    if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+
+    val->p = *p;
+    *p += val->len;
+
+    cur->next = NULL;
+
+    return( 0 );
+}
+
+/*
+ *  Name ::= CHOICE { -- only one possibility for now --
+ *       rdnSequence  RDNSequence }
+ *
+ *  RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ *
+ *  RelativeDistinguishedName ::=
+ *    SET OF AttributeTypeAndValue
+ *
+ *  AttributeTypeAndValue ::= SEQUENCE {
+ *    type     AttributeType,
+ *    value    AttributeValue }
+ *
+ *  AttributeType ::= OBJECT IDENTIFIER
+ *
+ *  AttributeValue ::= ANY DEFINED BY AttributeType
+ *
+ * The data structure is optimized for the common case where each RDN has only
+ * one element, which is represented as a list of AttributeTypeAndValue.
+ * For the general case we still use a flat list, but we mark elements of the
+ * same set so that they are "merged" together in the functions that consume
+ * this list, eg mbedtls_x509_dn_gets().
+ */
+int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
+                   mbedtls_x509_name *cur )
+{
+    int ret;
+    size_t set_len;
+    const unsigned char *end_set;
+
+    /* don't use recursion, we'd risk stack overflow if not optimized */
+    while( 1 )
+    {
+        /*
+         * parse SET
+         */
+        if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
+                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+
+        end_set  = *p + set_len;
+
+        while( 1 )
+        {
+            if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
+                return( ret );
+
+            if( *p == end_set )
+                break;
+
+            /* Mark this item as being no the only one in a set */
+            cur->next_merged = 1;
+
+            cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
+
+            if( cur->next == NULL )
+                return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+
+            cur = cur->next;
+        }
+
+        /*
+         * continue until end of SEQUENCE is reached
+         */
+        if( *p == end )
+            return( 0 );
+
+        cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
+
+        if( cur->next == NULL )
+            return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+
+        cur = cur->next;
+    }
+}
+
+static int x509_parse_int( unsigned char **p, size_t n, int *res )
+{
+    *res = 0;
+
+    for( ; n > 0; --n )
+    {
+        if( ( **p < '0') || ( **p > '9' ) )
+            return ( MBEDTLS_ERR_X509_INVALID_DATE );
+
+        *res *= 10;
+        *res += ( *(*p)++ - '0' );
+    }
+
+    return( 0 );
+}
+
+static int x509_date_is_valid(const mbedtls_x509_time *t )
+{
+    int ret = MBEDTLS_ERR_X509_INVALID_DATE;
+    int month_len;
+
+    CHECK_RANGE( 0, 9999, t->year );
+    CHECK_RANGE( 0, 23,   t->hour );
+    CHECK_RANGE( 0, 59,   t->min  );
+    CHECK_RANGE( 0, 59,   t->sec  );
+
+    switch( t->mon )
+    {
+        case 1: case 3: case 5: case 7: case 8: case 10: case 12:
+            month_len = 31;
+            break;
+        case 4: case 6: case 9: case 11:
+            month_len = 30;
+            break;
+        case 2:
+            if( ( !( t->year % 4 ) && t->year % 100 ) ||
+                !( t->year % 400 ) )
+                month_len = 29;
+            else
+                month_len = 28;
+            break;
+        default:
+            return( ret );
+    }
+    CHECK_RANGE( 1, month_len, t->day );
+
+    return( 0 );
+}
+
+/*
+ * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4)
+ * field.
+ */
+static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
+                            mbedtls_x509_time *tm )
+{
+    int ret;
+
+    /*
+     * Minimum length is 10 or 12 depending on yearlen
+     */
+    if ( len < yearlen + 8 )
+        return ( MBEDTLS_ERR_X509_INVALID_DATE );
+    len -= yearlen + 8;
+
+    /*
+     * Parse year, month, day, hour, minute
+     */
+    CHECK( x509_parse_int( p, yearlen, &tm->year ) );
+    if ( 2 == yearlen )
+    {
+        if ( tm->year < 50 )
+            tm->year += 100;
+
+        tm->year += 1900;
+    }
+
+    CHECK( x509_parse_int( p, 2, &tm->mon ) );
+    CHECK( x509_parse_int( p, 2, &tm->day ) );
+    CHECK( x509_parse_int( p, 2, &tm->hour ) );
+    CHECK( x509_parse_int( p, 2, &tm->min ) );
+
+    /*
+     * Parse seconds if present
+     */
+    if ( len >= 2 )
+    {
+        CHECK( x509_parse_int( p, 2, &tm->sec ) );
+        len -= 2;
+    }
+    else
+        return ( MBEDTLS_ERR_X509_INVALID_DATE );
+
+    /*
+     * Parse trailing 'Z' if present
+     */
+    if ( 1 == len && 'Z' == **p )
+    {
+        (*p)++;
+        len--;
+    }
+
+    /*
+     * We should have parsed all characters at this point
+     */
+    if ( 0 != len )
+        return ( MBEDTLS_ERR_X509_INVALID_DATE );
+
+    CHECK( x509_date_is_valid( tm ) );
+
+    return ( 0 );
+}
+
+/*
+ *  Time ::= CHOICE {
+ *       utcTime        UTCTime,
+ *       generalTime    GeneralizedTime }
+ */
+int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
+                           mbedtls_x509_time *tm )
+{
+    int ret;
+    size_t len, year_len;
+    unsigned char tag;
+
+    if( ( end - *p ) < 1 )
+        return( MBEDTLS_ERR_X509_INVALID_DATE +
+                MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    tag = **p;
+
+    if( tag == MBEDTLS_ASN1_UTC_TIME )
+        year_len = 2;
+    else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME )
+        year_len = 4;
+    else
+        return( MBEDTLS_ERR_X509_INVALID_DATE +
+                MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+
+    (*p)++;
+    ret = mbedtls_asn1_get_len( p, end, &len );
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
+
+    return x509_parse_time( p, len, year_len, tm );
+}
+
+int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig )
+{
+    int ret;
+    size_t len;
+    int tag_type;
+
+    if( ( end - *p ) < 1 )
+        return( MBEDTLS_ERR_X509_INVALID_SIGNATURE +
+                MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+    tag_type = **p;
+
+    if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret );
+
+    sig->tag = tag_type;
+    sig->len = len;
+    sig->p = *p;
+
+    *p += len;
+
+    return( 0 );
+}
+
+/*
+ * Get signature algorithm from alg OID and optional parameters
+ */
+int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
+                      mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
+                      void **sig_opts )
+{
+    int ret;
+
+    if( *sig_opts != NULL )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
+        return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret );
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+    if( *pk_alg == MBEDTLS_PK_RSASSA_PSS )
+    {
+        mbedtls_pk_rsassa_pss_options *pss_opts;
+
+        pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) );
+        if( pss_opts == NULL )
+            return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+
+        ret = mbedtls_x509_get_rsassa_pss_params( sig_params,
+                                          md_alg,
+                                          &pss_opts->mgf1_hash_id,
+                                          &pss_opts->expected_salt_len );
+        if( ret != 0 )
+        {
+            mbedtls_free( pss_opts );
+            return( ret );
+        }
+
+        *sig_opts = (void *) pss_opts;
+    }
+    else
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+    {
+        /* Make sure parameters are absent or NULL */
+        if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) ||
+              sig_params->len != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_ALG );
+    }
+
+    return( 0 );
+}
+
+/*
+ * X.509 Extensions (No parsing of extensions, pointer should
+ * be either manually updated or extensions should be parsed!)
+ */
+int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
+                  mbedtls_x509_buf *ext, int tag )
+{
+    int ret;
+    size_t len;
+
+    if( *p == end )
+        return( 0 );
+
+    ext->tag = **p;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len,
+            MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ) ) != 0 )
+        return( ret );
+
+    ext->p = *p;
+    end = *p + ext->len;
+
+    /*
+     * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
+     *
+     * Extension  ::=  SEQUENCE  {
+     *      extnID      OBJECT IDENTIFIER,
+     *      critical    BOOLEAN DEFAULT FALSE,
+     *      extnValue   OCTET STRING  }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+    if( end != *p + len )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+/*
+ * Store the name in printable form into buf; no more
+ * than size characters will be written
+ */
+int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
+{
+    int ret;
+    size_t i, n;
+    unsigned char c, merge = 0;
+    const mbedtls_x509_name *name;
+    const char *short_name = NULL;
+    char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
+
+    memset( s, 0, sizeof( s ) );
+
+    name = dn;
+    p = buf;
+    n = size;
+
+    while( name != NULL )
+    {
+        if( !name->oid.p )
+        {
+            name = name->next;
+            continue;
+        }
+
+        if( name != dn )
+        {
+            ret = mbedtls_snprintf( p, n, merge ? " + " : ", " );
+            MBEDTLS_X509_SAFE_SNPRINTF;
+        }
+
+        ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name );
+
+        if( ret == 0 )
+            ret = mbedtls_snprintf( p, n, "%s=", short_name );
+        else
+            ret = mbedtls_snprintf( p, n, "\?\?=" );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        for( i = 0; i < name->val.len; i++ )
+        {
+            if( i >= sizeof( s ) - 1 )
+                break;
+
+            c = name->val.p[i];
+            if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
+                 s[i] = '?';
+            else s[i] = c;
+        }
+        s[i] = '\0';
+        ret = mbedtls_snprintf( p, n, "%s", s );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        merge = name->next_merged;
+        name = name->next;
+    }
+
+    return( (int) ( size - n ) );
+}
+
+/*
+ * Store the serial in printable form into buf; no more
+ * than size characters will be written
+ */
+int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial )
+{
+    int ret;
+    size_t i, n, nr;
+    char *p;
+
+    p = buf;
+    n = size;
+
+    nr = ( serial->len <= 32 )
+        ? serial->len  : 28;
+
+    for( i = 0; i < nr; i++ )
+    {
+        if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
+            continue;
+
+        ret = mbedtls_snprintf( p, n, "%02X%s",
+                serial->p[i], ( i < nr - 1 ) ? ":" : "" );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+    }
+
+    if( nr != serial->len )
+    {
+        ret = mbedtls_snprintf( p, n, "...." );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+    }
+
+    return( (int) ( size - n ) );
+}
+
+/*
+ * Helper for writing signature algorithms
+ */
+int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
+                       mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
+                       const void *sig_opts )
+{
+    int ret;
+    char *p = buf;
+    size_t n = size;
+    const char *desc = NULL;
+
+    ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc );
+    if( ret != 0 )
+        ret = mbedtls_snprintf( p, n, "???"  );
+    else
+        ret = mbedtls_snprintf( p, n, "%s", desc );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+    if( pk_alg == MBEDTLS_PK_RSASSA_PSS )
+    {
+        const mbedtls_pk_rsassa_pss_options *pss_opts;
+        const mbedtls_md_info_t *md_info, *mgf_md_info;
+
+        pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
+
+        md_info = mbedtls_md_info_from_type( md_alg );
+        mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id );
+
+        ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
+                              md_info ? mbedtls_md_get_name( md_info ) : "???",
+                              mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???",
+                              pss_opts->expected_salt_len );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+    }
+#else
+    ((void) pk_alg);
+    ((void) md_alg);
+    ((void) sig_opts);
+#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
+
+    return( (int)( size - n ) );
+}
+
+/*
+ * Helper for writing "RSA key size", "EC key size", etc
+ */
+int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
+{
+    char *p = buf;
+    size_t n = buf_size;
+    int ret;
+
+    ret = mbedtls_snprintf( p, n, "%s key size", name );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_HAVE_TIME_DATE)
+/*
+ * Set the time structure to the current time.
+ * Return 0 on success, non-zero on failure.
+ */
+static int x509_get_current_time( mbedtls_x509_time *now )
+{
+    struct tm *lt, tm_buf;
+    mbedtls_time_t tt;
+    int ret = 0;
+
+    tt = mbedtls_time( NULL );
+    lt = mbedtls_platform_gmtime_r( &tt, &tm_buf );
+
+    if( lt == NULL )
+        ret = -1;
+    else
+    {
+        now->year = lt->tm_year + 1900;
+        now->mon  = lt->tm_mon  + 1;
+        now->day  = lt->tm_mday;
+        now->hour = lt->tm_hour;
+        now->min  = lt->tm_min;
+        now->sec  = lt->tm_sec;
+    }
+
+    return( ret );
+}
+
+/*
+ * Return 0 if before <= after, 1 otherwise
+ */
+static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after )
+{
+    if( before->year  > after->year )
+        return( 1 );
+
+    if( before->year == after->year &&
+        before->mon   > after->mon )
+        return( 1 );
+
+    if( before->year == after->year &&
+        before->mon  == after->mon  &&
+        before->day   > after->day )
+        return( 1 );
+
+    if( before->year == after->year &&
+        before->mon  == after->mon  &&
+        before->day  == after->day  &&
+        before->hour  > after->hour )
+        return( 1 );
+
+    if( before->year == after->year &&
+        before->mon  == after->mon  &&
+        before->day  == after->day  &&
+        before->hour == after->hour &&
+        before->min   > after->min  )
+        return( 1 );
+
+    if( before->year == after->year &&
+        before->mon  == after->mon  &&
+        before->day  == after->day  &&
+        before->hour == after->hour &&
+        before->min  == after->min  &&
+        before->sec   > after->sec  )
+        return( 1 );
+
+    return( 0 );
+}
+
+int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
+{
+    mbedtls_x509_time now;
+
+    if( x509_get_current_time( &now ) != 0 )
+        return( 1 );
+
+    return( x509_check_time( &now, to ) );
+}
+
+int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
+{
+    mbedtls_x509_time now;
+
+    if( x509_get_current_time( &now ) != 0 )
+        return( 1 );
+
+    return( x509_check_time( from, &now ) );
+}
+
+#else  /* MBEDTLS_HAVE_TIME_DATE */
+
+int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
+{
+    ((void) to);
+    return( 0 );
+}
+
+int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
+{
+    ((void) from);
+    return( 0 );
+}
+#endif /* MBEDTLS_HAVE_TIME_DATE */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/certs.h"
+
+/*
+ * Checkup routine
+ */
+int mbedtls_x509_self_test( int verbose )
+{
+#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C)
+    int ret;
+    uint32_t flags;
+    mbedtls_x509_crt cacert;
+    mbedtls_x509_crt clicert;
+
+    if( verbose != 0 )
+        mbedtls_printf( "  X.509 certificate load: " );
+
+    mbedtls_x509_crt_init( &clicert );
+
+    ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt,
+                           mbedtls_test_cli_crt_len );
+    if( ret != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        return( ret );
+    }
+
+    mbedtls_x509_crt_init( &cacert );
+
+    ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt,
+                          mbedtls_test_ca_crt_len );
+    if( ret != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        return( ret );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n  X.509 signature verify: ");
+
+    ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
+    if( ret != 0 )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "failed\n" );
+
+        return( ret );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "passed\n\n");
+
+    mbedtls_x509_crt_free( &cacert  );
+    mbedtls_x509_crt_free( &clicert );
+
+    return( 0 );
+#else
+    ((void) verbose);
+    return( 0 );
+#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_X509_USE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_create.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_create.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_create.c	(revision 398)
@@ -0,0 +1,379 @@
+/*
+ *  X.509 base functions for creating certificates / CSRs
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_X509_CREATE_C)
+
+#include "mbedtls/x509.h"
+#include "mbedtls/asn1write.h"
+#include "mbedtls/oid.h"
+
+#include <string.h>
+
+/* Structure linking OIDs for X.509 DN AttributeTypes to their
+ * string representations and default string encodings used by Mbed TLS. */
+typedef struct {
+   const char *name; /* String representation of AttributeType, e.g.
+                      * "CN" or "emailAddress". */
+   size_t name_len;  /* Length of 'name', without trailing 0 byte. */
+   const char *oid;  /* String representation of OID of AttributeType,
+                      * as per RFC 5280, Appendix A.1. */
+   int default_tag;  /* The default character encoding used for the
+                      * given attribute type, e.g.
+                      * MBEDTLS_ASN1_UTF8_STRING for UTF-8. */
+} x509_attr_descriptor_t;
+
+#define ADD_STRLEN( s )     s, sizeof( s ) - 1
+
+/* X.509 DN attributes from RFC 5280, Appendix A.1. */
+static const x509_attr_descriptor_t x509_attrs[] =
+{
+    { ADD_STRLEN( "CN" ),
+      MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "commonName" ),
+      MBEDTLS_OID_AT_CN, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "C" ),
+      MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING },
+    { ADD_STRLEN( "countryName" ),
+      MBEDTLS_OID_AT_COUNTRY, MBEDTLS_ASN1_PRINTABLE_STRING },
+    { ADD_STRLEN( "O" ),
+      MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "organizationName" ),
+      MBEDTLS_OID_AT_ORGANIZATION, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "L" ),
+      MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "locality" ),
+      MBEDTLS_OID_AT_LOCALITY, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "R" ),
+      MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING },
+    { ADD_STRLEN( "OU" ),
+      MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "organizationalUnitName" ),
+      MBEDTLS_OID_AT_ORG_UNIT, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "ST" ),
+      MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "stateOrProvinceName" ),
+      MBEDTLS_OID_AT_STATE, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "emailAddress" ),
+      MBEDTLS_OID_PKCS9_EMAIL, MBEDTLS_ASN1_IA5_STRING },
+    { ADD_STRLEN( "serialNumber" ),
+      MBEDTLS_OID_AT_SERIAL_NUMBER, MBEDTLS_ASN1_PRINTABLE_STRING },
+    { ADD_STRLEN( "postalAddress" ),
+      MBEDTLS_OID_AT_POSTAL_ADDRESS, MBEDTLS_ASN1_PRINTABLE_STRING },
+    { ADD_STRLEN( "postalCode" ),
+      MBEDTLS_OID_AT_POSTAL_CODE, MBEDTLS_ASN1_PRINTABLE_STRING },
+    { ADD_STRLEN( "dnQualifier" ),
+      MBEDTLS_OID_AT_DN_QUALIFIER, MBEDTLS_ASN1_PRINTABLE_STRING },
+    { ADD_STRLEN( "title" ),
+      MBEDTLS_OID_AT_TITLE, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "surName" ),
+      MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "SN" ),
+      MBEDTLS_OID_AT_SUR_NAME, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "givenName" ),
+      MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "GN" ),
+      MBEDTLS_OID_AT_GIVEN_NAME, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "initials" ),
+      MBEDTLS_OID_AT_INITIALS, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "pseudonym" ),
+      MBEDTLS_OID_AT_PSEUDONYM, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "generationQualifier" ),
+      MBEDTLS_OID_AT_GENERATION_QUALIFIER, MBEDTLS_ASN1_UTF8_STRING },
+    { ADD_STRLEN( "domainComponent" ),
+      MBEDTLS_OID_DOMAIN_COMPONENT, MBEDTLS_ASN1_IA5_STRING },
+    { ADD_STRLEN( "DC" ),
+      MBEDTLS_OID_DOMAIN_COMPONENT,   MBEDTLS_ASN1_IA5_STRING },
+    { NULL, 0, NULL, MBEDTLS_ASN1_NULL }
+};
+
+static const x509_attr_descriptor_t *x509_attr_descr_from_name( const char *name, size_t name_len )
+{
+    const x509_attr_descriptor_t *cur;
+
+    for( cur = x509_attrs; cur->name != NULL; cur++ )
+        if( cur->name_len == name_len &&
+            strncmp( cur->name, name, name_len ) == 0 )
+            break;
+
+    if ( cur->name == NULL )
+        return( NULL );
+
+    return( cur );
+}
+
+int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name )
+{
+    int ret = 0;
+    const char *s = name, *c = s;
+    const char *end = s + strlen( s );
+    const char *oid = NULL;
+    const x509_attr_descriptor_t* attr_descr = NULL;
+    int in_tag = 1;
+    char data[MBEDTLS_X509_MAX_DN_NAME_SIZE];
+    char *d = data;
+
+    /* Clear existing chain if present */
+    mbedtls_asn1_free_named_data_list( head );
+
+    while( c <= end )
+    {
+        if( in_tag && *c == '=' )
+        {
+            if( ( attr_descr = x509_attr_descr_from_name( s, c - s ) ) == NULL )
+            {
+                ret = MBEDTLS_ERR_X509_UNKNOWN_OID;
+                goto exit;
+            }
+
+            oid = attr_descr->oid;
+            s = c + 1;
+            in_tag = 0;
+            d = data;
+        }
+
+        if( !in_tag && *c == '\\' && c != end )
+        {
+            c++;
+
+            /* Check for valid escaped characters */
+            if( c == end || *c != ',' )
+            {
+                ret = MBEDTLS_ERR_X509_INVALID_NAME;
+                goto exit;
+            }
+        }
+        else if( !in_tag && ( *c == ',' || c == end ) )
+        {
+            mbedtls_asn1_named_data* cur =
+                mbedtls_asn1_store_named_data( head, oid, strlen( oid ),
+                                               (unsigned char *) data,
+                                               d - data );
+
+            if(cur == NULL )
+            {
+                return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+            }
+
+            // set tagType
+            cur->val.tag = attr_descr->default_tag;
+
+            while( c < end && *(c + 1) == ' ' )
+                c++;
+
+            s = c + 1;
+            in_tag = 1;
+        }
+
+        if( !in_tag && s != c + 1 )
+        {
+            *(d++) = *c;
+
+            if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE )
+            {
+                ret = MBEDTLS_ERR_X509_INVALID_NAME;
+                goto exit;
+            }
+        }
+
+        c++;
+    }
+
+exit:
+
+    return( ret );
+}
+
+/* The first byte of the value in the mbedtls_asn1_named_data structure is reserved
+ * to store the critical boolean for us
+ */
+int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len,
+                        int critical, const unsigned char *val, size_t val_len )
+{
+    mbedtls_asn1_named_data *cur;
+
+    if( ( cur = mbedtls_asn1_store_named_data( head, oid, oid_len,
+                                       NULL, val_len + 1 ) ) == NULL )
+    {
+        return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+    }
+
+    cur->val.p[0] = critical;
+    memcpy( cur->val.p + 1, val, val_len );
+
+    return( 0 );
+}
+
+/*
+ *  RelativeDistinguishedName ::=
+ *    SET OF AttributeTypeAndValue
+ *
+ *  AttributeTypeAndValue ::= SEQUENCE {
+ *    type     AttributeType,
+ *    value    AttributeValue }
+ *
+ *  AttributeType ::= OBJECT IDENTIFIER
+ *
+ *  AttributeValue ::= ANY DEFINED BY AttributeType
+ */
+static int x509_write_name( unsigned char **p, unsigned char *start, mbedtls_asn1_named_data* cur_name)
+{
+    int ret;
+    size_t len = 0;
+    const char *oid             = (const char*)cur_name->oid.p;
+    size_t oid_len              = cur_name->oid.len;
+    const unsigned char *name   = cur_name->val.p;
+    size_t name_len             = cur_name->val.len;
+
+    // Write correct string tag and value
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tagged_string( p, start,
+                                                       cur_name->val.tag,
+                                                       (const char *) name,
+                                                       name_len ) );
+    // Write OID
+    //
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid,
+                                                       oid_len ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
+                                                    MBEDTLS_ASN1_CONSTRUCTED |
+                                                    MBEDTLS_ASN1_SEQUENCE ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start,
+                                                 MBEDTLS_ASN1_CONSTRUCTED |
+                                                 MBEDTLS_ASN1_SET ) );
+
+    return( (int) len );
+}
+
+int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
+                              mbedtls_asn1_named_data *first )
+{
+    int ret;
+    size_t len = 0;
+    mbedtls_asn1_named_data *cur = first;
+
+    while( cur != NULL )
+    {
+        MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, cur ) );
+        cur = cur->next;
+    }
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
+                                                 MBEDTLS_ASN1_SEQUENCE ) );
+
+    return( (int) len );
+}
+
+int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
+                    const char *oid, size_t oid_len,
+                    unsigned char *sig, size_t size )
+{
+    int ret;
+    size_t len = 0;
+
+    if( *p < start || (size_t)( *p - start ) < size )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    len = size;
+    (*p) -= len;
+    memcpy( *p, sig, len );
+
+    if( *p - start < 1 )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    *--(*p) = 0;
+    len += 1;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) );
+
+    // Write OID
+    //
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid,
+                                                        oid_len, 0 ) );
+
+    return( (int) len );
+}
+
+static int x509_write_extension( unsigned char **p, unsigned char *start,
+                                 mbedtls_asn1_named_data *ext )
+{
+    int ret;
+    size_t len = 0;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1,
+                                              ext->val.len - 1 ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->val.len - 1 ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) );
+
+    if( ext->val.p[0] != 0 )
+    {
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( p, start, 1 ) );
+    }
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->oid.p,
+                                              ext->oid.len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->oid.len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
+                                                 MBEDTLS_ASN1_SEQUENCE ) );
+
+    return( (int) len );
+}
+
+/*
+ * Extension  ::=  SEQUENCE  {
+ *     extnID      OBJECT IDENTIFIER,
+ *     critical    BOOLEAN DEFAULT FALSE,
+ *     extnValue   OCTET STRING
+ *                 -- contains the DER encoding of an ASN.1 value
+ *                 -- corresponding to the extension type identified
+ *                 -- by extnID
+ *     }
+ */
+int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
+                           mbedtls_asn1_named_data *first )
+{
+    int ret;
+    size_t len = 0;
+    mbedtls_asn1_named_data *cur_ext = first;
+
+    while( cur_ext != NULL )
+    {
+        MBEDTLS_ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) );
+        cur_ext = cur_ext->next;
+    }
+
+    return( (int) len );
+}
+
+#endif /* MBEDTLS_X509_CREATE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_crl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_crl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_crl.c	(revision 398)
@@ -0,0 +1,773 @@
+/*
+ *  X.509 Certidicate Revocation List (CRL) parsing
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The ITU-T X.509 standard defines a certificate format for PKI.
+ *
+ *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
+ *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
+ *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
+ *
+ *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
+ *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
+
+#include "mbedtls/x509_crl.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+#include "mbedtls/pem.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#define mbedtls_free       free
+#define mbedtls_calloc    calloc
+#define mbedtls_snprintf   snprintf
+#endif
+
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+#include <windows.h>
+#else
+#include <time.h>
+#endif
+
+#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
+#include <stdio.h>
+#endif
+
+/*
+ *  Version  ::=  INTEGER  {  v1(0), v2(1)  }
+ */
+static int x509_crl_get_version( unsigned char **p,
+                             const unsigned char *end,
+                             int *ver )
+{
+    int ret;
+
+    if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+        {
+            *ver = 0;
+            return( 0 );
+        }
+
+        return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * X.509 CRL v2 extensions
+ *
+ * We currently don't parse any extension's content, but we do check that the
+ * list of extensions is well-formed and abort on critical extensions (that
+ * are unsupported as we don't support any extension so far)
+ */
+static int x509_get_crl_ext( unsigned char **p,
+                             const unsigned char *end,
+                             mbedtls_x509_buf *ext )
+{
+    int ret;
+
+    /*
+     * crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
+     *                              -- if present, version MUST be v2
+     */
+    if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0 ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+            return( 0 );
+
+        return( ret );
+    }
+
+    while( *p < end )
+    {
+        /*
+         * Extension  ::=  SEQUENCE  {
+         *      extnID      OBJECT IDENTIFIER,
+         *      critical    BOOLEAN DEFAULT FALSE,
+         *      extnValue   OCTET STRING  }
+         */
+        int is_critical = 0;
+        const unsigned char *end_ext_data;
+        size_t len;
+
+        /* Get enclosing sequence tag */
+        if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+        end_ext_data = *p + len;
+
+        /* Get OID (currently ignored) */
+        if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
+                                          MBEDTLS_ASN1_OID ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+        }
+        *p += len;
+
+        /* Get optional critical */
+        if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data,
+                                           &is_critical ) ) != 0 &&
+            ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
+        {
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+        }
+
+        /* Data should be octet string type */
+        if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
+                MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+        /* Ignore data so far and just check its length */
+        *p += len;
+        if( *p != end_ext_data )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                    MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+        /* Abort on (unsupported) critical extensions */
+        if( is_critical )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                    MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+    }
+
+    if( *p != end )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+/*
+ * X.509 CRL v2 entry extensions (no extensions parsed yet.)
+ */
+static int x509_get_crl_entry_ext( unsigned char **p,
+                             const unsigned char *end,
+                             mbedtls_x509_buf *ext )
+{
+    int ret;
+    size_t len = 0;
+
+    /* OPTIONAL */
+    if( end <= *p )
+        return( 0 );
+
+    ext->tag = **p;
+    ext->p = *p;
+
+    /*
+     * Get CRL-entry extension sequence header
+     * crlEntryExtensions      Extensions OPTIONAL  -- if present, MUST be v2
+     */
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+        {
+            ext->p = NULL;
+            return( 0 );
+        }
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+    }
+
+    end = *p + ext->len;
+
+    if( end != *p + ext->len )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    while( *p < end )
+    {
+        if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+        *p += len;
+    }
+
+    if( *p != end )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+/*
+ * X.509 CRL Entries
+ */
+static int x509_get_entries( unsigned char **p,
+                             const unsigned char *end,
+                             mbedtls_x509_crl_entry *entry )
+{
+    int ret;
+    size_t entry_len;
+    mbedtls_x509_crl_entry *cur_entry = entry;
+
+    if( *p == end )
+        return( 0 );
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &entry_len,
+            MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+            return( 0 );
+
+        return( ret );
+    }
+
+    end = *p + entry_len;
+
+    while( *p < end )
+    {
+        size_t len2;
+        const unsigned char *end2;
+
+        if( ( ret = mbedtls_asn1_get_tag( p, end, &len2,
+                MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 )
+        {
+            return( ret );
+        }
+
+        cur_entry->raw.tag = **p;
+        cur_entry->raw.p = *p;
+        cur_entry->raw.len = len2;
+        end2 = *p + len2;
+
+        if( ( ret = mbedtls_x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
+            return( ret );
+
+        if( ( ret = mbedtls_x509_get_time( p, end2,
+                                   &cur_entry->revocation_date ) ) != 0 )
+            return( ret );
+
+        if( ( ret = x509_get_crl_entry_ext( p, end2,
+                                            &cur_entry->entry_ext ) ) != 0 )
+            return( ret );
+
+        if( *p < end )
+        {
+            cur_entry->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl_entry ) );
+
+            if( cur_entry->next == NULL )
+                return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+
+            cur_entry = cur_entry->next;
+        }
+    }
+
+    return( 0 );
+}
+
+/*
+ * Parse one  CRLs in DER format and append it to the chained list
+ */
+int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
+                        const unsigned char *buf, size_t buflen )
+{
+    int ret;
+    size_t len;
+    unsigned char *p = NULL, *end = NULL;
+    mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
+    mbedtls_x509_crl *crl = chain;
+
+    /*
+     * Check for valid input
+     */
+    if( crl == NULL || buf == NULL )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
+    memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
+    memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
+
+    /*
+     * Add new CRL on the end of the chain if needed.
+     */
+    while( crl->version != 0 && crl->next != NULL )
+        crl = crl->next;
+
+    if( crl->version != 0 && crl->next == NULL )
+    {
+        crl->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl ) );
+
+        if( crl->next == NULL )
+        {
+            mbedtls_x509_crl_free( crl );
+            return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+        }
+
+        mbedtls_x509_crl_init( crl->next );
+        crl = crl->next;
+    }
+
+    /*
+     * Copy raw DER-encoded CRL
+     */
+    if( buflen == 0 )
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT );
+
+    p = mbedtls_calloc( 1, buflen );
+    if( p == NULL )
+        return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+
+    memcpy( p, buf, buflen );
+
+    crl->raw.p = p;
+    crl->raw.len = buflen;
+
+    end = p + buflen;
+
+    /*
+     * CertificateList  ::=  SEQUENCE  {
+     *      tbsCertList          TBSCertList,
+     *      signatureAlgorithm   AlgorithmIdentifier,
+     *      signatureValue       BIT STRING  }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT );
+    }
+
+    if( len != (size_t) ( end - p ) )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+
+    /*
+     * TBSCertList  ::=  SEQUENCE  {
+     */
+    crl->tbs.p = p;
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+    }
+
+    end = p + len;
+    crl->tbs.len = end - crl->tbs.p;
+
+    /*
+     * Version  ::=  INTEGER  OPTIONAL {  v1(0), v2(1)  }
+     *               -- if present, MUST be v2
+     *
+     * signature            AlgorithmIdentifier
+     */
+    if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
+        ( ret = mbedtls_x509_get_alg( &p, end, &crl->sig_oid, &sig_params1 ) ) != 0 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( ret );
+    }
+
+    if( crl->version < 0 || crl->version > 1 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
+    }
+
+    crl->version++;
+
+    if( ( ret = mbedtls_x509_get_sig_alg( &crl->sig_oid, &sig_params1,
+                                  &crl->sig_md, &crl->sig_pk,
+                                  &crl->sig_opts ) ) != 0 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
+    }
+
+    /*
+     * issuer               Name
+     */
+    crl->issuer_raw.p = p;
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+    }
+
+    if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( ret );
+    }
+
+    crl->issuer_raw.len = p - crl->issuer_raw.p;
+
+    /*
+     * thisUpdate          Time
+     * nextUpdate          Time OPTIONAL
+     */
+    if( ( ret = mbedtls_x509_get_time( &p, end, &crl->this_update ) ) != 0 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_x509_get_time( &p, end, &crl->next_update ) ) != 0 )
+    {
+        if( ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
+                        MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) &&
+            ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
+                        MBEDTLS_ERR_ASN1_OUT_OF_DATA ) )
+        {
+            mbedtls_x509_crl_free( crl );
+            return( ret );
+        }
+    }
+
+    /*
+     * revokedCertificates    SEQUENCE OF SEQUENCE   {
+     *      userCertificate        CertificateSerialNumber,
+     *      revocationDate         Time,
+     *      crlEntryExtensions     Extensions OPTIONAL
+     *                                   -- if present, MUST be v2
+     *                        } OPTIONAL
+     */
+    if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( ret );
+    }
+
+    /*
+     * crlExtensions          EXPLICIT Extensions OPTIONAL
+     *                              -- if present, MUST be v2
+     */
+    if( crl->version == 2 )
+    {
+        ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
+
+        if( ret != 0 )
+        {
+            mbedtls_x509_crl_free( crl );
+            return( ret );
+        }
+    }
+
+    if( p != end )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+
+    end = crl->raw.p + crl->raw.len;
+
+    /*
+     *  signatureAlgorithm   AlgorithmIdentifier,
+     *  signatureValue       BIT STRING
+     */
+    if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( ret );
+    }
+
+    if( crl->sig_oid.len != sig_oid2.len ||
+        memcmp( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 ||
+        sig_params1.len != sig_params2.len ||
+        ( sig_params1.len != 0 &&
+          memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( MBEDTLS_ERR_X509_SIG_MISMATCH );
+    }
+
+    if( ( ret = mbedtls_x509_get_sig( &p, end, &crl->sig ) ) != 0 )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( ret );
+    }
+
+    if( p != end )
+    {
+        mbedtls_x509_crl_free( crl );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Parse one or more CRLs and add them to the chained list
+ */
+int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen )
+{
+#if defined(MBEDTLS_PEM_PARSE_C)
+    int ret;
+    size_t use_len;
+    mbedtls_pem_context pem;
+    int is_pem = 0;
+
+    if( chain == NULL || buf == NULL )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    do
+    {
+        mbedtls_pem_init( &pem );
+
+        // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated
+        // string
+        if( buflen == 0 || buf[buflen - 1] != '\0' )
+            ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+        else
+            ret = mbedtls_pem_read_buffer( &pem,
+                                           "-----BEGIN X509 CRL-----",
+                                           "-----END X509 CRL-----",
+                                            buf, NULL, 0, &use_len );
+
+        if( ret == 0 )
+        {
+            /*
+             * Was PEM encoded
+             */
+            is_pem = 1;
+
+            buflen -= use_len;
+            buf += use_len;
+
+            if( ( ret = mbedtls_x509_crl_parse_der( chain,
+                                            pem.buf, pem.buflen ) ) != 0 )
+            {
+                mbedtls_pem_free( &pem );
+                return( ret );
+            }
+        }
+        else if( is_pem )
+        {
+            mbedtls_pem_free( &pem );
+            return( ret );
+        }
+
+        mbedtls_pem_free( &pem );
+    }
+    /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte.
+     * And a valid CRL cannot be less than 1 byte anyway. */
+    while( is_pem && buflen > 1 );
+
+    if( is_pem )
+        return( 0 );
+    else
+#endif /* MBEDTLS_PEM_PARSE_C */
+        return( mbedtls_x509_crl_parse_der( chain, buf, buflen ) );
+}
+
+#if defined(MBEDTLS_FS_IO)
+/*
+ * Load one or more CRLs and add them to the chained list
+ */
+int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path )
+{
+    int ret;
+    size_t n;
+    unsigned char *buf;
+
+    if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
+
+    ret = mbedtls_x509_crl_parse( chain, buf, n );
+
+    mbedtls_platform_zeroize( buf, n );
+    mbedtls_free( buf );
+
+    return( ret );
+}
+#endif /* MBEDTLS_FS_IO */
+
+/*
+ * Return an informational string about the certificate.
+ */
+#define BEFORE_COLON    14
+#define BC              "14"
+/*
+ * Return an informational string about the CRL.
+ */
+int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
+                   const mbedtls_x509_crl *crl )
+{
+    int ret;
+    size_t n;
+    char *p;
+    const mbedtls_x509_crl_entry *entry;
+
+    p = buf;
+    n = size;
+
+    ret = mbedtls_snprintf( p, n, "%sCRL version   : %d",
+                               prefix, crl->version );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n%sissuer name   : ", prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+    ret = mbedtls_x509_dn_gets( p, n, &crl->issuer );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n%sthis update   : " \
+                   "%04d-%02d-%02d %02d:%02d:%02d", prefix,
+                   crl->this_update.year, crl->this_update.mon,
+                   crl->this_update.day,  crl->this_update.hour,
+                   crl->this_update.min,  crl->this_update.sec );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n%snext update   : " \
+                   "%04d-%02d-%02d %02d:%02d:%02d", prefix,
+                   crl->next_update.year, crl->next_update.mon,
+                   crl->next_update.day,  crl->next_update.hour,
+                   crl->next_update.min,  crl->next_update.sec );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    entry = &crl->entry;
+
+    ret = mbedtls_snprintf( p, n, "\n%sRevoked certificates:",
+                               prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    while( entry != NULL && entry->raw.len != 0 )
+    {
+        ret = mbedtls_snprintf( p, n, "\n%sserial number: ",
+                               prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        ret = mbedtls_x509_serial_gets( p, n, &entry->serial );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        ret = mbedtls_snprintf( p, n, " revocation date: " \
+                   "%04d-%02d-%02d %02d:%02d:%02d",
+                   entry->revocation_date.year, entry->revocation_date.mon,
+                   entry->revocation_date.day,  entry->revocation_date.hour,
+                   entry->revocation_date.min,  entry->revocation_date.sec );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        entry = entry->next;
+    }
+
+    ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
+                             crl->sig_opts );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n" );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    return( (int) ( size - n ) );
+}
+
+/*
+ * Initialize a CRL chain
+ */
+void mbedtls_x509_crl_init( mbedtls_x509_crl *crl )
+{
+    memset( crl, 0, sizeof(mbedtls_x509_crl) );
+}
+
+/*
+ * Unallocate all CRL data
+ */
+void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
+{
+    mbedtls_x509_crl *crl_cur = crl;
+    mbedtls_x509_crl *crl_prv;
+    mbedtls_x509_name *name_cur;
+    mbedtls_x509_name *name_prv;
+    mbedtls_x509_crl_entry *entry_cur;
+    mbedtls_x509_crl_entry *entry_prv;
+
+    if( crl == NULL )
+        return;
+
+    do
+    {
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+        mbedtls_free( crl_cur->sig_opts );
+#endif
+
+        name_cur = crl_cur->issuer.next;
+        while( name_cur != NULL )
+        {
+            name_prv = name_cur;
+            name_cur = name_cur->next;
+            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+            mbedtls_free( name_prv );
+        }
+
+        entry_cur = crl_cur->entry.next;
+        while( entry_cur != NULL )
+        {
+            entry_prv = entry_cur;
+            entry_cur = entry_cur->next;
+            mbedtls_platform_zeroize( entry_prv,
+                                      sizeof( mbedtls_x509_crl_entry ) );
+            mbedtls_free( entry_prv );
+        }
+
+        if( crl_cur->raw.p != NULL )
+        {
+            mbedtls_platform_zeroize( crl_cur->raw.p, crl_cur->raw.len );
+            mbedtls_free( crl_cur->raw.p );
+        }
+
+        crl_cur = crl_cur->next;
+    }
+    while( crl_cur != NULL );
+
+    crl_cur = crl;
+    do
+    {
+        crl_prv = crl_cur;
+        crl_cur = crl_cur->next;
+
+        mbedtls_platform_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) );
+        if( crl_prv != crl )
+            mbedtls_free( crl_prv );
+    }
+    while( crl_cur != NULL );
+}
+
+#endif /* MBEDTLS_X509_CRL_PARSE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_crt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_crt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_crt.c	(revision 398)
@@ -0,0 +1,2733 @@
+/*
+ *  X.509 certificate parsing and verification
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The ITU-T X.509 standard defines a certificate format for PKI.
+ *
+ *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
+ *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
+ *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
+ *
+ *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
+ *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
+ *
+ *  [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+#include "mbedtls/pem.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_free       free
+#define mbedtls_calloc    calloc
+#define mbedtls_snprintf   snprintf
+#endif
+
+#if defined(MBEDTLS_THREADING_C)
+#include "mbedtls/threading.h"
+#endif
+
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+#include <windows.h>
+#else
+#include <time.h>
+#endif
+
+#if defined(MBEDTLS_FS_IO)
+#include <stdio.h>
+#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#endif /* !_WIN32 || EFIX64 || EFI32 */
+#endif
+
+/*
+ * Item in a verification chain: cert and flags for it
+ */
+typedef struct {
+    mbedtls_x509_crt *crt;
+    uint32_t flags;
+} x509_crt_verify_chain_item;
+
+/*
+ * Max size of verification chain: end-entity + intermediates + trusted root
+ */
+#define X509_MAX_VERIFY_CHAIN_SIZE    ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 )
+
+/*
+ * Default profile
+ */
+const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
+{
+#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES)
+    /* Allow SHA-1 (weak, but still safe in controlled environments) */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
+#endif
+    /* Only SHA-2 hashes */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
+    0xFFFFFFF, /* Any PK alg    */
+    0xFFFFFFF, /* Any curve     */
+    2048,
+};
+
+/*
+ * Next-default profile
+ */
+const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
+{
+    /* Hashes from SHA-256 and above */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
+    0xFFFFFFF, /* Any PK alg    */
+#if defined(MBEDTLS_ECP_C)
+    /* Curves at or above 128-bit security level */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ),
+#else
+    0,
+#endif
+    2048,
+};
+
+/*
+ * NSA Suite B Profile
+ */
+const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
+{
+    /* Only SHA-256 and 384 */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
+    /* Only ECDSA */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ),
+#if defined(MBEDTLS_ECP_C)
+    /* Only NIST P-256 and P-384 */
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
+    MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ),
+#else
+    0,
+#endif
+    0,
+};
+
+/*
+ * Check md_alg against profile
+ * Return 0 if md_alg is acceptable for this profile, -1 otherwise
+ */
+static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
+                                      mbedtls_md_type_t md_alg )
+{
+    if( md_alg == MBEDTLS_MD_NONE )
+        return( -1 );
+
+    if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 )
+        return( 0 );
+
+    return( -1 );
+}
+
+/*
+ * Check pk_alg against profile
+ * Return 0 if pk_alg is acceptable for this profile, -1 otherwise
+ */
+static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile,
+                                      mbedtls_pk_type_t pk_alg )
+{
+    if( pk_alg == MBEDTLS_PK_NONE )
+        return( -1 );
+
+    if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 )
+        return( 0 );
+
+    return( -1 );
+}
+
+/*
+ * Check key against profile
+ * Return 0 if pk is acceptable for this profile, -1 otherwise
+ */
+static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
+                                   const mbedtls_pk_context *pk )
+{
+    const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type( pk );
+
+#if defined(MBEDTLS_RSA_C)
+    if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS )
+    {
+        if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen )
+            return( 0 );
+
+        return( -1 );
+    }
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+    if( pk_alg == MBEDTLS_PK_ECDSA ||
+        pk_alg == MBEDTLS_PK_ECKEY ||
+        pk_alg == MBEDTLS_PK_ECKEY_DH )
+    {
+        const mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
+
+        if( gid == MBEDTLS_ECP_DP_NONE )
+            return( -1 );
+
+        if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 )
+            return( 0 );
+
+        return( -1 );
+    }
+#endif
+
+    return( -1 );
+}
+
+/*
+ * Like memcmp, but case-insensitive and always returns -1 if different
+ */
+static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
+{
+    size_t i;
+    unsigned char diff;
+    const unsigned char *n1 = s1, *n2 = s2;
+
+    for( i = 0; i < len; i++ )
+    {
+        diff = n1[i] ^ n2[i];
+
+        if( diff == 0 )
+            continue;
+
+        if( diff == 32 &&
+            ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
+              ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
+        {
+            continue;
+        }
+
+        return( -1 );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Return 0 if name matches wildcard, -1 otherwise
+ */
+static int x509_check_wildcard( const char *cn, const mbedtls_x509_buf *name )
+{
+    size_t i;
+    size_t cn_idx = 0, cn_len = strlen( cn );
+
+    /* We can't have a match if there is no wildcard to match */
+    if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
+        return( -1 );
+
+    for( i = 0; i < cn_len; ++i )
+    {
+        if( cn[i] == '.' )
+        {
+            cn_idx = i;
+            break;
+        }
+    }
+
+    if( cn_idx == 0 )
+        return( -1 );
+
+    if( cn_len - cn_idx == name->len - 1 &&
+        x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
+    {
+        return( 0 );
+    }
+
+    return( -1 );
+}
+
+/*
+ * Compare two X.509 strings, case-insensitive, and allowing for some encoding
+ * variations (but not all).
+ *
+ * Return 0 if equal, -1 otherwise.
+ */
+static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b )
+{
+    if( a->tag == b->tag &&
+        a->len == b->len &&
+        memcmp( a->p, b->p, b->len ) == 0 )
+    {
+        return( 0 );
+    }
+
+    if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
+        ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
+        a->len == b->len &&
+        x509_memcasecmp( a->p, b->p, b->len ) == 0 )
+    {
+        return( 0 );
+    }
+
+    return( -1 );
+}
+
+/*
+ * Compare two X.509 Names (aka rdnSequence).
+ *
+ * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
+ * we sometimes return unequal when the full algorithm would return equal,
+ * but never the other way. (In particular, we don't do Unicode normalisation
+ * or space folding.)
+ *
+ * Return 0 if equal, -1 otherwise.
+ */
+static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b )
+{
+    /* Avoid recursion, it might not be optimised by the compiler */
+    while( a != NULL || b != NULL )
+    {
+        if( a == NULL || b == NULL )
+            return( -1 );
+
+        /* type */
+        if( a->oid.tag != b->oid.tag ||
+            a->oid.len != b->oid.len ||
+            memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
+        {
+            return( -1 );
+        }
+
+        /* value */
+        if( x509_string_cmp( &a->val, &b->val ) != 0 )
+            return( -1 );
+
+        /* structure of the list of sets */
+        if( a->next_merged != b->next_merged )
+            return( -1 );
+
+        a = a->next;
+        b = b->next;
+    }
+
+    /* a == NULL == b */
+    return( 0 );
+}
+
+/*
+ * Reset (init or clear) a verify_chain
+ */
+static void x509_crt_verify_chain_reset(
+    mbedtls_x509_crt_verify_chain *ver_chain )
+{
+    size_t i;
+
+    for( i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++ )
+    {
+        ver_chain->items[i].crt = NULL;
+        ver_chain->items[i].flags = (uint32_t) -1;
+    }
+
+    ver_chain->len = 0;
+}
+
+/*
+ *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+ */
+static int x509_get_version( unsigned char **p,
+                             const unsigned char *end,
+                             int *ver )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+        {
+            *ver = 0;
+            return( 0 );
+        }
+
+        return( ret );
+    }
+
+    end = *p + len;
+
+    if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
+
+    if( *p != end )
+        return( MBEDTLS_ERR_X509_INVALID_VERSION +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+/*
+ *  Validity ::= SEQUENCE {
+ *       notBefore      Time,
+ *       notAfter       Time }
+ */
+static int x509_get_dates( unsigned char **p,
+                           const unsigned char *end,
+                           mbedtls_x509_time *from,
+                           mbedtls_x509_time *to )
+{
+    int ret;
+    size_t len;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
+
+    end = *p + len;
+
+    if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 )
+        return( ret );
+
+    if( *p != end )
+        return( MBEDTLS_ERR_X509_INVALID_DATE +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+/*
+ * X.509 v2/v3 unique identifier (not parsed)
+ */
+static int x509_get_uid( unsigned char **p,
+                         const unsigned char *end,
+                         mbedtls_x509_buf *uid, int n )
+{
+    int ret;
+
+    if( *p == end )
+        return( 0 );
+
+    uid->tag = **p;
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len,
+            MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+            return( 0 );
+
+        return( ret );
+    }
+
+    uid->p = *p;
+    *p += uid->len;
+
+    return( 0 );
+}
+
+static int x509_get_basic_constraints( unsigned char **p,
+                                       const unsigned char *end,
+                                       int *ca_istrue,
+                                       int *max_pathlen )
+{
+    int ret;
+    size_t len;
+
+    /*
+     * BasicConstraints ::= SEQUENCE {
+     *      cA                      BOOLEAN DEFAULT FALSE,
+     *      pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
+     */
+    *ca_istrue = 0; /* DEFAULT FALSE */
+    *max_pathlen = 0; /* endless */
+
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+    if( *p == end )
+        return( 0 );
+
+    if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+            ret = mbedtls_asn1_get_int( p, end, ca_istrue );
+
+        if( ret != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+        if( *ca_istrue != 0 )
+            *ca_istrue = 1;
+    }
+
+    if( *p == end )
+        return( 0 );
+
+    if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+    if( *p != end )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    (*max_pathlen)++;
+
+    return( 0 );
+}
+
+static int x509_get_ns_cert_type( unsigned char **p,
+                                       const unsigned char *end,
+                                       unsigned char *ns_cert_type)
+{
+    int ret;
+    mbedtls_x509_bitstring bs = { 0, 0, NULL };
+
+    if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+    if( bs.len != 1 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+
+    /* Get actual bitstring */
+    *ns_cert_type = *bs.p;
+    return( 0 );
+}
+
+static int x509_get_key_usage( unsigned char **p,
+                               const unsigned char *end,
+                               unsigned int *key_usage)
+{
+    int ret;
+    size_t i;
+    mbedtls_x509_bitstring bs = { 0, 0, NULL };
+
+    if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+    if( bs.len < 1 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+
+    /* Get actual bitstring */
+    *key_usage = 0;
+    for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ )
+    {
+        *key_usage |= (unsigned int) bs.p[i] << (8*i);
+    }
+
+    return( 0 );
+}
+
+/*
+ * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+ *
+ * KeyPurposeId ::= OBJECT IDENTIFIER
+ */
+static int x509_get_ext_key_usage( unsigned char **p,
+                               const unsigned char *end,
+                               mbedtls_x509_sequence *ext_key_usage)
+{
+    int ret;
+
+    if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+    /* Sequence length must be >= 1 */
+    if( ext_key_usage->buf.p == NULL )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+
+    return( 0 );
+}
+
+/*
+ * SubjectAltName ::= GeneralNames
+ *
+ * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+ *
+ * GeneralName ::= CHOICE {
+ *      otherName                       [0]     OtherName,
+ *      rfc822Name                      [1]     IA5String,
+ *      dNSName                         [2]     IA5String,
+ *      x400Address                     [3]     ORAddress,
+ *      directoryName                   [4]     Name,
+ *      ediPartyName                    [5]     EDIPartyName,
+ *      uniformResourceIdentifier       [6]     IA5String,
+ *      iPAddress                       [7]     OCTET STRING,
+ *      registeredID                    [8]     OBJECT IDENTIFIER }
+ *
+ * OtherName ::= SEQUENCE {
+ *      type-id    OBJECT IDENTIFIER,
+ *      value      [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * EDIPartyName ::= SEQUENCE {
+ *      nameAssigner            [0]     DirectoryString OPTIONAL,
+ *      partyName               [1]     DirectoryString }
+ *
+ * NOTE: we only parse and use dNSName at this point.
+ */
+static int x509_get_subject_alt_name( unsigned char **p,
+                                      const unsigned char *end,
+                                      mbedtls_x509_sequence *subject_alt_name )
+{
+    int ret;
+    size_t len, tag_len;
+    mbedtls_asn1_buf *buf;
+    unsigned char tag;
+    mbedtls_asn1_sequence *cur = subject_alt_name;
+
+    /* Get main sequence tag */
+    if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+    if( *p + len != end )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    while( *p < end )
+    {
+        if( ( end - *p ) < 1 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                    MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+
+        tag = **p;
+        (*p)++;
+        if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+        if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) !=
+                MBEDTLS_ASN1_CONTEXT_SPECIFIC )
+        {
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                    MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+        }
+
+        /* Skip everything but DNS name */
+        if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
+        {
+            *p += tag_len;
+            continue;
+        }
+
+        /* Allocate and assign next pointer */
+        if( cur->buf.p != NULL )
+        {
+            if( cur->next != NULL )
+                return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
+
+            cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
+
+            if( cur->next == NULL )
+                return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                        MBEDTLS_ERR_ASN1_ALLOC_FAILED );
+
+            cur = cur->next;
+        }
+
+        buf = &(cur->buf);
+        buf->tag = tag;
+        buf->p = *p;
+        buf->len = tag_len;
+        *p += buf->len;
+    }
+
+    /* Set final sequence entry's next pointer to NULL */
+    cur->next = NULL;
+
+    if( *p != end )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+/*
+ * X.509 v3 extensions
+ *
+ */
+static int x509_get_crt_ext( unsigned char **p,
+                             const unsigned char *end,
+                             mbedtls_x509_crt *crt )
+{
+    int ret;
+    size_t len;
+    unsigned char *end_ext_data, *end_ext_octet;
+
+    if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+            return( 0 );
+
+        return( ret );
+    }
+
+    while( *p < end )
+    {
+        /*
+         * Extension  ::=  SEQUENCE  {
+         *      extnID      OBJECT IDENTIFIER,
+         *      critical    BOOLEAN DEFAULT FALSE,
+         *      extnValue   OCTET STRING  }
+         */
+        mbedtls_x509_buf extn_oid = {0, 0, NULL};
+        int is_critical = 0; /* DEFAULT FALSE */
+        int ext_type = 0;
+
+        if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+        end_ext_data = *p + len;
+
+        /* Get extension ID */
+        if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len,
+                                          MBEDTLS_ASN1_OID ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+        extn_oid.tag = MBEDTLS_ASN1_OID;
+        extn_oid.p = *p;
+        *p += extn_oid.len;
+
+        /* Get optional critical */
+        if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
+            ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+        /* Data should be octet string type */
+        if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
+                MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+
+        end_ext_octet = *p + len;
+
+        if( end_ext_octet != end_ext_data )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                    MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+        /*
+         * Detect supported extensions
+         */
+        ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
+
+        if( ret != 0 )
+        {
+            /* No parser found, skip extension */
+            *p = end_ext_octet;
+
+#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
+            if( is_critical )
+            {
+                /* Data is marked as critical: fail */
+                return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                        MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+            }
+#endif
+            continue;
+        }
+
+        /* Forbid repeated extensions */
+        if( ( crt->ext_types & ext_type ) != 0 )
+            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
+
+        crt->ext_types |= ext_type;
+
+        switch( ext_type )
+        {
+        case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS:
+            /* Parse basic constraints */
+            if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
+                    &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
+                return( ret );
+            break;
+
+        case MBEDTLS_X509_EXT_KEY_USAGE:
+            /* Parse key usage */
+            if( ( ret = x509_get_key_usage( p, end_ext_octet,
+                    &crt->key_usage ) ) != 0 )
+                return( ret );
+            break;
+
+        case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE:
+            /* Parse extended key usage */
+            if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
+                    &crt->ext_key_usage ) ) != 0 )
+                return( ret );
+            break;
+
+        case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
+            /* Parse subject alt name */
+            if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
+                    &crt->subject_alt_names ) ) != 0 )
+                return( ret );
+            break;
+
+        case MBEDTLS_X509_EXT_NS_CERT_TYPE:
+            /* Parse netscape certificate type */
+            if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
+                    &crt->ns_cert_type ) ) != 0 )
+                return( ret );
+            break;
+
+        default:
+            return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+        }
+    }
+
+    if( *p != end )
+        return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+    return( 0 );
+}
+
+/*
+ * Parse and fill a single X.509 certificate in DER format
+ */
+static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf,
+                                    size_t buflen )
+{
+    int ret;
+    size_t len;
+    unsigned char *p, *end, *crt_end;
+    mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
+
+    memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
+    memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
+    memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
+
+    /*
+     * Check for valid input
+     */
+    if( crt == NULL || buf == NULL )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    // Use the original buffer until we figure out actual length
+    p = (unsigned char*) buf;
+    len = buflen;
+    end = p + len;
+
+    /*
+     * Certificate  ::=  SEQUENCE  {
+     *      tbsCertificate       TBSCertificate,
+     *      signatureAlgorithm   AlgorithmIdentifier,
+     *      signatureValue       BIT STRING  }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT );
+    }
+
+    if( len > (size_t) ( end - p ) )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+    crt_end = p + len;
+
+    // Create and populate a new buffer for the raw field
+    crt->raw.len = crt_end - buf;
+    crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
+    if( p == NULL )
+        return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+
+    memcpy( p, buf, crt->raw.len );
+
+    // Direct pointers to the new buffer
+    p += crt->raw.len - len;
+    end = crt_end = p + len;
+
+    /*
+     * TBSCertificate  ::=  SEQUENCE  {
+     */
+    crt->tbs.p = p;
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+    }
+
+    end = p + len;
+    crt->tbs.len = end - crt->tbs.p;
+
+    /*
+     * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+     *
+     * CertificateSerialNumber  ::=  INTEGER
+     *
+     * signature            AlgorithmIdentifier
+     */
+    if( ( ret = x509_get_version(  &p, end, &crt->version  ) ) != 0 ||
+        ( ret = mbedtls_x509_get_serial(   &p, end, &crt->serial   ) ) != 0 ||
+        ( ret = mbedtls_x509_get_alg(      &p, end, &crt->sig_oid,
+                                            &sig_params1 ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( ret );
+    }
+
+    if( crt->version < 0 || crt->version > 2 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
+    }
+
+    crt->version++;
+
+    if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1,
+                                  &crt->sig_md, &crt->sig_pk,
+                                  &crt->sig_opts ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( ret );
+    }
+
+    /*
+     * issuer               Name
+     */
+    crt->issuer_raw.p = p;
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+    }
+
+    if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( ret );
+    }
+
+    crt->issuer_raw.len = p - crt->issuer_raw.p;
+
+    /*
+     * Validity ::= SEQUENCE {
+     *      notBefore      Time,
+     *      notAfter       Time }
+     *
+     */
+    if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
+                                         &crt->valid_to ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( ret );
+    }
+
+    /*
+     * subject              Name
+     */
+    crt->subject_raw.p = p;
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+    }
+
+    if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( ret );
+    }
+
+    crt->subject_raw.len = p - crt->subject_raw.p;
+
+    /*
+     * SubjectPublicKeyInfo
+     */
+    if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( ret );
+    }
+
+    /*
+     *  issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
+     *                       -- If present, version shall be v2 or v3
+     *  subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
+     *                       -- If present, version shall be v2 or v3
+     *  extensions      [3]  EXPLICIT Extensions OPTIONAL
+     *                       -- If present, version shall be v3
+     */
+    if( crt->version == 2 || crt->version == 3 )
+    {
+        ret = x509_get_uid( &p, end, &crt->issuer_id,  1 );
+        if( ret != 0 )
+        {
+            mbedtls_x509_crt_free( crt );
+            return( ret );
+        }
+    }
+
+    if( crt->version == 2 || crt->version == 3 )
+    {
+        ret = x509_get_uid( &p, end, &crt->subject_id,  2 );
+        if( ret != 0 )
+        {
+            mbedtls_x509_crt_free( crt );
+            return( ret );
+        }
+    }
+
+#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
+    if( crt->version == 3 )
+#endif
+    {
+        ret = x509_get_crt_ext( &p, end, crt );
+        if( ret != 0 )
+        {
+            mbedtls_x509_crt_free( crt );
+            return( ret );
+        }
+    }
+
+    if( p != end )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+
+    end = crt_end;
+
+    /*
+     *  }
+     *  -- end of TBSCertificate
+     *
+     *  signatureAlgorithm   AlgorithmIdentifier,
+     *  signatureValue       BIT STRING
+     */
+    if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( ret );
+    }
+
+    if( crt->sig_oid.len != sig_oid2.len ||
+        memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 ||
+        sig_params1.len != sig_params2.len ||
+        ( sig_params1.len != 0 &&
+          memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_SIG_MISMATCH );
+    }
+
+    if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( ret );
+    }
+
+    if( p != end )
+    {
+        mbedtls_x509_crt_free( crt );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Parse one X.509 certificate in DER format from a buffer and add them to a
+ * chained list
+ */
+int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
+                        size_t buflen )
+{
+    int ret;
+    mbedtls_x509_crt *crt = chain, *prev = NULL;
+
+    /*
+     * Check for valid input
+     */
+    if( crt == NULL || buf == NULL )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    while( crt->version != 0 && crt->next != NULL )
+    {
+        prev = crt;
+        crt = crt->next;
+    }
+
+    /*
+     * Add new certificate on the end of the chain if needed.
+     */
+    if( crt->version != 0 && crt->next == NULL )
+    {
+        crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
+
+        if( crt->next == NULL )
+            return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+
+        prev = crt;
+        mbedtls_x509_crt_init( crt->next );
+        crt = crt->next;
+    }
+
+    if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
+    {
+        if( prev )
+            prev->next = NULL;
+
+        if( crt != chain )
+            mbedtls_free( crt );
+
+        return( ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Parse one or more PEM certificates from a buffer and add them to the chained
+ * list
+ */
+int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
+{
+#if defined(MBEDTLS_PEM_PARSE_C)
+    int success = 0, first_error = 0, total_failed = 0;
+    int buf_format = MBEDTLS_X509_FORMAT_DER;
+#endif
+
+    /*
+     * Check for valid input
+     */
+    if( chain == NULL || buf == NULL )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    /*
+     * Determine buffer content. Buffer contains either one DER certificate or
+     * one or more PEM certificates.
+     */
+#if defined(MBEDTLS_PEM_PARSE_C)
+    if( buflen != 0 && buf[buflen - 1] == '\0' &&
+        strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
+    {
+        buf_format = MBEDTLS_X509_FORMAT_PEM;
+    }
+
+    if( buf_format == MBEDTLS_X509_FORMAT_DER )
+        return mbedtls_x509_crt_parse_der( chain, buf, buflen );
+#else
+    return mbedtls_x509_crt_parse_der( chain, buf, buflen );
+#endif
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+    if( buf_format == MBEDTLS_X509_FORMAT_PEM )
+    {
+        int ret;
+        mbedtls_pem_context pem;
+
+        /* 1 rather than 0 since the terminating NULL byte is counted in */
+        while( buflen > 1 )
+        {
+            size_t use_len;
+            mbedtls_pem_init( &pem );
+
+            /* If we get there, we know the string is null-terminated */
+            ret = mbedtls_pem_read_buffer( &pem,
+                           "-----BEGIN CERTIFICATE-----",
+                           "-----END CERTIFICATE-----",
+                           buf, NULL, 0, &use_len );
+
+            if( ret == 0 )
+            {
+                /*
+                 * Was PEM encoded
+                 */
+                buflen -= use_len;
+                buf += use_len;
+            }
+            else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA )
+            {
+                return( ret );
+            }
+            else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+            {
+                mbedtls_pem_free( &pem );
+
+                /*
+                 * PEM header and footer were found
+                 */
+                buflen -= use_len;
+                buf += use_len;
+
+                if( first_error == 0 )
+                    first_error = ret;
+
+                total_failed++;
+                continue;
+            }
+            else
+                break;
+
+            ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen );
+
+            mbedtls_pem_free( &pem );
+
+            if( ret != 0 )
+            {
+                /*
+                 * Quit parsing on a memory error
+                 */
+                if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED )
+                    return( ret );
+
+                if( first_error == 0 )
+                    first_error = ret;
+
+                total_failed++;
+                continue;
+            }
+
+            success = 1;
+        }
+    }
+
+    if( success )
+        return( total_failed );
+    else if( first_error )
+        return( first_error );
+    else
+        return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT );
+#endif /* MBEDTLS_PEM_PARSE_C */
+}
+
+#if defined(MBEDTLS_FS_IO)
+/*
+ * Load one or more certificates and add them to the chained list
+ */
+int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
+{
+    int ret;
+    size_t n;
+    unsigned char *buf;
+
+    if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
+
+    ret = mbedtls_x509_crt_parse( chain, buf, n );
+
+    mbedtls_platform_zeroize( buf, n );
+    mbedtls_free( buf );
+
+    return( ret );
+}
+
+int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
+{
+    int ret = 0;
+#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
+    int w_ret;
+    WCHAR szDir[MAX_PATH];
+    char filename[MAX_PATH];
+    char *p;
+    size_t len = strlen( path );
+
+    WIN32_FIND_DATAW file_data;
+    HANDLE hFind;
+
+    if( len > MAX_PATH - 3 )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    memset( szDir, 0, sizeof(szDir) );
+    memset( filename, 0, MAX_PATH );
+    memcpy( filename, path, len );
+    filename[len++] = '\\';
+    p = filename + len;
+    filename[len++] = '*';
+
+    w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir,
+                                 MAX_PATH - 3 );
+    if( w_ret == 0 )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    hFind = FindFirstFileW( szDir, &file_data );
+    if( hFind == INVALID_HANDLE_VALUE )
+        return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
+
+    len = MAX_PATH - len;
+    do
+    {
+        memset( p, 0, len );
+
+        if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+            continue;
+
+        w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
+                                     lstrlenW( file_data.cFileName ),
+                                     p, (int) len - 1,
+                                     NULL, NULL );
+        if( w_ret == 0 )
+        {
+            ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
+            goto cleanup;
+        }
+
+        w_ret = mbedtls_x509_crt_parse_file( chain, filename );
+        if( w_ret < 0 )
+            ret++;
+        else
+            ret += w_ret;
+    }
+    while( FindNextFileW( hFind, &file_data ) != 0 );
+
+    if( GetLastError() != ERROR_NO_MORE_FILES )
+        ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
+
+cleanup:
+    FindClose( hFind );
+#else /* _WIN32 */
+    int t_ret;
+    int snp_ret;
+    struct stat sb;
+    struct dirent *entry;
+    char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN];
+    DIR *dir = opendir( path );
+
+    if( dir == NULL )
+        return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 )
+    {
+        closedir( dir );
+        return( ret );
+    }
+#endif /* MBEDTLS_THREADING_C */
+
+    while( ( entry = readdir( dir ) ) != NULL )
+    {
+        snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name,
+                                    "%s/%s", path, entry->d_name );
+
+        if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name )
+        {
+            ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
+            goto cleanup;
+        }
+        else if( stat( entry_name, &sb ) == -1 )
+        {
+            ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
+            goto cleanup;
+        }
+
+        if( !S_ISREG( sb.st_mode ) )
+            continue;
+
+        // Ignore parse errors
+        //
+        t_ret = mbedtls_x509_crt_parse_file( chain, entry_name );
+        if( t_ret < 0 )
+            ret++;
+        else
+            ret += t_ret;
+    }
+
+cleanup:
+    closedir( dir );
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 )
+        ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
+#endif /* MBEDTLS_THREADING_C */
+
+#endif /* _WIN32 */
+
+    return( ret );
+}
+#endif /* MBEDTLS_FS_IO */
+
+static int x509_info_subject_alt_name( char **buf, size_t *size,
+                                       const mbedtls_x509_sequence *subject_alt_name )
+{
+    size_t i;
+    size_t n = *size;
+    char *p = *buf;
+    const mbedtls_x509_sequence *cur = subject_alt_name;
+    const char *sep = "";
+    size_t sep_len = 0;
+
+    while( cur != NULL )
+    {
+        if( cur->buf.len + sep_len >= n )
+        {
+            *p = '\0';
+            return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+        }
+
+        n -= cur->buf.len + sep_len;
+        for( i = 0; i < sep_len; i++ )
+            *p++ = sep[i];
+        for( i = 0; i < cur->buf.len; i++ )
+            *p++ = cur->buf.p[i];
+
+        sep = ", ";
+        sep_len = 2;
+
+        cur = cur->next;
+    }
+
+    *p = '\0';
+
+    *size = n;
+    *buf = p;
+
+    return( 0 );
+}
+
+#define PRINT_ITEM(i)                           \
+    {                                           \
+        ret = mbedtls_snprintf( p, n, "%s" i, sep );    \
+        MBEDTLS_X509_SAFE_SNPRINTF;                        \
+        sep = ", ";                             \
+    }
+
+#define CERT_TYPE(type,name)                    \
+    if( ns_cert_type & type )                   \
+        PRINT_ITEM( name );
+
+static int x509_info_cert_type( char **buf, size_t *size,
+                                unsigned char ns_cert_type )
+{
+    int ret;
+    size_t n = *size;
+    char *p = *buf;
+    const char *sep = "";
+
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA" );
+    CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA" );
+
+    *size = n;
+    *buf = p;
+
+    return( 0 );
+}
+
+#define KEY_USAGE(code,name)    \
+    if( key_usage & code )      \
+        PRINT_ITEM( name );
+
+static int x509_info_key_usage( char **buf, size_t *size,
+                                unsigned int key_usage )
+{
+    int ret;
+    size_t n = *size;
+    char *p = *buf;
+    const char *sep = "";
+
+    KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature" );
+    KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation" );
+    KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment" );
+    KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment" );
+    KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement" );
+    KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign" );
+    KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign" );
+    KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only" );
+    KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only" );
+
+    *size = n;
+    *buf = p;
+
+    return( 0 );
+}
+
+static int x509_info_ext_key_usage( char **buf, size_t *size,
+                                    const mbedtls_x509_sequence *extended_key_usage )
+{
+    int ret;
+    const char *desc;
+    size_t n = *size;
+    char *p = *buf;
+    const mbedtls_x509_sequence *cur = extended_key_usage;
+    const char *sep = "";
+
+    while( cur != NULL )
+    {
+        if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
+            desc = "???";
+
+        ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        sep = ", ";
+
+        cur = cur->next;
+    }
+
+    *size = n;
+    *buf = p;
+
+    return( 0 );
+}
+
+/*
+ * Return an informational string about the certificate.
+ */
+#define BEFORE_COLON    18
+#define BC              "18"
+int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
+                   const mbedtls_x509_crt *crt )
+{
+    int ret;
+    size_t n;
+    char *p;
+    char key_size_str[BEFORE_COLON];
+
+    p = buf;
+    n = size;
+
+    if( NULL == crt )
+    {
+        ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        return( (int) ( size - n ) );
+    }
+
+    ret = mbedtls_snprintf( p, n, "%scert. version     : %d\n",
+                               prefix, crt->version );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+    ret = mbedtls_snprintf( p, n, "%sserial number     : ",
+                               prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n%sissuer name       : ", prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+    ret = mbedtls_x509_dn_gets( p, n, &crt->issuer  );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n%ssubject name      : ", prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+    ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n%sissued  on        : " \
+                   "%04d-%02d-%02d %02d:%02d:%02d", prefix,
+                   crt->valid_from.year, crt->valid_from.mon,
+                   crt->valid_from.day,  crt->valid_from.hour,
+                   crt->valid_from.min,  crt->valid_from.sec );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n%sexpires on        : " \
+                   "%04d-%02d-%02d %02d:%02d:%02d", prefix,
+                   crt->valid_to.year, crt->valid_to.mon,
+                   crt->valid_to.day,  crt->valid_to.hour,
+                   crt->valid_to.min,  crt->valid_to.sec );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n%ssigned using      : ", prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk,
+                             crt->sig_md, crt->sig_opts );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    /* Key size */
+    if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
+                                      mbedtls_pk_get_name( &crt->pk ) ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
+                          (int) mbedtls_pk_get_bitlen( &crt->pk ) );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    /*
+     * Optional extensions
+     */
+
+    if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS )
+    {
+        ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
+                        crt->ca_istrue ? "true" : "false" );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        if( crt->max_pathlen > 0 )
+        {
+            ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 );
+            MBEDTLS_X509_SAFE_SNPRINTF;
+        }
+    }
+
+    if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
+    {
+        ret = mbedtls_snprintf( p, n, "\n%ssubject alt name  : ", prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        if( ( ret = x509_info_subject_alt_name( &p, &n,
+                                            &crt->subject_alt_names ) ) != 0 )
+            return( ret );
+    }
+
+    if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE )
+    {
+        ret = mbedtls_snprintf( p, n, "\n%scert. type        : ", prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 )
+            return( ret );
+    }
+
+    if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE )
+    {
+        ret = mbedtls_snprintf( p, n, "\n%skey usage         : ", prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 )
+            return( ret );
+    }
+
+    if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE )
+    {
+        ret = mbedtls_snprintf( p, n, "\n%sext key usage     : ", prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+
+        if( ( ret = x509_info_ext_key_usage( &p, &n,
+                                             &crt->ext_key_usage ) ) != 0 )
+            return( ret );
+    }
+
+    ret = mbedtls_snprintf( p, n, "\n" );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    return( (int) ( size - n ) );
+}
+
+struct x509_crt_verify_string {
+    int code;
+    const char *string;
+};
+
+static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
+    { MBEDTLS_X509_BADCERT_EXPIRED,       "The certificate validity has expired" },
+    { MBEDTLS_X509_BADCERT_REVOKED,       "The certificate has been revoked (is on a CRL)" },
+    { MBEDTLS_X509_BADCERT_CN_MISMATCH,   "The certificate Common Name (CN) does not match with the expected CN" },
+    { MBEDTLS_X509_BADCERT_NOT_TRUSTED,   "The certificate is not correctly signed by the trusted CA" },
+    { MBEDTLS_X509_BADCRL_NOT_TRUSTED,    "The CRL is not correctly signed by the trusted CA" },
+    { MBEDTLS_X509_BADCRL_EXPIRED,        "The CRL is expired" },
+    { MBEDTLS_X509_BADCERT_MISSING,       "Certificate was missing" },
+    { MBEDTLS_X509_BADCERT_SKIP_VERIFY,   "Certificate verification was skipped" },
+    { MBEDTLS_X509_BADCERT_OTHER,         "Other reason (can be used by verify callback)" },
+    { MBEDTLS_X509_BADCERT_FUTURE,        "The certificate validity starts in the future" },
+    { MBEDTLS_X509_BADCRL_FUTURE,         "The CRL is from the future" },
+    { MBEDTLS_X509_BADCERT_KEY_USAGE,     "Usage does not match the keyUsage extension" },
+    { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
+    { MBEDTLS_X509_BADCERT_NS_CERT_TYPE,  "Usage does not match the nsCertType extension" },
+    { MBEDTLS_X509_BADCERT_BAD_MD,        "The certificate is signed with an unacceptable hash." },
+    { MBEDTLS_X509_BADCERT_BAD_PK,        "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
+    { MBEDTLS_X509_BADCERT_BAD_KEY,       "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
+    { MBEDTLS_X509_BADCRL_BAD_MD,         "The CRL is signed with an unacceptable hash." },
+    { MBEDTLS_X509_BADCRL_BAD_PK,         "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
+    { MBEDTLS_X509_BADCRL_BAD_KEY,        "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
+    { 0, NULL }
+};
+
+int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
+                          uint32_t flags )
+{
+    int ret;
+    const struct x509_crt_verify_string *cur;
+    char *p = buf;
+    size_t n = size;
+
+    for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
+    {
+        if( ( flags & cur->code ) == 0 )
+            continue;
+
+        ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+        flags ^= cur->code;
+    }
+
+    if( flags != 0 )
+    {
+        ret = mbedtls_snprintf( p, n, "%sUnknown reason "
+                                       "(this should not happen)\n", prefix );
+        MBEDTLS_X509_SAFE_SNPRINTF;
+    }
+
+    return( (int) ( size - n ) );
+}
+
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
+int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
+                                      unsigned int usage )
+{
+    unsigned int usage_must, usage_may;
+    unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
+                          | MBEDTLS_X509_KU_DECIPHER_ONLY;
+
+    if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 )
+        return( 0 );
+
+    usage_must = usage & ~may_mask;
+
+    if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    usage_may = usage & may_mask;
+
+    if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    return( 0 );
+}
+#endif
+
+#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
+int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
+                                       const char *usage_oid,
+                                       size_t usage_len )
+{
+    const mbedtls_x509_sequence *cur;
+
+    /* Extension is not mandatory, absent means no restriction */
+    if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 )
+        return( 0 );
+
+    /*
+     * Look for the requested usage (or wildcard ANY) in our list
+     */
+    for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next )
+    {
+        const mbedtls_x509_buf *cur_oid = &cur->buf;
+
+        if( cur_oid->len == usage_len &&
+            memcmp( cur_oid->p, usage_oid, usage_len ) == 0 )
+        {
+            return( 0 );
+        }
+
+        if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 )
+            return( 0 );
+    }
+
+    return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+}
+#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
+
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
+/*
+ * Return 1 if the certificate is revoked, or 0 otherwise.
+ */
+int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl )
+{
+    const mbedtls_x509_crl_entry *cur = &crl->entry;
+
+    while( cur != NULL && cur->serial.len != 0 )
+    {
+        if( crt->serial.len == cur->serial.len &&
+            memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
+        {
+            if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
+                return( 1 );
+        }
+
+        cur = cur->next;
+    }
+
+    return( 0 );
+}
+
+/*
+ * Check that the given certificate is not revoked according to the CRL.
+ * Skip validation if no CRL for the given CA is present.
+ */
+static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
+                               mbedtls_x509_crl *crl_list,
+                               const mbedtls_x509_crt_profile *profile )
+{
+    int flags = 0;
+    unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+    const mbedtls_md_info_t *md_info;
+
+    if( ca == NULL )
+        return( flags );
+
+    while( crl_list != NULL )
+    {
+        if( crl_list->version == 0 ||
+            x509_name_cmp( &crl_list->issuer, &ca->subject ) != 0 )
+        {
+            crl_list = crl_list->next;
+            continue;
+        }
+
+        /*
+         * Check if the CA is configured to sign CRLs
+         */
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
+        if( mbedtls_x509_crt_check_key_usage( ca,
+                                              MBEDTLS_X509_KU_CRL_SIGN ) != 0 )
+        {
+            flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
+            break;
+        }
+#endif
+
+        /*
+         * Check if CRL is correctly signed by the trusted CA
+         */
+        if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 )
+            flags |= MBEDTLS_X509_BADCRL_BAD_MD;
+
+        if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 )
+            flags |= MBEDTLS_X509_BADCRL_BAD_PK;
+
+        md_info = mbedtls_md_info_from_type( crl_list->sig_md );
+        if( mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ) != 0 )
+        {
+            /* Note: this can't happen except after an internal error */
+            flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
+            break;
+        }
+
+        if( x509_profile_check_key( profile, &ca->pk ) != 0 )
+            flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
+
+        if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
+                           crl_list->sig_md, hash, mbedtls_md_get_size( md_info ),
+                           crl_list->sig.p, crl_list->sig.len ) != 0 )
+        {
+            flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
+            break;
+        }
+
+        /*
+         * Check for validity of CRL (Do not drop out)
+         */
+        if( mbedtls_x509_time_is_past( &crl_list->next_update ) )
+            flags |= MBEDTLS_X509_BADCRL_EXPIRED;
+
+        if( mbedtls_x509_time_is_future( &crl_list->this_update ) )
+            flags |= MBEDTLS_X509_BADCRL_FUTURE;
+
+        /*
+         * Check if certificate is revoked
+         */
+        if( mbedtls_x509_crt_is_revoked( crt, crl_list ) )
+        {
+            flags |= MBEDTLS_X509_BADCERT_REVOKED;
+            break;
+        }
+
+        crl_list = crl_list->next;
+    }
+
+    return( flags );
+}
+#endif /* MBEDTLS_X509_CRL_PARSE_C */
+
+/*
+ * Check the signature of a certificate by its parent
+ */
+static int x509_crt_check_signature( const mbedtls_x509_crt *child,
+                                     mbedtls_x509_crt *parent,
+                                     mbedtls_x509_crt_restart_ctx *rs_ctx )
+{
+    const mbedtls_md_info_t *md_info;
+    unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+
+    md_info = mbedtls_md_info_from_type( child->sig_md );
+    if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 )
+    {
+        /* Note: this can't happen except after an internal error */
+        return( -1 );
+    }
+
+    /* Skip expensive computation on obvious mismatch */
+    if( ! mbedtls_pk_can_do( &parent->pk, child->sig_pk ) )
+        return( -1 );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA )
+    {
+        return( mbedtls_pk_verify_restartable( &parent->pk,
+                    child->sig_md, hash, mbedtls_md_get_size( md_info ),
+                    child->sig.p, child->sig.len, &rs_ctx->pk ) );
+    }
+#else
+    (void) rs_ctx;
+#endif
+
+    return( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
+                child->sig_md, hash, mbedtls_md_get_size( md_info ),
+                child->sig.p, child->sig.len ) );
+}
+
+/*
+ * Check if 'parent' is a suitable parent (signing CA) for 'child'.
+ * Return 0 if yes, -1 if not.
+ *
+ * top means parent is a locally-trusted certificate
+ */
+static int x509_crt_check_parent( const mbedtls_x509_crt *child,
+                                  const mbedtls_x509_crt *parent,
+                                  int top )
+{
+    int need_ca_bit;
+
+    /* Parent must be the issuer */
+    if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 )
+        return( -1 );
+
+    /* Parent must have the basicConstraints CA bit set as a general rule */
+    need_ca_bit = 1;
+
+    /* Exception: v1/v2 certificates that are locally trusted. */
+    if( top && parent->version < 3 )
+        need_ca_bit = 0;
+
+    if( need_ca_bit && ! parent->ca_istrue )
+        return( -1 );
+
+#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
+    if( need_ca_bit &&
+        mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 )
+    {
+        return( -1 );
+    }
+#endif
+
+    return( 0 );
+}
+
+/*
+ * Find a suitable parent for child in candidates, or return NULL.
+ *
+ * Here suitable is defined as:
+ *  1. subject name matches child's issuer
+ *  2. if necessary, the CA bit is set and key usage allows signing certs
+ *  3. for trusted roots, the signature is correct
+ *     (for intermediates, the signature is checked and the result reported)
+ *  4. pathlen constraints are satisfied
+ *
+ * If there's a suitable candidate which is also time-valid, return the first
+ * such. Otherwise, return the first suitable candidate (or NULL if there is
+ * none).
+ *
+ * The rationale for this rule is that someone could have a list of trusted
+ * roots with two versions on the same root with different validity periods.
+ * (At least one user reported having such a list and wanted it to just work.)
+ * The reason we don't just require time-validity is that generally there is
+ * only one version, and if it's expired we want the flags to state that
+ * rather than NOT_TRUSTED, as would be the case if we required it here.
+ *
+ * The rationale for rule 3 (signature for trusted roots) is that users might
+ * have two versions of the same CA with different keys in their list, and the
+ * way we select the correct one is by checking the signature (as we don't
+ * rely on key identifier extensions). (This is one way users might choose to
+ * handle key rollover, another relies on self-issued certs, see [SIRO].)
+ *
+ * Arguments:
+ *  - [in] child: certificate for which we're looking for a parent
+ *  - [in] candidates: chained list of potential parents
+ *  - [out] r_parent: parent found (or NULL)
+ *  - [out] r_signature_is_good: 1 if child signature by parent is valid, or 0
+ *  - [in] top: 1 if candidates consists of trusted roots, ie we're at the top
+ *         of the chain, 0 otherwise
+ *  - [in] path_cnt: number of intermediates seen so far
+ *  - [in] self_cnt: number of self-signed intermediates seen so far
+ *         (will never be greater than path_cnt)
+ *  - [in-out] rs_ctx: context for restarting operations
+ *
+ * Return value:
+ *  - 0 on success
+ *  - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise
+ */
+static int x509_crt_find_parent_in(
+                        mbedtls_x509_crt *child,
+                        mbedtls_x509_crt *candidates,
+                        mbedtls_x509_crt **r_parent,
+                        int *r_signature_is_good,
+                        int top,
+                        unsigned path_cnt,
+                        unsigned self_cnt,
+                        mbedtls_x509_crt_restart_ctx *rs_ctx )
+{
+    int ret;
+    mbedtls_x509_crt *parent, *fallback_parent;
+    int signature_is_good, fallback_signature_is_good;
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    /* did we have something in progress? */
+    if( rs_ctx != NULL && rs_ctx->parent != NULL )
+    {
+        /* restore saved state */
+        parent = rs_ctx->parent;
+        fallback_parent = rs_ctx->fallback_parent;
+        fallback_signature_is_good = rs_ctx->fallback_signature_is_good;
+
+        /* clear saved state */
+        rs_ctx->parent = NULL;
+        rs_ctx->fallback_parent = NULL;
+        rs_ctx->fallback_signature_is_good = 0;
+
+        /* resume where we left */
+        goto check_signature;
+    }
+#endif
+
+    fallback_parent = NULL;
+    fallback_signature_is_good = 0;
+
+    for( parent = candidates; parent != NULL; parent = parent->next )
+    {
+        /* basic parenting skills (name, CA bit, key usage) */
+        if( x509_crt_check_parent( child, parent, top ) != 0 )
+            continue;
+
+        /* +1 because stored max_pathlen is 1 higher that the actual value */
+        if( parent->max_pathlen > 0 &&
+            (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt )
+        {
+            continue;
+        }
+
+        /* Signature */
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+check_signature:
+#endif
+        ret = x509_crt_check_signature( child, parent, rs_ctx );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+        if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+        {
+            /* save state */
+            rs_ctx->parent = parent;
+            rs_ctx->fallback_parent = fallback_parent;
+            rs_ctx->fallback_signature_is_good = fallback_signature_is_good;
+
+            return( ret );
+        }
+#else
+        (void) ret;
+#endif
+
+        signature_is_good = ret == 0;
+        if( top && ! signature_is_good )
+            continue;
+
+        /* optional time check */
+        if( mbedtls_x509_time_is_past( &parent->valid_to ) ||
+            mbedtls_x509_time_is_future( &parent->valid_from ) )
+        {
+            if( fallback_parent == NULL )
+            {
+                fallback_parent = parent;
+                fallback_signature_is_good = signature_is_good;
+            }
+
+            continue;
+        }
+
+        break;
+    }
+
+    if( parent != NULL )
+    {
+        *r_parent = parent;
+        *r_signature_is_good = signature_is_good;
+    }
+    else
+    {
+        *r_parent = fallback_parent;
+        *r_signature_is_good = fallback_signature_is_good;
+    }
+
+    return( 0 );
+}
+
+/*
+ * Find a parent in trusted CAs or the provided chain, or return NULL.
+ *
+ * Searches in trusted CAs first, and return the first suitable parent found
+ * (see find_parent_in() for definition of suitable).
+ *
+ * Arguments:
+ *  - [in] child: certificate for which we're looking for a parent, followed
+ *         by a chain of possible intermediates
+ *  - [in] trust_ca: list of locally trusted certificates
+ *  - [out] parent: parent found (or NULL)
+ *  - [out] parent_is_trusted: 1 if returned `parent` is trusted, or 0
+ *  - [out] signature_is_good: 1 if child signature by parent is valid, or 0
+ *  - [in] path_cnt: number of links in the chain so far (EE -> ... -> child)
+ *  - [in] self_cnt: number of self-signed certs in the chain so far
+ *         (will always be no greater than path_cnt)
+ *  - [in-out] rs_ctx: context for restarting operations
+ *
+ * Return value:
+ *  - 0 on success
+ *  - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise
+ */
+static int x509_crt_find_parent(
+                        mbedtls_x509_crt *child,
+                        mbedtls_x509_crt *trust_ca,
+                        mbedtls_x509_crt **parent,
+                        int *parent_is_trusted,
+                        int *signature_is_good,
+                        unsigned path_cnt,
+                        unsigned self_cnt,
+                        mbedtls_x509_crt_restart_ctx *rs_ctx )
+{
+    int ret;
+    mbedtls_x509_crt *search_list;
+
+    *parent_is_trusted = 1;
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    /* restore then clear saved state if we have some stored */
+    if( rs_ctx != NULL && rs_ctx->parent_is_trusted != -1 )
+    {
+        *parent_is_trusted = rs_ctx->parent_is_trusted;
+        rs_ctx->parent_is_trusted = -1;
+    }
+#endif
+
+    while( 1 ) {
+        search_list = *parent_is_trusted ? trust_ca : child->next;
+
+        ret = x509_crt_find_parent_in( child, search_list,
+                                       parent, signature_is_good,
+                                       *parent_is_trusted,
+                                       path_cnt, self_cnt, rs_ctx );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+        if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+        {
+            /* save state */
+            rs_ctx->parent_is_trusted = *parent_is_trusted;
+            return( ret );
+        }
+#else
+        (void) ret;
+#endif
+
+        /* stop here if found or already in second iteration */
+        if( *parent != NULL || *parent_is_trusted == 0 )
+            break;
+
+        /* prepare second iteration */
+        *parent_is_trusted = 0;
+    }
+
+    /* extra precaution against mistakes in the caller */
+    if( *parent == NULL )
+    {
+        *parent_is_trusted = 0;
+        *signature_is_good = 0;
+    }
+
+    return( 0 );
+}
+
+/*
+ * Check if an end-entity certificate is locally trusted
+ *
+ * Currently we require such certificates to be self-signed (actually only
+ * check for self-issued as self-signatures are not checked)
+ */
+static int x509_crt_check_ee_locally_trusted(
+                    mbedtls_x509_crt *crt,
+                    mbedtls_x509_crt *trust_ca )
+{
+    mbedtls_x509_crt *cur;
+
+    /* must be self-issued */
+    if( x509_name_cmp( &crt->issuer, &crt->subject ) != 0 )
+        return( -1 );
+
+    /* look for an exact match with trusted cert */
+    for( cur = trust_ca; cur != NULL; cur = cur->next )
+    {
+        if( crt->raw.len == cur->raw.len &&
+            memcmp( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 )
+        {
+            return( 0 );
+        }
+    }
+
+    /* too bad */
+    return( -1 );
+}
+
+/*
+ * Build and verify a certificate chain
+ *
+ * Given a peer-provided list of certificates EE, C1, ..., Cn and
+ * a list of trusted certs R1, ... Rp, try to build and verify a chain
+ *      EE, Ci1, ... Ciq [, Rj]
+ * such that every cert in the chain is a child of the next one,
+ * jumping to a trusted root as early as possible.
+ *
+ * Verify that chain and return it with flags for all issues found.
+ *
+ * Special cases:
+ * - EE == Rj -> return a one-element list containing it
+ * - EE, Ci1, ..., Ciq cannot be continued with a trusted root
+ *   -> return that chain with NOT_TRUSTED set on Ciq
+ *
+ * Tests for (aspects of) this function should include at least:
+ * - trusted EE
+ * - EE -> trusted root
+ * - EE -> intermedate CA -> trusted root
+ * - if relevant: EE untrusted
+ * - if relevant: EE -> intermediate, untrusted
+ * with the aspect under test checked at each relevant level (EE, int, root).
+ * For some aspects longer chains are required, but usually length 2 is
+ * enough (but length 1 is not in general).
+ *
+ * Arguments:
+ *  - [in] crt: the cert list EE, C1, ..., Cn
+ *  - [in] trust_ca: the trusted list R1, ..., Rp
+ *  - [in] ca_crl, profile: as in verify_with_profile()
+ *  - [out] ver_chain: the built and verified chain
+ *      Only valid when return value is 0, may contain garbage otherwise!
+ *      Restart note: need not be the same when calling again to resume.
+ *  - [in-out] rs_ctx: context for restarting operations
+ *
+ * Return value:
+ *  - non-zero if the chain could not be fully built and examined
+ *  - 0 is the chain was successfully built and examined,
+ *      even if it was found to be invalid
+ */
+static int x509_crt_verify_chain(
+                mbedtls_x509_crt *crt,
+                mbedtls_x509_crt *trust_ca,
+                mbedtls_x509_crl *ca_crl,
+                const mbedtls_x509_crt_profile *profile,
+                mbedtls_x509_crt_verify_chain *ver_chain,
+                mbedtls_x509_crt_restart_ctx *rs_ctx )
+{
+    /* Don't initialize any of those variables here, so that the compiler can
+     * catch potential issues with jumping ahead when restarting */
+    int ret;
+    uint32_t *flags;
+    mbedtls_x509_crt_verify_chain_item *cur;
+    mbedtls_x509_crt *child;
+    mbedtls_x509_crt *parent;
+    int parent_is_trusted;
+    int child_is_trusted;
+    int signature_is_good;
+    unsigned self_cnt;
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    /* resume if we had an operation in progress */
+    if( rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent )
+    {
+        /* restore saved state */
+        *ver_chain = rs_ctx->ver_chain; /* struct copy */
+        self_cnt = rs_ctx->self_cnt;
+
+        /* restore derived state */
+        cur = &ver_chain->items[ver_chain->len - 1];
+        child = cur->crt;
+        flags = &cur->flags;
+
+        goto find_parent;
+    }
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+    child = crt;
+    self_cnt = 0;
+    parent_is_trusted = 0;
+    child_is_trusted = 0;
+
+    while( 1 ) {
+        /* Add certificate to the verification chain */
+        cur = &ver_chain->items[ver_chain->len];
+        cur->crt = child;
+        cur->flags = 0;
+        ver_chain->len++;
+        flags = &cur->flags;
+
+        /* Check time-validity (all certificates) */
+        if( mbedtls_x509_time_is_past( &child->valid_to ) )
+            *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
+
+        if( mbedtls_x509_time_is_future( &child->valid_from ) )
+            *flags |= MBEDTLS_X509_BADCERT_FUTURE;
+
+        /* Stop here for trusted roots (but not for trusted EE certs) */
+        if( child_is_trusted )
+            return( 0 );
+
+        /* Check signature algorithm: MD & PK algs */
+        if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
+            *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
+
+        if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
+            *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
+
+        /* Special case: EE certs that are locally trusted */
+        if( ver_chain->len == 1 &&
+            x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 )
+        {
+            return( 0 );
+        }
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+find_parent:
+#endif
+        /* Look for a parent in trusted CAs or up the chain */
+        ret = x509_crt_find_parent( child, trust_ca, &parent,
+                                       &parent_is_trusted, &signature_is_good,
+                                       ver_chain->len - 1, self_cnt, rs_ctx );
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+        if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+        {
+            /* save state */
+            rs_ctx->in_progress = x509_crt_rs_find_parent;
+            rs_ctx->self_cnt = self_cnt;
+            rs_ctx->ver_chain = *ver_chain; /* struct copy */
+
+            return( ret );
+        }
+#else
+        (void) ret;
+#endif
+
+        /* No parent? We're done here */
+        if( parent == NULL )
+        {
+            *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
+            return( 0 );
+        }
+
+        /* Count intermediate self-issued (not necessarily self-signed) certs.
+         * These can occur with some strategies for key rollover, see [SIRO],
+         * and should be excluded from max_pathlen checks. */
+        if( ver_chain->len != 1 &&
+            x509_name_cmp( &child->issuer, &child->subject ) == 0 )
+        {
+            self_cnt++;
+        }
+
+        /* path_cnt is 0 for the first intermediate CA,
+         * and if parent is trusted it's not an intermediate CA */
+        if( ! parent_is_trusted &&
+            ver_chain->len > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
+        {
+            /* return immediately to avoid overflow the chain array */
+            return( MBEDTLS_ERR_X509_FATAL_ERROR );
+        }
+
+        /* signature was checked while searching parent */
+        if( ! signature_is_good )
+            *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
+
+        /* check size of signing key */
+        if( x509_profile_check_key( profile, &parent->pk ) != 0 )
+            *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
+
+#if defined(MBEDTLS_X509_CRL_PARSE_C)
+        /* Check trusted CA's CRL for the given crt */
+        *flags |= x509_crt_verifycrl( child, parent, ca_crl, profile );
+#else
+        (void) ca_crl;
+#endif
+
+        /* prepare for next iteration */
+        child = parent;
+        parent = NULL;
+        child_is_trusted = parent_is_trusted;
+        signature_is_good = 0;
+    }
+}
+
+/*
+ * Check for CN match
+ */
+static int x509_crt_check_cn( const mbedtls_x509_buf *name,
+                              const char *cn, size_t cn_len )
+{
+    /* try exact match */
+    if( name->len == cn_len &&
+        x509_memcasecmp( cn, name->p, cn_len ) == 0 )
+    {
+        return( 0 );
+    }
+
+    /* try wildcard match */
+    if( x509_check_wildcard( cn, name ) == 0 )
+    {
+        return( 0 );
+    }
+
+    return( -1 );
+}
+
+/*
+ * Verify the requested CN - only call this if cn is not NULL!
+ */
+static void x509_crt_verify_name( const mbedtls_x509_crt *crt,
+                                  const char *cn,
+                                  uint32_t *flags )
+{
+    const mbedtls_x509_name *name;
+    const mbedtls_x509_sequence *cur;
+    size_t cn_len = strlen( cn );
+
+    if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
+    {
+        for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next )
+        {
+            if( x509_crt_check_cn( &cur->buf, cn, cn_len ) == 0 )
+                break;
+        }
+
+        if( cur == NULL )
+            *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
+    }
+    else
+    {
+        for( name = &crt->subject; name != NULL; name = name->next )
+        {
+            if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 &&
+                x509_crt_check_cn( &name->val, cn, cn_len ) == 0 )
+            {
+                break;
+            }
+        }
+
+        if( name == NULL )
+            *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
+    }
+}
+
+/*
+ * Merge the flags for all certs in the chain, after calling callback
+ */
+static int x509_crt_merge_flags_with_cb(
+           uint32_t *flags,
+           const mbedtls_x509_crt_verify_chain *ver_chain,
+           int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+           void *p_vrfy )
+{
+    int ret;
+    unsigned i;
+    uint32_t cur_flags;
+    const mbedtls_x509_crt_verify_chain_item *cur;
+
+    for( i = ver_chain->len; i != 0; --i )
+    {
+        cur = &ver_chain->items[i-1];
+        cur_flags = cur->flags;
+
+        if( NULL != f_vrfy )
+            if( ( ret = f_vrfy( p_vrfy, cur->crt, (int) i-1, &cur_flags ) ) != 0 )
+                return( ret );
+
+        *flags |= cur_flags;
+    }
+
+    return( 0 );
+}
+
+/*
+ * Verify the certificate validity (default profile, not restartable)
+ */
+int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
+                     mbedtls_x509_crt *trust_ca,
+                     mbedtls_x509_crl *ca_crl,
+                     const char *cn, uint32_t *flags,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+                     void *p_vrfy )
+{
+    return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
+                &mbedtls_x509_crt_profile_default, cn, flags,
+                f_vrfy, p_vrfy, NULL ) );
+}
+
+/*
+ * Verify the certificate validity (user-chosen profile, not restartable)
+ */
+int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
+                     mbedtls_x509_crt *trust_ca,
+                     mbedtls_x509_crl *ca_crl,
+                     const mbedtls_x509_crt_profile *profile,
+                     const char *cn, uint32_t *flags,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+                     void *p_vrfy )
+{
+    return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
+                profile, cn, flags, f_vrfy, p_vrfy, NULL ) );
+}
+
+/*
+ * Verify the certificate validity, with profile, restartable version
+ *
+ * This function:
+ *  - checks the requested CN (if any)
+ *  - checks the type and size of the EE cert's key,
+ *    as that isn't done as part of chain building/verification currently
+ *  - builds and verifies the chain
+ *  - then calls the callback and merges the flags
+ */
+int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
+                     mbedtls_x509_crt *trust_ca,
+                     mbedtls_x509_crl *ca_crl,
+                     const mbedtls_x509_crt_profile *profile,
+                     const char *cn, uint32_t *flags,
+                     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+                     void *p_vrfy,
+                     mbedtls_x509_crt_restart_ctx *rs_ctx )
+{
+    int ret;
+    mbedtls_pk_type_t pk_type;
+    mbedtls_x509_crt_verify_chain ver_chain;
+    uint32_t ee_flags;
+
+    *flags = 0;
+    ee_flags = 0;
+    x509_crt_verify_chain_reset( &ver_chain );
+
+    if( profile == NULL )
+    {
+        ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
+        goto exit;
+    }
+
+    /* check name if requested */
+    if( cn != NULL )
+        x509_crt_verify_name( crt, cn, &ee_flags );
+
+    /* Check the type and size of the key */
+    pk_type = mbedtls_pk_get_type( &crt->pk );
+
+    if( x509_profile_check_pk_alg( profile, pk_type ) != 0 )
+        ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK;
+
+    if( x509_profile_check_key( profile, &crt->pk ) != 0 )
+        ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
+
+    /* Check the chain */
+    ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile,
+                                 &ver_chain, rs_ctx );
+
+    if( ret != 0 )
+        goto exit;
+
+    /* Merge end-entity flags */
+    ver_chain.items[0].flags |= ee_flags;
+
+    /* Build final flags, calling callback on the way if any */
+    ret = x509_crt_merge_flags_with_cb( flags, &ver_chain, f_vrfy, p_vrfy );
+
+exit:
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
+        mbedtls_x509_crt_restart_free( rs_ctx );
+#endif
+
+    /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by
+     * the SSL module for authmode optional, but non-zero return from the
+     * callback means a fatal error so it shouldn't be ignored */
+    if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
+        ret = MBEDTLS_ERR_X509_FATAL_ERROR;
+
+    if( ret != 0 )
+    {
+        *flags = (uint32_t) -1;
+        return( ret );
+    }
+
+    if( *flags != 0 )
+        return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
+
+    return( 0 );
+}
+
+/*
+ * Initialize a certificate chain
+ */
+void mbedtls_x509_crt_init( mbedtls_x509_crt *crt )
+{
+    memset( crt, 0, sizeof(mbedtls_x509_crt) );
+}
+
+/*
+ * Unallocate all certificate data
+ */
+void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
+{
+    mbedtls_x509_crt *cert_cur = crt;
+    mbedtls_x509_crt *cert_prv;
+    mbedtls_x509_name *name_cur;
+    mbedtls_x509_name *name_prv;
+    mbedtls_x509_sequence *seq_cur;
+    mbedtls_x509_sequence *seq_prv;
+
+    if( crt == NULL )
+        return;
+
+    do
+    {
+        mbedtls_pk_free( &cert_cur->pk );
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+        mbedtls_free( cert_cur->sig_opts );
+#endif
+
+        name_cur = cert_cur->issuer.next;
+        while( name_cur != NULL )
+        {
+            name_prv = name_cur;
+            name_cur = name_cur->next;
+            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+            mbedtls_free( name_prv );
+        }
+
+        name_cur = cert_cur->subject.next;
+        while( name_cur != NULL )
+        {
+            name_prv = name_cur;
+            name_cur = name_cur->next;
+            mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+            mbedtls_free( name_prv );
+        }
+
+        seq_cur = cert_cur->ext_key_usage.next;
+        while( seq_cur != NULL )
+        {
+            seq_prv = seq_cur;
+            seq_cur = seq_cur->next;
+            mbedtls_platform_zeroize( seq_prv,
+                                      sizeof( mbedtls_x509_sequence ) );
+            mbedtls_free( seq_prv );
+        }
+
+        seq_cur = cert_cur->subject_alt_names.next;
+        while( seq_cur != NULL )
+        {
+            seq_prv = seq_cur;
+            seq_cur = seq_cur->next;
+            mbedtls_platform_zeroize( seq_prv,
+                                      sizeof( mbedtls_x509_sequence ) );
+            mbedtls_free( seq_prv );
+        }
+
+        if( cert_cur->raw.p != NULL )
+        {
+            mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len );
+            mbedtls_free( cert_cur->raw.p );
+        }
+
+        cert_cur = cert_cur->next;
+    }
+    while( cert_cur != NULL );
+
+    cert_cur = crt;
+    do
+    {
+        cert_prv = cert_cur;
+        cert_cur = cert_cur->next;
+
+        mbedtls_platform_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
+        if( cert_prv != crt )
+            mbedtls_free( cert_prv );
+    }
+    while( cert_cur != NULL );
+}
+
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+/*
+ * Initialize a restart context
+ */
+void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx )
+{
+    mbedtls_pk_restart_init( &ctx->pk );
+
+    ctx->parent = NULL;
+    ctx->fallback_parent = NULL;
+    ctx->fallback_signature_is_good = 0;
+
+    ctx->parent_is_trusted = -1;
+
+    ctx->in_progress = x509_crt_rs_none;
+    ctx->self_cnt = 0;
+    x509_crt_verify_chain_reset( &ctx->ver_chain );
+}
+
+/*
+ * Free the components of a restart context
+ */
+void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_pk_restart_free( &ctx->pk );
+    mbedtls_x509_crt_restart_init( ctx );
+}
+#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
+
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_csr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_csr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509_csr.c	(revision 398)
@@ -0,0 +1,419 @@
+/*
+ *  X.509 Certificate Signing Request (CSR) parsing
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ *  The ITU-T X.509 standard defines a certificate format for PKI.
+ *
+ *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
+ *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
+ *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
+ *
+ *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
+ *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_X509_CSR_PARSE_C)
+
+#include "mbedtls/x509_csr.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+#include "mbedtls/pem.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#define mbedtls_free       free
+#define mbedtls_calloc    calloc
+#define mbedtls_snprintf   snprintf
+#endif
+
+#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
+#include <stdio.h>
+#endif
+
+/*
+ *  Version  ::=  INTEGER  {  v1(0)  }
+ */
+static int x509_csr_get_version( unsigned char **p,
+                             const unsigned char *end,
+                             int *ver )
+{
+    int ret;
+
+    if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
+    {
+        if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
+        {
+            *ver = 0;
+            return( 0 );
+        }
+
+        return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Parse a CSR in DER format
+ */
+int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
+                        const unsigned char *buf, size_t buflen )
+{
+    int ret;
+    size_t len;
+    unsigned char *p, *end;
+    mbedtls_x509_buf sig_params;
+
+    memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) );
+
+    /*
+     * Check for valid input
+     */
+    if( csr == NULL || buf == NULL || buflen == 0 )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    mbedtls_x509_csr_init( csr );
+
+    /*
+     * first copy the raw DER data
+     */
+    p = mbedtls_calloc( 1, len = buflen );
+
+    if( p == NULL )
+        return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+
+    memcpy( p, buf, buflen );
+
+    csr->raw.p = p;
+    csr->raw.len = len;
+    end = p + len;
+
+    /*
+     *  CertificationRequest ::= SEQUENCE {
+     *       certificationRequestInfo CertificationRequestInfo,
+     *       signatureAlgorithm AlgorithmIdentifier,
+     *       signature          BIT STRING
+     *  }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT );
+    }
+
+    if( len != (size_t) ( end - p ) )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+
+    /*
+     *  CertificationRequestInfo ::= SEQUENCE {
+     */
+    csr->cri.p = p;
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+    }
+
+    end = p + len;
+    csr->cri.len = end - csr->cri.p;
+
+    /*
+     *  Version  ::=  INTEGER {  v1(0) }
+     */
+    if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( ret );
+    }
+
+    if( csr->version != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
+    }
+
+    csr->version++;
+
+    /*
+     *  subject               Name
+     */
+    csr->subject_raw.p = p;
+
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+    }
+
+    if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( ret );
+    }
+
+    csr->subject_raw.len = p - csr->subject_raw.p;
+
+    /*
+     *  subjectPKInfo SubjectPublicKeyInfo
+     */
+    if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( ret );
+    }
+
+    /*
+     *  attributes    [0] Attributes
+     *
+     *  The list of possible attributes is open-ended, though RFC 2985
+     *  (PKCS#9) defines a few in section 5.4. We currently don't support any,
+     *  so we just ignore them. This is a safe thing to do as the worst thing
+     *  that could happen is that we issue a certificate that does not match
+     *  the requester's expectations - this cannot cause a violation of our
+     *  signature policies.
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+    }
+
+    p += len;
+
+    end = csr->raw.p + csr->raw.len;
+
+    /*
+     *  signatureAlgorithm   AlgorithmIdentifier,
+     *  signature            BIT STRING
+     */
+    if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params,
+                                  &csr->sig_md, &csr->sig_pk,
+                                  &csr->sig_opts ) ) != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
+    }
+
+    if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( ret );
+    }
+
+    if( p != end )
+    {
+        mbedtls_x509_csr_free( csr );
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+    }
+
+    return( 0 );
+}
+
+/*
+ * Parse a CSR, allowing for PEM or raw DER encoding
+ */
+int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen )
+{
+#if defined(MBEDTLS_PEM_PARSE_C)
+    int ret;
+    size_t use_len;
+    mbedtls_pem_context pem;
+#endif
+
+    /*
+     * Check for valid input
+     */
+    if( csr == NULL || buf == NULL || buflen == 0 )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+    /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
+    if( buf[buflen - 1] == '\0' )
+    {
+        mbedtls_pem_init( &pem );
+        ret = mbedtls_pem_read_buffer( &pem,
+                                       "-----BEGIN CERTIFICATE REQUEST-----",
+                                       "-----END CERTIFICATE REQUEST-----",
+                                       buf, NULL, 0, &use_len );
+        if( ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+        {
+            ret = mbedtls_pem_read_buffer( &pem,
+                                           "-----BEGIN NEW CERTIFICATE REQUEST-----",
+                                           "-----END NEW CERTIFICATE REQUEST-----",
+                                           buf, NULL, 0, &use_len );
+        }
+
+        if( ret == 0 )
+        {
+            /*
+             * Was PEM encoded, parse the result
+             */
+            ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen );
+        }
+
+        mbedtls_pem_free( &pem );
+        if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+            return( ret );
+    }
+#endif /* MBEDTLS_PEM_PARSE_C */
+    return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) );
+}
+
+#if defined(MBEDTLS_FS_IO)
+/*
+ * Load a CSR into the structure
+ */
+int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
+{
+    int ret;
+    size_t n;
+    unsigned char *buf;
+
+    if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
+        return( ret );
+
+    ret = mbedtls_x509_csr_parse( csr, buf, n );
+
+    mbedtls_platform_zeroize( buf, n );
+    mbedtls_free( buf );
+
+    return( ret );
+}
+#endif /* MBEDTLS_FS_IO */
+
+#define BEFORE_COLON    14
+#define BC              "14"
+/*
+ * Return an informational string about the CSR.
+ */
+int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
+                   const mbedtls_x509_csr *csr )
+{
+    int ret;
+    size_t n;
+    char *p;
+    char key_size_str[BEFORE_COLON];
+
+    p = buf;
+    n = size;
+
+    ret = mbedtls_snprintf( p, n, "%sCSR version   : %d",
+                               prefix, csr->version );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n%ssubject name  : ", prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+    ret = mbedtls_x509_dn_gets( p, n, &csr->subject );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
+                             csr->sig_opts );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
+                                      mbedtls_pk_get_name( &csr->pk ) ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
+                          (int) mbedtls_pk_get_bitlen( &csr->pk ) );
+    MBEDTLS_X509_SAFE_SNPRINTF;
+
+    return( (int) ( size - n ) );
+}
+
+/*
+ * Initialize a CSR
+ */
+void mbedtls_x509_csr_init( mbedtls_x509_csr *csr )
+{
+    memset( csr, 0, sizeof(mbedtls_x509_csr) );
+}
+
+/*
+ * Unallocate all CSR data
+ */
+void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
+{
+    mbedtls_x509_name *name_cur;
+    mbedtls_x509_name *name_prv;
+
+    if( csr == NULL )
+        return;
+
+    mbedtls_pk_free( &csr->pk );
+
+#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
+    mbedtls_free( csr->sig_opts );
+#endif
+
+    name_cur = csr->subject.next;
+    while( name_cur != NULL )
+    {
+        name_prv = name_cur;
+        name_cur = name_cur->next;
+        mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
+        mbedtls_free( name_prv );
+    }
+
+    if( csr->raw.p != NULL )
+    {
+        mbedtls_platform_zeroize( csr->raw.p, csr->raw.len );
+        mbedtls_free( csr->raw.p );
+    }
+
+    mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) );
+}
+
+#endif /* MBEDTLS_X509_CSR_PARSE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509write_crt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509write_crt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509write_crt.c	(revision 398)
@@ -0,0 +1,512 @@
+/*
+ *  X.509 certificate writing
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * References:
+ * - certificates: RFC 5280, updated by RFC 6818
+ * - CSRs: PKCS#10 v1.7 aka RFC 2986
+ * - attributes: PKCS#9 v2.0 aka RFC 2985
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_X509_CRT_WRITE_C)
+
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/asn1write.h"
+#include "mbedtls/sha1.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+#include "mbedtls/pem.h"
+#endif /* MBEDTLS_PEM_WRITE_C */
+
+void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_x509write_cert ) );
+
+    mbedtls_mpi_init( &ctx->serial );
+    ctx->version = MBEDTLS_X509_CRT_VERSION_3;
+}
+
+void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx )
+{
+    mbedtls_mpi_free( &ctx->serial );
+
+    mbedtls_asn1_free_named_data_list( &ctx->subject );
+    mbedtls_asn1_free_named_data_list( &ctx->issuer );
+    mbedtls_asn1_free_named_data_list( &ctx->extensions );
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_cert ) );
+}
+
+void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version )
+{
+    ctx->version = version;
+}
+
+void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg )
+{
+    ctx->md_alg = md_alg;
+}
+
+void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key )
+{
+    ctx->subject_key = key;
+}
+
+void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key )
+{
+    ctx->issuer_key = key;
+}
+
+int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx,
+                                    const char *subject_name )
+{
+    return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
+}
+
+int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx,
+                                   const char *issuer_name )
+{
+    return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name );
+}
+
+int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial )
+{
+    int ret;
+
+    if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before,
+                                const char *not_after )
+{
+    if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ||
+        strlen( not_after )  != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 )
+    {
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+    }
+    strncpy( ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN );
+    strncpy( ctx->not_after , not_after , MBEDTLS_X509_RFC5280_UTC_TIME_LEN );
+    ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
+    ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
+
+    return( 0 );
+}
+
+int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx,
+                                 const char *oid, size_t oid_len,
+                                 int critical,
+                                 const unsigned char *val, size_t val_len )
+{
+    return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
+                               critical, val, val_len );
+}
+
+int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
+                                         int is_ca, int max_pathlen )
+{
+    int ret;
+    unsigned char buf[9];
+    unsigned char *c = buf + sizeof(buf);
+    size_t len = 0;
+
+    memset( buf, 0, sizeof(buf) );
+
+    if( is_ca && max_pathlen > 127 )
+        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+
+    if( is_ca )
+    {
+        if( max_pathlen >= 0 )
+        {
+            MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, max_pathlen ) );
+        }
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) );
+    }
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                MBEDTLS_ASN1_SEQUENCE ) );
+
+    return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS,
+                                        MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ),
+                                        0, buf + sizeof(buf) - len, len );
+}
+
+#if defined(MBEDTLS_SHA1_C)
+int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx )
+{
+    int ret;
+    unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
+    unsigned char *c = buf + sizeof(buf);
+    size_t len = 0;
+
+    memset( buf, 0, sizeof(buf) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) );
+
+    ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
+                            buf + sizeof( buf ) - 20 );
+    if( ret != 0 )
+        return( ret );
+    c = buf + sizeof( buf ) - 20;
+    len = 20;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) );
+
+    return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
+                                        MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ),
+                                        0, buf + sizeof(buf) - len, len );
+}
+
+int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx )
+{
+    int ret;
+    unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
+    unsigned char *c = buf + sizeof( buf );
+    size_t len = 0;
+
+    memset( buf, 0, sizeof(buf) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) );
+
+    ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len,
+                            buf + sizeof( buf ) - 20 );
+    if( ret != 0 )
+        return( ret );
+    c = buf + sizeof( buf ) - 20;
+    len = 20;
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                MBEDTLS_ASN1_SEQUENCE ) );
+
+    return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
+                                   MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ),
+                                   0, buf + sizeof( buf ) - len, len );
+}
+#endif /* MBEDTLS_SHA1_C */
+
+static size_t crt_get_unused_bits_for_named_bitstring( unsigned char bitstring,
+                                                       size_t bit_offset )
+{
+    size_t unused_bits;
+
+     /* Count the unused bits removing trailing 0s */
+    for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ )
+        if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 )
+            break;
+
+     return( unused_bits );
+}
+
+int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
+                                         unsigned int key_usage )
+{
+    unsigned char buf[4], ku;
+    unsigned char *c;
+    int ret;
+    size_t unused_bits;
+    const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
+        MBEDTLS_X509_KU_NON_REPUDIATION   |
+        MBEDTLS_X509_KU_KEY_ENCIPHERMENT  |
+        MBEDTLS_X509_KU_DATA_ENCIPHERMENT |
+        MBEDTLS_X509_KU_KEY_AGREEMENT     |
+        MBEDTLS_X509_KU_KEY_CERT_SIGN     |
+        MBEDTLS_X509_KU_CRL_SIGN;
+
+    /* Check that nothing other than the allowed flags is set */
+    if( ( key_usage & ~allowed_bits ) != 0 )
+        return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+
+    c = buf + 4;
+    ku = (unsigned char)key_usage;
+    unused_bits = crt_get_unused_bits_for_named_bitstring( ku, 1 );
+    ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 8 - unused_bits );
+
+    if( ret < 0 )
+        return( ret );
+    else if( ret < 3 || ret > 4 )
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT );
+
+    ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
+                                       MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
+                                       1, c, (size_t)ret );
+    if( ret != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
+                                    unsigned char ns_cert_type )
+{
+    unsigned char buf[4];
+    unsigned char *c;
+    size_t unused_bits;
+    int ret;
+
+    c = buf + 4;
+
+    unused_bits = crt_get_unused_bits_for_named_bitstring( ns_cert_type, 0 );
+    ret = mbedtls_asn1_write_bitstring( &c,
+                                        buf,
+                                        &ns_cert_type,
+                                        8 - unused_bits );
+    if( ret < 3 || ret > 4 )
+        return( ret );
+
+    ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
+                                       MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
+                                       0, c, (size_t)ret );
+    if( ret != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+static int x509_write_time( unsigned char **p, unsigned char *start,
+                            const char *t, size_t size )
+{
+    int ret;
+    size_t len = 0;
+
+    /*
+     * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter)
+     */
+    if( t[0] == '2' && t[1] == '0' && t[2] < '5' )
+    {
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
+                                             (const unsigned char *) t + 2,
+                                             size - 2 ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_UTC_TIME ) );
+    }
+    else
+    {
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
+                                                  (const unsigned char *) t,
+                                                  size ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_GENERALIZED_TIME ) );
+    }
+
+    return( (int) len );
+}
+
+int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng )
+{
+    int ret;
+    const char *sig_oid;
+    size_t sig_oid_len = 0;
+    unsigned char *c, *c2;
+    unsigned char hash[64];
+    unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
+    unsigned char tmp_buf[2048];
+    size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
+    size_t len = 0;
+    mbedtls_pk_type_t pk_alg;
+
+    /*
+     * Prepare data to be signed in tmp_buf
+     */
+    c = tmp_buf + sizeof( tmp_buf );
+
+    /* Signature algorithm needed in TBS, and later for actual signature */
+
+    /* There's no direct way of extracting a signature algorithm
+     * (represented as an element of mbedtls_pk_type_t) from a PK instance. */
+    if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_RSA ) )
+        pk_alg = MBEDTLS_PK_RSA;
+    else if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_ECDSA ) )
+        pk_alg = MBEDTLS_PK_ECDSA;
+    else
+        return( MBEDTLS_ERR_X509_INVALID_ALG );
+
+    if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
+                                          &sig_oid, &sig_oid_len ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /*
+     *  Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
+     */
+
+    /* Only for v3 */
+    if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 )
+    {
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                           MBEDTLS_ASN1_SEQUENCE ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+                                                           MBEDTLS_ASN1_CONSTRUCTED | 3 ) );
+    }
+
+    /*
+     *  SubjectPublicKeyInfo
+     */
+    MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->subject_key,
+                                                tmp_buf, c - tmp_buf ) );
+    c -= pub_len;
+    len += pub_len;
+
+    /*
+     *  Subject  ::=  Name
+     */
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
+
+    /*
+     *  Validity ::= SEQUENCE {
+     *       notBefore      Time,
+     *       notAfter       Time }
+     */
+    sub_len = 0;
+
+    MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after,
+                                            MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
+
+    MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before,
+                                            MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
+
+    len += sub_len;
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                    MBEDTLS_ASN1_SEQUENCE ) );
+
+    /*
+     *  Issuer  ::=  Name
+     */
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->issuer ) );
+
+    /*
+     *  Signature   ::=  AlgorithmIdentifier
+     */
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, tmp_buf,
+                       sig_oid, strlen( sig_oid ), 0 ) );
+
+    /*
+     *  Serial   ::=  INTEGER
+     */
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, tmp_buf, &ctx->serial ) );
+
+    /*
+     *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+     */
+
+    /* Can be omitted for v1 */
+    if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 )
+    {
+        sub_len = 0;
+        MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) );
+        len += sub_len;
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
+                                                           MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
+    }
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                       MBEDTLS_ASN1_SEQUENCE ) );
+
+    /*
+     * Make signature
+     */
+    if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c,
+                            len, hash ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len,
+                         f_rng, p_rng ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /*
+     * Write data to output buffer
+     */
+    c2 = buf + size;
+    MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
+                                        sig_oid, sig_oid_len, sig, sig_len ) );
+
+    if( len > (size_t)( c2 - buf ) )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    c2 -= len;
+    memcpy( c2, c, len );
+
+    len += sig_and_oid_len;
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                 MBEDTLS_ASN1_SEQUENCE ) );
+
+    return( (int) len );
+}
+
+#define PEM_BEGIN_CRT           "-----BEGIN CERTIFICATE-----\n"
+#define PEM_END_CRT             "-----END CERTIFICATE-----\n"
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, unsigned char *buf, size_t size,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng )
+{
+    int ret;
+    unsigned char output_buf[4096];
+    size_t olen = 0;
+
+    if( ( ret = mbedtls_x509write_crt_der( crt, output_buf, sizeof(output_buf),
+                                   f_rng, p_rng ) ) < 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT,
+                                  output_buf + sizeof(output_buf) - ret,
+                                  ret, buf, size, &olen ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_PEM_WRITE_C */
+
+#endif /* MBEDTLS_X509_CRT_WRITE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509write_csr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509write_csr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509write_csr.c	(revision 398)
@@ -0,0 +1,290 @@
+/*
+ *  X.509 Certificate Signing Request writing
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+/*
+ * References:
+ * - CSRs: PKCS#10 v1.7 aka RFC 2986
+ * - attributes: PKCS#9 v2.0 aka RFC 2985
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_X509_CSR_WRITE_C)
+
+#include "mbedtls/x509_csr.h"
+#include "mbedtls/oid.h"
+#include "mbedtls/asn1write.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+#include "mbedtls/pem.h"
+#endif
+
+void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_x509write_csr ) );
+}
+
+void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx )
+{
+    mbedtls_asn1_free_named_data_list( &ctx->subject );
+    mbedtls_asn1_free_named_data_list( &ctx->extensions );
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_csr ) );
+}
+
+void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg )
+{
+    ctx->md_alg = md_alg;
+}
+
+void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key )
+{
+    ctx->key = key;
+}
+
+int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx,
+                                    const char *subject_name )
+{
+    return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
+}
+
+int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
+                                 const char *oid, size_t oid_len,
+                                 const unsigned char *val, size_t val_len )
+{
+    return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
+                               0, val, val_len );
+}
+
+static size_t csr_get_unused_bits_for_named_bitstring( unsigned char bitstring,
+                                                       size_t bit_offset )
+{
+    size_t unused_bits;
+
+     /* Count the unused bits removing trailing 0s */
+    for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ )
+        if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 )
+            break;
+
+     return( unused_bits );
+}
+
+int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage )
+{
+    unsigned char buf[4];
+    unsigned char *c;
+    size_t unused_bits;
+    int ret;
+
+    c = buf + 4;
+
+    unused_bits = csr_get_unused_bits_for_named_bitstring( key_usage, 0 );
+    ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 8 - unused_bits );
+
+    if( ret < 0 )
+        return( ret );
+    else if( ret < 3 || ret > 4 )
+        return( MBEDTLS_ERR_X509_INVALID_FORMAT );
+
+    ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
+                                       MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
+                                       c, (size_t)ret );
+    if( ret != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
+                                    unsigned char ns_cert_type )
+{
+    unsigned char buf[4];
+    unsigned char *c;
+    size_t unused_bits;
+    int ret;
+
+    c = buf + 4;
+
+    unused_bits = csr_get_unused_bits_for_named_bitstring( ns_cert_type, 0 );
+    ret = mbedtls_asn1_write_bitstring( &c,
+                                        buf,
+                                        &ns_cert_type,
+                                        8 - unused_bits );
+
+    if( ret < 0 )
+        return( ret );
+    else if( ret < 3 || ret > 4 )
+        return( ret );
+
+    ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
+                                       MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
+                                       c, (size_t)ret );
+    if( ret != 0 )
+        return( ret );
+
+    return( 0 );
+}
+
+int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng )
+{
+    int ret;
+    const char *sig_oid;
+    size_t sig_oid_len = 0;
+    unsigned char *c, *c2;
+    unsigned char hash[64];
+    unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
+    unsigned char tmp_buf[2048];
+    size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
+    size_t len = 0;
+    mbedtls_pk_type_t pk_alg;
+
+    /*
+     * Prepare data to be signed in tmp_buf
+     */
+    c = tmp_buf + sizeof( tmp_buf );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
+
+    if( len )
+    {
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                        MBEDTLS_ASN1_SEQUENCE ) );
+
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                        MBEDTLS_ASN1_SET ) );
+
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
+                                          MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) );
+
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
+        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                        MBEDTLS_ASN1_SEQUENCE ) );
+    }
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                    MBEDTLS_ASN1_CONTEXT_SPECIFIC ) );
+
+    MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key,
+                                                tmp_buf, c - tmp_buf ) );
+    c -= pub_len;
+    len += pub_len;
+
+    /*
+     *  Subject  ::=  Name
+     */
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
+
+    /*
+     *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+     */
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) );
+
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                    MBEDTLS_ASN1_SEQUENCE ) );
+
+    /*
+     * Prepare signature
+     */
+    mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
+
+    if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
+                                 f_rng, p_rng ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_RSA ) )
+        pk_alg = MBEDTLS_PK_RSA;
+    else if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_ECDSA ) )
+        pk_alg = MBEDTLS_PK_ECDSA;
+    else
+        return( MBEDTLS_ERR_X509_INVALID_ALG );
+
+    if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
+                                                &sig_oid, &sig_oid_len ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    /*
+     * Write data to output buffer
+     */
+    c2 = buf + size;
+    MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
+                                        sig_oid, sig_oid_len, sig, sig_len ) );
+
+    if( len > (size_t)( c2 - buf ) )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+    c2 -= len;
+    memcpy( c2, c, len );
+
+    len += sig_and_oid_len;
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
+    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
+                                                 MBEDTLS_ASN1_SEQUENCE ) );
+
+    return( (int) len );
+}
+
+#define PEM_BEGIN_CSR           "-----BEGIN CERTIFICATE REQUEST-----\n"
+#define PEM_END_CSR             "-----END CERTIFICATE REQUEST-----\n"
+
+#if defined(MBEDTLS_PEM_WRITE_C)
+int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
+                       int (*f_rng)(void *, unsigned char *, size_t),
+                       void *p_rng )
+{
+    int ret;
+    unsigned char output_buf[4096];
+    size_t olen = 0;
+
+    if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf),
+                                   f_rng, p_rng ) ) < 0 )
+    {
+        return( ret );
+    }
+
+    if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
+                                  output_buf + sizeof(output_buf) - ret,
+                                  ret, buf, size, &olen ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_PEM_WRITE_C */
+
+#endif /* MBEDTLS_X509_CSR_WRITE_C */
Index: /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/xtea.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/xtea.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/xtea.c	(revision 398)
@@ -0,0 +1,277 @@
+/*
+ *  An 32-bit implementation of the XTEA algorithm
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_XTEA_C)
+
+#include "mbedtls/xtea.h"
+#include "mbedtls/platform_util.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if !defined(MBEDTLS_XTEA_ALT)
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_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
+
+void mbedtls_xtea_init( mbedtls_xtea_context *ctx )
+{
+    memset( ctx, 0, sizeof( mbedtls_xtea_context ) );
+}
+
+void mbedtls_xtea_free( mbedtls_xtea_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_xtea_context ) );
+}
+
+/*
+ * XTEA key schedule
+ */
+void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] )
+{
+    int i;
+
+    memset( ctx, 0, sizeof(mbedtls_xtea_context) );
+
+    for( i = 0; i < 4; i++ )
+    {
+        GET_UINT32_BE( ctx->k[i], key, i << 2 );
+    }
+}
+
+/*
+ * XTEA encrypt function
+ */
+int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode,
+                    const unsigned char input[8], unsigned char output[8])
+{
+    uint32_t *k, v0, v1, i;
+
+    k = ctx->k;
+
+    GET_UINT32_BE( v0, input, 0 );
+    GET_UINT32_BE( v1, input, 4 );
+
+    if( mode == MBEDTLS_XTEA_ENCRYPT )
+    {
+        uint32_t sum = 0, delta = 0x9E3779B9;
+
+        for( i = 0; i < 32; i++ )
+        {
+            v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
+            sum += delta;
+            v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
+        }
+    }
+    else /* MBEDTLS_XTEA_DECRYPT */
+    {
+        uint32_t delta = 0x9E3779B9, sum = delta * 32;
+
+        for( i = 0; i < 32; i++ )
+        {
+            v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
+            sum -= delta;
+            v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
+        }
+    }
+
+    PUT_UINT32_BE( v0, output, 0 );
+    PUT_UINT32_BE( v1, output, 4 );
+
+    return( 0 );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * XTEA-CBC buffer encryption/decryption
+ */
+int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, int mode, size_t length,
+                    unsigned char iv[8], const unsigned char *input,
+                    unsigned char *output)
+{
+    int i;
+    unsigned char temp[8];
+
+    if( length % 8 )
+        return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH );
+
+    if( mode == MBEDTLS_XTEA_DECRYPT )
+    {
+        while( length > 0 )
+        {
+            memcpy( temp, input, 8 );
+            mbedtls_xtea_crypt_ecb( ctx, mode, input, output );
+
+            for( i = 0; i < 8; i++ )
+                output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+            memcpy( iv, temp, 8 );
+
+            input  += 8;
+            output += 8;
+            length -= 8;
+        }
+    }
+    else
+    {
+        while( length > 0 )
+        {
+            for( i = 0; i < 8; i++ )
+                output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+            mbedtls_xtea_crypt_ecb( ctx, mode, output, output );
+            memcpy( iv, output, 8 );
+
+            input  += 8;
+            output += 8;
+            length -= 8;
+        }
+    }
+
+    return( 0 );
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#endif /* !MBEDTLS_XTEA_ALT */
+
+#if defined(MBEDTLS_SELF_TEST)
+
+/*
+ * XTEA tests vectors (non-official)
+ */
+
+static const unsigned char xtea_test_key[6][16] =
+{
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+     0x0c, 0x0d, 0x0e, 0x0f },
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+     0x0c, 0x0d, 0x0e, 0x0f },
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+     0x0c, 0x0d, 0x0e, 0x0f },
+   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00 },
+   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 unsigned char xtea_test_pt[6][8] =
+{
+    { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
+    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
+    { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
+    { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
+    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
+    { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
+};
+
+static const unsigned char xtea_test_ct[6][8] =
+{
+    { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
+    { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
+    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
+    { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
+    { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
+    { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
+};
+
+/*
+ * Checkup routine
+ */
+int mbedtls_xtea_self_test( int verbose )
+{
+    int i, ret = 0;
+    unsigned char buf[8];
+    mbedtls_xtea_context ctx;
+
+    mbedtls_xtea_init( &ctx );
+    for( i = 0; i < 6; i++ )
+    {
+        if( verbose != 0 )
+            mbedtls_printf( "  XTEA test #%d: ", i + 1 );
+
+        memcpy( buf, xtea_test_pt[i], 8 );
+
+        mbedtls_xtea_setup( &ctx, xtea_test_key[i] );
+        mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, buf, buf );
+
+        if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 )
+        {
+            if( verbose != 0 )
+                mbedtls_printf( "failed\n" );
+
+            ret = 1;
+            goto exit;
+        }
+
+        if( verbose != 0 )
+            mbedtls_printf( "passed\n" );
+    }
+
+    if( verbose != 0 )
+        mbedtls_printf( "\n" );
+
+exit:
+    mbedtls_xtea_free( &ctx );
+
+    return( ret );
+}
+
+#endif /* MBEDTLS_SELF_TEST */
+
+#endif /* MBEDTLS_XTEA_C */
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/.cproject
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/.cproject	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/.cproject	(revision 398)
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.922945172">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.922945172" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings>
+					<externalSetting>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/musl"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/musl-1.1.18"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/musl/Debug"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/musl-1.1.18/Debug"/>
+						<entry flags="RESOLVED" kind="libraryFile" name="musl" srcPrefixMapping="" srcRootPath=""/>
+					</externalSetting>
+				</externalSettings>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="com.renesas.cdt.managedbuild.core.toolchainInfo">
+				<option id="toolchain.id" value="RENESAS_GCC_RX"/>
+				<option id="toolchain.version" value="4.8.4.201803"/>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="a" artifactName="musl" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="" id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.922945172" name="Debug" parent="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib">
+					<folderInfo id="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.922945172." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib.634294089" name="GCC for Renesas RX" superClass="com.renesas.cdt.managedbuild.gcc.rx.ui.toolChain.debug.lib">
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.274900320" name="Optimization Level" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.optimization.optimizationLevel.debug" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections.433780073" name="Data sections (-fdata-sections)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.fdatasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.2018829133" name="Debug format" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.debug.debugFormat.Default" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.1157831340" name="Architecture" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture" useByScannerDiscovery="false" value="com.renesas.cdt.managedbuild.gcc.rx.architecture.v1" valueType="enumerated"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability.326382737" name="Architecture Applicability" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.architecture.applicability" useByScannerDiscovery="false" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName.556693418" name="DeviceName" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceShortName" useByScannerDiscovery="false" value="R5F563NBDxFP" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand.614640820" name="DeviceCommand" superClass="com.renesas.cdt.managedbuild.gcc.core.option.deviceCommand" useByScannerDiscovery="false" value="R5F563NB" valueType="string"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize.223830224" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.managedbuild.gcc.core.option.debug.warnStackSize" useByScannerDiscovery="false" value="100" valueType="string"/>
+							<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.gcc.core.option.warnings.otherFlags.1638796861" name="Other Flags" superClass="com.renesas.cdt.managedbuild.gcc.core.option.warnings.otherFlags" useByScannerDiscovery="false" valueType="stringList">
+								<listOptionValue builtIn="false" value="-Werror=implicit-function-declaration"/>
+								<listOptionValue builtIn="false" value="-Werror=implicit-int"/>
+								<listOptionValue builtIn="false" value="-Werror=pointer-sign"/>
+								<listOptionValue builtIn="false" value="-Werror=pointer-arith"/>
+							</option>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.optimization.functionsections.730653111" name="Function sections (-ffunction-sections)" superClass="com.renesas.cdt.managedbuild.gcc.core.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<option id="com.renesas.cdt.managedbuild.gcc.core.option.cpu.64bitdouble.1900028908" name="Make the double data type be 64 bits in size" superClass="com.renesas.cdt.managedbuild.gcc.core.option.cpu.64bitdouble" useByScannerDiscovery="true" value="true" valueType="boolean"/>
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.renesas.cdt.managedbuild.gcc.core.targetPlatform.1287712370" isAbstract="false" osList="all" superClass="com.renesas.cdt.managedbuild.gcc.core.targetPlatform"/>
+							<builder buildPath="${workspace_loc:/musl}/Debug" id="com.renesas.cdt.managedbuild.gcc.core.builder.1709148240" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="GCC for Renesas Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.managedbuild.gcc.core.builder"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen.155921276" name="Library Generator" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.libgen">
+								<option id="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary.338777218" name="Select Library" superClass="com.renesas.cdt.managedbuild.gcc.rx.option.selectlibrary" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.selectLibrary.newLib" valueType="enumerated"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.ctype.283378288" name="ctype.h : Handles and checks characters" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.ctype" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.math.850604504" name="math.h : Performs numeric calculations" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.math" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdio.2135972498" name="stdio.h : Performs input/output handling" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdio" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdlib.2100068518" name="stdlib.h : Performs C program standard processing" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.stdlib" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.string.937981782" name="string.h : Performs string operations" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.headerfiles.string" useByScannerDiscovery="true" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType.862347981" name="Library type" superClass="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.librarygenerator.settings.libraryType.preBuilt" valueType="enumerated"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.763816090" name="Compiler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.1951916691" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" useByScannerDiscovery="false" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/arch/rx}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/internal}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
+								</option>
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.source.std.6972765" name="Language standard" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.source.std" useByScannerDiscovery="true" value="com.renesas.cdt.managedbuild.gcc.core.option.compiler.common.c99" valueType="enumerated"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.macroDefines.1564870843" name="Macro Defines" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.macroDefines" useByScannerDiscovery="false" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="__RX_LITTLE_ENDIAN__=1"/>
+									<listOptionValue builtIn="false" value="_XOPEN_SOURCE=700"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.source.userDefinedCompilerOptions.156982428" name="User defined compiler options" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.source.userDefinedCompilerOptions" useByScannerDiscovery="false" valueType="stringList">
+									<listOptionValue builtIn="false" value="-ffreestanding"/>
+									<listOptionValue builtIn="false" value="-fexcess-precision=standard"/>
+									<listOptionValue builtIn="false" value="-frounding-math"/>
+									<listOptionValue builtIn="false" value="-fomit-frame-pointer"/>
+									<listOptionValue builtIn="false" value="-fno-unwind-tables"/>
+									<listOptionValue builtIn="false" value="-fno-asynchronous-unwind-tables"/>
+									<listOptionValue builtIn="false" value="-include vis.h"/>
+								</option>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.915674107" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler.547534028" name="Compiler CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.compiler">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir.319518528" name="Include file directories" superClass="com.renesas.cdt.managedbuild.gcc.core.option.compiler.includes.includeFileDir" valueType="includePath"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler.976766199" name="Assembler" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.assembler">
+								<option id="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor.1250603937" name="Use preprocessor" superClass="com.renesas.cdt.managedbuild.gcc.core.option.assembler.source.usepreprocessor" useByScannerDiscovery="false"/>
+								<inputType id="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler.1545118025" superClass="com.renesas.cdt.managedbuild.gcc.core.inputType.assembler"/>
+							</tool>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.linker.482711349" name="Linker" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.linker"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker.656351591" name="Linker CPP" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.cpp.linker"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy.1548183937" name="Objcopy" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.objcopy"/>
+							<tool id="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver.14438548" name="Archiver" superClass="com.renesas.cdt.managedbuild.gcc.rx.tool.archiver"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="crt"/>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="ldso"/>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="musl.com.renesas.cdt.managedbuild.gcc.rx.ui.projectType.lib.1855892303" name="static ã©ã¤ãã©ãªã¼" projectType="com.renesas.cdt.managedbuild.gcc.rx.ui.projectType.lib"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		<scannerConfigBuildInfo instanceId="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.922945172;com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.debug.lib.922945172.;com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.763816090;com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.915674107">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+		<scannerConfigBuildInfo instanceId="com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.release.lib.1854302758;com.renesas.cdt.managedbuild.gcc.rx.ui.configuration.release.lib.1854302758.;com.renesas.cdt.managedbuild.gcc.rx.tool.compiler.501037853;com.renesas.cdt.managedbuild.gcc.core.inputType.compiler.c.1092496434">
+			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+		</scannerConfigBuildInfo>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/musl-1.1.18"/>
+		</configuration>
+		<configuration configurationName="Release">
+			<resource resourceType="PROJECT" workspacePath="/musl-1.1.18"/>
+		</configuration>
+	</storageModule>
+</cproject>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/.project
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/.project	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/.project	(revision 398)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>musl</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/COPYRIGHT
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/COPYRIGHT	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/COPYRIGHT	(revision 398)
@@ -0,0 +1,163 @@
+musl as a whole is licensed under the following standard MIT license:
+
+----------------------------------------------------------------------
+Copyright 息 2005-2014 Rich Felker, et al.
+
+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.
+----------------------------------------------------------------------
+
+Authors/contributors include:
+
+Alex Dowad
+Alexander Monakov
+Anthony G. Basile
+Arvid Picciani
+Bobby Bingham
+Boris Brezillon
+Brent Cook
+Chris Spiegel
+Cl辿ment Vasseur
+Daniel Micay
+Denys Vlasenko
+Emil Renner Berthing
+Felix Fietkau
+Felix Janda
+Gianluca Anzolin
+Hauke Mehrtens
+Hiltjo Posthuma
+Isaac Dunham
+Jaydeep Patil
+Jens Gustedt
+Jeremy Huntwork
+Jo-Philipp Wich
+Joakim Sindholt
+John Spencer
+Josiah Worcester
+Justin Cormack
+Khem Raj
+Kylie McClain
+Luca Barbato
+Luka Perkov
+M Farkas-Dyck (Strake)
+Mahesh Bodapati
+Michael Forney
+Natanael Copa
+Nicholas J. Kain
+orc
+Pascal Cuoq
+Petr Hosek
+Pierre Carrier
+Rich Felker
+Richard Pennington
+Shiz
+sin
+Solar Designer
+Stefan Kristiansson
+Szabolcs Nagy
+Timo Ter辰s
+Trutz Behn
+Valentin Ochs
+William Haddon
+
+Portions of this software are derived from third-party works licensed
+under terms compatible with the above MIT license:
+
+The TRE regular expression implementation (src/regex/reg* and
+src/regex/tre*) is Copyright 息 2001-2008 Ville Laurikari and licensed
+under a 2-clause BSD license (license text in the source files). The
+included version has been heavily modified by Rich Felker in 2012, in
+the interests of size, simplicity, and namespace cleanliness.
+
+Much of the math library code (src/math/* and src/complex/*) is
+Copyright 息 1993,2004 Sun Microsystems or
+Copyright 息 2003-2011 David Schultz or
+Copyright 息 2003-2009 Steven G. Kargl or
+Copyright 息 2003-2009 Bruce D. Evans or
+Copyright 息 2008 Stephen L. Moshier
+and labelled as such in comments in the individual source files. All
+have been licensed under extremely permissive terms.
+
+The ARM memcpy code (src/string/arm/memcpy_el.S) is Copyright 息 2008
+The Android Open Source Project and is licensed under a two-clause BSD
+license. It was taken from Bionic libc, used on Android.
+
+The implementation of DES for crypt (src/crypt/crypt_des.c) is
+Copyright 息 1994 David Burren. It is licensed under a BSD license.
+
+The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
+originally written by Solar Designer and placed into the public
+domain. The code also comes with a fallback permissive license for use
+in jurisdictions that may not recognize the public domain.
+
+The smoothsort implementation (src/stdlib/qsort.c) is Copyright 息 2011
+Valentin Ochs and is licensed under an MIT-style license.
+
+The BSD PRNG implementation (src/prng/random.c) and XSI search API
+(src/search/*.c) functions are Copyright 息 2011 Szabolcs Nagy and
+licensed under following terms: "Permission to use, copy, modify,
+and/or distribute this code for any purpose with or without fee is
+hereby granted. There is no warranty."
+
+The x86_64 port was written by Nicholas J. Kain and is licensed under
+the standard MIT terms.
+
+The mips and microblaze ports were originally written by Richard
+Pennington for use in the ellcc project. The original code was adapted
+by Rich Felker for build system and code conventions during upstream
+integration. It is licensed under the standard MIT terms.
+
+The mips64 port was contributed by Imagination Technologies and is
+licensed under the standard MIT terms.
+
+The powerpc port was also originally written by Richard Pennington,
+and later supplemented and integrated by John Spencer. It is licensed
+under the standard MIT terms.
+
+All other files which have no copyright comments are original works
+produced specifically for use as part of this library, written either
+by Rich Felker, the main author of the library, or by one or more
+contibutors listed above. Details on authorship of individual files
+can be found in the git version control history of the project. The
+omission of copyright and license comments in each file is in the
+interest of source tree size.
+
+In addition, permission is hereby granted for all public header files
+(include/* and arch/*/bits/*) and crt files intended to be linked into
+applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
+the copyright notice and permission notice otherwise required by the
+license, and to use these files without any requirement of
+attribution. These files include substantial contributions from:
+
+Bobby Bingham
+John Spencer
+Nicholas J. Kain
+Rich Felker
+Richard Pennington
+Stefan Kristiansson
+Szabolcs Nagy
+
+all of whom have explicitly granted such permission.
+
+This file previously contained text expressing a belief that most of
+the files covered by the above exception were sufficiently trivial not
+to be subject to copyright, resulting in confusion over whether it
+negated the permissions granted in the license. In the spirit of
+permissive licensing, and of not having licensing issues being an
+obstacle to adoption, that text has been removed.
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/INSTALL
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/INSTALL	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/INSTALL	(revision 398)
@@ -0,0 +1,185 @@
+
+Quick Installation Guide for musl libc
+======================================
+
+There are many different ways to install musl depending on your usage
+case. This document covers only the build and installation of musl by
+itself, which is useful for upgrading an existing musl-based system or
+compiler toolchain, or for using the provided musl-gcc wrapper with an
+existing non-musl-based compiler.
+
+Building complete native or cross-compiler toolchains is outside the
+scope of this INSTALL file. More information can be found on the musl
+website and community wiki.
+
+
+Build Prerequisites
+-------------------
+
+The only build-time prerequisites for musl are GNU Make and a
+freestanding C99 compiler toolchain targeting the desired instruction
+set architecture and ABI, with support for a minimal subset of "GNU C"
+extensions consisting mainly of gcc-style inline assembly, weak
+aliases, hidden visibility, and stand-alone assembly source files.
+
+GCC, LLVM/clang, Firm/cparser, and PCC have all successfully built
+musl, but GCC is the most widely used/tested. Recent compiler (and
+binutils) versions should be used if possible since some older
+versions have bugs which affect musl.
+
+The system used to build musl does not need to be Linux-based, nor do
+the Linux kernel headers need to be available.
+
+
+
+Supported Targets
+-----------------
+
+musl can be built for the following CPU instruction set architecture
+and ABI combinations:
+
+* i386
+    * Minimum CPU model is actually 80486 unless kernel emulation of
+      the `cmpxchg` instruction is added
+
+* x86_64
+    * ILP32 ABI (x32) is available as a separate arch but is still
+      experimental
+
+* ARM
+    * EABI, standard or hard-float VFP variant
+    * Little-endian default; big-endian variants also supported
+    * Compiler toolchains only support armv4t and later
+
+* AArch64
+    * Little-endian default; big-endian variants also supported
+
+* MIPS
+    * ABI is o32
+    * Big-endian default; little-endian variants also supported
+    * Default ABI variant uses FPU registers; alternate soft-float ABI
+      that does not use FPU registers or instructions is available
+    * MIPS2 or later, or kernel emulation of ll/sc (standard in Linux)
+      is required
+
+* MIPS64
+    * ABI is n64 (LP64)
+    * Big-endian default; little-endian variants also supported
+    * Default ABI variant uses FPU registers; alternate soft-float ABI
+      that does not use FPU registers or instructions is available
+
+* PowerPC
+    * Compiler toolchain must provide 64-bit long double, not IBM
+      double-double or IEEE quad
+    * For dynamic linking, compiler toolchain must be configured for
+      "secure PLT" variant
+
+* PowerPC64
+    * Both little and big endian variants are supported
+    * Compiler toolchain must provide 64-bit long double, not IBM
+      double-double or IEEE quad
+    * Compiler toolchain must use the new (ELFv2) ABI regardless of
+      whether it is for little or big endian
+
+* S390X (64-bit S390)
+
+* SuperH (SH)
+    * Standard ELF ABI or FDPIC ABI (shared-text without MMU)
+    * Little-endian by default; big-engian variant also supported
+    * Full FPU ABI or soft-float ABI is supported, but the
+      single-precision-only FPU ABI is not
+
+* Microblaze
+    * Big-endian default; little-endian variants also supported
+    * Soft-float
+    * Requires support for lwx/swx instructions
+
+* OpenRISC 1000 (or1k)
+
+
+
+Build and Installation Procedure
+--------------------------------
+
+To build and install musl:
+
+1. Run the provided configure script from the top-level source
+   directory, passing on its command line any desired options.
+
+2. Run "make" to compile.
+
+3. Run "make install" with appropriate privileges to write to the
+   target locations.
+
+The configure script attempts to determine automatically the correct
+target architecture based on the compiler being used. For some
+compilers, this may not be possible. If detection fails or selects the
+wrong architecture, you can provide an explicit selection on the
+configure command line.
+
+By default, configure installs to a prefix of "/usr/local/musl". This
+differs from the behavior of most configure scripts, and is chosen
+specifically to avoid clashing with libraries already present on the
+system. DO NOT set the prefix to "/usr", "/usr/local", or "/" unless
+you're upgrading libc on an existing musl-based system. Doing so will
+break your existing system when you run "make install" and it may be
+difficult to recover.
+
+
+
+Notes on Dynamic Linking
+------------------------
+
+If dynamic linking is enabled, one file needs to be installed outside
+of the installation prefix: /lib/ld-musl-$ARCH.so.1. This is the
+dynamic linker. Its pathname is hard-coded into all dynamic-linked
+programs, so for the sake of being able to share binaries between
+systems, a consistent location should be used everywhere. Note that
+the same applies to glibc and its dynamic linker, which is named
+/lib/ld-linux.so.2 on i386 systems.
+
+If for some reason it is impossible to install the dynamic linker in
+its standard location (for example, if you are installing without root
+privileges), the --syslibdir option to configure can be used to
+provide a different location
+
+At runtime, the dynamic linker needs to know the paths to search for
+shared libraries. You should create a text file named
+/etc/ld-musl-$ARCH.path (where $ARCH matches the architecture name
+used in the dynamic linker) containing a list of directories where you
+want the dynamic linker to search for shared libraries, separated by
+colons or newlines. If the dynamic linker has been installed in a
+non-default location, the path file also needs to reside at that
+location (../etc relative to the chosen syslibdir).
+
+If you do not intend to use dynamic linking, you may disable it by
+passing --disable-shared to configure; this also cuts the build time
+in half.
+
+
+
+Checking for Successful Installation
+------------------------------------
+
+After installing, you should be able to use musl via the musl-gcc
+wrapper. For example:
+
+cat > hello.c <<EOF
+#include <stdio.h>
+int main()
+{
+	printf("hello, world!\n");
+	return 0;
+}
+EOF
+/usr/local/musl/bin/musl-gcc hello.c
+./a.out
+
+To configure autoconf-based program to compile and link against musl,
+set the CC variable to musl-gcc when running configure, as in:
+
+CC=musl-gcc ./configure ...
+
+You will probably also want to use --prefix when building libraries to
+ensure that they are installed under the musl prefix and not in the
+main host system library directories.
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/README
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/README	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/README	(revision 398)
@@ -0,0 +1,23 @@
+
+    musl libc
+
+musl, pronounced like the word "mussel", is an MIT-licensed
+implementation of the standard C library targetting the Linux syscall
+API, suitable for use in a wide range of deployment environments. musl
+offers efficient static and dynamic linking support, lightweight code
+and low runtime overhead, strong fail-safe guarantees under correct
+usage, and correctness in the sense of standards conformance and
+safety. musl is built on the principle that these goals are best
+achieved through simple code that is easy to understand and maintain.
+
+The 1.1 release series for musl features coverage for all interfaces
+defined in ISO C99 and POSIX 2008 base, along with a number of
+non-standardized interfaces for compatibility with Linux, BSD, and
+glibc functionality.
+
+For basic installation instructions, see the included INSTALL file.
+Information on full musl-targeted compiler toolchains, system
+bootstrapping, and Linux distributions built on musl can be found on
+the project website:
+
+    http://www.musl-libc.org/
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/VERSION
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/VERSION	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/VERSION	(revision 398)
@@ -0,0 +1,1 @@
+1.1.18
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/WHATSNEW
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/WHATSNEW	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/WHATSNEW	(revision 398)
@@ -0,0 +1,1864 @@
+0.5.0 - initial release
+
+
+
+0.5.9 - signal ABI bugfix, various cleanup and fixes:
+
+sigset_t was wrongly defined as 1024 bytes instead of 1024 bits,
+breaking the intended ABI compatibility with the LSB/glibc sigaction
+structure. users should upgrade immediately and rebuild any libraries
+or object files that might be using the incorrect definitions.
+
+improved security against DoS with tcb shadow passwords by checking
+that the file opened was really an ordinary file.
+
+fixed a bug in the implementation of atomic ops that could have
+allowed the compiler to incorrectly reorder them (in practice, gcc
+with the default settings on i386 was not reordering them).
+
+greatly improved conformance to the C and POSIX standards regarding
+what the standard header files make visible. _POSIX_C_SOURCE is now
+needed to get POSIX functions in standard C headers, and _XOPEN_SOURCE
+or _GNU_SOURCE are required to get XSI interfaces or GNU extensions,
+respectively.
+
+many internal improvements have been made to the syscall-related code
+in preparation for porting to x86_64 and other archs.
+
+
+
+0.6.0 - x86_64 port, various important bugs fixed
+
+new x86_64 (amd64) architecture port, contributed by Nicholas J. Kain,
+along with PORTING guide. source tree layout and build system have
+been improved to accommodate further ports.
+
+various bugs that were introduced while making the headers respect C
+and POSIX namespace standards have been fixed. conformance to the
+standards has been improved.
+
+fixed an inefficiency in qsort that triggered a bug (occasionaly
+internal compiler error) in some versions of gcc.
+
+fixed a major bug in the printf %n specifier that prevented it from
+working and caused memory corruption.
+
+
+
+0.7.0 - major improvements to posix conformance and completeness
+
+implemented posix shared memory and semaphore interfaces.
+
+implemented all remaining required pthread and clock interfaces.
+
+major fixes to signal semantics.
+
+greatly improved temporary file name generation for safety against
+denial of service due to intentional name collisions.
+
+added syscall wrappers for the linux inotify interface.
+
+malloc(0) now returns a non-null pointer.
+
+fixed printf %n specifier (again), pthread_once (it was always
+hanging), and non-default-type mutex behavior.
+
+added ucontext/sigcontext support in headers to facilitate building
+libgcc with dwarf2 unwind support, and possibly other low-level tools.
+
+improved musl-gcc compiler wrapper.
+
+implemented many small missing functions here and there, minor header
+fixes, etc.
+
+
+
+0.7.1 - improvements to completeness, bug fixes
+
+implemented flockfile, wprintf, and robust mutex functions.
+
+fixed stack corruption bug in times(), minor header bugs, and some
+error return value bugs in thread interfaces.
+
+
+
+0.7.5 - new features, major optimization, and robustness
+
+implemented POSIX timers.
+
+optimized and simplified many thread-related functions.
+
+eliminated resource leak races in thread cancellation. (almost all
+existing implementations, including glibc, have these leaks.)
+
+overhauled stdio implementation to take advantage of readv/writev for
+reduced syscall load, and improved stdio's handling of error status.
+
+added syscall header and interface for applications to use and
+greatly simplified internal system for making syscalls.
+
+strangthened tmpnam/tempnam/tmpfile filename generation and made the
+straight C functions not depend on POSIX symbols.
+
+fixed pthread cancellation ABI on i386 to match the LSB/glibc ABI
+
+better double-free handling in malloc
+
+various minor bug fixes
+
+
+
+0.7.6 - major bug fixes
+
+fixed rare but serious under-allocation bug in malloc.
+
+fixed signedness bug in strchr that prevented finding high bytes.
+
+fixed serious parsing bugs in strtold.
+
+fixed statvfs syscall (it was always failing with EINVAL).
+
+fixed race condition in set*id() functions with threads (possible
+deadlock). further audit still needed though.
+
+fseek no longer sets the stream error flag on failed seeks (this was
+wrong and broke some programs, notably GNU m4).
+
+nl_langinfo is no longer a dummy function. (the functionality was
+previously implemented but accidentally left unused).
+
+various small fixes have been made to the implementations and
+prototypes for nonstandard and obsolete functions
+
+
+
+0.7.7 - more bug fixes and program-compatibility improvements
+
+fixed floating point formatting and rounding bugs in printf.
+
+fixed broken %N$ positional argument specifiers in printf.
+
+fixed misaligned read/overread bug in strchr which could lead to
+crashes scanning tiny strings at the end of a page when the next page
+is not readable, or on archs (not yet supported) that forbid
+misaligned reads.
+
+fixed breakage of statvfs on x86_64
+
+fixed crash in getmntent_r
+
+fixed bug in POSIX timers created with NULL sigevent argument
+
+improved semaphore performance, and sem_wait is now interruptable by
+signals, as required by POSIX.
+
+added many compatibility and system-level interfaces, increasing the
+proportion of busybox that works with musl.
+
+
+
+0.7.8 - more bug fixes and compatibility improvements
+
+fixed problems with ipv6 dns and address printing code that made ipv6
+support practically unusable, and some other getaddrinfo bugs.
+
+fixed broken sendmsg/recvmsg functions on x86_64 (caused by incorrect
+msghdr structure).
+
+fixed broken sigsetjmp asm on x86_64.
+
+worked around a problem with input buffering on terminals reblocking
+after getting a blank line, due to a bug in the linux readv syscall.
+
+various improvements to the "rsyscall" system used to implement
+threaded setuid, setgid, etc.
+
+exiting/cancelling the a timer handler thread no longer kills the
+timer.
+
+fixed incorrect trailing zeros on some %g conversions in printf.
+
+fixed buggy byte-swapping functions and moved them to inlines in
+byteswap.h.
+
+many small improvements to header/application compatibility, support
+for nonstandard macros, etc.
+
+
+
+0.7.9 release notes
+
+new pthread cancellation implementation:
+- safe against resource-leak/side-effect-leak race conditions
+- safe against interruption by signal handlers
+- reduced bloat in all cancellable functions
+- reduced bloat for blocking cancellation
+
+new interfaces implemented:
+- realpath (limited functionality)
+- wordexp (limited functionality)
+- flock (nonstandard)
+- forkpty (nonstandard)
+- posix_fadvise
+- posix_fallocate
+
+general bug fixes:
+- syslog function failure to communicate with syslogd
+- bug in siginfo_t definition if wait.h was included before signal.h
+- incorrect struct definitions for most of sysv ipc
+- pthread_exit/cancel on timer handler wrongly destroying the timer
+- linux dup2 ebusy workaround
+- obscure issues in non-threaded programs using some pthread functions
+- getopt_long allowed mismatch in last char of option name
+- incorrect parsing of obscure ip address forms
+- initgroups not working reliably (uninitialized var)
+- shadow pass treating empty expiry field as pass-expired-in-1970
+- bogus longjmp if pthread_exit was called from cancellation handlers
+
+x86_64-specific bug fixes:
+- fcntl file locking
+- thread stack alignment
+- broken select timeouts due to incorrect timeval definition
+
+
+
+0.7.10 release notes
+
+new features:
+- ipv6 numeric string parsing
+- eventfd syscall wrappers
+
+optimizations:
+- new qsort implementation using the smoothsort algorithm
+- much smaller/faster sigset_t handling functions
+- lowered spin count before futex wait in synchronization functions
+
+general bug fixes:
+- incorrect floating point round-to-even behavior in printf
+- major bugs in pthread barrier implementation
+- off-by-one error in scanf %n results
+- scanf failure to report EOF when scanning for literal text
+- minor missing/incorrect prototype issues
+- dependency on undefined call order in fclose
+
+compiler issue workarounds:
+- incorrect inlining of variadic functions on recent gcc versions
+- pcc preprocessor bug with recursive macro expansion
+
+
+
+0.7.11 release notes
+
+new features:
+- integrated dynamic linker
+- dynamic loading (dlopen/dlsym) (for dynamic-linked programs only)
+- XSI search.h API
+- POSIX message queues
+- POSIX spawn interfaces
+- BSD pseudo-random number generator API (random/srandom/initstate/etc.)
+- floating point environment (limited usefulness due to gcc bugs)
+
+general bug fixes:
+- possible crashes with wordexp due to uninitialized variable
+- race condition in pthread_kill (also present and unfixed in glibc/nptl)
+- pthread exit destructors called too late
+- dangerous unbounded vla in glob
+- brk/sbrk legacy functions mismatching legacy semantics
+- wcsncpy dest buffer overflow
+- strncat and wcsncat possible overflows due to double-termination
+
+
+
+0.7.12 release notes
+
+new features:
+- support for textrels in shared objects
+- rpath support in dynamic linker
+- stdio_ext.h functions (for better gnu software compatibility)
+
+bug fixes:
+- some compilers miscompiling dlopen due to misuse of longjmp
+- safe handling of invalid long-double bit patterns (affects printf)
+- workaround for bugs in linux mprotect syscall
+- thread-safety for random() functions
+- various minor issues
+
+
+
+0.8.0 release notes
+
+new features:
+- chinese and japanese legacy charset support in iconv
+- zero-syscall clock_gettime support (dynamic-linked x86_64 only)
+- futex-based locking for stdio (previously used spinlocks)
+- LD_PRELOAD and RTLD_NEXT support in dynamic linker
+- strptime (mostly working but incomplete)
+- posix aio (mostly working but not entirely conformant)
+- memory streams (fmemopen, open_memstream, ...)
+- stub/dummy implementations for various useless legacy functions
+- if_nameindex
+
+security hardening:
+- setuid, etc. should not longer be able to "partially fail" with threads
+- ensure suid programs start with fd 0,1,2 open
+- improved openpty/forkpty failure checks
+
+threads/synchronization bug fixes:
+- dangerous spurious wakeup in pthread_join lead to early return
+- race condition enabling async cancellation (delayed/lost cancellation)
+- destruction/unmapping race conditions in semaphores, mutexes, rwlocks
+- recursive rwlock_rdlock deadlock when a writer is waiting
+- race condition in sigqueue with fork
+- timer expiration thread exit wasn't running dtors
+- timer threads weren't blocking signals
+- close was wrongly cancellable after succeeding on some devices
+- robust mutex list was not reset on fork
+
+general bug fixes:
+- incorrect logic in fread (spurious blocking; crash on write-only files)
+- many corner cases and overflow cases for strtol-family functions
+- various printf integer formatting issues with flags/width/precision
+- incorrect iconv return value on failure
+- broken FD_* macros on 64-bit targets
+- clock function returning wrong value (real time not cpu time)
+- siglongjmp signal mask clobbering (off-by-one pointer error)
+- dynamic linker weak symbol resolution issues
+- fdopendir failure to set errno
+- various minor header fixes
+
+
+
+0.8.1 release notes
+
+bug fixes:
+- mismatching prototypes caused build failure on 64-bit
+- other minor prototype errors in the headers have been fixed
+- various other small omissions fixed
+
+
+
+0.8.2 release notes
+
+new features:
+- ptrace syscall support
+
+bug fixes:
+- const error (only a warning with many compilers) in lio_listio
+- minor portability fixes aimed at supporting new arch targets
+
+
+
+0.8.3 release notes
+
+new features:
+- arm port (experimental)
+- better musl-gcc wrapper script for building against musl
+- added clone system call
+
+bug fixes:
+- numerous header file typos, copy/paste errors, omissions
+- statfs and statvfs ABI are now LSB-conformant (and actually work)
+
+
+
+0.8.4 release notes
+
+new features: 
+- arm dynamic linker support
+- process-shared pthread barriers now work
+- efficient futex-requeue-based cond var broadcast
+- more optional cancellation points are now cancellable
+- printf accepts null pointers with %s, prints as "(null)"
+- recursive mutexes are now fully reentrant
+- __cxa_atexit support
+- real vfork
+- dynamic linker now gold-compatible
+- prlimit syscall
+- support for large limits with setrlimit/getrlimit (even on 32-bit)
+- glob now supports GLOB_PERIOD option (GNU extension)
+
+bug fixes:
+- many serious issues in condition variables
+- rwlock failure-to-wake deadlock issues
+- various small header files bugs/omissions
+- wrong failure return for pthread_create
+- path handling issues on execvp
+- lock count corruption with robust recursive mutexes on owner death
+- integer overflows in atoi, etc. reading most-negative value
+- spurious mremaps on every realloc of large memory chunks
+- pthread cancellation failure in single-threaded programs
+
+security:
+- avoid fd_set overflow in dns lookups
+
+
+
+0.8.5 release notes
+
+new features:
+- stdio operations are now cancellable (only when low-level io happens)
+- global ctor/dtor support in main program start code and shared libs
+- dynamic linker support for PIE executables (but missing startup code)
+- vfork support on x86_64
+- complete set of locale_t functions (all ignore the locale argument)
+- provide define float_t and double_t in math.h
+- lighter/faster cancellation cleanup handler register/unregister
+
+bug fixes:
+- gcc wrapper now supports -shared, -nostdlib, -nostartfiles
+- removed one wrongly-classified character from iswspace set (zwsp)
+- fixed crashes in dns lookup on some errors, e.g. resolv.conf missing
+- "make install" no longer tries to build shared libc if disabled
+- ptrace argument handling bugs fixed
+- work around visibility-hidden bugs in gcc 3.x
+- fix thread-pointer-loss issue when it's initialized in signal handlers
+- various minor typo/misc fixes in headers
+
+compatibility:
+- glob behaves more like traditional implementations w.r.t. GLOB_MARK
+- added legacy futimes, lutimes functions
+- more compatibility macros in sys/param.h (nonstandard header)
+- setfs[ug]id syscall wrappers (linux specific)
+- fgetpwent function (nonstandard)
+- utmp.h matches traditional version more closely
+- caddr_t now matches glibc type (void * instead of long)
+- dummy (always-fail) dlopen and dlsym functions for static linked programs
+- [efg]cvt functions (previously posix, removed from standard)
+- get_current_dir_name function (nonstandard)
+
+
+
+0.8.6 release notes
+
+bug fixes:
+- fix crash in dns lookups for all static-linked, non-threaded programs
+
+
+
+0.8.7 release notes
+
+new features:
+- c++ support with g++'s libstdc++
+- c99 math library (float, long double, complex, etc.)
+- numerous wchar_t functions
+- a64l, l64a functions
+- getdate function
+
+compatibility:
+- c89 compatibility in math.h
+- syscall.h alias for sys/syscall.h
+- memory.h alias for string.h
+- getcwd supports null buffer argument (auto-allocation)
+
+bug fixes:
+- major fenv (floating point environment) fixes and optimizations
+- strptime mishandling of day/month names
+- strtoull wrongly rejecting the highest 16 possible values as overflow
+- math.h constant expression fixes for INFINITY/NAN/etc.
+- scanf mishandling of "0" with "%x"
+
+
+
+0.8.8 release notes
+
+new feature:
+- major math correctness and performance improvements
+- many math functions implemented in asm for i386
+- some math functions (mostly long double) in asm for x86_64
+- new floating point parser/converter with correct rounding
+- implement wcstod, wcstof, and wcstold
+- new scanf implementation - cleaner, faster, more correct
+- minimal/incomplete strfmon implementation
+
+compatibility:
+- header fixes for c++
+- regex code resync with TRE; support common regex extensions
+- support for compiling apps with gcc's -funsigned-char
+- sysconf now returns dynamic limits for open files, processes
+- give dlerror proper error status stickiness
+- make alloca work even with -fno-builtin
+
+critical security fixes:
+- stack-based buffer overflow in fprintf on unbuffered files
+
+other bug fixes:
+- rare gcc register allocation (miscompilation) bug in syscall wrappers
+- printf was rejecting the valid (but redundant) %lf format specifier
+- fixed big data bloat (missing const) in math functions
+- many math fixes related to floating point exceptions and rounding
+- corrected DECIMAL_DIG definitions
+- tgammal was wrongly setting global signgam
+- crash in wordfree with uninitialized we_offs
+- fix wordexp not null-initializing the we_offs initial slots
+
+
+
+0.8.9 release notes
+
+bug fixes:
+- major breakage in strtol and family: failure to accept leading spaces
+- incorrect name for MATH_ERREXCEPT in math.h
+
+compatibility:
+- prototypes for a few additional nonstandard functions
+
+
+
+0.8.10 release notes
+
+new features:
+- correct over/underflow detection (ERANGE setting) for strtod
+- new musl-gcc wrapper, specfile based, faster and more robust
+- meaningful return strings for dlerror
+- new iswalpha, iswpunct, and wcwidth; sync'd to Unicode 6.1
+- towupper/towlower sync'd with Unicode 6.1
+- new futex-based libc-internal locks instead of spinlocks
+- experimental stack protector support (minimal; no random canary)
+- experimental gdb shared library tracking support
+
+compatibility:
+- getusershell family functions
+- getresuid and getresgid syscall wrappers
+- byte swapping macros in endian.h
+- getdtablesize was wrongly declared in unistd.h for _XOPEN_SOURCE
+
+bug fixes:
+- iconv_open wrongly rejecting most dest charsets (broken in 0.8.0)
+- sysconf failure when correct value is -1 (broken in 0.8.8)
+- scanf and strtod family functions overreading past NAN (4 bytes vs 3)
+- scanf and strtod wrongly treating "0.00000000001", etc. as 0
+- many bugs in towupper/towlower (never seriously tested before)
+- int8_t definition was wrong when gcc -funsigned-char was used
+
+
+
+0.9.0 release notes
+
+license change: MIT
+
+new features:
+- configure script, improved build system
+- full stack protector support
+- PIE support on x86 and x86_64
+- new O(1) space, O(nm) time implementation of fnmatch
+- improved support for sse2 floating point mode on x86
+
+compatibility:
+- added linux unshare syscall
+- exp10/pow10 function
+- sqrtl support on arm (previously missing)
+- removed minimal linux/*.h headers that could conflict with real ones
+- support for _LARGEFILE64_SOURCE (mapped to standard fcns with #define)
+- better c89 compatibility in headers
+- stub versions of sched_* functions (previously missing)
+- pthread stacks no longer executable (compat with hardened kernels)
+- new ar.h and lastlog.h (legacy junk)
+- various other header improvements
+
+optimization:
+- additional x86_64 math asm
+- better formula for acos use in i386 asm
+
+bug fixes:
+- large (up to a few %) errors in strtod for certain values due to bug
+- mbsnrtowcs and wcsnrtombs were completely broken (bad exit logic)
+- wide printf %.0s could fail due to uninitialized variable
+- missing dlerror strings for dlsym in some cases
+
+
+
+0.9.1 release notes
+
+new features:
+- dynamic linker can be used as a program to explicitly load/run executables
+- ldd command, usable by making a symlink to the dynamic linker named ldd
+
+bug fixes:
+- major bugs in POSIX BRE parsing inherited from TRE regex code
+- character matching bug in regex on ARM: WCHAR_MAX was assumed to be signed
+- various obscure fixes related to signals and pthread cancellation
+- remquot subnormal remainder bug
+- buggy macros in (nonstandard) sys/param.h
+- major bug in pthread barriers on x86_64 (out of bounds write)
+- utimes (legacy) function was making wrong syscall (utime instead of utimes)
+- avoid using "old" syscalls that don't exist on arm eabi linux
+- broken strrchr(str, 0)
+- broken mbsinit(0)
+- broken wcsncmp
+- syntax error in nextafter macro in tgmath.h
+- missing support for -pie in musl-gcc wrapper
+- abort could wrongly fail to terminate the program in some cases
+
+compatibility:
+- increase default thread stack size to 80k
+- support _BSD_SOURCE feature test macro
+- support _LARGEFILE64_SOURCE feature test macro (merely exposes alt names)
+- lots of legacy-compatibility improvements in headers
+- various minor GNU extension functions
+- sysconf reporting number of available CPUs/cores
+- various LSB/glibc ABI interfaces aimed at compatibility with some binaries
+- use fistpll asm mnemonic instead of fistpq for compat with clang
+
+
+
+0.9.2 release notes
+
+bug fixes:
+- pointer overflow in printf (crash on 32bit userspace, 64bit kernel)
+- printf %ls over-read bug
+- strtod failure to read -0x as negative zero
+- flush stdio after dtors, not before
+- wrong file position for buffered input streams on exit
+- popen was broken when stdin/out were already closed
+- broken wcwidth tables (missing many characters)
+- fwrite: wrong return value of partial/failed write
+- broken utf-16 conversions
+- bad buffer length check in getlogin_r
+- bad perror("") behavior; did not match perror(0)
+- broken sysinfo syscall/structure
+- stdint.h const macro signedness bugs
+- broken include guards in some headers
+- bogus localeconv values
+- cancellation-safety for popen and pclose
+- fma corner cases wrong on i386
+- fcntl F_GETOWN errno missing on failure.
+- char signedness bug in dynamic linker broke dlopen on arm
+- mprotect failure in dynamic linker caused crash instead of error
+
+build system:
+- configure check to work around hacked-up gcc versions
+- test for old binutils that can't support musl dynamic linker
+
+compatibility:
+- make _GNU_SOURCE imply _LARGEFILE64_SOURCE
+- syscall wrapper for lots of nonstandard and/or legacy linux syscalls
+- versionsort stub
+- timegm function (inverse of gmtime)
+- various minor header tweaks
+- make __freading/__fwriting semantics match traditional ones
+- added gnulib-compatibility stdio interfaces
+- added pthread_attr_setstack interface
+- make strerror_r return partial string when buffer is too small
+- duplocale should accept LC_GLOBAL_LOCALE
+- align ptsname_r to upcoming posix requirements
+- support invalid ld80 bit patterns as extra nans.
+
+
+
+0.9.3 release notes
+
+new features:
+- mips (32-bit, o32 abi) port, currently static-linked only
+- newly overhauled crypt implementation
+- improved library pathname info for debugger from the dynamic linker
+- getaddrinfo (and getservbyname) now support /etc/services lookups
+- pipe2 syscall wrapper
+- splice and vmsplice syscall wrappers
+- syscall wrappers for extended attribute interfaces
+- ioperm/iopl syscall wrappers on archs that support these operations
+
+bug fixes:
+- dlsym RTLD_NEXT library search order was wrong
+- multiple dlopen pathname and library name handling errors
+- potential race condition in detached thread exit
+- broken internal-lock-handling code not updated for futex-based __lock
+- sem_trywait spurious EAGAIN errors arising from CAS failures
+- workaround kernel bug in cmsghdr size_t vs socklen_t issue (64-bit)
+- getservby* crash on null protocol argument
+- logic error skipping failed interfaces in if_nameindex
+- various minor header/declaration related issues
+
+arm-specific bug fixes:
+- broken crti/crtn startup code when gcc crtbegin/end files are linked
+- sigsetjmp tail call optimization failure broke the function
+- incorrect little-endian assumptions in atomic.h functions
+- use of blx instruction in asm (not supported on pre-v5 arm)
+
+build system:
+- only use expensive -ffloat-store cflag on archs/compilers that need it
+- make musl-gcc wrapper support -lgcc (mainly for self-hosting)
+
+
+
+0.9.4 release notes
+
+new features:
+- blowfish crypt
+- dynamic linking on mips
+- arm hard float support
+- BSD fgetln function in stdio
+- minor header improvements for compatibility
+- support for CROSS_COMPILE variable to configure
+- legacy significand function
+- better support for SUSv3-targeted programs
+
+performance:
+- assembly (string ops based) memcpy for i386 and x86_64
+- reduce printf overhead
+
+bug fixes:
+- failure of strtod, etc. to process extremely long strings correctly
+- read overrun in wcsstr for short needles
+- various major mips issues that prevented most software from working
+- erroneous floating point exception behavior in i386/x86_64 exp asm
+- crashes on null arguments to legacy err.h functions
+- various header file/type issues
+- extremely rare/obscure race condition with robust mutexes
+- crypt now never returns null (most programs don't check, then crash)
+- missing xattr remove functions
+
+
+
+0.9.5 release notes
+
+compatibility and headers:
+- POSIX+XSI+BSD features enabled by default with no macros defined
+- most programs can now be built without adding -D_GNU_SOURCE
+- added C99 restrict keyword where required in all prototypes
+- greater C89 compatibility
+- cleaner, more-compatible public syscall.h
+- many other header fixes
+- support for compiling musl with clang/llvm
+
+new features:
+- sha 256/512 password hash functions in crypt
+- GNU hash support in dynamic linker
+- partial C11 coverage
+- dladdr function added
+- dynamic linker reports all errors instead of exiting on first error
+- syscall wrappers added for most remaining linux syscalls
+- provide POSIX O_SEARCH open mode using linux O_PATH
+
+bug fixes:
+- most atexit functions were being skipped when exiting
+- some BSD functions were not being exposed under _BSD_SOURCE
+- issues loading ssp-protected DSO into non-ssp program with dlopen
+
+debloating:
+- eliminate .eh_frame (10-15% loaded size bloat)
+- optimal inline syscall asm for ARM and MIPS
+- no longer force -O3 for shared libs
+
+
+
+0.9.6 release notes
+
+bug fixes:
+- serious breakage in definition of O_ACCMODE mask (missing a bit)
+
+new features:
+- O_EXEC open mode
+- md5 crypt hash function
+
+
+
+0.9.7 release notes
+
+new features:
+- thread-local storage (__thread/_Thread_local)
+- microblaze port
+- getopt option parsing reset support
+- vsyscall (sysenter, etc.) support on i386 (faster syscalls)
+- memmem function (GNU extension)
+- mips fenv support
+- accept "nan(n-char-sequence)" in strtod/scanf family functions
+- configure now supports compiling with pcc
+
+quality and correctness improvements:
+- close-on-exec flag for all library-internal file descriptors
+- cancellation-safety and corner-case overhaul in shm_open/sem_open
+- close EINTR vs EINPROGRESS issue
+- mark binaries as not requiring executable stack
+- better gdb compatibility in dynamic linker
+- support recursive dlopen (dlopen called from constructors)
+- posix_spawn/system/popen no longer momentarily double commit charge
+- all stdio functions wait for locks
+
+bug fixes:
+- broken sysvipc *ctl functions on 64-bit archs
+- broken shmdt on some archs
+- getaddrinfo failure with port "0"
+- dirname handling of trailing slash
+- vfork race in posix_spawn
+
+
+
+0.9.8 release notes
+
+new features:
+- powerpc port
+- dl_iterate_phdr interface
+- added mips-specific syscalls
+- thread priority scheduling
+- C11 CMPLX macro in complex.h
+- x86 port io functions in sys/io.h
+
+compatibility:
+- improved headers for trace/debugging/machine-access
+- stub functions for unsupported thread-related functionality
+
+bug fixes:
+- numerous math bugs (mostly exception flags and excess-precision issues)
+- register clobber error in i386 vsyscall asm (did not affect most callers)
+- various incorrect definitions in mips headers
+- broken dlsym asm on mips
+- empty prefix handling in configure script (--prefix="")
+- ldso search path logic issues
+- lock handling for stdio memory streams at exit time
+- invalid SO_REUSEPORT definition in socket.h (not supported by Linux)
+- broken redirection attempt to /dev/null in configure script
+
+
+
+0.9.9 release notes
+
+new features:
+- tgamma implementation (no longer lgamma wrapper with low precision)
+- various gnu extensions: sigandset, sigorset, etc.
+- futimesat function (obsolete)
+- various linux syscalls: arch_prctl, personality, etc.
+
+optimizations:
+- hyperbolic, inverse hyperbolic, and inverse trig, bessel functions
+- is* comparison macros in math.h now expand inline properly
+
+library bugs fixed:
+- calling getenv from shared library ctors was broken
+- invalid read in mmap-serviced aligned_alloc/memalign (possible crash)
+- wrong errno result in fallback path of pipe2 
+- various math functions raising spurious exceptions
+- mmap errno value on invalid offsets
+- backwards alignment logic in strlcpy
+- integer overflows in bessel functions
+- large (up to 60ulp) error in erfcf
+- dlsym/dlclose crashing on invalid library handles
+- failure to handle arch variations for cloexec/nonblock flags
+- lio_listio wrong return value for LIO_WAIT mode
+- dladdr failure to resolve PLT addresses
+- time_t/struct tm conversion off-by-one-day in december
+- malloc corruption on nonstandard kernels with non-page-aligned brk
+
+arch-specific bugs fixed:
+- arm ctors/dtors were not working with recent gcc versions
+- arm and mips setjmp/longjmp wrongly saved/restored fenv state
+- loss of precision in i386/x86_64 expl
+
+header bugs fixed:
+- incorrect PRI/SCN macros in inttypes.h for some types
+- arm sys/user.h regressions
+- failure of offsetof() to be an integer constant expression
+- tgmath return value type problems
+
+header compatibility improvements:
+- _GNU_SOURCE now enables everything; _ALL_SOURCE also works
+- scsi/scsi.h and scsi/sg.h are now provided
+- additional MAP_* flags for mmap
+- additional F_* commands and flags for fcntl
+- additional socket option, IPPROTO_* values, and multicase macros
+- thread-related waitpid flags
+- EHWPOISON added to errno.h
+- additional macros for mount, swap, and reboot operations
+- expose additional link.h structures
+- always ensure sizeof(NULL)==sizeof(void *), even in c++
+- additional flags for poll, epoll, inotify, timerfd, timex, dlfcn
+- register names in signal.h/ucontext.h for x86
+- ipc.h ipc_perm nonstandard struct field name compatibility improve
+
+
+
+0.9.10 release notes
+
+new features:
+- getifaddrs 
+- pthread_getattr_np (widely used by garbage collectors)
+- mkostemps, mkostemp, mkstemps functions (mkostemp is future-POSIX)
+- strcasestr and strverscmp (previously stubs)
+
+improvements:
+- major performance improvements in mbtowc
+- avoid filling caller-provided thread stacks with large TLS
+- debloat unnecessary static buffers
+- robust posix_spawn based on CLONE_VM instead of vfork
+- new system() and popen() based on posix_spawn
+- better strerror strings
+- further emulation of atomic close-on-exec/nonblock options for old kernels
+- provide macro constants for new-ish kernel features
+
+compatibility:
+- several nonstandard but widely-available pwd/grp/shadow functions
+- program_invocation_[short_]name
+- re-added useconds_t type used by some programs
+- some legacy arpa headers
+- dn_skipname function (legacy resolver API)
+- additional ABI aliases for supporting glibc-linked libraries/binaries
+
+general bugs fixed:
+- stale locks and bogus munmap call when pthread_create fails
+- uninitialized argument to munmap when dynlink load_library fails
+- incorrect error returns in gethostby*_r
+- memory leak in gethostbyname family
+- blank ai_canonname in getaddrinfo for non-CNAME records
+- undefined HZ macro in scsi/sg.h
+- wrong return value for wmemmove on forward-copy
+- namespace conformance in strings.h
+- various utmp.h bugs
+- unnecessary DT_SONAME in libc.so caused problems on some systems
+- multiple bugs in syslog, some possibly dangerous
+- non-functional setpriority function
+- slight mishandling of 0xf5 byte in UTF-8 decoder
+- misaligned memory accesses in mbsrtowcs
+
+arch-specific bugs fixed:
+- crash in shared library loading on arm
+- missing __aeabi_atexit needed by arm eabi
+- wrong float_t definition on x86_64
+- various low-impact type size/alignment mismatches in some headers
+- epoll struct alignment wrong on non-x86[_64] archs
+- broken pipe2 fallback code on mips with old kernels
+
+
+
+0.9.11 release notes
+
+new features:
+- %m allocation modifier for scanf
+- week number and ISO week-based-year functionality in strftime
+- per-process and per-thread cputime clocks
+- ethernet address conversion interfaces
+- legacy classful ipv4 network address interfaces
+- minimal dlinfo function (nonstandard)
+
+other improvements:
+- dynamic linker path file can now use newlines to separate paths
+- math optimizations for archs with extended precision (i386)
+- musl-gcc wrapper now exposes gcc's intrinsic headers
+- quality of rand and rand_r pseudo-random sequences
+- support for large device minor numbers (greater than 8 bits)
+- various header conformance and compatibility fixes
+
+directly user-visible bugs fixed:
+- scanf losing characters on unbuffered streams and fmemopen streams
+- failure of mbsrtowcs to record stop position when dest is full
+- failure of iconv to convert to legacy codepages
+- non-working pthread_[sg]etschedparam functions (wrong syscall arguments)
+
+other potentially-serious bugs fixed:
+- resource leaks in sem_open
+- various bugs in thread exit synchronization
+- invalid access in aio notification after aiocb free/reuse
+- synchronization in dynamic linker when new thread dlopens during ctors
+- lack of error handling for failure to read dynamic linker path file
+- creation by mmap or shmget of objects larger than PTRDIFF_MAX
+
+minor conformance bugs fixed:
+- overflow handling for the clock function
+- workaround for incorrect exceptions in fma due to compiler bugs
+- workaround wrong kernel type for sem_nsems field in struct semid_ds
+
+arch-specific bugs fixed:
+- x86_64 sigsetjmp clobbered the signal mask rather than saving it
+- misaligned stack when calling ctors/dtors (crashing on x86_64)
+
+
+
+0.9.12 release notes
+
+new features:
+- zoneinfo time zone support
+- PIE support on all supported archs
+- named sub-archs for endian and float ABI variants
+- improved support for non-root installs of the dynamic linker
+- ability to selectively build only performance-critical modules with -O3
+- simple buffer overflow detection in free/realloc
+- inet_ntop now presents v4-mapped addresses in ::ffff:a.b.c.d form
+- ldd now reports libc and the dynamic linker in its output
+
+compatibility:
+- support for new init/fini array (needed for ctors/dtors on newer gcc)
+- C++ ABI fully matches glibc/LSB, at least on x86
+- many added ABI compatibility symbols for using glibc-linked libs
+- support for STB_GNU_UNIQUE symbol bindings (found in some C++ libs)
+- macros/types for new Linux kernel features in headers
+
+bugs fixed:
+- crashes in scanf on literal mismatches (regression from adding %m)
+- dl_iterate_phdr was passing invalid phdr pointers to its callback
+- getaddrinfo with null host and AF_UNSPEC was failing to report IPv6
+- integer overflows in date/time conversion code
+- misinterpretation of pre-1930s dates as post-2038 on 32-bit archs
+- make install failed to install bits headers if make was not run first
+- shm_open was wrongly cancellable
+- low- or no-impact heap corruption in memalign
+- explicitly running the dynamic linker on PIE programs did not work
+- missing macros and sysconf for some supported POSIX option groups
+- missing close-on-exec flags for several internal fd uses
+
+arch-specific bugs:
+- wrong SIG_ATOMIC_MIN/MAX macros on x86_64
+- erfcl was missing on archs where long double is same as double
+- broken dynamic-model TLS in static-linked arm/mips/powerpc programs
+
+
+
+0.9.13 release notes
+
+new features:
+- iconv support for EUC-KR and Big5 (including HKSCS) encodings
+- field widths (POSIX 2008 feature) in strftime
+- recursive rpath and $ORIGIN support in dynamic linker
+- cpu affinity interfaces
+- support for armhf (hardfloat) floating point environment (fenv)
+- support for SSE fenv on i386 (for apps using -mfpmath=sse -msse2)
+- strftime %s format (seconds since the epoch, future POSIX requirement)
+- configure script now saves its command line as a comment in config.mak
+- legacy functions valloc and euidaccess
+
+performance:
+- optimized asm memcpy for arm
+- optimized asm memset for i386 and x86_64
+- optimized C versions of memcpy and memset for all archs
+- eliminated major spurious syscalls from posix_spawn
+- some math asm for armhf (hardfloat)
+
+workarounds for:
+- qemu-user's rt_sigaction syscall does not allow old to alias new
+- qemu-user's madvise always succeeds (broke pthread_getattr_np)
+- passing PT_INTERP to dlopen attempted to double-load libc
+- gcc 4.8.x generating self-referential (infinite recursion) memcpy/memset
+- linux's lack of support for fchdir, fchmod, fchown, fstat on O_PATH fds
+
+bugs fixed:
+- failure to honor flags for fchmodat and faccessat (linux syscall api flaws)
+- SIGEV_THREAD timer id corruption and race condition issues
+- timer thread TLS incorrectly keeping values from previous expiry run
+- ecvt/fcvt decimal position off-by-one
+- in symbol-versioned libs, symbol resolved to oldest instead of newest
+- posix_spawn not correctly reporting errno from exec failure
+- "make install" was not atomic (overwrote files rather than replacing)
+- integer overflows in strftime
+- unset/empty TZ variable was mishandled
+- strftime could crash if the struct tm did not have valid tm_zone field
+- failure of fenv functions to handle invalid arguments (required by ISO C)
+- failure of some math functions (C and i386 asm) to raise underflow flag
+- broken dn_expand function (previously not used internally)
+- race conditions with signals during fork
+- incorrect access check in mktemp (obsolete function)
+- unnecessary arbitrary limits on size of program headers in dynamic loader
+- text formatting bugs in output of err.h functions
+
+arch-specific bugs:
+- fesetenv(FE_DFL_ENV) crashed on i386
+- breakage of arm crt code when libc is compiled as thumb
+- arm/armhf (hardfloat) misidentified by configure
+- ambiguity of wait (exit status) macros on mips with signal number 127
+- wrong value of _NSIG and SIGRTMAX on mips
+
+
+
+0.9.14 release notes
+
+bugs fixed:
+- failure to properly install dynamic linker with DESTDIR set (symlink wrong)
+- rare deadlock in libc-internal locking routines
+- dynamic linker used fallback paths wrongly on (possibly transient) errors
+- popen broken when stdin or stdout was already closed in parent
+- deadlock/memory-corruption in multithreaded set*id and setrlimit functions
+- realpath failed when file was not readable
+- readpath mistakenly had cancellation points in it
+- crashes in scanf with invalid %m conversion specifiers
+- misclassificiation of some invalid ld80 float representation in fpclassify
+- various overflow and underflow flag issues in math functions
+- domain handling errors for acoshf and acoshl
+- wrong values for some sysconf properties
+- lack of proper memory barriers on arm
+
+mips-specific bugs:
+- broken sysv ipc structures
+- multiple stack-related bugs in clone, leading to crashes in parent or child
+- overflow writing sigset_t in multithreaded set*id and setrlimit functions
+
+other improvements:
+- size and performance improvements to various math functions
+- wait.h as a compatibility alias for sys/wait.h
+- various header improvements
+- support for runtime-variable page size on archs that need it (mainly mips)
+
+
+
+0.9.15 release notes
+
+new features:
+- support for mixing IPv4 and v6 nameserver addresses in resolv.conf
+- RFC 3678 multicast structures/macros in netinet/in.h
+- putspent and fgetspent functions (shadow password API)
+- timef function (obsolete, removed in POSIX 2008)
+- fanotify syscalls (Linux-specific feature)
+- semtimedop syscall (Linux-specific sysvipc extension)
+- quotactl syscall and header (filesystem quotas support)
+- drem and finite functions (obsolete BSD functions)
+- getloadavg function (non-standard)
+- herror function (non-standard and obsolete)
+- libc.so now stores and prints its version information
+- expose constants for new Linux features including O_TMPFILE
+- implement FNM_LEADING_DIR option to fnmatch (GNU extension)
+- posix_close function (accepted for inclusion in next POSIX issue)
+
+bugs fixed:
+- buffer overflow in mbsrtowcs
+- clobbering of gr_name in getgrnam_r and getgrgid_r
+- execle ignoring the environment argument
+- setenv crash on malloc failure
+- out-of-bounds access in fnmatch with FNM_PATHNAME and certain patterns
+- failure of malloc to set errno when failing to extend heap
+- incorrect errno value from getcwd with zero size
+- spurious failure in faccessat with AT_EACCESS flag with suid/sgid programs
+- several fd leaks due to missing close-on-exec flag
+- misspellings/typos in macro names in several headers
+- incorrect failure return value in inet_pton
+- various numeric ip address parsing and validation fixes
+- namespace conformance issues in several headers
+- minor header issues
+- zombie processes left by faccessat with AT_EACCESS
+- timezone file parser failing/crashing on 64-bit archs
+- hang in localtime with near-overflowing time_t values on 64-bit archs
+- timezone path search was only trying first path
+- incorrect handling of excessive-length TZ environment strings
+- timezone file loading was wrongly enforcing O_NOFOLLOW/rejecting symlinks
+- iswspace was wrongly returning true for the null character
+- various bugs in wordexp
+- putgrent could write corrupt lines after write failures
+- dn_expand misinterpreted in-packet offsets greater than 255
+- spurious strftime/wcsftime failure on len+1==bufsize case
+- incorrect underflow flag in fma corner cases
+- log*(0) wrongly returned +inf in downward-rounding mode
+- failure of fchmod, fstat, fchdir, and fchown to produce EBADF
+
+arch-specific bugs fixed:
+- i386: failure of fesetround to set sse rounding mode
+- i386: floating point limit constants misinterpreted due to excess precision
+- powerpc: broken thread pointer access when compiled with clang
+- microblaze: dynamic linker entry point code possibly clobbering argv
+
+strict conformance issues:
+- NULL definition re-aligned with POSIX (requires (void *) cast)
+- alignment of math.h is* comparison functions with C11 annex F requirements
+
+
+
+1.0.0 release notes
+
+new features:
+- support for mips softfloat ABI variant
+- legacy setkey and encrypt API for DES
+- support for BSD version of struct tcphdr in addition to GNU version
+- added ipv6 and icmpv6 protocol lookups to getprotoent-family functions
+
+new experimental ports:
+- sh (SuperH)
+- x32 (ILP32 ABI for x86_64)
+
+compatibility:
+- improved c89 compiler support in math.h
+- eliminate some compiler warnings in public headers
+- added some missing things for LFS64 APIs
+- added fallback emulation of accept4 for older kernels
+
+bugs fixed:
+- buffer overflow in printf when printing smallest denormal exactly
+- rounding errors in printf in some just-over-halfway cases
+- posix_spawn did not accept null pid pointer (crashed)
+- ftello gave incorrect result for unflushed append-mode streams
+- mishandling of n=0 case in wcsxfrm (wild buffer overrun)
+- possible system breakage during libc upgrade due to install.sh bugs
+- nftw FTW_MOUNT flag prevented walking any directories at all
+- ptsname/ptsname_r returned negated error codes
+- getprotoent function returned junk after listing valid protocols
+- wrong error code from readdir when the directory has been deleted
+- various prototype/argument-type fixes, mostly to legacy functions
+- various header namespace violations
+
+arch-specific bugs fixed:
+- fesetenv(FE_DFL_ENV) was broken on i386 and x86_64
+- strerror(EDQUOT) did not work on mips
+- recvmsg/sendmsg were broken on powerpc
+- sysv ipc was broken on powerpc and mips
+- statfs/statvfs were broken on mips
+- sigaltstack was broken on mips
+
+
+
+1.1.0 release notes
+
+new features:
+- relro memory protection in dynamic linker
+- malloc can now extend heap with mmap if brk fails
+- vdso clock_gettime/gettimeofday/time acceleration on x86_64
+- thread/library-safe versions of search.h functions (nonstandard)
+- getauxval function (nonstandard)
+- sysconf extensions to query physical memory size
+
+bugs fixed:
+- floating point printf output corruption from carry into uninitialized slot
+- possible runaway carry overflow in printf floating point
+- printf %g failure to strip trailing zeros in some cases
+- search past end of haystack in memmem
+- off-by-one error in confstr return value
+- crashes in some near-empty static programs that use stack protector
+- deadlock race in pthread_once
+- non-working clock_gettime fallback for old kernels
+
+arch-specific bugs fixed:
+- crash from missing syscall asm register clobbers on real microblaze kernel
+- crash in all nontrivial dynamic linker use on microblaze
+- incorrect rlimit constants on mips
+- broken, possibly dangerous, use of getrlimit syscall on x32 in sysconf
+
+
+
+1.1.1 release notes
+
+new features:
+- new options --preload and --library-path to dynamic linker
+- public execvpe function (nonstandard extension)
+- iconv support for cp437 and cp850
+
+bugs fixed:
+- false negatives with some periodic needles in strstr, wcsstr, and memmem
+- crash on invalid zoneinfo files
+- incorrect zero-padding of some outputs for strftime %s specifier
+- misreporting of errors in configure script when $CC does not work at all
+- treating not-yet-implemented strptime specifiers as errors
+
+compatibility:
+- configure now detects serious constant-folding bug in gcc 4.9.0
+- removed __yield symbol (unused) that clashed with some compilers
+- improvements to sysconf's handling of unsupported/invalid arguments
+
+arch-specific bugs fixed:
+- misdetection of superh ABI variant by configure on gcc 3.x
+- missing SO_RCVBUFFORCE and SO_SNDBUFFORCE in mips socket.h
+- build regression on armv6 and later with -mthumb
+
+
+
+1.1.2 release notes
+
+new features:
+- multi-protocol matches (tcp and udp) in getaddrinfo
+- support for AI_V4MAPPED and AI_ALL flags to getaddrinfo
+- reverse name lookups from /etc/hosts
+- reverse service lookups from /etc/services
+- support for service aliases in /etc/services
+- ipsec and tunneling protocols to getprotoent-family functions
+- res_send, res_mkquery, res_querydomain, and dn_comp functions
+- ipv6 scope id handling for link-local scope addresses
+- previously-unimplemented %C and %y in strptime now work
+- vdso clock_gettime acceleration on i386 (new kernel feature)
+- better O_CLOEXEC/SOCK_CLOEXEC fallbacks for old kernels
+
+bugs fixed:
+- buffer overflow in dns response parsing (CVE-2014-3484)
+- possible infinite loop in dns response parsing
+- sendfile off_t 32/64-bit size mismatch
+- incorrect end pointer in some cases when wcsrtombs stops early
+- incorrect if_nametoindex return value when interface does not exist
+- dummy "ent" function aliases that possibly shadowed real ones
+- tmpfile fd leak on memory exhaustion
+- getaddrinfo returning EAI_NONAME for some transient failures
+
+arch-specific bugs fixed:
+- broken kernel side RLIM_INFINITY on mips
+- incorrect syscall argument 6/7 types for pselect on x32
+
+
+
+1.1.3 release notes
+
+new features:
+- address sorting in getaddrinfo, etc. modeled on rfc 3484/6724
+- default timezone taken from /etc/localtime when $TZ is unset
+- getopt double-colon extension for optional arguments
+- support for TLSDESC-based (gnu2) TLS dialect on i386 and x86_64
+- sendmmsg/recvmmsg (linux-specific)
+- fmtmsg (last mandatory XSI function that was missing)
+
+compatibility:
+- treat dns rcode=2 as temporary failure, not negative result
+- working thread-pointer for pre-2.6 kernels on i386
+- further ABI-compat symbols: __xmknod[at], __sysv_signal
+
+bugs fixed:
+- memmem false positives/false negatives/crashes from invalid logic
+- gethostby*_r not setting result pointer to null on failure
+- aliasing violations in syscall.h SYSLOG_NAMES feature
+- fanotify_mark syscall arguments wrong
+
+arch-specific bugs fixed:
+- various subtle relocation bugs in powerpc and sh dynamic linker
+
+
+
+1.1.4 release notes
+
+new features:
+- experimental locale support for LC_MESSAGES and LC_TIME
+- non-stub gettext family functions for message translation
+- or1k (OpenRISC 1000) port
+- syslog options LOG_CONS and LOG_PERROR
+- issetugid function (from OpenBSD)
+- improved if_nameindex and getifaddrs functions
+
+compatibility:
+- work around bug #61144 in gcc 4.9.0 and 4.9.1
+- support getauxval(AT_SECURE) even on kernels without AT_SECURE
+
+bugs fixed:
+- empty dynamic linker error messages (regression in 1.1.3)
+- if_nameindex omitted unconfigured and ipv6-only interfaces
+- incorrect return value for fwide function
+- failure of wide printf/scanf functions to set wide orientation
+- multiple issues in legacy function getpass
+- dynamic linker did not accept colon as a separator for LD_PRELOAD
+- errno clobber in syslog caused wrong output for %m specifier
+- crash in regexec for nonzero nmatch argument with REG_NOSUB
+- minor bugs in rarely-used nl_langinfo item lookups
+
+arch-specific bugs fixed:
+- broken relocations in mips dynamic linker (regression in 1.1.3)
+- register state corruption in setjmp asm for microblaze
+- broken struct stat st_ino field on microblaze
+- broken struct stat st_dev field on big endian mips
+- broken asm register constraints in atomics on powerpc
+- missing barriers in atomics on mips, powerpc, microblaze, and sh
+
+
+
+1.1.5 release notes
+
+new features:
+- full C11 coverage (threads, UTF-16/32 API, timespec_get, etc.)
+- malloc_usable_size function (nonstandard)
+- support for new F_OFD_* fcntl operations (linux 3.15, POSIX-future)
+- new _DEFAULT_SOURCE feature test macro to request default profile
+
+performance:
+- private-futex support
+- redesigned cond var implementation with major performance improvement
+- tweaked spinning in userspace before performing futex waits
+
+bugs fixed:
+- failure of dn_expand to null-terminate name for crafted DNS packets
+- corruption of cond var mutex state when switching mutexes
+- use of uninitialized memory with application-provided thread stacks
+- false ownership of orphaned mutexes due to tid reuse
+- possible failure-to-wake for robust mutexes on owner death
+- subtle errors in robust mutex unrecoverable status handling
+- missing memory/compiler barrier spinning to obtain locks
+- wrong behavior in various zero-length stdio operations
+- buffer overflow in swab with odd argument
+- incorrect sequence generation in the rand48 family of prng functions
+- missing cancellation check in non-wait paths of sem_wait, pthread_join
+- missing barrier in pthread_once fast path
+- memory leak in regexec when input contains illegal sequence
+- various parser bugs in regcomp
+- wrong return value on overflow in some strtoul-family functions
+- broken CPU_EQUAL macro in sched.h
+- dlerror not working in static-linked programs
+- mishandling of negative non-whole-hour TZ offsets
+- incorrect case mappings for U+00DF
+- namespace pollution via accidentally-non-static function named "dummy"
+- missing __fpclassifyl and __signbitl definitions for ld64 archs
+
+
+
+1.1.6 release notes
+
+new features:
+- getopt '-' flag for processing non-option arguments
+- getopt_long argument permutation extension
+- getopt_long abbreviated options
+- ns_parserr and related DNS-packet-parsing functions
+- fnmatch FNM_CASEFOLD extension
+- support for translation of getopt error messages
+- login_tty function (legacy)
+
+performance:
+- efficient atomics on armv7+ targets
+- pthread_once shrink-wrapping of fast path
+
+compatibility:
+- baseline arm binaries now work on new cpus/kernels without kuser_helper
+- dynamic linker now honors DT_RUNPATH without DT_RPATH (new binutils)
+- arm asm is now compatible with clang's internal assembler
+- suppress macro implementations of functions when headers are used in C++
+- increased message length limit for syslog
+
+bugs fixed:
+- open ignored file creation mode argument for O_TMPFILE
+- wrong printf formatting for %#.0o with value zero
+- missing private state for uchar.h functions (null ps pointer)
+- sched_getaffinity left uninitialized data in output bit array
+- wrong return values for pthread_getaffinity_np and pthread_setaffinity_np
+- buggy handling of multibyte option chars with arguments in getopt
+- printf failed to report or stop on write errors
+- printf failed to honor '+' modifier when printing NANs
+- wcsnrtombs returned the wrong value in one code path
+- syslog failed to check for connect error
+- multi-threaded set*id() had spurious failures from ugly workaround code
+- various minor header conformance bugs (signedness, constant expressions, ...)
+
+arch-specific bugs fixed:
+- on or1k, some syscalls with 64-bit arguments were broken (misaligned)
+- usage of sahf instruction on x86_64 crashed on some early cpu models
+
+
+
+1.1.7 release notes
+
+new features:
+- alternate passwd/group backend support via nscd protocol
+- masked cancellation mode extension (experimental)
+- aio cancellation
+- aarch64 port (experimental)
+
+performance:
+- significant memset asm optimizations on i386 and x86_64
+
+compatibility:
+- suppress EINTR in semaphores for old kernels where futex restart is broken
+- always set optarg in getopt_long
+- support SOCK_RAW socket type in getaddrinfo
+- report success instead of EINPROGRESS when close is interrupted
+
+bugs fixed:
+- multithreaded set*id() was not async-signal safe, had various race bugs
+- getspnam_r returned results for partial username matches
+- wordexp bad character checker mis-counted parentheses
+- close on fd with pending aio could lead to file corruption
+- old aio implementation had numerous conformance bugs
+- malloc init code could deadlock due to race condition
+- pthread_exit did not disable cancellation
+- pthread_cond_wait could wrongly consume signal on cancellation
+- execvp wrongly stopped path search on EACCESS
+- fsync, fdatasync, and msync were not honored as cancellation points
+- fchmodat was subject to fd leak race (missing O_CLOEXEC)
+- fchmodat failed to report EOPNOTSUPP in race path
+- passwd/group lookup functions had various minor error-reporting bugs
+- isatty had false-positives/device-state-corruption for OSS sound devices
+- configure script failed to detect gcc with translated messages
+- FLT_ROUNDS macro failed to reflect rounding mode changes in fenv
+
+arch-specific bugs fixed:
+- mips fesetenv did not handle FE_DFL_ENV
+- mips POLLWRNORM and POLLWRBAND macros had wrong values
+- x32 pthread synchronization object type definitions were wrong
+- powerpc minimum signal stack size was insufficient
+
+
+
+1.1.8 release notes
+
+bugs fixed:
+- stack-based buffer overflow in inet_pton (CVE-2015-1817)
+- regcomp crash/mem-corruption with illegal bytes after backslash
+- regcomp wrongly allowed backrefs in ER
+- regcomp miscompiled character class brace-repetitions
+- regcomp wrongly processed \0 as an unmatchable backref
+- new FLT_ROUNDS definition failed to work in C++ code
+
+arch-specific bugs fixed:
+- aarch64 was missing max_align_t definition
+
+
+
+1.1.9 release notes
+
+new features:
+- ability to protect libc code itself with stack protector
+- sigsetjmp now restores signal mask after restoring context, not before
+- thread-local dlerror status/messages
+- dlerror messages are no longer truncated
+- diagnostics for constraint violations with ctype.h macros
+
+optimizations:
+- reduce cost of PIC on archs where PLT calls need a fixed GOT register
+- spin locks no longer constantly invalidate cache lines while spinning
+- code size reduction in static-linked TLS init
+
+bugs fixed:
+- failure to process robust mutexes on detached-thread exit
+- possible memory corruption due to robust mutex list on detached-thread exit
+- crash on memory exhaustion in getgr* internals
+- misaligned memory accesses in static binaries with low-alignment TLS blocks
+- multiple cases of wrongful path search continuation after transient failure
+- small memory leak on failure of dlopen with RPATH $ORIGIN
+- several small math bugs related to exception flags with non-finite args
+- mmap leak in sem_open failure path for link call
+- duplocale clobbered new locale struct with memcpy of old
+- futimes crashed with null timeval argument
+
+arch-specific bugs fixed:
+- stack protector spuriously aborted after forking on x32
+- stack protector spuriously aborted with flockfile on powerpc
+- theoretically-possible clobbering of syscall return value on mips
+- random thread-pointer setup failure on sh (uninitialized return value)
+- possible crash in dlsym on sh due to incorrectly-computed branch target
+- broken fesetenv(FE_DFL_ENV) on mips
+- dynamic linker name for sh ignored fpu/nofpu and endianness
+- various minor aarch64 bugs
+- dangling pointers in x32 syscall timespec fixup code
+
+
+
+1.1.10 release notes
+
+new features:
+- fail-safe (allocation-free) C locale for newlocale to return
+- all locale categories track requested locale name
+- rcrt1.o start file for static PIE
+
+optimizations:
+- inline atomics for sh4a
+- removed heavy atomics from locale-related code paths
+- removed global data accesses from CURRENT_LOCALE macro & callers
+- dynamic linker stage 1 size reduction
+
+compatibility:
+- better configure detection of unsupported compiler options
+- support for more relocation types in libc.so, not currently used
+- iconv_open accepts "" and "CHAR" as aliases for native (UTF-8)
+- additional LFS64 macros in sys/resource.h
+
+regressions fixed:
+- dynamic linker crash on NONE-type relocations (only mips affected)
+- inability to build as thumb2 on arm
+- failure to run under qemu-i386 user-level emulation
+- inability to access globals from libc on powerpc
+- PIE link errors in Scrt1.o under unusual usage on some archs
+
+other bugs fixed:
+- failure of ungetc/ungetwc to work on FILE streams in EOF state
+- possible null pointer dereference in gettext
+- possible initial stack misalignment on mips with PIE
+
+
+
+1.1.11 release notes
+
+new features:
+- byte-based C locale
+- vdso clock_gettime on arm
+- musl-clang wrapper
+- sh2 nommu target support
+
+performance:
+- major speed-up for dynamic linker symbol lookups with GNU hash
+
+compatibility:
+- strverscmp now matches GNU behavior in corner cases
+- empty TZ environment variable gives GMT rather than system default
+- reconnection on syslog server socket loss (syslogd restart)
+- mmap fallback in simple_malloc when brk fails
+- support for %m and %s with null pointers in wide printf variants
+- call frame information in i386 asm for improved debugger support
+
+bugs fixed:
+- spurious errors from pwd/grp functions when nscd backend is absent
+- possible invalid access on calloc with simple_malloc
+- null pointer dereferences after calling uselocale((locale_t)0)
+- erroneous support for cancellation in stdio caused data loss
+- inconsistent handling of atexit called from atexit handler
+- missing locking in error paths for ungetwc
+- btowc mishandling of out-of-range non-EOF inputs
+- negated return value of ns_skiprr, failure in related functions
+- incorrect void return type for syncfs, missing error status
+- possible failure of tempnam due to missing null termination
+- negated tm_gmtoff field in struct tm
+- off-by-one error in getsubopt leaving equals sign in value result
+
+arch-specific bugs fixed:
+- soft deadlocks on i386/x86_64 due to missing barrier in internal locks
+- regression in arm pre-v7 support for kernels with kuser helper removed
+- runaway PC on mips detached thread exit (due to kernel regression)
+- mismatched ABI for local-dynamic model TLS on mips and powerpc
+- incorrect value of some SO_* constants on mips
+- broken 64-bit syscall argument passing on aarch64
+
+
+
+1.1.12 release notes
+
+new features:
+- fdpic abi on sh2 for shareable text segment without mmu
+- general fdpic elf support in dynamic linker
+- CFI generation for x86_64 asm source files
+- protection against silently building a libc.so with missing symbols
+
+compatibility:
+- nl_langinfo(CODESET) now returns "ASCII" in byte-based C locale
+- fixed build regression due to buggy .SECONDARY in some GNU make versions
+- additional arm eabi functions needed by llvm arm backend
+- added format argument attributes to gettext function prototypes
+- static PIE no longer requires linking with -E/-rdynamic
+- eliminated spurious protected-data warnings linking against libc.so
+- avoided spurious fpu asm errors with some armhf toolchains
+
+bugs fixed:
+- fclose of stdin/stdout caused deadlock at exit
+- missing memory barrier in pthread_join
+- open_[w]memstream produced no buffer when no writes took place
+- uninitialized scopeid in address lookups from hosts file and ip literals
+- ip literals for mismatching family (v4 vs v6) were queried as hostnames
+- possible crash on OOM in regcomp
+- incorrect contents in localeconv structure (-1 instead of CHAR_MAX)
+- strftime mishandling of out-of-range struct tm members
+- wrongful attribute((const)) on pthread_self and errno location function
+
+arch-specific bugs fixed:
+- arm crt1 entry point failed to align stack pointer in some cases
+- mips fesetround failed to actually set rounding mode
+- i386 asm source CFI generation had multiple bugs
+
+
+
+1.1.13 release notes
+
+new features:
+- out-of-tree builds
+- search domains in resolv.conf
+- sh arch supports j-core (j2) cas.l atomics
+- dynamic linker includes arch/abi in output when run as a command
+- header support for new kernel features through linux 4.4
+- mips vdso clock_gettime support
+- regex BRE extensions: \|, \+, \?
+
+performance:
+- improved atomics performance on all archs with ll/sc model
+- atomic instructions are now inlined on armv6
+- use fpu sqrt for arm softfp abi on targets with vfp
+
+compatibility:
+- getnameinfo now accepts sockaddr sizes larger than needed
+- new default CFLAGS/LDFLAGS avoid entire classes of toolchain bugs
+- explicit use of float_t/double_t avoids compiler float spill bugs
+- i386 max_align_t definition now works with g++ 4.7's pseudo-c++11
+- all known protocols are added to protoent functions
+- stub utmpname, utmpxname functions
+- linker support for -Bsymbolic-functions is no longer mandatory
+- regex parsing size limits increased
+- malloc_usable_size now accepts null pointer input
+
+bugs fixed:
+- potential single-byte heap overflow in getdelim
+- mishandling of transient failure opening hosts, services, resolv.conf
+- mremap was sometimes able to allocate objects larger than PTRDIFF_MAX
+- nl_langinfo wrongly returned NULL instead of "" for invalid items
+- out-of-bounds dynamic tls allocation due to pointer/index scaling error
+- getifaddrs misreported point-to-point interface addresses
+- tdelete left tsearch trees misbalanced
+- tsearch crashed on allocation failure
+- tsearch, tfind, and tdelete failed to handle null pointer input
+- passing signal number 0 to sigaction resulted in a crash
+- getdelim updated caller's size wrongly when realloc failed
+- getdelim realloc strategy was wasteful
+- if_nametoindex returned wrong value on failure
+- missing ssp-suppression for some source files called from early-init
+- various minor resolv.conf parsing bugs
+- fwrite wrongly reported success on write errors in line-buffered flush
+- fwrite and fread wrongly returned nmemb (not 0) when size was 0
+
+nommu-specific bugs fix:
+- failure to zero bss in FDPIC shared library loader
+- unsafe writes to read-only file mapping in non-FDPIC library loader
+
+arch-specific bugs fixed:
+- sh[eb]-nofpu-fdpic was using fpu-dependent setjmp/longjmp variants
+- dynamic linker path file name was wrong for arm "softfp" targets
+- mips siginfo_t and related macros were defined incorrectly
+- possibly misaligned pointer globals on arm (from an asm source file)
+- mips dynamic linker failed to provide info needed by debugger
+- mips cancellation asm wrongly assumed validity of $gp register value
+
+
+
+1.1.14 release notes
+
+regressions fixed:
+- treatment of empty string argument as error by puts and fputs
+- make clean and distclean failure in unconfigured trees
+- sh/fdpic dynamic linker entry point hang due to wrong code
+- armhf (and arm softfp model) build failure with clang
+
+other bugs fixed:
+- wrongly clamping (rather than failing) excessive rounds in crypt-sha*
+
+
+
+1.1.15 release notes
+
+new features:
+- mips64 (full 64-bit and n32) port
+- mips r6 isa support (subarch for mips, mips64, and mipsn32 archs)
+- powerpc64 port
+- powerpc (32-bit) soft-float ABI support (subarch)
+- pthread_tryjoin_np and pthread_timedjoin_np (nonstandard extensions)
+- header-level support for linux 4.5 and 4.6 features
+- sched_getcpu (nonstandard extension) support, including vdso version
+- __STDC_ISO_10646__, __STDC_IEC_559__ macros predefined via stdc-predef.h
+- support for new elf/arch features in elf.h
+
+compatibility:
+- configure now correctly chooses cross-prefix based on build/host/target
+- abort now successfully terminates pid 1 in a container (or top-level)
+
+bugs fixed:
+- memmem read past end of haystack, possible false positives or crashes
+- buffer underflow (reverse-overflow) in ungetwc
+- double-free under certain usage of putenv
+- incorrect treatment by regcomp of * at start of BRE subexpression
+- gethostbyname[2][_r] produced ip addresses in misaligned buffers
+- looking up some invalid hostnames caused malformed dns queries
+- lookups from hosts file were inconsistent with non-matching family
+- missing h_length value in gethostbyaddr results
+- a64l function produced wrong-signed results on 64-bit archs
+- broken padding of string formats to width in wide printf variants
+- wrong results for expf(-NAN) and exp2f(-NAN)
+- wrong value for RUSAGE_CHILDREN prevented it from working
+- abort failed to provide abnormal termination with SIGABRT blocked
+
+arch-specific bugs fixed:
+- broken posix_fadvise on arm and powerpc (32-bit)
+- thread structure/dtv corruption on powerpc at thread startup
+- various wrong mips and powerpc ioctl and termios constant values
+
+
+
+1.1.16 release notes
+
+new features:
+- s390x (64-bit S/390) port
+- pthread_setname_np extension function
+- limited pthread_setattr_default_np function to set stack size defaults
+- header-level support for linux 4.7, 4.8, and 4.9 features
+- confstr _CS_V6_ENV and _CS_V7_ENV items
+
+compatibility:
+- public prototypes for abi-compat *_unlocked symbols, etc.
+- fflush_unlocked(NULL) now works
+- resolv.h __RES version macro now matches supported APIs
+- workaround for gdb bugs backtracing across signals on x86_64
+- anchors ^ and $ are now accepted in BRE subexpressions
+- building for thumb2-only arm isa levels is now possible
+
+bugs fixed:
+- integer overflows in regexec buffer allocation (CVE-2016-8859)
+- failure of regexec to report matches at offsets past INT_MAX
+- static-pie executables with initialized thread-local storage crashed
+- printf failed to catch EOVERFLOW in some cases, wrongly produced it in others
+- printf produced wrong output, result for float with precision near INT_MAX
+- printf produced wrong results with alt-form octal, zero flag, & field width
+- printf float rounding was wrong for some midpoint cases
+- swprintf printed junk after internal (256-byte) buffer filled up
+- strtod family rounded incorrectly in several corner cases
+- getmntent failed to handle long records
+- getopt_long_only wrongly treated "--" as an option
+- asctime output wrongly varied by locale
+- strftime %y specifier produced wrong output for negative tm_year
+- time zone names quoted with <> were misparsed
+- corner case integer overflow in tm_year for some date conversions
+- failure to load shared libs whose names were prefixes of standard lib names
+- wrong error codes for several failure cases in various functions
+- various asymptomatic undefined behavior
+- various minor namespace issues in headers
+
+arch-specific bugs fixed:
+- tcsetattr regression on mips (completely non-working)
+- wrong pread/pwrite syscall calling convention on sh
+- wrong preadv2/pwritev2 syscall numbers on x32
+- mrand48/jrand48 produced wrong-signedness results on 64-bit archs
+
+
+1.1.17 release notes
+
+new features:
+- RTLD_LAZY deferred symbol binding, functionally equivalent to lazy binding
+- safeguard against dlopen of multiple libc versions/instances
+- new posix_spawn flag POSIX_SPAWN_SETSID
+- posix_spawnattr_setflags now reports unknown flags as error
+- ldso option --argv0 to set argv[0]
+- added _NL_LOCALE_NAME extension to nl_langinfo
+
+compatibility:
+- dlopen local-to-global promotion no longer changes existing symbols
+- gettext now searches locale name variants for translation files
+- increased locale name length limit from 15 to 23 bytes
+- setlocale(LC_ALL, 0) returns single name if all categories are same
+- realloc no longer fails when mremap doesn't work
+- getservby* no longer treat numeric port strings as service records
+- mmap now works around incorrect EPERM error codes from kernel
+- impact of REG_* namespace pollution in x86[_64] signal.h is reduced
+- arm atomic asm now assembles correctly with new binutils
+- PAGE_SIZE on arm is no longer constant (quiet upstream ABI relaxation)
+- lsearch/lfind now pass args to compare callback in canonical order
+- STB_WEAK and STB_GNU_UNIQUE symbols now behave same as STB_GLOBAL
+- better clang CFLAGS checks in configure
+- global vis.h hack, which made lld refuse to link to libc.so, is disabled
+
+performance:
+- single-instruction optimized math functions for aarch64, s390x, powerpc64
+- fast path for ASCII in towupper/towlower
+- new mostly-integer-math fma function
+
+semantic bugs fixed:
+- POSIX-format TZ dst time transitions were wrong for southern hemisphere
+- regex REG_NEWLINE semantics were wrong with negated brackets
+- various bugs in strptime %j, %p, %C formats
+- iconv mapped some characters to legacy 8bit encodings incorrectly
+- glob failed to match "/"
+- UTF-8 decoder accepted invalid f4 9x xx xx code sequences
+- scanf %% conversion failed to consume whitespace
+- glob with GLOB_PERIOD wrongly descended into . and ..
+- nftw gave incorrect base name offset when pathname ends in "/"
+- functional regression in resolv.conf attempts option
+- scalbn could produce wrong result due to double rounding in subnormal range
+- strftime %y format wrong with negative years
+- mbsnrtowcs and wcsnrtombs mishandled input limits
+- minor issues with error codes for various functions
+
+safety/consistency bugs fixed:
+- stack-based buffer overflow in dns response processing
+- invalid free in regexec on certain error paths
+- invalid free in globfree after failed glob
+- one-byte buffer overflow in legacy getpass function
+- failed dlopen corrupted thread-local storage module list
+- race in pthread_create with priority attributes could leave signals masked
+- multithreaded set*id() functions could induce spurious EINTRs
+- dl_iterate_phdr reported wrong base address in static PIE
+- fd leak and wrong cancellation state after dns socket failure
+- memory leaks and other issues in environment-modification functions
+- read-after-free race in pthread_detach
+- memmem performed single-byte over-read in short-needle code paths
+- read via uninitialized pointer in gettext core
+- bindtextdomain broke bindings for all other domains
+- various silent undefined behavior
+- getopt clobbered optopt on success
+
+arch-specific bugs fixed:
+- x32 dynamic TLS accesses crashed
+- s390x was missing dlsym entry point (needed for RTLD_NEXT)
+- powerpc64 ldso startup could crash depending on link order
+- powerpc64 setjmp/longjmp didn't properly save/restore TOC pointer
+- thumb2 setjmp/longjmp silently broke at ld-time with text not aligned
+- fchown was broken on archs without SYS_fchown syscall
+- fstatat was broken on mips64
+- various incorrect constants in powerpc64 and mips headers
+
+
+1.1.18 release notes
+
+regression fixes:
+- glob failed to match literal . and .. path components
+- build for armv4t ISA level was broken
+
+other bug fixes:
+- stack overflow in posix_spawnp with large PATH variable in environment
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/atomic_arch.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/atomic_arch.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/atomic_arch.h	(revision 398)
@@ -0,0 +1,54 @@
+#if defined(__SH4A__)
+
+#define a_ll a_ll
+static inline int a_ll(volatile int *p)
+{
+	int v;
+	__asm__ __volatile__ ("movli.l @%1, %0" : "=z"(v) : "r"(p), "m"(*p));
+	return v;
+}
+
+#define a_sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+	int r;
+	__asm__ __volatile__ (
+		"movco.l %2, @%3 ; movt %0"
+		: "=r"(r), "=m"(*p) : "z"(v), "r"(p) : "memory", "cc");
+	return r;
+}
+
+#define a_barrier a_barrier
+static inline void a_barrier()
+{
+	__asm__ __volatile__ ("synco" ::: "memory");
+}
+
+#define a_pre_llsc a_barrier
+#define a_post_llsc a_barrier
+
+#else
+
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+#ifndef __c2__
+	__asm__ __volatile__ ("clrpsw i");
+	if (*p == t)
+		*p = s;
+	else
+		s = *p;
+	__asm__ __volatile__ ("setpsw i");
+	return s;
+#else
+	extern int __attribute__((stdcall)) InterlockedCompareExchange(
+		volatile int *Destination, int Exchange, int Comperand);
+	/*__asm__ __volatile__(
+		"lock ; cmpxchg %3, %1"
+		: "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory");
+	return t;*/
+	return InterlockedCompareExchange(p,t,s);
+#endif
+}
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/bits/endian.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/bits/endian.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/bits/endian.h	(revision 398)
@@ -0,0 +1,5 @@
+#if __BIG_ENDIAN__
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/crt_arch.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/crt_arch.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/crt_arch.h	(revision 398)
@@ -0,0 +1,9 @@
+#ifndef __c2__
+#define main sta_ker
+#else
+#define main dummy_start
+static int dummy_start(int argc, char **argv, char **envp)
+{
+	return 0;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/pthread_arch.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/pthread_arch.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/pthread_arch.h	(revision 398)
@@ -0,0 +1,16 @@
+static inline struct pthread *__pthread_self()
+{
+#ifndef __c2__
+	char *self;
+	__asm__ __volatile__ ("mvfc fintv,%0" : "=r" (self) );
+#else
+	extern void *thread_area;
+	char *self = (char *)thread_area;
+#endif
+	return (struct pthread *) (self + 8 - sizeof(struct pthread));
+}
+
+#define TLS_ABOVE_TP
+#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8)
+
+#define MC_PC sc_pc
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/reloc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/reloc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/reloc.h	(revision 398)
@@ -0,0 +1,54 @@
+#include <endian.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ENDIAN_SUFFIX "eb"
+#else
+#define ENDIAN_SUFFIX ""
+#endif
+
+#if __RX_FPU_ANY__ || __SH4__
+#define FP_SUFFIX ""
+#else
+#define FP_SUFFIX "-nofpu"
+#endif
+
+#if __RX_FDPIC__
+#define ABI_SUFFIX "-fdpic"
+#else
+#define ABI_SUFFIX ""
+#endif
+
+#define LDSO_ARCH "rx" ENDIAN_SUFFIX FP_SUFFIX ABI_SUFFIX
+
+#define TPOFF_K 8
+
+#define REL_SYMBOLIC    R_RX_DIR32
+#define REL_OFFSET      R_RX_REL32
+#define REL_GOT         R_RX_GLOB_DAT
+#define REL_PLT         R_RX_JMP_SLOT
+#define REL_RELATIVE    R_RX_RELATIVE
+#define REL_COPY        R_RX_COPY
+#define REL_DTPMOD      R_RX_TLS_DTPMOD32
+#define REL_DTPOFF      R_RX_TLS_DTPOFF32
+#define REL_TPOFF       R_RX_TLS_TPOFF32
+
+#define DL_NOMMU_SUPPORT 1
+
+#if __RX_FDPIC__
+#define REL_FUNCDESC    R_RX_FUNCDESC
+#define REL_FUNCDESC_VAL R_RX_FUNCDESC_VALUE
+#undef  REL_RELATIVE
+#define DL_FDPIC 1
+#define FDPIC_CONSTDISP_FLAG 0x100
+#define CRTJMP(pc,sp) do { \
+	register size_t r8 __asm__("r8") = ((size_t *)(sp))[-2]; \
+	__asm__ __volatile__( "jsr %0 ; mov %1,r15" \
+	: : "r"(pc), "r"(sp), "r"(r8) : "memory" ); } while(0)
+#define GETFUNCSYM(fp, sym, got) __asm__ ( \
+	"mov.l 1f,%0 ; add %1,%0 ; bra 2f ; nop ; .align 2 \n" \
+	"1:	.long " #sym "@GOTOFFFUNCDESC \n2:" \
+	: "=&r"(*fp) : "r"(got) : "memory" )
+#else
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+	"jsr %0 ; mov %1,r15" : : "r"(pc), "r"(sp) : "memory" )
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/syscall_arch.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/syscall_arch.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/arch/rx/syscall_arch.h	(revision 398)
@@ -0,0 +1,115 @@
+#define __SYSCALL_LL_E(x) \
+((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
+((union { long long ll; long l[2]; }){ .ll = x }).l[1]
+#define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))
+#define __SYSCALL_LL_PRW(x) 0, __SYSCALL_LL_E((x))
+
+#if 0
+#define __asm_syscall(...) do {   \
+	__asm__ __volatile__ (                \
+		"int #08\n"                       \
+	: "=r"(r0) : __VA_ARGS__ : "memory"); \
+	return r0;                            \
+	} while (0)
+
+static inline long __syscall0(long n)
+{
+	register long r3 __asm__("r3") = n;
+	register long r0 __asm__("r0");
+	__asm_syscall("r"(r3));
+}
+
+static inline long __syscall1(long n, long a)
+{
+	register long r3 __asm__("r3") = n;
+	register long r4 __asm__("r4") = a;
+	register long r0 __asm__("r0");
+	__asm_syscall("r"(r3), "r"(r4));
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+	register long r3 __asm__("r3") = n;
+	register long r4 __asm__("r4") = a;
+	register long r5 __asm__("r5") = b;
+	register long r0 __asm__("r0");
+	__asm_syscall("r"(r3), "r"(r4), "r"(r5));
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+	register long r3 __asm__("r3") = n;
+	register long r4 __asm__("r4") = a;
+	register long r5 __asm__("r5") = b;
+	register long r6 __asm__("r6") = c;
+	register long r0 __asm__("r0");
+	__asm_syscall("r"(r3), "r"(r4), "r"(r5), "r"(r6));
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+	register long r3 __asm__("r3") = n;
+	register long r4 __asm__("r4") = a;
+	register long r5 __asm__("r5") = b;
+	register long r6 __asm__("r6") = c;
+	register long r7 __asm__("r7") = d;
+	register long r0 __asm__("r0");
+	__asm_syscall("r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7));
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+	register long r3 __asm__("r3") = n;
+	register long r4 __asm__("r4") = a;
+	register long r5 __asm__("r5") = b;
+	register long r6 __asm__("r6") = c;
+	register long r7 __asm__("r7") = d;
+	register long r0 __asm__("r0") = e;
+	__asm_syscall("r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "0"(r0));
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+	register long r3 __asm__("r3") = n;
+	register long r4 __asm__("r4") = a;
+	register long r5 __asm__("r5") = b;
+	register long r6 __asm__("r6") = c;
+	register long r7 __asm__("r7") = d;
+	register long r0 __asm__("r0") = e;
+	register long r1 __asm__("r1") = f;
+	__asm_syscall("r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "0"(r0), "r"(r1));
+}
+#else
+#define __scc(X) ((long) (X))
+typedef long syscall_arg_t;
+
+__attribute__((visibility("hidden")))
+long __syscall_ret(unsigned long), __syscall_nr(long nr, ...);
+
+#define __syscall0(n) n()
+#define __syscall1(n,a) n(__scc(a))
+#define __syscall2(n,a,b) n(__scc(a),__scc(b))
+#define __syscall3(n,a,b,c) n(__scc(a),__scc(b),__scc(c))
+#define __syscall4(n,a,b,c,d) n(__scc(a),__scc(b),__scc(c),__scc(d))
+#define __syscall5(n,a,b,c,d,e) n(__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
+#define __syscall6(n,a,b,c,d,e,f) n(__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
+#define __syscall7(n,a,b,c,d,e,f,g) n(__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g))
+
+#define __syscall_cp0(n) n()
+#define __syscall_cp1(n,a) n(__scc(a))
+#define __syscall_cp2(n,a,b) n(__scc(a),__scc(b))
+#define __syscall_cp3(n,a,b,c) n(__scc(a),__scc(b),__scc(c))
+#define __syscall_cp4(n,a,b,c,d) n(__scc(a),__scc(b),__scc(c),__scc(d))
+#define __syscall_cp5(n,a,b,c,d,e) n(__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
+#define __syscall_cp6(n,a,b,c,d,e,f) n(__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
+#define __syscall_cp7(n,a,b,c,d,e,f,g) n(__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g))
+
+#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
+#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
+#define __SYSCALL_CONCAT_X(a,b) a##b
+#define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b)
+#define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
+
+#define syscall(...) __syscall_ret(__SYSCALL_DISP(__syscall, __VA_ARGS__))
+#define syscall_cp(...) __syscall_ret(__SYSCALL_DISP(__syscall_cp, __VA_ARGS__))
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/Scrt1.~c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/Scrt1.~c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/Scrt1.~c	(revision 398)
@@ -0,0 +1,1 @@
+#include "crt1.c"
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/crt1.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/crt1.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/crt1.c	(revision 398)
@@ -0,0 +1,18 @@
+#include <features.h>
+
+#define START "_start"
+
+#include "crt_arch.h"
+
+int main();
+void _init() __attribute__((weak));
+void _fini() __attribute__((weak));
+_Noreturn int __libc_start_main(int (*)(), int, char **,
+	void (*)(), void(*)(), void(*)());
+
+void _start_c(long *p)
+{
+	int argc = p[0];
+	char **argv = (void *)(p+1);
+	__libc_start_main(main, argc, argv, _init, _fini, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/rcrt1.~c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/rcrt1.~c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/rcrt1.~c	(revision 398)
@@ -0,0 +1,15 @@
+#define START "_start"
+#define _dlstart_c _start_c
+#include "../ldso/dlstart.c"
+
+int main();
+void _init() __attribute__((weak));
+void _fini() __attribute__((weak));
+_Noreturn int __libc_start_main(int (*)(), int, char **,
+	void (*)(), void(*)(), void(*)());
+
+__attribute__((__visibility__("hidden")))
+_Noreturn void __dls2(unsigned char *base, size_t *sp)
+{
+	__libc_start_main(main, *sp, (void *)(sp+1), _init, _fini, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/rx/crti.s
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/rx/crti.s	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/rx/crti.s	(revision 398)
@@ -0,0 +1,27 @@
+.section .init
+.global  _init
+.type    _init, @function
+_init:
+	mov.l   #0, r14
+	cmp     #0, r14
+	beq.b   break1
+	mov.l   #0, r1
+	mov.l   #4, r2
+break1:
+	jsr     r14
+	mov.l   #0, r1
+	mov.l   [r1], r14
+	cmp     #0, r14
+	beq.b   end
+	mov.l   #0, r14
+	cmp     #0, r14
+	beq.s   end
+	jsr     r14
+end:
+	nop
+
+.section .fini
+.global  _fini
+.type    _fini, @function
+_fini:
+	nop
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/rx/crtn.s
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/rx/crtn.s	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/crt/rx/crtn.s	(revision 398)
@@ -0,0 +1,21 @@
+.section .init
+	mov.l   #0, r14
+	cmp     #0, r14
+	beq.b   break1
+	mov.l   #0, r1
+	mov.l   #4, r2
+break1:
+	jsr     r14
+	mov.l   #0, r1
+	mov.l   [r1], r14
+	cmp     #0, r14
+	beq.b   end
+	mov.l   #0, r14
+	cmp     #0, r14
+	beq.s   end
+	jsr     r14
+end:
+	rts
+
+.section .fini
+	rts
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/aio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/aio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/aio.h	(revision 398)
@@ -0,0 +1,69 @@
+#ifndef _AIO_H
+#define _AIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <signal.h>
+#include <time.h>
+
+#define __NEED_ssize_t
+#define __NEED_off_t
+
+#include <bits/alltypes.h>
+
+struct aiocb {
+	int aio_fildes, aio_lio_opcode, aio_reqprio;
+	volatile void *aio_buf;
+	size_t aio_nbytes;
+	struct sigevent aio_sigevent;
+	void *__td;
+	int __lock[2];
+	volatile int __err;
+	ssize_t __ret;
+	off_t aio_offset;
+	void *__next, *__prev;
+	char __dummy4[32-2*sizeof(void *)];
+};
+
+#define AIO_CANCELED 0
+#define AIO_NOTCANCELED 1
+#define AIO_ALLDONE 2
+
+#define LIO_READ 0
+#define LIO_WRITE 1
+#define LIO_NOP 2
+
+#define LIO_WAIT 0
+#define LIO_NOWAIT 1
+
+int aio_read(struct aiocb *);
+int aio_write(struct aiocb *);
+int aio_error(const struct aiocb *);
+ssize_t aio_return(struct aiocb *);
+int aio_cancel(int, struct aiocb *);
+int aio_suspend(const struct aiocb *const [], int, const struct timespec *);
+int aio_fsync(int, struct aiocb *);
+
+int lio_listio(int, struct aiocb *__restrict const *__restrict, int, struct sigevent *__restrict);
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define aiocb64 aiocb
+#define aio_read64 aio_read
+#define aio_write64 aio_write
+#define aio_error64 aio_error
+#define aio_return64 aio_return
+#define aio_cancel64 aio_cancel
+#define aio_suspend64 aio_suspend
+#define aio_fsync64 aio_fsync
+#define lio_listio64 lio_listio
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/alloca.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/alloca.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/alloca.h	(revision 398)
@@ -0,0 +1,21 @@
+#ifndef	_ALLOCA_H
+#define	_ALLOCA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	__NEED_size_t
+#include <bits/alltypes.h>
+
+void *alloca(size_t);
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ar.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ar.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ar.h	(revision 398)
@@ -0,0 +1,25 @@
+#ifndef _AR_H
+#define _AR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+#define ARFMAG "`\n"
+
+struct ar_hdr {
+	char ar_name[16];
+	char ar_date[12];
+	char ar_uid[6], ar_gid[6];
+	char ar_mode[8];
+	char ar_size[10];
+	char ar_fmag[2];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/ftp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/ftp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/ftp.h	(revision 398)
@@ -0,0 +1,35 @@
+#ifndef _ARPA_FTP_H
+#define _ARPA_FTP_H
+#define PRELIM 1
+#define COMPLETE 2
+#define CONTINUE 3
+#define TRANSIENT 4
+#define ERROR 5
+#define TYPE_A 1
+#define TYPE_E 2
+#define TYPE_I 3
+#define TYPE_L 4
+#define FORM_N 1
+#define FORM_T 2
+#define FORM_C 3
+#define STRU_F 1
+#define STRU_R 2
+#define STRU_P 3
+#define MODE_S 1
+#define MODE_B 2
+#define MODE_C 3
+#define REC_ESC '\377'
+#define REC_EOR '\001'
+#define REC_EOF '\002'
+#define BLK_EOR 0x80
+#define BLK_EOF 0x40
+#define BLK_ERRORS 0x20
+#define BLK_RESTART 0x10
+#define BLK_BYTECOUNT 2
+#ifdef FTP_NAMES
+char *modenames[] =  {"0", "Stream", "Block", "Compressed" };
+char *strunames[] =  {"0", "File", "Record", "Page" };
+char *typenames[] =  {"0", "ASCII", "EBCDIC", "Image", "Local" };
+char *formnames[] =  {"0", "Nonprint", "Telnet", "Carriage-control" };
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/inet.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/inet.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/inet.h	(revision 398)
@@ -0,0 +1,36 @@
+#ifndef _ARPA_INET_H
+#define	_ARPA_INET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+
+in_addr_t inet_addr (const char *);
+in_addr_t inet_network (const char *);
+char *inet_ntoa (struct in_addr);
+int inet_pton (int, const char *__restrict, void *__restrict);
+const char *inet_ntop (int, const void *__restrict, char *__restrict, socklen_t);
+
+int inet_aton (const char *, struct in_addr *);
+struct in_addr inet_makeaddr(in_addr_t, in_addr_t);
+in_addr_t inet_lnaof(struct in_addr);
+in_addr_t inet_netof(struct in_addr);
+
+#undef INET_ADDRSTRLEN
+#undef INET6_ADDRSTRLEN
+#define INET_ADDRSTRLEN  16
+#define INET6_ADDRSTRLEN 46
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/nameser.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/nameser.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/nameser.h	(revision 398)
@@ -0,0 +1,455 @@
+#ifndef _ARPA_NAMESER_H
+#define _ARPA_NAMESER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define __NAMESER	19991006
+#define NS_PACKETSZ	512
+#define NS_MAXDNAME	1025
+#define NS_MAXMSG	65535
+#define NS_MAXCDNAME	255
+#define NS_MAXLABEL	63
+#define NS_HFIXEDSZ	12
+#define NS_QFIXEDSZ	4
+#define NS_RRFIXEDSZ	10
+#define NS_INT32SZ	4
+#define NS_INT16SZ	2
+#define NS_INT8SZ	1
+#define NS_INADDRSZ	4
+#define NS_IN6ADDRSZ	16
+#define NS_CMPRSFLGS	0xc0
+#define NS_DEFAULTPORT	53
+
+typedef enum __ns_sect {
+	ns_s_qd = 0,
+	ns_s_zn = 0,
+	ns_s_an = 1,
+	ns_s_pr = 1,
+	ns_s_ns = 2,
+	ns_s_ud = 2,
+	ns_s_ar = 3,
+	ns_s_max = 4
+} ns_sect;
+
+typedef struct __ns_msg {
+	const unsigned char *_msg, *_eom;
+	uint16_t _id, _flags, _counts[ns_s_max];
+	const unsigned char *_sections[ns_s_max];
+	ns_sect _sect;
+	int _rrnum;
+	const unsigned char *_msg_ptr;
+} ns_msg;
+
+struct _ns_flagdata {  int mask, shift;  };
+extern const struct _ns_flagdata _ns_flagdata[];
+
+#define ns_msg_id(handle) ((handle)._id + 0)
+#define ns_msg_base(handle) ((handle)._msg + 0)
+#define ns_msg_end(handle) ((handle)._eom + 0)
+#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
+#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
+#define ns_msg_getflag(handle, flag) \
+	(((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
+
+typedef	struct __ns_rr {
+	char		name[NS_MAXDNAME];
+	uint16_t	type;
+	uint16_t	rr_class;
+	uint32_t	ttl;
+	uint16_t	rdlength;
+	const unsigned char *rdata;
+} ns_rr;
+
+#define ns_rr_name(rr)	(((rr).name[0] != '\0') ? (rr).name : ".")
+#define ns_rr_type(rr)	((ns_type)((rr).type + 0))
+#define ns_rr_class(rr)	((ns_class)((rr).rr_class + 0))
+#define ns_rr_ttl(rr)	((rr).ttl + 0)
+#define ns_rr_rdlen(rr)	((rr).rdlength + 0)
+#define ns_rr_rdata(rr)	((rr).rdata + 0)
+
+typedef enum __ns_flag {
+	ns_f_qr,
+	ns_f_opcode,
+	ns_f_aa,
+	ns_f_tc,
+	ns_f_rd,
+	ns_f_ra,
+	ns_f_z,
+	ns_f_ad,
+	ns_f_cd,
+	ns_f_rcode,
+	ns_f_max
+} ns_flag;
+
+typedef enum __ns_opcode {
+	ns_o_query = 0,
+	ns_o_iquery = 1,
+	ns_o_status = 2,
+	ns_o_notify = 4,
+	ns_o_update = 5,
+	ns_o_max = 6
+} ns_opcode;
+
+typedef	enum __ns_rcode {
+	ns_r_noerror = 0,
+	ns_r_formerr = 1,
+	ns_r_servfail = 2,
+	ns_r_nxdomain = 3,
+	ns_r_notimpl = 4,
+	ns_r_refused = 5,
+	ns_r_yxdomain = 6,
+	ns_r_yxrrset = 7,
+	ns_r_nxrrset = 8,
+	ns_r_notauth = 9,
+	ns_r_notzone = 10,
+	ns_r_max = 11,
+	ns_r_badvers = 16,
+	ns_r_badsig = 16,
+	ns_r_badkey = 17,
+	ns_r_badtime = 18
+} ns_rcode;
+
+typedef enum __ns_update_operation {
+	ns_uop_delete = 0,
+	ns_uop_add = 1,
+	ns_uop_max = 2
+} ns_update_operation;
+
+struct ns_tsig_key {
+        char name[NS_MAXDNAME], alg[NS_MAXDNAME];
+        unsigned char *data;
+        int len;
+};
+typedef struct ns_tsig_key ns_tsig_key;
+
+struct ns_tcp_tsig_state {
+	int counter;
+	struct dst_key *key;
+	void *ctx;
+	unsigned char sig[NS_PACKETSZ];
+	int siglen;
+};
+typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
+
+#define NS_TSIG_FUDGE 300
+#define NS_TSIG_TCP_COUNT 100
+#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
+
+#define NS_TSIG_ERROR_NO_TSIG -10
+#define NS_TSIG_ERROR_NO_SPACE -11
+#define NS_TSIG_ERROR_FORMERR -12
+
+typedef enum __ns_type {
+	ns_t_invalid = 0,
+	ns_t_a = 1,
+	ns_t_ns = 2,
+	ns_t_md = 3,
+	ns_t_mf = 4,
+	ns_t_cname = 5,
+	ns_t_soa = 6,
+	ns_t_mb = 7,
+	ns_t_mg = 8,
+	ns_t_mr = 9,
+	ns_t_null = 10,
+	ns_t_wks = 11,
+	ns_t_ptr = 12,
+	ns_t_hinfo = 13,
+	ns_t_minfo = 14,
+	ns_t_mx = 15,
+	ns_t_txt = 16,
+	ns_t_rp = 17,
+	ns_t_afsdb = 18,
+	ns_t_x25 = 19,
+	ns_t_isdn = 20,
+	ns_t_rt = 21,
+	ns_t_nsap = 22,
+	ns_t_nsap_ptr = 23,
+	ns_t_sig = 24,
+	ns_t_key = 25,
+	ns_t_px = 26,
+	ns_t_gpos = 27,
+	ns_t_aaaa = 28,
+	ns_t_loc = 29,
+	ns_t_nxt = 30,
+	ns_t_eid = 31,
+	ns_t_nimloc = 32,
+	ns_t_srv = 33,
+	ns_t_atma = 34,
+	ns_t_naptr = 35,
+	ns_t_kx = 36,
+	ns_t_cert = 37,
+	ns_t_a6 = 38,
+	ns_t_dname = 39,
+	ns_t_sink = 40,
+	ns_t_opt = 41,
+	ns_t_apl = 42,
+	ns_t_tkey = 249,
+	ns_t_tsig = 250,
+	ns_t_ixfr = 251,
+	ns_t_axfr = 252,
+	ns_t_mailb = 253,
+	ns_t_maila = 254,
+	ns_t_any = 255,
+	ns_t_zxfr = 256,
+	ns_t_max = 65536
+} ns_type;
+
+#define	ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
+		      (t) == ns_t_mailb || (t) == ns_t_maila)
+#define	ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
+#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
+#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
+#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
+		       (t) == ns_t_zxfr)
+
+typedef enum __ns_class {
+	ns_c_invalid = 0,
+	ns_c_in = 1,
+	ns_c_2 = 2,
+	ns_c_chaos = 3,
+	ns_c_hs = 4,
+	ns_c_none = 254,
+	ns_c_any = 255,
+	ns_c_max = 65536
+} ns_class;
+
+typedef enum __ns_key_types {
+	ns_kt_rsa = 1,
+	ns_kt_dh  = 2,
+	ns_kt_dsa = 3,
+	ns_kt_private = 254
+} ns_key_types;
+
+typedef enum __ns_cert_types {
+	cert_t_pkix = 1,
+	cert_t_spki = 2,
+	cert_t_pgp  = 3,
+	cert_t_url  = 253,
+	cert_t_oid  = 254
+} ns_cert_types;
+
+#define	NS_KEY_TYPEMASK		0xC000
+#define	NS_KEY_TYPE_AUTH_CONF	0x0000
+#define	NS_KEY_TYPE_CONF_ONLY	0x8000
+#define	NS_KEY_TYPE_AUTH_ONLY	0x4000
+#define	NS_KEY_TYPE_NO_KEY	0xC000
+#define	NS_KEY_NO_AUTH		0x8000
+#define	NS_KEY_NO_CONF		0x4000
+#define	NS_KEY_RESERVED2	0x2000
+#define	NS_KEY_EXTENDED_FLAGS	0x1000
+#define	NS_KEY_RESERVED4	0x0800
+#define	NS_KEY_RESERVED5	0x0400
+#define	NS_KEY_NAME_TYPE	0x0300
+#define	NS_KEY_NAME_USER	0x0000
+#define	NS_KEY_NAME_ENTITY	0x0200
+#define	NS_KEY_NAME_ZONE	0x0100
+#define	NS_KEY_NAME_RESERVED	0x0300
+#define	NS_KEY_RESERVED8	0x0080
+#define	NS_KEY_RESERVED9	0x0040
+#define	NS_KEY_RESERVED10	0x0020
+#define	NS_KEY_RESERVED11	0x0010
+#define	NS_KEY_SIGNATORYMASK	0x000F
+#define	NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
+				  NS_KEY_RESERVED4 | \
+				  NS_KEY_RESERVED5 | \
+				  NS_KEY_RESERVED8 | \
+				  NS_KEY_RESERVED9 | \
+				  NS_KEY_RESERVED10 | \
+				  NS_KEY_RESERVED11 )
+#define NS_KEY_RESERVED_BITMASK2 0xFFFF
+#define	NS_ALG_MD5RSA		1
+#define	NS_ALG_DH               2
+#define	NS_ALG_DSA              3
+#define	NS_ALG_DSS              NS_ALG_DSA
+#define	NS_ALG_EXPIRE_ONLY	253
+#define	NS_ALG_PRIVATE_OID	254
+
+#define NS_KEY_PROT_TLS         1
+#define NS_KEY_PROT_EMAIL       2
+#define NS_KEY_PROT_DNSSEC      3
+#define NS_KEY_PROT_IPSEC       4
+#define NS_KEY_PROT_ANY		255
+
+#define	NS_MD5RSA_MIN_BITS	 512
+#define	NS_MD5RSA_MAX_BITS	4096
+#define	NS_MD5RSA_MAX_BYTES	((NS_MD5RSA_MAX_BITS+7/8)*2+3)
+#define	NS_MD5RSA_MAX_BASE64	(((NS_MD5RSA_MAX_BYTES+2)/3)*4)
+#define NS_MD5RSA_MIN_SIZE	((NS_MD5RSA_MIN_BITS+7)/8)
+#define NS_MD5RSA_MAX_SIZE	((NS_MD5RSA_MAX_BITS+7)/8)
+
+#define NS_DSA_SIG_SIZE         41
+#define NS_DSA_MIN_SIZE         213
+#define NS_DSA_MAX_BYTES        405
+
+#define	NS_SIG_TYPE	0
+#define	NS_SIG_ALG	2
+#define	NS_SIG_LABELS	3
+#define	NS_SIG_OTTL	4
+#define	NS_SIG_EXPIR	8
+#define	NS_SIG_SIGNED	12
+#define	NS_SIG_FOOT	16
+#define	NS_SIG_SIGNER	18
+#define	NS_NXT_BITS 8
+#define	NS_NXT_BIT_SET(  n,p) (p[(n)/NS_NXT_BITS] |=  (0x80>>((n)%NS_NXT_BITS)))
+#define	NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
+#define	NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] &   (0x80>>((n)%NS_NXT_BITS)))
+#define NS_NXT_MAX 127
+
+#define NS_OPT_DNSSEC_OK        0x8000U
+#define NS_OPT_NSID		3
+
+#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp)+=2)-2))
+#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp)+=4)-4))
+#define NS_PUT16(s, cp) ns_put16((s), ((cp)+=2)-2)
+#define NS_PUT32(l, cp) ns_put32((l), ((cp)+=4)-4)
+
+unsigned ns_get16(const unsigned char *);
+unsigned long ns_get32(const unsigned char *);
+void ns_put16(unsigned, unsigned char *);
+void ns_put32(unsigned long, unsigned char *);
+
+int ns_initparse(const unsigned char *, int, ns_msg *);
+int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
+int ns_skiprr(const unsigned char *, const unsigned char *, ns_sect, int);
+int ns_name_uncompress(const unsigned char *, const unsigned char *, const unsigned char *, char *, size_t);
+
+
+#define	__BIND		19950621
+
+typedef struct {
+	unsigned	id :16;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	unsigned	qr: 1;
+	unsigned	opcode: 4;
+	unsigned	aa: 1;
+	unsigned	tc: 1;
+	unsigned	rd: 1;
+	unsigned	ra: 1;
+	unsigned	unused :1;
+	unsigned	ad: 1;
+	unsigned	cd: 1;
+	unsigned	rcode :4;
+#else
+	unsigned	rd :1;
+	unsigned	tc :1;
+	unsigned	aa :1;
+	unsigned	opcode :4;
+	unsigned	qr :1;
+	unsigned	rcode :4;
+	unsigned	cd: 1;
+	unsigned	ad: 1;
+	unsigned	unused :1;
+	unsigned	ra :1;
+#endif
+	unsigned	qdcount :16;
+	unsigned	ancount :16;
+	unsigned	nscount :16;
+	unsigned	arcount :16;
+} HEADER;
+
+#define PACKETSZ	NS_PACKETSZ
+#define MAXDNAME	NS_MAXDNAME
+#define MAXCDNAME	NS_MAXCDNAME
+#define MAXLABEL	NS_MAXLABEL
+#define	HFIXEDSZ	NS_HFIXEDSZ
+#define QFIXEDSZ	NS_QFIXEDSZ
+#define RRFIXEDSZ	NS_RRFIXEDSZ
+#define	INT32SZ		NS_INT32SZ
+#define	INT16SZ		NS_INT16SZ
+#define INT8SZ		NS_INT8SZ
+#define	INADDRSZ	NS_INADDRSZ
+#define	IN6ADDRSZ	NS_IN6ADDRSZ
+#define	INDIR_MASK	NS_CMPRSFLGS
+#define NAMESERVER_PORT	NS_DEFAULTPORT
+
+#define S_ZONE		ns_s_zn
+#define S_PREREQ	ns_s_pr
+#define S_UPDATE	ns_s_ud
+#define S_ADDT		ns_s_ar
+
+#define QUERY		ns_o_query
+#define IQUERY		ns_o_iquery
+#define STATUS		ns_o_status
+#define	NS_NOTIFY_OP	ns_o_notify
+#define	NS_UPDATE_OP	ns_o_update
+
+#define NOERROR		ns_r_noerror
+#define FORMERR		ns_r_formerr
+#define SERVFAIL	ns_r_servfail
+#define NXDOMAIN	ns_r_nxdomain
+#define NOTIMP		ns_r_notimpl
+#define REFUSED		ns_r_refused
+#define YXDOMAIN	ns_r_yxdomain
+#define YXRRSET		ns_r_yxrrset
+#define NXRRSET		ns_r_nxrrset
+#define NOTAUTH		ns_r_notauth
+#define NOTZONE		ns_r_notzone
+
+#define DELETE		ns_uop_delete
+#define ADD		ns_uop_add
+
+#define T_A		ns_t_a
+#define T_NS		ns_t_ns
+#define T_MD		ns_t_md
+#define T_MF		ns_t_mf
+#define T_CNAME		ns_t_cname
+#define T_SOA		ns_t_soa
+#define T_MB		ns_t_mb
+#define T_MG		ns_t_mg
+#define T_MR		ns_t_mr
+#define T_NULL		ns_t_null
+#define T_WKS		ns_t_wks
+#define T_PTR		ns_t_ptr
+#define T_HINFO		ns_t_hinfo
+#define T_MINFO		ns_t_minfo
+#define T_MX		ns_t_mx
+#define T_TXT		ns_t_txt
+#define	T_RP		ns_t_rp
+#define T_AFSDB		ns_t_afsdb
+#define T_X25		ns_t_x25
+#define T_ISDN		ns_t_isdn
+#define T_RT		ns_t_rt
+#define T_NSAP		ns_t_nsap
+#define T_NSAP_PTR	ns_t_nsap_ptr
+#define	T_SIG		ns_t_sig
+#define	T_KEY		ns_t_key
+#define	T_PX		ns_t_px
+#define	T_GPOS		ns_t_gpos
+#define	T_AAAA		ns_t_aaaa
+#define	T_LOC		ns_t_loc
+#define	T_NXT		ns_t_nxt
+#define	T_EID		ns_t_eid
+#define	T_NIMLOC	ns_t_nimloc
+#define	T_SRV		ns_t_srv
+#define T_ATMA		ns_t_atma
+#define T_NAPTR		ns_t_naptr
+#define T_A6		ns_t_a6
+#define T_DNAME		ns_t_dname
+#define	T_TSIG		ns_t_tsig
+#define	T_IXFR		ns_t_ixfr
+#define T_AXFR		ns_t_axfr
+#define T_MAILB		ns_t_mailb
+#define T_MAILA		ns_t_maila
+#define T_ANY		ns_t_any
+
+#define C_IN		ns_c_in
+#define C_CHAOS		ns_c_chaos
+#define C_HS		ns_c_hs
+#define C_NONE		ns_c_none
+#define C_ANY		ns_c_any
+
+#define	GETSHORT		NS_GET16
+#define	GETLONG			NS_GET32
+#define	PUTSHORT		NS_PUT16
+#define	PUTLONG			NS_PUT32
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/nameser_compat.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/nameser_compat.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/nameser_compat.h	(revision 398)
@@ -0,0 +1,2 @@
+#include <arpa/nameser.h>
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/telnet.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/telnet.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/telnet.h	(revision 398)
@@ -0,0 +1,251 @@
+#ifndef _ARPA_TELNET_H
+#define	_ARPA_TELNET_H
+
+#define	IAC	255
+#define	DONT	254
+#define	DO	253
+#define	WONT	252
+#define	WILL	251
+#define	SB	250
+#define	GA	249
+#define	EL	248
+#define	EC	247
+#define	AYT	246
+#define	AO	245
+#define	IP	244
+#define	BREAK	243
+#define	DM	242
+#define	NOP	241
+#define	SE	240
+#define EOR     239
+#define	ABORT	238
+#define	SUSP	237
+#define	xEOF	236
+
+#define SYNCH	242
+
+#define telcmds ((char [][6]){ "EOF", "SUSP", "ABORT", "EOR", "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0 })
+
+#define	TELCMD_FIRST	xEOF
+#define	TELCMD_LAST	IAC
+#define	TELCMD_OK(x)	((unsigned int)(x) <= TELCMD_LAST && \
+			 (unsigned int)(x) >= TELCMD_FIRST)
+#define	TELCMD(x)	telcmds[(x)-TELCMD_FIRST]
+
+#define TELOPT_BINARY	0
+#define TELOPT_ECHO	1
+#define	TELOPT_RCP	2
+#define	TELOPT_SGA	3
+#define	TELOPT_NAMS	4
+#define	TELOPT_STATUS	5
+#define	TELOPT_TM	6
+#define	TELOPT_RCTE	7
+#define TELOPT_NAOL 	8
+#define TELOPT_NAOP 	9
+#define TELOPT_NAOCRD	10
+#define TELOPT_NAOHTS	11
+#define TELOPT_NAOHTD	12
+#define TELOPT_NAOFFD	13
+#define TELOPT_NAOVTS	14
+#define TELOPT_NAOVTD	15
+#define TELOPT_NAOLFD	16
+#define TELOPT_XASCII	17
+#define	TELOPT_LOGOUT	18
+#define	TELOPT_BM	19
+#define	TELOPT_DET	20
+#define	TELOPT_SUPDUP	21
+#define	TELOPT_SUPDUPOUTPUT 22
+#define	TELOPT_SNDLOC	23
+#define	TELOPT_TTYPE	24
+#define	TELOPT_EOR	25
+#define	TELOPT_TUID	26
+#define	TELOPT_OUTMRK	27
+#define	TELOPT_TTYLOC	28
+#define	TELOPT_3270REGIME 29
+#define	TELOPT_X3PAD	30
+#define	TELOPT_NAWS	31
+#define	TELOPT_TSPEED	32
+#define	TELOPT_LFLOW	33
+#define TELOPT_LINEMODE	34
+#define TELOPT_XDISPLOC	35
+#define TELOPT_OLD_ENVIRON 36
+#define	TELOPT_AUTHENTICATION 37/* Authenticate */
+#define	TELOPT_ENCRYPT	38
+#define TELOPT_NEW_ENVIRON 39
+#define	TELOPT_EXOPL	255
+
+
+#define	NTELOPTS	(1+TELOPT_NEW_ENVIRON)
+#ifdef TELOPTS
+char *telopts[NTELOPTS+1] = {
+	"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
+	"STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
+	"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
+	"NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
+	"DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
+	"SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
+	"TACACS UID", "OUTPUT MARKING", "TTYLOC",
+	"3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
+	"LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
+	"ENCRYPT", "NEW-ENVIRON",
+	0,
+};
+#define	TELOPT_FIRST	TELOPT_BINARY
+#define	TELOPT_LAST	TELOPT_NEW_ENVIRON
+#define	TELOPT_OK(x)	((unsigned int)(x) <= TELOPT_LAST)
+#define	TELOPT(x)	telopts[(x)-TELOPT_FIRST]
+#endif
+
+#define	TELQUAL_IS	0
+#define	TELQUAL_SEND	1
+#define	TELQUAL_INFO	2
+#define	TELQUAL_REPLY	2
+#define	TELQUAL_NAME	3
+
+#define	LFLOW_OFF		0
+#define	LFLOW_ON		1
+#define	LFLOW_RESTART_ANY	2
+#define	LFLOW_RESTART_XON	3
+
+
+#define	LM_MODE		1
+#define	LM_FORWARDMASK	2
+#define	LM_SLC		3
+
+#define	MODE_EDIT	0x01
+#define	MODE_TRAPSIG	0x02
+#define	MODE_ACK	0x04
+#define MODE_SOFT_TAB	0x08
+#define MODE_LIT_ECHO	0x10
+
+#define	MODE_MASK	0x1f
+
+#define MODE_FLOW		0x0100
+#define MODE_ECHO		0x0200
+#define MODE_INBIN		0x0400
+#define MODE_OUTBIN		0x0800
+#define MODE_FORCE		0x1000
+
+#define	SLC_SYNCH	1
+#define	SLC_BRK		2
+#define	SLC_IP		3
+#define	SLC_AO		4
+#define	SLC_AYT		5
+#define	SLC_EOR		6
+#define	SLC_ABORT	7
+#define	SLC_EOF		8
+#define	SLC_SUSP	9
+#define	SLC_EC		10
+#define	SLC_EL		11
+#define	SLC_EW		12
+#define	SLC_RP		13
+#define	SLC_LNEXT	14
+#define	SLC_XON		15
+#define	SLC_XOFF	16
+#define	SLC_FORW1	17
+#define	SLC_FORW2	18
+
+#define	NSLC		18
+
+#define	SLC_NAMELIST	"0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
+			"ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
+			"LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
+#ifdef	SLC_NAMES
+char *slc_names[] = {
+	SLC_NAMELIST
+};
+#else
+extern char *slc_names[];
+#define	SLC_NAMES SLC_NAMELIST
+#endif
+
+#define	SLC_NAME_OK(x)	((unsigned int)(x) <= NSLC)
+#define SLC_NAME(x)	slc_names[x]
+
+#define	SLC_NOSUPPORT	0
+#define	SLC_CANTCHANGE	1
+#define	SLC_VARIABLE	2
+#define	SLC_DEFAULT	3
+#define	SLC_LEVELBITS	0x03
+
+#define	SLC_FUNC	0
+#define	SLC_FLAGS	1
+#define	SLC_VALUE	2
+
+#define	SLC_ACK		0x80
+#define	SLC_FLUSHIN	0x40
+#define	SLC_FLUSHOUT	0x20
+
+#define	OLD_ENV_VAR	1
+#define	OLD_ENV_VALUE	0
+#define	NEW_ENV_VAR	0
+#define	NEW_ENV_VALUE	1
+#define	ENV_ESC		2
+#define ENV_USERVAR	3
+
+#define	AUTH_WHO_CLIENT		0
+#define	AUTH_WHO_SERVER		1
+#define	AUTH_WHO_MASK		1
+
+#define	AUTH_HOW_ONE_WAY	0
+#define	AUTH_HOW_MUTUAL		2
+#define	AUTH_HOW_MASK		2
+
+#define	AUTHTYPE_NULL		0
+#define	AUTHTYPE_KERBEROS_V4	1
+#define	AUTHTYPE_KERBEROS_V5	2
+#define	AUTHTYPE_SPX		3
+#define	AUTHTYPE_MINK		4
+#define	AUTHTYPE_CNT		5
+
+#define	AUTHTYPE_TEST		99
+
+#ifdef	AUTH_NAMES
+char *authtype_names[] = {
+	"NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
+};
+#else
+extern char *authtype_names[];
+#endif
+
+#define	AUTHTYPE_NAME_OK(x)	((unsigned int)(x) < AUTHTYPE_CNT)
+#define	AUTHTYPE_NAME(x)	authtype_names[x]
+
+#define	ENCRYPT_IS		0
+#define	ENCRYPT_SUPPORT		1
+#define	ENCRYPT_REPLY		2
+#define	ENCRYPT_START		3
+#define	ENCRYPT_END		4
+#define	ENCRYPT_REQSTART	5
+#define	ENCRYPT_REQEND		6
+#define	ENCRYPT_ENC_KEYID	7
+#define	ENCRYPT_DEC_KEYID	8
+#define	ENCRYPT_CNT		9
+
+#define	ENCTYPE_ANY		0
+#define	ENCTYPE_DES_CFB64	1
+#define	ENCTYPE_DES_OFB64	2
+#define	ENCTYPE_CNT		3
+
+#ifdef	ENCRYPT_NAMES
+char *encrypt_names[] = {
+	"IS", "SUPPORT", "REPLY", "START", "END",
+	"REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
+	0,
+};
+char *enctype_names[] = {
+	"ANY", "DES_CFB64",  "DES_OFB64",  0,
+};
+#else
+extern char *encrypt_names[];
+extern char *enctype_names[];
+#endif
+
+
+#define	ENCRYPT_NAME_OK(x)	((unsigned int)(x) < ENCRYPT_CNT)
+#define	ENCRYPT_NAME(x)		encrypt_names[x]
+
+#define	ENCTYPE_NAME_OK(x)	((unsigned int)(x) < ENCTYPE_CNT)
+#define	ENCTYPE_NAME(x)		enctype_names[x]
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/tftp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/tftp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/arpa/tftp.h	(revision 398)
@@ -0,0 +1,31 @@
+#ifndef _ARPA_TFTP_H
+#define _ARPA_TFTP_H
+#define SEGSIZE 512
+#define RRQ 01
+#define WRQ 02
+#define DATA 03
+#define ACK 04
+#define ERROR 05
+struct tftphdr {
+	short th_opcode;
+	union {
+		unsigned short tu_block;
+		short tu_code;
+		char tu_stuff[1];
+	} th_u;
+	char th_data[1];
+};
+#define th_block th_u.tu_block
+#define th_code th_u.tu_code
+#define th_stuff th_u.tu_stuff
+#define th_msg th_data
+#define EUNDEF 0
+#define ENOTFOUND 1
+#define EACCESS 2
+#define ENOSPACE 3
+#define EBADOP 4
+#define EBADID 5
+#define EEXISTS 6
+#define ENOUSER 7
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/assert.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/assert.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/assert.h	(revision 398)
@@ -0,0 +1,23 @@
+#include <features.h>
+
+#undef assert
+
+#ifdef NDEBUG
+#define	assert(x) (void)0
+#else
+#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__),0)))
+#endif
+
+#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
+#define static_assert _Static_assert
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_Noreturn void __assert_fail (const char *, const char *, int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/alltypes.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/alltypes.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/alltypes.h	(revision 398)
@@ -0,0 +1,385 @@
+#define _Addr int
+#define _Int64 long long
+#define _Reg int
+
+#if defined(__NEED_va_list) && !defined(__DEFINED_va_list)
+typedef __builtin_va_list va_list;
+#define __DEFINED_va_list
+#endif
+
+#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list)
+typedef __builtin_va_list __isoc_va_list;
+#define __DEFINED___isoc_va_list
+#endif
+
+
+#ifndef __cplusplus
+#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
+typedef unsigned wchar_t;
+#define __DEFINED_wchar_t
+#endif
+
+#endif
+
+#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
+typedef float float_t;
+#define __DEFINED_float_t
+#endif
+
+#if defined(__NEED_double_t) && !defined(__DEFINED_double_t)
+typedef double double_t;
+#define __DEFINED_double_t
+#endif
+
+
+#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
+typedef struct { long long __ll; long double __ld; } max_align_t;
+#define __DEFINED_max_align_t
+#endif
+
+
+#if defined(__NEED_time_t) && !defined(__DEFINED_time_t)
+typedef long time_t;
+#define __DEFINED_time_t
+#endif
+
+#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t)
+typedef long suseconds_t;
+#define __DEFINED_suseconds_t
+#endif
+
+
+#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t)
+typedef struct { union { int __i[9]; volatile int __vi[9]; unsigned __s[9]; } __u; } pthread_attr_t;
+#define __DEFINED_pthread_attr_t
+#endif
+
+#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t)
+typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
+#define __DEFINED_pthread_mutex_t
+#endif
+
+#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t)
+typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
+#define __DEFINED_mtx_t
+#endif
+
+#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t)
+typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } pthread_cond_t;
+#define __DEFINED_pthread_cond_t
+#endif
+
+#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t)
+typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } cnd_t;
+#define __DEFINED_cnd_t
+#endif
+
+#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t)
+typedef struct { union { int __i[8]; volatile int __vi[8]; void *__p[8]; } __u; } pthread_rwlock_t;
+#define __DEFINED_pthread_rwlock_t
+#endif
+
+#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t)
+typedef struct { union { int __i[5]; volatile int __vi[5]; void *__p[5]; } __u; } pthread_barrier_t;
+#define __DEFINED_pthread_barrier_t
+#endif
+
+#if defined(__NEED_size_t) && !defined(__DEFINED_size_t)
+typedef unsigned _Addr size_t;
+#define __DEFINED_size_t
+#endif
+
+#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t)
+typedef unsigned _Addr uintptr_t;
+#define __DEFINED_uintptr_t
+#endif
+
+#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t)
+typedef _Addr ptrdiff_t;
+#define __DEFINED_ptrdiff_t
+#endif
+
+#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t)
+typedef _Addr ssize_t;
+#define __DEFINED_ssize_t
+#endif
+
+#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t)
+typedef _Addr intptr_t;
+#define __DEFINED_intptr_t
+#endif
+
+#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t)
+typedef _Addr regoff_t;
+#define __DEFINED_regoff_t
+#endif
+
+#if defined(__NEED_register_t) && !defined(__DEFINED_register_t)
+typedef _Reg register_t;
+#define __DEFINED_register_t
+#endif
+
+
+#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t)
+typedef signed char     int8_t;
+#define __DEFINED_int8_t
+#endif
+
+#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t)
+typedef short           int16_t;
+#define __DEFINED_int16_t
+#endif
+
+#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t)
+typedef int             int32_t;
+#define __DEFINED_int32_t
+#endif
+
+#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t)
+typedef _Int64          int64_t;
+#define __DEFINED_int64_t
+#endif
+
+#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t)
+typedef _Int64          intmax_t;
+#define __DEFINED_intmax_t
+#endif
+
+#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t)
+typedef unsigned char   uint8_t;
+#define __DEFINED_uint8_t
+#endif
+
+#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t)
+typedef unsigned short  uint16_t;
+#define __DEFINED_uint16_t
+#endif
+
+#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t)
+typedef unsigned int    uint32_t;
+#define __DEFINED_uint32_t
+#endif
+
+#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t)
+typedef unsigned _Int64 uint64_t;
+#define __DEFINED_uint64_t
+#endif
+
+#if defined(__NEED_u_int64_t) && !defined(__DEFINED_u_int64_t)
+typedef unsigned _Int64 u_int64_t;
+#define __DEFINED_u_int64_t
+#endif
+
+#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t)
+typedef unsigned _Int64 uintmax_t;
+#define __DEFINED_uintmax_t
+#endif
+
+
+#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t)
+typedef unsigned mode_t;
+#define __DEFINED_mode_t
+#endif
+
+#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t)
+typedef unsigned _Reg nlink_t;
+#define __DEFINED_nlink_t
+#endif
+
+#if defined(__NEED_off_t) && !defined(__DEFINED_off_t)
+typedef _Int64 off_t;
+#define __DEFINED_off_t
+#endif
+
+#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t)
+typedef unsigned _Int64 ino_t;
+#define __DEFINED_ino_t
+#endif
+
+#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t)
+typedef unsigned _Int64 dev_t;
+#define __DEFINED_dev_t
+#endif
+
+#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t)
+typedef long blksize_t;
+#define __DEFINED_blksize_t
+#endif
+
+#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t)
+typedef _Int64 blkcnt_t;
+#define __DEFINED_blkcnt_t
+#endif
+
+#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t)
+typedef unsigned _Int64 fsblkcnt_t;
+#define __DEFINED_fsblkcnt_t
+#endif
+
+#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t)
+typedef unsigned _Int64 fsfilcnt_t;
+#define __DEFINED_fsfilcnt_t
+#endif
+
+
+#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t)
+typedef unsigned wint_t;
+#define __DEFINED_wint_t
+#endif
+
+#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t)
+typedef unsigned long wctype_t;
+#define __DEFINED_wctype_t
+#endif
+
+
+#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t)
+typedef void * timer_t;
+#define __DEFINED_timer_t
+#endif
+
+#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t)
+typedef int clockid_t;
+#define __DEFINED_clockid_t
+#endif
+
+#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t)
+typedef long clock_t;
+#define __DEFINED_clock_t
+#endif
+
+#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval)
+struct timeval { time_t tv_sec; suseconds_t tv_usec; };
+#define __DEFINED_struct_timeval
+#endif
+
+#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec)
+struct timespec { time_t tv_sec; long tv_nsec; };
+#define __DEFINED_struct_timespec
+#endif
+
+
+#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t)
+typedef int pid_t;
+#define __DEFINED_pid_t
+#endif
+
+#if defined(__NEED_id_t) && !defined(__DEFINED_id_t)
+typedef unsigned id_t;
+#define __DEFINED_id_t
+#endif
+
+#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t)
+typedef unsigned uid_t;
+#define __DEFINED_uid_t
+#endif
+
+#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t)
+typedef unsigned gid_t;
+#define __DEFINED_gid_t
+#endif
+
+#if defined(__NEED_key_t) && !defined(__DEFINED_key_t)
+typedef int key_t;
+#define __DEFINED_key_t
+#endif
+
+#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t)
+typedef unsigned useconds_t;
+#define __DEFINED_useconds_t
+#endif
+
+
+#ifdef __cplusplus
+#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
+typedef unsigned long pthread_t;
+#define __DEFINED_pthread_t
+#endif
+
+#else
+#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
+typedef struct __pthread * pthread_t;
+#define __DEFINED_pthread_t
+#endif
+
+#endif
+#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t)
+typedef int pthread_once_t;
+#define __DEFINED_pthread_once_t
+#endif
+
+#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t)
+typedef unsigned pthread_key_t;
+#define __DEFINED_pthread_key_t
+#endif
+
+#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t)
+typedef int pthread_spinlock_t;
+#define __DEFINED_pthread_spinlock_t
+#endif
+
+#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t)
+typedef struct { unsigned __attr; } pthread_mutexattr_t;
+#define __DEFINED_pthread_mutexattr_t
+#endif
+
+#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t)
+typedef struct { unsigned __attr; } pthread_condattr_t;
+#define __DEFINED_pthread_condattr_t
+#endif
+
+#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t)
+typedef struct { unsigned __attr; } pthread_barrierattr_t;
+#define __DEFINED_pthread_barrierattr_t
+#endif
+
+#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t)
+typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t;
+#define __DEFINED_pthread_rwlockattr_t
+#endif
+
+
+#if defined(__NEED_FILE) && !defined(__DEFINED_FILE)
+typedef struct _IO_FILE FILE;
+#define __DEFINED_FILE
+#endif
+
+
+#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t)
+typedef struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t;
+#define __DEFINED_mbstate_t
+#endif
+
+
+#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t)
+typedef struct __locale_struct * locale_t;
+#define __DEFINED_locale_t
+#endif
+
+
+#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t)
+typedef struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t;
+#define __DEFINED_sigset_t
+#endif
+
+
+#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec)
+struct iovec { void *iov_base; size_t iov_len; };
+#define __DEFINED_struct_iovec
+#endif
+
+
+#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
+typedef unsigned socklen_t;
+#define __DEFINED_socklen_t
+#endif
+
+#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t)
+typedef unsigned short sa_family_t;
+#define __DEFINED_sa_family_t
+#endif
+
+
+#undef _Addr
+#undef _Int64
+#undef _Reg
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/errno.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/errno.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/errno.h	(revision 398)
@@ -0,0 +1,134 @@
+#define EPERM            1
+#define ENOENT           2
+#define ESRCH            3
+#define EINTR            4
+#define EIO              5
+#define ENXIO            6
+#define E2BIG            7
+#define ENOEXEC          8
+#define EBADF            9
+#define ECHILD          10
+#define EAGAIN          11
+#define ENOMEM          12
+#define EACCES          13
+#define EFAULT          14
+#define ENOTBLK         15
+#define EBUSY           16
+#define EEXIST          17
+#define EXDEV           18
+#define ENODEV          19
+#define ENOTDIR         20
+#define EISDIR          21
+#define EINVAL          22
+#define ENFILE          23
+#define EMFILE          24
+#define ENOTTY          25
+#define ETXTBSY         26
+#define EFBIG           27
+#define ENOSPC          28
+#define ESPIPE          29
+#define EROFS           30
+#define EMLINK          31
+#define EPIPE           32
+#define EDOM            33
+#define ERANGE          34
+#define EDEADLK         35
+#define ENAMETOOLONG    36
+#define ENOLCK          37
+#define ENOSYS          38
+#define ENOTEMPTY       39
+#define ELOOP           40
+#define EWOULDBLOCK     EAGAIN
+#define ENOMSG          42
+#define EIDRM           43
+#define ECHRNG          44
+#define EL2NSYNC        45
+#define EL3HLT          46
+#define EL3RST          47
+#define ELNRNG          48
+#define EUNATCH         49
+#define ENOCSI          50
+#define EL2HLT          51
+#define EBADE           52
+#define EBADR           53
+#define EXFULL          54
+#define ENOANO          55
+#define EBADRQC         56
+#define EBADSLT         57
+#define EDEADLOCK       EDEADLK
+#define EBFONT          59
+#define ENOSTR          60
+#define ENODATA         61
+#define ETIME           62
+#define ENOSR           63
+#define ENONET          64
+#define ENOPKG          65
+#define EREMOTE         66
+#define ENOLINK         67
+#define EADV            68
+#define ESRMNT          69
+#define ECOMM           70
+#define EPROTO          71
+#define EMULTIHOP       72
+#define EDOTDOT         73
+#define EBADMSG         74
+#define EOVERFLOW       75
+#define ENOTUNIQ        76
+#define EBADFD          77
+#define EREMCHG         78
+#define ELIBACC         79
+#define ELIBBAD         80
+#define ELIBSCN         81
+#define ELIBMAX         82
+#define ELIBEXEC        83
+#define EILSEQ          84
+#define ERESTART        85
+#define ESTRPIPE        86
+#define EUSERS          87
+#define ENOTSOCK        88
+#define EDESTADDRREQ    89
+#define EMSGSIZE        90
+#define EPROTOTYPE      91
+#define ENOPROTOOPT     92
+#define EPROTONOSUPPORT 93
+#define ESOCKTNOSUPPORT 94
+#define EOPNOTSUPP      95
+#define ENOTSUP         EOPNOTSUPP
+#define EPFNOSUPPORT    96
+#define EAFNOSUPPORT    97
+#define EADDRINUSE      98
+#define EADDRNOTAVAIL   99
+#define ENETDOWN        100
+#define ENETUNREACH     101
+#define ENETRESET       102
+#define ECONNABORTED    103
+#define ECONNRESET      104
+#define ENOBUFS         105
+#define EISCONN         106
+#define ENOTCONN        107
+#define ESHUTDOWN       108
+#define ETOOMANYREFS    109
+#define ETIMEDOUT       110
+#define ECONNREFUSED    111
+#define EHOSTDOWN       112
+#define EHOSTUNREACH    113
+#define EALREADY        114
+#define EINPROGRESS     115
+#define ESTALE          116
+#define EUCLEAN         117
+#define ENOTNAM         118
+#define ENAVAIL         119
+#define EISNAM          120
+#define EREMOTEIO       121
+#define EDQUOT          122
+#define ENOMEDIUM       123
+#define EMEDIUMTYPE     124
+#define ECANCELED       125
+#define ENOKEY          126
+#define EKEYEXPIRED     127
+#define EKEYREVOKED     128
+#define EKEYREJECTED    129
+#define EOWNERDEAD      130
+#define ENOTRECOVERABLE 131
+#define ERFKILL         132
+#define EHWPOISON       133
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/fcntl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/fcntl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/fcntl.h	(revision 398)
@@ -0,0 +1,40 @@
+#define O_CREAT        0100
+#define O_EXCL         0200
+#define O_NOCTTY       0400
+#define O_TRUNC       01000
+#define O_APPEND      02000
+#define O_NONBLOCK    04000
+#define O_DSYNC      010000
+#define O_SYNC     04010000
+#define O_RSYNC    04010000
+#define O_DIRECTORY 0200000
+#define O_NOFOLLOW  0400000
+#define O_CLOEXEC  02000000
+
+#define O_ASYNC      020000
+#define O_DIRECT     040000
+#define O_LARGEFILE 0100000
+#define O_NOATIME  01000000
+#define O_PATH    010000000
+#define O_TMPFILE 020200000
+#define O_NDELAY O_NONBLOCK
+
+#define F_DUPFD  0
+#define F_GETFD  1
+#define F_SETFD  2
+#define F_GETFL  3
+#define F_SETFL  4
+
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_GETLK 12
+#define F_SETLK 13
+#define F_SETLKW 14
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/fenv.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/fenv.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/fenv.h	(revision 398)
@@ -0,0 +1,10 @@
+#define FE_ALL_EXCEPT 0
+#define FE_TONEAREST  0
+
+typedef unsigned long fexcept_t;
+
+typedef struct {
+	unsigned long __cw;
+} fenv_t;
+
+#define FE_DFL_ENV      ((const fenv_t *) -1)
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/float.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/float.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/float.h	(revision 398)
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_TRUE_MIN 4.94065645841246544177e-324L
+#define LDBL_MIN 2.22507385850720138309e-308L
+#define LDBL_MAX 1.79769313486231570815e+308L
+#define LDBL_EPSILON 2.22044604925031308085e-16L
+
+#define LDBL_MANT_DIG 53
+#define LDBL_MIN_EXP (-1021)
+#define LDBL_MAX_EXP 1024
+
+#define LDBL_DIG 15
+#define LDBL_MIN_10_EXP (-307)
+#define LDBL_MAX_10_EXP 308
+
+#define DECIMAL_DIG 17
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/ioctl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/ioctl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/ioctl.h	(revision 398)
@@ -0,0 +1,204 @@
+#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
+#define _IOC_NONE  0U
+#define _IOC_WRITE 1U
+#define _IOC_READ  2U
+
+#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
+#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
+#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
+#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425
+#define TIOCSBRK	0x5427
+#define TIOCCBRK	0x5428
+#define TIOCGSID	0x5429
+#define TIOCGRS485	0x542E
+#define TIOCSRS485	0x542F
+#define TIOCGPTN	0x80045430
+#define TIOCSPTLCK	0x40045431
+#define TIOCGDEV	0x80045432
+#define TCGETX		0x5432
+#define TCSETX		0x5433
+#define TCSETXF		0x5434
+#define TCSETXW		0x5435
+#define TIOCSIG		0x40045436
+#define TIOCVHANGUP	0x5437
+#define TIOCGPKT	0x80045438
+#define TIOCGPTLCK	0x80045439
+#define TIOCGEXCL	0x80045440
+
+#define FIONCLEX	0x5450
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458
+#define TIOCSERGETLSR   0x5459
+#define TIOCSERGETMULTI 0x545A
+#define TIOCSERSETMULTI 0x545B
+
+#define TIOCMIWAIT	0x545C
+#define TIOCGICOUNT	0x545D
+#define FIOQSIZE	0x5460
+
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+#define TIOCPKT_IOCTL		64
+
+#define TIOCSER_TEMT    0x01
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define TIOCM_LE        0x001
+#define TIOCM_DTR       0x002
+#define TIOCM_RTS       0x004
+#define TIOCM_ST        0x008
+#define TIOCM_SR        0x010
+#define TIOCM_CTS       0x020
+#define TIOCM_CAR       0x040
+#define TIOCM_RNG       0x080
+#define TIOCM_DSR       0x100
+#define TIOCM_CD        TIOCM_CAR
+#define TIOCM_RI        TIOCM_RNG
+#define TIOCM_OUT1      0x2000
+#define TIOCM_OUT2      0x4000
+#define TIOCM_LOOP      0x8000
+
+#define N_TTY           0
+#define N_SLIP          1
+#define N_MOUSE         2
+#define N_PPP           3
+#define N_STRIP         4
+#define N_AX25          5
+#define N_X25           6
+#define N_6PACK         7
+#define N_MASC          8
+#define N_R3964         9
+#define N_PROFIBUS_FDL  10
+#define N_IRDA          11
+#define N_SMSBLOCK      12
+#define N_HDLC          13
+#define N_SYNC_PPP      14
+#define N_HCI           15
+
+#define FIOSETOWN       0x8901
+#define SIOCSPGRP       0x8902
+#define FIOGETOWN       0x8903
+#define SIOCGPGRP       0x8904
+#define SIOCATMARK      0x8905
+#define SIOCGSTAMP      0x8906
+
+#define SIOCADDRT       0x890B
+#define SIOCDELRT       0x890C
+#define SIOCRTMSG       0x890D
+
+#define SIOCGIFNAME     0x8910
+#define SIOCSIFLINK     0x8911
+#define SIOCGIFCONF     0x8912
+#define SIOCGIFFLAGS    0x8913
+#define SIOCSIFFLAGS    0x8914
+#define SIOCGIFADDR     0x8915
+#define SIOCSIFADDR     0x8916
+#define SIOCGIFDSTADDR  0x8917
+#define SIOCSIFDSTADDR  0x8918
+#define SIOCGIFBRDADDR  0x8919
+#define SIOCSIFBRDADDR  0x891a
+#define SIOCGIFNETMASK  0x891b
+#define SIOCSIFNETMASK  0x891c
+#define SIOCGIFMETRIC   0x891d
+#define SIOCSIFMETRIC   0x891e
+#define SIOCGIFMEM      0x891f
+#define SIOCSIFMEM      0x8920
+#define SIOCGIFMTU      0x8921
+#define SIOCSIFMTU      0x8922
+#define SIOCSIFNAME     0x8923
+#define SIOCSIFHWADDR   0x8924
+#define SIOCGIFENCAP    0x8925
+#define SIOCSIFENCAP    0x8926
+#define SIOCGIFHWADDR   0x8927
+#define SIOCGIFSLAVE    0x8929
+#define SIOCSIFSLAVE    0x8930
+#define SIOCADDMULTI    0x8931
+#define SIOCDELMULTI    0x8932
+#define SIOCGIFINDEX    0x8933
+#define SIOGIFINDEX     SIOCGIFINDEX
+#define SIOCSIFPFLAGS   0x8934
+#define SIOCGIFPFLAGS   0x8935
+#define SIOCDIFADDR     0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT    0x8938
+
+#define SIOCGIFBR       0x8940
+#define SIOCSIFBR       0x8941
+
+#define SIOCGIFTXQLEN   0x8942
+#define SIOCSIFTXQLEN   0x8943
+
+#define SIOCDARP        0x8953
+#define SIOCGARP        0x8954
+#define SIOCSARP        0x8955
+
+#define SIOCDRARP       0x8960
+#define SIOCGRARP       0x8961
+#define SIOCSRARP       0x8962
+
+#define SIOCGIFMAP      0x8970
+#define SIOCSIFMAP      0x8971
+
+#define SIOCADDDLCI     0x8980
+#define SIOCDELDLCI     0x8981
+
+#define SIOCDEVPRIVATE		0x89F0
+#define SIOCPROTOPRIVATE	0x89E0
+
+#include <bits/ioctl_fix.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/ipc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/ipc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/ipc.h	(revision 398)
@@ -0,0 +1,13 @@
+struct ipc_perm {
+	key_t __ipc_perm_key;
+	uid_t uid;
+	gid_t gid;
+	uid_t cuid;
+	gid_t cgid;
+	mode_t mode;
+	int __ipc_perm_seq;
+	long __pad1;
+	long __pad2;
+};
+
+#define IPC_64 0x100
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/limits.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/limits.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/limits.h	(revision 398)
@@ -0,0 +1,8 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define PAGE_SIZE 4096
+#define LONG_BIT 32
+#endif
+
+#define LONG_MAX  0x7fffffffL
+#define LLONG_MAX  0x7fffffffffffffffLL
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/link.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/link.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/link.h	(revision 398)
@@ -0,0 +1,1 @@
+typedef uint32_t Elf_Symndx;
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/msg.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/msg.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/msg.h	(revision 398)
@@ -0,0 +1,15 @@
+struct msqid_ds {
+	struct ipc_perm msg_perm;
+	time_t msg_stime;
+	int __unused1;
+	time_t msg_rtime;
+	int __unused2;
+	time_t msg_ctime;
+	int __unused3;
+	unsigned long msg_cbytes;
+	msgqnum_t msg_qnum;
+	msglen_t msg_qbytes;
+	pid_t msg_lspid;
+	pid_t msg_lrpid;
+	unsigned long __unused[2];
+};
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/posix.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/posix.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/posix.h	(revision 398)
@@ -0,0 +1,2 @@
+#define _POSIX_V6_ILP32_OFFBIG  1
+#define _POSIX_V7_ILP32_OFFBIG  1
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/sem.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/sem.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/sem.h	(revision 398)
@@ -0,0 +1,16 @@
+struct semid_ds {
+	struct ipc_perm sem_perm;
+	time_t sem_otime;
+	time_t __unused1;
+	time_t sem_ctime;
+	time_t __unused2;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned short sem_nsems;
+	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
+#else
+	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
+	unsigned short sem_nsems;
+#endif
+	time_t __unused3;
+	time_t __unused4;
+};
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/setjmp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/setjmp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/setjmp.h	(revision 398)
@@ -0,0 +1,1 @@
+typedef unsigned long __jmp_buf[15];
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/shm.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/shm.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/shm.h	(revision 398)
@@ -0,0 +1,28 @@
+#define SHMLBA 4096
+
+struct shmid_ds {
+	struct ipc_perm shm_perm;
+	size_t shm_segsz;
+	time_t shm_atime;
+	int __unused1;
+	time_t shm_dtime;
+	int __unused2;
+	time_t shm_ctime;
+	int __unused3;
+	pid_t shm_cpid;
+	pid_t shm_lpid;
+	unsigned long shm_nattch;
+	unsigned long __pad1;
+	unsigned long __pad2;
+};
+
+struct shminfo {
+	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+};
+
+struct shm_info {
+	int __used_ids;
+	unsigned long shm_tot, shm_rss, shm_swp;
+	unsigned long __swap_attempts, __swap_successes;
+};
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/signal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/signal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/signal.h	(revision 398)
@@ -0,0 +1,87 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef int greg_t, gregset_t[16];
+typedef int freg_t, fpregset_t[16];
+typedef struct sigcontext {
+	unsigned long oldmask;
+	unsigned long sc_regs[16];
+	unsigned long sc_pc, sc_pr, sc_sr;
+	unsigned long sc_gbr, sc_mach, sc_macl;
+	unsigned long sc_fpregs[16];
+	unsigned long sc_xfpregs[16];
+	unsigned int sc_fpscr, sc_fpul, sc_ownedfp;
+} mcontext_t;
+#else
+typedef struct {
+	unsigned long __regs[58];
+} mcontext_t;
+#endif
+
+struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+};
+
+typedef struct __ucontext {
+	unsigned long uc_flags;
+	struct __ucontext *uc_link;
+	stack_t uc_stack;
+	mcontext_t uc_mcontext;
+	sigset_t uc_sigmask;
+} ucontext_t;
+
+#define SA_NOCLDSTOP  1
+#define SA_NOCLDWAIT  2
+#define SA_SIGINFO    4
+#define SA_ONSTACK    0x08000000
+#define SA_RESTART    0x10000000
+#define SA_NODEFER    0x40000000
+#define SA_RESETHAND  0x80000000
+#define SA_RESTORER   0x04000000
+
+#endif
+
+#define SIGHUP    1
+#define SIGINT    2
+#define SIGQUIT   3
+#define SIGILL    4
+#define SIGTRAP   5
+#define SIGABRT   6
+#define SIGIOT    SIGABRT
+#define SIGBUS    7
+#define SIGFPE    8
+#define SIGKILL   9
+#define SIGUSR1   10
+#define SIGSEGV   11
+#define SIGUSR2   12
+#define SIGPIPE   13
+#define SIGALRM   14
+#define SIGTERM   15
+#define SIGSTKFLT 16
+#define SIGCHLD   17
+#define SIGCONT   18
+#define SIGSTOP   19
+#define SIGTSTP   20
+#define SIGTTIN   21
+#define SIGTTOU   22
+#define SIGURG    23
+#define SIGXCPU   24
+#define SIGXFSZ   25
+#define SIGVTALRM 26
+#define SIGPROF   27
+#define SIGWINCH  28
+#define SIGIO     29
+#define SIGPOLL   29
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/socket.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/socket.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/socket.h	(revision 398)
@@ -0,0 +1,15 @@
+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 cmsghdr {
+	socklen_t cmsg_len;
+	int cmsg_level;
+	int cmsg_type;
+};
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/stat.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/stat.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/stat.h	(revision 398)
@@ -0,0 +1,21 @@
+/* copied from kernel definition, but with padding replaced
+ * by the corresponding correctly-sized userspace types. */
+
+struct stat {
+	dev_t st_dev;
+	int __st_dev_padding;
+	long __st_ino_truncated;
+	mode_t st_mode;
+	nlink_t st_nlink;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	int __st_rdev_padding;
+	off_t st_size;
+	blksize_t st_blksize;
+	blkcnt_t st_blocks;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	ino_t st_ino;
+};
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/statfs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/statfs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/statfs.h	(revision 398)
@@ -0,0 +1,7 @@
+struct statfs {
+	unsigned long f_type, f_bsize;
+	fsblkcnt_t f_blocks, f_bfree, f_bavail;
+	fsfilcnt_t f_files, f_ffree;
+	fsid_t f_fsid;
+	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
+};
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/stdint.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/stdint.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/stdint.h	(revision 398)
@@ -0,0 +1,20 @@
+typedef int32_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef uint32_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+
+#define INT_FAST16_MIN  INT32_MIN
+#define INT_FAST32_MIN  INT32_MIN
+
+#define INT_FAST16_MAX  INT32_MAX
+#define INT_FAST32_MAX  INT32_MAX
+
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INTPTR_MIN      INT32_MIN
+#define INTPTR_MAX      INT32_MAX
+#define UINTPTR_MAX     UINT32_MAX
+#define PTRDIFF_MIN     INT32_MIN
+#define PTRDIFF_MAX     INT32_MAX
+#define SIZE_MAX        UINT32_MAX
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/syscall.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/syscall.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/syscall.h	(revision 398)
@@ -0,0 +1,1068 @@
+#define __NR_restart_syscall	0
+#define __NR_exit	1
+#define __NR_fork	2
+#define __NR_read	3
+#define __NR_write	4
+#define __NR_open	5
+#define __NR_close	6
+#define __NR_creat	8
+#define __NR_link	9
+#define __NR_unlink	10
+#define __NR_execve	11
+#define __NR_chdir	12
+#define __NR_mknod	14
+#define __NR_chmod	15
+#define __NR_lchown	16
+#define __NR_lseek	19
+#define __NR_getpid	20
+#define __NR_mount	21
+#define __NR_setuid	23
+#define __NR_getuid	24
+#define __NR_ptrace	26
+#define __NR_pause	29
+#define __NR_access	33
+#define __NR_nice	34
+#define __NR_sync	36
+#define __NR_kill	37
+#define __NR_rename	38
+#define __NR_mkdir	39
+#define __NR_rmdir	40
+#define __NR_dup	41
+#define __NR_pipe	42
+#define __NR_times	43
+#define __NR_brk	45
+#define __NR_setgid	46
+#define __NR_getgid	47
+#define __NR_geteuid	49
+#define __NR_getegid	50
+#define __NR_acct	51
+#define __NR_umount2	52
+#define __NR_ioctl	54
+#define __NR_fcntl	55
+#define __NR_setpgid	57
+#define __NR_umask	60
+#define __NR_chroot	61
+#define __NR_ustat	62
+#define __NR_dup2	63
+#define __NR_getppid	64
+#define __NR_getpgrp	65
+#define __NR_setsid	66
+#define __NR_sigaction	67
+#define __NR_setreuid	70
+#define __NR_setregid	71
+#define __NR_sigsuspend	72
+#define __NR_sigpending	73
+#define __NR_sethostname	74
+#define __NR_setrlimit	75
+#define __NR_getrusage	77
+#define __NR_gettimeofday	78
+#define __NR_settimeofday	79
+#define __NR_getgroups	80
+#define __NR_setgroups	81
+#define __NR_symlink	83
+#define __NR_readlink	85
+#define __NR_uselib	86
+#define __NR_swapon	87
+#define __NR_reboot	88
+#define __NR_munmap	91
+#define __NR_truncate	92
+#define __NR_ftruncate	93
+#define __NR_fchmod	94
+#define __NR_fchown	95
+#define __NR_getpriority	96
+#define __NR_setpriority	97
+#define __NR_statfs	99
+#define __NR_fstatfs	100
+#define __NR_syslog	103
+#define __NR_setitimer	104
+#define __NR_getitimer	105
+#define __NR_stat	106
+#define __NR_lstat	107
+#define __NR_fstat	108
+#define __NR_vhangup	111
+#define __NR_wait4	114
+#define __NR_swapoff	115
+#define __NR_sysinfo	116
+#define __NR_fsync	118
+#define __NR_sigreturn	119
+#define __NR_clone	120
+#define __NR_setdomainname	121
+#define __NR_uname	122
+#define __NR_adjtimex	124
+#define __NR_mprotect	125
+#define __NR_sigprocmask	126
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_quotactl	131
+#define __NR_getpgid	132
+#define __NR_fchdir	133
+#define __NR_bdflush	134
+#define __NR_sysfs	135
+#define __NR_personality	136
+#define __NR_setfsuid	138
+#define __NR_setfsgid	139
+#define __NR__llseek	140
+#define __NR_getdents	141
+#define __NR__newselect	142
+#define __NR_flock	143
+#define __NR_msync	144
+#define __NR_readv	145
+#define __NR_writev	146
+#define __NR_getsid	147
+#define __NR_fdatasync	148
+#define __NR__sysctl	149
+#define __NR_mlock	150
+#define __NR_munlock	151
+#define __NR_mlockall	152
+#define __NR_munlockall	153
+#define __NR_sched_setparam	154
+#define __NR_sched_getparam	155
+#define __NR_sched_setscheduler	156
+#define __NR_sched_getscheduler	157
+#define __NR_sched_yield	158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep	162
+#define __NR_mremap	163
+#define __NR_setresuid	164
+#define __NR_getresuid	165
+#define __NR_poll	168
+#define __NR_nfsservctl	169
+#define __NR_setresgid	170
+#define __NR_getresgid	171
+#define __NR_prctl	172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread64	180
+#define __NR_pwrite64	181
+#define __NR_chown	182
+#define __NR_getcwd	183
+#define __NR_capget	184
+#define __NR_capset	185
+#define __NR_sigaltstack	186
+#define __NR_sendfile	187
+#define __NR_vfork	190
+#define __NR_ugetrlimit	191
+#define __NR_mmap2	192
+#define __NR_truncate64	193
+#define __NR_ftruncate64	194
+#define __NR_stat64	195
+#define __NR_lstat64	196
+#define __NR_fstat64	197
+#define __NR_lchown32	198
+#define __NR_getuid32	199
+#define __NR_getgid32	200
+#define __NR_geteuid32	201
+#define __NR_getegid32	202
+#define __NR_setreuid32	203
+#define __NR_setregid32	204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32	207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32	212
+#define __NR_setuid32	213
+#define __NR_setgid32	214
+#define __NR_setfsuid32	215
+#define __NR_setfsgid32	216
+#define __NR_getdents64	217
+#define __NR_pivot_root	218
+#define __NR_mincore	219
+#define __NR_madvise	220
+#define __NR_fcntl64	221
+#define __NR_gettid	224
+#define __NR_readahead	225
+#define __NR_setxattr	226
+#define __NR_lsetxattr	227
+#define __NR_fsetxattr	228
+#define __NR_getxattr	229
+#define __NR_lgetxattr	230
+#define __NR_fgetxattr	231
+#define __NR_listxattr	232
+#define __NR_llistxattr	233
+#define __NR_flistxattr	234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
+#define __NR_tkill	238
+#define __NR_sendfile64	239
+#define __NR_futex	240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
+#define __NR_io_setup	243
+#define __NR_io_destroy	244
+#define __NR_io_getevents	245
+#define __NR_io_submit	246
+#define __NR_io_cancel	247
+#define __NR_exit_group	248
+#define __NR_lookup_dcookie	249
+#define __NR_epoll_create	250
+#define __NR_epoll_ctl	251
+#define __NR_epoll_wait	252
+#define __NR_remap_file_pages	253
+#define __NR_set_tid_address	256
+#define __NR_timer_create	257
+#define __NR_timer_settime	258
+#define __NR_timer_gettime	259
+#define __NR_timer_getoverrun	260
+#define __NR_timer_delete	261
+#define __NR_clock_settime	262
+#define __NR_clock_gettime	263
+#define __NR_clock_getres	264
+#define __NR_clock_nanosleep	265
+#define __NR_statfs64	266
+#define __NR_fstatfs64	267
+#define __NR_tgkill	268
+#define __NR_utimes	269
+#define __NR_fadvise64_64	270
+#define __NR_pciconfig_iobase	271
+#define __NR_pciconfig_read	272
+#define __NR_pciconfig_write	273
+#define __NR_mq_open	274
+#define __NR_mq_unlink	275
+#define __NR_mq_timedsend	276
+#define __NR_mq_timedreceive	277
+#define __NR_mq_notify	278
+#define __NR_mq_getsetattr	279
+#define __NR_waitid	280
+#define __NR_socket	281
+#define __NR_bind	282
+#define __NR_connect	283
+#define __NR_listen	284
+#define __NR_accept	285
+#define __NR_getsockname	286
+#define __NR_getpeername	287
+#define __NR_socketpair	288
+#define __NR_send	289
+#define __NR_sendto	290
+#define __NR_recv	291
+#define __NR_recvfrom	292
+#define __NR_shutdown	293
+#define __NR_setsockopt	294
+#define __NR_getsockopt	295
+#define __NR_sendmsg	296
+#define __NR_recvmsg	297
+#define __NR_semop	298
+#define __NR_semget	299
+#define __NR_semctl	300
+#define __NR_msgsnd	301
+#define __NR_msgrcv	302
+#define __NR_msgget	303
+#define __NR_msgctl	304
+#define __NR_shmat	305
+#define __NR_shmdt	306
+#define __NR_shmget	307
+#define __NR_shmctl	308
+#define __NR_add_key	309
+#define __NR_request_key	310
+#define __NR_keyctl	311
+#define __NR_semtimedop	312
+#define __NR_vserver	313
+#define __NR_ioprio_set	314
+#define __NR_ioprio_get	315
+#define __NR_inotify_init	316
+#define __NR_inotify_add_watch	317
+#define __NR_inotify_rm_watch	318
+#define __NR_mbind	319
+#define __NR_get_mempolicy	320
+#define __NR_set_mempolicy	321
+#define __NR_openat	322
+#define __NR_mkdirat	323
+#define __NR_mknodat	324
+#define __NR_fchownat	325
+#define __NR_futimesat	326
+#define __NR_fstatat64	327
+#define __NR_unlinkat	328
+#define __NR_renameat	329
+#define __NR_linkat	330
+#define __NR_symlinkat	331
+#define __NR_readlinkat	332
+#define __NR_fchmodat	333
+#define __NR_faccessat	334
+#define __NR_pselect6	335
+#define __NR_ppoll	336
+#define __NR_unshare	337
+#define __NR_set_robust_list	338
+#define __NR_get_robust_list	339
+#define __NR_splice	340
+#define __NR_sync_file_range2	341
+#define __NR_tee	342
+#define __NR_vmsplice	343
+#define __NR_move_pages	344
+#define __NR_getcpu	345
+#define __NR_epoll_pwait	346
+#define __NR_kexec_load	347
+#define __NR_utimensat	348
+#define __NR_signalfd	349
+#define __NR_timerfd_create	350
+#define __NR_eventfd	351
+#define __NR_fallocate	352
+#define __NR_timerfd_settime	353
+#define __NR_timerfd_gettime	354
+#define __NR_signalfd4	355
+#define __NR_eventfd2	356
+#define __NR_epoll_create1	357
+#define __NR_dup3	358
+#define __NR_pipe2	359
+#define __NR_inotify_init1	360
+#define __NR_preadv	361
+#define __NR_pwritev	362
+#define __NR_rt_tgsigqueueinfo	363
+#define __NR_perf_event_open	364
+#define __NR_recvmmsg	365
+#define __NR_accept4	366
+#define __NR_fanotify_init	367
+#define __NR_fanotify_mark	368
+#define __NR_prlimit64	369
+#define __NR_name_to_handle_at	370
+#define __NR_open_by_handle_at	371
+#define __NR_clock_adjtime	372
+#define __NR_syncfs	373
+#define __NR_sendmmsg	374
+#define __NR_setns	375
+#define __NR_process_vm_readv	376
+#define __NR_process_vm_writev	377
+#define __NR_kcmp		378
+#define __NR_finit_module	379
+#define __NR_sched_setattr	380
+#define __NR_sched_getattr	381
+#define __NR_renameat2	382
+#define __NR_seccomp	383
+#define __NR_getrandom	384
+#define __NR_memfd_create	385
+#define __NR_bpf	386
+#define __NR_execveat	387
+#define __NR_userfaultfd	388
+#define __NR_membarrier		389
+#define __NR_mlock2		390
+#define __NR_copy_file_range	391
+#define __NR_preadv2	392
+#define __NR_pwritev2	393
+#define __NR_pkey_mprotect	394
+#define __NR_pkey_alloc	395
+#define __NR_pkey_free	396
+
+#define __ARM_NR_breakpoint	0x0f0001
+#define __ARM_NR_cacheflush	0x0f0002
+#define __ARM_NR_usr26		0x0f0003
+#define __ARM_NR_usr32		0x0f0004
+#define __ARM_NR_set_tls	0x0f0005
+
+#define SYS_restart_syscall SYS_restart_syscall
+long SYS_restart_syscall();
+#define SYS_exit SYS_exit
+long SYS_exit();
+#define SYS_fork SYS_fork
+long SYS_fork();
+#define SYS_read SYS_read
+long SYS_read();
+#define SYS_write SYS_write
+long SYS_write();
+#define SYS_open SYS_open
+long SYS_open();
+#define SYS_close SYS_close
+long SYS_close();
+#define SYS_creat SYS_creat
+long SYS_creat();
+#define SYS_link SYS_link
+long SYS_link();
+#define SYS_unlink SYS_unlink
+long SYS_unlink();
+#define SYS_execve SYS_execve
+long SYS_execve();
+#define SYS_chdir SYS_chdir
+long SYS_chdir();
+#define SYS_mknod SYS_mknod
+long SYS_mknod();
+#define SYS_chmod SYS_chmod
+long SYS_chmod();
+#define SYS_lchown SYS_lchown
+long SYS_lchown();
+#define SYS_lseek SYS_lseek
+long SYS_lseek();
+#define SYS_getpid SYS_getpid
+long SYS_getpid();
+#define SYS_mount SYS_mount
+long SYS_mount();
+#define SYS_setuid SYS_setuid
+long SYS_setuid();
+#define SYS_getuid SYS_getuid
+long SYS_getuid();
+#define SYS_ptrace SYS_ptrace
+long SYS_ptrace();
+#define SYS_pause SYS_pause
+long SYS_pause();
+#define SYS_access SYS_access
+long SYS_access();
+#define SYS_nice SYS_nice
+long SYS_nice();
+#define SYS_sync SYS_sync
+long SYS_sync();
+#define SYS_kill SYS_kill
+long SYS_kill();
+#define SYS_rename SYS_rename
+long SYS_rename();
+#define SYS_mkdir SYS_mkdir
+long SYS_mkdir();
+#define SYS_rmdir SYS_rmdir
+long SYS_rmdir();
+#define SYS_dup SYS_dup
+long SYS_dup();
+#define SYS_pipe SYS_pipe
+long SYS_pipe();
+#define SYS_times SYS_times
+long SYS_times();
+#define SYS_brk SYS_brk
+long SYS_brk();
+#define SYS_setgid SYS_setgid
+long SYS_setgid();
+#define SYS_getgid SYS_getgid
+long SYS_getgid();
+#define SYS_geteuid SYS_geteuid
+long SYS_geteuid();
+#define SYS_getegid SYS_getegid
+long SYS_getegid();
+#define SYS_acct SYS_acct
+long SYS_acct();
+#define SYS_umount2 SYS_umount2
+long SYS_umount2();
+#define SYS_ioctl SYS_ioctl
+long SYS_ioctl();
+#define SYS_fcntl SYS_fcntl
+long SYS_fcntl();
+#define SYS_setpgid SYS_setpgid
+long SYS_setpgid();
+#define SYS_umask SYS_umask
+long SYS_umask();
+#define SYS_chroot SYS_chroot
+long SYS_chroot();
+#define SYS_ustat SYS_ustat
+long SYS_ustat();
+#define SYS_dup2 SYS_dup2
+long SYS_dup2();
+#define SYS_getppid SYS_getppid
+long SYS_getppid();
+#define SYS_getpgrp SYS_getpgrp
+long SYS_getpgrp();
+#define SYS_setsid SYS_setsid
+long SYS_setsid();
+#define SYS_sigaction SYS_sigaction
+long SYS_sigaction();
+#define SYS_setreuid SYS_setreuid
+long SYS_setreuid();
+#define SYS_setregid SYS_setregid
+long SYS_setregid();
+#define SYS_sigsuspend SYS_sigsuspend
+long SYS_sigsuspend();
+#define SYS_sigpending SYS_sigpending
+long SYS_sigpending();
+#define SYS_sethostname SYS_sethostname
+long SYS_sethostname();
+#define SYS_setrlimit SYS_setrlimit
+long SYS_setrlimit();
+#define SYS_getrusage SYS_getrusage
+long SYS_getrusage();
+#define SYS_gettimeofday SYS_gettimeofday
+long SYS_gettimeofday();
+#define SYS_settimeofday SYS_settimeofday
+long SYS_settimeofday();
+#define SYS_getgroups SYS_getgroups
+long SYS_getgroups();
+#define SYS_setgroups SYS_setgroups
+long SYS_setgroups();
+#define SYS_symlink SYS_symlink
+long SYS_symlink();
+#define SYS_readlink SYS_readlink
+long SYS_readlink();
+#define SYS_uselib SYS_uselib
+long SYS_uselib();
+#define SYS_swapon SYS_swapon
+long SYS_swapon();
+#define SYS_reboot SYS_reboot
+long SYS_reboot();
+#define SYS_munmap SYS_munmap
+long SYS_munmap();
+#define SYS_truncate SYS_truncate
+long SYS_truncate();
+#define SYS_ftruncate SYS_ftruncate
+long SYS_ftruncate();
+#define SYS_fchmod SYS_fchmod
+long SYS_fchmod();
+#define SYS_fchown SYS_fchown
+long SYS_fchown();
+#define SYS_getpriority SYS_getpriority
+long SYS_getpriority();
+#define SYS_setpriority SYS_setpriority
+long SYS_setpriority();
+#define SYS_statfs SYS_statfs
+long SYS_statfs();
+#define SYS_fstatfs SYS_fstatfs
+long SYS_fstatfs();
+#define SYS_syslog SYS_syslog
+long SYS_syslog();
+#define SYS_setitimer SYS_setitimer
+long SYS_setitimer();
+#define SYS_getitimer SYS_getitimer
+long SYS_getitimer();
+#define SYS_stat SYS_stat
+long SYS_stat();
+#define SYS_lstat SYS_lstat
+long SYS_lstat();
+#define SYS_fstat SYS_fstat
+long SYS_fstat();
+#define SYS_vhangup SYS_vhangup
+long SYS_vhangup();
+#define SYS_wait4 SYS_wait4
+long SYS_wait4();
+#define SYS_swapoff SYS_swapoff
+long SYS_swapoff();
+#define SYS_sysinfo SYS_sysinfo
+long SYS_sysinfo();
+#define SYS_fsync SYS_fsync
+long SYS_fsync();
+#define SYS_sigreturn SYS_sigreturn
+long SYS_sigreturn();
+#define SYS_clone SYS_clone
+long SYS_clone();
+#define SYS_setdomainname SYS_setdomainname
+long SYS_setdomainname();
+#define SYS_uname SYS_uname
+long SYS_uname();
+#define SYS_adjtimex SYS_adjtimex
+long SYS_adjtimex();
+#define SYS_mprotect SYS_mprotect
+long SYS_mprotect();
+#define SYS_sigprocmask SYS_sigprocmask
+long SYS_sigprocmask();
+#define SYS_init_module SYS_init_module
+long SYS_init_module();
+#define SYS_delete_module SYS_delete_module
+long SYS_delete_module();
+#define SYS_quotactl SYS_quotactl
+long SYS_quotactl();
+#define SYS_getpgid SYS_getpgid
+long SYS_getpgid();
+#define SYS_fchdir SYS_fchdir
+long SYS_fchdir();
+#define SYS_bdflush SYS_bdflush
+long SYS_bdflush();
+#define SYS_sysfs SYS_sysfs
+long SYS_sysfs();
+#define SYS_personality SYS_personality
+long SYS_personality();
+#define SYS_setfsuid SYS_setfsuid
+long SYS_setfsuid();
+#define SYS_setfsgid SYS_setfsgid
+long SYS_setfsgid();
+#define SYS__llseek SYS__llseek
+long SYS__llseek();
+#define SYS_getdents SYS_getdents
+long SYS_getdents();
+#define SYS__newselect SYS__newselect
+long SYS__newselect();
+#define SYS_flock SYS_flock
+long SYS_flock();
+#define SYS_msync SYS_msync
+long SYS_msync();
+#define SYS_readv SYS_readv
+long SYS_readv();
+#define SYS_writev SYS_writev
+long SYS_writev();
+#define SYS_getsid SYS_getsid
+long SYS_getsid();
+#define SYS_fdatasync SYS_fdatasync
+long SYS_fdatasync();
+#define SYS__sysctl SYS__sysctl
+long SYS__sysctl();
+#define SYS_mlock SYS_mlock
+long SYS_mlock();
+#define SYS_munlock SYS_munlock
+long SYS_munlock();
+#define SYS_mlockall SYS_mlockall
+long SYS_mlockall();
+#define SYS_munlockall SYS_munlockall
+long SYS_munlockall();
+#define SYS_sched_setparam SYS_sched_setparam
+long SYS_sched_setparam();
+#define SYS_sched_getparam SYS_sched_getparam
+long SYS_sched_getparam();
+#define SYS_sched_setscheduler SYS_sched_setscheduler
+long SYS_sched_setscheduler();
+#define SYS_sched_getscheduler SYS_sched_getscheduler
+long SYS_sched_getscheduler();
+#define SYS_sched_yield SYS_sched_yield
+long SYS_sched_yield();
+#define SYS_sched_get_priority_max SYS_sched_get_priority_max
+long SYS_sched_get_priority_max();
+#define SYS_sched_get_priority_min SYS_sched_get_priority_min
+long SYS_sched_get_priority_min();
+#define SYS_sched_rr_get_interval SYS_sched_rr_get_interval
+long SYS_sched_rr_get_interval();
+#define SYS_nanosleep SYS_nanosleep
+long SYS_nanosleep();
+#define SYS_mremap SYS_mremap
+long SYS_mremap();
+#define SYS_setresuid SYS_setresuid
+long SYS_setresuid();
+#define SYS_getresuid SYS_getresuid
+long SYS_getresuid();
+#define SYS_poll SYS_poll
+long SYS_poll();
+#define SYS_nfsservctl SYS_nfsservctl
+long SYS_nfsservctl();
+#define SYS_setresgid SYS_setresgid
+long SYS_setresgid();
+#define SYS_getresgid SYS_getresgid
+long SYS_getresgid();
+#define SYS_prctl SYS_prctl
+long SYS_prctl();
+#define SYS_rt_sigreturn SYS_rt_sigreturn
+long SYS_rt_sigreturn();
+#define SYS_rt_sigaction SYS_rt_sigaction
+long SYS_rt_sigaction();
+#define SYS_rt_sigprocmask SYS_rt_sigprocmask
+long SYS_rt_sigprocmask();
+#define SYS_rt_sigpending SYS_rt_sigpending
+long SYS_rt_sigpending();
+#define SYS_rt_sigtimedwait SYS_rt_sigtimedwait
+long SYS_rt_sigtimedwait();
+#define SYS_rt_sigqueueinfo SYS_rt_sigqueueinfo
+long SYS_rt_sigqueueinfo();
+#define SYS_rt_sigsuspend SYS_rt_sigsuspend
+long SYS_rt_sigsuspend();
+#define SYS_pread64 SYS_pread64
+long SYS_pread64();
+#define SYS_pwrite64 SYS_pwrite64
+long SYS_pwrite64();
+#define SYS_chown SYS_chown
+long SYS_chown();
+#define SYS_getcwd SYS_getcwd
+long SYS_getcwd();
+#define SYS_capget SYS_capget
+long SYS_capget();
+#define SYS_capset SYS_capset
+long SYS_capset();
+#define SYS_sigaltstack SYS_sigaltstack
+long SYS_sigaltstack();
+#define SYS_sendfile SYS_sendfile
+long SYS_sendfile();
+#define SYS_vfork SYS_vfork
+long SYS_vfork();
+#define SYS_ugetrlimit SYS_ugetrlimit
+long SYS_ugetrlimit();
+#define SYS_mmap2 SYS_mmap2
+long SYS_mmap2();
+#define SYS_truncate64 SYS_truncate64
+long SYS_truncate64();
+#define SYS_ftruncate64 SYS_ftruncate64
+long SYS_ftruncate64();
+#define SYS_stat64 SYS_stat64
+long SYS_stat64();
+#define SYS_lstat64 SYS_lstat64
+long SYS_lstat64();
+#define SYS_fstat64 SYS_fstat64
+long SYS_fstat64();
+#define SYS_lchown32 SYS_lchown32
+long SYS_lchown32();
+#define SYS_getuid32 SYS_getuid32
+long SYS_getuid32();
+#define SYS_getgid32 SYS_getgid32
+long SYS_getgid32();
+#define SYS_geteuid32 SYS_geteuid32
+long SYS_geteuid32();
+#define SYS_getegid32 SYS_getegid32
+long SYS_getegid32();
+#define SYS_setreuid32 SYS_setreuid32
+long SYS_setreuid32();
+#define SYS_setregid32 SYS_setregid32
+long SYS_setregid32();
+#define SYS_getgroups32 SYS_getgroups32
+long SYS_getgroups32();
+#define SYS_setgroups32 SYS_setgroups32
+long SYS_setgroups32();
+#define SYS_fchown32 SYS_fchown32
+long SYS_fchown32();
+#define SYS_setresuid32 SYS_setresuid32
+long SYS_setresuid32();
+#define SYS_getresuid32 SYS_getresuid32
+long SYS_getresuid32();
+#define SYS_setresgid32 SYS_setresgid32
+long SYS_setresgid32();
+#define SYS_getresgid32 SYS_getresgid32
+long SYS_getresgid32();
+#define SYS_chown32 SYS_chown32
+long SYS_chown32();
+#define SYS_setuid32 SYS_setuid32
+long SYS_setuid32();
+#define SYS_setgid32 SYS_setgid32
+long SYS_setgid32();
+#define SYS_setfsuid32 SYS_setfsuid32
+long SYS_setfsuid32();
+#define SYS_setfsgid32 SYS_setfsgid32
+long SYS_setfsgid32();
+#define SYS_getdents64 SYS_getdents64
+long SYS_getdents64();
+#define SYS_pivot_root SYS_pivot_root
+long SYS_pivot_root();
+#define SYS_mincore SYS_mincore
+long SYS_mincore();
+#define SYS_madvise SYS_madvise
+long SYS_madvise();
+#define SYS_fcntl64 SYS_fcntl64
+long SYS_fcntl64();
+#define SYS_gettid SYS_gettid
+long SYS_gettid();
+#define SYS_readahead SYS_readahead
+long SYS_readahead();
+#define SYS_setxattr SYS_setxattr
+long SYS_setxattr();
+#define SYS_lsetxattr SYS_lsetxattr
+long SYS_lsetxattr();
+#define SYS_fsetxattr SYS_fsetxattr
+long SYS_fsetxattr();
+#define SYS_getxattr SYS_getxattr
+long SYS_getxattr();
+#define SYS_lgetxattr SYS_lgetxattr
+long SYS_lgetxattr();
+#define SYS_fgetxattr SYS_fgetxattr
+long SYS_fgetxattr();
+#define SYS_listxattr SYS_listxattr
+long SYS_listxattr();
+#define SYS_llistxattr SYS_llistxattr
+long SYS_llistxattr();
+#define SYS_flistxattr SYS_flistxattr
+long SYS_flistxattr();
+#define SYS_removexattr SYS_removexattr
+long SYS_removexattr();
+#define SYS_lremovexattr SYS_lremovexattr
+long SYS_lremovexattr();
+#define SYS_fremovexattr SYS_fremovexattr
+long SYS_fremovexattr();
+#define SYS_tkill SYS_tkill
+long SYS_tkill();
+#define SYS_sendfile64 SYS_sendfile64
+long SYS_sendfile64();
+#define SYS_futex SYS_futex
+long SYS_futex();
+#define SYS_sched_setaffinity SYS_sched_setaffinity
+long SYS_sched_setaffinity();
+#define SYS_sched_getaffinity SYS_sched_getaffinity
+long SYS_sched_getaffinity();
+#define SYS_io_setup SYS_io_setup
+long SYS_io_setup();
+#define SYS_io_destroy SYS_io_destroy
+long SYS_io_destroy();
+#define SYS_io_getevents SYS_io_getevents
+long SYS_io_getevents();
+#define SYS_io_submit SYS_io_submit
+long SYS_io_submit();
+#define SYS_io_cancel SYS_io_cancel
+long SYS_io_cancel();
+#define SYS_exit_group SYS_exit_group
+long SYS_exit_group();
+#define SYS_lookup_dcookie SYS_lookup_dcookie
+long SYS_lookup_dcookie();
+#define SYS_epoll_create SYS_epoll_create
+long SYS_epoll_create();
+#define SYS_epoll_ctl SYS_epoll_ctl
+long SYS_epoll_ctl();
+#define SYS_epoll_wait SYS_epoll_wait
+long SYS_epoll_wait();
+#define SYS_remap_file_pages SYS_remap_file_pages
+long SYS_remap_file_pages();
+#define SYS_set_tid_address SYS_set_tid_address
+long SYS_set_tid_address();
+#define SYS_timer_create SYS_timer_create
+long SYS_timer_create();
+#define SYS_timer_settime SYS_timer_settime
+long SYS_timer_settime();
+#define SYS_timer_gettime SYS_timer_gettime
+long SYS_timer_gettime();
+#define SYS_timer_getoverrun SYS_timer_getoverrun
+long SYS_timer_getoverrun();
+#define SYS_timer_delete SYS_timer_delete
+long SYS_timer_delete();
+#define SYS_clock_settime SYS_clock_settime
+long SYS_clock_settime();
+#define SYS_clock_gettime SYS_clock_gettime
+long SYS_clock_gettime();
+#define SYS_clock_getres SYS_clock_getres
+long SYS_clock_getres();
+#define SYS_clock_nanosleep SYS_clock_nanosleep
+long SYS_clock_nanosleep();
+#define SYS_statfs64 SYS_statfs64
+long SYS_statfs64();
+#define SYS_fstatfs64 SYS_fstatfs64
+long SYS_fstatfs64();
+#define SYS_tgkill SYS_tgkill
+long SYS_tgkill();
+#define SYS_utimes SYS_utimes
+long SYS_utimes();
+#define SYS_fadvise64_64 SYS_fadvise64_64
+long SYS_fadvise64_64();
+#define SYS_pciconfig_iobase SYS_pciconfig_iobase
+long SYS_pciconfig_iobase();
+#define SYS_pciconfig_read SYS_pciconfig_read
+long SYS_pciconfig_read();
+#define SYS_pciconfig_write SYS_pciconfig_write
+long SYS_pciconfig_write();
+#define SYS_mq_open SYS_mq_open
+long SYS_mq_open();
+#define SYS_mq_unlink SYS_mq_unlink
+long SYS_mq_unlink();
+#define SYS_mq_timedsend SYS_mq_timedsend
+long SYS_mq_timedsend();
+#define SYS_mq_timedreceive SYS_mq_timedreceive
+long SYS_mq_timedreceive();
+#define SYS_mq_notify SYS_mq_notify
+long SYS_mq_notify();
+#define SYS_mq_getsetattr SYS_mq_getsetattr
+long SYS_mq_getsetattr();
+#define SYS_waitid SYS_waitid
+long SYS_waitid();
+#define SYS_socket SYS_socket
+long SYS_socket();
+#define SYS_bind SYS_bind
+long SYS_bind();
+#define SYS_connect SYS_connect
+long SYS_connect();
+#define SYS_listen SYS_listen
+long SYS_listen();
+#define SYS_accept SYS_accept
+long SYS_accept();
+#define SYS_getsockname SYS_getsockname
+long SYS_getsockname();
+#define SYS_getpeername SYS_getpeername
+long SYS_getpeername();
+#define SYS_socketpair SYS_socketpair
+long SYS_socketpair();
+#define SYS_send SYS_send
+long SYS_send();
+#define SYS_sendto SYS_sendto
+long SYS_sendto();
+#define SYS_recv SYS_recv
+long SYS_recv();
+#define SYS_recvfrom SYS_recvfrom
+long SYS_recvfrom();
+#define SYS_shutdown SYS_shutdown
+long SYS_shutdown();
+#define SYS_setsockopt SYS_setsockopt
+long SYS_setsockopt();
+#define SYS_getsockopt SYS_getsockopt
+long SYS_getsockopt();
+#define SYS_sendmsg SYS_sendmsg
+long SYS_sendmsg();
+#define SYS_recvmsg SYS_recvmsg
+long SYS_recvmsg();
+#define SYS_semop SYS_semop
+long SYS_semop();
+#define SYS_semget SYS_semget
+long SYS_semget();
+#define SYS_semctl SYS_semctl
+long SYS_semctl();
+#define SYS_msgsnd SYS_msgsnd
+long SYS_msgsnd();
+#define SYS_msgrcv SYS_msgrcv
+long SYS_msgrcv();
+#define SYS_msgget SYS_msgget
+long SYS_msgget();
+#define SYS_msgctl SYS_msgctl
+long SYS_msgctl();
+#define SYS_shmat SYS_shmat
+long SYS_shmat();
+#define SYS_shmdt SYS_shmdt
+long SYS_shmdt();
+#define SYS_shmget SYS_shmget
+long SYS_shmget();
+#define SYS_shmctl SYS_shmctl
+long SYS_shmctl();
+#define SYS_add_key SYS_add_key
+long SYS_add_key();
+#define SYS_request_key SYS_request_key
+long SYS_request_key();
+#define SYS_keyctl SYS_keyctl
+long SYS_keyctl();
+#define SYS_semtimedop SYS_semtimedop
+long SYS_semtimedop();
+#define SYS_vserver SYS_vserver
+long SYS_vserver();
+#define SYS_ioprio_set SYS_ioprio_set
+long SYS_ioprio_set();
+#define SYS_ioprio_get SYS_ioprio_get
+long SYS_ioprio_get();
+#define SYS_inotify_init SYS_inotify_init
+long SYS_inotify_init();
+#define SYS_inotify_add_watch SYS_inotify_add_watch
+long SYS_inotify_add_watch();
+#define SYS_inotify_rm_watch SYS_inotify_rm_watch
+long SYS_inotify_rm_watch();
+#define SYS_mbind SYS_mbind
+long SYS_mbind();
+#define SYS_get_mempolicy SYS_get_mempolicy
+long SYS_get_mempolicy();
+#define SYS_set_mempolicy SYS_set_mempolicy
+long SYS_set_mempolicy();
+#define SYS_openat SYS_openat
+long SYS_openat();
+#define SYS_mkdirat SYS_mkdirat
+long SYS_mkdirat();
+#define SYS_mknodat SYS_mknodat
+long SYS_mknodat();
+#define SYS_fchownat SYS_fchownat
+long SYS_fchownat();
+#define SYS_futimesat SYS_futimesat
+long SYS_futimesat();
+#define SYS_fstatat64 SYS_fstatat64
+long SYS_fstatat64();
+#define SYS_unlinkat SYS_unlinkat
+long SYS_unlinkat();
+#define SYS_renameat SYS_renameat
+long SYS_renameat();
+#define SYS_linkat SYS_linkat
+long SYS_linkat();
+#define SYS_symlinkat SYS_symlinkat
+long SYS_symlinkat();
+#define SYS_readlinkat SYS_readlinkat
+long SYS_readlinkat();
+#define SYS_fchmodat SYS_fchmodat
+long SYS_fchmodat();
+#define SYS_faccessat SYS_faccessat
+long SYS_faccessat();
+#define SYS_pselect6 SYS_pselect6
+long SYS_pselect6();
+#define SYS_ppoll SYS_ppoll
+long SYS_ppoll();
+#define SYS_unshare SYS_unshare
+long SYS_unshare();
+#define SYS_set_robust_list SYS_set_robust_list
+long SYS_set_robust_list();
+#define SYS_get_robust_list SYS_get_robust_list
+long SYS_get_robust_list();
+#define SYS_splice SYS_splice
+long SYS_splice();
+#define SYS_sync_file_range2 SYS_sync_file_range2
+long SYS_sync_file_range2();
+#define SYS_tee SYS_tee
+long SYS_tee();
+#define SYS_vmsplice SYS_vmsplice
+long SYS_vmsplice();
+#define SYS_move_pages SYS_move_pages
+long SYS_move_pages();
+#define SYS_getcpu SYS_getcpu
+long SYS_getcpu();
+#define SYS_epoll_pwait SYS_epoll_pwait
+long SYS_epoll_pwait();
+#define SYS_kexec_load SYS_kexec_load
+long SYS_kexec_load();
+#define SYS_utimensat SYS_utimensat
+long SYS_utimensat();
+#define SYS_signalfd SYS_signalfd
+long SYS_signalfd();
+#define SYS_timerfd_create SYS_timerfd_create
+long SYS_timerfd_create();
+#define SYS_eventfd SYS_eventfd
+long SYS_eventfd();
+#define SYS_fallocate SYS_fallocate
+long SYS_fallocate();
+#define SYS_timerfd_settime SYS_timerfd_settime
+long SYS_timerfd_settime();
+#define SYS_timerfd_gettime SYS_timerfd_gettime
+long SYS_timerfd_gettime();
+#define SYS_signalfd4 SYS_signalfd4
+long SYS_signalfd4();
+#define SYS_eventfd2 SYS_eventfd2
+long SYS_eventfd2();
+#define SYS_epoll_create1 SYS_epoll_create1
+long SYS_epoll_create1();
+#define SYS_dup3 SYS_dup3
+long SYS_dup3();
+#define SYS_pipe2 SYS_pipe2
+long SYS_pipe2();
+#define SYS_inotify_init1 SYS_inotify_init1
+long SYS_inotify_init1();
+#define SYS_preadv SYS_preadv
+long SYS_preadv();
+#define SYS_pwritev SYS_pwritev
+long SYS_pwritev();
+#define SYS_rt_tgsigqueueinfo SYS_rt_tgsigqueueinfo
+long SYS_rt_tgsigqueueinfo();
+#define SYS_perf_event_open SYS_perf_event_open
+long SYS_perf_event_open();
+#define SYS_recvmmsg SYS_recvmmsg
+long SYS_recvmmsg();
+#define SYS_accept4 SYS_accept4
+long SYS_accept4();
+#define SYS_fanotify_init SYS_fanotify_init
+long SYS_fanotify_init();
+#define SYS_fanotify_mark SYS_fanotify_mark
+long SYS_fanotify_mark();
+#define SYS_prlimit64 SYS_prlimit64
+long SYS_prlimit64();
+#define SYS_name_to_handle_at SYS_name_to_handle_at
+long SYS_name_to_handle_at();
+#define SYS_open_by_handle_at SYS_open_by_handle_at
+long SYS_open_by_handle_at();
+#define SYS_clock_adjtime SYS_clock_adjtime
+long SYS_clock_adjtime();
+#define SYS_syncfs SYS_syncfs
+long SYS_syncfs();
+#define SYS_sendmmsg SYS_sendmmsg
+long SYS_sendmmsg();
+#define SYS_setns SYS_setns
+long SYS_setns();
+#define SYS_process_vm_readv SYS_process_vm_readv
+long SYS_process_vm_readv();
+#define SYS_process_vm_writev SYS_process_vm_writev
+long SYS_process_vm_writev();
+#define SYS_kcmp SYS_kcmp
+long SYS_kcmp();
+#define SYS_finit_module SYS_finit_module
+long SYS_finit_module();
+#define SYS_sched_setattr SYS_sched_setattr
+long SYS_sched_setattr();
+#define SYS_sched_getattr SYS_sched_getattr
+long SYS_sched_getattr();
+#define SYS_renameat2 SYS_renameat2
+long SYS_renameat2();
+#define SYS_seccomp SYS_seccomp
+long SYS_seccomp();
+#define SYS_getrandom SYS_getrandom
+long SYS_getrandom();
+#define SYS_memfd_create SYS_memfd_create
+long SYS_memfd_create();
+#define SYS_bpf SYS_bpf
+long SYS_bpf();
+#define SYS_execveat SYS_execveat
+long SYS_execveat();
+#define SYS_userfaultfd SYS_userfaultfd
+long SYS_userfaultfd();
+#define SYS_membarrier SYS_membarrier
+long SYS_membarrier();
+#define SYS_mlock2 SYS_mlock2
+long SYS_mlock2();
+#define SYS_copy_file_range SYS_copy_file_range
+long SYS_copy_file_range();
+#define SYS_preadv2 SYS_preadv2
+long SYS_preadv2();
+#define SYS_pwritev2 SYS_pwritev2
+long SYS_pwritev2();
+#define SYS_pkey_mprotect SYS_pkey_mprotect
+long SYS_pkey_mprotect();
+#define SYS_pkey_alloc SYS_pkey_alloc
+long SYS_pkey_alloc();
+#define SYS_pkey_free SYS_pkey_free
+long SYS_pkey_free();
+
+#define SYS_set_thread_area SYS_set_thread_area
+long SYS_set_thread_area();
+#define SYS_get_thread_area SYS_get_thread_area
+long SYS_get_thread_area();
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/termios.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/termios.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/bits/termios.h	(revision 398)
@@ -0,0 +1,164 @@
+struct termios {
+	tcflag_t c_iflag;
+	tcflag_t c_oflag;
+	tcflag_t c_cflag;
+	tcflag_t c_lflag;
+	cc_t c_line;
+	cc_t c_cc[NCCS];
+	speed_t __c_ispeed;
+	speed_t __c_ospeed;
+};
+
+#define VINTR     0
+#define VQUIT     1
+#define VERASE    2
+#define VKILL     3
+#define VEOF      4
+#define VTIME     5
+#define VMIN      6
+#define VSWTC     7
+#define VSTART    8
+#define VSTOP     9
+#define VSUSP    10
+#define VEOL     11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE  14
+#define VLNEXT   15
+#define VEOL2    16
+
+#define IGNBRK  0000001
+#define BRKINT  0000002
+#define IGNPAR  0000004
+#define PARMRK  0000010
+#define INPCK   0000020
+#define ISTRIP  0000040
+#define INLCR   0000100
+#define IGNCR   0000200
+#define ICRNL   0000400
+#define IUCLC   0001000
+#define IXON    0002000
+#define IXANY   0004000
+#define IXOFF   0010000
+#define IMAXBEL 0020000
+#define IUTF8   0040000
+
+#define OPOST  0000001
+#define OLCUC  0000002
+#define ONLCR  0000004
+#define OCRNL  0000010
+#define ONOCR  0000020
+#define ONLRET 0000040
+#define OFILL  0000100
+#define OFDEL  0000200
+#define NLDLY  0000400
+#define NL0    0000000
+#define NL1    0000400
+#define CRDLY  0003000
+#define CR0    0000000
+#define CR1    0001000
+#define CR2    0002000
+#define CR3    0003000
+#define TABDLY 0014000
+#define TAB0   0000000
+#define TAB1   0004000
+#define TAB2   0010000
+#define TAB3   0014000
+#define BSDLY  0020000
+#define BS0    0000000
+#define BS1    0020000
+#define FFDLY  0100000
+#define FF0    0000000
+#define FF1    0100000
+
+#define VTDLY  0040000
+#define VT0    0000000
+#define VT1    0040000
+
+#define B0       0000000
+#define B50      0000001
+#define B75      0000002
+#define B110     0000003
+#define B134     0000004
+#define B150     0000005
+#define B200     0000006
+#define B300     0000007
+#define B600     0000010
+#define B1200    0000011
+#define B1800    0000012
+#define B2400    0000013
+#define B4800    0000014
+#define B9600    0000015
+#define B19200   0000016
+#define B38400   0000017
+
+#define B57600   0010001
+#define B115200  0010002
+#define B230400  0010003
+#define B460800  0010004
+#define B500000  0010005
+#define B576000  0010006
+#define B921600  0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+
+#define CSIZE  0000060
+#define CS5    0000000
+#define CS6    0000020
+#define CS7    0000040
+#define CS8    0000060
+#define CSTOPB 0000100
+#define CREAD  0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL  0002000
+#define CLOCAL 0004000
+
+#define ISIG   0000001
+#define ICANON 0000002
+#define ECHO   0000010
+#define ECHOE  0000020
+#define ECHOK  0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define IEXTEN 0100000
+
+#define TCOOFF 0
+#define TCOON  1
+#define TCIOFF 2
+#define TCION  3
+
+#define TCIFLUSH  0
+#define TCOFLUSH  1
+#define TCIOFLUSH 2
+
+#define TCSANOW   0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define EXTA    0000016
+#define EXTB    0000017
+#define CBAUD   0010017
+#define CBAUDEX 0010000
+#define CIBAUD  002003600000
+#define CMSPAR  010000000000
+#define CRTSCTS 020000000000
+
+#define XCASE   0000004
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE  0004000
+#define FLUSHO  0010000
+#define PENDIN  0040000
+#define EXTPROC 0200000
+
+#define XTABS  0014000
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/byteswap.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/byteswap.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/byteswap.h	(revision 398)
@@ -0,0 +1,26 @@
+#ifndef _BYTESWAP_H
+#define _BYTESWAP_H
+
+#include <features.h>
+#include <stdint.h>
+
+static __inline uint16_t __bswap_16(uint16_t __x)
+{
+	return (__x<<8) | (__x>>8);
+}
+
+static __inline uint32_t __bswap_32(uint32_t __x)
+{
+	return (__x>>24) | ((__x>>8)&0xff00) | ((__x<<8)&0xff0000) | (__x<<24);
+}
+
+static __inline uint64_t __bswap_64(uint64_t __x)
+{
+	return ((__bswap_32(__x)+0ULL)<<32) | __bswap_32(__x>>32);
+}
+
+#define bswap_16(x) __bswap_16(x)
+#define bswap_32(x) __bswap_32(x)
+#define bswap_64(x) __bswap_64(x)
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/complex.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/complex.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/complex.h	(revision 398)
@@ -0,0 +1,133 @@
+#ifndef _COMPLEX_H
+#define _COMPLEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define complex _Complex
+#ifdef __GNUC__
+#define _Complex_I (__extension__ (0.0f+1.0fi))
+#else
+#define _Complex_I (0.0f+1.0fi)
+#endif
+#define I _Complex_I
+
+double complex cacos(double complex);
+float complex cacosf(float complex);
+long double complex cacosl(long double complex);
+
+double complex casin(double complex);
+float complex casinf(float complex);
+long double complex casinl(long double complex);
+
+double complex catan(double complex);
+float complex catanf(float complex);
+long double complex catanl(long double complex);
+
+double complex ccos(double complex);
+float complex ccosf(float complex);
+long double complex ccosl(long double complex);
+
+double complex csin(double complex);
+float complex csinf(float complex);
+long double complex csinl(long double complex);
+
+double complex ctan(double complex);
+float complex ctanf(float complex);
+long double complex ctanl(long double complex);
+
+double complex cacosh(double complex);
+float complex cacoshf(float complex);
+long double complex cacoshl(long double complex);
+
+double complex casinh(double complex);
+float complex casinhf(float complex);
+long double complex casinhl(long double complex);
+
+double complex catanh(double complex);
+float complex catanhf(float complex);
+long double complex catanhl(long double complex);
+
+double complex ccosh(double complex);
+float complex ccoshf(float complex);
+long double complex ccoshl(long double complex);
+
+double complex csinh(double complex);
+float complex csinhf(float complex);
+long double complex csinhl(long double complex);
+
+double complex ctanh(double complex);
+float complex ctanhf(float complex);
+long double complex ctanhl(long double complex);
+
+double complex cexp(double complex);
+float complex cexpf(float complex);
+long double complex cexpl(long double complex);
+
+double complex clog(double complex);
+float complex clogf(float complex);
+long double complex clogl(long double complex);
+
+double cabs(double complex);
+float cabsf(float complex);
+long double cabsl(long double complex);
+
+double complex cpow(double complex, double complex);
+float complex cpowf(float complex, float complex);
+long double complex cpowl(long double complex, long double complex);
+
+double complex csqrt(double complex);
+float complex csqrtf(float complex);
+long double complex csqrtl(long double complex);
+
+double carg(double complex);
+float cargf(float complex);
+long double cargl(long double complex);
+
+double cimag(double complex);
+float cimagf(float complex);
+long double cimagl(long double complex);
+
+double complex conj(double complex);
+float complex conjf(float complex);
+long double complex conjl(long double complex);
+
+double complex cproj(double complex);
+float complex cprojf(float complex);
+long double complex cprojl(long double complex);
+
+double creal(double complex);
+float crealf(float complex);
+long double creall(long double complex);
+
+#ifndef __cplusplus
+#define __CIMAG(x, t) \
+	(+(union { _Complex t __z; t __xy[2]; }){(_Complex t)(x)}.__xy[1])
+
+#define creal(x) ((double)(x))
+#define crealf(x) ((float)(x))
+#define creall(x) ((long double)(x))
+
+#define cimag(x) __CIMAG(x, double)
+#define cimagf(x) __CIMAG(x, float)
+#define cimagl(x) __CIMAG(x, long double)
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+#if defined(_Imaginary_I)
+#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y))
+#elif defined(__clang__)
+#define __CMPLX(x, y, t) (+(_Complex t){ (t)(x), (t)(y) })
+#else
+#define __CMPLX(x, y, t) (__builtin_complex((t)(x), (t)(y)))
+#endif
+#define CMPLX(x, y) __CMPLX(x, y, double)
+#define CMPLXF(x, y) __CMPLX(x, y, float)
+#define CMPLXL(x, y) __CMPLX(x, y, long double)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/cpio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/cpio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/cpio.h	(revision 398)
@@ -0,0 +1,29 @@
+#ifndef _CPIO_H
+#define _CPIO_H
+
+#define MAGIC "070707"
+
+#define C_IRUSR  000400
+#define C_IWUSR  000200
+#define C_IXUSR  000100
+#define C_IRGRP  000040
+#define C_IWGRP  000020
+#define C_IXGRP  000010
+#define C_IROTH  000004
+#define C_IWOTH  000002
+#define C_IXOTH  000001
+
+#define C_ISUID  004000
+#define C_ISGID  002000
+#define C_ISVTX  001000
+
+#define C_ISBLK  060000
+#define C_ISCHR  020000
+#define C_ISDIR  040000
+#define C_ISFIFO 010000
+#define C_ISSOCK 0140000
+#define C_ISLNK  0120000
+#define C_ISCTG  0110000
+#define C_ISREG  0100000
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/crypt.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/crypt.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/crypt.h	(revision 398)
@@ -0,0 +1,20 @@
+#ifndef _CRYPT_H
+#define _CRYPT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct crypt_data {
+	int initialized;
+	char __buf[256];
+};
+
+char *crypt(const char *, const char *);
+char *crypt_r(const char *, const char *, struct crypt_data *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ctype.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ctype.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ctype.h	(revision 398)
@@ -0,0 +1,75 @@
+#ifndef	_CTYPE_H
+#define	_CTYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+int   isalnum(int);
+int   isalpha(int);
+int   isblank(int);
+int   iscntrl(int);
+int   isdigit(int);
+int   isgraph(int);
+int   islower(int);
+int   isprint(int);
+int   ispunct(int);
+int   isspace(int);
+int   isupper(int);
+int   isxdigit(int);
+int   tolower(int);
+int   toupper(int);
+
+#ifndef __cplusplus
+static __inline int __isspace(int _c)
+{
+	return _c == ' ' || (unsigned)_c-'\t' < 5;
+}
+
+#define isalpha(a) (0 ? isalpha(a) : (((unsigned)(a)|32)-'a') < 26)
+#define isdigit(a) (0 ? isdigit(a) : ((unsigned)(a)-'0') < 10)
+#define islower(a) (0 ? islower(a) : ((unsigned)(a)-'a') < 26)
+#define isupper(a) (0 ? isupper(a) : ((unsigned)(a)-'A') < 26)
+#define isprint(a) (0 ? isprint(a) : ((unsigned)(a)-0x20) < 0x5f)
+#define isgraph(a) (0 ? isgraph(a) : ((unsigned)(a)-0x21) < 0x5e)
+#define isspace(a) __isspace(a)
+#endif
+
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#define __NEED_locale_t
+#include <bits/alltypes.h>
+
+int   isalnum_l(int, locale_t);
+int   isalpha_l(int, locale_t);
+int   isblank_l(int, locale_t);
+int   iscntrl_l(int, locale_t);
+int   isdigit_l(int, locale_t);
+int   isgraph_l(int, locale_t);
+int   islower_l(int, locale_t);
+int   isprint_l(int, locale_t);
+int   ispunct_l(int, locale_t);
+int   isspace_l(int, locale_t);
+int   isupper_l(int, locale_t);
+int   isxdigit_l(int, locale_t);
+int   tolower_l(int, locale_t);
+int   toupper_l(int, locale_t);
+
+int   isascii(int);
+int   toascii(int);
+#define _tolower(a) ((a)|0x20)
+#define _toupper(a) ((a)&0x5f)
+#define isascii(a) (0 ? isascii(a) : (unsigned)(a) < 128)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/dirent.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/dirent.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/dirent.h	(revision 398)
@@ -0,0 +1,81 @@
+#ifndef	_DIRENT_H
+#define	_DIRENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ino_t
+#define __NEED_off_t
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+typedef struct __dirstream DIR;
+
+struct dirent {
+	ino_t d_ino;
+	off_t d_off;
+	unsigned short d_reclen;
+	unsigned char d_type;
+	char d_name[256];
+};
+
+#define d_fileno d_ino
+
+int            closedir(DIR *);
+DIR           *fdopendir(int);
+DIR           *opendir(const char *);
+struct dirent *readdir(DIR *);
+int            readdir_r(DIR *__restrict, struct dirent *__restrict, struct dirent **__restrict);
+void           rewinddir(DIR *);
+int            dirfd(DIR *);
+
+int alphasort(const struct dirent **, const struct dirent **);
+int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **));
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void           seekdir(DIR *, long);
+long           telldir(DIR *);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 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
+#define IFTODT(x) ((x)>>12 & 017)
+#define DTTOIF(x) ((x)<<12)
+int getdents(int, struct dirent *, size_t);
+#endif
+
+#ifdef _GNU_SOURCE
+int versionsort(const struct dirent **, const struct dirent **);
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define dirent64 dirent
+#define readdir64 readdir
+#define readdir64_r readdir_r
+#define scandir64 scandir
+#define alphasort64 alphasort
+#define versionsort64 versionsort
+#define off64_t off_t
+#define ino64_t ino_t
+#define getdents64 getdents
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/dlfcn.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/dlfcn.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/dlfcn.h	(revision 398)
@@ -0,0 +1,42 @@
+#ifndef	_DLFCN_H
+#define	_DLFCN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define RTLD_LAZY   1
+#define RTLD_NOW    2
+#define RTLD_NOLOAD 4
+#define RTLD_NODELETE 4096
+#define RTLD_GLOBAL 256
+#define RTLD_LOCAL  0
+
+#define RTLD_NEXT    ((void *)-1)
+#define RTLD_DEFAULT ((void *)0)
+
+#define RTLD_DI_LINKMAP 2
+
+int    dlclose(void *);
+char  *dlerror(void);
+void  *dlopen(const char *, int);
+void  *dlsym(void *__restrict, const char *__restrict);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef struct {
+	const char *dli_fname;
+	void *dli_fbase;
+	const char *dli_sname;
+	void *dli_saddr;
+} Dl_info;
+int dladdr(const void *, Dl_info *);
+int dlinfo(void *, int, void *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/elf.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/elf.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/elf.h	(revision 398)
@@ -0,0 +1,3129 @@
+#ifndef _ELF_H
+#define _ELF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+typedef uint32_t Elf32_Word;
+typedef	int32_t  Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef	int32_t  Elf64_Sword;
+
+typedef uint64_t Elf32_Xword;
+typedef	int64_t  Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef	int64_t  Elf64_Sxword;
+
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+#define EI_NIDENT (16)
+
+typedef struct {
+  unsigned char	e_ident[EI_NIDENT];
+  Elf32_Half	e_type;
+  Elf32_Half	e_machine;
+  Elf32_Word	e_version;
+  Elf32_Addr	e_entry;
+  Elf32_Off	e_phoff;
+  Elf32_Off	e_shoff;
+  Elf32_Word	e_flags;
+  Elf32_Half	e_ehsize;
+  Elf32_Half	e_phentsize;
+  Elf32_Half	e_phnum;
+  Elf32_Half	e_shentsize;
+  Elf32_Half	e_shnum;
+  Elf32_Half	e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct {
+  unsigned char	e_ident[EI_NIDENT];
+  Elf64_Half	e_type;
+  Elf64_Half	e_machine;
+  Elf64_Word	e_version;
+  Elf64_Addr	e_entry;
+  Elf64_Off	e_phoff;
+  Elf64_Off	e_shoff;
+  Elf64_Word	e_flags;
+  Elf64_Half	e_ehsize;
+  Elf64_Half	e_phentsize;
+  Elf64_Half	e_phnum;
+  Elf64_Half	e_shentsize;
+  Elf64_Half	e_shnum;
+  Elf64_Half	e_shstrndx;
+} Elf64_Ehdr;
+
+#define EI_MAG0		0
+#define ELFMAG0		0x7f
+
+#define EI_MAG1		1
+#define ELFMAG1		'E'
+
+#define EI_MAG2		2
+#define ELFMAG2		'L'
+
+#define EI_MAG3		3
+#define ELFMAG3		'F'
+
+
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define EI_CLASS	4
+#define ELFCLASSNONE	0
+#define ELFCLASS32	1
+#define ELFCLASS64	2
+#define ELFCLASSNUM	3
+
+#define EI_DATA		5
+#define ELFDATANONE	0
+#define ELFDATA2LSB	1
+#define ELFDATA2MSB	2
+#define ELFDATANUM	3
+
+#define EI_VERSION	6
+
+
+#define EI_OSABI	7
+#define ELFOSABI_NONE		0
+#define ELFOSABI_SYSV		0
+#define ELFOSABI_HPUX		1
+#define ELFOSABI_NETBSD		2
+#define ELFOSABI_LINUX		3
+#define ELFOSABI_GNU		3
+#define ELFOSABI_SOLARIS	6
+#define ELFOSABI_AIX		7
+#define ELFOSABI_IRIX		8
+#define ELFOSABI_FREEBSD	9
+#define ELFOSABI_TRU64		10
+#define ELFOSABI_MODESTO	11
+#define ELFOSABI_OPENBSD	12
+#define ELFOSABI_ARM		97
+#define ELFOSABI_STANDALONE	255
+
+#define EI_ABIVERSION	8
+
+#define EI_PAD		9
+
+
+
+#define ET_NONE		0
+#define ET_REL		1
+#define ET_EXEC		2
+#define ET_DYN		3
+#define ET_CORE		4
+#define	ET_NUM		5
+#define ET_LOOS		0xfe00
+#define ET_HIOS		0xfeff
+#define ET_LOPROC	0xff00
+#define ET_HIPROC	0xffff
+
+
+
+#define EM_NONE		 0
+#define EM_M32		 1
+#define EM_SPARC	 2
+#define EM_386		 3
+#define EM_68K		 4
+#define EM_88K		 5
+#define EM_860		 7
+#define EM_MIPS		 8
+#define EM_S370		 9
+#define EM_MIPS_RS3_LE	10
+
+#define EM_PARISC	15
+#define EM_VPP500	17
+#define EM_SPARC32PLUS	18
+#define EM_960		19
+#define EM_PPC		20
+#define EM_PPC64	21
+#define EM_S390		22
+
+#define EM_V800		36
+#define EM_FR20		37
+#define EM_RH32		38
+#define EM_RCE		39
+#define EM_ARM		40
+#define EM_FAKE_ALPHA	41
+#define EM_SH		42
+#define EM_SPARCV9	43
+#define EM_TRICORE	44
+#define EM_ARC		45
+#define EM_H8_300	46
+#define EM_H8_300H	47
+#define EM_H8S		48
+#define EM_H8_500	49
+#define EM_IA_64	50
+#define EM_MIPS_X	51
+#define EM_COLDFIRE	52
+#define EM_68HC12	53
+#define EM_MMA		54
+#define EM_PCP		55
+#define EM_NCPU		56
+#define EM_NDR1		57
+#define EM_STARCORE	58
+#define EM_ME16		59
+#define EM_ST100	60
+#define EM_TINYJ	61
+#define EM_X86_64	62
+#define EM_PDSP		63
+
+#define EM_FX66		66
+#define EM_ST9PLUS	67
+#define EM_ST7		68
+#define EM_68HC16	69
+#define EM_68HC11	70
+#define EM_68HC08	71
+#define EM_68HC05	72
+#define EM_SVX		73
+#define EM_ST19		74
+#define EM_VAX		75
+#define EM_CRIS		76
+#define EM_JAVELIN	77
+#define EM_FIREPATH	78
+#define EM_ZSP		79
+#define EM_MMIX		80
+#define EM_HUANY	81
+#define EM_PRISM	82
+#define EM_AVR		83
+#define EM_FR30		84
+#define EM_D10V		85
+#define EM_D30V		86
+#define EM_V850		87
+#define EM_M32R		88
+#define EM_MN10300	89
+#define EM_MN10200	90
+#define EM_PJ		91
+#define EM_OR1K		92
+#define EM_OPENRISC	92
+#define EM_ARC_A5	93
+#define EM_ARC_COMPACT	93
+#define EM_XTENSA	94
+#define EM_VIDEOCORE	95
+#define EM_TMM_GPP	96
+#define EM_NS32K	97
+#define EM_TPC		98
+#define EM_SNP1K	99
+#define EM_ST200	100
+#define EM_IP2K		101
+#define EM_MAX		102
+#define EM_CR		103
+#define EM_F2MC16	104
+#define EM_MSP430	105
+#define EM_BLACKFIN	106
+#define EM_SE_C33	107
+#define EM_SEP		108
+#define EM_ARCA		109
+#define EM_UNICORE	110
+#define EM_EXCESS	111
+#define EM_DXP		112
+#define EM_ALTERA_NIOS2 113
+#define EM_CRX		114
+#define EM_XGATE	115
+#define EM_C166		116
+#define EM_M16C		117
+#define EM_DSPIC30F	118
+#define EM_CE		119
+#define EM_M32C		120
+#define EM_TSK3000	131
+#define EM_RS08		132
+#define EM_SHARC	133
+#define EM_ECOG2	134
+#define EM_SCORE7	135
+#define EM_DSP24	136
+#define EM_VIDEOCORE3	137
+#define EM_LATTICEMICO32 138
+#define EM_SE_C17	139
+#define EM_TI_C6000	140
+#define EM_TI_C2000	141
+#define EM_TI_C5500	142
+#define EM_TI_ARP32	143
+#define EM_TI_PRU	144
+#define EM_MMDSP_PLUS	160
+#define EM_CYPRESS_M8C	161
+#define EM_R32C		162
+#define EM_TRIMEDIA	163
+#define EM_QDSP6	164
+#define EM_8051		165
+#define EM_STXP7X	166
+#define EM_NDS32	167
+#define EM_ECOG1X	168
+#define EM_MAXQ30	169
+#define EM_XIMO16	170
+#define EM_MANIK	171
+#define EM_CRAYNV2	172
+#define EM_RX		173
+#define EM_METAG	174
+#define EM_MCST_ELBRUS	175
+#define EM_ECOG16	176
+#define EM_CR16		177
+#define EM_ETPU		178
+#define EM_SLE9X	179
+#define EM_L10M		180
+#define EM_K10M		181
+#define EM_AARCH64	183
+#define EM_AVR32	185
+#define EM_STM8		186
+#define EM_TILE64	187
+#define EM_TILEPRO	188
+#define EM_MICROBLAZE	189
+#define EM_CUDA		190
+#define EM_TILEGX	191
+#define EM_CLOUDSHIELD	192
+#define EM_COREA_1ST	193
+#define EM_COREA_2ND	194
+#define EM_ARC_COMPACT2	195
+#define EM_OPEN8	196
+#define EM_RL78		197
+#define EM_VIDEOCORE5	198
+#define EM_78KOR	199
+#define EM_56800EX	200
+#define EM_BA1		201
+#define EM_BA2		202
+#define EM_XCORE	203
+#define EM_MCHP_PIC	204
+#define EM_KM32		210
+#define EM_KMX32	211
+#define EM_EMX16	212
+#define EM_EMX8		213
+#define EM_KVARC	214
+#define EM_CDP		215
+#define EM_COGE		216
+#define EM_COOL		217
+#define EM_NORC		218
+#define EM_CSR_KALIMBA	219
+#define EM_Z80		220
+#define EM_VISIUM	221
+#define EM_FT32		222
+#define EM_MOXIE	223
+#define EM_AMDGPU	224
+#define EM_RISCV	243
+#define EM_BPF		247
+#define EM_NUM		248
+
+#define EM_ALPHA	0x9026
+
+#define EV_NONE		0
+#define EV_CURRENT	1
+#define EV_NUM		2
+
+typedef struct {
+  Elf32_Word	sh_name;
+  Elf32_Word	sh_type;
+  Elf32_Word	sh_flags;
+  Elf32_Addr	sh_addr;
+  Elf32_Off	sh_offset;
+  Elf32_Word	sh_size;
+  Elf32_Word	sh_link;
+  Elf32_Word	sh_info;
+  Elf32_Word	sh_addralign;
+  Elf32_Word	sh_entsize;
+} Elf32_Shdr;
+
+typedef struct {
+  Elf64_Word	sh_name;
+  Elf64_Word	sh_type;
+  Elf64_Xword	sh_flags;
+  Elf64_Addr	sh_addr;
+  Elf64_Off	sh_offset;
+  Elf64_Xword	sh_size;
+  Elf64_Word	sh_link;
+  Elf64_Word	sh_info;
+  Elf64_Xword	sh_addralign;
+  Elf64_Xword	sh_entsize;
+} Elf64_Shdr;
+
+
+
+#define SHN_UNDEF	0
+#define SHN_LORESERVE	0xff00
+#define SHN_LOPROC	0xff00
+#define SHN_BEFORE	0xff00
+
+#define SHN_AFTER	0xff01
+
+#define SHN_HIPROC	0xff1f
+#define SHN_LOOS	0xff20
+#define SHN_HIOS	0xff3f
+#define SHN_ABS		0xfff1
+#define SHN_COMMON	0xfff2
+#define SHN_XINDEX	0xffff
+#define SHN_HIRESERVE	0xffff
+
+
+
+#define SHT_NULL	  0
+#define SHT_PROGBITS	  1
+#define SHT_SYMTAB	  2
+#define SHT_STRTAB	  3
+#define SHT_RELA	  4
+#define SHT_HASH	  5
+#define SHT_DYNAMIC	  6
+#define SHT_NOTE	  7
+#define SHT_NOBITS	  8
+#define SHT_REL		  9
+#define SHT_SHLIB	  10
+#define SHT_DYNSYM	  11
+#define SHT_INIT_ARRAY	  14
+#define SHT_FINI_ARRAY	  15
+#define SHT_PREINIT_ARRAY 16
+#define SHT_GROUP	  17
+#define SHT_SYMTAB_SHNDX  18
+#define	SHT_NUM		  19
+#define SHT_LOOS	  0x60000000
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5
+#define SHT_GNU_HASH	  0x6ffffff6
+#define SHT_GNU_LIBLIST	  0x6ffffff7
+#define SHT_CHECKSUM	  0x6ffffff8
+#define SHT_LOSUNW	  0x6ffffffa
+#define SHT_SUNW_move	  0x6ffffffa
+#define SHT_SUNW_COMDAT   0x6ffffffb
+#define SHT_SUNW_syminfo  0x6ffffffc
+#define SHT_GNU_verdef	  0x6ffffffd
+#define SHT_GNU_verneed	  0x6ffffffe
+#define SHT_GNU_versym	  0x6fffffff
+#define SHT_HISUNW	  0x6fffffff
+#define SHT_HIOS	  0x6fffffff
+#define SHT_LOPROC	  0x70000000
+#define SHT_HIPROC	  0x7fffffff
+#define SHT_LOUSER	  0x80000000
+#define SHT_HIUSER	  0x8fffffff
+
+#define SHF_WRITE	     (1 << 0)
+#define SHF_ALLOC	     (1 << 1)
+#define SHF_EXECINSTR	     (1 << 2)
+#define SHF_MERGE	     (1 << 4)
+#define SHF_STRINGS	     (1 << 5)
+#define SHF_INFO_LINK	     (1 << 6)
+#define SHF_LINK_ORDER	     (1 << 7)
+#define SHF_OS_NONCONFORMING (1 << 8)
+
+#define SHF_GROUP	     (1 << 9)
+#define SHF_TLS		     (1 << 10)
+#define SHF_COMPRESSED	     (1 << 11)
+#define SHF_MASKOS	     0x0ff00000
+#define SHF_MASKPROC	     0xf0000000
+#define SHF_ORDERED	     (1 << 30)
+#define SHF_EXCLUDE	     (1U << 31)
+
+typedef struct {
+  Elf32_Word	ch_type;
+  Elf32_Word	ch_size;
+  Elf32_Word	ch_addralign;
+} Elf32_Chdr;
+
+typedef struct {
+  Elf64_Word	ch_type;
+  Elf64_Word	ch_reserved;
+  Elf64_Xword	ch_size;
+  Elf64_Xword	ch_addralign;
+} Elf64_Chdr;
+
+#define ELFCOMPRESS_ZLIB	1
+#define ELFCOMPRESS_LOOS	0x60000000
+#define ELFCOMPRESS_HIOS	0x6fffffff
+#define ELFCOMPRESS_LOPROC	0x70000000
+#define ELFCOMPRESS_HIPROC	0x7fffffff
+
+
+#define GRP_COMDAT	0x1
+
+typedef struct {
+  Elf32_Word	st_name;
+  Elf32_Addr	st_value;
+  Elf32_Word	st_size;
+  unsigned char	st_info;
+  unsigned char	st_other;
+  Elf32_Section	st_shndx;
+} Elf32_Sym;
+
+typedef struct {
+  Elf64_Word	st_name;
+  unsigned char	st_info;
+  unsigned char st_other;
+  Elf64_Section	st_shndx;
+  Elf64_Addr	st_value;
+  Elf64_Xword	st_size;
+} Elf64_Sym;
+
+typedef struct {
+  Elf32_Half si_boundto;
+  Elf32_Half si_flags;
+} Elf32_Syminfo;
+
+typedef struct {
+  Elf64_Half si_boundto;
+  Elf64_Half si_flags;
+} Elf64_Syminfo;
+
+#define SYMINFO_BT_SELF		0xffff
+#define SYMINFO_BT_PARENT	0xfffe
+#define SYMINFO_BT_LOWRESERVE	0xff00
+
+#define SYMINFO_FLG_DIRECT	0x0001
+#define SYMINFO_FLG_PASSTHRU	0x0002
+#define SYMINFO_FLG_COPY	0x0004
+#define SYMINFO_FLG_LAZYLOAD	0x0008
+
+#define SYMINFO_NONE		0
+#define SYMINFO_CURRENT		1
+#define SYMINFO_NUM		2
+
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
+
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
+
+#define STB_LOCAL	0
+#define STB_GLOBAL	1
+#define STB_WEAK	2
+#define	STB_NUM		3
+#define STB_LOOS	10
+#define STB_GNU_UNIQUE	10
+#define STB_HIOS	12
+#define STB_LOPROC	13
+#define STB_HIPROC	15
+
+#define STT_NOTYPE	0
+#define STT_OBJECT	1
+#define STT_FUNC	2
+#define STT_SECTION	3
+#define STT_FILE	4
+#define STT_COMMON	5
+#define STT_TLS		6
+#define	STT_NUM		7
+#define STT_LOOS	10
+#define STT_GNU_IFUNC	10
+#define STT_HIOS	12
+#define STT_LOPROC	13
+#define STT_HIPROC	15
+
+#define STN_UNDEF	0
+
+#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
+#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
+
+#define STV_DEFAULT	0
+#define STV_INTERNAL	1
+#define STV_HIDDEN	2
+#define STV_PROTECTED	3
+
+
+
+
+typedef struct {
+  Elf32_Addr	r_offset;
+  Elf32_Word	r_info;
+} Elf32_Rel;
+
+typedef struct {
+  Elf64_Addr	r_offset;
+  Elf64_Xword	r_info;
+} Elf64_Rel;
+
+
+
+typedef struct {
+  Elf32_Addr	r_offset;
+  Elf32_Word	r_info;
+  Elf32_Sword	r_addend;
+} Elf32_Rela;
+
+typedef struct {
+  Elf64_Addr	r_offset;
+  Elf64_Xword	r_info;
+  Elf64_Sxword	r_addend;
+} Elf64_Rela;
+
+
+
+#define ELF32_R_SYM(val)		((val) >> 8)
+#define ELF32_R_TYPE(val)		((val) & 0xff)
+#define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)			((i) >> 32)
+#define ELF64_R_TYPE(i)			((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
+
+
+
+typedef struct {
+  Elf32_Word	p_type;
+  Elf32_Off	p_offset;
+  Elf32_Addr	p_vaddr;
+  Elf32_Addr	p_paddr;
+  Elf32_Word	p_filesz;
+  Elf32_Word	p_memsz;
+  Elf32_Word	p_flags;
+  Elf32_Word	p_align;
+} Elf32_Phdr;
+
+typedef struct {
+  Elf64_Word	p_type;
+  Elf64_Word	p_flags;
+  Elf64_Off	p_offset;
+  Elf64_Addr	p_vaddr;
+  Elf64_Addr	p_paddr;
+  Elf64_Xword	p_filesz;
+  Elf64_Xword	p_memsz;
+  Elf64_Xword	p_align;
+} Elf64_Phdr;
+
+
+
+#define	PT_NULL		0
+#define PT_LOAD		1
+#define PT_DYNAMIC	2
+#define PT_INTERP	3
+#define PT_NOTE		4
+#define PT_SHLIB	5
+#define PT_PHDR		6
+#define PT_TLS		7
+#define	PT_NUM		8
+#define PT_LOOS		0x60000000
+#define PT_GNU_EH_FRAME	0x6474e550
+#define PT_GNU_STACK	0x6474e551
+#define PT_GNU_RELRO	0x6474e552
+#define PT_LOSUNW	0x6ffffffa
+#define PT_SUNWBSS	0x6ffffffa
+#define PT_SUNWSTACK	0x6ffffffb
+#define PT_HISUNW	0x6fffffff
+#define PT_HIOS		0x6fffffff
+#define PT_LOPROC	0x70000000
+#define PT_HIPROC	0x7fffffff
+
+
+#define PN_XNUM 0xffff
+
+
+#define PF_X		(1 << 0)
+#define PF_W		(1 << 1)
+#define PF_R		(1 << 2)
+#define PF_MASKOS	0x0ff00000
+#define PF_MASKPROC	0xf0000000
+
+
+
+#define NT_PRSTATUS	1
+#define NT_FPREGSET	2
+#define NT_PRPSINFO	3
+#define NT_PRXREG	4
+#define NT_TASKSTRUCT	4
+#define NT_PLATFORM	5
+#define NT_AUXV		6
+#define NT_GWINDOWS	7
+#define NT_ASRS		8
+#define NT_PSTATUS	10
+#define NT_PSINFO	13
+#define NT_PRCRED	14
+#define NT_UTSNAME	15
+#define NT_LWPSTATUS	16
+#define NT_LWPSINFO	17
+#define NT_PRFPXREG	20
+#define NT_SIGINFO	0x53494749
+#define NT_FILE		0x46494c45
+#define NT_PRXFPREG	0x46e62b7f
+#define NT_PPC_VMX	0x100
+#define NT_PPC_SPE	0x101
+#define NT_PPC_VSX	0x102
+#define NT_386_TLS	0x200
+#define NT_386_IOPERM	0x201
+#define NT_X86_XSTATE	0x202
+#define NT_S390_HIGH_GPRS	0x300
+#define NT_S390_TIMER	0x301
+#define NT_S390_TODCMP	0x302
+#define NT_S390_TODPREG	0x303
+#define NT_S390_CTRS	0x304
+#define NT_S390_PREFIX	0x305
+#define NT_S390_LAST_BREAK	0x306
+#define NT_S390_SYSTEM_CALL	0x307
+#define NT_S390_TDB	0x308
+#define NT_ARM_VFP	0x400
+#define NT_ARM_TLS	0x401
+#define NT_ARM_HW_BREAK	0x402
+#define NT_ARM_HW_WATCH	0x403
+#define NT_ARM_SYSTEM_CALL	0x404
+#define NT_METAG_CBUF	0x500
+#define NT_METAG_RPIPE	0x501
+#define NT_METAG_TLS	0x502
+#define NT_VERSION	1
+
+
+
+
+typedef struct {
+  Elf32_Sword d_tag;
+  union {
+      Elf32_Word d_val;
+      Elf32_Addr d_ptr;
+  } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+  Elf64_Sxword d_tag;
+  union {
+      Elf64_Xword d_val;
+      Elf64_Addr d_ptr;
+  } d_un;
+} Elf64_Dyn;
+
+
+
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT	9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH	15
+#define DT_SYMBOLIC	16
+#define DT_REL		17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
+#define	DT_BIND_NOW	24
+#define	DT_INIT_ARRAY	25
+#define	DT_FINI_ARRAY	26
+#define	DT_INIT_ARRAYSZ	27
+#define	DT_FINI_ARRAYSZ	28
+#define DT_RUNPATH	29
+#define DT_FLAGS	30
+#define DT_ENCODING	32
+#define DT_PREINIT_ARRAY 32
+#define DT_PREINIT_ARRAYSZ 33
+#define	DT_NUM		34
+#define DT_LOOS		0x6000000d
+#define DT_HIOS		0x6ffff000
+#define DT_LOPROC	0x70000000
+#define DT_HIPROC	0x7fffffff
+#define	DT_PROCNUM	DT_MIPS_NUM
+
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc
+#define DT_POSFLAG_1	0x6ffffdfd
+
+#define DT_SYMINSZ	0x6ffffdfe
+#define DT_SYMINENT	0x6ffffdff
+#define DT_VALRNGHI	0x6ffffdff
+#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))
+#define DT_VALNUM 12
+
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_GNU_HASH	0x6ffffef5
+#define DT_TLSDESC_PLT	0x6ffffef6
+#define DT_TLSDESC_GOT	0x6ffffef7
+#define DT_GNU_CONFLICT	0x6ffffef8
+#define DT_GNU_LIBLIST	0x6ffffef9
+#define DT_CONFIG	0x6ffffefa
+#define DT_DEPAUDIT	0x6ffffefb
+#define DT_AUDIT	0x6ffffefc
+#define	DT_PLTPAD	0x6ffffefd
+#define	DT_MOVETAB	0x6ffffefe
+#define DT_SYMINFO	0x6ffffeff
+#define DT_ADDRRNGHI	0x6ffffeff
+#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))
+#define DT_ADDRNUM 11
+
+
+
+#define DT_VERSYM	0x6ffffff0
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
+
+
+#define DT_FLAGS_1	0x6ffffffb
+#define	DT_VERDEF	0x6ffffffc
+
+#define	DT_VERDEFNUM	0x6ffffffd
+#define	DT_VERNEED	0x6ffffffe
+
+#define	DT_VERNEEDNUM	0x6fffffff
+#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))
+#define DT_VERSIONTAGNUM 16
+
+
+
+#define DT_AUXILIARY    0x7ffffffd
+#define DT_FILTER       0x7fffffff
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+
+#define DF_ORIGIN	0x00000001
+#define DF_SYMBOLIC	0x00000002
+#define DF_TEXTREL	0x00000004
+#define DF_BIND_NOW	0x00000008
+#define DF_STATIC_TLS	0x00000010
+
+
+
+#define DF_1_NOW	0x00000001
+#define DF_1_GLOBAL	0x00000002
+#define DF_1_GROUP	0x00000004
+#define DF_1_NODELETE	0x00000008
+#define DF_1_LOADFLTR	0x00000010
+#define DF_1_INITFIRST	0x00000020
+#define DF_1_NOOPEN	0x00000040
+#define DF_1_ORIGIN	0x00000080
+#define DF_1_DIRECT	0x00000100
+#define DF_1_TRANS	0x00000200
+#define DF_1_INTERPOSE	0x00000400
+#define DF_1_NODEFLIB	0x00000800
+#define DF_1_NODUMP	0x00001000
+#define DF_1_CONFALT	0x00002000
+#define DF_1_ENDFILTEE	0x00004000
+#define	DF_1_DISPRELDNE	0x00008000
+#define	DF_1_DISPRELPND	0x00010000
+#define	DF_1_NODIRECT	0x00020000
+#define	DF_1_IGNMULDEF	0x00040000
+#define	DF_1_NOKSYMS	0x00080000
+#define	DF_1_NOHDR	0x00100000
+#define	DF_1_EDITED	0x00200000
+#define	DF_1_NORELOC	0x00400000
+#define	DF_1_SYMINTPOSE	0x00800000
+#define	DF_1_GLOBAUDIT	0x01000000
+#define	DF_1_SINGLETON	0x02000000
+
+#define DTF_1_PARINIT	0x00000001
+#define DTF_1_CONFEXP	0x00000002
+
+
+#define DF_P1_LAZYLOAD	0x00000001
+#define DF_P1_GROUPPERM	0x00000002
+
+
+
+
+typedef struct {
+  Elf32_Half	vd_version;
+  Elf32_Half	vd_flags;
+  Elf32_Half	vd_ndx;
+  Elf32_Half	vd_cnt;
+  Elf32_Word	vd_hash;
+  Elf32_Word	vd_aux;
+  Elf32_Word	vd_next;
+} Elf32_Verdef;
+
+typedef struct {
+  Elf64_Half	vd_version;
+  Elf64_Half	vd_flags;
+  Elf64_Half	vd_ndx;
+  Elf64_Half	vd_cnt;
+  Elf64_Word	vd_hash;
+  Elf64_Word	vd_aux;
+  Elf64_Word	vd_next;
+} Elf64_Verdef;
+
+
+
+#define VER_DEF_NONE	0
+#define VER_DEF_CURRENT	1
+#define VER_DEF_NUM	2
+
+
+#define VER_FLG_BASE	0x1
+#define VER_FLG_WEAK	0x2
+
+
+#define	VER_NDX_LOCAL		0
+#define	VER_NDX_GLOBAL		1
+#define	VER_NDX_LORESERVE	0xff00
+#define	VER_NDX_ELIMINATE	0xff01
+
+
+
+typedef struct {
+  Elf32_Word	vda_name;
+  Elf32_Word	vda_next;
+} Elf32_Verdaux;
+
+typedef struct {
+  Elf64_Word	vda_name;
+  Elf64_Word	vda_next;
+} Elf64_Verdaux;
+
+
+
+
+typedef struct {
+  Elf32_Half	vn_version;
+  Elf32_Half	vn_cnt;
+  Elf32_Word	vn_file;
+  Elf32_Word	vn_aux;
+  Elf32_Word	vn_next;
+} Elf32_Verneed;
+
+typedef struct {
+  Elf64_Half	vn_version;
+  Elf64_Half	vn_cnt;
+  Elf64_Word	vn_file;
+  Elf64_Word	vn_aux;
+  Elf64_Word	vn_next;
+} Elf64_Verneed;
+
+
+
+#define VER_NEED_NONE	 0
+#define VER_NEED_CURRENT 1
+#define VER_NEED_NUM	 2
+
+
+
+typedef struct {
+  Elf32_Word	vna_hash;
+  Elf32_Half	vna_flags;
+  Elf32_Half	vna_other;
+  Elf32_Word	vna_name;
+  Elf32_Word	vna_next;
+} Elf32_Vernaux;
+
+typedef struct {
+  Elf64_Word	vna_hash;
+  Elf64_Half	vna_flags;
+  Elf64_Half	vna_other;
+  Elf64_Word	vna_name;
+  Elf64_Word	vna_next;
+} Elf64_Vernaux;
+
+
+
+#define VER_FLG_WEAK	0x2
+
+
+
+typedef struct {
+  uint32_t a_type;
+  union {
+      uint32_t a_val;
+  } a_un;
+} Elf32_auxv_t;
+
+typedef struct {
+  uint64_t a_type;
+  union {
+      uint64_t a_val;
+  } a_un;
+} Elf64_auxv_t;
+
+
+
+#define AT_NULL		0
+#define AT_IGNORE	1
+#define AT_EXECFD	2
+#define AT_PHDR		3
+#define AT_PHENT	4
+#define AT_PHNUM	5
+#define AT_PAGESZ	6
+#define AT_BASE		7
+#define AT_FLAGS	8
+#define AT_ENTRY	9
+#define AT_NOTELF	10
+#define AT_UID		11
+#define AT_EUID		12
+#define AT_GID		13
+#define AT_EGID		14
+#define AT_CLKTCK	17
+
+
+#define AT_PLATFORM	15
+#define AT_HWCAP	16
+
+
+
+
+#define AT_FPUCW	18
+
+
+#define AT_DCACHEBSIZE	19
+#define AT_ICACHEBSIZE	20
+#define AT_UCACHEBSIZE	21
+
+
+
+#define AT_IGNOREPPC	22
+
+#define	AT_SECURE	23
+
+#define AT_BASE_PLATFORM 24
+
+#define AT_RANDOM	25
+
+#define AT_HWCAP2	26
+
+#define AT_EXECFN	31
+
+
+
+#define AT_SYSINFO	32
+#define AT_SYSINFO_EHDR	33
+
+
+
+#define AT_L1I_CACHESHAPE	34
+#define AT_L1D_CACHESHAPE	35
+#define AT_L2_CACHESHAPE	36
+#define AT_L3_CACHESHAPE	37
+
+
+
+
+typedef struct {
+  Elf32_Word n_namesz;
+  Elf32_Word n_descsz;
+  Elf32_Word n_type;
+} Elf32_Nhdr;
+
+typedef struct {
+  Elf64_Word n_namesz;
+  Elf64_Word n_descsz;
+  Elf64_Word n_type;
+} Elf64_Nhdr;
+
+
+
+
+#define ELF_NOTE_SOLARIS	"SUNW Solaris"
+
+
+#define ELF_NOTE_GNU		"GNU"
+
+
+
+
+
+#define ELF_NOTE_PAGESIZE_HINT	1
+
+
+#define NT_GNU_ABI_TAG	1
+#define ELF_NOTE_ABI	NT_GNU_ABI_TAG
+
+
+
+#define ELF_NOTE_OS_LINUX	0
+#define ELF_NOTE_OS_GNU		1
+#define ELF_NOTE_OS_SOLARIS2	2
+#define ELF_NOTE_OS_FREEBSD	3
+
+#define NT_GNU_BUILD_ID	3
+#define NT_GNU_GOLD_VERSION	4
+
+
+
+typedef struct {
+  Elf32_Xword m_value;
+  Elf32_Word m_info;
+  Elf32_Word m_poffset;
+  Elf32_Half m_repeat;
+  Elf32_Half m_stride;
+} Elf32_Move;
+
+typedef struct {
+  Elf64_Xword m_value;
+  Elf64_Xword m_info;
+  Elf64_Xword m_poffset;
+  Elf64_Half m_repeat;
+  Elf64_Half m_stride;
+} Elf64_Move;
+
+
+#define ELF32_M_SYM(info)	((info) >> 8)
+#define ELF32_M_SIZE(info)	((unsigned char) (info))
+#define ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)	ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)	ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size)	ELF32_M_INFO (sym, size)
+
+#define EF_CPU32	0x00810000
+
+#define R_68K_NONE	0
+#define R_68K_32	1
+#define R_68K_16	2
+#define R_68K_8		3
+#define R_68K_PC32	4
+#define R_68K_PC16	5
+#define R_68K_PC8	6
+#define R_68K_GOT32	7
+#define R_68K_GOT16	8
+#define R_68K_GOT8	9
+#define R_68K_GOT32O	10
+#define R_68K_GOT16O	11
+#define R_68K_GOT8O	12
+#define R_68K_PLT32	13
+#define R_68K_PLT16	14
+#define R_68K_PLT8	15
+#define R_68K_PLT32O	16
+#define R_68K_PLT16O	17
+#define R_68K_PLT8O	18
+#define R_68K_COPY	19
+#define R_68K_GLOB_DAT	20
+#define R_68K_JMP_SLOT	21
+#define R_68K_RELATIVE	22
+#define R_68K_NUM	23
+
+#define R_386_NONE	   0
+#define R_386_32	   1
+#define R_386_PC32	   2
+#define R_386_GOT32	   3
+#define R_386_PLT32	   4
+#define R_386_COPY	   5
+#define R_386_GLOB_DAT	   6
+#define R_386_JMP_SLOT	   7
+#define R_386_RELATIVE	   8
+#define R_386_GOTOFF	   9
+#define R_386_GOTPC	   10
+#define R_386_32PLT	   11
+#define R_386_TLS_TPOFF	   14
+#define R_386_TLS_IE	   15
+#define R_386_TLS_GOTIE	   16
+#define R_386_TLS_LE	   17
+#define R_386_TLS_GD	   18
+#define R_386_TLS_LDM	   19
+#define R_386_16	   20
+#define R_386_PC16	   21
+#define R_386_8		   22
+#define R_386_PC8	   23
+#define R_386_TLS_GD_32	   24
+#define R_386_TLS_GD_PUSH  25
+#define R_386_TLS_GD_CALL  26
+#define R_386_TLS_GD_POP   27
+#define R_386_TLS_LDM_32   28
+#define R_386_TLS_LDM_PUSH 29
+#define R_386_TLS_LDM_CALL 30
+#define R_386_TLS_LDM_POP  31
+#define R_386_TLS_LDO_32   32
+#define R_386_TLS_IE_32	   33
+#define R_386_TLS_LE_32	   34
+#define R_386_TLS_DTPMOD32 35
+#define R_386_TLS_DTPOFF32 36
+#define R_386_TLS_TPOFF32  37
+#define R_386_SIZE32       38
+#define R_386_TLS_GOTDESC  39
+#define R_386_TLS_DESC_CALL 40
+#define R_386_TLS_DESC     41
+#define R_386_IRELATIVE	   42
+#define R_386_GOT32X	   43
+#define R_386_NUM	   44
+
+
+
+
+
+#define STT_SPARC_REGISTER	13
+
+
+
+#define EF_SPARCV9_MM		3
+#define EF_SPARCV9_TSO		0
+#define EF_SPARCV9_PSO		1
+#define EF_SPARCV9_RMO		2
+#define EF_SPARC_LEDATA		0x800000
+#define EF_SPARC_EXT_MASK	0xFFFF00
+#define EF_SPARC_32PLUS		0x000100
+#define EF_SPARC_SUN_US1	0x000200
+#define EF_SPARC_HAL_R1		0x000400
+#define EF_SPARC_SUN_US3	0x000800
+
+
+
+#define R_SPARC_NONE		0
+#define R_SPARC_8		1
+#define R_SPARC_16		2
+#define R_SPARC_32		3
+#define R_SPARC_DISP8		4
+#define R_SPARC_DISP16		5
+#define R_SPARC_DISP32		6
+#define R_SPARC_WDISP30		7
+#define R_SPARC_WDISP22		8
+#define R_SPARC_HI22		9
+#define R_SPARC_22		10
+#define R_SPARC_13		11
+#define R_SPARC_LO10		12
+#define R_SPARC_GOT10		13
+#define R_SPARC_GOT13		14
+#define R_SPARC_GOT22		15
+#define R_SPARC_PC10		16
+#define R_SPARC_PC22		17
+#define R_SPARC_WPLT30		18
+#define R_SPARC_COPY		19
+#define R_SPARC_GLOB_DAT	20
+#define R_SPARC_JMP_SLOT	21
+#define R_SPARC_RELATIVE	22
+#define R_SPARC_UA32		23
+
+
+
+#define R_SPARC_PLT32		24
+#define R_SPARC_HIPLT22		25
+#define R_SPARC_LOPLT10		26
+#define R_SPARC_PCPLT32		27
+#define R_SPARC_PCPLT22		28
+#define R_SPARC_PCPLT10		29
+#define R_SPARC_10		30
+#define R_SPARC_11		31
+#define R_SPARC_64		32
+#define R_SPARC_OLO10		33
+#define R_SPARC_HH22		34
+#define R_SPARC_HM10		35
+#define R_SPARC_LM22		36
+#define R_SPARC_PC_HH22		37
+#define R_SPARC_PC_HM10		38
+#define R_SPARC_PC_LM22		39
+#define R_SPARC_WDISP16		40
+#define R_SPARC_WDISP19		41
+#define R_SPARC_GLOB_JMP	42
+#define R_SPARC_7		43
+#define R_SPARC_5		44
+#define R_SPARC_6		45
+#define R_SPARC_DISP64		46
+#define R_SPARC_PLT64		47
+#define R_SPARC_HIX22		48
+#define R_SPARC_LOX10		49
+#define R_SPARC_H44		50
+#define R_SPARC_M44		51
+#define R_SPARC_L44		52
+#define R_SPARC_REGISTER	53
+#define R_SPARC_UA64		54
+#define R_SPARC_UA16		55
+#define R_SPARC_TLS_GD_HI22	56
+#define R_SPARC_TLS_GD_LO10	57
+#define R_SPARC_TLS_GD_ADD	58
+#define R_SPARC_TLS_GD_CALL	59
+#define R_SPARC_TLS_LDM_HI22	60
+#define R_SPARC_TLS_LDM_LO10	61
+#define R_SPARC_TLS_LDM_ADD	62
+#define R_SPARC_TLS_LDM_CALL	63
+#define R_SPARC_TLS_LDO_HIX22	64
+#define R_SPARC_TLS_LDO_LOX10	65
+#define R_SPARC_TLS_LDO_ADD	66
+#define R_SPARC_TLS_IE_HI22	67
+#define R_SPARC_TLS_IE_LO10	68
+#define R_SPARC_TLS_IE_LD	69
+#define R_SPARC_TLS_IE_LDX	70
+#define R_SPARC_TLS_IE_ADD	71
+#define R_SPARC_TLS_LE_HIX22	72
+#define R_SPARC_TLS_LE_LOX10	73
+#define R_SPARC_TLS_DTPMOD32	74
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF32	76
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF32	78
+#define R_SPARC_TLS_TPOFF64	79
+#define R_SPARC_GOTDATA_HIX22	80
+#define R_SPARC_GOTDATA_LOX10	81
+#define R_SPARC_GOTDATA_OP_HIX22	82
+#define R_SPARC_GOTDATA_OP_LOX10	83
+#define R_SPARC_GOTDATA_OP	84
+#define R_SPARC_H34		85
+#define R_SPARC_SIZE32		86
+#define R_SPARC_SIZE64		87
+#define R_SPARC_GNU_VTINHERIT	250
+#define R_SPARC_GNU_VTENTRY	251
+#define R_SPARC_REV32		252
+
+#define R_SPARC_NUM		253
+
+
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM	2
+
+
+#define EF_MIPS_NOREORDER   1
+#define EF_MIPS_PIC	    2
+#define EF_MIPS_CPIC	    4
+#define EF_MIPS_XGOT	    8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2	    32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_FP64	    512
+#define EF_MIPS_NAN2008     1024
+#define EF_MIPS_ARCH	    0xf0000000
+
+
+
+#define EF_MIPS_ARCH_1	    0x00000000
+#define EF_MIPS_ARCH_2	    0x10000000
+#define EF_MIPS_ARCH_3	    0x20000000
+#define EF_MIPS_ARCH_4	    0x30000000
+#define EF_MIPS_ARCH_5	    0x40000000
+#define EF_MIPS_ARCH_32     0x50000000
+#define EF_MIPS_ARCH_64     0x60000000
+#define EF_MIPS_ARCH_32R2   0x70000000
+#define EF_MIPS_ARCH_64R2   0x80000000
+
+
+#define E_MIPS_ARCH_1	  0x00000000
+#define E_MIPS_ARCH_2	  0x10000000
+#define E_MIPS_ARCH_3	  0x20000000
+#define E_MIPS_ARCH_4	  0x30000000
+#define E_MIPS_ARCH_5	  0x40000000
+#define E_MIPS_ARCH_32	  0x50000000
+#define E_MIPS_ARCH_64	  0x60000000
+
+
+
+#define SHN_MIPS_ACOMMON    0xff00
+#define SHN_MIPS_TEXT	    0xff01
+#define SHN_MIPS_DATA	    0xff02
+#define SHN_MIPS_SCOMMON    0xff03
+#define SHN_MIPS_SUNDEFINED 0xff04
+
+
+
+#define SHT_MIPS_LIBLIST       0x70000000
+#define SHT_MIPS_MSYM	       0x70000001
+#define SHT_MIPS_CONFLICT      0x70000002
+#define SHT_MIPS_GPTAB	       0x70000003
+#define SHT_MIPS_UCODE	       0x70000004
+#define SHT_MIPS_DEBUG	       0x70000005
+#define SHT_MIPS_REGINFO       0x70000006
+#define SHT_MIPS_PACKAGE       0x70000007
+#define SHT_MIPS_PACKSYM       0x70000008
+#define SHT_MIPS_RELD	       0x70000009
+#define SHT_MIPS_IFACE         0x7000000b
+#define SHT_MIPS_CONTENT       0x7000000c
+#define SHT_MIPS_OPTIONS       0x7000000d
+#define SHT_MIPS_SHDR	       0x70000010
+#define SHT_MIPS_FDESC	       0x70000011
+#define SHT_MIPS_EXTSYM	       0x70000012
+#define SHT_MIPS_DENSE	       0x70000013
+#define SHT_MIPS_PDESC	       0x70000014
+#define SHT_MIPS_LOCSYM	       0x70000015
+#define SHT_MIPS_AUXSYM	       0x70000016
+#define SHT_MIPS_OPTSYM	       0x70000017
+#define SHT_MIPS_LOCSTR	       0x70000018
+#define SHT_MIPS_LINE	       0x70000019
+#define SHT_MIPS_RFDESC	       0x7000001a
+#define SHT_MIPS_DELTASYM      0x7000001b
+#define SHT_MIPS_DELTAINST     0x7000001c
+#define SHT_MIPS_DELTACLASS    0x7000001d
+#define SHT_MIPS_DWARF         0x7000001e
+#define SHT_MIPS_DELTADECL     0x7000001f
+#define SHT_MIPS_SYMBOL_LIB    0x70000020
+#define SHT_MIPS_EVENTS	       0x70000021
+#define SHT_MIPS_TRANSLATE     0x70000022
+#define SHT_MIPS_PIXIE	       0x70000023
+#define SHT_MIPS_XLATE	       0x70000024
+#define SHT_MIPS_XLATE_DEBUG   0x70000025
+#define SHT_MIPS_WHIRL	       0x70000026
+#define SHT_MIPS_EH_REGION     0x70000027
+#define SHT_MIPS_XLATE_OLD     0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+
+
+#define SHF_MIPS_GPREL	 0x10000000
+#define SHF_MIPS_MERGE	 0x20000000
+#define SHF_MIPS_ADDR	 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL	 0x04000000
+#define SHF_MIPS_NAMES	 0x02000000
+#define SHF_MIPS_NODUPE	 0x01000000
+
+
+
+
+
+#define STO_MIPS_DEFAULT		0x0
+#define STO_MIPS_INTERNAL		0x1
+#define STO_MIPS_HIDDEN			0x2
+#define STO_MIPS_PROTECTED		0x3
+#define STO_MIPS_PLT			0x8
+#define STO_MIPS_SC_ALIGN_UNUSED	0xff
+
+
+#define STB_MIPS_SPLIT_COMMON		13
+
+
+
+typedef union {
+  struct {
+      Elf32_Word gt_current_g_value;
+      Elf32_Word gt_unused;
+  } gt_header;
+  struct {
+      Elf32_Word gt_g_value;
+      Elf32_Word gt_bytes;
+  } gt_entry;
+} Elf32_gptab;
+
+
+
+typedef struct {
+  Elf32_Word	ri_gprmask;
+  Elf32_Word	ri_cprmask[4];
+  Elf32_Sword	ri_gp_value;
+} Elf32_RegInfo;
+
+
+
+typedef struct {
+  unsigned char kind;
+
+  unsigned char size;
+  Elf32_Section section;
+
+  Elf32_Word info;
+} Elf_Options;
+
+
+
+#define ODK_NULL	0
+#define ODK_REGINFO	1
+#define ODK_EXCEPTIONS	2
+#define ODK_PAD		3
+#define ODK_HWPATCH	4
+#define ODK_FILL	5
+#define ODK_TAGS	6
+#define ODK_HWAND	7
+#define ODK_HWOR	8
+
+
+
+#define OEX_FPU_MIN	0x1f
+#define OEX_FPU_MAX	0x1f00
+#define OEX_PAGE0	0x10000
+#define OEX_SMM		0x20000
+#define OEX_FPDBUG	0x40000
+#define OEX_PRECISEFP	OEX_FPDBUG
+#define OEX_DISMISS	0x80000
+
+#define OEX_FPU_INVAL	0x10
+#define OEX_FPU_DIV0	0x08
+#define OEX_FPU_OFLO	0x04
+#define OEX_FPU_UFLO	0x02
+#define OEX_FPU_INEX	0x01
+
+
+
+#define OHW_R4KEOP	0x1
+#define OHW_R8KPFETCH	0x2
+#define OHW_R5KEOP	0x4
+#define OHW_R5KCVTL	0x8
+
+#define OPAD_PREFIX	0x1
+#define OPAD_POSTFIX	0x2
+#define OPAD_SYMBOL	0x4
+
+
+
+typedef struct {
+  Elf32_Word hwp_flags1;
+  Elf32_Word hwp_flags2;
+} Elf_Options_Hw;
+
+
+
+#define OHWA0_R4KEOP_CHECKED	0x00000001
+#define OHWA1_R4KEOP_CLEAN	0x00000002
+
+
+
+#define R_MIPS_NONE		0
+#define R_MIPS_16		1
+#define R_MIPS_32		2
+#define R_MIPS_REL32		3
+#define R_MIPS_26		4
+#define R_MIPS_HI16		5
+#define R_MIPS_LO16		6
+#define R_MIPS_GPREL16		7
+#define R_MIPS_LITERAL		8
+#define R_MIPS_GOT16		9
+#define R_MIPS_PC16		10
+#define R_MIPS_CALL16		11
+#define R_MIPS_GPREL32		12
+
+#define R_MIPS_SHIFT5		16
+#define R_MIPS_SHIFT6		17
+#define R_MIPS_64		18
+#define R_MIPS_GOT_DISP		19
+#define R_MIPS_GOT_PAGE		20
+#define R_MIPS_GOT_OFST		21
+#define R_MIPS_GOT_HI16		22
+#define R_MIPS_GOT_LO16		23
+#define R_MIPS_SUB		24
+#define R_MIPS_INSERT_A		25
+#define R_MIPS_INSERT_B		26
+#define R_MIPS_DELETE		27
+#define R_MIPS_HIGHER		28
+#define R_MIPS_HIGHEST		29
+#define R_MIPS_CALL_HI16	30
+#define R_MIPS_CALL_LO16	31
+#define R_MIPS_SCN_DISP		32
+#define R_MIPS_REL16		33
+#define R_MIPS_ADD_IMMEDIATE	34
+#define R_MIPS_PJUMP		35
+#define R_MIPS_RELGOT		36
+#define R_MIPS_JALR		37
+#define R_MIPS_TLS_DTPMOD32	38
+#define R_MIPS_TLS_DTPREL32	39
+#define R_MIPS_TLS_DTPMOD64	40
+#define R_MIPS_TLS_DTPREL64	41
+#define R_MIPS_TLS_GD		42
+#define R_MIPS_TLS_LDM		43
+#define R_MIPS_TLS_DTPREL_HI16	44
+#define R_MIPS_TLS_DTPREL_LO16	45
+#define R_MIPS_TLS_GOTTPREL	46
+#define R_MIPS_TLS_TPREL32	47
+#define R_MIPS_TLS_TPREL64	48
+#define R_MIPS_TLS_TPREL_HI16	49
+#define R_MIPS_TLS_TPREL_LO16	50
+#define R_MIPS_GLOB_DAT		51
+#define R_MIPS_COPY		126
+#define R_MIPS_JUMP_SLOT        127
+
+#define R_MIPS_NUM		128
+
+
+
+#define PT_MIPS_REGINFO	0x70000000
+#define PT_MIPS_RTPROC  0x70000001
+#define PT_MIPS_OPTIONS 0x70000002
+#define PT_MIPS_ABIFLAGS 0x70000003
+
+
+
+#define PF_MIPS_LOCAL	0x10000000
+
+
+
+#define DT_MIPS_RLD_VERSION  0x70000001
+#define DT_MIPS_TIME_STAMP   0x70000002
+#define DT_MIPS_ICHECKSUM    0x70000003
+#define DT_MIPS_IVERSION     0x70000004
+#define DT_MIPS_FLAGS	     0x70000005
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_MSYM	     0x70000007
+#define DT_MIPS_CONFLICT     0x70000008
+#define DT_MIPS_LIBLIST	     0x70000009
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a
+#define DT_MIPS_CONFLICTNO   0x7000000b
+#define DT_MIPS_LIBLISTNO    0x70000010
+#define DT_MIPS_SYMTABNO     0x70000011
+#define DT_MIPS_UNREFEXTNO   0x70000012
+#define DT_MIPS_GOTSYM	     0x70000013
+#define DT_MIPS_HIPAGENO     0x70000014
+#define DT_MIPS_RLD_MAP	     0x70000016
+#define DT_MIPS_DELTA_CLASS  0x70000017
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018
+
+#define DT_MIPS_DELTA_INSTANCE    0x70000019
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a
+
+#define DT_MIPS_DELTA_RELOC  0x7000001b
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c
+
+#define DT_MIPS_DELTA_SYM    0x7000001d
+
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e
+
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020
+
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
+
+#define DT_MIPS_CXX_FLAGS    0x70000022
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS	     0x70000029
+#define DT_MIPS_INTERFACE    0x7000002a
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d
+
+#define DT_MIPS_PERF_SUFFIX  0x7000002e
+
+#define DT_MIPS_COMPACT_SIZE 0x7000002f
+#define DT_MIPS_GP_VALUE     0x70000030
+#define DT_MIPS_AUX_DYNAMIC  0x70000031
+
+#define DT_MIPS_PLTGOT	     0x70000032
+
+#define DT_MIPS_RWPLT        0x70000034
+#define DT_MIPS_RLD_MAP_REL  0x70000035
+#define DT_MIPS_NUM	     0x36
+
+
+
+#define RHF_NONE		   0
+#define RHF_QUICKSTART		   (1 << 0)
+#define RHF_NOTPOT		   (1 << 1)
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)
+#define RHF_NO_MOVE		   (1 << 3)
+#define RHF_SGI_ONLY		   (1 << 4)
+#define RHF_GUARANTEE_INIT	   (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE		   (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
+#define RHF_REQUICKSTART	   (1 << 10)
+#define RHF_REQUICKSTARTED	   (1 << 11)
+#define RHF_CORD		   (1 << 12)
+#define RHF_NO_UNRES_UNDEF	   (1 << 13)
+#define RHF_RLD_ORDER_SAFE	   (1 << 14)
+
+
+
+typedef struct {
+  Elf32_Word l_name;
+  Elf32_Word l_time_stamp;
+  Elf32_Word l_checksum;
+  Elf32_Word l_version;
+  Elf32_Word l_flags;
+} Elf32_Lib;
+
+typedef struct {
+  Elf64_Word l_name;
+  Elf64_Word l_time_stamp;
+  Elf64_Word l_checksum;
+  Elf64_Word l_version;
+  Elf64_Word l_flags;
+} Elf64_Lib;
+
+
+
+
+#define LL_NONE		  0
+#define LL_EXACT_MATCH	  (1 << 0)
+#define LL_IGNORE_INT_VER (1 << 1)
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS	  (1 << 3)
+#define LL_DELAY_LOAD	  (1 << 4)
+#define LL_DELTA	  (1 << 5)
+
+
+
+typedef Elf32_Addr Elf32_Conflict;
+
+typedef struct {
+  Elf32_Half version;
+  unsigned char isa_level;
+  unsigned char isa_rev;
+  unsigned char gpr_size;
+  unsigned char cpr1_size;
+  unsigned char cpr2_size;
+  unsigned char fp_abi;
+  Elf32_Word isa_ext;
+  Elf32_Word ases;
+  Elf32_Word flags1;
+  Elf32_Word flags2;
+} Elf_MIPS_ABIFlags_v0;
+
+#define MIPS_AFL_REG_NONE	0x00
+#define MIPS_AFL_REG_32		0x01
+#define MIPS_AFL_REG_64		0x02
+#define MIPS_AFL_REG_128	0x03
+
+#define MIPS_AFL_ASE_DSP	0x00000001
+#define MIPS_AFL_ASE_DSPR2	0x00000002
+#define MIPS_AFL_ASE_EVA	0x00000004
+#define MIPS_AFL_ASE_MCU	0x00000008
+#define MIPS_AFL_ASE_MDMX	0x00000010
+#define MIPS_AFL_ASE_MIPS3D	0x00000020
+#define MIPS_AFL_ASE_MT		0x00000040
+#define MIPS_AFL_ASE_SMARTMIPS	0x00000080
+#define MIPS_AFL_ASE_VIRT	0x00000100
+#define MIPS_AFL_ASE_MSA	0x00000200
+#define MIPS_AFL_ASE_MIPS16	0x00000400
+#define MIPS_AFL_ASE_MICROMIPS	0x00000800
+#define MIPS_AFL_ASE_XPA	0x00001000
+#define MIPS_AFL_ASE_MASK	0x00001fff
+
+#define MIPS_AFL_EXT_XLR	  1
+#define MIPS_AFL_EXT_OCTEON2	  2
+#define MIPS_AFL_EXT_OCTEONP	  3
+#define MIPS_AFL_EXT_LOONGSON_3A  4
+#define MIPS_AFL_EXT_OCTEON	  5
+#define MIPS_AFL_EXT_5900	  6
+#define MIPS_AFL_EXT_4650	  7
+#define MIPS_AFL_EXT_4010	  8
+#define MIPS_AFL_EXT_4100	  9
+#define MIPS_AFL_EXT_3900	  10
+#define MIPS_AFL_EXT_10000	  11
+#define MIPS_AFL_EXT_SB1	  12
+#define MIPS_AFL_EXT_4111	  13
+#define MIPS_AFL_EXT_4120	  14
+#define MIPS_AFL_EXT_5400	  15
+#define MIPS_AFL_EXT_5500	  16
+#define MIPS_AFL_EXT_LOONGSON_2E  17
+#define MIPS_AFL_EXT_LOONGSON_2F  18
+
+#define MIPS_AFL_FLAGS1_ODDSPREG  1
+
+enum
+{
+  Val_GNU_MIPS_ABI_FP_ANY = 0,
+  Val_GNU_MIPS_ABI_FP_DOUBLE = 1,
+  Val_GNU_MIPS_ABI_FP_SINGLE = 2,
+  Val_GNU_MIPS_ABI_FP_SOFT = 3,
+  Val_GNU_MIPS_ABI_FP_OLD_64 = 4,
+  Val_GNU_MIPS_ABI_FP_XX = 5,
+  Val_GNU_MIPS_ABI_FP_64 = 6,
+  Val_GNU_MIPS_ABI_FP_64A = 7,
+  Val_GNU_MIPS_ABI_FP_MAX = 7
+};
+
+
+
+
+#define EF_PARISC_TRAPNIL	0x00010000
+#define EF_PARISC_EXT		0x00020000
+#define EF_PARISC_LSB		0x00040000
+#define EF_PARISC_WIDE		0x00080000
+#define EF_PARISC_NO_KABP	0x00100000
+
+#define EF_PARISC_LAZYSWAP	0x00400000
+#define EF_PARISC_ARCH		0x0000ffff
+
+
+
+#define EFA_PARISC_1_0		    0x020b
+#define EFA_PARISC_1_1		    0x0210
+#define EFA_PARISC_2_0		    0x0214
+
+
+
+#define SHN_PARISC_ANSI_COMMON	0xff00
+
+#define SHN_PARISC_HUGE_COMMON	0xff01
+
+
+
+#define SHT_PARISC_EXT		0x70000000
+#define SHT_PARISC_UNWIND	0x70000001
+#define SHT_PARISC_DOC		0x70000002
+
+
+
+#define SHF_PARISC_SHORT	0x20000000
+#define SHF_PARISC_HUGE		0x40000000
+#define SHF_PARISC_SBP		0x80000000
+
+
+
+#define STT_PARISC_MILLICODE	13
+
+#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
+#define STT_HP_STUB		(STT_LOOS + 0x2)
+
+
+
+#define R_PARISC_NONE		0
+#define R_PARISC_DIR32		1
+#define R_PARISC_DIR21L		2
+#define R_PARISC_DIR17R		3
+#define R_PARISC_DIR17F		4
+#define R_PARISC_DIR14R		6
+#define R_PARISC_PCREL32	9
+#define R_PARISC_PCREL21L	10
+#define R_PARISC_PCREL17R	11
+#define R_PARISC_PCREL17F	12
+#define R_PARISC_PCREL14R	14
+#define R_PARISC_DPREL21L	18
+#define R_PARISC_DPREL14R	22
+#define R_PARISC_GPREL21L	26
+#define R_PARISC_GPREL14R	30
+#define R_PARISC_LTOFF21L	34
+#define R_PARISC_LTOFF14R	38
+#define R_PARISC_SECREL32	41
+#define R_PARISC_SEGBASE	48
+#define R_PARISC_SEGREL32	49
+#define R_PARISC_PLTOFF21L	50
+#define R_PARISC_PLTOFF14R	54
+#define R_PARISC_LTOFF_FPTR32	57
+#define R_PARISC_LTOFF_FPTR21L	58
+#define R_PARISC_LTOFF_FPTR14R	62
+#define R_PARISC_FPTR64		64
+#define R_PARISC_PLABEL32	65
+#define R_PARISC_PLABEL21L	66
+#define R_PARISC_PLABEL14R	70
+#define R_PARISC_PCREL64	72
+#define R_PARISC_PCREL22F	74
+#define R_PARISC_PCREL14WR	75
+#define R_PARISC_PCREL14DR	76
+#define R_PARISC_PCREL16F	77
+#define R_PARISC_PCREL16WF	78
+#define R_PARISC_PCREL16DF	79
+#define R_PARISC_DIR64		80
+#define R_PARISC_DIR14WR	83
+#define R_PARISC_DIR14DR	84
+#define R_PARISC_DIR16F		85
+#define R_PARISC_DIR16WF	86
+#define R_PARISC_DIR16DF	87
+#define R_PARISC_GPREL64	88
+#define R_PARISC_GPREL14WR	91
+#define R_PARISC_GPREL14DR	92
+#define R_PARISC_GPREL16F	93
+#define R_PARISC_GPREL16WF	94
+#define R_PARISC_GPREL16DF	95
+#define R_PARISC_LTOFF64	96
+#define R_PARISC_LTOFF14WR	99
+#define R_PARISC_LTOFF14DR	100
+#define R_PARISC_LTOFF16F	101
+#define R_PARISC_LTOFF16WF	102
+#define R_PARISC_LTOFF16DF	103
+#define R_PARISC_SECREL64	104
+#define R_PARISC_SEGREL64	112
+#define R_PARISC_PLTOFF14WR	115
+#define R_PARISC_PLTOFF14DR	116
+#define R_PARISC_PLTOFF16F	117
+#define R_PARISC_PLTOFF16WF	118
+#define R_PARISC_PLTOFF16DF	119
+#define R_PARISC_LTOFF_FPTR64	120
+#define R_PARISC_LTOFF_FPTR14WR	123
+#define R_PARISC_LTOFF_FPTR14DR	124
+#define R_PARISC_LTOFF_FPTR16F	125
+#define R_PARISC_LTOFF_FPTR16WF	126
+#define R_PARISC_LTOFF_FPTR16DF	127
+#define R_PARISC_LORESERVE	128
+#define R_PARISC_COPY		128
+#define R_PARISC_IPLT		129
+#define R_PARISC_EPLT		130
+#define R_PARISC_TPREL32	153
+#define R_PARISC_TPREL21L	154
+#define R_PARISC_TPREL14R	158
+#define R_PARISC_LTOFF_TP21L	162
+#define R_PARISC_LTOFF_TP14R	166
+#define R_PARISC_LTOFF_TP14F	167
+#define R_PARISC_TPREL64	216
+#define R_PARISC_TPREL14WR	219
+#define R_PARISC_TPREL14DR	220
+#define R_PARISC_TPREL16F	221
+#define R_PARISC_TPREL16WF	222
+#define R_PARISC_TPREL16DF	223
+#define R_PARISC_LTOFF_TP64	224
+#define R_PARISC_LTOFF_TP14WR	227
+#define R_PARISC_LTOFF_TP14DR	228
+#define R_PARISC_LTOFF_TP16F	229
+#define R_PARISC_LTOFF_TP16WF	230
+#define R_PARISC_LTOFF_TP16DF	231
+#define R_PARISC_GNU_VTENTRY	232
+#define R_PARISC_GNU_VTINHERIT	233
+#define R_PARISC_TLS_GD21L	234
+#define R_PARISC_TLS_GD14R	235
+#define R_PARISC_TLS_GDCALL	236
+#define R_PARISC_TLS_LDM21L	237
+#define R_PARISC_TLS_LDM14R	238
+#define R_PARISC_TLS_LDMCALL	239
+#define R_PARISC_TLS_LDO21L	240
+#define R_PARISC_TLS_LDO14R	241
+#define R_PARISC_TLS_DTPMOD32	242
+#define R_PARISC_TLS_DTPMOD64	243
+#define R_PARISC_TLS_DTPOFF32	244
+#define R_PARISC_TLS_DTPOFF64	245
+#define R_PARISC_TLS_LE21L	R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R	R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L	R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R	R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32	R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64	R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE	255
+
+
+
+#define PT_HP_TLS		(PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
+#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
+#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
+#define PT_HP_STACK		(PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT	0x70000000
+#define PT_PARISC_UNWIND	0x70000001
+
+
+
+#define PF_PARISC_SBP		0x08000000
+
+#define PF_HP_PAGE_SIZE		0x00100000
+#define PF_HP_FAR_SHARED	0x00200000
+#define PF_HP_NEAR_SHARED	0x00400000
+#define PF_HP_CODE		0x01000000
+#define PF_HP_MODIFY		0x02000000
+#define PF_HP_LAZYSWAP		0x04000000
+#define PF_HP_SBP		0x08000000
+
+
+
+
+
+
+#define EF_ALPHA_32BIT		1
+#define EF_ALPHA_CANRELAX	2
+
+
+
+
+#define SHT_ALPHA_DEBUG		0x70000001
+#define SHT_ALPHA_REGINFO	0x70000002
+
+
+
+#define SHF_ALPHA_GPREL		0x10000000
+
+
+#define STO_ALPHA_NOPV		0x80
+#define STO_ALPHA_STD_GPLOAD	0x88
+
+
+
+#define R_ALPHA_NONE		0
+#define R_ALPHA_REFLONG		1
+#define R_ALPHA_REFQUAD		2
+#define R_ALPHA_GPREL32		3
+#define R_ALPHA_LITERAL		4
+#define R_ALPHA_LITUSE		5
+#define R_ALPHA_GPDISP		6
+#define R_ALPHA_BRADDR		7
+#define R_ALPHA_HINT		8
+#define R_ALPHA_SREL16		9
+#define R_ALPHA_SREL32		10
+#define R_ALPHA_SREL64		11
+#define R_ALPHA_GPRELHIGH	17
+#define R_ALPHA_GPRELLOW	18
+#define R_ALPHA_GPREL16		19
+#define R_ALPHA_COPY		24
+#define R_ALPHA_GLOB_DAT	25
+#define R_ALPHA_JMP_SLOT	26
+#define R_ALPHA_RELATIVE	27
+#define R_ALPHA_TLS_GD_HI	28
+#define R_ALPHA_TLSGD		29
+#define R_ALPHA_TLS_LDM		30
+#define R_ALPHA_DTPMOD64	31
+#define R_ALPHA_GOTDTPREL	32
+#define R_ALPHA_DTPREL64	33
+#define R_ALPHA_DTPRELHI	34
+#define R_ALPHA_DTPRELLO	35
+#define R_ALPHA_DTPREL16	36
+#define R_ALPHA_GOTTPREL	37
+#define R_ALPHA_TPREL64		38
+#define R_ALPHA_TPRELHI		39
+#define R_ALPHA_TPRELLO		40
+#define R_ALPHA_TPREL16		41
+
+#define R_ALPHA_NUM		46
+
+
+#define LITUSE_ALPHA_ADDR	0
+#define LITUSE_ALPHA_BASE	1
+#define LITUSE_ALPHA_BYTOFF	2
+#define LITUSE_ALPHA_JSR	3
+#define LITUSE_ALPHA_TLS_GD	4
+#define LITUSE_ALPHA_TLS_LDM	5
+
+
+#define DT_ALPHA_PLTRO		(DT_LOPROC + 0)
+#define DT_ALPHA_NUM		1
+
+
+
+
+#define EF_PPC_EMB		0x80000000
+
+
+#define EF_PPC_RELOCATABLE	0x00010000
+#define EF_PPC_RELOCATABLE_LIB	0x00008000
+
+
+
+#define R_PPC_NONE		0
+#define R_PPC_ADDR32		1
+#define R_PPC_ADDR24		2
+#define R_PPC_ADDR16		3
+#define R_PPC_ADDR16_LO		4
+#define R_PPC_ADDR16_HI		5
+#define R_PPC_ADDR16_HA		6
+#define R_PPC_ADDR14		7
+#define R_PPC_ADDR14_BRTAKEN	8
+#define R_PPC_ADDR14_BRNTAKEN	9
+#define R_PPC_REL24		10
+#define R_PPC_REL14		11
+#define R_PPC_REL14_BRTAKEN	12
+#define R_PPC_REL14_BRNTAKEN	13
+#define R_PPC_GOT16		14
+#define R_PPC_GOT16_LO		15
+#define R_PPC_GOT16_HI		16
+#define R_PPC_GOT16_HA		17
+#define R_PPC_PLTREL24		18
+#define R_PPC_COPY		19
+#define R_PPC_GLOB_DAT		20
+#define R_PPC_JMP_SLOT		21
+#define R_PPC_RELATIVE		22
+#define R_PPC_LOCAL24PC		23
+#define R_PPC_UADDR32		24
+#define R_PPC_UADDR16		25
+#define R_PPC_REL32		26
+#define R_PPC_PLT32		27
+#define R_PPC_PLTREL32		28
+#define R_PPC_PLT16_LO		29
+#define R_PPC_PLT16_HI		30
+#define R_PPC_PLT16_HA		31
+#define R_PPC_SDAREL16		32
+#define R_PPC_SECTOFF		33
+#define R_PPC_SECTOFF_LO	34
+#define R_PPC_SECTOFF_HI	35
+#define R_PPC_SECTOFF_HA	36
+
+
+#define R_PPC_TLS		67
+#define R_PPC_DTPMOD32		68
+#define R_PPC_TPREL16		69
+#define R_PPC_TPREL16_LO	70
+#define R_PPC_TPREL16_HI	71
+#define R_PPC_TPREL16_HA	72
+#define R_PPC_TPREL32		73
+#define R_PPC_DTPREL16		74
+#define R_PPC_DTPREL16_LO	75
+#define R_PPC_DTPREL16_HI	76
+#define R_PPC_DTPREL16_HA	77
+#define R_PPC_DTPREL32		78
+#define R_PPC_GOT_TLSGD16	79
+#define R_PPC_GOT_TLSGD16_LO	80
+#define R_PPC_GOT_TLSGD16_HI	81
+#define R_PPC_GOT_TLSGD16_HA	82
+#define R_PPC_GOT_TLSLD16	83
+#define R_PPC_GOT_TLSLD16_LO	84
+#define R_PPC_GOT_TLSLD16_HI	85
+#define R_PPC_GOT_TLSLD16_HA	86
+#define R_PPC_GOT_TPREL16	87
+#define R_PPC_GOT_TPREL16_LO	88
+#define R_PPC_GOT_TPREL16_HI	89
+#define R_PPC_GOT_TPREL16_HA	90
+#define R_PPC_GOT_DTPREL16	91
+#define R_PPC_GOT_DTPREL16_LO	92
+#define R_PPC_GOT_DTPREL16_HI	93
+#define R_PPC_GOT_DTPREL16_HA	94
+#define R_PPC_TLSGD		95
+#define R_PPC_TLSLD		96
+
+
+#define R_PPC_EMB_NADDR32	101
+#define R_PPC_EMB_NADDR16	102
+#define R_PPC_EMB_NADDR16_LO	103
+#define R_PPC_EMB_NADDR16_HI	104
+#define R_PPC_EMB_NADDR16_HA	105
+#define R_PPC_EMB_SDAI16	106
+#define R_PPC_EMB_SDA2I16	107
+#define R_PPC_EMB_SDA2REL	108
+#define R_PPC_EMB_SDA21		109
+#define R_PPC_EMB_MRKREF	110
+#define R_PPC_EMB_RELSEC16	111
+#define R_PPC_EMB_RELST_LO	112
+#define R_PPC_EMB_RELST_HI	113
+#define R_PPC_EMB_RELST_HA	114
+#define R_PPC_EMB_BIT_FLD	115
+#define R_PPC_EMB_RELSDA	116
+
+
+#define R_PPC_DIAB_SDA21_LO	180
+#define R_PPC_DIAB_SDA21_HI	181
+#define R_PPC_DIAB_SDA21_HA	182
+#define R_PPC_DIAB_RELSDA_LO	183
+#define R_PPC_DIAB_RELSDA_HI	184
+#define R_PPC_DIAB_RELSDA_HA	185
+
+
+#define R_PPC_IRELATIVE		248
+
+
+#define R_PPC_REL16		249
+#define R_PPC_REL16_LO		250
+#define R_PPC_REL16_HI		251
+#define R_PPC_REL16_HA		252
+
+
+
+#define R_PPC_TOC16		255
+
+
+#define DT_PPC_GOT		(DT_LOPROC + 0)
+#define DT_PPC_OPT		(DT_LOPROC + 1)
+#define DT_PPC_NUM		2
+
+#define PPC_OPT_TLS		1
+
+
+#define R_PPC64_NONE		R_PPC_NONE
+#define R_PPC64_ADDR32		R_PPC_ADDR32
+#define R_PPC64_ADDR24		R_PPC_ADDR24
+#define R_PPC64_ADDR16		R_PPC_ADDR16
+#define R_PPC64_ADDR16_LO	R_PPC_ADDR16_LO
+#define R_PPC64_ADDR16_HI	R_PPC_ADDR16_HI
+#define R_PPC64_ADDR16_HA	R_PPC_ADDR16_HA
+#define R_PPC64_ADDR14		R_PPC_ADDR14
+#define R_PPC64_ADDR14_BRTAKEN	R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN	R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24		R_PPC_REL24
+#define R_PPC64_REL14		R_PPC_REL14
+#define R_PPC64_REL14_BRTAKEN	R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN	R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16		R_PPC_GOT16
+#define R_PPC64_GOT16_LO	R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI	R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA	R_PPC_GOT16_HA
+
+#define R_PPC64_COPY		R_PPC_COPY
+#define R_PPC64_GLOB_DAT	R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT	R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE	R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32		R_PPC_UADDR32
+#define R_PPC64_UADDR16		R_PPC_UADDR16
+#define R_PPC64_REL32		R_PPC_REL32
+#define R_PPC64_PLT32		R_PPC_PLT32
+#define R_PPC64_PLTREL32	R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO	R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI	R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA	R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF		R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO	R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI	R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA	R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30		37
+#define R_PPC64_ADDR64		38
+#define R_PPC64_ADDR16_HIGHER	39
+#define R_PPC64_ADDR16_HIGHERA	40
+#define R_PPC64_ADDR16_HIGHEST	41
+#define R_PPC64_ADDR16_HIGHESTA	42
+#define R_PPC64_UADDR64		43
+#define R_PPC64_REL64		44
+#define R_PPC64_PLT64		45
+#define R_PPC64_PLTREL64	46
+#define R_PPC64_TOC16		47
+#define R_PPC64_TOC16_LO	48
+#define R_PPC64_TOC16_HI	49
+#define R_PPC64_TOC16_HA	50
+#define R_PPC64_TOC		51
+#define R_PPC64_PLTGOT16	52
+#define R_PPC64_PLTGOT16_LO	53
+#define R_PPC64_PLTGOT16_HI	54
+#define R_PPC64_PLTGOT16_HA	55
+
+#define R_PPC64_ADDR16_DS	56
+#define R_PPC64_ADDR16_LO_DS	57
+#define R_PPC64_GOT16_DS	58
+#define R_PPC64_GOT16_LO_DS	59
+#define R_PPC64_PLT16_LO_DS	60
+#define R_PPC64_SECTOFF_DS	61
+#define R_PPC64_SECTOFF_LO_DS	62
+#define R_PPC64_TOC16_DS	63
+#define R_PPC64_TOC16_LO_DS	64
+#define R_PPC64_PLTGOT16_DS	65
+#define R_PPC64_PLTGOT16_LO_DS	66
+
+
+#define R_PPC64_TLS		67
+#define R_PPC64_DTPMOD64	68
+#define R_PPC64_TPREL16		69
+#define R_PPC64_TPREL16_LO	70
+#define R_PPC64_TPREL16_HI	71
+#define R_PPC64_TPREL16_HA	72
+#define R_PPC64_TPREL64		73
+#define R_PPC64_DTPREL16	74
+#define R_PPC64_DTPREL16_LO	75
+#define R_PPC64_DTPREL16_HI	76
+#define R_PPC64_DTPREL16_HA	77
+#define R_PPC64_DTPREL64	78
+#define R_PPC64_GOT_TLSGD16	79
+#define R_PPC64_GOT_TLSGD16_LO	80
+#define R_PPC64_GOT_TLSGD16_HI	81
+#define R_PPC64_GOT_TLSGD16_HA	82
+#define R_PPC64_GOT_TLSLD16	83
+#define R_PPC64_GOT_TLSLD16_LO	84
+#define R_PPC64_GOT_TLSLD16_HI	85
+#define R_PPC64_GOT_TLSLD16_HA	86
+#define R_PPC64_GOT_TPREL16_DS	87
+#define R_PPC64_GOT_TPREL16_LO_DS 88
+#define R_PPC64_GOT_TPREL16_HI	89
+#define R_PPC64_GOT_TPREL16_HA	90
+#define R_PPC64_GOT_DTPREL16_DS	91
+#define R_PPC64_GOT_DTPREL16_LO_DS 92
+#define R_PPC64_GOT_DTPREL16_HI	93
+#define R_PPC64_GOT_DTPREL16_HA	94
+#define R_PPC64_TPREL16_DS	95
+#define R_PPC64_TPREL16_LO_DS	96
+#define R_PPC64_TPREL16_HIGHER	97
+#define R_PPC64_TPREL16_HIGHERA	98
+#define R_PPC64_TPREL16_HIGHEST	99
+#define R_PPC64_TPREL16_HIGHESTA 100
+#define R_PPC64_DTPREL16_DS	101
+#define R_PPC64_DTPREL16_LO_DS	102
+#define R_PPC64_DTPREL16_HIGHER	103
+#define R_PPC64_DTPREL16_HIGHERA 104
+#define R_PPC64_DTPREL16_HIGHEST 105
+#define R_PPC64_DTPREL16_HIGHESTA 106
+#define R_PPC64_TLSGD		107
+#define R_PPC64_TLSLD		108
+#define R_PPC64_TOCSAVE		109
+#define R_PPC64_ADDR16_HIGH	110
+#define R_PPC64_ADDR16_HIGHA	111
+#define R_PPC64_TPREL16_HIGH	112
+#define R_PPC64_TPREL16_HIGHA	113
+#define R_PPC64_DTPREL16_HIGH	114
+#define R_PPC64_DTPREL16_HIGHA	115
+
+
+#define R_PPC64_JMP_IREL	247
+#define R_PPC64_IRELATIVE	248
+#define R_PPC64_REL16		249
+#define R_PPC64_REL16_LO	250
+#define R_PPC64_REL16_HI	251
+#define R_PPC64_REL16_HA	252
+
+#define EF_PPC64_ABI	3
+
+#define DT_PPC64_GLINK  (DT_LOPROC + 0)
+#define DT_PPC64_OPD	(DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
+#define DT_PPC64_OPT	(DT_LOPROC + 3)
+#define DT_PPC64_NUM	4
+
+#define PPC64_OPT_TLS		1
+#define PPC64_OPT_MULTI_TOC	2
+
+#define STO_PPC64_LOCAL_BIT	5
+#define STO_PPC64_LOCAL_MASK	0xe0
+#define PPC64_LOCAL_ENTRY_OFFSET(x) (1 << (((x)&0xe0)>>5) & 0xfc)
+
+
+#define EF_ARM_RELEXEC		0x01
+#define EF_ARM_HASENTRY		0x02
+#define EF_ARM_INTERWORK	0x04
+#define EF_ARM_APCS_26		0x08
+#define EF_ARM_APCS_FLOAT	0x10
+#define EF_ARM_PIC		0x20
+#define EF_ARM_ALIGN8		0x40
+#define EF_ARM_NEW_ABI		0x80
+#define EF_ARM_OLD_ABI		0x100
+#define EF_ARM_SOFT_FLOAT	0x200
+#define EF_ARM_VFP_FLOAT	0x400
+#define EF_ARM_MAVERICK_FLOAT	0x800
+
+#define EF_ARM_ABI_FLOAT_SOFT	0x200
+#define EF_ARM_ABI_FLOAT_HARD	0x400
+
+
+#define EF_ARM_SYMSARESORTED	0x04
+#define EF_ARM_DYNSYMSUSESEGIDX	0x08
+#define EF_ARM_MAPSYMSFIRST	0x10
+#define EF_ARM_EABIMASK		0XFF000000
+
+
+#define EF_ARM_BE8	    0x00800000
+#define EF_ARM_LE8	    0x00400000
+
+#define EF_ARM_EABI_VERSION(flags)	((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN	0x00000000
+#define EF_ARM_EABI_VER1	0x01000000
+#define EF_ARM_EABI_VER2	0x02000000
+#define EF_ARM_EABI_VER3	0x03000000
+#define EF_ARM_EABI_VER4	0x04000000
+#define EF_ARM_EABI_VER5	0x05000000
+
+
+#define STT_ARM_TFUNC		STT_LOPROC
+#define STT_ARM_16BIT		STT_HIPROC
+
+
+#define SHF_ARM_ENTRYSECT	0x10000000
+#define SHF_ARM_COMDEF		0x80000000
+
+
+
+#define PF_ARM_SB		0x10000000
+
+#define PF_ARM_PI		0x20000000
+#define PF_ARM_ABS		0x40000000
+
+
+#define PT_ARM_EXIDX		(PT_LOPROC + 1)
+
+
+#define SHT_ARM_EXIDX		(SHT_LOPROC + 1)
+#define SHT_ARM_PREEMPTMAP	(SHT_LOPROC + 2)
+#define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3)
+
+#define R_AARCH64_NONE            0
+#define R_AARCH64_P32_ABS32	1
+#define R_AARCH64_P32_COPY	180
+#define R_AARCH64_P32_GLOB_DAT	181
+#define R_AARCH64_P32_JUMP_SLOT	182
+#define R_AARCH64_P32_RELATIVE	183
+#define R_AARCH64_P32_TLS_DTPMOD 184
+#define R_AARCH64_P32_TLS_DTPREL 185
+#define R_AARCH64_P32_TLS_TPREL	186
+#define R_AARCH64_P32_TLSDESC	187
+#define R_AARCH64_P32_IRELATIVE	188
+#define R_AARCH64_ABS64         257
+#define R_AARCH64_ABS32         258
+#define R_AARCH64_ABS16		259
+#define R_AARCH64_PREL64	260
+#define R_AARCH64_PREL32	261
+#define R_AARCH64_PREL16	262
+#define R_AARCH64_MOVW_UABS_G0	263
+#define R_AARCH64_MOVW_UABS_G0_NC 264
+#define R_AARCH64_MOVW_UABS_G1	265
+#define R_AARCH64_MOVW_UABS_G1_NC 266
+#define R_AARCH64_MOVW_UABS_G2	267
+#define R_AARCH64_MOVW_UABS_G2_NC 268
+#define R_AARCH64_MOVW_UABS_G3	269
+#define R_AARCH64_MOVW_SABS_G0	270
+#define R_AARCH64_MOVW_SABS_G1	271
+#define R_AARCH64_MOVW_SABS_G2	272
+#define R_AARCH64_LD_PREL_LO19	273
+#define R_AARCH64_ADR_PREL_LO21	274
+#define R_AARCH64_ADR_PREL_PG_HI21 275
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276
+#define R_AARCH64_ADD_ABS_LO12_NC 277
+#define R_AARCH64_LDST8_ABS_LO12_NC 278
+#define R_AARCH64_TSTBR14	279
+#define R_AARCH64_CONDBR19	280
+#define R_AARCH64_JUMP26	282
+#define R_AARCH64_CALL26	283
+#define R_AARCH64_LDST16_ABS_LO12_NC 284
+#define R_AARCH64_LDST32_ABS_LO12_NC 285
+#define R_AARCH64_LDST64_ABS_LO12_NC 286
+#define R_AARCH64_MOVW_PREL_G0	287
+#define R_AARCH64_MOVW_PREL_G0_NC 288
+#define R_AARCH64_MOVW_PREL_G1	289
+#define R_AARCH64_MOVW_PREL_G1_NC 290
+#define R_AARCH64_MOVW_PREL_G2	291
+#define R_AARCH64_MOVW_PREL_G2_NC 292
+#define R_AARCH64_MOVW_PREL_G3	293
+#define R_AARCH64_LDST128_ABS_LO12_NC 299
+#define R_AARCH64_MOVW_GOTOFF_G0 300
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301
+#define R_AARCH64_MOVW_GOTOFF_G1 302
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303
+#define R_AARCH64_MOVW_GOTOFF_G2 304
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305
+#define R_AARCH64_MOVW_GOTOFF_G3 306
+#define R_AARCH64_GOTREL64	307
+#define R_AARCH64_GOTREL32	308
+#define R_AARCH64_GOT_LD_PREL19	309
+#define R_AARCH64_LD64_GOTOFF_LO15 310
+#define R_AARCH64_ADR_GOT_PAGE	311
+#define R_AARCH64_LD64_GOT_LO12_NC 312
+#define R_AARCH64_LD64_GOTPAGE_LO15 313
+#define R_AARCH64_TLSGD_ADR_PREL21 512
+#define R_AARCH64_TLSGD_ADR_PAGE21 513
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514
+#define R_AARCH64_TLSGD_MOVW_G1	515
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516
+#define R_AARCH64_TLSLD_ADR_PREL21 517
+#define R_AARCH64_TLSLD_ADR_PAGE21 518
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519
+#define R_AARCH64_TLSLD_MOVW_G1	520
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521
+#define R_AARCH64_TLSLD_LD_PREL19 522
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559
+#define R_AARCH64_TLSDESC_LD_PREL19 560
+#define R_AARCH64_TLSDESC_ADR_PREL21 561
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562
+#define R_AARCH64_TLSDESC_LD64_LO12 563
+#define R_AARCH64_TLSDESC_ADD_LO12 564
+#define R_AARCH64_TLSDESC_OFF_G1 565
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566
+#define R_AARCH64_TLSDESC_LDR	567
+#define R_AARCH64_TLSDESC_ADD	568
+#define R_AARCH64_TLSDESC_CALL	569
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573
+#define R_AARCH64_COPY         1024
+#define R_AARCH64_GLOB_DAT     1025
+#define R_AARCH64_JUMP_SLOT    1026
+#define R_AARCH64_RELATIVE     1027
+#define R_AARCH64_TLS_DTPMOD   1028
+#define R_AARCH64_TLS_DTPMOD64 1028
+#define R_AARCH64_TLS_DTPREL   1029
+#define R_AARCH64_TLS_DTPREL64 1029
+#define R_AARCH64_TLS_TPREL    1030
+#define R_AARCH64_TLS_TPREL64  1030
+#define R_AARCH64_TLSDESC      1031
+
+
+#define R_ARM_NONE		0
+#define R_ARM_PC24		1
+#define R_ARM_ABS32		2
+#define R_ARM_REL32		3
+#define R_ARM_PC13		4
+#define R_ARM_ABS16		5
+#define R_ARM_ABS12		6
+#define R_ARM_THM_ABS5		7
+#define R_ARM_ABS8		8
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_PC22		10
+#define R_ARM_THM_PC8		11
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_TLS_DESC		13
+#define R_ARM_THM_SWI8		14
+#define R_ARM_XPC25		15
+#define R_ARM_THM_XPC22		16
+#define R_ARM_TLS_DTPMOD32	17
+#define R_ARM_TLS_DTPOFF32	18
+#define R_ARM_TLS_TPOFF32	19
+#define R_ARM_COPY		20
+#define R_ARM_GLOB_DAT		21
+#define R_ARM_JUMP_SLOT		22
+#define R_ARM_RELATIVE		23
+#define R_ARM_GOTOFF		24
+#define R_ARM_GOTPC		25
+#define R_ARM_GOT32		26
+#define R_ARM_PLT32		27
+#define R_ARM_CALL		28
+#define R_ARM_JUMP24		29
+#define R_ARM_THM_JUMP24	30
+#define R_ARM_BASE_ABS		31
+#define R_ARM_ALU_PCREL_7_0	32
+#define R_ARM_ALU_PCREL_15_8	33
+#define R_ARM_ALU_PCREL_23_15	34
+#define R_ARM_LDR_SBREL_11_0	35
+#define R_ARM_ALU_SBREL_19_12	36
+#define R_ARM_ALU_SBREL_27_20	37
+#define R_ARM_TARGET1		38
+#define R_ARM_SBREL31		39
+#define R_ARM_V4BX		40
+#define R_ARM_TARGET2		41
+#define R_ARM_PREL31		42
+#define R_ARM_MOVW_ABS_NC	43
+#define R_ARM_MOVT_ABS		44
+#define R_ARM_MOVW_PREL_NC	45
+#define R_ARM_MOVT_PREL		46
+#define R_ARM_THM_MOVW_ABS_NC	47
+#define R_ARM_THM_MOVT_ABS	48
+#define R_ARM_THM_MOVW_PREL_NC	49
+#define R_ARM_THM_MOVT_PREL	50
+#define R_ARM_THM_JUMP19	51
+#define R_ARM_THM_JUMP6		52
+#define R_ARM_THM_ALU_PREL_11_0	53
+#define R_ARM_THM_PC12		54
+#define R_ARM_ABS32_NOI		55
+#define R_ARM_REL32_NOI		56
+#define R_ARM_ALU_PC_G0_NC	57
+#define R_ARM_ALU_PC_G0		58
+#define R_ARM_ALU_PC_G1_NC	59
+#define R_ARM_ALU_PC_G1		60
+#define R_ARM_ALU_PC_G2		61
+#define R_ARM_LDR_PC_G1		62
+#define R_ARM_LDR_PC_G2		63
+#define R_ARM_LDRS_PC_G0	64
+#define R_ARM_LDRS_PC_G1	65
+#define R_ARM_LDRS_PC_G2	66
+#define R_ARM_LDC_PC_G0		67
+#define R_ARM_LDC_PC_G1		68
+#define R_ARM_LDC_PC_G2		69
+#define R_ARM_ALU_SB_G0_NC	70
+#define R_ARM_ALU_SB_G0		71
+#define R_ARM_ALU_SB_G1_NC	72
+#define R_ARM_ALU_SB_G1		73
+#define R_ARM_ALU_SB_G2		74
+#define R_ARM_LDR_SB_G0		75
+#define R_ARM_LDR_SB_G1		76
+#define R_ARM_LDR_SB_G2		77
+#define R_ARM_LDRS_SB_G0	78
+#define R_ARM_LDRS_SB_G1	79
+#define R_ARM_LDRS_SB_G2	80
+#define R_ARM_LDC_SB_G0		81
+#define R_ARM_LDC_SB_G1		82
+#define R_ARM_LDC_SB_G2		83
+#define R_ARM_MOVW_BREL_NC	84
+#define R_ARM_MOVT_BREL		85
+#define R_ARM_MOVW_BREL		86
+#define R_ARM_THM_MOVW_BREL_NC	87
+#define R_ARM_THM_MOVT_BREL	88
+#define R_ARM_THM_MOVW_BREL	89
+#define R_ARM_TLS_GOTDESC	90
+#define R_ARM_TLS_CALL		91
+#define R_ARM_TLS_DESCSEQ	92
+#define R_ARM_THM_TLS_CALL	93
+#define R_ARM_PLT32_ABS		94
+#define R_ARM_GOT_ABS		95
+#define R_ARM_GOT_PREL		96
+#define R_ARM_GOT_BREL12	97
+#define R_ARM_GOTOFF12		98
+#define R_ARM_GOTRELAX		99
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_PC11		102
+#define R_ARM_THM_PC9		103
+#define R_ARM_TLS_GD32		104
+
+#define R_ARM_TLS_LDM32		105
+
+#define R_ARM_TLS_LDO32		106
+
+#define R_ARM_TLS_IE32		107
+
+#define R_ARM_TLS_LE32		108
+#define R_ARM_TLS_LDO12		109
+#define R_ARM_TLS_LE12		110
+#define R_ARM_TLS_IE12GP	111
+#define R_ARM_ME_TOO		128
+#define R_ARM_THM_TLS_DESCSEQ	129
+#define R_ARM_THM_TLS_DESCSEQ16	129
+#define R_ARM_THM_TLS_DESCSEQ32	130
+#define R_ARM_THM_GOT_BREL12	131
+#define R_ARM_IRELATIVE		160
+#define R_ARM_RXPC25		249
+#define R_ARM_RSBREL32		250
+#define R_ARM_THM_RPC22		251
+#define R_ARM_RREL32		252
+#define R_ARM_RABS22		253
+#define R_ARM_RPC24		254
+#define R_ARM_RBASE		255
+
+#define R_ARM_NUM		256
+
+
+
+
+#define EF_IA_64_MASKOS		0x0000000f
+#define EF_IA_64_ABI64		0x00000010
+#define EF_IA_64_ARCH		0xff000000
+
+
+#define PT_IA_64_ARCHEXT	(PT_LOPROC + 0)
+#define PT_IA_64_UNWIND		(PT_LOPROC + 1)
+#define PT_IA_64_HP_OPT_ANOT	(PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT	(PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK	(PT_LOOS + 0x14)
+
+
+#define PF_IA_64_NORECOV	0x80000000
+
+
+#define SHT_IA_64_EXT		(SHT_LOPROC + 0)
+#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1)
+
+
+#define SHF_IA_64_SHORT		0x10000000
+#define SHF_IA_64_NORECOV	0x20000000
+
+
+#define DT_IA_64_PLT_RESERVE	(DT_LOPROC + 0)
+#define DT_IA_64_NUM		1
+
+
+#define R_IA64_NONE		0x00
+#define R_IA64_IMM14		0x21
+#define R_IA64_IMM22		0x22
+#define R_IA64_IMM64		0x23
+#define R_IA64_DIR32MSB		0x24
+#define R_IA64_DIR32LSB		0x25
+#define R_IA64_DIR64MSB		0x26
+#define R_IA64_DIR64LSB		0x27
+#define R_IA64_GPREL22		0x2a
+#define R_IA64_GPREL64I		0x2b
+#define R_IA64_GPREL32MSB	0x2c
+#define R_IA64_GPREL32LSB	0x2d
+#define R_IA64_GPREL64MSB	0x2e
+#define R_IA64_GPREL64LSB	0x2f
+#define R_IA64_LTOFF22		0x32
+#define R_IA64_LTOFF64I		0x33
+#define R_IA64_PLTOFF22		0x3a
+#define R_IA64_PLTOFF64I	0x3b
+#define R_IA64_PLTOFF64MSB	0x3e
+#define R_IA64_PLTOFF64LSB	0x3f
+#define R_IA64_FPTR64I		0x43
+#define R_IA64_FPTR32MSB	0x44
+#define R_IA64_FPTR32LSB	0x45
+#define R_IA64_FPTR64MSB	0x46
+#define R_IA64_FPTR64LSB	0x47
+#define R_IA64_PCREL60B		0x48
+#define R_IA64_PCREL21B		0x49
+#define R_IA64_PCREL21M		0x4a
+#define R_IA64_PCREL21F		0x4b
+#define R_IA64_PCREL32MSB	0x4c
+#define R_IA64_PCREL32LSB	0x4d
+#define R_IA64_PCREL64MSB	0x4e
+#define R_IA64_PCREL64LSB	0x4f
+#define R_IA64_LTOFF_FPTR22	0x52
+#define R_IA64_LTOFF_FPTR64I	0x53
+#define R_IA64_LTOFF_FPTR32MSB	0x54
+#define R_IA64_LTOFF_FPTR32LSB	0x55
+#define R_IA64_LTOFF_FPTR64MSB	0x56
+#define R_IA64_LTOFF_FPTR64LSB	0x57
+#define R_IA64_SEGREL32MSB	0x5c
+#define R_IA64_SEGREL32LSB	0x5d
+#define R_IA64_SEGREL64MSB	0x5e
+#define R_IA64_SEGREL64LSB	0x5f
+#define R_IA64_SECREL32MSB	0x64
+#define R_IA64_SECREL32LSB	0x65
+#define R_IA64_SECREL64MSB	0x66
+#define R_IA64_SECREL64LSB	0x67
+#define R_IA64_REL32MSB		0x6c
+#define R_IA64_REL32LSB		0x6d
+#define R_IA64_REL64MSB		0x6e
+#define R_IA64_REL64LSB		0x6f
+#define R_IA64_LTV32MSB		0x74
+#define R_IA64_LTV32LSB		0x75
+#define R_IA64_LTV64MSB		0x76
+#define R_IA64_LTV64LSB		0x77
+#define R_IA64_PCREL21BI	0x79
+#define R_IA64_PCREL22		0x7a
+#define R_IA64_PCREL64I		0x7b
+#define R_IA64_IPLTMSB		0x80
+#define R_IA64_IPLTLSB		0x81
+#define R_IA64_COPY		0x84
+#define R_IA64_SUB		0x85
+#define R_IA64_LTOFF22X		0x86
+#define R_IA64_LDXMOV		0x87
+#define R_IA64_TPREL14		0x91
+#define R_IA64_TPREL22		0x92
+#define R_IA64_TPREL64I		0x93
+#define R_IA64_TPREL64MSB	0x96
+#define R_IA64_TPREL64LSB	0x97
+#define R_IA64_LTOFF_TPREL22	0x9a
+#define R_IA64_DTPMOD64MSB	0xa6
+#define R_IA64_DTPMOD64LSB	0xa7
+#define R_IA64_LTOFF_DTPMOD22	0xaa
+#define R_IA64_DTPREL14		0xb1
+#define R_IA64_DTPREL22		0xb2
+#define R_IA64_DTPREL64I	0xb3
+#define R_IA64_DTPREL32MSB	0xb4
+#define R_IA64_DTPREL32LSB	0xb5
+#define R_IA64_DTPREL64MSB	0xb6
+#define R_IA64_DTPREL64LSB	0xb7
+#define R_IA64_LTOFF_DTPREL22	0xba
+
+
+#define EF_SH_MACH_MASK		0x1f
+#define EF_SH_UNKNOWN		0x0
+#define EF_SH1			0x1
+#define EF_SH2			0x2
+#define EF_SH3			0x3
+#define EF_SH_DSP		0x4
+#define EF_SH3_DSP		0x5
+#define EF_SH4AL_DSP		0x6
+#define EF_SH3E			0x8
+#define EF_SH4			0x9
+#define EF_SH2E			0xb
+#define EF_SH4A			0xc
+#define EF_SH2A			0xd
+#define EF_SH4_NOFPU		0x10
+#define EF_SH4A_NOFPU		0x11
+#define EF_SH4_NOMMU_NOFPU	0x12
+#define EF_SH2A_NOFPU		0x13
+#define EF_SH3_NOMMU		0x14
+#define EF_SH2A_SH4_NOFPU	0x15
+#define EF_SH2A_SH3_NOFPU	0x16
+#define EF_SH2A_SH4		0x17
+#define EF_SH2A_SH3E		0x18
+
+#define	R_SH_NONE		0
+#define	R_SH_DIR32		1
+#define	R_SH_REL32		2
+#define	R_SH_DIR8WPN		3
+#define	R_SH_IND12W		4
+#define	R_SH_DIR8WPL		5
+#define	R_SH_DIR8WPZ		6
+#define	R_SH_DIR8BP		7
+#define	R_SH_DIR8W		8
+#define	R_SH_DIR8L		9
+#define	R_SH_SWITCH16		25
+#define	R_SH_SWITCH32		26
+#define	R_SH_USES		27
+#define	R_SH_COUNT		28
+#define	R_SH_ALIGN		29
+#define	R_SH_CODE		30
+#define	R_SH_DATA		31
+#define	R_SH_LABEL		32
+#define	R_SH_SWITCH8		33
+#define	R_SH_GNU_VTINHERIT	34
+#define	R_SH_GNU_VTENTRY	35
+#define	R_SH_TLS_GD_32		144
+#define	R_SH_TLS_LD_32		145
+#define	R_SH_TLS_LDO_32		146
+#define	R_SH_TLS_IE_32		147
+#define	R_SH_TLS_LE_32		148
+#define	R_SH_TLS_DTPMOD32	149
+#define	R_SH_TLS_DTPOFF32	150
+#define	R_SH_TLS_TPOFF32	151
+#define	R_SH_GOT32		160
+#define	R_SH_PLT32		161
+#define	R_SH_COPY		162
+#define	R_SH_GLOB_DAT		163
+#define	R_SH_JMP_SLOT		164
+#define	R_SH_RELATIVE		165
+#define	R_SH_GOTOFF		166
+#define	R_SH_GOTPC		167
+#define	R_SH_GOT20		201
+#define	R_SH_GOTOFF20		202
+#define	R_SH_GOTFUNCDESC	203
+#define	R_SH_GOTFUNCDEST20	204
+#define	R_SH_GOTOFFFUNCDESC	205
+#define	R_SH_GOTOFFFUNCDEST20	206
+#define	R_SH_FUNCDESC		207
+#define	R_SH_FUNCDESC_VALUE	208
+
+#define	R_SH_NUM		256
+
+#define R_RX_DIR32			1	/* TODO */
+#define R_RX_REL32			2	/* TODO */
+#define R_RX_GLOB_DAT		3	/* TODO */
+#define R_RX_JMP_SLOT		4	/* TODO */
+#define R_RX_RELATIVE		5	/* TODO */
+#define R_RX_COPY			6	/* TODO */
+#define R_RX_TLS_DTPMOD32	7	/* TODO */
+#define R_RX_TLS_DTPOFF32	8	/* TODO */
+#define R_RX_TLS_TPOFF32	9	/* TODO */
+
+#define R_390_NONE		0
+#define R_390_8			1
+#define R_390_12		2
+#define R_390_16		3
+#define R_390_32		4
+#define R_390_PC32		5
+#define R_390_GOT12		6
+#define R_390_GOT32		7
+#define R_390_PLT32		8
+#define R_390_COPY		9
+#define R_390_GLOB_DAT		10
+#define R_390_JMP_SLOT		11
+#define R_390_RELATIVE		12
+#define R_390_GOTOFF32		13
+#define R_390_GOTPC		14
+#define R_390_GOT16		15
+#define R_390_PC16		16
+#define R_390_PC16DBL		17
+#define R_390_PLT16DBL		18
+#define R_390_PC32DBL		19
+#define R_390_PLT32DBL		20
+#define R_390_GOTPCDBL		21
+#define R_390_64		22
+#define R_390_PC64		23
+#define R_390_GOT64		24
+#define R_390_PLT64		25
+#define R_390_GOTENT		26
+#define R_390_GOTOFF16		27
+#define R_390_GOTOFF64		28
+#define R_390_GOTPLT12		29
+#define R_390_GOTPLT16		30
+#define R_390_GOTPLT32		31
+#define R_390_GOTPLT64		32
+#define R_390_GOTPLTENT		33
+#define R_390_PLTOFF16		34
+#define R_390_PLTOFF32		35
+#define R_390_PLTOFF64		36
+#define R_390_TLS_LOAD		37
+#define R_390_TLS_GDCALL	38
+
+#define R_390_TLS_LDCALL	39
+
+#define R_390_TLS_GD32		40
+
+#define R_390_TLS_GD64		41
+
+#define R_390_TLS_GOTIE12	42
+
+#define R_390_TLS_GOTIE32	43
+
+#define R_390_TLS_GOTIE64	44
+
+#define R_390_TLS_LDM32		45
+
+#define R_390_TLS_LDM64		46
+
+#define R_390_TLS_IE32		47
+
+#define R_390_TLS_IE64		48
+
+#define R_390_TLS_IEENT		49
+
+#define R_390_TLS_LE32		50
+
+#define R_390_TLS_LE64		51
+
+#define R_390_TLS_LDO32		52
+
+#define R_390_TLS_LDO64		53
+
+#define R_390_TLS_DTPMOD	54
+#define R_390_TLS_DTPOFF	55
+#define R_390_TLS_TPOFF		56
+
+#define R_390_20		57
+#define R_390_GOT20		58
+#define R_390_GOTPLT20		59
+#define R_390_TLS_GOTIE20	60
+
+
+#define R_390_NUM		61
+
+
+
+#define R_CRIS_NONE		0
+#define R_CRIS_8		1
+#define R_CRIS_16		2
+#define R_CRIS_32		3
+#define R_CRIS_8_PCREL		4
+#define R_CRIS_16_PCREL		5
+#define R_CRIS_32_PCREL		6
+#define R_CRIS_GNU_VTINHERIT	7
+#define R_CRIS_GNU_VTENTRY	8
+#define R_CRIS_COPY		9
+#define R_CRIS_GLOB_DAT		10
+#define R_CRIS_JUMP_SLOT	11
+#define R_CRIS_RELATIVE		12
+#define R_CRIS_16_GOT		13
+#define R_CRIS_32_GOT		14
+#define R_CRIS_16_GOTPLT	15
+#define R_CRIS_32_GOTPLT	16
+#define R_CRIS_32_GOTREL	17
+#define R_CRIS_32_PLT_GOTREL	18
+#define R_CRIS_32_PLT_PCREL	19
+
+#define R_CRIS_NUM		20
+
+
+
+#define R_X86_64_NONE		0
+#define R_X86_64_64		1
+#define R_X86_64_PC32		2
+#define R_X86_64_GOT32		3
+#define R_X86_64_PLT32		4
+#define R_X86_64_COPY		5
+#define R_X86_64_GLOB_DAT	6
+#define R_X86_64_JUMP_SLOT	7
+#define R_X86_64_RELATIVE	8
+#define R_X86_64_GOTPCREL	9
+
+#define R_X86_64_32		10
+#define R_X86_64_32S		11
+#define R_X86_64_16		12
+#define R_X86_64_PC16		13
+#define R_X86_64_8		14
+#define R_X86_64_PC8		15
+#define R_X86_64_DTPMOD64	16
+#define R_X86_64_DTPOFF64	17
+#define R_X86_64_TPOFF64	18
+#define R_X86_64_TLSGD		19
+
+#define R_X86_64_TLSLD		20
+
+#define R_X86_64_DTPOFF32	21
+#define R_X86_64_GOTTPOFF	22
+
+#define R_X86_64_TPOFF32	23
+#define R_X86_64_PC64		24
+#define R_X86_64_GOTOFF64	25
+#define R_X86_64_GOTPC32	26
+#define R_X86_64_GOT64		27
+#define R_X86_64_GOTPCREL64	28
+#define R_X86_64_GOTPC64	29
+#define R_X86_64_GOTPLT64	30
+#define R_X86_64_PLTOFF64	31
+#define R_X86_64_SIZE32		32
+#define R_X86_64_SIZE64		33
+
+#define R_X86_64_GOTPC32_TLSDESC 34
+#define R_X86_64_TLSDESC_CALL   35
+
+#define R_X86_64_TLSDESC        36
+#define R_X86_64_IRELATIVE	37
+#define R_X86_64_RELATIVE64	38
+#define R_X86_64_GOTPCRELX	41
+#define R_X86_64_REX_GOTPCRELX	42
+#define R_X86_64_NUM		43
+
+
+
+#define R_MN10300_NONE		0
+#define R_MN10300_32		1
+#define R_MN10300_16		2
+#define R_MN10300_8		3
+#define R_MN10300_PCREL32	4
+#define R_MN10300_PCREL16	5
+#define R_MN10300_PCREL8	6
+#define R_MN10300_GNU_VTINHERIT	7
+#define R_MN10300_GNU_VTENTRY	8
+#define R_MN10300_24		9
+#define R_MN10300_GOTPC32	10
+#define R_MN10300_GOTPC16	11
+#define R_MN10300_GOTOFF32	12
+#define R_MN10300_GOTOFF24	13
+#define R_MN10300_GOTOFF16	14
+#define R_MN10300_PLT32		15
+#define R_MN10300_PLT16		16
+#define R_MN10300_GOT32		17
+#define R_MN10300_GOT24		18
+#define R_MN10300_GOT16		19
+#define R_MN10300_COPY		20
+#define R_MN10300_GLOB_DAT	21
+#define R_MN10300_JMP_SLOT	22
+#define R_MN10300_RELATIVE	23
+
+#define R_MN10300_NUM		24
+
+
+
+#define R_M32R_NONE		0
+#define R_M32R_16		1
+#define R_M32R_32		2
+#define R_M32R_24		3
+#define R_M32R_10_PCREL		4
+#define R_M32R_18_PCREL		5
+#define R_M32R_26_PCREL		6
+#define R_M32R_HI16_ULO		7
+#define R_M32R_HI16_SLO		8
+#define R_M32R_LO16		9
+#define R_M32R_SDA16		10
+#define R_M32R_GNU_VTINHERIT	11
+#define R_M32R_GNU_VTENTRY	12
+
+#define R_M32R_16_RELA		33
+#define R_M32R_32_RELA		34
+#define R_M32R_24_RELA		35
+#define R_M32R_10_PCREL_RELA	36
+#define R_M32R_18_PCREL_RELA	37
+#define R_M32R_26_PCREL_RELA	38
+#define R_M32R_HI16_ULO_RELA	39
+#define R_M32R_HI16_SLO_RELA	40
+#define R_M32R_LO16_RELA	41
+#define R_M32R_SDA16_RELA	42
+#define R_M32R_RELA_GNU_VTINHERIT	43
+#define R_M32R_RELA_GNU_VTENTRY	44
+#define R_M32R_REL32		45
+
+#define R_M32R_GOT24		48
+#define R_M32R_26_PLTREL	49
+#define R_M32R_COPY		50
+#define R_M32R_GLOB_DAT		51
+#define R_M32R_JMP_SLOT		52
+#define R_M32R_RELATIVE		53
+#define R_M32R_GOTOFF		54
+#define R_M32R_GOTPC24		55
+#define R_M32R_GOT16_HI_ULO	56
+
+#define R_M32R_GOT16_HI_SLO	57
+
+#define R_M32R_GOT16_LO		58
+#define R_M32R_GOTPC_HI_ULO	59
+
+#define R_M32R_GOTPC_HI_SLO	60
+
+#define R_M32R_GOTPC_LO		61
+
+#define R_M32R_GOTOFF_HI_ULO	62
+
+#define R_M32R_GOTOFF_HI_SLO	63
+
+#define R_M32R_GOTOFF_LO	64
+#define R_M32R_NUM		256
+
+#define R_MICROBLAZE_NONE 0
+#define R_MICROBLAZE_32 1
+#define R_MICROBLAZE_32_PCREL 2
+#define R_MICROBLAZE_64_PCREL 3
+#define R_MICROBLAZE_32_PCREL_LO 4
+#define R_MICROBLAZE_64 5
+#define R_MICROBLAZE_32_LO 6
+#define R_MICROBLAZE_SRO32 7
+#define R_MICROBLAZE_SRW32 8
+#define R_MICROBLAZE_64_NONE 9
+#define R_MICROBLAZE_32_SYM_OP_SYM 10
+#define R_MICROBLAZE_GNU_VTINHERIT 11
+#define R_MICROBLAZE_GNU_VTENTRY 12
+#define R_MICROBLAZE_GOTPC_64 13
+#define R_MICROBLAZE_GOT_64 14
+#define R_MICROBLAZE_PLT_64 15
+#define R_MICROBLAZE_REL 16
+#define R_MICROBLAZE_JUMP_SLOT 17
+#define R_MICROBLAZE_GLOB_DAT 18
+#define R_MICROBLAZE_GOTOFF_64 19
+#define R_MICROBLAZE_GOTOFF_32 20
+#define R_MICROBLAZE_COPY 21
+#define R_MICROBLAZE_TLS 22
+#define R_MICROBLAZE_TLSGD 23
+#define R_MICROBLAZE_TLSLD 24
+#define R_MICROBLAZE_TLSDTPMOD32 25
+#define R_MICROBLAZE_TLSDTPREL32 26
+#define R_MICROBLAZE_TLSDTPREL64 27
+#define R_MICROBLAZE_TLSGOTTPREL32 28
+#define R_MICROBLAZE_TLSTPREL32	 29
+
+#define DT_NIOS2_GP             0x70000002
+
+#define R_NIOS2_NONE		0
+#define R_NIOS2_S16		1
+#define R_NIOS2_U16		2
+#define R_NIOS2_PCREL16		3
+#define R_NIOS2_CALL26		4
+#define R_NIOS2_IMM5		5
+#define R_NIOS2_CACHE_OPX	6
+#define R_NIOS2_IMM6		7
+#define R_NIOS2_IMM8		8
+#define R_NIOS2_HI16		9
+#define R_NIOS2_LO16		10
+#define R_NIOS2_HIADJ16		11
+#define R_NIOS2_BFD_RELOC_32	12
+#define R_NIOS2_BFD_RELOC_16	13
+#define R_NIOS2_BFD_RELOC_8	14
+#define R_NIOS2_GPREL		15
+#define R_NIOS2_GNU_VTINHERIT	16
+#define R_NIOS2_GNU_VTENTRY	17
+#define R_NIOS2_UJMP		18
+#define R_NIOS2_CJMP		19
+#define R_NIOS2_CALLR		20
+#define R_NIOS2_ALIGN		21
+#define R_NIOS2_GOT16		22
+#define R_NIOS2_CALL16		23
+#define R_NIOS2_GOTOFF_LO	24
+#define R_NIOS2_GOTOFF_HA	25
+#define R_NIOS2_PCREL_LO	26
+#define R_NIOS2_PCREL_HA	27
+#define R_NIOS2_TLS_GD16	28
+#define R_NIOS2_TLS_LDM16	29
+#define R_NIOS2_TLS_LDO16	30
+#define R_NIOS2_TLS_IE16	31
+#define R_NIOS2_TLS_LE16	32
+#define R_NIOS2_TLS_DTPMOD	33
+#define R_NIOS2_TLS_DTPREL	34
+#define R_NIOS2_TLS_TPREL	35
+#define R_NIOS2_COPY		36
+#define R_NIOS2_GLOB_DAT	37
+#define R_NIOS2_JUMP_SLOT	38
+#define R_NIOS2_RELATIVE	39
+#define R_NIOS2_GOTOFF		40
+#define R_NIOS2_CALL26_NOAT	41
+#define R_NIOS2_GOT_LO		42
+#define R_NIOS2_GOT_HA		43
+#define R_NIOS2_CALL_LO		44
+#define R_NIOS2_CALL_HA		45
+
+#define R_OR1K_NONE		0
+#define R_OR1K_32		1
+#define R_OR1K_16		2
+#define R_OR1K_8		3
+#define R_OR1K_LO_16_IN_INSN	4
+#define R_OR1K_HI_16_IN_INSN	5
+#define R_OR1K_INSN_REL_26	6
+#define R_OR1K_GNU_VTENTRY	7
+#define R_OR1K_GNU_VTINHERIT	8
+#define R_OR1K_32_PCREL		9
+#define R_OR1K_16_PCREL		10
+#define R_OR1K_8_PCREL		11
+#define R_OR1K_GOTPC_HI16	12
+#define R_OR1K_GOTPC_LO16	13
+#define R_OR1K_GOT16		14
+#define R_OR1K_PLT26		15
+#define R_OR1K_GOTOFF_HI16	16
+#define R_OR1K_GOTOFF_LO16	17
+#define R_OR1K_COPY		18
+#define R_OR1K_GLOB_DAT		19
+#define R_OR1K_JMP_SLOT		20
+#define R_OR1K_RELATIVE		21
+#define R_OR1K_TLS_GD_HI16	22
+#define R_OR1K_TLS_GD_LO16	23
+#define R_OR1K_TLS_LDM_HI16	24
+#define R_OR1K_TLS_LDM_LO16	25
+#define R_OR1K_TLS_LDO_HI16	26
+#define R_OR1K_TLS_LDO_LO16	27
+#define R_OR1K_TLS_IE_HI16	28
+#define R_OR1K_TLS_IE_LO16	29
+#define R_OR1K_TLS_LE_HI16	30
+#define R_OR1K_TLS_LE_LO16	31
+#define R_OR1K_TLS_TPOFF	32
+#define R_OR1K_TLS_DTPOFF	33
+#define R_OR1K_TLS_DTPMOD	34
+
+#define R_BPF_NONE		0
+#define R_BPF_MAP_FD		1
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/endian.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/endian.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/endian.h	(revision 398)
@@ -0,0 +1,82 @@
+#ifndef _ENDIAN_H
+#define _ENDIAN_H
+
+#include <features.h>
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __PDP_ENDIAN 3412
+
+#if defined(__GNUC__) && defined(__BYTE_ORDER__)
+#define __BYTE_ORDER __BYTE_ORDER__
+#else
+#include <bits/endian.h>
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define BIG_ENDIAN __BIG_ENDIAN
+#define LITTLE_ENDIAN __LITTLE_ENDIAN
+#define PDP_ENDIAN __PDP_ENDIAN
+#define BYTE_ORDER __BYTE_ORDER
+
+#include <stdint.h>
+
+static __inline uint16_t __bswap16(uint16_t __x)
+{
+	return (__x<<8) | (__x>>8);
+}
+
+static __inline uint32_t __bswap32(uint32_t __x)
+{
+	return (__x>>24) | ((__x>>8)&0xff00) | ((__x<<8)&0xff0000) | (__x<<24);
+}
+
+static __inline uint64_t __bswap64(uint64_t __x)
+{
+	return ((__bswap32(__x)+0ULL)<<32) | __bswap32(__x>>32);
+}
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htobe16(x) __bswap16(x)
+#define be16toh(x) __bswap16(x)
+#define betoh16(x) __bswap16(x)
+#define htobe32(x) __bswap32(x)
+#define be32toh(x) __bswap32(x)
+#define betoh32(x) __bswap32(x)
+#define htobe64(x) __bswap64(x)
+#define be64toh(x) __bswap64(x)
+#define betoh64(x) __bswap64(x)
+#define htole16(x) (uint16_t)(x)
+#define le16toh(x) (uint16_t)(x)
+#define letoh16(x) (uint16_t)(x)
+#define htole32(x) (uint32_t)(x)
+#define le32toh(x) (uint32_t)(x)
+#define letoh32(x) (uint32_t)(x)
+#define htole64(x) (uint64_t)(x)
+#define le64toh(x) (uint64_t)(x)
+#define letoh64(x) (uint64_t)(x)
+#else
+#define htobe16(x) (uint16_t)(x)
+#define be16toh(x) (uint16_t)(x)
+#define betoh16(x) (uint16_t)(x)
+#define htobe32(x) (uint32_t)(x)
+#define be32toh(x) (uint32_t)(x)
+#define betoh32(x) (uint32_t)(x)
+#define htobe64(x) (uint64_t)(x)
+#define be64toh(x) (uint64_t)(x)
+#define betoh64(x) (uint64_t)(x)
+#define htole16(x) __bswap16(x)
+#define le16toh(x) __bswap16(x)
+#define letoh16(x) __bswap16(x)
+#define htole32(x) __bswap32(x)
+#define le32toh(x) __bswap32(x)
+#define letoh32(x) __bswap32(x)
+#define htole64(x) __bswap64(x)
+#define le64toh(x) __bswap64(x)
+#define letoh64(x) __bswap64(x)
+#endif
+
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/err.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/err.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/err.h	(revision 398)
@@ -0,0 +1,25 @@
+#ifndef _ERR_H
+#define _ERR_H
+
+#include <features.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void warn(const char *, ...);
+void vwarn(const char *, va_list);
+void warnx(const char *, ...);
+void vwarnx(const char *, va_list);
+
+_Noreturn void err(int, const char *, ...);
+_Noreturn void verr(int, const char *, va_list);
+_Noreturn void errx(int, const char *, ...);
+_Noreturn void verrx(int, const char *, va_list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/errno.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/errno.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/errno.h	(revision 398)
@@ -0,0 +1,24 @@
+#ifndef	_ERRNO_H
+#define _ERRNO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/errno.h>
+
+int *__errno_location(void);
+#define errno (*__errno_location())
+
+#ifdef _GNU_SOURCE
+extern char *program_invocation_short_name, *program_invocation_name;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fcntl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fcntl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fcntl.h	(revision 398)
@@ -0,0 +1,187 @@
+#ifndef	_FCNTL_H
+#define	_FCNTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_mode_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_struct_iovec
+#endif
+
+#include <bits/alltypes.h>
+
+#include <bits/fcntl.h>
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+int creat(const char *, mode_t);
+int fcntl(int, int, ...);
+int open(const char *, int, ...);
+int openat(int, const char *, int, ...);
+int posix_fadvise(int, off_t, off_t, int);
+int posix_fallocate(int, off_t, off_t);
+
+#define O_SEARCH  O_PATH
+#define O_EXEC    O_PATH
+
+#define O_ACCMODE (03|O_SEARCH)
+#define O_RDONLY  00
+#define O_WRONLY  01
+#define O_RDWR    02
+
+#define F_OFD_GETLK 36
+#define F_OFD_SETLK 37
+#define F_OFD_SETLKW 38
+
+#define F_DUPFD_CLOEXEC 1030
+
+#define F_RDLCK 0
+#define F_WRLCK 1
+#define F_UNLCK 2
+
+#define FD_CLOEXEC 1
+
+#define AT_FDCWD (-100)
+#define AT_SYMLINK_NOFOLLOW 0x100
+#define AT_REMOVEDIR 0x200
+#define AT_SYMLINK_FOLLOW 0x400
+#define AT_EACCESS 0x200
+
+#define POSIX_FADV_NORMAL     0
+#define POSIX_FADV_RANDOM     1
+#define POSIX_FADV_SEQUENTIAL 2
+#define POSIX_FADV_WILLNEED   3
+#define POSIX_FADV_DONTNEED   4
+#define POSIX_FADV_NOREUSE    5
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#ifndef S_IRUSR
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXU 0700
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IRWXG 0070
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#define S_IRWXO 0007
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define AT_NO_AUTOMOUNT 0x800
+#define AT_EMPTY_PATH 0x1000
+
+#define FAPPEND O_APPEND
+#define FFSYNC O_SYNC
+#define FASYNC O_ASYNC
+#define FNONBLOCK O_NONBLOCK
+#define FNDELAY O_NDELAY
+
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#define F_ULOCK 0
+#define F_LOCK  1
+#define F_TLOCK 2
+#define F_TEST  3
+
+#define F_SETLEASE	1024
+#define F_GETLEASE	1025
+#define F_NOTIFY	1026
+#define F_CANCELLK	1029
+#define F_SETPIPE_SZ	1031
+#define F_GETPIPE_SZ	1032
+#define F_ADD_SEALS	1033
+#define F_GET_SEALS	1034
+
+#define F_SEAL_SEAL	0x0001
+#define F_SEAL_SHRINK	0x0002
+#define F_SEAL_GROW	0x0004
+#define F_SEAL_WRITE	0x0008
+
+#define DN_ACCESS	0x00000001
+#define DN_MODIFY	0x00000002
+#define DN_CREATE	0x00000004
+#define DN_DELETE	0x00000008
+#define DN_RENAME	0x00000010
+#define DN_ATTRIB	0x00000020
+#define DN_MULTISHOT	0x80000000
+
+int lockf(int, int, off_t);
+#endif
+
+#if defined(_GNU_SOURCE)
+#define F_OWNER_TID 0
+#define F_OWNER_PID 1
+#define F_OWNER_PGRP 2
+#define F_OWNER_GID 2
+struct f_owner_ex {
+	int type;
+	pid_t pid;
+};
+#define FALLOC_FL_KEEP_SIZE 1
+#define FALLOC_FL_PUNCH_HOLE 2
+#define SYNC_FILE_RANGE_WAIT_BEFORE 1
+#define SYNC_FILE_RANGE_WRITE 2
+#define SYNC_FILE_RANGE_WAIT_AFTER 4
+#define SPLICE_F_MOVE 1
+#define SPLICE_F_NONBLOCK 2
+#define SPLICE_F_MORE 4
+#define SPLICE_F_GIFT 8
+int fallocate(int, int, off_t, off_t);
+#define fallocate64 fallocate
+ssize_t readahead(int, off_t, size_t);
+int sync_file_range(int, off_t, off_t, unsigned);
+ssize_t vmsplice(int, const struct iovec *, size_t, unsigned);
+ssize_t splice(int, off_t *, int, off_t *, size_t, unsigned);
+ssize_t tee(int, int, size_t, unsigned);
+#define loff_t off_t
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define F_GETLK64 F_GETLK
+#define F_SETLK64 F_SETLK
+#define F_SETLKW64 F_SETLKW
+#define flock64 flock
+#define open64 open
+#define openat64 openat
+#define creat64 creat
+#define lockf64 lockf
+#define posix_fadvise64 posix_fadvise
+#define posix_fallocate64 posix_fallocate
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/features.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/features.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/features.h	(revision 398)
@@ -0,0 +1,38 @@
+#ifndef _FEATURES_H
+#define _FEATURES_H
+
+#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE)
+#define _GNU_SOURCE 1
+#endif
+
+#if defined(_DEFAULT_SOURCE) && !defined(_BSD_SOURCE)
+#define _BSD_SOURCE 1
+#endif
+
+#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) \
+ && !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) \
+ && !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__)
+#define _BSD_SOURCE 1
+#define _XOPEN_SOURCE 700
+#endif
+
+#if __STDC_VERSION__ >= 199901L
+#define __restrict restrict
+#elif !defined(__GNUC__)
+#define __restrict
+#endif
+
+#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
+#define __inline inline
+#elif !defined(__GNUC__)
+#define __inline
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+#elif defined(__GNUC__)
+#define _Noreturn __attribute__((__noreturn__))
+#else
+#define _Noreturn
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fenv.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fenv.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fenv.h	(revision 398)
@@ -0,0 +1,28 @@
+#ifndef _FENV_H
+#define _FENV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/fenv.h>
+
+int feclearexcept(int);
+int fegetexceptflag(fexcept_t *, int);
+int feraiseexcept(int);
+int fesetexceptflag(const fexcept_t *, int);
+int fetestexcept(int);
+
+int fegetround(void);
+int fesetround(int);
+
+int fegetenv(fenv_t *);
+int feholdexcept(fenv_t *);
+int fesetenv(const fenv_t *);
+int feupdateenv(const fenv_t *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/float.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/float.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/float.h	(revision 398)
@@ -0,0 +1,52 @@
+#ifndef _FLOAT_H
+#define _FLOAT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int __flt_rounds(void);
+#define FLT_ROUNDS (__flt_rounds())
+
+#define FLT_RADIX 2
+
+#define FLT_TRUE_MIN 1.40129846432481707092e-45F
+#define FLT_MIN 1.17549435082228750797e-38F
+#define FLT_MAX 3.40282346638528859812e+38F
+#define FLT_EPSILON 1.1920928955078125e-07F
+
+#define FLT_MANT_DIG 24
+#define FLT_MIN_EXP (-125)
+#define FLT_MAX_EXP 128
+#define FLT_HAS_SUBNORM 1
+
+#define FLT_DIG 6
+#define FLT_DECIMAL_DIG 9
+#define FLT_MIN_10_EXP (-37)
+#define FLT_MAX_10_EXP 38
+
+#define DBL_TRUE_MIN 4.94065645841246544177e-324
+#define DBL_MIN 2.22507385850720138309e-308
+#define DBL_MAX 1.79769313486231570815e+308
+#define DBL_EPSILON 2.22044604925031308085e-16
+
+#define DBL_MANT_DIG 53
+#define DBL_MIN_EXP (-1021)
+#define DBL_MAX_EXP 1024
+#define DBL_HAS_SUBNORM 1
+
+#define DBL_DIG 15
+#define DBL_DECIMAL_DIG 17
+#define DBL_MIN_10_EXP (-307)
+#define DBL_MAX_10_EXP 308
+
+#define LDBL_HAS_SUBNORM 1
+#define LDBL_DECIMAL_DIG DECIMAL_DIG
+
+#include <bits/float.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fmtmsg.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fmtmsg.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fmtmsg.h	(revision 398)
@@ -0,0 +1,47 @@
+#ifndef _FMTMSG_H
+#define _FMTMSG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MM_HARD		1
+#define MM_SOFT		2
+#define MM_FIRM		4
+
+#define MM_APPL		8
+#define MM_UTIL		16
+#define MM_OPSYS	32
+
+#define MM_RECOVER	64
+#define MM_NRECOV	128
+
+#define MM_PRINT	256
+#define MM_CONSOLE	512
+
+#define MM_NULLMC	0L
+
+#define MM_HALT		1
+#define MM_ERROR	2
+#define MM_WARNING	3
+#define MM_INFO		4
+#define MM_NOSEV	0
+
+#define MM_OK		0
+#define MM_NOTOK	(-1)
+#define MM_NOMSG	1
+#define MM_NOCON	4
+
+#define MM_NULLLBL	((char*)0)
+#define MM_NULLTXT	((char*)0)
+#define MM_NULLACT	((char*)0)
+#define MM_NULLTAG	((char*)0)
+#define MM_NULLSEV	0
+
+int fmtmsg(long, const char *, int, const char *, const char *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fnmatch.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fnmatch.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/fnmatch.h	(revision 398)
@@ -0,0 +1,24 @@
+#ifndef	_FNMATCH_H
+#define	_FNMATCH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	FNM_PATHNAME 0x1
+#define	FNM_NOESCAPE 0x2
+#define	FNM_PERIOD   0x4
+#define	FNM_LEADING_DIR	0x8           
+#define	FNM_CASEFOLD	0x10
+#define	FNM_FILE_NAME	FNM_PATHNAME
+
+#define	FNM_NOMATCH 1
+#define FNM_NOSYS   (-1)
+
+int fnmatch(const char *, const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ftw.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ftw.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ftw.h	(revision 398)
@@ -0,0 +1,41 @@
+#ifndef _FTW_H
+#define	_FTW_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <sys/stat.h>
+
+#define FTW_F   1
+#define FTW_D   2
+#define FTW_DNR 3
+#define FTW_NS  4
+#define FTW_SL  5
+#define FTW_DP  6
+#define FTW_SLN 7
+
+#define FTW_PHYS  1
+#define FTW_MOUNT 2
+#define FTW_CHDIR 4
+#define FTW_DEPTH 8
+
+struct FTW {
+	int base;
+	int level;
+};
+
+int ftw(const char *, int (*)(const char *, const struct stat *, int), int);
+int nftw(const char *, int (*)(const char *, const struct stat *, int, struct FTW *), int, int);
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define ftw64 ftw
+#define nftw64 nftw
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/getopt.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/getopt.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/getopt.h	(revision 398)
@@ -0,0 +1,30 @@
+#ifndef _GETOPT_H
+#define _GETOPT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getopt(int, char * const [], const char *);
+extern char *optarg;
+extern int optind, opterr, optopt, optreset;
+
+struct option {
+	const char *name;
+	int has_arg;
+	int *flag;
+	int val;
+};
+
+int getopt_long(int, char *const *, const char *, const struct option *, int *);
+int getopt_long_only(int, char *const *, const char *, const struct option *, int *);
+
+#define no_argument        0
+#define required_argument  1
+#define optional_argument  2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/glob.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/glob.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/glob.h	(revision 398)
@@ -0,0 +1,49 @@
+#ifndef	_GLOB_H
+#define	_GLOB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef struct {
+	size_t gl_pathc;
+	char **gl_pathv;
+	size_t gl_offs;
+	int __dummy1;
+	void *__dummy2[5];
+} glob_t;
+
+int  glob(const char *__restrict, int, int (*)(const char *, int), glob_t *__restrict);
+void globfree(glob_t *);
+
+#define GLOB_ERR      0x01
+#define GLOB_MARK     0x02
+#define GLOB_NOSORT   0x04
+#define GLOB_DOOFFS   0x08
+#define GLOB_NOCHECK  0x10
+#define GLOB_APPEND   0x20
+#define GLOB_NOESCAPE 0x40
+#define	GLOB_PERIOD   0x80
+
+#define GLOB_NOSPACE 1
+#define GLOB_ABORTED 2
+#define GLOB_NOMATCH 3
+#define GLOB_NOSYS   4
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define glob64 glob
+#define globfree64 globfree
+#define glob64_t glob_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/grp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/grp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/grp.h	(revision 398)
@@ -0,0 +1,53 @@
+#ifndef	_GRP_H
+#define	_GRP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_gid_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_FILE
+#endif
+
+#include <bits/alltypes.h>
+
+struct group {
+	char *gr_name;
+	char *gr_passwd;
+	gid_t gr_gid;
+	char **gr_mem;
+};
+
+struct group  *getgrgid(gid_t);
+struct group  *getgrnam(const char *);
+
+int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
+int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct group  *getgrent(void);
+void           endgrent(void);
+void           setgrent(void);
+#endif
+
+#ifdef _GNU_SOURCE
+struct group  *fgetgrent(FILE *);
+int putgrent(const struct group *, FILE *);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int getgrouplist(const char *, gid_t, gid_t *, int *);
+int setgroups(size_t, const gid_t *);
+int initgroups(const char *, gid_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/iconv.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/iconv.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/iconv.h	(revision 398)
@@ -0,0 +1,24 @@
+#ifndef _ICONV_H
+#define _ICONV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef void *iconv_t;
+
+iconv_t iconv_open(const char *, const char *);
+size_t iconv(iconv_t, char **__restrict, size_t *__restrict, char **__restrict, size_t *__restrict);
+int iconv_close(iconv_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ifaddrs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ifaddrs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ifaddrs.h	(revision 398)
@@ -0,0 +1,35 @@
+#ifndef _IFADDRS_H
+#define _IFADDRS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+struct ifaddrs {
+	struct ifaddrs *ifa_next;
+	char *ifa_name;
+	unsigned ifa_flags;
+	struct sockaddr *ifa_addr;
+	struct sockaddr *ifa_netmask;
+	union {
+		struct sockaddr *ifu_broadaddr;
+		struct sockaddr *ifu_dstaddr;
+	} ifa_ifu;
+	void *ifa_data;
+};
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr
+
+void freeifaddrs(struct ifaddrs *);
+int getifaddrs(struct ifaddrs **);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/inttypes.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/inttypes.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/inttypes.h	(revision 398)
@@ -0,0 +1,229 @@
+#ifndef _INTTYPES_H
+#define _INTTYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <stdint.h>
+
+#define __NEED_wchar_t
+#include <bits/alltypes.h>
+
+typedef struct { intmax_t quot, rem; } imaxdiv_t;
+
+intmax_t imaxabs(intmax_t);
+imaxdiv_t imaxdiv(intmax_t, intmax_t);
+
+intmax_t strtoimax(const char *__restrict, char **__restrict, int);
+uintmax_t strtoumax(const char *__restrict, char **__restrict, int);
+
+intmax_t wcstoimax(const wchar_t *__restrict, wchar_t **__restrict, int);
+uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int);
+
+#if UINTPTR_MAX == UINT64_MAX
+#define __PRI64  "l"
+#define __PRIPTR "l"
+#else
+#define __PRI64  "ll"
+#define __PRIPTR ""
+#endif
+
+#define PRId8  "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 __PRI64 "d"
+
+#define PRIdLEAST8  "d"
+#define PRIdLEAST16 "d"
+#define PRIdLEAST32 "d"
+#define PRIdLEAST64 __PRI64 "d"
+
+#define PRIdFAST8  "d"
+#define PRIdFAST16 "d"
+#define PRIdFAST32 "d"
+#define PRIdFAST64 __PRI64 "d"
+
+#define PRIi8  "i"
+#define PRIi16 "i"
+#define PRIi32 "i"
+#define PRIi64 __PRI64 "i"
+
+#define PRIiLEAST8  "i"
+#define PRIiLEAST16 "i"
+#define PRIiLEAST32 "i"
+#define PRIiLEAST64 __PRI64 "i"
+
+#define PRIiFAST8  "i"
+#define PRIiFAST16 "i"
+#define PRIiFAST32 "i"
+#define PRIiFAST64 __PRI64 "i"
+
+#define PRIo8  "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 __PRI64 "o"
+
+#define PRIoLEAST8  "o"
+#define PRIoLEAST16 "o"
+#define PRIoLEAST32 "o"
+#define PRIoLEAST64 __PRI64 "o"
+
+#define PRIoFAST8  "o"
+#define PRIoFAST16 "o"
+#define PRIoFAST32 "o"
+#define PRIoFAST64 __PRI64 "o"
+
+#define PRIu8  "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 __PRI64 "u"
+
+#define PRIuLEAST8  "u"
+#define PRIuLEAST16 "u"
+#define PRIuLEAST32 "u"
+#define PRIuLEAST64 __PRI64 "u"
+
+#define PRIuFAST8  "u"
+#define PRIuFAST16 "u"
+#define PRIuFAST32 "u"
+#define PRIuFAST64 __PRI64 "u"
+
+#define PRIx8  "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 __PRI64 "x"
+
+#define PRIxLEAST8  "x"
+#define PRIxLEAST16 "x"
+#define PRIxLEAST32 "x"
+#define PRIxLEAST64 __PRI64 "x"
+
+#define PRIxFAST8  "x"
+#define PRIxFAST16 "x"
+#define PRIxFAST32 "x"
+#define PRIxFAST64 __PRI64 "x"
+
+#define PRIX8  "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 __PRI64 "X"
+
+#define PRIXLEAST8  "X"
+#define PRIXLEAST16 "X"
+#define PRIXLEAST32 "X"
+#define PRIXLEAST64 __PRI64 "X"
+
+#define PRIXFAST8  "X"
+#define PRIXFAST16 "X"
+#define PRIXFAST32 "X"
+#define PRIXFAST64 __PRI64 "X"
+
+#define PRIdMAX __PRI64 "d"
+#define PRIiMAX __PRI64 "i"
+#define PRIoMAX __PRI64 "o"
+#define PRIuMAX __PRI64 "u"
+#define PRIxMAX __PRI64 "x"
+#define PRIXMAX __PRI64 "X"
+
+#define PRIdPTR __PRIPTR "d"
+#define PRIiPTR __PRIPTR "i"
+#define PRIoPTR __PRIPTR "o"
+#define PRIuPTR __PRIPTR "u"
+#define PRIxPTR __PRIPTR "x"
+#define PRIXPTR __PRIPTR "X"
+
+#define SCNd8   "hhd"
+#define SCNd16  "hd"
+#define SCNd32  "d"
+#define SCNd64  __PRI64 "d"
+
+#define SCNdLEAST8  "hhd"
+#define SCNdLEAST16 "hd"
+#define SCNdLEAST32 "d"
+#define SCNdLEAST64 __PRI64 "d"
+
+#define SCNdFAST8  "hhd"
+#define SCNdFAST16 "d"
+#define SCNdFAST32 "d"
+#define SCNdFAST64 __PRI64 "d"
+
+#define SCNi8   "hhi"
+#define SCNi16  "hi"
+#define SCNi32  "i"
+#define SCNi64  __PRI64 "i"
+
+#define SCNiLEAST8  "hhi"
+#define SCNiLEAST16 "hi"
+#define SCNiLEAST32 "i"
+#define SCNiLEAST64 __PRI64 "i"
+
+#define SCNiFAST8  "hhi"
+#define SCNiFAST16 "i"
+#define SCNiFAST32 "i"
+#define SCNiFAST64 __PRI64 "i"
+
+#define SCNu8   "hhu"
+#define SCNu16  "hu"
+#define SCNu32  "u"
+#define SCNu64  __PRI64 "u"
+
+#define SCNuLEAST8  "hhu"
+#define SCNuLEAST16 "hu"
+#define SCNuLEAST32 "u"
+#define SCNuLEAST64 __PRI64 "u"
+
+#define SCNuFAST8 "hhu"
+#define SCNuFAST16 "u"
+#define SCNuFAST32 "u"
+#define SCNuFAST64 __PRI64 "u"
+
+#define SCNo8   "hho"
+#define SCNo16  "ho"
+#define SCNo32  "o"
+#define SCNo64  __PRI64 "o"
+
+#define SCNoLEAST8  "hho"
+#define SCNoLEAST16 "ho"
+#define SCNoLEAST32 "o"
+#define SCNoLEAST64 __PRI64 "o"
+
+#define SCNoFAST8  "hho"
+#define SCNoFAST16 "o"
+#define SCNoFAST32 "o"
+#define SCNoFAST64 __PRI64 "o"
+
+#define SCNx8   "hhx"
+#define SCNx16  "hx"
+#define SCNx32  "x"
+#define SCNx64  __PRI64 "x"
+
+#define SCNxLEAST8  "hhx"
+#define SCNxLEAST16 "hx"
+#define SCNxLEAST32 "x"
+#define SCNxLEAST64 __PRI64 "x"
+
+#define SCNxFAST8  "hhx"
+#define SCNxFAST16 "x"
+#define SCNxFAST32 "x"
+#define SCNxFAST64 __PRI64 "x"
+
+#define SCNdMAX __PRI64 "d"
+#define SCNiMAX __PRI64 "i"
+#define SCNoMAX __PRI64 "o"
+#define SCNuMAX __PRI64 "u"
+#define SCNxMAX __PRI64 "x"
+
+#define SCNdPTR __PRIPTR "d"
+#define SCNiPTR __PRIPTR "i"
+#define SCNoPTR __PRIPTR "o"
+#define SCNuPTR __PRIPTR "u"
+#define SCNxPTR __PRIPTR "x"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/iso646.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/iso646.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/iso646.h	(revision 398)
@@ -0,0 +1,20 @@
+#ifndef _ISO646_H
+#define _ISO646_H
+
+#ifndef __cplusplus
+
+#define and    &&
+#define and_eq &=
+#define bitand &
+#define bitor  |
+#define compl  ~
+#define not    !
+#define not_eq !=
+#define or     ||
+#define or_eq  |=
+#define xor    ^
+#define xor_eq ^=
+
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/langinfo.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/langinfo.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/langinfo.h	(revision 398)
@@ -0,0 +1,98 @@
+#ifndef _LANGINFO_H
+#define _LANGINFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <nl_types.h>
+
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+#define ABDAY_1 0x20000
+#define ABDAY_2 0x20001
+#define ABDAY_3 0x20002
+#define ABDAY_4 0x20003
+#define ABDAY_5 0x20004
+#define ABDAY_6 0x20005
+#define ABDAY_7 0x20006
+
+#define DAY_1 0x20007
+#define DAY_2 0x20008
+#define DAY_3 0x20009
+#define DAY_4 0x2000A
+#define DAY_5 0x2000B
+#define DAY_6 0x2000C
+#define DAY_7 0x2000D
+
+#define ABMON_1 0x2000E
+#define ABMON_2 0x2000F
+#define ABMON_3 0x20010
+#define ABMON_4 0x20011
+#define ABMON_5 0x20012
+#define ABMON_6 0x20013
+#define ABMON_7 0x20014
+#define ABMON_8 0x20015
+#define ABMON_9 0x20016
+#define ABMON_10 0x20017
+#define ABMON_11 0x20018
+#define ABMON_12 0x20019
+
+#define MON_1 0x2001A
+#define MON_2 0x2001B
+#define MON_3 0x2001C
+#define MON_4 0x2001D
+#define MON_5 0x2001E
+#define MON_6 0x2001F
+#define MON_7 0x20020
+#define MON_8 0x20021
+#define MON_9 0x20022
+#define MON_10 0x20023
+#define MON_11 0x20024
+#define MON_12 0x20025
+
+#define AM_STR 0x20026
+#define PM_STR 0x20027
+
+#define D_T_FMT 0x20028
+#define D_FMT 0x20029
+#define T_FMT 0x2002A
+#define T_FMT_AMPM 0x2002B
+
+#define ERA 0x2002C
+#define ERA_D_FMT 0x2002E
+#define ALT_DIGITS 0x2002F
+#define ERA_D_T_FMT 0x20030
+#define ERA_T_FMT 0x20031
+
+#define CODESET 14
+
+#define CRNCYSTR 0x4000F
+
+#define RADIXCHAR 0x10000
+#define THOUSEP 0x10001
+#define YESEXPR 0x50000
+#define NOEXPR 0x50001
+
+#define _NL_LOCALE_NAME(cat) (((cat)<<16) | 0xffff)
+
+#if defined(_GNU_SOURCE)
+#define NL_LOCALE_NAME(cat) _NL_LOCALE_NAME(cat)
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define YESSTR 0x50002
+#define NOSTR 0x50003
+#endif
+
+char *nl_langinfo(nl_item);
+char *nl_langinfo_l(nl_item, locale_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/lastlog.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/lastlog.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/lastlog.h	(revision 398)
@@ -0,0 +1,1 @@
+#include <utmp.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/libgen.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/libgen.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/libgen.h	(revision 398)
@@ -0,0 +1,15 @@
+#ifndef _LIBGEN_H
+#define _LIBGEN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *dirname(char *);
+char *basename(char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/libintl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/libintl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/libintl.h	(revision 398)
@@ -0,0 +1,33 @@
+#ifndef _LIBINTL_H
+#define _LIBINTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __USE_GNU_GETTEXT 1
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 1 : -1)
+
+#if __GNUC__ >= 3
+#define __fa(n) __attribute__ ((__format_arg__ (n)))
+#else
+#define __fa(n)
+#endif
+
+char *gettext(const char *) __fa(1);
+char *dgettext(const char *, const char *) __fa(2);
+char *dcgettext(const char *, const char *, int) __fa(2);
+char *ngettext(const char *, const char *, unsigned long) __fa(1) __fa(2);
+char *dngettext(const char *, const char *, const char *, unsigned long) __fa(2) __fa(3);
+char *dcngettext(const char *, const char *, const char *, unsigned long, int) __fa(2) __fa(3);
+char *textdomain(const char *);
+char *bindtextdomain (const char *, const char *);
+char *bind_textdomain_codeset(const char *, const char *);
+
+#undef __fa
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/limits.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/limits.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/limits.h	(revision 398)
@@ -0,0 +1,154 @@
+#ifndef _LIMITS_H
+#define _LIMITS_H
+
+#include <features.h>
+
+/* Most limits are system-specific */
+
+#include <bits/limits.h>
+
+/* Support signed or unsigned plain-char */
+
+#if '\0'-1 > 0
+#define CHAR_MIN 0
+#define CHAR_MAX 255
+#else
+#define CHAR_MIN (-128)
+#define CHAR_MAX 127
+#endif
+
+/* Some universal constants... */
+
+#define CHAR_BIT 8
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+#define UCHAR_MAX 255
+#define SHRT_MIN  (-1-0x7fff)
+#define SHRT_MAX  0x7fff
+#define USHRT_MAX 0xffff
+#define INT_MIN  (-1-0x7fffffff)
+#define INT_MAX  0x7fffffff
+#define UINT_MAX 0xffffffffU
+#define LONG_MIN (-LONG_MAX-1)
+#define ULONG_MAX (2UL*LONG_MAX+1)
+#define LLONG_MIN (-LLONG_MAX-1)
+#define ULLONG_MAX (2ULL*LLONG_MAX+1)
+
+#define MB_LEN_MAX 4
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define PIPE_BUF 4096
+#ifdef PAGE_SIZE
+#define PAGESIZE PAGE_SIZE
+#endif
+#define FILESIZEBITS 64
+#define NAME_MAX 255
+#define SYMLINK_MAX 255
+#define PATH_MAX 4096
+#define NZERO 20
+#define NGROUPS_MAX 32
+#define ARG_MAX 131072
+#define IOV_MAX 1024
+#define SYMLOOP_MAX 40
+#define WORD_BIT 32
+#define SSIZE_MAX LONG_MAX
+#define TZNAME_MAX 6
+#define TTY_NAME_MAX 32
+#define HOST_NAME_MAX 255
+
+/* Implementation choices... */
+
+#define PTHREAD_KEYS_MAX 128
+#define PTHREAD_STACK_MIN 2048
+#define PTHREAD_DESTRUCTOR_ITERATIONS 4
+#define SEM_VALUE_MAX 0x7fffffff
+#define SEM_NSEMS_MAX 256
+#define DELAYTIMER_MAX 0x7fffffff
+#define MQ_PRIO_MAX 32768
+#define LOGIN_NAME_MAX 256
+
+/* Arbitrary numbers... */
+
+#define BC_BASE_MAX 99
+#define BC_DIM_MAX 2048
+#define BC_SCALE_MAX 99
+#define BC_STRING_MAX 1000
+#define CHARCLASS_NAME_MAX 14
+#define COLL_WEIGHTS_MAX 2
+#define EXPR_NEST_MAX 32
+#define LINE_MAX 4096
+#define RE_DUP_MAX 255
+
+#define NL_ARGMAX 9
+#define NL_LANGMAX 32
+#define NL_MSGMAX 32767
+#define NL_SETMAX 255
+#define NL_TEXTMAX 2048
+
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \
+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
+
+#define NL_NMAX 16
+
+#endif
+
+/* POSIX/SUS requirements follow. These numbers come directly
+ * from SUS and have nothing to do with the host system. */
+
+#define _POSIX_AIO_LISTIO_MAX   2
+#define _POSIX_AIO_MAX          1
+#define _POSIX_ARG_MAX          4096
+#define _POSIX_CHILD_MAX        25
+#define _POSIX_CLOCKRES_MIN     20000000
+#define _POSIX_DELAYTIMER_MAX   32
+#define _POSIX_HOST_NAME_MAX    255
+#define _POSIX_LINK_MAX         8
+#define _POSIX_LOGIN_NAME_MAX   9
+#define _POSIX_MAX_CANON        255
+#define _POSIX_MAX_INPUT        255
+#define _POSIX_MQ_OPEN_MAX      8
+#define _POSIX_MQ_PRIO_MAX      32
+#define _POSIX_NAME_MAX         14
+#define _POSIX_NGROUPS_MAX      8
+#define _POSIX_OPEN_MAX         20
+#define _POSIX_PATH_MAX         256
+#define _POSIX_PIPE_BUF         512
+#define _POSIX_RE_DUP_MAX       255
+#define _POSIX_RTSIG_MAX        8
+#define _POSIX_SEM_NSEMS_MAX    256
+#define _POSIX_SEM_VALUE_MAX    32767
+#define _POSIX_SIGQUEUE_MAX     32
+#define _POSIX_SSIZE_MAX        32767
+#define _POSIX_STREAM_MAX       8
+#define _POSIX_SS_REPL_MAX      4
+#define _POSIX_SYMLINK_MAX      255
+#define _POSIX_SYMLOOP_MAX      8
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+#define _POSIX_THREAD_KEYS_MAX  128
+#define _POSIX_THREAD_THREADS_MAX 64
+#define _POSIX_TIMER_MAX        32
+#define _POSIX_TRACE_EVENT_NAME_MAX 30
+#define _POSIX_TRACE_NAME_MAX   8
+#define _POSIX_TRACE_SYS_MAX    8
+#define _POSIX_TRACE_USER_EVENT_MAX 32
+#define _POSIX_TTY_NAME_MAX     9
+#define _POSIX_TZNAME_MAX       6
+#define _POSIX2_BC_BASE_MAX     99
+#define _POSIX2_BC_DIM_MAX      2048
+#define _POSIX2_BC_SCALE_MAX    99
+#define _POSIX2_BC_STRING_MAX   1000
+#define _POSIX2_CHARCLASS_NAME_MAX 14
+#define _POSIX2_COLL_WEIGHTS_MAX 2
+#define _POSIX2_EXPR_NEST_MAX   32
+#define _POSIX2_LINE_MAX        2048
+#define _POSIX2_RE_DUP_MAX      255
+
+#define _XOPEN_IOV_MAX          16
+#define _XOPEN_NAME_MAX         255
+#define _XOPEN_PATH_MAX         1024
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/link.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/link.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/link.h	(revision 398)
@@ -0,0 +1,53 @@
+#ifndef _LINK_H
+#define _LINK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <elf.h>
+#define __NEED_size_t
+#define __NEED_uint32_t
+#include <bits/alltypes.h>
+
+#if UINTPTR_MAX > 0xffffffff
+#define ElfW(type) Elf64_ ## type
+#else
+#define ElfW(type) Elf32_ ## type
+#endif
+
+#include <bits/link.h>
+
+struct dl_phdr_info {
+	ElfW(Addr) dlpi_addr;
+	const char *dlpi_name;
+	const ElfW(Phdr) *dlpi_phdr;
+	ElfW(Half) dlpi_phnum;
+	unsigned long long int dlpi_adds;
+	unsigned long long int dlpi_subs;
+	size_t dlpi_tls_modid;
+	void *dlpi_tls_data;
+};
+
+struct link_map {
+	ElfW(Addr) l_addr;
+	char *l_name;
+	ElfW(Dyn) *l_ld;
+	struct link_map *l_next, *l_prev;
+};
+
+struct r_debug {
+	int r_version;
+	struct link_map *r_map;
+	ElfW(Addr) r_brk;
+	enum { RT_CONSISTENT, RT_ADD, RT_DELETE } r_state;
+	ElfW(Addr) r_ldbase;
+};
+
+int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *), void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/locale.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/locale.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/locale.h	(revision 398)
@@ -0,0 +1,86 @@
+#ifndef	_LOCALE_H
+#define	_LOCALE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#define LC_CTYPE    0
+#define LC_NUMERIC  1
+#define LC_TIME     2
+#define LC_COLLATE  3
+#define LC_MONETARY 4
+#define LC_MESSAGES 5
+#define LC_ALL      6
+
+struct lconv {
+	char *decimal_point;
+	char *thousands_sep;
+	char *grouping;
+
+	char *int_curr_symbol;
+	char *currency_symbol;
+	char *mon_decimal_point;
+	char *mon_thousands_sep;
+	char *mon_grouping;
+	char *positive_sign;
+	char *negative_sign;
+	char int_frac_digits;
+	char frac_digits;
+	char p_cs_precedes;
+	char p_sep_by_space;
+	char n_cs_precedes;
+	char n_sep_by_space;
+	char p_sign_posn;
+	char n_sign_posn;
+	char int_p_cs_precedes;
+	char int_p_sep_by_space;
+	char int_n_cs_precedes;
+	char int_n_sep_by_space;
+	char int_p_sign_posn;
+	char int_n_sign_posn;
+};
+
+
+char *setlocale (int, const char *);
+struct lconv *localeconv(void);
+
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+#define LC_GLOBAL_LOCALE ((locale_t)-1)
+
+#define LC_CTYPE_MASK    (1<<LC_CTYPE)
+#define LC_NUMERIC_MASK  (1<<LC_NUMERIC)
+#define LC_TIME_MASK     (1<<LC_TIME)
+#define LC_COLLATE_MASK  (1<<LC_COLLATE)
+#define LC_MONETARY_MASK (1<<LC_MONETARY)
+#define LC_MESSAGES_MASK (1<<LC_MESSAGES)
+#define LC_ALL_MASK      0x7fffffff
+
+locale_t duplocale(locale_t);
+void freelocale(locale_t);
+locale_t newlocale(int, const char *, locale_t);
+locale_t uselocale(locale_t);
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/malloc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/malloc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/malloc.h	(revision 398)
@@ -0,0 +1,25 @@
+#ifndef _MALLOC_H
+#define _MALLOC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+void *malloc (size_t);
+void *calloc (size_t, size_t);
+void *realloc (void *, size_t);
+void free (void *);
+void *valloc (size_t);
+void *memalign(size_t, size_t);
+
+size_t malloc_usable_size(void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/math.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/math.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/math.h	(revision 398)
@@ -0,0 +1,430 @@
+#ifndef _MATH_H
+#define _MATH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_float_t
+#define __NEED_double_t
+#include <bits/alltypes.h>
+
+#if 100*__GNUC__+__GNUC_MINOR__ >= 303
+#define NAN       __builtin_nanf("")
+#define INFINITY  __builtin_inff()
+#else
+#define NAN       (0.0f/0.0f)
+#define INFINITY  1e5000f
+#endif
+
+#define HUGE_VALF INFINITY
+#define HUGE_VAL  ((double)INFINITY)
+#define HUGE_VALL ((long double)INFINITY)
+
+#define MATH_ERRNO  1
+#define MATH_ERREXCEPT 2
+#define math_errhandling 2
+
+#define FP_ILOGBNAN (-1-(int)(((unsigned)-1)>>1))
+#define FP_ILOGB0 FP_ILOGBNAN
+
+#define FP_NAN       0
+#define FP_INFINITE  1
+#define FP_ZERO      2
+#define FP_SUBNORMAL 3
+#define FP_NORMAL    4
+
+int __fpclassify(double);
+int __fpclassifyf(float);
+int __fpclassifyl(long double);
+
+static __inline unsigned __FLOAT_BITS(float __f)
+{
+	union {float __f; unsigned __i;} __u;
+	__u.__f = __f;
+	return __u.__i;
+}
+static __inline unsigned long long __DOUBLE_BITS(double __f)
+{
+	union {double __f; unsigned long long __i;} __u;
+	__u.__f = __f;
+	return __u.__i;
+}
+
+#define fpclassify(x) ( \
+	sizeof(x) == sizeof(float) ? __fpclassifyf(x) : \
+	sizeof(x) == sizeof(double) ? __fpclassify(x) : \
+	__fpclassifyl(x) )
+
+#define isinf(x) ( \
+	sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : \
+	sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) == 0x7ffULL<<52 : \
+	__fpclassifyl(x) == FP_INFINITE)
+
+#define isnan(x) ( \
+	sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : \
+	sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) > 0x7ffULL<<52 : \
+	__fpclassifyl(x) == FP_NAN)
+
+#define isnormal(x) ( \
+	sizeof(x) == sizeof(float) ? ((__FLOAT_BITS(x)+0x00800000) & 0x7fffffff) >= 0x01000000 : \
+	sizeof(x) == sizeof(double) ? ((__DOUBLE_BITS(x)+(1ULL<<52)) & -1ULL>>1) >= 1ULL<<53 : \
+	__fpclassifyl(x) == FP_NORMAL)
+
+#define isfinite(x) ( \
+	sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000 : \
+	sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) < 0x7ffULL<<52 : \
+	__fpclassifyl(x) > FP_INFINITE)
+
+int __signbit(double);
+int __signbitf(float);
+int __signbitl(long double);
+
+#define signbit(x) ( \
+	sizeof(x) == sizeof(float) ? (int)(__FLOAT_BITS(x)>>31) : \
+	sizeof(x) == sizeof(double) ? (int)(__DOUBLE_BITS(x)>>63) : \
+	__signbitl(x) )
+
+#define isunordered(x,y) (isnan((x)) ? ((void)(y),1) : isnan((y)))
+
+#define __ISREL_DEF(rel, op, type) \
+static __inline int __is##rel(type __x, type __y) \
+{ return !isunordered(__x,__y) && __x op __y; }
+
+__ISREL_DEF(lessf, <, float_t)
+__ISREL_DEF(less, <, double_t)
+__ISREL_DEF(lessl, <, long double)
+__ISREL_DEF(lessequalf, <=, float_t)
+__ISREL_DEF(lessequal, <=, double_t)
+__ISREL_DEF(lessequall, <=, long double)
+__ISREL_DEF(lessgreaterf, !=, float_t)
+__ISREL_DEF(lessgreater, !=, double_t)
+__ISREL_DEF(lessgreaterl, !=, long double)
+__ISREL_DEF(greaterf, >, float_t)
+__ISREL_DEF(greater, >, double_t)
+__ISREL_DEF(greaterl, >, long double)
+__ISREL_DEF(greaterequalf, >=, float_t)
+__ISREL_DEF(greaterequal, >=, double_t)
+__ISREL_DEF(greaterequall, >=, long double)
+
+#define __tg_pred_2(x, y, p) ( \
+	sizeof((x)+(y)) == sizeof(float) ? p##f(x, y) : \
+	sizeof((x)+(y)) == sizeof(double) ? p(x, y) : \
+	p##l(x, y) )
+
+#define isless(x, y)            __tg_pred_2(x, y, __isless)
+#define islessequal(x, y)       __tg_pred_2(x, y, __islessequal)
+#define islessgreater(x, y)     __tg_pred_2(x, y, __islessgreater)
+#define isgreater(x, y)         __tg_pred_2(x, y, __isgreater)
+#define isgreaterequal(x, y)    __tg_pred_2(x, y, __isgreaterequal)
+
+double      acos(double);
+float       acosf(float);
+long double acosl(long double);
+
+double      acosh(double);
+float       acoshf(float);
+long double acoshl(long double);
+
+double      asin(double);
+float       asinf(float);
+long double asinl(long double);
+
+double      asinh(double);
+float       asinhf(float);
+long double asinhl(long double);
+
+double      atan(double);
+float       atanf(float);
+long double atanl(long double);
+
+double      atan2(double, double);
+float       atan2f(float, float);
+long double atan2l(long double, long double);
+
+double      atanh(double);
+float       atanhf(float);
+long double atanhl(long double);
+
+double      cbrt(double);
+float       cbrtf(float);
+long double cbrtl(long double);
+
+double      ceil(double);
+float       ceilf(float);
+long double ceill(long double);
+
+double      copysign(double, double);
+float       copysignf(float, float);
+long double copysignl(long double, long double);
+
+double      cos(double);
+float       cosf(float);
+long double cosl(long double);
+
+double      cosh(double);
+float       coshf(float);
+long double coshl(long double);
+
+double      erf(double);
+float       erff(float);
+long double erfl(long double);
+
+double      erfc(double);
+float       erfcf(float);
+long double erfcl(long double);
+
+double      exp(double);
+float       expf(float);
+long double expl(long double);
+
+double      exp2(double);
+float       exp2f(float);
+long double exp2l(long double);
+
+double      expm1(double);
+float       expm1f(float);
+long double expm1l(long double);
+
+double      fabs(double);
+float       fabsf(float);
+long double fabsl(long double);
+
+double      fdim(double, double);
+float       fdimf(float, float);
+long double fdiml(long double, long double);
+
+double      floor(double);
+float       floorf(float);
+long double floorl(long double);
+
+double      fma(double, double, double);
+float       fmaf(float, float, float);
+long double fmal(long double, long double, long double);
+
+double      fmax(double, double);
+float       fmaxf(float, float);
+long double fmaxl(long double, long double);
+
+double      fmin(double, double);
+float       fminf(float, float);
+long double fminl(long double, long double);
+
+double      fmod(double, double);
+float       fmodf(float, float);
+long double fmodl(long double, long double);
+
+double      frexp(double, int *);
+float       frexpf(float, int *);
+long double frexpl(long double, int *);
+
+double      hypot(double, double);
+float       hypotf(float, float);
+long double hypotl(long double, long double);
+
+int         ilogb(double);
+int         ilogbf(float);
+int         ilogbl(long double);
+
+double      ldexp(double, int);
+float       ldexpf(float, int);
+long double ldexpl(long double, int);
+
+double      lgamma(double);
+float       lgammaf(float);
+long double lgammal(long double);
+
+long long   llrint(double);
+long long   llrintf(float);
+long long   llrintl(long double);
+
+long long   llround(double);
+long long   llroundf(float);
+long long   llroundl(long double);
+
+double      log(double);
+float       logf(float);
+long double logl(long double);
+
+double      log10(double);
+float       log10f(float);
+long double log10l(long double);
+
+double      log1p(double);
+float       log1pf(float);
+long double log1pl(long double);
+
+double      log2(double);
+float       log2f(float);
+long double log2l(long double);
+
+double      logb(double);
+float       logbf(float);
+long double logbl(long double);
+
+long        lrint(double);
+long        lrintf(float);
+long        lrintl(long double);
+
+long        lround(double);
+long        lroundf(float);
+long        lroundl(long double);
+
+double      modf(double, double *);
+float       modff(float, float *);
+long double modfl(long double, long double *);
+
+double      nan(const char *);
+float       nanf(const char *);
+long double nanl(const char *);
+
+double      nearbyint(double);
+float       nearbyintf(float);
+long double nearbyintl(long double);
+
+double      nextafter(double, double);
+float       nextafterf(float, float);
+long double nextafterl(long double, long double);
+
+double      nexttoward(double, long double);
+float       nexttowardf(float, long double);
+long double nexttowardl(long double, long double);
+
+double      pow(double, double);
+float       powf(float, float);
+long double powl(long double, long double);
+
+double      remainder(double, double);
+float       remainderf(float, float);
+long double remainderl(long double, long double);
+
+double      remquo(double, double, int *);
+float       remquof(float, float, int *);
+long double remquol(long double, long double, int *);
+
+double      rint(double);
+float       rintf(float);
+long double rintl(long double);
+
+double      round(double);
+float       roundf(float);
+long double roundl(long double);
+
+double      scalbln(double, long);
+float       scalblnf(float, long);
+long double scalblnl(long double, long);
+
+double      scalbn(double, int);
+float       scalbnf(float, int);
+long double scalbnl(long double, int);
+
+double      sin(double);
+float       sinf(float);
+long double sinl(long double);
+
+double      sinh(double);
+float       sinhf(float);
+long double sinhl(long double);
+
+double      sqrt(double);
+float       sqrtf(float);
+long double sqrtl(long double);
+
+double      tan(double);
+float       tanf(float);
+long double tanl(long double);
+
+double      tanh(double);
+float       tanhf(float);
+long double tanhl(long double);
+
+double      tgamma(double);
+float       tgammaf(float);
+long double tgammal(long double);
+
+double      trunc(double);
+float       truncf(float);
+long double truncl(long double);
+
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE)
+#undef  MAXFLOAT
+#define MAXFLOAT        3.40282346638528859812e+38F
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define M_E             2.7182818284590452354   /* e */
+#define M_LOG2E         1.4426950408889634074   /* log_2 e */
+#define M_LOG10E        0.43429448190325182765  /* log_10 e */
+#define M_LN2           0.69314718055994530942  /* log_e 2 */
+#define M_LN10          2.30258509299404568402  /* log_e 10 */
+#define M_PI            3.14159265358979323846  /* pi */
+#define M_PI_2          1.57079632679489661923  /* pi/2 */
+#define M_PI_4          0.78539816339744830962  /* pi/4 */
+#define M_1_PI          0.31830988618379067154  /* 1/pi */
+#define M_2_PI          0.63661977236758134308  /* 2/pi */
+#define M_2_SQRTPI      1.12837916709551257390  /* 2/sqrt(pi) */
+#define M_SQRT2         1.41421356237309504880  /* sqrt(2) */
+#define M_SQRT1_2       0.70710678118654752440  /* 1/sqrt(2) */
+
+extern int signgam;
+
+double      j0(double);
+double      j1(double);
+double      jn(int, double);
+
+double      y0(double);
+double      y1(double);
+double      yn(int, double);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define HUGE            3.40282346638528859812e+38F
+
+double      drem(double, double);
+float       dremf(float, float);
+
+int         finite(double);
+int         finitef(float);
+
+double      scalb(double, double);
+float       scalbf(float, float);
+
+double      significand(double);
+float       significandf(float);
+
+double      lgamma_r(double, int*);
+float       lgammaf_r(float, int*);
+
+float       j0f(float);
+float       j1f(float);
+float       jnf(int, float);
+
+float       y0f(float);
+float       y1f(float);
+float       ynf(int, float);
+#endif
+
+#ifdef _GNU_SOURCE
+long double lgammal_r(long double, int*);
+
+void        sincos(double, double*, double*);
+void        sincosf(float, float*, float*);
+void        sincosl(long double, long double*, long double*);
+
+double      exp10(double);
+float       exp10f(float);
+long double exp10l(long double);
+
+double      pow10(double);
+float       pow10f(float);
+long double pow10l(long double);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/memory.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/memory.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/memory.h	(revision 398)
@@ -0,0 +1,1 @@
+#include <string.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/mntent.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/mntent.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/mntent.h	(revision 398)
@@ -0,0 +1,43 @@
+#ifndef _MNTENT_H
+#define _MNTENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_FILE
+#include <bits/alltypes.h>
+
+#define MOUNTED "/etc/mtab"
+
+#define MNTTYPE_IGNORE	"ignore"
+#define MNTTYPE_NFS	"nfs"
+#define MNTTYPE_SWAP	"swap"
+#define MNTOPT_DEFAULTS	"defaults"
+#define MNTOPT_RO	"ro"
+#define MNTOPT_RW	"rw"
+#define MNTOPT_SUID	"suid"
+#define MNTOPT_NOSUID	"nosuid"
+#define MNTOPT_NOAUTO	"noauto"
+
+struct mntent {
+	char *mnt_fsname;
+	char *mnt_dir;
+	char *mnt_type;
+	char *mnt_opts;
+	int mnt_freq;
+	int mnt_passno;
+};
+
+FILE *setmntent(const char *, const char *);
+int endmntent(FILE *);
+struct mntent *getmntent(FILE *);
+struct mntent *getmntent_r(FILE *, struct mntent *, char *, int);
+int addmntent(FILE *, const struct mntent *);
+char *hasmntopt(const struct mntent *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/monetary.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/monetary.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/monetary.h	(revision 398)
@@ -0,0 +1,23 @@
+#ifndef _MONETARY_H
+#define _MONETARY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ssize_t
+#define __NEED_size_t
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+ssize_t strfmon(char *__restrict, size_t, const char *__restrict, ...);
+ssize_t strfmon_l(char *__restrict, size_t, locale_t, const char *__restrict, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/mqueue.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/mqueue.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/mqueue.h	(revision 398)
@@ -0,0 +1,36 @@
+#ifndef _MQUEUE_H
+#define _MQUEUE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_pthread_attr_t
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#include <bits/alltypes.h>
+
+typedef int mqd_t;
+struct mq_attr {
+	long mq_flags, mq_maxmsg, mq_msgsize, mq_curmsgs, __unused[4];
+};
+struct sigevent;
+
+int mq_close(mqd_t);
+int mq_getattr(mqd_t, struct mq_attr *);
+int mq_notify(mqd_t, const struct sigevent *);
+mqd_t mq_open(const char *, int, ...);
+ssize_t mq_receive(mqd_t, char *, size_t, unsigned *);
+int mq_send(mqd_t, const char *, size_t, unsigned);
+int mq_setattr(mqd_t, const struct mq_attr *__restrict, struct mq_attr *__restrict);
+ssize_t mq_timedreceive(mqd_t, char *__restrict, size_t, unsigned *__restrict, const struct timespec *__restrict);
+int mq_timedsend(mqd_t, const char *, size_t, unsigned, const struct timespec *);
+int mq_unlink(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/ethernet.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/ethernet.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/ethernet.h	(revision 398)
@@ -0,0 +1,55 @@
+#ifndef _NET_ETHERNET_H
+#define _NET_ETHERNET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <netinet/if_ether.h>
+
+struct ether_addr {
+	uint8_t ether_addr_octet[ETH_ALEN];
+};
+
+struct ether_header {
+	uint8_t  ether_dhost[ETH_ALEN];
+	uint8_t  ether_shost[ETH_ALEN];
+	uint16_t ether_type;
+};
+
+#define	ETHERTYPE_PUP		0x0200
+#define ETHERTYPE_SPRITE	0x0500
+#define	ETHERTYPE_IP		0x0800
+#define	ETHERTYPE_ARP		0x0806
+#define	ETHERTYPE_REVARP	0x8035
+#define ETHERTYPE_AT		0x809B
+#define ETHERTYPE_AARP		0x80F3
+#define	ETHERTYPE_VLAN		0x8100
+#define ETHERTYPE_IPX		0x8137
+#define	ETHERTYPE_IPV6		0x86dd
+#define ETHERTYPE_LOOPBACK	0x9000
+
+
+#define	ETHER_ADDR_LEN	ETH_ALEN
+#define	ETHER_TYPE_LEN	2
+#define	ETHER_CRC_LEN	4
+#define	ETHER_HDR_LEN	ETH_HLEN
+#define	ETHER_MIN_LEN	(ETH_ZLEN + ETHER_CRC_LEN)
+#define	ETHER_MAX_LEN	(ETH_FRAME_LEN + ETHER_CRC_LEN)
+
+#define	ETHER_IS_VALID_LEN(foo)	\
+	((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+#define	ETHERTYPE_TRAIL		0x1000
+#define	ETHERTYPE_NTRAILER	16
+
+#define	ETHERMTU	ETH_DATA_LEN
+#define	ETHERMIN	(ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/if.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/if.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/if.h	(revision 398)
@@ -0,0 +1,134 @@
+#ifndef _NET_IF_H
+#define _NET_IF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define IF_NAMESIZE 16
+
+struct if_nameindex {
+	unsigned int if_index;
+	char *if_name;
+};
+
+unsigned int if_nametoindex (const char *);
+char *if_indextoname (unsigned int, char *);
+struct if_nameindex *if_nameindex (void);
+void if_freenameindex (struct if_nameindex *);
+
+
+
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#include <sys/socket.h>
+
+#define IFF_UP	0x1
+#define IFF_BROADCAST 0x2
+#define IFF_DEBUG 0x4
+#define IFF_LOOPBACK 0x8
+#define IFF_POINTOPOINT 0x10
+#define IFF_NOTRAILERS 0x20
+#define IFF_RUNNING 0x40
+#define IFF_NOARP 0x80
+#define IFF_PROMISC 0x100
+#define IFF_ALLMULTI 0x200
+#define IFF_MASTER 0x400
+#define IFF_SLAVE 0x800
+#define IFF_MULTICAST 0x1000
+#define IFF_PORTSEL 0x2000
+#define IFF_AUTOMEDIA 0x4000
+#define IFF_DYNAMIC 0x8000
+#define IFF_LOWER_UP 0x10000
+#define IFF_DORMANT 0x20000
+#define IFF_ECHO 0x40000
+#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST| \
+        IFF_ECHO|IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
+
+struct ifaddr {
+	struct sockaddr ifa_addr;
+	union {
+		struct sockaddr	ifu_broadaddr;
+		struct sockaddr	ifu_dstaddr;
+	} ifa_ifu;
+	struct iface *ifa_ifp;
+	struct ifaddr *ifa_next;
+};
+
+#define ifa_broadaddr	ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr	ifa_ifu.ifu_dstaddr
+
+struct ifmap {
+	unsigned long int mem_start;
+	unsigned long int mem_end;
+	unsigned short int base_addr;
+	unsigned char irq;
+	unsigned char dma;
+	unsigned char port;
+};
+
+#define IFHWADDRLEN	6
+#define IFNAMSIZ	IF_NAMESIZE
+
+struct ifreq {
+	union {
+		char ifrn_name[IFNAMSIZ];
+	} ifr_ifrn;
+	union {
+		struct sockaddr ifru_addr;
+		struct sockaddr ifru_dstaddr;
+		struct sockaddr ifru_broadaddr;
+		struct sockaddr ifru_netmask;
+		struct sockaddr ifru_hwaddr;
+		short int ifru_flags;
+		int ifru_ivalue;
+		int ifru_mtu;
+		struct ifmap ifru_map;
+		char ifru_slave[IFNAMSIZ];
+		char ifru_newname[IFNAMSIZ];
+		char *ifru_data;
+	} ifr_ifru;
+};
+
+#define ifr_name	ifr_ifrn.ifrn_name
+#define ifr_hwaddr	ifr_ifru.ifru_hwaddr
+#define ifr_addr	ifr_ifru.ifru_addr
+#define ifr_dstaddr	ifr_ifru.ifru_dstaddr
+#define ifr_broadaddr	ifr_ifru.ifru_broadaddr
+#define ifr_netmask	ifr_ifru.ifru_netmask
+#define ifr_flags	ifr_ifru.ifru_flags
+#define ifr_metric	ifr_ifru.ifru_ivalue
+#define ifr_mtu		ifr_ifru.ifru_mtu
+#define ifr_map		ifr_ifru.ifru_map
+#define ifr_slave	ifr_ifru.ifru_slave
+#define ifr_data	ifr_ifru.ifru_data
+#define ifr_ifindex	ifr_ifru.ifru_ivalue
+#define ifr_bandwidth	ifr_ifru.ifru_ivalue
+#define ifr_qlen	ifr_ifru.ifru_ivalue
+#define ifr_newname	ifr_ifru.ifru_newname
+#define _IOT_ifreq	_IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
+#define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
+#define _IOT_ifreq_int	_IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
+
+struct ifconf {
+	int ifc_len;		
+	union {
+		char *ifcu_buf;
+		struct ifreq *ifcu_req;
+	} ifc_ifcu;
+};
+
+#define ifc_buf		ifc_ifcu.ifcu_buf
+#define ifc_req		ifc_ifcu.ifcu_req
+#define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/if_arp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/if_arp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/if_arp.h	(revision 398)
@@ -0,0 +1,140 @@
+/* Nonstandard header */
+#ifndef _NET_IF_ARP_H
+#define _NET_IF_ARP_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#define MAX_ADDR_LEN	7
+
+#define	ARPOP_REQUEST	1
+#define	ARPOP_REPLY	2
+#define	ARPOP_RREQUEST	3
+#define	ARPOP_RREPLY	4
+#define	ARPOP_InREQUEST	8
+#define	ARPOP_InREPLY	9
+#define	ARPOP_NAK	10
+
+struct arphdr {
+	uint16_t ar_hrd;
+	uint16_t ar_pro;
+	uint8_t ar_hln;
+	uint8_t ar_pln;
+	uint16_t ar_op;
+};
+
+
+#define ARPHRD_NETROM	0
+#define ARPHRD_ETHER 	1
+#define	ARPHRD_EETHER	2
+#define	ARPHRD_AX25	3
+#define	ARPHRD_PRONET	4
+#define	ARPHRD_CHAOS	5
+#define	ARPHRD_IEEE802	6
+#define	ARPHRD_ARCNET	7
+#define	ARPHRD_APPLETLK	8
+#define	ARPHRD_DLCI	15
+#define	ARPHRD_ATM	19
+#define	ARPHRD_METRICOM	23
+#define ARPHRD_IEEE1394	24
+#define ARPHRD_EUI64		27
+#define ARPHRD_INFINIBAND	32
+#define ARPHRD_SLIP	256
+#define ARPHRD_CSLIP	257
+#define ARPHRD_SLIP6	258
+#define ARPHRD_CSLIP6	259
+#define ARPHRD_RSRVD	260
+#define ARPHRD_ADAPT	264
+#define ARPHRD_ROSE	270
+#define ARPHRD_X25	271
+#define ARPHRD_HWX25	272
+#define ARPHRD_CAN	280
+#define ARPHRD_PPP	512
+#define ARPHRD_CISCO	513
+#define ARPHRD_HDLC	ARPHRD_CISCO
+#define ARPHRD_LAPB	516
+#define ARPHRD_DDCMP	517
+#define	ARPHRD_RAWHDLC	518
+
+#define ARPHRD_TUNNEL	768
+#define ARPHRD_TUNNEL6	769
+#define ARPHRD_FRAD	770
+#define ARPHRD_SKIP	771
+#define ARPHRD_LOOPBACK	772
+#define ARPHRD_LOCALTLK 773
+#define ARPHRD_FDDI	774
+#define ARPHRD_BIF	775
+#define ARPHRD_SIT	776
+#define ARPHRD_IPDDP	777
+#define ARPHRD_IPGRE	778
+#define ARPHRD_PIMREG	779
+#define ARPHRD_HIPPI	780
+#define ARPHRD_ASH	781
+#define ARPHRD_ECONET	782
+#define ARPHRD_IRDA	783
+#define ARPHRD_FCPP	784
+#define ARPHRD_FCAL	785
+#define ARPHRD_FCPL	786
+#define ARPHRD_FCFABRIC 787
+#define ARPHRD_IEEE802_TR 800
+#define ARPHRD_IEEE80211 801
+#define ARPHRD_IEEE80211_PRISM 802
+#define ARPHRD_IEEE80211_RADIOTAP 803
+#define ARPHRD_IEEE802154 804
+#define ARPHRD_IEEE802154_MONITOR 805
+#define ARPHRD_PHONET 820
+#define ARPHRD_PHONET_PIPE 821
+#define ARPHRD_CAIF 822
+#define ARPHRD_IP6GRE 823
+#define ARPHRD_NETLINK 824
+#define ARPHRD_6LOWPAN 825
+
+#define ARPHRD_VOID	  0xFFFF
+#define ARPHRD_NONE	  0xFFFE
+
+struct arpreq {
+	struct sockaddr arp_pa;
+	struct sockaddr arp_ha;
+	int arp_flags;
+	struct sockaddr arp_netmask;
+	char arp_dev[16];
+};
+
+struct arpreq_old {
+	struct sockaddr arp_pa;
+	struct sockaddr arp_ha;
+	int arp_flags;
+	struct sockaddr arp_netmask;
+};
+
+#define ATF_COM		0x02
+#define	ATF_PERM	0x04
+#define	ATF_PUBL	0x08
+#define	ATF_USETRAILERS	0x10
+#define ATF_NETMASK     0x20
+#define ATF_DONTPUB	0x40
+#define ATF_MAGIC	0x80
+
+#define ARPD_UPDATE	0x01
+#define ARPD_LOOKUP	0x02
+#define ARPD_FLUSH	0x03
+
+struct arpd_request {
+	unsigned short req;
+	uint32_t ip;
+	unsigned long dev;
+	unsigned long stamp;
+	unsigned long updated;
+	unsigned char ha[MAX_ADDR_LEN];
+};
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/route.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/route.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/net/route.h	(revision 398)
@@ -0,0 +1,124 @@
+#ifndef _NET_ROUTE_H
+#define _NET_ROUTE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+
+struct rtentry {
+	unsigned long int rt_pad1;
+	struct sockaddr rt_dst;
+	struct sockaddr rt_gateway;
+	struct sockaddr rt_genmask;
+	unsigned short int rt_flags;
+	short int rt_pad2;
+	unsigned long int rt_pad3;
+	unsigned char rt_tos;
+	unsigned char rt_class;
+	short int rt_pad4[sizeof(long)/2-1];
+	short int rt_metric;
+	char *rt_dev;
+	unsigned long int rt_mtu;
+	unsigned long int rt_window;
+	unsigned short int rt_irtt;
+};
+
+#define rt_mss	rt_mtu
+
+
+struct in6_rtmsg {
+	struct in6_addr rtmsg_dst;
+	struct in6_addr rtmsg_src;
+	struct in6_addr rtmsg_gateway;
+	uint32_t rtmsg_type;
+	uint16_t rtmsg_dst_len;
+	uint16_t rtmsg_src_len;
+	uint32_t rtmsg_metric;
+	unsigned long int rtmsg_info;
+	uint32_t rtmsg_flags;
+	int rtmsg_ifindex;
+};
+
+
+#define	RTF_UP		0x0001
+#define	RTF_GATEWAY	0x0002
+
+#define	RTF_HOST	0x0004
+#define RTF_REINSTATE	0x0008
+#define	RTF_DYNAMIC	0x0010
+#define	RTF_MODIFIED	0x0020
+#define RTF_MTU		0x0040
+#define RTF_MSS		RTF_MTU
+#define RTF_WINDOW	0x0080
+#define RTF_IRTT	0x0100
+#define RTF_REJECT	0x0200
+#define	RTF_STATIC	0x0400
+#define	RTF_XRESOLVE	0x0800
+#define RTF_NOFORWARD   0x1000
+#define RTF_THROW	0x2000
+#define RTF_NOPMTUDISC  0x4000
+
+#define RTF_DEFAULT	0x00010000
+#define RTF_ALLONLINK	0x00020000
+#define RTF_ADDRCONF	0x00040000
+
+#define RTF_LINKRT	0x00100000
+#define RTF_NONEXTHOP	0x00200000
+
+#define RTF_CACHE	0x01000000
+#define RTF_FLOW	0x02000000
+#define RTF_POLICY	0x04000000
+
+#define RTCF_VALVE	0x00200000
+#define RTCF_MASQ	0x00400000
+#define RTCF_NAT	0x00800000
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_LOG	0x02000000
+#define RTCF_DIRECTSRC	0x04000000
+
+#define RTF_LOCAL	0x80000000
+#define RTF_INTERFACE	0x40000000
+#define RTF_MULTICAST	0x20000000
+#define RTF_BROADCAST	0x10000000
+#define RTF_NAT		0x08000000
+
+#define RTF_ADDRCLASSMASK	0xF8000000
+#define RT_ADDRCLASS(flags)	((uint32_t) flags >> 23)
+
+#define RT_TOS(tos)		((tos) & IPTOS_TOS_MASK)
+
+#define RT_LOCALADDR(flags)	((flags & RTF_ADDRCLASSMASK) \
+				 == (RTF_LOCAL|RTF_INTERFACE))
+
+#define RT_CLASS_UNSPEC		0
+#define RT_CLASS_DEFAULT	253
+
+#define RT_CLASS_MAIN		254
+#define RT_CLASS_LOCAL		255
+#define RT_CLASS_MAX		255
+
+
+#define RTMSG_ACK		NLMSG_ACK
+#define RTMSG_OVERRUN		NLMSG_OVERRUN
+
+#define RTMSG_NEWDEVICE		0x11
+#define RTMSG_DELDEVICE		0x12
+#define RTMSG_NEWROUTE		0x21
+#define RTMSG_DELROUTE		0x22
+#define RTMSG_NEWRULE		0x31
+#define RTMSG_DELRULE		0x32
+#define RTMSG_CONTROL		0x40
+
+#define RTMSG_AR_FAILED		0x51
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netdb.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netdb.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netdb.h	(revision 398)
@@ -0,0 +1,153 @@
+#ifndef	_NETDB_H
+#define	_NETDB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_size_t
+#include <bits/alltypes.h>
+#endif
+
+struct addrinfo {
+	int ai_flags;
+	int ai_family;
+	int ai_socktype;
+	int ai_protocol;
+	socklen_t ai_addrlen;
+	struct sockaddr *ai_addr;
+	char *ai_canonname;
+	struct addrinfo *ai_next;
+};
+
+#define AI_PASSIVE      0x01
+#define AI_CANONNAME    0x02
+#define AI_NUMERICHOST  0x04
+#define AI_V4MAPPED     0x08
+#define AI_ALL          0x10
+#define AI_ADDRCONFIG   0x20
+#define AI_NUMERICSERV  0x400
+
+
+#define NI_NUMERICHOST  0x01
+#define NI_NUMERICSERV  0x02
+#define NI_NOFQDN       0x04
+#define NI_NAMEREQD     0x08
+#define NI_DGRAM        0x10
+#define NI_NUMERICSCOPE 0x100
+
+#define EAI_BADFLAGS   -1
+#define EAI_NONAME     -2
+#define EAI_AGAIN      -3
+#define EAI_FAIL       -4
+#define EAI_FAMILY     -6
+#define EAI_SOCKTYPE   -7
+#define EAI_SERVICE    -8
+#define EAI_MEMORY     -10
+#define EAI_SYSTEM     -11
+#define EAI_OVERFLOW   -12
+
+int getaddrinfo (const char *__restrict, const char *__restrict, const struct addrinfo *__restrict, struct addrinfo **__restrict);
+void freeaddrinfo (struct addrinfo *);
+int getnameinfo (const struct sockaddr *__restrict, socklen_t, char *__restrict, socklen_t, char *__restrict, socklen_t, int);
+const char *gai_strerror(int);
+
+
+/* Legacy functions follow (marked OBsolete in SUS) */
+
+struct netent {
+	char *n_name;
+	char **n_aliases;
+	int n_addrtype;
+	uint32_t n_net;
+};
+
+struct hostent {
+	char *h_name;
+	char **h_aliases;
+	int h_addrtype;
+	int h_length;
+	char **h_addr_list;
+};
+#define h_addr h_addr_list[0]
+
+struct servent {
+	char *s_name;
+	char **s_aliases;
+	int s_port;
+	char *s_proto;
+};
+
+struct protoent {
+	char *p_name;
+	char **p_aliases;
+	int p_proto;
+};
+
+void sethostent (int);
+void endhostent (void);
+struct hostent *gethostent (void);
+
+void setnetent (int);
+void endnetent (void);
+struct netent *getnetent (void);
+struct netent *getnetbyaddr (uint32_t, int);
+struct netent *getnetbyname (const char *);
+
+void setservent (int);
+void endservent (void);
+struct servent *getservent (void);
+struct servent *getservbyname (const char *, const char *);
+struct servent *getservbyport (int, const char *);
+
+void setprotoent (int);
+void endprotoent (void);
+struct protoent *getprotoent (void);
+struct protoent *getprotobyname (const char *);
+struct protoent *getprotobynumber (int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \
+ || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \
+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
+struct hostent *gethostbyname (const char *);
+struct hostent *gethostbyaddr (const void *, socklen_t, int);
+int *__h_errno_location(void);
+#define h_errno (*__h_errno_location())
+#define HOST_NOT_FOUND 1
+#define TRY_AGAIN      2
+#define NO_RECOVERY    3
+#define NO_DATA        4
+#define NO_ADDRESS     NO_DATA
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void herror(const char *);
+const char *hstrerror(int);
+int gethostbyname_r(const char *, struct hostent *, char *, size_t, struct hostent **, int *);
+int gethostbyname2_r(const char *, int, struct hostent *, char *, size_t, struct hostent **, int *);
+struct hostent *gethostbyname2(const char *, int);
+int gethostbyaddr_r(const void *, socklen_t, int, struct hostent *, char *, size_t, struct hostent **, int *);
+int getservbyport_r(int, const char *, struct servent *, char *, size_t, struct servent **);
+int getservbyname_r(const char *, const char *, struct servent *, char *, size_t, struct servent **);
+#define EAI_NODATA     -5
+#define EAI_ADDRFAMILY -9
+#define EAI_INPROGRESS -100
+#define EAI_CANCELED   -101
+#define EAI_NOTCANCELED -102
+#define EAI_ALLDONE    -103
+#define EAI_INTR       -104
+#define EAI_IDN_ENCODE -105
+#define NI_MAXHOST 255
+#define NI_MAXSERV 32
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ether.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ether.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ether.h	(revision 398)
@@ -0,0 +1,22 @@
+#ifndef _NETINET_ETHER_H
+#define _NETINET_ETHER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/if_ether.h>
+
+char *ether_ntoa (const struct ether_addr *);
+struct ether_addr *ether_aton (const char *);
+char *ether_ntoa_r (const struct ether_addr *, char *);
+struct ether_addr *ether_aton_r (const char *, struct ether_addr *);
+int ether_line(const char *, struct ether_addr *, char *);
+int ether_ntohost(char *, const struct ether_addr *);
+int ether_hostton(const char *, struct ether_addr *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/icmp6.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/icmp6.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/icmp6.h	(revision 398)
@@ -0,0 +1,305 @@
+#ifndef _NETINET_ICMP6_H
+#define _NETINET_ICMP6_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#define ICMP6_FILTER 1
+
+#define ICMP6_FILTER_BLOCK		1
+#define ICMP6_FILTER_PASS		2
+#define ICMP6_FILTER_BLOCKOTHERS	3
+#define ICMP6_FILTER_PASSONLY		4
+
+struct icmp6_filter {
+	uint32_t icmp6_filt[8];
+};
+
+struct icmp6_hdr {
+	uint8_t     icmp6_type;
+	uint8_t     icmp6_code;
+	uint16_t    icmp6_cksum;
+	union {
+		uint32_t  icmp6_un_data32[1];
+		uint16_t  icmp6_un_data16[2];
+		uint8_t   icmp6_un_data8[4];
+	} icmp6_dataun;
+};
+
+#define icmp6_data32    icmp6_dataun.icmp6_un_data32
+#define icmp6_data16    icmp6_dataun.icmp6_un_data16
+#define icmp6_data8     icmp6_dataun.icmp6_un_data8
+#define icmp6_pptr      icmp6_data32[0]
+#define icmp6_mtu       icmp6_data32[0]
+#define icmp6_id        icmp6_data16[0]
+#define icmp6_seq       icmp6_data16[1]
+#define icmp6_maxdelay  icmp6_data16[0]
+
+#define ICMP6_DST_UNREACH             1
+#define ICMP6_PACKET_TOO_BIG          2
+#define ICMP6_TIME_EXCEEDED           3
+#define ICMP6_PARAM_PROB              4
+
+#define ICMP6_INFOMSG_MASK  0x80
+
+#define ICMP6_ECHO_REQUEST          128
+#define ICMP6_ECHO_REPLY            129
+#define MLD_LISTENER_QUERY          130
+#define MLD_LISTENER_REPORT         131
+#define MLD_LISTENER_REDUCTION      132
+
+#define ICMP6_DST_UNREACH_NOROUTE     0
+#define ICMP6_DST_UNREACH_ADMIN       1
+#define ICMP6_DST_UNREACH_BEYONDSCOPE 2
+#define ICMP6_DST_UNREACH_ADDR        3
+#define ICMP6_DST_UNREACH_NOPORT      4
+
+#define ICMP6_TIME_EXCEED_TRANSIT     0
+#define ICMP6_TIME_EXCEED_REASSEMBLY  1
+
+#define ICMP6_PARAMPROB_HEADER        0
+#define ICMP6_PARAMPROB_NEXTHEADER    1
+#define ICMP6_PARAMPROB_OPTION        2
+
+#define ICMP6_FILTER_WILLPASS(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
+
+#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
+
+#define ICMP6_FILTER_SETPASS(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))
+
+#define ICMP6_FILTER_SETBLOCK(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) |=  (1 << ((type) & 31))))
+
+#define ICMP6_FILTER_SETPASSALL(filterp) \
+	memset (filterp, 0, sizeof (struct icmp6_filter));
+
+#define ICMP6_FILTER_SETBLOCKALL(filterp) \
+	memset (filterp, 0xFF, sizeof (struct icmp6_filter));
+
+#define ND_ROUTER_SOLICIT           133
+#define ND_ROUTER_ADVERT            134
+#define ND_NEIGHBOR_SOLICIT         135
+#define ND_NEIGHBOR_ADVERT          136
+#define ND_REDIRECT                 137
+
+struct nd_router_solicit {
+	struct icmp6_hdr  nd_rs_hdr;
+};
+
+#define nd_rs_type               nd_rs_hdr.icmp6_type
+#define nd_rs_code               nd_rs_hdr.icmp6_code
+#define nd_rs_cksum              nd_rs_hdr.icmp6_cksum
+#define nd_rs_reserved           nd_rs_hdr.icmp6_data32[0]
+
+struct nd_router_advert {
+	struct icmp6_hdr  nd_ra_hdr;
+	uint32_t   nd_ra_reachable;
+	uint32_t   nd_ra_retransmit;
+};
+
+#define nd_ra_type               nd_ra_hdr.icmp6_type
+#define nd_ra_code               nd_ra_hdr.icmp6_code
+#define nd_ra_cksum              nd_ra_hdr.icmp6_cksum
+#define nd_ra_curhoplimit        nd_ra_hdr.icmp6_data8[0]
+#define nd_ra_flags_reserved     nd_ra_hdr.icmp6_data8[1]
+#define ND_RA_FLAG_MANAGED       0x80
+#define ND_RA_FLAG_OTHER         0x40
+#define ND_RA_FLAG_HOME_AGENT    0x20
+#define nd_ra_router_lifetime    nd_ra_hdr.icmp6_data16[1]
+
+struct nd_neighbor_solicit {
+	struct icmp6_hdr  nd_ns_hdr;
+	struct in6_addr   nd_ns_target;
+};
+
+#define nd_ns_type               nd_ns_hdr.icmp6_type
+#define nd_ns_code               nd_ns_hdr.icmp6_code
+#define nd_ns_cksum              nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved           nd_ns_hdr.icmp6_data32[0]
+
+struct nd_neighbor_advert {
+	struct icmp6_hdr  nd_na_hdr;
+	struct in6_addr   nd_na_target;
+};
+
+#define nd_na_type               nd_na_hdr.icmp6_type
+#define nd_na_code               nd_na_hdr.icmp6_code
+#define nd_na_cksum              nd_na_hdr.icmp6_cksum
+#define nd_na_flags_reserved     nd_na_hdr.icmp6_data32[0]
+#if     __BYTE_ORDER == __BIG_ENDIAN
+#define ND_NA_FLAG_ROUTER        0x80000000
+#define ND_NA_FLAG_SOLICITED     0x40000000
+#define ND_NA_FLAG_OVERRIDE      0x20000000
+#else
+#define ND_NA_FLAG_ROUTER        0x00000080
+#define ND_NA_FLAG_SOLICITED     0x00000040
+#define ND_NA_FLAG_OVERRIDE      0x00000020
+#endif
+
+struct nd_redirect {
+	struct icmp6_hdr  nd_rd_hdr;
+	struct in6_addr   nd_rd_target;
+	struct in6_addr   nd_rd_dst;
+};
+
+#define nd_rd_type               nd_rd_hdr.icmp6_type
+#define nd_rd_code               nd_rd_hdr.icmp6_code
+#define nd_rd_cksum              nd_rd_hdr.icmp6_cksum
+#define nd_rd_reserved           nd_rd_hdr.icmp6_data32[0]
+
+struct nd_opt_hdr {
+	uint8_t  nd_opt_type;
+	uint8_t  nd_opt_len;
+};
+
+#define ND_OPT_SOURCE_LINKADDR		1
+#define ND_OPT_TARGET_LINKADDR		2
+#define ND_OPT_PREFIX_INFORMATION	3
+#define ND_OPT_REDIRECTED_HEADER	4
+#define ND_OPT_MTU			5
+#define ND_OPT_RTR_ADV_INTERVAL		7
+#define ND_OPT_HOME_AGENT_INFO		8
+
+struct nd_opt_prefix_info {
+	uint8_t   nd_opt_pi_type;
+	uint8_t   nd_opt_pi_len;
+	uint8_t   nd_opt_pi_prefix_len;
+	uint8_t   nd_opt_pi_flags_reserved;
+	uint32_t  nd_opt_pi_valid_time;
+	uint32_t  nd_opt_pi_preferred_time;
+	uint32_t  nd_opt_pi_reserved2;
+	struct in6_addr  nd_opt_pi_prefix;
+};
+
+#define ND_OPT_PI_FLAG_ONLINK	0x80
+#define ND_OPT_PI_FLAG_AUTO	0x40
+#define ND_OPT_PI_FLAG_RADDR	0x20
+
+struct nd_opt_rd_hdr {
+	uint8_t   nd_opt_rh_type;
+	uint8_t   nd_opt_rh_len;
+	uint16_t  nd_opt_rh_reserved1;
+	uint32_t  nd_opt_rh_reserved2;
+};
+
+struct nd_opt_mtu {
+	uint8_t   nd_opt_mtu_type;
+	uint8_t   nd_opt_mtu_len;
+	uint16_t  nd_opt_mtu_reserved;
+	uint32_t  nd_opt_mtu_mtu;
+};
+
+struct mld_hdr {
+	struct icmp6_hdr    mld_icmp6_hdr;
+	struct in6_addr     mld_addr;
+};
+
+#define mld_type        mld_icmp6_hdr.icmp6_type
+#define mld_code        mld_icmp6_hdr.icmp6_code
+#define mld_cksum       mld_icmp6_hdr.icmp6_cksum
+#define mld_maxdelay    mld_icmp6_hdr.icmp6_data16[0]
+#define mld_reserved    mld_icmp6_hdr.icmp6_data16[1]
+
+#define ICMP6_ROUTER_RENUMBERING    138
+
+struct icmp6_router_renum {
+	struct icmp6_hdr    rr_hdr;
+	uint8_t             rr_segnum;
+	uint8_t             rr_flags;
+	uint16_t            rr_maxdelay;
+	uint32_t            rr_reserved;
+};
+
+#define rr_type		rr_hdr.icmp6_type
+#define rr_code         rr_hdr.icmp6_code
+#define rr_cksum        rr_hdr.icmp6_cksum
+#define rr_seqnum       rr_hdr.icmp6_data32[0]
+
+#define ICMP6_RR_FLAGS_TEST             0x80
+#define ICMP6_RR_FLAGS_REQRESULT        0x40
+#define ICMP6_RR_FLAGS_FORCEAPPLY       0x20
+#define ICMP6_RR_FLAGS_SPECSITE         0x10
+#define ICMP6_RR_FLAGS_PREVDONE         0x08
+
+struct rr_pco_match {
+	uint8_t             rpm_code;
+	uint8_t             rpm_len;
+	uint8_t             rpm_ordinal;
+	uint8_t             rpm_matchlen;
+	uint8_t             rpm_minlen;
+	uint8_t             rpm_maxlen;
+	uint16_t            rpm_reserved;
+	struct in6_addr     rpm_prefix;
+};
+
+#define RPM_PCO_ADD             1
+#define RPM_PCO_CHANGE          2
+#define RPM_PCO_SETGLOBAL       3
+
+struct rr_pco_use {
+	uint8_t             rpu_uselen;
+	uint8_t             rpu_keeplen;
+	uint8_t             rpu_ramask;
+	uint8_t             rpu_raflags;
+	uint32_t            rpu_vltime;
+	uint32_t            rpu_pltime;
+	uint32_t            rpu_flags;
+	struct in6_addr     rpu_prefix;
+};
+
+#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK  0x20
+#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO    0x10
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
+#else
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
+#endif
+
+struct rr_result {
+	uint16_t            rrr_flags;
+	uint8_t             rrr_ordinal;
+	uint8_t             rrr_matchedlen;
+	uint32_t            rrr_ifid;
+	struct in6_addr     rrr_prefix;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ICMP6_RR_RESULT_FLAGS_OOB       0x0002
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001
+#else
+#define ICMP6_RR_RESULT_FLAGS_OOB       0x0200
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100
+#endif
+
+struct nd_opt_adv_interval {
+	uint8_t   nd_opt_adv_interval_type;
+	uint8_t   nd_opt_adv_interval_len;
+	uint16_t  nd_opt_adv_interval_reserved;
+	uint32_t  nd_opt_adv_interval_ival;
+};
+
+struct nd_opt_home_agent_info {
+	uint8_t   nd_opt_home_agent_info_type;
+	uint8_t   nd_opt_home_agent_info_len;
+	uint16_t  nd_opt_home_agent_info_reserved;
+	uint16_t  nd_opt_home_agent_info_preference;
+	uint16_t  nd_opt_home_agent_info_lifetime;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/if_ether.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/if_ether.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/if_ether.h	(revision 398)
@@ -0,0 +1,134 @@
+#ifndef _NETINET_IF_ETHER_H
+#define _NETINET_IF_ETHER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define ETH_ALEN	6
+#define ETH_HLEN	14
+#define ETH_ZLEN	60
+#define ETH_DATA_LEN	1500
+#define ETH_FRAME_LEN	1514
+#define ETH_FCS_LEN	4
+
+#define ETH_P_LOOP	0x0060
+#define ETH_P_PUP	0x0200
+#define ETH_P_PUPAT	0x0201
+#define ETH_P_TSN	0x22F0
+#define ETH_P_IP	0x0800
+#define ETH_P_X25	0x0805
+#define ETH_P_ARP	0x0806
+#define	ETH_P_BPQ	0x08FF
+#define ETH_P_IEEEPUP	0x0a00
+#define ETH_P_IEEEPUPAT	0x0a01
+#define ETH_P_BATMAN	0x4305
+#define ETH_P_DEC       0x6000
+#define ETH_P_DNA_DL    0x6001
+#define ETH_P_DNA_RC    0x6002
+#define ETH_P_DNA_RT    0x6003
+#define ETH_P_LAT       0x6004
+#define ETH_P_DIAG      0x6005
+#define ETH_P_CUST      0x6006
+#define ETH_P_SCA       0x6007
+#define ETH_P_TEB	0x6558
+#define ETH_P_RARP      0x8035
+#define ETH_P_ATALK	0x809B
+#define ETH_P_AARP	0x80F3
+#define ETH_P_8021Q	0x8100
+#define ETH_P_IPX	0x8137
+#define ETH_P_IPV6	0x86DD
+#define ETH_P_PAUSE	0x8808
+#define ETH_P_SLOW	0x8809
+#define ETH_P_WCCP	0x883E
+#define ETH_P_MPLS_UC	0x8847
+#define ETH_P_MPLS_MC	0x8848
+#define ETH_P_ATMMPOA	0x884c
+#define ETH_P_PPP_DISC	0x8863
+#define ETH_P_PPP_SES	0x8864
+#define ETH_P_LINK_CTL	0x886c
+#define ETH_P_ATMFATE	0x8884
+#define ETH_P_PAE	0x888E
+#define ETH_P_AOE	0x88A2
+#define ETH_P_8021AD	0x88A8
+#define ETH_P_802_EX1	0x88B5
+#define ETH_P_TIPC	0x88CA
+#define ETH_P_MACSEC	0x88E5
+#define ETH_P_8021AH	0x88E7
+#define ETH_P_MVRP	0x88F5
+#define ETH_P_1588	0x88F7
+#define ETH_P_NCSI	0x88F8
+#define ETH_P_PRP	0x88FB
+#define ETH_P_FCOE	0x8906
+#define ETH_P_TDLS	0x890D
+#define ETH_P_FIP	0x8914
+#define ETH_P_80221	0x8917
+#define ETH_P_HSR	0x892F
+#define ETH_P_LOOPBACK	0x9000
+#define ETH_P_QINQ1	0x9100
+#define ETH_P_QINQ2	0x9200
+#define ETH_P_QINQ3	0x9300
+#define ETH_P_EDSA	0xDADA
+#define ETH_P_AF_IUCV	0xFBFB
+
+#define ETH_P_802_3_MIN	0x0600
+
+#define ETH_P_802_3	0x0001
+#define ETH_P_AX25	0x0002
+#define ETH_P_ALL	0x0003
+#define ETH_P_802_2	0x0004
+#define ETH_P_SNAP	0x0005
+#define ETH_P_DDCMP     0x0006
+#define ETH_P_WAN_PPP   0x0007
+#define ETH_P_PPP_MP    0x0008
+#define ETH_P_LOCALTALK 0x0009
+#define ETH_P_CAN	0x000C
+#define ETH_P_CANFD	0x000D
+#define ETH_P_PPPTALK	0x0010
+#define ETH_P_TR_802_2	0x0011
+#define ETH_P_MOBITEX	0x0015
+#define ETH_P_CONTROL	0x0016
+#define ETH_P_IRDA	0x0017
+#define ETH_P_ECONET	0x0018
+#define ETH_P_HDLC	0x0019
+#define ETH_P_ARCNET	0x001A
+#define ETH_P_DSA	0x001B
+#define ETH_P_TRAILER	0x001C
+#define ETH_P_PHONET	0x00F5
+#define ETH_P_IEEE802154 0x00F6
+#define ETH_P_CAIF	0x00F7
+#define ETH_P_XDSA	0x00F8
+
+struct ethhdr {
+	uint8_t h_dest[ETH_ALEN];
+	uint8_t h_source[ETH_ALEN];
+	uint16_t h_proto;
+};
+
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+
+struct	ether_arp {
+	struct	arphdr ea_hdr;
+	uint8_t arp_sha[ETH_ALEN];
+	uint8_t arp_spa[4];
+	uint8_t arp_tha[ETH_ALEN];
+	uint8_t arp_tpa[4];
+};
+#define	arp_hrd	ea_hdr.ar_hrd
+#define	arp_pro	ea_hdr.ar_pro
+#define	arp_hln	ea_hdr.ar_hln
+#define	arp_pln	ea_hdr.ar_pln
+#define	arp_op	ea_hdr.ar_op
+
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
+do { \
+	(enaddr)[0] = 0x01; \
+	(enaddr)[1] = 0x00; \
+	(enaddr)[2] = 0x5e; \
+	(enaddr)[3] = ((uint8_t *)ipaddr)[1] & 0x7f; \
+	(enaddr)[4] = ((uint8_t *)ipaddr)[2]; \
+	(enaddr)[5] = ((uint8_t *)ipaddr)[3]; \
+} while(0)
+
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/igmp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/igmp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/igmp.h	(revision 398)
@@ -0,0 +1,45 @@
+#ifndef _NETINET_IGMP_H
+#define _NETINET_IGMP_H
+
+#include <stdint.h>
+#include <netinet/in.h>
+
+struct igmp {
+	uint8_t igmp_type;
+	uint8_t igmp_code;
+	uint16_t igmp_cksum;
+	struct in_addr igmp_group;
+};
+
+#define IGMP_MINLEN			8
+
+#define IGMP_MEMBERSHIP_QUERY   	0x11
+#define IGMP_V1_MEMBERSHIP_REPORT	0x12
+#define IGMP_V2_MEMBERSHIP_REPORT	0x16
+#define IGMP_V2_LEAVE_GROUP		0x17
+
+#define IGMP_DVMRP			0x13
+#define IGMP_PIM			0x14
+#define IGMP_TRACE			0x15
+
+#define IGMP_MTRACE_RESP		0x1e
+#define IGMP_MTRACE			0x1f
+
+#define IGMP_MAX_HOST_REPORT_DELAY	10
+#define IGMP_TIMER_SCALE		10
+
+#define IGMP_DELAYING_MEMBER	1
+#define IGMP_IDLE_MEMBER	2
+#define IGMP_LAZY_MEMBER	3
+#define IGMP_SLEEPING_MEMBER	4
+#define IGMP_AWAKENING_MEMBER	5
+
+#define IGMP_v1_ROUTER		1
+#define IGMP_v2_ROUTER		2
+
+#define IGMP_HOST_MEMBERSHIP_QUERY	IGMP_MEMBERSHIP_QUERY
+#define IGMP_HOST_MEMBERSHIP_REPORT	IGMP_V1_MEMBERSHIP_REPORT
+#define IGMP_HOST_NEW_MEMBERSHIP_REPORT	IGMP_V2_MEMBERSHIP_REPORT
+#define IGMP_HOST_LEAVE_MESSAGE		IGMP_V2_LEAVE_GROUP
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/in.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/in.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/in.h	(revision 398)
@@ -0,0 +1,409 @@
+#ifndef	_NETINET_IN_H
+#define	_NETINET_IN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+
+typedef uint16_t in_port_t;
+typedef uint32_t in_addr_t;
+struct in_addr { in_addr_t s_addr; };
+
+struct sockaddr_in {
+	sa_family_t sin_family;
+	in_port_t sin_port;
+	struct in_addr sin_addr;
+	uint8_t sin_zero[8];
+};
+
+struct in6_addr {
+	union {
+		uint8_t __s6_addr[16];
+		uint16_t __s6_addr16[8];
+		uint32_t __s6_addr32[4];
+	} __in6_union;
+};
+#define s6_addr __in6_union.__s6_addr
+#define s6_addr16 __in6_union.__s6_addr16
+#define s6_addr32 __in6_union.__s6_addr32
+
+struct sockaddr_in6 {
+	sa_family_t     sin6_family;
+	in_port_t       sin6_port;
+	uint32_t        sin6_flowinfo;
+	struct in6_addr sin6_addr;
+	uint32_t        sin6_scope_id;
+};
+
+struct ipv6_mreq {
+	struct in6_addr ipv6mr_multiaddr;
+	unsigned        ipv6mr_interface;
+};
+
+#define INADDR_ANY        ((in_addr_t) 0x00000000)
+#define INADDR_BROADCAST  ((in_addr_t) 0xffffffff)
+#define INADDR_NONE       ((in_addr_t) 0xffffffff)
+#define INADDR_LOOPBACK   ((in_addr_t) 0x7f000001)
+
+#define INADDR_UNSPEC_GROUP     ((in_addr_t) 0xe0000000)
+#define INADDR_ALLHOSTS_GROUP   ((in_addr_t) 0xe0000001)
+#define INADDR_ALLRTRS_GROUP    ((in_addr_t) 0xe0000002)
+#define INADDR_MAX_LOCAL_GROUP  ((in_addr_t) 0xe00000ff)
+
+#define IN6ADDR_ANY_INIT      { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+
+extern const struct in6_addr in6addr_any, in6addr_loopback;
+
+#undef INET_ADDRSTRLEN
+#undef INET6_ADDRSTRLEN
+#define INET_ADDRSTRLEN  16
+#define INET6_ADDRSTRLEN 46
+
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+
+#define IPPORT_RESERVED 1024
+
+#define IPPROTO_IP       0
+#define IPPROTO_HOPOPTS  0
+#define IPPROTO_ICMP     1
+#define IPPROTO_IGMP     2
+#define IPPROTO_IPIP     4
+#define IPPROTO_TCP      6
+#define IPPROTO_EGP      8
+#define IPPROTO_PUP      12
+#define IPPROTO_UDP      17
+#define IPPROTO_IDP      22
+#define IPPROTO_TP       29
+#define IPPROTO_DCCP     33
+#define IPPROTO_IPV6     41
+#define IPPROTO_ROUTING  43
+#define IPPROTO_FRAGMENT 44
+#define IPPROTO_RSVP     46
+#define IPPROTO_GRE      47
+#define IPPROTO_ESP      50
+#define IPPROTO_AH       51
+#define IPPROTO_ICMPV6   58
+#define IPPROTO_NONE     59
+#define IPPROTO_DSTOPTS  60
+#define IPPROTO_MTP      92
+#define IPPROTO_BEETPH   94
+#define IPPROTO_ENCAP    98
+#define IPPROTO_PIM      103
+#define IPPROTO_COMP     108
+#define IPPROTO_SCTP     132
+#define IPPROTO_MH       135
+#define IPPROTO_UDPLITE  136
+#define IPPROTO_MPLS     137
+#define IPPROTO_RAW      255
+#define IPPROTO_MAX      256
+
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint32_t *) (a))[2] == 0 && ((uint32_t *) (a))[3] == 0)
+
+#define IN6_IS_ADDR_LOOPBACK(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint32_t *) (a))[2] == 0 && \
+         ((uint8_t *) (a))[12] == 0 && ((uint8_t *) (a))[13] == 0 && \
+         ((uint8_t *) (a))[14] == 0 && ((uint8_t *) (a))[15] == 1 )
+
+#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff)
+
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+        ((((uint8_t *) (a))[0]) == 0xfe && (((uint8_t *) (a))[1] & 0xc0) == 0x80)
+
+#define IN6_IS_ADDR_SITELOCAL(a) \
+        ((((uint8_t *) (a))[0]) == 0xfe && (((uint8_t *) (a))[1] & 0xc0) == 0xc0)
+
+#define IN6_IS_ADDR_V4MAPPED(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint8_t *) (a))[8] == 0 && ((uint8_t *) (a))[9] == 0 && \
+         ((uint8_t *) (a))[10] == 0xff && ((uint8_t *) (a))[11] == 0xff)
+
+#define IN6_IS_ADDR_V4COMPAT(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint32_t *) (a))[2] == 0 && ((uint8_t *) (a))[15] > 1)
+
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x1))
+
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x2))
+
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x5))
+
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x8))
+
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0xe))
+
+#define __ARE_4_EQUAL(a,b) \
+	(!( (0[a]-0[b]) | (1[a]-1[b]) | (2[a]-2[b]) | (3[a]-3[b]) ))
+#define IN6_ARE_ADDR_EQUAL(a,b) \
+	__ARE_4_EQUAL((const uint32_t *)(a), (const uint32_t *)(b))
+
+#define	IN_CLASSA(a)		((((in_addr_t)(a)) & 0x80000000) == 0)
+#define	IN_CLASSA_NET		0xff000000
+#define	IN_CLASSA_NSHIFT	24
+#define	IN_CLASSA_HOST		(0xffffffff & ~IN_CLASSA_NET)
+#define	IN_CLASSA_MAX		128
+#define	IN_CLASSB(a)		((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)
+#define	IN_CLASSB_NET		0xffff0000
+#define	IN_CLASSB_NSHIFT	16
+#define	IN_CLASSB_HOST		(0xffffffff & ~IN_CLASSB_NET)
+#define	IN_CLASSB_MAX		65536
+#define	IN_CLASSC(a)		((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)
+#define	IN_CLASSC_NET		0xffffff00
+#define	IN_CLASSC_NSHIFT	8
+#define	IN_CLASSC_HOST		(0xffffffff & ~IN_CLASSC_NET)
+#define	IN_CLASSD(a)		((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)
+#define	IN_MULTICAST(a)		IN_CLASSD(a)
+#define	IN_EXPERIMENTAL(a)	((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000)
+#define	IN_BADCLASS(a)		((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000)
+
+#define IN_LOOPBACKNET 127
+
+
+#define IP_TOS             1
+#define IP_TTL             2
+#define IP_HDRINCL         3
+#define IP_OPTIONS         4
+#define IP_ROUTER_ALERT    5
+#define IP_RECVOPTS        6
+#define IP_RETOPTS         7
+#define IP_PKTINFO         8
+#define IP_PKTOPTIONS      9
+#define IP_PMTUDISC        10
+#define IP_MTU_DISCOVER    10
+#define IP_RECVERR         11
+#define IP_RECVTTL         12
+#define IP_RECVTOS         13
+#define IP_MTU             14
+#define IP_FREEBIND        15
+#define IP_IPSEC_POLICY    16
+#define IP_XFRM_POLICY     17
+#define IP_PASSSEC         18
+#define IP_TRANSPARENT     19
+#define IP_ORIGDSTADDR     20
+#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
+#define IP_MINTTL          21
+#define IP_NODEFRAG        22
+#define IP_CHECKSUM        23
+#define IP_BIND_ADDRESS_NO_PORT 24
+#define IP_MULTICAST_IF    32
+#define IP_MULTICAST_TTL   33
+#define IP_MULTICAST_LOOP  34
+#define IP_ADD_MEMBERSHIP  35
+#define IP_DROP_MEMBERSHIP 36
+#define IP_UNBLOCK_SOURCE  37
+#define IP_BLOCK_SOURCE    38
+#define IP_ADD_SOURCE_MEMBERSHIP  39
+#define IP_DROP_SOURCE_MEMBERSHIP 40
+#define IP_MSFILTER        41
+#define IP_MULTICAST_ALL   49
+#define IP_UNICAST_IF      50
+
+#define IP_RECVRETOPTS IP_RETOPTS
+
+#define IP_PMTUDISC_DONT   0
+#define IP_PMTUDISC_WANT   1
+#define IP_PMTUDISC_DO     2
+#define IP_PMTUDISC_PROBE  3
+#define IP_PMTUDISC_INTERFACE 4
+#define IP_PMTUDISC_OMIT   5
+
+#define IP_DEFAULT_MULTICAST_TTL        1
+#define IP_DEFAULT_MULTICAST_LOOP       1
+#define IP_MAX_MEMBERSHIPS              20
+
+struct ip_opts {
+	struct in_addr ip_dst;
+	char ip_opts[40];
+};
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define MCAST_JOIN_GROUP   42
+#define MCAST_BLOCK_SOURCE 43
+#define MCAST_UNBLOCK_SOURCE      44
+#define MCAST_LEAVE_GROUP  45
+#define MCAST_JOIN_SOURCE_GROUP   46
+#define MCAST_LEAVE_SOURCE_GROUP  47
+#define MCAST_MSFILTER     48
+
+#define MCAST_EXCLUDE 0
+#define MCAST_INCLUDE 1
+
+struct ip_mreq {
+	struct in_addr imr_multiaddr;
+	struct in_addr imr_interface;
+};
+
+struct ip_mreqn {
+	struct in_addr imr_multiaddr;
+	struct in_addr imr_address;
+	int imr_ifindex;
+};
+
+struct ip_mreq_source {
+	struct in_addr imr_multiaddr;
+	struct in_addr imr_interface;
+	struct in_addr imr_sourceaddr;
+};
+
+struct ip_msfilter {
+	struct in_addr imsf_multiaddr;
+	struct in_addr imsf_interface;
+	uint32_t imsf_fmode;
+	uint32_t imsf_numsrc;
+	struct in_addr imsf_slist[1];
+};
+#define IP_MSFILTER_SIZE(numsrc) \
+	(sizeof(struct ip_msfilter) - sizeof(struct in_addr) \
+	+ (numsrc) * sizeof(struct in_addr))
+
+struct group_req {
+	uint32_t gr_interface;
+	struct sockaddr_storage gr_group;
+};
+
+struct group_source_req {
+	uint32_t gsr_interface;
+	struct sockaddr_storage gsr_group;
+	struct sockaddr_storage gsr_source;
+};
+
+struct group_filter {
+	uint32_t gf_interface;
+	struct sockaddr_storage gf_group;
+	uint32_t gf_fmode;
+	uint32_t gf_numsrc;
+	struct sockaddr_storage gf_slist[1];
+};
+#define GROUP_FILTER_SIZE(numsrc) \
+	(sizeof(struct group_filter) - sizeof(struct sockaddr_storage) \
+	+ (numsrc) * sizeof(struct sockaddr_storage))
+
+struct in_pktinfo {
+	int ipi_ifindex;
+	struct in_addr ipi_spec_dst;
+	struct in_addr ipi_addr;
+};
+
+struct in6_pktinfo {
+	struct in6_addr ipi6_addr;
+	unsigned ipi6_ifindex;
+};
+
+struct ip6_mtuinfo {
+	struct sockaddr_in6 ip6m_addr;
+	uint32_t ip6m_mtu;
+};
+#endif
+
+#define IPV6_ADDRFORM           1
+#define IPV6_2292PKTINFO        2
+#define IPV6_2292HOPOPTS        3
+#define IPV6_2292DSTOPTS        4
+#define IPV6_2292RTHDR          5
+#define IPV6_2292PKTOPTIONS     6
+#define IPV6_CHECKSUM           7
+#define IPV6_2292HOPLIMIT       8
+#define IPV6_NEXTHOP            9
+#define IPV6_AUTHHDR            10
+#define IPV6_UNICAST_HOPS       16
+#define IPV6_MULTICAST_IF       17
+#define IPV6_MULTICAST_HOPS     18
+#define IPV6_MULTICAST_LOOP     19
+#define IPV6_JOIN_GROUP         20
+#define IPV6_LEAVE_GROUP        21
+#define IPV6_ROUTER_ALERT       22
+#define IPV6_MTU_DISCOVER       23
+#define IPV6_MTU                24
+#define IPV6_RECVERR            25
+#define IPV6_V6ONLY             26
+#define IPV6_JOIN_ANYCAST       27
+#define IPV6_LEAVE_ANYCAST      28
+#define IPV6_IPSEC_POLICY       34
+#define IPV6_XFRM_POLICY        35
+#define IPV6_HDRINCL            36
+
+#define IPV6_RECVPKTINFO        49
+#define IPV6_PKTINFO            50
+#define IPV6_RECVHOPLIMIT       51
+#define IPV6_HOPLIMIT           52
+#define IPV6_RECVHOPOPTS        53
+#define IPV6_HOPOPTS            54
+#define IPV6_RTHDRDSTOPTS       55
+#define IPV6_RECVRTHDR          56
+#define IPV6_RTHDR              57
+#define IPV6_RECVDSTOPTS        58
+#define IPV6_DSTOPTS            59
+#define IPV6_RECVPATHMTU        60
+#define IPV6_PATHMTU            61
+#define IPV6_DONTFRAG           62
+#define IPV6_RECVTCLASS         66
+#define IPV6_TCLASS             67
+#define IPV6_AUTOFLOWLABEL      70
+#define IPV6_ADDR_PREFERENCES   72
+#define IPV6_MINHOPCOUNT        73
+#define IPV6_ORIGDSTADDR        74
+#define IPV6_RECVORIGDSTADDR    IPV6_ORIGDSTADDR
+#define IPV6_TRANSPARENT        75
+#define IPV6_UNICAST_IF         76
+
+#define IPV6_ADD_MEMBERSHIP     IPV6_JOIN_GROUP
+#define IPV6_DROP_MEMBERSHIP    IPV6_LEAVE_GROUP
+#define IPV6_RXHOPOPTS          IPV6_HOPOPTS
+#define IPV6_RXDSTOPTS          IPV6_DSTOPTS
+
+#define IPV6_PMTUDISC_DONT      0
+#define IPV6_PMTUDISC_WANT      1
+#define IPV6_PMTUDISC_DO        2
+#define IPV6_PMTUDISC_PROBE     3
+#define IPV6_PMTUDISC_INTERFACE 4
+#define IPV6_PMTUDISC_OMIT      5
+
+#define IPV6_PREFER_SRC_TMP            0x0001
+#define IPV6_PREFER_SRC_PUBLIC         0x0002
+#define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100
+#define IPV6_PREFER_SRC_COA            0x0004
+#define IPV6_PREFER_SRC_HOME           0x0400
+#define IPV6_PREFER_SRC_CGA            0x0008
+#define IPV6_PREFER_SRC_NONCGA         0x0800
+
+#define IPV6_RTHDR_LOOSE        0
+#define IPV6_RTHDR_STRICT       1
+
+#define IPV6_RTHDR_TYPE_0       0
+
+#define __UAPI_DEF_IN_ADDR      0
+#define __UAPI_DEF_IN_IPPROTO   0
+#define __UAPI_DEF_IN_PKTINFO   0
+#define __UAPI_DEF_IP_MREQ      0
+#define __UAPI_DEF_SOCKADDR_IN  0
+#define __UAPI_DEF_IN_CLASS     0
+#define __UAPI_DEF_IN6_ADDR     0
+#define __UAPI_DEF_IN6_ADDR_ALT 0
+#define __UAPI_DEF_SOCKADDR_IN6 0
+#define __UAPI_DEF_IPV6_MREQ    0
+#define __UAPI_DEF_IPPROTO_V6   0
+#define __UAPI_DEF_IPV6_OPTIONS 0
+#define __UAPI_DEF_IN6_PKTINFO  0
+#define __UAPI_DEF_IP6_MTUINFO  0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/in_systm.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/in_systm.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/in_systm.h	(revision 398)
@@ -0,0 +1,9 @@
+#ifndef _NETINET_IN_SYSTM_H
+#define _NETINET_IN_SYSTM_H
+
+#include <stdint.h>
+
+typedef uint16_t n_short;
+typedef uint32_t n_long, n_time;
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ip.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ip.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ip.h	(revision 398)
@@ -0,0 +1,198 @@
+#ifndef _NETINET_IP_H
+#define _NETINET_IP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <endian.h>
+
+struct timestamp {
+	uint8_t len;
+	uint8_t ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int flags:4;
+	unsigned int overflow:4;
+#else
+	unsigned int overflow:4;
+	unsigned int flags:4;
+#endif
+	uint32_t data[9];
+  };
+
+struct iphdr {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int ihl:4;
+	unsigned int version:4;
+#else
+	unsigned int version:4;
+	unsigned int ihl:4;
+#endif
+	uint8_t tos;
+	uint16_t tot_len;
+	uint16_t id;
+	uint16_t frag_off;
+	uint8_t ttl;
+	uint8_t protocol;
+	uint16_t check;
+	uint32_t saddr;
+	uint32_t daddr;
+};
+
+struct ip {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int ip_hl:4;
+	unsigned int ip_v:4;
+#else
+	unsigned int ip_v:4;
+	unsigned int ip_hl:4;
+#endif
+	uint8_t ip_tos;
+	uint16_t ip_len;
+	uint16_t ip_id;
+	uint16_t ip_off;
+	uint8_t ip_ttl;
+	uint8_t ip_p;
+	uint16_t ip_sum;
+	struct in_addr ip_src, ip_dst;
+};
+
+#define	IP_RF 0x8000
+#define	IP_DF 0x4000
+#define	IP_MF 0x2000
+#define	IP_OFFMASK 0x1fff
+
+struct ip_timestamp {
+	uint8_t ipt_code;
+	uint8_t ipt_len;
+	uint8_t ipt_ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int ipt_flg:4;
+	unsigned int ipt_oflw:4;
+#else
+	unsigned int ipt_oflw:4;
+	unsigned int ipt_flg:4;
+#endif
+	uint32_t data[9];
+};
+
+#define	IPVERSION	4
+#define	IP_MAXPACKET	65535
+
+#define	IPTOS_ECN_MASK		0x03
+#define	IPTOS_ECN(x)		((x) & IPTOS_ECN_MASK)
+#define	IPTOS_ECN_NOT_ECT	0x00
+#define	IPTOS_ECN_ECT1		0x01
+#define	IPTOS_ECN_ECT0		0x02
+#define	IPTOS_ECN_CE		0x03
+
+#define	IPTOS_DSCP_MASK		0xfc
+#define	IPTOS_DSCP(x)		((x) & IPTOS_DSCP_MASK)
+#define	IPTOS_DSCP_AF11		0x28
+#define	IPTOS_DSCP_AF12		0x30
+#define	IPTOS_DSCP_AF13		0x38
+#define	IPTOS_DSCP_AF21		0x48
+#define	IPTOS_DSCP_AF22		0x50
+#define	IPTOS_DSCP_AF23		0x58
+#define	IPTOS_DSCP_AF31		0x68
+#define	IPTOS_DSCP_AF32		0x70
+#define	IPTOS_DSCP_AF33		0x78
+#define	IPTOS_DSCP_AF41		0x88
+#define	IPTOS_DSCP_AF42		0x90
+#define	IPTOS_DSCP_AF43		0x98
+#define	IPTOS_DSCP_EF		0xb8
+
+#define	IPTOS_CLASS_MASK	0xe0
+#define	IPTOS_CLASS(x)		((x) & IPTOS_CLASS_MASK)
+#define	IPTOS_CLASS_CS0		0x00
+#define	IPTOS_CLASS_CS1		0x20
+#define	IPTOS_CLASS_CS2		0x40
+#define	IPTOS_CLASS_CS3		0x60
+#define	IPTOS_CLASS_CS4		0x80
+#define	IPTOS_CLASS_CS5		0xa0
+#define	IPTOS_CLASS_CS6		0xc0
+#define	IPTOS_CLASS_CS7		0xe0
+#define	IPTOS_CLASS_DEFAULT	IPTOS_CLASS_CS0
+
+#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
+
+#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
+
+#define	IPOPT_COPY		0x80
+#define	IPOPT_CLASS_MASK	0x60
+#define	IPOPT_NUMBER_MASK	0x1f
+
+#define	IPOPT_COPIED(o)		((o) & IPOPT_COPY)
+#define	IPOPT_CLASS(o)		((o) & IPOPT_CLASS_MASK)
+#define	IPOPT_NUMBER(o)		((o) & IPOPT_NUMBER_MASK)
+
+#define	IPOPT_CONTROL		0x00
+#define	IPOPT_RESERVED1		0x20
+#define	IPOPT_DEBMEAS		0x40
+#define	IPOPT_MEASUREMENT       IPOPT_DEBMEAS
+#define	IPOPT_RESERVED2		0x60
+
+#define	IPOPT_EOL		0
+#define	IPOPT_END		IPOPT_EOL
+#define	IPOPT_NOP		1
+#define	IPOPT_NOOP		IPOPT_NOP
+
+#define	IPOPT_RR		7
+#define	IPOPT_TS		68
+#define	IPOPT_TIMESTAMP		IPOPT_TS
+#define	IPOPT_SECURITY		130
+#define	IPOPT_SEC		IPOPT_SECURITY
+#define	IPOPT_LSRR		131
+#define	IPOPT_SATID		136
+#define	IPOPT_SID		IPOPT_SATID
+#define	IPOPT_SSRR		137
+#define	IPOPT_RA		148
+
+#define	IPOPT_OPTVAL		0
+#define	IPOPT_OLEN		1
+#define	IPOPT_OFFSET		2
+#define	IPOPT_MINOFF		4
+
+#define	MAX_IPOPTLEN		40
+
+#define	IPOPT_TS_TSONLY		0
+#define	IPOPT_TS_TSANDADDR	1
+#define	IPOPT_TS_PRESPEC	3
+
+#define	IPOPT_SECUR_UNCLASS	0x0000
+#define	IPOPT_SECUR_CONFID	0xf135
+#define	IPOPT_SECUR_EFTO	0x789a
+#define	IPOPT_SECUR_MMMM	0xbc4d
+#define	IPOPT_SECUR_RESTR	0xaf13
+#define	IPOPT_SECUR_SECRET	0xd788
+#define	IPOPT_SECUR_TOPSECRET	0x6bc5
+
+#define	MAXTTL		255
+#define	IPDEFTTL	64
+#define	IPFRAGTTL	60
+#define	IPTTLDEC	1
+
+#define	IP_MSS		576
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ip6.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ip6.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ip6.h	(revision 398)
@@ -0,0 +1,142 @@
+#ifndef _NETINET_IP6_H
+#define _NETINET_IP6_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <endian.h>
+
+struct ip6_hdr {
+	union {
+		struct ip6_hdrctl {
+			uint32_t ip6_un1_flow;
+			uint16_t ip6_un1_plen;
+			uint8_t  ip6_un1_nxt;
+			uint8_t  ip6_un1_hlim;
+		} ip6_un1;
+		uint8_t ip6_un2_vfc;
+	} ip6_ctlun;
+	struct in6_addr ip6_src;
+	struct in6_addr ip6_dst;
+};
+
+#define ip6_vfc   ip6_ctlun.ip6_un2_vfc
+#define ip6_flow  ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen  ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt   ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim  ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops  ip6_ctlun.ip6_un1.ip6_un1_hlim
+
+struct ip6_ext {
+	uint8_t  ip6e_nxt;
+	uint8_t  ip6e_len;
+};
+
+struct ip6_hbh {
+	uint8_t  ip6h_nxt;
+	uint8_t  ip6h_len;
+};
+
+struct ip6_dest {
+	uint8_t  ip6d_nxt;
+	uint8_t  ip6d_len;
+};
+
+struct ip6_rthdr {
+	uint8_t  ip6r_nxt;
+	uint8_t  ip6r_len;
+	uint8_t  ip6r_type;
+	uint8_t  ip6r_segleft;
+};
+
+struct ip6_rthdr0 {
+	uint8_t  ip6r0_nxt;
+	uint8_t  ip6r0_len;
+	uint8_t  ip6r0_type;
+	uint8_t  ip6r0_segleft;
+	uint8_t  ip6r0_reserved;
+	uint8_t  ip6r0_slmap[3];
+	struct in6_addr ip6r0_addr[];
+};
+
+struct ip6_frag {
+	uint8_t   ip6f_nxt;
+	uint8_t   ip6f_reserved;
+	uint16_t  ip6f_offlg;
+	uint32_t  ip6f_ident;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IP6F_OFF_MASK       0xfff8
+#define IP6F_RESERVED_MASK  0x0006
+#define IP6F_MORE_FRAG      0x0001
+#else
+#define IP6F_OFF_MASK       0xf8ff
+#define IP6F_RESERVED_MASK  0x0600
+#define IP6F_MORE_FRAG      0x0100
+#endif
+
+struct ip6_opt {
+	uint8_t  ip6o_type;
+	uint8_t  ip6o_len;
+};
+
+#define IP6OPT_TYPE(o)		((o) & 0xc0)
+#define IP6OPT_TYPE_SKIP	0x00
+#define IP6OPT_TYPE_DISCARD	0x40
+#define IP6OPT_TYPE_FORCEICMP	0x80
+#define IP6OPT_TYPE_ICMP	0xc0
+#define IP6OPT_TYPE_MUTABLE	0x20
+
+#define IP6OPT_PAD1	0
+#define IP6OPT_PADN	1
+
+#define IP6OPT_JUMBO		0xc2
+#define IP6OPT_NSAP_ADDR	0xc3
+#define IP6OPT_TUNNEL_LIMIT	0x04
+#define IP6OPT_ROUTER_ALERT	0x05
+
+struct ip6_opt_jumbo {
+	uint8_t  ip6oj_type;
+	uint8_t  ip6oj_len;
+	uint8_t  ip6oj_jumbo_len[4];
+};
+#define IP6OPT_JUMBO_LEN	6
+
+struct ip6_opt_nsap {
+	uint8_t  ip6on_type;
+	uint8_t  ip6on_len;
+	uint8_t  ip6on_src_nsap_len;
+	uint8_t  ip6on_dst_nsap_len;
+};
+
+struct ip6_opt_tunnel {
+	uint8_t  ip6ot_type;
+	uint8_t  ip6ot_len;
+	uint8_t  ip6ot_encap_limit;
+};
+
+struct ip6_opt_router {
+	uint8_t  ip6or_type;
+	uint8_t  ip6or_len;
+	uint8_t  ip6or_value[2];
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IP6_ALERT_MLD	0x0000
+#define IP6_ALERT_RSVP	0x0001
+#define IP6_ALERT_AN	0x0002
+#else
+#define IP6_ALERT_MLD	0x0000
+#define IP6_ALERT_RSVP	0x0100
+#define IP6_ALERT_AN	0x0200
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ip_icmp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ip_icmp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/ip_icmp.h	(revision 398)
@@ -0,0 +1,193 @@
+#ifndef _NETINET_IP_ICMP_H
+#define _NETINET_IP_ICMP_H
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct icmphdr {
+	uint8_t type;
+	uint8_t code;
+	uint16_t checksum;
+	union {
+		struct {
+			uint16_t id;
+			uint16_t sequence;
+		} echo;
+		uint32_t gateway;
+		struct {
+			uint16_t __unused;
+			uint16_t mtu;
+		} frag;
+		uint8_t reserved[4];
+	} un;
+};
+
+#define ICMP_ECHOREPLY		0
+#define ICMP_DEST_UNREACH	3
+#define ICMP_SOURCE_QUENCH	4
+#define ICMP_REDIRECT		5
+#define ICMP_ECHO		8
+#define ICMP_TIME_EXCEEDED	11
+#define ICMP_PARAMETERPROB	12
+#define ICMP_TIMESTAMP		13
+#define ICMP_TIMESTAMPREPLY	14
+#define ICMP_INFO_REQUEST	15
+#define ICMP_INFO_REPLY		16
+#define ICMP_ADDRESS		17
+#define ICMP_ADDRESSREPLY	18
+#define NR_ICMP_TYPES		18
+
+
+#define ICMP_NET_UNREACH	0
+#define ICMP_HOST_UNREACH	1
+#define ICMP_PROT_UNREACH	2
+#define ICMP_PORT_UNREACH	3
+#define ICMP_FRAG_NEEDED	4
+#define ICMP_SR_FAILED		5
+#define ICMP_NET_UNKNOWN	6
+#define ICMP_HOST_UNKNOWN	7
+#define ICMP_HOST_ISOLATED	8
+#define ICMP_NET_ANO		9
+#define ICMP_HOST_ANO		10
+#define ICMP_NET_UNR_TOS	11
+#define ICMP_HOST_UNR_TOS	12
+#define ICMP_PKT_FILTERED	13
+#define ICMP_PREC_VIOLATION	14
+#define ICMP_PREC_CUTOFF	15
+#define NR_ICMP_UNREACH		15
+
+#define ICMP_REDIR_NET		0
+#define ICMP_REDIR_HOST		1
+#define ICMP_REDIR_NETTOS	2
+#define ICMP_REDIR_HOSTTOS	3
+
+#define ICMP_EXC_TTL		0
+#define ICMP_EXC_FRAGTIME	1
+
+
+struct icmp_ra_addr {
+	uint32_t ira_addr;
+	uint32_t ira_preference;
+};
+
+struct icmp {
+	uint8_t  icmp_type;
+	uint8_t  icmp_code;
+	uint16_t icmp_cksum;
+	union {
+		uint8_t ih_pptr;
+		struct in_addr ih_gwaddr;
+		struct ih_idseq {
+			uint16_t icd_id;
+			uint16_t icd_seq;
+		} ih_idseq;
+		uint32_t ih_void;
+
+		struct ih_pmtu {
+			uint16_t ipm_void;
+			uint16_t ipm_nextmtu;
+		} ih_pmtu;
+
+		struct ih_rtradv {
+			uint8_t irt_num_addrs;
+			uint8_t irt_wpa;
+			uint16_t irt_lifetime;
+		} ih_rtradv;
+	} icmp_hun;
+	union {
+		struct {
+			uint32_t its_otime;
+			uint32_t its_rtime;
+			uint32_t its_ttime;
+		} id_ts;
+		struct {
+			struct ip idi_ip;
+		} id_ip;
+		struct icmp_ra_addr id_radv;
+		uint32_t   id_mask;
+		uint8_t    id_data[1];
+	} icmp_dun;
+};
+
+#define	icmp_pptr	icmp_hun.ih_pptr
+#define	icmp_gwaddr	icmp_hun.ih_gwaddr
+#define	icmp_id		icmp_hun.ih_idseq.icd_id
+#define	icmp_seq	icmp_hun.ih_idseq.icd_seq
+#define	icmp_void	icmp_hun.ih_void
+#define	icmp_pmvoid	icmp_hun.ih_pmtu.ipm_void
+#define	icmp_nextmtu	icmp_hun.ih_pmtu.ipm_nextmtu
+#define	icmp_num_addrs	icmp_hun.ih_rtradv.irt_num_addrs
+#define	icmp_wpa	icmp_hun.ih_rtradv.irt_wpa
+#define	icmp_lifetime	icmp_hun.ih_rtradv.irt_lifetime
+#define	icmp_otime	icmp_dun.id_ts.its_otime
+#define	icmp_rtime	icmp_dun.id_ts.its_rtime
+#define	icmp_ttime	icmp_dun.id_ts.its_ttime
+#define	icmp_ip		icmp_dun.id_ip.idi_ip
+#define	icmp_radv	icmp_dun.id_radv
+#define	icmp_mask	icmp_dun.id_mask
+#define	icmp_data	icmp_dun.id_data
+
+#define	ICMP_MINLEN	8
+#define	ICMP_TSLEN	(8 + 3 * sizeof (n_time))
+#define	ICMP_MASKLEN	12
+#define	ICMP_ADVLENMIN	(8 + sizeof (struct ip) + 8)
+#define	ICMP_ADVLEN(p)	(8 + ((p)->icmp_ip.ip_hl << 2) + 8)
+
+#define	ICMP_UNREACH		3
+#define	ICMP_SOURCEQUENCH	4
+#define	ICMP_ROUTERADVERT	9
+#define	ICMP_ROUTERSOLICIT	10
+#define	ICMP_TIMXCEED		11
+#define	ICMP_PARAMPROB		12
+#define	ICMP_TSTAMP		13
+#define	ICMP_TSTAMPREPLY	14
+#define	ICMP_IREQ		15
+#define	ICMP_IREQREPLY		16
+#define	ICMP_MASKREQ		17
+#define	ICMP_MASKREPLY		18
+#define	ICMP_MAXTYPE		18
+
+#define	ICMP_UNREACH_NET	        0
+#define	ICMP_UNREACH_HOST	        1
+#define	ICMP_UNREACH_PROTOCOL	        2
+#define	ICMP_UNREACH_PORT	        3
+#define	ICMP_UNREACH_NEEDFRAG	        4
+#define	ICMP_UNREACH_SRCFAIL	        5
+#define	ICMP_UNREACH_NET_UNKNOWN        6
+#define	ICMP_UNREACH_HOST_UNKNOWN       7
+#define	ICMP_UNREACH_ISOLATED	        8
+#define	ICMP_UNREACH_NET_PROHIB	        9
+#define	ICMP_UNREACH_HOST_PROHIB        10
+#define	ICMP_UNREACH_TOSNET	        11
+#define	ICMP_UNREACH_TOSHOST	        12
+#define	ICMP_UNREACH_FILTER_PROHIB      13
+#define	ICMP_UNREACH_HOST_PRECEDENCE    14
+#define	ICMP_UNREACH_PRECEDENCE_CUTOFF  15
+
+#define	ICMP_REDIRECT_NET	0
+#define	ICMP_REDIRECT_HOST	1
+#define	ICMP_REDIRECT_TOSNET	2
+#define	ICMP_REDIRECT_TOSHOST	3
+
+#define	ICMP_TIMXCEED_INTRANS	0
+#define	ICMP_TIMXCEED_REASS	1
+
+#define	ICMP_PARAMPROB_OPTABSENT 1
+
+#define	ICMP_INFOTYPE(type) \
+	((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
+	(type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
+	(type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+	(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
+	(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/tcp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/tcp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/tcp.h	(revision 398)
@@ -0,0 +1,215 @@
+#ifndef _NETINET_TCP_H
+#define _NETINET_TCP_H
+
+#include <features.h>
+
+#define TCP_NODELAY 1
+#define TCP_MAXSEG	 2
+#define TCP_CORK	 3
+#define TCP_KEEPIDLE	 4
+#define TCP_KEEPINTVL	 5
+#define TCP_KEEPCNT	 6
+#define TCP_SYNCNT	 7
+#define TCP_LINGER2	 8
+#define TCP_DEFER_ACCEPT 9
+#define TCP_WINDOW_CLAMP 10
+#define TCP_INFO	 11
+#define	TCP_QUICKACK	 12
+#define TCP_CONGESTION	 13
+#define TCP_MD5SIG	 14
+#define TCP_THIN_LINEAR_TIMEOUTS 16
+#define TCP_THIN_DUPACK  17
+#define TCP_USER_TIMEOUT 18
+#define TCP_REPAIR       19
+#define TCP_REPAIR_QUEUE 20
+#define TCP_QUEUE_SEQ    21
+#define TCP_REPAIR_OPTIONS 22
+#define TCP_FASTOPEN     23
+#define TCP_TIMESTAMP    24
+#define TCP_NOTSENT_LOWAT 25
+#define TCP_CC_INFO      26
+#define TCP_SAVE_SYN     27
+#define TCP_SAVED_SYN    28
+#define TCP_REPAIR_WINDOW 29
+
+#define TCP_ESTABLISHED  1
+#define TCP_SYN_SENT     2
+#define TCP_SYN_RECV     3
+#define TCP_FIN_WAIT1    4
+#define TCP_FIN_WAIT2    5
+#define TCP_TIME_WAIT    6
+#define TCP_CLOSE        7
+#define TCP_CLOSE_WAIT   8
+#define TCP_LAST_ACK     9
+#define TCP_LISTEN       10
+#define TCP_CLOSING      11
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define TCPOPT_EOL              0
+#define TCPOPT_NOP              1
+#define TCPOPT_MAXSEG           2
+#define TCPOPT_WINDOW           3
+#define TCPOPT_SACK_PERMITTED   4
+#define TCPOPT_SACK             5
+#define TCPOPT_TIMESTAMP        8
+#define TCPOLEN_SACK_PERMITTED  2
+#define TCPOLEN_WINDOW          3
+#define TCPOLEN_MAXSEG          4
+#define TCPOLEN_TIMESTAMP       10
+
+#define SOL_TCP 6
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdint.h>
+#include <endian.h>
+
+typedef uint32_t tcp_seq;
+
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+
+struct tcphdr {
+#ifdef _GNU_SOURCE
+#ifdef __GNUC__
+	__extension__
+#endif
+	union { struct {
+
+	uint16_t source;
+	uint16_t dest;
+	uint32_t seq;
+	uint32_t ack_seq;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	uint16_t res1:4;
+	uint16_t doff:4;
+	uint16_t fin:1;
+	uint16_t syn:1;
+	uint16_t rst:1;
+	uint16_t psh:1;
+	uint16_t ack:1;
+	uint16_t urg:1;
+	uint16_t res2:2;
+#else
+	uint16_t doff:4;
+	uint16_t res1:4;
+	uint16_t res2:2;
+	uint16_t urg:1;
+	uint16_t ack:1;
+	uint16_t psh:1;
+	uint16_t rst:1;
+	uint16_t syn:1;
+	uint16_t fin:1;
+#endif
+	uint16_t window;
+	uint16_t check;
+	uint16_t urg_ptr;
+
+	}; struct {
+#endif
+
+	uint16_t th_sport;
+	uint16_t th_dport;
+	uint32_t th_seq;
+	uint32_t th_ack;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	uint8_t th_x2:4;
+	uint8_t th_off:4;
+#else
+	uint8_t th_off:4;
+	uint8_t th_x2:4;
+#endif
+	uint8_t th_flags;
+	uint16_t th_win;
+	uint16_t th_sum;
+	uint16_t th_urp;
+
+#ifdef _GNU_SOURCE
+	}; };
+#endif
+};
+#endif
+
+#ifdef _GNU_SOURCE
+#define TCPI_OPT_TIMESTAMPS	1
+#define TCPI_OPT_SACK		2
+#define TCPI_OPT_WSCALE		4
+#define TCPI_OPT_ECN		8
+
+#define TCP_CA_Open		0
+#define TCP_CA_Disorder		1
+#define TCP_CA_CWR		2
+#define TCP_CA_Recovery		3
+#define TCP_CA_Loss		4
+
+struct tcp_info {
+	uint8_t tcpi_state;
+	uint8_t tcpi_ca_state;
+	uint8_t tcpi_retransmits;
+	uint8_t tcpi_probes;
+	uint8_t tcpi_backoff;
+	uint8_t tcpi_options;
+	uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+	uint8_t tcpi_delivery_rate_app_limited : 1;
+	uint32_t tcpi_rto;
+	uint32_t tcpi_ato;
+	uint32_t tcpi_snd_mss;
+	uint32_t tcpi_rcv_mss;
+	uint32_t tcpi_unacked;
+	uint32_t tcpi_sacked;
+	uint32_t tcpi_lost;
+	uint32_t tcpi_retrans;
+	uint32_t tcpi_fackets;
+	uint32_t tcpi_last_data_sent;
+	uint32_t tcpi_last_ack_sent;
+	uint32_t tcpi_last_data_recv;
+	uint32_t tcpi_last_ack_recv;
+	uint32_t tcpi_pmtu;
+	uint32_t tcpi_rcv_ssthresh;
+	uint32_t tcpi_rtt;
+	uint32_t tcpi_rttvar;
+	uint32_t tcpi_snd_ssthresh;
+	uint32_t tcpi_snd_cwnd;
+	uint32_t tcpi_advmss;
+	uint32_t tcpi_reordering;
+	uint32_t tcpi_rcv_rtt;
+	uint32_t tcpi_rcv_space;
+	uint32_t tcpi_total_retrans;
+	uint64_t tcpi_pacing_rate;
+	uint64_t tcpi_max_pacing_rate;
+	uint64_t tcpi_bytes_acked;
+	uint64_t tcpi_bytes_received;
+	uint32_t tcpi_segs_out;
+	uint32_t tcpi_segs_in;
+	uint32_t tcpi_notsent_bytes;
+	uint32_t tcpi_min_rtt;
+	uint32_t tcpi_data_segs_in;
+	uint32_t tcpi_data_segs_out;
+	uint64_t tcpi_delivery_rate;
+};
+
+#define TCP_MD5SIG_MAXKEYLEN    80
+
+struct tcp_md5sig {
+	struct sockaddr_storage tcpm_addr;
+	uint16_t __tcpm_pad1;
+	uint16_t tcpm_keylen;
+	uint32_t __tcpm_pad2;
+	uint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN];
+};
+
+struct tcp_repair_window {
+	uint32_t snd_wl1;
+	uint32_t snd_wnd;
+	uint32_t max_window;
+	uint32_t rcv_wnd;
+	uint32_t rcv_wup;
+};
+
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/udp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/udp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netinet/udp.h	(revision 398)
@@ -0,0 +1,40 @@
+#ifndef _NETINET_UDP_H
+#define _NETINET_UDP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <stdint.h>
+
+#ifdef _GNU_SOURCE
+#define uh_sport source
+#define uh_dport dest
+#define uh_ulen len
+#define uh_sum check
+#endif
+
+struct udphdr {
+	uint16_t uh_sport;
+	uint16_t uh_dport;
+	uint16_t uh_ulen;
+	uint16_t uh_sum;
+};
+
+#define UDP_CORK	1
+#define UDP_ENCAP	100
+
+#define UDP_ENCAP_ESPINUDP_NON_IKE 1
+#define UDP_ENCAP_ESPINUDP	2
+#define UDP_ENCAP_L2TPINUDP	3
+#define UDP_ENCAP_GTP0		4
+#define UDP_ENCAP_GTP1U		5
+
+#define SOL_UDP            17
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netpacket/packet.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netpacket/packet.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/netpacket/packet.h	(revision 398)
@@ -0,0 +1,61 @@
+#ifndef _NETPACKET_PACKET_H
+#define _NETPACKET_PACKET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct sockaddr_ll {
+	unsigned short sll_family, sll_protocol;
+	int sll_ifindex;
+	unsigned short sll_hatype;
+	unsigned char sll_pkttype, sll_halen;
+	unsigned char sll_addr[8];
+};
+
+struct packet_mreq {
+	int mr_ifindex;
+	unsigned short int mr_type,  mr_alen;
+	unsigned char mr_address[8];
+};
+
+#define PACKET_HOST		0
+#define PACKET_BROADCAST	1
+#define PACKET_MULTICAST	2
+#define PACKET_OTHERHOST	3
+#define PACKET_OUTGOING		4
+#define PACKET_LOOPBACK		5
+#define PACKET_FASTROUTE	6
+
+#define PACKET_ADD_MEMBERSHIP		1
+#define PACKET_DROP_MEMBERSHIP		2
+#define	PACKET_RECV_OUTPUT		3
+#define	PACKET_RX_RING			5
+#define	PACKET_STATISTICS		6
+#define PACKET_COPY_THRESH		7
+#define PACKET_AUXDATA			8
+#define PACKET_ORIGDEV			9
+#define PACKET_VERSION			10
+#define PACKET_HDRLEN			11
+#define PACKET_RESERVE			12
+#define PACKET_TX_RING			13
+#define PACKET_LOSS			14
+#define PACKET_VNET_HDR			15
+#define PACKET_TX_TIMESTAMP		16
+#define PACKET_TIMESTAMP		17
+#define PACKET_FANOUT			18
+#define PACKET_TX_HAS_OFF		19
+#define PACKET_QDISC_BYPASS		20
+#define PACKET_ROLLOVER_STATS		21
+#define PACKET_FANOUT_DATA		22
+
+#define PACKET_MR_MULTICAST	0
+#define PACKET_MR_PROMISC	1
+#define PACKET_MR_ALLMULTI	2
+#define PACKET_MR_UNICAST	3
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/nl_types.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/nl_types.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/nl_types.h	(revision 398)
@@ -0,0 +1,22 @@
+#ifndef _NL_TYPES_H
+#define _NL_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NL_SETD 1
+#define NL_CAT_LOCALE 1
+
+typedef int nl_item;
+typedef void *nl_catd;
+
+nl_catd catopen (const char *, int);
+char *catgets (nl_catd, int, int, const char *);
+int catclose (nl_catd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/paths.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/paths.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/paths.h	(revision 398)
@@ -0,0 +1,31 @@
+#ifndef _PATHS_H
+#define _PATHS_H
+
+#define	_PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
+#define	_PATH_STDPATH "/bin:/usr/bin:/sbin:/usr/sbin"
+
+#define	_PATH_BSHELL	"/bin/sh"
+#define	_PATH_CONSOLE	"/dev/console"
+#define	_PATH_DEVNULL	"/dev/null"
+#define	_PATH_KLOG	"/proc/kmsg"
+#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define	_PATH_MAILDIR	"/var/mail"
+#define	_PATH_MAN	"/usr/share/man"
+#define	_PATH_MNTTAB	"/etc/fstab"
+#define	_PATH_MOUNTED	"/etc/mtab"
+#define	_PATH_NOLOGIN	"/etc/nologin"
+#define	_PATH_SENDMAIL	"/usr/sbin/sendmail"
+#define	_PATH_SHADOW	"/etc/shadow"
+#define	_PATH_SHELLS	"/etc/shells"
+#define	_PATH_TTY	"/dev/tty"
+#define _PATH_UTMP	"/dev/null/utmp"
+#define	_PATH_VI	"/usr/bin/vi"
+#define _PATH_WTMP	"/dev/null/wtmp"
+
+#define	_PATH_DEV	"/dev/"
+#define	_PATH_TMP	"/tmp/"
+#define	_PATH_VARDB	"/var/lib/misc/"
+#define	_PATH_VARRUN	"/var/run/"
+#define	_PATH_VARTMP	"/var/tmp/"
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/poll.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/poll.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/poll.h	(revision 398)
@@ -0,0 +1,51 @@
+#ifndef	_POLL_H
+#define	_POLL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/poll.h>
+
+#define POLLIN     0x001
+#define POLLPRI    0x002
+#define POLLOUT    0x004
+#define POLLERR    0x008
+#define POLLHUP    0x010
+#define POLLNVAL   0x020
+#define POLLRDNORM 0x040
+#define POLLRDBAND 0x080
+#ifndef POLLWRNORM
+#define POLLWRNORM 0x100
+#define POLLWRBAND 0x200
+#endif
+#ifndef POLLMSG
+#define POLLMSG    0x400
+#define POLLRDHUP  0x2000
+#endif
+
+typedef unsigned long nfds_t;
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+int poll (struct pollfd *, nfds_t, int);
+
+#ifdef _GNU_SOURCE
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+#include <bits/alltypes.h>
+int ppoll(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/pthread.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/pthread.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/pthread.h	(revision 398)
@@ -0,0 +1,227 @@
+#ifndef _PTHREAD_H
+#define _PTHREAD_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_time_t
+#define __NEED_clockid_t
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_pthread_mutexattr_t
+#define __NEED_pthread_condattr_t
+#define __NEED_pthread_rwlockattr_t
+#define __NEED_pthread_barrierattr_t
+#define __NEED_pthread_mutex_t
+#define __NEED_pthread_cond_t
+#define __NEED_pthread_rwlock_t
+#define __NEED_pthread_barrier_t
+#define __NEED_pthread_spinlock_t
+#define __NEED_pthread_key_t
+#define __NEED_pthread_once_t
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+#include <sched.h>
+#include <time.h>
+
+#define PTHREAD_CREATE_JOINABLE 0
+#define PTHREAD_CREATE_DETACHED 1
+
+#define PTHREAD_MUTEX_NORMAL 0
+#define PTHREAD_MUTEX_DEFAULT 0
+#define PTHREAD_MUTEX_RECURSIVE 1
+#define PTHREAD_MUTEX_ERRORCHECK 2
+
+#define PTHREAD_MUTEX_STALLED 0
+#define PTHREAD_MUTEX_ROBUST 1
+
+#define PTHREAD_PRIO_NONE 0
+#define PTHREAD_PRIO_INHERIT 1
+#define PTHREAD_PRIO_PROTECT 2
+
+#define PTHREAD_INHERIT_SCHED 0
+#define PTHREAD_EXPLICIT_SCHED 1
+
+#define PTHREAD_SCOPE_SYSTEM 0
+#define PTHREAD_SCOPE_PROCESS 1
+
+#define PTHREAD_PROCESS_PRIVATE 0
+#define PTHREAD_PROCESS_SHARED 1
+
+
+#define PTHREAD_MUTEX_INITIALIZER {{{0}}}
+#define PTHREAD_RWLOCK_INITIALIZER {{{0}}}
+#define PTHREAD_COND_INITIALIZER {{{0}}}
+#define PTHREAD_ONCE_INIT 0
+
+
+#define PTHREAD_CANCEL_ENABLE 0
+#define PTHREAD_CANCEL_DISABLE 1
+#define PTHREAD_CANCEL_MASKED 2
+
+#define PTHREAD_CANCEL_DEFERRED 0
+#define PTHREAD_CANCEL_ASYNCHRONOUS 1
+
+#define PTHREAD_CANCELED ((void *)-1)
+
+
+#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
+
+
+int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, void *(*)(void *), void *__restrict);
+int pthread_detach(pthread_t);
+_Noreturn void pthread_exit(void *);
+int pthread_join(pthread_t, void **);
+
+pthread_t pthread_self(void);
+
+int pthread_equal(pthread_t, pthread_t);
+#ifndef __cplusplus
+#define pthread_equal(x,y) ((x)==(y))
+#endif
+
+int pthread_setcancelstate(int, int *);
+int pthread_setcanceltype(int, int *);
+void pthread_testcancel(void);
+int pthread_cancel(pthread_t);
+
+int pthread_getschedparam(pthread_t, int *__restrict, struct sched_param *__restrict);
+int pthread_setschedparam(pthread_t, int, const struct sched_param *);
+int pthread_setschedprio(pthread_t, int);
+
+int pthread_once(pthread_once_t *, void (*)(void));
+
+int pthread_mutex_init(pthread_mutex_t *__restrict, const pthread_mutexattr_t *__restrict);
+int pthread_mutex_lock(pthread_mutex_t *);
+int pthread_mutex_unlock(pthread_mutex_t *);
+int pthread_mutex_trylock(pthread_mutex_t *);
+int pthread_mutex_timedlock(pthread_mutex_t *__restrict, const struct timespec *__restrict);
+int pthread_mutex_destroy(pthread_mutex_t *);
+int pthread_mutex_consistent(pthread_mutex_t *);
+
+int pthread_mutex_getprioceiling(const pthread_mutex_t *__restrict, int *__restrict);
+int pthread_mutex_setprioceiling(pthread_mutex_t *__restrict, int, int *__restrict);
+
+int pthread_cond_init(pthread_cond_t *__restrict, const pthread_condattr_t *__restrict);
+int pthread_cond_destroy(pthread_cond_t *);
+int pthread_cond_wait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict);
+int pthread_cond_timedwait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict, const struct timespec *__restrict);
+int pthread_cond_broadcast(pthread_cond_t *);
+int pthread_cond_signal(pthread_cond_t *);
+
+int pthread_rwlock_init(pthread_rwlock_t *__restrict, const pthread_rwlockattr_t *__restrict);
+int pthread_rwlock_destroy(pthread_rwlock_t *);
+int pthread_rwlock_rdlock(pthread_rwlock_t *);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);
+int pthread_rwlock_wrlock(pthread_rwlock_t *);
+int pthread_rwlock_trywrlock(pthread_rwlock_t *);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);
+int pthread_rwlock_unlock(pthread_rwlock_t *);
+
+int pthread_spin_init(pthread_spinlock_t *, int);
+int pthread_spin_destroy(pthread_spinlock_t *);
+int pthread_spin_lock(pthread_spinlock_t *);
+int pthread_spin_trylock(pthread_spinlock_t *);
+int pthread_spin_unlock(pthread_spinlock_t *);
+
+int pthread_barrier_init(pthread_barrier_t *__restrict, const pthread_barrierattr_t *__restrict, unsigned);
+int pthread_barrier_destroy(pthread_barrier_t *);
+int pthread_barrier_wait(pthread_barrier_t *);
+
+int pthread_key_create(pthread_key_t *, void (*)(void *));
+int pthread_key_delete(pthread_key_t);
+void *pthread_getspecific(pthread_key_t);
+int pthread_setspecific(pthread_key_t, const void *);
+
+int pthread_attr_init(pthread_attr_t *);
+int pthread_attr_destroy(pthread_attr_t *);
+
+int pthread_attr_getguardsize(const pthread_attr_t *__restrict, size_t *__restrict);
+int pthread_attr_setguardsize(pthread_attr_t *, size_t);
+int pthread_attr_getstacksize(const pthread_attr_t *__restrict, size_t *__restrict);
+int pthread_attr_setstacksize(pthread_attr_t *, size_t);
+int pthread_attr_getdetachstate(const pthread_attr_t *, int *);
+int pthread_attr_setdetachstate(pthread_attr_t *, int);
+int pthread_attr_getstack(const pthread_attr_t *__restrict, void **__restrict, size_t *__restrict);
+int pthread_attr_setstack(pthread_attr_t *, void *, size_t);
+int pthread_attr_getscope(const pthread_attr_t *__restrict, int *__restrict);
+int pthread_attr_setscope(pthread_attr_t *, int);
+int pthread_attr_getschedpolicy(const pthread_attr_t *__restrict, int *__restrict);
+int pthread_attr_setschedpolicy(pthread_attr_t *, int);
+int pthread_attr_getschedparam(const pthread_attr_t *__restrict, struct sched_param *__restrict);
+int pthread_attr_setschedparam(pthread_attr_t *__restrict, const struct sched_param *__restrict);
+int pthread_attr_getinheritsched(const pthread_attr_t *__restrict, int *__restrict);
+int pthread_attr_setinheritsched(pthread_attr_t *, int);
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t *);
+int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *__restrict, int *__restrict);
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *__restrict, int *__restrict);
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t *__restrict, int *__restrict);
+int pthread_mutexattr_getrobust(const pthread_mutexattr_t *__restrict, int *__restrict);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict, int *__restrict);
+int pthread_mutexattr_init(pthread_mutexattr_t *);
+int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
+int pthread_mutexattr_setrobust(pthread_mutexattr_t *, int);
+int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
+
+int pthread_condattr_init(pthread_condattr_t *);
+int pthread_condattr_destroy(pthread_condattr_t *);
+int pthread_condattr_setclock(pthread_condattr_t *, clockid_t);
+int pthread_condattr_setpshared(pthread_condattr_t *, int);
+int pthread_condattr_getclock(const pthread_condattr_t *__restrict, clockid_t *__restrict);
+int pthread_condattr_getpshared(const pthread_condattr_t *__restrict, int *__restrict);
+
+int pthread_rwlockattr_init(pthread_rwlockattr_t *);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *__restrict, int *__restrict);
+
+int pthread_barrierattr_destroy(pthread_barrierattr_t *);
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t *__restrict, int *__restrict);
+int pthread_barrierattr_init(pthread_barrierattr_t *);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
+
+int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
+
+int pthread_getconcurrency(void);
+int pthread_setconcurrency(int);
+
+int pthread_getcpuclockid(pthread_t, clockid_t *);
+
+struct __ptcb {
+	void (*__f)(void *);
+	void *__x;
+	struct __ptcb *__next;
+};
+
+void _pthread_cleanup_push(struct __ptcb *, void (*)(void *), void *);
+void _pthread_cleanup_pop(struct __ptcb *, int);
+
+#define pthread_cleanup_push(f, x) do { struct __ptcb __cb; _pthread_cleanup_push(&__cb, f, x);
+#define pthread_cleanup_pop(r) _pthread_cleanup_pop(&__cb, (r)); } while(0)
+
+#ifdef _GNU_SOURCE
+struct cpu_set_t;
+int pthread_getaffinity_np(pthread_t, size_t, struct cpu_set_t *);
+int pthread_setaffinity_np(pthread_t, size_t, const struct cpu_set_t *);
+int pthread_getattr_np(pthread_t, pthread_attr_t *);
+int pthread_setname_np(pthread_t, const char *);
+int pthread_getattr_default_np(pthread_attr_t *);
+int pthread_setattr_default_np(const pthread_attr_t *);
+int pthread_tryjoin_np(pthread_t, void **);
+int pthread_timedjoin_np(pthread_t, void **, const struct timespec *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/pty.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/pty.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/pty.h	(revision 398)
@@ -0,0 +1,18 @@
+#ifndef	_PTY_H
+#define	_PTY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int openpty(int *, int *, char *, const struct termios *, const struct winsize *);
+int forkpty(int *, char *, const struct termios *, const struct winsize *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/pwd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/pwd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/pwd.h	(revision 398)
@@ -0,0 +1,50 @@
+#ifndef _PWD_H
+#define _PWD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_FILE
+#endif
+
+#include <bits/alltypes.h>
+
+struct passwd {
+	char *pw_name;
+	char *pw_passwd;
+	uid_t pw_uid;
+	gid_t pw_gid;
+	char *pw_gecos;
+	char *pw_dir;
+	char *pw_shell;
+};
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void setpwent (void);
+void endpwent (void);
+struct passwd *getpwent (void);
+#endif
+
+struct passwd *getpwuid (uid_t);
+struct passwd *getpwnam (const char *);
+int getpwuid_r (uid_t, struct passwd *, char *, size_t, struct passwd **);
+int getpwnam_r (const char *, struct passwd *, char *, size_t, struct passwd **);
+
+#ifdef _GNU_SOURCE
+struct passwd *fgetpwent(FILE *);
+int putpwent(const struct passwd *, FILE *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/regex.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/regex.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/regex.h	(revision 398)
@@ -0,0 +1,62 @@
+#ifndef _REGEX_H
+#define _REGEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_regoff_t
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef struct re_pattern_buffer {
+	size_t re_nsub;
+	void *__opaque, *__padding[4];
+	size_t __nsub2;
+	char __padding2;
+} regex_t;
+
+typedef struct {
+	regoff_t rm_so;
+	regoff_t rm_eo;
+} regmatch_t;
+
+#define REG_EXTENDED    1
+#define REG_ICASE       2
+#define REG_NEWLINE     4
+#define REG_NOSUB       8
+
+#define REG_NOTBOL      1
+#define REG_NOTEOL      2
+
+#define REG_OK          0
+#define REG_NOMATCH     1
+#define REG_BADPAT      2
+#define REG_ECOLLATE    3
+#define REG_ECTYPE      4
+#define REG_EESCAPE     5
+#define REG_ESUBREG     6
+#define REG_EBRACK      7
+#define REG_EPAREN      8
+#define REG_EBRACE      9
+#define REG_BADBR       10
+#define REG_ERANGE      11
+#define REG_ESPACE      12
+#define REG_BADRPT      13
+
+#define REG_ENOSYS      -1
+
+int regcomp(regex_t *__restrict, const char *__restrict, int);
+int regexec(const regex_t *__restrict, const char *__restrict, size_t, regmatch_t *__restrict, int);
+void regfree(regex_t *);
+
+size_t regerror(int, const regex_t *__restrict, char *__restrict, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/resolv.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/resolv.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/resolv.h	(revision 398)
@@ -0,0 +1,142 @@
+#ifndef _RESOLV_H
+#define _RESOLV_H
+
+#include <stdint.h>
+#include <arpa/nameser.h>
+#include <netinet/in.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAXNS			3
+#define MAXDFLSRCH		3
+#define MAXDNSRCH		6
+#define LOCALDOMAINPARTS	2
+
+#define RES_TIMEOUT		5
+#define MAXRESOLVSORT		10
+#define RES_MAXNDOTS		15
+#define RES_MAXRETRANS		30
+#define RES_MAXRETRY		5
+#define RES_DFLRETRY		2
+#define RES_MAXTIME		65535
+
+/* unused; purely for broken apps */
+typedef struct __res_state {
+	int retrans;
+	int retry;
+	unsigned long options;
+	int nscount;
+	struct sockaddr_in nsaddr_list[MAXNS];
+# define nsaddr	nsaddr_list[0]
+	unsigned short id;
+	char *dnsrch[MAXDNSRCH+1];
+	char defdname[256];
+	unsigned long pfcode;
+	unsigned ndots:4;
+	unsigned nsort:4;
+	unsigned ipv6_unavail:1;
+	unsigned unused:23;
+	struct {
+		struct in_addr addr;
+		uint32_t mask;
+	} sort_list[MAXRESOLVSORT];
+	void *qhook;
+	void *rhook;
+	int res_h_errno;
+	int _vcsock;
+	unsigned _flags;
+	union {
+		char pad[52];
+		struct {
+			uint16_t		nscount;
+			uint16_t		nsmap[MAXNS];
+			int			nssocks[MAXNS];
+			uint16_t		nscount6;
+			uint16_t		nsinit;
+			struct sockaddr_in6	*nsaddrs[MAXNS];
+			unsigned int		_initstamp[2];
+		} _ext;
+	} _u;
+} *res_state;
+
+#define	__RES	19960801
+
+#ifndef _PATH_RESCONF
+#define _PATH_RESCONF        "/etc/resolv.conf"
+#endif
+
+struct res_sym {
+	int number;
+	char *name;
+	char *humanname;
+};
+
+#define	RES_F_VC	0x00000001
+#define	RES_F_CONN	0x00000002
+#define RES_F_EDNS0ERR	0x00000004
+
+#define	RES_EXHAUSTIVE	0x00000001
+
+#define RES_INIT	0x00000001
+#define RES_DEBUG	0x00000002
+#define RES_AAONLY	0x00000004
+#define RES_USEVC	0x00000008
+#define RES_PRIMARY	0x00000010
+#define RES_IGNTC	0x00000020
+#define RES_RECURSE	0x00000040
+#define RES_DEFNAMES	0x00000080
+#define RES_STAYOPEN	0x00000100
+#define RES_DNSRCH	0x00000200
+#define	RES_INSECURE1	0x00000400
+#define	RES_INSECURE2	0x00000800
+#define	RES_NOALIASES	0x00001000
+#define	RES_USE_INET6	0x00002000
+#define RES_ROTATE	0x00004000
+#define	RES_NOCHECKNAME	0x00008000
+#define	RES_KEEPTSIG	0x00010000
+#define	RES_BLAST	0x00020000
+#define RES_USEBSTRING	0x00040000
+#define RES_NOIP6DOTINT	0x00080000
+#define RES_USE_EDNS0	0x00100000
+#define RES_SNGLKUP	0x00200000
+#define RES_SNGLKUPREOP	0x00400000
+#define RES_USE_DNSSEC	0x00800000
+
+#define RES_DEFAULT	(RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)
+
+#define RES_PRF_STATS	0x00000001
+#define RES_PRF_UPDATE	0x00000002
+#define RES_PRF_CLASS   0x00000004
+#define RES_PRF_CMD	0x00000008
+#define RES_PRF_QUES	0x00000010
+#define RES_PRF_ANS	0x00000020
+#define RES_PRF_AUTH	0x00000040
+#define RES_PRF_ADD	0x00000080
+#define RES_PRF_HEAD1	0x00000100
+#define RES_PRF_HEAD2	0x00000200
+#define RES_PRF_TTLID	0x00000400
+#define RES_PRF_HEADX	0x00000800
+#define RES_PRF_QUERY	0x00001000
+#define RES_PRF_REPLY	0x00002000
+#define RES_PRF_INIT	0x00004000
+
+struct __res_state *__res_state(void);
+#define _res (*__res_state())
+
+int res_init(void);
+int res_query(const char *, int, int, unsigned char *, int);
+int res_querydomain(const char *, const char *, int, int, unsigned char *, int);
+int res_search(const char *, int, int, unsigned char *, int);
+int res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
+int res_send(const unsigned char *, int, unsigned char *, int);
+int dn_comp(const char *, unsigned char *, int, unsigned char **, unsigned char **);
+int dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
+int dn_skipname(const unsigned char *, const unsigned char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sched.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sched.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sched.h	(revision 398)
@@ -0,0 +1,136 @@
+#ifndef _SCHED_H
+#define _SCHED_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_struct_timespec
+#define __NEED_pid_t
+#define __NEED_time_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+struct sched_param {
+	int sched_priority;
+	int sched_ss_low_priority;
+	struct timespec sched_ss_repl_period;
+	struct timespec sched_ss_init_budget;
+	int sched_ss_max_repl;
+};
+
+int    sched_get_priority_max(int);
+int    sched_get_priority_min(int);
+int    sched_getparam(pid_t, struct sched_param *);
+int    sched_getscheduler(pid_t);
+int    sched_rr_get_interval(pid_t, struct timespec *);
+int    sched_setparam(pid_t, const struct sched_param *);
+int    sched_setscheduler(pid_t, int, const struct sched_param *);
+int     sched_yield(void);
+
+#define SCHED_OTHER 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+#define SCHED_IDLE 5
+#define SCHED_DEADLINE 6
+#define SCHED_RESET_ON_FORK 0x40000000
+
+#ifdef _GNU_SOURCE
+#define CSIGNAL		0x000000ff
+#define CLONE_VM	0x00000100
+#define CLONE_FS	0x00000200
+#define CLONE_FILES	0x00000400
+#define CLONE_SIGHAND	0x00000800
+#define CLONE_PTRACE	0x00002000
+#define CLONE_VFORK	0x00004000
+#define CLONE_PARENT	0x00008000
+#define CLONE_THREAD	0x00010000
+#define CLONE_NEWNS	0x00020000
+#define CLONE_SYSVSEM	0x00040000
+#define CLONE_SETTLS	0x00080000
+#define CLONE_PARENT_SETTID	0x00100000
+#define CLONE_CHILD_CLEARTID	0x00200000
+#define CLONE_DETACHED	0x00400000
+#define CLONE_UNTRACED	0x00800000
+#define CLONE_CHILD_SETTID	0x01000000
+#define CLONE_NEWCGROUP	0x02000000
+#define CLONE_NEWUTS	0x04000000
+#define CLONE_NEWIPC	0x08000000
+#define CLONE_NEWUSER	0x10000000
+#define CLONE_NEWPID	0x20000000
+#define CLONE_NEWNET	0x40000000
+#define CLONE_IO	0x80000000
+int clone (int (*)(void *), void *, int, void *, ...);
+int unshare(int);
+int setns(int, int);
+
+void *memcpy(void *__restrict, const void *__restrict, size_t);
+int memcmp(const void *, const void *, size_t);
+void *memset (void *, int, size_t);
+void *calloc(size_t, size_t);
+void free(void *);
+
+typedef struct cpu_set_t { unsigned long __bits[128/sizeof(long)]; } cpu_set_t;
+int __sched_cpucount(size_t, const cpu_set_t *);
+int sched_getcpu(void);
+int sched_getaffinity(pid_t, size_t, cpu_set_t *);
+int sched_setaffinity(pid_t, size_t, const cpu_set_t *);
+
+#define __CPU_op_S(i, size, set, op) ( (i)/8U >= (size) ? 0 : \
+	(((unsigned long *)(set))[(i)/8/sizeof(long)] op (1UL<<((i)%(8*sizeof(long))))) )
+
+#define CPU_SET_S(i, size, set) __CPU_op_S(i, size, set, |=)
+#define CPU_CLR_S(i, size, set) __CPU_op_S(i, size, set, &=~)
+#define CPU_ISSET_S(i, size, set) __CPU_op_S(i, size, set, &)
+
+#define __CPU_op_func_S(func, op) \
+static __inline void __CPU_##func##_S(size_t __size, cpu_set_t *__dest, \
+	const cpu_set_t *__src1, const cpu_set_t *__src2) \
+{ \
+	size_t __i; \
+	for (__i=0; __i<__size/sizeof(long); __i++) \
+		((unsigned long *)__dest)[__i] = ((unsigned long *)__src1)[__i] \
+			op ((unsigned long *)__src2)[__i] ; \
+}
+
+__CPU_op_func_S(AND, &)
+__CPU_op_func_S(OR, |)
+__CPU_op_func_S(XOR, ^)
+
+#define CPU_AND_S(a,b,c,d) __CPU_AND_S(a,b,c,d)
+#define CPU_OR_S(a,b,c,d) __CPU_OR_S(a,b,c,d)
+#define CPU_XOR_S(a,b,c,d) __CPU_XOR_S(a,b,c,d)
+
+#define CPU_COUNT_S(size,set) __sched_cpucount(size,set)
+#define CPU_ZERO_S(size,set) memset(set,0,size)
+#define CPU_EQUAL_S(size,set1,set2) (!memcmp(set1,set2,size))
+
+#define CPU_ALLOC_SIZE(n) (sizeof(long) * ( (n)/(8*sizeof(long)) \
+	+ ((n)%(8*sizeof(long)) + 8*sizeof(long)-1)/(8*sizeof(long)) ) )
+#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
+#define CPU_FREE(set) free(set)
+
+#define CPU_SETSIZE 128
+
+#define CPU_SET(i, set) CPU_SET_S(i,sizeof(cpu_set_t),set)
+#define CPU_CLR(i, set) CPU_CLR_S(i,sizeof(cpu_set_t),set)
+#define CPU_ISSET(i, set) CPU_ISSET_S(i,sizeof(cpu_set_t),set)
+#define CPU_AND(d,s1,s2) CPU_AND_S(sizeof(cpu_set_t),d,s1,s2)
+#define CPU_OR(d,s1,s2) CPU_OR_S(sizeof(cpu_set_t),d,s1,s2)
+#define CPU_XOR(d,s1,s2) CPU_XOR_S(sizeof(cpu_set_t),d,s1,s2)
+#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set)
+#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set)
+#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/scsi/scsi.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/scsi/scsi.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/scsi/scsi.h	(revision 398)
@@ -0,0 +1,150 @@
+#ifndef _SCSI_SCSI_H
+#define _SCSI_SCSI_H
+
+#define TEST_UNIT_READY 0x00
+#define REZERO_UNIT 0x01
+#define REQUEST_SENSE 0x03
+#define FORMAT_UNIT 0x04
+#define READ_BLOCK_LIMITS 0x05
+#define REASSIGN_BLOCKS 0x07
+#define READ_6 0x08
+#define WRITE_6 0x0a
+#define SEEK_6 0x0b
+#define READ_REVERSE 0x0f
+#define WRITE_FILEMARKS 0x10
+#define SPACE 0x11
+#define INQUIRY 0x12
+#define RECOVER_BUFFERED_DATA 0x14
+#define MODE_SELECT 0x15
+#define RESERVE 0x16
+#define RELEASE 0x17
+#define COPY 0x18
+#define ERASE 0x19
+#define MODE_SENSE 0x1a
+#define START_STOP 0x1b
+#define RECEIVE_DIAGNOSTIC 0x1c
+#define SEND_DIAGNOSTIC 0x1d
+#define ALLOW_MEDIUM_REMOVAL 0x1e
+#define SET_WINDOW 0x24
+#define READ_CAPACITY 0x25
+#define READ_10 0x28
+#define WRITE_10 0x2a
+#define SEEK_10 0x2b
+#define WRITE_VERIFY 0x2e
+#define VERIFY 0x2f
+#define SEARCH_HIGH 0x30
+#define SEARCH_EQUAL 0x31
+#define SEARCH_LOW 0x32
+#define SET_LIMITS 0x33
+#define PRE_FETCH 0x34
+#define READ_POSITION 0x34
+#define SYNCHRONIZE_CACHE 0x35
+#define LOCK_UNLOCK_CACHE 0x36
+#define READ_DEFECT_DATA 0x37
+#define MEDIUM_SCAN 0x38
+#define COMPARE 0x39
+#define COPY_VERIFY 0x3a
+#define WRITE_BUFFER 0x3b
+#define READ_BUFFER 0x3c
+#define UPDATE_BLOCK 0x3d
+#define READ_LONG 0x3e
+#define WRITE_LONG 0x3f
+#define CHANGE_DEFINITION 0x40
+#define WRITE_SAME 0x41
+#define READ_TOC 0x43
+#define LOG_SELECT 0x4c
+#define LOG_SENSE 0x4d
+#define MODE_SELECT_10 0x55
+#define RESERVE_10 0x56
+#define RELEASE_10 0x57
+#define MODE_SENSE_10 0x5a
+#define PERSISTENT_RESERVE_IN 0x5e
+#define PERSISTENT_RESERVE_OUT 0x5f
+#define MOVE_MEDIUM 0xa5
+#define READ_12 0xa8
+#define WRITE_12 0xaa
+#define WRITE_VERIFY_12 0xae
+#define SEARCH_HIGH_12 0xb0
+#define SEARCH_EQUAL_12 0xb1
+#define SEARCH_LOW_12 0xb2
+#define READ_ELEMENT_STATUS 0xb8
+#define SEND_VOLUME_TAG 0xb6
+#define WRITE_LONG_2 0xea
+#define GOOD 0x00
+#define CHECK_CONDITION 0x01
+#define CONDITION_GOOD 0x02
+#define BUSY 0x04
+#define INTERMEDIATE_GOOD 0x08
+#define INTERMEDIATE_C_GOOD 0x0a
+#define RESERVATION_CONFLICT 0x0c
+#define COMMAND_TERMINATED 0x11
+#define QUEUE_FULL 0x14
+#define STATUS_MASK 0x3e
+#define NO_SENSE 0x00
+#define RECOVERED_ERROR 0x01
+#define NOT_READY 0x02
+#define MEDIUM_ERROR 0x03
+#define HARDWARE_ERROR 0x04
+#define ILLEGAL_REQUEST 0x05
+#define UNIT_ATTENTION 0x06
+#define DATA_PROTECT 0x07
+#define BLANK_CHECK 0x08
+#define COPY_ABORTED 0x0a
+#define ABORTED_COMMAND 0x0b
+#define VOLUME_OVERFLOW 0x0d
+#define MISCOMPARE 0x0e
+#define TYPE_DISK 0x00
+#define TYPE_TAPE 0x01
+#define TYPE_PROCESSOR 0x03
+#define TYPE_WORM 0x04
+#define TYPE_ROM 0x05
+#define TYPE_SCANNER 0x06
+#define TYPE_MOD 0x07
+#define TYPE_MEDIUM_CHANGER 0x08
+#define TYPE_ENCLOSURE 0x0d
+#define TYPE_NO_LUN 0x7f
+#define COMMAND_COMPLETE 0x00
+#define EXTENDED_MESSAGE 0x01
+#define EXTENDED_MODIFY_DATA_POINTER 0x00
+#define EXTENDED_SDTR 0x01
+#define EXTENDED_EXTENDED_IDENTIFY 0x02
+#define EXTENDED_WDTR 0x03
+#define SAVE_POINTERS 0x02
+#define RESTORE_POINTERS 0x03
+#define DISCONNECT 0x04
+#define INITIATOR_ERROR 0x05
+#define ABORT 0x06
+#define MESSAGE_REJECT 0x07
+#define NOP 0x08
+#define MSG_PARITY_ERROR 0x09
+#define LINKED_CMD_COMPLETE 0x0a
+#define LINKED_FLG_CMD_COMPLETE 0x0b
+#define BUS_DEVICE_RESET 0x0c
+#define INITIATE_RECOVERY 0x0f
+#define RELEASE_RECOVERY 0x10
+#define SIMPLE_QUEUE_TAG 0x20
+#define HEAD_OF_QUEUE_TAG 0x21
+#define ORDERED_QUEUE_TAG 0x22
+#define SCSI_IOCTL_GET_IDLUN 0x5382
+#define SCSI_IOCTL_TAGGED_ENABLE 0x5383
+#define SCSI_IOCTL_TAGGED_DISABLE 0x5384
+#define SCSI_IOCTL_PROBE_HOST 0x5385
+#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386
+
+struct ccs_modesel_head {
+	unsigned char _r1;
+	unsigned char medium;
+	unsigned char _r2;
+	unsigned char block_desc_length;
+	unsigned char density;
+	unsigned char number_blocks_hi;
+	unsigned char number_blocks_med;
+	unsigned char number_blocks_lo;
+	unsigned char _r3;
+	unsigned char block_length_hi;
+	unsigned char block_length_med;
+	unsigned char block_length_lo;
+};
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/scsi/scsi_ioctl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/scsi/scsi_ioctl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/scsi/scsi_ioctl.h	(revision 398)
@@ -0,0 +1,11 @@
+#ifndef _SCSI_IOCTL_H
+#define _SCSI_IOCTL_H
+#define SCSI_IOCTL_SEND_COMMAND 1
+#define SCSI_IOCTL_TEST_UNIT_READY 2
+#define SCSI_IOCTL_BENCHMARK_COMMAND 3
+#define SCSI_IOCTL_SYNC 4
+#define SCSI_IOCTL_START_UNIT 5
+#define SCSI_IOCTL_STOP_UNIT 6
+#define SCSI_IOCTL_DOORLOCK 0x5380
+#define SCSI_IOCTL_DOORUNLOCK 0x5381
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/scsi/sg.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/scsi/sg.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/scsi/sg.h	(revision 398)
@@ -0,0 +1,129 @@
+#ifndef _SCSI_SG_H
+#define _SCSI_SG_H
+
+#define SG_DXFER_NONE -1
+#define SG_DXFER_TO_DEV -2
+#define SG_DXFER_FROM_DEV -3
+#define SG_DXFER_TO_FROM_DEV -4
+#define SG_FLAG_DIRECT_IO 1
+#define SG_FLAG_LUN_INHIBIT 2
+#define SG_FLAG_NO_DXFER 0x10000
+#define SG_INFO_OK_MASK 0x1
+#define SG_INFO_OK 0x0
+#define SG_INFO_CHECK 0x1
+#define SG_INFO_DIRECT_IO_MASK 0x6
+#define SG_INFO_INDIRECT_IO 0x0
+#define SG_INFO_DIRECT_IO 0x2
+#define SG_INFO_MIXED_IO 0x4
+#define SG_EMULATED_HOST 0x2203
+#define SG_SET_TRANSFORM 0x2204
+#define SG_GET_TRANSFORM 0x2205
+#define SG_SET_RESERVED_SIZE 0x2275
+#define SG_GET_RESERVED_SIZE 0x2272
+#define SG_GET_SCSI_ID 0x2276
+#define SG_SET_FORCE_LOW_DMA 0x2279
+#define SG_GET_LOW_DMA 0x227a
+#define SG_SET_FORCE_PACK_ID 0x227b
+#define SG_GET_PACK_ID 0x227c
+#define SG_GET_NUM_WAITING 0x227d
+#define SG_GET_SG_TABLESIZE 0x227F
+#define SG_GET_VERSION_NUM 0x2282
+#define SG_SCSI_RESET 0x2284
+#define SG_SCSI_RESET_NOTHING 0
+#define SG_SCSI_RESET_DEVICE 1
+#define SG_SCSI_RESET_BUS 2
+#define SG_SCSI_RESET_HOST 3
+#define SG_IO 0x2285
+#define SG_GET_REQUEST_TABLE 0x2286
+#define SG_SET_KEEP_ORPHAN 0x2287
+#define SG_GET_KEEP_ORPHAN 0x2288
+#define SG_SCATTER_SZ (8 * 4096)
+#define SG_DEFAULT_RETRIES 1
+#define SG_DEF_FORCE_LOW_DMA 0
+#define SG_DEF_FORCE_PACK_ID 0
+#define SG_DEF_KEEP_ORPHAN 0
+#define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ
+#define SG_MAX_QUEUE 16
+#define SG_BIG_BUFF SG_DEF_RESERVED_SIZE
+#define SG_MAX_SENSE 16
+#define SG_SET_TIMEOUT 0x2201
+#define SG_GET_TIMEOUT 0x2202
+#define SG_GET_COMMAND_Q 0x2270
+#define SG_SET_COMMAND_Q 0x2271
+#define SG_SET_DEBUG 0x227e
+#define SG_NEXT_CMD_LEN 0x2283
+#define SG_DEFAULT_TIMEOUT (60*100) /* 60*HZ */
+#define SG_DEF_COMMAND_Q 0
+#define SG_DEF_UNDERRUN_FLAG 0
+
+typedef struct sg_iovec {
+	void *iov_base;
+	unsigned long iov_len;
+} sg_iovec_t;
+
+typedef struct sg_io_hdr { 
+	int interface_id; 
+	int dxfer_direction; 
+	unsigned char cmd_len;
+	unsigned char mx_sb_len;
+	unsigned short iovec_count;
+	unsigned dxfer_len;
+	void *dxferp;
+	unsigned char *cmdp;
+	unsigned char *sbp;
+	unsigned timeout;
+	unsigned flags;
+	int pack_id;
+	void *usr_ptr;
+	unsigned char status;
+	unsigned char masked_status;
+	unsigned char msg_status;
+	unsigned char sb_len_wr;
+	unsigned short host_status;
+	unsigned short driver_status;
+	int resid; 
+	unsigned int duration;
+	unsigned int info;
+} sg_io_hdr_t;
+
+struct sg_scsi_id {
+	int host_no;
+	int channel;
+	int scsi_id;
+	int lun;
+	int scsi_type;
+	short h_cmd_per_lun;
+	short d_queue_depth;
+	int unused[2];
+};
+
+typedef struct sg_req_info {
+	char req_state;
+	char orphan;
+	char sg_io_owned;
+	char problem;
+	int pack_id;
+	void *usr_ptr;
+	unsigned duration; 
+	int unused; 
+} sg_req_info_t;
+
+typedef struct sg_io_hdr Sg_io_hdr;
+typedef struct sg_io_vec Sg_io_vec;
+typedef struct sg_scsi_id Sg_scsi_id;
+typedef struct sg_req_info Sg_req_info;
+
+struct sg_header {
+	int pack_len;
+	int reply_len;
+	int pack_id;
+	int result;
+	unsigned twelve_byte:1;
+	unsigned target_status:5;
+	unsigned host_status:8;
+	unsigned driver_status:8;
+	unsigned other_flags:10;
+	unsigned char sense_buffer[SG_MAX_SENSE];
+};
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/search.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/search.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/search.h	(revision 398)
@@ -0,0 +1,63 @@
+#ifndef _SEARCH_H
+#define _SEARCH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+typedef enum { FIND, ENTER } ACTION;
+typedef enum { preorder, postorder, endorder, leaf } VISIT;
+
+typedef struct entry {
+	char *key;
+	void *data;
+} ENTRY;
+
+int hcreate(size_t);
+void hdestroy(void);
+ENTRY *hsearch(ENTRY, ACTION);
+
+#ifdef _GNU_SOURCE
+struct hsearch_data {
+	struct __tab *__tab;
+	unsigned int __unused1;
+	unsigned int __unused2;
+};
+
+int hcreate_r(size_t, struct hsearch_data *);
+void hdestroy_r(struct hsearch_data *);
+int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
+#endif
+
+void insque(void *, void *);
+void remque(void *);
+
+void *lsearch(const void *, void *, size_t *, size_t,
+	int (*)(const void *, const void *));
+void *lfind(const void *, const void *, size_t *, size_t,
+	int (*)(const void *, const void *));
+
+void *tdelete(const void *__restrict, void **__restrict, int(*)(const void *, const void *));
+void *tfind(const void *, void *const *, int(*)(const void *, const void *));
+void *tsearch(const void *, void **, int (*)(const void *, const void *));
+void twalk(const void *, void (*)(const void *, VISIT, int));
+
+#ifdef _GNU_SOURCE
+struct qelem {
+	struct qelem *q_forw, *q_back;
+	char q_data[1];
+};
+
+void tdestroy(void *, void (*)(void *));
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/semaphore.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/semaphore.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/semaphore.h	(revision 398)
@@ -0,0 +1,35 @@
+#ifndef _SEMAPHORE_H
+#define _SEMAPHORE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#include <bits/alltypes.h>
+
+#include <fcntl.h>
+
+#define SEM_FAILED ((sem_t *)0)
+
+typedef struct {
+	volatile int __val[4*sizeof(long)/sizeof(int)];
+} sem_t;
+
+int    sem_close(sem_t *);
+int    sem_destroy(sem_t *);
+int    sem_getvalue(sem_t *__restrict, int *__restrict);
+int    sem_init(sem_t *, int, unsigned);
+sem_t *sem_open(const char *, int, ...);
+int    sem_post(sem_t *);
+int    sem_timedwait(sem_t *__restrict, const struct timespec *__restrict);
+int    sem_trywait(sem_t *);
+int    sem_unlink(const char *);
+int    sem_wait(sem_t *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/setjmp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/setjmp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/setjmp.h	(revision 398)
@@ -0,0 +1,41 @@
+#ifndef	_SETJMP_H
+#define	_SETJMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/setjmp.h>
+
+typedef struct __jmp_buf_tag {
+	__jmp_buf __jb;
+	unsigned long __fl;
+	unsigned long __ss[128/sizeof(long)];
+} jmp_buf[1];
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+typedef jmp_buf sigjmp_buf;
+int sigsetjmp (sigjmp_buf, int);
+_Noreturn void siglongjmp (sigjmp_buf, int);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+int _setjmp (jmp_buf);
+_Noreturn void _longjmp (jmp_buf, int);
+#endif
+
+int setjmp (jmp_buf);
+_Noreturn void longjmp (jmp_buf, int);
+
+#define setjmp setjmp
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/shadow.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/shadow.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/shadow.h	(revision 398)
@@ -0,0 +1,44 @@
+#ifndef _SHADOW_H
+#define _SHADOW_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	__NEED_FILE
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+#define	SHADOW "/etc/shadow"
+
+struct spwd {
+	char *sp_namp;
+	char *sp_pwdp;
+	long sp_lstchg;
+	long sp_min;
+	long sp_max;
+	long sp_warn;
+	long sp_inact;
+	long sp_expire;
+	unsigned long sp_flag;
+};
+
+void setspent(void);
+void endspent(void);
+struct spwd *getspent(void);
+struct spwd *fgetspent(FILE *);
+struct spwd *sgetspent(const char *);
+int putspent(const struct spwd *, FILE *);
+
+struct spwd *getspnam(const char *);
+int getspnam_r(const char *, struct spwd *, char *, size_t, struct spwd **);
+
+int lckpwdf(void);
+int ulckpwdf(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/signal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/signal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/signal.h	(revision 398)
@@ -0,0 +1,275 @@
+#ifndef _SIGNAL_H
+#define _SIGNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#ifdef _GNU_SOURCE
+#define __ucontext ucontext
+#endif
+
+#define __NEED_size_t
+#define __NEED_pid_t
+#define __NEED_uid_t
+#define __NEED_struct_timespec
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_time_t
+#define __NEED_clock_t
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define SIG_BLOCK     0
+#define SIG_UNBLOCK   1
+#define SIG_SETMASK   2
+
+#define SI_ASYNCNL (-60)
+#define SI_TKILL (-6)
+#define SI_SIGIO (-5)
+#define SI_ASYNCIO (-4)
+#define SI_MESGQ (-3)
+#define SI_TIMER (-2)
+#define SI_QUEUE (-1)
+#define SI_USER 0
+#define SI_KERNEL 128
+
+typedef struct sigaltstack stack_t;
+
+#endif
+
+#include <bits/signal.h>
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#define SIG_HOLD ((void (*)(int)) 2)
+
+#define FPE_INTDIV 1
+#define FPE_INTOVF 2
+#define FPE_FLTDIV 3
+#define FPE_FLTOVF 4
+#define FPE_FLTUND 5
+#define FPE_FLTRES 6
+#define FPE_FLTINV 7
+#define FPE_FLTSUB 8
+
+#define ILL_ILLOPC 1
+#define ILL_ILLOPN 2
+#define ILL_ILLADR 3
+#define ILL_ILLTRP 4
+#define ILL_PRVOPC 5
+#define ILL_PRVREG 6
+#define ILL_COPROC 7
+#define ILL_BADSTK 8
+
+#define SEGV_MAPERR 1
+#define SEGV_ACCERR 2
+#define SEGV_BNDERR 3
+#define SEGV_PKUERR 4
+
+#define BUS_ADRALN 1
+#define BUS_ADRERR 2
+#define BUS_OBJERR 3
+#define BUS_MCEERR_AR 4
+#define BUS_MCEERR_AO 5
+
+#define CLD_EXITED 1
+#define CLD_KILLED 2
+#define CLD_DUMPED 3
+#define CLD_TRAPPED 4
+#define CLD_STOPPED 5
+#define CLD_CONTINUED 6
+
+union sigval {
+	int sival_int;
+	void *sival_ptr;
+};
+
+typedef struct {
+#ifdef __SI_SWAP_ERRNO_CODE
+	int si_signo, si_code, si_errno;
+#else
+	int si_signo, si_errno, si_code;
+#endif
+	union {
+		char __pad[128 - 2*sizeof(int) - sizeof(long)];
+		struct {
+			union {
+				struct {
+					pid_t si_pid;
+					uid_t si_uid;
+				} __piduid;
+				struct {
+					int si_timerid;
+					int si_overrun;
+				} __timer;
+			} __first;
+			union {
+				union sigval si_value;
+				struct {
+					int si_status;
+					clock_t si_utime, si_stime;
+				} __sigchld;
+			} __second;
+		} __si_common;
+		struct {
+			void *si_addr;
+			short si_addr_lsb;
+			union {
+				struct {
+					void *si_lower;
+					void *si_upper;
+				} __addr_bnd;
+				unsigned si_pkey;
+			} __first;
+		} __sigfault;
+		struct {
+			long si_band;
+			int si_fd;
+		} __sigpoll;
+		struct {
+			void *si_call_addr;
+			int si_syscall;
+			unsigned si_arch;
+		} __sigsys;
+	} __si_fields;
+} siginfo_t;
+#define si_pid     __si_fields.__si_common.__first.__piduid.si_pid
+#define si_uid     __si_fields.__si_common.__first.__piduid.si_uid
+#define si_status  __si_fields.__si_common.__second.__sigchld.si_status
+#define si_utime   __si_fields.__si_common.__second.__sigchld.si_utime
+#define si_stime   __si_fields.__si_common.__second.__sigchld.si_stime
+#define si_value   __si_fields.__si_common.__second.si_value
+#define si_addr    __si_fields.__sigfault.si_addr
+#define si_addr_lsb __si_fields.__sigfault.si_addr_lsb
+#define si_lower   __si_fields.__sigfault.__first.__addr_bnd.si_lower
+#define si_upper   __si_fields.__sigfault.__first.__addr_bnd.si_upper
+#define si_pkey    __si_fields.__sigfault.__first.si_pkey
+#define si_band    __si_fields.__sigpoll.si_band
+#define si_fd      __si_fields.__sigpoll.si_fd
+#define si_timerid __si_fields.__si_common.__first.__timer.si_timerid
+#define si_overrun __si_fields.__si_common.__first.__timer.si_overrun
+#define si_ptr     si_value.sival_ptr
+#define si_int     si_value.sival_int
+#define si_call_addr __si_fields.__sigsys.si_call_addr
+#define si_syscall __si_fields.__sigsys.si_syscall
+#define si_arch    __si_fields.__sigsys.si_arch
+
+struct sigaction {
+	union {
+		void (*sa_handler)(int);
+		void (*sa_sigaction)(int, siginfo_t *, void *);
+	} __sa_handler;
+	sigset_t sa_mask;
+	int sa_flags;
+	void (*sa_restorer)(void);
+};
+#define sa_handler   __sa_handler.sa_handler
+#define sa_sigaction __sa_handler.sa_sigaction
+
+struct sigevent {
+	union sigval sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	void (*sigev_notify_function)(union sigval);
+	pthread_attr_t *sigev_notify_attributes;
+	char __pad[56-3*sizeof(long)];
+};
+
+#define SIGEV_SIGNAL 0
+#define SIGEV_NONE 1
+#define SIGEV_THREAD 2
+
+int __libc_current_sigrtmin(void);
+int __libc_current_sigrtmax(void);
+
+#define SIGRTMIN  (__libc_current_sigrtmin())
+#define SIGRTMAX  (__libc_current_sigrtmax())
+
+int kill(pid_t, int);
+
+int sigemptyset(sigset_t *);
+int sigfillset(sigset_t *);
+int sigaddset(sigset_t *, int);
+int sigdelset(sigset_t *, int);
+int sigismember(const sigset_t *, int);
+
+int sigprocmask(int, const sigset_t *__restrict, sigset_t *__restrict);
+int sigsuspend(const sigset_t *);
+int sigaction(int, const struct sigaction *__restrict, struct sigaction *__restrict);
+int sigpending(sigset_t *);
+int sigwait(const sigset_t *__restrict, int *__restrict);
+int sigwaitinfo(const sigset_t *__restrict, siginfo_t *__restrict);
+int sigtimedwait(const sigset_t *__restrict, siginfo_t *__restrict, const struct timespec *__restrict);
+int sigqueue(pid_t, int, const union sigval);
+
+int pthread_sigmask(int, const sigset_t *__restrict, sigset_t *__restrict);
+int pthread_kill(pthread_t, int);
+
+void psiginfo(const siginfo_t *, const char *);
+void psignal(int, const char *);
+
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+int killpg(pid_t, int);
+int sigaltstack(const stack_t *__restrict, stack_t *__restrict);
+int sighold(int);
+int sigignore(int);
+int siginterrupt(int, int);
+int sigpause(int);
+int sigrelse(int);
+void (*sigset(int, void (*)(int)))(int);
+#define TRAP_BRKPT 1
+#define TRAP_TRACE 2
+#define POLL_IN 1
+#define POLL_OUT 2
+#define POLL_MSG 3
+#define POLL_ERR 4
+#define POLL_PRI 5
+#define POLL_HUP 6
+#define SS_ONSTACK    1
+#define SS_DISABLE    2
+#define SS_AUTODISARM (1U << 31)
+#define SS_FLAG_BITS SS_AUTODISARM
+#endif
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define NSIG _NSIG
+typedef void (*sig_t)(int);
+#endif
+
+#ifdef _GNU_SOURCE
+typedef void (*sighandler_t)(int);
+void (*bsd_signal(int, void (*)(int)))(int);
+int sigisemptyset(const sigset_t *);
+int sigorset (sigset_t *, const sigset_t *, const sigset_t *);
+int sigandset(sigset_t *, const sigset_t *, const sigset_t *);
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+#endif
+
+#define SIG_ERR  ((void (*)(int))-1)
+#define SIG_DFL  ((void (*)(int)) 0)
+#define SIG_IGN  ((void (*)(int)) 1)
+
+typedef int sig_atomic_t;
+
+void (*signal(int, void (*)(int)))(int);
+int raise(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/spawn.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/spawn.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/spawn.h	(revision 398)
@@ -0,0 +1,76 @@
+#ifndef _SPAWN_H
+#define _SPAWN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_mode_t
+#define __NEED_pid_t
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+struct sched_param;
+
+#define POSIX_SPAWN_RESETIDS 1
+#define POSIX_SPAWN_SETPGROUP 2
+#define POSIX_SPAWN_SETSIGDEF 4
+#define POSIX_SPAWN_SETSIGMASK 8
+#define POSIX_SPAWN_SETSCHEDPARAM 16
+#define POSIX_SPAWN_SETSCHEDULER 32
+#define POSIX_SPAWN_USEVFORK 64
+#define POSIX_SPAWN_SETSID 128
+
+typedef struct {
+	int __flags;
+	pid_t __pgrp;
+	sigset_t __def, __mask;
+	int __prio, __pol, __pad[16];
+} posix_spawnattr_t;
+
+typedef struct {
+	int __pad0[2];
+	void *__actions;
+	int __pad[16];
+} posix_spawn_file_actions_t;
+
+int posix_spawn(pid_t *__restrict, const char *__restrict, const posix_spawn_file_actions_t *,
+	const posix_spawnattr_t *__restrict, char *const *__restrict, char *const *__restrict);
+int posix_spawnp(pid_t *__restrict, const char *__restrict, const posix_spawn_file_actions_t *,
+	const posix_spawnattr_t *__restrict, char *const *__restrict, char *const *__restrict);
+
+int posix_spawnattr_init(posix_spawnattr_t *);
+int posix_spawnattr_destroy(posix_spawnattr_t *);
+
+int posix_spawnattr_setflags(posix_spawnattr_t *, short);
+int posix_spawnattr_getflags(const posix_spawnattr_t *__restrict, short *__restrict);
+
+int posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t);
+int posix_spawnattr_getpgroup(const posix_spawnattr_t *__restrict, pid_t *__restrict);
+
+int posix_spawnattr_setsigmask(posix_spawnattr_t *__restrict, const sigset_t *__restrict);
+int posix_spawnattr_getsigmask(const posix_spawnattr_t *__restrict, sigset_t *__restrict);
+
+int posix_spawnattr_setsigdefault(posix_spawnattr_t *__restrict, const sigset_t *__restrict);
+int posix_spawnattr_getsigdefault(const posix_spawnattr_t *__restrict, sigset_t *__restrict);
+
+int posix_spawnattr_setschedparam(posix_spawnattr_t *__restrict, const struct sched_param *__restrict);
+int posix_spawnattr_getschedparam(const posix_spawnattr_t *__restrict, struct sched_param *__restrict);
+int posix_spawnattr_setschedpolicy(posix_spawnattr_t *, int);
+int posix_spawnattr_getschedpolicy(const posix_spawnattr_t *__restrict, int *__restrict);
+
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t *);
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *);
+
+int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *__restrict, int, const char *__restrict, int, mode_t);
+int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int);
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdalign.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdalign.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdalign.h	(revision 398)
@@ -0,0 +1,20 @@
+#ifndef _STDALIGN_H
+#define _STDALIGN_H
+
+#ifndef __cplusplus
+
+/* this whole header only works in C11 or with compiler extensions */
+#if __STDC_VERSION__ < 201112L && defined( __GNUC__)
+#define _Alignas(t) __attribute__((__aligned__(t)))
+#define _Alignof(t) __alignof__(t)
+#endif
+
+#define alignas _Alignas
+#define alignof _Alignof
+
+#endif
+
+#define __alignas_is_defined 1
+#define __alignof_is_defined 1
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdarg.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdarg.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdarg.h	(revision 398)
@@ -0,0 +1,21 @@
+#ifndef _STDARG_H
+#define _STDARG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_va_list
+
+#include <bits/alltypes.h>
+
+#define va_start(v,l)   __builtin_va_start(v,l)
+#define va_end(v)       __builtin_va_end(v)
+#define va_arg(v,l)     __builtin_va_arg(v,l)
+#define va_copy(d,s)    __builtin_va_copy(d,s)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdbool.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdbool.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdbool.h	(revision 398)
@@ -0,0 +1,14 @@
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+#ifndef __cplusplus
+
+#define true 1
+#define false 0
+#define bool _Bool
+
+#endif
+
+#define __bool_true_false_are_defined 1
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdc-predef.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdc-predef.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdc-predef.h	(revision 398)
@@ -0,0 +1,10 @@
+#ifndef _STDC_PREDEF_H
+#define _STDC_PREDEF_H
+
+#define __STDC_ISO_10646__ 201206L
+
+#if !defined(__GCC_IEC_559) || __GCC_IEC_559 > 0
+#define __STDC_IEC_559__ 1
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stddef.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stddef.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stddef.h	(revision 398)
@@ -0,0 +1,25 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_ptrdiff_t
+#define __NEED_size_t
+#define __NEED_wchar_t
+#if __STDC_VERSION__ >= 201112L || (defined(__cplusplus) && __cplusplus >= 201103L)
+#define __NEED_max_align_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if __GNUC__ > 3
+#define offsetof(type, member) __builtin_offsetof(type, member)
+#else
+#define offsetof(type, member) ((size_t)( (char *)&(((type *)0)->member) - (char *)0 ))
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdint.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdint.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdint.h	(revision 398)
@@ -0,0 +1,117 @@
+#ifndef _STDINT_H
+#define _STDINT_H
+
+#define __NEED_int8_t
+#define __NEED_int16_t
+#define __NEED_int32_t
+#define __NEED_int64_t
+
+#define __NEED_uint8_t
+#define __NEED_uint16_t
+#define __NEED_uint32_t
+#define __NEED_uint64_t
+
+#define __NEED_intptr_t
+#define __NEED_uintptr_t
+
+#define __NEED_intmax_t
+#define __NEED_uintmax_t
+
+#include <bits/alltypes.h>
+
+typedef int8_t int_fast8_t;
+typedef int64_t int_fast64_t;
+
+typedef int8_t  int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+
+typedef uint8_t uint_fast8_t;
+typedef uint64_t uint_fast64_t;
+
+typedef uint8_t  uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+#define INT8_MIN   (-1-0x7f)
+#define INT16_MIN  (-1-0x7fff)
+#define INT32_MIN  (-1-0x7fffffff)
+#define INT64_MIN  (-1-0x7fffffffffffffff)
+
+#define INT8_MAX   (0x7f)
+#define INT16_MAX  (0x7fff)
+#define INT32_MAX  (0x7fffffff)
+#define INT64_MAX  (0x7fffffffffffffff)
+
+#define UINT8_MAX  (0xff)
+#define UINT16_MAX (0xffff)
+#define UINT32_MAX (0xffffffffu)
+#define UINT64_MAX (0xffffffffffffffffu)
+
+#define INT_FAST8_MIN   INT8_MIN
+#define INT_FAST64_MIN  INT64_MIN
+
+#define INT_LEAST8_MIN   INT8_MIN
+#define INT_LEAST16_MIN  INT16_MIN
+#define INT_LEAST32_MIN  INT32_MIN
+#define INT_LEAST64_MIN  INT64_MIN
+
+#define INT_FAST8_MAX   INT8_MAX
+#define INT_FAST64_MAX  INT64_MAX
+
+#define INT_LEAST8_MAX   INT8_MAX
+#define INT_LEAST16_MAX  INT16_MAX
+#define INT_LEAST32_MAX  INT32_MAX
+#define INT_LEAST64_MAX  INT64_MAX
+
+#define UINT_FAST8_MAX  UINT8_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+#define UINT_LEAST8_MAX  UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+#define INTMAX_MIN  INT64_MIN
+#define INTMAX_MAX  INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+#define WINT_MIN 0U
+#define WINT_MAX UINT32_MAX
+
+#if L'\0'-1 > 0
+#define WCHAR_MAX (0xffffffffu+L'\0')
+#define WCHAR_MIN (0+L'\0')
+#else
+#define WCHAR_MAX (0x7fffffff+L'\0')
+#define WCHAR_MIN (-1-0x7fffffff+L'\0')
+#endif
+
+#define SIG_ATOMIC_MIN  INT32_MIN
+#define SIG_ATOMIC_MAX  INT32_MAX
+
+#include <bits/stdint.h>
+
+#define INT8_C(c)  c
+#define INT16_C(c) c
+#define INT32_C(c) c
+
+#define UINT8_C(c)  c
+#define UINT16_C(c) c
+#define UINT32_C(c) c ## U
+
+#if UINTPTR_MAX == UINT64_MAX
+#define INT64_C(c) c ## L
+#define UINT64_C(c) c ## UL
+#define INTMAX_C(c)  c ## L
+#define UINTMAX_C(c) c ## UL
+#else
+#define INT64_C(c) c ## LL
+#define UINT64_C(c) c ## ULL
+#define INTMAX_C(c)  c ## LL
+#define UINTMAX_C(c) c ## ULL
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdio.h	(revision 398)
@@ -0,0 +1,203 @@
+#ifndef _STDIO_H
+#define _STDIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_FILE
+#define __NEED___isoc_va_list
+#define __NEED_size_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#define __NEED_ssize_t
+#define __NEED_off_t
+#define __NEED_va_list
+#endif
+
+#include <bits/alltypes.h>
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#undef EOF
+#define EOF (-1)
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define _IOFBF 0
+#define _IOLBF 1
+#define _IONBF 2
+
+#define BUFSIZ 1024
+#define FILENAME_MAX 4096
+#define FOPEN_MAX 1000
+#define TMP_MAX 10000
+#define L_tmpnam 20
+
+typedef union _G_fpos64_t {
+	char __opaque[16];
+	double __align;
+} fpos_t;
+
+extern FILE *const stdin;
+extern FILE *const stdout;
+extern FILE *const stderr;
+
+#define stdin  (stdin)
+#define stdout (stdout)
+#define stderr (stderr)
+
+FILE *fopen(const char *__restrict, const char *__restrict);
+FILE *freopen(const char *__restrict, const char *__restrict, FILE *__restrict);
+int fclose(FILE *);
+
+int remove(const char *);
+int rename(const char *, const char *);
+
+int feof(FILE *);
+int ferror(FILE *);
+int fflush(FILE *);
+void clearerr(FILE *);
+
+int fseek(FILE *, long, int);
+long ftell(FILE *);
+void rewind(FILE *);
+
+int fgetpos(FILE *__restrict, fpos_t *__restrict);
+int fsetpos(FILE *, const fpos_t *);
+
+size_t fread(void *__restrict, size_t, size_t, FILE *__restrict);
+size_t fwrite(const void *__restrict, size_t, size_t, FILE *__restrict);
+
+int fgetc(FILE *);
+int getc(FILE *);
+int getchar(void);
+int ungetc(int, FILE *);
+
+int fputc(int, FILE *);
+int putc(int, FILE *);
+int putchar(int);
+
+char *fgets(char *__restrict, int, FILE *__restrict);
+#if __STDC_VERSION__ < 201112L
+char *gets(char *);
+#endif
+
+int fputs(const char *__restrict, FILE *__restrict);
+int puts(const char *);
+
+int printf(const char *__restrict, ...);
+int fprintf(FILE *__restrict, const char *__restrict, ...);
+int sprintf(char *__restrict, const char *__restrict, ...);
+int snprintf(char *__restrict, size_t, const char *__restrict, ...);
+
+int vprintf(const char *__restrict, __isoc_va_list);
+int vfprintf(FILE *__restrict, const char *__restrict, __isoc_va_list);
+int vsprintf(char *__restrict, const char *__restrict, __isoc_va_list);
+int vsnprintf(char *__restrict, size_t, const char *__restrict, __isoc_va_list);
+
+int scanf(const char *__restrict, ...);
+int fscanf(FILE *__restrict, const char *__restrict, ...);
+int sscanf(const char *__restrict, const char *__restrict, ...);
+int vscanf(const char *__restrict, __isoc_va_list);
+int vfscanf(FILE *__restrict, const char *__restrict, __isoc_va_list);
+int vsscanf(const char *__restrict, const char *__restrict, __isoc_va_list);
+
+void perror(const char *);
+
+int setvbuf(FILE *__restrict, char *__restrict, int, size_t);
+void setbuf(FILE *__restrict, char *__restrict);
+
+char *tmpnam(char *);
+FILE *tmpfile(void);
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+FILE *fmemopen(void *__restrict, size_t, const char *__restrict);
+FILE *open_memstream(char **, size_t *);
+FILE *fdopen(int, const char *);
+FILE *popen(const char *, const char *);
+int pclose(FILE *);
+int fileno(FILE *);
+int fseeko(FILE *, off_t, int);
+off_t ftello(FILE *);
+int dprintf(int, const char *__restrict, ...);
+int vdprintf(int, const char *__restrict, __isoc_va_list);
+void flockfile(FILE *);
+int ftrylockfile(FILE *);
+void funlockfile(FILE *);
+int getc_unlocked(FILE *);
+int getchar_unlocked(void);
+int putc_unlocked(int, FILE *);
+int putchar_unlocked(int);
+ssize_t getdelim(char **__restrict, size_t *__restrict, int, FILE *__restrict);
+ssize_t getline(char **__restrict, size_t *__restrict, FILE *__restrict);
+int renameat(int, const char *, int, const char *);
+char *ctermid(char *);
+#define L_ctermid 20
+#endif
+
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#define P_tmpdir "/tmp"
+char *tempnam(const char *, const char *);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define L_cuserid 20
+char *cuserid(char *);
+void setlinebuf(FILE *);
+void setbuffer(FILE *, char *, size_t);
+int fgetc_unlocked(FILE *);
+int fputc_unlocked(int, FILE *);
+int fflush_unlocked(FILE *);
+size_t fread_unlocked(void *, size_t, size_t, FILE *);
+size_t fwrite_unlocked(const void *, size_t, size_t, FILE *);
+void clearerr_unlocked(FILE *);
+int feof_unlocked(FILE *);
+int ferror_unlocked(FILE *);
+int fileno_unlocked(FILE *);
+int getw(FILE *);
+int putw(int, FILE *);
+char *fgetln(FILE *, size_t *);
+int asprintf(char **, const char *, ...);
+int vasprintf(char **, const char *, __isoc_va_list);
+#endif
+
+#ifdef _GNU_SOURCE
+char *fgets_unlocked(char *, int, FILE *);
+int fputs_unlocked(const char *, FILE *);
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define tmpfile64 tmpfile
+#define fopen64 fopen
+#define freopen64 freopen
+#define fseeko64 fseeko
+#define ftello64 ftello
+#define fgetpos64 fgetpos
+#define fsetpos64 fsetpos
+#define fpos64_t fpos_t
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdio_ext.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdio_ext.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdio_ext.h	(revision 398)
@@ -0,0 +1,34 @@
+#ifndef _STDIO_EXT_H
+#define _STDIO_EXT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+#define FSETLOCKING_QUERY 0
+#define FSETLOCKING_INTERNAL 1
+#define FSETLOCKING_BYCALLER 2
+
+void _flushlbf(void);
+int __fsetlocking(FILE *, int);
+int __fwriting(FILE *);
+int __freading(FILE *);
+int __freadable(FILE *);
+int __fwritable(FILE *);
+int __flbf(FILE *);
+size_t __fbufsize(FILE *);
+size_t __fpending(FILE *);
+int __fpurge(FILE *);
+
+size_t __freadahead(FILE *);
+const char *__freadptr(FILE *, size_t *);
+void __freadptrinc(FILE *, size_t);
+void __fseterr(FILE *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdlib.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdlib.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdlib.h	(revision 398)
@@ -0,0 +1,174 @@
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#define __NEED_wchar_t
+
+#include <bits/alltypes.h>
+
+int atoi (const char *);
+long atol (const char *);
+long long atoll (const char *);
+double atof (const char *);
+
+float strtof (const char *__restrict, char **__restrict);
+double strtod (const char *__restrict, char **__restrict);
+long double strtold (const char *__restrict, char **__restrict);
+
+long strtol (const char *__restrict, char **__restrict, int);
+unsigned long strtoul (const char *__restrict, char **__restrict, int);
+long long strtoll (const char *__restrict, char **__restrict, int);
+unsigned long long strtoull (const char *__restrict, char **__restrict, int);
+
+int rand (void);
+void srand (unsigned);
+
+void *malloc (size_t);
+void *calloc (size_t, size_t);
+void *realloc (void *, size_t);
+void free (void *);
+void *aligned_alloc(size_t, size_t);
+
+_Noreturn void abort (void);
+int atexit (void (*) (void));
+_Noreturn void exit (int);
+_Noreturn void _Exit (int);
+int at_quick_exit (void (*) (void));
+_Noreturn void quick_exit (int);
+
+char *getenv (const char *);
+
+int system (const char *);
+
+void *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *));
+void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
+
+int abs (int);
+long labs (long);
+long long llabs (long long);
+
+typedef struct { int quot, rem; } div_t;
+typedef struct { long quot, rem; } ldiv_t;
+typedef struct { long long quot, rem; } lldiv_t;
+
+div_t div (int, int);
+ldiv_t ldiv (long, long);
+lldiv_t lldiv (long long, long long);
+
+int mblen (const char *, size_t);
+int mbtowc (wchar_t *__restrict, const char *__restrict, size_t);
+int wctomb (char *, wchar_t);
+size_t mbstowcs (wchar_t *__restrict, const char *__restrict, size_t);
+size_t wcstombs (char *__restrict, const wchar_t *__restrict, size_t);
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+size_t __ctype_get_mb_cur_max(void);
+#define MB_CUR_MAX (__ctype_get_mb_cur_max())
+
+#define RAND_MAX (0x7fffffff)
+
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#define WNOHANG    1
+#define WUNTRACED  2
+
+#define WEXITSTATUS(s) (((s) & 0xff00) >> 8)
+#define WTERMSIG(s) ((s) & 0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001)>>8) > 0x7f00)
+#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)
+
+int posix_memalign (void **, size_t, size_t);
+int setenv (const char *, const char *, int);
+int unsetenv (const char *);
+int mkstemp (char *);
+int mkostemp (char *, int);
+char *mkdtemp (char *);
+int getsubopt (char **, char *const *, char **);
+int rand_r (unsigned *);
+
+#endif
+
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+char *realpath (const char *__restrict, char *__restrict);
+long int random (void);
+void srandom (unsigned int);
+char *initstate (unsigned int, char *, size_t);
+char *setstate (char *);
+int putenv (char *);
+int posix_openpt (int);
+int grantpt (int);
+int unlockpt (int);
+char *ptsname (int);
+char *l64a (long);
+long a64l (const char *);
+void setkey (const char *);
+double drand48 (void);
+double erand48 (unsigned short [3]);
+long int lrand48 (void);
+long int nrand48 (unsigned short [3]);
+long mrand48 (void);
+long jrand48 (unsigned short [3]);
+void srand48 (long);
+unsigned short *seed48 (unsigned short [3]);
+void lcong48 (unsigned short [7]);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <alloca.h>
+char *mktemp (char *);
+int mkstemps (char *, int);
+int mkostemps (char *, int, int);
+void *valloc (size_t);
+void *memalign(size_t, size_t);
+int getloadavg(double *, int);
+int clearenv(void);
+#define WCOREDUMP(s) ((s) & 0x80)
+#define WIFCONTINUED(s) ((s) == 0xffff)
+#endif
+
+#ifdef _GNU_SOURCE
+int ptsname_r(int, char *, size_t);
+char *ecvt(double, int, int *, int *);
+char *fcvt(double, int, int *, int *);
+char *gcvt(double, int, char *);
+struct __locale_struct;
+float strtof_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+double strtod_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+long double strtold_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define mkstemp64 mkstemp
+#define mkostemp64 mkostemp
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define mkstemps64 mkstemps
+#define mkostemps64 mkostemps
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdnoreturn.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdnoreturn.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stdnoreturn.h	(revision 398)
@@ -0,0 +1,7 @@
+#ifndef _STDNORETURN_H
+#define _STDNORETURN_H
+#ifndef __cplusplus
+#include <features.h>
+#define noreturn _Noreturn
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/string.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/string.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/string.h	(revision 398)
@@ -0,0 +1,104 @@
+#ifndef	_STRING_H
+#define	_STRING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#define __NEED_locale_t
+#endif
+
+#include <bits/alltypes.h>
+
+void *memcpy (void *__restrict, const void *__restrict, size_t);
+void *memmove (void *, const void *, size_t);
+void *memset (void *, int, size_t);
+int memcmp (const void *, const void *, size_t);
+void *memchr (const void *, int, size_t);
+
+char *strcpy (char *__restrict, const char *__restrict);
+char *strncpy (char *__restrict, const char *__restrict, size_t);
+
+char *strcat (char *__restrict, const char *__restrict);
+char *strncat (char *__restrict, const char *__restrict, size_t);
+
+int strcmp (const char *, const char *);
+int strncmp (const char *, const char *, size_t);
+
+int strcoll (const char *, const char *);
+size_t strxfrm (char *__restrict, const char *__restrict, size_t);
+
+char *strchr (const char *, int);
+char *strrchr (const char *, int);
+
+size_t strcspn (const char *, const char *);
+size_t strspn (const char *, const char *);
+char *strpbrk (const char *, const char *);
+char *strstr (const char *, const char *);
+char *strtok (char *__restrict, const char *__restrict);
+
+size_t strlen (const char *);
+
+char *strerror (int);
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#include <strings.h>
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+char *strtok_r (char *__restrict, const char *__restrict, char **__restrict);
+int strerror_r (int, char *, size_t);
+char *stpcpy(char *__restrict, const char *__restrict);
+char *stpncpy(char *__restrict, const char *__restrict, size_t);
+size_t strnlen (const char *, size_t);
+char *strdup (const char *);
+char *strndup (const char *, size_t);
+char *strsignal(int);
+char *strerror_l (int, locale_t);
+int strcoll_l (const char *, const char *, locale_t);
+size_t strxfrm_l (char *__restrict, const char *__restrict, size_t, locale_t);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+void *memccpy (void *__restrict, const void *__restrict, int, size_t);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+char *strsep(char **, const char *);
+size_t strlcat (char *, const char *, size_t);
+size_t strlcpy (char *, const char *, size_t);
+#endif
+
+#ifdef _GNU_SOURCE
+#define	strdupa(x)	strcpy(alloca(strlen(x)+1),x)
+int strverscmp (const char *, const char *);
+char *strchrnul(const char *, int);
+char *strcasestr(const char *, const char *);
+void *memmem(const void *, size_t, const void *, size_t);
+void *memrchr(const void *, int, size_t);
+void *mempcpy(void *, const void *, size_t);
+#ifndef __cplusplus
+char *basename();
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/strings.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/strings.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/strings.h	(revision 398)
@@ -0,0 +1,39 @@
+#ifndef	_STRINGS_H
+#define	_STRINGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define __NEED_size_t
+#define __NEED_locale_t
+#include <bits/alltypes.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \
+ || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \
+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
+int bcmp (const void *, const void *, size_t);
+void bcopy (const void *, void *, size_t);
+void bzero (void *, size_t);
+char *index (const char *, int);
+char *rindex (const char *, int);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE)  || defined(_BSD_SOURCE)
+int ffs (int);
+int ffsl (long);
+int ffsll (long long);
+#endif
+
+int strcasecmp (const char *, const char *);
+int strncasecmp (const char *, const char *, size_t);
+
+int strcasecmp_l (const char *, const char *, locale_t);
+int strncasecmp_l (const char *, const char *, size_t, locale_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stropts.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stropts.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/stropts.h	(revision 398)
@@ -0,0 +1,139 @@
+#ifndef _STROPTS_H
+#define _STROPTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __SID		('S' << 8)
+
+#define I_NREAD		(__SID | 1)
+#define I_PUSH		(__SID | 2)
+#define I_POP		(__SID | 3)
+#define I_LOOK		(__SID | 4)
+#define I_FLUSH		(__SID | 5)
+#define I_SRDOPT	(__SID | 6)
+#define I_GRDOPT	(__SID | 7)
+#define I_STR		(__SID | 8)
+#define I_SETSIG	(__SID | 9)
+#define I_GETSIG	(__SID |10)
+#define I_FIND		(__SID |11)
+#define I_LINK		(__SID |12)
+#define I_UNLINK	(__SID |13)
+#define I_PEEK		(__SID |15)
+#define I_FDINSERT	(__SID |16)
+#define I_SENDFD	(__SID |17)
+#define I_RECVFD	(__SID |14)
+#define I_SWROPT	(__SID |19)
+#define I_GWROPT	(__SID |20)
+#define I_LIST		(__SID |21)
+#define I_PLINK		(__SID |22)
+#define I_PUNLINK	(__SID |23)
+#define I_FLUSHBAND	(__SID |28)
+#define I_CKBAND	(__SID |29)
+#define I_GETBAND	(__SID |30)
+#define I_ATMARK	(__SID |31)
+#define I_SETCLTIME	(__SID |32)
+#define I_GETCLTIME	(__SID |33)
+#define I_CANPUT	(__SID |34)
+
+#define FMNAMESZ	8
+
+#define FLUSHR		0x01
+#define FLUSHW		0x02
+#define FLUSHRW		0x03
+#define FLUSHBAND	0x04
+
+#define S_INPUT		0x0001
+#define S_HIPRI		0x0002
+#define S_OUTPUT	0x0004
+#define S_MSG		0x0008
+#define S_ERROR		0x0010
+#define S_HANGUP	0x0020
+#define S_RDNORM	0x0040
+#define S_WRNORM	S_OUTPUT
+#define S_RDBAND	0x0080
+#define S_WRBAND	0x0100
+#define S_BANDURG	0x0200
+
+#define RS_HIPRI	0x01
+
+#define RNORM		0x0000
+#define RMSGD		0x0001
+#define RMSGN		0x0002
+#define RPROTDAT	0x0004
+#define RPROTDIS	0x0008
+#define RPROTNORM	0x0010
+#define RPROTMASK	0x001C
+
+#define SNDZERO		0x001
+#define SNDPIPE		0x002
+
+#define ANYMARK		0x01
+#define LASTMARK	0x02
+
+#define MUXID_ALL	(-1)
+
+#define MSG_HIPRI	0x01
+#define MSG_ANY		0x02
+#define MSG_BAND	0x04
+
+#define MORECTL		1
+#define MOREDATA	2
+
+struct bandinfo {
+	unsigned char bi_pri;
+	int bi_flag;
+};
+
+struct strbuf {
+	int maxlen;
+	int len;
+	char *buf;
+};
+
+struct strpeek {
+	struct strbuf ctlbuf;
+	struct strbuf databuf;
+	unsigned flags;
+};
+
+struct strfdinsert {
+	struct strbuf ctlbuf;
+	struct strbuf databuf;
+	unsigned flags;
+	int fildes;
+	int offset;
+};
+
+struct strioctl {
+	int ic_cmd;
+	int ic_timout;
+	int ic_len;
+	char *ic_dp;
+};
+
+struct strrecvfd {
+	int fd;
+	int uid;
+	int gid;
+	char __fill[8];
+};
+
+struct str_mlist {
+	char l_name[FMNAMESZ + 1];
+};
+
+struct str_list {
+	int sl_nmods;
+	struct str_mlist *sl_modlist;
+};
+
+int isastream(int);
+int ioctl(int, int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/acct.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/acct.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/acct.h	(revision 398)
@@ -0,0 +1,73 @@
+#ifndef _SYS_ACCT_H
+#define _SYS_ACCT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <endian.h>
+#include <time.h>
+#include <stdint.h>
+
+#define ACCT_COMM 16
+
+typedef uint16_t comp_t;
+
+struct acct {
+	char ac_flag;
+	uint16_t ac_uid;
+	uint16_t ac_gid;
+	uint16_t ac_tty;
+	uint32_t ac_btime;
+	comp_t ac_utime;
+	comp_t ac_stime;
+	comp_t ac_etime;
+	comp_t ac_mem;
+	comp_t ac_io;
+	comp_t ac_rw;
+	comp_t ac_minflt;
+	comp_t ac_majflt;
+	comp_t ac_swaps;
+	uint32_t ac_exitcode;
+	char ac_comm[ACCT_COMM+1];
+	char ac_pad[10];
+};
+
+
+struct acct_v3 {
+	char ac_flag;
+	char ac_version;
+	uint16_t ac_tty;
+	uint32_t ac_exitcode;
+	uint32_t ac_uid;
+	uint32_t ac_gid;
+	uint32_t ac_pid;
+	uint32_t ac_ppid;
+	uint32_t ac_btime;
+	float ac_etime;
+	comp_t ac_utime;
+	comp_t ac_stime;
+	comp_t ac_mem;
+	comp_t ac_io;
+	comp_t ac_rw;
+	comp_t ac_minflt;
+	comp_t ac_majflt;
+	comp_t ac_swaps;
+	char ac_comm[ACCT_COMM];
+};
+
+#define AFORK 1
+#define ASU 2
+#define ACORE 8
+#define AXSIG 16
+#define ACCT_BYTEORDER (128*(__BYTE_ORDER==__BIG_ENDIAN))
+#define AHZ 100
+
+int acct(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/auxv.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/auxv.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/auxv.h	(revision 398)
@@ -0,0 +1,17 @@
+#ifndef _SYS_AUXV_H
+#define _SYS_AUXV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <elf.h>
+#include <bits/hwcap.h>
+
+unsigned long getauxval(unsigned long);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/cachectl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/cachectl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/cachectl.h	(revision 398)
@@ -0,0 +1,22 @@
+#ifndef _SYS_CACHECTL_H
+#define _SYS_CACHECTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ICACHE (1<<0)
+#define DCACHE (1<<1)
+#define BCACHE (ICACHE|DCACHE)
+#define CACHEABLE 0
+#define UNCACHEABLE 1
+ 
+int cachectl(void *, int, int);
+int cacheflush(void *, int, int);
+int _flush_cache(void *, int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/dir.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/dir.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/dir.h	(revision 398)
@@ -0,0 +1,2 @@
+#include <dirent.h>
+#define direct dirent
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/epoll.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/epoll.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/epoll.h	(revision 398)
@@ -0,0 +1,68 @@
+#ifndef	_SYS_EPOLL_H
+#define	_SYS_EPOLL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define EPOLL_CLOEXEC O_CLOEXEC
+#define EPOLL_NONBLOCK O_NONBLOCK
+
+enum EPOLL_EVENTS { __EPOLL_DUMMY };
+#define EPOLLIN 0x001
+#define EPOLLPRI 0x002
+#define EPOLLOUT 0x004
+#define EPOLLRDNORM 0x040
+#define EPOLLRDBAND 0x080
+#define EPOLLWRNORM 0x100
+#define EPOLLWRBAND 0x200
+#define EPOLLMSG 0x400
+#define EPOLLERR 0x008
+#define EPOLLHUP 0x010
+#define EPOLLRDHUP 0x2000
+#define EPOLLEXCLUSIVE (1U<<28)
+#define EPOLLWAKEUP (1U<<29)
+#define EPOLLONESHOT (1U<<30)
+#define EPOLLET (1U<<31)
+
+#define EPOLL_CTL_ADD 1
+#define EPOLL_CTL_DEL 2
+#define EPOLL_CTL_MOD 3
+
+typedef union epoll_data {
+	void *ptr;
+	int fd;
+	uint32_t u32;
+	uint64_t u64;
+} epoll_data_t;
+
+struct epoll_event {
+	uint32_t events;
+	epoll_data_t data;
+}
+#ifdef __x86_64__
+__attribute__ ((__packed__))
+#endif
+;
+
+
+int epoll_create(int);
+int epoll_create1(int);
+int epoll_ctl(int, int, int, struct epoll_event *);
+int epoll_wait(int, struct epoll_event *, int, int);
+int epoll_pwait(int, struct epoll_event *, int, int, const sigset_t *);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sys/epoll.h */
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/errno.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/errno.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/errno.h	(revision 398)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/errno.h> to <errno.h>
+#include <errno.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/eventfd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/eventfd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/eventfd.h	(revision 398)
@@ -0,0 +1,26 @@
+#ifndef _SYS_EVENTFD_H
+#define _SYS_EVENTFD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <fcntl.h>
+
+typedef uint64_t eventfd_t;
+
+#define EFD_SEMAPHORE 1
+#define EFD_CLOEXEC O_CLOEXEC
+#define EFD_NONBLOCK O_NONBLOCK
+
+int eventfd(unsigned int, int);
+int eventfd_read(int, eventfd_t *);
+int eventfd_write(int, eventfd_t);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sys/eventfd.h */
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/fanotify.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/fanotify.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/fanotify.h	(revision 398)
@@ -0,0 +1,73 @@
+#ifndef _FANOTIFY_H
+#define _FANOTIFY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct fanotify_event_metadata {
+	unsigned event_len;
+	unsigned char vers;
+	unsigned char reserved;
+	unsigned short metadata_len;
+	unsigned long long mask
+#ifdef __GNUC__
+	__attribute__((__aligned__(8)))
+#endif
+	;
+	int fd;
+	int pid;
+};
+
+struct fanotify_response {
+	int fd;
+	unsigned response;
+};
+
+#define FAN_ACCESS 0x01
+#define FAN_MODIFY 0x02
+#define FAN_CLOSE_WRITE 0x08
+#define FAN_CLOSE_NOWRITE 0x10
+#define FAN_OPEN 0x20
+#define FAN_Q_OVERFLOW 0x4000
+#define FAN_OPEN_PERM 0x10000
+#define FAN_ACCESS_PERM 0x20000
+#define FAN_ONDIR 0x40000000
+#define FAN_EVENT_ON_CHILD 0x08000000
+#define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)
+#define FAN_CLOEXEC 0x01
+#define FAN_NONBLOCK 0x02
+#define FAN_CLASS_NOTIF 0
+#define FAN_CLASS_CONTENT 0x04
+#define FAN_CLASS_PRE_CONTENT 0x08
+#define FAN_ALL_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | FAN_CLASS_PRE_CONTENT)
+#define FAN_UNLIMITED_QUEUE 0x10
+#define FAN_UNLIMITED_MARKS 0x20
+#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
+#define FAN_MARK_ADD 0x01
+#define FAN_MARK_REMOVE 0x02
+#define FAN_MARK_DONT_FOLLOW 0x04
+#define FAN_MARK_ONLYDIR 0x08
+#define FAN_MARK_MOUNT 0x10
+#define FAN_MARK_IGNORED_MASK 0x20
+#define FAN_MARK_IGNORED_SURV_MODIFY 0x40
+#define FAN_MARK_FLUSH 0x80
+#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_DONT_FOLLOW | FAN_MARK_ONLYDIR | FAN_MARK_MOUNT | FAN_MARK_IGNORED_MASK | FAN_MARK_IGNORED_SURV_MODIFY | FAN_MARK_FLUSH)
+#define FAN_ALL_EVENTS (FAN_ACCESS | FAN_MODIFY | FAN_CLOSE | FAN_OPEN)
+#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM | FAN_ACCESS_PERM)
+#define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_Q_OVERFLOW)
+#define FANOTIFY_METADATA_VERSION 3
+#define FAN_ALLOW 0x01
+#define FAN_DENY 0x02
+#define FAN_NOFD -1
+#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
+#define FAN_EVENT_NEXT(meta, len) ((len) -= (meta)->event_len, (struct fanotify_event_metadata*)(((char *)(meta)) + (meta)->event_len))
+#define FAN_EVENT_OK(meta, len) ((long)(len) >= (long)FAN_EVENT_METADATA_LEN && (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && (long)(meta)->event_len <= (long)(len))
+
+int fanotify_init(unsigned, unsigned);
+int fanotify_mark(int, unsigned, unsigned long long, int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/fcntl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/fcntl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/fcntl.h	(revision 398)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
+#include <fcntl.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/file.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/file.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/file.h	(revision 398)
@@ -0,0 +1,21 @@
+#ifndef _SYS_FILE_H
+#define _SYS_FILE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LOCK_SH	1
+#define LOCK_EX	2
+#define LOCK_NB	4
+#define LOCK_UN	8
+
+#define L_SET 0
+#define L_INCR 1
+#define L_XTND 2
+
+int flock(int, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/fsuid.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/fsuid.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/fsuid.h	(revision 398)
@@ -0,0 +1,20 @@
+#ifndef _SYS_FSUID_H
+#define _SYS_FSUID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_uid_t
+#define __NEED_gid_t
+
+#include <bits/alltypes.h>
+
+int setfsuid(uid_t);
+int setfsgid(gid_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/inotify.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/inotify.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/inotify.h	(revision 398)
@@ -0,0 +1,57 @@
+#ifndef _SYS_INOTIFY_H
+#define _SYS_INOTIFY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <fcntl.h>
+
+struct inotify_event {
+	int wd;
+	uint32_t mask, cookie, len;
+	char name[];
+};
+
+#define IN_CLOEXEC O_CLOEXEC
+#define IN_NONBLOCK O_NONBLOCK
+
+#define IN_ACCESS        0x00000001
+#define IN_MODIFY        0x00000002
+#define IN_ATTRIB        0x00000004
+#define IN_CLOSE_WRITE   0x00000008
+#define IN_CLOSE_NOWRITE 0x00000010
+#define IN_CLOSE         (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
+#define IN_OPEN          0x00000020
+#define IN_MOVED_FROM    0x00000040
+#define IN_MOVED_TO      0x00000080
+#define IN_MOVE          (IN_MOVED_FROM | IN_MOVED_TO)
+#define IN_CREATE        0x00000100
+#define IN_DELETE        0x00000200
+#define IN_DELETE_SELF   0x00000400
+#define IN_MOVE_SELF     0x00000800
+#define IN_ALL_EVENTS    0x00000fff
+
+#define IN_UNMOUNT       0x00002000
+#define IN_Q_OVERFLOW    0x00004000
+#define IN_IGNORED       0x00008000
+
+#define IN_ONLYDIR       0x01000000
+#define IN_DONT_FOLLOW   0x02000000
+#define IN_EXCL_UNLINK   0x04000000
+#define IN_MASK_ADD      0x20000000
+
+#define IN_ISDIR         0x40000000
+#define IN_ONESHOT       0x80000000
+
+int inotify_init(void);
+int inotify_init1(int);
+int inotify_add_watch(int, const char *, uint32_t);
+int inotify_rm_watch(int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/io.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/io.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/io.h	(revision 398)
@@ -0,0 +1,17 @@
+#ifndef	_SYS_IO_H
+#define	_SYS_IO_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/io.h>
+
+int iopl(int);
+int ioperm(unsigned long, unsigned long, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ioctl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ioctl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ioctl.h	(revision 398)
@@ -0,0 +1,14 @@
+#ifndef	_SYS_IOCTL_H
+#define	_SYS_IOCTL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/ioctl.h>
+
+int ioctl (int, int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ipc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ipc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ipc.h	(revision 398)
@@ -0,0 +1,42 @@
+#ifndef _SYS_IPC_H
+#define _SYS_IPC_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_mode_t
+#define __NEED_key_t
+
+#include <bits/alltypes.h>
+
+#define __ipc_perm_key __key
+#define __ipc_perm_seq __seq
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __key key
+#define __seq seq
+#endif
+
+#include <bits/ipc.h>
+
+#define IPC_CREAT  01000
+#define IPC_EXCL   02000
+#define IPC_NOWAIT 04000
+
+#define IPC_RMID 0
+#define IPC_SET  1
+#define IPC_STAT 2
+#define IPC_INFO 3
+
+#define IPC_PRIVATE ((key_t) 0)
+
+key_t ftok (const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/kd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/kd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/kd.h	(revision 398)
@@ -0,0 +1,8 @@
+#ifndef _SYS_KD_H
+#define _SYS_KD_H
+
+#define _LINUX_TYPES_H
+#include <linux/kd.h>
+#undef _LINUX_TYPES_H
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/klog.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/klog.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/klog.h	(revision 398)
@@ -0,0 +1,14 @@
+#ifndef	_SYS_KLOG_H
+#define	_SYS_KLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int klogctl (int, char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/mman.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/mman.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/mman.h	(revision 398)
@@ -0,0 +1,118 @@
+#ifndef	_SYS_MMAN_H
+#define	_SYS_MMAN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_mode_t
+#define __NEED_size_t
+#define __NEED_off_t
+
+#if defined(_GNU_SOURCE)
+#define __NEED_ssize_t
+#endif
+
+#include <bits/alltypes.h>
+
+#define MAP_FAILED ((void *) -1)
+
+#define MAP_SHARED     0x01
+#define MAP_PRIVATE    0x02
+#define MAP_TYPE       0x0f
+#define MAP_FIXED      0x10
+#define MAP_ANON       0x20
+#define MAP_ANONYMOUS  MAP_ANON
+#define MAP_NORESERVE  0x4000
+#define MAP_GROWSDOWN  0x0100
+#define MAP_DENYWRITE  0x0800
+#define MAP_EXECUTABLE 0x1000
+#define MAP_LOCKED     0x2000
+#define MAP_POPULATE   0x8000
+#define MAP_NONBLOCK   0x10000
+#define MAP_STACK      0x20000
+#define MAP_HUGETLB    0x40000
+#define MAP_FILE       0
+
+#define PROT_NONE      0
+#define PROT_READ      1
+#define PROT_WRITE     2
+#define PROT_EXEC      4
+#define PROT_GROWSDOWN 0x01000000
+#define PROT_GROWSUP   0x02000000
+
+#define MS_ASYNC       1
+#define MS_INVALIDATE  2
+#define MS_SYNC        4
+
+#define MCL_CURRENT    1
+#define MCL_FUTURE     2
+#define MCL_ONFAULT    4
+
+#define POSIX_MADV_NORMAL     0
+#define POSIX_MADV_RANDOM     1
+#define POSIX_MADV_SEQUENTIAL 2
+#define POSIX_MADV_WILLNEED   3
+#define POSIX_MADV_DONTNEED   4
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MADV_NORMAL      0
+#define MADV_RANDOM      1
+#define MADV_SEQUENTIAL  2
+#define MADV_WILLNEED    3
+#define MADV_DONTNEED    4
+#define MADV_FREE        8
+#define MADV_REMOVE      9
+#define MADV_DONTFORK    10
+#define MADV_DOFORK      11
+#define MADV_MERGEABLE   12
+#define MADV_UNMERGEABLE 13
+#define MADV_HUGEPAGE    14
+#define MADV_NOHUGEPAGE  15
+#define MADV_DONTDUMP    16
+#define MADV_DODUMP      17
+#define MADV_HWPOISON    100
+#define MADV_SOFT_OFFLINE 101
+#endif
+
+#include <bits/mman.h>
+
+void *mmap (void *, size_t, int, int, int, off_t);
+int munmap (void *, size_t);
+
+int mprotect (void *, size_t, int);
+int msync (void *, size_t, int);
+
+int posix_madvise (void *, size_t, int);
+
+int mlock (const void *, size_t);
+int munlock (const void *, size_t);
+int mlockall (int);
+int munlockall (void);
+
+#ifdef _GNU_SOURCE
+#define MREMAP_MAYMOVE 1
+#define MREMAP_FIXED 2
+void *mremap (void *, size_t, size_t, int, ...);
+int remap_file_pages (void *, size_t, int, size_t, int);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MLOCK_ONFAULT   0x01
+int madvise (void *, size_t, int);
+int mincore (void *, size_t, unsigned char *);
+#endif
+
+int shm_open (const char *, int, mode_t);
+int shm_unlink (const char *);
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define mmap64 mmap
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/mount.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/mount.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/mount.h	(revision 398)
@@ -0,0 +1,74 @@
+#ifndef _SYS_MOUNT_H
+#define _SYS_MOUNT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/ioctl.h>
+
+#define BLKROSET   _IO(0x12, 93)
+#define BLKROGET   _IO(0x12, 94)
+#define BLKRRPART  _IO(0x12, 95)
+#define BLKGETSIZE _IO(0x12, 96)
+#define BLKFLSBUF  _IO(0x12, 97)
+#define BLKRASET   _IO(0x12, 98)
+#define BLKRAGET   _IO(0x12, 99)
+#define BLKFRASET  _IO(0x12,100)
+#define BLKFRAGET  _IO(0x12,101)
+#define BLKSECTSET _IO(0x12,102)
+#define BLKSECTGET _IO(0x12,103)
+#define BLKSSZGET  _IO(0x12,104)
+#define BLKBSZGET  _IOR(0x12,112,size_t)
+#define BLKBSZSET  _IOW(0x12,113,size_t)
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)
+
+#define MS_RDONLY      1
+#define MS_NOSUID      2
+#define MS_NODEV       4
+#define MS_NOEXEC      8
+#define MS_SYNCHRONOUS 16
+#define MS_REMOUNT     32
+#define MS_MANDLOCK    64
+#define MS_DIRSYNC     128
+#define MS_NOATIME     1024
+#define MS_NODIRATIME  2048
+#define MS_BIND        4096
+#define MS_MOVE        8192
+#define MS_REC         16384
+#define MS_SILENT      32768
+#define MS_POSIXACL    (1<<16)
+#define MS_UNBINDABLE  (1<<17)
+#define MS_PRIVATE     (1<<18)
+#define MS_SLAVE       (1<<19)
+#define MS_SHARED      (1<<20)
+#define MS_RELATIME    (1<<21)
+#define MS_KERNMOUNT   (1<<22)
+#define MS_I_VERSION   (1<<23)
+#define MS_STRICTATIME (1<<24)
+#define MS_LAZYTIME    (1<<25)
+#define MS_NOREMOTELOCK (1<<27)
+#define MS_NOSEC       (1<<28)
+#define MS_BORN        (1<<29)
+#define MS_ACTIVE      (1<<30)
+#define MS_NOUSER      (1U<<31)
+
+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|MS_LAZYTIME)
+
+#define MS_MGC_VAL 0xc0ed0000
+#define MS_MGC_MSK 0xffff0000
+
+#define MNT_FORCE       1
+#define MNT_DETACH      2
+#define MNT_EXPIRE      4
+#define UMOUNT_NOFOLLOW 8
+
+int mount(const char *, const char *, const char *, unsigned long, const void *);
+int umount(const char *);
+int umount2(const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/msg.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/msg.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/msg.h	(revision 398)
@@ -0,0 +1,52 @@
+#ifndef _SYS_MSG_H
+#define _SYS_MSG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/ipc.h>
+
+#define __NEED_pid_t
+#define __NEED_key_t
+#define __NEED_time_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+
+#include <bits/alltypes.h>
+
+typedef unsigned long msgqnum_t;
+typedef unsigned long msglen_t;
+
+#include <bits/msg.h>
+
+#define __msg_cbytes msg_cbytes
+
+#define MSG_NOERROR 010000
+#define MSG_EXCEPT  020000
+
+#define MSG_STAT 11
+#define MSG_INFO 12
+
+struct msginfo {
+	int msgpool, msgmap, msgmax, msgmnb, msgmni, msgssz, msgtql;
+	unsigned short msgseg;
+};
+
+int msgctl (int, int, struct msqid_ds *);
+int msgget (key_t, int);
+ssize_t msgrcv (int, void *, size_t, long, int);
+int msgsnd (int, const void *, size_t, int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct msgbuf {
+	long mtype;
+	char mtext[1];
+};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/mtio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/mtio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/mtio.h	(revision 398)
@@ -0,0 +1,188 @@
+#ifndef _SYS_MTIO_H
+#define _SYS_MTIO_H
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+struct mtop {
+	short mt_op;
+	int mt_count;
+};
+
+#define _IOT_mtop _IOT (_IOTS (short), 1, _IOTS (int), 1, 0, 0)
+#define _IOT_mtget _IOT (_IOTS (long), 7, 0, 0, 0, 0)
+#define _IOT_mtpos _IOT_SIMPLE (long)
+#define _IOT_mtconfiginfo _IOT (_IOTS (long), 2, _IOTS (short), 3, _IOTS (long), 1)
+
+
+#define MTRESET 0
+#define MTFSF	1
+#define MTBSF	2
+#define MTFSR	3
+#define MTBSR	4
+#define MTWEOF	5
+#define MTREW	6
+#define MTOFFL	7
+#define MTNOP	8
+#define MTRETEN 9
+#define MTBSFM	10
+#define MTFSFM  11
+#define MTEOM	12
+#define MTERASE 13
+#define MTRAS1  14
+#define MTRAS2	15
+#define MTRAS3  16
+#define MTSETBLK 20
+#define MTSETDENSITY 21
+#define MTSEEK	22
+#define MTTELL	23
+#define MTSETDRVBUFFER 24
+#define MTFSS	25
+#define MTBSS	26
+#define MTWSM	27
+#define MTLOCK  28
+#define MTUNLOCK 29
+#define MTLOAD  30
+#define MTUNLOAD 31
+#define MTCOMPRESSION 32
+#define MTSETPART 33
+#define MTMKPART  34
+
+struct mtget {
+	long mt_type;
+	long mt_resid;
+	long mt_dsreg;
+	long mt_gstat;
+	long mt_erreg;
+	int mt_fileno;
+	int mt_blkno;
+};
+
+#define MT_ISUNKNOWN		0x01
+#define MT_ISQIC02		0x02
+#define MT_ISWT5150		0x03
+#define MT_ISARCHIVE_5945L2	0x04
+#define MT_ISCMSJ500		0x05
+#define MT_ISTDC3610		0x06
+#define MT_ISARCHIVE_VP60I	0x07
+#define MT_ISARCHIVE_2150L	0x08
+#define MT_ISARCHIVE_2060L	0x09
+#define MT_ISARCHIVESC499	0x0A
+#define MT_ISQIC02_ALL_FEATURES	0x0F
+#define MT_ISWT5099EEN24	0x11
+#define MT_ISTEAC_MT2ST		0x12
+#define MT_ISEVEREX_FT40A	0x32
+#define MT_ISDDS1		0x51
+#define MT_ISDDS2		0x52
+#define MT_ISSCSI1		0x71
+#define MT_ISSCSI2		0x72
+#define MT_ISFTAPE_UNKNOWN	0x800000
+#define MT_ISFTAPE_FLAG		0x800000
+
+struct mt_tape_info {
+	long t_type;
+	char *t_name;
+};
+
+#define MT_TAPE_INFO \
+{									      \
+	{MT_ISUNKNOWN,		"Unknown type of tape device"},		      \
+	{MT_ISQIC02,		"Generic QIC-02 tape streamer"},	      \
+	{MT_ISWT5150,		"Wangtek 5150, QIC-150"},		      \
+	{MT_ISARCHIVE_5945L2,	"Archive 5945L-2"},			      \
+	{MT_ISCMSJ500,		"CMS Jumbo 500"},			      \
+	{MT_ISTDC3610,		"Tandberg TDC 3610, QIC-24"},		      \
+	{MT_ISARCHIVE_VP60I,	"Archive VP60i, QIC-02"},		      \
+	{MT_ISARCHIVE_2150L,	"Archive Viper 2150L"},			      \
+	{MT_ISARCHIVE_2060L,	"Archive Viper 2060L"},			      \
+	{MT_ISARCHIVESC499,	"Archive SC-499 QIC-36 controller"},	      \
+	{MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"},	      \
+	{MT_ISWT5099EEN24,	"Wangtek 5099-een24, 60MB"},		      \
+	{MT_ISTEAC_MT2ST,	"Teac MT-2ST 155mb data cassette drive"},     \
+	{MT_ISEVEREX_FT40A,	"Everex FT40A, QIC-40"},		      \
+	{MT_ISSCSI1,		"Generic SCSI-1 tape"},			      \
+	{MT_ISSCSI2,		"Generic SCSI-2 tape"},			      \
+	{0, 0}								      \
+}
+
+struct mtpos {
+	long mt_blkno;
+};
+
+struct mtconfiginfo  {
+	long mt_type;
+	long ifc_type;
+	unsigned short irqnr;
+	unsigned short dmanr;
+	unsigned short port;
+	unsigned long debug;
+	unsigned have_dens:1;
+	unsigned have_bsf:1;
+	unsigned have_fsr:1;
+	unsigned have_bsr:1;
+	unsigned have_eod:1;
+	unsigned have_seek:1;
+	unsigned have_tell:1;
+	unsigned have_ras1:1;
+	unsigned have_ras2:1;
+	unsigned have_ras3:1;
+	unsigned have_qfa:1;
+	unsigned pad1:5;
+	char reserved[10];
+};
+
+#define	MTIOCTOP _IOW('m', 1, struct mtop)
+#define	MTIOCGET _IOR('m', 2, struct mtget)
+#define	MTIOCPOS _IOR('m', 3, struct mtpos)
+
+#define	MTIOCGETCONFIG	_IOR('m', 4, struct mtconfiginfo)
+#define	MTIOCSETCONFIG	_IOW('m', 5, struct mtconfiginfo)
+
+#define GMT_EOF(x)              ((x) & 0x80000000)
+#define GMT_BOT(x)              ((x) & 0x40000000)
+#define GMT_EOT(x)              ((x) & 0x20000000)
+#define GMT_SM(x)               ((x) & 0x10000000)
+#define GMT_EOD(x)              ((x) & 0x08000000)
+#define GMT_WR_PROT(x)          ((x) & 0x04000000)
+#define GMT_ONLINE(x)           ((x) & 0x01000000)
+#define GMT_D_6250(x)           ((x) & 0x00800000)
+#define GMT_D_1600(x)           ((x) & 0x00400000)
+#define GMT_D_800(x)            ((x) & 0x00200000)
+#define GMT_DR_OPEN(x)          ((x) & 0x00040000)
+#define GMT_IM_REP_EN(x)        ((x) & 0x00010000)
+
+#define MT_ST_BLKSIZE_SHIFT	0
+#define MT_ST_BLKSIZE_MASK	0xffffff
+#define MT_ST_DENSITY_SHIFT	24
+#define MT_ST_DENSITY_MASK	0xff000000
+#define MT_ST_SOFTERR_SHIFT	0
+#define MT_ST_SOFTERR_MASK	0xffff
+#define MT_ST_OPTIONS		0xf0000000
+#define MT_ST_BOOLEANS		0x10000000
+#define MT_ST_SETBOOLEANS	0x30000000
+#define MT_ST_CLEARBOOLEANS	0x40000000
+#define MT_ST_WRITE_THRESHOLD	0x20000000
+#define MT_ST_DEF_BLKSIZE	0x50000000
+#define MT_ST_DEF_OPTIONS	0x60000000
+#define MT_ST_BUFFER_WRITES	0x1
+#define MT_ST_ASYNC_WRITES	0x2
+#define MT_ST_READ_AHEAD	0x4
+#define MT_ST_DEBUGGING		0x8
+#define MT_ST_TWO_FM		0x10
+#define MT_ST_FAST_MTEOM	0x20
+#define MT_ST_AUTO_LOCK		0x40
+#define MT_ST_DEF_WRITES	0x80
+#define MT_ST_CAN_BSR		0x100
+#define MT_ST_NO_BLKLIMS	0x200
+#define MT_ST_CAN_PARTITIONS    0x400
+#define MT_ST_SCSI2LOGICAL      0x800
+#define MT_ST_CLEAR_DEFAULT	0xfffff
+#define MT_ST_DEF_DENSITY	(MT_ST_DEF_OPTIONS | 0x100000)
+#define MT_ST_DEF_COMPRESSION	(MT_ST_DEF_OPTIONS | 0x200000)
+#define MT_ST_DEF_DRVBUFFER	(MT_ST_DEF_OPTIONS | 0x300000)
+#define MT_ST_HPLOADER_OFFSET 10000
+#ifndef DEFTAPE
+# define DEFTAPE	"/dev/tape"
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/param.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/param.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/param.h	(revision 398)
@@ -0,0 +1,35 @@
+#ifndef _SYS_PARAM_H
+#define _SYS_PARAM_H
+
+#define MAXSYMLINKS 20
+#define MAXHOSTNAMELEN 64
+#define MAXNAMLEN 255
+#define MAXPATHLEN 4096
+#define NBBY 8
+#define NGROUPS 32
+#define CANBSIZ 255
+#define NOFILE 256
+#define NCARGS 131072
+#define DEV_BSIZE 512
+#define NOGROUP (-1)
+
+#undef MIN
+#undef MAX
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+#define __bitop(x,i,o) ((x)[(i)/8] o (1<<(i)%8))
+#define setbit(x,i) __bitop(x,i,|=)
+#define clrbit(x,i) __bitop(x,i,&=~)
+#define isset(x,i) __bitop(x,i,&)
+#define isclr(x,i) !isset(x,i)
+
+#define howmany(n,d) (((n)+((d)-1))/(d))
+#define roundup(n,d) (howmany(n,d)*(d))
+#define powerof2(n) !(((n)-1) & (n))
+
+#include <sys/resource.h>
+#include <endian.h>
+#include <limits.h>
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/personality.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/personality.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/personality.h	(revision 398)
@@ -0,0 +1,46 @@
+#ifndef _PERSONALITY_H
+#define _PERSONALITY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ADDR_NO_RANDOMIZE  0x0040000
+#define MMAP_PAGE_ZERO     0x0100000
+#define ADDR_COMPAT_LAYOUT 0x0200000
+#define READ_IMPLIES_EXEC  0x0400000
+#define ADDR_LIMIT_32BIT   0x0800000
+#define SHORT_INODE        0x1000000
+#define WHOLE_SECONDS      0x2000000
+#define STICKY_TIMEOUTS    0x4000000
+#define ADDR_LIMIT_3GB     0x8000000
+
+#define PER_LINUX 0
+#define PER_LINUX_32BIT ADDR_LIMIT_32BIT
+#define PER_SVR4 (1 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
+#define PER_SVR3 (2 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_SCOSVR3 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE)
+#define PER_OSR5 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS)
+#define PER_WYSEV386 (4 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_ISCR4 (5 | STICKY_TIMEOUTS)
+#define PER_BSD 6
+#define PER_SUNOS (6 | STICKY_TIMEOUTS)
+#define PER_XENIX (7 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_LINUX32 8
+#define PER_LINUX32_3GB (8 | ADDR_LIMIT_3GB)
+#define PER_IRIX32 (9 | STICKY_TIMEOUTS)
+#define PER_IRIXN32 (0xa | STICKY_TIMEOUTS)
+#define PER_IRIX64 (0x0b | STICKY_TIMEOUTS)
+#define PER_RISCOS 0xc
+#define PER_SOLARIS (0xd | STICKY_TIMEOUTS)
+#define PER_UW7 (0xe | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
+#define PER_OSF4 0xf
+#define PER_HPUX 0x10
+#define PER_MASK 0xff
+
+int personality(unsigned long);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/poll.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/poll.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/poll.h	(revision 398)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/poll.h> to <poll.h>
+#include <poll.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/prctl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/prctl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/prctl.h	(revision 398)
@@ -0,0 +1,139 @@
+#ifndef _SYS_PRCTL_H
+#define _SYS_PRCTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define PR_SET_PDEATHSIG  1
+#define PR_GET_PDEATHSIG  2
+#define PR_GET_DUMPABLE   3
+#define PR_SET_DUMPABLE   4
+#define PR_GET_UNALIGN   5
+#define PR_SET_UNALIGN   6
+#define PR_UNALIGN_NOPRINT 1
+#define PR_UNALIGN_SIGBUS 2
+#define PR_GET_KEEPCAPS   7
+#define PR_SET_KEEPCAPS   8
+#define PR_GET_FPEMU  9
+#define PR_SET_FPEMU 10
+#define PR_FPEMU_NOPRINT 1
+#define PR_FPEMU_SIGFPE 2
+#define PR_GET_FPEXC 11
+#define PR_SET_FPEXC 12
+#define PR_FP_EXC_SW_ENABLE 0x80
+#define PR_FP_EXC_DIV  0x010000
+#define PR_FP_EXC_OVF  0x020000
+#define PR_FP_EXC_UND  0x040000
+#define PR_FP_EXC_RES  0x080000
+#define PR_FP_EXC_INV  0x100000
+#define PR_FP_EXC_DISABLED 0
+#define PR_FP_EXC_NONRECOV 1
+#define PR_FP_EXC_ASYNC 2
+#define PR_FP_EXC_PRECISE 3
+#define PR_GET_TIMING   13
+#define PR_SET_TIMING   14
+#define PR_TIMING_STATISTICAL  0
+#define PR_TIMING_TIMESTAMP    1
+#define PR_SET_NAME    15
+#define PR_GET_NAME    16
+#define PR_GET_ENDIAN 19
+#define PR_SET_ENDIAN 20
+#define PR_ENDIAN_BIG 0
+#define PR_ENDIAN_LITTLE 1
+#define PR_ENDIAN_PPC_LITTLE 2
+#define PR_GET_SECCOMP 21
+#define PR_SET_SECCOMP 22
+#define PR_CAPBSET_READ 23
+#define PR_CAPBSET_DROP 24
+#define PR_GET_TSC 25
+#define PR_SET_TSC 26
+#define PR_TSC_ENABLE 1
+#define PR_TSC_SIGSEGV 2
+#define PR_GET_SECUREBITS 27
+#define PR_SET_SECUREBITS 28
+#define PR_SET_TIMERSLACK 29
+#define PR_GET_TIMERSLACK 30
+
+#define PR_TASK_PERF_EVENTS_DISABLE             31
+#define PR_TASK_PERF_EVENTS_ENABLE              32
+
+#define PR_MCE_KILL     33
+#define PR_MCE_KILL_CLEAR   0
+#define PR_MCE_KILL_SET     1
+#define PR_MCE_KILL_LATE    0
+#define PR_MCE_KILL_EARLY   1
+#define PR_MCE_KILL_DEFAULT 2
+#define PR_MCE_KILL_GET 34
+
+#define PR_SET_MM               35
+#define PR_SET_MM_START_CODE           1
+#define PR_SET_MM_END_CODE             2
+#define PR_SET_MM_START_DATA           3
+#define PR_SET_MM_END_DATA             4
+#define PR_SET_MM_START_STACK          5
+#define PR_SET_MM_START_BRK            6
+#define PR_SET_MM_BRK                  7
+#define PR_SET_MM_ARG_START            8
+#define PR_SET_MM_ARG_END              9
+#define PR_SET_MM_ENV_START            10
+#define PR_SET_MM_ENV_END              11
+#define PR_SET_MM_AUXV                 12
+#define PR_SET_MM_EXE_FILE             13
+#define PR_SET_MM_MAP                  14
+#define PR_SET_MM_MAP_SIZE             15
+
+struct prctl_mm_map {
+	uint64_t start_code;
+	uint64_t end_code;
+	uint64_t start_data;
+	uint64_t end_data;
+	uint64_t start_brk;
+	uint64_t brk;
+	uint64_t start_stack;
+	uint64_t arg_start;
+	uint64_t arg_end;
+	uint64_t env_start;
+	uint64_t env_end;
+	uint64_t *auxv;
+	uint32_t auxv_size;
+	uint32_t exe_fd;
+};
+
+#define PR_SET_PTRACER 0x59616d61
+#define PR_SET_PTRACER_ANY (-1UL)
+
+#define PR_SET_CHILD_SUBREAPER  36
+#define PR_GET_CHILD_SUBREAPER  37
+
+#define PR_SET_NO_NEW_PRIVS     38
+#define PR_GET_NO_NEW_PRIVS     39
+
+#define PR_GET_TID_ADDRESS      40
+
+#define PR_SET_THP_DISABLE      41
+#define PR_GET_THP_DISABLE      42
+
+#define PR_MPX_ENABLE_MANAGEMENT  43
+#define PR_MPX_DISABLE_MANAGEMENT 44
+
+#define PR_SET_FP_MODE          45
+#define PR_GET_FP_MODE          46
+#define PR_FP_MODE_FR (1 << 0)
+#define PR_FP_MODE_FRE (1 << 1)
+
+#define PR_CAP_AMBIENT          47
+#define PR_CAP_AMBIENT_IS_SET   1
+#define PR_CAP_AMBIENT_RAISE    2
+#define PR_CAP_AMBIENT_LOWER    3
+#define PR_CAP_AMBIENT_CLEAR_ALL 4
+
+int prctl (int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/procfs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/procfs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/procfs.h	(revision 398)
@@ -0,0 +1,64 @@
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+struct elf_siginfo {
+	int si_signo;
+	int si_code;
+	int si_errno;
+};
+
+struct elf_prstatus {
+	struct elf_siginfo pr_info;
+	short int pr_cursig;
+	unsigned long int pr_sigpend;
+	unsigned long int pr_sighold;
+	pid_t pr_pid;
+	pid_t pr_ppid;
+	pid_t pr_pgrp;
+	pid_t pr_sid;
+	struct timeval pr_utime;
+	struct timeval pr_stime;
+	struct timeval pr_cutime;
+	struct timeval pr_cstime;
+	elf_gregset_t pr_reg;
+	int pr_fpvalid;
+};
+
+#define ELF_PRARGSZ 80
+
+struct elf_prpsinfo {
+	char pr_state;
+	char pr_sname;
+	char pr_zomb;
+	char pr_nice;
+	unsigned long int pr_flag;
+#if UINTPTR_MAX == 0xffffffff
+	unsigned short int pr_uid;
+	unsigned short int pr_gid;
+#else
+	unsigned int pr_uid;
+	unsigned int pr_gid;
+#endif
+	int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+	char pr_fname[16];
+	char pr_psargs[ELF_PRARGSZ];
+};
+
+typedef void *psaddr_t;
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+typedef pid_t lwpid_t;
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ptrace.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ptrace.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ptrace.h	(revision 398)
@@ -0,0 +1,100 @@
+#ifndef _SYS_PTRACE_H
+#define _SYS_PTRACE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define PTRACE_TRACEME 0
+#define PT_TRACE_ME PTRACE_TRACEME
+
+#define PTRACE_PEEKTEXT 1
+#define PTRACE_PEEKDATA 2
+#define PTRACE_PEEKUSER 3
+#define PTRACE_POKETEXT 4
+#define PTRACE_POKEDATA 5
+#define PTRACE_POKEUSER 6
+#define PTRACE_CONT 7
+#define PTRACE_KILL 8
+#define PTRACE_SINGLESTEP 9
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+#define PTRACE_ATTACH 16
+#define PTRACE_DETACH 17
+#define PTRACE_GETFPXREGS 18
+#define PTRACE_SETFPXREGS 19
+#define PTRACE_SYSCALL 24
+#define PTRACE_SETOPTIONS 0x4200
+#define PTRACE_GETEVENTMSG 0x4201
+#define PTRACE_GETSIGINFO 0x4202
+#define PTRACE_SETSIGINFO 0x4203
+#define PTRACE_GETREGSET 0x4204
+#define PTRACE_SETREGSET 0x4205
+#define PTRACE_SEIZE 0x4206
+#define PTRACE_INTERRUPT 0x4207
+#define PTRACE_LISTEN 0x4208
+#define PTRACE_PEEKSIGINFO 0x4209
+#define PTRACE_GETSIGMASK 0x420a
+#define PTRACE_SETSIGMASK 0x420b
+#define PTRACE_SECCOMP_GET_FILTER 0x420c
+
+#define PT_READ_I PTRACE_PEEKTEXT
+#define PT_READ_D PTRACE_PEEKDATA
+#define PT_READ_U PTRACE_PEEKUSER
+#define PT_WRITE_I PTRACE_POKETEXT
+#define PT_WRITE_D PTRACE_POKEDATA
+#define PT_WRITE_U PTRACE_POKEUSER
+#define PT_CONTINUE PTRACE_CONT
+#define PT_KILL PTRACE_KILL
+#define PT_STEP PTRACE_SINGLESTEP
+#define PT_GETREGS PTRACE_GETREGS
+#define PT_SETREGS PTRACE_SETREGS
+#define PT_GETFPREGS PTRACE_GETFPREGS
+#define PT_SETFPREGS PTRACE_SETFPREGS
+#define PT_ATTACH PTRACE_ATTACH
+#define PT_DETACH PTRACE_DETACH
+#define PT_GETFPXREGS PTRACE_GETFPXREGS
+#define PT_SETFPXREGS PTRACE_SETFPXREGS
+#define PT_SYSCALL PTRACE_SYSCALL
+#define PT_SETOPTIONS PTRACE_SETOPTIONS
+#define PT_GETEVENTMSG PTRACE_GETEVENTMSG
+#define PT_GETSIGINFO PTRACE_GETSIGINFO
+#define PT_SETSIGINFO PTRACE_SETSIGINFO
+
+#define PTRACE_O_TRACESYSGOOD   0x00000001
+#define PTRACE_O_TRACEFORK      0x00000002
+#define PTRACE_O_TRACEVFORK     0x00000004
+#define PTRACE_O_TRACECLONE     0x00000008
+#define PTRACE_O_TRACEEXEC      0x00000010
+#define PTRACE_O_TRACEVFORKDONE 0x00000020
+#define PTRACE_O_TRACEEXIT      0x00000040
+#define PTRACE_O_TRACESECCOMP   0x00000080
+#define PTRACE_O_EXITKILL       0x00100000
+#define PTRACE_O_SUSPEND_SECCOMP 0x00200000
+#define PTRACE_O_MASK           0x003000ff
+
+#define PTRACE_EVENT_FORK 1
+#define PTRACE_EVENT_VFORK 2
+#define PTRACE_EVENT_CLONE 3
+#define PTRACE_EVENT_EXEC 4
+#define PTRACE_EVENT_VFORK_DONE 5
+#define PTRACE_EVENT_EXIT 6
+#define PTRACE_EVENT_SECCOMP 7
+
+#define PTRACE_PEEKSIGINFO_SHARED 1
+
+struct ptrace_peeksiginfo_args {
+	uint64_t off;
+	uint32_t flags;
+	int32_t nr;
+};
+
+long ptrace(int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/quota.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/quota.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/quota.h	(revision 398)
@@ -0,0 +1,102 @@
+#ifndef _SYS_QUOTA_H
+#define _SYS_QUOTA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define _LINUX_QUOTA_VERSION 2
+
+#define dbtob(num) ((num) << 10)
+#define btodb(num) ((num) >> 10)
+#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / 1024)
+
+#define MAX_IQ_TIME 604800
+#define MAX_DQ_TIME 604800
+
+#define MAXQUOTAS 2
+#define USRQUOTA  0
+#define GRPQUOTA  1
+
+#define INITQFNAMES { "user", "group", "undefined" };
+
+#define QUOTAFILENAME "quota"
+#define QUOTAGROUP "staff"
+
+#define NR_DQHASH 43
+#define NR_DQUOTS 256
+
+#define SUBCMDMASK       0x00ff
+#define SUBCMDSHIFT      8
+#define QCMD(cmd, type)  (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
+
+#define Q_SYNC     0x800001
+#define Q_QUOTAON  0x800002
+#define Q_QUOTAOFF 0x800003
+#define Q_GETFMT   0x800004
+#define Q_GETINFO  0x800005
+#define Q_SETINFO  0x800006
+#define Q_GETQUOTA 0x800007
+#define Q_SETQUOTA 0x800008
+
+#define	QFMT_VFS_OLD 1
+#define	QFMT_VFS_V0 2
+#define QFMT_OCFS2 3
+#define	QFMT_VFS_V1 4
+
+#define QIF_BLIMITS	1
+#define QIF_SPACE	2
+#define QIF_ILIMITS	4
+#define QIF_INODES	8
+#define QIF_BTIME	16
+#define QIF_ITIME	32
+#define QIF_LIMITS	(QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE	(QIF_SPACE | QIF_INODES)
+#define QIF_TIMES	(QIF_BTIME | QIF_ITIME)
+#define QIF_ALL		(QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+
+struct dqblk {
+	uint64_t dqb_bhardlimit;
+	uint64_t dqb_bsoftlimit;
+	uint64_t dqb_curspace;
+	uint64_t dqb_ihardlimit;
+	uint64_t dqb_isoftlimit;
+	uint64_t dqb_curinodes;
+	uint64_t dqb_btime;
+	uint64_t dqb_itime;
+	uint32_t dqb_valid;
+};
+
+#define	dq_bhardlimit	dq_dqb.dqb_bhardlimit
+#define	dq_bsoftlimit	dq_dqb.dqb_bsoftlimit
+#define dq_curspace	dq_dqb.dqb_curspace
+#define dq_valid	dq_dqb.dqb_valid
+#define	dq_ihardlimit	dq_dqb.dqb_ihardlimit
+#define	dq_isoftlimit	dq_dqb.dqb_isoftlimit
+#define	dq_curinodes	dq_dqb.dqb_curinodes
+#define	dq_btime	dq_dqb.dqb_btime
+#define	dq_itime	dq_dqb.dqb_itime
+
+#define dqoff(UID)      ((long long)(UID) * sizeof (struct dqblk))
+
+#define IIF_BGRACE	1
+#define IIF_IGRACE	2
+#define IIF_FLAGS	4
+#define IIF_ALL		(IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+
+struct dqinfo {
+	uint64_t dqi_bgrace;
+	uint64_t dqi_igrace;
+	uint32_t dqi_flags;
+	uint32_t dqi_valid;
+};
+
+int quotactl(int, const char *, int, char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/reboot.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/reboot.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/reboot.h	(revision 398)
@@ -0,0 +1,20 @@
+#ifndef _SYS_REBOOT_H
+#define _SYS_REBOOT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RB_AUTOBOOT     0x01234567
+#define RB_HALT_SYSTEM  0xcdef0123
+#define RB_ENABLE_CAD   0x89abcdef
+#define RB_DISABLE_CAD  0
+#define RB_POWER_OFF    0x4321fedc
+#define RB_SW_SUSPEND   0xd000fce2
+#define RB_KEXEC        0x45584543
+
+int reboot(int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/reg.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/reg.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/reg.h	(revision 398)
@@ -0,0 +1,9 @@
+#ifndef _SYS_REG_H
+#define _SYS_REG_H
+
+#include <limits.h>
+#include <unistd.h>
+
+#include <bits/reg.h>
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/resource.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/resource.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/resource.h	(revision 398)
@@ -0,0 +1,111 @@
+#ifndef	_SYS_RESOURCE_H
+#define	_SYS_RESOURCE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <sys/time.h>
+
+#define __NEED_id_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_pid_t
+#endif
+
+#include <bits/alltypes.h>
+#include <bits/resource.h>
+
+typedef unsigned long long rlim_t;
+
+struct rlimit {
+	rlim_t rlim_cur;
+	rlim_t rlim_max;
+};
+
+struct rusage {
+	struct timeval ru_utime;
+	struct timeval ru_stime;
+	/* linux extentions, but useful */
+	long	ru_maxrss;
+	long	ru_ixrss;
+	long	ru_idrss;
+	long	ru_isrss;
+	long	ru_minflt;
+	long	ru_majflt;
+	long	ru_nswap;
+	long	ru_inblock;
+	long	ru_oublock;
+	long	ru_msgsnd;
+	long	ru_msgrcv;
+	long	ru_nsignals;
+	long	ru_nvcsw;
+	long	ru_nivcsw;
+	/* room for more... */
+	long    __reserved[16];
+};
+
+int getrlimit (int, struct rlimit *);
+int setrlimit (int, const struct rlimit *);
+int getrusage (int, struct rusage *);
+
+int getpriority (int, id_t);
+int setpriority (int, id_t, int);
+
+#ifdef _GNU_SOURCE
+int prlimit(pid_t, int, const struct rlimit *, struct rlimit *);
+#define prlimit64 prlimit
+#endif
+
+#define PRIO_MIN (-20)
+#define PRIO_MAX 20
+
+#define PRIO_PROCESS 0
+#define PRIO_PGRP    1
+#define PRIO_USER    2
+
+#define RUSAGE_SELF     0
+#define RUSAGE_CHILDREN (-1)
+#define RUSAGE_THREAD   1
+
+#define RLIM_INFINITY (~0ULL)
+#define RLIM_SAVED_CUR RLIM_INFINITY
+#define RLIM_SAVED_MAX RLIM_INFINITY
+
+#define RLIMIT_CPU     0
+#define RLIMIT_FSIZE   1
+#define RLIMIT_DATA    2
+#define RLIMIT_STACK   3
+#define RLIMIT_CORE    4
+#ifndef RLIMIT_RSS
+#define RLIMIT_RSS     5
+#define RLIMIT_NPROC   6
+#define RLIMIT_NOFILE  7
+#define RLIMIT_MEMLOCK 8
+#define RLIMIT_AS      9
+#endif
+#define RLIMIT_LOCKS   10
+#define RLIMIT_SIGPENDING 11
+#define RLIMIT_MSGQUEUE 12
+#define RLIMIT_NICE    13
+#define RLIMIT_RTPRIO  14
+#define RLIMIT_NLIMITS 15
+
+#define RLIM_NLIMITS RLIMIT_NLIMITS
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define RLIM64_INFINITY RLIM_INFINITY
+#define RLIM64_SAVED_CUR RLIM_SAVED_CUR
+#define RLIM64_SAVED_MAX RLIM_SAVED_MAX
+#define getrlimit64 getrlimit
+#define setrlimit64 setrlimit
+#define rlimit64 rlimit
+#define rlim64_t rlim_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/select.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/select.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/select.h	(revision 398)
@@ -0,0 +1,41 @@
+#ifndef _SYS_SELECT_H
+#define _SYS_SELECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_time_t
+#define __NEED_suseconds_t
+#define __NEED_struct_timeval
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define FD_SETSIZE 32
+
+typedef unsigned long fd_mask;
+
+typedef struct {
+	unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)];
+} fd_set;
+
+#define FD_ZERO(s) do { int __i; unsigned long *__b=(s)->fds_bits; for(__i=sizeof (fd_set)/sizeof (long); __i; __i--) *__b++=0; } while(0)
+#define FD_SET(d, s)   ((s)->fds_bits[(d)/(8*sizeof(long))] |= (1UL<<((d)%(8*sizeof(long)))))
+#define FD_CLR(d, s)   ((s)->fds_bits[(d)/(8*sizeof(long))] &= ~(1UL<<((d)%(8*sizeof(long)))))
+#define FD_ISSET(d, s) !!((s)->fds_bits[(d)/(8*sizeof(long))] & (1UL<<((d)%(8*sizeof(long)))))
+
+int select (int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, struct timeval *__restrict);
+int pselect (int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, const struct timespec *__restrict, const sigset_t *__restrict);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define NFDBITS (8*(int)sizeof(long))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sem.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sem.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sem.h	(revision 398)
@@ -0,0 +1,67 @@
+#ifndef _SYS_SEM_H
+#define _SYS_SEM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_pid_t
+#define __NEED_time_t
+#ifdef _GNU_SOURCE
+#define __NEED_struct_timespec
+#endif
+#include <bits/alltypes.h>
+
+#include <sys/ipc.h>
+
+#define SEM_UNDO	0x1000
+#define GETPID		11
+#define GETVAL		12
+#define GETALL		13
+#define GETNCNT		14
+#define GETZCNT		15
+#define SETVAL		16
+#define SETALL		17
+
+#include <endian.h>
+
+#include <bits/sem.h>
+
+#define _SEM_SEMUN_UNDEFINED 1
+
+#define SEM_STAT 18
+#define SEM_INFO 19
+
+struct  seminfo {
+	int semmap;
+	int semmni;
+	int semmns;
+	int semmnu;
+	int semmsl;
+	int semopm;
+	int semume;
+	int semusz;
+	int semvmx;
+	int semaem;
+};
+
+struct sembuf {
+	unsigned short sem_num;
+	short sem_op;
+	short sem_flg;
+};
+
+int semctl(int, int, int, ...);
+int semget(key_t, int, int);
+int semop(int, struct sembuf *, size_t);
+
+#ifdef _GNU_SOURCE
+int semtimedop(int, struct sembuf *, size_t, const struct timespec *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sendfile.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sendfile.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sendfile.h	(revision 398)
@@ -0,0 +1,22 @@
+#ifndef _SYS_SENDFILE_H
+#define _SYS_SENDFILE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <unistd.h>
+
+ssize_t sendfile(int, int, off_t *, size_t);
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define sendfile64 sendfile
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/shm.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/shm.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/shm.h	(revision 398)
@@ -0,0 +1,54 @@
+#ifndef _SYS_SHM_H
+#define _SYS_SHM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_time_t
+#define __NEED_size_t
+#define __NEED_pid_t
+
+#include <bits/alltypes.h>
+
+#include <sys/ipc.h>
+
+#ifdef _GNU_SOURCE
+#define __used_ids used_ids
+#define __swap_attempts swap_attempts
+#define __swap_successes swap_successes
+#endif
+
+#include <bits/shm.h>
+
+#define SHM_R 0400
+#define SHM_W 0200
+
+#define SHM_RDONLY 010000
+#define SHM_RND    020000
+#define SHM_REMAP  040000
+#define SHM_EXEC   0100000
+
+#define SHM_LOCK 11
+#define SHM_UNLOCK 12
+#define SHM_STAT 13
+#define SHM_INFO 14
+#define SHM_DEST 01000
+#define SHM_LOCKED 02000
+#define SHM_HUGETLB 04000
+#define SHM_NORESERVE 010000
+
+typedef unsigned long shmatt_t;
+
+void *shmat(int, const void *, int);
+int shmctl(int, int, struct shmid_ds *);
+int shmdt(const void *);
+int shmget(key_t, size_t, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/signal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/signal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/signal.h	(revision 398)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/signal.h> to <signal.h>
+#include <signal.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/signalfd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/signalfd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/signalfd.h	(revision 398)
@@ -0,0 +1,45 @@
+#ifndef _SYS_SIGNALFD_H
+#define _SYS_SIGNALFD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <fcntl.h>
+
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define SFD_CLOEXEC O_CLOEXEC
+#define SFD_NONBLOCK O_NONBLOCK
+
+int signalfd(int, const sigset_t *, int);
+
+struct signalfd_siginfo {
+	uint32_t  ssi_signo;
+	int32_t   ssi_errno;
+	int32_t   ssi_code;
+	uint32_t  ssi_pid;
+	uint32_t  ssi_uid;
+	int32_t   ssi_fd;
+	uint32_t  ssi_tid;
+	uint32_t  ssi_band;
+	uint32_t  ssi_overrun;
+	uint32_t  ssi_trapno;
+	int32_t   ssi_status;
+	int32_t   ssi_int;
+	uint64_t  ssi_ptr;
+	uint64_t  ssi_utime;
+	uint64_t  ssi_stime;
+	uint64_t  ssi_addr;
+	uint16_t  ssi_addr_lsb;
+	uint8_t   pad[128-12*4-4*8-2];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/socket.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/socket.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/socket.h	(revision 398)
@@ -0,0 +1,339 @@
+#ifndef	_SYS_SOCKET_H
+#define	_SYS_SOCKET_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_socklen_t
+#define __NEED_sa_family_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_uid_t
+#define __NEED_pid_t
+#define __NEED_gid_t
+#define __NEED_struct_iovec
+
+#include <bits/alltypes.h>
+
+#include <bits/socket.h>
+
+#ifdef _GNU_SOURCE
+struct ucred {
+	pid_t pid;
+	uid_t uid;
+	gid_t gid;
+};
+
+struct mmsghdr {
+	struct msghdr msg_hdr;
+	unsigned int  msg_len;
+};
+
+struct timespec;
+
+int sendmmsg (int, struct mmsghdr *, unsigned int, unsigned int);
+int recvmmsg (int, struct mmsghdr *, unsigned int, unsigned int, struct timespec *);
+#endif
+
+struct linger {
+	int l_onoff;
+	int l_linger;
+};
+
+#define SHUT_RD 0
+#define SHUT_WR 1
+#define SHUT_RDWR 2
+
+#ifndef SOCK_STREAM
+#define SOCK_STREAM    1
+#define SOCK_DGRAM     2
+#endif
+
+#define SOCK_RAW       3
+#define SOCK_RDM       4
+#define SOCK_SEQPACKET 5
+#define SOCK_DCCP      6
+#define SOCK_PACKET    10
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC   02000000
+#define SOCK_NONBLOCK  04000
+#endif
+
+#define PF_UNSPEC       0
+#define PF_LOCAL        1
+#define PF_UNIX         PF_LOCAL
+#define PF_FILE         PF_LOCAL
+#define PF_INET         2
+#define PF_AX25         3
+#define PF_IPX          4
+#define PF_APPLETALK    5
+#define PF_NETROM       6
+#define PF_BRIDGE       7
+#define PF_ATMPVC       8
+#define PF_X25          9
+#define PF_INET6        10
+#define PF_ROSE         11
+#define PF_DECnet       12
+#define PF_NETBEUI      13
+#define PF_SECURITY     14
+#define PF_KEY          15
+#define PF_NETLINK      16
+#define PF_ROUTE        PF_NETLINK
+#define PF_PACKET       17
+#define PF_ASH          18
+#define PF_ECONET       19
+#define PF_ATMSVC       20
+#define PF_RDS          21
+#define PF_SNA          22
+#define PF_IRDA         23
+#define PF_PPPOX        24
+#define PF_WANPIPE      25
+#define PF_LLC          26
+#define PF_IB           27
+#define PF_MPLS         28
+#define PF_CAN          29
+#define PF_TIPC         30
+#define PF_BLUETOOTH    31
+#define PF_IUCV         32
+#define PF_RXRPC        33
+#define PF_ISDN         34
+#define PF_PHONET       35
+#define PF_IEEE802154   36
+#define PF_CAIF         37
+#define PF_ALG          38
+#define PF_NFC          39
+#define PF_VSOCK        40
+#define PF_KCM          41
+#define PF_QIPCRTR      42
+#define PF_MAX          43
+
+#define AF_UNSPEC       PF_UNSPEC
+#define AF_LOCAL        PF_LOCAL
+#define AF_UNIX         AF_LOCAL
+#define AF_FILE         AF_LOCAL
+#define AF_INET         PF_INET
+#define AF_AX25         PF_AX25
+#define AF_IPX          PF_IPX
+#define AF_APPLETALK    PF_APPLETALK
+#define AF_NETROM       PF_NETROM
+#define AF_BRIDGE       PF_BRIDGE
+#define AF_ATMPVC       PF_ATMPVC
+#define AF_X25          PF_X25
+#define AF_INET6        PF_INET6
+#define AF_ROSE         PF_ROSE
+#define AF_DECnet       PF_DECnet
+#define AF_NETBEUI      PF_NETBEUI
+#define AF_SECURITY     PF_SECURITY
+#define AF_KEY          PF_KEY
+#define AF_NETLINK      PF_NETLINK
+#define AF_ROUTE        PF_ROUTE
+#define AF_PACKET       PF_PACKET
+#define AF_ASH          PF_ASH
+#define AF_ECONET       PF_ECONET
+#define AF_ATMSVC       PF_ATMSVC
+#define AF_RDS          PF_RDS
+#define AF_SNA          PF_SNA
+#define AF_IRDA         PF_IRDA
+#define AF_PPPOX        PF_PPPOX
+#define AF_WANPIPE      PF_WANPIPE
+#define AF_LLC          PF_LLC
+#define AF_IB           PF_IB
+#define AF_MPLS         PF_MPLS
+#define AF_CAN          PF_CAN
+#define AF_TIPC         PF_TIPC
+#define AF_BLUETOOTH    PF_BLUETOOTH
+#define AF_IUCV         PF_IUCV
+#define AF_RXRPC        PF_RXRPC
+#define AF_ISDN         PF_ISDN
+#define AF_PHONET       PF_PHONET
+#define AF_IEEE802154   PF_IEEE802154
+#define AF_CAIF         PF_CAIF
+#define AF_ALG          PF_ALG
+#define AF_NFC          PF_NFC
+#define AF_VSOCK        PF_VSOCK
+#define AF_KCM          PF_KCM
+#define AF_QIPCRTR      PF_QIPCRTR
+#define AF_MAX          PF_MAX
+
+#ifndef SO_DEBUG
+#define SO_DEBUG        1
+#define SO_REUSEADDR    2
+#define SO_TYPE         3
+#define SO_ERROR        4
+#define SO_DONTROUTE    5
+#define SO_BROADCAST    6
+#define SO_SNDBUF       7
+#define SO_RCVBUF       8
+#define SO_KEEPALIVE    9
+#define SO_OOBINLINE    10
+#define SO_NO_CHECK     11
+#define SO_PRIORITY     12
+#define SO_LINGER       13
+#define SO_BSDCOMPAT    14
+#define SO_REUSEPORT    15
+#define SO_PASSCRED     16
+#define SO_PEERCRED     17
+#define SO_RCVLOWAT     18
+#define SO_SNDLOWAT     19
+#define SO_RCVTIMEO     20
+#define SO_SNDTIMEO     21
+#define SO_ACCEPTCONN   30
+#define SO_SNDBUFFORCE  32
+#define SO_RCVBUFFORCE  33
+#define SO_PROTOCOL     38
+#define SO_DOMAIN       39
+#endif
+
+#define SO_SECURITY_AUTHENTICATION              22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT        23
+#define SO_SECURITY_ENCRYPTION_NETWORK          24
+
+#define SO_BINDTODEVICE 25
+
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+#define SO_GET_FILTER           SO_ATTACH_FILTER
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP            29
+#define SCM_TIMESTAMP           SO_TIMESTAMP
+
+#define SO_PEERSEC              31
+#define SO_PASSSEC              34
+#define SO_TIMESTAMPNS          35
+#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS
+#define SO_MARK                 36
+#define SO_TIMESTAMPING         37
+#define SCM_TIMESTAMPING        SO_TIMESTAMPING
+#define SO_RXQ_OVFL             40
+#define SO_WIFI_STATUS          41
+#define SCM_WIFI_STATUS         SO_WIFI_STATUS
+#define SO_PEEK_OFF             42
+#define SO_NOFCS                43
+#define SO_LOCK_FILTER          44
+#define SO_SELECT_ERR_QUEUE     45
+#define SO_BUSY_POLL            46
+#define SO_MAX_PACING_RATE      47
+#define SO_BPF_EXTENSIONS       48
+#define SO_INCOMING_CPU         49
+#define SO_ATTACH_BPF           50
+#define SO_DETACH_BPF           SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+#define SO_CNX_ADVICE           53
+
+#ifndef SOL_SOCKET
+#define SOL_SOCKET      1
+#endif
+
+#define SOL_IP          0
+#define SOL_IPV6        41
+#define SOL_ICMPV6      58
+
+#define SOL_RAW         255
+#define SOL_DECNET      261
+#define SOL_X25         262
+#define SOL_PACKET      263
+#define SOL_ATM         264
+#define SOL_AAL         265
+#define SOL_IRDA        266
+#define SOL_NETBEUI     267
+#define SOL_LLC         268
+#define SOL_DCCP        269
+#define SOL_NETLINK     270
+#define SOL_TIPC        271
+#define SOL_RXRPC       272
+#define SOL_PPPOL2TP    273
+#define SOL_BLUETOOTH   274
+#define SOL_PNPIPE      275
+#define SOL_RDS         276
+#define SOL_IUCV        277
+#define SOL_CAIF        278
+#define SOL_ALG         279
+#define SOL_NFC         280
+#define SOL_KCM         281
+
+#define SOMAXCONN       128
+
+#define MSG_OOB       0x0001
+#define MSG_PEEK      0x0002
+#define MSG_DONTROUTE 0x0004
+#define MSG_CTRUNC    0x0008
+#define MSG_PROXY     0x0010
+#define MSG_TRUNC     0x0020
+#define MSG_DONTWAIT  0x0040
+#define MSG_EOR       0x0080
+#define MSG_WAITALL   0x0100
+#define MSG_FIN       0x0200
+#define MSG_SYN       0x0400
+#define MSG_CONFIRM   0x0800
+#define MSG_RST       0x1000
+#define MSG_ERRQUEUE  0x2000
+#define MSG_NOSIGNAL  0x4000
+#define MSG_MORE      0x8000
+#define MSG_WAITFORONE 0x10000
+#define MSG_BATCH     0x40000
+#define MSG_FASTOPEN  0x20000000
+#define MSG_CMSG_CLOEXEC 0x40000000
+
+#define __CMSG_LEN(cmsg) (((cmsg)->cmsg_len + sizeof(long) - 1) & ~(long)(sizeof(long) - 1))
+#define __CMSG_NEXT(cmsg) ((unsigned char *)(cmsg) + __CMSG_LEN(cmsg))
+#define __MHDR_END(mhdr) ((unsigned char *)(mhdr)->msg_control + (mhdr)->msg_controllen)
+
+#define CMSG_DATA(cmsg) ((unsigned char *) (((struct cmsghdr *)(cmsg)) + 1))
+#define CMSG_NXTHDR(mhdr, cmsg) ((cmsg)->cmsg_len < sizeof (struct cmsghdr) || \
+	__CMSG_LEN(cmsg) + sizeof(struct cmsghdr) >= __MHDR_END(mhdr) - (unsigned char *)(cmsg) \
+	? 0 : (struct cmsghdr *)__CMSG_NEXT(cmsg))
+#define CMSG_FIRSTHDR(mhdr) ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)
+
+#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1))
+#define CMSG_SPACE(len) (CMSG_ALIGN (len) + CMSG_ALIGN (sizeof (struct cmsghdr)))
+#define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+
+#define SCM_RIGHTS      0x01
+#define SCM_CREDENTIALS 0x02
+
+struct sockaddr {
+	sa_family_t sa_family;
+	char sa_data[14];
+};
+
+struct sockaddr_storage {
+	sa_family_t ss_family;
+	char __ss_padding[128-sizeof(long)-sizeof(sa_family_t)];
+	unsigned long __ss_align;
+};
+
+int socket (int, int, int);
+int socketpair (int, int, int, int [2]);
+
+int shutdown (int, int);
+
+int bind (int, const struct sockaddr *, socklen_t);
+int connect (int, const struct sockaddr *, socklen_t);
+int listen (int, int);
+int accept (int, struct sockaddr *__restrict, socklen_t *__restrict);
+int accept4(int, struct sockaddr *__restrict, socklen_t *__restrict, int);
+
+int getsockname (int, struct sockaddr *__restrict, socklen_t *__restrict);
+int getpeername (int, struct sockaddr *__restrict, socklen_t *__restrict);
+
+ssize_t send (int, const void *, size_t, int);
+ssize_t recv (int, void *, size_t, int);
+ssize_t sendto (int, const void *, size_t, int, const struct sockaddr *, socklen_t);
+ssize_t recvfrom (int, void *__restrict, size_t, int, struct sockaddr *__restrict, socklen_t *__restrict);
+ssize_t sendmsg (int, const struct msghdr *, int);
+ssize_t recvmsg (int, struct msghdr *, int);
+
+int getsockopt (int, int, int, void *__restrict, socklen_t *__restrict);
+int setsockopt (int, int, int, const void *, socklen_t);
+
+int sockatmark (int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/soundcard.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/soundcard.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/soundcard.h	(revision 398)
@@ -0,0 +1,1 @@
+#include <linux/soundcard.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/stat.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/stat.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/stat.h	(revision 398)
@@ -0,0 +1,118 @@
+#ifndef	_SYS_STAT_H
+#define	_SYS_STAT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_dev_t
+#define __NEED_ino_t
+#define __NEED_mode_t
+#define __NEED_nlink_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_off_t
+#define __NEED_time_t
+#define __NEED_blksize_t
+#define __NEED_blkcnt_t
+#define __NEED_struct_timespec
+
+#include <bits/alltypes.h>
+
+#include <bits/stat.h>
+
+#define st_atime st_atim.tv_sec
+#define st_mtime st_mtim.tv_sec
+#define st_ctime st_ctim.tv_sec
+
+#define S_IFMT  0170000
+
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFBLK 0060000
+#define S_IFREG 0100000
+#define S_IFIFO 0010000
+#define S_IFLNK 0120000
+#define S_IFSOCK 0140000
+
+#define S_TYPEISMQ(buf)  0
+#define S_TYPEISSEM(buf) 0
+#define S_TYPEISSHM(buf) 0
+#define S_TYPEISTMO(buf) 0
+
+#define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)
+#define S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
+#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
+#define S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
+#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
+
+#ifndef S_IRUSR
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXU 0700
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IRWXG 0070
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#define S_IRWXO 0007
+#endif
+
+#define UTIME_NOW  0x3fffffff
+#define UTIME_OMIT 0x3ffffffe
+
+int stat(const char *__restrict, struct stat *__restrict);
+int fstat(int, struct stat *);
+int lstat(const char *__restrict, struct stat *__restrict);
+int fstatat(int, const char *__restrict, struct stat *__restrict, int);
+int chmod(const char *, mode_t);
+int fchmod(int, mode_t);
+int fchmodat(int, const char *, mode_t, int);
+mode_t umask(mode_t);
+int mkdir(const char *, mode_t);
+int mkfifo(const char *, mode_t);
+int mkdirat(int, const char *, mode_t);
+int mkfifoat(int, const char *, mode_t);
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int mknod(const char *, mode_t, dev_t);
+int mknodat(int, const char *, mode_t, dev_t);
+#endif
+
+int futimens(int, const struct timespec [2]);
+int utimensat(int, const char *, const struct timespec [2], int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int lchmod(const char *, mode_t);
+#define S_IREAD S_IRUSR
+#define S_IWRITE S_IWUSR
+#define S_IEXEC S_IXUSR
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define stat64 stat
+#define fstat64 fstat
+#define lstat64 lstat
+#define fstatat64 fstatat
+#define blkcnt64_t blkcnt_t
+#define fsblkcnt64_t fsblkcnt_t
+#define fsfilcnt64_t fsfilcnt_t
+#define ino64_t ino_t
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/statfs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/statfs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/statfs.h	(revision 398)
@@ -0,0 +1,32 @@
+#ifndef	_SYS_STATFS_H
+#define	_SYS_STATFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <sys/statvfs.h>
+
+typedef struct __fsid_t {
+	int __val[2];
+} fsid_t;
+
+#include <bits/statfs.h>
+
+int statfs (const char *, struct statfs *);
+int fstatfs (int, struct statfs *);
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define statfs64 statfs
+#define fstatfs64 fstatfs
+#define fsblkcnt64_t fsblkcnt_t
+#define fsfilcnt64_t fsfilcnt_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/statvfs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/statvfs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/statvfs.h	(revision 398)
@@ -0,0 +1,57 @@
+#ifndef	_SYS_STATVFS_H
+#define	_SYS_STATVFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_fsblkcnt_t
+#define __NEED_fsfilcnt_t
+#include <bits/alltypes.h>
+
+#include <endian.h>
+
+struct statvfs {
+	unsigned long f_bsize, f_frsize;
+	fsblkcnt_t f_blocks, f_bfree, f_bavail;
+	fsfilcnt_t f_files, f_ffree, f_favail;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned long f_fsid;
+	unsigned :8*(2*sizeof(int)-sizeof(long));
+#else
+	unsigned :8*(2*sizeof(int)-sizeof(long));
+	unsigned long f_fsid;
+#endif
+	unsigned long f_flag, f_namemax;
+	int __reserved[6];
+};
+
+int statvfs (const char *__restrict, struct statvfs *__restrict);
+int fstatvfs (int, struct statvfs *);
+
+#define ST_RDONLY 1
+#define ST_NOSUID 2
+#define ST_NODEV  4
+#define ST_NOEXEC 8
+#define ST_SYNCHRONOUS 16
+#define ST_MANDLOCK    64
+#define ST_WRITE       128
+#define ST_APPEND      256
+#define ST_IMMUTABLE   512
+#define ST_NOATIME     1024
+#define ST_NODIRATIME  2048
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define statvfs64 statvfs
+#define fstatvfs64 fstatvfs
+#define fsblkcnt64_t fsblkcnt_t
+#define fsfilcnt64_t fsfilcnt_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/stropts.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/stropts.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/stropts.h	(revision 398)
@@ -0,0 +1,1 @@
+#include <stropts.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/swap.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/swap.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/swap.h	(revision 398)
@@ -0,0 +1,21 @@
+#ifndef _SYS_SWAP_H
+#define _SYS_SWAP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define	SWAP_FLAG_PREFER        0x8000
+#define	SWAP_FLAG_PRIO_MASK     0x7fff
+#define	SWAP_FLAG_PRIO_SHIFT    0
+#define SWAP_FLAG_DISCARD       0x10000
+
+int swapon (const char *, int);
+int swapoff (const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/syscall.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/syscall.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/syscall.h	(revision 398)
@@ -0,0 +1,6 @@
+#ifndef _SYS_SYSCALL_H
+#define _SYS_SYSCALL_H
+
+#include <bits/syscall.h>
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sysinfo.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sysinfo.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sysinfo.h	(revision 398)
@@ -0,0 +1,36 @@
+#ifndef _SYS_SYSINFO_H
+#define _SYS_SYSINFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SI_LOAD_SHIFT 16
+
+struct sysinfo {
+	unsigned long uptime;
+	unsigned long loads[3];
+	unsigned long totalram;
+	unsigned long freeram;
+	unsigned long sharedram;
+	unsigned long bufferram;
+	unsigned long totalswap;
+	unsigned long freeswap;
+	unsigned short procs, pad;
+	unsigned long totalhigh;
+	unsigned long freehigh;
+	unsigned mem_unit;
+	char __reserved[256];
+};
+
+int sysinfo (struct sysinfo *);
+int get_nprocs_conf (void);
+int get_nprocs (void);
+long get_phys_pages (void);
+long get_avphys_pages (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/syslog.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/syslog.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/syslog.h	(revision 398)
@@ -0,0 +1,1 @@
+#include <syslog.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sysmacros.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sysmacros.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/sysmacros.h	(revision 398)
@@ -0,0 +1,15 @@
+#ifndef _SYS_SYSMACROS_H
+#define _SYS_SYSMACROS_H
+
+#define major(x) \
+	((unsigned)( (((x)>>31>>1) & 0xfffff000) | (((x)>>8) & 0x00000fff) ))
+#define minor(x) \
+	((unsigned)( (((x)>>12) & 0xffffff00) | ((x) & 0x000000ff) ))
+
+#define makedev(x,y) ( \
+        (((x)&0xfffff000ULL) << 32) | \
+	(((x)&0x00000fffULL) << 8) | \
+        (((y)&0xffffff00ULL) << 12) | \
+	(((y)&0x000000ffULL)) )
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/termios.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/termios.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/termios.h	(revision 398)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/termios.h> to <termios.h>
+#include <termios.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/time.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/time.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/time.h	(revision 398)
@@ -0,0 +1,62 @@
+#ifndef _SYS_TIME_H
+#define _SYS_TIME_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <sys/select.h>
+
+int gettimeofday (struct timeval *__restrict, void *__restrict);
+
+#define ITIMER_REAL    0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF    2
+
+struct itimerval {
+	struct timeval it_interval;
+	struct timeval it_value;
+};
+
+int getitimer (int, struct itimerval *);
+int setitimer (int, const struct itimerval *__restrict, struct itimerval *__restrict);
+int utimes (const char *, const struct timeval [2]);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct timezone {
+	int tz_minuteswest;
+	int tz_dsttime;
+};
+int futimes(int, const struct timeval [2]);
+int futimesat(int, const char *, const struct timeval [2]);
+int lutimes(const char *, const struct timeval [2]);
+int settimeofday(const struct timeval *, const struct timezone *);
+int adjtime (const struct timeval *, struct timeval *);
+#define timerisset(t) ((t)->tv_sec || (t)->tv_usec)
+#define timerclear(t) ((t)->tv_sec = (t)->tv_usec = 0)
+#define timercmp(s,t,op) ((s)->tv_sec == (t)->tv_sec ? \
+	(s)->tv_usec op (t)->tv_usec : (s)->tv_sec op (t)->tv_sec)
+#define timeradd(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec + (t)->tv_sec, \
+	((a)->tv_usec = (s)->tv_usec + (t)->tv_usec) >= 1000000 && \
+	((a)->tv_usec -= 1000000, (a)->tv_sec++) )
+#define timersub(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec - (t)->tv_sec, \
+	((a)->tv_usec = (s)->tv_usec - (t)->tv_usec) < 0 && \
+	((a)->tv_usec += 1000000, (a)->tv_sec--) )
+#endif
+
+#if defined(_GNU_SOURCE)
+#define TIMEVAL_TO_TIMESPEC(tv, ts) ( \
+	(ts)->tv_sec = (tv)->tv_sec, \
+	(ts)->tv_nsec = (tv)->tv_usec * 1000, \
+	(void)0 )
+#define TIMESPEC_TO_TIMEVAL(tv, ts) ( \
+	(tv)->tv_sec = (ts)->tv_sec, \
+	(tv)->tv_usec = (ts)->tv_nsec / 1000, \
+	(void)0 )
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/timeb.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/timeb.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/timeb.h	(revision 398)
@@ -0,0 +1,22 @@
+#ifndef _SYS_TIMEB_H
+#define _SYS_TIMEB_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_time_t
+
+#include <bits/alltypes.h>
+
+struct timeb {
+	time_t time;
+	unsigned short millitm;
+	short timezone, dstflag;
+};
+
+int ftime(struct timeb *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/timerfd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/timerfd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/timerfd.h	(revision 398)
@@ -0,0 +1,26 @@
+#ifndef _SYS_TIMERFD_H
+#define _SYS_TIMERFD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+#include <fcntl.h>
+
+#define TFD_NONBLOCK O_NONBLOCK
+#define TFD_CLOEXEC O_CLOEXEC
+
+#define TFD_TIMER_ABSTIME 1
+
+struct itimerspec;
+
+int timerfd_create(int, int);
+int timerfd_settime(int, int, const struct itimerspec *, struct itimerspec *);
+int timerfd_gettime(int, struct itimerspec *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/times.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/times.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/times.h	(revision 398)
@@ -0,0 +1,25 @@
+#ifndef	_SYS_TIMES_H
+#define	_SYS_TIMES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_clock_t
+#include <bits/alltypes.h>
+
+struct tms {
+	clock_t tms_utime;
+	clock_t tms_stime;
+	clock_t tms_cutime;
+	clock_t tms_cstime;
+};
+
+clock_t times (struct tms *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/timex.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/timex.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/timex.h	(revision 398)
@@ -0,0 +1,98 @@
+#ifndef _SYS_TIMEX_H
+#define _SYS_TIMEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_clockid_t
+
+#include <bits/alltypes.h>
+
+#include <sys/time.h>
+
+struct ntptimeval {
+	struct timeval time;
+	long maxerror, esterror;
+};
+
+struct timex {
+	unsigned modes;
+	long offset, freq, maxerror, esterror;
+	int status;
+	long constant, precision, tolerance;
+	struct timeval time;
+	long tick, ppsfreq, jitter;
+	int shift;
+	long stabil, jitcnt, calcnt, errcnt, stbcnt;
+	int tai;
+	int __padding[11];
+};
+
+#define ADJ_OFFSET		0x0001
+#define ADJ_FREQUENCY		0x0002
+#define ADJ_MAXERROR		0x0004
+#define ADJ_ESTERROR		0x0008
+#define ADJ_STATUS		0x0010
+#define ADJ_TIMECONST		0x0020
+#define ADJ_TAI			0x0080
+#define ADJ_SETOFFSET		0x0100
+#define ADJ_MICRO		0x1000
+#define ADJ_NANO		0x2000
+#define ADJ_TICK		0x4000
+#define ADJ_OFFSET_SINGLESHOT	0x8001
+#define ADJ_OFFSET_SS_READ	0xa001
+
+#define MOD_OFFSET	ADJ_OFFSET
+#define MOD_FREQUENCY	ADJ_FREQUENCY
+#define MOD_MAXERROR	ADJ_MAXERROR
+#define MOD_ESTERROR	ADJ_ESTERROR
+#define MOD_STATUS	ADJ_STATUS
+#define MOD_TIMECONST	ADJ_TIMECONST
+#define MOD_CLKB	ADJ_TICK
+#define MOD_CLKA	ADJ_OFFSET_SINGLESHOT
+#define MOD_TAI		ADJ_TAI
+#define MOD_MICRO	ADJ_MICRO
+#define MOD_NANO	ADJ_NANO
+
+#define STA_PLL		0x0001
+#define STA_PPSFREQ	0x0002
+#define STA_PPSTIME	0x0004
+#define STA_FLL		0x0008
+
+#define STA_INS		0x0010
+#define STA_DEL		0x0020
+#define STA_UNSYNC	0x0040
+#define STA_FREQHOLD	0x0080
+
+#define STA_PPSSIGNAL	0x0100
+#define STA_PPSJITTER	0x0200
+#define STA_PPSWANDER	0x0400
+#define STA_PPSERROR	0x0800
+
+#define STA_CLOCKERR	0x1000
+#define STA_NANO	0x2000
+#define STA_MODE	0x4000
+#define STA_CLK		0x8000
+
+#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \
+    STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK)
+
+#define TIME_OK		0
+#define TIME_INS	1
+#define TIME_DEL	2
+#define TIME_OOP	3
+#define TIME_WAIT	4
+#define TIME_ERROR	5
+#define TIME_BAD	TIME_ERROR
+
+#define MAXTC		6
+
+int adjtimex(struct timex *);
+int clock_adjtime(clockid_t, struct timex *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ttydefaults.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ttydefaults.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ttydefaults.h	(revision 398)
@@ -0,0 +1,39 @@
+#ifndef _SYS_TTYDEFAULTS_H
+#define _SYS_TTYDEFAULTS_H
+
+#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY)
+#define TTYDEF_OFLAG (OPOST | ONLCR | XTABS)
+#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)
+#define TTYDEF_CFLAG (CREAD | CS7 | PARENB | HUPCL)
+#define TTYDEF_SPEED (B9600)
+#define CTRL(x) (x&037)
+#define CEOF CTRL('d')
+
+#ifdef _POSIX_VDISABLE
+#define CEOL _POSIX_VDISABLE
+#define CSTATUS _POSIX_VDISABLE
+#else
+#define CEOL '\0'
+#define CSTATUS '\0'
+#endif
+
+#define CERASE 0177
+#define CINTR CTRL('c')
+#define CKILL CTRL('u')
+#define CMIN 1
+#define CQUIT 034
+#define CSUSP CTRL('z')
+#define CTIME 0
+#define CDSUSP CTRL('y')
+#define CSTART CTRL('q')
+#define CSTOP CTRL('s')
+#define CLNEXT CTRL('v')
+#define CDISCARD CTRL('o')
+#define CWERASE CTRL('w')
+#define CREPRINT CTRL('r')
+#define CEOT CEOF
+#define CBRK CEOL
+#define CRPRNT CREPRINT
+#define CFLUSH CDISCARD
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/types.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/types.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/types.h	(revision 398)
@@ -0,0 +1,86 @@
+#ifndef	_SYS_TYPES_H
+#define	_SYS_TYPES_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ino_t
+#define __NEED_dev_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_mode_t
+#define __NEED_nlink_t
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_time_t
+#define __NEED_timer_t
+#define __NEED_clockid_t
+
+#define __NEED_blkcnt_t
+#define __NEED_fsblkcnt_t
+#define __NEED_fsfilcnt_t
+
+#define __NEED_id_t
+#define __NEED_key_t
+#define __NEED_clock_t
+#define __NEED_suseconds_t
+#define __NEED_blksize_t
+
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_pthread_mutexattr_t
+#define __NEED_pthread_condattr_t
+#define __NEED_pthread_rwlockattr_t
+#define __NEED_pthread_barrierattr_t
+#define __NEED_pthread_mutex_t
+#define __NEED_pthread_cond_t
+#define __NEED_pthread_rwlock_t
+#define __NEED_pthread_barrier_t
+#define __NEED_pthread_spinlock_t
+#define __NEED_pthread_key_t
+#define __NEED_pthread_once_t
+#define __NEED_useconds_t
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_int8_t
+#define __NEED_int16_t
+#define __NEED_int32_t
+#define __NEED_int64_t
+#define __NEED_u_int64_t
+#define __NEED_register_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned char u_int8_t;
+typedef unsigned short u_int16_t;
+typedef unsigned u_int32_t;
+typedef char *caddr_t;
+typedef unsigned char u_char;
+typedef unsigned short u_short, ushort;
+typedef unsigned u_int, uint;
+typedef unsigned long u_long, ulong;
+typedef long long quad_t;
+typedef unsigned long long u_quad_t;
+#include <endian.h>
+#include <sys/select.h>
+#include <sys/sysmacros.h>
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define blkcnt64_t blkcnt_t
+#define fsblkcnt64_t fsblkcnt_t
+#define fsfilcnt64_t fsfilcnt_t
+#define ino64_t ino_t
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ucontext.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ucontext.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/ucontext.h	(revision 398)
@@ -0,0 +1,1 @@
+#include <ucontext.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/uio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/uio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/uio.h	(revision 398)
@@ -0,0 +1,48 @@
+#ifndef _SYS_UIO_H
+#define _SYS_UIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_struct_iovec
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_off_t
+#endif
+
+#ifdef _GNU_SOURCE
+#define __NEED_pid_t
+#endif
+
+#include <bits/alltypes.h>
+
+#define UIO_MAXIOV 1024
+
+ssize_t readv (int, const struct iovec *, int);
+ssize_t writev (int, const struct iovec *, int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+ssize_t preadv (int, const struct iovec *, int, off_t);
+ssize_t pwritev (int, const struct iovec *, int, off_t);
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define preadv64 preadv
+#define pwritev64 pwritev
+#define off64_t off_t
+#endif
+#endif
+
+#ifdef _GNU_SOURCE
+ssize_t process_vm_writev(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);
+ssize_t process_vm_readv(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/un.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/un.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/un.h	(revision 398)
@@ -0,0 +1,31 @@
+#ifndef	_SYS_UN_H
+#define	_SYS_UN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_sa_family_t
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+struct sockaddr_un {
+	sa_family_t sun_family;
+	char sun_path[108];
+};
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+size_t strlen(const char *);
+#define SUN_LEN(s) (2+strlen((s)->sun_path))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/user.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/user.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/user.h	(revision 398)
@@ -0,0 +1,16 @@
+#ifndef _SYS_USER_H
+#define _SYS_USER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <limits.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <bits/user.h>
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/utsname.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/utsname.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/utsname.h	(revision 398)
@@ -0,0 +1,29 @@
+#ifndef	_SYS_UTSNAME_H
+#define	_SYS_UTSNAME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+struct utsname {
+	char sysname[65];
+	char nodename[65];
+	char release[65];
+	char version[65];
+	char machine[65];
+#ifdef _GNU_SOURCE
+	char domainname[65];
+#else
+	char __domainname[65];
+#endif
+};
+
+int uname (struct utsname *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/vfs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/vfs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/vfs.h	(revision 398)
@@ -0,0 +1,1 @@
+#include <sys/statfs.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/vt.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/vt.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/vt.h	(revision 398)
@@ -0,0 +1,1 @@
+#include <linux/vt.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/wait.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/wait.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/wait.h	(revision 398)
@@ -0,0 +1,59 @@
+#ifndef	_SYS_WAIT_H
+#define	_SYS_WAIT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_pid_t
+#define __NEED_id_t
+#include <bits/alltypes.h>
+
+typedef enum {
+	P_ALL = 0,
+	P_PID = 1,
+	P_PGID = 2
+} idtype_t;
+
+pid_t wait (int *);
+pid_t waitpid (pid_t, int *, int );
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#include <signal.h>
+int waitid (idtype_t, id_t, siginfo_t *, int);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <sys/resource.h>
+pid_t wait3 (int *, int, struct rusage *);
+pid_t wait4 (pid_t, int *, int, struct rusage *);
+#endif
+
+#define WNOHANG    1
+#define WUNTRACED  2
+
+#define WSTOPPED   2
+#define WEXITED    4
+#define WCONTINUED 8
+#define WNOWAIT    0x1000000
+
+#define __WNOTHREAD 0x20000000
+#define __WALL      0x40000000
+#define __WCLONE    0x80000000
+
+#define WEXITSTATUS(s) (((s) & 0xff00) >> 8)
+#define WTERMSIG(s) ((s) & 0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WCOREDUMP(s) ((s) & 0x80)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001)>>8) > 0x7f00)
+#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)
+#define WIFCONTINUED(s) ((s) == 0xffff)
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/xattr.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/xattr.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sys/xattr.h	(revision 398)
@@ -0,0 +1,30 @@
+#ifndef	_SYS_XATTR_H
+#define	_SYS_XATTR_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_ssize_t
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+#define XATTR_CREATE 1
+#define XATTR_REPLACE 2
+
+ssize_t getxattr(const char *, const char *, void *, size_t);
+ssize_t lgetxattr(const char *, const char *, void *, size_t);
+ssize_t fgetxattr(int, const char *, void *, size_t);
+ssize_t listxattr(const char *, char *, size_t);
+ssize_t llistxattr(const char *, char *, size_t);
+ssize_t flistxattr(int, char *, size_t);
+int setxattr(const char *, const char *, const void *, size_t, int);
+int lsetxattr(const char *, const char *, const void *, size_t, int);
+int fsetxattr(int, const char *, const void *, size_t, int);
+int removexattr(const char *, const char *);
+int lremovexattr(const char *, const char *);
+int fremovexattr(int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/syscall.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/syscall.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/syscall.h	(revision 398)
@@ -0,0 +1,1 @@
+#include <sys/syscall.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sysexits.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sysexits.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/sysexits.h	(revision 398)
@@ -0,0 +1,21 @@
+#ifndef	_SYSEXITS_H
+#define _SYSEXITS_H
+#define EX_OK 0
+#define EX__BASE 64
+#define EX_USAGE 64
+#define EX_DATAERR 65
+#define EX_NOINPUT 66
+#define EX_NOUSER 67
+#define EX_NOHOST 68
+#define EX_UNAVAILABLE 69
+#define EX_SOFTWARE 70
+#define EX_OSERR 71
+#define EX_OSFILE 72
+#define EX_CANTCREAT 73
+#define EX_IOERR 74
+#define EX_TEMPFAIL 75
+#define EX_PROTOCOL 76
+#define EX_NOPERM 77
+#define EX_CONFIG 78
+#define EX__MAX 78
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/syslog.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/syslog.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/syslog.h	(revision 398)
@@ -0,0 +1,100 @@
+#ifndef _SYSLOG_H
+#define _SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define LOG_EMERG   0
+#define LOG_ALERT   1
+#define LOG_CRIT    2
+#define LOG_ERR     3
+#define LOG_WARNING 4
+#define LOG_NOTICE  5
+#define LOG_INFO    6
+#define LOG_DEBUG   7
+
+#define LOG_PRIMASK 7
+#define LOG_PRI(p) ((p)&LOG_PRIMASK)
+#define	LOG_MAKEPRI(f, p) (((f)<<3)|(p))
+
+#define LOG_MASK(p) (1<<(p))
+#define LOG_UPTO(p) ((1<<((p)+1))-1)
+
+#define LOG_KERN     (0<<3)
+#define LOG_USER     (1<<3)
+#define LOG_MAIL     (2<<3)
+#define LOG_DAEMON   (3<<3)
+#define LOG_AUTH     (4<<3)
+#define LOG_SYSLOG   (5<<3)
+#define LOG_LPR      (6<<3)
+#define LOG_NEWS     (7<<3)
+#define LOG_UUCP     (8<<3)
+#define LOG_CRON     (9<<3)
+#define	LOG_AUTHPRIV (10<<3)
+#define	LOG_FTP      (11<<3)
+
+#define LOG_LOCAL0   (16<<3)
+#define LOG_LOCAL1   (17<<3)
+#define LOG_LOCAL2   (18<<3)
+#define LOG_LOCAL3   (19<<3)
+#define LOG_LOCAL4   (20<<3)
+#define LOG_LOCAL5   (21<<3)
+#define LOG_LOCAL6   (22<<3)
+#define LOG_LOCAL7   (23<<3)
+
+#define LOG_NFACILITIES 24
+#define LOG_FACMASK 0x3f8
+#define LOG_FAC(p) (((p)&LOG_FACMASK)>>3)
+
+#define LOG_PID    0x01
+#define LOG_CONS   0x02
+#define LOG_ODELAY 0x04
+#define LOG_NDELAY 0x08
+#define LOG_NOWAIT 0x10
+#define LOG_PERROR 0x20
+
+void closelog (void);
+void openlog (const char *, int, int);
+int setlogmask (int);
+void syslog (int, const char *, ...);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define _PATH_LOG "/dev/log"
+#define __NEED_va_list
+#include <bits/alltypes.h>
+void vsyslog (int, const char *, va_list);
+#if defined(SYSLOG_NAMES)
+#define	INTERNAL_NOPRI 0x10
+#define	INTERNAL_MARK (LOG_NFACILITIES<<3)
+typedef struct {
+	char *c_name;
+	int c_val;
+} CODE;
+#define prioritynames ((CODE *)(const CODE []){ \
+	{ "alert", LOG_ALERT }, { "crit", LOG_CRIT }, { "debug", LOG_DEBUG }, \
+	{ "emerg", LOG_EMERG }, { "err", LOG_ERR }, { "error", LOG_ERR }, \
+	{ "info", LOG_INFO }, { "none", INTERNAL_NOPRI }, \
+	{ "notice", LOG_NOTICE }, { "panic", LOG_EMERG }, \
+	{ "warn", LOG_WARNING }, { "warning", LOG_WARNING }, { 0, -1 } })
+#define facilitynames ((CODE *)(const CODE []){ \
+	{ "auth", LOG_AUTH }, { "authpriv", LOG_AUTHPRIV }, \
+	{ "cron", LOG_CRON }, { "daemon", LOG_DAEMON }, { "ftp", LOG_FTP }, \
+	{ "kern", LOG_KERN }, { "lpr", LOG_LPR }, { "mail", LOG_MAIL }, \
+	{ "mark", INTERNAL_MARK }, { "news", LOG_NEWS }, \
+	{ "security", LOG_AUTH }, { "syslog", LOG_SYSLOG }, \
+	{ "user", LOG_USER }, { "uucp", LOG_UUCP }, \
+	{ "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 }, \
+	{ "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 }, \
+	{ "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 }, \
+	{ "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, { 0, -1 } })
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/tar.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/tar.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/tar.h	(revision 398)
@@ -0,0 +1,33 @@
+#ifndef	_TAR_H
+#define	_TAR_H
+
+#define TSUID   04000
+#define TSGID   02000
+#define TSVTX   01000
+#define TUREAD  00400
+#define TUWRITE 00200
+#define TUEXEC  00100
+#define TGREAD  00040
+#define TGWRITE 00020
+#define TGEXEC  00010
+#define TOREAD  00004
+#define TOWRITE 00002
+#define TOEXEC  00001
+
+#define REGTYPE  '0'
+#define AREGTYPE '\0'
+#define LNKTYPE  '1'
+#define SYMTYPE  '2'
+#define CHRTYPE  '3'
+#define BLKTYPE  '4'
+#define DIRTYPE  '5'
+#define FIFOTYPE '6'
+#define CONTTYPE '7'
+
+#define TMAGIC "ustar"
+#define TMAGLEN 6
+
+#define TVERSION "00"
+#define TVERSLEN 2
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/termios.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/termios.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/termios.h	(revision 398)
@@ -0,0 +1,46 @@
+#ifndef	_TERMIOS_H
+#define	_TERMIOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_pid_t
+
+#include <bits/alltypes.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 32
+
+#include <bits/termios.h>
+
+speed_t cfgetospeed (const struct termios *);
+speed_t cfgetispeed (const struct termios *);
+int cfsetospeed (struct termios *, speed_t);
+int cfsetispeed (struct termios *, speed_t);
+
+int tcgetattr (int, struct termios *);
+int tcsetattr (int, int, const struct termios *);
+
+int tcsendbreak (int, int);
+int tcdrain (int);
+int tcflush (int, int);
+int tcflow (int, int);
+
+pid_t tcgetsid (int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void cfmakeraw(struct termios *);
+int cfsetspeed(struct termios *, speed_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/tgmath.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/tgmath.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/tgmath.h	(revision 398)
@@ -0,0 +1,270 @@
+#ifndef _TGMATH_H
+#define _TGMATH_H
+
+/*
+the return types are only correct with gcc (__GNUC__)
+otherwise they are long double or long double complex
+
+the long double version of a function is never chosen when
+sizeof(double) == sizeof(long double)
+(but the return type is set correctly with gcc)
+*/
+
+#include <math.h>
+#include <complex.h>
+
+#define __IS_FP(x) (sizeof((x)+1ULL) == sizeof((x)+1.0f))
+#define __IS_CX(x) (__IS_FP(x) && sizeof(x) == sizeof((x)+I))
+#define __IS_REAL(x) (__IS_FP(x) && 2*sizeof(x) == sizeof((x)+I))
+
+#define __FLT(x) (__IS_REAL(x) && sizeof(x) == sizeof(float))
+#define __LDBL(x) (__IS_REAL(x) && sizeof(x) == sizeof(long double) && sizeof(long double) != sizeof(double))
+
+#define __FLTCX(x) (__IS_CX(x) && sizeof(x) == sizeof(float complex))
+#define __DBLCX(x) (__IS_CX(x) && sizeof(x) == sizeof(double complex))
+#define __LDBLCX(x) (__IS_CX(x) && sizeof(x) == sizeof(long double complex) && sizeof(long double) != sizeof(double))
+
+/* return type */
+
+#ifdef __GNUC__
+/*
+the result must be casted to the right type
+(otherwise the result type is determined by the conversion
+rules applied to all the function return types so it is long
+double or long double complex except for integral functions)
+
+this cannot be done in c99, so the typeof gcc extension is
+used and that the type of ?: depends on wether an operand is
+a null pointer constant or not
+(in c11 _Generic can be used)
+
+the c arguments below must be integer constant expressions
+so they can be in null pointer constants
+(__IS_FP above was carefully chosen this way)
+*/
+/* if c then t else void */
+#define __type1(c,t) __typeof__(*(0?(t*)0:(void*)!(c)))
+/* if c then t1 else t2 */
+#define __type2(c,t1,t2) __typeof__(*(0?(__type1(c,t1)*)0:(__type1(!(c),t2)*)0))
+/* cast to double when x is integral, otherwise use typeof(x) */
+#define __RETCAST(x) ( \
+	__type2(__IS_FP(x), __typeof__(x), double))
+/* 2 args case, should work for complex types (cpow) */
+#define __RETCAST_2(x, y) ( \
+	__type2(__IS_FP(x) && __IS_FP(y), \
+		__typeof__((x)+(y)), \
+		__typeof__((x)+(y)+1.0)))
+/* 3 args case (fma only) */
+#define __RETCAST_3(x, y, z) ( \
+	__type2(__IS_FP(x) && __IS_FP(y) && __IS_FP(z), \
+		__typeof__((x)+(y)+(z)), \
+		__typeof__((x)+(y)+(z)+1.0)))
+/* drop complex from the type of x */
+/* TODO: wrong when sizeof(long double)==sizeof(double) */
+#define __RETCAST_REAL(x) (  \
+	__type2(__IS_FP(x) && sizeof((x)+I) == sizeof(float complex), float, \
+	__type2(sizeof((x)+1.0+I) == sizeof(double complex), double, \
+		long double)))
+/* add complex to the type of x */
+#define __RETCAST_CX(x) (__typeof__(__RETCAST(x)0+I))
+#else
+#define __RETCAST(x)
+#define __RETCAST_2(x, y)
+#define __RETCAST_3(x, y, z)
+#define __RETCAST_REAL(x)
+#define __RETCAST_CX(x)
+#endif
+
+/* function selection */
+
+#define __tg_real_nocast(fun, x) ( \
+	__FLT(x) ? fun ## f (x) : \
+	__LDBL(x) ? fun ## l (x) : \
+	fun(x) )
+
+#define __tg_real(fun, x) (__RETCAST(x)__tg_real_nocast(fun, x))
+
+#define __tg_real_2_1(fun, x, y) (__RETCAST(x)( \
+	__FLT(x) ? fun ## f (x, y) : \
+	__LDBL(x) ? fun ## l (x, y) : \
+	fun(x, y) ))
+
+#define __tg_real_2(fun, x, y) (__RETCAST_2(x, y)( \
+	__FLT(x) && __FLT(y) ? fun ## f (x, y) : \
+	__LDBL((x)+(y)) ? fun ## l (x, y) : \
+	fun(x, y) ))
+
+#define __tg_complex(fun, x) (__RETCAST_CX(x)( \
+	__FLTCX((x)+I) && __IS_FP(x) ? fun ## f (x) : \
+	__LDBLCX((x)+I) ? fun ## l (x) : \
+	fun(x) ))
+
+#define __tg_complex_retreal(fun, x) (__RETCAST_REAL(x)( \
+	__FLTCX((x)+I) && __IS_FP(x) ? fun ## f (x) : \
+	__LDBLCX((x)+I) ? fun ## l (x) : \
+	fun(x) ))
+
+#define __tg_real_complex(fun, x) (__RETCAST(x)( \
+	__FLTCX(x) ? c ## fun ## f (x) : \
+	__DBLCX(x) ? c ## fun (x) : \
+	__LDBLCX(x) ? c ## fun ## l (x) : \
+	__FLT(x) ? fun ## f (x) : \
+	__LDBL(x) ? fun ## l (x) : \
+	fun(x) ))
+
+/* special cases */
+
+#define __tg_real_remquo(x, y, z) (__RETCAST_2(x, y)( \
+	__FLT(x) && __FLT(y) ? remquof(x, y, z) : \
+	__LDBL((x)+(y)) ? remquol(x, y, z) : \
+	remquo(x, y, z) ))
+
+#define __tg_real_fma(x, y, z) (__RETCAST_3(x, y, z)( \
+	__FLT(x) && __FLT(y) && __FLT(z) ? fmaf(x, y, z) : \
+	__LDBL((x)+(y)+(z)) ? fmal(x, y, z) : \
+	fma(x, y, z) ))
+
+#define __tg_real_complex_pow(x, y) (__RETCAST_2(x, y)( \
+	__FLTCX((x)+(y)) && __IS_FP(x) && __IS_FP(y) ? cpowf(x, y) : \
+	__FLTCX((x)+(y)) ? cpow(x, y) : \
+	__DBLCX((x)+(y)) ? cpow(x, y) : \
+	__LDBLCX((x)+(y)) ? cpowl(x, y) : \
+	__FLT(x) && __FLT(y) ? powf(x, y) : \
+	__LDBL((x)+(y)) ? powl(x, y) : \
+	pow(x, y) ))
+
+#define __tg_real_complex_fabs(x) (__RETCAST_REAL(x)( \
+	__FLTCX(x) ? cabsf(x) : \
+	__DBLCX(x) ? cabs(x) : \
+	__LDBLCX(x) ? cabsl(x) : \
+	__FLT(x) ? fabsf(x) : \
+	__LDBL(x) ? fabsl(x) : \
+	fabs(x) ))
+
+/* suppress any macros in math.h or complex.h */
+
+#undef acos
+#undef acosh
+#undef asin
+#undef asinh
+#undef atan
+#undef atan2
+#undef atanh
+#undef carg
+#undef cbrt
+#undef ceil
+#undef cimag
+#undef conj
+#undef copysign
+#undef cos
+#undef cosh
+#undef cproj
+#undef creal
+#undef erf
+#undef erfc
+#undef exp
+#undef exp2
+#undef expm1
+#undef fabs
+#undef fdim
+#undef floor
+#undef fma
+#undef fmax
+#undef fmin
+#undef fmod
+#undef frexp
+#undef hypot
+#undef ilogb
+#undef ldexp
+#undef lgamma
+#undef llrint
+#undef llround
+#undef log
+#undef log10
+#undef log1p
+#undef log2
+#undef logb
+#undef lrint
+#undef lround
+#undef nearbyint
+#undef nextafter
+#undef nexttoward
+#undef pow
+#undef remainder
+#undef remquo
+#undef rint
+#undef round
+#undef scalbln
+#undef scalbn
+#undef sin
+#undef sinh
+#undef sqrt
+#undef tan
+#undef tanh
+#undef tgamma
+#undef trunc
+
+/* tg functions */
+
+#define acos(x)         __tg_real_complex(acos, (x))
+#define acosh(x)        __tg_real_complex(acosh, (x))
+#define asin(x)         __tg_real_complex(asin, (x))
+#define asinh(x)        __tg_real_complex(asinh, (x))
+#define atan(x)         __tg_real_complex(atan, (x))
+#define atan2(x,y)      __tg_real_2(atan2, (x), (y))
+#define atanh(x)        __tg_real_complex(atanh, (x))
+#define carg(x)         __tg_complex_retreal(carg, (x))
+#define cbrt(x)         __tg_real(cbrt, (x))
+#define ceil(x)         __tg_real(ceil, (x))
+#define cimag(x)        __tg_complex_retreal(cimag, (x))
+#define conj(x)         __tg_complex(conj, (x))
+#define copysign(x,y)   __tg_real_2(copysign, (x), (y))
+#define cos(x)          __tg_real_complex(cos, (x))
+#define cosh(x)         __tg_real_complex(cosh, (x))
+#define cproj(x)        __tg_complex(cproj, (x))
+#define creal(x)        __tg_complex_retreal(creal, (x))
+#define erf(x)          __tg_real(erf, (x))
+#define erfc(x)         __tg_real(erfc, (x))
+#define exp(x)          __tg_real_complex(exp, (x))
+#define exp2(x)         __tg_real(exp2, (x))
+#define expm1(x)        __tg_real(expm1, (x))
+#define fabs(x)         __tg_real_complex_fabs(x)
+#define fdim(x,y)       __tg_real_2(fdim, (x), (y))
+#define floor(x)        __tg_real(floor, (x))
+#define fma(x,y,z)      __tg_real_fma((x), (y), (z))
+#define fmax(x,y)       __tg_real_2(fmax, (x), (y))
+#define fmin(x,y)       __tg_real_2(fmin, (x), (y))
+#define fmod(x,y)       __tg_real_2(fmod, (x), (y))
+#define frexp(x,y)      __tg_real_2_1(frexp, (x), (y))
+#define hypot(x,y)      __tg_real_2(hypot, (x), (y))
+#define ilogb(x)        __tg_real_nocast(ilogb, (x))
+#define ldexp(x,y)      __tg_real_2_1(ldexp, (x), (y))
+#define lgamma(x)       __tg_real(lgamma, (x))
+#define llrint(x)       __tg_real_nocast(llrint, (x))
+#define llround(x)      __tg_real_nocast(llround, (x))
+#define log(x)          __tg_real_complex(log, (x))
+#define log10(x)        __tg_real(log10, (x))
+#define log1p(x)        __tg_real(log1p, (x))
+#define log2(x)         __tg_real(log2, (x))
+#define logb(x)         __tg_real(logb, (x))
+#define lrint(x)        __tg_real_nocast(lrint, (x))
+#define lround(x)       __tg_real_nocast(lround, (x))
+#define nearbyint(x)    __tg_real(nearbyint, (x))
+#define nextafter(x,y)  __tg_real_2(nextafter, (x), (y))
+#define nexttoward(x,y) __tg_real_2(nexttoward, (x), (y))
+#define pow(x,y)        __tg_real_complex_pow((x), (y))
+#define remainder(x,y)  __tg_real_2(remainder, (x), (y))
+#define remquo(x,y,z)   __tg_real_remquo((x), (y), (z))
+#define rint(x)         __tg_real(rint, (x))
+#define round(x)        __tg_real(round, (x))
+#define scalbln(x,y)    __tg_real_2_1(scalbln, (x), (y))
+#define scalbn(x,y)     __tg_real_2_1(scalbn, (x), (y))
+#define sin(x)          __tg_real_complex(sin, (x))
+#define sinh(x)         __tg_real_complex(sinh, (x))
+#define sqrt(x)         __tg_real_complex(sqrt, (x))
+#define tan(x)          __tg_real_complex(tan, (x))
+#define tanh(x)         __tg_real_complex(tanh, (x))
+#define tgamma(x)       __tg_real(tgamma, (x))
+#define trunc(x)        __tg_real(trunc, (x))
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/threads.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/threads.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/threads.h	(revision 398)
@@ -0,0 +1,87 @@
+#ifndef _THREADS_H
+#define _THREADS_H
+
+#include <features.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+typedef unsigned long thrd_t;
+#else
+typedef struct __pthread *thrd_t;
+#define thread_local _Thread_local
+#endif
+
+typedef int once_flag;
+typedef unsigned tss_t;
+typedef int (*thrd_start_t)(void *);
+typedef void (*tss_dtor_t)(void *);
+
+#define __NEED_cnd_t
+#define __NEED_mtx_t
+
+#include <bits/alltypes.h>
+
+#define TSS_DTOR_ITERATIONS 4
+
+enum {
+	thrd_success  = 0,
+	thrd_busy     = 1,
+	thrd_error    = 2,
+	thrd_nomem    = 3,
+	thrd_timedout = 4,
+};
+
+enum {
+	mtx_plain     = 0,
+	mtx_recursive = 1,
+	mtx_timed     = 2,
+};
+
+#define ONCE_FLAG_INIT 0
+
+int thrd_create(thrd_t *, thrd_start_t, void *);
+_Noreturn void thrd_exit(int);
+
+int thrd_detach(thrd_t);
+int thrd_join(thrd_t, int *);
+
+int thrd_sleep(const struct timespec *, struct timespec *);
+void thrd_yield(void);
+
+thrd_t thrd_current(void);
+int thrd_equal(thrd_t, thrd_t);
+#ifndef __cplusplus
+#define thrd_equal(A, B) ((A) == (B))
+#endif
+
+void call_once(once_flag *, void (*)(void));
+
+int mtx_init(mtx_t *, int);
+void mtx_destroy(mtx_t *);
+
+int mtx_lock(mtx_t *);
+int mtx_timedlock(mtx_t *__restrict, const struct timespec *__restrict);
+int mtx_trylock(mtx_t *);
+int mtx_unlock(mtx_t *);
+
+int cnd_init(cnd_t *);
+void cnd_destroy(cnd_t *);
+
+int cnd_broadcast(cnd_t *);
+int cnd_signal(cnd_t *);
+
+int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict, const struct timespec *__restrict);
+int cnd_wait(cnd_t *, mtx_t *);
+
+int tss_create(tss_t *, tss_dtor_t);
+void tss_delete(tss_t);
+
+int tss_set(tss_t, void *);
+void *tss_get(tss_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/time.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/time.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/time.h	(revision 398)
@@ -0,0 +1,140 @@
+#ifndef	_TIME_H
+#define _TIME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+
+#define __NEED_size_t
+#define __NEED_time_t
+#define __NEED_clock_t
+#define __NEED_struct_timespec
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#define __NEED_clockid_t
+#define __NEED_timer_t
+#define __NEED_pid_t
+#define __NEED_locale_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define __tm_gmtoff tm_gmtoff
+#define __tm_zone tm_zone
+#endif
+
+struct tm {
+	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;
+	long __tm_gmtoff;
+	const char *__tm_zone;
+};
+
+clock_t clock (void);
+time_t time (time_t *);
+double difftime (time_t, time_t);
+time_t mktime (struct tm *);
+size_t strftime (char *__restrict, size_t, const char *__restrict, const struct tm *__restrict);
+struct tm *gmtime (const time_t *);
+struct tm *localtime (const time_t *);
+char *asctime (const struct tm *);
+char *ctime (const time_t *);
+int timespec_get(struct timespec *, int);
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000L
+#endif // CLOCKS_PER_SEC
+
+#define TIME_UTC 1
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+size_t strftime_l (char *  __restrict, size_t, const char *  __restrict, const struct tm *  __restrict, locale_t);
+
+struct tm *gmtime_r (const time_t *__restrict, struct tm *__restrict);
+struct tm *localtime_r (const time_t *__restrict, struct tm *__restrict);
+char *asctime_r (const struct tm *__restrict, char *__restrict);
+char *ctime_r (const time_t *, char *);
+
+void tzset (void);
+
+struct itimerspec {
+	struct timespec it_interval;
+	struct timespec it_value;
+};
+
+#define CLOCK_REALTIME           0
+#define CLOCK_MONOTONIC          1
+#define CLOCK_PROCESS_CPUTIME_ID 2
+#define CLOCK_THREAD_CPUTIME_ID  3
+#define CLOCK_MONOTONIC_RAW      4
+#define CLOCK_REALTIME_COARSE    5
+#define CLOCK_MONOTONIC_COARSE   6
+#define CLOCK_BOOTTIME           7
+#define CLOCK_REALTIME_ALARM     8
+#define CLOCK_BOOTTIME_ALARM     9
+#define CLOCK_SGI_CYCLE         10
+#define CLOCK_TAI               11
+
+#define TIMER_ABSTIME 1
+
+int nanosleep (const struct timespec *, struct timespec *);
+int clock_getres (clockid_t, struct timespec *);
+int clock_gettime (clockid_t, struct timespec *);
+int clock_settime (clockid_t, const struct timespec *);
+int clock_nanosleep (clockid_t, int, const struct timespec *, struct timespec *);
+int clock_getcpuclockid (pid_t, clockid_t *);
+
+struct sigevent;
+int timer_create (clockid_t, struct sigevent *__restrict, timer_t *__restrict);
+int timer_delete (timer_t);
+int timer_settime (timer_t, int, const struct itimerspec *__restrict, struct itimerspec *__restrict);
+int timer_gettime (timer_t, struct itimerspec *);
+int timer_getoverrun (timer_t);
+
+extern char *tzname[2];
+
+#endif
+
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+char *strptime (const char *__restrict, const char *__restrict, struct tm *__restrict);
+extern int daylight;
+extern long timezone;
+extern int getdate_err;
+struct tm *getdate (const char *);
+#endif
+
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int stime(const time_t *);
+time_t timegm(struct tm *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/uchar.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/uchar.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/uchar.h	(revision 398)
@@ -0,0 +1,27 @@
+#ifndef _UCHAR_H
+#define _UCHAR_H
+
+#ifdef __cplusplus
+extern "C" {
+#else
+typedef unsigned short char16_t;
+typedef unsigned char32_t;
+#endif
+
+#define __NEED_mbstate_t
+#define __NEED_size_t
+
+#include <features.h>
+#include <bits/alltypes.h>
+
+size_t c16rtomb(char *__restrict, char16_t, mbstate_t *__restrict);
+size_t mbrtoc16(char16_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict);
+
+size_t c32rtomb(char *__restrict, char32_t, mbstate_t *__restrict);
+size_t mbrtoc32(char32_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ucontext.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ucontext.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ucontext.h	(revision 398)
@@ -0,0 +1,25 @@
+#ifndef _UCONTEXT_H
+#define _UCONTEXT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <signal.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define NGREG (sizeof(gregset_t)/sizeof(greg_t))
+#endif
+
+struct __ucontext;
+
+int  getcontext(struct __ucontext *);
+void makecontext(struct __ucontext *, void (*)(void), int, ...);
+int  setcontext(const struct __ucontext *);
+int  swapcontext(struct __ucontext *, const struct __ucontext *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ulimit.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ulimit.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/ulimit.h	(revision 398)
@@ -0,0 +1,17 @@
+#ifndef _ULIMIT_H
+#define _ULIMIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UL_GETFSIZE 1
+#define UL_SETFSIZE 2
+
+long ulimit (int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/unistd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/unistd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/unistd.h	(revision 398)
@@ -0,0 +1,467 @@
+#ifndef	_UNISTD_H
+#define	_UNISTD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define STDIN_FILENO  0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_intptr_t
+#define __NEED_useconds_t
+
+#include <bits/alltypes.h>
+
+int pipe(int [2]);
+int pipe2(int [2], int);
+int close(int);
+int posix_close(int, int);
+int dup(int);
+int dup2(int, int);
+int dup3(int, int, int);
+off_t lseek(int, off_t, int);
+int fsync(int);
+int fdatasync(int);
+
+ssize_t read(int, void *, size_t);
+ssize_t write(int, const void *, size_t);
+ssize_t pread(int, void *, size_t, off_t);
+ssize_t pwrite(int, const void *, size_t, off_t);
+
+int chown(const char *, uid_t, gid_t);
+int fchown(int, uid_t, gid_t);
+int lchown(const char *, uid_t, gid_t);
+int fchownat(int, const char *, uid_t, gid_t, int);
+
+int link(const char *, const char *);
+int linkat(int, const char *, int, const char *, int);
+int symlink(const char *, const char *);
+int symlinkat(const char *, int, const char *);
+ssize_t readlink(const char *__restrict, char *__restrict, size_t);
+ssize_t readlinkat(int, const char *__restrict, char *__restrict, size_t);
+int unlink(const char *);
+int unlinkat(int, const char *, int);
+int rmdir(const char *);
+int truncate(const char *, off_t);
+int ftruncate(int, off_t);
+
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+
+int access(const char *, int);
+int faccessat(int, const char *, int, int);
+
+int chdir(const char *);
+int fchdir(int);
+char *getcwd(char *, size_t);
+
+unsigned alarm(unsigned);
+unsigned sleep(unsigned);
+int pause(void);
+
+pid_t fork(void);
+int execve(const char *, char *const [], char *const []);
+int execv(const char *, char *const []);
+int execle(const char *, const char *, ...);
+int execl(const char *, const char *, ...);
+int execvp(const char *, char *const []);
+int execlp(const char *, const char *, ...);
+int fexecve(int, char *const [], char *const []);
+_Noreturn void _exit(int);
+
+pid_t getpid(void);
+pid_t getppid(void);
+pid_t getpgrp(void);
+pid_t getpgid(pid_t);
+int setpgid(pid_t, pid_t);
+pid_t setsid(void);
+pid_t getsid(pid_t);
+char *ttyname(int);
+int ttyname_r(int, char *, size_t);
+int isatty(int);
+pid_t tcgetpgrp(int);
+int tcsetpgrp(int, pid_t);
+
+uid_t getuid(void);
+uid_t geteuid(void);
+gid_t getgid(void);
+gid_t getegid(void);
+int getgroups(int, gid_t []);
+int setuid(uid_t);
+int seteuid(uid_t);
+int setgid(gid_t);
+int setegid(gid_t);
+
+char *getlogin(void);
+int getlogin_r(char *, size_t);
+int gethostname(char *, size_t);
+char *ctermid(char *);
+
+int getopt(int, char * const [], const char *);
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+long pathconf(const char *, int);
+long fpathconf(int, int);
+long sysconf(int);
+size_t confstr(int, char *, size_t);
+
+#define F_ULOCK 0
+#define F_LOCK  1
+#define F_TLOCK 2
+#define F_TEST  3
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int setreuid(uid_t, uid_t);
+int setregid(gid_t, gid_t);
+int lockf(int, int, off_t);
+long gethostid(void);
+int nice(int);
+void sync(void);
+pid_t setpgrp(void);
+char *crypt(const char *, const char *);
+void encrypt(char *, int);
+void swab(const void *__restrict, void *__restrict, ssize_t);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \
+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
+int usleep(unsigned);
+unsigned ualarm(unsigned, unsigned);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define L_SET 0
+#define L_INCR 1
+#define L_XTND 2
+int brk(void *);
+void *sbrk(intptr_t);
+pid_t vfork(void);
+int vhangup(void);
+int chroot(const char *);
+int getpagesize(void);
+int getdtablesize(void);
+int sethostname(const char *, size_t);
+int getdomainname(char *, size_t);
+int setdomainname(const char *, size_t);
+int setgroups(size_t, const gid_t *);
+char *getpass(const char *);
+int daemon(int, int);
+void setusershell(void);
+void endusershell(void);
+char *getusershell(void);
+int acct(const char *);
+long syscall(long, ...);
+int execvpe(const char *, char *const [], char *const []);
+int issetugid(void);
+#endif
+
+#ifdef _GNU_SOURCE
+extern char **environ;
+int setresuid(uid_t, uid_t, uid_t);
+int setresgid(gid_t, gid_t, gid_t);
+int getresuid(uid_t *, uid_t *, uid_t *);
+int getresgid(gid_t *, gid_t *, gid_t *);
+char *get_current_dir_name(void);
+int syncfs(int);
+int euidaccess(const char *, int);
+int eaccess(const char *, int);
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define lseek64 lseek
+#define pread64 pread
+#define pwrite64 pwrite
+#define truncate64 truncate
+#define ftruncate64 ftruncate
+#define lockf64 lockf
+#define off64_t off_t
+#endif
+
+#define POSIX_CLOSE_RESTART     0
+
+#define _XOPEN_VERSION          700
+#define _XOPEN_UNIX             1
+#define _XOPEN_ENH_I18N         1
+
+#define _POSIX_VERSION          200809L
+#define _POSIX2_VERSION         _POSIX_VERSION
+
+#define _POSIX_ADVISORY_INFO    _POSIX_VERSION
+#define _POSIX_CHOWN_RESTRICTED 1
+#define _POSIX_IPV6             _POSIX_VERSION
+#define _POSIX_JOB_CONTROL      1
+#define _POSIX_MAPPED_FILES     _POSIX_VERSION
+#define _POSIX_MEMLOCK          _POSIX_VERSION
+#define _POSIX_MEMLOCK_RANGE    _POSIX_VERSION
+#define _POSIX_MEMORY_PROTECTION _POSIX_VERSION
+#define _POSIX_MESSAGE_PASSING  _POSIX_VERSION
+#define _POSIX_FSYNC            _POSIX_VERSION
+#define _POSIX_NO_TRUNC         1
+#define _POSIX_RAW_SOCKETS      _POSIX_VERSION
+#define _POSIX_REALTIME_SIGNALS _POSIX_VERSION
+#define _POSIX_REGEXP           1
+#define _POSIX_SAVED_IDS        1
+#define _POSIX_SHELL            1
+#define _POSIX_SPAWN            _POSIX_VERSION
+#define _POSIX_VDISABLE         0
+
+#define _POSIX_THREADS          _POSIX_VERSION
+#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
+#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
+#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION
+#define _POSIX_THREAD_CPUTIME   _POSIX_VERSION
+#define _POSIX_TIMERS           _POSIX_VERSION
+#define _POSIX_TIMEOUTS         _POSIX_VERSION
+#define _POSIX_MONOTONIC_CLOCK  _POSIX_VERSION
+#define _POSIX_CPUTIME          _POSIX_VERSION
+#define _POSIX_CLOCK_SELECTION  _POSIX_VERSION
+#define _POSIX_BARRIERS         _POSIX_VERSION
+#define _POSIX_SPIN_LOCKS       _POSIX_VERSION
+#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION
+#define _POSIX_ASYNCHRONOUS_IO  _POSIX_VERSION
+#define _POSIX_SEMAPHORES       _POSIX_VERSION
+#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION
+
+#define _POSIX2_C_BIND          _POSIX_VERSION
+
+#include <bits/posix.h>
+
+
+
+#define _PC_LINK_MAX	0
+#define _PC_MAX_CANON	1
+#define _PC_MAX_INPUT	2
+#define _PC_NAME_MAX	3
+#define _PC_PATH_MAX	4
+#define _PC_PIPE_BUF	5
+#define _PC_CHOWN_RESTRICTED	6
+#define _PC_NO_TRUNC	7
+#define _PC_VDISABLE	8
+#define _PC_SYNC_IO	9
+#define _PC_ASYNC_IO	10
+#define _PC_PRIO_IO	11
+#define _PC_SOCK_MAXBUF	12
+#define _PC_FILESIZEBITS	13
+#define _PC_REC_INCR_XFER_SIZE	14
+#define _PC_REC_MAX_XFER_SIZE	15
+#define _PC_REC_MIN_XFER_SIZE	16
+#define _PC_REC_XFER_ALIGN	17
+#define _PC_ALLOC_SIZE_MIN	18
+#define _PC_SYMLINK_MAX	19
+#define _PC_2_SYMLINKS	20
+
+#define _SC_ARG_MAX	0
+#define _SC_CHILD_MAX	1
+#define _SC_CLK_TCK	2
+#define _SC_NGROUPS_MAX	3
+#define _SC_OPEN_MAX	4
+#define _SC_STREAM_MAX	5
+#define _SC_TZNAME_MAX	6
+#define _SC_JOB_CONTROL	7
+#define _SC_SAVED_IDS	8
+#define _SC_REALTIME_SIGNALS	9
+#define _SC_PRIORITY_SCHEDULING	10
+#define _SC_TIMERS	11
+#define _SC_ASYNCHRONOUS_IO	12
+#define _SC_PRIORITIZED_IO	13
+#define _SC_SYNCHRONIZED_IO	14
+#define _SC_FSYNC	15
+#define _SC_MAPPED_FILES	16
+#define _SC_MEMLOCK	17
+#define _SC_MEMLOCK_RANGE	18
+#define _SC_MEMORY_PROTECTION	19
+#define _SC_MESSAGE_PASSING	20
+#define _SC_SEMAPHORES	21
+#define _SC_SHARED_MEMORY_OBJECTS	22
+#define _SC_AIO_LISTIO_MAX	23
+#define _SC_AIO_MAX	24
+#define _SC_AIO_PRIO_DELTA_MAX	25
+#define _SC_DELAYTIMER_MAX	26
+#define _SC_MQ_OPEN_MAX	27
+#define _SC_MQ_PRIO_MAX	28
+#define _SC_VERSION	29
+#define _SC_PAGE_SIZE	30
+#define _SC_PAGESIZE	30 /* !! */
+#define _SC_RTSIG_MAX	31
+#define _SC_SEM_NSEMS_MAX	32
+#define _SC_SEM_VALUE_MAX	33
+#define _SC_SIGQUEUE_MAX	34
+#define _SC_TIMER_MAX	35
+#define _SC_BC_BASE_MAX	36
+#define _SC_BC_DIM_MAX	37
+#define _SC_BC_SCALE_MAX	38
+#define _SC_BC_STRING_MAX	39
+#define _SC_COLL_WEIGHTS_MAX	40
+#define _SC_EXPR_NEST_MAX	42
+#define _SC_LINE_MAX	43
+#define _SC_RE_DUP_MAX	44
+#define _SC_2_VERSION	46
+#define _SC_2_C_BIND	47
+#define _SC_2_C_DEV	48
+#define _SC_2_FORT_DEV	49
+#define _SC_2_FORT_RUN	50
+#define _SC_2_SW_DEV	51
+#define _SC_2_LOCALEDEF	52
+#define _SC_UIO_MAXIOV	60 /* !! */
+#define _SC_IOV_MAX	60
+#define _SC_THREADS	67
+#define _SC_THREAD_SAFE_FUNCTIONS	68
+#define _SC_GETGR_R_SIZE_MAX	69
+#define _SC_GETPW_R_SIZE_MAX	70
+#define _SC_LOGIN_NAME_MAX	71
+#define _SC_TTY_NAME_MAX	72
+#define _SC_THREAD_DESTRUCTOR_ITERATIONS	73
+#define _SC_THREAD_KEYS_MAX	74
+#define _SC_THREAD_STACK_MIN	75
+#define _SC_THREAD_THREADS_MAX	76
+#define _SC_THREAD_ATTR_STACKADDR	77
+#define _SC_THREAD_ATTR_STACKSIZE	78
+#define _SC_THREAD_PRIORITY_SCHEDULING	79
+#define _SC_THREAD_PRIO_INHERIT	80
+#define _SC_THREAD_PRIO_PROTECT	81
+#define _SC_THREAD_PROCESS_SHARED	82
+#define _SC_NPROCESSORS_CONF	83
+#define _SC_NPROCESSORS_ONLN	84
+#define _SC_PHYS_PAGES	85
+#define _SC_AVPHYS_PAGES	86
+#define _SC_ATEXIT_MAX	87
+#define _SC_PASS_MAX	88
+#define _SC_XOPEN_VERSION	89
+#define _SC_XOPEN_XCU_VERSION	90
+#define _SC_XOPEN_UNIX	91
+#define _SC_XOPEN_CRYPT	92
+#define _SC_XOPEN_ENH_I18N	93
+#define _SC_XOPEN_SHM	94
+#define _SC_2_CHAR_TERM	95
+#define _SC_2_UPE	97
+#define _SC_XOPEN_XPG2	98
+#define _SC_XOPEN_XPG3	99
+#define _SC_XOPEN_XPG4	100
+#define _SC_NZERO	109
+#define _SC_XBS5_ILP32_OFF32	125
+#define _SC_XBS5_ILP32_OFFBIG	126
+#define _SC_XBS5_LP64_OFF64	127
+#define _SC_XBS5_LPBIG_OFFBIG	128
+#define _SC_XOPEN_LEGACY	129
+#define _SC_XOPEN_REALTIME	130
+#define _SC_XOPEN_REALTIME_THREADS	131
+#define _SC_ADVISORY_INFO	132
+#define _SC_BARRIERS	133
+#define _SC_CLOCK_SELECTION	137
+#define _SC_CPUTIME	138
+#define _SC_THREAD_CPUTIME	139
+#define _SC_MONOTONIC_CLOCK	149
+#define _SC_READER_WRITER_LOCKS	153
+#define _SC_SPIN_LOCKS	154
+#define _SC_REGEXP	155
+#define _SC_SHELL	157
+#define _SC_SPAWN	159
+#define _SC_SPORADIC_SERVER	160
+#define _SC_THREAD_SPORADIC_SERVER	161
+#define _SC_TIMEOUTS	164
+#define _SC_TYPED_MEMORY_OBJECTS	165
+#define _SC_2_PBS	168
+#define _SC_2_PBS_ACCOUNTING	169
+#define _SC_2_PBS_LOCATE	170
+#define _SC_2_PBS_MESSAGE	171
+#define _SC_2_PBS_TRACK	172
+#define _SC_SYMLOOP_MAX	173
+#define _SC_STREAMS	174
+#define _SC_2_PBS_CHECKPOINT	175
+#define _SC_V6_ILP32_OFF32	176
+#define _SC_V6_ILP32_OFFBIG	177
+#define _SC_V6_LP64_OFF64	178
+#define _SC_V6_LPBIG_OFFBIG	179
+#define _SC_HOST_NAME_MAX	180
+#define _SC_TRACE	181
+#define _SC_TRACE_EVENT_FILTER	182
+#define _SC_TRACE_INHERIT	183
+#define _SC_TRACE_LOG	184
+
+#define _SC_IPV6	235
+#define _SC_RAW_SOCKETS	236
+#define _SC_V7_ILP32_OFF32	237
+#define _SC_V7_ILP32_OFFBIG	238
+#define _SC_V7_LP64_OFF64	239
+#define _SC_V7_LPBIG_OFFBIG	240
+#define _SC_SS_REPL_MAX	241
+#define _SC_TRACE_EVENT_NAME_MAX	242
+#define _SC_TRACE_NAME_MAX	243
+#define _SC_TRACE_SYS_MAX	244
+#define _SC_TRACE_USER_EVENT_MAX	245
+#define _SC_XOPEN_STREAMS	246
+#define _SC_THREAD_ROBUST_PRIO_INHERIT	247
+#define _SC_THREAD_ROBUST_PRIO_PROTECT	248
+
+#define _CS_PATH	0
+#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS	1
+#define _CS_GNU_LIBC_VERSION	2
+#define _CS_GNU_LIBPTHREAD_VERSION	3
+#define _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS	4
+#define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS	5
+
+#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS	1116
+#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS	1117
+#define _CS_POSIX_V6_ILP32_OFF32_LIBS	1118
+#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS	1119
+#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS	1120
+#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS	1121
+#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS	1122
+#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS	1123
+#define _CS_POSIX_V6_LP64_OFF64_CFLAGS	1124
+#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS	1125
+#define _CS_POSIX_V6_LP64_OFF64_LIBS	1126
+#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS	1127
+#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS	1128
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS	1129
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS	1130
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS	1131
+#define _CS_POSIX_V7_ILP32_OFF32_CFLAGS	1132
+#define _CS_POSIX_V7_ILP32_OFF32_LDFLAGS	1133
+#define _CS_POSIX_V7_ILP32_OFF32_LIBS	1134
+#define _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS	1135
+#define _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS	1136
+#define _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS	1137
+#define _CS_POSIX_V7_ILP32_OFFBIG_LIBS	1138
+#define _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS	1139
+#define _CS_POSIX_V7_LP64_OFF64_CFLAGS	1140
+#define _CS_POSIX_V7_LP64_OFF64_LDFLAGS	1141
+#define _CS_POSIX_V7_LP64_OFF64_LIBS	1142
+#define _CS_POSIX_V7_LP64_OFF64_LINTFLAGS	1143
+#define _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS	1144
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS	1145
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LIBS	1146
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS	1147
+#define _CS_V6_ENV	1148
+#define _CS_V7_ENV	1149
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/utime.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/utime.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/utime.h	(revision 398)
@@ -0,0 +1,23 @@
+#ifndef	_UTIME_H
+#define	_UTIME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_time_t
+
+#include <bits/alltypes.h>
+
+struct utimbuf {
+	time_t actime;
+	time_t modtime;
+};
+
+int utime (const char *, const struct utimbuf *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/utmp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/utmp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/utmp.h	(revision 398)
@@ -0,0 +1,52 @@
+#ifndef _UTMP_H
+#define _UTMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <utmpx.h>
+
+#define ACCOUNTING 9
+#define UT_NAMESIZE 32
+#define UT_HOSTSIZE 256
+#define UT_LINESIZE 32
+
+struct lastlog {
+	time_t ll_time;
+	char ll_line[UT_LINESIZE];
+	char ll_host[UT_HOSTSIZE];
+};
+
+#define ut_time ut_tv.tv_sec
+#define ut_name ut_user
+#define ut_addr ut_addr_v6[0]
+#define utmp utmpx
+#define e_exit __e_exit
+#define e_termination __e_termination
+
+void         endutent(void);
+struct utmp *getutent(void);
+struct utmp *getutid(const struct utmp *);
+struct utmp *getutline(const struct utmp *);
+struct utmp *pututline(const struct utmp *);
+void         setutent(void);
+
+void updwtmp(const char *, const struct utmp *);
+int utmpname(const char *);
+
+int login_tty(int);
+
+#define _PATH_UTMP "/dev/null/utmp"
+#define _PATH_WTMP "/dev/null/wtmp"
+
+#define UTMP_FILE _PATH_UTMP
+#define WTMP_FILE _PATH_WTMP
+#define UTMP_FILENAME _PATH_UTMP
+#define WTMP_FILENAME _PATH_WTMP
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/utmpx.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/utmpx.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/utmpx.h	(revision 398)
@@ -0,0 +1,62 @@
+#ifndef _UTMPX_H
+#define _UTMPX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_pid_t
+#define __NEED_time_t
+#define __NEED_suseconds_t
+#define __NEED_struct_timeval
+
+#include <bits/alltypes.h>
+
+struct utmpx {
+	short ut_type;
+	pid_t ut_pid;
+	char ut_line[32];
+	char ut_id[4];
+	char ut_user[32];
+	char ut_host[256];
+	struct {
+		short __e_termination;
+		short __e_exit;
+	} ut_exit;
+	long ut_session;
+	struct timeval ut_tv;
+	unsigned ut_addr_v6[4];
+	char __unused[20];
+};
+
+void          endutxent(void);
+struct utmpx *getutxent(void);
+struct utmpx *getutxid(const struct utmpx *);
+struct utmpx *getutxline(const struct utmpx *);
+struct utmpx *pututxline(const struct utmpx *);
+void          setutxent(void);
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define e_exit __e_exit
+#define e_termination __e_termination
+void updwtmpx(const char *, const struct utmpx *);
+int utmpxname(const char *);
+#endif
+
+#define EMPTY           0
+#define RUN_LVL         1
+#define BOOT_TIME       2
+#define NEW_TIME        3
+#define OLD_TIME        4
+#define INIT_PROCESS    5
+#define LOGIN_PROCESS   6
+#define USER_PROCESS    7
+#define DEAD_PROCESS    8
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/values.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/values.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/values.h	(revision 398)
@@ -0,0 +1,39 @@
+#ifndef _VALUES_H
+#define _VALUES_H
+
+#include <limits.h>
+
+#define CHARBITS   (sizeof(char)   * 8)
+#define SHORTBITS  (sizeof(short)  * 8)
+#define INTBITS    (sizeof(int)    * 8)
+#define LONGBITS   (sizeof(long)   * 8)
+#define PTRBITS    (sizeof(char *) * 8)
+#define DOUBLEBITS (sizeof(double) * 8)
+#define FLOATBITS  (sizeof(float)  * 8)
+
+#define MINSHORT SHRT_MIN
+#define MININT   INT_MIN
+#define MINLONG  LONG_MIN
+
+#define MAXSHORT SHRT_MAX
+#define MAXINT   INT_MAX
+#define MAXLONG  LONG_MAX
+
+#define HIBITS   MINSHORT
+#define HIBITL   MINLONG
+
+#include <float.h>
+
+#define MAXDOUBLE DBL_MAX
+#undef  MAXFLOAT
+#define MAXFLOAT  FLT_MAX
+#define MINDOUBLE DBL_MIN
+#define MINFLOAT  FLT_MIN
+#define DMINEXP   DBL_MIN_EXP
+#define FMINEXP   FLT_MIN_EXP
+#define DMAXEXP   DBL_MAX_EXP
+#define FMAXEXP   FLT_MAX_EXP
+
+#define BITSPERBYTE CHAR_BIT
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wait.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wait.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wait.h	(revision 398)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <wait.h> to <sys/wait.h>
+#include <sys/wait.h>
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wchar.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wchar.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wchar.h	(revision 398)
@@ -0,0 +1,201 @@
+#ifndef _WCHAR_H
+#define _WCHAR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_FILE
+#define __NEED___isoc_va_list
+#define __NEED_size_t
+#define __NEED_wchar_t
+#define __NEED_wint_t
+#define __NEED_mbstate_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_locale_t
+#define __NEED_va_list
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_wctype_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if L'\0'-1 > 0
+#define WCHAR_MAX (0xffffffffu+L'\0')
+#define WCHAR_MIN (0+L'\0')
+#else
+#define WCHAR_MAX (0x7fffffff+L'\0')
+#define WCHAR_MIN (-1-0x7fffffff+L'\0')
+#endif
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#undef WEOF
+#define WEOF 0xffffffffU
+
+wchar_t *wcscpy (wchar_t *__restrict, const wchar_t *__restrict);
+wchar_t *wcsncpy (wchar_t *__restrict, const wchar_t *__restrict, size_t);
+
+wchar_t *wcscat (wchar_t *__restrict, const wchar_t *__restrict);
+wchar_t *wcsncat (wchar_t *__restrict, const wchar_t *__restrict, size_t);
+
+int wcscmp (const wchar_t *, const wchar_t *);
+int wcsncmp (const wchar_t *, const wchar_t *, size_t);
+
+int wcscoll(const wchar_t *, const wchar_t *);
+size_t wcsxfrm (wchar_t *__restrict, const wchar_t *__restrict, size_t);
+
+wchar_t *wcschr (const wchar_t *, wchar_t);
+wchar_t *wcsrchr (const wchar_t *, wchar_t);
+
+size_t wcscspn (const wchar_t *, const wchar_t *);
+size_t wcsspn (const wchar_t *, const wchar_t *);
+wchar_t *wcspbrk (const wchar_t *, const wchar_t *);
+
+wchar_t *wcstok (wchar_t *__restrict, const wchar_t *__restrict, wchar_t **__restrict);
+
+size_t wcslen (const wchar_t *);
+
+wchar_t *wcsstr (const wchar_t *__restrict, const wchar_t *__restrict);
+wchar_t *wcswcs (const wchar_t *, const wchar_t *);
+
+wchar_t *wmemchr (const wchar_t *, wchar_t, size_t);
+int wmemcmp (const wchar_t *, const wchar_t *, size_t);
+wchar_t *wmemcpy (wchar_t *__restrict, const wchar_t *__restrict, size_t);
+wchar_t *wmemmove (wchar_t *, const wchar_t *, size_t);
+wchar_t *wmemset (wchar_t *, wchar_t, size_t);
+
+wint_t btowc (int);
+int wctob (wint_t);
+
+int mbsinit (const mbstate_t *);
+size_t mbrtowc (wchar_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict);
+size_t wcrtomb (char *__restrict, wchar_t, mbstate_t *__restrict);
+
+size_t mbrlen (const char *__restrict, size_t, mbstate_t *__restrict);
+
+size_t mbsrtowcs (wchar_t *__restrict, const char **__restrict, size_t, mbstate_t *__restrict);
+size_t wcsrtombs (char *__restrict, const wchar_t **__restrict, size_t, mbstate_t *__restrict);
+
+float wcstof (const wchar_t *__restrict, wchar_t **__restrict);
+double wcstod (const wchar_t *__restrict, wchar_t **__restrict);
+long double wcstold (const wchar_t *__restrict, wchar_t **__restrict);
+
+long wcstol (const wchar_t *__restrict, wchar_t **__restrict, int);
+unsigned long wcstoul (const wchar_t *__restrict, wchar_t **__restrict, int);
+
+long long wcstoll (const wchar_t *__restrict, wchar_t **__restrict, int);
+unsigned long long wcstoull (const wchar_t *__restrict, wchar_t **__restrict, int);
+
+
+
+int fwide (FILE *, int);
+
+
+int wprintf (const wchar_t *__restrict, ...);
+int fwprintf (FILE *__restrict, const wchar_t *__restrict, ...);
+int swprintf (wchar_t *__restrict, size_t, const wchar_t *__restrict, ...);
+
+int vwprintf (const wchar_t *__restrict, __isoc_va_list);
+int vfwprintf (FILE *__restrict, const wchar_t *__restrict, __isoc_va_list);
+int vswprintf (wchar_t *__restrict, size_t, const wchar_t *__restrict, __isoc_va_list);
+
+int wscanf (const wchar_t *__restrict, ...);
+int fwscanf (FILE *__restrict, const wchar_t *__restrict, ...);
+int swscanf (const wchar_t *__restrict, const wchar_t *__restrict, ...);
+
+int vwscanf (const wchar_t *__restrict, __isoc_va_list);
+int vfwscanf (FILE *__restrict, const wchar_t *__restrict, __isoc_va_list);
+int vswscanf (const wchar_t *__restrict, const wchar_t *__restrict, __isoc_va_list);
+
+wint_t fgetwc (FILE *);
+wint_t getwc (FILE *);
+wint_t getwchar (void);
+
+wint_t fputwc (wchar_t, FILE *);
+wint_t putwc (wchar_t, FILE *);
+wint_t putwchar (wchar_t);
+
+wchar_t *fgetws (wchar_t *__restrict, int, FILE *__restrict);
+int fputws (const wchar_t *__restrict, FILE *__restrict);
+
+wint_t ungetwc (wint_t, FILE *);
+
+struct tm;
+size_t wcsftime (wchar_t *__restrict, size_t, const wchar_t *__restrict, const struct tm *__restrict);
+
+#undef iswdigit
+
+#if defined(_GNU_SOURCE)
+wint_t fgetwc_unlocked (FILE *);
+wint_t getwc_unlocked (FILE *);
+wint_t getwchar_unlocked (void);
+wint_t fputwc_unlocked (wchar_t, FILE *);
+wint_t putwc_unlocked (wchar_t, FILE *);
+wint_t putwchar_unlocked (wchar_t);
+wchar_t *fgetws_unlocked (wchar_t *__restrict, int, FILE *__restrict);
+int fputws_unlocked (const wchar_t *__restrict, FILE *__restrict);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+size_t wcsftime_l (wchar_t *__restrict, size_t, const wchar_t *__restrict, const struct tm *__restrict, locale_t);
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE)  || defined(_BSD_SOURCE)
+FILE *open_wmemstream(wchar_t **, size_t *);
+size_t mbsnrtowcs(wchar_t *__restrict, const char **__restrict, size_t, size_t, mbstate_t *__restrict);
+size_t wcsnrtombs(char *__restrict, const wchar_t **__restrict, size_t, size_t, mbstate_t *__restrict);
+wchar_t *wcsdup(const wchar_t *);
+size_t wcsnlen (const wchar_t *, size_t);
+wchar_t *wcpcpy (wchar_t *__restrict, const wchar_t *__restrict);
+wchar_t *wcpncpy (wchar_t *__restrict, const wchar_t *__restrict, size_t);
+int wcscasecmp(const wchar_t *, const wchar_t *);
+int wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t);
+int wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
+int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);
+int wcscoll_l(const wchar_t *, const wchar_t *, locale_t);
+size_t wcsxfrm_l(wchar_t *__restrict, const wchar_t *__restrict, size_t, locale_t);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int wcwidth (wchar_t);
+int wcswidth (const wchar_t *, size_t);
+int       iswalnum(wint_t);
+int       iswalpha(wint_t);
+int       iswblank(wint_t);
+int       iswcntrl(wint_t);
+int       iswdigit(wint_t);
+int       iswgraph(wint_t);
+int       iswlower(wint_t);
+int       iswprint(wint_t);
+int       iswpunct(wint_t);
+int       iswspace(wint_t);
+int       iswupper(wint_t);
+int       iswxdigit(wint_t);
+int       iswctype(wint_t, wctype_t);
+wint_t    towlower(wint_t);
+wint_t    towupper(wint_t);
+wctype_t  wctype(const char *);
+
+#ifndef __cplusplus
+#undef iswdigit
+#define iswdigit(a) (0 ? iswdigit(a) : ((unsigned)(a)-'0') < 10)
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wctype.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wctype.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wctype.h	(revision 398)
@@ -0,0 +1,79 @@
+#ifndef _WCTYPE_H
+#define _WCTYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_wint_t
+#define __NEED_wctype_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_locale_t
+#endif
+
+#include <bits/alltypes.h>
+
+typedef const int * wctrans_t;
+
+#undef WEOF
+#define WEOF 0xffffffffU
+
+#undef iswdigit
+
+int       iswalnum(wint_t);
+int       iswalpha(wint_t);
+int       iswblank(wint_t);
+int       iswcntrl(wint_t);
+int       iswdigit(wint_t);
+int       iswgraph(wint_t);
+int       iswlower(wint_t);
+int       iswprint(wint_t);
+int       iswpunct(wint_t);
+int       iswspace(wint_t);
+int       iswupper(wint_t);
+int       iswxdigit(wint_t);
+int       iswctype(wint_t, wctype_t);
+wint_t    towctrans(wint_t, wctrans_t);
+wint_t    towlower(wint_t);
+wint_t    towupper(wint_t);
+wctrans_t wctrans(const char *);
+wctype_t  wctype(const char *);
+
+#ifndef __cplusplus
+#undef iswdigit
+#define iswdigit(a) (0 ? iswdigit(a) : ((unsigned)(a)-'0') < 10)
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+int iswalnum_l(wint_t, locale_t);
+int iswalpha_l(wint_t, locale_t);
+int iswblank_l(wint_t, locale_t);
+int iswcntrl_l(wint_t, locale_t);
+int iswdigit_l(wint_t, locale_t);
+int iswgraph_l(wint_t, locale_t);
+int iswlower_l(wint_t, locale_t);
+int iswprint_l(wint_t, locale_t);
+int iswpunct_l(wint_t, locale_t);
+int iswspace_l(wint_t, locale_t);
+int iswupper_l(wint_t, locale_t);
+int iswxdigit_l(wint_t, locale_t);
+int iswctype_l(wint_t, wctype_t, locale_t);
+wint_t towlower_l(wint_t, locale_t);
+wint_t towupper_l(wint_t, locale_t);
+wint_t towctrans_l(wint_t, wctrans_t, locale_t);
+wctrans_t wctrans_l(const char *, locale_t);
+wctype_t  wctype_l(const char *, locale_t);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wordexp.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wordexp.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/include/wordexp.h	(revision 398)
@@ -0,0 +1,41 @@
+#ifndef	_WORDEXP_H
+#define	_WORDEXP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+#define WRDE_DOOFFS  1
+#define WRDE_APPEND  2
+#define WRDE_NOCMD   4
+#define WRDE_REUSE   8
+#define WRDE_SHOWERR 16
+#define WRDE_UNDEF   32
+
+typedef struct {
+	size_t we_wordc;
+	char **we_wordv;
+	size_t we_offs;
+} wordexp_t;
+
+#define WRDE_NOSYS   -1
+#define WRDE_NOSPACE 1
+#define WRDE_BADCHAR 2
+#define WRDE_BADVAL  3
+#define WRDE_CMDSUB  4
+#define WRDE_SYNTAX  5
+
+int wordexp (const char *__restrict, wordexp_t *__restrict, int);
+void wordfree (wordexp_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/ldso/dlstart.~c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/ldso/dlstart.~c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/ldso/dlstart.~c	(revision 398)
@@ -0,0 +1,148 @@
+#include <stddef.h>
+#include "dynlink.h"
+
+#ifndef START
+#define START "_dlstart"
+#endif
+
+#define SHARED
+
+#include "crt_arch.h"
+
+#ifndef GETFUNCSYM
+#define GETFUNCSYM(fp, sym, got) do { \
+	__attribute__((__visibility__("hidden"))) void sym(); \
+	static void (*static_func_ptr)() = sym; \
+	__asm__ __volatile__ ( "" : "+m"(static_func_ptr) : : "memory"); \
+	*(fp) = static_func_ptr; } while(0)
+#endif
+
+__attribute__((__visibility__("hidden")))
+void _dlstart_c(size_t *sp, size_t *dynv)
+{
+	size_t i, aux[AUX_CNT], dyn[DYN_CNT];
+	size_t *rel, rel_size, base;
+
+	int argc = *sp;
+	char **argv = (void *)(sp+1);
+
+	for (i=argc+1; argv[i]; i++);
+	size_t *auxv = (void *)(argv+i+1);
+
+	for (i=0; i<AUX_CNT; i++) aux[i] = 0;
+	for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT)
+		aux[auxv[i]] = auxv[i+1];
+
+#if DL_FDPIC
+	struct fdpic_loadseg *segs, fakeseg;
+	size_t j;
+	if (dynv) {
+		/* crt_arch.h entry point asm is responsible for reserving
+		 * space and moving the extra fdpic arguments to the stack
+		 * vector where they are easily accessible from C. */
+		segs = ((struct fdpic_loadmap *)(sp[-1] ? sp[-1] : sp[-2]))->segs;
+	} else {
+		/* If dynv is null, the entry point was started from loader
+		 * that is not fdpic-aware. We can assume normal fixed-
+		 * displacement ELF loading was performed, but when ldso was
+		 * run as a command, finding the Ehdr is a heursitic: we
+		 * have to assume Phdrs start in the first 4k of the file. */
+		base = aux[AT_BASE];
+		if (!base) base = aux[AT_PHDR] & -4096;
+		segs = &fakeseg;
+		segs[0].addr = base;
+		segs[0].p_vaddr = 0;
+		segs[0].p_memsz = -1;
+		Ehdr *eh = (void *)base;
+		Phdr *ph = (void *)(base + eh->e_phoff);
+		size_t phnum = eh->e_phnum;
+		size_t phent = eh->e_phentsize;
+		while (phnum-- && ph->p_type != PT_DYNAMIC)
+			ph = (void *)((size_t)ph + phent);
+		dynv = (void *)(base + ph->p_vaddr);
+	}
+#endif
+
+	for (i=0; i<DYN_CNT; i++) dyn[i] = 0;
+	for (i=0; dynv[i]; i+=2) if (dynv[i]<DYN_CNT)
+		dyn[dynv[i]] = dynv[i+1];
+
+#if DL_FDPIC
+	for (i=0; i<DYN_CNT; i++) {
+		if (i==DT_RELASZ || i==DT_RELSZ) continue;
+		if (!dyn[i]) continue;
+		for (j=0; dyn[i]-segs[j].p_vaddr >= segs[j].p_memsz; j++);
+		dyn[i] += segs[j].addr - segs[j].p_vaddr;
+	}
+	base = 0;
+
+	const Sym *syms = (void *)dyn[DT_SYMTAB];
+
+	rel = (void *)dyn[DT_RELA];
+	rel_size = dyn[DT_RELASZ];
+	for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {
+		if (!IS_RELATIVE(rel[1], syms)) continue;
+		for (j=0; rel[0]-segs[j].p_vaddr >= segs[j].p_memsz; j++);
+		size_t *rel_addr = (void *)
+			(rel[0] + segs[j].addr - segs[j].p_vaddr);
+		if (R_TYPE(rel[1]) == REL_FUNCDESC_VAL) {
+			*rel_addr += segs[rel_addr[1]].addr
+				- segs[rel_addr[1]].p_vaddr
+				+ syms[R_SYM(rel[1])].st_value;
+			rel_addr[1] = dyn[DT_PLTGOT];
+		} else {
+			size_t val = syms[R_SYM(rel[1])].st_value;
+			for (j=0; val-segs[j].p_vaddr >= segs[j].p_memsz; j++);
+			*rel_addr = rel[2] + segs[j].addr - segs[j].p_vaddr + val;
+		}
+	}
+#else
+	/* If the dynamic linker is invoked as a command, its load
+	 * address is not available in the aux vector. Instead, compute
+	 * the load address as the difference between &_DYNAMIC and the
+	 * virtual address in the PT_DYNAMIC program header. */
+	base = aux[AT_BASE];
+	if (!base) {
+		size_t phnum = aux[AT_PHNUM];
+		size_t phentsize = aux[AT_PHENT];
+		Phdr *ph = (void *)aux[AT_PHDR];
+		for (i=phnum; i--; ph = (void *)((char *)ph + phentsize)) {
+			if (ph->p_type == PT_DYNAMIC) {
+				base = (size_t)dynv - ph->p_vaddr;
+				break;
+			}
+		}
+	}
+
+	/* MIPS uses an ugly packed form for GOT relocations. Since we
+	 * can't make function calls yet and the code is tiny anyway,
+	 * it's simply inlined here. */
+	if (NEED_MIPS_GOT_RELOCS) {
+		size_t local_cnt = 0;
+		size_t *got = (void *)(base + dyn[DT_PLTGOT]);
+		for (i=0; dynv[i]; i+=2) if (dynv[i]==DT_MIPS_LOCAL_GOTNO)
+			local_cnt = dynv[i+1];
+		for (i=0; i<local_cnt; i++) got[i] += base;
+	}
+
+	rel = (void *)(base+dyn[DT_REL]);
+	rel_size = dyn[DT_RELSZ];
+	for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) {
+		if (!IS_RELATIVE(rel[1], 0)) continue;
+		size_t *rel_addr = (void *)(base + rel[0]);
+		*rel_addr += base;
+	}
+
+	rel = (void *)(base+dyn[DT_RELA]);
+	rel_size = dyn[DT_RELASZ];
+	for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {
+		if (!IS_RELATIVE(rel[1], 0)) continue;
+		size_t *rel_addr = (void *)(base + rel[0]);
+		*rel_addr = base + rel[2];
+	}
+#endif
+
+	stage2_func dls2;
+	GETFUNCSYM(&dls2, __dls2, base+dyn[DT_PLTGOT]);
+	dls2((void *)base, sp);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/ldso/dynlink.~c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/ldso/dynlink.~c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/ldso/dynlink.~c	(revision 398)
@@ -0,0 +1,2038 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <elf.h>
+#include <sys/mman.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <link.h>
+#include <setjmp.h>
+#include <pthread.h>
+#include <ctype.h>
+#include <dlfcn.h>
+#include "pthread_impl.h"
+#include "libc.h"
+#include "dynlink.h"
+
+static void error(const char *, ...);
+
+#define MAXP2(a,b) (-(-(a)&-(b)))
+#define ALIGN(x,y) ((x)+(y)-1 & -(y))
+
+struct debug {
+	int ver;
+	void *head;
+	void (*bp)(void);
+	int state;
+	void *base;
+};
+
+struct td_index {
+	size_t args[2];
+	struct td_index *next;
+};
+
+struct dso {
+#if DL_FDPIC
+	struct fdpic_loadmap *loadmap;
+#else
+	unsigned char *base;
+#endif
+	char *name;
+	size_t *dynv;
+	struct dso *next, *prev;
+
+	Phdr *phdr;
+	int phnum;
+	size_t phentsize;
+	Sym *syms;
+	Elf_Symndx *hashtab;
+	uint32_t *ghashtab;
+	int16_t *versym;
+	char *strings;
+	struct dso *syms_next, *lazy_next;
+	size_t *lazy, lazy_cnt;
+	unsigned char *map;
+	size_t map_len;
+	dev_t dev;
+	ino_t ino;
+	char relocated;
+	char constructed;
+	char kernel_mapped;
+	struct dso **deps, *needed_by;
+	char *rpath_orig, *rpath;
+	struct tls_module tls;
+	size_t tls_id;
+	size_t relro_start, relro_end;
+	void **new_dtv;
+	unsigned char *new_tls;
+	volatile int new_dtv_idx, new_tls_idx;
+	struct td_index *td_index;
+	struct dso *fini_next;
+	char *shortname;
+#if DL_FDPIC
+	unsigned char *base;
+#else
+	struct fdpic_loadmap *loadmap;
+#endif
+	struct funcdesc {
+		void *addr;
+		size_t *got;
+	} *funcdescs;
+	size_t *got;
+	char buf[];
+};
+
+struct symdef {
+	Sym *sym;
+	struct dso *dso;
+};
+
+int __init_tp(void *);
+void __init_libc(char **, char *);
+void *__copy_tls(unsigned char *);
+
+__attribute__((__visibility__("hidden")))
+const char *__libc_get_version(void);
+
+static struct builtin_tls {
+	char c;
+	struct pthread pt;
+	void *space[16];
+} builtin_tls[1];
+#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
+
+#define ADDEND_LIMIT 4096
+static size_t *saved_addends, *apply_addends_to;
+
+static struct dso ldso;
+static struct dso *head, *tail, *fini_head, *syms_tail, *lazy_head;
+static char *env_path, *sys_path;
+static unsigned long long gencnt;
+static int runtime;
+static int ldd_mode;
+static int ldso_fail;
+static int noload;
+static jmp_buf *rtld_fail;
+static pthread_rwlock_t lock;
+static struct debug debug;
+static struct tls_module *tls_tail;
+static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;
+static size_t static_tls_cnt;
+static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE };
+static struct fdpic_loadmap *app_loadmap;
+static struct fdpic_dummy_loadmap app_dummy_loadmap;
+static struct dso *const nodeps_dummy;
+
+struct debug *_dl_debug_addr = &debug;
+
+#ifndef __c2__
+__attribute__((__visibility__("hidden")))
+void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;
+
+__attribute__((__visibility__("hidden")))
+extern void (*const __init_array_end)(void), (*const __fini_array_end)(void);
+
+weak_alias(__init_array_start, __init_array_end);
+weak_alias(__fini_array_start, __fini_array_end);
+#else
+void(*const __init_array_start)(void) = 0, (*const __fini_array_start)(void) = 0;
+#define __init_array_end __init_array_start
+#define __fini_array_end __fini_array_start
+#endif
+
+static int dl_strcmp(const char *l, const char *r)
+{
+	for (; *l==*r && *l; l++, r++);
+	return *(unsigned char *)l - *(unsigned char *)r;
+}
+#define strcmp(l,r) dl_strcmp(l,r)
+
+/* Compute load address for a virtual address in a given dso. */
+#if DL_FDPIC
+static void *laddr(const struct dso *p, size_t v)
+{
+	size_t j=0;
+	if (!p->loadmap) return p->base + v;
+	for (j=0; v-p->loadmap->segs[j].p_vaddr >= p->loadmap->segs[j].p_memsz; j++);
+	return (void *)(v - p->loadmap->segs[j].p_vaddr + p->loadmap->segs[j].addr);
+}
+#define fpaddr(p, v) ((void (*)())&(struct funcdesc){ \
+	laddr(p, v), (p)->got })
+#else
+#define laddr(p, v) (void *)((p)->base + (v))
+#define fpaddr(p, v) ((void (*)())laddr(p, v))
+#endif
+
+static void decode_vec(size_t *v, size_t *a, size_t cnt)
+{
+	size_t i;
+	for (i=0; i<cnt; i++) a[i] = 0;
+	for (; v[0]; v+=2) if (v[0]-1<cnt-1) {
+		a[0] |= 1UL<<v[0];
+		a[v[0]] = v[1];
+	}
+}
+
+static int search_vec(size_t *v, size_t *r, size_t key)
+{
+	for (; v[0]!=key; v+=2)
+		if (!v[0]) return 0;
+	*r = v[1];
+	return 1;
+}
+
+static uint32_t sysv_hash(const char *s0)
+{
+	const unsigned char *s = (void *)s0;
+	uint_fast32_t h = 0;
+	while (*s) {
+		h = 16*h + *s++;
+		h ^= h>>24 & 0xf0;
+	}
+	return h & 0xfffffff;
+}
+
+static uint32_t gnu_hash(const char *s0)
+{
+	const unsigned char *s = (void *)s0;
+	uint_fast32_t h = 5381;
+	for (; *s; s++)
+		h += h*32 + *s;
+	return h;
+}
+
+static Sym *sysv_lookup(const char *s, uint32_t h, struct dso *dso)
+{
+	size_t i;
+	Sym *syms = dso->syms;
+	Elf_Symndx *hashtab = dso->hashtab;
+	char *strings = dso->strings;
+	for (i=hashtab[2+h%hashtab[0]]; i; i=hashtab[2+hashtab[0]+i]) {
+		if ((!dso->versym || dso->versym[i] >= 0)
+		    && (!strcmp(s, strings+syms[i].st_name)))
+			return syms+i;
+	}
+	return 0;
+}
+
+static Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s)
+{
+	uint32_t nbuckets = hashtab[0];
+	uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
+	uint32_t i = buckets[h1 % nbuckets];
+
+	if (!i) return 0;
+
+	uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]);
+
+	for (h1 |= 1; ; i++) {
+		uint32_t h2 = *hashval++;
+		if ((h1 == (h2|1)) && (!dso->versym || dso->versym[i] >= 0)
+		    && !strcmp(s, dso->strings + dso->syms[i].st_name))
+			return dso->syms+i;
+		if (h2 & 1) break;
+	}
+
+	return 0;
+}
+
+static Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s, uint32_t fofs, size_t fmask)
+{
+	const size_t *bloomwords = (const void *)(hashtab+4);
+	size_t f = bloomwords[fofs & (hashtab[2]-1)];
+	if (!(f & fmask)) return 0;
+
+	f >>= (h1 >> hashtab[3]) % (8 * sizeof f);
+	if (!(f & 1)) return 0;
+
+	return gnu_lookup(h1, hashtab, dso, s);
+}
+
+#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
+#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
+
+#ifndef ARCH_SYM_REJECT_UND
+#define ARCH_SYM_REJECT_UND(s) 0
+#endif
+
+static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
+{
+	uint32_t h = 0, gh = gnu_hash(s), gho = gh / (8*sizeof(size_t)), *ght;
+	size_t ghm = 1ul << gh % (8*sizeof(size_t));
+	struct symdef def = {0};
+	for (; dso; dso=dso->syms_next) {
+		Sym *sym;
+		if ((ght = dso->ghashtab)) {
+			sym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm);
+		} else {
+			if (!h) h = sysv_hash(s);
+			sym = sysv_lookup(s, h, dso);
+		}
+		if (!sym) continue;
+		if (!sym->st_shndx)
+			if (need_def || (sym->st_info&0xf) == STT_TLS
+			    || ARCH_SYM_REJECT_UND(sym))
+				continue;
+		if (!sym->st_value)
+			if ((sym->st_info&0xf) != STT_TLS)
+				continue;
+		if (!(1<<(sym->st_info&0xf) & OK_TYPES)) continue;
+		if (!(1<<(sym->st_info>>4) & OK_BINDS)) continue;
+		def.sym = sym;
+		def.dso = dso;
+		break;
+	}
+	return def;
+}
+
+__attribute__((__visibility__("hidden")))
+ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();
+
+static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
+{
+	unsigned char *base = dso->base;
+	Sym *syms = dso->syms;
+	char *strings = dso->strings;
+	Sym *sym;
+	const char *name;
+	void *ctx;
+	int type;
+	int sym_index;
+	struct symdef def;
+	size_t *reloc_addr;
+	size_t sym_val;
+	size_t tls_val;
+	size_t addend;
+	int skip_relative = 0, reuse_addends = 0, save_slot = 0;
+
+	if (dso == &ldso) {
+		/* Only ldso's REL table needs addend saving/reuse. */
+		if (rel == apply_addends_to)
+			reuse_addends = 1;
+		skip_relative = 1;
+	}
+
+	for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
+		if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue;
+		type = R_TYPE(rel[1]);
+		if (type == REL_NONE) continue;
+		reloc_addr = laddr(dso, rel[0]);
+
+		if (stride > 2) {
+			addend = rel[2];
+		} else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {
+			addend = 0;
+		} else if (reuse_addends) {
+			/* Save original addend in stage 2 where the dso
+			 * chain consists of just ldso; otherwise read back
+			 * saved addend since the inline one was clobbered. */
+			if (head==&ldso)
+				saved_addends[save_slot] = *reloc_addr;
+			addend = saved_addends[save_slot++];
+		} else {
+			addend = *reloc_addr;
+		}
+
+		sym_index = R_SYM(rel[1]);
+		if (sym_index) {
+			sym = syms + sym_index;
+			name = strings + sym->st_name;
+			ctx = type==REL_COPY ? head->syms_next : head;
+			def = (sym->st_info&0xf) == STT_SECTION
+				? (struct symdef){ .dso = dso, .sym = sym }
+				: find_sym(ctx, name, type==REL_PLT);
+			if (!def.sym && (sym->st_shndx != SHN_UNDEF
+			    || sym->st_info>>4 != STB_WEAK)) {
+				if (dso->lazy && (type==REL_PLT || type==REL_GOT)) {
+					dso->lazy[3*dso->lazy_cnt+0] = rel[0];
+					dso->lazy[3*dso->lazy_cnt+1] = rel[1];
+					dso->lazy[3*dso->lazy_cnt+2] = addend;
+					dso->lazy_cnt++;
+					continue;
+				}
+				error("Error relocating %s: %s: symbol not found",
+					dso->name, name);
+				if (runtime) longjmp(*rtld_fail, 1);
+				continue;
+			}
+		} else {
+			sym = 0;
+			def.sym = 0;
+			def.dso = dso;
+		}
+
+		sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0;
+		tls_val = def.sym ? def.sym->st_value : 0;
+
+		switch(type) {
+		case REL_NONE:
+			break;
+		case REL_OFFSET:
+			addend -= (size_t)reloc_addr;
+		case REL_SYMBOLIC:
+		case REL_GOT:
+		case REL_PLT:
+			*reloc_addr = sym_val + addend;
+			break;
+		case REL_RELATIVE:
+			*reloc_addr = (size_t)base + addend;
+			break;
+		case REL_SYM_OR_REL:
+			if (sym) *reloc_addr = sym_val + addend;
+			else *reloc_addr = (size_t)base + addend;
+			break;
+		case REL_COPY:
+			memcpy(reloc_addr, (void *)sym_val, sym->st_size);
+			break;
+		case REL_OFFSET32:
+			*(uint32_t *)reloc_addr = sym_val + addend
+				- (size_t)reloc_addr;
+			break;
+		case REL_FUNCDESC:
+			*reloc_addr = def.sym ? (size_t)(def.dso->funcdescs
+				+ (def.sym - def.dso->syms)) : 0;
+			break;
+		case REL_FUNCDESC_VAL:
+			if ((sym->st_info&0xf) == STT_SECTION) *reloc_addr += sym_val;
+			else *reloc_addr = sym_val;
+			reloc_addr[1] = def.sym ? (size_t)def.dso->got : 0;
+			break;
+		case REL_DTPMOD:
+			*reloc_addr = def.dso->tls_id;
+			break;
+		case REL_DTPOFF:
+			*reloc_addr = tls_val + addend - DTP_OFFSET;
+			break;
+#ifdef TLS_ABOVE_TP
+		case REL_TPOFF:
+			*reloc_addr = tls_val + def.dso->tls.offset + TPOFF_K + addend;
+			break;
+#else
+		case REL_TPOFF:
+			*reloc_addr = tls_val - def.dso->tls.offset + addend;
+			break;
+		case REL_TPOFF_NEG:
+			*reloc_addr = def.dso->tls.offset - tls_val + addend;
+			break;
+#endif
+		case REL_TLSDESC:
+			if (stride<3) addend = reloc_addr[1];
+			if (runtime && def.dso->tls_id >= static_tls_cnt) {
+				struct td_index *new = malloc(sizeof *new);
+				if (!new) {
+					error(
+					"Error relocating %s: cannot allocate TLSDESC for %s",
+					dso->name, sym ? name : "(local)" );
+					longjmp(*rtld_fail, 1);
+				}
+				new->next = dso->td_index;
+				dso->td_index = new;
+				new->args[0] = def.dso->tls_id;
+				new->args[1] = tls_val + addend;
+				reloc_addr[0] = (size_t)__tlsdesc_dynamic;
+				reloc_addr[1] = (size_t)new;
+			} else {
+				reloc_addr[0] = (size_t)__tlsdesc_static;
+#ifdef TLS_ABOVE_TP
+				reloc_addr[1] = tls_val + def.dso->tls.offset
+					+ TPOFF_K + addend;
+#else
+				reloc_addr[1] = tls_val - def.dso->tls.offset
+					+ addend;
+#endif
+			}
+			break;
+		default:
+			error("Error relocating %s: unsupported relocation type %d",
+				dso->name, type);
+			if (runtime) longjmp(*rtld_fail, 1);
+			continue;
+		}
+	}
+}
+
+static void redo_lazy_relocs()
+{
+	struct dso *p = lazy_head, *next;
+	lazy_head = 0;
+	for (; p; p=next) {
+		next = p->lazy_next;
+		size_t size = p->lazy_cnt*3*sizeof(size_t);
+		p->lazy_cnt = 0;
+		do_relocs(p, p->lazy, size, 3);
+		if (p->lazy_cnt) {
+			p->lazy_next = lazy_head;
+			lazy_head = p;
+		} else {
+			free(p->lazy);
+			p->lazy = 0;
+			p->lazy_next = 0;
+		}
+	}
+}
+
+/* A huge hack: to make up for the wastefulness of shared libraries
+ * needing at least a page of dirty memory even if they have no global
+ * data, we reclaim the gaps at the beginning and end of writable maps
+ * and "donate" them to the heap by setting up minimal malloc
+ * structures and then freeing them. */
+
+static void reclaim(struct dso *dso, size_t start, size_t end)
+{
+	size_t *a, *z;
+	if (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end;
+	if (end   >= dso->relro_start && end   < dso->relro_end) end = dso->relro_start;
+	start = start + 6*sizeof(size_t)-1 & -4*sizeof(size_t);
+	end = (end & -4*sizeof(size_t)) - 2*sizeof(size_t);
+	if (start>end || end-start < 4*sizeof(size_t)) return;
+	a = laddr(dso, start);
+	z = laddr(dso, end);
+	a[-2] = 1;
+	a[-1] = z[0] = end-start + 2*sizeof(size_t) | 1;
+	z[1] = 1;
+	free(a);
+}
+
+static void reclaim_gaps(struct dso *dso)
+{
+	Phdr *ph = dso->phdr;
+	size_t phcnt = dso->phnum;
+
+	if (DL_FDPIC) return; // FIXME
+	for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) {
+		if (ph->p_type!=PT_LOAD) continue;
+		if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue;
+		reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr);
+		reclaim(dso, ph->p_vaddr+ph->p_memsz,
+			ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE);
+	}
+}
+
+static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
+{
+	static int no_map_fixed;
+	char *q;
+	if (!no_map_fixed) {
+		q = mmap(p, n, prot, flags|MAP_FIXED, fd, off);
+		if (!DL_NOMMU_SUPPORT || q != MAP_FAILED || errno != EINVAL)
+			return q;
+		no_map_fixed = 1;
+	}
+	/* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
+	if (flags & MAP_ANONYMOUS) {
+		memset(p, 0, n);
+		return p;
+	}
+	ssize_t r;
+	if (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED;
+	for (q=p; n; q+=r, off+=r, n-=r) {
+		r = read(fd, q, n);
+		if (r < 0 && errno != EINTR) return MAP_FAILED;
+		if (!r) {
+			memset(q, 0, n);
+			break;
+		}
+	}
+	return p;
+}
+
+static void unmap_library(struct dso *dso)
+{
+	if (dso->loadmap) {
+		size_t i;
+		for (i=0; i<dso->loadmap->nsegs; i++) {
+			if (!dso->loadmap->segs[i].p_memsz)
+				continue;
+			munmap((void *)dso->loadmap->segs[i].addr,
+				dso->loadmap->segs[i].p_memsz);
+		}
+		free(dso->loadmap);
+	} else if (dso->map && dso->map_len) {
+		munmap(dso->map, dso->map_len);
+	}
+}
+
+static void *map_library(int fd, struct dso *dso)
+{
+	Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
+	void *allocated_buf=0;
+	size_t phsize;
+	size_t addr_min=SIZE_MAX, addr_max=0, map_len;
+	size_t this_min, this_max;
+	size_t nsegs = 0;
+	off_t off_start;
+	Ehdr *eh;
+	Phdr *ph, *ph0;
+	unsigned prot;
+	unsigned char *map=MAP_FAILED, *base;
+	size_t dyn=0;
+	size_t tls_image=0;
+	size_t i;
+
+	ssize_t l = read(fd, buf, sizeof buf);
+	eh = buf;
+	if (l<0) return 0;
+	if (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC))
+		goto noexec;
+	phsize = eh->e_phentsize * eh->e_phnum;
+	if (phsize > sizeof buf - sizeof *eh) {
+		allocated_buf = malloc(phsize);
+		if (!allocated_buf) return 0;
+		l = pread(fd, allocated_buf, phsize, eh->e_phoff);
+		if (l < 0) goto error;
+		if (l != phsize) goto noexec;
+		ph = ph0 = allocated_buf;
+	} else if (eh->e_phoff + phsize > l) {
+		l = pread(fd, buf+1, phsize, eh->e_phoff);
+		if (l < 0) goto error;
+		if (l != phsize) goto noexec;
+		ph = ph0 = (void *)(buf + 1);
+	} else {
+		ph = ph0 = (void *)((char *)buf + eh->e_phoff);
+	}
+	for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
+		if (ph->p_type == PT_DYNAMIC) {
+			dyn = ph->p_vaddr;
+		} else if (ph->p_type == PT_TLS) {
+			tls_image = ph->p_vaddr;
+			dso->tls.align = ph->p_align;
+			dso->tls.len = ph->p_filesz;
+			dso->tls.size = ph->p_memsz;
+		} else if (ph->p_type == PT_GNU_RELRO) {
+			dso->relro_start = ph->p_vaddr & -PAGE_SIZE;
+			dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
+		}
+		if (ph->p_type != PT_LOAD) continue;
+		nsegs++;
+		if (ph->p_vaddr < addr_min) {
+			addr_min = ph->p_vaddr;
+			off_start = ph->p_offset;
+			prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
+				((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
+				((ph->p_flags&PF_X) ? PROT_EXEC : 0));
+		}
+		if (ph->p_vaddr+ph->p_memsz > addr_max) {
+			addr_max = ph->p_vaddr+ph->p_memsz;
+		}
+	}
+	if (!dyn) goto noexec;
+	if (DL_FDPIC && !(eh->e_flags & FDPIC_CONSTDISP_FLAG)) {
+		dso->loadmap = calloc(1, sizeof *dso->loadmap
+			+ nsegs * sizeof *dso->loadmap->segs);
+		if (!dso->loadmap) goto error;
+		dso->loadmap->nsegs = nsegs;
+		for (ph=ph0, i=0; i<nsegs; ph=(void *)((char *)ph+eh->e_phentsize)) {
+			if (ph->p_type != PT_LOAD) continue;
+			prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
+				((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
+				((ph->p_flags&PF_X) ? PROT_EXEC : 0));
+			map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),
+				prot, MAP_PRIVATE,
+				fd, ph->p_offset & -PAGE_SIZE);
+			if (map == MAP_FAILED) {
+				unmap_library(dso);
+				goto error;
+			}
+			dso->loadmap->segs[i].addr = (size_t)map +
+				(ph->p_vaddr & PAGE_SIZE-1);
+			dso->loadmap->segs[i].p_vaddr = ph->p_vaddr;
+			dso->loadmap->segs[i].p_memsz = ph->p_memsz;
+			i++;
+			if (prot & PROT_WRITE) {
+				size_t brk = (ph->p_vaddr & PAGE_SIZE-1)
+					+ ph->p_filesz;
+				size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE;
+				size_t pgend = brk + ph->p_memsz - ph->p_filesz
+					+ PAGE_SIZE-1 & -PAGE_SIZE;
+				if (pgend > pgbrk && mmap_fixed(map+pgbrk,
+					pgend-pgbrk, prot,
+					MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
+					-1, off_start) == MAP_FAILED)
+					goto error;
+				memset(map + brk, 0, pgbrk-brk);
+			}
+		}
+		map = (void *)dso->loadmap->segs[0].addr;
+		map_len = 0;
+		goto done_mapping;
+	}
+	addr_max += PAGE_SIZE-1;
+	addr_max &= -PAGE_SIZE;
+	addr_min &= -PAGE_SIZE;
+	off_start &= -PAGE_SIZE;
+	map_len = addr_max - addr_min + off_start;
+	/* The first time, we map too much, possibly even more than
+	 * the length of the file. This is okay because we will not
+	 * use the invalid part; we just need to reserve the right
+	 * amount of virtual address space to map over later. */
+	map = DL_NOMMU_SUPPORT
+		? mmap((void *)addr_min, map_len, PROT_READ|PROT_WRITE|PROT_EXEC,
+			MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
+		: mmap((void *)addr_min, map_len, prot,
+			MAP_PRIVATE, fd, off_start);
+	if (map==MAP_FAILED) goto error;
+	dso->map = map;
+	dso->map_len = map_len;
+	/* If the loaded file is not relocatable and the requested address is
+	 * not available, then the load operation must fail. */
+	if (eh->e_type != ET_DYN && addr_min && map!=(void *)addr_min) {
+		errno = EBUSY;
+		goto error;
+	}
+	base = map - addr_min;
+	dso->phdr = 0;
+	dso->phnum = 0;
+	for (ph=ph0, i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) {
+		if (ph->p_type != PT_LOAD) continue;
+		/* Check if the programs headers are in this load segment, and
+		 * if so, record the address for use by dl_iterate_phdr. */
+		if (!dso->phdr && eh->e_phoff >= ph->p_offset
+		    && eh->e_phoff+phsize <= ph->p_offset+ph->p_filesz) {
+			dso->phdr = (void *)(base + ph->p_vaddr
+				+ (eh->e_phoff-ph->p_offset));
+			dso->phnum = eh->e_phnum;
+			dso->phentsize = eh->e_phentsize;
+		}
+		/* Reuse the existing mapping for the lowest-address LOAD */
+		if ((ph->p_vaddr & -PAGE_SIZE) == addr_min && !DL_NOMMU_SUPPORT)
+			continue;
+		this_min = ph->p_vaddr & -PAGE_SIZE;
+		this_max = ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE;
+		off_start = ph->p_offset & -PAGE_SIZE;
+		prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
+			((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
+			((ph->p_flags&PF_X) ? PROT_EXEC : 0));
+		if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
+			goto error;
+		if (ph->p_memsz > ph->p_filesz) {
+			size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
+			size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
+			memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
+			if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
+				goto error;
+		}
+	}
+	for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
+		if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
+			if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC)
+			    && errno != ENOSYS)
+				goto error;
+			break;
+		}
+done_mapping:
+	dso->base = base;
+	dso->dynv = laddr(dso, dyn);
+	if (dso->tls.size) dso->tls.image = laddr(dso, tls_image);
+	if (!runtime) reclaim_gaps(dso);
+	free(allocated_buf);
+	return map;
+noexec:
+	errno = ENOEXEC;
+error:
+	if (map!=MAP_FAILED) unmap_library(dso);
+	free(allocated_buf);
+	return 0;
+}
+
+static int path_open(const char *name, const char *s, char *buf, size_t buf_size)
+{
+	size_t l;
+	int fd;
+	for (;;) {
+		s += strspn(s, ":\n");
+		l = strcspn(s, ":\n");
+		if (l-1 >= INT_MAX) return -1;
+		if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
+			if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;
+			switch (errno) {
+			case ENOENT:
+			case ENOTDIR:
+			case EACCES:
+			case ENAMETOOLONG:
+				break;
+			default:
+				/* Any negative value but -1 will inhibit
+				 * futher path search. */
+				return -2;
+			}
+		}
+		s += l;
+	}
+}
+
+static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
+{
+	size_t n, l;
+	const char *s, *t, *origin;
+	char *d;
+	if (p->rpath || !p->rpath_orig) return 0;
+	if (!strchr(p->rpath_orig, '$')) {
+		p->rpath = p->rpath_orig;
+		return 0;
+	}
+	n = 0;
+	s = p->rpath_orig;
+	while ((t=strchr(s, '$'))) {
+		if (strncmp(t, "$ORIGIN", 7) && strncmp(t, "${ORIGIN}", 9))
+			return 0;
+		s = t+1;
+		n++;
+	}
+	if (n > SSIZE_MAX/PATH_MAX) return 0;
+
+	if (p->kernel_mapped) {
+		/* $ORIGIN searches cannot be performed for the main program
+		 * when it is suid/sgid/AT_SECURE. This is because the
+		 * pathname is under the control of the caller of execve.
+		 * For libraries, however, $ORIGIN can be processed safely
+		 * since the library's pathname came from a trusted source
+		 * (either system paths or a call to dlopen). */
+		if (libc.secure)
+			return 0;
+		l = readlink("/proc/self/exe", buf, buf_size);
+		if (l == -1) switch (errno) {
+		case ENOENT:
+		case ENOTDIR:
+		case EACCES:
+			break;
+		default:
+			return -1;
+		}
+		if (l >= buf_size)
+			return 0;
+		buf[l] = 0;
+		origin = buf;
+	} else {
+		origin = p->name;
+	}
+	t = strrchr(origin, '/');
+	l = t ? t-origin : 0;
+	p->rpath = malloc(strlen(p->rpath_orig) + n*l + 1);
+	if (!p->rpath) return -1;
+
+	d = p->rpath;
+	s = p->rpath_orig;
+	while ((t=strchr(s, '$'))) {
+		memcpy(d, s, t-s);
+		d += t-s;
+		memcpy(d, origin, l);
+		d += l;
+		/* It was determined previously that the '$' is followed
+		 * either by "ORIGIN" or "{ORIGIN}". */
+		s = t + 7 + 2*(t[1]=='{');
+	}
+	strcpy(d, s);
+	return 0;
+}
+
+static void decode_dyn(struct dso *p)
+{
+	size_t dyn[DYN_CNT];
+	decode_vec(p->dynv, dyn, DYN_CNT);
+	p->syms = laddr(p, dyn[DT_SYMTAB]);
+	p->strings = laddr(p, dyn[DT_STRTAB]);
+	if (dyn[0]&(1<<DT_HASH))
+		p->hashtab = laddr(p, dyn[DT_HASH]);
+	if (dyn[0]&(1<<DT_RPATH))
+		p->rpath_orig = p->strings + dyn[DT_RPATH];
+	if (dyn[0]&(1<<DT_RUNPATH))
+		p->rpath_orig = p->strings + dyn[DT_RUNPATH];
+	if (dyn[0]&(1<<DT_PLTGOT))
+		p->got = laddr(p, dyn[DT_PLTGOT]);
+	if (search_vec(p->dynv, dyn, DT_GNU_HASH))
+		p->ghashtab = laddr(p, *dyn);
+	if (search_vec(p->dynv, dyn, DT_VERSYM))
+		p->versym = laddr(p, *dyn);
+}
+
+static size_t count_syms(struct dso *p)
+{
+	if (p->hashtab) return p->hashtab[1];
+
+	size_t nsym, i;
+	uint32_t *buckets = p->ghashtab + 4 + (p->ghashtab[2]*sizeof(size_t)/4);
+	uint32_t *hashval;
+	for (i = nsym = 0; i < p->ghashtab[0]; i++) {
+		if (buckets[i] > nsym)
+			nsym = buckets[i];
+	}
+	if (nsym) {
+		hashval = buckets + p->ghashtab[0] + (nsym - p->ghashtab[1]);
+		do nsym++;
+		while (!(*hashval++ & 1));
+	}
+	return nsym;
+}
+
+static void *dl_mmap(size_t n)
+{
+	void *p;
+	int prot = PROT_READ|PROT_WRITE, flags = MAP_ANONYMOUS|MAP_PRIVATE;
+#ifdef SYS_mmap2
+	p = (void *)__syscall(SYS_mmap2, 0, n, prot, flags, -1, 0);
+#else
+	p = (void *)__syscall(SYS_mmap, 0, n, prot, flags, -1, 0);
+#endif
+	return p == MAP_FAILED ? 0 : p;
+}
+
+static void makefuncdescs(struct dso *p)
+{
+	static int self_done;
+	size_t nsym = count_syms(p);
+	size_t i, size = nsym * sizeof(*p->funcdescs);
+
+	if (!self_done) {
+		p->funcdescs = dl_mmap(size);
+		self_done = 1;
+	} else {
+		p->funcdescs = malloc(size);
+	}
+	if (!p->funcdescs) {
+		if (!runtime) a_crash();
+		error("Error allocating function descriptors for %s", p->name);
+		longjmp(*rtld_fail, 1);
+	}
+	for (i=0; i<nsym; i++) {
+		if ((p->syms[i].st_info&0xf)==STT_FUNC && p->syms[i].st_shndx) {
+			p->funcdescs[i].addr = laddr(p, p->syms[i].st_value);
+			p->funcdescs[i].got = p->got;
+		} else {
+			p->funcdescs[i].addr = 0;
+			p->funcdescs[i].got = 0;
+		}
+	}
+}
+
+static struct dso *load_library(const char *name, struct dso *needed_by)
+{
+	char buf[2*NAME_MAX+2];
+	const char *pathname;
+	unsigned char *map;
+	struct dso *p, temp_dso = {0};
+	int fd;
+	struct stat st;
+	size_t alloc_size;
+	int n_th = 0;
+	int is_self = 0;
+
+	if (!*name) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	/* Catch and block attempts to reload the implementation itself */
+	if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
+		static const char reserved[] =
+			"c.pthread.rt.m.dl.util.xnet.";
+		const char *rp, *next;
+		for (rp=reserved; *rp; rp=next) {
+			next = strchr(rp, '.') + 1;
+			if (strncmp(name+3, rp, next-rp) == 0)
+				break;
+		}
+		if (*rp) {
+			if (ldd_mode) {
+				/* Track which names have been resolved
+				 * and only report each one once. */
+				static unsigned reported;
+				unsigned mask = 1U<<(rp-reserved);
+				if (!(reported & mask)) {
+					reported |= mask;
+					dprintf(1, "\t%s => %s (%p)\n",
+						name, ldso.name,
+						ldso.base);
+				}
+			}
+			is_self = 1;
+		}
+	}
+	if (!strcmp(name, ldso.name)) is_self = 1;
+	if (is_self) {
+		if (!ldso.prev) {
+			tail->next = &ldso;
+			ldso.prev = tail;
+			tail = &ldso;
+		}
+		return &ldso;
+	}
+	if (strchr(name, '/')) {
+		pathname = name;
+		fd = open(name, O_RDONLY|O_CLOEXEC);
+	} else {
+		/* Search for the name to see if it's already loaded */
+		for (p=head->next; p; p=p->next) {
+			if (p->shortname && !strcmp(p->shortname, name)) {
+				return p;
+			}
+		}
+		if (strlen(name) > NAME_MAX) return 0;
+		fd = -1;
+		if (env_path) fd = path_open(name, env_path, buf, sizeof buf);
+		for (p=needed_by; fd == -1 && p; p=p->needed_by) {
+			if (fixup_rpath(p, buf, sizeof buf) < 0)
+				fd = -2; /* Inhibit further search. */
+			if (p->rpath)
+				fd = path_open(name, p->rpath, buf, sizeof buf);
+		}
+		if (fd == -1) {
+			if (!sys_path) {
+				char *prefix = 0;
+				size_t prefix_len;
+				if (ldso.name[0]=='/') {
+					char *s, *t, *z;
+					for (s=t=z=ldso.name; *s; s++)
+						if (*s=='/') z=t, t=s;
+					prefix_len = z-ldso.name;
+					if (prefix_len < PATH_MAX)
+						prefix = ldso.name;
+				}
+				if (!prefix) {
+					prefix = "";
+					prefix_len = 0;
+				}
+				char etc_ldso_path[prefix_len + 1
+					+ sizeof "/etc/ld-musl-" LDSO_ARCH ".path"];
+				snprintf(etc_ldso_path, sizeof etc_ldso_path,
+					"%.*s/etc/ld-musl-" LDSO_ARCH ".path",
+					(int)prefix_len, prefix);
+				FILE *f = fopen(etc_ldso_path, "rbe");
+				if (f) {
+					if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) {
+						free(sys_path);
+						sys_path = "";
+					}
+					fclose(f);
+				} else if (errno != ENOENT) {
+					sys_path = "";
+				}
+			}
+			if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
+			fd = path_open(name, sys_path, buf, sizeof buf);
+		}
+		pathname = buf;
+	}
+	if (fd < 0) return 0;
+	if (fstat(fd, &st) < 0) {
+		close(fd);
+		return 0;
+	}
+	for (p=head->next; p; p=p->next) {
+		if (p->dev == st.st_dev && p->ino == st.st_ino) {
+			/* If this library was previously loaded with a
+			 * pathname but a search found the same inode,
+			 * setup its shortname so it can be found by name. */
+			if (!p->shortname && pathname != name)
+				p->shortname = strrchr(p->name, '/')+1;
+			close(fd);
+			return p;
+		}
+	}
+	map = noload ? 0 : map_library(fd, &temp_dso);
+	close(fd);
+	if (!map) return 0;
+
+	/* Avoid the danger of getting two versions of libc mapped into the
+	 * same process when an absolute pathname was used. The symbols
+	 * checked are chosen to catch both musl and glibc, and to avoid
+	 * false positives from interposition-hack libraries. */
+	decode_dyn(&temp_dso);
+	if (find_sym(&temp_dso, "__libc_start_main", 1).sym &&
+	    find_sym(&temp_dso, "stdin", 1).sym) {
+		unmap_library(&temp_dso);
+		return load_library("libc.so", needed_by);
+	}
+
+	/* Allocate storage for the new DSO. When there is TLS, this
+	 * storage must include a reservation for all pre-existing
+	 * threads to obtain copies of both the new TLS, and an
+	 * extended DTV capable of storing an additional slot for
+	 * the newly-loaded DSO. */
+	alloc_size = sizeof *p + strlen(pathname) + 1;
+	if (runtime && temp_dso.tls.image) {
+		size_t per_th = temp_dso.tls.size + temp_dso.tls.align
+			+ sizeof(void *) * (tls_cnt+3);
+		n_th = libc.threads_minus_1 + 1;
+		if (n_th > SSIZE_MAX / per_th) alloc_size = SIZE_MAX;
+		else alloc_size += n_th * per_th;
+	}
+	p = calloc(1, alloc_size);
+	if (!p) {
+		unmap_library(&temp_dso);
+		return 0;
+	}
+	memcpy(p, &temp_dso, sizeof temp_dso);
+	p->dev = st.st_dev;
+	p->ino = st.st_ino;
+	p->needed_by = needed_by;
+	p->name = p->buf;
+	strcpy(p->name, pathname);
+	/* Add a shortname only if name arg was not an explicit pathname. */
+	if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
+	if (p->tls.image) {
+		p->tls_id = ++tls_cnt;
+		tls_align = MAXP2(tls_align, p->tls.align);
+#ifdef TLS_ABOVE_TP
+		p->tls.offset = tls_offset + ( (tls_align-1) &
+			-(tls_offset + (uintptr_t)p->tls.image) );
+		tls_offset += p->tls.size;
+#else
+		tls_offset += p->tls.size + p->tls.align - 1;
+		tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
+			& (p->tls.align-1);
+		p->tls.offset = tls_offset;
+#endif
+		p->new_dtv = (void *)(-sizeof(size_t) &
+			(uintptr_t)(p->name+strlen(p->name)+sizeof(size_t)));
+		p->new_tls = (void *)(p->new_dtv + n_th*(tls_cnt+1));
+		if (tls_tail) tls_tail->next = &p->tls;
+		else libc.tls_head = &p->tls;
+		tls_tail = &p->tls;
+	}
+
+	tail->next = p;
+	p->prev = tail;
+	tail = p;
+
+	if (DL_FDPIC) makefuncdescs(p);
+
+	if (ldd_mode) dprintf(1, "\t%s => %s (%p)\n", name, pathname, p->base);
+
+	return p;
+}
+
+static void load_deps(struct dso *p)
+{
+	size_t i, ndeps=0;
+	struct dso ***deps = &p->deps, **tmp, *dep;
+	for (; p; p=p->next) {
+		for (i=0; p->dynv[i]; i+=2) {
+			if (p->dynv[i] != DT_NEEDED) continue;
+			dep = load_library(p->strings + p->dynv[i+1], p);
+			if (!dep) {
+				error("Error loading shared library %s: %m (needed by %s)",
+					p->strings + p->dynv[i+1], p->name);
+				if (runtime) longjmp(*rtld_fail, 1);
+				continue;
+			}
+			if (runtime) {
+				tmp = realloc(*deps, sizeof(*tmp)*(ndeps+2));
+				if (!tmp) longjmp(*rtld_fail, 1);
+				tmp[ndeps++] = dep;
+				tmp[ndeps] = 0;
+				*deps = tmp;
+			}
+		}
+	}
+	if (!*deps) *deps = (struct dso **)&nodeps_dummy;
+}
+
+static void load_preload(char *s)
+{
+	int tmp;
+	char *z;
+	for (z=s; *z; s=z) {
+		for (   ; *s && (isspace(*s) || *s==':'); s++);
+		for (z=s; *z && !isspace(*z) && *z!=':'; z++);
+		tmp = *z;
+		*z = 0;
+		load_library(s, 0);
+		*z = tmp;
+	}
+}
+
+static void add_syms(struct dso *p)
+{
+	if (!p->syms_next && syms_tail != p) {
+		syms_tail->syms_next = p;
+		syms_tail = p;
+	}
+}
+
+static void revert_syms(struct dso *old_tail)
+{
+	struct dso *p, *next;
+	/* Chop off the tail of the list of dsos that participate in
+	 * the global symbol table, reverting them to RTLD_LOCAL. */
+	for (p=old_tail; p; p=next) {
+		next = p->syms_next;
+		p->syms_next = 0;
+	}
+	syms_tail = old_tail;
+}
+
+static void do_mips_relocs(struct dso *p, size_t *got)
+{
+	size_t i, j, rel[2];
+	unsigned char *base = p->base;
+	i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO);
+	if (p==&ldso) {
+		got += i;
+	} else {
+		while (i--) *got++ += (size_t)base;
+	}
+	j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
+	i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
+	Sym *sym = p->syms + j;
+	rel[0] = (unsigned char *)got - base;
+	for (i-=j; i; i--, sym++, rel[0]+=sizeof(size_t)) {
+		rel[1] = R_INFO(sym-p->syms, R_MIPS_JUMP_SLOT);
+		do_relocs(p, rel, sizeof rel, 2);
+	}
+}
+
+static void reloc_all(struct dso *p)
+{
+	size_t dyn[DYN_CNT];
+	for (; p; p=p->next) {
+		if (p->relocated) continue;
+		decode_vec(p->dynv, dyn, DYN_CNT);
+		if (NEED_MIPS_GOT_RELOCS)
+			do_mips_relocs(p, laddr(p, dyn[DT_PLTGOT]));
+		do_relocs(p, laddr(p, dyn[DT_JMPREL]), dyn[DT_PLTRELSZ],
+			2+(dyn[DT_PLTREL]==DT_RELA));
+		do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);
+		do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);
+
+		if (head != &ldso && p->relro_start != p->relro_end &&
+		    mprotect(laddr(p, p->relro_start), p->relro_end-p->relro_start, PROT_READ)
+		    && errno != ENOSYS) {
+			error("Error relocating %s: RELRO protection failed: %m",
+				p->name);
+			if (runtime) longjmp(*rtld_fail, 1);
+		}
+
+		p->relocated = 1;
+	}
+}
+
+static void kernel_mapped_dso(struct dso *p)
+{
+	size_t min_addr = -1, max_addr = 0, cnt;
+	Phdr *ph = p->phdr;
+	for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) {
+		if (ph->p_type == PT_DYNAMIC) {
+			p->dynv = laddr(p, ph->p_vaddr);
+		} else if (ph->p_type == PT_GNU_RELRO) {
+			p->relro_start = ph->p_vaddr & -PAGE_SIZE;
+			p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
+		}
+		if (ph->p_type != PT_LOAD) continue;
+		if (ph->p_vaddr < min_addr)
+			min_addr = ph->p_vaddr;
+		if (ph->p_vaddr+ph->p_memsz > max_addr)
+			max_addr = ph->p_vaddr+ph->p_memsz;
+	}
+	min_addr &= -PAGE_SIZE;
+	max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE;
+	p->map = p->base + min_addr;
+	p->map_len = max_addr - min_addr;
+	p->kernel_mapped = 1;
+}
+
+void __libc_exit_fini()
+{
+	struct dso *p;
+	size_t dyn[DYN_CNT];
+	for (p=fini_head; p; p=p->fini_next) {
+		if (!p->constructed) continue;
+		decode_vec(p->dynv, dyn, DYN_CNT);
+		if (dyn[0] & (1<<DT_FINI_ARRAY)) {
+			size_t n = dyn[DT_FINI_ARRAYSZ]/sizeof(size_t);
+			size_t *fn = (size_t *)laddr(p, dyn[DT_FINI_ARRAY])+n;
+			while (n--) ((void (*)(void))*--fn)();
+		}
+#ifndef NO_LEGACY_INITFINI
+		if ((dyn[0] & (1<<DT_FINI)) && dyn[DT_FINI])
+			fpaddr(p, dyn[DT_FINI])();
+#endif
+	}
+}
+
+static void do_init_fini(struct dso *p)
+{
+	size_t dyn[DYN_CNT];
+	int need_locking = libc.threads_minus_1;
+	/* Allow recursive calls that arise when a library calls
+	 * dlopen from one of its constructors, but block any
+	 * other threads until all ctors have finished. */
+	if (need_locking) pthread_mutex_lock(&init_fini_lock);
+	for (; p; p=p->prev) {
+		if (p->constructed) continue;
+		p->constructed = 1;
+		decode_vec(p->dynv, dyn, DYN_CNT);
+		if (dyn[0] & ((1<<DT_FINI) | (1<<DT_FINI_ARRAY))) {
+			p->fini_next = fini_head;
+			fini_head = p;
+		}
+#ifndef NO_LEGACY_INITFINI
+		if ((dyn[0] & (1<<DT_INIT)) && dyn[DT_INIT])
+			fpaddr(p, dyn[DT_INIT])();
+#endif
+		if (dyn[0] & (1<<DT_INIT_ARRAY)) {
+			size_t n = dyn[DT_INIT_ARRAYSZ]/sizeof(size_t);
+			size_t *fn = laddr(p, dyn[DT_INIT_ARRAY]);
+			while (n--) ((void (*)(void))*fn++)();
+		}
+		if (!need_locking && libc.threads_minus_1) {
+			need_locking = 1;
+			pthread_mutex_lock(&init_fini_lock);
+		}
+	}
+	if (need_locking) pthread_mutex_unlock(&init_fini_lock);
+}
+
+#ifndef __c2__
+void __libc_start_init(void)
+{
+	do_init_fini(tail);
+}
+#endif
+
+static void dl_debug_state(void)
+{
+}
+
+#ifndef __c2__
+weak_alias(dl_debug_state, _dl_debug_state);
+
+void __init_tls(size_t *auxv)
+{
+}
+#else
+__attribute__((weak))
+void _dl_debug_state(void)
+{
+	dl_debug_state();
+}
+#endif
+
+__attribute__((__visibility__("hidden")))
+void *__tls_get_new(tls_mod_off_t *v)
+{
+	pthread_t self = __pthread_self();
+
+	/* Block signals to make accessing new TLS async-signal-safe */
+	sigset_t set;
+	__block_all_sigs(&set);
+	if (v[0]<=(size_t)self->dtv[0]) {
+		__restore_sigs(&set);
+		return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
+	}
+
+	/* This is safe without any locks held because, if the caller
+	 * is able to request the Nth entry of the DTV, the DSO list
+	 * must be valid at least that far out and it was synchronized
+	 * at program startup or by an already-completed call to dlopen. */
+	struct dso *p;
+	for (p=head; p->tls_id != v[0]; p=p->next);
+
+	/* Get new DTV space from new DSO if needed */
+	if (v[0] > (size_t)self->dtv[0]) {
+		void **newdtv = p->new_dtv +
+			(v[0]+1)*a_fetch_add(&p->new_dtv_idx,1);
+		memcpy(newdtv, self->dtv,
+			((size_t)self->dtv[0]+1) * sizeof(void *));
+		newdtv[0] = (void *)v[0];
+		self->dtv = self->dtv_copy = newdtv;
+	}
+
+	/* Get new TLS memory from all new DSOs up to the requested one */
+	unsigned char *mem;
+	for (p=head; ; p=p->next) {
+		if (!p->tls_id || self->dtv[p->tls_id]) continue;
+		mem = p->new_tls + (p->tls.size + p->tls.align)
+			* a_fetch_add(&p->new_tls_idx,1);
+		mem += ((uintptr_t)p->tls.image - (uintptr_t)mem)
+			& (p->tls.align-1);
+		self->dtv[p->tls_id] = mem;
+		memcpy(mem, p->tls.image, p->tls.len);
+		if (p->tls_id == v[0]) break;
+	}
+	__restore_sigs(&set);
+	return mem + v[1] + DTP_OFFSET;
+}
+
+static void update_tls_size()
+{
+	libc.tls_cnt = tls_cnt;
+	libc.tls_align = tls_align;
+	libc.tls_size = ALIGN(
+		(1+tls_cnt) * sizeof(void *) +
+		tls_offset +
+		sizeof(struct pthread) +
+		tls_align * 2,
+	tls_align);
+}
+
+/* Stage 1 of the dynamic linker is defined in dlstart.c. It calls the
+ * following stage 2 and stage 3 functions via primitive symbolic lookup
+ * since it does not have access to their addresses to begin with. */
+
+/* Stage 2 of the dynamic linker is called after relative relocations 
+ * have been processed. It can make function calls to static functions
+ * and access string literals and static data, but cannot use extern
+ * symbols. Its job is to perform symbolic relocations on the dynamic
+ * linker itself, but some of the relocations performed may need to be
+ * replaced later due to copy relocations in the main program. */
+
+__attribute__((__visibility__("hidden")))
+void __dls2(unsigned char *base, size_t *sp)
+{
+	if (DL_FDPIC) {
+		void *p1 = (void *)sp[-2];
+		void *p2 = (void *)sp[-1];
+		if (!p1) {
+			size_t *auxv, aux[AUX_CNT];
+			for (auxv=sp+1+*sp+1; *auxv; auxv++); auxv++;
+			decode_vec(auxv, aux, AUX_CNT);
+			if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];
+			else ldso.base = (void *)(aux[AT_PHDR] & -4096);
+		}
+		app_loadmap = p2 ? p1 : 0;
+		ldso.loadmap = p2 ? p2 : p1;
+		ldso.base = laddr(&ldso, 0);
+	} else {
+		ldso.base = base;
+	}
+	Ehdr *ehdr = (void *)ldso.base;
+	ldso.name = ldso.shortname = "libc.so";
+	ldso.phnum = ehdr->e_phnum;
+	ldso.phdr = laddr(&ldso, ehdr->e_phoff);
+	ldso.phentsize = ehdr->e_phentsize;
+	kernel_mapped_dso(&ldso);
+	decode_dyn(&ldso);
+
+	if (DL_FDPIC) makefuncdescs(&ldso);
+
+	/* Prepare storage for to save clobbered REL addends so they
+	 * can be reused in stage 3. There should be very few. If
+	 * something goes wrong and there are a huge number, abort
+	 * instead of risking stack overflow. */
+	size_t dyn[DYN_CNT];
+	decode_vec(ldso.dynv, dyn, DYN_CNT);
+	size_t *rel = laddr(&ldso, dyn[DT_REL]);
+	size_t rel_size = dyn[DT_RELSZ];
+	size_t symbolic_rel_cnt = 0;
+	apply_addends_to = rel;
+	for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))
+		if (!IS_RELATIVE(rel[1], ldso.syms)) symbolic_rel_cnt++;
+	if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash();
+	size_t addends[symbolic_rel_cnt+1];
+	saved_addends = addends;
+
+	head = &ldso;
+	reloc_all(&ldso);
+
+	ldso.relocated = 0;
+
+	/* Call dynamic linker stage-3, __dls3, looking it up
+	 * symbolically as a barrier against moving the address
+	 * load across the above relocation processing. */
+	struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
+	if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp);
+	else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp);
+}
+
+/* Stage 3 of the dynamic linker is called with the dynamic linker/libc
+ * fully functional. Its job is to load (if not already loaded) and
+ * process dependencies and relocations for the main application and
+ * transfer control to its entry point. */
+
+_Noreturn void __dls3(size_t *sp)
+{
+	static struct dso app, vdso;
+	size_t aux[AUX_CNT], *auxv;
+	size_t i;
+	char *env_preload=0;
+	char *replace_argv0=0;
+	size_t vdso_base;
+	int argc = *sp;
+	char **argv = (void *)(sp+1);
+	char **argv_orig = argv;
+	char **envp = argv+argc+1;
+
+	/* Find aux vector just past environ[] and use it to initialize
+	 * global data that may be needed before we can make syscalls. */
+	__environ = envp;
+	for (i=argc+1; argv[i]; i++);
+	libc.auxv = auxv = (void *)(argv+i+1);
+	decode_vec(auxv, aux, AUX_CNT);
+	__hwcap = aux[AT_HWCAP];
+	libc.page_size = aux[AT_PAGESZ];
+	libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
+		|| aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]);
+
+	/* Setup early thread pointer in builtin_tls for ldso/libc itself to
+	 * use during dynamic linking. If possible it will also serve as the
+	 * thread pointer at runtime. */
+	libc.tls_size = sizeof builtin_tls;
+	libc.tls_align = tls_align;
+	if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
+		a_crash();
+	}
+
+	/* Only trust user/env if kernel says we're not suid/sgid */
+	if (!libc.secure) {
+		env_path = getenv("LD_LIBRARY_PATH");
+		env_preload = getenv("LD_PRELOAD");
+	}
+
+	/* If the main program was already loaded by the kernel,
+	 * AT_PHDR will point to some location other than the dynamic
+	 * linker's program headers. */
+	if (aux[AT_PHDR] != (size_t)ldso.phdr) {
+		size_t interp_off = 0;
+		size_t tls_image = 0;
+		/* Find load address of the main program, via AT_PHDR vs PT_PHDR. */
+		Phdr *phdr = app.phdr = (void *)aux[AT_PHDR];
+		app.phnum = aux[AT_PHNUM];
+		app.phentsize = aux[AT_PHENT];
+		for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) {
+			if (phdr->p_type == PT_PHDR)
+				app.base = (void *)(aux[AT_PHDR] - phdr->p_vaddr);
+			else if (phdr->p_type == PT_INTERP)
+				interp_off = (size_t)phdr->p_vaddr;
+			else if (phdr->p_type == PT_TLS) {
+				tls_image = phdr->p_vaddr;
+				app.tls.len = phdr->p_filesz;
+				app.tls.size = phdr->p_memsz;
+				app.tls.align = phdr->p_align;
+			}
+		}
+		if (DL_FDPIC) app.loadmap = app_loadmap;
+		if (app.tls.size) app.tls.image = laddr(&app, tls_image);
+		if (interp_off) ldso.name = laddr(&app, interp_off);
+		if ((aux[0] & (1UL<<AT_EXECFN))
+		    && strncmp((char *)aux[AT_EXECFN], "/proc/", 6))
+			app.name = (char *)aux[AT_EXECFN];
+		else
+			app.name = argv[0];
+		kernel_mapped_dso(&app);
+	} else {
+		int fd;
+		char *ldname = argv[0];
+		size_t l = strlen(ldname);
+		if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1;
+		argv++;
+		while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') {
+			char *opt = argv[0]+2;
+			*argv++ = (void *)-1;
+			if (!*opt) {
+				break;
+			} else if (!memcmp(opt, "list", 5)) {
+				ldd_mode = 1;
+			} else if (!memcmp(opt, "library-path", 12)) {
+				if (opt[12]=='=') env_path = opt+13;
+				else if (opt[12]) *argv = 0;
+				else if (*argv) env_path = *argv++;
+			} else if (!memcmp(opt, "preload", 7)) {
+				if (opt[7]=='=') env_preload = opt+8;
+				else if (opt[7]) *argv = 0;
+				else if (*argv) env_preload = *argv++;
+			} else if (!memcmp(opt, "argv0", 5)) {
+				if (opt[5]=='=') replace_argv0 = opt+6;
+				else if (opt[5]) *argv = 0;
+				else if (*argv) replace_argv0 = *argv++;
+			} else {
+				argv[0] = 0;
+			}
+		}
+		argv[-1] = (void *)(argc - (argv-argv_orig));
+		if (!argv[0]) {
+			dprintf(2, "musl libc (" LDSO_ARCH ")\n"
+				"Version %s\n"
+				"Dynamic Program Loader\n"
+				"Usage: %s [options] [--] pathname%s\n",
+				__libc_get_version(), ldname,
+				ldd_mode ? "" : " [args]");
+			_exit(1);
+		}
+		fd = open(argv[0], O_RDONLY);
+		if (fd < 0) {
+			dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno));
+			_exit(1);
+		}
+		runtime = 1;
+		Ehdr *ehdr = (void *)map_library(fd, &app);
+		if (!ehdr) {
+			dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
+			_exit(1);
+		}
+		runtime = 0;
+		close(fd);
+		ldso.name = ldname;
+		app.name = argv[0];
+		aux[AT_ENTRY] = (size_t)laddr(&app, ehdr->e_entry);
+		/* Find the name that would have been used for the dynamic
+		 * linker had ldd not taken its place. */
+		if (ldd_mode) {
+			for (i=0; i<app.phnum; i++) {
+				if (app.phdr[i].p_type == PT_INTERP)
+					ldso.name = laddr(&app, app.phdr[i].p_vaddr);
+			}
+			dprintf(1, "\t%s (%p)\n", ldso.name, ldso.base);
+		}
+	}
+	if (app.tls.size) {
+		libc.tls_head = tls_tail = &app.tls;
+		app.tls_id = tls_cnt = 1;
+#ifdef TLS_ABOVE_TP
+		app.tls.offset = 0;
+		tls_offset = app.tls.size
+			+ ( -((uintptr_t)app.tls.image + app.tls.size)
+			& (app.tls.align-1) );
+#else
+		tls_offset = app.tls.offset = app.tls.size
+			+ ( -((uintptr_t)app.tls.image + app.tls.size)
+			& (app.tls.align-1) );
+#endif
+		tls_align = MAXP2(tls_align, app.tls.align);
+	}
+	decode_dyn(&app);
+	if (DL_FDPIC) {
+		makefuncdescs(&app);
+		if (!app.loadmap) {
+			app.loadmap = (void *)&app_dummy_loadmap;
+			app.loadmap->nsegs = 1;
+			app.loadmap->segs[0].addr = (size_t)app.map;
+			app.loadmap->segs[0].p_vaddr = (size_t)app.map
+				- (size_t)app.base;
+			app.loadmap->segs[0].p_memsz = app.map_len;
+		}
+		argv[-3] = (void *)app.loadmap;
+	}
+
+	/* Initial dso chain consists only of the app. */
+	head = tail = syms_tail = &app;
+
+	/* Donate unused parts of app and library mapping to malloc */
+	reclaim_gaps(&app);
+	reclaim_gaps(&ldso);
+
+	/* Load preload/needed libraries, add symbols to global namespace. */
+	if (env_preload) load_preload(env_preload);
+ 	load_deps(&app);
+	for (struct dso *p=head; p; p=p->next)
+		add_syms(p);
+
+	/* Attach to vdso, if provided by the kernel, last so that it does
+	 * not become part of the global namespace.  */
+	if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) {
+		Ehdr *ehdr = (void *)vdso_base;
+		Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);
+		vdso.phnum = ehdr->e_phnum;
+		vdso.phentsize = ehdr->e_phentsize;
+		for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
+			if (phdr->p_type == PT_DYNAMIC)
+				vdso.dynv = (void *)(vdso_base + phdr->p_offset);
+			if (phdr->p_type == PT_LOAD)
+				vdso.base = (void *)(vdso_base - phdr->p_vaddr + phdr->p_offset);
+		}
+		vdso.name = "";
+		vdso.shortname = "linux-gate.so.1";
+		vdso.relocated = 1;
+		decode_dyn(&vdso);
+		vdso.prev = tail;
+		tail->next = &vdso;
+		tail = &vdso;
+	}
+
+	for (i=0; app.dynv[i]; i+=2) {
+		if (!DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG)
+			app.dynv[i+1] = (size_t)&debug;
+		if (DT_DEBUG_INDIRECT && app.dynv[i]==DT_DEBUG_INDIRECT) {
+			size_t *ptr = (size_t *) app.dynv[i+1];
+			*ptr = (size_t)&debug;
+		}
+	}
+
+	/* The main program must be relocated LAST since it may contin
+	 * copy relocations which depend on libraries' relocations. */
+	reloc_all(app.next);
+	reloc_all(&app);
+
+	update_tls_size();
+	if (libc.tls_size > sizeof builtin_tls || tls_align > MIN_TLS_ALIGN) {
+		void *initial_tls = calloc(libc.tls_size, 1);
+		if (!initial_tls) {
+			dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n",
+				argv[0], libc.tls_size);
+			_exit(127);
+		}
+		if (__init_tp(__copy_tls(initial_tls)) < 0) {
+			a_crash();
+		}
+	} else {
+		size_t tmp_tls_size = libc.tls_size;
+		pthread_t self = __pthread_self();
+		/* Temporarily set the tls size to the full size of
+		 * builtin_tls so that __copy_tls will use the same layout
+		 * as it did for before. Then check, just to be safe. */
+		libc.tls_size = sizeof builtin_tls;
+		if (__copy_tls((void*)builtin_tls) != self) a_crash();
+		libc.tls_size = tmp_tls_size;
+	}
+	static_tls_cnt = tls_cnt;
+
+	if (ldso_fail) _exit(127);
+	if (ldd_mode) _exit(0);
+
+	/* Switch to runtime mode: any further failures in the dynamic
+	 * linker are a reportable failure rather than a fatal startup
+	 * error. */
+	runtime = 1;
+
+	debug.ver = 1;
+	debug.bp = dl_debug_state;
+	debug.head = head;
+	debug.base = ldso.base;
+	debug.state = 0;
+	_dl_debug_state();
+
+	if (replace_argv0) argv[0] = replace_argv0;
+
+	errno = 0;
+
+	CRTJMP((void *)aux[AT_ENTRY], argv-1);
+	for(;;);
+}
+
+static void prepare_lazy(struct dso *p)
+{
+	size_t dyn[DYN_CNT], n, flags1=0;
+	decode_vec(p->dynv, dyn, DYN_CNT);
+	search_vec(p->dynv, &flags1, DT_FLAGS_1);
+	if (dyn[DT_BIND_NOW] || (dyn[DT_FLAGS] & DF_BIND_NOW) || (flags1 & DF_1_NOW))
+		return;
+	n = dyn[DT_RELSZ]/2 + dyn[DT_RELASZ]/3 + dyn[DT_PLTRELSZ]/2 + 1;
+	if (NEED_MIPS_GOT_RELOCS) {
+		size_t j=0; search_vec(p->dynv, &j, DT_MIPS_GOTSYM);
+		size_t i=0; search_vec(p->dynv, &i, DT_MIPS_SYMTABNO);
+		n += i-j;
+	}
+	p->lazy = calloc(n, 3*sizeof(size_t));
+	if (!p->lazy) {
+		error("Error preparing lazy relocation for %s: %m", p->name);
+		longjmp(*rtld_fail, 1);
+	}
+	p->lazy_next = lazy_head;
+	lazy_head = p;
+}
+
+void *dlopen(const char *file, int mode)
+{
+	struct dso *volatile p, *orig_tail, *orig_syms_tail, *orig_lazy_head, *next;
+	struct tls_module *orig_tls_tail;
+	size_t orig_tls_cnt, orig_tls_offset, orig_tls_align;
+	size_t i;
+	int cs;
+	jmp_buf jb;
+
+	if (!file) return head;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	pthread_rwlock_wrlock(&lock);
+	__inhibit_ptc();
+
+	p = 0;
+	orig_tls_tail = tls_tail;
+	orig_tls_cnt = tls_cnt;
+	orig_tls_offset = tls_offset;
+	orig_tls_align = tls_align;
+	orig_lazy_head = lazy_head;
+	orig_syms_tail = syms_tail;
+	orig_tail = tail;
+	noload = mode & RTLD_NOLOAD;
+
+	rtld_fail = &jb;
+	if (setjmp(*rtld_fail)) {
+		/* Clean up anything new that was (partially) loaded */
+		revert_syms(orig_syms_tail);
+		for (p=orig_tail->next; p; p=next) {
+			next = p->next;
+			while (p->td_index) {
+				void *tmp = p->td_index->next;
+				free(p->td_index);
+				p->td_index = tmp;
+			}
+			free(p->funcdescs);
+			if (p->rpath != p->rpath_orig)
+				free(p->rpath);
+			if (p->deps != &nodeps_dummy)
+				free(p->deps);
+			unmap_library(p);
+			free(p);
+		}
+		if (!orig_tls_tail) libc.tls_head = 0;
+		tls_tail = orig_tls_tail;
+		if (tls_tail) tls_tail->next = 0;
+		tls_cnt = orig_tls_cnt;
+		tls_offset = orig_tls_offset;
+		tls_align = orig_tls_align;
+		lazy_head = orig_lazy_head;
+		tail = orig_tail;
+		tail->next = 0;
+		p = 0;
+		goto end;
+	} else p = load_library(file, head);
+
+	if (!p) {
+		error(noload ?
+			"Library %s is not already loaded" :
+			"Error loading shared library %s: %m",
+			file);
+		goto end;
+	}
+
+	/* First load handling */
+	int first_load = !p->deps;
+	if (first_load) {
+		load_deps(p);
+		if (!p->relocated && (mode & RTLD_LAZY)) {
+			prepare_lazy(p);
+			for (i=0; p->deps[i]; i++)
+				if (!p->deps[i]->relocated)
+					prepare_lazy(p->deps[i]);
+		}
+	}
+	if (first_load || (mode & RTLD_GLOBAL)) {
+		/* Make new symbols global, at least temporarily, so we can do
+		 * relocations. If not RTLD_GLOBAL, this is reverted below. */
+		add_syms(p);
+		for (i=0; p->deps[i]; i++)
+			add_syms(p->deps[i]);
+	}
+	if (first_load) {
+		reloc_all(p);
+	}
+
+	/* If RTLD_GLOBAL was not specified, undo any new additions
+	 * to the global symbol table. This is a nop if the library was
+	 * previously loaded and already global. */
+	if (!(mode & RTLD_GLOBAL))
+		revert_syms(orig_syms_tail);
+
+	/* Processing of deferred lazy relocations must not happen until
+	 * the new libraries are committed; otherwise we could end up with
+	 * relocations resolved to symbol definitions that get removed. */
+	redo_lazy_relocs();
+
+	update_tls_size();
+	_dl_debug_state();
+	orig_tail = tail;
+end:
+	__release_ptc();
+	if (p) gencnt++;
+	pthread_rwlock_unlock(&lock);
+	if (p) do_init_fini(orig_tail);
+	pthread_setcancelstate(cs, 0);
+	return p;
+}
+
+__attribute__((__visibility__("hidden")))
+int __dl_invalid_handle(void *h)
+{
+	struct dso *p;
+	for (p=head; p; p=p->next) if (h==p) return 0;
+	error("Invalid library handle %p", (void *)h);
+	return 1;
+}
+
+static void *addr2dso(size_t a)
+{
+	struct dso *p;
+	size_t i;
+	if (DL_FDPIC) for (p=head; p; p=p->next) {
+		i = count_syms(p);
+		if (a-(size_t)p->funcdescs < i*sizeof(*p->funcdescs))
+			return p;
+	}
+	for (p=head; p; p=p->next) {
+		if (DL_FDPIC && p->loadmap) {
+			for (i=0; i<p->loadmap->nsegs; i++) {
+				if (a-p->loadmap->segs[i].p_vaddr
+				    < p->loadmap->segs[i].p_memsz)
+					return p;
+			}
+		} else {
+			if (a-(size_t)p->map < p->map_len)
+				return p;
+		}
+	}
+	return 0;
+}
+
+void *__tls_get_addr(tls_mod_off_t *);
+
+static void *do_dlsym(struct dso *p, const char *s, void *ra)
+{
+	size_t i;
+	uint32_t h = 0, gh = 0, *ght;
+	Sym *sym;
+	if (p == head || p == RTLD_DEFAULT || p == RTLD_NEXT) {
+		if (p == RTLD_DEFAULT) {
+			p = head;
+		} else if (p == RTLD_NEXT) {
+			p = addr2dso((size_t)ra);
+			if (!p) p=head;
+			p = p->next;
+		}
+		struct symdef def = find_sym(p, s, 0);
+		if (!def.sym) goto failed;
+		if ((def.sym->st_info&0xf) == STT_TLS)
+			return __tls_get_addr((tls_mod_off_t []){def.dso->tls_id, def.sym->st_value});
+		if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC)
+			return def.dso->funcdescs + (def.sym - def.dso->syms);
+		return laddr(def.dso, def.sym->st_value);
+	}
+	if (__dl_invalid_handle(p))
+		return 0;
+	if ((ght = p->ghashtab)) {
+		gh = gnu_hash(s);
+		sym = gnu_lookup(gh, ght, p, s);
+	} else {
+		h = sysv_hash(s);
+		sym = sysv_lookup(s, h, p);
+	}
+	if (sym && (sym->st_info&0xf) == STT_TLS)
+		return __tls_get_addr((tls_mod_off_t []){p->tls_id, sym->st_value});
+	if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC)
+		return p->funcdescs + (sym - p->syms);
+	if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
+		return laddr(p, sym->st_value);
+	for (i=0; p->deps[i]; i++) {
+		if ((ght = p->deps[i]->ghashtab)) {
+			if (!gh) gh = gnu_hash(s);
+			sym = gnu_lookup(gh, ght, p->deps[i], s);
+		} else {
+			if (!h) h = sysv_hash(s);
+			sym = sysv_lookup(s, h, p->deps[i]);
+		}
+		if (sym && (sym->st_info&0xf) == STT_TLS)
+			return __tls_get_addr((tls_mod_off_t []){p->deps[i]->tls_id, sym->st_value});
+		if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC)
+			return p->deps[i]->funcdescs + (sym - p->deps[i]->syms);
+		if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
+			return laddr(p->deps[i], sym->st_value);
+	}
+failed:
+	error("Symbol not found: %s", s);
+	return 0;
+}
+
+int dladdr(const void *addr, Dl_info *info)
+{
+	struct dso *p;
+	Sym *sym, *bestsym;
+	uint32_t nsym;
+	char *strings;
+	void *best = 0;
+
+	pthread_rwlock_rdlock(&lock);
+	p = addr2dso((size_t)addr);
+	pthread_rwlock_unlock(&lock);
+
+	if (!p) return 0;
+
+	sym = p->syms;
+	strings = p->strings;
+	nsym = count_syms(p);
+
+	if (DL_FDPIC) {
+		size_t idx = ((size_t)addr-(size_t)p->funcdescs)
+			/ sizeof(*p->funcdescs);
+		if (idx < nsym && (sym[idx].st_info&0xf) == STT_FUNC) {
+			best = p->funcdescs + idx;
+			bestsym = sym + idx;
+		}
+	}
+
+	if (!best) for (; nsym; nsym--, sym++) {
+		if (sym->st_value
+		 && (1<<(sym->st_info&0xf) & OK_TYPES)
+		 && (1<<(sym->st_info>>4) & OK_BINDS)) {
+			void *symaddr = laddr(p, sym->st_value);
+			if (symaddr > addr || symaddr < best)
+				continue;
+			best = symaddr;
+			bestsym = sym;
+			if (addr == symaddr)
+				break;
+		}
+	}
+
+	if (!best) return 0;
+
+	if (DL_FDPIC && (bestsym->st_info&0xf) == STT_FUNC)
+		best = p->funcdescs + (bestsym - p->syms);
+
+	info->dli_fname = p->name;
+	info->dli_fbase = p->base;
+	info->dli_sname = strings + bestsym->st_name;
+	info->dli_saddr = best;
+
+	return 1;
+}
+
+__attribute__((__visibility__("hidden")))
+void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
+{
+	void *res;
+	pthread_rwlock_rdlock(&lock);
+	res = do_dlsym(p, s, ra);
+	pthread_rwlock_unlock(&lock);
+	return res;
+}
+
+int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
+{
+	struct dso *current;
+	struct dl_phdr_info info;
+	int ret = 0;
+	for(current = head; current;) {
+		info.dlpi_addr      = (uintptr_t)current->base;
+		info.dlpi_name      = current->name;
+		info.dlpi_phdr      = current->phdr;
+		info.dlpi_phnum     = current->phnum;
+		info.dlpi_adds      = gencnt;
+		info.dlpi_subs      = 0;
+		info.dlpi_tls_modid = current->tls_id;
+		info.dlpi_tls_data  = current->tls.image;
+
+		ret = (callback)(&info, sizeof (info), data);
+
+		if (ret != 0) break;
+
+		pthread_rwlock_rdlock(&lock);
+		current = current->next;
+		pthread_rwlock_unlock(&lock);
+	}
+	return ret;
+}
+
+__attribute__((__visibility__("hidden")))
+void __dl_vseterr(const char *, va_list);
+
+static void error(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	if (!runtime) {
+		vdprintf(2, fmt, ap);
+		dprintf(2, "\n");
+		ldso_fail = 1;
+		va_end(ap);
+		return;
+	}
+	__dl_vseterr(fmt, ap);
+	va_end(ap);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/aio/aio.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/aio/aio.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/aio/aio.c	(revision 398)
@@ -0,0 +1,379 @@
+#include <aio.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "syscall.h"
+#include "atomic.h"
+#include "libc.h"
+#include "pthread_impl.h"
+
+/* The following is a threads-based implementation of AIO with minimal
+ * dependence on implementation details. Most synchronization is
+ * performed with pthread primitives, but atomics and futex operations
+ * are used for notification in a couple places where the pthread
+ * primitives would be inefficient or impractical.
+ *
+ * For each fd with outstanding aio operations, an aio_queue structure
+ * is maintained. These are reference-counted and destroyed by the last
+ * aio worker thread to exit. Accessing any member of the aio_queue
+ * structure requires a lock on the aio_queue. Adding and removing aio
+ * queues themselves requires a write lock on the global map object,
+ * a 4-level table mapping file descriptor numbers to aio queues. A
+ * read lock on the map is used to obtain locks on existing queues by
+ * excluding destruction of the queue by a different thread while it is
+ * being locked.
+ *
+ * Each aio queue has a list of active threads/operations. Presently there
+ * is a one to one relationship between threads and operations. The only
+ * members of the aio_thread structure which are accessed by other threads
+ * are the linked list pointers, op (which is immutable), running (which
+ * is updated atomically), and err (which is synchronized via running),
+ * so no locking is necessary. Most of the other other members are used
+ * for sharing data between the main flow of execution and cancellation
+ * cleanup handler.
+ *
+ * Taking any aio locks requires having all signals blocked. This is
+ * necessary because aio_cancel is needed by close, and close is required
+ * to be async-signal safe. All aio worker threads run with all signals
+ * blocked permanently.
+ */
+
+struct aio_args {
+	struct aiocb *cb;
+	int op;
+	int err;
+	sem_t sem;
+};
+
+struct aio_thread {
+	pthread_t td;
+	struct aiocb *cb;
+	struct aio_thread *next, *prev;
+	struct aio_queue *q;
+	volatile int running;
+	int err, op;
+	ssize_t ret;
+};
+
+struct aio_queue {
+	int fd, seekable, append, ref, init;
+	pthread_mutex_t lock;
+	pthread_cond_t cond;
+	struct aio_thread *head;
+};
+
+static pthread_rwlock_t maplock = PTHREAD_RWLOCK_INITIALIZER;
+static struct aio_queue *****map;
+static volatile int aio_fd_cnt;
+volatile int __aio_fut;
+
+static struct aio_queue *__aio_get_queue(int fd, int need)
+{
+	if (fd < 0) return 0;
+	int a=fd>>24;
+	unsigned char b=fd>>16, c=fd>>8, d=fd;
+	struct aio_queue *q = 0;
+	pthread_rwlock_rdlock(&maplock);
+	if ((!map || !map[a] || !map[a][b] || !map[a][b][c] || !(q=map[a][b][c][d])) && need) {
+		pthread_rwlock_unlock(&maplock);
+		pthread_rwlock_wrlock(&maplock);
+		if (!map) map = calloc(sizeof *map, (-1U/2+1)>>24);
+		if (!map) goto out;
+		if (!map[a]) map[a] = calloc(sizeof **map, 256);
+		if (!map[a]) goto out;
+		if (!map[a][b]) map[a][b] = calloc(sizeof ***map, 256);
+		if (!map[a][b]) goto out;
+		if (!map[a][b][c]) map[a][b][c] = calloc(sizeof ****map, 256);
+		if (!map[a][b][c]) goto out;
+		if (!(q = map[a][b][c][d])) {
+			map[a][b][c][d] = q = calloc(sizeof *****map, 1);
+			if (q) {
+				q->fd = fd;
+				pthread_mutex_init(&q->lock, 0);
+				pthread_cond_init(&q->cond, 0);
+				a_inc(&aio_fd_cnt);
+			}
+		}
+	}
+	if (q) pthread_mutex_lock(&q->lock);
+out:
+	pthread_rwlock_unlock(&maplock);
+	return q;
+}
+
+static void __aio_unref_queue(struct aio_queue *q)
+{
+	if (q->ref > 1) {
+		q->ref--;
+		pthread_mutex_unlock(&q->lock);
+		return;
+	}
+
+	/* This is potentially the last reference, but a new reference
+	 * may arrive since we cannot free the queue object without first
+	 * taking the maplock, which requires releasing the queue lock. */
+	pthread_mutex_unlock(&q->lock);
+	pthread_rwlock_wrlock(&maplock);
+	pthread_mutex_lock(&q->lock);
+	if (q->ref == 1) {
+		int fd=q->fd;
+		int a=fd>>24;
+		unsigned char b=fd>>16, c=fd>>8, d=fd;
+		map[a][b][c][d] = 0;
+		a_dec(&aio_fd_cnt);
+		pthread_rwlock_unlock(&maplock);
+		pthread_mutex_unlock(&q->lock);
+		free(q);
+	} else {
+		q->ref--;
+		pthread_rwlock_unlock(&maplock);
+		pthread_mutex_unlock(&q->lock);
+	}
+}
+
+static void cleanup(void *ctx)
+{
+	struct aio_thread *at = ctx;
+	struct aio_queue *q = at->q;
+	struct aiocb *cb = at->cb;
+	struct sigevent sev = cb->aio_sigevent;
+
+	/* There are four potential types of waiters we could need to wake:
+	 *   1. Callers of aio_cancel/close.
+	 *   2. Callers of aio_suspend with a single aiocb.
+	 *   3. Callers of aio_suspend with a list.
+	 *   4. AIO worker threads waiting for sequenced operations.
+	 * Types 1-3 are notified via atomics/futexes, mainly for AS-safety
+	 * considerations. Type 4 is notified later via a cond var. */
+
+	cb->__ret = at->ret;
+	if (a_swap(&at->running, 0) < 0)
+		__wake(&at->running, -1, 1);
+	if (a_swap(&cb->__err, at->err) != EINPROGRESS)
+		__wake(&cb->__err, -1, 1);
+	if (a_swap(&__aio_fut, 0))
+		__wake(&__aio_fut, -1, 1);
+
+	pthread_mutex_lock(&q->lock);
+
+	if (at->next) at->next->prev = at->prev;
+	if (at->prev) at->prev->next = at->next;
+	else q->head = at->next;
+
+	/* Signal aio worker threads waiting for sequenced operations. */
+	pthread_cond_broadcast(&q->cond);
+
+	__aio_unref_queue(q);
+
+	if (sev.sigev_notify == SIGEV_SIGNAL) {
+		siginfo_t si = {
+			.si_signo = sev.sigev_signo,
+			.si_value = sev.sigev_value,
+			.si_code = SI_ASYNCIO,
+			.si_pid = getpid(),
+			.si_uid = getuid()
+		};
+		__syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si);
+	}
+	if (sev.sigev_notify == SIGEV_THREAD) {
+		a_store(&__pthread_self()->cancel, 0);
+		sev.sigev_notify_function(sev.sigev_value);
+	}
+}
+
+static void *io_thread_func(void *ctx)
+{
+	struct aio_thread at, *p;
+
+	struct aio_args *args = ctx;
+	struct aiocb *cb = args->cb;
+	int fd = cb->aio_fildes;
+	int op = args->op;
+	void *buf = (void *)cb->aio_buf;
+	size_t len = cb->aio_nbytes;
+	off_t off = cb->aio_offset;
+
+	struct aio_queue *q = __aio_get_queue(fd, 1);
+	ssize_t ret;
+
+	args->err = q ? 0 : EAGAIN;
+	sem_post(&args->sem);
+	if (!q) return 0;
+
+	at.op = op;
+	at.running = 1;
+	at.ret = -1;
+	at.err = ECANCELED;
+	at.q = q;
+	at.td = __pthread_self();
+	at.cb = cb;
+	at.prev = 0;
+	if ((at.next = q->head)) at.next->prev = &at;
+	q->head = &at;
+	q->ref++;
+
+	if (!q->init) {
+		int seekable = lseek(fd, 0, SEEK_CUR) >= 0;
+		q->seekable = seekable;
+		q->append = !seekable || (fcntl(fd, F_GETFL) & O_APPEND);
+		q->init = 1;
+	}
+
+	pthread_cleanup_push(cleanup, &at);
+
+	/* Wait for sequenced operations. */
+	if (op!=LIO_READ && (op!=LIO_WRITE || q->append)) {
+		for (;;) {
+			for (p=at.next; p && p->op!=LIO_WRITE; p=p->next);
+			if (!p) break;
+			pthread_cond_wait(&q->cond, &q->lock);
+		}
+	}
+
+	pthread_mutex_unlock(&q->lock);
+
+	switch (op) {
+	case LIO_WRITE:
+		ret = q->append ? write(fd, buf, len) : pwrite(fd, buf, len, off);
+		break;
+	case LIO_READ:
+		ret = !q->seekable ? read(fd, buf, len) : pread(fd, buf, len, off);
+		break;
+	case O_SYNC:
+		ret = fsync(fd);
+		break;
+	case O_DSYNC:
+		ret = fdatasync(fd);
+		break;
+	}
+	at.ret = ret;
+	at.err = ret<0 ? errno : 0;
+	
+	pthread_cleanup_pop(1);
+
+	return 0;
+}
+
+static int submit(struct aiocb *cb, int op)
+{
+	int ret = 0;
+	pthread_attr_t a;
+	sigset_t allmask, origmask;
+	pthread_t td;
+	struct aio_args args = { .cb = cb, .op = op };
+	sem_init(&args.sem, 0, 0);
+
+	if (cb->aio_sigevent.sigev_notify == SIGEV_THREAD) {
+		if (cb->aio_sigevent.sigev_notify_attributes)
+			a = *cb->aio_sigevent.sigev_notify_attributes;
+		else
+			pthread_attr_init(&a);
+	} else {
+		pthread_attr_init(&a);
+		pthread_attr_setstacksize(&a, PTHREAD_STACK_MIN);
+		pthread_attr_setguardsize(&a, 0);
+	}
+	pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
+	sigfillset(&allmask);
+	pthread_sigmask(SIG_BLOCK, &allmask, &origmask);
+	cb->__err = EINPROGRESS;
+	if (pthread_create(&td, &a, io_thread_func, &args)) {
+		errno = EAGAIN;
+		ret = -1;
+	}
+	pthread_sigmask(SIG_SETMASK, &origmask, 0);
+
+	if (!ret) {
+		while (sem_wait(&args.sem));
+		if (args.err) {
+			errno = args.err;
+			ret = -1;
+		}
+	}
+
+	return ret;
+}
+
+int aio_read(struct aiocb *cb)
+{
+	return submit(cb, LIO_READ);
+}
+
+int aio_write(struct aiocb *cb)
+{
+	return submit(cb, LIO_WRITE);
+}
+
+int aio_fsync(int op, struct aiocb *cb)
+{
+	if (op != O_SYNC && op != O_DSYNC) {
+		errno = EINVAL;
+		return -1;
+	}
+	return submit(cb, op);
+}
+
+ssize_t aio_return(struct aiocb *cb)
+{
+	return cb->__ret;
+}
+
+int aio_error(const struct aiocb *cb)
+{
+	a_barrier();
+	return cb->__err & 0x7fffffff;
+}
+
+int aio_cancel(int fd, struct aiocb *cb)
+{
+	sigset_t allmask, origmask;
+	int ret = AIO_ALLDONE;
+	struct aio_thread *p;
+	struct aio_queue *q;
+
+	/* Unspecified behavior case. Report an error. */
+	if (cb && fd != cb->aio_fildes) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	sigfillset(&allmask);
+	pthread_sigmask(SIG_BLOCK, &allmask, &origmask);
+
+	if (!(q = __aio_get_queue(fd, 0))) {
+		if (fcntl(fd, F_GETFD) < 0) ret = -1;
+		goto done;
+	}
+
+	for (p = q->head; p; p = p->next) {
+		if (cb && cb != p->cb) continue;
+		/* Transition target from running to running-with-waiters */
+		if (a_cas(&p->running, 1, -1)) {
+			pthread_cancel(p->td);
+			__wait(&p->running, 0, -1, 1);
+			if (p->err == ECANCELED) ret = AIO_CANCELED;
+		}
+	}
+
+	pthread_mutex_unlock(&q->lock);
+done:
+	pthread_sigmask(SIG_SETMASK, &origmask, 0);
+	return ret;
+}
+
+int __aio_close(int fd)
+{
+	a_barrier();
+	if (aio_fd_cnt) aio_cancel(fd, 0);
+	return fd;
+}
+
+LFS64(aio_cancel);
+LFS64(aio_error);
+LFS64(aio_fsync);
+LFS64(aio_read);
+LFS64(aio_write);
+LFS64(aio_return);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/aio/aio_suspend.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/aio/aio_suspend.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/aio/aio_suspend.c	(revision 398)
@@ -0,0 +1,79 @@
+#include <aio.h>
+#include <errno.h>
+#include <time.h>
+#include "atomic.h"
+#include "libc.h"
+#include "pthread_impl.h"
+
+extern volatile int __aio_fut;
+
+int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec *ts)
+{
+	int i, tid = 0, ret, expect = 0;
+	struct timespec at;
+	volatile int dummy_fut, *pfut;
+	int nzcnt = 0;
+	const struct aiocb *cb = 0;
+
+	pthread_testcancel();
+
+	if (cnt<0) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	for (i=0; i<cnt; i++) if (cbs[i]) {
+		if (aio_error(cbs[i]) != EINPROGRESS) return 0;
+		nzcnt++;
+		cb = cbs[i];
+	}
+
+	if (ts) {
+		clock_gettime(CLOCK_MONOTONIC, &at);
+		at.tv_sec += ts->tv_sec;
+		if ((at.tv_nsec += ts->tv_nsec) >= 1000000000) {
+			at.tv_nsec -= 1000000000;
+			at.tv_sec++;
+		}
+	}
+
+	for (;;) {
+		for (i=0; i<cnt; i++)
+			if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS)
+				return 0;
+
+		switch (nzcnt) {
+		case 0:
+			pfut = &dummy_fut;
+			break;
+		case 1:
+			pfut = (void *)&cb->__err;
+			expect = EINPROGRESS | 0x80000000;
+			a_cas(pfut, EINPROGRESS, expect);
+			break;
+		default:
+			pfut = &__aio_fut;
+			if (!tid) tid = __pthread_self()->tid;
+			expect = a_cas(pfut, 0, tid);
+			if (!expect) expect = tid;
+			/* Need to recheck the predicate before waiting. */
+			for (i=0; i<cnt; i++)
+				if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS)
+					return 0;
+			break;
+		}
+
+		ret = __timedwait_cp(pfut, expect, CLOCK_MONOTONIC, ts?&at:0, 1);
+
+		switch (ret) {
+		case ETIMEDOUT:
+			ret = EAGAIN;
+		case ECANCELED:
+		case EINTR:
+			errno = ret;
+			return -1;
+		}
+	}
+}
+
+LFS64(aio_suspend);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/aio/lio_listio.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/aio/lio_listio.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/aio/lio_listio.c	(revision 398)
@@ -0,0 +1,144 @@
+#include <aio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+struct lio_state {
+	struct sigevent *sev;
+	int cnt;
+	struct aiocb *cbs[];
+};
+
+static int lio_wait(struct lio_state *st)
+{
+	int i, err, got_err = 0;
+	int cnt = st->cnt;
+	struct aiocb **cbs = st->cbs;
+
+	for (;;) {
+		for (i=0; i<cnt; i++) {
+			if (!cbs[i]) continue;
+			err = aio_error(cbs[i]);
+			if (err==EINPROGRESS)
+				break;
+			if (err) got_err=1;
+			cbs[i] = 0;
+		}
+		if (i==cnt) {
+			if (got_err) {
+				errno = EIO;
+				return -1;
+			}
+			return 0;
+		}
+		if (aio_suspend((void *)cbs, cnt, 0))
+			return -1;
+	}
+}
+
+static void notify_signal(struct sigevent *sev)
+{
+	siginfo_t si = {
+		.si_signo = sev->sigev_signo,
+		.si_value = sev->sigev_value,
+		.si_code = SI_ASYNCIO,
+		.si_pid = getpid(),
+		.si_uid = getuid()
+	};
+	__syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si);
+}
+
+static void *wait_thread(void *p)
+{
+	struct lio_state *st = p;
+	struct sigevent *sev = st->sev;
+	lio_wait(st);
+	free(st);
+	switch (sev->sigev_notify) {
+	case SIGEV_SIGNAL:
+		notify_signal(sev);
+		break;
+	case SIGEV_THREAD:
+		sev->sigev_notify_function(sev->sigev_value);
+		break;
+	}
+	return 0;
+}
+
+int lio_listio(int mode, struct aiocb *restrict const *restrict cbs, int cnt, struct sigevent *restrict sev)
+{
+	int i, ret;
+	struct lio_state *st=0;
+
+	if (cnt < 0) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (mode == LIO_WAIT || (sev && sev->sigev_notify != SIGEV_NONE)) {
+		if (!(st = malloc(sizeof *st + cnt*sizeof *cbs))) {
+			errno = EAGAIN;
+			return -1;
+		}
+		st->cnt = cnt;
+		st->sev = sev;
+		memcpy(st->cbs, (void*) cbs, cnt*sizeof *cbs);
+	}
+
+	for (i=0; i<cnt; i++) {
+		if (!cbs[i]) continue;
+		switch (cbs[i]->aio_lio_opcode) {
+		case LIO_READ:
+			ret = aio_read(cbs[i]);
+			break;
+		case LIO_WRITE:
+			ret = aio_write(cbs[i]);
+			break;
+		default:
+			continue;
+		}
+		if (ret) {
+			free(st);
+			errno = EAGAIN;
+			return -1;
+		}
+	}
+
+	if (mode == LIO_WAIT) {
+		ret = lio_wait(st);
+		free(st);
+		return ret;
+	}
+
+	if (st) {
+		pthread_attr_t a;
+		sigset_t set;
+		pthread_t td;
+
+		if (sev->sigev_notify == SIGEV_THREAD) {
+			if (sev->sigev_notify_attributes)
+				a = *sev->sigev_notify_attributes;
+			else
+				pthread_attr_init(&a);
+		} else {
+			pthread_attr_init(&a);
+			pthread_attr_setstacksize(&a, PAGE_SIZE);
+			pthread_attr_setguardsize(&a, 0);
+		}
+		pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
+		sigfillset(&set);
+		pthread_sigmask(SIG_BLOCK, &set, &set);
+		if (pthread_create(&td, &a, wait_thread, st)) {
+			free(st);
+			errno = EAGAIN;
+			return -1;
+		}
+		pthread_sigmask(SIG_SETMASK, &set, 0);
+	}
+
+	return 0;
+}
+
+LFS64(lio_listio);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/__cexp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/__cexp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/__cexp.c	(revision 398)
@@ -0,0 +1,87 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_exp.c */
+/*-
+ * Copyright (c) 2011 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 "libm.h"
+
+static const uint32_t k = 1799; /* constant for reduction */
+static const double kln2 = 1246.97177782734161156; /* k * ln2 */
+
+/*
+ * Compute exp(x), scaled to avoid spurious overflow.  An exponent is
+ * returned separately in 'expt'.
+ *
+ * Input:  ln(DBL_MAX) <= x < ln(2 * DBL_MAX / DBL_MIN_DENORM) ~= 1454.91
+ * Output: 2**1023 <= y < 2**1024
+ */
+static double __frexp_exp(double x, int *expt)
+{
+	double exp_x;
+	uint32_t hx;
+
+	/*
+	 * We use exp(x) = exp(x - kln2) * 2**k, carefully chosen to
+	 * minimize |exp(kln2) - 2**k|.  We also scale the exponent of
+	 * exp_x to MAX_EXP so that the result can be multiplied by
+	 * a tiny number without losing accuracy due to denormalization.
+	 */
+	exp_x = exp(x - kln2);
+	GET_HIGH_WORD(hx, exp_x);
+	*expt = (hx >> 20) - (0x3ff + 1023) + k;
+	SET_HIGH_WORD(exp_x, (hx & 0xfffff) | ((0x3ff + 1023) << 20));
+	return exp_x;
+}
+
+/*
+ * __ldexp_cexp(x, expt) compute exp(x) * 2**expt.
+ * It is intended for large arguments (real part >= ln(DBL_MAX))
+ * where care is needed to avoid overflow.
+ *
+ * The present implementation is narrowly tailored for our hyperbolic and
+ * exponential functions.  We assume expt is small (0 or -1), and the caller
+ * has filtered out very large x, for which overflow would be inevitable.
+ */
+double complex __ldexp_cexp(double complex z, int expt)
+{
+	double x, y, exp_x, scale1, scale2;
+	int ex_expt, half_expt;
+
+	x = creal(z);
+	y = cimag(z);
+	exp_x = __frexp_exp(x, &ex_expt);
+	expt += ex_expt;
+
+	/*
+	 * Arrange so that scale1 * scale2 == 2**expt.  We use this to
+	 * compensate for scalbn being horrendously slow.
+	 */
+	half_expt = expt / 2;
+	INSERT_WORDS(scale1, (0x3ff + half_expt) << 20, 0);
+	half_expt = expt - half_expt;
+	INSERT_WORDS(scale2, (0x3ff + half_expt) << 20, 0);
+
+	return CMPLX(cos(y) * exp_x * scale1 * scale2, sin(y) * exp_x * scale1 * scale2);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/__cexpf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/__cexpf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/__cexpf.c	(revision 398)
@@ -0,0 +1,68 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_expf.c */
+/*-
+ * Copyright (c) 2011 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 "libm.h"
+
+static const uint32_t k = 235; /* constant for reduction */
+static const float kln2 = 162.88958740F; /* k * ln2 */
+
+/*
+ * See __cexp.c for details.
+ *
+ * Input:  ln(FLT_MAX) <= x < ln(2 * FLT_MAX / FLT_MIN_DENORM) ~= 192.7
+ * Output: 2**127 <= y < 2**128
+ */
+static float __frexp_expf(float x, int *expt)
+{
+	float exp_x;
+	uint32_t hx;
+
+	exp_x = expf(x - kln2);
+	GET_FLOAT_WORD(hx, exp_x);
+	*expt = (hx >> 23) - (0x7f + 127) + k;
+	SET_FLOAT_WORD(exp_x, (hx & 0x7fffff) | ((0x7f + 127) << 23));
+	return exp_x;
+}
+
+float complex __ldexp_cexpf(float complex z, int expt)
+{
+	float x, y, exp_x, scale1, scale2;
+	int ex_expt, half_expt;
+
+	x = crealf(z);
+	y = cimagf(z);
+	exp_x = __frexp_expf(x, &ex_expt);
+	expt += ex_expt;
+
+	half_expt = expt / 2;
+	SET_FLOAT_WORD(scale1, (0x7f + half_expt) << 23);
+	half_expt = expt - half_expt;
+	SET_FLOAT_WORD(scale2, (0x7f + half_expt) << 23);
+
+	return CMPLXF(cosf(y) * exp_x * scale1 * scale2,
+	  sinf(y) * exp_x * scale1 * scale2);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cabs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cabs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cabs.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+double cabs(double complex z)
+{
+	return hypot(creal(z), cimag(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cabsf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cabsf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cabsf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float cabsf(float complex z)
+{
+	return hypotf(crealf(z), cimagf(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cabsl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cabsl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cabsl.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double cabsl(long double complex z)
+{
+	return cabs(z);
+}
+#else
+long double cabsl(long double complex z)
+{
+	return hypotl(creall(z), cimagl(z));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacos.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacos.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacos.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "libm.h"
+
+// FIXME: Hull et al. "Implementing the complex arcsine and arccosine functions using exception handling" 1997
+
+/* acos(z) = pi/2 - asin(z) */
+
+double complex cacos(double complex z)
+{
+	z = casin(z);
+	return CMPLX(M_PI_2 - creal(z), -cimag(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacosf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacosf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacosf.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+// FIXME
+
+float complex cacosf(float complex z)
+{
+	z = casinf(z);
+	return CMPLXF((float)M_PI_2 - crealf(z), -cimagf(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacosh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacosh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacosh.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+/* acosh(z) = i acos(z) */
+
+double complex cacosh(double complex z)
+{
+	z = cacos(z);
+	return CMPLX(-cimag(z), creal(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacoshf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacoshf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacoshf.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+float complex cacoshf(float complex z)
+{
+	z = cacosf(z);
+	return CMPLXF(-cimagf(z), crealf(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacoshl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacoshl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacoshl.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex cacoshl(long double complex z)
+{
+	return cacosh(z);
+}
+#else
+long double complex cacoshl(long double complex z)
+{
+	z = cacosl(z);
+	return CMPLXL(-cimagl(z), creall(z));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacosl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacosl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cacosl.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex cacosl(long double complex z)
+{
+	return cacos(z);
+}
+#else
+// FIXME
+#define PI_2 1.57079632679489661923132169163975144L
+long double complex cacosl(long double complex z)
+{
+	z = casinl(z);
+	return CMPLXL(PI_2 - creall(z), -cimagl(z));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/carg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/carg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/carg.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+double carg(double complex z)
+{
+	return atan2(cimag(z), creal(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cargf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cargf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cargf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float cargf(float complex z)
+{
+	return atan2f(cimagf(z), crealf(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cargl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cargl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cargl.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double cargl(long double complex z)
+{
+	return carg(z);
+}
+#else
+long double cargl(long double complex z)
+{
+	return atan2l(cimagl(z), creall(z));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casin.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casin.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casin.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "libm.h"
+
+// FIXME
+
+/* asin(z) = -i log(i z + sqrt(1 - z*z)) */
+
+double complex casin(double complex z)
+{
+	double complex w;
+	double x, y;
+
+	x = creal(z);
+	y = cimag(z);
+	w = CMPLX(1.0 - (x - y)*(x + y), -2.0*x*y);
+	return clog(CMPLX(-y, x) + csqrt(w));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinf.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+// FIXME
+
+float complex casinf(float complex z)
+{
+	float complex w;
+	float x, y;
+
+	x = crealf(z);
+	y = cimagf(z);
+	w = CMPLXF(1.0 - (x - y)*(x + y), -2.0*x*y);
+	return clogf(CMPLXF(-y, x) + csqrtf(w));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinh.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+/* asinh(z) = -i asin(i z) */
+
+double complex casinh(double complex z)
+{
+	z = casin(CMPLX(-cimag(z), creal(z)));
+	return CMPLX(cimag(z), -creal(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinhf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinhf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinhf.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+float complex casinhf(float complex z)
+{
+	z = casinf(CMPLXF(-cimagf(z), crealf(z)));
+	return CMPLXF(cimagf(z), -crealf(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinhl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinhl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinhl.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex casinhl(long double complex z)
+{
+	return casinh(z);
+}
+#else
+long double complex casinhl(long double complex z)
+{
+	z = casinl(CMPLXL(-cimagl(z), creall(z)));
+	return CMPLXL(cimagl(z), -creall(z));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/casinl.c	(revision 398)
@@ -0,0 +1,20 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex casinl(long double complex z)
+{
+	return casin(z);
+}
+#else
+// FIXME
+long double complex casinl(long double complex z)
+{
+	long double complex w;
+	long double x, y;
+
+	x = creall(z);
+	y = cimagl(z);
+	w = CMPLXL(1.0 - (x - y)*(x + y), -2.0*x*y);
+	return clogl(CMPLXL(-y, x) + csqrtl(w));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catan.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catan.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catan.c	(revision 398)
@@ -0,0 +1,119 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/s_catan.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Complex circular arc tangent
+ *
+ *
+ * SYNOPSIS:
+ *
+ * double complex catan();
+ * double complex z, w;
+ *
+ * w = catan (z);
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ *     z = x + iy,
+ *
+ * then
+ *          1       (    2x     )
+ * Re w  =  - arctan(-----------)  +  k PI
+ *          2       (     2    2)
+ *                  (1 - x  - y )
+ *
+ *               ( 2         2)
+ *          1    (x  +  (y+1) )
+ * Im w  =  - log(------------)
+ *          4    ( 2         2)
+ *               (x  +  (y-1) )
+ *
+ * Where k is an arbitrary integer.
+ *
+ * catan(z) = -i catanh(iz).
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    DEC       -10,+10      5900       1.3e-16     7.8e-18
+ *    IEEE      -10,+10     30000       2.3e-15     8.5e-17
+ * The check catan( ctan(z) )  =  z, with |x| and |y| < PI/2,
+ * had peak relative error 1.5e-16, rms relative error
+ * 2.9e-17.  See also clog().
+ */
+
+#include "libm.h"
+
+#define MAXNUM 1.0e308
+
+static const double DP1 = 3.14159265160560607910E0;
+static const double DP2 = 1.98418714791870343106E-9;
+static const double DP3 = 1.14423774522196636802E-17;
+
+static double _redupi(double x)
+{
+	double t;
+	long i;
+
+	t = x/M_PI;
+	if (t >= 0.0)
+		t += 0.5;
+	else
+		t -= 0.5;
+
+	i = t;  /* the multiple */
+	t = i;
+	t = ((x - t * DP1) - t * DP2) - t * DP3;
+	return t;
+}
+
+double complex catan(double complex z)
+{
+	double complex w;
+	double a, t, x, x2, y;
+
+	x = creal(z);
+	y = cimag(z);
+
+	if (x == 0.0 && y > 1.0)
+		goto ovrf;
+
+	x2 = x * x;
+	a = 1.0 - x2 - (y * y);
+	if (a == 0.0)
+		goto ovrf;
+
+	t = 0.5 * atan2(2.0 * x, a);
+	w = _redupi(t);
+
+	t = y - 1.0;
+	a = x2 + (t * t);
+	if (a == 0.0)
+		goto ovrf;
+
+	t = y + 1.0;
+	a = (x2 + t * t)/a;
+	w = w + (0.25 * log(a)) * I;
+	return w;
+
+ovrf:
+	// FIXME
+	w = MAXNUM + MAXNUM * I;
+	return w;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanf.c	(revision 398)
@@ -0,0 +1,115 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/s_catanf.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Complex circular arc tangent
+ *
+ *
+ * SYNOPSIS:
+ *
+ * float complex catanf();
+ * float complex z, w;
+ *
+ * w = catanf( z );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ *     z = x + iy,
+ *
+ * then
+ *          1       (    2x     )
+ * Re w  =  - arctan(-----------)  +  k PI
+ *          2       (     2    2)
+ *                  (1 - x  - y )
+ *
+ *               ( 2         2)
+ *          1    (x  +  (y+1) )
+ * Im w  =  - log(------------)
+ *          4    ( 2         2)
+ *               (x  +  (y-1) )
+ *
+ * Where k is an arbitrary integer.
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      -10,+10     30000        2.3e-6      5.2e-8
+ */
+
+#include "libm.h"
+
+#define MAXNUMF 1.0e38F
+
+static const double DP1 = 3.140625;
+static const double DP2 = 9.67502593994140625E-4;
+static const double DP3 = 1.509957990978376432E-7;
+
+static float _redupif(float xx)
+{
+	float x, t;
+	long i;
+
+	x = xx;
+	t = x/(float)M_PI;
+	if (t >= 0.0f)
+		t += 0.5f;
+	else
+		t -= 0.5f;
+
+	i = t;  /* the multiple */
+	t = i;
+	t = ((x - t * DP1) - t * DP2) - t * DP3;
+	return t;
+}
+
+float complex catanf(float complex z)
+{
+	float complex w;
+	float a, t, x, x2, y;
+
+	x = crealf(z);
+	y = cimagf(z);
+
+	if ((x == 0.0f) && (y > 1.0f))
+		goto ovrf;
+
+	x2 = x * x;
+	a = 1.0f - x2 - (y * y);
+	if (a == 0.0f)
+		goto ovrf;
+
+	t = 0.5f * atan2f(2.0f * x, a);
+	w = _redupif(t);
+
+	t = y - 1.0f;
+	a = x2 + (t * t);
+	if (a == 0.0f)
+		goto ovrf;
+
+	t = y + 1.0f;
+	a = (x2 + (t * t))/a;
+	w = w + (0.25f * logf (a)) * I;
+	return w;
+
+ovrf:
+	// FIXME
+	w = MAXNUMF + MAXNUMF * I;
+	return w;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanh.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+/* atanh = -i atan(i z) */
+
+double complex catanh(double complex z)
+{
+	z = catan(CMPLX(-cimag(z), creal(z)));
+	return CMPLX(cimag(z), -creal(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanhf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanhf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanhf.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+float complex catanhf(float complex z)
+{
+	z = catanf(CMPLXF(-cimagf(z), crealf(z)));
+	return CMPLXF(cimagf(z), -crealf(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanhl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanhl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanhl.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex catanhl(long double complex z)
+{
+	return catanh(z);
+}
+#else
+long double complex catanhl(long double complex z)
+{
+	z = catanl(CMPLXL(-cimagl(z), creall(z)));
+	return CMPLXL(cimagl(z), -creall(z));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/catanl.c	(revision 398)
@@ -0,0 +1,126 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/s_catanl.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Complex circular arc tangent
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double complex catanl();
+ * long double complex z, w;
+ *
+ * w = catanl( z );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * If
+ *     z = x + iy,
+ *
+ * then
+ *          1       (    2x     )
+ * Re w  =  - arctan(-----------)  +  k PI
+ *          2       (     2    2)
+ *                  (1 - x  - y )
+ *
+ *               ( 2         2)
+ *          1    (x  +  (y+1) )
+ * Im w  =  - log(------------)
+ *          4    ( 2         2)
+ *               (x  +  (y-1) )
+ *
+ * Where k is an arbitrary integer.
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    DEC       -10,+10      5900       1.3e-16     7.8e-18
+ *    IEEE      -10,+10     30000       2.3e-15     8.5e-17
+ * The check catan( ctan(z) )  =  z, with |x| and |y| < PI/2,
+ * had peak relative error 1.5e-16, rms relative error
+ * 2.9e-17.  See also clog().
+ */
+
+#include <complex.h>
+#include <float.h>
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex catanl(long double complex z)
+{
+	return catan(z);
+}
+#else
+static const long double PIL = 3.141592653589793238462643383279502884197169L;
+static const long double DP1 = 3.14159265358979323829596852490908531763125L;
+static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L;
+static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L;
+
+static long double redupil(long double x)
+{
+	long double t;
+	long i;
+
+	t = x / PIL;
+	if (t >= 0.0L)
+		t += 0.5L;
+	else
+		t -= 0.5L;
+
+	i = t;  /* the multiple */
+	t = i;
+	t = ((x - t * DP1) - t * DP2) - t * DP3;
+	return t;
+}
+
+long double complex catanl(long double complex z)
+{
+	long double complex w;
+	long double a, t, x, x2, y;
+
+	x = creall(z);
+	y = cimagl(z);
+
+	if ((x == 0.0L) && (y > 1.0L))
+		goto ovrf;
+
+	x2 = x * x;
+	a = 1.0L - x2 - (y * y);
+	if (a == 0.0L)
+		goto ovrf;
+
+	t = atan2l(2.0L * x, a) * 0.5L;
+	w = redupil(t);
+
+	t = y - 1.0L;
+	a = x2 + (t * t);
+	if (a == 0.0L)
+		goto ovrf;
+
+	t = y + 1.0L;
+	a = (x2 + (t * t)) / a;
+	w = w + (0.25L * logl(a)) * I;
+	return w;
+
+ovrf:
+	// FIXME
+	w = LDBL_MAX + LDBL_MAX * I;
+	return w;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccos.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccos.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccos.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "libm.h"
+
+/* cos(z) = cosh(i z) */
+
+double complex ccos(double complex z)
+{
+	return ccosh(CMPLX(-cimag(z), creal(z)));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccosf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccosf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccosf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float complex ccosf(float complex z)
+{
+	return ccoshf(CMPLXF(-cimagf(z), crealf(z)));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccosh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccosh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccosh.c	(revision 398)
@@ -0,0 +1,140 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_ccosh.c */
+/*-
+ * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Hyperbolic cosine of a complex argument z = x + i y.
+ *
+ * cosh(z) = cosh(x+iy)
+ *         = cosh(x) cos(y) + i sinh(x) sin(y).
+ *
+ * Exceptional values are noted in the comments within the source code.
+ * These values and the return value were taken from n1124.pdf.
+ */
+
+#include "libm.h"
+
+static const double huge = 0x1p1023;
+
+double complex ccosh(double complex z)
+{
+	double x, y, h;
+	int32_t hx, hy, ix, iy, lx, ly;
+
+	x = creal(z);
+	y = cimag(z);
+
+	EXTRACT_WORDS(hx, lx, x);
+	EXTRACT_WORDS(hy, ly, y);
+
+	ix = 0x7fffffff & hx;
+	iy = 0x7fffffff & hy;
+
+	/* Handle the nearly-non-exceptional cases where x and y are finite. */
+	if (ix < 0x7ff00000 && iy < 0x7ff00000) {
+		if ((iy | ly) == 0)
+			return CMPLX(cosh(x), x * y);
+		if (ix < 0x40360000)    /* small x: normal case */
+			return CMPLX(cosh(x) * cos(y), sinh(x) * sin(y));
+
+		/* |x| >= 22, so cosh(x) ~= exp(|x|) */
+		if (ix < 0x40862e42) {
+			/* x < 710: exp(|x|) won't overflow */
+			h = exp(fabs(x)) * 0.5;
+			return CMPLX(h * cos(y), copysign(h, x) * sin(y));
+		} else if (ix < 0x4096bbaa) {
+			/* x < 1455: scale to avoid overflow */
+			z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
+			return CMPLX(creal(z), cimag(z) * copysign(1, x));
+		} else {
+			/* x >= 1455: the result always overflows */
+			h = huge * x;
+			return CMPLX(h * h * cos(y), h * sin(y));
+		}
+	}
+
+	/*
+	 * cosh(+-0 +- I Inf) = dNaN + I sign(d(+-0, dNaN))0.
+	 * The sign of 0 in the result is unspecified.  Choice = normally
+	 * the same as dNaN.  Raise the invalid floating-point exception.
+	 *
+	 * cosh(+-0 +- I NaN) = d(NaN) + I sign(d(+-0, NaN))0.
+	 * The sign of 0 in the result is unspecified.  Choice = normally
+	 * the same as d(NaN).
+	 */
+	if ((ix | lx) == 0 && iy >= 0x7ff00000)
+		return CMPLX(y - y, copysign(0, x * (y - y)));
+
+	/*
+	 * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0.
+	 *
+	 * cosh(NaN +- I 0)   = d(NaN) + I sign(d(NaN, +-0))0.
+	 * The sign of 0 in the result is unspecified.
+	 */
+	if ((iy | ly) == 0 && ix >= 0x7ff00000) {
+		if (((hx & 0xfffff) | lx) == 0)
+			return CMPLX(x * x, copysign(0, x) * y);
+		return CMPLX(x * x, copysign(0, (x + x) * y));
+	}
+
+	/*
+	 * cosh(x +- I Inf) = dNaN + I dNaN.
+	 * Raise the invalid floating-point exception for finite nonzero x.
+	 *
+	 * cosh(x + I NaN) = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception for finite
+	 * nonzero x.  Choice = don't raise (except for signaling NaNs).
+	 */
+	if (ix < 0x7ff00000 && iy >= 0x7ff00000)
+		return CMPLX(y - y, x * (y - y));
+
+	/*
+	 * cosh(+-Inf + I NaN)  = +Inf + I d(NaN).
+	 *
+	 * cosh(+-Inf +- I Inf) = +Inf + I dNaN.
+	 * The sign of Inf in the result is unspecified.  Choice = always +.
+	 * Raise the invalid floating-point exception.
+	 *
+	 * cosh(+-Inf + I y)   = +Inf cos(y) +- I Inf sin(y)
+	 */
+	if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
+		if (iy >= 0x7ff00000)
+			return CMPLX(x * x, x * (y - y));
+		return CMPLX((x * x) * cos(y), x * sin(y));
+	}
+
+	/*
+	 * cosh(NaN + I NaN)  = d(NaN) + I d(NaN).
+	 *
+	 * cosh(NaN +- I Inf) = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception.
+	 * Choice = raise.
+	 *
+	 * cosh(NaN + I y)    = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception for finite
+	 * nonzero y.  Choice = don't raise (except for signaling NaNs).
+	 */
+	return CMPLX((x * x) * (y - y), (x + x) * (y - y));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccoshf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccoshf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccoshf.c	(revision 398)
@@ -0,0 +1,90 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_ccoshf.c */
+/*-
+ * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Hyperbolic cosine of a complex argument.  See s_ccosh.c for details.
+ */
+
+#include "libm.h"
+
+static const float huge = 0x1p127;
+
+float complex ccoshf(float complex z)
+{
+	float x, y, h;
+	int32_t hx, hy, ix, iy;
+
+	x = crealf(z);
+	y = cimagf(z);
+
+	GET_FLOAT_WORD(hx, x);
+	GET_FLOAT_WORD(hy, y);
+
+	ix = 0x7fffffff & hx;
+	iy = 0x7fffffff & hy;
+
+	if (ix < 0x7f800000 && iy < 0x7f800000) {
+		if (iy == 0)
+			return CMPLXF(coshf(x), x * y);
+		if (ix < 0x41100000)    /* small x: normal case */
+			return CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y));
+
+		/* |x| >= 9, so cosh(x) ~= exp(|x|) */
+		if (ix < 0x42b17218) {
+			/* x < 88.7: expf(|x|) won't overflow */
+			h = expf(fabsf(x)) * 0.5f;
+			return CMPLXF(h * cosf(y), copysignf(h, x) * sinf(y));
+		} else if (ix < 0x4340b1e7) {
+			/* x < 192.7: scale to avoid overflow */
+			z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
+			return CMPLXF(crealf(z), cimagf(z) * copysignf(1, x));
+		} else {
+			/* x >= 192.7: the result always overflows */
+			h = huge * x;
+			return CMPLXF(h * h * cosf(y), h * sinf(y));
+		}
+	}
+
+	if (ix == 0 && iy >= 0x7f800000)
+		return CMPLXF(y - y, copysignf(0, x * (y - y)));
+
+	if (iy == 0 && ix >= 0x7f800000) {
+		if ((hx & 0x7fffff) == 0)
+			return CMPLXF(x * x, copysignf(0, x) * y);
+		return CMPLXF(x * x, copysignf(0, (x + x) * y));
+	}
+
+	if (ix < 0x7f800000 && iy >= 0x7f800000)
+		return CMPLXF(y - y, x * (y - y));
+
+	if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
+		if (iy >= 0x7f800000)
+			return CMPLXF(x * x, x * (y - y));
+		return CMPLXF((x * x) * cosf(y), x * sinf(y));
+	}
+
+	return CMPLXF((x * x) * (y - y), (x + x) * (y - y));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccoshl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccoshl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccoshl.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+//FIXME
+long double complex ccoshl(long double complex z)
+{
+	return ccosh(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccosl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccosl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ccosl.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex ccosl(long double complex z)
+{
+	return ccos(z);
+}
+#else
+long double complex ccosl(long double complex z)
+{
+	return ccoshl(CMPLXL(-cimagl(z), creall(z)));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cexp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cexp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cexp.c	(revision 398)
@@ -0,0 +1,83 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cexp.c */
+/*-
+ * Copyright (c) 2011 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 "libm.h"
+
+static const uint32_t
+exp_ovfl  = 0x40862e42,  /* high bits of MAX_EXP * ln2 ~= 710 */
+cexp_ovfl = 0x4096b8e4;  /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */
+
+double complex cexp(double complex z)
+{
+	double x, y, exp_x;
+	uint32_t hx, hy, lx, ly;
+
+	x = creal(z);
+	y = cimag(z);
+
+	EXTRACT_WORDS(hy, ly, y);
+	hy &= 0x7fffffff;
+
+	/* cexp(x + I 0) = exp(x) + I 0 */
+	if ((hy | ly) == 0)
+		return CMPLX(exp(x), y);
+	EXTRACT_WORDS(hx, lx, x);
+	/* cexp(0 + I y) = cos(y) + I sin(y) */
+	if (((hx & 0x7fffffff) | lx) == 0)
+		return CMPLX(cos(y), sin(y));
+
+	if (hy >= 0x7ff00000) {
+		if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) {
+			/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
+			return CMPLX(y - y, y - y);
+		} else if (hx & 0x80000000) {
+			/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
+			return CMPLX(0.0, 0.0);
+		} else {
+			/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
+			return CMPLX(x, y - y);
+		}
+	}
+
+	if (hx >= exp_ovfl && hx <= cexp_ovfl) {
+		/*
+		 * x is between 709.7 and 1454.3, so we must scale to avoid
+		 * overflow in exp(x).
+		 */
+		return __ldexp_cexp(z, 0);
+	} else {
+		/*
+		 * Cases covered here:
+		 *  -  x < exp_ovfl and exp(x) won't overflow (common case)
+		 *  -  x > cexp_ovfl, so exp(x) * s overflows for all s > 0
+		 *  -  x = +-Inf (generated by exp())
+		 *  -  x = NaN (spurious inexact exception from y)
+		 */
+		exp_x = exp(x);
+		return CMPLX(exp_x * cos(y), exp_x * sin(y));
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cexpf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cexpf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cexpf.c	(revision 398)
@@ -0,0 +1,83 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cexpf.c */
+/*-
+ * Copyright (c) 2011 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 "libm.h"
+
+static const uint32_t
+exp_ovfl  = 0x42b17218,  /* MAX_EXP * ln2 ~= 88.722839355 */
+cexp_ovfl = 0x43400074;  /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */
+
+float complex cexpf(float complex z)
+{
+	float x, y, exp_x;
+	uint32_t hx, hy;
+
+	x = crealf(z);
+	y = cimagf(z);
+
+	GET_FLOAT_WORD(hy, y);
+	hy &= 0x7fffffff;
+
+	/* cexp(x + I 0) = exp(x) + I 0 */
+	if (hy == 0)
+		return CMPLXF(expf(x), y);
+	GET_FLOAT_WORD(hx, x);
+	/* cexp(0 + I y) = cos(y) + I sin(y) */
+	if ((hx & 0x7fffffff) == 0)
+		return CMPLXF(cosf(y), sinf(y));
+
+	if (hy >= 0x7f800000) {
+		if ((hx & 0x7fffffff) != 0x7f800000) {
+			/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
+			return CMPLXF(y - y, y - y);
+		} else if (hx & 0x80000000) {
+			/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
+			return CMPLXF(0.0, 0.0);
+		} else {
+			/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
+			return CMPLXF(x, y - y);
+		}
+	}
+
+	if (hx >= exp_ovfl && hx <= cexp_ovfl) {
+		/*
+		 * x is between 88.7 and 192, so we must scale to avoid
+		 * overflow in expf(x).
+		 */
+		return __ldexp_cexpf(z, 0);
+	} else {
+		/*
+		 * Cases covered here:
+		 *  -  x < exp_ovfl and exp(x) won't overflow (common case)
+		 *  -  x > cexp_ovfl, so exp(x) * s overflows for all s > 0
+		 *  -  x = +-Inf (generated by exp())
+		 *  -  x = NaN (spurious inexact exception from y)
+		 */
+		exp_x = expf(x);
+		return CMPLXF(exp_x * cosf(y), exp_x * sinf(y));
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cexpl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cexpl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cexpl.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+//FIXME
+long double complex cexpl(long double complex z)
+{
+	return cexp(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cimag.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cimag.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cimag.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+double (cimag)(double complex z)
+{
+	return cimag(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cimagf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cimagf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cimagf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float (cimagf)(float complex z)
+{
+	return cimagf(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cimagl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cimagl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cimagl.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+long double (cimagl)(long double complex z)
+{
+	return cimagl(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/clog.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/clog.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/clog.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+// FIXME
+
+/* log(z) = log(|z|) + i arg(z) */
+
+double complex clog(double complex z)
+{
+	double r, phi;
+
+	r = cabs(z);
+	phi = carg(z);
+	return CMPLX(log(r), phi);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/clogf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/clogf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/clogf.c	(revision 398)
@@ -0,0 +1,12 @@
+#include "libm.h"
+
+// FIXME
+
+float complex clogf(float complex z)
+{
+	float r, phi;
+
+	r = cabsf(z);
+	phi = cargf(z);
+	return CMPLXF(logf(r), phi);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/clogl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/clogl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/clogl.c	(revision 398)
@@ -0,0 +1,18 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex clogl(long double complex z)
+{
+	return clog(z);
+}
+#else
+// FIXME
+long double complex clogl(long double complex z)
+{
+	long double r, phi;
+
+	r = cabsl(z);
+	phi = cargl(z);
+	return CMPLXL(logl(r), phi);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/conj.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/conj.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/conj.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+double complex conj(double complex z)
+{
+	return CMPLX(creal(z), -cimag(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/conjf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/conjf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/conjf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float complex conjf(float complex z)
+{
+	return CMPLXF(crealf(z), -cimagf(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/conjl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/conjl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/conjl.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+long double complex conjl(long double complex z)
+{
+	return CMPLXL(creall(z), -cimagl(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cpow.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cpow.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cpow.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "libm.h"
+
+/* pow(z, c) = exp(c log(z)), See C99 G.6.4.1 */
+
+double complex cpow(double complex z, double complex c)
+{
+	return cexp(c * clog(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cpowf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cpowf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cpowf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libm.h"
+
+float complex cpowf(float complex z, float complex c)
+{
+	return cexpf(c * clogf(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cpowl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cpowl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cpowl.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex cpowl(long double complex z, long double complex c)
+{
+	return cpow(z, c);
+}
+#else
+long double complex cpowl(long double complex z, long double complex c)
+{
+	return cexpl(c * clogl(z));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cproj.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cproj.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cproj.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "libm.h"
+
+double complex cproj(double complex z)
+{
+	if (isinf(creal(z)) || isinf(cimag(z)))
+		return CMPLX(INFINITY, copysign(0.0, creal(z)));
+	return z;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cprojf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cprojf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cprojf.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "libm.h"
+
+float complex cprojf(float complex z)
+{
+	if (isinf(crealf(z)) || isinf(cimagf(z)))
+		return CMPLXF(INFINITY, copysignf(0.0, crealf(z)));
+	return z;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cprojl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cprojl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/cprojl.c	(revision 398)
@@ -0,0 +1,15 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex cprojl(long double complex z)
+{
+	return cproj(z);
+}
+#else
+long double complex cprojl(long double complex z)
+{
+	if (isinf(creall(z)) || isinf(cimagl(z)))
+		return CMPLXL(INFINITY, copysignl(0.0, creall(z)));
+	return z;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/creal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/creal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/creal.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <complex.h>
+
+double (creal)(double complex z)
+{
+	return creal(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/crealf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/crealf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/crealf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <complex.h>
+
+float (crealf)(float complex z)
+{
+	return crealf(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/creall.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/creall.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/creall.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <complex.h>
+
+long double (creall)(long double complex z)
+{
+	return creall(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csin.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csin.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csin.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+/* sin(z) = -i sinh(i z) */
+
+double complex csin(double complex z)
+{
+	z = csinh(CMPLX(-cimag(z), creal(z)));
+	return CMPLX(cimag(z), -creal(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinf.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+float complex csinf(float complex z)
+{
+	z = csinhf(CMPLXF(-cimagf(z), crealf(z)));
+	return CMPLXF(cimagf(z), -crealf(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinh.c	(revision 398)
@@ -0,0 +1,141 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_csinh.c */
+/*-
+ * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Hyperbolic sine of a complex argument z = x + i y.
+ *
+ * sinh(z) = sinh(x+iy)
+ *         = sinh(x) cos(y) + i cosh(x) sin(y).
+ *
+ * Exceptional values are noted in the comments within the source code.
+ * These values and the return value were taken from n1124.pdf.
+ */
+
+#include "libm.h"
+
+static const double huge = 0x1p1023;
+
+double complex csinh(double complex z)
+{
+	double x, y, h;
+	int32_t hx, hy, ix, iy, lx, ly;
+
+	x = creal(z);
+	y = cimag(z);
+
+	EXTRACT_WORDS(hx, lx, x);
+	EXTRACT_WORDS(hy, ly, y);
+
+	ix = 0x7fffffff & hx;
+	iy = 0x7fffffff & hy;
+
+	/* Handle the nearly-non-exceptional cases where x and y are finite. */
+	if (ix < 0x7ff00000 && iy < 0x7ff00000) {
+		if ((iy | ly) == 0)
+			return CMPLX(sinh(x), y);
+		if (ix < 0x40360000)    /* small x: normal case */
+			return CMPLX(sinh(x) * cos(y), cosh(x) * sin(y));
+
+		/* |x| >= 22, so cosh(x) ~= exp(|x|) */
+		if (ix < 0x40862e42) {
+			/* x < 710: exp(|x|) won't overflow */
+			h = exp(fabs(x)) * 0.5;
+			return CMPLX(copysign(h, x) * cos(y), h * sin(y));
+		} else if (ix < 0x4096bbaa) {
+			/* x < 1455: scale to avoid overflow */
+			z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
+			return CMPLX(creal(z) * copysign(1, x), cimag(z));
+		} else {
+			/* x >= 1455: the result always overflows */
+			h = huge * x;
+			return CMPLX(h * cos(y), h * h * sin(y));
+		}
+	}
+
+	/*
+	 * sinh(+-0 +- I Inf) = sign(d(+-0, dNaN))0 + I dNaN.
+	 * The sign of 0 in the result is unspecified.  Choice = normally
+	 * the same as dNaN.  Raise the invalid floating-point exception.
+	 *
+	 * sinh(+-0 +- I NaN) = sign(d(+-0, NaN))0 + I d(NaN).
+	 * The sign of 0 in the result is unspecified.  Choice = normally
+	 * the same as d(NaN).
+	 */
+	if ((ix | lx) == 0 && iy >= 0x7ff00000)
+		return CMPLX(copysign(0, x * (y - y)), y - y);
+
+	/*
+	 * sinh(+-Inf +- I 0) = +-Inf + I +-0.
+	 *
+	 * sinh(NaN +- I 0)   = d(NaN) + I +-0.
+	 */
+	if ((iy | ly) == 0 && ix >= 0x7ff00000) {
+		if (((hx & 0xfffff) | lx) == 0)
+			return CMPLX(x, y);
+		return CMPLX(x, copysign(0, y));
+	}
+
+	/*
+	 * sinh(x +- I Inf) = dNaN + I dNaN.
+	 * Raise the invalid floating-point exception for finite nonzero x.
+	 *
+	 * sinh(x + I NaN) = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception for finite
+	 * nonzero x.  Choice = don't raise (except for signaling NaNs).
+	 */
+	if (ix < 0x7ff00000 && iy >= 0x7ff00000)
+		return CMPLX(y - y, x * (y - y));
+
+	/*
+	 * sinh(+-Inf + I NaN)  = +-Inf + I d(NaN).
+	 * The sign of Inf in the result is unspecified.  Choice = normally
+	 * the same as d(NaN).
+	 *
+	 * sinh(+-Inf +- I Inf) = +Inf + I dNaN.
+	 * The sign of Inf in the result is unspecified.  Choice = always +.
+	 * Raise the invalid floating-point exception.
+	 *
+	 * sinh(+-Inf + I y)   = +-Inf cos(y) + I Inf sin(y)
+	 */
+	if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
+		if (iy >= 0x7ff00000)
+			return CMPLX(x * x, x * (y - y));
+		return CMPLX(x * cos(y), INFINITY * sin(y));
+	}
+
+	/*
+	 * sinh(NaN + I NaN)  = d(NaN) + I d(NaN).
+	 *
+	 * sinh(NaN +- I Inf) = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception.
+	 * Choice = raise.
+	 *
+	 * sinh(NaN + I y)    = d(NaN) + I d(NaN).
+	 * Optionally raises the invalid floating-point exception for finite
+	 * nonzero y.  Choice = don't raise (except for signaling NaNs).
+	 */
+	return CMPLX((x * x) * (y - y), (x + x) * (y - y));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinhf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinhf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinhf.c	(revision 398)
@@ -0,0 +1,90 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_csinhf.c */
+/*-
+ * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Hyperbolic sine of a complex argument z.  See s_csinh.c for details.
+ */
+
+#include "libm.h"
+
+static const float huge = 0x1p127;
+
+float complex csinhf(float complex z)
+{
+	float x, y, h;
+	int32_t hx, hy, ix, iy;
+
+	x = crealf(z);
+	y = cimagf(z);
+
+	GET_FLOAT_WORD(hx, x);
+	GET_FLOAT_WORD(hy, y);
+
+	ix = 0x7fffffff & hx;
+	iy = 0x7fffffff & hy;
+
+	if (ix < 0x7f800000 && iy < 0x7f800000) {
+		if (iy == 0)
+			return CMPLXF(sinhf(x), y);
+		if (ix < 0x41100000)    /* small x: normal case */
+			return CMPLXF(sinhf(x) * cosf(y), coshf(x) * sinf(y));
+
+		/* |x| >= 9, so cosh(x) ~= exp(|x|) */
+		if (ix < 0x42b17218) {
+			/* x < 88.7: expf(|x|) won't overflow */
+			h = expf(fabsf(x)) * 0.5f;
+			return CMPLXF(copysignf(h, x) * cosf(y), h * sinf(y));
+		} else if (ix < 0x4340b1e7) {
+			/* x < 192.7: scale to avoid overflow */
+			z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
+			return CMPLXF(crealf(z) * copysignf(1, x), cimagf(z));
+		} else {
+			/* x >= 192.7: the result always overflows */
+			h = huge * x;
+			return CMPLXF(h * cosf(y), h * h * sinf(y));
+		}
+	}
+
+	if (ix == 0 && iy >= 0x7f800000)
+		return CMPLXF(copysignf(0, x * (y - y)), y - y);
+
+	if (iy == 0 && ix >= 0x7f800000) {
+		if ((hx & 0x7fffff) == 0)
+			return CMPLXF(x, y);
+		return CMPLXF(x, copysignf(0, y));
+	}
+
+	if (ix < 0x7f800000 && iy >= 0x7f800000)
+		return CMPLXF(y - y, x * (y - y));
+
+	if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
+		if (iy >= 0x7f800000)
+			return CMPLXF(x * x, x * (y - y));
+		return CMPLXF(x * cosf(y), INFINITY * sinf(y));
+	}
+
+	return CMPLXF((x * x) * (y - y), (x + x) * (y - y));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinhl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinhl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinhl.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+//FIXME
+long double complex csinhl(long double complex z)
+{
+	return csinh(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csinl.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex csinl(long double complex z)
+{
+	return csin(z);
+}
+#else
+long double complex csinl(long double complex z)
+{
+	z = csinhl(CMPLXL(-cimagl(z), creall(z)));
+	return CMPLXL(cimagl(z), -creall(z));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csqrt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csqrt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csqrt.c	(revision 398)
@@ -0,0 +1,100 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_csqrt.c */
+/*-
+ * Copyright (c) 2007 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 "libm.h"
+
+/*
+ * gcc doesn't implement complex multiplication or division correctly,
+ * so we need to handle infinities specially. We turn on this pragma to
+ * notify conforming c99 compilers that the fast-but-incorrect code that
+ * gcc generates is acceptable, since the special cases have already been
+ * handled.
+ */
+#pragma STDC CX_LIMITED_RANGE ON
+
+/* We risk spurious overflow for components >= DBL_MAX / (1 + sqrt(2)). */
+#define THRESH  0x1.a827999fcef32p+1022
+
+double complex csqrt(double complex z)
+{
+	double complex result;
+	double a, b;
+	double t;
+	int scale;
+
+	a = creal(z);
+	b = cimag(z);
+
+	/* Handle special cases. */
+	if (z == 0)
+		return CMPLX(0, b);
+	if (isinf(b))
+		return CMPLX(INFINITY, b);
+	if (isnan(a)) {
+		t = (b - b) / (b - b);  /* raise invalid if b is not a NaN */
+		return CMPLX(a, t);   /* return NaN + NaN i */
+	}
+	if (isinf(a)) {
+		/*
+		 * csqrt(inf + NaN i)  = inf +  NaN i
+		 * csqrt(inf + y i)    = inf +  0 i
+		 * csqrt(-inf + NaN i) = NaN +- inf i
+		 * csqrt(-inf + y i)   = 0   +  inf i
+		 */
+		if (signbit(a))
+			return CMPLX(fabs(b - b), copysign(a, b));
+		else
+			return CMPLX(a, copysign(b - b, b));
+	}
+	/*
+	 * The remaining special case (b is NaN) is handled just fine by
+	 * the normal code path below.
+	 */
+
+	/* Scale to avoid overflow. */
+	if (fabs(a) >= THRESH || fabs(b) >= THRESH) {
+		a *= 0.25;
+		b *= 0.25;
+		scale = 1;
+	} else {
+		scale = 0;
+	}
+
+	/* Algorithm 312, CACM vol 10, Oct 1967. */
+	if (a >= 0) {
+		t = sqrt((a + hypot(a, b)) * 0.5);
+		result = CMPLX(t, b / (2 * t));
+	} else {
+		t = sqrt((-a + hypot(a, b)) * 0.5);
+		result = CMPLX(fabs(b) / (2 * t), copysign(t, b));
+	}
+
+	/* Rescale. */
+	if (scale)
+		result *= 2;
+	return result;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csqrtf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csqrtf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csqrtf.c	(revision 398)
@@ -0,0 +1,82 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_csqrtf.c */
+/*-
+ * Copyright (c) 2007 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 "libm.h"
+
+/*
+ * gcc doesn't implement complex multiplication or division correctly,
+ * so we need to handle infinities specially. We turn on this pragma to
+ * notify conforming c99 compilers that the fast-but-incorrect code that
+ * gcc generates is acceptable, since the special cases have already been
+ * handled.
+ */
+#pragma STDC CX_LIMITED_RANGE ON
+
+float complex csqrtf(float complex z)
+{
+	float a = crealf(z), b = cimagf(z);
+	double t;
+
+	/* Handle special cases. */
+	if (z == 0)
+		return CMPLXF(0, b);
+	if (isinf(b))
+		return CMPLXF(INFINITY, b);
+	if (isnan(a)) {
+		t = (b - b) / (b - b);  /* raise invalid if b is not a NaN */
+		return CMPLXF(a, t);  /* return NaN + NaN i */
+	}
+	if (isinf(a)) {
+		/*
+		 * csqrtf(inf + NaN i)  = inf +  NaN i
+		 * csqrtf(inf + y i)    = inf +  0 i
+		 * csqrtf(-inf + NaN i) = NaN +- inf i
+		 * csqrtf(-inf + y i)   = 0   +  inf i
+		 */
+		if (signbit(a))
+			return CMPLXF(fabsf(b - b), copysignf(a, b));
+		else
+			return CMPLXF(a, copysignf(b - b, b));
+	}
+	/*
+	 * The remaining special case (b is NaN) is handled just fine by
+	 * the normal code path below.
+	 */
+
+	/*
+	 * We compute t in double precision to avoid overflow and to
+	 * provide correct rounding in nearly all cases.
+	 * This is Algorithm 312, CACM vol 10, Oct 1967.
+	 */
+	if (a >= 0) {
+		t = sqrt((a + hypot(a, b)) * 0.5);
+		return CMPLXF(t, b / (2.0 * t));
+	} else {
+		t = sqrt((-a + hypot(a, b)) * 0.5);
+		return CMPLXF(fabsf(b) / (2.0 * t), copysignf(t, b));
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csqrtl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csqrtl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/csqrtl.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+//FIXME
+long double complex csqrtl(long double complex z)
+{
+	return csqrt(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctan.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctan.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctan.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "libm.h"
+
+/* tan(z) = -i tanh(i z) */
+
+double complex ctan(double complex z)
+{
+	z = ctanh(CMPLX(-cimag(z), creal(z)));
+	return CMPLX(cimag(z), -creal(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanf.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+float complex ctanf(float complex z)
+{
+	z = ctanhf(CMPLXF(-cimagf(z), crealf(z)));
+	return CMPLXF(cimagf(z), -crealf(z));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanh.c	(revision 398)
@@ -0,0 +1,129 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_ctanh.c */
+/*-
+ * Copyright (c) 2011 David Schultz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Hyperbolic tangent of a complex argument z = x + i y.
+ *
+ * The algorithm is from:
+ *
+ *   W. Kahan.  Branch Cuts for Complex Elementary Functions or Much
+ *   Ado About Nothing's Sign Bit.  In The State of the Art in
+ *   Numerical Analysis, pp. 165 ff.  Iserles and Powell, eds., 1987.
+ *
+ * Method:
+ *
+ *   Let t    = tan(x)
+ *       beta = 1/cos^2(y)
+ *       s    = sinh(x)
+ *       rho  = cosh(x)
+ *
+ *   We have:
+ *
+ *   tanh(z) = sinh(z) / cosh(z)
+ *
+ *             sinh(x) cos(y) + i cosh(x) sin(y)
+ *           = ---------------------------------
+ *             cosh(x) cos(y) + i sinh(x) sin(y)
+ *
+ *             cosh(x) sinh(x) / cos^2(y) + i tan(y)
+ *           = -------------------------------------
+ *                    1 + sinh^2(x) / cos^2(y)
+ *
+ *             beta rho s + i t
+ *           = ----------------
+ *               1 + beta s^2
+ *
+ * Modifications:
+ *
+ *   I omitted the original algorithm's handling of overflow in tan(x) after
+ *   verifying with nearpi.c that this can't happen in IEEE single or double
+ *   precision.  I also handle large x differently.
+ */
+
+#include "libm.h"
+
+double complex ctanh(double complex z)
+{
+	double x, y;
+	double t, beta, s, rho, denom;
+	uint32_t hx, ix, lx;
+
+	x = creal(z);
+	y = cimag(z);
+
+	EXTRACT_WORDS(hx, lx, x);
+	ix = hx & 0x7fffffff;
+
+	/*
+	 * ctanh(NaN + i 0) = NaN + i 0
+	 *
+	 * ctanh(NaN + i y) = NaN + i NaN               for y != 0
+	 *
+	 * The imaginary part has the sign of x*sin(2*y), but there's no
+	 * special effort to get this right.
+	 *
+	 * ctanh(+-Inf +- i Inf) = +-1 +- 0
+	 *
+	 * ctanh(+-Inf + i y) = +-1 + 0 sin(2y)         for y finite
+	 *
+	 * The imaginary part of the sign is unspecified.  This special
+	 * case is only needed to avoid a spurious invalid exception when
+	 * y is infinite.
+	 */
+	if (ix >= 0x7ff00000) {
+		if ((ix & 0xfffff) | lx)        /* x is NaN */
+			return CMPLX(x, (y == 0 ? y : x * y));
+		SET_HIGH_WORD(x, hx - 0x40000000);      /* x = copysign(1, x) */
+		return CMPLX(x, copysign(0, isinf(y) ? y : sin(y) * cos(y)));
+	}
+
+	/*
+	 * ctanh(+-0 + i NAN) = +-0 + i NaN
+	 * ctanh(+-0 +- i Inf) = +-0 + i NaN
+	 * ctanh(x + i NAN) = NaN + i NaN
+	 * ctanh(x +- i Inf) = NaN + i NaN
+	 */
+	if (!isfinite(y))
+		return CMPLX(x ? y - y : x, y - y);
+
+	/*
+	 * ctanh(+-huge + i +-y) ~= +-1 +- i 2sin(2y)/exp(2x), using the
+	 * approximation sinh^2(huge) ~= exp(2*huge) / 4.
+	 * We use a modified formula to avoid spurious overflow.
+	 */
+	if (ix >= 0x40360000) { /* x >= 22 */
+		double exp_mx = exp(-fabs(x));
+		return CMPLX(copysign(1, x), 4 * sin(y) * cos(y) * exp_mx * exp_mx);
+	}
+
+	/* Kahan's algorithm */
+	t = tan(y);
+	beta = 1.0 + t * t;     /* = 1 / cos^2(y) */
+	s = sinh(x);
+	rho = sqrt(1 + s * s);  /* = cosh(x) */
+	denom = 1 + beta * s * s;
+	return CMPLX((beta * rho * s) / denom, t / denom);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanhf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanhf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanhf.c	(revision 398)
@@ -0,0 +1,66 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_ctanhf.c */
+/*-
+ * Copyright (c) 2011 David Schultz
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Hyperbolic tangent of a complex argument z.  See s_ctanh.c for details.
+ */
+
+#include "libm.h"
+
+float complex ctanhf(float complex z)
+{
+	float x, y;
+	float t, beta, s, rho, denom;
+	uint32_t hx, ix;
+
+	x = crealf(z);
+	y = cimagf(z);
+
+	GET_FLOAT_WORD(hx, x);
+	ix = hx & 0x7fffffff;
+
+	if (ix >= 0x7f800000) {
+		if (ix & 0x7fffff)
+			return CMPLXF(x, (y == 0 ? y : x * y));
+		SET_FLOAT_WORD(x, hx - 0x40000000);
+		return CMPLXF(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)));
+	}
+
+	if (!isfinite(y))
+		return CMPLXF(ix ? y - y : x, y - y);
+
+	if (ix >= 0x41300000) { /* x >= 11 */
+		float exp_mx = expf(-fabsf(x));
+		return CMPLXF(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx * exp_mx);
+	}
+
+	t = tanf(y);
+	beta = 1.0 + t * t;
+	s = sinhf(x);
+	rho = sqrtf(1 + s * s);
+	denom = 1 + beta * s * s;
+	return CMPLXF((beta * rho * s) / denom, t / denom);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanhl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanhl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanhl.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "libm.h"
+
+//FIXME
+long double complex ctanhl(long double complex z)
+{
+	return ctanh(z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/complex/ctanl.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double complex ctanl(long double complex z)
+{
+	return ctan(z);
+}
+#else
+long double complex ctanl(long double complex z)
+{
+	z = ctanhl(CMPLXL(-cimagl(z), creall(z)));
+	return CMPLXL(cimagl(z), -creall(z));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/confstr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/confstr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/confstr.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+
+size_t confstr(int name, char *buf, size_t len)
+{
+	const char *s = "";
+	if (!name) {
+		s = "/bin:/usr/bin";
+	} else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>33U) {
+		errno = EINVAL;
+		return 0;
+	}
+	// snprintf is overkill but avoid wasting code size to implement
+	// this completely useless function and its truncation semantics
+	return snprintf(buf, len, "%s", s) + 1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/fpathconf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/fpathconf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/fpathconf.c	(revision 398)
@@ -0,0 +1,35 @@
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+long fpathconf(int fd, int name)
+{
+	static const short values[] = {
+		[_PC_LINK_MAX] = _POSIX_LINK_MAX,
+		[_PC_MAX_CANON] = _POSIX_MAX_CANON,
+		[_PC_MAX_INPUT] = _POSIX_MAX_INPUT,
+		[_PC_NAME_MAX] = NAME_MAX,
+		[_PC_PATH_MAX] = PATH_MAX,
+		[_PC_PIPE_BUF] = PIPE_BUF,
+		[_PC_CHOWN_RESTRICTED] = 1,
+		[_PC_NO_TRUNC] = 1,
+		[_PC_VDISABLE] = 0,
+		[_PC_SYNC_IO] = 1,
+		[_PC_ASYNC_IO] = -1,
+		[_PC_PRIO_IO] = -1,
+		[_PC_SOCK_MAXBUF] = -1,
+		[_PC_FILESIZEBITS] = FILESIZEBITS,
+		[_PC_REC_INCR_XFER_SIZE] = 4096,
+		[_PC_REC_MAX_XFER_SIZE] = 4096,
+		[_PC_REC_MIN_XFER_SIZE] = 4096,
+		[_PC_REC_XFER_ALIGN] = 4096,
+		[_PC_ALLOC_SIZE_MIN] = 4096,
+		[_PC_SYMLINK_MAX] = SYMLINK_MAX,
+		[_PC_2_SYMLINKS] = 1
+	};
+	if (name >= sizeof(values)/sizeof(values[0])) {
+		errno = EINVAL;
+		return -1;
+	}
+	return values[name];
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/legacy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/legacy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/legacy.c	(revision 398)
@@ -0,0 +1,22 @@
+#include <sys/sysinfo.h>
+#include <unistd.h>
+
+int get_nprocs_conf()
+{
+	return sysconf(_SC_NPROCESSORS_CONF);
+}
+
+int get_nprocs()
+{
+	return sysconf(_SC_NPROCESSORS_ONLN);
+}
+
+long get_phys_pages()
+{
+	return sysconf(_SC_PHYS_PAGES);	
+}
+
+long get_avphys_pages()
+{
+	return sysconf(_SC_AVPHYS_PAGES);	
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/pathconf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/pathconf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/pathconf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+long pathconf(const char *path, int name)
+{
+	return fpathconf(-1, name);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/sysconf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/sysconf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/conf/sysconf.c	(revision 398)
@@ -0,0 +1,215 @@
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/resource.h>
+#include <signal.h>
+#include <sys/sysinfo.h>
+#include "syscall.h"
+#include "libc.h"
+
+#define JT(x) (-256|(x))
+#define VER JT(1)
+#define JT_ARG_MAX JT(2)
+#define JT_MQ_PRIO_MAX JT(3)
+#define JT_PAGE_SIZE JT(4)
+#define JT_SEM_VALUE_MAX JT(5)
+#define JT_NPROCESSORS_CONF JT(6)
+#define JT_NPROCESSORS_ONLN JT(7)
+#define JT_PHYS_PAGES JT(8)
+#define JT_AVPHYS_PAGES JT(9)
+#define JT_ZERO JT(10)
+
+#define RLIM(x) (-32768|(RLIMIT_ ## x))
+
+long sysconf(int name)
+{
+	static const short values[] = {
+		[_SC_ARG_MAX] = JT_ARG_MAX,
+		[_SC_CHILD_MAX] = RLIM(NPROC),
+		[_SC_CLK_TCK] = 100,
+		[_SC_NGROUPS_MAX] = 32,
+		[_SC_OPEN_MAX] = RLIM(NOFILE),
+		[_SC_STREAM_MAX] = -1,
+		[_SC_TZNAME_MAX] = TZNAME_MAX,
+		[_SC_JOB_CONTROL] = 1,
+		[_SC_SAVED_IDS] = 1,
+		[_SC_REALTIME_SIGNALS] = 1,
+		[_SC_PRIORITY_SCHEDULING] = -1,
+		[_SC_TIMERS] = VER,
+		[_SC_ASYNCHRONOUS_IO] = VER,
+		[_SC_PRIORITIZED_IO] = -1,
+		[_SC_SYNCHRONIZED_IO] = -1,
+		[_SC_FSYNC] = VER,
+		[_SC_MAPPED_FILES] = VER,
+		[_SC_MEMLOCK] = VER,
+		[_SC_MEMLOCK_RANGE] = VER,
+		[_SC_MEMORY_PROTECTION] = VER,
+		[_SC_MESSAGE_PASSING] = VER,
+		[_SC_SEMAPHORES] = VER,
+		[_SC_SHARED_MEMORY_OBJECTS] = VER,
+		[_SC_AIO_LISTIO_MAX] = -1,
+		[_SC_AIO_MAX] = -1,
+		[_SC_AIO_PRIO_DELTA_MAX] = JT_ZERO, /* ?? */
+		[_SC_DELAYTIMER_MAX] = _POSIX_DELAYTIMER_MAX,
+		[_SC_MQ_OPEN_MAX] = -1,
+		[_SC_MQ_PRIO_MAX] = JT_MQ_PRIO_MAX,
+		[_SC_VERSION] = VER,
+		[_SC_PAGE_SIZE] = JT_PAGE_SIZE,
+		[_SC_RTSIG_MAX] = _NSIG - 1 - 31 - 3,
+		[_SC_SEM_NSEMS_MAX] = SEM_NSEMS_MAX,
+		[_SC_SEM_VALUE_MAX] = JT_SEM_VALUE_MAX,
+		[_SC_SIGQUEUE_MAX] = -1,
+		[_SC_TIMER_MAX] = -1,
+		[_SC_BC_BASE_MAX] = _POSIX2_BC_BASE_MAX,
+		[_SC_BC_DIM_MAX] = _POSIX2_BC_DIM_MAX,
+		[_SC_BC_SCALE_MAX] = _POSIX2_BC_SCALE_MAX,
+		[_SC_BC_STRING_MAX] = _POSIX2_BC_STRING_MAX,
+		[_SC_COLL_WEIGHTS_MAX] = COLL_WEIGHTS_MAX,
+		[_SC_EXPR_NEST_MAX] = -1,
+		[_SC_LINE_MAX] = -1,
+		[_SC_RE_DUP_MAX] = RE_DUP_MAX,
+		[_SC_2_VERSION] = VER,
+		[_SC_2_C_BIND] = VER,
+		[_SC_2_C_DEV] = -1,
+		[_SC_2_FORT_DEV] = -1,
+		[_SC_2_FORT_RUN] = -1,
+		[_SC_2_SW_DEV] = -1,
+		[_SC_2_LOCALEDEF] = -1,
+		[_SC_IOV_MAX] = IOV_MAX,
+		[_SC_THREADS] = VER,
+		[_SC_THREAD_SAFE_FUNCTIONS] = VER,
+		[_SC_GETGR_R_SIZE_MAX] = -1,
+		[_SC_GETPW_R_SIZE_MAX] = -1,
+		[_SC_LOGIN_NAME_MAX] = 256,
+		[_SC_TTY_NAME_MAX] = TTY_NAME_MAX,
+		[_SC_THREAD_DESTRUCTOR_ITERATIONS] = PTHREAD_DESTRUCTOR_ITERATIONS,
+		[_SC_THREAD_KEYS_MAX] = PTHREAD_KEYS_MAX,
+		[_SC_THREAD_STACK_MIN] = PTHREAD_STACK_MIN,
+		[_SC_THREAD_THREADS_MAX] = -1,
+		[_SC_THREAD_ATTR_STACKADDR] = VER,
+		[_SC_THREAD_ATTR_STACKSIZE] = VER,
+		[_SC_THREAD_PRIORITY_SCHEDULING] = VER,
+		[_SC_THREAD_PRIO_INHERIT] = -1,
+		[_SC_THREAD_PRIO_PROTECT] = -1,
+		[_SC_THREAD_PROCESS_SHARED] = VER,
+		[_SC_NPROCESSORS_CONF] = JT_NPROCESSORS_CONF,
+		[_SC_NPROCESSORS_ONLN] = JT_NPROCESSORS_ONLN,
+		[_SC_PHYS_PAGES] = JT_PHYS_PAGES,
+		[_SC_AVPHYS_PAGES] = JT_AVPHYS_PAGES,
+		[_SC_ATEXIT_MAX] = -1,
+		[_SC_PASS_MAX] = -1,
+		[_SC_XOPEN_VERSION] = _XOPEN_VERSION,
+		[_SC_XOPEN_XCU_VERSION] = _XOPEN_VERSION,
+		[_SC_XOPEN_UNIX] = 1,
+		[_SC_XOPEN_CRYPT] = -1,
+		[_SC_XOPEN_ENH_I18N] = 1,
+		[_SC_XOPEN_SHM] = 1,
+		[_SC_2_CHAR_TERM] = -1,
+		[_SC_2_UPE] = -1,
+		[_SC_XOPEN_XPG2] = -1,
+		[_SC_XOPEN_XPG3] = -1,
+		[_SC_XOPEN_XPG4] = -1,
+		[_SC_NZERO] = NZERO,
+		[_SC_XBS5_ILP32_OFF32] = -1,
+		[_SC_XBS5_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : JT_ZERO,
+		[_SC_XBS5_LP64_OFF64] = sizeof(long)==8 ? 1 : JT_ZERO,
+		[_SC_XBS5_LPBIG_OFFBIG] = -1,
+		[_SC_XOPEN_LEGACY] = -1,
+		[_SC_XOPEN_REALTIME] = -1,
+		[_SC_XOPEN_REALTIME_THREADS] = -1,
+		[_SC_ADVISORY_INFO] = VER,
+		[_SC_BARRIERS] = VER,
+		[_SC_CLOCK_SELECTION] = VER,
+		[_SC_CPUTIME] = VER,
+		[_SC_THREAD_CPUTIME] = VER,
+		[_SC_MONOTONIC_CLOCK] = VER,
+		[_SC_READER_WRITER_LOCKS] = VER,
+		[_SC_SPIN_LOCKS] = VER,
+		[_SC_REGEXP] = 1,
+		[_SC_SHELL] = 1,
+		[_SC_SPAWN] = VER,
+		[_SC_SPORADIC_SERVER] = -1,
+		[_SC_THREAD_SPORADIC_SERVER] = -1,
+		[_SC_TIMEOUTS] = VER,
+		[_SC_TYPED_MEMORY_OBJECTS] = -1,
+		[_SC_2_PBS] = -1,
+		[_SC_2_PBS_ACCOUNTING] = -1,
+		[_SC_2_PBS_LOCATE] = -1,
+		[_SC_2_PBS_MESSAGE] = -1,
+		[_SC_2_PBS_TRACK] = -1,
+		[_SC_SYMLOOP_MAX] = SYMLOOP_MAX,
+		[_SC_STREAMS] = JT_ZERO,
+		[_SC_2_PBS_CHECKPOINT] = -1,
+		[_SC_V6_ILP32_OFF32] = -1,
+		[_SC_V6_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : JT_ZERO,
+		[_SC_V6_LP64_OFF64] = sizeof(long)==8 ? 1 : JT_ZERO,
+		[_SC_V6_LPBIG_OFFBIG] = -1,
+		[_SC_HOST_NAME_MAX] = HOST_NAME_MAX,
+		[_SC_TRACE] = -1,
+		[_SC_TRACE_EVENT_FILTER] = -1,
+		[_SC_TRACE_INHERIT] = -1,
+		[_SC_TRACE_LOG] = -1,
+
+		[_SC_IPV6] = VER,
+		[_SC_RAW_SOCKETS] = VER,
+		[_SC_V7_ILP32_OFF32] = -1,
+		[_SC_V7_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : JT_ZERO,
+		[_SC_V7_LP64_OFF64] = sizeof(long)==8 ? 1 : JT_ZERO,
+		[_SC_V7_LPBIG_OFFBIG] = -1,
+		[_SC_SS_REPL_MAX] = -1,
+		[_SC_TRACE_EVENT_NAME_MAX] = -1,
+		[_SC_TRACE_NAME_MAX] = -1,
+		[_SC_TRACE_SYS_MAX] = -1,
+		[_SC_TRACE_USER_EVENT_MAX] = -1,
+		[_SC_XOPEN_STREAMS] = JT_ZERO,
+		[_SC_THREAD_ROBUST_PRIO_INHERIT] = -1,
+		[_SC_THREAD_ROBUST_PRIO_PROTECT] = -1,
+	};
+
+	if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) {
+		errno = EINVAL;
+		return -1;
+	} else if (values[name] >= -1) {
+		return values[name];
+	} else if (values[name] < -256) {
+		struct rlimit lim;
+		getrlimit(values[name]&16383, &lim);
+		return lim.rlim_cur > LONG_MAX ? LONG_MAX : lim.rlim_cur;
+	}
+
+	switch ((unsigned char)values[name]) {
+	case VER & 255:
+		return _POSIX_VERSION;
+	case JT_ARG_MAX & 255:
+		return ARG_MAX;
+	case JT_MQ_PRIO_MAX & 255:
+		return MQ_PRIO_MAX;
+	case JT_PAGE_SIZE & 255:
+		return PAGE_SIZE;
+	case JT_SEM_VALUE_MAX & 255:
+		return SEM_VALUE_MAX;
+	case JT_NPROCESSORS_CONF & 255:
+	case JT_NPROCESSORS_ONLN & 255: ;
+		unsigned char set[128] = {1};
+		int i, cnt;
+		__syscall(SYS_sched_getaffinity, 0, sizeof set, set);
+		for (i=cnt=0; i<sizeof set; i++)
+			for (; set[i]; set[i]&=set[i]-1, cnt++);
+		return cnt;
+	case JT_PHYS_PAGES & 255:
+	case JT_AVPHYS_PAGES & 255: ;
+		unsigned long long mem;
+		int __lsysinfo(struct sysinfo *);
+		struct sysinfo si;
+		__lsysinfo(&si);
+		if (!si.mem_unit) si.mem_unit = 1;
+		if (name==_SC_PHYS_PAGES) mem = si.totalram;
+		else mem = si.freeram + si.bufferram;
+		mem *= si.mem_unit;
+		mem /= PAGE_SIZE;
+		return (mem > LONG_MAX) ? LONG_MAX : mem;
+	case JT_ZERO & 255:
+		return 0;
+	}
+	return values[name];
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <unistd.h>
+#include <crypt.h>
+
+char *__crypt_r(const char *, const char *, struct crypt_data *);
+
+char *crypt(const char *key, const char *salt)
+{
+	/* This buffer is sufficiently large for all
+	 * currently-supported hash types. It needs to be updated if
+	 * longer hashes are added. The cast to struct crypt_data * is
+	 * purely to meet the public API requirements of the crypt_r
+	 * function; the implementation of crypt_r uses the object
+	 * purely as a char buffer. */
+	static char buf[128];
+	return __crypt_r(key, salt, (struct crypt_data *)buf);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_blowfish.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_blowfish.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_blowfish.c	(revision 398)
@@ -0,0 +1,798 @@
+/* Modified by Rich Felker in for inclusion in musl libc, based on
+ * Solar Designer's second size-optimized version sent to the musl
+ * mailing list. */
+
+/*
+ * The crypt_blowfish homepage is:
+ *
+ *	http://www.openwall.com/crypt/
+ *
+ * This code comes from John the Ripper password cracker, with reentrant
+ * and crypt(3) interfaces added, but optimizations specific to password
+ * cracking removed.
+ *
+ * Written by Solar Designer <solar at openwall.com> in 1998-2012.
+ * No copyright is claimed, and the software is hereby placed in the public
+ * domain.  In case this attempt to disclaim copyright and place the software
+ * in the public domain is deemed null and void, then the software is
+ * Copyright (c) 1998-2012 Solar Designer and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * It is my intent that you should be able to use this on your system,
+ * as part of a software package, or anywhere else to improve security,
+ * ensure compatibility, or for any other purpose.  I would appreciate
+ * it if you give credit where it is due and keep your modifications in
+ * the public domain as well, but I don't require that in order to let
+ * you place this code and any modifications you make under a license
+ * of your choice.
+ *
+ * This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix
+ * "$2a$") by Niels Provos <provos at citi.umich.edu>, and uses some of his
+ * ideas.  The password hashing algorithm was designed by David Mazieres
+ * <dm at lcs.mit.edu>.  For more information on the level of compatibility,
+ * please refer to the comments in BF_set_key() below and to the included
+ * crypt(3) man page.
+ *
+ * There's a paper on the algorithm that explains its design decisions:
+ *
+ *	http://www.usenix.org/events/usenix99/provos.html
+ *
+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
+ * Blowfish library (I can't be sure if I would think of something if I
+ * hadn't seen his code).
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+typedef uint32_t BF_word;
+typedef int32_t BF_word_signed;
+
+/* Number of Blowfish rounds, this is also hardcoded into a few places */
+#define BF_N				16
+
+typedef BF_word BF_key[BF_N + 2];
+
+typedef union {
+	struct {
+		BF_key P;
+		BF_word S[4][0x100];
+	} s;
+	BF_word PS[BF_N + 2 + 4 * 0x100];
+} BF_ctx;
+
+/*
+ * Magic IV for 64 Blowfish encryptions that we do at the end.
+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
+ */
+static const BF_word BF_magic_w[6] = {
+	0x4F727068, 0x65616E42, 0x65686F6C,
+	0x64657253, 0x63727944, 0x6F756274
+};
+
+/*
+ * P-box and S-box tables initialized with digits of Pi.
+ */
+static const BF_ctx BF_init_state = {{
+	{
+		0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+		0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+		0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+		0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+		0x9216d5d9, 0x8979fb1b
+	}, {
+		{
+			0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+			0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+			0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+			0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+			0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+			0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+			0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+			0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+			0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+			0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+			0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+			0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+			0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+			0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+			0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+			0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+			0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+			0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+			0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+			0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+			0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+			0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+			0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+			0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+			0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+			0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+			0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+			0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+			0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+			0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+			0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+			0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+			0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+			0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+			0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+			0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+			0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+			0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+			0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+			0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+			0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+			0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+			0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+			0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+			0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+			0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+			0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+			0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+			0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+			0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+			0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+			0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+			0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+			0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+			0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
+		}, {
+			0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+			0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+			0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+			0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+			0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+			0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+			0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+			0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+			0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+			0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+			0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+			0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+			0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+			0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+			0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+			0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+			0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+			0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+			0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+			0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+			0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+			0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+			0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+			0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+			0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+			0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+			0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+			0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+			0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+			0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+			0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+			0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+			0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+			0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+			0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+			0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+			0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+			0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+			0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+			0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+			0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+			0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+			0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+			0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+			0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+			0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+			0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+			0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+			0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+			0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+			0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+			0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+			0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+			0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+			0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+			0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+			0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+			0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+			0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+			0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+			0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+			0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+			0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+			0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
+		}, {
+			0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+			0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+			0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+			0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+			0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+			0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+			0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+			0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+			0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+			0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+			0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+			0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+			0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+			0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+			0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+			0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+			0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+			0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+			0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+			0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+			0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+			0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+			0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+			0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+			0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+			0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+			0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+			0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+			0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+			0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+			0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+			0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+			0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+			0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+			0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+			0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+			0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+			0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+			0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+			0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+			0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+			0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+			0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+			0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+			0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+			0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+			0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+			0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+			0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+			0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+			0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+			0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+			0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+			0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+			0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+			0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+			0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+			0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+			0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+			0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+			0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+			0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+			0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+			0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
+		}, {
+			0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+			0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+			0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+			0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+			0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+			0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+			0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+			0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+			0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+			0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+			0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+			0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+			0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+			0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+			0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+			0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+			0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+			0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+			0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+			0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+			0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+			0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+			0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+			0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+			0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+			0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+			0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+			0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+			0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+			0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+			0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+			0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+			0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+			0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+			0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+			0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+			0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+			0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+			0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+			0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+			0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+			0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+			0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+			0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+			0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+			0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+			0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+			0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+			0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+			0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+			0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+			0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+			0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+			0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+			0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+			0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+			0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+			0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+			0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+			0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+			0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+			0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+			0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+			0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
+		}
+	}
+}};
+
+static const unsigned char BF_itoa64[64 + 1] =
+	"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+static const unsigned char BF_atoi64[0x60] = {
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
+	54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
+	64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
+	64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+	43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
+};
+
+#define BF_safe_atoi64(dst, src) \
+{ \
+	tmp = (unsigned char)(src); \
+	if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
+	tmp = BF_atoi64[tmp]; \
+	if (tmp > 63) return -1; \
+	(dst) = tmp; \
+}
+
+static int BF_decode(BF_word *dst, const char *src, int size)
+{
+	unsigned char *dptr = (unsigned char *)dst;
+	unsigned char *end = dptr + size;
+	const unsigned char *sptr = (const unsigned char *)src;
+	unsigned int tmp, c1, c2, c3, c4;
+
+	do {
+		BF_safe_atoi64(c1, *sptr++);
+		BF_safe_atoi64(c2, *sptr++);
+		*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
+		if (dptr >= end) break;
+
+		BF_safe_atoi64(c3, *sptr++);
+		*dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
+		if (dptr >= end) break;
+
+		BF_safe_atoi64(c4, *sptr++);
+		*dptr++ = ((c3 & 0x03) << 6) | c4;
+	} while (dptr < end);
+
+	return 0;
+}
+
+static void BF_encode(char *dst, const BF_word *src, int size)
+{
+	const unsigned char *sptr = (const unsigned char *)src;
+	const unsigned char *end = sptr + size;
+	unsigned char *dptr = (unsigned char *)dst;
+	unsigned int c1, c2;
+
+	do {
+		c1 = *sptr++;
+		*dptr++ = BF_itoa64[c1 >> 2];
+		c1 = (c1 & 0x03) << 4;
+		if (sptr >= end) {
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 4;
+		*dptr++ = BF_itoa64[c1];
+		c1 = (c2 & 0x0f) << 2;
+		if (sptr >= end) {
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 6;
+		*dptr++ = BF_itoa64[c1];
+		*dptr++ = BF_itoa64[c2 & 0x3f];
+	} while (sptr < end);
+}
+
+static void BF_swap(BF_word *x, int count)
+{
+	if ((union { int i; char c; }){1}.c)
+	do {
+		BF_word tmp = *x;
+		tmp = (tmp << 16) | (tmp >> 16);
+		*x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
+	} while (--count);
+}
+
+#define BF_ROUND(L, R, N) \
+	tmp1 = L & 0xFF; \
+	tmp2 = L >> 8; \
+	tmp2 &= 0xFF; \
+	tmp3 = L >> 16; \
+	tmp3 &= 0xFF; \
+	tmp4 = L >> 24; \
+	tmp1 = ctx->s.S[3][tmp1]; \
+	tmp2 = ctx->s.S[2][tmp2]; \
+	tmp3 = ctx->s.S[1][tmp3]; \
+	tmp3 += ctx->s.S[0][tmp4]; \
+	tmp3 ^= tmp2; \
+	R ^= ctx->s.P[N + 1]; \
+	tmp3 += tmp1; \
+	R ^= tmp3;
+
+static BF_word BF_encrypt(BF_ctx *ctx,
+    BF_word L, BF_word R,
+    BF_word *start, BF_word *end)
+{
+	BF_word tmp1, tmp2, tmp3, tmp4;
+	BF_word *ptr = start;
+
+	do {
+		L ^= ctx->s.P[0];
+#if 0
+		BF_ROUND(L, R, 0);
+		BF_ROUND(R, L, 1);
+		BF_ROUND(L, R, 2);
+		BF_ROUND(R, L, 3);
+		BF_ROUND(L, R, 4);
+		BF_ROUND(R, L, 5);
+		BF_ROUND(L, R, 6);
+		BF_ROUND(R, L, 7);
+		BF_ROUND(L, R, 8);
+		BF_ROUND(R, L, 9);
+		BF_ROUND(L, R, 10);
+		BF_ROUND(R, L, 11);
+		BF_ROUND(L, R, 12);
+		BF_ROUND(R, L, 13);
+		BF_ROUND(L, R, 14);
+		BF_ROUND(R, L, 15);
+#else
+		for (int i=0; i<16; i+=2) {
+			BF_ROUND(L, R, i);
+			BF_ROUND(R, L, i+1);
+		}
+#endif
+		tmp4 = R;
+		R = L;
+		L = tmp4 ^ ctx->s.P[BF_N + 1];
+		*ptr++ = L;
+		*ptr++ = R;
+	} while (ptr < end);
+
+	return L;
+}
+
+static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
+    unsigned char flags)
+{
+	const char *ptr = key;
+	unsigned int bug, i, j;
+	BF_word safety, sign, diff, tmp[2];
+
+/*
+ * There was a sign extension bug in older revisions of this function.  While
+ * we would have liked to simply fix the bug and move on, we have to provide
+ * a backwards compatibility feature (essentially the bug) for some systems and
+ * a safety measure for some others.  The latter is needed because for certain
+ * multiple inputs to the buggy algorithm there exist easily found inputs to
+ * the correct algorithm that produce the same hash.  Thus, we optionally
+ * deviate from the correct algorithm just enough to avoid such collisions.
+ * While the bug itself affected the majority of passwords containing
+ * characters with the 8th bit set (although only a percentage of those in a
+ * collision-producing way), the anti-collision safety measure affects
+ * only a subset of passwords containing the '\xff' character (not even all of
+ * those passwords, just some of them).  This character is not found in valid
+ * UTF-8 sequences and is rarely used in popular 8-bit character encodings.
+ * Thus, the safety measure is unlikely to cause much annoyance, and is a
+ * reasonable tradeoff to use when authenticating against existing hashes that
+ * are not reliably known to have been computed with the correct algorithm.
+ *
+ * We use an approach that tries to minimize side-channel leaks of password
+ * information - that is, we mostly use fixed-cost bitwise operations instead
+ * of branches or table lookups.  (One conditional branch based on password
+ * length remains.  It is not part of the bug aftermath, though, and is
+ * difficult and possibly unreasonable to avoid given the use of C strings by
+ * the caller, which results in similar timing leaks anyway.)
+ *
+ * For actual implementation, we set an array index in the variable "bug"
+ * (0 means no bug, 1 means sign extension bug emulation) and a flag in the
+ * variable "safety" (bit 16 is set when the safety measure is requested).
+ * Valid combinations of settings are:
+ *
+ * Prefix "$2a$": bug = 0, safety = 0x10000
+ * Prefix "$2x$": bug = 1, safety = 0
+ * Prefix "$2y$": bug = 0, safety = 0
+ */
+	bug = flags & 1;
+	safety = ((BF_word)flags & 2) << 15;
+
+	sign = diff = 0;
+
+	for (i = 0; i < BF_N + 2; i++) {
+		tmp[0] = tmp[1] = 0;
+		for (j = 0; j < 4; j++) {
+			tmp[0] <<= 8;
+			tmp[0] |= (unsigned char)*ptr; /* correct */
+			tmp[1] <<= 8;
+			tmp[1] |= (signed char)*ptr; /* bug */
+/*
+ * Sign extension in the first char has no effect - nothing to overwrite yet,
+ * and those extra 24 bits will be fully shifted out of the 32-bit word.  For
+ * chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign
+ * extension in tmp[1] occurs.  Once this flag is set, it remains set.
+ */
+			if (j)
+				sign |= tmp[1] & 0x80;
+			if (!*ptr)
+				ptr = key;
+			else
+				ptr++;
+		}
+		diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */
+
+		expanded[i] = tmp[bug];
+		initial[i] = BF_init_state.s.P[i] ^ tmp[bug];
+	}
+
+/*
+ * At this point, "diff" is zero iff the correct and buggy algorithms produced
+ * exactly the same result.  If so and if "sign" is non-zero, which indicates
+ * that there was a non-benign sign extension, this means that we have a
+ * collision between the correctly computed hash for this password and a set of
+ * passwords that could be supplied to the buggy algorithm.  Our safety measure
+ * is meant to protect from such many-buggy to one-correct collisions, by
+ * deviating from the correct algorithm in such cases.  Let's check for this.
+ */
+	diff |= diff >> 16; /* still zero iff exact match */
+	diff &= 0xffff; /* ditto */
+	diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */
+	sign <<= 9; /* move the non-benign sign extension flag to bit 16 */
+	sign &= ~diff & safety; /* action needed? */
+
+/*
+ * If we have determined that we need to deviate from the correct algorithm,
+ * flip bit 16 in initial expanded key.  (The choice of 16 is arbitrary, but
+ * let's stick to it now.  It came out of the approach we used above, and it's
+ * not any worse than any other choice we could make.)
+ *
+ * It is crucial that we don't do the same to the expanded key used in the main
+ * Eksblowfish loop.  By doing it to only one of these two, we deviate from a
+ * state that could be directly specified by a password to the buggy algorithm
+ * (and to the fully correct one as well, but that's a side-effect).
+ */
+	initial[0] ^= sign;
+}
+
+static char *BF_crypt(const char *key, const char *setting,
+	char *output, BF_word min)
+{
+	static const unsigned char flags_by_subtype[26] =
+		{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0};
+	struct {
+		BF_ctx ctx;
+		BF_key expanded_key;
+		union {
+			BF_word salt[4];
+			BF_word output[6];
+		} binary;
+	} data;
+	BF_word count;
+	int i;
+
+	if (setting[0] != '$' ||
+	    setting[1] != '2' ||
+	    setting[2] - 'a' > 25U ||
+	    !flags_by_subtype[setting[2] - 'a'] ||
+	    setting[3] != '$' ||
+	    setting[4] - '0' > 1U ||
+	    setting[5] - '0' > 9U ||
+	    setting[6] != '$') {
+		return NULL;
+	}
+
+	count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
+	if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) {
+		return NULL;
+	}
+	BF_swap(data.binary.salt, 4);
+
+	BF_set_key(key, data.expanded_key, data.ctx.s.P,
+	    flags_by_subtype[setting[2] - 'a']);
+
+	memcpy(data.ctx.s.S, BF_init_state.s.S, sizeof(data.ctx.s.S));
+
+	{
+		BF_word L = 0, R = 0;
+		BF_word *ptr = &data.ctx.PS[0];
+		do {
+			L = BF_encrypt(&data.ctx,
+			    L ^ data.binary.salt[0], R ^ data.binary.salt[1],
+			    ptr, ptr);
+			R = *(ptr + 1);
+			ptr += 2;
+
+			if (ptr >= &data.ctx.PS[BF_N + 2 + 4 * 0x100])
+				break;
+
+			L = BF_encrypt(&data.ctx,
+			    L ^ data.binary.salt[2], R ^ data.binary.salt[3],
+			    ptr, ptr);
+			R = *(ptr + 1);
+			ptr += 2;
+		} while (1);
+	}
+
+	do {
+		int done;
+
+		for (i = 0; i < BF_N + 2; i += 2) {
+			data.ctx.s.P[i] ^= data.expanded_key[i];
+			data.ctx.s.P[i + 1] ^= data.expanded_key[i + 1];
+		}
+
+		done = 0;
+		do {
+			BF_encrypt(&data.ctx, 0, 0,
+			    &data.ctx.PS[0],
+			    &data.ctx.PS[BF_N + 2 + 4 * 0x100]);
+
+			if (done)
+				break;
+			done = 1;
+
+			{
+				BF_word tmp1, tmp2, tmp3, tmp4;
+
+				tmp1 = data.binary.salt[0];
+				tmp2 = data.binary.salt[1];
+				tmp3 = data.binary.salt[2];
+				tmp4 = data.binary.salt[3];
+				for (i = 0; i < BF_N; i += 4) {
+					data.ctx.s.P[i] ^= tmp1;
+					data.ctx.s.P[i + 1] ^= tmp2;
+					data.ctx.s.P[i + 2] ^= tmp3;
+					data.ctx.s.P[i + 3] ^= tmp4;
+				}
+				data.ctx.s.P[16] ^= tmp1;
+				data.ctx.s.P[17] ^= tmp2;
+			}
+		} while (1);
+	} while (--count);
+
+	for (i = 0; i < 6; i += 2) {
+		BF_word L, LR[2];
+
+		L = BF_magic_w[i];
+		LR[1] = BF_magic_w[i + 1];
+
+		count = 64;
+		do {
+			L = BF_encrypt(&data.ctx, L, LR[1],
+			    &LR[0], &LR[0]);
+		} while (--count);
+
+		data.binary.output[i] = L;
+		data.binary.output[i + 1] = LR[1];
+	}
+
+	memcpy(output, setting, 7 + 22 - 1);
+	output[7 + 22 - 1] = BF_itoa64[
+		BF_atoi64[setting[7 + 22 - 1] - 0x20] & 0x30];
+
+/* This has to be bug-compatible with the original implementation, so
+ * only encode 23 of the 24 bytes. :-) */
+	BF_swap(data.binary.output, 6);
+	BF_encode(&output[7 + 22], data.binary.output, 23);
+	output[7 + 22 + 31] = '\0';
+
+	return output;
+}
+
+/*
+ * Please preserve the runtime self-test.  It serves two purposes at once:
+ *
+ * 1. We really can't afford the risk of producing incompatible hashes e.g.
+ * when there's something like gcc bug 26587 again, whereas an application or
+ * library integrating this code might not also integrate our external tests or
+ * it might not run them after every build.  Even if it does, the miscompile
+ * might only occur on the production build, but not on a testing build (such
+ * as because of different optimization settings).  It is painful to recover
+ * from incorrectly-computed hashes - merely fixing whatever broke is not
+ * enough.  Thus, a proactive measure like this self-test is needed.
+ *
+ * 2. We don't want to leave sensitive data from our actual password hash
+ * computation on the stack or in registers.  Previous revisions of the code
+ * would do explicit cleanups, but simply running the self-test after hash
+ * computation is more reliable.
+ *
+ * The performance cost of this quick self-test is around 0.6% at the "$2a$08"
+ * setting.
+ */
+char *__crypt_blowfish(const char *key, const char *setting, char *output)
+{
+	const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
+	const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu";
+	static const char test_hash[2][34] =
+		{"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* $2x$ */
+		"i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55"}; /* $2a$, $2y$ */
+	char *retval;
+	const char *p;
+	int ok;
+	struct {
+		char s[7 + 22 + 1];
+		char o[7 + 22 + 31 + 1 + 1 + 1];
+	} buf;
+
+/* Hash the supplied password */
+	retval = BF_crypt(key, setting, output, 16);
+
+/*
+ * Do a quick self-test.  It is important that we make both calls to BF_crypt()
+ * from the same scope such that they likely use the same stack locations,
+ * which makes the second call overwrite the first call's sensitive data on the
+ * stack and makes it more likely that any alignment related issues would be
+ * detected by the self-test.
+ */
+	memcpy(buf.s, test_setting, sizeof(buf.s));
+	if (retval)
+		buf.s[2] = setting[2];
+	memset(buf.o, 0x55, sizeof(buf.o));
+	buf.o[sizeof(buf.o) - 1] = 0;
+	p = BF_crypt(test_key, buf.s, buf.o, 1);
+
+	ok = (p == buf.o &&
+	    !memcmp(p, buf.s, 7 + 22) &&
+	    !memcmp(p + (7 + 22),
+	    test_hash[buf.s[2] & 1],
+	    31 + 1 + 1 + 1));
+
+	{
+		const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345";
+		BF_key ae, ai, ye, yi;
+		BF_set_key(k, ae, ai, 2); /* $2a$ */
+		BF_set_key(k, ye, yi, 4); /* $2y$ */
+		ai[0] ^= 0x10000; /* undo the safety (for comparison) */
+		ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 &&
+		    !memcmp(ae, ye, sizeof(ae)) &&
+		    !memcmp(ai, yi, sizeof(ai));
+	}
+
+	if (ok && retval)
+		return retval;
+
+	return "*";
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_des.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_des.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_des.c	(revision 398)
@@ -0,0 +1,1018 @@
+/*
+ * This version has been further modified by Rich Felker, primary author
+ * and maintainer of musl libc, to remove table generation code and
+ * replaced all runtime-generated constant tables with static-initialized
+ * tables in the binary, in the interest of minimizing non-shareable
+ * memory usage and stack size requirements.
+ */
+/*
+ * This version is derived from the original implementation of FreeSec
+ * (release 1.1) by David Burren.  I've made it reentrant, reduced its memory
+ * usage from about 70 KB to about 7 KB (with only minimal performance impact
+ * and keeping code size about the same), made the handling of invalid salts
+ * mostly UFC-crypt compatible, added a quick runtime self-test (which also
+ * serves to zeroize the stack from sensitive data), and added optional tests.
+ * - Solar Designer <solar at openwall.com>
+ */
+
+/*
+ * FreeSec: libcrypt for NetBSD
+ *
+ * Copyright (c) 1994 David Burren
+ * Copyright (c) 2000,2002,2010,2012 Solar Designer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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 author nor the names of other contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ *	$Owl: Owl/packages/glibc/crypt_freesec.c,v 1.6 2010/02/20 14:45:06 solar Exp $
+ *	$Id$
+ *
+ * This is an original implementation of the DES and the crypt(3) interfaces
+ * by David Burren.  It has been heavily re-worked by Solar Designer.
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+struct expanded_key {
+	uint32_t l[16], r[16];
+};
+
+#define _PASSWORD_EFMT1 '_'
+
+static const unsigned char key_shifts[16] = {
+	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+static const uint32_t psbox[8][64] = {
+	{
+		0x00808200,0x00000000,0x00008000,0x00808202,
+		0x00808002,0x00008202,0x00000002,0x00008000,
+		0x00000200,0x00808200,0x00808202,0x00000200,
+		0x00800202,0x00808002,0x00800000,0x00000002,
+		0x00000202,0x00800200,0x00800200,0x00008200,
+		0x00008200,0x00808000,0x00808000,0x00800202,
+		0x00008002,0x00800002,0x00800002,0x00008002,
+		0x00000000,0x00000202,0x00008202,0x00800000,
+		0x00008000,0x00808202,0x00000002,0x00808000,
+		0x00808200,0x00800000,0x00800000,0x00000200,
+		0x00808002,0x00008000,0x00008200,0x00800002,
+		0x00000200,0x00000002,0x00800202,0x00008202,
+		0x00808202,0x00008002,0x00808000,0x00800202,
+		0x00800002,0x00000202,0x00008202,0x00808200,
+		0x00000202,0x00800200,0x00800200,0x00000000,
+		0x00008002,0x00008200,0x00000000,0x00808002,
+	},{
+		0x40084010,0x40004000,0x00004000,0x00084010,
+		0x00080000,0x00000010,0x40080010,0x40004010,
+		0x40000010,0x40084010,0x40084000,0x40000000,
+		0x40004000,0x00080000,0x00000010,0x40080010,
+		0x00084000,0x00080010,0x40004010,0x00000000,
+		0x40000000,0x00004000,0x00084010,0x40080000,
+		0x00080010,0x40000010,0x00000000,0x00084000,
+		0x00004010,0x40084000,0x40080000,0x00004010,
+		0x00000000,0x00084010,0x40080010,0x00080000,
+		0x40004010,0x40080000,0x40084000,0x00004000,
+		0x40080000,0x40004000,0x00000010,0x40084010,
+		0x00084010,0x00000010,0x00004000,0x40000000,
+		0x00004010,0x40084000,0x00080000,0x40000010,
+		0x00080010,0x40004010,0x40000010,0x00080010,
+		0x00084000,0x00000000,0x40004000,0x00004010,
+		0x40000000,0x40080010,0x40084010,0x00084000,
+	},{
+		0x00000104,0x04010100,0x00000000,0x04010004,
+		0x04000100,0x00000000,0x00010104,0x04000100,
+		0x00010004,0x04000004,0x04000004,0x00010000,
+		0x04010104,0x00010004,0x04010000,0x00000104,
+		0x04000000,0x00000004,0x04010100,0x00000100,
+		0x00010100,0x04010000,0x04010004,0x00010104,
+		0x04000104,0x00010100,0x00010000,0x04000104,
+		0x00000004,0x04010104,0x00000100,0x04000000,
+		0x04010100,0x04000000,0x00010004,0x00000104,
+		0x00010000,0x04010100,0x04000100,0x00000000,
+		0x00000100,0x00010004,0x04010104,0x04000100,
+		0x04000004,0x00000100,0x00000000,0x04010004,
+		0x04000104,0x00010000,0x04000000,0x04010104,
+		0x00000004,0x00010104,0x00010100,0x04000004,
+		0x04010000,0x04000104,0x00000104,0x04010000,
+		0x00010104,0x00000004,0x04010004,0x00010100,
+	},{
+		0x80401000,0x80001040,0x80001040,0x00000040,
+		0x00401040,0x80400040,0x80400000,0x80001000,
+		0x00000000,0x00401000,0x00401000,0x80401040,
+		0x80000040,0x00000000,0x00400040,0x80400000,
+		0x80000000,0x00001000,0x00400000,0x80401000,
+		0x00000040,0x00400000,0x80001000,0x00001040,
+		0x80400040,0x80000000,0x00001040,0x00400040,
+		0x00001000,0x00401040,0x80401040,0x80000040,
+		0x00400040,0x80400000,0x00401000,0x80401040,
+		0x80000040,0x00000000,0x00000000,0x00401000,
+		0x00001040,0x00400040,0x80400040,0x80000000,
+		0x80401000,0x80001040,0x80001040,0x00000040,
+		0x80401040,0x80000040,0x80000000,0x00001000,
+		0x80400000,0x80001000,0x00401040,0x80400040,
+		0x80001000,0x00001040,0x00400000,0x80401000,
+		0x00000040,0x00400000,0x00001000,0x00401040,
+	},{
+		0x00000080,0x01040080,0x01040000,0x21000080,
+		0x00040000,0x00000080,0x20000000,0x01040000,
+		0x20040080,0x00040000,0x01000080,0x20040080,
+		0x21000080,0x21040000,0x00040080,0x20000000,
+		0x01000000,0x20040000,0x20040000,0x00000000,
+		0x20000080,0x21040080,0x21040080,0x01000080,
+		0x21040000,0x20000080,0x00000000,0x21000000,
+		0x01040080,0x01000000,0x21000000,0x00040080,
+		0x00040000,0x21000080,0x00000080,0x01000000,
+		0x20000000,0x01040000,0x21000080,0x20040080,
+		0x01000080,0x20000000,0x21040000,0x01040080,
+		0x20040080,0x00000080,0x01000000,0x21040000,
+		0x21040080,0x00040080,0x21000000,0x21040080,
+		0x01040000,0x00000000,0x20040000,0x21000000,
+		0x00040080,0x01000080,0x20000080,0x00040000,
+		0x00000000,0x20040000,0x01040080,0x20000080,
+	},{
+		0x10000008,0x10200000,0x00002000,0x10202008,
+		0x10200000,0x00000008,0x10202008,0x00200000,
+		0x10002000,0x00202008,0x00200000,0x10000008,
+		0x00200008,0x10002000,0x10000000,0x00002008,
+		0x00000000,0x00200008,0x10002008,0x00002000,
+		0x00202000,0x10002008,0x00000008,0x10200008,
+		0x10200008,0x00000000,0x00202008,0x10202000,
+		0x00002008,0x00202000,0x10202000,0x10000000,
+		0x10002000,0x00000008,0x10200008,0x00202000,
+		0x10202008,0x00200000,0x00002008,0x10000008,
+		0x00200000,0x10002000,0x10000000,0x00002008,
+		0x10000008,0x10202008,0x00202000,0x10200000,
+		0x00202008,0x10202000,0x00000000,0x10200008,
+		0x00000008,0x00002000,0x10200000,0x00202008,
+		0x00002000,0x00200008,0x10002008,0x00000000,
+		0x10202000,0x10000000,0x00200008,0x10002008,
+	},{
+		0x00100000,0x02100001,0x02000401,0x00000000,
+		0x00000400,0x02000401,0x00100401,0x02100400,
+		0x02100401,0x00100000,0x00000000,0x02000001,
+		0x00000001,0x02000000,0x02100001,0x00000401,
+		0x02000400,0x00100401,0x00100001,0x02000400,
+		0x02000001,0x02100000,0x02100400,0x00100001,
+		0x02100000,0x00000400,0x00000401,0x02100401,
+		0x00100400,0x00000001,0x02000000,0x00100400,
+		0x02000000,0x00100400,0x00100000,0x02000401,
+		0x02000401,0x02100001,0x02100001,0x00000001,
+		0x00100001,0x02000000,0x02000400,0x00100000,
+		0x02100400,0x00000401,0x00100401,0x02100400,
+		0x00000401,0x02000001,0x02100401,0x02100000,
+		0x00100400,0x00000000,0x00000001,0x02100401,
+		0x00000000,0x00100401,0x02100000,0x00000400,
+		0x02000001,0x02000400,0x00000400,0x00100001,
+	},{
+		0x08000820,0x00000800,0x00020000,0x08020820,
+		0x08000000,0x08000820,0x00000020,0x08000000,
+		0x00020020,0x08020000,0x08020820,0x00020800,
+		0x08020800,0x00020820,0x00000800,0x00000020,
+		0x08020000,0x08000020,0x08000800,0x00000820,
+		0x00020800,0x00020020,0x08020020,0x08020800,
+		0x00000820,0x00000000,0x00000000,0x08020020,
+		0x08000020,0x08000800,0x00020820,0x00020000,
+		0x00020820,0x00020000,0x08020800,0x00000800,
+		0x00000020,0x08020020,0x00000800,0x00020820,
+		0x08000800,0x00000020,0x08000020,0x08020000,
+		0x08020020,0x08000000,0x00020000,0x08000820,
+		0x00000000,0x08020820,0x00020020,0x08000020,
+		0x08020000,0x08000800,0x08000820,0x00000000,
+		0x08020820,0x00020800,0x00020800,0x00000820,
+		0x00000820,0x00020020,0x08000000,0x08020800,
+	},
+};
+static const uint32_t ip_maskl[16][16] = {
+	{
+		0x00000000,0x00010000,0x00000000,0x00010000,
+		0x01000000,0x01010000,0x01000000,0x01010000,
+		0x00000000,0x00010000,0x00000000,0x00010000,
+		0x01000000,0x01010000,0x01000000,0x01010000,
+	},{
+		0x00000000,0x00000001,0x00000000,0x00000001,
+		0x00000100,0x00000101,0x00000100,0x00000101,
+		0x00000000,0x00000001,0x00000000,0x00000001,
+		0x00000100,0x00000101,0x00000100,0x00000101,
+	},{
+		0x00000000,0x00020000,0x00000000,0x00020000,
+		0x02000000,0x02020000,0x02000000,0x02020000,
+		0x00000000,0x00020000,0x00000000,0x00020000,
+		0x02000000,0x02020000,0x02000000,0x02020000,
+	},{
+		0x00000000,0x00000002,0x00000000,0x00000002,
+		0x00000200,0x00000202,0x00000200,0x00000202,
+		0x00000000,0x00000002,0x00000000,0x00000002,
+		0x00000200,0x00000202,0x00000200,0x00000202,
+	},{
+		0x00000000,0x00040000,0x00000000,0x00040000,
+		0x04000000,0x04040000,0x04000000,0x04040000,
+		0x00000000,0x00040000,0x00000000,0x00040000,
+		0x04000000,0x04040000,0x04000000,0x04040000,
+	},{
+		0x00000000,0x00000004,0x00000000,0x00000004,
+		0x00000400,0x00000404,0x00000400,0x00000404,
+		0x00000000,0x00000004,0x00000000,0x00000004,
+		0x00000400,0x00000404,0x00000400,0x00000404,
+	},{
+		0x00000000,0x00080000,0x00000000,0x00080000,
+		0x08000000,0x08080000,0x08000000,0x08080000,
+		0x00000000,0x00080000,0x00000000,0x00080000,
+		0x08000000,0x08080000,0x08000000,0x08080000,
+	},{
+		0x00000000,0x00000008,0x00000000,0x00000008,
+		0x00000800,0x00000808,0x00000800,0x00000808,
+		0x00000000,0x00000008,0x00000000,0x00000008,
+		0x00000800,0x00000808,0x00000800,0x00000808,
+	},{
+		0x00000000,0x00100000,0x00000000,0x00100000,
+		0x10000000,0x10100000,0x10000000,0x10100000,
+		0x00000000,0x00100000,0x00000000,0x00100000,
+		0x10000000,0x10100000,0x10000000,0x10100000,
+	},{
+		0x00000000,0x00000010,0x00000000,0x00000010,
+		0x00001000,0x00001010,0x00001000,0x00001010,
+		0x00000000,0x00000010,0x00000000,0x00000010,
+		0x00001000,0x00001010,0x00001000,0x00001010,
+	},{
+		0x00000000,0x00200000,0x00000000,0x00200000,
+		0x20000000,0x20200000,0x20000000,0x20200000,
+		0x00000000,0x00200000,0x00000000,0x00200000,
+		0x20000000,0x20200000,0x20000000,0x20200000,
+	},{
+		0x00000000,0x00000020,0x00000000,0x00000020,
+		0x00002000,0x00002020,0x00002000,0x00002020,
+		0x00000000,0x00000020,0x00000000,0x00000020,
+		0x00002000,0x00002020,0x00002000,0x00002020,
+	},{
+		0x00000000,0x00400000,0x00000000,0x00400000,
+		0x40000000,0x40400000,0x40000000,0x40400000,
+		0x00000000,0x00400000,0x00000000,0x00400000,
+		0x40000000,0x40400000,0x40000000,0x40400000,
+	},{
+		0x00000000,0x00000040,0x00000000,0x00000040,
+		0x00004000,0x00004040,0x00004000,0x00004040,
+		0x00000000,0x00000040,0x00000000,0x00000040,
+		0x00004000,0x00004040,0x00004000,0x00004040,
+	},{
+		0x00000000,0x00800000,0x00000000,0x00800000,
+		0x80000000,0x80800000,0x80000000,0x80800000,
+		0x00000000,0x00800000,0x00000000,0x00800000,
+		0x80000000,0x80800000,0x80000000,0x80800000,
+	},{
+		0x00000000,0x00000080,0x00000000,0x00000080,
+		0x00008000,0x00008080,0x00008000,0x00008080,
+		0x00000000,0x00000080,0x00000000,0x00000080,
+		0x00008000,0x00008080,0x00008000,0x00008080,
+	},
+};
+static const uint32_t ip_maskr[16][16] = {
+	{
+		0x00000000,0x00000000,0x00010000,0x00010000,
+		0x00000000,0x00000000,0x00010000,0x00010000,
+		0x01000000,0x01000000,0x01010000,0x01010000,
+		0x01000000,0x01000000,0x01010000,0x01010000,
+	},{
+		0x00000000,0x00000000,0x00000001,0x00000001,
+		0x00000000,0x00000000,0x00000001,0x00000001,
+		0x00000100,0x00000100,0x00000101,0x00000101,
+		0x00000100,0x00000100,0x00000101,0x00000101,
+	},{
+		0x00000000,0x00000000,0x00020000,0x00020000,
+		0x00000000,0x00000000,0x00020000,0x00020000,
+		0x02000000,0x02000000,0x02020000,0x02020000,
+		0x02000000,0x02000000,0x02020000,0x02020000,
+	},{
+		0x00000000,0x00000000,0x00000002,0x00000002,
+		0x00000000,0x00000000,0x00000002,0x00000002,
+		0x00000200,0x00000200,0x00000202,0x00000202,
+		0x00000200,0x00000200,0x00000202,0x00000202,
+	},{
+		0x00000000,0x00000000,0x00040000,0x00040000,
+		0x00000000,0x00000000,0x00040000,0x00040000,
+		0x04000000,0x04000000,0x04040000,0x04040000,
+		0x04000000,0x04000000,0x04040000,0x04040000,
+	},{
+		0x00000000,0x00000000,0x00000004,0x00000004,
+		0x00000000,0x00000000,0x00000004,0x00000004,
+		0x00000400,0x00000400,0x00000404,0x00000404,
+		0x00000400,0x00000400,0x00000404,0x00000404,
+	},{
+		0x00000000,0x00000000,0x00080000,0x00080000,
+		0x00000000,0x00000000,0x00080000,0x00080000,
+		0x08000000,0x08000000,0x08080000,0x08080000,
+		0x08000000,0x08000000,0x08080000,0x08080000,
+	},{
+		0x00000000,0x00000000,0x00000008,0x00000008,
+		0x00000000,0x00000000,0x00000008,0x00000008,
+		0x00000800,0x00000800,0x00000808,0x00000808,
+		0x00000800,0x00000800,0x00000808,0x00000808,
+	},{
+		0x00000000,0x00000000,0x00100000,0x00100000,
+		0x00000000,0x00000000,0x00100000,0x00100000,
+		0x10000000,0x10000000,0x10100000,0x10100000,
+		0x10000000,0x10000000,0x10100000,0x10100000,
+	},{
+		0x00000000,0x00000000,0x00000010,0x00000010,
+		0x00000000,0x00000000,0x00000010,0x00000010,
+		0x00001000,0x00001000,0x00001010,0x00001010,
+		0x00001000,0x00001000,0x00001010,0x00001010,
+	},{
+		0x00000000,0x00000000,0x00200000,0x00200000,
+		0x00000000,0x00000000,0x00200000,0x00200000,
+		0x20000000,0x20000000,0x20200000,0x20200000,
+		0x20000000,0x20000000,0x20200000,0x20200000,
+	},{
+		0x00000000,0x00000000,0x00000020,0x00000020,
+		0x00000000,0x00000000,0x00000020,0x00000020,
+		0x00002000,0x00002000,0x00002020,0x00002020,
+		0x00002000,0x00002000,0x00002020,0x00002020,
+	},{
+		0x00000000,0x00000000,0x00400000,0x00400000,
+		0x00000000,0x00000000,0x00400000,0x00400000,
+		0x40000000,0x40000000,0x40400000,0x40400000,
+		0x40000000,0x40000000,0x40400000,0x40400000,
+	},{
+		0x00000000,0x00000000,0x00000040,0x00000040,
+		0x00000000,0x00000000,0x00000040,0x00000040,
+		0x00004000,0x00004000,0x00004040,0x00004040,
+		0x00004000,0x00004000,0x00004040,0x00004040,
+	},{
+		0x00000000,0x00000000,0x00800000,0x00800000,
+		0x00000000,0x00000000,0x00800000,0x00800000,
+		0x80000000,0x80000000,0x80800000,0x80800000,
+		0x80000000,0x80000000,0x80800000,0x80800000,
+	},{
+		0x00000000,0x00000000,0x00000080,0x00000080,
+		0x00000000,0x00000000,0x00000080,0x00000080,
+		0x00008000,0x00008000,0x00008080,0x00008080,
+		0x00008000,0x00008000,0x00008080,0x00008080,
+	},
+};
+static const uint32_t fp_maskl[8][16] = {
+	{
+		0x00000000,0x40000000,0x00400000,0x40400000,
+		0x00004000,0x40004000,0x00404000,0x40404000,
+		0x00000040,0x40000040,0x00400040,0x40400040,
+		0x00004040,0x40004040,0x00404040,0x40404040,
+	},{
+		0x00000000,0x10000000,0x00100000,0x10100000,
+		0x00001000,0x10001000,0x00101000,0x10101000,
+		0x00000010,0x10000010,0x00100010,0x10100010,
+		0x00001010,0x10001010,0x00101010,0x10101010,
+	},{
+		0x00000000,0x04000000,0x00040000,0x04040000,
+		0x00000400,0x04000400,0x00040400,0x04040400,
+		0x00000004,0x04000004,0x00040004,0x04040004,
+		0x00000404,0x04000404,0x00040404,0x04040404,
+	},{
+		0x00000000,0x01000000,0x00010000,0x01010000,
+		0x00000100,0x01000100,0x00010100,0x01010100,
+		0x00000001,0x01000001,0x00010001,0x01010001,
+		0x00000101,0x01000101,0x00010101,0x01010101,
+	},{
+		0x00000000,0x80000000,0x00800000,0x80800000,
+		0x00008000,0x80008000,0x00808000,0x80808000,
+		0x00000080,0x80000080,0x00800080,0x80800080,
+		0x00008080,0x80008080,0x00808080,0x80808080,
+	},{
+		0x00000000,0x20000000,0x00200000,0x20200000,
+		0x00002000,0x20002000,0x00202000,0x20202000,
+		0x00000020,0x20000020,0x00200020,0x20200020,
+		0x00002020,0x20002020,0x00202020,0x20202020,
+	},{
+		0x00000000,0x08000000,0x00080000,0x08080000,
+		0x00000800,0x08000800,0x00080800,0x08080800,
+		0x00000008,0x08000008,0x00080008,0x08080008,
+		0x00000808,0x08000808,0x00080808,0x08080808,
+	},{
+		0x00000000,0x02000000,0x00020000,0x02020000,
+		0x00000200,0x02000200,0x00020200,0x02020200,
+		0x00000002,0x02000002,0x00020002,0x02020002,
+		0x00000202,0x02000202,0x00020202,0x02020202,
+	},
+};
+static const uint32_t fp_maskr[8][16] = {
+	{
+		0x00000000,0x40000000,0x00400000,0x40400000,
+		0x00004000,0x40004000,0x00404000,0x40404000,
+		0x00000040,0x40000040,0x00400040,0x40400040,
+		0x00004040,0x40004040,0x00404040,0x40404040,
+	},{
+		0x00000000,0x10000000,0x00100000,0x10100000,
+		0x00001000,0x10001000,0x00101000,0x10101000,
+		0x00000010,0x10000010,0x00100010,0x10100010,
+		0x00001010,0x10001010,0x00101010,0x10101010,
+	},{
+		0x00000000,0x04000000,0x00040000,0x04040000,
+		0x00000400,0x04000400,0x00040400,0x04040400,
+		0x00000004,0x04000004,0x00040004,0x04040004,
+		0x00000404,0x04000404,0x00040404,0x04040404,
+	},{
+		0x00000000,0x01000000,0x00010000,0x01010000,
+		0x00000100,0x01000100,0x00010100,0x01010100,
+		0x00000001,0x01000001,0x00010001,0x01010001,
+		0x00000101,0x01000101,0x00010101,0x01010101,
+	},{
+		0x00000000,0x80000000,0x00800000,0x80800000,
+		0x00008000,0x80008000,0x00808000,0x80808000,
+		0x00000080,0x80000080,0x00800080,0x80800080,
+		0x00008080,0x80008080,0x00808080,0x80808080,
+	},{
+		0x00000000,0x20000000,0x00200000,0x20200000,
+		0x00002000,0x20002000,0x00202000,0x20202000,
+		0x00000020,0x20000020,0x00200020,0x20200020,
+		0x00002020,0x20002020,0x00202020,0x20202020,
+	},{
+		0x00000000,0x08000000,0x00080000,0x08080000,
+		0x00000800,0x08000800,0x00080800,0x08080800,
+		0x00000008,0x08000008,0x00080008,0x08080008,
+		0x00000808,0x08000808,0x00080808,0x08080808,
+	},{
+		0x00000000,0x02000000,0x00020000,0x02020000,
+		0x00000200,0x02000200,0x00020200,0x02020200,
+		0x00000002,0x02000002,0x00020002,0x02020002,
+		0x00000202,0x02000202,0x00020202,0x02020202,
+	},
+};
+static const uint32_t key_perm_maskl[8][16] = {
+	{
+		0x00000000,0x00000000,0x00000010,0x00000010,
+		0x00001000,0x00001000,0x00001010,0x00001010,
+		0x00100000,0x00100000,0x00100010,0x00100010,
+		0x00101000,0x00101000,0x00101010,0x00101010,
+	},{
+		0x00000000,0x00000000,0x00000020,0x00000020,
+		0x00002000,0x00002000,0x00002020,0x00002020,
+		0x00200000,0x00200000,0x00200020,0x00200020,
+		0x00202000,0x00202000,0x00202020,0x00202020,
+	},{
+		0x00000000,0x00000000,0x00000040,0x00000040,
+		0x00004000,0x00004000,0x00004040,0x00004040,
+		0x00400000,0x00400000,0x00400040,0x00400040,
+		0x00404000,0x00404000,0x00404040,0x00404040,
+	},{
+		0x00000000,0x00000000,0x00000080,0x00000080,
+		0x00008000,0x00008000,0x00008080,0x00008080,
+		0x00800000,0x00800000,0x00800080,0x00800080,
+		0x00808000,0x00808000,0x00808080,0x00808080,
+	},{
+		0x00000000,0x00000001,0x00000100,0x00000101,
+		0x00010000,0x00010001,0x00010100,0x00010101,
+		0x01000000,0x01000001,0x01000100,0x01000101,
+		0x01010000,0x01010001,0x01010100,0x01010101,
+	},{
+		0x00000000,0x00000002,0x00000200,0x00000202,
+		0x00020000,0x00020002,0x00020200,0x00020202,
+		0x02000000,0x02000002,0x02000200,0x02000202,
+		0x02020000,0x02020002,0x02020200,0x02020202,
+	},{
+		0x00000000,0x00000004,0x00000400,0x00000404,
+		0x00040000,0x00040004,0x00040400,0x00040404,
+		0x04000000,0x04000004,0x04000400,0x04000404,
+		0x04040000,0x04040004,0x04040400,0x04040404,
+	},{
+		0x00000000,0x00000008,0x00000800,0x00000808,
+		0x00080000,0x00080008,0x00080800,0x00080808,
+		0x08000000,0x08000008,0x08000800,0x08000808,
+		0x08080000,0x08080008,0x08080800,0x08080808,
+	},
+};
+static const uint32_t key_perm_maskr[12][16] = {
+	{
+		0x00000000,0x00000001,0x00000000,0x00000001,
+		0x00000000,0x00000001,0x00000000,0x00000001,
+		0x00000000,0x00000001,0x00000000,0x00000001,
+		0x00000000,0x00000001,0x00000000,0x00000001,
+	},{
+		0x00000000,0x00000000,0x00100000,0x00100000,
+		0x00001000,0x00001000,0x00101000,0x00101000,
+		0x00000010,0x00000010,0x00100010,0x00100010,
+		0x00001010,0x00001010,0x00101010,0x00101010,
+	},{
+		0x00000000,0x00000002,0x00000000,0x00000002,
+		0x00000000,0x00000002,0x00000000,0x00000002,
+		0x00000000,0x00000002,0x00000000,0x00000002,
+		0x00000000,0x00000002,0x00000000,0x00000002,
+	},{
+		0x00000000,0x00000000,0x00200000,0x00200000,
+		0x00002000,0x00002000,0x00202000,0x00202000,
+		0x00000020,0x00000020,0x00200020,0x00200020,
+		0x00002020,0x00002020,0x00202020,0x00202020,
+	},{
+		0x00000000,0x00000004,0x00000000,0x00000004,
+		0x00000000,0x00000004,0x00000000,0x00000004,
+		0x00000000,0x00000004,0x00000000,0x00000004,
+		0x00000000,0x00000004,0x00000000,0x00000004,
+	},{
+		0x00000000,0x00000000,0x00400000,0x00400000,
+		0x00004000,0x00004000,0x00404000,0x00404000,
+		0x00000040,0x00000040,0x00400040,0x00400040,
+		0x00004040,0x00004040,0x00404040,0x00404040,
+	},{
+		0x00000000,0x00000008,0x00000000,0x00000008,
+		0x00000000,0x00000008,0x00000000,0x00000008,
+		0x00000000,0x00000008,0x00000000,0x00000008,
+		0x00000000,0x00000008,0x00000000,0x00000008,
+	},{
+		0x00000000,0x00000000,0x00800000,0x00800000,
+		0x00008000,0x00008000,0x00808000,0x00808000,
+		0x00000080,0x00000080,0x00800080,0x00800080,
+		0x00008080,0x00008080,0x00808080,0x00808080,
+	},{
+		0x00000000,0x00000000,0x01000000,0x01000000,
+		0x00010000,0x00010000,0x01010000,0x01010000,
+		0x00000100,0x00000100,0x01000100,0x01000100,
+		0x00010100,0x00010100,0x01010100,0x01010100,
+	},{
+		0x00000000,0x00000000,0x02000000,0x02000000,
+		0x00020000,0x00020000,0x02020000,0x02020000,
+		0x00000200,0x00000200,0x02000200,0x02000200,
+		0x00020200,0x00020200,0x02020200,0x02020200,
+	},{
+		0x00000000,0x00000000,0x04000000,0x04000000,
+		0x00040000,0x00040000,0x04040000,0x04040000,
+		0x00000400,0x00000400,0x04000400,0x04000400,
+		0x00040400,0x00040400,0x04040400,0x04040400,
+	},{
+		0x00000000,0x00000000,0x08000000,0x08000000,
+		0x00080000,0x00080000,0x08080000,0x08080000,
+		0x00000800,0x00000800,0x08000800,0x08000800,
+		0x00080800,0x00080800,0x08080800,0x08080800,
+	},
+};
+static const uint32_t comp_maskl0[4][8] = {
+	{
+		0x00000000,0x00020000,0x00000001,0x00020001,
+		0x00080000,0x000a0000,0x00080001,0x000a0001,
+	},{
+		0x00000000,0x00001000,0x00000000,0x00001000,
+		0x00000040,0x00001040,0x00000040,0x00001040,
+	},{
+		0x00000000,0x00400000,0x00000020,0x00400020,
+		0x00008000,0x00408000,0x00008020,0x00408020,
+	},{
+		0x00000000,0x00100000,0x00000800,0x00100800,
+		0x00000000,0x00100000,0x00000800,0x00100800,
+	},
+};
+static const uint32_t comp_maskr0[4][8] = {
+	{
+		0x00000000,0x00200000,0x00020000,0x00220000,
+		0x00000002,0x00200002,0x00020002,0x00220002,
+	},{
+		0x00000000,0x00000000,0x00100000,0x00100000,
+		0x00000004,0x00000004,0x00100004,0x00100004,
+	},{
+		0x00000000,0x00004000,0x00000800,0x00004800,
+		0x00000000,0x00004000,0x00000800,0x00004800,
+	},{
+		0x00000000,0x00400000,0x00008000,0x00408000,
+		0x00000008,0x00400008,0x00008008,0x00408008,
+	},
+};
+static const uint32_t comp_maskl1[4][16] = {
+	{
+		0x00000000,0x00000010,0x00004000,0x00004010,
+		0x00040000,0x00040010,0x00044000,0x00044010,
+		0x00000100,0x00000110,0x00004100,0x00004110,
+		0x00040100,0x00040110,0x00044100,0x00044110,
+	},{
+		0x00000000,0x00800000,0x00000002,0x00800002,
+		0x00000200,0x00800200,0x00000202,0x00800202,
+		0x00200000,0x00a00000,0x00200002,0x00a00002,
+		0x00200200,0x00a00200,0x00200202,0x00a00202,
+	},{
+		0x00000000,0x00002000,0x00000004,0x00002004,
+		0x00000400,0x00002400,0x00000404,0x00002404,
+		0x00000000,0x00002000,0x00000004,0x00002004,
+		0x00000400,0x00002400,0x00000404,0x00002404,
+	},{
+		0x00000000,0x00010000,0x00000008,0x00010008,
+		0x00000080,0x00010080,0x00000088,0x00010088,
+		0x00000000,0x00010000,0x00000008,0x00010008,
+		0x00000080,0x00010080,0x00000088,0x00010088,
+	},
+};
+static const uint32_t comp_maskr1[4][16] = {
+	{
+		0x00000000,0x00000000,0x00000080,0x00000080,
+		0x00002000,0x00002000,0x00002080,0x00002080,
+		0x00000001,0x00000001,0x00000081,0x00000081,
+		0x00002001,0x00002001,0x00002081,0x00002081,
+	},{
+		0x00000000,0x00000010,0x00800000,0x00800010,
+		0x00010000,0x00010010,0x00810000,0x00810010,
+		0x00000200,0x00000210,0x00800200,0x00800210,
+		0x00010200,0x00010210,0x00810200,0x00810210,
+	},{
+		0x00000000,0x00000400,0x00001000,0x00001400,
+		0x00080000,0x00080400,0x00081000,0x00081400,
+		0x00000020,0x00000420,0x00001020,0x00001420,
+		0x00080020,0x00080420,0x00081020,0x00081420,
+	},{
+		0x00000000,0x00000100,0x00040000,0x00040100,
+		0x00000000,0x00000100,0x00040000,0x00040100,
+		0x00000040,0x00000140,0x00040040,0x00040140,
+		0x00000040,0x00000140,0x00040040,0x00040140,
+	},
+};
+
+static const unsigned char ascii64[] =
+    "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+/*   0000000000111111111122222222223333333333444444444455555555556666 */
+/*   0123456789012345678901234567890123456789012345678901234567890123 */
+
+/*
+ * We match the behavior of UFC-crypt on systems where "char" is signed by
+ * default (the majority), regardless of char's signedness on our system.
+ */
+static uint32_t ascii_to_bin(int ch)
+{
+	int sch = (ch < 0x80) ? ch : -(0x100 - ch);
+	int retval;
+
+	retval = sch - '.';
+	if (sch >= 'A') {
+		retval = sch - ('A' - 12);
+		if (sch >= 'a')
+			retval = sch - ('a' - 38);
+	}
+	retval &= 0x3f;
+
+	return retval;
+}
+
+/*
+ * When we choose to "support" invalid salts, nevertheless disallow those
+ * containing characters that would violate the passwd file format.
+ */
+static inline int ascii_is_unsafe(unsigned char ch)
+{
+	return !ch || ch == '\n' || ch == ':';
+}
+
+static uint32_t setup_salt(uint32_t salt)
+{
+	uint32_t obit, saltbit, saltbits;
+	unsigned int i;
+
+	saltbits = 0;
+	saltbit = 1;
+	obit = 0x800000;
+	for (i = 0; i < 24; i++) {
+		if (salt & saltbit)
+			saltbits |= obit;
+		saltbit <<= 1;
+		obit >>= 1;
+	}
+
+	return saltbits;
+}
+
+void __des_setkey(const unsigned char *key, struct expanded_key *ekey)
+{
+	uint32_t k0, k1, rawkey0, rawkey1;
+	unsigned int shifts, round, i, ibit;
+
+	rawkey0 =
+	    (uint32_t)key[3] |
+	    ((uint32_t)key[2] << 8) |
+	    ((uint32_t)key[1] << 16) |
+	    ((uint32_t)key[0] << 24);
+	rawkey1 =
+	    (uint32_t)key[7] |
+	    ((uint32_t)key[6] << 8) |
+	    ((uint32_t)key[5] << 16) |
+	    ((uint32_t)key[4] << 24);
+
+	/*
+	 * Do key permutation and split into two 28-bit subkeys.
+	 */
+	k0 = k1 = 0;
+	for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) {
+		unsigned int j = i << 1;
+		k0 |= key_perm_maskl[i][(rawkey0 >> ibit) & 0xf] |
+		      key_perm_maskl[i + 4][(rawkey1 >> ibit) & 0xf];
+		k1 |= key_perm_maskr[j][(rawkey0 >> ibit) & 0xf];
+		ibit -= 4;
+		k1 |= key_perm_maskr[j + 1][(rawkey0 >> ibit) & 0xf] |
+		      key_perm_maskr[i + 8][(rawkey1 >> ibit) & 0xf];
+	}
+
+	/*
+	 * Rotate subkeys and do compression permutation.
+	 */
+	shifts = 0;
+	for (round = 0; round < 16; round++) {
+		uint32_t t0, t1;
+		uint32_t kl, kr;
+
+		shifts += key_shifts[round];
+
+		t0 = (k0 << shifts) | (k0 >> (28 - shifts));
+		t1 = (k1 << shifts) | (k1 >> (28 - shifts));
+
+		kl = kr = 0;
+		ibit = 25;
+		for (i = 0; i < 4; i++) {
+			kl |= comp_maskl0[i][(t0 >> ibit) & 7];
+			kr |= comp_maskr0[i][(t1 >> ibit) & 7];
+			ibit -= 4;
+			kl |= comp_maskl1[i][(t0 >> ibit) & 0xf];
+			kr |= comp_maskr1[i][(t1 >> ibit) & 0xf];
+			ibit -= 3;
+		}
+		ekey->l[round] = kl;
+		ekey->r[round] = kr;
+	}
+}
+
+/*
+ * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
+ */
+void __do_des(uint32_t l_in, uint32_t r_in,
+    uint32_t *l_out, uint32_t *r_out,
+    uint32_t count, uint32_t saltbits, const struct expanded_key *ekey)
+{
+	uint32_t l, r;
+
+	/*
+	 * Do initial permutation (IP).
+	 */
+	l = r = 0;
+	if (l_in | r_in) {
+		unsigned int i, ibit;
+		for (i = 0, ibit = 28; i < 8; i++, ibit -= 4) {
+			l |= ip_maskl[i][(l_in >> ibit) & 0xf] |
+			     ip_maskl[i + 8][(r_in >> ibit) & 0xf];
+			r |= ip_maskr[i][(l_in >> ibit) & 0xf] |
+			     ip_maskr[i + 8][(r_in >> ibit) & 0xf];
+		}
+	}
+
+	while (count--) {
+		/*
+		 * Do each round.
+		 */
+		unsigned int round = 16;
+		const uint32_t *kl = ekey->l;
+		const uint32_t *kr = ekey->r;
+		uint32_t f;
+		while (round--) {
+			uint32_t r48l, r48r;
+			/*
+			 * Expand R to 48 bits (simulate the E-box).
+			 */
+			r48l	= ((r & 0x00000001) << 23)
+				| ((r & 0xf8000000) >> 9)
+				| ((r & 0x1f800000) >> 11)
+				| ((r & 0x01f80000) >> 13)
+				| ((r & 0x001f8000) >> 15);
+
+			r48r	= ((r & 0x0001f800) << 7)
+				| ((r & 0x00001f80) << 5)
+				| ((r & 0x000001f8) << 3)
+				| ((r & 0x0000001f) << 1)
+				| ((r & 0x80000000) >> 31);
+			/*
+			 * Do salting for crypt() and friends, and
+			 * XOR with the permuted key.
+			 */
+			f = (r48l ^ r48r) & saltbits;
+			r48l ^= f ^ *kl++;
+			r48r ^= f ^ *kr++;
+			/*
+			 * Do S-box lookups (which shrink it back to 32 bits)
+			 * and do the P-box permutation at the same time.
+			 */
+			f = psbox[0][r48l >> 18]
+			  | psbox[1][(r48l >> 12) & 0x3f]
+			  | psbox[2][(r48l >> 6) & 0x3f]
+			  | psbox[3][r48l & 0x3f]
+			  | psbox[4][r48r >> 18]
+			  | psbox[5][(r48r >> 12) & 0x3f]
+			  | psbox[6][(r48r >> 6) & 0x3f]
+			  | psbox[7][r48r & 0x3f];
+			/*
+			 * Now that we've permuted things, complete f().
+			 */
+			f ^= l;
+			l = r;
+			r = f;
+		}
+		r = l;
+		l = f;
+	}
+
+	/*
+	 * Do final permutation (inverse of IP).
+	 */
+	{
+		unsigned int i, ibit;
+		uint32_t lo, ro;
+		lo = ro = 0;
+		for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) {
+			ro |= fp_maskr[i][(l >> ibit) & 0xf] |
+			      fp_maskr[i + 4][(r >> ibit) & 0xf];
+			ibit -= 4;
+			lo |= fp_maskl[i][(l >> ibit) & 0xf] |
+			      fp_maskl[i + 4][(r >> ibit) & 0xf];
+		}
+		*l_out = lo;
+		*r_out = ro;
+	}
+}
+
+static void des_cipher(const unsigned char *in, unsigned char *out,
+    uint32_t count, uint32_t saltbits, const struct expanded_key *ekey)
+{
+	uint32_t l_out, r_out, rawl, rawr;
+
+	rawl =
+	    (uint32_t)in[3] |
+	    ((uint32_t)in[2] << 8) |
+	    ((uint32_t)in[1] << 16) |
+	    ((uint32_t)in[0] << 24);
+	rawr =
+	    (uint32_t)in[7] |
+	    ((uint32_t)in[6] << 8) |
+	    ((uint32_t)in[5] << 16) |
+	    ((uint32_t)in[4] << 24);
+
+	__do_des(rawl, rawr, &l_out, &r_out, count, saltbits, ekey);
+
+	out[0] = l_out >> 24;
+	out[1] = l_out >> 16;
+	out[2] = l_out >> 8;
+	out[3] = l_out;
+	out[4] = r_out >> 24;
+	out[5] = r_out >> 16;
+	out[6] = r_out >> 8;
+	out[7] = r_out;
+}
+
+static char *_crypt_extended_r_uut(const char *_key, const char *_setting, char *output)
+{
+	const unsigned char *key = (const unsigned char *)_key;
+	const unsigned char *setting = (const unsigned char *)_setting;
+	struct expanded_key ekey;
+	unsigned char keybuf[8];
+	unsigned char *p, *q;
+	uint32_t count, salt, l, r0, r1;
+	unsigned int i;
+
+	/*
+	 * Copy the key, shifting each character left by one bit and padding
+	 * with zeroes.
+	 */
+	q = keybuf;
+	while (q <= &keybuf[sizeof(keybuf) - 1]) {
+		*q++ = *key << 1;
+		if (*key)
+			key++;
+	}
+	__des_setkey(keybuf, &ekey);
+
+	if (*setting == _PASSWORD_EFMT1) {
+		/*
+		 * "new"-style:
+		 *	setting - underscore, 4 chars of count, 4 chars of salt
+		 *	key - unlimited characters
+		 */
+		for (i = 1, count = 0; i < 5; i++) {
+			uint32_t value = ascii_to_bin(setting[i]);
+			if (ascii64[value] != setting[i])
+				return NULL;
+			count |= value << (i - 1) * 6;
+		}
+		if (!count)
+			return NULL;
+
+		for (i = 5, salt = 0; i < 9; i++) {
+			uint32_t value = ascii_to_bin(setting[i]);
+			if (ascii64[value] != setting[i])
+				return NULL;
+			salt |= value << (i - 5) * 6;
+		}
+
+		while (*key) {
+			/*
+			 * Encrypt the key with itself.
+			 */
+			des_cipher(keybuf, keybuf, 1, 0, &ekey);
+			/*
+			 * And XOR with the next 8 characters of the key.
+			 */
+			q = keybuf;
+			while (q <= &keybuf[sizeof(keybuf) - 1] && *key)
+				*q++ ^= *key++ << 1;
+			__des_setkey(keybuf, &ekey);
+		}
+
+		memcpy(output, setting, 9);
+		output[9] = '\0';
+		p = (unsigned char *)output + 9;
+	} else {
+		/*
+		 * "old"-style:
+		 *	setting - 2 chars of salt
+		 *	key - up to 8 characters
+		 */
+		count = 25;
+
+		if (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1]))
+			return NULL;
+
+		salt = (ascii_to_bin(setting[1]) << 6)
+		     |  ascii_to_bin(setting[0]);
+
+		output[0] = setting[0];
+		output[1] = setting[1];
+		p = (unsigned char *)output + 2;
+	}
+
+	/*
+	 * Do it.
+	 */
+	__do_des(0, 0, &r0, &r1, count, setup_salt(salt), &ekey);
+
+	/*
+	 * Now encode the result...
+	 */
+	l = (r0 >> 8);
+	*p++ = ascii64[(l >> 18) & 0x3f];
+	*p++ = ascii64[(l >> 12) & 0x3f];
+	*p++ = ascii64[(l >> 6) & 0x3f];
+	*p++ = ascii64[l & 0x3f];
+
+	l = (r0 << 16) | ((r1 >> 16) & 0xffff);
+	*p++ = ascii64[(l >> 18) & 0x3f];
+	*p++ = ascii64[(l >> 12) & 0x3f];
+	*p++ = ascii64[(l >> 6) & 0x3f];
+	*p++ = ascii64[l & 0x3f];
+
+	l = r1 << 2;
+	*p++ = ascii64[(l >> 12) & 0x3f];
+	*p++ = ascii64[(l >> 6) & 0x3f];
+	*p++ = ascii64[l & 0x3f];
+	*p = 0;
+
+	return output;
+}
+
+char *__crypt_des(const char *key, const char *setting, char *output)
+{
+	const char *test_key = "\x80\xff\x80\x01 "
+	    "\x7f\x81\x80\x80\x0d\x0a\xff\x7f \x81 test";
+	const char *test_setting = "_0.../9Zz";
+	const char *test_hash = "_0.../9ZzX7iSJNd21sU";
+	char test_buf[21];
+	char *retval;
+	const char *p;
+
+	if (*setting != _PASSWORD_EFMT1) {
+		test_setting = "\x80x";
+		test_hash = "\x80x22/wK52ZKGA";
+	}
+
+	/*
+	 * Hash the supplied password.
+	 */
+	retval = _crypt_extended_r_uut(key, setting, output);
+
+	/*
+	 * Perform a quick self-test.  It is important that we make both calls
+	 * to _crypt_extended_r_uut() from the same scope such that they likely
+	 * use the same stack locations, which makes the second call overwrite
+	 * the first call's sensitive data on the stack and makes it more
+	 * likely that any alignment related issues would be detected.
+	 */
+	p = _crypt_extended_r_uut(test_key, test_setting, test_buf);
+	if (p && !strcmp(p, test_hash) && retval)
+		return retval;
+
+	return (setting[0]=='*') ? "x" : "*";
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_md5.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_md5.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_md5.c	(revision 398)
@@ -0,0 +1,285 @@
+/*
+ * md5 crypt implementation
+ *
+ * original md5 crypt design is from Poul-Henning Kamp
+ * this implementation was created based on the code in freebsd
+ * at least 32bit int is assumed, key is limited and $1$ prefix is mandatory,
+ * on error "*" is returned
+ */
+#include <string.h>
+#include <stdint.h>
+
+/* public domain md5 implementation based on rfc1321 and libtomcrypt */
+
+struct md5 {
+	uint64_t len;    /* processed message length */
+	uint32_t h[4];   /* hash state */
+	uint8_t buf[64]; /* message block buffer */
+};
+
+static uint32_t rol(uint32_t n, int k) { return (n << k) | (n >> (32-k)); }
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define G(x,y,z) (y ^ (z & (y ^ x)))
+#define H(x,y,z) (x ^ y ^ z)
+#define I(x,y,z) (y ^ (x | ~z))
+#define FF(a,b,c,d,w,s,t) a += F(b,c,d) + w + t; a = rol(a,s) + b
+#define GG(a,b,c,d,w,s,t) a += G(b,c,d) + w + t; a = rol(a,s) + b
+#define HH(a,b,c,d,w,s,t) a += H(b,c,d) + w + t; a = rol(a,s) + b
+#define II(a,b,c,d,w,s,t) a += I(b,c,d) + w + t; a = rol(a,s) + b
+
+static const uint32_t tab[64] = {
+0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+};
+
+static void processblock(struct md5 *s, const uint8_t *buf)
+{
+	uint32_t i, W[16], a, b, c, d;
+
+	for (i = 0; i < 16; i++) {
+		W[i] = buf[4*i];
+		W[i] |= (uint32_t)buf[4*i+1]<<8;
+		W[i] |= (uint32_t)buf[4*i+2]<<16;
+		W[i] |= (uint32_t)buf[4*i+3]<<24;
+	}
+
+	a = s->h[0];
+	b = s->h[1];
+	c = s->h[2];
+	d = s->h[3];
+
+	i = 0;
+	while (i < 16) {
+		FF(a,b,c,d, W[i],  7, tab[i]); i++;
+		FF(d,a,b,c, W[i], 12, tab[i]); i++;
+		FF(c,d,a,b, W[i], 17, tab[i]); i++;
+		FF(b,c,d,a, W[i], 22, tab[i]); i++;
+	}
+	while (i < 32) {
+		GG(a,b,c,d, W[(5*i+1)%16],  5, tab[i]); i++;
+		GG(d,a,b,c, W[(5*i+1)%16],  9, tab[i]); i++;
+		GG(c,d,a,b, W[(5*i+1)%16], 14, tab[i]); i++;
+		GG(b,c,d,a, W[(5*i+1)%16], 20, tab[i]); i++;
+	}
+	while (i < 48) {
+		HH(a,b,c,d, W[(3*i+5)%16],  4, tab[i]); i++;
+		HH(d,a,b,c, W[(3*i+5)%16], 11, tab[i]); i++;
+		HH(c,d,a,b, W[(3*i+5)%16], 16, tab[i]); i++;
+		HH(b,c,d,a, W[(3*i+5)%16], 23, tab[i]); i++;
+	}
+	while (i < 64) {
+		II(a,b,c,d, W[7*i%16],  6, tab[i]); i++;
+		II(d,a,b,c, W[7*i%16], 10, tab[i]); i++;
+		II(c,d,a,b, W[7*i%16], 15, tab[i]); i++;
+		II(b,c,d,a, W[7*i%16], 21, tab[i]); i++;
+	}
+
+	s->h[0] += a;
+	s->h[1] += b;
+	s->h[2] += c;
+	s->h[3] += d;
+}
+
+static void pad(struct md5 *s)
+{
+	unsigned r = s->len % 64;
+
+	s->buf[r++] = 0x80;
+	if (r > 56) {
+		memset(s->buf + r, 0, 64 - r);
+		r = 0;
+		processblock(s, s->buf);
+	}
+	memset(s->buf + r, 0, 56 - r);
+	s->len *= 8;
+	s->buf[56] = s->len;
+	s->buf[57] = s->len >> 8;
+	s->buf[58] = s->len >> 16;
+	s->buf[59] = s->len >> 24;
+	s->buf[60] = s->len >> 32;
+	s->buf[61] = s->len >> 40;
+	s->buf[62] = s->len >> 48;
+	s->buf[63] = s->len >> 56;
+	processblock(s, s->buf);
+}
+
+static void md5_init(struct md5 *s)
+{
+	s->len = 0;
+	s->h[0] = 0x67452301;
+	s->h[1] = 0xefcdab89;
+	s->h[2] = 0x98badcfe;
+	s->h[3] = 0x10325476;
+}
+
+static void md5_sum(struct md5 *s, uint8_t *md)
+{
+	int i;
+
+	pad(s);
+	for (i = 0; i < 4; i++) {
+		md[4*i] = s->h[i];
+		md[4*i+1] = s->h[i] >> 8;
+		md[4*i+2] = s->h[i] >> 16;
+		md[4*i+3] = s->h[i] >> 24;
+	}
+}
+
+static void md5_update(struct md5 *s, const void *m, unsigned long len)
+{
+	const uint8_t *p = m;
+	unsigned r = s->len % 64;
+
+	s->len += len;
+	if (r) {
+		if (len < 64 - r) {
+			memcpy(s->buf + r, p, len);
+			return;
+		}
+		memcpy(s->buf + r, p, 64 - r);
+		len -= 64 - r;
+		p += 64 - r;
+		processblock(s, s->buf);
+	}
+	for (; len >= 64; len -= 64, p += 64)
+		processblock(s, p);
+	memcpy(s->buf, p, len);
+}
+
+/*-
+ * Copyright (c) 2003 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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.
+ */
+
+/* key limit is not part of the original design, added for DoS protection */
+#define KEY_MAX 30000
+#define SALT_MAX 8
+
+static const unsigned char b64[] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static char *to64(char *s, unsigned int u, int n)
+{
+	while (--n >= 0) {
+		*s++ = b64[u % 64];
+		u /= 64;
+	}
+	return s;
+}
+
+static char *md5crypt(const char *key, const char *setting, char *output)
+{
+	struct md5 ctx;
+	unsigned char md[16];
+	unsigned int i, klen, slen;
+	const char *salt;
+	char *p;
+
+	/* reject large keys */
+	klen = strnlen(key, KEY_MAX+1);
+	if (klen > KEY_MAX)
+		return 0;
+
+	/* setting: $1$salt$ (closing $ is optional) */
+	if (strncmp(setting, "$1$", 3) != 0)
+		return 0;
+	salt = setting + 3;
+	for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++);
+	slen = i;
+
+	/* md5(key salt key) */
+	md5_init(&ctx);
+	md5_update(&ctx, key, klen);
+	md5_update(&ctx, salt, slen);
+	md5_update(&ctx, key, klen);
+	md5_sum(&ctx, md);
+
+	/* md5(key $1$ salt repeated-md weird-key[0]-0) */
+	md5_init(&ctx);
+	md5_update(&ctx, key, klen);
+	md5_update(&ctx, setting, 3 + slen);
+	for (i = klen; i > sizeof md; i -= sizeof md)
+		md5_update(&ctx, md, sizeof md);
+	md5_update(&ctx, md, i);
+	md[0] = 0;
+	for (i = klen; i; i >>= 1)
+		if (i & 1)
+			md5_update(&ctx, md, 1);
+		else
+			md5_update(&ctx, key, 1);
+	md5_sum(&ctx, md);
+
+	/* md = f(md, key, salt) iteration */
+	for (i = 0; i < 1000; i++) {
+		md5_init(&ctx);
+		if (i % 2)
+			md5_update(&ctx, key, klen);
+		else
+			md5_update(&ctx, md, sizeof md);
+		if (i % 3)
+			md5_update(&ctx, salt, slen);
+		if (i % 7)
+			md5_update(&ctx, key, klen);
+		if (i % 2)
+			md5_update(&ctx, md, sizeof md);
+		else
+			md5_update(&ctx, key, klen);
+		md5_sum(&ctx, md);
+	}
+
+	/* output is $1$salt$hash */
+	memcpy(output, setting, 3 + slen);
+	p = output + 3 + slen;
+	*p++ = '$';
+	static const unsigned char perm[][3] = {
+		0,6,12,1,7,13,2,8,14,3,9,15,4,10,5 };
+	for (i=0; i<5; i++) p = to64(p,
+		(md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);
+	p = to64(p, md[11], 2);
+	*p = 0;
+
+	return output;
+}
+
+char *__crypt_md5(const char *key, const char *setting, char *output)
+{
+	static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !";
+	static const char testsetting[] = "$1$abcd0123$";
+	static const char testhash[] = "$1$abcd0123$9Qcg8DyviekV3tDGMZynJ1";
+	char testbuf[64];
+	char *p, *q;
+
+	p = md5crypt(key, setting, output);
+	/* self test and stack cleanup */
+	q = md5crypt(testkey, testsetting, testbuf);
+	if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))
+		return "*";
+	return p;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_r.c	(revision 398)
@@ -0,0 +1,32 @@
+#include <crypt.h>
+#include "libc.h"
+
+struct crypt_data;
+
+char *__crypt_des(const char *, const char *, char *);
+char *__crypt_md5(const char *, const char *, char *);
+char *__crypt_blowfish(const char *, const char *, char *);
+char *__crypt_sha256(const char *, const char *, char *);
+char *__crypt_sha512(const char *, const char *, char *);
+
+char *__crypt_r(const char *key, const char *salt, struct crypt_data *data)
+{
+	/* Per the crypt_r API, the caller has provided a pointer to
+	 * struct crypt_data; however, this implementation does not
+	 * use the structure to store any internal state, and treats
+	 * it purely as a char buffer for storing the result. */
+	char *output = (char *)data;
+	if (salt[0] == '$' && salt[1] && salt[2]) {
+		if (salt[1] == '1' && salt[2] == '$')
+			return __crypt_md5(key, salt, output);
+		if (salt[1] == '2' && salt[3] == '$')
+			return __crypt_blowfish(key, salt, output);
+		if (salt[1] == '5' && salt[2] == '$')
+			return __crypt_sha256(key, salt, output);
+		if (salt[1] == '6' && salt[2] == '$')
+			return __crypt_sha512(key, salt, output);
+	}
+	return __crypt_des(key, salt, output);
+}
+
+weak_alias(__crypt_r, crypt_r);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_sha256.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_sha256.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_sha256.c	(revision 398)
@@ -0,0 +1,322 @@
+/*
+ * public domain sha256 crypt implementation
+ *
+ * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt
+ * in this implementation at least 32bit int is assumed,
+ * key length is limited, the $5$ prefix is mandatory, '\n' and ':' is rejected
+ * in the salt and rounds= setting must contain a valid iteration count,
+ * on error "*" is returned.
+ */
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+/* public domain sha256 implementation based on fips180-3 */
+
+struct sha256 {
+	uint64_t len;    /* processed message length */
+	uint32_t h[8];   /* hash state */
+	uint8_t buf[64]; /* message block buffer */
+};
+
+static uint32_t ror(uint32_t n, int k) { return (n >> k) | (n << (32-k)); }
+#define Ch(x,y,z)  (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) ((x & y) | (z & (x | y)))
+#define S0(x)      (ror(x,2) ^ ror(x,13) ^ ror(x,22))
+#define S1(x)      (ror(x,6) ^ ror(x,11) ^ ror(x,25))
+#define R0(x)      (ror(x,7) ^ ror(x,18) ^ (x>>3))
+#define R1(x)      (ror(x,17) ^ ror(x,19) ^ (x>>10))
+
+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
+};
+
+static void processblock(struct sha256 *s, const uint8_t *buf)
+{
+	uint32_t W[64], t1, t2, a, b, c, d, e, f, g, h;
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		W[i] = (uint32_t)buf[4*i]<<24;
+		W[i] |= (uint32_t)buf[4*i+1]<<16;
+		W[i] |= (uint32_t)buf[4*i+2]<<8;
+		W[i] |= buf[4*i+3];
+	}
+	for (; i < 64; i++)
+		W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
+	a = s->h[0];
+	b = s->h[1];
+	c = s->h[2];
+	d = s->h[3];
+	e = s->h[4];
+	f = s->h[5];
+	g = s->h[6];
+	h = s->h[7];
+	for (i = 0; i < 64; i++) {
+		t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
+		t2 = S0(a) + Maj(a,b,c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + t1;
+		d = c;
+		c = b;
+		b = a;
+		a = t1 + t2;
+	}
+	s->h[0] += a;
+	s->h[1] += b;
+	s->h[2] += c;
+	s->h[3] += d;
+	s->h[4] += e;
+	s->h[5] += f;
+	s->h[6] += g;
+	s->h[7] += h;
+}
+
+static void pad(struct sha256 *s)
+{
+	unsigned r = s->len % 64;
+
+	s->buf[r++] = 0x80;
+	if (r > 56) {
+		memset(s->buf + r, 0, 64 - r);
+		r = 0;
+		processblock(s, s->buf);
+	}
+	memset(s->buf + r, 0, 56 - r);
+	s->len *= 8;
+	s->buf[56] = s->len >> 56;
+	s->buf[57] = s->len >> 48;
+	s->buf[58] = s->len >> 40;
+	s->buf[59] = s->len >> 32;
+	s->buf[60] = s->len >> 24;
+	s->buf[61] = s->len >> 16;
+	s->buf[62] = s->len >> 8;
+	s->buf[63] = s->len;
+	processblock(s, s->buf);
+}
+
+static void sha256_init(struct sha256 *s)
+{
+	s->len = 0;
+	s->h[0] = 0x6a09e667;
+	s->h[1] = 0xbb67ae85;
+	s->h[2] = 0x3c6ef372;
+	s->h[3] = 0xa54ff53a;
+	s->h[4] = 0x510e527f;
+	s->h[5] = 0x9b05688c;
+	s->h[6] = 0x1f83d9ab;
+	s->h[7] = 0x5be0cd19;
+}
+
+static void sha256_sum(struct sha256 *s, uint8_t *md)
+{
+	int i;
+
+	pad(s);
+	for (i = 0; i < 8; i++) {
+		md[4*i] = s->h[i] >> 24;
+		md[4*i+1] = s->h[i] >> 16;
+		md[4*i+2] = s->h[i] >> 8;
+		md[4*i+3] = s->h[i];
+	}
+}
+
+static void sha256_update(struct sha256 *s, const void *m, unsigned long len)
+{
+	const uint8_t *p = m;
+	unsigned r = s->len % 64;
+
+	s->len += len;
+	if (r) {
+		if (len < 64 - r) {
+			memcpy(s->buf + r, p, len);
+			return;
+		}
+		memcpy(s->buf + r, p, 64 - r);
+		len -= 64 - r;
+		p += 64 - r;
+		processblock(s, s->buf);
+	}
+	for (; len >= 64; len -= 64, p += 64)
+		processblock(s, p);
+	memcpy(s->buf, p, len);
+}
+
+static const unsigned char b64[] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static char *to64(char *s, unsigned int u, int n)
+{
+	while (--n >= 0) {
+		*s++ = b64[u % 64];
+		u /= 64;
+	}
+	return s;
+}
+
+/* key limit is not part of the original design, added for DoS protection.
+ * rounds limit has been lowered (versus the reference/spec), also for DoS
+ * protection. runtime is O(klen^2 + klen*rounds) */
+#define KEY_MAX 256
+#define SALT_MAX 16
+#define ROUNDS_DEFAULT 5000
+#define ROUNDS_MIN 1000
+#define ROUNDS_MAX 9999999
+
+/* hash n bytes of the repeated md message digest */
+static void hashmd(struct sha256 *s, unsigned int n, const void *md)
+{
+	unsigned int i;
+
+	for (i = n; i > 32; i -= 32)
+		sha256_update(s, md, 32);
+	sha256_update(s, md, i);
+}
+
+static char *sha256crypt(const char *key, const char *setting, char *output)
+{
+	struct sha256 ctx;
+	unsigned char md[32], kmd[32], smd[32];
+	unsigned int i, r, klen, slen;
+	char rounds[20] = "";
+	const char *salt;
+	char *p;
+
+	/* reject large keys */
+	klen = strnlen(key, KEY_MAX+1);
+	if (klen > KEY_MAX)
+		return 0;
+
+	/* setting: $5$rounds=n$salt$ (rounds=n$ and closing $ are optional) */
+	if (strncmp(setting, "$5$", 3) != 0)
+		return 0;
+	salt = setting + 3;
+
+	r = ROUNDS_DEFAULT;
+	if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) {
+		unsigned long u;
+		char *end;
+
+		/*
+		 * this is a deviation from the reference:
+		 * bad rounds setting is rejected if it is
+		 * - empty
+		 * - unterminated (missing '$')
+		 * - begins with anything but a decimal digit
+		 * the reference implementation treats these bad
+		 * rounds as part of the salt or parse them with
+		 * strtoul semantics which may cause problems
+		 * including non-portable hashes that depend on
+		 * the host's value of ULONG_MAX.
+		 */
+		salt += sizeof "rounds=" - 1;
+		if (!isdigit(*salt))
+			return 0;
+		u = strtoul(salt, &end, 10);
+		if (*end != '$')
+			return 0;
+		salt = end+1;
+		if (u < ROUNDS_MIN)
+			r = ROUNDS_MIN;
+		else if (u > ROUNDS_MAX)
+			return 0;
+		else
+			r = u;
+		/* needed when rounds is zero prefixed or out of bounds */
+		sprintf(rounds, "rounds=%u$", r);
+	}
+
+	for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++)
+		/* reject characters that interfere with /etc/shadow parsing */
+		if (salt[i] == '\n' || salt[i] == ':')
+			return 0;
+	slen = i;
+
+	/* B = sha(key salt key) */
+	sha256_init(&ctx);
+	sha256_update(&ctx, key, klen);
+	sha256_update(&ctx, salt, slen);
+	sha256_update(&ctx, key, klen);
+	sha256_sum(&ctx, md);
+
+	/* A = sha(key salt repeat-B alternate-B-key) */
+	sha256_init(&ctx);
+	sha256_update(&ctx, key, klen);
+	sha256_update(&ctx, salt, slen);
+	hashmd(&ctx, klen, md);
+	for (i = klen; i > 0; i >>= 1)
+		if (i & 1)
+			sha256_update(&ctx, md, sizeof md);
+		else
+			sha256_update(&ctx, key, klen);
+	sha256_sum(&ctx, md);
+
+	/* DP = sha(repeat-key), this step takes O(klen^2) time */
+	sha256_init(&ctx);
+	for (i = 0; i < klen; i++)
+		sha256_update(&ctx, key, klen);
+	sha256_sum(&ctx, kmd);
+
+	/* DS = sha(repeat-salt) */
+	sha256_init(&ctx);
+	for (i = 0; i < 16 + md[0]; i++)
+		sha256_update(&ctx, salt, slen);
+	sha256_sum(&ctx, smd);
+
+	/* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */
+	for (i = 0; i < r; i++) {
+		sha256_init(&ctx);
+		if (i % 2)
+			hashmd(&ctx, klen, kmd);
+		else
+			sha256_update(&ctx, md, sizeof md);
+		if (i % 3)
+			sha256_update(&ctx, smd, slen);
+		if (i % 7)
+			hashmd(&ctx, klen, kmd);
+		if (i % 2)
+			sha256_update(&ctx, md, sizeof md);
+		else
+			hashmd(&ctx, klen, kmd);
+		sha256_sum(&ctx, md);
+	}
+
+	/* output is $5$rounds=n$salt$hash */
+	p = output;
+	p += sprintf(p, "$5$%s%.*s$", rounds, slen, salt);
+	static const unsigned char perm[][3] = {
+		0,10,20,21,1,11,12,22,2,3,13,23,24,4,14,
+		15,25,5,6,16,26,27,7,17,18,28,8,9,19,29 };
+	for (i=0; i<10; i++) p = to64(p,
+		(md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);
+	p = to64(p, (md[31]<<8)|md[30], 3);
+	*p = 0;
+	return output;
+}
+
+char *__crypt_sha256(const char *key, const char *setting, char *output)
+{
+	static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !";
+	static const char testsetting[] = "$5$rounds=1234$abc0123456789$";
+	static const char testhash[] = "$5$rounds=1234$abc0123456789$3VfDjPt05VHFn47C/ojFZ6KRPYrOjj1lLbH.dkF3bZ6";
+	char testbuf[128];
+	char *p, *q;
+
+	p = sha256crypt(key, setting, output);
+	/* self test and stack cleanup */
+	q = sha256crypt(testkey, testsetting, testbuf);
+	if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))
+		return "*";
+	return p;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_sha512.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_sha512.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/crypt_sha512.c	(revision 398)
@@ -0,0 +1,371 @@
+/*
+ * public domain sha512 crypt implementation
+ *
+ * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt
+ * in this implementation at least 32bit int is assumed,
+ * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected
+ * in the salt and rounds= setting must contain a valid iteration count,
+ * on error "*" is returned.
+ */
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+/* public domain sha512 implementation based on fips180-3 */
+/* >=2^64 bits messages are not supported (about 2000 peta bytes) */
+
+struct sha512 {
+	uint64_t len;     /* processed message length */
+	uint64_t h[8];    /* hash state */
+	uint8_t buf[128]; /* message block buffer */
+};
+
+static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); }
+#define Ch(x,y,z)  (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) ((x & y) | (z & (x | y)))
+#define S0(x)      (ror(x,28) ^ ror(x,34) ^ ror(x,39))
+#define S1(x)      (ror(x,14) ^ ror(x,18) ^ ror(x,41))
+#define R0(x)      (ror(x,1) ^ ror(x,8) ^ (x>>7))
+#define R1(x)      (ror(x,19) ^ ror(x,61) ^ (x>>6))
+
+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
+};
+
+static void processblock(struct sha512 *s, const uint8_t *buf)
+{
+	uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h;
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		W[i] = (uint64_t)buf[8*i]<<56;
+		W[i] |= (uint64_t)buf[8*i+1]<<48;
+		W[i] |= (uint64_t)buf[8*i+2]<<40;
+		W[i] |= (uint64_t)buf[8*i+3]<<32;
+		W[i] |= (uint64_t)buf[8*i+4]<<24;
+		W[i] |= (uint64_t)buf[8*i+5]<<16;
+		W[i] |= (uint64_t)buf[8*i+6]<<8;
+		W[i] |= buf[8*i+7];
+	}
+	for (; i < 80; i++)
+		W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
+	a = s->h[0];
+	b = s->h[1];
+	c = s->h[2];
+	d = s->h[3];
+	e = s->h[4];
+	f = s->h[5];
+	g = s->h[6];
+	h = s->h[7];
+	for (i = 0; i < 80; i++) {
+		t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
+		t2 = S0(a) + Maj(a,b,c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + t1;
+		d = c;
+		c = b;
+		b = a;
+		a = t1 + t2;
+	}
+	s->h[0] += a;
+	s->h[1] += b;
+	s->h[2] += c;
+	s->h[3] += d;
+	s->h[4] += e;
+	s->h[5] += f;
+	s->h[6] += g;
+	s->h[7] += h;
+}
+
+static void pad(struct sha512 *s)
+{
+	unsigned r = s->len % 128;
+
+	s->buf[r++] = 0x80;
+	if (r > 112) {
+		memset(s->buf + r, 0, 128 - r);
+		r = 0;
+		processblock(s, s->buf);
+	}
+	memset(s->buf + r, 0, 120 - r);
+	s->len *= 8;
+	s->buf[120] = s->len >> 56;
+	s->buf[121] = s->len >> 48;
+	s->buf[122] = s->len >> 40;
+	s->buf[123] = s->len >> 32;
+	s->buf[124] = s->len >> 24;
+	s->buf[125] = s->len >> 16;
+	s->buf[126] = s->len >> 8;
+	s->buf[127] = s->len;
+	processblock(s, s->buf);
+}
+
+static void sha512_init(struct sha512 *s)
+{
+	s->len = 0;
+	s->h[0] = 0x6a09e667f3bcc908ULL;
+	s->h[1] = 0xbb67ae8584caa73bULL;
+	s->h[2] = 0x3c6ef372fe94f82bULL;
+	s->h[3] = 0xa54ff53a5f1d36f1ULL;
+	s->h[4] = 0x510e527fade682d1ULL;
+	s->h[5] = 0x9b05688c2b3e6c1fULL;
+	s->h[6] = 0x1f83d9abfb41bd6bULL;
+	s->h[7] = 0x5be0cd19137e2179ULL;
+}
+
+static void sha512_sum(struct sha512 *s, uint8_t *md)
+{
+	int i;
+
+	pad(s);
+	for (i = 0; i < 8; i++) {
+		md[8*i] = s->h[i] >> 56;
+		md[8*i+1] = s->h[i] >> 48;
+		md[8*i+2] = s->h[i] >> 40;
+		md[8*i+3] = s->h[i] >> 32;
+		md[8*i+4] = s->h[i] >> 24;
+		md[8*i+5] = s->h[i] >> 16;
+		md[8*i+6] = s->h[i] >> 8;
+		md[8*i+7] = s->h[i];
+	}
+}
+
+static void sha512_update(struct sha512 *s, const void *m, unsigned long len)
+{
+	const uint8_t *p = m;
+	unsigned r = s->len % 128;
+
+	s->len += len;
+	if (r) {
+		if (len < 128 - r) {
+			memcpy(s->buf + r, p, len);
+			return;
+		}
+		memcpy(s->buf + r, p, 128 - r);
+		len -= 128 - r;
+		p += 128 - r;
+		processblock(s, s->buf);
+	}
+	for (; len >= 128; len -= 128, p += 128)
+		processblock(s, p);
+	memcpy(s->buf, p, len);
+}
+
+static const unsigned char b64[] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static char *to64(char *s, unsigned int u, int n)
+{
+	while (--n >= 0) {
+		*s++ = b64[u % 64];
+		u /= 64;
+	}
+	return s;
+}
+
+/* key limit is not part of the original design, added for DoS protection.
+ * rounds limit has been lowered (versus the reference/spec), also for DoS
+ * protection. runtime is O(klen^2 + klen*rounds) */
+#define KEY_MAX 256
+#define SALT_MAX 16
+#define ROUNDS_DEFAULT 5000
+#define ROUNDS_MIN 1000
+#define ROUNDS_MAX 9999999
+
+/* hash n bytes of the repeated md message digest */
+static void hashmd(struct sha512 *s, unsigned int n, const void *md)
+{
+	unsigned int i;
+
+	for (i = n; i > 64; i -= 64)
+		sha512_update(s, md, 64);
+	sha512_update(s, md, i);
+}
+
+static char *sha512crypt(const char *key, const char *setting, char *output)
+{
+	struct sha512 ctx;
+	unsigned char md[64], kmd[64], smd[64];
+	unsigned int i, r, klen, slen;
+	char rounds[20] = "";
+	const char *salt;
+	char *p;
+
+	/* reject large keys */
+	for (i = 0; i <= KEY_MAX && key[i]; i++);
+	if (i > KEY_MAX)
+		return 0;
+	klen = i;
+
+	/* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */
+	if (strncmp(setting, "$6$", 3) != 0)
+		return 0;
+	salt = setting + 3;
+
+	r = ROUNDS_DEFAULT;
+	if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) {
+		unsigned long u;
+		char *end;
+
+		/*
+		 * this is a deviation from the reference:
+		 * bad rounds setting is rejected if it is
+		 * - empty
+		 * - unterminated (missing '$')
+		 * - begins with anything but a decimal digit
+		 * the reference implementation treats these bad
+		 * rounds as part of the salt or parse them with
+		 * strtoul semantics which may cause problems
+		 * including non-portable hashes that depend on
+		 * the host's value of ULONG_MAX.
+		 */
+		salt += sizeof "rounds=" - 1;
+		if (!isdigit(*salt))
+			return 0;
+		u = strtoul(salt, &end, 10);
+		if (*end != '$')
+			return 0;
+		salt = end+1;
+		if (u < ROUNDS_MIN)
+			r = ROUNDS_MIN;
+		else if (u > ROUNDS_MAX)
+			return 0;
+		else
+			r = u;
+		/* needed when rounds is zero prefixed or out of bounds */
+		sprintf(rounds, "rounds=%u$", r);
+	}
+
+	for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++)
+		/* reject characters that interfere with /etc/shadow parsing */
+		if (salt[i] == '\n' || salt[i] == ':')
+			return 0;
+	slen = i;
+
+	/* B = sha(key salt key) */
+	sha512_init(&ctx);
+	sha512_update(&ctx, key, klen);
+	sha512_update(&ctx, salt, slen);
+	sha512_update(&ctx, key, klen);
+	sha512_sum(&ctx, md);
+
+	/* A = sha(key salt repeat-B alternate-B-key) */
+	sha512_init(&ctx);
+	sha512_update(&ctx, key, klen);
+	sha512_update(&ctx, salt, slen);
+	hashmd(&ctx, klen, md);
+	for (i = klen; i > 0; i >>= 1)
+		if (i & 1)
+			sha512_update(&ctx, md, sizeof md);
+		else
+			sha512_update(&ctx, key, klen);
+	sha512_sum(&ctx, md);
+
+	/* DP = sha(repeat-key), this step takes O(klen^2) time */
+	sha512_init(&ctx);
+	for (i = 0; i < klen; i++)
+		sha512_update(&ctx, key, klen);
+	sha512_sum(&ctx, kmd);
+
+	/* DS = sha(repeat-salt) */
+	sha512_init(&ctx);
+	for (i = 0; i < 16 + md[0]; i++)
+		sha512_update(&ctx, salt, slen);
+	sha512_sum(&ctx, smd);
+
+	/* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */
+	for (i = 0; i < r; i++) {
+		sha512_init(&ctx);
+		if (i % 2)
+			hashmd(&ctx, klen, kmd);
+		else
+			sha512_update(&ctx, md, sizeof md);
+		if (i % 3)
+			sha512_update(&ctx, smd, slen);
+		if (i % 7)
+			hashmd(&ctx, klen, kmd);
+		if (i % 2)
+			sha512_update(&ctx, md, sizeof md);
+		else
+			hashmd(&ctx, klen, kmd);
+		sha512_sum(&ctx, md);
+	}
+
+	/* output is $6$rounds=n$salt$hash */
+	p = output;
+	p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt);
+#if 1
+	static const unsigned char perm[][3] = {
+		0,21,42,22,43,1,44,2,23,3,24,45,25,46,4,
+		47,5,26,6,27,48,28,49,7,50,8,29,9,30,51,
+		31,52,10,53,11,32,12,33,54,34,55,13,56,14,35,
+		15,36,57,37,58,16,59,17,38,18,39,60,40,61,19,
+		62,20,41 };
+	for (i=0; i<21; i++) p = to64(p,
+		(md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);
+#else
+	p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4);
+	p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4);
+	p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4);
+	p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4);
+	p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4);
+	p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4);
+	p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4);
+	p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4);
+	p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4);
+	p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4);
+	p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4);
+	p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4);
+	p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4);
+	p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4);
+	p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4);
+	p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4);
+	p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4);
+	p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4);
+	p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4);
+	p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4);
+	p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4);
+#endif
+	p = to64(p, md[63], 2);
+	*p = 0;
+	return output;
+}
+
+char *__crypt_sha512(const char *key, const char *setting, char *output)
+{
+	static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !";
+	static const char testsetting[] = "$6$rounds=1234$abc0123456789$";
+	static const char testhash[] = "$6$rounds=1234$abc0123456789$BCpt8zLrc/RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1";
+	char testbuf[128];
+	char *p, *q;
+
+	p = sha512crypt(key, setting, output);
+	/* self test and stack cleanup */
+	q = sha512crypt(testkey, testsetting, testbuf);
+	if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))
+		return "*";
+	return p;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/encrypt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/encrypt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/crypt/encrypt.c	(revision 398)
@@ -0,0 +1,60 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+struct expanded_key {
+        uint32_t l[16], r[16];
+};
+
+void __des_setkey(const unsigned char *key, struct expanded_key *ekey);
+void __do_des(uint32_t l_in, uint32_t r_in,
+    uint32_t *l_out, uint32_t *r_out,
+    uint32_t count, uint32_t saltbits, const struct expanded_key *ekey);
+
+
+static struct expanded_key __encrypt_key;
+
+void setkey(const char *key)
+{
+	unsigned char bkey[8];
+	int i, j;
+
+	for (i = 0; i < 8; i++) {
+		bkey[i] = 0;
+		for (j = 7; j >= 0; j--, key++)
+			bkey[i] |= (uint32_t)(*key & 1) << j;
+	}
+
+	__des_setkey(bkey, &__encrypt_key);
+}
+
+void encrypt(char *block, int edflag)
+{
+	struct expanded_key decrypt_key, *key;
+	uint32_t b[2];
+	int i, j;
+	char *p;
+
+	p = block;
+	for (i = 0; i < 2; i++) {
+		b[i] = 0;
+		for (j = 31; j >= 0; j--, p++)
+			b[i] |= (uint32_t)(*p & 1) << j;
+	}
+
+	key = &__encrypt_key;
+	if (edflag) {
+		key = &decrypt_key;
+		for (i = 0; i < 16; i++) {
+			decrypt_key.l[i] = __encrypt_key.l[15-i];
+			decrypt_key.r[i] = __encrypt_key.r[15-i];
+		}
+	}
+
+	__do_des(b[0], b[1], b, b + 1, 1, 0, key);
+
+	p = block;
+	for (i = 0; i < 2; i++)
+		for (j = 31; j >= 0; j--)
+			*p++ = b[i]>>j & 1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_b_loc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_b_loc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_b_loc.c	(revision 398)
@@ -0,0 +1,41 @@
+#include <endian.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define X(x) x
+#else
+#define X(x) (((x)/256 | (x)*256) % 65536)
+#endif
+
+static const unsigned short table[] = {
+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,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,0,0,
+X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),
+X(0x200),X(0x320),X(0x220),X(0x220),X(0x220),X(0x220),X(0x200),X(0x200),
+X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),
+X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),
+X(0x160),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
+X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
+X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),
+X(0x8d8),X(0x8d8),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
+X(0x4c0),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8c5),
+X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),
+X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),
+X(0x8c5),X(0x8c5),X(0x8c5),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
+X(0x4c0),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8c6),
+X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),
+X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),
+X(0x8c6),X(0x8c6),X(0x8c6),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x200),
+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,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,0,0,
+};
+
+static const unsigned short *const ptable = table+128;
+
+const unsigned short **__ctype_b_loc(void)
+{
+	return (void *)&ptable;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_get_mb_cur_max.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_get_mb_cur_max.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_get_mb_cur_max.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include "locale_impl.h"
+
+size_t __ctype_get_mb_cur_max()
+{
+	return MB_CUR_MAX;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_tolower_loc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_tolower_loc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_tolower_loc.c	(revision 398)
@@ -0,0 +1,30 @@
+#include <stdint.h>
+
+static const int32_t table[] = {
+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,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,0,0,
+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,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,52,53,54,55,56,57,58,59,60,61,62,63,
+64,
+'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',
+91,92,93,94,95,96,
+'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',
+123,124,125,126,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,
+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,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,
+};
+
+static const int32_t *const ptable = table+128;
+
+const int32_t **__ctype_tolower_loc(void)
+{
+	return (void *)&ptable;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_toupper_loc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_toupper_loc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/__ctype_toupper_loc.c	(revision 398)
@@ -0,0 +1,30 @@
+#include <stdint.h>
+
+static const int32_t table[] = {
+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,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,0,0,
+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,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,52,53,54,55,56,57,58,59,60,61,62,63,
+64,
+'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',
+91,92,93,94,95,96,
+'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',
+123,124,125,126,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,
+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,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,
+};
+
+static const int32_t *const ptable = table+128;
+
+const int32_t **__ctype_toupper_loc(void)
+{
+	return (void *)&ptable;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/alpha.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/alpha.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/alpha.h	(revision 398)
@@ -0,0 +1,125 @@
+18,17,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,17,34,35,36,17,37,38,39,40,
+41,42,43,44,17,45,46,47,16,16,48,16,16,16,16,16,16,16,49,50,51,16,52,53,16,16,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,54,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,55,17,17,17,17,56,17,57,58,59,60,61,62,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,63,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,64,65,17,66,67,68,69,70,71,72,
+73,16,16,16,74,75,76,77,78,16,16,16,79,80,16,16,16,16,81,16,16,16,16,16,16,16,
+16,16,17,17,17,82,83,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,84,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,85,16,
+16,16,16,86,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,87,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+88,89,90,91,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+92,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,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,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,0,0,0,0,0,0,0,0,254,255,255,7,254,255,255,7,0,0,0,0,0,4,32,4,
+255,255,127,255,255,255,127,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,195,255,3,0,31,80,0,0,0,0,
+0,0,0,0,0,0,32,0,0,0,0,0,223,60,64,215,255,255,251,255,255,255,255,255,255,
+255,255,255,191,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,3,252,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,0,254,255,255,255,127,2,254,255,255,255,255,0,0,0,0,0,255,191,182,
+0,255,255,255,7,7,0,0,0,255,7,255,255,255,255,255,255,255,254,255,195,255,255,
+255,255,255,255,255,255,255,255,255,255,239,31,254,225,255,159,0,0,255,255,
+255,255,255,255,0,224,255,255,255,255,255,255,255,255,255,255,255,255,3,0,255,
+255,255,255,255,7,48,4,255,255,255,252,255,31,0,0,255,255,255,1,0,0,0,0,0,0,0,
+0,253,31,0,0,0,0,0,0,240,3,255,127,255,255,255,255,255,255,255,239,255,223,
+225,255,207,255,254,254,238,159,249,255,255,253,197,227,159,89,128,176,207,
+255,3,0,238,135,249,255,255,253,109,195,135,25,2,94,192,255,63,0,238,191,251,
+255,255,253,237,227,191,27,1,0,207,255,0,0,238,159,249,255,255,253,237,227,
+159,25,192,176,207,255,2,0,236,199,61,214,24,199,255,195,199,29,129,0,192,255,
+0,0,238,223,253,255,255,253,239,227,223,29,96,3,207,255,0,0,236,223,253,255,
+255,253,239,227,223,29,96,64,207,255,6,0,236,223,253,255,255,255,255,231,223,
+93,128,0,207,255,0,252,236,255,127,252,255,255,251,47,127,128,95,255,0,0,12,0,
+254,255,255,255,255,127,255,7,63,32,255,3,0,0,0,0,150,37,240,254,174,236,255,
+59,95,32,255,243,0,0,0,0,1,0,0,0,255,3,0,0,255,254,255,255,255,31,254,255,3,
+255,255,254,255,255,255,31,0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,249,
+255,3,255,255,231,193,255,255,127,64,255,51,255,255,255,255,191,32,255,255,
+255,255,255,247,255,255,255,255,255,255,255,255,255,61,127,61,255,255,255,255,
+255,61,255,255,255,255,61,127,61,255,127,255,255,255,255,255,255,255,61,255,
+255,255,255,255,255,255,255,135,0,0,0,0,255,255,0,0,255,255,255,255,255,255,
+255,255,255,255,31,0,254,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,159,255,255,254,255,255,7,255,
+255,255,255,255,255,255,255,255,199,1,0,255,223,15,0,255,255,15,0,255,255,15,
+0,255,223,13,0,255,255,255,255,255,255,207,255,255,1,128,16,255,3,0,0,0,0,255,
+3,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,255,255,7,255,255,
+255,255,255,255,255,255,63,0,255,255,255,31,255,15,255,1,192,255,255,255,255,
+63,31,0,255,255,255,255,255,15,255,255,255,3,255,3,0,0,0,0,255,255,255,15,255,
+255,255,255,255,255,255,127,254,255,31,0,255,3,255,3,128,0,0,0,0,0,0,0,0,0,0,
+0,255,255,255,255,255,255,239,255,239,15,255,3,0,0,0,0,255,255,255,255,255,
+243,255,255,255,255,255,255,191,255,3,0,255,255,255,255,255,255,63,0,255,227,
+255,255,255,255,255,63,0,0,0,0,0,0,0,0,0,0,0,0,0,222,111,0,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,0,0,0,0,0,0,0,0,255,255,63,63,255,255,255,255,63,63,255,170,255,255,255,
+63,255,255,255,255,255,255,223,95,220,31,207,15,255,31,220,31,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,2,128,0,0,255,31,0,0,0,0,0,0,0,0,0,0,0,0,132,252,47,62,80,189,255,
+243,224,67,0,0,255,255,255,255,255,1,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,192,255,255,255,255,255,255,3,0,0,255,255,255,
+255,255,127,255,255,255,255,255,127,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,31,120,12,0,255,255,255,255,191,32,255,255,255,255,
+255,255,255,128,0,0,255,255,127,0,127,127,127,127,127,127,127,127,255,255,255,
+255,0,0,0,0,0,128,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,224,0,0,
+0,254,3,62,31,254,255,255,255,255,255,255,255,255,255,127,224,254,255,255,255,
+255,255,255,255,255,255,255,247,224,255,255,255,255,63,254,255,255,255,255,
+255,255,255,255,255,255,127,0,0,255,255,255,7,0,0,0,0,0,0,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+63,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,31,0,0,0,0,0,0,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,0,0,0,0,0,0,255,
+255,255,255,255,63,255,31,255,255,255,15,0,0,255,255,255,255,255,127,240,143,
+255,255,255,128,255,255,255,255,255,255,255,255,255,255,0,0,0,0,128,255,252,
+255,255,255,255,255,255,255,255,255,255,255,255,121,15,0,255,7,0,0,0,0,0,0,0,
+0,0,255,187,247,255,255,255,0,0,0,255,255,255,255,255,255,15,0,255,255,255,
+255,255,255,255,255,15,0,255,3,0,0,252,8,255,255,255,255,255,7,255,255,255,
+255,7,0,255,255,255,31,255,255,255,255,255,255,247,255,0,128,255,3,0,0,0,0,
+255,255,255,255,255,255,127,0,255,63,255,3,255,255,127,4,255,255,255,255,255,
+255,255,127,5,0,0,56,255,255,60,0,126,126,126,0,127,127,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,255,255,255,255,255,7,255,3,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,15,0,255,255,127,248,255,255,255,
+255,255,15,255,255,255,255,255,255,255,255,255,255,255,255,255,63,255,255,255,
+255,255,255,255,255,255,255,255,255,255,3,0,0,0,0,127,0,248,224,255,253,127,
+95,219,255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,248,255,
+255,255,255,255,255,255,255,255,255,255,255,63,0,0,255,255,255,255,255,255,
+255,255,252,255,255,255,255,255,255,0,0,0,0,0,255,15,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,223,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,
+0,255,3,254,255,255,7,254,255,255,7,192,255,255,255,255,255,255,255,255,255,
+255,127,252,252,252,28,0,0,0,0,255,239,255,255,127,255,255,183,255,63,255,63,
+0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,0,0,0,0,
+0,0,0,0,255,255,255,255,255,255,31,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,255,255,255,31,255,255,255,255,255,255,1,0,0,0,0,0,
+255,255,255,127,0,0,255,255,255,7,0,0,0,0,0,0,255,255,255,63,255,255,255,255,
+15,255,62,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,63,255,3,0,0,0,0,0,0,0,0,0,0,63,253,255,255,255,255,191,
+145,255,255,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,63,0,255,255,
+255,3,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,192,0,0,0,0,0,0,0,0,111,240,
+239,254,255,255,15,0,0,0,0,0,255,255,255,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+255,255,255,255,255,255,63,0,255,255,63,0,255,255,7,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,255,255,255,255,255,255,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,255,255,255,255,255,255,255,255,63,0,0,0,192,255,0,0,252,255,255,
+255,255,255,255,1,0,0,255,255,255,1,255,3,255,255,255,255,255,255,199,255,0,0,
+0,0,0,0,0,0,255,255,255,255,255,255,255,255,30,0,255,3,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,63,0,255,3,0,0,0,0,0,0,255,255,255,
+255,255,255,255,255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,255,255,255,255,255,255,255,255,255,255,255,255,7,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,255,255,255,255,255,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,255,255,255,255,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,255,255,255,255,255,255,255,255,31,0,255,255,255,255,255,127,0,0,
+248,255,0,0,0,0,0,0,0,0,0,0,0,0,3,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,255,255,255,255,255,255,255,255,255,255,223,255,255,255,255,
+255,255,255,255,223,100,222,255,235,239,255,255,255,255,255,255,255,191,231,
+223,223,255,255,255,123,95,252,253,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,63,255,255,255,253,255,255,
+247,255,255,255,247,255,255,223,255,255,255,223,255,255,127,255,255,255,127,
+255,255,255,253,255,255,255,253,255,255,247,207,255,255,255,255,255,255,239,
+255,255,255,150,254,247,10,132,234,150,170,150,247,247,94,255,251,255,15,238,
+251,255,15,0,0,0,0,0,0,0,0,
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isalnum.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isalnum.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isalnum.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#include "libc.h"
+
+int isalnum(int c)
+{
+	return isalpha(c) || isdigit(c);
+}
+
+int __isalnum_l(int c, locale_t l)
+{
+	return isalnum(c);
+}
+
+weak_alias(__isalnum_l, isalnum_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isalpha.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isalpha.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isalpha.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <ctype.h>
+#include "libc.h"
+#undef isalpha
+
+int isalpha(int c)
+{
+	return ((unsigned)c|32)-'a' < 26;
+}
+
+int __isalpha_l(int c, locale_t l)
+{
+	return isalpha(c);
+}
+
+weak_alias(__isalpha_l, isalpha_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isascii.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isascii.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isascii.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <ctype.h>
+#undef isascii
+
+int isascii(int c)
+{
+	return !(c&~0x7f);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isblank.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isblank.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isblank.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#include "libc.h"
+
+int isblank(int c)
+{
+	return (c == ' ' || c == '\t');
+}
+
+int __isblank_l(int c, locale_t l)
+{
+	return isblank(c);
+}
+
+weak_alias(__isblank_l, isblank_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iscntrl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iscntrl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iscntrl.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#include "libc.h"
+
+int iscntrl(int c)
+{
+	return (unsigned)c < 0x20 || c == 0x7f;
+}
+
+int __iscntrl_l(int c, locale_t l)
+{
+	return iscntrl(c);
+}
+
+weak_alias(__iscntrl_l, iscntrl_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isdigit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isdigit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isdigit.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <ctype.h>
+#include "libc.h"
+#undef isdigit
+
+int isdigit(int c)
+{
+	return (unsigned)c-'0' < 10;
+}
+
+int __isdigit_l(int c, locale_t l)
+{
+	return isdigit(c);
+}
+
+weak_alias(__isdigit_l, isdigit_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isgraph.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isgraph.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isgraph.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <ctype.h>
+#include "libc.h"
+#undef isgraph
+
+int isgraph(int c)
+{
+	return (unsigned)c-0x21 < 0x5e;
+}
+
+int __isgraph_l(int c, locale_t l)
+{
+	return isgraph(c);
+}
+
+weak_alias(__isgraph_l, isgraph_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/islower.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/islower.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/islower.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <ctype.h>
+#include "libc.h"
+#undef islower
+
+int islower(int c)
+{
+	return (unsigned)c-'a' < 26;
+}
+
+int __islower_l(int c, locale_t l)
+{
+	return islower(c);
+}
+
+weak_alias(__islower_l, islower_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isprint.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isprint.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isprint.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <ctype.h>
+#include "libc.h"
+#undef isprint
+
+int isprint(int c)
+{
+	return (unsigned)c-0x20 < 0x5f;
+}
+
+int __isprint_l(int c, locale_t l)
+{
+	return isprint(c);
+}
+
+weak_alias(__isprint_l, isprint_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/ispunct.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/ispunct.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/ispunct.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#include "libc.h"
+
+int ispunct(int c)
+{
+	return isgraph(c) && !isalnum(c);
+}
+
+int __ispunct_l(int c, locale_t l)
+{
+	return ispunct(c);
+}
+
+weak_alias(__ispunct_l, ispunct_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isspace.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isspace.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isspace.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <ctype.h>
+#include "libc.h"
+#undef isspace
+
+int isspace(int c)
+{
+	return c == ' ' || (unsigned)c-'\t' < 5;
+}
+
+int __isspace_l(int c, locale_t l)
+{
+	return isspace(c);
+}
+
+weak_alias(__isspace_l, isspace_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isupper.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isupper.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isupper.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <ctype.h>
+#include "libc.h"
+#undef isupper
+
+int isupper(int c)
+{
+	return (unsigned)c-'A' < 26;
+}
+
+int __isupper_l(int c, locale_t l)
+{
+	return isupper(c);
+}
+
+weak_alias(__isupper_l, isupper_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswalnum.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswalnum.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswalnum.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <wctype.h>
+#include "libc.h"
+
+int iswalnum(wint_t wc)
+{
+	return iswdigit(wc) || iswalpha(wc);
+}
+
+int __iswalnum_l(wint_t c, locale_t l)
+{
+	return iswalnum(c);
+}
+
+weak_alias(__iswalnum_l, iswalnum_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswalpha.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswalpha.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswalpha.c	(revision 398)
@@ -0,0 +1,22 @@
+#include <wctype.h>
+#include "libc.h"
+
+static const unsigned char table[] = {
+#include "alpha.h"
+};
+
+int iswalpha(wint_t wc)
+{
+	if (wc<0x20000U)
+		return (table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1;
+	if (wc<0x2fffeU)
+		return 1;
+	return 0;
+}
+
+int __iswalpha_l(wint_t c, locale_t l)
+{
+	return iswalpha(c);
+}
+
+weak_alias(__iswalpha_l, iswalpha_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswblank.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswblank.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswblank.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <wctype.h>
+#include <ctype.h>
+#include "libc.h"
+
+int iswblank(wint_t wc)
+{
+	return isblank(wc);
+}
+
+int __iswblank_l(wint_t c, locale_t l)
+{
+	return iswblank(c);
+}
+
+weak_alias(__iswblank_l, iswblank_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswcntrl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswcntrl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswcntrl.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <wctype.h>
+#include "libc.h"
+
+int iswcntrl(wint_t wc)
+{
+	return (unsigned)wc < 32
+	    || (unsigned)(wc-0x7f) < 33
+	    || (unsigned)(wc-0x2028) < 2
+	    || (unsigned)(wc-0xfff9) < 3;
+}
+
+int __iswcntrl_l(wint_t c, locale_t l)
+{
+	return iswcntrl(c);
+}
+
+weak_alias(__iswcntrl_l, iswcntrl_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswctype.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswctype.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswctype.c	(revision 398)
@@ -0,0 +1,76 @@
+#include <wctype.h>
+#include <string.h>
+#include "libc.h"
+
+#define WCTYPE_ALNUM  1
+#define WCTYPE_ALPHA  2
+#define WCTYPE_BLANK  3
+#define WCTYPE_CNTRL  4
+#define WCTYPE_DIGIT  5
+#define WCTYPE_GRAPH  6
+#define WCTYPE_LOWER  7
+#define WCTYPE_PRINT  8
+#define WCTYPE_PUNCT  9
+#define WCTYPE_SPACE  10
+#define WCTYPE_UPPER  11
+#define WCTYPE_XDIGIT 12
+
+int iswctype(wint_t wc, wctype_t type)
+{
+	switch (type) {
+	case WCTYPE_ALNUM:
+		return iswalnum(wc);
+	case WCTYPE_ALPHA:
+		return iswalpha(wc);
+	case WCTYPE_BLANK:
+		return iswblank(wc);
+	case WCTYPE_CNTRL:
+		return iswcntrl(wc);
+	case WCTYPE_DIGIT:
+		return iswdigit(wc);
+	case WCTYPE_GRAPH:
+		return iswgraph(wc);
+	case WCTYPE_LOWER:
+		return iswlower(wc);
+	case WCTYPE_PRINT:
+		return iswprint(wc);
+	case WCTYPE_PUNCT:
+		return iswpunct(wc);
+	case WCTYPE_SPACE:
+		return iswspace(wc);
+	case WCTYPE_UPPER:
+		return iswupper(wc);
+	case WCTYPE_XDIGIT:
+		return iswxdigit(wc);
+	}
+	return 0;
+}
+
+wctype_t wctype(const char *s)
+{
+	int i;
+	const char *p;
+	/* order must match! */
+	static const char names[] =
+		"alnum\0" "alpha\0" "blank\0"
+		"cntrl\0" "digit\0" "graph\0"
+		"lower\0" "print\0" "punct\0"
+		"space\0" "upper\0" "xdigit";
+	for (i=1, p=names; *p; i++, p+=6)
+		if (*s == *p && !strcmp(s, p))
+			return i;
+	return 0;
+}
+
+int __iswctype_l(wint_t c, wctype_t t, locale_t l)
+{
+	return iswctype(c, t);
+}
+
+wctype_t __wctype_l(const char *s, locale_t l)
+{
+	return wctype(s);
+}
+
+weak_alias(__iswctype_l, iswctype_l);
+weak_alias(__wctype_l, wctype_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswdigit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswdigit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswdigit.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <wctype.h>
+#include "libc.h"
+
+#undef iswdigit
+
+int iswdigit(wint_t wc)
+{
+	return (unsigned)wc-'0' < 10;
+}
+
+int __iswdigit_l(wint_t c, locale_t l)
+{
+	return iswdigit(c);
+}
+
+weak_alias(__iswdigit_l, iswdigit_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswgraph.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswgraph.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswgraph.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <wctype.h>
+#include "libc.h"
+
+int iswgraph(wint_t wc)
+{
+	/* ISO C defines this function as: */
+	return !iswspace(wc) && iswprint(wc);
+}
+
+int __iswgraph_l(wint_t c, locale_t l)
+{
+	return iswgraph(c);
+}
+
+weak_alias(__iswgraph_l, iswgraph_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswlower.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswlower.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswlower.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <wctype.h>
+#include "libc.h"
+
+int iswlower(wint_t wc)
+{
+	return towupper(wc) != wc;
+}
+
+int __iswlower_l(wint_t c, locale_t l)
+{
+	return iswlower(c);
+}
+
+weak_alias(__iswlower_l, iswlower_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswprint.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswprint.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswprint.c	(revision 398)
@@ -0,0 +1,27 @@
+#include <wctype.h>
+#include "libc.h"
+
+/* Consider all legal codepoints as printable except for:
+ * - C0 and C1 control characters
+ * - U+2028 and U+2029 (line/para break)
+ * - U+FFF9 through U+FFFB (interlinear annotation controls)
+ * The following code is optimized heavily to make hot paths for the
+ * expected printable characters. */
+
+int iswprint(wint_t wc)
+{
+	if (wc < 0xffU)
+		return (wc+1 & 0x7f) >= 0x21;
+	if (wc < 0x2028U || wc-0x202aU < 0xd800-0x202a || wc-0xe000U < 0xfff9-0xe000)
+		return 1;
+	if (wc-0xfffcU > 0x10ffff-0xfffc || (wc&0xfffe)==0xfffe)
+		return 0;
+	return 1;
+}
+
+int __iswprint_l(wint_t c, locale_t l)
+{
+	return iswprint(c);
+}
+
+weak_alias(__iswprint_l, iswprint_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswpunct.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswpunct.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswpunct.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <wctype.h>
+#include "libc.h"
+
+static const unsigned char table[] = {
+#include "punct.h"
+};
+
+int iswpunct(wint_t wc)
+{
+	if (wc<0x20000U)
+		return (table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1;
+	return 0;
+}
+
+int __iswpunct_l(wint_t c, locale_t l)
+{
+	return iswpunct(c);
+}
+
+weak_alias(__iswpunct_l, iswpunct_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswspace.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswspace.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswspace.c	(revision 398)
@@ -0,0 +1,25 @@
+#include <wchar.h>
+#include <wctype.h>
+#include "libc.h"
+
+/* Our definition of whitespace is the Unicode White_Space property,
+ * minus non-breaking spaces (U+00A0, U+2007, and U+202F) and script-
+ * specific characters with non-blank glyphs (U+1680 and U+180E). */
+
+int iswspace(wint_t wc)
+{
+	static const wchar_t spaces[] = {
+		' ', '\t', '\n', '\r', 11, 12,  0x0085,
+		0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,
+		0x2006, 0x2008, 0x2009, 0x200a,
+		0x2028, 0x2029, 0x205f, 0x3000, 0
+	};
+	return wc && wcschr(spaces, wc);
+}
+
+int __iswspace_l(wint_t c, locale_t l)
+{
+	return iswspace(c);
+}
+
+weak_alias(__iswspace_l, iswspace_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswupper.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswupper.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswupper.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <wctype.h>
+#include "libc.h"
+
+int iswupper(wint_t wc)
+{
+	return towlower(wc) != wc;
+}
+
+int __iswupper_l(wint_t c, locale_t l)
+{
+	return iswupper(c);
+}
+
+weak_alias(__iswupper_l, iswupper_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswxdigit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswxdigit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/iswxdigit.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <wctype.h>
+#include "libc.h"
+
+int iswxdigit(wint_t wc)
+{
+	return (unsigned)(wc-'0') < 10 || (unsigned)((wc|32)-'a') < 6;
+}
+
+int __iswxdigit_l(wint_t c, locale_t l)
+{
+	return iswxdigit(c);
+}
+
+weak_alias(__iswxdigit_l, iswxdigit_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isxdigit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isxdigit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/isxdigit.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <ctype.h>
+#include "libc.h"
+
+int isxdigit(int c)
+{
+	return isdigit(c) || ((unsigned)c|32)-'a' < 6;
+}
+
+int __isxdigit_l(int c, locale_t l)
+{
+	return isxdigit(c);
+}
+
+weak_alias(__isxdigit_l, isxdigit_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/nonspacing.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/nonspacing.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/nonspacing.h	(revision 398)
@@ -0,0 +1,62 @@
+16,16,16,18,19,20,21,22,23,24,25,26,27,28,29,30,31,16,16,32,16,16,16,33,34,35,
+36,37,38,39,16,16,40,16,16,16,16,16,16,16,16,16,16,16,41,42,16,16,43,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,44,16,45,46,47,48,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,49,16,16,50,51,16,52,16,16,
+16,16,16,16,16,16,53,16,16,16,16,16,54,55,16,16,16,16,56,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,57,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,58,59,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,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,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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,248,3,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,254,255,255,255,255,191,
+182,0,0,0,0,0,0,0,31,0,255,7,0,0,0,0,0,248,255,255,0,0,1,0,0,0,0,0,0,0,0,0,0,
+0,192,191,159,61,0,0,0,128,2,0,0,0,255,255,255,7,0,0,0,0,0,0,0,0,0,0,192,255,
+1,0,0,0,0,0,0,248,15,0,0,0,192,251,239,62,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,240,255,255,127,7,0,0,0,0,0,0,20,254,33,254,0,12,0,0,0,2,0,0,0,0,0,
+0,16,30,32,0,0,12,0,0,0,6,0,0,0,0,0,0,16,134,57,2,0,0,0,35,0,6,0,0,0,0,0,0,16,
+190,33,0,0,12,0,0,0,2,0,0,0,0,0,0,144,30,32,64,0,12,0,0,0,4,0,0,0,0,0,0,0,1,
+32,0,0,0,0,0,0,0,0,0,0,0,0,0,192,193,61,96,0,12,0,0,0,0,0,0,0,0,0,0,144,64,48,
+0,0,12,0,0,0,0,0,0,0,0,0,0,0,30,32,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,4,92,0,0,0,
+0,0,0,0,0,0,0,0,242,7,128,127,0,0,0,0,0,0,0,0,0,0,0,0,242,27,0,63,0,0,0,0,0,0,
+0,0,0,3,0,0,160,2,0,0,0,0,0,0,254,127,223,224,255,254,255,255,255,31,64,0,0,0,
+0,0,0,0,0,0,0,0,0,224,253,102,0,0,0,195,1,0,30,0,100,32,0,32,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+28,0,0,0,28,0,0,0,12,0,0,0,12,0,0,0,0,0,0,0,176,63,64,254,15,32,0,0,0,0,0,56,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,135,1,4,
+14,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,128,1,0,0,0,0,0,0,64,
+127,229,31,248,159,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,208,23,4,0,0,
+0,0,248,15,0,3,0,0,0,60,11,0,0,0,0,0,0,64,163,3,0,0,0,0,0,0,240,207,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,247,255,253,33,16,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,255,255,255,255,127,0,0,240,0,248,0,0,0,124,0,0,0,0,0,0,31,
+252,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,1,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,128,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,
+0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,6,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,128,247,63,0,0,0,128,0,0,0,0,0,
+0,0,0,0,0,3,0,68,8,0,0,96,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,255,
+255,3,0,0,0,0,0,192,63,0,0,128,255,3,0,0,0,0,0,7,0,0,0,0,0,200,19,0,0,0,0,0,0,
+0,0,0,0,0,0,0,126,102,0,8,16,0,0,0,0,0,0,0,0,0,0,0,0,157,193,2,0,0,0,0,48,64,
+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,32,33,0,0,0,0,0,64,
+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,255,255,0,0,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,128,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,14,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,32,110,240,0,0,0,0,0,135,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,255,127,0,0,0,0,0,0,0,3,0,0,0,0,0,120,38,0,0,
+0,0,0,0,0,0,7,0,0,0,128,239,31,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,192,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,40,191,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,128,7,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,128,3,248,255,231,15,0,0,0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/punct.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/punct.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/punct.h	(revision 398)
@@ -0,0 +1,109 @@
+18,16,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,16,16,34,35,16,36,37,38,39,
+40,41,42,43,16,44,45,46,17,47,48,17,17,49,17,17,17,50,51,52,53,54,55,56,57,17,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,58,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,59,16,60,61,62,63,64,65,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,66,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,67,16,16,68,16,69,70,71,16,72,16,73,
+16,16,16,16,74,75,76,77,16,16,78,16,79,80,16,16,16,16,81,16,16,16,16,16,16,16,
+16,16,16,16,16,16,82,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,83,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,84,85,86,87,
+16,16,88,89,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+90,16,91,92,93,94,95,96,97,98,16,16,16,16,16,16,16,16,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,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,0,0,0,0,254,255,0,252,1,0,0,248,1,0,0,120,0,0,0,0,255,251,223,
+251,0,0,128,0,0,0,128,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,60,0,
+252,255,224,175,255,255,255,255,255,255,255,255,255,255,223,255,255,255,255,
+255,32,64,176,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+252,3,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,252,0,0,0,0,0,134,254,
+255,255,255,0,64,73,0,0,0,0,0,24,0,223,255,0,200,0,0,0,0,0,0,0,1,0,60,0,0,0,0,
+0,0,0,0,0,0,0,0,16,224,1,30,0,96,255,191,0,0,0,0,0,0,255,7,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,248,207,3,0,0,0,3,0,32,255,127,0,0,0,78,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,252,0,0,0,0,0,0,0,0,0,16,0,32,30,0,48,0,1,0,0,0,0,0,0,0,0,16,
+0,32,0,0,0,0,252,15,0,0,0,0,0,0,0,16,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,32,0,
+0,0,0,3,0,0,0,0,0,0,0,0,16,0,32,0,0,0,0,253,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,
+255,7,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,255,0,0,0,0,0,0,0,16,0,32,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,32,0,0,0,0,63,2,0,0,0,0,0,0,0,0,0,4,0,0,0,0,16,0,0,0,0,0,0,
+128,0,128,192,223,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,254,255,255,
+255,0,252,255,255,0,0,0,0,0,0,0,0,252,0,0,0,0,0,0,192,255,223,255,7,0,0,0,0,0,
+0,0,0,0,0,128,6,0,252,0,0,24,62,0,0,128,191,0,204,0,0,0,0,0,0,0,0,0,0,0,8,0,0,
+0,0,0,0,0,0,0,0,0,96,255,255,255,31,0,0,255,3,0,0,0,0,0,0,0,0,0,0,0,0,1,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,96,0,0,1,0,0,24,0,0,0,0,0,0,0,0,0,56,0,0,0,0,16,0,0,0,112,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,48,0,0,254,127,47,0,0,255,3,255,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,0,0,0,0,0,14,49,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,196,255,255,255,255,0,0,0,192,0,0,0,0,0,0,0,0,1,0,224,159,0,0,0,0,
+127,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,16,0,0,252,255,255,255,31,0,0,0,0,
+0,12,0,0,0,0,0,0,64,0,12,240,0,0,0,0,0,0,192,248,0,0,0,0,0,0,0,192,0,0,0,0,0,
+0,0,0,255,0,255,255,255,33,16,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,255,255,255,255,127,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+160,3,224,0,224,0,224,0,96,128,248,255,255,255,252,255,255,255,255,255,127,31,
+252,241,127,255,127,0,0,255,255,255,3,0,0,255,255,255,255,1,0,123,3,208,193,
+175,66,0,12,31,188,255,255,0,0,0,0,0,2,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,15,0,255,255,
+255,255,127,0,0,0,255,7,0,0,255,255,255,255,255,255,255,255,255,255,63,0,0,0,
+0,0,0,252,255,255,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,31,255,3,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,224,135,3,254,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,
+127,255,15,0,0,0,0,0,0,0,0,255,255,255,251,255,255,255,255,255,255,255,255,
+255,255,15,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,63,0,0,0,255,15,30,255,255,255,1,252,
+193,224,0,0,0,0,0,0,0,0,0,0,0,30,1,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,255,255,0,0,0,0,255,255,255,255,15,0,0,0,255,255,255,127,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,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,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
+255,255,255,255,127,0,0,0,0,0,0,192,0,224,0,0,0,0,0,0,0,0,0,0,0,128,15,112,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,255,127,0,3,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,68,8,0,0,0,15,255,3,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,
+16,192,0,0,255,255,3,7,0,0,0,0,0,248,0,0,0,0,8,128,0,0,0,0,0,0,0,0,0,0,8,0,
+255,63,0,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,0,0,128,11,0,0,0,0,0,0,0,128,2,
+0,0,192,0,0,67,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,56,
+0,0,1,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,128,0,0,0,0,0,2,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,252,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,255,255,255,3,127,0,255,255,255,255,247,
+255,127,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,254,255,0,252,1,0,0,248,1,0,
+0,248,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,0,48,135,255,255,255,255,255,
+143,255,0,0,0,0,0,0,224,255,255,7,255,15,0,0,0,0,0,0,255,255,255,255,255,63,0,
+0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,128,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,143,0,0,0,128,
+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,135,255,0,255,1,
+0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,0,0,0,255,0,0,0,
+255,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,255,255,255,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,192,63,252,255,63,0,0,0,3,0,0,0,
+0,0,0,254,3,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+225,1,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,192,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,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,128,7,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,63,0,255,255,255,255,127,254,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,
+255,255,255,255,255,255,255,255,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,255,255,255,255,255,255,255,255,255,255,127,0,255,255,3,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,2,0,0,8,0,0,0,
+8,0,0,32,0,0,0,32,0,0,128,0,0,0,128,0,0,0,2,0,0,0,2,0,0,8,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,3,0,255,255,255,255,255,
+15,255,255,255,255,255,255,255,255,255,255,255,255,15,0,255,127,254,127,254,
+255,254,255,0,0,0,0,255,7,255,255,255,127,255,255,255,255,255,255,255,15,255,
+255,255,255,255,7,0,0,0,0,0,0,0,0,192,255,255,255,7,0,255,255,255,255,255,7,
+255,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,1,0,191,255,
+255,255,255,255,255,255,255,31,255,255,15,0,255,255,255,255,223,7,0,0,255,255,
+1,0,255,255,255,255,255,255,255,127,253,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,30,255,255,255,255,255,
+255,255,63,15,0,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,255,255,
+255,255,255,255,255,255,225,255,0,0,0,0,0,0,255,255,255,255,255,255,255,255,
+63,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,15,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/toascii.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/toascii.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/toascii.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <ctype.h>
+
+/* nonsense function that should NEVER be used! */
+int toascii(int c)
+{
+	return c & 0x7f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/tolower.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/tolower.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/tolower.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <ctype.h>
+#include "libc.h"
+
+int tolower(int c)
+{
+	if (isupper(c)) return c | 32;
+	return c;
+}
+
+int __tolower_l(int c, locale_t l)
+{
+	return tolower(c);
+}
+
+weak_alias(__tolower_l, tolower_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/toupper.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/toupper.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/toupper.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <ctype.h>
+#include "libc.h"
+
+int toupper(int c)
+{
+	if (islower(c)) return c & 0x5f;
+	return c;
+}
+
+int __toupper_l(int c, locale_t l)
+{
+	return toupper(c);
+}
+
+weak_alias(__toupper_l, toupper_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/towctrans.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/towctrans.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/towctrans.c	(revision 398)
@@ -0,0 +1,279 @@
+#include <ctype.h>
+#include <wctype.h>
+#include "libc.h"
+
+#define CASEMAP(u1,u2,l) { (u1), (l)-(u1), (u2)-(u1)+1 }
+#define CASELACE(u1,u2) CASEMAP((u1),(u2),(u1)+1)
+
+static const struct {
+	unsigned short upper;
+	signed char lower;
+	unsigned char len;
+} casemaps[] = {
+	CASEMAP(0xc0,0xde,0xe0),
+
+	CASELACE(0x0100,0x012e),
+	CASELACE(0x0132,0x0136),
+	CASELACE(0x0139,0x0147),
+	CASELACE(0x014a,0x0176),
+	CASELACE(0x0179,0x017d),
+
+	CASELACE(0x370,0x372),
+	CASEMAP(0x391,0x3a1,0x3b1),
+	CASEMAP(0x3a3,0x3ab,0x3c3),
+	CASEMAP(0x400,0x40f,0x450),
+	CASEMAP(0x410,0x42f,0x430),
+
+	CASELACE(0x460,0x480),
+	CASELACE(0x48a,0x4be),
+	CASELACE(0x4c1,0x4cd),
+	CASELACE(0x4d0,0x50e),
+
+	CASELACE(0x514,0x526),
+	CASEMAP(0x531,0x556,0x561),
+
+	CASELACE(0x01a0,0x01a4),
+	CASELACE(0x01b3,0x01b5),
+	CASELACE(0x01cd,0x01db),
+	CASELACE(0x01de,0x01ee),
+	CASELACE(0x01f8,0x021e),
+	CASELACE(0x0222,0x0232),
+	CASELACE(0x03d8,0x03ee),
+
+	CASELACE(0x1e00,0x1e94),
+	CASELACE(0x1ea0,0x1efe),
+
+	CASEMAP(0x1f08,0x1f0f,0x1f00),
+	CASEMAP(0x1f18,0x1f1d,0x1f10),
+	CASEMAP(0x1f28,0x1f2f,0x1f20),
+	CASEMAP(0x1f38,0x1f3f,0x1f30),
+	CASEMAP(0x1f48,0x1f4d,0x1f40),
+
+	CASEMAP(0x1f68,0x1f6f,0x1f60),
+	CASEMAP(0x1f88,0x1f8f,0x1f80),
+	CASEMAP(0x1f98,0x1f9f,0x1f90),
+	CASEMAP(0x1fa8,0x1faf,0x1fa0),
+	CASEMAP(0x1fb8,0x1fb9,0x1fb0),
+	CASEMAP(0x1fba,0x1fbb,0x1f70),
+	CASEMAP(0x1fc8,0x1fcb,0x1f72),
+	CASEMAP(0x1fd8,0x1fd9,0x1fd0),
+	CASEMAP(0x1fda,0x1fdb,0x1f76),
+	CASEMAP(0x1fe8,0x1fe9,0x1fe0),
+	CASEMAP(0x1fea,0x1feb,0x1f7a),
+	CASEMAP(0x1ff8,0x1ff9,0x1f78),
+	CASEMAP(0x1ffa,0x1ffb,0x1f7c),
+
+	CASELACE(0x246,0x24e),
+	CASELACE(0x510,0x512),
+	CASEMAP(0x2160,0x216f,0x2170),
+	CASEMAP(0x2c00,0x2c2e,0x2c30),
+	CASELACE(0x2c67,0x2c6b),
+	CASELACE(0x2c80,0x2ce2),
+	CASELACE(0x2ceb,0x2ced),
+
+	CASELACE(0xa640,0xa66c),
+	CASELACE(0xa680,0xa696),
+
+	CASELACE(0xa722,0xa72e),
+	CASELACE(0xa732,0xa76e),
+	CASELACE(0xa779,0xa77b),
+	CASELACE(0xa77e,0xa786),
+
+	CASELACE(0xa790,0xa792),
+	CASELACE(0xa7a0,0xa7a8),
+
+	CASEMAP(0xff21,0xff3a,0xff41),
+	{ 0,0,0 }
+};
+
+static const unsigned short pairs[][2] = {
+	{ 'I',    0x0131 },
+	{ 'S',    0x017f },
+	{ 0x0130, 'i'    },
+	{ 0x0178, 0x00ff },
+	{ 0x0181, 0x0253 },
+	{ 0x0182, 0x0183 },
+	{ 0x0184, 0x0185 },
+	{ 0x0186, 0x0254 },
+	{ 0x0187, 0x0188 },
+	{ 0x0189, 0x0256 },
+	{ 0x018a, 0x0257 },
+	{ 0x018b, 0x018c },
+	{ 0x018e, 0x01dd },
+	{ 0x018f, 0x0259 },
+	{ 0x0190, 0x025b },
+	{ 0x0191, 0x0192 },
+	{ 0x0193, 0x0260 },
+	{ 0x0194, 0x0263 },
+	{ 0x0196, 0x0269 },
+	{ 0x0197, 0x0268 },
+	{ 0x0198, 0x0199 },
+	{ 0x019c, 0x026f },
+	{ 0x019d, 0x0272 },
+	{ 0x019f, 0x0275 },
+	{ 0x01a6, 0x0280 },
+	{ 0x01a7, 0x01a8 },
+	{ 0x01a9, 0x0283 },
+	{ 0x01ac, 0x01ad },
+	{ 0x01ae, 0x0288 },
+	{ 0x01af, 0x01b0 },
+	{ 0x01b1, 0x028a },
+	{ 0x01b2, 0x028b },
+	{ 0x01b7, 0x0292 },
+	{ 0x01b8, 0x01b9 },
+	{ 0x01bc, 0x01bd },
+	{ 0x01c4, 0x01c6 },
+	{ 0x01c4, 0x01c5 },
+	{ 0x01c5, 0x01c6 },
+	{ 0x01c7, 0x01c9 },
+	{ 0x01c7, 0x01c8 },
+	{ 0x01c8, 0x01c9 },
+	{ 0x01ca, 0x01cc },
+	{ 0x01ca, 0x01cb },
+	{ 0x01cb, 0x01cc },
+	{ 0x01f1, 0x01f3 },
+	{ 0x01f1, 0x01f2 },
+	{ 0x01f2, 0x01f3 },
+	{ 0x01f4, 0x01f5 },
+	{ 0x01f6, 0x0195 },
+	{ 0x01f7, 0x01bf },
+	{ 0x0220, 0x019e },
+	{ 0x0386, 0x03ac },
+	{ 0x0388, 0x03ad },
+	{ 0x0389, 0x03ae },
+	{ 0x038a, 0x03af },
+	{ 0x038c, 0x03cc },
+	{ 0x038e, 0x03cd },
+	{ 0x038f, 0x03ce },
+	{ 0x0399, 0x0345 },
+	{ 0x0399, 0x1fbe },
+	{ 0x03a3, 0x03c2 },
+	{ 0x03f7, 0x03f8 },
+	{ 0x03fa, 0x03fb },
+	{ 0x1e60, 0x1e9b },
+	{ 0x1e9e, 0xdf },
+
+	{ 0x1f59, 0x1f51 },
+	{ 0x1f5b, 0x1f53 },
+	{ 0x1f5d, 0x1f55 },
+	{ 0x1f5f, 0x1f57 },
+	{ 0x1fbc, 0x1fb3 },
+	{ 0x1fcc, 0x1fc3 },
+	{ 0x1fec, 0x1fe5 },
+	{ 0x1ffc, 0x1ff3 },
+
+	{ 0x23a, 0x2c65 },
+	{ 0x23b, 0x23c },
+	{ 0x23d, 0x19a },
+	{ 0x23e, 0x2c66 },
+	{ 0x241, 0x242 },
+	{ 0x243, 0x180 },
+	{ 0x244, 0x289 },
+	{ 0x245, 0x28c },
+	{ 0x3f4, 0x3b8 },
+	{ 0x3f9, 0x3f2 },
+	{ 0x3fd, 0x37b },
+	{ 0x3fe, 0x37c },
+	{ 0x3ff, 0x37d },
+	{ 0x4c0, 0x4cf },
+
+	{ 0x2126, 0x3c9 },
+	{ 0x212a, 'k' },
+	{ 0x212b, 0xe5 },
+	{ 0x2132, 0x214e },
+	{ 0x2183, 0x2184 },
+	{ 0x2c60, 0x2c61 },
+	{ 0x2c62, 0x26b },
+	{ 0x2c63, 0x1d7d },
+	{ 0x2c64, 0x27d },
+	{ 0x2c6d, 0x251 },
+	{ 0x2c6e, 0x271 },
+	{ 0x2c6f, 0x250 },
+	{ 0x2c70, 0x252 },
+	{ 0x2c72, 0x2c73 },
+	{ 0x2c75, 0x2c76 },
+	{ 0x2c7e, 0x23f },
+	{ 0x2c7f, 0x240 },
+	{ 0x2cf2, 0x2cf3 },
+
+	{ 0xa77d, 0x1d79 },
+	{ 0xa78b, 0xa78c },
+	{ 0xa78d, 0x265 },
+	{ 0xa7aa, 0x266 },
+
+	{ 0x10c7, 0x2d27 },
+	{ 0x10cd, 0x2d2d },
+
+	/* bogus greek 'symbol' letters */
+	{ 0x376, 0x377 },
+	{ 0x39c, 0xb5 },
+	{ 0x392, 0x3d0 },
+	{ 0x398, 0x3d1 },
+	{ 0x3a6, 0x3d5 },
+	{ 0x3a0, 0x3d6 },
+	{ 0x39a, 0x3f0 },
+	{ 0x3a1, 0x3f1 },
+	{ 0x395, 0x3f5 },
+	{ 0x3cf, 0x3d7 },
+
+	{ 0,0 }
+};
+
+
+static wchar_t __towcase(wchar_t wc, int lower)
+{
+	int i;
+	int lmul = 2*lower-1;
+	int lmask = lower-1;
+	/* no letters with case in these large ranges */
+	if (!iswalpha(wc)
+	 || (unsigned)wc - 0x0600 <= 0x0fff-0x0600
+	 || (unsigned)wc - 0x2e00 <= 0xa63f-0x2e00
+	 || (unsigned)wc - 0xa800 <= 0xfeff-0xa800)
+		return wc;
+	/* special case because the diff between upper/lower is too big */
+	if (lower && (unsigned)wc - 0x10a0 < 0x2e)
+		if (wc>0x10c5 && wc != 0x10c7 && wc != 0x10cd) return wc;
+		else return wc + 0x2d00 - 0x10a0;
+	if (!lower && (unsigned)wc - 0x2d00 < 0x26)
+		if (wc>0x2d25 && wc != 0x2d27 && wc != 0x2d2d) return wc;
+		else return wc + 0x10a0 - 0x2d00;
+	for (i=0; casemaps[i].len; i++) {
+		int base = casemaps[i].upper + (lmask & casemaps[i].lower);
+		if ((unsigned)wc-base < casemaps[i].len) {
+			if (casemaps[i].lower == 1)
+				return wc + lower - ((wc-casemaps[i].upper)&1);
+			return wc + lmul*casemaps[i].lower;
+		}
+	}
+	for (i=0; pairs[i][1-lower]; i++) {
+		if (pairs[i][1-lower] == wc)
+			return pairs[i][lower];
+	}
+	if ((unsigned)wc - (0x10428 - 0x28*lower) < 0x28)
+		return wc - 0x28 + 0x50*lower;
+	return wc;
+}
+
+wint_t towupper(wint_t wc)
+{
+	return (unsigned)wc < 128 ? toupper(wc) : __towcase(wc, 0);
+}
+
+wint_t towlower(wint_t wc)
+{
+	return (unsigned)wc < 128 ? tolower(wc) : __towcase(wc, 1);
+}
+
+wint_t __towupper_l(wint_t c, locale_t l)
+{
+	return towupper(c);
+}
+
+wint_t __towlower_l(wint_t c, locale_t l)
+{
+	return towlower(c);
+}
+
+weak_alias(__towupper_l, towupper_l);
+weak_alias(__towlower_l, towlower_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wcswidth.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wcswidth.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wcswidth.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+int wcswidth(const wchar_t *wcs, size_t n)
+{
+	int l=0, k=0;
+	for (; n-- && *wcs && (k = wcwidth(*wcs)) >= 0; l+=k, wcs++);
+	return (k < 0) ? k : l;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wctrans.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wctrans.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wctrans.c	(revision 398)
@@ -0,0 +1,30 @@
+#include <wctype.h>
+#include <string.h>
+#include "libc.h"
+
+wctrans_t wctrans(const char *class)
+{
+	if (!strcmp(class, "toupper")) return (wctrans_t)1;
+	if (!strcmp(class, "tolower")) return (wctrans_t)2;
+	return 0;
+}
+
+wint_t towctrans(wint_t wc, wctrans_t trans)
+{
+	if (trans == (wctrans_t)1) return towupper(wc);
+	if (trans == (wctrans_t)2) return towlower(wc);
+	return wc;
+}
+
+wctrans_t __wctrans_l(const char *s, locale_t l)
+{
+	return wctrans(s);
+}
+
+wint_t __towctrans_l(wint_t c, wctrans_t t, locale_t l)
+{
+	return towctrans(c, t);
+}
+
+weak_alias(__wctrans_l, wctrans_l);
+weak_alias(__towctrans_l, towctrans_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wcwidth.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wcwidth.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wcwidth.c	(revision 398)
@@ -0,0 +1,29 @@
+#include <wchar.h>
+
+static const unsigned char table[] = {
+#include "nonspacing.h"
+};
+
+static const unsigned char wtable[] = {
+#include "wide.h"
+};
+
+int wcwidth(wchar_t wc)
+{
+	if (wc < 0xffU)
+		return (wc+1 & 0x7f) >= 0x21 ? 1 : wc ? -1 : 0;
+	if ((wc & 0xfffeffffU) < 0xfffe) {
+		if ((table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1)
+			return 0;
+		if ((wtable[wtable[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1)
+			return 2;
+		return 1;
+	}
+	if ((wc & 0xfffe) == 0xfffe)
+		return -1;
+	if (wc-0x20000U < 0x20000)
+		return 2;
+	if (wc == 0xe0001 || wc-0xe0020U < 0x5f || wc-0xe0100 < 0xef)
+		return 0;
+	return 1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wide.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wide.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ctype/wide.h	(revision 398)
@@ -0,0 +1,42 @@
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,19,16,16,16,16,16,16,16,16,16,16,20,21,22,23,24,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,25,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,26,16,16,16,16,27,16,16,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,28,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,16,16,16,29,30,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,31,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,32,16,16,16,16,16,16,16,16,16,16,16,16,16,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,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,
+0,248,0,0,0,0,0,0,0,0,0,0,252,0,0,0,0,0,6,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,255,255,255,251,255,255,255,
+255,255,255,255,255,255,255,15,0,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,63,0,0,0,255,15,
+255,255,255,255,255,255,255,127,254,255,255,255,255,255,255,255,255,255,127,
+254,255,255,255,255,255,255,255,255,255,255,255,255,224,255,255,255,255,63,
+254,255,255,255,255,255,255,255,255,255,255,127,255,255,255,255,255,7,255,255,
+255,255,15,0,255,255,255,255,255,127,255,255,255,255,255,0,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,127,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,31,255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,255,255,255,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,15,0,255,
+255,127,248,255,255,255,255,255,15,0,0,255,3,0,0,255,255,255,255,247,255,127,
+15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,255,255,255,255,255,255,255,255,
+255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,3,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,7,0,255,255,255,255,255,7,255,1,3,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/__dirent.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/__dirent.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/__dirent.h	(revision 398)
@@ -0,0 +1,9 @@
+struct __dirstream
+{
+	int fd;
+	off_t tell;
+	int buf_pos;
+	int buf_end;
+	volatile int lock[2];
+	char buf[2048];
+};
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/__getdents.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/__getdents.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/__getdents.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <dirent.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __getdents(int fd, struct dirent *buf, size_t len)
+{
+	return syscall(SYS_getdents, fd, buf, len);
+}
+
+weak_alias(__getdents, getdents);
+
+LFS64(getdents);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/alphasort.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/alphasort.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/alphasort.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <string.h>
+#include <dirent.h>
+#include "libc.h"
+
+int alphasort(const struct dirent **a, const struct dirent **b)
+{
+	return strcoll((*a)->d_name, (*b)->d_name);
+}
+
+LFS64(alphasort);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/closedir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/closedir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/closedir.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <dirent.h>
+#include <unistd.h>
+#include "__dirent.h"
+#include "libc.h"
+
+int closedir(DIR *dir)
+{
+	int ret = close(dir->fd);
+	free(dir);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/dirfd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/dirfd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/dirfd.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <dirent.h>
+#include "__dirent.h"
+
+int dirfd(DIR *d)
+{
+	return d->fd;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/fdopendir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/fdopendir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/fdopendir.c	(revision 398)
@@ -0,0 +1,27 @@
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "__dirent.h"
+
+DIR *fdopendir(int fd)
+{
+	DIR *dir;
+	struct stat st;
+
+	if (fstat(fd, &st) < 0) {
+		return 0;
+	}
+	if (!S_ISDIR(st.st_mode)) {
+		errno = ENOTDIR;
+		return 0;
+	}
+	if (!(dir = calloc(1, sizeof *dir))) {
+		return 0;
+	}
+
+	fcntl(fd, F_SETFD, FD_CLOEXEC);
+	dir->fd = fd;
+	return dir;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/opendir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/opendir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/opendir.c	(revision 398)
@@ -0,0 +1,21 @@
+#define _GNU_SOURCE
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include "__dirent.h"
+#include "syscall.h"
+
+DIR *opendir(const char *name)
+{
+	int fd;
+	DIR *dir;
+
+	if ((fd = open(name, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) < 0)
+		return 0;
+	if (!(dir = calloc(1, sizeof *dir))) {
+		__syscall(SYS_close, fd);
+		return 0;
+	}
+	dir->fd = fd;
+	return dir;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/readdir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/readdir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/readdir.c	(revision 398)
@@ -0,0 +1,28 @@
+#include <dirent.h>
+#include <errno.h>
+#include "__dirent.h"
+#include "syscall.h"
+#include "libc.h"
+
+int __getdents(int, struct dirent *, size_t);
+
+struct dirent *readdir(DIR *dir)
+{
+	struct dirent *de;
+	
+	if (dir->buf_pos >= dir->buf_end) {
+		int len = __syscall(SYS_getdents, dir->fd, dir->buf, sizeof dir->buf);
+		if (len <= 0) {
+			if (len < 0 && len != -ENOENT) errno = -len;
+			return 0;
+		}
+		dir->buf_end = len;
+		dir->buf_pos = 0;
+	}
+	de = (void *)(dir->buf + dir->buf_pos);
+	dir->buf_pos += de->d_reclen;
+	dir->tell = de->d_off;
+	return de;
+}
+
+LFS64(readdir);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/readdir_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/readdir_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/readdir_r.c	(revision 398)
@@ -0,0 +1,29 @@
+#include <dirent.h>
+#include <errno.h>
+#include <string.h>
+#include "__dirent.h"
+#include "libc.h"
+
+int readdir_r(DIR *restrict dir, struct dirent *restrict buf, struct dirent **restrict result)
+{
+	struct dirent *de;
+	int errno_save = errno;
+	int ret;
+	
+	LOCK(dir->lock);
+	errno = 0;
+	de = readdir(dir);
+	if ((ret = errno)) {
+		UNLOCK(dir->lock);
+		return ret;
+	}
+	errno = errno_save;
+	if (de) memcpy(buf, de, de->d_reclen);
+	else buf = NULL;
+
+	UNLOCK(dir->lock);
+	*result = buf;
+	return 0;
+}
+
+LFS64_2(readdir_r, readdir64_r);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/rewinddir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/rewinddir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/rewinddir.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <dirent.h>
+#include <unistd.h>
+#include "__dirent.h"
+#include "libc.h"
+
+void rewinddir(DIR *dir)
+{
+	LOCK(dir->lock);
+	lseek(dir->fd, 0, SEEK_SET);
+	dir->buf_pos = dir->buf_end = 0;
+	dir->tell = 0;
+	UNLOCK(dir->lock);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/scandir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/scandir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/scandir.c	(revision 398)
@@ -0,0 +1,48 @@
+#include <dirent.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <stddef.h>
+#include "libc.h"
+
+int scandir(const char *path, struct dirent ***res,
+	int (*sel)(const struct dirent *),
+	int (*cmp)(const struct dirent **, const struct dirent **))
+{
+	DIR *d = opendir(path);
+	struct dirent *de, **names=0, **tmp;
+	size_t cnt=0, len=0;
+	int old_errno = errno;
+
+	if (!d) return -1;
+
+	while ((errno=0), (de = readdir(d))) {
+		if (sel && !sel(de)) continue;
+		if (cnt >= len) {
+			len = 2*len+1;
+			if (len > SIZE_MAX/sizeof *names) break;
+			tmp = realloc(names, len * sizeof *names);
+			if (!tmp) break;
+			names = tmp;
+		}
+		names[cnt] = malloc(de->d_reclen);
+		if (!names[cnt]) break;
+		memcpy(names[cnt++], de, de->d_reclen);
+	}
+
+	closedir(d);
+
+	if (errno) {
+		if (names) while (cnt-->0) free(names[cnt]);
+		free(names);
+		return -1;
+	}
+	errno = old_errno;
+
+	if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp);
+	*res = names;
+	return cnt;
+}
+
+LFS64(scandir);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/seekdir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/seekdir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/seekdir.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <dirent.h>
+#include <unistd.h>
+#include "__dirent.h"
+#include "libc.h"
+
+void seekdir(DIR *dir, long off)
+{
+	LOCK(dir->lock);
+	dir->tell = lseek(dir->fd, off, SEEK_SET);
+	dir->buf_pos = dir->buf_end = 0;
+	UNLOCK(dir->lock);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/telldir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/telldir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/telldir.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <dirent.h>
+#include "__dirent.h"
+
+long telldir(DIR *dir)
+{
+	return dir->tell;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/versionsort.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/versionsort.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/dirent/versionsort.c	(revision 398)
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <dirent.h>
+#include "libc.h"
+
+int versionsort(const struct dirent **a, const struct dirent **b)
+{
+	return strverscmp((*a)->d_name, (*b)->d_name);
+}
+
+#undef versionsort64
+LFS64(versionsort);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__environ.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__environ.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__environ.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "libc.h"
+
+char **__environ = 0;
+weak_alias(__environ, ___environ);
+weak_alias(__environ, _environ);
+weak_alias(__environ, environ);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__init_tls.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__init_tls.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__init_tls.c	(revision 398)
@@ -0,0 +1,136 @@
+#include <elf.h>
+#include <limits.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <stddef.h>
+#include "pthread_impl.h"
+#include "libc.h"
+#include "atomic.h"
+#include "syscall.h"
+
+int __init_tp(void *p)
+{
+	pthread_t td = p;
+	td->self = td;
+	int r = __set_thread_area(TP_ADJ(p));
+	if (r < 0) return -1;
+	if (!r) libc.can_do_threads = 1;
+	td->tid = __syscall(SYS_set_tid_address, &td->tid);
+	td->locale = &libc.global_locale;
+	td->robust_list.head = &td->robust_list.head;
+	return 0;
+}
+
+static struct builtin_tls {
+	char c;
+	struct pthread pt;
+	void *space[16];
+} builtin_tls[1];
+#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
+
+static struct tls_module main_tls;
+
+void *__copy_tls(unsigned char *mem)
+{
+	pthread_t td;
+	struct tls_module *p;
+	size_t i;
+	void **dtv;
+
+#ifdef TLS_ABOVE_TP
+	dtv = (void **)(mem + libc.tls_size) - (libc.tls_cnt + 1);
+
+	mem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align-1);
+	td = (pthread_t)mem;
+	mem += sizeof(struct pthread);
+
+	for (i=1, p=libc.tls_head; p; i++, p=p->next) {
+		dtv[i] = mem + p->offset;
+		memcpy(dtv[i], p->image, p->len);
+	}
+#else
+	dtv = (void **)mem;
+
+	mem += libc.tls_size - sizeof(struct pthread);
+	mem -= (uintptr_t)mem & (libc.tls_align-1);
+	td = (pthread_t)mem;
+
+	for (i=1, p=libc.tls_head; p; i++, p=p->next) {
+		dtv[i] = mem - p->offset;
+		memcpy(dtv[i], p->image, p->len);
+	}
+#endif
+	dtv[0] = (void *)libc.tls_cnt;
+	td->dtv = td->dtv_copy = dtv;
+	return td;
+}
+
+#if ULONG_MAX == 0xffffffff
+typedef Elf32_Phdr Phdr;
+#else
+typedef Elf64_Phdr Phdr;
+#endif
+
+__attribute__((__weak__, __visibility__("hidden")))
+extern const size_t _DYNAMIC[];
+
+static void static_init_tls(size_t *aux)
+{
+	unsigned char *p;
+	size_t n;
+	Phdr *phdr, *tls_phdr=0;
+	size_t base = 0;
+	void *mem;
+
+	for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
+		phdr = (void *)p;
+		if (phdr->p_type == PT_PHDR)
+			base = aux[AT_PHDR] - phdr->p_vaddr;
+		if (phdr->p_type == PT_DYNAMIC && _DYNAMIC)
+			base = (size_t)_DYNAMIC - phdr->p_vaddr;
+		if (phdr->p_type == PT_TLS)
+			tls_phdr = phdr;
+	}
+
+	if (tls_phdr) {
+		main_tls.image = (void *)(base + tls_phdr->p_vaddr);
+		main_tls.len = tls_phdr->p_filesz;
+		main_tls.size = tls_phdr->p_memsz;
+		main_tls.align = tls_phdr->p_align;
+		libc.tls_cnt = 1;
+		libc.tls_head = &main_tls;
+	}
+
+	main_tls.size += (-main_tls.size - (uintptr_t)main_tls.image)
+		& (main_tls.align-1);
+	if (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN;
+#ifndef TLS_ABOVE_TP
+	main_tls.offset = main_tls.size;
+#endif
+
+	libc.tls_align = main_tls.align;
+	libc.tls_size = 2*sizeof(void *) + sizeof(struct pthread)
+		+ main_tls.size + main_tls.align
+		+ MIN_TLS_ALIGN-1 & -MIN_TLS_ALIGN;
+
+	if (libc.tls_size > sizeof builtin_tls) {
+#ifndef SYS_mmap2
+#define SYS_mmap2 SYS_mmap
+#endif
+		mem = (void *)__syscall(
+			SYS_mmap2,
+			0, libc.tls_size, PROT_READ|PROT_WRITE,
+			MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+		/* -4095...-1 cast to void * will crash on dereference anyway,
+		 * so don't bloat the init code checking for error codes and
+		 * explicitly calling a_crash(). */
+	} else {
+		mem = builtin_tls;
+	}
+
+	/* Failure to initialize thread pointer is always fatal. */
+	if (__init_tp(__copy_tls(mem)) < 0)
+		a_crash();
+}
+
+weak_alias(static_init_tls, __init_tls);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__libc_start_main.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__libc_start_main.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__libc_start_main.c	(revision 398)
@@ -0,0 +1,76 @@
+#include <elf.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <signal.h>
+#include "syscall.h"
+#include "atomic.h"
+#include "libc.h"
+
+void __init_tls(size_t *);
+
+static void dummy(void) {}
+weak_alias(dummy, _init);
+
+__attribute__((__weak__, __visibility__("hidden")))
+extern void (*const __init_array_start)(void), (*const __init_array_end)(void);
+
+static void dummy1(void *p) {}
+weak_alias(dummy1, __init_ssp);
+
+#define AUX_CNT 38
+
+void __init_libc(char **envp, char *pn)
+{
+	size_t i, *auxv, aux[AUX_CNT] = { 0 };
+	__environ = envp;
+	for (i=0; envp[i]; i++);
+	libc.auxv = auxv = (void *)(envp+i+1);
+	for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1];
+	__hwcap = aux[AT_HWCAP];
+	__sysinfo = aux[AT_SYSINFO];
+	libc.page_size = aux[AT_PAGESZ];
+
+	if (!pn) pn = (void*)aux[AT_EXECFN];
+	if (!pn) pn = "";
+	__progname = __progname_full = pn;
+	for (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1;
+
+	__init_tls(aux);
+	__init_ssp((void *)aux[AT_RANDOM]);
+
+	if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
+		&& !aux[AT_SECURE]) return;
+
+	struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} };
+#ifdef SYS_poll
+	__syscall(SYS_poll, pfd, 3, 0);
+#else
+	__syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG/8);
+#endif
+	for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL)
+		if (__sys_open("/dev/null", O_RDWR)<0)
+			a_crash();
+	libc.secure = 1;
+}
+
+static void libc_start_init(void)
+{
+	_init();
+	uintptr_t a = (uintptr_t)&__init_array_start;
+	for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
+		(*(void (**)(void))a)();
+}
+
+weak_alias(libc_start_init, __libc_start_init);
+
+int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
+{
+	char **envp = argv+argc+1;
+
+	__init_libc(envp, argv[0]);
+	__libc_start_init();
+
+	/* Pass control to the application */
+	exit(main(argc, argv, envp));
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__reset_tls.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__reset_tls.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__reset_tls.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <string.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+void __reset_tls()
+{
+	pthread_t self = __pthread_self();
+	struct tls_module *p;
+	size_t i, n = (size_t)self->dtv[0];
+	if (n) for (p=libc.tls_head, i=1; i<=n; i++, p=p->next) {
+		if (!self->dtv[i]) continue;
+		memcpy(self->dtv[i], p->image, p->len);
+		memset((char *)self->dtv[i]+p->len, 0,
+			p->size - p->len);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__stack_chk_fail.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__stack_chk_fail.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/__stack_chk_fail.c	(revision 398)
@@ -0,0 +1,23 @@
+#include <string.h>
+#include <stdint.h>
+#include "pthread_impl.h"
+
+uintptr_t __stack_chk_guard;
+
+void __init_ssp(void *entropy)
+{
+	if (entropy) memcpy(&__stack_chk_guard, entropy, sizeof(uintptr_t));
+	else __stack_chk_guard = (uintptr_t)&__stack_chk_guard * 1103515245;
+
+	__pthread_self()->CANARY = __stack_chk_guard;
+}
+
+void __stack_chk_fail(void)
+{
+	a_crash();
+}
+
+__attribute__((__visibility__("hidden")))
+void __stack_chk_fail_local(void);
+
+weak_alias(__stack_chk_fail, __stack_chk_fail_local);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/clearenv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/clearenv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/clearenv.c	(revision 398)
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include "libc.h"
+
+static void dummy(char *old, char *new) {}
+weak_alias(dummy, __env_rm_add);
+
+int clearenv()
+{
+	char **e = __environ;
+	__environ = 0;
+	if (e) while (*e) __env_rm_add(*e++, 0);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/getenv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/getenv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/getenv.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <string.h>
+#include "libc.h"
+
+char *__strchrnul(const char *, int);
+
+char *getenv(const char *name)
+{
+	size_t l = __strchrnul(name, '=') - name;
+	if (l && !name[l] && __environ)
+		for (char **e = __environ; *e; e++)
+			if (!strncmp(name, *e, l) && l[*e] == '=')
+				return *e + l+1;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/putenv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/putenv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/putenv.c	(revision 398)
@@ -0,0 +1,48 @@
+#include <stdlib.h>
+#include <string.h>
+#include "libc.h"
+
+char *__strchrnul(const char *, int);
+
+static void dummy(char *old, char *new) {}
+weak_alias(dummy, __env_rm_add);
+
+int __putenv(char *s, size_t l, char *r)
+{
+	size_t i=0;
+	if (__environ) {
+		for (char **e = __environ; *e; e++, i++)
+			if (!strncmp(s, *e, l+1)) {
+				char *tmp = *e;
+				*e = s;
+				__env_rm_add(tmp, r);
+				return 0;
+			}
+	}
+	static char **oldenv;
+	char **newenv;
+	if (__environ == oldenv) {
+		newenv = realloc(oldenv, sizeof *newenv * (i+2));
+		if (!newenv) goto oom;
+	} else {
+		newenv = malloc(sizeof *newenv * (i+2));
+		if (!newenv) goto oom;
+		if (i) memcpy(newenv, __environ, sizeof *newenv * i);
+		free(oldenv);
+	}
+	newenv[i] = s;
+	newenv[i+1] = 0;
+	__environ = oldenv = newenv;
+	if (r) __env_rm_add(0, r);
+	return 0;
+oom:
+	free(r);
+	return -1;
+}
+
+int putenv(char *s)
+{
+	size_t l = __strchrnul(s, '=') - s;
+	if (!l || !s[l]) return unsetenv(s);
+	return __putenv(s, l, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/setenv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/setenv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/setenv.c	(revision 398)
@@ -0,0 +1,45 @@
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+char *__strchrnul(const char *, int);
+int __putenv(char *, size_t, char *);
+
+void __env_rm_add(char *old, char *new)
+{
+	static char **env_alloced;
+	static size_t env_alloced_n;
+	for (size_t i=0; i < env_alloced_n; i++)
+		if (env_alloced[i] == old) {
+			env_alloced[i] = new;
+			free(old);
+			return;
+		} else if (!env_alloced[i] && new) {
+			env_alloced[i] = new;
+			new = 0;
+		}
+	if (!new) return;
+	char **t = realloc(env_alloced, sizeof *t * (env_alloced_n+1));
+	if (!t) return;
+	(env_alloced = t)[env_alloced_n++] = new;
+}
+
+int setenv(const char *var, const char *value, int overwrite)
+{
+	char *s;
+	size_t l1, l2;
+
+	if (!var || !(l1 = __strchrnul(var, '=') - var) || var[l1]) {
+		errno = EINVAL;
+		return -1;
+	}
+	if (!overwrite && getenv(var)) return 0;
+
+	l2 = strlen(value);
+	s = malloc(l1+l2+2);
+	if (!s) return -1;
+	memcpy(s, var, l1);
+	s[l1] = '=';
+	memcpy(s+l1+1, value, l2+1);
+	return __putenv(s, l1, s);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/unsetenv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/unsetenv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/env/unsetenv.c	(revision 398)
@@ -0,0 +1,30 @@
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "libc.h"
+
+char *__strchrnul(const char *, int);
+
+static void dummy(char *old, char *new) {}
+weak_alias(dummy, __env_rm_add);
+
+int unsetenv(const char *name)
+{
+	size_t l = __strchrnul(name, '=') - name;
+	if (!l || name[l]) {
+		errno = EINVAL;
+		return -1;
+	}
+	if (__environ) {
+		char **e = __environ, **eo = e;
+		for (; *e; e++)
+			if (!strncmp(name, *e, l) && l[*e] == '=')
+				__env_rm_add(*e, 0);
+			else if (eo != e)
+				*eo++ = *e;
+			else
+				eo++;
+		if (eo != e) *eo = 0;
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/errno/__errno_location.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/errno/__errno_location.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/errno/__errno_location.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int *__errno_location(void)
+{
+	return &__pthread_self()->errno_val;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/errno/__strerror.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/errno/__strerror.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/errno/__strerror.h	(revision 398)
@@ -0,0 +1,104 @@
+/* This file is sorted such that 'errors' which represent exceptional
+ * conditions under which a correct program may fail come first, followed
+ * by messages that indicate an incorrect program or system failure. The
+ * macro E() along with double-inclusion is used to ensure that ordering
+ * of the strings remains synchronized. */
+
+E(EILSEQ,       "Illegal byte sequence")
+E(EDOM,         "Domain error")
+E(ERANGE,       "Result not representable")
+
+E(ENOTTY,       "Not a tty")
+E(EACCES,       "Permission denied")
+E(EPERM,        "Operation not permitted")
+E(ENOENT,       "No such file or directory")
+E(ESRCH,        "No such process")
+E(EEXIST,       "File exists")
+
+E(EOVERFLOW,    "Value too large for data type")
+E(ENOSPC,       "No space left on device")
+E(ENOMEM,       "Out of memory")
+
+E(EBUSY,        "Resource busy")
+E(EINTR,        "Interrupted system call")
+E(EAGAIN,       "Resource temporarily unavailable")
+E(ESPIPE,       "Invalid seek")
+
+E(EXDEV,        "Cross-device link")
+E(EROFS,        "Read-only file system")
+E(ENOTEMPTY,    "Directory not empty")
+
+E(ECONNRESET,   "Connection reset by peer")
+E(ETIMEDOUT,    "Operation timed out")
+E(ECONNREFUSED, "Connection refused")
+E(EHOSTDOWN,    "Host is down")
+E(EHOSTUNREACH, "Host is unreachable")
+E(EADDRINUSE,   "Address in use")
+
+E(EPIPE,        "Broken pipe")
+E(EIO,          "I/O error")
+E(ENXIO,        "No such device or address")
+E(ENOTBLK,      "Block device required")
+E(ENODEV,       "No such device")
+E(ENOTDIR,      "Not a directory")
+E(EISDIR,       "Is a directory")
+E(ETXTBSY,      "Text file busy")
+E(ENOEXEC,      "Exec format error")
+
+E(EINVAL,       "Invalid argument")
+
+E(E2BIG,        "Argument list too long")
+E(ELOOP,        "Symbolic link loop")
+E(ENAMETOOLONG, "Filename too long")
+E(ENFILE,       "Too many open files in system")
+E(EMFILE,       "No file descriptors available")
+E(EBADF,        "Bad file descriptor")
+E(ECHILD,       "No child process")
+E(EFAULT,       "Bad address")
+E(EFBIG,        "File too large")
+E(EMLINK,       "Too many links")
+E(ENOLCK,       "No locks available")
+
+E(EDEADLK,      "Resource deadlock would occur")
+E(ENOTRECOVERABLE, "State not recoverable")
+E(EOWNERDEAD,   "Previous owner died")
+E(ECANCELED,    "Operation canceled")
+E(ENOSYS,       "Function not implemented")
+E(ENOMSG,       "No message of desired type")
+E(EIDRM,        "Identifier removed")
+E(ENOSTR,       "Device not a stream")
+E(ENODATA,      "No data available")
+E(ETIME,        "Device timeout")
+E(ENOSR,        "Out of streams resources")
+E(ENOLINK,      "Link has been severed")
+E(EPROTO,       "Protocol error")
+E(EBADMSG,      "Bad message")
+E(EBADFD,       "File descriptor in bad state")
+E(ENOTSOCK,     "Not a socket")
+E(EDESTADDRREQ, "Destination address required")
+E(EMSGSIZE,     "Message too large")
+E(EPROTOTYPE,   "Protocol wrong type for socket")
+E(ENOPROTOOPT,  "Protocol not available")
+E(EPROTONOSUPPORT,"Protocol not supported")
+E(ESOCKTNOSUPPORT,"Socket type not supported")
+E(ENOTSUP,      "Not supported")
+E(EPFNOSUPPORT, "Protocol family not supported")
+E(EAFNOSUPPORT, "Address family not supported by protocol")
+E(EADDRNOTAVAIL,"Address not available")
+E(ENETDOWN,     "Network is down")
+E(ENETUNREACH,  "Network unreachable")
+E(ENETRESET,    "Connection reset by network")
+E(ECONNABORTED, "Connection aborted")
+E(ENOBUFS,      "No buffer space available")
+E(EISCONN,      "Socket is connected")
+E(ENOTCONN,     "Socket not connected")
+E(ESHUTDOWN,    "Cannot send after socket shutdown")
+E(EALREADY,     "Operation already in progress")
+E(EINPROGRESS,  "Operation in progress")
+E(ESTALE,       "Stale file handle")
+E(EREMOTEIO,    "Remote I/O error")
+E(EDQUOT,       "Quota exceeded")
+E(ENOMEDIUM,    "No medium found")
+E(EMEDIUMTYPE,  "Wrong medium type")
+
+E(0,            "No error information")
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/errno/strerror.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/errno/strerror.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/errno/strerror.c	(revision 398)
@@ -0,0 +1,37 @@
+#include <errno.h>
+#include <string.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+#define E(a,b) ((unsigned char)a),
+static const unsigned char errid[] = {
+#include "__strerror.h"
+};
+
+#undef E
+#define E(a,b) b "\0"
+static const char errmsg[] =
+#include "__strerror.h"
+;
+
+char *__strerror_l(int e, locale_t loc)
+{
+	const char *s;
+	int i;
+	/* mips has one error code outside of the 8-bit range due to a
+	 * historical typo, so we just remap it. */
+	if (EDQUOT==1133) {
+		if (e==109) e=-1;
+		else if (e==EDQUOT) e=109;
+	}
+	for (i=0; errid[i] && errid[i] != e; i++);
+	for (s=errmsg; i; s++, i--) for (; *s; s++);
+	return (char *)LCTRANS(s, LC_MESSAGES, loc);
+}
+
+char *strerror(int e)
+{
+	return __strerror_l(e, CURRENT_LOCALE);
+}
+
+weak_alias(__strerror_l, strerror_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/_Exit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/_Exit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/_Exit.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include "syscall.h"
+
+_Noreturn void _Exit(int ec)
+{
+	__syscall(SYS_exit_group, ec);
+	for (;;) __syscall(SYS_exit, ec);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/abort.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/abort.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/abort.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <stdlib.h>
+#include <signal.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+#include "atomic.h"
+
+_Noreturn void abort(void)
+{
+	raise(SIGABRT);
+	__block_all_sigs(0);
+	a_crash();
+	raise(SIGKILL);
+	_Exit(127);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/assert.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/assert.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/assert.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+_Noreturn void __assert_fail(const char *expr, const char *file, int line, const char *func)
+{
+	fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line);
+	fflush(NULL);
+	abort();
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/at_quick_exit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/at_quick_exit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/at_quick_exit.c	(revision 398)
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+#include "libc.h"
+
+#define COUNT 32
+
+static void (*funcs[COUNT])(void);
+static int count;
+static volatile int lock[2];
+
+void __funcs_on_quick_exit()
+{
+	void (*func)(void);
+	LOCK(lock);
+	while (count > 0) {
+		func = funcs[--count];
+		UNLOCK(lock);
+		func();
+		LOCK(lock);
+	}
+}
+
+int at_quick_exit(void (*func)(void))
+{
+	if (count == 32) return -1;
+	LOCK(lock);
+	funcs[count++] = func;
+	UNLOCK(lock);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/atexit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/atexit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/atexit.c	(revision 398)
@@ -0,0 +1,71 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include "libc.h"
+
+/* Ensure that at least 32 atexit handlers can be registered without malloc */
+#define COUNT 32
+
+static struct fl
+{
+	struct fl *next;
+	void (*f[COUNT])(void *);
+	void *a[COUNT];
+} builtin, *head;
+
+static int slot;
+static volatile int lock[2];
+
+void __funcs_on_exit()
+{
+	void (*func)(void *), *arg;
+	LOCK(lock);
+	for (; head; head=head->next, slot=COUNT) while(slot-->0) {
+		func = head->f[slot];
+		arg = head->a[slot];
+		UNLOCK(lock);
+		func(arg);
+		LOCK(lock);
+	}
+}
+
+void __cxa_finalize(void *dso)
+{
+}
+
+int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
+{
+	LOCK(lock);
+
+	/* Defer initialization of head so it can be in BSS */
+	if (!head) head = &builtin;
+
+	/* If the current function list is full, add a new one */
+	if (slot==COUNT) {
+		struct fl *new_fl = calloc(sizeof(struct fl), 1);
+		if (!new_fl) {
+			UNLOCK(lock);
+			return -1;
+		}
+		new_fl->next = head;
+		head = new_fl;
+		slot = 0;
+	}
+
+	/* Append function to the list. */
+	head->f[slot] = func;
+	head->a[slot] = arg;
+	slot++;
+
+	UNLOCK(lock);
+	return 0;
+}
+
+static void call(void *p)
+{
+	((void (*)(void))(uintptr_t)p)();
+}
+
+int atexit(void (*func)(void))
+{
+	return __cxa_atexit(call, (void *)(uintptr_t)func, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/exit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/exit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/exit.c	(revision 398)
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include "libc.h"
+
+static void dummy()
+{
+}
+
+/* atexit.c and __stdio_exit.c override these. the latter is linked
+ * as a consequence of linking either __toread.c or __towrite.c. */
+weak_alias(dummy, __funcs_on_exit);
+weak_alias(dummy, __stdio_exit);
+weak_alias(dummy, _fini);
+
+__attribute__((__weak__, __visibility__("hidden")))
+extern void (*const __fini_array_start)(void), (*const __fini_array_end)(void);
+
+static void libc_exit_fini(void)
+{
+	uintptr_t a = (uintptr_t)&__fini_array_end;
+	for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)()))
+		(*(void (**)())(a-sizeof(void(*)())))();
+	_fini();
+}
+
+weak_alias(libc_exit_fini, __libc_exit_fini);
+
+_Noreturn void exit(int code)
+{
+	__funcs_on_exit();
+	__libc_exit_fini();
+	__stdio_exit();
+	_Exit(code);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/quick_exit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/quick_exit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/exit/quick_exit.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include "libc.h"
+
+static void dummy() { }
+weak_alias(dummy, __funcs_on_quick_exit);
+
+_Noreturn void quick_exit(int code)
+{
+	__funcs_on_quick_exit();
+	_Exit(code);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/creat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/creat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/creat.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <fcntl.h>
+#include "libc.h"
+
+int creat(const char *filename, mode_t mode)
+{
+	return open(filename, O_CREAT|O_WRONLY|O_TRUNC, mode);
+}
+
+LFS64(creat);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/fcntl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/fcntl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/fcntl.c	(revision 398)
@@ -0,0 +1,49 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <stdarg.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+
+int fcntl(int fd, int cmd, ...)
+{
+	unsigned long arg;
+	va_list ap;
+	va_start(ap, cmd);
+	arg = va_arg(ap, unsigned long);
+	va_end(ap);
+	if (cmd == F_SETFL) arg |= O_LARGEFILE;
+	if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, (void *)arg);
+	if (cmd == F_GETOWN) {
+		struct f_owner_ex ex;
+		int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex);
+		if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, (void *)arg);
+		if (ret) return __syscall_ret(ret);
+		return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid;
+	}
+	if (cmd == F_DUPFD_CLOEXEC) {
+		int ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg);
+		if (ret != -EINVAL) {
+			if (ret >= 0)
+				__syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+			return __syscall_ret(ret);
+		}
+		ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, 0);
+		if (ret != -EINVAL) {
+			if (ret >= 0) __syscall(SYS_close, ret);
+			return __syscall_ret(-EINVAL);
+		}
+		ret = __syscall(SYS_fcntl, fd, F_DUPFD, arg);
+		if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+		return __syscall_ret(ret);
+	}
+	switch (cmd) {
+	case F_SETLK:
+	case F_GETLK:
+	case F_GETOWN_EX:
+	case F_SETOWN_EX:
+		return syscall(SYS_fcntl, fd, cmd, (void *)arg);
+	default:
+		return syscall(SYS_fcntl, fd, cmd, arg);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/open.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/open.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/open.c	(revision 398)
@@ -0,0 +1,24 @@
+#include <fcntl.h>
+#include <stdarg.h>
+#include "syscall.h"
+#include "libc.h"
+
+int open(const char *filename, int flags, ...)
+{
+	mode_t mode = 0;
+
+	if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
+		va_list ap;
+		va_start(ap, flags);
+		mode = va_arg(ap, mode_t);
+		va_end(ap);
+	}
+
+	int fd = __sys_open_cp(filename, flags, mode);
+	if (fd>=0 && (flags & O_CLOEXEC))
+		__syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
+
+	return __syscall_ret(fd);
+}
+
+LFS64(open);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/openat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/openat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/openat.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <fcntl.h>
+#include <stdarg.h>
+#include "syscall.h"
+#include "libc.h"
+
+int openat(int fd, const char *filename, int flags, ...)
+{
+	mode_t mode = 0;
+
+	if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
+		va_list ap;
+		va_start(ap, flags);
+		mode = va_arg(ap, mode_t);
+		va_end(ap);
+	}
+
+	return syscall_cp(SYS_openat, fd, filename, flags|O_LARGEFILE, mode);
+}
+
+LFS64(openat);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/posix_fadvise.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/posix_fadvise.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/posix_fadvise.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <fcntl.h>
+#include "syscall.h"
+#include "libc.h"
+
+int posix_fadvise(int fd, off_t base, off_t len, int advice)
+{
+#if defined(SYSCALL_FADVISE_6_ARG)
+	/* Some archs, at least arm and powerpc, have the syscall
+	 * arguments reordered to avoid needing 7 argument registers
+	 * due to 64-bit argument alignment. */
+	return -__syscall(SYS_fadvise, fd, advice,
+		__SYSCALL_LL_E(base), __SYSCALL_LL_E(len));
+#else
+	return -__syscall(SYS_fadvise, fd, __SYSCALL_LL_O(base),
+		__SYSCALL_LL_E(len), advice);
+#endif
+}
+
+LFS64(posix_fadvise);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/posix_fallocate.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/posix_fallocate.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fcntl/posix_fallocate.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <fcntl.h>
+#include "syscall.h"
+#include "libc.h"
+
+int posix_fallocate(int fd, off_t base, off_t len)
+{
+	return -__syscall(SYS_fallocate, fd, 0, __SYSCALL_LL_E(base),
+		__SYSCALL_LL_E(len));
+}
+
+LFS64(posix_fallocate);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/__flt_rounds.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/__flt_rounds.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/__flt_rounds.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <float.h>
+#include <fenv.h>
+
+int __flt_rounds()
+{
+	switch (fegetround()) {
+#ifdef FE_TOWARDZERO
+	case FE_TOWARDZERO: return 0;
+#endif
+	case FE_TONEAREST: return 1;
+#ifdef FE_UPWARD
+	case FE_UPWARD: return 2;
+#endif
+#ifdef FE_DOWNWARD
+	case FE_DOWNWARD: return 3;
+#endif
+	}
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fegetexceptflag.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fegetexceptflag.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fegetexceptflag.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <fenv.h>
+
+int fegetexceptflag(fexcept_t *fp, int mask)
+{
+	*fp = fetestexcept(mask);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/feholdexcept.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/feholdexcept.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/feholdexcept.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <fenv.h>
+
+int feholdexcept(fenv_t *envp)
+{
+	fegetenv(envp);
+	feclearexcept(FE_ALL_EXCEPT);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fenv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fenv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fenv.c	(revision 398)
@@ -0,0 +1,38 @@
+#include <fenv.h>
+
+/* Dummy functions for archs lacking fenv implementation */
+
+int feclearexcept(int mask)
+{
+	return 0;
+}
+
+int feraiseexcept(int mask)
+{
+	return 0;
+}
+
+int fetestexcept(int mask)
+{
+	return 0;
+}
+
+int fegetround(void)
+{
+	return FE_TONEAREST;
+}
+
+int __fesetround(int r)
+{
+	return 0;
+}
+
+int fegetenv(fenv_t *envp)
+{
+	return 0;
+}
+
+int fesetenv(const fenv_t *envp)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fesetexceptflag.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fesetexceptflag.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fesetexceptflag.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <fenv.h>
+
+int fesetexceptflag(const fexcept_t *fp, int mask)
+{
+	feclearexcept(~*fp & mask);
+	feraiseexcept(*fp & mask);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fesetround.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fesetround.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/fesetround.c	(revision 398)
@@ -0,0 +1,23 @@
+#include <fenv.h>
+
+/* __fesetround wrapper for arch independent argument check */
+
+int __fesetround(int);
+
+int fesetround(int r)
+{
+	if (r & ~(
+		FE_TONEAREST
+#ifdef FE_DOWNWARD
+		|FE_DOWNWARD
+#endif
+#ifdef FE_UPWARD
+		|FE_UPWARD
+#endif
+#ifdef FE_TOWARDZERO
+		|FE_TOWARDZERO
+#endif
+		))
+		return -1;
+	return __fesetround(r);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/feupdateenv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/feupdateenv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/fenv/feupdateenv.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <fenv.h>
+
+int feupdateenv(const fenv_t *envp)
+{
+	int ex = fetestexcept(FE_ALL_EXCEPT);
+	fesetenv(envp);
+	feraiseexcept(ex);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/atomic.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/atomic.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/atomic.h	(revision 398)
@@ -0,0 +1,314 @@
+#ifndef _ATOMIC_H
+#define _ATOMIC_H
+
+#include <stdint.h>
+
+#include "atomic_arch.h"
+
+#ifdef a_ll
+
+#ifndef a_pre_llsc
+#define a_pre_llsc()
+#endif
+
+#ifndef a_post_llsc
+#define a_post_llsc()
+#endif
+
+#ifndef a_cas
+#define a_cas a_cas
+static inline int a_cas(volatile int *p, int t, int s)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (old==t && !a_sc(p, s));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_swap
+#define a_swap a_swap
+static inline int a_swap(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_fetch_add
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, (unsigned)old + v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_fetch_and
+#define a_fetch_and a_fetch_and
+static inline int a_fetch_and(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, old & v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#ifndef a_fetch_or
+#define a_fetch_or a_fetch_or
+static inline int a_fetch_or(volatile int *p, int v)
+{
+	int old;
+	a_pre_llsc();
+	do old = a_ll(p);
+	while (!a_sc(p, old | v));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#endif
+
+#ifdef a_ll_p
+
+#ifndef a_cas_p
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	void *old;
+	a_pre_llsc();
+	do old = a_ll_p(p);
+	while (old==t && !a_sc_p(p, s));
+	a_post_llsc();
+	return old;
+}
+#endif
+
+#endif
+
+#ifndef a_cas
+#error missing definition of a_cas
+#endif
+
+#ifndef a_swap
+#define a_swap a_swap
+static inline int a_swap(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, v) != old);
+	return old;
+}
+#endif
+
+#ifndef a_fetch_add
+#define a_fetch_add a_fetch_add
+static inline int a_fetch_add(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, (unsigned)old+v) != old);
+	return old;
+}
+#endif
+
+#ifndef a_fetch_and
+#define a_fetch_and a_fetch_and
+static inline int a_fetch_and(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, old&v) != old);
+	return old;
+}
+#endif
+#ifndef a_fetch_or
+#define a_fetch_or a_fetch_or
+static inline int a_fetch_or(volatile int *p, int v)
+{
+	int old;
+	do old = *p;
+	while (a_cas(p, old, old|v) != old);
+	return old;
+}
+#endif
+
+#ifndef a_and
+#define a_and a_and
+static inline void a_and(volatile int *p, int v)
+{
+	a_fetch_and(p, v);
+}
+#endif
+
+#ifndef a_or
+#define a_or a_or
+static inline void a_or(volatile int *p, int v)
+{
+	a_fetch_or(p, v);
+}
+#endif
+
+#ifndef a_inc
+#define a_inc a_inc
+static inline void a_inc(volatile int *p)
+{
+	a_fetch_add(p, 1);
+}
+#endif
+
+#ifndef a_dec
+#define a_dec a_dec
+static inline void a_dec(volatile int *p)
+{
+	a_fetch_add(p, -1);
+}
+#endif
+
+#ifndef a_store
+#define a_store a_store
+static inline void a_store(volatile int *p, int v)
+{
+#ifdef a_barrier
+	a_barrier();
+	*p = v;
+	a_barrier();
+#else
+	a_swap(p, v);
+#endif
+}
+#endif
+
+#ifndef a_barrier
+#define a_barrier a_barrier
+static void a_barrier()
+{
+	volatile int tmp = 0;
+	a_cas(&tmp, 0, 0);
+}
+#endif
+
+#ifndef a_spin
+#define a_spin a_barrier
+#endif
+
+#ifndef a_and_64
+#define a_and_64 a_and_64
+static inline void a_and_64(volatile uint64_t *p, uint64_t v)
+{
+	union { uint64_t v; uint32_t r[2]; } u = { v };
+	if (u.r[0]+1) a_and((int *)p, u.r[0]);
+	if (u.r[1]+1) a_and((int *)p+1, u.r[1]);
+}
+#endif
+
+#ifndef a_or_64
+#define a_or_64 a_or_64
+static inline void a_or_64(volatile uint64_t *p, uint64_t v)
+{
+	union { uint64_t v; uint32_t r[2]; } u = { v };
+	if (u.r[0]) a_or((int *)p, u.r[0]);
+	if (u.r[1]) a_or((int *)p+1, u.r[1]);
+}
+#endif
+
+#ifndef a_cas_p
+typedef char a_cas_p_undefined_but_pointer_not_32bit[-sizeof(char) == 0xffffffff ? 1 : -1];
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)
+{
+	return (void *)a_cas((volatile int *)p, (int)t, (int)s);
+}
+#endif
+
+#ifndef a_or_l
+#define a_or_l a_or_l
+static inline void a_or_l(volatile void *p, long v)
+{
+	if (sizeof(long) == sizeof(int)) a_or(p, v);
+	else a_or_64(p, v);
+}
+#endif
+
+#ifndef a_crash
+#define a_crash a_crash
+static inline void a_crash()
+{
+	*(volatile char *)0=0;
+}
+#endif
+
+#ifndef a_ctz_64
+#define a_ctz_64 a_ctz_64
+static inline int a_ctz_64(uint64_t x)
+{
+	static const char debruijn64[64] = {
+		0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
+		62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
+		63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
+		51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
+	};
+	static const char debruijn32[32] = {
+		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
+		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
+	};
+	if (sizeof(long) < 8) {
+		uint32_t y = x;
+		if (!y) {
+			y = x>>32;
+			return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
+		}
+		return debruijn32[(y&-y)*0x076be629 >> 27];
+	}
+	return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
+}
+#endif
+
+#ifndef a_clz_64
+#define a_clz_64 a_clz_64
+static inline int a_clz_64(uint64_t x)
+{
+#ifdef a_clz_32
+	if (x>>32)
+		return a_clz_32(x>>32);
+	return a_clz_32(x) + 32;
+#else
+	uint32_t y;
+	int r;
+	if (x>>32) y=x>>32, r=0; else y=x, r=32;
+	if (y>>16) y>>=16; else r |= 16;
+	if (y>>8) y>>=8; else r |= 8;
+	if (y>>4) y>>=4; else r |= 4;
+	if (y>>2) y>>=2; else r |= 2;
+	return r | !(y>>1);
+#endif
+}
+#endif
+
+#ifndef a_ctz_l
+#define a_ctz_l a_ctz_l
+static inline int a_ctz_l(unsigned long x)
+{
+	static const char debruijn32[32] = {
+		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
+		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
+	};
+	if (sizeof(long) == 8) return a_ctz_64(x);
+	return debruijn32[(x&-x)*0x076be629 >> 27];
+}
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/dynlink.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/dynlink.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/dynlink.h	(revision 398)
@@ -0,0 +1,98 @@
+#ifndef _INTERNAL_RELOC_H
+#define _INTERNAL_RELOC_H
+
+#include <features.h>
+#include <elf.h>
+#include <stdint.h>
+
+#if UINTPTR_MAX == 0xffffffff
+typedef Elf32_Ehdr Ehdr;
+typedef Elf32_Phdr Phdr;
+typedef Elf32_Sym Sym;
+#define R_TYPE(x) ((x)&255)
+#define R_SYM(x) ((x)>>8)
+#define R_INFO ELF32_R_INFO
+#else
+typedef Elf64_Ehdr Ehdr;
+typedef Elf64_Phdr Phdr;
+typedef Elf64_Sym Sym;
+#define R_TYPE(x) ((x)&0x7fffffff)
+#define R_SYM(x) ((x)>>32)
+#define R_INFO ELF64_R_INFO
+#endif
+
+/* These enum constants provide unmatchable default values for
+ * any relocation type the arch does not use. */
+enum {
+	REL_NONE = 0,
+	REL_SYMBOLIC = -100,
+	REL_GOT,
+	REL_PLT,
+	REL_RELATIVE,
+	REL_OFFSET,
+	REL_OFFSET32,
+	REL_COPY,
+	REL_SYM_OR_REL,
+	REL_DTPMOD,
+	REL_DTPOFF,
+	REL_TPOFF,
+	REL_TPOFF_NEG,
+	REL_TLSDESC,
+	REL_FUNCDESC,
+	REL_FUNCDESC_VAL,
+};
+
+struct fdpic_loadseg {
+	uintptr_t addr, p_vaddr, p_memsz;
+};
+
+struct fdpic_loadmap {
+	unsigned short version, nsegs;
+	struct fdpic_loadseg segs[];
+};
+
+struct fdpic_dummy_loadmap {
+	unsigned short version, nsegs;
+	struct fdpic_loadseg segs[1];
+};
+
+#include "reloc.h"
+
+#ifndef FDPIC_CONSTDISP_FLAG
+#define FDPIC_CONSTDISP_FLAG 0
+#endif
+
+#ifndef DL_FDPIC
+#define DL_FDPIC 0
+#endif
+
+#ifndef DL_NOMMU_SUPPORT
+#define DL_NOMMU_SUPPORT 0
+#endif
+
+#if !DL_FDPIC
+#define IS_RELATIVE(x,s) ( \
+	(R_TYPE(x) == REL_RELATIVE) || \
+	(R_TYPE(x) == REL_SYM_OR_REL && !R_SYM(x)) )
+#else
+#define IS_RELATIVE(x,s) ( ( \
+	(R_TYPE(x) == REL_FUNCDESC_VAL) || \
+	(R_TYPE(x) == REL_SYMBOLIC) ) \
+	&& (((s)[R_SYM(x)].st_info & 0xf) == STT_SECTION) )
+#endif
+
+#ifndef NEED_MIPS_GOT_RELOCS
+#define NEED_MIPS_GOT_RELOCS 0
+#endif
+
+#ifndef DT_DEBUG_INDIRECT
+#define DT_DEBUG_INDIRECT 0
+#endif
+
+#define AUX_CNT 32
+#define DYN_CNT 32
+
+typedef void (*stage2_func)(unsigned char *, size_t *);
+typedef _Noreturn void (*stage3_func)(size_t *);
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/fdpic_crt.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/fdpic_crt.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/fdpic_crt.h	(revision 398)
@@ -0,0 +1,28 @@
+#include <stdint.h>
+
+__attribute__((__visibility__("hidden")))
+void *__fdpic_fixup(void *map, uintptr_t *a, uintptr_t *z)
+{
+	/* If map is a null pointer, the program was loaded by a
+	 * non-FDPIC-aware ELF loader, and fixups are not needed,
+	 * but the value for the GOT pointer is. */
+	if (!map) return (void *)z[-1];
+
+	struct {
+		unsigned short version, nsegs;
+		struct fdpic_loadseg {
+			uintptr_t addr, p_vaddr, p_memsz;
+		} segs[];
+	} *lm = map;
+	int nsegs = lm->nsegs, rseg = 0, vseg = 0;
+	for (;;) {
+		while (*a-lm->segs[rseg].p_vaddr >= lm->segs[rseg].p_memsz)
+			if (++rseg == nsegs) rseg = 0;
+		uintptr_t *r = (uintptr_t *)
+			(*a + lm->segs[rseg].addr - lm->segs[rseg].p_vaddr);
+		if (++a == z) return r;
+		while (*r-lm->segs[vseg].p_vaddr >= lm->segs[vseg].p_memsz)
+			if (++vseg == nsegs) vseg = 0;
+		*r += lm->segs[vseg].addr - lm->segs[vseg].p_vaddr;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/floatscan.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/floatscan.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/floatscan.c	(revision 398)
@@ -0,0 +1,510 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <math.h>
+#include <float.h>
+#include <limits.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "shgetc.h"
+#include "floatscan.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+
+#define LD_B1B_DIG 2
+#define LD_B1B_MAX 9007199, 254740991
+#define KMAX 128
+
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+
+#define LD_B1B_DIG 3
+#define LD_B1B_MAX 18, 446744073, 709551615
+#define KMAX 2048
+
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+
+#define LD_B1B_DIG 4
+#define LD_B1B_MAX 10384593, 717069655, 257060992, 658440191
+#define KMAX 2048
+
+#else
+#error Unsupported long double representation
+#endif
+
+#define MASK (KMAX-1)
+
+#define CONCAT2(x,y) x ## y
+#define CONCAT(x,y) CONCAT2(x,y)
+
+static long long scanexp(FILE *f, int pok)
+{
+	int c;
+	int x;
+	long long y;
+	int neg = 0;
+	
+	c = shgetc(f);
+	if (c=='+' || c=='-') {
+		neg = (c=='-');
+		c = shgetc(f);
+		if (c-'0'>=10U && pok) shunget(f);
+	}
+	if (c-'0'>=10U) {
+		shunget(f);
+		return LLONG_MIN;
+	}
+	for (x=0; c-'0'<10U && x<INT_MAX/10; c = shgetc(f))
+		x = 10*x + c-'0';
+	for (y=x; c-'0'<10U && y<LLONG_MAX/100; c = shgetc(f))
+		y = 10*y + c-'0';
+	for (; c-'0'<10U; c = shgetc(f));
+	shunget(f);
+	return neg ? -y : y;
+}
+
+
+static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int pok)
+{
+	uint32_t x[KMAX];
+	static const uint32_t th[] = { LD_B1B_MAX };
+	int i, j, k, a, z;
+	long long lrp=0, dc=0;
+	long long e10=0;
+	int lnz = 0;
+	int gotdig = 0, gotrad = 0;
+	int rp;
+	int e2;
+	int emax = -emin-bits+3;
+	int denormal = 0;
+	long double y;
+	long double frac=0;
+	long double bias=0;
+	static const int p10s[] = { 10, 100, 1000, 10000,
+		100000, 1000000, 10000000, 100000000 };
+
+	j=0;
+	k=0;
+
+	/* Don't let leading zeros consume buffer space */
+	for (; c=='0'; c = shgetc(f)) gotdig=1;
+	if (c=='.') {
+		gotrad = 1;
+		for (c = shgetc(f); c=='0'; c = shgetc(f)) gotdig=1, lrp--;
+	}
+
+	x[0] = 0;
+	for (; c-'0'<10U || c=='.'; c = shgetc(f)) {
+		if (c == '.') {
+			if (gotrad) break;
+			gotrad = 1;
+			lrp = dc;
+		} else if (k < KMAX-3) {
+			dc++;
+			if (c!='0') lnz = dc;
+			if (j) x[k] = x[k]*10 + c-'0';
+			else x[k] = c-'0';
+			if (++j==9) {
+				k++;
+				j=0;
+			}
+			gotdig=1;
+		} else {
+			dc++;
+			if (c!='0') {
+				lnz = (KMAX-4)*9;
+				x[KMAX-4] |= 1;
+			}
+		}
+	}
+	if (!gotrad) lrp=dc;
+
+	if (gotdig && (c|32)=='e') {
+		e10 = scanexp(f, pok);
+		if (e10 == LLONG_MIN) {
+			if (pok) {
+				shunget(f);
+			} else {
+				shlim(f, 0);
+				return 0;
+			}
+			e10 = 0;
+		}
+		lrp += e10;
+	} else if (c>=0) {
+		shunget(f);
+	}
+	if (!gotdig) {
+		errno = EINVAL;
+		shlim(f, 0);
+		return 0;
+	}
+
+	/* Handle zero specially to avoid nasty special cases later */
+	if (!x[0]) return sign * 0.0;
+
+	/* Optimize small integers (w/no exponent) and over/under-flow */
+	if (lrp==dc && dc<10 && (bits>30 || x[0]>>bits==0))
+		return sign * (long double)x[0];
+	if (lrp > -emin/2) {
+		errno = ERANGE;
+		return sign * LDBL_MAX * LDBL_MAX;
+	}
+	if (lrp < emin-2*LDBL_MANT_DIG) {
+		errno = ERANGE;
+		return sign * LDBL_MIN * LDBL_MIN;
+	}
+
+	/* Align incomplete final B1B digit */
+	if (j) {
+		for (; j<9; j++) x[k]*=10;
+		k++;
+		j=0;
+	}
+
+	a = 0;
+	z = k;
+	e2 = 0;
+	rp = lrp;
+
+	/* Optimize small to mid-size integers (even in exp. notation) */
+	if (lnz<9 && lnz<=rp && rp < 18) {
+		if (rp == 9) return sign * (long double)x[0];
+		if (rp < 9) return sign * (long double)x[0] / p10s[8-rp];
+		int bitlim = bits-3*(int)(rp-9);
+		if (bitlim>30 || x[0]>>bitlim==0)
+			return sign * (long double)x[0] * p10s[rp-10];
+	}
+
+	/* Drop trailing zeros */
+	for (; !x[z-1]; z--);
+
+	/* Align radix point to B1B digit boundary */
+	if (rp % 9) {
+		int rpm9 = rp>=0 ? rp%9 : rp%9+9;
+		int p10 = p10s[8-rpm9];
+		uint32_t carry = 0;
+		for (k=a; k!=z; k++) {
+			uint32_t tmp = x[k] % p10;
+			x[k] = x[k]/p10 + carry;
+			carry = 1000000000/p10 * tmp;
+			if (k==a && !x[k]) {
+				a = (a+1 & MASK);
+				rp -= 9;
+			}
+		}
+		if (carry) x[z++] = carry;
+		rp += 9-rpm9;
+	}
+
+	/* Upscale until desired number of bits are left of radix point */
+	while (rp < 9*LD_B1B_DIG || (rp == 9*LD_B1B_DIG && x[a]<th[0])) {
+		uint32_t carry = 0;
+		e2 -= 29;
+		for (k=(z-1 & MASK); ; k=(k-1 & MASK)) {
+			uint64_t tmp = ((uint64_t)x[k] << 29) + carry;
+			if (tmp > 1000000000) {
+				carry = tmp / 1000000000;
+				x[k] = tmp % 1000000000;
+			} else {
+				carry = 0;
+				x[k] = tmp;
+			}
+			if (k==(z-1 & MASK) && k!=a && !x[k]) z = k;
+			if (k==a) break;
+		}
+		if (carry) {
+			rp += 9;
+			a = (a-1 & MASK);
+			if (a == z) {
+				z = (z-1 & MASK);
+				x[z-1 & MASK] |= x[z];
+			}
+			x[a] = carry;
+		}
+	}
+
+	/* Downscale until exactly number of bits are left of radix point */
+	for (;;) {
+		uint32_t carry = 0;
+		int sh = 1;
+		for (i=0; i<LD_B1B_DIG; i++) {
+			k = (a+i & MASK);
+			if (k == z || x[k] < th[i]) {
+				i=LD_B1B_DIG;
+				break;
+			}
+			if (x[a+i & MASK] > th[i]) break;
+		}
+		if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break;
+		/* FIXME: find a way to compute optimal sh */
+		if (rp > 9+9*LD_B1B_DIG) sh = 9;
+		e2 += sh;
+		for (k=a; k!=z; k=(k+1 & MASK)) {
+			uint32_t tmp = x[k] & (1<<sh)-1;
+			x[k] = (x[k]>>sh) + carry;
+			carry = (1000000000>>sh) * tmp;
+			if (k==a && !x[k]) {
+				a = (a+1 & MASK);
+				i--;
+				rp -= 9;
+			}
+		}
+		if (carry) {
+			if ((z+1 & MASK) != a) {
+				x[z] = carry;
+				z = (z+1 & MASK);
+			} else x[z-1 & MASK] |= 1;
+		}
+	}
+
+	/* Assemble desired bits into floating point variable */
+	for (y=i=0; i<LD_B1B_DIG; i++) {
+		if ((a+i & MASK)==z) x[(z=(z+1 & MASK))-1] = 0;
+		y = 1000000000.0L * y + x[a+i & MASK];
+	}
+
+	y *= sign;
+
+	/* Limit precision for denormal results */
+	if (bits > LDBL_MANT_DIG+e2-emin) {
+		bits = LDBL_MANT_DIG+e2-emin;
+		if (bits<0) bits=0;
+		denormal = 1;
+	}
+
+	/* Calculate bias term to force rounding, move out lower bits */
+	if (bits < LDBL_MANT_DIG) {
+		bias = copysignl(scalbn(1, 2*LDBL_MANT_DIG-bits-1), y);
+		frac = fmodl(y, scalbn(1, LDBL_MANT_DIG-bits));
+		y -= frac;
+		y += bias;
+	}
+
+	/* Process tail of decimal input so it can affect rounding */
+	if ((a+i & MASK) != z) {
+		uint32_t t = x[a+i & MASK];
+		if (t < 500000000 && (t || (a+i+1 & MASK) != z))
+			frac += 0.25*sign;
+		else if (t > 500000000)
+			frac += 0.75*sign;
+		else if (t == 500000000) {
+			if ((a+i+1 & MASK) == z)
+				frac += 0.5*sign;
+			else
+				frac += 0.75*sign;
+		}
+		if (LDBL_MANT_DIG-bits >= 2 && !fmodl(frac, 1))
+			frac++;
+	}
+
+	y += frac;
+	y -= bias;
+
+	if ((e2+LDBL_MANT_DIG & INT_MAX) > emax-5) {
+		if (fabs(y) >= CONCAT(0x1p, LDBL_MANT_DIG)) {
+			if (denormal && bits==LDBL_MANT_DIG+e2-emin)
+				denormal = 0;
+			y *= 0.5;
+			e2++;
+		}
+		if (e2+LDBL_MANT_DIG>emax || (denormal && frac))
+			errno = ERANGE;
+	}
+
+	return scalbnl(y, e2);
+}
+
+static long double hexfloat(FILE *f, int bits, int emin, int sign, int pok)
+{
+	uint32_t x = 0;
+	long double y = 0;
+	long double scale = 1;
+	long double bias = 0;
+	int gottail = 0, gotrad = 0, gotdig = 0;
+	long long rp = 0;
+	long long dc = 0;
+	long long e2 = 0;
+	int d;
+	int c;
+
+	c = shgetc(f);
+
+	/* Skip leading zeros */
+	for (; c=='0'; c = shgetc(f)) gotdig = 1;
+
+	if (c=='.') {
+		gotrad = 1;
+		c = shgetc(f);
+		/* Count zeros after the radix point before significand */
+		for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1;
+	}
+
+	for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) {
+		if (c=='.') {
+			if (gotrad) break;
+			rp = dc;
+			gotrad = 1;
+		} else {
+			gotdig = 1;
+			if (c > '9') d = (c|32)+10-'a';
+			else d = c-'0';
+			if (dc<8) {
+				x = x*16 + d;
+			} else if (dc < LDBL_MANT_DIG/4+1) {
+				y += d*(scale/=16);
+			} else if (d && !gottail) {
+				y += 0.5*scale;
+				gottail = 1;
+			}
+			dc++;
+		}
+	}
+	if (!gotdig) {
+		shunget(f);
+		if (pok) {
+			shunget(f);
+			if (gotrad) shunget(f);
+		} else {
+			shlim(f, 0);
+		}
+		return sign * 0.0;
+	}
+	if (!gotrad) rp = dc;
+	while (dc<8) x *= 16, dc++;
+	if ((c|32)=='p') {
+		e2 = scanexp(f, pok);
+		if (e2 == LLONG_MIN) {
+			if (pok) {
+				shunget(f);
+			} else {
+				shlim(f, 0);
+				return 0;
+			}
+			e2 = 0;
+		}
+	} else {
+		shunget(f);
+	}
+	e2 += 4*rp - 32;
+
+	if (!x) return sign * 0.0;
+	if (e2 > -emin) {
+		errno = ERANGE;
+		return sign * LDBL_MAX * LDBL_MAX;
+	}
+	if (e2 < emin-2*LDBL_MANT_DIG) {
+		errno = ERANGE;
+		return sign * LDBL_MIN * LDBL_MIN;
+	}
+
+	while (x < 0x80000000) {
+		if (y>=0.5) {
+			x += x + 1;
+			y += y - 1;
+		} else {
+			x += x;
+			y += y;
+		}
+		e2--;
+	}
+
+	if (bits > 32+e2-emin) {
+		bits = 32+e2-emin;
+		if (bits<0) bits=0;
+	}
+
+	if (bits < LDBL_MANT_DIG)
+		bias = copysignl(scalbn(1, 32+LDBL_MANT_DIG-bits-1), sign);
+
+	if (bits<32 && y && !(x&1)) x++, y=0;
+
+	y = bias + sign*(long double)x + sign*y;
+	y -= bias;
+
+	if (!y) errno = ERANGE;
+
+	return scalbnl(y, e2);
+}
+
+long double __floatscan(FILE *f, int prec, int pok)
+{
+	int sign = 1;
+	size_t i;
+	int bits;
+	int emin;
+	int c;
+
+	switch (prec) {
+	case 0:
+		bits = FLT_MANT_DIG;
+		emin = FLT_MIN_EXP-bits;
+		break;
+	case 1:
+		bits = DBL_MANT_DIG;
+		emin = DBL_MIN_EXP-bits;
+		break;
+	case 2:
+		bits = LDBL_MANT_DIG;
+		emin = LDBL_MIN_EXP-bits;
+		break;
+	default:
+		return 0;
+	}
+
+	while (isspace((c=shgetc(f))));
+
+	if (c=='+' || c=='-') {
+		sign -= 2*(c=='-');
+		c = shgetc(f);
+	}
+
+	for (i=0; i<8 && (c|32)=="infinity"[i]; i++)
+		if (i<7) c = shgetc(f);
+	if (i==3 || i==8 || (i>3 && pok)) {
+		if (i!=8) {
+			shunget(f);
+			if (pok) for (; i>3; i--) shunget(f);
+		}
+		return sign * INFINITY;
+	}
+	if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++)
+		if (i<2) c = shgetc(f);
+	if (i==3) {
+		if (shgetc(f) != '(') {
+			shunget(f);
+			return NAN;
+		}
+		for (i=1; ; i++) {
+			c = shgetc(f);
+			if (c-'0'<10U || c-'A'<26U || c-'a'<26U || c=='_')
+				continue;
+			if (c==')') return NAN;
+			shunget(f);
+			if (!pok) {
+				errno = EINVAL;
+				shlim(f, 0);
+				return 0;
+			}
+			while (i--) shunget(f);
+			return NAN;
+		}
+		return NAN;
+	}
+
+	if (i) {
+		shunget(f);
+		errno = EINVAL;
+		shlim(f, 0);
+		return 0;
+	}
+
+	if (c=='0') {
+		c = shgetc(f);
+		if ((c|32) == 'x')
+			return hexfloat(f, bits, emin, sign, pok);
+		shunget(f);
+		c = '0';
+	}
+
+	return decfloat(f, c, bits, emin, sign, pok);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/floatscan.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/floatscan.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/floatscan.h	(revision 398)
@@ -0,0 +1,8 @@
+#ifndef FLOATSCAN_H
+#define FLOATSCAN_H
+
+#include <stdio.h>
+
+long double __floatscan(FILE *, int, int);
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/futex.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/futex.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/futex.h	(revision 398)
@@ -0,0 +1,21 @@
+#ifndef _INTERNAL_FUTEX_H
+#define _INTERNAL_FUTEX_H
+
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_FD		2
+#define FUTEX_REQUEUE		3
+#define FUTEX_CMP_REQUEUE	4
+#define FUTEX_WAKE_OP		5
+#define FUTEX_LOCK_PI		6
+#define FUTEX_UNLOCK_PI		7
+#define FUTEX_TRYLOCK_PI	8
+#define FUTEX_WAIT_BITSET	9
+
+#define FUTEX_PRIVATE 128
+
+#define FUTEX_CLOCK_REALTIME 256
+
+int __futex(volatile int *, int, int, void *);
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/intscan.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/intscan.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/intscan.c	(revision 398)
@@ -0,0 +1,100 @@
+#include <limits.h>
+#include <errno.h>
+#include <ctype.h>
+#include "shgetc.h"
+
+/* Lookup table for digit values. -1==255>=36 -> invalid */
+static const unsigned char table[] = { -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, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
+-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
+25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
+-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
+25,26,27,28,29,30,31,32,33,34,35,-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,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+};
+
+unsigned long long __intscan(FILE *f, unsigned base, int pok, unsigned long long lim)
+{
+	const unsigned char *val = table+1;
+	int c, neg=0;
+	unsigned x;
+	unsigned long long y;
+	if (base > 36 || base == 1) {
+		errno = EINVAL;
+		return 0;
+	}
+	while (isspace((c=shgetc(f))));
+	if (c=='+' || c=='-') {
+		neg = -(c=='-');
+		c = shgetc(f);
+	}
+	if ((base == 0 || base == 16) && c=='0') {
+		c = shgetc(f);
+		if ((c|32)=='x') {
+			c = shgetc(f);
+			if (val[c]>=16) {
+				shunget(f);
+				if (pok) shunget(f);
+				else shlim(f, 0);
+				return 0;
+			}
+			base = 16;
+		} else if (base == 0) {
+			base = 8;
+		}
+	} else {
+		if (base == 0) base = 10;
+		if (val[c] >= base) {
+			shunget(f);
+			shlim(f, 0);
+			errno = EINVAL;
+			return 0;
+		}
+	}
+	if (base == 10) {
+		for (x=0; c-'0'<10U && x<=UINT_MAX/10-1; c=shgetc(f))
+			x = x*10 + (c-'0');
+		for (y=x; c-'0'<10U && y<=ULLONG_MAX/10 && 10*y<=ULLONG_MAX-(c-'0'); c=shgetc(f))
+			y = y*10 + (c-'0');
+		if (c-'0'>=10U) goto done;
+	} else if (!(base & base-1)) {
+		int bs = "\0\1\2\4\7\3\6\5"[(0x17*base)>>5&7];
+		for (x=0; val[c]<base && x<=UINT_MAX/32; c=shgetc(f))
+			x = x<<bs | val[c];
+		for (y=x; val[c]<base && y<=ULLONG_MAX>>bs; c=shgetc(f))
+			y = y<<bs | val[c];
+	} else {
+		for (x=0; val[c]<base && x<=UINT_MAX/36-1; c=shgetc(f))
+			x = x*base + val[c];
+		for (y=x; val[c]<base && y<=ULLONG_MAX/base && base*y<=ULLONG_MAX-val[c]; c=shgetc(f))
+			y = y*base + val[c];
+	}
+	if (val[c]<base) {
+		for (; val[c]<base; c=shgetc(f));
+		errno = ERANGE;
+		y = lim;
+		if (lim&1) neg = 0;
+	}
+done:
+	shunget(f);
+	if (y>=lim) {
+		if (!(lim&1) && !neg) {
+			errno = ERANGE;
+			return lim-1;
+		} else if (y>lim) {
+			errno = ERANGE;
+			return lim;
+		}
+	}
+	return (y^neg)-neg;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/intscan.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/intscan.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/intscan.h	(revision 398)
@@ -0,0 +1,8 @@
+#ifndef INTSCAN_H
+#define INTSCAN_H
+
+#include <stdio.h>
+
+unsigned long long __intscan(FILE *, unsigned, int, unsigned long long);
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/ksigaction.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/ksigaction.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/ksigaction.h	(revision 398)
@@ -0,0 +1,11 @@
+/* This is the structure used for the rt_sigaction syscall on most archs,
+ * but it can be overridden by a file with the same name in the top-level
+ * arch dir for a given arch, if necessary. */
+struct k_sigaction {
+	void (*handler)(int);
+	unsigned long flags;
+	void (*restorer)(void);
+	unsigned mask[2];
+};
+
+void __restore(), __restore_rt();
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/libc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/libc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/libc.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "libc.h"
+
+struct __libc __libc;
+
+size_t __hwcap;
+size_t __sysinfo;
+char *__progname=0, *__progname_full=0;
+
+weak_alias(__progname, program_invocation_short_name);
+weak_alias(__progname_full, program_invocation_name);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/libc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/libc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/libc.h	(revision 398)
@@ -0,0 +1,72 @@
+#ifndef LIBC_H
+#define LIBC_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+
+struct __locale_map;
+
+struct __locale_struct {
+	const struct __locale_map *volatile cat[6];
+};
+
+struct tls_module {
+	struct tls_module *next;
+	void *image;
+	size_t len, size, align, offset;
+};
+
+struct __libc {
+	int can_do_threads;
+	int threaded;
+	int secure;
+	volatile int threads_minus_1;
+	size_t *auxv;
+	struct tls_module *tls_head;
+	size_t tls_size, tls_align, tls_cnt;
+	size_t page_size;
+	struct __locale_struct global_locale;
+};
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE libc.page_size
+#endif
+
+#ifdef __PIC__
+#define ATTR_LIBC_VISIBILITY __attribute__((visibility("hidden")))
+#else
+#define ATTR_LIBC_VISIBILITY
+#endif
+
+extern struct __libc __libc ATTR_LIBC_VISIBILITY;
+#define libc __libc
+
+extern size_t __hwcap ATTR_LIBC_VISIBILITY;
+extern size_t __sysinfo ATTR_LIBC_VISIBILITY;
+extern char *__progname, *__progname_full;
+
+/* Designed to avoid any overhead in non-threaded processes */
+void __lock(volatile int *) ATTR_LIBC_VISIBILITY;
+void __unlock(volatile int *) ATTR_LIBC_VISIBILITY;
+int __lockfile(FILE *) ATTR_LIBC_VISIBILITY;
+void __unlockfile(FILE *) ATTR_LIBC_VISIBILITY;
+#define LOCK(x) __lock(x)
+#define UNLOCK(x) __unlock(x)
+
+void __synccall(void (*)(void *), void *);
+int __setxid(int, int, int, int);
+
+extern char **__environ;
+
+#undef weak_alias
+#define weak_alias(old, new) \
+	extern __typeof(old) new __attribute__((weak, alias(#old)))
+
+#undef LFS64_2
+#define LFS64_2(x, y) weak_alias(x, y)
+
+#undef LFS64
+#define LFS64(x) LFS64_2(x, x##64)
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/libm.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/libm.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/libm.h	(revision 398)
@@ -0,0 +1,184 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef _LIBM_H
+#define _LIBM_H
+
+#include <stdint.h>
+#include <float.h>
+#include <math.h>
+#include <complex.h>
+#include <endian.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
+union ldshape {
+	long double f;
+	struct {
+		uint64_t m;
+		uint16_t se;
+	} i;
+};
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
+union ldshape {
+	long double f;
+	struct {
+		uint64_t lo;
+		uint32_t mid;
+		uint16_t top;
+		uint16_t se;
+	} i;
+	struct {
+		uint64_t lo;
+		uint64_t hi;
+	} i2;
+};
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
+union ldshape {
+	long double f;
+	struct {
+		uint16_t se;
+		uint16_t top;
+		uint32_t mid;
+		uint64_t lo;
+	} i;
+	struct {
+		uint64_t hi;
+		uint64_t lo;
+	} i2;
+};
+#else
+#error Unsupported long double representation
+#endif
+
+#define FORCE_EVAL(x) do {                        \
+	if (sizeof(x) == sizeof(float)) {         \
+		volatile float __x;               \
+		__x = (x);                        \
+	} else if (sizeof(x) == sizeof(double)) { \
+		volatile double __x;              \
+		__x = (x);                        \
+	} else {                                  \
+		volatile long double __x;         \
+		__x = (x);                        \
+	}                                         \
+} while(0)
+
+/* Get two 32 bit ints from a double.  */
+#define EXTRACT_WORDS(hi,lo,d)                    \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  (hi) = __u.i >> 32;                             \
+  (lo) = (uint32_t)__u.i;                         \
+} while (0)
+
+/* Get the more significant 32 bit int from a double.  */
+#define GET_HIGH_WORD(hi,d)                       \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  (hi) = __u.i >> 32;                             \
+} while (0)
+
+/* Get the less significant 32 bit int from a double.  */
+#define GET_LOW_WORD(lo,d)                        \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  (lo) = (uint32_t)__u.i;                         \
+} while (0)
+
+/* Set a double from two 32 bit ints.  */
+#define INSERT_WORDS(d,hi,lo)                     \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo);  \
+  (d) = __u.f;                                    \
+} while (0)
+
+/* Set the more significant 32 bits of a double from an int.  */
+#define SET_HIGH_WORD(d,hi)                       \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  __u.i &= 0xffffffff;                            \
+  __u.i |= (uint64_t)(hi) << 32;                  \
+  (d) = __u.f;                                    \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int.  */
+#define SET_LOW_WORD(d,lo)                        \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  __u.i &= 0xffffffff00000000ull;                 \
+  __u.i |= (uint32_t)(lo);                        \
+  (d) = __u.f;                                    \
+} while (0)
+
+/* Get a 32 bit int from a float.  */
+#define GET_FLOAT_WORD(w,d)                       \
+do {                                              \
+  union {float f; uint32_t i;} __u;               \
+  __u.f = (d);                                    \
+  (w) = __u.i;                                    \
+} while (0)
+
+/* Set a float from a 32 bit int.  */
+#define SET_FLOAT_WORD(d,w)                       \
+do {                                              \
+  union {float f; uint32_t i;} __u;               \
+  __u.i = (w);                                    \
+  (d) = __u.f;                                    \
+} while (0)
+
+#undef __CMPLX
+#undef CMPLX
+#undef CMPLXF
+#undef CMPLXL
+
+#define __CMPLX(x, y, t) \
+	((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z)
+
+#define CMPLX(x, y) __CMPLX(x, y, double)
+#define CMPLXF(x, y) __CMPLX(x, y, float)
+#define CMPLXL(x, y) __CMPLX(x, y, long double)
+
+/* fdlibm kernel functions */
+
+int    __rem_pio2_large(double*,double*,int,int,int);
+
+int    __rem_pio2(double,double*);
+double __sin(double,double,int);
+double __cos(double,double);
+double __tan(double,double,int);
+double __expo2(double);
+double complex __ldexp_cexp(double complex,int);
+
+int    __rem_pio2f(float,double*);
+float  __sindf(double);
+float  __cosdf(double);
+float  __tandf(double,int);
+float  __expo2f(float);
+float complex __ldexp_cexpf(float complex,int);
+
+int __rem_pio2l(long double, long double *);
+long double __sinl(long double, long double, int);
+long double __cosl(long double, long double);
+long double __tanl(long double, long double, int);
+
+/* polynomial evaluation */
+long double __polevll(long double, const long double *, int);
+long double __p1evll(long double, const long double *, int);
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/locale_impl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/locale_impl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/locale_impl.h	(revision 398)
@@ -0,0 +1,40 @@
+#ifndef _LOCALE_IMPL_H
+#define _LOCALE_IMPL_H
+
+#include <locale.h>
+#include <stdlib.h>
+#include "libc.h"
+#include "pthread_impl.h"
+
+#define LOCALE_NAME_MAX 23
+
+struct __locale_map {
+	const void *map;
+	size_t map_size;
+	char name[LOCALE_NAME_MAX+1];
+	const struct __locale_map *next;
+};
+
+extern const struct __locale_map __c_dot_utf8;
+extern const struct __locale_struct __c_locale;
+extern const struct __locale_struct __c_dot_utf8_locale;
+
+const struct __locale_map *__get_locale(int, const char *);
+const char *__mo_lookup(const void *, size_t, const char *);
+const char *__lctrans(const char *, const struct __locale_map *);
+const char *__lctrans_cur(const char *);
+
+#define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)])
+#define LCTRANS_CUR(msg) __lctrans_cur(msg)
+
+#define C_LOCALE ((locale_t)&__c_locale)
+#define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale)
+
+#define CURRENT_LOCALE (__pthread_self()->locale)
+
+#define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])
+
+#undef MB_CUR_MAX
+#define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/procfdname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/procfdname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/procfdname.c	(revision 398)
@@ -0,0 +1,13 @@
+void __procfdname(char *buf, unsigned fd)
+{
+	unsigned i, j;
+	for (i=0; (buf[i] = "/proc/self/fd/"[i]); i++);
+	if (!fd) {
+		buf[i] = '0';
+		buf[i+1] = 0;
+		return;
+	}
+	for (j=fd; j; j/=10, i++);
+	buf[i] = 0;
+	for (; fd; fd/=10) buf[--i] = '0' + fd%10;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/pthread_impl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/pthread_impl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/pthread_impl.h	(revision 398)
@@ -0,0 +1,153 @@
+#ifndef _PTHREAD_IMPL_H
+#define _PTHREAD_IMPL_H
+
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+#include <limits.h>
+#include "libc.h"
+#include "syscall.h"
+#include "atomic.h"
+#include "futex.h"
+
+#define pthread __pthread
+
+struct pthread {
+	struct pthread *self;
+	void **dtv, *unused1, *unused2;
+	uintptr_t sysinfo;
+	uintptr_t canary, canary2;
+	pid_t tid, pid;
+	int tsd_used, errno_val;
+	volatile int cancel, canceldisable, cancelasync;
+	int detached;
+	unsigned char *map_base;
+	size_t map_size;
+	void *stack;
+	size_t stack_size;
+	void *start_arg;
+	void *(*start)(void *);
+	void *result;
+	struct __ptcb *cancelbuf;
+	void **tsd;
+	volatile int dead;
+	struct {
+		volatile void *volatile head;
+		long off;
+		volatile void *volatile pending;
+	} robust_list;
+	int unblock_cancel;
+	volatile int timer_id;
+	locale_t locale;
+	volatile int killlock[2];
+	volatile int exitlock[2];
+	volatile int startlock[2];
+	unsigned long sigmask[_NSIG/8/sizeof(long)];
+	char *dlerror_buf;
+	int dlerror_flag;
+	void *stdio_locks;
+	uintptr_t canary_at_end;
+	void **dtv_copy;
+};
+
+struct __timer {
+	int timerid;
+	pthread_t thread;
+};
+
+#define __SU (sizeof(size_t)/sizeof(int))
+
+#define _a_stacksize __u.__s[0]
+#define _a_guardsize __u.__s[1]
+#define _a_stackaddr __u.__s[2]
+#define _a_detach __u.__i[3*__SU+0]
+#define _a_sched __u.__i[3*__SU+1]
+#define _a_policy __u.__i[3*__SU+2]
+#define _a_prio __u.__i[3*__SU+3]
+#define _m_type __u.__i[0]
+#define _m_lock __u.__vi[1]
+#define _m_waiters __u.__vi[2]
+#define _m_prev __u.__p[3]
+#define _m_next __u.__p[4]
+#define _m_count __u.__i[5]
+#define _c_shared __u.__p[0]
+#define _c_seq __u.__vi[2]
+#define _c_waiters __u.__vi[3]
+#define _c_clock __u.__i[4]
+#define _c_lock __u.__vi[8]
+#define _c_head __u.__p[1]
+#define _c_tail __u.__p[5]
+#define _rw_lock __u.__vi[0]
+#define _rw_waiters __u.__vi[1]
+#define _rw_shared __u.__i[2]
+#define _b_lock __u.__vi[0]
+#define _b_waiters __u.__vi[1]
+#define _b_limit __u.__i[2]
+#define _b_count __u.__vi[3]
+#define _b_waiters2 __u.__vi[4]
+#define _b_inst __u.__p[3]
+
+#include "pthread_arch.h"
+
+#ifndef CANARY
+#define CANARY canary
+#endif
+
+#ifndef DTP_OFFSET
+#define DTP_OFFSET 0
+#endif
+
+#ifndef tls_mod_off_t
+#define tls_mod_off_t size_t
+#endif
+
+#define SIGTIMER 32
+#define SIGCANCEL 33
+#define SIGSYNCCALL 34
+
+#define SIGALL_SET ((sigset_t *)(const unsigned long long [2]){ -1,-1 })
+#define SIGPT_SET \
+	((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \
+	[sizeof(long)==4] = 3UL<<(32*(sizeof(long)>4)) })
+#define SIGTIMER_SET \
+	((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \
+	 0x80000000 })
+
+pthread_t __pthread_self_init(void);
+
+int __clone(int (*)(void *), void *, int, void *, ...);
+int __set_thread_area(void *);
+int __libc_sigaction(int, const struct sigaction *, struct sigaction *);
+int __libc_sigprocmask(int, const sigset_t *, sigset_t *);
+void __lock(volatile int *);
+void __unmapself(void *, size_t);
+
+void __vm_wait(void);
+void __vm_lock(void);
+void __vm_unlock(void);
+
+int __timedwait(volatile int *, int, clockid_t, const struct timespec *, int);
+int __timedwait_cp(volatile int *, int, clockid_t, const struct timespec *, int);
+void __wait(volatile int *, volatile int *, int, int);
+static inline void __wake(volatile void *addr, int cnt, int priv)
+{
+	if (priv) priv = FUTEX_PRIVATE;
+	if (cnt<0) cnt = INT_MAX;
+	__syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS ||
+	__syscall(SYS_futex, addr, FUTEX_WAKE, cnt);
+}
+
+void __acquire_ptc(void);
+void __release_ptc(void);
+void __inhibit_ptc(void);
+
+void __block_all_sigs(void *);
+void __block_app_sigs(void *);
+void __restore_sigs(void *);
+
+#define DEFAULT_STACK_SIZE 81920
+#define DEFAULT_GUARD_SIZE 4096
+
+#define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1)
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/shgetc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/shgetc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/shgetc.c	(revision 398)
@@ -0,0 +1,27 @@
+#include "shgetc.h"
+
+void __shlim(FILE *f, off_t lim)
+{
+	f->shlim = lim;
+	f->shcnt = f->rend - f->rpos;
+	if (lim && f->shcnt > lim)
+		f->shend = f->rpos + lim;
+	else
+		f->shend = f->rend;
+}
+
+int __shgetc(FILE *f)
+{
+	int c;
+	if (f->shlim && f->shcnt >= f->shlim || (c=__uflow(f)) < 0) {
+		f->shend = 0;
+		return EOF;
+	}
+	if (f->shlim && f->rend - f->rpos > f->shlim - f->shcnt - 1)
+		f->shend = f->rpos + (f->shlim - f->shcnt - 1);
+	else
+		f->shend = f->rend;
+	if (f->rend) f->shcnt += f->rend - f->rpos + 1;
+	if (f->rpos[-1] != c) f->rpos[-1] = c;
+	return c;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/shgetc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/shgetc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/shgetc.h	(revision 398)
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+
+void __shlim(FILE *, off_t);
+int __shgetc(FILE *);
+
+#define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->rend))
+#define shlim(f, lim) __shlim((f), (lim))
+#define shgetc(f) (((f)->rpos < (f)->shend) ? *(f)->rpos++ : __shgetc(f))
+#define shunget(f) ((f)->shend ? (void)(f)->rpos-- : (void)0)
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/stdio_impl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/stdio_impl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/stdio_impl.h	(revision 398)
@@ -0,0 +1,97 @@
+#ifndef _STDIO_IMPL_H
+#define _STDIO_IMPL_H
+
+#include <stdio.h>
+#include "syscall.h"
+#include "libc.h"
+
+#define UNGET 8
+
+#define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0)
+#define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0)
+#define FUNLOCK(f) if (__need_unlock) __unlockfile((f)); else
+
+#define F_PERM 1
+#define F_NORD 4
+#define F_NOWR 8
+#define F_EOF 16
+#define F_ERR 32
+#define F_SVB 64
+#define F_APP 128
+
+struct _IO_FILE {
+	unsigned flags;
+	unsigned char *rpos, *rend;
+	int (*close)(FILE *);
+	unsigned char *wend, *wpos;
+	unsigned char *mustbezero_1;
+	unsigned char *wbase;
+	size_t (*read)(FILE *, unsigned char *, size_t);
+	size_t (*write)(FILE *, const unsigned char *, size_t);
+	off_t (*seek)(FILE *, off_t, int);
+	unsigned char *buf;
+	size_t buf_size;
+	FILE *prev, *next;
+	int fd;
+	int pipe_pid;
+	long lockcount;
+	short dummy3;
+	signed char mode;
+	signed char lbf;
+	volatile int lock;
+	volatile int waiters;
+	void *cookie;
+	off_t off;
+	char *getln_buf;
+	void *mustbezero_2;
+	unsigned char *shend;
+	off_t shlim, shcnt;
+	FILE *prev_locked, *next_locked;
+	struct __locale_struct *locale;
+};
+
+size_t __stdio_read(FILE *, unsigned char *, size_t);
+size_t __stdio_write(FILE *, const unsigned char *, size_t);
+size_t __stdout_write(FILE *, const unsigned char *, size_t);
+off_t __stdio_seek(FILE *, off_t, int);
+int __stdio_close(FILE *);
+
+size_t __string_read(FILE *, unsigned char *, size_t);
+
+int __toread(FILE *);
+int __towrite(FILE *);
+
+#if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303)
+__attribute__((visibility("protected")))
+#endif
+int __overflow(FILE *, int), __uflow(FILE *);
+
+int __fseeko(FILE *, off_t, int);
+int __fseeko_unlocked(FILE *, off_t, int);
+off_t __ftello(FILE *);
+off_t __ftello_unlocked(FILE *);
+size_t __fwritex(const unsigned char *, size_t, FILE *);
+int __putc_unlocked(int, FILE *);
+
+FILE *__fdopen(int, const char *);
+int __fmodeflags(const char *);
+
+FILE *__ofl_add(FILE *f);
+FILE **__ofl_lock(void);
+void __ofl_unlock(void);
+
+#define feof(f) ((f)->flags & F_EOF)
+#define ferror(f) ((f)->flags & F_ERR)
+
+#define getc_unlocked(f) \
+	( ((f)->rpos < (f)->rend) ? *(f)->rpos++ : __uflow((f)) )
+
+#define putc_unlocked(c, f) \
+	( ((unsigned char)(c)!=(f)->lbf && (f)->wpos<(f)->wend) \
+	? *(f)->wpos++ = (c) : __overflow((f),(c)) )
+
+/* Caller-allocated FILE * operations */
+FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t);
+int __fclose_ca(FILE *);
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/syscall.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/syscall.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/syscall.h	(revision 398)
@@ -0,0 +1,247 @@
+#ifndef _INTERNAL_SYSCALL_H
+#define _INTERNAL_SYSCALL_H
+
+#include <sys/syscall.h>
+#include "syscall_arch.h"
+
+#ifndef SYSCALL_RLIM_INFINITY
+#define SYSCALL_RLIM_INFINITY (~0ULL)
+#endif
+
+#ifndef SYSCALL_MMAP2_UNIT
+#define SYSCALL_MMAP2_UNIT 4096ULL
+#endif
+
+#ifndef __SYSCALL_LL_PRW
+#define __SYSCALL_LL_PRW(x) __SYSCALL_LL_O(x)
+#endif
+
+#ifndef __scc
+#define __scc(X) ((long) (X))
+typedef long syscall_arg_t;
+#endif
+#if 0
+__attribute__((visibility("hidden")))
+long __syscall_ret(unsigned long), __syscall(syscall_arg_t, ...),
+	__syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t,
+	             syscall_arg_t, syscall_arg_t, syscall_arg_t);
+
+#ifdef SYSCALL_NO_INLINE
+#define __syscall0(n) (__syscall)(n)
+#define __syscall1(n,a) (__syscall)(n,__scc(a))
+#define __syscall2(n,a,b) (__syscall)(n,__scc(a),__scc(b))
+#define __syscall3(n,a,b,c) (__syscall)(n,__scc(a),__scc(b),__scc(c))
+#define __syscall4(n,a,b,c,d) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d))
+#define __syscall5(n,a,b,c,d,e) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
+#define __syscall6(n,a,b,c,d,e,f) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
+#else
+#define __syscall1(n,a) __syscall1(n,__scc(a))
+#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b))
+#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c))
+#define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d))
+#define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
+#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
+#endif
+#define __syscall7(n,a,b,c,d,e,f,g) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g))
+
+#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
+#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
+#define __SYSCALL_CONCAT_X(a,b) a##b
+#define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b)
+#define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
+#endif
+#define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__)
+//#define syscall(...) __syscall_ret(__syscall(__VA_ARGS__))
+
+#define socketcall __socketcall
+#define socketcall_cp __socketcall_cp
+#if 0
+#define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0)
+#define __syscall_cp1(n,a) (__syscall_cp)(n,__scc(a),0,0,0,0,0)
+#define __syscall_cp2(n,a,b) (__syscall_cp)(n,__scc(a),__scc(b),0,0,0,0)
+#define __syscall_cp3(n,a,b,c) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),0,0,0)
+#define __syscall_cp4(n,a,b,c,d) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),0,0)
+#define __syscall_cp5(n,a,b,c,d,e) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),0)
+#define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
+#endif
+#define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
+//#define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
+
+#ifndef SYSCALL_USE_SOCKETCALL
+#define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_##nm, a, b, c, d, e, f)
+#define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_##nm, a, b, c, d, e, f)
+#else
+#define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_socketcall, __SC_##nm, \
+    ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
+#define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_socketcall, __SC_##nm, \
+    ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
+#endif
+
+/* fixup legacy 16-bit junk */
+
+#ifdef SYS_getuid32
+#undef SYS_lchown
+#undef SYS_getuid
+#undef SYS_getgid
+#undef SYS_geteuid
+#undef SYS_getegid
+#undef SYS_setreuid
+#undef SYS_setregid
+#undef SYS_getgroups
+#undef SYS_setgroups
+#undef SYS_fchown
+#undef SYS_setresuid
+#undef SYS_getresuid
+#undef SYS_setresgid
+#undef SYS_getresgid
+#undef SYS_chown
+#undef SYS_setuid
+#undef SYS_setgid
+#undef SYS_setfsuid
+#undef SYS_setfsgid
+#define SYS_lchown SYS_lchown32
+#define SYS_getuid SYS_getuid32
+#define SYS_getgid SYS_getgid32
+#define SYS_geteuid SYS_geteuid32
+#define SYS_getegid SYS_getegid32
+#define SYS_setreuid SYS_setreuid32
+#define SYS_setregid SYS_setregid32
+#define SYS_getgroups SYS_getgroups32
+#define SYS_setgroups SYS_setgroups32
+#define SYS_fchown SYS_fchown32
+#define SYS_setresuid SYS_setresuid32
+#define SYS_getresuid SYS_getresuid32
+#define SYS_setresgid SYS_setresgid32
+#define SYS_getresgid SYS_getresgid32
+#define SYS_chown SYS_chown32
+#define SYS_setuid SYS_setuid32
+#define SYS_setgid SYS_setgid32
+#define SYS_setfsuid SYS_setfsuid32
+#define SYS_setfsgid SYS_setfsgid32
+#endif
+
+
+/* fixup legacy 32-bit-vs-lfs64 junk */
+
+#ifdef SYS_fcntl64
+#undef SYS_fcntl
+#define SYS_fcntl SYS_fcntl64
+#endif
+
+#ifdef SYS_getdents64
+#undef SYS_getdents
+#define SYS_getdents SYS_getdents64
+#endif
+
+#ifdef SYS_ftruncate64
+#undef SYS_ftruncate
+#undef SYS_truncate
+#define SYS_ftruncate SYS_ftruncate64
+#define SYS_truncate SYS_truncate64
+#endif
+
+#ifdef SYS_stat64
+#undef SYS_stat
+#define SYS_stat SYS_stat64
+#endif
+
+#ifdef SYS_fstat64
+#undef SYS_fstat
+#define SYS_fstat SYS_fstat64
+#endif
+
+#ifdef SYS_lstat64
+#undef SYS_lstat
+#define SYS_lstat SYS_lstat64
+#endif
+
+#ifdef SYS_statfs64
+#undef SYS_statfs
+#define SYS_statfs SYS_statfs64
+#endif
+
+#ifdef SYS_fstatfs64
+#undef SYS_fstatfs
+#define SYS_fstatfs SYS_fstatfs64
+#endif
+
+#if defined(SYS_newfstatat)
+#undef SYS_fstatat
+#define SYS_fstatat SYS_newfstatat
+#elif defined(SYS_fstatat64)
+#undef SYS_fstatat
+#define SYS_fstatat SYS_fstatat64
+#endif
+
+#ifdef SYS_ugetrlimit
+#undef SYS_getrlimit
+#define SYS_getrlimit SYS_ugetrlimit
+#endif
+
+#ifdef SYS__newselect
+#undef SYS_select
+#define SYS_select SYS__newselect
+#endif
+
+#ifdef SYS_pread64
+#undef SYS_pread
+#undef SYS_pwrite
+#define SYS_pread SYS_pread64
+#define SYS_pwrite SYS_pwrite64
+#endif
+
+#ifdef SYS_fadvise64_64
+#undef SYS_fadvise
+#define SYS_fadvise SYS_fadvise64_64
+#elif defined(SYS_fadvise64)
+#undef SYS_fadvise
+#define SYS_fadvise SYS_fadvise64
+#endif
+
+#ifdef SYS_sendfile64
+#undef SYS_sendfile
+#define SYS_sendfile SYS_sendfile64
+#endif
+
+/* socketcall calls */
+
+#define __SC_socket      1
+#define __SC_bind        2
+#define __SC_connect     3
+#define __SC_listen      4
+#define __SC_accept      5
+#define __SC_getsockname 6
+#define __SC_getpeername 7
+#define __SC_socketpair  8
+#define __SC_send        9
+#define __SC_recv        10
+#define __SC_sendto      11
+#define __SC_recvfrom    12
+#define __SC_shutdown    13
+#define __SC_setsockopt  14
+#define __SC_getsockopt  15
+#define __SC_sendmsg     16
+#define __SC_recvmsg     17
+#define __SC_accept4     18
+#define __SC_recvmmsg    19
+#define __SC_sendmmsg    20
+
+#ifdef SYS_open
+#define __sys_open2(x,pn,fl) __syscall2(SYS_open, pn, (fl)|O_LARGEFILE)
+#define __sys_open3(x,pn,fl,mo) __syscall3(SYS_open, pn, (fl)|O_LARGEFILE, mo)
+#define __sys_open_cp2(x,pn,fl) __syscall_cp2(SYS_open, pn, (fl)|O_LARGEFILE)
+#define __sys_open_cp3(x,pn,fl,mo) __syscall_cp3(SYS_open, pn, (fl)|O_LARGEFILE, mo)
+#else
+#define __sys_open2(x,pn,fl) __syscall3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE)
+#define __sys_open3(x,pn,fl,mo) __syscall4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo)
+#define __sys_open_cp2(x,pn,fl) __syscall_cp3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE)
+#define __sys_open_cp3(x,pn,fl,mo) __syscall_cp4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo)
+#endif
+
+#define __sys_open(...) __SYSCALL_DISP(__sys_open,,__VA_ARGS__)
+#define sys_open(...) __syscall_ret(__sys_open(__VA_ARGS__))
+
+#define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__)
+#define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__))
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/syscall_ret.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/syscall_ret.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/syscall_ret.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <errno.h>
+#include "syscall.h"
+
+long __syscall_ret(unsigned long r)
+{
+	if (r > -4096UL) {
+		errno = -r;
+		return -1;
+	}
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/vdso.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/vdso.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/vdso.c	(revision 398)
@@ -0,0 +1,93 @@
+#include <elf.h>
+#include <link.h>
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#include "libc.h"
+#include "syscall.h"
+
+#ifdef VDSO_USEFUL
+
+#if ULONG_MAX == 0xffffffff
+typedef Elf32_Ehdr Ehdr;
+typedef Elf32_Phdr Phdr;
+typedef Elf32_Sym Sym;
+typedef Elf32_Verdef Verdef;
+typedef Elf32_Verdaux Verdaux;
+#else
+typedef Elf64_Ehdr Ehdr;
+typedef Elf64_Phdr Phdr;
+typedef Elf64_Sym Sym;
+typedef Elf64_Verdef Verdef;
+typedef Elf64_Verdaux Verdaux;
+#endif
+
+static int checkver(Verdef *def, int vsym, const char *vername, char *strings)
+{
+	vsym &= 0x7fff;
+	for (;;) {
+		if (!(def->vd_flags & VER_FLG_BASE)
+		  && (def->vd_ndx & 0x7fff) == vsym)
+			break;
+		if (def->vd_next == 0)
+			return 0;
+		def = (Verdef *)((char *)def + def->vd_next);
+	}
+	Verdaux *aux = (Verdaux *)((char *)def + def->vd_aux);
+	return !strcmp(vername, strings + aux->vda_name);
+}
+
+#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON)
+#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
+
+void *__vdsosym(const char *vername, const char *name)
+{
+	size_t i;
+	for (i=0; libc.auxv[i] != AT_SYSINFO_EHDR; i+=2)
+		if (!libc.auxv[i]) return 0;
+	if (!libc.auxv[i+1]) return 0;
+	Ehdr *eh = (void *)libc.auxv[i+1];
+	Phdr *ph = (void *)((char *)eh + eh->e_phoff);
+	size_t *dynv=0, base=-1;
+	for (i=0; i<eh->e_phnum; i++, ph=(void *)((char *)ph+eh->e_phentsize)) {
+		if (ph->p_type == PT_LOAD)
+			base = (size_t)eh + ph->p_offset - ph->p_vaddr;
+		else if (ph->p_type == PT_DYNAMIC)
+			dynv = (void *)((char *)eh + ph->p_offset);
+	}
+	if (!dynv || base==(size_t)-1) return 0;
+
+	char *strings = 0;
+	Sym *syms = 0;
+	Elf_Symndx *hashtab = 0;
+	uint16_t *versym = 0;
+	Verdef *verdef = 0;
+	
+	for (i=0; dynv[i]; i+=2) {
+		void *p = (void *)(base + dynv[i+1]);
+		switch(dynv[i]) {
+		case DT_STRTAB: strings = p; break;
+		case DT_SYMTAB: syms = p; break;
+		case DT_HASH: hashtab = p; break;
+		case DT_VERSYM: versym = p; break;
+		case DT_VERDEF: verdef = p; break;
+		}
+	}	
+
+	if (!strings || !syms || !hashtab) return 0;
+	if (!verdef) versym = 0;
+
+	for (i=0; i<hashtab[1]; i++) {
+		if (!(1<<(syms[i].st_info&0xf) & OK_TYPES)) continue;
+		if (!(1<<(syms[i].st_info>>4) & OK_BINDS)) continue;
+		if (!syms[i].st_shndx) continue;
+		if (strcmp(name, strings+syms[i].st_name)) continue;
+		if (versym && !checkver(verdef, versym[i], vername, strings))
+			continue;
+		return (void *)(base + syms[i].st_value);
+	}
+
+	return 0;
+}
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/version.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/version.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/version.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "version.h"
+
+static const char version[] = VERSION;
+
+__attribute__((__visibility__("hidden")))
+const char *__libc_get_version()
+{
+	return version;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/version.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/version.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/version.h	(revision 398)
@@ -0,0 +1,1 @@
+#define VERSION "1.1.16"
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/vis.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/vis.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/internal/vis.h	(revision 398)
@@ -0,0 +1,27 @@
+/* This file is only used if enabled in the build system, in which case it is
+ * included automatically via command line options. It is not included
+ * explicitly by any source files or other headers. Its purpose is to
+ * override default visibilities to reduce the size and performance costs
+ * of position-independent code. */
+
+#if !defined(CRT) && !defined(__ASSEMBLER__)
+
+/* Conceptually, all symbols should be protected, but some toolchains
+ * fail to support copy relocations for protected data, so exclude all
+ * exported data symbols. */
+
+__attribute__((__visibility__("default")))
+extern struct _IO_FILE *const stdin, *const stdout, *const stderr;
+
+__attribute__((__visibility__("default")))
+extern int optind, opterr, optopt, optreset, __optreset, getdate_err, h_errno, daylight, __daylight, signgam, __signgam;
+
+__attribute__((__visibility__("default")))
+extern long timezone, __timezone;
+
+__attribute__((__visibility__("default")))
+extern char *optarg, **environ, **__environ, *tzname[2], *__tzname[2], *__progname, *__progname_full;
+
+#pragma GCC visibility push(protected)
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/ftok.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/ftok.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/ftok.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <sys/ipc.h>
+#include <sys/stat.h>
+
+key_t ftok(const char *path, int id)
+{
+	struct stat st;
+	if (stat(path, &st) < 0) return -1;
+
+	return ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((id & 0xffu) << 24));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/ipc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/ipc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/ipc.h	(revision 398)
@@ -0,0 +1,12 @@
+#define IPCOP_semop      1
+#define IPCOP_semget     2
+#define IPCOP_semctl     3
+#define IPCOP_semtimedop 4
+#define IPCOP_msgsnd    11
+#define IPCOP_msgrcv    12
+#define IPCOP_msgget    13
+#define IPCOP_msgctl    14
+#define IPCOP_shmat     21
+#define IPCOP_shmdt     22
+#define IPCOP_shmget    23
+#define IPCOP_shmctl    24
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgctl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgctl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgctl.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/msg.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int msgctl(int q, int cmd, struct msqid_ds *buf)
+{
+#ifdef SYS_msgctl
+	return syscall(SYS_msgctl, q, cmd | IPC_64, buf);
+#else
+	return syscall(SYS_ipc, IPCOP_msgctl, q, cmd | IPC_64, 0, buf, 0);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgget.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgget.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgget.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/msg.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int msgget(key_t k, int flag)
+{
+#ifdef SYS_msgget
+	return syscall(SYS_msgget, k, flag);
+#else
+	return syscall(SYS_ipc, IPCOP_msgget, k, flag);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgrcv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgrcv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgrcv.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <sys/msg.h>
+#include "syscall.h"
+#include "ipc.h"
+#include "libc.h"
+
+ssize_t msgrcv(int q, void *m, size_t len, long type, int flag)
+{
+#ifdef SYS_msgrcv
+	return syscall_cp(SYS_msgrcv, q, m, len, type, flag);
+#else
+	return syscall_cp(SYS_ipc, IPCOP_msgrcv, q, len, flag, ((long[]){ (long)m, type }));
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgsnd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgsnd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/msgsnd.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <sys/msg.h>
+#include "syscall.h"
+#include "ipc.h"
+#include "libc.h"
+
+int msgsnd(int q, const void *m, size_t len, int flag)
+{
+#ifdef SYS_msgsnd
+	return syscall_cp(SYS_msgsnd, q, m, len, flag);
+#else
+	return syscall_cp(SYS_ipc, IPCOP_msgsnd, q, len, flag, m);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semctl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semctl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semctl.c	(revision 398)
@@ -0,0 +1,28 @@
+#include <sys/sem.h>
+#include <stdarg.h>
+#include "syscall.h"
+#include "ipc.h"
+
+union semun {
+	int val;
+	struct semid_ds *buf;
+	unsigned short *array;
+};
+
+int semctl(int id, int num, int cmd, ...)
+{
+	union semun arg = {0};
+	va_list ap;
+	switch (cmd) {
+	case SETVAL: case GETALL: case SETALL: case IPC_STAT: case IPC_SET:
+	case IPC_INFO: case SEM_INFO: case SEM_STAT:
+		va_start(ap, cmd);
+		arg = va_arg(ap, union semun);
+		va_end(ap);
+	}
+#ifdef SYS_semctl
+	return syscall(SYS_semctl, id, num, cmd | IPC_64, arg.buf);
+#else
+	return syscall(SYS_ipc, IPCOP_semctl, id, num, cmd | IPC_64, &arg.buf);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semget.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semget.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semget.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <sys/sem.h>
+#include <limits.h>
+#include <errno.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int semget(key_t key, int n, int fl)
+{
+	/* The kernel uses the wrong type for the sem_nsems member
+	 * of struct semid_ds, and thus might not check that the
+	 * n fits in the correct (per POSIX) userspace type, so
+	 * we have to check here. */
+	if (n > USHRT_MAX) return __syscall_ret(-EINVAL);
+#ifdef SYS_semget
+	return syscall(SYS_semget, key, n, fl);
+#else
+	return syscall(SYS_ipc, IPCOP_semget, key, n, fl);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semop.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semop.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semop.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/sem.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int semop(int id, struct sembuf *buf, size_t n)
+{
+#ifdef SYS_semop
+	return syscall(SYS_semop, id, buf, n);
+#else
+	return syscall(SYS_ipc, IPCOP_semop, id, n, 0, buf);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semtimedop.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semtimedop.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/semtimedop.c	(revision 398)
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <sys/sem.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int semtimedop(int id, struct sembuf *buf, size_t n, const struct timespec *ts)
+{
+#ifdef SYS_semtimedop
+	return syscall(SYS_semtimedop, id, buf, n, ts);
+#else
+	return syscall(SYS_ipc, IPCOP_semtimedop, id, n, 0, buf, ts);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmat.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <sys/shm.h>
+#include "syscall.h"
+#include "ipc.h"
+
+#ifdef SYS_shmat
+void *shmat(int id, const void *addr, int flag)
+{
+	return (void *)syscall(SYS_shmat, id, addr, flag);
+}
+#else
+void *shmat(int id, const void *addr, int flag)
+{
+	unsigned long ret;
+	ret = syscall(SYS_ipc, IPCOP_shmat, id, flag, &addr, addr);
+	return (ret > -(unsigned long)SHMLBA) ? (void *)ret : (void *)addr;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmctl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmctl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmctl.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/shm.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int shmctl(int id, int cmd, struct shmid_ds *buf)
+{
+#ifdef SYS_shmctl
+	return syscall(SYS_shmctl, id, cmd | IPC_64, buf);
+#else
+	return syscall(SYS_ipc, IPCOP_shmctl, id, cmd | IPC_64, 0, buf, 0);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmdt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmdt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmdt.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/shm.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int shmdt(const void *addr)
+{
+#ifdef SYS_shmdt
+	return syscall(SYS_shmdt, addr);
+#else
+	return syscall(SYS_ipc, IPCOP_shmdt, 0, 0, 0, addr);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmget.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmget.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ipc/shmget.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <sys/shm.h>
+#include <stdint.h>
+#include "syscall.h"
+#include "ipc.h"
+
+int shmget(key_t key, size_t size, int flag)
+{
+	if (size > PTRDIFF_MAX) size = SIZE_MAX;
+#ifdef SYS_shmget
+	return syscall(SYS_shmget, key, size, flag);
+#else
+	return syscall(SYS_ipc, IPCOP_shmget, key, size, flag);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/__dlsym.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/__dlsym.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/__dlsym.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <dlfcn.h>
+#include "libc.h"
+
+__attribute__((__visibility__("hidden")))
+void __dl_seterr(const char *, ...);
+
+static void *stub_dlsym(void *restrict p, const char *restrict s, void *restrict ra)
+{
+	__dl_seterr("Symbol not found: %s", s);
+	return 0;
+}
+
+weak_alias(stub_dlsym, __dlsym);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dl_iterate_phdr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dl_iterate_phdr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dl_iterate_phdr.c	(revision 398)
@@ -0,0 +1,47 @@
+#include <elf.h>
+#include <link.h>
+#include "libc.h"
+
+#define AUX_CNT 38
+
+__attribute__((__weak__, __visibility__("hidden")))
+extern const size_t _DYNAMIC[];
+
+static int static_dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
+{
+	unsigned char *p;
+	ElfW(Phdr) *phdr, *tls_phdr=0;
+	size_t base = 0;
+	size_t n;
+	struct dl_phdr_info info;
+	size_t i, aux[AUX_CNT] = {0};
+
+	for (i=0; libc.auxv[i]; i+=2)
+		if (libc.auxv[i]<AUX_CNT) aux[libc.auxv[i]] = libc.auxv[i+1];
+
+	for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
+		phdr = (void *)p;
+		if (phdr->p_type == PT_PHDR)
+			base = aux[AT_PHDR] - phdr->p_vaddr;
+		if (phdr->p_type == PT_DYNAMIC && _DYNAMIC)
+			base = (size_t)_DYNAMIC - phdr->p_vaddr;
+		if (phdr->p_type == PT_TLS)
+			tls_phdr = phdr;
+	}
+	info.dlpi_addr  = base;
+	info.dlpi_name  = "/proc/self/exe";
+	info.dlpi_phdr  = (void *)aux[AT_PHDR];
+	info.dlpi_phnum = aux[AT_PHNUM];
+	info.dlpi_adds  = 0;
+	info.dlpi_subs  = 0;
+	if (tls_phdr) {
+		info.dlpi_tls_modid = 1;
+		info.dlpi_tls_data = (void *)(base + tls_phdr->p_vaddr);
+	} else {
+		info.dlpi_tls_modid = 0;
+		info.dlpi_tls_data = 0;
+	}
+	return (callback)(&info, sizeof (info), data);
+}
+
+weak_alias(static_dl_iterate_phdr, dl_iterate_phdr);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dladdr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dladdr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dladdr.c	(revision 398)
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include "libc.h"
+
+static int stub_dladdr(const void *addr, Dl_info *info)
+{
+	return 0;
+}
+
+weak_alias(stub_dladdr, dladdr);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlclose.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlclose.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlclose.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <dlfcn.h>
+
+__attribute__((__visibility__("hidden")))
+int __dl_invalid_handle(void *);
+
+int dlclose(void *p)
+{
+	return __dl_invalid_handle(p);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlerror.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlerror.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlerror.c	(revision 398)
@@ -0,0 +1,64 @@
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+char *dlerror()
+{
+	pthread_t self = __pthread_self();
+	if (!self->dlerror_flag) return 0;
+	self->dlerror_flag = 0;
+	char *s = self->dlerror_buf;
+	if (s == (void *)-1)
+		return "Dynamic linker failed to allocate memory for error message";
+	else
+		return s;
+}
+
+void __dl_thread_cleanup(void)
+{
+	pthread_t self = __pthread_self();
+	if (self->dlerror_buf != (void *)-1)
+		free(self->dlerror_buf);
+}
+
+__attribute__((__visibility__("hidden")))
+void __dl_vseterr(const char *fmt, va_list ap)
+{
+	va_list ap2;
+	va_copy(ap2, ap);
+	pthread_t self = __pthread_self();
+	if (self->dlerror_buf != (void *)-1)
+		free(self->dlerror_buf);
+	size_t len = vsnprintf(0, 0, fmt, ap2);
+	va_end(ap2);
+	char *buf = malloc(len+1);
+	if (buf) {
+		vsnprintf(buf, len+1, fmt, ap);
+	} else {
+		buf = (void *)-1;	
+	}
+	self->dlerror_buf = buf;
+	self->dlerror_flag = 1;
+}
+
+__attribute__((__visibility__("hidden")))
+void __dl_seterr(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	__dl_vseterr(fmt, ap);
+	va_end(ap);
+}
+
+__attribute__((__visibility__("hidden")))
+int __dl_invalid_handle(void *);
+
+static int stub_invalid_handle(void *h)
+{
+	__dl_seterr("Invalid library handle %p", (void *)h);
+	return 1;
+}
+
+weak_alias(stub_invalid_handle, __dl_invalid_handle);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlinfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlinfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlinfo.c	(revision 398)
@@ -0,0 +1,19 @@
+#define _GNU_SOURCE
+#include <dlfcn.h>
+
+__attribute__((__visibility__("hidden")))
+int __dl_invalid_handle(void *);
+
+__attribute__((__visibility__("hidden")))
+void __dl_seterr(const char *, ...);
+
+int dlinfo(void *dso, int req, void *res)
+{
+	if (__dl_invalid_handle(dso)) return -1;
+	if (req != RTLD_DI_LINKMAP) {
+		__dl_seterr("Unsupported request %d", req);
+		return -1;
+	}
+	*(struct link_map **)res = dso;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlopen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlopen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlopen.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <dlfcn.h>
+#include "libc.h"
+
+__attribute__((__visibility__("hidden")))
+void __dl_seterr(const char *, ...);
+
+static void *stub_dlopen(const char *file, int mode)
+{
+	__dl_seterr("Dynamic loading not supported");
+	return 0;
+}
+
+weak_alias(stub_dlopen, dlopen);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlsym.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlsym.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/dlsym.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <dlfcn.h>
+
+void *__dlsym(void *restrict, const char *restrict, void *restrict);
+
+void *dlsym(void *restrict p, const char *restrict s)
+{
+	return __dlsym(p, s, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/tlsdesc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/tlsdesc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/ldso/tlsdesc.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <stddef.h>
+#include "libc.h"
+
+__attribute__((__visibility__("hidden")))
+ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();
+
+ptrdiff_t __tlsdesc_static()
+{
+	return 0;
+}
+
+weak_alias(__tlsdesc_static, __tlsdesc_dynamic);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/cuserid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/cuserid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/cuserid.c	(revision 398)
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <pwd.h>
+#include <stdio.h>
+#include <unistd.h>
+
+char *cuserid(char *buf)
+{
+	struct passwd pw, *ppw;
+	long pwb[256];
+	if (getpwuid_r(geteuid(), &pw, (void *)pwb, sizeof pwb, &ppw))
+		return 0;
+	snprintf(buf, L_cuserid, "%s", pw.pw_name);
+	return buf;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/daemon.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/daemon.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/daemon.c	(revision 398)
@@ -0,0 +1,33 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <unistd.h>
+
+int daemon(int nochdir, int noclose)
+{
+	if (!nochdir && chdir("/"))
+		return -1;
+	if (!noclose) {
+		int fd, failed = 0;
+		if ((fd = open("/dev/null", O_RDWR)) < 0) return -1;
+		if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0)
+			failed++;
+		if (fd > 2) close(fd);
+		if (failed) return -1;
+	}
+
+	switch(fork()) {
+	case 0: break;
+	case -1: return -1;
+	default: _exit(0);
+	}
+
+	if (setsid() < 0) return -1;
+
+	switch(fork()) {
+	case 0: break;
+	case -1: return -1;
+	default: _exit(0);
+	}
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/err.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/err.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/err.c	(revision 398)
@@ -0,0 +1,67 @@
+#include <err.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+extern char *__progname;
+
+void vwarn(const char *fmt, va_list ap)
+{
+	fprintf (stderr, "%s: ", __progname);
+	if (fmt) {
+		vfprintf(stderr, fmt, ap);
+		fputs (": ", stderr);
+	}
+	perror(0);
+}
+
+void vwarnx(const char *fmt, va_list ap)
+{
+	fprintf (stderr, "%s: ", __progname);
+	if (fmt) vfprintf(stderr, fmt, ap);
+	putc('\n', stderr);
+}
+
+_Noreturn void verr(int status, const char *fmt, va_list ap)
+{
+	vwarn(fmt, ap);
+	exit(status);
+}
+
+_Noreturn void verrx(int status, const char *fmt, va_list ap)
+{
+	vwarnx(fmt, ap);
+	exit(status);
+}
+
+void warn(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	vwarn(fmt, ap);
+	va_end(ap);
+}
+
+void warnx(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	vwarnx(fmt, ap);
+	va_end(ap);
+}
+
+_Noreturn void err(int status, const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	verr(status, fmt, ap);
+	va_end(ap);
+}
+
+_Noreturn void errx(int status, const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	verrx(status, fmt, ap);
+	va_end(ap);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/euidaccess.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/euidaccess.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/euidaccess.c	(revision 398)
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <fcntl.h>
+#include "libc.h"
+
+int euidaccess(const char *filename, int amode)
+{
+	return faccessat(AT_FDCWD, filename, amode, AT_EACCESS);
+}
+
+weak_alias(euidaccess, eaccess);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/ftw.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/ftw.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/ftw.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <ftw.h>
+#include "libc.h"
+
+int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int fd_limit)
+{
+	/* The following cast assumes that calling a function with one
+	 * argument more than it needs behaves as expected. This is
+	 * actually undefined, but works on all real-world machines. */
+	return nftw(path, (int (*)())fn, fd_limit, FTW_PHYS);
+}
+
+LFS64(ftw);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/futimes.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/futimes.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/futimes.c	(revision 398)
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <sys/time.h>
+
+int futimes(int fd, const struct timeval tv[2])
+{
+	struct timespec times[2];
+	if (!tv) return futimens(fd, 0);
+	times[0].tv_sec  = tv[0].tv_sec;
+	times[0].tv_nsec = tv[0].tv_usec * 1000;
+	times[1].tv_sec  = tv[1].tv_sec;
+	times[1].tv_nsec = tv[1].tv_usec * 1000;
+	return futimens(fd, times);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getdtablesize.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getdtablesize.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getdtablesize.c	(revision 398)
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <limits.h>
+#include <sys/resource.h>
+
+int getdtablesize(void)
+{
+	struct rlimit rl;
+	getrlimit(RLIMIT_NOFILE, &rl);
+	return rl.rlim_cur < INT_MAX ? rl.rlim_cur : INT_MAX;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getloadavg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getloadavg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getloadavg.c	(revision 398)
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <sys/sysinfo.h>
+
+int getloadavg(double *a, int n)
+{
+	struct sysinfo si;
+	if (n <= 0) return n ? -1 : 0;
+	sysinfo(&si);
+	if (n > 3) n = 3;
+	for (int i=0; i<n; i++)
+		a[i] = 1.0/(1<<SI_LOAD_SHIFT) * si.loads[i];
+	return n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getpagesize.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getpagesize.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getpagesize.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "libc.h"
+
+int getpagesize(void)
+{
+	return PAGE_SIZE;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getpass.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getpass.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getpass.c	(revision 398)
@@ -0,0 +1,40 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+
+char *getpass(const char *prompt)
+{
+	int fd;
+	struct termios s, t;
+	ssize_t l;
+	static char password[128];
+
+	if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0) return 0;
+
+	tcgetattr(fd, &t);
+	s = t;
+	t.c_lflag &= ~(ECHO|ISIG);
+	t.c_lflag |= ICANON;
+	t.c_iflag &= ~(INLCR|IGNCR);
+	t.c_iflag |= ICRNL;
+	tcsetattr(fd, TCSAFLUSH, &t);
+	tcdrain(fd);
+
+	dprintf(fd, "%s", prompt);
+
+	l = read(fd, password, sizeof password);
+	if (l >= 0) {
+		if (l > 0 && password[l-1] == '\n' || l==sizeof password) l--;
+		password[l] = 0;
+	}
+
+	tcsetattr(fd, TCSAFLUSH, &s);
+
+	dprintf(fd, "\n");
+	close(fd);
+
+	return l<0 ? 0 : password;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getusershell.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getusershell.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/getusershell.c	(revision 398)
@@ -0,0 +1,32 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+
+static const char defshells[] = "/bin/sh\n/bin/csh\n";
+
+static char *line;
+static size_t linesize;
+static FILE *f;
+
+void endusershell(void)
+{
+	if (f) fclose(f);
+	f = 0;
+}
+
+void setusershell(void)
+{
+	if (!f) f = fopen("/etc/shells", "rbe");
+	if (!f) f = fmemopen((void *)defshells, sizeof defshells - 1, "rb");
+}
+
+char *getusershell(void)
+{
+	ssize_t l;
+	if (!f) setusershell();
+	if (!f) return 0;
+	l = getline(&line, &linesize, f);
+	if (l <= 0) return 0;
+	if (line[l-1]=='\n') line[l-1]=0;
+	return line;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/isastream.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/isastream.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/isastream.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <stropts.h>
+#include <fcntl.h>
+
+int isastream(int fd)
+{
+	return fcntl(fd, F_GETFD) < 0 ? -1 : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/lutimes.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/lutimes.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/lutimes.c	(revision 398)
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+
+int lutimes(const char *filename, const struct timeval tv[2])
+{
+	struct timespec times[2];
+	times[0].tv_sec  = tv[0].tv_sec;
+	times[0].tv_nsec = tv[0].tv_usec * 1000;
+	times[1].tv_sec  = tv[1].tv_sec;
+	times[1].tv_nsec = tv[1].tv_usec * 1000;
+	return utimensat(AT_FDCWD, filename, times, AT_SYMLINK_NOFOLLOW);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/ulimit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/ulimit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/ulimit.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <sys/resource.h>
+#include <ulimit.h>
+#include <stdarg.h>
+
+long ulimit(int cmd, ...)
+{
+	struct rlimit rl;
+	getrlimit(RLIMIT_FSIZE, &rl);
+	if (cmd == UL_SETFSIZE) {
+		long val;
+		va_list ap;
+		va_start(ap, cmd);
+		val = va_arg(ap, long);
+		va_end(ap);
+		rl.rlim_cur = 512ULL * val;
+		if (setrlimit(RLIMIT_FSIZE, &rl)) return -1;
+	}
+	return rl.rlim_cur / 512;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/utmpx.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/utmpx.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/utmpx.c	(revision 398)
@@ -0,0 +1,52 @@
+#include <utmpx.h>
+#include <stddef.h>
+#include <errno.h>
+#include "libc.h"
+
+void endutxent(void)
+{
+}
+
+void setutxent(void)
+{
+}
+
+struct utmpx *getutxent(void)
+{
+	return NULL;
+}
+
+struct utmpx *getutxid(const struct utmpx *ut)
+{
+	return NULL;
+}
+
+struct utmpx *getutxline(const struct utmpx *ut)
+{
+	return NULL;
+}
+
+struct utmpx *pututxline(const struct utmpx *ut)
+{
+	return NULL;
+}
+
+void updwtmpx(const char *f, const struct utmpx *u)
+{
+}
+
+int __utmpxname(const char *f)
+{
+	errno = ENOTSUP;
+	return -1;
+}
+
+weak_alias(endutxent, endutent);
+weak_alias(setutxent, setutent);
+weak_alias(getutxent, getutent);
+weak_alias(getutxid, getutid);
+weak_alias(getutxline, getutline);
+weak_alias(pututxline, pututline);
+weak_alias(updwtmpx, updwtmp);
+weak_alias(__utmpxname, utmpname);
+weak_alias(__utmpxname, utmpxname);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/valloc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/valloc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/legacy/valloc.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <stdlib.h>
+#include "libc.h"
+
+void *valloc(size_t size)
+{
+	return memalign(PAGE_SIZE, size);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/adjtime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/adjtime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/adjtime.c	(revision 398)
@@ -0,0 +1,27 @@
+#define _GNU_SOURCE
+#include <sys/time.h>
+#include <sys/timex.h>
+#include <errno.h>
+#include "syscall.h"
+
+int adjtime(const struct timeval *in, struct timeval *out)
+{
+	struct timex tx = { 0 };
+	if (in) {
+		if (in->tv_sec > 1000 || in->tv_usec > 1000000000) {
+			errno = EINVAL;
+			return -1;
+		}
+		tx.offset = in->tv_sec*1000000 + in->tv_usec;
+		tx.modes = ADJ_OFFSET_SINGLESHOT;
+	}
+	if (syscall(SYS_adjtimex, &tx) < 0) return -1;
+	if (out) {
+		out->tv_sec = tx.offset / 1000000;
+		if ((out->tv_usec = tx.offset % 1000000) < 0) {
+			out->tv_sec--;
+			out->tv_usec += 1000000;
+		}
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/adjtimex.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/adjtimex.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/adjtimex.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/timex.h>
+#include "syscall.h"
+
+int adjtimex(struct timex *tx)
+{
+	return syscall(SYS_adjtimex, tx);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/arch_prctl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/arch_prctl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/arch_prctl.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "syscall.h"
+#ifdef SYS_arch_prctl
+int arch_prctl(int code, unsigned long addr)
+{
+	return syscall(SYS_arch_prctl, code, addr);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/brk.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/brk.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/brk.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <errno.h>
+#include "syscall.h"
+
+int brk(void *end)
+{
+	return __syscall_ret(-ENOMEM);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/cache.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/cache.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/cache.c	(revision 398)
@@ -0,0 +1,18 @@
+#include "syscall.h"
+#include "libc.h"
+
+#ifdef SYS_cacheflush
+int _flush_cache(void *addr, int len, int op)
+{
+	return syscall(SYS_cacheflush, addr, len, op);
+}
+weak_alias(_flush_cache, cacheflush);
+#endif
+
+#ifdef SYS_cachectl
+int __cachectl(void *addr, int len, int op)
+{
+	return syscall(SYS_cachectl, addr, len, op);
+}
+weak_alias(__cachectl, cachectl);
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/cap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/cap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/cap.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "syscall.h"
+
+int capset(void *a, void *b)
+{
+	return syscall(SYS_capset, a, b);
+}
+
+int capget(void *a, void *b)
+{
+	return syscall(SYS_capget, a, b);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/chroot.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/chroot.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/chroot.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int chroot(const char *path)
+{
+	return syscall(SYS_chroot, path);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/clock_adjtime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/clock_adjtime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/clock_adjtime.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/timex.h>
+#include "syscall.h"
+
+int clock_adjtime (clockid_t clock_id, struct timex *utx)
+{
+	return syscall(SYS_clock_adjtime, clock_id, utx);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/clone.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/clone.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/clone.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <stdarg.h>
+#include <unistd.h>
+#include "pthread_impl.h"
+#include "syscall.h"
+
+int clone(int (*func)(void *), void *stack, int flags, void *arg, ...)
+{
+	va_list ap;
+	pid_t *ptid, *ctid;
+	void  *tls;
+
+	va_start(ap, arg);
+	ptid = va_arg(ap, pid_t *);
+	tls  = va_arg(ap, void *);
+	ctid = va_arg(ap, pid_t *);
+	va_end(ap);
+
+	return __syscall_ret(__clone(func, stack, flags, arg, ptid, tls, ctid));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/epoll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/epoll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/epoll.c	(revision 398)
@@ -0,0 +1,37 @@
+#include <sys/epoll.h>
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+
+int epoll_create(int size)
+{
+	return epoll_create1(0);
+}
+
+int epoll_create1(int flags)
+{
+	int r = __syscall(SYS_epoll_create1, flags);
+#ifdef SYS_epoll_create
+	if (r==-ENOSYS && !flags) r = __syscall(SYS_epoll_create, 1);
+#endif
+	return __syscall_ret(r);
+}
+
+int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev)
+{
+	return syscall(SYS_epoll_ctl, fd, op, fd2, ev);
+}
+
+int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs)
+{
+	int r = __syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8);
+#ifdef SYS_epoll_wait
+	if (r==-ENOSYS && !sigs) r = __syscall(SYS_epoll_wait, fd, ev, cnt, to);
+#endif
+	return __syscall_ret(r);
+}
+
+int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to)
+{
+	return epoll_pwait(fd, ev, cnt, to, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/eventfd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/eventfd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/eventfd.c	(revision 398)
@@ -0,0 +1,23 @@
+#include <sys/eventfd.h>
+#include <unistd.h>
+#include <errno.h>
+#include "syscall.h"
+
+int eventfd(unsigned int count, int flags)
+{
+	int r = __syscall(SYS_eventfd2, count, flags);
+#ifdef SYS_eventfd
+	if (r==-ENOSYS && !flags) r = __syscall(SYS_eventfd, count);
+#endif
+	return __syscall_ret(r);
+}
+
+int eventfd_read(int fd, eventfd_t *value)
+{
+	return (sizeof(*value) == read(fd, value, sizeof(*value))) ? 0 : -1;
+}
+
+int eventfd_write(int fd, eventfd_t value)
+{
+	return (sizeof(value) == write(fd, &value, sizeof(value))) ? 0 : -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/fallocate.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/fallocate.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/fallocate.c	(revision 398)
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+#include "libc.h"
+
+int fallocate(int fd, int mode, off_t base, off_t len)
+{
+	return syscall(SYS_fallocate, fd, mode, __SYSCALL_LL_E(base),
+		__SYSCALL_LL_E(len));
+}
+
+#undef fallocate64
+LFS64(fallocate);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/fanotify.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/fanotify.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/fanotify.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "syscall.h"
+#include <sys/fanotify.h>
+
+int fanotify_init(unsigned flags, unsigned event_f_flags)
+{
+	return syscall(SYS_fanotify_init, flags, event_f_flags);
+}
+
+int fanotify_mark(int fanotify_fd, unsigned flags, unsigned long long mask,
+	          int dfd, const char *pathname)
+{
+	return syscall(SYS_fanotify_mark, fanotify_fd, flags, __SYSCALL_LL_E(mask), dfd, pathname);
+}
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/flock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/flock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/flock.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/file.h>
+#include "syscall.h"
+
+int flock(int fd, int op)
+{
+	return syscall(SYS_flock, fd, op);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/inotify.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/inotify.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/inotify.c	(revision 398)
@@ -0,0 +1,26 @@
+#include <sys/inotify.h>
+#include <errno.h>
+#include "syscall.h"
+
+int inotify_init()
+{
+	return inotify_init1(0);
+}
+int inotify_init1(int flags)
+{
+	int r = __syscall(SYS_inotify_init1, flags);
+#ifdef SYS_inotify_init
+	if (r==-ENOSYS && !flags) r = __syscall(SYS_inotify_init);
+#endif
+	return __syscall_ret(r);
+}
+
+int inotify_add_watch(int fd, const char *pathname, uint32_t mask)
+{
+	return syscall(SYS_inotify_add_watch, fd, pathname, mask);
+}
+
+int inotify_rm_watch(int fd, int wd)
+{
+	return syscall(SYS_inotify_rm_watch, fd, wd);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/ioperm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/ioperm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/ioperm.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "syscall.h"
+
+#ifdef SYS_ioperm
+#include <sys/io.h>
+
+int ioperm(unsigned long from, unsigned long num, int turn_on)
+{
+	return syscall(SYS_ioperm, from, num, turn_on);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/iopl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/iopl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/iopl.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "syscall.h"
+
+#ifdef SYS_iopl
+#include <sys/io.h>
+
+int iopl(int level)
+{
+	return syscall(SYS_iopl, level);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/klogctl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/klogctl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/klogctl.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/klog.h>
+#include "syscall.h"
+
+int klogctl (int type, char *buf, int len)
+{
+	return syscall(SYS_syslog, type, buf, len);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/module.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/module.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/module.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "syscall.h"
+
+int init_module(void *a, unsigned long b, const char *c)
+{
+	return syscall(SYS_init_module, a, b, c);
+}
+
+int delete_module(const char *a, unsigned b)
+{
+	return syscall(SYS_delete_module, a, b);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/mount.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/mount.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/mount.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <sys/mount.h>
+#include "syscall.h"
+
+int mount(const char *special, const char *dir, const char *fstype, unsigned long flags, const void *data)
+{
+	return syscall(SYS_mount, special, dir, fstype, flags, data);
+}
+
+int umount(const char *special)
+{
+	return syscall(SYS_umount2, special, 0);
+}
+
+int umount2(const char *special, int flags)
+{
+	return syscall(SYS_umount2, special, flags);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/personality.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/personality.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/personality.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/personality.h>
+#include "syscall.h"
+#ifdef SYS_personality
+int personality(unsigned long persona)
+{
+	return syscall(SYS_personality, persona);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/pivot_root.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/pivot_root.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/pivot_root.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "syscall.h"
+
+int pivot_root(const char *new, const char *old)
+{
+	return syscall(SYS_pivot_root, new, old);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/ppoll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/ppoll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/ppoll.c	(revision 398)
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <poll.h>
+#include <signal.h>
+#include "syscall.h"
+
+int ppoll(struct pollfd *fds, nfds_t n, const struct timespec *to, const sigset_t *mask)
+{
+	return syscall_cp(SYS_ppoll, fds, n,
+		to ? (struct timespec []){*to} : 0, mask, _NSIG/8);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/prctl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/prctl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/prctl.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <sys/prctl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+int prctl(int op, ...)
+{
+	unsigned long x[4];
+	int i;
+	va_list ap;
+	va_start(ap, op);
+	for (i=0; i<4; i++) x[i] = va_arg(ap, unsigned long);
+	va_end(ap);
+	return syscall(SYS_prctl, op, x[0], x[1], x[2], x[3]);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/prlimit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/prlimit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/prlimit.c	(revision 398)
@@ -0,0 +1,27 @@
+#define _GNU_SOURCE
+#include <sys/resource.h>
+#include "syscall.h"
+#include "libc.h"
+
+#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
+
+int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit)
+{
+	struct rlimit tmp;
+	int r;
+	if (new_limit && SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
+		tmp = *new_limit;
+		FIX(tmp.rlim_cur);
+		FIX(tmp.rlim_max);
+		new_limit = &tmp;
+	}
+	r = syscall(SYS_prlimit64, pid, resource, new_limit, old_limit);
+	if (!r && old_limit && SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
+		FIX(old_limit->rlim_cur);
+		FIX(old_limit->rlim_max);
+	}
+	return r;
+}
+
+#undef prlimit64
+LFS64(prlimit);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/process_vm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/process_vm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/process_vm.c	(revision 398)
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <sys/uio.h>
+#include "syscall.h"
+
+ssize_t process_vm_writev(pid_t pid, const struct iovec *lvec, unsigned long liovcnt, const struct iovec *rvec, unsigned long riovcnt, unsigned long flags)
+{
+	return syscall(SYS_process_vm_writev, pid, lvec, liovcnt, rvec, riovcnt, flags);
+}
+
+ssize_t process_vm_readv(pid_t pid, const struct iovec *lvec, unsigned long liovcnt, const struct iovec *rvec, unsigned long riovcnt, unsigned long flags)
+{
+	return syscall(SYS_process_vm_readv, pid, lvec, liovcnt, rvec, riovcnt, flags);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/ptrace.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/ptrace.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/ptrace.c	(revision 398)
@@ -0,0 +1,29 @@
+#include <sys/ptrace.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include "syscall.h"
+
+long ptrace(int req, ...)
+{
+	va_list ap;
+	pid_t pid;
+	void *addr, *data, *addr2 = 0;
+	long ret, result;
+
+	va_start(ap, req);
+	pid = va_arg(ap, pid_t);
+	addr = va_arg(ap, void *);
+	data = va_arg(ap, void *);
+	/* PTRACE_{READ,WRITE}{DATA,TEXT} (16...19) are specific to SPARC. */
+#ifdef PTRACE_READDATA
+	if ((unsigned)req - PTRACE_READDATA < 4)
+		addr2 = va_arg(ap, void *);
+#endif
+	va_end(ap);
+
+	if (req-1U < 3) data = &result;
+	ret = syscall(SYS_ptrace, req, pid, addr, data, addr2);
+
+	if (ret < 0 || req-1U >= 3) return ret;
+	return result;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/quotactl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/quotactl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/quotactl.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/quota.h>
+#include "syscall.h"
+
+int quotactl(int cmd, const char *special, int id, char *addr)
+{
+	return syscall(SYS_quotactl, cmd, special, id, addr);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/readahead.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/readahead.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/readahead.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t readahead(int fd, off_t pos, size_t len)
+{
+	return syscall(SYS_readahead, fd, __SYSCALL_LL_O(pos), len);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/reboot.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/reboot.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/reboot.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/reboot.h>
+#include "syscall.h"
+
+int reboot(int type)
+{
+	return syscall(SYS_reboot, 0xfee1dead, 672274793, type);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/remap_file_pages.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/remap_file_pages.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/remap_file_pages.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sys/mman.h>
+#include "syscall.h"
+
+int remap_file_pages(void *addr, size_t size, int prot, size_t pgoff, int flags)
+{
+	return syscall(SYS_remap_file_pages, addr, size, prot, pgoff, flags);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sbrk.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sbrk.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sbrk.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <stdint.h>
+#include <errno.h>
+#include "syscall.h"
+
+void *sbrk(intptr_t inc)
+{
+	if (inc) return (void *)__syscall_ret(-ENOMEM);
+	return (void *)__syscall(SYS_brk, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sendfile.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sendfile.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sendfile.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <sys/sendfile.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t sendfile(int out_fd, int in_fd, off_t *ofs, size_t count)
+{
+	return syscall(SYS_sendfile, out_fd, in_fd, ofs, count);
+}
+
+LFS64(sendfile);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setfsgid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setfsgid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setfsgid.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/fsuid.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setfsgid(gid_t gid)
+{
+	return syscall(SYS_setfsgid, gid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setfsuid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setfsuid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setfsuid.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/fsuid.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setfsuid(uid_t uid)
+{
+	return syscall(SYS_setfsuid, uid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setgroups.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setgroups.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setgroups.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int setgroups(size_t count, const gid_t list[])
+{
+	return syscall(SYS_setgroups, count, list);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sethostname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sethostname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sethostname.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int sethostname(const char *name, size_t len)
+{
+	return syscall(SYS_sethostname, name, len);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setns.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setns.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/setns.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include "syscall.h"
+
+int setns(int fd, int nstype)
+{
+	return syscall(SYS_setns, fd, nstype);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/settimeofday.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/settimeofday.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/settimeofday.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <sys/time.h>
+#include "syscall.h"
+
+int settimeofday(const struct timeval *tv, const struct timezone *tz)
+{
+	return syscall(SYS_settimeofday, tv, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/signalfd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/signalfd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/signalfd.c	(revision 398)
@@ -0,0 +1,21 @@
+#include <sys/signalfd.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int signalfd(int fd, const sigset_t *sigs, int flags)
+{
+	int ret = __syscall(SYS_signalfd4, fd, sigs, _NSIG/8, flags);
+#ifdef SYS_signalfd
+	if (ret != -ENOSYS) return __syscall_ret(ret);
+	ret = __syscall(SYS_signalfd, fd, sigs, _NSIG/8);
+	if (ret >= 0) {
+		if (flags & SFD_CLOEXEC)
+			__syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+		if (flags & SFD_NONBLOCK)
+			__syscall(SYS_fcntl, ret, F_SETFL, O_NONBLOCK);
+	}
+#endif
+	return __syscall_ret(ret);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/splice.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/splice.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/splice.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t splice(int fd_in, off_t *off_in, int fd_out, off_t *off_out, size_t len, unsigned flags)
+{
+	return syscall(SYS_splice, fd_in, off_in, fd_out, off_out, len, flags);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/stime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/stime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/stime.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <time.h>
+#include <sys/time.h>
+
+int stime(const time_t *t)
+{
+	struct timeval tv = { .tv_sec = *t, .tv_usec = 0 };
+	return settimeofday(&tv, (void *)0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/swap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/swap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/swap.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/swap.h>
+#include "syscall.h"
+
+int swapon(const char *path, int flags)
+{
+	return syscall(SYS_swapon, path, flags);
+}
+
+int swapoff(const char *path)
+{
+	return syscall(SYS_swapoff, path);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sync_file_range.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sync_file_range.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sync_file_range.c	(revision 398)
@@ -0,0 +1,17 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sync_file_range(int fd, off_t pos, off_t len, unsigned flags)
+{
+#if defined(SYS_sync_file_range2)
+	return syscall(SYS_sync_file_range2, fd, flags,
+		__SYSCALL_LL_E(pos), __SYSCALL_LL_E(len));
+#elif defined(SYS_sync_file_range)
+	return syscall(SYS_sync_file_range, fd,
+		__SYSCALL_LL_O(pos), __SYSCALL_LL_E(len), flags);
+#else
+	return __syscall_ret(-ENOSYS);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/syncfs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/syncfs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/syncfs.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int syncfs(int fd)
+{
+	return syscall(SYS_syncfs, fd);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sysinfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sysinfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/sysinfo.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <sys/sysinfo.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __lsysinfo(struct sysinfo *info)
+{
+	return syscall(SYS_sysinfo, info);
+}
+
+weak_alias(__lsysinfo, sysinfo);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/tee.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/tee.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/tee.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t tee(int src, int dest, size_t len, unsigned flags)
+{
+	return syscall(SYS_tee, src, dest, len, flags);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/timerfd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/timerfd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/timerfd.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <sys/timerfd.h>
+#include "syscall.h"
+
+int timerfd_create(int clockid, int flags)
+{
+	return syscall(SYS_timerfd_create, clockid, flags);
+}
+
+int timerfd_settime(int fd, int flags, const struct itimerspec *new, struct itimerspec *old)
+{
+	return syscall(SYS_timerfd_settime, fd, flags, new, old);
+}
+
+int timerfd_gettime(int fd, struct itimerspec *cur)
+{
+	return syscall(SYS_timerfd_gettime, fd, cur);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/unshare.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/unshare.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/unshare.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include "syscall.h"
+
+int unshare(int flags)
+{
+	return syscall(SYS_unshare, flags);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/utimes.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/utimes.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/utimes.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <sys/time.h>
+#include "fcntl.h"
+#include "syscall.h"
+
+int __futimesat(int, const char *, const struct timeval [2]);
+
+int utimes(const char *path, const struct timeval times[2])
+{
+	return __futimesat(AT_FDCWD, path, times);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/vhangup.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/vhangup.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/vhangup.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int vhangup(void)
+{
+	return syscall(SYS_vhangup);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/vmsplice.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/vmsplice.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/vmsplice.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t vmsplice(int fd, const struct iovec *iov, size_t cnt, unsigned flags)
+{
+	return syscall(SYS_vmsplice, fd, iov, cnt, flags);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/wait3.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/wait3.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/wait3.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include "syscall.h"
+
+pid_t wait3(int *status, int options, struct rusage *usage)
+{
+	return wait4(-1, status, options, usage);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/wait4.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/wait4.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/wait4.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include "syscall.h"
+
+pid_t wait4(pid_t pid, int *status, int options, struct rusage *usage)
+{
+	return syscall(SYS_wait4, pid, status, options, usage);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/xattr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/xattr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/linux/xattr.c	(revision 398)
@@ -0,0 +1,62 @@
+#include <sys/xattr.h>
+#include "syscall.h"
+
+ssize_t getxattr(const char *path, const char *name, void *value, size_t size)
+{
+	return syscall(SYS_getxattr, path, name, value, size);
+}
+
+ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size)
+{
+	return syscall(SYS_lgetxattr, path, name, value, size);
+}
+
+ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size)
+{
+	return syscall(SYS_fgetxattr, filedes, name, value, size);
+}
+
+ssize_t listxattr(const char *path, char *list, size_t size)
+{
+	return syscall(SYS_listxattr, path, list, size);
+}
+
+ssize_t llistxattr(const char *path, char *list, size_t size)
+{
+	return syscall(SYS_llistxattr, path, list, size);
+}
+
+ssize_t flistxattr(int filedes, char *list, size_t size)
+{
+	return syscall(SYS_flistxattr, filedes, list, size);
+}
+
+int setxattr(const char *path, const char *name, const void *value, size_t size, int flags)
+{
+	return syscall(SYS_setxattr, path, name, value, size, flags);
+}
+
+int lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags)
+{
+	return syscall(SYS_lsetxattr, path, name, value, size, flags);
+}
+
+int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags)
+{
+	return syscall(SYS_fsetxattr, filedes, name, value, size, flags);
+}
+
+int removexattr(const char *path, const char *name)
+{
+	return syscall(SYS_removexattr, path, name);
+}
+
+int lremovexattr(const char *path, const char *name)
+{
+	return syscall(SYS_lremovexattr, path, name);
+}
+
+int fremovexattr(int fd, const char *name)
+{
+	return syscall(SYS_fremovexattr, fd, name);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/__lctrans.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/__lctrans.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/__lctrans.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <locale.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+static const char *dummy(const char *msg, const struct __locale_map *lm)
+{
+	return msg;
+}
+
+weak_alias(dummy, __lctrans_impl);
+
+const char *__lctrans(const char *msg, const struct __locale_map *lm)
+{
+	return __lctrans_impl(msg, lm);
+}
+
+const char *__lctrans_cur(const char *msg)
+{
+	return __lctrans_impl(msg, CURRENT_LOCALE->cat[LC_MESSAGES]);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/__mo_lookup.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/__mo_lookup.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/__mo_lookup.c	(revision 398)
@@ -0,0 +1,42 @@
+#include <stdint.h>
+#include <string.h>
+
+static inline uint32_t swapc(uint32_t x, int c)
+{
+	return c ? (x>>24) | (x>>8&0xff00) | (x<<8&0xff0000) | (x<<24) : x;
+}
+
+const char *__mo_lookup(const void *p, size_t size, const char *s)
+{
+	const uint32_t *mo = p;
+	int sw = *mo - 0x950412de;
+	uint32_t b = 0, n = swapc(mo[2], sw);
+	uint32_t o = swapc(mo[3], sw);
+	uint32_t t = swapc(mo[4], sw);
+	if (n>=size/4 || o>=size-4*n || t>=size-4*n || ((o|t)%4))
+		return 0;
+	o/=4;
+	t/=4;
+	for (;;) {
+		uint32_t ol = swapc(mo[o+2*(b+n/2)], sw);
+		uint32_t os = swapc(mo[o+2*(b+n/2)+1], sw);
+		if (os >= size || ol >= size-os || ((char *)p)[os+ol])
+			return 0;
+		int sign = strcmp(s, (char *)p + os);
+		if (!sign) {
+			uint32_t tl = swapc(mo[t+2*(b+n/2)], sw);
+			uint32_t ts = swapc(mo[t+2*(b+n/2)+1], sw);
+			if (ts >= size || tl >= size-ts || ((char *)p)[ts+tl])
+				return 0;
+			return (char *)p + ts;
+		}
+		else if (n == 1) return 0;
+		else if (sign < 0)
+			n /= 2;
+		else {
+			b += n/2;
+			n -= n/2;
+		}
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/big5.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/big5.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/big5.h	(revision 398)
@@ -0,0 +1,1085 @@
+12288,65292,12289,12290,65294,8231,65307,65306,65311,65281,65072,8230,8229,
+65104,65105,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075,
+9588,65076,65103,65288,65289,65077,65078,65371,65373,65079,65080,12308,12309,
+65081,65082,12304,12305,65083,65084,12298,12299,65085,65086,12296,12297,65087,
+65088,12300,12301,65089,65090,12302,12303,65091,65092,65113,65114,65115,65116,
+65117,65118,8216,8217,8220,8221,12317,12318,8245,8242,65283,65286,65290,8251,
+167,12291,9675,9679,9651,9650,9678,9734,9733,9671,9670,9633,9632,9661,9660,
+12963,8453,175,65507,65343,717,65097,65098,65101,65102,65099,65100,65119,
+65120,65121,65291,65293,215,247,177,8730,65308,65310,65309,8806,8807,8800,
+8734,8786,8801,65122,65123,65124,65125,65126,65374,8745,8746,8869,8736,8735,
+8895,13266,13265,8747,8750,8757,8756,9792,9794,8853,8857,8593,8595,8592,8594,
+8598,8599,8601,8600,8741,8739,65295,65340,8725,65128,65284,65509,12306,65504,
+65505,65285,65312,8451,8457,65129,65130,65131,13269,13212,13213,13214,13262,
+13217,13198,13199,13252,176,20825,20827,20830,20829,20833,20835,21991,29929,
+31950,9601,9602,9603,9604,9605,9606,9607,9608,9615,9614,9613,9612,9611,9610,
+9609,9532,9524,9516,9508,9500,9620,9472,9474,9621,9484,9488,9492,9496,9581,
+9582,9584,9583,9552,9566,9578,9569,9698,9699,9701,9700,9585,9586,9587,65296,
+65297,65298,65299,65300,65301,65302,65303,65304,65305,8544,8545,8546,8547,
+8548,8549,8550,8551,8552,8553,12321,
+12322,12323,12324,12325,12326,12327,12328,12329,21313,21316,21317,65313,65314,
+65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,
+65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65345,65346,
+65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,
+65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,913,914,915,
+916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,
+936,937,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,
+963,964,965,966,967,968,969,12549,12550,12551,12552,12553,12554,12555,12556,
+12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,
+12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,
+12583,12584,12585,729,713,714,711,715,9216,9217,9218,9219,9220,9221,9222,9223,
+9224,9225,9226,9227,9228,9229,9230,9231,9232,9233,9234,9235,9236,9237,9238,
+9239,9240,9241,9242,9243,9244,9245,9246,9247,9249,8364,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,19968,20057,19969,19971,20035,20061,20102,
+20108,20154,20799,20837,20843,20960,20992,20993,21147,21269,21313,21340,21448,
+19977,19979,19976,19978,20011,20024,20961,20037,20040,20063,20062,20110,20129,
+20800,20995,21242,21315,21449,21475,22303,
+22763,22805,22823,22899,23376,23377,23379,23544,23567,23586,23608,23665,24029,
+24037,24049,24050,24051,24062,24178,24318,24331,24339,25165,19985,19984,19981,
+20013,20016,20025,20043,23609,20104,20113,20117,20114,20116,20130,20161,20160,
+20163,20166,20167,20173,20170,20171,20164,20803,20801,20839,20845,20846,20844,
+20887,20982,20998,20999,21000,21243,21246,21247,21270,21305,21320,21319,21317,
+21342,21380,21451,21450,21453,22764,22825,22827,22826,22829,23380,23569,23588,
+23610,23663,24052,24187,24319,24340,24341,24515,25096,25142,25163,25166,25903,
+25991,26007,26020,26041,26085,26352,26376,26408,27424,27490,27513,27595,27604,
+27611,27663,27700,28779,29226,29238,29243,29255,29273,29275,29356,29579,19993,
+19990,19989,19988,19992,20027,20045,20047,20046,20197,20184,20180,20181,20182,
+20183,20195,20196,20185,20190,20805,20804,20873,20874,20908,20985,20986,20984,
+21002,21152,21151,21253,21254,21271,21277,20191,21322,21321,21345,21344,21359,
+21358,21435,21487,21476,21491,21484,21486,21481,21480,21500,21496,21493,21483,
+21478,21482,21490,21489,21488,21477,21485,21499,22235,22234,22806,22830,22833,
+22900,22902,23381,23427,23612,24040,24039,24038,24066,24067,24179,24188,24321,
+24344,24343,24517,25098,25171,25172,25170,25169,26021,26086,26414,26412,26410,
+26411,26413,27491,27597,27665,27664,27704,27713,27712,27710,29359,29572,29577,
+29916,29926,29976,29983,29992,29993,30000,30001,30002,30003,30091,30333,30382,
+30399,30446,30683,30690,30707,31034,31166,31348,31435,19998,19999,20050,20051,
+20073,20121,20132,20134,20133,20223,20233,20249,20234,
+20245,20237,20240,20241,20239,20210,20214,20219,20208,20211,20221,20225,20235,
+20809,20807,20806,20808,20840,20849,20877,20912,21015,21009,21010,21006,21014,
+21155,21256,21281,21280,21360,21361,21513,21519,21516,21514,21520,21505,21515,
+21508,21521,21517,21512,21507,21518,21510,21522,22240,22238,22237,22323,22320,
+22312,22317,22316,22319,22313,22809,22810,22839,22840,22916,22904,22915,22909,
+22905,22914,22913,23383,23384,23431,23432,23429,23433,23546,23574,23673,24030,
+24070,24182,24180,24335,24347,24537,24534,25102,25100,25101,25104,25187,25179,
+25176,25910,26089,26088,26092,26093,26354,26355,26377,26429,26420,26417,26421,
+27425,27492,27515,27670,27741,27735,27737,27743,27744,27728,27733,27745,27739,
+27725,27726,28784,29279,29277,30334,31481,31859,31992,32566,32650,32701,32769,
+32771,32780,32786,32819,32895,32905,32907,32908,33251,33258,33267,33276,33292,
+33307,33311,33390,33394,33406,34411,34880,34892,34915,35199,38433,20018,20136,
+20301,20303,20295,20311,20318,20276,20315,20309,20272,20304,20305,20285,20282,
+20280,20291,20308,20284,20294,20323,20316,20320,20271,20302,20278,20313,20317,
+20296,20314,20812,20811,20813,20853,20918,20919,21029,21028,21033,21034,21032,
+21163,21161,21162,21164,21283,21363,21365,21533,21549,21534,21566,21542,21582,
+21543,21574,21571,21555,21576,21570,21531,21545,21578,21561,21563,21560,21550,
+21557,21558,21536,21564,21568,21553,21547,21535,21548,22250,22256,22244,22251,
+22346,22353,22336,22349,22343,22350,22334,22352,22351,22331,22767,22846,22941,
+22930,22952,22942,22947,22937,22934,22925,22948,22931,
+22922,22949,23389,23388,23386,23387,23436,23435,23439,23596,23616,23617,23615,
+23614,23696,23697,23700,23692,24043,24076,24207,24199,24202,24311,24324,24351,
+24420,24418,24439,24441,24536,24524,24535,24525,24561,24555,24568,24554,25106,
+25105,25220,25239,25238,25216,25206,25225,25197,25226,25212,25214,25209,25203,
+25234,25199,25240,25198,25237,25235,25233,25222,25913,25915,25912,26097,26356,
+26463,26446,26447,26448,26449,26460,26454,26462,26441,26438,26464,26451,26455,
+27493,27599,27714,27742,27801,27777,27784,27785,27781,27803,27754,27770,27792,
+27760,27788,27752,27798,27794,27773,27779,27762,27774,27764,27782,27766,27789,
+27796,27800,27778,28790,28796,28797,28792,29282,29281,29280,29380,29378,29590,
+29996,29995,30007,30008,30338,30447,30691,31169,31168,31167,31350,31995,32597,
+32918,32915,32925,32920,32923,32922,32946,33391,33426,33419,33421,35211,35282,
+35328,35895,35910,35925,35997,36196,36208,36275,36523,36554,36763,36784,36802,
+36806,36805,36804,24033,37009,37026,37034,37030,37027,37193,37318,37324,38450,
+38446,38449,38442,38444,20006,20054,20083,20107,20123,20126,20139,20140,20335,
+20381,20365,20339,20351,20332,20379,20363,20358,20355,20336,20341,20360,20329,
+20347,20374,20350,20367,20369,20346,20820,20818,20821,20841,20855,20854,20856,
+20925,20989,21051,21048,21047,21050,21040,21038,21046,21057,21182,21179,21330,
+21332,21331,21329,21350,21367,21368,21369,21462,21460,21463,21619,21621,21654,
+21624,21653,21632,21627,21623,21636,21650,21638,21628,21648,21617,21622,21644,
+21658,21602,21608,21643,21629,21646,22266,22403,22391,
+22378,22377,22369,22374,22372,22396,22812,22857,22855,22856,22852,22868,22974,
+22971,22996,22969,22958,22993,22982,22992,22989,22987,22995,22986,22959,22963,
+22994,22981,23391,23396,23395,23447,23450,23448,23452,23449,23451,23578,23624,
+23621,23622,23735,23713,23736,23721,23723,23729,23731,24088,24090,24086,24085,
+24091,24081,24184,24218,24215,24220,24213,24214,24310,24358,24359,24361,24448,
+24449,24447,24444,24541,24544,24573,24565,24575,24591,24596,24623,24629,24598,
+24618,24597,24609,24615,24617,24619,24603,25110,25109,25151,25150,25152,25215,
+25289,25292,25284,25279,25282,25273,25298,25307,25259,25299,25300,25291,25288,
+25256,25277,25276,25296,25305,25287,25293,25269,25306,25265,25304,25302,25303,
+25286,25260,25294,25918,26023,26044,26106,26132,26131,26124,26118,26114,26126,
+26112,26127,26133,26122,26119,26381,26379,26477,26507,26517,26481,26524,26483,
+26487,26503,26525,26519,26479,26480,26495,26505,26494,26512,26485,26522,26515,
+26492,26474,26482,27427,27494,27495,27519,27667,27675,27875,27880,27891,27825,
+27852,27877,27827,27837,27838,27836,27874,27819,27861,27859,27832,27844,27833,
+27841,27822,27863,27845,27889,27839,27835,27873,27867,27850,27820,27887,27868,
+27862,27872,28821,28814,28818,28810,28825,29228,29229,29240,29256,29287,29289,
+29376,29390,29401,29399,29392,29609,29608,29599,29611,29605,30013,30109,30105,
+30106,30340,30402,30450,30452,30693,30717,31038,31040,31041,31177,31176,31354,
+31353,31482,31998,32596,32652,32651,32773,32954,32933,32930,32945,32929,32939,
+32937,32948,32938,32943,33253,33278,33293,33459,33437,
+33433,33453,33469,33439,33465,33457,33452,33445,33455,33464,33443,33456,33470,
+33463,34382,34417,21021,34920,36555,36814,36820,36817,37045,37048,37041,37046,
+37319,37329,38263,38272,38428,38464,38463,38459,38468,38466,38585,38632,38738,
+38750,20127,20141,20142,20449,20405,20399,20415,20448,20433,20431,20445,20419,
+20406,20440,20447,20426,20439,20398,20432,20420,20418,20442,20430,20446,20407,
+20823,20882,20881,20896,21070,21059,21066,21069,21068,21067,21063,21191,21193,
+21187,21185,21261,21335,21371,21402,21467,21676,21696,21672,21710,21705,21688,
+21670,21683,21703,21698,21693,21674,21697,21700,21704,21679,21675,21681,21691,
+21673,21671,21695,22271,22402,22411,22432,22435,22434,22478,22446,22419,22869,
+22865,22863,22862,22864,23004,23000,23039,23011,23016,23043,23013,23018,23002,
+23014,23041,23035,23401,23459,23462,23460,23458,23461,23553,23630,23631,23629,
+23627,23769,23762,24055,24093,24101,24095,24189,24224,24230,24314,24328,24365,
+24421,24456,24453,24458,24459,24455,24460,24457,24594,24605,24608,24613,24590,
+24616,24653,24688,24680,24674,24646,24643,24684,24683,24682,24676,25153,25308,
+25366,25353,25340,25325,25345,25326,25341,25351,25329,25335,25327,25324,25342,
+25332,25361,25346,25919,25925,26027,26045,26082,26149,26157,26144,26151,26159,
+26143,26152,26161,26148,26359,26623,26579,26609,26580,26576,26604,26550,26543,
+26613,26601,26607,26564,26577,26548,26586,26597,26552,26575,26590,26611,26544,
+26585,26594,26589,26578,27498,27523,27526,27573,27602,27607,27679,27849,27915,
+27954,27946,27969,27941,27916,27953,27934,27927,27963,
+27965,27966,27958,27931,27893,27961,27943,27960,27945,27950,27957,27918,27947,
+28843,28858,28851,28844,28847,28845,28856,28846,28836,29232,29298,29295,29300,
+29417,29408,29409,29623,29642,29627,29618,29645,29632,29619,29978,29997,30031,
+30028,30030,30027,30123,30116,30117,30114,30115,30328,30342,30343,30344,30408,
+30406,30403,30405,30465,30457,30456,30473,30475,30462,30460,30471,30684,30722,
+30740,30732,30733,31046,31049,31048,31047,31161,31162,31185,31186,31179,31359,
+31361,31487,31485,31869,32002,32005,32000,32009,32007,32004,32006,32568,32654,
+32703,32772,32784,32781,32785,32822,32982,32997,32986,32963,32964,32972,32993,
+32987,32974,32990,32996,32989,33268,33314,33511,33539,33541,33507,33499,33510,
+33540,33509,33538,33545,33490,33495,33521,33537,33500,33492,33489,33502,33491,
+33503,33519,33542,34384,34425,34427,34426,34893,34923,35201,35284,35336,35330,
+35331,35998,36000,36212,36211,36276,36557,36556,36848,36838,36834,36842,36837,
+36845,36843,36836,36840,37066,37070,37057,37059,37195,37194,37325,38274,38480,
+38475,38476,38477,38754,38761,38859,38893,38899,38913,39080,39131,39135,39318,
+39321,20056,20147,20492,20493,20515,20463,20518,20517,20472,20521,20502,20486,
+20540,20511,20506,20498,20497,20474,20480,20500,20520,20465,20513,20491,20505,
+20504,20467,20462,20525,20522,20478,20523,20489,20860,20900,20901,20898,20941,
+20940,20934,20939,21078,21084,21076,21083,21085,21290,21375,21407,21405,21471,
+21736,21776,21761,21815,21756,21733,21746,21766,21754,21780,21737,21741,21729,
+21769,21742,21738,21734,21799,21767,21757,21775,22275,
+22276,22466,22484,22475,22467,22537,22799,22871,22872,22874,23057,23064,23068,
+23071,23067,23059,23020,23072,23075,23081,23077,23052,23049,23403,23640,23472,
+23475,23478,23476,23470,23477,23481,23480,23556,23633,23637,23632,23789,23805,
+23803,23786,23784,23792,23798,23809,23796,24046,24109,24107,24235,24237,24231,
+24369,24466,24465,24464,24665,24675,24677,24656,24661,24685,24681,24687,24708,
+24735,24730,24717,24724,24716,24709,24726,25159,25331,25352,25343,25422,25406,
+25391,25429,25410,25414,25423,25417,25402,25424,25405,25386,25387,25384,25421,
+25420,25928,25929,26009,26049,26053,26178,26185,26191,26179,26194,26188,26181,
+26177,26360,26388,26389,26391,26657,26680,26696,26694,26707,26681,26690,26708,
+26665,26803,26647,26700,26705,26685,26612,26704,26688,26684,26691,26666,26693,
+26643,26648,26689,27530,27529,27575,27683,27687,27688,27686,27684,27888,28010,
+28053,28040,28039,28006,28024,28023,27993,28051,28012,28041,28014,27994,28020,
+28009,28044,28042,28025,28037,28005,28052,28874,28888,28900,28889,28872,28879,
+29241,29305,29436,29433,29437,29432,29431,29574,29677,29705,29678,29664,29674,
+29662,30036,30045,30044,30042,30041,30142,30149,30151,30130,30131,30141,30140,
+30137,30146,30136,30347,30384,30410,30413,30414,30505,30495,30496,30504,30697,
+30768,30759,30776,30749,30772,30775,30757,30765,30752,30751,30770,31061,31056,
+31072,31071,31062,31070,31069,31063,31066,31204,31203,31207,31199,31206,31209,
+31192,31364,31368,31449,31494,31505,31881,32033,32023,32011,32010,32032,32034,
+32020,32016,32021,32026,32028,32013,32025,32027,32570,
+32607,32660,32709,32705,32774,32792,32789,32793,32791,32829,32831,33009,33026,
+33008,33029,33005,33012,33030,33016,33011,33032,33021,33034,33020,33007,33261,
+33260,33280,33296,33322,33323,33320,33324,33467,33579,33618,33620,33610,33592,
+33616,33609,33589,33588,33615,33586,33593,33590,33559,33600,33585,33576,33603,
+34388,34442,34474,34451,34468,34473,34444,34467,34460,34928,34935,34945,34946,
+34941,34937,35352,35344,35342,35340,35349,35338,35351,35347,35350,35343,35345,
+35912,35962,35961,36001,36002,36215,36524,36562,36564,36559,36785,36865,36870,
+36855,36864,36858,36852,36867,36861,36869,36856,37013,37089,37085,37090,37202,
+37197,37196,37336,37341,37335,37340,37337,38275,38498,38499,38497,38491,38493,
+38500,38488,38494,38587,39138,39340,39592,39640,39717,39730,39740,20094,20602,
+20605,20572,20551,20547,20556,20570,20553,20581,20598,20558,20565,20597,20596,
+20599,20559,20495,20591,20589,20828,20885,20976,21098,21103,21202,21209,21208,
+21205,21264,21263,21273,21311,21312,21310,21443,26364,21830,21866,21862,21828,
+21854,21857,21827,21834,21809,21846,21839,21845,21807,21860,21816,21806,21852,
+21804,21859,21811,21825,21847,22280,22283,22281,22495,22533,22538,22534,22496,
+22500,22522,22530,22581,22519,22521,22816,22882,23094,23105,23113,23142,23146,
+23104,23100,23138,23130,23110,23114,23408,23495,23493,23492,23490,23487,23494,
+23561,23560,23559,23648,23644,23645,23815,23814,23822,23835,23830,23842,23825,
+23849,23828,23833,23844,23847,23831,24034,24120,24118,24115,24119,24247,24248,
+24246,24245,24254,24373,24375,24407,24428,24425,24427,
+24471,24473,24478,24472,24481,24480,24476,24703,24739,24713,24736,24744,24779,
+24756,24806,24765,24773,24763,24757,24796,24764,24792,24789,24774,24799,24760,
+24794,24775,25114,25115,25160,25504,25511,25458,25494,25506,25509,25463,25447,
+25496,25514,25457,25513,25481,25475,25499,25451,25512,25476,25480,25497,25505,
+25516,25490,25487,25472,25467,25449,25448,25466,25949,25942,25937,25945,25943,
+21855,25935,25944,25941,25940,26012,26011,26028,26063,26059,26060,26062,26205,
+26202,26212,26216,26214,26206,26361,21207,26395,26753,26799,26786,26771,26805,
+26751,26742,26801,26791,26775,26800,26755,26820,26797,26758,26757,26772,26781,
+26792,26783,26785,26754,27442,27578,27627,27628,27691,28046,28092,28147,28121,
+28082,28129,28108,28132,28155,28154,28165,28103,28107,28079,28113,28078,28126,
+28153,28088,28151,28149,28101,28114,28186,28085,28122,28139,28120,28138,28145,
+28142,28136,28102,28100,28074,28140,28095,28134,28921,28937,28938,28925,28911,
+29245,29309,29313,29468,29467,29462,29459,29465,29575,29701,29706,29699,29702,
+29694,29709,29920,29942,29943,29980,29986,30053,30054,30050,30064,30095,30164,
+30165,30133,30154,30157,30350,30420,30418,30427,30519,30526,30524,30518,30520,
+30522,30827,30787,30798,31077,31080,31085,31227,31378,31381,31520,31528,31515,
+31532,31526,31513,31518,31534,31890,31895,31893,32070,32067,32113,32046,32057,
+32060,32064,32048,32051,32068,32047,32066,32050,32049,32573,32670,32666,32716,
+32718,32722,32796,32842,32838,33071,33046,33059,33067,33065,33072,33060,33282,
+33333,33335,33334,33337,33678,33694,33688,33656,33698,
+33686,33725,33707,33682,33674,33683,33673,33696,33655,33659,33660,33670,33703,
+34389,24426,34503,34496,34486,34500,34485,34502,34507,34481,34479,34505,34899,
+34974,34952,34987,34962,34966,34957,34955,35219,35215,35370,35357,35363,35365,
+35377,35373,35359,35355,35362,35913,35930,36009,36012,36011,36008,36010,36007,
+36199,36198,36286,36282,36571,36575,36889,36877,36890,36887,36899,36895,36893,
+36880,36885,36894,36896,36879,36898,36886,36891,36884,37096,37101,37117,37207,
+37326,37365,37350,37347,37351,37357,37353,38281,38506,38517,38515,38520,38512,
+38516,38518,38519,38508,38592,38634,38633,31456,31455,38914,38915,39770,40165,
+40565,40575,40613,40635,20642,20621,20613,20633,20625,20608,20630,20632,20634,
+26368,20977,21106,21108,21109,21097,21214,21213,21211,21338,21413,21883,21888,
+21927,21884,21898,21917,21912,21890,21916,21930,21908,21895,21899,21891,21939,
+21934,21919,21822,21938,21914,21947,21932,21937,21886,21897,21931,21913,22285,
+22575,22570,22580,22564,22576,22577,22561,22557,22560,22777,22778,22880,23159,
+23194,23167,23186,23195,23207,23411,23409,23506,23500,23507,23504,23562,23563,
+23601,23884,23888,23860,23879,24061,24133,24125,24128,24131,24190,24266,24257,
+24258,24260,24380,24429,24489,24490,24488,24785,24801,24754,24758,24800,24860,
+24867,24826,24853,24816,24827,24820,24936,24817,24846,24822,24841,24832,24850,
+25119,25161,25507,25484,25551,25536,25577,25545,25542,25549,25554,25571,25552,
+25569,25558,25581,25582,25462,25588,25578,25563,25682,25562,25593,25950,25958,
+25954,25955,26001,26000,26031,26222,26224,26228,26230,
+26223,26257,26234,26238,26231,26366,26367,26399,26397,26874,26837,26848,26840,
+26839,26885,26847,26869,26862,26855,26873,26834,26866,26851,26827,26829,26893,
+26898,26894,26825,26842,26990,26875,27454,27450,27453,27544,27542,27580,27631,
+27694,27695,27692,28207,28216,28244,28193,28210,28263,28234,28192,28197,28195,
+28187,28251,28248,28196,28246,28270,28205,28198,28271,28212,28237,28218,28204,
+28227,28189,28222,28363,28297,28185,28238,28259,28228,28274,28265,28255,28953,
+28954,28966,28976,28961,28982,29038,28956,29260,29316,29312,29494,29477,29492,
+29481,29754,29738,29747,29730,29733,29749,29750,29748,29743,29723,29734,29736,
+29989,29990,30059,30058,30178,30171,30179,30169,30168,30174,30176,30331,30332,
+30358,30355,30388,30428,30543,30701,30813,30828,30831,31245,31240,31243,31237,
+31232,31384,31383,31382,31461,31459,31561,31574,31558,31568,31570,31572,31565,
+31563,31567,31569,31903,31909,32094,32080,32104,32085,32043,32110,32114,32097,
+32102,32098,32112,32115,21892,32724,32725,32779,32850,32901,33109,33108,33099,
+33105,33102,33081,33094,33086,33100,33107,33140,33298,33308,33769,33795,33784,
+33805,33760,33733,33803,33729,33775,33777,33780,33879,33802,33776,33804,33740,
+33789,33778,33738,33848,33806,33796,33756,33799,33748,33759,34395,34527,34521,
+34541,34516,34523,34532,34512,34526,34903,35009,35010,34993,35203,35222,35387,
+35424,35413,35422,35388,35393,35412,35419,35408,35398,35380,35386,35382,35414,
+35937,35970,36015,36028,36019,36029,36033,36027,36032,36020,36023,36022,36031,
+36024,36234,36229,36225,36302,36317,36299,36314,36305,
+36300,36315,36294,36603,36600,36604,36764,36910,36917,36913,36920,36914,36918,
+37122,37109,37129,37118,37219,37221,37327,37396,37397,37411,37385,37406,37389,
+37392,37383,37393,38292,38287,38283,38289,38291,38290,38286,38538,38542,38539,
+38525,38533,38534,38541,38514,38532,38593,38597,38596,38598,38599,38639,38642,
+38860,38917,38918,38920,39143,39146,39151,39145,39154,39149,39342,39341,40643,
+40653,40657,20098,20653,20661,20658,20659,20677,20670,20652,20663,20667,20655,
+20679,21119,21111,21117,21215,21222,21220,21218,21219,21295,21983,21992,21971,
+21990,21966,21980,21959,21969,21987,21988,21999,21978,21985,21957,21958,21989,
+21961,22290,22291,22622,22609,22616,22615,22618,22612,22635,22604,22637,22602,
+22626,22610,22603,22887,23233,23241,23244,23230,23229,23228,23219,23234,23218,
+23913,23919,24140,24185,24265,24264,24338,24409,24492,24494,24858,24847,24904,
+24863,24819,24859,24825,24833,24840,24910,24908,24900,24909,24894,24884,24871,
+24845,24838,24887,25121,25122,25619,25662,25630,25642,25645,25661,25644,25615,
+25628,25620,25613,25654,25622,25623,25606,25964,26015,26032,26263,26249,26247,
+26248,26262,26244,26264,26253,26371,27028,26989,26970,26999,26976,26964,26997,
+26928,27010,26954,26984,26987,26974,26963,27001,27014,26973,26979,26971,27463,
+27506,27584,27583,27603,27645,28322,28335,28371,28342,28354,28304,28317,28359,
+28357,28325,28312,28348,28346,28331,28369,28310,28316,28356,28372,28330,28327,
+28340,29006,29017,29033,29028,29001,29031,29020,29036,29030,29004,29029,29022,
+28998,29032,29014,29242,29266,29495,29509,29503,29502,
+29807,29786,29781,29791,29790,29761,29759,29785,29787,29788,30070,30072,30208,
+30192,30209,30194,30193,30202,30207,30196,30195,30430,30431,30555,30571,30566,
+30558,30563,30585,30570,30572,30556,30565,30568,30562,30702,30862,30896,30871,
+30872,30860,30857,30844,30865,30867,30847,31098,31103,31105,33836,31165,31260,
+31258,31264,31252,31263,31262,31391,31392,31607,31680,31584,31598,31591,31921,
+31923,31925,32147,32121,32145,32129,32143,32091,32622,32617,32618,32626,32681,
+32680,32676,32854,32856,32902,32900,33137,33136,33144,33125,33134,33139,33131,
+33145,33146,33126,33285,33351,33922,33911,33853,33841,33909,33894,33899,33865,
+33900,33883,33852,33845,33889,33891,33897,33901,33862,34398,34396,34399,34553,
+34579,34568,34567,34560,34558,34555,34562,34563,34566,34570,34905,35039,35028,
+35033,35036,35032,35037,35041,35018,35029,35026,35228,35299,35435,35442,35443,
+35430,35433,35440,35463,35452,35427,35488,35441,35461,35437,35426,35438,35436,
+35449,35451,35390,35432,35938,35978,35977,36042,36039,36040,36036,36018,36035,
+36034,36037,36321,36319,36328,36335,36339,36346,36330,36324,36326,36530,36611,
+36617,36606,36618,36767,36786,36939,36938,36947,36930,36948,36924,36949,36944,
+36935,36943,36942,36941,36945,36926,36929,37138,37143,37228,37226,37225,37321,
+37431,37463,37432,37437,37440,37438,37467,37451,37476,37457,37428,37449,37453,
+37445,37433,37439,37466,38296,38552,38548,38549,38605,38603,38601,38602,38647,
+38651,38649,38646,38742,38772,38774,38928,38929,38931,38922,38930,38924,39164,
+39156,39165,39166,39347,39345,39348,39649,40169,40578,
+40718,40723,40736,20711,20718,20709,20694,20717,20698,20693,20687,20689,20721,
+20686,20713,20834,20979,21123,21122,21297,21421,22014,22016,22043,22039,22013,
+22036,22022,22025,22029,22030,22007,22038,22047,22024,22032,22006,22296,22294,
+22645,22654,22659,22675,22666,22649,22661,22653,22781,22821,22818,22820,22890,
+22889,23265,23270,23273,23255,23254,23256,23267,23413,23518,23527,23521,23525,
+23526,23528,23522,23524,23519,23565,23650,23940,23943,24155,24163,24149,24151,
+24148,24275,24278,24330,24390,24432,24505,24903,24895,24907,24951,24930,24931,
+24927,24922,24920,24949,25130,25735,25688,25684,25764,25720,25695,25722,25681,
+25703,25652,25709,25723,25970,26017,26071,26070,26274,26280,26269,27036,27048,
+27029,27073,27054,27091,27083,27035,27063,27067,27051,27060,27088,27085,27053,
+27084,27046,27075,27043,27465,27468,27699,28467,28436,28414,28435,28404,28457,
+28478,28448,28460,28431,28418,28450,28415,28399,28422,28465,28472,28466,28451,
+28437,28459,28463,28552,28458,28396,28417,28402,28364,28407,29076,29081,29053,
+29066,29060,29074,29246,29330,29334,29508,29520,29796,29795,29802,29808,29805,
+29956,30097,30247,30221,30219,30217,30227,30433,30435,30596,30589,30591,30561,
+30913,30879,30887,30899,30889,30883,31118,31119,31117,31278,31281,31402,31401,
+31469,31471,31649,31637,31627,31605,31639,31645,31636,31631,31672,31623,31620,
+31929,31933,31934,32187,32176,32156,32189,32190,32160,32202,32180,32178,32177,
+32186,32162,32191,32181,32184,32173,32210,32199,32172,32624,32736,32737,32735,
+32862,32858,32903,33104,33152,33167,33160,33162,33151,
+33154,33255,33274,33287,33300,33310,33355,33993,33983,33990,33988,33945,33950,
+33970,33948,33995,33976,33984,34003,33936,33980,34001,33994,34623,34588,34619,
+34594,34597,34612,34584,34645,34615,34601,35059,35074,35060,35065,35064,35069,
+35048,35098,35055,35494,35468,35486,35491,35469,35489,35475,35492,35498,35493,
+35496,35480,35473,35482,35495,35946,35981,35980,36051,36049,36050,36203,36249,
+36245,36348,36628,36626,36629,36627,36771,36960,36952,36956,36963,36953,36958,
+36962,36957,36955,37145,37144,37150,37237,37240,37239,37236,37496,37504,37509,
+37528,37526,37499,37523,37532,37544,37500,37521,38305,38312,38313,38307,38309,
+38308,38553,38556,38555,38604,38610,38656,38780,38789,38902,38935,38936,39087,
+39089,39171,39173,39180,39177,39361,39599,39600,39654,39745,39746,40180,40182,
+40179,40636,40763,40778,20740,20736,20731,20725,20729,20738,20744,20745,20741,
+20956,21127,21128,21129,21133,21130,21232,21426,22062,22075,22073,22066,22079,
+22068,22057,22099,22094,22103,22132,22070,22063,22064,22656,22687,22686,22707,
+22684,22702,22697,22694,22893,23305,23291,23307,23285,23308,23304,23534,23532,
+23529,23531,23652,23653,23965,23956,24162,24159,24161,24290,24282,24287,24285,
+24291,24288,24392,24433,24503,24501,24950,24935,24942,24925,24917,24962,24956,
+24944,24939,24958,24999,24976,25003,24974,25004,24986,24996,24980,25006,25134,
+25705,25711,25721,25758,25778,25736,25744,25776,25765,25747,25749,25769,25746,
+25774,25773,25771,25754,25772,25753,25762,25779,25973,25975,25976,26286,26283,
+26292,26289,27171,27167,27112,27137,27166,27161,27133,
+27169,27155,27146,27123,27138,27141,27117,27153,27472,27470,27556,27589,27590,
+28479,28540,28548,28497,28518,28500,28550,28525,28507,28536,28526,28558,28538,
+28528,28516,28567,28504,28373,28527,28512,28511,29087,29100,29105,29096,29270,
+29339,29518,29527,29801,29835,29827,29822,29824,30079,30240,30249,30239,30244,
+30246,30241,30242,30362,30394,30436,30606,30599,30604,30609,30603,30923,30917,
+30906,30922,30910,30933,30908,30928,31295,31292,31296,31293,31287,31291,31407,
+31406,31661,31665,31684,31668,31686,31687,31681,31648,31692,31946,32224,32244,
+32239,32251,32216,32236,32221,32232,32227,32218,32222,32233,32158,32217,32242,
+32249,32629,32631,32687,32745,32806,33179,33180,33181,33184,33178,33176,34071,
+34109,34074,34030,34092,34093,34067,34065,34083,34081,34068,34028,34085,34047,
+34054,34690,34676,34678,34656,34662,34680,34664,34649,34647,34636,34643,34907,
+34909,35088,35079,35090,35091,35093,35082,35516,35538,35527,35524,35477,35531,
+35576,35506,35529,35522,35519,35504,35542,35533,35510,35513,35547,35916,35918,
+35948,36064,36062,36070,36068,36076,36077,36066,36067,36060,36074,36065,36205,
+36255,36259,36395,36368,36381,36386,36367,36393,36383,36385,36382,36538,36637,
+36635,36639,36649,36646,36650,36636,36638,36645,36969,36974,36968,36973,36983,
+37168,37165,37159,37169,37255,37257,37259,37251,37573,37563,37559,37610,37548,
+37604,37569,37555,37564,37586,37575,37616,37554,38317,38321,38660,38662,38663,
+38665,38752,38797,38795,38799,38945,38955,38940,39091,39178,39187,39186,39192,
+39389,39376,39391,39387,39377,39381,39378,39385,39607,
+39662,39663,39719,39749,39748,39799,39791,40198,40201,40195,40617,40638,40654,
+22696,40786,20754,20760,20756,20752,20757,20864,20906,20957,21137,21139,21235,
+22105,22123,22137,22121,22116,22136,22122,22120,22117,22129,22127,22124,22114,
+22134,22721,22718,22727,22725,22894,23325,23348,23416,23536,23566,24394,25010,
+24977,25001,24970,25037,25014,25022,25034,25032,25136,25797,25793,25803,25787,
+25788,25818,25796,25799,25794,25805,25791,25810,25812,25790,25972,26310,26313,
+26297,26308,26311,26296,27197,27192,27194,27225,27243,27224,27193,27204,27234,
+27233,27211,27207,27189,27231,27208,27481,27511,27653,28610,28593,28577,28611,
+28580,28609,28583,28595,28608,28601,28598,28582,28576,28596,29118,29129,29136,
+29138,29128,29141,29113,29134,29145,29148,29123,29124,29544,29852,29859,29848,
+29855,29854,29922,29964,29965,30260,30264,30266,30439,30437,30624,30622,30623,
+30629,30952,30938,30956,30951,31142,31309,31310,31302,31308,31307,31418,31705,
+31761,31689,31716,31707,31713,31721,31718,31957,31958,32266,32273,32264,32283,
+32291,32286,32285,32265,32272,32633,32690,32752,32753,32750,32808,33203,33193,
+33192,33275,33288,33368,33369,34122,34137,34120,34152,34153,34115,34121,34157,
+34154,34142,34691,34719,34718,34722,34701,34913,35114,35122,35109,35115,35105,
+35242,35238,35558,35578,35563,35569,35584,35548,35559,35566,35582,35585,35586,
+35575,35565,35571,35574,35580,35947,35949,35987,36084,36420,36401,36404,36418,
+36409,36405,36667,36655,36664,36659,36776,36774,36981,36980,36984,36978,36988,
+36986,37172,37266,37664,37686,37624,37683,37679,37666,
+37628,37675,37636,37658,37648,37670,37665,37653,37678,37657,38331,38567,38568,
+38570,38613,38670,38673,38678,38669,38675,38671,38747,38748,38758,38808,38960,
+38968,38971,38967,38957,38969,38948,39184,39208,39198,39195,39201,39194,39405,
+39394,39409,39608,39612,39675,39661,39720,39825,40213,40227,40230,40232,40210,
+40219,40664,40660,40845,40860,20778,20767,20769,20786,21237,22158,22144,22160,
+22149,22151,22159,22741,22739,22737,22734,23344,23338,23332,23418,23607,23656,
+23996,23994,23997,23992,24171,24396,24509,25033,25026,25031,25062,25035,25138,
+25140,25806,25802,25816,25824,25840,25830,25836,25841,25826,25837,25986,25987,
+26329,26326,27264,27284,27268,27298,27292,27355,27299,27262,27287,27280,27296,
+27484,27566,27610,27656,28632,28657,28639,28640,28635,28644,28651,28655,28544,
+28652,28641,28649,28629,28654,28656,29159,29151,29166,29158,29157,29165,29164,
+29172,29152,29237,29254,29552,29554,29865,29872,29862,29864,30278,30274,30284,
+30442,30643,30634,30640,30636,30631,30637,30703,30967,30970,30964,30959,30977,
+31143,31146,31319,31423,31751,31757,31742,31735,31756,31712,31968,31964,31966,
+31970,31967,31961,31965,32302,32318,32326,32311,32306,32323,32299,32317,32305,
+32325,32321,32308,32313,32328,32309,32319,32303,32580,32755,32764,32881,32882,
+32880,32879,32883,33222,33219,33210,33218,33216,33215,33213,33225,33214,33256,
+33289,33393,34218,34180,34174,34204,34193,34196,34223,34203,34183,34216,34186,
+34407,34752,34769,34739,34770,34758,34731,34747,34746,34760,34763,35131,35126,
+35140,35128,35133,35244,35598,35607,35609,35611,35594,
+35616,35613,35588,35600,35905,35903,35955,36090,36093,36092,36088,36091,36264,
+36425,36427,36424,36426,36676,36670,36674,36677,36671,36991,36989,36996,36993,
+36994,36992,37177,37283,37278,37276,37709,37762,37672,37749,37706,37733,37707,
+37656,37758,37740,37723,37744,37722,37716,38346,38347,38348,38344,38342,38577,
+38584,38614,38684,38686,38816,38867,38982,39094,39221,39425,39423,39854,39851,
+39850,39853,40251,40255,40587,40655,40670,40668,40669,40667,40766,40779,21474,
+22165,22190,22745,22744,23352,24413,25059,25139,25844,25842,25854,25862,25850,
+25851,25847,26039,26332,26406,27315,27308,27331,27323,27320,27330,27310,27311,
+27487,27512,27567,28681,28683,28670,28678,28666,28689,28687,29179,29180,29182,
+29176,29559,29557,29863,29887,29973,30294,30296,30290,30653,30655,30651,30652,
+30990,31150,31329,31330,31328,31428,31429,31787,31783,31786,31774,31779,31777,
+31975,32340,32341,32350,32346,32353,32338,32345,32584,32761,32763,32887,32886,
+33229,33231,33290,34255,34217,34253,34256,34249,34224,34234,34233,34214,34799,
+34796,34802,34784,35206,35250,35316,35624,35641,35628,35627,35920,36101,36441,
+36451,36454,36452,36447,36437,36544,36681,36685,36999,36995,37000,37291,37292,
+37328,37780,37770,37782,37794,37811,37806,37804,37808,37784,37786,37783,38356,
+38358,38352,38357,38626,38620,38617,38619,38622,38692,38819,38822,38829,38905,
+38989,38991,38988,38990,38995,39098,39230,39231,39229,39214,39333,39438,39617,
+39683,39686,39759,39758,39757,39882,39881,39933,39880,39872,40273,40285,40288,
+40672,40725,40748,20787,22181,22750,22751,22754,23541,
+40848,24300,25074,25079,25078,25077,25856,25871,26336,26333,27365,27357,27354,
+27347,28699,28703,28712,28698,28701,28693,28696,29190,29197,29272,29346,29560,
+29562,29885,29898,29923,30087,30086,30303,30305,30663,31001,31153,31339,31337,
+31806,31807,31800,31805,31799,31808,32363,32365,32377,32361,32362,32645,32371,
+32694,32697,32696,33240,34281,34269,34282,34261,34276,34277,34295,34811,34821,
+34829,34809,34814,35168,35167,35158,35166,35649,35676,35672,35657,35674,35662,
+35663,35654,35673,36104,36106,36476,36466,36487,36470,36460,36474,36468,36692,
+36686,36781,37002,37003,37297,37294,37857,37841,37855,37827,37832,37852,37853,
+37846,37858,37837,37848,37860,37847,37864,38364,38580,38627,38698,38695,38753,
+38876,38907,39006,39000,39003,39100,39237,39241,39446,39449,39693,39912,39911,
+39894,39899,40329,40289,40306,40298,40300,40594,40599,40595,40628,21240,22184,
+22199,22198,22196,22204,22756,23360,23363,23421,23542,24009,25080,25082,25880,
+25876,25881,26342,26407,27372,28734,28720,28722,29200,29563,29903,30306,30309,
+31014,31018,31020,31019,31431,31478,31820,31811,31821,31983,31984,36782,32381,
+32380,32386,32588,32768,33242,33382,34299,34297,34321,34298,34310,34315,34311,
+34314,34836,34837,35172,35258,35320,35696,35692,35686,35695,35679,35691,36111,
+36109,36489,36481,36485,36482,37300,37323,37912,37891,37885,38369,38704,39108,
+39250,39249,39336,39467,39472,39479,39477,39955,39949,40569,40629,40680,40751,
+40799,40803,40801,20791,20792,22209,22208,22210,22804,23660,24013,25084,25086,
+25885,25884,26005,26345,27387,27396,27386,27570,28748,
+29211,29351,29910,29908,30313,30675,31824,32399,32396,32700,34327,34349,34330,
+34851,34850,34849,34847,35178,35180,35261,35700,35703,35709,36115,36490,36493,
+36491,36703,36783,37306,37934,37939,37941,37946,37944,37938,37931,38370,38712,
+38713,38706,38911,39015,39013,39255,39493,39491,39488,39486,39631,39764,39761,
+39981,39973,40367,40372,40386,40376,40605,40687,40729,40796,40806,40807,20796,
+20795,22216,22218,22217,23423,24020,24018,24398,25087,25892,27402,27489,28753,
+28760,29568,29924,30090,30318,30316,31155,31840,31839,32894,32893,33247,35186,
+35183,35324,35712,36118,36119,36497,36499,36705,37192,37956,37969,37970,38717,
+38718,38851,38849,39019,39253,39509,39501,39634,39706,40009,39985,39998,39995,
+40403,40407,40756,40812,40810,40852,22220,24022,25088,25891,25899,25898,26348,
+27408,29914,31434,31844,31843,31845,32403,32406,32404,33250,34360,34367,34865,
+35722,37008,37007,37987,37984,37988,38760,39023,39260,39514,39515,39511,39635,
+39636,39633,40020,40023,40022,40421,40607,40692,22225,22761,25900,28766,30321,
+30322,30679,32592,32648,34870,34873,34914,35731,35730,35734,33399,36123,37312,
+37994,38722,38728,38724,38854,39024,39519,39714,39768,40031,40441,40442,40572,
+40573,40711,40823,40818,24307,27414,28771,31852,31854,34875,35264,36513,37313,
+38002,38000,39025,39262,39638,39715,40652,28772,30682,35738,38007,38857,39522,
+39525,32412,35740,36522,37317,38013,38014,38012,40055,40056,40695,35924,38015,
+40474,29224,39530,39729,40475,40478,31858,9312,9313,9314,9315,9316,9317,9318,
+9319,9320,9321,9332,9333,9334,9335,9336,
+9337,9338,9339,9340,9341,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,
+20022,20031,20101,20128,20866,20886,20907,21241,21304,21353,21430,22794,23424,
+24027,24186,24191,24308,24400,24417,25908,26080,30098,30326,36789,38582,168,
+710,12541,12542,12445,12446,0,0,12293,12294,12295,12540,65339,65341,10045,
+12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,
+12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,
+12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,
+12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,
+12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,
+12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,
+12431,12432,12433,12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,
+12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,
+12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,
+12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,
+12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,
+12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,
+12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,
+1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,
+1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,
+1069,1070,
+1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,
+1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,
+1100,1101,1102,1103,8679,8632,8633,12751,204,20058,138,20994,17553,40880,
+20872,40881,30215,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,65506,65508,65287,65282,12849,8470,8481,12443,12444,11904,
+11908,11910,11911,11912,11914,11916,11917,11925,11932,11933,11941,11943,11946,
+11948,11950,11958,11964,11966,11974,11978,11980,11981,11983,11990,11991,11998,
+12003,0,0,0,643,592,603,596,629,339,248,331,650,618,20034,20060,20981,21274,
+21378,19975,19980,20039,20109,22231,64012,23662,24435,19983,20871,19982,20014,
+20115,20162,20169,20168,20888,21244,21356,21433,22304,22787,22828,23568,24063,
+26081,27571,27596,27668,29247,20017,20028,20200,20188,20201,20193,20189,20186,
+21004,21276,21324,22306,22307,22807,22831,23425,23428,23570,23611,23668,23667,
+24068,24192,24194,24521,25097,25168,27669,27702,27715,27711,27707,29358,29360,
+29578,31160,32906,38430,20238,20248,20268,20213,20244,20209,20224,20215,20232,
+20253,20226,20229,20258,20243,20228,20212,20242,20913,21011,21001,21008,21158,
+21282,21279,21325,21386,21511,22241,22239,22318,22314,22324,22844,22912,22908,
+22917,22907,22910,22903,22911,23382,23573,23589,23676,23674,23675,
+23678,24031,24181,24196,24322,24346,24436,24533,24532,24527,25180,25182,25188,
+25185,25190,25186,25177,25184,25178,25189,26095,26094,26430,26425,26424,26427,
+26426,26431,26428,26419,27672,27718,27730,27740,27727,27722,27732,27723,27724,
+28785,29278,29364,29365,29582,29994,30335,31349,32593,33400,33404,33408,33405,
+33407,34381,35198,37017,37015,37016,37019,37012,38434,38436,38432,38435,20310,
+20283,20322,20297,20307,20324,20286,20327,20306,20319,20289,20312,20269,20275,
+20287,20321,20879,20921,21020,21022,21025,21165,21166,21257,21347,21362,21390,
+21391,21552,21559,21546,21588,21573,21529,21532,21541,21528,21565,21583,21569,
+21544,21540,21575,22254,22247,22245,22337,22341,22348,22345,22347,22354,22790,
+22848,22950,22936,22944,22935,22926,22946,22928,22927,22951,22945,23438,23442,
+23592,23594,23693,23695,23688,23691,23689,23698,23690,23686,23699,23701,24032,
+24074,24078,24203,24201,24204,24200,24205,24325,24349,24440,24438,24530,24529,
+24528,24557,24552,24558,24563,24545,24548,24547,24570,24559,24567,24571,24576,
+24564,25146,25219,25228,25230,25231,25236,25223,25201,25211,25210,25200,25217,
+25224,25207,25213,25202,25204,25911,26096,26100,26099,26098,26101,26437,26439,
+26457,26453,26444,26440,26461,26445,26458,26443,27600,27673,27674,27768,27751,
+27755,27780,27787,27791,27761,27759,27753,27802,27757,27783,27797,27804,27750,
+27763,27749,27771,27790,28788,28794,29283,29375,29373,29379,29382,29377,29370,
+29381,29589,29591,29587,29588,29586,30010,30009,30100,30101,30337,31037,32820,
+32917,32921,32912,32914,32924,33424,33423,33413,33422,
+33425,33427,33418,33411,33412,35960,36809,36799,37023,37025,37029,37022,37031,
+37024,38448,38440,38447,38445,20019,20376,20348,20357,20349,20352,20359,20342,
+20340,20361,20356,20343,20300,20375,20330,20378,20345,20353,20344,20368,20380,
+20372,20382,20370,20354,20373,20331,20334,20894,20924,20926,21045,21042,21043,
+21062,21041,21180,21258,21259,21308,21394,21396,21639,21631,21633,21649,21634,
+21640,21611,21626,21630,21605,21612,21620,21606,21645,21615,21601,21600,21656,
+21603,21607,21604,22263,22265,22383,22386,22381,22379,22385,22384,22390,22400,
+22389,22395,22387,22388,22370,22376,22397,22796,22853,22965,22970,22991,22990,
+22962,22988,22977,22966,22972,22979,22998,22961,22973,22976,22984,22964,22983,
+23394,23397,23443,23445,23620,23623,23726,23716,23712,23733,23727,23720,23724,
+23711,23715,23725,23714,23722,23719,23709,23717,23734,23728,23718,24087,24084,
+24089,24360,24354,24355,24356,24404,24450,24446,24445,24542,24549,24621,24614,
+24601,24626,24587,24628,24586,24599,24627,24602,24606,24620,24610,24589,24592,
+24622,24595,24593,24588,24585,24604,25108,25149,25261,25268,25297,25278,25258,
+25270,25290,25262,25267,25263,25275,25257,25264,25272,25917,26024,26043,26121,
+26108,26116,26130,26120,26107,26115,26123,26125,26117,26109,26129,26128,26358,
+26378,26501,26476,26510,26514,26486,26491,26520,26502,26500,26484,26509,26508,
+26490,26527,26513,26521,26499,26493,26497,26488,26489,26516,27429,27520,27518,
+27614,27677,27795,27884,27883,27886,27865,27830,27860,27821,27879,27831,27856,
+27842,27834,27843,27846,27885,27890,27858,27869,27828,
+27786,27805,27776,27870,27840,27952,27853,27847,27824,27897,27855,27881,27857,
+28820,28824,28805,28819,28806,28804,28817,28822,28802,28826,28803,29290,29398,
+29387,29400,29385,29404,29394,29396,29402,29388,29393,29604,29601,29613,29606,
+29602,29600,29612,29597,29917,29928,30015,30016,30014,30092,30104,30383,30451,
+30449,30448,30453,30712,30716,30713,30715,30714,30711,31042,31039,31173,31352,
+31355,31483,31861,31997,32821,32911,32942,32931,32952,32949,32941,33312,33440,
+33472,33451,33434,33432,33435,33461,33447,33454,33468,33438,33466,33460,33448,
+33441,33449,33474,33444,33475,33462,33442,34416,34415,34413,34414,35926,36818,
+36811,36819,36813,36822,36821,36823,37042,37044,37039,37043,37040,38457,38461,
+38460,38458,38467,20429,20421,20435,20402,20425,20427,20417,20436,20444,20441,
+20411,20403,20443,20423,20438,20410,20416,20409,20460,21060,21065,21184,21186,
+21309,21372,21399,21398,21401,21400,21690,21665,21677,21669,21711,21699,33549,
+21687,21678,21718,21686,21701,21702,21664,21616,21692,21666,21694,21618,21726,
+21680,22453,22430,22431,22436,22412,22423,22429,22427,22420,22424,22415,22425,
+22437,22426,22421,22772,22797,22867,23009,23006,23022,23040,23025,23005,23034,
+23037,23036,23030,23012,23026,23031,23003,23017,23027,23029,23008,23038,23028,
+23021,23464,23628,23760,23768,23756,23767,23755,23771,23774,23770,23753,23751,
+23754,23766,23763,23764,23759,23752,23750,23758,23775,23800,24057,24097,24098,
+24099,24096,24100,24240,24228,24226,24219,24227,24229,24327,24366,24406,24454,
+24631,24633,24660,24690,24670,24645,24659,24647,24649,
+24667,24652,24640,24642,24671,24612,24644,24664,24678,24686,25154,25155,25295,
+25357,25355,25333,25358,25347,25323,25337,25359,25356,25336,25334,25344,25363,
+25364,25338,25365,25339,25328,25921,25923,26026,26047,26166,26145,26162,26165,
+26140,26150,26146,26163,26155,26170,26141,26164,26169,26158,26383,26384,26561,
+26610,26568,26554,26588,26555,26616,26584,26560,26551,26565,26603,26596,26591,
+26549,26573,26547,26615,26614,26606,26595,26562,26553,26574,26599,26608,26546,
+26620,26566,26605,26572,26542,26598,26587,26618,26569,26570,26563,26602,26571,
+27432,27522,27524,27574,27606,27608,27616,27680,27681,27944,27956,27949,27935,
+27964,27967,27922,27914,27866,27955,27908,27929,27962,27930,27921,27904,27933,
+27970,27905,27928,27959,27907,27919,27968,27911,27936,27948,27912,27938,27913,
+27920,28855,28831,28862,28849,28848,28833,28852,28853,28841,29249,29257,29258,
+29292,29296,29299,29294,29386,29412,29416,29419,29407,29418,29414,29411,29573,
+29644,29634,29640,29637,29625,29622,29621,29620,29675,29631,29639,29630,29635,
+29638,29624,29643,29932,29934,29998,30023,30024,30119,30122,30329,30404,30472,
+30467,30468,30469,30474,30455,30459,30458,30695,30696,30726,30737,30738,30725,
+30736,30735,30734,30729,30723,30739,31050,31052,31051,31045,31044,31189,31181,
+31183,31190,31182,31360,31358,31441,31488,31489,31866,31864,31865,31871,31872,
+31873,32003,32008,32001,32600,32657,32653,32702,32775,32782,32783,32788,32823,
+32984,32967,32992,32977,32968,32962,32976,32965,32995,32985,32988,32970,32981,
+32969,32975,32983,32998,32973,33279,33313,33428,33497,
+33534,33529,33543,33512,33536,33493,33594,33515,33494,33524,33516,33505,33522,
+33525,33548,33531,33526,33520,33514,33508,33504,33530,33523,33517,34423,34420,
+34428,34419,34881,34894,34919,34922,34921,35283,35332,35335,36210,36835,36833,
+36846,36832,37105,37053,37055,37077,37061,37054,37063,37067,37064,37332,37331,
+38484,38479,38481,38483,38474,38478,20510,20485,20487,20499,20514,20528,20507,
+20469,20468,20531,20535,20524,20470,20471,20503,20508,20512,20519,20533,20527,
+20529,20494,20826,20884,20883,20938,20932,20933,20936,20942,21089,21082,21074,
+21086,21087,21077,21090,21197,21262,21406,21798,21730,21783,21778,21735,21747,
+21732,21786,21759,21764,21768,21739,21777,21765,21745,21770,21755,21751,21752,
+21728,21774,21763,21771,22273,22274,22476,22578,22485,22482,22458,22470,22461,
+22460,22456,22454,22463,22471,22480,22457,22465,22798,22858,23065,23062,23085,
+23086,23061,23055,23063,23050,23070,23091,23404,23463,23469,23468,23555,23638,
+23636,23788,23807,23790,23793,23799,23808,23801,24105,24104,24232,24238,24234,
+24236,24371,24368,24423,24669,24666,24679,24641,24738,24712,24704,24722,24705,
+24733,24707,24725,24731,24727,24711,24732,24718,25113,25158,25330,25360,25430,
+25388,25412,25413,25398,25411,25572,25401,25419,25418,25404,25385,25409,25396,
+25432,25428,25433,25389,25415,25395,25434,25425,25400,25431,25408,25416,25930,
+25926,26054,26051,26052,26050,26186,26207,26183,26193,26386,26387,26655,26650,
+26697,26674,26675,26683,26699,26703,26646,26673,26652,26677,26667,26669,26671,
+26702,26692,26676,26653,26642,26644,26662,26664,26670,
+26701,26682,26661,26656,27436,27439,27437,27441,27444,27501,32898,27528,27622,
+27620,27624,27619,27618,27623,27685,28026,28003,28004,28022,27917,28001,28050,
+27992,28002,28013,28015,28049,28045,28143,28031,28038,27998,28007,28000,28055,
+28016,28028,27999,28034,28056,27951,28008,28043,28030,28032,28036,27926,28035,
+28027,28029,28021,28048,28892,28883,28881,28893,28875,32569,28898,28887,28882,
+28894,28896,28884,28877,28869,28870,28871,28890,28878,28897,29250,29304,29303,
+29302,29440,29434,29428,29438,29430,29427,29435,29441,29651,29657,29669,29654,
+29628,29671,29667,29673,29660,29650,29659,29652,29661,29658,29655,29656,29672,
+29918,29919,29940,29941,29985,30043,30047,30128,30145,30139,30148,30144,30143,
+30134,30138,30346,30409,30493,30491,30480,30483,30482,30499,30481,30485,30489,
+30490,30498,30503,30755,30764,30754,30773,30767,30760,30766,30763,30753,30761,
+30771,30762,30769,31060,31067,31055,31068,31059,31058,31057,31211,31212,31200,
+31214,31213,31210,31196,31198,31197,31366,31369,31365,31371,31372,31370,31367,
+31448,31504,31492,31507,31493,31503,31496,31498,31502,31497,31506,31876,31889,
+31882,31884,31880,31885,31877,32030,32029,32017,32014,32024,32022,32019,32031,
+32018,32015,32012,32604,32609,32606,32608,32605,32603,32662,32658,32707,32706,
+32704,32790,32830,32825,33018,33010,33017,33013,33025,33019,33024,33281,33327,
+33317,33587,33581,33604,33561,33617,33573,33622,33599,33601,33574,33564,33570,
+33602,33614,33563,33578,33544,33596,33613,33558,33572,33568,33591,33583,33577,
+33607,33605,33612,33619,33566,33580,33611,33575,33608,
+34387,34386,34466,34472,34454,34445,34449,34462,34439,34455,34438,34443,34458,
+34437,34469,34457,34465,34471,34453,34456,34446,34461,34448,34452,34883,34884,
+34925,34933,34934,34930,34944,34929,34943,34927,34947,34942,34932,34940,35346,
+35911,35927,35963,36004,36003,36214,36216,36277,36279,36278,36561,36563,36862,
+36853,36866,36863,36859,36868,36860,36854,37078,37088,37081,37082,37091,37087,
+37093,37080,37083,37079,37084,37092,37200,37198,37199,37333,37346,37338,38492,
+38495,38588,39139,39647,39727,20095,20592,20586,20577,20574,20576,20563,20555,
+20573,20594,20552,20557,20545,20571,20554,20578,20501,20549,20575,20585,20587,
+20579,20580,20550,20544,20590,20595,20567,20561,20944,21099,21101,21100,21102,
+21206,21203,21293,21404,21877,21878,21820,21837,21840,21812,21802,21841,21858,
+21814,21813,21808,21842,21829,21772,21810,21861,21838,21817,21832,21805,21819,
+21824,21835,22282,22279,22523,22548,22498,22518,22492,22516,22528,22509,22525,
+22536,22520,22539,22515,22479,22535,22510,22499,22514,22501,22508,22497,22542,
+22524,22544,22503,22529,22540,22513,22505,22512,22541,22532,22876,23136,23128,
+23125,23143,23134,23096,23093,23149,23120,23135,23141,23148,23123,23140,23127,
+23107,23133,23122,23108,23131,23112,23182,23102,23117,23097,23116,23152,23145,
+23111,23121,23126,23106,23132,23410,23406,23489,23488,23641,23838,23819,23837,
+23834,23840,23820,23848,23821,23846,23845,23823,23856,23826,23843,23839,23854,
+24126,24116,24241,24244,24249,24242,24243,24374,24376,24475,24470,24479,24714,
+24720,24710,24766,24752,24762,24787,24788,24783,24804,
+24793,24797,24776,24753,24795,24759,24778,24767,24771,24781,24768,25394,25445,
+25482,25474,25469,25533,25502,25517,25501,25495,25515,25486,25455,25479,25488,
+25454,25519,25461,25500,25453,25518,25468,25508,25403,25503,25464,25477,25473,
+25489,25485,25456,25939,26061,26213,26209,26203,26201,26204,26210,26392,26745,
+26759,26768,26780,26733,26734,26798,26795,26966,26735,26787,26796,26793,26741,
+26740,26802,26767,26743,26770,26748,26731,26738,26794,26752,26737,26750,26779,
+26774,26763,26784,26761,26788,26744,26747,26769,26764,26762,26749,27446,27443,
+27447,27448,27537,27535,27533,27534,27532,27690,28096,28075,28084,28083,28276,
+28076,28137,28130,28087,28150,28116,28160,28104,28128,28127,28118,28094,28133,
+28124,28125,28123,28148,28106,28093,28141,28144,28090,28117,28098,28111,28105,
+28112,28146,28115,28157,28119,28109,28131,28091,28922,28941,28919,28951,28916,
+28940,28912,28932,28915,28944,28924,28927,28934,28947,28928,28920,28918,28939,
+28930,28942,29310,29307,29308,29311,29469,29463,29447,29457,29464,29450,29448,
+29439,29455,29470,29576,29686,29688,29685,29700,29697,29693,29703,29696,29690,
+29692,29695,29708,29707,29684,29704,30052,30051,30158,30162,30159,30155,30156,
+30161,30160,30351,30345,30419,30521,30511,30509,30513,30514,30516,30515,30525,
+30501,30523,30517,30792,30802,30793,30797,30794,30796,30758,30789,30800,31076,
+31079,31081,31082,31075,31083,31073,31163,31226,31224,31222,31223,31375,31380,
+31376,31541,31559,31540,31525,31536,31522,31524,31539,31512,31530,31517,31537,
+31531,31533,31535,31538,31544,31514,31523,31892,31896,
+31894,31907,32053,32061,32056,32054,32058,32069,32044,32041,32065,32071,32062,
+32063,32074,32059,32040,32611,32661,32668,32669,32667,32714,32715,32717,32720,
+32721,32711,32719,32713,32799,32798,32795,32839,32835,32840,33048,33061,33049,
+33051,33069,33055,33068,33054,33057,33045,33063,33053,33058,33297,33336,33331,
+33338,33332,33330,33396,33680,33699,33704,33677,33658,33651,33700,33652,33679,
+33665,33685,33689,33653,33684,33705,33661,33667,33676,33693,33691,33706,33675,
+33662,33701,33711,33672,33687,33712,33663,33702,33671,33710,33654,33690,34393,
+34390,34495,34487,34498,34497,34501,34490,34480,34504,34489,34483,34488,34508,
+34484,34491,34492,34499,34493,34494,34898,34953,34965,34984,34978,34986,34970,
+34961,34977,34975,34968,34983,34969,34971,34967,34980,34988,34956,34963,34958,
+35202,35286,35289,35285,35376,35367,35372,35358,35897,35899,35932,35933,35965,
+36005,36221,36219,36217,36284,36290,36281,36287,36289,36568,36574,36573,36572,
+36567,36576,36577,36900,36875,36881,36892,36876,36897,37103,37098,37104,37108,
+37106,37107,37076,37099,37100,37097,37206,37208,37210,37203,37205,37356,37364,
+37361,37363,37368,37348,37369,37354,37355,37367,37352,37358,38266,38278,38280,
+38524,38509,38507,38513,38511,38591,38762,38916,39141,39319,20635,20629,20628,
+20638,20619,20643,20611,20620,20622,20637,20584,20636,20626,20610,20615,20831,
+20948,21266,21265,21412,21415,21905,21928,21925,21933,21879,22085,21922,21907,
+21896,21903,21941,21889,21923,21906,21924,21885,21900,21926,21887,21909,21921,
+21902,22284,22569,22583,22553,22558,22567,22563,22568,
+22517,22600,22565,22556,22555,22579,22591,22582,22574,22585,22584,22573,22572,
+22587,22881,23215,23188,23199,23162,23202,23198,23160,23206,23164,23205,23212,
+23189,23214,23095,23172,23178,23191,23171,23179,23209,23163,23165,23180,23196,
+23183,23187,23197,23530,23501,23499,23508,23505,23498,23502,23564,23600,23863,
+23875,23915,23873,23883,23871,23861,23889,23886,23893,23859,23866,23890,23869,
+23857,23897,23874,23865,23881,23864,23868,23858,23862,23872,23877,24132,24129,
+24408,24486,24485,24491,24777,24761,24780,24802,24782,24772,24852,24818,24842,
+24854,24837,24821,24851,24824,24828,24830,24769,24835,24856,24861,24848,24831,
+24836,24843,25162,25492,25521,25520,25550,25573,25576,25583,25539,25757,25587,
+25546,25568,25590,25557,25586,25589,25697,25567,25534,25565,25564,25540,25560,
+25555,25538,25543,25548,25547,25544,25584,25559,25561,25906,25959,25962,25956,
+25948,25960,25957,25996,26013,26014,26030,26064,26066,26236,26220,26235,26240,
+26225,26233,26218,26226,26369,26892,26835,26884,26844,26922,26860,26858,26865,
+26895,26838,26871,26859,26852,26870,26899,26896,26867,26849,26887,26828,26888,
+26992,26804,26897,26863,26822,26900,26872,26832,26877,26876,26856,26891,26890,
+26903,26830,26824,26845,26846,26854,26868,26833,26886,26836,26857,26901,26917,
+26823,27449,27451,27455,27452,27540,27543,27545,27541,27581,27632,27634,27635,
+27696,28156,28230,28231,28191,28233,28296,28220,28221,28229,28258,28203,28223,
+28225,28253,28275,28188,28211,28235,28224,28241,28219,28163,28206,28254,28264,
+28252,28257,28209,28200,28256,28273,28267,28217,28194,
+28208,28243,28261,28199,28280,28260,28279,28245,28281,28242,28262,28213,28214,
+28250,28960,28958,28975,28923,28974,28977,28963,28965,28962,28978,28959,28968,
+28986,28955,29259,29274,29320,29321,29318,29317,29323,29458,29451,29488,29474,
+29489,29491,29479,29490,29485,29478,29475,29493,29452,29742,29740,29744,29739,
+29718,29722,29729,29741,29745,29732,29731,29725,29737,29728,29746,29947,29999,
+30063,30060,30183,30170,30177,30182,30173,30175,30180,30167,30357,30354,30426,
+30534,30535,30532,30541,30533,30538,30542,30539,30540,30686,30700,30816,30820,
+30821,30812,30829,30833,30826,30830,30832,30825,30824,30814,30818,31092,31091,
+31090,31088,31234,31242,31235,31244,31236,31385,31462,31460,31562,31547,31556,
+31560,31564,31566,31552,31576,31557,31906,31902,31912,31905,32088,32111,32099,
+32083,32086,32103,32106,32079,32109,32092,32107,32082,32084,32105,32081,32095,
+32078,32574,32575,32613,32614,32674,32672,32673,32727,32849,32847,32848,33022,
+32980,33091,33098,33106,33103,33095,33085,33101,33082,33254,33262,33271,33272,
+33273,33284,33340,33341,33343,33397,33595,33743,33785,33827,33728,33768,33810,
+33767,33764,33788,33782,33808,33734,33736,33771,33763,33727,33793,33757,33765,
+33752,33791,33761,33739,33742,33750,33781,33737,33801,33807,33758,33809,33798,
+33730,33779,33749,33786,33735,33745,33770,33811,33731,33772,33774,33732,33787,
+33751,33762,33819,33755,33790,34520,34530,34534,34515,34531,34522,34538,34525,
+34539,34524,34540,34537,34519,34536,34513,34888,34902,34901,35002,35031,35001,
+35000,35008,35006,34998,35004,34999,35005,34994,35073,
+35017,35221,35224,35223,35293,35290,35291,35406,35405,35385,35417,35392,35415,
+35416,35396,35397,35410,35400,35409,35402,35404,35407,35935,35969,35968,36026,
+36030,36016,36025,36021,36228,36224,36233,36312,36307,36301,36295,36310,36316,
+36303,36309,36313,36296,36311,36293,36591,36599,36602,36601,36582,36590,36581,
+36597,36583,36584,36598,36587,36593,36588,36596,36585,36909,36916,36911,37126,
+37164,37124,37119,37116,37128,37113,37115,37121,37120,37127,37125,37123,37217,
+37220,37215,37218,37216,37377,37386,37413,37379,37402,37414,37391,37388,37376,
+37394,37375,37373,37382,37380,37415,37378,37404,37412,37401,37399,37381,37398,
+38267,38285,38284,38288,38535,38526,38536,38537,38531,38528,38594,38600,38595,
+38641,38640,38764,38768,38766,38919,39081,39147,40166,40697,20099,20100,20150,
+20669,20671,20678,20654,20676,20682,20660,20680,20674,20656,20673,20666,20657,
+20683,20681,20662,20664,20951,21114,21112,21115,21116,21955,21979,21964,21968,
+21963,21962,21981,21952,21972,21956,21993,21951,21970,21901,21967,21973,21986,
+21974,21960,22002,21965,21977,21954,22292,22611,22632,22628,22607,22605,22601,
+22639,22613,22606,22621,22617,22629,22619,22589,22627,22641,22780,23239,23236,
+23243,23226,23224,23217,23221,23216,23231,23240,23227,23238,23223,23232,23242,
+23220,23222,23245,23225,23184,23510,23512,23513,23583,23603,23921,23907,23882,
+23909,23922,23916,23902,23912,23911,23906,24048,24143,24142,24138,24141,24139,
+24261,24268,24262,24267,24263,24384,24495,24493,24823,24905,24906,24875,24901,
+24886,24882,24878,24902,24879,24911,24873,24896,25120,
+37224,25123,25125,25124,25541,25585,25579,25616,25618,25609,25632,25636,25651,
+25667,25631,25621,25624,25657,25655,25634,25635,25612,25638,25648,25640,25665,
+25653,25647,25610,25626,25664,25637,25639,25611,25575,25627,25646,25633,25614,
+25967,26002,26067,26246,26252,26261,26256,26251,26250,26265,26260,26232,26400,
+26982,26975,26936,26958,26978,26993,26943,26949,26986,26937,26946,26967,26969,
+27002,26952,26953,26933,26988,26931,26941,26981,26864,27000,26932,26985,26944,
+26991,26948,26998,26968,26945,26996,26956,26939,26955,26935,26972,26959,26961,
+26930,26962,26927,27003,26940,27462,27461,27459,27458,27464,27457,27547,64013,
+27643,27644,27641,27639,27640,28315,28374,28360,28303,28352,28319,28307,28308,
+28320,28337,28345,28358,28370,28349,28353,28318,28361,28343,28336,28365,28326,
+28367,28338,28350,28355,28380,28376,28313,28306,28302,28301,28324,28321,28351,
+28339,28368,28362,28311,28334,28323,28999,29012,29010,29027,29024,28993,29021,
+29026,29042,29048,29034,29025,28994,29016,28995,29003,29040,29023,29008,29011,
+28996,29005,29018,29263,29325,29324,29329,29328,29326,29500,29506,29499,29498,
+29504,29514,29513,29764,29770,29771,29778,29777,29783,29760,29775,29776,29774,
+29762,29766,29773,29780,29921,29951,29950,29949,29981,30073,30071,27011,30191,
+30223,30211,30199,30206,30204,30201,30200,30224,30203,30198,30189,30197,30205,
+30361,30389,30429,30549,30559,30560,30546,30550,30554,30569,30567,30548,30553,
+30573,30688,30855,30874,30868,30863,30852,30869,30853,30854,30881,30851,30841,
+30873,30848,30870,30843,31100,31106,31101,31097,31249,
+31256,31257,31250,31255,31253,31266,31251,31259,31248,31395,31394,31390,31467,
+31590,31588,31597,31604,31593,31602,31589,31603,31601,31600,31585,31608,31606,
+31587,31922,31924,31919,32136,32134,32128,32141,32127,32133,32122,32142,32123,
+32131,32124,32140,32148,32132,32125,32146,32621,32619,32615,32616,32620,32678,
+32677,32679,32731,32732,32801,33124,33120,33143,33116,33129,33115,33122,33138,
+26401,33118,33142,33127,33135,33092,33121,33309,33353,33348,33344,33346,33349,
+34033,33855,33878,33910,33913,33935,33933,33893,33873,33856,33926,33895,33840,
+33869,33917,33882,33881,33908,33907,33885,34055,33886,33847,33850,33844,33914,
+33859,33912,33842,33861,33833,33753,33867,33839,33858,33837,33887,33904,33849,
+33870,33868,33874,33903,33989,33934,33851,33863,33846,33843,33896,33918,33860,
+33835,33888,33876,33902,33872,34571,34564,34551,34572,34554,34518,34549,34637,
+34552,34574,34569,34561,34550,34573,34565,35030,35019,35021,35022,35038,35035,
+35034,35020,35024,35205,35227,35295,35301,35300,35297,35296,35298,35292,35302,
+35446,35462,35455,35425,35391,35447,35458,35460,35445,35459,35457,35444,35450,
+35900,35915,35914,35941,35940,35942,35974,35972,35973,36044,36200,36201,36241,
+36236,36238,36239,36237,36243,36244,36240,36242,36336,36320,36332,36337,36334,
+36304,36329,36323,36322,36327,36338,36331,36340,36614,36607,36609,36608,36613,
+36615,36616,36610,36619,36946,36927,36932,36937,36925,37136,37133,37135,37137,
+37142,37140,37131,37134,37230,37231,37448,37458,37424,37434,37478,37427,37477,
+37470,37507,37422,37450,37446,37485,37484,37455,37472,
+37479,37487,37430,37473,37488,37425,37460,37475,37456,37490,37454,37459,37452,
+37462,37426,38303,38300,38302,38299,38546,38547,38545,38551,38606,38650,38653,
+38648,38645,38771,38775,38776,38770,38927,38925,38926,39084,39158,39161,39343,
+39346,39344,39349,39597,39595,39771,40170,40173,40167,40576,40701,20710,20692,
+20695,20712,20723,20699,20714,20701,20708,20691,20716,20720,20719,20707,20704,
+20952,21120,21121,21225,21227,21296,21420,22055,22037,22028,22034,22012,22031,
+22044,22017,22035,22018,22010,22045,22020,22015,22009,22665,22652,22672,22680,
+22662,22657,22655,22644,22667,22650,22663,22673,22670,22646,22658,22664,22651,
+22676,22671,22782,22891,23260,23278,23269,23253,23274,23258,23277,23275,23283,
+23266,23264,23259,23276,23262,23261,23257,23272,23263,23415,23520,23523,23651,
+23938,23936,23933,23942,23930,23937,23927,23946,23945,23944,23934,23932,23949,
+23929,23935,24152,24153,24147,24280,24273,24279,24270,24284,24277,24281,24274,
+24276,24388,24387,24431,24502,24876,24872,24897,24926,24945,24947,24914,24915,
+24946,24940,24960,24948,24916,24954,24923,24933,24891,24938,24929,24918,25129,
+25127,25131,25643,25677,25691,25693,25716,25718,25714,25715,25725,25717,25702,
+25766,25678,25730,25694,25692,25675,25683,25696,25680,25727,25663,25708,25707,
+25689,25701,25719,25971,26016,26273,26272,26271,26373,26372,26402,27057,27062,
+27081,27040,27086,27030,27056,27052,27068,27025,27033,27022,27047,27021,27049,
+27070,27055,27071,27076,27069,27044,27092,27065,27082,27034,27087,27059,27027,
+27050,27041,27038,27097,27031,27024,27074,27061,27045,
+27078,27466,27469,27467,27550,27551,27552,27587,27588,27646,28366,28405,28401,
+28419,28453,28408,28471,28411,28462,28425,28494,28441,28442,28455,28440,28475,
+28434,28397,28426,28470,28531,28409,28398,28461,28480,28464,28476,28469,28395,
+28423,28430,28483,28421,28413,28406,28473,28444,28412,28474,28447,28429,28446,
+28424,28449,29063,29072,29065,29056,29061,29058,29071,29051,29062,29057,29079,
+29252,29267,29335,29333,29331,29507,29517,29521,29516,29794,29811,29809,29813,
+29810,29799,29806,29952,29954,29955,30077,30096,30230,30216,30220,30229,30225,
+30218,30228,30392,30593,30588,30597,30594,30574,30592,30575,30590,30595,30898,
+30890,30900,30893,30888,30846,30891,30878,30885,30880,30892,30882,30884,31128,
+31114,31115,31126,31125,31124,31123,31127,31112,31122,31120,31275,31306,31280,
+31279,31272,31270,31400,31403,31404,31470,31624,31644,31626,31633,31632,31638,
+31629,31628,31643,31630,31621,31640,21124,31641,31652,31618,31931,31935,31932,
+31930,32167,32183,32194,32163,32170,32193,32192,32197,32157,32206,32196,32198,
+32203,32204,32175,32185,32150,32188,32159,32166,32174,32169,32161,32201,32627,
+32738,32739,32741,32734,32804,32861,32860,33161,33158,33155,33159,33165,33164,
+33163,33301,33943,33956,33953,33951,33978,33998,33986,33964,33966,33963,33977,
+33972,33985,33997,33962,33946,33969,34000,33949,33959,33979,33954,33940,33991,
+33996,33947,33961,33967,33960,34006,33944,33974,33999,33952,34007,34004,34002,
+34011,33968,33937,34401,34611,34595,34600,34667,34624,34606,34590,34593,34585,
+34587,34627,34604,34625,34622,34630,34592,34610,34602,
+34605,34620,34578,34618,34609,34613,34626,34598,34599,34616,34596,34586,34608,
+34577,35063,35047,35057,35058,35066,35070,35054,35068,35062,35067,35056,35052,
+35051,35229,35233,35231,35230,35305,35307,35304,35499,35481,35467,35474,35471,
+35478,35901,35944,35945,36053,36047,36055,36246,36361,36354,36351,36365,36349,
+36362,36355,36359,36358,36357,36350,36352,36356,36624,36625,36622,36621,37155,
+37148,37152,37154,37151,37149,37146,37156,37153,37147,37242,37234,37241,37235,
+37541,37540,37494,37531,37498,37536,37524,37546,37517,37542,37530,37547,37497,
+37527,37503,37539,37614,37518,37506,37525,37538,37501,37512,37537,37514,37510,
+37516,37529,37543,37502,37511,37545,37533,37515,37421,38558,38561,38655,38744,
+38781,38778,38782,38787,38784,38786,38779,38788,38785,38783,38862,38861,38934,
+39085,39086,39170,39168,39175,39325,39324,39363,39353,39355,39354,39362,39357,
+39367,39601,39651,39655,39742,39743,39776,39777,39775,40177,40178,40181,40615,
+20735,20739,20784,20728,20742,20743,20726,20734,20747,20748,20733,20746,21131,
+21132,21233,21231,22088,22082,22092,22069,22081,22090,22089,22086,22104,22106,
+22080,22067,22077,22060,22078,22072,22058,22074,22298,22699,22685,22705,22688,
+22691,22703,22700,22693,22689,22783,23295,23284,23293,23287,23286,23299,23288,
+23298,23289,23297,23303,23301,23311,23655,23961,23959,23967,23954,23970,23955,
+23957,23968,23964,23969,23962,23966,24169,24157,24160,24156,32243,24283,24286,
+24289,24393,24498,24971,24963,24953,25009,25008,24994,24969,24987,24979,25007,
+25005,24991,24978,25002,24993,24973,24934,25011,25133,
+25710,25712,25750,25760,25733,25751,25756,25743,25739,25738,25740,25763,25759,
+25704,25777,25752,25974,25978,25977,25979,26034,26035,26293,26288,26281,26290,
+26295,26282,26287,27136,27142,27159,27109,27128,27157,27121,27108,27168,27135,
+27116,27106,27163,27165,27134,27175,27122,27118,27156,27127,27111,27200,27144,
+27110,27131,27149,27132,27115,27145,27140,27160,27173,27151,27126,27174,27143,
+27124,27158,27473,27557,27555,27554,27558,27649,27648,27647,27650,28481,28454,
+28542,28551,28614,28562,28557,28553,28556,28514,28495,28549,28506,28566,28534,
+28524,28546,28501,28530,28498,28496,28503,28564,28563,28509,28416,28513,28523,
+28541,28519,28560,28499,28555,28521,28543,28565,28515,28535,28522,28539,29106,
+29103,29083,29104,29088,29082,29097,29109,29085,29093,29086,29092,29089,29098,
+29084,29095,29107,29336,29338,29528,29522,29534,29535,29536,29533,29531,29537,
+29530,29529,29538,29831,29833,29834,29830,29825,29821,29829,29832,29820,29817,
+29960,29959,30078,30245,30238,30233,30237,30236,30243,30234,30248,30235,30364,
+30365,30366,30363,30605,30607,30601,30600,30925,30907,30927,30924,30929,30926,
+30932,30920,30915,30916,30921,31130,31137,31136,31132,31138,31131,27510,31289,
+31410,31412,31411,31671,31691,31678,31660,31694,31663,31673,31690,31669,31941,
+31944,31948,31947,32247,32219,32234,32231,32215,32225,32259,32250,32230,32246,
+32241,32240,32238,32223,32630,32684,32688,32685,32749,32747,32746,32748,32742,
+32744,32868,32871,33187,33183,33182,33173,33186,33177,33175,33302,33359,33363,
+33362,33360,33358,33361,34084,34107,34063,34048,34089,
+34062,34057,34061,34079,34058,34087,34076,34043,34091,34042,34056,34060,34036,
+34090,34034,34069,34039,34027,34035,34044,34066,34026,34025,34070,34046,34088,
+34077,34094,34050,34045,34078,34038,34097,34086,34023,34024,34032,34031,34041,
+34072,34080,34096,34059,34073,34095,34402,34646,34659,34660,34679,34785,34675,
+34648,34644,34651,34642,34657,34650,34641,34654,34669,34666,34640,34638,34655,
+34653,34671,34668,34682,34670,34652,34661,34639,34683,34677,34658,34663,34665,
+34906,35077,35084,35092,35083,35095,35096,35097,35078,35094,35089,35086,35081,
+35234,35236,35235,35309,35312,35308,35535,35526,35512,35539,35537,35540,35541,
+35515,35543,35518,35520,35525,35544,35523,35514,35517,35545,35902,35917,35983,
+36069,36063,36057,36072,36058,36061,36071,36256,36252,36257,36251,36384,36387,
+36389,36388,36398,36373,36379,36374,36369,36377,36390,36391,36372,36370,36376,
+36371,36380,36375,36378,36652,36644,36632,36634,36640,36643,36630,36631,36979,
+36976,36975,36967,36971,37167,37163,37161,37162,37170,37158,37166,37253,37254,
+37258,37249,37250,37252,37248,37584,37571,37572,37568,37593,37558,37583,37617,
+37599,37592,37609,37591,37597,37580,37615,37570,37608,37578,37576,37582,37606,
+37581,37589,37577,37600,37598,37607,37585,37587,37557,37601,37574,37556,38268,
+38316,38315,38318,38320,38564,38562,38611,38661,38664,38658,38746,38794,38798,
+38792,38864,38863,38942,38941,38950,38953,38952,38944,38939,38951,39090,39176,
+39162,39185,39188,39190,39191,39189,39388,39373,39375,39379,39380,39374,39369,
+39382,39384,39371,39383,39372,39603,39660,39659,39667,
+39666,39665,39750,39747,39783,39796,39793,39782,39798,39797,39792,39784,39780,
+39788,40188,40186,40189,40191,40183,40199,40192,40185,40187,40200,40197,40196,
+40579,40659,40719,40720,20764,20755,20759,20762,20753,20958,21300,21473,22128,
+22112,22126,22131,22118,22115,22125,22130,22110,22135,22300,22299,22728,22717,
+22729,22719,22714,22722,22716,22726,23319,23321,23323,23329,23316,23315,23312,
+23318,23336,23322,23328,23326,23535,23980,23985,23977,23975,23989,23984,23982,
+23978,23976,23986,23981,23983,23988,24167,24168,24166,24175,24297,24295,24294,
+24296,24293,24395,24508,24989,25000,24982,25029,25012,25030,25025,25036,25018,
+25023,25016,24972,25815,25814,25808,25807,25801,25789,25737,25795,25819,25843,
+25817,25907,25983,25980,26018,26312,26302,26304,26314,26315,26319,26301,26299,
+26298,26316,26403,27188,27238,27209,27239,27186,27240,27198,27229,27245,27254,
+27227,27217,27176,27226,27195,27199,27201,27242,27236,27216,27215,27220,27247,
+27241,27232,27196,27230,27222,27221,27213,27214,27206,27477,27476,27478,27559,
+27562,27563,27592,27591,27652,27651,27654,28589,28619,28579,28615,28604,28622,
+28616,28510,28612,28605,28574,28618,28584,28676,28581,28590,28602,28588,28586,
+28623,28607,28600,28578,28617,28587,28621,28591,28594,28592,29125,29122,29119,
+29112,29142,29120,29121,29131,29140,29130,29127,29135,29117,29144,29116,29126,
+29146,29147,29341,29342,29545,29542,29543,29548,29541,29547,29546,29823,29850,
+29856,29844,29842,29845,29857,29963,30080,30255,30253,30257,30269,30259,30268,
+30261,30258,30256,30395,30438,30618,30621,30625,30620,
+30619,30626,30627,30613,30617,30615,30941,30953,30949,30954,30942,30947,30939,
+30945,30946,30957,30943,30944,31140,31300,31304,31303,31414,31416,31413,31409,
+31415,31710,31715,31719,31709,31701,31717,31706,31720,31737,31700,31722,31714,
+31708,31723,31704,31711,31954,31956,31959,31952,31953,32274,32289,32279,32268,
+32287,32288,32275,32270,32284,32277,32282,32290,32267,32271,32278,32269,32276,
+32293,32292,32579,32635,32636,32634,32689,32751,32810,32809,32876,33201,33190,
+33198,33209,33205,33195,33200,33196,33204,33202,33207,33191,33266,33365,33366,
+33367,34134,34117,34155,34125,34131,34145,34136,34112,34118,34148,34113,34146,
+34116,34129,34119,34147,34110,34139,34161,34126,34158,34165,34133,34151,34144,
+34188,34150,34141,34132,34149,34156,34403,34405,34404,34715,34703,34711,34707,
+34706,34696,34689,34710,34712,34681,34695,34723,34693,34704,34705,34717,34692,
+34708,34716,34714,34697,35102,35110,35120,35117,35118,35111,35121,35106,35113,
+35107,35119,35116,35103,35313,35552,35554,35570,35572,35573,35549,35604,35556,
+35551,35568,35528,35550,35553,35560,35583,35567,35579,35985,35986,35984,36085,
+36078,36081,36080,36083,36204,36206,36261,36263,36403,36414,36408,36416,36421,
+36406,36412,36413,36417,36400,36415,36541,36662,36654,36661,36658,36665,36663,
+36660,36982,36985,36987,36998,37114,37171,37173,37174,37267,37264,37265,37261,
+37263,37671,37662,37640,37663,37638,37647,37754,37688,37692,37659,37667,37650,
+37633,37702,37677,37646,37645,37579,37661,37626,37669,37651,37625,37623,37684,
+37634,37668,37631,37673,37689,37685,37674,37652,37644,
+37643,37630,37641,37632,37627,37654,38332,38349,38334,38329,38330,38326,38335,
+38325,38333,38569,38612,38667,38674,38672,38809,38807,38804,38896,38904,38965,
+38959,38962,39204,39199,39207,39209,39326,39406,39404,39397,39396,39408,39395,
+39402,39401,39399,39609,39615,39604,39611,39670,39674,39673,39671,39731,39808,
+39813,39815,39804,39806,39803,39810,39827,39826,39824,39802,39829,39805,39816,
+40229,40215,40224,40222,40212,40233,40221,40216,40226,40208,40217,40223,40584,
+40582,40583,40622,40621,40661,40662,40698,40722,40765,20774,20773,20770,20772,
+20768,20777,21236,22163,22156,22157,22150,22148,22147,22142,22146,22143,22145,
+22742,22740,22735,22738,23341,23333,23346,23331,23340,23335,23334,23343,23342,
+23419,23537,23538,23991,24172,24170,24510,24507,25027,25013,25020,25063,25056,
+25061,25060,25064,25054,25839,25833,25827,25835,25828,25832,25985,25984,26038,
+26074,26322,27277,27286,27265,27301,27273,27295,27291,27297,27294,27271,27283,
+27278,27285,27267,27304,27300,27281,27263,27302,27290,27269,27276,27282,27483,
+27565,27657,28620,28585,28660,28628,28643,28636,28653,28647,28646,28638,28658,
+28637,28642,28648,29153,29169,29160,29170,29156,29168,29154,29555,29550,29551,
+29847,29874,29867,29840,29866,29869,29873,29861,29871,29968,29969,29970,29967,
+30084,30275,30280,30281,30279,30372,30441,30645,30635,30642,30647,30646,30644,
+30641,30632,30704,30963,30973,30978,30971,30972,30962,30981,30969,30974,30980,
+31147,31144,31324,31323,31318,31320,31316,31322,31422,31424,31425,31749,31759,
+31730,31744,31743,31739,31758,31732,31755,31731,31746,
+31753,31747,31745,31736,31741,31750,31728,31729,31760,31754,31976,32301,32316,
+32322,32307,38984,32312,32298,32329,32320,32327,32297,32332,32304,32315,32310,
+32324,32314,32581,32639,32638,32637,32756,32754,32812,33211,33220,33228,33226,
+33221,33223,33212,33257,33371,33370,33372,34179,34176,34191,34215,34197,34208,
+34187,34211,34171,34212,34202,34206,34167,34172,34185,34209,34170,34168,34135,
+34190,34198,34182,34189,34201,34205,34177,34210,34178,34184,34181,34169,34166,
+34200,34192,34207,34408,34750,34730,34733,34757,34736,34732,34745,34741,34748,
+34734,34761,34755,34754,34764,34743,34735,34756,34762,34740,34742,34751,34744,
+34749,34782,34738,35125,35123,35132,35134,35137,35154,35127,35138,35245,35247,
+35246,35314,35315,35614,35608,35606,35601,35589,35595,35618,35599,35602,35605,
+35591,35597,35592,35590,35612,35603,35610,35919,35952,35954,35953,35951,35989,
+35988,36089,36207,36430,36429,36435,36432,36428,36423,36675,36672,36997,36990,
+37176,37274,37282,37275,37273,37279,37281,37277,37280,37793,37763,37807,37732,
+37718,37703,37756,37720,37724,37750,37705,37712,37713,37728,37741,37775,37708,
+37738,37753,37719,37717,37714,37711,37745,37751,37755,37729,37726,37731,37735,
+37760,37710,37721,38343,38336,38345,38339,38341,38327,38574,38576,38572,38688,
+38687,38680,38685,38681,38810,38817,38812,38814,38813,38869,38868,38897,38977,
+38980,38986,38985,38981,38979,39205,39211,39212,39210,39219,39218,39215,39213,
+39217,39216,39320,39331,39329,39426,39418,39412,39415,39417,39416,39414,39419,
+39421,39422,39420,39427,39614,39678,39677,39681,39676,
+39752,39834,39848,39838,39835,39846,39841,39845,39844,39814,39842,39840,39855,
+40243,40257,40295,40246,40238,40239,40241,40248,40240,40261,40258,40259,40254,
+40247,40256,40253,32757,40237,40586,40585,40589,40624,40648,40666,40699,40703,
+40740,40739,40738,40788,40864,20785,20781,20782,22168,22172,22167,22170,22173,
+22169,22896,23356,23657,23658,24000,24173,24174,25048,25055,25069,25070,25073,
+25066,25072,25067,25046,25065,25855,25860,25853,25848,25857,25859,25852,26004,
+26075,26330,26331,26328,27333,27321,27325,27361,27334,27322,27318,27319,27335,
+27316,27309,27486,27593,27659,28679,28684,28685,28673,28677,28692,28686,28671,
+28672,28667,28710,28668,28663,28682,29185,29183,29177,29187,29181,29558,29880,
+29888,29877,29889,29886,29878,29883,29890,29972,29971,30300,30308,30297,30288,
+30291,30295,30298,30374,30397,30444,30658,30650,30975,30988,30995,30996,30985,
+30992,30994,30993,31149,31148,31327,31772,31785,31769,31776,31775,31789,31773,
+31782,31784,31778,31781,31792,32348,32336,32342,32355,32344,32354,32351,32337,
+32352,32343,32339,32693,32691,32759,32760,32885,33233,33234,33232,33375,33374,
+34228,34246,34240,34243,34242,34227,34229,34237,34247,34244,34239,34251,34254,
+34248,34245,34225,34230,34258,34340,34232,34231,34238,34409,34791,34790,34786,
+34779,34795,34794,34789,34783,34803,34788,34772,34780,34771,34797,34776,34787,
+34724,34775,34777,34817,34804,34792,34781,35155,35147,35151,35148,35142,35152,
+35153,35145,35626,35623,35619,35635,35632,35637,35655,35631,35644,35646,35633,
+35621,35639,35622,35638,35630,35620,35643,35645,35642,
+35906,35957,35993,35992,35991,36094,36100,36098,36096,36444,36450,36448,36439,
+36438,36446,36453,36455,36443,36442,36449,36445,36457,36436,36678,36679,36680,
+36683,37160,37178,37179,37182,37288,37285,37287,37295,37290,37813,37772,37778,
+37815,37787,37789,37769,37799,37774,37802,37790,37798,37781,37768,37785,37791,
+37773,37809,37777,37810,37796,37800,37812,37795,37797,38354,38355,38353,38579,
+38615,38618,24002,38623,38616,38621,38691,38690,38693,38828,38830,38824,38827,
+38820,38826,38818,38821,38871,38873,38870,38872,38906,38992,38993,38994,39096,
+39233,39228,39226,39439,39435,39433,39437,39428,39441,39434,39429,39431,39430,
+39616,39644,39688,39684,39685,39721,39733,39754,39756,39755,39879,39878,39875,
+39871,39873,39861,39864,39891,39862,39876,39865,39869,40284,40275,40271,40266,
+40283,40267,40281,40278,40268,40279,40274,40276,40287,40280,40282,40590,40588,
+40671,40705,40704,40726,40741,40747,40746,40745,40744,40780,40789,20788,20789,
+21142,21239,21428,22187,22189,22182,22183,22186,22188,22746,22749,22747,22802,
+23357,23358,23359,24003,24176,24511,25083,25863,25872,25869,25865,25868,25870,
+25988,26078,26077,26334,27367,27360,27340,27345,27353,27339,27359,27356,27344,
+27371,27343,27341,27358,27488,27568,27660,28697,28711,28704,28694,28715,28705,
+28706,28707,28713,28695,28708,28700,28714,29196,29194,29191,29186,29189,29349,
+29350,29348,29347,29345,29899,29893,29879,29891,29974,30304,30665,30666,30660,
+30705,31005,31003,31009,31004,30999,31006,31152,31335,31336,31795,31804,31801,
+31788,31803,31980,31978,32374,32373,32376,32368,32375,
+32367,32378,32370,32372,32360,32587,32586,32643,32646,32695,32765,32766,32888,
+33239,33237,33380,33377,33379,34283,34289,34285,34265,34273,34280,34266,34263,
+34284,34290,34296,34264,34271,34275,34268,34257,34288,34278,34287,34270,34274,
+34816,34810,34819,34806,34807,34825,34828,34827,34822,34812,34824,34815,34826,
+34818,35170,35162,35163,35159,35169,35164,35160,35165,35161,35208,35255,35254,
+35318,35664,35656,35658,35648,35667,35670,35668,35659,35669,35665,35650,35666,
+35671,35907,35959,35958,35994,36102,36103,36105,36268,36266,36269,36267,36461,
+36472,36467,36458,36463,36475,36546,36690,36689,36687,36688,36691,36788,37184,
+37183,37296,37293,37854,37831,37839,37826,37850,37840,37881,37868,37836,37849,
+37801,37862,37834,37844,37870,37859,37845,37828,37838,37824,37842,37863,38269,
+38362,38363,38625,38697,38699,38700,38696,38694,38835,38839,38838,38877,38878,
+38879,39004,39001,39005,38999,39103,39101,39099,39102,39240,39239,39235,39334,
+39335,39450,39445,39461,39453,39460,39451,39458,39456,39463,39459,39454,39452,
+39444,39618,39691,39690,39694,39692,39735,39914,39915,39904,39902,39908,39910,
+39906,39920,39892,39895,39916,39900,39897,39909,39893,39905,39898,40311,40321,
+40330,40324,40328,40305,40320,40312,40326,40331,40332,40317,40299,40308,40309,
+40304,40297,40325,40307,40315,40322,40303,40313,40319,40327,40296,40596,40593,
+40640,40700,40749,40768,40769,40781,40790,40791,40792,21303,22194,22197,22195,
+22755,23365,24006,24007,24302,24303,24512,24513,25081,25879,25878,25877,25875,
+26079,26344,26339,26340,27379,27376,27370,27368,27385,
+27377,27374,27375,28732,28725,28719,28727,28724,28721,28738,28728,28735,28730,
+28729,28736,28731,28723,28737,29203,29204,29352,29565,29564,29882,30379,30378,
+30398,30445,30668,30670,30671,30669,30706,31013,31011,31015,31016,31012,31017,
+31154,31342,31340,31341,31479,31817,31816,31818,31815,31813,31982,32379,32382,
+32385,32384,32698,32767,32889,33243,33241,33291,33384,33385,34338,34303,34305,
+34302,34331,34304,34294,34308,34313,34309,34316,34301,34841,34832,34833,34839,
+34835,34838,35171,35174,35257,35319,35680,35690,35677,35688,35683,35685,35687,
+35693,36270,36486,36488,36484,36697,36694,36695,36693,36696,36698,37005,37187,
+37185,37303,37301,37298,37299,37899,37907,37883,37920,37903,37908,37886,37909,
+37904,37928,37913,37901,37877,37888,37879,37895,37902,37910,37906,37882,37897,
+37880,37898,37887,37884,37900,37878,37905,37894,38366,38368,38367,38702,38703,
+38841,38843,38909,38910,39008,39010,39011,39007,39105,39106,39248,39246,39257,
+39244,39243,39251,39474,39476,39473,39468,39466,39478,39465,39470,39480,39469,
+39623,39626,39622,39696,39698,39697,39947,39944,39927,39941,39954,39928,40000,
+39943,39950,39942,39959,39956,39945,40351,40345,40356,40349,40338,40344,40336,
+40347,40352,40340,40348,40362,40343,40353,40346,40354,40360,40350,40355,40383,
+40361,40342,40358,40359,40601,40603,40602,40677,40676,40679,40678,40752,40750,
+40795,40800,40798,40797,40793,40849,20794,20793,21144,21143,22211,22205,22206,
+23368,23367,24011,24015,24305,25085,25883,27394,27388,27395,27384,27392,28739,
+28740,28746,28744,28745,28741,28742,29213,29210,29209,
+29566,29975,30314,30672,31021,31025,31023,31828,31827,31986,32394,32391,32392,
+32395,32390,32397,32589,32699,32816,33245,34328,34346,34342,34335,34339,34332,
+34329,34343,34350,34337,34336,34345,34334,34341,34857,34845,34843,34848,34852,
+34844,34859,34890,35181,35177,35182,35179,35322,35705,35704,35653,35706,35707,
+36112,36116,36271,36494,36492,36702,36699,36701,37190,37188,37189,37305,37951,
+37947,37942,37929,37949,37948,37936,37945,37930,37943,37932,37952,37937,38373,
+38372,38371,38709,38714,38847,38881,39012,39113,39110,39104,39256,39254,39481,
+39485,39494,39492,39490,39489,39482,39487,39629,39701,39703,39704,39702,39738,
+39762,39979,39965,39964,39980,39971,39976,39977,39972,39969,40375,40374,40380,
+40385,40391,40394,40399,40382,40389,40387,40379,40373,40398,40377,40378,40364,
+40392,40369,40365,40396,40371,40397,40370,40570,40604,40683,40686,40685,40731,
+40728,40730,40753,40782,40805,40804,40850,20153,22214,22213,22219,22897,23371,
+23372,24021,24017,24306,25889,25888,25894,25890,27403,27400,27401,27661,28757,
+28758,28759,28754,29214,29215,29353,29567,29912,29909,29913,29911,30317,30381,
+31029,31156,31344,31345,31831,31836,31833,31835,31834,31988,31985,32401,32591,
+32647,33246,33387,34356,34357,34355,34348,34354,34358,34860,34856,34854,34858,
+34853,35185,35263,35262,35323,35710,35716,35714,35718,35717,35711,36117,36501,
+36500,36506,36498,36496,36502,36503,36704,36706,37191,37964,37968,37962,37963,
+37967,37959,37957,37960,37961,37958,38719,38883,39018,39017,39115,39252,39259,
+39502,39507,39508,39500,39503,39496,39498,39497,39506,
+39504,39632,39705,39723,39739,39766,39765,40006,40008,39999,40004,39993,39987,
+40001,39996,39991,39988,39986,39997,39990,40411,40402,40414,40410,40395,40400,
+40412,40401,40415,40425,40409,40408,40406,40437,40405,40413,40630,40688,40757,
+40755,40754,40770,40811,40853,40866,20797,21145,22760,22759,22898,23373,24024,
+34863,24399,25089,25091,25092,25897,25893,26006,26347,27409,27410,27407,27594,
+28763,28762,29218,29570,29569,29571,30320,30676,31847,31846,32405,33388,34362,
+34368,34361,34364,34353,34363,34366,34864,34866,34862,34867,35190,35188,35187,
+35326,35724,35726,35723,35720,35909,36121,36504,36708,36707,37308,37986,37973,
+37981,37975,37982,38852,38853,38912,39510,39513,39710,39711,39712,40018,40024,
+40016,40010,40013,40011,40021,40025,40012,40014,40443,40439,40431,40419,40427,
+40440,40420,40438,40417,40430,40422,40434,40432,40418,40428,40436,40435,40424,
+40429,40642,40656,40690,40691,40710,40732,40760,40759,40758,40771,40783,40817,
+40816,40814,40815,22227,22221,23374,23661,25901,26349,26350,27411,28767,28769,
+28765,28768,29219,29915,29925,30677,31032,31159,31158,31850,32407,32649,33389,
+34371,34872,34871,34869,34891,35732,35733,36510,36511,36512,36509,37310,37309,
+37314,37995,37992,37993,38629,38726,38723,38727,38855,38885,39518,39637,39769,
+40035,40039,40038,40034,40030,40032,40450,40446,40455,40451,40454,40453,40448,
+40449,40457,40447,40445,40452,40608,40734,40774,40820,40821,40822,22228,25902,
+26040,27416,27417,27415,27418,28770,29222,29354,30680,30681,31033,31849,31851,
+31990,32410,32408,32411,32409,33248,33249,34374,34375,
+34376,35193,35194,35196,35195,35327,35736,35737,36517,36516,36515,37998,37997,
+37999,38001,38003,38729,39026,39263,40040,40046,40045,40459,40461,40464,40463,
+40466,40465,40609,40693,40713,40775,40824,40827,40826,40825,22302,28774,31855,
+34876,36274,36518,37315,38004,38008,38006,38005,39520,40052,40051,40049,40053,
+40468,40467,40694,40714,40868,28776,28773,31991,34410,34878,34877,34879,35742,
+35996,36521,36553,38731,39027,39028,39116,39265,39339,39524,39526,39527,39716,
+40469,40471,40776,25095,27422,29223,34380,36520,38018,38016,38017,39529,39528,
+39726,40473,29225,34379,35743,38019,40057,40631,30325,39531,40058,40477,28777,
+28778,40612,40830,40777,40856,30849,37561,35023,22715,24658,31911,23290,9556,
+9574,9559,9568,9580,9571,9562,9577,9565,9554,9572,9557,9566,9578,9569,9560,
+9575,9563,9555,9573,9558,9567,9579,9570,9561,9576,9564,9553,9552,9581,9582,
+9584,9583,9619,
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/bind_textdomain_codeset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/bind_textdomain_codeset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/bind_textdomain_codeset.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <libintl.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+
+char *bind_textdomain_codeset(const char *domainname, const char *codeset)
+{
+	if (codeset && strcasecmp(codeset, "UTF-8"))
+		errno = EINVAL;
+	return NULL;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/c_locale.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/c_locale.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/c_locale.c	(revision 398)
@@ -0,0 +1,15 @@
+#include "locale_impl.h"
+#include <stdint.h>
+
+static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
+
+const struct __locale_map __c_dot_utf8 = {
+	.map = empty_mo,
+	.map_size = sizeof empty_mo,
+	.name = "C.UTF-8"
+};
+
+const struct __locale_struct __c_locale = { 0 };
+const struct __locale_struct __c_dot_utf8_locale = {
+	.cat[LC_CTYPE] = &__c_dot_utf8
+};
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/catclose.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/catclose.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/catclose.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <nl_types.h>
+
+int catclose (nl_catd catd)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/catgets.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/catgets.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/catgets.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <nl_types.h>
+
+char *catgets (nl_catd catd, int set_id, int msg_id, const char *s)
+{
+	return (char *)s;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/catopen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/catopen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/catopen.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <nl_types.h>
+#include <errno.h>
+
+nl_catd catopen (const char *name, int oflag)
+{
+	errno = EOPNOTSUPP;
+	return (nl_catd)-1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/codepages.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/codepages.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/codepages.h	(revision 398)
@@ -0,0 +1,265 @@
+"iso88591\0"
+"latin1\0"
+"\0\200"
+
+"iso88592\0"
+"\0\40"
+"\0\330\20\313\32\0\244\21\10\0\0\34\122\310\42\240\0\100\212\50\0\334\60\13\33"
+"\0\250\41\10\54\0\40\142\10\43\241\324\122\312\50\173\0\0\0\15\0\224\201\3\0"
+"\76\0\200\4\0\112\0\0\0\20\102\264\21\7\0\0\334\1\0\0\177\124\2\300\45"
+"\0\0\220\10\0\174\0\0\100\15\0\230\221\3\0\77\0\220\4\0\113\0\0\100\20"
+"\103\270\41\7\0\0\340\1\0\0\200\130\2\0\46\0\0\240\210\54"
+
+"iso88593\0"
+"\0\40"
+"\0\130\21\13\0\0\4\100\5\0\0\170\121\210\23\140\0\20\200\50\0\134\1\0\0"
+"\0\0\120\5\0\0\174\141\310\23\141\0\20\300\50\0\0\0\100\0\0\360\240\3\0"
+"\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0\100\1\0\0\114\0\0\0\0\0\114\62\10\0"
+"\0\0\0\100\0\0\364\260\3\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0\104\1\0\0"
+"\115\0\0\0\0\0\120\102\210\54"
+
+"iso88594\0"
+"\0\40"
+"\0\330\100\106\37\0\140\161\6\0\0\34\102\204\24\215\0\100\12\0\0\334\60\213\37"
+"\0\144\201\6\54\0\40\122\304\24\216\314\121\12\35\62\0\0\0\0\0\0\0\0\27"
+"\76\0\200\4\0\106\0\0\200\26\102\274\121\207\30\0\0\0\0\0\0\144\2\0\0"
+"\0\74\22\11\0\63\0\0\0\0\0\0\0\100\27\77\0\220\4\0\107\0\0\300\26"
+"\103\300\141\307\30\0\0\0\0\0\0\150\2\0\0\0\100\42\211\54"
+
+"iso88595\0"
+"\0\40"
+"\0\14\104\120\101\6\35\204\120\102\12\55\304\120\103\16\1\360\20\104"
+"\21\111\64\21\105\25\131\164\21\106\31\151\264\21\107\35\171\364\21\110"
+"\41\211\64\22\111\45\231\164\22\112\51\251\264\22\113\55\271\364\22\114"
+"\61\311\64\23\115\65\331\164\23\116\71\351\264\23\117\75\371\364\23\120"
+"\101\11\65\24\121\105\31\165\24\122\111\51\265\24\123\115\71\365\24\124"
+"\127\106\45\325\124\124\125\145\325\125\130\145\245\325\126\134\15\320\225\127"
+
+"iso88596\0"
+"\0\40"
+"\0\4\20\100\0\0\4\20\100\0\1\4\20\100\0\224\1\20\100\0\1\4\20\100\0"
+"\1\4\20\100\0\1\4\20\100\145\1\4\20\200\145\1\134\206\131\146"
+"\232\155\306\131\147\236\175\6\132\150\242\215\106\132\151\246\235\206\132\152"
+"\252\255\306\132\153\256\275\6\133\0\1\4\20\100\0\261\311\66\33\155"
+"\265\331\166\33\156\271\351\266\33\157\275\371\366\33\160\301\11\67\134\0"
+"\1\4\20\100\0\1\4\20\100\0\1\4\20\100\0"
+
+"iso88597\0"
+"\0\40"
+"\0\24\151\44\0\124\126\11\0\0\0\0\260\13\0\0\0\20\300\220\0\0\0\0\0"
+"\274\364\342\13\0\277\0\23\14\0\302\0\60\14\61\305\30\163\14\62"
+"\311\50\263\14\63\315\70\363\14\64\321\110\63\15\65\325\130\23\300\65"
+"\330\144\243\315\66\334\164\343\315\67\340\204\43\316\70\344\224\143\316\71"
+"\350\244\243\316\72\354\264\343\316\73\360\304\43\317\74\364\324\143\317\75"
+"\370\344\243\317\76\374\364\343\317\77\0\5\44\120\0"
+
+"iso88598\0"
+"\0\40"
+"\0\4\0\0\0\0\0\0\0\0\0\0\300\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\360\0\0"
+"\0\0\0\100\0\1\4\20\100\0\1\4\20\100\0\1\4\20\100\0\1\4\20\100\0\1\4\20\100\0"
+"\1\4\20\100\0\1\4\20\100\0\1\4\20\0\221\164\325\145\327\135"
+"\170\345\245\327\136\174\365\345\327\137\200\5\46\330\140\204\25\146\330\141"
+"\210\45\246\330\142\214\65\346\130\0\1\374\10\144\0"
+
+"iso88599\0"
+"\0\120"
+"\116\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\170\121\10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+"\0\0\0\0\0\117\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\174\141\10\0"
+
+"iso885910\0"
+"\0\40"
+"\0\330\100\204\24\132\140\41\6\0\147\10\161\110\43\244\0\20\311\34"
+"\0\334\120\304\24\133\144\61\6\0\150\14\201\210\43\245\14\51\11\35\62\0\0\0\0"
+"\0\0\0\0\27\76\0\200\4\0\106\0\0\0\0\0\274\121\7\0\0\0\0\300\43\0\144\2\0\0"
+"\0\0\0\0\0\63\0\0\0\0\0\0\0\100\27\77\0\220\4\0\107\0\0\0\0\0\300\141\7\0"
+"\0\0\0\0\44\0\150\2\0\0\0\0\0\0\31"
+
+"iso885911\0"
+"tis620\0"
+"\0\40"
+"\0\100\27\235\164\323\121\127\235\165\327\141\227\235\166\333\161\327\235\167"
+"\337\201\27\236\170\343\221\127\236\171\347\241\227\236\172"
+"\353\261\327\236\173\357\301\27\237\174\363\321\127\237\175"
+"\367\341\227\237\176\373\361\327\237\177\377\1\30\240\200\3\22\130\240\201"
+"\7\42\230\140\0\1\4\20\200\202\13\62\330\240\203\17\102\30\241\204"
+"\23\122\130\241\205\27\142\230\241\206\33\162\330\241\207\37\202\30\242\210"
+"\43\222\130\242\211\1\4\20\100\0"
+
+"iso885913\0"
+"\0\40"
+"\0\44\11\0\0\0\50\11\0\0\15\0\320\7\0\0\0\0\300\2\0\0\0\0\0\110\2\0\0\0"
+"\20\0\340\7\0\0\0\0\200\3\66\160\41\3\16\0\0\200\4\21\76\0\0\212\21"
+"\122\210\241\305\31\207\264\361\6\0\165\0\0\0\0\231\254\21\110\44"
+"\0\210\102\12\0\67\164\61\103\16\0\0\220\104\21\77\0\20\312\21"
+"\123\214\261\5\32\210\270\1\7\0\166\0\0\0\0\232\260\41\210\44"
+"\0\214\122\212\221"
+
+"iso885914\0"
+"\0\40"
+"\0\234\210\42\0\74\364\220\42\0\65\2\160\243\212\73\2\0\300\47"
+"\53\262\10\105\24\55\272\10\300\213\66\302\210\143\214\74\346\250\243\214"
+"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\233\0\0\0\0\0\0\0\300\214\0\0\0\0\0"
+"\0\0\320\11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\234\0\0\0\0\0\0\0\0\215"
+"\0\0\0\0\0\0\0\340\11\0"
+
+"iso885915\0"
+"latin9\0"
+"\0\44"
+"\124\2\160\10\0\210\0\0\0\0\0\0\0\0\0\0\0\0\0\0\244\0\0\0\0\245\0\0\0\0"
+"\171\350\361\11\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\0\0\0"
+"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+
+"iso885916\0"
+"\0\40"
+"\0\330\160\303\32\124\52\171\10\0\210\0\260\12\0\240\0\20\212\50\0\0\340\3\33"
+"\244\44\11\0\0\245\374\300\12\0\171\350\361\311\50\0\0\0\0\15\0\340\0\0\0"
+"\0\0\0\0\0\0\0\0\0\0\102\264\1\0\0\0\334\1\100\40\227\0\0\0\0\0\40\321\12\0"
+"\0\0\0\100\15\0\344\0\0\0\0\0\0\0\0\0\0\0\0\0\103\270\1\0\0\0\340\1\200\40"
+"\230\0\0\0\0\0\44\341\12\0"
+
+"cp1250\0"
+"windows1250\0"
+"\0\0"
+"\124\6\160\144\0\112\72\271\44\223\1\74\171\10\224\201\54\102\12\50"
+"\1\24\151\44\222\111\66\31\244\220\1\140\211\110\224\202\60\122\112\50"
+"\0\300\22\313\32\0\330\0\0\0\0\0\120\10\0\0\0\0\200\50\0\0\60\13\33\0\0\0\0\0"
+"\0\334\140\10\0\151\324\242\306\50\173\0\0\0\15\0\224\201\3\0\76\0\200\4\0"
+"\112\0\0\0\20\102\264\21\7\0\0\334\1\0\0\177\124\2\300\45\0\0\220\10\0"
+"\174\0\0\100\15\0\230\221\3\0\77\0\220\4\0\113\0\0\100\20\103\270\41\7\0"
+"\0\340\1\0\0\200\130\2\0\46\0\0\240\210\54"
+
+"cp1251\0"
+"windows1251\0"
+"\0\0"
+"\4\25\164\344\124\112\72\271\44\223\124\76\271\20\224\14\71\324\20\104"
+"\122\25\151\44\222\111\66\31\244\220\1\140\231\125\224\132\161\265\225\127"
+"\0\74\324\225\102\0\174\5\0\0\3\1\140\20\0\0\0\0\100\102\0\0\200\220\125"
+"\140\1\0\0\0\121\135\111\25\0\130\35\124\325\125\21\111\64\21\105"
+"\25\131\164\21\106\31\151\264\21\107\35\171\364\21\110\41\211\64\22\111"
+"\45\231\164\22\112\51\251\264\22\113\55\271\364\22\114\61\311\64\23\115"
+"\65\331\164\23\116\71\351\264\23\117\75\371\364\23\120\101\11\65\24\121"
+"\105\31\165\24\122\111\51\265\24\123\115\71\365\24\124"
+
+"cp1252\0"
+"windows1252\0"
+"\0\0"
+"\124\6\160\244\51\112\72\271\44\223\257\74\171\10\224\171\4\100\112\0"
+"\1\24\151\44\222\111\66\31\244\220\264\140\211\110\224\172\4\120\312\47"
+"\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\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"
+
+"cp1253\0"
+"windows1253\0"
+"\0\0"
+"\124\6\160\244\51\112\72\271\44\223\1\74\31\0\224\1\4\20\100\0\1\24\151\44\222"
+"\111\66\31\244\220\1\140\31\100\224\1\4\20\100\0\0\364\342\13\0\0\0\0\0\0"
+"\0\0\20\0\0\0\0\0\300\220\0\0\0\0\0\274\0\0\0\0\277\0\23\14\0\302\0\60\14\61"
+"\305\30\163\14\62\311\50\263\14\63\315\70\363\14\64\321\110\63\15\65"
+"\325\130\23\300\65\330\144\243\315\66\334\164\343\315\67\340\204\43\316\70"
+"\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73\360\304\43\317\74"
+"\364\324\143\317\75\370\344\243\317\76\374\364\343\317\77\0\5\44\120\0"
+
+"cp1254\0"
+"windows1254\0"
+"\0\0"
+"\124\6\160\244\51\112\72\271\44\223\257\74\171\10\224\171\4\20\100\0"
+"\1\24\151\44\222\111\66\31\244\220\264\140\211\110\224\172\4\20\300\47"
+"\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\116\0\0\0\0\0\0\0\0\0"
+"\0\0\0\0\0\0\170\121\10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\117\0\0\0\0"
+"\0\0\0\0\0\0\0\0\0\0\0\174\141\10\0"
+
+"cp1255\0"
+"windows1255\0"
+"\0\0"
+"\124\6\160\244\51\112\72\271\44\223\257\74\31\0\224\1\4\20\100\0"
+"\1\24\151\44\222\111\66\31\244\220\264\140\31\100\224\1\4\20\100\0\0\0\0\0\0"
+"\122\2\0\0\0\0\0\300\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\360\0\0\0\0\0\0\0"
+"\141\211\65\26\131\145\231\165\26\132\151\251\25\300\132\154\265\345\326\133"
+"\160\305\45\327\134\217\101\26\231\144\223\5\20\100\0\1\4\20\100\0"
+"\164\325\145\327\135\170\345\245\327\136\174\365\345\327\137\200\5\46\330\140"
+"\204\25\146\330\141\210\45\246\330\142\214\65\346\130\0\1\374\10\144\0"
+
+"cp1256\0"
+"windows1256\0"
+"\0\0"
+"\124\26\167\244\51\112\72\271\44\223\257\74\111\34\224\171\30\227\334\161"
+"\313\25\151\44\222\111\66\31\244\220\312\141\211\134\224\172\364\350\43\163"
+"\0\120\6\0\0\0\0\0\0\0\0\0\320\34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\120\31\0"
+"\0\0\0\200\145\316\135\206\131\146\232\155\306\131\147\236\175\6\132\150"
+"\242\215\106\132\151\246\235\206\132\152\252\255\306\32\0\255\271\366\32\154"
+"\261\311\66\33\155\0\324\6\200\155\267\341\226\33\0\0\0\0\0\0\272\355\6\0\0"
+"\274\365\346\333\157\0\0\27\34\0\302\1\60\34\0\0\374\10\344\163"
+
+"cp1257\0"
+"windows1257\0"
+"\0\0"
+"\124\6\160\144\0\112\72\271\44\223\1\74\31\0\224\1\20\0\213\2\1\24\151\44\222"
+"\111\66\31\244\220\1\140\31\100\224\1\30\60\113\0\0\4\0\0\0\0\4\0\0\0"
+"\15\0\320\7\0\0\0\0\300\2\0\0\0\0\0\0\0\0\0\0\20\0\340\7\0\0\0\0\200\3"
+"\66\160\41\3\16\0\0\200\4\21\76\0\0\212\21\122\210\241\305\31\207\264\361\6\0"
+"\165\0\0\0\0\231\254\21\110\44\0\210\102\12\0\67\164\61\103\16\0\0\220\104\21"
+"\77\0\20\312\21\123\214\261\5\32\210\270\1\7\0\166\0\0\0\0\232\260\41\210\44"
+"\0\214\122\212\54"
+
+"cp1258\0"
+"windows1258\0"
+"\0\0"
+"\124\6\160\244\51\112\72\271\44\223\257\74\31\0\224\171\4\20\100\0"
+"\1\24\151\44\222\111\66\31\244\220\264\140\31\100\224\172\4\20\300\47"
+"\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\15\0\0\0\0\0\0\0\0\0\0\266\0\0\0\0\102\0\220\13\0"
+"\0\234\2\0\0\0\0\0\0\0\0\244\202\13\0\0\0\0\100\15\0\0\0\0\0\0\0\0\0\0"
+"\267\0\0\0\0\103\0\240\13\0\0\240\2\0\0\0\0\0\0\0\0\250\62\45\0"
+
+"koi8r\0"
+"\0\0"
+"\140\206\51\346\230\144\226\151\346\231\150\246\251\46\242\211\52\272\50\243"
+"\215\72\372\250\227\220\146\251\345\226\134\166\51\300\227\7\40\220\300\3"
+"\153\262\331\146\124\156\276\11\147\234\162\316\111\147\235"
+"\166\336\211\147\236\172\356\311\347\100\175\372\371\47\240\201\12\72\50\241"
+"\205\32\172\150\1\117\305\44\323\121\65\331\124\24\115\106\345\244\323\116"
+"\74\365\344\323\117\100\101\25\224\120\103\21\165\323\114\115\61\205\123\122"
+"\116\51\205\324\122\57\105\44\321\111\25\131\124\22\105\46\145\244\321\106"
+"\34\165\344\321\107\40\301\24\222\110\43\221\164\321\104\55\261\204\121\112"
+"\56\251\204\322\112"
+
+"koi8u\0"
+"\0\0"
+"\140\206\51\346\230\144\226\151\346\231\150\246\251\46\242\211\52\272\50\243"
+"\215\72\372\250\227\220\146\251\345\226\134\166\51\300\227\7\40\220\300\3"
+"\153\262\331\146\124\124\275\151\325\125\162\316\111\147\235"
+"\166\202\205\147\236\172\356\311\347\100\6\371\211\120\102\201\12\72\50\241"
+"\205\176\165\150\1\117\305\44\323\121\65\331\124\24\115\106\345\244\323\116"
+"\74\365\344\323\117\100\101\25\224\120\103\21\165\323\114\115\61\205\123\122"
+"\116\51\205\324\122\57\105\44\321\111\25\131\124\22\105\46\145\244\321\106"
+"\34\165\344\321\107\40\301\24\222\110\43\221\164\321\104\55\261\204\121\112"
+"\56\251\204\322\112"
+
+"cp437\0"
+"\0\0"
+"\27\300\100\202\7\37\164\0\202\10\45\230\60\102\12\50\234\100\101\5"
+"\30\70\260\300\12\54\250\360\202\13\61\144\300\101\4\22\114\140\245\51"
+"\221\106\32\151\244\221\106\32\151\244\221\106\32\151\244\221\106\32\151\244"
+"\215\72\372\150\230\147\362\331\147\234\160\372\311\246\234"
+"\170\336\151\347\230\144\246\211\246\231\140\252\231\247\236"
+"\165\276\111\150\240\173\256\171\250\240\203\376\11\50\235\163\266\351\246\241"
+"\205\226\51\246\242\211\56\312\50\242\345\104\212\14\75\327\334\23\51\76"
+"\332\64\323\15\72\221\352\223\116\244\221\106\332\45\227\136\176\371\300\226"
+"\7\144\231\200\226\221\42\0\251\0"
+
+"cp850\0"
+"\0\0"
+"\27\300\100\202\7\37\164\0\202\10\45\230\60\102\12\50\234\100\101\5"
+"\30\70\260\300\12\54\250\360\202\13\61\144\300\1\4\22\64\300\200\51"
+"\221\106\32\151\244\221\106\32\151\244\221\106\32\151\244\221\106\32\151\244"
+"\215\72\372\150\230\147\106\32\151\244\5\370\311\246\234\170\106\60\301\230"
+"\144\246\211\246\231\140\252\31\151\244\165\276\111\150\240"
+"\173\256\171\150\244\221\106\32\151\244\221\176\21\151\244\221\226\51\246\242"
+"\211\106\32\51\242\221\106\32\151\244\221\106\32\151\244\221\106\32\151\244"
+"\221\106\152\100\244\221\106\112\144\244\221\16\360\200\2\7\20\220\100\244"
+"\221\42\0\251\0"
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/dcngettext.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/dcngettext.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/dcngettext.c	(revision 398)
@@ -0,0 +1,272 @@
+#include <libintl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include "locale_impl.h"
+#include "libc.h"
+#include "atomic.h"
+
+struct binding {
+	struct binding *next;
+	int dirlen;
+	volatile int active;
+	char *domainname;
+	char *dirname;
+	char buf[];
+};
+
+static void *volatile bindings;
+
+static char *gettextdir(const char *domainname, size_t *dirlen)
+{
+	struct binding *p;
+	for (p=bindings; p; p=p->next) {
+		if (!strcmp(p->domainname, domainname) && p->active) {
+			*dirlen = p->dirlen;
+			return (char *)p->dirname;
+		}
+	}
+	return 0;
+}
+
+char *bindtextdomain(const char *domainname, const char *dirname)
+{
+	static volatile int lock[2];
+	struct binding *p, *q;
+
+	if (!domainname) return 0;
+	if (!dirname) return gettextdir(domainname, &(size_t){0});
+
+	size_t domlen = strnlen(domainname, NAME_MAX+1);
+	size_t dirlen = strnlen(dirname, PATH_MAX);
+	if (domlen > NAME_MAX || dirlen >= PATH_MAX) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	LOCK(lock);
+
+	for (p=bindings; p; p=p->next) {
+		if (!strcmp(p->domainname, domainname) &&
+		    !strcmp(p->dirname, dirname)) {
+			break;
+		}
+	}
+
+	if (!p) {
+		p = calloc(sizeof *p + domlen + dirlen + 2, 1);
+		if (!p) {
+			UNLOCK(lock);
+			return 0;
+		}
+		p->next = bindings;
+		p->dirlen = dirlen;
+		p->domainname = p->buf;
+		p->dirname = p->buf + domlen + 1;
+		memcpy(p->domainname, domainname, domlen+1);
+		memcpy(p->dirname, dirname, dirlen+1);
+		a_cas_p(&bindings, bindings, p);
+	}
+
+	a_store(&p->active, 1);
+
+	for (q=bindings; q; q=q->next) {
+		if (!strcmp(q->domainname, domainname) && q != p)
+			a_store(&q->active, 0);
+	}
+
+	UNLOCK(lock);
+	
+	return (char *)p->dirname;
+}
+
+static const char catnames[][12] = {
+	"LC_CTYPE",
+	"LC_NUMERIC",
+	"LC_TIME",
+	"LC_COLLATE",
+	"LC_MONETARY",
+	"LC_MESSAGES",
+};
+
+static const char catlens[] = { 8, 10, 7, 10, 11, 11 };
+
+struct msgcat {
+	struct msgcat *next;
+	const void *map;
+	size_t map_size;
+	void *volatile plural_rule;
+	volatile int nplurals;
+	struct binding *binding;
+	const struct __locale_map *lm;
+	int cat;
+};
+
+static char *dummy_gettextdomain()
+{
+	return "messages";
+}
+
+weak_alias(dummy_gettextdomain, __gettextdomain);
+
+const unsigned char *__map_file(const char *, size_t *);
+int __munmap(void *, size_t);
+unsigned long __pleval(const char *, unsigned long);
+
+char *dcngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n, int category)
+{
+	static struct msgcat *volatile cats;
+	struct msgcat *p;
+	struct __locale_struct *loc = CURRENT_LOCALE;
+	const struct __locale_map *lm;
+	size_t domlen;
+	struct binding *q;
+
+	if ((unsigned)category >= LC_ALL) goto notrans;
+
+	if (!domainname) domainname = __gettextdomain();
+
+	domlen = strnlen(domainname, NAME_MAX+1);
+	if (domlen > NAME_MAX) goto notrans;
+
+	for (q=bindings; q; q=q->next)
+		if (!strcmp(q->domainname, domainname) && q->active)
+			break;
+	if (!q) goto notrans;
+
+	lm = loc->cat[category];
+	if (!lm) {
+notrans:
+		return (char *) ((n == 1) ? msgid1 : msgid2);
+	}
+
+	for (p=cats; p; p=p->next)
+		if (p->binding == q && p->lm == lm && p->cat == category)
+			break;
+
+	if (!p) {
+		const char *dirname, *locname, *catname, *modname, *locp;
+		size_t dirlen, loclen, catlen, modlen, alt_modlen;
+		void *old_cats;
+		size_t map_size;
+
+		dirname = q->dirname;
+		locname = lm->name;
+		catname = catnames[category];
+
+		dirlen = q->dirlen;
+		loclen = strlen(locname);
+		catlen = catlens[category];
+
+		/* Logically split @mod suffix from locale name. */
+		modname = memchr(locname, '@', loclen);
+		if (!modname) modname = locname + loclen;
+		alt_modlen = modlen = loclen - (modname-locname);
+		loclen = modname-locname;
+
+		/* Drop .charset identifier; it is not used. */
+		const char *csp = memchr(locname, '.', loclen);
+		if (csp) loclen = csp-locname;
+
+		char name[dirlen+1 + loclen+modlen+1 + catlen+1 + domlen+3 + 1];
+		const void *map;
+
+		for (;;) {
+			snprintf(name, sizeof name, "%s/%.*s%.*s/%s/%s.mo\0",
+				dirname, (int)loclen, locname,
+				(int)alt_modlen, modname, catname, domainname);
+			if (map = __map_file(name, &map_size)) break;
+
+			/* Try dropping @mod, _YY, then both. */
+			if (alt_modlen) {
+				alt_modlen = 0;
+			} else if ((locp = memchr(locname, '_', loclen))) {
+				loclen = locp-locname;
+				alt_modlen = modlen;
+			} else {
+				break;
+			}
+		}
+		if (!map) goto notrans;
+
+		p = calloc(sizeof *p, 1);
+		if (!p) {
+			__munmap((void *)map, map_size);
+			goto notrans;
+		}
+		p->cat = category;
+		p->binding = q;
+		p->lm = lm;
+		p->map = map;
+		p->map_size = map_size;
+		do {
+			old_cats = cats;
+			p->next = old_cats;
+		} while (a_cas_p(&cats, old_cats, p) != old_cats);
+	}
+
+	const char *trans = __mo_lookup(p->map, p->map_size, msgid1);
+	if (!trans) goto notrans;
+
+	/* Non-plural-processing gettext forms pass a null pointer as
+	 * msgid2 to request that dcngettext suppress plural processing. */
+	if (!msgid2) return (char *)trans;
+
+	if (!p->plural_rule) {
+		const char *rule = "n!=1;";
+		unsigned long np = 2;
+		const char *r = __mo_lookup(p->map, p->map_size, "");
+		char *z;
+		while (r && strncmp(r, "Plural-Forms:", 13)) {
+			z = strchr(r, '\n');
+			r = z ? z+1 : 0;
+		}
+		if (r) {
+			r += 13;
+			while (isspace(*r)) r++;
+			if (!strncmp(r, "nplurals=", 9)) {
+				np = strtoul(r+9, &z, 10);
+				r = z;
+			}
+			while (*r && *r != ';') r++;
+			if (*r) {
+				r++;
+				while (isspace(*r)) r++;
+				if (!strncmp(r, "plural=", 7))
+					rule = r+7;
+			}
+		}
+		a_store(&p->nplurals, np);
+		a_cas_p(&p->plural_rule, 0, (void *)rule);
+	}
+	if (p->nplurals) {
+		unsigned long plural = __pleval(p->plural_rule, n);
+		if (plural > p->nplurals) goto notrans;
+		while (plural--) {
+			size_t rem = p->map_size - (trans - (char *)p->map);
+			size_t l = strnlen(trans, rem);
+			if (l+1 >= rem)
+				goto notrans;
+			trans += l+1;
+		}
+	}
+	return (char *)trans;
+}
+
+char *dcgettext(const char *domainname, const char *msgid, int category)
+{
+	return dcngettext(domainname, msgid, 0, 1, category);
+}
+
+char *dngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n)
+{
+	return dcngettext(domainname, msgid1, msgid2, n, LC_MESSAGES);
+}
+
+char *dgettext(const char *domainname, const char *msgid)
+{
+	return dcngettext(domainname, msgid, 0, 1, LC_MESSAGES);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/duplocale.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/duplocale.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/duplocale.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <string.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+locale_t __duplocale(locale_t old)
+{
+	locale_t new = malloc(sizeof *new);
+	if (!new) return 0;
+	if (old == LC_GLOBAL_LOCALE) old = &libc.global_locale;
+	*new = *old;
+	return new;
+}
+
+weak_alias(__duplocale, duplocale);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/freelocale.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/freelocale.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/freelocale.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+int __loc_is_allocated(locale_t);
+
+void freelocale(locale_t l)
+{
+	if (__loc_is_allocated(l)) free(l);
+}
+
+weak_alias(freelocale, __freelocale);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/gb18030.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/gb18030.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/gb18030.h	(revision 398)
@@ -0,0 +1,1836 @@
+19970,19972,19973,19974,19983,19986,19991,19999,20000,20001,20003,20006,20009,
+20014,20015,20017,20019,20021,20023,20028,20032,20033,20034,20036,20038,20042,
+20049,20053,20055,20058,20059,20066,20067,20068,20069,20071,20072,20074,20075,
+20076,20077,20078,20079,20082,20084,20085,20086,20087,20088,20089,20090,20091,
+20092,20093,20095,20096,20097,20098,20099,20100,20101,20103,20106,20112,20118,
+20119,20121,20124,20125,20126,20131,20138,20143,20144,20145,20148,20150,20151,
+20152,20153,20156,20157,20158,20168,20172,20175,20176,20178,20186,20187,20188,
+20192,20194,20198,20199,20201,20205,20206,20207,20209,20212,20216,20217,20218,
+20220,20222,20224,20226,20227,20228,20229,20230,20231,20232,20235,20236,20242,
+20243,20244,20245,20246,20252,20253,20257,20259,20264,20265,20268,20269,20270,
+20273,20275,20277,20279,20281,20283,20286,20287,20288,20289,20290,20292,20293,
+20295,20296,20297,20298,20299,20300,20306,20308,20310,20321,20322,20326,20328,
+20330,20331,20333,20334,20337,20338,20341,20343,20344,20345,20346,20349,20352,
+20353,20354,20357,20358,20359,20362,20364,20366,20368,20370,20371,20373,20374,
+20376,20377,20378,20380,20382,20383,20385,20386,20388,20395,20397,20400,20401,
+20402,20403,20404,20406,20407,20408,20409,20410,20411,20412,20413,20414,20416,
+20417,20418,20422,20423,20424,20425,20427,20428,20429,20434,20435,20436,20437,
+20438,20441,20443,20448,20450,20452,20453,20455,20459,20460,20464,20466,20468,
+20469,20470,20471,20473,20475,20476,20477,20479,20480,20481,20482,20483,20484,
+20485,20486,20487,20488,20489,20490,20491,20494,20496,20497,20499,20501,20502,
+20503,20507,20509,20510,20512,20514,20515,20516,20519,20523,20527,20528,20529,
+20530,20531,20532,20533,20534,20535,20536,20537,20539,20541,20543,20544,20545,
+20546,20548,20549,20550,20553,20554,20555,20557,20560,20561,20562,20563,20564,
+20566,20567,20568,20569,20571,20573,20574,20575,20576,20577,20578,20579,20580,
+20582,20583,20584,20585,20586,20587,20589,20590,20591,20592,20593,20594,20595,
+20596,20597,20600,20601,20602,20604,20605,20609,20610,20611,20612,20614,20615,
+20617,20618,20619,20620,20622,20623,20624,20625,20626,20627,20628,20629,20630,
+20631,20632,20633,20634,20635,20636,20637,20638,20639,20640,20641,20642,20644,
+20646,20650,20651,20653,20654,20655,20656,20657,20659,20660,20661,20662,20663,
+20664,20665,20668,20669,20670,20671,20672,20673,20674,20675,20676,20677,20678,
+20679,20680,20681,20682,20683,20684,20685,20686,20688,20689,20690,20691,20692,
+20693,20695,20696,20697,20699,20700,20701,20702,20703,20704,20705,20706,20707,
+20708,20709,20712,20713,20714,20715,20719,20720,20721,20722,20724,20726,20727,
+20728,20729,20730,20732,20733,20734,20735,20736,20737,20738,20739,20740,20741,
+20744,20745,20746,20748,20749,20750,20751,20752,20753,20755,20756,20757,20758,
+20759,20760,20761,20762,20763,20764,20765,20766,20767,20768,20770,20771,20772,
+20773,20774,20775,20776,20777,20778,20779,20780,20781,20782,20783,20784,20785,
+20786,20787,20788,20789,20790,20791,20792,20793,20794,20795,20796,20797,20798,
+20802,20807,20810,20812,20814,20815,20816,20818,20819,20823,20824,20825,20827,
+20829,20830,20831,20832,20833,20835,20836,20838,20839,20841,20842,20847,20850,
+20858,20862,20863,20867,20868,20870,20871,20874,20875,20878,20879,20880,20881,
+20883,20884,20888,20890,20893,20894,20895,20897,20899,20902,20903,20904,20905,
+20906,20909,20910,20916,20920,20921,20922,20926,20927,20929,20930,20931,20933,
+20936,20938,20941,20942,20944,20946,20947,20948,20949,20950,20951,20952,20953,
+20954,20956,20958,20959,20962,20963,20965,20966,20967,20968,20969,20970,20972,
+20974,20977,20978,20980,20983,20990,20996,20997,21001,21003,21004,21007,21008,
+21011,21012,21013,21020,21022,21023,21025,21026,21027,21029,21030,21031,21034,
+21036,21039,21041,21042,21044,21045,21052,21054,21060,21061,21062,21063,21064,
+21065,21067,21070,21071,21074,21075,21077,21079,21080,21081,21082,21083,21085,
+21087,21088,21090,21091,21092,21094,21096,21099,21100,21101,21102,21104,21105,
+21107,21108,21109,21110,21111,21112,21113,21114,21115,21116,21118,21120,21123,
+21124,21125,21126,21127,21129,21130,21131,21132,21133,21134,21135,21137,21138,
+21140,21141,21142,21143,21144,21145,21146,21148,21156,21157,21158,21159,21166,
+21167,21168,21172,21173,21174,21175,21176,21177,21178,21179,21180,21181,21184,
+21185,21186,21188,21189,21190,21192,21194,21196,21197,21198,21199,21201,21203,
+21204,21205,21207,21209,21210,21211,21212,21213,21214,21216,21217,21218,21219,
+21221,21222,21223,21224,21225,21226,21227,21228,21229,21230,21231,21233,21234,
+21235,21236,21237,21238,21239,21240,21243,21244,21245,21249,21250,21251,21252,
+21255,21257,21258,21259,21260,21262,21265,21266,21267,21268,21272,21275,21276,
+21278,21279,21282,21284,21285,21287,21288,21289,21291,21292,21293,21295,21296,
+21297,21298,21299,21300,21301,21302,21303,21304,21308,21309,21312,21314,21316,
+21318,21323,21324,21325,21328,21332,21336,21337,21339,21341,21349,21352,21354,
+21356,21357,21362,21366,21369,21371,21372,21373,21374,21376,21377,21379,21383,
+21384,21386,21390,21391,21392,21393,21394,21395,21396,21398,21399,21401,21403,
+21404,21406,21408,21409,21412,21415,21418,21419,21420,21421,21423,21424,21425,
+21426,21427,21428,21429,21431,21432,21433,21434,21436,21437,21438,21440,21443,
+21444,21445,21446,21447,21454,21455,21456,21458,21459,21461,21466,21468,21469,
+21470,21473,21474,21479,21492,21498,21502,21503,21504,21506,21509,21511,21515,
+21524,21528,21529,21530,21532,21538,21540,21541,21546,21552,21555,21558,21559,
+21562,21565,21567,21569,21570,21572,21573,21575,21577,21580,21581,21582,21583,
+21585,21594,21597,21598,21599,21600,21601,21603,21605,21607,21609,21610,21611,
+21612,21613,21614,21615,21616,21620,21625,21626,21630,21631,21633,21635,21637,
+21639,21640,21641,21642,21645,21649,21651,21655,21656,21660,21662,21663,21664,
+21665,21666,21669,21678,21680,21682,21685,21686,21687,21689,21690,21692,21694,
+21699,21701,21706,21707,21718,21720,21723,21728,21729,21730,21731,21732,21739,
+21740,21743,21744,21745,21748,21749,21750,21751,21752,21753,21755,21758,21760,
+21762,21763,21764,21765,21768,21770,21771,21772,21773,21774,21778,21779,21781,
+21782,21783,21784,21785,21786,21788,21789,21790,21791,21793,21797,21798,21800,
+21801,21803,21805,21810,21812,21813,21814,21816,21817,21818,21819,21821,21824,
+21826,21829,21831,21832,21835,21836,21837,21838,21839,21841,21842,21843,21844,
+21847,21848,21849,21850,21851,21853,21854,21855,21856,21858,21859,21864,21865,
+21867,21871,21872,21873,21874,21875,21876,21881,21882,21885,21887,21893,21894,
+21900,21901,21902,21904,21906,21907,21909,21910,21911,21914,21915,21918,21920,
+21921,21922,21923,21924,21925,21926,21928,21929,21930,21931,21932,21933,21934,
+21935,21936,21938,21940,21942,21944,21946,21948,21951,21952,21953,21954,21955,
+21958,21959,21960,21962,21963,21966,21967,21968,21973,21975,21976,21977,21978,
+21979,21982,21984,21986,21991,21993,21997,21998,22000,22001,22004,22006,22008,
+22009,22010,22011,22012,22015,22018,22019,22020,22021,22022,22023,22026,22027,
+22029,22032,22033,22034,22035,22036,22037,22038,22039,22041,22042,22044,22045,
+22048,22049,22050,22053,22054,22056,22057,22058,22059,22062,22063,22064,22067,
+22069,22071,22072,22074,22076,22077,22078,22080,22081,22082,22083,22084,22085,
+22086,22087,22088,22089,22090,22091,22095,22096,22097,22098,22099,22101,22102,
+22106,22107,22109,22110,22111,22112,22113,22115,22117,22118,22119,22125,22126,
+22127,22128,22130,22131,22132,22133,22135,22136,22137,22138,22141,22142,22143,
+22144,22145,22146,22147,22148,22151,22152,22153,22154,22155,22156,22157,22160,
+22161,22162,22164,22165,22166,22167,22168,22169,22170,22171,22172,22173,22174,
+22175,22176,22177,22178,22180,22181,22182,22183,22184,22185,22186,22187,22188,
+22189,22190,22192,22193,22194,22195,22196,22197,22198,22200,22201,22202,22203,
+22205,22206,22207,22208,22209,22210,22211,22212,22213,22214,22215,22216,22217,
+22219,22220,22221,22222,22223,22224,22225,22226,22227,22229,22230,22232,22233,
+22236,22243,22245,22246,22247,22248,22249,22250,22252,22254,22255,22258,22259,
+22262,22263,22264,22267,22268,22272,22273,22274,22277,22279,22283,22284,22285,
+22286,22287,22288,22289,22290,22291,22292,22293,22294,22295,22296,22297,22298,
+22299,22301,22302,22304,22305,22306,22308,22309,22310,22311,22315,22321,22322,
+22324,22325,22326,22327,22328,22332,22333,22335,22337,22339,22340,22341,22342,
+22344,22345,22347,22354,22355,22356,22357,22358,22360,22361,22370,22371,22373,
+22375,22380,22382,22384,22385,22386,22388,22389,22392,22393,22394,22397,22398,
+22399,22400,22401,22407,22408,22409,22410,22413,22414,22415,22416,22417,22420,
+22421,22422,22423,22424,22425,22426,22428,22429,22430,22431,22437,22440,22442,
+22444,22447,22448,22449,22451,22453,22454,22455,22457,22458,22459,22460,22461,
+22462,22463,22464,22465,22468,22469,22470,22471,22472,22473,22474,22476,22477,
+22480,22481,22483,22486,22487,22491,22492,22494,22497,22498,22499,22501,22502,
+22503,22504,22505,22506,22507,22508,22510,22512,22513,22514,22515,22517,22518,
+22519,22523,22524,22526,22527,22529,22531,22532,22533,22536,22537,22538,22540,
+22542,22543,22544,22546,22547,22548,22550,22551,22552,22554,22555,22556,22557,
+22559,22562,22563,22565,22566,22567,22568,22569,22571,22572,22573,22574,22575,
+22577,22578,22579,22580,22582,22583,22584,22585,22586,22587,22588,22589,22590,
+22591,22592,22593,22594,22595,22597,22598,22599,22600,22601,22602,22603,22606,
+22607,22608,22610,22611,22613,22614,22615,22617,22618,22619,22620,22621,22623,
+22624,22625,22626,22627,22628,22630,22631,22632,22633,22634,22637,22638,22639,
+22640,22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,22652,
+22653,22655,22658,22660,22662,22663,22664,22666,22667,22668,22669,22670,22671,
+22672,22673,22676,22677,22678,22679,22680,22683,22684,22685,22688,22689,22690,
+22691,22692,22693,22694,22695,22698,22699,22700,22701,22702,22703,22704,22705,
+22706,22707,22708,22709,22710,22711,22712,22713,22714,22715,22717,22718,22719,
+22720,22722,22723,22724,22726,22727,22728,22729,22730,22731,22732,22733,22734,
+22735,22736,22738,22739,22740,22742,22743,22744,22745,22746,22747,22748,22749,
+22750,22751,22752,22753,22754,22755,22757,22758,22759,22760,22761,22762,22765,
+22767,22769,22770,22772,22773,22775,22776,22778,22779,22780,22781,22782,22783,
+22784,22785,22787,22789,22790,22792,22793,22794,22795,22796,22798,22800,22801,
+22802,22803,22807,22808,22811,22813,22814,22816,22817,22818,22819,22822,22824,
+22828,22832,22834,22835,22837,22838,22843,22845,22846,22847,22848,22851,22853,
+22854,22858,22860,22861,22864,22866,22867,22873,22875,22876,22877,22878,22879,
+22881,22883,22884,22886,22887,22888,22889,22890,22891,22892,22893,22894,22895,
+22896,22897,22898,22901,22903,22906,22907,22908,22910,22911,22912,22917,22921,
+22923,22924,22926,22927,22928,22929,22932,22933,22936,22938,22939,22940,22941,
+22943,22944,22945,22946,22950,22951,22956,22957,22960,22961,22963,22964,22965,
+22966,22967,22968,22970,22972,22973,22975,22976,22977,22978,22979,22980,22981,
+22983,22984,22985,22988,22989,22990,22991,22997,22998,23001,23003,23006,23007,
+23008,23009,23010,23012,23014,23015,23017,23018,23019,23021,23022,23023,23024,
+23025,23026,23027,23028,23029,23030,23031,23032,23034,23036,23037,23038,23040,
+23042,23050,23051,23053,23054,23055,23056,23058,23060,23061,23062,23063,23065,
+23066,23067,23069,23070,23073,23074,23076,23078,23079,23080,23082,23083,23084,
+23085,23086,23087,23088,23091,23093,23095,23096,23097,23098,23099,23101,23102,
+23103,23105,23106,23107,23108,23109,23111,23112,23115,23116,23117,23118,23119,
+23120,23121,23122,23123,23124,23126,23127,23128,23129,23131,23132,23133,23134,
+23135,23136,23137,23139,23140,23141,23142,23144,23145,23147,23148,23149,23150,
+23151,23152,23153,23154,23155,23160,23161,23163,23164,23165,23166,23168,23169,
+23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,23180,23181,23182,
+23183,23184,23185,23187,23188,23189,23190,23191,23192,23193,23196,23197,23198,
+23199,23200,23201,23202,23203,23204,23205,23206,23207,23208,23209,23211,23212,
+23213,23214,23215,23216,23217,23220,23222,23223,23225,23226,23227,23228,23229,
+23231,23232,23235,23236,23237,23238,23239,23240,23242,23243,23245,23246,23247,
+23248,23249,23251,23253,23255,23257,23258,23259,23261,23262,23263,23266,23268,
+23269,23271,23272,23274,23276,23277,23278,23279,23280,23282,23283,23284,23285,
+23286,23287,23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,
+23299,23300,23301,23302,23303,23304,23306,23307,23308,23309,23310,23311,23312,
+23313,23314,23315,23316,23317,23320,23321,23322,23323,23324,23325,23326,23327,
+23328,23329,23330,23331,23332,23333,23334,23335,23336,23337,23338,23339,23340,
+23341,23342,23343,23344,23345,23347,23349,23350,23352,23353,23354,23355,23356,
+23357,23358,23359,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,
+23371,23372,23373,23374,23375,23378,23382,23390,23392,23393,23399,23400,23403,
+23405,23406,23407,23410,23412,23414,23415,23416,23417,23419,23420,23422,23423,
+23426,23430,23434,23437,23438,23440,23441,23442,23444,23446,23455,23463,23464,
+23465,23468,23469,23470,23471,23473,23474,23479,23482,23483,23484,23488,23489,
+23491,23496,23497,23498,23499,23501,23502,23503,23505,23508,23509,23510,23511,
+23512,23513,23514,23515,23516,23520,23522,23523,23526,23527,23529,23530,23531,
+23532,23533,23535,23537,23538,23539,23540,23541,23542,23543,23549,23550,23552,
+23554,23555,23557,23559,23560,23563,23564,23565,23566,23568,23570,23571,23575,
+23577,23579,23582,23583,23584,23585,23587,23590,23592,23593,23594,23595,23597,
+23598,23599,23600,23602,23603,23605,23606,23607,23619,23620,23622,23623,23628,
+23629,23634,23635,23636,23638,23639,23640,23642,23643,23644,23645,23647,23650,
+23652,23655,23656,23657,23658,23659,23660,23661,23664,23666,23667,23668,23669,
+23670,23671,23672,23675,23676,23677,23678,23680,23683,23684,23685,23686,23687,
+23689,23690,23691,23694,23695,23698,23699,23701,23709,23710,23711,23712,23713,
+23716,23717,23718,23719,23720,23722,23726,23727,23728,23730,23732,23734,23737,
+23738,23739,23740,23742,23744,23746,23747,23749,23750,23751,23752,23753,23754,
+23756,23757,23758,23759,23760,23761,23763,23764,23765,23766,23767,23768,23770,
+23771,23772,23773,23774,23775,23776,23778,23779,23783,23785,23787,23788,23790,
+23791,23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23804,23805,
+23806,23807,23808,23809,23812,23813,23816,23817,23818,23819,23820,23821,23823,
+23824,23825,23826,23827,23829,23831,23832,23833,23834,23836,23837,23839,23840,
+23841,23842,23843,23845,23848,23850,23851,23852,23855,23856,23857,23858,23859,
+23861,23862,23863,23864,23865,23866,23867,23868,23871,23872,23873,23874,23875,
+23876,23877,23878,23880,23881,23885,23886,23887,23888,23889,23890,23891,23892,
+23893,23894,23895,23897,23898,23900,23902,23903,23904,23905,23906,23907,23908,
+23909,23910,23911,23912,23914,23917,23918,23920,23921,23922,23923,23925,23926,
+23927,23928,23929,23930,23931,23932,23933,23934,23935,23936,23937,23939,23940,
+23941,23942,23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953,
+23954,23955,23956,23957,23958,23959,23960,23962,23963,23964,23966,23967,23968,
+23969,23970,23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,
+23982,23983,23984,23985,23986,23987,23988,23989,23990,23992,23993,23994,23995,
+23996,23997,23998,23999,24000,24001,24002,24003,24004,24006,24007,24008,24009,
+24010,24011,24012,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023,
+24024,24025,24026,24028,24031,24032,24035,24036,24042,24044,24045,24048,24053,
+24054,24056,24057,24058,24059,24060,24063,24064,24068,24071,24073,24074,24075,
+24077,24078,24082,24083,24087,24094,24095,24096,24097,24098,24099,24100,24101,
+24104,24105,24106,24107,24108,24111,24112,24114,24115,24116,24117,24118,24121,
+24122,24126,24127,24128,24129,24131,24134,24135,24136,24137,24138,24139,24141,
+24142,24143,24144,24145,24146,24147,24150,24151,24152,24153,24154,24156,24157,
+24159,24160,24163,24164,24165,24166,24167,24168,24169,24170,24171,24172,24173,
+24174,24175,24176,24177,24181,24183,24185,24190,24193,24194,24195,24197,24200,
+24201,24204,24205,24206,24210,24216,24219,24221,24225,24226,24227,24228,24232,
+24233,24234,24235,24236,24238,24239,24240,24241,24242,24244,24250,24251,24252,
+24253,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,24267,24268,
+24269,24270,24271,24272,24276,24277,24279,24280,24281,24282,24284,24285,24286,
+24287,24288,24289,24290,24291,24292,24293,24294,24295,24297,24299,24300,24301,
+24302,24303,24304,24305,24306,24307,24309,24312,24313,24315,24316,24317,24325,
+24326,24327,24329,24332,24333,24334,24336,24338,24340,24342,24345,24346,24348,
+24349,24350,24353,24354,24355,24356,24360,24363,24364,24366,24368,24370,24371,
+24372,24373,24374,24375,24376,24379,24381,24382,24383,24385,24386,24387,24388,
+24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399,24401,24404,
+24409,24410,24411,24412,24414,24415,24416,24419,24421,24423,24424,24427,24430,
+24431,24434,24436,24437,24438,24440,24442,24445,24446,24447,24451,24454,24461,
+24462,24463,24465,24467,24468,24470,24474,24475,24477,24478,24479,24480,24482,
+24483,24484,24485,24486,24487,24489,24491,24492,24495,24496,24497,24498,24499,
+24500,24502,24504,24505,24506,24507,24510,24511,24512,24513,24514,24519,24520,
+24522,24523,24526,24531,24532,24533,24538,24539,24540,24542,24543,24546,24547,
+24549,24550,24552,24553,24556,24559,24560,24562,24563,24564,24566,24567,24569,
+24570,24572,24583,24584,24585,24587,24588,24592,24593,24595,24599,24600,24602,
+24606,24607,24610,24611,24612,24620,24621,24622,24624,24625,24626,24627,24628,
+24630,24631,24632,24633,24634,24637,24638,24640,24644,24645,24646,24647,24648,
+24649,24650,24652,24654,24655,24657,24659,24660,24662,24663,24664,24667,24668,
+24670,24671,24672,24673,24677,24678,24686,24689,24690,24692,24693,24695,24702,
+24704,24705,24706,24709,24710,24711,24712,24714,24715,24718,24719,24720,24721,
+24723,24725,24727,24728,24729,24732,24734,24737,24738,24740,24741,24743,24745,
+24746,24750,24752,24755,24757,24758,24759,24761,24762,24765,24766,24767,24768,
+24769,24770,24771,24772,24775,24776,24777,24780,24781,24782,24783,24784,24786,
+24787,24788,24790,24791,24793,24795,24798,24801,24802,24803,24804,24805,24810,
+24817,24818,24821,24823,24824,24827,24828,24829,24830,24831,24834,24835,24836,
+24837,24839,24842,24843,24844,24848,24849,24850,24851,24852,24854,24855,24856,
+24857,24859,24860,24861,24862,24865,24866,24869,24872,24873,24874,24876,24877,
+24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,24888,24889,24890,
+24891,24892,24893,24894,24896,24897,24898,24899,24900,24901,24902,24903,24905,
+24907,24909,24911,24912,24914,24915,24916,24918,24919,24920,24921,24922,24923,
+24924,24926,24927,24928,24929,24931,24932,24933,24934,24937,24938,24939,24940,
+24941,24942,24943,24945,24946,24947,24948,24950,24952,24953,24954,24955,24956,
+24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,
+24970,24972,24973,24975,24976,24977,24978,24979,24981,24982,24983,24984,24985,
+24986,24987,24988,24990,24991,24992,24993,24994,24995,24996,24997,24998,25002,
+25003,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25016,25017,
+25018,25019,25020,25021,25023,25024,25025,25027,25028,25029,25030,25031,25033,
+25036,25037,25038,25039,25040,25043,25045,25046,25047,25048,25049,25050,25051,
+25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25063,25064,25065,
+25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25078,25079,
+25080,25081,25082,25083,25084,25085,25086,25088,25089,25090,25091,25092,25093,
+25095,25097,25107,25108,25113,25116,25117,25118,25120,25123,25126,25127,25128,
+25129,25131,25133,25135,25136,25137,25138,25141,25142,25144,25145,25146,25147,
+25148,25154,25156,25157,25158,25162,25167,25168,25173,25174,25175,25177,25178,
+25180,25181,25182,25183,25184,25185,25186,25188,25189,25192,25201,25202,25204,
+25205,25207,25208,25210,25211,25213,25217,25218,25219,25221,25222,25223,25224,
+25227,25228,25229,25230,25231,25232,25236,25241,25244,25245,25246,25251,25254,
+25255,25257,25258,25261,25262,25263,25264,25266,25267,25268,25270,25271,25272,
+25274,25278,25280,25281,25283,25291,25295,25297,25301,25309,25310,25312,25313,
+25316,25322,25323,25328,25330,25333,25336,25337,25338,25339,25344,25347,25348,
+25349,25350,25354,25355,25356,25357,25359,25360,25362,25363,25364,25365,25367,
+25368,25369,25372,25382,25383,25385,25388,25389,25390,25392,25393,25395,25396,
+25397,25398,25399,25400,25403,25404,25406,25407,25408,25409,25412,25415,25416,
+25418,25425,25426,25427,25428,25430,25431,25432,25433,25434,25435,25436,25437,
+25440,25444,25445,25446,25448,25450,25451,25452,25455,25456,25458,25459,25460,
+25461,25464,25465,25468,25469,25470,25471,25473,25475,25476,25477,25478,25483,
+25485,25489,25491,25492,25493,25495,25497,25498,25499,25500,25501,25502,25503,
+25505,25508,25510,25515,25519,25521,25522,25525,25526,25529,25531,25533,25535,
+25536,25537,25538,25539,25541,25543,25544,25546,25547,25548,25553,25555,25556,
+25557,25559,25560,25561,25562,25563,25564,25565,25567,25570,25572,25573,25574,
+25575,25576,25579,25580,25582,25583,25584,25585,25587,25589,25591,25593,25594,
+25595,25596,25598,25603,25604,25606,25607,25608,25609,25610,25613,25614,25617,
+25618,25621,25622,25623,25624,25625,25626,25629,25631,25634,25635,25636,25637,
+25639,25640,25641,25643,25646,25647,25648,25649,25650,25651,25653,25654,25655,
+25656,25657,25659,25660,25662,25664,25666,25667,25673,25675,25676,25677,25678,
+25679,25680,25681,25683,25685,25686,25687,25689,25690,25691,25692,25693,25695,
+25696,25697,25698,25699,25700,25701,25702,25704,25706,25707,25708,25710,25711,
+25712,25713,25714,25715,25716,25717,25718,25719,25723,25724,25725,25726,25727,
+25728,25729,25731,25734,25736,25737,25738,25739,25740,25741,25742,25743,25744,
+25747,25748,25751,25752,25754,25755,25756,25757,25759,25760,25761,25762,25763,
+25765,25766,25767,25768,25770,25771,25775,25777,25778,25779,25780,25782,25785,
+25787,25789,25790,25791,25793,25795,25796,25798,25799,25800,25801,25802,25803,
+25804,25807,25809,25811,25812,25813,25814,25817,25818,25819,25820,25821,25823,
+25824,25825,25827,25829,25831,25832,25833,25834,25835,25836,25837,25838,25839,
+25840,25841,25842,25843,25844,25845,25846,25847,25848,25849,25850,25851,25852,
+25853,25854,25855,25857,25858,25859,25860,25861,25862,25863,25864,25866,25867,
+25868,25869,25870,25871,25872,25873,25875,25876,25877,25878,25879,25881,25882,
+25883,25884,25885,25886,25887,25888,25889,25890,25891,25892,25894,25895,25896,
+25897,25898,25900,25901,25904,25905,25906,25907,25911,25914,25916,25917,25920,
+25921,25922,25923,25924,25926,25927,25930,25931,25933,25934,25936,25938,25939,
+25940,25943,25944,25946,25948,25951,25952,25953,25956,25957,25959,25960,25961,
+25962,25965,25966,25967,25969,25971,25973,25974,25976,25977,25978,25979,25980,
+25981,25982,25983,25984,25985,25986,25987,25988,25989,25990,25992,25993,25994,
+25997,25998,25999,26002,26004,26005,26006,26008,26010,26013,26014,26016,26018,
+26019,26022,26024,26026,26028,26030,26033,26034,26035,26036,26037,26038,26039,
+26040,26042,26043,26046,26047,26048,26050,26055,26056,26057,26058,26061,26064,
+26065,26067,26068,26069,26072,26073,26074,26075,26076,26077,26078,26079,26081,
+26083,26084,26090,26091,26098,26099,26100,26101,26104,26105,26107,26108,26109,
+26110,26111,26113,26116,26117,26119,26120,26121,26123,26125,26128,26129,26130,
+26134,26135,26136,26138,26139,26140,26142,26145,26146,26147,26148,26150,26153,
+26154,26155,26156,26158,26160,26162,26163,26167,26168,26169,26170,26171,26173,
+26175,26176,26178,26180,26181,26182,26183,26184,26185,26186,26189,26190,26192,
+26193,26200,26201,26203,26204,26205,26206,26208,26210,26211,26213,26215,26217,
+26218,26219,26220,26221,26225,26226,26227,26229,26232,26233,26235,26236,26237,
+26239,26240,26241,26243,26245,26246,26248,26249,26250,26251,26253,26254,26255,
+26256,26258,26259,26260,26261,26264,26265,26266,26267,26268,26270,26271,26272,
+26273,26274,26275,26276,26277,26278,26281,26282,26283,26284,26285,26287,26288,
+26289,26290,26291,26293,26294,26295,26296,26298,26299,26300,26301,26303,26304,
+26305,26306,26307,26308,26309,26310,26311,26312,26313,26314,26315,26316,26317,
+26318,26319,26320,26321,26322,26323,26324,26325,26326,26327,26328,26330,26334,
+26335,26336,26337,26338,26339,26340,26341,26343,26344,26346,26347,26348,26349,
+26350,26351,26353,26357,26358,26360,26362,26363,26365,26369,26370,26371,26372,
+26373,26374,26375,26380,26382,26383,26385,26386,26387,26390,26392,26393,26394,
+26396,26398,26400,26401,26402,26403,26404,26405,26407,26409,26414,26416,26418,
+26419,26422,26423,26424,26425,26427,26428,26430,26431,26433,26436,26437,26439,
+26442,26443,26445,26450,26452,26453,26455,26456,26457,26458,26459,26461,26466,
+26467,26468,26470,26471,26475,26476,26478,26481,26484,26486,26488,26489,26490,
+26491,26493,26496,26498,26499,26501,26502,26504,26506,26508,26509,26510,26511,
+26513,26514,26515,26516,26518,26521,26523,26527,26528,26529,26532,26534,26537,
+26540,26542,26545,26546,26548,26553,26554,26555,26556,26557,26558,26559,26560,
+26562,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26581,26582,
+26583,26587,26591,26593,26595,26596,26598,26599,26600,26602,26603,26605,26606,
+26610,26613,26614,26615,26616,26617,26618,26619,26620,26622,26625,26626,26627,
+26628,26630,26637,26640,26642,26644,26645,26648,26649,26650,26651,26652,26654,
+26655,26656,26658,26659,26660,26661,26662,26663,26664,26667,26668,26669,26670,
+26671,26672,26673,26676,26677,26678,26682,26683,26687,26695,26699,26701,26703,
+26706,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,26730,26732,
+26733,26734,26735,26736,26737,26738,26739,26741,26744,26745,26746,26747,26748,
+26749,26750,26751,26752,26754,26756,26759,26760,26761,26762,26763,26764,26765,
+26766,26768,26769,26770,26772,26773,26774,26776,26777,26778,26779,26780,26781,
+26782,26783,26784,26785,26787,26788,26789,26793,26794,26795,26796,26798,26801,
+26802,26804,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,26817,
+26819,26820,26821,26822,26823,26824,26826,26828,26830,26831,26832,26833,26835,
+26836,26838,26839,26841,26843,26844,26845,26846,26847,26849,26850,26852,26853,
+26854,26855,26856,26857,26858,26859,26860,26861,26863,26866,26867,26868,26870,
+26871,26872,26875,26877,26878,26879,26880,26882,26883,26884,26886,26887,26888,
+26889,26890,26892,26895,26897,26899,26900,26901,26902,26903,26904,26905,26906,
+26907,26908,26909,26910,26913,26914,26915,26917,26918,26919,26920,26921,26922,
+26923,26924,26926,26927,26929,26930,26931,26933,26934,26935,26936,26938,26939,
+26940,26942,26944,26945,26947,26948,26949,26950,26951,26952,26953,26954,26955,
+26956,26957,26958,26959,26960,26961,26962,26963,26965,26966,26968,26969,26971,
+26972,26975,26977,26978,26980,26981,26983,26984,26985,26986,26988,26989,26991,
+26992,26994,26995,26996,26997,26998,27002,27003,27005,27006,27007,27009,27011,
+27013,27018,27019,27020,27022,27023,27024,27025,27026,27027,27030,27031,27033,
+27034,27037,27038,27039,27040,27041,27042,27043,27044,27045,27046,27049,27050,
+27052,27054,27055,27056,27058,27059,27061,27062,27064,27065,27066,27068,27069,
+27070,27071,27072,27074,27075,27076,27077,27078,27079,27080,27081,27083,27085,
+27087,27089,27090,27091,27093,27094,27095,27096,27097,27098,27100,27101,27102,
+27105,27106,27107,27108,27109,27110,27111,27112,27113,27114,27115,27116,27118,
+27119,27120,27121,27123,27124,27125,27126,27127,27128,27129,27130,27131,27132,
+27134,27136,27137,27138,27139,27140,27141,27142,27143,27144,27145,27147,27148,
+27149,27150,27151,27152,27153,27154,27155,27156,27157,27158,27161,27162,27163,
+27164,27165,27166,27168,27170,27171,27172,27173,27174,27175,27177,27179,27180,
+27181,27182,27184,27186,27187,27188,27190,27191,27192,27193,27194,27195,27196,
+27199,27200,27201,27202,27203,27205,27206,27208,27209,27210,27211,27212,27213,
+27214,27215,27217,27218,27219,27220,27221,27222,27223,27226,27228,27229,27230,
+27231,27232,27234,27235,27236,27238,27239,27240,27241,27242,27243,27244,27245,
+27246,27247,27248,27250,27251,27252,27253,27254,27255,27256,27258,27259,27261,
+27262,27263,27265,27266,27267,27269,27270,27271,27272,27273,27274,27275,27276,
+27277,27279,27282,27283,27284,27285,27286,27288,27289,27290,27291,27292,27293,
+27294,27295,27297,27298,27299,27300,27301,27302,27303,27304,27306,27309,27310,
+27311,27312,27313,27314,27315,27316,27317,27318,27319,27320,27321,27322,27323,
+27324,27325,27326,27327,27328,27329,27330,27331,27332,27333,27334,27335,27336,
+27337,27338,27339,27340,27341,27342,27343,27344,27345,27346,27347,27348,27349,
+27350,27351,27352,27353,27354,27355,27356,27357,27358,27359,27360,27361,27362,
+27363,27364,27365,27366,27367,27368,27369,27370,27371,27372,27373,27374,27375,
+27376,27377,27378,27379,27380,27381,27382,27383,27384,27385,27386,27387,27388,
+27389,27390,27391,27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,
+27402,27403,27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,
+27415,27416,27417,27418,27419,27420,27421,27422,27423,27429,27430,27432,27433,
+27434,27435,27436,27437,27438,27439,27440,27441,27443,27444,27445,27446,27448,
+27451,27452,27453,27455,27456,27457,27458,27460,27461,27464,27466,27467,27469,
+27470,27471,27472,27473,27474,27475,27476,27477,27478,27479,27480,27482,27483,
+27484,27485,27486,27487,27488,27489,27496,27497,27499,27500,27501,27502,27503,
+27504,27505,27506,27507,27508,27509,27510,27511,27512,27514,27517,27518,27519,
+27520,27525,27528,27532,27534,27535,27536,27537,27540,27541,27543,27544,27545,
+27548,27549,27550,27551,27552,27554,27555,27556,27557,27558,27559,27560,27561,
+27563,27564,27565,27566,27567,27568,27569,27570,27574,27576,27577,27578,27579,
+27580,27581,27582,27584,27587,27588,27590,27591,27592,27593,27594,27596,27598,
+27600,27601,27608,27610,27612,27613,27614,27615,27616,27618,27619,27620,27621,
+27622,27623,27624,27625,27628,27629,27630,27632,27633,27634,27636,27638,27639,
+27640,27642,27643,27644,27646,27647,27648,27649,27650,27651,27652,27656,27657,
+27658,27659,27660,27662,27666,27671,27676,27677,27678,27680,27683,27685,27691,
+27692,27693,27697,27699,27702,27703,27705,27706,27707,27708,27710,27711,27715,
+27716,27717,27720,27723,27724,27725,27726,27727,27729,27730,27731,27734,27736,
+27737,27738,27746,27747,27749,27750,27751,27755,27756,27757,27758,27759,27761,
+27763,27765,27767,27768,27770,27771,27772,27775,27776,27780,27783,27786,27787,
+27789,27790,27793,27794,27797,27798,27799,27800,27802,27804,27805,27806,27808,
+27810,27816,27820,27823,27824,27828,27829,27830,27831,27834,27840,27841,27842,
+27843,27846,27847,27848,27851,27853,27854,27855,27857,27858,27864,27865,27866,
+27868,27869,27871,27876,27878,27879,27881,27884,27885,27890,27892,27897,27903,
+27904,27906,27907,27909,27910,27912,27913,27914,27917,27919,27920,27921,27923,
+27924,27925,27926,27928,27932,27933,27935,27936,27937,27938,27939,27940,27942,
+27944,27945,27948,27949,27951,27952,27956,27958,27959,27960,27962,27967,27968,
+27970,27972,27977,27980,27984,27989,27990,27991,27992,27995,27997,27999,28001,
+28002,28004,28005,28007,28008,28011,28012,28013,28016,28017,28018,28019,28021,
+28022,28025,28026,28027,28029,28030,28031,28032,28033,28035,28036,28038,28039,
+28042,28043,28045,28047,28048,28050,28054,28055,28056,28057,28058,28060,28066,
+28069,28076,28077,28080,28081,28083,28084,28086,28087,28089,28090,28091,28092,
+28093,28094,28097,28098,28099,28104,28105,28106,28109,28110,28111,28112,28114,
+28115,28116,28117,28119,28122,28123,28124,28127,28130,28131,28133,28135,28136,
+28137,28138,28141,28143,28144,28146,28148,28149,28150,28152,28154,28157,28158,
+28159,28160,28161,28162,28163,28164,28166,28167,28168,28169,28171,28175,28178,
+28179,28181,28184,28185,28187,28188,28190,28191,28194,28198,28199,28200,28202,
+28204,28206,28208,28209,28211,28213,28214,28215,28217,28219,28220,28221,28222,
+28223,28224,28225,28226,28229,28230,28231,28232,28233,28234,28235,28236,28239,
+28240,28241,28242,28245,28247,28249,28250,28252,28253,28254,28256,28257,28258,
+28259,28260,28261,28262,28263,28264,28265,28266,28268,28269,28271,28272,28273,
+28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,28284,28285,28288,
+28289,28290,28292,28295,28296,28298,28299,28300,28301,28302,28305,28306,28307,
+28308,28309,28310,28311,28313,28314,28315,28317,28318,28320,28321,28323,28324,
+28326,28328,28329,28331,28332,28333,28334,28336,28339,28341,28344,28345,28348,
+28350,28351,28352,28355,28356,28357,28358,28360,28361,28362,28364,28365,28366,
+28368,28370,28374,28376,28377,28379,28380,28381,28387,28391,28394,28395,28396,
+28397,28398,28399,28400,28401,28402,28403,28405,28406,28407,28408,28410,28411,
+28412,28413,28414,28415,28416,28417,28419,28420,28421,28423,28424,28426,28427,
+28428,28429,28430,28432,28433,28434,28438,28439,28440,28441,28442,28443,28444,
+28445,28446,28447,28449,28450,28451,28453,28454,28455,28456,28460,28462,28464,
+28466,28468,28469,28471,28472,28473,28474,28475,28476,28477,28479,28480,28481,
+28482,28483,28484,28485,28488,28489,28490,28492,28494,28495,28496,28497,28498,
+28499,28500,28501,28502,28503,28505,28506,28507,28509,28511,28512,28513,28515,
+28516,28517,28519,28520,28521,28522,28523,28524,28527,28528,28529,28531,28533,
+28534,28535,28537,28539,28541,28542,28543,28544,28545,28546,28547,28549,28550,
+28551,28554,28555,28559,28560,28561,28562,28563,28564,28565,28566,28567,28568,
+28569,28570,28571,28573,28574,28575,28576,28578,28579,28580,28581,28582,28584,
+28585,28586,28587,28588,28589,28590,28591,28592,28593,28594,28596,28597,28599,
+28600,28602,28603,28604,28605,28606,28607,28609,28611,28612,28613,28614,28615,
+28616,28618,28619,28620,28621,28622,28623,28624,28627,28628,28629,28630,28631,
+28632,28633,28634,28635,28636,28637,28639,28642,28643,28644,28645,28646,28647,
+28648,28649,28650,28651,28652,28653,28656,28657,28658,28659,28660,28661,28662,
+28663,28664,28665,28666,28667,28668,28669,28670,28671,28672,28673,28674,28675,
+28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,28686,28687,28688,
+28690,28691,28692,28693,28694,28695,28696,28697,28700,28701,28702,28703,28704,
+28705,28706,28708,28709,28710,28711,28712,28713,28714,28715,28716,28717,28718,
+28719,28720,28721,28722,28723,28724,28726,28727,28728,28730,28731,28732,28733,
+28734,28735,28736,28737,28738,28739,28740,28741,28742,28743,28744,28745,28746,
+28747,28749,28750,28752,28753,28754,28755,28756,28757,28758,28759,28760,28761,
+28762,28763,28764,28765,28767,28768,28769,28770,28771,28772,28773,28774,28775,
+28776,28777,28778,28782,28785,28786,28787,28788,28791,28793,28794,28795,28797,
+28801,28802,28803,28804,28806,28807,28808,28811,28812,28813,28815,28816,28817,
+28819,28823,28824,28826,28827,28830,28831,28832,28833,28834,28835,28836,28837,
+28838,28839,28840,28841,28842,28848,28850,28852,28853,28854,28858,28862,28863,
+28868,28869,28870,28871,28873,28875,28876,28877,28878,28879,28880,28881,28882,
+28883,28884,28885,28886,28887,28890,28892,28893,28894,28896,28897,28898,28899,
+28901,28906,28910,28912,28913,28914,28915,28916,28917,28918,28920,28922,28923,
+28924,28926,28927,28928,28929,28930,28931,28932,28933,28934,28935,28936,28939,
+28940,28941,28942,28943,28945,28946,28948,28951,28955,28956,28957,28958,28959,
+28960,28961,28962,28963,28964,28965,28967,28968,28969,28970,28971,28972,28973,
+28974,28978,28979,28980,28981,28983,28984,28985,28986,28987,28988,28989,28990,
+28991,28992,28993,28994,28995,28996,28998,28999,29000,29001,29003,29005,29007,
+29008,29009,29010,29011,29012,29013,29014,29015,29016,29017,29018,29019,29021,
+29023,29024,29025,29026,29027,29029,29033,29034,29035,29036,29037,29039,29040,
+29041,29044,29045,29046,29047,29049,29051,29052,29054,29055,29056,29057,29058,
+29059,29061,29062,29063,29064,29065,29067,29068,29069,29070,29072,29073,29074,
+29075,29077,29078,29079,29082,29083,29084,29085,29086,29089,29090,29091,29092,
+29093,29094,29095,29097,29098,29099,29101,29102,29103,29104,29105,29106,29108,
+29110,29111,29112,29114,29115,29116,29117,29118,29119,29120,29121,29122,29124,
+29125,29126,29127,29128,29129,29130,29131,29132,29133,29135,29136,29137,29138,
+29139,29142,29143,29144,29145,29146,29147,29148,29149,29150,29151,29153,29154,
+29155,29156,29158,29160,29161,29162,29163,29164,29165,29167,29168,29169,29170,
+29171,29172,29173,29174,29175,29176,29178,29179,29180,29181,29182,29183,29184,
+29185,29186,29187,29188,29189,29191,29192,29193,29194,29195,29196,29197,29198,
+29199,29200,29201,29202,29203,29204,29205,29206,29207,29208,29209,29210,29211,
+29212,29214,29215,29216,29217,29218,29219,29220,29221,29222,29223,29225,29227,
+29229,29230,29231,29234,29235,29236,29242,29244,29246,29248,29249,29250,29251,
+29252,29253,29254,29257,29258,29259,29262,29263,29264,29265,29267,29268,29269,
+29271,29272,29274,29276,29278,29280,29283,29284,29285,29288,29290,29291,29292,
+29293,29296,29297,29299,29300,29302,29303,29304,29307,29308,29309,29314,29315,
+29317,29318,29319,29320,29321,29324,29326,29328,29329,29331,29332,29333,29334,
+29335,29336,29337,29338,29339,29340,29341,29342,29344,29345,29346,29347,29348,
+29349,29350,29351,29352,29353,29354,29355,29358,29361,29362,29363,29365,29370,
+29371,29372,29373,29374,29375,29376,29381,29382,29383,29385,29386,29387,29388,
+29391,29393,29395,29396,29397,29398,29400,29402,29403,58566,58567,58568,58569,
+58570,58571,58572,58573,58574,58575,58576,58577,58578,58579,58580,58581,58582,
+58583,58584,58585,58586,58587,58588,58589,58590,58591,58592,58593,58594,58595,
+58596,58597,58598,58599,58600,58601,58602,58603,58604,58605,58606,58607,58608,
+58609,58610,58611,58612,58613,58614,58615,58616,58617,58618,58619,58620,58621,
+58622,58623,58624,58625,58626,58627,58628,58629,58630,58631,58632,58633,58634,
+58635,58636,58637,58638,58639,58640,58641,58642,58643,58644,58645,58646,58647,
+58648,58649,58650,58651,58652,58653,58654,58655,58656,58657,58658,58659,58660,
+58661,12288,12289,12290,183,713,711,168,12291,12293,8212,65374,8214,8230,8216,
+8217,8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,
+12310,12311,12304,12305,177,215,247,8758,8743,8744,8721,8719,8746,8745,8712,
+8759,8730,8869,8741,8736,8978,8857,8747,8750,8801,8780,8776,8765,8733,8800,
+8814,8815,8804,8805,8734,8757,8756,9794,9792,176,8242,8243,8451,65284,164,
+65504,65505,8240,167,8470,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,
+9650,8251,8594,8592,8593,8595,12307,58662,58663,58664,58665,58666,58667,58668,
+58669,58670,58671,58672,58673,58674,58675,58676,58677,58678,58679,58680,58681,
+58682,58683,58684,58685,58686,58687,58688,58689,58690,58691,58692,58693,58694,
+58695,58696,58697,58698,58699,58700,58701,58702,58703,58704,58705,58706,58707,
+58708,58709,58710,58711,58712,58713,58714,58715,58716,58717,58718,58719,58720,
+58721,58722,58723,58724,58725,58726,58727,58728,58729,58730,58731,58732,58733,
+58734,58735,58736,58737,58738,58739,58740,58741,58742,58743,58744,58745,58746,
+58747,58748,58749,58750,58751,58752,58753,58754,58755,58756,58757,8560,8561,
+8562,8563,8564,8565,8566,8567,8568,8569,59238,59239,59240,59241,59242,59243,
+9352,9353,9354,9355,9356,9357,9358,9359,9360,9361,9362,9363,9364,9365,9366,
+9367,9368,9369,9370,9371,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,
+9342,9343,9344,9345,9346,9347,9348,9349,9350,9351,9312,9313,9314,9315,9316,
+9317,9318,9319,9320,9321,8364,59245,12832,12833,12834,12835,12836,12837,12838,
+12839,12840,12841,59246,59247,8544,8545,8546,8547,8548,8549,8550,8551,8552,
+8553,8554,8555,59248,59249,58758,58759,58760,58761,58762,58763,58764,58765,
+58766,58767,58768,58769,58770,58771,58772,58773,58774,58775,58776,58777,58778,
+58779,58780,58781,58782,58783,58784,58785,58786,58787,58788,58789,58790,58791,
+58792,58793,58794,58795,58796,58797,58798,58799,58800,58801,58802,58803,58804,
+58805,58806,58807,58808,58809,58810,58811,58812,58813,58814,58815,58816,58817,
+58818,58819,58820,58821,58822,58823,58824,58825,58826,58827,58828,58829,58830,
+58831,58832,58833,58834,58835,58836,58837,58838,58839,58840,58841,58842,58843,
+58844,58845,58846,58847,58848,58849,58850,58851,58852,58853,65281,65282,65283,
+65509,65285,65286,65287,65288,65289,65290,65291,65292,65293,65294,65295,65296,
+65297,65298,65299,65300,65301,65302,65303,65304,65305,65306,65307,65308,65309,
+65310,65311,65312,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,
+65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,
+65336,65337,65338,65339,65340,65341,65342,65343,65344,65345,65346,65347,65348,
+65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,
+65362,65363,65364,65365,65366,65367,65368,65369,65370,65371,65372,65373,65507,
+58854,58855,58856,58857,58858,58859,58860,58861,58862,58863,58864,58865,58866,
+58867,58868,58869,58870,58871,58872,58873,58874,58875,58876,58877,58878,58879,
+58880,58881,58882,58883,58884,58885,58886,58887,58888,58889,58890,58891,58892,
+58893,58894,58895,58896,58897,58898,58899,58900,58901,58902,58903,58904,58905,
+58906,58907,58908,58909,58910,58911,58912,58913,58914,58915,58916,58917,58918,
+58919,58920,58921,58922,58923,58924,58925,58926,58927,58928,58929,58930,58931,
+58932,58933,58934,58935,58936,58937,58938,58939,58940,58941,58942,58943,58944,
+58945,58946,58947,58948,58949,12353,12354,12355,12356,12357,12358,12359,12360,
+12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,
+12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,
+12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,
+12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,
+12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,
+12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,59250,59251,59252,
+59253,59254,59255,59256,59257,59258,59259,59260,58950,58951,58952,58953,58954,
+58955,58956,58957,58958,58959,58960,58961,58962,58963,58964,58965,58966,58967,
+58968,58969,58970,58971,58972,58973,58974,58975,58976,58977,58978,58979,58980,
+58981,58982,58983,58984,58985,58986,58987,58988,58989,58990,58991,58992,58993,
+58994,58995,58996,58997,58998,58999,59000,59001,59002,59003,59004,59005,59006,
+59007,59008,59009,59010,59011,59012,59013,59014,59015,59016,59017,59018,59019,
+59020,59021,59022,59023,59024,59025,59026,59027,59028,59029,59030,59031,59032,
+59033,59034,59035,59036,59037,59038,59039,59040,59041,59042,59043,59044,59045,
+12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,
+12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,
+12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,
+12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,
+12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,
+12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,
+12527,12528,12529,12530,12531,12532,12533,12534,59261,59262,59263,59264,59265,
+59266,59267,59268,59046,59047,59048,59049,59050,59051,59052,59053,59054,59055,
+59056,59057,59058,59059,59060,59061,59062,59063,59064,59065,59066,59067,59068,
+59069,59070,59071,59072,59073,59074,59075,59076,59077,59078,59079,59080,59081,
+59082,59083,59084,59085,59086,59087,59088,59089,59090,59091,59092,59093,59094,
+59095,59096,59097,59098,59099,59100,59101,59102,59103,59104,59105,59106,59107,
+59108,59109,59110,59111,59112,59113,59114,59115,59116,59117,59118,59119,59120,
+59121,59122,59123,59124,59125,59126,59127,59128,59129,59130,59131,59132,59133,
+59134,59135,59136,59137,59138,59139,59140,59141,913,914,915,916,917,918,919,
+920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,59269,
+59270,59271,59272,59273,59274,59275,59276,945,946,947,948,949,950,951,952,953,
+954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,59277,59278,59279,
+59280,59281,59282,59283,65077,65078,65081,65082,65087,65088,65085,65086,65089,
+65090,65091,65092,59284,59285,65083,65084,65079,65080,65073,59286,65075,65076,
+59287,59288,59289,59290,59291,59292,59293,59294,59295,59142,59143,59144,59145,
+59146,59147,59148,59149,59150,59151,59152,59153,59154,59155,59156,59157,59158,
+59159,59160,59161,59162,59163,59164,59165,59166,59167,59168,59169,59170,59171,
+59172,59173,59174,59175,59176,59177,59178,59179,59180,59181,59182,59183,59184,
+59185,59186,59187,59188,59189,59190,59191,59192,59193,59194,59195,59196,59197,
+59198,59199,59200,59201,59202,59203,59204,59205,59206,59207,59208,59209,59210,
+59211,59212,59213,59214,59215,59216,59217,59218,59219,59220,59221,59222,59223,
+59224,59225,59226,59227,59228,59229,59230,59231,59232,59233,59234,59235,59236,
+59237,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,
+1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,
+1068,1069,1070,1071,59296,59297,59298,59299,59300,59301,59302,59303,59304,
+59305,59306,59307,59308,59309,59310,1072,1073,1074,1075,1076,1077,1105,1078,
+1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,
+1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,59311,59312,59313,59314,
+59315,59316,59317,59318,59319,59320,59321,59322,59323,714,715,729,8211,8213,
+8229,8245,8453,8457,8598,8599,8600,8601,8725,8735,8739,8786,8806,8807,8895,
+9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,
+9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,
+9582,9583,9584,9585,9586,9587,9601,9602,9603,9604,9605,9606,9607,9608,9609,
+9610,9611,9612,9613,9614,9615,9619,9620,9621,9660,9661,9698,9699,9700,9701,
+9737,8853,12306,12317,12318,59324,59325,59326,59327,59328,59329,59330,59331,
+59332,59333,59334,257,225,462,224,275,233,283,232,299,237,464,236,333,243,466,
+242,363,250,468,249,470,472,474,476,252,234,593,59335,324,328,505,609,59337,
+59338,59339,59340,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,
+12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571,
+12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583,12584,
+12585,59341,59342,59343,59344,59345,59346,59347,59348,59349,59350,59351,59352,
+59353,59354,59355,59356,59357,59358,59359,59360,59361,12321,12322,12323,12324,
+12325,12326,12327,12328,12329,12963,13198,13199,13212,13213,13214,13217,13252,
+13262,13265,13266,13269,65072,65506,65508,59362,8481,12849,59363,8208,59364,
+59365,59366,12540,12443,12444,12541,12542,12294,12445,12446,65097,65098,65099,
+65100,65101,65102,65103,65104,65105,65106,65108,65109,65110,65111,65113,65114,
+65115,65116,65117,65118,65119,65120,65121,65122,65123,65124,65125,65126,65128,
+65129,65130,65131,12350,12272,12273,12274,12275,12276,12277,12278,12279,12280,
+12281,12282,12283,12295,59380,59381,59382,59383,59384,59385,59386,59387,59388,
+59389,59390,59391,59392,9472,9473,9474,9475,9476,9477,9478,9479,9480,9481,
+9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,9493,9494,9495,9496,
+9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507,9508,9509,9510,9511,
+9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,
+9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,
+9542,9543,9544,9545,9546,9547,59393,59394,59395,59396,59397,59398,59399,59400,
+59401,59402,59403,59404,59405,59406,59407,29404,29405,29407,29410,29411,29412,
+29413,29414,29415,29418,29419,29429,29430,29433,29437,29438,29439,29440,29442,
+29444,29445,29446,29447,29448,29449,29451,29452,29453,29455,29456,29457,29458,
+29460,29464,29465,29466,29471,29472,29475,29476,29478,29479,29480,29485,29487,
+29488,29490,29491,29493,29494,29498,29499,29500,29501,29504,29505,29506,29507,
+29508,29509,29510,29511,29512,29513,29514,29515,29516,29518,29519,29521,29523,
+29524,29525,29526,29528,29529,29530,29531,29532,29533,29534,29535,29537,29538,
+29539,29540,29541,29542,29543,29544,29545,29546,29547,29550,29552,29553,57344,
+57345,57346,57347,57348,57349,57350,57351,57352,57353,57354,57355,57356,57357,
+57358,57359,57360,57361,57362,57363,57364,57365,57366,57367,57368,57369,57370,
+57371,57372,57373,57374,57375,57376,57377,57378,57379,57380,57381,57382,57383,
+57384,57385,57386,57387,57388,57389,57390,57391,57392,57393,57394,57395,57396,
+57397,57398,57399,57400,57401,57402,57403,57404,57405,57406,57407,57408,57409,
+57410,57411,57412,57413,57414,57415,57416,57417,57418,57419,57420,57421,57422,
+57423,57424,57425,57426,57427,57428,57429,57430,57431,57432,57433,57434,57435,
+57436,57437,29554,29555,29556,29557,29558,29559,29560,29561,29562,29563,29564,
+29565,29567,29568,29569,29570,29571,29573,29574,29576,29578,29580,29581,29583,
+29584,29586,29587,29588,29589,29591,29592,29593,29594,29596,29597,29598,29600,
+29601,29603,29604,29605,29606,29607,29608,29610,29612,29613,29617,29620,29621,
+29622,29624,29625,29628,29629,29630,29631,29633,29635,29636,29637,29638,29639,
+29643,29644,29646,29650,29651,29652,29653,29654,29655,29656,29658,29659,29660,
+29661,29663,29665,29666,29667,29668,29670,29672,29674,29675,29676,29678,29679,
+29680,29681,29683,29684,29685,29686,29687,57438,57439,57440,57441,57442,57443,
+57444,57445,57446,57447,57448,57449,57450,57451,57452,57453,57454,57455,57456,
+57457,57458,57459,57460,57461,57462,57463,57464,57465,57466,57467,57468,57469,
+57470,57471,57472,57473,57474,57475,57476,57477,57478,57479,57480,57481,57482,
+57483,57484,57485,57486,57487,57488,57489,57490,57491,57492,57493,57494,57495,
+57496,57497,57498,57499,57500,57501,57502,57503,57504,57505,57506,57507,57508,
+57509,57510,57511,57512,57513,57514,57515,57516,57517,57518,57519,57520,57521,
+57522,57523,57524,57525,57526,57527,57528,57529,57530,57531,29688,29689,29690,
+29691,29692,29693,29694,29695,29696,29697,29698,29700,29703,29704,29707,29708,
+29709,29710,29713,29714,29715,29716,29717,29718,29719,29720,29721,29724,29725,
+29726,29727,29728,29729,29731,29732,29735,29737,29739,29741,29743,29745,29746,
+29751,29752,29753,29754,29755,29757,29758,29759,29760,29762,29763,29764,29765,
+29766,29767,29768,29769,29770,29771,29772,29773,29774,29775,29776,29777,29778,
+29779,29780,29782,29784,29789,29792,29793,29794,29795,29796,29797,29798,29799,
+29800,29801,29802,29803,29804,29806,29807,29809,29810,29811,29812,29813,29816,
+29817,29818,57532,57533,57534,57535,57536,57537,57538,57539,57540,57541,57542,
+57543,57544,57545,57546,57547,57548,57549,57550,57551,57552,57553,57554,57555,
+57556,57557,57558,57559,57560,57561,57562,57563,57564,57565,57566,57567,57568,
+57569,57570,57571,57572,57573,57574,57575,57576,57577,57578,57579,57580,57581,
+57582,57583,57584,57585,57586,57587,57588,57589,57590,57591,57592,57593,57594,
+57595,57596,57597,57598,57599,57600,57601,57602,57603,57604,57605,57606,57607,
+57608,57609,57610,57611,57612,57613,57614,57615,57616,57617,57618,57619,57620,
+57621,57622,57623,57624,57625,29819,29820,29821,29823,29826,29828,29829,29830,
+29832,29833,29834,29836,29837,29839,29841,29842,29843,29844,29845,29846,29847,
+29848,29849,29850,29851,29853,29855,29856,29857,29858,29859,29860,29861,29862,
+29866,29867,29868,29869,29870,29871,29872,29873,29874,29875,29876,29877,29878,
+29879,29880,29881,29883,29884,29885,29886,29887,29888,29889,29890,29891,29892,
+29893,29894,29895,29896,29897,29898,29899,29900,29901,29902,29903,29904,29905,
+29907,29908,29909,29910,29911,29912,29913,29914,29915,29917,29919,29921,29925,
+29927,29928,29929,29930,29931,29932,29933,29936,29937,29938,57626,57627,57628,
+57629,57630,57631,57632,57633,57634,57635,57636,57637,57638,57639,57640,57641,
+57642,57643,57644,57645,57646,57647,57648,57649,57650,57651,57652,57653,57654,
+57655,57656,57657,57658,57659,57660,57661,57662,57663,57664,57665,57666,57667,
+57668,57669,57670,57671,57672,57673,57674,57675,57676,57677,57678,57679,57680,
+57681,57682,57683,57684,57685,57686,57687,57688,57689,57690,57691,57692,57693,
+57694,57695,57696,57697,57698,57699,57700,57701,57702,57703,57704,57705,57706,
+57707,57708,57709,57710,57711,57712,57713,57714,57715,57716,57717,57718,57719,
+29939,29941,29944,29945,29946,29947,29948,29949,29950,29952,29953,29954,29955,
+29957,29958,29959,29960,29961,29962,29963,29964,29966,29968,29970,29972,29973,
+29974,29975,29979,29981,29982,29984,29985,29986,29987,29988,29990,29991,29994,
+29998,30004,30006,30009,30012,30013,30015,30017,30018,30019,30020,30022,30023,
+30025,30026,30029,30032,30033,30034,30035,30037,30038,30039,30040,30045,30046,
+30047,30048,30049,30050,30051,30052,30055,30056,30057,30059,30060,30061,30062,
+30063,30064,30065,30067,30069,30070,30071,30074,30075,30076,30077,30078,30080,
+30081,30082,30084,30085,30087,57720,57721,57722,57723,57724,57725,57726,57727,
+57728,57729,57730,57731,57732,57733,57734,57735,57736,57737,57738,57739,57740,
+57741,57742,57743,57744,57745,57746,57747,57748,57749,57750,57751,57752,57753,
+57754,57755,57756,57757,57758,57759,57760,57761,57762,57763,57764,57765,57766,
+57767,57768,57769,57770,57771,57772,57773,57774,57775,57776,57777,57778,57779,
+57780,57781,57782,57783,57784,57785,57786,57787,57788,57789,57790,57791,57792,
+57793,57794,57795,57796,57797,57798,57799,57800,57801,57802,57803,57804,57805,
+57806,57807,57808,57809,57810,57811,57812,57813,30088,30089,30090,30092,30093,
+30094,30096,30099,30101,30104,30107,30108,30110,30114,30118,30119,30120,30121,
+30122,30125,30134,30135,30138,30139,30143,30144,30145,30150,30155,30156,30158,
+30159,30160,30161,30163,30167,30169,30170,30172,30173,30175,30176,30177,30181,
+30185,30188,30189,30190,30191,30194,30195,30197,30198,30199,30200,30202,30203,
+30205,30206,30210,30212,30214,30215,30216,30217,30219,30221,30222,30223,30225,
+30226,30227,30228,30230,30234,30236,30237,30238,30241,30243,30247,30248,30252,
+30254,30255,30257,30258,30262,30263,30265,30266,30267,30269,30273,30274,30276,
+57814,57815,57816,57817,57818,57819,57820,57821,57822,57823,57824,57825,57826,
+57827,57828,57829,57830,57831,57832,57833,57834,57835,57836,57837,57838,57839,
+57840,57841,57842,57843,57844,57845,57846,57847,57848,57849,57850,57851,57852,
+57853,57854,57855,57856,57857,57858,57859,57860,57861,57862,57863,57864,57865,
+57866,57867,57868,57869,57870,57871,57872,57873,57874,57875,57876,57877,57878,
+57879,57880,57881,57882,57883,57884,57885,57886,57887,57888,57889,57890,57891,
+57892,57893,57894,57895,57896,57897,57898,57899,57900,57901,57902,57903,57904,
+57905,57906,57907,30277,30278,30279,30280,30281,30282,30283,30286,30287,30288,
+30289,30290,30291,30293,30295,30296,30297,30298,30299,30301,30303,30304,30305,
+30306,30308,30309,30310,30311,30312,30313,30314,30316,30317,30318,30320,30321,
+30322,30323,30324,30325,30326,30327,30329,30330,30332,30335,30336,30337,30339,
+30341,30345,30346,30348,30349,30351,30352,30354,30356,30357,30359,30360,30362,
+30363,30364,30365,30366,30367,30368,30369,30370,30371,30373,30374,30375,30376,
+30377,30378,30379,30380,30381,30383,30384,30387,30389,30390,30391,30392,30393,
+30394,30395,30396,30397,30398,30400,30401,30403,21834,38463,22467,25384,21710,
+21769,21696,30353,30284,34108,30702,33406,30861,29233,38552,38797,27688,23433,
+20474,25353,26263,23736,33018,26696,32942,26114,30414,20985,25942,29100,32753,
+34948,20658,22885,25034,28595,33453,25420,25170,21485,21543,31494,20843,30116,
+24052,25300,36299,38774,25226,32793,22365,38712,32610,29240,30333,26575,30334,
+25670,20336,36133,25308,31255,26001,29677,25644,25203,33324,39041,26495,29256,
+25198,25292,20276,29923,21322,21150,32458,37030,24110,26758,27036,33152,32465,
+26834,30917,34444,38225,20621,35876,33502,32990,21253,35090,21093,30404,30407,
+30409,30411,30412,30419,30421,30425,30426,30428,30429,30430,30432,30433,30434,
+30435,30436,30438,30439,30440,30441,30442,30443,30444,30445,30448,30451,30453,
+30454,30455,30458,30459,30461,30463,30464,30466,30467,30469,30470,30474,30476,
+30478,30479,30480,30481,30482,30483,30484,30485,30486,30487,30488,30491,30492,
+30493,30494,30497,30499,30500,30501,30503,30506,30507,30508,30510,30512,30513,
+30514,30515,30516,30521,30523,30525,30526,30527,30530,30532,30533,30534,30536,
+30537,30538,30539,30540,30541,30542,30543,30546,30547,30548,30549,30550,30551,
+30552,30553,30556,34180,38649,20445,22561,39281,23453,25265,25253,26292,35961,
+40077,29190,26479,30865,24754,21329,21271,36744,32972,36125,38049,20493,29384,
+22791,24811,28953,34987,22868,33519,26412,31528,23849,32503,29997,27893,36454,
+36856,36924,40763,27604,37145,31508,24444,30887,34006,34109,27605,27609,27606,
+24065,24199,30201,38381,25949,24330,24517,36767,22721,33218,36991,38491,38829,
+36793,32534,36140,25153,20415,21464,21342,36776,36777,36779,36941,26631,24426,
+33176,34920,40150,24971,21035,30250,24428,25996,28626,28392,23486,25672,20853,
+20912,26564,19993,31177,39292,28851,30557,30558,30559,30560,30564,30567,30569,
+30570,30573,30574,30575,30576,30577,30578,30579,30580,30581,30582,30583,30584,
+30586,30587,30588,30593,30594,30595,30598,30599,30600,30601,30602,30603,30607,
+30608,30611,30612,30613,30614,30615,30616,30617,30618,30619,30620,30621,30622,
+30625,30627,30628,30630,30632,30635,30637,30638,30639,30641,30642,30644,30646,
+30647,30648,30649,30650,30652,30654,30656,30657,30658,30659,30660,30661,30662,
+30663,30664,30665,30666,30667,30668,30670,30671,30672,30673,30674,30675,30676,
+30677,30678,30680,30681,30682,30685,30686,30687,30688,30689,30692,30149,24182,
+29627,33760,25773,25320,38069,27874,21338,21187,25615,38082,31636,20271,24091,
+33334,33046,33162,28196,27850,39539,25429,21340,21754,34917,22496,19981,24067,
+27493,31807,37096,24598,25830,29468,35009,26448,25165,36130,30572,36393,37319,
+24425,33756,34081,39184,21442,34453,27531,24813,24808,28799,33485,33329,20179,
+27815,34255,25805,31961,27133,26361,33609,21397,31574,20391,20876,27979,23618,
+36461,25554,21449,33580,33590,26597,30900,25661,23519,23700,24046,35815,25286,
+26612,35962,25600,25530,34633,39307,35863,32544,38130,20135,38416,39076,26124,
+29462,30694,30696,30698,30703,30704,30705,30706,30708,30709,30711,30713,30714,
+30715,30716,30723,30724,30725,30726,30727,30728,30730,30731,30734,30735,30736,
+30739,30741,30745,30747,30750,30752,30753,30754,30756,30760,30762,30763,30766,
+30767,30769,30770,30771,30773,30774,30781,30783,30785,30786,30787,30788,30790,
+30792,30793,30794,30795,30797,30799,30801,30803,30804,30808,30809,30810,30811,
+30812,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,30824,30825,
+30831,30832,30833,30834,30835,30836,30837,30838,30840,30841,30842,30843,30845,
+30846,30847,30848,30849,30850,30851,22330,23581,24120,38271,20607,32928,21378,
+25950,30021,21809,20513,36229,25220,38046,26397,22066,28526,24034,21557,28818,
+36710,25199,25764,25507,24443,28552,37108,33251,36784,23576,26216,24561,27785,
+38472,36225,34924,25745,31216,22478,27225,25104,21576,20056,31243,24809,28548,
+35802,25215,36894,39563,31204,21507,30196,25345,21273,27744,36831,24347,39536,
+32827,40831,20360,23610,36196,32709,26021,28861,20805,20914,34411,23815,23456,
+25277,37228,30068,36364,31264,24833,31609,20167,32504,30597,19985,33261,21021,
+20986,27249,21416,36487,38148,38607,28353,38500,26970,30852,30853,30854,30856,
+30858,30859,30863,30864,30866,30868,30869,30870,30873,30877,30878,30880,30882,
+30884,30886,30888,30889,30890,30891,30892,30893,30894,30895,30901,30902,30903,
+30904,30906,30907,30908,30909,30911,30912,30914,30915,30916,30918,30919,30920,
+30924,30925,30926,30927,30929,30930,30931,30934,30935,30936,30938,30939,30940,
+30941,30942,30943,30944,30945,30946,30947,30948,30949,30950,30951,30953,30954,
+30955,30957,30958,30959,30960,30961,30963,30965,30966,30968,30969,30971,30972,
+30973,30974,30975,30976,30978,30979,30980,30982,30983,30984,30985,30986,30987,
+30988,30784,20648,30679,25616,35302,22788,25571,24029,31359,26941,20256,33337,
+21912,20018,30126,31383,24162,24202,38383,21019,21561,28810,25462,38180,22402,
+26149,26943,37255,21767,28147,32431,34850,25139,32496,30133,33576,30913,38604,
+36766,24904,29943,35789,27492,21050,36176,27425,32874,33905,22257,21254,20174,
+19995,20945,31895,37259,31751,20419,36479,31713,31388,25703,23828,20652,33030,
+30209,31929,28140,32736,26449,23384,23544,30923,25774,25619,25514,25387,38169,
+25645,36798,31572,30249,25171,22823,21574,27513,20643,25140,24102,27526,20195,
+36151,34955,24453,36910,30989,30990,30991,30992,30993,30994,30996,30997,30998,
+30999,31000,31001,31002,31003,31004,31005,31007,31008,31009,31010,31011,31013,
+31014,31015,31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,31026,
+31027,31029,31030,31031,31032,31033,31037,31039,31042,31043,31044,31045,31047,
+31050,31051,31052,31053,31054,31055,31056,31057,31058,31060,31061,31064,31065,
+31073,31075,31076,31078,31081,31082,31083,31084,31086,31088,31089,31090,31091,
+31092,31093,31094,31097,31099,31100,31101,31102,31103,31106,31107,31110,31111,
+31112,31113,31115,31116,31117,31118,31120,31121,31122,24608,32829,25285,20025,
+21333,37112,25528,32966,26086,27694,20294,24814,28129,35806,24377,34507,24403,
+25377,20826,33633,26723,20992,25443,36424,20498,23707,31095,23548,21040,31291,
+24764,36947,30423,24503,24471,30340,36460,28783,30331,31561,30634,20979,37011,
+22564,20302,28404,36842,25932,31515,29380,28068,32735,23265,25269,24213,22320,
+33922,31532,24093,24351,36882,32532,39072,25474,28359,30872,28857,20856,38747,
+22443,30005,20291,30008,24215,24806,22880,28096,27583,30857,21500,38613,20939,
+20993,25481,21514,38035,35843,36300,29241,30879,34678,36845,35853,21472,31123,
+31124,31125,31126,31127,31128,31129,31131,31132,31133,31134,31135,31136,31137,
+31138,31139,31140,31141,31142,31144,31145,31146,31147,31148,31149,31150,31151,
+31152,31153,31154,31156,31157,31158,31159,31160,31164,31167,31170,31172,31173,
+31175,31176,31178,31180,31182,31183,31184,31187,31188,31190,31191,31193,31194,
+31195,31196,31197,31198,31200,31201,31202,31205,31208,31210,31212,31214,31217,
+31218,31219,31220,31221,31222,31223,31225,31226,31228,31230,31231,31233,31236,
+31237,31239,31240,31241,31242,31244,31247,31248,31249,31250,31251,31253,31254,
+31256,31257,31259,31260,19969,30447,21486,38025,39030,40718,38189,23450,35746,
+20002,19996,20908,33891,25026,21160,26635,20375,24683,20923,27934,20828,25238,
+26007,38497,35910,36887,30168,37117,30563,27602,29322,29420,35835,22581,30585,
+36172,26460,38208,32922,24230,28193,22930,31471,30701,38203,27573,26029,32526,
+22534,20817,38431,23545,22697,21544,36466,25958,39039,22244,38045,30462,36929,
+25479,21702,22810,22842,22427,36530,26421,36346,33333,21057,24816,22549,34558,
+23784,40517,20420,39069,35769,23077,24694,21380,25212,36943,37122,39295,24681,
+32780,20799,32819,23572,39285,27953,20108,31261,31263,31265,31266,31268,31269,
+31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,31280,31281,31282,
+31284,31285,31286,31288,31290,31294,31296,31297,31298,31299,31300,31301,31303,
+31304,31305,31306,31307,31308,31309,31310,31311,31312,31314,31315,31316,31317,
+31318,31320,31321,31322,31323,31324,31325,31326,31327,31328,31329,31330,31331,
+31332,31333,31334,31335,31336,31337,31338,31339,31340,31341,31342,31343,31345,
+31346,31347,31349,31355,31356,31357,31358,31362,31365,31367,31369,31370,31371,
+31372,31374,31375,31376,31379,31380,31385,31386,31387,31390,31393,31394,36144,
+21457,32602,31567,20240,20047,38400,27861,29648,34281,24070,30058,32763,27146,
+30718,38034,32321,20961,28902,21453,36820,33539,36137,29359,39277,27867,22346,
+33459,26041,32938,25151,38450,22952,20223,35775,32442,25918,33778,38750,21857,
+39134,32933,21290,35837,21536,32954,24223,27832,36153,33452,37210,21545,27675,
+20998,32439,22367,28954,27774,31881,22859,20221,24575,24868,31914,20016,23553,
+26539,34562,23792,38155,39118,30127,28925,36898,20911,32541,35773,22857,20964,
+20315,21542,22827,25975,32932,23413,25206,25282,36752,24133,27679,31526,20239,
+20440,26381,31395,31396,31399,31401,31402,31403,31406,31407,31408,31409,31410,
+31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31424,31425,
+31426,31427,31428,31429,31430,31431,31432,31433,31434,31436,31437,31438,31439,
+31440,31441,31442,31443,31444,31445,31447,31448,31450,31451,31452,31453,31457,
+31458,31460,31463,31464,31465,31466,31467,31468,31470,31472,31473,31474,31475,
+31476,31477,31478,31479,31480,31483,31484,31486,31488,31489,31490,31493,31495,
+31497,31500,31501,31502,31504,31506,31507,31510,31511,31512,31514,31516,31517,
+31519,31521,31522,31523,31527,31529,31533,28014,28074,31119,34993,24343,29995,
+25242,36741,20463,37340,26023,33071,33105,24220,33104,36212,21103,35206,36171,
+22797,20613,20184,38428,29238,33145,36127,23500,35747,38468,22919,32538,21648,
+22134,22030,35813,25913,27010,38041,30422,28297,24178,29976,26438,26577,31487,
+32925,36214,24863,31174,25954,36195,20872,21018,38050,32568,32923,32434,23703,
+28207,26464,31705,30347,39640,33167,32660,31957,25630,38224,31295,21578,21733,
+27468,25601,25096,40509,33011,30105,21106,38761,33883,26684,34532,38401,38548,
+38124,20010,21508,32473,26681,36319,32789,26356,24218,32697,31535,31536,31538,
+31540,31541,31542,31543,31545,31547,31549,31551,31552,31553,31554,31555,31556,
+31558,31560,31562,31565,31566,31571,31573,31575,31577,31580,31582,31583,31585,
+31587,31588,31589,31590,31591,31592,31593,31594,31595,31596,31597,31599,31600,
+31603,31604,31606,31608,31610,31612,31613,31615,31617,31618,31619,31620,31622,
+31623,31624,31625,31626,31627,31628,31630,31631,31633,31634,31635,31638,31640,
+31641,31642,31643,31646,31647,31648,31651,31652,31653,31662,31663,31664,31666,
+31667,31669,31670,31671,31673,31674,31675,31676,31677,31678,31679,31680,31682,
+31683,31684,22466,32831,26775,24037,25915,21151,24685,40858,20379,36524,20844,
+23467,24339,24041,27742,25329,36129,20849,38057,21246,27807,33503,29399,22434,
+26500,36141,22815,36764,33735,21653,31629,20272,27837,23396,22993,40723,21476,
+34506,39592,35895,32929,25925,39038,22266,38599,21038,29916,21072,23521,25346,
+35074,20054,25296,24618,26874,20851,23448,20896,35266,31649,39302,32592,24815,
+28748,36143,20809,24191,36891,29808,35268,22317,30789,24402,40863,38394,36712,
+39740,35809,30328,26690,26588,36330,36149,21053,36746,28378,26829,38149,37101,
+22269,26524,35065,36807,21704,31685,31688,31689,31690,31691,31693,31694,31695,
+31696,31698,31700,31701,31702,31703,31704,31707,31708,31710,31711,31712,31714,
+31715,31716,31719,31720,31721,31723,31724,31725,31727,31728,31730,31731,31732,
+31733,31734,31736,31737,31738,31739,31741,31743,31744,31745,31746,31747,31748,
+31749,31750,31752,31753,31754,31757,31758,31760,31761,31762,31763,31764,31765,
+31767,31768,31769,31770,31771,31772,31773,31774,31776,31777,31778,31779,31780,
+31781,31784,31785,31787,31788,31789,31790,31791,31792,31793,31794,31795,31796,
+31797,31798,31799,31801,31802,31803,31804,31805,31806,31810,39608,23401,28023,
+27686,20133,23475,39559,37219,25000,37039,38889,21547,28085,23506,20989,21898,
+32597,32752,25788,25421,26097,25022,24717,28938,27735,27721,22831,26477,33322,
+22741,22158,35946,27627,37085,22909,32791,21495,28009,21621,21917,33655,33743,
+26680,31166,21644,20309,21512,30418,35977,38402,27827,28088,36203,35088,40548,
+36154,22079,40657,30165,24456,29408,24680,21756,20136,27178,34913,24658,36720,
+21700,28888,34425,40511,27946,23439,24344,32418,21897,20399,29492,21564,21402,
+20505,21518,21628,20046,24573,29786,22774,33899,32993,34676,29392,31946,28246,
+31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31822,31823,31824,
+31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835,31836,31837,
+31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848,31849,31850,
+31851,31852,31853,31854,31855,31856,31857,31858,31861,31862,31863,31864,31865,
+31866,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,31880,31882,
+31883,31884,31885,31886,31887,31888,31891,31892,31894,31897,31898,31899,31904,
+31905,31907,31910,31911,31912,31913,31915,31916,31917,31919,31920,31924,31925,
+31926,31927,31928,31930,31931,24359,34382,21804,25252,20114,27818,25143,33457,
+21719,21326,29502,28369,30011,21010,21270,35805,27088,24458,24576,28142,22351,
+27426,29615,26707,36824,32531,25442,24739,21796,30186,35938,28949,28067,23462,
+24187,33618,24908,40644,30970,34647,31783,30343,20976,24822,29004,26179,24140,
+24653,35854,28784,25381,36745,24509,24674,34516,22238,27585,24724,24935,21321,
+24800,26214,36159,31229,20250,28905,27719,35763,35826,32472,33636,26127,23130,
+39746,27985,28151,35905,27963,20249,28779,33719,25110,24785,38669,36135,31096,
+20987,22334,22522,26426,30072,31293,31215,31637,31935,31936,31938,31939,31940,
+31942,31945,31947,31950,31951,31952,31953,31954,31955,31956,31960,31962,31963,
+31965,31966,31969,31970,31971,31972,31973,31974,31975,31977,31978,31979,31980,
+31981,31982,31984,31985,31986,31987,31988,31989,31990,31991,31993,31994,31996,
+31997,31998,31999,32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,
+32011,32012,32013,32014,32015,32016,32017,32018,32019,32020,32021,32022,32023,
+32024,32025,32026,32027,32028,32029,32030,32031,32033,32035,32036,32037,32038,
+32040,32041,32042,32044,32045,32046,32048,32049,32050,32051,32052,32053,32054,
+32908,39269,36857,28608,35749,40481,23020,32489,32521,21513,26497,26840,36753,
+31821,38598,21450,24613,30142,27762,21363,23241,32423,25380,20960,33034,24049,
+34015,25216,20864,23395,20238,31085,21058,24760,27982,23492,23490,35745,35760,
+26082,24524,38469,22931,32487,32426,22025,26551,22841,20339,23478,21152,33626,
+39050,36158,30002,38078,20551,31292,20215,26550,39550,23233,27516,30417,22362,
+23574,31546,38388,29006,20860,32937,33392,22904,32516,33575,26816,26604,30897,
+30839,25315,25441,31616,20461,21098,20943,33616,27099,37492,36341,36145,35265,
+38190,31661,20214,32055,32056,32057,32058,32059,32060,32061,32062,32063,32064,
+32065,32066,32067,32068,32069,32070,32071,32072,32073,32074,32075,32076,32077,
+32078,32079,32080,32081,32082,32083,32084,32085,32086,32087,32088,32089,32090,
+32091,32092,32093,32094,32095,32096,32097,32098,32099,32100,32101,32102,32103,
+32104,32105,32106,32107,32108,32109,32111,32112,32113,32114,32115,32116,32117,
+32118,32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,
+32132,32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,32144,
+32145,32146,32147,32148,32149,32150,32151,32152,20581,33328,21073,39279,28176,
+28293,28071,24314,20725,23004,23558,27974,27743,30086,33931,26728,22870,35762,
+21280,37233,38477,34121,26898,30977,28966,33014,20132,37066,27975,39556,23047,
+22204,25605,38128,30699,20389,33050,29409,35282,39290,32564,32478,21119,25945,
+37237,36735,36739,21483,31382,25581,25509,30342,31224,34903,38454,25130,21163,
+33410,26708,26480,25463,30571,31469,27905,32467,35299,22992,25106,34249,33445,
+30028,20511,20171,30117,35819,23626,24062,31563,26020,37329,20170,27941,35167,
+32039,38182,20165,35880,36827,38771,26187,31105,36817,28908,28024,32153,32154,
+32155,32156,32157,32158,32159,32160,32161,32162,32163,32164,32165,32167,32168,
+32169,32170,32171,32172,32173,32175,32176,32177,32178,32179,32180,32181,32182,
+32183,32184,32185,32186,32187,32188,32189,32190,32191,32192,32193,32194,32195,
+32196,32197,32198,32199,32200,32201,32202,32203,32204,32205,32206,32207,32208,
+32209,32210,32211,32212,32213,32214,32215,32216,32217,32218,32219,32220,32221,
+32222,32223,32224,32225,32226,32227,32228,32229,32230,32231,32232,32233,32234,
+32235,32236,32237,32238,32239,32240,32241,32242,32243,32244,32245,32246,32247,
+32248,32249,32250,23613,21170,33606,20834,33550,30555,26230,40120,20140,24778,
+31934,31923,32463,20117,35686,26223,39048,38745,22659,25964,38236,24452,30153,
+38742,31455,31454,20928,28847,31384,25578,31350,32416,29590,38893,20037,28792,
+20061,37202,21417,25937,26087,33276,33285,21646,23601,30106,38816,25304,29401,
+30141,23621,39545,33738,23616,21632,30697,20030,27822,32858,25298,25454,24040,
+20855,36317,36382,38191,20465,21477,24807,28844,21095,25424,40515,23071,20518,
+30519,21367,32482,25733,25899,25225,25496,20500,29237,35273,20915,35776,32477,
+22343,33740,38055,20891,21531,23803,32251,32252,32253,32254,32255,32256,32257,
+32258,32259,32260,32261,32262,32263,32264,32265,32266,32267,32268,32269,32270,
+32271,32272,32273,32274,32275,32276,32277,32278,32279,32280,32281,32282,32283,
+32284,32285,32286,32287,32288,32289,32290,32291,32292,32293,32294,32295,32296,
+32297,32298,32299,32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,
+32310,32311,32312,32313,32314,32316,32317,32318,32319,32320,32322,32323,32324,
+32325,32326,32328,32329,32330,32331,32332,32333,32334,32335,32336,32337,32338,
+32339,32340,32341,32342,32343,32344,32345,32346,32347,32348,32349,20426,31459,
+27994,37089,39567,21888,21654,21345,21679,24320,25577,26999,20975,24936,21002,
+22570,21208,22350,30733,30475,24247,24951,31968,25179,25239,20130,28821,32771,
+25335,28900,38752,22391,33499,26607,26869,30933,39063,31185,22771,21683,21487,
+28212,20811,21051,23458,35838,32943,21827,22438,24691,22353,21549,31354,24656,
+23380,25511,25248,21475,25187,23495,26543,21741,31391,33510,37239,24211,35044,
+22840,22446,25358,36328,33007,22359,31607,20393,24555,23485,27454,21281,31568,
+29378,26694,30719,30518,26103,20917,20111,30420,23743,31397,33909,22862,39745,
+20608,32350,32351,32352,32353,32354,32355,32356,32357,32358,32359,32360,32361,
+32362,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373,32374,
+32375,32376,32377,32378,32379,32380,32381,32382,32383,32384,32385,32387,32388,
+32389,32390,32391,32392,32393,32394,32395,32396,32397,32398,32399,32400,32401,
+32402,32403,32404,32405,32406,32407,32408,32409,32410,32412,32413,32414,32430,
+32436,32443,32444,32470,32484,32492,32505,32522,32528,32542,32567,32569,32571,
+32572,32573,32574,32575,32576,32577,32579,32582,32583,32584,32585,32586,32587,
+32588,32589,32590,32591,32594,32595,39304,24871,28291,22372,26118,25414,22256,
+25324,25193,24275,38420,22403,25289,21895,34593,33098,36771,21862,33713,26469,
+36182,34013,23146,26639,25318,31726,38417,20848,28572,35888,25597,35272,25042,
+32518,28866,28389,29701,27028,29436,24266,37070,26391,28010,25438,21171,29282,
+32769,20332,23013,37226,28889,28061,21202,20048,38647,38253,34174,30922,32047,
+20769,22418,25794,32907,31867,27882,26865,26974,20919,21400,26792,29313,40654,
+31729,29432,31163,28435,29702,26446,37324,40100,31036,33673,33620,21519,26647,
+20029,21385,21169,30782,21382,21033,20616,20363,20432,32598,32601,32603,32604,
+32605,32606,32608,32611,32612,32613,32614,32615,32619,32620,32621,32623,32624,
+32627,32629,32630,32631,32632,32634,32635,32636,32637,32639,32640,32642,32643,
+32644,32645,32646,32647,32648,32649,32651,32653,32655,32656,32657,32658,32659,
+32661,32662,32663,32664,32665,32667,32668,32672,32674,32675,32677,32678,32680,
+32681,32682,32683,32684,32685,32686,32689,32691,32692,32693,32694,32695,32698,
+32699,32702,32704,32706,32707,32708,32710,32711,32712,32713,32715,32717,32719,
+32720,32721,32722,32723,32726,32727,32729,32730,32731,32732,32733,32734,32738,
+32739,30178,31435,31890,27813,38582,21147,29827,21737,20457,32852,33714,36830,
+38256,24265,24604,28063,24088,25947,33080,38142,24651,28860,32451,31918,20937,
+26753,31921,33391,20004,36742,37327,26238,20142,35845,25769,32842,20698,30103,
+29134,23525,36797,28518,20102,25730,38243,24278,26009,21015,35010,28872,21155,
+29454,29747,26519,30967,38678,20020,37051,40158,28107,20955,36161,21533,25294,
+29618,33777,38646,40836,38083,20278,32666,20940,28789,38517,23725,39046,21478,
+20196,28316,29705,27060,30827,39311,30041,21016,30244,27969,26611,20845,40857,
+32843,21657,31548,31423,32740,32743,32744,32746,32747,32748,32749,32751,32754,
+32756,32757,32758,32759,32760,32761,32762,32765,32766,32767,32770,32775,32776,
+32777,32778,32782,32783,32785,32787,32794,32795,32797,32798,32799,32801,32803,
+32804,32811,32812,32813,32814,32815,32816,32818,32820,32825,32826,32828,32830,
+32832,32833,32836,32837,32839,32840,32841,32846,32847,32848,32849,32851,32853,
+32854,32855,32857,32859,32860,32861,32862,32863,32864,32865,32866,32867,32868,
+32869,32870,32871,32872,32875,32876,32877,32878,32879,32880,32882,32883,32884,
+32885,32886,32887,32888,32889,32890,32891,32892,32893,38534,22404,25314,38471,
+27004,23044,25602,31699,28431,38475,33446,21346,39045,24208,28809,25523,21348,
+34383,40065,40595,30860,38706,36335,36162,40575,28510,31108,24405,38470,25134,
+39540,21525,38109,20387,26053,23653,23649,32533,34385,27695,24459,29575,28388,
+32511,23782,25371,23402,28390,21365,20081,25504,30053,25249,36718,20262,20177,
+27814,32438,35770,33821,34746,32599,36923,38179,31657,39585,35064,33853,27931,
+39558,32476,22920,40635,29595,30721,34434,39532,39554,22043,21527,22475,20080,
+40614,21334,36808,33033,30610,39314,34542,28385,34067,26364,24930,28459,32894,
+32897,32898,32901,32904,32906,32909,32910,32911,32912,32913,32914,32916,32917,
+32919,32921,32926,32931,32934,32935,32936,32940,32944,32947,32949,32950,32952,
+32953,32955,32965,32967,32968,32969,32970,32971,32975,32976,32977,32978,32979,
+32980,32981,32984,32991,32992,32994,32995,32998,33006,33013,33015,33017,33019,
+33022,33023,33024,33025,33027,33028,33029,33031,33032,33035,33036,33045,33047,
+33049,33051,33052,33053,33055,33056,33057,33058,33059,33060,33061,33062,33063,
+33064,33065,33066,33067,33069,33070,33072,33075,33076,33077,33079,33081,33082,
+33083,33084,33085,33087,35881,33426,33579,30450,27667,24537,33725,29483,33541,
+38170,27611,30683,38086,21359,33538,20882,24125,35980,36152,20040,29611,26522,
+26757,37238,38665,29028,27809,30473,23186,38209,27599,32654,26151,23504,22969,
+23194,38376,38391,20204,33804,33945,27308,30431,38192,29467,26790,23391,30511,
+37274,38753,31964,36855,35868,24357,31859,31192,35269,27852,34588,23494,24130,
+26825,30496,32501,20885,20813,21193,23081,32517,38754,33495,25551,30596,34256,
+31186,28218,24217,22937,34065,28781,27665,25279,30399,25935,24751,38397,26126,
+34719,40483,38125,21517,21629,35884,25720,33088,33089,33090,33091,33092,33093,
+33095,33097,33101,33102,33103,33106,33110,33111,33112,33115,33116,33117,33118,
+33119,33121,33122,33123,33124,33126,33128,33130,33131,33132,33135,33138,33139,
+33141,33142,33143,33144,33153,33155,33156,33157,33158,33159,33161,33163,33164,
+33165,33166,33168,33170,33171,33172,33173,33174,33175,33177,33178,33182,33183,
+33184,33185,33186,33188,33189,33191,33193,33195,33196,33197,33198,33199,33200,
+33201,33202,33204,33205,33206,33207,33208,33209,33212,33213,33214,33215,33220,
+33221,33223,33224,33225,33227,33229,33230,33231,33232,33233,33234,33235,25721,
+34321,27169,33180,30952,25705,39764,25273,26411,33707,22696,40664,27819,28448,
+23518,38476,35851,29279,26576,25287,29281,20137,22982,27597,22675,26286,24149,
+21215,24917,26408,30446,30566,29287,31302,25343,21738,21584,38048,37027,23068,
+32435,27670,20035,22902,32784,22856,21335,30007,38590,22218,25376,33041,24700,
+38393,28118,21602,39297,20869,23273,33021,22958,38675,20522,27877,23612,25311,
+20320,21311,33147,36870,28346,34091,25288,24180,30910,25781,25467,24565,23064,
+37247,40479,23615,25423,32834,23421,21870,38218,38221,28037,24744,26592,29406,
+20957,23425,33236,33237,33238,33239,33240,33241,33242,33243,33244,33245,33246,
+33247,33248,33249,33250,33252,33253,33254,33256,33257,33259,33262,33263,33264,
+33265,33266,33269,33270,33271,33272,33273,33274,33277,33279,33283,33287,33288,
+33289,33290,33291,33294,33295,33297,33299,33301,33302,33303,33304,33305,33306,
+33309,33312,33316,33317,33318,33319,33321,33326,33330,33338,33340,33341,33343,
+33344,33345,33346,33347,33349,33350,33352,33354,33356,33357,33358,33360,33361,
+33362,33363,33364,33365,33366,33367,33369,33371,33372,33373,33374,33376,33377,
+33378,33379,33380,33381,33382,33383,33385,25319,27870,29275,25197,38062,32445,
+33043,27987,20892,24324,22900,21162,24594,22899,26262,34384,30111,25386,25062,
+31983,35834,21734,27431,40485,27572,34261,21589,20598,27812,21866,36276,29228,
+24085,24597,29750,25293,25490,29260,24472,28227,27966,25856,28504,30424,30928,
+30460,30036,21028,21467,20051,24222,26049,32810,32982,25243,21638,21032,28846,
+34957,36305,27873,21624,32986,22521,35060,36180,38506,37197,20329,27803,21943,
+30406,30768,25256,28921,28558,24429,34028,26842,30844,31735,33192,26379,40527,
+25447,30896,22383,30738,38713,25209,25259,21128,29749,27607,33386,33387,33388,
+33389,33393,33397,33398,33399,33400,33403,33404,33408,33409,33411,33413,33414,
+33415,33417,33420,33424,33427,33428,33429,33430,33434,33435,33438,33440,33442,
+33443,33447,33458,33461,33462,33466,33467,33468,33471,33472,33474,33475,33477,
+33478,33481,33488,33494,33497,33498,33501,33506,33511,33512,33513,33514,33516,
+33517,33518,33520,33522,33523,33525,33526,33528,33530,33532,33533,33534,33535,
+33536,33546,33547,33549,33552,33554,33555,33558,33560,33561,33565,33566,33567,
+33568,33569,33570,33571,33572,33573,33574,33577,33578,33582,33584,33586,33591,
+33595,33597,21860,33086,30130,30382,21305,30174,20731,23617,35692,31687,20559,
+29255,39575,39128,28418,29922,31080,25735,30629,25340,39057,36139,21697,32856,
+20050,22378,33529,33805,24179,20973,29942,35780,23631,22369,27900,39047,23110,
+30772,39748,36843,31893,21078,25169,38138,20166,33670,33889,33769,33970,22484,
+26420,22275,26222,28006,35889,26333,28689,26399,27450,26646,25114,22971,19971,
+20932,28422,26578,27791,20854,26827,22855,27495,30054,23822,33040,40784,26071,
+31048,31041,39569,36215,23682,20062,20225,21551,22865,30732,22120,27668,36804,
+24323,27773,27875,35755,25488,33598,33599,33601,33602,33604,33605,33608,33610,
+33611,33612,33613,33614,33619,33621,33622,33623,33624,33625,33629,33634,33648,
+33649,33650,33651,33652,33653,33654,33657,33658,33662,33663,33664,33665,33666,
+33667,33668,33671,33672,33674,33675,33676,33677,33679,33680,33681,33684,33685,
+33686,33687,33689,33690,33693,33695,33697,33698,33699,33700,33701,33702,33703,
+33708,33709,33710,33711,33717,33723,33726,33727,33730,33731,33732,33734,33736,
+33737,33739,33741,33742,33744,33745,33746,33747,33749,33751,33753,33754,33755,
+33758,33762,33763,33764,33766,33767,33768,33771,33772,33773,24688,27965,29301,
+25190,38030,38085,21315,36801,31614,20191,35878,20094,40660,38065,38067,21069,
+28508,36963,27973,35892,22545,23884,27424,27465,26538,21595,33108,32652,22681,
+34103,24378,25250,27207,38201,25970,24708,26725,30631,20052,20392,24039,38808,
+25772,32728,23789,20431,31373,20999,33540,19988,24623,31363,38054,20405,20146,
+31206,29748,21220,33465,25810,31165,23517,27777,38738,36731,27682,20542,21375,
+28165,25806,26228,27696,24773,39031,35831,24198,29756,31351,31179,19992,37041,
+29699,27714,22234,37195,27845,36235,21306,34502,26354,36527,23624,39537,28192,
+33774,33775,33779,33780,33781,33782,33783,33786,33787,33788,33790,33791,33792,
+33794,33797,33799,33800,33801,33802,33808,33810,33811,33812,33813,33814,33815,
+33817,33818,33819,33822,33823,33824,33825,33826,33827,33833,33834,33835,33836,
+33837,33838,33839,33840,33842,33843,33844,33845,33846,33847,33849,33850,33851,
+33854,33855,33856,33857,33858,33859,33860,33861,33863,33864,33865,33866,33867,
+33868,33869,33870,33871,33872,33874,33875,33876,33877,33878,33880,33885,33886,
+33887,33888,33890,33892,33893,33894,33895,33896,33898,33902,33903,33904,33906,
+33908,33911,33913,33915,33916,21462,23094,40843,36259,21435,22280,39079,26435,
+37275,27849,20840,30154,25331,29356,21048,21149,32570,28820,30264,21364,40522,
+27063,30830,38592,35033,32676,28982,29123,20873,26579,29924,22756,25880,22199,
+35753,39286,25200,32469,24825,28909,22764,20161,20154,24525,38887,20219,35748,
+20995,22922,32427,25172,20173,26085,25102,33592,33993,33635,34701,29076,28342,
+23481,32466,20887,25545,26580,32905,33593,34837,20754,23418,22914,36785,20083,
+27741,20837,35109,36719,38446,34122,29790,38160,38384,28070,33509,24369,25746,
+27922,33832,33134,40131,22622,36187,19977,21441,33917,33918,33919,33920,33921,
+33923,33924,33925,33926,33930,33933,33935,33936,33937,33938,33939,33940,33941,
+33942,33944,33946,33947,33949,33950,33951,33952,33954,33955,33956,33957,33958,
+33959,33960,33961,33962,33963,33964,33965,33966,33968,33969,33971,33973,33974,
+33975,33979,33980,33982,33984,33986,33987,33989,33990,33991,33992,33995,33996,
+33998,33999,34002,34004,34005,34007,34008,34009,34010,34011,34012,34014,34017,
+34018,34020,34023,34024,34025,34026,34027,34029,34030,34031,34033,34034,34035,
+34036,34037,34038,34039,34040,34041,34042,34043,34045,34046,34048,34049,34050,
+20254,25955,26705,21971,20007,25620,39578,25195,23234,29791,33394,28073,26862,
+20711,33678,30722,26432,21049,27801,32433,20667,21861,29022,31579,26194,29642,
+33515,26441,23665,21024,29053,34923,38378,38485,25797,36193,33203,21892,27733,
+25159,32558,22674,20260,21830,36175,26188,19978,23578,35059,26786,25422,31245,
+28903,33421,21242,38902,23569,21736,37045,32461,22882,36170,34503,33292,33293,
+36198,25668,23556,24913,28041,31038,35774,30775,30003,21627,20280,36523,28145,
+23072,32453,31070,27784,23457,23158,29978,32958,24910,28183,22768,29983,29989,
+29298,21319,32499,34051,34052,34053,34054,34055,34056,34057,34058,34059,34061,
+34062,34063,34064,34066,34068,34069,34070,34072,34073,34075,34076,34077,34078,
+34080,34082,34083,34084,34085,34086,34087,34088,34089,34090,34093,34094,34095,
+34096,34097,34098,34099,34100,34101,34102,34110,34111,34112,34113,34114,34116,
+34117,34118,34119,34123,34124,34125,34126,34127,34128,34129,34130,34131,34132,
+34133,34135,34136,34138,34139,34140,34141,34143,34144,34145,34146,34147,34149,
+34150,34151,34153,34154,34155,34156,34157,34158,34159,34160,34161,34163,34165,
+34166,34167,34168,34172,34173,34175,34176,34177,30465,30427,21097,32988,22307,
+24072,22833,29422,26045,28287,35799,23608,34417,21313,30707,25342,26102,20160,
+39135,34432,23454,35782,21490,30690,20351,23630,39542,22987,24335,31034,22763,
+19990,26623,20107,25325,35475,36893,21183,26159,21980,22124,36866,20181,20365,
+37322,39280,27663,24066,24643,23460,35270,35797,25910,25163,39318,23432,23551,
+25480,21806,21463,30246,20861,34092,26530,26803,27530,25234,36755,21460,33298,
+28113,30095,20070,36174,23408,29087,34223,26257,26329,32626,34560,40653,40736,
+23646,26415,36848,26641,26463,25101,31446,22661,24246,25968,28465,34178,34179,
+34182,34184,34185,34186,34187,34188,34189,34190,34192,34193,34194,34195,34196,
+34197,34198,34199,34200,34201,34202,34205,34206,34207,34208,34209,34210,34211,
+34213,34214,34215,34217,34219,34220,34221,34225,34226,34227,34228,34229,34230,
+34232,34234,34235,34236,34237,34238,34239,34240,34242,34243,34244,34245,34246,
+34247,34248,34250,34251,34252,34253,34254,34257,34258,34260,34262,34263,34264,
+34265,34266,34267,34269,34270,34271,34272,34273,34274,34275,34277,34278,34279,
+34280,34282,34283,34284,34285,34286,34287,34288,34289,34290,34291,34292,34293,
+34294,34295,34296,24661,21047,32781,25684,34928,29993,24069,26643,25332,38684,
+21452,29245,35841,27700,30561,31246,21550,30636,39034,33308,35828,30805,26388,
+28865,26031,25749,22070,24605,31169,21496,19997,27515,32902,23546,21987,22235,
+20282,20284,39282,24051,26494,32824,24578,39042,36865,23435,35772,35829,25628,
+33368,25822,22013,33487,37221,20439,32032,36895,31903,20723,22609,28335,23487,
+35785,32899,37240,33948,31639,34429,38539,38543,32485,39635,30862,23681,31319,
+36930,38567,31071,23385,25439,31499,34001,26797,21766,32553,29712,32034,38145,
+25152,22604,20182,23427,22905,22612,34297,34298,34300,34301,34302,34304,34305,
+34306,34307,34308,34310,34311,34312,34313,34314,34315,34316,34317,34318,34319,
+34320,34322,34323,34324,34325,34327,34328,34329,34330,34331,34332,34333,34334,
+34335,34336,34337,34338,34339,34340,34341,34342,34344,34346,34347,34348,34349,
+34350,34351,34352,34353,34354,34355,34356,34357,34358,34359,34361,34362,34363,
+34365,34366,34367,34368,34369,34370,34371,34372,34373,34374,34375,34376,34377,
+34378,34379,34380,34386,34387,34389,34390,34391,34392,34393,34395,34396,34397,
+34399,34400,34401,34403,34404,34405,34406,34407,34408,34409,34410,29549,25374,
+36427,36367,32974,33492,25260,21488,27888,37214,22826,24577,27760,22349,25674,
+36138,30251,28393,22363,27264,30192,28525,35885,35848,22374,27631,34962,30899,
+25506,21497,28845,27748,22616,25642,22530,26848,33179,21776,31958,20504,36538,
+28108,36255,28907,25487,28059,28372,32486,33796,26691,36867,28120,38518,35752,
+22871,29305,34276,33150,30140,35466,26799,21076,36386,38161,25552,39064,36420,
+21884,20307,26367,22159,24789,28053,21059,23625,22825,28155,22635,30000,29980,
+24684,33300,33094,25361,26465,36834,30522,36339,36148,38081,24086,21381,21548,
+28867,34413,34415,34416,34418,34419,34420,34421,34422,34423,34424,34435,34436,
+34437,34438,34439,34440,34441,34446,34447,34448,34449,34450,34452,34454,34455,
+34456,34457,34458,34459,34462,34463,34464,34465,34466,34469,34470,34475,34477,
+34478,34482,34483,34487,34488,34489,34491,34492,34493,34494,34495,34497,34498,
+34499,34501,34504,34508,34509,34514,34515,34517,34518,34519,34522,34524,34525,
+34528,34529,34530,34531,34533,34534,34535,34536,34538,34539,34540,34543,34549,
+34550,34551,34554,34555,34556,34557,34559,34561,34564,34565,34566,34571,34572,
+34574,34575,34576,34577,34580,34582,27712,24311,20572,20141,24237,25402,33351,
+36890,26704,37230,30643,21516,38108,24420,31461,26742,25413,31570,32479,30171,
+20599,25237,22836,36879,20984,31171,31361,22270,24466,36884,28034,23648,22303,
+21520,20820,28237,22242,25512,39059,33151,34581,35114,36864,21534,23663,33216,
+25302,25176,33073,40501,38464,39534,39548,26925,22949,25299,21822,25366,21703,
+34521,27964,23043,29926,34972,27498,22806,35916,24367,28286,29609,39037,20024,
+28919,23436,30871,25405,26202,30358,24779,23451,23113,19975,33109,27754,29579,
+20129,26505,32593,24448,26106,26395,24536,22916,23041,34585,34587,34589,34591,
+34592,34596,34598,34599,34600,34602,34603,34604,34605,34607,34608,34610,34611,
+34613,34614,34616,34617,34618,34620,34621,34624,34625,34626,34627,34628,34629,
+34630,34634,34635,34637,34639,34640,34641,34642,34644,34645,34646,34648,34650,
+34651,34652,34653,34654,34655,34657,34658,34662,34663,34664,34665,34666,34667,
+34668,34669,34671,34673,34674,34675,34677,34679,34680,34681,34682,34687,34688,
+34689,34692,34694,34695,34697,34698,34700,34702,34703,34704,34705,34706,34708,
+34709,34710,34712,34713,34714,34715,34716,34717,34718,34720,34721,34722,34723,
+34724,24013,24494,21361,38886,36829,26693,22260,21807,24799,20026,28493,32500,
+33479,33806,22996,20255,20266,23614,32428,26410,34074,21619,30031,32963,21890,
+39759,20301,28205,35859,23561,24944,21355,30239,28201,34442,25991,38395,32441,
+21563,31283,32010,38382,21985,32705,29934,25373,34583,28065,31389,25105,26017,
+21351,25569,27779,24043,21596,38056,20044,27745,35820,23627,26080,33436,26791,
+21566,21556,27595,27494,20116,25410,21320,33310,20237,20398,22366,25098,38654,
+26212,29289,21247,21153,24735,35823,26132,29081,26512,35199,30802,30717,26224,
+22075,21560,38177,29306,34725,34726,34727,34729,34730,34734,34736,34737,34738,
+34740,34742,34743,34744,34745,34747,34748,34750,34751,34753,34754,34755,34756,
+34757,34759,34760,34761,34764,34765,34766,34767,34768,34772,34773,34774,34775,
+34776,34777,34778,34780,34781,34782,34783,34785,34786,34787,34788,34790,34791,
+34792,34793,34795,34796,34797,34799,34800,34801,34802,34803,34804,34805,34806,
+34807,34808,34810,34811,34812,34813,34815,34816,34817,34818,34820,34821,34822,
+34823,34824,34825,34827,34828,34829,34830,34831,34832,34833,34834,34836,34839,
+34840,34841,34842,34844,34845,34846,34847,34848,34851,31232,24687,24076,24713,
+33181,22805,24796,29060,28911,28330,27728,29312,27268,34989,24109,20064,23219,
+21916,38115,27927,31995,38553,25103,32454,30606,34430,21283,38686,36758,26247,
+23777,20384,29421,19979,21414,22799,21523,25472,38184,20808,20185,40092,32420,
+21688,36132,34900,33335,38386,28046,24358,23244,26174,38505,29616,29486,21439,
+33146,39301,32673,23466,38519,38480,32447,30456,21410,38262,39321,31665,35140,
+28248,20065,32724,31077,35814,24819,21709,20139,39033,24055,27233,20687,21521,
+35937,33831,30813,38660,21066,21742,22179,38144,28040,23477,28102,26195,34852,
+34853,34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,
+34867,34868,34869,34870,34871,34872,34874,34875,34877,34878,34879,34881,34882,
+34883,34886,34887,34888,34889,34890,34891,34894,34895,34896,34897,34898,34899,
+34901,34902,34904,34906,34907,34908,34909,34910,34911,34912,34918,34919,34922,
+34925,34927,34929,34931,34932,34933,34934,34936,34937,34938,34939,34940,34944,
+34947,34950,34951,34953,34954,34956,34958,34959,34960,34961,34963,34964,34965,
+34967,34968,34969,34970,34971,34973,34974,34975,34976,34977,34979,34981,34982,
+34983,34984,34985,34986,23567,23389,26657,32918,21880,31505,25928,26964,20123,
+27463,34638,38795,21327,25375,25658,37034,26012,32961,35856,20889,26800,21368,
+34809,25032,27844,27899,35874,23633,34218,33455,38156,27427,36763,26032,24571,
+24515,20449,34885,26143,33125,29481,24826,20852,21009,22411,24418,37026,34892,
+37266,24184,26447,24615,22995,20804,20982,33016,21256,27769,38596,29066,20241,
+20462,32670,26429,21957,38152,31168,34966,32483,22687,25100,38656,34394,22040,
+39035,24464,35768,33988,37207,21465,26093,24207,30044,24676,32110,23167,32490,
+32493,36713,21927,23459,24748,26059,29572,34988,34990,34991,34992,34994,34995,
+34996,34997,34998,35000,35001,35002,35003,35005,35006,35007,35008,35011,35012,
+35015,35016,35018,35019,35020,35021,35023,35024,35025,35027,35030,35031,35034,
+35035,35036,35037,35038,35040,35041,35046,35047,35049,35050,35051,35052,35053,
+35054,35055,35058,35061,35062,35063,35066,35067,35069,35071,35072,35073,35075,
+35076,35077,35078,35079,35080,35081,35083,35084,35085,35086,35087,35089,35092,
+35093,35094,35095,35096,35100,35101,35102,35103,35104,35106,35107,35108,35110,
+35111,35112,35113,35116,35117,35118,35119,35121,35122,35123,35125,35127,36873,
+30307,30505,32474,38772,34203,23398,31348,38634,34880,21195,29071,24490,26092,
+35810,23547,39535,24033,27529,27739,35757,35759,36874,36805,21387,25276,40486,
+40493,21568,20011,33469,29273,34460,23830,34905,28079,38597,21713,20122,35766,
+28937,21693,38409,28895,28153,30416,20005,30740,34578,23721,24310,35328,39068,
+38414,28814,27839,22852,25513,30524,34893,28436,33395,22576,29141,21388,30746,
+38593,21761,24422,28976,23476,35866,39564,27523,22830,40495,31207,26472,25196,
+20335,30113,32650,27915,38451,27687,20208,30162,20859,26679,28478,36992,33136,
+22934,29814,35128,35129,35130,35131,35132,35133,35134,35135,35136,35138,35139,
+35141,35142,35143,35144,35145,35146,35147,35148,35149,35150,35151,35152,35153,
+35154,35155,35156,35157,35158,35159,35160,35161,35162,35163,35164,35165,35168,
+35169,35170,35171,35172,35173,35175,35176,35177,35178,35179,35180,35181,35182,
+35183,35184,35185,35186,35187,35188,35189,35190,35191,35192,35193,35194,35196,
+35197,35198,35200,35202,35204,35205,35207,35208,35209,35210,35211,35212,35213,
+35214,35215,35216,35217,35218,35219,35220,35221,35222,35223,35224,35225,35226,
+35227,35228,35229,35230,35231,35232,35233,25671,23591,36965,31377,35875,23002,
+21676,33280,33647,35201,32768,26928,22094,32822,29239,37326,20918,20063,39029,
+25494,19994,21494,26355,33099,22812,28082,19968,22777,21307,25558,38129,20381,
+20234,34915,39056,22839,36951,31227,20202,33008,30097,27778,23452,23016,24413,
+26885,34433,20506,24050,20057,30691,20197,33402,25233,26131,37009,23673,20159,
+24441,33222,36920,32900,30123,20134,35028,24847,27589,24518,20041,30410,28322,
+35811,35758,35850,35793,24322,32764,32716,32462,33589,33643,22240,27575,38899,
+38452,23035,21535,38134,28139,23493,39278,23609,24341,38544,35234,35235,35236,
+35237,35238,35239,35240,35241,35242,35243,35244,35245,35246,35247,35248,35249,
+35250,35251,35252,35253,35254,35255,35256,35257,35258,35259,35260,35261,35262,
+35263,35264,35267,35277,35283,35284,35285,35287,35288,35289,35291,35293,35295,
+35296,35297,35298,35300,35303,35304,35305,35306,35308,35309,35310,35312,35313,
+35314,35316,35317,35318,35319,35320,35321,35322,35323,35324,35325,35326,35327,
+35329,35330,35331,35332,35333,35334,35336,35337,35338,35339,35340,35341,35342,
+35343,35344,35345,35346,35347,35348,35349,35350,35351,35352,35353,35354,35355,
+35356,35357,21360,33521,27185,23156,40560,24212,32552,33721,33828,33829,33639,
+34631,36814,36194,30408,24433,39062,30828,26144,21727,25317,20323,33219,30152,
+24248,38605,36362,34553,21647,27891,28044,27704,24703,21191,29992,24189,20248,
+24736,24551,23588,30001,37038,38080,29369,27833,28216,37193,26377,21451,21491,
+20305,37321,35825,21448,24188,36802,28132,20110,30402,27014,34398,24858,33286,
+20313,20446,36926,40060,24841,28189,28180,38533,20104,23089,38632,19982,23679,
+31161,23431,35821,32701,29577,22495,33419,37057,21505,36935,21947,23786,24481,
+24840,27442,29425,32946,35465,35358,35359,35360,35361,35362,35363,35364,35365,
+35366,35367,35368,35369,35370,35371,35372,35373,35374,35375,35376,35377,35378,
+35379,35380,35381,35382,35383,35384,35385,35386,35387,35388,35389,35391,35392,
+35393,35394,35395,35396,35397,35398,35399,35401,35402,35403,35404,35405,35406,
+35407,35408,35409,35410,35411,35412,35413,35414,35415,35416,35417,35418,35419,
+35420,35421,35422,35423,35424,35425,35426,35427,35428,35429,35430,35431,35432,
+35433,35434,35435,35436,35437,35438,35439,35440,35441,35442,35443,35444,35445,
+35446,35447,35448,35450,35451,35452,35453,35454,35455,35456,28020,23507,35029,
+39044,35947,39533,40499,28170,20900,20803,22435,34945,21407,25588,36757,22253,
+21592,22278,29503,28304,32536,36828,33489,24895,24616,38498,26352,32422,36234,
+36291,38053,23731,31908,26376,24742,38405,32792,20113,37095,21248,38504,20801,
+36816,34164,37213,26197,38901,23381,21277,30776,26434,26685,21705,28798,23472,
+36733,20877,22312,21681,25874,26242,36190,36163,33039,33900,36973,31967,20991,
+34299,26531,26089,28577,34468,36481,22122,36896,30338,28790,29157,36131,25321,
+21017,27901,36156,24590,22686,24974,26366,36192,25166,21939,28195,26413,36711,
+35457,35458,35459,35460,35461,35462,35463,35464,35467,35468,35469,35470,35471,
+35472,35473,35474,35476,35477,35478,35479,35480,35481,35482,35483,35484,35485,
+35486,35487,35488,35489,35490,35491,35492,35493,35494,35495,35496,35497,35498,
+35499,35500,35501,35502,35503,35504,35505,35506,35507,35508,35509,35510,35511,
+35512,35513,35514,35515,35516,35517,35518,35519,35520,35521,35522,35523,35524,
+35525,35526,35527,35528,35529,35530,35531,35532,35533,35534,35535,35536,35537,
+35538,35539,35540,35541,35542,35543,35544,35545,35546,35547,35548,35549,35550,
+35551,35552,35553,35554,35555,38113,38392,30504,26629,27048,21643,20045,28856,
+35784,25688,25995,23429,31364,20538,23528,30651,27617,35449,31896,27838,30415,
+26025,36759,23853,23637,34360,26632,21344,25112,31449,28251,32509,27167,31456,
+24432,28467,24352,25484,28072,26454,19976,24080,36134,20183,32960,30260,38556,
+25307,26157,25214,27836,36213,29031,32617,20806,32903,21484,36974,25240,21746,
+34544,36761,32773,38167,34071,36825,27993,29645,26015,30495,29956,30759,33275,
+36126,38024,20390,26517,30137,35786,38663,25391,38215,38453,33976,25379,30529,
+24449,29424,20105,24596,25972,25327,27491,25919,35556,35557,35558,35559,35560,
+35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,
+35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,35585,35586,
+35587,35588,35589,35590,35592,35593,35594,35595,35596,35597,35598,35599,35600,
+35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,35612,35613,
+35614,35615,35616,35617,35618,35619,35620,35621,35623,35624,35625,35626,35627,
+35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,35639,35640,
+35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,35652,35653,
+24103,30151,37073,35777,33437,26525,25903,21553,34584,30693,32930,33026,27713,
+20043,32455,32844,30452,26893,27542,25191,20540,20356,22336,25351,27490,36286,
+21482,26088,32440,24535,25370,25527,33267,33268,32622,24092,23769,21046,26234,
+31209,31258,36136,28825,30164,28382,27835,31378,20013,30405,24544,38047,34935,
+32456,31181,32959,37325,20210,20247,33311,21608,24030,27954,35788,31909,36724,
+32920,24090,21650,30385,23449,26172,39588,29664,26666,34523,26417,29482,35832,
+35803,36880,31481,28891,29038,25284,30633,22065,20027,33879,26609,21161,34496,
+36142,38136,31569,35654,35655,35656,35657,35658,35659,35660,35661,35662,35663,
+35664,35665,35666,35667,35668,35669,35670,35671,35672,35673,35674,35675,35676,
+35677,35678,35679,35680,35681,35682,35683,35684,35685,35687,35688,35689,35690,
+35691,35693,35694,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,
+35705,35706,35707,35708,35709,35710,35711,35712,35713,35714,35715,35716,35717,
+35718,35719,35720,35721,35722,35723,35724,35725,35726,35727,35728,35729,35730,
+35731,35732,35733,35734,35735,35736,35737,35738,35739,35740,35741,35742,35743,
+35756,35761,35771,35783,35792,35818,35849,35870,20303,27880,31069,39547,25235,
+29226,25341,19987,30742,36716,25776,36186,31686,26729,24196,35013,22918,25758,
+22766,29366,26894,38181,36861,36184,22368,32512,35846,20934,25417,25305,21331,
+26700,29730,33537,37196,21828,30528,28796,27978,20857,21672,36164,23039,28363,
+28100,23388,32043,20180,31869,28371,23376,33258,28173,23383,39683,26837,36394,
+23447,32508,24635,32437,37049,36208,22863,25549,31199,36275,21330,26063,31062,
+35781,38459,32452,38075,32386,22068,37257,26368,32618,23562,36981,26152,24038,
+20304,26590,20570,20316,22352,24231,59408,59409,59410,59411,59412,35896,35897,
+35898,35899,35900,35901,35902,35903,35904,35906,35907,35908,35909,35912,35914,
+35915,35917,35918,35919,35920,35921,35922,35923,35924,35926,35927,35928,35929,
+35931,35932,35933,35934,35935,35936,35939,35940,35941,35942,35943,35944,35945,
+35948,35949,35950,35951,35952,35953,35954,35956,35957,35958,35959,35963,35964,
+35965,35966,35967,35968,35969,35971,35972,35974,35975,35976,35979,35981,35982,
+35983,35984,35985,35986,35987,35989,35990,35991,35993,35994,35995,35996,35997,
+35998,35999,36000,36001,36002,36003,36004,36005,36006,36007,36008,36009,36010,
+36011,36012,36013,20109,19980,20800,19984,24319,21317,19989,20120,19998,39730,
+23404,22121,20008,31162,20031,21269,20039,22829,29243,21358,27664,22239,32996,
+39319,27603,30590,40727,20022,20127,40720,20060,20073,20115,33416,23387,21868,
+22031,20164,21389,21405,21411,21413,21422,38757,36189,21274,21493,21286,21294,
+21310,36188,21350,21347,20994,21000,21006,21037,21043,21055,21056,21068,21086,
+21089,21084,33967,21117,21122,21121,21136,21139,20866,32596,20155,20163,20169,
+20162,20200,20193,20203,20190,20251,20211,20258,20324,20213,20261,20263,20233,
+20267,20318,20327,25912,20314,20317,36014,36015,36016,36017,36018,36019,36020,
+36021,36022,36023,36024,36025,36026,36027,36028,36029,36030,36031,36032,36033,
+36034,36035,36036,36037,36038,36039,36040,36041,36042,36043,36044,36045,36046,
+36047,36048,36049,36050,36051,36052,36053,36054,36055,36056,36057,36058,36059,
+36060,36061,36062,36063,36064,36065,36066,36067,36068,36069,36070,36071,36072,
+36073,36074,36075,36076,36077,36078,36079,36080,36081,36082,36083,36084,36085,
+36086,36087,36088,36089,36090,36091,36092,36093,36094,36095,36096,36097,36098,
+36099,36100,36101,36102,36103,36104,36105,36106,36107,36108,36109,20319,20311,
+20274,20285,20342,20340,20369,20361,20355,20367,20350,20347,20394,20348,20396,
+20372,20454,20456,20458,20421,20442,20451,20444,20433,20447,20472,20521,20556,
+20467,20524,20495,20526,20525,20478,20508,20492,20517,20520,20606,20547,20565,
+20552,20558,20588,20603,20645,20647,20649,20666,20694,20742,20717,20716,20710,
+20718,20743,20747,20189,27709,20312,20325,20430,40864,27718,31860,20846,24061,
+40649,39320,20865,22804,21241,21261,35335,21264,20971,22809,20821,20128,20822,
+20147,34926,34980,20149,33044,35026,31104,23348,34819,32696,20907,20913,20925,
+20924,36110,36111,36112,36113,36114,36115,36116,36117,36118,36119,36120,36121,
+36122,36123,36124,36128,36177,36178,36183,36191,36197,36200,36201,36202,36204,
+36206,36207,36209,36210,36216,36217,36218,36219,36220,36221,36222,36223,36224,
+36226,36227,36230,36231,36232,36233,36236,36237,36238,36239,36240,36242,36243,
+36245,36246,36247,36248,36249,36250,36251,36252,36253,36254,36256,36257,36258,
+36260,36261,36262,36263,36264,36265,36266,36267,36268,36269,36270,36271,36272,
+36274,36278,36279,36281,36283,36285,36288,36289,36290,36293,36295,36296,36297,
+36298,36301,36304,36306,36307,36308,20935,20886,20898,20901,35744,35750,35751,
+35754,35764,35765,35767,35778,35779,35787,35791,35790,35794,35795,35796,35798,
+35800,35801,35804,35807,35808,35812,35816,35817,35822,35824,35827,35830,35833,
+35836,35839,35840,35842,35844,35847,35852,35855,35857,35858,35860,35861,35862,
+35865,35867,35864,35869,35871,35872,35873,35877,35879,35882,35883,35886,35887,
+35890,35891,35893,35894,21353,21370,38429,38434,38433,38449,38442,38461,38460,
+38466,38473,38484,38495,38503,38508,38514,38516,38536,38541,38551,38576,37015,
+37019,37021,37017,37036,37025,37044,37043,37046,37050,36309,36312,36313,36316,
+36320,36321,36322,36325,36326,36327,36329,36333,36334,36336,36337,36338,36340,
+36342,36348,36350,36351,36352,36353,36354,36355,36356,36358,36359,36360,36363,
+36365,36366,36368,36369,36370,36371,36373,36374,36375,36376,36377,36378,36379,
+36380,36384,36385,36388,36389,36390,36391,36392,36395,36397,36400,36402,36403,
+36404,36406,36407,36408,36411,36412,36414,36415,36419,36421,36422,36428,36429,
+36430,36431,36432,36435,36436,36437,36438,36439,36440,36442,36443,36444,36445,
+36446,36447,36448,36449,36450,36451,36452,36453,36455,36456,36458,36459,36462,
+36465,37048,37040,37071,37061,37054,37072,37060,37063,37075,37094,37090,37084,
+37079,37083,37099,37103,37118,37124,37154,37150,37155,37169,37167,37177,37187,
+37190,21005,22850,21154,21164,21165,21182,21759,21200,21206,21232,21471,29166,
+30669,24308,20981,20988,39727,21430,24321,30042,24047,22348,22441,22433,22654,
+22716,22725,22737,22313,22316,22314,22323,22329,22318,22319,22364,22331,22338,
+22377,22405,22379,22406,22396,22395,22376,22381,22390,22387,22445,22436,22412,
+22450,22479,22439,22452,22419,22432,22485,22488,22490,22489,22482,22456,22516,
+22511,22520,22500,22493,36467,36469,36471,36472,36473,36474,36475,36477,36478,
+36480,36482,36483,36484,36486,36488,36489,36490,36491,36492,36493,36494,36497,
+36498,36499,36501,36502,36503,36504,36505,36506,36507,36509,36511,36512,36513,
+36514,36515,36516,36517,36518,36519,36520,36521,36522,36525,36526,36528,36529,
+36531,36532,36533,36534,36535,36536,36537,36539,36540,36541,36542,36543,36544,
+36545,36546,36547,36548,36549,36550,36551,36552,36553,36554,36555,36556,36557,
+36559,36560,36561,36562,36563,36564,36565,36566,36567,36568,36569,36570,36571,
+36572,36573,36574,36575,36576,36577,36578,36579,36580,22539,22541,22525,22509,
+22528,22558,22553,22596,22560,22629,22636,22657,22665,22682,22656,39336,40729,
+25087,33401,33405,33407,33423,33418,33448,33412,33422,33425,33431,33433,33451,
+33464,33470,33456,33480,33482,33507,33432,33463,33454,33483,33484,33473,33449,
+33460,33441,33450,33439,33476,33486,33444,33505,33545,33527,33508,33551,33543,
+33500,33524,33490,33496,33548,33531,33491,33553,33562,33542,33556,33557,33504,
+33493,33564,33617,33627,33628,33544,33682,33596,33588,33585,33691,33630,33583,
+33615,33607,33603,33631,33600,33559,33632,33581,33594,33587,33638,33637,36581,
+36582,36583,36584,36585,36586,36587,36588,36589,36590,36591,36592,36593,36594,
+36595,36596,36597,36598,36599,36600,36601,36602,36603,36604,36605,36606,36607,
+36608,36609,36610,36611,36612,36613,36614,36615,36616,36617,36618,36619,36620,
+36621,36622,36623,36624,36625,36626,36627,36628,36629,36630,36631,36632,36633,
+36634,36635,36636,36637,36638,36639,36640,36641,36642,36643,36644,36645,36646,
+36647,36648,36649,36650,36651,36652,36653,36654,36655,36656,36657,36658,36659,
+36660,36661,36662,36663,36664,36665,36666,36667,36668,36669,36670,36671,36672,
+36673,36674,36675,36676,33640,33563,33641,33644,33642,33645,33646,33712,33656,
+33715,33716,33696,33706,33683,33692,33669,33660,33718,33705,33661,33720,33659,
+33688,33694,33704,33722,33724,33729,33793,33765,33752,22535,33816,33803,33757,
+33789,33750,33820,33848,33809,33798,33748,33759,33807,33795,33784,33785,33770,
+33733,33728,33830,33776,33761,33884,33873,33882,33881,33907,33927,33928,33914,
+33929,33912,33852,33862,33897,33910,33932,33934,33841,33901,33985,33997,34000,
+34022,33981,34003,33994,33983,33978,34016,33953,33977,33972,33943,34021,34019,
+34060,29965,34104,34032,34105,34079,34106,36677,36678,36679,36680,36681,36682,
+36683,36684,36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,
+36696,36697,36698,36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,
+36709,36714,36736,36748,36754,36765,36768,36769,36770,36772,36773,36774,36775,
+36778,36780,36781,36782,36783,36786,36787,36788,36789,36791,36792,36794,36795,
+36796,36799,36800,36803,36806,36809,36810,36811,36812,36813,36815,36818,36822,
+36823,36826,36832,36833,36835,36839,36844,36847,36849,36850,36852,36853,36854,
+36858,36859,36860,36862,36863,36871,36872,36876,36878,36883,36885,36888,34134,
+34107,34047,34044,34137,34120,34152,34148,34142,34170,30626,34115,34162,34171,
+34212,34216,34183,34191,34169,34222,34204,34181,34233,34231,34224,34259,34241,
+34268,34303,34343,34309,34345,34326,34364,24318,24328,22844,22849,32823,22869,
+22874,22872,21263,23586,23589,23596,23604,25164,25194,25247,25275,25290,25306,
+25303,25326,25378,25334,25401,25419,25411,25517,25590,25457,25466,25486,25524,
+25453,25516,25482,25449,25518,25532,25586,25592,25568,25599,25540,25566,25550,
+25682,25542,25534,25669,25665,25611,25627,25632,25612,25638,25633,25694,25732,
+25709,25750,36889,36892,36899,36900,36901,36903,36904,36905,36906,36907,36908,
+36912,36913,36914,36915,36916,36919,36921,36922,36925,36927,36928,36931,36933,
+36934,36936,36937,36938,36939,36940,36942,36948,36949,36950,36953,36954,36956,
+36957,36958,36959,36960,36961,36964,36966,36967,36969,36970,36971,36972,36975,
+36976,36977,36978,36979,36982,36983,36984,36985,36986,36987,36988,36990,36993,
+36996,36997,36998,36999,37001,37002,37004,37005,37006,37007,37008,37010,37012,
+37014,37016,37018,37020,37022,37023,37024,37028,37029,37031,37032,37033,37035,
+37037,37042,37047,37052,37053,37055,37056,25722,25783,25784,25753,25786,25792,
+25808,25815,25828,25826,25865,25893,25902,24331,24530,29977,24337,21343,21489,
+21501,21481,21480,21499,21522,21526,21510,21579,21586,21587,21588,21590,21571,
+21537,21591,21593,21539,21554,21634,21652,21623,21617,21604,21658,21659,21636,
+21622,21606,21661,21712,21677,21698,21684,21714,21671,21670,21715,21716,21618,
+21667,21717,21691,21695,21708,21721,21722,21724,21673,21674,21668,21725,21711,
+21726,21787,21735,21792,21757,21780,21747,21794,21795,21775,21777,21799,21802,
+21863,21903,21941,21833,21869,21825,21845,21823,21840,21820,37058,37059,37062,
+37064,37065,37067,37068,37069,37074,37076,37077,37078,37080,37081,37082,37086,
+37087,37088,37091,37092,37093,37097,37098,37100,37102,37104,37105,37106,37107,
+37109,37110,37111,37113,37114,37115,37116,37119,37120,37121,37123,37125,37126,
+37127,37128,37129,37130,37131,37132,37133,37134,37135,37136,37137,37138,37139,
+37140,37141,37142,37143,37144,37146,37147,37148,37149,37151,37152,37153,37156,
+37157,37158,37159,37160,37161,37162,37163,37164,37165,37166,37168,37170,37171,
+37172,37173,37174,37175,37176,37178,37179,37180,37181,37182,37183,37184,37185,
+37186,37188,21815,21846,21877,21878,21879,21811,21808,21852,21899,21970,21891,
+21937,21945,21896,21889,21919,21886,21974,21905,21883,21983,21949,21950,21908,
+21913,21994,22007,21961,22047,21969,21995,21996,21972,21990,21981,21956,21999,
+21989,22002,22003,21964,21965,21992,22005,21988,36756,22046,22024,22028,22017,
+22052,22051,22014,22016,22055,22061,22104,22073,22103,22060,22093,22114,22105,
+22108,22092,22100,22150,22116,22129,22123,22139,22140,22149,22163,22191,22228,
+22231,22237,22241,22261,22251,22265,22271,22276,22282,22281,22300,24079,24089,
+24084,24081,24113,24123,24124,37189,37191,37192,37201,37203,37204,37205,37206,
+37208,37209,37211,37212,37215,37216,37222,37223,37224,37227,37229,37235,37242,
+37243,37244,37248,37249,37250,37251,37252,37254,37256,37258,37262,37263,37267,
+37268,37269,37270,37271,37272,37273,37276,37277,37278,37279,37280,37281,37284,
+37285,37286,37287,37288,37289,37291,37292,37296,37297,37298,37299,37302,37303,
+37304,37305,37307,37308,37309,37310,37311,37312,37313,37314,37315,37316,37317,
+37318,37320,37323,37328,37330,37331,37332,37333,37334,37335,37336,37337,37338,
+37339,37341,37342,37343,37344,37345,37346,37347,37348,37349,24119,24132,24148,
+24155,24158,24161,23692,23674,23693,23696,23702,23688,23704,23705,23697,23706,
+23708,23733,23714,23741,23724,23723,23729,23715,23745,23735,23748,23762,23780,
+23755,23781,23810,23811,23847,23846,23854,23844,23838,23814,23835,23896,23870,
+23860,23869,23916,23899,23919,23901,23915,23883,23882,23913,23924,23938,23961,
+23965,35955,23991,24005,24435,24439,24450,24455,24457,24460,24469,24473,24476,
+24488,24493,24501,24508,34914,24417,29357,29360,29364,29367,29368,29379,29377,
+29390,29389,29394,29416,29423,29417,29426,29428,29431,29441,29427,29443,29434,
+37350,37351,37352,37353,37354,37355,37356,37357,37358,37359,37360,37361,37362,
+37363,37364,37365,37366,37367,37368,37369,37370,37371,37372,37373,37374,37375,
+37376,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37387,37388,
+37389,37390,37391,37392,37393,37394,37395,37396,37397,37398,37399,37400,37401,
+37402,37403,37404,37405,37406,37407,37408,37409,37410,37411,37412,37413,37414,
+37415,37416,37417,37418,37419,37420,37421,37422,37423,37424,37425,37426,37427,
+37428,37429,37430,37431,37432,37433,37434,37435,37436,37437,37438,37439,37440,
+37441,37442,37443,37444,37445,29435,29463,29459,29473,29450,29470,29469,29461,
+29474,29497,29477,29484,29496,29489,29520,29517,29527,29536,29548,29551,29566,
+33307,22821,39143,22820,22786,39267,39271,39272,39273,39274,39275,39276,39284,
+39287,39293,39296,39300,39303,39306,39309,39312,39313,39315,39316,39317,24192,
+24209,24203,24214,24229,24224,24249,24245,24254,24243,36179,24274,24273,24283,
+24296,24298,33210,24516,24521,24534,24527,24579,24558,24580,24545,24548,24574,
+24581,24582,24554,24557,24568,24601,24629,24614,24603,24591,24589,24617,24619,
+24586,24639,24609,24696,24697,24699,24698,24642,37446,37447,37448,37449,37450,
+37451,37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463,
+37464,37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476,
+37477,37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489,
+37490,37491,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503,
+37504,37505,37506,37507,37508,37509,37510,37511,37512,37513,37514,37515,37516,
+37517,37519,37520,37521,37522,37523,37524,37525,37526,37527,37528,37529,37530,
+37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,37543,
+24682,24701,24726,24730,24749,24733,24707,24722,24716,24731,24812,24763,24753,
+24797,24792,24774,24794,24756,24864,24870,24853,24867,24820,24832,24846,24875,
+24906,24949,25004,24980,24999,25015,25044,25077,24541,38579,38377,38379,38385,
+38387,38389,38390,38396,38398,38403,38404,38406,38408,38410,38411,38412,38413,
+38415,38418,38421,38422,38423,38425,38426,20012,29247,25109,27701,27732,27740,
+27722,27811,27781,27792,27796,27788,27752,27753,27764,27766,27782,27817,27856,
+27860,27821,27895,27896,27889,27863,27826,27872,27862,27898,27883,27886,27825,
+27859,27887,27902,37544,37545,37546,37547,37548,37549,37551,37552,37553,37554,
+37555,37556,37557,37558,37559,37560,37561,37562,37563,37564,37565,37566,37567,
+37568,37569,37570,37571,37572,37573,37574,37575,37577,37578,37579,37580,37581,
+37582,37583,37584,37585,37586,37587,37588,37589,37590,37591,37592,37593,37594,
+37595,37596,37597,37598,37599,37600,37601,37602,37603,37604,37605,37606,37607,
+37608,37609,37610,37611,37612,37613,37614,37615,37616,37617,37618,37619,37620,
+37621,37622,37623,37624,37625,37626,37627,37628,37629,37630,37631,37632,37633,
+37634,37635,37636,37637,37638,37639,37640,37641,27961,27943,27916,27971,27976,
+27911,27908,27929,27918,27947,27981,27950,27957,27930,27983,27986,27988,27955,
+28049,28015,28062,28064,27998,28051,28052,27996,28000,28028,28003,28186,28103,
+28101,28126,28174,28095,28128,28177,28134,28125,28121,28182,28075,28172,28078,
+28203,28270,28238,28267,28338,28255,28294,28243,28244,28210,28197,28228,28383,
+28337,28312,28384,28461,28386,28325,28327,28349,28347,28343,28375,28340,28367,
+28303,28354,28319,28514,28486,28487,28452,28437,28409,28463,28470,28491,28532,
+28458,28425,28457,28553,28557,28556,28536,28530,28540,28538,28625,37642,37643,
+37644,37645,37646,37647,37648,37649,37650,37651,37652,37653,37654,37655,37656,
+37657,37658,37659,37660,37661,37662,37663,37664,37665,37666,37667,37668,37669,
+37670,37671,37672,37673,37674,37675,37676,37677,37678,37679,37680,37681,37682,
+37683,37684,37685,37686,37687,37688,37689,37690,37691,37692,37693,37695,37696,
+37697,37698,37699,37700,37701,37702,37703,37704,37705,37706,37707,37708,37709,
+37710,37711,37712,37713,37714,37715,37716,37717,37718,37719,37720,37721,37722,
+37723,37724,37725,37726,37727,37728,37729,37730,37731,37732,37733,37734,37735,
+37736,37737,37739,28617,28583,28601,28598,28610,28641,28654,28638,28640,28655,
+28698,28707,28699,28729,28725,28751,28766,23424,23428,23445,23443,23461,23480,
+29999,39582,25652,23524,23534,35120,23536,36423,35591,36790,36819,36821,36837,
+36846,36836,36841,36838,36851,36840,36869,36868,36875,36902,36881,36877,36886,
+36897,36917,36918,36909,36911,36932,36945,36946,36944,36968,36952,36962,36955,
+26297,36980,36989,36994,37000,36995,37003,24400,24407,24406,24408,23611,21675,
+23632,23641,23409,23651,23654,32700,24362,24361,24365,33396,24380,39739,23662,
+22913,22915,22925,22953,22954,22947,37740,37741,37742,37743,37744,37745,37746,
+37747,37748,37749,37750,37751,37752,37753,37754,37755,37756,37757,37758,37759,
+37760,37761,37762,37763,37764,37765,37766,37767,37768,37769,37770,37771,37772,
+37773,37774,37776,37777,37778,37779,37780,37781,37782,37783,37784,37785,37786,
+37787,37788,37789,37790,37791,37792,37793,37794,37795,37796,37797,37798,37799,
+37800,37801,37802,37803,37804,37805,37806,37807,37808,37809,37810,37811,37812,
+37813,37814,37815,37816,37817,37818,37819,37820,37821,37822,37823,37824,37825,
+37826,37827,37828,37829,37830,37831,37832,37833,37835,37836,37837,22935,22986,
+22955,22942,22948,22994,22962,22959,22999,22974,23045,23046,23005,23048,23011,
+23000,23033,23052,23049,23090,23092,23057,23075,23059,23104,23143,23114,23125,
+23100,23138,23157,33004,23210,23195,23159,23162,23230,23275,23218,23250,23252,
+23224,23264,23267,23281,23254,23270,23256,23260,23305,23319,23318,23346,23351,
+23360,23573,23580,23386,23397,23411,23377,23379,23394,39541,39543,39544,39546,
+39551,39549,39552,39553,39557,39560,39562,39568,39570,39571,39574,39576,39579,
+39580,39581,39583,39584,39586,39587,39589,39591,32415,32417,32419,32421,32424,
+32425,37838,37839,37840,37841,37842,37843,37844,37845,37847,37848,37849,37850,
+37851,37852,37853,37854,37855,37856,37857,37858,37859,37860,37861,37862,37863,
+37864,37865,37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,
+37877,37878,37879,37880,37881,37882,37883,37884,37885,37886,37887,37888,37889,
+37890,37891,37892,37893,37894,37895,37896,37897,37898,37899,37900,37901,37902,
+37903,37904,37905,37906,37907,37908,37909,37910,37911,37912,37913,37914,37915,
+37916,37917,37918,37919,37920,37921,37922,37923,37924,37925,37926,37927,37928,
+37929,37930,37931,37932,37933,37934,32429,32432,32446,32448,32449,32450,32457,
+32459,32460,32464,32468,32471,32475,32480,32481,32488,32491,32494,32495,32497,
+32498,32525,32502,32506,32507,32510,32513,32514,32515,32519,32520,32523,32524,
+32527,32529,32530,32535,32537,32540,32539,32543,32545,32546,32547,32548,32549,
+32550,32551,32554,32555,32556,32557,32559,32560,32561,32562,32563,32565,24186,
+30079,24027,30014,37013,29582,29585,29614,29602,29599,29647,29634,29649,29623,
+29619,29632,29641,29640,29669,29657,39036,29706,29673,29671,29662,29626,29682,
+29711,29738,29787,29734,29733,29736,29744,29742,29740,37935,37936,37937,37938,
+37939,37940,37941,37942,37943,37944,37945,37946,37947,37948,37949,37951,37952,
+37953,37954,37955,37956,37957,37958,37959,37960,37961,37962,37963,37964,37965,
+37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,37976,37977,37978,
+37979,37980,37981,37982,37983,37984,37985,37986,37987,37988,37989,37990,37991,
+37992,37993,37994,37996,37997,37998,37999,38000,38001,38002,38003,38004,38005,
+38006,38007,38008,38009,38010,38011,38012,38013,38014,38015,38016,38017,38018,
+38019,38020,38033,38038,38040,38087,38095,38099,38100,38106,38118,38139,38172,
+38176,29723,29722,29761,29788,29783,29781,29785,29815,29805,29822,29852,29838,
+29824,29825,29831,29835,29854,29864,29865,29840,29863,29906,29882,38890,38891,
+38892,26444,26451,26462,26440,26473,26533,26503,26474,26483,26520,26535,26485,
+26536,26526,26541,26507,26487,26492,26608,26633,26584,26634,26601,26544,26636,
+26585,26549,26586,26547,26589,26624,26563,26552,26594,26638,26561,26621,26674,
+26675,26720,26721,26702,26722,26692,26724,26755,26653,26709,26726,26689,26727,
+26688,26686,26698,26697,26665,26805,26767,26740,26743,26771,26731,26818,26990,
+26876,26911,26912,26873,38183,38195,38205,38211,38216,38219,38229,38234,38240,
+38254,38260,38261,38263,38264,38265,38266,38267,38268,38269,38270,38272,38273,
+38274,38275,38276,38277,38278,38279,38280,38281,38282,38283,38284,38285,38286,
+38287,38288,38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,38299,
+38300,38301,38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,38312,
+38313,38314,38315,38316,38317,38318,38319,38320,38321,38322,38323,38324,38325,
+38326,38327,38328,38329,38330,38331,38332,38333,38334,38335,38336,38337,38338,
+38339,38340,38341,38342,38343,38344,38345,38346,38347,26916,26864,26891,26881,
+26967,26851,26896,26993,26937,26976,26946,26973,27012,26987,27008,27032,27000,
+26932,27084,27015,27016,27086,27017,26982,26979,27001,27035,27047,27067,27051,
+27053,27092,27057,27073,27082,27103,27029,27104,27021,27135,27183,27117,27159,
+27160,27237,27122,27204,27198,27296,27216,27227,27189,27278,27257,27197,27176,
+27224,27260,27281,27280,27305,27287,27307,29495,29522,27521,27522,27527,27524,
+27538,27539,27533,27546,27547,27553,27562,36715,36717,36721,36722,36723,36725,
+36726,36728,36727,36729,36730,36732,36734,36737,36738,36740,36743,36747,38348,
+38349,38350,38351,38352,38353,38354,38355,38356,38357,38358,38359,38360,38361,
+38362,38363,38364,38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,
+38375,38380,38399,38407,38419,38424,38427,38430,38432,38435,38436,38437,38438,
+38439,38440,38441,38443,38444,38445,38447,38448,38455,38456,38457,38458,38462,
+38465,38467,38474,38478,38479,38481,38482,38483,38486,38487,38488,38489,38490,
+38492,38493,38494,38496,38499,38501,38502,38507,38509,38510,38511,38512,38513,
+38515,38520,38521,38522,38523,38524,38525,38526,38527,38528,38529,38530,38531,
+38532,38535,38537,38538,36749,36750,36751,36760,36762,36558,25099,25111,25115,
+25119,25122,25121,25125,25124,25132,33255,29935,29940,29951,29967,29969,29971,
+25908,26094,26095,26096,26122,26137,26482,26115,26133,26112,28805,26359,26141,
+26164,26161,26166,26165,32774,26207,26196,26177,26191,26198,26209,26199,26231,
+26244,26252,26279,26269,26302,26331,26332,26342,26345,36146,36147,36150,36155,
+36157,36160,36165,36166,36168,36169,36167,36173,36181,36185,35271,35274,35275,
+35276,35278,35279,35280,35281,29294,29343,29277,29286,29295,29310,29311,29316,
+29323,29325,29327,29330,25352,25394,25520,38540,38542,38545,38546,38547,38549,
+38550,38554,38555,38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,
+38568,38569,38570,38571,38572,38573,38574,38575,38577,38578,38580,38581,38583,
+38584,38586,38587,38591,38594,38595,38600,38602,38603,38608,38609,38611,38612,
+38614,38615,38616,38617,38618,38619,38620,38621,38622,38623,38625,38626,38627,
+38628,38629,38630,38631,38635,38636,38637,38638,38640,38641,38642,38644,38645,
+38648,38650,38651,38652,38653,38655,38658,38659,38661,38666,38667,38668,38672,
+38673,38674,38676,38677,38679,38680,38681,38682,38683,38685,38687,38688,25663,
+25816,32772,27626,27635,27645,27637,27641,27653,27655,27654,27661,27669,27672,
+27673,27674,27681,27689,27684,27690,27698,25909,25941,25963,29261,29266,29270,
+29232,34402,21014,32927,32924,32915,32956,26378,32957,32945,32939,32941,32948,
+32951,32999,33000,33001,33002,32987,32962,32964,32985,32973,32983,26384,32989,
+33003,33009,33012,33005,33037,33038,33010,33020,26389,33042,35930,33078,33054,
+33068,33048,33074,33096,33100,33107,33140,33113,33114,33137,33120,33129,33148,
+33149,33133,33127,22605,23221,33160,33154,33169,28373,33187,33194,33228,26406,
+33226,33211,38689,38690,38691,38692,38693,38694,38695,38696,38697,38699,38700,
+38702,38703,38705,38707,38708,38709,38710,38711,38714,38715,38716,38717,38719,
+38720,38721,38722,38723,38724,38725,38726,38727,38728,38729,38730,38731,38732,
+38733,38734,38735,38736,38737,38740,38741,38743,38744,38746,38748,38749,38751,
+38755,38756,38758,38759,38760,38762,38763,38764,38765,38766,38767,38768,38769,
+38770,38773,38775,38776,38777,38778,38779,38781,38782,38783,38784,38785,38786,
+38787,38788,38790,38791,38792,38793,38794,38796,38798,38799,38800,38803,38805,
+38806,38807,38809,38810,38811,38812,38813,33217,33190,27428,27447,27449,27459,
+27462,27481,39121,39122,39123,39125,39129,39130,27571,24384,27586,35315,26000,
+40785,26003,26044,26054,26052,26051,26060,26062,26066,26070,28800,28828,28822,
+28829,28859,28864,28855,28843,28849,28904,28874,28944,28947,28950,28975,28977,
+29043,29020,29032,28997,29042,29002,29048,29050,29080,29107,29109,29096,29088,
+29152,29140,29159,29177,29213,29224,28780,28952,29030,29113,25150,25149,25155,
+25160,25161,31035,31040,31046,31049,31067,31068,31059,31066,31074,31063,31072,
+31087,31079,31098,31109,31114,31130,31143,31155,24529,24528,38814,38815,38817,
+38818,38820,38821,38822,38823,38824,38825,38826,38828,38830,38832,38833,38835,
+38837,38838,38839,38840,38841,38842,38843,38844,38845,38846,38847,38848,38849,
+38850,38851,38852,38853,38854,38855,38856,38857,38858,38859,38860,38861,38862,
+38863,38864,38865,38866,38867,38868,38869,38870,38871,38872,38873,38874,38875,
+38876,38877,38878,38879,38880,38881,38882,38883,38884,38885,38888,38894,38895,
+38896,38897,38898,38900,38903,38904,38905,38906,38907,38908,38909,38910,38911,
+38912,38913,38914,38915,38916,38917,38918,38919,38920,38921,38922,38923,38924,
+38925,38926,24636,24669,24666,24679,24641,24665,24675,24747,24838,24845,24925,
+25001,24989,25035,25041,25094,32896,32895,27795,27894,28156,30710,30712,30720,
+30729,30743,30744,30737,26027,30765,30748,30749,30777,30778,30779,30751,30780,
+30757,30764,30755,30761,30798,30829,30806,30807,30758,30800,30791,30796,30826,
+30875,30867,30874,30855,30876,30881,30883,30898,30905,30885,30932,30937,30921,
+30956,30962,30981,30964,30995,31012,31006,31028,40859,40697,40699,40700,30449,
+30468,30477,30457,30471,30472,30490,30498,30489,30509,30502,30517,30520,30544,
+30545,30535,30531,30554,30568,38927,38928,38929,38930,38931,38932,38933,38934,
+38935,38936,38937,38938,38939,38940,38941,38942,38943,38944,38945,38946,38947,
+38948,38949,38950,38951,38952,38953,38954,38955,38956,38957,38958,38959,38960,
+38961,38962,38963,38964,38965,38966,38967,38968,38969,38970,38971,38972,38973,
+38974,38975,38976,38977,38978,38979,38980,38981,38982,38983,38984,38985,38986,
+38987,38988,38989,38990,38991,38992,38993,38994,38995,38996,38997,38998,38999,
+39000,39001,39002,39003,39004,39005,39006,39007,39008,39009,39010,39011,39012,
+39013,39014,39015,39016,39017,39018,39019,39020,39021,39022,30562,30565,30591,
+30605,30589,30592,30604,30609,30623,30624,30640,30645,30653,30010,30016,30030,
+30027,30024,30043,30066,30073,30083,32600,32609,32607,35400,32616,32628,32625,
+32633,32641,32638,30413,30437,34866,38021,38022,38023,38027,38026,38028,38029,
+38031,38032,38036,38039,38037,38042,38043,38044,38051,38052,38059,38058,38061,
+38060,38063,38064,38066,38068,38070,38071,38072,38073,38074,38076,38077,38079,
+38084,38088,38089,38090,38091,38092,38093,38094,38096,38097,38098,38101,38102,
+38103,38105,38104,38107,38110,38111,38112,38114,38116,38117,38119,38120,38122,
+39023,39024,39025,39026,39027,39028,39051,39054,39058,39061,39065,39075,39080,
+39081,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,39092,39093,
+39094,39095,39096,39097,39098,39099,39100,39101,39102,39103,39104,39105,39106,
+39107,39108,39109,39110,39111,39112,39113,39114,39115,39116,39117,39119,39120,
+39124,39126,39127,39131,39132,39133,39136,39137,39138,39139,39140,39141,39142,
+39145,39146,39147,39148,39149,39150,39151,39152,39153,39154,39155,39156,39157,
+39158,39159,39160,39161,39162,39163,39164,39165,39166,39167,39168,39169,39170,
+39171,39172,39173,39174,39175,38121,38123,38126,38127,38131,38132,38133,38135,
+38137,38140,38141,38143,38147,38146,38150,38151,38153,38154,38157,38158,38159,
+38162,38163,38164,38165,38166,38168,38171,38173,38174,38175,38178,38186,38187,
+38185,38188,38193,38194,38196,38198,38199,38200,38204,38206,38207,38210,38197,
+38212,38213,38214,38217,38220,38222,38223,38226,38227,38228,38230,38231,38232,
+38233,38235,38238,38239,38237,38241,38242,38244,38245,38246,38247,38248,38249,
+38250,38251,38252,38255,38257,38258,38259,38202,30695,30700,38601,31189,31213,
+31203,31211,31238,23879,31235,31234,31262,31252,39176,39177,39178,39179,39180,
+39182,39183,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195,
+39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208,
+39209,39210,39211,39212,39213,39215,39216,39217,39218,39219,39220,39221,39222,
+39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235,
+39236,39237,39238,39239,39240,39241,39242,39243,39244,39245,39246,39247,39248,
+39249,39250,39251,39254,39255,39256,39257,39258,39259,39260,39261,39262,39263,
+39264,39265,39266,39268,39270,39283,39288,39289,39291,39294,39298,39299,39305,
+31289,31287,31313,40655,39333,31344,30344,30350,30355,30361,30372,29918,29920,
+29996,40480,40482,40488,40489,40490,40491,40492,40498,40497,40502,40504,40503,
+40505,40506,40510,40513,40514,40516,40518,40519,40520,40521,40523,40524,40526,
+40529,40533,40535,40538,40539,40540,40542,40547,40550,40551,40552,40553,40554,
+40555,40556,40561,40557,40563,30098,30100,30102,30112,30109,30124,30115,30131,
+30132,30136,30148,30129,30128,30147,30146,30166,30157,30179,30184,30182,30180,
+30187,30183,30211,30193,30204,30207,30224,30208,30213,30220,30231,30218,30245,
+30232,30229,30233,39308,39310,39322,39323,39324,39325,39326,39327,39328,39329,
+39330,39331,39332,39334,39335,39337,39338,39339,39340,39341,39342,39343,39344,
+39345,39346,39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,
+39358,39359,39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,
+39371,39372,39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,
+39384,39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,
+39397,39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,
+39410,39411,39412,39413,39414,39415,39416,39417,30235,30268,30242,30240,30272,
+30253,30256,30271,30261,30275,30270,30259,30285,30302,30292,30300,30294,30315,
+30319,32714,31462,31352,31353,31360,31366,31368,31381,31398,31392,31404,31400,
+31405,31411,34916,34921,34930,34941,34943,34946,34978,35014,34999,35004,35017,
+35042,35022,35043,35045,35057,35098,35068,35048,35070,35056,35105,35097,35091,
+35099,35082,35124,35115,35126,35137,35174,35195,30091,32997,30386,30388,30684,
+32786,32788,32790,32796,32800,32802,32805,32806,32807,32809,32808,32817,32779,
+32821,32835,32838,32845,32850,32873,32881,35203,39032,39040,39043,39418,39419,
+39420,39421,39422,39423,39424,39425,39426,39427,39428,39429,39430,39431,39432,
+39433,39434,39435,39436,39437,39438,39439,39440,39441,39442,39443,39444,39445,
+39446,39447,39448,39449,39450,39451,39452,39453,39454,39455,39456,39457,39458,
+39459,39460,39461,39462,39463,39464,39465,39466,39467,39468,39469,39470,39471,
+39472,39473,39474,39475,39476,39477,39478,39479,39480,39481,39482,39483,39484,
+39485,39486,39487,39488,39489,39490,39491,39492,39493,39494,39495,39496,39497,
+39498,39499,39500,39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,
+39511,39512,39513,39049,39052,39053,39055,39060,39066,39067,39070,39071,39073,
+39074,39077,39078,34381,34388,34412,34414,34431,34426,34428,34427,34472,34445,
+34443,34476,34461,34471,34467,34474,34451,34473,34486,34500,34485,34510,34480,
+34490,34481,34479,34505,34511,34484,34537,34545,34546,34541,34547,34512,34579,
+34526,34548,34527,34520,34513,34563,34567,34552,34568,34570,34573,34569,34595,
+34619,34590,34597,34606,34586,34622,34632,34612,34609,34601,34615,34623,34690,
+34594,34685,34686,34683,34656,34672,34636,34670,34699,34643,34659,34684,34660,
+34649,34661,34707,34735,34728,34770,39514,39515,39516,39517,39518,39519,39520,
+39521,39522,39523,39524,39525,39526,39527,39528,39529,39530,39531,39538,39555,
+39561,39565,39566,39572,39573,39577,39590,39593,39594,39595,39596,39597,39598,
+39599,39602,39603,39604,39605,39609,39611,39613,39614,39615,39619,39620,39622,
+39623,39624,39625,39626,39629,39630,39631,39632,39634,39636,39637,39638,39639,
+39641,39642,39643,39644,39645,39646,39648,39650,39651,39652,39653,39655,39656,
+39657,39658,39660,39662,39664,39665,39666,39667,39668,39669,39670,39671,39672,
+39674,39676,39677,39678,39679,39680,39681,39682,39684,39685,39686,34758,34696,
+34693,34733,34711,34691,34731,34789,34732,34741,34739,34763,34771,34749,34769,
+34752,34762,34779,34794,34784,34798,34838,34835,34814,34826,34843,34849,34873,
+34876,32566,32578,32580,32581,33296,31482,31485,31496,31491,31492,31509,31498,
+31531,31503,31559,31544,31530,31513,31534,31537,31520,31525,31524,31539,31550,
+31518,31576,31578,31557,31605,31564,31581,31584,31598,31611,31586,31602,31601,
+31632,31654,31655,31672,31660,31645,31656,31621,31658,31644,31650,31659,31668,
+31697,31681,31692,31709,31706,31717,31718,31722,31756,31742,31740,31759,31766,
+31755,39687,39689,39690,39691,39692,39693,39694,39696,39697,39698,39700,39701,
+39702,39703,39704,39705,39706,39707,39708,39709,39710,39712,39713,39714,39716,
+39717,39718,39719,39720,39721,39722,39723,39724,39725,39726,39728,39729,39731,
+39732,39733,39734,39735,39736,39737,39738,39741,39742,39743,39744,39750,39754,
+39755,39756,39758,39760,39762,39763,39765,39766,39767,39768,39769,39770,39771,
+39772,39773,39774,39775,39776,39777,39778,39779,39780,39781,39782,39783,39784,
+39785,39786,39787,39788,39789,39790,39791,39792,39793,39794,39795,39796,39797,
+39798,39799,39800,39801,39802,39803,31775,31786,31782,31800,31809,31808,33278,
+33281,33282,33284,33260,34884,33313,33314,33315,33325,33327,33320,33323,33336,
+33339,33331,33332,33342,33348,33353,33355,33359,33370,33375,33384,34942,34949,
+34952,35032,35039,35166,32669,32671,32679,32687,32688,32690,31868,25929,31889,
+31901,31900,31902,31906,31922,31932,31933,31937,31943,31948,31949,31944,31941,
+31959,31976,33390,26280,32703,32718,32725,32741,32737,32742,32745,32750,32755,
+31992,32119,32166,32174,32327,32411,40632,40628,36211,36228,36244,36241,36273,
+36199,36205,35911,35913,37194,37200,37198,37199,37220,39804,39805,39806,39807,
+39808,39809,39810,39811,39812,39813,39814,39815,39816,39817,39818,39819,39820,
+39821,39822,39823,39824,39825,39826,39827,39828,39829,39830,39831,39832,39833,
+39834,39835,39836,39837,39838,39839,39840,39841,39842,39843,39844,39845,39846,
+39847,39848,39849,39850,39851,39852,39853,39854,39855,39856,39857,39858,39859,
+39860,39861,39862,39863,39864,39865,39866,39867,39868,39869,39870,39871,39872,
+39873,39874,39875,39876,39877,39878,39879,39880,39881,39882,39883,39884,39885,
+39886,39887,39888,39889,39890,39891,39892,39893,39894,39895,39896,39897,39898,
+39899,37218,37217,37232,37225,37231,37245,37246,37234,37236,37241,37260,37253,
+37264,37261,37265,37282,37283,37290,37293,37294,37295,37301,37300,37306,35925,
+40574,36280,36331,36357,36441,36457,36277,36287,36284,36282,36292,36310,36311,
+36314,36318,36302,36303,36315,36294,36332,36343,36344,36323,36345,36347,36324,
+36361,36349,36372,36381,36383,36396,36398,36387,36399,36410,36416,36409,36405,
+36413,36401,36425,36417,36418,36433,36434,36426,36464,36470,36476,36463,36468,
+36485,36495,36500,36496,36508,36510,35960,35970,35978,35973,35992,35988,26011,
+35286,35294,35290,35292,39900,39901,39902,39903,39904,39905,39906,39907,39908,
+39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920,39921,
+39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933,39934,
+39935,39936,39937,39938,39939,39940,39941,39942,39943,39944,39945,39946,39947,
+39948,39949,39950,39951,39952,39953,39954,39955,39956,39957,39958,39959,39960,
+39961,39962,39963,39964,39965,39966,39967,39968,39969,39970,39971,39972,39973,
+39974,39975,39976,39977,39978,39979,39980,39981,39982,39983,39984,39985,39986,
+39987,39988,39989,39990,39991,39992,39993,39994,39995,35301,35307,35311,35390,
+35622,38739,38633,38643,38639,38662,38657,38664,38671,38670,38698,38701,38704,
+38718,40832,40835,40837,40838,40839,40840,40841,40842,40844,40702,40715,40717,
+38585,38588,38589,38606,38610,30655,38624,37518,37550,37576,37694,37738,37834,
+37775,37950,37995,40063,40066,40069,40070,40071,40072,31267,40075,40078,40080,
+40081,40082,40084,40085,40090,40091,40094,40095,40096,40097,40098,40099,40101,
+40102,40103,40104,40105,40107,40109,40110,40112,40113,40114,40115,40116,40117,
+40118,40119,40122,40123,40124,40125,40132,40133,40134,40135,40138,40139,39996,
+39997,39998,39999,40000,40001,40002,40003,40004,40005,40006,40007,40008,40009,
+40010,40011,40012,40013,40014,40015,40016,40017,40018,40019,40020,40021,40022,
+40023,40024,40025,40026,40027,40028,40029,40030,40031,40032,40033,40034,40035,
+40036,40037,40038,40039,40040,40041,40042,40043,40044,40045,40046,40047,40048,
+40049,40050,40051,40052,40053,40054,40055,40056,40057,40058,40059,40061,40062,
+40064,40067,40068,40073,40074,40076,40079,40083,40086,40087,40088,40089,40093,
+40106,40108,40111,40121,40126,40127,40128,40129,40130,40136,40137,40145,40146,
+40154,40155,40160,40161,40140,40141,40142,40143,40144,40147,40148,40149,40151,
+40152,40153,40156,40157,40159,40162,38780,38789,38801,38802,38804,38831,38827,
+38819,38834,38836,39601,39600,39607,40536,39606,39610,39612,39617,39616,39621,
+39618,39627,39628,39633,39749,39747,39751,39753,39752,39757,39761,39144,39181,
+39214,39253,39252,39647,39649,39654,39663,39659,39675,39661,39673,39688,39695,
+39699,39711,39715,40637,40638,32315,40578,40583,40584,40587,40594,37846,40605,
+40607,40667,40668,40669,40672,40671,40674,40681,40679,40677,40682,40687,40738,
+40748,40751,40761,40759,40765,40766,40772,40163,40164,40165,40166,40167,40168,
+40169,40170,40171,40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,
+40182,40183,40184,40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,
+40195,40196,40197,40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,
+40208,40209,40210,40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,
+40221,40222,40223,40224,40225,40226,40227,40228,40229,40230,40231,40232,40233,
+40234,40235,40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,
+40247,40248,40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,57908,
+57909,57910,57911,57912,57913,57914,57915,57916,57917,57918,57919,57920,57921,
+57922,57923,57924,57925,57926,57927,57928,57929,57930,57931,57932,57933,57934,
+57935,57936,57937,57938,57939,57940,57941,57942,57943,57944,57945,57946,57947,
+57948,57949,57950,57951,57952,57953,57954,57955,57956,57957,57958,57959,57960,
+57961,57962,57963,57964,57965,57966,57967,57968,57969,57970,57971,57972,57973,
+57974,57975,57976,57977,57978,57979,57980,57981,57982,57983,57984,57985,57986,
+57987,57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,57998,57999,
+58000,58001,40259,40260,40261,40262,40263,40264,40265,40266,40267,40268,40269,
+40270,40271,40272,40273,40274,40275,40276,40277,40278,40279,40280,40281,40282,
+40283,40284,40285,40286,40287,40288,40289,40290,40291,40292,40293,40294,40295,
+40296,40297,40298,40299,40300,40301,40302,40303,40304,40305,40306,40307,40308,
+40309,40310,40311,40312,40313,40314,40315,40316,40317,40318,40319,40320,40321,
+40322,40323,40324,40325,40326,40327,40328,40329,40330,40331,40332,40333,40334,
+40335,40336,40337,40338,40339,40340,40341,40342,40343,40344,40345,40346,40347,
+40348,40349,40350,40351,40352,40353,40354,58002,58003,58004,58005,58006,58007,
+58008,58009,58010,58011,58012,58013,58014,58015,58016,58017,58018,58019,58020,
+58021,58022,58023,58024,58025,58026,58027,58028,58029,58030,58031,58032,58033,
+58034,58035,58036,58037,58038,58039,58040,58041,58042,58043,58044,58045,58046,
+58047,58048,58049,58050,58051,58052,58053,58054,58055,58056,58057,58058,58059,
+58060,58061,58062,58063,58064,58065,58066,58067,58068,58069,58070,58071,58072,
+58073,58074,58075,58076,58077,58078,58079,58080,58081,58082,58083,58084,58085,
+58086,58087,58088,58089,58090,58091,58092,58093,58094,58095,40355,40356,40357,
+40358,40359,40360,40361,40362,40363,40364,40365,40366,40367,40368,40369,40370,
+40371,40372,40373,40374,40375,40376,40377,40378,40379,40380,40381,40382,40383,
+40384,40385,40386,40387,40388,40389,40390,40391,40392,40393,40394,40395,40396,
+40397,40398,40399,40400,40401,40402,40403,40404,40405,40406,40407,40408,40409,
+40410,40411,40412,40413,40414,40415,40416,40417,40418,40419,40420,40421,40422,
+40423,40424,40425,40426,40427,40428,40429,40430,40431,40432,40433,40434,40435,
+40436,40437,40438,40439,40440,40441,40442,40443,40444,40445,40446,40447,40448,
+40449,40450,58096,58097,58098,58099,58100,58101,58102,58103,58104,58105,58106,
+58107,58108,58109,58110,58111,58112,58113,58114,58115,58116,58117,58118,58119,
+58120,58121,58122,58123,58124,58125,58126,58127,58128,58129,58130,58131,58132,
+58133,58134,58135,58136,58137,58138,58139,58140,58141,58142,58143,58144,58145,
+58146,58147,58148,58149,58150,58151,58152,58153,58154,58155,58156,58157,58158,
+58159,58160,58161,58162,58163,58164,58165,58166,58167,58168,58169,58170,58171,
+58172,58173,58174,58175,58176,58177,58178,58179,58180,58181,58182,58183,58184,
+58185,58186,58187,58188,58189,40451,40452,40453,40454,40455,40456,40457,40458,
+40459,40460,40461,40462,40463,40464,40465,40466,40467,40468,40469,40470,40471,
+40472,40473,40474,40475,40476,40477,40478,40484,40487,40494,40496,40500,40507,
+40508,40512,40525,40528,40530,40531,40532,40534,40537,40541,40543,40544,40545,
+40546,40549,40558,40559,40562,40564,40565,40566,40567,40568,40569,40570,40571,
+40572,40573,40576,40577,40579,40580,40581,40582,40585,40586,40588,40589,40590,
+40591,40592,40593,40596,40597,40598,40599,40600,40601,40602,40603,40604,40606,
+40608,40609,40610,40611,40612,40613,40615,40616,40617,40618,58190,58191,58192,
+58193,58194,58195,58196,58197,58198,58199,58200,58201,58202,58203,58204,58205,
+58206,58207,58208,58209,58210,58211,58212,58213,58214,58215,58216,58217,58218,
+58219,58220,58221,58222,58223,58224,58225,58226,58227,58228,58229,58230,58231,
+58232,58233,58234,58235,58236,58237,58238,58239,58240,58241,58242,58243,58244,
+58245,58246,58247,58248,58249,58250,58251,58252,58253,58254,58255,58256,58257,
+58258,58259,58260,58261,58262,58263,58264,58265,58266,58267,58268,58269,58270,
+58271,58272,58273,58274,58275,58276,58277,58278,58279,58280,58281,58282,58283,
+40619,40620,40621,40622,40623,40624,40625,40626,40627,40629,40630,40631,40633,
+40634,40636,40639,40640,40641,40642,40643,40645,40646,40647,40648,40650,40651,
+40652,40656,40658,40659,40661,40662,40663,40665,40666,40670,40673,40675,40676,
+40678,40680,40683,40684,40685,40686,40688,40689,40690,40691,40692,40693,40694,
+40695,40696,40698,40701,40703,40704,40705,40706,40707,40708,40709,40710,40711,
+40712,40713,40714,40716,40719,40721,40722,40724,40725,40726,40728,40730,40731,
+40732,40733,40734,40735,40737,40739,40740,40741,40742,40743,40744,40745,40746,
+40747,40749,40750,40752,40753,58284,58285,58286,58287,58288,58289,58290,58291,
+58292,58293,58294,58295,58296,58297,58298,58299,58300,58301,58302,58303,58304,
+58305,58306,58307,58308,58309,58310,58311,58312,58313,58314,58315,58316,58317,
+58318,58319,58320,58321,58322,58323,58324,58325,58326,58327,58328,58329,58330,
+58331,58332,58333,58334,58335,58336,58337,58338,58339,58340,58341,58342,58343,
+58344,58345,58346,58347,58348,58349,58350,58351,58352,58353,58354,58355,58356,
+58357,58358,58359,58360,58361,58362,58363,58364,58365,58366,58367,58368,58369,
+58370,58371,58372,58373,58374,58375,58376,58377,40754,40755,40756,40757,40758,
+40760,40762,40764,40767,40768,40769,40770,40771,40773,40774,40775,40776,40777,
+40778,40779,40780,40781,40782,40783,40786,40787,40788,40789,40790,40791,40792,
+40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,40805,
+40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,
+40819,40820,40821,40822,40823,40824,40825,40826,40827,40828,40829,40830,40833,
+40834,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855,40856,
+40860,40861,40862,40865,40866,40867,40868,40869,63788,63865,63893,63975,63985,
+58378,58379,58380,58381,58382,58383,58384,58385,58386,58387,58388,58389,58390,
+58391,58392,58393,58394,58395,58396,58397,58398,58399,58400,58401,58402,58403,
+58404,58405,58406,58407,58408,58409,58410,58411,58412,58413,58414,58415,58416,
+58417,58418,58419,58420,58421,58422,58423,58424,58425,58426,58427,58428,58429,
+58430,58431,58432,58433,58434,58435,58436,58437,58438,58439,58440,58441,58442,
+58443,58444,58445,58446,58447,58448,58449,58450,58451,58452,58453,58454,58455,
+58456,58457,58458,58459,58460,58461,58462,58463,58464,58465,58466,58467,58468,
+58469,58470,58471,64012,64013,64014,64015,64017,64019,64020,64024,64031,64032,
+64033,64035,64036,64039,64040,64041,11905,59414,59415,59416,11908,13427,13383,
+11912,11915,59422,13726,13850,13838,11916,11927,14702,14616,59430,14799,14815,
+14963,14800,59435,59436,15182,15470,15584,11943,59441,59442,11946,16470,16735,
+11950,17207,11955,11958,11959,59451,17329,17324,11963,17373,17622,18017,17996,
+59459,18211,18217,18300,18317,11978,18759,18810,18813,18818,18819,18821,18822,
+18847,18843,18871,18870,59476,59477,19619,19615,19616,19617,19575,19618,19731,
+19732,19733,19734,19735,19736,19737,19886,59492,58472,58473,58474,58475,58476,
+58477,58478,58479,58480,58481,58482,58483,58484,58485,58486,58487,58488,58489,
+58490,58491,58492,58493,58494,58495,58496,58497,58498,58499,58500,58501,58502,
+58503,58504,58505,58506,58507,58508,58509,58510,58511,58512,58513,58514,58515,
+58516,58517,58518,58519,58520,58521,58522,58523,58524,58525,58526,58527,58528,
+58529,58530,58531,58532,58533,58534,58535,58536,58537,58538,58539,58540,58541,
+58542,58543,58544,58545,58546,58547,58548,58549,58550,58551,58552,58553,58554,
+58555,58556,58557,58558,58559,58560,58561,58562,58563,58564,58565,
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/hkscs.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/hkscs.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/hkscs.h	(revision 398)
@@ -0,0 +1,390 @@
+17392,19506,17923,17830,17784,29287,19831,17843,31921,19682,31941,15253,18230,
+18244,19527,19520,17087,13847,29522,28299,28882,19543,41809,18255,17882,19589,
+31852,19719,19108,18081,27427,29221,23124,6755,15878,16225,26189,22267,0,
+32149,22813,35769,15860,38708,31727,23515,7518,23204,13861,40624,23249,23479,
+23804,26478,34195,39237,29793,29853,14453,7507,13982,24609,16108,22750,15093,
+31484,40855,16737,35085,12778,2698,12894,17162,33924,40854,37935,18736,34323,
+22678,38730,37400,31184,31282,26208,27177,34973,29772,31685,26498,31276,21071,
+36934,13542,29636,23993,29894,40903,22451,18735,21580,16689,13966,22552,31346,
+31589,35727,18094,28296,16769,23961,31662,9404,40904,9409,9417,9420,40905,
+34052,13755,16564,40906,17633,44543,25281,28782,40907,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,12736,12737,12738,12739,12740,268,12741,
+209,205,12742,12743,203,8168,12744,202,12745,12746,12747,12748,270,12749,
+12750,256,193,461,192,274,201,282,200,332,211,465,210,56320,7870,56324,7872,
+202,257,225,462,224,593,275,233,283,232,299,237,464,236,333,243,466,242,363,
+250,468,249,470,472,474,476,252,56328,7871,56332,7873,234,609,9178,9179,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,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41897,4421,0,25866,0,0,20029,28381,
+40270,37343,0,0,30517,25745,20250,20264,20392,20822,20852,20892,20964,21153,
+21160,21307,21326,21457,21464,22242,22768,22788,22791,22834,22836,23398,23454,
+23455,23706,24198,24635,25993,26622,26628,26725,27982,28860,30005,32420,32428,
+32442,32455,32463,32479,32518,32567,33402,33487,33647,35270,35774,35810,36710,
+36711,36718,29713,31996,32205,26950,31433,21031,0,0,0,0,37260,30904,37214,
+32956,0,36107,33014,2535,0,0,32927,40647,19661,40393,40460,19518,40438,28686,
+40458,41267,13761,0,28314,33342,29977,0,18705,39532,39567,40857,31111,33900,
+7626,1488,10982,20004,20097,20096,20103,20159,20203,20279,13388,20413,15944,
+20483,20616,13437,13459,13477,20870,22789,20955,20988,20997,20105,21113,21136,
+21287,13767,21417,13649,21424,13651,21442,21539,13677,13682,13953,21651,21667,
+21684,21689,21712,21743,21784,21795,21800,13720,21823,13733,13759,21975,13765,
+32132,21797,0,3138,3349,20779,21904,11462,14828,833,36422,19896,38117,16467,
+32958,30586,11320,14900,18389,33117,27122,19946,25821,3452,4020,3285,4340,
+25741,36478,3734,3083,3940,11433,33366,17619,0,3398,39501,33001,18420,
+20135,11458,39602,14951,38388,16365,13574,21191,38868,30920,11588,40302,38933,
+0,17369,24741,25780,21731,11596,11210,4215,14843,4207,26330,26390,31136,25834,
+20562,3139,36456,8609,35660,1841,0,18443,425,16378,22643,11661,0,17864,1276,
+24727,3916,3478,21881,16571,17338,0,19124,10854,4253,33194,39157,3484,25465,
+14846,10101,36288,22177,25724,15939,0,42497,3593,10959,11465,0,4296,14786,
+14738,14854,33435,13688,24137,8391,22098,3889,11442,38688,13500,27709,20027,0,
+0,30068,11915,8712,42587,36045,3706,3124,26652,32659,4303,10243,10553,13819,
+20963,3724,3981,3754,16275,3888,3399,4431,3660,0,3755,2985,3400,4288,4413,
+16377,9878,25650,4013,13300,30265,11214,3454,3455,11345,11349,14872,3736,4295,
+3886,42546,27472,36050,36249,36042,38314,21708,33476,21945,0,40643,39974,
+39606,30558,11758,28992,33133,33004,23580,25970,33076,14231,21343,32957,37302,
+3834,3599,3703,3835,13789,19947,13833,3286,22191,10165,4297,3600,3704,4216,
+4424,33287,5205,3705,20048,11684,23124,4125,4126,4341,4342,22428,3601,30356,
+33485,4021,3707,20862,14083,4022,4480,21208,41661,18906,6202,16759,33404,
+22681,21096,13850,22333,31666,23400,18432,19244,40743,18919,39967,39821,23412,
+12605,22011,13810,22153,20008,22786,7105,63608,38737,134,20059,20155,13630,
+23587,24401,24516,14586,25164,25909,27514,27701,27706,28780,29227,20012,29357,
+18665,32594,31035,31993,32595,25194,13505,0,25419,32770,32896,26130,26961,
+21341,34916,35265,30898,35744,36125,38021,38264,38271,38376,
+36367,38886,39029,39118,39134,39267,38928,40060,40479,40644,27503,63751,20023,
+135,38429,25143,38050,0,20539,28158,40051,40870,15817,34959,16718,28791,23797,
+19232,20941,13657,23856,24866,35378,36775,37366,29073,26393,29626,12929,41223,
+15499,6528,19216,30948,29698,20910,34575,16393,27235,41658,16931,34319,2671,
+31274,39239,35562,38741,28749,21284,8318,37876,30425,35299,40871,30685,20131,
+20464,20668,20015,20247,40872,21556,32139,22674,22736,7606,24210,24217,24514,
+10002,25995,13305,26905,27203,15459,27903,0,29184,17669,29580,16091,18963,
+23317,29881,35715,23716,22165,31379,31724,31939,32364,33528,34199,40873,34960,
+40874,36537,40875,36815,34143,39392,37409,40876,36281,5183,16497,17058,23066,
+0,0,0,39016,26475,17014,22333,0,34262,18811,33471,28941,19585,28020,23931,
+27413,28606,40877,40878,23446,40879,26343,32347,28247,31178,15752,17603,12886,
+10134,17306,17718,0,23765,15130,35577,23672,15634,13649,23928,40882,29015,
+17752,16620,7715,19575,14712,13386,420,27713,35532,20404,569,22975,33132,
+38998,39162,24379,2975,0,8641,35181,16642,18107,36985,16135,40883,41397,16632,
+14294,18167,27718,16764,34482,29695,17773,14548,21658,17761,17691,19849,19579,
+19830,17898,16328,19215,13921,17630,17597,16877,23870,23880,23894,15868,14351,
+23972,23993,14368,14392,24130,24253,24357,24451,14600,14612,14655,14669,24791,
+24893,23781,14729,25015,25017,25039,14776,25132,25232,25317,25368,14840,22193,
+14851,25570,25595,25607,25690,14923,25792,23829,22049,40863,14999,25990,15037,
+26111,26195,15090,26258,15138,
+26390,15170,26532,26624,15192,26698,26756,15218,15217,15227,26889,26947,29276,
+26980,27039,27013,15292,27094,15325,27237,27252,27249,27266,15340,27289,15346,
+27307,27317,27348,27382,27521,27585,27626,27765,27818,15563,27906,27910,27942,
+28033,15599,28068,28081,28181,28184,28201,28294,35264,28347,28386,28378,40831,
+28392,28393,28452,28468,15686,16193,28545,28606,15722,15733,29111,23705,15754,
+28716,15761,28752,28756,28783,28799,28809,805,17345,13809,3800,16087,22462,
+28371,28990,22496,13902,27042,35817,23412,31305,22753,38105,31333,31357,22956,
+31419,31408,31426,31427,29137,25741,16842,31450,31453,31466,16879,21682,23553,
+31499,31573,31529,21262,23806,31650,31599,33692,23476,27775,31696,33825,31634,
+0,23840,15789,23653,33938,31738,0,31797,23745,31812,31875,18562,31910,26237,
+17784,31945,31943,31974,31860,31987,31989,0,32359,17693,28228,32093,28374,
+29837,32137,32171,28981,32179,0,16471,24617,32228,15635,32245,6137,32229,
+33645,0,24865,24922,32366,32402,17195,37996,32295,32576,32577,32583,31030,
+25296,39393,32663,25425,32675,5729,104,17756,14182,17667,33594,32762,25737,0,
+32776,32797,0,32815,41095,27843,32827,32828,32865,10004,18825,26150,15843,
+26344,26405,32935,35400,33031,33050,22704,9974,27775,25752,20408,25831,5258,
+33304,6238,27219,19045,19093,17530,33321,2829,27218,15742,20473,5373,34018,
+33634,27402,18855,13616,6003,15864,33450,26907,63892,16859,34123,33488,33562,
+3606,6068,14017,12669,13658,33403,33506,33560,16011,28067,27397,27543,13774,
+15807,33565,21996,33669,17675,28069,33708,
+0,33747,13438,28372,27223,34138,13462,28226,12015,33880,23524,33905,15827,
+17636,27303,33866,15541,31064,0,27542,28279,28227,34014,0,33681,17568,33939,
+34020,23697,16960,23744,17731,34100,23282,28313,17703,34163,17686,26559,34326,
+34341,34363,34241,28808,34306,5506,28877,63922,17770,34344,13896,6306,21495,
+29594,34430,34673,41208,34798,11303,34737,34778,34831,22113,34412,26710,17935,
+34885,34886,30176,15801,30180,34910,34972,18011,34996,34997,25537,35013,30583,
+30479,35207,35210,0,0,35239,35260,35365,35303,31012,31421,35484,30611,37374,
+35472,31321,31465,31546,16271,18195,31544,29052,35596,35615,21552,21861,35647,
+35660,35661,35497,19066,35728,35739,35503,5855,17941,34895,35995,32084,32143,
+63956,14117,32083,36054,32152,32189,36114,36099,6416,36059,28764,36113,19657,
+16080,0,36265,32770,4116,18826,15228,33212,28940,31463,36525,36534,36547,
+37588,36633,36653,33637,33810,36773,37635,41631,2640,36787,18730,35294,34109,
+15803,24312,12898,36857,40980,34492,34049,8997,14720,28375,36919,34108,31422,
+36961,34156,34315,37032,34579,37060,34534,37038,0,37223,15088,37289,37316,
+31916,35123,7817,37390,27807,37441,37474,21945,0,35526,15515,35596,21979,3377,
+37676,37739,35553,35819,28815,23235,35554,35557,18789,37444,35820,35897,35839,
+37747,37979,36540,38277,38310,37926,38304,28662,17081,9850,34520,4732,15918,
+18911,27676,38523,38550,16748,38563,28373,25050,38582,30965,35552,38589,21452,
+18849,27832,628,25616,37039,37093,19153,6421,13066,38705,34370,38710,18959,
+17725,17797,19177,28789,23361,38683,
+0,37333,38743,23370,37355,38751,37925,20688,12471,12476,38793,38815,38833,
+38846,38848,38866,38880,21612,38894,29724,37939,0,38901,37917,31098,19153,
+38964,38963,38987,39014,15118,29045,15697,1584,16732,22278,39114,39095,39112,
+39111,19199,27943,5843,21936,39137,39142,39148,37752,39225,18985,19314,38999,
+39173,39413,39436,39483,39440,39512,22309,14020,37041,39893,39648,39650,39685,
+39668,19470,39700,39725,34304,20532,39732,27048,14531,12413,39760,39744,40254,
+23109,6243,39822,16971,39938,39935,39948,40552,40404,40887,41362,41387,41185,
+41251,41439,40318,40323,41268,40462,26760,40388,8539,41363,41504,6459,41523,
+40249,41145,41652,40592,40597,40606,40610,19764,40618,40623,17252,40641,15200,
+14821,15645,20274,14270,35883,40706,40712,19350,37924,28066,40727,0,40761,
+22175,22154,40773,39352,37003,38898,33919,40802,40809,31452,40846,29206,19390,
+18805,18875,29047,18936,17224,19025,29598,35802,6394,31135,35198,36406,37737,
+37875,35396,37612,37761,37835,35180,17593,29207,16107,30578,31299,28880,17523,
+17400,29054,6127,28835,6334,13721,16071,6277,21551,6136,14114,5883,6201,14049,
+6004,6353,24395,14115,5824,22363,18981,5118,4776,5062,5302,34051,13990,0,
+33877,18836,29029,15921,21852,16123,28754,17652,14062,39325,28454,26617,14131,
+15381,15847,22636,6434,26640,16471,14143,16609,16523,16655,27681,21707,22174,
+26289,22162,4063,2984,3597,37830,35603,37788,20216,20779,14361,17462,20156,
+1125,895,20299,20362,22097,23144,427,971,14745,778,1044,13365,20265,704,36531,
+629,35546,524,20120,20685,
+20749,20386,20227,18958,16010,20290,20526,20588,20609,20428,20453,20568,20732,
+0,0,0,0,28278,13717,15929,16063,28018,6276,16009,20904,20931,1504,17629,1187,
+1170,1169,36218,35484,1806,21081,21156,2163,21217,0,18042,29068,17292,3104,
+18860,4324,27089,3613,0,16094,29849,29716,29782,29592,19342,19132,16525,21456,
+13700,29199,16585,21940,837,21709,3014,22301,37469,38644,37734,22493,22413,
+22399,13886,22731,23193,35398,5882,5999,5904,23084,22968,37519,23166,23247,
+23058,22854,6643,6241,17045,14069,27909,29763,23073,24195,23169,35799,1043,
+37856,29836,4867,28933,18802,37896,35323,37821,14240,23582,23710,24158,24136,
+6550,6524,15086,24269,23375,6403,6404,14081,6304,14045,5886,14035,33066,35399,
+7610,13426,35240,24332,24334,6439,6059,23147,5947,23364,34324,30205,34912,
+24702,10336,9771,24539,16056,9647,9662,37000,28531,25024,62,70,9755,24985,
+24984,24693,11419,11527,18132,37197,25713,18021,11114,14889,11042,13392,39146,
+11896,25399,42075,25782,25393,25553,18915,11623,25252,11425,25659,25963,26994,
+15348,12430,12973,18825,12971,21773,13024,6361,37951,26318,12937,12723,15072,
+16784,21892,35618,21903,5884,21851,21541,30958,12547,6186,12852,13412,12815,
+12674,17097,26254,27940,26219,19347,26160,30832,7659,26211,13010,13025,26142,
+22642,14545,14394,14268,15257,14242,13310,29904,15254,26511,17962,26806,26654,
+15300,27326,14435,14293,17543,27187,27218,27337,27397,6418,25873,26776,27212,
+15319,27258,27479,16320,15514,37792,37618,35818,35531,37513,32798,35292,37991,
+28069,28427,
+18924,0,16255,15759,28164,16444,23101,28170,22599,27940,30786,28987,17178,
+17014,28913,29264,29319,29332,18319,18213,20857,19108,1515,29818,16120,13919,
+19018,18711,24545,16134,16049,19167,35875,16181,24743,16115,29900,29756,37767,
+29751,17567,28138,17745,30083,16227,19673,19718,16216,30037,30323,42438,15129,
+29800,35532,18859,18830,15099,15821,19022,16127,18885,18675,37370,22322,37698,
+35555,6244,20703,21025,20967,30584,12850,30478,30479,30587,18071,14209,14942,
+18672,29752,29851,16063,19130,19143,16584,19094,25006,37639,21889,30750,30861,
+30856,30930,29648,31065,30529,22243,16654,0,33942,31141,27181,16122,31290,
+31220,16750,5862,16690,37429,31217,3404,18828,665,15802,5998,13719,21867,
+13680,13994,468,3085,31458,23129,9973,23215,23196,23053,603,30960,23082,23494,
+31486,16889,31837,31853,16913,23475,24252,24230,31949,18937,6064,31886,31868,
+31918,27314,32220,32263,32211,32590,25185,24924,31560,32151,24194,17002,27509,
+2326,26582,78,13775,22468,25618,25592,18786,32733,31527,2092,23273,23875,
+31500,24078,39398,34373,39523,27164,13375,14818,18935,26029,39455,26016,33920,
+28967,27857,17642,33079,17410,32966,33033,33090,26548,39107,27202,33378,33381,
+27217,33875,28071,34320,29211,23174,16767,6208,23339,6305,23268,6360,34464,
+63932,15759,34861,29730,23042,34926,20293,34951,35007,35046,35173,35149,22147,
+35156,30597,30596,35829,35801,35740,35321,16045,33955,18165,18127,14322,35389,
+35356,37960,24397,37419,17028,26068,28969,28868,6213,40301,35999,36073,32220,
+22938,30659,23024,17262,14036,36394,36519,19465,
+36656,36682,17140,27736,28603,8993,18587,28537,28299,6106,39913,14005,18735,
+37051,0,21873,18694,37307,37892,35403,16482,35580,37927,35869,35899,34021,
+35371,38297,38311,38295,38294,36148,29765,16066,18687,19010,17386,16103,12837,
+38543,36583,36454,36453,16076,18925,19064,16366,29714,29803,16124,38721,37040,
+26695,18973,37011,22495,0,37736,35209,35878,35631,25534,37562,23313,35689,
+18748,29689,16923,38811,38769,39224,3878,24001,35781,19122,38943,38106,37622,
+38359,37349,17600,35664,19047,35684,39132,35397,16128,37418,18725,33812,39227,
+39245,31494,15869,39323,19311,39338,39516,35685,22728,27279,39457,23294,39471,
+39153,19344,39240,39356,19389,19351,37757,22642,4866,22562,18872,5352,30788,
+10015,15800,26821,15741,37976,14631,24912,10113,10603,24839,40015,40019,40059,
+39989,39952,39807,39887,40493,39839,41461,41214,40225,19630,16644,40472,19632,
+40204,41396,41197,41203,39215,40357,33981,28178,28639,27522,34300,17715,28068,
+28292,28144,33824,34286,28160,14295,24676,31202,13724,13888,18733,18910,15714,
+37851,37566,37704,703,30905,37495,37965,20452,13376,36964,21853,30781,30804,
+30902,30795,5975,12745,18753,13978,20338,28634,28633,0,28702,21524,16821,
+22459,22771,22410,40214,22487,28980,13487,16812,29163,27712,20375,0,6069,
+35401,24844,23246,23051,17084,17544,14124,19323,35324,37819,37816,6358,3869,
+33906,27840,5139,17146,11302,17345,22932,15799,26433,32168,24923,24740,18873,
+18827,35322,37605,29666,16105,29876,35683,6303,16097,19123,27352,29683,29691,
+16086,19006,19092,6105,19046,935,5156,18917,29768,
+18710,28837,18806,37508,29670,37727,1278,37681,35534,35350,37766,35815,21973,
+18741,35458,29035,18755,3327,22180,1562,3051,3256,21762,31172,6138,32254,5826,
+19024,6226,17710,37889,14090,35520,18861,22960,6335,6275,29828,23201,14050,
+15707,14000,37471,23161,35457,6242,37748,15565,2740,19094,14730,20724,15721,
+15692,5020,29045,17147,33304,28175,37092,17643,27991,32335,28775,27823,15574,
+16365,15917,28162,28428,15727,1013,30033,14012,13512,18048,16090,18545,22980,
+37486,18750,36673,35868,27584,22546,22472,14038,5202,28926,17250,19057,12259,
+4784,9149,26809,26983,5016,13541,31732,14047,35459,14294,13306,19615,27162,
+13997,27831,33854,17631,17614,27942,27985,27778,28638,28439,28937,33597,5946,
+33773,27776,28755,6107,22921,23170,6067,23137,23153,6405,16892,14125,23023,
+5948,14023,29070,37776,26266,17061,23150,23083,17043,27179,16121,30518,17499,
+17098,28957,16985,35297,20400,27944,23746,17614,32333,17341,27148,16982,4868,
+28838,28979,17385,15781,27871,63525,19023,32357,23019,23855,15859,24412,19037,
+6111,32164,33830,21637,15098,13056,532,22398,2261,1561,16357,8094,41654,28675,
+37211,23920,29583,31955,35417,37920,20424,32743,29389,29456,31476,29496,29497,
+22262,29505,29512,16041,31512,36972,29173,18674,29665,33270,16074,30476,16081,
+27810,22269,29721,29726,29727,16098,16112,16116,16122,29907,16142,16211,30018,
+30061,30066,30093,16252,30152,30172,16320,30285,16343,30324,16348,30330,20316,
+29064,22051,35200,22633,16413,30531,16441,26465,16453,13787,30616,16490,16495,
+23646,30654,30667,22770,30744,28857,30748,
+16552,30777,30791,30801,30822,33864,21813,31027,26627,31026,16643,16649,31121,
+31129,36795,31238,36796,16743,31377,16818,31420,33401,16836,31439,31451,16847,
+20001,31586,31596,31611,31762,31771,16992,17018,31867,31900,17036,31928,17044,
+31981,36755,28864,3279,32207,32212,32208,32253,32686,32692,29343,17303,32800,
+32805,31545,32814,32817,32852,15820,22452,28832,32951,33001,17389,33036,29482,
+33038,33042,30048,33044,17409,15161,33110,33113,33114,17427,22586,33148,33156,
+17445,33171,17453,33189,22511,33217,33252,33364,17551,33446,33398,33482,33496,
+33535,17584,33623,38505,27018,33797,28917,33892,24803,33928,17668,33982,34017,
+34040,34064,34104,34130,17723,34159,34160,34272,17783,34418,34450,34482,34543,
+38469,34699,17926,17943,34990,35071,35108,35143,35217,31079,35369,35384,35476,
+35508,35921,36052,36082,36124,18328,22623,36291,18413,20206,36410,21976,22356,
+36465,22005,36528,18487,36558,36578,36580,36589,36594,36791,36801,36810,36812,
+36915,39364,18605,39136,37395,18718,37416,37464,37483,37553,37550,37567,37603,
+37611,37619,37620,37629,37699,37764,37805,18757,18769,40639,37911,21249,37917,
+37933,37950,18794,37972,38009,38189,38306,18855,38388,38451,18917,26528,18980,
+38720,18997,38834,38850,22100,19172,24808,39097,19225,39153,22596,39182,39193,
+20916,39196,39223,39234,39261,39266,19312,39365,19357,39484,39695,31363,39785,
+39809,39901,39921,39924,19565,39968,14191,7106,40265,39994,40702,22096,40339,
+40381,40384,40444,38134,36790,40571,40620,40625,40637,40646,38108,40674,40689,
+40696,31432,40772,148,695,928,26906,38083,22956,
+1239,22592,38081,14265,1493,1557,1654,5818,22359,29043,2754,2765,3007,21610,
+63547,3019,21662,3067,3131,3155,3173,3196,24807,3213,22138,3253,3293,3309,
+3439,3506,3528,26965,39983,34725,3588,3598,3799,3984,3885,3699,23584,4028,
+24075,4188,4175,4214,26398,4219,4232,4246,13895,4287,4307,4399,4411,21348,
+33965,4835,4981,4918,35713,5495,5657,6083,6087,20088,28859,6189,6506,6701,
+6725,7210,7280,7340,7880,25283,7893,7957,29080,26709,8261,27113,14024,8828,
+9175,9210,10026,10353,10575,33533,10599,10643,10965,35237,10984,36768,11022,
+38840,11071,38983,39613,11340,0,11400,11447,23528,11528,11538,11703,11669,
+11842,12148,12236,12339,12390,13087,13278,24497,26184,26303,31353,13671,13811,
+0,18874,0,13850,14102,0,838,22709,26382,26904,15015,30295,24546,15889,16057,
+30206,8346,18640,19128,16665,35482,17134,17165,16443,17204,17302,19013,1482,
+20946,1553,22943,7848,15294,15615,17412,17622,22408,18036,14747,18223,34280,
+39369,14178,8643,35678,35662,0,18450,18683,18965,29193,19136,3192,22885,20133,
+20358,1913,36570,20524,21135,22335,29041,21145,21529,16202,19111,21948,21574,
+21614,27474,0,13427,21823,30258,21854,18200,21858,21862,22471,18751,22621,
+20582,13563,13260,0,22787,18300,35144,23214,23433,23558,7568,22433,29009,0,
+24834,31762,36950,25010,20378,35682,25602,25674,23899,27639,0,25732,6428,
+35562,18934,25736,16367,25874,19392,26047,26293,10011,37989,22497,24981,23079,
+63693,0,22201,17697,26364,20074,18740,38486,28047,27837,13848,35191,
+26521,26734,25617,26718,0,26823,31554,37056,2577,26918,0,26937,31301,0,27130,
+39462,27181,13919,25705,33,31107,27188,27483,23852,13593,0,27549,18128,27812,
+30011,34917,28078,22710,14108,9613,28747,29133,15444,29312,29317,37505,8570,
+29323,37680,29414,18896,27705,38047,29776,3832,34855,35061,10534,33907,6065,
+28344,18986,6176,14756,14009,0,0,17727,26294,40109,39076,35139,30668,30808,
+22230,16607,5642,14753,14127,33000,5061,29101,33638,31197,37288,0,19639,28847,
+35243,31229,31242,31499,32102,16762,31555,31102,32777,28597,41695,27139,33560,
+21410,28167,37823,26678,38749,33135,32803,27061,5101,12847,32840,23941,35888,
+32899,22293,38947,35145,23979,18824,26046,27093,21458,19109,16257,15377,26422,
+32912,33012,33070,8097,33103,33161,33199,33306,33542,33583,33674,13770,33896,
+34474,18682,25574,35158,30728,37461,35256,17394,35303,17375,35304,35654,35796,
+23032,35849,0,36805,37100,0,37136,37180,15863,37214,19146,36816,29327,22155,
+38119,38377,38320,38328,38706,39121,39241,39274,39363,39464,39694,40282,40347,
+32415,40696,40739,19620,38215,41619,29090,41727,19857,36882,42443,19868,3228,
+36798,21953,36794,9392,36793,19091,17673,32383,28502,27313,20202,13540,35628,
+30877,14138,36480,6133,32804,35692,35737,31294,26287,15851,30293,15543,22069,
+22870,20122,24193,25176,22207,3693,36366,23405,16008,19614,25566,0,6134,6267,
+25904,22061,23626,21530,21265,15814,40344,19581,22050,22046,32585,24280,22901,
+15680,34672,19996,4074,3401,14010,33047,40286,36120,30267,40005,30286,30649,
+37701,21554,
+33096,33527,22053,33074,33816,32957,21994,31074,22083,21526,3741,13774,22021,
+22001,26353,33506,13869,30004,22000,21946,21655,21874,3137,3222,24272,20808,
+3702,11362,3746,40619,32090,21982,4213,25245,38765,21652,36045,29174,37238,
+25596,25529,25598,21865,11075,40050,11955,20890,13535,3495,20903,21581,21790,
+21779,30310,36397,26762,30129,32950,34820,34694,35015,33206,33820,4289,17644,
+29444,18182,23440,33547,26771,22139,9972,32047,16803,32115,28368,29366,37232,
+4569,37384,15612,42665,3756,3833,29286,7330,18254,20418,32761,4075,16634,
+40029,25887,11680,18675,18400,40316,4076,3594,0,30115,4077,0,24648,4487,29091,
+32398,40272,19994,19972,13687,23309,27826,21351,13996,14812,21373,13989,17944,
+22682,19310,33325,21579,22442,23189,2425,0,14930,9317,29556,40620,19721,39917,
+15614,40752,19547,20393,38302,40926,33884,15798,29362,26547,14112,25390,32037,
+16119,15916,14890,36872,21196,15988,13946,17897,1166,30272,23280,3766,30842,
+32558,22695,16575,22140,39819,23924,30292,42036,40581,19681,0,14331,24857,
+12506,17394,0,22109,4777,22439,18787,40454,21044,28846,13741,0,40316,31830,
+39737,22494,5996,23635,25811,38096,25397,29028,34477,3368,27938,19170,3441,0,
+20990,7951,23950,38659,7633,40577,36940,31519,39682,23761,31651,25192,25397,
+39679,31695,39722,31870,0,31810,31878,39957,31740,39689,0,39963,18750,40794,
+21875,23491,20477,40600,20466,21088,15878,21201,22375,20566,22967,24082,38856,
+40363,36700,21609,38836,39232,38842,21292,24880,26924,21466,39946,40194,19515,
+38465,27008,20646,
+30022,5997,39386,21107,0,37209,38529,37212,0,37201,36503,25471,27939,27338,
+22033,37262,30074,25221,1020,29519,31856,23585,15613,0,18713,30422,39837,
+20010,3284,33726,34882,0,23626,27072,0,22394,21023,24053,20174,27697,498,
+20281,21660,21722,21146,36226,13822,0,13811,0,27474,37244,40869,39831,38958,
+39092,39610,40616,40580,29050,31508,0,27642,34840,32632,0,22048,42570,36471,
+40787,0,36308,36431,40476,36353,25218,33661,36392,36469,31443,19063,31294,
+30936,27882,35431,30215,35418,40742,27854,34774,30147,41650,30803,63552,36108,
+29410,29553,35629,29442,29937,36075,19131,34351,24506,34976,17591,0,6203,
+28165,0,35454,9499,0,24829,30311,39639,40260,37742,39823,34805,0,0,36087,
+29484,38689,39856,13782,29362,19463,31825,39242,24921,24921,19460,40598,24957,
+0,22367,24943,25254,25145,0,14940,25058,21418,13301,25444,26626,13778,23895,
+35778,36826,36409,0,20697,7494,30982,21298,38456,3899,16485,0,30718,0,31938,
+24346,31962,31277,32870,32867,32077,29957,29938,35220,33306,26380,32866,29830,
+32859,29936,33027,30500,35209,26572,30035,28369,34729,34766,33224,34700,35401,
+36013,35651,30507,29944,34010,13877,27058,36262,0,35241,0,28089,34753,16401,
+29927,15835,29046,24740,24988,15569,0,24695,0,32625,35629,0,24809,19326,21024,
+15384,15559,24279,30294,21809,6468,4862,39171,28124,28845,23745,25005,35343,
+13943,238,26694,20238,17762,23327,25420,40784,40614,25195,1351,37595,1503,
+16325,34124,17077,29679,20917,13897,18754,35300,37700,6619,
+33518,15560,30780,26436,25311,18739,35242,672,27571,4869,20395,9453,20488,
+27945,31364,13824,19121,9491,0,894,24484,896,839,28379,1055,0,20737,13434,
+20750,39020,14147,33814,18852,1159,20832,13236,20842,3071,8444,741,9520,1422,
+12851,6531,23426,34685,1459,15513,20914,20920,40244,20937,20943,20945,15580,
+20947,19110,20915,20962,21314,20973,33741,26942,14125,24443,21003,21030,21052,
+21173,21079,21140,21177,21189,31765,34114,21216,34317,27411,0,35550,21833,
+28377,16256,2388,16364,21299,0,3042,27851,5926,26651,29653,24650,16042,14540,
+5864,29149,17570,21357,21364,34475,21374,0,5526,5651,30694,21395,35483,21408,
+21419,21422,29607,22386,16217,29596,21441,21445,27721,20041,22526,21465,15019,
+2959,21472,16363,11683,21494,3191,21523,28793,21803,26199,27995,21613,27475,
+3444,21853,21647,21668,18342,5901,3805,15796,3405,35260,9880,21831,19693,
+21551,29719,21894,21929,0,6359,16442,17746,17461,26291,4276,22071,26317,12938,
+26276,26285,22093,22095,30961,22257,38791,21502,22272,22255,22253,35686,13859,
+4687,22342,16805,27758,28811,22338,14001,27774,22502,5142,22531,5204,17251,
+22566,19445,22620,22698,13665,22752,22748,4668,22779,23551,22339,41296,17016,
+37843,13729,22815,26790,14019,28249,5694,23076,21843,5778,34053,22985,3406,
+27777,27946,6108,23001,6139,6066,28070,28017,6184,5845,23033,28229,23211,
+23139,14054,18857,0,14088,23190,29797,23251,28577,9556,15749,6417,14130,5816,
+24195,21200,23414,25992,23420,31246,16388,18525,516,23509,24928,6708,22988,
+1445,23539,
+23453,19728,23557,6980,23571,29646,23572,7333,27432,23625,18653,23685,23785,
+23791,23947,7673,7735,23824,23832,23878,7844,23738,24023,33532,14381,18689,
+8265,8563,33415,14390,15298,24110,27274,0,24186,17596,3283,21414,20151,0,
+21416,6001,24073,24308,33922,24313,24315,14496,24316,26686,37915,24333,449,
+63636,15070,18606,4922,24378,26760,9168,0,9329,24419,38845,28270,24434,37696,
+35382,24487,23990,15711,21072,8042,28920,9832,37334,670,35369,24625,26245,
+6263,14691,15815,13881,22416,10164,31089,15936,24734,0,24755,18818,18831,
+31315,29860,20705,23200,24932,33828,24898,63654,28370,24961,20980,1622,24967,
+23466,16311,10335,25043,35741,39261,25040,14642,10624,10433,24611,24924,25886,
+25483,280,25285,6000,25301,11789,25452,18911,14871,25656,25592,5006,6140,0,
+28554,11830,38932,16524,22301,25825,25829,38011,14950,25658,14935,25933,28438,
+18984,18979,25989,25965,25951,12414,26037,18752,19255,26065,16600,6185,26080,
+26083,24543,13312,26136,12791,12792,26180,12708,12709,26187,3701,26215,20966,
+26227,0,7741,12849,34292,12744,21267,30661,10487,39332,26370,17308,18977,
+15147,27130,14274,0,26471,26466,16845,37101,26583,17641,26658,28240,37436,
+26625,13286,28064,26717,13423,27105,27147,35551,26995,26819,13773,26881,26880,
+15666,14849,13884,15232,26540,26977,35402,17148,26934,27032,15265,969,33635,
+20624,27129,13913,8490,27205,14083,27293,15347,26545,27336,37276,15373,27421,
+2339,24798,27445,27508,10189,28341,15067,949,6488,14144,21537,15194,27617,
+16124,27612,27703,9355,18673,27473,
+27738,33318,27769,15804,17605,15805,16804,18700,18688,15561,14053,15595,3378,
+39811,12793,9361,32655,26679,27941,28065,28139,28054,27996,28284,28420,18815,
+16517,28274,34099,28532,20935,0,0,33838,35617,0,15919,29779,16258,31180,28239,
+23185,12363,28664,14093,28573,15920,28410,5271,16445,17749,37872,28484,28508,
+15694,28532,37232,15675,28575,16708,28627,16529,16725,16441,16368,16308,16703,
+20959,16726,16727,16704,25053,28747,28798,28839,28801,28876,28885,28886,28895,
+16644,15848,29108,29078,17015,28971,28997,23176,29002,0,23708,17253,29007,
+37730,17089,28972,17498,18983,18978,29114,35816,28861,29198,37954,29205,22801,
+37955,29220,37697,22021,29230,29248,18804,26813,29269,29271,15957,12356,26637,
+28477,29314,0,29483,18467,34859,18669,34820,29480,29486,29647,29610,3130,
+27182,29641,29769,16866,5863,18980,26147,14021,18871,18829,18939,29687,29717,
+26883,18982,29753,1475,16087,0,10413,29792,36530,29767,29668,29814,33721,
+29804,14128,29812,37873,27180,29826,18771,19084,16735,19065,35727,23366,35843,
+6302,29896,6536,29966,0,29982,36569,6731,23511,36524,37765,30029,30026,30055,
+30062,20354,16132,19731,30094,29789,30110,30132,30210,30252,30289,30287,30319,
+30326,25589,30352,33263,14328,26897,26894,30369,30373,30391,30412,28575,33890,
+20637,20861,7708,30494,30502,30528,25775,21024,30552,12972,30639,35172,35176,
+5825,30708,0,4982,18962,26826,30895,30919,30931,38565,31022,21984,30935,31028,
+30897,30220,36792,34948,35627,24707,9756,31110,35072,26882,31104,22615,31133,
+31545,31036,31145,28202,28966,
+16040,31174,37133,31188,1312,17503,21007,47234,248,16384,43296,1102,0,0,2868,
+1,0,0,0,0,0,0,0,3072,64,0,0,0,1024,88,60,0,0,23680,56493,48115,17353,60910,
+4004,49446,30363,61426,64478,63482,12815,44868,61438,65277,24593,176,8448,
+33049,4128,43144,8544,9321,17408,50313,0,16387,53,33859,20785,26771,514,0,0,0,
+0,0,16384,256,44160,33380,35904,37025,20484,54368,53760,6186,26781,38709,
+55375,8440,33476,10268,30082,660,16440,41376,4293,19825,3524,47512,23390,
+17153,39327,30723,57888,2079,393,16585,775,39437,21136,20433,892,8450,49184,
+4974,46467,62939,30693,20368,39447,5942,12,47726,12041,21600,7680,26744,28706,
+40534,62245,46990,2839,59119,6007,7003,4289,36248,6162,53174,12545,6770,11355,
+49334,57888,23747,7042,56032,34254,16598,21673,53259,18447,16452,2320,16596,
+15278,7780,11076,2071,33414,6198,35232,40167,2139,900,55810,60560,34779,49029,
+44450,36509,39069,9504,70,40774,58239,51669,62596,19926,58118,6326,2322,0,
+1024,0,32,0,512,0,0,0,0,8192,0,0,0,0,0,0,8,36352,28280,16223,56702,63293,
+39932,44796,65490,27535,59377,47807,28334,61207,42972,46654,30645,37577,42455,
+19126,39790,33209,26445,21758,39921,65122,21103,14039,49150,17705,63873,26045,
+17062,57,16896,36704,37888,16448,45010,53719,219,39072,31666,20998,38944,
+51222,2365,0,1,0,2561,2226,128,0,34820,5152,19472,0,4,17569,16,321,
+2048,61504,20447,22582,62961,32949,26613,16512,20480,16718,33992,23040,55392,
+11009,20481,5793,16580,28402,44049,14624,49348,1800,2316,38552,39876,7184,
+27800,10886,422,4422,58733,50379,37568,8464,4630,29341,27124,5902,41514,62593,
+123,41992,36875,11280,14796,330,5872,2571,3136,59933,17420,17678,2,
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/iconv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/iconv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/iconv.c	(revision 398)
@@ -0,0 +1,458 @@
+#include <iconv.h>
+#include <errno.h>
+#include <wchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdint.h>
+#include "locale_impl.h"
+
+#define UTF_32BE    0300
+#define UTF_16LE    0301
+#define UTF_16BE    0302
+#define UTF_32LE    0303
+#define UCS2BE      0304
+#define UCS2LE      0305
+#define WCHAR_T     0306
+#define US_ASCII    0307
+#define UTF_8       0310
+#define EUC_JP      0320
+#define SHIFT_JIS   0321
+#define GB18030     0330
+#define GBK         0331
+#define GB2312      0332
+#define BIG5        0340
+#define EUC_KR      0350
+
+/* Definitions of charmaps. Each charmap consists of:
+ * 1. Empty-string-terminated list of null-terminated aliases.
+ * 2. Special type code or number of elided entries.
+ * 3. Character table (size determined by field 2). */
+
+static const unsigned char charmaps[] =
+"utf8\0char\0\0\310"
+"wchart\0\0\306"
+"ucs2\0ucs2be\0\0\304"
+"ucs2le\0\0\305"
+"utf16\0utf16be\0\0\302"
+"utf16le\0\0\301"
+"ucs4\0ucs4be\0utf32\0utf32be\0\0\300"
+"ucs4le\0utf32le\0\0\303"
+"ascii\0usascii\0iso646\0iso646us\0\0\307"
+"eucjp\0\0\320"
+"shiftjis\0sjis\0\0\321"
+"gb18030\0\0\330"
+"gbk\0\0\331"
+"gb2312\0\0\332"
+"big5\0bigfive\0cp950\0big5hkscs\0\0\340"
+"euckr\0ksc5601\0ksx1001\0cp949\0\0\350"
+#include "codepages.h"
+;
+
+static const unsigned short legacy_chars[] = {
+#include "legacychars.h"
+};
+
+static const unsigned short jis0208[84][94] = {
+#include "jis0208.h"
+};
+
+static const unsigned short gb18030[126][190] = {
+#include "gb18030.h"
+};
+
+static const unsigned short big5[89][157] = {
+#include "big5.h"
+};
+
+static const unsigned short hkscs[] = {
+#include "hkscs.h"
+};
+
+static const unsigned short ksc[93][94] = {
+#include "ksc.h"
+};
+
+static int fuzzycmp(const unsigned char *a, const unsigned char *b)
+{
+	for (; *a && *b; a++, b++) {
+		while (*a && (*a|32U)-'a'>26 && *a-'0'>10U) a++;
+		if ((*a|32U) != *b) return 1;
+	}
+	return *a != *b;
+}
+
+static size_t find_charmap(const void *name)
+{
+	const unsigned char *s;
+	if (!*(char *)name) name=charmaps; /* "utf8" */
+	for (s=charmaps; *s; ) {
+		if (!fuzzycmp(name, s)) {
+			for (; *s; s+=strlen((void *)s)+1);
+			return s+1-charmaps;
+		}
+		s += strlen((void *)s)+1;
+		if (!*s) {
+			if (s[1] > 0200) s+=2;
+			else s+=2+(128U-s[1])/4*5;
+		}
+	}
+	return -1;
+}
+
+iconv_t iconv_open(const char *to, const char *from)
+{
+	size_t f, t;
+
+	if ((t = find_charmap(to))==-1
+	 || (f = find_charmap(from))==-1
+	 || (charmaps[t] >= 0320)) {
+		errno = EINVAL;
+		return (iconv_t)-1;
+	}
+
+	return (void *)(f<<16 | t);
+}
+
+int iconv_close(iconv_t cd)
+{
+	return 0;
+}
+
+static unsigned get_16(const unsigned char *s, int e)
+{
+	e &= 1;
+	return s[e]<<8 | s[1-e];
+}
+
+static void put_16(unsigned char *s, unsigned c, int e)
+{
+	e &= 1;
+	s[e] = c>>8;
+	s[1-e] = c;
+}
+
+static unsigned get_32(const unsigned char *s, int e)
+{
+	e &= 3;
+	return (s[e]+0U)<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3];
+}
+
+static void put_32(unsigned char *s, unsigned c, int e)
+{
+	e &= 3;
+	s[e^0] = c>>24;
+	s[e^1] = c>>16;
+	s[e^2] = c>>8;
+	s[e^3] = c;
+}
+
+/* Adapt as needed */
+#define mbrtowc_utf8 mbrtowc
+#define wctomb_utf8 wctomb
+
+static unsigned legacy_map(const unsigned char *map, unsigned c)
+{
+	unsigned x = c - 128 - map[-1];
+	x = legacy_chars[ map[x*5/4]>>2*x%8 |
+		(map[x*5/4+1]<<(8-2*x%8) & 1023) ];
+	return x ? x : c;
+}
+
+size_t iconv(iconv_t cd0, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb)
+{
+	size_t x=0;
+	unsigned long cd = (unsigned long)cd0;
+	unsigned to = cd & 0xffff;
+	unsigned from = cd >> 16;
+	const unsigned char *map = charmaps+from+1;
+	const unsigned char *tomap = charmaps+to+1;
+	mbstate_t st = {0};
+	wchar_t wc;
+	unsigned c, d;
+	size_t k, l;
+	int err;
+	unsigned char type = map[-1];
+	unsigned char totype = tomap[-1];
+	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
+
+	if (!in || !*in || !*inb) return 0;
+
+	*ploc = UTF8_LOCALE;
+
+	for (; *inb; *in+=l, *inb-=l) {
+		c = *(unsigned char *)*in;
+		l = 1;
+
+		if (c >= 128 || type-UTF_32BE < 7U) switch (type) {
+		case UTF_8:
+			l = mbrtowc_utf8(&wc, *in, *inb, &st);
+			if (!l) l++;
+			else if (l == (size_t)-1) goto ilseq;
+			else if (l == (size_t)-2) goto starved;
+			c = wc;
+			break;
+		case US_ASCII:
+			goto ilseq;
+		case WCHAR_T:
+			l = sizeof(wchar_t);
+			if (*inb < l) goto starved;
+			c = *(wchar_t *)*in;
+			if (0) {
+		case UTF_32BE:
+		case UTF_32LE:
+			l = 4;
+			if (*inb < 4) goto starved;
+			c = get_32((void *)*in, type);
+			}
+			if (c-0xd800u < 0x800u || c >= 0x110000u) goto ilseq;
+			break;
+		case UCS2BE:
+		case UCS2LE:
+		case UTF_16BE:
+		case UTF_16LE:
+			l = 2;
+			if (*inb < 2) goto starved;
+			c = get_16((void *)*in, type);
+			if ((unsigned)(c-0xdc00) < 0x400) goto ilseq;
+			if ((unsigned)(c-0xd800) < 0x400) {
+				if (type-UCS2BE < 2U) goto ilseq;
+				l = 4;
+				if (*inb < 4) goto starved;
+				d = get_16((void *)(*in + 2), type);
+				if ((unsigned)(d-0xdc00) >= 0x400) goto ilseq;
+				c = ((c-0xd7c0)<<10) + (d-0xdc00);
+			}
+			break;
+		case SHIFT_JIS:
+			if (c-0xa1 <= 0xdf-0xa1) {
+				c += 0xff61-0xa1;
+				break;
+			}
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			if (c-129 <= 159-129) c -= 129;
+			else if (c-224 <= 239-224) c -= 193;
+			else goto ilseq;
+			c *= 2;
+			if (d-64 <= 158-64) {
+				if (d==127) goto ilseq;
+				if (d>127) d--;
+				d -= 64;
+			} else if (d-159 <= 252-159) {
+				c++;
+				d -= 159;
+			}
+			c = jis0208[c][d];
+			if (!c) goto ilseq;
+			break;
+		case EUC_JP:
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			if (c==0x8e) {
+				c = d;
+				if (c-0xa1 > 0xdf-0xa1) goto ilseq;
+				c += 0xff61 - 0xa1;
+				break;
+			}
+			c -= 0xa1;
+			d -= 0xa1;
+			if (c >= 84 || d >= 94) goto ilseq;
+			c = jis0208[c][d];
+			if (!c) goto ilseq;
+			break;
+		case GB2312:
+			if (c < 0xa1) goto ilseq;
+		case GBK:
+		case GB18030:
+			c -= 0x81;
+			if (c >= 126) goto ilseq;
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			if (d < 0xa1 && type == GB2312) goto ilseq;
+			if (d-0x40>=191 || d==127) {
+				if (d-'0'>9 || type != GB18030)
+					goto ilseq;
+				l = 4;
+				if (*inb < 4) goto starved;
+				c = (10*c + d-'0') * 1260;
+				d = *((unsigned char *)*in + 2);
+				if (d-0x81>126) goto ilseq;
+				c += 10*(d-0x81);
+				d = *((unsigned char *)*in + 3);
+				if (d-'0'>9) goto ilseq;
+				c += d-'0';
+				c += 128;
+				for (d=0; d<=c; ) {
+					k = 0;
+					for (int i=0; i<126; i++)
+						for (int j=0; j<190; j++)
+							if (gb18030[i][j]-d <= c-d)
+								k++;
+					d = c+1;
+					c += k;
+				}
+				break;
+			}
+			d -= 0x40;
+			if (d>63) d--;
+			c = gb18030[c][d];
+			break;
+		case BIG5:
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			if (d-0x40>=0xff-0x40 || d-0x7f<0xa1-0x7f) goto ilseq;
+			d -= 0x40;
+			if (d > 0x3e) d -= 0x22;
+			if (c-0xa1>=0xfa-0xa1) {
+				if (c-0x87>=0xff-0x87) goto ilseq;
+				if (c < 0xa1) c -= 0x87;
+				else c -= 0x87 + (0xfa-0xa1);
+				c = (hkscs[4867+(c*157+d)/16]>>(c*157+d)%16)%2<<17
+					| hkscs[c*157+d];
+				/* A few HKSCS characters map to pairs of UCS
+				 * characters. These are mapped to surrogate
+				 * range in the hkscs table then hard-coded
+				 * here. Ugly, yes. */
+				if (c/256 == 0xdc) {
+					if (totype-0300U > 8) k = 2;
+					else k = "\10\4\4\10\4\4\10\2\4"[totype-0300];
+					if (k > *outb) goto toobig;
+					x += iconv((iconv_t)(uintptr_t)to,
+						&(char *){"\303\212\314\204"
+						"\303\212\314\214"
+						"\303\252\314\204"
+						"\303\252\314\214"
+						+c%256}, &(size_t){4},
+						out, outb);
+					continue;
+				}
+				if (!c) goto ilseq;
+				break;
+			}
+			c -= 0xa1;
+			c = big5[c][d]|(c==0x27&&(d==0x3a||d==0x3c||d==0x42))<<17;
+			if (!c) goto ilseq;
+			break;
+		case EUC_KR:
+			l = 2;
+			if (*inb < 2) goto starved;
+			d = *((unsigned char *)*in + 1);
+			c -= 0xa1;
+			d -= 0xa1;
+			if (c >= 93 || d >= 94) {
+				c += (0xa1-0x81);
+				d += 0xa1;
+				if (c >= 93 || (c>=0xc6-0x81 && d>0x52))
+					goto ilseq;
+				if (d-'A'<26) d = d-'A';
+				else if (d-'a'<26) d = d-'a'+26;
+				else if (d-0x81<0xff-0x81) d = d-0x81+52;
+				else goto ilseq;
+				if (c < 0x20) c = 178*c + d;
+				else c = 178*0x20 + 84*(c-0x20) + d;
+				c += 0xac00;
+				for (d=0xac00; d<=c; ) {
+					k = 0;
+					for (int i=0; i<93; i++)
+						for (int j=0; j<94; j++)
+							if (ksc[i][j]-d <= c-d)
+								k++;
+					d = c+1;
+					c += k;
+				}
+				break;
+			}
+			c = ksc[c][d];
+			if (!c) goto ilseq;
+			break;
+		default:
+			if (c < 128+type) break;
+			c = legacy_map(map, c);
+			if (c==1) goto ilseq;
+		}
+
+		switch (totype) {
+		case WCHAR_T:
+			if (*outb < sizeof(wchar_t)) goto toobig;
+			*(wchar_t *)*out = c;
+			*out += sizeof(wchar_t);
+			*outb -= sizeof(wchar_t);
+			break;
+		case UTF_8:
+			if (*outb < 4) {
+				char tmp[4];
+				k = wctomb_utf8(tmp, c);
+				if (*outb < k) goto toobig;
+				memcpy(*out, tmp, k);
+			} else k = wctomb_utf8(*out, c);
+			*out += k;
+			*outb -= k;
+			break;
+		case US_ASCII:
+			if (c > 0x7f) subst: x++, c='*';
+		default:
+			if (*outb < 1) goto toobig;
+			if (c < 128+totype || (c<256 && c==legacy_map(tomap, c))) {
+			revout:
+				*(*out)++ = c;
+				*outb -= 1;
+				break;
+			}
+			d = c;
+			for (c=128+totype; c<256; c++) {
+				if (d == legacy_map(tomap, c)) {
+					goto revout;
+				}
+			}
+			goto subst;
+		case UCS2BE:
+		case UCS2LE:
+		case UTF_16BE:
+		case UTF_16LE:
+			if (c < 0x10000 || type-UCS2BE < 2U) {
+				if (c >= 0x10000) c = 0xFFFD;
+				if (*outb < 2) goto toobig;
+				put_16((void *)*out, c, totype);
+				*out += 2;
+				*outb -= 2;
+				break;
+			}
+			if (*outb < 4) goto toobig;
+			c -= 0x10000;
+			put_16((void *)*out, (c>>10)|0xd800, totype);
+			put_16((void *)(*out + 2), (c&0x3ff)|0xdc00, totype);
+			*out += 4;
+			*outb -= 4;
+			break;
+		case UTF_32BE:
+		case UTF_32LE:
+			if (*outb < 4) goto toobig;
+			put_32((void *)*out, c, totype);
+			*out += 4;
+			*outb -= 4;
+			break;
+		}
+	}
+	*ploc = loc;
+	return x;
+ilseq:
+	err = EILSEQ;
+	x = -1;
+	goto end;
+toobig:
+	err = E2BIG;
+	x = -1;
+	goto end;
+starved:
+	err = EINVAL;
+	x = -1;
+end:
+	errno = err;
+	*ploc = loc;
+	return x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/jis0208.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/jis0208.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/jis0208.h	(revision 398)
@@ -0,0 +1,550 @@
+12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180,
+65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294,
+12295,12540,8213,8208,65295,92,12316,8214,65372,8230,8229,8216,8217,8220,8221,
+65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300,
+12301,12302,12303,12304,12305,65291,8722,177,215,247,65309,8800,65308,65310,
+8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,162,163,65285,
+65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,
+9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,0,0,0,0,0,0,0,0,0,0,0,
+8712,8715,8838,8839,8834,8835,8746,8745,0,0,0,0,0,0,0,0,8743,8744,172,8658,
+8660,8704,8707,0,0,0,0,0,0,0,0,0,0,0,8736,8869,8978,8706,8711,8801,8786,8810,
+8811,8730,8765,8733,8757,8747,8748,0,0,0,0,0,0,0,8491,8240,9839,9837,9834,
+8224,8225,182,0,0,0,0,9711,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65296,65297,65298,
+65299,65300,65301,65302,65303,65304,65305,0,0,0,0,0,0,0,65313,65314,65315,
+65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,
+65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,0,0,0,0,0,0,65345,
+65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,
+65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,0,0,0,
+0,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,
+12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,
+12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,
+12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,
+12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,
+12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,
+12430,12431,12432,12433,12434,12435,0,0,0,0,0,0,0,0,0,0,0,12449,12450,12451,
+12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,
+12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,
+12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,
+12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,
+12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,
+12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,
+12530,12531,12532,12533,12534,0,0,0,0,0,0,0,0,913,914,915,916,917,918,919,920,
+921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,0,0,0,0,0,0,0,
+0,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,964,
+965,966,967,968,969,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,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,
+1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,
+1066,1067,1068,1069,1070,1071,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1072,1073,1074,
+1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,
+1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,0,
+0,0,0,0,0,0,0,0,0,0,0,0,9472,9474,9484,9488,9496,9492,9500,9516,9508,9524,
+9532,9473,9475,9487,9491,9499,9495,9507,9523,9515,9531,9547,9504,9519,9512,
+9527,9535,9501,9520,9509,9528,9538,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,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,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,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,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,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,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,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,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,
+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,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,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,20124,
+21782,23043,38463,21696,24859,25384,23030,36898,33909,33564,31312,24746,25569,
+28197,26093,33894,33446,39925,26771,22311,26017,25201,23451,22992,34427,39156,
+32098,32190,39822,25110,31903,34999,23433,24245,25353,26263,26696,38343,38797,
+26447,20197,20234,20301,20381,20553,22258,22839,22996,23041,23561,24799,24847,
+24944,26131,26885,28858,30031,30064,31227,32173,32239,32963,33806,34915,35586,
+36949,36986,21307,20117,20133,22495,32946,37057,30959,19968,22769,28322,36920,
+31282,33576,33419,39983,20801,21360,21693,21729,22240,23035,24341,39154,28139,
+32996,34093,38498,38512,38560,38907,21515,21491,23431,28879,32701,36802,38632,
+21359,40284,31418,19985,30867,33276,28198,22040,21764,27421,34074,39995,23013,
+21417,28006,29916,38287,22082,20113,36939,38642,33615,39180,21473,21942,23344,
+24433,26144,26355,26628,27704,27891,27945,29787,30408,31310,38964,33521,34907,
+35424,37613,28082,30123,30410,39365,24742,35585,36234,38322,27022,21421,20870,
+22290,22576,22852,23476,24310,24616,25513,25588,27839,28436,28814,28948,29017,
+29141,29503,32257,33398,33489,34199,36960,37467,40219,22633,26044,27738,29989,
+20985,22830,22885,24448,24540,25276,26106,27178,27431,27572,29579,32705,35158,
+40236,40206,40644,23713,27798,33659,20740,23627,25014,33222,26742,29281,20057,
+20474,21368,24681,28201,31311,38899,19979,21270,20206,20309,20285,20385,20339,
+21152,21487,22025,22799,23233,23478,23521,31185,26247,26524,26550,27468,27827,
+28779,29634,31117,31166,31292,31623,33457,33499,33540,33655,33775,33747,34662,
+35506,22057,36008,36838,36942,38686,34442,20420,23784,25105,29273,30011,33253,
+33469,34558,36032,38597,39187,39381,20171,20250,35299,22238,22602,22730,24315,
+24555,24618,24724,24674,25040,25106,25296,25913,39745,26214,26800,28023,28784,
+30028,30342,32117,33445,34809,38283,38542,35997,20977,21182,22806,21683,23475,
+23830,24936,27010,28079,30861,33995,34903,35442,37799,39608,28012,39336,34521,
+22435,26623,34510,37390,21123,22151,21508,24275,25313,25785,26684,26680,27579,
+29554,30906,31339,35226,35282,36203,36611,37101,38307,38548,38761,23398,23731,
+27005,38989,38990,25499,31520,27179,27263,26806,39949,28511,21106,21917,24688,
+25324,27963,28167,28369,33883,35088,36676,19988,39993,21494,26907,27194,38788,
+26666,20828,31427,33970,37340,37772,22107,40232,26658,33541,33841,31909,21000,
+33477,29926,20094,20355,20896,23506,21002,21208,21223,24059,21914,22570,23014,
+23436,23448,23515,24178,24185,24739,24863,24931,25022,25563,25954,26577,26707,
+26874,27454,27475,27735,28450,28567,28485,29872,29976,30435,30475,31487,31649,
+31777,32233,32566,32752,32925,33382,33694,35251,35532,36011,36996,37969,38291,
+38289,38306,38501,38867,39208,33304,20024,21547,23736,24012,29609,30284,30524,
+23721,32747,36107,38593,38929,38996,39000,20225,20238,21361,21916,22120,22522,
+22855,23305,23492,23696,24076,24190,24524,25582,26426,26071,26082,26399,26827,
+26820,27231,24112,27589,27671,27773,30079,31048,23395,31232,32000,24509,35215,
+35352,36020,36215,36556,36637,39138,39438,39740,20096,20605,20736,22931,23452,
+25135,25216,25836,27450,29344,30097,31047,32681,34811,35516,35696,25516,33738,
+38816,21513,21507,21931,26708,27224,35440,30759,26485,40653,21364,23458,33050,
+34384,36870,19992,20037,20167,20241,21450,21560,23470,24339,24613,25937,26429,
+27714,27762,27875,28792,29699,31350,31406,31496,32026,31998,32102,26087,29275,
+21435,23621,24040,25298,25312,25369,28192,34394,35377,36317,37624,28417,31142,
+39770,20136,20139,20140,20379,20384,20689,20807,31478,20849,20982,21332,21281,
+21375,21483,21932,22659,23777,24375,24394,24623,24656,24685,25375,25945,27211,
+27841,29378,29421,30703,33016,33029,33288,34126,37111,37857,38911,39255,39514,
+20208,20957,23597,26241,26989,23616,26354,26997,29577,26704,31873,20677,21220,
+22343,24062,37670,26020,27427,27453,29748,31105,31165,31563,32202,33465,33740,
+34943,35167,35641,36817,37329,21535,37504,20061,20534,21477,21306,29399,29590,
+30697,33510,36527,39366,39368,39378,20855,24858,34398,21936,31354,20598,23507,
+36935,38533,20018,27355,37351,23633,23624,25496,31391,27795,38772,36705,31402,
+29066,38536,31874,26647,32368,26705,37740,21234,21531,34219,35347,32676,36557,
+37089,21350,34952,31041,20418,20670,21009,20804,21843,22317,29674,22411,22865,
+24418,24452,24693,24950,24935,25001,25522,25658,25964,26223,26690,28179,30054,
+31293,31995,32076,32153,32331,32619,33550,33610,34509,35336,35427,35686,36605,
+38938,40335,33464,36814,39912,21127,25119,25731,28608,38553,26689,20625,27424,
+27770,28500,31348,32080,34880,35363,26376,20214,20537,20518,20581,20860,21048,
+21091,21927,22287,22533,23244,24314,25010,25080,25331,25458,26908,27177,29309,
+29356,29486,30740,30831,32121,30476,32937,35211,35609,36066,36562,36963,37749,
+38522,38997,39443,40568,20803,21407,21427,24187,24358,28187,28304,29572,29694,
+32067,33335,35328,35578,38480,20046,20491,21476,21628,22266,22993,23396,24049,
+24235,24359,25144,25925,26543,28246,29392,31946,34996,32929,32993,33776,34382,
+35463,36328,37431,38599,39015,40723,20116,20114,20237,21320,21577,21566,23087,
+24460,24481,24735,26791,27278,29786,30849,35486,35492,35703,37264,20062,39881,
+20132,20348,20399,20505,20502,20809,20844,21151,21177,21246,21402,21475,21521,
+21518,21897,22353,22434,22909,23380,23389,23439,24037,24039,24055,24184,24195,
+24218,24247,24344,24658,24908,25239,25304,25511,25915,26114,26179,26356,26477,
+26657,26775,27083,27743,27946,28009,28207,28317,30002,30343,30828,31295,31968,
+32005,32024,32094,32177,32789,32771,32943,32945,33108,33167,33322,33618,34892,
+34913,35611,36002,36092,37066,37237,37489,30783,37628,38308,38477,38917,39321,
+39640,40251,21083,21163,21495,21512,22741,25335,28640,35946,36703,40633,20811,
+21051,21578,22269,31296,37239,40288,40658,29508,28425,33136,29969,24573,24794,
+39592,29403,36796,27492,38915,20170,22256,22372,22718,23130,24680,25031,26127,
+26118,26681,26801,28151,30165,32058,33390,39746,20123,20304,21449,21766,23919,
+24038,24046,26619,27801,29811,30722,35408,37782,35039,22352,24231,25387,20661,
+20652,20877,26368,21705,22622,22971,23472,24425,25165,25505,26685,27507,28168,
+28797,37319,29312,30741,30758,31085,25998,32048,33756,35009,36617,38555,21092,
+22312,26448,32618,36001,20916,22338,38442,22586,27018,32948,21682,23822,22524,
+30869,40442,20316,21066,21643,25662,26152,26388,26613,31364,31574,32034,37679,
+26716,39853,31545,21273,20874,21047,23519,25334,25774,25830,26413,27578,34217,
+38609,30352,39894,25420,37638,39851,30399,26194,19977,20632,21442,23665,24808,
+25746,25955,26719,29158,29642,29987,31639,32386,34453,35715,36059,37240,39184,
+26028,26283,27531,20181,20180,20282,20351,21050,21496,21490,21987,22235,22763,
+22987,22985,23039,23376,23629,24066,24107,24535,24605,25351,25903,23388,26031,
+26045,26088,26525,27490,27515,27663,29509,31049,31169,31992,32025,32043,32930,
+33026,33267,35222,35422,35433,35430,35468,35566,36039,36060,38604,39164,27503,
+20107,20284,20365,20816,23383,23546,24904,25345,26178,27425,28363,27835,29246,
+29885,30164,30913,31034,32780,32819,33258,33940,36766,27728,40575,24335,35672,
+40235,31482,36600,23437,38635,19971,21489,22519,22833,23241,23460,24713,28287,
+28422,30142,36074,23455,34048,31712,20594,26612,33437,23649,34122,32286,33294,
+20889,23556,25448,36198,26012,29038,31038,32023,32773,35613,36554,36974,34503,
+37034,20511,21242,23610,26451,28796,29237,37196,37320,37675,33509,23490,24369,
+24825,20027,21462,23432,25163,26417,27530,29417,29664,31278,33131,36259,37202,
+39318,20754,21463,21610,23551,25480,27193,32172,38656,22234,21454,21608,23447,
+23601,24030,20462,24833,25342,27954,31168,31179,32066,32333,32722,33261,33311,
+33936,34886,35186,35728,36468,36655,36913,37195,37228,38598,37276,20160,20303,
+20805,21313,24467,25102,26580,27713,28171,29539,32294,37325,37507,21460,22809,
+23487,28113,31069,32302,31899,22654,29087,20986,34899,36848,20426,23803,26149,
+30636,31459,33308,39423,20934,24490,26092,26991,27529,28147,28310,28516,30462,
+32020,24033,36981,37255,38918,20966,21021,25152,26257,26329,28186,24246,32210,
+32626,26360,34223,34295,35576,21161,21465,22899,24207,24464,24661,37604,38500,
+20663,20767,21213,21280,21319,21484,21736,21830,21809,22039,22888,22974,23100,
+23477,23558,23567,23569,23578,24196,24202,24288,24432,25215,25220,25307,25484,
+25463,26119,26124,26157,26230,26494,26786,27167,27189,27836,28040,28169,28248,
+28988,28966,29031,30151,30465,30813,30977,31077,31216,31456,31505,31911,32057,
+32918,33750,33931,34121,34909,35059,35359,35388,35412,35443,35937,36062,37284,
+37478,37758,37912,38556,38808,19978,19976,19998,20055,20887,21104,22478,22580,
+22732,23330,24120,24773,25854,26465,26454,27972,29366,30067,31331,33976,35698,
+37304,37664,22065,22516,39166,25325,26893,27542,29165,32340,32887,33394,35302,
+39135,34645,36785,23611,20280,20449,20405,21767,23072,23517,23529,24515,24910,
+25391,26032,26187,26862,27035,28024,28145,30003,30137,30495,31070,31206,32051,
+33251,33455,34218,35242,35386,36523,36763,36914,37341,38663,20154,20161,20995,
+22645,22764,23563,29978,23613,33102,35338,36805,38499,38765,31525,35535,38920,
+37218,22259,21416,36887,21561,22402,24101,25512,27700,28810,30561,31883,32736,
+34928,36930,37204,37648,37656,38543,29790,39620,23815,23913,25968,26530,36264,
+38619,25454,26441,26905,33733,38935,38592,35070,28548,25722,23544,19990,28716,
+30045,26159,20932,21046,21218,22995,24449,24615,25104,25919,25972,26143,26228,
+26866,26646,27491,28165,29298,29983,30427,31934,32854,22768,35069,35199,35488,
+35475,35531,36893,37266,38738,38745,25993,31246,33030,38587,24109,24796,25114,
+26021,26132,26512,30707,31309,31821,32318,33034,36012,36196,36321,36447,30889,
+20999,25305,25509,25666,25240,35373,31363,31680,35500,38634,32118,33292,34633,
+20185,20808,21315,21344,23459,23554,23574,24029,25126,25159,25776,26643,26676,
+27849,27973,27927,26579,28508,29006,29053,26059,31359,31661,32218,32330,32680,
+33146,33307,33337,34214,35438,36046,36341,36984,36983,37549,37521,38275,39854,
+21069,21892,28472,28982,20840,31109,32341,33203,31950,22092,22609,23720,25514,
+26366,26365,26970,29401,30095,30094,30990,31062,31199,31895,32032,32068,34311,
+35380,38459,36961,40736,20711,21109,21452,21474,20489,21930,22766,22863,29245,
+23435,23652,21277,24803,24819,25436,25475,25407,25531,25805,26089,26361,24035,
+27085,27133,28437,29157,20105,30185,30456,31379,31967,32207,32156,32865,33609,
+33624,33900,33980,34299,35013,36208,36865,36973,37783,38684,39442,20687,22679,
+24974,33235,34101,36104,36896,20419,20596,21063,21363,24687,25417,26463,28204,
+36275,36895,20439,23646,36042,26063,32154,21330,34966,20854,25539,23384,23403,
+23562,25613,26449,36956,20182,22810,22826,27760,35409,21822,22549,22949,24816,
+25171,26561,33333,26965,38464,39364,39464,20307,22534,23550,32784,23729,24111,
+24453,24608,24907,25140,26367,27888,28382,32974,33151,33492,34955,36024,36864,
+36910,38538,40667,39899,20195,21488,22823,31532,37261,38988,40441,28381,28711,
+21331,21828,23429,25176,25246,25299,27810,28655,29730,35351,37944,28609,35582,
+33592,20967,34552,21482,21481,20294,36948,36784,22890,33073,24061,31466,36799,
+26842,35895,29432,40008,27197,35504,20025,21336,22022,22374,25285,25506,26086,
+27470,28129,28251,28845,30701,31471,31658,32187,32829,32966,34507,35477,37723,
+22243,22727,24382,26029,26262,27264,27573,30007,35527,20516,30693,22320,24347,
+24677,26234,27744,30196,31258,32622,33268,34584,36933,39347,31689,30044,31481,
+31569,33988,36880,31209,31378,33590,23265,30528,20013,20210,23449,24544,25277,
+26172,26609,27880,34411,34935,35387,37198,37619,39376,27159,28710,29482,33511,
+33879,36015,19969,20806,20939,21899,23541,24086,24115,24193,24340,24373,24427,
+24500,25074,25361,26274,26397,28526,29266,30010,30522,32884,33081,33144,34678,
+35519,35548,36229,36339,37530,38263,38914,40165,21189,25431,30452,26389,27784,
+29645,36035,37806,38515,27941,22684,26894,27084,36861,37786,30171,36890,22618,
+26626,25524,27131,20291,28460,26584,36795,34086,32180,37716,26943,28528,22378,
+22775,23340,32044,29226,21514,37347,40372,20141,20302,20572,20597,21059,35998,
+21576,22564,23450,24093,24213,24237,24311,24351,24716,25269,25402,25552,26799,
+27712,30855,31118,31243,32224,33351,35330,35558,36420,36883,37048,37165,37336,
+40718,27877,25688,25826,25973,28404,30340,31515,36969,37841,28346,21746,24505,
+25764,36685,36845,37444,20856,22635,22825,23637,24215,28155,32399,29980,36028,
+36578,39003,28857,20253,27583,28593,30000,38651,20814,21520,22581,22615,22956,
+23648,24466,26007,26460,28193,30331,33759,36077,36884,37117,37709,30757,30778,
+21162,24230,22303,22900,24594,20498,20826,20908,20941,20992,21776,22612,22616,
+22871,23445,23798,23947,24764,25237,25645,26481,26691,26812,26847,30423,28120,
+28271,28059,28783,29128,24403,30168,31095,31561,31572,31570,31958,32113,21040,
+33891,34153,34276,35342,35588,35910,36367,36867,36879,37913,38518,38957,39472,
+38360,20685,21205,21516,22530,23566,24999,25758,27934,30643,31461,33012,33796,
+36947,37509,23776,40199,21311,24471,24499,28060,29305,30563,31167,31716,27602,
+29420,35501,26627,27233,20984,31361,26932,23626,40182,33515,23493,37193,28702,
+22136,23663,24775,25958,27788,35930,36929,38931,21585,26311,37389,22856,37027,
+20869,20045,20970,34201,35598,28760,25466,37707,26978,39348,32260,30071,21335,
+26976,36575,38627,27741,20108,23612,24336,36841,21250,36049,32905,34425,24319,
+26085,20083,20837,22914,23615,38894,20219,22922,24525,35469,28641,31152,31074,
+23527,33905,29483,29105,24180,24565,25467,25754,29123,31896,20035,24316,20043,
+22492,22178,24745,28611,32013,33021,33075,33215,36786,35223,34468,24052,25226,
+25773,35207,26487,27874,27966,29750,30772,23110,32629,33453,39340,20467,24259,
+25309,25490,25943,26479,30403,29260,32972,32954,36649,37197,20493,22521,23186,
+26757,26995,29028,29437,36023,22770,36064,38506,36889,34687,31204,30695,33833,
+20271,21093,21338,25293,26575,27850,30333,31636,31893,33334,34180,36843,26333,
+28448,29190,32283,33707,39361,40614,20989,31665,30834,31672,32903,31560,27368,
+24161,32908,30033,30048,20843,37474,28300,30330,37271,39658,20240,32624,25244,
+31567,38309,40169,22138,22617,34532,38588,20276,21028,21322,21453,21467,24070,
+25644,26001,26495,27710,27726,29256,29359,29677,30036,32321,33324,34281,36009,
+31684,37318,29033,38930,39151,25405,26217,30058,30436,30928,34115,34542,21290,
+21329,21542,22915,24199,24444,24754,25161,25209,25259,26000,27604,27852,30130,
+30382,30865,31192,32203,32631,32933,34987,35513,36027,36991,38750,39131,27147,
+31800,20633,23614,24494,26503,27608,29749,30473,32654,40763,26570,31255,21305,
+30091,39661,24422,33181,33777,32920,24380,24517,30050,31558,36924,26727,23019,
+23195,32016,30334,35628,20469,24426,27161,27703,28418,29922,31080,34920,35413,
+35961,24287,25551,30149,31186,33495,37672,37618,33948,34541,39981,21697,24428,
+25996,27996,28693,36007,36051,38971,25935,29942,19981,20184,22496,22827,23142,
+23500,20904,24067,24220,24598,25206,25975,26023,26222,28014,29238,31526,33104,
+33178,33433,35676,36000,36070,36212,38428,38468,20398,25771,27494,33310,33889,
+34154,37096,23553,26963,39080,33914,34135,20239,21103,24489,24133,26381,31119,
+33145,35079,35206,28149,24343,25173,27832,20175,29289,39826,20998,21563,22132,
+22707,24996,25198,28954,22894,31881,31966,32027,38640,25991,32862,19993,20341,
+20853,22592,24163,24179,24330,26564,20006,34109,38281,38491,31859,38913,20731,
+22721,30294,30887,21029,30629,34065,31622,20559,22793,29255,31687,32232,36794,
+36820,36941,20415,21193,23081,24321,38829,20445,33303,37610,22275,25429,27497,
+29995,35036,36628,31298,21215,22675,24917,25098,26286,27597,31807,33769,20515,
+20472,21253,21574,22577,22857,23453,23792,23791,23849,24214,25265,25447,25918,
+26041,26379,27861,27873,28921,30770,32299,32990,33459,33804,34028,34562,35090,
+35370,35914,37030,37586,39165,40179,40300,20047,20129,20621,21078,22346,22952,
+24125,24536,24537,25151,26292,26395,26576,26834,20882,32033,32938,33192,35584,
+35980,36031,37502,38450,21536,38956,21271,20693,21340,22696,25778,26420,29287,
+30566,31302,37350,21187,27809,27526,22528,24140,22868,26412,32763,20961,30406,
+25705,30952,39764,40635,22475,22969,26151,26522,27598,21737,27097,24149,33180,
+26517,39850,26622,40018,26717,20134,20451,21448,25273,26411,27819,36804,20397,
+32365,40639,19975,24930,28288,28459,34067,21619,26410,39749,24051,31637,23724,
+23494,34588,28234,34001,31252,33032,22937,31885,27665,30496,21209,22818,28961,
+29279,30683,38695,40289,26891,23167,23064,20901,21517,21629,26126,30431,36855,
+37528,40180,23018,29277,28357,20813,26825,32191,32236,38754,40634,25720,27169,
+33538,22916,23391,27611,29467,30450,32178,32791,33945,20786,26408,40665,30446,
+26466,21247,39173,23588,25147,31870,36016,21839,24758,32011,38272,21249,20063,
+20918,22812,29242,32822,37326,24357,30690,21380,24441,32004,34220,35379,36493,
+38742,26611,34222,37971,24841,24840,27833,30290,35565,36664,21807,20305,20778,
+21191,21451,23461,24189,24736,24962,25558,26377,26586,28263,28044,29494,29495,
+30001,31056,35029,35480,36938,37009,37109,38596,34701,22805,20104,20313,19982,
+35465,36671,38928,20653,24188,22934,23481,24248,25562,25594,25793,26332,26954,
+27096,27915,28342,29076,29992,31407,32650,32768,33865,33993,35201,35617,36362,
+36965,38525,39178,24958,25233,27442,27779,28020,32716,32764,28096,32645,34746,
+35064,26469,33713,38972,38647,27931,32097,33853,37226,20081,21365,23888,27396,
+28651,34253,34349,35239,21033,21519,23653,26446,26792,29702,29827,30178,35023,
+35041,37324,38626,38520,24459,29575,31435,33870,25504,30053,21129,27969,28316,
+29705,30041,30827,31890,38534,31452,40845,20406,24942,26053,34396,20102,20142,
+20698,20001,20940,23534,26009,26753,28092,29471,30274,30637,31260,31975,33391,
+35538,36988,37327,38517,38936,21147,32209,20523,21400,26519,28107,29136,29747,
+33256,36650,38563,40023,40607,29792,22593,28057,32047,39006,20196,20278,20363,
+20919,21169,23994,24604,29618,31036,33491,37428,38583,38646,38666,40599,40802,
+26278,27508,21015,21155,28872,35010,24265,24651,24976,28451,29001,31806,32244,
+32879,34030,36899,37676,21570,39791,27347,28809,36034,36335,38706,21172,23105,
+24266,24324,26391,27004,27028,28010,28431,29282,29436,31725,32769,32894,34635,
+37070,20845,40595,31108,32907,37682,35542,20525,21644,35441,27498,36036,33031,
+24785,26528,40434,20121,20120,39952,35435,34241,34152,26880,28286,30871,33109,
+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,24332,19984,19989,20010,20017,20022,20028,20031,20034,20054,20056,
+20098,20101,35947,20106,33298,24333,20110,20126,20127,20128,20130,20144,20147,
+20150,20174,20173,20164,20166,20162,20183,20190,20205,20191,20215,20233,20314,
+20272,20315,20317,20311,20295,20342,20360,20367,20376,20347,20329,20336,20369,
+20335,20358,20374,20760,20436,20447,20430,20440,20443,20433,20442,20432,20452,
+20453,20506,20520,20500,20522,20517,20485,20252,20470,20513,20521,20524,20478,
+20463,20497,20486,20547,20551,26371,20565,20560,20552,20570,20566,20588,20600,
+20608,20634,20613,20660,20658,20681,20682,20659,20674,20694,20702,20709,20717,
+20707,20718,20729,20725,20745,20737,20738,20758,20757,20756,20762,20769,20794,
+20791,20796,20795,20799,20800,20818,20812,20820,20834,31480,20841,20842,20846,
+20864,20866,22232,20876,20873,20879,20881,20883,20885,20886,20900,20902,20898,
+20905,20906,20907,20915,20913,20914,20912,20917,20925,20933,20937,20955,20960,
+34389,20969,20973,20976,20981,20990,20996,21003,21012,21006,21031,21034,21038,
+21043,21049,21071,21060,21067,21068,21086,21076,21098,21108,21097,21107,21119,
+21117,21133,21140,21138,21105,21128,21137,36776,36775,21164,21165,21180,21173,
+21185,21197,21207,21214,21219,21222,39149,21216,21235,21237,21240,21241,21254,
+21256,30008,21261,21264,21263,21269,21274,21283,21295,21297,21299,21304,21312,
+21318,21317,19991,21321,21325,20950,21342,21353,21358,22808,21371,21367,21378,
+21398,21408,21414,21413,21422,21424,21430,21443,31762,38617,21471,26364,29166,
+21486,21480,21485,21498,21505,21565,21568,21548,21549,21564,21550,21558,21545,
+21533,21582,21647,21621,21646,21599,21617,21623,21616,21650,21627,21632,21622,
+21636,21648,21638,21703,21666,21688,21669,21676,21700,21704,21672,21675,21698,
+21668,21694,21692,21720,21733,21734,21775,21780,21757,21742,21741,21754,21730,
+21817,21824,21859,21836,21806,21852,21829,21846,21847,21816,21811,21853,21913,
+21888,21679,21898,21919,21883,21886,21912,21918,21934,21884,21891,21929,21895,
+21928,21978,21957,21983,21956,21980,21988,21972,22036,22007,22038,22014,22013,
+22043,22009,22094,22096,29151,22068,22070,22066,22072,22123,22116,22063,22124,
+22122,22150,22144,22154,22176,22164,22159,22181,22190,22198,22196,22210,22204,
+22209,22211,22208,22216,22222,22225,22227,22231,22254,22265,22272,22271,22276,
+22281,22280,22283,22285,22291,22296,22294,21959,22300,22310,22327,22328,22350,
+22331,22336,22351,22377,22464,22408,22369,22399,22409,22419,22432,22451,22436,
+22442,22448,22467,22470,22484,22482,22483,22538,22486,22499,22539,22553,22557,
+22642,22561,22626,22603,22640,27584,22610,22589,22649,22661,22713,22687,22699,
+22714,22750,22715,22712,22702,22725,22739,22737,22743,22745,22744,22757,22748,
+22756,22751,22767,22778,22777,22779,22780,22781,22786,22794,22800,22811,26790,
+22821,22828,22829,22834,22840,22846,31442,22869,22864,22862,22874,22872,22882,
+22880,22887,22892,22889,22904,22913,22941,20318,20395,22947,22962,22982,23016,
+23004,22925,23001,23002,23077,23071,23057,23068,23049,23066,23104,23148,23113,
+23093,23094,23138,23146,23194,23228,23230,23243,23234,23229,23267,23255,23270,
+23273,23254,23290,23291,23308,23307,23318,23346,23248,23338,23350,23358,23363,
+23365,23360,23377,23381,23386,23387,23397,23401,23408,23411,23413,23416,25992,
+23418,23424,23427,23462,23480,23491,23495,23497,23508,23504,23524,23526,23522,
+23518,23525,23531,23536,23542,23539,23557,23559,23560,23565,23571,23584,23586,
+23592,23608,23609,23617,23622,23630,23635,23632,23631,23409,23660,23662,20066,
+23670,23673,23692,23697,23700,22939,23723,23739,23734,23740,23735,23749,23742,
+23751,23769,23785,23805,23802,23789,23948,23786,23819,23829,23831,23900,23839,
+23835,23825,23828,23842,23834,23833,23832,23884,23890,23886,23883,23916,23923,
+23926,23943,23940,23938,23970,23965,23980,23982,23997,23952,23991,23996,24009,
+24013,24019,24018,24022,24027,24043,24050,24053,24075,24090,24089,24081,24091,
+24118,24119,24132,24131,24128,24142,24151,24148,24159,24162,24164,24135,24181,
+24182,24186,40636,24191,24224,24257,24258,24264,24272,24271,24278,24291,24285,
+24282,24283,24290,24289,24296,24297,24300,24305,24307,24304,24308,24312,24318,
+24323,24329,24413,24412,24331,24337,24342,24361,24365,24376,24385,24392,24396,
+24398,24367,24401,24406,24407,24409,24417,24429,24435,24439,24451,24450,24447,
+24458,24456,24465,24455,24478,24473,24472,24480,24488,24493,24508,24534,24571,
+24548,24568,24561,24541,24755,24575,24609,24672,24601,24592,24617,24590,24625,
+24603,24597,24619,24614,24591,24634,24666,24641,24682,24695,24671,24650,24646,
+24653,24675,24643,24676,24642,24684,24683,24665,24705,24717,24807,24707,24730,
+24708,24731,24726,24727,24722,24743,24715,24801,24760,24800,24787,24756,24560,
+24765,24774,24757,24792,24909,24853,24838,24822,24823,24832,24820,24826,24835,
+24865,24827,24817,24845,24846,24903,24894,24872,24871,24906,24895,24892,24876,
+24884,24893,24898,24900,24947,24951,24920,24921,24922,24939,24948,24943,24933,
+24945,24927,24925,24915,24949,24985,24982,24967,25004,24980,24986,24970,24977,
+25003,25006,25036,25034,25033,25079,25032,25027,25030,25018,25035,32633,25037,
+25062,25059,25078,25082,25076,25087,25085,25084,25086,25088,25096,25097,25101,
+25100,25108,25115,25118,25121,25130,25134,25136,25138,25139,25153,25166,25182,
+25187,25179,25184,25192,25212,25218,25225,25214,25234,25235,25238,25300,25219,
+25236,25303,25297,25275,25295,25343,25286,25812,25288,25308,25292,25290,25282,
+25287,25243,25289,25356,25326,25329,25383,25346,25352,25327,25333,25424,25406,
+25421,25628,25423,25494,25486,25472,25515,25462,25507,25487,25481,25503,25525,
+25451,25449,25534,25577,25536,25542,25571,25545,25554,25590,25540,25622,25652,
+25606,25619,25638,25654,25885,25623,25640,25615,25703,25711,25718,25678,25898,
+25749,25747,25765,25769,25736,25788,25818,25810,25797,25799,25787,25816,25794,
+25841,25831,33289,25824,25825,25260,25827,25839,25900,25846,25844,25842,25850,
+25856,25853,25880,25884,25861,25892,25891,25899,25908,25909,25911,25910,25912,
+30027,25928,25942,25941,25933,25944,25950,25949,25970,25976,25986,25987,35722,
+26011,26015,26027,26039,26051,26054,26049,26052,26060,26066,26075,26073,26080,
+26081,26097,26482,26122,26115,26107,26483,26165,26166,26164,26140,26191,26180,
+26185,26177,26206,26205,26212,26215,26216,26207,26210,26224,26243,26248,26254,
+26249,26244,26264,26269,26305,26297,26313,26302,26300,26308,26296,26326,26330,
+26336,26175,26342,26345,26352,26357,26359,26383,26390,26398,26406,26407,38712,
+26414,26431,26422,26433,26424,26423,26438,26462,26464,26457,26467,26468,26505,
+26480,26537,26492,26474,26508,26507,26534,26529,26501,26551,26607,26548,26604,
+26547,26601,26552,26596,26590,26589,26594,26606,26553,26574,26566,26599,27292,
+26654,26694,26665,26688,26701,26674,26702,26803,26667,26713,26723,26743,26751,
+26783,26767,26797,26772,26781,26779,26755,27310,26809,26740,26805,26784,26810,
+26895,26765,26750,26881,26826,26888,26840,26914,26918,26849,26892,26829,26836,
+26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,26863,26920,26922,
+26906,26915,26913,26822,27001,26999,26972,27000,26987,26964,27006,26990,26937,
+26996,26941,26969,26928,26977,26974,26973,27009,26986,27058,27054,27088,27071,
+27073,27091,27070,27086,23528,27082,27101,27067,27075,27047,27182,27025,27040,
+27036,27029,27060,27102,27112,27138,27163,27135,27402,27129,27122,27111,27141,
+27057,27166,27117,27156,27115,27146,27154,27329,27171,27155,27204,27148,27250,
+27190,27256,27207,27234,27225,27238,27208,27192,27170,27280,27277,27296,27268,
+27298,27299,27287,34327,27323,27331,27330,27320,27315,27308,27358,27345,27359,
+27306,27354,27370,27387,27397,34326,27386,27410,27414,39729,27423,27448,27447,
+30428,27449,39150,27463,27459,27465,27472,27481,27476,27483,27487,27489,27512,
+27513,27519,27520,27524,27523,27533,27544,27541,27550,27556,27562,27563,27567,
+27570,27569,27571,27575,27580,27590,27595,27603,27615,27628,27627,27635,27631,
+40638,27656,27667,27668,27675,27684,27683,27742,27733,27746,27754,27778,27789,
+27802,27777,27803,27774,27752,27763,27794,27792,27844,27889,27859,27837,27863,
+27845,27869,27822,27825,27838,27834,27867,27887,27865,27882,27935,34893,27958,
+27947,27965,27960,27929,27957,27955,27922,27916,28003,28051,28004,27994,28025,
+27993,28046,28053,28644,28037,28153,28181,28170,28085,28103,28134,28088,28102,
+28140,28126,28108,28136,28114,28101,28154,28121,28132,28117,28138,28142,28205,
+28270,28206,28185,28274,28255,28222,28195,28267,28203,28278,28237,28191,28227,
+28218,28238,28196,28415,28189,28216,28290,28330,28312,28361,28343,28371,28349,
+28335,28356,28338,28372,28373,28303,28325,28354,28319,28481,28433,28748,28396,
+28408,28414,28479,28402,28465,28399,28466,28364,28478,28435,28407,28550,28538,
+28536,28545,28544,28527,28507,28659,28525,28546,28540,28504,28558,28561,28610,
+28518,28595,28579,28577,28580,28601,28614,28586,28639,28629,28652,28628,28632,
+28657,28654,28635,28681,28683,28666,28689,28673,28687,28670,28699,28698,28532,
+28701,28696,28703,28720,28734,28722,28753,28771,28825,28818,28847,28913,28844,
+28856,28851,28846,28895,28875,28893,28889,28937,28925,28956,28953,29029,29013,
+29064,29030,29026,29004,29014,29036,29071,29179,29060,29077,29096,29100,29143,
+29113,29118,29138,29129,29140,29134,29152,29164,29159,29173,29180,29177,29183,
+29197,29200,29211,29224,29229,29228,29232,29234,29243,29244,29247,29248,29254,
+29259,29272,29300,29310,29314,29313,29319,29330,29334,29346,29351,29369,29362,
+29379,29382,29380,29390,29394,29410,29408,29409,29433,29431,20495,29463,29450,
+29468,29462,29469,29492,29487,29481,29477,29502,29518,29519,40664,29527,29546,
+29544,29552,29560,29557,29563,29562,29640,29619,29646,29627,29632,29669,29678,
+29662,29858,29701,29807,29733,29688,29746,29754,29781,29759,29791,29785,29761,
+29788,29801,29808,29795,29802,29814,29822,29835,29854,29863,29898,29903,29908,
+29681,29920,29923,29927,29929,29934,29938,29936,29937,29944,29943,29956,29955,
+29957,29964,29966,29965,29973,29971,29982,29990,29996,30012,30020,30029,30026,
+30025,30043,30022,30042,30057,30052,30055,30059,30061,30072,30070,30086,30087,
+30068,30090,30089,30082,30100,30106,30109,30117,30115,30146,30131,30147,30133,
+30141,30136,30140,30129,30157,30154,30162,30169,30179,30174,30206,30207,30204,
+30209,30192,30202,30194,30195,30219,30221,30217,30239,30247,30240,30241,30242,
+30244,30260,30256,30267,30279,30280,30278,30300,30296,30305,30306,30312,30313,
+30314,30311,30316,30320,30322,30326,30328,30332,30336,30339,30344,30347,30350,
+30358,30355,30361,30362,30384,30388,30392,30393,30394,30402,30413,30422,30418,
+30430,30433,30437,30439,30442,34351,30459,30472,30471,30468,30505,30500,30494,
+30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565,30591,30590,
+30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652,30653,30651,
+30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014,30752,31018,
+30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895,30929,30918,
+30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964,30983,30994,
+30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059,31098,31103,
+31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189,31207,31212,
+31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291,31294,31287,
+31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368,31383,31381,
+31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431,31434,31437,
+31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472,31490,31503,
+31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610,31492,31565,
+31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598,31645,31640,
+31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681,31692,31695,
+31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751,31763,31731,
+31735,31767,31757,31734,31779,31783,31786,31775,31799,31787,31805,31820,31811,
+31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861,31875,31888,
+31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929,31933,31936,
+31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990,31994,32006,
+32002,32028,32021,32010,32069,32075,32046,32050,32063,32053,32070,32115,32086,
+32078,32114,32104,32110,32079,32099,32147,32137,32091,32143,32125,32155,32186,
+32174,32163,32181,32199,32189,32171,32317,32162,32175,32220,32184,32159,32176,
+32216,32221,32228,32222,32251,32242,32225,32261,32266,32291,32289,32274,32305,
+32287,32265,32267,32290,32326,32358,32315,32309,32313,32323,32311,32306,32314,
+32359,32349,32342,32350,32345,32346,32377,32362,32361,32380,32379,32387,32213,
+32381,36782,32383,32392,32393,32396,32402,32400,32403,32404,32406,32398,32411,
+32412,32568,32570,32581,32588,32589,32590,32592,32593,32597,32596,32600,32607,
+32608,32616,32617,32615,32632,32642,32646,32643,32648,32647,32652,32660,32670,
+32669,32666,32675,32687,32690,32697,32686,32694,32696,35697,32709,32710,32714,
+32725,32724,32737,32742,32745,32755,32761,39132,32774,32772,32779,32786,32792,
+32793,32796,32801,32808,32831,32827,32842,32838,32850,32856,32858,32863,32866,
+32872,32883,32882,32880,32886,32889,32893,32895,32900,32902,32901,32923,32915,
+32922,32941,20880,32940,32987,32997,32985,32989,32964,32986,32982,33033,33007,
+33009,33051,33065,33059,33071,33099,38539,33094,33086,33107,33105,33020,33137,
+33134,33125,33126,33140,33155,33160,33162,33152,33154,33184,33173,33188,33187,
+33119,33171,33193,33200,33205,33214,33208,33213,33216,33218,33210,33225,33229,
+33233,33241,33240,33224,33242,33247,33248,33255,33274,33275,33278,33281,33282,
+33285,33287,33290,33293,33296,33302,33321,33323,33336,33331,33344,33369,33368,
+33373,33370,33375,33380,33378,33384,33386,33387,33326,33393,33399,33400,33406,
+33421,33426,33451,33439,33467,33452,33505,33507,33503,33490,33524,33523,33530,
+33683,33539,33531,33529,33502,33542,33500,33545,33497,33589,33588,33558,33586,
+33585,33600,33593,33616,33605,33583,33579,33559,33560,33669,33690,33706,33695,
+33698,33686,33571,33678,33671,33674,33660,33717,33651,33653,33696,33673,33704,
+33780,33811,33771,33742,33789,33795,33752,33803,33729,33783,33799,33760,33778,
+33805,33826,33824,33725,33848,34054,33787,33901,33834,33852,34138,33924,33911,
+33899,33965,33902,33922,33897,33862,33836,33903,33913,33845,33994,33890,33977,
+33983,33951,34009,33997,33979,34010,34000,33985,33990,34006,33953,34081,34047,
+34036,34071,34072,34092,34079,34069,34068,34044,34112,34147,34136,34120,34113,
+34306,34123,34133,34176,34212,34184,34193,34186,34216,34157,34196,34203,34282,
+34183,34204,34167,34174,34192,34249,34234,34255,34233,34256,34261,34269,34277,
+34268,34297,34314,34323,34315,34302,34298,34310,34338,34330,34352,34367,34381,
+20053,34388,34399,34407,34417,34451,34467,34473,34474,34443,34444,34486,34479,
+34500,34502,34480,34505,34851,34475,34516,34526,34537,34540,34527,34523,34543,
+34578,34566,34568,34560,34563,34555,34577,34569,34573,34553,34570,34612,34623,
+34615,34619,34597,34601,34586,34656,34655,34680,34636,34638,34676,34647,34664,
+34670,34649,34643,34659,34666,34821,34722,34719,34690,34735,34763,34749,34752,
+34768,38614,34731,34756,34739,34759,34758,34747,34799,34802,34784,34831,34829,
+34814,34806,34807,34830,34770,34833,34838,34837,34850,34849,34865,34870,34873,
+34855,34875,34884,34882,34898,34905,34910,34914,34923,34945,34942,34974,34933,
+34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980,34992,35007,
+34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060,35048,35058,
+35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140,35131,35126,
+35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188,35191,35198,
+35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250,35258,35261,
+35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344,35340,35355,
+35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436,35426,35461,
+35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533,35522,35546,
+35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547,35596,35591,
+35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646,35624,35649,
+35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695,35700,35709,
+35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903,35912,35916,
+35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978,35981,35982,
+35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022,36040,36033,
+36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111,36109,36112,
+40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249,36290,36286,
+36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323,36348,36360,
+36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426,36423,36425,
+36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466,36476,36481,
+36487,36485,36484,36491,36490,36499,36497,36500,36505,36522,36513,36524,36528,
+36550,36529,36542,36549,36552,36555,36571,36579,36604,36603,36587,36606,36618,
+36613,36629,36626,36633,36627,36636,36639,36635,36620,36646,36659,36667,36665,
+36677,36674,36670,36684,36681,36678,36686,36695,36700,36706,36707,36708,36764,
+36767,36771,36781,36783,36791,36826,36837,36834,36842,36847,36999,36852,36869,
+36857,36858,36881,36885,36897,36877,36894,36886,36875,36903,36918,36917,36921,
+36856,36943,36944,36945,36946,36878,36937,36926,36950,36952,36958,36968,36975,
+36982,38568,36978,36994,36989,36993,36992,37002,37001,37007,37032,37039,37041,
+37045,37090,37092,25160,37083,37122,37138,37145,37170,37168,37194,37206,37208,
+37219,37221,37225,37235,37234,37259,37257,37250,37282,37291,37295,37290,37301,
+37300,37306,37312,37313,37321,37323,37328,37334,37343,37345,37339,37372,37365,
+37366,37406,37375,37396,37420,37397,37393,37470,37463,37445,37449,37476,37448,
+37525,37439,37451,37456,37532,37526,37523,37531,37466,37583,37561,37559,37609,
+37647,37626,37700,37678,37657,37666,37658,37667,37690,37685,37691,37724,37728,
+37756,37742,37718,37808,37804,37805,37780,37817,37846,37847,37864,37861,37848,
+37827,37853,37840,37832,37860,37914,37908,37907,37891,37895,37904,37942,37931,
+37941,37921,37946,37953,37970,37956,37979,37984,37986,37982,37994,37417,38000,
+38005,38007,38013,37978,38012,38014,38017,38015,38274,38279,38282,38292,38294,
+38296,38297,38304,38312,38311,38317,38332,38331,38329,38334,38346,28662,38339,
+38349,38348,38357,38356,38358,38364,38369,38373,38370,38433,38440,38446,38447,
+38466,38476,38479,38475,38519,38492,38494,38493,38495,38502,38514,38508,38541,
+38552,38549,38551,38570,38567,38577,38578,38576,38580,38582,38584,38585,38606,
+38603,38601,38605,35149,38620,38669,38613,38649,38660,38662,38664,38675,38670,
+38673,38671,38678,38681,38692,38698,38704,38713,38717,38718,38724,38726,38728,
+38722,38729,38748,38752,38756,38758,38760,21202,38763,38769,38777,38789,38780,
+38785,38778,38790,38795,38799,38800,38812,38824,38822,38819,38835,38836,38851,
+38854,38856,38859,38876,38893,40783,38898,31455,38902,38901,38927,38924,38968,
+38948,38945,38967,38973,38982,38991,38987,39019,39023,39024,39025,39028,39027,
+39082,39087,39089,39094,39108,39107,39110,39145,39147,39171,39177,39186,39188,
+39192,39201,39197,39198,39204,39200,39212,39214,39229,39230,39234,39241,39237,
+39248,39243,39249,39250,39244,39253,39319,39320,39333,39341,39342,39356,39391,
+39387,39389,39384,39377,39405,39406,39409,39410,39419,39416,39425,39439,39429,
+39394,39449,39467,39479,39493,39490,39488,39491,39486,39509,39501,39515,39511,
+39519,39522,39525,39524,39529,39531,39530,39597,39600,39612,39616,39631,39633,
+39635,39636,39646,39647,39650,39651,39654,39663,39659,39662,39668,39665,39671,
+39675,39686,39704,39706,39711,39714,39715,39717,39719,39720,39721,39722,39726,
+39727,39730,39748,39747,39759,39757,39758,39761,39768,39796,39827,39811,39825,
+39830,39831,39839,39840,39848,39860,39872,39882,39865,39878,39887,39889,39890,
+39907,39906,39908,39892,39905,39994,39922,39921,39920,39957,39956,39945,39955,
+39948,39942,39944,39954,39946,39940,39982,39963,39973,39972,39969,39984,40007,
+39986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176,40201,40200,
+40171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210,40257,40255,
+40254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329,40327,40363,
+40303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378,40390,40399,
+40386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478,40565,40569,
+40573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617,40632,40618,
+40621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672,40677,40680,
+40687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391,40725,40737,
+40748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807,40812,40810,
+40823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956,29081,
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/ksc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/ksc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/ksc.h	(revision 398)
@@ -0,0 +1,640 @@
+12288,12289,12290,183,8229,8230,168,12291,173,8213,8741,65340,8764,8216,8217,
+8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12304,
+12305,177,215,247,8800,8804,8805,8734,8756,176,8242,8243,8451,8491,65504,
+65505,65509,9794,9792,8736,8869,8978,8706,8711,8801,8786,167,8251,9734,9733,
+9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,8594,8592,8593,8595,
+8596,12307,8810,8811,8730,8765,8733,8757,8747,8748,8712,8715,8838,8839,8834,
+8835,8746,8745,8743,8744,65506,8658,8660,8704,8707,180,65374,711,728,733,730,
+729,184,731,161,191,720,8750,8721,8719,164,8457,8240,9665,9664,9655,9654,9828,
+9824,9825,9829,9831,9827,8857,9672,9635,9680,9681,9618,9636,9637,9640,9639,
+9638,9641,9832,9743,9742,9756,9758,182,8224,8225,8597,8599,8601,8598,8600,
+9837,9833,9834,9836,12927,12828,8470,13255,8482,13250,13272,8481,8364,174,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65281,65282,65283,65284,65285,65286,
+65287,65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,
+65300,65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,
+65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,
+65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,
+65339,65510,65341,65342,65343,65344,65345,65346,65347,65348,65349,65350,65351,
+65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,
+65365,65366,65367,65368,65369,65370,65371,65372,65373,65507,12593,12594,12595,
+12596,12597,12598,12599,12600,12601,12602,12603,12604,12605,12606,12607,12608,
+12609,12610,12611,12612,12613,12614,12615,12616,12617,12618,12619,12620,12621,
+12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,12632,12633,12634,
+12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,12647,
+12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,12659,12660,
+12661,12662,12663,12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,
+12674,12675,12676,12677,12678,12679,12680,12681,12682,12683,12684,12685,12686,
+8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,0,0,0,0,0,8544,8545,8546,
+8547,8548,8549,8550,8551,8552,8553,0,0,0,0,0,0,0,913,914,915,916,917,918,919,
+920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,0,0,0,0,0,
+0,0,0,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,
+964,965,966,967,968,969,0,0,0,0,0,0,9472,9474,9484,9488,9496,9492,9500,9516,
+9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,9523,9515,9531,9547,9504,
+9519,9512,9527,9535,9501,9520,9509,9528,9538,9490,9489,9498,9497,9494,9493,
+9486,9485,9502,9503,9505,9506,9510,9511,9513,9514,9517,9518,9521,9522,9525,
+9526,9529,9530,9533,9534,9536,9537,9539,9540,9541,9542,9543,9544,9545,9546,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,13205,13206,13207,8467,
+13208,13252,13219,13220,13221,13222,13209,13210,13211,13212,13213,13214,13215,
+13216,13217,13218,13258,13197,13198,13199,13263,13192,13193,13256,13223,13224,
+13232,13233,13234,13235,13236,13237,13238,13239,13240,13241,13184,13185,13186,
+13187,13188,13242,13243,13244,13245,13246,13247,13200,13201,13202,13203,13204,
+8486,13248,13249,13194,13195,13196,13270,13253,13229,13230,13231,13275,13225,
+13226,13227,13228,13277,13264,13267,13251,13257,13276,13254,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,198,208,170,294,0,306,0,319,321,216,338,186,222,358,330,0,12896,
+12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,
+12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,
+12923,9424,9425,9426,9427,9428,9429,9430,9431,9432,9433,9434,9435,9436,9437,
+9438,9439,9440,9441,9442,9443,9444,9445,9446,9447,9448,9449,9312,9313,9314,
+9315,9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,9326,189,8531,8532,188,
+190,8539,8540,8541,8542,230,273,240,295,305,307,312,320,322,248,339,223,254,
+359,331,329,12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810,
+12811,12812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823,
+12824,12825,12826,12827,9372,9373,9374,9375,9376,9377,9378,9379,9380,9381,
+9382,9383,9384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394,9395,9396,
+9397,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,
+9346,185,178,179,8308,8319,8321,8322,8323,8324,12353,12354,12355,12356,12357,
+12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,
+12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,
+12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,
+12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,
+12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,
+12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,
+0,0,0,0,0,0,0,0,0,0,0,12449,12450,12451,12452,12453,12454,12455,12456,12457,
+12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,
+12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,
+12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,
+12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,
+12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,
+12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,0,0,0,
+0,0,0,0,0,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,
+1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,
+1067,1068,1069,1070,1071,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1072,1073,1074,1075,
+1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,
+1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,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,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,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,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,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,44032,44033,44036,44039,44040,44041,44042,
+44048,44049,44050,44051,44052,44053,44054,44055,44057,44058,44059,44060,44061,
+44064,44068,44076,44077,44079,44080,44081,44088,44089,44092,44096,44107,44109,
+44116,44120,44124,44144,44145,44148,44151,44152,44154,44160,44161,44163,44164,
+44165,44166,44169,44170,44171,44172,44176,44180,44188,44189,44191,44192,44193,
+44200,44201,44202,44204,44207,44208,44216,44217,44219,44220,44221,44225,44228,
+44232,44236,44245,44247,44256,44257,44260,44263,44264,44266,44268,44271,44272,
+44273,44275,44277,44278,44284,44285,44288,44292,44294,44300,44301,44303,44305,
+44312,44316,44320,44329,44332,44333,44340,44341,44344,44348,44356,44357,44359,
+44361,44368,44372,44376,44385,44387,44396,44397,44400,44403,44404,44405,44406,
+44411,44412,44413,44415,44417,44418,44424,44425,44428,44432,44444,44445,44452,
+44471,44480,44481,44484,44488,44496,44497,44499,44508,44512,44516,44536,44537,
+44540,44543,44544,44545,44552,44553,44555,44557,44564,44592,44593,44596,44599,
+44600,44602,44608,44609,44611,44613,44614,44618,44620,44621,44622,44624,44628,
+44630,44636,44637,44639,44640,44641,44645,44648,44649,44652,44656,44664,44665,
+44667,44668,44669,44676,44677,44684,44732,44733,44734,44736,44740,44748,44749,
+44751,44752,44753,44760,44761,44764,44776,44779,44781,44788,44792,44796,44807,
+44808,44813,44816,44844,44845,44848,44850,44852,44860,44861,44863,44865,44866,
+44867,44872,44873,44880,44892,44893,44900,44901,44921,44928,44932,44936,44944,
+44945,44949,44956,44984,44985,44988,44992,44999,45000,45001,45003,45005,45006,
+45012,45020,45032,45033,45040,45041,45044,45048,45056,45057,45060,45068,45072,
+45076,45084,45085,45096,45124,45125,45128,45130,45132,45134,45139,45140,45141,
+45143,45145,45149,45180,45181,45184,45188,45196,45197,45199,45201,45208,45209,
+45210,45212,45215,45216,45217,45218,45224,45225,45227,45228,45229,45230,45231,
+45233,45235,45236,45237,45240,45244,45252,45253,45255,45256,45257,45264,45265,
+45268,45272,45280,45285,45320,45321,45323,45324,45328,45330,45331,45336,45337,
+45339,45340,45341,45347,45348,45349,45352,45356,45364,45365,45367,45368,45369,
+45376,45377,45380,45384,45392,45393,45396,45397,45400,45404,45408,45432,45433,
+45436,45440,45442,45448,45449,45451,45453,45458,45459,45460,45464,45468,45480,
+45516,45520,45524,45532,45533,45535,45544,45545,45548,45552,45561,45563,45565,
+45572,45573,45576,45579,45580,45588,45589,45591,45593,45600,45620,45628,45656,
+45660,45664,45672,45673,45684,45685,45692,45700,45701,45705,45712,45713,45716,
+45720,45721,45722,45728,45729,45731,45733,45734,45738,45740,45744,45748,45768,
+45769,45772,45776,45778,45784,45785,45787,45789,45794,45796,45797,45798,45800,
+45803,45804,45805,45806,45807,45811,45812,45813,45815,45816,45817,45818,45819,
+45823,45824,45825,45828,45832,45840,45841,45843,45844,45845,45852,45908,45909,
+45910,45912,45915,45916,45918,45919,45924,45925,45927,45929,45931,45934,45936,
+45937,45940,45944,45952,45953,45955,45956,45957,45964,45968,45972,45984,45985,
+45992,45996,46020,46021,46024,46027,46028,46030,46032,46036,46037,46039,46041,
+46043,46045,46048,46052,46056,46076,46096,46104,46108,46112,46120,46121,46123,
+46132,46160,46161,46164,46168,46176,46177,46179,46181,46188,46208,46216,46237,
+46244,46248,46252,46261,46263,46265,46272,46276,46280,46288,46293,46300,46301,
+46304,46307,46308,46310,46316,46317,46319,46321,46328,46356,46357,46360,46363,
+46364,46372,46373,46375,46376,46377,46378,46384,46385,46388,46392,46400,46401,
+46403,46404,46405,46411,46412,46413,46416,46420,46428,46429,46431,46432,46433,
+46496,46497,46500,46504,46506,46507,46512,46513,46515,46516,46517,46523,46524,
+46525,46528,46532,46540,46541,46543,46544,46545,46552,46572,46608,46609,46612,
+46616,46629,46636,46644,46664,46692,46696,46748,46749,46752,46756,46763,46764,
+46769,46804,46832,46836,46840,46848,46849,46853,46888,46889,46892,46895,46896,
+46904,46905,46907,46916,46920,46924,46932,46933,46944,46948,46952,46960,46961,
+46963,46965,46972,46973,46976,46980,46988,46989,46991,46992,46993,46994,46998,
+46999,47000,47001,47004,47008,47016,47017,47019,47020,47021,47028,47029,47032,
+47047,47049,47084,47085,47088,47092,47100,47101,47103,47104,47105,47111,47112,
+47113,47116,47120,47128,47129,47131,47133,47140,47141,47144,47148,47156,47157,
+47159,47160,47161,47168,47172,47185,47187,47196,47197,47200,47204,47212,47213,
+47215,47217,47224,47228,47245,47272,47280,47284,47288,47296,47297,47299,47301,
+47308,47312,47316,47325,47327,47329,47336,47337,47340,47344,47352,47353,47355,
+47357,47364,47384,47392,47420,47421,47424,47428,47436,47439,47441,47448,47449,
+47452,47456,47464,47465,47467,47469,47476,47477,47480,47484,47492,47493,47495,
+47497,47498,47501,47502,47532,47533,47536,47540,47548,47549,47551,47553,47560,
+47561,47564,47566,47567,47568,47569,47570,47576,47577,47579,47581,47582,47585,
+47587,47588,47589,47592,47596,47604,47605,47607,47608,47609,47610,47616,47617,
+47624,47637,47672,47673,47676,47680,47682,47688,47689,47691,47693,47694,47699,
+47700,47701,47704,47708,47716,47717,47719,47720,47721,47728,47729,47732,47736,
+47747,47748,47749,47751,47756,47784,47785,47787,47788,47792,47794,47800,47801,
+47803,47805,47812,47816,47832,47833,47868,47872,47876,47885,47887,47889,47896,
+47900,47904,47913,47915,47924,47925,47926,47928,47931,47932,47933,47934,47940,
+47941,47943,47945,47949,47951,47952,47956,47960,47969,47971,47980,48008,48012,
+48016,48036,48040,48044,48052,48055,48064,48068,48072,48080,48083,48120,48121,
+48124,48127,48128,48130,48136,48137,48139,48140,48141,48143,48145,48148,48149,
+48150,48151,48152,48155,48156,48157,48158,48159,48164,48165,48167,48169,48173,
+48176,48177,48180,48184,48192,48193,48195,48196,48197,48201,48204,48205,48208,
+48221,48260,48261,48264,48267,48268,48270,48276,48277,48279,48281,48282,48288,
+48289,48292,48295,48296,48304,48305,48307,48308,48309,48316,48317,48320,48324,
+48333,48335,48336,48337,48341,48344,48348,48372,48373,48374,48376,48380,48388,
+48389,48391,48393,48400,48404,48420,48428,48448,48456,48457,48460,48464,48472,
+48473,48484,48488,48512,48513,48516,48519,48520,48521,48522,48528,48529,48531,
+48533,48537,48538,48540,48548,48560,48568,48596,48597,48600,48604,48617,48624,
+48628,48632,48640,48643,48645,48652,48653,48656,48660,48668,48669,48671,48708,
+48709,48712,48716,48718,48724,48725,48727,48729,48730,48731,48736,48737,48740,
+48744,48746,48752,48753,48755,48756,48757,48763,48764,48765,48768,48772,48780,
+48781,48783,48784,48785,48792,48793,48808,48848,48849,48852,48855,48856,48864,
+48867,48868,48869,48876,48897,48904,48905,48920,48921,48923,48924,48925,48960,
+48961,48964,48968,48976,48977,48981,49044,49072,49093,49100,49101,49104,49108,
+49116,49119,49121,49212,49233,49240,49244,49248,49256,49257,49296,49297,49300,
+49304,49312,49313,49315,49317,49324,49325,49327,49328,49331,49332,49333,49334,
+49340,49341,49343,49344,49345,49349,49352,49353,49356,49360,49368,49369,49371,
+49372,49373,49380,49381,49384,49388,49396,49397,49399,49401,49408,49412,49416,
+49424,49429,49436,49437,49438,49439,49440,49443,49444,49446,49447,49452,49453,
+49455,49456,49457,49462,49464,49465,49468,49472,49480,49481,49483,49484,49485,
+49492,49493,49496,49500,49508,49509,49511,49512,49513,49520,49524,49528,49541,
+49548,49549,49550,49552,49556,49558,49564,49565,49567,49569,49573,49576,49577,
+49580,49584,49597,49604,49608,49612,49620,49623,49624,49632,49636,49640,49648,
+49649,49651,49660,49661,49664,49668,49676,49677,49679,49681,49688,49689,49692,
+49695,49696,49704,49705,49707,49709,49711,49713,49714,49716,49736,49744,49745,
+49748,49752,49760,49765,49772,49773,49776,49780,49788,49789,49791,49793,49800,
+49801,49808,49816,49819,49821,49828,49829,49832,49836,49837,49844,49845,49847,
+49849,49884,49885,49888,49891,49892,49899,49900,49901,49903,49905,49910,49912,
+49913,49915,49916,49920,49928,49929,49932,49933,49939,49940,49941,49944,49948,
+49956,49957,49960,49961,49989,50024,50025,50028,50032,50034,50040,50041,50044,
+50045,50052,50056,50060,50112,50136,50137,50140,50143,50144,50146,50152,50153,
+50157,50164,50165,50168,50184,50192,50212,50220,50224,50228,50236,50237,50248,
+50276,50277,50280,50284,50292,50293,50297,50304,50324,50332,50360,50364,50409,
+50416,50417,50420,50424,50426,50431,50432,50433,50444,50448,50452,50460,50472,
+50473,50476,50480,50488,50489,50491,50493,50500,50501,50504,50505,50506,50508,
+50509,50510,50515,50516,50517,50519,50520,50521,50525,50526,50528,50529,50532,
+50536,50544,50545,50547,50548,50549,50556,50557,50560,50564,50567,50572,50573,
+50575,50577,50581,50583,50584,50588,50592,50601,50612,50613,50616,50617,50619,
+50620,50621,50622,50628,50629,50630,50631,50632,50633,50634,50636,50638,50640,
+50641,50644,50648,50656,50657,50659,50661,50668,50669,50670,50672,50676,50678,
+50679,50684,50685,50686,50687,50688,50689,50693,50694,50695,50696,50700,50704,
+50712,50713,50715,50716,50724,50725,50728,50732,50733,50734,50736,50739,50740,
+50741,50743,50745,50747,50752,50753,50756,50760,50768,50769,50771,50772,50773,
+50780,50781,50784,50796,50799,50801,50808,50809,50812,50816,50824,50825,50827,
+50829,50836,50837,50840,50844,50852,50853,50855,50857,50864,50865,50868,50872,
+50873,50874,50880,50881,50883,50885,50892,50893,50896,50900,50908,50909,50912,
+50913,50920,50921,50924,50928,50936,50937,50941,50948,50949,50952,50956,50964,
+50965,50967,50969,50976,50977,50980,50984,50992,50993,50995,50997,50999,51004,
+51005,51008,51012,51018,51020,51021,51023,51025,51026,51027,51028,51029,51030,
+51031,51032,51036,51040,51048,51051,51060,51061,51064,51068,51069,51070,51075,
+51076,51077,51079,51080,51081,51082,51086,51088,51089,51092,51094,51095,51096,
+51098,51104,51105,51107,51108,51109,51110,51116,51117,51120,51124,51132,51133,
+51135,51136,51137,51144,51145,51148,51150,51152,51160,51165,51172,51176,51180,
+51200,51201,51204,51208,51210,51216,51217,51219,51221,51222,51228,51229,51232,
+51236,51244,51245,51247,51249,51256,51260,51264,51272,51273,51276,51277,51284,
+51312,51313,51316,51320,51322,51328,51329,51331,51333,51334,51335,51339,51340,
+51341,51348,51357,51359,51361,51368,51388,51389,51396,51400,51404,51412,51413,
+51415,51417,51424,51425,51428,51445,51452,51453,51456,51460,51461,51462,51468,
+51469,51471,51473,51480,51500,51508,51536,51537,51540,51544,51552,51553,51555,
+51564,51568,51572,51580,51592,51593,51596,51600,51608,51609,51611,51613,51648,
+51649,51652,51655,51656,51658,51664,51665,51667,51669,51670,51673,51674,51676,
+51677,51680,51682,51684,51687,51692,51693,51695,51696,51697,51704,51705,51708,
+51712,51720,51721,51723,51724,51725,51732,51736,51753,51788,51789,51792,51796,
+51804,51805,51807,51808,51809,51816,51837,51844,51864,51900,51901,51904,51908,
+51916,51917,51919,51921,51923,51928,51929,51936,51948,51956,51976,51984,51988,
+51992,52000,52001,52033,52040,52041,52044,52048,52056,52057,52061,52068,52088,
+52089,52124,52152,52180,52196,52199,52201,52236,52237,52240,52244,52252,52253,
+52257,52258,52263,52264,52265,52268,52270,52272,52280,52281,52283,52284,52285,
+52286,52292,52293,52296,52300,52308,52309,52311,52312,52313,52320,52324,52326,
+52328,52336,52341,52376,52377,52380,52384,52392,52393,52395,52396,52397,52404,
+52405,52408,52412,52420,52421,52423,52425,52432,52436,52452,52460,52464,52481,
+52488,52489,52492,52496,52504,52505,52507,52509,52516,52520,52524,52537,52572,
+52576,52580,52588,52589,52591,52593,52600,52616,52628,52629,52632,52636,52644,
+52645,52647,52649,52656,52676,52684,52688,52712,52716,52720,52728,52729,52731,
+52733,52740,52744,52748,52756,52761,52768,52769,52772,52776,52784,52785,52787,
+52789,52824,52825,52828,52831,52832,52833,52840,52841,52843,52845,52852,52853,
+52856,52860,52868,52869,52871,52873,52880,52881,52884,52888,52896,52897,52899,
+52900,52901,52908,52909,52929,52964,52965,52968,52971,52972,52980,52981,52983,
+52984,52985,52992,52993,52996,53000,53008,53009,53011,53013,53020,53024,53028,
+53036,53037,53039,53040,53041,53048,53076,53077,53080,53084,53092,53093,53095,
+53097,53104,53105,53108,53112,53120,53125,53132,53153,53160,53168,53188,53216,
+53217,53220,53224,53232,53233,53235,53237,53244,53248,53252,53265,53272,53293,
+53300,53301,53304,53308,53316,53317,53319,53321,53328,53332,53336,53344,53356,
+53357,53360,53364,53372,53373,53377,53412,53413,53416,53420,53428,53429,53431,
+53433,53440,53441,53444,53448,53449,53456,53457,53459,53460,53461,53468,53469,
+53472,53476,53484,53485,53487,53488,53489,53496,53517,53552,53553,53556,53560,
+53562,53568,53569,53571,53572,53573,53580,53581,53584,53588,53596,53597,53599,
+53601,53608,53612,53628,53636,53640,53664,53665,53668,53672,53680,53681,53683,
+53685,53690,53692,53696,53720,53748,53752,53767,53769,53776,53804,53805,53808,
+53812,53820,53821,53823,53825,53832,53852,53860,53888,53889,53892,53896,53904,
+53905,53909,53916,53920,53924,53932,53937,53944,53945,53948,53951,53952,53954,
+53960,53961,53963,53972,53976,53980,53988,53989,54000,54001,54004,54008,54016,
+54017,54019,54021,54028,54029,54030,54032,54036,54038,54044,54045,54047,54048,
+54049,54053,54056,54057,54060,54064,54072,54073,54075,54076,54077,54084,54085,
+54140,54141,54144,54148,54156,54157,54159,54160,54161,54168,54169,54172,54176,
+54184,54185,54187,54189,54196,54200,54204,54212,54213,54216,54217,54224,54232,
+54241,54243,54252,54253,54256,54260,54268,54269,54271,54273,54280,54301,54336,
+54340,54364,54368,54372,54381,54383,54392,54393,54396,54399,54400,54402,54408,
+54409,54411,54413,54420,54441,54476,54480,54484,54492,54495,54504,54508,54512,
+54520,54523,54525,54532,54536,54540,54548,54549,54551,54588,54589,54592,54596,
+54604,54605,54607,54609,54616,54617,54620,54624,54629,54632,54633,54635,54637,
+54644,54645,54648,54652,54660,54661,54663,54664,54665,54672,54693,54728,54729,
+54732,54736,54738,54744,54745,54747,54749,54756,54757,54760,54764,54772,54773,
+54775,54777,54784,54785,54788,54792,54800,54801,54803,54804,54805,54812,54816,
+54820,54829,54840,54841,54844,54848,54853,54856,54857,54859,54861,54865,54868,
+54869,54872,54876,54887,54889,54896,54897,54900,54915,54917,54924,54925,54928,
+54932,54941,54943,54945,54952,54956,54960,54969,54971,54980,54981,54984,54988,
+54993,54996,54999,55001,55008,55012,55016,55024,55029,55036,55037,55040,55044,
+55057,55064,55065,55068,55072,55080,55081,55083,55085,55092,55093,55096,55100,
+55108,55111,55113,55120,55121,55124,55126,55127,55128,55129,55136,55137,55139,
+55141,55145,55148,55152,55156,55164,55165,55169,55176,55177,55180,55184,55192,
+55193,55195,55197,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,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,20285,20339,20551,20729,
+21152,21487,21621,21733,22025,23233,23478,26247,26550,26551,26607,27468,29634,
+30146,31292,33499,33540,34903,34952,35382,36040,36303,36603,36838,39381,21051,
+21364,21508,24682,24932,27580,29647,33050,35258,35282,38307,20355,21002,22718,
+22904,23014,24178,24185,25031,25536,26438,26604,26751,28567,30286,30475,30965,
+31240,31487,31777,32925,33390,33393,35563,38291,20075,21917,26359,28212,30883,
+31469,33883,35088,34638,38824,21208,22350,22570,23884,24863,25022,25121,25954,
+26577,27204,28187,29976,30131,30435,30640,32058,37039,37969,37970,40853,21283,
+23724,30002,32987,37440,38296,21083,22536,23004,23713,23831,24247,24378,24394,
+24951,27743,30074,30086,31968,32115,32177,32652,33108,33313,34193,35137,35611,
+37628,38477,40007,20171,20215,20491,20977,22607,24887,24894,24936,25913,27114,
+28433,30117,30342,30422,31623,33445,33995,63744,37799,38283,21888,23458,22353,
+63745,31923,32697,37301,20520,21435,23621,24040,25298,25454,25818,25831,28192,
+28844,31067,36317,36382,63746,36989,37445,37624,20094,20214,20581,24062,24314,
+24838,26967,33137,34388,36423,37749,39467,20062,20625,26480,26688,20745,21133,
+21138,27298,30652,37392,40660,21163,24623,36850,20552,25001,25581,25802,26684,
+27268,28608,33160,35233,38548,22533,29309,29356,29956,32121,32365,32937,35211,
+35700,36963,40273,25225,27770,28500,32080,32570,35363,20860,24906,31645,35609,
+37463,37772,20140,20435,20510,20670,20742,21185,21197,21375,22384,22659,24218,
+24465,24950,25004,25806,25964,26223,26299,26356,26775,28039,28805,28913,29855,
+29861,29898,30169,30828,30956,31455,31478,32069,32147,32789,32831,33051,33686,
+35686,36629,36885,37857,38915,38968,39514,39912,20418,21843,22586,22865,23395,
+23622,24760,25106,26690,26800,26856,28330,30028,30328,30926,31293,31995,32363,
+32380,35336,35489,35903,38542,40388,21476,21481,21578,21617,22266,22993,23396,
+23611,24235,25335,25911,25925,25970,26272,26543,27073,27837,30204,30352,30590,
+31295,32660,32771,32929,33167,33510,33533,33776,34241,34865,34996,35493,63747,
+36764,37678,38599,39015,39640,40723,21741,26011,26354,26767,31296,35895,40288,
+22256,22372,23825,26118,26801,26829,28414,29736,34974,39908,27752,63748,39592,
+20379,20844,20849,21151,23380,24037,24656,24685,25329,25511,25915,29657,31354,
+34467,36002,38799,20018,23521,25096,26524,29916,31185,33747,35463,35506,36328,
+36942,37707,38982,24275,27112,34303,37101,63749,20896,23448,23532,24931,26874,
+27454,28748,29743,29912,31649,32592,33733,35264,36011,38364,39208,21038,24669,
+25324,36866,20362,20809,21281,22745,24291,26336,27960,28826,29378,29654,31568,
+33009,37979,21350,25499,32619,20054,20608,22602,22750,24618,24871,25296,27088,
+39745,23439,32024,32945,36703,20132,20689,21676,21932,23308,23968,24039,25898,
+25934,26657,27211,29409,30350,30703,32094,32761,33184,34126,34527,36611,36686,
+37066,39171,39509,39851,19992,20037,20061,20167,20465,20855,21246,21312,21475,
+21477,21646,22036,22389,22434,23495,23943,24272,25084,25304,25937,26552,26601,
+27083,27472,27590,27628,27714,28317,28792,29399,29590,29699,30655,30697,31350,
+32127,32777,33276,33285,33290,33503,34914,35635,36092,36544,36881,37041,37476,
+37558,39378,39493,40169,40407,40860,22283,23616,33738,38816,38827,40628,21531,
+31384,32676,35033,36557,37089,22528,23624,25496,31391,23470,24339,31353,31406,
+33422,36524,20518,21048,21240,21367,22280,25331,25458,27402,28099,30519,21413,
+29527,34152,36470,38357,26426,27331,28528,35437,36556,39243,63750,26231,27512,
+36020,39740,63751,21483,22317,22862,25542,27131,29674,30789,31418,31429,31998,
+33909,35215,36211,36917,38312,21243,22343,30023,31584,33740,37406,63752,27224,
+20811,21067,21127,25119,26840,26997,38553,20677,21156,21220,25027,26020,26681,
+27135,29822,31563,33465,33771,35250,35641,36817,39241,63753,20170,22935,25810,
+26129,27278,29748,31105,31165,33449,34942,34943,35167,63754,37670,20235,21450,
+24613,25201,27762,32026,32102,20120,20834,30684,32943,20225,20238,20854,20864,
+21980,22120,22331,22522,22524,22804,22855,22931,23492,23696,23822,24049,24190,
+24524,25216,26071,26083,26398,26399,26462,26827,26820,27231,27450,27683,27773,
+27778,28103,29592,29734,29738,29826,29859,30072,30079,30849,30959,31041,31047,
+31048,31098,31637,32000,32186,32648,32774,32813,32908,35352,35663,35912,36215,
+37665,37668,39138,39249,39438,39439,39525,40594,32202,20342,21513,25326,26708,
+37329,21931,20794,63755,63756,23068,25062,63757,25295,25343,63758,63759,63760,
+63761,63762,63763,37027,63764,63765,63766,63767,63768,35582,63769,63770,63771,
+63772,26262,63773,29014,63774,63775,38627,63776,25423,25466,21335,63777,26511,
+26976,28275,63778,30007,63779,63780,63781,32013,63782,63783,34930,22218,23064,
+63784,63785,63786,63787,63788,20035,63789,20839,22856,26608,32784,63790,22899,
+24180,25754,31178,24565,24684,25288,25467,23527,23511,21162,63791,22900,24361,
+24594,63792,63793,63794,29785,63795,63796,63797,63798,63799,63800,39377,63801,
+63802,63803,63804,63805,63806,63807,63808,63809,63810,63811,28611,63812,63813,
+33215,36786,24817,63814,63815,33126,63816,63817,23615,63818,63819,63820,63821,
+63822,63823,63824,63825,23273,35365,26491,32016,63826,63827,63828,63829,63830,
+63831,33021,63832,63833,23612,27877,21311,28346,22810,33590,20025,20150,20294,
+21934,22296,22727,24406,26039,26086,27264,27573,28237,30701,31471,31774,32222,
+34507,34962,37170,37723,25787,28606,29562,30136,36948,21846,22349,25018,25812,
+26311,28129,28251,28525,28601,30192,32835,33213,34113,35203,35527,35674,37663,
+27795,30035,31572,36367,36957,21776,22530,22616,24162,25095,25758,26848,30070,
+31958,34739,40680,20195,22408,22382,22823,23565,23729,24118,24453,25140,25825,
+29619,33274,34955,36024,38538,40667,23429,24503,24755,20498,20992,21040,22294,
+22581,22615,23566,23648,23798,23947,24230,24466,24764,25361,25481,25623,26691,
+26873,27330,28120,28193,28372,28644,29182,30428,30585,31153,31291,33796,35241,
+36077,36339,36424,36867,36884,36947,37117,37709,38518,38876,27602,28678,29272,
+29346,29544,30563,31167,31716,32411,35712,22697,24775,25958,26109,26302,27788,
+28958,29129,35930,38931,20077,31361,20189,20908,20941,21205,21516,24999,26481,
+26704,26847,27934,28540,30140,30643,31461,33012,33891,37509,20828,26007,26460,
+26515,30168,31431,33651,63834,35910,36887,38957,23663,33216,33434,36929,36975,
+37389,24471,23965,27225,29128,30331,31561,34276,35588,37159,39472,21895,25078,
+63835,30313,32645,34367,34746,35064,37007,63836,27931,28889,29662,32097,33853,
+63837,37226,39409,63838,20098,21365,27396,27410,28734,29211,34349,40478,21068,
+36771,23888,25829,25900,27414,28651,31811,32412,34253,35172,35261,25289,33240,
+34847,24266,26391,28010,29436,29701,29807,34690,37086,20358,23821,24480,33802,
+20919,25504,30053,20142,20486,20841,20937,26753,27153,31918,31921,31975,33391,
+35538,36635,37327,20406,20791,21237,21570,24300,24942,25150,26053,27354,28670,
+31018,34268,34851,38317,39522,39530,40599,40654,21147,26310,27511,28701,31019,
+36706,38722,24976,25088,25891,28451,29001,29833,32244,32879,34030,36646,36899,
+37706,20925,21015,21155,27916,28872,35010,24265,25986,27566,28610,31806,29557,
+20196,20278,22265,63839,23738,23994,24604,29618,31533,32666,32718,32838,36894,
+37428,38646,38728,38936,40801,20363,28583,31150,37300,38583,21214,63840,25736,
+25796,27347,28510,28696,29200,30439,32769,34310,34396,36335,36613,38706,39791,
+40442,40565,30860,31103,32160,33737,37636,40575,40595,35542,22751,24324,26407,
+28711,29903,31840,32894,20769,28712,29282,30922,36034,36058,36084,38647,20102,
+20698,23534,24278,26009,29134,30274,30637,32842,34044,36988,39719,40845,22744,
+23105,23650,27155,28122,28431,30267,32047,32311,34078,35128,37860,38475,21129,
+26066,26611,27060,27969,28316,28687,29705,29792,30041,30244,30827,35628,39006,
+20845,25134,38520,20374,20523,23833,28138,32184,36650,24459,24900,26647,63841,
+38534,21202,32907,20956,20940,26974,31260,32190,33777,38517,20442,21033,21400,
+21519,21774,23653,24743,26446,26792,28012,29313,29432,29702,29827,63842,30178,
+31852,32633,32696,33673,35023,35041,37324,37328,38626,39881,21533,28542,29136,
+29848,34298,36522,38563,40023,40607,26519,28107,29747,33256,38678,30764,31435,
+31520,31890,25705,29802,30194,30908,30952,39340,39764,40635,23518,24149,28448,
+33180,33707,37000,19975,21325,23081,24018,24398,24930,25405,26217,26364,28415,
+28459,28771,30622,33836,34067,34875,36627,39237,39995,21788,25273,26411,27819,
+33545,35178,38778,20129,22916,24536,24537,26395,32178,32596,33426,33579,33725,
+36638,37017,22475,22969,23186,23504,26151,26522,26757,27599,29028,32629,36023,
+36067,36993,39749,33032,35978,38476,39488,40613,23391,27667,29467,30450,30431,
+33804,20906,35219,20813,20885,21193,26825,27796,30468,30496,32191,32236,38754,
+40629,28357,34065,20901,21517,21629,26126,26269,26919,28319,30399,30609,33559,
+33986,34719,37225,37528,40180,34946,20398,20882,21215,22982,24125,24917,25720,
+25721,26286,26576,27169,27597,27611,29279,29281,29761,30520,30683,32791,33468,
+33541,35584,35624,35980,26408,27792,29287,30446,30566,31302,40361,27519,27794,
+22818,26406,33945,21359,22675,22937,24287,25551,26164,26483,28218,29483,31447,
+33495,37672,21209,24043,25006,25035,25098,25287,25771,26080,26969,27494,27595,
+28961,29687,30045,32326,33310,33538,34154,35491,36031,38695,40289,22696,40664,
+20497,21006,21563,21839,25991,27766,32010,32011,32862,34442,38272,38639,21247,
+27797,29289,21619,23194,23614,23883,24396,24494,26410,26806,26979,28220,28228,
+30473,31859,32654,34183,35598,36855,38753,40692,23735,24758,24845,25003,25935,
+26107,26108,27665,27887,29599,29641,32225,38292,23494,34588,35600,21085,21338,
+25293,25615,25778,26420,27192,27850,29632,29854,31636,31893,32283,33162,33334,
+34180,36843,38649,39361,20276,21322,21453,21467,25292,25644,25856,26001,27075,
+27886,28504,29677,30036,30242,30436,30460,30928,30971,31020,32070,33324,34784,
+36820,38930,39151,21187,25300,25765,28196,28497,30332,36299,37297,37474,39662,
+39747,20515,20621,22346,22952,23592,24135,24439,25151,25918,26041,26049,26121,
+26507,27036,28354,30917,32033,32938,33152,33323,33459,33953,34444,35370,35607,
+37030,38450,40848,20493,20467,63843,22521,24472,25308,25490,26479,28227,28953,
+30403,32972,32986,35060,35061,35097,36064,36649,37197,38506,20271,20336,24091,
+26575,26658,30333,30334,39748,24161,27146,29033,29140,30058,63844,32321,34115,
+34281,39132,20240,31567,32624,38309,20961,24070,26805,27710,27726,27867,29359,
+31684,33539,27861,29754,20731,21128,22721,25816,27287,29863,30294,30887,34327,
+38370,38713,63845,21342,24321,35722,36776,36783,37002,21029,30629,40009,40712,
+19993,20482,20853,23643,24183,26142,26170,26564,26821,28851,29953,30149,31177,
+31453,36647,39200,39432,20445,22561,22577,23542,26222,27493,27921,28282,28541,
+29668,29995,33769,35036,35091,35676,36628,20239,20693,21264,21340,23443,24489,
+26381,31119,33145,33583,34068,35079,35206,36665,36667,39333,39954,26412,20086,
+20472,22857,23553,23791,23792,25447,26834,28925,29090,29739,32299,34028,34562,
+36898,37586,40179,19981,20184,20463,20613,21078,21103,21542,21648,22496,22827,
+23142,23386,23413,23500,24220,63846,25206,25975,26023,28014,28325,29238,31526,
+31807,32566,33104,33105,33178,33344,33433,33705,35331,36000,36070,36091,36212,
+36282,37096,37340,38428,38468,39385,40167,21271,20998,21545,22132,22707,22868,
+22894,24575,24996,25198,26128,27774,28954,30406,31881,31966,32027,33452,36033,
+38640,63847,20315,24343,24447,25282,23849,26379,26842,30844,32323,40300,19989,
+20633,21269,21290,21329,22915,23138,24199,24754,24970,25161,25209,26000,26503,
+27047,27604,27606,27607,27608,27832,63848,29749,30202,30738,30865,31189,31192,
+31875,32203,32737,32933,33086,33218,33778,34586,35048,35513,35692,36027,37145,
+38750,39131,40763,22188,23338,24428,25996,27315,27567,27996,28657,28693,29277,
+29613,36007,36051,38971,24977,27703,32856,39425,20045,20107,20123,20181,20282,
+20284,20351,20447,20735,21490,21496,21766,21987,22235,22763,22882,23057,23531,
+23546,23556,24051,24107,24473,24605,25448,26012,26031,26614,26619,26797,27515,
+27801,27863,28195,28681,29509,30722,31038,31040,31072,31169,31721,32023,32114,
+32902,33293,33678,34001,34503,35039,35408,35422,35613,36060,36198,36781,37034,
+39164,39391,40605,21066,63849,26388,63850,20632,21034,23665,25955,27733,29642,
+29987,30109,31639,33948,37240,38704,20087,25746,27578,29022,34217,19977,63851,
+26441,26862,28183,33439,34072,34923,25591,28545,37394,39087,19978,20663,20687,
+20767,21830,21930,22039,23360,23577,23776,24120,24202,24224,24258,24819,26705,
+27233,28248,29245,29248,29376,30456,31077,31665,32724,35059,35316,35443,35937,
+36062,38684,22622,29885,36093,21959,63852,31329,32034,33394,29298,29983,29989,
+63853,31513,22661,22779,23996,24207,24246,24464,24661,25234,25471,25933,26257,
+26329,26360,26646,26866,29312,29790,31598,32110,32214,32626,32997,33298,34223,
+35199,35475,36893,37604,40653,40736,22805,22893,24109,24796,26132,26227,26512,
+27728,28101,28511,30707,30889,33990,37323,37675,20185,20682,20808,21892,23307,
+23459,25159,25982,26059,28210,29053,29697,29764,29831,29887,30316,31146,32218,
+32341,32680,33146,33203,33337,34330,34796,35445,36323,36984,37521,37925,39245,
+39854,21352,23633,26964,27844,27945,28203,33292,34203,35131,35373,35498,38634,
+40807,21089,26297,27570,32406,34814,36109,38275,38493,25885,28041,29166,63854,
+22478,22995,23468,24615,24826,25104,26143,26207,29481,29689,30427,30465,31596,
+32854,32882,33125,35488,37266,19990,21218,27506,27927,31237,31545,32048,63855,
+36016,21484,22063,22609,23477,23567,23569,24034,25152,25475,25620,26157,26803,
+27836,28040,28335,28703,28836,29138,29990,30095,30094,30233,31505,31712,31787,
+32032,32057,34092,34157,34311,35380,36877,36961,37045,37559,38902,39479,20439,
+23660,26463,28049,31903,32396,35606,36118,36895,23403,24061,25613,33984,36956,
+39137,29575,23435,24730,26494,28126,35359,35494,36865,38924,21047,63856,28753,
+30862,37782,34928,37335,20462,21463,22013,22234,22402,22781,23234,23432,23723,
+23744,24101,24833,25101,25163,25480,25628,25910,25976,27193,27530,27700,27929,
+28465,29159,29417,29560,29703,29874,30246,30561,31168,31319,31466,31929,32143,
+32172,32353,32670,33065,33585,33936,34010,34282,34966,35504,35728,36664,36930,
+36995,37228,37526,37561,38539,38567,38568,38614,38656,38920,39318,39635,39706,
+21460,22654,22809,23408,23487,28113,28506,29087,29729,29881,32901,33789,24033,
+24455,24490,24642,26092,26642,26991,27219,27529,27957,28147,29667,30462,30636,
+31565,32020,33059,33308,33600,34036,34147,35426,35524,37255,37662,38918,39348,
+25100,34899,36848,37477,23815,23847,23913,29791,33181,34664,28629,25342,32722,
+35126,35186,19998,20056,20711,21213,21319,25215,26119,32361,34821,38494,20365,
+21273,22070,22987,23204,23608,23630,23629,24066,24337,24643,26045,26159,26178,
+26558,26612,29468,30690,31034,32709,33940,33997,35222,35430,35433,35553,35925,
+35962,22516,23508,24335,24687,25325,26893,27542,28252,29060,31698,34645,35672,
+36606,39135,39166,20280,20353,20449,21627,23072,23480,24892,26032,26216,29180,
+30003,31070,32051,33102,33251,33688,34218,34254,34563,35338,36523,36763,63857,
+36805,22833,23460,23526,24713,23529,23563,24515,27777,63858,28145,28683,29978,
+33455,35574,20160,21313,63859,38617,27663,20126,20420,20818,21854,23077,23784,
+25105,29273,33469,33706,34558,34905,35357,38463,38597,39187,40201,40285,22538,
+23731,23997,24132,24801,24853,25569,27138,28197,37122,37716,38990,39952,40823,
+23433,23736,25353,26191,26696,30524,38593,38797,38996,39839,26017,35585,36555,
+38332,21813,23721,24022,24245,26263,30284,33780,38343,22739,25276,29390,40232,
+20208,22830,24591,26171,27523,31207,40230,21395,21696,22467,23830,24859,26326,
+28079,30861,33406,38552,38724,21380,25212,25494,28082,32266,33099,38989,27387,
+32588,40367,40474,20063,20539,20918,22812,24825,25590,26928,29242,32822,63860,
+37326,24369,63861,63862,32004,33509,33903,33979,34277,36493,63863,20335,63864,
+63865,22756,23363,24665,25562,25880,25965,26264,63866,26954,27171,27915,28673,
+29036,30162,30221,31155,31344,63867,32650,63868,35140,63869,35731,37312,38525,
+63870,39178,22276,24481,26044,28417,30208,31142,35486,39341,39770,40812,20740,
+25014,25233,27277,33222,20547,22576,24422,28937,35328,35578,23420,34326,20474,
+20796,22196,22852,25513,28153,23978,26989,20870,20104,20313,63871,63872,63873,
+22914,63874,63875,27487,27741,63876,29877,30998,63877,33287,33349,33593,36671,
+36701,63878,39192,63879,63880,63881,20134,63882,22495,24441,26131,63883,63884,
+30123,32377,35695,63885,36870,39515,22181,22567,23032,23071,23476,63886,24310,
+63887,63888,25424,25403,63889,26941,27783,27839,28046,28051,28149,28436,63890,
+28895,28982,29017,63891,29123,29141,63892,30799,30831,63893,31605,32227,63894,
+32303,63895,34893,36575,63896,63897,63898,37467,63899,40182,63900,63901,63902,
+24709,28037,63903,29105,63904,63905,38321,21421,63906,63907,63908,26579,63909,
+28814,28976,29744,33398,33490,63910,38331,39653,40573,26308,63911,29121,33865,
+63912,63913,22603,63914,63915,23992,24433,63916,26144,26254,27001,27054,27704,
+27891,28214,28481,28634,28699,28719,29008,29151,29552,63917,29787,63918,29908,
+30408,31310,32403,63919,63920,33521,35424,36814,63921,37704,63922,38681,63923,
+63924,20034,20522,63925,21000,21473,26355,27757,28618,29450,30591,31330,33454,
+34269,34306,63926,35028,35427,35709,35947,63927,37555,63928,38675,38928,20116,
+20237,20425,20658,21320,21566,21555,21978,22626,22714,22887,23067,23524,24735,
+63929,25034,25942,26111,26212,26791,27738,28595,28879,29100,29522,31613,34568,
+35492,39986,40711,23627,27779,29508,29577,37434,28331,29797,30239,31337,32277,
+34314,20800,22725,25793,29934,29973,30320,32705,37013,38605,39252,28198,29926,
+31401,31402,33253,34521,34680,35355,23113,23436,23451,26785,26880,28003,29609,
+29715,29740,30871,32233,32747,33048,33109,33694,35916,38446,38929,26352,24448,
+26106,26505,27754,29579,20525,23043,27498,30702,22806,23916,24013,29477,30031,
+63930,63931,20709,20985,22575,22829,22934,23002,23525,63932,63933,23970,25303,
+25622,25747,25854,63934,26332,63935,27208,63936,29183,29796,63937,31368,31407,
+32327,32350,32768,33136,63938,34799,35201,35616,36953,63939,36992,39250,24958,
+27442,28020,32287,35109,36785,20433,20653,20887,21191,22471,22665,23481,24248,
+24898,27029,28044,28263,28342,29076,29794,29992,29996,32883,33592,33993,36362,
+37780,37854,63940,20110,20305,20598,20778,21448,21451,21491,23431,23507,23588,
+24858,24962,26100,29275,29591,29760,30402,31056,31121,31161,32006,32701,33419,
+34261,34398,36802,36935,37109,37354,38533,38632,38633,21206,24423,26093,26161,
+26671,29020,31286,37057,38922,20113,63941,27218,27550,28560,29065,32792,33464,
+34131,36939,38549,38642,38907,34074,39729,20112,29066,38596,20803,21407,21729,
+22291,22290,22435,23195,23236,23491,24616,24895,25588,27781,27961,28274,28304,
+29232,29503,29783,33489,34945,36677,36960,63942,38498,39000,40219,26376,36234,
+37470,20301,20553,20702,21361,22285,22996,23041,23561,24944,26256,28205,29234,
+29771,32239,32963,33806,33894,34111,34655,34907,35096,35586,36949,38859,39759,
+20083,20369,20754,20842,63943,21807,21929,23418,23461,24188,24189,24254,24736,
+24799,24840,24841,25540,25912,26377,63944,26580,26586,63945,26977,26978,27833,
+27943,63946,28216,63947,28641,29494,29495,63948,29788,30001,63949,30290,63950,
+63951,32173,33278,33848,35029,35480,35547,35565,36400,36418,36938,36926,36986,
+37193,37321,37742,63952,63953,22537,63954,27603,32905,32946,63955,63956,20801,
+22891,23609,63957,63958,28516,29607,32996,36103,63959,37399,38287,63960,63961,
+63962,63963,32895,25102,28700,32104,34701,63964,22432,24681,24903,27575,35518,
+37504,38577,20057,21535,28139,34093,38512,38899,39150,25558,27875,37009,20957,
+25033,33210,40441,20381,20506,20736,23452,24847,25087,25836,26885,27589,30097,
+30691,32681,33380,34191,34811,34915,35516,35696,37291,20108,20197,20234,63965,
+63966,22839,23016,63967,24050,24347,24411,24609,63968,63969,63970,63971,29246,
+29669,63972,30064,30157,63973,31227,63974,32780,32819,32900,33505,33617,63975,
+63976,36029,36019,36999,63977,63978,39156,39180,63979,63980,28727,30410,32714,
+32716,32764,35610,20154,20161,20995,21360,63981,21693,22240,23035,23493,24341,
+24525,28270,63982,63983,32106,33589,63984,34451,35469,63985,38765,38775,63986,
+63987,19968,20314,20350,22777,26085,28322,36920,37808,39353,20219,22764,22922,
+23001,24641,63988,63989,31252,63990,33615,36035,20837,21316,63991,63992,63993,
+20173,21097,23381,33471,20180,21050,21672,22985,23039,23376,23383,23388,24675,
+24904,28363,28825,29038,29574,29943,30133,30913,32043,32773,33258,33576,34071,
+34249,35566,36039,38604,20316,21242,22204,26027,26152,28796,28856,29237,32189,
+33421,37196,38592,40306,23409,26855,27544,28538,30430,23697,26283,28507,31668,
+31786,34870,38620,19976,20183,21280,22580,22715,22767,22892,23559,24115,24196,
+24373,25484,26290,26454,27167,27299,27404,28479,29254,63994,29520,29835,31456,
+31911,33144,33247,33255,33674,33900,34083,34196,34255,35037,36115,37292,38263,
+38556,20877,21705,22312,23472,25165,26448,26685,26771,28221,28371,28797,32289,
+35009,36001,36617,40779,40782,29229,31631,35533,37658,20295,20302,20786,21632,
+22992,24213,25269,26485,26990,27159,27822,28186,29401,29482,30141,31672,32053,
+33511,33785,33879,34295,35419,36015,36487,36889,37048,38606,40799,21219,21514,
+23265,23490,25688,25973,28404,29380,63995,30340,31309,31515,31821,32318,32735,
+33659,35627,36042,36196,36321,36447,36842,36857,36969,37841,20291,20346,20659,
+20840,20856,21069,21098,22625,22652,22880,23560,23637,24283,24731,25136,26643,
+27583,27656,28593,29006,29728,30000,30008,30033,30322,31564,31627,31661,31686,
+32399,35438,36670,36681,37439,37523,37666,37931,38651,39002,39019,39198,20999,
+25130,25240,27993,30308,31434,31680,32118,21344,23742,24215,28472,28857,31896,
+38673,39822,40670,25509,25722,34678,19969,20117,20141,20572,20597,21576,22979,
+23450,24128,24237,24311,24449,24773,25402,25919,25972,26060,26230,26232,26622,
+26984,27273,27491,27712,28096,28136,28191,28254,28702,28833,29582,29693,30010,
+30555,30855,31118,31243,31357,31934,32142,33351,35330,35562,35998,37165,37194,
+37336,37478,37580,37664,38662,38742,38748,38914,40718,21046,21137,21884,22564,
+24093,24351,24716,25552,26799,28639,31085,31532,33229,34234,35069,35576,36420,
+37261,38500,38555,38717,38988,40778,20430,20806,20939,21161,22066,24340,24427,
+25514,25805,26089,26177,26362,26361,26397,26781,26839,27133,28437,28526,29031,
+29157,29226,29866,30522,31062,31066,31199,31264,31381,31895,31967,32068,32368,
+32903,34299,34468,35412,35519,36249,36481,36896,36973,37347,38459,38613,40165,
+26063,31751,36275,37827,23384,23562,21330,25305,29469,20519,23447,24478,24752,
+24939,26837,28121,29742,31278,32066,32156,32305,33131,36394,36405,37758,37912,
+20304,22352,24038,24231,25387,32618,20027,20303,20367,20570,23005,32964,21610,
+21608,22014,22863,23449,24030,24282,26205,26417,26609,26666,27880,27954,28234,
+28557,28855,29664,30087,31820,32002,32044,32162,33311,34523,35387,35461,36208,
+36490,36659,36913,37198,37202,37956,39376,31481,31909,20426,20737,20934,22472,
+23535,23803,26201,27197,27994,28310,28652,28940,30063,31459,34850,36897,36981,
+38603,39423,33537,20013,20210,34886,37325,21373,27355,26987,27713,33914,22686,
+24974,26366,25327,28893,29969,30151,32338,33976,35657,36104,20043,21482,21675,
+22320,22336,24535,25345,25351,25711,25903,26088,26234,26525,26547,27490,27744,
+27802,28460,30693,30757,31049,31063,32025,32930,33026,33267,33437,33463,34584,
+35468,63996,36100,36286,36978,30452,31257,31287,32340,32887,21767,21972,22645,
+25391,25634,26185,26187,26733,27035,27524,27941,28337,29645,29800,29857,30043,
+30137,30433,30494,30603,31206,32265,32285,33275,34095,34967,35386,36049,36587,
+36784,36914,37805,38499,38515,38663,20356,21489,23018,23241,24089,26702,29894,
+30142,31209,31378,33187,34541,36074,36300,36845,26015,26389,63997,22519,28503,
+32221,36655,37878,38598,24501,25074,28548,19988,20376,20511,21449,21983,23919,
+24046,27425,27492,30923,31642,63998,36425,36554,36974,25417,25662,30528,31364,
+37679,38015,40810,25776,28591,29158,29864,29914,31428,31762,32386,31922,32408,
+35738,36106,38013,39184,39244,21049,23519,25830,26413,32046,20717,21443,22649,
+24920,24921,25082,26028,31449,35730,35734,20489,20513,21109,21809,23100,24288,
+24432,24884,25950,26124,26166,26274,27085,28356,28466,29462,30241,31379,33081,
+33369,33750,33980,20661,22512,23488,23528,24425,25505,30758,32181,33756,34081,
+37319,37365,20874,26613,31574,36012,20932,22971,24765,34389,20508,63999,21076,
+23610,24957,25114,25299,25842,26021,28364,30240,33034,36448,38495,38587,20191,
+21315,21912,22825,24029,25797,27849,28154,29588,31359,33307,34214,36068,36368,
+36983,37351,38369,38433,38854,20984,21746,21894,24505,25764,28552,32180,36639,
+36685,37941,20681,23574,27838,28155,29979,30651,31805,31844,35449,35522,22558,
+22974,24086,25463,29266,30090,30571,35548,36028,36626,24307,26228,28152,32893,
+33729,35531,38737,39894,64000,21059,26367,28053,28399,32224,35558,36910,36958,
+39636,21021,21119,21736,24980,25220,25307,26786,26898,26970,27189,28818,28966,
+30813,30977,30990,31186,31245,32918,33400,33493,33609,34121,35970,36229,37218,
+37259,37294,20419,22225,29165,30679,34560,35320,23544,24534,26449,37032,21474,
+22618,23541,24740,24961,25696,32317,32880,34085,37507,25774,20652,23828,26368,
+22684,25277,25512,26894,27000,27166,28267,30394,31179,33467,33833,35535,36264,
+36861,37138,37195,37276,37648,37656,37786,38619,39478,39949,19985,30044,31069,
+31482,31569,31689,32302,33988,36441,36468,36600,36880,26149,26943,29763,20986,
+26414,40668,20805,24544,27798,34802,34909,34935,24756,33205,33795,36101,21462,
+21561,22068,23094,23601,28810,32736,32858,33030,33261,36259,37257,39519,40434,
+20596,20164,21408,24827,28204,23652,20360,20516,21988,23769,24159,24677,26772,
+27835,28100,29118,30164,30196,30305,31258,31305,32199,32251,32622,33268,34473,
+36636,38601,39347,40786,21063,21189,39149,35242,19971,26578,28422,20405,23522,
+26517,27784,28024,29723,30759,37341,37756,34756,31204,31281,24555,20182,21668,
+21822,22702,22949,24816,25171,25302,26422,26965,33333,38464,39345,39389,20524,
+21331,21828,22396,64001,25176,64002,25826,26219,26589,28609,28655,29730,29752,
+35351,37944,21585,22022,22374,24392,24986,27470,28760,28845,32187,35477,22890,
+33067,25506,30472,32829,36010,22612,25645,27067,23445,24081,28271,64003,34153,
+20812,21488,22826,24608,24907,27526,27760,27888,31518,32974,33492,36294,37040,
+39089,64004,25799,28580,25745,25860,20814,21520,22303,35342,24927,26742,64005,
+30171,31570,32113,36890,22534,27084,33151,35114,36864,38969,20600,22871,22956,
+25237,36879,39722,24925,29305,38358,22369,23110,24052,25226,25773,25850,26487,
+27874,27966,29228,29750,30772,32631,33453,36315,38935,21028,22338,26495,29256,
+29923,36009,36774,37393,38442,20843,21485,25420,20329,21764,24726,25943,27803,
+28031,29260,29437,31255,35207,35997,24429,28558,28921,33192,24846,20415,20559,
+25153,29255,31687,32232,32745,36941,38829,39449,36022,22378,24179,26544,33805,
+35413,21536,23318,24163,24290,24330,25987,32954,34109,38281,38491,20296,21253,
+21261,21263,21638,21754,22275,24067,24598,25243,25265,25429,64006,27873,28006,
+30129,30770,32990,33071,33502,33889,33970,34957,35090,36875,37610,39165,39825,
+24133,26292,26333,28689,29190,64007,20469,21117,24426,24915,26451,27161,28418,
+29922,31080,34920,35961,39111,39108,39491,21697,31263,26963,35575,35914,39080,
+39342,24444,25259,30130,30382,34987,36991,38466,21305,24380,24517,27852,29644,
+30050,30091,31558,33534,39325,20047,36924,19979,20309,21414,22799,24264,26160,
+27827,29781,33655,34662,36032,36944,38686,39957,22737,23416,34384,35604,40372,
+23506,24680,24717,26097,27735,28450,28579,28698,32597,32752,38289,38290,38480,
+38867,21106,36676,20989,21547,21688,21859,21898,27323,28085,32216,33382,37532,
+38519,40569,21512,21704,30418,34532,38308,38356,38492,20130,20233,23022,23270,
+24055,24658,25239,26477,26689,27782,28207,32568,32923,33322,64008,64009,38917,
+20133,20565,21683,22419,22874,23401,23475,25032,26999,28023,28707,34809,35299,
+35442,35559,36994,39405,39608,21182,26680,20502,24184,26447,33607,34892,20139,
+21521,22190,29670,37141,38911,39177,39255,39321,22099,22687,34395,35377,25010,
+27382,29563,36562,27463,38570,39511,22869,29184,36203,38761,20436,23796,24358,
+25080,26203,27883,28843,29572,29625,29694,30505,30541,32067,32098,32291,33335,
+34898,64010,36066,37449,39023,23377,31348,34880,38913,23244,20448,21332,22846,
+23805,25406,28025,29433,33029,33031,33698,37583,38960,20136,20804,21009,22411,
+24418,27842,28366,28677,28752,28847,29074,29673,29801,33610,34722,34913,36872,
+37026,37795,39336,20846,24407,24800,24935,26291,34137,36426,37295,38795,20046,
+20114,21628,22741,22778,22909,23733,24359,25142,25160,26122,26215,27627,28009,
+28111,28246,28408,28564,28640,28649,28765,29392,29733,29786,29920,30355,31068,
+31946,32286,32993,33446,33899,33983,34382,34399,34676,35703,35946,37804,38912,
+39013,24785,25110,37239,23130,26127,28151,28222,29759,39746,24573,24794,31503,
+21700,24344,27742,27859,27946,28888,32005,34425,35340,40251,21270,21644,23301,
+27194,28779,30069,31117,31166,33457,33775,35441,35649,36008,38772,64011,25844,
+25899,30906,30907,31339,20024,21914,22864,23462,24187,24739,25563,27489,26213,
+26707,28185,29029,29872,32008,36996,39529,39973,27963,28369,29502,35905,38346,
+20976,24140,24488,24653,24822,24880,24908,26179,26180,27045,27841,28255,28361,
+28514,29004,29852,30343,31681,31783,33618,34647,36945,38541,40643,21295,22238,
+24315,24458,24674,24724,25079,26214,26371,27292,28142,28590,28784,29546,32362,
+33214,33588,34516,35496,36036,21123,29554,23446,27243,37892,21742,22150,23389,
+25928,25989,26313,26783,28045,28102,29243,32948,37237,39501,20399,20505,21402,
+21518,21564,21897,21957,24127,24460,26429,29030,29661,36869,21211,21235,22628,
+22734,28932,29071,29179,34224,35347,26248,34216,21927,26244,29002,33841,21321,
+21913,27585,24409,24509,25582,26249,28999,35569,36637,40638,20241,25658,28875,
+30054,34407,24676,35662,40440,20807,20982,21256,27958,33016,40657,26133,27427,
+28824,30165,21507,23673,32007,35350,27424,27453,27462,21560,24688,27965,32725,
+33288,20694,20958,21916,22123,22221,23020,23305,24076,24985,24984,25137,26206,
+26342,29081,29113,29114,29351,31143,31232,32690,35440,
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/langinfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/langinfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/langinfo.c	(revision 398)
@@ -0,0 +1,74 @@
+#include <locale.h>
+#include <langinfo.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+static const char c_time[] =
+	"Sun\0" "Mon\0" "Tue\0" "Wed\0" "Thu\0" "Fri\0" "Sat\0"
+	"Sunday\0" "Monday\0" "Tuesday\0" "Wednesday\0"
+	"Thursday\0" "Friday\0" "Saturday\0"
+	"Jan\0" "Feb\0" "Mar\0" "Apr\0" "May\0" "Jun\0"
+	"Jul\0" "Aug\0" "Sep\0" "Oct\0" "Nov\0" "Dec\0"
+	"January\0"   "February\0" "March\0"    "April\0"
+	"May\0"       "June\0"     "July\0"     "August\0"
+	"September\0" "October\0"  "November\0" "December\0"
+	"AM\0" "PM\0"
+	"%a %b %e %T %Y\0"
+	"%m/%d/%y\0"
+	"%H:%M:%S\0"
+	"%I:%M:%S %p\0"
+	"\0"
+	"\0"
+	"%m/%d/%y\0"
+	"0123456789\0"
+	"%a %b %e %T %Y\0"
+	"%H:%M:%S";
+
+static const char c_messages[] = "^[yY]\0" "^[nN]\0" "yes\0" "no";
+static const char c_numeric[] = ".\0" "";
+
+char *__nl_langinfo_l(nl_item item, locale_t loc)
+{
+	int cat = item >> 16;
+	int idx = item & 65535;
+	const char *str;
+
+	if (item == CODESET) return MB_CUR_MAX==1 ? "ASCII" : "UTF-8";
+
+	/* _NL_LOCALE_NAME extension */
+	if (idx == 65535 && cat < LC_ALL)
+		return loc->cat[cat] ? (char *)loc->cat[cat]->name : "C";
+	
+	switch (cat) {
+	case LC_NUMERIC:
+		if (idx > 1) return "";
+		str = c_numeric;
+		break;
+	case LC_TIME:
+		if (idx > 0x31) return "";
+		str = c_time;
+		break;
+	case LC_MONETARY:
+		if (idx > 0) return "";
+		str = "";
+		break;
+	case LC_MESSAGES:
+		if (idx > 3) return "";
+		str = c_messages;
+		break;
+	default:
+		return "";
+	}
+
+	for (; idx; idx--, str++) for (; *str; str++);
+	if (cat != LC_NUMERIC && *str) str = LCTRANS(str, cat, loc);
+	return (char *)str;
+}
+
+char *__nl_langinfo(nl_item item)
+{
+	return __nl_langinfo_l(item, CURRENT_LOCALE);
+}
+
+weak_alias(__nl_langinfo, nl_langinfo);
+weak_alias(__nl_langinfo_l, nl_langinfo_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/legacychars.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/legacychars.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/legacychars.h	(revision 398)
@@ -0,0 +1,41 @@
+0,1,160,167,168,169,175,176,178,183,184,198,215,216,230,247,248,162,163,165,
+196,197,198,199,201,214,215,216,220,224,226,228,229,230,231,232,233,234,235,
+236,238,239,242,244,246,248,249,251,252,255,256,257,258,259,260,261,262,263,
+264,265,266,267,268,269,270,271,272,273,274,275,278,279,280,281,282,283,284,
+285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,302,303,304,305,
+308,309,310,311,312,313,314,315,316,317,318,321,322,323,324,325,326,327,328,
+330,331,332,333,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,
+351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,
+370,371,372,373,374,375,376,377,378,379,380,381,382,402,416,417,431,432,536,
+537,538,539,710,711,728,729,731,732,733,768,769,771,777,803,890,900,901,902,
+904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,
+925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,
+945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,
+964,965,966,967,968,969,970,
+971,972,973,974,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,
+1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,
+1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,
+1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,
+1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,
+1098,1099,1100,1101,1102,1103,1105,1106,1107,1108,1109,1110,1111,1112,1113,
+1114,1115,1116,1118,1119,1168,1169,1456,1457,1458,1459,1460,1461,1462,1463,
+1464,1465,1467,1468,1469,1470,1471,1472,1473,1474,1475,1488,1489,1490,1491,
+1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,
+1507,1508,1509,1510,1511,1512,1513,1514,1520,1521,1522,1523,1524,1548,1563,
+1567,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,
+1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1600,1601,1602,
+1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,
+1618,1657,1662,1670,1672,1681,1688,1705,1711,1722,1726,1729,1746,3585,3586,
+3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,
+3602,3603,3604,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,
+3617,3618,3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,
+3632,3633,3634,3635,3636,3637,3638,3639,3640,3641,3642,3647,3648,3649,3650,
+3651,3652,3653,3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,
+3666,3667,3668,3669,3670,3671,3672,3673,3674,3675,7682,7683,7690,7691,7710,
+7711,7744,7745,7766,7767,7776,7777,7786,7787,7808,7809,7810,7811,7812,7813,
+7922,7923,8204,8205,8206,8207,8211,8212,8213,8215,8216,8217,8218,8220,8221,
+8222,8224,8225,8226,8230,8240,8249,8250,8362,8363,8364,8367,8359,8470,8482,
+8729,8730,8776,8804,8805,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,
+9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,
+9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,
+9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/locale_map.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/locale_map.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/locale_map.c	(revision 398)
@@ -0,0 +1,116 @@
+#include <locale.h>
+#include <string.h>
+#include "locale_impl.h"
+#include "libc.h"
+#include "atomic.h"
+
+const char *__lctrans_impl(const char *msg, const struct __locale_map *lm)
+{
+	const char *trans = 0;
+	if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg);
+	return trans ? trans : msg;
+}
+
+const unsigned char *__map_file(const char *, size_t *);
+int __munmap(void *, size_t);
+char *__strchrnul(const char *, int);
+
+static const char envvars[][12] = {
+	"LC_CTYPE",
+	"LC_NUMERIC",
+	"LC_TIME",
+	"LC_COLLATE",
+	"LC_MONETARY",
+	"LC_MESSAGES",
+};
+
+const struct __locale_map *__get_locale(int cat, const char *val)
+{
+	static volatile int lock[2];
+	static void *volatile loc_head;
+	const struct __locale_map *p;
+	struct __locale_map *new = 0;
+	const char *path = 0, *z;
+	char buf[256];
+	size_t l, n;
+
+	if (!*val) {
+		((val = getenv("LC_ALL")) && *val) ||
+		((val = getenv(envvars[cat])) && *val) ||
+		((val = getenv("LANG")) && *val) ||
+		(val = "C.UTF-8");
+	}
+
+	/* Limit name length and forbid leading dot or any slashes. */
+	for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++);
+	if (val[0]=='.' || val[n]) val = "C.UTF-8";
+	int builtin = (val[0]=='C' && !val[1])
+		|| !strcmp(val, "C.UTF-8")
+		|| !strcmp(val, "POSIX");
+
+	if (builtin) {
+		if (cat == LC_CTYPE && val[1]=='.')
+			return (void *)&__c_dot_utf8;
+		return 0;
+	}
+
+	for (p=loc_head; p; p=p->next)
+		if (!strcmp(val, p->name)) return p;
+
+	LOCK(lock);
+
+	for (p=loc_head; p; p=p->next)
+		if (!strcmp(val, p->name)) {
+			UNLOCK(lock);
+			return p;
+		}
+
+	if (!libc.secure) path = getenv("MUSL_LOCPATH");
+	/* FIXME: add a default path? */
+
+	if (path) for (; *path; path=z+!!*z) {
+		z = __strchrnul(path, ':');
+		l = z - path - !!*z;
+		if (l >= sizeof buf - n - 2) continue;
+		memcpy(buf, path, l);
+		buf[l] = '/';
+		memcpy(buf+l+1, val, n);
+		buf[l+1+n] = 0;
+		size_t map_size;
+		const void *map = __map_file(buf, &map_size);
+		if (map) {
+			new = malloc(sizeof *new);
+			if (!new) {
+				__munmap((void *)map, map_size);
+				break;
+			}
+			new->map = map;
+			new->map_size = map_size;
+			memcpy(new->name, val, n);
+			new->name[n] = 0;
+			new->next = loc_head;
+			loc_head = new;
+			break;
+		}
+	}
+
+	/* If no locale definition was found, make a locale map
+	 * object anyway to store the name, which is kept for the
+	 * sake of being able to do message translations at the
+	 * application level. */
+	if (!new && (new = malloc(sizeof *new))) {
+		new->map = __c_dot_utf8.map;
+		new->map_size = __c_dot_utf8.map_size;
+		memcpy(new->name, val, n);
+		new->name[n] = 0;
+		new->next = loc_head;
+		loc_head = new;
+	}
+
+	/* For LC_CTYPE, never return a null pointer unless the
+	 * requested name was "C" or "POSIX". */
+	if (!new && cat == LC_CTYPE) new = (void *)&__c_dot_utf8;
+
+	UNLOCK(lock);
+	return new;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/localeconv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/localeconv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/localeconv.c	(revision 398)
@@ -0,0 +1,34 @@
+#include <locale.h>
+#include <limits.h>
+
+static const struct lconv posix_lconv = {
+	.decimal_point = ".",
+	.thousands_sep = "",
+	.grouping = "",
+	.int_curr_symbol = "",
+	.currency_symbol = "",
+	.mon_decimal_point = "",
+	.mon_thousands_sep = "",
+	.mon_grouping = "",
+	.positive_sign = "",
+	.negative_sign = "",
+	.int_frac_digits = CHAR_MAX,
+	.frac_digits = CHAR_MAX,
+	.p_cs_precedes = CHAR_MAX,
+	.p_sep_by_space = CHAR_MAX,
+	.n_cs_precedes = CHAR_MAX,
+	.n_sep_by_space = CHAR_MAX,
+	.p_sign_posn = CHAR_MAX,
+	.n_sign_posn = CHAR_MAX,
+	.int_p_cs_precedes = CHAR_MAX,
+	.int_p_sep_by_space = CHAR_MAX,
+	.int_n_cs_precedes = CHAR_MAX,
+	.int_n_sep_by_space = CHAR_MAX,
+	.int_p_sign_posn = CHAR_MAX,
+	.int_n_sign_posn = CHAR_MAX,
+};
+
+struct lconv *localeconv(void)
+{
+	return (void *)&posix_lconv;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/newlocale.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/newlocale.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/newlocale.c	(revision 398)
@@ -0,0 +1,49 @@
+#include <stdlib.h>
+#include <string.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+int __loc_is_allocated(locale_t loc)
+{
+	return loc && loc != C_LOCALE && loc != UTF8_LOCALE;
+}
+
+locale_t __newlocale(int mask, const char *name, locale_t loc)
+{
+	int i, j;
+	struct __locale_struct tmp;
+	const struct __locale_map *lm;
+
+	/* For locales with allocated storage, modify in-place. */
+	if (__loc_is_allocated(loc)) {
+		for (i=0; i<LC_ALL; i++)
+			if (mask & (1<<i))
+				loc->cat[i] = __get_locale(i, name);
+		return loc;
+	}
+
+	/* Otherwise, build a temporary locale object, which will only
+	 * be instantiated in allocated storage if it does not match
+	 * one of the built-in static locales. This makes the common
+	 * usage case for newlocale, getting a C locale with predictable
+	 * behavior, very fast, and more importantly, fail-safe. */
+	for (j=i=0; i<LC_ALL; i++) {
+		if (loc && !(mask & (1<<i)))
+			lm = loc->cat[i];
+		else
+			lm = __get_locale(i, mask & (1<<i) ? name : "");
+		if (lm) j++;
+		tmp.cat[i] = lm;
+	}
+
+	if (!j)
+		return C_LOCALE;
+	if (j==1 && tmp.cat[LC_CTYPE]==&__c_dot_utf8)
+		return UTF8_LOCALE;
+
+	if ((loc = malloc(sizeof *loc))) *loc = tmp;
+
+	return loc;
+}
+
+weak_alias(__newlocale, newlocale);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/pleval.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/pleval.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/pleval.c	(revision 398)
@@ -0,0 +1,157 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+/*
+grammar:
+
+Start = Expr ';'
+Expr  = Or | Or '?' Expr ':' Expr
+Or    = And | Or '||' And
+And   = Eq | And '&&' Eq
+Eq    = Rel | Eq '==' Rel | Eq '!=' Rel
+Rel   = Add | Rel '<=' Add | Rel '>=' Add | Rel '<' Add | Rel '>' Add
+Add   = Mul | Add '+' Mul | Add '-' Mul
+Mul   = Prim | Mul '*' Prim | Mul '/' Prim | Mul '%' Prim
+Prim  = '(' Expr ')' | '!' Prim | decimal | 'n'
+
+internals:
+
+recursive descent expression evaluator with stack depth limit.
+for binary operators an operator-precedence parser is used.
+eval* functions store the result of the parsed subexpression
+and return a pointer to the next non-space character.
+*/
+
+struct st {
+	unsigned long r;
+	unsigned long n;
+	int op;
+};
+
+static const char *skipspace(const char *s)
+{
+	while (isspace(*s)) s++;
+	return s;
+}
+
+static const char *evalexpr(struct st *st, const char *s, int d);
+
+static const char *evalprim(struct st *st, const char *s, int d)
+{
+	char *e;
+	if (--d < 0) return "";
+	s = skipspace(s);
+	if (isdigit(*s)) {
+		st->r = strtoul(s, &e, 10);
+		if (e == s || st->r == -1) return "";
+		return skipspace(e);
+	}
+	if (*s == 'n') {
+		st->r = st->n;
+		return skipspace(s+1);
+	}
+	if (*s == '(') {
+		s = evalexpr(st, s+1, d);
+		if (*s != ')') return "";
+		return skipspace(s+1);
+	}
+	if (*s == '!') {
+		s = evalprim(st, s+1, d);
+		st->r = !st->r;
+		return s;
+	}
+	return "";
+}
+
+static int binop(struct st *st, int op, unsigned long left)
+{
+	unsigned long a = left, b = st->r;
+	switch (op) {
+	case 0: st->r = a||b; return 0;
+	case 1: st->r = a&&b; return 0;
+	case 2: st->r = a==b; return 0;
+	case 3: st->r = a!=b; return 0;
+	case 4: st->r = a>=b; return 0;
+	case 5: st->r = a<=b; return 0;
+	case 6: st->r = a>b; return 0;
+	case 7: st->r = a<b; return 0;
+	case 8: st->r = a+b; return 0;
+	case 9: st->r = a-b; return 0;
+	case 10: st->r = a*b; return 0;
+	case 11: if (b) {st->r = a%b; return 0;} return 1;
+	case 12: if (b) {st->r = a/b; return 0;} return 1;
+	}
+	return 1;
+}
+
+static const char *parseop(struct st *st, const char *s)
+{
+	static const char opch[11] = "|&=!><+-*%/";
+	static const char opch2[6] = "|&====";
+	int i;
+	for (i=0; i<11; i++)
+		if (*s == opch[i]) {
+			/* note: >,< are accepted with or without = */
+			if (i<6 && s[1] == opch2[i]) {
+				st->op = i;
+				return s+2;
+			}
+			if (i>=4) {
+				st->op = i+2;
+				return s+1;
+			}
+			break;
+		}
+	st->op = 13;
+	return s;
+}
+
+static const char *evalbinop(struct st *st, const char *s, int minprec, int d)
+{
+	static const char prec[14] = {1,2,3,3,4,4,4,4,5,5,6,6,6,0};
+	unsigned long left;
+	int op;
+	d--;
+	s = evalprim(st, s, d);
+	s = parseop(st, s);
+	for (;;) {
+		/*
+		st->r (left hand side value) and st->op are now set,
+		get the right hand side or back out if op has low prec,
+		if op was missing then prec[op]==0
+		*/
+		op = st->op;
+		if (prec[op] <= minprec)
+			return s;
+		left = st->r;
+		s = evalbinop(st, s, prec[op], d);
+		if (binop(st, op, left))
+			return "";
+	}
+}
+
+static const char *evalexpr(struct st *st, const char *s, int d)
+{
+	unsigned long a, b;
+	if (--d < 0)
+		return "";
+	s = evalbinop(st, s, 0, d);
+	if (*s != '?')
+		return s;
+	a = st->r;
+	s = evalexpr(st, s+1, d);
+	if (*s != ':')
+		return "";
+	b = st->r;
+	s = evalexpr(st, s+1, d);
+	st->r = a ? b : st->r;
+	return s;
+}
+
+unsigned long __pleval(const char *s, unsigned long n)
+{
+	struct st st;
+	st.n = n;
+	s = evalexpr(&st, s, 100);
+	return *s == ';' ? st.r : -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/setlocale.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/setlocale.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/setlocale.c	(revision 398)
@@ -0,0 +1,73 @@
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include "locale_impl.h"
+#include "libc.h"
+#include "atomic.h"
+
+static char buf[LC_ALL*(LOCALE_NAME_MAX+1)];
+
+static char *setlocale_one_unlocked(int cat, const char *name)
+{
+	const struct __locale_map *lm;
+
+	if (name) libc.global_locale.cat[cat] = lm = __get_locale(cat, name);
+	else lm = libc.global_locale.cat[cat];
+
+	return lm ? (char *)lm->name : "C";
+}
+
+char *__strchrnul(const char *, int);
+
+char *setlocale(int cat, const char *name)
+{
+	static volatile int lock[2];
+
+	if ((unsigned)cat > LC_ALL) return 0;
+
+	LOCK(lock);
+
+	/* For LC_ALL, setlocale is required to return a string which
+	 * encodes the current setting for all categories. The format of
+	 * this string is unspecified, and only the following code, which
+	 * performs both the serialization and deserialization, depends
+	 * on the format, so it can easily be changed if needed. */
+	if (cat == LC_ALL) {
+		int i;
+		if (name) {
+			char part[LOCALE_NAME_MAX+1] = "C.UTF-8";
+			const char *p = name;
+			for (i=0; i<LC_ALL; i++) {
+				const char *z = __strchrnul(p, ';');
+				if (z-p <= LOCALE_NAME_MAX) {
+					memcpy(part, p, z-p);
+					part[z-p] = 0;
+					if (*z) p = z+1;
+				}
+				setlocale_one_unlocked(i, part);
+			}
+		}
+		char *s = buf;
+		const char *part;
+		int same = 0;
+		for (i=0; i<LC_ALL; i++) {
+			const struct __locale_map *lm =
+				libc.global_locale.cat[i];
+			if (lm == libc.global_locale.cat[0]) same++;
+			part = lm ? lm->name : "C";
+			size_t l = strlen(part);
+			memcpy(s, part, l);
+			s[l] = ';';
+			s += l+1;
+		}
+		*--s = 0;
+		UNLOCK(lock);
+		return same==LC_ALL ? (char *)part : buf;
+	}
+
+	char *ret = setlocale_one_unlocked(cat, name);
+
+	UNLOCK(lock);
+
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/strcoll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/strcoll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/strcoll.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <string.h>
+#include <locale.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+int __strcoll_l(const char *l, const char *r, locale_t loc)
+{
+	return strcmp(l, r);
+}
+
+int strcoll(const char *l, const char *r)
+{
+	return __strcoll_l(l, r, CURRENT_LOCALE);
+}
+
+weak_alias(__strcoll_l, strcoll_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/strfmon.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/strfmon.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/strfmon.c	(revision 398)
@@ -0,0 +1,101 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <monetary.h>
+#include <errno.h>
+#include "locale_impl.h"
+
+static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_list ap)
+{
+	size_t l;
+	double x;
+	int fill, nogrp, negpar, nosym, left, intl;
+	int lp, rp, w, fw;
+	char *s0=s;
+	for (; n && *fmt; ) {
+		if (*fmt != '%') {
+		literal:
+			*s++ = *fmt++;
+			n--;
+			continue;
+		}
+		fmt++;
+		if (*fmt == '%') goto literal;
+
+		fill = ' ';
+		nogrp = 0;
+		negpar = 0;
+		nosym = 0;
+		left = 0;
+		for (; ; fmt++) {
+			switch (*fmt) {
+			case '=':
+				fill = *++fmt;
+				continue;
+			case '^':
+				nogrp = 1;
+				continue;
+			case '(':
+				negpar = 1;
+			case '+':
+				continue;
+			case '!':
+				nosym = 1;
+				continue;
+			case '-':
+				left = 1;
+				continue;
+			}
+			break;
+		}
+
+		for (fw=0; isdigit(*fmt); fmt++)
+			fw = 10*fw + (*fmt-'0');
+		lp = 0;
+		rp = 2;
+		if (*fmt=='#') for (lp=0, fmt++; isdigit(*fmt); fmt++)
+			lp = 10*lp + (*fmt-'0');
+		if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++)
+			rp = 10*rp + (*fmt-'0');
+
+		intl = *fmt++ == 'i';
+
+		w = lp + 1 + rp;
+		if (!left && fw>w) w = fw;
+
+		x = va_arg(ap, double);
+		l = snprintf(s, n, "%*.*f", w, rp, x);
+		if (l >= n) {
+			errno = E2BIG;
+			return -1;
+		}
+		s += l;
+		n -= l;
+	}
+	return s-s0;
+}
+
+ssize_t strfmon_l(char *restrict s, size_t n, locale_t loc, const char *restrict fmt, ...)
+{
+	va_list ap;
+	ssize_t ret;
+
+	va_start(ap, fmt);
+	ret = vstrfmon_l(s, n, loc, fmt, ap);
+	va_end(ap);
+
+	return ret;
+}
+
+
+ssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...)
+{
+	va_list ap;
+	ssize_t ret;
+
+	va_start(ap, fmt);
+	ret = vstrfmon_l(s, n, CURRENT_LOCALE, fmt, ap);
+	va_end(ap);
+
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/strxfrm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/strxfrm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/strxfrm.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <string.h>
+#include <locale.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+/* collate only by code points */
+size_t __strxfrm_l(char *restrict dest, const char *restrict src, size_t n, locale_t loc)
+{
+	size_t l = strlen(src);
+	if (n > l) strcpy(dest, src);
+	return l;
+}
+
+size_t strxfrm(char *restrict dest, const char *restrict src, size_t n)
+{
+	return __strxfrm_l(dest, src, n, CURRENT_LOCALE);
+}
+
+weak_alias(__strxfrm_l, strxfrm_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/textdomain.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/textdomain.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/textdomain.c	(revision 398)
@@ -0,0 +1,44 @@
+#include <libintl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+#include "libc.h"
+#include "atomic.h"
+
+static char *current_domain;
+
+char *__gettextdomain()
+{
+	return current_domain ? current_domain : "messages";
+}
+
+char *textdomain(const char *domainname)
+{
+	if (!domainname) return __gettextdomain();
+
+	size_t domlen = strlen(domainname);
+	if (domlen > NAME_MAX) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	if (!current_domain) {
+		current_domain = malloc(NAME_MAX+1);
+		if (!current_domain) return 0;
+	}
+
+	memcpy(current_domain, domainname, domlen+1);
+
+	return current_domain;
+}
+
+char *gettext(const char *msgid)
+{
+	return dgettext(0, msgid);
+}
+
+char *ngettext(const char *msgid1, const char *msgid2, unsigned long int n)
+{
+	return dngettext(0, msgid1, msgid2, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/uselocale.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/uselocale.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/uselocale.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "locale_impl.h"
+#include "pthread_impl.h"
+#include "libc.h"
+
+locale_t __uselocale(locale_t new)
+{
+	pthread_t self = __pthread_self();
+	locale_t old = self->locale;
+	locale_t global = &libc.global_locale;
+
+	if (new) self->locale = new == LC_GLOBAL_LOCALE ? global : new;
+
+	return old == global ? LC_GLOBAL_LOCALE : old;
+}
+
+weak_alias(__uselocale, uselocale);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/wcscoll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/wcscoll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/wcscoll.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <wchar.h>
+#include <locale.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+/* FIXME: stub */
+int __wcscoll_l(const wchar_t *l, const wchar_t *r, locale_t locale)
+{
+	return wcscmp(l, r);
+}
+
+int wcscoll(const wchar_t *l, const wchar_t *r)
+{
+	return __wcscoll_l(l, r, CURRENT_LOCALE);
+}
+
+weak_alias(__wcscoll_l, wcscoll_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/wcsxfrm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/wcsxfrm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/locale/wcsxfrm.c	(revision 398)
@@ -0,0 +1,24 @@
+#include <wchar.h>
+#include <locale.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+/* collate only by code points */
+size_t __wcsxfrm_l(wchar_t *restrict dest, const wchar_t *restrict src, size_t n, locale_t loc)
+{
+	size_t l = wcslen(src);
+	if (l < n) {
+		wmemcpy(dest, src, l+1);
+	} else if (n) {
+		wmemcpy(dest, src, n-1);
+		dest[n-1] = 0;
+	}
+	return l;
+}
+
+size_t wcsxfrm(wchar_t *restrict dest, const wchar_t *restrict src, size_t n)
+{
+	return __wcsxfrm_l(dest, src, n, CURRENT_LOCALE);
+}
+
+weak_alias(__wcsxfrm_l, wcsxfrm_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/__brk.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/__brk.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/__brk.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <stdint.h>
+#include "syscall.h"
+
+uintptr_t __brk(uintptr_t newbrk)
+{
+	return __syscall(SYS_brk, newbrk);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/aligned_alloc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/aligned_alloc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/aligned_alloc.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+
+void *__memalign(size_t, size_t);
+
+void *aligned_alloc(size_t align, size_t len)
+{
+	return __memalign(align, len);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/calloc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/calloc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/calloc.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <errno.h>
+
+void *__malloc0(size_t);
+
+void *calloc(size_t m, size_t n)
+{
+	if (n && m > (size_t)-1/n) {
+		errno = ENOMEM;
+		return 0;
+	}
+	return __malloc0(n * m);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/expand_heap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/expand_heap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/expand_heap.c	(revision 398)
@@ -0,0 +1,72 @@
+#include <limits.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include "libc.h"
+#include "syscall.h"
+
+/* This function returns true if the interval [old,new]
+ * intersects the 'len'-sized interval below &libc.auxv
+ * (interpreted as the main-thread stack) or below &b
+ * (the current stack). It is used to defend against
+ * buggy brk implementations that can cross the stack. */
+
+static int traverses_stack_p(uintptr_t old, uintptr_t new)
+{
+	const uintptr_t len = 8<<20;
+	uintptr_t a, b;
+
+	b = (uintptr_t)libc.auxv;
+	a = b > len ? b-len : 0;
+	if (new>a && old<b) return 1;
+
+	b = (uintptr_t)&b;
+	a = b > len ? b-len : 0;
+	if (new>a && old<b) return 1;
+
+	return 0;
+}
+
+void *__mmap(void *, size_t, int, int, int, off_t);
+
+/* Expand the heap in-place if brk can be used, or otherwise via mmap,
+ * using an exponential lower bound on growth by mmap to make
+ * fragmentation asymptotically irrelevant. The size argument is both
+ * an input and an output, since the caller needs to know the size
+ * allocated, which will be larger than requested due to page alignment
+ * and mmap minimum size rules. The caller is responsible for locking
+ * to prevent concurrent calls. */
+
+void *__expand_heap(size_t *pn)
+{
+	static uintptr_t brk;
+	static unsigned mmap_step;
+	size_t n = *pn;
+
+	if (n > SIZE_MAX/2 - PAGE_SIZE) {
+		errno = ENOMEM;
+		return 0;
+	}
+	n += -n & PAGE_SIZE-1;
+
+	if (!brk) {
+		brk = __syscall(SYS_brk, 0);
+		brk += -brk & PAGE_SIZE-1;
+	}
+
+	if (n < SIZE_MAX-brk && !traverses_stack_p(brk, brk+n)
+	    && __syscall(SYS_brk, brk+n)==brk+n) {
+		*pn = n;
+		brk += n;
+		return (void *)(brk-n);
+	}
+
+	size_t min = (size_t)PAGE_SIZE << mmap_step/2;
+	if (n < min) n = min;
+	void *area = __mmap(0, n, PROT_READ|PROT_WRITE,
+		MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+	if (area == MAP_FAILED) return 0;
+	*pn = n;
+	mmap_step++;
+	return area;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/lite_malloc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/lite_malloc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/lite_malloc.c	(revision 398)
@@ -0,0 +1,50 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include <errno.h>
+#include "libc.h"
+
+#define ALIGN 16
+
+void *__expand_heap(size_t *);
+
+static void *__simple_malloc(size_t n)
+{
+	static char *cur, *end;
+	static volatile int lock[2];
+	size_t align=1, pad;
+	void *p;
+
+	if (!n) n++;
+	while (align<n && align<ALIGN)
+		align += align;
+
+	LOCK(lock);
+
+	pad = -(uintptr_t)cur & align-1;
+
+	if (n <= SIZE_MAX/2 + ALIGN) n += pad;
+
+	if (n > end-cur) {
+		size_t m = n;
+		char *new = __expand_heap(&m);
+		if (!new) {
+			UNLOCK(lock);
+			return 0;
+		}
+		if (new != end) {
+			cur = new;
+			n -= pad;
+			pad = 0;
+		}
+		end = new + m;
+	}
+
+	p = cur + pad;
+	cur += n;
+	UNLOCK(lock);
+	return p;
+}
+
+weak_alias(__simple_malloc, malloc);
+weak_alias(__simple_malloc, __malloc0);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/malloc.~c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/malloc.~c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/malloc.~c	(revision 398)
@@ -0,0 +1,533 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include "libc.h"
+#include "atomic.h"
+#include "pthread_impl.h"
+
+#if defined(__GNUC__) && defined(__PIC__)
+#define inline inline __attribute__((always_inline))
+#endif
+
+void *__mmap(void *, size_t, int, int, int, off_t);
+int __munmap(void *, size_t);
+void *__mremap(void *, size_t, size_t, int, ...);
+int __madvise(void *, size_t, int);
+
+struct chunk {
+	size_t psize, csize;
+	struct chunk *next, *prev;
+};
+
+struct bin {
+	volatile int lock[2];
+	struct chunk *head;
+	struct chunk *tail;
+};
+
+static struct {
+	volatile uint64_t binmap;
+	struct bin bins[64];
+	volatile int free_lock[2];
+} mal;
+
+
+#define SIZE_ALIGN (4*sizeof(size_t))
+#define SIZE_MASK (-SIZE_ALIGN)
+#define OVERHEAD (2*sizeof(size_t))
+#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN)
+#define DONTCARE 16
+#define RECLAIM 163840
+
+#define CHUNK_SIZE(c) ((c)->csize & -2)
+#define CHUNK_PSIZE(c) ((c)->psize & -2)
+#define PREV_CHUNK(c) ((struct chunk *)((char *)(c) - CHUNK_PSIZE(c)))
+#define NEXT_CHUNK(c) ((struct chunk *)((char *)(c) + CHUNK_SIZE(c)))
+#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD)
+#define CHUNK_TO_MEM(c) (void *)((char *)(c) + OVERHEAD)
+#define BIN_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.bins[i].head))
+
+#define C_INUSE  ((size_t)1)
+
+#define IS_MMAPPED(c) !((c)->csize & (C_INUSE))
+
+
+/* Synchronization tools */
+
+static inline void lock(volatile int *lk)
+{
+	if (libc.threads_minus_1)
+		while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
+}
+
+static inline void unlock(volatile int *lk)
+{
+	if (lk[0]) {
+		a_store(lk, 0);
+		if (lk[1]) __wake(lk, 1, 1);
+	}
+}
+
+static inline void lock_bin(int i)
+{
+	lock(mal.bins[i].lock);
+	if (!mal.bins[i].head)
+		mal.bins[i].head = mal.bins[i].tail = BIN_TO_CHUNK(i);
+}
+
+static inline void unlock_bin(int i)
+{
+	unlock(mal.bins[i].lock);
+}
+
+static int first_set(uint64_t x)
+{
+#if 1
+	return a_ctz_64(x);
+#else
+	static const char debruijn64[64] = {
+		0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
+		62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
+		63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
+		51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
+	};
+	static const char debruijn32[32] = {
+		0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
+		31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
+	};
+	if (sizeof(long) < 8) {
+		uint32_t y = x;
+		if (!y) {
+			y = x>>32;
+			return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
+		}
+		return debruijn32[(y&-y)*0x076be629 >> 27];
+	}
+	return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
+#endif
+}
+
+static const unsigned char bin_tab[60] = {
+	            32,33,34,35,36,36,37,37,38,38,39,39,
+	40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,
+	44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,45,
+	46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,
+};
+
+static int bin_index(size_t x)
+{
+	x = x / SIZE_ALIGN - 1;
+	if (x <= 32) return x;
+	if (x < 512) return bin_tab[x/8-4];
+	if (x > 0x1c00) return 63;
+	return bin_tab[x/128-4] + 16;
+}
+
+static int bin_index_up(size_t x)
+{
+	x = x / SIZE_ALIGN - 1;
+	if (x <= 32) return x;
+	x--;
+	if (x < 512) return bin_tab[x/8-4] + 1;
+	return bin_tab[x/128-4] + 17;
+}
+
+#if 0
+void __dump_heap(int x)
+{
+	struct chunk *c;
+	int i;
+	for (c = (void *)mal.heap; CHUNK_SIZE(c); c = NEXT_CHUNK(c))
+		fprintf(stderr, "base %p size %zu (%d) flags %d/%d\n",
+			c, CHUNK_SIZE(c), bin_index(CHUNK_SIZE(c)),
+			c->csize & 15,
+			NEXT_CHUNK(c)->psize & 15);
+	for (i=0; i<64; i++) {
+		if (mal.bins[i].head != BIN_TO_CHUNK(i) && mal.bins[i].head) {
+			fprintf(stderr, "bin %d: %p\n", i, mal.bins[i].head);
+			if (!(mal.binmap & 1ULL<<i))
+				fprintf(stderr, "missing from binmap!\n");
+		} else if (mal.binmap & 1ULL<<i)
+			fprintf(stderr, "binmap wrongly contains %d!\n", i);
+	}
+}
+#endif
+
+void *__expand_heap(size_t *);
+
+static struct chunk *expand_heap(size_t n)
+{
+	static int heap_lock[2];
+	static void *end;
+	void *p;
+	struct chunk *w;
+
+	/* The argument n already accounts for the caller's chunk
+	 * overhead needs, but if the heap can't be extended in-place,
+	 * we need room for an extra zero-sized sentinel chunk. */
+	n += SIZE_ALIGN;
+
+	lock(heap_lock);
+
+	p = __expand_heap(&n);
+	if (!p) {
+		unlock(heap_lock);
+		return 0;
+	}
+
+	/* If not just expanding existing space, we need to make a
+	 * new sentinel chunk below the allocated space. */
+	if (p != end) {
+		/* Valid/safe because of the prologue increment. */
+		n -= SIZE_ALIGN;
+		p = (char *)p + SIZE_ALIGN;
+		w = MEM_TO_CHUNK(p);
+		w->psize = 0 | C_INUSE;
+	}
+
+	/* Record new heap end and fill in footer. */
+	end = (char *)p + n;
+	w = MEM_TO_CHUNK(end);
+	w->psize = n | C_INUSE;
+	w->csize = 0 | C_INUSE;
+
+	/* Fill in header, which may be new or may be replacing a
+	 * zero-size sentinel header at the old end-of-heap. */
+	w = MEM_TO_CHUNK(p);
+	w->csize = n | C_INUSE;
+
+	unlock(heap_lock);
+
+	return w;
+}
+
+static int adjust_size(size_t *n)
+{
+	/* Result of pointer difference must fit in ptrdiff_t. */
+	if (*n-1 > PTRDIFF_MAX - SIZE_ALIGN - PAGE_SIZE) {
+		if (*n) {
+			errno = ENOMEM;
+			return -1;
+		} else {
+			*n = SIZE_ALIGN;
+			return 0;
+		}
+	}
+	*n = (*n + OVERHEAD + SIZE_ALIGN - 1) & SIZE_MASK;
+	return 0;
+}
+
+static void unbin(struct chunk *c, int i)
+{
+	if (c->prev == c->next)
+		a_and_64(&mal.binmap, ~(1ULL<<i));
+	c->prev->next = c->next;
+	c->next->prev = c->prev;
+	c->csize |= C_INUSE;
+	NEXT_CHUNK(c)->psize |= C_INUSE;
+}
+
+static int alloc_fwd(struct chunk *c)
+{
+	int i;
+	size_t k;
+	while (!((k=c->csize) & C_INUSE)) {
+		i = bin_index(k);
+		lock_bin(i);
+		if (c->csize == k) {
+			unbin(c, i);
+			unlock_bin(i);
+			return 1;
+		}
+		unlock_bin(i);
+	}
+	return 0;
+}
+
+static int alloc_rev(struct chunk *c)
+{
+	int i;
+	size_t k;
+	while (!((k=c->psize) & C_INUSE)) {
+		i = bin_index(k);
+		lock_bin(i);
+		if (c->psize == k) {
+			unbin(PREV_CHUNK(c), i);
+			unlock_bin(i);
+			return 1;
+		}
+		unlock_bin(i);
+	}
+	return 0;
+}
+
+
+/* pretrim - trims a chunk _prior_ to removing it from its bin.
+ * Must be called with i as the ideal bin for size n, j the bin
+ * for the _free_ chunk self, and bin j locked. */
+static int pretrim(struct chunk *self, size_t n, int i, int j)
+{
+	size_t n1;
+	struct chunk *next, *split;
+
+	/* We cannot pretrim if it would require re-binning. */
+	if (j < 40) return 0;
+	if (j < i+3) {
+		if (j != 63) return 0;
+		n1 = CHUNK_SIZE(self);
+		if (n1-n <= MMAP_THRESHOLD) return 0;
+	} else {
+		n1 = CHUNK_SIZE(self);
+	}
+	if (bin_index(n1-n) != j) return 0;
+
+	next = NEXT_CHUNK(self);
+	split = (void *)((char *)self + n);
+
+	split->prev = self->prev;
+	split->next = self->next;
+	split->prev->next = split;
+	split->next->prev = split;
+	split->psize = n | C_INUSE;
+	split->csize = n1-n;
+	next->psize = n1-n;
+	self->csize = n | C_INUSE;
+	return 1;
+}
+
+static void trim(struct chunk *self, size_t n)
+{
+	size_t n1 = CHUNK_SIZE(self);
+	struct chunk *next, *split;
+
+	if (n >= n1 - DONTCARE) return;
+
+	next = NEXT_CHUNK(self);
+	split = (void *)((char *)self + n);
+
+	split->psize = n | C_INUSE;
+	split->csize = n1-n | C_INUSE;
+	next->psize = n1-n | C_INUSE;
+	self->csize = n | C_INUSE;
+
+	free(CHUNK_TO_MEM(split));
+}
+
+void *malloc(size_t n)
+{
+	struct chunk *c;
+	int i, j;
+
+	if (adjust_size(&n) < 0) return 0;
+
+	if (n > MMAP_THRESHOLD) {
+		size_t len = n + OVERHEAD + PAGE_SIZE - 1 & -PAGE_SIZE;
+		char *base = __mmap(0, len, PROT_READ|PROT_WRITE,
+			MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+		if (base == (void *)-1) return 0;
+		c = (void *)(base + SIZE_ALIGN - OVERHEAD);
+		c->csize = len - (SIZE_ALIGN - OVERHEAD);
+		c->psize = SIZE_ALIGN - OVERHEAD;
+		return CHUNK_TO_MEM(c);
+	}
+
+	i = bin_index_up(n);
+	for (;;) {
+		uint64_t mask = mal.binmap & -(1ULL<<i);
+		if (!mask) {
+			c = expand_heap(n);
+			if (!c) return 0;
+			if (alloc_rev(c)) {
+				struct chunk *x = c;
+				c = PREV_CHUNK(c);
+				NEXT_CHUNK(x)->psize = c->csize =
+					x->csize + CHUNK_SIZE(c);
+			}
+			break;
+		}
+		j = first_set(mask);
+		lock_bin(j);
+		c = mal.bins[j].head;
+		if (c != BIN_TO_CHUNK(j)) {
+			if (!pretrim(c, n, i, j)) unbin(c, j);
+			unlock_bin(j);
+			break;
+		}
+		unlock_bin(j);
+	}
+
+	/* Now patch up in case we over-allocated */
+	trim(c, n);
+
+	return CHUNK_TO_MEM(c);
+}
+
+void *__malloc0(size_t n)
+{
+	void *p = malloc(n);
+	if (p && !IS_MMAPPED(MEM_TO_CHUNK(p))) {
+		size_t *z;
+		n = (n + sizeof *z - 1)/sizeof *z;
+		for (z=p; n; n--, z++) if (*z) *z=0;
+	}
+	return p;
+}
+
+void *realloc(void *p, size_t n)
+{
+	struct chunk *self, *next;
+	size_t n0, n1;
+	void *new;
+
+	if (!p) return malloc(n);
+
+	if (adjust_size(&n) < 0) return 0;
+
+	self = MEM_TO_CHUNK(p);
+	n1 = n0 = CHUNK_SIZE(self);
+
+	if (IS_MMAPPED(self)) {
+		size_t extra = self->psize;
+		char *base = (char *)self - extra;
+		size_t oldlen = n0 + extra;
+		size_t newlen = n + extra;
+		/* Crash on realloc of freed chunk */
+		if (extra & 1) a_crash();
+		if (newlen < PAGE_SIZE && (new = malloc(n))) {
+			memcpy(new, p, n-OVERHEAD);
+			free(p);
+			return new;
+		}
+		newlen = (newlen + PAGE_SIZE-1) & -PAGE_SIZE;
+		if (oldlen == newlen) return p;
+		base = __mremap(base, oldlen, newlen, MREMAP_MAYMOVE);
+		if (base == (void *)-1)
+			goto copy_realloc;
+		self = (void *)(base + extra);
+		self->csize = newlen - extra;
+		return CHUNK_TO_MEM(self);
+	}
+
+	next = NEXT_CHUNK(self);
+
+	/* Crash on corrupted footer (likely from buffer overflow) */
+	if (next->psize != self->csize) a_crash();
+
+	/* Merge adjacent chunks if we need more space. This is not
+	 * a waste of time even if we fail to get enough space, because our
+	 * subsequent call to free would otherwise have to do the merge. */
+	if (n > n1 && alloc_fwd(next)) {
+		n1 += CHUNK_SIZE(next);
+		next = NEXT_CHUNK(next);
+	}
+	/* FIXME: find what's wrong here and reenable it..? */
+	if (0 && n > n1 && alloc_rev(self)) {
+		self = PREV_CHUNK(self);
+		n1 += CHUNK_SIZE(self);
+	}
+	self->csize = n1 | C_INUSE;
+	next->psize = n1 | C_INUSE;
+
+	/* If we got enough space, split off the excess and return */
+	if (n <= n1) {
+		//memmove(CHUNK_TO_MEM(self), p, n0-OVERHEAD);
+		trim(self, n);
+		return CHUNK_TO_MEM(self);
+	}
+
+copy_realloc:
+	/* As a last resort, allocate a new chunk and copy to it. */
+	new = malloc(n-OVERHEAD);
+	if (!new) return 0;
+	memcpy(new, p, n0-OVERHEAD);
+	free(CHUNK_TO_MEM(self));
+	return new;
+}
+
+void free(void *p)
+{
+	struct chunk *self, *next;
+	size_t final_size, new_size, size;
+	int reclaim=0;
+	int i;
+
+	if (!p) return;
+
+	self = MEM_TO_CHUNK(p);
+
+	if (IS_MMAPPED(self)) {
+		size_t extra = self->psize;
+		char *base = (char *)self - extra;
+		size_t len = CHUNK_SIZE(self) + extra;
+		/* Crash on double free */
+		if (extra & 1) a_crash();
+		__munmap(base, len);
+		return;
+	}
+
+	final_size = new_size = CHUNK_SIZE(self);
+	next = NEXT_CHUNK(self);
+
+	/* Crash on corrupted footer (likely from buffer overflow) */
+	if (next->psize != self->csize) a_crash();
+
+	for (;;) {
+		if (self->psize & next->csize & C_INUSE) {
+			self->csize = final_size | C_INUSE;
+			next->psize = final_size | C_INUSE;
+			i = bin_index(final_size);
+			lock_bin(i);
+			lock(mal.free_lock);
+			if (self->psize & next->csize & C_INUSE)
+				break;
+			unlock(mal.free_lock);
+			unlock_bin(i);
+		}
+
+		if (alloc_rev(self)) {
+			self = PREV_CHUNK(self);
+			size = CHUNK_SIZE(self);
+			final_size += size;
+			if (new_size+size > RECLAIM && (new_size+size^size) > size)
+				reclaim = 1;
+		}
+
+		if (alloc_fwd(next)) {
+			size = CHUNK_SIZE(next);
+			final_size += size;
+			if (new_size+size > RECLAIM && (new_size+size^size) > size)
+				reclaim = 1;
+			next = NEXT_CHUNK(next);
+		}
+	}
+
+	if (!(mal.binmap & 1ULL<<i))
+		a_or_64(&mal.binmap, 1ULL<<i);
+
+	self->csize = final_size;
+	next->psize = final_size;
+	unlock(mal.free_lock);
+
+	self->next = BIN_TO_CHUNK(i);
+	self->prev = mal.bins[i].tail;
+	self->next->prev = self;
+	self->prev->next = self;
+
+	/* Replace middle of large chunks with fresh zero pages */
+	if (reclaim) {
+		uintptr_t a = (uintptr_t)self + SIZE_ALIGN+PAGE_SIZE-1 & -PAGE_SIZE;
+		uintptr_t b = (uintptr_t)next - SIZE_ALIGN & -PAGE_SIZE;
+#if 1
+		__madvise((void *)a, b-a, MADV_DONTNEED);
+#else
+		__mmap((void *)a, b-a, PROT_READ|PROT_WRITE,
+			MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
+#endif
+	}
+
+	unlock_bin(i);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/malloc_usable_size.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/malloc_usable_size.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/malloc_usable_size.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <malloc.h>
+
+void *(*const __realloc_dep)(void *, size_t) = realloc;
+
+struct chunk {
+	size_t psize, csize;
+	struct chunk *next, *prev;
+};
+
+#define OVERHEAD (2*sizeof(size_t))
+#define CHUNK_SIZE(c) ((c)->csize & -2)
+#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD)
+
+size_t malloc_usable_size(void *p)
+{
+	return p ? CHUNK_SIZE(MEM_TO_CHUNK(p)) - OVERHEAD : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/memalign.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/memalign.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/memalign.c	(revision 398)
@@ -0,0 +1,57 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include "libc.h"
+
+/* This function should work with most dlmalloc-like chunk bookkeeping
+ * systems, but it's only guaranteed to work with the native implementation
+ * used in this library. */
+
+void *__memalign(size_t align, size_t len)
+{
+	unsigned char *mem, *new, *end;
+	size_t header, footer;
+
+	if ((align & -align) != align) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	if (len > SIZE_MAX - align) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	if (align <= 4*sizeof(size_t)) {
+		if (!(mem = malloc(len)))
+			return NULL;
+		return mem;
+	}
+
+	if (!(mem = malloc(len + align-1)))
+		return NULL;
+
+	new = (void *)((uintptr_t)mem + align-1 & -align);
+	if (new == mem) return mem;
+
+	header = ((size_t *)mem)[-1];
+
+	if (!(header & 7)) {
+		((size_t *)new)[-2] = ((size_t *)mem)[-2] + (new-mem);
+		((size_t *)new)[-1] = ((size_t *)mem)[-1] - (new-mem);
+		return new;
+	}
+
+	end = mem + (header & -8);
+	footer = ((size_t *)end)[-2];
+
+	((size_t *)mem)[-1] = (header&7) | new-mem;
+	((size_t *)new)[-2] = (footer&7) | new-mem;
+	((size_t *)new)[-1] = (header&7) | end-new;
+	((size_t *)end)[-2] = (footer&7) | end-new;
+
+	free(mem);
+	return new;
+}
+
+weak_alias(__memalign, memalign);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/posix_memalign.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/posix_memalign.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/malloc/posix_memalign.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <errno.h>
+
+void *__memalign(size_t, size_t);
+
+int posix_memalign(void **res, size_t align, size_t len)
+{
+	if (align < sizeof(void *)) return EINVAL;
+	void *mem = __memalign(align, len);
+	if (!mem) return errno;
+	*res = mem;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__cos.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__cos.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__cos.c	(revision 398)
@@ -0,0 +1,71 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * __cos( x,  y )
+ * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ *
+ * Algorithm
+ *      1. Since cos(-x) = cos(x), we need only to consider positive x.
+ *      2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
+ *      3. cos(x) is approximated by a polynomial of degree 14 on
+ *         [0,pi/4]
+ *                                       4            14
+ *              cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
+ *         where the remez error is
+ *
+ *      |              2     4     6     8     10    12     14 |     -58
+ *      |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  )| <= 2
+ *      |                                                      |
+ *
+ *                     4     6     8     10    12     14
+ *      4. let r = C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  , then
+ *             cos(x) ~ 1 - x*x/2 + r
+ *         since cos(x+y) ~ cos(x) - sin(x)*y
+ *                        ~ cos(x) - x*y,
+ *         a correction term is necessary in cos(x) and hence
+ *              cos(x+y) = 1 - (x*x/2 - (r - x*y))
+ *         For better accuracy, rearrange to
+ *              cos(x+y) ~ w + (tmp + (r-x*y))
+ *         where w = 1 - x*x/2 and tmp is a tiny correction term
+ *         (1 - x*x/2 == w + tmp exactly in infinite precision).
+ *         The exactness of w + tmp in infinite precision depends on w
+ *         and tmp having the same precision as x.  If they have extra
+ *         precision due to compiler bugs, then the extra precision is
+ *         only good provided it is retained in all terms of the final
+ *         expression for cos().  Retention happens in all cases tested
+ *         under FreeBSD, so don't pessimize things by forcibly clipping
+ *         any extra precision in w.
+ */
+
+#include "libm.h"
+
+static const double
+C1  =  4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
+C2  = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
+C3  =  2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
+C4  = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
+C5  =  2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
+C6  = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
+
+double __cos(double x, double y)
+{
+	double_t hz,z,r,w;
+
+	z  = x*x;
+	w  = z*z;
+	r  = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6));
+	hz = 0.5*z;
+	w  = 1.0-hz;
+	return w + (((1.0-w)-hz) + (z*r-x*y));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__cosdf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__cosdf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__cosdf.c	(revision 398)
@@ -0,0 +1,35 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Debugged and optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
+static const double
+C0  = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */
+C1  =  0x155553e1053a42.0p-57, /*  0.0416666233237390631894 */
+C2  = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
+C3  =  0x199342e0ee5069.0p-68; /*  0.0000243904487962774090654 */
+
+float __cosdf(double x)
+{
+	double_t r, w, z;
+
+	/* Try to optimize for parallel evaluation as in __tandf.c. */
+	z = x*x;
+	w = z*z;
+	r = C2+z*C3;
+	return ((1.0+z*C0) + w*C1) + (w*z)*r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__cosl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__cosl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__cosl.c	(revision 398)
@@ -0,0 +1,96 @@
+/* origin: FreeBSD /usr/src/lib/msun/ld80/k_cosl.c */
+/* origin: FreeBSD /usr/src/lib/msun/ld128/k_cosl.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+
+#include "libm.h"
+
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#if LDBL_MANT_DIG == 64
+/*
+ * ld80 version of __cos.c.  See __cos.c for most comments.
+ */
+/*
+ * Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]:
+ * |cos(x) - c(x)| < 2**-75.1
+ *
+ * The coefficients of c(x) were generated by a pari-gp script using
+ * a Remez algorithm that searches for the best higher coefficients
+ * after rounding leading coefficients to a specified precision.
+ *
+ * Simpler methods like Chebyshev or basic Remez barely suffice for
+ * cos() in 64-bit precision, because we want the coefficient of x^2
+ * to be precisely -0.5 so that multiplying by it is exact, and plain
+ * rounding of the coefficients of a good polynomial approximation only
+ * gives this up to about 64-bit precision.  Plain rounding also gives
+ * a mediocre approximation for the coefficient of x^4, but a rounding
+ * error of 0.5 ulps for this coefficient would only contribute ~0.01
+ * ulps to the final error, so this is unimportant.  Rounding errors in
+ * higher coefficients are even less important.
+ *
+ * In fact, coefficients above the x^4 one only need to have 53-bit
+ * precision, and this is more efficient.  We get this optimization
+ * almost for free from the complications needed to search for the best
+ * higher coefficients.
+ */
+static const long double
+C1 =  0.0416666666666666666136L;        /*  0xaaaaaaaaaaaaaa9b.0p-68 */
+static const double
+C2 = -0.0013888888888888874,            /* -0x16c16c16c16c10.0p-62 */
+C3 =  0.000024801587301571716,          /*  0x1a01a01a018e22.0p-68 */
+C4 = -0.00000027557319215507120,        /* -0x127e4fb7602f22.0p-74 */
+C5 =  0.0000000020876754400407278,      /*  0x11eed8caaeccf1.0p-81 */
+C6 = -1.1470297442401303e-11,           /* -0x19393412bd1529.0p-89 */
+C7 =  4.7383039476436467e-14;           /*  0x1aac9d9af5c43e.0p-97 */
+#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))))
+#elif LDBL_MANT_DIG == 113
+/*
+ * ld128 version of __cos.c.  See __cos.c for most comments.
+ */
+/*
+ * Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]:
+ * |cos(x) - c(x))| < 2**-122.0
+ *
+ * 113-bit precision requires more care than 64-bit precision, since
+ * simple methods give a minimax polynomial with coefficient for x^2
+ * that is 1 ulp below 0.5, but we want it to be precisely 0.5.  See
+ * above for more details.
+ */
+static const long double
+C1 =  0.04166666666666666666666666666666658424671L,
+C2 = -0.001388888888888888888888888888863490893732L,
+C3 =  0.00002480158730158730158730158600795304914210L,
+C4 = -0.2755731922398589065255474947078934284324e-6L,
+C5 =  0.2087675698786809897659225313136400793948e-8L,
+C6 = -0.1147074559772972315817149986812031204775e-10L,
+C7 =  0.4779477332386808976875457937252120293400e-13L;
+static const double
+C8 = -0.1561920696721507929516718307820958119868e-15,
+C9 =  0.4110317413744594971475941557607804508039e-18,
+C10 = -0.8896592467191938803288521958313920156409e-21,
+C11 =  0.1601061435794535138244346256065192782581e-23;
+#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ \
+	z*(C8+z*(C9+z*(C10+z*C11)))))))))))
+#endif
+
+long double __cosl(long double x, long double y)
+{
+	long double hz,z,r,w;
+
+	z  = x*x;
+	r  = POLY(z);
+	hz = 0.5*z;
+	w  = 1.0-hz;
+	return w + (((1.0-w)-hz) + (z*r-x*y));
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__expo2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__expo2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__expo2.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "libm.h"
+
+/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */
+static const int k = 2043;
+static const double kln2 = 0x1.62066151add8bp+10;
+
+/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */
+double __expo2(double x)
+{
+	double scale;
+
+	/* note that k is odd and scale*scale overflows */
+	INSERT_WORDS(scale, (uint32_t)(0x3ff + k/2) << 20, 0);
+	/* exp(x - k ln2) * 2**(k-1) */
+	return exp(x - kln2) * scale * scale;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__expo2f.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__expo2f.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__expo2f.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "libm.h"
+
+/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */
+static const int k = 235;
+static const float kln2 = 0x1.45c778p+7f;
+
+/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */
+float __expo2f(float x)
+{
+	float scale;
+
+	/* note that k is odd and scale*scale overflows */
+	SET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23);
+	/* exp(x - k ln2) * 2**(k-1) */
+	return expf(x - kln2) * scale * scale;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__fpclassify.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__fpclassify.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__fpclassify.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <math.h>
+#include <stdint.h>
+
+int __fpclassify(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i>>52 & 0x7ff;
+	if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
+	if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
+	return FP_NORMAL;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__fpclassifyf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__fpclassifyf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__fpclassifyf.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <math.h>
+#include <stdint.h>
+
+int __fpclassifyf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = u.i>>23 & 0xff;
+	if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
+	if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
+	return FP_NORMAL;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__fpclassifyl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__fpclassifyl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__fpclassifyl.c	(revision 398)
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+int __fpclassifyl(long double x)
+{
+	return __fpclassify(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+int __fpclassifyl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	int msb = u.i.m>>63;
+	if (!e && !msb)
+		return u.i.m ? FP_SUBNORMAL : FP_ZERO;
+	if (!msb)
+		return FP_NAN;
+	if (e == 0x7fff)
+		return u.i.m << 1 ? FP_NAN : FP_INFINITE;
+	return FP_NORMAL;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+int __fpclassifyl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	u.i.se = 0;
+	if (!e)
+		return u.i2.lo | u.i2.hi ? FP_SUBNORMAL : FP_ZERO;
+	if (e == 0x7fff)
+		return u.i2.lo | u.i2.hi ? FP_NAN : FP_INFINITE;
+	return FP_NORMAL;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__invtrigl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__invtrigl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__invtrigl.c	(revision 398)
@@ -0,0 +1,63 @@
+#include <float.h>
+#include "__invtrigl.h"
+
+#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+static const long double
+pS0 =  1.66666666666666666631e-01L,
+pS1 = -4.16313987993683104320e-01L,
+pS2 =  3.69068046323246813704e-01L,
+pS3 = -1.36213932016738603108e-01L,
+pS4 =  1.78324189708471965733e-02L,
+pS5 = -2.19216428382605211588e-04L,
+pS6 = -7.10526623669075243183e-06L,
+qS1 = -2.94788392796209867269e+00L,
+qS2 =  3.27309890266528636716e+00L,
+qS3 = -1.68285799854822427013e+00L,
+qS4 =  3.90699412641738801874e-01L,
+qS5 = -3.14365703596053263322e-02L;
+
+const long double pio2_hi = 1.57079632679489661926L;
+const long double pio2_lo = -2.50827880633416601173e-20L;
+
+/* used in asinl() and acosl() */
+/* R(x^2) is a rational approximation of (asin(x)-x)/x^3 with Remez algorithm */
+long double __invtrigl_R(long double z)
+{
+	long double p, q;
+	p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*pS6))))));
+	q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*qS5))));
+	return p/q;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+static const long double
+pS0 =  1.66666666666666666666666666666700314e-01L,
+pS1 = -7.32816946414566252574527475428622708e-01L,
+pS2 =  1.34215708714992334609030036562143589e+00L,
+pS3 = -1.32483151677116409805070261790752040e+00L,
+pS4 =  7.61206183613632558824485341162121989e-01L,
+pS5 = -2.56165783329023486777386833928147375e-01L,
+pS6 =  4.80718586374448793411019434585413855e-02L,
+pS7 = -4.42523267167024279410230886239774718e-03L,
+pS8 =  1.44551535183911458253205638280410064e-04L,
+pS9 = -2.10558957916600254061591040482706179e-07L,
+qS1 = -4.84690167848739751544716485245697428e+00L,
+qS2 =  9.96619113536172610135016921140206980e+00L,
+qS3 = -1.13177895428973036660836798461641458e+01L,
+qS4 =  7.74004374389488266169304117714658761e+00L,
+qS5 = -3.25871986053534084709023539900339905e+00L,
+qS6 =  8.27830318881232209752469022352928864e-01L,
+qS7 = -1.18768052702942805423330715206348004e-01L,
+qS8 =  8.32600764660522313269101537926539470e-03L,
+qS9 = -1.99407384882605586705979504567947007e-04L;
+
+const long double pio2_hi = 1.57079632679489661923132169163975140L;
+const long double pio2_lo = 4.33590506506189051239852201302167613e-35L;
+
+long double __invtrigl_R(long double z)
+{
+	long double p, q;
+	p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*(pS6+z*(pS7+z*(pS8+z*pS9)))))))));
+	q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*(qS5+z*(qS6+z*(qS7+z*(qS8+z*qS9))))))));
+	return p/q;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__invtrigl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__invtrigl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__invtrigl.h	(revision 398)
@@ -0,0 +1,6 @@
+/* shared by acosl, asinl and atan2l */
+#define pio2_hi __pio2_hi
+#define pio2_lo __pio2_lo
+extern const long double pio2_hi, pio2_lo;
+
+long double __invtrigl_R(long double z);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__polevll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__polevll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__polevll.c	(revision 398)
@@ -0,0 +1,93 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/polevll.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Evaluate polynomial
+ *
+ *
+ * SYNOPSIS:
+ *
+ * int N;
+ * long double x, y, coef[N+1], polevl[];
+ *
+ * y = polevll( x, coef, N );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Evaluates polynomial of degree N:
+ *
+ *                     2          N
+ * y  =  C  + C x + C x  +...+ C x
+ *        0    1     2          N
+ *
+ * Coefficients are stored in reverse order:
+ *
+ * coef[0] = C  , ..., coef[N] = C  .
+ *            N                   0
+ *
+ *  The function p1evll() assumes that coef[N] = 1.0 and is
+ * omitted from the array.  Its calling arguments are
+ * otherwise the same as polevll().
+ *
+ *
+ * SPEED:
+ *
+ * In the interest of speed, there are no checks for out
+ * of bounds arithmetic.  This routine is used by most of
+ * the functions in the library.  Depending on available
+ * equipment features, the user may wish to rewrite the
+ * program in microcode or assembly language.
+ *
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+#else
+/*
+ * Polynomial evaluator:
+ *  P[0] x^n  +  P[1] x^(n-1)  +  ...  +  P[n]
+ */
+long double __polevll(long double x, const long double *P, int n)
+{
+	long double y;
+
+	y = *P++;
+	do {
+		y = y * x + *P++;
+	} while (--n);
+
+	return y;
+}
+
+/*
+ * Polynomial evaluator:
+ *  x^n  +  P[0] x^(n-1)  +  P[1] x^(n-2)  +  ...  +  P[n]
+ */
+long double __p1evll(long double x, const long double *P, int n)
+{
+	long double y;
+
+	n -= 1;
+	y = x + *P++;
+	do {
+		y = y * x + *P++;
+	} while (--n);
+
+	return y;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2.c	(revision 398)
@@ -0,0 +1,177 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ * Optimized by Bruce D. Evans.
+ */
+/* __rem_pio2(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __rem_pio2_large() for large x
+ */
+
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+
+/*
+ * invpio2:  53 bits of 2/pi
+ * pio2_1:   first  33 bit of pi/2
+ * pio2_1t:  pi/2 - pio2_1
+ * pio2_2:   second 33 bit of pi/2
+ * pio2_2t:  pi/2 - (pio2_1+pio2_2)
+ * pio2_3:   third  33 bit of pi/2
+ * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+static const double
+toint   = 1.5/EPS,
+invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+pio2_1  = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
+pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
+pio2_2  = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
+pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
+pio2_3  = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
+pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
+
+/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */
+int __rem_pio2(double x, double *y)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t z,w,t,r,fn;
+	double tx[3],ty[2];
+	uint32_t ix;
+	int sign, n, ex, ey, i;
+
+	sign = u.i>>63;
+	ix = u.i>>32 & 0x7fffffff;
+	if (ix <= 0x400f6a7a) {  /* |x| ~<= 5pi/4 */
+		if ((ix & 0xfffff) == 0x921fb)  /* |x| ~= pi/2 or 2pi/2 */
+			goto medium;  /* cancellation -- use medium case */
+		if (ix <= 0x4002d97c) {  /* |x| ~<= 3pi/4 */
+			if (!sign) {
+				z = x - pio2_1;  /* one round good to 85 bits */
+				y[0] = z - pio2_1t;
+				y[1] = (z-y[0]) - pio2_1t;
+				return 1;
+			} else {
+				z = x + pio2_1;
+				y[0] = z + pio2_1t;
+				y[1] = (z-y[0]) + pio2_1t;
+				return -1;
+			}
+		} else {
+			if (!sign) {
+				z = x - 2*pio2_1;
+				y[0] = z - 2*pio2_1t;
+				y[1] = (z-y[0]) - 2*pio2_1t;
+				return 2;
+			} else {
+				z = x + 2*pio2_1;
+				y[0] = z + 2*pio2_1t;
+				y[1] = (z-y[0]) + 2*pio2_1t;
+				return -2;
+			}
+		}
+	}
+	if (ix <= 0x401c463b) {  /* |x| ~<= 9pi/4 */
+		if (ix <= 0x4015fdbc) {  /* |x| ~<= 7pi/4 */
+			if (ix == 0x4012d97c)  /* |x| ~= 3pi/2 */
+				goto medium;
+			if (!sign) {
+				z = x - 3*pio2_1;
+				y[0] = z - 3*pio2_1t;
+				y[1] = (z-y[0]) - 3*pio2_1t;
+				return 3;
+			} else {
+				z = x + 3*pio2_1;
+				y[0] = z + 3*pio2_1t;
+				y[1] = (z-y[0]) + 3*pio2_1t;
+				return -3;
+			}
+		} else {
+			if (ix == 0x401921fb)  /* |x| ~= 4pi/2 */
+				goto medium;
+			if (!sign) {
+				z = x - 4*pio2_1;
+				y[0] = z - 4*pio2_1t;
+				y[1] = (z-y[0]) - 4*pio2_1t;
+				return 4;
+			} else {
+				z = x + 4*pio2_1;
+				y[0] = z + 4*pio2_1t;
+				y[1] = (z-y[0]) + 4*pio2_1t;
+				return -4;
+			}
+		}
+	}
+	if (ix < 0x413921fb) {  /* |x| ~< 2^20*(pi/2), medium size */
+medium:
+		/* rint(x/(pi/2)), Assume round-to-nearest. */
+		fn = (double_t)x*invpio2 + toint - toint;
+		n = (int32_t)fn;
+		r = x - fn*pio2_1;
+		w = fn*pio2_1t;  /* 1st round, good to 85 bits */
+		y[0] = r - w;
+		u.f = y[0];
+		ey = u.i>>52 & 0x7ff;
+		ex = ix>>20;
+		if (ex - ey > 16) { /* 2nd round, good to 118 bits */
+			t = r;
+			w = fn*pio2_2;
+			r = t - w;
+			w = fn*pio2_2t - ((t-r)-w);
+			y[0] = r - w;
+			u.f = y[0];
+			ey = u.i>>52 & 0x7ff;
+			if (ex - ey > 49) {  /* 3rd round, good to 151 bits, covers all cases */
+				t = r;
+				w = fn*pio2_3;
+				r = t - w;
+				w = fn*pio2_3t - ((t-r)-w);
+				y[0] = r - w;
+			}
+		}
+		y[1] = (r - y[0]) - w;
+		return n;
+	}
+	/*
+	 * all other (large) arguments
+	 */
+	if (ix >= 0x7ff00000) {  /* x is inf or NaN */
+		y[0] = y[1] = x - x;
+		return 0;
+	}
+	/* set z = scalbn(|x|,-ilogb(x)+23) */
+	u.f = x;
+	u.i &= (uint64_t)-1>>12;
+	u.i |= (uint64_t)(0x3ff + 23)<<52;
+	z = u.f;
+	for (i=0; i < 2; i++) {
+		tx[i] = (double)(int32_t)z;
+		z     = (z-tx[i])*0x1p24;
+	}
+	tx[i] = z;
+	/* skip zero terms, first term is non-zero */
+	while (tx[i] == 0.0)
+		i--;
+	n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1);
+	if (sign) {
+		y[0] = -ty[0];
+		y[1] = -ty[1];
+		return -n;
+	}
+	y[0] = ty[0];
+	y[1] = ty[1];
+	return n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2_large.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2_large.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2_large.c	(revision 398)
@@ -0,0 +1,442 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_rem_pio2.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * __rem_pio2_large(x,y,e0,nx,prec)
+ * double x[],y[]; int e0,nx,prec;
+ *
+ * __rem_pio2_large return the last three digits of N with
+ *              y = x - N*pi/2
+ * so that |y| < pi/2.
+ *
+ * The method is to compute the integer (mod 8) and fraction parts of
+ * (2/pi)*x without doing the full multiplication. In general we
+ * skip the part of the product that are known to be a huge integer (
+ * more accurately, = 0 mod 8 ). Thus the number of operations are
+ * independent of the exponent of the input.
+ *
+ * (2/pi) is represented by an array of 24-bit integers in ipio2[].
+ *
+ * Input parameters:
+ *      x[]     The input value (must be positive) is broken into nx
+ *              pieces of 24-bit integers in double precision format.
+ *              x[i] will be the i-th 24 bit of x. The scaled exponent
+ *              of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
+ *              match x's up to 24 bits.
+ *
+ *              Example of breaking a double positive z into x[0]+x[1]+x[2]:
+ *                      e0 = ilogb(z)-23
+ *                      z  = scalbn(z,-e0)
+ *              for i = 0,1,2
+ *                      x[i] = floor(z)
+ *                      z    = (z-x[i])*2**24
+ *
+ *
+ *      y[]     ouput result in an array of double precision numbers.
+ *              The dimension of y[] is:
+ *                      24-bit  precision       1
+ *                      53-bit  precision       2
+ *                      64-bit  precision       2
+ *                      113-bit precision       3
+ *              The actual value is the sum of them. Thus for 113-bit
+ *              precison, one may have to do something like:
+ *
+ *              long double t,w,r_head, r_tail;
+ *              t = (long double)y[2] + (long double)y[1];
+ *              w = (long double)y[0];
+ *              r_head = t+w;
+ *              r_tail = w - (r_head - t);
+ *
+ *      e0      The exponent of x[0]. Must be <= 16360 or you need to
+ *              expand the ipio2 table.
+ *
+ *      nx      dimension of x[]
+ *
+ *      prec    an integer indicating the precision:
+ *                      0       24  bits (single)
+ *                      1       53  bits (double)
+ *                      2       64  bits (extended)
+ *                      3       113 bits (quad)
+ *
+ * External function:
+ *      double scalbn(), floor();
+ *
+ *
+ * Here is the description of some local variables:
+ *
+ *      jk      jk+1 is the initial number of terms of ipio2[] needed
+ *              in the computation. The minimum and recommended value
+ *              for jk is 3,4,4,6 for single, double, extended, and quad.
+ *              jk+1 must be 2 larger than you might expect so that our
+ *              recomputation test works. (Up to 24 bits in the integer
+ *              part (the 24 bits of it that we compute) and 23 bits in
+ *              the fraction part may be lost to cancelation before we
+ *              recompute.)
+ *
+ *      jz      local integer variable indicating the number of
+ *              terms of ipio2[] used.
+ *
+ *      jx      nx - 1
+ *
+ *      jv      index for pointing to the suitable ipio2[] for the
+ *              computation. In general, we want
+ *                      ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
+ *              is an integer. Thus
+ *                      e0-3-24*jv >= 0 or (e0-3)/24 >= jv
+ *              Hence jv = max(0,(e0-3)/24).
+ *
+ *      jp      jp+1 is the number of terms in PIo2[] needed, jp = jk.
+ *
+ *      q[]     double array with integral value, representing the
+ *              24-bits chunk of the product of x and 2/pi.
+ *
+ *      q0      the corresponding exponent of q[0]. Note that the
+ *              exponent for q[i] would be q0-24*i.
+ *
+ *      PIo2[]  double precision array, obtained by cutting pi/2
+ *              into 24 bits chunks.
+ *
+ *      f[]     ipio2[] in floating point
+ *
+ *      iq[]    integer array by breaking up q[] in 24-bits chunk.
+ *
+ *      fq[]    final product of x*(2/pi) in fq[0],..,fq[jk]
+ *
+ *      ih      integer. If >0 it indicates q[] is >= 0.5, hence
+ *              it also indicates the *sign* of the result.
+ *
+ */
+/*
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "libm.h"
+
+static const int init_jk[] = {3,4,4,6}; /* initial value for jk */
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
+ *
+ *              integer array, contains the (24*i)-th to (24*i+23)-th
+ *              bit of 2/pi after binary point. The corresponding
+ *              floating value is
+ *
+ *                      ipio2[i] * 2^(-24(i+1)).
+ *
+ * NB: This table must have at least (e0-3)/24 + jk terms.
+ *     For quad precision (e0 <= 16360, jk = 6), this is 686.
+ */
+static const int32_t ipio2[] = {
+0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
+0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
+0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
+0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
+0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
+0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
+0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
+0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
+0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
+0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
+0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
+
+#if LDBL_MAX_EXP > 1024
+0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6,
+0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2,
+0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35,
+0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30,
+0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C,
+0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4,
+0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770,
+0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7,
+0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19,
+0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522,
+0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16,
+0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6,
+0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E,
+0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48,
+0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3,
+0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF,
+0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55,
+0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612,
+0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929,
+0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC,
+0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B,
+0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C,
+0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4,
+0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB,
+0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC,
+0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C,
+0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F,
+0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5,
+0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437,
+0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B,
+0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA,
+0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD,
+0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3,
+0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3,
+0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717,
+0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F,
+0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61,
+0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB,
+0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51,
+0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0,
+0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C,
+0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6,
+0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC,
+0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED,
+0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328,
+0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D,
+0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0,
+0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B,
+0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4,
+0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3,
+0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F,
+0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD,
+0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B,
+0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4,
+0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761,
+0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31,
+0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30,
+0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262,
+0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E,
+0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1,
+0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C,
+0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4,
+0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08,
+0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196,
+0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9,
+0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4,
+0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC,
+0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C,
+0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0,
+0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C,
+0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0,
+0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC,
+0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22,
+0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893,
+0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7,
+0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5,
+0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F,
+0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4,
+0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF,
+0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B,
+0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2,
+0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138,
+0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E,
+0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569,
+0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34,
+0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9,
+0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D,
+0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F,
+0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855,
+0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569,
+0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B,
+0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE,
+0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41,
+0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49,
+0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F,
+0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110,
+0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8,
+0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365,
+0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A,
+0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270,
+0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5,
+0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616,
+0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B,
+0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0,
+#endif
+};
+
+static const double PIo2[] = {
+  1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
+  7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
+  5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
+  3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
+  1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
+  1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
+  2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
+  2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
+};
+
+int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec)
+{
+	int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+	double z,fw,f[20],fq[20],q[20];
+
+	/* initialize jk*/
+	jk = init_jk[prec];
+	jp = jk;
+
+	/* determine jx,jv,q0, note that 3>q0 */
+	jx = nx-1;
+	jv = (e0-3)/24;  if(jv<0) jv=0;
+	q0 = e0-24*(jv+1);
+
+	/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
+	j = jv-jx; m = jx+jk;
+	for (i=0; i<=m; i++,j++)
+		f[i] = j<0 ? 0.0 : (double)ipio2[j];
+
+	/* compute q[0],q[1],...q[jk] */
+	for (i=0; i<=jk; i++) {
+		for (j=0,fw=0.0; j<=jx; j++)
+			fw += x[j]*f[jx+i-j];
+		q[i] = fw;
+	}
+
+	jz = jk;
+recompute:
+	/* distill q[] into iq[] reversingly */
+	for (i=0,j=jz,z=q[jz]; j>0; i++,j--) {
+		fw    = (double)(int32_t)(0x1p-24*z);
+		iq[i] = (int32_t)(z - 0x1p24*fw);
+		z     = q[j-1]+fw;
+	}
+
+	/* compute n */
+	z  = scalbn(z,q0);       /* actual value of z */
+	z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
+	n  = (int32_t)z;
+	z -= (double)n;
+	ih = 0;
+	if (q0 > 0) {  /* need iq[jz-1] to determine n */
+		i  = iq[jz-1]>>(24-q0); n += i;
+		iq[jz-1] -= i<<(24-q0);
+		ih = iq[jz-1]>>(23-q0);
+	}
+	else if (q0 == 0) ih = iq[jz-1]>>23;
+	else if (z >= 0.5) ih = 2;
+
+	if (ih > 0) {  /* q > 0.5 */
+		n += 1; carry = 0;
+		for (i=0; i<jz; i++) {  /* compute 1-q */
+			j = iq[i];
+			if (carry == 0) {
+				if (j != 0) {
+					carry = 1;
+					iq[i] = 0x1000000 - j;
+				}
+			} else
+				iq[i] = 0xffffff - j;
+		}
+		if (q0 > 0) {  /* rare case: chance is 1 in 12 */
+			switch(q0) {
+			case 1:
+				iq[jz-1] &= 0x7fffff; break;
+			case 2:
+				iq[jz-1] &= 0x3fffff; break;
+			}
+		}
+		if (ih == 2) {
+			z = 1.0 - z;
+			if (carry != 0)
+				z -= scalbn(1.0,q0);
+		}
+	}
+
+	/* check if recomputation is needed */
+	if (z == 0.0) {
+		j = 0;
+		for (i=jz-1; i>=jk; i--) j |= iq[i];
+		if (j == 0) {  /* need recomputation */
+			for (k=1; iq[jk-k]==0; k++);  /* k = no. of terms needed */
+
+			for (i=jz+1; i<=jz+k; i++) {  /* add q[jz+1] to q[jz+k] */
+				f[jx+i] = (double)ipio2[jv+i];
+				for (j=0,fw=0.0; j<=jx; j++)
+					fw += x[j]*f[jx+i-j];
+				q[i] = fw;
+			}
+			jz += k;
+			goto recompute;
+		}
+	}
+
+	/* chop off zero terms */
+	if (z == 0.0) {
+		jz -= 1;
+		q0 -= 24;
+		while (iq[jz] == 0) {
+			jz--;
+			q0 -= 24;
+		}
+	} else { /* break z into 24-bit if necessary */
+		z = scalbn(z,-q0);
+		if (z >= 0x1p24) {
+			fw = (double)(int32_t)(0x1p-24*z);
+			iq[jz] = (int32_t)(z - 0x1p24*fw);
+			jz += 1;
+			q0 += 24;
+			iq[jz] = (int32_t)fw;
+		} else
+			iq[jz] = (int32_t)z;
+	}
+
+	/* convert integer "bit" chunk to floating-point value */
+	fw = scalbn(1.0,q0);
+	for (i=jz; i>=0; i--) {
+		q[i] = fw*(double)iq[i];
+		fw *= 0x1p-24;
+	}
+
+	/* compute PIo2[0,...,jp]*q[jz,...,0] */
+	for(i=jz; i>=0; i--) {
+		for (fw=0.0,k=0; k<=jp && k<=jz-i; k++)
+			fw += PIo2[k]*q[i+k];
+		fq[jz-i] = fw;
+	}
+
+	/* compress fq[] into y[] */
+	switch(prec) {
+	case 0:
+		fw = 0.0;
+		for (i=jz; i>=0; i--)
+			fw += fq[i];
+		y[0] = ih==0 ? fw : -fw;
+		break;
+	case 1:
+	case 2:
+		fw = 0.0;
+		for (i=jz; i>=0; i--)
+			fw += fq[i];
+		// TODO: drop excess precision here once double_t is used
+		fw = (double)fw;
+		y[0] = ih==0 ? fw : -fw;
+		fw = fq[0]-fw;
+		for (i=1; i<=jz; i++)
+			fw += fq[i];
+		y[1] = ih==0 ? fw : -fw;
+		break;
+	case 3:  /* painful */
+		for (i=jz; i>0; i--) {
+			fw      = fq[i-1]+fq[i];
+			fq[i]  += fq[i-1]-fw;
+			fq[i-1] = fw;
+		}
+		for (i=jz; i>1; i--) {
+			fw      = fq[i-1]+fq[i];
+			fq[i]  += fq[i-1]-fw;
+			fq[i-1] = fw;
+		}
+		for (fw=0.0,i=jz; i>=2; i--)
+			fw += fq[i];
+		if (ih==0) {
+			y[0] =  fq[0]; y[1] =  fq[1]; y[2] =  fw;
+		} else {
+			y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
+		}
+	}
+	return n&7;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2f.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2f.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2f.c	(revision 398)
@@ -0,0 +1,75 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2f.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Debugged and optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* __rem_pio2f(x,y)
+ *
+ * return the remainder of x rem pi/2 in *y
+ * use double precision for everything except passing x
+ * use __rem_pio2_large() for large x
+ */
+
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+
+/*
+ * invpio2:  53 bits of 2/pi
+ * pio2_1:   first 25 bits of pi/2
+ * pio2_1t:  pi/2 - pio2_1
+ */
+static const double
+toint   = 1.5/EPS,
+invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+pio2_1  = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */
+pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */
+
+int __rem_pio2f(float x, double *y)
+{
+	union {float f; uint32_t i;} u = {x};
+	double tx[1],ty[1];
+	double_t fn;
+	uint32_t ix;
+	int n, sign, e0;
+
+	ix = u.i & 0x7fffffff;
+	/* 25+53 bit pi is good enough for medium size */
+	if (ix < 0x4dc90fdb) {  /* |x| ~< 2^28*(pi/2), medium size */
+		/* Use a specialized rint() to get fn.  Assume round-to-nearest. */
+		fn = (double_t)x*invpio2 + toint - toint;
+		n  = (int32_t)fn;
+		*y = x - fn*pio2_1 - fn*pio2_1t;
+		return n;
+	}
+	if(ix>=0x7f800000) {  /* x is inf or NaN */
+		*y = x-x;
+		return 0;
+	}
+	/* scale x into [2^23, 2^24-1] */
+	sign = u.i>>31;
+	e0 = (ix>>23) - (0x7f+23);  /* e0 = ilogb(|x|)-23, positive */
+	u.i = ix - (e0<<23);
+	tx[0] = u.f;
+	n  =  __rem_pio2_large(tx,ty,e0,1,0);
+	if (sign) {
+		*y = -ty[0];
+		return -n;
+	}
+	*y = ty[0];
+	return n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2l.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2l.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__rem_pio2l.c	(revision 398)
@@ -0,0 +1,141 @@
+/* origin: FreeBSD /usr/src/lib/msun/ld80/e_rem_pio2.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ * Optimized by Bruce D. Evans.
+ */
+#include "libm.h"
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+/* ld80 and ld128 version of __rem_pio2(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __rem_pio2_large() for large x
+ */
+
+static const long double toint = 1.5/LDBL_EPSILON;
+
+#if LDBL_MANT_DIG == 64
+/* u ~< 0x1p25*pi/2 */
+#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.m>>48) < ((0x3fff + 25)<<16 | 0x921f>>1 | 0x8000))
+#define QUOBITS(x) ((uint32_t)(int32_t)x & 0x7fffffff)
+#define ROUND1 22
+#define ROUND2 61
+#define NX 3
+#define NY 2
+/*
+ * invpio2:  64 bits of 2/pi
+ * pio2_1:   first  39 bits of pi/2
+ * pio2_1t:  pi/2 - pio2_1
+ * pio2_2:   second 39 bits of pi/2
+ * pio2_2t:  pi/2 - (pio2_1+pio2_2)
+ * pio2_3:   third  39 bits of pi/2
+ * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+static const double
+pio2_1 =  1.57079632679597125389e+00, /* 0x3FF921FB, 0x54444000 */
+pio2_2 = -1.07463465549783099519e-12, /* -0x12e7b967674000.0p-92 */
+pio2_3 =  6.36831716351370313614e-25; /*  0x18a2e037074000.0p-133 */
+static const long double
+invpio2 =  6.36619772367581343076e-01L, /*  0xa2f9836e4e44152a.0p-64 */
+pio2_1t = -1.07463465549719416346e-12L, /* -0x973dcb3b399d747f.0p-103 */
+pio2_2t =  6.36831716351095013979e-25L, /*  0xc51701b839a25205.0p-144 */
+pio2_3t = -2.75299651904407171810e-37L; /* -0xbb5bf6c7ddd660ce.0p-185 */
+#elif LDBL_MANT_DIG == 113
+/* u ~< 0x1p45*pi/2 */
+#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.top) < ((0x3fff + 45)<<16 | 0x921f))
+#define QUOBITS(x) ((uint32_t)(int64_t)x & 0x7fffffff)
+#define ROUND1 51
+#define ROUND2 119
+#define NX 5
+#define NY 3
+static const long double
+invpio2 =  6.3661977236758134307553505349005747e-01L,	/*  0x145f306dc9c882a53f84eafa3ea6a.0p-113 */
+pio2_1  =  1.5707963267948966192292994253909555e+00L,	/*  0x1921fb54442d18469800000000000.0p-112 */
+pio2_1t =  2.0222662487959507323996846200947577e-21L,	/*  0x13198a2e03707344a4093822299f3.0p-181 */
+pio2_2  =  2.0222662487959507323994779168837751e-21L,	/*  0x13198a2e03707344a400000000000.0p-181 */
+pio2_2t =  2.0670321098263988236496903051604844e-43L,	/*  0x127044533e63a0105df531d89cd91.0p-254 */
+pio2_3  =  2.0670321098263988236499468110329591e-43L,	/*  0x127044533e63a0105e00000000000.0p-254 */
+pio2_3t = -2.5650587247459238361625433492959285e-65L;	/* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */
+#endif
+
+int __rem_pio2l(long double x, long double *y)
+{
+	union ldshape u,uz;
+	long double z,w,t,r,fn;
+	double tx[NX],ty[NY];
+	int ex,ey,n,i;
+
+	u.f = x;
+	ex = u.i.se & 0x7fff;
+	if (SMALL(u)) {
+		/* rint(x/(pi/2)), Assume round-to-nearest. */
+		fn = x*invpio2 + toint - toint;
+		n = QUOBITS(fn);
+		r = x-fn*pio2_1;
+		w = fn*pio2_1t;  /* 1st round good to 102/180 bits (ld80/ld128) */
+		y[0] = r-w;
+		u.f = y[0];
+		ey = u.i.se & 0x7fff;
+		if (ex - ey > ROUND1) {  /* 2nd iteration needed, good to 141/248 (ld80/ld128) */
+			t = r;
+			w = fn*pio2_2;
+			r = t-w;
+			w = fn*pio2_2t-((t-r)-w);
+			y[0] = r-w;
+			u.f = y[0];
+			ey = u.i.se & 0x7fff;
+			if (ex - ey > ROUND2) {  /* 3rd iteration, good to 180/316 bits */
+				t = r; /* will cover all possible cases (not verified for ld128) */
+				w = fn*pio2_3;
+				r = t-w;
+				w = fn*pio2_3t-((t-r)-w);
+				y[0] = r-w;
+			}
+		}
+		y[1] = (r - y[0]) - w;
+		return n;
+	}
+	/*
+	 * all other (large) arguments
+	 */
+	if (ex == 0x7fff) {                /* x is inf or NaN */
+		y[0] = y[1] = x - x;
+		return 0;
+	}
+	/* set z = scalbn(|x|,-ilogb(x)+23) */
+	uz.f = x;
+	uz.i.se = 0x3fff + 23;
+	z = uz.f;
+	for (i=0; i < NX - 1; i++) {
+		tx[i] = (double)(int32_t)z;
+		z     = (z-tx[i])*0x1p24;
+	}
+	tx[i] = z;
+	while (tx[i] == 0)
+		i--;
+	n = __rem_pio2_large(tx, ty, ex-0x3fff-23, i+1, NY);
+	w = ty[1];
+	if (NY == 3)
+		w += ty[2];
+	r = ty[0] + w;
+	/* TODO: for ld128 this does not follow the recommendation of the
+	comments of __rem_pio2_large which seem wrong if |ty[0]| > |ty[1]+ty[2]| */
+	w -= r - ty[0];
+	if (u.i.se >> 15) {
+		y[0] = -r;
+		y[1] = -w;
+		return -n;
+	}
+	y[0] = r;
+	y[1] = w;
+	return n;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__signbit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__signbit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__signbit.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "libm.h"
+
+// FIXME: macro in math.h
+int __signbit(double x)
+{
+	union {
+		double d;
+		uint64_t i;
+	} y = { x };
+	return y.i>>63;
+}
+
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__signbitf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__signbitf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__signbitf.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "libm.h"
+
+// FIXME: macro in math.h
+int __signbitf(float x)
+{
+	union {
+		float f;
+		uint32_t i;
+	} y = { x };
+	return y.i>>31;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__signbitl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__signbitl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__signbitl.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "libm.h"
+
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+int __signbitl(long double x)
+{
+	union ldshape u = {x};
+	return u.i.se >> 15;
+}
+#elif LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+int __signbitl(long double x)
+{
+	return __signbit(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__sin.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__sin.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__sin.c	(revision 398)
@@ -0,0 +1,64 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_sin.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* __sin( x, y, iy)
+ * kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
+ *
+ * Algorithm
+ *      1. Since sin(-x) = -sin(x), we need only to consider positive x.
+ *      2. Callers must return sin(-0) = -0 without calling here since our
+ *         odd polynomial is not evaluated in a way that preserves -0.
+ *         Callers may do the optimization sin(x) ~ x for tiny x.
+ *      3. sin(x) is approximated by a polynomial of degree 13 on
+ *         [0,pi/4]
+ *                               3            13
+ *              sin(x) ~ x + S1*x + ... + S6*x
+ *         where
+ *
+ *      |sin(x)         2     4     6     8     10     12  |     -58
+ *      |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x  +S6*x   )| <= 2
+ *      |  x                                               |
+ *
+ *      4. sin(x+y) = sin(x) + sin'(x')*y
+ *                  ~ sin(x) + (1-x*x/2)*y
+ *         For better accuracy, let
+ *                   3      2      2      2      2
+ *              r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
+ *         then                   3    2
+ *              sin(x) = x + (S1*x + (x *(r-y/2)+y))
+ */
+
+#include "libm.h"
+
+static const double
+S1  = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
+S2  =  8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
+S3  = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
+S4  =  2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
+S5  = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
+S6  =  1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
+
+double __sin(double x, double y, int iy)
+{
+	double_t z,r,v,w;
+
+	z = x*x;
+	w = z*z;
+	r = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6);
+	v = z*x;
+	if (iy == 0)
+		return x + v*(S1 + z*r);
+	else
+		return x - ((z*(0.5*y - v*r) - y) - v*S1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__sindf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__sindf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__sindf.c	(revision 398)
@@ -0,0 +1,36 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_sinf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
+static const double
+S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
+S2 =  0x111110896efbb2.0p-59, /*  0.0083333293858894631756 */
+S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
+S4 =  0x16cd878c3b46a7.0p-71; /*  0.0000027183114939898219064 */
+
+float __sindf(double x)
+{
+	double_t r, s, w, z;
+
+	/* Try to optimize for parallel evaluation as in __tandf.c. */
+	z = x*x;
+	w = z*z;
+	r = S3 + z*S4;
+	s = z*x;
+	return (x + s*(S1 + z*S2)) + s*w*r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__sinl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__sinl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__sinl.c	(revision 398)
@@ -0,0 +1,78 @@
+/* origin: FreeBSD /usr/src/lib/msun/ld80/k_sinl.c */
+/* origin: FreeBSD /usr/src/lib/msun/ld128/k_sinl.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#if LDBL_MANT_DIG == 64
+/*
+ * ld80 version of __sin.c.  See __sin.c for most comments.
+ */
+/*
+ * Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22]
+ * |sin(x)/x - s(x)| < 2**-72.1
+ *
+ * See __cosl.c for more details about the polynomial.
+ */
+static const long double
+S1 = -0.166666666666666666671L;   /* -0xaaaaaaaaaaaaaaab.0p-66 */
+static const double
+S2 =  0.0083333333333333332,      /*  0x11111111111111.0p-59 */
+S3 = -0.00019841269841269427,     /* -0x1a01a01a019f81.0p-65 */
+S4 =  0.0000027557319223597490,   /*  0x171de3a55560f7.0p-71 */
+S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */
+S6 =  1.6059006598854211e-10,     /*  0x161242b90243b5.0p-85 */
+S7 = -7.6429779983024564e-13,     /* -0x1ae42ebd1b2e00.0p-93 */
+S8 =  2.6174587166648325e-15;     /*  0x179372ea0b3f64.0p-101 */
+#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8))))))
+#elif LDBL_MANT_DIG == 113
+/*
+ * ld128 version of __sin.c.  See __sin.c for most comments.
+ */
+/*
+ * Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37]
+ * |sin(x)/x - s(x)| < 2**-122.1
+ *
+ * See __cosl.c for more details about the polynomial.
+ */
+static const long double
+S1 = -0.16666666666666666666666666666666666606732416116558L,
+S2 =  0.0083333333333333333333333333333331135404851288270047L,
+S3 = -0.00019841269841269841269841269839935785325638310428717L,
+S4 =  0.27557319223985890652557316053039946268333231205686e-5L,
+S5 = -0.25052108385441718775048214826384312253862930064745e-7L,
+S6 =  0.16059043836821614596571832194524392581082444805729e-9L,
+S7 = -0.76471637318198151807063387954939213287488216303768e-12L,
+S8 =  0.28114572543451292625024967174638477283187397621303e-14L;
+static const double
+S9  = -0.82206352458348947812512122163446202498005154296863e-17,
+S10 =  0.19572940011906109418080609928334380560135358385256e-19,
+S11 = -0.38680813379701966970673724299207480965452616911420e-22,
+S12 =  0.64038150078671872796678569586315881020659912139412e-25;
+#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ \
+	z*(S9+z*(S10+z*(S11+z*S12))))))))))
+#endif
+
+long double __sinl(long double x, long double y, int iy)
+{
+	long double z,r,v;
+
+	z = x*x;
+	v = z*x;
+	r = POLY(z);
+	if (iy == 0)
+		return x+v*(S1+z*r);
+	return x-((z*(0.5*y-v*r)-y)-v*S1);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__tan.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__tan.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__tan.c	(revision 398)
@@ -0,0 +1,110 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_tan.c */
+/*
+ * ====================================================
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* __tan( x, y, k )
+ * kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input odd indicates whether tan (if odd = 0) or -1/tan (if odd = 1) is returned.
+ *
+ * Algorithm
+ *      1. Since tan(-x) = -tan(x), we need only to consider positive x.
+ *      2. Callers must return tan(-0) = -0 without calling here since our
+ *         odd polynomial is not evaluated in a way that preserves -0.
+ *         Callers may do the optimization tan(x) ~ x for tiny x.
+ *      3. tan(x) is approximated by a odd polynomial of degree 27 on
+ *         [0,0.67434]
+ *                               3             27
+ *              tan(x) ~ x + T1*x + ... + T13*x
+ *         where
+ *
+ *              |tan(x)         2     4            26   |     -59.2
+ *              |----- - (1+T1*x +T2*x +.... +T13*x    )| <= 2
+ *              |  x                                    |
+ *
+ *         Note: tan(x+y) = tan(x) + tan'(x)*y
+ *                        ~ tan(x) + (1+x*x)*y
+ *         Therefore, for better accuracy in computing tan(x+y), let
+ *                   3      2      2       2       2
+ *              r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
+ *         then
+ *                                  3    2
+ *              tan(x+y) = x + (T1*x + (x *(r+y)+y))
+ *
+ *      4. For x in [0.67434,pi/4],  let y = pi/4 - x, then
+ *              tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
+ *                     = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
+ */
+
+#include "libm.h"
+
+static const double T[] = {
+             3.33333333333334091986e-01, /* 3FD55555, 55555563 */
+             1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */
+             5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */
+             2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */
+             8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */
+             3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */
+             1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */
+             5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */
+             2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */
+             7.81794442939557092300e-05, /* 3F147E88, A03792A6 */
+             7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */
+            -1.85586374855275456654e-05, /* BEF375CB, DB605373 */
+             2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */
+},
+pio4 =       7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */
+pio4lo =     3.06161699786838301793e-17; /* 3C81A626, 33145C07 */
+
+double __tan(double x, double y, int odd)
+{
+	double_t z, r, v, w, s, a;
+	double w0, a0;
+	uint32_t hx;
+	int big, sign;
+
+	GET_HIGH_WORD(hx,x);
+	big = (hx&0x7fffffff) >= 0x3FE59428; /* |x| >= 0.6744 */
+	if (big) {
+		sign = hx>>31;
+		if (sign) {
+			x = -x;
+			y = -y;
+		}
+		x = (pio4 - x) + (pio4lo - y);
+		y = 0.0;
+	}
+	z = x * x;
+	w = z * z;
+	/*
+	 * Break x^5*(T[1]+x^2*T[2]+...) into
+	 * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
+	 * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
+	 */
+	r = T[1] + w*(T[3] + w*(T[5] + w*(T[7] + w*(T[9] + w*T[11]))));
+	v = z*(T[2] + w*(T[4] + w*(T[6] + w*(T[8] + w*(T[10] + w*T[12])))));
+	s = z * x;
+	r = y + z*(s*(r + v) + y) + s*T[0];
+	w = x + r;
+	if (big) {
+		s = 1 - 2*odd;
+		v = s - 2.0 * (x + (r - w*w/(w + s)));
+		return sign ? -v : v;
+	}
+	if (!odd)
+		return w;
+	/* -1.0/(x+r) has up to 2ulp error, so compute it accurately */
+	w0 = w;
+	SET_LOW_WORD(w0, 0);
+	v = r - (w0 - x);       /* w0+v = r+x */
+	a0 = a = -1.0 / w;
+	SET_LOW_WORD(a0, 0);
+	return a0 + a*(1.0 + a0*w0 + a0*v);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__tandf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__tandf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__tandf.c	(revision 398)
@@ -0,0 +1,54 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/k_tanf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */
+static const double T[] = {
+  0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */
+  0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */
+  0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */
+  0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */
+  0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */
+  0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */
+};
+
+float __tandf(double x, int odd)
+{
+	double_t z,r,w,s,t,u;
+
+	z = x*x;
+	/*
+	 * Split up the polynomial into small independent terms to give
+	 * opportunities for parallel evaluation.  The chosen splitting is
+	 * micro-optimized for Athlons (XP, X64).  It costs 2 multiplications
+	 * relative to Horner's method on sequential machines.
+	 *
+	 * We add the small terms from lowest degree up for efficiency on
+	 * non-sequential machines (the lowest degree terms tend to be ready
+	 * earlier).  Apart from this, we don't care about order of
+	 * operations, and don't need to to care since we have precision to
+	 * spare.  However, the chosen splitting is good for accuracy too,
+	 * and would give results as accurate as Horner's method if the
+	 * small terms were added from highest degree down.
+	 */
+	r = T[4] + z*T[5];
+	t = T[2] + z*T[3];
+	w = z*z;
+	s = z*x;
+	u = T[0] + z*T[1];
+	r = (x + s*u) + (s*w)*(t + w*r);
+	return odd ? -1.0/r : r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__tanl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__tanl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/__tanl.c	(revision 398)
@@ -0,0 +1,143 @@
+/* origin: FreeBSD /usr/src/lib/msun/ld80/k_tanl.c */
+/* origin: FreeBSD /usr/src/lib/msun/ld128/k_tanl.c */
+/*
+ * ====================================================
+ * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#if LDBL_MANT_DIG == 64
+/*
+ * ld80 version of __tan.c.  See __tan.c for most comments.
+ */
+/*
+ * Domain [-0.67434, 0.67434], range ~[-2.25e-22, 1.921e-22]
+ * |tan(x)/x - t(x)| < 2**-71.9
+ *
+ * See __cosl.c for more details about the polynomial.
+ */
+static const long double
+T3 =  0.333333333333333333180L,         /*  0xaaaaaaaaaaaaaaa5.0p-65 */
+T5 =  0.133333333333333372290L,         /*  0x88888888888893c3.0p-66 */
+T7 =  0.0539682539682504975744L,        /*  0xdd0dd0dd0dc13ba2.0p-68 */
+pio4   =  0.785398163397448309628L,     /*  0xc90fdaa22168c235.0p-64 */
+pio4lo = -1.25413940316708300586e-20L;  /* -0xece675d1fc8f8cbb.0p-130 */
+static const double
+T9  =  0.021869488536312216,            /*  0x1664f4882cc1c2.0p-58 */
+T11 =  0.0088632355256619590,           /*  0x1226e355c17612.0p-59 */
+T13 =  0.0035921281113786528,           /*  0x1d6d3d185d7ff8.0p-61 */
+T15 =  0.0014558334756312418,           /*  0x17da354aa3f96b.0p-62 */
+T17 =  0.00059003538700862256,          /*  0x13559358685b83.0p-63 */
+T19 =  0.00023907843576635544,          /*  0x1f56242026b5be.0p-65 */
+T21 =  0.000097154625656538905,         /*  0x1977efc26806f4.0p-66 */
+T23 =  0.000038440165747303162,         /*  0x14275a09b3ceac.0p-67 */
+T25 =  0.000018082171885432524,         /*  0x12f5e563e5487e.0p-68 */
+T27 =  0.0000024196006108814377,        /*  0x144c0d80cc6896.0p-71 */
+T29 =  0.0000078293456938132840,        /*  0x106b59141a6cb3.0p-69 */
+T31 = -0.0000032609076735050182,        /* -0x1b5abef3ba4b59.0p-71 */
+T33 =  0.0000023261313142559411;        /*  0x13835436c0c87f.0p-71 */
+#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
+	w * (T25 + w * (T29 + w * T33)))))))
+#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
+	w * (T27 + w * T31))))))
+#elif LDBL_MANT_DIG == 113
+/*
+ * ld128 version of __tan.c.  See __tan.c for most comments.
+ */
+/*
+ * Domain [-0.67434, 0.67434], range ~[-3.37e-36, 1.982e-37]
+ * |tan(x)/x - t(x)| < 2**-117.8 (XXX should be ~1e-37)
+ *
+ * See __cosl.c for more details about the polynomial.
+ */
+static const long double
+T3 = 0x1.5555555555555555555555555553p-2L,
+T5 = 0x1.1111111111111111111111111eb5p-3L,
+T7 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5L,
+T9 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6L,
+T11 = 0x1.226e355e6c23c8f5b4f5762322eep-7L,
+T13 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9L,
+T15 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10L,
+T17 = 0x1.355824803674477dfcf726649efep-11L,
+T19 = 0x1.f57d7734d1656e0aceb716f614c2p-13L,
+T21 = 0x1.967e18afcb180ed942dfdc518d6cp-14L,
+T23 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15L,
+T25 = 0x1.0b132d39f055c81be49eff7afd50p-16L,
+T27 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18L,
+T29 = 0x1.5ef2daf21d1113df38d0fbc00267p-19L,
+T31 = 0x1.1c77d6eac0234988cdaa04c96626p-20L,
+T33 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22L,
+T35 = 0x1.75c7357d0298c01a31d0a6f7d518p-23L,
+T37 = 0x1.2f3190f4718a9a520f98f50081fcp-24L,
+pio4 = 0x1.921fb54442d18469898cc51701b8p-1L,
+pio4lo = 0x1.cd129024e088a67cc74020bbea60p-116L;
+static const double
+T39 =  0.000000028443389121318352,	/*  0x1e8a7592977938.0p-78 */
+T41 =  0.000000011981013102001973,	/*  0x19baa1b1223219.0p-79 */
+T43 =  0.0000000038303578044958070,	/*  0x107385dfb24529.0p-80 */
+T45 =  0.0000000034664378216909893,	/*  0x1dc6c702a05262.0p-81 */
+T47 = -0.0000000015090641701997785,	/* -0x19ecef3569ebb6.0p-82 */
+T49 =  0.0000000029449552300483952,	/*  0x194c0668da786a.0p-81 */
+T51 = -0.0000000022006995706097711,	/* -0x12e763b8845268.0p-81 */
+T53 =  0.0000000015468200913196612,	/*  0x1a92fc98c29554.0p-82 */
+T55 = -0.00000000061311613386849674,	/* -0x151106cbc779a9.0p-83 */
+T57 =  1.4912469681508012e-10;		/*  0x147edbdba6f43a.0p-85 */
+#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
+	w * (T25 + w * (T29 + w * (T33 + w * (T37 + w * (T41 + \
+	w * (T45 + w * (T49 + w * (T53 + w * T57)))))))))))))
+#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
+	w * (T27 + w * (T31 + w * (T35 + w * (T39 + w * (T43 + \
+	w * (T47 + w * (T51 + w * T55))))))))))))
+#endif
+
+long double __tanl(long double x, long double y, int odd) {
+	long double z, r, v, w, s, a, t;
+	int big, sign;
+
+	big = fabsl(x) >= 0.67434;
+	if (big) {
+		sign = 0;
+		if (x < 0) {
+			sign = 1;
+			x = -x;
+			y = -y;
+		}
+		x = (pio4 - x) + (pio4lo - y);
+		y = 0.0;
+	}
+	z = x * x;
+	w = z * z;
+	r = RPOLY(w);
+	v = z * VPOLY(w);
+	s = z * x;
+	r = y + z * (s * (r + v) + y) + T3 * s;
+	w = x + r;
+	if (big) {
+		s = 1 - 2*odd;
+		v = s - 2.0 * (x + (r - w * w / (w + s)));
+		return sign ? -v : v;
+	}
+	if (!odd)
+		return w;
+	/*
+	 * if allow error up to 2 ulp, simply return
+	 * -1.0 / (x+r) here
+	 */
+	/* compute -1.0 / (x+r) accurately */
+	z = w;
+	z = z + 0x1p32 - 0x1p32;
+	v = r - (z - x);        /* z+v = r+x */
+	t = a = -1.0 / w;       /* a = -1.0/w */
+	t = t + 0x1p32 - 0x1p32;
+	s = 1.0 + t * z;
+	return t + a * (s + t * v);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acos.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acos.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acos.c	(revision 398)
@@ -0,0 +1,101 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_acos.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* acos(x)
+ * Method :
+ *      acos(x)  = pi/2 - asin(x)
+ *      acos(-x) = pi/2 + asin(x)
+ * For |x|<=0.5
+ *      acos(x) = pi/2 - (x + x*x^2*R(x^2))     (see asin.c)
+ * For x>0.5
+ *      acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
+ *              = 2asin(sqrt((1-x)/2))
+ *              = 2s + 2s*z*R(z)        ...z=(1-x)/2, s=sqrt(z)
+ *              = 2f + (2c + 2s*z*R(z))
+ *     where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
+ *     for f so that f+c ~ sqrt(z).
+ * For x<-0.5
+ *      acos(x) = pi - 2asin(sqrt((1-|x|)/2))
+ *              = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
+ *
+ * Special cases:
+ *      if x is NaN, return x itself;
+ *      if |x|>1, return NaN with invalid signal.
+ *
+ * Function needed: sqrt
+ */
+
+#include "libm.h"
+
+static const double
+pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pS0 =  1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 =  2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 =  7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 =  3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 =  2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+static double R(double z)
+{
+	double_t p, q;
+	p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+	q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+	return p/q;
+}
+
+double acos(double x)
+{
+	double z,w,s,c,df;
+	uint32_t hx,ix;
+
+	GET_HIGH_WORD(hx, x);
+	ix = hx & 0x7fffffff;
+	/* |x| >= 1 or nan */
+	if (ix >= 0x3ff00000) {
+		uint32_t lx;
+
+		GET_LOW_WORD(lx,x);
+		if ((ix-0x3ff00000 | lx) == 0) {
+			/* acos(1)=0, acos(-1)=pi */
+			if (hx >> 31)
+				return 2*pio2_hi + 0x1p-120f;
+			return 0;
+		}
+		return 0/(x-x);
+	}
+	/* |x| < 0.5 */
+	if (ix < 0x3fe00000) {
+		if (ix <= 0x3c600000)  /* |x| < 2**-57 */
+			return pio2_hi + 0x1p-120f;
+		return pio2_hi - (x - (pio2_lo-x*R(x*x)));
+	}
+	/* x < -0.5 */
+	if (hx >> 31) {
+		z = (1.0+x)*0.5;
+		s = sqrt(z);
+		w = R(z)*s-pio2_lo;
+		return 2*(pio2_hi - (s+w));
+	}
+	/* x > 0.5 */
+	z = (1.0-x)*0.5;
+	s = sqrt(z);
+	df = s;
+	SET_LOW_WORD(df,0);
+	c = (z-df*df)/(s+df);
+	w = R(z)*s+c;
+	return 2*(df+w);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acosf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acosf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acosf.c	(revision 398)
@@ -0,0 +1,71 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_acosf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
+pio2_lo = 7.5497894159e-08, /* 0x33a22168 */
+pS0 =  1.6666586697e-01,
+pS1 = -4.2743422091e-02,
+pS2 = -8.6563630030e-03,
+qS1 = -7.0662963390e-01;
+
+static float R(float z)
+{
+	float_t p, q;
+	p = z*(pS0+z*(pS1+z*pS2));
+	q = 1.0f+z*qS1;
+	return p/q;
+}
+
+float acosf(float x)
+{
+	float z,w,s,c,df;
+	uint32_t hx,ix;
+
+	GET_FLOAT_WORD(hx, x);
+	ix = hx & 0x7fffffff;
+	/* |x| >= 1 or nan */
+	if (ix >= 0x3f800000) {
+		if (ix == 0x3f800000) {
+			if (hx >> 31)
+				return 2*pio2_hi + 0x1p-120f;
+			return 0;
+		}
+		return 0/(x-x);
+	}
+	/* |x| < 0.5 */
+	if (ix < 0x3f000000) {
+		if (ix <= 0x32800000) /* |x| < 2**-26 */
+			return pio2_hi + 0x1p-120f;
+		return pio2_hi - (x - (pio2_lo-x*R(x*x)));
+	}
+	/* x < -0.5 */
+	if (hx >> 31) {
+		z = (1+x)*0.5f;
+		s = sqrtf(z);
+		w = R(z)*s-pio2_lo;
+		return 2*(pio2_hi - (s+w));
+	}
+	/* x > 0.5 */
+	z = (1-x)*0.5f;
+	s = sqrtf(z);
+	GET_FLOAT_WORD(hx,s);
+	SET_FLOAT_WORD(df,hx&0xfffff000);
+	c = (z-df*df)/(s+df);
+	w = R(z)*s+c;
+	return 2*(df+w);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acosh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acosh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acosh.c	(revision 398)
@@ -0,0 +1,24 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==2
+#undef sqrt
+#define sqrt sqrtl
+#endif
+
+/* acosh(x) = log(x + sqrt(x*x-1)) */
+double acosh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	unsigned e = u.i >> 52 & 0x7ff;
+
+	/* x < 1 domain error is handled in the called functions */
+
+	if (e < 0x3ff + 1)
+		/* |x| < 2, up to 2ulp error in [1,1.125] */
+		return log1p(x-1 + sqrt((x-1)*(x-1)+2*(x-1)));
+	if (e < 0x3ff + 26)
+		/* |x| < 0x1p26 */
+		return log(2*x - 1/(x+sqrt(x*x-1)));
+	/* |x| >= 0x1p26 or nan */
+	return log(x) + 0.693147180559945309417232121458176568;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acoshf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acoshf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acoshf.c	(revision 398)
@@ -0,0 +1,26 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==2
+#undef sqrtf
+#define sqrtf sqrtl
+#elif FLT_EVAL_METHOD==1
+#undef sqrtf
+#define sqrtf sqrt
+#endif
+
+/* acosh(x) = log(x + sqrt(x*x-1)) */
+float acoshf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	uint32_t a = u.i & 0x7fffffff;
+
+	if (a < 0x3f800000+(1<<23))
+		/* |x| < 2, invalid if x < 1 or nan */
+		/* up to 2ulp error in [1,1.125] */
+		return log1pf(x-1 + sqrtf((x-1)*(x-1)+2*(x-1)));
+	if (a < 0x3f800000+(12<<23))
+		/* |x| < 0x1p12 */
+		return logf(2*x - 1/(x+sqrtf(x*x-1)));
+	/* x >= 0x1p12 */
+	return logf(x) + 0.693147180559945309417232121458176568f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acoshl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acoshl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acoshl.c	(revision 398)
@@ -0,0 +1,29 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double acoshl(long double x)
+{
+	return acosh(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* acosh(x) = log(x + sqrt(x*x-1)) */
+long double acoshl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+
+	if (e < 0x3fff + 1)
+		/* |x| < 2, invalid if x < 1 or nan */
+		return log1pl(x-1 + sqrtl((x-1)*(x-1)+2*(x-1)));
+	if (e < 0x3fff + 32)
+		/* |x| < 0x1p32 */
+		return logl(2*x - 1/(x+sqrtl(x*x-1)));
+	return logl(x) + 0.693147180559945309417232121458176568L;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double acoshl(long double x)
+{
+	return acosh(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acosl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acosl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/acosl.c	(revision 398)
@@ -0,0 +1,67 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_acosl.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * See comments in acos.c.
+ * Converted to long double by David Schultz <das@FreeBSD.ORG>.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double acosl(long double x)
+{
+	return acos(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#include "__invtrigl.h"
+#if LDBL_MANT_DIG == 64
+#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)
+#elif LDBL_MANT_DIG == 113
+#define CLEARBOTTOM(u) (u.i.lo = 0)
+#endif
+
+long double acosl(long double x)
+{
+	union ldshape u = {x};
+	long double z, s, c, f;
+	uint16_t e = u.i.se & 0x7fff;
+
+	/* |x| >= 1 or nan */
+	if (e >= 0x3fff) {
+		if (x == 1)
+			return 0;
+		if (x == -1)
+			return 2*pio2_hi + 0x1p-120f;
+		return 0/(x-x);
+	}
+	/* |x| < 0.5 */
+	if (e < 0x3fff - 1) {
+		if (e < 0x3fff - LDBL_MANT_DIG - 1)
+			return pio2_hi + 0x1p-120f;
+		return pio2_hi - (__invtrigl_R(x*x)*x - pio2_lo + x);
+	}
+	/* x < -0.5 */
+	if (u.i.se >> 15) {
+		z = (1 + x)*0.5;
+		s = sqrtl(z);
+		return 2*(pio2_hi - (__invtrigl_R(z)*s - pio2_lo + s));
+	}
+	/* x > 0.5 */
+	z = (1 - x)*0.5;
+	s = sqrtl(z);
+	u.f = s;
+	CLEARBOTTOM(u);
+	f = u.f;
+	c = (z - f*f)/(s + f);
+	return 2*(__invtrigl_R(z)*s + c + f);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asin.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asin.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asin.c	(revision 398)
@@ -0,0 +1,107 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_asin.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* asin(x)
+ * Method :
+ *      Since  asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
+ *      we approximate asin(x) on [0,0.5] by
+ *              asin(x) = x + x*x^2*R(x^2)
+ *      where
+ *              R(x^2) is a rational approximation of (asin(x)-x)/x^3
+ *      and its remez error is bounded by
+ *              |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
+ *
+ *      For x in [0.5,1]
+ *              asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ *      Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ *      then for x>0.98
+ *              asin(x) = pi/2 - 2*(s+s*z*R(z))
+ *                      = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ *      For x<=0.98, let pio4_hi = pio2_hi/2, then
+ *              f = hi part of s;
+ *              c = sqrt(z) - f = (z-f*f)/(s+f)         ...f+c=sqrt(z)
+ *      and
+ *              asin(x) = pi/2 - 2*(s+s*z*R(z))
+ *                      = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ *                      = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ *      if x is NaN, return x itself;
+ *      if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+#include "libm.h"
+
+static const double
+pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+/* coefficients for R(x^2) */
+pS0 =  1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 =  2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 =  7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 =  3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 =  2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+static double R(double z)
+{
+	double_t p, q;
+	p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+	q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+	return p/q;
+}
+
+double asin(double x)
+{
+	double z,r,s;
+	uint32_t hx,ix;
+
+	GET_HIGH_WORD(hx, x);
+	ix = hx & 0x7fffffff;
+	/* |x| >= 1 or nan */
+	if (ix >= 0x3ff00000) {
+		uint32_t lx;
+		GET_LOW_WORD(lx, x);
+		if ((ix-0x3ff00000 | lx) == 0)
+			/* asin(1) = +-pi/2 with inexact */
+			return x*pio2_hi + 0x1p-120f;
+		return 0/(x-x);
+	}
+	/* |x| < 0.5 */
+	if (ix < 0x3fe00000) {
+		/* if 0x1p-1022 <= |x| < 0x1p-26, avoid raising underflow */
+		if (ix < 0x3e500000 && ix >= 0x00100000)
+			return x;
+		return x + x*R(x*x);
+	}
+	/* 1 > |x| >= 0.5 */
+	z = (1 - fabs(x))*0.5;
+	s = sqrt(z);
+	r = R(z);
+	if (ix >= 0x3fef3333) {  /* if |x| > 0.975 */
+		x = pio2_hi-(2*(s+s*r)-pio2_lo);
+	} else {
+		double f,c;
+		/* f+c = sqrt(z) */
+		f = s;
+		SET_LOW_WORD(f,0);
+		c = (z-f*f)/(s+f);
+		x = 0.5*pio2_hi - (2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));
+	}
+	if (hx >> 31)
+		return -x;
+	return x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinf.c	(revision 398)
@@ -0,0 +1,61 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_asinf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+#include "libm.h"
+
+static const double
+pio2 = 1.570796326794896558e+00;
+
+static const float
+/* coefficients for R(x^2) */
+pS0 =  1.6666586697e-01,
+pS1 = -4.2743422091e-02,
+pS2 = -8.6563630030e-03,
+qS1 = -7.0662963390e-01;
+
+static float R(float z)
+{
+	float_t p, q;
+	p = z*(pS0+z*(pS1+z*pS2));
+	q = 1.0f+z*qS1;
+	return p/q;
+}
+
+float asinf(float x)
+{
+	double s;
+	float z;
+	uint32_t hx,ix;
+
+	GET_FLOAT_WORD(hx, x);
+	ix = hx & 0x7fffffff;
+	if (ix >= 0x3f800000) {  /* |x| >= 1 */
+		if (ix == 0x3f800000)  /* |x| == 1 */
+			return x*pio2 + 0x1p-120f;  /* asin(+-1) = +-pi/2 with inexact */
+		return 0/(x-x);  /* asin(|x|>1) is NaN */
+	}
+	if (ix < 0x3f000000) {  /* |x| < 0.5 */
+		/* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */
+		if (ix < 0x39800000 && ix >= 0x00800000)
+			return x;
+		return x + x*R(x*x);
+	}
+	/* 1 > |x| >= 0.5 */
+	z = (1 - fabsf(x))*0.5f;
+	s = sqrt(z);
+	x = pio2 - 2*(s+s*R(z));
+	if (hx >> 31)
+		return -x;
+	return x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinh.c	(revision 398)
@@ -0,0 +1,28 @@
+#include "libm.h"
+
+/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
+double asinh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	unsigned e = u.i >> 52 & 0x7ff;
+	unsigned s = u.i >> 63;
+
+	/* |x| */
+	u.i &= (uint64_t)-1/2;
+	x = u.f;
+
+	if (e >= 0x3ff + 26) {
+		/* |x| >= 0x1p26 or inf or nan */
+		x = log(x) + 0.693147180559945309417232121458176568;
+	} else if (e >= 0x3ff + 1) {
+		/* |x| >= 2 */
+		x = log(2*x + 1/(sqrt(x*x+1)+x));
+	} else if (e >= 0x3ff - 26) {
+		/* |x| >= 0x1p-26, up to 1.6ulp error in [0.125,0.5] */
+		x = log1p(x + x*x/(sqrt(x*x+1)+1));
+	} else {
+		/* |x| < 0x1p-26, raise inexact if x != 0 */
+		FORCE_EVAL(x + 0x1p120f);
+	}
+	return s ? -x : x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinhf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinhf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinhf.c	(revision 398)
@@ -0,0 +1,28 @@
+#include "libm.h"
+
+/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
+float asinhf(float x)
+{
+	union {float f; uint32_t i;} u = {.f = x};
+	uint32_t i = u.i & 0x7fffffff;
+	unsigned s = u.i >> 31;
+
+	/* |x| */
+	u.i = i;
+	x = u.f;
+
+	if (i >= 0x3f800000 + (12<<23)) {
+		/* |x| >= 0x1p12 or inf or nan */
+		x = logf(x) + 0.693147180559945309417232121458176568f;
+	} else if (i >= 0x3f800000 + (1<<23)) {
+		/* |x| >= 2 */
+		x = logf(2*x + 1/(sqrtf(x*x+1)+x));
+	} else if (i >= 0x3f800000 - (12<<23)) {
+		/* |x| >= 0x1p-12, up to 1.6ulp error in [0.125,0.5] */
+		x = log1pf(x + x*x/(sqrtf(x*x+1)+1));
+	} else {
+		/* |x| < 0x1p-12, raise inexact if x!=0 */
+		FORCE_EVAL(x + 0x1p120f);
+	}
+	return s ? -x : x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinhl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinhl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinhl.c	(revision 398)
@@ -0,0 +1,41 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double asinhl(long double x)
+{
+	return asinh(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
+long double asinhl(long double x)
+{
+	union ldshape u = {x};
+	unsigned e = u.i.se & 0x7fff;
+	unsigned s = u.i.se >> 15;
+
+	/* |x| */
+	u.i.se = e;
+	x = u.f;
+
+	if (e >= 0x3fff + 32) {
+		/* |x| >= 0x1p32 or inf or nan */
+		x = logl(x) + 0.693147180559945309417232121458176568L;
+	} else if (e >= 0x3fff + 1) {
+		/* |x| >= 2 */
+		x = logl(2*x + 1/(sqrtl(x*x+1)+x));
+	} else if (e >= 0x3fff - 32) {
+		/* |x| >= 0x1p-32 */
+		x = log1pl(x + x*x/(sqrtl(x*x+1)+1));
+	} else {
+		/* |x| < 0x1p-32, raise inexact if x!=0 */
+		FORCE_EVAL(x + 0x1p120f);
+	}
+	return s ? -x : x;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double asinhl(long double x)
+{
+	return asinh(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/asinl.c	(revision 398)
@@ -0,0 +1,71 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_asinl.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * See comments in asin.c.
+ * Converted to long double by David Schultz <das@FreeBSD.ORG>.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double asinl(long double x)
+{
+	return asin(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#include "__invtrigl.h"
+#if LDBL_MANT_DIG == 64
+#define CLOSETO1(u) (u.i.m>>56 >= 0xf7)
+#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)
+#elif LDBL_MANT_DIG == 113
+#define CLOSETO1(u) (u.i.top >= 0xee00)
+#define CLEARBOTTOM(u) (u.i.lo = 0)
+#endif
+
+long double asinl(long double x)
+{
+	union ldshape u = {x};
+	long double z, r, s;
+	uint16_t e = u.i.se & 0x7fff;
+	int sign = u.i.se >> 15;
+
+	if (e >= 0x3fff) {   /* |x| >= 1 or nan */
+		/* asin(+-1)=+-pi/2 with inexact */
+		if (x == 1 || x == -1)
+			return x*pio2_hi + 0x1p-120f;
+		return 0/(x-x);
+	}
+	if (e < 0x3fff - 1) {  /* |x| < 0.5 */
+		if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {
+			/* return x with inexact if x!=0 */
+			FORCE_EVAL(x + 0x1p120f);
+			return x;
+		}
+		return x + x*__invtrigl_R(x*x);
+	}
+	/* 1 > |x| >= 0.5 */
+	z = (1.0 - fabsl(x))*0.5;
+	s = sqrtl(z);
+	r = __invtrigl_R(z);
+	if (CLOSETO1(u)) {
+		x = pio2_hi - (2*(s+s*r)-pio2_lo);
+	} else {
+		long double f, c;
+		u.f = s;
+		CLEARBOTTOM(u);
+		f = u.f;
+		c = (z - f*f)/(s + f);
+		x = 0.5*pio2_hi-(2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));
+	}
+	return sign ? -x : x;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan.c	(revision 398)
@@ -0,0 +1,116 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_atan.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* atan(x)
+ * Method
+ *   1. Reduce x to positive by atan(x) = -atan(-x).
+ *   2. According to the integer k=4t+0.25 chopped, t=x, the argument
+ *      is further reduced to one of the following intervals and the
+ *      arctangent of t is evaluated by the corresponding formula:
+ *
+ *      [0,7/16]      atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
+ *      [7/16,11/16]  atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
+ *      [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
+ *      [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
+ *      [39/16,INF]   atan(x) = atan(INF) + atan( -1/t )
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+
+#include "libm.h"
+
+static const double atanhi[] = {
+  4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
+  7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
+  9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
+  1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
+};
+
+static const double atanlo[] = {
+  2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
+  3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
+  1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
+  6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
+};
+
+static const double aT[] = {
+  3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
+ -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
+  1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
+ -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
+  9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
+ -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
+  6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
+ -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
+  4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
+ -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
+  1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
+};
+
+double atan(double x)
+{
+	double_t w,s1,s2,z;
+	uint32_t ix,sign;
+	int id;
+
+	GET_HIGH_WORD(ix, x);
+	sign = ix >> 31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x44100000) {   /* if |x| >= 2^66 */
+		if (isnan(x))
+			return x;
+		z = atanhi[3] + 0x1p-120f;
+		return sign ? -z : z;
+	}
+	if (ix < 0x3fdc0000) {    /* |x| < 0.4375 */
+		if (ix < 0x3e400000) {  /* |x| < 2^-27 */
+			if (ix < 0x00100000)
+				/* raise underflow for subnormal x */
+				FORCE_EVAL((float)x);
+			return x;
+		}
+		id = -1;
+	} else {
+		x = fabs(x);
+		if (ix < 0x3ff30000) {  /* |x| < 1.1875 */
+			if (ix < 0x3fe60000) {  /*  7/16 <= |x| < 11/16 */
+				id = 0;
+				x = (2.0*x-1.0)/(2.0+x);
+			} else {                /* 11/16 <= |x| < 19/16 */
+				id = 1;
+				x = (x-1.0)/(x+1.0);
+			}
+		} else {
+			if (ix < 0x40038000) {  /* |x| < 2.4375 */
+				id = 2;
+				x = (x-1.5)/(1.0+1.5*x);
+			} else {                /* 2.4375 <= |x| < 2^66 */
+				id = 3;
+				x = -1.0/x;
+			}
+		}
+	}
+	/* end of argument reduction */
+	z = x*x;
+	w = z*z;
+	/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+	s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
+	s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
+	if (id < 0)
+		return x - x*(s1+s2);
+	z = atanhi[id] - (x*(s1+s2) - atanlo[id] - x);
+	return sign ? -z : z;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan2.c	(revision 398)
@@ -0,0 +1,107 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+/* atan2(y,x)
+ * Method :
+ *      1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
+ *      2. Reduce x to positive by (if x and y are unexceptional):
+ *              ARG (x+iy) = arctan(y/x)           ... if x > 0,
+ *              ARG (x+iy) = pi - arctan[y/(-x)]   ... if x < 0,
+ *
+ * Special cases:
+ *
+ *      ATAN2((anything), NaN ) is NaN;
+ *      ATAN2(NAN , (anything) ) is NaN;
+ *      ATAN2(+-0, +(anything but NaN)) is +-0  ;
+ *      ATAN2(+-0, -(anything but NaN)) is +-pi ;
+ *      ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
+ *      ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
+ *      ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
+ *      ATAN2(+-INF,+INF ) is +-pi/4 ;
+ *      ATAN2(+-INF,-INF ) is +-3pi/4;
+ *      ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "libm.h"
+
+static const double
+pi     = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
+pi_lo  = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
+
+double atan2(double y, double x)
+{
+	double z;
+	uint32_t m,lx,ly,ix,iy;
+
+	if (isnan(x) || isnan(y))
+		return x+y;
+	EXTRACT_WORDS(ix, lx, x);
+	EXTRACT_WORDS(iy, ly, y);
+	if ((ix-0x3ff00000 | lx) == 0)  /* x = 1.0 */
+		return atan(y);
+	m = ((iy>>31)&1) | ((ix>>30)&2);  /* 2*sign(x)+sign(y) */
+	ix = ix & 0x7fffffff;
+	iy = iy & 0x7fffffff;
+
+	/* when y = 0 */
+	if ((iy|ly) == 0) {
+		switch(m) {
+		case 0:
+		case 1: return y;   /* atan(+-0,+anything)=+-0 */
+		case 2: return  pi; /* atan(+0,-anything) = pi */
+		case 3: return -pi; /* atan(-0,-anything) =-pi */
+		}
+	}
+	/* when x = 0 */
+	if ((ix|lx) == 0)
+		return m&1 ? -pi/2 : pi/2;
+	/* when x is INF */
+	if (ix == 0x7ff00000) {
+		if (iy == 0x7ff00000) {
+			switch(m) {
+			case 0: return  pi/4;   /* atan(+INF,+INF) */
+			case 1: return -pi/4;   /* atan(-INF,+INF) */
+			case 2: return  3*pi/4; /* atan(+INF,-INF) */
+			case 3: return -3*pi/4; /* atan(-INF,-INF) */
+			}
+		} else {
+			switch(m) {
+			case 0: return  0.0; /* atan(+...,+INF) */
+			case 1: return -0.0; /* atan(-...,+INF) */
+			case 2: return  pi;  /* atan(+...,-INF) */
+			case 3: return -pi;  /* atan(-...,-INF) */
+			}
+		}
+	}
+	/* |y/x| > 0x1p64 */
+	if (ix+(64<<20) < iy || iy == 0x7ff00000)
+		return m&1 ? -pi/2 : pi/2;
+
+	/* z = atan(|y/x|) without spurious underflow */
+	if ((m&2) && iy+(64<<20) < ix)  /* |y/x| < 0x1p-64, x<0 */
+		z = 0;
+	else
+		z = atan(fabs(y/x));
+	switch (m) {
+	case 0: return z;              /* atan(+,+) */
+	case 1: return -z;             /* atan(-,+) */
+	case 2: return pi - (z-pi_lo); /* atan(+,-) */
+	default: /* case 3 */
+		return (z-pi_lo) - pi; /* atan(-,-) */
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan2f.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan2f.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan2f.c	(revision 398)
@@ -0,0 +1,83 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2f.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+pi     = 3.1415927410e+00, /* 0x40490fdb */
+pi_lo  = -8.7422776573e-08; /* 0xb3bbbd2e */
+
+float atan2f(float y, float x)
+{
+	float z;
+	uint32_t m,ix,iy;
+
+	if (isnan(x) || isnan(y))
+		return x+y;
+	GET_FLOAT_WORD(ix, x);
+	GET_FLOAT_WORD(iy, y);
+	if (ix == 0x3f800000)  /* x=1.0 */
+		return atanf(y);
+	m = ((iy>>31)&1) | ((ix>>30)&2);  /* 2*sign(x)+sign(y) */
+	ix &= 0x7fffffff;
+	iy &= 0x7fffffff;
+
+	/* when y = 0 */
+	if (iy == 0) {
+		switch (m) {
+		case 0:
+		case 1: return y;   /* atan(+-0,+anything)=+-0 */
+		case 2: return  pi; /* atan(+0,-anything) = pi */
+		case 3: return -pi; /* atan(-0,-anything) =-pi */
+		}
+	}
+	/* when x = 0 */
+	if (ix == 0)
+		return m&1 ? -pi/2 : pi/2;
+	/* when x is INF */
+	if (ix == 0x7f800000) {
+		if (iy == 0x7f800000) {
+			switch (m) {
+			case 0: return  pi/4; /* atan(+INF,+INF) */
+			case 1: return -pi/4; /* atan(-INF,+INF) */
+			case 2: return 3*pi/4;  /*atan(+INF,-INF)*/
+			case 3: return -3*pi/4; /*atan(-INF,-INF)*/
+			}
+		} else {
+			switch (m) {
+			case 0: return  0.0f;    /* atan(+...,+INF) */
+			case 1: return -0.0f;    /* atan(-...,+INF) */
+			case 2: return  pi; /* atan(+...,-INF) */
+			case 3: return -pi; /* atan(-...,-INF) */
+			}
+		}
+	}
+	/* |y/x| > 0x1p26 */
+	if (ix+(26<<23) < iy || iy == 0x7f800000)
+		return m&1 ? -pi/2 : pi/2;
+
+	/* z = atan(|y/x|) with correct underflow */
+	if ((m&2) && iy+(26<<23) < ix)  /*|y/x| < 0x1p-26, x < 0 */
+		z = 0.0;
+	else
+		z = atanf(fabsf(y/x));
+	switch (m) {
+	case 0: return z;              /* atan(+,+) */
+	case 1: return -z;             /* atan(-,+) */
+	case 2: return pi - (z-pi_lo); /* atan(+,-) */
+	default: /* case 3 */
+		return (z-pi_lo) - pi; /* atan(-,-) */
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan2l.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan2l.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atan2l.c	(revision 398)
@@ -0,0 +1,85 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2l.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+/*
+ * See comments in atan2.c.
+ * Converted to long double by David Schultz <das@FreeBSD.ORG>.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double atan2l(long double y, long double x)
+{
+	return atan2(y, x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#include "__invtrigl.h"
+
+long double atan2l(long double y, long double x)
+{
+	union ldshape ux, uy;
+	long double z;
+	int m, ex, ey;
+
+	if (isnan(x) || isnan(y))
+		return x+y;
+	if (x == 1)
+		return atanl(y);
+	ux.f = x;
+	uy.f = y;
+	ex = ux.i.se & 0x7fff;
+	ey = uy.i.se & 0x7fff;
+	m = 2*(ux.i.se>>15) | uy.i.se>>15;
+	if (y == 0) {
+		switch(m) {
+		case 0:
+		case 1: return y;           /* atan(+-0,+anything)=+-0 */
+		case 2: return  2*pio2_hi;  /* atan(+0,-anything) = pi */
+		case 3: return -2*pio2_hi;  /* atan(-0,-anything) =-pi */
+		}
+	}
+	if (x == 0)
+		return m&1 ? -pio2_hi : pio2_hi;
+	if (ex == 0x7fff) {
+		if (ey == 0x7fff) {
+			switch(m) {
+			case 0: return  pio2_hi/2;   /* atan(+INF,+INF) */
+			case 1: return -pio2_hi/2;   /* atan(-INF,+INF) */
+			case 2: return  1.5*pio2_hi; /* atan(+INF,-INF) */
+			case 3: return -1.5*pio2_hi; /* atan(-INF,-INF) */
+			}
+		} else {
+			switch(m) {
+			case 0: return  0.0;        /* atan(+...,+INF) */
+			case 1: return -0.0;        /* atan(-...,+INF) */
+			case 2: return  2*pio2_hi;  /* atan(+...,-INF) */
+			case 3: return -2*pio2_hi;  /* atan(-...,-INF) */
+			}
+		}
+	}
+	if (ex+120 < ey || ey == 0x7fff)
+		return m&1 ? -pio2_hi : pio2_hi;
+	/* z = atan(|y/x|) without spurious underflow */
+	if ((m&2) && ey+120 < ex)  /* |y/x| < 0x1p-120, x<0 */
+		z = 0.0;
+	else
+		z = atanl(fabsl(y/x));
+	switch (m) {
+	case 0: return z;               /* atan(+,+) */
+	case 1: return -z;              /* atan(-,+) */
+	case 2: return 2*pio2_hi-(z-2*pio2_lo); /* atan(+,-) */
+	default: /* case 3 */
+		return (z-2*pio2_lo)-2*pio2_hi; /* atan(-,-) */
+	}
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanf.c	(revision 398)
@@ -0,0 +1,94 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_atanf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+
+#include "libm.h"
+
+static const float atanhi[] = {
+  4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */
+  7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */
+  9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */
+  1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */
+};
+
+static const float atanlo[] = {
+  5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */
+  3.7748947079e-08, /* atan(1.0)lo 0x33222168 */
+  3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */
+  7.5497894159e-08, /* atan(inf)lo 0x33a22168 */
+};
+
+static const float aT[] = {
+  3.3333328366e-01,
+ -1.9999158382e-01,
+  1.4253635705e-01,
+ -1.0648017377e-01,
+  6.1687607318e-02,
+};
+
+float atanf(float x)
+{
+	float_t w,s1,s2,z;
+	uint32_t ix,sign;
+	int id;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x4c800000) {  /* if |x| >= 2**26 */
+		if (isnan(x))
+			return x;
+		z = atanhi[3] + 0x1p-120f;
+		return sign ? -z : z;
+	}
+	if (ix < 0x3ee00000) {   /* |x| < 0.4375 */
+		if (ix < 0x39800000) {  /* |x| < 2**-12 */
+			if (ix < 0x00800000)
+				/* raise underflow for subnormal x */
+				FORCE_EVAL(x*x);
+			return x;
+		}
+		id = -1;
+	} else {
+		x = fabsf(x);
+		if (ix < 0x3f980000) {  /* |x| < 1.1875 */
+			if (ix < 0x3f300000) {  /*  7/16 <= |x| < 11/16 */
+				id = 0;
+				x = (2.0f*x - 1.0f)/(2.0f + x);
+			} else {                /* 11/16 <= |x| < 19/16 */
+				id = 1;
+				x = (x - 1.0f)/(x + 1.0f);
+			}
+		} else {
+			if (ix < 0x401c0000) {  /* |x| < 2.4375 */
+				id = 2;
+				x = (x - 1.5f)/(1.0f + 1.5f*x);
+			} else {                /* 2.4375 <= |x| < 2**26 */
+				id = 3;
+				x = -1.0f/x;
+			}
+		}
+	}
+	/* end of argument reduction */
+	z = x*x;
+	w = z*z;
+	/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+	s1 = z*(aT[0]+w*(aT[2]+w*aT[4]));
+	s2 = w*(aT[1]+w*aT[3]);
+	if (id < 0)
+		return x - x*(s1+s2);
+	z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+	return sign ? -z : z;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanh.c	(revision 398)
@@ -0,0 +1,29 @@
+#include "libm.h"
+
+/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
+double atanh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	unsigned e = u.i >> 52 & 0x7ff;
+	unsigned s = u.i >> 63;
+	double_t y;
+
+	/* |x| */
+	u.i &= (uint64_t)-1/2;
+	y = u.f;
+
+	if (e < 0x3ff - 1) {
+		if (e < 0x3ff - 32) {
+			/* handle underflow */
+			if (e == 0)
+				FORCE_EVAL((float)y);
+		} else {
+			/* |x| < 0.5, up to 1.7ulp error */
+			y = 0.5*log1p(2*y + 2*y*y/(1-y));
+		}
+	} else {
+		/* avoid overflow */
+		y = 0.5*log1p(2*(y/(1-y)));
+	}
+	return s ? -y : y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanhf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanhf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanhf.c	(revision 398)
@@ -0,0 +1,28 @@
+#include "libm.h"
+
+/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
+float atanhf(float x)
+{
+	union {float f; uint32_t i;} u = {.f = x};
+	unsigned s = u.i >> 31;
+	float_t y;
+
+	/* |x| */
+	u.i &= 0x7fffffff;
+	y = u.f;
+
+	if (u.i < 0x3f800000 - (1<<23)) {
+		if (u.i < 0x3f800000 - (32<<23)) {
+			/* handle underflow */
+			if (u.i < (1<<23))
+				FORCE_EVAL((float)(y*y));
+		} else {
+			/* |x| < 0.5, up to 1.7ulp error */
+			y = 0.5f*log1pf(2*y + 2*y*y/(1-y));
+		}
+	} else {
+		/* avoid overflow */
+		y = 0.5f*log1pf(2*(y/(1-y)));
+	}
+	return s ? -y : y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanhl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanhl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanhl.c	(revision 398)
@@ -0,0 +1,35 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double atanhl(long double x)
+{
+	return atanh(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
+long double atanhl(long double x)
+{
+	union ldshape u = {x};
+	unsigned e = u.i.se & 0x7fff;
+	unsigned s = u.i.se >> 15;
+
+	/* |x| */
+	u.i.se = e;
+	x = u.f;
+
+	if (e < 0x3ff - 1) {
+		if (e < 0x3ff - LDBL_MANT_DIG/2) {
+			/* handle underflow */
+			if (e == 0)
+				FORCE_EVAL((float)x);
+		} else {
+			/* |x| < 0.5, up to 1.7ulp error */
+			x = 0.5*log1pl(2*x + 2*x*x/(1-x));
+		}
+	} else {
+		/* avoid overflow */
+		x = 0.5*log1pl(2*(x/(1-x)));
+	}
+	return s ? -x : x;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/atanl.c	(revision 398)
@@ -0,0 +1,184 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_atanl.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * See comments in atan.c.
+ * Converted to long double by David Schultz <das@FreeBSD.ORG>.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double atanl(long double x)
+{
+	return atan(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+#if LDBL_MANT_DIG == 64
+#define EXPMAN(u) ((u.i.se & 0x7fff)<<8 | (u.i.m>>55 & 0xff))
+
+static const long double atanhi[] = {
+	 4.63647609000806116202e-01L,
+	 7.85398163397448309628e-01L,
+	 9.82793723247329067960e-01L,
+	 1.57079632679489661926e+00L,
+};
+
+static const long double atanlo[] = {
+	 1.18469937025062860669e-20L,
+	-1.25413940316708300586e-20L,
+	 2.55232234165405176172e-20L,
+	-2.50827880633416601173e-20L,
+};
+
+static const long double aT[] = {
+	 3.33333333333333333017e-01L,
+	-1.99999999999999632011e-01L,
+	 1.42857142857046531280e-01L,
+	-1.11111111100562372733e-01L,
+	 9.09090902935647302252e-02L,
+	-7.69230552476207730353e-02L,
+	 6.66661718042406260546e-02L,
+	-5.88158892835030888692e-02L,
+	 5.25499891539726639379e-02L,
+	-4.70119845393155721494e-02L,
+	 4.03539201366454414072e-02L,
+	-2.91303858419364158725e-02L,
+	 1.24822046299269234080e-02L,
+};
+
+static long double T_even(long double x)
+{
+	return aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] +
+		x * (aT[8] + x * (aT[10] + x * aT[12])))));
+}
+
+static long double T_odd(long double x)
+{
+	return aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] +
+		x * (aT[9] + x * aT[11]))));
+}
+#elif LDBL_MANT_DIG == 113
+#define EXPMAN(u) ((u.i.se & 0x7fff)<<8 | u.i.top>>8)
+
+const long double atanhi[] = {
+	 4.63647609000806116214256231461214397e-01L,
+	 7.85398163397448309615660845819875699e-01L,
+	 9.82793723247329067985710611014666038e-01L,
+	 1.57079632679489661923132169163975140e+00L,
+};
+
+const long double atanlo[] = {
+	 4.89509642257333492668618435220297706e-36L,
+	 2.16795253253094525619926100651083806e-35L,
+	-2.31288434538183565909319952098066272e-35L,
+	 4.33590506506189051239852201302167613e-35L,
+};
+
+const long double aT[] = {
+	 3.33333333333333333333333333333333125e-01L,
+	-1.99999999999999999999999999999180430e-01L,
+	 1.42857142857142857142857142125269827e-01L,
+	-1.11111111111111111111110834490810169e-01L,
+	 9.09090909090909090908522355708623681e-02L,
+	-7.69230769230769230696553844935357021e-02L,
+	 6.66666666666666660390096773046256096e-02L,
+	-5.88235294117646671706582985209643694e-02L,
+	 5.26315789473666478515847092020327506e-02L,
+	-4.76190476189855517021024424991436144e-02L,
+	 4.34782608678695085948531993458097026e-02L,
+	-3.99999999632663469330634215991142368e-02L,
+	 3.70370363987423702891250829918659723e-02L,
+	-3.44827496515048090726669907612335954e-02L,
+	 3.22579620681420149871973710852268528e-02L,
+	-3.03020767654269261041647570626778067e-02L,
+	 2.85641979882534783223403715930946138e-02L,
+	-2.69824879726738568189929461383741323e-02L,
+	 2.54194698498808542954187110873675769e-02L,
+	-2.35083879708189059926183138130183215e-02L,
+	 2.04832358998165364349957325067131428e-02L,
+	-1.54489555488544397858507248612362957e-02L,
+	 8.64492360989278761493037861575248038e-03L,
+	-2.58521121597609872727919154569765469e-03L,
+};
+
+static long double T_even(long double x)
+{
+	return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * (aT[8] +
+		x * (aT[10] + x * (aT[12] + x * (aT[14] + x * (aT[16] +
+		x * (aT[18] + x * (aT[20] + x * aT[22])))))))))));
+}
+
+static long double T_odd(long double x)
+{
+	return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * (aT[9] +
+		x * (aT[11] + x * (aT[13] + x * (aT[15] + x * (aT[17] +
+		x * (aT[19] + x * (aT[21] + x * aT[23])))))))))));
+}
+#endif
+
+long double atanl(long double x)
+{
+	union ldshape u = {x};
+	long double w, s1, s2, z;
+	int id;
+	unsigned e = u.i.se & 0x7fff;
+	unsigned sign = u.i.se >> 15;
+	unsigned expman;
+
+	if (e >= 0x3fff + LDBL_MANT_DIG + 1) { /* if |x| is large, atan(x)~=pi/2 */
+		if (isnan(x))
+			return x;
+		return sign ? -atanhi[3] : atanhi[3];
+	}
+	/* Extract the exponent and the first few bits of the mantissa. */
+	expman = EXPMAN(u);
+	if (expman < ((0x3fff - 2) << 8) + 0xc0) {  /* |x| < 0.4375 */
+		if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {   /* if |x| is small, atanl(x)~=x */
+			/* raise underflow if subnormal */
+			if (e == 0)
+				FORCE_EVAL((float)x);
+			return x;
+		}
+		id = -1;
+	} else {
+		x = fabsl(x);
+		if (expman < (0x3fff << 8) + 0x30) {  /* |x| < 1.1875 */
+			if (expman < ((0x3fff - 1) << 8) + 0x60) { /*  7/16 <= |x| < 11/16 */
+				id = 0;
+				x = (2.0*x-1.0)/(2.0+x);
+			} else {                                 /* 11/16 <= |x| < 19/16 */
+				id = 1;
+				x = (x-1.0)/(x+1.0);
+			}
+		} else {
+			if (expman < ((0x3fff + 1) << 8) + 0x38) { /* |x| < 2.4375 */
+				id = 2;
+				x = (x-1.5)/(1.0+1.5*x);
+			} else {                                 /* 2.4375 <= |x| */
+				id = 3;
+				x = -1.0/x;
+			}
+		}
+	}
+	/* end of argument reduction */
+	z = x*x;
+	w = z*z;
+	/* break sum aT[i]z**(i+1) into odd and even poly */
+	s1 = z*T_even(w);
+	s2 = w*T_odd(w);
+	if (id < 0)
+		return x - x*(s1+s2);
+	z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+	return sign ? -z : z;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cbrt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cbrt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cbrt.c	(revision 398)
@@ -0,0 +1,103 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrt.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ * Optimized by Bruce D. Evans.
+ */
+/* cbrt(x)
+ * Return cube root of x
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const uint32_t
+B1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */
+B2 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */
+
+/* |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]). */
+static const double
+P0 =  1.87595182427177009643,  /* 0x3ffe03e6, 0x0f61e692 */
+P1 = -1.88497979543377169875,  /* 0xbffe28e0, 0x92f02420 */
+P2 =  1.621429720105354466140, /* 0x3ff9f160, 0x4a49d6c2 */
+P3 = -0.758397934778766047437, /* 0xbfe844cb, 0xbee751d9 */
+P4 =  0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */
+
+double cbrt(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t r,s,t,w;
+	uint32_t hx = u.i>>32 & 0x7fffffff;
+
+	if (hx >= 0x7ff00000)  /* cbrt(NaN,INF) is itself */
+		return x+x;
+
+	/*
+	 * Rough cbrt to 5 bits:
+	 *    cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3)
+	 * where e is integral and >= 0, m is real and in [0, 1), and "/" and
+	 * "%" are integer division and modulus with rounding towards minus
+	 * infinity.  The RHS is always >= the LHS and has a maximum relative
+	 * error of about 1 in 16.  Adding a bias of -0.03306235651 to the
+	 * (e%3+m)/3 term reduces the error to about 1 in 32. With the IEEE
+	 * floating point representation, for finite positive normal values,
+	 * ordinary integer divison of the value in bits magically gives
+	 * almost exactly the RHS of the above provided we first subtract the
+	 * exponent bias (1023 for doubles) and later add it back.  We do the
+	 * subtraction virtually to keep e >= 0 so that ordinary integer
+	 * division rounds towards minus infinity; this is also efficient.
+	 */
+	if (hx < 0x00100000) { /* zero or subnormal? */
+		u.f = x*0x1p54;
+		hx = u.i>>32 & 0x7fffffff;
+		if (hx == 0)
+			return x;  /* cbrt(0) is itself */
+		hx = hx/3 + B2;
+	} else
+		hx = hx/3 + B1;
+	u.i &= 1ULL<<63;
+	u.i |= (uint64_t)hx << 32;
+	t = u.f;
+
+	/*
+	 * New cbrt to 23 bits:
+	 *    cbrt(x) = t*cbrt(x/t**3) ~= t*P(t**3/x)
+	 * where P(r) is a polynomial of degree 4 that approximates 1/cbrt(r)
+	 * to within 2**-23.5 when |r - 1| < 1/10.  The rough approximation
+	 * has produced t such than |t/cbrt(x) - 1| ~< 1/32, and cubing this
+	 * gives us bounds for r = t**3/x.
+	 *
+	 * Try to optimize for parallel evaluation as in __tanf.c.
+	 */
+	r = (t*t)*(t/x);
+	t = t*((P0+r*(P1+r*P2))+((r*r)*r)*(P3+r*P4));
+
+	/*
+	 * Round t away from zero to 23 bits (sloppily except for ensuring that
+	 * the result is larger in magnitude than cbrt(x) but not much more than
+	 * 2 23-bit ulps larger).  With rounding towards zero, the error bound
+	 * would be ~5/6 instead of ~4/6.  With a maximum error of 2 23-bit ulps
+	 * in the rounded t, the infinite-precision error in the Newton
+	 * approximation barely affects third digit in the final error
+	 * 0.667; the error in the rounded t can be up to about 3 23-bit ulps
+	 * before the final error is larger than 0.667 ulps.
+	 */
+	u.f = t;
+	u.i = (u.i + 0x80000000) & 0xffffffffc0000000ULL;
+	t = u.f;
+
+	/* one step Newton iteration to 53 bits with error < 0.667 ulps */
+	s = t*t;         /* t*t is exact */
+	r = x/s;         /* error <= 0.5 ulps; |r| < |t| */
+	w = t+t;         /* t+t is exact */
+	r = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */
+	t = t+t*r;       /* error <= 0.5 + 0.5/3 + epsilon */
+	return t;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cbrtf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cbrtf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cbrtf.c	(revision 398)
@@ -0,0 +1,66 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Debugged and optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* cbrtf(x)
+ * Return cube root of x
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const unsigned
+B1 = 709958130, /* B1 = (127-127.0/3-0.03306235651)*2**23 */
+B2 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */
+
+float cbrtf(float x)
+{
+	double_t r,T;
+	union {float f; uint32_t i;} u = {x};
+	uint32_t hx = u.i & 0x7fffffff;
+
+	if (hx >= 0x7f800000)  /* cbrt(NaN,INF) is itself */
+		return x + x;
+
+	/* rough cbrt to 5 bits */
+	if (hx < 0x00800000) {  /* zero or subnormal? */
+		if (hx == 0)
+			return x;  /* cbrt(+-0) is itself */
+		u.f = x*0x1p24f;
+		hx = u.i & 0x7fffffff;
+		hx = hx/3 + B2;
+	} else
+		hx = hx/3 + B1;
+	u.i &= 0x80000000;
+	u.i |= hx;
+
+	/*
+	 * First step Newton iteration (solving t*t-x/t == 0) to 16 bits.  In
+	 * double precision so that its terms can be arranged for efficiency
+	 * without causing overflow or underflow.
+	 */
+	T = u.f;
+	r = T*T*T;
+	T = T*((double_t)x+x+r)/(x+r+r);
+
+	/*
+	 * Second step Newton iteration to 47 bits.  In double precision for
+	 * efficiency and accuracy.
+	 */
+	r = T*T*T;
+	T = T*((double_t)x+x+r)/(x+r+r);
+
+	/* rounding to 24 bits is perfect in round-to-nearest mode */
+	return T;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cbrtl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cbrtl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cbrtl.c	(revision 398)
@@ -0,0 +1,124 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtl.c */
+/*-
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2009-2011, Bruce D. Evans, Steven G. Kargl, David Schultz.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ * The argument reduction and testing for exceptional cases was
+ * written by Steven G. Kargl with input from Bruce D. Evans
+ * and David A. Schultz.
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double cbrtl(long double x)
+{
+	return cbrt(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+static const unsigned B1 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */
+
+long double cbrtl(long double x)
+{
+	union ldshape u = {x}, v;
+	union {float f; uint32_t i;} uft;
+	long double r, s, t, w;
+	double_t dr, dt, dx;
+	float_t ft;
+	int e = u.i.se & 0x7fff;
+	int sign = u.i.se & 0x8000;
+
+	/*
+	 * If x = +-Inf, then cbrt(x) = +-Inf.
+	 * If x = NaN, then cbrt(x) = NaN.
+	 */
+	if (e == 0x7fff)
+		return x + x;
+	if (e == 0) {
+		/* Adjust subnormal numbers. */
+		u.f *= 0x1p120;
+		e = u.i.se & 0x7fff;
+		/* If x = +-0, then cbrt(x) = +-0. */
+		if (e == 0)
+			return x;
+		e -= 120;
+	}
+	e -= 0x3fff;
+	u.i.se = 0x3fff;
+	x = u.f;
+	switch (e % 3) {
+	case 1:
+	case -2:
+		x *= 2;
+		e--;
+		break;
+	case 2:
+	case -1:
+		x *= 4;
+		e -= 2;
+		break;
+	}
+	v.f = 1.0;
+	v.i.se = sign | (0x3fff + e/3);
+
+	/*
+	 * The following is the guts of s_cbrtf, with the handling of
+	 * special values removed and extra care for accuracy not taken,
+	 * but with most of the extra accuracy not discarded.
+	 */
+
+	/* ~5-bit estimate: */
+	uft.f = x;
+	uft.i = (uft.i & 0x7fffffff)/3 + B1;
+	ft = uft.f;
+
+	/* ~16-bit estimate: */
+	dx = x;
+	dt = ft;
+	dr = dt * dt * dt;
+	dt = dt * (dx + dx + dr) / (dx + dr + dr);
+
+	/* ~47-bit estimate: */
+	dr = dt * dt * dt;
+	dt = dt * (dx + dx + dr) / (dx + dr + dr);
+
+#if LDBL_MANT_DIG == 64
+	/*
+	 * dt is cbrtl(x) to ~47 bits (after x has been reduced to 1 <= x < 8).
+	 * Round it away from zero to 32 bits (32 so that t*t is exact, and
+	 * away from zero for technical reasons).
+	 */
+	t = dt + (0x1.0p32L + 0x1.0p-31L) - 0x1.0p32;
+#elif LDBL_MANT_DIG == 113
+	/*
+	 * Round dt away from zero to 47 bits.  Since we don't trust the 47,
+	 * add 2 47-bit ulps instead of 1 to round up.  Rounding is slow and
+	 * might be avoidable in this case, since on most machines dt will
+	 * have been evaluated in 53-bit precision and the technical reasons
+	 * for rounding up might not apply to either case in cbrtl() since
+	 * dt is much more accurate than needed.
+	 */
+	t = dt + 0x2.0p-46 + 0x1.0p60L - 0x1.0p60;
+#endif
+
+	/*
+	 * Final step Newton iteration to 64 or 113 bits with
+	 * error < 0.667 ulps
+	 */
+	s = t*t;         /* t*t is exact */
+	r = x/s;         /* error <= 0.5 ulps; |r| < |t| */
+	w = t+t;         /* t+t is exact */
+	r = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */
+	t = t+t*r;       /* error <= 0.5 + 0.5/3 + epsilon */
+
+	t *= v.f;
+	return t;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ceil.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ceil.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ceil.c	(revision 398)
@@ -0,0 +1,31 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const double_t toint = 1/EPS;
+
+double ceil(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i >> 52 & 0x7ff;
+	double_t y;
+
+	if (e >= 0x3ff+52 || x == 0)
+		return x;
+	/* y = int(x) - x, where int(x) is an integer neighbor of x */
+	if (u.i >> 63)
+		y = x - toint + toint - x;
+	else
+		y = x + toint - toint - x;
+	/* special case because of non-nearest rounding modes */
+	if (e <= 0x3ff-1) {
+		FORCE_EVAL(y);
+		return u.i >> 63 ? -0.0 : 1;
+	}
+	if (y < 0)
+		return x + y + 1;
+	return x + y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ceilf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ceilf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ceilf.c	(revision 398)
@@ -0,0 +1,27 @@
+#include "libm.h"
+
+float ceilf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = (int)(u.i >> 23 & 0xff) - 0x7f;
+	uint32_t m;
+
+	if (e >= 23)
+		return x;
+	if (e >= 0) {
+		m = 0x007fffff >> e;
+		if ((u.i & m) == 0)
+			return x;
+		FORCE_EVAL(x + 0x1p120f);
+		if (u.i >> 31 == 0)
+			u.i += m;
+		u.i &= ~m;
+	} else {
+		FORCE_EVAL(x + 0x1p120f);
+		if (u.i >> 31)
+			u.f = -0.0;
+		else if (u.i << 1)
+			u.f = 1.0;
+	}
+	return u.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ceill.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ceill.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ceill.c	(revision 398)
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double ceill(long double x)
+{
+	return ceil(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double ceill(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	long double y;
+
+	if (e >= 0x3fff+LDBL_MANT_DIG-1 || x == 0)
+		return x;
+	/* y = int(x) - x, where int(x) is an integer neighbor of x */
+	if (u.i.se >> 15)
+		y = x - toint + toint - x;
+	else
+		y = x + toint - toint - x;
+	/* special case because of non-nearest rounding modes */
+	if (e <= 0x3fff-1) {
+		FORCE_EVAL(y);
+		return u.i.se >> 15 ? -0.0 : 1;
+	}
+	if (y < 0)
+		return x + y + 1;
+	return x + y;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/copysign.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/copysign.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/copysign.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "libm.h"
+
+double copysign(double x, double y) {
+	union {double f; uint64_t i;} ux={x}, uy={y};
+	ux.i &= -1ULL/2;
+	ux.i |= uy.i & 1ULL<<63;
+	return ux.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/copysignf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/copysignf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/copysignf.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <math.h>
+#include <stdint.h>
+
+float copysignf(float x, float y)
+{
+	union {float f; uint32_t i;} ux={x}, uy={y};
+	ux.i &= 0x7fffffff;
+	ux.i |= uy.i & 0x80000000;
+	return ux.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/copysignl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/copysignl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/copysignl.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double copysignl(long double x, long double y)
+{
+	return copysign(x, y);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double copysignl(long double x, long double y)
+{
+	union ldshape ux = {x}, uy = {y};
+	ux.i.se &= 0x7fff;
+	ux.i.se |= uy.i.se & 0x8000;
+	return ux.f;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cos.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cos.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cos.c	(revision 398)
@@ -0,0 +1,77 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cos.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* cos(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ *      __sin           ... sine function on [-pi/4,pi/4]
+ *      __cos           ... cosine function on [-pi/4,pi/4]
+ *      __rem_pio2      ... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on
+ *      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ *      in [-pi/4 , +pi/4], and let n = k mod 4.
+ *      We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *          0          S           C             T
+ *          1          C          -S            -1/T
+ *          2         -S          -C             T
+ *          3         -C           S            -1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *      TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "libm.h"
+
+double cos(double x)
+{
+	double y[2];
+	uint32_t ix;
+	unsigned n;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+
+	/* |x| ~< pi/4 */
+	if (ix <= 0x3fe921fb) {
+		if (ix < 0x3e46a09e) {  /* |x| < 2**-27 * sqrt(2) */
+			/* raise inexact if x!=0 */
+			FORCE_EVAL(x + 0x1p120f);
+			return 1.0;
+		}
+		return __cos(x, 0);
+	}
+
+	/* cos(Inf or NaN) is NaN */
+	if (ix >= 0x7ff00000)
+		return x-x;
+
+	/* argument reduction */
+	n = __rem_pio2(x, y);
+	switch (n&3) {
+	case 0: return  __cos(y[0], y[1]);
+	case 1: return -__sin(y[0], y[1], 1);
+	case 2: return -__cos(y[0], y[1]);
+	default:
+		return  __sin(y[0], y[1], 1);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cosf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cosf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cosf.c	(revision 398)
@@ -0,0 +1,78 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_cosf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+/* Small multiples of pi/2 rounded to double precision. */
+static const double
+c1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
+c2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
+c3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
+c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
+
+float cosf(float x)
+{
+	double y;
+	uint32_t ix;
+	unsigned n, sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix >> 31;
+	ix &= 0x7fffffff;
+
+	if (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */
+		if (ix < 0x39800000) {  /* |x| < 2**-12 */
+			/* raise inexact if x != 0 */
+			FORCE_EVAL(x + 0x1p120f);
+			return 1.0f;
+		}
+		return __cosdf(x);
+	}
+	if (ix <= 0x407b53d1) {  /* |x| ~<= 5*pi/4 */
+		if (ix > 0x4016cbe3)  /* |x|  ~> 3*pi/4 */
+			return -__cosdf(sign ? x+c2pio2 : x-c2pio2);
+		else {
+			if (sign)
+				return __sindf(x + c1pio2);
+			else
+				return __sindf(c1pio2 - x);
+		}
+	}
+	if (ix <= 0x40e231d5) {  /* |x| ~<= 9*pi/4 */
+		if (ix > 0x40afeddf)  /* |x| ~> 7*pi/4 */
+			return __cosdf(sign ? x+c4pio2 : x-c4pio2);
+		else {
+			if (sign)
+				return __sindf(-x - c3pio2);
+			else
+				return __sindf(x - c3pio2);
+		}
+	}
+
+	/* cos(Inf or NaN) is NaN */
+	if (ix >= 0x7f800000)
+		return x-x;
+
+	/* general argument reduction needed */
+	n = __rem_pio2f(x,&y);
+	switch (n&3) {
+	case 0: return  __cosdf(y);
+	case 1: return  __sindf(-y);
+	case 2: return -__cosdf(y);
+	default:
+		return  __sindf(y);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cosh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cosh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cosh.c	(revision 398)
@@ -0,0 +1,40 @@
+#include "libm.h"
+
+/* cosh(x) = (exp(x) + 1/exp(x))/2
+ *         = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x)
+ *         = 1 + x*x/2 + o(x^4)
+ */
+double cosh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	uint32_t w;
+	double t;
+
+	/* |x| */
+	u.i &= (uint64_t)-1/2;
+	x = u.f;
+	w = u.i >> 32;
+
+	/* |x| < log(2) */
+	if (w < 0x3fe62e42) {
+		if (w < 0x3ff00000 - (26<<20)) {
+			/* raise inexact if x!=0 */
+			FORCE_EVAL(x + 0x1p120f);
+			return 1;
+		}
+		t = expm1(x);
+		return 1 + t*t/(2*(1+t));
+	}
+
+	/* |x| < log(DBL_MAX) */
+	if (w < 0x40862e42) {
+		t = exp(x);
+		/* note: if x>log(0x1p26) then the 1/t is not needed */
+		return 0.5*(t + 1/t);
+	}
+
+	/* |x| > log(DBL_MAX) or nan */
+	/* note: the result is stored to handle overflow */
+	t = __expo2(x);
+	return t;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/coshf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/coshf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/coshf.c	(revision 398)
@@ -0,0 +1,33 @@
+#include "libm.h"
+
+float coshf(float x)
+{
+	union {float f; uint32_t i;} u = {.f = x};
+	uint32_t w;
+	float t;
+
+	/* |x| */
+	u.i &= 0x7fffffff;
+	x = u.f;
+	w = u.i;
+
+	/* |x| < log(2) */
+	if (w < 0x3f317217) {
+		if (w < 0x3f800000 - (12<<23)) {
+			FORCE_EVAL(x + 0x1p120f);
+			return 1;
+		}
+		t = expm1f(x);
+		return 1 + t*t/(2*(1+t));
+	}
+
+	/* |x| < log(FLT_MAX) */
+	if (w < 0x42b17217) {
+		t = expf(x);
+		return 0.5f*(t + 1/t);
+	}
+
+	/* |x| > log(FLT_MAX) or nan */
+	t = __expo2f(x);
+	return t;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/coshl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/coshl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/coshl.c	(revision 398)
@@ -0,0 +1,47 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double coshl(long double x)
+{
+	return cosh(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+long double coshl(long double x)
+{
+	union ldshape u = {x};
+	unsigned ex = u.i.se & 0x7fff;
+	uint32_t w;
+	long double t;
+
+	/* |x| */
+	u.i.se = ex;
+	x = u.f;
+	w = u.i.m >> 32;
+
+	/* |x| < log(2) */
+	if (ex < 0x3fff-1 || (ex == 0x3fff-1 && w < 0xb17217f7)) {
+		if (ex < 0x3fff-32) {
+			FORCE_EVAL(x + 0x1p120f);
+			return 1;
+		}
+		t = expm1l(x);
+		return 1 + t*t/(2*(1+t));
+	}
+
+	/* |x| < log(LDBL_MAX) */
+	if (ex < 0x3fff+13 || (ex == 0x3fff+13 && w < 0xb17217f7)) {
+		t = expl(x);
+		return 0.5*(t + 1/t);
+	}
+
+	/* |x| > log(LDBL_MAX) or nan */
+	t = expl(0.5*x);
+	return 0.5*t*t;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double coshl(long double x)
+{
+	return cosh(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cosl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cosl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/cosl.c	(revision 398)
@@ -0,0 +1,39 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double cosl(long double x) {
+	return cos(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double cosl(long double x)
+{
+	union ldshape u = {x};
+	unsigned n;
+	long double y[2], hi, lo;
+
+	u.i.se &= 0x7fff;
+	if (u.i.se == 0x7fff)
+		return x - x;
+	x = u.f;
+	if (x < M_PI_4) {
+		if (u.i.se < 0x3fff - LDBL_MANT_DIG)
+			/* raise inexact if x!=0 */
+			return 1.0 + x;
+		return __cosl(x, 0);
+	}
+	n = __rem_pio2l(x, y);
+	hi = y[0];
+	lo = y[1];
+	switch (n & 3) {
+	case 0:
+		return __cosl(hi, lo);
+	case 1:
+		return -__sinl(hi, lo, 1);
+	case 2:
+		return -__cosl(hi, lo);
+	case 3:
+	default:
+		return __sinl(hi, lo, 1);
+	}
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/erf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/erf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/erf.c	(revision 398)
@@ -0,0 +1,273 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_erf.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* double erf(double x)
+ * double erfc(double x)
+ *                           x
+ *                    2      |\
+ *     erf(x)  =  ---------  | exp(-t*t)dt
+ *                 sqrt(pi) \|
+ *                           0
+ *
+ *     erfc(x) =  1-erf(x)
+ *  Note that
+ *              erf(-x) = -erf(x)
+ *              erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ *      1. For |x| in [0, 0.84375]
+ *          erf(x)  = x + x*R(x^2)
+ *          erfc(x) = 1 - erf(x)           if x in [-.84375,0.25]
+ *                  = 0.5 + ((0.5-x)-x*R)  if x in [0.25,0.84375]
+ *         where R = P/Q where P is an odd poly of degree 8 and
+ *         Q is an odd poly of degree 10.
+ *                                               -57.90
+ *                      | R - (erf(x)-x)/x | <= 2
+ *
+ *
+ *         Remark. The formula is derived by noting
+ *          erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ *         and that
+ *          2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ *         is close to one. The interval is chosen because the fix
+ *         point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
+ *         near 0.6174), and by some experiment, 0.84375 is chosen to
+ *         guarantee the error is less than one ulp for erf.
+ *
+ *      2. For |x| in [0.84375,1.25], let s = |x| - 1, and
+ *         c = 0.84506291151 rounded to single (24 bits)
+ *              erf(x)  = sign(x) * (c  + P1(s)/Q1(s))
+ *              erfc(x) = (1-c)  - P1(s)/Q1(s) if x > 0
+ *                        1+(c+P1(s)/Q1(s))    if x < 0
+ *              |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
+ *         Remark: here we use the taylor series expansion at x=1.
+ *              erf(1+s) = erf(1) + s*Poly(s)
+ *                       = 0.845.. + P1(s)/Q1(s)
+ *         That is, we use rational approximation to approximate
+ *                      erf(1+s) - (c = (single)0.84506291151)
+ *         Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ *         where
+ *              P1(s) = degree 6 poly in s
+ *              Q1(s) = degree 6 poly in s
+ *
+ *      3. For x in [1.25,1/0.35(~2.857143)],
+ *              erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
+ *              erf(x)  = 1 - erfc(x)
+ *         where
+ *              R1(z) = degree 7 poly in z, (z=1/x^2)
+ *              S1(z) = degree 8 poly in z
+ *
+ *      4. For x in [1/0.35,28]
+ *              erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
+ *                      = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
+ *                      = 2.0 - tiny            (if x <= -6)
+ *              erf(x)  = sign(x)*(1.0 - erfc(x)) if x < 6, else
+ *              erf(x)  = sign(x)*(1.0 - tiny)
+ *         where
+ *              R2(z) = degree 6 poly in z, (z=1/x^2)
+ *              S2(z) = degree 7 poly in z
+ *
+ *      Note1:
+ *         To compute exp(-x*x-0.5625+R/S), let s be a single
+ *         precision number and s := x; then
+ *              -x*x = -s*s + (s-x)*(s+x)
+ *              exp(-x*x-0.5626+R/S) =
+ *                      exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ *      Note2:
+ *         Here 4 and 5 make use of the asymptotic series
+ *                        exp(-x*x)
+ *              erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ *                        x*sqrt(pi)
+ *         We use rational approximation to approximate
+ *              g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
+ *         Here is the error bound for R1/S1 and R2/S2
+ *              |R1/S1 - f(x)|  < 2**(-62.57)
+ *              |R2/S2 - f(x)|  < 2**(-61.52)
+ *
+ *      5. For inf > x >= 28
+ *              erf(x)  = sign(x) *(1 - tiny)  (raise inexact)
+ *              erfc(x) = tiny*tiny (raise underflow) if x > 0
+ *                      = 2 - tiny if x<0
+ *
+ *      7. Special case:
+ *              erf(0)  = 0, erf(inf)  = 1, erf(-inf) = -1,
+ *              erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ *              erfc/erf(NaN) is NaN
+ */
+
+#include "libm.h"
+
+static const double
+erx  = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
+/*
+ * Coefficients for approximation to  erf on [0,0.84375]
+ */
+efx8 =  1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
+pp0  =  1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
+pp1  = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
+pp2  = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
+pp3  = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
+pp4  = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */
+qq1  =  3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
+qq2  =  6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
+qq3  =  5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
+qq4  =  1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
+qq5  = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */
+/*
+ * Coefficients for approximation to  erf  in [0.84375,1.25]
+ */
+pa0  = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
+pa1  =  4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
+pa2  = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
+pa3  =  3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
+pa4  = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
+pa5  =  3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
+pa6  = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */
+qa1  =  1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
+qa2  =  5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
+qa3  =  7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
+qa4  =  1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
+qa5  =  1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
+qa6  =  1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */
+/*
+ * Coefficients for approximation to  erfc in [1.25,1/0.35]
+ */
+ra0  = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
+ra1  = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
+ra2  = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
+ra3  = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
+ra4  = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
+ra5  = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
+ra6  = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
+ra7  = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */
+sa1  =  1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
+sa2  =  1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
+sa3  =  4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
+sa4  =  6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
+sa5  =  4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
+sa6  =  1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
+sa7  =  6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
+sa8  = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */
+/*
+ * Coefficients for approximation to  erfc in [1/.35,28]
+ */
+rb0  = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
+rb1  = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
+rb2  = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
+rb3  = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
+rb4  = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
+rb5  = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
+rb6  = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */
+sb1  =  3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
+sb2  =  3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
+sb3  =  1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
+sb4  =  3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
+sb5  =  2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
+sb6  =  4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
+sb7  = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */
+
+static double erfc1(double x)
+{
+	double_t s,P,Q;
+
+	s = fabs(x) - 1;
+	P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+	Q = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+	return 1 - erx - P/Q;
+}
+
+static double erfc2(uint32_t ix, double x)
+{
+	double_t s,R,S;
+	double z;
+
+	if (ix < 0x3ff40000)  /* |x| < 1.25 */
+		return erfc1(x);
+
+	x = fabs(x);
+	s = 1/(x*x);
+	if (ix < 0x4006db6d) {  /* |x| < 1/.35 ~ 2.85714 */
+		R = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+		     ra5+s*(ra6+s*ra7))))));
+		S = 1.0+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+		     sa5+s*(sa6+s*(sa7+s*sa8)))))));
+	} else {                /* |x| > 1/.35 */
+		R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+		     rb5+s*rb6)))));
+		S = 1.0+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+		     sb5+s*(sb6+s*sb7))))));
+	}
+	z = x;
+	SET_LOW_WORD(z,0);
+	return exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S)/x;
+}
+
+double erf(double x)
+{
+	double r,s,z,y;
+	uint32_t ix;
+	int sign;
+
+	GET_HIGH_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7ff00000) {
+		/* erf(nan)=nan, erf(+-inf)=+-1 */
+		return 1-2*sign + 1/x;
+	}
+	if (ix < 0x3feb0000) {  /* |x| < 0.84375 */
+		if (ix < 0x3e300000) {  /* |x| < 2**-28 */
+			/* avoid underflow */
+			return 0.125*(8*x + efx8*x);
+		}
+		z = x*x;
+		r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+		s = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+		y = r/s;
+		return x + x*y;
+	}
+	if (ix < 0x40180000)  /* 0.84375 <= |x| < 6 */
+		y = 1 - erfc2(ix,x);
+	else
+		y = 1 - 0x1p-1022;
+	return sign ? -y : y;
+}
+
+double erfc(double x)
+{
+	double r,s,z,y;
+	uint32_t ix;
+	int sign;
+
+	GET_HIGH_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7ff00000) {
+		/* erfc(nan)=nan, erfc(+-inf)=0,2 */
+		return 2*sign + 1/x;
+	}
+	if (ix < 0x3feb0000) {  /* |x| < 0.84375 */
+		if (ix < 0x3c700000)  /* |x| < 2**-56 */
+			return 1.0 - x;
+		z = x*x;
+		r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+		s = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+		y = r/s;
+		if (sign || ix < 0x3fd00000) {  /* x < 1/4 */
+			return 1.0 - (x+x*y);
+		}
+		return 0.5 - (x - 0.5 + x*y);
+	}
+	if (ix < 0x403c0000) {  /* 0.84375 <= |x| < 28 */
+		return sign ? 2 - erfc2(ix,x) : erfc2(ix,x);
+	}
+	return sign ? 2 - 0x1p-1022 : 0x1p-1022*0x1p-1022;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/erff.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/erff.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/erff.c	(revision 398)
@@ -0,0 +1,183 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_erff.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+erx  =  8.4506291151e-01, /* 0x3f58560b */
+/*
+ * Coefficients for approximation to  erf on [0,0.84375]
+ */
+efx8 =  1.0270333290e+00, /* 0x3f8375d4 */
+pp0  =  1.2837916613e-01, /* 0x3e0375d4 */
+pp1  = -3.2504209876e-01, /* 0xbea66beb */
+pp2  = -2.8481749818e-02, /* 0xbce9528f */
+pp3  = -5.7702702470e-03, /* 0xbbbd1489 */
+pp4  = -2.3763017452e-05, /* 0xb7c756b1 */
+qq1  =  3.9791721106e-01, /* 0x3ecbbbce */
+qq2  =  6.5022252500e-02, /* 0x3d852a63 */
+qq3  =  5.0813062117e-03, /* 0x3ba68116 */
+qq4  =  1.3249473704e-04, /* 0x390aee49 */
+qq5  = -3.9602282413e-06, /* 0xb684e21a */
+/*
+ * Coefficients for approximation to  erf  in [0.84375,1.25]
+ */
+pa0  = -2.3621185683e-03, /* 0xbb1acdc6 */
+pa1  =  4.1485610604e-01, /* 0x3ed46805 */
+pa2  = -3.7220788002e-01, /* 0xbebe9208 */
+pa3  =  3.1834661961e-01, /* 0x3ea2fe54 */
+pa4  = -1.1089469492e-01, /* 0xbde31cc2 */
+pa5  =  3.5478305072e-02, /* 0x3d1151b3 */
+pa6  = -2.1663755178e-03, /* 0xbb0df9c0 */
+qa1  =  1.0642088205e-01, /* 0x3dd9f331 */
+qa2  =  5.4039794207e-01, /* 0x3f0a5785 */
+qa3  =  7.1828655899e-02, /* 0x3d931ae7 */
+qa4  =  1.2617121637e-01, /* 0x3e013307 */
+qa5  =  1.3637083583e-02, /* 0x3c5f6e13 */
+qa6  =  1.1984500103e-02, /* 0x3c445aa3 */
+/*
+ * Coefficients for approximation to  erfc in [1.25,1/0.35]
+ */
+ra0  = -9.8649440333e-03, /* 0xbc21a093 */
+ra1  = -6.9385856390e-01, /* 0xbf31a0b7 */
+ra2  = -1.0558626175e+01, /* 0xc128f022 */
+ra3  = -6.2375331879e+01, /* 0xc2798057 */
+ra4  = -1.6239666748e+02, /* 0xc322658c */
+ra5  = -1.8460508728e+02, /* 0xc3389ae7 */
+ra6  = -8.1287437439e+01, /* 0xc2a2932b */
+ra7  = -9.8143291473e+00, /* 0xc11d077e */
+sa1  =  1.9651271820e+01, /* 0x419d35ce */
+sa2  =  1.3765776062e+02, /* 0x4309a863 */
+sa3  =  4.3456588745e+02, /* 0x43d9486f */
+sa4  =  6.4538726807e+02, /* 0x442158c9 */
+sa5  =  4.2900814819e+02, /* 0x43d6810b */
+sa6  =  1.0863500214e+02, /* 0x42d9451f */
+sa7  =  6.5702495575e+00, /* 0x40d23f7c */
+sa8  = -6.0424413532e-02, /* 0xbd777f97 */
+/*
+ * Coefficients for approximation to  erfc in [1/.35,28]
+ */
+rb0  = -9.8649431020e-03, /* 0xbc21a092 */
+rb1  = -7.9928326607e-01, /* 0xbf4c9dd4 */
+rb2  = -1.7757955551e+01, /* 0xc18e104b */
+rb3  = -1.6063638306e+02, /* 0xc320a2ea */
+rb4  = -6.3756646729e+02, /* 0xc41f6441 */
+rb5  = -1.0250950928e+03, /* 0xc480230b */
+rb6  = -4.8351919556e+02, /* 0xc3f1c275 */
+sb1  =  3.0338060379e+01, /* 0x41f2b459 */
+sb2  =  3.2579251099e+02, /* 0x43a2e571 */
+sb3  =  1.5367296143e+03, /* 0x44c01759 */
+sb4  =  3.1998581543e+03, /* 0x4547fdbb */
+sb5  =  2.5530502930e+03, /* 0x451f90ce */
+sb6  =  4.7452853394e+02, /* 0x43ed43a7 */
+sb7  = -2.2440952301e+01; /* 0xc1b38712 */
+
+static float erfc1(float x)
+{
+	float_t s,P,Q;
+
+	s = fabsf(x) - 1;
+	P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+	Q = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+	return 1 - erx - P/Q;
+}
+
+static float erfc2(uint32_t ix, float x)
+{
+	float_t s,R,S;
+	float z;
+
+	if (ix < 0x3fa00000)  /* |x| < 1.25 */
+		return erfc1(x);
+
+	x = fabsf(x);
+	s = 1/(x*x);
+	if (ix < 0x4036db6d) {   /* |x| < 1/0.35 */
+		R = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+		     ra5+s*(ra6+s*ra7))))));
+		S = 1.0f+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+		     sa5+s*(sa6+s*(sa7+s*sa8)))))));
+	} else {                 /* |x| >= 1/0.35 */
+		R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+		     rb5+s*rb6)))));
+		S = 1.0f+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+		     sb5+s*(sb6+s*sb7))))));
+	}
+	GET_FLOAT_WORD(ix, x);
+	SET_FLOAT_WORD(z, ix&0xffffe000);
+	return expf(-z*z - 0.5625f) * expf((z-x)*(z+x) + R/S)/x;
+}
+
+float erff(float x)
+{
+	float r,s,z,y;
+	uint32_t ix;
+	int sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7f800000) {
+		/* erf(nan)=nan, erf(+-inf)=+-1 */
+		return 1-2*sign + 1/x;
+	}
+	if (ix < 0x3f580000) {  /* |x| < 0.84375 */
+		if (ix < 0x31800000) {  /* |x| < 2**-28 */
+			/*avoid underflow */
+			return 0.125f*(8*x + efx8*x);
+		}
+		z = x*x;
+		r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+		s = 1+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+		y = r/s;
+		return x + x*y;
+	}
+	if (ix < 0x40c00000)  /* |x| < 6 */
+		y = 1 - erfc2(ix,x);
+	else
+		y = 1 - 0x1p-120f;
+	return sign ? -y : y;
+}
+
+float erfcf(float x)
+{
+	float r,s,z,y;
+	uint32_t ix;
+	int sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7f800000) {
+		/* erfc(nan)=nan, erfc(+-inf)=0,2 */
+		return 2*sign + 1/x;
+	}
+
+	if (ix < 0x3f580000) {  /* |x| < 0.84375 */
+		if (ix < 0x23800000)  /* |x| < 2**-56 */
+			return 1.0f - x;
+		z = x*x;
+		r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+		s = 1.0f+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+		y = r/s;
+		if (sign || ix < 0x3e800000)  /* x < 1/4 */
+			return 1.0f - (x+x*y);
+		return 0.5f - (x - 0.5f + x*y);
+	}
+	if (ix < 0x41e00000) {  /* |x| < 28 */
+		return sign ? 2 - erfc2(ix,x) : erfc2(ix,x);
+	}
+	return sign ? 2 - 0x1p-120f : 0x1p-120f*0x1p-120f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/erfl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/erfl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/erfl.c	(revision 398)
@@ -0,0 +1,353 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_erfl.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/* double erf(double x)
+ * double erfc(double x)
+ *                           x
+ *                    2      |\
+ *     erf(x)  =  ---------  | exp(-t*t)dt
+ *                 sqrt(pi) \|
+ *                           0
+ *
+ *     erfc(x) =  1-erf(x)
+ *  Note that
+ *              erf(-x) = -erf(x)
+ *              erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ *      1. For |x| in [0, 0.84375]
+ *          erf(x)  = x + x*R(x^2)
+ *          erfc(x) = 1 - erf(x)           if x in [-.84375,0.25]
+ *                  = 0.5 + ((0.5-x)-x*R)  if x in [0.25,0.84375]
+ *         Remark. The formula is derived by noting
+ *          erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ *         and that
+ *          2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ *         is close to one. The interval is chosen because the fix
+ *         point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
+ *         near 0.6174), and by some experiment, 0.84375 is chosen to
+ *         guarantee the error is less than one ulp for erf.
+ *
+ *      2. For |x| in [0.84375,1.25], let s = |x| - 1, and
+ *         c = 0.84506291151 rounded to single (24 bits)
+ *      erf(x)  = sign(x) * (c  + P1(s)/Q1(s))
+ *      erfc(x) = (1-c)  - P1(s)/Q1(s) if x > 0
+ *                        1+(c+P1(s)/Q1(s))    if x < 0
+ *         Remark: here we use the taylor series expansion at x=1.
+ *              erf(1+s) = erf(1) + s*Poly(s)
+ *                       = 0.845.. + P1(s)/Q1(s)
+ *         Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ *
+ *      3. For x in [1.25,1/0.35(~2.857143)],
+ *      erfc(x) = (1/x)*exp(-x*x-0.5625+R1(z)/S1(z))
+ *              z=1/x^2
+ *      erf(x)  = 1 - erfc(x)
+ *
+ *      4. For x in [1/0.35,107]
+ *      erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
+ *                      = 2.0 - (1/x)*exp(-x*x-0.5625+R2(z)/S2(z))
+ *                             if -6.666<x<0
+ *                      = 2.0 - tiny            (if x <= -6.666)
+ *              z=1/x^2
+ *      erf(x)  = sign(x)*(1.0 - erfc(x)) if x < 6.666, else
+ *      erf(x)  = sign(x)*(1.0 - tiny)
+ *      Note1:
+ *         To compute exp(-x*x-0.5625+R/S), let s be a single
+ *         precision number and s := x; then
+ *              -x*x = -s*s + (s-x)*(s+x)
+ *              exp(-x*x-0.5626+R/S) =
+ *                      exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ *      Note2:
+ *         Here 4 and 5 make use of the asymptotic series
+ *                        exp(-x*x)
+ *              erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ *                        x*sqrt(pi)
+ *
+ *      5. For inf > x >= 107
+ *      erf(x)  = sign(x) *(1 - tiny)  (raise inexact)
+ *      erfc(x) = tiny*tiny (raise underflow) if x > 0
+ *                      = 2 - tiny if x<0
+ *
+ *      7. Special case:
+ *      erf(0)  = 0, erf(inf)  = 1, erf(-inf) = -1,
+ *      erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ *              erfc/erf(NaN) is NaN
+ */
+
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double erfl(long double x)
+{
+	return erf(x);
+}
+long double erfcl(long double x)
+{
+	return erfc(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+static const long double
+erx = 0.845062911510467529296875L,
+
+/*
+ * Coefficients for approximation to  erf on [0,0.84375]
+ */
+/* 8 * (2/sqrt(pi) - 1) */
+efx8 = 1.0270333367641005911692712249723613735048E0L,
+pp[6] = {
+	1.122751350964552113068262337278335028553E6L,
+	-2.808533301997696164408397079650699163276E6L,
+	-3.314325479115357458197119660818768924100E5L,
+	-6.848684465326256109712135497895525446398E4L,
+	-2.657817695110739185591505062971929859314E3L,
+	-1.655310302737837556654146291646499062882E2L,
+},
+qq[6] = {
+	8.745588372054466262548908189000448124232E6L,
+	3.746038264792471129367533128637019611485E6L,
+	7.066358783162407559861156173539693900031E5L,
+	7.448928604824620999413120955705448117056E4L,
+	4.511583986730994111992253980546131408924E3L,
+	1.368902937933296323345610240009071254014E2L,
+	/* 1.000000000000000000000000000000000000000E0 */
+},
+
+/*
+ * Coefficients for approximation to  erf  in [0.84375,1.25]
+ */
+/* erf(x+1) = 0.845062911510467529296875 + pa(x)/qa(x)
+   -0.15625 <= x <= +.25
+   Peak relative error 8.5e-22  */
+pa[8] = {
+	-1.076952146179812072156734957705102256059E0L,
+	 1.884814957770385593365179835059971587220E2L,
+	-5.339153975012804282890066622962070115606E1L,
+	 4.435910679869176625928504532109635632618E1L,
+	 1.683219516032328828278557309642929135179E1L,
+	-2.360236618396952560064259585299045804293E0L,
+	 1.852230047861891953244413872297940938041E0L,
+	 9.394994446747752308256773044667843200719E-2L,
+},
+qa[7] =  {
+	4.559263722294508998149925774781887811255E2L,
+	3.289248982200800575749795055149780689738E2L,
+	2.846070965875643009598627918383314457912E2L,
+	1.398715859064535039433275722017479994465E2L,
+	6.060190733759793706299079050985358190726E1L,
+	2.078695677795422351040502569964299664233E1L,
+	4.641271134150895940966798357442234498546E0L,
+	/* 1.000000000000000000000000000000000000000E0 */
+},
+
+/*
+ * Coefficients for approximation to  erfc in [1.25,1/0.35]
+ */
+/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + ra(x^2)/sa(x^2))
+   1/2.85711669921875 < 1/x < 1/1.25
+   Peak relative error 3.1e-21  */
+ra[] = {
+	1.363566591833846324191000679620738857234E-1L,
+	1.018203167219873573808450274314658434507E1L,
+	1.862359362334248675526472871224778045594E2L,
+	1.411622588180721285284945138667933330348E3L,
+	5.088538459741511988784440103218342840478E3L,
+	8.928251553922176506858267311750789273656E3L,
+	7.264436000148052545243018622742770549982E3L,
+	2.387492459664548651671894725748959751119E3L,
+	2.220916652813908085449221282808458466556E2L,
+},
+sa[] = {
+	-1.382234625202480685182526402169222331847E1L,
+	-3.315638835627950255832519203687435946482E2L,
+	-2.949124863912936259747237164260785326692E3L,
+	-1.246622099070875940506391433635999693661E4L,
+	-2.673079795851665428695842853070996219632E4L,
+	-2.880269786660559337358397106518918220991E4L,
+	-1.450600228493968044773354186390390823713E4L,
+	-2.874539731125893533960680525192064277816E3L,
+	-1.402241261419067750237395034116942296027E2L,
+	/* 1.000000000000000000000000000000000000000E0 */
+},
+
+/*
+ * Coefficients for approximation to  erfc in [1/.35,107]
+ */
+/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rb(x^2)/sb(x^2))
+   1/6.6666259765625 < 1/x < 1/2.85711669921875
+   Peak relative error 4.2e-22  */
+rb[] = {
+	-4.869587348270494309550558460786501252369E-5L,
+	-4.030199390527997378549161722412466959403E-3L,
+	-9.434425866377037610206443566288917589122E-2L,
+	-9.319032754357658601200655161585539404155E-1L,
+	-4.273788174307459947350256581445442062291E0L,
+	-8.842289940696150508373541814064198259278E0L,
+	-7.069215249419887403187988144752613025255E0L,
+	-1.401228723639514787920274427443330704764E0L,
+},
+sb[] = {
+	4.936254964107175160157544545879293019085E-3L,
+	1.583457624037795744377163924895349412015E-1L,
+	1.850647991850328356622940552450636420484E0L,
+	9.927611557279019463768050710008450625415E0L,
+	2.531667257649436709617165336779212114570E1L,
+	2.869752886406743386458304052862814690045E1L,
+	1.182059497870819562441683560749192539345E1L,
+	/* 1.000000000000000000000000000000000000000E0 */
+},
+/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rc(x^2)/sc(x^2))
+   1/107 <= 1/x <= 1/6.6666259765625
+   Peak relative error 1.1e-21  */
+rc[] = {
+	-8.299617545269701963973537248996670806850E-5L,
+	-6.243845685115818513578933902532056244108E-3L,
+	-1.141667210620380223113693474478394397230E-1L,
+	-7.521343797212024245375240432734425789409E-1L,
+	-1.765321928311155824664963633786967602934E0L,
+	-1.029403473103215800456761180695263439188E0L,
+},
+sc[] = {
+	8.413244363014929493035952542677768808601E-3L,
+	2.065114333816877479753334599639158060979E-1L,
+	1.639064941530797583766364412782135680148E0L,
+	4.936788463787115555582319302981666347450E0L,
+	5.005177727208955487404729933261347679090E0L,
+	/* 1.000000000000000000000000000000000000000E0 */
+};
+
+static long double erfc1(long double x)
+{
+	long double s,P,Q;
+
+	s = fabsl(x) - 1;
+	P = pa[0] + s * (pa[1] + s * (pa[2] +
+	     s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7]))))));
+	Q = qa[0] + s * (qa[1] + s * (qa[2] +
+	     s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s))))));
+	return 1 - erx - P / Q;
+}
+
+static long double erfc2(uint32_t ix, long double x)
+{
+	union ldshape u;
+	long double s,z,R,S;
+
+	if (ix < 0x3fffa000)  /* 0.84375 <= |x| < 1.25 */
+		return erfc1(x);
+
+	x = fabsl(x);
+	s = 1 / (x * x);
+	if (ix < 0x4000b6db) {  /* 1.25 <= |x| < 2.857 ~ 1/.35 */
+		R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] +
+		     s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8])))))));
+		S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] +
+		     s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s))))))));
+	} else if (ix < 0x4001d555) {  /* 2.857 <= |x| < 6.6666259765625 */
+		R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] +
+		     s * (rb[5] + s * (rb[6] + s * rb[7]))))));
+		S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] +
+		     s * (sb[5] + s * (sb[6] + s))))));
+	} else { /* 6.666 <= |x| < 107 (erfc only) */
+		R = rc[0] + s * (rc[1] + s * (rc[2] + s * (rc[3] +
+		     s * (rc[4] + s * rc[5]))));
+		S = sc[0] + s * (sc[1] + s * (sc[2] + s * (sc[3] +
+		     s * (sc[4] + s))));
+	}
+	u.f = x;
+	u.i.m &= -1ULL << 40;
+	z = u.f;
+	return expl(-z*z - 0.5625) * expl((z - x) * (z + x) + R / S) / x;
+}
+
+long double erfl(long double x)
+{
+	long double r, s, z, y;
+	union ldshape u = {x};
+	uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
+	int sign = u.i.se >> 15;
+
+	if (ix >= 0x7fff0000)
+		/* erf(nan)=nan, erf(+-inf)=+-1 */
+		return 1 - 2*sign + 1/x;
+	if (ix < 0x3ffed800) {  /* |x| < 0.84375 */
+		if (ix < 0x3fde8000) {  /* |x| < 2**-33 */
+			return 0.125 * (8 * x + efx8 * x);  /* avoid underflow */
+		}
+		z = x * x;
+		r = pp[0] + z * (pp[1] +
+		     z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5]))));
+		s = qq[0] + z * (qq[1] +
+		     z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z)))));
+		y = r / s;
+		return x + x * y;
+	}
+	if (ix < 0x4001d555)  /* |x| < 6.6666259765625 */
+		y = 1 - erfc2(ix,x);
+	else
+		y = 1 - 0x1p-16382L;
+	return sign ? -y : y;
+}
+
+long double erfcl(long double x)
+{
+	long double r, s, z, y;
+	union ldshape u = {x};
+	uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
+	int sign = u.i.se >> 15;
+
+	if (ix >= 0x7fff0000)
+		/* erfc(nan) = nan, erfc(+-inf) = 0,2 */
+		return 2*sign + 1/x;
+	if (ix < 0x3ffed800) {  /* |x| < 0.84375 */
+		if (ix < 0x3fbe0000)  /* |x| < 2**-65 */
+			return 1.0 - x;
+		z = x * x;
+		r = pp[0] + z * (pp[1] +
+		     z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5]))));
+		s = qq[0] + z * (qq[1] +
+		     z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z)))));
+		y = r / s;
+		if (ix < 0x3ffd8000) /* x < 1/4 */
+			return 1.0 - (x + x * y);
+		return 0.5 - (x - 0.5 + x * y);
+	}
+	if (ix < 0x4005d600)  /* |x| < 107 */
+		return sign ? 2 - erfc2(ix,x) : erfc2(ix,x);
+	y = 0x1p-16382L;
+	return sign ? 2 - y : y*y;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double erfl(long double x)
+{
+	return erf(x);
+}
+long double erfcl(long double x)
+{
+	return erfc(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp.c	(revision 398)
@@ -0,0 +1,134 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_exp.c */
+/*
+ * ====================================================
+ * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* exp(x)
+ * Returns the exponential of x.
+ *
+ * Method
+ *   1. Argument reduction:
+ *      Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
+ *      Given x, find r and integer k such that
+ *
+ *               x = k*ln2 + r,  |r| <= 0.5*ln2.
+ *
+ *      Here r will be represented as r = hi-lo for better
+ *      accuracy.
+ *
+ *   2. Approximation of exp(r) by a special rational function on
+ *      the interval [0,0.34658]:
+ *      Write
+ *          R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
+ *      We use a special Remez algorithm on [0,0.34658] to generate
+ *      a polynomial of degree 5 to approximate R. The maximum error
+ *      of this polynomial approximation is bounded by 2**-59. In
+ *      other words,
+ *          R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
+ *      (where z=r*r, and the values of P1 to P5 are listed below)
+ *      and
+ *          |                  5          |     -59
+ *          | 2.0+P1*z+...+P5*z   -  R(z) | <= 2
+ *          |                             |
+ *      The computation of exp(r) thus becomes
+ *                              2*r
+ *              exp(r) = 1 + ----------
+ *                            R(r) - r
+ *                                 r*c(r)
+ *                     = 1 + r + ----------- (for better accuracy)
+ *                                2 - c(r)
+ *      where
+ *                              2       4             10
+ *              c(r) = r - (P1*r  + P2*r  + ... + P5*r   ).
+ *
+ *   3. Scale back to obtain exp(x):
+ *      From step 1, we have
+ *         exp(x) = 2^k * exp(r)
+ *
+ * Special cases:
+ *      exp(INF) is INF, exp(NaN) is NaN;
+ *      exp(-INF) is 0, and
+ *      for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ *      according to an error analysis, the error is always less than
+ *      1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ *      For IEEE double
+ *          if x >  709.782712893383973096 then exp(x) overflows
+ *          if x < -745.133219101941108420 then exp(x) underflows
+ */
+
+#include "libm.h"
+
+static const double
+half[2] = {0.5,-0.5},
+ln2hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
+ln2lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
+invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
+P1   =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2   = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3   =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4   = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5   =  4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
+
+double exp(double x)
+{
+	double_t hi, lo, c, xx, y;
+	int k, sign;
+	uint32_t hx;
+
+	GET_HIGH_WORD(hx, x);
+	sign = hx>>31;
+	hx &= 0x7fffffff;  /* high word of |x| */
+
+	/* special cases */
+	if (hx >= 0x4086232b) {  /* if |x| >= 708.39... */
+		if (isnan(x))
+			return x;
+		if (x > 709.782712893383973096) {
+			/* overflow if x!=inf */
+			x *= 0x1p1023;
+			return x;
+		}
+		if (x < -708.39641853226410622) {
+			/* underflow if x!=-inf */
+			FORCE_EVAL((float)(-0x1p-149/x));
+			if (x < -745.13321910194110842)
+				return 0;
+		}
+	}
+
+	/* argument reduction */
+	if (hx > 0x3fd62e42) {  /* if |x| > 0.5 ln2 */
+		if (hx >= 0x3ff0a2b2)  /* if |x| >= 1.5 ln2 */
+			k = (int)(invln2*x + half[sign]);
+		else
+			k = 1 - sign - sign;
+		hi = x - k*ln2hi;  /* k*ln2hi is exact here */
+		lo = k*ln2lo;
+		x = hi - lo;
+	} else if (hx > 0x3e300000)  {  /* if |x| > 2**-28 */
+		k = 0;
+		hi = x;
+		lo = 0;
+	} else {
+		/* inexact if x!=0 */
+		FORCE_EVAL(0x1p1023 + x);
+		return 1 + x;
+	}
+
+	/* x is now in primary range */
+	xx = x*x;
+	c = x - xx*(P1+xx*(P2+xx*(P3+xx*(P4+xx*P5))));
+	y = 1 + (x*c/(2-c) - lo + hi);
+	if (k == 0)
+		return y;
+	return scalbn(y, k);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp10.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp10.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp10.c	(revision 398)
@@ -0,0 +1,25 @@
+#define _GNU_SOURCE
+#include <math.h>
+#include <stdint.h>
+#include "libc.h"
+
+double exp10(double x)
+{
+	static const double p10[] = {
+		1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10,
+		1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
+		1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+		1e10, 1e11, 1e12, 1e13, 1e14, 1e15
+	};
+	double n, y = modf(x, &n);
+	union {double f; uint64_t i;} u = {n};
+	/* fabs(n) < 16 without raising invalid on nan */
+	if ((u.i>>52 & 0x7ff) < 0x3ff+4) {
+		if (!y) return p10[(int)n+15];
+		y = exp2(3.32192809488736234787031942948939 * y);
+		return y * p10[(int)n+15];
+	}
+	return pow(10.0, x);
+}
+
+weak_alias(exp10, pow10);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp10f.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp10f.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp10f.c	(revision 398)
@@ -0,0 +1,23 @@
+#define _GNU_SOURCE
+#include <math.h>
+#include <stdint.h>
+#include "libc.h"
+
+float exp10f(float x)
+{
+	static const float p10[] = {
+		1e-7f, 1e-6f, 1e-5f, 1e-4f, 1e-3f, 1e-2f, 1e-1f,
+		1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7
+	};
+	float n, y = modff(x, &n);
+	union {float f; uint32_t i;} u = {n};
+	/* fabsf(n) < 8 without raising invalid on nan */
+	if ((u.i>>23 & 0xff) < 0x7f+3) {
+		if (!y) return p10[(int)n+7];
+		y = exp2f(3.32192809488736234787031942948939f * y);
+		return y * p10[(int)n+7];
+	}
+	return exp2(3.32192809488736234787031942948939 * x);
+}
+
+weak_alias(exp10f, pow10f);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp10l.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp10l.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp10l.c	(revision 398)
@@ -0,0 +1,33 @@
+#define _GNU_SOURCE
+#include <float.h>
+#include <math.h>
+#include "libc.h"
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double exp10l(long double x)
+{
+	return exp10(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double exp10l(long double x)
+{
+	static const long double p10[] = {
+		1e-15L, 1e-14L, 1e-13L, 1e-12L, 1e-11L, 1e-10L,
+		1e-9L, 1e-8L, 1e-7L, 1e-6L, 1e-5L, 1e-4L, 1e-3L, 1e-2L, 1e-1L,
+		1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+		1e10, 1e11, 1e12, 1e13, 1e14, 1e15
+	};
+	long double n, y = modfl(x, &n);
+	union ldshape u = {n};
+	/* fabsl(n) < 16 without raising invalid on nan */
+	if ((u.i.se & 0x7fff) < 0x3fff+4) {
+		if (!y) return p10[(int)n+15];
+		y = exp2l(3.32192809488736234787031942948939L * y);
+		return y * p10[(int)n+15];
+	}
+	return powl(10.0, x);
+}
+#endif
+
+weak_alias(exp10l, pow10l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp2.c	(revision 398)
@@ -0,0 +1,375 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_exp2.c */
+/*-
+ * Copyright (c) 2005 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 "libm.h"
+
+#define TBLSIZE 256
+
+static const double
+redux = 0x1.8p52 / TBLSIZE,
+P1    = 0x1.62e42fefa39efp-1,
+P2    = 0x1.ebfbdff82c575p-3,
+P3    = 0x1.c6b08d704a0a6p-5,
+P4    = 0x1.3b2ab88f70400p-7,
+P5    = 0x1.5d88003875c74p-10;
+
+static const double tbl[TBLSIZE * 2] = {
+/*  exp2(z + eps)          eps     */
+  0x1.6a09e667f3d5dp-1,  0x1.9880p-44,
+  0x1.6b052fa751744p-1,  0x1.8000p-50,
+  0x1.6c012750bd9fep-1, -0x1.8780p-45,
+  0x1.6cfdcddd476bfp-1,  0x1.ec00p-46,
+  0x1.6dfb23c651a29p-1, -0x1.8000p-50,
+  0x1.6ef9298593ae3p-1, -0x1.c000p-52,
+  0x1.6ff7df9519386p-1, -0x1.fd80p-45,
+  0x1.70f7466f42da3p-1, -0x1.c880p-45,
+  0x1.71f75e8ec5fc3p-1,  0x1.3c00p-46,
+  0x1.72f8286eacf05p-1, -0x1.8300p-44,
+  0x1.73f9a48a58152p-1, -0x1.0c00p-47,
+  0x1.74fbd35d7ccfcp-1,  0x1.f880p-45,
+  0x1.75feb564267f1p-1,  0x1.3e00p-47,
+  0x1.77024b1ab6d48p-1, -0x1.7d00p-45,
+  0x1.780694fde5d38p-1, -0x1.d000p-50,
+  0x1.790b938ac1d00p-1,  0x1.3000p-49,
+  0x1.7a11473eb0178p-1, -0x1.d000p-49,
+  0x1.7b17b0976d060p-1,  0x1.0400p-45,
+  0x1.7c1ed0130c133p-1,  0x1.0000p-53,
+  0x1.7d26a62ff8636p-1, -0x1.6900p-45,
+  0x1.7e2f336cf4e3bp-1, -0x1.2e00p-47,
+  0x1.7f3878491c3e8p-1, -0x1.4580p-45,
+  0x1.80427543e1b4ep-1,  0x1.3000p-44,
+  0x1.814d2add1071ap-1,  0x1.f000p-47,
+  0x1.82589994ccd7ep-1, -0x1.1c00p-45,
+  0x1.8364c1eb942d0p-1,  0x1.9d00p-45,
+  0x1.8471a4623cab5p-1,  0x1.7100p-43,
+  0x1.857f4179f5bbcp-1,  0x1.2600p-45,
+  0x1.868d99b4491afp-1, -0x1.2c40p-44,
+  0x1.879cad931a395p-1, -0x1.3000p-45,
+  0x1.88ac7d98a65b8p-1, -0x1.a800p-45,
+  0x1.89bd0a4785800p-1, -0x1.d000p-49,
+  0x1.8ace5422aa223p-1,  0x1.3280p-44,
+  0x1.8be05bad619fap-1,  0x1.2b40p-43,
+  0x1.8cf3216b54383p-1, -0x1.ed00p-45,
+  0x1.8e06a5e08664cp-1, -0x1.0500p-45,
+  0x1.8f1ae99157807p-1,  0x1.8280p-45,
+  0x1.902fed0282c0ep-1, -0x1.cb00p-46,
+  0x1.9145b0b91ff96p-1, -0x1.5e00p-47,
+  0x1.925c353aa2ff9p-1,  0x1.5400p-48,
+  0x1.93737b0cdc64ap-1,  0x1.7200p-46,
+  0x1.948b82b5f98aep-1, -0x1.9000p-47,
+  0x1.95a44cbc852cbp-1,  0x1.5680p-45,
+  0x1.96bdd9a766f21p-1, -0x1.6d00p-44,
+  0x1.97d829fde4e2ap-1, -0x1.1000p-47,
+  0x1.98f33e47a23a3p-1,  0x1.d000p-45,
+  0x1.9a0f170ca0604p-1, -0x1.8a40p-44,
+  0x1.9b2bb4d53ff89p-1,  0x1.55c0p-44,
+  0x1.9c49182a3f15bp-1,  0x1.6b80p-45,
+  0x1.9d674194bb8c5p-1, -0x1.c000p-49,
+  0x1.9e86319e3238ep-1,  0x1.7d00p-46,
+  0x1.9fa5e8d07f302p-1,  0x1.6400p-46,
+  0x1.a0c667b5de54dp-1, -0x1.5000p-48,
+  0x1.a1e7aed8eb8f6p-1,  0x1.9e00p-47,
+  0x1.a309bec4a2e27p-1,  0x1.ad80p-45,
+  0x1.a42c980460a5dp-1, -0x1.af00p-46,
+  0x1.a5503b23e259bp-1,  0x1.b600p-47,
+  0x1.a674a8af46213p-1,  0x1.8880p-44,
+  0x1.a799e1330b3a7p-1,  0x1.1200p-46,
+  0x1.a8bfe53c12e8dp-1,  0x1.6c00p-47,
+  0x1.a9e6b5579fcd2p-1, -0x1.9b80p-45,
+  0x1.ab0e521356fb8p-1,  0x1.b700p-45,
+  0x1.ac36bbfd3f381p-1,  0x1.9000p-50,
+  0x1.ad5ff3a3c2780p-1,  0x1.4000p-49,
+  0x1.ae89f995ad2a3p-1, -0x1.c900p-45,
+  0x1.afb4ce622f367p-1,  0x1.6500p-46,
+  0x1.b0e07298db790p-1,  0x1.fd40p-45,
+  0x1.b20ce6c9a89a9p-1,  0x1.2700p-46,
+  0x1.b33a2b84f1a4bp-1,  0x1.d470p-43,
+  0x1.b468415b747e7p-1, -0x1.8380p-44,
+  0x1.b59728de5593ap-1,  0x1.8000p-54,
+  0x1.b6c6e29f1c56ap-1,  0x1.ad00p-47,
+  0x1.b7f76f2fb5e50p-1,  0x1.e800p-50,
+  0x1.b928cf22749b2p-1, -0x1.4c00p-47,
+  0x1.ba5b030a10603p-1, -0x1.d700p-47,
+  0x1.bb8e0b79a6f66p-1,  0x1.d900p-47,
+  0x1.bcc1e904bc1ffp-1,  0x1.2a00p-47,
+  0x1.bdf69c3f3a16fp-1, -0x1.f780p-46,
+  0x1.bf2c25bd71db8p-1, -0x1.0a00p-46,
+  0x1.c06286141b2e9p-1, -0x1.1400p-46,
+  0x1.c199bdd8552e0p-1,  0x1.be00p-47,
+  0x1.c2d1cd9fa64eep-1, -0x1.9400p-47,
+  0x1.c40ab5fffd02fp-1, -0x1.ed00p-47,
+  0x1.c544778fafd15p-1,  0x1.9660p-44,
+  0x1.c67f12e57d0cbp-1, -0x1.a100p-46,
+  0x1.c7ba88988c1b6p-1, -0x1.8458p-42,
+  0x1.c8f6d9406e733p-1, -0x1.a480p-46,
+  0x1.ca3405751c4dfp-1,  0x1.b000p-51,
+  0x1.cb720dcef9094p-1,  0x1.1400p-47,
+  0x1.ccb0f2e6d1689p-1,  0x1.0200p-48,
+  0x1.cdf0b555dc412p-1,  0x1.3600p-48,
+  0x1.cf3155b5bab3bp-1, -0x1.6900p-47,
+  0x1.d072d4a0789bcp-1,  0x1.9a00p-47,
+  0x1.d1b532b08c8fap-1, -0x1.5e00p-46,
+  0x1.d2f87080d8a85p-1,  0x1.d280p-46,
+  0x1.d43c8eacaa203p-1,  0x1.1a00p-47,
+  0x1.d5818dcfba491p-1,  0x1.f000p-50,
+  0x1.d6c76e862e6a1p-1, -0x1.3a00p-47,
+  0x1.d80e316c9834ep-1, -0x1.cd80p-47,
+  0x1.d955d71ff6090p-1,  0x1.4c00p-48,
+  0x1.da9e603db32aep-1,  0x1.f900p-48,
+  0x1.dbe7cd63a8325p-1,  0x1.9800p-49,
+  0x1.dd321f301b445p-1, -0x1.5200p-48,
+  0x1.de7d5641c05bfp-1, -0x1.d700p-46,
+  0x1.dfc97337b9aecp-1, -0x1.6140p-46,
+  0x1.e11676b197d5ep-1,  0x1.b480p-47,
+  0x1.e264614f5a3e7p-1,  0x1.0ce0p-43,
+  0x1.e3b333b16ee5cp-1,  0x1.c680p-47,
+  0x1.e502ee78b3fb4p-1, -0x1.9300p-47,
+  0x1.e653924676d68p-1, -0x1.5000p-49,
+  0x1.e7a51fbc74c44p-1, -0x1.7f80p-47,
+  0x1.e8f7977cdb726p-1, -0x1.3700p-48,
+  0x1.ea4afa2a490e8p-1,  0x1.5d00p-49,
+  0x1.eb9f4867ccae4p-1,  0x1.61a0p-46,
+  0x1.ecf482d8e680dp-1,  0x1.5500p-48,
+  0x1.ee4aaa2188514p-1,  0x1.6400p-51,
+  0x1.efa1bee615a13p-1, -0x1.e800p-49,
+  0x1.f0f9c1cb64106p-1, -0x1.a880p-48,
+  0x1.f252b376bb963p-1, -0x1.c900p-45,
+  0x1.f3ac948dd7275p-1,  0x1.a000p-53,
+  0x1.f50765b6e4524p-1, -0x1.4f00p-48,
+  0x1.f6632798844fdp-1,  0x1.a800p-51,
+  0x1.f7bfdad9cbe38p-1,  0x1.abc0p-48,
+  0x1.f91d802243c82p-1, -0x1.4600p-50,
+  0x1.fa7c1819e908ep-1, -0x1.b0c0p-47,
+  0x1.fbdba3692d511p-1, -0x1.0e00p-51,
+  0x1.fd3c22b8f7194p-1, -0x1.0de8p-46,
+  0x1.fe9d96b2a23eep-1,  0x1.e430p-49,
+  0x1.0000000000000p+0,  0x0.0000p+0,
+  0x1.00b1afa5abcbep+0, -0x1.3400p-52,
+  0x1.0163da9fb3303p+0, -0x1.2170p-46,
+  0x1.02168143b0282p+0,  0x1.a400p-52,
+  0x1.02c9a3e77806cp+0,  0x1.f980p-49,
+  0x1.037d42e11bbcap+0, -0x1.7400p-51,
+  0x1.04315e86e7f89p+0,  0x1.8300p-50,
+  0x1.04e5f72f65467p+0, -0x1.a3f0p-46,
+  0x1.059b0d315855ap+0, -0x1.2840p-47,
+  0x1.0650a0e3c1f95p+0,  0x1.1600p-48,
+  0x1.0706b29ddf71ap+0,  0x1.5240p-46,
+  0x1.07bd42b72a82dp+0, -0x1.9a00p-49,
+  0x1.0874518759bd0p+0,  0x1.6400p-49,
+  0x1.092bdf66607c8p+0, -0x1.0780p-47,
+  0x1.09e3ecac6f383p+0, -0x1.8000p-54,
+  0x1.0a9c79b1f3930p+0,  0x1.fa00p-48,
+  0x1.0b5586cf988fcp+0, -0x1.ac80p-48,
+  0x1.0c0f145e46c8ap+0,  0x1.9c00p-50,
+  0x1.0cc922b724816p+0,  0x1.5200p-47,
+  0x1.0d83b23395dd8p+0, -0x1.ad00p-48,
+  0x1.0e3ec32d3d1f3p+0,  0x1.bac0p-46,
+  0x1.0efa55fdfa9a6p+0, -0x1.4e80p-47,
+  0x1.0fb66affed2f0p+0, -0x1.d300p-47,
+  0x1.1073028d7234bp+0,  0x1.1500p-48,
+  0x1.11301d0125b5bp+0,  0x1.c000p-49,
+  0x1.11edbab5e2af9p+0,  0x1.6bc0p-46,
+  0x1.12abdc06c31d5p+0,  0x1.8400p-49,
+  0x1.136a814f2047dp+0, -0x1.ed00p-47,
+  0x1.1429aaea92de9p+0,  0x1.8e00p-49,
+  0x1.14e95934f3138p+0,  0x1.b400p-49,
+  0x1.15a98c8a58e71p+0,  0x1.5300p-47,
+  0x1.166a45471c3dfp+0,  0x1.3380p-47,
+  0x1.172b83c7d5211p+0,  0x1.8d40p-45,
+  0x1.17ed48695bb9fp+0, -0x1.5d00p-47,
+  0x1.18af9388c8d93p+0, -0x1.c880p-46,
+  0x1.1972658375d66p+0,  0x1.1f00p-46,
+  0x1.1a35beb6fcba7p+0,  0x1.0480p-46,
+  0x1.1af99f81387e3p+0, -0x1.7390p-43,
+  0x1.1bbe084045d54p+0,  0x1.4e40p-45,
+  0x1.1c82f95281c43p+0, -0x1.a200p-47,
+  0x1.1d4873168b9b2p+0,  0x1.3800p-49,
+  0x1.1e0e75eb44031p+0,  0x1.ac00p-49,
+  0x1.1ed5022fcd938p+0,  0x1.1900p-47,
+  0x1.1f9c18438cdf7p+0, -0x1.b780p-46,
+  0x1.2063b88628d8fp+0,  0x1.d940p-45,
+  0x1.212be3578a81ep+0,  0x1.8000p-50,
+  0x1.21f49917ddd41p+0,  0x1.b340p-45,
+  0x1.22bdda2791323p+0,  0x1.9f80p-46,
+  0x1.2387a6e7561e7p+0, -0x1.9c80p-46,
+  0x1.2451ffb821427p+0,  0x1.2300p-47,
+  0x1.251ce4fb2a602p+0, -0x1.3480p-46,
+  0x1.25e85711eceb0p+0,  0x1.2700p-46,
+  0x1.26b4565e27d16p+0,  0x1.1d00p-46,
+  0x1.2780e341de00fp+0,  0x1.1ee0p-44,
+  0x1.284dfe1f5633ep+0, -0x1.4c00p-46,
+  0x1.291ba7591bb30p+0, -0x1.3d80p-46,
+  0x1.29e9df51fdf09p+0,  0x1.8b00p-47,
+  0x1.2ab8a66d10e9bp+0, -0x1.27c0p-45,
+  0x1.2b87fd0dada3ap+0,  0x1.a340p-45,
+  0x1.2c57e39771af9p+0, -0x1.0800p-46,
+  0x1.2d285a6e402d9p+0, -0x1.ed00p-47,
+  0x1.2df961f641579p+0, -0x1.4200p-48,
+  0x1.2ecafa93e2ecfp+0, -0x1.4980p-45,
+  0x1.2f9d24abd8822p+0, -0x1.6300p-46,
+  0x1.306fe0a31b625p+0, -0x1.2360p-44,
+  0x1.31432edeea50bp+0, -0x1.0df8p-40,
+  0x1.32170fc4cd7b8p+0, -0x1.2480p-45,
+  0x1.32eb83ba8e9a2p+0, -0x1.5980p-45,
+  0x1.33c08b2641766p+0,  0x1.ed00p-46,
+  0x1.3496266e3fa27p+0, -0x1.c000p-50,
+  0x1.356c55f929f0fp+0, -0x1.0d80p-44,
+  0x1.36431a2de88b9p+0,  0x1.2c80p-45,
+  0x1.371a7373aaa39p+0,  0x1.0600p-45,
+  0x1.37f26231e74fep+0, -0x1.6600p-46,
+  0x1.38cae6d05d838p+0, -0x1.ae00p-47,
+  0x1.39a401b713ec3p+0, -0x1.4720p-43,
+  0x1.3a7db34e5a020p+0,  0x1.8200p-47,
+  0x1.3b57fbfec6e95p+0,  0x1.e800p-44,
+  0x1.3c32dc313a8f2p+0,  0x1.f800p-49,
+  0x1.3d0e544ede122p+0, -0x1.7a00p-46,
+  0x1.3dea64c1234bbp+0,  0x1.6300p-45,
+  0x1.3ec70df1c4eccp+0, -0x1.8a60p-43,
+  0x1.3fa4504ac7e8cp+0, -0x1.cdc0p-44,
+  0x1.40822c367a0bbp+0,  0x1.5b80p-45,
+  0x1.4160a21f72e95p+0,  0x1.ec00p-46,
+  0x1.423fb27094646p+0, -0x1.3600p-46,
+  0x1.431f5d950a920p+0,  0x1.3980p-45,
+  0x1.43ffa3f84b9ebp+0,  0x1.a000p-48,
+  0x1.44e0860618919p+0, -0x1.6c00p-48,
+  0x1.45c2042a7d201p+0, -0x1.bc00p-47,
+  0x1.46a41ed1d0016p+0, -0x1.2800p-46,
+  0x1.4786d668b3326p+0,  0x1.0e00p-44,
+  0x1.486a2b5c13c00p+0, -0x1.d400p-45,
+  0x1.494e1e192af04p+0,  0x1.c200p-47,
+  0x1.4a32af0d7d372p+0, -0x1.e500p-46,
+  0x1.4b17dea6db801p+0,  0x1.7800p-47,
+  0x1.4bfdad53629e1p+0, -0x1.3800p-46,
+  0x1.4ce41b817c132p+0,  0x1.0800p-47,
+  0x1.4dcb299fddddbp+0,  0x1.c700p-45,
+  0x1.4eb2d81d8ab96p+0, -0x1.ce00p-46,
+  0x1.4f9b2769d2d02p+0,  0x1.9200p-46,
+  0x1.508417f4531c1p+0, -0x1.8c00p-47,
+  0x1.516daa2cf662ap+0, -0x1.a000p-48,
+  0x1.5257de83f51eap+0,  0x1.a080p-43,
+  0x1.5342b569d4edap+0, -0x1.6d80p-45,
+  0x1.542e2f4f6ac1ap+0, -0x1.2440p-44,
+  0x1.551a4ca5d94dbp+0,  0x1.83c0p-43,
+  0x1.56070dde9116bp+0,  0x1.4b00p-45,
+  0x1.56f4736b529dep+0,  0x1.15a0p-43,
+  0x1.57e27dbe2c40ep+0, -0x1.9e00p-45,
+  0x1.58d12d497c76fp+0, -0x1.3080p-45,
+  0x1.59c0827ff0b4cp+0,  0x1.dec0p-43,
+  0x1.5ab07dd485427p+0, -0x1.4000p-51,
+  0x1.5ba11fba87af4p+0,  0x1.0080p-44,
+  0x1.5c9268a59460bp+0, -0x1.6c80p-45,
+  0x1.5d84590998e3fp+0,  0x1.69a0p-43,
+  0x1.5e76f15ad20e1p+0, -0x1.b400p-46,
+  0x1.5f6a320dcebcap+0,  0x1.7700p-46,
+  0x1.605e1b976dcb8p+0,  0x1.6f80p-45,
+  0x1.6152ae6cdf715p+0,  0x1.1000p-47,
+  0x1.6247eb03a5531p+0, -0x1.5d00p-46,
+  0x1.633dd1d1929b5p+0, -0x1.2d00p-46,
+  0x1.6434634ccc313p+0, -0x1.a800p-49,
+  0x1.652b9febc8efap+0, -0x1.8600p-45,
+  0x1.6623882553397p+0,  0x1.1fe0p-40,
+  0x1.671c1c708328ep+0, -0x1.7200p-44,
+  0x1.68155d44ca97ep+0,  0x1.6800p-49,
+  0x1.690f4b19e9471p+0, -0x1.9780p-45,
+};
+
+/*
+ * exp2(x): compute the base 2 exponential of x
+ *
+ * Accuracy: Peak error < 0.503 ulp for normalized results.
+ *
+ * Method: (accurate tables)
+ *
+ *   Reduce x:
+ *     x = k + y, for integer k and |y| <= 1/2.
+ *     Thus we have exp2(x) = 2**k * exp2(y).
+ *
+ *   Reduce y:
+ *     y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE.
+ *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]),
+ *     with |z - eps[i]| <= 2**-9 + 2**-39 for the table used.
+ *
+ *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via
+ *   a degree-5 minimax polynomial with maximum error under 1.3 * 2**-61.
+ *   The values in exp2t[] and eps[] are chosen such that
+ *   exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such
+ *   that exp2t[i] is accurate to 2**-64.
+ *
+ *   Note that the range of i is +-TBLSIZE/2, so we actually index the tables
+ *   by i0 = i + TBLSIZE/2.  For cache efficiency, exp2t[] and eps[] are
+ *   virtual tables, interleaved in the real table tbl[].
+ *
+ *   This method is due to Gal, with many details due to Gal and Bachelis:
+ *
+ *      Gal, S. and Bachelis, B.  An Accurate Elementary Mathematical Library
+ *      for the IEEE Floating Point Standard.  TOMS 17(1), 26-46 (1991).
+ */
+double exp2(double x)
+{
+	double_t r, t, z;
+	uint32_t ix, i0;
+	union {double f; uint64_t i;} u = {x};
+	union {uint32_t u; int32_t i;} k;
+
+	/* Filter out exceptional cases. */
+	ix = u.i>>32 & 0x7fffffff;
+	if (ix >= 0x408ff000) {  /* |x| >= 1022 or nan */
+		if (ix >= 0x40900000 && u.i>>63 == 0) {  /* x >= 1024 or nan */
+			/* overflow */
+			x *= 0x1p1023;
+			return x;
+		}
+		if (ix >= 0x7ff00000)  /* -inf or -nan */
+			return -1/x;
+		if (u.i>>63) {  /* x <= -1022 */
+			/* underflow */
+			if (x <= -1075 || x - 0x1p52 + 0x1p52 != x)
+				FORCE_EVAL((float)(-0x1p-149/x));
+			if (x <= -1075)
+				return 0;
+		}
+	} else if (ix < 0x3c900000) {  /* |x| < 0x1p-54 */
+		return 1.0 + x;
+	}
+
+	/* Reduce x, computing z, i0, and k. */
+	u.f = x + redux;
+	i0 = u.i;
+	i0 += TBLSIZE / 2;
+	k.u = i0 / TBLSIZE * TBLSIZE;
+	k.i /= TBLSIZE;
+	i0 %= TBLSIZE;
+	u.f -= redux;
+	z = x - u.f;
+
+	/* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
+	t = tbl[2*i0];       /* exp2t[i0] */
+	z -= tbl[2*i0 + 1];  /* eps[i0]   */
+	r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
+
+	return scalbn(r, k.i);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp2f.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp2f.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp2f.c	(revision 398)
@@ -0,0 +1,126 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_exp2f.c */
+/*-
+ * Copyright (c) 2005 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 "libm.h"
+
+#define TBLSIZE 16
+
+static const float
+redux = 0x1.8p23f / TBLSIZE,
+P1    = 0x1.62e430p-1f,
+P2    = 0x1.ebfbe0p-3f,
+P3    = 0x1.c6b348p-5f,
+P4    = 0x1.3b2c9cp-7f;
+
+static const double exp2ft[TBLSIZE] = {
+  0x1.6a09e667f3bcdp-1,
+  0x1.7a11473eb0187p-1,
+  0x1.8ace5422aa0dbp-1,
+  0x1.9c49182a3f090p-1,
+  0x1.ae89f995ad3adp-1,
+  0x1.c199bdd85529cp-1,
+  0x1.d5818dcfba487p-1,
+  0x1.ea4afa2a490dap-1,
+  0x1.0000000000000p+0,
+  0x1.0b5586cf9890fp+0,
+  0x1.172b83c7d517bp+0,
+  0x1.2387a6e756238p+0,
+  0x1.306fe0a31b715p+0,
+  0x1.3dea64c123422p+0,
+  0x1.4bfdad5362a27p+0,
+  0x1.5ab07dd485429p+0,
+};
+
+/*
+ * exp2f(x): compute the base 2 exponential of x
+ *
+ * Accuracy: Peak error < 0.501 ulp; location of peak: -0.030110927.
+ *
+ * Method: (equally-spaced tables)
+ *
+ *   Reduce x:
+ *     x = k + y, for integer k and |y| <= 1/2.
+ *     Thus we have exp2f(x) = 2**k * exp2(y).
+ *
+ *   Reduce y:
+ *     y = i/TBLSIZE + z for integer i near y * TBLSIZE.
+ *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z),
+ *     with |z| <= 2**-(TBLSIZE+1).
+ *
+ *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a
+ *   degree-4 minimax polynomial with maximum error under 1.4 * 2**-33.
+ *   Using double precision for everything except the reduction makes
+ *   roundoff error insignificant and simplifies the scaling step.
+ *
+ *   This method is due to Tang, but I do not use his suggested parameters:
+ *
+ *      Tang, P.  Table-driven Implementation of the Exponential Function
+ *      in IEEE Floating-Point Arithmetic.  TOMS 15(2), 144-157 (1989).
+ */
+float exp2f(float x)
+{
+	double_t t, r, z;
+	union {float f; uint32_t i;} u = {x};
+	union {double f; uint64_t i;} uk;
+	uint32_t ix, i0, k;
+
+	/* Filter out exceptional cases. */
+	ix = u.i & 0x7fffffff;
+	if (ix > 0x42fc0000) {  /* |x| > 126 */
+		if (ix > 0x7f800000) /* NaN */
+			return x;
+		if (u.i >= 0x43000000 && u.i < 0x80000000) {  /* x >= 128 */
+			x *= 0x1p127f;
+			return x;
+		}
+		if (u.i >= 0x80000000) {  /* x < -126 */
+			if (u.i >= 0xc3160000 || (u.i & 0x0000ffff))
+				FORCE_EVAL(-0x1p-149f/x);
+			if (u.i >= 0xc3160000)  /* x <= -150 */
+				return 0;
+		}
+	} else if (ix <= 0x33000000) {  /* |x| <= 0x1p-25 */
+		return 1.0f + x;
+	}
+
+	/* Reduce x, computing z, i0, and k. */
+	u.f = x + redux;
+	i0 = u.i;
+	i0 += TBLSIZE / 2;
+	k = i0 / TBLSIZE;
+	uk.i = (uint64_t)(0x3ff + k)<<52;
+	i0 &= TBLSIZE - 1;
+	u.f -= redux;
+	z = x - u.f;
+	/* Compute r = exp2(y) = exp2ft[i0] * p(z). */
+	r = exp2ft[i0];
+	t = r * z;
+	r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
+
+	/* Scale by 2**k */
+	return r * uk.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp2l.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp2l.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/exp2l.c	(revision 398)
@@ -0,0 +1,619 @@
+/* origin: FreeBSD /usr/src/lib/msun/ld80/s_exp2l.c and /usr/src/lib/msun/ld128/s_exp2l.c */
+/*-
+ * Copyright (c) 2005-2008 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double exp2l(long double x)
+{
+	return exp2(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+#define TBLBITS 7
+#define TBLSIZE (1 << TBLBITS)
+
+static const double
+redux = 0x1.8p63 / TBLSIZE,
+P1    = 0x1.62e42fefa39efp-1,
+P2    = 0x1.ebfbdff82c58fp-3,
+P3    = 0x1.c6b08d7049fap-5,
+P4    = 0x1.3b2ab6fba4da5p-7,
+P5    = 0x1.5d8804780a736p-10,
+P6    = 0x1.430918835e33dp-13;
+
+static const double tbl[TBLSIZE * 2] = {
+	0x1.6a09e667f3bcdp-1,   -0x1.bdd3413b2648p-55,
+	0x1.6c012750bdabfp-1,   -0x1.2895667ff0cp-57,
+	0x1.6dfb23c651a2fp-1,   -0x1.bbe3a683c88p-58,
+	0x1.6ff7df9519484p-1,   -0x1.83c0f25860fp-56,
+	0x1.71f75e8ec5f74p-1,   -0x1.16e4786887bp-56,
+	0x1.73f9a48a58174p-1,   -0x1.0a8d96c65d5p-55,
+	0x1.75feb564267c9p-1,   -0x1.0245957316ep-55,
+	0x1.780694fde5d3fp-1,    0x1.866b80a0216p-55,
+	0x1.7a11473eb0187p-1,   -0x1.41577ee0499p-56,
+	0x1.7c1ed0130c132p-1,    0x1.f124cd1164ep-55,
+	0x1.7e2f336cf4e62p-1,    0x1.05d02ba157ap-57,
+	0x1.80427543e1a12p-1,   -0x1.27c86626d97p-55,
+	0x1.82589994cce13p-1,   -0x1.d4c1dd41533p-55,
+	0x1.8471a4623c7adp-1,   -0x1.8d684a341cep-56,
+	0x1.868d99b4492edp-1,   -0x1.fc6f89bd4f68p-55,
+	0x1.88ac7d98a6699p-1,    0x1.994c2f37cb5p-55,
+	0x1.8ace5422aa0dbp-1,    0x1.6e9f156864bp-55,
+	0x1.8cf3216b5448cp-1,   -0x1.0d55e32e9e4p-57,
+	0x1.8f1ae99157736p-1,    0x1.5cc13a2e397p-56,
+	0x1.9145b0b91ffc6p-1,   -0x1.dd6792e5825p-55,
+	0x1.93737b0cdc5e5p-1,   -0x1.75fc781b58p-58,
+	0x1.95a44cbc8520fp-1,   -0x1.64b7c96a5fp-57,
+	0x1.97d829fde4e5p-1,    -0x1.d185b7c1b86p-55,
+	0x1.9a0f170ca07bap-1,   -0x1.173bd91cee6p-55,
+	0x1.9c49182a3f09p-1,     0x1.c7c46b071f2p-57,
+	0x1.9e86319e32323p-1,    0x1.824ca78e64cp-57,
+	0x1.a0c667b5de565p-1,   -0x1.359495d1cd5p-55,
+	0x1.a309bec4a2d33p-1,    0x1.6305c7ddc368p-55,
+	0x1.a5503b23e255dp-1,   -0x1.d2f6edb8d42p-55,
+	0x1.a799e1330b358p-1,    0x1.bcb7ecac564p-55,
+	0x1.a9e6b5579fdbfp-1,    0x1.0fac90ef7fdp-55,
+	0x1.ac36bbfd3f37ap-1,   -0x1.f9234cae76dp-56,
+	0x1.ae89f995ad3adp-1,    0x1.7a1cd345dcc8p-55,
+	0x1.b0e07298db666p-1,   -0x1.bdef54c80e4p-55,
+	0x1.b33a2b84f15fbp-1,   -0x1.2805e3084d8p-58,
+	0x1.b59728de5593ap-1,   -0x1.c71dfbbba6ep-55,
+	0x1.b7f76f2fb5e47p-1,   -0x1.5584f7e54acp-57,
+	0x1.ba5b030a1064ap-1,   -0x1.efcd30e5429p-55,
+	0x1.bcc1e904bc1d2p-1,    0x1.23dd07a2d9fp-56,
+	0x1.bf2c25bd71e09p-1,   -0x1.efdca3f6b9c8p-55,
+	0x1.c199bdd85529cp-1,    0x1.11065895049p-56,
+	0x1.c40ab5fffd07ap-1,    0x1.b4537e083c6p-55,
+	0x1.c67f12e57d14bp-1,    0x1.2884dff483c8p-55,
+	0x1.c8f6d9406e7b5p-1,    0x1.1acbc48805cp-57,
+	0x1.cb720dcef9069p-1,    0x1.503cbd1e94ap-57,
+	0x1.cdf0b555dc3fap-1,   -0x1.dd83b53829dp-56,
+	0x1.d072d4a07897cp-1,   -0x1.cbc3743797a8p-55,
+	0x1.d2f87080d89f2p-1,   -0x1.d487b719d858p-55,
+	0x1.d5818dcfba487p-1,    0x1.2ed02d75b37p-56,
+	0x1.d80e316c98398p-1,   -0x1.11ec18bedep-55,
+	0x1.da9e603db3285p-1,    0x1.c2300696db5p-55,
+	0x1.dd321f301b46p-1,     0x1.2da5778f019p-55,
+	0x1.dfc97337b9b5fp-1,   -0x1.1a5cd4f184b8p-55,
+	0x1.e264614f5a129p-1,   -0x1.7b627817a148p-55,
+	0x1.e502ee78b3ff6p-1,    0x1.39e8980a9cdp-56,
+	0x1.e7a51fbc74c83p-1,    0x1.2d522ca0c8ep-55,
+	0x1.ea4afa2a490dap-1,   -0x1.e9c23179c288p-55,
+	0x1.ecf482d8e67f1p-1,   -0x1.c93f3b411ad8p-55,
+	0x1.efa1bee615a27p-1,    0x1.dc7f486a4b68p-55,
+	0x1.f252b376bba97p-1,    0x1.3a1a5bf0d8e8p-55,
+	0x1.f50765b6e454p-1,     0x1.9d3e12dd8a18p-55,
+	0x1.f7bfdad9cbe14p-1,   -0x1.dbb12d00635p-55,
+	0x1.fa7c1819e90d8p-1,    0x1.74853f3a593p-56,
+	0x1.fd3c22b8f71f1p-1,    0x1.2eb74966578p-58,
+	0x1p+0,                  0x0p+0,
+	0x1.0163da9fb3335p+0,    0x1.b61299ab8cd8p-54,
+	0x1.02c9a3e778061p+0,   -0x1.19083535b08p-56,
+	0x1.04315e86e7f85p+0,   -0x1.0a31c1977c98p-54,
+	0x1.059b0d3158574p+0,    0x1.d73e2a475b4p-55,
+	0x1.0706b29ddf6dep+0,   -0x1.c91dfe2b13cp-55,
+	0x1.0874518759bc8p+0,    0x1.186be4bb284p-57,
+	0x1.09e3ecac6f383p+0,    0x1.14878183161p-54,
+	0x1.0b5586cf9890fp+0,    0x1.8a62e4adc61p-54,
+	0x1.0cc922b7247f7p+0,    0x1.01edc16e24f8p-54,
+	0x1.0e3ec32d3d1a2p+0,    0x1.03a1727c58p-59,
+	0x1.0fb66affed31bp+0,   -0x1.b9bedc44ebcp-57,
+	0x1.11301d0125b51p+0,   -0x1.6c51039449bp-54,
+	0x1.12abdc06c31ccp+0,   -0x1.1b514b36ca8p-58,
+	0x1.1429aaea92dep+0,    -0x1.32fbf9af1368p-54,
+	0x1.15a98c8a58e51p+0,    0x1.2406ab9eeabp-55,
+	0x1.172b83c7d517bp+0,   -0x1.19041b9d78ap-55,
+	0x1.18af9388c8deap+0,   -0x1.11023d1970f8p-54,
+	0x1.1a35beb6fcb75p+0,    0x1.e5b4c7b4969p-55,
+	0x1.1bbe084045cd4p+0,   -0x1.95386352ef6p-54,
+	0x1.1d4873168b9aap+0,    0x1.e016e00a264p-54,
+	0x1.1ed5022fcd91dp+0,   -0x1.1df98027bb78p-54,
+	0x1.2063b88628cd6p+0,    0x1.dc775814a85p-55,
+	0x1.21f49917ddc96p+0,    0x1.2a97e9494a6p-55,
+	0x1.2387a6e756238p+0,    0x1.9b07eb6c7058p-54,
+	0x1.251ce4fb2a63fp+0,    0x1.ac155bef4f5p-55,
+	0x1.26b4565e27cddp+0,    0x1.2bd339940eap-55,
+	0x1.284dfe1f56381p+0,   -0x1.a4c3a8c3f0d8p-54,
+	0x1.29e9df51fdee1p+0,    0x1.612e8afad12p-55,
+	0x1.2b87fd0dad99p+0,    -0x1.10adcd6382p-59,
+	0x1.2d285a6e4030bp+0,    0x1.0024754db42p-54,
+	0x1.2ecafa93e2f56p+0,    0x1.1ca0f45d524p-56,
+	0x1.306fe0a31b715p+0,    0x1.6f46ad23183p-55,
+	0x1.32170fc4cd831p+0,    0x1.a9ce78e1804p-55,
+	0x1.33c08b26416ffp+0,    0x1.327218436598p-54,
+	0x1.356c55f929ff1p+0,   -0x1.b5cee5c4e46p-55,
+	0x1.371a7373aa9cbp+0,   -0x1.63aeabf42ebp-54,
+	0x1.38cae6d05d866p+0,   -0x1.e958d3c99048p-54,
+	0x1.3a7db34e59ff7p+0,   -0x1.5e436d661f6p-56,
+	0x1.3c32dc313a8e5p+0,   -0x1.efff8375d2ap-54,
+	0x1.3dea64c123422p+0,    0x1.ada0911f09fp-55,
+	0x1.3fa4504ac801cp+0,   -0x1.7d023f956fap-54,
+	0x1.4160a21f72e2ap+0,   -0x1.ef3691c309p-58,
+	0x1.431f5d950a897p+0,   -0x1.1c7dde35f7ap-55,
+	0x1.44e086061892dp+0,    0x1.89b7a04ef8p-59,
+	0x1.46a41ed1d0057p+0,    0x1.c944bd1648a8p-54,
+	0x1.486a2b5c13cdp+0,     0x1.3c1a3b69062p-56,
+	0x1.4a32af0d7d3dep+0,    0x1.9cb62f3d1be8p-54,
+	0x1.4bfdad5362a27p+0,    0x1.d4397afec42p-56,
+	0x1.4dcb299fddd0dp+0,    0x1.8ecdbbc6a78p-54,
+	0x1.4f9b2769d2ca7p+0,   -0x1.4b309d25958p-54,
+	0x1.516daa2cf6642p+0,   -0x1.f768569bd94p-55,
+	0x1.5342b569d4f82p+0,   -0x1.07abe1db13dp-55,
+	0x1.551a4ca5d920fp+0,   -0x1.d689cefede6p-55,
+	0x1.56f4736b527dap+0,    0x1.9bb2c011d938p-54,
+	0x1.58d12d497c7fdp+0,    0x1.295e15b9a1ep-55,
+	0x1.5ab07dd485429p+0,    0x1.6324c0546478p-54,
+	0x1.5c9268a5946b7p+0,    0x1.c4b1b81698p-60,
+	0x1.5e76f15ad2148p+0,    0x1.ba6f93080e68p-54,
+	0x1.605e1b976dc09p+0,   -0x1.3e2429b56de8p-54,
+	0x1.6247eb03a5585p+0,   -0x1.383c17e40b48p-54,
+	0x1.6434634ccc32p+0,    -0x1.c483c759d89p-55,
+	0x1.6623882552225p+0,   -0x1.bb60987591cp-54,
+	0x1.68155d44ca973p+0,    0x1.038ae44f74p-57,
+};
+
+/*
+ * exp2l(x): compute the base 2 exponential of x
+ *
+ * Accuracy: Peak error < 0.511 ulp.
+ *
+ * Method: (equally-spaced tables)
+ *
+ *   Reduce x:
+ *     x = 2**k + y, for integer k and |y| <= 1/2.
+ *     Thus we have exp2l(x) = 2**k * exp2(y).
+ *
+ *   Reduce y:
+ *     y = i/TBLSIZE + z for integer i near y * TBLSIZE.
+ *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z),
+ *     with |z| <= 2**-(TBLBITS+1).
+ *
+ *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a
+ *   degree-6 minimax polynomial with maximum error under 2**-69.
+ *   The table entries each have 104 bits of accuracy, encoded as
+ *   a pair of double precision values.
+ */
+long double exp2l(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	long double r, z;
+	uint32_t i0;
+	union {uint32_t u; int32_t i;} k;
+
+	/* Filter out exceptional cases. */
+	if (e >= 0x3fff + 13) {  /* |x| >= 8192 or x is NaN */
+		if (u.i.se >= 0x3fff + 14 && u.i.se >> 15 == 0)
+			/* overflow */
+			return x * 0x1p16383L;
+		if (e == 0x7fff)  /* -inf or -nan */
+			return -1/x;
+		if (x < -16382) {
+			if (x <= -16446 || x - 0x1p63 + 0x1p63 != x)
+				/* underflow */
+				FORCE_EVAL((float)(-0x1p-149/x));
+			if (x <= -16446)
+				return 0;
+		}
+	} else if (e < 0x3fff - 64) {
+		return 1 + x;
+	}
+
+	/*
+	 * Reduce x, computing z, i0, and k. The low bits of x + redux
+	 * contain the 16-bit integer part of the exponent (k) followed by
+	 * TBLBITS fractional bits (i0). We use bit tricks to extract these
+	 * as integers, then set z to the remainder.
+	 *
+	 * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8.
+	 * Then the low-order word of x + redux is 0x000abc12,
+	 * We split this into k = 0xabc and i0 = 0x12 (adjusted to
+	 * index into the table), then we compute z = 0x0.003456p0.
+	 */
+	u.f = x + redux;
+	i0 = u.i.m + TBLSIZE / 2;
+	k.u = i0 / TBLSIZE * TBLSIZE;
+	k.i /= TBLSIZE;
+	i0 %= TBLSIZE;
+	u.f -= redux;
+	z = x - u.f;
+
+	/* Compute r = exp2l(y) = exp2lt[i0] * p(z). */
+	long double t_hi = tbl[2*i0];
+	long double t_lo = tbl[2*i0 + 1];
+	/* XXX This gives > 1 ulp errors outside of FE_TONEAREST mode */
+	r = t_lo + (t_hi + t_lo) * z * (P1 + z * (P2 + z * (P3 + z * (P4
+	     + z * (P5 + z * P6))))) + t_hi;
+
+	return scalbnl(r, k.i);
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+#define TBLBITS 7
+#define TBLSIZE (1 << TBLBITS)
+
+static const long double
+    P1        = 0x1.62e42fefa39ef35793c7673007e6p-1L,
+    P2        = 0x1.ebfbdff82c58ea86f16b06ec9736p-3L,
+    P3        = 0x1.c6b08d704a0bf8b33a762bad3459p-5L,
+    P4        = 0x1.3b2ab6fba4e7729ccbbe0b4f3fc2p-7L,
+    P5        = 0x1.5d87fe78a67311071dee13fd11d9p-10L,
+    P6        = 0x1.430912f86c7876f4b663b23c5fe5p-13L;
+
+static const double
+    P7        = 0x1.ffcbfc588b041p-17,
+    P8        = 0x1.62c0223a5c7c7p-20,
+    P9        = 0x1.b52541ff59713p-24,
+    P10       = 0x1.e4cf56a391e22p-28,
+    redux     = 0x1.8p112 / TBLSIZE;
+
+static const long double tbl[TBLSIZE] = {
+	0x1.6a09e667f3bcc908b2fb1366dfeap-1L,
+	0x1.6c012750bdabeed76a99800f4edep-1L,
+	0x1.6dfb23c651a2ef220e2cbe1bc0d4p-1L,
+	0x1.6ff7df9519483cf87e1b4f3e1e98p-1L,
+	0x1.71f75e8ec5f73dd2370f2ef0b148p-1L,
+	0x1.73f9a48a58173bd5c9a4e68ab074p-1L,
+	0x1.75feb564267c8bf6e9aa33a489a8p-1L,
+	0x1.780694fde5d3f619ae02808592a4p-1L,
+	0x1.7a11473eb0186d7d51023f6ccb1ap-1L,
+	0x1.7c1ed0130c1327c49334459378dep-1L,
+	0x1.7e2f336cf4e62105d02ba1579756p-1L,
+	0x1.80427543e1a11b60de67649a3842p-1L,
+	0x1.82589994cce128acf88afab34928p-1L,
+	0x1.8471a4623c7acce52f6b97c6444cp-1L,
+	0x1.868d99b4492ec80e41d90ac2556ap-1L,
+	0x1.88ac7d98a669966530bcdf2d4cc0p-1L,
+	0x1.8ace5422aa0db5ba7c55a192c648p-1L,
+	0x1.8cf3216b5448bef2aa1cd161c57ap-1L,
+	0x1.8f1ae991577362b982745c72eddap-1L,
+	0x1.9145b0b91ffc588a61b469f6b6a0p-1L,
+	0x1.93737b0cdc5e4f4501c3f2540ae8p-1L,
+	0x1.95a44cbc8520ee9b483695a0e7fep-1L,
+	0x1.97d829fde4e4f8b9e920f91e8eb6p-1L,
+	0x1.9a0f170ca07b9ba3109b8c467844p-1L,
+	0x1.9c49182a3f0901c7c46b071f28dep-1L,
+	0x1.9e86319e323231824ca78e64c462p-1L,
+	0x1.a0c667b5de564b29ada8b8cabbacp-1L,
+	0x1.a309bec4a2d3358c171f770db1f4p-1L,
+	0x1.a5503b23e255c8b424491caf88ccp-1L,
+	0x1.a799e1330b3586f2dfb2b158f31ep-1L,
+	0x1.a9e6b5579fdbf43eb243bdff53a2p-1L,
+	0x1.ac36bbfd3f379c0db966a3126988p-1L,
+	0x1.ae89f995ad3ad5e8734d17731c80p-1L,
+	0x1.b0e07298db66590842acdfc6fb4ep-1L,
+	0x1.b33a2b84f15faf6bfd0e7bd941b0p-1L,
+	0x1.b59728de559398e3881111648738p-1L,
+	0x1.b7f76f2fb5e46eaa7b081ab53ff6p-1L,
+	0x1.ba5b030a10649840cb3c6af5b74cp-1L,
+	0x1.bcc1e904bc1d2247ba0f45b3d06cp-1L,
+	0x1.bf2c25bd71e088408d7025190cd0p-1L,
+	0x1.c199bdd85529c2220cb12a0916bap-1L,
+	0x1.c40ab5fffd07a6d14df820f17deap-1L,
+	0x1.c67f12e57d14b4a2137fd20f2a26p-1L,
+	0x1.c8f6d9406e7b511acbc48805c3f6p-1L,
+	0x1.cb720dcef90691503cbd1e949d0ap-1L,
+	0x1.cdf0b555dc3f9c44f8958fac4f12p-1L,
+	0x1.d072d4a07897b8d0f22f21a13792p-1L,
+	0x1.d2f87080d89f18ade123989ea50ep-1L,
+	0x1.d5818dcfba48725da05aeb66dff8p-1L,
+	0x1.d80e316c98397bb84f9d048807a0p-1L,
+	0x1.da9e603db3285708c01a5b6d480cp-1L,
+	0x1.dd321f301b4604b695de3c0630c0p-1L,
+	0x1.dfc97337b9b5eb968cac39ed284cp-1L,
+	0x1.e264614f5a128a12761fa17adc74p-1L,
+	0x1.e502ee78b3ff6273d130153992d0p-1L,
+	0x1.e7a51fbc74c834b548b2832378a4p-1L,
+	0x1.ea4afa2a490d9858f73a18f5dab4p-1L,
+	0x1.ecf482d8e67f08db0312fb949d50p-1L,
+	0x1.efa1bee615a27771fd21a92dabb6p-1L,
+	0x1.f252b376bba974e8696fc3638f24p-1L,
+	0x1.f50765b6e4540674f84b762861a6p-1L,
+	0x1.f7bfdad9cbe138913b4bfe72bd78p-1L,
+	0x1.fa7c1819e90d82e90a7e74b26360p-1L,
+	0x1.fd3c22b8f71f10975ba4b32bd006p-1L,
+	0x1.0000000000000000000000000000p+0L,
+	0x1.0163da9fb33356d84a66ae336e98p+0L,
+	0x1.02c9a3e778060ee6f7caca4f7a18p+0L,
+	0x1.04315e86e7f84bd738f9a20da442p+0L,
+	0x1.059b0d31585743ae7c548eb68c6ap+0L,
+	0x1.0706b29ddf6ddc6dc403a9d87b1ep+0L,
+	0x1.0874518759bc808c35f25d942856p+0L,
+	0x1.09e3ecac6f3834521e060c584d5cp+0L,
+	0x1.0b5586cf9890f6298b92b7184200p+0L,
+	0x1.0cc922b7247f7407b705b893dbdep+0L,
+	0x1.0e3ec32d3d1a2020742e4f8af794p+0L,
+	0x1.0fb66affed31af232091dd8a169ep+0L,
+	0x1.11301d0125b50a4ebbf1aed9321cp+0L,
+	0x1.12abdc06c31cbfb92bad324d6f84p+0L,
+	0x1.1429aaea92ddfb34101943b2588ep+0L,
+	0x1.15a98c8a58e512480d573dd562aep+0L,
+	0x1.172b83c7d517adcdf7c8c50eb162p+0L,
+	0x1.18af9388c8de9bbbf70b9a3c269cp+0L,
+	0x1.1a35beb6fcb753cb698f692d2038p+0L,
+	0x1.1bbe084045cd39ab1e72b442810ep+0L,
+	0x1.1d4873168b9aa7805b8028990be8p+0L,
+	0x1.1ed5022fcd91cb8819ff61121fbep+0L,
+	0x1.2063b88628cd63b8eeb0295093f6p+0L,
+	0x1.21f49917ddc962552fd29294bc20p+0L,
+	0x1.2387a6e75623866c1fadb1c159c0p+0L,
+	0x1.251ce4fb2a63f3582ab7de9e9562p+0L,
+	0x1.26b4565e27cdd257a673281d3068p+0L,
+	0x1.284dfe1f5638096cf15cf03c9fa0p+0L,
+	0x1.29e9df51fdee12c25d15f5a25022p+0L,
+	0x1.2b87fd0dad98ffddea46538fca24p+0L,
+	0x1.2d285a6e4030b40091d536d0733ep+0L,
+	0x1.2ecafa93e2f5611ca0f45d5239a4p+0L,
+	0x1.306fe0a31b7152de8d5a463063bep+0L,
+	0x1.32170fc4cd8313539cf1c3009330p+0L,
+	0x1.33c08b26416ff4c9c8610d96680ep+0L,
+	0x1.356c55f929ff0c94623476373be4p+0L,
+	0x1.371a7373aa9caa7145502f45452ap+0L,
+	0x1.38cae6d05d86585a9cb0d9bed530p+0L,
+	0x1.3a7db34e59ff6ea1bc9299e0a1fep+0L,
+	0x1.3c32dc313a8e484001f228b58cf0p+0L,
+	0x1.3dea64c12342235b41223e13d7eep+0L,
+	0x1.3fa4504ac801ba0bf701aa417b9cp+0L,
+	0x1.4160a21f72e29f84325b8f3dbacap+0L,
+	0x1.431f5d950a896dc704439410b628p+0L,
+	0x1.44e086061892d03136f409df0724p+0L,
+	0x1.46a41ed1d005772512f459229f0ap+0L,
+	0x1.486a2b5c13cd013c1a3b69062f26p+0L,
+	0x1.4a32af0d7d3de672d8bcf46f99b4p+0L,
+	0x1.4bfdad5362a271d4397afec42e36p+0L,
+	0x1.4dcb299fddd0d63b36ef1a9e19dep+0L,
+	0x1.4f9b2769d2ca6ad33d8b69aa0b8cp+0L,
+	0x1.516daa2cf6641c112f52c84d6066p+0L,
+	0x1.5342b569d4f81df0a83c49d86bf4p+0L,
+	0x1.551a4ca5d920ec52ec620243540cp+0L,
+	0x1.56f4736b527da66ecb004764e61ep+0L,
+	0x1.58d12d497c7fd252bc2b7343d554p+0L,
+	0x1.5ab07dd48542958c93015191e9a8p+0L,
+	0x1.5c9268a5946b701c4b1b81697ed4p+0L,
+	0x1.5e76f15ad21486e9be4c20399d12p+0L,
+	0x1.605e1b976dc08b076f592a487066p+0L,
+	0x1.6247eb03a5584b1f0fa06fd2d9eap+0L,
+	0x1.6434634ccc31fc76f8714c4ee122p+0L,
+	0x1.66238825522249127d9e29b92ea2p+0L,
+	0x1.68155d44ca973081c57227b9f69ep+0L,
+};
+
+static const float eps[TBLSIZE] = {
+	-0x1.5c50p-101,
+	-0x1.5d00p-106,
+	 0x1.8e90p-102,
+	-0x1.5340p-103,
+	 0x1.1bd0p-102,
+	-0x1.4600p-105,
+	-0x1.7a40p-104,
+	 0x1.d590p-102,
+	-0x1.d590p-101,
+	 0x1.b100p-103,
+	-0x1.0d80p-105,
+	 0x1.6b00p-103,
+	-0x1.9f00p-105,
+	 0x1.c400p-103,
+	 0x1.e120p-103,
+	-0x1.c100p-104,
+	-0x1.9d20p-103,
+	 0x1.a800p-108,
+	 0x1.4c00p-106,
+	-0x1.9500p-106,
+	 0x1.6900p-105,
+	-0x1.29d0p-100,
+	 0x1.4c60p-103,
+	 0x1.13a0p-102,
+	-0x1.5b60p-103,
+	-0x1.1c40p-103,
+	 0x1.db80p-102,
+	 0x1.91a0p-102,
+	 0x1.dc00p-105,
+	 0x1.44c0p-104,
+	 0x1.9710p-102,
+	 0x1.8760p-103,
+	-0x1.a720p-103,
+	 0x1.ed20p-103,
+	-0x1.49c0p-102,
+	-0x1.e000p-111,
+	 0x1.86a0p-103,
+	 0x1.2b40p-103,
+	-0x1.b400p-108,
+	 0x1.1280p-99,
+	-0x1.02d8p-102,
+	-0x1.e3d0p-103,
+	-0x1.b080p-105,
+	-0x1.f100p-107,
+	-0x1.16c0p-105,
+	-0x1.1190p-103,
+	-0x1.a7d2p-100,
+	 0x1.3450p-103,
+	-0x1.67c0p-105,
+	 0x1.4b80p-104,
+	-0x1.c4e0p-103,
+	 0x1.6000p-108,
+	-0x1.3f60p-105,
+	 0x1.93f0p-104,
+	 0x1.5fe0p-105,
+	 0x1.6f80p-107,
+	-0x1.7600p-106,
+	 0x1.21e0p-106,
+	-0x1.3a40p-106,
+	-0x1.40c0p-104,
+	-0x1.9860p-105,
+	-0x1.5d40p-108,
+	-0x1.1d70p-106,
+	 0x1.2760p-105,
+	 0x0.0000p+0,
+	 0x1.21e2p-104,
+	-0x1.9520p-108,
+	-0x1.5720p-106,
+	-0x1.4810p-106,
+	-0x1.be00p-109,
+	 0x1.0080p-105,
+	-0x1.5780p-108,
+	-0x1.d460p-105,
+	-0x1.6140p-105,
+	 0x1.4630p-104,
+	 0x1.ad50p-103,
+	 0x1.82e0p-105,
+	 0x1.1d3cp-101,
+	 0x1.6100p-107,
+	 0x1.ec30p-104,
+	 0x1.f200p-108,
+	 0x1.0b40p-103,
+	 0x1.3660p-102,
+	 0x1.d9d0p-103,
+	-0x1.02d0p-102,
+	 0x1.b070p-103,
+	 0x1.b9c0p-104,
+	-0x1.01c0p-103,
+	-0x1.dfe0p-103,
+	 0x1.1b60p-104,
+	-0x1.ae94p-101,
+	-0x1.3340p-104,
+	 0x1.b3d8p-102,
+	-0x1.6e40p-105,
+	-0x1.3670p-103,
+	 0x1.c140p-104,
+	 0x1.1840p-101,
+	 0x1.1ab0p-102,
+	-0x1.a400p-104,
+	 0x1.1f00p-104,
+	-0x1.7180p-103,
+	 0x1.4ce0p-102,
+	 0x1.9200p-107,
+	-0x1.54c0p-103,
+	 0x1.1b80p-105,
+	-0x1.1828p-101,
+	 0x1.5720p-102,
+	-0x1.a060p-100,
+	 0x1.9160p-102,
+	 0x1.a280p-104,
+	 0x1.3400p-107,
+	 0x1.2b20p-102,
+	 0x1.7800p-108,
+	 0x1.cfd0p-101,
+	 0x1.2ef0p-102,
+	-0x1.2760p-99,
+	 0x1.b380p-104,
+	 0x1.0048p-101,
+	-0x1.60b0p-102,
+	 0x1.a1ccp-100,
+	-0x1.a640p-104,
+	-0x1.08a0p-101,
+	 0x1.7e60p-102,
+	 0x1.22c0p-103,
+	-0x1.7200p-106,
+	 0x1.f0f0p-102,
+	 0x1.eb4ep-99,
+	 0x1.c6e0p-103,
+};
+
+/*
+ * exp2l(x): compute the base 2 exponential of x
+ *
+ * Accuracy: Peak error < 0.502 ulp.
+ *
+ * Method: (accurate tables)
+ *
+ *   Reduce x:
+ *     x = 2**k + y, for integer k and |y| <= 1/2.
+ *     Thus we have exp2(x) = 2**k * exp2(y).
+ *
+ *   Reduce y:
+ *     y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE.
+ *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]),
+ *     with |z - eps[i]| <= 2**-8 + 2**-98 for the table used.
+ *
+ *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via
+ *   a degree-10 minimax polynomial with maximum error under 2**-120.
+ *   The values in exp2t[] and eps[] are chosen such that
+ *   exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such
+ *   that exp2t[i] is accurate to 2**-122.
+ *
+ *   Note that the range of i is +-TBLSIZE/2, so we actually index the tables
+ *   by i0 = i + TBLSIZE/2.
+ *
+ *   This method is due to Gal, with many details due to Gal and Bachelis:
+ *
+ *	Gal, S. and Bachelis, B.  An Accurate Elementary Mathematical Library
+ *	for the IEEE Floating Point Standard.  TOMS 17(1), 26-46 (1991).
+ */
+long double
+exp2l(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	long double r, z, t;
+	uint32_t i0;
+	union {uint32_t u; int32_t i;} k;
+
+	/* Filter out exceptional cases. */
+	if (e >= 0x3fff + 14) {  /* |x| >= 16384 or x is NaN */
+		if (u.i.se >= 0x3fff + 15 && u.i.se >> 15 == 0)
+			/* overflow */
+			return x * 0x1p16383L;
+		if (e == 0x7fff)  /* -inf or -nan */
+			return -1/x;
+		if (x < -16382) {
+			if (x <= -16495 || x - 0x1p112 + 0x1p112 != x)
+				/* underflow */
+				FORCE_EVAL((float)(-0x1p-149/x));
+			if (x <= -16446)
+				return 0;
+		}
+	} else if (e < 0x3fff - 114) {
+		return 1 + x;
+	}
+
+	/*
+	 * Reduce x, computing z, i0, and k. The low bits of x + redux
+	 * contain the 16-bit integer part of the exponent (k) followed by
+	 * TBLBITS fractional bits (i0). We use bit tricks to extract these
+	 * as integers, then set z to the remainder.
+	 *
+	 * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8.
+	 * Then the low-order word of x + redux is 0x000abc12,
+	 * We split this into k = 0xabc and i0 = 0x12 (adjusted to
+	 * index into the table), then we compute z = 0x0.003456p0.
+	 */
+	u.f = x + redux;
+	i0 = u.i2.lo + TBLSIZE / 2;
+	k.u = i0 / TBLSIZE * TBLSIZE;
+	k.i /= TBLSIZE;
+	i0 %= TBLSIZE;
+	u.f -= redux;
+	z = x - u.f;
+
+	/* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
+	t = tbl[i0];
+	z -= eps[i0];
+	r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * (P5 + z * (P6
+	    + z * (P7 + z * (P8 + z * (P9 + z * P10)))))))));
+
+	return scalbnl(r, k.i);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expf.c	(revision 398)
@@ -0,0 +1,83 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_expf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+half[2] = {0.5,-0.5},
+ln2hi   = 6.9314575195e-1f,  /* 0x3f317200 */
+ln2lo   = 1.4286067653e-6f,  /* 0x35bfbe8e */
+invln2  = 1.4426950216e+0f,  /* 0x3fb8aa3b */
+/*
+ * Domain [-0.34568, 0.34568], range ~[-4.278e-9, 4.447e-9]:
+ * |x*(exp(x)+1)/(exp(x)-1) - p(x)| < 2**-27.74
+ */
+P1 =  1.6666625440e-1f, /*  0xaaaa8f.0p-26 */
+P2 = -2.7667332906e-3f; /* -0xb55215.0p-32 */
+
+float expf(float x)
+{
+	float_t hi, lo, c, xx, y;
+	int k, sign;
+	uint32_t hx;
+
+	GET_FLOAT_WORD(hx, x);
+	sign = hx >> 31;   /* sign bit of x */
+	hx &= 0x7fffffff;  /* high word of |x| */
+
+	/* special cases */
+	if (hx >= 0x42aeac50) {  /* if |x| >= -87.33655f or NaN */
+		if (hx > 0x7f800000) /* NaN */
+			return x;
+		if (hx >= 0x42b17218 && !sign) {  /* x >= 88.722839f */
+			/* overflow */
+			x *= 0x1p127f;
+			return x;
+		}
+		if (sign) {
+			/* underflow */
+			FORCE_EVAL(-0x1p-149f/x);
+			if (hx >= 0x42cff1b5)  /* x <= -103.972084f */
+				return 0;
+		}
+	}
+
+	/* argument reduction */
+	if (hx > 0x3eb17218) {  /* if |x| > 0.5 ln2 */
+		if (hx > 0x3f851592)  /* if |x| > 1.5 ln2 */
+			k = invln2*x + half[sign];
+		else
+			k = 1 - sign - sign;
+		hi = x - k*ln2hi;  /* k*ln2hi is exact here */
+		lo = k*ln2lo;
+		x = hi - lo;
+	} else if (hx > 0x39000000) {  /* |x| > 2**-14 */
+		k = 0;
+		hi = x;
+		lo = 0;
+	} else {
+		/* raise inexact */
+		FORCE_EVAL(0x1p127f + x);
+		return 1 + x;
+	}
+
+	/* x is now in primary range */
+	xx = x*x;
+	c = x - xx*(P1+xx*P2);
+	y = 1 + (x*c/(2-c) - lo + hi);
+	if (k == 0)
+		return y;
+	return scalbnf(y, k);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expl.c	(revision 398)
@@ -0,0 +1,128 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_expl.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Exponential function, long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, expl();
+ *
+ * y = expl( x );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns e (2.71828...) raised to the x power.
+ *
+ * Range reduction is accomplished by separating the argument
+ * into an integer k and fraction f such that
+ *
+ *     x    k  f
+ *    e  = 2  e.
+ *
+ * A Pade' form of degree 5/6 is used to approximate exp(f) - 1
+ * in the basic range [-0.5 ln 2, 0.5 ln 2].
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      +-10000     50000       1.12e-19    2.81e-20
+ *
+ *
+ * Error amplification in the exponential function can be
+ * a serious matter.  The error propagation involves
+ * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ),
+ * which shows that a 1 lsb error in representing X produces
+ * a relative error of X times 1 lsb in the function.
+ * While the routine gives an accurate result for arguments
+ * that are exactly represented by a long double precision
+ * computer number, the result contains amplified roundoff
+ * error for large arguments not exactly represented.
+ *
+ *
+ * ERROR MESSAGES:
+ *
+ *   message         condition      value returned
+ * exp underflow    x < MINLOG         0.0
+ * exp overflow     x > MAXLOG         MAXNUM
+ *
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double expl(long double x)
+{
+	return exp(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+
+static const long double P[3] = {
+ 1.2617719307481059087798E-4L,
+ 3.0299440770744196129956E-2L,
+ 9.9999999999999999991025E-1L,
+};
+static const long double Q[4] = {
+ 3.0019850513866445504159E-6L,
+ 2.5244834034968410419224E-3L,
+ 2.2726554820815502876593E-1L,
+ 2.0000000000000000000897E0L,
+};
+static const long double
+LN2HI = 6.9314575195312500000000E-1L,
+LN2LO = 1.4286068203094172321215E-6L,
+LOG2E = 1.4426950408889634073599E0L;
+
+long double expl(long double x)
+{
+	long double px, xx;
+	int k;
+
+	if (isnan(x))
+		return x;
+	if (x > 11356.5234062941439488L) /* x > ln(2^16384 - 0.5) */
+		return x * 0x1p16383L;
+	if (x < -11399.4985314888605581L) /* x < ln(2^-16446) */
+		return -0x1p-16445L/x;
+
+	/* Express e**x = e**f 2**k
+	 *   = e**(f + k ln(2))
+	 */
+	px = floorl(LOG2E * x + 0.5);
+	k = px;
+	x -= px * LN2HI;
+	x -= px * LN2LO;
+
+	/* rational approximation of the fractional part:
+	 * e**x =  1 + 2x P(x**2)/(Q(x**2) - x P(x**2))
+	 */
+	xx = x * x;
+	px = x * __polevll(xx, P, 2);
+	x = px/(__polevll(xx, Q, 3) - px);
+	x = 1.0 + 2.0 * x;
+	return scalbnl(x, k);
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double expl(long double x)
+{
+	return exp(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expm1.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expm1.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expm1.c	(revision 398)
@@ -0,0 +1,201 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* expm1(x)
+ * Returns exp(x)-1, the exponential of x minus 1.
+ *
+ * Method
+ *   1. Argument reduction:
+ *      Given x, find r and integer k such that
+ *
+ *               x = k*ln2 + r,  |r| <= 0.5*ln2 ~ 0.34658
+ *
+ *      Here a correction term c will be computed to compensate
+ *      the error in r when rounded to a floating-point number.
+ *
+ *   2. Approximating expm1(r) by a special rational function on
+ *      the interval [0,0.34658]:
+ *      Since
+ *          r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
+ *      we define R1(r*r) by
+ *          r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
+ *      That is,
+ *          R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
+ *                   = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
+ *                   = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
+ *      We use a special Remez algorithm on [0,0.347] to generate
+ *      a polynomial of degree 5 in r*r to approximate R1. The
+ *      maximum error of this polynomial approximation is bounded
+ *      by 2**-61. In other words,
+ *          R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
+ *      where   Q1  =  -1.6666666666666567384E-2,
+ *              Q2  =   3.9682539681370365873E-4,
+ *              Q3  =  -9.9206344733435987357E-6,
+ *              Q4  =   2.5051361420808517002E-7,
+ *              Q5  =  -6.2843505682382617102E-9;
+ *              z   =  r*r,
+ *      with error bounded by
+ *          |                  5           |     -61
+ *          | 1.0+Q1*z+...+Q5*z   -  R1(z) | <= 2
+ *          |                              |
+ *
+ *      expm1(r) = exp(r)-1 is then computed by the following
+ *      specific way which minimize the accumulation rounding error:
+ *                             2     3
+ *                            r     r    [ 3 - (R1 + R1*r/2)  ]
+ *            expm1(r) = r + --- + --- * [--------------------]
+ *                            2     2    [ 6 - r*(3 - R1*r/2) ]
+ *
+ *      To compensate the error in the argument reduction, we use
+ *              expm1(r+c) = expm1(r) + c + expm1(r)*c
+ *                         ~ expm1(r) + c + r*c
+ *      Thus c+r*c will be added in as the correction terms for
+ *      expm1(r+c). Now rearrange the term to avoid optimization
+ *      screw up:
+ *                      (      2                                    2 )
+ *                      ({  ( r    [ R1 -  (3 - R1*r/2) ]  )  }    r  )
+ *       expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
+ *                      ({  ( 2    [ 6 - r*(3 - R1*r/2) ]  )  }    2  )
+ *                      (                                             )
+ *
+ *                 = r - E
+ *   3. Scale back to obtain expm1(x):
+ *      From step 1, we have
+ *         expm1(x) = either 2^k*[expm1(r)+1] - 1
+ *                  = or     2^k*[expm1(r) + (1-2^-k)]
+ *   4. Implementation notes:
+ *      (A). To save one multiplication, we scale the coefficient Qi
+ *           to Qi*2^i, and replace z by (x^2)/2.
+ *      (B). To achieve maximum accuracy, we compute expm1(x) by
+ *        (i)   if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
+ *        (ii)  if k=0, return r-E
+ *        (iii) if k=-1, return 0.5*(r-E)-0.5
+ *        (iv)  if k=1 if r < -0.25, return 2*((r+0.5)- E)
+ *                     else          return  1.0+2.0*(r-E);
+ *        (v)   if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
+ *        (vi)  if k <= 20, return 2^k((1-2^-k)-(E-r)), else
+ *        (vii) return 2^k(1-((E+2^-k)-r))
+ *
+ * Special cases:
+ *      expm1(INF) is INF, expm1(NaN) is NaN;
+ *      expm1(-INF) is -1, and
+ *      for finite argument, only expm1(0)=0 is exact.
+ *
+ * Accuracy:
+ *      according to an error analysis, the error is always less than
+ *      1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ *      For IEEE double
+ *          if x >  7.09782712893383973096e+02 then expm1(x) overflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "libm.h"
+
+static const double
+o_threshold = 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
+ln2_hi      = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
+ln2_lo      = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
+invln2      = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
+/* Scaled Q's: Qn_here = 2**n * Qn_above, for R(2*z) where z = hxs = x*x/2: */
+Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */
+Q2 =  1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
+Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
+Q4 =  4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
+Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
+
+double expm1(double x)
+{
+	double_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
+	union {double f; uint64_t i;} u = {x};
+	uint32_t hx = u.i>>32 & 0x7fffffff;
+	int k, sign = u.i>>63;
+
+	/* filter out huge and non-finite argument */
+	if (hx >= 0x4043687A) {  /* if |x|>=56*ln2 */
+		if (isnan(x))
+			return x;
+		if (sign)
+			return -1;
+		if (x > o_threshold) {
+			x *= 0x1p1023;
+			return x;
+		}
+	}
+
+	/* argument reduction */
+	if (hx > 0x3fd62e42) {  /* if  |x| > 0.5 ln2 */
+		if (hx < 0x3FF0A2B2) {  /* and |x| < 1.5 ln2 */
+			if (!sign) {
+				hi = x - ln2_hi;
+				lo = ln2_lo;
+				k =  1;
+			} else {
+				hi = x + ln2_hi;
+				lo = -ln2_lo;
+				k = -1;
+			}
+		} else {
+			k  = invln2*x + (sign ? -0.5 : 0.5);
+			t  = k;
+			hi = x - t*ln2_hi;  /* t*ln2_hi is exact here */
+			lo = t*ln2_lo;
+		}
+		x = hi-lo;
+		c = (hi-x)-lo;
+	} else if (hx < 0x3c900000) {  /* |x| < 2**-54, return x */
+		if (hx < 0x00100000)
+			FORCE_EVAL((float)x);
+		return x;
+	} else
+		k = 0;
+
+	/* x is now in primary range */
+	hfx = 0.5*x;
+	hxs = x*hfx;
+	r1 = 1.0+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
+	t  = 3.0-r1*hfx;
+	e  = hxs*((r1-t)/(6.0 - x*t));
+	if (k == 0)   /* c is 0 */
+		return x - (x*e-hxs);
+	e  = x*(e-c) - c;
+	e -= hxs;
+	/* exp(x) ~ 2^k (x_reduced - e + 1) */
+	if (k == -1)
+		return 0.5*(x-e) - 0.5;
+	if (k == 1) {
+		if (x < -0.25)
+			return -2.0*(e-(x+0.5));
+		return 1.0+2.0*(x-e);
+	}
+	u.i = (uint64_t)(0x3ff + k)<<52;  /* 2^k */
+	twopk = u.f;
+	if (k < 0 || k > 56) {  /* suffice to return exp(x)-1 */
+		y = x - e + 1.0;
+		if (k == 1024)
+			y = y*2.0*0x1p1023;
+		else
+			y = y*twopk;
+		return y - 1.0;
+	}
+	u.i = (uint64_t)(0x3ff - k)<<52;  /* 2^-k */
+	if (k < 20)
+		y = (x-e+(1-u.f))*twopk;
+	else
+		y = (x-(e+u.f)+1)*twopk;
+	return y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expm1f.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expm1f.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expm1f.c	(revision 398)
@@ -0,0 +1,111 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1f.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+o_threshold = 8.8721679688e+01, /* 0x42b17180 */
+ln2_hi      = 6.9313812256e-01, /* 0x3f317180 */
+ln2_lo      = 9.0580006145e-06, /* 0x3717f7d1 */
+invln2      = 1.4426950216e+00, /* 0x3fb8aa3b */
+/*
+ * Domain [-0.34568, 0.34568], range ~[-6.694e-10, 6.696e-10]:
+ * |6 / x * (1 + 2 * (1 / (exp(x) - 1) - 1 / x)) - q(x)| < 2**-30.04
+ * Scaled coefficients: Qn_here = 2**n * Qn_for_q (see s_expm1.c):
+ */
+Q1 = -3.3333212137e-2, /* -0x888868.0p-28 */
+Q2 =  1.5807170421e-3; /*  0xcf3010.0p-33 */
+
+float expm1f(float x)
+{
+	float_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
+	union {float f; uint32_t i;} u = {x};
+	uint32_t hx = u.i & 0x7fffffff;
+	int k, sign = u.i >> 31;
+
+	/* filter out huge and non-finite argument */
+	if (hx >= 0x4195b844) {  /* if |x|>=27*ln2 */
+		if (hx > 0x7f800000)  /* NaN */
+			return x;
+		if (sign)
+			return -1;
+		if (x > o_threshold) {
+			x *= 0x1p127f;
+			return x;
+		}
+	}
+
+	/* argument reduction */
+	if (hx > 0x3eb17218) {           /* if  |x| > 0.5 ln2 */
+		if (hx < 0x3F851592) {       /* and |x| < 1.5 ln2 */
+			if (!sign) {
+				hi = x - ln2_hi;
+				lo = ln2_lo;
+				k =  1;
+			} else {
+				hi = x + ln2_hi;
+				lo = -ln2_lo;
+				k = -1;
+			}
+		} else {
+			k  = invln2*x + (sign ? -0.5f : 0.5f);
+			t  = k;
+			hi = x - t*ln2_hi;      /* t*ln2_hi is exact here */
+			lo = t*ln2_lo;
+		}
+		x = hi-lo;
+		c = (hi-x)-lo;
+	} else if (hx < 0x33000000) {  /* when |x|<2**-25, return x */
+		if (hx < 0x00800000)
+			FORCE_EVAL(x*x);
+		return x;
+	} else
+		k = 0;
+
+	/* x is now in primary range */
+	hfx = 0.5f*x;
+	hxs = x*hfx;
+	r1 = 1.0f+hxs*(Q1+hxs*Q2);
+	t  = 3.0f - r1*hfx;
+	e  = hxs*((r1-t)/(6.0f - x*t));
+	if (k == 0)  /* c is 0 */
+		return x - (x*e-hxs);
+	e  = x*(e-c) - c;
+	e -= hxs;
+	/* exp(x) ~ 2^k (x_reduced - e + 1) */
+	if (k == -1)
+		return 0.5f*(x-e) - 0.5f;
+	if (k == 1) {
+		if (x < -0.25f)
+			return -2.0f*(e-(x+0.5f));
+		return 1.0f + 2.0f*(x-e);
+	}
+	u.i = (0x7f+k)<<23;  /* 2^k */
+	twopk = u.f;
+	if (k < 0 || k > 56) {   /* suffice to return exp(x)-1 */
+		y = x - e + 1.0f;
+		if (k == 128)
+			y = y*2.0f*0x1p127f;
+		else
+			y = y*twopk;
+		return y - 1.0f;
+	}
+	u.i = (0x7f-k)<<23;  /* 2^-k */
+	if (k < 23)
+		y = (x-e+(1-u.f))*twopk;
+	else
+		y = (x-(e+u.f)+1)*twopk;
+	return y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expm1l.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expm1l.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/expm1l.c	(revision 398)
@@ -0,0 +1,123 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_expm1l.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Exponential function, minus 1
+ *      Long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, expm1l();
+ *
+ * y = expm1l( x );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns e (2.71828...) raised to the x power, minus 1.
+ *
+ * Range reduction is accomplished by separating the argument
+ * into an integer k and fraction f such that
+ *
+ *     x    k  f
+ *    e  = 2  e.
+ *
+ * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1
+ * in the basic range [-0.5 ln 2, 0.5 ln 2].
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE    -45,+maxarg   200,000     1.2e-19     2.5e-20
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double expm1l(long double x)
+{
+	return expm1(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+
+/* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x)
+   -.5 ln 2  <  x  <  .5 ln 2
+   Theoretical peak relative error = 3.4e-22  */
+static const long double
+P0 = -1.586135578666346600772998894928250240826E4L,
+P1 =  2.642771505685952966904660652518429479531E3L,
+P2 = -3.423199068835684263987132888286791620673E2L,
+P3 =  1.800826371455042224581246202420972737840E1L,
+P4 = -5.238523121205561042771939008061958820811E-1L,
+Q0 = -9.516813471998079611319047060563358064497E4L,
+Q1 =  3.964866271411091674556850458227710004570E4L,
+Q2 = -7.207678383830091850230366618190187434796E3L,
+Q3 =  7.206038318724600171970199625081491823079E2L,
+Q4 = -4.002027679107076077238836622982900945173E1L,
+/* Q5 = 1.000000000000000000000000000000000000000E0 */
+/* C1 + C2 = ln 2 */
+C1 = 6.93145751953125E-1L,
+C2 = 1.428606820309417232121458176568075500134E-6L,
+/* ln 2^-65 */
+minarg = -4.5054566736396445112120088E1L,
+/* ln 2^16384 */
+maxarg = 1.1356523406294143949492E4L;
+
+long double expm1l(long double x)
+{
+	long double px, qx, xx;
+	int k;
+
+	if (isnan(x))
+		return x;
+	if (x > maxarg)
+		return x*0x1p16383L; /* overflow, unless x==inf */
+	if (x == 0.0)
+		return x;
+	if (x < minarg)
+		return -1.0;
+
+	xx = C1 + C2;
+	/* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */
+	px = floorl(0.5 + x / xx);
+	k = px;
+	/* remainder times ln 2 */
+	x -= px * C1;
+	x -= px * C2;
+
+	/* Approximate exp(remainder ln 2).*/
+	px = (((( P4 * x + P3) * x + P2) * x + P1) * x + P0) * x;
+	qx = (((( x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0;
+	xx = x * x;
+	qx = x + (0.5 * xx + xx * px / qx);
+
+	/* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2).
+	 We have qx = exp(remainder ln 2) - 1, so
+	 exp(x) - 1  =  2^k (qx + 1) - 1  =  2^k qx + 2^k - 1.  */
+	px = scalbnl(1.0, k);
+	x = px * qx + (px - 1.0);
+	return x;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double expm1l(long double x)
+{
+	return expm1(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fabs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fabs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fabs.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <math.h>
+#include <stdint.h>
+
+double fabs(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	u.i &= -1ULL/2;
+	return u.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fabsf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fabsf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fabsf.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <math.h>
+#include <stdint.h>
+
+float fabsf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	u.i &= 0x7fffffff;
+	return u.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fabsl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fabsl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fabsl.c	(revision 398)
@@ -0,0 +1,15 @@
+#include "libm.h"
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fabsl(long double x)
+{
+	return fabs(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double fabsl(long double x)
+{
+	union ldshape u = {x};
+
+	u.i.se &= 0x7fff;
+	return u.f;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fdim.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fdim.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fdim.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <math.h>
+
+double fdim(double x, double y)
+{
+	if (isnan(x))
+		return x;
+	if (isnan(y))
+		return y;
+	return x > y ? x - y : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fdimf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fdimf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fdimf.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <math.h>
+
+float fdimf(float x, float y)
+{
+	if (isnan(x))
+		return x;
+	if (isnan(y))
+		return y;
+	return x > y ? x - y : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fdiml.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fdiml.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fdiml.c	(revision 398)
@@ -0,0 +1,18 @@
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fdiml(long double x, long double y)
+{
+	return fdim(x, y);
+}
+#else
+long double fdiml(long double x, long double y)
+{
+	if (isnan(x))
+		return x;
+	if (isnan(y))
+		return y;
+	return x > y ? x - y : 0;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/finite.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/finite.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/finite.c	(revision 398)
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <math.h>
+
+int finite(double x)
+{
+	return isfinite(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/finitef.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/finitef.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/finitef.c	(revision 398)
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <math.h>
+
+int finitef(float x)
+{
+	return isfinite(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/floor.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/floor.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/floor.c	(revision 398)
@@ -0,0 +1,31 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const double_t toint = 1/EPS;
+
+double floor(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i >> 52 & 0x7ff;
+	double_t y;
+
+	if (e >= 0x3ff+52 || x == 0)
+		return x;
+	/* y = int(x) - x, where int(x) is an integer neighbor of x */
+	if (u.i >> 63)
+		y = x - toint + toint - x;
+	else
+		y = x + toint - toint - x;
+	/* special case because of non-nearest rounding modes */
+	if (e <= 0x3ff-1) {
+		FORCE_EVAL(y);
+		return u.i >> 63 ? -1 : 0;
+	}
+	if (y > 0)
+		return x + y - 1;
+	return x + y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/floorf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/floorf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/floorf.c	(revision 398)
@@ -0,0 +1,27 @@
+#include "libm.h"
+
+float floorf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = (int)(u.i >> 23 & 0xff) - 0x7f;
+	uint32_t m;
+
+	if (e >= 23)
+		return x;
+	if (e >= 0) {
+		m = 0x007fffff >> e;
+		if ((u.i & m) == 0)
+			return x;
+		FORCE_EVAL(x + 0x1p120f);
+		if (u.i >> 31)
+			u.i += m;
+		u.i &= ~m;
+	} else {
+		FORCE_EVAL(x + 0x1p120f);
+		if (u.i >> 31 == 0)
+			u.i = 0;
+		else if (u.i << 1)
+			u.f = -1.0;
+	}
+	return u.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/floorl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/floorl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/floorl.c	(revision 398)
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double floorl(long double x)
+{
+	return floor(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double floorl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	long double y;
+
+	if (e >= 0x3fff+LDBL_MANT_DIG-1 || x == 0)
+		return x;
+	/* y = int(x) - x, where int(x) is an integer neighbor of x */
+	if (u.i.se >> 15)
+		y = x - toint + toint - x;
+	else
+		y = x + toint - toint - x;
+	/* special case because of non-nearest rounding modes */
+	if (e <= 0x3fff-1) {
+		FORCE_EVAL(y);
+		return u.i.se >> 15 ? -1 : 0;
+	}
+	if (y > 0)
+		return x + y - 1;
+	return x + y;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fma.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fma.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fma.c	(revision 398)
@@ -0,0 +1,183 @@
+#include <stdint.h>
+#include <float.h>
+#include <math.h>
+#include "atomic.h"
+
+#define ASUINT64(x) ((union {double f; uint64_t i;}){x}).i
+#define ZEROINFNAN (0x7ff-0x3ff-52-1)
+
+struct num { uint64_t m; int e; int sign; };
+
+static struct num normalize(double x)
+{
+	uint64_t ix = ASUINT64(x);
+	int e = ix>>52;
+	int sign = e & 0x800;
+	e &= 0x7ff;
+	if (!e) {
+		ix = ASUINT64(x*0x1p63);
+		e = ix>>52 & 0x7ff;
+		e = e ? e-63 : 0x800;
+	}
+	ix &= (1ull<<52)-1;
+	ix |= 1ull<<52;
+	ix <<= 1;
+	e -= 0x3ff + 52 + 1;
+	return (struct num){ix,e,sign};
+}
+
+static void mul(uint64_t *hi, uint64_t *lo, uint64_t x, uint64_t y)
+{
+	uint64_t t1,t2,t3;
+	uint64_t xlo = (uint32_t)x, xhi = x>>32;
+	uint64_t ylo = (uint32_t)y, yhi = y>>32;
+
+	t1 = xlo*ylo;
+	t2 = xlo*yhi + xhi*ylo;
+	t3 = xhi*yhi;
+	*lo = t1 + (t2<<32);
+	*hi = t3 + (t2>>32) + (t1 > *lo);
+}
+
+double fma(double x, double y, double z)
+{
+	#pragma STDC FENV_ACCESS ON
+
+	/* normalize so top 10bits and last bit are 0 */
+	struct num nx, ny, nz;
+	nx = normalize(x);
+	ny = normalize(y);
+	nz = normalize(z);
+
+	if (nx.e >= ZEROINFNAN || ny.e >= ZEROINFNAN)
+		return x*y + z;
+	if (nz.e >= ZEROINFNAN) {
+		if (nz.e > ZEROINFNAN) /* z==0 */
+			return x*y + z;
+		return z;
+	}
+
+	/* mul: r = x*y */
+	uint64_t rhi, rlo, zhi, zlo;
+	mul(&rhi, &rlo, nx.m, ny.m);
+	/* either top 20 or 21 bits of rhi and last 2 bits of rlo are 0 */
+
+	/* align exponents */
+	int e = nx.e + ny.e;
+	int d = nz.e - e;
+	/* shift bits z<<=kz, r>>=kr, so kz+kr == d, set e = e+kr (== ez-kz) */
+	if (d > 0) {
+		if (d < 64) {
+			zlo = nz.m<<d;
+			zhi = nz.m>>(64-d);
+		} else {
+			zlo = 0;
+			zhi = nz.m;
+			e = nz.e - 64;
+			d -= 64;
+			if (d == 0) {
+			} else if (d < 64) {
+				rlo = rhi<<(64-d) | rlo>>d | !!(rlo<<(64-d));
+				rhi = rhi>>d;
+			} else {
+				rlo = 1;
+				rhi = 0;
+			}
+		}
+	} else {
+		zhi = 0;
+		d = -d;
+		if (d == 0) {
+			zlo = nz.m;
+		} else if (d < 64) {
+			zlo = nz.m>>d | !!(nz.m<<(64-d));
+		} else {
+			zlo = 1;
+		}
+	}
+
+	/* add */
+	int sign = nx.sign^ny.sign;
+	int samesign = !(sign^nz.sign);
+	int nonzero = 1;
+	if (samesign) {
+		/* r += z */
+		rlo += zlo;
+		rhi += zhi + (rlo < zlo);
+	} else {
+		/* r -= z */
+		uint64_t t = rlo;
+		rlo -= zlo;
+		rhi = rhi - zhi - (t < rlo);
+		if (rhi>>63) {
+			rlo = -rlo;
+			rhi = -rhi-!!rlo;
+			sign = !sign;
+		}
+		nonzero = !!rhi;
+	}
+
+	/* set rhi to top 63bit of the result (last bit is sticky) */
+	if (nonzero) {
+		e += 64;
+		d = a_clz_64(rhi)-1;
+		/* note: d > 0 */
+		rhi = rhi<<d | rlo>>(64-d) | !!(rlo<<d);
+	} else if (rlo) {
+		d = a_clz_64(rlo)-1;
+		if (d < 0)
+			rhi = rlo>>1 | (rlo&1);
+		else
+			rhi = rlo<<d;
+	} else {
+		/* exact +-0 */
+		return x*y + z;
+	}
+	e -= d;
+
+	/* convert to double */
+	int64_t i = rhi; /* i is in [1<<62,(1<<63)-1] */
+	if (sign)
+		i = -i;
+	double r = i; /* |r| is in [0x1p62,0x1p63] */
+
+	if (e < -1022-62) {
+		/* result is subnormal before rounding */
+		if (e == -1022-63) {
+			double c = 0x1p63;
+			if (sign)
+				c = -c;
+			if (r == c) {
+				/* min normal after rounding, underflow depends
+				   on arch behaviour which can be imitated by
+				   a double to float conversion */
+				float fltmin = 0x0.ffffff8p-63*FLT_MIN * r;
+				return DBL_MIN/FLT_MIN * fltmin;
+			}
+			/* one bit is lost when scaled, add another top bit to
+			   only round once at conversion if it is inexact */
+			if (rhi << 53) {
+				i = rhi>>1 | (rhi&1) | 1ull<<62;
+				if (sign)
+					i = -i;
+				r = i;
+				r = 2*r - c; /* remove top bit */
+
+				/* raise underflow portably, such that it
+				   cannot be optimized away */
+				{
+					double_t tiny = DBL_MIN/FLT_MIN * r;
+					r += (double)(tiny*tiny) * (r-r);
+				}
+			}
+		} else {
+			/* only round once when scaled */
+			d = 10;
+			i = ( rhi>>d | !!(rhi<<(64-d)) ) << d;
+			if (sign)
+				i = -i;
+			r = i;
+		}
+	}
+	return scalbn(r, e);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmaf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmaf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmaf.c	(revision 398)
@@ -0,0 +1,93 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_fmaf.c */
+/*-
+ * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 <fenv.h>
+#include <math.h>
+#include <stdint.h>
+
+/*
+ * Fused multiply-add: Compute x * y + z with a single rounding error.
+ *
+ * A double has more than twice as much precision than a float, so
+ * direct double-precision arithmetic suffices, except where double
+ * rounding occurs.
+ */
+float fmaf(float x, float y, float z)
+{
+	#pragma STDC FENV_ACCESS ON
+	double xy, result;
+	union {double f; uint64_t i;} u;
+	int e;
+
+	xy = (double)x * y;
+	result = xy + z;
+	u.f = result;
+	e = u.i>>52 & 0x7ff;
+	/* Common case: The double precision result is fine. */
+	if ((u.i & 0x1fffffff) != 0x10000000 || /* not a halfway case */
+		e == 0x7ff ||                   /* NaN */
+		result - xy == z ||                 /* exact */
+		fegetround() != FE_TONEAREST)       /* not round-to-nearest */
+	{
+		/*
+		underflow may not be raised correctly, example:
+		fmaf(0x1p-120f, 0x1p-120f, 0x1p-149f)
+		*/
+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)
+		if (e < 0x3ff-126 && e >= 0x3ff-149 && fetestexcept(FE_INEXACT)) {
+			feclearexcept(FE_INEXACT);
+			/* TODO: gcc and clang bug workaround */
+			volatile float vz = z;
+			result = xy + vz;
+			if (fetestexcept(FE_INEXACT))
+				feraiseexcept(FE_UNDERFLOW);
+			else
+				feraiseexcept(FE_INEXACT);
+		}
+#endif
+		z = result;
+		return z;
+	}
+
+	/*
+	 * If result is inexact, and exactly halfway between two float values,
+	 * we need to adjust the low-order bit in the direction of the error.
+	 */
+#ifdef FE_TOWARDZERO
+	fesetround(FE_TOWARDZERO);
+#endif
+	volatile double vxy = xy;  /* XXX work around gcc CSE bug */
+	double adjusted_result = vxy + z;
+	fesetround(FE_TONEAREST);
+	if (result == adjusted_result) {
+		u.f = adjusted_result;
+		u.i++;
+		adjusted_result = u.f;
+	}
+	z = adjusted_result;
+	return z;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmal.c	(revision 398)
@@ -0,0 +1,293 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_fmal.c */
+/*-
+ * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.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:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must 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 AUTHOR 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 AUTHOR 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 "libm.h"
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fmal(long double x, long double y, long double z)
+{
+	return fma(x, y, z);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#include <fenv.h>
+#if LDBL_MANT_DIG == 64
+#define LASTBIT(u) (u.i.m & 1)
+#define SPLIT (0x1p32L + 1)
+#elif LDBL_MANT_DIG == 113
+#define LASTBIT(u) (u.i.lo & 1)
+#define SPLIT (0x1p57L + 1)
+#endif
+
+/*
+ * A struct dd represents a floating-point number with twice the precision
+ * of a long double.  We maintain the invariant that "hi" stores the high-order
+ * bits of the result.
+ */
+struct dd {
+	long double hi;
+	long double lo;
+};
+
+/*
+ * Compute a+b exactly, returning the exact result in a struct dd.  We assume
+ * that both a and b are finite, but make no assumptions about their relative
+ * magnitudes.
+ */
+static inline struct dd dd_add(long double a, long double b)
+{
+	struct dd ret;
+	long double s;
+
+	ret.hi = a + b;
+	s = ret.hi - a;
+	ret.lo = (a - (ret.hi - s)) + (b - s);
+	return (ret);
+}
+
+/*
+ * Compute a+b, with a small tweak:  The least significant bit of the
+ * result is adjusted into a sticky bit summarizing all the bits that
+ * were lost to rounding.  This adjustment negates the effects of double
+ * rounding when the result is added to another number with a higher
+ * exponent.  For an explanation of round and sticky bits, see any reference
+ * on FPU design, e.g.,
+ *
+ *     J. Coonen.  An Implementation Guide to a Proposed Standard for
+ *     Floating-Point Arithmetic.  Computer, vol. 13, no. 1, Jan 1980.
+ */
+static inline long double add_adjusted(long double a, long double b)
+{
+	struct dd sum;
+	union ldshape u;
+
+	sum = dd_add(a, b);
+	if (sum.lo != 0) {
+		u.f = sum.hi;
+		if (!LASTBIT(u))
+			sum.hi = nextafterl(sum.hi, INFINITY * sum.lo);
+	}
+	return (sum.hi);
+}
+
+/*
+ * Compute ldexp(a+b, scale) with a single rounding error. It is assumed
+ * that the result will be subnormal, and care is taken to ensure that
+ * double rounding does not occur.
+ */
+static inline long double add_and_denormalize(long double a, long double b, int scale)
+{
+	struct dd sum;
+	int bits_lost;
+	union ldshape u;
+
+	sum = dd_add(a, b);
+
+	/*
+	 * If we are losing at least two bits of accuracy to denormalization,
+	 * then the first lost bit becomes a round bit, and we adjust the
+	 * lowest bit of sum.hi to make it a sticky bit summarizing all the
+	 * bits in sum.lo. With the sticky bit adjusted, the hardware will
+	 * break any ties in the correct direction.
+	 *
+	 * If we are losing only one bit to denormalization, however, we must
+	 * break the ties manually.
+	 */
+	if (sum.lo != 0) {
+		u.f = sum.hi;
+		bits_lost = -u.i.se - scale + 1;
+		if ((bits_lost != 1) ^ LASTBIT(u))
+			sum.hi = nextafterl(sum.hi, INFINITY * sum.lo);
+	}
+	return scalbnl(sum.hi, scale);
+}
+
+/*
+ * Compute a*b exactly, returning the exact result in a struct dd.  We assume
+ * that both a and b are normalized, so no underflow or overflow will occur.
+ * The current rounding mode must be round-to-nearest.
+ */
+static inline struct dd dd_mul(long double a, long double b)
+{
+	struct dd ret;
+	long double ha, hb, la, lb, p, q;
+
+	p = a * SPLIT;
+	ha = a - p;
+	ha += p;
+	la = a - ha;
+
+	p = b * SPLIT;
+	hb = b - p;
+	hb += p;
+	lb = b - hb;
+
+	p = ha * hb;
+	q = ha * lb + la * hb;
+
+	ret.hi = p + q;
+	ret.lo = p - ret.hi + q + la * lb;
+	return (ret);
+}
+
+/*
+ * Fused multiply-add: Compute x * y + z with a single rounding error.
+ *
+ * We use scaling to avoid overflow/underflow, along with the
+ * canonical precision-doubling technique adapted from:
+ *
+ *      Dekker, T.  A Floating-Point Technique for Extending the
+ *      Available Precision.  Numer. Math. 18, 224-242 (1971).
+ */
+long double fmal(long double x, long double y, long double z)
+{
+	#pragma STDC FENV_ACCESS ON
+	long double xs, ys, zs, adj;
+	struct dd xy, r;
+	int oround;
+	int ex, ey, ez;
+	int spread;
+
+	/*
+	 * Handle special cases. The order of operations and the particular
+	 * return values here are crucial in handling special cases involving
+	 * infinities, NaNs, overflows, and signed zeroes correctly.
+	 */
+	if (!isfinite(x) || !isfinite(y))
+		return (x * y + z);
+	if (!isfinite(z))
+		return (z);
+	if (x == 0.0 || y == 0.0)
+		return (x * y + z);
+	if (z == 0.0)
+		return (x * y);
+
+	xs = frexpl(x, &ex);
+	ys = frexpl(y, &ey);
+	zs = frexpl(z, &ez);
+	oround = fegetround();
+	spread = ex + ey - ez;
+
+	/*
+	 * If x * y and z are many orders of magnitude apart, the scaling
+	 * will overflow, so we handle these cases specially.  Rounding
+	 * modes other than FE_TONEAREST are painful.
+	 */
+	if (spread < -LDBL_MANT_DIG) {
+#ifdef FE_INEXACT
+		feraiseexcept(FE_INEXACT);
+#endif
+#ifdef FE_UNDERFLOW
+		if (!isnormal(z))
+			feraiseexcept(FE_UNDERFLOW);
+#endif
+		switch (oround) {
+		default: /* FE_TONEAREST */
+			return (z);
+#ifdef FE_TOWARDZERO
+		case FE_TOWARDZERO:
+			if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
+				return (z);
+			else
+				return (nextafterl(z, 0));
+#endif
+#ifdef FE_DOWNWARD
+		case FE_DOWNWARD:
+			if (x > 0.0 ^ y < 0.0)
+				return (z);
+			else
+				return (nextafterl(z, -INFINITY));
+#endif
+#ifdef FE_UPWARD
+		case FE_UPWARD:
+			if (x > 0.0 ^ y < 0.0)
+				return (nextafterl(z, INFINITY));
+			else
+				return (z);
+#endif
+		}
+	}
+	if (spread <= LDBL_MANT_DIG * 2)
+		zs = scalbnl(zs, -spread);
+	else
+		zs = copysignl(LDBL_MIN, zs);
+
+	fesetround(FE_TONEAREST);
+
+	/*
+	 * Basic approach for round-to-nearest:
+	 *
+	 *     (xy.hi, xy.lo) = x * y           (exact)
+	 *     (r.hi, r.lo)   = xy.hi + z       (exact)
+	 *     adj = xy.lo + r.lo               (inexact; low bit is sticky)
+	 *     result = r.hi + adj              (correctly rounded)
+	 */
+	xy = dd_mul(xs, ys);
+	r = dd_add(xy.hi, zs);
+
+	spread = ex + ey;
+
+	if (r.hi == 0.0) {
+		/*
+		 * When the addends cancel to 0, ensure that the result has
+		 * the correct sign.
+		 */
+		fesetround(oround);
+		volatile long double vzs = zs; /* XXX gcc CSE bug workaround */
+		return xy.hi + vzs + scalbnl(xy.lo, spread);
+	}
+
+	if (oround != FE_TONEAREST) {
+		/*
+		 * There is no need to worry about double rounding in directed
+		 * rounding modes.
+		 * But underflow may not be raised correctly, example in downward rounding:
+		 * fmal(0x1.0000000001p-16000L, 0x1.0000000001p-400L, -0x1p-16440L)
+		 */
+		long double ret;
+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)
+		int e = fetestexcept(FE_INEXACT);
+		feclearexcept(FE_INEXACT);
+#endif
+		fesetround(oround);
+		adj = r.lo + xy.lo;
+		ret = scalbnl(r.hi + adj, spread);
+#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)
+		if (ilogbl(ret) < -16382 && fetestexcept(FE_INEXACT))
+			feraiseexcept(FE_UNDERFLOW);
+		else if (e)
+			feraiseexcept(FE_INEXACT);
+#endif
+		return ret;
+	}
+
+	adj = add_adjusted(r.lo, xy.lo);
+	if (spread + ilogbl(r.hi) > -16383)
+		return scalbnl(r.hi + adj, spread);
+	else
+		return add_and_denormalize(r.hi, adj, spread);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmax.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmax.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmax.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <math.h>
+
+double fmax(double x, double y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeros, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? y : x;
+	return x < y ? y : x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmaxf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmaxf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmaxf.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <math.h>
+
+float fmaxf(float x, float y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeroes, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? y : x;
+	return x < y ? y : x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmaxl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmaxl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmaxl.c	(revision 398)
@@ -0,0 +1,21 @@
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fmaxl(long double x, long double y)
+{
+	return fmax(x, y);
+}
+#else
+long double fmaxl(long double x, long double y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeros, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? y : x;
+	return x < y ? y : x;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmin.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmin.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmin.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <math.h>
+
+double fmin(double x, double y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeros, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? x : y;
+	return x < y ? x : y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fminf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fminf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fminf.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <math.h>
+
+float fminf(float x, float y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeros, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? x : y;
+	return x < y ? x : y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fminl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fminl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fminl.c	(revision 398)
@@ -0,0 +1,21 @@
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fminl(long double x, long double y)
+{
+	return fmin(x, y);
+}
+#else
+long double fminl(long double x, long double y)
+{
+	if (isnan(x))
+		return y;
+	if (isnan(y))
+		return x;
+	/* handle signed zeros, see C99 Annex F.9.9.2 */
+	if (signbit(x) != signbit(y))
+		return signbit(x) ? x : y;
+	return x < y ? x : y;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmod.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmod.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmod.c	(revision 398)
@@ -0,0 +1,68 @@
+#include <math.h>
+#include <stdint.h>
+
+double fmod(double x, double y)
+{
+	union {double f; uint64_t i;} ux = {x}, uy = {y};
+	int ex = ux.i>>52 & 0x7ff;
+	int ey = uy.i>>52 & 0x7ff;
+	int sx = ux.i>>63;
+	uint64_t i;
+
+	/* in the followings uxi should be ux.i, but then gcc wrongly adds */
+	/* float load/store to inner loops ruining performance and code size */
+	uint64_t uxi = ux.i;
+
+	if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
+		return (x*y)/(x*y);
+	if (uxi<<1 <= uy.i<<1) {
+		if (uxi<<1 == uy.i<<1)
+			return 0*x;
+		return x;
+	}
+
+	/* normalize x and y */
+	if (!ex) {
+		for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);
+		uxi <<= -ex + 1;
+	} else {
+		uxi &= -1ULL >> 12;
+		uxi |= 1ULL << 52;
+	}
+	if (!ey) {
+		for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);
+		uy.i <<= -ey + 1;
+	} else {
+		uy.i &= -1ULL >> 12;
+		uy.i |= 1ULL << 52;
+	}
+
+	/* x mod y */
+	for (; ex > ey; ex--) {
+		i = uxi - uy.i;
+		if (i >> 63 == 0) {
+			if (i == 0)
+				return 0*x;
+			uxi = i;
+		}
+		uxi <<= 1;
+	}
+	i = uxi - uy.i;
+	if (i >> 63 == 0) {
+		if (i == 0)
+			return 0*x;
+		uxi = i;
+	}
+	for (; uxi>>52 == 0; uxi <<= 1, ex--);
+
+	/* scale result */
+	if (ex > 0) {
+		uxi -= 1ULL << 52;
+		uxi |= (uint64_t)ex << 52;
+	} else {
+		uxi >>= -ex + 1;
+	}
+	uxi |= (uint64_t)sx << 63;
+	ux.i = uxi;
+	return ux.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmodf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmodf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmodf.c	(revision 398)
@@ -0,0 +1,65 @@
+#include <math.h>
+#include <stdint.h>
+
+float fmodf(float x, float y)
+{
+	union {float f; uint32_t i;} ux = {x}, uy = {y};
+	int ex = ux.i>>23 & 0xff;
+	int ey = uy.i>>23 & 0xff;
+	uint32_t sx = ux.i & 0x80000000;
+	uint32_t i;
+	uint32_t uxi = ux.i;
+
+	if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
+		return (x*y)/(x*y);
+	if (uxi<<1 <= uy.i<<1) {
+		if (uxi<<1 == uy.i<<1)
+			return 0*x;
+		return x;
+	}
+
+	/* normalize x and y */
+	if (!ex) {
+		for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);
+		uxi <<= -ex + 1;
+	} else {
+		uxi &= -1U >> 9;
+		uxi |= 1U << 23;
+	}
+	if (!ey) {
+		for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);
+		uy.i <<= -ey + 1;
+	} else {
+		uy.i &= -1U >> 9;
+		uy.i |= 1U << 23;
+	}
+
+	/* x mod y */
+	for (; ex > ey; ex--) {
+		i = uxi - uy.i;
+		if (i >> 31 == 0) {
+			if (i == 0)
+				return 0*x;
+			uxi = i;
+		}
+		uxi <<= 1;
+	}
+	i = uxi - uy.i;
+	if (i >> 31 == 0) {
+		if (i == 0)
+			return 0*x;
+		uxi = i;
+	}
+	for (; uxi>>23 == 0; uxi <<= 1, ex--);
+
+	/* scale result up */
+	if (ex > 0) {
+		uxi -= 1U << 23;
+		uxi |= (uint32_t)ex << 23;
+	} else {
+		uxi >>= -ex + 1;
+	}
+	uxi |= sx;
+	ux.i = uxi;
+	return ux.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmodl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmodl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/fmodl.c	(revision 398)
@@ -0,0 +1,105 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double fmodl(long double x, long double y)
+{
+	return fmod(x, y);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double fmodl(long double x, long double y)
+{
+	union ldshape ux = {x}, uy = {y};
+	int ex = ux.i.se & 0x7fff;
+	int ey = uy.i.se & 0x7fff;
+	int sx = ux.i.se & 0x8000;
+
+	if (y == 0 || isnan(y) || ex == 0x7fff)
+		return (x*y)/(x*y);
+	ux.i.se = ex;
+	uy.i.se = ey;
+	if (ux.f <= uy.f) {
+		if (ux.f == uy.f)
+			return 0*x;
+		return x;
+	}
+
+	/* normalize x and y */
+	if (!ex) {
+		ux.f *= 0x1p120f;
+		ex = ux.i.se - 120;
+	}
+	if (!ey) {
+		uy.f *= 0x1p120f;
+		ey = uy.i.se - 120;
+	}
+
+	/* x mod y */
+#if LDBL_MANT_DIG == 64
+	uint64_t i, mx, my;
+	mx = ux.i.m;
+	my = uy.i.m;
+	for (; ex > ey; ex--) {
+		i = mx - my;
+		if (mx >= my) {
+			if (i == 0)
+				return 0*x;
+			mx = 2*i;
+		} else if (2*mx < mx) {
+			mx = 2*mx - my;
+		} else {
+			mx = 2*mx;
+		}
+	}
+	i = mx - my;
+	if (mx >= my) {
+		if (i == 0)
+			return 0*x;
+		mx = i;
+	}
+	for (; mx >> 63 == 0; mx *= 2, ex--);
+	ux.i.m = mx;
+#elif LDBL_MANT_DIG == 113
+	uint64_t hi, lo, xhi, xlo, yhi, ylo;
+	xhi = (ux.i2.hi & -1ULL>>16) | 1ULL<<48;
+	yhi = (uy.i2.hi & -1ULL>>16) | 1ULL<<48;
+	xlo = ux.i2.lo;
+	ylo = uy.i2.lo;
+	for (; ex > ey; ex--) {
+		hi = xhi - yhi;
+		lo = xlo - ylo;
+		if (xlo < ylo)
+			hi -= 1;
+		if (hi >> 63 == 0) {
+			if ((hi|lo) == 0)
+				return 0*x;
+			xhi = 2*hi + (lo>>63);
+			xlo = 2*lo;
+		} else {
+			xhi = 2*xhi + (xlo>>63);
+			xlo = 2*xlo;
+		}
+	}
+	hi = xhi - yhi;
+	lo = xlo - ylo;
+	if (xlo < ylo)
+		hi -= 1;
+	if (hi >> 63 == 0) {
+		if ((hi|lo) == 0)
+			return 0*x;
+		xhi = hi;
+		xlo = lo;
+	}
+	for (; xhi >> 48 == 0; xhi = 2*xhi + (xlo>>63), xlo = 2*xlo, ex--);
+	ux.i2.hi = xhi;
+	ux.i2.lo = xlo;
+#endif
+
+	/* scale result */
+	if (ex <= 0) {
+		ux.i.se = (ex+120)|sx;
+		ux.f *= 0x1p-120f;
+	} else
+		ux.i.se = ex|sx;
+	return ux.f;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/frexp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/frexp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/frexp.c	(revision 398)
@@ -0,0 +1,23 @@
+#include <math.h>
+#include <stdint.h>
+
+double frexp(double x, int *e)
+{
+	union { double d; uint64_t i; } y = { x };
+	int ee = y.i>>52 & 0x7ff;
+
+	if (!ee) {
+		if (x) {
+			x = frexp(x*0x1p64, e);
+			*e -= 64;
+		} else *e = 0;
+		return x;
+	} else if (ee == 0x7ff) {
+		return x;
+	}
+
+	*e = ee - 0x3fe;
+	y.i &= 0x800fffffffffffffull;
+	y.i |= 0x3fe0000000000000ull;
+	return y.d;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/frexpf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/frexpf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/frexpf.c	(revision 398)
@@ -0,0 +1,23 @@
+#include <math.h>
+#include <stdint.h>
+
+float frexpf(float x, int *e)
+{
+	union { float f; uint32_t i; } y = { x };
+	int ee = y.i>>23 & 0xff;
+
+	if (!ee) {
+		if (x) {
+			x = frexpf(x*0x1p64, e);
+			*e -= 64;
+		} else *e = 0;
+		return x;
+	} else if (ee == 0xff) {
+		return x;
+	}
+
+	*e = ee - 0x7e;
+	y.i &= 0x807ffffful;
+	y.i |= 0x3f000000ul;
+	return y.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/frexpl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/frexpl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/frexpl.c	(revision 398)
@@ -0,0 +1,29 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double frexpl(long double x, int *e)
+{
+	return frexp(x, e);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double frexpl(long double x, int *e)
+{
+	union ldshape u = {x};
+	int ee = u.i.se & 0x7fff;
+
+	if (!ee) {
+		if (x) {
+			x = frexpl(x*0x1p120, e);
+			*e -= 120;
+		} else *e = 0;
+		return x;
+	} else if (ee == 0x7fff) {
+		return x;
+	}
+
+	*e = ee - 0x3ffe;
+	u.i.se &= 0x8000;
+	u.i.se |= 0x3ffe;
+	return u.f;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/hypot.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/hypot.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/hypot.c	(revision 398)
@@ -0,0 +1,67 @@
+#include <math.h>
+#include <stdint.h>
+#include <float.h>
+
+#if FLT_EVAL_METHOD > 1U && LDBL_MANT_DIG == 64
+#define SPLIT (0x1p32 + 1)
+#else
+#define SPLIT (0x1p27 + 1)
+#endif
+
+static void sq(double_t *hi, double_t *lo, double x)
+{
+	double_t xh, xl, xc;
+
+	xc = (double_t)x*SPLIT;
+	xh = x - xc + xc;
+	xl = x - xh;
+	*hi = (double_t)x*x;
+	*lo = xh*xh - *hi + 2*xh*xl + xl*xl;
+}
+
+double hypot(double x, double y)
+{
+	union {double f; uint64_t i;} ux = {x}, uy = {y}, ut;
+	int ex, ey;
+	double_t hx, lx, hy, ly, z;
+
+	/* arrange |x| >= |y| */
+	ux.i &= -1ULL>>1;
+	uy.i &= -1ULL>>1;
+	if (ux.i < uy.i) {
+		ut = ux;
+		ux = uy;
+		uy = ut;
+	}
+
+	/* special cases */
+	ex = ux.i>>52;
+	ey = uy.i>>52;
+	x = ux.f;
+	y = uy.f;
+	/* note: hypot(inf,nan) == inf */
+	if (ey == 0x7ff)
+		return y;
+	if (ex == 0x7ff || uy.i == 0)
+		return x;
+	/* note: hypot(x,y) ~= x + y*y/x/2 with inexact for small y/x */
+	/* 64 difference is enough for ld80 double_t */
+	if (ex - ey > 64)
+		return x + y;
+
+	/* precise sqrt argument in nearest rounding mode without overflow */
+	/* xh*xh must not overflow and xl*xl must not underflow in sq */
+	z = 1;
+	if (ex > 0x3ff+510) {
+		z = 0x1p700;
+		x *= 0x1p-700;
+		y *= 0x1p-700;
+	} else if (ey < 0x3ff-450) {
+		z = 0x1p-700;
+		x *= 0x1p700;
+		y *= 0x1p700;
+	}
+	sq(&hx, &lx, x);
+	sq(&hy, &ly, y);
+	return z*sqrt(ly+lx+hy+hx);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/hypotf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/hypotf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/hypotf.c	(revision 398)
@@ -0,0 +1,35 @@
+#include <math.h>
+#include <stdint.h>
+
+float hypotf(float x, float y)
+{
+	union {float f; uint32_t i;} ux = {x}, uy = {y}, ut;
+	float_t z;
+
+	ux.i &= -1U>>1;
+	uy.i &= -1U>>1;
+	if (ux.i < uy.i) {
+		ut = ux;
+		ux = uy;
+		uy = ut;
+	}
+
+	x = ux.f;
+	y = uy.f;
+	if (uy.i == 0xff<<23)
+		return y;
+	if (ux.i >= 0xff<<23 || uy.i == 0 || ux.i - uy.i >= 25<<23)
+		return x + y;
+
+	z = 1;
+	if (ux.i >= (0x7f+60)<<23) {
+		z = 0x1p90f;
+		x *= 0x1p-90f;
+		y *= 0x1p-90f;
+	} else if (uy.i < (0x7f-60)<<23) {
+		z = 0x1p-90f;
+		x *= 0x1p90f;
+		y *= 0x1p90f;
+	}
+	return z*sqrtf((double)x*x + (double)y*y);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/hypotl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/hypotl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/hypotl.c	(revision 398)
@@ -0,0 +1,66 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double hypotl(long double x, long double y)
+{
+	return hypot(x, y);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+#if LDBL_MANT_DIG == 64
+#define SPLIT (0x1p32L+1)
+#elif LDBL_MANT_DIG == 113
+#define SPLIT (0x1p57L+1)
+#endif
+
+static void sq(long double *hi, long double *lo, long double x)
+{
+	long double xh, xl, xc;
+	xc = x*SPLIT;
+	xh = x - xc + xc;
+	xl = x - xh;
+	*hi = x*x;
+	*lo = xh*xh - *hi + 2*xh*xl + xl*xl;
+}
+
+long double hypotl(long double x, long double y)
+{
+	union ldshape ux = {x}, uy = {y};
+	int ex, ey;
+	long double hx, lx, hy, ly, z;
+
+	ux.i.se &= 0x7fff;
+	uy.i.se &= 0x7fff;
+	if (ux.i.se < uy.i.se) {
+		ex = uy.i.se;
+		ey = ux.i.se;
+		x = uy.f;
+		y = ux.f;
+	} else {
+		ex = ux.i.se;
+		ey = uy.i.se;
+		x = ux.f;
+		y = uy.f;
+	}
+
+	if (ex == 0x7fff && isinf(y))
+		return y;
+	if (ex == 0x7fff || y == 0)
+		return x;
+	if (ex - ey > LDBL_MANT_DIG)
+		return x + y;
+
+	z = 1;
+	if (ex > 0x3fff+8000) {
+		z = 0x1p10000L;
+		x *= 0x1p-10000L;
+		y *= 0x1p-10000L;
+	} else if (ey < 0x3fff-8000) {
+		z = 0x1p-10000L;
+		x *= 0x1p10000L;
+		y *= 0x1p10000L;
+	}
+	sq(&hx, &lx, x);
+	sq(&hy, &ly, y);
+	return z*sqrtl(ly+lx+hy+hx);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ilogb.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ilogb.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ilogb.c	(revision 398)
@@ -0,0 +1,26 @@
+#include <limits.h>
+#include "libm.h"
+
+int ilogb(double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	union {double f; uint64_t i;} u = {x};
+	uint64_t i = u.i;
+	int e = i>>52 & 0x7ff;
+
+	if (!e) {
+		i <<= 12;
+		if (i == 0) {
+			FORCE_EVAL(0/0.0f);
+			return FP_ILOGB0;
+		}
+		/* subnormal x */
+		for (e = -0x3ff; i>>63 == 0; e--, i<<=1);
+		return e;
+	}
+	if (e == 0x7ff) {
+		FORCE_EVAL(0/0.0f);
+		return i<<12 ? FP_ILOGBNAN : INT_MAX;
+	}
+	return e - 0x3ff;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ilogbf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ilogbf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ilogbf.c	(revision 398)
@@ -0,0 +1,26 @@
+#include <limits.h>
+#include "libm.h"
+
+int ilogbf(float x)
+{
+	#pragma STDC FENV_ACCESS ON
+	union {float f; uint32_t i;} u = {x};
+	uint32_t i = u.i;
+	int e = i>>23 & 0xff;
+
+	if (!e) {
+		i <<= 9;
+		if (i == 0) {
+			FORCE_EVAL(0/0.0f);
+			return FP_ILOGB0;
+		}
+		/* subnormal x */
+		for (e = -0x7f; i>>31 == 0; e--, i<<=1);
+		return e;
+	}
+	if (e == 0xff) {
+		FORCE_EVAL(0/0.0f);
+		return i<<9 ? FP_ILOGBNAN : INT_MAX;
+	}
+	return e - 0x7f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ilogbl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ilogbl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ilogbl.c	(revision 398)
@@ -0,0 +1,55 @@
+#include <limits.h>
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+int ilogbl(long double x)
+{
+	return ilogb(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+int ilogbl(long double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	union ldshape u = {x};
+	uint64_t m = u.i.m;
+	int e = u.i.se & 0x7fff;
+
+	if (!e) {
+		if (m == 0) {
+			FORCE_EVAL(0/0.0f);
+			return FP_ILOGB0;
+		}
+		/* subnormal x */
+		for (e = -0x3fff+1; m>>63 == 0; e--, m<<=1);
+		return e;
+	}
+	if (e == 0x7fff) {
+		FORCE_EVAL(0/0.0f);
+		return m<<1 ? FP_ILOGBNAN : INT_MAX;
+	}
+	return e - 0x3fff;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+int ilogbl(long double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+
+	if (!e) {
+		if (x == 0) {
+			FORCE_EVAL(0/0.0f);
+			return FP_ILOGB0;
+		}
+		/* subnormal x */
+		x *= 0x1p120;
+		return ilogbl(x) - 120;
+	}
+	if (e == 0x7fff) {
+		FORCE_EVAL(0/0.0f);
+		u.i.se = 0;
+		return u.f ? FP_ILOGBNAN : INT_MAX;
+	}
+	return e - 0x3fff;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j0.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j0.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j0.c	(revision 398)
@@ -0,0 +1,375 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_j0.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* j0(x), y0(x)
+ * Bessel function of the first and second kinds of order zero.
+ * Method -- j0(x):
+ *      1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ...
+ *      2. Reduce x to |x| since j0(x)=j0(-x),  and
+ *         for x in (0,2)
+ *              j0(x) = 1-z/4+ z^2*R0/S0,  where z = x*x;
+ *         (precision:  |j0-1+z/4-z^2R0/S0 |<2**-63.67 )
+ *         for x in (2,inf)
+ *              j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0))
+ *         where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ *         as follow:
+ *              cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ *                      = 1/sqrt(2) * (cos(x) + sin(x))
+ *              sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4)
+ *                      = 1/sqrt(2) * (sin(x) - cos(x))
+ *         (To avoid cancellation, use
+ *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ *          to compute the worse one.)
+ *
+ *      3 Special cases
+ *              j0(nan)= nan
+ *              j0(0) = 1
+ *              j0(inf) = 0
+ *
+ * Method -- y0(x):
+ *      1. For x<2.
+ *         Since
+ *              y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...)
+ *         therefore y0(x)-2/pi*j0(x)*ln(x) is an even function.
+ *         We use the following function to approximate y0,
+ *              y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2
+ *         where
+ *              U(z) = u00 + u01*z + ... + u06*z^6
+ *              V(z) = 1  + v01*z + ... + v04*z^4
+ *         with absolute approximation error bounded by 2**-72.
+ *         Note: For tiny x, U/V = u0 and j0(x)~1, hence
+ *              y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27)
+ *      2. For x>=2.
+ *              y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0))
+ *         where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ *         by the method mentioned above.
+ *      3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0.
+ */
+
+#include "libm.h"
+
+static double pzero(double), qzero(double);
+
+static const double
+invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+tpi       = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */
+
+/* common method when |x|>=2 */
+static double common(uint32_t ix, double x, int y0)
+{
+	double s,c,ss,cc,z;
+
+	/*
+	 * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x-pi/4)-q0(x)*sin(x-pi/4))
+	 * y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x-pi/4)+q0(x)*cos(x-pi/4))
+	 *
+	 * sin(x-pi/4) = (sin(x) - cos(x))/sqrt(2)
+	 * cos(x-pi/4) = (sin(x) + cos(x))/sqrt(2)
+	 * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+	 */
+	s = sin(x);
+	c = cos(x);
+	if (y0)
+		c = -c;
+	cc = s+c;
+	/* avoid overflow in 2*x, big ulp error when x>=0x1p1023 */
+	if (ix < 0x7fe00000) {
+		ss = s-c;
+		z = -cos(2*x);
+		if (s*c < 0)
+			cc = z/ss;
+		else
+			ss = z/cc;
+		if (ix < 0x48000000) {
+			if (y0)
+				ss = -ss;
+			cc = pzero(x)*cc-qzero(x)*ss;
+		}
+	}
+	return invsqrtpi*cc/sqrt(x);
+}
+
+/* R0/S0 on [0, 2.00] */
+static const double
+R02 =  1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */
+R03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */
+R04 =  1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */
+R05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */
+S01 =  1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */
+S02 =  1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */
+S03 =  5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */
+S04 =  1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */
+
+double j0(double x)
+{
+	double z,r,s;
+	uint32_t ix;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+
+	/* j0(+-inf)=0, j0(nan)=nan */
+	if (ix >= 0x7ff00000)
+		return 1/(x*x);
+	x = fabs(x);
+
+	if (ix >= 0x40000000) {  /* |x| >= 2 */
+		/* large ulp error near zeros: 2.4, 5.52, 8.6537,.. */
+		return common(ix,x,0);
+	}
+
+	/* 1 - x*x/4 + x*x*R(x^2)/S(x^2) */
+	if (ix >= 0x3f200000) {  /* |x| >= 2**-13 */
+		/* up to 4ulp error close to 2 */
+		z = x*x;
+		r = z*(R02+z*(R03+z*(R04+z*R05)));
+		s = 1+z*(S01+z*(S02+z*(S03+z*S04)));
+		return (1+x/2)*(1-x/2) + z*(r/s);
+	}
+
+	/* 1 - x*x/4 */
+	/* prevent underflow */
+	/* inexact should be raised when x!=0, this is not done correctly */
+	if (ix >= 0x38000000)  /* |x| >= 2**-127 */
+		x = 0.25*x*x;
+	return 1 - x;
+}
+
+static const double
+u00  = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */
+u01  =  1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */
+u02  = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */
+u03  =  3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */
+u04  = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */
+u05  =  1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */
+u06  = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */
+v01  =  1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */
+v02  =  7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */
+v03  =  2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */
+v04  =  4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */
+
+double y0(double x)
+{
+	double z,u,v;
+	uint32_t ix,lx;
+
+	EXTRACT_WORDS(ix, lx, x);
+
+	/* y0(nan)=nan, y0(<0)=nan, y0(0)=-inf, y0(inf)=0 */
+	if ((ix<<1 | lx) == 0)
+		return -1/0.0;
+	if (ix>>31)
+		return 0/0.0;
+	if (ix >= 0x7ff00000)
+		return 1/x;
+
+	if (ix >= 0x40000000) {  /* x >= 2 */
+		/* large ulp errors near zeros: 3.958, 7.086,.. */
+		return common(ix,x,1);
+	}
+
+	/* U(x^2)/V(x^2) + (2/pi)*j0(x)*log(x) */
+	if (ix >= 0x3e400000) {  /* x >= 2**-27 */
+		/* large ulp error near the first zero, x ~= 0.89 */
+		z = x*x;
+		u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
+		v = 1.0+z*(v01+z*(v02+z*(v03+z*v04)));
+		return u/v + tpi*(j0(x)*log(x));
+	}
+	return u00 + tpi*log(x);
+}
+
+/* The asymptotic expansions of pzero is
+ *      1 - 9/128 s^2 + 11025/98304 s^4 - ...,  where s = 1/x.
+ * For x >= 2, We approximate pzero by
+ *      pzero(x) = 1 + (R/S)
+ * where  R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10
+ *        S = 1 + pS0*s^2 + ... + pS4*s^10
+ * and
+ *      | pzero(x)-1-R/S | <= 2  ** ( -60.26)
+ */
+static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */
+ -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */
+ -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */
+ -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */
+ -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */
+};
+static const double pS8[5] = {
+  1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */
+  3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */
+  4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */
+  1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */
+  4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */
+};
+
+static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */
+ -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */
+ -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */
+ -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */
+ -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */
+ -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */
+};
+static const double pS5[5] = {
+  6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */
+  1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */
+  5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */
+  9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */
+  2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */
+};
+
+static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+ -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */
+ -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */
+ -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */
+ -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */
+ -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */
+ -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */
+};
+static const double pS3[5] = {
+  3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */
+  3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */
+  1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */
+  1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */
+  1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */
+};
+
+static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */
+ -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */
+ -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */
+ -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */
+ -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */
+ -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */
+};
+static const double pS2[5] = {
+  2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */
+  1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */
+  2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */
+  1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */
+  1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */
+};
+
+static double pzero(double x)
+{
+	const double *p,*q;
+	double_t z,r,s;
+	uint32_t ix;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x40200000){p = pR8; q = pS8;}
+	else if (ix >= 0x40122E8B){p = pR5; q = pS5;}
+	else if (ix >= 0x4006DB6D){p = pR3; q = pS3;}
+	else /*ix >= 0x40000000*/ {p = pR2; q = pS2;}
+	z = 1.0/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+	return 1.0 + r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qzero is
+ *      -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
+ * We approximate pzero by
+ *      qzero(x) = s*(-1.25 + (R/S))
+ * where  R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10
+ *        S = 1 + qS0*s^2 + ... + qS5*s^12
+ * and
+ *      | qzero(x)/s +1.25-R/S | <= 2  ** ( -61.22)
+ */
+static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+  7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */
+  1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */
+  5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */
+  8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */
+  3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */
+};
+static const double qS8[6] = {
+  1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */
+  8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */
+  1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */
+  8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */
+  8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */
+ -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */
+};
+
+static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+  1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */
+  7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */
+  5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */
+  1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */
+  1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */
+  1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */
+};
+static const double qS5[6] = {
+  8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */
+  2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */
+  1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */
+  5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */
+  3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */
+ -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */
+};
+
+static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+  4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */
+  7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */
+  3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */
+  4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */
+  1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */
+  1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */
+};
+static const double qS3[6] = {
+  4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */
+  7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */
+  3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */
+  6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */
+  2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */
+ -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */
+};
+
+static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+  1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */
+  7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */
+  1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */
+  1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */
+  3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */
+  1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */
+};
+static const double qS2[6] = {
+  3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */
+  2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */
+  8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */
+  8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */
+  2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */
+ -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */
+};
+
+static double qzero(double x)
+{
+	const double *p,*q;
+	double_t s,r,z;
+	uint32_t ix;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x40200000){p = qR8; q = qS8;}
+	else if (ix >= 0x40122E8B){p = qR5; q = qS5;}
+	else if (ix >= 0x4006DB6D){p = qR3; q = qS3;}
+	else /*ix >= 0x40000000*/ {p = qR2; q = qS2;}
+	z = 1.0/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+	return (-.125 + r/s)/x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j0f.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j0f.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j0f.c	(revision 398)
@@ -0,0 +1,314 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_j0f.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+static float pzerof(float), qzerof(float);
+
+static const float
+invsqrtpi = 5.6418961287e-01, /* 0x3f106ebb */
+tpi       = 6.3661974669e-01; /* 0x3f22f983 */
+
+static float common(uint32_t ix, float x, int y0)
+{
+	float z,s,c,ss,cc;
+	/*
+	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+	 */
+	s = sinf(x);
+	c = cosf(x);
+	if (y0)
+		c = -c;
+	cc = s+c;
+	if (ix < 0x7f000000) {
+		ss = s-c;
+		z = -cosf(2*x);
+		if (s*c < 0)
+			cc = z/ss;
+		else
+			ss = z/cc;
+		if (ix < 0x58800000) {
+			if (y0)
+				ss = -ss;
+			cc = pzerof(x)*cc-qzerof(x)*ss;
+		}
+	}
+	return invsqrtpi*cc/sqrtf(x);
+}
+
+/* R0/S0 on [0, 2.00] */
+static const float
+R02 =  1.5625000000e-02, /* 0x3c800000 */
+R03 = -1.8997929874e-04, /* 0xb947352e */
+R04 =  1.8295404516e-06, /* 0x35f58e88 */
+R05 = -4.6183270541e-09, /* 0xb19eaf3c */
+S01 =  1.5619102865e-02, /* 0x3c7fe744 */
+S02 =  1.1692678527e-04, /* 0x38f53697 */
+S03 =  5.1354652442e-07, /* 0x3509daa6 */
+S04 =  1.1661400734e-09; /* 0x30a045e8 */
+
+float j0f(float x)
+{
+	float z,r,s;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if (ix >= 0x7f800000)
+		return 1/(x*x);
+	x = fabsf(x);
+
+	if (ix >= 0x40000000) {  /* |x| >= 2 */
+		/* large ulp error near zeros */
+		return common(ix, x, 0);
+	}
+	if (ix >= 0x3a000000) {  /* |x| >= 2**-11 */
+		/* up to 4ulp error near 2 */
+		z = x*x;
+		r = z*(R02+z*(R03+z*(R04+z*R05)));
+		s = 1+z*(S01+z*(S02+z*(S03+z*S04)));
+		return (1+x/2)*(1-x/2) + z*(r/s);
+	}
+	if (ix >= 0x21800000)  /* |x| >= 2**-60 */
+		x = 0.25f*x*x;
+	return 1 - x;
+}
+
+static const float
+u00  = -7.3804296553e-02, /* 0xbd9726b5 */
+u01  =  1.7666645348e-01, /* 0x3e34e80d */
+u02  = -1.3818567619e-02, /* 0xbc626746 */
+u03  =  3.4745343146e-04, /* 0x39b62a69 */
+u04  = -3.8140706238e-06, /* 0xb67ff53c */
+u05  =  1.9559013964e-08, /* 0x32a802ba */
+u06  = -3.9820518410e-11, /* 0xae2f21eb */
+v01  =  1.2730483897e-02, /* 0x3c509385 */
+v02  =  7.6006865129e-05, /* 0x389f65e0 */
+v03  =  2.5915085189e-07, /* 0x348b216c */
+v04  =  4.4111031494e-10; /* 0x2ff280c2 */
+
+float y0f(float x)
+{
+	float z,u,v;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	if ((ix & 0x7fffffff) == 0)
+		return -1/0.0f;
+	if (ix>>31)
+		return 0/0.0f;
+	if (ix >= 0x7f800000)
+		return 1/x;
+	if (ix >= 0x40000000) {  /* |x| >= 2.0 */
+		/* large ulp error near zeros */
+		return common(ix,x,1);
+	}
+	if (ix >= 0x39000000) {  /* x >= 2**-13 */
+		/* large ulp error at x ~= 0.89 */
+		z = x*x;
+		u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
+		v = 1+z*(v01+z*(v02+z*(v03+z*v04)));
+		return u/v + tpi*(j0f(x)*logf(x));
+	}
+	return u00 + tpi*logf(x);
+}
+
+/* The asymptotic expansions of pzero is
+ *      1 - 9/128 s^2 + 11025/98304 s^4 - ...,  where s = 1/x.
+ * For x >= 2, We approximate pzero by
+ *      pzero(x) = 1 + (R/S)
+ * where  R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10
+ *        S = 1 + pS0*s^2 + ... + pS4*s^10
+ * and
+ *      | pzero(x)-1-R/S | <= 2  ** ( -60.26)
+ */
+static const float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.0000000000e+00, /* 0x00000000 */
+ -7.0312500000e-02, /* 0xbd900000 */
+ -8.0816707611e+00, /* 0xc1014e86 */
+ -2.5706311035e+02, /* 0xc3808814 */
+ -2.4852163086e+03, /* 0xc51b5376 */
+ -5.2530439453e+03, /* 0xc5a4285a */
+};
+static const float pS8[5] = {
+  1.1653436279e+02, /* 0x42e91198 */
+  3.8337448730e+03, /* 0x456f9beb */
+  4.0597855469e+04, /* 0x471e95db */
+  1.1675296875e+05, /* 0x47e4087c */
+  4.7627726562e+04, /* 0x473a0bba */
+};
+static const float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ -1.1412546255e-11, /* 0xad48c58a */
+ -7.0312492549e-02, /* 0xbd8fffff */
+ -4.1596107483e+00, /* 0xc0851b88 */
+ -6.7674766541e+01, /* 0xc287597b */
+ -3.3123129272e+02, /* 0xc3a59d9b */
+ -3.4643338013e+02, /* 0xc3ad3779 */
+};
+static const float pS5[5] = {
+  6.0753936768e+01, /* 0x42730408 */
+  1.0512523193e+03, /* 0x44836813 */
+  5.9789707031e+03, /* 0x45bad7c4 */
+  9.6254453125e+03, /* 0x461665c8 */
+  2.4060581055e+03, /* 0x451660ee */
+};
+
+static const float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+ -2.5470459075e-09, /* 0xb12f081b */
+ -7.0311963558e-02, /* 0xbd8fffb8 */
+ -2.4090321064e+00, /* 0xc01a2d95 */
+ -2.1965976715e+01, /* 0xc1afba52 */
+ -5.8079170227e+01, /* 0xc2685112 */
+ -3.1447946548e+01, /* 0xc1fb9565 */
+};
+static const float pS3[5] = {
+  3.5856033325e+01, /* 0x420f6c94 */
+  3.6151397705e+02, /* 0x43b4c1ca */
+  1.1936077881e+03, /* 0x44953373 */
+  1.1279968262e+03, /* 0x448cffe6 */
+  1.7358093262e+02, /* 0x432d94b8 */
+};
+
+static const float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ -8.8753431271e-08, /* 0xb3be98b7 */
+ -7.0303097367e-02, /* 0xbd8ffb12 */
+ -1.4507384300e+00, /* 0xbfb9b1cc */
+ -7.6356959343e+00, /* 0xc0f4579f */
+ -1.1193166733e+01, /* 0xc1331736 */
+ -3.2336456776e+00, /* 0xc04ef40d */
+};
+static const float pS2[5] = {
+  2.2220300674e+01, /* 0x41b1c32d */
+  1.3620678711e+02, /* 0x430834f0 */
+  2.7047027588e+02, /* 0x43873c32 */
+  1.5387539673e+02, /* 0x4319e01a */
+  1.4657617569e+01, /* 0x416a859a */
+};
+
+static float pzerof(float x)
+{
+	const float *p,*q;
+	float_t z,r,s;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x41000000){p = pR8; q = pS8;}
+	else if (ix >= 0x409173eb){p = pR5; q = pS5;}
+	else if (ix >= 0x4036d917){p = pR3; q = pS3;}
+	else /*ix >= 0x40000000*/ {p = pR2; q = pS2;}
+	z = 1.0f/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+	return 1.0f + r/s;
+}
+
+
+/* For x >= 8, the asymptotic expansions of qzero is
+ *      -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
+ * We approximate pzero by
+ *      qzero(x) = s*(-1.25 + (R/S))
+ * where  R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10
+ *        S = 1 + qS0*s^2 + ... + qS5*s^12
+ * and
+ *      | qzero(x)/s +1.25-R/S | <= 2  ** ( -61.22)
+ */
+static const float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.0000000000e+00, /* 0x00000000 */
+  7.3242187500e-02, /* 0x3d960000 */
+  1.1768206596e+01, /* 0x413c4a93 */
+  5.5767340088e+02, /* 0x440b6b19 */
+  8.8591972656e+03, /* 0x460a6cca */
+  3.7014625000e+04, /* 0x471096a0 */
+};
+static const float qS8[6] = {
+  1.6377603149e+02, /* 0x4323c6aa */
+  8.0983447266e+03, /* 0x45fd12c2 */
+  1.4253829688e+05, /* 0x480b3293 */
+  8.0330925000e+05, /* 0x49441ed4 */
+  8.4050156250e+05, /* 0x494d3359 */
+ -3.4389928125e+05, /* 0xc8a7eb69 */
+};
+
+static const float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+  1.8408595828e-11, /* 0x2da1ec79 */
+  7.3242180049e-02, /* 0x3d95ffff */
+  5.8356351852e+00, /* 0x40babd86 */
+  1.3511157227e+02, /* 0x43071c90 */
+  1.0272437744e+03, /* 0x448067cd */
+  1.9899779053e+03, /* 0x44f8bf4b */
+};
+static const float qS5[6] = {
+  8.2776611328e+01, /* 0x42a58da0 */
+  2.0778142090e+03, /* 0x4501dd07 */
+  1.8847289062e+04, /* 0x46933e94 */
+  5.6751113281e+04, /* 0x475daf1d */
+  3.5976753906e+04, /* 0x470c88c1 */
+ -5.3543427734e+03, /* 0xc5a752be */
+};
+
+static const float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+  4.3774099900e-09, /* 0x3196681b */
+  7.3241114616e-02, /* 0x3d95ff70 */
+  3.3442313671e+00, /* 0x405607e3 */
+  4.2621845245e+01, /* 0x422a7cc5 */
+  1.7080809021e+02, /* 0x432acedf */
+  1.6673394775e+02, /* 0x4326bbe4 */
+};
+static const float qS3[6] = {
+  4.8758872986e+01, /* 0x42430916 */
+  7.0968920898e+02, /* 0x44316c1c */
+  3.7041481934e+03, /* 0x4567825f */
+  6.4604252930e+03, /* 0x45c9e367 */
+  2.5163337402e+03, /* 0x451d4557 */
+ -1.4924745178e+02, /* 0xc3153f59 */
+};
+
+static const float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+  1.5044444979e-07, /* 0x342189db */
+  7.3223426938e-02, /* 0x3d95f62a */
+  1.9981917143e+00, /* 0x3fffc4bf */
+  1.4495602608e+01, /* 0x4167edfd */
+  3.1666231155e+01, /* 0x41fd5471 */
+  1.6252708435e+01, /* 0x4182058c */
+};
+static const float qS2[6] = {
+  3.0365585327e+01, /* 0x41f2ecb8 */
+  2.6934811401e+02, /* 0x4386ac8f */
+  8.4478375244e+02, /* 0x44533229 */
+  8.8293585205e+02, /* 0x445cbbe5 */
+  2.1266638184e+02, /* 0x4354aa98 */
+ -5.3109550476e+00, /* 0xc0a9f358 */
+};
+
+static float qzerof(float x)
+{
+	const float *p,*q;
+	float_t s,r,z;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x41000000){p = qR8; q = qS8;}
+	else if (ix >= 0x409173eb){p = qR5; q = qS5;}
+	else if (ix >= 0x4036d917){p = qR3; q = qS3;}
+	else /*ix >= 0x40000000*/ {p = qR2; q = qS2;}
+	z = 1.0f/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+	return (-.125f + r/s)/x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j1.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j1.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j1.c	(revision 398)
@@ -0,0 +1,362 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_j1.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* j1(x), y1(x)
+ * Bessel function of the first and second kinds of order zero.
+ * Method -- j1(x):
+ *      1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ...
+ *      2. Reduce x to |x| since j1(x)=-j1(-x),  and
+ *         for x in (0,2)
+ *              j1(x) = x/2 + x*z*R0/S0,  where z = x*x;
+ *         (precision:  |j1/x - 1/2 - R0/S0 |<2**-61.51 )
+ *         for x in (2,inf)
+ *              j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
+ *              y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ *         where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ *         as follow:
+ *              cos(x1) =  cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ *                      =  1/sqrt(2) * (sin(x) - cos(x))
+ *              sin(x1) =  sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ *                      = -1/sqrt(2) * (sin(x) + cos(x))
+ *         (To avoid cancellation, use
+ *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ *          to compute the worse one.)
+ *
+ *      3 Special cases
+ *              j1(nan)= nan
+ *              j1(0) = 0
+ *              j1(inf) = 0
+ *
+ * Method -- y1(x):
+ *      1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN
+ *      2. For x<2.
+ *         Since
+ *              y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...)
+ *         therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function.
+ *         We use the following function to approximate y1,
+ *              y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2
+ *         where for x in [0,2] (abs err less than 2**-65.89)
+ *              U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4
+ *              V(z) = 1  + v0[0]*z + ... + v0[4]*z^5
+ *         Note: For tiny x, 1/x dominate y1 and hence
+ *              y1(tiny) = -2/pi/tiny, (choose tiny<2**-54)
+ *      3. For x>=2.
+ *              y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ *         where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ *         by method mentioned above.
+ */
+
+#include "libm.h"
+
+static double pone(double), qone(double);
+
+static const double
+invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+tpi       = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */
+
+static double common(uint32_t ix, double x, int y1, int sign)
+{
+	double z,s,c,ss,cc;
+
+	/*
+	 * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x-3pi/4)-q1(x)*sin(x-3pi/4))
+	 * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x-3pi/4)+q1(x)*cos(x-3pi/4))
+	 *
+	 * sin(x-3pi/4) = -(sin(x) + cos(x))/sqrt(2)
+	 * cos(x-3pi/4) = (sin(x) - cos(x))/sqrt(2)
+	 * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+	 */
+	s = sin(x);
+	if (y1)
+		s = -s;
+	c = cos(x);
+	cc = s-c;
+	if (ix < 0x7fe00000) {
+		/* avoid overflow in 2*x */
+		ss = -s-c;
+		z = cos(2*x);
+		if (s*c > 0)
+			cc = z/ss;
+		else
+			ss = z/cc;
+		if (ix < 0x48000000) {
+			if (y1)
+				ss = -ss;
+			cc = pone(x)*cc-qone(x)*ss;
+		}
+	}
+	if (sign)
+		cc = -cc;
+	return invsqrtpi*cc/sqrt(x);
+}
+
+/* R0/S0 on [0,2] */
+static const double
+r00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */
+r01 =  1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */
+r02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */
+r03 =  4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */
+s01 =  1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */
+s02 =  1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */
+s03 =  1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */
+s04 =  5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */
+s05 =  1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */
+
+double j1(double x)
+{
+	double z,r,s;
+	uint32_t ix;
+	int sign;
+
+	GET_HIGH_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7ff00000)
+		return 1/(x*x);
+	if (ix >= 0x40000000)  /* |x| >= 2 */
+		return common(ix, fabs(x), 0, sign);
+	if (ix >= 0x38000000) {  /* |x| >= 2**-127 */
+		z = x*x;
+		r = z*(r00+z*(r01+z*(r02+z*r03)));
+		s = 1+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
+		z = r/s;
+	} else
+		/* avoid underflow, raise inexact if x!=0 */
+		z = x;
+	return (0.5 + z)*x;
+}
+
+static const double U0[5] = {
+ -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */
+  5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */
+ -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */
+  2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */
+ -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */
+};
+static const double V0[5] = {
+  1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */
+  2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */
+  1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */
+  6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */
+  1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */
+};
+
+double y1(double x)
+{
+	double z,u,v;
+	uint32_t ix,lx;
+
+	EXTRACT_WORDS(ix, lx, x);
+	/* y1(nan)=nan, y1(<0)=nan, y1(0)=-inf, y1(inf)=0 */
+	if ((ix<<1 | lx) == 0)
+		return -1/0.0;
+	if (ix>>31)
+		return 0/0.0;
+	if (ix >= 0x7ff00000)
+		return 1/x;
+
+	if (ix >= 0x40000000)  /* x >= 2 */
+		return common(ix, x, 1, 0);
+	if (ix < 0x3c900000)  /* x < 2**-54 */
+		return -tpi/x;
+	z = x*x;
+	u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
+	v = 1+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
+	return x*(u/v) + tpi*(j1(x)*log(x)-1/x);
+}
+
+/* For x >= 8, the asymptotic expansions of pone is
+ *      1 + 15/128 s^2 - 4725/2^15 s^4 - ...,   where s = 1/x.
+ * We approximate pone by
+ *      pone(x) = 1 + (R/S)
+ * where  R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
+ *        S = 1 + ps0*s^2 + ... + ps4*s^10
+ * and
+ *      | pone(x)-1-R/S | <= 2  ** ( -60.06)
+ */
+
+static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+  1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */
+  1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */
+  4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */
+  3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */
+  7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */
+};
+static const double ps8[5] = {
+  1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */
+  3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */
+  3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */
+  9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */
+  3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */
+};
+
+static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+  1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */
+  1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */
+  6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */
+  1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */
+  5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */
+  5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */
+};
+static const double ps5[5] = {
+  5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */
+  9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */
+  5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */
+  7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */
+  1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */
+};
+
+static const double pr3[6] = {
+  3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */
+  1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */
+  3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */
+  3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */
+  9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */
+  4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */
+};
+static const double ps3[5] = {
+  3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */
+  3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */
+  1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */
+  8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */
+  1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */
+};
+
+static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+  1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */
+  1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */
+  2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */
+  1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */
+  1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */
+  5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */
+};
+static const double ps2[5] = {
+  2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */
+  1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */
+  2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */
+  1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */
+  8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */
+};
+
+static double pone(double x)
+{
+	const double *p,*q;
+	double_t z,r,s;
+	uint32_t ix;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x40200000){p = pr8; q = ps8;}
+	else if (ix >= 0x40122E8B){p = pr5; q = ps5;}
+	else if (ix >= 0x4006DB6D){p = pr3; q = ps3;}
+	else /*ix >= 0x40000000*/ {p = pr2; q = ps2;}
+	z = 1.0/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+	return 1.0+ r/s;
+}
+
+/* For x >= 8, the asymptotic expansions of qone is
+ *      3/8 s - 105/1024 s^3 - ..., where s = 1/x.
+ * We approximate pone by
+ *      qone(x) = s*(0.375 + (R/S))
+ * where  R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
+ *        S = 1 + qs1*s^2 + ... + qs6*s^12
+ * and
+ *      | qone(x)/s -0.375-R/S | <= 2  ** ( -61.13)
+ */
+
+static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */
+ -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */
+ -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */
+ -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */
+ -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */
+};
+static const double qs8[6] = {
+  1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */
+  7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */
+  1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */
+  7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */
+  6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */
+ -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */
+};
+
+static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */
+ -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */
+ -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */
+ -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */
+ -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */
+ -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */
+};
+static const double qs5[6] = {
+  8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */
+  1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */
+  1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */
+  4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */
+  2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */
+ -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */
+};
+
+static const double qr3[6] = {
+ -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */
+ -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */
+ -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */
+ -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */
+ -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */
+ -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */
+};
+static const double qs3[6] = {
+  4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */
+  6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */
+  3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */
+  5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */
+  1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */
+ -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */
+};
+
+static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */
+ -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */
+ -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */
+ -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */
+ -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */
+ -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */
+};
+static const double qs2[6] = {
+  2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */
+  2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */
+  7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */
+  7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */
+  1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */
+ -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */
+};
+
+static double qone(double x)
+{
+	const double *p,*q;
+	double_t s,r,z;
+	uint32_t ix;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x40200000){p = qr8; q = qs8;}
+	else if (ix >= 0x40122E8B){p = qr5; q = qs5;}
+	else if (ix >= 0x4006DB6D){p = qr3; q = qs3;}
+	else /*ix >= 0x40000000*/ {p = qr2; q = qs2;}
+	z = 1.0/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+	return (.375 + r/s)/x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j1f.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j1f.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/j1f.c	(revision 398)
@@ -0,0 +1,310 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_j1f.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+static float ponef(float), qonef(float);
+
+static const float
+invsqrtpi = 5.6418961287e-01, /* 0x3f106ebb */
+tpi       = 6.3661974669e-01; /* 0x3f22f983 */
+
+static float common(uint32_t ix, float x, int y1, int sign)
+{
+	double z,s,c,ss,cc;
+
+	s = sinf(x);
+	if (y1)
+		s = -s;
+	c = cosf(x);
+	cc = s-c;
+	if (ix < 0x7f000000) {
+		ss = -s-c;
+		z = cosf(2*x);
+		if (s*c > 0)
+			cc = z/ss;
+		else
+			ss = z/cc;
+		if (ix < 0x58800000) {
+			if (y1)
+				ss = -ss;
+			cc = ponef(x)*cc-qonef(x)*ss;
+		}
+	}
+	if (sign)
+		cc = -cc;
+	return invsqrtpi*cc/sqrtf(x);
+}
+
+/* R0/S0 on [0,2] */
+static const float
+r00 = -6.2500000000e-02, /* 0xbd800000 */
+r01 =  1.4070566976e-03, /* 0x3ab86cfd */
+r02 = -1.5995563444e-05, /* 0xb7862e36 */
+r03 =  4.9672799207e-08, /* 0x335557d2 */
+s01 =  1.9153760746e-02, /* 0x3c9ce859 */
+s02 =  1.8594678841e-04, /* 0x3942fab6 */
+s03 =  1.1771846857e-06, /* 0x359dffc2 */
+s04 =  5.0463624390e-09, /* 0x31ad6446 */
+s05 =  1.2354227016e-11; /* 0x2d59567e */
+
+float j1f(float x)
+{
+	float z,r,s;
+	uint32_t ix;
+	int sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix >= 0x7f800000)
+		return 1/(x*x);
+	if (ix >= 0x40000000)  /* |x| >= 2 */
+		return common(ix, fabsf(x), 0, sign);
+	if (ix >= 0x39000000) {  /* |x| >= 2**-13 */
+		z = x*x;
+		r = z*(r00+z*(r01+z*(r02+z*r03)));
+		s = 1+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
+		z = 0.5f + r/s;
+	} else
+		z = 0.5f;
+	return z*x;
+}
+
+static const float U0[5] = {
+ -1.9605709612e-01, /* 0xbe48c331 */
+  5.0443872809e-02, /* 0x3d4e9e3c */
+ -1.9125689287e-03, /* 0xbafaaf2a */
+  2.3525259166e-05, /* 0x37c5581c */
+ -9.1909917899e-08, /* 0xb3c56003 */
+};
+static const float V0[5] = {
+  1.9916731864e-02, /* 0x3ca3286a */
+  2.0255257550e-04, /* 0x3954644b */
+  1.3560879779e-06, /* 0x35b602d4 */
+  6.2274145840e-09, /* 0x31d5f8eb */
+  1.6655924903e-11, /* 0x2d9281cf */
+};
+
+float y1f(float x)
+{
+	float z,u,v;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	if ((ix & 0x7fffffff) == 0)
+		return -1/0.0f;
+	if (ix>>31)
+		return 0/0.0f;
+	if (ix >= 0x7f800000)
+		return 1/x;
+	if (ix >= 0x40000000)  /* |x| >= 2.0 */
+		return common(ix,x,1,0);
+	if (ix < 0x33000000)  /* x < 2**-25 */
+		return -tpi/x;
+	z = x*x;
+	u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
+	v = 1.0f+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
+	return x*(u/v) + tpi*(j1f(x)*logf(x)-1.0f/x);
+}
+
+/* For x >= 8, the asymptotic expansions of pone is
+ *      1 + 15/128 s^2 - 4725/2^15 s^4 - ...,   where s = 1/x.
+ * We approximate pone by
+ *      pone(x) = 1 + (R/S)
+ * where  R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
+ *        S = 1 + ps0*s^2 + ... + ps4*s^10
+ * and
+ *      | pone(x)-1-R/S | <= 2  ** ( -60.06)
+ */
+
+static const float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.0000000000e+00, /* 0x00000000 */
+  1.1718750000e-01, /* 0x3df00000 */
+  1.3239480972e+01, /* 0x4153d4ea */
+  4.1205184937e+02, /* 0x43ce06a3 */
+  3.8747453613e+03, /* 0x45722bed */
+  7.9144794922e+03, /* 0x45f753d6 */
+};
+static const float ps8[5] = {
+  1.1420736694e+02, /* 0x42e46a2c */
+  3.6509309082e+03, /* 0x45642ee5 */
+  3.6956207031e+04, /* 0x47105c35 */
+  9.7602796875e+04, /* 0x47bea166 */
+  3.0804271484e+04, /* 0x46f0a88b */
+};
+
+static const float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+  1.3199052094e-11, /* 0x2d68333f */
+  1.1718749255e-01, /* 0x3defffff */
+  6.8027510643e+00, /* 0x40d9b023 */
+  1.0830818176e+02, /* 0x42d89dca */
+  5.1763616943e+02, /* 0x440168b7 */
+  5.2871520996e+02, /* 0x44042dc6 */
+};
+static const float ps5[5] = {
+  5.9280597687e+01, /* 0x426d1f55 */
+  9.9140142822e+02, /* 0x4477d9b1 */
+  5.3532670898e+03, /* 0x45a74a23 */
+  7.8446904297e+03, /* 0x45f52586 */
+  1.5040468750e+03, /* 0x44bc0180 */
+};
+
+static const float pr3[6] = {
+  3.0250391081e-09, /* 0x314fe10d */
+  1.1718686670e-01, /* 0x3defffab */
+  3.9329774380e+00, /* 0x407bb5e7 */
+  3.5119403839e+01, /* 0x420c7a45 */
+  9.1055007935e+01, /* 0x42b61c2a */
+  4.8559066772e+01, /* 0x42423c7c */
+};
+static const float ps3[5] = {
+  3.4791309357e+01, /* 0x420b2a4d */
+  3.3676245117e+02, /* 0x43a86198 */
+  1.0468714600e+03, /* 0x4482dbe3 */
+  8.9081134033e+02, /* 0x445eb3ed */
+  1.0378793335e+02, /* 0x42cf936c */
+};
+
+static const float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+  1.0771083225e-07, /* 0x33e74ea8 */
+  1.1717621982e-01, /* 0x3deffa16 */
+  2.3685150146e+00, /* 0x401795c0 */
+  1.2242610931e+01, /* 0x4143e1bc */
+  1.7693971634e+01, /* 0x418d8d41 */
+  5.0735230446e+00, /* 0x40a25a4d */
+};
+static const float ps2[5] = {
+  2.1436485291e+01, /* 0x41ab7dec */
+  1.2529022980e+02, /* 0x42fa9499 */
+  2.3227647400e+02, /* 0x436846c7 */
+  1.1767937469e+02, /* 0x42eb5bd7 */
+  8.3646392822e+00, /* 0x4105d590 */
+};
+
+static float ponef(float x)
+{
+	const float *p,*q;
+	float_t z,r,s;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x41000000){p = pr8; q = ps8;}
+	else if (ix >= 0x409173eb){p = pr5; q = ps5;}
+	else if (ix >= 0x4036d917){p = pr3; q = ps3;}
+	else /*ix >= 0x40000000*/ {p = pr2; q = ps2;}
+	z = 1.0f/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+	return 1.0f + r/s;
+}
+
+/* For x >= 8, the asymptotic expansions of qone is
+ *      3/8 s - 105/1024 s^3 - ..., where s = 1/x.
+ * We approximate pone by
+ *      qone(x) = s*(0.375 + (R/S))
+ * where  R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
+ *        S = 1 + qs1*s^2 + ... + qs6*s^12
+ * and
+ *      | qone(x)/s -0.375-R/S | <= 2  ** ( -61.13)
+ */
+
+static const float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+  0.0000000000e+00, /* 0x00000000 */
+ -1.0253906250e-01, /* 0xbdd20000 */
+ -1.6271753311e+01, /* 0xc1822c8d */
+ -7.5960174561e+02, /* 0xc43de683 */
+ -1.1849806641e+04, /* 0xc639273a */
+ -4.8438511719e+04, /* 0xc73d3683 */
+};
+static const float qs8[6] = {
+  1.6139537048e+02, /* 0x43216537 */
+  7.8253862305e+03, /* 0x45f48b17 */
+  1.3387534375e+05, /* 0x4802bcd6 */
+  7.1965775000e+05, /* 0x492fb29c */
+  6.6660125000e+05, /* 0x4922be94 */
+ -2.9449025000e+05, /* 0xc88fcb48 */
+};
+
+static const float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+ -2.0897993405e-11, /* 0xadb7d219 */
+ -1.0253904760e-01, /* 0xbdd1fffe */
+ -8.0564479828e+00, /* 0xc100e736 */
+ -1.8366960144e+02, /* 0xc337ab6b */
+ -1.3731937256e+03, /* 0xc4aba633 */
+ -2.6124443359e+03, /* 0xc523471c */
+};
+static const float qs5[6] = {
+  8.1276550293e+01, /* 0x42a28d98 */
+  1.9917987061e+03, /* 0x44f8f98f */
+  1.7468484375e+04, /* 0x468878f8 */
+  4.9851425781e+04, /* 0x4742bb6d */
+  2.7948074219e+04, /* 0x46da5826 */
+ -4.7191835938e+03, /* 0xc5937978 */
+};
+
+static const float qr3[6] = {
+ -5.0783124372e-09, /* 0xb1ae7d4f */
+ -1.0253783315e-01, /* 0xbdd1ff5b */
+ -4.6101160049e+00, /* 0xc0938612 */
+ -5.7847221375e+01, /* 0xc267638e */
+ -2.2824453735e+02, /* 0xc3643e9a */
+ -2.1921012878e+02, /* 0xc35b35cb */
+};
+static const float qs3[6] = {
+  4.7665153503e+01, /* 0x423ea91e */
+  6.7386511230e+02, /* 0x4428775e */
+  3.3801528320e+03, /* 0x45534272 */
+  5.5477290039e+03, /* 0x45ad5dd5 */
+  1.9031191406e+03, /* 0x44ede3d0 */
+ -1.3520118713e+02, /* 0xc3073381 */
+};
+
+static const float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+ -1.7838172539e-07, /* 0xb43f8932 */
+ -1.0251704603e-01, /* 0xbdd1f475 */
+ -2.7522056103e+00, /* 0xc0302423 */
+ -1.9663616180e+01, /* 0xc19d4f16 */
+ -4.2325313568e+01, /* 0xc2294d1f */
+ -2.1371921539e+01, /* 0xc1aaf9b2 */
+};
+static const float qs2[6] = {
+  2.9533363342e+01, /* 0x41ec4454 */
+  2.5298155212e+02, /* 0x437cfb47 */
+  7.5750280762e+02, /* 0x443d602e */
+  7.3939318848e+02, /* 0x4438d92a */
+  1.5594900513e+02, /* 0x431bf2f2 */
+ -4.9594988823e+00, /* 0xc09eb437 */
+};
+
+static float qonef(float x)
+{
+	const float *p,*q;
+	float_t s,r,z;
+	uint32_t ix;
+
+	GET_FLOAT_WORD(ix, x);
+	ix &= 0x7fffffff;
+	if      (ix >= 0x41000000){p = qr8; q = qs8;}
+	else if (ix >= 0x409173eb){p = qr5; q = qs5;}
+	else if (ix >= 0x4036d917){p = qr3; q = qs3;}
+	else /*ix >= 0x40000000*/ {p = qr2; q = qs2;}
+	z = 1.0f/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+	return (.375f + r/s)/x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/jn.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/jn.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/jn.c	(revision 398)
@@ -0,0 +1,280 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_jn.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * jn(n, x), yn(n, x)
+ * floating point Bessel's function of the 1st and 2nd kind
+ * of order n
+ *
+ * Special cases:
+ *      y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
+ *      y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
+ * Note 2. About jn(n,x), yn(n,x)
+ *      For n=0, j0(x) is called,
+ *      for n=1, j1(x) is called,
+ *      for n<=x, forward recursion is used starting
+ *      from values of j0(x) and j1(x).
+ *      for n>x, a continued fraction approximation to
+ *      j(n,x)/j(n-1,x) is evaluated and then backward
+ *      recursion is used starting from a supposed value
+ *      for j(n,x). The resulting value of j(0,x) is
+ *      compared with the actual value to correct the
+ *      supposed value of j(n,x).
+ *
+ *      yn(n,x) is similar in all respects, except
+ *      that forward recursion is used for all
+ *      values of n>1.
+ */
+
+#include "libm.h"
+
+static const double invsqrtpi = 5.64189583547756279280e-01; /* 0x3FE20DD7, 0x50429B6D */
+
+double jn(int n, double x)
+{
+	uint32_t ix, lx;
+	int nm1, i, sign;
+	double a, b, temp;
+
+	EXTRACT_WORDS(ix, lx, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+
+	if ((ix | (lx|-lx)>>31) > 0x7ff00000) /* nan */
+		return x;
+
+	/* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+	 * Thus, J(-n,x) = J(n,-x)
+	 */
+	/* nm1 = |n|-1 is used instead of |n| to handle n==INT_MIN */
+	if (n == 0)
+		return j0(x);
+	if (n < 0) {
+		nm1 = -(n+1);
+		x = -x;
+		sign ^= 1;
+	} else
+		nm1 = n-1;
+	if (nm1 == 0)
+		return j1(x);
+
+	sign &= n;  /* even n: 0, odd n: signbit(x) */
+	x = fabs(x);
+	if ((ix|lx) == 0 || ix == 0x7ff00000)  /* if x is 0 or inf */
+		b = 0.0;
+	else if (nm1 < x) {
+		/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+		if (ix >= 0x52d00000) { /* x > 2**302 */
+			/* (x >> n**2)
+			 *      Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+			 *      Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+			 *      Let s=sin(x), c=cos(x),
+			 *          xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+			 *
+			 *             n    sin(xn)*sqt2    cos(xn)*sqt2
+			 *          ----------------------------------
+			 *             0     s-c             c+s
+			 *             1    -s-c            -c+s
+			 *             2    -s+c            -c-s
+			 *             3     s+c             c-s
+			 */
+			switch(nm1&3) {
+			case 0: temp = -cos(x)+sin(x); break;
+			case 1: temp = -cos(x)-sin(x); break;
+			case 2: temp =  cos(x)-sin(x); break;
+			default:
+			case 3: temp =  cos(x)+sin(x); break;
+			}
+			b = invsqrtpi*temp/sqrt(x);
+		} else {
+			a = j0(x);
+			b = j1(x);
+			for (i=0; i<nm1; ) {
+				i++;
+				temp = b;
+				b = b*(2.0*i/x) - a; /* avoid underflow */
+				a = temp;
+			}
+		}
+	} else {
+		if (ix < 0x3e100000) { /* x < 2**-29 */
+			/* x is tiny, return the first Taylor expansion of J(n,x)
+			 * J(n,x) = 1/n!*(x/2)^n  - ...
+			 */
+			if (nm1 > 32)  /* underflow */
+				b = 0.0;
+			else {
+				temp = x*0.5;
+				b = temp;
+				a = 1.0;
+				for (i=2; i<=nm1+1; i++) {
+					a *= (double)i; /* a = n! */
+					b *= temp;      /* b = (x/2)^n */
+				}
+				b = b/a;
+			}
+		} else {
+			/* use backward recurrence */
+			/*                      x      x^2      x^2
+			 *  J(n,x)/J(n-1,x) =  ----   ------   ------   .....
+			 *                      2n  - 2(n+1) - 2(n+2)
+			 *
+			 *                      1      1        1
+			 *  (for large x)   =  ----  ------   ------   .....
+			 *                      2n   2(n+1)   2(n+2)
+			 *                      -- - ------ - ------ -
+			 *                       x     x         x
+			 *
+			 * Let w = 2n/x and h=2/x, then the above quotient
+			 * is equal to the continued fraction:
+			 *                  1
+			 *      = -----------------------
+			 *                     1
+			 *         w - -----------------
+			 *                        1
+			 *              w+h - ---------
+			 *                     w+2h - ...
+			 *
+			 * To determine how many terms needed, let
+			 * Q(0) = w, Q(1) = w(w+h) - 1,
+			 * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+			 * When Q(k) > 1e4      good for single
+			 * When Q(k) > 1e9      good for double
+			 * When Q(k) > 1e17     good for quadruple
+			 */
+			/* determine k */
+			double t,q0,q1,w,h,z,tmp,nf;
+			int k;
+
+			nf = nm1 + 1.0;
+			w = 2*nf/x;
+			h = 2/x;
+			z = w+h;
+			q0 = w;
+			q1 = w*z - 1.0;
+			k = 1;
+			while (q1 < 1.0e9) {
+				k += 1;
+				z += h;
+				tmp = z*q1 - q0;
+				q0 = q1;
+				q1 = tmp;
+			}
+			for (t=0.0, i=k; i>=0; i--)
+				t = 1/(2*(i+nf)/x - t);
+			a = t;
+			b = 1.0;
+			/*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+			 *  Hence, if n*(log(2n/x)) > ...
+			 *  single 8.8722839355e+01
+			 *  double 7.09782712893383973096e+02
+			 *  long double 1.1356523406294143949491931077970765006170e+04
+			 *  then recurrent value may overflow and the result is
+			 *  likely underflow to zero
+			 */
+			tmp = nf*log(fabs(w));
+			if (tmp < 7.09782712893383973096e+02) {
+				for (i=nm1; i>0; i--) {
+					temp = b;
+					b = b*(2.0*i)/x - a;
+					a = temp;
+				}
+			} else {
+				for (i=nm1; i>0; i--) {
+					temp = b;
+					b = b*(2.0*i)/x - a;
+					a = temp;
+					/* scale b to avoid spurious overflow */
+					if (b > 0x1p500) {
+						a /= b;
+						t /= b;
+						b  = 1.0;
+					}
+				}
+			}
+			z = j0(x);
+			w = j1(x);
+			if (fabs(z) >= fabs(w))
+				b = t*z/b;
+			else
+				b = t*w/a;
+		}
+	}
+	return sign ? -b : b;
+}
+
+
+double yn(int n, double x)
+{
+	uint32_t ix, lx, ib;
+	int nm1, sign, i;
+	double a, b, temp;
+
+	EXTRACT_WORDS(ix, lx, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+
+	if ((ix | (lx|-lx)>>31) > 0x7ff00000) /* nan */
+		return x;
+	if (sign && (ix|lx)!=0) /* x < 0 */
+		return 0/0.0;
+	if (ix == 0x7ff00000)
+		return 0.0;
+
+	if (n == 0)
+		return y0(x);
+	if (n < 0) {
+		nm1 = -(n+1);
+		sign = n&1;
+	} else {
+		nm1 = n-1;
+		sign = 0;
+	}
+	if (nm1 == 0)
+		return sign ? -y1(x) : y1(x);
+
+	if (ix >= 0x52d00000) { /* x > 2**302 */
+		/* (x >> n**2)
+		 *      Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+		 *      Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+		 *      Let s=sin(x), c=cos(x),
+		 *          xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+		 *
+		 *             n    sin(xn)*sqt2    cos(xn)*sqt2
+		 *          ----------------------------------
+		 *             0     s-c             c+s
+		 *             1    -s-c            -c+s
+		 *             2    -s+c            -c-s
+		 *             3     s+c             c-s
+		 */
+		switch(nm1&3) {
+		case 0: temp = -sin(x)-cos(x); break;
+		case 1: temp = -sin(x)+cos(x); break;
+		case 2: temp =  sin(x)+cos(x); break;
+		default:
+		case 3: temp =  sin(x)-cos(x); break;
+		}
+		b = invsqrtpi*temp/sqrt(x);
+	} else {
+		a = y0(x);
+		b = y1(x);
+		/* quit if b is -inf */
+		GET_HIGH_WORD(ib, b);
+		for (i=0; i<nm1 && ib!=0xfff00000; ){
+			i++;
+			temp = b;
+			b = (2.0*i/x)*b - a;
+			GET_HIGH_WORD(ib, b);
+			a = temp;
+		}
+	}
+	return sign ? -b : b;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/jnf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/jnf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/jnf.c	(revision 398)
@@ -0,0 +1,202 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_jnf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+float jnf(int n, float x)
+{
+	uint32_t ix;
+	int nm1, sign, i;
+	float a, b, temp;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix > 0x7f800000) /* nan */
+		return x;
+
+	/* J(-n,x) = J(n,-x), use |n|-1 to avoid overflow in -n */
+	if (n == 0)
+		return j0f(x);
+	if (n < 0) {
+		nm1 = -(n+1);
+		x = -x;
+		sign ^= 1;
+	} else
+		nm1 = n-1;
+	if (nm1 == 0)
+		return j1f(x);
+
+	sign &= n;  /* even n: 0, odd n: signbit(x) */
+	x = fabsf(x);
+	if (ix == 0 || ix == 0x7f800000)  /* if x is 0 or inf */
+		b = 0.0f;
+	else if (nm1 < x) {
+		/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+		a = j0f(x);
+		b = j1f(x);
+		for (i=0; i<nm1; ){
+			i++;
+			temp = b;
+			b = b*(2.0f*i/x) - a;
+			a = temp;
+		}
+	} else {
+		if (ix < 0x35800000) { /* x < 2**-20 */
+			/* x is tiny, return the first Taylor expansion of J(n,x)
+			 * J(n,x) = 1/n!*(x/2)^n  - ...
+			 */
+			if (nm1 > 8)  /* underflow */
+				nm1 = 8;
+			temp = 0.5f * x;
+			b = temp;
+			a = 1.0f;
+			for (i=2; i<=nm1+1; i++) {
+				a *= (float)i;    /* a = n! */
+				b *= temp;        /* b = (x/2)^n */
+			}
+			b = b/a;
+		} else {
+			/* use backward recurrence */
+			/*                      x      x^2      x^2
+			 *  J(n,x)/J(n-1,x) =  ----   ------   ------   .....
+			 *                      2n  - 2(n+1) - 2(n+2)
+			 *
+			 *                      1      1        1
+			 *  (for large x)   =  ----  ------   ------   .....
+			 *                      2n   2(n+1)   2(n+2)
+			 *                      -- - ------ - ------ -
+			 *                       x     x         x
+			 *
+			 * Let w = 2n/x and h=2/x, then the above quotient
+			 * is equal to the continued fraction:
+			 *                  1
+			 *      = -----------------------
+			 *                     1
+			 *         w - -----------------
+			 *                        1
+			 *              w+h - ---------
+			 *                     w+2h - ...
+			 *
+			 * To determine how many terms needed, let
+			 * Q(0) = w, Q(1) = w(w+h) - 1,
+			 * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+			 * When Q(k) > 1e4      good for single
+			 * When Q(k) > 1e9      good for double
+			 * When Q(k) > 1e17     good for quadruple
+			 */
+			/* determine k */
+			float t,q0,q1,w,h,z,tmp,nf;
+			int k;
+
+			nf = nm1+1.0f;
+			w = 2*nf/x;
+			h = 2/x;
+			z = w+h;
+			q0 = w;
+			q1 = w*z - 1.0f;
+			k = 1;
+			while (q1 < 1.0e4f) {
+				k += 1;
+				z += h;
+				tmp = z*q1 - q0;
+				q0 = q1;
+				q1 = tmp;
+			}
+			for (t=0.0f, i=k; i>=0; i--)
+				t = 1.0f/(2*(i+nf)/x-t);
+			a = t;
+			b = 1.0f;
+			/*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+			 *  Hence, if n*(log(2n/x)) > ...
+			 *  single 8.8722839355e+01
+			 *  double 7.09782712893383973096e+02
+			 *  long double 1.1356523406294143949491931077970765006170e+04
+			 *  then recurrent value may overflow and the result is
+			 *  likely underflow to zero
+			 */
+			tmp = nf*logf(fabsf(w));
+			if (tmp < 88.721679688f) {
+				for (i=nm1; i>0; i--) {
+					temp = b;
+					b = 2.0f*i*b/x - a;
+					a = temp;
+				}
+			} else {
+				for (i=nm1; i>0; i--){
+					temp = b;
+					b = 2.0f*i*b/x - a;
+					a = temp;
+					/* scale b to avoid spurious overflow */
+					if (b > 0x1p60f) {
+						a /= b;
+						t /= b;
+						b = 1.0f;
+					}
+				}
+			}
+			z = j0f(x);
+			w = j1f(x);
+			if (fabsf(z) >= fabsf(w))
+				b = t*z/b;
+			else
+				b = t*w/a;
+		}
+	}
+	return sign ? -b : b;
+}
+
+float ynf(int n, float x)
+{
+	uint32_t ix, ib;
+	int nm1, sign, i;
+	float a, b, temp;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix>>31;
+	ix &= 0x7fffffff;
+	if (ix > 0x7f800000) /* nan */
+		return x;
+	if (sign && ix != 0) /* x < 0 */
+		return 0/0.0f;
+	if (ix == 0x7f800000)
+		return 0.0f;
+
+	if (n == 0)
+		return y0f(x);
+	if (n < 0) {
+		nm1 = -(n+1);
+		sign = n&1;
+	} else {
+		nm1 = n-1;
+		sign = 0;
+	}
+	if (nm1 == 0)
+		return sign ? -y1f(x) : y1f(x);
+
+	a = y0f(x);
+	b = y1f(x);
+	/* quit if b is -inf */
+	GET_FLOAT_WORD(ib,b);
+	for (i = 0; i < nm1 && ib != 0xff800000; ) {
+		i++;
+		temp = b;
+		b = (2.0f*i/x)*b - a;
+		GET_FLOAT_WORD(ib, b);
+		a = temp;
+	}
+	return sign ? -b : b;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ldexp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ldexp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ldexp.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+double ldexp(double x, int n)
+{
+	return scalbn(x, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ldexpf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ldexpf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ldexpf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+float ldexpf(float x, int n)
+{
+	return scalbnf(x, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ldexpl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ldexpl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/ldexpl.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long double ldexpl(long double x, int n)
+{
+	return scalbnl(x, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgamma.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgamma.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgamma.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <math.h>
+
+extern int __signgam;
+double __lgamma_r(double, int *);
+
+double lgamma(double x)
+{
+	return __lgamma_r(x, &__signgam);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgamma_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgamma_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgamma_r.c	(revision 398)
@@ -0,0 +1,284 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_lgamma_r.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+/* lgamma_r(x, signgamp)
+ * Reentrant version of the logarithm of the Gamma function
+ * with user provide pointer for the sign of Gamma(x).
+ *
+ * Method:
+ *   1. Argument Reduction for 0 < x <= 8
+ *      Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
+ *      reduce x to a number in [1.5,2.5] by
+ *              lgamma(1+s) = log(s) + lgamma(s)
+ *      for example,
+ *              lgamma(7.3) = log(6.3) + lgamma(6.3)
+ *                          = log(6.3*5.3) + lgamma(5.3)
+ *                          = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
+ *   2. Polynomial approximation of lgamma around its
+ *      minimun ymin=1.461632144968362245 to maintain monotonicity.
+ *      On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
+ *              Let z = x-ymin;
+ *              lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
+ *      where
+ *              poly(z) is a 14 degree polynomial.
+ *   2. Rational approximation in the primary interval [2,3]
+ *      We use the following approximation:
+ *              s = x-2.0;
+ *              lgamma(x) = 0.5*s + s*P(s)/Q(s)
+ *      with accuracy
+ *              |P/Q - (lgamma(x)-0.5s)| < 2**-61.71
+ *      Our algorithms are based on the following observation
+ *
+ *                             zeta(2)-1    2    zeta(3)-1    3
+ * lgamma(2+s) = s*(1-Euler) + --------- * s  -  --------- * s  + ...
+ *                                 2                 3
+ *
+ *      where Euler = 0.5771... is the Euler constant, which is very
+ *      close to 0.5.
+ *
+ *   3. For x>=8, we have
+ *      lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
+ *      (better formula:
+ *         lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
+ *      Let z = 1/x, then we approximation
+ *              f(z) = lgamma(x) - (x-0.5)(log(x)-1)
+ *      by
+ *                                  3       5             11
+ *              w = w0 + w1*z + w2*z  + w3*z  + ... + w6*z
+ *      where
+ *              |w - f(z)| < 2**-58.74
+ *
+ *   4. For negative x, since (G is gamma function)
+ *              -x*G(-x)*G(x) = pi/sin(pi*x),
+ *      we have
+ *              G(x) = pi/(sin(pi*x)*(-x)*G(-x))
+ *      since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
+ *      Hence, for x<0, signgam = sign(sin(pi*x)) and
+ *              lgamma(x) = log(|Gamma(x)|)
+ *                        = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
+ *      Note: one should avoid compute pi*(-x) directly in the
+ *            computation of sin(pi*(-x)).
+ *
+ *   5. Special Cases
+ *              lgamma(2+s) ~ s*(1-Euler) for tiny s
+ *              lgamma(1) = lgamma(2) = 0
+ *              lgamma(x) ~ -log(|x|) for tiny x
+ *              lgamma(0) = lgamma(neg.integer) = inf and raise divide-by-zero
+ *              lgamma(inf) = inf
+ *              lgamma(-inf) = inf (bug for bug compatible with C99!?)
+ *
+ */
+
+#include "libm.h"
+#include "libc.h"
+
+static const double
+pi  =  3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
+a0  =  7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */
+a1  =  3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */
+a2  =  6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */
+a3  =  2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */
+a4  =  7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */
+a5  =  2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */
+a6  =  1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */
+a7  =  5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */
+a8  =  2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */
+a9  =  1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */
+a10 =  2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */
+a11 =  4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */
+tc  =  1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */
+tf  = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */
+/* tt = -(tail of tf) */
+tt  = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */
+t0  =  4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */
+t1  = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */
+t2  =  6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */
+t3  = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */
+t4  =  1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */
+t5  = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */
+t6  =  6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */
+t7  = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */
+t8  =  2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */
+t9  = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */
+t10 =  8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */
+t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */
+t12 =  3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */
+t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */
+t14 =  3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */
+u0  = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
+u1  =  6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */
+u2  =  1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */
+u3  =  9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */
+u4  =  2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */
+u5  =  1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */
+v1  =  2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */
+v2  =  2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */
+v3  =  7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */
+v4  =  1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */
+v5  =  3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */
+s0  = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
+s1  =  2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */
+s2  =  3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */
+s3  =  1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */
+s4  =  2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */
+s5  =  1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */
+s6  =  3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */
+r1  =  1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */
+r2  =  7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */
+r3  =  1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */
+r4  =  1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */
+r5  =  7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */
+r6  =  7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */
+w0  =  4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */
+w1  =  8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */
+w2  = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */
+w3  =  7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */
+w4  = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */
+w5  =  8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */
+w6  = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */
+
+/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */
+static double sin_pi(double x)
+{
+	int n;
+
+	/* spurious inexact if odd int */
+	x = 2.0*(x*0.5 - floor(x*0.5));  /* x mod 2.0 */
+
+	n = (int)(x*4.0);
+	n = (n+1)/2;
+	x -= n*0.5f;
+	x *= pi;
+
+	switch (n) {
+	default: /* case 4: */
+	case 0: return __sin(x, 0.0, 0);
+	case 1: return __cos(x, 0.0);
+	case 2: return __sin(-x, 0.0, 0);
+	case 3: return -__cos(x, 0.0);
+	}
+}
+
+double __lgamma_r(double x, int *signgamp)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t t,y,z,nadj,p,p1,p2,p3,q,r,w;
+	uint32_t ix;
+	int sign,i;
+
+	/* purge off +-inf, NaN, +-0, tiny and negative arguments */
+	*signgamp = 1;
+	sign = u.i>>63;
+	ix = u.i>>32 & 0x7fffffff;
+	if (ix >= 0x7ff00000)
+		return x*x;
+	if (ix < (0x3ff-70)<<20) {  /* |x|<2**-70, return -log(|x|) */
+		if(sign) {
+			x = -x;
+			*signgamp = -1;
+		}
+		return -log(x);
+	}
+	if (sign) {
+		x = -x;
+		t = sin_pi(x);
+		if (t == 0.0) /* -integer */
+			return 1.0/(x-x);
+		if (t > 0.0)
+			*signgamp = -1;
+		else
+			t = -t;
+		nadj = log(pi/(t*x));
+	}
+
+	/* purge off 1 and 2 */
+	if ((ix == 0x3ff00000 || ix == 0x40000000) && (uint32_t)u.i == 0)
+		r = 0;
+	/* for x < 2.0 */
+	else if (ix < 0x40000000) {
+		if (ix <= 0x3feccccc) {   /* lgamma(x) = lgamma(x+1)-log(x) */
+			r = -log(x);
+			if (ix >= 0x3FE76944) {
+				y = 1.0 - x;
+				i = 0;
+			} else if (ix >= 0x3FCDA661) {
+				y = x - (tc-1.0);
+				i = 1;
+			} else {
+				y = x;
+				i = 2;
+			}
+		} else {
+			r = 0.0;
+			if (ix >= 0x3FFBB4C3) {  /* [1.7316,2] */
+				y = 2.0 - x;
+				i = 0;
+			} else if(ix >= 0x3FF3B4C4) {  /* [1.23,1.73] */
+				y = x - tc;
+				i = 1;
+			} else {
+				y = x - 1.0;
+				i = 2;
+			}
+		}
+		switch (i) {
+		case 0:
+			z = y*y;
+			p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
+			p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
+			p = y*p1+p2;
+			r += (p-0.5*y);
+			break;
+		case 1:
+			z = y*y;
+			w = z*y;
+			p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12)));    /* parallel comp */
+			p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
+			p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
+			p = z*p1-(tt-w*(p2+y*p3));
+			r += tf + p;
+			break;
+		case 2:
+			p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
+			p2 = 1.0+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
+			r += -0.5*y + p1/p2;
+		}
+	} else if (ix < 0x40200000) {  /* x < 8.0 */
+		i = (int)x;
+		y = x - (double)i;
+		p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+		q = 1.0+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
+		r = 0.5*y+p/q;
+		z = 1.0;    /* lgamma(1+s) = log(s) + lgamma(s) */
+		switch (i) {
+		case 7: z *= y + 6.0;  /* FALLTHRU */
+		case 6: z *= y + 5.0;  /* FALLTHRU */
+		case 5: z *= y + 4.0;  /* FALLTHRU */
+		case 4: z *= y + 3.0;  /* FALLTHRU */
+		case 3: z *= y + 2.0;  /* FALLTHRU */
+			r += log(z);
+			break;
+		}
+	} else if (ix < 0x43900000) {  /* 8.0 <= x < 2**58 */
+		t = log(x);
+		z = 1.0/x;
+		y = z*z;
+		w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
+		r = (x-0.5)*(t-1.0)+w;
+	} else                         /* 2**58 <= x <= inf */
+		r =  x*(log(x)-1.0);
+	if (sign)
+		r = nadj - r;
+	return r;
+}
+
+weak_alias(__lgamma_r, lgamma_r);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgammaf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgammaf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgammaf.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <math.h>
+
+extern int __signgam;
+float __lgammaf_r(float, int *);
+
+float lgammaf(float x)
+{
+	return __lgammaf_r(x, &__signgam);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgammaf_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgammaf_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgammaf_r.c	(revision 398)
@@ -0,0 +1,219 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_lgammaf_r.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+#include "libc.h"
+
+static const float
+pi  =  3.1415927410e+00, /* 0x40490fdb */
+a0  =  7.7215664089e-02, /* 0x3d9e233f */
+a1  =  3.2246702909e-01, /* 0x3ea51a66 */
+a2  =  6.7352302372e-02, /* 0x3d89f001 */
+a3  =  2.0580807701e-02, /* 0x3ca89915 */
+a4  =  7.3855509982e-03, /* 0x3bf2027e */
+a5  =  2.8905137442e-03, /* 0x3b3d6ec6 */
+a6  =  1.1927076848e-03, /* 0x3a9c54a1 */
+a7  =  5.1006977446e-04, /* 0x3a05b634 */
+a8  =  2.2086278477e-04, /* 0x39679767 */
+a9  =  1.0801156895e-04, /* 0x38e28445 */
+a10 =  2.5214456400e-05, /* 0x37d383a2 */
+a11 =  4.4864096708e-05, /* 0x383c2c75 */
+tc  =  1.4616321325e+00, /* 0x3fbb16c3 */
+tf  = -1.2148628384e-01, /* 0xbdf8cdcd */
+/* tt = -(tail of tf) */
+tt  =  6.6971006518e-09, /* 0x31e61c52 */
+t0  =  4.8383611441e-01, /* 0x3ef7b95e */
+t1  = -1.4758771658e-01, /* 0xbe17213c */
+t2  =  6.4624942839e-02, /* 0x3d845a15 */
+t3  = -3.2788541168e-02, /* 0xbd064d47 */
+t4  =  1.7970675603e-02, /* 0x3c93373d */
+t5  = -1.0314224288e-02, /* 0xbc28fcfe */
+t6  =  6.1005386524e-03, /* 0x3bc7e707 */
+t7  = -3.6845202558e-03, /* 0xbb7177fe */
+t8  =  2.2596477065e-03, /* 0x3b141699 */
+t9  = -1.4034647029e-03, /* 0xbab7f476 */
+t10 =  8.8108185446e-04, /* 0x3a66f867 */
+t11 = -5.3859531181e-04, /* 0xba0d3085 */
+t12 =  3.1563205994e-04, /* 0x39a57b6b */
+t13 = -3.1275415677e-04, /* 0xb9a3f927 */
+t14 =  3.3552918467e-04, /* 0x39afe9f7 */
+u0  = -7.7215664089e-02, /* 0xbd9e233f */
+u1  =  6.3282704353e-01, /* 0x3f2200f4 */
+u2  =  1.4549225569e+00, /* 0x3fba3ae7 */
+u3  =  9.7771751881e-01, /* 0x3f7a4bb2 */
+u4  =  2.2896373272e-01, /* 0x3e6a7578 */
+u5  =  1.3381091878e-02, /* 0x3c5b3c5e */
+v1  =  2.4559779167e+00, /* 0x401d2ebe */
+v2  =  2.1284897327e+00, /* 0x4008392d */
+v3  =  7.6928514242e-01, /* 0x3f44efdf */
+v4  =  1.0422264785e-01, /* 0x3dd572af */
+v5  =  3.2170924824e-03, /* 0x3b52d5db */
+s0  = -7.7215664089e-02, /* 0xbd9e233f */
+s1  =  2.1498242021e-01, /* 0x3e5c245a */
+s2  =  3.2577878237e-01, /* 0x3ea6cc7a */
+s3  =  1.4635047317e-01, /* 0x3e15dce6 */
+s4  =  2.6642270386e-02, /* 0x3cda40e4 */
+s5  =  1.8402845599e-03, /* 0x3af135b4 */
+s6  =  3.1947532989e-05, /* 0x3805ff67 */
+r1  =  1.3920053244e+00, /* 0x3fb22d3b */
+r2  =  7.2193557024e-01, /* 0x3f38d0c5 */
+r3  =  1.7193385959e-01, /* 0x3e300f6e */
+r4  =  1.8645919859e-02, /* 0x3c98bf54 */
+r5  =  7.7794247773e-04, /* 0x3a4beed6 */
+r6  =  7.3266842264e-06, /* 0x36f5d7bd */
+w0  =  4.1893854737e-01, /* 0x3ed67f1d */
+w1  =  8.3333335817e-02, /* 0x3daaaaab */
+w2  = -2.7777778450e-03, /* 0xbb360b61 */
+w3  =  7.9365057172e-04, /* 0x3a500cfd */
+w4  = -5.9518753551e-04, /* 0xba1c065c */
+w5  =  8.3633989561e-04, /* 0x3a5b3dd2 */
+w6  = -1.6309292987e-03; /* 0xbad5c4e8 */
+
+/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */
+static float sin_pi(float x)
+{
+	double_t y;
+	int n;
+
+	/* spurious inexact if odd int */
+	x = 2*(x*0.5f - floorf(x*0.5f));  /* x mod 2.0 */
+
+	n = (int)(x*4);
+	n = (n+1)/2;
+	y = x - n*0.5f;
+	y *= 3.14159265358979323846;
+	switch (n) {
+	default: /* case 4: */
+	case 0: return __sindf(y);
+	case 1: return __cosdf(y);
+	case 2: return __sindf(-y);
+	case 3: return -__cosdf(y);
+	}
+}
+
+float __lgammaf_r(float x, int *signgamp)
+{
+	union {float f; uint32_t i;} u = {x};
+	float t,y,z,nadj,p,p1,p2,p3,q,r,w;
+	uint32_t ix;
+	int i,sign;
+
+	/* purge off +-inf, NaN, +-0, tiny and negative arguments */
+	*signgamp = 1;
+	sign = u.i>>31;
+	ix = u.i & 0x7fffffff;
+	if (ix >= 0x7f800000)
+		return x*x;
+	if (ix < 0x35000000) {  /* |x| < 2**-21, return -log(|x|) */
+		if (sign) {
+			*signgamp = -1;
+			x = -x;
+		}
+		return -logf(x);
+	}
+	if (sign) {
+		x = -x;
+		t = sin_pi(x);
+		if (t == 0.0f) /* -integer */
+			return 1.0f/(x-x);
+		if (t > 0.0f)
+			*signgamp = -1;
+		else
+			t = -t;
+		nadj = logf(pi/(t*x));
+	}
+
+	/* purge off 1 and 2 */
+	if (ix == 0x3f800000 || ix == 0x40000000)
+		r = 0;
+	/* for x < 2.0 */
+	else if (ix < 0x40000000) {
+		if (ix <= 0x3f666666) {  /* lgamma(x) = lgamma(x+1)-log(x) */
+			r = -logf(x);
+			if (ix >= 0x3f3b4a20) {
+				y = 1.0f - x;
+				i = 0;
+			} else if (ix >= 0x3e6d3308) {
+				y = x - (tc-1.0f);
+				i = 1;
+			} else {
+				y = x;
+				i = 2;
+			}
+		} else {
+			r = 0.0f;
+			if (ix >= 0x3fdda618) {  /* [1.7316,2] */
+				y = 2.0f - x;
+				i = 0;
+			} else if (ix >= 0x3F9da620) {  /* [1.23,1.73] */
+				y = x - tc;
+				i = 1;
+			} else {
+				y = x - 1.0f;
+				i = 2;
+			}
+		}
+		switch(i) {
+		case 0:
+			z = y*y;
+			p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
+			p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
+			p = y*p1+p2;
+			r += p - 0.5f*y;
+			break;
+		case 1:
+			z = y*y;
+			w = z*y;
+			p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12)));    /* parallel comp */
+			p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
+			p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
+			p = z*p1-(tt-w*(p2+y*p3));
+			r += (tf + p);
+			break;
+		case 2:
+			p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
+			p2 = 1.0f+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
+			r += -0.5f*y + p1/p2;
+		}
+	} else if (ix < 0x41000000) {  /* x < 8.0 */
+		i = (int)x;
+		y = x - (float)i;
+		p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+		q = 1.0f+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
+		r = 0.5f*y+p/q;
+		z = 1.0f;    /* lgamma(1+s) = log(s) + lgamma(s) */
+		switch (i) {
+		case 7: z *= y + 6.0f;  /* FALLTHRU */
+		case 6: z *= y + 5.0f;  /* FALLTHRU */
+		case 5: z *= y + 4.0f;  /* FALLTHRU */
+		case 4: z *= y + 3.0f;  /* FALLTHRU */
+		case 3: z *= y + 2.0f;  /* FALLTHRU */
+			r += logf(z);
+			break;
+		}
+	} else if (ix < 0x5c800000) {  /* 8.0 <= x < 2**58 */
+		t = logf(x);
+		z = 1.0f/x;
+		y = z*z;
+		w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
+		r = (x-0.5f)*(t-1.0f)+w;
+	} else                         /* 2**58 <= x <= inf */
+		r =  x*(logf(x)-1.0f);
+	if (sign)
+		r = nadj - r;
+	return r;
+}
+
+weak_alias(__lgammaf_r, lgammaf_r);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgammal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgammal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lgammal.c	(revision 398)
@@ -0,0 +1,360 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_lgammal.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/* lgammal(x)
+ * Reentrant version of the logarithm of the Gamma function
+ * with user provide pointer for the sign of Gamma(x).
+ *
+ * Method:
+ *   1. Argument Reduction for 0 < x <= 8
+ *      Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
+ *      reduce x to a number in [1.5,2.5] by
+ *              lgamma(1+s) = log(s) + lgamma(s)
+ *      for example,
+ *              lgamma(7.3) = log(6.3) + lgamma(6.3)
+ *                          = log(6.3*5.3) + lgamma(5.3)
+ *                          = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
+ *   2. Polynomial approximation of lgamma around its
+ *      minimun ymin=1.461632144968362245 to maintain monotonicity.
+ *      On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
+ *              Let z = x-ymin;
+ *              lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
+ *   2. Rational approximation in the primary interval [2,3]
+ *      We use the following approximation:
+ *              s = x-2.0;
+ *              lgamma(x) = 0.5*s + s*P(s)/Q(s)
+ *      Our algorithms are based on the following observation
+ *
+ *                             zeta(2)-1    2    zeta(3)-1    3
+ * lgamma(2+s) = s*(1-Euler) + --------- * s  -  --------- * s  + ...
+ *                                 2                 3
+ *
+ *      where Euler = 0.5771... is the Euler constant, which is very
+ *      close to 0.5.
+ *
+ *   3. For x>=8, we have
+ *      lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
+ *      (better formula:
+ *         lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
+ *      Let z = 1/x, then we approximation
+ *              f(z) = lgamma(x) - (x-0.5)(log(x)-1)
+ *      by
+ *                                  3       5             11
+ *              w = w0 + w1*z + w2*z  + w3*z  + ... + w6*z
+ *
+ *   4. For negative x, since (G is gamma function)
+ *              -x*G(-x)*G(x) = pi/sin(pi*x),
+ *      we have
+ *              G(x) = pi/(sin(pi*x)*(-x)*G(-x))
+ *      since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
+ *      Hence, for x<0, signgam = sign(sin(pi*x)) and
+ *              lgamma(x) = log(|Gamma(x)|)
+ *                        = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
+ *      Note: one should avoid compute pi*(-x) directly in the
+ *            computation of sin(pi*(-x)).
+ *
+ *   5. Special Cases
+ *              lgamma(2+s) ~ s*(1-Euler) for tiny s
+ *              lgamma(1)=lgamma(2)=0
+ *              lgamma(x) ~ -log(x) for tiny x
+ *              lgamma(0) = lgamma(inf) = inf
+ *              lgamma(-integer) = +-inf
+ *
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+#include "libc.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+double __lgamma_r(double x, int *sg);
+
+long double __lgammal_r(long double x, int *sg)
+{
+	return __lgamma_r(x, sg);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+static const long double
+pi = 3.14159265358979323846264L,
+
+/* lgam(1+x) = 0.5 x + x a(x)/b(x)
+    -0.268402099609375 <= x <= 0
+    peak relative error 6.6e-22 */
+a0 = -6.343246574721079391729402781192128239938E2L,
+a1 =  1.856560238672465796768677717168371401378E3L,
+a2 =  2.404733102163746263689288466865843408429E3L,
+a3 =  8.804188795790383497379532868917517596322E2L,
+a4 =  1.135361354097447729740103745999661157426E2L,
+a5 =  3.766956539107615557608581581190400021285E0L,
+
+b0 =  8.214973713960928795704317259806842490498E3L,
+b1 =  1.026343508841367384879065363925870888012E4L,
+b2 =  4.553337477045763320522762343132210919277E3L,
+b3 =  8.506975785032585797446253359230031874803E2L,
+b4 =  6.042447899703295436820744186992189445813E1L,
+/* b5 =  1.000000000000000000000000000000000000000E0 */
+
+
+tc =  1.4616321449683623412626595423257213284682E0L,
+tf = -1.2148629053584961146050602565082954242826E-1, /* double precision */
+/* tt = (tail of tf), i.e. tf + tt has extended precision. */
+tt = 3.3649914684731379602768989080467587736363E-18L,
+/* lgam ( 1.4616321449683623412626595423257213284682E0 ) =
+-1.2148629053584960809551455717769158215135617312999903886372437313313530E-1 */
+
+/* lgam (x + tc) = tf + tt + x g(x)/h(x)
+    -0.230003726999612341262659542325721328468 <= x
+       <= 0.2699962730003876587373404576742786715318
+     peak relative error 2.1e-21 */
+g0 = 3.645529916721223331888305293534095553827E-18L,
+g1 = 5.126654642791082497002594216163574795690E3L,
+g2 = 8.828603575854624811911631336122070070327E3L,
+g3 = 5.464186426932117031234820886525701595203E3L,
+g4 = 1.455427403530884193180776558102868592293E3L,
+g5 = 1.541735456969245924860307497029155838446E2L,
+g6 = 4.335498275274822298341872707453445815118E0L,
+
+h0 = 1.059584930106085509696730443974495979641E4L,
+h1 = 2.147921653490043010629481226937850618860E4L,
+h2 = 1.643014770044524804175197151958100656728E4L,
+h3 = 5.869021995186925517228323497501767586078E3L,
+h4 = 9.764244777714344488787381271643502742293E2L,
+h5 = 6.442485441570592541741092969581997002349E1L,
+/* h6 = 1.000000000000000000000000000000000000000E0 */
+
+
+/* lgam (x+1) = -0.5 x + x u(x)/v(x)
+    -0.100006103515625 <= x <= 0.231639862060546875
+    peak relative error 1.3e-21 */
+u0 = -8.886217500092090678492242071879342025627E1L,
+u1 =  6.840109978129177639438792958320783599310E2L,
+u2 =  2.042626104514127267855588786511809932433E3L,
+u3 =  1.911723903442667422201651063009856064275E3L,
+u4 =  7.447065275665887457628865263491667767695E2L,
+u5 =  1.132256494121790736268471016493103952637E2L,
+u6 =  4.484398885516614191003094714505960972894E0L,
+
+v0 =  1.150830924194461522996462401210374632929E3L,
+v1 =  3.399692260848747447377972081399737098610E3L,
+v2 =  3.786631705644460255229513563657226008015E3L,
+v3 =  1.966450123004478374557778781564114347876E3L,
+v4 =  4.741359068914069299837355438370682773122E2L,
+v5 =  4.508989649747184050907206782117647852364E1L,
+/* v6 =  1.000000000000000000000000000000000000000E0 */
+
+
+/* lgam (x+2) = .5 x + x s(x)/r(x)
+     0 <= x <= 1
+     peak relative error 7.2e-22 */
+s0 =  1.454726263410661942989109455292824853344E6L,
+s1 = -3.901428390086348447890408306153378922752E6L,
+s2 = -6.573568698209374121847873064292963089438E6L,
+s3 = -3.319055881485044417245964508099095984643E6L,
+s4 = -7.094891568758439227560184618114707107977E5L,
+s5 = -6.263426646464505837422314539808112478303E4L,
+s6 = -1.684926520999477529949915657519454051529E3L,
+
+r0 = -1.883978160734303518163008696712983134698E7L,
+r1 = -2.815206082812062064902202753264922306830E7L,
+r2 = -1.600245495251915899081846093343626358398E7L,
+r3 = -4.310526301881305003489257052083370058799E6L,
+r4 = -5.563807682263923279438235987186184968542E5L,
+r5 = -3.027734654434169996032905158145259713083E4L,
+r6 = -4.501995652861105629217250715790764371267E2L,
+/* r6 =  1.000000000000000000000000000000000000000E0 */
+
+
+/* lgam(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x w(1/x^2)
+    x >= 8
+    Peak relative error 1.51e-21
+w0 = LS2PI - 0.5 */
+w0 =  4.189385332046727417803e-1L,
+w1 =  8.333333333333331447505E-2L,
+w2 = -2.777777777750349603440E-3L,
+w3 =  7.936507795855070755671E-4L,
+w4 = -5.952345851765688514613E-4L,
+w5 =  8.412723297322498080632E-4L,
+w6 = -1.880801938119376907179E-3L,
+w7 =  4.885026142432270781165E-3L;
+
+/* sin(pi*x) assuming x > 2^-1000, if sin(pi*x)==0 the sign is arbitrary */
+static long double sin_pi(long double x)
+{
+	int n;
+
+	/* spurious inexact if odd int */
+	x *= 0.5;
+	x = 2.0*(x - floorl(x));  /* x mod 2.0 */
+
+	n = (int)(x*4.0);
+	n = (n+1)/2;
+	x -= n*0.5f;
+	x *= pi;
+
+	switch (n) {
+	default: /* case 4: */
+	case 0: return __sinl(x, 0.0, 0);
+	case 1: return __cosl(x, 0.0);
+	case 2: return __sinl(-x, 0.0, 0);
+	case 3: return -__cosl(x, 0.0);
+	}
+}
+
+long double __lgammal_r(long double x, int *sg) {
+	long double t, y, z, nadj, p, p1, p2, q, r, w;
+	union ldshape u = {x};
+	uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
+	int sign = u.i.se >> 15;
+	int i;
+
+	*sg = 1;
+
+	/* purge off +-inf, NaN, +-0, tiny and negative arguments */
+	if (ix >= 0x7fff0000)
+		return x * x;
+	if (ix < 0x3fc08000) {  /* |x|<2**-63, return -log(|x|) */
+		if (sign) {
+			*sg = -1;
+			x = -x;
+		}
+		return -logl(x);
+	}
+	if (sign) {
+		x = -x;
+		t = sin_pi(x);
+		if (t == 0.0)
+			return 1.0 / (x-x); /* -integer */
+		if (t > 0.0)
+			*sg = -1;
+		else
+			t = -t;
+		nadj = logl(pi / (t * x));
+	}
+
+	/* purge off 1 and 2 (so the sign is ok with downward rounding) */
+	if ((ix == 0x3fff8000 || ix == 0x40008000) && u.i.m == 0) {
+		r = 0;
+	} else if (ix < 0x40008000) {  /* x < 2.0 */
+		if (ix <= 0x3ffee666) {  /* 8.99993896484375e-1 */
+			/* lgamma(x) = lgamma(x+1) - log(x) */
+			r = -logl(x);
+			if (ix >= 0x3ffebb4a) {  /* 7.31597900390625e-1 */
+				y = x - 1.0;
+				i = 0;
+			} else if (ix >= 0x3ffced33) {  /* 2.31639862060546875e-1 */
+				y = x - (tc - 1.0);
+				i = 1;
+			} else { /* x < 0.23 */
+				y = x;
+				i = 2;
+			}
+		} else {
+			r = 0.0;
+			if (ix >= 0x3fffdda6) {  /* 1.73162841796875 */
+				/* [1.7316,2] */
+				y = x - 2.0;
+				i = 0;
+			} else if (ix >= 0x3fff9da6) {  /* 1.23162841796875 */
+				/* [1.23,1.73] */
+				y = x - tc;
+				i = 1;
+			} else {
+				/* [0.9, 1.23] */
+				y = x - 1.0;
+				i = 2;
+			}
+		}
+		switch (i) {
+		case 0:
+			p1 = a0 + y * (a1 + y * (a2 + y * (a3 + y * (a4 + y * a5))));
+			p2 = b0 + y * (b1 + y * (b2 + y * (b3 + y * (b4 + y))));
+			r += 0.5 * y + y * p1/p2;
+			break;
+		case 1:
+			p1 = g0 + y * (g1 + y * (g2 + y * (g3 + y * (g4 + y * (g5 + y * g6)))));
+			p2 = h0 + y * (h1 + y * (h2 + y * (h3 + y * (h4 + y * (h5 + y)))));
+			p = tt + y * p1/p2;
+			r += (tf + p);
+			break;
+		case 2:
+			p1 = y * (u0 + y * (u1 + y * (u2 + y * (u3 + y * (u4 + y * (u5 + y * u6))))));
+			p2 = v0 + y * (v1 + y * (v2 + y * (v3 + y * (v4 + y * (v5 + y)))));
+			r += (-0.5 * y + p1 / p2);
+		}
+	} else if (ix < 0x40028000) {  /* 8.0 */
+		/* x < 8.0 */
+		i = (int)x;
+		y = x - (double)i;
+		p = y * (s0 + y * (s1 + y * (s2 + y * (s3 + y * (s4 + y * (s5 + y * s6))))));
+		q = r0 + y * (r1 + y * (r2 + y * (r3 + y * (r4 + y * (r5 + y * (r6 + y))))));
+		r = 0.5 * y + p / q;
+		z = 1.0;
+		/* lgamma(1+s) = log(s) + lgamma(s) */
+		switch (i) {
+		case 7:
+			z *= (y + 6.0); /* FALLTHRU */
+		case 6:
+			z *= (y + 5.0); /* FALLTHRU */
+		case 5:
+			z *= (y + 4.0); /* FALLTHRU */
+		case 4:
+			z *= (y + 3.0); /* FALLTHRU */
+		case 3:
+			z *= (y + 2.0); /* FALLTHRU */
+			r += logl(z);
+			break;
+		}
+	} else if (ix < 0x40418000) {  /* 2^66 */
+		/* 8.0 <= x < 2**66 */
+		t = logl(x);
+		z = 1.0 / x;
+		y = z * z;
+		w = w0 + z * (w1 + y * (w2 + y * (w3 + y * (w4 + y * (w5 + y * (w6 + y * w7))))));
+		r = (x - 0.5) * (t - 1.0) + w;
+	} else /* 2**66 <= x <= inf */
+		r = x * (logl(x) - 1.0);
+	if (sign)
+		r = nadj - r;
+	return r;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+double __lgamma_r(double x, int *sg);
+
+long double __lgammal_r(long double x, int *sg)
+{
+	return __lgamma_r(x, sg);
+}
+#endif
+
+extern int __signgam;
+
+long double lgammal(long double x)
+{
+	return __lgammal_r(x, &__signgam);
+}
+
+weak_alias(__lgammal_r, lgammal_r);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llrint.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llrint.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llrint.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <math.h>
+
+/* uses LLONG_MAX > 2^53, see comments in lrint.c */
+
+long long llrint(double x)
+{
+	return rint(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llrintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llrintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llrintf.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <math.h>
+
+/* uses LLONG_MAX > 2^24, see comments in lrint.c */
+
+long long llrintf(float x)
+{
+	return rintf(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llrintl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llrintl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llrintl.c	(revision 398)
@@ -0,0 +1,36 @@
+#include <limits.h>
+#include <fenv.h>
+#include "libm.h"
+
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long long llrintl(long double x)
+{
+	return llrint(x);
+}
+#elif defined(FE_INEXACT)
+/*
+see comments in lrint.c
+
+Note that if LLONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64
+then x == 2**63 - 0.5 is the only input that overflows and
+raises inexact (with tonearest or upward rounding mode)
+*/
+long long llrintl(long double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+	x = rintl(x);
+	if (!e && (x > LLONG_MAX || x < LLONG_MIN))
+		feclearexcept(FE_INEXACT);
+	/* conversion */
+	return x;
+}
+#else
+long long llrintl(long double x)
+{
+	return rintl(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llround.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llround.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llround.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long long llround(double x)
+{
+	return round(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llroundf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llroundf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llroundf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long long llroundf(float x)
+{
+	return roundf(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llroundl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llroundl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/llroundl.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long long llroundl(long double x)
+{
+	return roundl(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log.c	(revision 398)
@@ -0,0 +1,118 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_log.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* log(x)
+ * Return the logarithm of x
+ *
+ * Method :
+ *   1. Argument Reduction: find k and f such that
+ *                      x = 2^k * (1+f),
+ *         where  sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ *   2. Approximation of log(1+f).
+ *      Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ *               = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ *               = 2s + s*R
+ *      We use a special Remez algorithm on [0,0.1716] to generate
+ *      a polynomial of degree 14 to approximate R The maximum error
+ *      of this polynomial approximation is bounded by 2**-58.45. In
+ *      other words,
+ *                      2      4      6      8      10      12      14
+ *          R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s  +Lg6*s  +Lg7*s
+ *      (the values of Lg1 to Lg7 are listed in the program)
+ *      and
+ *          |      2          14          |     -58.45
+ *          | Lg1*s +...+Lg7*s    -  R(z) | <= 2
+ *          |                             |
+ *      Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ *      In order to guarantee error in log below 1ulp, we compute log
+ *      by
+ *              log(1+f) = f - s*(f - R)        (if f is not too large)
+ *              log(1+f) = f - (hfsq - s*(hfsq+R)).     (better accuracy)
+ *
+ *      3. Finally,  log(x) = k*ln2 + log(1+f).
+ *                          = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ *         Here ln2 is split into two floating point number:
+ *                      ln2_hi + ln2_lo,
+ *         where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ *      log(x) is NaN with signal if x < 0 (including -INF) ;
+ *      log(+INF) is +INF; log(0) is -INF with signal;
+ *      log(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ *      according to an error analysis, the error is always less than
+ *      1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const double
+ln2_hi = 6.93147180369123816490e-01,  /* 3fe62e42 fee00000 */
+ln2_lo = 1.90821492927058770002e-10,  /* 3dea39ef 35793c76 */
+Lg1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
+
+double log(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t hfsq,f,s,z,R,w,t1,t2,dk;
+	uint32_t hx;
+	int k;
+
+	hx = u.i>>32;
+	k = 0;
+	if (hx < 0x00100000 || hx>>31) {
+		if (u.i<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (hx>>31)
+			return (x-x)/0.0; /* log(-#) = NaN */
+		/* subnormal number, scale x up */
+		k -= 54;
+		x *= 0x1p54;
+		u.f = x;
+		hx = u.i>>32;
+	} else if (hx >= 0x7ff00000) {
+		return x;
+	} else if (hx == 0x3ff00000 && u.i<<32 == 0)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	hx += 0x3ff00000 - 0x3fe6a09e;
+	k += (int)(hx>>20) - 0x3ff;
+	hx = (hx&0x000fffff) + 0x3fe6a09e;
+	u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
+	x = u.f;
+
+	f = x - 1.0;
+	hfsq = 0.5*f*f;
+	s = f/(2.0+f);
+	z = s*s;
+	w = z*z;
+	t1 = w*(Lg2+w*(Lg4+w*Lg6));
+	t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+	R = t2 + t1;
+	dk = k;
+	return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log10.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log10.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log10.c	(revision 398)
@@ -0,0 +1,101 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_log10.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * Return the base 10 logarithm of x.  See log.c for most comments.
+ *
+ * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2
+ * as in log.c, then combine and scale in extra precision:
+ *    log10(x) = (f - f*f/2 + r)/log(10) + k*log10(2)
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const double
+ivln10hi  = 4.34294481878168880939e-01, /* 0x3fdbcb7b, 0x15200000 */
+ivln10lo  = 2.50829467116452752298e-11, /* 0x3dbb9438, 0xca9aadd5 */
+log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
+log10_2lo = 3.69423907715893078616e-13, /* 0x3D59FEF3, 0x11F12B36 */
+Lg1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
+
+double log10(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t hfsq,f,s,z,R,w,t1,t2,dk,y,hi,lo,val_hi,val_lo;
+	uint32_t hx;
+	int k;
+
+	hx = u.i>>32;
+	k = 0;
+	if (hx < 0x00100000 || hx>>31) {
+		if (u.i<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (hx>>31)
+			return (x-x)/0.0; /* log(-#) = NaN */
+		/* subnormal number, scale x up */
+		k -= 54;
+		x *= 0x1p54;
+		u.f = x;
+		hx = u.i>>32;
+	} else if (hx >= 0x7ff00000) {
+		return x;
+	} else if (hx == 0x3ff00000 && u.i<<32 == 0)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	hx += 0x3ff00000 - 0x3fe6a09e;
+	k += (int)(hx>>20) - 0x3ff;
+	hx = (hx&0x000fffff) + 0x3fe6a09e;
+	u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
+	x = u.f;
+
+	f = x - 1.0;
+	hfsq = 0.5*f*f;
+	s = f/(2.0+f);
+	z = s*s;
+	w = z*z;
+	t1 = w*(Lg2+w*(Lg4+w*Lg6));
+	t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+	R = t2 + t1;
+
+	/* See log2.c for details. */
+	/* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */
+	hi = f - hfsq;
+	u.f = hi;
+	u.i &= (uint64_t)-1<<32;
+	hi = u.f;
+	lo = f - hi - hfsq + s*(hfsq+R);
+
+	/* val_hi+val_lo ~ log10(1+f) + k*log10(2) */
+	val_hi = hi*ivln10hi;
+	dk = k;
+	y = dk*log10_2hi;
+	val_lo = dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi;
+
+	/*
+	 * Extra precision in for adding y is not strictly needed
+	 * since there is no very large cancellation near x = sqrt(2) or
+	 * x = 1/sqrt(2), but we do it anyway since it costs little on CPUs
+	 * with some parallelism and it reduces the error for many args.
+	 */
+	w = y + val_hi;
+	val_lo += (y - w) + val_hi;
+	val_hi = w;
+
+	return val_lo + val_hi;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log10f.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log10f.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log10f.c	(revision 398)
@@ -0,0 +1,77 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_log10f.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * See comments in log10.c.
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const float
+ivln10hi  =  4.3432617188e-01, /* 0x3ede6000 */
+ivln10lo  = -3.1689971365e-05, /* 0xb804ead9 */
+log10_2hi =  3.0102920532e-01, /* 0x3e9a2080 */
+log10_2lo =  7.9034151668e-07, /* 0x355427db */
+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
+
+float log10f(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	float_t hfsq,f,s,z,R,w,t1,t2,dk,hi,lo;
+	uint32_t ix;
+	int k;
+
+	ix = u.i;
+	k = 0;
+	if (ix < 0x00800000 || ix>>31) {  /* x < 2**-126  */
+		if (ix<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (ix>>31)
+			return (x-x)/0.0f; /* log(-#) = NaN */
+		/* subnormal number, scale up x */
+		k -= 25;
+		x *= 0x1p25f;
+		u.f = x;
+		ix = u.i;
+	} else if (ix >= 0x7f800000) {
+		return x;
+	} else if (ix == 0x3f800000)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	ix += 0x3f800000 - 0x3f3504f3;
+	k += (int)(ix>>23) - 0x7f;
+	ix = (ix&0x007fffff) + 0x3f3504f3;
+	u.i = ix;
+	x = u.f;
+
+	f = x - 1.0f;
+	s = f/(2.0f + f);
+	z = s*s;
+	w = z*z;
+	t1= w*(Lg2+w*Lg4);
+	t2= z*(Lg1+w*Lg3);
+	R = t2 + t1;
+	hfsq = 0.5f*f*f;
+
+	hi = f - hfsq;
+	u.f = hi;
+	u.i &= 0xfffff000;
+	hi = u.f;
+	lo = f - hi - hfsq + s*(hfsq+R);
+	dk = k;
+	return dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi + hi*ivln10hi + dk*log10_2hi;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log10l.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log10l.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log10l.c	(revision 398)
@@ -0,0 +1,191 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_log10l.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Common logarithm, long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, log10l();
+ *
+ * y = log10l( x );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base 10 logarithm of x.
+ *
+ * The argument is separated into its exponent and fractional
+ * parts.  If the exponent is between -1 and +1, the logarithm
+ * of the fraction is approximated by
+ *
+ *     log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).
+ *
+ * Otherwise, setting  z = 2(x-1)/x+1),
+ *
+ *     log(x) = z + z**3 P(z)/Q(z).
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      0.5, 2.0     30000      9.0e-20     2.6e-20
+ *    IEEE     exp(+-10000)  30000      6.0e-20     2.3e-20
+ *
+ * In the tests over the interval exp(+-10000), the logarithms
+ * of the random arguments were uniformly distributed over
+ * [-10000, +10000].
+ *
+ * ERROR MESSAGES:
+ *
+ * log singularity:  x = 0; returns MINLOG
+ * log domain:       x < 0; returns MINLOG
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double log10l(long double x)
+{
+	return log10(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 6.2e-22
+ */
+static const long double P[] = {
+ 4.9962495940332550844739E-1L,
+ 1.0767376367209449010438E1L,
+ 7.7671073698359539859595E1L,
+ 2.5620629828144409632571E2L,
+ 4.2401812743503691187826E2L,
+ 3.4258224542413922935104E2L,
+ 1.0747524399916215149070E2L,
+};
+static const long double Q[] = {
+/* 1.0000000000000000000000E0,*/
+ 2.3479774160285863271658E1L,
+ 1.9444210022760132894510E2L,
+ 7.7952888181207260646090E2L,
+ 1.6911722418503949084863E3L,
+ 2.0307734695595183428202E3L,
+ 1.2695660352705325274404E3L,
+ 3.2242573199748645407652E2L,
+};
+
+/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
+ * where z = 2(x-1)/(x+1)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 6.16e-22
+ */
+static const long double R[4] = {
+ 1.9757429581415468984296E-3L,
+-7.1990767473014147232598E-1L,
+ 1.0777257190312272158094E1L,
+-3.5717684488096787370998E1L,
+};
+static const long double S[4] = {
+/* 1.00000000000000000000E0L,*/
+-2.6201045551331104417768E1L,
+ 1.9361891836232102174846E2L,
+-4.2861221385716144629696E2L,
+};
+/* log10(2) */
+#define L102A 0.3125L
+#define L102B -1.1470004336018804786261e-2L
+/* log10(e) */
+#define L10EA 0.5L
+#define L10EB -6.5705518096748172348871e-2L
+
+#define SQRTH 0.70710678118654752440L
+
+long double log10l(long double x)
+{
+	long double y, z;
+	int e;
+
+	if (isnan(x))
+		return x;
+	if(x <= 0.0) {
+		if(x == 0.0)
+			return -1.0 / (x*x);
+		return (x - x) / 0.0;
+	}
+	if (x == INFINITY)
+		return INFINITY;
+	/* separate mantissa from exponent */
+	/* Note, frexp is used so that denormal numbers
+	 * will be handled properly.
+	 */
+	x = frexpl(x, &e);
+
+	/* logarithm using log(x) = z + z**3 P(z)/Q(z),
+	 * where z = 2(x-1)/x+1)
+	 */
+	if (e > 2 || e < -2) {
+		if (x < SQRTH) {  /* 2(2x-1)/(2x+1) */
+			e -= 1;
+			z = x - 0.5;
+			y = 0.5 * z + 0.5;
+		} else {  /*  2 (x-1)/(x+1)   */
+			z = x - 0.5;
+			z -= 0.5;
+			y = 0.5 * x  + 0.5;
+		}
+		x = z / y;
+		z = x*x;
+		y = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
+		goto done;
+	}
+
+	/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
+	if (x < SQRTH) {
+		e -= 1;
+		x = 2.0*x - 1.0;
+	} else {
+		x = x - 1.0;
+	}
+	z = x*x;
+	y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 7));
+	y = y - 0.5*z;
+
+done:
+	/* Multiply log of fraction by log10(e)
+	 * and base 2 exponent by log10(2).
+	 *
+	 * ***CAUTION***
+	 *
+	 * This sequence of operations is critical and it may
+	 * be horribly defeated by some compiler optimizers.
+	 */
+	z = y * (L10EB);
+	z += x * (L10EB);
+	z += e * (L102B);
+	z += y * (L10EA);
+	z += x * (L10EA);
+	z += e * (L102A);
+	return z;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double log10l(long double x)
+{
+	return log10(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log1p.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log1p.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log1p.c	(revision 398)
@@ -0,0 +1,122 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_log1p.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* double log1p(double x)
+ * Return the natural logarithm of 1+x.
+ *
+ * Method :
+ *   1. Argument Reduction: find k and f such that
+ *                      1+x = 2^k * (1+f),
+ *         where  sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ *      Note. If k=0, then f=x is exact. However, if k!=0, then f
+ *      may not be representable exactly. In that case, a correction
+ *      term is need. Let u=1+x rounded. Let c = (1+x)-u, then
+ *      log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
+ *      and add back the correction term c/u.
+ *      (Note: when x > 2**53, one can simply return log(x))
+ *
+ *   2. Approximation of log(1+f): See log.c
+ *
+ *   3. Finally, log1p(x) = k*ln2 + log(1+f) + c/u. See log.c
+ *
+ * Special cases:
+ *      log1p(x) is NaN with signal if x < -1 (including -INF) ;
+ *      log1p(+INF) is +INF; log1p(-1) is -INF with signal;
+ *      log1p(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ *      according to an error analysis, the error is always less than
+ *      1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ *
+ * Note: Assuming log() return accurate answer, the following
+ *       algorithm can be used to compute log1p(x) to within a few ULP:
+ *
+ *              u = 1+x;
+ *              if(u==1.0) return x ; else
+ *                         return log(u)*(x/(u-1.0));
+ *
+ *       See HP-15C Advanced Functions Handbook, p.193.
+ */
+
+#include "libm.h"
+
+static const double
+ln2_hi = 6.93147180369123816490e-01,  /* 3fe62e42 fee00000 */
+ln2_lo = 1.90821492927058770002e-10,  /* 3dea39ef 35793c76 */
+Lg1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
+
+double log1p(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t hfsq,f,c,s,z,R,w,t1,t2,dk;
+	uint32_t hx,hu;
+	int k;
+
+	hx = u.i>>32;
+	k = 1;
+	if (hx < 0x3fda827a || hx>>31) {  /* 1+x < sqrt(2)+ */
+		if (hx >= 0xbff00000) {  /* x <= -1.0 */
+			if (x == -1)
+				return x/0.0; /* log1p(-1) = -inf */
+			return (x-x)/0.0;     /* log1p(x<-1) = NaN */
+		}
+		if (hx<<1 < 0x3ca00000<<1) {  /* |x| < 2**-53 */
+			/* underflow if subnormal */
+			if ((hx&0x7ff00000) == 0)
+				FORCE_EVAL((float)x);
+			return x;
+		}
+		if (hx <= 0xbfd2bec4) {  /* sqrt(2)/2- <= 1+x < sqrt(2)+ */
+			k = 0;
+			c = 0;
+			f = x;
+		}
+	} else if (hx >= 0x7ff00000)
+		return x;
+	if (k) {
+		u.f = 1 + x;
+		hu = u.i>>32;
+		hu += 0x3ff00000 - 0x3fe6a09e;
+		k = (int)(hu>>20) - 0x3ff;
+		/* correction term ~ log(1+x)-log(u), avoid underflow in c/u */
+		if (k < 54) {
+			c = k >= 2 ? 1-(u.f-x) : x-(u.f-1);
+			c /= u.f;
+		} else
+			c = 0;
+		/* reduce u into [sqrt(2)/2, sqrt(2)] */
+		hu = (hu&0x000fffff) + 0x3fe6a09e;
+		u.i = (uint64_t)hu<<32 | (u.i&0xffffffff);
+		f = u.f - 1;
+	}
+	hfsq = 0.5*f*f;
+	s = f/(2.0+f);
+	z = s*s;
+	w = z*z;
+	t1 = w*(Lg2+w*(Lg4+w*Lg6));
+	t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+	R = t2 + t1;
+	dk = k;
+	return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log1pf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log1pf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log1pf.c	(revision 398)
@@ -0,0 +1,77 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_log1pf.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
+ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
+
+float log1pf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	float_t hfsq,f,c,s,z,R,w,t1,t2,dk;
+	uint32_t ix,iu;
+	int k;
+
+	ix = u.i;
+	k = 1;
+	if (ix < 0x3ed413d0 || ix>>31) {  /* 1+x < sqrt(2)+  */
+		if (ix >= 0xbf800000) {  /* x <= -1.0 */
+			if (x == -1)
+				return x/0.0f; /* log1p(-1)=+inf */
+			return (x-x)/0.0f;     /* log1p(x<-1)=NaN */
+		}
+		if (ix<<1 < 0x33800000<<1) {   /* |x| < 2**-24 */
+			/* underflow if subnormal */
+			if ((ix&0x7f800000) == 0)
+				FORCE_EVAL(x*x);
+			return x;
+		}
+		if (ix <= 0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */
+			k = 0;
+			c = 0;
+			f = x;
+		}
+	} else if (ix >= 0x7f800000)
+		return x;
+	if (k) {
+		u.f = 1 + x;
+		iu = u.i;
+		iu += 0x3f800000 - 0x3f3504f3;
+		k = (int)(iu>>23) - 0x7f;
+		/* correction term ~ log(1+x)-log(u), avoid underflow in c/u */
+		if (k < 25) {
+			c = k >= 2 ? 1-(u.f-x) : x-(u.f-1);
+			c /= u.f;
+		} else
+			c = 0;
+		/* reduce u into [sqrt(2)/2, sqrt(2)] */
+		iu = (iu&0x007fffff) + 0x3f3504f3;
+		u.i = iu;
+		f = u.f - 1;
+	}
+	s = f/(2.0f + f);
+	z = s*s;
+	w = z*z;
+	t1= w*(Lg2+w*Lg4);
+	t2= z*(Lg1+w*Lg3);
+	R = t2 + t1;
+	hfsq = 0.5f*f*f;
+	dk = k;
+	return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log1pl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log1pl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log1pl.c	(revision 398)
@@ -0,0 +1,177 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/s_log1pl.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Relative error logarithm
+ *      Natural logarithm of 1+x, long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, log1pl();
+ *
+ * y = log1pl( x );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base e (2.718...) logarithm of 1+x.
+ *
+ * The argument 1+x is separated into its exponent and fractional
+ * parts.  If the exponent is between -1 and +1, the logarithm
+ * of the fraction is approximated by
+ *
+ *     log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
+ *
+ * Otherwise, setting  z = 2(x-1)/x+1),
+ *
+ *     log(x) = z + z^3 P(z)/Q(z).
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE     -1.0, 9.0    100000      8.2e-20    2.5e-20
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double log1pl(long double x)
+{
+	return log1p(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 2.32e-20
+ */
+static const long double P[] = {
+ 4.5270000862445199635215E-5L,
+ 4.9854102823193375972212E-1L,
+ 6.5787325942061044846969E0L,
+ 2.9911919328553073277375E1L,
+ 6.0949667980987787057556E1L,
+ 5.7112963590585538103336E1L,
+ 2.0039553499201281259648E1L,
+};
+static const long double Q[] = {
+/* 1.0000000000000000000000E0,*/
+ 1.5062909083469192043167E1L,
+ 8.3047565967967209469434E1L,
+ 2.2176239823732856465394E2L,
+ 3.0909872225312059774938E2L,
+ 2.1642788614495947685003E2L,
+ 6.0118660497603843919306E1L,
+};
+
+/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
+ * where z = 2(x-1)/(x+1)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 6.16e-22
+ */
+static const long double R[4] = {
+ 1.9757429581415468984296E-3L,
+-7.1990767473014147232598E-1L,
+ 1.0777257190312272158094E1L,
+-3.5717684488096787370998E1L,
+};
+static const long double S[4] = {
+/* 1.00000000000000000000E0L,*/
+-2.6201045551331104417768E1L,
+ 1.9361891836232102174846E2L,
+-4.2861221385716144629696E2L,
+};
+static const long double C1 = 6.9314575195312500000000E-1L;
+static const long double C2 = 1.4286068203094172321215E-6L;
+
+#define SQRTH 0.70710678118654752440L
+
+long double log1pl(long double xm1)
+{
+	long double x, y, z;
+	int e;
+
+	if (isnan(xm1))
+		return xm1;
+	if (xm1 == INFINITY)
+		return xm1;
+	if (xm1 == 0.0)
+		return xm1;
+
+	x = xm1 + 1.0;
+
+	/* Test for domain errors.  */
+	if (x <= 0.0) {
+		if (x == 0.0)
+			return -1/(x*x); /* -inf with divbyzero */
+		return 0/0.0f; /* nan with invalid */
+	}
+
+	/* Separate mantissa from exponent.
+	   Use frexp so that denormal numbers will be handled properly.  */
+	x = frexpl(x, &e);
+
+	/* logarithm using log(x) = z + z^3 P(z)/Q(z),
+	   where z = 2(x-1)/x+1)  */
+	if (e > 2 || e < -2) {
+		if (x < SQRTH) { /* 2(2x-1)/(2x+1) */
+			e -= 1;
+			z = x - 0.5;
+			y = 0.5 * z + 0.5;
+		} else { /*  2 (x-1)/(x+1)   */
+			z = x - 0.5;
+			z -= 0.5;
+			y = 0.5 * x  + 0.5;
+		}
+		x = z / y;
+		z = x*x;
+		z = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
+		z = z + e * C2;
+		z = z + x;
+		z = z + e * C1;
+		return z;
+	}
+
+	/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
+	if (x < SQRTH) {
+		e -= 1;
+		if (e != 0)
+			x = 2.0 * x - 1.0;
+		else
+			x = xm1;
+	} else {
+		if (e != 0)
+			x = x - 1.0;
+		else
+			x = xm1;
+	}
+	z = x*x;
+	y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6));
+	y = y + e * C2;
+	z = y - 0.5 * z;
+	z = z + x;
+	z = z + e * C1;
+	return z;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double log1pl(long double x)
+{
+	return log1p(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log2.c	(revision 398)
@@ -0,0 +1,122 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_log2.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * Return the base 2 logarithm of x.  See log.c for most comments.
+ *
+ * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2
+ * as in log.c, then combine and scale in extra precision:
+ *    log2(x) = (f - f*f/2 + r)/log(2) + k
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const double
+ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */
+ivln2lo = 1.67517131648865118353e-10, /* 0x3de705fc, 0x2eefa200 */
+Lg1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
+
+double log2(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double_t hfsq,f,s,z,R,w,t1,t2,y,hi,lo,val_hi,val_lo;
+	uint32_t hx;
+	int k;
+
+	hx = u.i>>32;
+	k = 0;
+	if (hx < 0x00100000 || hx>>31) {
+		if (u.i<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (hx>>31)
+			return (x-x)/0.0; /* log(-#) = NaN */
+		/* subnormal number, scale x up */
+		k -= 54;
+		x *= 0x1p54;
+		u.f = x;
+		hx = u.i>>32;
+	} else if (hx >= 0x7ff00000) {
+		return x;
+	} else if (hx == 0x3ff00000 && u.i<<32 == 0)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	hx += 0x3ff00000 - 0x3fe6a09e;
+	k += (int)(hx>>20) - 0x3ff;
+	hx = (hx&0x000fffff) + 0x3fe6a09e;
+	u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
+	x = u.f;
+
+	f = x - 1.0;
+	hfsq = 0.5*f*f;
+	s = f/(2.0+f);
+	z = s*s;
+	w = z*z;
+	t1 = w*(Lg2+w*(Lg4+w*Lg6));
+	t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+	R = t2 + t1;
+
+	/*
+	 * f-hfsq must (for args near 1) be evaluated in extra precision
+	 * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2).
+	 * This is fairly efficient since f-hfsq only depends on f, so can
+	 * be evaluated in parallel with R.  Not combining hfsq with R also
+	 * keeps R small (though not as small as a true `lo' term would be),
+	 * so that extra precision is not needed for terms involving R.
+	 *
+	 * Compiler bugs involving extra precision used to break Dekker's
+	 * theorem for spitting f-hfsq as hi+lo, unless double_t was used
+	 * or the multi-precision calculations were avoided when double_t
+	 * has extra precision.  These problems are now automatically
+	 * avoided as a side effect of the optimization of combining the
+	 * Dekker splitting step with the clear-low-bits step.
+	 *
+	 * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra
+	 * precision to avoid a very large cancellation when x is very near
+	 * these values.  Unlike the above cancellations, this problem is
+	 * specific to base 2.  It is strange that adding +-1 is so much
+	 * harder than adding +-ln2 or +-log10_2.
+	 *
+	 * This uses Dekker's theorem to normalize y+val_hi, so the
+	 * compiler bugs are back in some configurations, sigh.  And I
+	 * don't want to used double_t to avoid them, since that gives a
+	 * pessimization and the support for avoiding the pessimization
+	 * is not yet available.
+	 *
+	 * The multi-precision calculations for the multiplications are
+	 * routine.
+	 */
+
+	/* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */
+	hi = f - hfsq;
+	u.f = hi;
+	u.i &= (uint64_t)-1<<32;
+	hi = u.f;
+	lo = f - hi - hfsq + s*(hfsq+R);
+
+	val_hi = hi*ivln2hi;
+	val_lo = (lo+hi)*ivln2lo + lo*ivln2hi;
+
+	/* spadd(val_hi, val_lo, y), except for not using double_t: */
+	y = k;
+	w = y + val_hi;
+	val_lo += (y - w) + val_hi;
+	val_hi = w;
+
+	return val_lo + val_hi;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log2f.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log2f.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log2f.c	(revision 398)
@@ -0,0 +1,74 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_log2f.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * See comments in log2.c.
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const float
+ivln2hi =  1.4428710938e+00, /* 0x3fb8b000 */
+ivln2lo = -1.7605285393e-04, /* 0xb9389ad4 */
+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
+
+float log2f(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	float_t hfsq,f,s,z,R,w,t1,t2,hi,lo;
+	uint32_t ix;
+	int k;
+
+	ix = u.i;
+	k = 0;
+	if (ix < 0x00800000 || ix>>31) {  /* x < 2**-126  */
+		if (ix<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (ix>>31)
+			return (x-x)/0.0f; /* log(-#) = NaN */
+		/* subnormal number, scale up x */
+		k -= 25;
+		x *= 0x1p25f;
+		u.f = x;
+		ix = u.i;
+	} else if (ix >= 0x7f800000) {
+		return x;
+	} else if (ix == 0x3f800000)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	ix += 0x3f800000 - 0x3f3504f3;
+	k += (int)(ix>>23) - 0x7f;
+	ix = (ix&0x007fffff) + 0x3f3504f3;
+	u.i = ix;
+	x = u.f;
+
+	f = x - 1.0f;
+	s = f/(2.0f + f);
+	z = s*s;
+	w = z*z;
+	t1= w*(Lg2+w*Lg4);
+	t2= z*(Lg1+w*Lg3);
+	R = t2 + t1;
+	hfsq = 0.5f*f*f;
+
+	hi = f - hfsq;
+	u.f = hi;
+	u.i &= 0xfffff000;
+	hi = u.f;
+	lo = f - hi - hfsq + s*(hfsq+R);
+	return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + k;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log2l.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log2l.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/log2l.c	(revision 398)
@@ -0,0 +1,182 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_log2l.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Base 2 logarithm, long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, log2l();
+ *
+ * y = log2l( x );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base 2 logarithm of x.
+ *
+ * The argument is separated into its exponent and fractional
+ * parts.  If the exponent is between -1 and +1, the (natural)
+ * logarithm of the fraction is approximated by
+ *
+ *     log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).
+ *
+ * Otherwise, setting  z = 2(x-1)/x+1),
+ *
+ *     log(x) = z + z**3 P(z)/Q(z).
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      0.5, 2.0     30000      9.8e-20     2.7e-20
+ *    IEEE     exp(+-10000)  70000      5.4e-20     2.3e-20
+ *
+ * In the tests over the interval exp(+-10000), the logarithms
+ * of the random arguments were uniformly distributed over
+ * [-10000, +10000].
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double log2l(long double x)
+{
+	return log2(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 6.2e-22
+ */
+static const long double P[] = {
+ 4.9962495940332550844739E-1L,
+ 1.0767376367209449010438E1L,
+ 7.7671073698359539859595E1L,
+ 2.5620629828144409632571E2L,
+ 4.2401812743503691187826E2L,
+ 3.4258224542413922935104E2L,
+ 1.0747524399916215149070E2L,
+};
+static const long double Q[] = {
+/* 1.0000000000000000000000E0,*/
+ 2.3479774160285863271658E1L,
+ 1.9444210022760132894510E2L,
+ 7.7952888181207260646090E2L,
+ 1.6911722418503949084863E3L,
+ 2.0307734695595183428202E3L,
+ 1.2695660352705325274404E3L,
+ 3.2242573199748645407652E2L,
+};
+
+/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
+ * where z = 2(x-1)/(x+1)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 6.16e-22
+ */
+static const long double R[4] = {
+ 1.9757429581415468984296E-3L,
+-7.1990767473014147232598E-1L,
+ 1.0777257190312272158094E1L,
+-3.5717684488096787370998E1L,
+};
+static const long double S[4] = {
+/* 1.00000000000000000000E0L,*/
+-2.6201045551331104417768E1L,
+ 1.9361891836232102174846E2L,
+-4.2861221385716144629696E2L,
+};
+/* log2(e) - 1 */
+#define LOG2EA 4.4269504088896340735992e-1L
+
+#define SQRTH 0.70710678118654752440L
+
+long double log2l(long double x)
+{
+	long double y, z;
+	int e;
+
+	if (isnan(x))
+		return x;
+	if (x == INFINITY)
+		return x;
+	if (x <= 0.0) {
+		if (x == 0.0)
+			return -1/(x*x); /* -inf with divbyzero */
+		return 0/0.0f; /* nan with invalid */
+	}
+
+	/* separate mantissa from exponent */
+	/* Note, frexp is used so that denormal numbers
+	 * will be handled properly.
+	 */
+	x = frexpl(x, &e);
+
+	/* logarithm using log(x) = z + z**3 P(z)/Q(z),
+	 * where z = 2(x-1)/x+1)
+	 */
+	if (e > 2 || e < -2) {
+		if (x < SQRTH) {  /* 2(2x-1)/(2x+1) */
+			e -= 1;
+			z = x - 0.5;
+			y = 0.5 * z + 0.5;
+		} else {  /*  2 (x-1)/(x+1)   */
+			z = x - 0.5;
+			z -= 0.5;
+			y = 0.5 * x + 0.5;
+		}
+		x = z / y;
+		z = x*x;
+		y = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
+		goto done;
+	}
+
+	/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
+	if (x < SQRTH) {
+		e -= 1;
+		x = 2.0*x - 1.0;
+	} else {
+		x = x - 1.0;
+	}
+	z = x*x;
+	y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 7));
+	y = y - 0.5*z;
+
+done:
+	/* Multiply log of fraction by log2(e)
+	 * and base 2 exponent by 1
+	 *
+	 * ***CAUTION***
+	 *
+	 * This sequence of operations is critical and it may
+	 * be horribly defeated by some compiler optimizers.
+	 */
+	z = y * LOG2EA;
+	z += x * LOG2EA;
+	z += y;
+	z += x;
+	z += e;
+	return z;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double log2l(long double x)
+{
+	return log2(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logb.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logb.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logb.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <math.h>
+
+/*
+special cases:
+	logb(+-0) = -inf, and raise divbyzero
+	logb(+-inf) = +inf
+	logb(nan) = nan
+*/
+
+double logb(double x)
+{
+	if (!isfinite(x))
+		return x * x;
+	if (x == 0)
+		return -1/(x*x);
+	return ilogb(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logbf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logbf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logbf.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <math.h>
+
+float logbf(float x)
+{
+	if (!isfinite(x))
+		return x * x;
+	if (x == 0)
+		return -1/(x*x);
+	return ilogbf(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logbl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logbl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logbl.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <math.h>
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double logbl(long double x)
+{
+	return logb(x);
+}
+#else
+long double logbl(long double x)
+{
+	if (!isfinite(x))
+		return x * x;
+	if (x == 0)
+		return -1/(x*x);
+	return ilogbl(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logf.c	(revision 398)
@@ -0,0 +1,69 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_logf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include <stdint.h>
+
+static const float
+ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
+ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
+/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
+Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
+Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
+Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
+Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
+
+float logf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	float_t hfsq,f,s,z,R,w,t1,t2,dk;
+	uint32_t ix;
+	int k;
+
+	ix = u.i;
+	k = 0;
+	if (ix < 0x00800000 || ix>>31) {  /* x < 2**-126  */
+		if (ix<<1 == 0)
+			return -1/(x*x);  /* log(+-0)=-inf */
+		if (ix>>31)
+			return (x-x)/0.0f; /* log(-#) = NaN */
+		/* subnormal number, scale up x */
+		k -= 25;
+		x *= 0x1p25f;
+		u.f = x;
+		ix = u.i;
+	} else if (ix >= 0x7f800000) {
+		return x;
+	} else if (ix == 0x3f800000)
+		return 0;
+
+	/* reduce x into [sqrt(2)/2, sqrt(2)] */
+	ix += 0x3f800000 - 0x3f3504f3;
+	k += (int)(ix>>23) - 0x7f;
+	ix = (ix&0x007fffff) + 0x3f3504f3;
+	u.i = ix;
+	x = u.f;
+
+	f = x - 1.0f;
+	s = f/(2.0f + f);
+	z = s*s;
+	w = z*z;
+	t1= w*(Lg2+w*Lg4);
+	t2= z*(Lg1+w*Lg3);
+	R = t2 + t1;
+	hfsq = 0.5f*f*f;
+	dk = k;
+	return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/logl.c	(revision 398)
@@ -0,0 +1,175 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_logl.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Natural logarithm, long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, logl();
+ *
+ * y = logl( x );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns the base e (2.718...) logarithm of x.
+ *
+ * The argument is separated into its exponent and fractional
+ * parts.  If the exponent is between -1 and +1, the logarithm
+ * of the fraction is approximated by
+ *
+ *     log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).
+ *
+ * Otherwise, setting  z = 2(x-1)/(x+1),
+ *
+ *     log(x) = log(1+z/2) - log(1-z/2) = z + z**3 P(z)/Q(z).
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE      0.5, 2.0    150000      8.71e-20    2.75e-20
+ *    IEEE     exp(+-10000) 100000      5.39e-20    2.34e-20
+ *
+ * In the tests over the interval exp(+-10000), the logarithms
+ * of the random arguments were uniformly distributed over
+ * [-10000, +10000].
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double logl(long double x)
+{
+	return log(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 2.32e-20
+ */
+static const long double P[] = {
+ 4.5270000862445199635215E-5L,
+ 4.9854102823193375972212E-1L,
+ 6.5787325942061044846969E0L,
+ 2.9911919328553073277375E1L,
+ 6.0949667980987787057556E1L,
+ 5.7112963590585538103336E1L,
+ 2.0039553499201281259648E1L,
+};
+static const long double Q[] = {
+/* 1.0000000000000000000000E0,*/
+ 1.5062909083469192043167E1L,
+ 8.3047565967967209469434E1L,
+ 2.2176239823732856465394E2L,
+ 3.0909872225312059774938E2L,
+ 2.1642788614495947685003E2L,
+ 6.0118660497603843919306E1L,
+};
+
+/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
+ * where z = 2(x-1)/(x+1)
+ * 1/sqrt(2) <= x < sqrt(2)
+ * Theoretical peak relative error = 6.16e-22
+ */
+static const long double R[4] = {
+ 1.9757429581415468984296E-3L,
+-7.1990767473014147232598E-1L,
+ 1.0777257190312272158094E1L,
+-3.5717684488096787370998E1L,
+};
+static const long double S[4] = {
+/* 1.00000000000000000000E0L,*/
+-2.6201045551331104417768E1L,
+ 1.9361891836232102174846E2L,
+-4.2861221385716144629696E2L,
+};
+static const long double C1 = 6.9314575195312500000000E-1L;
+static const long double C2 = 1.4286068203094172321215E-6L;
+
+#define SQRTH 0.70710678118654752440L
+
+long double logl(long double x)
+{
+	long double y, z;
+	int e;
+
+	if (isnan(x))
+		return x;
+	if (x == INFINITY)
+		return x;
+	if (x <= 0.0) {
+		if (x == 0.0)
+			return -1/(x*x); /* -inf with divbyzero */
+		return 0/0.0f; /* nan with invalid */
+	}
+
+	/* separate mantissa from exponent */
+	/* Note, frexp is used so that denormal numbers
+	 * will be handled properly.
+	 */
+	x = frexpl(x, &e);
+
+	/* logarithm using log(x) = z + z**3 P(z)/Q(z),
+	 * where z = 2(x-1)/(x+1)
+	 */
+	if (e > 2 || e < -2) {
+		if (x < SQRTH) {  /* 2(2x-1)/(2x+1) */
+			e -= 1;
+			z = x - 0.5;
+			y = 0.5 * z + 0.5;
+		} else {  /*  2 (x-1)/(x+1)   */
+			z = x - 0.5;
+			z -= 0.5;
+			y = 0.5 * x  + 0.5;
+		}
+		x = z / y;
+		z = x*x;
+		z = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
+		z = z + e * C2;
+		z = z + x;
+		z = z + e * C1;
+		return z;
+	}
+
+	/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
+	if (x < SQRTH) {
+		e -= 1;
+		x = 2.0*x - 1.0;
+	} else {
+		x = x - 1.0;
+	}
+	z = x*x;
+	y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6));
+	y = y + e * C2;
+	z = y - 0.5*z;
+	/* Note, the sum of above terms does not exceed x/4,
+	 * so it contributes at most about 1/4 lsb to the error.
+	 */
+	z = z + x;
+	z = z + e * C1; /* This sum has an error of 1/2 lsb. */
+	return z;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double logl(long double x)
+{
+	return log(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lrint.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lrint.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lrint.c	(revision 398)
@@ -0,0 +1,46 @@
+#include <limits.h>
+#include <fenv.h>
+#include "libm.h"
+
+/*
+If the result cannot be represented (overflow, nan), then
+lrint raises the invalid exception.
+
+Otherwise if the input was not an integer then the inexact
+exception is raised.
+
+C99 is a bit vague about whether inexact exception is
+allowed to be raised when invalid is raised.
+(F.9 explicitly allows spurious inexact exceptions, F.9.6.5
+does not make it clear if that rule applies to lrint, but
+IEEE 754r 7.8 seems to forbid spurious inexact exception in
+the ineger conversion functions)
+
+So we try to make sure that no spurious inexact exception is
+raised in case of an overflow.
+
+If the bit size of long > precision of double, then there
+cannot be inexact rounding in case the result overflows,
+otherwise LONG_MAX and LONG_MIN can be represented exactly
+as a double.
+*/
+
+#if LONG_MAX < 1U<<53 && defined(FE_INEXACT)
+long lrint(double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+	x = rint(x);
+	if (!e && (x > LONG_MAX || x < LONG_MIN))
+		feclearexcept(FE_INEXACT);
+	/* conversion */
+	return x;
+}
+#else
+long lrint(double x)
+{
+	return rint(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lrintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lrintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lrintf.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <math.h>
+
+/* uses LONG_MAX > 2^24, see comments in lrint.c */
+
+long lrintf(float x)
+{
+	return rintf(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lrintl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lrintl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lrintl.c	(revision 398)
@@ -0,0 +1,36 @@
+#include <limits.h>
+#include <fenv.h>
+#include "libm.h"
+
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long lrintl(long double x)
+{
+	return lrint(x);
+}
+#elif defined(FE_INEXACT)
+/*
+see comments in lrint.c
+
+Note that if LONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64
+then x == 2**63 - 0.5 is the only input that overflows and
+raises inexact (with tonearest or upward rounding mode)
+*/
+long lrintl(long double x)
+{
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+	x = rintl(x);
+	if (!e && (x > LONG_MAX || x < LONG_MIN))
+		feclearexcept(FE_INEXACT);
+	/* conversion */
+	return x;
+}
+#else
+long lrintl(long double x)
+{
+	return rintl(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lround.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lround.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lround.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long lround(double x)
+{
+	return round(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lroundf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lroundf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lroundf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long lroundf(float x)
+{
+	return roundf(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lroundl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lroundl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/lroundl.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long lroundl(long double x)
+{
+	return roundl(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/modf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/modf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/modf.c	(revision 398)
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+double modf(double x, double *iptr)
+{
+	union {double f; uint64_t i;} u = {x};
+	uint64_t mask;
+	int e = (int)(u.i>>52 & 0x7ff) - 0x3ff;
+
+	/* no fractional part */
+	if (e >= 52) {
+		*iptr = x;
+		if (e == 0x400 && u.i<<12 != 0) /* nan */
+			return x;
+		u.i &= 1ULL<<63;
+		return u.f;
+	}
+
+	/* no integral part*/
+	if (e < 0) {
+		u.i &= 1ULL<<63;
+		*iptr = u.f;
+		return x;
+	}
+
+	mask = -1ULL>>12>>e;
+	if ((u.i & mask) == 0) {
+		*iptr = x;
+		u.i &= 1ULL<<63;
+		return u.f;
+	}
+	u.i &= ~mask;
+	*iptr = u.f;
+	return x - u.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/modff.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/modff.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/modff.c	(revision 398)
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+float modff(float x, float *iptr)
+{
+	union {float f; uint32_t i;} u = {x};
+	uint32_t mask;
+	int e = (int)(u.i>>23 & 0xff) - 0x7f;
+
+	/* no fractional part */
+	if (e >= 23) {
+		*iptr = x;
+		if (e == 0x80 && u.i<<9 != 0) { /* nan */
+			return x;
+		}
+		u.i &= 0x80000000;
+		return u.f;
+	}
+	/* no integral part */
+	if (e < 0) {
+		u.i &= 0x80000000;
+		*iptr = u.f;
+		return x;
+	}
+
+	mask = 0x007fffff>>e;
+	if ((u.i & mask) == 0) {
+		*iptr = x;
+		u.i &= 0x80000000;
+		return u.f;
+	}
+	u.i &= ~mask;
+	*iptr = u.f;
+	return x - u.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/modfl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/modfl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/modfl.c	(revision 398)
@@ -0,0 +1,53 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double modfl(long double x, long double *iptr)
+{
+	double d;
+	long double r;
+
+	r = modf(x, &d);
+	*iptr = d;
+	return r;
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double modfl(long double x, long double *iptr)
+{
+	union ldshape u = {x};
+	int e = (u.i.se & 0x7fff) - 0x3fff;
+	int s = u.i.se >> 15;
+	long double absx;
+	long double y;
+
+	/* no fractional part */
+	if (e >= LDBL_MANT_DIG-1) {
+		*iptr = x;
+		if (isnan(x))
+			return x;
+		return s ? -0.0 : 0.0;
+	}
+
+	/* no integral part*/
+	if (e < 0) {
+		*iptr = s ? -0.0 : 0.0;
+		return x;
+	}
+
+	/* raises spurious inexact */
+	absx = s ? -x : x;
+	y = absx + toint - toint - absx;
+	if (y == 0) {
+		*iptr = x;
+		return s ? -0.0 : 0.0;
+	}
+	if (y > 0)
+		y -= 1;
+	if (s)
+		y = -y;
+	*iptr = x + y;
+	return -y;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nan.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nan.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nan.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+double nan(const char *s)
+{
+	return NAN;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nanf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+float nanf(const char *s)
+{
+	return NAN;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nanl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nanl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nanl.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long double nanl(const char *s)
+{
+	return NAN;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nearbyint.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nearbyint.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nearbyint.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <fenv.h>
+#include <math.h>
+
+/* nearbyint is the same as rint, but it must not raise the inexact exception */
+
+double nearbyint(double x)
+{
+#ifdef FE_INEXACT
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+#endif
+	x = rint(x);
+#ifdef FE_INEXACT
+	if (!e)
+		feclearexcept(FE_INEXACT);
+#endif
+	return x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nearbyintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nearbyintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nearbyintf.c	(revision 398)
@@ -0,0 +1,18 @@
+#include <fenv.h>
+#include <math.h>
+
+float nearbyintf(float x)
+{
+#ifdef FE_INEXACT
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+#endif
+	x = rintf(x);
+#ifdef FE_INEXACT
+	if (!e)
+		feclearexcept(FE_INEXACT);
+#endif
+	return x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nearbyintl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nearbyintl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nearbyintl.c	(revision 398)
@@ -0,0 +1,26 @@
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double nearbyintl(long double x)
+{
+	return nearbyint(x);
+}
+#else
+#include <fenv.h>
+long double nearbyintl(long double x)
+{
+#ifdef FE_INEXACT
+	#pragma STDC FENV_ACCESS ON
+	int e;
+
+	e = fetestexcept(FE_INEXACT);
+#endif
+	x = rintl(x);
+#ifdef FE_INEXACT
+	if (!e)
+		feclearexcept(FE_INEXACT);
+#endif
+	return x;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nextafter.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nextafter.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nextafter.c	(revision 398)
@@ -0,0 +1,31 @@
+#include "libm.h"
+
+double nextafter(double x, double y)
+{
+	union {double f; uint64_t i;} ux={x}, uy={y};
+	uint64_t ax, ay;
+	int e;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (ux.i == uy.i)
+		return y;
+	ax = ux.i & -1ULL/2;
+	ay = uy.i & -1ULL/2;
+	if (ax == 0) {
+		if (ay == 0)
+			return y;
+		ux.i = (uy.i & 1ULL<<63) | 1;
+	} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63))
+		ux.i--;
+	else
+		ux.i++;
+	e = ux.i >> 52 & 0x7ff;
+	/* raise overflow if ux.f is infinite and x is finite */
+	if (e == 0x7ff)
+		FORCE_EVAL(x+x);
+	/* raise underflow if ux.f is subnormal or zero */
+	if (e == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nextafterf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nextafterf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nextafterf.c	(revision 398)
@@ -0,0 +1,30 @@
+#include "libm.h"
+
+float nextafterf(float x, float y)
+{
+	union {float f; uint32_t i;} ux={x}, uy={y};
+	uint32_t ax, ay, e;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (ux.i == uy.i)
+		return y;
+	ax = ux.i & 0x7fffffff;
+	ay = uy.i & 0x7fffffff;
+	if (ax == 0) {
+		if (ay == 0)
+			return y;
+		ux.i = (uy.i & 0x80000000) | 1;
+	} else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000))
+		ux.i--;
+	else
+		ux.i++;
+	e = ux.i & 0x7f800000;
+	/* raise overflow if ux.f is infinite and x is finite */
+	if (e == 0x7f800000)
+		FORCE_EVAL(x+x);
+	/* raise underflow if ux.f is subnormal or zero */
+	if (e == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nextafterl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nextafterl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nextafterl.c	(revision 398)
@@ -0,0 +1,75 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double nextafterl(long double x, long double y)
+{
+	return nextafter(x, y);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+long double nextafterl(long double x, long double y)
+{
+	union ldshape ux, uy;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (x == y)
+		return y;
+	ux.f = x;
+	if (x == 0) {
+		uy.f = y;
+		ux.i.m = 1;
+		ux.i.se = uy.i.se & 0x8000;
+	} else if ((x < y) == !(ux.i.se & 0x8000)) {
+		ux.i.m++;
+		if (ux.i.m << 1 == 0) {
+			ux.i.m = 1ULL << 63;
+			ux.i.se++;
+		}
+	} else {
+		if (ux.i.m << 1 == 0) {
+			ux.i.se--;
+			if (ux.i.se)
+				ux.i.m = 0;
+		}
+		ux.i.m--;
+	}
+	/* raise overflow if ux is infinite and x is finite */
+	if ((ux.i.se & 0x7fff) == 0x7fff)
+		return x + x;
+	/* raise underflow if ux is subnormal or zero */
+	if ((ux.i.se & 0x7fff) == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+long double nextafterl(long double x, long double y)
+{
+	union ldshape ux, uy;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (x == y)
+		return y;
+	ux.f = x;
+	if (x == 0) {
+		uy.f = y;
+		ux.i.lo = 1;
+		ux.i.se = uy.i.se & 0x8000;
+	} else if ((x < y) == !(ux.i.se & 0x8000)) {
+		ux.i2.lo++;
+		if (ux.i2.lo == 0)
+			ux.i2.hi++;
+	} else {
+		if (ux.i2.lo == 0)
+			ux.i2.hi--;
+		ux.i2.lo--;
+	}
+	/* raise overflow if ux is infinite and x is finite */
+	if ((ux.i.se & 0x7fff) == 0x7fff)
+		return x + x;
+	/* raise underflow if ux is subnormal or zero */
+	if ((ux.i.se & 0x7fff) == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nexttoward.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nexttoward.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nexttoward.c	(revision 398)
@@ -0,0 +1,42 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+double nexttoward(double x, long double y)
+{
+	return nextafter(x, y);
+}
+#else
+double nexttoward(double x, long double y)
+{
+	union {double f; uint64_t i;} ux = {x};
+	int e;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (x == y)
+		return y;
+	if (x == 0) {
+		ux.i = 1;
+		if (signbit(y))
+			ux.i |= 1ULL<<63;
+	} else if (x < y) {
+		if (signbit(x))
+			ux.i--;
+		else
+			ux.i++;
+	} else {
+		if (signbit(x))
+			ux.i++;
+		else
+			ux.i--;
+	}
+	e = ux.i>>52 & 0x7ff;
+	/* raise overflow if ux.f is infinite and x is finite */
+	if (e == 0x7ff)
+		FORCE_EVAL(x+x);
+	/* raise underflow if ux.f is subnormal or zero */
+	if (e == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nexttowardf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nexttowardf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nexttowardf.c	(revision 398)
@@ -0,0 +1,35 @@
+#include "libm.h"
+
+float nexttowardf(float x, long double y)
+{
+	union {float f; uint32_t i;} ux = {x};
+	uint32_t e;
+
+	if (isnan(x) || isnan(y))
+		return x + y;
+	if (x == y)
+		return y;
+	if (x == 0) {
+		ux.i = 1;
+		if (signbit(y))
+			ux.i |= 0x80000000;
+	} else if (x < y) {
+		if (signbit(x))
+			ux.i--;
+		else
+			ux.i++;
+	} else {
+		if (signbit(x))
+			ux.i++;
+		else
+			ux.i--;
+	}
+	e = ux.i & 0x7f800000;
+	/* raise overflow if ux.f is infinite and x is finite */
+	if (e == 0x7f800000)
+		FORCE_EVAL(x+x);
+	/* raise underflow if ux.f is subnormal or zero */
+	if (e == 0)
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nexttowardl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nexttowardl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/nexttowardl.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+long double nexttowardl(long double x, long double y)
+{
+	return nextafterl(x, y);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/pow.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/pow.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/pow.c	(revision 398)
@@ -0,0 +1,328 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_pow.c */
+/*
+ * ====================================================
+ * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* pow(x,y) return x**y
+ *
+ *                    n
+ * Method:  Let x =  2   * (1+f)
+ *      1. Compute and return log2(x) in two pieces:
+ *              log2(x) = w1 + w2,
+ *         where w1 has 53-24 = 29 bit trailing zeros.
+ *      2. Perform y*log2(x) = n+y' by simulating muti-precision
+ *         arithmetic, where |y'|<=0.5.
+ *      3. Return x**y = 2**n*exp(y'*log2)
+ *
+ * Special cases:
+ *      1.  (anything) ** 0  is 1
+ *      2.  1 ** (anything)  is 1
+ *      3.  (anything except 1) ** NAN is NAN
+ *      4.  NAN ** (anything except 0) is NAN
+ *      5.  +-(|x| > 1) **  +INF is +INF
+ *      6.  +-(|x| > 1) **  -INF is +0
+ *      7.  +-(|x| < 1) **  +INF is +0
+ *      8.  +-(|x| < 1) **  -INF is +INF
+ *      9.  -1          ** +-INF is 1
+ *      10. +0 ** (+anything except 0, NAN)               is +0
+ *      11. -0 ** (+anything except 0, NAN, odd integer)  is +0
+ *      12. +0 ** (-anything except 0, NAN)               is +INF, raise divbyzero
+ *      13. -0 ** (-anything except 0, NAN, odd integer)  is +INF, raise divbyzero
+ *      14. -0 ** (+odd integer) is -0
+ *      15. -0 ** (-odd integer) is -INF, raise divbyzero
+ *      16. +INF ** (+anything except 0,NAN) is +INF
+ *      17. +INF ** (-anything except 0,NAN) is +0
+ *      18. -INF ** (+odd integer) is -INF
+ *      19. -INF ** (anything) = -0 ** (-anything), (anything except odd integer)
+ *      20. (anything) ** 1 is (anything)
+ *      21. (anything) ** -1 is 1/(anything)
+ *      22. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ *      23. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ * Accuracy:
+ *      pow(x,y) returns x**y nearly rounded. In particular
+ *                      pow(integer,integer)
+ *      always returns the correct integer provided it is
+ *      representable.
+ *
+ * Constants :
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "libm.h"
+
+static const double
+bp[]   = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
+dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
+two53  =  9007199254740992.0, /* 0x43400000, 0x00000000 */
+huge   =  1.0e300,
+tiny   =  1.0e-300,
+/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1 =  5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
+L2 =  4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
+L3 =  3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
+L4 =  2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
+L5 =  2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
+L6 =  2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
+P1 =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3 =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5 =  4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
+lg2     =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+lg2_h   =  6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
+lg2_l   = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
+ovt     =  8.0085662595372944372e-017, /* -(1024-log2(ovfl+.5ulp)) */
+cp      =  9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
+cp_h    =  9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
+cp_l    = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
+ivln2   =  1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
+ivln2_h =  1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
+ivln2_l =  1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
+
+double pow(double x, double y)
+{
+	double z,ax,z_h,z_l,p_h,p_l;
+	double y1,t1,t2,r,s,t,u,v,w;
+	int32_t i,j,k,yisint,n;
+	int32_t hx,hy,ix,iy;
+	uint32_t lx,ly;
+
+	EXTRACT_WORDS(hx, lx, x);
+	EXTRACT_WORDS(hy, ly, y);
+	ix = hx & 0x7fffffff;
+	iy = hy & 0x7fffffff;
+
+	/* x**0 = 1, even if x is NaN */
+	if ((iy|ly) == 0)
+		return 1.0;
+	/* 1**y = 1, even if y is NaN */
+	if (hx == 0x3ff00000 && lx == 0)
+		return 1.0;
+	/* NaN if either arg is NaN */
+	if (ix > 0x7ff00000 || (ix == 0x7ff00000 && lx != 0) ||
+	    iy > 0x7ff00000 || (iy == 0x7ff00000 && ly != 0))
+		return x + y;
+
+	/* determine if y is an odd int when x < 0
+	 * yisint = 0       ... y is not an integer
+	 * yisint = 1       ... y is an odd int
+	 * yisint = 2       ... y is an even int
+	 */
+	yisint = 0;
+	if (hx < 0) {
+		if (iy >= 0x43400000)
+			yisint = 2; /* even integer y */
+		else if (iy >= 0x3ff00000) {
+			k = (iy>>20) - 0x3ff;  /* exponent */
+			if (k > 20) {
+				uint32_t j = ly>>(52-k);
+				if ((j<<(52-k)) == ly)
+					yisint = 2 - (j&1);
+			} else if (ly == 0) {
+				uint32_t j = iy>>(20-k);
+				if ((j<<(20-k)) == iy)
+					yisint = 2 - (j&1);
+			}
+		}
+	}
+
+	/* special value of y */
+	if (ly == 0) {
+		if (iy == 0x7ff00000) {  /* y is +-inf */
+			if (((ix-0x3ff00000)|lx) == 0)  /* (-1)**+-inf is 1 */
+				return 1.0;
+			else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */
+				return hy >= 0 ? y : 0.0;
+			else                       /* (|x|<1)**+-inf = 0,inf */
+				return hy >= 0 ? 0.0 : -y;
+		}
+		if (iy == 0x3ff00000) {    /* y is +-1 */
+			if (hy >= 0)
+				return x;
+			y = 1/x;
+#if FLT_EVAL_METHOD!=0
+			{
+				union {double f; uint64_t i;} u = {y};
+				uint64_t i = u.i & -1ULL/2;
+				if (i>>52 == 0 && (i&(i-1)))
+					FORCE_EVAL((float)y);
+			}
+#endif
+			return y;
+		}
+		if (hy == 0x40000000)    /* y is 2 */
+			return x*x;
+		if (hy == 0x3fe00000) {  /* y is 0.5 */
+			if (hx >= 0)     /* x >= +0 */
+				return sqrt(x);
+		}
+	}
+
+	ax = fabs(x);
+	/* special value of x */
+	if (lx == 0) {
+		if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { /* x is +-0,+-inf,+-1 */
+			z = ax;
+			if (hy < 0)   /* z = (1/|x|) */
+				z = 1.0/z;
+			if (hx < 0) {
+				if (((ix-0x3ff00000)|yisint) == 0) {
+					z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+				} else if (yisint == 1)
+					z = -z;          /* (x<0)**odd = -(|x|**odd) */
+			}
+			return z;
+		}
+	}
+
+	s = 1.0; /* sign of result */
+	if (hx < 0) {
+		if (yisint == 0) /* (x<0)**(non-int) is NaN */
+			return (x-x)/(x-x);
+		if (yisint == 1) /* (x<0)**(odd int) */
+			s = -1.0;
+	}
+
+	/* |y| is huge */
+	if (iy > 0x41e00000) { /* if |y| > 2**31 */
+		if (iy > 0x43f00000) {  /* if |y| > 2**64, must o/uflow */
+			if (ix <= 0x3fefffff)
+				return hy < 0 ? huge*huge : tiny*tiny;
+			if (ix >= 0x3ff00000)
+				return hy > 0 ? huge*huge : tiny*tiny;
+		}
+		/* over/underflow if x is not close to one */
+		if (ix < 0x3fefffff)
+			return hy < 0 ? s*huge*huge : s*tiny*tiny;
+		if (ix > 0x3ff00000)
+			return hy > 0 ? s*huge*huge : s*tiny*tiny;
+		/* now |1-x| is tiny <= 2**-20, suffice to compute
+		   log(x) by x-x^2/2+x^3/3-x^4/4 */
+		t = ax - 1.0;       /* t has 20 trailing zeros */
+		w = (t*t)*(0.5 - t*(0.3333333333333333333333-t*0.25));
+		u = ivln2_h*t;      /* ivln2_h has 21 sig. bits */
+		v = t*ivln2_l - w*ivln2;
+		t1 = u + v;
+		SET_LOW_WORD(t1, 0);
+		t2 = v - (t1-u);
+	} else {
+		double ss,s2,s_h,s_l,t_h,t_l;
+		n = 0;
+		/* take care subnormal number */
+		if (ix < 0x00100000) {
+			ax *= two53;
+			n -= 53;
+			GET_HIGH_WORD(ix,ax);
+		}
+		n += ((ix)>>20) - 0x3ff;
+		j = ix & 0x000fffff;
+		/* determine interval */
+		ix = j | 0x3ff00000;   /* normalize ix */
+		if (j <= 0x3988E)      /* |x|<sqrt(3/2) */
+			k = 0;
+		else if (j < 0xBB67A)  /* |x|<sqrt(3)   */
+			k = 1;
+		else {
+			k = 0;
+			n += 1;
+			ix -= 0x00100000;
+		}
+		SET_HIGH_WORD(ax, ix);
+
+		/* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+		u = ax - bp[k];        /* bp[0]=1.0, bp[1]=1.5 */
+		v = 1.0/(ax+bp[k]);
+		ss = u*v;
+		s_h = ss;
+		SET_LOW_WORD(s_h, 0);
+		/* t_h=ax+bp[k] High */
+		t_h = 0.0;
+		SET_HIGH_WORD(t_h, ((ix>>1)|0x20000000) + 0x00080000 + (k<<18));
+		t_l = ax - (t_h-bp[k]);
+		s_l = v*((u-s_h*t_h)-s_h*t_l);
+		/* compute log(ax) */
+		s2 = ss*ss;
+		r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+		r += s_l*(s_h+ss);
+		s2 = s_h*s_h;
+		t_h = 3.0 + s2 + r;
+		SET_LOW_WORD(t_h, 0);
+		t_l = r - ((t_h-3.0)-s2);
+		/* u+v = ss*(1+...) */
+		u = s_h*t_h;
+		v = s_l*t_h + t_l*ss;
+		/* 2/(3log2)*(ss+...) */
+		p_h = u + v;
+		SET_LOW_WORD(p_h, 0);
+		p_l = v - (p_h-u);
+		z_h = cp_h*p_h;        /* cp_h+cp_l = 2/(3*log2) */
+		z_l = cp_l*p_h+p_l*cp + dp_l[k];
+		/* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+		t = (double)n;
+		t1 = ((z_h + z_l) + dp_h[k]) + t;
+		SET_LOW_WORD(t1, 0);
+		t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
+	}
+
+	/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+	y1 = y;
+	SET_LOW_WORD(y1, 0);
+	p_l = (y-y1)*t1 + y*t2;
+	p_h = y1*t1;
+	z = p_l + p_h;
+	EXTRACT_WORDS(j, i, z);
+	if (j >= 0x40900000) {                      /* z >= 1024 */
+		if (((j-0x40900000)|i) != 0)        /* if z > 1024 */
+			return s*huge*huge;         /* overflow */
+		if (p_l + ovt > z - p_h)
+			return s*huge*huge;         /* overflow */
+	} else if ((j&0x7fffffff) >= 0x4090cc00) {  /* z <= -1075 */  // FIXME: instead of abs(j) use unsigned j
+		if (((j-0xc090cc00)|i) != 0)        /* z < -1075 */
+			return s*tiny*tiny;         /* underflow */
+		if (p_l <= z - p_h)
+			return s*tiny*tiny;         /* underflow */
+	}
+	/*
+	 * compute 2**(p_h+p_l)
+	 */
+	i = j & 0x7fffffff;
+	k = (i>>20) - 0x3ff;
+	n = 0;
+	if (i > 0x3fe00000) {  /* if |z| > 0.5, set n = [z+0.5] */
+		n = j + (0x00100000>>(k+1));
+		k = ((n&0x7fffffff)>>20) - 0x3ff;  /* new k for n */
+		t = 0.0;
+		SET_HIGH_WORD(t, n & ~(0x000fffff>>k));
+		n = ((n&0x000fffff)|0x00100000)>>(20-k);
+		if (j < 0)
+			n = -n;
+		p_h -= t;
+	}
+	t = p_l + p_h;
+	SET_LOW_WORD(t, 0);
+	u = t*lg2_h;
+	v = (p_l-(t-p_h))*lg2 + t*lg2_l;
+	z = u + v;
+	w = v - (z-u);
+	t = z*z;
+	t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+	r = (z*t1)/(t1-2.0) - (w + z*w);
+	z = 1.0 - (r-z);
+	GET_HIGH_WORD(j, z);
+	j += n<<20;
+	if ((j>>20) <= 0)  /* subnormal output */
+		z = scalbn(z,n);
+	else
+		SET_HIGH_WORD(z, j);
+	return s*z;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/powf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/powf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/powf.c	(revision 398)
@@ -0,0 +1,259 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_powf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float
+bp[]   = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */
+dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */
+two24  =  16777216.0,  /* 0x4b800000 */
+huge   =  1.0e30,
+tiny   =  1.0e-30,
+/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1 =  6.0000002384e-01, /* 0x3f19999a */
+L2 =  4.2857143283e-01, /* 0x3edb6db7 */
+L3 =  3.3333334327e-01, /* 0x3eaaaaab */
+L4 =  2.7272811532e-01, /* 0x3e8ba305 */
+L5 =  2.3066075146e-01, /* 0x3e6c3255 */
+L6 =  2.0697501302e-01, /* 0x3e53f142 */
+P1 =  1.6666667163e-01, /* 0x3e2aaaab */
+P2 = -2.7777778450e-03, /* 0xbb360b61 */
+P3 =  6.6137559770e-05, /* 0x388ab355 */
+P4 = -1.6533901999e-06, /* 0xb5ddea0e */
+P5 =  4.1381369442e-08, /* 0x3331bb4c */
+lg2     =  6.9314718246e-01, /* 0x3f317218 */
+lg2_h   =  6.93145752e-01,   /* 0x3f317200 */
+lg2_l   =  1.42860654e-06,   /* 0x35bfbe8c */
+ovt     =  4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */
+cp      =  9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */
+cp_h    =  9.6191406250e-01, /* 0x3f764000 =12b cp */
+cp_l    = -1.1736857402e-04, /* 0xb8f623c6 =tail of cp_h */
+ivln2   =  1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */
+ivln2_h =  1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/
+ivln2_l =  7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
+
+float powf(float x, float y)
+{
+	float z,ax,z_h,z_l,p_h,p_l;
+	float y1,t1,t2,r,s,sn,t,u,v,w;
+	int32_t i,j,k,yisint,n;
+	int32_t hx,hy,ix,iy,is;
+
+	GET_FLOAT_WORD(hx, x);
+	GET_FLOAT_WORD(hy, y);
+	ix = hx & 0x7fffffff;
+	iy = hy & 0x7fffffff;
+
+	/* x**0 = 1, even if x is NaN */
+	if (iy == 0)
+		return 1.0f;
+	/* 1**y = 1, even if y is NaN */
+	if (hx == 0x3f800000)
+		return 1.0f;
+	/* NaN if either arg is NaN */
+	if (ix > 0x7f800000 || iy > 0x7f800000)
+		return x + y;
+
+	/* determine if y is an odd int when x < 0
+	 * yisint = 0       ... y is not an integer
+	 * yisint = 1       ... y is an odd int
+	 * yisint = 2       ... y is an even int
+	 */
+	yisint  = 0;
+	if (hx < 0) {
+		if (iy >= 0x4b800000)
+			yisint = 2; /* even integer y */
+		else if (iy >= 0x3f800000) {
+			k = (iy>>23) - 0x7f;         /* exponent */
+			j = iy>>(23-k);
+			if ((j<<(23-k)) == iy)
+				yisint = 2 - (j & 1);
+		}
+	}
+
+	/* special value of y */
+	if (iy == 0x7f800000) {  /* y is +-inf */
+		if (ix == 0x3f800000)      /* (-1)**+-inf is 1 */
+			return 1.0f;
+		else if (ix > 0x3f800000)  /* (|x|>1)**+-inf = inf,0 */
+			return hy >= 0 ? y : 0.0f;
+		else                       /* (|x|<1)**+-inf = 0,inf */
+			return hy >= 0 ? 0.0f: -y;
+	}
+	if (iy == 0x3f800000)    /* y is +-1 */
+		return hy >= 0 ? x : 1.0f/x;
+	if (hy == 0x40000000)    /* y is 2 */
+		return x*x;
+	if (hy == 0x3f000000) {  /* y is  0.5 */
+		if (hx >= 0)     /* x >= +0 */
+			return sqrtf(x);
+	}
+
+	ax = fabsf(x);
+	/* special value of x */
+	if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) { /* x is +-0,+-inf,+-1 */
+		z = ax;
+		if (hy < 0)  /* z = (1/|x|) */
+			z = 1.0f/z;
+		if (hx < 0) {
+			if (((ix-0x3f800000)|yisint) == 0) {
+				z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+			} else if (yisint == 1)
+				z = -z;          /* (x<0)**odd = -(|x|**odd) */
+		}
+		return z;
+	}
+
+	sn = 1.0f; /* sign of result */
+	if (hx < 0) {
+		if (yisint == 0) /* (x<0)**(non-int) is NaN */
+			return (x-x)/(x-x);
+		if (yisint == 1) /* (x<0)**(odd int) */
+			sn = -1.0f;
+	}
+
+	/* |y| is huge */
+	if (iy > 0x4d000000) { /* if |y| > 2**27 */
+		/* over/underflow if x is not close to one */
+		if (ix < 0x3f7ffff8)
+			return hy < 0 ? sn*huge*huge : sn*tiny*tiny;
+		if (ix > 0x3f800007)
+			return hy > 0 ? sn*huge*huge : sn*tiny*tiny;
+		/* now |1-x| is tiny <= 2**-20, suffice to compute
+		   log(x) by x-x^2/2+x^3/3-x^4/4 */
+		t = ax - 1;     /* t has 20 trailing zeros */
+		w = (t*t)*(0.5f - t*(0.333333333333f - t*0.25f));
+		u = ivln2_h*t;  /* ivln2_h has 16 sig. bits */
+		v = t*ivln2_l - w*ivln2;
+		t1 = u + v;
+		GET_FLOAT_WORD(is, t1);
+		SET_FLOAT_WORD(t1, is & 0xfffff000);
+		t2 = v - (t1-u);
+	} else {
+		float s2,s_h,s_l,t_h,t_l;
+		n = 0;
+		/* take care subnormal number */
+		if (ix < 0x00800000) {
+			ax *= two24;
+			n -= 24;
+			GET_FLOAT_WORD(ix, ax);
+		}
+		n += ((ix)>>23) - 0x7f;
+		j = ix & 0x007fffff;
+		/* determine interval */
+		ix = j | 0x3f800000;     /* normalize ix */
+		if (j <= 0x1cc471)       /* |x|<sqrt(3/2) */
+			k = 0;
+		else if (j < 0x5db3d7)   /* |x|<sqrt(3)   */
+			k = 1;
+		else {
+			k = 0;
+			n += 1;
+			ix -= 0x00800000;
+		}
+		SET_FLOAT_WORD(ax, ix);
+
+		/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+		u = ax - bp[k];   /* bp[0]=1.0, bp[1]=1.5 */
+		v = 1.0f/(ax+bp[k]);
+		s = u*v;
+		s_h = s;
+		GET_FLOAT_WORD(is, s_h);
+		SET_FLOAT_WORD(s_h, is & 0xfffff000);
+		/* t_h=ax+bp[k] High */
+		is = ((ix>>1) & 0xfffff000) | 0x20000000;
+		SET_FLOAT_WORD(t_h, is + 0x00400000 + (k<<21));
+		t_l = ax - (t_h - bp[k]);
+		s_l = v*((u - s_h*t_h) - s_h*t_l);
+		/* compute log(ax) */
+		s2 = s*s;
+		r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+		r += s_l*(s_h+s);
+		s2 = s_h*s_h;
+		t_h = 3.0f + s2 + r;
+		GET_FLOAT_WORD(is, t_h);
+		SET_FLOAT_WORD(t_h, is & 0xfffff000);
+		t_l = r - ((t_h - 3.0f) - s2);
+		/* u+v = s*(1+...) */
+		u = s_h*t_h;
+		v = s_l*t_h + t_l*s;
+		/* 2/(3log2)*(s+...) */
+		p_h = u + v;
+		GET_FLOAT_WORD(is, p_h);
+		SET_FLOAT_WORD(p_h, is & 0xfffff000);
+		p_l = v - (p_h - u);
+		z_h = cp_h*p_h;  /* cp_h+cp_l = 2/(3*log2) */
+		z_l = cp_l*p_h + p_l*cp+dp_l[k];
+		/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+		t = (float)n;
+		t1 = (((z_h + z_l) + dp_h[k]) + t);
+		GET_FLOAT_WORD(is, t1);
+		SET_FLOAT_WORD(t1, is & 0xfffff000);
+		t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
+	}
+
+	/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+	GET_FLOAT_WORD(is, y);
+	SET_FLOAT_WORD(y1, is & 0xfffff000);
+	p_l = (y-y1)*t1 + y*t2;
+	p_h = y1*t1;
+	z = p_l + p_h;
+	GET_FLOAT_WORD(j, z);
+	if (j > 0x43000000)          /* if z > 128 */
+		return sn*huge*huge;  /* overflow */
+	else if (j == 0x43000000) {  /* if z == 128 */
+		if (p_l + ovt > z - p_h)
+			return sn*huge*huge;  /* overflow */
+	} else if ((j&0x7fffffff) > 0x43160000)  /* z < -150 */ // FIXME: check should be  (uint32_t)j > 0xc3160000
+		return sn*tiny*tiny;  /* underflow */
+	else if (j == 0xc3160000) {  /* z == -150 */
+		if (p_l <= z-p_h)
+			return sn*tiny*tiny;  /* underflow */
+	}
+	/*
+	 * compute 2**(p_h+p_l)
+	 */
+	i = j & 0x7fffffff;
+	k = (i>>23) - 0x7f;
+	n = 0;
+	if (i > 0x3f000000) {   /* if |z| > 0.5, set n = [z+0.5] */
+		n = j + (0x00800000>>(k+1));
+		k = ((n&0x7fffffff)>>23) - 0x7f;  /* new k for n */
+		SET_FLOAT_WORD(t, n & ~(0x007fffff>>k));
+		n = ((n&0x007fffff)|0x00800000)>>(23-k);
+		if (j < 0)
+			n = -n;
+		p_h -= t;
+	}
+	t = p_l + p_h;
+	GET_FLOAT_WORD(is, t);
+	SET_FLOAT_WORD(t, is & 0xffff8000);
+	u = t*lg2_h;
+	v = (p_l-(t-p_h))*lg2 + t*lg2_l;
+	z = u + v;
+	w = v - (z - u);
+	t = z*z;
+	t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+	r = (z*t1)/(t1-2.0f) - (w+z*w);
+	z = 1.0f - (r - z);
+	GET_FLOAT_WORD(j, z);
+	j += n<<23;
+	if ((j>>23) <= 0)  /* subnormal output */
+		z = scalbnf(z, n);
+	else
+		SET_FLOAT_WORD(z, j);
+	return sn*z;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/powl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/powl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/powl.c	(revision 398)
@@ -0,0 +1,522 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_powl.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*                                                      powl.c
+ *
+ *      Power function, long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, z, powl();
+ *
+ * z = powl( x, y );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Computes x raised to the yth power.  Analytically,
+ *
+ *      x**y  =  exp( y log(x) ).
+ *
+ * Following Cody and Waite, this program uses a lookup table
+ * of 2**-i/32 and pseudo extended precision arithmetic to
+ * obtain several extra bits of accuracy in both the logarithm
+ * and the exponential.
+ *
+ *
+ * ACCURACY:
+ *
+ * The relative error of pow(x,y) can be estimated
+ * by   y dl ln(2),   where dl is the absolute error of
+ * the internally computed base 2 logarithm.  At the ends
+ * of the approximation interval the logarithm equal 1/32
+ * and its relative error is about 1 lsb = 1.1e-19.  Hence
+ * the predicted relative error in the result is 2.3e-21 y .
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *
+ *    IEEE     +-1000       40000      2.8e-18      3.7e-19
+ * .001 < x < 1000, with log(x) uniformly distributed.
+ * -1000 < y < 1000, y uniformly distributed.
+ *
+ *    IEEE     0,8700       60000      6.5e-18      1.0e-18
+ * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed.
+ *
+ *
+ * ERROR MESSAGES:
+ *
+ *   message         condition      value returned
+ * pow overflow     x**y > MAXNUM      INFINITY
+ * pow underflow   x**y < 1/MAXNUM       0.0
+ * pow domain      x<0 and y noninteger  0.0
+ *
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double powl(long double x, long double y)
+{
+	return pow(x, y);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+
+/* Table size */
+#define NXT 32
+
+/* log(1+x) =  x - .5x^2 + x^3 *  P(z)/Q(z)
+ * on the domain  2^(-1/32) - 1  <=  x  <=  2^(1/32) - 1
+ */
+static const long double P[] = {
+ 8.3319510773868690346226E-4L,
+ 4.9000050881978028599627E-1L,
+ 1.7500123722550302671919E0L,
+ 1.4000100839971580279335E0L,
+};
+static const long double Q[] = {
+/* 1.0000000000000000000000E0L,*/
+ 5.2500282295834889175431E0L,
+ 8.4000598057587009834666E0L,
+ 4.2000302519914740834728E0L,
+};
+/* A[i] = 2^(-i/32), rounded to IEEE long double precision.
+ * If i is even, A[i] + B[i/2] gives additional accuracy.
+ */
+static const long double A[33] = {
+ 1.0000000000000000000000E0L,
+ 9.7857206208770013448287E-1L,
+ 9.5760328069857364691013E-1L,
+ 9.3708381705514995065011E-1L,
+ 9.1700404320467123175367E-1L,
+ 8.9735453750155359320742E-1L,
+ 8.7812608018664974155474E-1L,
+ 8.5930964906123895780165E-1L,
+ 8.4089641525371454301892E-1L,
+ 8.2287773907698242225554E-1L,
+ 8.0524516597462715409607E-1L,
+ 7.8799042255394324325455E-1L,
+ 7.7110541270397041179298E-1L,
+ 7.5458221379671136985669E-1L,
+ 7.3841307296974965571198E-1L,
+ 7.2259040348852331001267E-1L,
+ 7.0710678118654752438189E-1L,
+ 6.9195494098191597746178E-1L,
+ 6.7712777346844636413344E-1L,
+ 6.6261832157987064729696E-1L,
+ 6.4841977732550483296079E-1L,
+ 6.3452547859586661129850E-1L,
+ 6.2092890603674202431705E-1L,
+ 6.0762367999023443907803E-1L,
+ 5.9460355750136053334378E-1L,
+ 5.8186242938878875689693E-1L,
+ 5.6939431737834582684856E-1L,
+ 5.5719337129794626814472E-1L,
+ 5.4525386633262882960438E-1L,
+ 5.3357020033841180906486E-1L,
+ 5.2213689121370692017331E-1L,
+ 5.1094857432705833910408E-1L,
+ 5.0000000000000000000000E-1L,
+};
+static const long double B[17] = {
+ 0.0000000000000000000000E0L,
+ 2.6176170809902549338711E-20L,
+-1.0126791927256478897086E-20L,
+ 1.3438228172316276937655E-21L,
+ 1.2207982955417546912101E-20L,
+-6.3084814358060867200133E-21L,
+ 1.3164426894366316434230E-20L,
+-1.8527916071632873716786E-20L,
+ 1.8950325588932570796551E-20L,
+ 1.5564775779538780478155E-20L,
+ 6.0859793637556860974380E-21L,
+-2.0208749253662532228949E-20L,
+ 1.4966292219224761844552E-20L,
+ 3.3540909728056476875639E-21L,
+-8.6987564101742849540743E-22L,
+-1.2327176863327626135542E-20L,
+ 0.0000000000000000000000E0L,
+};
+
+/* 2^x = 1 + x P(x),
+ * on the interval -1/32 <= x <= 0
+ */
+static const long double R[] = {
+ 1.5089970579127659901157E-5L,
+ 1.5402715328927013076125E-4L,
+ 1.3333556028915671091390E-3L,
+ 9.6181291046036762031786E-3L,
+ 5.5504108664798463044015E-2L,
+ 2.4022650695910062854352E-1L,
+ 6.9314718055994530931447E-1L,
+};
+
+#define MEXP (NXT*16384.0L)
+/* The following if denormal numbers are supported, else -MEXP: */
+#define MNEXP (-NXT*(16384.0L+64.0L))
+/* log2(e) - 1 */
+#define LOG2EA 0.44269504088896340735992L
+
+#define F W
+#define Fa Wa
+#define Fb Wb
+#define G W
+#define Ga Wa
+#define Gb u
+#define H W
+#define Ha Wb
+#define Hb Wb
+
+static const long double MAXLOGL = 1.1356523406294143949492E4L;
+static const long double MINLOGL = -1.13994985314888605586758E4L;
+static const long double LOGE2L = 6.9314718055994530941723E-1L;
+static const long double huge = 0x1p10000L;
+/* XXX Prevent gcc from erroneously constant folding this. */
+static const volatile long double twom10000 = 0x1p-10000L;
+
+static long double reducl(long double);
+static long double powil(long double, int);
+
+long double powl(long double x, long double y)
+{
+	/* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */
+	int i, nflg, iyflg, yoddint;
+	long e;
+	volatile long double z=0;
+	long double w=0, W=0, Wa=0, Wb=0, ya=0, yb=0, u=0;
+
+	/* make sure no invalid exception is raised by nan comparision */
+	if (isnan(x)) {
+		if (!isnan(y) && y == 0.0)
+			return 1.0;
+		return x;
+	}
+	if (isnan(y)) {
+		if (x == 1.0)
+			return 1.0;
+		return y;
+	}
+	if (x == 1.0)
+		return 1.0; /* 1**y = 1, even if y is nan */
+	if (x == -1.0 && !isfinite(y))
+		return 1.0; /* -1**inf = 1 */
+	if (y == 0.0)
+		return 1.0; /* x**0 = 1, even if x is nan */
+	if (y == 1.0)
+		return x;
+	if (y >= LDBL_MAX) {
+		if (x > 1.0 || x < -1.0)
+			return INFINITY;
+		if (x != 0.0)
+			return 0.0;
+	}
+	if (y <= -LDBL_MAX) {
+		if (x > 1.0 || x < -1.0)
+			return 0.0;
+		if (x != 0.0 || y == -INFINITY)
+			return INFINITY;
+	}
+	if (x >= LDBL_MAX) {
+		if (y > 0.0)
+			return INFINITY;
+		return 0.0;
+	}
+
+	w = floorl(y);
+
+	/* Set iyflg to 1 if y is an integer. */
+	iyflg = 0;
+	if (w == y)
+		iyflg = 1;
+
+	/* Test for odd integer y. */
+	yoddint = 0;
+	if (iyflg) {
+		ya = fabsl(y);
+		ya = floorl(0.5 * ya);
+		yb = 0.5 * fabsl(w);
+		if( ya != yb )
+			yoddint = 1;
+	}
+
+	if (x <= -LDBL_MAX) {
+		if (y > 0.0) {
+			if (yoddint)
+				return -INFINITY;
+			return INFINITY;
+		}
+		if (y < 0.0) {
+			if (yoddint)
+				return -0.0;
+			return 0.0;
+		}
+	}
+	nflg = 0; /* (x<0)**(odd int) */
+	if (x <= 0.0) {
+		if (x == 0.0) {
+			if (y < 0.0) {
+				if (signbit(x) && yoddint)
+					/* (-0.0)**(-odd int) = -inf, divbyzero */
+					return -1.0/0.0;
+				/* (+-0.0)**(negative) = inf, divbyzero */
+				return 1.0/0.0;
+			}
+			if (signbit(x) && yoddint)
+				return -0.0;
+			return 0.0;
+		}
+		if (iyflg == 0)
+			return (x - x) / (x - x); /* (x<0)**(non-int) is NaN */
+		/* (x<0)**(integer) */
+		if (yoddint)
+			nflg = 1; /* negate result */
+		x = -x;
+	}
+	/* (+integer)**(integer)  */
+	if (iyflg && floorl(x) == x && fabsl(y) < 32768.0) {
+		w = powil(x, (int)y);
+		return nflg ? -w : w;
+	}
+
+	/* separate significand from exponent */
+	x = frexpl(x, &i);
+	e = i;
+
+	/* find significand in antilog table A[] */
+	i = 1;
+	if (x <= A[17])
+		i = 17;
+	if (x <= A[i+8])
+		i += 8;
+	if (x <= A[i+4])
+		i += 4;
+	if (x <= A[i+2])
+		i += 2;
+	if (x >= A[1])
+		i = -1;
+	i += 1;
+
+	/* Find (x - A[i])/A[i]
+	 * in order to compute log(x/A[i]):
+	 *
+	 * log(x) = log( a x/a ) = log(a) + log(x/a)
+	 *
+	 * log(x/a) = log(1+v),  v = x/a - 1 = (x-a)/a
+	 */
+	x -= A[i];
+	x -= B[i/2];
+	x /= A[i];
+
+	/* rational approximation for log(1+v):
+	 *
+	 * log(1+v)  =  v  -  v**2/2  +  v**3 P(v) / Q(v)
+	 */
+	z = x*x;
+	w = x * (z * __polevll(x, P, 3) / __p1evll(x, Q, 3));
+	w = w - 0.5*z;
+
+	/* Convert to base 2 logarithm:
+	 * multiply by log2(e) = 1 + LOG2EA
+	 */
+	z = LOG2EA * w;
+	z += w;
+	z += LOG2EA * x;
+	z += x;
+
+	/* Compute exponent term of the base 2 logarithm. */
+	w = -i;
+	w /= NXT;
+	w += e;
+	/* Now base 2 log of x is w + z. */
+
+	/* Multiply base 2 log by y, in extended precision. */
+
+	/* separate y into large part ya
+	 * and small part yb less than 1/NXT
+	 */
+	ya = reducl(y);
+	yb = y - ya;
+
+	/* (w+z)(ya+yb)
+	 * = w*ya + w*yb + z*y
+	 */
+	F = z * y  +  w * yb;
+	Fa = reducl(F);
+	Fb = F - Fa;
+
+	G = Fa + w * ya;
+	Ga = reducl(G);
+	Gb = G - Ga;
+
+	H = Fb + Gb;
+	Ha = reducl(H);
+	w = (Ga + Ha) * NXT;
+
+	/* Test the power of 2 for overflow */
+	if (w > MEXP)
+		return huge * huge;  /* overflow */
+	if (w < MNEXP)
+		return twom10000 * twom10000;  /* underflow */
+
+	e = w;
+	Hb = H - Ha;
+
+	if (Hb > 0.0) {
+		e += 1;
+		Hb -= 1.0/NXT;  /*0.0625L;*/
+	}
+
+	/* Now the product y * log2(x)  =  Hb + e/NXT.
+	 *
+	 * Compute base 2 exponential of Hb,
+	 * where -0.0625 <= Hb <= 0.
+	 */
+	z = Hb * __polevll(Hb, R, 6);  /*  z = 2**Hb - 1  */
+
+	/* Express e/NXT as an integer plus a negative number of (1/NXT)ths.
+	 * Find lookup table entry for the fractional power of 2.
+	 */
+	if (e < 0)
+		i = 0;
+	else
+		i = 1;
+	i = e/NXT + i;
+	e = NXT*i - e;
+	w = A[e];
+	z = w * z;  /*  2**-e * ( 1 + (2**Hb-1) )  */
+	z = z + w;
+	z = scalbnl(z, i);  /* multiply by integer power of 2 */
+
+	if (nflg)
+		z = -z;
+	return z;
+}
+
+
+/* Find a multiple of 1/NXT that is within 1/NXT of x. */
+static long double reducl(long double x)
+{
+	long double t;
+
+	t = x * NXT;
+	t = floorl(t);
+	t = t / NXT;
+	return t;
+}
+
+/*
+ *      Positive real raised to integer power, long double precision
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, powil();
+ * int n;
+ *
+ * y = powil( x, n );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns argument x>0 raised to the nth power.
+ * The routine efficiently decomposes n as a sum of powers of
+ * two. The desired power is a product of two-to-the-kth
+ * powers of x.  Thus to compute the 32767 power of x requires
+ * 28 multiplications instead of 32767 multiplications.
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   x domain   n domain  # trials      peak         rms
+ *    IEEE     .001,1000  -1022,1023  50000       4.3e-17     7.8e-18
+ *    IEEE        1,2     -1022,1023  20000       3.9e-17     7.6e-18
+ *    IEEE     .99,1.01     0,8700    10000       3.6e-16     7.2e-17
+ *
+ * Returns MAXNUM on overflow, zero on underflow.
+ */
+
+static long double powil(long double x, int nn)
+{
+	long double ww, y;
+	long double s;
+	int n, e, sign, lx;
+
+	if (nn == 0)
+		return 1.0;
+
+	if (nn < 0) {
+		sign = -1;
+		n = -nn;
+	} else {
+		sign = 1;
+		n = nn;
+	}
+
+	/* Overflow detection */
+
+	/* Calculate approximate logarithm of answer */
+	s = x;
+	s = frexpl( s, &lx);
+	e = (lx - 1)*n;
+	if ((e == 0) || (e > 64) || (e < -64)) {
+		s = (s - 7.0710678118654752e-1L) / (s +  7.0710678118654752e-1L);
+		s = (2.9142135623730950L * s - 0.5 + lx) * nn * LOGE2L;
+	} else {
+		s = LOGE2L * e;
+	}
+
+	if (s > MAXLOGL)
+		return huge * huge;  /* overflow */
+
+	if (s < MINLOGL)
+		return twom10000 * twom10000;  /* underflow */
+	/* Handle tiny denormal answer, but with less accuracy
+	 * since roundoff error in 1.0/x will be amplified.
+	 * The precise demarcation should be the gradual underflow threshold.
+	 */
+	if (s < -MAXLOGL+2.0) {
+		x = 1.0/x;
+		sign = -sign;
+	}
+
+	/* First bit of the power */
+	if (n & 1)
+		y = x;
+	else
+		y = 1.0;
+
+	ww = x;
+	n >>= 1;
+	while (n) {
+		ww = ww * ww;   /* arg to the 2-to-the-kth power */
+		if (n & 1)     /* if that bit is set, then include in product */
+			y *= ww;
+		n >>= 1;
+	}
+
+	if (sign < 0)
+		y = 1.0/y;
+	return y;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double powl(long double x, long double y)
+{
+	return pow(x, y);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remainder.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remainder.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remainder.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <math.h>
+#include "libc.h"
+
+double remainder(double x, double y)
+{
+	int q;
+	return remquo(x, y, &q);
+}
+
+weak_alias(remainder, drem);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remainderf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remainderf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remainderf.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <math.h>
+#include "libc.h"
+
+float remainderf(float x, float y)
+{
+	int q;
+	return remquof(x, y, &q);
+}
+
+weak_alias(remainderf, dremf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remainderl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remainderl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remainderl.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double remainderl(long double x, long double y)
+{
+	return remainder(x, y);
+}
+#else
+long double remainderl(long double x, long double y)
+{
+	int q;
+	return remquol(x, y, &q);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remquo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remquo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remquo.c	(revision 398)
@@ -0,0 +1,82 @@
+#include <math.h>
+#include <stdint.h>
+
+double remquo(double x, double y, int *quo)
+{
+	union {double f; uint64_t i;} ux = {x}, uy = {y};
+	int ex = ux.i>>52 & 0x7ff;
+	int ey = uy.i>>52 & 0x7ff;
+	int sx = ux.i>>63;
+	int sy = uy.i>>63;
+	uint32_t q;
+	uint64_t i;
+	uint64_t uxi = ux.i;
+
+	*quo = 0;
+	if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
+		return (x*y)/(x*y);
+	if (ux.i<<1 == 0)
+		return x;
+
+	/* normalize x and y */
+	if (!ex) {
+		for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);
+		uxi <<= -ex + 1;
+	} else {
+		uxi &= -1ULL >> 12;
+		uxi |= 1ULL << 52;
+	}
+	if (!ey) {
+		for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);
+		uy.i <<= -ey + 1;
+	} else {
+		uy.i &= -1ULL >> 12;
+		uy.i |= 1ULL << 52;
+	}
+
+	q = 0;
+	if (ex < ey) {
+		if (ex+1 == ey)
+			goto end;
+		return x;
+	}
+
+	/* x mod y */
+	for (; ex > ey; ex--) {
+		i = uxi - uy.i;
+		if (i >> 63 == 0) {
+			uxi = i;
+			q++;
+		}
+		uxi <<= 1;
+		q <<= 1;
+	}
+	i = uxi - uy.i;
+	if (i >> 63 == 0) {
+		uxi = i;
+		q++;
+	}
+	if (uxi == 0)
+		ex = -60;
+	else
+		for (; uxi>>52 == 0; uxi <<= 1, ex--);
+end:
+	/* scale result and decide between |x| and |x|-|y| */
+	if (ex > 0) {
+		uxi -= 1ULL << 52;
+		uxi |= (uint64_t)ex << 52;
+	} else {
+		uxi >>= -ex + 1;
+	}
+	ux.i = uxi;
+	x = ux.f;
+	if (sy)
+		y = -y;
+	if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {
+		x -= y;
+		q++;
+	}
+	q &= 0x7fffffff;
+	*quo = sx^sy ? -(int)q : (int)q;
+	return sx ? -x : x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remquof.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remquof.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remquof.c	(revision 398)
@@ -0,0 +1,82 @@
+#include <math.h>
+#include <stdint.h>
+
+float remquof(float x, float y, int *quo)
+{
+	union {float f; uint32_t i;} ux = {x}, uy = {y};
+	int ex = ux.i>>23 & 0xff;
+	int ey = uy.i>>23 & 0xff;
+	int sx = ux.i>>31;
+	int sy = uy.i>>31;
+	uint32_t q;
+	uint32_t i;
+	uint32_t uxi = ux.i;
+
+	*quo = 0;
+	if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
+		return (x*y)/(x*y);
+	if (ux.i<<1 == 0)
+		return x;
+
+	/* normalize x and y */
+	if (!ex) {
+		for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);
+		uxi <<= -ex + 1;
+	} else {
+		uxi &= -1U >> 9;
+		uxi |= 1U << 23;
+	}
+	if (!ey) {
+		for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);
+		uy.i <<= -ey + 1;
+	} else {
+		uy.i &= -1U >> 9;
+		uy.i |= 1U << 23;
+	}
+
+	q = 0;
+	if (ex < ey) {
+		if (ex+1 == ey)
+			goto end;
+		return x;
+	}
+
+	/* x mod y */
+	for (; ex > ey; ex--) {
+		i = uxi - uy.i;
+		if (i >> 31 == 0) {
+			uxi = i;
+			q++;
+		}
+		uxi <<= 1;
+		q <<= 1;
+	}
+	i = uxi - uy.i;
+	if (i >> 31 == 0) {
+		uxi = i;
+		q++;
+	}
+	if (uxi == 0)
+		ex = -30;
+	else
+		for (; uxi>>23 == 0; uxi <<= 1, ex--);
+end:
+	/* scale result and decide between |x| and |x|-|y| */
+	if (ex > 0) {
+		uxi -= 1U << 23;
+		uxi |= (uint32_t)ex << 23;
+	} else {
+		uxi >>= -ex + 1;
+	}
+	ux.i = uxi;
+	x = ux.f;
+	if (sy)
+		y = -y;
+	if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {
+		x -= y;
+		q++;
+	}
+	q &= 0x7fffffff;
+	*quo = sx^sy ? -(int)q : (int)q;
+	return sx ? -x : x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remquol.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remquol.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/remquol.c	(revision 398)
@@ -0,0 +1,124 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double remquol(long double x, long double y, int *quo)
+{
+	return remquo(x, y, quo);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double remquol(long double x, long double y, int *quo)
+{
+	union ldshape ux = {x}, uy = {y};
+	int ex = ux.i.se & 0x7fff;
+	int ey = uy.i.se & 0x7fff;
+	int sx = ux.i.se >> 15;
+	int sy = uy.i.se >> 15;
+	uint32_t q;
+
+	*quo = 0;
+	if (y == 0 || isnan(y) || ex == 0x7fff)
+		return (x*y)/(x*y);
+	if (x == 0)
+		return x;
+
+	/* normalize x and y */
+	if (!ex) {
+		ux.i.se = ex;
+		ux.f *= 0x1p120f;
+		ex = ux.i.se - 120;
+	}
+	if (!ey) {
+		uy.i.se = ey;
+		uy.f *= 0x1p120f;
+		ey = uy.i.se - 120;
+	}
+
+	q = 0;
+	if (ex >= ey) {
+		/* x mod y */
+#if LDBL_MANT_DIG == 64
+		uint64_t i, mx, my;
+		mx = ux.i.m;
+		my = uy.i.m;
+		for (; ex > ey; ex--) {
+			i = mx - my;
+			if (mx >= my) {
+				mx = 2*i;
+				q++;
+				q <<= 1;
+			} else if (2*mx < mx) {
+				mx = 2*mx - my;
+				q <<= 1;
+				q++;
+			} else {
+				mx = 2*mx;
+				q <<= 1;
+			}
+		}
+		i = mx - my;
+		if (mx >= my) {
+			mx = i;
+			q++;
+		}
+		if (mx == 0)
+			ex = -120;
+		else
+			for (; mx >> 63 == 0; mx *= 2, ex--);
+		ux.i.m = mx;
+#elif LDBL_MANT_DIG == 113
+		uint64_t hi, lo, xhi, xlo, yhi, ylo;
+		xhi = (ux.i2.hi & -1ULL>>16) | 1ULL<<48;
+		yhi = (uy.i2.hi & -1ULL>>16) | 1ULL<<48;
+		xlo = ux.i2.lo;
+		ylo = ux.i2.lo;
+		for (; ex > ey; ex--) {
+			hi = xhi - yhi;
+			lo = xlo - ylo;
+			if (xlo < ylo)
+				hi -= 1;
+			if (hi >> 63 == 0) {
+				xhi = 2*hi + (lo>>63);
+				xlo = 2*lo;
+				q++;
+			} else {
+				xhi = 2*xhi + (xlo>>63);
+				xlo = 2*xlo;
+			}
+			q <<= 1;
+		}
+		hi = xhi - yhi;
+		lo = xlo - ylo;
+		if (xlo < ylo)
+			hi -= 1;
+		if (hi >> 63 == 0) {
+			xhi = hi;
+			xlo = lo;
+			q++;
+		}
+		if ((xhi|xlo) == 0)
+			ex = -120;
+		else
+			for (; xhi >> 48 == 0; xhi = 2*xhi + (xlo>>63), xlo = 2*xlo, ex--);
+		ux.i2.hi = xhi;
+		ux.i2.lo = xlo;
+#endif
+	}
+
+	/* scale result and decide between |x| and |x|-|y| */
+	if (ex <= 0) {
+		ux.i.se = ex + 120;
+		ux.f *= 0x1p-120f;
+	} else
+		ux.i.se = ex;
+	x = ux.f;
+	if (sy)
+		y = -y;
+	if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {
+		x -= y;
+		q++;
+	}
+	q &= 0x7fffffff;
+	*quo = sx^sy ? -(int)q : (int)q;
+	return sx ? -x : x;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/rint.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/rint.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/rint.c	(revision 398)
@@ -0,0 +1,28 @@
+#include <float.h>
+#include <math.h>
+#include <stdint.h>
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const double_t toint = 1/EPS;
+
+double rint(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i>>52 & 0x7ff;
+	int s = u.i>>63;
+	double_t y;
+
+	if (e >= 0x3ff+52)
+		return x;
+	if (s)
+		y = x - toint + toint;
+	else
+		y = x + toint - toint;
+	if (y == 0)
+		return s ? -0.0 : 0;
+	return y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/rintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/rintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/rintf.c	(revision 398)
@@ -0,0 +1,30 @@
+#include <float.h>
+#include <math.h>
+#include <stdint.h>
+
+#if FLT_EVAL_METHOD==0
+#define EPS FLT_EPSILON
+#elif FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const float_t toint = 1/EPS;
+
+float rintf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = u.i>>23 & 0xff;
+	int s = u.i>>31;
+	float_t y;
+
+	if (e >= 0x7f+23)
+		return x;
+	if (s)
+		y = x - toint + toint;
+	else
+		y = x + toint - toint;
+	if (y == 0)
+		return s ? -0.0f : 0.0f;
+	return y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/rintl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/rintl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/rintl.c	(revision 398)
@@ -0,0 +1,29 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double rintl(long double x)
+{
+	return rint(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double rintl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	int s = u.i.se >> 15;
+	long double y;
+
+	if (e >= 0x3fff+LDBL_MANT_DIG-1)
+		return x;
+	if (s)
+		y = x - toint + toint;
+	else
+		y = x + toint - toint;
+	if (y == 0)
+		return 0*x;
+	return y;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/round.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/round.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/round.c	(revision 398)
@@ -0,0 +1,35 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const double_t toint = 1/EPS;
+
+double round(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i >> 52 & 0x7ff;
+	double_t y;
+
+	if (e >= 0x3ff+52)
+		return x;
+	if (u.i >> 63)
+		x = -x;
+	if (e < 0x3ff-1) {
+		/* raise inexact if x!=0 */
+		FORCE_EVAL(x + toint);
+		return 0*u.f;
+	}
+	y = x + toint - toint - x;
+	if (y > 0.5)
+		y = y + x - 1;
+	else if (y <= -0.5)
+		y = y + x + 1;
+	else
+		y = y + x;
+	if (u.i >> 63)
+		y = -y;
+	return y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/roundf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/roundf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/roundf.c	(revision 398)
@@ -0,0 +1,36 @@
+#include "libm.h"
+
+#if FLT_EVAL_METHOD==0
+#define EPS FLT_EPSILON
+#elif FLT_EVAL_METHOD==1
+#define EPS DBL_EPSILON
+#elif FLT_EVAL_METHOD==2
+#define EPS LDBL_EPSILON
+#endif
+static const float_t toint = 1/EPS;
+
+float roundf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = u.i >> 23 & 0xff;
+	float_t y;
+
+	if (e >= 0x7f+23)
+		return x;
+	if (u.i >> 31)
+		x = -x;
+	if (e < 0x7f-1) {
+		FORCE_EVAL(x + toint);
+		return 0*u.f;
+	}
+	y = x + toint - toint - x;
+	if (y > 0.5f)
+		y = y + x - 1;
+	else if (y <= -0.5f)
+		y = y + x + 1;
+	else
+		y = y + x;
+	if (u.i >> 31)
+		y = -y;
+	return y;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/roundl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/roundl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/roundl.c	(revision 398)
@@ -0,0 +1,37 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double roundl(long double x)
+{
+	return round(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double roundl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	long double y;
+
+	if (e >= 0x3fff+LDBL_MANT_DIG-1)
+		return x;
+	if (u.i.se >> 15)
+		x = -x;
+	if (e < 0x3fff-1) {
+		FORCE_EVAL(x + toint);
+		return 0*u.f;
+	}
+	y = x + toint - toint - x;
+	if (y > 0.5)
+		y = y + x - 1;
+	else if (y <= -0.5)
+		y = y + x + 1;
+	else
+		y = y + x;
+	if (u.i.se >> 15)
+		y = -y;
+	return y;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalb.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalb.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalb.c	(revision 398)
@@ -0,0 +1,35 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_scalb.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/*
+ * scalb(x, fn) is provide for
+ * passing various standard test suite. One
+ * should use scalbn() instead.
+ */
+
+#define _GNU_SOURCE
+#include <math.h>
+
+double scalb(double x, double fn)
+{
+	if (isnan(x) || isnan(fn))
+		return x*fn;
+	if (!isfinite(fn)) {
+		if (fn > 0.0)
+			return x*fn;
+		else
+			return x/(-fn);
+	}
+	if (rint(fn) != fn) return (fn-fn)/(fn-fn);
+	if ( fn > 65000.0) return scalbn(x, 65000);
+	if (-fn > 65000.0) return scalbn(x,-65000);
+	return scalbn(x,(int)fn);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbf.c	(revision 398)
@@ -0,0 +1,32 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_scalbf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include <math.h>
+
+float scalbf(float x, float fn)
+{
+	if (isnan(x) || isnan(fn)) return x*fn;
+	if (!isfinite(fn)) {
+		if (fn > 0.0f)
+			return x*fn;
+		else
+			return x/(-fn);
+	}
+	if (rintf(fn) != fn) return (fn-fn)/(fn-fn);
+	if ( fn > 65000.0f) return scalbnf(x, 65000);
+	if (-fn > 65000.0f) return scalbnf(x,-65000);
+	return scalbnf(x,(int)fn);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbln.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbln.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbln.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <limits.h>
+#include <math.h>
+
+double scalbln(double x, long n)
+{
+	if (n > INT_MAX)
+		n = INT_MAX;
+	else if (n < INT_MIN)
+		n = INT_MIN;
+	return scalbn(x, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalblnf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalblnf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalblnf.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <limits.h>
+#include <math.h>
+
+float scalblnf(float x, long n)
+{
+	if (n > INT_MAX)
+		n = INT_MAX;
+	else if (n < INT_MIN)
+		n = INT_MIN;
+	return scalbnf(x, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalblnl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalblnl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalblnl.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <limits.h>
+#include <math.h>
+#include <float.h>
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double scalblnl(long double x, long n)
+{
+	return scalbln(x, n);
+}
+#else
+long double scalblnl(long double x, long n)
+{
+	if (n > INT_MAX)
+		n = INT_MAX;
+	else if (n < INT_MIN)
+		n = INT_MIN;
+	return scalbnl(x, n);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbn.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbn.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbn.c	(revision 398)
@@ -0,0 +1,33 @@
+#include <math.h>
+#include <stdint.h>
+
+double scalbn(double x, int n)
+{
+	union {double f; uint64_t i;} u;
+	double_t y = x;
+
+	if (n > 1023) {
+		y *= 0x1p1023;
+		n -= 1023;
+		if (n > 1023) {
+			y *= 0x1p1023;
+			n -= 1023;
+			if (n > 1023)
+				n = 1023;
+		}
+	} else if (n < -1022) {
+		/* make sure final n < -53 to avoid double
+		   rounding in the subnormal range */
+		y *= 0x1p-1022 * 0x1p53;
+		n += 1022 - 53;
+		if (n < -1022) {
+			y *= 0x1p-1022 * 0x1p53;
+			n += 1022 - 53;
+			if (n < -1022)
+				n = -1022;
+		}
+	}
+	u.i = (uint64_t)(0x3ff+n)<<52;
+	x = y * u.f;
+	return x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbnf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbnf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbnf.c	(revision 398)
@@ -0,0 +1,31 @@
+#include <math.h>
+#include <stdint.h>
+
+float scalbnf(float x, int n)
+{
+	union {float f; uint32_t i;} u;
+	float_t y = x;
+
+	if (n > 127) {
+		y *= 0x1p127f;
+		n -= 127;
+		if (n > 127) {
+			y *= 0x1p127f;
+			n -= 127;
+			if (n > 127)
+				n = 127;
+		}
+	} else if (n < -126) {
+		y *= 0x1p-126f * 0x1p24f;
+		n += 126 - 24;
+		if (n < -126) {
+			y *= 0x1p-126f * 0x1p24f;
+			n += 126 - 24;
+			if (n < -126)
+				n = -126;
+		}
+	}
+	u.i = (uint32_t)(0x7f+n)<<23;
+	x = y * u.f;
+	return x;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbnl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbnl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/scalbnl.c	(revision 398)
@@ -0,0 +1,36 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double scalbnl(long double x, int n)
+{
+	return scalbn(x, n);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double scalbnl(long double x, int n)
+{
+	union ldshape u;
+
+	if (n > 16383) {
+		x *= 0x1p16383L;
+		n -= 16383;
+		if (n > 16383) {
+			x *= 0x1p16383L;
+			n -= 16383;
+			if (n > 16383)
+				n = 16383;
+		}
+	} else if (n < -16382) {
+		x *= 0x1p-16382L * 0x1p113L;
+		n += 16382 - 113;
+		if (n < -16382) {
+			x *= 0x1p-16382L * 0x1p113L;
+			n += 16382 - 113;
+			if (n < -16382)
+				n = -16382;
+		}
+	}
+	u.f = 1.0;
+	u.i.se = 0x3fff + n;
+	return x * u.f;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/signgam.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/signgam.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/signgam.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+#include "libc.h"
+
+int __signgam = 0;
+
+weak_alias(__signgam, signgam);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/significand.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/significand.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/significand.c	(revision 398)
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <math.h>
+
+double significand(double x)
+{
+	return scalbn(x, -ilogb(x));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/significandf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/significandf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/significandf.c	(revision 398)
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <math.h>
+
+float significandf(float x)
+{
+	return scalbnf(x, -ilogbf(x));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sin.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sin.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sin.c	(revision 398)
@@ -0,0 +1,78 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* sin(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ *      __sin            ... sine function on [-pi/4,pi/4]
+ *      __cos            ... cose function on [-pi/4,pi/4]
+ *      __rem_pio2       ... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on
+ *      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ *      in [-pi/4 , +pi/4], and let n = k mod 4.
+ *      We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *          0          S           C             T
+ *          1          C          -S            -1/T
+ *          2         -S          -C             T
+ *          3         -C           S            -1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *      TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "libm.h"
+
+double sin(double x)
+{
+	double y[2];
+	uint32_t ix;
+	unsigned n;
+
+	/* High word of x. */
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+
+	/* |x| ~< pi/4 */
+	if (ix <= 0x3fe921fb) {
+		if (ix < 0x3e500000) {  /* |x| < 2**-26 */
+			/* raise inexact if x != 0 and underflow if subnormal*/
+			FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
+			return x;
+		}
+		return __sin(x, 0.0, 0);
+	}
+
+	/* sin(Inf or NaN) is NaN */
+	if (ix >= 0x7ff00000)
+		return x - x;
+
+	/* argument reduction needed */
+	n = __rem_pio2(x, y);
+	switch (n&3) {
+	case 0: return  __sin(y[0], y[1], 1);
+	case 1: return  __cos(y[0], y[1]);
+	case 2: return -__sin(y[0], y[1], 1);
+	default:
+		return -__cos(y[0], y[1]);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sincos.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sincos.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sincos.c	(revision 398)
@@ -0,0 +1,69 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+void sincos(double x, double *sin, double *cos)
+{
+	double y[2], s, c;
+	uint32_t ix;
+	unsigned n;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+
+	/* |x| ~< pi/4 */
+	if (ix <= 0x3fe921fb) {
+		/* if |x| < 2**-27 * sqrt(2) */
+		if (ix < 0x3e46a09e) {
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
+			*sin = x;
+			*cos = 1.0;
+			return;
+		}
+		*sin = __sin(x, 0.0, 0);
+		*cos = __cos(x, 0.0);
+		return;
+	}
+
+	/* sincos(Inf or NaN) is NaN */
+	if (ix >= 0x7ff00000) {
+		*sin = *cos = x - x;
+		return;
+	}
+
+	/* argument reduction needed */
+	n = __rem_pio2(x, y);
+	s = __sin(y[0], y[1], 1);
+	c = __cos(y[0], y[1]);
+	switch (n&3) {
+	case 0:
+		*sin = s;
+		*cos = c;
+		break;
+	case 1:
+		*sin = c;
+		*cos = -s;
+		break;
+	case 2:
+		*sin = -s;
+		*cos = -c;
+		break;
+	case 3:
+	default:
+		*sin = -c;
+		*cos = s;
+		break;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sincosf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sincosf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sincosf.c	(revision 398)
@@ -0,0 +1,117 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#define _GNU_SOURCE
+#include "libm.h"
+
+/* Small multiples of pi/2 rounded to double precision. */
+static const double
+s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
+s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
+s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
+s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
+
+void sincosf(float x, float *sin, float *cos)
+{
+	double y;
+	float_t s, c;
+	uint32_t ix;
+	unsigned n, sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix >> 31;
+	ix &= 0x7fffffff;
+
+	/* |x| ~<= pi/4 */
+	if (ix <= 0x3f490fda) {
+		/* |x| < 2**-12 */
+		if (ix < 0x39800000) {
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
+			*sin = x;
+			*cos = 1.0f;
+			return;
+		}
+		*sin = __sindf(x);
+		*cos = __cosdf(x);
+		return;
+	}
+
+	/* |x| ~<= 5*pi/4 */
+	if (ix <= 0x407b53d1) {
+		if (ix <= 0x4016cbe3) {  /* |x| ~<= 3pi/4 */
+			if (sign) {
+				*sin = -__cosdf(x + s1pio2);
+				*cos = __sindf(x + s1pio2);
+			} else {
+				*sin = __cosdf(s1pio2 - x);
+				*cos = __sindf(s1pio2 - x);
+			}
+			return;
+		}
+		/* -sin(x+c) is not correct if x+c could be 0: -0 vs +0 */
+		*sin = -__sindf(sign ? x + s2pio2 : x - s2pio2);
+		*cos = -__cosdf(sign ? x + s2pio2 : x - s2pio2);
+		return;
+	}
+
+	/* |x| ~<= 9*pi/4 */
+	if (ix <= 0x40e231d5) {
+		if (ix <= 0x40afeddf) {  /* |x| ~<= 7*pi/4 */
+			if (sign) {
+				*sin = __cosdf(x + s3pio2);
+				*cos = -__sindf(x + s3pio2);
+			} else {
+				*sin = -__cosdf(x - s3pio2);
+				*cos = __sindf(x - s3pio2);
+			}
+			return;
+		}
+		*sin = __sindf(sign ? x + s4pio2 : x - s4pio2);
+		*cos = __cosdf(sign ? x + s4pio2 : x - s4pio2);
+		return;
+	}
+
+	/* sin(Inf or NaN) is NaN */
+	if (ix >= 0x7f800000) {
+		*sin = *cos = x - x;
+		return;
+	}
+
+	/* general argument reduction needed */
+	n = __rem_pio2f(x, &y);
+	s = __sindf(y);
+	c = __cosdf(y);
+	switch (n&3) {
+	case 0:
+		*sin = s;
+		*cos = c;
+		break;
+	case 1:
+		*sin = c;
+		*cos = -s;
+		break;
+	case 2:
+		*sin = -s;
+		*cos = -c;
+		break;
+	case 3:
+	default:
+		*sin = -c;
+		*cos = s;
+		break;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sincosl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sincosl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sincosl.c	(revision 398)
@@ -0,0 +1,60 @@
+#define _GNU_SOURCE
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+void sincosl(long double x, long double *sin, long double *cos)
+{
+	double sind, cosd;
+	sincos(x, &sind, &cosd);
+	*sin = sind;
+	*cos = cosd;
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+void sincosl(long double x, long double *sin, long double *cos)
+{
+	union ldshape u = {x};
+	unsigned n;
+	long double y[2], s, c;
+
+	u.i.se &= 0x7fff;
+	if (u.i.se == 0x7fff) {
+		*sin = *cos = x - x;
+		return;
+	}
+	if (u.f < M_PI_4) {
+		if (u.i.se < 0x3fff - LDBL_MANT_DIG) {
+			/* raise underflow if subnormal */
+			if (u.i.se == 0) FORCE_EVAL(x*0x1p-120f);
+			*sin = x;
+			/* raise inexact if x!=0 */
+			*cos = 1.0 + x;
+			return;
+		}
+		*sin = __sinl(x, 0, 0);
+		*cos = __cosl(x, 0);
+		return;
+	}
+	n = __rem_pio2l(x, y);
+	s = __sinl(y[0], y[1], 1);
+	c = __cosl(y[0], y[1]);
+	switch (n & 3) {
+	case 0:
+		*sin = s;
+		*cos = c;
+		break;
+	case 1:
+		*sin = c;
+		*cos = -s;
+		break;
+	case 2:
+		*sin = -s;
+		*cos = -c;
+		break;
+	case 3:
+	default:
+		*sin = -c;
+		*cos = s;
+		break;
+	}
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinf.c	(revision 398)
@@ -0,0 +1,76 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+/* Small multiples of pi/2 rounded to double precision. */
+static const double
+s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
+s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
+s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
+s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
+
+float sinf(float x)
+{
+	double y;
+	uint32_t ix;
+	int n, sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix >> 31;
+	ix &= 0x7fffffff;
+
+	if (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */
+		if (ix < 0x39800000) {  /* |x| < 2**-12 */
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);
+			return x;
+		}
+		return __sindf(x);
+	}
+	if (ix <= 0x407b53d1) {  /* |x| ~<= 5*pi/4 */
+		if (ix <= 0x4016cbe3) {  /* |x| ~<= 3pi/4 */
+			if (sign)
+				return -__cosdf(x + s1pio2);
+			else
+				return __cosdf(x - s1pio2);
+		}
+		return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2));
+	}
+	if (ix <= 0x40e231d5) {  /* |x| ~<= 9*pi/4 */
+		if (ix <= 0x40afeddf) {  /* |x| ~<= 7*pi/4 */
+			if (sign)
+				return __cosdf(x + s3pio2);
+			else
+				return -__cosdf(x - s3pio2);
+		}
+		return __sindf(sign ? x + s4pio2 : x - s4pio2);
+	}
+
+	/* sin(Inf or NaN) is NaN */
+	if (ix >= 0x7f800000)
+		return x - x;
+
+	/* general argument reduction needed */
+	n = __rem_pio2f(x, &y);
+	switch (n&3) {
+	case 0: return  __sindf(y);
+	case 1: return  __cosdf(y);
+	case 2: return  __sindf(-y);
+	default:
+		return -__cosdf(y);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinh.c	(revision 398)
@@ -0,0 +1,39 @@
+#include "libm.h"
+
+/* sinh(x) = (exp(x) - 1/exp(x))/2
+ *         = (exp(x)-1 + (exp(x)-1)/exp(x))/2
+ *         = x + x^3/6 + o(x^5)
+ */
+double sinh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	uint32_t w;
+	double t, h, absx;
+
+	h = 0.5;
+	if (u.i >> 63)
+		h = -h;
+	/* |x| */
+	u.i &= (uint64_t)-1/2;
+	absx = u.f;
+	w = u.i >> 32;
+
+	/* |x| < log(DBL_MAX) */
+	if (w < 0x40862e42) {
+		t = expm1(absx);
+		if (w < 0x3ff00000) {
+			if (w < 0x3ff00000 - (26<<20))
+				/* note: inexact and underflow are raised by expm1 */
+				/* note: this branch avoids spurious underflow */
+				return x;
+			return h*(2*t - t*t/(t+1));
+		}
+		/* note: |x|>log(0x1p26)+eps could be just h*exp(x) */
+		return h*(t + t/(t+1));
+	}
+
+	/* |x| > log(DBL_MAX) or nan */
+	/* note: the result is stored to handle overflow */
+	t = 2*h*__expo2(absx);
+	return t;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinhf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinhf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinhf.c	(revision 398)
@@ -0,0 +1,31 @@
+#include "libm.h"
+
+float sinhf(float x)
+{
+	union {float f; uint32_t i;} u = {.f = x};
+	uint32_t w;
+	float t, h, absx;
+
+	h = 0.5;
+	if (u.i >> 31)
+		h = -h;
+	/* |x| */
+	u.i &= 0x7fffffff;
+	absx = u.f;
+	w = u.i;
+
+	/* |x| < log(FLT_MAX) */
+	if (w < 0x42b17217) {
+		t = expm1f(absx);
+		if (w < 0x3f800000) {
+			if (w < 0x3f800000 - (12<<23))
+				return x;
+			return h*(2*t - t*t/(t+1));
+		}
+		return h*(t + t/(t+1));
+	}
+
+	/* |x| > logf(FLT_MAX) or nan */
+	t = 2*h*__expo2f(absx);
+	return t;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinhl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinhl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinhl.c	(revision 398)
@@ -0,0 +1,43 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double sinhl(long double x)
+{
+	return sinh(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+long double sinhl(long double x)
+{
+	union ldshape u = {x};
+	unsigned ex = u.i.se & 0x7fff;
+	long double h, t, absx;
+
+	h = 0.5;
+	if (u.i.se & 0x8000)
+		h = -h;
+	/* |x| */
+	u.i.se = ex;
+	absx = u.f;
+
+	/* |x| < log(LDBL_MAX) */
+	if (ex < 0x3fff+13 || (ex == 0x3fff+13 && u.i.m>>32 < 0xb17217f7)) {
+		t = expm1l(absx);
+		if (ex < 0x3fff) {
+			if (ex < 0x3fff-32)
+				return x;
+			return h*(2*t - t*t/(1+t));
+		}
+		return h*(t + t/(t+1));
+	}
+
+	/* |x| > log(LDBL_MAX) or nan */
+	t = expl(0.5*absx);
+	return h*t*t;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double sinhl(long double x)
+{
+	return sinh(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sinl.c	(revision 398)
@@ -0,0 +1,41 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double sinl(long double x)
+{
+	return sin(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double sinl(long double x)
+{
+	union ldshape u = {x};
+	unsigned n;
+	long double y[2], hi, lo;
+
+	u.i.se &= 0x7fff;
+	if (u.i.se == 0x7fff)
+		return x - x;
+	if (u.f < M_PI_4) {
+		if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);
+			return x;
+		}
+		return __sinl(x, 0.0, 0);
+	}
+	n = __rem_pio2l(x, y);
+	hi = y[0];
+	lo = y[1];
+	switch (n & 3) {
+	case 0:
+		return __sinl(hi, lo, 1);
+	case 1:
+		return __cosl(hi, lo);
+	case 2:
+		return -__sinl(hi, lo, 1);
+	case 3:
+	default:
+		return -__cosl(hi, lo);
+	}
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sqrt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sqrt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sqrt.c	(revision 398)
@@ -0,0 +1,185 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrt.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* sqrt(x)
+ * Return correctly rounded sqrt.
+ *           ------------------------------------------
+ *           |  Use the hardware sqrt if you have one |
+ *           ------------------------------------------
+ * Method:
+ *   Bit by bit method using integer arithmetic. (Slow, but portable)
+ *   1. Normalization
+ *      Scale x to y in [1,4) with even powers of 2:
+ *      find an integer k such that  1 <= (y=x*2^(2k)) < 4, then
+ *              sqrt(x) = 2^k * sqrt(y)
+ *   2. Bit by bit computation
+ *      Let q  = sqrt(y) truncated to i bit after binary point (q = 1),
+ *           i                                                   0
+ *                                     i+1         2
+ *          s  = 2*q , and      y  =  2   * ( y - q  ).         (1)
+ *           i      i            i                 i
+ *
+ *      To compute q    from q , one checks whether
+ *                  i+1       i
+ *
+ *                            -(i+1) 2
+ *                      (q + 2      ) <= y.                     (2)
+ *                        i
+ *                                                            -(i+1)
+ *      If (2) is false, then q   = q ; otherwise q   = q  + 2      .
+ *                             i+1   i             i+1   i
+ *
+ *      With some algebric manipulation, it is not difficult to see
+ *      that (2) is equivalent to
+ *                             -(i+1)
+ *                      s  +  2       <= y                      (3)
+ *                       i                i
+ *
+ *      The advantage of (3) is that s  and y  can be computed by
+ *                                    i      i
+ *      the following recurrence formula:
+ *          if (3) is false
+ *
+ *          s     =  s  ,       y    = y   ;                    (4)
+ *           i+1      i          i+1    i
+ *
+ *          otherwise,
+ *                         -i                     -(i+1)
+ *          s     =  s  + 2  ,  y    = y  -  s  - 2             (5)
+ *           i+1      i          i+1    i     i
+ *
+ *      One may easily use induction to prove (4) and (5).
+ *      Note. Since the left hand side of (3) contain only i+2 bits,
+ *            it does not necessary to do a full (53-bit) comparison
+ *            in (3).
+ *   3. Final rounding
+ *      After generating the 53 bits result, we compute one more bit.
+ *      Together with the remainder, we can decide whether the
+ *      result is exact, bigger than 1/2ulp, or less than 1/2ulp
+ *      (it will never equal to 1/2ulp).
+ *      The rounding mode can be detected by checking whether
+ *      huge + tiny is equal to huge, and whether huge - tiny is
+ *      equal to huge for some floating point number "huge" and "tiny".
+ *
+ * Special cases:
+ *      sqrt(+-0) = +-0         ... exact
+ *      sqrt(inf) = inf
+ *      sqrt(-ve) = NaN         ... with invalid signal
+ *      sqrt(NaN) = NaN         ... with invalid signal for signaling NaN
+ */
+
+#include "libm.h"
+
+static const double tiny = 1.0e-300;
+
+double sqrt(double x)
+{
+	double z;
+	int32_t sign = (int)0x80000000;
+	int32_t ix0,s0,q,m,t,i;
+	uint32_t r,t1,s1,ix1,q1;
+
+	EXTRACT_WORDS(ix0, ix1, x);
+
+	/* take care of Inf and NaN */
+	if ((ix0&0x7ff00000) == 0x7ff00000) {
+		return x*x + x;  /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
+	}
+	/* take care of zero */
+	if (ix0 <= 0) {
+		if (((ix0&~sign)|ix1) == 0)
+			return x;  /* sqrt(+-0) = +-0 */
+		if (ix0 < 0)
+			return (x-x)/(x-x);  /* sqrt(-ve) = sNaN */
+	}
+	/* normalize x */
+	m = ix0>>20;
+	if (m == 0) {  /* subnormal x */
+		while (ix0 == 0) {
+			m -= 21;
+			ix0 |= (ix1>>11);
+			ix1 <<= 21;
+		}
+		for (i=0; (ix0&0x00100000) == 0; i++)
+			ix0<<=1;
+		m -= i - 1;
+		ix0 |= ix1>>(32-i);
+		ix1 <<= i;
+	}
+	m -= 1023;    /* unbias exponent */
+	ix0 = (ix0&0x000fffff)|0x00100000;
+	if (m & 1) {  /* odd m, double x to make it even */
+		ix0 += ix0 + ((ix1&sign)>>31);
+		ix1 += ix1;
+	}
+	m >>= 1;      /* m = [m/2] */
+
+	/* generate sqrt(x) bit by bit */
+	ix0 += ix0 + ((ix1&sign)>>31);
+	ix1 += ix1;
+	q = q1 = s0 = s1 = 0;  /* [q,q1] = sqrt(x) */
+	r = 0x00200000;        /* r = moving bit from right to left */
+
+	while (r != 0) {
+		t = s0 + r;
+		if (t <= ix0) {
+			s0   = t + r;
+			ix0 -= t;
+			q   += r;
+		}
+		ix0 += ix0 + ((ix1&sign)>>31);
+		ix1 += ix1;
+		r >>= 1;
+	}
+
+	r = sign;
+	while (r != 0) {
+		t1 = s1 + r;
+		t  = s0;
+		if (t < ix0 || (t == ix0 && t1 <= ix1)) {
+			s1 = t1 + r;
+			if ((t1&sign) == sign && (s1&sign) == 0)
+				s0++;
+			ix0 -= t;
+			if (ix1 < t1)
+				ix0--;
+			ix1 -= t1;
+			q1 += r;
+		}
+		ix0 += ix0 + ((ix1&sign)>>31);
+		ix1 += ix1;
+		r >>= 1;
+	}
+
+	/* use floating add to find out rounding direction */
+	if ((ix0|ix1) != 0) {
+		z = 1.0 - tiny; /* raise inexact flag */
+		if (z >= 1.0) {
+			z = 1.0 + tiny;
+			if (q1 == (uint32_t)0xffffffff) {
+				q1 = 0;
+				q++;
+			} else if (z > 1.0) {
+				if (q1 == (uint32_t)0xfffffffe)
+					q++;
+				q1 += 2;
+			} else
+				q1 += q1 & 1;
+		}
+	}
+	ix0 = (q>>1) + 0x3fe00000;
+	ix1 = q1>>1;
+	if (q&1)
+		ix1 |= sign;
+	ix0 += m << 20;
+	INSERT_WORDS(z, ix0, ix1);
+	return z;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sqrtf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sqrtf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sqrtf.c	(revision 398)
@@ -0,0 +1,84 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrtf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+static const float tiny = 1.0e-30;
+
+float sqrtf(float x)
+{
+	float z;
+	int32_t sign = (int)0x80000000;
+	int32_t ix,s,q,m,t,i;
+	uint32_t r;
+
+	GET_FLOAT_WORD(ix, x);
+
+	/* take care of Inf and NaN */
+	if ((ix&0x7f800000) == 0x7f800000)
+		return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
+
+	/* take care of zero */
+	if (ix <= 0) {
+		if ((ix&~sign) == 0)
+			return x;  /* sqrt(+-0) = +-0 */
+		if (ix < 0)
+			return (x-x)/(x-x);  /* sqrt(-ve) = sNaN */
+	}
+	/* normalize x */
+	m = ix>>23;
+	if (m == 0) {  /* subnormal x */
+		for (i = 0; (ix&0x00800000) == 0; i++)
+			ix<<=1;
+		m -= i - 1;
+	}
+	m -= 127;  /* unbias exponent */
+	ix = (ix&0x007fffff)|0x00800000;
+	if (m&1)  /* odd m, double x to make it even */
+		ix += ix;
+	m >>= 1;  /* m = [m/2] */
+
+	/* generate sqrt(x) bit by bit */
+	ix += ix;
+	q = s = 0;       /* q = sqrt(x) */
+	r = 0x01000000;  /* r = moving bit from right to left */
+
+	while (r != 0) {
+		t = s + r;
+		if (t <= ix) {
+			s = t+r;
+			ix -= t;
+			q += r;
+		}
+		ix += ix;
+		r >>= 1;
+	}
+
+	/* use floating add to find out rounding direction */
+	if (ix != 0) {
+		z = 1.0f - tiny; /* raise inexact flag */
+		if (z >= 1.0f) {
+			z = 1.0f + tiny;
+			if (z > 1.0f)
+				q += 2;
+			else
+				q += q & 1;
+		}
+	}
+	ix = (q>>1) + 0x3f000000;
+	ix += m << 23;
+	SET_FLOAT_WORD(z, ix);
+	return z;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sqrtl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sqrtl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/sqrtl.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <math.h>
+
+long double sqrtl(long double x)
+{
+	/* FIXME: implement in C, this is for LDBL_MANT_DIG == 64 only */
+	return sqrt(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tan.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tan.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tan.c	(revision 398)
@@ -0,0 +1,70 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_tan.c */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+/* tan(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ *      __tan           ... tangent function on [-pi/4,pi/4]
+ *      __rem_pio2      ... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on
+ *      [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ *      in [-pi/4 , +pi/4], and let n = k mod 4.
+ *      We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *          0          S           C             T
+ *          1          C          -S            -1/T
+ *          2         -S          -C             T
+ *          3         -C           S            -1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *      TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "libm.h"
+
+double tan(double x)
+{
+	double y[2];
+	uint32_t ix;
+	unsigned n;
+
+	GET_HIGH_WORD(ix, x);
+	ix &= 0x7fffffff;
+
+	/* |x| ~< pi/4 */
+	if (ix <= 0x3fe921fb) {
+		if (ix < 0x3e400000) { /* |x| < 2**-27 */
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
+			return x;
+		}
+		return __tan(x, 0.0, 0);
+	}
+
+	/* tan(Inf or NaN) is NaN */
+	if (ix >= 0x7ff00000)
+		return x - x;
+
+	/* argument reduction */
+	n = __rem_pio2(x, y);
+	return __tan(y[0], y[1], n&1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanf.c	(revision 398)
@@ -0,0 +1,64 @@
+/* origin: FreeBSD /usr/src/lib/msun/src/s_tanf.c */
+/*
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ * Optimized by Bruce D. Evans.
+ */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "libm.h"
+
+/* Small multiples of pi/2 rounded to double precision. */
+static const double
+t1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
+t2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
+t3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
+t4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
+
+float tanf(float x)
+{
+	double y;
+	uint32_t ix;
+	unsigned n, sign;
+
+	GET_FLOAT_WORD(ix, x);
+	sign = ix >> 31;
+	ix &= 0x7fffffff;
+
+	if (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */
+		if (ix < 0x39800000) {  /* |x| < 2**-12 */
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);
+			return x;
+		}
+		return __tandf(x, 0);
+	}
+	if (ix <= 0x407b53d1) {  /* |x| ~<= 5*pi/4 */
+		if (ix <= 0x4016cbe3)  /* |x| ~<= 3pi/4 */
+			return __tandf((sign ? x+t1pio2 : x-t1pio2), 1);
+		else
+			return __tandf((sign ? x+t2pio2 : x-t2pio2), 0);
+	}
+	if (ix <= 0x40e231d5) {  /* |x| ~<= 9*pi/4 */
+		if (ix <= 0x40afeddf)  /* |x| ~<= 7*pi/4 */
+			return __tandf((sign ? x+t3pio2 : x-t3pio2), 1);
+		else
+			return __tandf((sign ? x+t4pio2 : x-t4pio2), 0);
+	}
+
+	/* tan(Inf or NaN) is NaN */
+	if (ix >= 0x7f800000)
+		return x - x;
+
+	/* argument reduction */
+	n = __rem_pio2f(x, &y);
+	return __tandf(y, n&1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanh.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanh.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanh.c	(revision 398)
@@ -0,0 +1,45 @@
+#include "libm.h"
+
+/* tanh(x) = (exp(x) - exp(-x))/(exp(x) + exp(-x))
+ *         = (exp(2*x) - 1)/(exp(2*x) - 1 + 2)
+ *         = (1 - exp(-2*x))/(exp(-2*x) - 1 + 2)
+ */
+double tanh(double x)
+{
+	union {double f; uint64_t i;} u = {.f = x};
+	uint32_t w;
+	int sign;
+	double_t t;
+
+	/* x = |x| */
+	sign = u.i >> 63;
+	u.i &= (uint64_t)-1/2;
+	x = u.f;
+	w = u.i >> 32;
+
+	if (w > 0x3fe193ea) {
+		/* |x| > log(3)/2 ~= 0.5493 or nan */
+		if (w > 0x40340000) {
+			/* |x| > 20 or nan */
+			/* note: this branch avoids raising overflow */
+			t = 1 - 0/x;
+		} else {
+			t = expm1(2*x);
+			t = 1 - 2/(t+2);
+		}
+	} else if (w > 0x3fd058ae) {
+		/* |x| > log(5/3)/2 ~= 0.2554 */
+		t = expm1(2*x);
+		t = t/(t+2);
+	} else if (w >= 0x00100000) {
+		/* |x| >= 0x1p-1022, up to 2ulp error in [0.1,0.2554] */
+		t = expm1(-2*x);
+		t = -t/(t+2);
+	} else {
+		/* |x| is subnormal */
+		/* note: the branch above would not raise underflow in [0x1p-1023,0x1p-1022) */
+		FORCE_EVAL((float)x);
+		t = x;
+	}
+	return sign ? -t : t;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanhf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanhf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanhf.c	(revision 398)
@@ -0,0 +1,39 @@
+#include "libm.h"
+
+float tanhf(float x)
+{
+	union {float f; uint32_t i;} u = {.f = x};
+	uint32_t w;
+	int sign;
+	float t;
+
+	/* x = |x| */
+	sign = u.i >> 31;
+	u.i &= 0x7fffffff;
+	x = u.f;
+	w = u.i;
+
+	if (w > 0x3f0c9f54) {
+		/* |x| > log(3)/2 ~= 0.5493 or nan */
+		if (w > 0x41200000) {
+			/* |x| > 10 */
+			t = 1 + 0/x;
+		} else {
+			t = expm1f(2*x);
+			t = 1 - 2/(t+2);
+		}
+	} else if (w > 0x3e82c578) {
+		/* |x| > log(5/3)/2 ~= 0.2554 */
+		t = expm1f(2*x);
+		t = t/(t+2);
+	} else if (w >= 0x00800000) {
+		/* |x| >= 0x1p-126 */
+		t = expm1f(-2*x);
+		t = -t/(t+2);
+	} else {
+		/* |x| is subnormal */
+		FORCE_EVAL(x*x);
+		t = x;
+	}
+	return sign ? -t : t;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanhl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanhl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanhl.c	(revision 398)
@@ -0,0 +1,48 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double tanhl(long double x)
+{
+	return tanh(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+long double tanhl(long double x)
+{
+	union ldshape u = {x};
+	unsigned ex = u.i.se & 0x7fff;
+	unsigned sign = u.i.se & 0x8000;
+	uint32_t w;
+	long double t;
+
+	/* x = |x| */
+	u.i.se = ex;
+	x = u.f;
+	w = u.i.m >> 32;
+
+	if (ex > 0x3ffe || (ex == 0x3ffe && w > 0x8c9f53d5)) {
+		/* |x| > log(3)/2 ~= 0.5493 or nan */
+		if (ex >= 0x3fff+5) {
+			/* |x| >= 32 */
+			t = 1 + 0/(x + 0x1p-120f);
+		} else {
+			t = expm1l(2*x);
+			t = 1 - 2/(t+2);
+		}
+	} else if (ex > 0x3ffd || (ex == 0x3ffd && w > 0x82c577d4)) {
+		/* |x| > log(5/3)/2 ~= 0.2554 */
+		t = expm1l(2*x);
+		t = t/(t+2);
+	} else {
+		/* |x| is small */
+		t = expm1l(-2*x);
+		t = -t/(t+2);
+	}
+	return sign ? -t : t;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double tanhl(long double x)
+{
+	return tanh(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tanl.c	(revision 398)
@@ -0,0 +1,29 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double tanl(long double x)
+{
+	return tan(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double tanl(long double x)
+{
+	union ldshape u = {x};
+	long double y[2];
+	unsigned n;
+
+	u.i.se &= 0x7fff;
+	if (u.i.se == 0x7fff)
+		return x - x;
+	if (u.f < M_PI_4) {
+		if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {
+			/* raise inexact if x!=0 and underflow if subnormal */
+			FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);
+			return x;
+		}
+		return __tanl(x, 0, 0);
+	}
+	n = __rem_pio2l(x, y);
+	return __tanl(y[0], y[1], n&1);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tgamma.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tgamma.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tgamma.c	(revision 398)
@@ -0,0 +1,222 @@
+/*
+"A Precision Approximation of the Gamma Function" - Cornelius Lanczos (1964)
+"Lanczos Implementation of the Gamma Function" - Paul Godfrey (2001)
+"An Analysis of the Lanczos Gamma Approximation" - Glendon Ralph Pugh (2004)
+
+approximation method:
+
+                        (x - 0.5)         S(x)
+Gamma(x) = (x + g - 0.5)         *  ----------------
+                                    exp(x + g - 0.5)
+
+with
+                 a1      a2      a3            aN
+S(x) ~= [ a0 + ----- + ----- + ----- + ... + ----- ]
+               x + 1   x + 2   x + 3         x + N
+
+with a0, a1, a2, a3,.. aN constants which depend on g.
+
+for x < 0 the following reflection formula is used:
+
+Gamma(x)*Gamma(-x) = -pi/(x sin(pi x))
+
+most ideas and constants are from boost and python
+*/
+#include "libm.h"
+
+static const double pi = 3.141592653589793238462643383279502884;
+
+/* sin(pi x) with x > 0x1p-100, if sin(pi*x)==0 the sign is arbitrary */
+static double sinpi(double x)
+{
+	int n;
+
+	/* argument reduction: x = |x| mod 2 */
+	/* spurious inexact when x is odd int */
+	x = x * 0.5;
+	x = 2 * (x - floor(x));
+
+	/* reduce x into [-.25,.25] */
+	n = 4 * x;
+	n = (n+1)/2;
+	x -= n * 0.5;
+
+	x *= pi;
+	switch (n) {
+	default: /* case 4 */
+	case 0:
+		return __sin(x, 0, 0);
+	case 1:
+		return __cos(x, 0);
+	case 2:
+		return __sin(-x, 0, 0);
+	case 3:
+		return -__cos(x, 0);
+	}
+}
+
+#define N 12
+//static const double g = 6.024680040776729583740234375;
+static const double gmhalf = 5.524680040776729583740234375;
+static const double Snum[N+1] = {
+	23531376880.410759688572007674451636754734846804940,
+	42919803642.649098768957899047001988850926355848959,
+	35711959237.355668049440185451547166705960488635843,
+	17921034426.037209699919755754458931112671403265390,
+	6039542586.3520280050642916443072979210699388420708,
+	1439720407.3117216736632230727949123939715485786772,
+	248874557.86205415651146038641322942321632125127801,
+	31426415.585400194380614231628318205362874684987640,
+	2876370.6289353724412254090516208496135991145378768,
+	186056.26539522349504029498971604569928220784236328,
+	8071.6720023658162106380029022722506138218516325024,
+	210.82427775157934587250973392071336271166969580291,
+	2.5066282746310002701649081771338373386264310793408,
+};
+static const double Sden[N+1] = {
+	0, 39916800, 120543840, 150917976, 105258076, 45995730, 13339535,
+	2637558, 357423, 32670, 1925, 66, 1,
+};
+/* n! for small integer n */
+static const double fact[] = {
+	1, 1, 2, 6, 24, 120, 720, 5040.0, 40320.0, 362880.0, 3628800.0, 39916800.0,
+	479001600.0, 6227020800.0, 87178291200.0, 1307674368000.0, 20922789888000.0,
+	355687428096000.0, 6402373705728000.0, 121645100408832000.0,
+	2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0,
+};
+
+/* S(x) rational function for positive x */
+static double S(double x)
+{
+	double_t num = 0, den = 0;
+	int i;
+
+	/* to avoid overflow handle large x differently */
+	if (x < 8)
+		for (i = N; i >= 0; i--) {
+			num = num * x + Snum[i];
+			den = den * x + Sden[i];
+		}
+	else
+		for (i = 0; i <= N; i++) {
+			num = num / x + Snum[i];
+			den = den / x + Sden[i];
+		}
+	return num/den;
+}
+
+double tgamma(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	double absx, y;
+	double_t dy, z, r;
+	uint32_t ix = u.i>>32 & 0x7fffffff;
+	int sign = u.i>>63;
+
+	/* special cases */
+	if (ix >= 0x7ff00000)
+		/* tgamma(nan)=nan, tgamma(inf)=inf, tgamma(-inf)=nan with invalid */
+		return x + INFINITY;
+	if (ix < (0x3ff-54)<<20)
+		/* |x| < 2^-54: tgamma(x) ~ 1/x, +-0 raises div-by-zero */
+		return 1/x;
+
+	/* integer arguments */
+	/* raise inexact when non-integer */
+	if (x == floor(x)) {
+		if (sign)
+			return 0/0.0;
+		if (x <= sizeof fact/sizeof *fact)
+			return fact[(int)x - 1];
+	}
+
+	/* x >= 172: tgamma(x)=inf with overflow */
+	/* x =< -184: tgamma(x)=+-0 with underflow */
+	if (ix >= 0x40670000) { /* |x| >= 184 */
+		if (sign) {
+			FORCE_EVAL((float)(0x1p-126/x));
+			if (floor(x) * 0.5 == floor(x * 0.5))
+				return 0;
+			return -0.0;
+		}
+		x *= 0x1p1023;
+		return x;
+	}
+
+	absx = sign ? -x : x;
+
+	/* handle the error of x + g - 0.5 */
+	y = absx + gmhalf;
+	if (absx > gmhalf) {
+		dy = y - absx;
+		dy -= gmhalf;
+	} else {
+		dy = y - gmhalf;
+		dy -= absx;
+	}
+
+	z = absx - 0.5;
+	r = S(absx) * exp(-y);
+	if (x < 0) {
+		/* reflection formula for negative x */
+		/* sinpi(absx) is not 0, integers are already handled */
+		r = -pi / (sinpi(absx) * absx * r);
+		dy = -dy;
+		z = -z;
+	}
+	r += dy * (gmhalf+0.5) * r / y;
+	z = pow(y, 0.5*z);
+	y = r * z * z;
+	return y;
+}
+
+#if 0
+double __lgamma_r(double x, int *sign)
+{
+	double r, absx;
+
+	*sign = 1;
+
+	/* special cases */
+	if (!isfinite(x))
+		/* lgamma(nan)=nan, lgamma(+-inf)=inf */
+		return x*x;
+
+	/* integer arguments */
+	if (x == floor(x) && x <= 2) {
+		/* n <= 0: lgamma(n)=inf with divbyzero */
+		/* n == 1,2: lgamma(n)=0 */
+		if (x <= 0)
+			return 1/0.0;
+		return 0;
+	}
+
+	absx = fabs(x);
+
+	/* lgamma(x) ~ -log(|x|) for tiny |x| */
+	if (absx < 0x1p-54) {
+		*sign = 1 - 2*!!signbit(x);
+		return -log(absx);
+	}
+
+	/* use tgamma for smaller |x| */
+	if (absx < 128) {
+		x = tgamma(x);
+		*sign = 1 - 2*!!signbit(x);
+		return log(fabs(x));
+	}
+
+	/* second term (log(S)-g) could be more precise here.. */
+	/* or with stirling: (|x|-0.5)*(log(|x|)-1) + poly(1/|x|) */
+	r = (absx-0.5)*(log(absx+gmhalf)-1) + (log(S(absx)) - (gmhalf+0.5));
+	if (x < 0) {
+		/* reflection formula for negative x */
+		x = sinpi(absx);
+		*sign = 2*!!signbit(x) - 1;
+		r = log(pi/(fabs(x)*absx)) - r;
+	}
+	return r;
+}
+
+weak_alias(__lgamma_r, lgamma_r);
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tgammaf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tgammaf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tgammaf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <math.h>
+
+float tgammaf(float x)
+{
+	return tgamma(x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tgammal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tgammal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/tgammal.c	(revision 398)
@@ -0,0 +1,281 @@
+/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_tgammal.c */
+/*
+ * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+/*
+ *      Gamma function
+ *
+ *
+ * SYNOPSIS:
+ *
+ * long double x, y, tgammal();
+ *
+ * y = tgammal( x );
+ *
+ *
+ * DESCRIPTION:
+ *
+ * Returns gamma function of the argument.  The result is
+ * correctly signed.
+ *
+ * Arguments |x| <= 13 are reduced by recurrence and the function
+ * approximated by a rational function of degree 7/8 in the
+ * interval (2,3).  Large arguments are handled by Stirling's
+ * formula. Large negative arguments are made positive using
+ * a reflection formula.
+ *
+ *
+ * ACCURACY:
+ *
+ *                      Relative error:
+ * arithmetic   domain     # trials      peak         rms
+ *    IEEE     -40,+40      10000       3.6e-19     7.9e-20
+ *    IEEE    -1755,+1755   10000       4.8e-18     6.5e-19
+ *
+ * Accuracy for large arguments is dominated by error in powl().
+ *
+ */
+
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double tgammal(long double x)
+{
+	return tgamma(x);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+/*
+tgamma(x+2) = tgamma(x+2) P(x)/Q(x)
+0 <= x <= 1
+Relative error
+n=7, d=8
+Peak error =  1.83e-20
+Relative error spread =  8.4e-23
+*/
+static const long double P[8] = {
+ 4.212760487471622013093E-5L,
+ 4.542931960608009155600E-4L,
+ 4.092666828394035500949E-3L,
+ 2.385363243461108252554E-2L,
+ 1.113062816019361559013E-1L,
+ 3.629515436640239168939E-1L,
+ 8.378004301573126728826E-1L,
+ 1.000000000000000000009E0L,
+};
+static const long double Q[9] = {
+-1.397148517476170440917E-5L,
+ 2.346584059160635244282E-4L,
+-1.237799246653152231188E-3L,
+-7.955933682494738320586E-4L,
+ 2.773706565840072979165E-2L,
+-4.633887671244534213831E-2L,
+-2.243510905670329164562E-1L,
+ 4.150160950588455434583E-1L,
+ 9.999999999999999999908E-1L,
+};
+
+/*
+static const long double P[] = {
+-3.01525602666895735709e0L,
+-3.25157411956062339893e1L,
+-2.92929976820724030353e2L,
+-1.70730828800510297666e3L,
+-7.96667499622741999770e3L,
+-2.59780216007146401957e4L,
+-5.99650230220855581642e4L,
+-7.15743521530849602425e4L
+};
+static const long double Q[] = {
+ 1.00000000000000000000e0L,
+-1.67955233807178858919e1L,
+ 8.85946791747759881659e1L,
+ 5.69440799097468430177e1L,
+-1.98526250512761318471e3L,
+ 3.31667508019495079814e3L,
+ 1.60577839621734713377e4L,
+-2.97045081369399940529e4L,
+-7.15743521530849602412e4L
+};
+*/
+#define MAXGAML 1755.455L
+/*static const long double LOGPI = 1.14472988584940017414L;*/
+
+/* Stirling's formula for the gamma function
+tgamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x))
+z(x) = x
+13 <= x <= 1024
+Relative error
+n=8, d=0
+Peak error =  9.44e-21
+Relative error spread =  8.8e-4
+*/
+static const long double STIR[9] = {
+ 7.147391378143610789273E-4L,
+-2.363848809501759061727E-5L,
+-5.950237554056330156018E-4L,
+ 6.989332260623193171870E-5L,
+ 7.840334842744753003862E-4L,
+-2.294719747873185405699E-4L,
+-2.681327161876304418288E-3L,
+ 3.472222222230075327854E-3L,
+ 8.333333333333331800504E-2L,
+};
+
+#define MAXSTIR 1024.0L
+static const long double SQTPI = 2.50662827463100050242E0L;
+
+/* 1/tgamma(x) = z P(z)
+ * z(x) = 1/x
+ * 0 < x < 0.03125
+ * Peak relative error 4.2e-23
+ */
+static const long double S[9] = {
+-1.193945051381510095614E-3L,
+ 7.220599478036909672331E-3L,
+-9.622023360406271645744E-3L,
+-4.219773360705915470089E-2L,
+ 1.665386113720805206758E-1L,
+-4.200263503403344054473E-2L,
+-6.558780715202540684668E-1L,
+ 5.772156649015328608253E-1L,
+ 1.000000000000000000000E0L,
+};
+
+/* 1/tgamma(-x) = z P(z)
+ * z(x) = 1/x
+ * 0 < x < 0.03125
+ * Peak relative error 5.16e-23
+ * Relative error spread =  2.5e-24
+ */
+static const long double SN[9] = {
+ 1.133374167243894382010E-3L,
+ 7.220837261893170325704E-3L,
+ 9.621911155035976733706E-3L,
+-4.219773343731191721664E-2L,
+-1.665386113944413519335E-1L,
+-4.200263503402112910504E-2L,
+ 6.558780715202536547116E-1L,
+ 5.772156649015328608727E-1L,
+-1.000000000000000000000E0L,
+};
+
+static const long double PIL = 3.1415926535897932384626L;
+
+/* Gamma function computed by Stirling's formula.
+ */
+static long double stirf(long double x)
+{
+	long double y, w, v;
+
+	w = 1.0/x;
+	/* For large x, use rational coefficients from the analytical expansion.  */
+	if (x > 1024.0)
+		w = (((((6.97281375836585777429E-5L * w
+		 + 7.84039221720066627474E-4L) * w
+		 - 2.29472093621399176955E-4L) * w
+		 - 2.68132716049382716049E-3L) * w
+		 + 3.47222222222222222222E-3L) * w
+		 + 8.33333333333333333333E-2L) * w
+		 + 1.0;
+	else
+		w = 1.0 + w * __polevll(w, STIR, 8);
+	y = expl(x);
+	if (x > MAXSTIR) { /* Avoid overflow in pow() */
+		v = powl(x, 0.5L * x - 0.25L);
+		y = v * (v / y);
+	} else {
+		y = powl(x, x - 0.5L) / y;
+	}
+	y = SQTPI * y * w;
+	return y;
+}
+
+long double tgammal(long double x)
+{
+	long double p, q, z;
+
+	if (!isfinite(x))
+		return x + INFINITY;
+
+	q = fabsl(x);
+	if (q > 13.0) {
+		if (x < 0.0) {
+			p = floorl(q);
+			z = q - p;
+			if (z == 0)
+				return 0 / z;
+			if (q > MAXGAML) {
+				z = 0;
+			} else {
+				if (z > 0.5) {
+					p += 1.0;
+					z = q - p;
+				}
+				z = q * sinl(PIL * z);
+				z = fabsl(z) * stirf(q);
+				z = PIL/z;
+			}
+			if (0.5 * p == floorl(q * 0.5))
+				z = -z;
+		} else if (x > MAXGAML) {
+			z = x * 0x1p16383L;
+		} else {
+			z = stirf(x);
+		}
+		return z;
+	}
+
+	z = 1.0;
+	while (x >= 3.0) {
+		x -= 1.0;
+		z *= x;
+	}
+	while (x < -0.03125L) {
+		z /= x;
+		x += 1.0;
+	}
+	if (x <= 0.03125L)
+		goto small;
+	while (x < 2.0) {
+		z /= x;
+		x += 1.0;
+	}
+	if (x == 2.0)
+		return z;
+
+	x -= 2.0;
+	p = __polevll(x, P, 7);
+	q = __polevll(x, Q, 8);
+	z = z * p / q;
+	return z;
+
+small:
+	/* z==1 if x was originally +-0 */
+	if (x == 0 && z != 1)
+		return x / x;
+	if (x < 0.0) {
+		x = -x;
+		q = z / (x * __polevll(x, SN, 8));
+	} else
+		q = z / (x * __polevll(x, S, 8));
+	return q;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+// TODO: broken implementation to make things compile
+long double tgammal(long double x)
+{
+	return tgamma(x);
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/trunc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/trunc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/trunc.c	(revision 398)
@@ -0,0 +1,19 @@
+#include "libm.h"
+
+double trunc(double x)
+{
+	union {double f; uint64_t i;} u = {x};
+	int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12;
+	uint64_t m;
+
+	if (e >= 52 + 12)
+		return x;
+	if (e < 12)
+		e = 1;
+	m = -1ULL >> e;
+	if ((u.i & m) == 0)
+		return x;
+	FORCE_EVAL(x + 0x1p120f);
+	u.i &= ~m;
+	return u.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/truncf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/truncf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/truncf.c	(revision 398)
@@ -0,0 +1,19 @@
+#include "libm.h"
+
+float truncf(float x)
+{
+	union {float f; uint32_t i;} u = {x};
+	int e = (int)(u.i >> 23 & 0xff) - 0x7f + 9;
+	uint32_t m;
+
+	if (e >= 23 + 9)
+		return x;
+	if (e < 9)
+		e = 1;
+	m = -1U >> e;
+	if ((u.i & m) == 0)
+		return x;
+	FORCE_EVAL(x + 0x1p120f);
+	u.i &= ~m;
+	return u.f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/truncl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/truncl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/math/truncl.c	(revision 398)
@@ -0,0 +1,34 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double truncl(long double x)
+{
+	return trunc(x);
+}
+#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+
+static const long double toint = 1/LDBL_EPSILON;
+
+long double truncl(long double x)
+{
+	union ldshape u = {x};
+	int e = u.i.se & 0x7fff;
+	int s = u.i.se >> 15;
+	long double y;
+
+	if (e >= 0x3fff+LDBL_MANT_DIG-1)
+		return x;
+	if (e <= 0x3fff-1) {
+		FORCE_EVAL(x + 0x1p120f);
+		return x*0;
+	}
+	/* y = int(|x|) - |x|, where int(|x|) is an integer neighbor of |x| */
+	if (s)
+		x = -x;
+	y = x + toint - toint - x;
+	if (y > 0)
+		y -= 1;
+	x += y;
+	return s ? -x : x;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/a64l.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/a64l.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/a64l.c	(revision 398)
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+static const char digits[] =
+	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+long a64l(const char *s)
+{
+	int e;
+	uint32_t x = 0;
+	for (e=0; e<36 && *s; e+=6, s++) {
+		const char *d = strchr(digits, *s);
+		if (!d) break;
+		x |= (uint32_t)(d-digits)<<e;
+	}
+	return (int32_t)x;
+}
+
+char *l64a(long x0)
+{
+	static char s[7];
+	char *p;
+	uint32_t x = x0;
+	for (p=s; x; p++, x>>=6)
+		*p = digits[x&63];
+	*p = 0;
+	return s;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/basename.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/basename.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/basename.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <string.h>
+#include <libgen.h>
+#include "libc.h"
+
+char *basename(char *s)
+{
+	size_t i;
+	if (!s || !*s) return ".";
+	i = strlen(s)-1;
+	for (; i&&s[i]=='/'; i--) s[i] = 0;
+	for (; i&&s[i-1]!='/'; i--);
+	return s+i;
+}
+
+weak_alias(basename, __xpg_basename);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/dirname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/dirname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/dirname.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <string.h>
+#include <libgen.h>
+
+char *dirname(char *s)
+{
+	size_t i;
+	if (!s || !*s) return ".";
+	i = strlen(s)-1;
+	for (; s[i]=='/'; i--) if (!i) return "/";
+	for (; s[i]!='/'; i--) if (!i) return ".";
+	for (; s[i]=='/'; i--) if (!i) return "/";
+	s[i+1] = 0;
+	return s;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ffs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ffs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ffs.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <strings.h>
+#include "atomic.h"
+
+int ffs(int i)
+{
+	return i ? a_ctz_l(i)+1 : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ffsl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ffsl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ffsl.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <strings.h>
+#include "atomic.h"
+
+int ffsl(long i)
+{
+	return i ? a_ctz_l(i)+1 : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ffsll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ffsll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ffsll.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <strings.h>
+#include "atomic.h"
+
+int ffsll(long long i)
+{
+	return i ? a_ctz_64(i)+1 : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/fmtmsg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/fmtmsg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/fmtmsg.c	(revision 398)
@@ -0,0 +1,90 @@
+/* Public domain fmtmsg()
+ * Written by Isaac Dunham, 2014
+ */
+#include <fmtmsg.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+/*
+ * If lstr is the first part of bstr, check that the next char in bstr
+ * is either \0 or :
+ */
+static int _strcolcmp(const char *lstr, const char *bstr)
+{
+	size_t i = 0;
+	while (lstr[i] && bstr[i] && (bstr[i] == lstr[i])) i++;
+	if ( lstr[i] || (bstr[i] && bstr[i] != ':')) return 1;
+	return 0;
+}
+
+int fmtmsg(long classification, const char *label, int severity,
+           const char *text, const char *action, const char *tag)
+{
+	int ret = 0, i, consolefd, verb = 0;
+	char *errstring = MM_NULLSEV, *cmsg = getenv("MSGVERB");
+	char *const msgs[] = {
+		"label", "severity", "text", "action", "tag", NULL
+	};
+	int cs;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	if (severity == MM_HALT) errstring = "HALT: ";
+	else if (severity == MM_ERROR) errstring = "ERROR: ";
+	else if (severity == MM_WARNING) errstring = "WARNING: ";
+	else if (severity == MM_INFO) errstring = "INFO: ";
+
+	if (classification & MM_CONSOLE) {
+		consolefd = open("/dev/console", O_WRONLY);
+		if (consolefd < 0) {
+			ret = MM_NOCON;
+		} else {
+			if (dprintf(consolefd, "%s%s%s%s%s%s%s%s\n",
+			            label?label:"", label?": ":"",
+			            severity?errstring:"", text?text:"",
+			            action?"\nTO FIX: ":"",
+			            action?action:"", action?" ":"",
+			            tag?tag:"" )<1)
+				ret = MM_NOCON;
+			close(consolefd);
+		}
+	}
+
+	if (classification & MM_PRINT) {
+		while (cmsg && cmsg[0]) {
+			for(i=0; msgs[i]; i++) {
+				if (!_strcolcmp(msgs[i], cmsg)) break;
+			}
+			if (msgs[i] == NULL) {
+				//ignore MSGVERB-unrecognized component
+				verb = 0xFF;
+				break;
+			} else {
+				verb |= (1 << i);
+				cmsg = strchr(cmsg, ':');
+				if (cmsg) cmsg++;
+			}
+		}
+		if (!verb) verb = 0xFF;
+		if (dprintf(2, "%s%s%s%s%s%s%s%s\n",
+		            (verb&1 && label) ? label : "",
+		            (verb&1 && label) ? ": " : "",
+		            (verb&2 && severity) ? errstring : "",
+		            (verb&4 && text) ? text : "",
+		            (verb&8 && action) ? "\nTO FIX: " : "",
+		            (verb&8 && action) ? action : "",
+		            (verb&8 && action) ? " " : "",
+		            (verb&16 && tag) ? tag : "" ) < 1)
+			ret |= MM_NOMSG;
+	}
+	if ((ret & (MM_NOCON|MM_NOMSG)) == (MM_NOCON|MM_NOMSG))
+		ret = MM_NOTOK;
+
+	pthread_setcancelstate(cs, 0);
+
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/forkpty.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/forkpty.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/forkpty.c	(revision 398)
@@ -0,0 +1,57 @@
+#include <pty.h>
+#include <utmp.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <pthread.h>
+
+int forkpty(int *pm, char *name, const struct termios *tio, const struct winsize *ws)
+{
+	int m, s, ec=0, p[2], cs;
+	pid_t pid=-1;
+	sigset_t set, oldset;
+
+	if (openpty(&m, &s, name, tio, ws) < 0) return -1;
+
+	sigfillset(&set);
+	pthread_sigmask(SIG_BLOCK, &set, &oldset);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	if (pipe2(p, O_CLOEXEC)) {
+		close(s);
+		goto out;
+	}
+
+	pid = fork();
+	if (!pid) {
+		close(m);
+		close(p[0]);
+		if (login_tty(s)) {
+			write(p[1], &errno, sizeof errno);
+			_exit(127);
+		}
+		close(p[1]);
+		pthread_setcancelstate(cs, 0);
+		pthread_sigmask(SIG_SETMASK, &oldset, 0);
+		return 0;
+	}
+	close(s);
+	close(p[1]);
+	if (read(p[0], &ec, sizeof ec) > 0) {
+		int status;
+		waitpid(pid, &status, 0);
+		pid = -1;
+		errno = ec;
+	}
+	close(p[0]);
+
+out:
+	if (pid > 0) *pm = m;
+	else close(m);
+
+	pthread_setcancelstate(cs, 0);
+	pthread_sigmask(SIG_SETMASK, &oldset, 0);
+
+	return pid;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/get_current_dir_name.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/get_current_dir_name.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/get_current_dir_name.c	(revision 398)
@@ -0,0 +1,15 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+char *get_current_dir_name(void) {
+	struct stat a, b;
+	char *res = getenv("PWD");
+	if (res && *res && !stat(res, &a) && !stat(".", &b)
+	    && (a.st_dev == b.st_dev) && (a.st_ino == b.st_ino))
+		return strdup(res);
+	return getcwd(0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getauxval.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getauxval.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getauxval.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <sys/auxv.h>
+#include <errno.h>
+#include "libc.h"
+
+unsigned long getauxval(unsigned long item)
+{
+	size_t *auxv = libc.auxv;
+	if (item == AT_SECURE) return libc.secure;
+	for (; *auxv; auxv+=2)
+		if (*auxv==item) return auxv[1];
+	errno = ENOENT;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getdomainname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getdomainname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getdomainname.c	(revision 398)
@@ -0,0 +1,17 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <string.h>
+#include <errno.h>
+
+int getdomainname(char *name, size_t len)
+{
+	struct utsname temp;
+	uname(&temp);
+	if (!len || strlen(temp.domainname) >= len) {
+		errno = EINVAL;
+		return -1;
+	}
+	strcpy(name, temp.domainname);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/gethostid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/gethostid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/gethostid.c	(revision 398)
@@ -0,0 +1,4 @@
+long gethostid()
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getopt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getopt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getopt.c	(revision 398)
@@ -0,0 +1,104 @@
+#include <unistd.h>
+#include <wchar.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "libc.h"
+#include "locale_impl.h"
+
+char *optarg;
+int optind=1, opterr=1, optopt, __optpos, __optreset=0;
+
+#define optpos __optpos
+weak_alias(__optreset, optreset);
+
+void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
+{
+	FILE *f = stderr;
+	b = __lctrans_cur(b);
+	flockfile(f);
+	fputs(a, f)>=0
+	&& fwrite(b, strlen(b), 1, f)
+	&& fwrite(c, 1, l, f)==l
+	&& putc('\n', f);
+	funlockfile(f);
+}
+
+int getopt(int argc, char * const argv[], const char *optstring)
+{
+	int i;
+	wchar_t c, d;
+	int k, l;
+	char *optchar;
+
+	if (!optind || __optreset) {
+		__optreset = 0;
+		__optpos = 0;
+		optind = 1;
+	}
+
+	if (optind >= argc || !argv[optind])
+		return -1;
+
+	if (argv[optind][0] != '-') {
+		if (optstring[0] == '-') {
+			optarg = argv[optind++];
+			return 1;
+		}
+		return -1;
+	}
+
+	if (!argv[optind][1])
+		return -1;
+
+	if (argv[optind][1] == '-' && !argv[optind][2])
+		return optind++, -1;
+
+	if (!optpos) optpos++;
+	if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
+		k = 1;
+		c = 0xfffd; /* replacement char */
+	}
+	optchar = argv[optind]+optpos;
+	optpos += k;
+
+	if (!argv[optind][optpos]) {
+		optind++;
+		optpos = 0;
+	}
+
+	if (optstring[0] == '-' || optstring[0] == '+')
+		optstring++;
+
+	i = 0;
+	d = 0;
+	do {
+		l = mbtowc(&d, optstring+i, MB_LEN_MAX);
+		if (l>0) i+=l; else i++;
+	} while (l && d != c);
+
+	if (d != c) {
+		optopt = c;
+		if (optstring[0] != ':' && opterr)
+			__getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
+		return '?';
+	}
+	if (optstring[i] == ':') {
+		if (optstring[i+1] == ':') optarg = 0;
+		else if (optind >= argc) {
+			optopt = c;
+			if (optstring[0] == ':') return ':';
+			if (opterr) __getopt_msg(argv[0],
+				": option requires an argument: ",
+				optchar, k);
+			return '?';
+		}
+		if (optstring[i+1] != ':' || optpos) {
+			optarg = argv[optind++] + optpos;
+			optpos = 0;
+		}
+	}
+	return c;
+}
+
+weak_alias(getopt, __posix_getopt);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getopt_long.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getopt_long.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getopt_long.c	(revision 398)
@@ -0,0 +1,133 @@
+#define _GNU_SOURCE
+#include <stddef.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <string.h>
+
+extern int __optpos, __optreset;
+
+static void permute(char *const *argv, int dest, int src)
+{
+	char **av = (char **)argv;
+	char *tmp = av[src];
+	int i;
+	for (i=src; i>dest; i--)
+		av[i] = av[i-1];
+	av[dest] = tmp;
+}
+
+void __getopt_msg(const char *, const char *, const char *, size_t);
+
+static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly);
+
+static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
+{
+	int ret, skipped, resumed;
+	if (!optind || __optreset) {
+		__optreset = 0;
+		__optpos = 0;
+		optind = 1;
+	}
+	if (optind >= argc || !argv[optind]) return -1;
+	skipped = optind;
+	if (optstring[0] != '+' && optstring[0] != '-') {
+		int i;
+		for (i=optind; ; i++) {
+			if (i >= argc || !argv[i]) return -1;
+			if (argv[i][0] == '-' && argv[i][1]) break;
+		}
+		optind = i;
+	}
+	resumed = optind;
+	ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly);
+	if (resumed > skipped) {
+		int i, cnt = optind-resumed;
+		for (i=0; i<cnt; i++)
+			permute(argv, skipped, optind-1);
+		optind = skipped + cnt;
+	}
+	return ret;
+}
+
+static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
+{
+	optarg = 0;
+	if (longopts && argv[optind][0] == '-' &&
+		((longonly && argv[optind][1] && argv[optind][1] != '-') ||
+		 (argv[optind][1] == '-' && argv[optind][2])))
+	{
+		int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':';
+		int i, cnt, match;
+		char *opt;
+		for (cnt=i=0; longopts[i].name; i++) {
+			const char *name = longopts[i].name;
+			opt = argv[optind]+1;
+			if (*opt == '-') opt++;
+			for (; *name && *name == *opt; name++, opt++);
+			if (*opt && *opt != '=') continue;
+			match = i;
+			if (!*name) {
+				cnt = 1;
+				break;
+			}
+			cnt++;
+		}
+		if (cnt==1) {
+			i = match;
+			optind++;
+			if (*opt == '=') {
+				if (!longopts[i].has_arg) {
+					optopt = longopts[i].val;
+					if (colon || !opterr)
+						return '?';
+					__getopt_msg(argv[0],
+						": option does not take an argument: ",
+						longopts[i].name,
+						strlen(longopts[i].name));
+					return '?';
+				}
+				optarg = opt+1;
+			} else if (longopts[i].has_arg == required_argument) {
+				if (!(optarg = argv[optind])) {
+					optopt = longopts[i].val;
+					if (colon) return ':';
+					if (!opterr) return '?';
+					__getopt_msg(argv[0],
+						": option requires an argument: ",
+						longopts[i].name,
+						strlen(longopts[i].name));
+					return '?';
+				}
+				optind++;
+			}
+			if (idx) *idx = i;
+			if (longopts[i].flag) {
+				*longopts[i].flag = longopts[i].val;
+				return 0;
+			}
+			return longopts[i].val;
+		}
+		if (argv[optind][1] == '-') {
+			optopt = 0;
+			if (!colon && opterr)
+				__getopt_msg(argv[0], cnt ?
+					": option is ambiguous: " :
+					": unrecognized option: ",
+					argv[optind]+2,
+					strlen(argv[optind]+2));
+			optind++;
+			return '?';
+		}
+	}
+	return getopt(argc, argv, optstring);
+}
+
+int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
+{
+	return __getopt_long(argc, argv, optstring, longopts, idx, 0);
+}
+
+int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
+{
+	return __getopt_long(argc, argv, optstring, longopts, idx, 1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getpriority.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getpriority.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getpriority.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <sys/resource.h>
+#include "syscall.h"
+
+int getpriority(int which, id_t who)
+{
+	int ret = syscall(SYS_getpriority, which, who);
+	if (ret < 0) return ret;
+	return 20-ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getresgid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getresgid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getresgid.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
+{
+	return syscall(SYS_getresgid, rgid, egid, sgid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getresuid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getresuid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getresuid.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
+{
+	return syscall(SYS_getresuid, ruid, euid, suid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getrlimit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getrlimit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getrlimit.c	(revision 398)
@@ -0,0 +1,27 @@
+#include <sys/resource.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+
+#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
+
+int getrlimit(int resource, struct rlimit *rlim)
+{
+	unsigned long k_rlim[2];
+	int ret = syscall(SYS_prlimit64, 0, resource, 0, rlim);
+	if (!ret) {
+		FIX(rlim->rlim_cur);
+		FIX(rlim->rlim_max);
+	}
+	if (!ret || errno != ENOSYS)
+		return ret;
+	if (syscall(SYS_getrlimit, resource, k_rlim) < 0)
+		return -1;
+	rlim->rlim_cur = k_rlim[0] == -1UL ? RLIM_INFINITY : k_rlim[0];
+	rlim->rlim_max = k_rlim[1] == -1UL ? RLIM_INFINITY : k_rlim[1];
+	FIX(rlim->rlim_cur);
+	FIX(rlim->rlim_max);
+	return 0;
+}
+
+LFS64(getrlimit);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getrusage.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getrusage.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getrusage.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/resource.h>
+#include "syscall.h"
+
+int getrusage(int who, struct rusage *ru)
+{
+	return syscall(SYS_getrusage, who, ru);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getsubopt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getsubopt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/getsubopt.c	(revision 398)
@@ -0,0 +1,23 @@
+#include <stdlib.h>
+#include <string.h>
+
+int getsubopt(char **opt, char *const *keys, char **val)
+{
+	char *s = *opt;
+	int i;
+
+	*val = NULL;
+	*opt = strchr(s, ',');
+	if (*opt) *(*opt)++ = 0;
+	else *opt = s + strlen(s);
+
+	for (i=0; keys[i]; i++) {
+		size_t l = strlen(keys[i]);
+		if (strncmp(keys[i], s, l)) continue;
+		if (s[l] == '=')
+			*val = s + l + 1;
+		else if (s[l]) continue;
+		return i;
+	}
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/initgroups.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/initgroups.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/initgroups.c	(revision 398)
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <grp.h>
+#include <limits.h>
+
+int initgroups(const char *user, gid_t gid)
+{
+	gid_t groups[NGROUPS_MAX];
+	int count = NGROUPS_MAX;
+	if (getgrouplist(user, gid, groups, &count) < 0) return -1;
+	return setgroups(count, groups);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ioctl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ioctl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ioctl.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <sys/ioctl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+int ioctl(int fd, int req, ...)
+{
+	void *arg;
+	va_list ap;
+	va_start(ap, req);
+	arg = va_arg(ap, void *);
+	va_end(ap);
+	return syscall(SYS_ioctl, fd, req, arg);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/issetugid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/issetugid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/issetugid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "libc.h"
+
+int issetugid(void)
+{
+	return libc.secure;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/lockf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/lockf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/lockf.c	(revision 398)
@@ -0,0 +1,33 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "libc.h"
+
+int lockf(int fd, int op, off_t size)
+{
+	struct flock l = {
+		.l_type = F_WRLCK,
+		.l_whence = SEEK_CUR,
+		.l_len = size,
+	};
+	switch (op) {
+	case F_TEST:
+		l.l_type = F_RDLCK;
+		if (fcntl(fd, F_GETLK, &l) < 0)
+			return -1;
+		if (l.l_type == F_UNLCK || l.l_pid == getpid())
+			return 0;
+		errno = EACCES;
+		return -1;
+	case F_ULOCK:
+		l.l_type = F_UNLCK;
+	case F_TLOCK:
+		return fcntl(fd, F_SETLK, &l);
+	case F_LOCK:
+		return fcntl(fd, F_SETLKW, &l);
+	}
+	errno = EINVAL;
+	return -1;
+}
+
+LFS64(lockf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/login_tty.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/login_tty.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/login_tty.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <utmp.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+int login_tty(int fd)
+{
+	setsid();
+	if (ioctl(fd, TIOCSCTTY, (char *)0)) return -1;
+	dup2(fd, 0);
+	dup2(fd, 1);
+	dup2(fd, 2);
+	if (fd>2) close(fd);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/mntent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/mntent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/mntent.c	(revision 398)
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <string.h>
+#include <mntent.h>
+#include <errno.h>
+
+static char *internal_buf;
+static size_t internal_bufsize;
+
+#define SENTINEL (char *)&internal_buf
+
+FILE *setmntent(const char *name, const char *mode)
+{
+	return fopen(name, mode);
+}
+
+int endmntent(FILE *f)
+{
+	if (f) fclose(f);
+	return 1;
+}
+
+struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen)
+{
+	int cnt, n[8], use_internal = (linebuf == SENTINEL);
+
+	mnt->mnt_freq = 0;
+	mnt->mnt_passno = 0;
+
+	do {
+		if (use_internal) {
+			getline(&internal_buf, &internal_bufsize, f);
+			linebuf = internal_buf;
+		} else {
+			fgets(linebuf, buflen, f);
+		}
+		if (feof(f) || ferror(f)) return 0;
+		if (!strchr(linebuf, '\n')) {
+			fscanf(f, "%*[^\n]%*[\n]");
+			errno = ERANGE;
+			return 0;
+		}
+		cnt = sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d",
+			n, n+1, n+2, n+3, n+4, n+5, n+6, n+7,
+			&mnt->mnt_freq, &mnt->mnt_passno);
+	} while (cnt < 2 || linebuf[n[0]] == '#');
+
+	linebuf[n[1]] = 0;
+	linebuf[n[3]] = 0;
+	linebuf[n[5]] = 0;
+	linebuf[n[7]] = 0;
+
+	mnt->mnt_fsname = linebuf+n[0];
+	mnt->mnt_dir = linebuf+n[2];
+	mnt->mnt_type = linebuf+n[4];
+	mnt->mnt_opts = linebuf+n[6];
+
+	return mnt;
+}
+
+struct mntent *getmntent(FILE *f)
+{
+	static struct mntent mnt;
+	return getmntent_r(f, &mnt, SENTINEL, 0);
+}
+
+int addmntent(FILE *f, const struct mntent *mnt)
+{
+	if (fseek(f, 0, SEEK_END)) return 1;
+	return fprintf(f, "%s\t%s\t%s\t%s\t%d\t%d\n",
+		mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts,
+		mnt->mnt_freq, mnt->mnt_passno) < 0;
+}
+
+char *hasmntopt(const struct mntent *mnt, const char *opt)
+{
+	return strstr(mnt->mnt_opts, opt);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/nftw.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/nftw.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/nftw.c	(revision 398)
@@ -0,0 +1,129 @@
+#include <ftw.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <pthread.h>
+#include "libc.h"
+
+struct history
+{
+	struct history *chain;
+	dev_t dev;
+	ino_t ino;
+	int level;
+	int base;
+};
+
+#undef dirfd
+#define dirfd(d) (*(int *)d)
+
+static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags, struct history *h)
+{
+	size_t l = strlen(path), j = l && path[l-1]=='/' ? l-1 : l;
+	struct stat st;
+	struct history new;
+	int type;
+	int r;
+	struct FTW lev;
+
+	if ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) {
+		if (!(flags & FTW_PHYS) && errno==ENOENT && !lstat(path, &st))
+			type = FTW_SLN;
+		else if (errno != EACCES) return -1;
+		else type = FTW_NS;
+	} else if (S_ISDIR(st.st_mode)) {
+		if (access(path, R_OK) < 0) type = FTW_DNR;
+		else if (flags & FTW_DEPTH) type = FTW_DP;
+		else type = FTW_D;
+	} else if (S_ISLNK(st.st_mode)) {
+		if (flags & FTW_PHYS) type = FTW_SL;
+		else type = FTW_SLN;
+	} else {
+		type = FTW_F;
+	}
+
+	if ((flags & FTW_MOUNT) && h && st.st_dev != h->dev)
+		return 0;
+	
+	new.chain = h;
+	new.dev = st.st_dev;
+	new.ino = st.st_ino;
+	new.level = h ? h->level+1 : 0;
+	new.base = j+1;
+	
+	lev.level = new.level;
+	if (h) {
+		lev.base = h->base;
+	} else {
+		size_t k;
+		for (k=j; k && path[k]=='/'; k--);
+		for (; k && path[k-1]!='/'; k--);
+		lev.base = k;
+	}
+
+	if (!(flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev)))
+		return r;
+
+	for (; h; h = h->chain)
+		if (h->dev == st.st_dev && h->ino == st.st_ino)
+			return 0;
+
+	if ((type == FTW_D || type == FTW_DP) && fd_limit) {
+		DIR *d = opendir(path);
+		if (d) {
+			struct dirent *de;
+			while ((de = readdir(d))) {
+				if (de->d_name[0] == '.'
+				 && (!de->d_name[1]
+				  || (de->d_name[1]=='.'
+				   && !de->d_name[2]))) continue;
+				if (strlen(de->d_name) >= PATH_MAX-l) {
+					errno = ENAMETOOLONG;
+					closedir(d);
+					return -1;
+				}
+				path[j]='/';
+				strcpy(path+j+1, de->d_name);
+				if ((r=do_nftw(path, fn, fd_limit-1, flags, &new))) {
+					closedir(d);
+					return r;
+				}
+			}
+			closedir(d);
+		} else if (errno != EACCES) {
+			return -1;
+		}
+	}
+
+	path[l] = 0;
+	if ((flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev)))
+		return r;
+
+	return 0;
+}
+
+int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags)
+{
+	int r, cs;
+	size_t l;
+	char pathbuf[PATH_MAX+1];
+
+	if (fd_limit <= 0) return 0;
+
+	l = strlen(path);
+	if (l > PATH_MAX) {
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+	memcpy(pathbuf, path, l+1);
+	
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	r = do_nftw(pathbuf, fn, fd_limit, flags, NULL);
+	pthread_setcancelstate(cs, 0);
+	return r;
+}
+
+LFS64(nftw);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/openpty.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/openpty.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/openpty.c	(revision 398)
@@ -0,0 +1,40 @@
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pty.h>
+#include <stdio.h>
+#include <pthread.h>
+
+/* Nonstandard, but vastly superior to the standard functions */
+
+int openpty(int *pm, int *ps, char *name, const struct termios *tio, const struct winsize *ws)
+{
+	int m, s, n=0, cs;
+	char buf[20];
+
+	m = open("/dev/ptmx", O_RDWR|O_NOCTTY);
+	if (m < 0) return -1;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	if (ioctl(m, TIOCSPTLCK, &n) || ioctl (m, TIOCGPTN, &n))
+		goto fail;
+
+	if (!name) name = buf;
+	snprintf(name, sizeof buf, "/dev/pts/%d", n);
+	if ((s = open(name, O_RDWR|O_NOCTTY)) < 0)
+		goto fail;
+
+	if (tio) tcsetattr(s, TCSANOW, tio);
+	if (ws) ioctl(s, TIOCSWINSZ, ws);
+
+	*pm = m;
+	*ps = s;
+
+	pthread_setcancelstate(cs, 0);
+	return 0;
+fail:
+	close(m);
+	pthread_setcancelstate(cs, 0);
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ptsname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ptsname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/ptsname.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <errno.h>
+
+int __ptsname_r(int, char *, size_t);
+
+char *ptsname(int fd)
+{
+	static char buf[9 + sizeof(int)*3 + 1];
+	int err = __ptsname_r(fd, buf, sizeof buf);
+	if (err) {
+		errno = err;
+		return 0;
+	}
+	return buf;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/pty.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/pty.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/pty.c	(revision 398)
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "libc.h"
+#include "syscall.h"
+
+int posix_openpt(int flags)
+{
+	return open("/dev/ptmx", flags);
+}
+
+int grantpt(int fd)
+{
+	return 0;
+}
+
+int unlockpt(int fd)
+{
+	int unlock = 0;
+	return ioctl(fd, TIOCSPTLCK, &unlock);
+}
+
+int __ptsname_r(int fd, char *buf, size_t len)
+{
+	int pty, err;
+	if (!buf) len = 0;
+	if ((err = __syscall(SYS_ioctl, fd, TIOCGPTN, &pty))) return -err;
+	if (snprintf(buf, len, "/dev/pts/%d", pty) >= len) return ERANGE;
+	return 0;
+}
+
+weak_alias(__ptsname_r, ptsname_r);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/realpath.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/realpath.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/realpath.c	(revision 398)
@@ -0,0 +1,45 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include "syscall.h"
+
+void __procfdname(char *, unsigned);
+
+char *realpath(const char *restrict filename, char *restrict resolved)
+{
+	int fd;
+	ssize_t r;
+	struct stat st1, st2;
+	char buf[15+3*sizeof(int)];
+	char tmp[PATH_MAX];
+
+	if (!filename) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	fd = sys_open(filename, O_PATH|O_NONBLOCK|O_CLOEXEC);
+	if (fd < 0) return 0;
+	__procfdname(buf, fd);
+
+	r = readlink(buf, tmp, sizeof tmp - 1);
+	if (r < 0) goto err;
+	tmp[r] = 0;
+
+	fstat(fd, &st1);
+	r = stat(tmp, &st2);
+	if (r<0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
+		if (!r) errno = ELOOP;
+		goto err;
+	}
+
+	__syscall(SYS_close, fd);
+	return resolved ? strcpy(resolved, tmp) : strdup(tmp);
+err:
+	__syscall(SYS_close, fd);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/setdomainname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/setdomainname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/setdomainname.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int setdomainname(const char *name, size_t len)
+{
+	return syscall(SYS_setdomainname, name, len);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/setpriority.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/setpriority.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/setpriority.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/resource.h>
+#include "syscall.h"
+
+int setpriority(int which, id_t who, int prio)
+{
+	return syscall(SYS_setpriority, which, who, prio);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/setrlimit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/setrlimit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/setrlimit.c	(revision 398)
@@ -0,0 +1,50 @@
+#include <sys/resource.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+
+#define MIN(a, b) ((a)<(b) ? (a) : (b))
+#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
+
+int __setrlimit(int resource, const struct rlimit *rlim)
+{
+	unsigned long k_rlim[2];
+	struct rlimit tmp;
+	if (SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
+		tmp = *rlim;
+		FIX(tmp.rlim_cur);
+		FIX(tmp.rlim_max);
+		rlim = &tmp;
+	}
+	int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
+	if (ret != -ENOSYS) return ret;
+	k_rlim[0] = MIN(rlim->rlim_cur, MIN(-1UL, SYSCALL_RLIM_INFINITY));
+	k_rlim[1] = MIN(rlim->rlim_max, MIN(-1UL, SYSCALL_RLIM_INFINITY));
+	return __syscall(SYS_setrlimit, resource, k_rlim);
+}
+
+struct ctx {
+	const struct rlimit *rlim;
+	int res;
+	int err;
+};
+
+static void do_setrlimit(void *p)
+{
+	struct ctx *c = p;
+	if (c->err>0) return;
+	c->err = -__setrlimit(c->res, c->rlim);
+}
+
+int setrlimit(int resource, const struct rlimit *rlim)
+{
+	struct ctx c = { .res = resource, .rlim = rlim, .err = -1 };
+	__synccall(do_setrlimit, &c);
+	if (c.err) {
+		if (c.err>0) errno = c.err;
+		return -1;
+	}
+	return 0;
+}
+
+LFS64(setrlimit);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/syscall.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/syscall.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/syscall.c	(revision 398)
@@ -0,0 +1,19 @@
+#include "syscall.h"
+#include <stdarg.h>
+
+#undef syscall
+
+long syscall(long n, ...)
+{
+	va_list ap;
+	syscall_arg_t a,b,c,d,e,f;
+	va_start(ap, n);
+	a=va_arg(ap, syscall_arg_t);
+	b=va_arg(ap, syscall_arg_t);
+	c=va_arg(ap, syscall_arg_t);
+	d=va_arg(ap, syscall_arg_t);
+	e=va_arg(ap, syscall_arg_t);
+	f=va_arg(ap, syscall_arg_t);
+	va_end(ap);
+	return __syscall_ret(__syscall_nr(n,a,b,c,d,e,f));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/syslog.~c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/syslog.~c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/syslog.~c	(revision 398)
@@ -0,0 +1,144 @@
+#include <stdarg.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <time.h>
+#include <signal.h>
+#include <string.h>
+#include <pthread.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "libc.h"
+
+static volatile int lock[2];
+static char log_ident[32];
+static int log_opt;
+static int log_facility = LOG_USER;
+static int log_mask = 0xff;
+static int log_fd = -1;
+
+int setlogmask(int maskpri)
+{
+	LOCK(lock);
+	int ret = log_mask;
+	if (maskpri) log_mask = maskpri;
+	UNLOCK(lock);
+	return ret;
+}
+
+static const struct {
+	short sun_family;
+	char sun_path[9];
+} log_addr = {
+	AF_UNIX,
+	"/dev/log"
+};
+
+void closelog(void)
+{
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	LOCK(lock);
+	close(log_fd);
+	log_fd = -1;
+	UNLOCK(lock);
+	pthread_setcancelstate(cs, 0);
+}
+
+static void __openlog()
+{
+	log_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+	if (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr);
+}
+
+void openlog(const char *ident, int opt, int facility)
+{
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	LOCK(lock);
+
+	if (ident) {
+		size_t n = strnlen(ident, sizeof log_ident - 1);
+		memcpy(log_ident, ident, n);
+		log_ident[n] = 0;
+	} else {
+		log_ident[0] = 0;
+	}
+	log_opt = opt;
+	log_facility = facility;
+
+	if ((opt & LOG_NDELAY) && log_fd<0) __openlog();
+
+	UNLOCK(lock);
+	pthread_setcancelstate(cs, 0);
+}
+
+static int is_lost_conn(int e)
+{
+	return e==ECONNREFUSED || e==ECONNRESET || e==ENOTCONN || e==EPIPE;
+}
+
+static void _vsyslog(int priority, const char *message, va_list ap)
+{
+	char timebuf[16];
+	time_t now;
+	struct tm tm;
+	char buf[1024];
+	int errno_save = errno;
+	int pid;
+	int l, l2;
+	int hlen;
+	int fd;
+
+	if (log_fd < 0) __openlog();
+
+	if (!(priority & LOG_FACMASK)) priority |= log_facility;
+
+	now = time(NULL);
+	gmtime_r(&now, &tm);
+	strftime(timebuf, sizeof timebuf, "%b %e %T", &tm);
+
+	pid = (log_opt & LOG_PID) ? getpid() : 0;
+	l = snprintf(buf, sizeof buf, "<%d>%s %n%s%s%.0d%s: ",
+		priority, timebuf, &hlen, log_ident, "["+!pid, pid, "]"+!pid);
+	errno = errno_save;
+	l2 = vsnprintf(buf+l, sizeof buf - l, message, ap);
+	if (l2 >= 0) {
+		if (l2 >= sizeof buf - l) l = sizeof buf - 1;
+		else l += l2;
+		if (buf[l-1] != '\n') buf[l++] = '\n';
+		if (send(log_fd, buf, l, 0) < 0 && (!is_lost_conn(errno)
+		    || connect(log_fd, (void *)&log_addr, sizeof log_addr) < 0
+		    || send(log_fd, buf, l, 0) < 0)
+		    && (log_opt & LOG_CONS)) {
+			fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+			if (fd >= 0) {
+				dprintf(fd, "%.*s", l-hlen, buf+hlen);
+				close(fd);
+			}
+		}
+		if (log_opt & LOG_PERROR) dprintf(2, "%.*s", l-hlen, buf+hlen);
+	}
+}
+
+void __vsyslog(int priority, const char *message, va_list ap)
+{
+	int cs;
+	if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	LOCK(lock);
+	_vsyslog(priority, message, ap);
+	UNLOCK(lock);
+	pthread_setcancelstate(cs, 0);
+}
+
+void syslog(int priority, const char *message, ...)
+{
+	va_list ap;
+	va_start(ap, message);
+	__vsyslog(priority, message, ap);
+	va_end(ap);
+}
+
+weak_alias(__vsyslog, vsyslog);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/uname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/uname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/uname.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/utsname.h>
+#include "syscall.h"
+
+int uname(struct utsname *uts)
+{
+	return syscall(SYS_uname, uts);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/wordexp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/wordexp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/misc/wordexp.c	(revision 398)
@@ -0,0 +1,193 @@
+#include <wordexp.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "pthread_impl.h"
+
+static void reap(pid_t pid)
+{
+	int status;
+	for (;;) {
+		if (waitpid(pid, &status, 0) < 0) {
+			if (errno != EINTR) return;
+		} else {
+			if (WIFEXITED(status)) return;
+		}
+	}
+}
+
+static char *getword(FILE *f)
+{
+	char *s = 0;
+	return getdelim(&s, (size_t [1]){0}, 0, f) < 0 ? 0 : s;
+}
+
+static int do_wordexp(const char *s, wordexp_t *we, int flags)
+{
+	size_t i, l;
+	int sq=0, dq=0;
+	size_t np=0;
+	char *w, **tmp;
+	char *redir = (flags & WRDE_SHOWERR) ? "" : "2>/dev/null";
+	int err = 0;
+	FILE *f;
+	size_t wc = 0;
+	char **wv = 0;
+	int p[2];
+	pid_t pid;
+	sigset_t set;
+
+	if (flags & WRDE_REUSE) wordfree(we);
+
+	if (flags & WRDE_NOCMD) for (i=0; s[i]; i++) switch (s[i]) {
+	case '\\':
+		if (!sq) i++;
+		break;
+	case '\'':
+		if (!dq) sq^=1;
+		break;
+	case '"':
+		if (!sq) dq^=1;
+		break;
+	case '(':
+		if (np) {
+			np++;
+			break;
+		}
+	case ')':
+		if (np) {
+			np--;
+			break;
+		}
+	case '\n':
+	case '|':
+	case '&':
+	case ';':
+	case '<':
+	case '>':
+	case '{':
+	case '}':
+		if (!(sq|dq|np)) return WRDE_BADCHAR;
+		break;
+	case '$':
+		if (sq) break;
+		if (s[i+1]=='(' && s[i+2]=='(') {
+			i += 2;
+			np += 2;
+			break;
+		} else if (s[i+1] != '(') break;
+	case '`':
+		if (sq) break;
+		return WRDE_CMDSUB;
+	}
+
+	if (flags & WRDE_APPEND) {
+		wc = we->we_wordc;
+		wv = we->we_wordv;
+	}
+
+	i = wc;
+	if (flags & WRDE_DOOFFS) {
+		if (we->we_offs > SIZE_MAX/sizeof(void *)/4)
+			goto nospace;
+		i += we->we_offs;
+	} else {
+		we->we_offs = 0;
+	}
+
+	if (pipe2(p, O_CLOEXEC) < 0) goto nospace;
+	__block_all_sigs(&set);
+	pid = fork();
+	__restore_sigs(&set);
+	if (pid < 0) {
+		close(p[0]);
+		close(p[1]);
+		goto nospace;
+	}
+	if (!pid) {
+		if (p[1] == 1) fcntl(1, F_SETFD, 0);
+		else dup2(p[1], 1);
+		execl("/bin/sh", "sh", "-c",
+			"eval \"printf %s\\\\\\\\0 x $1 $2\"",
+			"sh", s, redir, (char *)0);
+		_exit(1);
+	}
+	close(p[1]);
+	
+	f = fdopen(p[0], "r");
+	if (!f) {
+		close(p[0]);
+		kill(pid, SIGKILL);
+		reap(pid);
+		goto nospace;
+	}
+
+	l = wv ? i+1 : 0;
+
+	free(getword(f));
+	if (feof(f)) {
+		fclose(f);
+		reap(pid);
+		return WRDE_SYNTAX;
+	}
+
+	while ((w = getword(f))) {
+		if (i+1 >= l) {
+			l += l/2+10;
+			tmp = realloc(wv, l*sizeof(char *));
+			if (!tmp) break;
+			wv = tmp;
+		}
+		wv[i++] = w;
+		wv[i] = 0;
+	}
+	if (!feof(f)) err = WRDE_NOSPACE;
+
+	fclose(f);
+	reap(pid);
+
+	if (!wv) wv = calloc(i+1, sizeof *wv);
+
+	we->we_wordv = wv;
+	we->we_wordc = i;
+
+	if (flags & WRDE_DOOFFS) {
+		if (wv) for (i=we->we_offs; i; i--)
+			we->we_wordv[i-1] = 0;
+		we->we_wordc -= we->we_offs;
+	}
+	return err;
+
+nospace:
+	if (!(flags & WRDE_APPEND)) {
+		we->we_wordc = 0;
+		we->we_wordv = 0;
+	}
+	return WRDE_NOSPACE;
+}
+
+int wordexp(const char *restrict s, wordexp_t *restrict we, int flags)
+{
+	int r, cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	r = do_wordexp(s, we, flags);
+	pthread_setcancelstate(cs, 0);
+	return r;
+}
+
+void wordfree(wordexp_t *we)
+{
+	size_t i;
+	if (!we->we_wordv) return;
+	for (i=0; i<we->we_wordc; i++) free(we->we_wordv[we->we_offs+i]);
+	free(we->we_wordv);
+	we->we_wordv = 0;
+	we->we_wordc = 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/madvise.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/madvise.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/madvise.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <sys/mman.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __madvise(void *addr, size_t len, int advice)
+{
+	return syscall(SYS_madvise, addr, len, advice);
+}
+
+weak_alias(__madvise, madvise);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mincore.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mincore.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mincore.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mincore (void *addr, size_t len, unsigned char *vec)
+{
+	return syscall(SYS_mincore, addr, len, vec);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mlock.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mlock(const void *addr, size_t len)
+{
+	return syscall(SYS_mlock, addr, len);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mlockall.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mlockall.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mlockall.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mlockall(int flags)
+{
+	return syscall(SYS_mlockall, flags);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mmap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mmap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mmap.c	(revision 398)
@@ -0,0 +1,42 @@
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdint.h>
+#include <limits.h>
+#include "syscall.h"
+#include "libc.h"
+
+static void dummy(void) { }
+weak_alias(dummy, __vm_wait);
+
+#define UNIT SYSCALL_MMAP2_UNIT
+#define OFF_MASK ((-0x2000ULL << (8*sizeof(syscall_arg_t)-1)) | (UNIT-1))
+
+void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
+{
+	long ret;
+	if (off & OFF_MASK) {
+		errno = EINVAL;
+		return MAP_FAILED;
+	}
+	if (len >= PTRDIFF_MAX) {
+		errno = ENOMEM;
+		return MAP_FAILED;
+	}
+	if (flags & MAP_FIXED) {
+		__vm_wait();
+	}
+#ifdef SYS_mmap2
+	ret = __syscall(SYS_mmap2, start, len, prot, flags, fd, off/UNIT);
+#else
+	ret = __syscall(SYS_mmap, start, len, prot, flags, fd, off);
+#endif
+	/* Fixup incorrect EPERM from kernel. */
+	if (ret == -EPERM && !start && (flags&MAP_ANON) && !(flags&MAP_FIXED))
+		ret = -ENOMEM;
+	return (void *)__syscall_ret(ret);
+}
+
+weak_alias(__mmap, mmap);
+
+LFS64(mmap);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mprotect.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mprotect.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mprotect.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <sys/mman.h>
+#include "libc.h"
+#include "syscall.h"
+
+int __mprotect(void *addr, size_t len, int prot)
+{
+	size_t start, end;
+	start = (size_t)addr & -PAGE_SIZE;
+	end = (size_t)((char *)addr + len + PAGE_SIZE-1) & -PAGE_SIZE;
+	return syscall(SYS_mprotect, start, end-start, prot);
+}
+
+weak_alias(__mprotect, mprotect);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mremap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mremap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/mremap.c	(revision 398)
@@ -0,0 +1,33 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include "syscall.h"
+#include "libc.h"
+
+static void dummy(void) { }
+weak_alias(dummy, __vm_wait);
+
+void *__mremap(void *old_addr, size_t old_len, size_t new_len, int flags, ...)
+{
+	va_list ap;
+	void *new_addr = 0;
+
+	if (new_len >= PTRDIFF_MAX) {
+		errno = ENOMEM;
+		return MAP_FAILED;
+	}
+
+	if (flags & MREMAP_FIXED) {
+		__vm_wait();
+		va_start(ap, flags);
+		new_addr = va_arg(ap, void *);
+		va_end(ap);
+	}
+
+	return (void *)syscall(SYS_mremap, old_addr, old_len, new_len, flags, new_addr);
+}
+
+weak_alias(__mremap, mremap);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/msync.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/msync.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/msync.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int msync(void *start, size_t len, int flags)
+{
+	return syscall_cp(SYS_msync, start, len, flags);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/munlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/munlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/munlock.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int munlock(const void *addr, size_t len)
+{
+	return syscall(SYS_munlock, addr, len);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/munlockall.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/munlockall.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/munlockall.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/mman.h>
+#include "syscall.h"
+
+int munlockall(void)
+{
+	return syscall(SYS_munlockall);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/munmap.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/munmap.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/munmap.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <sys/mman.h>
+#include "syscall.h"
+#include "libc.h"
+
+static void dummy(void) { }
+weak_alias(dummy, __vm_wait);
+
+int __munmap(void *start, size_t len)
+{
+	__vm_wait();
+	return syscall(SYS_munmap, start, len);
+}
+
+weak_alias(__munmap, munmap);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/posix_madvise.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/posix_madvise.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/posix_madvise.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <sys/mman.h>
+#include "syscall.h"
+
+int posix_madvise(void *addr, size_t len, int advice)
+{
+	if (advice == MADV_DONTNEED) return 0;
+	return -__syscall(SYS_madvise, addr, len, advice);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/shm_open.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/shm_open.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mman/shm_open.c	(revision 398)
@@ -0,0 +1,45 @@
+#include <sys/mman.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <pthread.h>
+
+char *__strchrnul(const char *, int);
+
+char *__shm_mapname(const char *name, char *buf)
+{
+	char *p;
+	while (*name == '/') name++;
+	if (*(p = __strchrnul(name, '/')) || p==name ||
+	    (p-name <= 2 && name[0]=='.' && p[-1]=='.')) {
+		errno = EINVAL;
+		return 0;
+	}
+	if (p-name > NAME_MAX) {
+		errno = ENAMETOOLONG;
+		return 0;
+	}
+	memcpy(buf, "/dev/shm/", 9);
+	memcpy(buf+9, name, p-name+1);
+	return buf;
+}
+
+int shm_open(const char *name, int flag, mode_t mode)
+{
+	int cs;
+	char buf[NAME_MAX+10];
+	if (!(name = __shm_mapname(name, buf))) return -1;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	int fd = open(name, flag|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK, mode);
+	pthread_setcancelstate(cs, 0);
+	return fd;
+}
+
+int shm_unlink(const char *name)
+{
+	char buf[NAME_MAX+10];
+	if (!(name = __shm_mapname(name, buf))) return -1;
+	return unlink(name);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_close.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_close.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_close.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_close(mqd_t mqd)
+{
+	return syscall(SYS_close, mqd);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_getattr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_getattr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_getattr.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_getattr(mqd_t mqd, struct mq_attr *attr)
+{
+	return mq_setattr(mqd, 0, attr);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_notify.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_notify.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_notify.c	(revision 398)
@@ -0,0 +1,73 @@
+#include <mqueue.h>
+#include <pthread.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <unistd.h>
+#include "syscall.h"
+
+struct args {
+	pthread_barrier_t barrier;
+	int sock;
+	const struct sigevent *sev;
+};
+
+static void *start(void *p)
+{
+	struct args *args = p;
+	char buf[32];
+	ssize_t n;
+	int s = args->sock;
+	void (*func)(union sigval) = args->sev->sigev_notify_function;
+	union sigval val = args->sev->sigev_value;
+
+	pthread_barrier_wait(&args->barrier);
+	n = recv(s, buf, sizeof(buf), MSG_NOSIGNAL|MSG_WAITALL);
+	close(s);
+	if (n==sizeof buf && buf[sizeof buf - 1] == 1)
+		func(val);
+	return 0;
+}
+
+int mq_notify(mqd_t mqd, const struct sigevent *sev)
+{
+	struct args args = { .sev = sev };
+	pthread_attr_t attr;
+	pthread_t td;
+	int s;
+	struct sigevent sev2;
+	static const char zeros[32];
+
+	if (!sev || sev->sigev_notify != SIGEV_THREAD)
+		return syscall(SYS_mq_notify, mqd, sev);
+
+	s = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, 0);
+	if (s < 0) return -1;
+	args.sock = s;
+
+	if (sev->sigev_notify_attributes) attr = *sev->sigev_notify_attributes;
+	else pthread_attr_init(&attr);
+	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+	pthread_barrier_init(&args.barrier, 0, 2);
+
+	if (pthread_create(&td, &attr, start, &args)) {
+		__syscall(SYS_close, s);
+		errno = EAGAIN;
+		return -1;
+	}
+
+	pthread_barrier_wait(&args.barrier);
+	pthread_barrier_destroy(&args.barrier);
+
+	sev2.sigev_notify = SIGEV_THREAD;
+	sev2.sigev_signo = s;
+	sev2.sigev_value.sival_ptr = (void *)&zeros;
+
+	if (syscall(SYS_mq_notify, mqd, &sev2) < 0) {
+		pthread_cancel(td);
+		__syscall(SYS_close, s);
+		return -1;
+	}
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_open.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_open.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_open.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <mqueue.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+mqd_t mq_open(const char *name, int flags, ...)
+{
+	mode_t mode = 0;
+	struct mq_attr *attr = 0;
+	if (*name == '/') name++;
+	if (flags & O_CREAT) {
+		va_list ap;
+		va_start(ap, flags);
+		mode = va_arg(ap, mode_t);
+		attr = va_arg(ap, struct mq_attr *);
+		va_end(ap);
+	}
+	return syscall(SYS_mq_open, name, flags, mode, attr);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_receive.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_receive.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_receive.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <mqueue.h>
+
+ssize_t mq_receive(mqd_t mqd, char *msg, size_t len, unsigned *prio)
+{
+	return mq_timedreceive(mqd, msg, len, prio, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_send.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_send.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_send.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <mqueue.h>
+
+int mq_send(mqd_t mqd, const char *msg, size_t len, unsigned prio)
+{
+	return mq_timedsend(mqd, msg, len, prio, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_setattr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_setattr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_setattr.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_setattr(mqd_t mqd, const struct mq_attr *restrict new, struct mq_attr *restrict old)
+{
+	return syscall(SYS_mq_getsetattr, mqd, new, old);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_timedreceive.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_timedreceive.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_timedreceive.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+ssize_t mq_timedreceive(mqd_t mqd, char *restrict msg, size_t len, unsigned *restrict prio, const struct timespec *restrict at)
+{
+	return syscall_cp(SYS_mq_timedreceive, mqd, msg, len, prio, at);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_timedsend.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_timedsend.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_timedsend.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_timedsend(mqd_t mqd, const char *msg, size_t len, unsigned prio, const struct timespec *at)
+{
+	return syscall_cp(SYS_mq_timedsend, mqd, msg, len, prio, at);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_unlink.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_unlink.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/mq/mq_unlink.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <mqueue.h>
+#include <errno.h>
+#include "syscall.h"
+
+int mq_unlink(const char *name)
+{
+	int ret;
+	if (*name == '/') name++;
+	ret = __syscall(SYS_mq_unlink, name);
+	if (ret < 0) {
+		if (ret == -EPERM) ret = -EACCES;
+		errno = -ret;
+		return -1;
+	}
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/btowc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/btowc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/btowc.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <wchar.h>
+#include <stdlib.h>
+#include "internal.h"
+
+wint_t btowc(int c)
+{
+	int b = (unsigned char)c;
+	return b<128U ? b : (MB_CUR_MAX==1 && c!=EOF) ? CODEUNIT(c) : WEOF;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/c16rtomb.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/c16rtomb.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/c16rtomb.c	(revision 398)
@@ -0,0 +1,35 @@
+#include <uchar.h>
+#include <errno.h>
+#include <wchar.h>
+
+size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps)
+{
+	static unsigned internal_state;
+	if (!ps) ps = (void *)&internal_state;
+	unsigned *x = (unsigned *)ps;
+	wchar_t wc;
+
+	if (!s) {
+		if (*x) goto ilseq;
+		return 1;
+	}
+
+	if (!*x && c16 - 0xd800u < 0x400) {
+		*x = c16 - 0xd7c0 << 10;
+		return 0;
+	}
+
+	if (*x) {
+		if (c16 - 0xdc00u >= 0x400) goto ilseq;
+		else wc = *x + c16 - 0xdc00;
+		*x = 0;
+	} else {
+		wc = c16;
+	}
+	return wcrtomb(s, wc, 0);
+
+ilseq:
+	*x = 0;
+	errno = EILSEQ;
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/c32rtomb.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/c32rtomb.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/c32rtomb.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <uchar.h>
+#include <wchar.h>
+
+size_t c32rtomb(char *restrict s, char32_t c32, mbstate_t *restrict ps)
+{
+	return wcrtomb(s, c32, ps);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/internal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/internal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/internal.c	(revision 398)
@@ -0,0 +1,26 @@
+#include "internal.h"
+
+#define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) )
+#define D(x) C((x+16))
+#define E(x) ( ( x==0 ? R(0xa0,0xc0) : \
+                 x==0xd ? R(0x80,0xa0) : \
+                 R(0x80,0xc0) ) \
+             | ( R(0x80,0xc0) >> 6 ) \
+             | x )
+#define F(x) ( ( x>=5 ? 0 : \
+                 x==0 ? R(0x90,0xc0) : \
+                 x==4 ? R(0x80,0x90) : \
+                 R(0x80,0xc0) ) \
+             | ( R(0x80,0xc0) >> 6 ) \
+             | ( R(0x80,0xc0) >> 12 ) \
+             | x )
+
+const uint32_t bittab[] = {
+	              C(0x2),C(0x3),C(0x4),C(0x5),C(0x6),C(0x7),
+	C(0x8),C(0x9),C(0xa),C(0xb),C(0xc),C(0xd),C(0xe),C(0xf),
+	D(0x0),D(0x1),D(0x2),D(0x3),D(0x4),D(0x5),D(0x6),D(0x7),
+	D(0x8),D(0x9),D(0xa),D(0xb),D(0xc),D(0xd),D(0xe),D(0xf),
+	E(0x0),E(0x1),E(0x2),E(0x3),E(0x4),E(0x5),E(0x6),E(0x7),
+	E(0x8),E(0x9),E(0xa),E(0xb),E(0xc),E(0xd),E(0xe),E(0xf),
+	F(0x0),F(0x1),F(0x2),F(0x3),F(0x4)
+};
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/internal.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/internal.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/internal.h	(revision 398)
@@ -0,0 +1,26 @@
+#define bittab __fsmu8
+
+#include <stdint.h>
+
+#ifdef __PIC__
+__attribute__((__visibility__("hidden")))
+#endif
+extern const uint32_t bittab[];
+
+/* Upper 6 state bits are a negative integer offset to bound-check next byte */
+/*    equivalent to: ( (b-0x80) | (b+offset) ) & ~0x3f      */
+#define OOB(c,b) (((((b)>>3)-0x10)|(((b)>>3)+((int32_t)(c)>>26))) & ~7)
+
+/* Interval [a,b). Either a must be 80 or b must be c0, lower 3 bits clear. */
+#define R(a,b) ((uint32_t)((a==0x80 ? 0x40u-b : 0u-a) << 23))
+#define FAILSTATE R(0x80,0x80)
+
+#define SA 0xc2u
+#define SB 0xf4u
+
+/* Arbitrary encoding for representing code units instead of characters. */
+#define CODEUNIT(c) (0xdfff & (signed char)(c))
+#define IS_CODEUNIT(c) ((unsigned)(c)-0xdf80 < 0x80)
+
+/* Get inline definition of MB_CUR_MAX. */
+#include "locale_impl.h"
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mblen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mblen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mblen.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+int mblen(const char *s, size_t n)
+{
+	return mbtowc(0, s, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrlen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrlen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrlen.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+size_t mbrlen(const char *restrict s, size_t n, mbstate_t *restrict st)
+{
+	static unsigned internal;
+	return mbrtowc(0, s, n, st ? st : (mbstate_t *)&internal);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrtoc16.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrtoc16.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrtoc16.c	(revision 398)
@@ -0,0 +1,30 @@
+#include <uchar.h>
+#include <wchar.h>
+
+size_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, mbstate_t *restrict ps)
+{
+	static unsigned internal_state;
+	if (!ps) ps = (void *)&internal_state;
+	unsigned *pending = (unsigned *)ps;
+
+	if (!s) return mbrtoc16(0, "", 1, ps);
+
+	/* mbrtowc states for partial UTF-8 characters have the high bit set;
+	 * we use nonzero states without high bit for pending surrogates. */
+	if ((int)*pending > 0) {
+ 		if (pc16) *pc16 = *pending;
+		*pending = 0;
+		return -3;
+	}
+
+	wchar_t wc;
+	size_t ret = mbrtowc(&wc, s, n, ps);
+	if (ret <= 4) {
+		if (wc >= 0x10000) {
+			*pending = (wc & 0x3ff) + 0xdc00;
+			wc = 0xd7c0 + (wc >> 10);
+		}
+		if (pc16) *pc16 = wc;
+	}
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrtoc32.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrtoc32.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrtoc32.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <uchar.h>
+#include <wchar.h>
+
+size_t mbrtoc32(char32_t *restrict pc32, const char *restrict s, size_t n, mbstate_t *restrict ps)
+{
+	static unsigned internal_state;
+	if (!ps) ps = (void *)&internal_state;
+	if (!s) return mbrtoc32(0, "", 1, ps);
+	wchar_t wc;
+	size_t ret = mbrtowc(&wc, s, n, ps);
+	if (ret <= 4 && pc32) *pc32 = wc;
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrtowc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrtowc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbrtowc.c	(revision 398)
@@ -0,0 +1,51 @@
+#include <stdlib.h>
+#include <wchar.h>
+#include <errno.h>
+#include "internal.h"
+
+size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st)
+{
+	static unsigned internal_state;
+	unsigned c;
+	const unsigned char *s = (const void *)src;
+	const unsigned N = n;
+	wchar_t dummy;
+
+	if (!st) st = (void *)&internal_state;
+	c = *(unsigned *)st;
+	
+	if (!s) {
+		if (c) goto ilseq;
+		return 0;
+	} else if (!wc) wc = &dummy;
+
+	if (!n) return -2;
+	if (!c) {
+		if (*s < 0x80) return !!(*wc = *s);
+		if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
+		if (*s-SA > SB-SA) goto ilseq;
+		c = bittab[*s++-SA]; n--;
+	}
+
+	if (n) {
+		if (OOB(c,*s)) goto ilseq;
+loop:
+		c = c<<6 | *s++-0x80; n--;
+		if (!(c&(1U<<31))) {
+			*(unsigned *)st = 0;
+			*wc = c;
+			return N-n;
+		}
+		if (n) {
+			if (*s-0x80u >= 0x40) goto ilseq;
+			goto loop;
+		}
+	}
+
+	*(unsigned *)st = c;
+	return -2;
+ilseq:
+	*(unsigned *)st = 0;
+	errno = EILSEQ;
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbsinit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbsinit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbsinit.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+int mbsinit(const mbstate_t *st)
+{
+	return !st || !*(unsigned *)st;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbsnrtowcs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbsnrtowcs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbsnrtowcs.c	(revision 398)
@@ -0,0 +1,55 @@
+#include <wchar.h>
+
+size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, size_t wn, mbstate_t *restrict st)
+{
+	size_t l, cnt=0, n2;
+	wchar_t *ws, wbuf[256];
+	const char *s = *src;
+	const char *tmp_s;
+
+	if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf;
+	else ws = wcs;
+
+	/* making sure output buffer size is at most n/4 will ensure
+	 * that mbsrtowcs never reads more than n input bytes. thus
+	 * we can use mbsrtowcs as long as it's practical.. */
+
+	while ( s && wn && ( (n2=n/4)>=wn || n2>32 ) ) {
+		if (n2>=wn) n2=wn;
+		tmp_s = s;
+		l = mbsrtowcs(ws, &s, n2, st);
+		if (!(l+1)) {
+			cnt = l;
+			wn = 0;
+			break;
+		}
+		if (ws != wbuf) {
+			ws += l;
+			wn -= l;
+		}
+		n = s ? n - (s - tmp_s) : 0;
+		cnt += l;
+	}
+	if (s) while (wn && n) {
+		l = mbrtowc(ws, s, n, st);
+		if (l+2<=2) {
+			if (!(l+1)) {
+				cnt = l;
+				break;
+			}
+			if (!l) {
+				s = 0;
+				break;
+			}
+			/* have to roll back partial character */
+			*(unsigned *)st = 0;
+			break;
+		}
+		s += l; n -= l;
+		/* safe - this loop runs fewer than sizeof(wbuf)/8 times */
+		ws++; wn--;
+		cnt++;
+	}
+	if (wcs) *src = s;
+	return cnt;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbsrtowcs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbsrtowcs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbsrtowcs.c	(revision 398)
@@ -0,0 +1,114 @@
+#include <stdint.h>
+#include <wchar.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include "internal.h"
+
+size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st)
+{
+	const unsigned char *s = (const void *)*src;
+	size_t wn0 = wn;
+	unsigned c = 0;
+
+	if (st && (c = *(unsigned *)st)) {
+		if (ws) {
+			*(unsigned *)st = 0;
+			goto resume;
+		} else {
+			goto resume0;
+		}
+	}
+
+	if (MB_CUR_MAX==1) {
+		if (!ws) return strlen((const char *)s);
+		for (;;) {
+			if (!wn) {
+				*src = (const void *)s;
+				return wn0;
+			}
+			if (!*s) break;
+			c = *s++;
+			*ws++ = CODEUNIT(c);
+			wn--;
+		}
+		*ws = 0;
+		*src = 0;
+		return wn0-wn;
+	}
+
+	if (!ws) for (;;) {
+		if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
+			while (!(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
+				s += 4;
+				wn -= 4;
+			}
+		}
+		if (*s-1u < 0x7f) {
+			s++;
+			wn--;
+			continue;
+		}
+		if (*s-SA > SB-SA) break;
+		c = bittab[*s++-SA];
+resume0:
+		if (OOB(c,*s)) { s--; break; }
+		s++;
+		if (c&(1U<<25)) {
+			if (*s-0x80u >= 0x40) { s-=2; break; }
+			s++;
+			if (c&(1U<<19)) {
+				if (*s-0x80u >= 0x40) { s-=3; break; }
+				s++;
+			}
+		}
+		wn--;
+		c = 0;
+	} else for (;;) {
+		if (!wn) {
+			*src = (const void *)s;
+			return wn0;
+		}
+		if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
+			while (wn>=5 && !(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
+				*ws++ = *s++;
+				*ws++ = *s++;
+				*ws++ = *s++;
+				*ws++ = *s++;
+				wn -= 4;
+			}
+		}
+		if (*s-1u < 0x7f) {
+			*ws++ = *s++;
+			wn--;
+			continue;
+		}
+		if (*s-SA > SB-SA) break;
+		c = bittab[*s++-SA];
+resume:
+		if (OOB(c,*s)) { s--; break; }
+		c = (c<<6) | *s++-0x80;
+		if (c&(1U<<31)) {
+			if (*s-0x80u >= 0x40) { s-=2; break; }
+			c = (c<<6) | *s++-0x80;
+			if (c&(1U<<31)) {
+				if (*s-0x80u >= 0x40) { s-=3; break; }
+				c = (c<<6) | *s++-0x80;
+			}
+		}
+		*ws++ = c;
+		wn--;
+		c = 0;
+	}
+
+	if (!c && !*s) {
+		if (ws) {
+			*ws = 0;
+			*src = 0;
+		}
+		return wn0-wn;
+	}
+	errno = EILSEQ;
+	if (ws) *src = (const void *)s;
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbstowcs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbstowcs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbstowcs.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include <wchar.h>
+
+size_t mbstowcs(wchar_t *restrict ws, const char *restrict s, size_t wn)
+{
+	return mbsrtowcs(ws, (void*)&s, wn, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbtowc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbtowc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/mbtowc.c	(revision 398)
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+#include <wchar.h>
+#include <errno.h>
+#include "internal.h"
+
+int mbtowc(wchar_t *restrict wc, const char *restrict src, size_t n)
+{
+	unsigned c;
+	const unsigned char *s = (const void *)src;
+	wchar_t dummy;
+
+	if (!s) return 0;
+	if (!n) goto ilseq;
+	if (!wc) wc = &dummy;
+
+	if (*s < 0x80) return !!(*wc = *s);
+	if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
+	if (*s-SA > SB-SA) goto ilseq;
+	c = bittab[*s++-SA];
+
+	/* Avoid excessive checks against n: If shifting the state n-1
+	 * times does not clear the high bit, then the value of n is
+	 * insufficient to read a character */
+	if (n<4 && ((c<<(6*n-6)) & (1U<<31))) goto ilseq;
+
+	if (OOB(c,*s)) goto ilseq;
+	c = c<<6 | *s++-0x80;
+	if (!(c&(1U<<31))) {
+		*wc = c;
+		return 2;
+	}
+
+	if (*s-0x80u >= 0x40) goto ilseq;
+	c = c<<6 | *s++-0x80;
+	if (!(c&(1U<<31))) {
+		*wc = c;
+		return 3;
+	}
+
+	if (*s-0x80u >= 0x40) goto ilseq;
+	*wc = c<<6 | *s++-0x80;
+	return 4;
+
+ilseq:
+	errno = EILSEQ;
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcrtomb.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcrtomb.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcrtomb.c	(revision 398)
@@ -0,0 +1,37 @@
+#include <stdlib.h>
+#include <wchar.h>
+#include <errno.h>
+#include "internal.h"
+
+size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st)
+{
+	if (!s) return 1;
+	if ((unsigned)wc < 0x80) {
+		*s = wc;
+		return 1;
+	} else if (MB_CUR_MAX == 1) {
+		if (!IS_CODEUNIT(wc)) {
+			errno = EILSEQ;
+			return -1;
+		}
+		*s = wc;
+		return 1;
+	} else if ((unsigned)wc < 0x800) {
+		*s++ = 0xc0 | (wc>>6);
+		*s = 0x80 | (wc&0x3f);
+		return 2;
+	} else if ((unsigned)wc < 0xd800 || (unsigned)wc-0xe000 < 0x2000) {
+		*s++ = 0xe0 | (wc>>12);
+		*s++ = 0x80 | ((wc>>6)&0x3f);
+		*s = 0x80 | (wc&0x3f);
+		return 3;
+	} else if ((unsigned)wc-0x10000 < 0x100000) {
+		*s++ = 0xf0 | (wc>>18);
+		*s++ = 0x80 | ((wc>>12)&0x3f);
+		*s++ = 0x80 | ((wc>>6)&0x3f);
+		*s = 0x80 | (wc&0x3f);
+		return 4;
+	}
+	errno = EILSEQ;
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcsnrtombs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcsnrtombs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcsnrtombs.c	(revision 398)
@@ -0,0 +1,43 @@
+#include <wchar.h>
+
+size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
+{
+	size_t l, cnt=0, n2;
+	char *s, buf[256];
+	const wchar_t *ws = *wcs;
+	const wchar_t *tmp_ws;
+
+	if (!dst) s = buf, n = sizeof buf;
+	else s = dst;
+
+	while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
+		if (n2>=n) n2=n;
+		tmp_ws = ws;
+		l = wcsrtombs(s, &ws, n2, 0);
+		if (!(l+1)) {
+			cnt = l;
+			n = 0;
+			break;
+		}
+		if (s != buf) {
+			s += l;
+			n -= l;
+		}
+		wn = ws ? wn - (ws - tmp_ws) : 0;
+		cnt += l;
+	}
+	if (ws) while (n && wn) {
+		l = wcrtomb(s, *ws, 0);
+		if ((l+1)<=1) {
+			if (!l) ws = 0;
+			else cnt = l;
+			break;
+		}
+		ws++; wn--;
+		/* safe - this loop runs fewer than sizeof(buf) times */
+		s+=l; n-=l;
+		cnt += l;
+	}
+	if (dst) *wcs = ws;
+	return cnt;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcsrtombs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcsrtombs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcsrtombs.c	(revision 398)
@@ -0,0 +1,55 @@
+#include <wchar.h>
+
+size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)
+{
+	const wchar_t *ws2;
+	char buf[4];
+	size_t N = n, l;
+	if (!s) {
+		for (n=0, ws2=*ws; *ws2; ws2++) {
+			if (*ws2 >= 0x80u) {
+				l = wcrtomb(buf, *ws2, 0);
+				if (!(l+1)) return -1;
+				n += l;
+			} else n++;
+		}
+		return n;
+	}
+	while (n>=4) {
+		if (**ws-1u >= 0x7fu) {
+			if (!**ws) {
+				*s = 0;
+				*ws = 0;
+				return N-n;
+			}
+			l = wcrtomb(s, **ws, 0);
+			if (!(l+1)) return -1;
+			s += l;
+			n -= l;
+		} else {
+			*s++ = **ws;
+			n--;
+		}
+		(*ws)++;
+	}
+	while (n) {
+		if (**ws-1u >= 0x7fu) {
+			if (!**ws) {
+				*s = 0;
+				*ws = 0;
+				return N-n;
+			}
+			l = wcrtomb(buf, **ws, 0);
+			if (!(l+1)) return -1;
+			if (l>n) return N-n;
+			wcrtomb(s, **ws, 0);
+			s += l;
+			n -= l;
+		} else {
+			*s++ = **ws;
+			n--;
+		}
+		(*ws)++;
+	}
+	return N;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcstombs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcstombs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wcstombs.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include <wchar.h>
+
+size_t wcstombs(char *restrict s, const wchar_t *restrict ws, size_t n)
+{
+	return wcsrtombs(s, &(const wchar_t *){ws}, n, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wctob.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wctob.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wctob.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <wchar.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "internal.h"
+
+int wctob(wint_t c)
+{
+	if (c < 128U) return c;
+	if (MB_CUR_MAX==1 && IS_CODEUNIT(c)) return (unsigned char)c;
+	return EOF;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wctomb.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wctomb.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/multibyte/wctomb.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include <wchar.h>
+
+int wctomb(char *s, wchar_t wc)
+{
+	if (!s) return 0;
+	return wcrtomb(s, wc, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/accept.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/accept.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/accept.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "libc.h"
+
+int accept(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
+{
+	return socketcall_cp(accept, fd, addr, len, 0, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/accept4.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/accept4.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/accept4.c	(revision 398)
@@ -0,0 +1,20 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+#include "libc.h"
+
+int accept4(int fd, struct sockaddr *restrict addr, socklen_t *restrict len, int flg)
+{
+	if (!flg) return accept(fd, addr, len);
+	int ret = socketcall_cp(accept4, fd, addr, len, flg, 0, 0);
+	if (ret>=0 || (errno != ENOSYS && errno != EINVAL)) return ret;
+	ret = accept(fd, addr, len);
+	if (ret<0) return ret;
+	if (flg & SOCK_CLOEXEC)
+		__syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+	if (flg & SOCK_NONBLOCK)
+		__syscall(SYS_fcntl, ret, F_SETFL, O_NONBLOCK);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/bind.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/bind.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/bind.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int bind(int fd, const struct sockaddr *addr, socklen_t len)
+{
+	return socketcall(bind, fd, addr, len, 0, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/connect.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/connect.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/connect.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "libc.h"
+
+int connect(int fd, const struct sockaddr *addr, socklen_t len)
+{
+	return socketcall_cp(connect, fd, addr, len, 0, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dn_comp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dn_comp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dn_comp.c	(revision 398)
@@ -0,0 +1,110 @@
+#include <string.h>
+#include <resolv.h>
+#include "libc.h"
+
+/* RFC 1035 message compression */
+
+/* label start offsets of a compressed domain name s */
+static int getoffs(short *offs, const unsigned char *base, const unsigned char *s)
+{
+	int i=0;
+	for (;;) {
+		while (*s & 0xc0) {
+			if ((*s & 0xc0) != 0xc0) return 0;
+			s = base + ((s[0]&0x3f)<<8 | s[1]);
+		}
+		if (!*s) return i;
+		if (s-base >= 0x4000) return 0;
+		offs[i++] = s-base;
+		s += *s + 1;
+	}
+}
+
+/* label lengths of an ascii domain name s */
+static int getlens(unsigned char *lens, const char *s, int l)
+{
+	int i=0,j=0,k=0;
+	for (;;) {
+		for (; j<l && s[j]!='.'; j++);
+		if (j-k-1u > 62) return 0;
+		lens[i++] = j-k;
+		if (j==l) return i;
+		k = ++j;
+	}
+}
+
+/* longest suffix match of an ascii domain with a compressed domain name dn */
+static int match(int *offset, const unsigned char *base, const unsigned char *dn,
+	const char *end, const unsigned char *lens, int nlen)
+{
+	int l, o, m=0;
+	short offs[128];
+	int noff = getoffs(offs, base, dn);
+	if (!noff) return 0;
+	for (;;) {
+		l = lens[--nlen];
+		o = offs[--noff];
+		end -= l;
+		if (l != base[o] || memcmp(base+o+1, end, l))
+			return m;
+		*offset = o;
+		m += l;
+		if (nlen) m++;
+		if (!nlen || !noff) return m;
+		end--;
+	}
+}
+
+int __dn_comp(const char *src, unsigned char *dst, int space, unsigned char **dnptrs, unsigned char **lastdnptr)
+{
+	int i, j, n, m=0, offset, bestlen=0, bestoff;
+	unsigned char lens[127];
+	unsigned char **p;
+	const char *end;
+	size_t l = strnlen(src, 255);
+	if (l && src[l-1] == '.') l--;
+	if (l>253 || space<=0) return -1;
+	if (!l) {
+		*dst = 0;
+		return 1;
+	}
+	end = src+l;
+	n = getlens(lens, src, l);
+	if (!n) return -1;
+
+	p = dnptrs;
+	if (p && *p) for (p++; *p; p++) {
+		m = match(&offset, *dnptrs, *p, end, lens, n);
+		if (m > bestlen) {
+			bestlen = m;
+			bestoff = offset;
+			if (m == l)
+				break;
+		}
+	}
+
+	/* encode unmatched part */
+	if (space < l-bestlen+2+(bestlen-1 < l-1)) return -1;
+	memcpy(dst+1, src, l-bestlen);
+	for (i=j=0; i<l-bestlen; i+=lens[j++]+1)
+		dst[i] = lens[j];
+
+	/* add tail */
+	if (bestlen) {
+		dst[i++] = 0xc0 | bestoff>>8;
+		dst[i++] = bestoff;
+	} else
+		dst[i++] = 0;
+
+	/* save dst pointer */
+	if (i>2 && lastdnptr && dnptrs && *dnptrs) {
+		while (*p) p++;
+		if (p+1 < lastdnptr) {
+			*p++ = dst;
+			*p=0;
+		}
+	}
+	return i;
+}
+
+weak_alias(__dn_comp, dn_comp);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dn_expand.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dn_expand.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dn_expand.c	(revision 398)
@@ -0,0 +1,34 @@
+#include <resolv.h>
+#include "libc.h"
+
+int __dn_expand(const unsigned char *base, const unsigned char *end, const unsigned char *src, char *dest, int space)
+{
+	const unsigned char *p = src;
+	char *dend, *dbegin = dest;
+	int len = -1, i, j;
+	if (p==end || space <= 0) return -1;
+	dend = dest + (space > 254 ? 254 : space);
+	/* detect reference loop using an iteration counter */
+	for (i=0; i < end-base; i+=2) {
+		/* loop invariants: p<end, dest<dend */
+		if (*p & 0xc0) {
+			if (p+1==end) return -1;
+			j = ((p[0] & 0x3f) << 8) | p[1];
+			if (len < 0) len = p+2-src;
+			if (j >= end-base) return -1;
+			p = base+j;
+		} else if (*p) {
+			if (dest != dbegin) *dest++ = '.';
+			j = *p++;
+			if (j >= end-p || j >= dend-dest) return -1;
+			while (j--) *dest++ = *p++;
+		} else {
+			*dest = 0;
+			if (len < 0) len = p+1-src;
+			return len;
+		}
+	}
+	return -1;
+}
+
+weak_alias(__dn_expand, dn_expand);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dn_skipname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dn_skipname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dn_skipname.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <resolv.h>
+
+int dn_skipname(const unsigned char *s, const unsigned char *end)
+{
+	const unsigned char *p;
+	for (p=s; p<end; p++)
+		if (!*p) return p-s+1;
+		else if (*p>=192)
+			if (p+1<end) return p-s+2;
+			else break;
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dns_parse.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dns_parse.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/dns_parse.c	(revision 398)
@@ -0,0 +1,32 @@
+#include <string.h>
+
+int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, const void *, int, const void *), void *ctx)
+{
+	int qdcount, ancount;
+	const unsigned char *p;
+	int len;
+
+	if (rlen<12) return -1;
+	if ((r[3]&15)) return 0;
+	p = r+12;
+	qdcount = r[4]*256 + r[5];
+	ancount = r[6]*256 + r[7];
+	if (qdcount+ancount > 64) return -1;
+	while (qdcount--) {
+		while (p-r < rlen && *p-1U < 127) p++;
+		if (*p>193 || (*p==193 && p[1]>254) || p>r+rlen-6)
+			return -1;
+		p += 5 + !!*p;
+	}
+	while (ancount--) {
+		while (p-r < rlen && *p-1U < 127) p++;
+		if (*p>193 || (*p==193 && p[1]>254) || p>r+rlen-6)
+			return -1;
+		p += 1 + !!*p;
+		len = p[8]*256 + p[9];
+		if (p+len > r+rlen) return -1;
+		if (callback(ctx, p[1], p+10, len, r) < 0) return -1;
+		p += 10 + len;
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ent.c	(revision 398)
@@ -0,0 +1,18 @@
+#include "libc.h"
+
+void sethostent(int x)
+{
+}
+
+void *gethostent()
+{
+	return 0;
+}
+
+void endhostent(void)
+{
+}
+
+weak_alias(sethostent, setnetent);
+weak_alias(gethostent, getnetent);
+weak_alias(endhostent, endnetent);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ether.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ether.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ether.c	(revision 398)
@@ -0,0 +1,58 @@
+#include <stdlib.h>
+#include <netinet/ether.h>
+#include <stdio.h>
+
+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;
+}
+
+struct ether_addr *ether_aton (const char *x)
+{
+	static struct ether_addr a;
+	return ether_aton_r (x, &a);
+}
+
+char *ether_ntoa_r (const struct ether_addr *p_a, char *x) {
+	char *y;
+	y = x;
+	for (int ii = 0; ii < 6; ii++) {
+		x += sprintf (x, ii == 0 ? "%.2X" : ":%.2X", p_a->ether_addr_octet[ii]);
+	}
+	return y;
+}
+
+char *ether_ntoa (const struct ether_addr *p_a) {
+	static char x[18];
+	return ether_ntoa_r (p_a, x);
+}
+
+int ether_line(const char *l, struct ether_addr *e, char *hostname)
+{
+	return -1;
+}
+
+int ether_ntohost(char *hostname, const struct ether_addr *e)
+{
+	return -1;
+}
+
+int ether_hostton(const char *hostname, struct ether_addr *e)
+{
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/freeaddrinfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/freeaddrinfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/freeaddrinfo.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+#include <netdb.h>
+
+void freeaddrinfo(struct addrinfo *p)
+{
+	free(p);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gai_strerror.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gai_strerror.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gai_strerror.c	(revision 398)
@@ -0,0 +1,25 @@
+#include <netdb.h>
+#include "locale_impl.h"
+
+static const char msgs[] =
+	"Invalid flags\0"
+	"Name does not resolve\0"
+	"Try again\0"
+	"Non-recoverable error\0"
+	"Unknown error\0"
+	"Unrecognized address family or invalid length\0"
+	"Unrecognized socket type\0"
+	"Unrecognized service\0"
+	"Unknown error\0"
+	"Out of memory\0"
+	"System error\0"
+	"Overflow\0"
+	"\0Unknown error";
+
+const char *gai_strerror(int ecode)
+{
+	const char *s;
+	for (s=msgs, ecode++; ecode && *s; ecode++, s++) for (; *s; s++);
+	if (!*s) s++;
+	return LCTRANS_CUR(s);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getaddrinfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getaddrinfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getaddrinfo.c	(revision 398)
@@ -0,0 +1,92 @@
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+#include "lookup.h"
+
+int getaddrinfo(const char *restrict host, const char *restrict serv, const struct addrinfo *restrict hint, struct addrinfo **restrict res)
+{
+	struct service ports[MAXSERVS];
+	struct address addrs[MAXADDRS];
+	char canon[256], *outcanon;
+	int nservs, naddrs, nais, canon_len, i, j, k;
+	int family = AF_UNSPEC, flags = 0, proto = 0, socktype = 0;
+	struct aibuf {
+		struct addrinfo ai;
+		union sa {
+			struct sockaddr_in sin;
+			struct sockaddr_in6 sin6;
+		} sa;
+	} *out;
+
+	if (!host && !serv) return EAI_NONAME;
+
+	if (hint) {
+		family = hint->ai_family;
+		flags = hint->ai_flags;
+		proto = hint->ai_protocol;
+		socktype = hint->ai_socktype;
+
+		const int mask = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST |
+			AI_V4MAPPED | AI_ALL | AI_ADDRCONFIG | AI_NUMERICSERV;
+		if ((flags & mask) != flags)
+			return EAI_BADFLAGS;
+
+		switch (family) {
+		case AF_INET:
+		case AF_INET6:
+		case AF_UNSPEC:
+			break;
+		default:
+			return EAI_FAMILY;
+		}
+	}
+
+	nservs = __lookup_serv(ports, serv, proto, socktype, flags);
+	if (nservs < 0) return nservs;
+
+	naddrs = __lookup_name(addrs, canon, host, family, flags);
+	if (naddrs < 0) return naddrs;
+
+	nais = nservs * naddrs;
+	canon_len = strlen(canon);
+	out = calloc(1, nais * sizeof(*out) + canon_len + 1);
+	if (!out) return EAI_MEMORY;
+
+	if (canon_len) {
+		outcanon = (void *)&out[nais];
+		memcpy(outcanon, canon, canon_len+1);
+	} else {
+		outcanon = 0;
+	}
+
+	for (k=i=0; i<naddrs; i++) for (j=0; j<nservs; j++, k++) {
+		out[k].ai = (struct addrinfo){
+			.ai_family = addrs[i].family,
+			.ai_socktype = ports[j].socktype,
+			.ai_protocol = ports[j].proto,
+			.ai_addrlen = addrs[i].family == AF_INET
+				? sizeof(struct sockaddr_in)
+				: sizeof(struct sockaddr_in6),
+			.ai_addr = (void *)&out[k].sa,
+			.ai_canonname = outcanon,
+			.ai_next = &out[k+1].ai };
+		switch (addrs[i].family) {
+		case AF_INET:
+			out[k].sa.sin.sin_family = AF_INET;
+			out[k].sa.sin.sin_port = htons(ports[j].port);
+			memcpy(&out[k].sa.sin.sin_addr, &addrs[i].addr, 4);
+			break;
+		case AF_INET6:
+			out[k].sa.sin6.sin6_family = AF_INET6;
+			out[k].sa.sin6.sin6_port = htons(ports[j].port);
+			out[k].sa.sin6.sin6_scope_id = addrs[i].scopeid;
+			memcpy(&out[k].sa.sin6.sin6_addr, &addrs[i].addr, 16);
+			break;			
+		}
+	}
+	out[nais-1].ai.ai_next = 0;
+	*res = &out->ai;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyaddr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyaddr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyaddr.c	(revision 398)
@@ -0,0 +1,24 @@
+#define _GNU_SOURCE
+
+#include <netdb.h>
+#include <errno.h>
+#include <stdlib.h>
+
+struct hostent *gethostbyaddr(const void *a, socklen_t l, int af)
+{
+	static struct hostent *h;
+	size_t size = 63;
+	struct hostent *res;
+	int err;
+	do {
+		free(h);
+		h = malloc(size+=size+1);
+		if (!h) {
+			h_errno = NO_RECOVERY;
+			return 0;
+		}
+		err = gethostbyaddr_r(a, l, af, h,
+			(void *)(h+1), size-sizeof *h, &res, &h_errno);
+	} while (err == ERANGE);
+	return err ? 0 : h;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyaddr_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyaddr_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyaddr_r.c	(revision 398)
@@ -0,0 +1,71 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <inttypes.h>
+
+int gethostbyaddr_r(const void *a, socklen_t l, int af,
+	struct hostent *h, char *buf, size_t buflen,
+	struct hostent **res, int *err)
+{
+	union {
+		struct sockaddr_in sin;
+		struct sockaddr_in6 sin6;
+	} sa = { .sin.sin_family = af };
+	socklen_t sl = af==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin;
+	int i;
+
+	*res = 0;
+
+	/* Load address argument into sockaddr structure */
+	if (af==AF_INET6 && l==16) memcpy(&sa.sin6.sin6_addr, a, 16);
+	else if (af==AF_INET && l==4) memcpy(&sa.sin.sin_addr, a, 4);
+	else {
+		*err = NO_RECOVERY;
+		return EINVAL;
+	}
+
+	/* Align buffer and check for space for pointers and ip address */
+	i = (uintptr_t)buf & sizeof(char *)-1;
+	if (!i) i = sizeof(char *);
+	if (buflen <= 5*sizeof(char *)-i + l) return ERANGE;
+	buf += sizeof(char *)-i;
+	buflen -= 5*sizeof(char *)-i + l;
+
+	h->h_addr_list = (void *)buf;
+	buf += 2*sizeof(char *);
+	h->h_aliases = (void *)buf;
+	buf += 2*sizeof(char *);
+
+	h->h_addr_list[0] = buf;
+	memcpy(h->h_addr_list[0], a, l);
+	buf += l;
+	h->h_addr_list[1] = 0;
+	h->h_aliases[0] = buf;
+	h->h_aliases[1] = 0;
+
+	switch (getnameinfo((void *)&sa, sl, buf, buflen, 0, 0, 0)) {
+	case EAI_AGAIN:
+		*err = TRY_AGAIN;
+		return EAGAIN;
+	case EAI_OVERFLOW:
+		return ERANGE;
+	default:
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+	case EAI_FAIL:
+		*err = NO_RECOVERY;
+		return errno;
+	case 0:
+		break;
+	}
+
+	h->h_addrtype = af;
+	h->h_length = l;
+	h->h_name = h->h_aliases[0];
+	*res = h;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname.c	(revision 398)
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+
+struct hostent *gethostbyname(const char *name)
+{
+	return gethostbyname2(name, AF_INET);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname2.c	(revision 398)
@@ -0,0 +1,25 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <stdlib.h>
+
+struct hostent *gethostbyname2(const char *name, int af)
+{
+	static struct hostent *h;
+	size_t size = 63;
+	struct hostent *res;
+	int err;
+	do {
+		free(h);
+		h = malloc(size+=size+1);
+		if (!h) {
+			h_errno = NO_RECOVERY;
+			return 0;
+		}
+		err = gethostbyname2_r(name, af, h,
+			(void *)(h+1), size-sizeof *h, &res, &h_errno);
+	} while (err == ERANGE);
+	return err ? 0 : h;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname2_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname2_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname2_r.c	(revision 398)
@@ -0,0 +1,80 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <stdint.h>
+#include "lookup.h"
+
+int gethostbyname2_r(const char *name, int af,
+	struct hostent *h, char *buf, size_t buflen,
+	struct hostent **res, int *err)
+{
+	struct address addrs[MAXADDRS];
+	char canon[256];
+	int i, cnt;
+	size_t align, need;
+
+	*res = 0;
+	cnt = __lookup_name(addrs, canon, name, af, AI_CANONNAME);
+	if (cnt<0) switch (cnt) {
+	case EAI_NONAME:
+		*err = HOST_NOT_FOUND;
+		return ENOENT;
+	case EAI_AGAIN:
+		*err = TRY_AGAIN;
+		return EAGAIN;
+	default:
+	case EAI_FAIL:
+		*err = NO_RECOVERY;
+		return EBADMSG;
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+		*err = NO_RECOVERY;
+		return errno;
+	}
+
+	h->h_addrtype = af;
+	h->h_length = af==AF_INET6 ? 16 : 4;
+
+	/* Align buffer */
+	align = -(uintptr_t)buf & sizeof(char *)-1;
+
+	need = 4*sizeof(char *);
+	need += (cnt + 1) * (sizeof(char *) + h->h_length);
+	need += strlen(name)+1;
+	need += strlen(canon)+1;
+	need += align;
+
+	if (need > buflen) return ERANGE;
+
+	buf += align;
+	h->h_aliases = (void *)buf;
+	buf += 3*sizeof(char *);
+	h->h_addr_list = (void *)buf;
+	buf += (cnt+1)*sizeof(char *);
+
+	for (i=0; i<cnt; i++) {
+		h->h_addr_list[i] = (void *)buf;
+		buf += h->h_length;
+		memcpy(h->h_addr_list[i], addrs[i].addr, h->h_length);
+	}
+	h->h_addr_list[i] = 0;
+
+	h->h_name = h->h_aliases[0] = buf;
+	strcpy(h->h_name, canon);
+	buf += strlen(h->h_name)+1;
+
+	if (strcmp(h->h_name, name)) {
+		h->h_aliases[1] = buf;
+		strcpy(h->h_aliases[1], name);
+		buf += strlen(h->h_aliases[1])+1;
+	} else h->h_aliases[1] = 0;
+
+	h->h_aliases[2] = 0;
+
+	*res = h;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/gethostbyname_r.c	(revision 398)
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netdb.h>
+
+int gethostbyname_r(const char *name,
+	struct hostent *h, char *buf, size_t buflen,
+	struct hostent **res, int *err)
+{
+	return gethostbyname2_r(name, AF_INET, h, buf, buflen, res, err);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getifaddrs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getifaddrs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getifaddrs.c	(revision 398)
@@ -0,0 +1,216 @@
+#define _GNU_SOURCE
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ifaddrs.h>
+#include <syscall.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include "netlink.h"
+
+#define IFADDRS_HASH_SIZE 64
+
+/* getifaddrs() reports hardware addresses with PF_PACKET that implies
+ * struct sockaddr_ll.  But e.g. Infiniband socket address length is
+ * longer than sockaddr_ll.ssl_addr[8] can hold. Use this hack struct
+ * to extend ssl_addr - callers should be able to still use it. */
+struct sockaddr_ll_hack {
+	unsigned short sll_family, sll_protocol;
+	int sll_ifindex;
+	unsigned short sll_hatype;
+	unsigned char sll_pkttype, sll_halen;
+	unsigned char sll_addr[24];
+};
+
+union sockany {
+	struct sockaddr sa;
+	struct sockaddr_ll_hack ll;
+	struct sockaddr_in v4;
+	struct sockaddr_in6 v6;
+};
+
+struct ifaddrs_storage {
+	struct ifaddrs ifa;
+	struct ifaddrs_storage *hash_next;
+	union sockany addr, netmask, ifu;
+	unsigned int index;
+	char name[IFNAMSIZ+1];
+};
+
+struct ifaddrs_ctx {
+	struct ifaddrs_storage *first;
+	struct ifaddrs_storage *last;
+	struct ifaddrs_storage *hash[IFADDRS_HASH_SIZE];
+};
+
+void freeifaddrs(struct ifaddrs *ifp)
+{
+	struct ifaddrs *n;
+	while (ifp) {
+		n = ifp->ifa_next;
+		free(ifp);
+		ifp = n;
+	}
+}
+
+static void copy_addr(struct sockaddr **r, int af, union sockany *sa, void *addr, size_t addrlen, int ifindex)
+{
+	uint8_t *dst;
+	int len;
+
+	switch (af) {
+	case AF_INET:
+		dst = (uint8_t*) &sa->v4.sin_addr;
+		len = 4;
+		break;
+	case AF_INET6:
+		dst = (uint8_t*) &sa->v6.sin6_addr;
+		len = 16;
+		if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MC_LINKLOCAL(addr))
+			sa->v6.sin6_scope_id = ifindex;
+		break;
+	default:
+		return;
+	}
+	if (addrlen < len) return;
+	sa->sa.sa_family = af;
+	memcpy(dst, addr, len);
+	*r = &sa->sa;
+}
+
+static void gen_netmask(struct sockaddr **r, int af, union sockany *sa, int prefixlen)
+{
+	uint8_t addr[16] = {0};
+	int i;
+
+	if (prefixlen > 8*sizeof(addr)) prefixlen = 8*sizeof(addr);
+	i = prefixlen / 8;
+	memset(addr, 0xff, i);
+	if (i < sizeof(addr)) addr[i++] = 0xff << (8 - (prefixlen % 8));
+	copy_addr(r, af, sa, addr, sizeof(addr), 0);
+}
+
+static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *addr, size_t addrlen, int ifindex, unsigned short hatype)
+{
+	if (addrlen > sizeof(sa->ll.sll_addr)) return;
+	sa->ll.sll_family = AF_PACKET;
+	sa->ll.sll_ifindex = ifindex;
+	sa->ll.sll_hatype = hatype;
+	sa->ll.sll_halen = addrlen;
+	memcpy(sa->ll.sll_addr, addr, addrlen);
+	*r = &sa->sa;
+}
+
+static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h)
+{
+	struct ifaddrs_ctx *ctx = pctx;
+	struct ifaddrs_storage *ifs, *ifs0;
+	struct ifinfomsg *ifi = NLMSG_DATA(h);
+	struct ifaddrmsg *ifa = NLMSG_DATA(h);
+	struct rtattr *rta;
+	int stats_len = 0;
+
+	if (h->nlmsg_type == RTM_NEWLINK) {
+		for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
+			if (rta->rta_type != IFLA_STATS) continue;
+			stats_len = RTA_DATALEN(rta);
+			break;
+		}
+	} else {
+		for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0; ifs0 = ifs0->hash_next)
+			if (ifs0->index == ifa->ifa_index)
+				break;
+		if (!ifs0) return 0;
+	}
+
+	ifs = calloc(1, sizeof(struct ifaddrs_storage) + stats_len);
+	if (ifs == 0) return -1;
+
+	if (h->nlmsg_type == RTM_NEWLINK) {
+		ifs->index = ifi->ifi_index;
+		ifs->ifa.ifa_flags = ifi->ifi_flags;
+
+		for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
+			switch (rta->rta_type) {
+			case IFLA_IFNAME:
+				if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
+					memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
+					ifs->ifa.ifa_name = ifs->name;
+				}
+				break;
+			case IFLA_ADDRESS:
+				copy_lladdr(&ifs->ifa.ifa_addr, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
+				break;
+			case IFLA_BROADCAST:
+				copy_lladdr(&ifs->ifa.ifa_broadaddr, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
+				break;
+			case IFLA_STATS:
+				ifs->ifa.ifa_data = (void*)(ifs+1);
+				memcpy(ifs->ifa.ifa_data, RTA_DATA(rta), RTA_DATALEN(rta));
+				break;
+			}
+		}
+		if (ifs->ifa.ifa_name) {
+			unsigned int bucket = ifs->index % IFADDRS_HASH_SIZE;
+			ifs->hash_next = ctx->hash[bucket];
+			ctx->hash[bucket] = ifs;
+		}
+	} else {
+		ifs->ifa.ifa_name = ifs0->ifa.ifa_name;
+		ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags;
+		for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
+			switch (rta->rta_type) {
+			case IFA_ADDRESS:
+				/* If ifa_addr is already set we, received an IFA_LOCAL before
+				 * so treat this as destination address */
+				if (ifs->ifa.ifa_addr)
+					copy_addr(&ifs->ifa.ifa_dstaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				else
+					copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				break;
+			case IFA_BROADCAST:
+				copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				break;
+			case IFA_LOCAL:
+				/* If ifa_addr is set and we get IFA_LOCAL, assume we have
+				 * a point-to-point network. Move address to correct field. */
+				if (ifs->ifa.ifa_addr) {
+					ifs->ifu = ifs->addr;
+					ifs->ifa.ifa_dstaddr = &ifs->ifu.sa;
+					memset(&ifs->addr, 0, sizeof(ifs->addr));
+				}
+				copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
+				break;
+			case IFA_LABEL:
+				if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
+					memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
+					ifs->ifa.ifa_name = ifs->name;
+				}
+				break;
+			}
+		}
+		if (ifs->ifa.ifa_addr)
+			gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs->netmask, ifa->ifa_prefixlen);
+	}
+
+	if (ifs->ifa.ifa_name) {
+		if (!ctx->first) ctx->first = ifs;
+		if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa;
+		ctx->last = ifs;
+	} else {
+		free(ifs);
+	}
+	return 0;
+}
+
+int getifaddrs(struct ifaddrs **ifap)
+{
+	struct ifaddrs_ctx _ctx, *ctx = &_ctx;
+	int r;
+	memset(ctx, 0, sizeof *ctx);
+	r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx);
+	if (r == 0) *ifap = &ctx->first->ifa;
+	else freeifaddrs(&ctx->first->ifa);
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getnameinfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getnameinfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getnameinfo.c	(revision 398)
@@ -0,0 +1,202 @@
+#include <netdb.h>
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <ctype.h>
+#include "lookup.h"
+#include "stdio_impl.h"
+
+int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *);
+int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
+int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
+int __res_send(const unsigned char *, int, unsigned char *, int);
+
+#define PTR_MAX (64 + sizeof ".in-addr.arpa")
+#define RR_PTR 12
+
+static char *itoa(char *p, unsigned x) {
+	p += 3*sizeof(int);
+	*--p = 0;
+	do {
+		*--p = '0' + x % 10;
+		x /= 10;
+	} while (x);
+	return p;
+}
+
+static void mkptr4(char *s, const unsigned char *ip)
+{
+	sprintf(s, "%d.%d.%d.%d.in-addr.arpa",
+		ip[3], ip[2], ip[1], ip[0]);
+}
+
+static void mkptr6(char *s, const unsigned char *ip)
+{
+	static const char xdigits[] = "0123456789abcdef";
+	int i;
+	for (i=15; i>=0; i--) {
+		*s++ = xdigits[ip[i]&15]; *s++ = '.';
+		*s++ = xdigits[ip[i]>>4]; *s++ = '.';
+	}
+	strcpy(s, "ip6.arpa");
+}
+
+static void reverse_hosts(char *buf, const unsigned char *a, unsigned scopeid, int family)
+{
+	char line[512], *p, *z;
+	unsigned char _buf[1032], atmp[16];
+	struct address iplit;
+	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
+	if (!f) return;
+	if (family == AF_INET) {
+		memcpy(atmp+12, a, 4);
+		memcpy(atmp, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+		a = atmp;
+	}
+	while (fgets(line, sizeof line, f)) {
+		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
+
+		for (p=line; *p && !isspace(*p); p++);
+		*p++ = 0;
+		if (__lookup_ipliteral(&iplit, line, AF_UNSPEC)<=0)
+			continue;
+
+		if (iplit.family == AF_INET) {
+			memcpy(iplit.addr+12, iplit.addr, 4);
+			memcpy(iplit.addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			iplit.scopeid = 0;
+		}
+
+		if (memcmp(a, iplit.addr, 16) || iplit.scopeid != scopeid)
+			continue;
+			
+		for (; *p && isspace(*p); p++);
+		for (z=p; *z && !isspace(*z); z++);
+		*z = 0;
+		if (z-p < 256) {
+			memcpy(buf, p, z-p+1);
+			break;
+		}
+	}
+	__fclose_ca(f);
+}
+
+static void reverse_services(char *buf, int port, int dgram)
+{
+	unsigned long svport;
+	char line[128], *p, *z;
+	unsigned char _buf[1032];
+	FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
+	if (!f) return;
+	while (fgets(line, sizeof line, f)) {
+		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
+
+		for (p=line; *p && !isspace(*p); p++);
+		if (!*p) continue;
+		*p++ = 0;
+		svport = strtoul(p, &z, 10);
+
+		if (svport != port || z==p) continue;
+		if (dgram && strncmp(z, "/udp", 4)) continue;
+		if (!dgram && strncmp(z, "/tcp", 4)) continue;
+		if (p-line > 32) continue;
+
+		memcpy(buf, line, p-line);
+		break;
+	}
+	__fclose_ca(f);
+}
+
+static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
+{
+	if (rr != RR_PTR) return 0;
+	if (__dn_expand(packet, (const unsigned char *)packet + 512,
+	    data, c, 256) <= 0)
+		*(char *)c = 0;
+	return 0;
+	
+}
+
+int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl,
+	char *restrict node, socklen_t nodelen,
+	char *restrict serv, socklen_t servlen,
+	int flags)
+{
+	char ptr[PTR_MAX];
+	char buf[256], num[3*sizeof(int)+1];
+	int af = sa->sa_family;
+	unsigned char *a;
+	unsigned scopeid;
+
+	switch (af) {
+	case AF_INET:
+		a = (void *)&((struct sockaddr_in *)sa)->sin_addr;
+		if (sl < sizeof(struct sockaddr_in)) return EAI_FAMILY;
+		mkptr4(ptr, a);
+		scopeid = 0;
+		break;
+	case AF_INET6:
+		a = (void *)&((struct sockaddr_in6 *)sa)->sin6_addr;
+		if (sl < sizeof(struct sockaddr_in6)) return EAI_FAMILY;
+		if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12))
+			mkptr6(ptr, a);
+		else
+			mkptr4(ptr, a+12);
+		scopeid = ((struct sockaddr_in6 *)sa)->sin6_scope_id;
+		break;
+	default:
+		return EAI_FAMILY;
+	}
+
+	if (node && nodelen) {
+		buf[0] = 0;
+		if (!(flags & NI_NUMERICHOST)) {
+			reverse_hosts(buf, a, scopeid, af);
+		}
+		if (!*buf && !(flags & NI_NUMERICHOST)) {
+			unsigned char query[18+PTR_MAX], reply[512];
+			int qlen = __res_mkquery(0, ptr, 1, RR_PTR,
+				0, 0, 0, query, sizeof query);
+			int rlen = __res_send(query, qlen, reply, sizeof reply);
+			buf[0] = 0;
+			if (rlen > 0)
+				__dns_parse(reply, rlen, dns_parse_callback, buf);
+		}
+		if (!*buf) {
+			if (flags & NI_NAMEREQD) return EAI_NONAME;
+			inet_ntop(af, a, buf, sizeof buf);
+			if (scopeid) {
+				char *p = 0, tmp[IF_NAMESIZE+1];
+				if (!(flags & NI_NUMERICSCOPE) &&
+				    (IN6_IS_ADDR_LINKLOCAL(a) ||
+				     IN6_IS_ADDR_MC_LINKLOCAL(a)))
+					p = if_indextoname(scopeid, tmp+1);
+				if (!p)
+					p = itoa(num, scopeid);
+				*--p = '%';
+				strcat(buf, p);
+			}
+		}
+		if (strlen(buf) >= nodelen) return EAI_OVERFLOW;
+		strcpy(node, buf);
+	}
+
+	if (serv && servlen) {
+		char *p = buf;
+		int port = ntohs(((struct sockaddr_in *)sa)->sin_port);
+		buf[0] = 0;
+		if (!(flags & NI_NUMERICSERV))
+			reverse_services(buf, port, flags & NI_DGRAM);
+		if (!*p)
+			p = itoa(num, port);
+		if (strlen(p) >= servlen)
+			return EAI_OVERFLOW;
+		strcpy(serv, p);
+	}
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getpeername.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getpeername.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getpeername.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int getpeername(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
+{
+	return socketcall(getpeername, fd, addr, len, 0, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyname.c	(revision 398)
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <netdb.h>
+
+struct servent *getservbyname(const char *name, const char *prots)
+{
+	static struct servent se;
+	static char *buf[2];
+	struct servent *res;
+	if (getservbyname_r(name, prots, &se, (void *)buf, sizeof buf, &res))
+		return 0;
+	return &se;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyname_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyname_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyname_r.c	(revision 398)
@@ -0,0 +1,55 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include "lookup.h"
+
+#define ALIGN (sizeof(struct { char a; char *b; }) - sizeof(char *))
+
+int getservbyname_r(const char *name, const char *prots,
+	struct servent *se, char *buf, size_t buflen, struct servent **res)
+{
+	struct service servs[MAXSERVS];
+	int cnt, proto, align;
+
+	*res = 0;
+
+	/* Don't treat numeric port number strings as service records. */
+	char *end = "";
+	strtoul(name, &end, 10);
+	if (!*end) return ENOENT;
+
+	/* Align buffer */
+	align = -(uintptr_t)buf & ALIGN-1;
+	if (buflen < 2*sizeof(char *)+align)
+		return ERANGE;
+	buf += align;
+
+	if (!prots) proto = 0;
+	else if (!strcmp(prots, "tcp")) proto = IPPROTO_TCP;
+	else if (!strcmp(prots, "udp")) proto = IPPROTO_UDP;
+	else return EINVAL;
+
+	cnt = __lookup_serv(servs, name, proto, 0, 0);
+	if (cnt<0) switch (cnt) {
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+		return ENOMEM;
+	default:
+		return ENOENT;
+	}
+
+	se->s_name = (char *)name;
+	se->s_aliases = (void *)buf;
+	se->s_aliases[0] = se->s_name;
+	se->s_aliases[1] = 0;
+	se->s_port = htons(servs[0].port);
+	se->s_proto = servs[0].proto == IPPROTO_TCP ? "tcp" : "udp";
+
+	*res = se;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyport.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyport.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyport.c	(revision 398)
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <netdb.h>
+
+struct servent *getservbyport(int port, const char *prots)
+{
+	static struct servent se;
+	static long buf[32/sizeof(long)];
+	struct servent *res;
+	if (getservbyport_r(port, prots, &se, (void *)buf, sizeof buf, &res))
+		return 0;
+	return &se;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyport_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyport_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getservbyport_r.c	(revision 398)
@@ -0,0 +1,60 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+int getservbyport_r(int port, const char *prots,
+	struct servent *se, char *buf, size_t buflen, struct servent **res)
+{
+	int i;
+	struct sockaddr_in sin = {
+		.sin_family = AF_INET,
+		.sin_port = port,
+	};
+
+	if (!prots) {
+		int r = getservbyport_r(port, "tcp", se, buf, buflen, res);
+		if (r) r = getservbyport_r(port, "udp", se, buf, buflen, res);
+		return r;
+	}
+	*res = 0;
+
+	/* Align buffer */
+	i = (uintptr_t)buf & sizeof(char *)-1;
+	if (!i) i = sizeof(char *);
+	if (buflen < 3*sizeof(char *)-i)
+		return ERANGE;
+	buf += sizeof(char *)-i;
+	buflen -= sizeof(char *)-i;
+
+	if (strcmp(prots, "tcp") && strcmp(prots, "udp")) return EINVAL;
+
+	se->s_port = port;
+	se->s_proto = (char *)prots;
+	se->s_aliases = (void *)buf;
+	buf += 2*sizeof(char *);
+	buflen -= 2*sizeof(char *);
+	se->s_aliases[1] = 0;
+	se->s_aliases[0] = se->s_name = buf;
+
+	switch (getnameinfo((void *)&sin, sizeof sin, 0, 0, buf, buflen,
+		strcmp(prots, "udp") ? 0 : NI_DGRAM)) {
+	case EAI_MEMORY:
+	case EAI_SYSTEM:
+		return ENOMEM;
+	default:
+		return ENOENT;
+	case 0:
+		break;
+	}
+
+	/* A numeric port string is not a service record. */
+	if (strtol(buf, 0, 10)==ntohs(port)) return ENOENT;
+
+	*res = se;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getsockname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getsockname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getsockname.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int getsockname(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
+{
+	return socketcall(getsockname, fd, addr, len, 0, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getsockopt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getsockopt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/getsockopt.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int getsockopt(int fd, int level, int optname, void *restrict optval, socklen_t *restrict optlen)
+{
+	return socketcall(getsockopt, fd, level, optname, optval, optlen, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/h_errno.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/h_errno.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/h_errno.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <netdb.h>
+
+#undef h_errno
+int h_errno;
+
+int *__h_errno_location(void)
+{
+	return &h_errno;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/herror.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/herror.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/herror.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <netdb.h>
+
+void herror(const char *msg)
+{
+	fprintf(stderr, "%s%s%s", msg?msg:"", msg?": ":"", hstrerror(h_errno));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/hstrerror.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/hstrerror.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/hstrerror.c	(revision 398)
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include <netdb.h>
+#include "locale_impl.h"
+
+static const char msgs[] =
+	"Host not found\0"
+	"Try again\0"
+	"Non-recoverable error\0"
+	"Address not available\0"
+	"\0Unknown error";
+
+const char *hstrerror(int ecode)
+{
+	const char *s;
+	for (s=msgs, ecode--; ecode && *s; ecode--, s++) for (; *s; s++);
+	if (!*s) s++;
+	return LCTRANS_CUR(s);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/htonl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/htonl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/htonl.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <netinet/in.h>
+#include <byteswap.h>
+
+uint32_t htonl(uint32_t n)
+{
+	union { int i; char c; } u = { 1 };
+	return u.c ? bswap_32(n) : n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/htons.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/htons.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/htons.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <netinet/in.h>
+#include <byteswap.h>
+
+uint16_t htons(uint16_t n)
+{
+	union { int i; char c; } u = { 1 };
+	return u.c ? bswap_16(n) : n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_freenameindex.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_freenameindex.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_freenameindex.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <net/if.h>
+#include <stdlib.h>
+
+void if_freenameindex(struct if_nameindex *idx)
+{
+	free(idx);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_indextoname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_indextoname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_indextoname.c	(revision 398)
@@ -0,0 +1,23 @@
+#define _GNU_SOURCE
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <errno.h>
+#include "syscall.h"
+
+char *if_indextoname(unsigned index, char *name)
+{
+	struct ifreq ifr;
+	int fd, r;
+
+	if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
+	ifr.ifr_ifindex = index;
+	r = ioctl(fd, SIOCGIFNAME, &ifr);
+	__syscall(SYS_close, fd);
+	if (r < 0) {
+		if (errno == ENODEV) errno = ENXIO;
+		return 0;
+	}
+	return strncpy(name, ifr.ifr_name, IF_NAMESIZE);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_nameindex.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_nameindex.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_nameindex.c	(revision 398)
@@ -0,0 +1,114 @@
+#define _GNU_SOURCE
+#include <net/if.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "netlink.h"
+
+#define IFADDRS_HASH_SIZE 64
+
+struct ifnamemap {
+	unsigned int hash_next;
+	unsigned int index;
+	unsigned char namelen;
+	char name[IFNAMSIZ];
+};
+
+struct ifnameindexctx {
+	unsigned int num, allocated, str_bytes;
+	struct ifnamemap *list;
+	unsigned int hash[IFADDRS_HASH_SIZE];
+};
+
+static int netlink_msg_to_nameindex(void *pctx, struct nlmsghdr *h)
+{
+	struct ifnameindexctx *ctx = pctx;
+	struct ifnamemap *map;
+	struct rtattr *rta;
+	unsigned int i;
+	int index, type, namelen, bucket;
+
+	if (h->nlmsg_type == RTM_NEWLINK) {
+		struct ifinfomsg *ifi = NLMSG_DATA(h);
+		index = ifi->ifi_index;
+		type = IFLA_IFNAME;
+		rta = NLMSG_RTA(h, sizeof(*ifi));
+	} else {
+		struct ifaddrmsg *ifa = NLMSG_DATA(h);
+		index = ifa->ifa_index;
+		type = IFA_LABEL;
+		rta = NLMSG_RTA(h, sizeof(*ifa));
+	}
+	for (; NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
+		if (rta->rta_type != type) continue;
+
+		namelen = RTA_DATALEN(rta) - 1;
+		if (namelen > IFNAMSIZ) return 0;
+
+		/* suppress duplicates */
+		bucket = index % IFADDRS_HASH_SIZE;
+		i = ctx->hash[bucket];
+		while (i) {
+			map = &ctx->list[i-1];
+			if (map->index == index &&
+			    map->namelen == namelen &&
+			    memcmp(map->name, RTA_DATA(rta), namelen) == 0)
+				return 0;
+			i = map->hash_next;
+		}
+
+		if (ctx->num >= ctx->allocated) {
+			size_t a = ctx->allocated ? ctx->allocated * 2 + 1 : 8;
+			if (a > SIZE_MAX/sizeof *map) return -1;
+			map = realloc(ctx->list, a * sizeof *map);
+			if (!map) return -1;
+			ctx->list = map;
+			ctx->allocated = a;
+		}
+		map = &ctx->list[ctx->num];
+		map->index = index;
+		map->namelen = namelen;
+		memcpy(map->name, RTA_DATA(rta), namelen);
+		ctx->str_bytes += namelen + 1;
+		ctx->num++;
+		map->hash_next = ctx->hash[bucket];
+		ctx->hash[bucket] = ctx->num;
+		return 0;
+	}
+	return 0;
+}
+
+struct if_nameindex *if_nameindex()
+{
+	struct ifnameindexctx _ctx, *ctx = &_ctx;
+	struct if_nameindex *ifs = 0, *d;
+	struct ifnamemap *s;
+	char *p;
+	int i;
+	int cs;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	memset(ctx, 0, sizeof(*ctx));
+	if (__rtnetlink_enumerate(AF_UNSPEC, AF_INET, netlink_msg_to_nameindex, ctx) < 0) goto err;
+
+	ifs = malloc(sizeof(struct if_nameindex[ctx->num+1]) + ctx->str_bytes);
+	if (!ifs) goto err;
+
+	p = (char*)(ifs + ctx->num + 1);
+	for (i = ctx->num, d = ifs, s = ctx->list; i; i--, s++, d++) {
+		d->if_index = s->index;
+		d->if_name = p;
+		memcpy(p, s->name, s->namelen);
+		p += s->namelen;
+		*p++ = 0;
+	}
+	d->if_index = 0;
+	d->if_name = 0;
+err:
+	pthread_setcancelstate(cs, 0);
+	free(ctx->list);
+	errno = ENOBUFS;
+	return ifs;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_nametoindex.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_nametoindex.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/if_nametoindex.c	(revision 398)
@@ -0,0 +1,18 @@
+#define _GNU_SOURCE
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include "syscall.h"
+
+unsigned if_nametoindex(const char *name)
+{
+	struct ifreq ifr;
+	int fd, r;
+
+	if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
+	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
+	r = ioctl(fd, SIOCGIFINDEX, &ifr);
+	__syscall(SYS_close, fd);
+	return r < 0 ? 0 : ifr.ifr_ifindex;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/in6addr_any.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/in6addr_any.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/in6addr_any.c	(revision 398)
@@ -0,0 +1,3 @@
+#include <netinet/in.h>
+
+const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/in6addr_loopback.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/in6addr_loopback.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/in6addr_loopback.c	(revision 398)
@@ -0,0 +1,3 @@
+#include <netinet/in.h>
+
+const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_addr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_addr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_addr.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int __inet_aton(const char *, struct in_addr *);
+
+in_addr_t inet_addr(const char *p)
+{
+	struct in_addr a;
+	if (!__inet_aton(p, &a)) return -1;
+	return a.s_addr;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_aton.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_aton.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_aton.c	(revision 398)
@@ -0,0 +1,41 @@
+#include <ctype.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "libc.h"
+
+int __inet_aton(const char *s0, struct in_addr *dest)
+{
+	const char *s = s0;
+	unsigned char *d = (void *)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;
+}
+
+weak_alias(__inet_aton, inet_aton);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_legacy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_legacy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_legacy.c	(revision 398)
@@ -0,0 +1,32 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+in_addr_t inet_network(const char *p)
+{
+	return ntohl(inet_addr(p));
+}
+
+struct in_addr inet_makeaddr(in_addr_t n, in_addr_t h)
+{
+	if (n < 256) h |= n<<24;
+	else if (n < 65536) h |= n<<16;
+	else h |= n<<8;
+	return (struct in_addr){ h };
+}
+
+in_addr_t inet_lnaof(struct in_addr in)
+{
+	uint32_t h = in.s_addr;
+	if (h>>24 < 128) return h & 0xffffff;
+	if (h>>24 < 192) return h & 0xffff;
+	return h & 0xff;
+}
+
+in_addr_t inet_netof(struct in_addr in)
+{
+	uint32_t h = in.s_addr;
+	if (h>>24 < 128) return h >> 24;
+	if (h>>24 < 192) return h >> 16;
+	return h >> 8;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_ntoa.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_ntoa.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_ntoa.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <arpa/inet.h>
+#include <stdio.h>
+
+char *inet_ntoa(struct in_addr in)
+{
+	static char buf[16];
+	unsigned char *a = (void *)&in;
+	snprintf(buf, sizeof buf, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
+	return buf;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_ntop.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_ntop.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_ntop.c	(revision 398)
@@ -0,0 +1,54 @@
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen_t l)
+{
+	const unsigned char *a = a0;
+	int i, j, max, best;
+	char buf[100];
+
+	switch (af) {
+	case AF_INET:
+		if (snprintf(s, l, "%d.%d.%d.%d", a[0],a[1],a[2],a[3]) < l)
+			return s;
+		break;
+	case AF_INET6:
+		if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\377\377", 12))
+			snprintf(buf, sizeof buf,
+				"%x:%x:%x:%x:%x:%x:%x:%x",
+				256*a[0]+a[1],256*a[2]+a[3],
+				256*a[4]+a[5],256*a[6]+a[7],
+				256*a[8]+a[9],256*a[10]+a[11],
+				256*a[12]+a[13],256*a[14]+a[15]);
+		else
+			snprintf(buf, sizeof buf,
+				"%x:%x:%x:%x:%x:%x:%d.%d.%d.%d",
+				256*a[0]+a[1],256*a[2]+a[3],
+				256*a[4]+a[5],256*a[6]+a[7],
+				256*a[8]+a[9],256*a[10]+a[11],
+				a[12],a[13],a[14],a[15]);
+		/* Replace longest /(^0|:)[:0]{2,}/ with "::" */
+		for (i=best=0, max=2; buf[i]; i++) {
+			if (i && buf[i] != ':') continue;
+			j = strspn(buf+i, ":0");
+			if (j>max) best=i, max=j;
+		}
+		if (max>2) {
+			buf[best] = buf[best+1] = ':';
+			memmove(buf+best+2, buf+best+max, i-best-max+1);
+		}
+		if (strlen(buf) < l) {
+			strcpy(s, buf);
+			return s;
+		}
+		break;
+	default:
+		errno = EAFNOSUPPORT;
+		return 0;
+	}
+	errno = ENOSPC;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_pton.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_pton.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/inet_pton.c	(revision 398)
@@ -0,0 +1,71 @@
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+static int hexval(unsigned c)
+{
+	if (c-'0'<10) return c-'0';
+	c |= 32;
+	if (c-'a'<6) return c-'a'+10;
+	return -1;
+}
+
+int inet_pton(int af, const char *restrict s, void *restrict a0)
+{
+	uint16_t ip[8];
+	unsigned char *a = a0;
+	int i, j, v, d, brk=-1, need_v4=0;
+
+	if (af==AF_INET) {
+		for (i=0; i<4; i++) {
+			for (v=j=0; j<3 && isdigit(s[j]); j++)
+				v = 10*v + s[j]-'0';
+			if (j==0 || (j>1 && s[0]=='0') || v>255) return 0;
+			a[i] = v;
+			if (s[j]==0 && i==3) return 1;
+			if (s[j]!='.') return 0;
+			s += j+1;
+		}
+		return 0;
+	} else if (af!=AF_INET6) {
+		errno = EAFNOSUPPORT;
+		return -1;
+	}
+
+	if (*s==':' && *++s!=':') return 0;
+
+	for (i=0; ; i++) {
+		if (s[0]==':' && brk<0) {
+			brk=i;
+			ip[i&7]=0;
+			if (!*++s) break;
+			if (i==7) return 0;
+			continue;
+		}
+		for (v=j=0; j<4 && (d=hexval(s[j]))>=0; j++)
+			v=16*v+d;
+		if (j==0) return 0;
+		ip[i&7] = v;
+		if (!s[j] && (brk>=0 || i==7)) break;
+		if (i==7) return 0;
+		if (s[j]!=':') {
+			if (s[j]!='.' || (i<6 && brk<0)) return 0;
+			need_v4=1;
+			i++;
+			break;
+		}
+		s += j+1;
+	}
+	if (brk>=0) {
+		memmove(ip+brk+7-i, ip+brk, 2*(i+1-brk));
+		for (j=0; j<7-i; j++) ip[brk+j] = 0;
+	}
+	for (j=0; j<8; j++) {
+		*a++ = ip[j]>>8;
+		*a++ = ip[j];
+	}
+	if (need_v4 && inet_pton(AF_INET, (void *)s, a-4) <= 0) return 0;
+	return 1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/listen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/listen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/listen.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int listen(int fd, int backlog)
+{
+	return socketcall(listen, fd, backlog, 0, 0, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup.h	(revision 398)
@@ -0,0 +1,39 @@
+#ifndef LOOKUP_H
+#define LOOKUP_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+struct address {
+	int family;
+	unsigned scopeid;
+	uint8_t addr[16];
+	int sortkey;
+};
+
+struct service {
+	uint16_t port;
+	unsigned char proto, socktype;
+};
+
+#define MAXNS 3
+
+struct resolvconf {
+	struct address ns[MAXNS];
+	unsigned nns, attempts, ndots;
+	unsigned timeout;
+};
+
+/* The limit of 48 results is a non-sharp bound on the number of addresses
+ * that can fit in one 512-byte DNS packet full of v4 results and a second
+ * packet full of v6 results. Due to headers, the actual limit is lower. */
+#define MAXADDRS 48
+#define MAXSERVS 2
+
+int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags);
+int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags);
+int __lookup_ipliteral(struct address buf[static 1], const char *name, int family);
+
+int __get_resolv_conf(struct resolvconf *, char *, size_t);
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup_ipliteral.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup_ipliteral.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup_ipliteral.c	(revision 398)
@@ -0,0 +1,57 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "lookup.h"
+
+int __inet_aton(const char *, struct in_addr *);
+
+int __lookup_ipliteral(struct address buf[static 1], const char *name, int family)
+{
+	struct in_addr a4;
+	struct in6_addr a6;
+	if (__inet_aton(name, &a4) > 0) {
+		if (family == AF_INET6) /* wrong family */
+			return EAI_NONAME;
+		memcpy(&buf[0].addr, &a4, sizeof a4);
+		buf[0].family = AF_INET;
+		buf[0].scopeid = 0;
+		return 1;
+	}
+
+	char tmp[64];
+	char *p = strchr(name, '%'), *z;
+	unsigned long long scopeid = 0;
+	if (p && p-name < 64) {
+		memcpy(tmp, name, p-name);
+		tmp[p-name] = 0;
+		name = tmp;
+	}
+
+	if (inet_pton(AF_INET6, name, &a6) <= 0)
+		return 0;
+	if (family == AF_INET) /* wrong family */
+		return EAI_NONAME;
+
+	memcpy(&buf[0].addr, &a6, sizeof a6);
+	buf[0].family = AF_INET6;
+	if (p) {
+		if (isdigit(*++p)) scopeid = strtoull(p, &z, 10);
+		else z = p-1;
+		if (*z) {
+			if (!IN6_IS_ADDR_LINKLOCAL(&a6) &&
+			    !IN6_IS_ADDR_MC_LINKLOCAL(&a6))
+				return EAI_NONAME;
+			scopeid = if_nametoindex(p);
+			if (!scopeid) return EAI_NONAME;
+		}
+		if (scopeid > UINT_MAX) return EAI_NONAME;
+	}
+	buf[0].scopeid = scopeid;
+	return 1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup_name.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup_name.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup_name.c	(revision 398)
@@ -0,0 +1,421 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+#include <resolv.h>
+#include "lookup.h"
+#include "stdio_impl.h"
+#include "syscall.h"
+
+static int is_valid_hostname(const char *host)
+{
+	const unsigned char *s;
+	if (strnlen(host, 255)-1 >= 254 || mbstowcs(0, host, 0) == -1) return 0;
+	for (s=(void *)host; *s>=0x80 || *s=='.' || *s=='-' || isalnum(*s); s++);
+	return !*s;
+}
+
+static int name_from_null(struct address buf[static 2], const char *name, int family, int flags)
+{
+	int cnt = 0;
+	if (name) return 0;
+	if (flags & AI_PASSIVE) {
+		if (family != AF_INET6)
+			buf[cnt++] = (struct address){ .family = AF_INET };
+		if (family != AF_INET)
+			buf[cnt++] = (struct address){ .family = AF_INET6 };
+	} else {
+		if (family != AF_INET6)
+			buf[cnt++] = (struct address){ .family = AF_INET, .addr = { 127,0,0,1 } };
+		if (family != AF_INET)
+			buf[cnt++] = (struct address){ .family = AF_INET6, .addr = { [15] = 1 } };
+	}
+	return cnt;
+}
+
+static int name_from_numeric(struct address buf[static 1], const char *name, int family)
+{
+	return __lookup_ipliteral(buf, name, family);
+}
+
+static int name_from_hosts(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
+{
+	char line[512];
+	size_t l = strlen(name);
+	int cnt = 0, badfam = 0;
+	unsigned char _buf[1032];
+	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		return 0;
+	default:
+		return EAI_SYSTEM;
+	}
+	while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
+		char *p, *z;
+
+		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
+		for(p=line+1; (p=strstr(p, name)) &&
+			(!isspace(p[-1]) || !isspace(p[l])); p++);
+		if (!p) continue;
+
+		/* Isolate IP address to parse */
+		for (p=line; *p && !isspace(*p); p++);
+		*p++ = 0;
+		switch (name_from_numeric(buf+cnt, line, family)) {
+		case 1:
+			cnt++;
+			break;
+		case 0:
+			continue;
+		default:
+			badfam = EAI_NONAME;
+			continue;
+		}
+
+		/* Extract first name as canonical name */
+		for (; *p && isspace(*p); p++);
+		for (z=p; *z && !isspace(*z); z++);
+		*z = 0;
+		if (is_valid_hostname(p)) memcpy(canon, p, z-p+1);
+	}
+	__fclose_ca(f);
+	return cnt ? cnt : badfam;
+}
+
+struct dpc_ctx {
+	struct address *addrs;
+	char *canon;
+	int cnt;
+};
+
+int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *);
+int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
+int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
+int __res_msend_rc(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int, const struct resolvconf *);
+
+#define RR_A 1
+#define RR_CNAME 5
+#define RR_AAAA 28
+
+static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
+{
+	char tmp[256];
+	struct dpc_ctx *ctx = c;
+	if (ctx->cnt >= MAXADDRS) return -1;
+	switch (rr) {
+	case RR_A:
+		if (len != 4) return -1;
+		ctx->addrs[ctx->cnt].family = AF_INET;
+		ctx->addrs[ctx->cnt].scopeid = 0;
+		memcpy(ctx->addrs[ctx->cnt++].addr, data, 4);
+		break;
+	case RR_AAAA:
+		if (len != 16) return -1;
+		ctx->addrs[ctx->cnt].family = AF_INET6;
+		ctx->addrs[ctx->cnt].scopeid = 0;
+		memcpy(ctx->addrs[ctx->cnt++].addr, data, 16);
+		break;
+	case RR_CNAME:
+		if (__dn_expand(packet, (const unsigned char *)packet + 512,
+		    data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))
+			strcpy(ctx->canon, tmp);
+		break;
+	}
+	return 0;
+}
+
+static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf)
+{
+	unsigned char qbuf[2][280], abuf[2][512];
+	const unsigned char *qp[2] = { qbuf[0], qbuf[1] };
+	unsigned char *ap[2] = { abuf[0], abuf[1] };
+	int qlens[2], alens[2];
+	int i, nq = 0;
+	struct dpc_ctx ctx = { .addrs = buf, .canon = canon };
+	static const struct { int af; int rr; } afrr[2] = {
+		{ .af = AF_INET6, .rr = RR_A },
+		{ .af = AF_INET, .rr = RR_AAAA },
+	};
+
+	for (i=0; i<2; i++) {
+		if (family != afrr[i].af) {
+			qlens[nq] = __res_mkquery(0, name, 1, afrr[i].rr,
+				0, 0, 0, qbuf[nq], sizeof *qbuf);
+			if (qlens[nq] == -1)
+				return EAI_NONAME;
+			nq++;
+		}
+	}
+
+	if (__res_msend_rc(nq, qp, qlens, ap, alens, sizeof *abuf, conf) < 0)
+		return EAI_SYSTEM;
+
+	for (i=0; i<nq; i++)
+		__dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
+
+	if (ctx.cnt) return ctx.cnt;
+	if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN;
+	if ((abuf[0][3] & 15) == 0) return EAI_NONAME;
+	if ((abuf[0][3] & 15) == 3) return 0;
+	return EAI_FAIL;
+}
+
+static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
+{
+	char search[256];
+	struct resolvconf conf;
+	size_t l, dots;
+	char *p, *z;
+
+	if (__get_resolv_conf(&conf, search, sizeof search) < 0) return -1;
+
+	/* Count dots, suppress search when >=ndots or name ends in
+	 * a dot, which is an explicit request for global scope. */
+	for (dots=l=0; name[l]; l++) if (name[l]=='.') dots++;
+	if (dots >= conf.ndots || name[l-1]=='.') *search = 0;
+
+	/* Strip final dot for canon, fail if multiple trailing dots. */
+	if (name[l-1]=='.') l--;
+	if (!l || name[l-1]=='.') return EAI_NONAME;
+
+	/* This can never happen; the caller already checked length. */
+	if (l >= 256) return EAI_NONAME;
+
+	/* Name with search domain appended is setup in canon[]. This both
+	 * provides the desired default canonical name (if the requested
+	 * name is not a CNAME record) and serves as a buffer for passing
+	 * the full requested name to name_from_dns. */
+	memcpy(canon, name, l);
+	canon[l] = '.';
+
+	for (p=search; *p; p=z) {
+		for (; isspace(*p); p++);
+		for (z=p; *z && !isspace(*z); z++);
+		if (z==p) break;
+		if (z-p < 256 - l - 1) {
+			memcpy(canon+l+1, p, z-p);
+			canon[z-p+1+l] = 0;
+			int cnt = name_from_dns(buf, canon, canon, family, &conf);
+			if (cnt) return cnt;
+		}
+	}
+
+	canon[l] = 0;
+	return name_from_dns(buf, canon, name, family, &conf);
+}
+
+static const struct policy {
+	unsigned char addr[16];
+	unsigned char len, mask;
+	unsigned char prec, label;
+} defpolicy[] = {
+	{ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1", 15, 0xff, 50, 0 },
+	{ "\0\0\0\0\0\0\0\0\0\0\xff\xff", 11, 0xff, 35, 4 },
+	{ "\x20\2", 1, 0xff, 30, 2 },
+	{ "\x20\1", 3, 0xff, 5, 5 },
+	{ "\xfc", 0, 0xfe, 3, 13 },
+#if 0
+	/* These are deprecated and/or returned to the address
+	 * pool, so despite the RFC, treating them as special
+	 * is probably wrong. */
+	{ "", 11, 0xff, 1, 3 },
+	{ "\xfe\xc0", 1, 0xc0, 1, 11 },
+	{ "\x3f\xfe", 1, 0xff, 1, 12 },
+#endif
+	/* Last rule must match all addresses to stop loop. */
+	{ "", 0, 0, 40, 1 },
+};
+
+static const struct policy *policyof(const struct in6_addr *a)
+{
+	int i;
+	for (i=0; ; i++) {
+		if (memcmp(a->s6_addr, defpolicy[i].addr, defpolicy[i].len))
+			continue;
+		if ((a->s6_addr[defpolicy[i].len] & defpolicy[i].mask)
+		    != defpolicy[i].addr[defpolicy[i].len])
+			continue;
+		return defpolicy+i;
+	}
+}
+
+static int labelof(const struct in6_addr *a)
+{
+	return policyof(a)->label;
+}
+
+static int scopeof(const struct in6_addr *a)
+{
+	if (IN6_IS_ADDR_MULTICAST(a)) return a->s6_addr[1] & 15;
+	if (IN6_IS_ADDR_LINKLOCAL(a)) return 2;
+	if (IN6_IS_ADDR_LOOPBACK(a)) return 2;
+	if (IN6_IS_ADDR_SITELOCAL(a)) return 5;
+	return 14;
+}
+
+static int prefixmatch(const struct in6_addr *s, const struct in6_addr *d)
+{
+	/* FIXME: The common prefix length should be limited to no greater
+	 * than the nominal length of the prefix portion of the source
+	 * address. However the definition of the source prefix length is
+	 * not clear and thus this limiting is not yet implemented. */
+	unsigned i;
+	for (i=0; i<128 && !((s->s6_addr[i/8]^d->s6_addr[i/8])&(128>>(i%8))); i++);
+	return i;
+}
+
+#define DAS_USABLE              0x40000000
+#define DAS_MATCHINGSCOPE       0x20000000
+#define DAS_MATCHINGLABEL       0x10000000
+#define DAS_PREC_SHIFT          20
+#define DAS_SCOPE_SHIFT         16
+#define DAS_PREFIX_SHIFT        8
+#define DAS_ORDER_SHIFT         0
+
+static int addrcmp(const void *_a, const void *_b)
+{
+	const struct address *a = _a, *b = _b;
+	return b->sortkey - a->sortkey;
+}
+
+int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags)
+{
+	int cnt = 0, i, j;
+
+	*canon = 0;
+	if (name) {
+		/* reject empty name and check len so it fits into temp bufs */
+		size_t l = strnlen(name, 255);
+		if (l-1 >= 254)
+			return EAI_NONAME;
+		memcpy(canon, name, l+1);
+	}
+
+	/* Procedurally, a request for v6 addresses with the v4-mapped
+	 * flag set is like a request for unspecified family, followed
+	 * by filtering of the results. */
+	if (flags & AI_V4MAPPED) {
+		if (family == AF_INET6) family = AF_UNSPEC;
+		else flags -= AI_V4MAPPED;
+	}
+
+	/* Try each backend until there's at least one result. */
+	cnt = name_from_null(buf, name, family, flags);
+	if (!cnt) cnt = name_from_numeric(buf, name, family);
+	if (!cnt && !(flags & AI_NUMERICHOST)) {
+		cnt = name_from_hosts(buf, canon, name, family);
+		if (cnt<=0) cnt = name_from_dns_search(buf, canon, name, family);
+	}
+	if (cnt<=0) return cnt ? cnt : EAI_NONAME;
+
+	/* Filter/transform results for v4-mapped lookup, if requested. */
+	if (flags & AI_V4MAPPED) {
+		if (!(flags & AI_ALL)) {
+			/* If any v6 results exist, remove v4 results. */
+			for (i=0; i<cnt && buf[i].family != AF_INET6; i++);
+			if (i<cnt) {
+				for (j=0; i<cnt; i++) {
+					if (buf[i].family == AF_INET6)
+						buf[j++] = buf[i];
+				}
+				cnt = i = j;
+			}
+		}
+		/* Translate any remaining v4 results to v6 */
+		for (i=0; i<cnt; i++) {
+			if (buf[i].family != AF_INET) continue;
+			memcpy(buf[i].addr+12, buf[i].addr, 4);
+			memcpy(buf[i].addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			buf[i].family = AF_INET6;
+		}
+	}
+
+	/* No further processing is needed if there are fewer than 2
+	 * results or if there are only IPv4 results. */
+	if (cnt<2 || family==AF_INET) return cnt;
+	for (i=0; i<cnt; i++) if (buf[i].family != AF_INET) break;
+	if (i==cnt) return cnt;
+
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	/* The following implements a subset of RFC 3484/6724 destination
+	 * address selection by generating a single 31-bit sort key for
+	 * each address. Rules 3, 4, and 7 are omitted for having
+	 * excessive runtime and code size cost and dubious benefit.
+	 * So far the label/precedence table cannot be customized. */
+	for (i=0; i<cnt; i++) {
+		int family = buf[i].family;
+		int key = 0;
+		struct sockaddr_in6 sa6 = { 0 }, da6 = {
+			.sin6_family = AF_INET6,
+			.sin6_scope_id = buf[i].scopeid,
+			.sin6_port = 65535
+		};
+		struct sockaddr_in sa4 = { 0 }, da4 = {
+			.sin_family = AF_INET,
+			.sin_port = 65535
+		};
+		void *sa, *da;
+		socklen_t salen, dalen;
+		if (family == AF_INET6) {
+			memcpy(da6.sin6_addr.s6_addr, buf[i].addr, 16);
+			da = &da6; dalen = sizeof da6;
+			sa = &sa6; salen = sizeof sa6;
+		} else {
+			memcpy(sa6.sin6_addr.s6_addr,
+				"\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4);
+			memcpy(da6.sin6_addr.s6_addr,
+				"\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4);
+			memcpy(&da4.sin_addr, buf[i].addr, 4);
+			da = &da4; dalen = sizeof da4;
+			sa = &sa4; salen = sizeof sa4;
+		}
+		const struct policy *dpolicy = policyof(&da6.sin6_addr);
+		int dscope = scopeof(&da6.sin6_addr);
+		int dlabel = dpolicy->label;
+		int dprec = dpolicy->prec;
+		int prefixlen = 0;
+		int fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP);
+		if (fd >= 0) {
+			if (!connect(fd, da, dalen)) {
+				key |= DAS_USABLE;
+				if (!getsockname(fd, sa, &salen)) {
+					if (family == AF_INET) memcpy(
+						sa6.sin6_addr.s6_addr+12,
+						&sa4.sin_addr, 4);
+					if (dscope == scopeof(&sa6.sin6_addr))
+						key |= DAS_MATCHINGSCOPE;
+					if (dlabel == labelof(&sa6.sin6_addr))
+						key |= DAS_MATCHINGLABEL;
+					prefixlen = prefixmatch(&sa6.sin6_addr,
+						&da6.sin6_addr);
+				}
+			}
+			close(fd);
+		}
+		key |= dprec << DAS_PREC_SHIFT;
+		key |= (15-dscope) << DAS_SCOPE_SHIFT;
+		key |= prefixlen << DAS_PREFIX_SHIFT;
+		key |= (MAXADDRS-i) << DAS_ORDER_SHIFT;
+		buf[i].sortkey = key;
+	}
+	qsort(buf, cnt, sizeof *buf, addrcmp);
+
+	pthread_setcancelstate(cs, 0);
+
+	return cnt;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup_serv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup_serv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/lookup_serv.c	(revision 398)
@@ -0,0 +1,113 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "lookup.h"
+#include "stdio_impl.h"
+
+int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags)
+{
+	char line[128];
+	int cnt = 0;
+	char *p, *z = "";
+	unsigned long port = 0;
+
+	switch (socktype) {
+	case SOCK_STREAM:
+		switch (proto) {
+		case 0:
+			proto = IPPROTO_TCP;
+		case IPPROTO_TCP:
+			break;
+		default:
+			return EAI_SERVICE;
+		}
+		break;
+	case SOCK_DGRAM:
+		switch (proto) {
+		case 0:
+			proto = IPPROTO_UDP;
+		case IPPROTO_UDP:
+			break;
+		default:
+			return EAI_SERVICE;
+		}
+	case 0:
+		break;
+	default:
+		if (name) return EAI_SERVICE;
+		buf[0].port = 0;
+		buf[0].proto = proto;
+		buf[0].socktype = socktype;
+		return 1;
+	}
+
+	if (name) {
+		if (!*name) return EAI_SERVICE;
+		port = strtoul(name, &z, 10);
+	}
+	if (!*z) {
+		if (port > 65535) return EAI_SERVICE;
+		if (proto != IPPROTO_UDP) {
+			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_STREAM;
+			buf[cnt++].proto = IPPROTO_TCP;
+		}
+		if (proto != IPPROTO_TCP) {
+			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_DGRAM;
+			buf[cnt++].proto = IPPROTO_UDP;
+		}
+		return cnt;
+	}
+
+	if (flags & AI_NUMERICSERV) return EAI_SERVICE;
+
+	size_t l = strlen(name);
+
+	unsigned char _buf[1032];
+	FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		return EAI_SERVICE;
+	default:
+		return EAI_SYSTEM;
+	}
+
+	while (fgets(line, sizeof line, f) && cnt < MAXSERVS) {
+		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
+
+		/* Find service name */
+		for(p=line; (p=strstr(p, name)); p++) {
+			if (p>line && !isspace(p[-1])) continue;
+			if (p[l] && !isspace(p[l])) continue;
+			break;
+		}
+		if (!p) continue;
+
+		/* Skip past canonical name at beginning of line */
+		for (p=line; *p && !isspace(*p); p++);
+
+		port = strtoul(p, &z, 10);
+		if (port > 65535 || z==p) continue;
+		if (!strncmp(z, "/udp", 4)) {
+			if (proto == IPPROTO_TCP) continue;
+			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_DGRAM;
+			buf[cnt++].proto = IPPROTO_UDP;
+		}
+		if (!strncmp(z, "/tcp", 4)) {
+			if (proto == IPPROTO_UDP) continue;
+			buf[cnt].port = port;
+			buf[cnt].socktype = SOCK_STREAM;
+			buf[cnt++].proto = IPPROTO_TCP;
+		}
+	}
+	__fclose_ca(f);
+	return cnt > 0 ? cnt : EAI_SERVICE;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/netlink.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/netlink.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/netlink.c	(revision 398)
@@ -0,0 +1,52 @@
+#include <errno.h>
+#include <string.h>
+#include <syscall.h>
+#include <sys/socket.h>
+#include "netlink.h"
+
+static int __netlink_enumerate(int fd, unsigned int seq, int type, int af,
+	int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
+{
+	struct nlmsghdr *h;
+	union {
+		uint8_t buf[8192];
+		struct {
+			struct nlmsghdr nlh;
+			struct rtgenmsg g;
+		} req;
+		struct nlmsghdr reply;
+	} u;
+	int r, ret;
+
+	memset(&u.req, 0, sizeof(u.req));
+	u.req.nlh.nlmsg_len = sizeof(u.req);
+	u.req.nlh.nlmsg_type = type;
+	u.req.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
+	u.req.nlh.nlmsg_seq = seq;
+	u.req.g.rtgen_family = af;
+	r = send(fd, &u.req, sizeof(u.req), 0);
+	if (r < 0) return r;
+
+	while (1) {
+		r = recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT);
+		if (r <= 0) return -1;
+		for (h = &u.reply; NLMSG_OK(h, (void*)&u.buf[r]); h = NLMSG_NEXT(h)) {
+			if (h->nlmsg_type == NLMSG_DONE) return 0;
+			if (h->nlmsg_type == NLMSG_ERROR) return -1;
+			ret = cb(ctx, h);
+			if (ret) return ret;
+		}
+	}
+}
+
+int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
+{
+	int fd, r;
+
+	fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
+	if (fd < 0) return -1;
+	r = __netlink_enumerate(fd, 1, RTM_GETLINK, link_af, cb, ctx);
+	if (!r) r = __netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx);
+	__syscall(SYS_close,fd);
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/netlink.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/netlink.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/netlink.h	(revision 398)
@@ -0,0 +1,94 @@
+#include <stdint.h>
+
+/* linux/netlink.h */
+
+#define NETLINK_ROUTE 0
+
+struct nlmsghdr {
+	uint32_t	nlmsg_len;
+	uint16_t	nlmsg_type;
+	uint16_t	nlmsg_flags;
+	uint32_t	nlmsg_seq;
+	uint32_t	nlmsg_pid;
+};
+
+#define NLM_F_REQUEST	1
+#define NLM_F_MULTI	2
+#define NLM_F_ACK	4
+
+#define NLM_F_ROOT	0x100
+#define NLM_F_MATCH	0x200
+#define NLM_F_ATOMIC	0x400
+#define NLM_F_DUMP	(NLM_F_ROOT|NLM_F_MATCH)
+
+#define NLMSG_NOOP	0x1
+#define NLMSG_ERROR	0x2
+#define NLMSG_DONE	0x3
+#define NLMSG_OVERRUN	0x4
+
+/* linux/rtnetlink.h */
+
+#define RTM_NEWLINK	16
+#define RTM_GETLINK	18
+#define RTM_NEWADDR	20
+#define RTM_GETADDR	22
+
+struct rtattr {
+	unsigned short	rta_len;
+	unsigned short	rta_type;
+};
+
+struct rtgenmsg {
+	unsigned char	rtgen_family;
+};
+
+struct ifinfomsg {
+	unsigned char	ifi_family;
+	unsigned char	__ifi_pad;
+	unsigned short	ifi_type;
+	int		ifi_index;
+	unsigned	ifi_flags;
+	unsigned	ifi_change;
+};
+
+/* linux/if_link.h */
+
+#define IFLA_ADDRESS	1
+#define IFLA_BROADCAST	2
+#define IFLA_IFNAME	3
+#define IFLA_STATS	7
+
+/* linux/if_addr.h */
+
+struct ifaddrmsg {
+	uint8_t		ifa_family;
+	uint8_t		ifa_prefixlen;
+	uint8_t		ifa_flags;
+	uint8_t		ifa_scope;
+	uint32_t	ifa_index;
+};
+
+#define IFA_ADDRESS	1
+#define IFA_LOCAL	2
+#define IFA_LABEL	3
+#define IFA_BROADCAST	4
+
+/* musl */
+
+#define NETLINK_ALIGN(len)	(((len)+3) & ~3)
+#define NLMSG_DATA(nlh)		((void*)((char*)(nlh)+sizeof(struct nlmsghdr)))
+#define NLMSG_DATALEN(nlh)	((nlh)->nlmsg_len-sizeof(struct nlmsghdr))
+#define NLMSG_DATAEND(nlh)	((char*)(nlh)+(nlh)->nlmsg_len)
+#define NLMSG_NEXT(nlh)		(struct nlmsghdr*)((char*)(nlh)+NETLINK_ALIGN((nlh)->nlmsg_len))
+#define NLMSG_OK(nlh,end)	((char*)(end)-(char*)(nlh) >= sizeof(struct nlmsghdr))
+
+#define RTA_DATA(rta)		((void*)((char*)(rta)+sizeof(struct rtattr)))
+#define RTA_DATALEN(rta)	((rta)->rta_len-sizeof(struct rtattr))
+#define RTA_DATAEND(rta)	((char*)(rta)+(rta)->rta_len)
+#define RTA_NEXT(rta)		(struct rtattr*)((char*)(rta)+NETLINK_ALIGN((rta)->rta_len))
+#define RTA_OK(nlh,end)		((char*)(end)-(char*)(rta) >= sizeof(struct rtattr))
+
+#define NLMSG_RTA(nlh,len)	((void*)((char*)(nlh)+sizeof(struct nlmsghdr)+NETLINK_ALIGN(len)))
+#define NLMSG_RTAOK(rta,nlh)	RTA_OK(rta,NLMSG_DATAEND(nlh))
+
+int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/netname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/netname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/netname.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <netdb.h>
+
+struct netent *getnetbyaddr(uint32_t net, int type)
+{
+	return 0;
+}
+
+struct netent *getnetbyname(const char *name)
+{
+	return 0;
+}
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ns_parse.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ns_parse.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ns_parse.c	(revision 398)
@@ -0,0 +1,171 @@
+#define _BSD_SOURCE
+#include <errno.h>
+#include <stddef.h>
+#include <resolv.h>
+#include <arpa/nameser.h>
+
+const struct _ns_flagdata _ns_flagdata[16] = {
+	{ 0x8000, 15 },
+	{ 0x7800, 11 },
+	{ 0x0400, 10 },
+	{ 0x0200, 9 },
+	{ 0x0100, 8 },
+	{ 0x0080, 7 },
+	{ 0x0040, 6 },
+	{ 0x0020, 5 },
+	{ 0x0010, 4 },
+	{ 0x000f, 0 },
+	{ 0x0000, 0 },
+	{ 0x0000, 0 },
+	{ 0x0000, 0 },
+	{ 0x0000, 0 },
+	{ 0x0000, 0 },
+	{ 0x0000, 0 },
+};
+
+unsigned ns_get16(const unsigned char *cp)
+{
+	return cp[0]<<8 | cp[1];
+}
+
+unsigned long ns_get32(const unsigned char *cp)
+{
+	return (unsigned)cp[0]<<24 | cp[1]<<16 | cp[2]<<8 | cp[3];
+}
+
+void ns_put16(unsigned s, unsigned char *cp)
+{
+	*cp++ = s>>8;
+	*cp++ = s;
+}
+
+void ns_put32(unsigned long l, unsigned char *cp)
+{
+	*cp++ = l>>24;
+	*cp++ = l>>16;
+	*cp++ = l>>8;
+	*cp++ = l;
+}
+
+int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle)
+{
+	int i, r;
+
+	handle->_msg = msg;
+	handle->_eom = msg + msglen;
+	if (msglen < (2 + ns_s_max) * NS_INT16SZ) goto bad;
+	NS_GET16(handle->_id, msg);
+	NS_GET16(handle->_flags, msg);
+	for (i = 0; i < ns_s_max; i++) NS_GET16(handle->_counts[i], msg);
+	for (i = 0; i < ns_s_max; i++) {
+		if (handle->_counts[i]) {
+			handle->_sections[i] = msg;
+			r = ns_skiprr(msg, handle->_eom, i, handle->_counts[i]);
+			if (r < 0) return -1;
+			msg += r;
+		} else {
+			handle->_sections[i] = NULL;
+		}
+	}
+	if (msg != handle->_eom) goto bad;
+	handle->_sect = ns_s_max;
+	handle->_rrnum = -1;
+	handle->_msg_ptr = NULL;
+	return 0;
+bad:
+	errno = EMSGSIZE;
+	return -1;
+}
+
+int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count)
+{
+	const unsigned char *p = ptr;
+	int r;
+
+	while (count--) {
+		r = dn_skipname(p, eom);
+		if (r < 0) goto bad;
+		if (r + 2 * NS_INT16SZ > eom - p) goto bad;
+		p += r + 2 * NS_INT16SZ;
+		if (section != ns_s_qd) {
+			if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad;
+			p += NS_INT32SZ;
+			NS_GET16(r, p);
+			if (r > eom - p) goto bad;
+			p += r;
+		}
+	}
+	return p - ptr;
+bad:
+	errno = EMSGSIZE;
+	return -1;
+}
+
+int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
+{
+	int r;
+
+	if (section < 0 || section >= ns_s_max) goto bad;
+	if (section != handle->_sect) {
+		handle->_sect = section;
+		handle->_rrnum = 0;
+		handle->_msg_ptr = handle->_sections[section];
+	}
+	if (rrnum == -1) rrnum = handle->_rrnum;
+	if (rrnum < 0 || rrnum >= handle->_counts[section]) goto bad;
+	if (rrnum < handle->_rrnum) {
+		handle->_rrnum = 0;
+		handle->_msg_ptr = handle->_sections[section];
+	}
+	if (rrnum > handle->_rrnum) {
+		r = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum);
+		if (r < 0) return -1;
+		handle->_msg_ptr += r;
+		handle->_rrnum = rrnum;
+	}
+	r = ns_name_uncompress(handle->_msg, handle->_eom, handle->_msg_ptr, rr->name, NS_MAXDNAME);
+	if (r < 0) return -1;
+	handle->_msg_ptr += r;
+	if (2 * NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
+	NS_GET16(rr->type, handle->_msg_ptr);
+	NS_GET16(rr->rr_class, handle->_msg_ptr);
+	if (section != ns_s_qd) {
+		if (NS_INT32SZ + NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
+		NS_GET32(rr->ttl, handle->_msg_ptr);
+		NS_GET16(rr->rdlength, handle->_msg_ptr);
+		if (rr->rdlength > handle->_eom - handle->_msg_ptr) goto size;
+		rr->rdata = handle->_msg_ptr;
+		handle->_msg_ptr += rr->rdlength;
+	} else {
+		rr->ttl = 0;
+		rr->rdlength = 0;
+		rr->rdata = NULL;
+	}
+	handle->_rrnum++;
+	if (handle->_rrnum > handle->_counts[section]) {
+		handle->_sect = section + 1;
+		if (handle->_sect == ns_s_max) {
+			handle->_rrnum = -1;
+			handle->_msg_ptr = NULL;
+		} else {
+			handle->_rrnum = 0;
+		}
+	}
+	return 0;
+bad:
+	errno = ENODEV;
+	return -1;
+size:
+	errno = EMSGSIZE;
+	return -1;
+}
+
+int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom,
+                       const unsigned char *src, char *dst, size_t dstsiz)
+{
+	int r;
+	r = dn_expand(msg, eom, src, dst, dstsiz);
+	if (r < 0) errno = EMSGSIZE;
+	return r;
+}
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ntohl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ntohl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ntohl.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <netinet/in.h>
+#include <byteswap.h>
+
+uint32_t ntohl(uint32_t n)
+{
+	union { int i; char c; } u = { 1 };
+	return u.c ? bswap_32(n) : n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ntohs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ntohs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/ntohs.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <netinet/in.h>
+#include <byteswap.h>
+
+uint16_t ntohs(uint16_t n)
+{
+	union { int i; char c; } u = { 1 };
+	return u.c ? bswap_16(n) : n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/proto.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/proto.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/proto.c	(revision 398)
@@ -0,0 +1,84 @@
+#include <netdb.h>
+#include <string.h>
+
+/* do we really need all these?? */
+
+static int idx;
+static const unsigned char protos[] = {
+	"\000ip\0"
+	"\001icmp\0"
+	"\002igmp\0"
+	"\003ggp\0"
+	"\004ipencap\0"
+	"\005st\0"
+	"\006tcp\0"
+	"\010egp\0"
+	"\014pup\0"
+	"\021udp\0"
+	"\024hmp\0"
+	"\026xns-idp\0"
+	"\033rdp\0"
+	"\035iso-tp4\0"
+	"\044xtp\0"
+	"\045ddp\0"
+	"\046idpr-cmtp\0"
+	"\051ipv6\0"
+	"\053ipv6-route\0"
+	"\054ipv6-frag\0"
+	"\055idrp\0"
+	"\056rsvp\0"
+	"\057gre\0"
+	"\062esp\0"
+	"\063ah\0"
+	"\071skip\0"
+	"\072ipv6-icmp\0"
+	"\073ipv6-nonxt\0"
+	"\074ipv6-opts\0"
+	"\111rspf\0"
+	"\121vmtp\0"
+	"\131ospf\0"
+	"\136ipip\0"
+	"\142encap\0"
+	"\147pim\0"
+	"\377raw"
+};
+
+void endprotoent(void)
+{
+	idx = 0;
+}
+
+void setprotoent(int stayopen)
+{
+	idx = 0;
+}
+
+struct protoent *getprotoent(void)
+{
+	static struct protoent p;
+	static const char *aliases;
+	if (idx >= sizeof protos) return NULL;
+	p.p_proto = protos[idx];
+	p.p_name = (char *)&protos[idx+1];
+	p.p_aliases = (char **)&aliases;
+	idx += strlen(p.p_name) + 2;
+	return &p;
+}
+
+struct protoent *getprotobyname(const char *name)
+{
+	struct protoent *p;
+	endprotoent();
+	do p = getprotoent();
+	while (p && strcmp(name, p->p_name));
+	return p;
+}
+
+struct protoent *getprotobynumber(int num)
+{
+	struct protoent *p;
+	endprotoent();
+	do p = getprotoent();
+	while (p && p->p_proto != num);
+	return p;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recv.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <sys/socket.h>
+
+ssize_t recv(int fd, void *buf, size_t len, int flags)
+{
+	return recvfrom(fd, buf, len, flags, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recvfrom.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recvfrom.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recvfrom.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t recvfrom(int fd, void *restrict buf, size_t len, int flags, struct sockaddr *restrict addr, socklen_t *restrict alen)
+{
+	return socketcall_cp(recvfrom, fd, buf, len, flags, addr, alen);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recvmmsg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recvmmsg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recvmmsg.c	(revision 398)
@@ -0,0 +1,15 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <limits.h>
+#include "syscall.h"
+
+int recvmmsg(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags, struct timespec *timeout)
+{
+#if LONG_MAX > INT_MAX
+	struct mmsghdr *mh = msgvec;
+	unsigned int i;
+	for (i = vlen; i; i--, mh++)
+		mh->msg_hdr.__pad1 = mh->msg_hdr.__pad2 = 0;
+#endif
+	return syscall_cp(SYS_recvmmsg, fd, msgvec, vlen, flags, timeout);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recvmsg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recvmsg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/recvmsg.c	(revision 398)
@@ -0,0 +1,22 @@
+#include <sys/socket.h>
+#include <limits.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t recvmsg(int fd, struct msghdr *msg, int flags)
+{
+	ssize_t r;
+#if LONG_MAX > INT_MAX
+	struct msghdr h, *orig = msg;
+	if (msg) {
+		h = *msg;
+		h.__pad1 = h.__pad2 = 0;
+		msg = &h;
+	}
+#endif
+	r = socketcall_cp(recvmsg, fd, msg, flags, 0, 0, 0);
+#if LONG_MAX > INT_MAX
+	if (orig) *orig = h;
+#endif
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_init.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <resolv.h>
+
+int res_init()
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_mkquery.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_mkquery.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_mkquery.c	(revision 398)
@@ -0,0 +1,44 @@
+#include <resolv.h>
+#include <string.h>
+#include <time.h>
+#include "libc.h"
+
+int __res_mkquery(int op, const char *dname, int class, int type,
+	const unsigned char *data, int datalen,
+	const unsigned char *newrr, unsigned char *buf, int buflen)
+{
+	int id, i, j;
+	unsigned char q[280];
+	struct timespec ts;
+	size_t l = strnlen(dname, 255);
+	int n;
+
+	if (l && dname[l-1]=='.') l--;
+	n = 17+l+!!l;
+	if (l>253 || buflen<n || op>15u || class>255u || type>255u)
+		return -1;
+
+	/* Construct query template - ID will be filled later */
+	memset(q, 0, n);
+	q[2] = op*8 + 1;
+	q[5] = 1;
+	memcpy((char *)q+13, dname, l);
+	for (i=13; q[i]; i=j+1) {
+		for (j=i; q[j] && q[j] != '.'; j++);
+		if (j-i-1u > 62u) return -1;
+		q[i-1] = j-i;
+	}
+	q[i+1] = type;
+	q[i+3] = class;
+
+	/* Make a reasonably unpredictable id */
+	clock_gettime(CLOCK_REALTIME, &ts);
+	id = ts.tv_nsec + ts.tv_nsec/65536UL & 0xffff;
+	q[0] = id/256;
+	q[1] = id;
+
+	memcpy(buf, q, n);
+	return n;
+}
+
+weak_alias(__res_mkquery, res_mkquery);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_msend.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_msend.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_msend.c	(revision 398)
@@ -0,0 +1,188 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <stdint.h>
+#include <string.h>
+#include <poll.h>
+#include <time.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include "stdio_impl.h"
+#include "syscall.h"
+#include "lookup.h"
+
+static void cleanup(void *p)
+{
+	__syscall(SYS_close, (intptr_t)p);
+}
+
+static unsigned long mtime()
+{
+	struct timespec ts;
+	clock_gettime(CLOCK_REALTIME, &ts);
+	return (unsigned long)ts.tv_sec * 1000
+		+ ts.tv_nsec / 1000000;
+}
+
+int __res_msend_rc(int nqueries, const unsigned char *const *queries,
+	const int *qlens, unsigned char *const *answers, int *alens, int asize,
+	const struct resolvconf *conf)
+{
+	int fd;
+	int timeout, attempts, retry_interval, servfail_retry;
+	union {
+		struct sockaddr_in sin;
+		struct sockaddr_in6 sin6;
+	} sa = {0}, ns[MAXNS] = {{0}};
+	socklen_t sl = sizeof sa.sin;
+	int nns = 0;
+	int family = AF_INET;
+	int rlen;
+	int next;
+	int i, j;
+	int cs;
+	struct pollfd pfd;
+	unsigned long t0, t1, t2;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	timeout = 1000*conf->timeout;
+	attempts = conf->attempts;
+
+	for (nns=0; nns<conf->nns; nns++) {
+		const struct address *iplit = &conf->ns[nns];
+		if (iplit->family == AF_INET) {
+			memcpy(&ns[nns].sin.sin_addr, iplit->addr, 4);
+			ns[nns].sin.sin_port = htons(53);
+			ns[nns].sin.sin_family = AF_INET;
+		} else {
+			sl = sizeof sa.sin6;
+			memcpy(&ns[nns].sin6.sin6_addr, iplit->addr, 16);
+			ns[nns].sin6.sin6_port = htons(53);
+			ns[nns].sin6.sin6_scope_id = iplit->scopeid;
+			ns[nns].sin6.sin6_family = family = AF_INET6;
+		}
+	}
+
+	/* Get local address and open/bind a socket */
+	sa.sin.sin_family = family;
+	fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+
+	/* Handle case where system lacks IPv6 support */
+	if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
+		fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
+		family = AF_INET;
+	}
+	if (fd < 0 || bind(fd, (void *)&sa, sl) < 0) {
+		if (fd >= 0) close(fd);
+		pthread_setcancelstate(cs, 0);
+		return -1;
+	}
+
+	/* Past this point, there are no errors. Each individual query will
+	 * yield either no reply (indicated by zero length) or an answer
+	 * packet which is up to the caller to interpret. */
+
+	pthread_cleanup_push(cleanup, (void *)(intptr_t)fd);
+	pthread_setcancelstate(cs, 0);
+
+	/* Convert any IPv4 addresses in a mixed environment to v4-mapped */
+	if (family == AF_INET6) {
+		setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);
+		for (i=0; i<nns; i++) {
+			if (ns[i].sin.sin_family != AF_INET) continue;
+			memcpy(ns[i].sin6.sin6_addr.s6_addr+12,
+				&ns[i].sin.sin_addr, 4);
+			memcpy(ns[i].sin6.sin6_addr.s6_addr,
+				"\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			ns[i].sin6.sin6_family = AF_INET6;
+			ns[i].sin6.sin6_flowinfo = 0;
+			ns[i].sin6.sin6_scope_id = 0;
+		}
+	}
+
+	memset(alens, 0, sizeof *alens * nqueries);
+
+	pfd.fd = fd;
+	pfd.events = POLLIN;
+	retry_interval = timeout / attempts;
+	next = 0;
+	t0 = t2 = mtime();
+	t1 = t2 - retry_interval;
+
+	for (; t2-t0 < timeout; t2=mtime()) {
+		if (t2-t1 >= retry_interval) {
+			/* Query all configured namservers in parallel */
+			for (i=0; i<nqueries; i++)
+				if (!alens[i])
+					for (j=0; j<nns; j++)
+						sendto(fd, queries[i],
+							qlens[i], MSG_NOSIGNAL,
+							(void *)&ns[j], sl);
+			t1 = t2;
+			servfail_retry = 2 * nqueries;
+		}
+
+		/* Wait for a response, or until time to retry */
+		if (poll(&pfd, 1, t1+retry_interval-t2) <= 0) continue;
+
+		while ((rlen = recvfrom(fd, answers[next], asize, 0,
+		  (void *)&sa, (socklen_t[1]){sl})) >= 0) {
+
+			/* Ignore non-identifiable packets */
+			if (rlen < 4) continue;
+
+			/* Ignore replies from addresses we didn't send to */
+			for (j=0; j<nns && memcmp(ns+j, &sa, sl); j++);
+			if (j==nns) continue;
+
+			/* Find which query this answer goes with, if any */
+			for (i=next; i<nqueries && (
+				answers[next][0] != queries[i][0] ||
+				answers[next][1] != queries[i][1] ); i++);
+			if (i==nqueries) continue;
+			if (alens[i]) continue;
+
+			/* Only accept positive or negative responses;
+			 * retry immediately on server failure, and ignore
+			 * all other codes such as refusal. */
+			switch (answers[next][3] & 15) {
+			case 0:
+			case 3:
+				break;
+			case 2:
+				if (servfail_retry && servfail_retry--)
+					sendto(fd, queries[i],
+						qlens[i], MSG_NOSIGNAL,
+						(void *)&ns[j], sl);
+			default:
+				continue;
+			}
+
+			/* Store answer in the right slot, or update next
+			 * available temp slot if it's already in place. */
+			alens[i] = rlen;
+			if (i == next)
+				for (; next<nqueries && alens[next]; next++);
+			else
+				memcpy(answers[i], answers[next], rlen);
+
+			if (next == nqueries) goto out;
+		}
+	}
+out:
+	pthread_cleanup_pop(1);
+
+	return 0;
+}
+
+int __res_msend(int nqueries, const unsigned char *const *queries,
+	const int *qlens, unsigned char *const *answers, int *alens, int asize)
+{
+	struct resolvconf conf;
+	if (__get_resolv_conf(&conf, 0, 0) < 0) return -1;
+	return __res_msend_rc(nqueries, queries, qlens, answers, alens, asize, &conf);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_query.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_query.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_query.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <resolv.h>
+#include <netdb.h>
+#include "libc.h"
+
+int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
+int __res_send(const unsigned char *, int, unsigned char *, int);
+
+int __res_query(const char *name, int class, int type, unsigned char *dest, int len)
+{
+	unsigned char q[280];
+	int ql = __res_mkquery(0, name, class, type, 0, 0, 0, q, sizeof q);
+	if (ql < 0) return ql;
+	return __res_send(q, ql, dest, len);
+}
+
+weak_alias(__res_query, res_query);
+weak_alias(__res_query, res_search);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_querydomain.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_querydomain.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_querydomain.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <resolv.h>
+#include <string.h>
+
+int res_querydomain(const char *name, const char *domain, int class, int type, unsigned char *dest, int len)
+{
+	char tmp[255];
+	size_t nl = strnlen(name, 255);
+	size_t dl = strnlen(domain, 255);
+	if (nl+dl+1 > 254) return -1;
+	memcpy(tmp, name, nl);
+	tmp[nl] = '.';
+	memcpy(tmp+nl+1, domain, dl+1);
+	return res_query(tmp, class, type, dest, len);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_send.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_send.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_send.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <resolv.h>
+#include "libc.h"
+
+int __res_msend(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int);
+
+int __res_send(const unsigned char *msg, int msglen, unsigned char *answer, int anslen)
+{
+	int r = __res_msend(1, &msg, &msglen, &answer, &anslen, anslen);
+	return r<0 ? r : anslen;
+}
+
+weak_alias(__res_send, res_send);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_state.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_state.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/res_state.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <resolv.h>
+
+/* This is completely unused, and exists purely to satisfy broken apps. */
+
+struct __res_state *__res_state()
+{
+	static struct __res_state res;
+	return &res;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/resolvconf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/resolvconf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/resolvconf.c	(revision 398)
@@ -0,0 +1,93 @@
+#include "lookup.h"
+#include "stdio_impl.h"
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <netinet/in.h>
+
+int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
+{
+	char line[256];
+	unsigned char _buf[256];
+	FILE *f, _f;
+	int nns = 0;
+
+	conf->ndots = 1;
+	conf->timeout = 5;
+	conf->attempts = 2;
+	if (search) *search = 0;
+
+	f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		goto no_resolv_conf;
+	default:
+		return -1;
+	}
+
+	while (fgets(line, sizeof line, f)) {
+		char *p, *z;
+		if (!strchr(line, '\n') && !feof(f)) {
+			/* Ignore lines that get truncated rather than
+			 * potentially misinterpreting them. */
+			int c;
+			do c = getc(f);
+			while (c != '\n' && c != EOF);
+			continue;
+		}
+		if (!strncmp(line, "options", 7) && isspace(line[7])) {
+			p = strstr(line, "ndots:");
+			if (p && isdigit(p[6])) {
+				p += 6;
+				unsigned long x = strtoul(p, &z, 10);
+				if (z != p) conf->ndots = x > 15 ? 15 : x;
+			}
+			p = strstr(line, "attempts:");
+			if (p && isdigit(p[9])) {
+				p += 9;
+				unsigned long x = strtoul(p, &z, 10);
+				if (z != p) conf->attempts = x > 10 ? 10 : x;
+			}
+			p = strstr(line, "timeout:");
+			if (p && (isdigit(p[8]) || p[8]=='.')) {
+				p += 8;
+				unsigned long x = strtoul(p, &z, 10);
+				if (z != p) conf->timeout = x > 60 ? 60 : x;
+			}
+			continue;
+		}
+		if (!strncmp(line, "nameserver", 10) && isspace(line[10])) {
+			if (nns >= MAXNS) continue;
+			for (p=line+11; isspace(*p); p++);
+			for (z=p; *z && !isspace(*z); z++);
+			*z=0;
+			if (__lookup_ipliteral(conf->ns+nns, p, AF_UNSPEC) > 0)
+				nns++;
+			continue;
+		}
+
+		if (!search) continue;
+		if ((strncmp(line, "domain", 6) && strncmp(line, "search", 6))
+		    || !isspace(line[6]))
+			continue;
+		for (p=line+7; isspace(*p); p++);
+		size_t l = strlen(p);
+		/* This can never happen anyway with chosen buffer sizes. */
+		if (l >= search_sz) continue;
+		memcpy(search, p, l+1);
+	}
+
+	__fclose_ca(f);
+
+no_resolv_conf:
+	if (!nns) {
+		__lookup_ipliteral(conf->ns, "127.0.0.1", AF_UNSPEC);
+		nns = 1;
+	}
+
+	conf->nns = nns;
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/send.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/send.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/send.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <sys/socket.h>
+
+ssize_t send(int fd, const void *buf, size_t len, int flags)
+{
+	return sendto(fd, buf, len, flags, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sendmmsg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sendmmsg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sendmmsg.c	(revision 398)
@@ -0,0 +1,30 @@
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <limits.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sendmmsg(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags)
+{
+#if LONG_MAX > INT_MAX
+	/* Can't use the syscall directly because the kernel has the wrong
+	 * idea for the types of msg_iovlen, msg_controllen, and cmsg_len,
+	 * and the cmsg blocks cannot be modified in-place. */
+	int i;
+	if (vlen > IOV_MAX) vlen = IOV_MAX; /* This matches the kernel. */
+	if (!vlen) return 0;
+	for (i=0; i<vlen; i++) {
+		/* As an unfortunate inconsistency, the sendmmsg API uses
+		 * unsigned int for the resulting msg_len, despite sendmsg
+		 * returning ssize_t. However Linux limits the total bytes
+		 * sent by sendmsg to INT_MAX, so the assignment is safe. */
+		ssize_t r = sendmsg(fd, &msgvec[i].msg_hdr, flags);
+		if (r < 0) goto error;
+		msgvec[i].msg_len = r;
+	}
+error:
+	return i ? i : -1;
+#else
+	return syscall_cp(SYS_sendmmsg, fd, msgvec, vlen, flags);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sendmsg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sendmsg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sendmsg.c	(revision 398)
@@ -0,0 +1,30 @@
+#include <sys/socket.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
+{
+#if LONG_MAX > INT_MAX
+	struct msghdr h;
+	struct cmsghdr chbuf[1024/sizeof(struct cmsghdr)+1], *c;
+	if (msg) {
+		h = *msg;
+		h.__pad1 = h.__pad2 = 0;
+		msg = &h;
+		if (h.msg_controllen) {
+			if (h.msg_controllen > 1024) {
+				errno = ENOMEM;
+				return -1;
+			}
+			memcpy(chbuf, h.msg_control, h.msg_controllen);
+			h.msg_control = chbuf;
+			for (c=CMSG_FIRSTHDR(&h); c; c=CMSG_NXTHDR(&h,c))
+				c->__pad1 = 0;
+		}
+	}
+#endif
+	return socketcall_cp(sendmsg, fd, msg, flags, 0, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sendto.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sendto.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sendto.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/socket.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
+{
+	return socketcall_cp(sendto, fd, buf, len, flags, addr, alen);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/serv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/serv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/serv.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <netdb.h>
+
+void endservent(void)
+{
+}
+
+void setservent(int stayopen)
+{
+}
+
+struct servent *getservent(void)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/setsockopt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/setsockopt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/setsockopt.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
+{
+	return socketcall(setsockopt, fd, level, optname, optval, optlen, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/shutdown.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/shutdown.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/shutdown.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/socket.h>
+#include "syscall.h"
+
+int shutdown(int fd, int how)
+{
+	return socketcall(shutdown, fd, how, 0, 0, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sockatmark.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sockatmark.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/sockatmark.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+int sockatmark(int s)
+{
+	int ret;
+	if (ioctl(s, SIOCATMARK, &ret) < 0)
+		return -1;
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/socket.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/socket.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/socket.c	(revision 398)
@@ -0,0 +1,21 @@
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int socket(int domain, int type, int protocol)
+{
+	int s = socketcall(socket, domain, type, protocol, 0, 0, 0);
+	if (s<0 && (errno==EINVAL || errno==EPROTONOSUPPORT)
+	    && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) {
+		s = socketcall(socket, domain,
+			type & ~(SOCK_CLOEXEC|SOCK_NONBLOCK),
+			protocol, 0, 0, 0);
+		if (s < 0) return s;
+		if (type & SOCK_CLOEXEC)
+			__syscall(SYS_fcntl, s, F_SETFD, FD_CLOEXEC);
+		if (type & SOCK_NONBLOCK)
+			__syscall(SYS_fcntl, s, F_SETFL, O_NONBLOCK);
+	}
+	return s;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/socketpair.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/socketpair.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/network/socketpair.c	(revision 398)
@@ -0,0 +1,25 @@
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int socketpair(int domain, int type, int protocol, int fd[2])
+{
+	int r = socketcall(socketpair, domain, type, protocol, fd, 0, 0);
+	if (r<0 && (errno==EINVAL || errno==EPROTONOSUPPORT)
+	    && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) {
+		r = socketcall(socketpair, domain,
+			type & ~(SOCK_CLOEXEC|SOCK_NONBLOCK),
+			protocol, fd, 0, 0);
+		if (r < 0) return r;
+		if (type & SOCK_CLOEXEC) {
+			__syscall(SYS_fcntl, fd[0], F_SETFD, FD_CLOEXEC);
+			__syscall(SYS_fcntl, fd[1], F_SETFD, FD_CLOEXEC);
+		}
+		if (type & SOCK_NONBLOCK) {
+			__syscall(SYS_fcntl, fd[0], F_SETFL, O_NONBLOCK);
+			__syscall(SYS_fcntl, fd[1], F_SETFL, O_NONBLOCK);
+		}
+	}
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/fgetgrent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/fgetgrent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/fgetgrent.c	(revision 398)
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include "pwf.h"
+
+struct group *fgetgrent(FILE *f)
+{
+	static char *line, **mem;
+	static struct group gr;
+	struct group *res;
+	size_t size=0, nmem=0;
+	__getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);
+	return res;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/fgetpwent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/fgetpwent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/fgetpwent.c	(revision 398)
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include "pwf.h"
+
+struct passwd *fgetpwent(FILE *f)
+{
+	static char *line;
+	static struct passwd pw;
+	size_t size=0;
+	struct passwd *res;
+	__getpwent_a(f, &pw, &line, &size, &res);
+	return res;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/fgetspent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/fgetspent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/fgetspent.c	(revision 398)
@@ -0,0 +1,15 @@
+#include "pwf.h"
+#include <pthread.h>
+
+struct spwd *fgetspent(FILE *f)
+{
+	static char *line;
+	static struct spwd sp;
+	size_t size = 0;
+	struct spwd *res = 0;
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	if (getline(&line, &size, f) >= 0 && __parsespent(line, &sp) >= 0) res = &sp;
+	pthread_setcancelstate(cs, 0);
+	return res;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgr_a.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgr_a.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgr_a.c	(revision 398)
@@ -0,0 +1,169 @@
+#include <pthread.h>
+#include <byteswap.h>
+#include <string.h>
+#include <unistd.h>
+#include "pwf.h"
+#include "nscd.h"
+
+static char *itoa(char *p, uint32_t x)
+{
+	// number of digits in a uint32_t + NUL
+	p += 11;
+	*--p = 0;
+	do {
+		*--p = '0' + x % 10;
+		x /= 10;
+	} while (x);
+	return p;
+}
+
+int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t *size, char ***mem, size_t *nmem, struct group **res)
+{
+	FILE *f;
+	int rv = 0;
+	int cs;
+
+	*res = 0;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	f = fopen("/etc/group", "rbe");
+	if (!f) {
+		rv = errno;
+		goto done;
+	}
+
+	while (!(rv = __getgrent_a(f, gr, buf, size, mem, nmem, res)) && *res) {
+		if (name && !strcmp(name, (*res)->gr_name)
+		|| !name && (*res)->gr_gid == gid) {
+			break;
+		}
+	}
+	fclose(f);
+
+	if (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) {
+		int32_t req = name ? GETGRBYNAME : GETGRBYGID;
+		int32_t i;
+		const char *key;
+		int32_t groupbuf[GR_LEN] = {0};
+		size_t len = 0;
+		size_t grlist_len = 0;
+		char gidbuf[11] = {0};
+		int swap = 0;
+		char *ptr;
+
+		if (name) {
+			key = name;
+		} else {
+			if (gid < 0 || gid > UINT32_MAX) {
+				rv = 0;
+				goto done;
+			}
+			key = itoa(gidbuf, gid);
+		}
+
+		f = __nscd_query(req, key, groupbuf, sizeof groupbuf, &swap);
+		if (!f) { rv = errno; goto done; }
+
+		if (!groupbuf[GRFOUND]) { rv = 0; goto cleanup_f; }
+
+		if (!groupbuf[GRNAMELEN] || !groupbuf[GRPASSWDLEN]) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+		if (groupbuf[GRNAMELEN] > SIZE_MAX - groupbuf[GRPASSWDLEN]) {
+			rv = ENOMEM;
+			goto cleanup_f;
+		}
+		len = groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN];
+
+		for (i = 0; i < groupbuf[GRMEMCNT]; i++) {
+			uint32_t name_len;
+			if (fread(&name_len, sizeof name_len, 1, f) < 1) {
+				rv = ferror(f) ? errno : EIO;
+				goto cleanup_f;
+			}
+			if (swap) {
+				name_len = bswap_32(name_len);
+			}
+			if (name_len > SIZE_MAX - grlist_len
+			|| name_len > SIZE_MAX - len) {
+				rv = ENOMEM;
+				goto cleanup_f;
+			}
+			len += name_len;
+			grlist_len += name_len;
+		}
+
+		if (len > *size || !*buf) {
+			char *tmp = realloc(*buf, len);
+			if (!tmp) {
+				rv = errno;
+				goto cleanup_f;
+			}
+			*buf = tmp;
+			*size = len;
+		}
+
+		if (!fread(*buf, len, 1, f)) {
+			rv = ferror(f) ? errno : EIO;
+			goto cleanup_f;
+		}
+
+		if (groupbuf[GRMEMCNT] + 1 > *nmem) {
+			if (groupbuf[GRMEMCNT] + 1 > SIZE_MAX/sizeof(char*)) {
+				rv = ENOMEM;
+				goto cleanup_f;
+			}
+			char **tmp = realloc(*mem, (groupbuf[GRMEMCNT]+1)*sizeof(char*));
+			if (!tmp) {
+				rv = errno;
+				goto cleanup_f;
+			}
+			*mem = tmp;
+			*nmem = groupbuf[GRMEMCNT] + 1;
+		}
+
+		if (groupbuf[GRMEMCNT]) {
+			mem[0][0] = *buf + groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN];
+			for (ptr = mem[0][0], i = 0; ptr != mem[0][0]+grlist_len; ptr++)
+				if (!*ptr) mem[0][++i] = ptr+1;
+			mem[0][i] = 0;
+
+			if (i != groupbuf[GRMEMCNT]) {
+				rv = EIO;
+				goto cleanup_f;
+			}
+		} else {
+			mem[0][0] = 0;
+		}
+
+		gr->gr_name = *buf;
+		gr->gr_passwd = gr->gr_name + groupbuf[GRNAMELEN];
+		gr->gr_gid = groupbuf[GRGID];
+		gr->gr_mem = *mem;
+
+		if (gr->gr_passwd[-1]
+		|| gr->gr_passwd[groupbuf[GRPASSWDLEN]-1]) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+		if (name && strcmp(name, gr->gr_name)
+		|| !name && gid != gr->gr_gid) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+		*res = gr;
+
+cleanup_f:
+		fclose(f);
+		goto done;
+	}
+
+done:
+	pthread_setcancelstate(cs, 0);
+	if (rv) errno = rv;
+	return rv;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgr_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgr_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgr_r.c	(revision 398)
@@ -0,0 +1,49 @@
+#include "pwf.h"
+#include <pthread.h>
+
+#define FIX(x) (gr->gr_##x = gr->gr_##x-line+buf)
+
+static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	char *line = 0;
+	size_t len = 0;
+	char **mem = 0;
+	size_t nmem = 0;
+	int rv = 0;
+	size_t i;
+	int cs;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	rv = __getgr_a(name, gid, gr, &line, &len, &mem, &nmem, res);
+	if (*res && size < len + (nmem+1)*sizeof(char *) + 32) {
+		*res = 0;
+		rv = ERANGE;
+	}
+	if (*res) {
+		buf += (16-(uintptr_t)buf)%16;
+		gr->gr_mem = (void *)buf;
+		buf += (nmem+1)*sizeof(char *);
+		memcpy(buf, line, len);
+		FIX(name);
+		FIX(passwd);
+		for (i=0; mem[i]; i++)
+			gr->gr_mem[i] = mem[i]-line+buf;
+		gr->gr_mem[i] = 0;
+	}
+ 	free(mem);
+ 	free(line);
+	pthread_setcancelstate(cs, 0);
+	if (rv) errno = rv;
+	return rv;
+}
+
+int getgrnam_r(const char *name, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	return getgr_r(name, 0, gr, buf, size, res);
+}
+
+int getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	return getgr_r(0, gid, gr, buf, size, res);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgrent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgrent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgrent.c	(revision 398)
@@ -0,0 +1,39 @@
+#include "pwf.h"
+
+static FILE *f;
+static char *line, **mem;
+static struct group gr;
+
+void setgrent()
+{
+	if (f) fclose(f);
+	f = 0;
+}
+
+weak_alias(setgrent, endgrent);
+
+struct group *getgrent()
+{
+	struct group *res;
+	size_t size=0, nmem=0;
+	if (!f) f = fopen("/etc/group", "rbe");
+	if (!f) return 0;
+	__getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);
+	return res;
+}
+
+struct group *getgrgid(gid_t gid)
+{
+	struct group *res;
+	size_t size=0, nmem=0;
+	__getgr_a(0, gid, &gr, &line, &size, &mem, &nmem, &res);
+	return res;
+}
+
+struct group *getgrnam(const char *name)
+{
+	struct group *res;
+	size_t size=0, nmem=0;
+	__getgr_a(name, 0, &gr, &line, &size, &mem, &nmem, &res);
+	return res;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgrent_a.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgrent_a.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgrent_a.c	(revision 398)
@@ -0,0 +1,68 @@
+#include "pwf.h"
+#include <pthread.h>
+
+static unsigned atou(char **s)
+{
+	unsigned x;
+	for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
+	return x;
+}
+
+int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res)
+{
+	ssize_t l;
+	char *s, *mems;
+	size_t i;
+	int rv = 0;
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	for (;;) {
+		if ((l=getline(line, size, f)) < 0) {
+			rv = ferror(f) ? errno : 0;
+			free(*line);
+			*line = 0;
+			gr = 0;
+			goto end;
+		}
+		line[0][l-1] = 0;
+
+		s = line[0];
+		gr->gr_name = s++;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; gr->gr_passwd = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; gr->gr_gid = atou(&s);
+		if (*s != ':') continue;
+
+		*s++ = 0; mems = s;
+		break;
+	}
+
+	for (*nmem=!!*s; *s; s++)
+		if (*s==',') ++*nmem;
+	free(*mem);
+	*mem = calloc(sizeof(char *), *nmem+1);
+	if (!*mem) {
+		rv = errno;
+		free(*line);
+		*line = 0;
+		gr = 0;
+		goto end;
+	}
+	if (*mems) {
+		mem[0][0] = mems;
+		for (s=mems, i=0; *s; s++)
+			if (*s==',') *s++ = 0, mem[0][++i] = s;
+		mem[0][++i] = 0;
+	} else {
+		mem[0][0] = 0;
+	}
+	gr->gr_mem = *mem;
+end:
+	pthread_setcancelstate(cs, 0);
+	*res = gr;
+	if(rv) errno = rv;
+	return rv;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgrouplist.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgrouplist.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getgrouplist.c	(revision 398)
@@ -0,0 +1,80 @@
+#define _GNU_SOURCE
+#include "pwf.h"
+#include <grp.h>
+#include <string.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <byteswap.h>
+#include <errno.h>
+#include "nscd.h"
+
+int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
+{
+	int rv, nlim, ret = -1;
+	ssize_t i, n = 1;
+	struct group gr;
+	struct group *res;
+	FILE *f;
+	int swap = 0;
+	int32_t resp[INITGR_LEN];
+	uint32_t *nscdbuf = 0;
+	char *buf = 0;
+	char **mem = 0;
+	size_t nmem = 0;
+	size_t size;
+	nlim = *ngroups;
+	if (nlim >= 1) *groups++ = gid;
+
+	f = __nscd_query(GETINITGR, user, resp, sizeof resp, &swap);
+	if (!f) goto cleanup;
+	if (resp[INITGRFOUND]) {
+		nscdbuf = calloc(resp[INITGRNGRPS], sizeof(uint32_t));
+		if (!nscdbuf) goto cleanup;
+		if (!fread(nscdbuf, sizeof(*nscdbuf)*resp[INITGRNGRPS], 1, f)) {
+			if (!ferror(f)) errno = EIO;
+			goto cleanup;
+		}
+		if (swap) {
+			for (i = 0; i < resp[INITGRNGRPS]; i++)
+				nscdbuf[i] = bswap_32(nscdbuf[i]);
+		}
+	}
+	fclose(f);
+
+	f = fopen("/etc/group", "rbe");
+	if (!f && errno != ENOENT && errno != ENOTDIR)
+		goto cleanup;
+
+	if (f) {
+		while (!(rv = __getgrent_a(f, &gr, &buf, &size, &mem, &nmem, &res)) && res) {
+			if (nscdbuf)
+				for (i=0; i < resp[INITGRNGRPS]; i++) {
+					if (nscdbuf[i] == gr.gr_gid) nscdbuf[i] = gid;
+				}
+			for (i=0; gr.gr_mem[i] && strcmp(user, gr.gr_mem[i]); i++);
+			if (!gr.gr_mem[i]) continue;
+			if (++n <= nlim) *groups++ = gr.gr_gid;
+		}
+		if (rv) {
+			errno = rv;
+			goto cleanup;
+		}
+	}
+	if (nscdbuf) {
+		for(i=0; i < resp[INITGRNGRPS]; i++) {
+			if (nscdbuf[i] != gid)
+				if(++n <= nlim) *groups++ = nscdbuf[i];
+		}
+	}
+
+	ret = n > nlim ? -1 : n;
+	*ngroups = n;
+
+cleanup:
+	if (f) fclose(f);
+	free(nscdbuf);
+	free(buf);
+	free(mem);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpw_a.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpw_a.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpw_a.c	(revision 398)
@@ -0,0 +1,142 @@
+#include <pthread.h>
+#include <byteswap.h>
+#include <string.h>
+#include <unistd.h>
+#include "pwf.h"
+#include "nscd.h"
+
+static char *itoa(char *p, uint32_t x)
+{
+	// number of digits in a uint32_t + NUL
+	p += 11;
+	*--p = 0;
+	do {
+		*--p = '0' + x % 10;
+		x /= 10;
+	} while (x);
+	return p;
+}
+
+int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res)
+{
+	FILE *f;
+	int cs;
+	int rv = 0;
+
+	*res = 0;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	f = fopen("/etc/passwd", "rbe");
+	if (!f) {
+		rv = errno;
+		goto done;
+	}
+
+	while (!(rv = __getpwent_a(f, pw, buf, size, res)) && *res) {
+		if (name && !strcmp(name, (*res)->pw_name)
+		|| !name && (*res)->pw_uid == uid)
+			break;
+	}
+	fclose(f);
+
+	if (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) {
+		int32_t req = name ? GETPWBYNAME : GETPWBYUID;
+		const char *key;
+		int32_t passwdbuf[PW_LEN] = {0};
+		size_t len = 0;
+		char uidbuf[11] = {0};
+
+		if (name) {
+			key = name;
+		} else {
+			/* uid outside of this range can't be queried with the
+			 * nscd interface, but might happen if uid_t ever
+			 * happens to be a larger type (this is not true as of
+			 * now)
+			 */
+			if(uid < 0 || uid > UINT32_MAX) {
+				rv = 0;
+				goto done;
+			}
+			key = itoa(uidbuf, uid);
+		}
+
+		f = __nscd_query(req, key, passwdbuf, sizeof passwdbuf, (int[]){0});
+		if (!f) { rv = errno; goto done; }
+
+		if(!passwdbuf[PWFOUND]) { rv = 0; goto cleanup_f; }
+
+		/* A zero length response from nscd is invalid. We ignore
+		 * invalid responses and just report an error, rather than
+		 * trying to do something with them.
+		 */
+		if (!passwdbuf[PWNAMELEN] || !passwdbuf[PWPASSWDLEN]
+		|| !passwdbuf[PWGECOSLEN] || !passwdbuf[PWDIRLEN]
+		|| !passwdbuf[PWSHELLLEN]) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+		if ((passwdbuf[PWNAMELEN]|passwdbuf[PWPASSWDLEN]
+		     |passwdbuf[PWGECOSLEN]|passwdbuf[PWDIRLEN]
+		     |passwdbuf[PWSHELLLEN]) >= SIZE_MAX/8) {
+			rv = ENOMEM;
+			goto cleanup_f;
+		}
+
+		len = passwdbuf[PWNAMELEN] + passwdbuf[PWPASSWDLEN]
+		    + passwdbuf[PWGECOSLEN] + passwdbuf[PWDIRLEN]
+		    + passwdbuf[PWSHELLLEN];
+
+		if (len > *size || !*buf) {
+			char *tmp = realloc(*buf, len);
+			if (!tmp) {
+				rv = errno;
+				goto cleanup_f;
+			}
+			*buf = tmp;
+			*size = len;
+		}
+
+		if (!fread(*buf, len, 1, f)) {
+			rv = ferror(f) ? errno : EIO;
+			goto cleanup_f;
+		}
+
+		pw->pw_name = *buf;
+		pw->pw_passwd = pw->pw_name + passwdbuf[PWNAMELEN];
+		pw->pw_gecos = pw->pw_passwd + passwdbuf[PWPASSWDLEN];
+		pw->pw_dir = pw->pw_gecos + passwdbuf[PWGECOSLEN];
+		pw->pw_shell = pw->pw_dir + passwdbuf[PWDIRLEN];
+		pw->pw_uid = passwdbuf[PWUID];
+		pw->pw_gid = passwdbuf[PWGID];
+
+		/* Don't assume that nscd made sure to null terminate strings.
+		 * It's supposed to, but malicious nscd should be ignored
+		 * rather than causing a crash.
+		 */
+		if (pw->pw_passwd[-1] || pw->pw_gecos[-1] || pw->pw_dir[-1]
+		|| pw->pw_shell[passwdbuf[PWSHELLLEN]-1]) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+		if (name && strcmp(name, pw->pw_name)
+		|| !name && uid != pw->pw_uid) {
+			rv = EIO;
+			goto cleanup_f;
+		}
+
+
+		*res = pw;
+cleanup_f:
+		fclose(f);
+		goto done;
+	}
+
+done:
+	pthread_setcancelstate(cs, 0);
+	if (rv) errno = rv;
+	return rv;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpw_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpw_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpw_r.c	(revision 398)
@@ -0,0 +1,42 @@
+#include "pwf.h"
+#include <pthread.h>
+
+#define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)
+
+static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	char *line = 0;
+	size_t len = 0;
+	int rv = 0;
+	int cs;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	rv = __getpw_a(name, uid, pw, &line, &len, res);
+	if (*res && size < len) {
+		*res = 0;
+		rv = ERANGE;
+	}
+	if (*res) {
+		memcpy(buf, line, len);
+		FIX(name);
+		FIX(passwd);
+		FIX(gecos);
+		FIX(dir);
+		FIX(shell);
+	}
+ 	free(line);
+	pthread_setcancelstate(cs, 0);
+	if (rv) errno = rv;
+	return rv;
+}
+
+int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	return getpw_r(name, 0, pw, buf, size, res);
+}
+
+int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	return getpw_r(0, uid, pw, buf, size, res);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpwent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpwent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpwent.c	(revision 398)
@@ -0,0 +1,37 @@
+#include "pwf.h"
+
+static FILE *f;
+static char *line;
+static struct passwd pw;
+static size_t size;
+
+void setpwent()
+{
+	if (f) fclose(f);
+	f = 0;
+}
+
+weak_alias(setpwent, endpwent);
+
+struct passwd *getpwent()
+{
+	struct passwd *res;
+	if (!f) f = fopen("/etc/passwd", "rbe");
+	if (!f) return 0;
+	__getpwent_a(f, &pw, &line, &size, &res);
+	return res;
+}
+
+struct passwd *getpwuid(uid_t uid)
+{
+	struct passwd *res;
+	__getpw_a(0, uid, &pw, &line, &size, &res);
+	return res;
+}
+
+struct passwd *getpwnam(const char *name)
+{
+	struct passwd *res;
+	__getpw_a(name, 0, &pw, &line, &size, &res);
+	return res;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpwent_a.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpwent_a.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getpwent_a.c	(revision 398)
@@ -0,0 +1,54 @@
+#include "pwf.h"
+#include <pthread.h>
+
+static unsigned atou(char **s)
+{
+	unsigned x;
+	for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
+	return x;
+}
+
+int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res)
+{
+	ssize_t l;
+	char *s;
+	int rv = 0;
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	for (;;) {
+		if ((l=getline(line, size, f)) < 0) {
+			rv = ferror(f) ? errno : 0;
+			free(*line);
+			*line = 0;
+			pw = 0;
+			break;
+		}
+		line[0][l-1] = 0;
+
+		s = line[0];
+		pw->pw_name = s++;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_passwd = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_uid = atou(&s);
+		if (*s != ':') continue;
+
+		*s++ = 0; pw->pw_gid = atou(&s);
+		if (*s != ':') continue;
+
+		*s++ = 0; pw->pw_gecos = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_dir = s;
+		if (!(s = strchr(s, ':'))) continue;
+
+		*s++ = 0; pw->pw_shell = s;
+		break;
+	}
+	pthread_setcancelstate(cs, 0);
+	*res = pw;
+	if (rv) errno = rv;
+	return rv;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getspent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getspent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getspent.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "pwf.h"
+
+void setspent()
+{
+}
+
+void endspent()
+{
+}
+
+struct spwd *getspent()
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getspnam.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getspnam.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getspnam.c	(revision 398)
@@ -0,0 +1,17 @@
+#include "pwf.h"
+
+#define LINE_LIM 256
+
+struct spwd *getspnam(const char *name)
+{
+	static struct spwd sp;
+	static char *line;
+	struct spwd *res;
+	int e;
+
+	if (!line) line = malloc(LINE_LIM);
+	if (!line) return 0;
+	e = getspnam_r(name, &sp, line, LINE_LIM, &res);
+	if (e) errno = e;
+	return res;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getspnam_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getspnam_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/getspnam_r.c	(revision 398)
@@ -0,0 +1,118 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <pthread.h>
+#include "pwf.h"
+
+/* This implementation support Openwall-style TCB passwords in place of
+ * traditional shadow, if the appropriate directories and files exist.
+ * Thus, it is careful to avoid following symlinks or blocking on fifos
+ * which a malicious user might create in place of his or her TCB shadow
+ * file. It also avoids any allocation to prevent memory-exhaustion
+ * attacks via huge TCB shadow files. */
+
+static long xatol(char **s)
+{
+	long x;
+	if (**s == ':' || **s == '\n') return -1;
+	for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
+	return x;
+}
+
+int __parsespent(char *s, struct spwd *sp)
+{
+	sp->sp_namp = s;
+	if (!(s = strchr(s, ':'))) return -1;
+	*s = 0;
+
+	sp->sp_pwdp = ++s;
+	if (!(s = strchr(s, ':'))) return -1;
+	*s = 0;
+
+	s++; sp->sp_lstchg = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_min = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_max = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_warn = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_inact = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_expire = xatol(&s);
+	if (*s != ':') return -1;
+
+	s++; sp->sp_flag = xatol(&s);
+	if (*s != '\n') return -1;
+	return 0;
+}
+
+static void cleanup(void *p)
+{
+	fclose(p);
+}
+
+int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct spwd **res)
+{
+	char path[20+NAME_MAX];
+	FILE *f = 0;
+	int rv = 0;
+	int fd;
+	size_t k, l = strlen(name);
+	int skip = 0;
+	int cs;
+
+	*res = 0;
+
+	/* Disallow potentially-malicious user names */
+	if (*name=='.' || strchr(name, '/') || !l)
+		return errno = EINVAL;
+
+	/* Buffer size must at least be able to hold name, plus some.. */
+	if (size < l+100)
+		return errno = ERANGE;
+
+	/* Protect against truncation */
+	if (snprintf(path, sizeof path, "/etc/tcb/%s/shadow", name) >= sizeof path)
+		return errno = EINVAL;
+
+	fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC);
+	if (fd >= 0) {
+		struct stat st = { 0 };
+		errno = EINVAL;
+		if (fstat(fd, &st) || !S_ISREG(st.st_mode) || !(f = fdopen(fd, "rb"))) {
+			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+			close(fd);
+			pthread_setcancelstate(cs, 0);
+			return errno;
+		}
+	} else {
+		f = fopen("/etc/shadow", "rbe");
+		if (!f) return errno;
+	}
+
+	pthread_cleanup_push(cleanup, f);
+	while (fgets(buf, size, f) && (k=strlen(buf))>0) {
+		if (skip || strncmp(name, buf, l) || buf[l]!=':') {
+			skip = buf[k-1] != '\n';
+			continue;
+		}
+		if (buf[k-1] != '\n') {
+			rv = ERANGE;
+			break;
+		}
+
+		if (__parsespent(buf, sp) < 0) continue;
+		*res = sp;
+		break;
+	}
+	pthread_cleanup_pop(1);
+	if (rv) errno = rv;
+	return rv;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/lckpwdf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/lckpwdf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/lckpwdf.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <shadow.h>
+
+int lckpwdf()
+{
+	return 0;
+}
+
+int ulckpwdf()
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/nscd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/nscd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/nscd.h	(revision 398)
@@ -0,0 +1,44 @@
+#ifndef NSCD_H
+#define NSCD_H
+
+#include <stdint.h>
+
+#define NSCDVERSION 2
+#define GETPWBYNAME 0
+#define GETPWBYUID 1
+#define GETGRBYNAME 2
+#define GETGRBYGID 3
+#define GETINITGR 15
+
+#define REQVERSION 0
+#define REQTYPE 1
+#define REQKEYLEN 2
+#define REQ_LEN 3
+
+#define PWVERSION 0
+#define PWFOUND 1
+#define PWNAMELEN 2
+#define PWPASSWDLEN 3
+#define PWUID 4
+#define PWGID 5
+#define PWGECOSLEN 6
+#define PWDIRLEN 7
+#define PWSHELLLEN 8
+#define PW_LEN 9
+
+#define GRVERSION 0
+#define GRFOUND 1
+#define GRNAMELEN 2
+#define GRPASSWDLEN 3
+#define GRGID 4
+#define GRMEMCNT 5
+#define GR_LEN 6
+
+#define INITGRVERSION 0
+#define INITGRFOUND 1
+#define INITGRNGRPS 2
+#define INITGR_LEN 3
+
+FILE *__nscd_query(int32_t req, const char *key, int32_t *buf, size_t len, int *swap);
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/nscd_query.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/nscd_query.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/nscd_query.c	(revision 398)
@@ -0,0 +1,107 @@
+#include <sys/socket.h>
+#include <byteswap.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include "nscd.h"
+
+static const struct {
+	short sun_family;
+	char sun_path[21];
+} addr = {
+	AF_UNIX,
+	"/var/run/nscd/socket"
+};
+
+FILE *__nscd_query(int32_t req, const char *key, int32_t *buf, size_t len, int *swap)
+{
+	size_t i;
+	int fd;
+	FILE *f = 0;
+	int32_t req_buf[REQ_LEN] = {
+		NSCDVERSION,
+		req,
+		strnlen(key,LOGIN_NAME_MAX)+1
+	};
+	struct msghdr msg = {
+		.msg_iov = (struct iovec[]){
+			{&req_buf, sizeof(req_buf)},
+			{(char*)key, strlen(key)+1}
+		},
+		.msg_iovlen = 2
+	};
+	int errno_save = errno;
+
+	*swap = 0;
+retry:
+	memset(buf, 0, len);
+	buf[0] = NSCDVERSION;
+
+	fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+	if (fd < 0) return NULL;
+
+	if(!(f = fdopen(fd, "r"))) {
+		close(fd);
+		return 0;
+	}
+
+	if (req_buf[2] > LOGIN_NAME_MAX)
+		return f;
+
+	if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+		/* If there isn't a running nscd we simulate a "not found"
+		 * result and the caller is responsible for calling
+		 * fclose on the (unconnected) socket. The value of
+		 * errno must be left unchanged in this case.  */
+		if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT) {
+			errno = errno_save;
+			return f;
+		}
+		goto error;
+	}
+
+	if (sendmsg(fd, &msg, MSG_NOSIGNAL) < 0)
+		goto error;
+
+	if (!fread(buf, len, 1, f)) {
+		/* If the VERSION entry mismatches nscd will disconnect. The
+		 * most likely cause is that the endianness mismatched. So, we
+		 * byteswap and try once more. (if we already swapped, just
+		 * fail out)
+		 */
+		if (ferror(f)) goto error;
+		if (!*swap) {
+			fclose(f);
+			for (i = 0; i < sizeof(req_buf)/sizeof(req_buf[0]); i++) {
+				req_buf[i] = bswap_32(req_buf[i]);
+			}
+			*swap = 1;
+			goto retry;
+		} else {
+			errno = EIO;
+			goto error;
+		}
+	}
+
+	if (*swap) {
+		for (i = 0; i < len/sizeof(buf[0]); i++) {
+			buf[i] = bswap_32(buf[i]);
+		}
+	}
+
+	/* The first entry in every nscd response is the version number. This
+	 * really shouldn't happen, and is evidence of some form of malformed
+	 * response.
+	 */
+	if(buf[0] != NSCDVERSION) {
+		errno = EIO;
+		goto error;
+	}
+
+	return f;
+error:
+	fclose(f);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/putgrent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/putgrent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/putgrent.c	(revision 398)
@@ -0,0 +1,17 @@
+#define _GNU_SOURCE
+#include <grp.h>
+#include <stdio.h>
+
+int putgrent(const struct group *gr, FILE *f)
+{
+	int r;
+	size_t i;
+	flockfile(f);
+	if ((r = fprintf(f, "%s:%s:%d:", gr->gr_name, gr->gr_passwd, gr->gr_gid))<0) goto done;
+	if (gr->gr_mem) for (i=0; gr->gr_mem[i]; i++)
+		if ((r = fprintf(f, "%s%s", i?",":"", gr->gr_mem[i]))<0) goto done;
+	r = fputc('\n', f);
+done:
+	funlockfile(f);
+	return r<0 ? -1 : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/putpwent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/putpwent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/putpwent.c	(revision 398)
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <pwd.h>
+#include <stdio.h>
+
+int putpwent(const struct passwd *pw, FILE *f)
+{
+	return fprintf(f, "%s:%s:%d:%d:%s:%s:%s\n",
+		pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
+		pw->pw_gecos, pw->pw_dir, pw->pw_shell)<0 ? -1 : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/putspent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/putspent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/putspent.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <shadow.h>
+#include <stdio.h>
+
+#define NUM(n) ((n) == -1 ? 0 : -1), ((n) == -1 ? 0 : (n))
+#define STR(s) ((s) ? (s) : "")
+
+int putspent(const struct spwd *sp, FILE *f)
+{
+	return fprintf(f, "%s:%s:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*lu\n",
+		STR(sp->sp_namp), STR(sp->sp_pwdp), NUM(sp->sp_lstchg),
+		NUM(sp->sp_min), NUM(sp->sp_max), NUM(sp->sp_warn),
+		NUM(sp->sp_inact), NUM(sp->sp_expire), NUM(sp->sp_flag)) < 0 ? -1 : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/pwf.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/pwf.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/passwd/pwf.h	(revision 398)
@@ -0,0 +1,15 @@
+#include <pwd.h>
+#include <grp.h>
+#include <shadow.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+#include "libc.h"
+
+int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res);
+int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res);
+int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res);
+int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t *size, char ***mem, size_t *nmem, struct group **res);
+int __parsespent(char *s, struct spwd *sp);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/__rand48_step.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/__rand48_step.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/__rand48_step.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <stdint.h>
+
+uint64_t __rand48_step(unsigned short *xi, unsigned short *lc)
+{
+	uint64_t a, x;
+	x = xi[0] | xi[1]+0U<<16 | xi[2]+0ULL<<32;
+	a = lc[0] | lc[1]+0U<<16 | lc[2]+0ULL<<32;
+	x = a*x + lc[3];
+	xi[0] = x;
+	xi[1] = x>>16;
+	xi[2] = x>>32;
+	return x & 0xffffffffffffull;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/__seed48.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/__seed48.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/__seed48.c	(revision 398)
@@ -0,0 +1,1 @@
+unsigned short __seed48[7] = { 0, 0, 0, 0xe66d, 0xdeec, 0x5, 0xb };
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/drand48.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/drand48.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/drand48.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+#include <inttypes.h>
+
+uint64_t __rand48_step(unsigned short *xi, unsigned short *lc);
+extern unsigned short __seed48[7];
+
+double erand48(unsigned short s[3])
+{
+	union {
+		uint64_t u;
+		double f;
+	} x = { 0x3ff0000000000000ULL | __rand48_step(s, __seed48+3)<<4 };
+	return x.f - 1.0;
+}
+
+double drand48(void)
+{
+	return erand48(__seed48);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/lcong48.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/lcong48.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/lcong48.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+#include <string.h>
+
+extern unsigned short __seed48[7];
+
+void lcong48(unsigned short p[7])
+{
+	memcpy(__seed48, p, sizeof __seed48);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/lrand48.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/lrand48.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/lrand48.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <inttypes.h>
+
+uint64_t __rand48_step(unsigned short *xi, unsigned short *lc);
+extern unsigned short __seed48[7];
+
+long nrand48(unsigned short s[3])
+{
+	return __rand48_step(s, __seed48+3) >> 17;
+}
+
+long lrand48(void)
+{
+	return nrand48(__seed48);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/mrand48.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/mrand48.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/mrand48.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <inttypes.h>
+
+uint64_t __rand48_step(unsigned short *xi, unsigned short *lc);
+extern unsigned short __seed48[7];
+
+long jrand48(unsigned short s[3])
+{
+	return (int32_t)(__rand48_step(s, __seed48+3) >> 16);
+}
+
+long mrand48(void)
+{
+	return jrand48(__seed48);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/rand.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/rand.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/rand.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+static uint64_t seed;
+
+void srand(unsigned s)
+{
+	seed = s-1;
+}
+
+int rand(void)
+{
+	seed = 6364136223846793005ULL*seed + 1;
+	return seed>>33;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/rand_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/rand_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/rand_r.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+
+static unsigned temper(unsigned x)
+{
+	x ^= x>>11;
+	x ^= x<<7 & 0x9D2C5680;
+	x ^= x<<15 & 0xEFC60000;
+	x ^= x>>18;
+	return x;
+}
+
+int rand_r(unsigned *seed)
+{
+	return temper(*seed = *seed * 1103515245 + 12345)/2;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/random.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/random.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/random.c	(revision 398)
@@ -0,0 +1,122 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include "libc.h"
+
+/*
+this code uses the same lagged fibonacci generator as the
+original bsd random implementation except for the seeding
+which was broken in the original
+*/
+
+static uint32_t init[] = {
+0x00000000,0x5851f42d,0xc0b18ccf,0xcbb5f646,
+0xc7033129,0x30705b04,0x20fd5db4,0x9a8b7f78,
+0x502959d8,0xab894868,0x6c0356a7,0x88cdb7ff,
+0xb477d43f,0x70a3a52b,0xa8e4baf1,0xfd8341fc,
+0x8ae16fd9,0x742d2f7a,0x0d1f0796,0x76035e09,
+0x40f7702c,0x6fa72ca5,0xaaa84157,0x58a0df74,
+0xc74a0364,0xae533cc4,0x04185faf,0x6de3b115,
+0x0cab8628,0xf043bfa4,0x398150e9,0x37521657};
+
+static int n = 31;
+static int i = 3;
+static int j = 0;
+static uint32_t *x = init+1;
+static volatile int lock[2];
+
+static uint32_t lcg31(uint32_t x) {
+	return (1103515245*x + 12345) & 0x7fffffff;
+}
+
+static uint64_t lcg64(uint64_t x) {
+	return 6364136223846793005ull*x + 1;
+}
+
+static void *savestate() {
+	x[-1] = (n<<16)|(i<<8)|j;
+	return x-1;
+}
+
+static void loadstate(uint32_t *state) {
+	x = state+1;
+	n = x[-1]>>16;
+	i = (x[-1]>>8)&0xff;
+	j = x[-1]&0xff;
+}
+
+static void __srandom(unsigned seed) {
+	int k;
+	uint64_t s = seed;
+
+	if (n == 0) {
+		x[0] = s;
+		return;
+	}
+	i = n == 31 || n == 7 ? 3 : 1;
+	j = 0;
+	for (k = 0; k < n; k++) {
+		s = lcg64(s);
+		x[k] = s>>32;
+	}
+	/* make sure x contains at least one odd number */
+	x[0] |= 1;
+}
+
+void srandom(unsigned seed) {
+	LOCK(lock);
+	__srandom(seed);
+	UNLOCK(lock);
+}
+
+char *initstate(unsigned seed, char *state, size_t size) {
+	void *old;
+
+	if (size < 8)
+		return 0;
+	LOCK(lock);
+	old = savestate();
+	if (size < 32)
+		n = 0;
+	else if (size < 64)
+		n = 7;
+	else if (size < 128)
+		n = 15;
+	else if (size < 256)
+		n = 31;
+	else
+		n = 63;
+	x = (uint32_t*)state + 1;
+	__srandom(seed);
+	savestate();
+	UNLOCK(lock);
+	return old;
+}
+
+char *setstate(char *state) {
+	void *old;
+
+	LOCK(lock);
+	old = savestate();
+	loadstate((uint32_t*)state);
+	UNLOCK(lock);
+	return old;
+}
+
+long random(void) {
+	long k;
+
+	LOCK(lock);
+	if (n == 0) {
+		k = x[0] = lcg31(x[0]);
+		goto end;
+	}
+	x[i] += x[j];
+	k = x[i]>>1;
+	if (++i == n)
+		i = 0;
+	if (++j == n)
+		j = 0;
+end:
+	UNLOCK(lock);
+	return k;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/seed48.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/seed48.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/seed48.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include <string.h>
+
+extern unsigned short __seed48[7];
+
+unsigned short *seed48(unsigned short *s)
+{
+	static unsigned short p[3];
+	memcpy(p, __seed48, sizeof p);
+	memcpy(__seed48, s, sizeof p);
+	return p;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/srand48.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/srand48.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/prng/srand48.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+void srand48(long seed)
+{
+	seed48((unsigned short [3]){ 0x330e, seed, seed>>16 });
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execl.c	(revision 398)
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execl(const char *path, const char *argv0, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, argv0);
+	for (argc=1; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		va_start(ap, argv0);
+		argv[0] = (char *)argv0;
+		for (i=1; i<argc; i++)
+			argv[i] = va_arg(ap, char *);
+		argv[i] = NULL;
+		va_end(ap);
+		return execv(path, argv);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execle.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execle.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execle.c	(revision 398)
@@ -0,0 +1,23 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execle(const char *path, const char *argv0, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, argv0);
+	for (argc=1; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		char **envp;
+		va_start(ap, argv0);
+		argv[0] = (char *)argv0;
+		for (i=1; i<=argc; i++)
+			argv[i] = va_arg(ap, char *);
+		envp = va_arg(ap, char **);
+		va_end(ap);
+		return execve(path, argv, envp);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execlp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execlp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execlp.c	(revision 398)
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <stdarg.h>
+
+int execlp(const char *file, const char *argv0, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, argv0);
+	for (argc=1; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		va_start(ap, argv0);
+		argv[0] = (char *)argv0;
+		for (i=1; i<argc; i++)
+			argv[i] = va_arg(ap, char *);
+		argv[i] = NULL;
+		va_end(ap);
+		return execvp(file, argv);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execv.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <unistd.h>
+
+extern char **__environ;
+
+int execv(const char *path, char *const argv[])
+{
+	return execve(path, argv, __environ);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execve.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execve.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execve.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int execve(const char *path, char *const argv[], char *const envp[])
+{
+	/* do we need to use environ if envp is null? */
+	return syscall(SYS_execve, path, argv, envp);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execvp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execvp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/execvp.c	(revision 398)
@@ -0,0 +1,55 @@
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include "libc.h"
+
+extern char **__environ;
+
+int __execvpe(const char *file, char *const argv[], char *const envp[])
+{
+	const char *p, *z, *path = getenv("PATH");
+	size_t l, k;
+	int seen_eacces = 0;
+
+	errno = ENOENT;
+	if (!*file) return -1;
+
+	if (strchr(file, '/'))
+		return execve(file, argv, envp);
+
+	if (!path) path = "/usr/local/bin:/bin:/usr/bin";
+	k = strnlen(file, NAME_MAX+1);
+	if (k > NAME_MAX) {
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+	l = strnlen(path, PATH_MAX-1)+1;
+
+	for(p=path; ; p=z) {
+		char b[l+k+1];
+		z = strchr(p, ':');
+		if (!z) z = p+strlen(p);
+		if (z-p >= l) {
+			if (!*z++) break;
+			continue;
+		}
+		memcpy(b, p, z-p);
+		b[z-p] = '/';
+		memcpy(b+(z-p)+(z>p), file, k+1);
+		execve(b, argv, envp);
+		if (errno == EACCES) seen_eacces = 1;
+		else if (errno != ENOENT) return -1;
+		if (!*z++) break;
+	}
+	if (seen_eacces) errno = EACCES;
+	return -1;
+}
+
+int execvp(const char *file, char *const argv[])
+{
+	return __execvpe(file, argv, __environ);
+}
+
+weak_alias(__execvpe, execvpe);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/fdop.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/fdop.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/fdop.h	(revision 398)
@@ -0,0 +1,10 @@
+#define FDOP_CLOSE 1
+#define FDOP_DUP2 2
+#define FDOP_OPEN 3
+
+struct fdop {
+	struct fdop *next, *prev;
+	int cmd, fd, srcfd, oflag;
+	mode_t mode;
+	char path[];
+};
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/fexecve.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/fexecve.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/fexecve.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <errno.h>
+
+void __procfdname(char *, unsigned);
+
+int fexecve(int fd, char *const argv[], char *const envp[])
+{
+	char buf[15 + 3*sizeof(int)];
+	__procfdname(buf, fd);
+	execve(buf, argv, envp);
+	if (errno == ENOENT) errno = EBADF;
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/fork.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/fork.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/fork.c	(revision 398)
@@ -0,0 +1,35 @@
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include "syscall.h"
+#include "libc.h"
+#include "pthread_impl.h"
+
+static void dummy(int x)
+{
+}
+
+weak_alias(dummy, __fork_handler);
+
+pid_t fork(void)
+{
+	pid_t ret;
+	sigset_t set;
+	__fork_handler(-1);
+	__block_all_sigs(&set);
+#ifdef SYS_fork
+	ret = syscall(SYS_fork);
+#else
+	ret = syscall(SYS_clone, SIGCHLD, 0);
+#endif
+	if (!ret) {
+		pthread_t self = __pthread_self();
+		self->tid = __syscall(SYS_gettid);
+		self->robust_list.off = 0;
+		self->robust_list.pending = 0;
+		libc.threads_minus_1 = 0;
+	}
+	__restore_sigs(&set);
+	__fork_handler(!ret);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn.c	(revision 398)
@@ -0,0 +1,199 @@
+#define _GNU_SOURCE
+#include <spawn.h>
+#include <sched.h>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+#include "fdop.h"
+#include "libc.h"
+
+struct args {
+	int p[2];
+	sigset_t oldmask;
+	const char *path;
+	int (*exec)(const char *, char *const *, char *const *);
+	const posix_spawn_file_actions_t *fa;
+	const posix_spawnattr_t *restrict attr;
+	char *const *argv, *const *envp;
+};
+
+void __get_handler_set(sigset_t *);
+
+static int __sys_dup2(int old, int new)
+{
+#ifdef SYS_dup2
+	return __syscall(SYS_dup2, old, new);
+#else
+	if (old==new) {
+		int r = __syscall(SYS_fcntl, old, F_GETFD);
+		return r<0 ? r : old;
+	} else {
+		return __syscall(SYS_dup3, old, new, 0);
+	}
+#endif
+}
+
+static int child(void *args_vp)
+{
+	int i, ret;
+	struct sigaction sa = {0};
+	struct args *args = args_vp;
+	int p = args->p[1];
+	const posix_spawn_file_actions_t *fa = args->fa;
+	const posix_spawnattr_t *restrict attr = args->attr;
+	sigset_t hset;
+
+	close(args->p[0]);
+
+	/* All signal dispositions must be either SIG_DFL or SIG_IGN
+	 * before signals are unblocked. Otherwise a signal handler
+	 * from the parent might get run in the child while sharing
+	 * memory, with unpredictable and dangerous results. To
+	 * reduce overhead, sigaction has tracked for us which signals
+	 * potentially have a signal handler. */
+	__get_handler_set(&hset);
+	for (i=1; i<_NSIG; i++) {
+		if ((attr->__flags & POSIX_SPAWN_SETSIGDEF)
+		     && sigismember(&attr->__def, i)) {
+			sa.sa_handler = SIG_DFL;
+		} else if (sigismember(&hset, i)) {
+			if (i-32<3U) {
+				sa.sa_handler = SIG_IGN;
+			} else {
+				__libc_sigaction(i, 0, &sa);
+				if (sa.sa_handler==SIG_IGN) continue;
+				sa.sa_handler = SIG_DFL;
+			}
+		} else {
+			continue;
+		}
+		__libc_sigaction(i, &sa, 0);
+	}
+
+	if (attr->__flags & POSIX_SPAWN_SETSID)
+		if ((ret=__syscall(SYS_setsid)) < 0)
+			goto fail;
+
+	if (attr->__flags & POSIX_SPAWN_SETPGROUP)
+		if ((ret=__syscall(SYS_setpgid, 0, attr->__pgrp)))
+			goto fail;
+
+	/* Use syscalls directly because the library functions attempt
+	 * to do a multi-threaded synchronized id-change, which would
+	 * trash the parent's state. */
+	if (attr->__flags & POSIX_SPAWN_RESETIDS)
+		if ((ret=__syscall(SYS_setgid, __syscall(SYS_getgid))) ||
+		    (ret=__syscall(SYS_setuid, __syscall(SYS_getuid))) )
+			goto fail;
+
+	if (fa && fa->__actions) {
+		struct fdop *op;
+		int fd;
+		for (op = fa->__actions; op->next; op = op->next);
+		for (; op; op = op->prev) {
+			/* It's possible that a file operation would clobber
+			 * the pipe fd used for synchronizing with the
+			 * parent. To avoid that, we dup the pipe onto
+			 * an unoccupied fd. */
+			if (op->fd == p) {
+				ret = __syscall(SYS_dup, p);
+				if (ret < 0) goto fail;
+				__syscall(SYS_close, p);
+				p = ret;
+			}
+			switch(op->cmd) {
+			case FDOP_CLOSE:
+				__syscall(SYS_close, op->fd);
+				break;
+			case FDOP_DUP2:
+				if ((ret=__sys_dup2(op->srcfd, op->fd))<0)
+					goto fail;
+				break;
+			case FDOP_OPEN:
+				fd = __sys_open(op->path, op->oflag, op->mode);
+				if ((ret=fd) < 0) goto fail;
+				if (fd != op->fd) {
+					if ((ret=__sys_dup2(fd, op->fd))<0)
+						goto fail;
+					__syscall(SYS_close, fd);
+				}
+				break;
+			}
+		}
+	}
+
+	/* Close-on-exec flag may have been lost if we moved the pipe
+	 * to a different fd. We don't use F_DUPFD_CLOEXEC above because
+	 * it would fail on older kernels and atomicity is not needed --
+	 * in this process there are no threads or signal handlers. */
+	__syscall(SYS_fcntl, p, F_SETFD, FD_CLOEXEC);
+
+	pthread_sigmask(SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK)
+		? &attr->__mask : &args->oldmask, 0);
+
+	args->exec(args->path, args->argv, args->envp);
+	ret = -errno;
+
+fail:
+	/* Since sizeof errno < PIPE_BUF, the write is atomic. */
+	ret = -ret;
+	if (ret) while (__syscall(SYS_write, p, &ret, sizeof ret) < 0);
+	_exit(127);
+}
+
+
+int __posix_spawnx(pid_t *restrict res, const char *restrict path,
+	int (*exec)(const char *, char *const *, char *const *),
+	const posix_spawn_file_actions_t *fa,
+	const posix_spawnattr_t *restrict attr,
+	char *const argv[restrict], char *const envp[restrict])
+{
+	pid_t pid;
+	char stack[1024+PATH_MAX];
+	int ec=0, cs;
+	struct args args;
+
+	if (pipe2(args.p, O_CLOEXEC))
+		return errno;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	args.path = path;
+	args.exec = exec;
+	args.fa = fa;
+	args.attr = attr ? attr : &(const posix_spawnattr_t){0};
+	args.argv = argv;
+	args.envp = envp;
+	pthread_sigmask(SIG_BLOCK, SIGALL_SET, &args.oldmask);
+
+	pid = __clone(child, stack+sizeof stack,
+		CLONE_VM|CLONE_VFORK|SIGCHLD, &args);
+	close(args.p[1]);
+
+	if (pid > 0) {
+		if (read(args.p[0], &ec, sizeof ec) != sizeof ec) ec = 0;
+		else waitpid(pid, &(int){0}, 0);
+	} else {
+		ec = -pid;
+	}
+
+	close(args.p[0]);
+
+	if (!ec && res) *res = pid;
+
+	pthread_sigmask(SIG_SETMASK, &args.oldmask, 0);
+	pthread_setcancelstate(cs, 0);
+
+	return ec;
+}
+
+int posix_spawn(pid_t *restrict res, const char *restrict path,
+	const posix_spawn_file_actions_t *fa,
+	const posix_spawnattr_t *restrict attr,
+	char *const argv[restrict], char *const envp[restrict])
+{
+	return __posix_spawnx(res, path, execve, fa, attr, argv, envp);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_addclose.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_addclose.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_addclose.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <spawn.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "fdop.h"
+
+int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa, int fd)
+{
+	struct fdop *op = malloc(sizeof *op);
+	if (!op) return ENOMEM;
+	op->cmd = FDOP_CLOSE;
+	op->fd = fd;
+	if ((op->next = fa->__actions)) op->next->prev = op;
+	op->prev = 0;
+	fa->__actions = op;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_adddup2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_adddup2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_adddup2.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <spawn.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "fdop.h"
+
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *fa, int srcfd, int fd)
+{
+	struct fdop *op = malloc(sizeof *op);
+	if (!op) return ENOMEM;
+	op->cmd = FDOP_DUP2;
+	op->srcfd = srcfd;
+	op->fd = fd;
+	if ((op->next = fa->__actions)) op->next->prev = op;
+	op->prev = 0;
+	fa->__actions = op;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_addopen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_addopen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_addopen.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <spawn.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "fdop.h"
+
+int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *restrict fa, int fd, const char *restrict path, int flags, mode_t mode)
+{
+	struct fdop *op = malloc(sizeof *op + strlen(path) + 1);
+	if (!op) return ENOMEM;
+	op->cmd = FDOP_OPEN;
+	op->fd = fd;
+	op->oflag = flags;
+	op->mode = mode;
+	strcpy(op->path, path);
+	if ((op->next = fa->__actions)) op->next->prev = op;
+	op->prev = 0;
+	fa->__actions = op;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_destroy.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <spawn.h>
+#include <stdlib.h>
+#include "fdop.h"
+
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *fa)
+{
+	struct fdop *op = fa->__actions, *next;
+	while (op) {
+		next = op->next;
+		free(op);
+		op = next;
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawn_file_actions_init.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t *fa)
+{
+	fa->__actions = 0;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <spawn.h>
+
+int posix_spawnattr_destroy(posix_spawnattr_t *attr)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getflags.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getflags.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getflags.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_getflags(const posix_spawnattr_t *restrict attr, short *restrict flags)
+{
+	*flags = attr->__flags;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getpgroup.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getpgroup.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getpgroup.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_getpgroup(const posix_spawnattr_t *restrict attr, pid_t *restrict pgrp)
+{
+	*pgrp = attr->__pgrp;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getsigdefault.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getsigdefault.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getsigdefault.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_getsigdefault(const posix_spawnattr_t *restrict attr, sigset_t *restrict def)
+{
+	*def = attr->__def;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getsigmask.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getsigmask.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_getsigmask.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_getsigmask(const posix_spawnattr_t *restrict attr, sigset_t *restrict mask)
+{
+	*mask = attr->__mask;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_init.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_init(posix_spawnattr_t *attr)
+{
+	*attr = (posix_spawnattr_t){ 0 };
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_sched.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_sched.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_sched.c	(revision 398)
@@ -0,0 +1,25 @@
+#include <spawn.h>
+#include <sched.h>
+#include <errno.h>
+
+int posix_spawnattr_getschedparam(const posix_spawnattr_t *restrict attr,
+	struct sched_param *restrict schedparam)
+{
+	return ENOSYS;
+}
+
+int posix_spawnattr_setschedparam(posix_spawnattr_t *restrict attr,
+	const struct sched_param *restrict schedparam)
+{
+	return ENOSYS;
+}
+
+int posix_spawnattr_getschedpolicy(const posix_spawnattr_t *restrict attr, int *restrict policy)
+{
+	return ENOSYS;
+}
+
+int posix_spawnattr_setschedpolicy(posix_spawnattr_t *attr, int policy)
+{
+	return ENOSYS;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setflags.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setflags.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setflags.c	(revision 398)
@@ -0,0 +1,18 @@
+#include <spawn.h>
+#include <errno.h>
+
+int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags)
+{
+	const unsigned all_flags =
+		POSIX_SPAWN_RESETIDS |
+		POSIX_SPAWN_SETPGROUP |
+		POSIX_SPAWN_SETSIGDEF |
+		POSIX_SPAWN_SETSIGMASK |
+		POSIX_SPAWN_SETSCHEDPARAM |
+		POSIX_SPAWN_SETSCHEDULER |
+		POSIX_SPAWN_USEVFORK |
+		POSIX_SPAWN_SETSID;
+	if (flags & ~all_flags) return EINVAL;
+	attr->__flags = flags;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setpgroup.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setpgroup.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setpgroup.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, pid_t pgrp)
+{
+	attr->__pgrp = pgrp;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setsigdefault.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setsigdefault.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setsigdefault.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_setsigdefault(posix_spawnattr_t *restrict attr, const sigset_t *restrict def)
+{
+	attr->__def = *def;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setsigmask.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setsigmask.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnattr_setsigmask.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <spawn.h>
+
+int posix_spawnattr_setsigmask(posix_spawnattr_t *restrict attr, const sigset_t *restrict mask)
+{
+	attr->__mask = *mask;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/posix_spawnp.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <spawn.h>
+#include <unistd.h>
+
+int __execvpe(const char *, char *const *, char *const *);
+
+int __posix_spawnx(pid_t *restrict, const char *restrict,
+	int (*)(const char *, char *const *, char *const *),
+	const posix_spawn_file_actions_t *,
+	const posix_spawnattr_t *restrict, char *const *restrict, char *const *restrict);
+
+int posix_spawnp(pid_t *restrict res, const char *restrict file,
+	const posix_spawn_file_actions_t *fa,
+	const posix_spawnattr_t *restrict attr,
+	char *const argv[restrict], char *const envp[restrict])
+{
+	return __posix_spawnx(res, file, __execvpe, fa, attr, argv, envp);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/system.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/system.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/system.c	(revision 398)
@@ -0,0 +1,47 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <spawn.h>
+#include <errno.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+extern char **__environ;
+
+int system(const char *cmd)
+{
+	pid_t pid;
+	sigset_t old, reset;
+	struct sigaction sa = { .sa_handler = SIG_IGN }, oldint, oldquit;
+	int status = 0x7f00, ret;
+	posix_spawnattr_t attr;
+
+	pthread_testcancel();
+
+	if (!cmd) return 1;
+
+	sigaction(SIGINT, &sa, &oldint);
+	sigaction(SIGQUIT, &sa, &oldquit);
+	sigaddset(&sa.sa_mask, SIGCHLD);
+	sigprocmask(SIG_BLOCK, &sa.sa_mask, &old);
+
+	sigemptyset(&reset);
+	if (oldint.sa_handler != SIG_IGN) sigaddset(&reset, SIGINT);
+	if (oldquit.sa_handler != SIG_IGN) sigaddset(&reset, SIGQUIT);
+	posix_spawnattr_init(&attr);
+	posix_spawnattr_setsigmask(&attr, &old);
+	posix_spawnattr_setsigdefault(&attr, &reset);
+	posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK);
+	ret = posix_spawn(&pid, "/bin/sh", 0, &attr,
+		(char *[]){"sh", "-c", (char *)cmd, 0}, __environ);
+	posix_spawnattr_destroy(&attr);
+
+	if (!ret) while (waitpid(pid, &status, 0)<0 && errno == EINTR);
+	sigaction(SIGINT, &oldint, NULL);
+	sigaction(SIGQUIT, &oldquit, NULL);
+	sigprocmask(SIG_SETMASK, &old, NULL);
+
+	if (ret) errno = ret;
+	return status;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/vfork.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/vfork.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/vfork.c	(revision 398)
@@ -0,0 +1,17 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <signal.h>
+#include "syscall.h"
+#include "libc.h"
+
+pid_t __vfork(void)
+{
+	/* vfork syscall cannot be made from C code */
+#ifdef SYS_fork
+	return syscall(SYS_fork);
+#else
+	return syscall(SYS_clone, SIGCHLD, 0);
+#endif
+}
+
+weak_alias(__vfork, vfork);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/wait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/wait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/wait.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <sys/wait.h>
+
+pid_t wait(int *status)
+{
+	return waitpid((pid_t)-1, status, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/waitid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/waitid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/waitid.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/wait.h>
+#include "syscall.h"
+#include "libc.h"
+
+int waitid(idtype_t type, id_t id, siginfo_t *info, int options)
+{
+	return syscall_cp(SYS_waitid, type, id, info, options, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/waitpid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/waitpid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/process/waitpid.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/wait.h>
+#include "syscall.h"
+#include "libc.h"
+
+pid_t waitpid(pid_t pid, int *status, int options)
+{
+	return syscall_cp(SYS_wait4, pid, status, options, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/fnmatch.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/fnmatch.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/fnmatch.c	(revision 398)
@@ -0,0 +1,321 @@
+/*
+ * An implementation of what I call the "Sea of Stars" algorithm for
+ * POSIX fnmatch(). The basic idea is that we factor the pattern into
+ * a head component (which we match first and can reject without ever
+ * measuring the length of the string), an optional tail component
+ * (which only exists if the pattern contains at least one star), and
+ * an optional "sea of stars", a set of star-separated components
+ * between the head and tail. After the head and tail matches have
+ * been removed from the input string, the components in the "sea of
+ * stars" are matched sequentially by searching for their first
+ * occurrence past the end of the previous match.
+ *
+ * - Rich Felker, April 2012
+ */
+
+#include <string.h>
+#include <fnmatch.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+#include "locale_impl.h"
+
+#define END 0
+#define UNMATCHABLE -2
+#define BRACKET -3
+#define QUESTION -4
+#define STAR -5
+
+static int str_next(const char *str, size_t n, size_t *step)
+{
+	if (!n) {
+		*step = 0;
+		return 0;
+	}
+	if (str[0] >= 128U) {
+		wchar_t wc;
+		int k = mbtowc(&wc, str, n);
+		if (k<0) {
+			*step = 1;
+			return -1;
+		}
+		*step = k;
+		return wc;
+	}
+	*step = 1;
+	return str[0];
+}
+
+static int pat_next(const char *pat, size_t m, size_t *step, int flags)
+{
+	int esc = 0;
+	if (!m || !*pat) {
+		*step = 0;
+		return END;
+	}
+	*step = 1;
+	if (pat[0]=='\\' && pat[1] && !(flags & FNM_NOESCAPE)) {
+		*step = 2;
+		pat++;
+		esc = 1;
+		goto escaped;
+	}
+	if (pat[0]=='[') {
+		size_t k = 1;
+		if (k<m) if (pat[k] == '^' || pat[k] == '!') k++;
+		if (k<m) if (pat[k] == ']') k++;
+		for (; k<m && pat[k] && pat[k]!=']'; k++) {
+			if (k+1<m && pat[k+1] && pat[k]=='[' && (pat[k+1]==':' || pat[k+1]=='.' || pat[k+1]=='=')) {
+				int z = pat[k+1];
+				k+=2;
+				if (k<m && pat[k]) k++;
+				while (k<m && pat[k] && (pat[k-1]!=z || pat[k]!=']')) k++;
+				if (k==m || !pat[k]) break;
+			}
+		}
+		if (k==m || !pat[k]) {
+			*step = 1;
+			return '[';
+		}
+		*step = k+1;
+		return BRACKET;
+	}
+	if (pat[0] == '*')
+		return STAR;
+	if (pat[0] == '?')
+		return QUESTION;
+escaped:
+	if (pat[0] >= 128U) {
+		wchar_t wc;
+		int k = mbtowc(&wc, pat, m);
+		if (k<0) {
+			*step = 0;
+			return UNMATCHABLE;
+		}
+		*step = k + esc;
+		return wc;
+	}
+	return pat[0];
+}
+
+static int casefold(int k)
+{
+	int c = towupper(k);
+	return c == k ? towlower(k) : c;
+}
+
+static int match_bracket(const char *p, int k, int kfold)
+{
+	wchar_t wc;
+	int inv = 0;
+	p++;
+	if (*p=='^' || *p=='!') {
+		inv = 1;
+		p++;
+	}
+	if (*p==']') {
+		if (k==']') return !inv;
+		p++;
+	} else if (*p=='-') {
+		if (k=='-') return !inv;
+		p++;
+	}
+	wc = p[-1];
+	for (; *p != ']'; p++) {
+		if (p[0]=='-' && p[1]!=']') {
+			wchar_t wc2;
+			int l = mbtowc(&wc2, p+1, 4);
+			if (l < 0) return 0;
+			if (wc <= wc2)
+				if ((unsigned)k-wc <= wc2-wc ||
+				    (unsigned)kfold-wc <= wc2-wc)
+					return !inv;
+			p += l-1;
+			continue;
+		}
+		if (p[0]=='[' && (p[1]==':' || p[1]=='.' || p[1]=='=')) {
+			const char *p0 = p+2;
+			int z = p[1];
+			p+=3;
+			while (p[-1]!=z || p[0]!=']') p++;
+			if (z == ':' && p-1-p0 < 16) {
+				char buf[16];
+				memcpy(buf, p0, p-1-p0);
+				buf[p-1-p0] = 0;
+				if (iswctype(k, wctype(buf)) ||
+				    iswctype(kfold, wctype(buf)))
+					return !inv;
+			}
+			continue;
+		}
+		if (*p < 128U) {
+			wc = (unsigned char)*p;
+		} else {
+			int l = mbtowc(&wc, p, 4);
+			if (l < 0) return 0;
+			p += l-1;
+		}
+		if (wc==k || wc==kfold) return !inv;
+	}
+	return inv;
+}
+
+static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n, int flags)
+{
+	const char *p, *ptail, *endpat;
+	const char *s, *stail, *endstr;
+	size_t pinc, sinc, tailcnt=0;
+	int c, k, kfold;
+
+	if (flags & FNM_PERIOD) {
+		if (*str == '.' && *pat != '.')
+			return FNM_NOMATCH;
+	}
+	for (;;) {
+		switch ((c = pat_next(pat, m, &pinc, flags))) {
+		case UNMATCHABLE:
+			return FNM_NOMATCH;
+		case STAR:
+			pat++;
+			m--;
+			break;
+		default:
+			k = str_next(str, n, &sinc);
+			if (k <= 0)
+				return (c==END) ? 0 : FNM_NOMATCH;
+			str += sinc;
+			n -= sinc;
+			kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
+			if (c == BRACKET) {
+				if (!match_bracket(pat, k, kfold))
+					return FNM_NOMATCH;
+			} else if (c != QUESTION && k != c && kfold != c) {
+				return FNM_NOMATCH;
+			}
+			pat+=pinc;
+			m-=pinc;
+			continue;
+		}
+		break;
+	}
+
+	/* Compute real pat length if it was initially unknown/-1 */
+	m = strnlen(pat, m);
+	endpat = pat + m;
+
+	/* Find the last * in pat and count chars needed after it */
+	for (p=ptail=pat; p<endpat; p+=pinc) {
+		switch (pat_next(p, endpat-p, &pinc, flags)) {
+		case UNMATCHABLE:
+			return FNM_NOMATCH;
+		case STAR:
+			tailcnt=0;
+			ptail = p+1;
+			break;
+		default:
+			tailcnt++;
+			break;
+		}
+	}
+
+	/* Past this point we need not check for UNMATCHABLE in pat,
+	 * because all of pat has already been parsed once. */
+
+	/* Compute real str length if it was initially unknown/-1 */
+	n = strnlen(str, n);
+	endstr = str + n;
+	if (n < tailcnt) return FNM_NOMATCH;
+
+	/* Find the final tailcnt chars of str, accounting for UTF-8.
+	 * On illegal sequences we may get it wrong, but in that case
+	 * we necessarily have a matching failure anyway. */
+	for (s=endstr; s>str && tailcnt; tailcnt--) {
+		if (s[-1] < 128U || MB_CUR_MAX==1) s--;
+		else while ((unsigned char)*--s-0x80U<0x40 && s>str);
+	}
+	if (tailcnt) return FNM_NOMATCH;
+	stail = s;
+
+	/* Check that the pat and str tails match */
+	p = ptail;
+	for (;;) {
+		c = pat_next(p, endpat-p, &pinc, flags);
+		p += pinc;
+		if ((k = str_next(s, endstr-s, &sinc)) <= 0) {
+			if (c != END) return FNM_NOMATCH;
+			break;
+		}
+		s += sinc;
+		kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
+		if (c == BRACKET) {
+			if (!match_bracket(p-pinc, k, kfold))
+				return FNM_NOMATCH;
+		} else if (c != QUESTION && k != c && kfold != c) {
+			return FNM_NOMATCH;
+		}
+	}
+
+	/* We're all done with the tails now, so throw them out */
+	endstr = stail;
+	endpat = ptail;
+
+	/* Match pattern components until there are none left */
+	while (pat<endpat) {
+		p = pat;
+		s = str;
+		for (;;) {
+			c = pat_next(p, endpat-p, &pinc, flags);
+			p += pinc;
+			/* Encountering * completes/commits a component */
+			if (c == STAR) {
+				pat = p;
+				str = s;
+				break;
+			}
+			k = str_next(s, endstr-s, &sinc);
+			if (!k)
+				return FNM_NOMATCH;
+			kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
+			if (c == BRACKET) {
+				if (!match_bracket(p-pinc, k, kfold))
+					break;
+			} else if (c != QUESTION && k != c && kfold != c) {
+				break;
+			}
+			s += sinc;
+		}
+		if (c == STAR) continue;
+		/* If we failed, advance str, by 1 char if it's a valid
+		 * char, or past all invalid bytes otherwise. */
+		k = str_next(str, endstr-str, &sinc);
+		if (k > 0) str += sinc;
+		else for (str++; str_next(str, endstr-str, &sinc)<0; str++);
+	}
+
+	return 0;
+}
+
+int fnmatch(const char *pat, const char *str, int flags)
+{
+	const char *s, *p;
+	size_t inc;
+	int c;
+	if (flags & FNM_PATHNAME) for (;;) {
+		for (s=str; *s && *s!='/'; s++);
+		for (p=pat; (c=pat_next(p, -1, &inc, flags))!=END && c!='/'; p+=inc);
+		if (c!=*s && (!*s || !(flags & FNM_LEADING_DIR)))
+			return FNM_NOMATCH;
+		if (fnmatch_internal(pat, p-pat, str, s-str, flags))
+			return FNM_NOMATCH;
+		if (!c) return 0;
+		str = s+1;
+		pat = p+inc;
+	} else if (flags & FNM_LEADING_DIR) {
+		for (s=str; *s; s++) {
+			if (*s != '/') continue;
+			if (!fnmatch_internal(pat, -1, str, s-str, flags))
+				return 0;
+		}
+	}
+	return fnmatch_internal(pat, -1, str, -1, flags);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/glob.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/glob.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/glob.c	(revision 398)
@@ -0,0 +1,244 @@
+#include <glob.h>
+#include <fnmatch.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stddef.h>
+#include "libc.h"
+
+struct match
+{
+	struct match *next;
+	char name[1];
+};
+
+static int is_literal(const char *p, int useesc)
+{
+	int bracket = 0;
+	for (; *p; p++) {
+		switch (*p) {
+		case '\\':
+			if (!useesc) break;
+		case '?':
+		case '*':
+			return 0;
+		case '[':
+			bracket = 1;
+			break;
+		case ']':
+			if (bracket) return 0;
+			break;
+		}
+	}
+	return 1;
+}
+
+static int append(struct match **tail, const char *name, size_t len, int mark)
+{
+	struct match *new = malloc(sizeof(struct match) + len + 1);
+	if (!new) return -1;
+	(*tail)->next = new;
+	new->next = NULL;
+	strcpy(new->name, name);
+	if (mark) strcat(new->name, "/");
+	*tail = new;
+	return 0;
+}
+
+static int match_in_dir(const char *d, const char *p, int flags, int (*errfunc)(const char *path, int err), struct match **tail)
+{
+	DIR *dir;
+	struct dirent de_buf, *de;
+	char pat[strlen(p)+1];
+	char *p2;
+	size_t l = strlen(d);
+	int literal;
+	int fnm_flags= ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
+		| ((!(flags & GLOB_PERIOD)) ? FNM_PERIOD : 0);
+	int error;
+
+	if ((p2 = strchr(p, '/'))) {
+		strcpy(pat, p);
+		pat[p2-p] = 0;
+		for (; *p2 == '/'; p2++);
+		p = pat;
+	}
+	literal = is_literal(p, !(flags & GLOB_NOESCAPE));
+	if (*d == '/' && !*(d+1)) l = 0;
+
+	/* rely on opendir failing for nondirectory objects */
+	dir = opendir(*d ? d : ".");
+	error = errno;
+	if (!dir) {
+		/* this is not an error -- we let opendir call stat for us */
+		if (error == ENOTDIR) return 0;
+		if (error == EACCES && !*p) {
+			struct stat st;
+			if (!stat(d, &st) && S_ISDIR(st.st_mode)) {
+				if (append(tail, d, l, l))
+					return GLOB_NOSPACE;
+				return 0;
+			}
+		}
+		if (errfunc(d, error) || (flags & GLOB_ERR))
+			return GLOB_ABORTED;
+		return 0;
+	}
+	if (!*p) {
+		error = append(tail, d, l, l) ? GLOB_NOSPACE : 0;
+		closedir(dir);
+		return error;
+	}
+	while (!(error = readdir_r(dir, &de_buf, &de)) && de) {
+		char namebuf[l+de->d_reclen+2], *name = namebuf;
+		if (!literal && fnmatch(p, de->d_name, fnm_flags))
+			continue;
+		if (literal && strcmp(p, de->d_name))
+			continue;
+		if (p2 && de->d_type && !S_ISDIR(de->d_type<<12) && !S_ISLNK(de->d_type<<12))
+			continue;
+		/* With GLOB_PERIOD, don't allow matching . or .. unless
+		 * fnmatch would match them with FNM_PERIOD rules in effect. */
+		if (p2 && (flags & GLOB_PERIOD) && de->d_name[0]=='.'
+		    && (!de->d_name[1] || de->d_name[1]=='.' && !de->d_name[2])
+		    && fnmatch(p, de->d_name, fnm_flags | FNM_PERIOD))
+			continue;
+		if (*d) {
+			memcpy(name, d, l);
+			name[l] = '/';
+			strcpy(name+l+1, de->d_name);
+		} else {
+			name = de->d_name;
+		}
+		if (p2) {
+			if ((error = match_in_dir(name, p2, flags, errfunc, tail))) {
+				closedir(dir);
+				return error;
+			}
+		} else {
+			int mark = 0;
+			if (flags & GLOB_MARK) {
+				if (de->d_type && !S_ISLNK(de->d_type<<12))
+					mark = S_ISDIR(de->d_type<<12);
+				else {
+					struct stat st;
+					stat(name, &st);
+					mark = S_ISDIR(st.st_mode);
+				}
+			}
+			if (append(tail, name, l+de->d_reclen+1, mark)) {
+				closedir(dir);
+				return GLOB_NOSPACE;
+			}
+		}
+	}
+	closedir(dir);
+	if (error && (errfunc(d, error) || (flags & GLOB_ERR)))
+		return GLOB_ABORTED;
+	return 0;
+}
+
+static int ignore_err(const char *path, int err)
+{
+	return 0;
+}
+
+static void freelist(struct match *head)
+{
+	struct match *match, *next;
+	for (match=head->next; match; match=next) {
+		next = match->next;
+		free(match);
+	}
+}
+
+static int sort(const void *a, const void *b)
+{
+	return strcmp(*(const char **)a, *(const char **)b);
+}
+
+int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, int err), glob_t *restrict g)
+{
+	const char *p=pat, *d;
+	struct match head = { .next = NULL }, *tail = &head;
+	size_t cnt, i;
+	size_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0;
+	int error = 0;
+	
+	if (*p == '/') {
+		for (; *p == '/'; p++);
+		d = "/";
+	} else {
+		d = "";
+	}
+
+	if (!errfunc) errfunc = ignore_err;
+
+	if (!(flags & GLOB_APPEND)) {
+		g->gl_offs = offs;
+		g->gl_pathc = 0;
+		g->gl_pathv = NULL;
+	}
+
+	if (strnlen(p, PATH_MAX+1) > PATH_MAX) return GLOB_NOSPACE;
+
+	if (*pat) error = match_in_dir(d, p, flags, errfunc, &tail);
+	if (error == GLOB_NOSPACE) {
+		freelist(&head);
+		return error;
+	}
+	
+	for (cnt=0, tail=head.next; tail; tail=tail->next, cnt++);
+	if (!cnt) {
+		if (flags & GLOB_NOCHECK) {
+			tail = &head;
+			if (append(&tail, pat, strlen(pat), 0))
+				return GLOB_NOSPACE;
+			cnt++;
+		} else
+			return GLOB_NOMATCH;
+	}
+
+	if (flags & GLOB_APPEND) {
+		char **pathv = realloc(g->gl_pathv, (offs + g->gl_pathc + cnt + 1) * sizeof(char *));
+		if (!pathv) {
+			freelist(&head);
+			return GLOB_NOSPACE;
+		}
+		g->gl_pathv = pathv;
+		offs += g->gl_pathc;
+	} else {
+		g->gl_pathv = malloc((offs + cnt + 1) * sizeof(char *));
+		if (!g->gl_pathv) {
+			freelist(&head);
+			return GLOB_NOSPACE;
+		}
+		for (i=0; i<offs; i++)
+			g->gl_pathv[i] = NULL;
+	}
+	for (i=0, tail=head.next; i<cnt; tail=tail->next, i++)
+		g->gl_pathv[offs + i] = tail->name;
+	g->gl_pathv[offs + i] = NULL;
+	g->gl_pathc += cnt;
+
+	if (!(flags & GLOB_NOSORT))
+		qsort(g->gl_pathv+offs, cnt, sizeof(char *), sort);
+	
+	return error;
+}
+
+void globfree(glob_t *g)
+{
+	size_t i;
+	for (i=0; i<g->gl_pathc; i++)
+		free(g->gl_pathv[g->gl_offs + i] - offsetof(struct match, name));
+	free(g->gl_pathv);
+	g->gl_pathc = 0;
+	g->gl_pathv = NULL;
+}
+
+LFS64(glob);
+LFS64(globfree);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/regcomp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/regcomp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/regcomp.c	(revision 398)
@@ -0,0 +1,2953 @@
+/*
+  regcomp.c - TRE POSIX compatible regex compilation functions.
+
+  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must 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 HOLDER 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 <stdlib.h>
+#include <regex.h>
+#include <limits.h>
+#include <stdint.h>
+#include <ctype.h>
+
+#include "tre.h"
+
+#include <assert.h>
+
+/***********************************************************************
+ from tre-compile.h
+***********************************************************************/
+
+typedef struct {
+  int position;
+  int code_min;
+  int code_max;
+  int *tags;
+  int assertions;
+  tre_ctype_t class;
+  tre_ctype_t *neg_classes;
+  int backref;
+} tre_pos_and_tags_t;
+
+
+/***********************************************************************
+ from tre-ast.c and tre-ast.h
+***********************************************************************/
+
+/* The different AST node types. */
+typedef enum {
+  LITERAL,
+  CATENATION,
+  ITERATION,
+  UNION
+} tre_ast_type_t;
+
+/* Special subtypes of TRE_LITERAL. */
+#define EMPTY	  -1   /* Empty leaf (denotes empty string). */
+#define ASSERTION -2   /* Assertion leaf. */
+#define TAG	  -3   /* Tag leaf. */
+#define BACKREF	  -4   /* Back reference leaf. */
+
+#define IS_SPECIAL(x)	((x)->code_min < 0)
+#define IS_EMPTY(x)	((x)->code_min == EMPTY)
+#define IS_ASSERTION(x) ((x)->code_min == ASSERTION)
+#define IS_TAG(x)	((x)->code_min == TAG)
+#define IS_BACKREF(x)	((x)->code_min == BACKREF)
+
+
+/* A generic AST node.  All AST nodes consist of this node on the top
+   level with `obj' pointing to the actual content. */
+typedef struct {
+  tre_ast_type_t type;   /* Type of the node. */
+  void *obj;             /* Pointer to actual node. */
+  int nullable;
+  int submatch_id;
+  int num_submatches;
+  int num_tags;
+  tre_pos_and_tags_t *firstpos;
+  tre_pos_and_tags_t *lastpos;
+} tre_ast_node_t;
+
+
+/* A "literal" node.  These are created for assertions, back references,
+   tags, matching parameter settings, and all expressions that match one
+   character. */
+typedef struct {
+  long code_min;
+  long code_max;
+  int position;
+  tre_ctype_t class;
+  tre_ctype_t *neg_classes;
+} tre_literal_t;
+
+/* A "catenation" node.	 These are created when two regexps are concatenated.
+   If there are more than one subexpressions in sequence, the `left' part
+   holds all but the last, and `right' part holds the last subexpression
+   (catenation is left associative). */
+typedef struct {
+  tre_ast_node_t *left;
+  tre_ast_node_t *right;
+} tre_catenation_t;
+
+/* An "iteration" node.	 These are created for the "*", "+", "?", and "{m,n}"
+   operators. */
+typedef struct {
+  /* Subexpression to match. */
+  tre_ast_node_t *arg;
+  /* Minimum number of consecutive matches. */
+  int min;
+  /* Maximum number of consecutive matches. */
+  int max;
+  /* If 0, match as many characters as possible, if 1 match as few as
+     possible.	Note that this does not always mean the same thing as
+     matching as many/few repetitions as possible. */
+  unsigned int minimal:1;
+} tre_iteration_t;
+
+/* An "union" node.  These are created for the "|" operator. */
+typedef struct {
+  tre_ast_node_t *left;
+  tre_ast_node_t *right;
+} tre_union_t;
+
+
+static tre_ast_node_t *
+tre_ast_new_node(tre_mem_t mem, int type, void *obj)
+{
+	tre_ast_node_t *node = tre_mem_calloc(mem, sizeof *node);
+	if (!node || !obj)
+		return 0;
+	node->obj = obj;
+	node->type = type;
+	node->nullable = -1;
+	node->submatch_id = -1;
+	return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_literal(tre_mem_t mem, int code_min, int code_max, int position)
+{
+	tre_ast_node_t *node;
+	tre_literal_t *lit;
+
+	lit = tre_mem_calloc(mem, sizeof *lit);
+	node = tre_ast_new_node(mem, LITERAL, lit);
+	if (!node)
+		return 0;
+	lit->code_min = code_min;
+	lit->code_max = code_max;
+	lit->position = position;
+	return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_iter(tre_mem_t mem, tre_ast_node_t *arg, int min, int max, int minimal)
+{
+	tre_ast_node_t *node;
+	tre_iteration_t *iter;
+
+	iter = tre_mem_calloc(mem, sizeof *iter);
+	node = tre_ast_new_node(mem, ITERATION, iter);
+	if (!node)
+		return 0;
+	iter->arg = arg;
+	iter->min = min;
+	iter->max = max;
+	iter->minimal = minimal;
+	node->num_submatches = arg->num_submatches;
+	return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_union(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
+{
+	tre_ast_node_t *node;
+	tre_union_t *un;
+
+	if (!left)
+		return right;
+	un = tre_mem_calloc(mem, sizeof *un);
+	node = tre_ast_new_node(mem, UNION, un);
+	if (!node || !right)
+		return 0;
+	un->left = left;
+	un->right = right;
+	node->num_submatches = left->num_submatches + right->num_submatches;
+	return node;
+}
+
+static tre_ast_node_t *
+tre_ast_new_catenation(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
+{
+	tre_ast_node_t *node;
+	tre_catenation_t *cat;
+
+	if (!left)
+		return right;
+	cat = tre_mem_calloc(mem, sizeof *cat);
+	node = tre_ast_new_node(mem, CATENATION, cat);
+	if (!node)
+		return 0;
+	cat->left = left;
+	cat->right = right;
+	node->num_submatches = left->num_submatches + right->num_submatches;
+	return node;
+}
+
+
+/***********************************************************************
+ from tre-stack.c and tre-stack.h
+***********************************************************************/
+
+typedef struct tre_stack_rec tre_stack_t;
+
+/* Creates a new stack object.	`size' is initial size in bytes, `max_size'
+   is maximum size, and `increment' specifies how much more space will be
+   allocated with realloc() if all space gets used up.	Returns the stack
+   object or NULL if out of memory. */
+static tre_stack_t *
+tre_stack_new(int size, int max_size, int increment);
+
+/* Frees the stack object. */
+static void
+tre_stack_destroy(tre_stack_t *s);
+
+/* Returns the current number of objects in the stack. */
+static int
+tre_stack_num_objects(tre_stack_t *s);
+
+/* Each tre_stack_push_*(tre_stack_t *s, <type> value) function pushes
+   `value' on top of stack `s'.  Returns REG_ESPACE if out of memory.
+   This tries to realloc() more space before failing if maximum size
+   has not yet been reached.  Returns REG_OK if successful. */
+#define declare_pushf(typetag, type)					      \
+  static reg_errcode_t tre_stack_push_ ## typetag(tre_stack_t *s, type value)
+
+declare_pushf(voidptr, void *);
+declare_pushf(int, int);
+
+/* Each tre_stack_pop_*(tre_stack_t *s) function pops the topmost
+   element off of stack `s' and returns it.  The stack must not be
+   empty. */
+#define declare_popf(typetag, type)		  \
+  static type tre_stack_pop_ ## typetag(tre_stack_t *s)
+
+declare_popf(voidptr, void *);
+declare_popf(int, int);
+
+/* Just to save some typing. */
+#define STACK_PUSH(s, typetag, value)					      \
+  do									      \
+    {									      \
+      status = tre_stack_push_ ## typetag(s, value);			      \
+    }									      \
+  while (/*CONSTCOND*/0)
+
+#define STACK_PUSHX(s, typetag, value)					      \
+  {									      \
+    status = tre_stack_push_ ## typetag(s, value);			      \
+    if (status != REG_OK)						      \
+      break;								      \
+  }
+
+#define STACK_PUSHR(s, typetag, value)					      \
+  {									      \
+    reg_errcode_t _status;						      \
+    _status = tre_stack_push_ ## typetag(s, value);			      \
+    if (_status != REG_OK)						      \
+      return _status;							      \
+  }
+
+union tre_stack_item {
+  void *voidptr_value;
+  int int_value;
+};
+
+struct tre_stack_rec {
+  int size;
+  int max_size;
+  int increment;
+  int ptr;
+  union tre_stack_item *stack;
+};
+
+
+static tre_stack_t *
+tre_stack_new(int size, int max_size, int increment)
+{
+  tre_stack_t *s;
+
+  s = xmalloc(sizeof(*s));
+  if (s != NULL)
+    {
+      s->stack = xmalloc(sizeof(*s->stack) * size);
+      if (s->stack == NULL)
+	{
+	  xfree(s);
+	  return NULL;
+	}
+      s->size = size;
+      s->max_size = max_size;
+      s->increment = increment;
+      s->ptr = 0;
+    }
+  return s;
+}
+
+static void
+tre_stack_destroy(tre_stack_t *s)
+{
+  xfree(s->stack);
+  xfree(s);
+}
+
+static int
+tre_stack_num_objects(tre_stack_t *s)
+{
+  return s->ptr;
+}
+
+static reg_errcode_t
+tre_stack_push(tre_stack_t *s, union tre_stack_item value)
+{
+  if (s->ptr < s->size)
+    {
+      s->stack[s->ptr] = value;
+      s->ptr++;
+    }
+  else
+    {
+      if (s->size >= s->max_size)
+	{
+	  return REG_ESPACE;
+	}
+      else
+	{
+	  union tre_stack_item *new_buffer;
+	  int new_size;
+	  new_size = s->size + s->increment;
+	  if (new_size > s->max_size)
+	    new_size = s->max_size;
+	  new_buffer = xrealloc(s->stack, sizeof(*new_buffer) * new_size);
+	  if (new_buffer == NULL)
+	    {
+	      return REG_ESPACE;
+	    }
+	  assert(new_size > s->size);
+	  s->size = new_size;
+	  s->stack = new_buffer;
+	  tre_stack_push(s, value);
+	}
+    }
+  return REG_OK;
+}
+
+#define define_pushf(typetag, type)  \
+  declare_pushf(typetag, type) {     \
+    union tre_stack_item item;	     \
+    item.typetag ## _value = value;  \
+    return tre_stack_push(s, item);  \
+}
+
+define_pushf(int, int)
+define_pushf(voidptr, void *)
+
+#define define_popf(typetag, type)		    \
+  declare_popf(typetag, type) {			    \
+    return s->stack[--s->ptr].typetag ## _value;    \
+  }
+
+define_popf(int, int)
+define_popf(voidptr, void *)
+
+
+/***********************************************************************
+ from tre-parse.c and tre-parse.h
+***********************************************************************/
+
+/* Parse context. */
+typedef struct {
+	/* Memory allocator. The AST is allocated using this. */
+	tre_mem_t mem;
+	/* Stack used for keeping track of regexp syntax. */
+	tre_stack_t *stack;
+	/* The parsed node after a parse function returns. */
+	tre_ast_node_t *n;
+	/* Position in the regexp pattern after a parse function returns. */
+	const char *s;
+	/* The first character of the last subexpression parsed. */
+	const char *start;
+	/* Current submatch ID. */
+	int submatch_id;
+	/* Current position (number of literal). */
+	int position;
+	/* The highest back reference or -1 if none seen so far. */
+	int max_backref;
+	/* Compilation flags. */
+	int cflags;
+} tre_parse_ctx_t;
+
+/* Some macros for expanding \w, \s, etc. */
+static const struct {
+	char c;
+	const char *expansion;
+} tre_macros[] = {
+	{'t', "\t"}, {'n', "\n"}, {'r', "\r"},
+	{'f', "\f"}, {'a', "\a"}, {'e', "\033"},
+	{'w', "[[:alnum:]_]"}, {'W', "[^[:alnum:]_]"}, {'s', "[[:space:]]"},
+	{'S', "[^[:space:]]"}, {'d', "[[:digit:]]"}, {'D', "[^[:digit:]]"},
+	{ 0, 0 }
+};
+
+/* Expands a macro delimited by `regex' and `regex_end' to `buf', which
+   must have at least `len' items.  Sets buf[0] to zero if the there
+   is no match in `tre_macros'. */
+static const char *tre_expand_macro(const char *s)
+{
+	int i;
+	for (i = 0; tre_macros[i].c && tre_macros[i].c != *s; i++);
+	return tre_macros[i].expansion;
+}
+
+static int
+tre_compare_lit(const void *a, const void *b)
+{
+	const tre_literal_t *const *la = a;
+	const tre_literal_t *const *lb = b;
+	/* assumes the range of valid code_min is < INT_MAX */
+	return la[0]->code_min - lb[0]->code_min;
+}
+
+struct literals {
+	tre_mem_t mem;
+	tre_literal_t **a;
+	int len;
+	int cap;
+};
+
+static tre_literal_t *tre_new_lit(struct literals *p)
+{
+	tre_literal_t **a;
+	if (p->len >= p->cap) {
+		if (p->cap >= 1<<15)
+			return 0;
+		p->cap *= 2;
+		a = xrealloc(p->a, p->cap * sizeof *p->a);
+		if (!a)
+			return 0;
+		p->a = a;
+	}
+	a = p->a + p->len++;
+	*a = tre_mem_calloc(p->mem, sizeof **a);
+	return *a;
+}
+
+static int add_icase_literals(struct literals *ls, int min, int max)
+{
+	tre_literal_t *lit;
+	int b, e, c;
+	for (c=min; c<=max; ) {
+		/* assumes islower(c) and isupper(c) are exclusive
+		   and toupper(c)!=c if islower(c).
+		   multiple opposite case characters are not supported */
+		if (tre_islower(c)) {
+			b = e = tre_toupper(c);
+			for (c++, e++; c<=max; c++, e++)
+				if (tre_toupper(c) != e) break;
+		} else if (tre_isupper(c)) {
+			b = e = tre_tolower(c);
+			for (c++, e++; c<=max; c++, e++)
+				if (tre_tolower(c) != e) break;
+		} else {
+			c++;
+			continue;
+		}
+		lit = tre_new_lit(ls);
+		if (!lit)
+			return -1;
+		lit->code_min = b;
+		lit->code_max = e-1;
+		lit->position = -1;
+	}
+	return 0;
+}
+
+
+/* Maximum number of character classes in a negated bracket expression. */
+#define MAX_NEG_CLASSES 64
+
+struct neg {
+	int negate;
+	int len;
+	tre_ctype_t a[MAX_NEG_CLASSES];
+};
+
+// TODO: parse bracket into a set of non-overlapping [lo,hi] ranges
+
+/*
+bracket grammar:
+Bracket  =  '[' List ']'  |  '[^' List ']'
+List     =  Term  |  List Term
+Term     =  Char  |  Range  |  Chclass  |  Eqclass
+Range    =  Char '-' Char  |  Char '-' '-'
+Char     =  Coll  |  coll_single
+Meta     =  ']'  |  '-'
+Coll     =  '[.' coll_single '.]'  |  '[.' coll_multi '.]'  |  '[.' Meta '.]'
+Eqclass  =  '[=' coll_single '=]'  |  '[=' coll_multi '=]'
+Chclass  =  '[:' class ':]'
+
+coll_single is a single char collating element but it can be
+ '-' only at the beginning or end of a List and
+ ']' only at the beginning of a List and
+ '^' anywhere except after the openning '['
+*/
+
+static reg_errcode_t parse_bracket_terms(tre_parse_ctx_t *ctx, const char *s, struct literals *ls, struct neg *neg)
+{
+	const char *start = s;
+	tre_ctype_t class;
+	int min, max;
+	wchar_t wc;
+	int len;
+
+	for (;;) {
+		class = 0;
+		len = mbtowc(&wc, s, -1);
+		if (len <= 0)
+			return *s ? REG_BADPAT : REG_EBRACK;
+		if (*s == ']' && s != start) {
+			ctx->s = s+1;
+			return REG_OK;
+		}
+		if (*s == '-' && s != start && s[1] != ']' &&
+		    /* extension: [a-z--@] is accepted as [a-z]|[--@] */
+		    (s[1] != '-' || s[2] == ']'))
+			return REG_ERANGE;
+		if (*s == '[' && (s[1] == '.' || s[1] == '='))
+			/* collating symbols and equivalence classes are not supported */
+			return REG_ECOLLATE;
+		if (*s == '[' && s[1] == ':') {
+			char tmp[CHARCLASS_NAME_MAX+1];
+			s += 2;
+			for (len=0; len < CHARCLASS_NAME_MAX && s[len]; len++) {
+				if (s[len] == ':') {
+					memcpy(tmp, s, len);
+					tmp[len] = 0;
+					class = tre_ctype(tmp);
+					break;
+				}
+			}
+			if (!class || s[len+1] != ']')
+				return REG_ECTYPE;
+			min = 0;
+			max = TRE_CHAR_MAX;
+			s += len+2;
+		} else {
+			min = max = wc;
+			s += len;
+			if (*s == '-' && s[1] != ']') {
+				s++;
+				len = mbtowc(&wc, s, -1);
+				max = wc;
+				/* XXX - Should use collation order instead of
+				   encoding values in character ranges. */
+				if (len <= 0 || min > max)
+					return REG_ERANGE;
+				s += len;
+			}
+		}
+
+		if (class && neg->negate) {
+			if (neg->len >= MAX_NEG_CLASSES)
+				return REG_ESPACE;
+			neg->a[neg->len++] = class;
+		} else  {
+			tre_literal_t *lit = tre_new_lit(ls);
+			if (!lit)
+				return REG_ESPACE;
+			lit->code_min = min;
+			lit->code_max = max;
+			lit->class = class;
+			lit->position = -1;
+
+			/* Add opposite-case codepoints if REG_ICASE is present.
+			   It seems that POSIX requires that bracket negation
+			   should happen before case-folding, but most practical
+			   implementations do it the other way around. Changing
+			   the order would need efficient representation of
+			   case-fold ranges and bracket range sets even with
+			   simple patterns so this is ok for now. */
+			if (ctx->cflags & REG_ICASE && !class)
+				if (add_icase_literals(ls, min, max))
+					return REG_ESPACE;
+		}
+	}
+}
+
+static reg_errcode_t parse_bracket(tre_parse_ctx_t *ctx, const char *s)
+{
+	int i, max, min, negmax, negmin;
+	tre_ast_node_t *node = 0, *n;
+	tre_ctype_t *nc = 0;
+	tre_literal_t *lit;
+	struct literals ls;
+	struct neg neg;
+	reg_errcode_t err;
+
+	ls.mem = ctx->mem;
+	ls.len = 0;
+	ls.cap = 32;
+	ls.a = xmalloc(ls.cap * sizeof *ls.a);
+	if (!ls.a)
+		return REG_ESPACE;
+	neg.len = 0;
+	neg.negate = *s == '^';
+	if (neg.negate)
+		s++;
+
+	err = parse_bracket_terms(ctx, s, &ls, &neg);
+	if (err != REG_OK)
+		goto parse_bracket_done;
+
+	if (neg.negate) {
+		/*
+		 * With REG_NEWLINE, POSIX requires that newlines are not matched by
+		 * any form of a non-matching list.
+		 */
+		if (ctx->cflags & REG_NEWLINE) {
+			lit = tre_new_lit(&ls);
+			if (!lit) {
+				err = REG_ESPACE;
+				goto parse_bracket_done;
+			}
+			lit->code_min = '\n';
+			lit->code_max = '\n';
+			lit->position = -1;
+		}
+		/* Sort the array if we need to negate it. */
+		qsort(ls.a, ls.len, sizeof *ls.a, tre_compare_lit);
+		/* extra lit for the last negated range */
+		lit = tre_new_lit(&ls);
+		if (!lit) {
+			err = REG_ESPACE;
+			goto parse_bracket_done;
+		}
+		lit->code_min = TRE_CHAR_MAX+1;
+		lit->code_max = TRE_CHAR_MAX+1;
+		lit->position = -1;
+		/* negated classes */
+		if (neg.len) {
+			nc = tre_mem_alloc(ctx->mem, (neg.len+1)*sizeof *neg.a);
+			if (!nc) {
+				err = REG_ESPACE;
+				goto parse_bracket_done;
+			}
+			memcpy(nc, neg.a, neg.len*sizeof *neg.a);
+			nc[neg.len] = 0;
+		}
+	}
+
+	/* Build a union of the items in the array, negated if necessary. */
+	negmax = negmin = 0;
+	for (i = 0; i < ls.len; i++) {
+		lit = ls.a[i];
+		min = lit->code_min;
+		max = lit->code_max;
+		if (neg.negate) {
+			if (min <= negmin) {
+				/* Overlap. */
+				negmin = MAX(max + 1, negmin);
+				continue;
+			}
+			negmax = min - 1;
+			lit->code_min = negmin;
+			lit->code_max = negmax;
+			negmin = max + 1;
+		}
+		lit->position = ctx->position;
+		lit->neg_classes = nc;
+		n = tre_ast_new_node(ctx->mem, LITERAL, lit);
+		node = tre_ast_new_union(ctx->mem, node, n);
+		if (!node) {
+			err = REG_ESPACE;
+			break;
+		}
+	}
+
+parse_bracket_done:
+	xfree(ls.a);
+	ctx->position++;
+	ctx->n = node;
+	return err;
+}
+
+static const char *parse_dup_count(const char *s, int *n)
+{
+	*n = -1;
+	if (!isdigit(*s))
+		return s;
+	*n = 0;
+	for (;;) {
+		*n = 10 * *n + (*s - '0');
+		s++;
+		if (!isdigit(*s) || *n > RE_DUP_MAX)
+			break;
+	}
+	return s;
+}
+
+static const char *parse_dup(const char *s, int ere, int *pmin, int *pmax)
+{
+	int min, max;
+
+	s = parse_dup_count(s, &min);
+	if (*s == ',')
+		s = parse_dup_count(s+1, &max);
+	else
+		max = min;
+
+	if (
+		(max < min && max >= 0) ||
+		max > RE_DUP_MAX ||
+		min > RE_DUP_MAX ||
+		min < 0 ||
+		(!ere && *s++ != '\\') ||
+		*s++ != '}'
+	)
+		return 0;
+	*pmin = min;
+	*pmax = max;
+	return s;
+}
+
+static int hexval(unsigned c)
+{
+	if (c-'0'<10) return c-'0';
+	c |= 32;
+	if (c-'a'<6) return c-'a'+10;
+	return -1;
+}
+
+static reg_errcode_t marksub(tre_parse_ctx_t *ctx, tre_ast_node_t *node, int subid)
+{
+	if (node->submatch_id >= 0) {
+		tre_ast_node_t *n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+		if (!n)
+			return REG_ESPACE;
+		n = tre_ast_new_catenation(ctx->mem, n, node);
+		if (!n)
+			return REG_ESPACE;
+		n->num_submatches = node->num_submatches;
+		node = n;
+	}
+	node->submatch_id = subid;
+	node->num_submatches++;
+	ctx->n = node;
+	return REG_OK;
+}
+
+/*
+BRE grammar:
+Regex  =  Branch  |  '^'  |  '$'  |  '^$'  |  '^' Branch  |  Branch '$'  |  '^' Branch '$'
+Branch =  Atom  |  Branch Atom
+Atom   =  char  |  quoted_char  |  '.'  |  Bracket  |  Atom Dup  |  '\(' Branch '\)'  |  back_ref
+Dup    =  '*'  |  '\{' Count '\}'  |  '\{' Count ',\}'  |  '\{' Count ',' Count '\}'
+
+(leading ^ and trailing $ in a sub expr may be an anchor or literal as well)
+
+ERE grammar:
+Regex  =  Branch  |  Regex '|' Branch
+Branch =  Atom  |  Branch Atom
+Atom   =  char  |  quoted_char  |  '.'  |  Bracket  |  Atom Dup  |  '(' Regex ')'  |  '^'  |  '$'
+Dup    =  '*'  |  '+'  |  '?'  |  '{' Count '}'  |  '{' Count ',}'  |  '{' Count ',' Count '}'
+
+(a*+?, ^*, $+, \X, {, (|a) are unspecified)
+*/
+
+static reg_errcode_t parse_atom(tre_parse_ctx_t *ctx, const char *s)
+{
+	int len, ere = ctx->cflags & REG_EXTENDED;
+	const char *p;
+	tre_ast_node_t *node;
+	wchar_t wc;
+	switch (*s) {
+	case '[':
+		return parse_bracket(ctx, s+1);
+	case '\\':
+		p = tre_expand_macro(s+1);
+		if (p) {
+			/* assume \X expansion is a single atom */
+			reg_errcode_t err = parse_atom(ctx, p);
+			ctx->s = s+2;
+			return err;
+		}
+		/* extensions: \b, \B, \<, \>, \xHH \x{HHHH} */
+		switch (*++s) {
+		case 0:
+			return REG_EESCAPE;
+		case 'b':
+			node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB, -1);
+			break;
+		case 'B':
+			node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB_NEG, -1);
+			break;
+		case '<':
+			node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOW, -1);
+			break;
+		case '>':
+			node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOW, -1);
+			break;
+		case 'x':
+			s++;
+			int i, v = 0, c;
+			len = 2;
+			if (*s == '{') {
+				len = 8;
+				s++;
+			}
+			for (i=0; i<len && v<0x110000; i++) {
+				c = hexval(s[i]);
+				if (c < 0) break;
+				v = 16*v + c;
+			}
+			s += i;
+			if (len == 8) {
+				if (*s != '}')
+					return REG_EBRACE;
+				s++;
+			}
+			node = tre_ast_new_literal(ctx->mem, v, v, ctx->position++);
+			s--;
+			break;
+		case '{':
+		case '+':
+		case '?':
+			/* extension: treat \+, \? as repetitions in BRE */
+			/* reject repetitions after empty expression in BRE */
+			if (!ere)
+				return REG_BADRPT;
+		case '|':
+			/* extension: treat \| as alternation in BRE */
+			if (!ere) {
+				node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+				s--;
+				goto end;
+			}
+			/* fallthrough */
+		default:
+			if (!ere && (unsigned)*s-'1' < 9) {
+				/* back reference */
+				int val = *s - '0';
+				node = tre_ast_new_literal(ctx->mem, BACKREF, val, ctx->position++);
+				ctx->max_backref = MAX(val, ctx->max_backref);
+			} else {
+				/* extension: accept unknown escaped char
+				   as a literal */
+				goto parse_literal;
+			}
+		}
+		s++;
+		break;
+	case '.':
+		if (ctx->cflags & REG_NEWLINE) {
+			tre_ast_node_t *tmp1, *tmp2;
+			tmp1 = tre_ast_new_literal(ctx->mem, 0, '\n'-1, ctx->position++);
+			tmp2 = tre_ast_new_literal(ctx->mem, '\n'+1, TRE_CHAR_MAX, ctx->position++);
+			if (tmp1 && tmp2)
+				node = tre_ast_new_union(ctx->mem, tmp1, tmp2);
+			else
+				node = 0;
+		} else {
+			node = tre_ast_new_literal(ctx->mem, 0, TRE_CHAR_MAX, ctx->position++);
+		}
+		s++;
+		break;
+	case '^':
+		/* '^' has a special meaning everywhere in EREs, and at beginning of BRE. */
+		if (!ere && s != ctx->start)
+			goto parse_literal;
+		node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOL, -1);
+		s++;
+		break;
+	case '$':
+		/* '$' is special everywhere in EREs, and at the end of a BRE subexpression. */
+		if (!ere && s[1] && (s[1]!='\\'|| (s[2]!=')' && s[2]!='|')))
+			goto parse_literal;
+		node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOL, -1);
+		s++;
+		break;
+	case '*':
+	case '{':
+	case '+':
+	case '?':
+		/* reject repetitions after empty expression in ERE */
+		if (ere)
+			return REG_BADRPT;
+	case '|':
+		if (!ere)
+			goto parse_literal;
+	case 0:
+		node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+		break;
+	default:
+parse_literal:
+		len = mbtowc(&wc, s, -1);
+		if (len < 0)
+			return REG_BADPAT;
+		if (ctx->cflags & REG_ICASE && (tre_isupper(wc) || tre_islower(wc))) {
+			tre_ast_node_t *tmp1, *tmp2;
+			/* multiple opposite case characters are not supported */
+			tmp1 = tre_ast_new_literal(ctx->mem, tre_toupper(wc), tre_toupper(wc), ctx->position);
+			tmp2 = tre_ast_new_literal(ctx->mem, tre_tolower(wc), tre_tolower(wc), ctx->position);
+			if (tmp1 && tmp2)
+				node = tre_ast_new_union(ctx->mem, tmp1, tmp2);
+			else
+				node = 0;
+		} else {
+			node = tre_ast_new_literal(ctx->mem, wc, wc, ctx->position);
+		}
+		ctx->position++;
+		s += len;
+		break;
+	}
+end:
+	if (!node)
+		return REG_ESPACE;
+	ctx->n = node;
+	ctx->s = s;
+	return REG_OK;
+}
+
+#define PUSHPTR(err, s, v) do { \
+	if ((err = tre_stack_push_voidptr(s, v)) != REG_OK) \
+		return err; \
+} while(0)
+
+#define PUSHINT(err, s, v) do { \
+	if ((err = tre_stack_push_int(s, v)) != REG_OK) \
+		return err; \
+} while(0)
+
+static reg_errcode_t tre_parse(tre_parse_ctx_t *ctx)
+{
+	tre_ast_node_t *nbranch=0, *nunion=0;
+	int ere = ctx->cflags & REG_EXTENDED;
+	const char *s = ctx->start;
+	int subid = 0;
+	int depth = 0;
+	reg_errcode_t err;
+	tre_stack_t *stack = ctx->stack;
+
+	PUSHINT(err, stack, subid++);
+	for (;;) {
+		if ((!ere && *s == '\\' && s[1] == '(') ||
+		    (ere && *s == '(')) {
+			PUSHPTR(err, stack, nunion);
+			PUSHPTR(err, stack, nbranch);
+			PUSHINT(err, stack, subid++);
+			s++;
+			if (!ere)
+				s++;
+			depth++;
+			nbranch = nunion = 0;
+			ctx->start = s;
+			continue;
+		}
+		if ((!ere && *s == '\\' && s[1] == ')') ||
+		    (ere && *s == ')' && depth)) {
+			ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+			if (!ctx->n)
+				return REG_ESPACE;
+		} else {
+			err = parse_atom(ctx, s);
+			if (err != REG_OK)
+				return err;
+			s = ctx->s;
+		}
+
+	parse_iter:
+		for (;;) {
+			int min, max;
+
+			if (*s!='\\' && *s!='*') {
+				if (!ere)
+					break;
+				if (*s!='+' && *s!='?' && *s!='{')
+					break;
+			}
+			if (*s=='\\' && ere)
+				break;
+			/* extension: treat \+, \? as repetitions in BRE */
+			if (*s=='\\' && s[1]!='+' && s[1]!='?' && s[1]!='{')
+				break;
+			if (*s=='\\')
+				s++;
+
+			/* handle ^* at the start of a BRE. */
+			if (!ere && s==ctx->start+1 && s[-1]=='^')
+				break;
+
+			/* extension: multiple consecutive *+?{,} is unspecified,
+			   but (a+)+ has to be supported so accepting a++ makes
+			   sense, note however that the RE_DUP_MAX limit can be
+			   circumvented: (a{255}){255} uses a lot of memory.. */
+			if (*s=='{') {
+				s = parse_dup(s+1, ere, &min, &max);
+				if (!s)
+					return REG_BADBR;
+			} else {
+				min=0;
+				max=-1;
+				if (*s == '+')
+					min = 1;
+				if (*s == '?')
+					max = 1;
+				s++;
+			}
+			if (max == 0)
+				ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
+			else
+				ctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0);
+			if (!ctx->n)
+				return REG_ESPACE;
+		}
+
+		nbranch = tre_ast_new_catenation(ctx->mem, nbranch, ctx->n);
+		if ((ere && *s == '|') ||
+		    (ere && *s == ')' && depth) ||
+		    (!ere && *s == '\\' && s[1] == ')') ||
+		    /* extension: treat \| as alternation in BRE */
+		    (!ere && *s == '\\' && s[1] == '|') ||
+		    !*s) {
+			/* extension: empty branch is unspecified (), (|a), (a|)
+			   here they are not rejected but match on empty string */
+			int c = *s;
+			nunion = tre_ast_new_union(ctx->mem, nunion, nbranch);
+			nbranch = 0;
+
+			if (c == '\\' && s[1] == '|') {
+				s+=2;
+				ctx->start = s;
+			} else if (c == '|') {
+				s++;
+				ctx->start = s;
+			} else {
+				if (c == '\\') {
+					if (!depth) return REG_EPAREN;
+					s+=2;
+				} else if (c == ')')
+					s++;
+				depth--;
+				err = marksub(ctx, nunion, tre_stack_pop_int(stack));
+				if (err != REG_OK)
+					return err;
+				if (!c && depth<0) {
+					ctx->submatch_id = subid;
+					return REG_OK;
+				}
+				if (!c || depth<0)
+					return REG_EPAREN;
+				nbranch = tre_stack_pop_voidptr(stack);
+				nunion = tre_stack_pop_voidptr(stack);
+				goto parse_iter;
+			}
+		}
+	}
+}
+
+
+/***********************************************************************
+ from tre-compile.c
+***********************************************************************/
+
+
+/*
+  TODO:
+   - Fix tre_ast_to_tnfa() to recurse using a stack instead of recursive
+     function calls.
+*/
+
+/*
+  Algorithms to setup tags so that submatch addressing can be done.
+*/
+
+
+/* Inserts a catenation node to the root of the tree given in `node'.
+   As the left child a new tag with number `tag_id' to `node' is added,
+   and the right child is the old root. */
+static reg_errcode_t
+tre_add_tag_left(tre_mem_t mem, tre_ast_node_t *node, int tag_id)
+{
+  tre_catenation_t *c;
+
+  c = tre_mem_alloc(mem, sizeof(*c));
+  if (c == NULL)
+    return REG_ESPACE;
+  c->left = tre_ast_new_literal(mem, TAG, tag_id, -1);
+  if (c->left == NULL)
+    return REG_ESPACE;
+  c->right = tre_mem_alloc(mem, sizeof(tre_ast_node_t));
+  if (c->right == NULL)
+    return REG_ESPACE;
+
+  c->right->obj = node->obj;
+  c->right->type = node->type;
+  c->right->nullable = -1;
+  c->right->submatch_id = -1;
+  c->right->firstpos = NULL;
+  c->right->lastpos = NULL;
+  c->right->num_tags = 0;
+  c->right->num_submatches = 0;
+  node->obj = c;
+  node->type = CATENATION;
+  return REG_OK;
+}
+
+/* Inserts a catenation node to the root of the tree given in `node'.
+   As the right child a new tag with number `tag_id' to `node' is added,
+   and the left child is the old root. */
+static reg_errcode_t
+tre_add_tag_right(tre_mem_t mem, tre_ast_node_t *node, int tag_id)
+{
+  tre_catenation_t *c;
+
+  c = tre_mem_alloc(mem, sizeof(*c));
+  if (c == NULL)
+    return REG_ESPACE;
+  c->right = tre_ast_new_literal(mem, TAG, tag_id, -1);
+  if (c->right == NULL)
+    return REG_ESPACE;
+  c->left = tre_mem_alloc(mem, sizeof(tre_ast_node_t));
+  if (c->left == NULL)
+    return REG_ESPACE;
+
+  c->left->obj = node->obj;
+  c->left->type = node->type;
+  c->left->nullable = -1;
+  c->left->submatch_id = -1;
+  c->left->firstpos = NULL;
+  c->left->lastpos = NULL;
+  c->left->num_tags = 0;
+  c->left->num_submatches = 0;
+  node->obj = c;
+  node->type = CATENATION;
+  return REG_OK;
+}
+
+typedef enum {
+  ADDTAGS_RECURSE,
+  ADDTAGS_AFTER_ITERATION,
+  ADDTAGS_AFTER_UNION_LEFT,
+  ADDTAGS_AFTER_UNION_RIGHT,
+  ADDTAGS_AFTER_CAT_LEFT,
+  ADDTAGS_AFTER_CAT_RIGHT,
+  ADDTAGS_SET_SUBMATCH_END
+} tre_addtags_symbol_t;
+
+
+typedef struct {
+  int tag;
+  int next_tag;
+} tre_tag_states_t;
+
+
+/* Go through `regset' and set submatch data for submatches that are
+   using this tag. */
+static void
+tre_purge_regset(int *regset, tre_tnfa_t *tnfa, int tag)
+{
+  int i;
+
+  for (i = 0; regset[i] >= 0; i++)
+    {
+      int id = regset[i] / 2;
+      int start = !(regset[i] % 2);
+      if (start)
+	tnfa->submatch_data[id].so_tag = tag;
+      else
+	tnfa->submatch_data[id].eo_tag = tag;
+    }
+  regset[0] = -1;
+}
+
+
+/* Adds tags to appropriate locations in the parse tree in `tree', so that
+   subexpressions marked for submatch addressing can be traced. */
+static reg_errcode_t
+tre_add_tags(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree,
+	     tre_tnfa_t *tnfa)
+{
+  reg_errcode_t status = REG_OK;
+  tre_addtags_symbol_t symbol;
+  tre_ast_node_t *node = tree; /* Tree node we are currently looking at. */
+  int bottom = tre_stack_num_objects(stack);
+  /* True for first pass (counting number of needed tags) */
+  int first_pass = (mem == NULL || tnfa == NULL);
+  int *regset, *orig_regset;
+  int num_tags = 0; /* Total number of tags. */
+  int num_minimals = 0;	 /* Number of special minimal tags. */
+  int tag = 0;	    /* The tag that is to be added next. */
+  int next_tag = 1; /* Next tag to use after this one. */
+  int *parents;	    /* Stack of submatches the current submatch is
+		       contained in. */
+  int minimal_tag = -1; /* Tag that marks the beginning of a minimal match. */
+  tre_tag_states_t *saved_states;
+
+  tre_tag_direction_t direction = TRE_TAG_MINIMIZE;
+  if (!first_pass)
+    {
+      tnfa->end_tag = 0;
+      tnfa->minimal_tags[0] = -1;
+    }
+
+  regset = xmalloc(sizeof(*regset) * ((tnfa->num_submatches + 1) * 2));
+  if (regset == NULL)
+    return REG_ESPACE;
+  regset[0] = -1;
+  orig_regset = regset;
+
+  parents = xmalloc(sizeof(*parents) * (tnfa->num_submatches + 1));
+  if (parents == NULL)
+    {
+      xfree(regset);
+      return REG_ESPACE;
+    }
+  parents[0] = -1;
+
+  saved_states = xmalloc(sizeof(*saved_states) * (tnfa->num_submatches + 1));
+  if (saved_states == NULL)
+    {
+      xfree(regset);
+      xfree(parents);
+      return REG_ESPACE;
+    }
+  else
+    {
+      unsigned int i;
+      for (i = 0; i <= tnfa->num_submatches; i++)
+	saved_states[i].tag = -1;
+    }
+
+  STACK_PUSH(stack, voidptr, node);
+  STACK_PUSH(stack, int, ADDTAGS_RECURSE);
+
+  while (tre_stack_num_objects(stack) > bottom)
+    {
+      if (status != REG_OK)
+	break;
+
+      symbol = (tre_addtags_symbol_t)tre_stack_pop_int(stack);
+      switch (symbol)
+	{
+
+	case ADDTAGS_SET_SUBMATCH_END:
+	  {
+	    int id = tre_stack_pop_int(stack);
+	    int i;
+
+	    /* Add end of this submatch to regset. */
+	    for (i = 0; regset[i] >= 0; i++);
+	    regset[i] = id * 2 + 1;
+	    regset[i + 1] = -1;
+
+	    /* Pop this submatch from the parents stack. */
+	    for (i = 0; parents[i] >= 0; i++);
+	    parents[i - 1] = -1;
+	    break;
+	  }
+
+	case ADDTAGS_RECURSE:
+	  node = tre_stack_pop_voidptr(stack);
+
+	  if (node->submatch_id >= 0)
+	    {
+	      int id = node->submatch_id;
+	      int i;
+
+
+	      /* Add start of this submatch to regset. */
+	      for (i = 0; regset[i] >= 0; i++);
+	      regset[i] = id * 2;
+	      regset[i + 1] = -1;
+
+	      if (!first_pass)
+		{
+		  for (i = 0; parents[i] >= 0; i++);
+		  tnfa->submatch_data[id].parents = NULL;
+		  if (i > 0)
+		    {
+		      int *p = xmalloc(sizeof(*p) * (i + 1));
+		      if (p == NULL)
+			{
+			  status = REG_ESPACE;
+			  break;
+			}
+		      assert(tnfa->submatch_data[id].parents == NULL);
+		      tnfa->submatch_data[id].parents = p;
+		      for (i = 0; parents[i] >= 0; i++)
+			p[i] = parents[i];
+		      p[i] = -1;
+		    }
+		}
+
+	      /* Add end of this submatch to regset after processing this
+		 node. */
+	      STACK_PUSHX(stack, int, node->submatch_id);
+	      STACK_PUSHX(stack, int, ADDTAGS_SET_SUBMATCH_END);
+	    }
+
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit = node->obj;
+
+		if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
+		  {
+		    int i;
+		    if (regset[0] >= 0)
+		      {
+			/* Regset is not empty, so add a tag before the
+			   literal or backref. */
+			if (!first_pass)
+			  {
+			    status = tre_add_tag_left(mem, node, tag);
+			    tnfa->tag_directions[tag] = direction;
+			    if (minimal_tag >= 0)
+			      {
+				for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
+				tnfa->minimal_tags[i] = tag;
+				tnfa->minimal_tags[i + 1] = minimal_tag;
+				tnfa->minimal_tags[i + 2] = -1;
+				minimal_tag = -1;
+				num_minimals++;
+			      }
+			    tre_purge_regset(regset, tnfa, tag);
+			  }
+			else
+			  {
+			    node->num_tags = 1;
+			  }
+
+			regset[0] = -1;
+			tag = next_tag;
+			num_tags++;
+			next_tag++;
+		      }
+		  }
+		else
+		  {
+		    assert(!IS_TAG(lit));
+		  }
+		break;
+	      }
+	    case CATENATION:
+	      {
+		tre_catenation_t *cat = node->obj;
+		tre_ast_node_t *left = cat->left;
+		tre_ast_node_t *right = cat->right;
+		int reserved_tag = -1;
+
+
+		/* After processing right child. */
+		STACK_PUSHX(stack, voidptr, node);
+		STACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_RIGHT);
+
+		/* Process right child. */
+		STACK_PUSHX(stack, voidptr, right);
+		STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
+
+		/* After processing left child. */
+		STACK_PUSHX(stack, int, next_tag + left->num_tags);
+		if (left->num_tags > 0 && right->num_tags > 0)
+		  {
+		    /* Reserve the next tag to the right child. */
+		    reserved_tag = next_tag;
+		    next_tag++;
+		  }
+		STACK_PUSHX(stack, int, reserved_tag);
+		STACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_LEFT);
+
+		/* Process left child. */
+		STACK_PUSHX(stack, voidptr, left);
+		STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
+
+		}
+	      break;
+	    case ITERATION:
+	      {
+		tre_iteration_t *iter = node->obj;
+
+		if (first_pass)
+		  {
+		    STACK_PUSHX(stack, int, regset[0] >= 0 || iter->minimal);
+		  }
+		else
+		  {
+		    STACK_PUSHX(stack, int, tag);
+		    STACK_PUSHX(stack, int, iter->minimal);
+		  }
+		STACK_PUSHX(stack, voidptr, node);
+		STACK_PUSHX(stack, int, ADDTAGS_AFTER_ITERATION);
+
+		STACK_PUSHX(stack, voidptr, iter->arg);
+		STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
+
+		/* Regset is not empty, so add a tag here. */
+		if (regset[0] >= 0 || iter->minimal)
+		  {
+		    if (!first_pass)
+		      {
+			int i;
+			status = tre_add_tag_left(mem, node, tag);
+			if (iter->minimal)
+			  tnfa->tag_directions[tag] = TRE_TAG_MAXIMIZE;
+			else
+			  tnfa->tag_directions[tag] = direction;
+			if (minimal_tag >= 0)
+			  {
+			    for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
+			    tnfa->minimal_tags[i] = tag;
+			    tnfa->minimal_tags[i + 1] = minimal_tag;
+			    tnfa->minimal_tags[i + 2] = -1;
+			    minimal_tag = -1;
+			    num_minimals++;
+			  }
+			tre_purge_regset(regset, tnfa, tag);
+		      }
+
+		    regset[0] = -1;
+		    tag = next_tag;
+		    num_tags++;
+		    next_tag++;
+		  }
+		direction = TRE_TAG_MINIMIZE;
+	      }
+	      break;
+	    case UNION:
+	      {
+		tre_union_t *uni = node->obj;
+		tre_ast_node_t *left = uni->left;
+		tre_ast_node_t *right = uni->right;
+		int left_tag;
+		int right_tag;
+
+		if (regset[0] >= 0)
+		  {
+		    left_tag = next_tag;
+		    right_tag = next_tag + 1;
+		  }
+		else
+		  {
+		    left_tag = tag;
+		    right_tag = next_tag;
+		  }
+
+		/* After processing right child. */
+		STACK_PUSHX(stack, int, right_tag);
+		STACK_PUSHX(stack, int, left_tag);
+		STACK_PUSHX(stack, voidptr, regset);
+		STACK_PUSHX(stack, int, regset[0] >= 0);
+		STACK_PUSHX(stack, voidptr, node);
+		STACK_PUSHX(stack, voidptr, right);
+		STACK_PUSHX(stack, voidptr, left);
+		STACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_RIGHT);
+
+		/* Process right child. */
+		STACK_PUSHX(stack, voidptr, right);
+		STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
+
+		/* After processing left child. */
+		STACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_LEFT);
+
+		/* Process left child. */
+		STACK_PUSHX(stack, voidptr, left);
+		STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
+
+		/* Regset is not empty, so add a tag here. */
+		if (regset[0] >= 0)
+		  {
+		    if (!first_pass)
+		      {
+			int i;
+			status = tre_add_tag_left(mem, node, tag);
+			tnfa->tag_directions[tag] = direction;
+			if (minimal_tag >= 0)
+			  {
+			    for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
+			    tnfa->minimal_tags[i] = tag;
+			    tnfa->minimal_tags[i + 1] = minimal_tag;
+			    tnfa->minimal_tags[i + 2] = -1;
+			    minimal_tag = -1;
+			    num_minimals++;
+			  }
+			tre_purge_regset(regset, tnfa, tag);
+		      }
+
+		    regset[0] = -1;
+		    tag = next_tag;
+		    num_tags++;
+		    next_tag++;
+		  }
+
+		if (node->num_submatches > 0)
+		  {
+		    /* The next two tags are reserved for markers. */
+		    next_tag++;
+		    tag = next_tag;
+		    next_tag++;
+		  }
+
+		break;
+	      }
+	    }
+
+	  if (node->submatch_id >= 0)
+	    {
+	      int i;
+	      /* Push this submatch on the parents stack. */
+	      for (i = 0; parents[i] >= 0; i++);
+	      parents[i] = node->submatch_id;
+	      parents[i + 1] = -1;
+	    }
+
+	  break; /* end case: ADDTAGS_RECURSE */
+
+	case ADDTAGS_AFTER_ITERATION:
+	  {
+	    int minimal = 0;
+	    int enter_tag;
+	    node = tre_stack_pop_voidptr(stack);
+	    if (first_pass)
+	      {
+		node->num_tags = ((tre_iteration_t *)node->obj)->arg->num_tags
+		  + tre_stack_pop_int(stack);
+		minimal_tag = -1;
+	      }
+	    else
+	      {
+		minimal = tre_stack_pop_int(stack);
+		enter_tag = tre_stack_pop_int(stack);
+		if (minimal)
+		  minimal_tag = enter_tag;
+	      }
+
+	    if (!first_pass)
+	      {
+		if (minimal)
+		  direction = TRE_TAG_MINIMIZE;
+		else
+		  direction = TRE_TAG_MAXIMIZE;
+	      }
+	    break;
+	  }
+
+	case ADDTAGS_AFTER_CAT_LEFT:
+	  {
+	    int new_tag = tre_stack_pop_int(stack);
+	    next_tag = tre_stack_pop_int(stack);
+	    if (new_tag >= 0)
+	      {
+		tag = new_tag;
+	      }
+	    break;
+	  }
+
+	case ADDTAGS_AFTER_CAT_RIGHT:
+	  node = tre_stack_pop_voidptr(stack);
+	  if (first_pass)
+	    node->num_tags = ((tre_catenation_t *)node->obj)->left->num_tags
+	      + ((tre_catenation_t *)node->obj)->right->num_tags;
+	  break;
+
+	case ADDTAGS_AFTER_UNION_LEFT:
+	  /* Lift the bottom of the `regset' array so that when processing
+	     the right operand the items currently in the array are
+	     invisible.	 The original bottom was saved at ADDTAGS_UNION and
+	     will be restored at ADDTAGS_AFTER_UNION_RIGHT below. */
+	  while (*regset >= 0)
+	    regset++;
+	  break;
+
+	case ADDTAGS_AFTER_UNION_RIGHT:
+	  {
+	    int added_tags, tag_left, tag_right;
+	    tre_ast_node_t *left = tre_stack_pop_voidptr(stack);
+	    tre_ast_node_t *right = tre_stack_pop_voidptr(stack);
+	    node = tre_stack_pop_voidptr(stack);
+	    added_tags = tre_stack_pop_int(stack);
+	    if (first_pass)
+	      {
+		node->num_tags = ((tre_union_t *)node->obj)->left->num_tags
+		  + ((tre_union_t *)node->obj)->right->num_tags + added_tags
+		  + ((node->num_submatches > 0) ? 2 : 0);
+	      }
+	    regset = tre_stack_pop_voidptr(stack);
+	    tag_left = tre_stack_pop_int(stack);
+	    tag_right = tre_stack_pop_int(stack);
+
+	    /* Add tags after both children, the left child gets a smaller
+	       tag than the right child.  This guarantees that we prefer
+	       the left child over the right child. */
+	    /* XXX - This is not always necessary (if the children have
+	       tags which must be seen for every match of that child). */
+	    /* XXX - Check if this is the only place where tre_add_tag_right
+	       is used.	 If so, use tre_add_tag_left (putting the tag before
+	       the child as opposed after the child) and throw away
+	       tre_add_tag_right. */
+	    if (node->num_submatches > 0)
+	      {
+		if (!first_pass)
+		  {
+		    status = tre_add_tag_right(mem, left, tag_left);
+		    tnfa->tag_directions[tag_left] = TRE_TAG_MAXIMIZE;
+		    if (status == REG_OK)
+		      status = tre_add_tag_right(mem, right, tag_right);
+		    tnfa->tag_directions[tag_right] = TRE_TAG_MAXIMIZE;
+		  }
+		num_tags += 2;
+	      }
+	    direction = TRE_TAG_MAXIMIZE;
+	    break;
+	  }
+
+	default:
+	  assert(0);
+	  break;
+
+	} /* end switch(symbol) */
+    } /* end while(tre_stack_num_objects(stack) > bottom) */
+
+  if (!first_pass)
+    tre_purge_regset(regset, tnfa, tag);
+
+  if (!first_pass && minimal_tag >= 0)
+    {
+      int i;
+      for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
+      tnfa->minimal_tags[i] = tag;
+      tnfa->minimal_tags[i + 1] = minimal_tag;
+      tnfa->minimal_tags[i + 2] = -1;
+      minimal_tag = -1;
+      num_minimals++;
+    }
+
+  assert(tree->num_tags == num_tags);
+  tnfa->end_tag = num_tags;
+  tnfa->num_tags = num_tags;
+  tnfa->num_minimals = num_minimals;
+  xfree(orig_regset);
+  xfree(parents);
+  xfree(saved_states);
+  return status;
+}
+
+
+
+/*
+  AST to TNFA compilation routines.
+*/
+
+typedef enum {
+  COPY_RECURSE,
+  COPY_SET_RESULT_PTR
+} tre_copyast_symbol_t;
+
+/* Flags for tre_copy_ast(). */
+#define COPY_REMOVE_TAGS	 1
+#define COPY_MAXIMIZE_FIRST_TAG	 2
+
+static reg_errcode_t
+tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
+	     int flags, int *pos_add, tre_tag_direction_t *tag_directions,
+	     tre_ast_node_t **copy, int *max_pos)
+{
+  reg_errcode_t status = REG_OK;
+  int bottom = tre_stack_num_objects(stack);
+  int num_copied = 0;
+  int first_tag = 1;
+  tre_ast_node_t **result = copy;
+  tre_copyast_symbol_t symbol;
+
+  STACK_PUSH(stack, voidptr, ast);
+  STACK_PUSH(stack, int, COPY_RECURSE);
+
+  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
+    {
+      tre_ast_node_t *node;
+      if (status != REG_OK)
+	break;
+
+      symbol = (tre_copyast_symbol_t)tre_stack_pop_int(stack);
+      switch (symbol)
+	{
+	case COPY_SET_RESULT_PTR:
+	  result = tre_stack_pop_voidptr(stack);
+	  break;
+	case COPY_RECURSE:
+	  node = tre_stack_pop_voidptr(stack);
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit = node->obj;
+		int pos = lit->position;
+		int min = lit->code_min;
+		int max = lit->code_max;
+		if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
+		  {
+		    /* XXX - e.g. [ab] has only one position but two
+		       nodes, so we are creating holes in the state space
+		       here.  Not fatal, just wastes memory. */
+		    pos += *pos_add;
+		    num_copied++;
+		  }
+		else if (IS_TAG(lit) && (flags & COPY_REMOVE_TAGS))
+		  {
+		    /* Change this tag to empty. */
+		    min = EMPTY;
+		    max = pos = -1;
+		  }
+		else if (IS_TAG(lit) && (flags & COPY_MAXIMIZE_FIRST_TAG)
+			 && first_tag)
+		  {
+		    /* Maximize the first tag. */
+		    tag_directions[max] = TRE_TAG_MAXIMIZE;
+		    first_tag = 0;
+		  }
+		*result = tre_ast_new_literal(mem, min, max, pos);
+		if (*result == NULL)
+		  status = REG_ESPACE;
+		else {
+		  tre_literal_t *p = (*result)->obj;
+		  p->class = lit->class;
+		  p->neg_classes = lit->neg_classes;
+		}
+
+		if (pos > *max_pos)
+		  *max_pos = pos;
+		break;
+	      }
+	    case UNION:
+	      {
+		tre_union_t *uni = node->obj;
+		tre_union_t *tmp;
+		*result = tre_ast_new_union(mem, uni->left, uni->right);
+		if (*result == NULL)
+		  {
+		    status = REG_ESPACE;
+		    break;
+		  }
+		tmp = (*result)->obj;
+		result = &tmp->left;
+		STACK_PUSHX(stack, voidptr, uni->right);
+		STACK_PUSHX(stack, int, COPY_RECURSE);
+		STACK_PUSHX(stack, voidptr, &tmp->right);
+		STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);
+		STACK_PUSHX(stack, voidptr, uni->left);
+		STACK_PUSHX(stack, int, COPY_RECURSE);
+		break;
+	      }
+	    case CATENATION:
+	      {
+		tre_catenation_t *cat = node->obj;
+		tre_catenation_t *tmp;
+		*result = tre_ast_new_catenation(mem, cat->left, cat->right);
+		if (*result == NULL)
+		  {
+		    status = REG_ESPACE;
+		    break;
+		  }
+		tmp = (*result)->obj;
+		tmp->left = NULL;
+		tmp->right = NULL;
+		result = &tmp->left;
+
+		STACK_PUSHX(stack, voidptr, cat->right);
+		STACK_PUSHX(stack, int, COPY_RECURSE);
+		STACK_PUSHX(stack, voidptr, &tmp->right);
+		STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);
+		STACK_PUSHX(stack, voidptr, cat->left);
+		STACK_PUSHX(stack, int, COPY_RECURSE);
+		break;
+	      }
+	    case ITERATION:
+	      {
+		tre_iteration_t *iter = node->obj;
+		STACK_PUSHX(stack, voidptr, iter->arg);
+		STACK_PUSHX(stack, int, COPY_RECURSE);
+		*result = tre_ast_new_iter(mem, iter->arg, iter->min,
+					   iter->max, iter->minimal);
+		if (*result == NULL)
+		  {
+		    status = REG_ESPACE;
+		    break;
+		  }
+		iter = (*result)->obj;
+		result = &iter->arg;
+		break;
+	      }
+	    default:
+	      assert(0);
+	      break;
+	    }
+	  break;
+	}
+    }
+  *pos_add += num_copied;
+  return status;
+}
+
+typedef enum {
+  EXPAND_RECURSE,
+  EXPAND_AFTER_ITER
+} tre_expand_ast_symbol_t;
+
+/* Expands each iteration node that has a finite nonzero minimum or maximum
+   iteration count to a catenated sequence of copies of the node. */
+static reg_errcode_t
+tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
+	       int *position, tre_tag_direction_t *tag_directions)
+{
+  reg_errcode_t status = REG_OK;
+  int bottom = tre_stack_num_objects(stack);
+  int pos_add = 0;
+  int pos_add_total = 0;
+  int max_pos = 0;
+  int iter_depth = 0;
+
+  STACK_PUSHR(stack, voidptr, ast);
+  STACK_PUSHR(stack, int, EXPAND_RECURSE);
+  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
+    {
+      tre_ast_node_t *node;
+      tre_expand_ast_symbol_t symbol;
+
+      if (status != REG_OK)
+	break;
+
+      symbol = (tre_expand_ast_symbol_t)tre_stack_pop_int(stack);
+      node = tre_stack_pop_voidptr(stack);
+      switch (symbol)
+	{
+	case EXPAND_RECURSE:
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit= node->obj;
+		if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
+		  {
+		    lit->position += pos_add;
+		    if (lit->position > max_pos)
+		      max_pos = lit->position;
+		  }
+		break;
+	      }
+	    case UNION:
+	      {
+		tre_union_t *uni = node->obj;
+		STACK_PUSHX(stack, voidptr, uni->right);
+		STACK_PUSHX(stack, int, EXPAND_RECURSE);
+		STACK_PUSHX(stack, voidptr, uni->left);
+		STACK_PUSHX(stack, int, EXPAND_RECURSE);
+		break;
+	      }
+	    case CATENATION:
+	      {
+		tre_catenation_t *cat = node->obj;
+		STACK_PUSHX(stack, voidptr, cat->right);
+		STACK_PUSHX(stack, int, EXPAND_RECURSE);
+		STACK_PUSHX(stack, voidptr, cat->left);
+		STACK_PUSHX(stack, int, EXPAND_RECURSE);
+		break;
+	      }
+	    case ITERATION:
+	      {
+		tre_iteration_t *iter = node->obj;
+		STACK_PUSHX(stack, int, pos_add);
+		STACK_PUSHX(stack, voidptr, node);
+		STACK_PUSHX(stack, int, EXPAND_AFTER_ITER);
+		STACK_PUSHX(stack, voidptr, iter->arg);
+		STACK_PUSHX(stack, int, EXPAND_RECURSE);
+		/* If we are going to expand this node at EXPAND_AFTER_ITER
+		   then don't increase the `pos' fields of the nodes now, it
+		   will get done when expanding. */
+		if (iter->min > 1 || iter->max > 1)
+		  pos_add = 0;
+		iter_depth++;
+		break;
+	      }
+	    default:
+	      assert(0);
+	      break;
+	    }
+	  break;
+	case EXPAND_AFTER_ITER:
+	  {
+	    tre_iteration_t *iter = node->obj;
+	    int pos_add_last;
+	    pos_add = tre_stack_pop_int(stack);
+	    pos_add_last = pos_add;
+	    if (iter->min > 1 || iter->max > 1)
+	      {
+		tre_ast_node_t *seq1 = NULL, *seq2 = NULL;
+		int j;
+		int pos_add_save = pos_add;
+
+		/* Create a catenated sequence of copies of the node. */
+		for (j = 0; j < iter->min; j++)
+		  {
+		    tre_ast_node_t *copy;
+		    /* Remove tags from all but the last copy. */
+		    int flags = ((j + 1 < iter->min)
+				 ? COPY_REMOVE_TAGS
+				 : COPY_MAXIMIZE_FIRST_TAG);
+		    pos_add_save = pos_add;
+		    status = tre_copy_ast(mem, stack, iter->arg, flags,
+					  &pos_add, tag_directions, &copy,
+					  &max_pos);
+		    if (status != REG_OK)
+		      return status;
+		    if (seq1 != NULL)
+		      seq1 = tre_ast_new_catenation(mem, seq1, copy);
+		    else
+		      seq1 = copy;
+		    if (seq1 == NULL)
+		      return REG_ESPACE;
+		  }
+
+		if (iter->max == -1)
+		  {
+		    /* No upper limit. */
+		    pos_add_save = pos_add;
+		    status = tre_copy_ast(mem, stack, iter->arg, 0,
+					  &pos_add, NULL, &seq2, &max_pos);
+		    if (status != REG_OK)
+		      return status;
+		    seq2 = tre_ast_new_iter(mem, seq2, 0, -1, 0);
+		    if (seq2 == NULL)
+		      return REG_ESPACE;
+		  }
+		else
+		  {
+		    for (j = iter->min; j < iter->max; j++)
+		      {
+			tre_ast_node_t *tmp, *copy;
+			pos_add_save = pos_add;
+			status = tre_copy_ast(mem, stack, iter->arg, 0,
+					      &pos_add, NULL, &copy, &max_pos);
+			if (status != REG_OK)
+			  return status;
+			if (seq2 != NULL)
+			  seq2 = tre_ast_new_catenation(mem, copy, seq2);
+			else
+			  seq2 = copy;
+			if (seq2 == NULL)
+			  return REG_ESPACE;
+			tmp = tre_ast_new_literal(mem, EMPTY, -1, -1);
+			if (tmp == NULL)
+			  return REG_ESPACE;
+			seq2 = tre_ast_new_union(mem, tmp, seq2);
+			if (seq2 == NULL)
+			  return REG_ESPACE;
+		      }
+		  }
+
+		pos_add = pos_add_save;
+		if (seq1 == NULL)
+		  seq1 = seq2;
+		else if (seq2 != NULL)
+		  seq1 = tre_ast_new_catenation(mem, seq1, seq2);
+		if (seq1 == NULL)
+		  return REG_ESPACE;
+		node->obj = seq1->obj;
+		node->type = seq1->type;
+	      }
+
+	    iter_depth--;
+	    pos_add_total += pos_add - pos_add_last;
+	    if (iter_depth == 0)
+	      pos_add = pos_add_total;
+
+	    break;
+	  }
+	default:
+	  assert(0);
+	  break;
+	}
+    }
+
+  *position += pos_add_total;
+
+  /* `max_pos' should never be larger than `*position' if the above
+     code works, but just an extra safeguard let's make sure
+     `*position' is set large enough so enough memory will be
+     allocated for the transition table. */
+  if (max_pos > *position)
+    *position = max_pos;
+
+  return status;
+}
+
+static tre_pos_and_tags_t *
+tre_set_empty(tre_mem_t mem)
+{
+  tre_pos_and_tags_t *new_set;
+
+  new_set = tre_mem_calloc(mem, sizeof(*new_set));
+  if (new_set == NULL)
+    return NULL;
+
+  new_set[0].position = -1;
+  new_set[0].code_min = -1;
+  new_set[0].code_max = -1;
+
+  return new_set;
+}
+
+static tre_pos_and_tags_t *
+tre_set_one(tre_mem_t mem, int position, int code_min, int code_max,
+	    tre_ctype_t class, tre_ctype_t *neg_classes, int backref)
+{
+  tre_pos_and_tags_t *new_set;
+
+  new_set = tre_mem_calloc(mem, sizeof(*new_set) * 2);
+  if (new_set == NULL)
+    return NULL;
+
+  new_set[0].position = position;
+  new_set[0].code_min = code_min;
+  new_set[0].code_max = code_max;
+  new_set[0].class = class;
+  new_set[0].neg_classes = neg_classes;
+  new_set[0].backref = backref;
+  new_set[1].position = -1;
+  new_set[1].code_min = -1;
+  new_set[1].code_max = -1;
+
+  return new_set;
+}
+
+static tre_pos_and_tags_t *
+tre_set_union(tre_mem_t mem, tre_pos_and_tags_t *set1, tre_pos_and_tags_t *set2,
+	      int *tags, int assertions)
+{
+  int s1, s2, i, j;
+  tre_pos_and_tags_t *new_set;
+  int *new_tags;
+  int num_tags;
+
+  for (num_tags = 0; tags != NULL && tags[num_tags] >= 0; num_tags++);
+  for (s1 = 0; set1[s1].position >= 0; s1++);
+  for (s2 = 0; set2[s2].position >= 0; s2++);
+  new_set = tre_mem_calloc(mem, sizeof(*new_set) * (s1 + s2 + 1));
+  if (!new_set )
+    return NULL;
+
+  for (s1 = 0; set1[s1].position >= 0; s1++)
+    {
+      new_set[s1].position = set1[s1].position;
+      new_set[s1].code_min = set1[s1].code_min;
+      new_set[s1].code_max = set1[s1].code_max;
+      new_set[s1].assertions = set1[s1].assertions | assertions;
+      new_set[s1].class = set1[s1].class;
+      new_set[s1].neg_classes = set1[s1].neg_classes;
+      new_set[s1].backref = set1[s1].backref;
+      if (set1[s1].tags == NULL && tags == NULL)
+	new_set[s1].tags = NULL;
+      else
+	{
+	  for (i = 0; set1[s1].tags != NULL && set1[s1].tags[i] >= 0; i++);
+	  new_tags = tre_mem_alloc(mem, (sizeof(*new_tags)
+					 * (i + num_tags + 1)));
+	  if (new_tags == NULL)
+	    return NULL;
+	  for (j = 0; j < i; j++)
+	    new_tags[j] = set1[s1].tags[j];
+	  for (i = 0; i < num_tags; i++)
+	    new_tags[j + i] = tags[i];
+	  new_tags[j + i] = -1;
+	  new_set[s1].tags = new_tags;
+	}
+    }
+
+  for (s2 = 0; set2[s2].position >= 0; s2++)
+    {
+      new_set[s1 + s2].position = set2[s2].position;
+      new_set[s1 + s2].code_min = set2[s2].code_min;
+      new_set[s1 + s2].code_max = set2[s2].code_max;
+      /* XXX - why not | assertions here as well? */
+      new_set[s1 + s2].assertions = set2[s2].assertions;
+      new_set[s1 + s2].class = set2[s2].class;
+      new_set[s1 + s2].neg_classes = set2[s2].neg_classes;
+      new_set[s1 + s2].backref = set2[s2].backref;
+      if (set2[s2].tags == NULL)
+	new_set[s1 + s2].tags = NULL;
+      else
+	{
+	  for (i = 0; set2[s2].tags[i] >= 0; i++);
+	  new_tags = tre_mem_alloc(mem, sizeof(*new_tags) * (i + 1));
+	  if (new_tags == NULL)
+	    return NULL;
+	  for (j = 0; j < i; j++)
+	    new_tags[j] = set2[s2].tags[j];
+	  new_tags[j] = -1;
+	  new_set[s1 + s2].tags = new_tags;
+	}
+    }
+  new_set[s1 + s2].position = -1;
+  return new_set;
+}
+
+/* Finds the empty path through `node' which is the one that should be
+   taken according to POSIX.2 rules, and adds the tags on that path to
+   `tags'.   `tags' may be NULL.  If `num_tags_seen' is not NULL, it is
+   set to the number of tags seen on the path. */
+static reg_errcode_t
+tre_match_empty(tre_stack_t *stack, tre_ast_node_t *node, int *tags,
+		int *assertions, int *num_tags_seen)
+{
+  tre_literal_t *lit;
+  tre_union_t *uni;
+  tre_catenation_t *cat;
+  tre_iteration_t *iter;
+  int i;
+  int bottom = tre_stack_num_objects(stack);
+  reg_errcode_t status = REG_OK;
+  if (num_tags_seen)
+    *num_tags_seen = 0;
+
+  status = tre_stack_push_voidptr(stack, node);
+
+  /* Walk through the tree recursively. */
+  while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
+    {
+      node = tre_stack_pop_voidptr(stack);
+
+      switch (node->type)
+	{
+	case LITERAL:
+	  lit = (tre_literal_t *)node->obj;
+	  switch (lit->code_min)
+	    {
+	    case TAG:
+	      if (lit->code_max >= 0)
+		{
+		  if (tags != NULL)
+		    {
+		      /* Add the tag to `tags'. */
+		      for (i = 0; tags[i] >= 0; i++)
+			if (tags[i] == lit->code_max)
+			  break;
+		      if (tags[i] < 0)
+			{
+			  tags[i] = lit->code_max;
+			  tags[i + 1] = -1;
+			}
+		    }
+		  if (num_tags_seen)
+		    (*num_tags_seen)++;
+		}
+	      break;
+	    case ASSERTION:
+	      assert(lit->code_max >= 1
+		     || lit->code_max <= ASSERT_LAST);
+	      if (assertions != NULL)
+		*assertions |= lit->code_max;
+	      break;
+	    case EMPTY:
+	      break;
+	    default:
+	      assert(0);
+	      break;
+	    }
+	  break;
+
+	case UNION:
+	  /* Subexpressions starting earlier take priority over ones
+	     starting later, so we prefer the left subexpression over the
+	     right subexpression. */
+	  uni = (tre_union_t *)node->obj;
+	  if (uni->left->nullable)
+	    STACK_PUSHX(stack, voidptr, uni->left)
+	  else if (uni->right->nullable)
+	    STACK_PUSHX(stack, voidptr, uni->right)
+	  else
+	    assert(0);
+	  break;
+
+	case CATENATION:
+	  /* The path must go through both children. */
+	  cat = (tre_catenation_t *)node->obj;
+	  assert(cat->left->nullable);
+	  assert(cat->right->nullable);
+	  STACK_PUSHX(stack, voidptr, cat->left);
+	  STACK_PUSHX(stack, voidptr, cat->right);
+	  break;
+
+	case ITERATION:
+	  /* A match with an empty string is preferred over no match at
+	     all, so we go through the argument if possible. */
+	  iter = (tre_iteration_t *)node->obj;
+	  if (iter->arg->nullable)
+	    STACK_PUSHX(stack, voidptr, iter->arg);
+	  break;
+
+	default:
+	  assert(0);
+	  break;
+	}
+    }
+
+  return status;
+}
+
+
+typedef enum {
+  NFL_RECURSE,
+  NFL_POST_UNION,
+  NFL_POST_CATENATION,
+  NFL_POST_ITERATION
+} tre_nfl_stack_symbol_t;
+
+
+/* Computes and fills in the fields `nullable', `firstpos', and `lastpos' for
+   the nodes of the AST `tree'. */
+static reg_errcode_t
+tre_compute_nfl(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree)
+{
+  int bottom = tre_stack_num_objects(stack);
+
+  STACK_PUSHR(stack, voidptr, tree);
+  STACK_PUSHR(stack, int, NFL_RECURSE);
+
+  while (tre_stack_num_objects(stack) > bottom)
+    {
+      tre_nfl_stack_symbol_t symbol;
+      tre_ast_node_t *node;
+
+      symbol = (tre_nfl_stack_symbol_t)tre_stack_pop_int(stack);
+      node = tre_stack_pop_voidptr(stack);
+      switch (symbol)
+	{
+	case NFL_RECURSE:
+	  switch (node->type)
+	    {
+	    case LITERAL:
+	      {
+		tre_literal_t *lit = (tre_literal_t *)node->obj;
+		if (IS_BACKREF(lit))
+		  {
+		    /* Back references: nullable = false, firstpos = {i},
+		       lastpos = {i}. */
+		    node->nullable = 0;
+		    node->firstpos = tre_set_one(mem, lit->position, 0,
+					     TRE_CHAR_MAX, 0, NULL, -1);
+		    if (!node->firstpos)
+		      return REG_ESPACE;
+		    node->lastpos = tre_set_one(mem, lit->position, 0,
+						TRE_CHAR_MAX, 0, NULL,
+						(int)lit->code_max);
+		    if (!node->lastpos)
+		      return REG_ESPACE;
+		  }
+		else if (lit->code_min < 0)
+		  {
+		    /* Tags, empty strings, params, and zero width assertions:
+		       nullable = true, firstpos = {}, and lastpos = {}. */
+		    node->nullable = 1;
+		    node->firstpos = tre_set_empty(mem);
+		    if (!node->firstpos)
+		      return REG_ESPACE;
+		    node->lastpos = tre_set_empty(mem);
+		    if (!node->lastpos)
+		      return REG_ESPACE;
+		  }
+		else
+		  {
+		    /* Literal at position i: nullable = false, firstpos = {i},
+		       lastpos = {i}. */
+		    node->nullable = 0;
+		    node->firstpos =
+		      tre_set_one(mem, lit->position, (int)lit->code_min,
+				  (int)lit->code_max, 0, NULL, -1);
+		    if (!node->firstpos)
+		      return REG_ESPACE;
+		    node->lastpos = tre_set_one(mem, lit->position,
+						(int)lit->code_min,
+						(int)lit->code_max,
+						lit->class, lit->neg_classes,
+						-1);
+		    if (!node->lastpos)
+		      return REG_ESPACE;
+		  }
+		break;
+	      }
+
+	    case UNION:
+	      /* Compute the attributes for the two subtrees, and after that
+		 for this node. */
+	      STACK_PUSHR(stack, voidptr, node);
+	      STACK_PUSHR(stack, int, NFL_POST_UNION);
+	      STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->right);
+	      STACK_PUSHR(stack, int, NFL_RECURSE);
+	      STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->left);
+	      STACK_PUSHR(stack, int, NFL_RECURSE);
+	      break;
+
+	    case CATENATION:
+	      /* Compute the attributes for the two subtrees, and after that
+		 for this node. */
+	      STACK_PUSHR(stack, voidptr, node);
+	      STACK_PUSHR(stack, int, NFL_POST_CATENATION);
+	      STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->right);
+	      STACK_PUSHR(stack, int, NFL_RECURSE);
+	      STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->left);
+	      STACK_PUSHR(stack, int, NFL_RECURSE);
+	      break;
+
+	    case ITERATION:
+	      /* Compute the attributes for the subtree, and after that for
+		 this node. */
+	      STACK_PUSHR(stack, voidptr, node);
+	      STACK_PUSHR(stack, int, NFL_POST_ITERATION);
+	      STACK_PUSHR(stack, voidptr, ((tre_iteration_t *)node->obj)->arg);
+	      STACK_PUSHR(stack, int, NFL_RECURSE);
+	      break;
+	    }
+	  break; /* end case: NFL_RECURSE */
+
+	case NFL_POST_UNION:
+	  {
+	    tre_union_t *uni = (tre_union_t *)node->obj;
+	    node->nullable = uni->left->nullable || uni->right->nullable;
+	    node->firstpos = tre_set_union(mem, uni->left->firstpos,
+					   uni->right->firstpos, NULL, 0);
+	    if (!node->firstpos)
+	      return REG_ESPACE;
+	    node->lastpos = tre_set_union(mem, uni->left->lastpos,
+					  uni->right->lastpos, NULL, 0);
+	    if (!node->lastpos)
+	      return REG_ESPACE;
+	    break;
+	  }
+
+	case NFL_POST_ITERATION:
+	  {
+	    tre_iteration_t *iter = (tre_iteration_t *)node->obj;
+
+	    if (iter->min == 0 || iter->arg->nullable)
+	      node->nullable = 1;
+	    else
+	      node->nullable = 0;
+	    node->firstpos = iter->arg->firstpos;
+	    node->lastpos = iter->arg->lastpos;
+	    break;
+	  }
+
+	case NFL_POST_CATENATION:
+	  {
+	    int num_tags, *tags, assertions;
+	    reg_errcode_t status;
+	    tre_catenation_t *cat = node->obj;
+	    node->nullable = cat->left->nullable && cat->right->nullable;
+
+	    /* Compute firstpos. */
+	    if (cat->left->nullable)
+	      {
+		/* The left side matches the empty string.  Make a first pass
+		   with tre_match_empty() to get the number of tags and
+		   parameters. */
+		status = tre_match_empty(stack, cat->left,
+					 NULL, NULL, &num_tags);
+		if (status != REG_OK)
+		  return status;
+		/* Allocate arrays for the tags and parameters. */
+		tags = xmalloc(sizeof(*tags) * (num_tags + 1));
+		if (!tags)
+		  return REG_ESPACE;
+		tags[0] = -1;
+		assertions = 0;
+		/* Second pass with tre_mach_empty() to get the list of
+		   tags and parameters. */
+		status = tre_match_empty(stack, cat->left, tags,
+					 &assertions, NULL);
+		if (status != REG_OK)
+		  {
+		    xfree(tags);
+		    return status;
+		  }
+		node->firstpos =
+		  tre_set_union(mem, cat->right->firstpos, cat->left->firstpos,
+				tags, assertions);
+		xfree(tags);
+		if (!node->firstpos)
+		  return REG_ESPACE;
+	      }
+	    else
+	      {
+		node->firstpos = cat->left->firstpos;
+	      }
+
+	    /* Compute lastpos. */
+	    if (cat->right->nullable)
+	      {
+		/* The right side matches the empty string.  Make a first pass
+		   with tre_match_empty() to get the number of tags and
+		   parameters. */
+		status = tre_match_empty(stack, cat->right,
+					 NULL, NULL, &num_tags);
+		if (status != REG_OK)
+		  return status;
+		/* Allocate arrays for the tags and parameters. */
+		tags = xmalloc(sizeof(int) * (num_tags + 1));
+		if (!tags)
+		  return REG_ESPACE;
+		tags[0] = -1;
+		assertions = 0;
+		/* Second pass with tre_mach_empty() to get the list of
+		   tags and parameters. */
+		status = tre_match_empty(stack, cat->right, tags,
+					 &assertions, NULL);
+		if (status != REG_OK)
+		  {
+		    xfree(tags);
+		    return status;
+		  }
+		node->lastpos =
+		  tre_set_union(mem, cat->left->lastpos, cat->right->lastpos,
+				tags, assertions);
+		xfree(tags);
+		if (!node->lastpos)
+		  return REG_ESPACE;
+	      }
+	    else
+	      {
+		node->lastpos = cat->right->lastpos;
+	      }
+	    break;
+	  }
+
+	default:
+	  assert(0);
+	  break;
+	}
+    }
+
+  return REG_OK;
+}
+
+
+/* Adds a transition from each position in `p1' to each position in `p2'. */
+static reg_errcode_t
+tre_make_trans(tre_pos_and_tags_t *p1, tre_pos_and_tags_t *p2,
+	       tre_tnfa_transition_t *transitions,
+	       int *counts, int *offs)
+{
+  tre_pos_and_tags_t *orig_p2 = p2;
+  tre_tnfa_transition_t *trans;
+  int i, j, k, l, dup, prev_p2_pos;
+
+  if (transitions != NULL)
+    while (p1->position >= 0)
+      {
+	p2 = orig_p2;
+	prev_p2_pos = -1;
+	while (p2->position >= 0)
+	  {
+	    /* Optimization: if this position was already handled, skip it. */
+	    if (p2->position == prev_p2_pos)
+	      {
+		p2++;
+		continue;
+	      }
+	    prev_p2_pos = p2->position;
+	    /* Set `trans' to point to the next unused transition from
+	       position `p1->position'. */
+	    trans = transitions + offs[p1->position];
+	    while (trans->state != NULL)
+	      {
+#if 0
+		/* If we find a previous transition from `p1->position' to
+		   `p2->position', it is overwritten.  This can happen only
+		   if there are nested loops in the regexp, like in "((a)*)*".
+		   In POSIX.2 repetition using the outer loop is always
+		   preferred over using the inner loop.	 Therefore the
+		   transition for the inner loop is useless and can be thrown
+		   away. */
+		/* XXX - The same position is used for all nodes in a bracket
+		   expression, so this optimization cannot be used (it will
+		   break bracket expressions) unless I figure out a way to
+		   detect it here. */
+		if (trans->state_id == p2->position)
+		  {
+		    break;
+		  }
+#endif
+		trans++;
+	      }
+
+	    if (trans->state == NULL)
+	      (trans + 1)->state = NULL;
+	    /* Use the character ranges, assertions, etc. from `p1' for
+	       the transition from `p1' to `p2'. */
+	    trans->code_min = p1->code_min;
+	    trans->code_max = p1->code_max;
+	    trans->state = transitions + offs[p2->position];
+	    trans->state_id = p2->position;
+	    trans->assertions = p1->assertions | p2->assertions
+	      | (p1->class ? ASSERT_CHAR_CLASS : 0)
+	      | (p1->neg_classes != NULL ? ASSERT_CHAR_CLASS_NEG : 0);
+	    if (p1->backref >= 0)
+	      {
+		assert((trans->assertions & ASSERT_CHAR_CLASS) == 0);
+		assert(p2->backref < 0);
+		trans->u.backref = p1->backref;
+		trans->assertions |= ASSERT_BACKREF;
+	      }
+	    else
+	      trans->u.class = p1->class;
+	    if (p1->neg_classes != NULL)
+	      {
+		for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++);
+		trans->neg_classes =
+		  xmalloc(sizeof(*trans->neg_classes) * (i + 1));
+		if (trans->neg_classes == NULL)
+		  return REG_ESPACE;
+		for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++)
+		  trans->neg_classes[i] = p1->neg_classes[i];
+		trans->neg_classes[i] = (tre_ctype_t)0;
+	      }
+	    else
+	      trans->neg_classes = NULL;
+
+	    /* Find out how many tags this transition has. */
+	    i = 0;
+	    if (p1->tags != NULL)
+	      while(p1->tags[i] >= 0)
+		i++;
+	    j = 0;
+	    if (p2->tags != NULL)
+	      while(p2->tags[j] >= 0)
+		j++;
+
+	    /* If we are overwriting a transition, free the old tag array. */
+	    if (trans->tags != NULL)
+	      xfree(trans->tags);
+	    trans->tags = NULL;
+
+	    /* If there were any tags, allocate an array and fill it. */
+	    if (i + j > 0)
+	      {
+		trans->tags = xmalloc(sizeof(*trans->tags) * (i + j + 1));
+		if (!trans->tags)
+		  return REG_ESPACE;
+		i = 0;
+		if (p1->tags != NULL)
+		  while(p1->tags[i] >= 0)
+		    {
+		      trans->tags[i] = p1->tags[i];
+		      i++;
+		    }
+		l = i;
+		j = 0;
+		if (p2->tags != NULL)
+		  while (p2->tags[j] >= 0)
+		    {
+		      /* Don't add duplicates. */
+		      dup = 0;
+		      for (k = 0; k < i; k++)
+			if (trans->tags[k] == p2->tags[j])
+			  {
+			    dup = 1;
+			    break;
+			  }
+		      if (!dup)
+			trans->tags[l++] = p2->tags[j];
+		      j++;
+		    }
+		trans->tags[l] = -1;
+	      }
+
+	    p2++;
+	  }
+	p1++;
+      }
+  else
+    /* Compute a maximum limit for the number of transitions leaving
+       from each state. */
+    while (p1->position >= 0)
+      {
+	p2 = orig_p2;
+	while (p2->position >= 0)
+	  {
+	    counts[p1->position]++;
+	    p2++;
+	  }
+	p1++;
+      }
+  return REG_OK;
+}
+
+/* Converts the syntax tree to a TNFA.	All the transitions in the TNFA are
+   labelled with one character range (there are no transitions on empty
+   strings).  The TNFA takes O(n^2) space in the worst case, `n' is size of
+   the regexp. */
+static reg_errcode_t
+tre_ast_to_tnfa(tre_ast_node_t *node, tre_tnfa_transition_t *transitions,
+		int *counts, int *offs)
+{
+  tre_union_t *uni;
+  tre_catenation_t *cat;
+  tre_iteration_t *iter;
+  reg_errcode_t errcode = REG_OK;
+
+  /* XXX - recurse using a stack!. */
+  switch (node->type)
+    {
+    case LITERAL:
+      break;
+    case UNION:
+      uni = (tre_union_t *)node->obj;
+      errcode = tre_ast_to_tnfa(uni->left, transitions, counts, offs);
+      if (errcode != REG_OK)
+	return errcode;
+      errcode = tre_ast_to_tnfa(uni->right, transitions, counts, offs);
+      break;
+
+    case CATENATION:
+      cat = (tre_catenation_t *)node->obj;
+      /* Add a transition from each position in cat->left->lastpos
+	 to each position in cat->right->firstpos. */
+      errcode = tre_make_trans(cat->left->lastpos, cat->right->firstpos,
+			       transitions, counts, offs);
+      if (errcode != REG_OK)
+	return errcode;
+      errcode = tre_ast_to_tnfa(cat->left, transitions, counts, offs);
+      if (errcode != REG_OK)
+	return errcode;
+      errcode = tre_ast_to_tnfa(cat->right, transitions, counts, offs);
+      break;
+
+    case ITERATION:
+      iter = (tre_iteration_t *)node->obj;
+      assert(iter->max == -1 || iter->max == 1);
+
+      if (iter->max == -1)
+	{
+	  assert(iter->min == 0 || iter->min == 1);
+	  /* Add a transition from each last position in the iterated
+	     expression to each first position. */
+	  errcode = tre_make_trans(iter->arg->lastpos, iter->arg->firstpos,
+				   transitions, counts, offs);
+	  if (errcode != REG_OK)
+	    return errcode;
+	}
+      errcode = tre_ast_to_tnfa(iter->arg, transitions, counts, offs);
+      break;
+    }
+  return errcode;
+}
+
+
+#define ERROR_EXIT(err)		  \
+  do				  \
+    {				  \
+      errcode = err;		  \
+      if (/*CONSTCOND*/1)	  \
+      	goto error_exit;	  \
+    }				  \
+ while (/*CONSTCOND*/0)
+
+
+int
+regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
+{
+  tre_stack_t *stack;
+  tre_ast_node_t *tree, *tmp_ast_l, *tmp_ast_r;
+  tre_pos_and_tags_t *p;
+  int *counts = NULL, *offs = NULL;
+  int i, add = 0;
+  tre_tnfa_transition_t *transitions, *initial;
+  tre_tnfa_t *tnfa = NULL;
+  tre_submatch_data_t *submatch_data;
+  tre_tag_direction_t *tag_directions = NULL;
+  reg_errcode_t errcode;
+  tre_mem_t mem;
+
+  /* Parse context. */
+  tre_parse_ctx_t parse_ctx;
+
+  /* Allocate a stack used throughout the compilation process for various
+     purposes. */
+  stack = tre_stack_new(512, 1024000, 128);
+  if (!stack)
+    return REG_ESPACE;
+  /* Allocate a fast memory allocator. */
+  mem = tre_mem_new();
+  if (!mem)
+    {
+      tre_stack_destroy(stack);
+      return REG_ESPACE;
+    }
+
+  /* Parse the regexp. */
+  memset(&parse_ctx, 0, sizeof(parse_ctx));
+  parse_ctx.mem = mem;
+  parse_ctx.stack = stack;
+  parse_ctx.start = regex;
+  parse_ctx.cflags = cflags;
+  parse_ctx.max_backref = -1;
+  errcode = tre_parse(&parse_ctx);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+  preg->re_nsub = parse_ctx.submatch_id - 1;
+  tree = parse_ctx.n;
+
+#ifdef TRE_DEBUG
+  tre_ast_print(tree);
+#endif /* TRE_DEBUG */
+
+  /* Referring to nonexistent subexpressions is illegal. */
+  if (parse_ctx.max_backref > (int)preg->re_nsub)
+    ERROR_EXIT(REG_ESUBREG);
+
+  /* Allocate the TNFA struct. */
+  tnfa = xcalloc(1, sizeof(tre_tnfa_t));
+  if (tnfa == NULL)
+    ERROR_EXIT(REG_ESPACE);
+  tnfa->have_backrefs = parse_ctx.max_backref >= 0;
+  tnfa->have_approx = 0;
+  tnfa->num_submatches = parse_ctx.submatch_id;
+
+  /* Set up tags for submatch addressing.  If REG_NOSUB is set and the
+     regexp does not have back references, this can be skipped. */
+  if (tnfa->have_backrefs || !(cflags & REG_NOSUB))
+    {
+
+      /* Figure out how many tags we will need. */
+      errcode = tre_add_tags(NULL, stack, tree, tnfa);
+      if (errcode != REG_OK)
+	ERROR_EXIT(errcode);
+
+      if (tnfa->num_tags > 0)
+	{
+	  tag_directions = xmalloc(sizeof(*tag_directions)
+				   * (tnfa->num_tags + 1));
+	  if (tag_directions == NULL)
+	    ERROR_EXIT(REG_ESPACE);
+	  tnfa->tag_directions = tag_directions;
+	  memset(tag_directions, -1,
+		 sizeof(*tag_directions) * (tnfa->num_tags + 1));
+	}
+      tnfa->minimal_tags = xcalloc((unsigned)tnfa->num_tags * 2 + 1,
+				   sizeof(*tnfa->minimal_tags));
+      if (tnfa->minimal_tags == NULL)
+	ERROR_EXIT(REG_ESPACE);
+
+      submatch_data = xcalloc((unsigned)parse_ctx.submatch_id,
+			      sizeof(*submatch_data));
+      if (submatch_data == NULL)
+	ERROR_EXIT(REG_ESPACE);
+      tnfa->submatch_data = submatch_data;
+
+      errcode = tre_add_tags(mem, stack, tree, tnfa);
+      if (errcode != REG_OK)
+	ERROR_EXIT(errcode);
+
+    }
+
+  /* Expand iteration nodes. */
+  errcode = tre_expand_ast(mem, stack, tree, &parse_ctx.position,
+			   tag_directions);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+
+  /* Add a dummy node for the final state.
+     XXX - For certain patterns this dummy node can be optimized away,
+	   for example "a*" or "ab*".	Figure out a simple way to detect
+	   this possibility. */
+  tmp_ast_l = tree;
+  tmp_ast_r = tre_ast_new_literal(mem, 0, 0, parse_ctx.position++);
+  if (tmp_ast_r == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  tree = tre_ast_new_catenation(mem, tmp_ast_l, tmp_ast_r);
+  if (tree == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  errcode = tre_compute_nfl(mem, stack, tree);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+
+  counts = xmalloc(sizeof(int) * parse_ctx.position);
+  if (counts == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  offs = xmalloc(sizeof(int) * parse_ctx.position);
+  if (offs == NULL)
+    ERROR_EXIT(REG_ESPACE);
+
+  for (i = 0; i < parse_ctx.position; i++)
+    counts[i] = 0;
+  tre_ast_to_tnfa(tree, NULL, counts, NULL);
+
+  add = 0;
+  for (i = 0; i < parse_ctx.position; i++)
+    {
+      offs[i] = add;
+      add += counts[i] + 1;
+      counts[i] = 0;
+    }
+  transitions = xcalloc((unsigned)add + 1, sizeof(*transitions));
+  if (transitions == NULL)
+    ERROR_EXIT(REG_ESPACE);
+  tnfa->transitions = transitions;
+  tnfa->num_transitions = add;
+
+  errcode = tre_ast_to_tnfa(tree, transitions, counts, offs);
+  if (errcode != REG_OK)
+    ERROR_EXIT(errcode);
+
+  tnfa->firstpos_chars = NULL;
+
+  p = tree->firstpos;
+  i = 0;
+  while (p->position >= 0)
+    {
+      i++;
+      p++;
+    }
+
+  initial = xcalloc((unsigned)i + 1, sizeof(tre_tnfa_transition_t));
+  if (initial == NULL)
+    ERROR_EXIT(REG_ESPACE);
+  tnfa->initial = initial;
+
+  i = 0;
+  for (p = tree->firstpos; p->position >= 0; p++)
+    {
+      initial[i].state = transitions + offs[p->position];
+      initial[i].state_id = p->position;
+      initial[i].tags = NULL;
+      /* Copy the arrays p->tags, and p->params, they are allocated
+	 from a tre_mem object. */
+      if (p->tags)
+	{
+	  int j;
+	  for (j = 0; p->tags[j] >= 0; j++);
+	  initial[i].tags = xmalloc(sizeof(*p->tags) * (j + 1));
+	  if (!initial[i].tags)
+	    ERROR_EXIT(REG_ESPACE);
+	  memcpy(initial[i].tags, p->tags, sizeof(*p->tags) * (j + 1));
+	}
+      initial[i].assertions = p->assertions;
+      i++;
+    }
+  initial[i].state = NULL;
+
+  tnfa->num_transitions = add;
+  tnfa->final = transitions + offs[tree->lastpos[0].position];
+  tnfa->num_states = parse_ctx.position;
+  tnfa->cflags = cflags;
+
+  tre_mem_destroy(mem);
+  tre_stack_destroy(stack);
+  xfree(counts);
+  xfree(offs);
+
+  preg->TRE_REGEX_T_FIELD = (void *)tnfa;
+  return REG_OK;
+
+ error_exit:
+  /* Free everything that was allocated and return the error code. */
+  tre_mem_destroy(mem);
+  if (stack != NULL)
+    tre_stack_destroy(stack);
+  if (counts != NULL)
+    xfree(counts);
+  if (offs != NULL)
+    xfree(offs);
+  preg->TRE_REGEX_T_FIELD = (void *)tnfa;
+  regfree(preg);
+  return errcode;
+}
+
+
+
+
+void
+regfree(regex_t *preg)
+{
+  tre_tnfa_t *tnfa;
+  unsigned int i;
+  tre_tnfa_transition_t *trans;
+
+  tnfa = (void *)preg->TRE_REGEX_T_FIELD;
+  if (!tnfa)
+    return;
+
+  for (i = 0; i < tnfa->num_transitions; i++)
+    if (tnfa->transitions[i].state)
+      {
+	if (tnfa->transitions[i].tags)
+	  xfree(tnfa->transitions[i].tags);
+	if (tnfa->transitions[i].neg_classes)
+	  xfree(tnfa->transitions[i].neg_classes);
+      }
+  if (tnfa->transitions)
+    xfree(tnfa->transitions);
+
+  if (tnfa->initial)
+    {
+      for (trans = tnfa->initial; trans->state; trans++)
+	{
+	  if (trans->tags)
+	    xfree(trans->tags);
+	}
+      xfree(tnfa->initial);
+    }
+
+  if (tnfa->submatch_data)
+    {
+      for (i = 0; i < tnfa->num_submatches; i++)
+	if (tnfa->submatch_data[i].parents)
+	  xfree(tnfa->submatch_data[i].parents);
+      xfree(tnfa->submatch_data);
+    }
+
+  if (tnfa->tag_directions)
+    xfree(tnfa->tag_directions);
+  if (tnfa->firstpos_chars)
+    xfree(tnfa->firstpos_chars);
+  if (tnfa->minimal_tags)
+    xfree(tnfa->minimal_tags);
+  xfree(tnfa);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/regerror.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/regerror.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/regerror.c	(revision 398)
@@ -0,0 +1,37 @@
+#include <string.h>
+#include <regex.h>
+#include <stdio.h>
+#include "locale_impl.h"
+
+/* Error message strings for error codes listed in `regex.h'.  This list
+   needs to be in sync with the codes listed there, naturally. */
+
+/* Converted to single string by Rich Felker to remove the need for
+ * data relocations at runtime, 27 Feb 2006. */
+
+static const char messages[] = {
+  "No error\0"
+  "No match\0"
+  "Invalid regexp\0"
+  "Unknown collating element\0"
+  "Unknown character class name\0"
+  "Trailing backslash\0"
+  "Invalid back reference\0"
+  "Missing ']'\0"
+  "Missing ')'\0"
+  "Missing '}'\0"
+  "Invalid contents of {}\0"
+  "Invalid character range\0"
+  "Out of memory\0"
+  "Repetition not preceded by valid expression\0"
+  "\0Unknown error"
+};
+
+size_t regerror(int e, const regex_t *restrict preg, char *restrict buf, size_t size)
+{
+	const char *s;
+	for (s=messages; e && *s; e--, s+=strlen(s)+1);
+	if (!*s) s++;
+	s = LCTRANS_CUR(s);
+	return 1+snprintf(buf, size, "%s", s);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/regexec.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/regexec.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/regexec.c	(revision 398)
@@ -0,0 +1,1028 @@
+/*
+  regexec.c - TRE POSIX compatible matching functions (and more).
+
+  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must 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 HOLDER 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 <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include <regex.h>
+
+#include "tre.h"
+
+#include <assert.h>
+
+static void
+tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
+		const tre_tnfa_t *tnfa, regoff_t *tags, regoff_t match_eo);
+
+/***********************************************************************
+ from tre-match-utils.h
+***********************************************************************/
+
+#define GET_NEXT_WCHAR() do {                                                 \
+    prev_c = next_c; pos += pos_add_next;                                     \
+    if ((pos_add_next = mbtowc(&next_c, str_byte, MB_LEN_MAX)) <= 0) {        \
+        if (pos_add_next < 0) { ret = REG_NOMATCH; goto error_exit; }         \
+        else pos_add_next++;                                                  \
+    }                                                                         \
+    str_byte += pos_add_next;                                                 \
+  } while (0)
+
+#define IS_WORD_CHAR(c)	 ((c) == L'_' || tre_isalnum(c))
+
+#define CHECK_ASSERTIONS(assertions)					      \
+  (((assertions & ASSERT_AT_BOL)					      \
+    && (pos > 0 || reg_notbol)						      \
+    && (prev_c != L'\n' || !reg_newline))				      \
+   || ((assertions & ASSERT_AT_EOL)					      \
+       && (next_c != L'\0' || reg_noteol)				      \
+       && (next_c != L'\n' || !reg_newline))				      \
+   || ((assertions & ASSERT_AT_BOW)					      \
+       && (IS_WORD_CHAR(prev_c) || !IS_WORD_CHAR(next_c)))	              \
+   || ((assertions & ASSERT_AT_EOW)					      \
+       && (!IS_WORD_CHAR(prev_c) || IS_WORD_CHAR(next_c)))		      \
+   || ((assertions & ASSERT_AT_WB)					      \
+       && (pos != 0 && next_c != L'\0'					      \
+	   && IS_WORD_CHAR(prev_c) == IS_WORD_CHAR(next_c)))		      \
+   || ((assertions & ASSERT_AT_WB_NEG)					      \
+       && (pos == 0 || next_c == L'\0'					      \
+	   || IS_WORD_CHAR(prev_c) != IS_WORD_CHAR(next_c))))
+
+#define CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)                             \
+  (((trans_i->assertions & ASSERT_CHAR_CLASS)                                 \
+       && !(tnfa->cflags & REG_ICASE)                                         \
+       && !tre_isctype((tre_cint_t)prev_c, trans_i->u.class))                 \
+    || ((trans_i->assertions & ASSERT_CHAR_CLASS)                             \
+        && (tnfa->cflags & REG_ICASE)                                         \
+        && !tre_isctype(tre_tolower((tre_cint_t)prev_c),trans_i->u.class)     \
+	&& !tre_isctype(tre_toupper((tre_cint_t)prev_c),trans_i->u.class))    \
+    || ((trans_i->assertions & ASSERT_CHAR_CLASS_NEG)                         \
+        && tre_neg_char_classes_match(trans_i->neg_classes,(tre_cint_t)prev_c,\
+                                      tnfa->cflags & REG_ICASE)))
+
+
+
+
+/* Returns 1 if `t1' wins `t2', 0 otherwise. */
+static int
+tre_tag_order(int num_tags, tre_tag_direction_t *tag_directions,
+	      regoff_t *t1, regoff_t *t2)
+{
+  int i;
+  for (i = 0; i < num_tags; i++)
+    {
+      if (tag_directions[i] == TRE_TAG_MINIMIZE)
+	{
+	  if (t1[i] < t2[i])
+	    return 1;
+	  if (t1[i] > t2[i])
+	    return 0;
+	}
+      else
+	{
+	  if (t1[i] > t2[i])
+	    return 1;
+	  if (t1[i] < t2[i])
+	    return 0;
+	}
+    }
+  /*  assert(0);*/
+  return 0;
+}
+
+static int
+tre_neg_char_classes_match(tre_ctype_t *classes, tre_cint_t wc, int icase)
+{
+  while (*classes != (tre_ctype_t)0)
+    if ((!icase && tre_isctype(wc, *classes))
+	|| (icase && (tre_isctype(tre_toupper(wc), *classes)
+		      || tre_isctype(tre_tolower(wc), *classes))))
+      return 1; /* Match. */
+    else
+      classes++;
+  return 0; /* No match. */
+}
+
+
+/***********************************************************************
+ from tre-match-parallel.c
+***********************************************************************/
+
+/*
+  This algorithm searches for matches basically by reading characters
+  in the searched string one by one, starting at the beginning.	 All
+  matching paths in the TNFA are traversed in parallel.	 When two or
+  more paths reach the same state, exactly one is chosen according to
+  tag ordering rules; if returning submatches is not required it does
+  not matter which path is chosen.
+
+  The worst case time required for finding the leftmost and longest
+  match, or determining that there is no match, is always linearly
+  dependent on the length of the text being searched.
+
+  This algorithm cannot handle TNFAs with back referencing nodes.
+  See `tre-match-backtrack.c'.
+*/
+
+typedef struct {
+  tre_tnfa_transition_t *state;
+  regoff_t *tags;
+} tre_tnfa_reach_t;
+
+typedef struct {
+  regoff_t pos;
+  regoff_t **tags;
+} tre_reach_pos_t;
+
+
+static reg_errcode_t
+tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string,
+		      regoff_t *match_tags, int eflags,
+		      regoff_t *match_end_ofs)
+{
+  /* State variables required by GET_NEXT_WCHAR. */
+  tre_char_t prev_c = 0, next_c = 0;
+  const char *str_byte = string;
+  regoff_t pos = -1;
+  regoff_t pos_add_next = 1;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate;
+#endif /* TRE_MBSTATE */
+  int reg_notbol = eflags & REG_NOTBOL;
+  int reg_noteol = eflags & REG_NOTEOL;
+  int reg_newline = tnfa->cflags & REG_NEWLINE;
+  reg_errcode_t ret;
+
+  char *buf;
+  tre_tnfa_transition_t *trans_i;
+  tre_tnfa_reach_t *reach, *reach_next, *reach_i, *reach_next_i;
+  tre_reach_pos_t *reach_pos;
+  int *tag_i;
+  int num_tags, i;
+
+  regoff_t match_eo = -1;	   /* end offset of match (-1 if no match found yet) */
+  int new_match = 0;
+  regoff_t *tmp_tags = NULL;
+  regoff_t *tmp_iptr;
+
+#ifdef TRE_MBSTATE
+  memset(&mbstate, '\0', sizeof(mbstate));
+#endif /* TRE_MBSTATE */
+
+  if (!match_tags)
+    num_tags = 0;
+  else
+    num_tags = tnfa->num_tags;
+
+  /* Allocate memory for temporary data required for matching.	This needs to
+     be done for every matching operation to be thread safe.  This allocates
+     everything in a single large block with calloc(). */
+  {
+    size_t tbytes, rbytes, pbytes, xbytes, total_bytes;
+    char *tmp_buf;
+
+    /* Ensure that tbytes and xbytes*num_states cannot overflow, and that
+     * they don't contribute more than 1/8 of SIZE_MAX to total_bytes. */
+    if (num_tags > SIZE_MAX/(8 * sizeof(regoff_t) * tnfa->num_states))
+      return REG_ESPACE;
+
+    /* Likewise check rbytes. */
+    if (tnfa->num_states+1 > SIZE_MAX/(8 * sizeof(*reach_next)))
+      return REG_ESPACE;
+
+    /* Likewise check pbytes. */
+    if (tnfa->num_states > SIZE_MAX/(8 * sizeof(*reach_pos)))
+      return REG_ESPACE;
+
+    /* Compute the length of the block we need. */
+    tbytes = sizeof(*tmp_tags) * num_tags;
+    rbytes = sizeof(*reach_next) * (tnfa->num_states + 1);
+    pbytes = sizeof(*reach_pos) * tnfa->num_states;
+    xbytes = sizeof(regoff_t) * num_tags;
+    total_bytes =
+      (sizeof(long) - 1) * 4 /* for alignment paddings */
+      + (rbytes + xbytes * tnfa->num_states) * 2 + tbytes + pbytes;
+
+    /* Allocate the memory. */
+    buf = calloc(total_bytes, 1);
+    if (buf == NULL)
+      return REG_ESPACE;
+
+    /* Get the various pointers within tmp_buf (properly aligned). */
+    tmp_tags = (void *)buf;
+    tmp_buf = buf + tbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    reach_next = (void *)tmp_buf;
+    tmp_buf += rbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    reach = (void *)tmp_buf;
+    tmp_buf += rbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    reach_pos = (void *)tmp_buf;
+    tmp_buf += pbytes;
+    tmp_buf += ALIGN(tmp_buf, long);
+    for (i = 0; i < tnfa->num_states; i++)
+      {
+	reach[i].tags = (void *)tmp_buf;
+	tmp_buf += xbytes;
+	reach_next[i].tags = (void *)tmp_buf;
+	tmp_buf += xbytes;
+      }
+  }
+
+  for (i = 0; i < tnfa->num_states; i++)
+    reach_pos[i].pos = -1;
+
+  GET_NEXT_WCHAR();
+  pos = 0;
+
+  reach_next_i = reach_next;
+  while (1)
+    {
+      /* If no match found yet, add the initial states to `reach_next'. */
+      if (match_eo < 0)
+	{
+	  trans_i = tnfa->initial;
+	  while (trans_i->state != NULL)
+	    {
+	      if (reach_pos[trans_i->state_id].pos < pos)
+		{
+		  if (trans_i->assertions
+		      && CHECK_ASSERTIONS(trans_i->assertions))
+		    {
+		      trans_i++;
+		      continue;
+		    }
+
+		  reach_next_i->state = trans_i->state;
+		  for (i = 0; i < num_tags; i++)
+		    reach_next_i->tags[i] = -1;
+		  tag_i = trans_i->tags;
+		  if (tag_i)
+		    while (*tag_i >= 0)
+		      {
+			if (*tag_i < num_tags)
+			  reach_next_i->tags[*tag_i] = pos;
+			tag_i++;
+		      }
+		  if (reach_next_i->state == tnfa->final)
+		    {
+		      match_eo = pos;
+		      new_match = 1;
+		      for (i = 0; i < num_tags; i++)
+			match_tags[i] = reach_next_i->tags[i];
+		    }
+		  reach_pos[trans_i->state_id].pos = pos;
+		  reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
+		  reach_next_i++;
+		}
+	      trans_i++;
+	    }
+	  reach_next_i->state = NULL;
+	}
+      else
+	{
+	  if (num_tags == 0 || reach_next_i == reach_next)
+	    /* We have found a match. */
+	    break;
+	}
+
+      /* Check for end of string. */
+      if (!next_c) break;
+
+      GET_NEXT_WCHAR();
+
+      /* Swap `reach' and `reach_next'. */
+      reach_i = reach;
+      reach = reach_next;
+      reach_next = reach_i;
+
+      /* For each state in `reach', weed out states that don't fulfill the
+	 minimal matching conditions. */
+      if (tnfa->num_minimals && new_match)
+	{
+	  new_match = 0;
+	  reach_next_i = reach_next;
+	  for (reach_i = reach; reach_i->state; reach_i++)
+	    {
+	      int skip = 0;
+	      for (i = 0; tnfa->minimal_tags[i] >= 0; i += 2)
+		{
+		  int end = tnfa->minimal_tags[i];
+		  int start = tnfa->minimal_tags[i + 1];
+		  if (end >= num_tags)
+		    {
+		      skip = 1;
+		      break;
+		    }
+		  else if (reach_i->tags[start] == match_tags[start]
+			   && reach_i->tags[end] < match_tags[end])
+		    {
+		      skip = 1;
+		      break;
+		    }
+		}
+	      if (!skip)
+		{
+		  reach_next_i->state = reach_i->state;
+		  tmp_iptr = reach_next_i->tags;
+		  reach_next_i->tags = reach_i->tags;
+		  reach_i->tags = tmp_iptr;
+		  reach_next_i++;
+		}
+	    }
+	  reach_next_i->state = NULL;
+
+	  /* Swap `reach' and `reach_next'. */
+	  reach_i = reach;
+	  reach = reach_next;
+	  reach_next = reach_i;
+	}
+
+      /* For each state in `reach' see if there is a transition leaving with
+	 the current input symbol to a state not yet in `reach_next', and
+	 add the destination states to `reach_next'. */
+      reach_next_i = reach_next;
+      for (reach_i = reach; reach_i->state; reach_i++)
+	{
+	  for (trans_i = reach_i->state; trans_i->state; trans_i++)
+	    {
+	      /* Does this transition match the input symbol? */
+	      if (trans_i->code_min <= (tre_cint_t)prev_c &&
+		  trans_i->code_max >= (tre_cint_t)prev_c)
+		{
+		  if (trans_i->assertions
+		      && (CHECK_ASSERTIONS(trans_i->assertions)
+			  || CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)))
+		    {
+		      continue;
+		    }
+
+		  /* Compute the tags after this transition. */
+		  for (i = 0; i < num_tags; i++)
+		    tmp_tags[i] = reach_i->tags[i];
+		  tag_i = trans_i->tags;
+		  if (tag_i != NULL)
+		    while (*tag_i >= 0)
+		      {
+			if (*tag_i < num_tags)
+			  tmp_tags[*tag_i] = pos;
+			tag_i++;
+		      }
+
+		  if (reach_pos[trans_i->state_id].pos < pos)
+		    {
+		      /* Found an unvisited node. */
+		      reach_next_i->state = trans_i->state;
+		      tmp_iptr = reach_next_i->tags;
+		      reach_next_i->tags = tmp_tags;
+		      tmp_tags = tmp_iptr;
+		      reach_pos[trans_i->state_id].pos = pos;
+		      reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
+
+		      if (reach_next_i->state == tnfa->final
+			  && (match_eo == -1
+			      || (num_tags > 0
+				  && reach_next_i->tags[0] <= match_tags[0])))
+			{
+			  match_eo = pos;
+			  new_match = 1;
+			  for (i = 0; i < num_tags; i++)
+			    match_tags[i] = reach_next_i->tags[i];
+			}
+		      reach_next_i++;
+
+		    }
+		  else
+		    {
+		      assert(reach_pos[trans_i->state_id].pos == pos);
+		      /* Another path has also reached this state.  We choose
+			 the winner by examining the tag values for both
+			 paths. */
+		      if (tre_tag_order(num_tags, tnfa->tag_directions,
+					tmp_tags,
+					*reach_pos[trans_i->state_id].tags))
+			{
+			  /* The new path wins. */
+			  tmp_iptr = *reach_pos[trans_i->state_id].tags;
+			  *reach_pos[trans_i->state_id].tags = tmp_tags;
+			  if (trans_i->state == tnfa->final)
+			    {
+			      match_eo = pos;
+			      new_match = 1;
+			      for (i = 0; i < num_tags; i++)
+				match_tags[i] = tmp_tags[i];
+			    }
+			  tmp_tags = tmp_iptr;
+			}
+		    }
+		}
+	    }
+	}
+      reach_next_i->state = NULL;
+    }
+
+  *match_end_ofs = match_eo;
+  ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;
+error_exit:
+  xfree(buf);
+  return ret;
+}
+
+
+
+/***********************************************************************
+ from tre-match-backtrack.c
+***********************************************************************/
+
+/*
+  This matcher is for regexps that use back referencing.  Regexp matching
+  with back referencing is an NP-complete problem on the number of back
+  references.  The easiest way to match them is to use a backtracking
+  routine which basically goes through all possible paths in the TNFA
+  and chooses the one which results in the best (leftmost and longest)
+  match.  This can be spectacularly expensive and may run out of stack
+  space, but there really is no better known generic algorithm.	 Quoting
+  Henry Spencer from comp.compilers:
+  <URL: http://compilers.iecc.com/comparch/article/93-03-102>
+
+    POSIX.2 REs require longest match, which is really exciting to
+    implement since the obsolete ("basic") variant also includes
+    \<digit>.  I haven't found a better way of tackling this than doing
+    a preliminary match using a DFA (or simulation) on a modified RE
+    that just replicates subREs for \<digit>, and then doing a
+    backtracking match to determine whether the subRE matches were
+    right.  This can be rather slow, but I console myself with the
+    thought that people who use \<digit> deserve very slow execution.
+    (Pun unintentional but very appropriate.)
+
+*/
+
+typedef struct {
+  regoff_t pos;
+  const char *str_byte;
+  tre_tnfa_transition_t *state;
+  int state_id;
+  int next_c;
+  regoff_t *tags;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate;
+#endif /* TRE_MBSTATE */
+} tre_backtrack_item_t;
+
+typedef struct tre_backtrack_struct {
+  tre_backtrack_item_t item;
+  struct tre_backtrack_struct *prev;
+  struct tre_backtrack_struct *next;
+} *tre_backtrack_t;
+
+#ifdef TRE_MBSTATE
+#define BT_STACK_MBSTATE_IN  stack->item.mbstate = (mbstate)
+#define BT_STACK_MBSTATE_OUT (mbstate) = stack->item.mbstate
+#else /* !TRE_MBSTATE */
+#define BT_STACK_MBSTATE_IN
+#define BT_STACK_MBSTATE_OUT
+#endif /* !TRE_MBSTATE */
+
+#define tre_bt_mem_new		  tre_mem_new
+#define tre_bt_mem_alloc	  tre_mem_alloc
+#define tre_bt_mem_destroy	  tre_mem_destroy
+
+
+#define BT_STACK_PUSH(_pos, _str_byte, _str_wide, _state, _state_id, _next_c, _tags, _mbstate) \
+  do									      \
+    {									      \
+      int i;								      \
+      if (!stack->next)							      \
+	{								      \
+	  tre_backtrack_t s;						      \
+	  s = tre_bt_mem_alloc(mem, sizeof(*s));			      \
+	  if (!s)							      \
+	    {								      \
+	      tre_bt_mem_destroy(mem);					      \
+	      if (tags)							      \
+		xfree(tags);						      \
+	      if (pmatch)						      \
+		xfree(pmatch);						      \
+	      if (states_seen)						      \
+		xfree(states_seen);					      \
+	      return REG_ESPACE;					      \
+	    }								      \
+	  s->prev = stack;						      \
+	  s->next = NULL;						      \
+	  s->item.tags = tre_bt_mem_alloc(mem,				      \
+					  sizeof(*tags) * tnfa->num_tags);    \
+	  if (!s->item.tags)						      \
+	    {								      \
+	      tre_bt_mem_destroy(mem);					      \
+	      if (tags)							      \
+		xfree(tags);						      \
+	      if (pmatch)						      \
+		xfree(pmatch);						      \
+	      if (states_seen)						      \
+		xfree(states_seen);					      \
+	      return REG_ESPACE;					      \
+	    }								      \
+	  stack->next = s;						      \
+	  stack = s;							      \
+	}								      \
+      else								      \
+	stack = stack->next;						      \
+      stack->item.pos = (_pos);						      \
+      stack->item.str_byte = (_str_byte);				      \
+      stack->item.state = (_state);					      \
+      stack->item.state_id = (_state_id);				      \
+      stack->item.next_c = (_next_c);					      \
+      for (i = 0; i < tnfa->num_tags; i++)				      \
+	stack->item.tags[i] = (_tags)[i];				      \
+      BT_STACK_MBSTATE_IN;						      \
+    }									      \
+  while (0)
+
+#define BT_STACK_POP()							      \
+  do									      \
+    {									      \
+      int i;								      \
+      assert(stack->prev);						      \
+      pos = stack->item.pos;						      \
+      str_byte = stack->item.str_byte;					      \
+      state = stack->item.state;					      \
+      next_c = stack->item.next_c;					      \
+      for (i = 0; i < tnfa->num_tags; i++)				      \
+	tags[i] = stack->item.tags[i];					      \
+      BT_STACK_MBSTATE_OUT;						      \
+      stack = stack->prev;						      \
+    }									      \
+  while (0)
+
+#undef MIN
+#define MIN(a, b) ((a) <= (b) ? (a) : (b))
+
+static reg_errcode_t
+tre_tnfa_run_backtrack(const tre_tnfa_t *tnfa, const void *string,
+		       regoff_t *match_tags, int eflags, regoff_t *match_end_ofs)
+{
+  /* State variables required by GET_NEXT_WCHAR. */
+  tre_char_t prev_c = 0, next_c = 0;
+  const char *str_byte = string;
+  regoff_t pos = 0;
+  regoff_t pos_add_next = 1;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate;
+#endif /* TRE_MBSTATE */
+  int reg_notbol = eflags & REG_NOTBOL;
+  int reg_noteol = eflags & REG_NOTEOL;
+  int reg_newline = tnfa->cflags & REG_NEWLINE;
+
+  /* These are used to remember the necessary values of the above
+     variables to return to the position where the current search
+     started from. */
+  int next_c_start;
+  const char *str_byte_start;
+  regoff_t pos_start = -1;
+#ifdef TRE_MBSTATE
+  mbstate_t mbstate_start;
+#endif /* TRE_MBSTATE */
+
+  /* End offset of best match so far, or -1 if no match found yet. */
+  regoff_t match_eo = -1;
+  /* Tag arrays. */
+  int *next_tags;
+  regoff_t *tags = NULL;
+  /* Current TNFA state. */
+  tre_tnfa_transition_t *state;
+  int *states_seen = NULL;
+
+  /* Memory allocator to for allocating the backtracking stack. */
+  tre_mem_t mem = tre_bt_mem_new();
+
+  /* The backtracking stack. */
+  tre_backtrack_t stack;
+
+  tre_tnfa_transition_t *trans_i;
+  regmatch_t *pmatch = NULL;
+  int ret;
+
+#ifdef TRE_MBSTATE
+  memset(&mbstate, '\0', sizeof(mbstate));
+#endif /* TRE_MBSTATE */
+
+  if (!mem)
+    return REG_ESPACE;
+  stack = tre_bt_mem_alloc(mem, sizeof(*stack));
+  if (!stack)
+    {
+      ret = REG_ESPACE;
+      goto error_exit;
+    }
+  stack->prev = NULL;
+  stack->next = NULL;
+
+  if (tnfa->num_tags)
+    {
+      tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
+      if (!tags)
+	{
+	  ret = REG_ESPACE;
+	  goto error_exit;
+	}
+    }
+  if (tnfa->num_submatches)
+    {
+      pmatch = xmalloc(sizeof(*pmatch) * tnfa->num_submatches);
+      if (!pmatch)
+	{
+	  ret = REG_ESPACE;
+	  goto error_exit;
+	}
+    }
+  if (tnfa->num_states)
+    {
+      states_seen = xmalloc(sizeof(*states_seen) * tnfa->num_states);
+      if (!states_seen)
+	{
+	  ret = REG_ESPACE;
+	  goto error_exit;
+	}
+    }
+
+ retry:
+  {
+    int i;
+    for (i = 0; i < tnfa->num_tags; i++)
+      {
+	tags[i] = -1;
+	if (match_tags)
+	  match_tags[i] = -1;
+      }
+    for (i = 0; i < tnfa->num_states; i++)
+      states_seen[i] = 0;
+  }
+
+  state = NULL;
+  pos = pos_start;
+  GET_NEXT_WCHAR();
+  pos_start = pos;
+  next_c_start = next_c;
+  str_byte_start = str_byte;
+#ifdef TRE_MBSTATE
+  mbstate_start = mbstate;
+#endif /* TRE_MBSTATE */
+
+  /* Handle initial states. */
+  next_tags = NULL;
+  for (trans_i = tnfa->initial; trans_i->state; trans_i++)
+    {
+      if (trans_i->assertions && CHECK_ASSERTIONS(trans_i->assertions))
+	{
+	  continue;
+	}
+      if (state == NULL)
+	{
+	  /* Start from this state. */
+	  state = trans_i->state;
+	  next_tags = trans_i->tags;
+	}
+      else
+	{
+	  /* Backtrack to this state. */
+	  BT_STACK_PUSH(pos, str_byte, 0, trans_i->state,
+			trans_i->state_id, next_c, tags, mbstate);
+	  {
+	    int *tmp = trans_i->tags;
+	    if (tmp)
+	      while (*tmp >= 0)
+		stack->item.tags[*tmp++] = pos;
+	  }
+	}
+    }
+
+  if (next_tags)
+    for (; *next_tags >= 0; next_tags++)
+      tags[*next_tags] = pos;
+
+
+  if (state == NULL)
+    goto backtrack;
+
+  while (1)
+    {
+      tre_tnfa_transition_t *next_state;
+      int empty_br_match;
+
+      if (state == tnfa->final)
+	{
+	  if (match_eo < pos
+	      || (match_eo == pos
+		  && match_tags
+		  && tre_tag_order(tnfa->num_tags, tnfa->tag_directions,
+				   tags, match_tags)))
+	    {
+	      int i;
+	      /* This match wins the previous match. */
+	      match_eo = pos;
+	      if (match_tags)
+		for (i = 0; i < tnfa->num_tags; i++)
+		  match_tags[i] = tags[i];
+	    }
+	  /* Our TNFAs never have transitions leaving from the final state,
+	     so we jump right to backtracking. */
+	  goto backtrack;
+	}
+
+      /* Go to the next character in the input string. */
+      empty_br_match = 0;
+      trans_i = state;
+      if (trans_i->state && trans_i->assertions & ASSERT_BACKREF)
+	{
+	  /* This is a back reference state.  All transitions leaving from
+	     this state have the same back reference "assertion".  Instead
+	     of reading the next character, we match the back reference. */
+	  regoff_t so, eo;
+	  int bt = trans_i->u.backref;
+	  regoff_t bt_len;
+	  int result;
+
+	  /* Get the substring we need to match against.  Remember to
+	     turn off REG_NOSUB temporarily. */
+	  tre_fill_pmatch(bt + 1, pmatch, tnfa->cflags & ~REG_NOSUB,
+			  tnfa, tags, pos);
+	  so = pmatch[bt].rm_so;
+	  eo = pmatch[bt].rm_eo;
+	  bt_len = eo - so;
+
+	  result = strncmp((const char*)string + so, str_byte - 1,
+				 (size_t)bt_len);
+
+	  if (result == 0)
+	    {
+	      /* Back reference matched.  Check for infinite loop. */
+	      if (bt_len == 0)
+		empty_br_match = 1;
+	      if (empty_br_match && states_seen[trans_i->state_id])
+		{
+		  goto backtrack;
+		}
+
+	      states_seen[trans_i->state_id] = empty_br_match;
+
+	      /* Advance in input string and resync `prev_c', `next_c'
+		 and pos. */
+	      str_byte += bt_len - 1;
+	      pos += bt_len - 1;
+	      GET_NEXT_WCHAR();
+	    }
+	  else
+	    {
+	      goto backtrack;
+	    }
+	}
+      else
+	{
+	  /* Check for end of string. */
+	  if (next_c == L'\0')
+		goto backtrack;
+
+	  /* Read the next character. */
+	  GET_NEXT_WCHAR();
+	}
+
+      next_state = NULL;
+      for (trans_i = state; trans_i->state; trans_i++)
+	{
+	  if (trans_i->code_min <= (tre_cint_t)prev_c
+	      && trans_i->code_max >= (tre_cint_t)prev_c)
+	    {
+	      if (trans_i->assertions
+		  && (CHECK_ASSERTIONS(trans_i->assertions)
+		      || CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)))
+		{
+		  continue;
+		}
+
+	      if (next_state == NULL)
+		{
+		  /* First matching transition. */
+		  next_state = trans_i->state;
+		  next_tags = trans_i->tags;
+		}
+	      else
+		{
+		  /* Second matching transition.  We may need to backtrack here
+		     to take this transition instead of the first one, so we
+		     push this transition in the backtracking stack so we can
+		     jump back here if needed. */
+		  BT_STACK_PUSH(pos, str_byte, 0, trans_i->state,
+				trans_i->state_id, next_c, tags, mbstate);
+		  {
+		    int *tmp;
+		    for (tmp = trans_i->tags; tmp && *tmp >= 0; tmp++)
+		      stack->item.tags[*tmp] = pos;
+		  }
+#if 0 /* XXX - it's important not to look at all transitions here to keep
+	 the stack small! */
+		  break;
+#endif
+		}
+	    }
+	}
+
+      if (next_state != NULL)
+	{
+	  /* Matching transitions were found.  Take the first one. */
+	  state = next_state;
+
+	  /* Update the tag values. */
+	  if (next_tags)
+	    while (*next_tags >= 0)
+	      tags[*next_tags++] = pos;
+	}
+      else
+	{
+	backtrack:
+	  /* A matching transition was not found.  Try to backtrack. */
+	  if (stack->prev)
+	    {
+	      if (stack->item.state->assertions & ASSERT_BACKREF)
+		{
+		  states_seen[stack->item.state_id] = 0;
+		}
+
+	      BT_STACK_POP();
+	    }
+	  else if (match_eo < 0)
+	    {
+	      /* Try starting from a later position in the input string. */
+	      /* Check for end of string. */
+	      if (next_c == L'\0')
+		    {
+		      break;
+		    }
+	      next_c = next_c_start;
+#ifdef TRE_MBSTATE
+	      mbstate = mbstate_start;
+#endif /* TRE_MBSTATE */
+	      str_byte = str_byte_start;
+	      goto retry;
+	    }
+	  else
+	    {
+	      break;
+	    }
+	}
+    }
+
+  ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;
+  *match_end_ofs = match_eo;
+
+ error_exit:
+  tre_bt_mem_destroy(mem);
+#ifndef TRE_USE_ALLOCA
+  if (tags)
+    xfree(tags);
+  if (pmatch)
+    xfree(pmatch);
+  if (states_seen)
+    xfree(states_seen);
+#endif /* !TRE_USE_ALLOCA */
+
+  return ret;
+}
+
+/***********************************************************************
+ from regexec.c
+***********************************************************************/
+
+/* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match
+   endpoint values. */
+static void
+tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
+		const tre_tnfa_t *tnfa, regoff_t *tags, regoff_t match_eo)
+{
+  tre_submatch_data_t *submatch_data;
+  unsigned int i, j;
+  int *parents;
+
+  i = 0;
+  if (match_eo >= 0 && !(cflags & REG_NOSUB))
+    {
+      /* Construct submatch offsets from the tags. */
+      submatch_data = tnfa->submatch_data;
+      while (i < tnfa->num_submatches && i < nmatch)
+	{
+	  if (submatch_data[i].so_tag == tnfa->end_tag)
+	    pmatch[i].rm_so = match_eo;
+	  else
+	    pmatch[i].rm_so = tags[submatch_data[i].so_tag];
+
+	  if (submatch_data[i].eo_tag == tnfa->end_tag)
+	    pmatch[i].rm_eo = match_eo;
+	  else
+	    pmatch[i].rm_eo = tags[submatch_data[i].eo_tag];
+
+	  /* If either of the endpoints were not used, this submatch
+	     was not part of the match. */
+	  if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1)
+	    pmatch[i].rm_so = pmatch[i].rm_eo = -1;
+
+	  i++;
+	}
+      /* Reset all submatches that are not within all of their parent
+	 submatches. */
+      i = 0;
+      while (i < tnfa->num_submatches && i < nmatch)
+	{
+	  if (pmatch[i].rm_eo == -1)
+	    assert(pmatch[i].rm_so == -1);
+	  assert(pmatch[i].rm_so <= pmatch[i].rm_eo);
+
+	  parents = submatch_data[i].parents;
+	  if (parents != NULL)
+	    for (j = 0; parents[j] >= 0; j++)
+	      {
+		if (pmatch[i].rm_so < pmatch[parents[j]].rm_so
+		    || pmatch[i].rm_eo > pmatch[parents[j]].rm_eo)
+		  pmatch[i].rm_so = pmatch[i].rm_eo = -1;
+	      }
+	  i++;
+	}
+    }
+
+  while (i < nmatch)
+    {
+      pmatch[i].rm_so = -1;
+      pmatch[i].rm_eo = -1;
+      i++;
+    }
+}
+
+
+/*
+  Wrapper functions for POSIX compatible regexp matching.
+*/
+
+int
+regexec(const regex_t *restrict preg, const char *restrict string,
+	  size_t nmatch, regmatch_t pmatch[restrict], int eflags)
+{
+  tre_tnfa_t *tnfa = (void *)preg->TRE_REGEX_T_FIELD;
+  reg_errcode_t status;
+  regoff_t *tags = NULL, eo;
+  if (tnfa->cflags & REG_NOSUB) nmatch = 0;
+  if (tnfa->num_tags > 0 && nmatch > 0)
+    {
+      tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
+      if (tags == NULL)
+	return REG_ESPACE;
+    }
+
+  /* Dispatch to the appropriate matcher. */
+  if (tnfa->have_backrefs)
+    {
+      /* The regex has back references, use the backtracking matcher. */
+      status = tre_tnfa_run_backtrack(tnfa, string, tags, eflags, &eo);
+    }
+  else
+    {
+      /* Exact matching, no back references, use the parallel matcher. */
+      status = tre_tnfa_run_parallel(tnfa, string, tags, eflags, &eo);
+    }
+
+  if (status == REG_OK)
+    /* A match was found, so fill the submatch registers. */
+    tre_fill_pmatch(nmatch, pmatch, tnfa->cflags, tnfa, tags, eo);
+  if (tags)
+    xfree(tags);
+  return status;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/tre-mem.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/tre-mem.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/tre-mem.c	(revision 398)
@@ -0,0 +1,158 @@
+/*
+  tre-mem.c - TRE memory allocator
+
+  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must 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 HOLDER 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.
+
+*/
+
+/*
+  This memory allocator is for allocating small memory blocks efficiently
+  in terms of memory overhead and execution speed.  The allocated blocks
+  cannot be freed individually, only all at once.  There can be multiple
+  allocators, though.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "tre.h"
+
+/*
+  This memory allocator is for allocating small memory blocks efficiently
+  in terms of memory overhead and execution speed.  The allocated blocks
+  cannot be freed individually, only all at once.  There can be multiple
+  allocators, though.
+*/
+
+/* Returns a new memory allocator or NULL if out of memory. */
+tre_mem_t
+tre_mem_new_impl(int provided, void *provided_block)
+{
+  tre_mem_t mem;
+  if (provided)
+    {
+      mem = provided_block;
+      memset(mem, 0, sizeof(*mem));
+    }
+  else
+    mem = xcalloc(1, sizeof(*mem));
+  if (mem == NULL)
+    return NULL;
+  return mem;
+}
+
+
+/* Frees the memory allocator and all memory allocated with it. */
+void
+tre_mem_destroy(tre_mem_t mem)
+{
+  tre_list_t *tmp, *l = mem->blocks;
+
+  while (l != NULL)
+    {
+      xfree(l->data);
+      tmp = l->next;
+      xfree(l);
+      l = tmp;
+    }
+  xfree(mem);
+}
+
+
+/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
+   allocated block or NULL if an underlying malloc() failed. */
+void *
+tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
+		   int zero, size_t size)
+{
+  void *ptr;
+
+  if (mem->failed)
+    {
+      return NULL;
+    }
+
+  if (mem->n < size)
+    {
+      /* We need more memory than is available in the current block.
+	 Allocate a new block. */
+      tre_list_t *l;
+      if (provided)
+	{
+	  if (provided_block == NULL)
+	    {
+	      mem->failed = 1;
+	      return NULL;
+	    }
+	  mem->ptr = provided_block;
+	  mem->n = TRE_MEM_BLOCK_SIZE;
+	}
+      else
+	{
+	  int block_size;
+	  if (size * 8 > TRE_MEM_BLOCK_SIZE)
+	    block_size = size * 8;
+	  else
+	    block_size = TRE_MEM_BLOCK_SIZE;
+	  l = xmalloc(sizeof(*l));
+	  if (l == NULL)
+	    {
+	      mem->failed = 1;
+	      return NULL;
+	    }
+	  l->data = xmalloc(block_size);
+	  if (l->data == NULL)
+	    {
+	      xfree(l);
+	      mem->failed = 1;
+	      return NULL;
+	    }
+	  l->next = NULL;
+	  if (mem->current != NULL)
+	    mem->current->next = l;
+	  if (mem->blocks == NULL)
+	    mem->blocks = l;
+	  mem->current = l;
+	  mem->ptr = l->data;
+	  mem->n = block_size;
+	}
+    }
+
+  /* Make sure the next pointer will be aligned. */
+  size += ALIGN(mem->ptr + size, long);
+
+  /* Allocate from current block. */
+  ptr = mem->ptr;
+  mem->ptr += size;
+  mem->n -= size;
+
+  /* Set to zero if needed. */
+  if (zero)
+    memset(ptr, 0, size);
+
+  return ptr;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/tre.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/tre.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/regex/tre.h	(revision 398)
@@ -0,0 +1,231 @@
+/*
+  tre-internal.h - TRE internal definitions
+
+  Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must 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 HOLDER 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 <regex.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#undef  TRE_MBSTATE
+
+#define NDEBUG
+
+#define TRE_REGEX_T_FIELD __opaque
+typedef int reg_errcode_t;
+
+typedef wchar_t tre_char_t;
+
+#define DPRINT(msg) do { } while(0)
+
+#define elementsof(x)	( sizeof(x) / sizeof(x[0]) )
+
+#define tre_mbrtowc(pwc, s, n, ps) (mbtowc((pwc), (s), (n)))
+
+/* Wide characters. */
+typedef wint_t tre_cint_t;
+#define TRE_CHAR_MAX 0x10ffff
+
+#define tre_isalnum iswalnum
+#define tre_isalpha iswalpha
+#define tre_isblank iswblank
+#define tre_iscntrl iswcntrl
+#define tre_isdigit iswdigit
+#define tre_isgraph iswgraph
+#define tre_islower iswlower
+#define tre_isprint iswprint
+#define tre_ispunct iswpunct
+#define tre_isspace iswspace
+#define tre_isupper iswupper
+#define tre_isxdigit iswxdigit
+
+#define tre_tolower towlower
+#define tre_toupper towupper
+#define tre_strlen  wcslen
+
+/* Use system provided iswctype() and wctype(). */
+typedef wctype_t tre_ctype_t;
+#define tre_isctype iswctype
+#define tre_ctype   wctype
+
+/* Returns number of bytes to add to (char *)ptr to make it
+   properly aligned for the type. */
+#define ALIGN(ptr, type) \
+  ((((long)ptr) % sizeof(type)) \
+   ? (sizeof(type) - (((long)ptr) % sizeof(type))) \
+   : 0)
+
+#undef MAX
+#undef MIN
+#define MAX(a, b) (((a) >= (b)) ? (a) : (b))
+#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
+
+/* TNFA transition type. A TNFA state is an array of transitions,
+   the terminator is a transition with NULL `state'. */
+typedef struct tnfa_transition tre_tnfa_transition_t;
+
+struct tnfa_transition {
+  /* Range of accepted characters. */
+  tre_cint_t code_min;
+  tre_cint_t code_max;
+  /* Pointer to the destination state. */
+  tre_tnfa_transition_t *state;
+  /* ID number of the destination state. */
+  int state_id;
+  /* -1 terminated array of tags (or NULL). */
+  int *tags;
+  /* Assertion bitmap. */
+  int assertions;
+  /* Assertion parameters. */
+  union {
+    /* Character class assertion. */
+    tre_ctype_t class;
+    /* Back reference assertion. */
+    int backref;
+  } u;
+  /* Negative character class assertions. */
+  tre_ctype_t *neg_classes;
+};
+
+
+/* Assertions. */
+#define ASSERT_AT_BOL		  1   /* Beginning of line. */
+#define ASSERT_AT_EOL		  2   /* End of line. */
+#define ASSERT_CHAR_CLASS	  4   /* Character class in `class'. */
+#define ASSERT_CHAR_CLASS_NEG	  8   /* Character classes in `neg_classes'. */
+#define ASSERT_AT_BOW		 16   /* Beginning of word. */
+#define ASSERT_AT_EOW		 32   /* End of word. */
+#define ASSERT_AT_WB		 64   /* Word boundary. */
+#define ASSERT_AT_WB_NEG	128   /* Not a word boundary. */
+#define ASSERT_BACKREF		256   /* A back reference in `backref'. */
+#define ASSERT_LAST		256
+
+/* Tag directions. */
+typedef enum {
+  TRE_TAG_MINIMIZE = 0,
+  TRE_TAG_MAXIMIZE = 1
+} tre_tag_direction_t;
+
+/* Instructions to compute submatch register values from tag values
+   after a successful match.  */
+struct tre_submatch_data {
+  /* Tag that gives the value for rm_so (submatch start offset). */
+  int so_tag;
+  /* Tag that gives the value for rm_eo (submatch end offset). */
+  int eo_tag;
+  /* List of submatches this submatch is contained in. */
+  int *parents;
+};
+
+typedef struct tre_submatch_data tre_submatch_data_t;
+
+
+/* TNFA definition. */
+typedef struct tnfa tre_tnfa_t;
+
+struct tnfa {
+  tre_tnfa_transition_t *transitions;
+  unsigned int num_transitions;
+  tre_tnfa_transition_t *initial;
+  tre_tnfa_transition_t *final;
+  tre_submatch_data_t *submatch_data;
+  char *firstpos_chars;
+  int first_char;
+  unsigned int num_submatches;
+  tre_tag_direction_t *tag_directions;
+  int *minimal_tags;
+  int num_tags;
+  int num_minimals;
+  int end_tag;
+  int num_states;
+  int cflags;
+  int have_backrefs;
+  int have_approx;
+};
+
+/* from tre-mem.h: */
+
+#define TRE_MEM_BLOCK_SIZE 1024
+
+typedef struct tre_list {
+  void *data;
+  struct tre_list *next;
+} tre_list_t;
+
+typedef struct tre_mem_struct {
+  tre_list_t *blocks;
+  tre_list_t *current;
+  char *ptr;
+  size_t n;
+  int failed;
+  void **provided;
+} *tre_mem_t;
+
+#define tre_mem_new_impl   __tre_mem_new_impl
+#define tre_mem_alloc_impl __tre_mem_alloc_impl
+#define tre_mem_destroy    __tre_mem_destroy
+
+tre_mem_t tre_mem_new_impl(int provided, void *provided_block);
+void *tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
+			 int zero, size_t size);
+
+/* Returns a new memory allocator or NULL if out of memory. */
+#define tre_mem_new()  tre_mem_new_impl(0, NULL)
+
+/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
+   allocated block or NULL if an underlying malloc() failed. */
+#define tre_mem_alloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 0, size)
+
+/* Allocates a block of `size' bytes from `mem'.  Returns a pointer to the
+   allocated block or NULL if an underlying malloc() failed.  The memory
+   is set to zero. */
+#define tre_mem_calloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 1, size)
+
+#ifdef TRE_USE_ALLOCA
+/* alloca() versions.  Like above, but memory is allocated with alloca()
+   instead of malloc(). */
+
+#define tre_mem_newa() \
+  tre_mem_new_impl(1, alloca(sizeof(struct tre_mem_struct)))
+
+#define tre_mem_alloca(mem, size)					      \
+  ((mem)->n >= (size)							      \
+   ? tre_mem_alloc_impl((mem), 1, NULL, 0, (size))			      \
+   : tre_mem_alloc_impl((mem), 1, alloca(TRE_MEM_BLOCK_SIZE), 0, (size)))
+#endif /* TRE_USE_ALLOCA */
+
+
+/* Frees the memory allocator and all memory allocated with it. */
+void tre_mem_destroy(tre_mem_t mem);
+
+#define xmalloc malloc
+#define xcalloc calloc
+#define xfree free
+#define xrealloc realloc
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/affinity.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/affinity.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/affinity.c	(revision 398)
@@ -0,0 +1,33 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include <string.h>
+#include "pthread_impl.h"
+#include "syscall.h"
+
+int sched_setaffinity(pid_t tid, size_t size, const cpu_set_t *set)
+{
+	return syscall(SYS_sched_setaffinity, tid, size, set);
+}
+
+int pthread_setaffinity_np(pthread_t td, size_t size, const cpu_set_t *set)
+{
+	return -__syscall(SYS_sched_setaffinity, td->tid, size, set);
+}
+
+static int do_getaffinity(pid_t tid, size_t size, cpu_set_t *set)
+{
+	long ret = __syscall(SYS_sched_getaffinity, tid, size, set);
+	if (ret < 0) return ret;
+	if (ret < size) memset((char *)set+ret, 0, size-ret);
+	return 0;
+}
+
+int sched_getaffinity(pid_t tid, size_t size, cpu_set_t *set)
+{
+	return __syscall_ret(do_getaffinity(tid, size, set));
+}
+
+int pthread_getaffinity_np(pthread_t td, size_t size, cpu_set_t *set)
+{
+	return -do_getaffinity(td->tid, size, set);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_cpucount.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_cpucount.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_cpucount.c	(revision 398)
@@ -0,0 +1,11 @@
+#define _GNU_SOURCE
+#include <sched.h>
+
+int __sched_cpucount(size_t size, const cpu_set_t *set)
+{
+	size_t i, j, cnt=0;
+	const unsigned char *p = (const void *)set;
+	for (i=0; i<size; i++) for (j=0; j<8; j++)
+		if (p[i] & (1<<j)) cnt++;
+	return cnt;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_get_priority_max.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_get_priority_max.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_get_priority_max.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sched.h>
+#include "syscall.h"
+
+int sched_get_priority_max(int policy)
+{
+	return syscall(SYS_sched_get_priority_max, policy);
+}
+
+int sched_get_priority_min(int policy)
+{
+	return syscall(SYS_sched_get_priority_min, policy);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_getcpu.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_getcpu.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_getcpu.c	(revision 398)
@@ -0,0 +1,44 @@
+#define _GNU_SOURCE
+#include <errno.h>
+#include <sched.h>
+#include "syscall.h"
+#include "atomic.h"
+
+#ifdef VDSO_GETCPU_SYM
+
+void *__vdsosym(const char *, const char *);
+
+static void *volatile vdso_func;
+
+typedef long (*getcpu_f)(unsigned *, unsigned *, void *);
+
+static long getcpu_init(unsigned *cpu, unsigned *node, void *unused)
+{
+	void *p = __vdsosym(VDSO_GETCPU_VER, VDSO_GETCPU_SYM);
+	getcpu_f f = (getcpu_f)p;
+	a_cas_p(&vdso_func, (void *)getcpu_init, p);
+	return f ? f(cpu, node, unused) : -ENOSYS;
+}
+
+static void *volatile vdso_func = (void *)getcpu_init;
+
+#endif
+
+int sched_getcpu(void)
+{
+	int r;
+	unsigned cpu;
+
+#ifdef VDSO_GETCPU_SYM
+	getcpu_f f = (getcpu_f)vdso_func;
+	if (f) {
+		r = f(&cpu, 0, 0);
+		if (!r) return cpu;
+		if (r != -ENOSYS) return __syscall_ret(r);
+	}
+#endif
+
+	r = __syscall(SYS_getcpu, &cpu, 0, 0);
+	if (!r) return cpu;
+	return __syscall_ret(r);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_getparam.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_getparam.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_getparam.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sched_getparam(pid_t pid, struct sched_param *param)
+{
+	return __syscall_ret(-ENOSYS);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_getscheduler.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_getscheduler.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_getscheduler.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sched_getscheduler(pid_t pid)
+{
+	return __syscall_ret(-ENOSYS);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_rr_get_interval.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_rr_get_interval.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_rr_get_interval.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sched.h>
+#include "syscall.h"
+
+int sched_rr_get_interval(pid_t pid, struct timespec *ts)
+{
+	return syscall(SYS_sched_rr_get_interval, pid, ts);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_setparam.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_setparam.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_setparam.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sched_setparam(pid_t pid, const struct sched_param *param)
+{
+	return __syscall_ret(-ENOSYS);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_setscheduler.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_setscheduler.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_setscheduler.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sched.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sched_setscheduler(pid_t pid, int sched, const struct sched_param *param)
+{
+	return __syscall_ret(-ENOSYS);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_yield.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_yield.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/sched/sched_yield.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sched.h>
+#include "syscall.h"
+
+int sched_yield()
+{
+	return syscall(SYS_sched_yield);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/hsearch.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/hsearch.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/hsearch.c	(revision 398)
@@ -0,0 +1,154 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <search.h>
+#include "libc.h"
+
+/*
+open addressing hash table with 2^n table size
+quadratic probing is used in case of hash collision
+tab indices and hash are size_t
+after resize fails with ENOMEM the state of tab is still usable
+
+with the posix api items cannot be iterated and length cannot be queried
+*/
+
+#define MINSIZE 8
+#define MAXSIZE ((size_t)-1/2 + 1)
+
+struct __tab {
+	ENTRY *entries;
+	size_t mask;
+	size_t used;
+};
+
+static struct hsearch_data htab;
+
+int __hcreate_r(size_t, struct hsearch_data *);
+void __hdestroy_r(struct hsearch_data *);
+int __hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
+
+static size_t keyhash(char *k)
+{
+	unsigned char *p = (void *)k;
+	size_t h = 0;
+
+	while (*p)
+		h = 31*h + *p++;
+	return h;
+}
+
+static int resize(size_t nel, struct hsearch_data *htab)
+{
+	size_t newsize;
+	size_t i, j;
+	ENTRY *e, *newe;
+	ENTRY *oldtab = htab->__tab->entries;
+	ENTRY *oldend = htab->__tab->entries + htab->__tab->mask + 1;
+
+	if (nel > MAXSIZE)
+		nel = MAXSIZE;
+	for (newsize = MINSIZE; newsize < nel; newsize *= 2);
+	htab->__tab->entries = calloc(newsize, sizeof *htab->__tab->entries);
+	if (!htab->__tab->entries) {
+		htab->__tab->entries = oldtab;
+		return 0;
+	}
+	htab->__tab->mask = newsize - 1;
+	if (!oldtab)
+		return 1;
+	for (e = oldtab; e < oldend; e++)
+		if (e->key) {
+			for (i=keyhash(e->key),j=1; ; i+=j++) {
+				newe = htab->__tab->entries + (i & htab->__tab->mask);
+				if (!newe->key)
+					break;
+			}
+			*newe = *e;
+		}
+	free(oldtab);
+	return 1;
+}
+
+int hcreate(size_t nel)
+{
+	return __hcreate_r(nel, &htab);
+}
+
+void hdestroy(void)
+{
+	__hdestroy_r(&htab);
+}
+
+static ENTRY *lookup(char *key, size_t hash, struct hsearch_data *htab)
+{
+	size_t i, j;
+	ENTRY *e;
+
+	for (i=hash,j=1; ; i+=j++) {
+		e = htab->__tab->entries + (i & htab->__tab->mask);
+		if (!e->key || strcmp(e->key, key) == 0)
+			break;
+	}
+	return e;
+}
+
+ENTRY *hsearch(ENTRY item, ACTION action)
+{
+	ENTRY *e;
+
+	__hsearch_r(item, action, &e, &htab);
+	return e;
+}
+
+int __hcreate_r(size_t nel, struct hsearch_data *htab)
+{
+	int r;
+
+	htab->__tab = calloc(1, sizeof *htab->__tab);
+	if (!htab->__tab)
+		return 0;
+	r = resize(nel, htab);
+	if (r == 0) {
+		free(htab->__tab);
+		htab->__tab = 0;
+	}
+	return r;
+}
+weak_alias(__hcreate_r, hcreate_r);
+
+void __hdestroy_r(struct hsearch_data *htab)
+{
+	if (htab->__tab) free(htab->__tab->entries);
+	free(htab->__tab);
+	htab->__tab = 0;
+}
+weak_alias(__hdestroy_r, hdestroy_r);
+
+int __hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)
+{
+	size_t hash = keyhash(item.key);
+	ENTRY *e = lookup(item.key, hash, htab);
+
+	if (e->key) {
+		*retval = e;
+		return 1;
+	}
+	if (action == FIND) {
+		*retval = 0;
+		return 0;
+	}
+	*e = item;
+	if (++htab->__tab->used > htab->__tab->mask - htab->__tab->mask/4) {
+		if (!resize(2*htab->__tab->used, htab)) {
+			htab->__tab->used--;
+			e->key = 0;
+			*retval = 0;
+			return 0;
+		}
+		e = lookup(item.key, hash, htab);
+	}
+	*retval = e;
+	return 1;
+}
+weak_alias(__hsearch_r, hsearch_r);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/insque.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/insque.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/insque.c	(revision 398)
@@ -0,0 +1,32 @@
+#include <search.h>
+
+struct node {
+	struct node *next;
+	struct node *prev;
+};
+
+void insque(void *element, void *pred)
+{
+	struct node *e = element;
+	struct node *p = pred;
+
+	if (!p) {
+		e->next = e->prev = 0;
+		return;
+	}
+	e->next = p->next;
+	e->prev = p;
+	p->next = e;
+	if (e->next)
+		e->next->prev = e;
+}
+
+void remque(void *element)
+{
+	struct node *e = element;
+
+	if (e->next)
+		e->next->prev = e->prev;
+	if (e->prev)
+		e->prev->next = e->next;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/lsearch.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/lsearch.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/lsearch.c	(revision 398)
@@ -0,0 +1,31 @@
+#include <search.h>
+#include <string.h>
+
+void *lsearch(const void *key, void *base, size_t *nelp, size_t width,
+	int (*compar)(const void *, const void *))
+{
+	char (*p)[width] = base;
+	size_t n = *nelp;
+	size_t i;
+
+	for (i = 0; i < n; i++)
+		if (compar(key, p[i]) == 0)
+			return p[i];
+	*nelp = n+1;
+	return memcpy(p[n], key, width);
+}
+
+void *lfind(const void *key, const void *base, size_t *nelp,
+	size_t width, int (*compar)(const void *, const void *))
+{
+	char (*p)[width] = (void *)base;
+	size_t n = *nelp;
+	size_t i;
+
+	for (i = 0; i < n; i++)
+		if (compar(key, p[i]) == 0)
+			return p[i];
+	return 0;
+}
+
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/tdestroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/tdestroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/tdestroy.c	(revision 398)
@@ -0,0 +1,21 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <search.h>
+
+struct node {
+	void *key;
+	struct node *left;
+	struct node *right;
+};
+
+void tdestroy(void *root, void (*freekey)(void *))
+{
+	struct node *r = root;
+
+	if (r == 0)
+		return;
+	tdestroy(r->left, freekey);
+	tdestroy(r->right, freekey);
+	if (freekey) freekey(r->key);
+	free(r);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/tsearch_avl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/tsearch_avl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/search/tsearch_avl.c	(revision 398)
@@ -0,0 +1,204 @@
+#include <stdlib.h>
+#include <search.h>
+
+/*
+avl tree implementation using recursive functions
+the height of an n node tree is less than 1.44*log2(n+2)-1
+(so the max recursion depth in case of a tree with 2^32 nodes is 45)
+*/
+
+struct node {
+	const void *key;
+	struct node *left;
+	struct node *right;
+	int height;
+};
+
+static int delta(struct node *n) {
+	return (n->left ? n->left->height:0) - (n->right ? n->right->height:0);
+}
+
+static void updateheight(struct node *n) {
+	n->height = 0;
+	if (n->left && n->left->height > n->height)
+		n->height = n->left->height;
+	if (n->right && n->right->height > n->height)
+		n->height = n->right->height;
+	n->height++;
+}
+
+static struct node *rotl(struct node *n) {
+	struct node *r = n->right;
+	n->right = r->left;
+	r->left = n;
+	updateheight(n);
+	updateheight(r);
+	return r;
+}
+
+static struct node *rotr(struct node *n) {
+	struct node *l = n->left;
+	n->left = l->right;
+	l->right = n;
+	updateheight(n);
+	updateheight(l);
+	return l;
+}
+
+static struct node *balance(struct node *n) {
+	int d = delta(n);
+
+	if (d < -1) {
+		if (delta(n->right) > 0)
+			n->right = rotr(n->right);
+		return rotl(n);
+	} else if (d > 1) {
+		if (delta(n->left) < 0)
+			n->left = rotl(n->left);
+		return rotr(n);
+	}
+	updateheight(n);
+	return n;
+}
+
+static struct node *find(struct node *n, const void *k,
+	int (*cmp)(const void *, const void *))
+{
+	int c;
+
+	if (!n)
+		return 0;
+	c = cmp(k, n->key);
+	if (c == 0)
+		return n;
+	if (c < 0)
+		return find(n->left, k, cmp);
+	else
+		return find(n->right, k, cmp);
+}
+
+static struct node *insert(struct node *n, const void *k,
+	int (*cmp)(const void *, const void *), struct node **found)
+{
+	struct node *r;
+	int c;
+
+	if (!n) {
+		n = malloc(sizeof *n);
+		if (n) {
+			n->key = k;
+			n->left = n->right = 0;
+			n->height = 1;
+		}
+		*found = n;
+		return n;
+	}
+	c = cmp(k, n->key);
+	if (c == 0) {
+		*found = n;
+		return 0;
+	}
+	r = insert(c < 0 ? n->left : n->right, k, cmp, found);
+	if (r) {
+		if (c < 0)
+			n->left = r;
+		else
+			n->right = r;
+		r = balance(n);
+	}
+	return r;
+}
+
+static struct node *remove_rightmost(struct node *n, struct node **rightmost)
+{
+	if (!n->right) {
+		*rightmost = n;
+		return n->left;
+	}
+	n->right = remove_rightmost(n->right, rightmost);
+	return balance(n);
+}
+
+static struct node *remove(struct node **n, const void *k,
+	int (*cmp)(const void *, const void *), struct node *parent)
+{
+	int c;
+
+	if (!*n)
+		return 0;
+	c = cmp(k, (*n)->key);
+	if (c == 0) {
+		struct node *r = *n;
+		if (r->left) {
+			r->left = remove_rightmost(r->left, n);
+			(*n)->left = r->left;
+			(*n)->right = r->right;
+			*n = balance(*n);
+		} else
+			*n = r->right;
+		free(r);
+		return parent;
+	}
+	if (c < 0)
+		parent = remove(&(*n)->left, k, cmp, *n);
+	else
+		parent = remove(&(*n)->right, k, cmp, *n);
+	if (parent)
+		*n = balance(*n);
+	return parent;
+}
+
+void *tdelete(const void *restrict key, void **restrict rootp,
+	int(*compar)(const void *, const void *))
+{
+	if (!rootp)
+		return 0;
+	struct node *n = *rootp;
+	struct node *ret;
+	/* last argument is arbitrary non-null pointer
+	   which is returned when the root node is deleted */
+	ret = remove(&n, key, compar, n);
+	*rootp = n;
+	return ret;
+}
+
+void *tfind(const void *key, void *const *rootp,
+	int(*compar)(const void *, const void *))
+{
+	if (!rootp)
+		return 0;
+	return find(*rootp, key, compar);
+}
+
+void *tsearch(const void *key, void **rootp,
+	int (*compar)(const void *, const void *))
+{
+	struct node *update;
+	struct node *ret;
+	if (!rootp)
+		return 0;
+	update = insert(*rootp, key, compar, &ret);
+	if (update)
+		*rootp = update;
+	return ret;
+}
+
+static void walk(const struct node *r, void (*action)(const void *, VISIT, int), int d)
+{
+	if (r == 0)
+		return;
+	if (r->left == 0 && r->right == 0)
+		action(r, leaf, d);
+	else {
+		action(r, preorder, d);
+		walk(r->left, action, d+1);
+		action(r, postorder, d);
+		walk(r->right, action, d+1);
+		action(r, endorder, d);
+	}
+}
+
+void twalk(const void *root, void (*action)(const void *, VISIT, int))
+{
+	walk(root, action, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/select/poll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/select/poll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/select/poll.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <poll.h>
+#include <time.h>
+#include <signal.h>
+#include "syscall.h"
+#include "libc.h"
+
+int poll(struct pollfd *fds, nfds_t n, int timeout)
+{
+#ifdef SYS_poll
+	return syscall_cp(SYS_poll, fds, n, timeout);
+#else
+	return syscall_cp(SYS_ppoll, fds, n, timeout>=0 ?
+		&((struct timespec){ .tv_sec = timeout/1000,
+		.tv_nsec = timeout%1000*1000000 }) : 0, 0, _NSIG/8);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/select/pselect.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/select/pselect.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/select/pselect.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <sys/select.h>
+#include <signal.h>
+#include <stdint.h>
+#include "syscall.h"
+#include "libc.h"
+
+int pselect(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, const struct timespec *restrict ts, const sigset_t *restrict mask)
+{
+	syscall_arg_t data[2] = { (uintptr_t)mask, _NSIG/8 };
+	struct timespec ts_tmp;
+	if (ts) ts_tmp = *ts;
+	return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, ts ? &ts_tmp : 0, data);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/select/select.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/select/select.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/select/select.c	(revision 398)
@@ -0,0 +1,26 @@
+#include <sys/select.h>
+#include <signal.h>
+#include <stdint.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+
+int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval *restrict tv)
+{
+#ifdef SYS_select
+	return syscall_cp(SYS_select, n, rfds, wfds, efds, tv);
+#else
+	syscall_arg_t data[2] = { 0, _NSIG/8 };
+	struct timespec ts;
+	if (tv) {
+		if (tv->tv_sec < 0 || tv->tv_usec < 0)
+			return __syscall_ret(-EINVAL);
+		time_t extra_secs = tv->tv_usec / 1000000;
+		ts.tv_nsec = tv->tv_usec % 1000000 * 1000;
+		const time_t max_time = (1ULL<<8*sizeof(time_t)-1)-1;
+		ts.tv_sec = extra_secs > max_time - tv->tv_sec ?
+			max_time : tv->tv_sec + extra_secs;
+	}
+	return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, tv ? &ts : 0, data);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/setjmp/longjmp.S
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/setjmp/longjmp.S	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/setjmp/longjmp.S	(revision 398)
@@ -0,0 +1,30 @@
+.global _longjmp
+.global longjmp
+.type   _longjmp, @function
+.type   longjmp,  @function
+_longjmp:
+longjmp:
+	tst	r2, r2
+	stz	#1, r2
+	mov.l	r2, 4[r1]
+	mov.l	[r1], r0
+	mov.l	64[r1], r2
+	mov.l	r2, [r0]
+	mov.l	60[r1], r15
+	mov.l	56[r1], r14
+	mov.l	52[r1], r13
+	mov.l	48[r1], r12
+	mov.l	44[r1], r11
+	mov.l	40[r1], r10
+	mov.l	36[r1], r9
+	mov.l	32[r1], r8
+	mov.l	28[r1], r7
+	mov.l	24[r1], r6
+	mov.l	20[r1], r5
+	mov.l	16[r1], r4
+	mov.l	12[r1], r3
+	mov.l	8[r1], r2
+	mov.l	4[r1], r1
+
+	rts
+	 nop
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/setjmp/setjmp.S
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/setjmp/setjmp.S	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/setjmp/setjmp.S	(revision 398)
@@ -0,0 +1,33 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type   __setjmp, @function
+.type   _setjmp,  @function
+.type   setjmp,   @function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	mov.l	r0, [r1]
+	mov.l	r1, 4[r1]
+	mov.l	r2, 8[r1]
+	mov.l	r3, 12[r1]
+	mov.l	r4, 16[r1]
+	mov.l	r5, 20[r1]
+	mov.l	r6, 24[r1]
+	mov.l	r7, 28[r1]
+	mov.l	r8, 32[r1]
+	mov.l	r9, 36[r1]
+	mov.l	r10, 40[r1]
+	mov.l	r11, 44[r1]
+	mov.l	r12, 48[r1]
+	mov.l	r13, 52[r1]
+	mov.l	r14, 56[r1]
+	mov.l	r15, 60[r1]
+	mov.l	[r0], r2
+	mov.l	r2, 64[r1]
+	mov.l	#0, r1
+	rts
+	 mov  #0, r0
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/block.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/block.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/block.c	(revision 398)
@@ -0,0 +1,44 @@
+#include "pthread_impl.h"
+#include "syscall.h"
+#include <signal.h>
+
+static const unsigned long all_mask[] = {
+#if ULONG_MAX == 0xffffffff && _NSIG == 129
+	-1UL, -1UL, -1UL, -1UL
+#elif ULONG_MAX == 0xffffffff
+	-1UL, -1UL
+#else
+	-1UL
+#endif
+};
+
+static const unsigned long app_mask[] = {
+#if ULONG_MAX == 0xffffffff
+#if _NSIG == 65
+	0x7fffffff, 0xfffffffc
+#else
+	0x7fffffff, 0xfffffffc, -1UL, -1UL
+#endif
+#else
+#if _NSIG == 65
+	0xfffffffc7fffffff
+#else
+	0xfffffffc7fffffff, -1UL
+#endif
+#endif
+};
+
+void __block_all_sigs(void *set)
+{
+	__syscall(SYS_rt_sigprocmask, SIG_BLOCK, &all_mask, set, _NSIG/8);
+}
+
+void __block_app_sigs(void *set)
+{
+	__syscall(SYS_rt_sigprocmask, SIG_BLOCK, &app_mask, set, _NSIG/8);
+}
+
+void __restore_sigs(void *set)
+{
+	__syscall(SYS_rt_sigprocmask, SIG_SETMASK, set, 0, _NSIG/8);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/getitimer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/getitimer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/getitimer.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/time.h>
+#include "syscall.h"
+
+int getitimer(int which, struct itimerval *old)
+{
+	return syscall(SYS_getitimer, which, old);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/kill.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/kill.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/kill.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include "syscall.h"
+
+int kill(pid_t pid, int sig)
+{
+	return syscall(SYS_kill, pid, sig);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/killpg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/killpg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/killpg.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <signal.h>
+#include <errno.h>
+
+int killpg(pid_t pgid, int sig)
+{
+	if (pgid < 0) {
+		errno = EINVAL;
+		return -1;
+	}
+	return kill(-pgid, sig);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/psiginfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/psiginfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/psiginfo.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+void psiginfo(const siginfo_t *si, const char *msg)
+{
+	char *s = strsignal(si->si_signo);
+	if (msg) fprintf(stderr, "%s: %s\n", msg, s);
+	else fprintf(stderr, "%s\n", s);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/psignal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/psignal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/psignal.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+void psignal(int sig, const char *msg)
+{
+	char *s = strsignal(sig);
+	if (msg) fprintf(stderr, "%s: %s\n", msg, s);
+	else fprintf(stderr, "%s\n", s);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/raise.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/raise.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/raise.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <signal.h>
+#include <stdint.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+
+int raise(int sig)
+{
+	int tid, ret;
+	sigset_t set;
+	__block_app_sigs(&set);
+	tid = __syscall(SYS_gettid);
+	ret = syscall(SYS_tkill, tid, sig);
+	__restore_sigs(&set);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/restore.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/restore.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/restore.c	(revision 398)
@@ -0,0 +1,10 @@
+/* These functions will not work, but suffice for targets where the
+ * kernel sigaction structure does not actually use sa_restorer. */
+
+void __restore()
+{
+}
+
+void __restore_rt()
+{
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/setitimer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/setitimer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/setitimer.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/time.h>
+#include "syscall.h"
+
+int setitimer(int which, const struct itimerval *restrict new, struct itimerval *restrict old)
+{
+	return syscall(SYS_setitimer, which, new, old);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigaction.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigaction.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigaction.c	(revision 398)
@@ -0,0 +1,63 @@
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+#include "libc.h"
+#include "ksigaction.h"
+
+static int unmask_done;
+static unsigned long handler_set[_NSIG/(8*sizeof(long))];
+
+void __get_handler_set(sigset_t *set)
+{
+	memcpy(set, handler_set, sizeof handler_set);
+}
+
+int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
+{
+	struct k_sigaction ksa, ksa_old;
+	if (sa) {
+		if ((uintptr_t)sa->sa_handler > 1UL) {
+			a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
+				1UL<<(sig-1)%(8*sizeof(long)));
+
+			/* If pthread_create has not yet been called,
+			 * implementation-internal signals might not
+			 * yet have been unblocked. They must be
+			 * unblocked before any signal handler is
+			 * installed, so that an application cannot
+			 * receive an illegal sigset_t (with them
+			 * blocked) as part of the ucontext_t passed
+			 * to the signal handler. */
+			if (!libc.threaded && !unmask_done) {
+				__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
+					SIGPT_SET, 0, _NSIG/8);
+				unmask_done = 1;
+			}
+		}
+		ksa.handler = sa->sa_handler;
+		ksa.flags = sa->sa_flags | SA_RESTORER;
+		ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
+		memcpy(&ksa.mask, &sa->sa_mask, sizeof ksa.mask);
+	}
+	if (syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, sizeof ksa.mask))
+		return -1;
+	if (old) {
+		old->sa_handler = ksa_old.handler;
+		old->sa_flags = ksa_old.flags;
+		memcpy(&old->sa_mask, &ksa_old.mask, sizeof ksa_old.mask);
+	}
+	return 0;
+}
+
+int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
+{
+	if (sig-32U < 3 || sig-1U >= _NSIG-1) {
+		errno = EINVAL;
+		return -1;
+	}
+	return __libc_sigaction(sig, sa, old);
+}
+
+weak_alias(__sigaction, sigaction);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigaddset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigaddset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigaddset.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <errno.h>
+
+int sigaddset(sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	if (s >= _NSIG-1 || sig-32U < 3) {
+		errno = EINVAL;
+		return -1;
+	}
+	set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigaltstack.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigaltstack.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigaltstack.c	(revision 398)
@@ -0,0 +1,18 @@
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sigaltstack(const stack_t *restrict ss, stack_t *restrict old)
+{
+	if (ss) {
+		if (ss->ss_size < MINSIGSTKSZ) {
+			errno = ENOMEM;
+			return -1;
+		}
+		if (ss->ss_flags & ~SS_DISABLE) {
+			errno = EINVAL;
+			return -1;
+		}
+	}
+	return syscall(SYS_sigaltstack, ss, old);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigandset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigandset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigandset.c	(revision 398)
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <signal.h>
+
+#define SST_SIZE (_NSIG/8/sizeof(long))
+
+int sigandset(sigset_t *dest, const sigset_t *left, const sigset_t *right)
+{
+	unsigned long i = 0, *d = (void*) dest, *l = (void*) left, *r = (void*) right;
+	for(; i < SST_SIZE; i++) d[i] = l[i] & r[i];
+	return 0;
+}
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigdelset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigdelset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigdelset.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <errno.h>
+
+int sigdelset(sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	if (s >= _NSIG-1 || sig-32U < 3) {
+		errno = EINVAL;
+		return -1;
+	}
+	set->__bits[s/8/sizeof *set->__bits] &=~(1UL<<(s&8*sizeof *set->__bits-1));
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigemptyset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigemptyset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigemptyset.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <string.h>
+
+int sigemptyset(sigset_t *set)
+{
+	set->__bits[0] = 0;
+	if (sizeof(long)==4 || _NSIG > 65) set->__bits[1] = 0;
+	if (sizeof(long)==4 && _NSIG > 65) {
+		set->__bits[2] = 0;
+		set->__bits[3] = 0;
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigfillset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigfillset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigfillset.c	(revision 398)
@@ -0,0 +1,18 @@
+#include <signal.h>
+#include <limits.h>
+
+int sigfillset(sigset_t *set)
+{
+#if ULONG_MAX == 0xffffffff
+	set->__bits[0] = 0x7ffffffful;
+	set->__bits[1] = 0xfffffffcul;
+	if (_NSIG > 65) {
+		set->__bits[2] = 0xfffffffful;
+		set->__bits[3] = 0xfffffffful;
+	}
+#else
+	set->__bits[0] = 0xfffffffc7ffffffful;
+	if (_NSIG > 65) set->__bits[1] = 0xfffffffffffffffful;
+#endif
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sighold.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sighold.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sighold.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <signal.h>
+
+int sighold(int sig)
+{
+	sigset_t mask;
+
+	sigemptyset(&mask);
+	if (sigaddset(&mask, sig) < 0) return -1;
+	return sigprocmask(SIG_BLOCK, &mask, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigignore.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigignore.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigignore.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <signal.h>
+
+int sigignore(int sig)
+{
+	struct sigaction sa;
+
+	sigemptyset(&sa.sa_mask);
+	sa.sa_handler = SIG_IGN;
+	sa.sa_flags = 0;
+	return sigaction(sig, &sa, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/siginterrupt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/siginterrupt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/siginterrupt.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <signal.h>
+
+int siginterrupt(int sig, int flag)
+{
+	struct sigaction sa;
+
+	sigaction(sig, 0, &sa);
+	if (flag) sa.sa_flags &= ~SA_RESTART;
+	else sa.sa_flags |= SA_RESTART;
+
+	return sigaction(sig, &sa, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigisemptyset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigisemptyset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigisemptyset.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <signal.h>
+#include <string.h>
+
+int sigisemptyset(const sigset_t *set)
+{
+	static const unsigned long zeroset[_NSIG/8/sizeof(long)];
+	return !memcmp(set, &zeroset, _NSIG/8);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigismember.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigismember.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigismember.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <signal.h>
+
+int sigismember(const sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	if (s >= _NSIG-1) return 0;
+	return !!(set->__bits[s/8/sizeof *set->__bits] & 1UL<<(s&8*sizeof *set->__bits-1));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/siglongjmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/siglongjmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/siglongjmp.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <setjmp.h>
+#include <signal.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+
+_Noreturn void siglongjmp(sigjmp_buf buf, int ret)
+{
+	longjmp(buf, ret);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/signal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/signal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/signal.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <signal.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __sigaction(int, const struct sigaction *, struct sigaction *);
+
+void (*signal(int sig, void (*func)(int)))(int)
+{
+	struct sigaction sa_old, sa = { .sa_handler = func, .sa_flags = SA_RESTART };
+	if (__sigaction(sig, &sa, &sa_old) < 0)
+		return SIG_ERR;
+	return sa_old.sa_handler;
+}
+
+weak_alias(signal, bsd_signal);
+weak_alias(signal, __sysv_signal);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigorset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigorset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigorset.c	(revision 398)
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <signal.h>
+
+#define SST_SIZE (_NSIG/8/sizeof(long))
+
+int sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right)
+{
+	unsigned long i = 0, *d = (void*) dest, *l = (void*) left, *r = (void*) right;
+	for(; i < SST_SIZE; i++) d[i] = l[i] | r[i];
+	return 0;
+}
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigpause.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigpause.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigpause.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <signal.h>
+
+int sigpause(int sig)
+{
+	sigset_t mask;
+	sigprocmask(0, 0, &mask);
+	sigdelset(&mask, sig);
+	return sigsuspend(&mask);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigpending.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigpending.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigpending.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <signal.h>
+#include "syscall.h"
+
+int sigpending(sigset_t *set)
+{
+	return syscall(SYS_rt_sigpending, set, _NSIG/8);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigprocmask.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigprocmask.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigprocmask.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <signal.h>
+#include <errno.h>
+
+int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
+{
+	int r = pthread_sigmask(how, set, old);
+	if (!r) return r;
+	errno = r;
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigqueue.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigqueue.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigqueue.c	(revision 398)
@@ -0,0 +1,22 @@
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+
+int sigqueue(pid_t pid, int sig, const union sigval value)
+{
+	siginfo_t si;
+	sigset_t set;
+	int r;
+	memset(&si, 0, sizeof si);
+	si.si_signo = sig;
+	si.si_code = SI_QUEUE;
+	si.si_value = value;
+	si.si_uid = getuid();
+	__block_app_sigs(&set);
+	si.si_pid = getpid();
+	r = syscall(SYS_rt_sigqueueinfo, pid, sig, &si);
+	__restore_sigs(&set);
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigrelse.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigrelse.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigrelse.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <signal.h>
+
+int sigrelse(int sig)
+{
+	sigset_t mask;
+
+	sigemptyset(&mask);
+	if (sigaddset(&mask, sig) < 0) return -1;
+	return sigprocmask(SIG_UNBLOCK, &mask, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigrtmax.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigrtmax.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigrtmax.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <signal.h>
+
+int __libc_current_sigrtmax()
+{
+	return _NSIG-1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigrtmin.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigrtmin.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigrtmin.c	(revision 398)
@@ -0,0 +1,4 @@
+int __libc_current_sigrtmin()
+{
+	return 35;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigset.c	(revision 398)
@@ -0,0 +1,27 @@
+#include <signal.h>
+
+void (*sigset(int sig, void (*handler)(int)))(int)
+{
+	struct sigaction sa, sa_old;
+	sigset_t mask;
+
+	sigemptyset(&mask);
+	if (sigaddset(&mask, sig) < 0)
+		return SIG_ERR;
+	
+	if (handler == SIG_HOLD) {
+		if (sigaction(sig, 0, &sa_old) < 0)
+			return SIG_ERR;
+		if (sigprocmask(SIG_BLOCK, &mask, &mask) < 0)
+			return SIG_ERR;
+	} else {
+		sa.sa_handler = handler;
+		sa.sa_flags = 0;
+		sigemptyset(&sa.sa_mask);
+		if (sigaction(sig, &sa, &sa_old) < 0)
+			return SIG_ERR;
+		if (sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
+			return SIG_ERR;
+	}
+	return sigismember(&mask, sig) ? SIG_HOLD : sa_old.sa_handler;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigsetjmp_tail.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigsetjmp_tail.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigsetjmp_tail.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <setjmp.h>
+#include <signal.h>
+#include "syscall.h"
+
+__attribute__((__visibility__("hidden")))
+int __sigsetjmp_tail(sigjmp_buf jb, int ret)
+{
+	void *p = jb->__ss;
+	__syscall(SYS_rt_sigprocmask, SIG_SETMASK, ret?p:0, ret?0:p, _NSIG/8);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigsuspend.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigsuspend.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigsuspend.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <signal.h>
+#include "syscall.h"
+#include "libc.h"
+
+int sigsuspend(const sigset_t *mask)
+{
+	return syscall_cp(SYS_rt_sigsuspend, mask, _NSIG/8);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigtimedwait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigtimedwait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigtimedwait.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+
+int sigtimedwait(const sigset_t *restrict mask, siginfo_t *restrict si, const struct timespec *restrict timeout)
+{
+	int ret;
+	do ret = syscall_cp(SYS_rt_sigtimedwait, mask,
+		si, timeout, _NSIG/8);
+	while (ret<0 && errno==EINTR);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigwait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigwait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigwait.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <signal.h>
+
+int sigwait(const sigset_t *restrict mask, int *restrict sig)
+{
+	siginfo_t si;
+	if (sigtimedwait(mask, &si, 0) < 0)
+		return -1;
+	*sig = si.si_signo;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigwaitinfo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigwaitinfo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/signal/sigwaitinfo.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <signal.h>
+
+int sigwaitinfo(const sigset_t *restrict mask, siginfo_t *restrict si)
+{
+	return sigtimedwait(mask, si, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/__xstat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/__xstat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/__xstat.c	(revision 398)
@@ -0,0 +1,37 @@
+#include <sys/stat.h>
+#include "libc.h"
+
+int __fxstat(int ver, int fd, struct stat *buf)
+{
+	return fstat(fd, buf);
+}
+
+int __fxstatat(int ver, int fd, const char *path, struct stat *buf, int flag)
+{
+	return fstatat(fd, path, buf, flag);
+}
+
+int __lxstat(int ver, const char *path, struct stat *buf)
+{
+	return lstat(path, buf);
+}
+
+int __xstat(int ver, const char *path, struct stat *buf)
+{
+	return stat(path, buf);
+}
+
+LFS64(__fxstat);
+LFS64(__fxstatat);
+LFS64(__lxstat);
+LFS64(__xstat);
+
+int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev)
+{
+	return mknod(path, mode, *dev);
+}
+
+int __xmknodat(int ver, int fd, const char *path, mode_t mode, dev_t *dev)
+{
+	return mknodat(fd, path, mode, *dev);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/chmod.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/chmod.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/chmod.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int chmod(const char *path, mode_t mode)
+{
+#ifdef SYS_chmod
+	return syscall(SYS_chmod, path, mode);
+#else
+	return syscall(SYS_fchmodat, AT_FDCWD, path, mode);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fchmod.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fchmod.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fchmod.c	(revision 398)
@@ -0,0 +1,21 @@
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+void __procfdname(char *, unsigned);
+
+int fchmod(int fd, mode_t mode)
+{
+	int ret = __syscall(SYS_fchmod, fd, mode);
+	if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
+		return __syscall_ret(ret);
+
+	char buf[15+3*sizeof(int)];
+	__procfdname(buf, fd);
+#ifdef SYS_chmod
+	return syscall(SYS_chmod, buf, mode);
+#else
+	return syscall(SYS_fchmodat, AT_FDCWD, buf, mode);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fchmodat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fchmodat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fchmodat.c	(revision 398)
@@ -0,0 +1,39 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+void __procfdname(char *, unsigned);
+
+int fchmodat(int fd, const char *path, mode_t mode, int flag)
+{
+	if (!flag) return syscall(SYS_fchmodat, fd, path, mode, flag);
+
+	if (flag != AT_SYMLINK_NOFOLLOW)
+		return __syscall_ret(-EINVAL);
+
+	struct stat st;
+	int ret, fd2;
+	char proc[15+3*sizeof(int)];
+
+	if ((ret = __syscall(SYS_fstatat, fd, path, &st, flag)))
+		return __syscall_ret(ret);
+	if (S_ISLNK(st.st_mode))
+		return __syscall_ret(-EOPNOTSUPP);
+
+	if ((fd2 = __syscall(SYS_openat, fd, path, O_RDONLY|O_PATH|O_NOFOLLOW|O_NOCTTY|O_CLOEXEC)) < 0) {
+		if (fd2 == -ELOOP)
+			return __syscall_ret(-EOPNOTSUPP);
+		return __syscall_ret(fd2);
+	}
+
+	__procfdname(proc, fd2);
+	ret = __syscall(SYS_fstatat, AT_FDCWD, proc, &st, 0);
+	if (!ret) {
+		if (S_ISLNK(st.st_mode)) ret = -EOPNOTSUPP;
+		else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
+	}
+
+	__syscall(SYS_close, fd2);
+	return __syscall_ret(ret);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fstat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fstat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fstat.c	(revision 398)
@@ -0,0 +1,24 @@
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+#include "libc.h"
+
+void __procfdname(char *, unsigned);
+
+int fstat(int fd, struct stat *st)
+{
+	int ret = __syscall(SYS_fstat, fd, st);
+	if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
+		return __syscall_ret(ret);
+
+	char buf[15+3*sizeof(int)];
+	__procfdname(buf, fd);
+#ifdef SYS_stat
+	return syscall(SYS_stat, buf, st);
+#else
+	return syscall(SYS_fstatat, AT_FDCWD, buf, st, 0);
+#endif
+}
+
+LFS64(fstat);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fstatat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fstatat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/fstatat.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <sys/stat.h>
+#include "syscall.h"
+#include "libc.h"
+
+int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag)
+{
+	return syscall(SYS_fstatat, fd, path, buf, flag);
+}
+
+LFS64(fstatat);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/futimens.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/futimens.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/futimens.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <sys/stat.h>
+
+int futimens(int fd, const struct timespec times[2])
+{
+	return utimensat(fd, 0, times, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/futimesat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/futimesat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/futimesat.c	(revision 398)
@@ -0,0 +1,23 @@
+#define _GNU_SOURCE
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __futimesat(int dirfd, const char *pathname, const struct timeval times[2])
+{
+	struct timespec ts[2];
+	if (times) {
+		int i;
+		for (i=0; i<2; i++) {
+			if (times[i].tv_usec >= 1000000ULL)
+				return __syscall_ret(-EINVAL);
+			ts[i].tv_sec = times[i].tv_sec;
+			ts[i].tv_nsec = times[i].tv_usec * 1000;
+		}
+	}
+	return utimensat(dirfd, pathname, times ? ts : 0, 0);
+}
+
+weak_alias(__futimesat, futimesat);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/lchmod.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/lchmod.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/lchmod.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int lchmod(const char *path, mode_t mode)
+{
+	return fchmodat(AT_FDCWD, path, mode, AT_SYMLINK_NOFOLLOW);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/lstat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/lstat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/lstat.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "syscall.h"
+#include "libc.h"
+
+int lstat(const char *restrict path, struct stat *restrict buf)
+{
+#ifdef SYS_lstat
+	return syscall(SYS_lstat, path, buf);
+#else
+	return syscall(SYS_fstatat, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
+#endif
+}
+
+LFS64(lstat);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkdir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkdir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkdir.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int mkdir(const char *path, mode_t mode)
+{
+#ifdef SYS_mkdir
+	return syscall(SYS_mkdir, path, mode);
+#else
+	return syscall(SYS_mkdirat, AT_FDCWD, path, mode);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkdirat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkdirat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkdirat.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int mkdirat(int fd, const char *path, mode_t mode)
+{
+	return syscall(SYS_mkdirat, fd, path, mode);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkfifo.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkfifo.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkfifo.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <sys/stat.h>
+
+int mkfifo(const char *path, mode_t mode)
+{
+	return mknod(path, mode | S_IFIFO, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkfifoat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkfifoat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mkfifoat.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <sys/stat.h>
+
+int mkfifoat(int fd, const char *path, mode_t mode)
+{
+	return mknodat(fd, path, mode | S_IFIFO, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mknod.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mknod.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mknod.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int mknod(const char *path, mode_t mode, dev_t dev)
+{
+#ifdef SYS_mknod
+	return syscall(SYS_mknod, path, mode, dev);
+#else
+	return syscall(SYS_mknodat, AT_FDCWD, path, mode, dev);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mknodat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mknodat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/mknodat.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+int mknodat(int fd, const char *path, mode_t mode, dev_t dev)
+{
+	return syscall(SYS_mknodat, fd, path, mode, dev);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/stat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/stat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/stat.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "syscall.h"
+#include "libc.h"
+
+int stat(const char *restrict path, struct stat *restrict buf)
+{
+#ifdef SYS_stat
+	return syscall(SYS_stat, path, buf);
+#else
+	return syscall(SYS_fstatat, AT_FDCWD, path, buf, 0);
+#endif
+}
+
+LFS64(stat);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/statvfs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/statvfs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/statvfs.c	(revision 398)
@@ -0,0 +1,64 @@
+#include <sys/statvfs.h>
+#include <sys/statfs.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __statfs(const char *path, struct statfs *buf)
+{
+	*buf = (struct statfs){0};
+#ifdef SYS_statfs64
+	return syscall(SYS_statfs64, path, sizeof *buf, buf);
+#else
+	return syscall(SYS_statfs, path, buf);
+#endif
+}
+
+int __fstatfs(int fd, struct statfs *buf)
+{
+	*buf = (struct statfs){0};
+#ifdef SYS_fstatfs64
+	return syscall(SYS_fstatfs64, fd, sizeof *buf, buf);
+#else
+	return syscall(SYS_fstatfs, fd, buf);
+#endif
+}
+
+weak_alias(__statfs, statfs);
+weak_alias(__fstatfs, fstatfs);
+
+static void fixup(struct statvfs *out, const struct statfs *in)
+{
+	*out = (struct statvfs){0};
+	out->f_bsize = in->f_bsize;
+	out->f_frsize = in->f_frsize ? in->f_frsize : in->f_bsize;
+	out->f_blocks = in->f_blocks;
+	out->f_bfree = in->f_bfree;
+	out->f_bavail = in->f_bavail;
+	out->f_files = in->f_files;
+	out->f_ffree = in->f_ffree;
+	out->f_favail = in->f_ffree;
+	out->f_fsid = in->f_fsid.__val[0];
+	out->f_flag = in->f_flags;
+	out->f_namemax = in->f_namelen;
+}
+
+int statvfs(const char *restrict path, struct statvfs *restrict buf)
+{
+	struct statfs kbuf;
+	if (__statfs(path, &kbuf)<0) return -1;
+	fixup(buf, &kbuf);
+	return 0;
+}
+
+int fstatvfs(int fd, struct statvfs *buf)
+{
+	struct statfs kbuf;
+	if (__fstatfs(fd, &kbuf)<0) return -1;
+	fixup(buf, &kbuf);
+	return 0;
+}
+
+LFS64(statvfs);
+LFS64(statfs);
+LFS64(fstatvfs);
+LFS64(fstatfs);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/umask.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/umask.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/umask.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include "syscall.h"
+
+mode_t umask(mode_t mode)
+{
+	return syscall(SYS_umask, mode);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/utimensat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/utimensat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stat/utimensat.c	(revision 398)
@@ -0,0 +1,37 @@
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int utimensat(int fd, const char *path, const struct timespec times[2], int flags)
+{
+	int r = __syscall(SYS_utimensat, fd, path, times, flags);
+#ifdef SYS_futimesat
+	if (r != -ENOSYS || flags) return __syscall_ret(r);
+	struct timeval *tv = 0, tmp[2];
+	if (times) {
+		int i;
+		tv = tmp;
+		for (i=0; i<2; i++) {
+			if (times[i].tv_nsec >= 1000000000ULL) {
+				if (times[i].tv_nsec == UTIME_NOW &&
+				    times[1-i].tv_nsec == UTIME_NOW) {
+					tv = 0;
+					break;
+				}
+				if (times[i].tv_nsec == UTIME_OMIT)
+					return __syscall_ret(-ENOSYS);
+				return __syscall_ret(-EINVAL);
+			}
+			tmp[i].tv_sec = times[i].tv_sec;
+			tmp[i].tv_usec = times[i].tv_nsec / 1000;
+		}
+	}
+
+	r = __syscall(SYS_futimesat, fd, path, tv);
+	if (r != -ENOSYS || fd != AT_FDCWD) return __syscall_ret(r);
+	r = __syscall(SYS_utimes, path, tv);
+#endif
+	return __syscall_ret(r);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fclose_ca.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fclose_ca.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fclose_ca.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int __fclose_ca(FILE *f)
+{
+	return f->close(f);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fdopen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fdopen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fdopen.c	(revision 398)
@@ -0,0 +1,60 @@
+#include "stdio_impl.h"
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+FILE *__fdopen(int fd, const char *mode)
+{
+	FILE *f;
+	struct winsize wsz;
+
+	/* Check for valid initial mode character */
+	if (!strchr("rwa", *mode)) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	/* Allocate FILE+buffer or fail */
+	if (!(f=malloc(sizeof *f + UNGET + BUFSIZ))) return 0;
+
+	/* Zero-fill only the struct, not the buffer */
+	memset(f, 0, sizeof *f);
+
+	/* Impose mode restrictions */
+	if (!strchr(mode, '+')) f->flags = (*mode == 'r') ? F_NOWR : F_NORD;
+
+	/* Apply close-on-exec flag */
+	if (strchr(mode, 'e')) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
+
+	/* Set append mode on fd if opened for append */
+	if (*mode == 'a') {
+		int flags = __syscall(SYS_fcntl, fd, F_GETFL);
+		if (!(flags & O_APPEND))
+			__syscall(SYS_fcntl, fd, F_SETFL, flags | O_APPEND);
+		f->flags |= F_APP;
+	}
+
+	f->fd = fd;
+	f->buf = (unsigned char *)f + sizeof *f + UNGET;
+	f->buf_size = BUFSIZ;
+
+	/* Activate line buffered mode for terminals */
+	f->lbf = EOF;
+	if (!(f->flags & F_NOWR) && !__syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz))
+		f->lbf = '\n';
+
+	/* Initialize op ptrs. No problem if some are unneeded. */
+	f->read = __stdio_read;
+	f->write = __stdio_write;
+	f->seek = __stdio_seek;
+	f->close = __stdio_close;
+
+	if (!libc.threaded) f->lock = -1;
+
+	/* Add new FILE to open file list */
+	return __ofl_add(f);
+}
+
+weak_alias(__fdopen, fdopen);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fmodeflags.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fmodeflags.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fmodeflags.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <fcntl.h>
+#include <string.h>
+
+int __fmodeflags(const char *mode)
+{
+	int flags;
+	if (strchr(mode, '+')) flags = O_RDWR;
+	else if (*mode == 'r') flags = O_RDONLY;
+	else flags = O_WRONLY;
+	if (strchr(mode, 'x')) flags |= O_EXCL;
+	if (strchr(mode, 'e')) flags |= O_CLOEXEC;
+	if (*mode != 'r') flags |= O_CREAT;
+	if (*mode == 'w') flags |= O_TRUNC;
+	if (*mode == 'a') flags |= O_APPEND;
+	return flags;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fopen_rb_ca.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fopen_rb_ca.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__fopen_rb_ca.c	(revision 398)
@@ -0,0 +1,22 @@
+#include "stdio_impl.h"
+#include <fcntl.h>
+#include <string.h>
+
+FILE *__fopen_rb_ca(const char *filename, FILE *f, unsigned char *buf, size_t len)
+{
+	memset(f, 0, sizeof *f);
+
+	f->fd = sys_open(filename, O_RDONLY|O_CLOEXEC);
+	if (f->fd < 0) return 0;
+	__syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);
+
+	f->flags = F_NOWR | F_PERM;
+	f->buf = buf + UNGET;
+	f->buf_size = len - UNGET;
+	f->read = __stdio_read;
+	f->seek = __stdio_seek;
+	f->close = __stdio_close;
+	f->lock = -1;
+
+	return f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__lockfile.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__lockfile.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__lockfile.c	(revision 398)
@@ -0,0 +1,28 @@
+#include "stdio_impl.h"
+#include "pthread_impl.h"
+
+int __lockfile(FILE *f)
+{
+	int owner, tid = __pthread_self()->tid;
+	if (f->lock == tid)
+		return 0;
+	while ((owner = a_cas(&f->lock, 0, tid)))
+		__wait(&f->lock, &f->waiters, owner, 1);
+	return 1;
+}
+
+void __unlockfile(FILE *f)
+{
+	a_store(&f->lock, 0);
+
+	/* The following read is technically invalid under situations
+	 * of self-synchronized destruction. Another thread may have
+	 * called fclose as soon as the above store has completed.
+	 * Nonetheless, since FILE objects always live in memory
+	 * obtained by malloc from the heap, it's safe to assume
+	 * the dereferences below will not fault. In the worst case,
+	 * a spurious syscall will be made. If the implementation of
+	 * malloc changes, this assumption needs revisiting. */
+
+	if (f->waiters) __wake(&f->lock, 1, 1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__overflow.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__overflow.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__overflow.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+int __overflow(FILE *f, int _c)
+{
+	unsigned char c = _c;
+	if (!f->wend && __towrite(f)) return EOF;
+	if (f->wpos < f->wend && c != f->lbf) return *f->wpos++ = c;
+	if (f->write(f, &c, 1)!=1) return EOF;
+	return c;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_close.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_close.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_close.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+
+static int dummy(int fd)
+{
+	return fd;
+}
+
+weak_alias(dummy, __aio_close);
+
+int __stdio_close(FILE *f)
+{
+	return syscall(SYS_close, __aio_close(f->fd));
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_exit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_exit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_exit.c	(revision 398)
@@ -0,0 +1,24 @@
+#include "stdio_impl.h"
+
+static FILE *volatile dummy_file = 0;
+weak_alias(dummy_file, __stdin_used);
+weak_alias(dummy_file, __stdout_used);
+weak_alias(dummy_file, __stderr_used);
+
+static void close_file(FILE *f)
+{
+	if (!f) return;
+	FFINALLOCK(f);
+	if (f->wpos > f->wbase) f->write(f, 0, 0);
+	if (f->rpos < f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);
+}
+
+void __stdio_exit(void)
+{
+	FILE *f;
+	for (f=*__ofl_lock(); f; f=f->next) close_file(f);
+	close_file(__stdin_used);
+	close_file(__stdout_used);
+}
+
+weak_alias(__stdio_exit, __stdio_exit_needed);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_read.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_read.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_read.c	(revision 398)
@@ -0,0 +1,23 @@
+#include "stdio_impl.h"
+#include <sys/uio.h>
+
+size_t __stdio_read(FILE *f, unsigned char *buf, size_t len)
+{
+	struct iovec iov[2] = {
+		{ .iov_base = buf, .iov_len = len - !!f->buf_size },
+		{ .iov_base = f->buf, .iov_len = f->buf_size }
+	};
+	ssize_t cnt;
+
+	cnt = syscall(SYS_readv, f->fd, iov, 2);
+	if (cnt <= 0) {
+		f->flags |= F_EOF ^ ((F_ERR^F_EOF) & cnt);
+		return cnt;
+	}
+	if (cnt <= iov[0].iov_len) return cnt;
+	cnt -= iov[0].iov_len;
+	f->rpos = f->buf;
+	f->rend = f->buf + cnt;
+	if (f->buf_size) buf[len-1] = *f->rpos++;
+	return len;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_seek.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_seek.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_seek.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+
+off_t __stdio_seek(FILE *f, off_t off, int whence)
+{
+	off_t ret;
+#ifdef SYS__llseek
+	if (syscall(SYS__llseek, f->fd, off>>32, off, &ret, whence)<0)
+		ret = -1;
+#else
+	ret = syscall(SYS_lseek, f->fd, off, whence);
+#endif
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_write.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_write.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdio_write.c	(revision 398)
@@ -0,0 +1,35 @@
+#include "stdio_impl.h"
+#include <sys/uio.h>
+
+size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct iovec iovs[2] = {
+		{ .iov_base = f->wbase, .iov_len = f->wpos-f->wbase },
+		{ .iov_base = (void *)buf, .iov_len = len }
+	};
+	struct iovec *iov = iovs;
+	size_t rem = iov[0].iov_len + iov[1].iov_len;
+	int iovcnt = 2;
+	ssize_t cnt;
+	for (;;) {
+		cnt = syscall(SYS_writev, f->fd, iov, iovcnt);
+		if (cnt == rem) {
+			f->wend = f->buf + f->buf_size;
+			f->wpos = f->wbase = f->buf;
+			return len;
+		}
+		if (cnt < 0) {
+			f->wpos = f->wbase = f->wend = 0;
+			f->flags |= F_ERR;
+			return iovcnt == 2 ? 0 : len-iov[0].iov_len;
+		}
+		rem -= cnt;
+		if (cnt > iov[0].iov_len) {
+			cnt -= iov[0].iov_len;
+			iov++; iovcnt--;
+		}
+		iov[0].iov_base = (char *)iov[0].iov_base + cnt;
+		iov[0].iov_len -= cnt;
+	}
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdout_write.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdout_write.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__stdout_write.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+#include <sys/ioctl.h>
+
+size_t __stdout_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct winsize wsz;
+	f->write = __stdio_write;
+	if (!(f->flags & F_SVB) && __syscall(SYS_ioctl, f->fd, TIOCGWINSZ, &wsz))
+		f->lbf = -1;
+	return __stdio_write(f, buf, len);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__string_read.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__string_read.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__string_read.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+#include <string.h>
+
+size_t __string_read(FILE *f, unsigned char *buf, size_t len)
+{
+	char *src = f->cookie;
+	size_t k = len+256;
+	char *end = memchr(src, 0, k);
+	if (end) k = end-src;
+	if (k < len) len = k;
+	memcpy(buf, src, len);
+	f->rpos = (void *)(src+len);
+	f->rend = (void *)(src+k);
+	f->cookie = src+k;
+	return len;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__toread.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__toread.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__toread.c	(revision 398)
@@ -0,0 +1,21 @@
+#include <stdio_impl.h>
+
+int __toread(FILE *f)
+{
+	f->mode |= f->mode-1;
+	if (f->wpos > f->wbase) f->write(f, 0, 0);
+	f->wpos = f->wbase = f->wend = 0;
+	if (f->flags & F_NORD) {
+		f->flags |= F_ERR;
+		return EOF;
+	}
+	f->rpos = f->rend = f->buf + f->buf_size;
+	return (f->flags & F_EOF) ? EOF : 0;
+}
+
+void __stdio_exit_needed(void);
+
+void __toread_needs_stdio_exit()
+{
+	__stdio_exit_needed();
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__towrite.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__towrite.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__towrite.c	(revision 398)
@@ -0,0 +1,25 @@
+#include "stdio_impl.h"
+
+int __towrite(FILE *f)
+{
+	f->mode |= f->mode-1;
+	if (f->flags & (F_NOWR)) {
+		f->flags |= F_ERR;
+		return EOF;
+	}
+	/* Clear read buffer (easier than summoning nasal demons) */
+	f->rpos = f->rend = 0;
+
+	/* Activate write through the buffer. */
+	f->wpos = f->wbase = f->buf;
+	f->wend = f->buf + f->buf_size;
+
+	return 0;
+}
+
+void __stdio_exit_needed(void);
+
+void __towrite_needs_stdio_exit()
+{
+	__stdio_exit_needed();
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__uflow.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__uflow.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/__uflow.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+
+/* This function assumes it will never be called if there is already
+ * data buffered for reading. */
+
+int __uflow(FILE *f)
+{
+	unsigned char c;
+	if (!__toread(f) && f->read(f, &c, 1)==1) return c;
+	return EOF;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/asprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/asprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/asprintf.c	(revision 398)
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdarg.h>
+
+int asprintf(char **s, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vasprintf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/clearerr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/clearerr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/clearerr.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+void clearerr(FILE *f)
+{
+	FLOCK(f);
+	f->flags &= ~(F_EOF|F_ERR);
+	FUNLOCK(f);
+}
+
+weak_alias(clearerr, clearerr_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/dprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/dprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/dprintf.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int dprintf(int fd, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vdprintf(fd, fmt, ap);
+	va_end(ap);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ext.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ext.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ext.c	(revision 398)
@@ -0,0 +1,57 @@
+#define _GNU_SOURCE
+#include "stdio_impl.h"
+#include <stdio_ext.h>
+
+void _flushlbf(void)
+{
+	fflush(0);
+}
+
+int __fsetlocking(FILE *f, int type)
+{
+	return 0;
+}
+
+int __fwriting(FILE *f)
+{
+	return (f->flags & F_NORD) || f->wend;
+}
+
+int __freading(FILE *f)
+{
+	return (f->flags & F_NOWR) || f->rend;
+}
+
+int __freadable(FILE *f)
+{
+	return !(f->flags & F_NORD);
+}
+
+int __fwritable(FILE *f)
+{
+	return !(f->flags & F_NOWR);
+}
+
+int __flbf(FILE *f)
+{
+	return f->lbf >= 0;
+}
+
+size_t __fbufsize(FILE *f)
+{
+	return f->buf_size;
+}
+
+size_t __fpending(FILE *f)
+{
+	return f->wend ? f->wpos - f->wbase : 0;
+}
+
+int __fpurge(FILE *f)
+{
+	f->wpos = f->wbase = f->wend = 0;
+	f->rpos = f->rend = 0;
+	return 0;
+}
+
+weak_alias(__fpurge, fpurge);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ext2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ext2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ext2.c	(revision 398)
@@ -0,0 +1,24 @@
+#include "stdio_impl.h"
+
+size_t __freadahead(FILE *f)
+{
+	return f->rend - f->rpos;
+}
+
+const char *__freadptr(FILE *f, size_t *sizep)
+{
+	size_t size = f->rend - f->rpos;
+	if (!size) return 0;
+	*sizep = size;
+	return (const char *)f->rpos;
+}
+
+void __freadptrinc(FILE *f, size_t inc)
+{
+	f->rpos += inc;
+}
+
+void __fseterr(FILE *f)
+{
+	f->flags |= F_ERR;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fclose.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fclose.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fclose.c	(revision 398)
@@ -0,0 +1,36 @@
+#include "stdio_impl.h"
+#include "libc.h"
+
+#ifndef __c2__
+static void dummy(FILE *f) { }
+weak_alias(dummy, __unlist_locked_file);
+#else
+extern void __unlist_locked_file(FILE *f);
+#endif
+
+int fclose(FILE *f)
+{
+	int r;
+	int perm;
+	
+	FLOCK(f);
+
+	__unlist_locked_file(f);
+
+	if (!(perm = f->flags & F_PERM)) {
+		FILE **head = __ofl_lock();
+		if (f->prev) f->prev->next = f->next;
+		if (f->next) f->next->prev = f->prev;
+		if (*head == f) *head = f->next;
+		__ofl_unlock();
+	}
+
+	r = fflush(f);
+	r |= f->close(f);
+
+	if (f->getln_buf) free(f->getln_buf);
+	if (!perm) free(f);
+	else FUNLOCK(f);
+
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/feof.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/feof.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/feof.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "stdio_impl.h"
+
+#undef feof
+
+int feof(FILE *f)
+{
+	FLOCK(f);
+	int ret = !!(f->flags & F_EOF);
+	FUNLOCK(f);
+	return ret;
+}
+
+weak_alias(feof, feof_unlocked);
+weak_alias(feof, _IO_feof_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ferror.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ferror.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ferror.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "stdio_impl.h"
+
+#undef ferror
+
+int ferror(FILE *f)
+{
+	FLOCK(f);
+	int ret = !!(f->flags & F_ERR);
+	FUNLOCK(f);
+	return ret;
+}
+
+weak_alias(ferror, ferror_unlocked);
+weak_alias(ferror, _IO_ferror_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fflush.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fflush.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fflush.c	(revision 398)
@@ -0,0 +1,44 @@
+#include "stdio_impl.h"
+
+/* stdout.c will override this if linked */
+static FILE *volatile dummy = 0;
+weak_alias(dummy, __stdout_used);
+
+int fflush(FILE *f)
+{
+	if (!f) {
+		int r = __stdout_used ? fflush(__stdout_used) : 0;
+
+		for (f=*__ofl_lock(); f; f=f->next) {
+			FLOCK(f);
+			if (f->wpos > f->wbase) r |= fflush(f);
+			FUNLOCK(f);
+		}
+		__ofl_unlock();
+
+		return r;
+	}
+
+	FLOCK(f);
+
+	/* If writing, flush output */
+	if (f->wpos > f->wbase) {
+		f->write(f, 0, 0);
+		if (!f->wpos) {
+			FUNLOCK(f);
+			return EOF;
+		}
+	}
+
+	/* If reading, sync position, per POSIX */
+	if (f->rpos < f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);
+
+	/* Clear read and write modes */
+	f->wpos = f->wbase = f->wend = 0;
+	f->rpos = f->rend = 0;
+
+	FUNLOCK(f);
+	return 0;
+}
+
+weak_alias(fflush, fflush_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetc.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+
+int fgetc(FILE *f)
+{
+	int c;
+	if (f->lock < 0 || !__lockfile(f))
+		return getc_unlocked(f);
+	c = getc_unlocked(f);
+	__unlockfile(f);
+	return c;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetln.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetln.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetln.c	(revision 398)
@@ -0,0 +1,21 @@
+#define _GNU_SOURCE
+#include "stdio_impl.h"
+#include <string.h>
+
+char *fgetln(FILE *f, size_t *plen)
+{
+	char *ret = 0, *z;
+	ssize_t l;
+	FLOCK(f);
+	ungetc(getc_unlocked(f), f);
+	if ((z=memchr(f->rpos, '\n', f->rend - f->rpos))) {
+		ret = (char *)f->rpos;
+		*plen = ++z - ret;
+		f->rpos = (void *)z;
+	} else if ((l = getline(&f->getln_buf, (size_t[]){0}, f)) > 0) {
+		*plen = l;
+		ret = f->getln_buf;
+	}
+	FUNLOCK(f);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetpos.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetpos.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetpos.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+
+int fgetpos(FILE *restrict f, fpos_t *restrict pos)
+{
+	off_t off = __ftello(f);
+	if (off < 0) return -1;
+	*(off_t *)pos = off;
+	return 0;
+}
+
+LFS64(fgetpos);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgets.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgets.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgets.c	(revision 398)
@@ -0,0 +1,46 @@
+#include "stdio_impl.h"
+#include <string.h>
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+char *fgets(char *restrict s, int n, FILE *restrict f)
+{
+	char *p = s;
+	unsigned char *z;
+	size_t k;
+	int c;
+
+	FLOCK(f);
+
+	if (n--<=1) {
+		f->mode |= f->mode-1;
+		FUNLOCK(f);
+		if (n) return 0;
+		*s = 0;
+		return s;
+	}
+
+	while (n) {
+		z = memchr(f->rpos, '\n', f->rend - f->rpos);
+		k = z ? z - f->rpos + 1 : f->rend - f->rpos;
+		k = MIN(k, n);
+		memcpy(p, f->rpos, k);
+		f->rpos += k;
+		p += k;
+		n -= k;
+		if (z || !n) break;
+		if ((c = getc_unlocked(f)) < 0) {
+			if (p==s || !feof(f)) s = 0;
+			break;
+		}
+		n--;
+		if ((*p++ = c) == '\n') break;
+	}
+	if (s) *p = 0;
+
+	FUNLOCK(f);
+
+	return s;
+}
+
+weak_alias(fgets, fgets_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetwc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetwc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetwc.c	(revision 398)
@@ -0,0 +1,61 @@
+#include "stdio_impl.h"
+#include "locale_impl.h"
+#include <wchar.h>
+#include <errno.h>
+
+static wint_t __fgetwc_unlocked_internal(FILE *f)
+{
+	mbstate_t st = { 0 };
+	wchar_t wc;
+	int c;
+	unsigned char b;
+	size_t l;
+
+	/* Convert character from buffer if possible */
+	if (f->rpos < f->rend) {
+		l = mbrtowc(&wc, (void *)f->rpos, f->rend - f->rpos, &st);
+		if (l+2 >= 2) {
+			f->rpos += l + !l; /* l==0 means 1 byte, null */
+			return wc;
+		}
+		if (l == -1) {
+			f->rpos++;
+			return WEOF;
+		}
+	} else l = -2;
+
+	/* Convert character byte-by-byte */
+	while (l == -2) {
+		b = c = getc_unlocked(f);
+		if (c < 0) {
+			if (!mbsinit(&st)) errno = EILSEQ;
+			return WEOF;
+		}
+		l = mbrtowc(&wc, (void *)&b, 1, &st);
+		if (l == -1) return WEOF;
+	}
+
+	return wc;
+}
+
+wint_t __fgetwc_unlocked(FILE *f)
+{
+	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
+	if (f->mode <= 0) fwide(f, 1);
+	*ploc = f->locale;
+	wchar_t wc = __fgetwc_unlocked_internal(f);
+	*ploc = loc;
+	return wc;
+}
+
+wint_t fgetwc(FILE *f)
+{
+	wint_t c;
+	FLOCK(f);
+	c = __fgetwc_unlocked(f);
+	FUNLOCK(f);
+	return c;
+}
+
+weak_alias(__fgetwc_unlocked, fgetwc_unlocked);
+weak_alias(__fgetwc_unlocked, getwc_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetws.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetws.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fgetws.c	(revision 398)
@@ -0,0 +1,28 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+
+wint_t __fgetwc_unlocked(FILE *);
+
+wchar_t *fgetws(wchar_t *restrict s, int n, FILE *restrict f)
+{
+	wchar_t *p = s;
+
+	if (!n--) return s;
+
+	FLOCK(f);
+
+	for (; n; n--) {
+		wint_t c = __fgetwc_unlocked(f);
+		if (c == WEOF) break;
+		*p++ = c;
+		if (c == '\n') break;
+	}
+	*p = 0;
+	if (ferror(f)) p = s;
+
+	FUNLOCK(f);
+
+	return (p == s) ? NULL : s;
+}
+
+weak_alias(fgetws, fgetws_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fileno.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fileno.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fileno.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+
+int fileno(FILE *f)
+{
+	/* f->fd never changes, but the lock must be obtained and released
+	 * anyway since this function cannot return while another thread
+	 * holds the lock. */
+	FLOCK(f);
+	FUNLOCK(f);
+	return f->fd;
+}
+
+weak_alias(fileno, fileno_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/flockfile.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/flockfile.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/flockfile.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+#include "pthread_impl.h"
+
+void flockfile(FILE *f)
+{
+	while (ftrylockfile(f)) {
+		int owner = f->lock;
+		if (owner) __wait(&f->lock, &f->waiters, owner, 1);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fmemopen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fmemopen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fmemopen.c	(revision 398)
@@ -0,0 +1,114 @@
+#include "stdio_impl.h"
+#include <errno.h>
+#include <string.h>
+#include <inttypes.h>
+
+struct cookie {
+	size_t pos, len, size;
+	unsigned char *buf;
+	int mode;
+};
+
+static off_t mseek(FILE *f, off_t off, int whence)
+{
+	ssize_t base;
+	struct cookie *c = f->cookie;
+	if (whence>2U) {
+fail:
+		errno = EINVAL;
+		return -1;
+	}
+	base = (size_t [3]){0, c->pos, c->len}[whence];
+	if (off < -base || off > (ssize_t)c->size-base) goto fail;
+	return c->pos = base+off;
+}
+
+static size_t mread(FILE *f, unsigned char *buf, size_t len)
+{
+	struct cookie *c = f->cookie;
+	size_t rem = c->len - c->pos;
+	if (c->pos > c->len) rem = 0;
+	if (len > rem) {
+		len = rem;
+		f->flags |= F_EOF;
+	}
+	memcpy(buf, c->buf+c->pos, len);
+	c->pos += len;
+	rem -= len;
+	if (rem > f->buf_size) rem = f->buf_size;
+	f->rpos = f->buf;
+	f->rend = f->buf + rem;
+	memcpy(f->rpos, c->buf+c->pos, rem);
+	c->pos += rem;
+	return len;
+}
+
+static size_t mwrite(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct cookie *c = f->cookie;
+	size_t rem;
+	size_t len2 = f->wpos - f->wbase;
+	if (len2) {
+		f->wpos = f->wbase;
+		if (mwrite(f, f->wpos, len2) < len2) return 0;
+	}
+	if (c->mode == 'a') c->pos = c->len;
+	rem = c->size - c->pos;
+	if (len > rem) len = rem;
+	memcpy(c->buf+c->pos, buf, len);
+	c->pos += len;
+	if (c->pos > c->len) {
+		c->len = c->pos;
+		if (c->len < c->size) c->buf[c->len] = 0;
+		else if ((f->flags&F_NORD) && c->size) c->buf[c->size-1] = 0;
+	}
+	return len;
+}
+
+static int mclose(FILE *m)
+{
+	return 0;
+}
+
+FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode)
+{
+	FILE *f;
+	struct cookie *c;
+	int plus = !!strchr(mode, '+');
+	
+	if (!size || !strchr("rwa", *mode)) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	if (!buf && size > SIZE_MAX-sizeof(FILE)-BUFSIZ-UNGET) {
+		errno = ENOMEM;
+		return 0;
+	}
+
+	f = calloc(sizeof *f + sizeof *c + UNGET + BUFSIZ + (buf?0:size), 1);
+	if (!f) return 0;
+	f->cookie = c = (void *)(f+1);
+	f->fd = -1;
+	f->lbf = EOF;
+	f->buf = (unsigned char *)(c+1) + UNGET;
+	f->buf_size = BUFSIZ;
+	if (!buf) buf = f->buf + BUFSIZ;
+
+	c->buf = buf;
+	c->size = size;
+	c->mode = *mode;
+	
+	if (!plus) f->flags = (*mode == 'r') ? F_NOWR : F_NORD;
+	if (*mode == 'r') c->len = size;
+	else if (*mode == 'a') c->len = c->pos = strnlen(buf, size);
+
+	f->read = mread;
+	f->write = mwrite;
+	f->seek = mseek;
+	f->close = mclose;
+
+	if (!libc.threaded) f->lock = -1;
+
+	return __ofl_add(f);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fopen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fopen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fopen.c	(revision 398)
@@ -0,0 +1,33 @@
+#include "stdio_impl.h"
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+FILE *fopen(const char *restrict filename, const char *restrict mode)
+{
+	FILE *f;
+	int fd;
+	int flags;
+
+	/* Check for valid initial mode character */
+	if (!strchr("rwa", *mode)) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	/* Compute the flags to pass to open() */
+	flags = __fmodeflags(mode);
+
+	fd = sys_open(filename, flags, 0666);
+	if (fd < 0) return 0;
+	if (flags & O_CLOEXEC)
+		__syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
+
+	f = __fdopen(fd, mode);
+	if (f) return f;
+
+	__syscall(SYS_close, fd);
+	return 0;
+}
+
+LFS64(fopen);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fprintf.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int fprintf(FILE *restrict f, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfprintf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputc.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+int fputc(int c, FILE *f)
+{
+	if (f->lock < 0 || !__lockfile(f))
+		return putc_unlocked(c, f);
+	c = putc_unlocked(c, f);
+	__unlockfile(f);
+	return c;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputs.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+#include <string.h>
+
+int fputs(const char *restrict s, FILE *restrict f)
+{
+	size_t l = strlen(s);
+	return (fwrite(s, 1, l, f)==l) - 1;
+}
+
+weak_alias(fputs, fputs_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputwc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputwc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputwc.c	(revision 398)
@@ -0,0 +1,40 @@
+#include "stdio_impl.h"
+#include "locale_impl.h"
+#include <wchar.h>
+#include <limits.h>
+#include <ctype.h>
+
+wint_t __fputwc_unlocked(wchar_t c, FILE *f)
+{
+	char mbc[MB_LEN_MAX];
+	int l;
+	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
+
+	if (f->mode <= 0) fwide(f, 1);
+	*ploc = f->locale;
+
+	if (isascii(c)) {
+		c = putc_unlocked(c, f);
+	} else if (f->wpos + MB_LEN_MAX < f->wend) {
+		l = wctomb((void *)f->wpos, c);
+		if (l < 0) c = WEOF;
+		else f->wpos += l;
+	} else {
+		l = wctomb(mbc, c);
+		if (l < 0 || __fwritex((void *)mbc, l, f) < l) c = WEOF;
+	}
+	if (c==WEOF) f->flags |= F_ERR;
+	*ploc = loc;
+	return c;
+}
+
+wint_t fputwc(wchar_t c, FILE *f)
+{
+	FLOCK(f);
+	c = __fputwc_unlocked(c, f);
+	FUNLOCK(f);
+	return c;
+}
+
+weak_alias(__fputwc_unlocked, fputwc_unlocked);
+weak_alias(__fputwc_unlocked, putwc_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputws.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputws.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fputws.c	(revision 398)
@@ -0,0 +1,29 @@
+#include "stdio_impl.h"
+#include "locale_impl.h"
+#include <wchar.h>
+
+int fputws(const wchar_t *restrict ws, FILE *restrict f)
+{
+	unsigned char buf[BUFSIZ];
+	size_t l=0;
+	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
+
+	FLOCK(f);
+
+	fwide(f, 1);
+	*ploc = f->locale;
+
+	while (ws && (l = wcsrtombs((void *)buf, (void*)&ws, sizeof buf, 0))+1 > 1)
+		if (__fwritex(buf, l, f) < l) {
+			FUNLOCK(f);
+			*ploc = loc;
+			return -1;
+		}
+
+	FUNLOCK(f);
+
+	*ploc = loc;
+	return l; /* 0 or -1 */
+}
+
+weak_alias(fputws, fputws_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fread.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fread.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fread.c	(revision 398)
@@ -0,0 +1,38 @@
+#include "stdio_impl.h"
+#include <string.h>
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+size_t fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f)
+{
+	unsigned char *dest = destv;
+	size_t len = size*nmemb, l = len, k;
+	if (!size) nmemb = 0;
+
+	FLOCK(f);
+
+	f->mode |= f->mode-1;
+
+	if (f->rend - f->rpos > 0) {
+		/* First exhaust the buffer. */
+		k = MIN(f->rend - f->rpos, l);
+		memcpy(dest, f->rpos, k);
+		f->rpos += k;
+		dest += k;
+		l -= k;
+	}
+	
+	/* Read the remainder directly */
+	for (; l; l-=k, dest+=k) {
+		k = __toread(f) ? 0 : f->read(f, dest, l);
+		if (k+1<=1) {
+			FUNLOCK(f);
+			return (len-l)/size;
+		}
+	}
+
+	FUNLOCK(f);
+	return nmemb;
+}
+
+weak_alias(fread, fread_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/freopen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/freopen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/freopen.c	(revision 398)
@@ -0,0 +1,54 @@
+#include "stdio_impl.h"
+#include <fcntl.h>
+
+/* The basic idea of this implementation is to open a new FILE,
+ * hack the necessary parts of the new FILE into the old one, then
+ * close the new FILE. */
+
+/* Locking IS necessary because another thread may provably hold the
+ * lock, via flockfile or otherwise, when freopen is called, and in that
+ * case, freopen cannot act until the lock is released. */
+
+int __dup3(int, int, int);
+
+FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict f)
+{
+	int fl = __fmodeflags(mode);
+	FILE *f2;
+
+	FLOCK(f);
+
+	fflush(f);
+
+	if (!filename) {
+		if (fl&O_CLOEXEC)
+			__syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);
+		fl &= ~(O_CREAT|O_EXCL|O_CLOEXEC);
+		if (syscall(SYS_fcntl, f->fd, F_SETFL, fl) < 0)
+			goto fail;
+	} else {
+		f2 = fopen(filename, mode);
+		if (!f2) goto fail;
+		if (f2->fd == f->fd) f2->fd = -1; /* avoid closing in fclose */
+		else if (__dup3(f2->fd, f->fd, fl&O_CLOEXEC)<0) goto fail2;
+
+		f->flags = (f->flags & F_PERM) | f2->flags;
+		f->read = f2->read;
+		f->write = f2->write;
+		f->seek = f2->seek;
+		f->close = f2->close;
+
+		fclose(f2);
+	}
+
+	FUNLOCK(f);
+	return f;
+
+fail2:
+	fclose(f2);
+fail:
+	fclose(f);
+	return NULL;
+}
+
+LFS64(freopen);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fscanf.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include "libc.h"
+
+int fscanf(FILE *restrict f, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfscanf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(fscanf, __isoc99_fscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fseek.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fseek.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fseek.c	(revision 398)
@@ -0,0 +1,43 @@
+#include "stdio_impl.h"
+
+int __fseeko_unlocked(FILE *f, off_t off, int whence)
+{
+	/* Adjust relative offset for unread data in buffer, if any. */
+	if (whence == SEEK_CUR) off -= f->rend - f->rpos;
+
+	/* Flush write buffer, and report error on failure. */
+	if (f->wpos > f->wbase) {
+		f->write(f, 0, 0);
+		if (!f->wpos) return -1;
+	}
+
+	/* Leave writing mode */
+	f->wpos = f->wbase = f->wend = 0;
+
+	/* Perform the underlying seek. */
+	if (f->seek(f, off, whence) < 0) return -1;
+
+	/* If seek succeeded, file is seekable and we discard read buffer. */
+	f->rpos = f->rend = 0;
+	f->flags &= ~F_EOF;
+	
+	return 0;
+}
+
+int __fseeko(FILE *f, off_t off, int whence)
+{
+	int result;
+	FLOCK(f);
+	result = __fseeko_unlocked(f, off, whence);
+	FUNLOCK(f);
+	return result;
+}
+
+int fseek(FILE *f, long off, int whence)
+{
+	return __fseeko(f, off, whence);
+}
+
+weak_alias(__fseeko, fseeko);
+
+LFS64(fseeko);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fsetpos.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fsetpos.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fsetpos.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "stdio_impl.h"
+
+int fsetpos(FILE *f, const fpos_t *pos)
+{
+	return __fseeko(f, *(const off_t *)pos, SEEK_SET);
+}
+
+LFS64(fsetpos);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ftell.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ftell.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ftell.c	(revision 398)
@@ -0,0 +1,37 @@
+#include "stdio_impl.h"
+#include <limits.h>
+#include <errno.h>
+
+off_t __ftello_unlocked(FILE *f)
+{
+	off_t pos = f->seek(f, 0,
+		(f->flags & F_APP) && f->wpos > f->wbase
+		? SEEK_END : SEEK_CUR);
+	if (pos < 0) return pos;
+
+	/* Adjust for data in buffer. */
+	return pos - (f->rend - f->rpos) + (f->wpos - f->wbase);
+}
+
+off_t __ftello(FILE *f)
+{
+	off_t pos;
+	FLOCK(f);
+	pos = __ftello_unlocked(f);
+	FUNLOCK(f);
+	return pos;
+}
+
+long ftell(FILE *f)
+{
+	off_t pos = __ftello(f);
+	if (pos > LONG_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+	return pos;
+}
+
+weak_alias(__ftello, ftello);
+
+LFS64(ftello);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ftrylockfile.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ftrylockfile.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ftrylockfile.c	(revision 398)
@@ -0,0 +1,40 @@
+#include "stdio_impl.h"
+#include "pthread_impl.h"
+#include <limits.h>
+
+void __do_orphaned_stdio_locks()
+{
+	FILE *f;
+	for (f=__pthread_self()->stdio_locks; f; f=f->next_locked)
+		a_store(&f->lock, 0x40000000);
+}
+
+void __unlist_locked_file(FILE *f)
+{
+	if (f->lockcount) {
+		if (f->next_locked) f->next_locked->prev_locked = f->prev_locked;
+		if (f->prev_locked) f->prev_locked->next_locked = f->next_locked;
+		else __pthread_self()->stdio_locks = f->next_locked;
+	}
+}
+
+int ftrylockfile(FILE *f)
+{
+	pthread_t self = __pthread_self();
+	int tid = self->tid;
+	if (f->lock == tid) {
+		if (f->lockcount == LONG_MAX)
+			return -1;
+		f->lockcount++;
+		return 0;
+	}
+	if (f->lock < 0) f->lock = 0;
+	if (f->lock || a_cas(&f->lock, 0, tid))
+		return -1;
+	f->lockcount = 1;
+	f->prev_locked = 0;
+	f->next_locked = self->stdio_locks;
+	if (f->next_locked) f->next_locked->prev_locked = f;
+	self->stdio_locks = f;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/funlockfile.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/funlockfile.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/funlockfile.c	(revision 398)
@@ -0,0 +1,15 @@
+#include "stdio_impl.h"
+#include "pthread_impl.h"
+
+void __unlist_locked_file(FILE *);
+
+void funlockfile(FILE *f)
+{
+	if (f->lockcount == 1) {
+		__unlist_locked_file(f);
+		f->lockcount = 0;
+		__unlockfile(f);
+	} else {
+		f->lockcount--;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwide.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwide.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwide.c	(revision 398)
@@ -0,0 +1,15 @@
+#include "stdio_impl.h"
+#include "locale_impl.h"
+
+int fwide(FILE *f, int mode)
+{
+	FLOCK(f);
+	if (mode) {
+		if (!f->locale) f->locale = MB_CUR_MAX==1
+			? C_LOCALE : UTF8_LOCALE;
+		if (!f->mode) f->mode = mode>0 ? 1 : -1;
+	}
+	mode = f->mode;
+	FUNLOCK(f);
+	return mode;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwprintf.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int fwprintf(FILE *restrict f, const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfwprintf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwrite.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwrite.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwrite.c	(revision 398)
@@ -0,0 +1,38 @@
+#include "stdio_impl.h"
+#include <string.h>
+
+size_t __fwritex(const unsigned char *restrict s, size_t l, FILE *restrict f)
+{
+	size_t i=0;
+
+	if (!f->wend && __towrite(f)) return 0;
+
+	if (l > f->wend - f->wpos) return f->write(f, s, l);
+
+	if (f->lbf >= 0) {
+		/* Match /^(.*\n|)/ */
+		for (i=l; i && s[i-1] != '\n'; i--);
+		if (i) {
+			size_t n = f->write(f, s, i);
+			if (n < i) return n;
+			s += i;
+			l -= i;
+		}
+	}
+
+	memcpy(f->wpos, s, l);
+	f->wpos += l;
+	return l+i;
+}
+
+size_t fwrite(const void *restrict src, size_t size, size_t nmemb, FILE *restrict f)
+{
+	size_t k, l = size*nmemb;
+	if (!size) nmemb = 0;
+	FLOCK(f);
+	k = __fwritex(src, l, f);
+	FUNLOCK(f);
+	return k==l ? nmemb : k/size;
+}
+
+weak_alias(fwrite, fwrite_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/fwscanf.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+#include "libc.h"
+
+int fwscanf(FILE *restrict f, const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfwscanf(f, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(fwscanf,__isoc99_fwscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getc.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+
+int getc(FILE *f)
+{
+	int c;
+	if (f->lock < 0 || !__lockfile(f))
+		return getc_unlocked(f);
+	c = getc_unlocked(f);
+	__unlockfile(f);
+	return c;
+}
+
+weak_alias(getc, _IO_getc);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getc_unlocked.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getc_unlocked.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getc_unlocked.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+
+int (getc_unlocked)(FILE *f)
+{
+	return getc_unlocked(f);
+}
+
+weak_alias (getc_unlocked, fgetc_unlocked);
+weak_alias (getc_unlocked, _IO_getc_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getchar.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getchar.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getchar.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int getchar(void)
+{
+	return fgetc(stdin);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getchar_unlocked.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getchar_unlocked.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getchar_unlocked.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int getchar_unlocked(void)
+{
+	return getc_unlocked(stdin);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getdelim.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getdelim.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getdelim.c	(revision 398)
@@ -0,0 +1,68 @@
+#include "stdio_impl.h"
+#include <string.h>
+#include <inttypes.h>
+#include <errno.h>
+
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+ssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restrict f)
+{
+	char *tmp;
+	unsigned char *z;
+	size_t k;
+	size_t i=0;
+	int c;
+
+	FLOCK(f);
+
+	if (!n || !s) {
+		f->flags |= F_ERR;
+		FUNLOCK(f);
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (!*s) *n=0;
+
+	for (;;) {
+		z = memchr(f->rpos, delim, f->rend - f->rpos);
+		k = z ? z - f->rpos + 1 : f->rend - f->rpos;
+		if (i+k+1 >= *n) {
+			if (k >= SIZE_MAX/2-i) goto oom;
+			size_t m = i+k+2;
+			if (!z && m < SIZE_MAX/4) m += m/2;
+			tmp = realloc(*s, m);
+			if (!tmp) {
+				m = i+k+2;
+				tmp = realloc(*s, m);
+				if (!tmp) goto oom;
+			}
+			*s = tmp;
+			*n = m;
+		}
+		memcpy(*s+i, f->rpos, k);
+		f->rpos += k;
+		i += k;
+		if (z) break;
+		if ((c = getc_unlocked(f)) == EOF) {
+			if (!i || !feof(f)) {
+				FUNLOCK(f);
+				return -1;
+			}
+			break;
+		}
+		if (((*s)[i++] = c) == delim) break;
+	}
+	(*s)[i] = 0;
+
+	FUNLOCK(f);
+
+	return i;
+oom:
+	f->flags |= F_ERR;
+	FUNLOCK(f);
+	errno = ENOMEM;
+	return -1;
+}
+
+weak_alias(getdelim, __getdelim);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getline.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getline.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getline.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+ssize_t getline(char **restrict s, size_t *restrict n, FILE *restrict f)
+{
+	return getdelim(s, n, '\n', f);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/gets.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/gets.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/gets.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+#include <limits.h>
+#include <string.h>
+
+char *gets(char *s)
+{
+	char *ret = fgets(s, INT_MAX, stdin);
+	if (ret && s[strlen(s)-1] == '\n') s[strlen(s)-1] = 0;
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getw.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getw.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getw.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+
+int getw(FILE *f)
+{
+	int x;
+	return fread(&x, sizeof x, 1, f) ? x : EOF;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getwc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getwc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getwc.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+
+wint_t getwc(FILE *f)
+{
+	return fgetwc(f);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getwchar.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getwchar.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/getwchar.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+
+wint_t getwchar(void)
+{
+	return fgetwc(stdin);
+}
+
+weak_alias(getwchar, getwchar_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ofl.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ofl.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ofl.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+#include "libc.h"
+
+static FILE *ofl_head;
+static volatile int ofl_lock[2];
+
+FILE **__ofl_lock()
+{
+	LOCK(ofl_lock);
+	return &ofl_head;
+}
+
+void __ofl_unlock()
+{
+	UNLOCK(ofl_lock);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ofl_add.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ofl_add.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ofl_add.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "stdio_impl.h"
+
+FILE *__ofl_add(FILE *f)
+{
+	FILE **head = __ofl_lock();
+	f->next = *head;
+	if (*head) (*head)->prev = f;
+	*head = f;
+	__ofl_unlock();
+	return f;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/open_memstream.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/open_memstream.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/open_memstream.c	(revision 398)
@@ -0,0 +1,90 @@
+#include "stdio_impl.h"
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+
+struct cookie {
+	char **bufp;
+	size_t *sizep;
+	size_t pos;
+	char *buf;
+	size_t len;
+	size_t space;
+};
+
+static off_t ms_seek(FILE *f, off_t off, int whence)
+{
+	ssize_t base;
+	struct cookie *c = f->cookie;
+	if (whence>2U) {
+fail:
+		errno = EINVAL;
+		return -1;
+	}
+	base = (size_t [3]){0, c->pos, c->len}[whence];
+	if (off < -base || off > SSIZE_MAX-base) goto fail;
+	return c->pos = base+off;
+}
+
+static size_t ms_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct cookie *c = f->cookie;
+	size_t len2 = f->wpos - f->wbase;
+	char *newbuf;
+	if (len2) {
+		f->wpos = f->wbase;
+		if (ms_write(f, f->wbase, len2) < len2) return 0;
+	}
+	if (len + c->pos >= c->space) {
+		len2 = 2*c->space+1 | c->pos+len+1;
+		newbuf = realloc(c->buf, len2);
+		if (!newbuf) return 0;
+		*c->bufp = c->buf = newbuf;
+		memset(c->buf + c->space, 0, len2 - c->space);
+		c->space = len2;
+	}
+	memcpy(c->buf+c->pos, buf, len);
+	c->pos += len;
+	if (c->pos >= c->len) c->len = c->pos;
+	*c->sizep = c->pos;
+	return len;
+}
+
+static int ms_close(FILE *f)
+{
+	return 0;
+}
+
+FILE *open_memstream(char **bufp, size_t *sizep)
+{
+	FILE *f;
+	struct cookie *c;
+	char *buf;
+
+	if (!(f=malloc(sizeof *f + sizeof *c + BUFSIZ))) return 0;
+	if (!(buf=malloc(sizeof *buf))) {
+		free(f);
+		return 0;
+	}
+	memset(f, 0, sizeof *f + sizeof *c);
+	f->cookie = c = (void *)(f+1);
+
+	c->bufp = bufp;
+	c->sizep = sizep;
+	c->pos = c->len = c->space = *sizep = 0;
+	c->buf = *bufp = buf;
+	*buf = 0;
+
+	f->flags = F_NORD;
+	f->fd = -1;
+	f->buf = (void *)(c+1);
+	f->buf_size = BUFSIZ;
+	f->lbf = EOF;
+	f->write = ms_write;
+	f->seek = ms_seek;
+	f->close = ms_close;
+
+	if (!libc.threaded) f->lock = -1;
+
+	return __ofl_add(f);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/open_wmemstream.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/open_wmemstream.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/open_wmemstream.c	(revision 398)
@@ -0,0 +1,92 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+
+struct cookie {
+	wchar_t **bufp;
+	size_t *sizep;
+	size_t pos;
+	wchar_t *buf;
+	size_t len;
+	size_t space;
+	mbstate_t mbs;
+};
+
+static off_t wms_seek(FILE *f, off_t off, int whence)
+{
+	ssize_t base;
+	struct cookie *c = f->cookie;
+	if (whence>2U) {
+fail:
+		errno = EINVAL;
+		return -1;
+	}
+	base = (size_t [3]){0, c->pos, c->len}[whence];
+	if (off < -base || off > SSIZE_MAX/4-base) goto fail;
+	memset(&c->mbs, 0, sizeof c->mbs);
+	return c->pos = base+off;
+}
+
+static size_t wms_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	struct cookie *c = f->cookie;
+	size_t len2;
+	wchar_t *newbuf;
+	if (len + c->pos >= c->space) {
+		len2 = 2*c->space+1 | c->pos+len+1;
+		if (len2 > SSIZE_MAX/4) return 0;
+		newbuf = realloc(c->buf, len2*4);
+		if (!newbuf) return 0;
+		*c->bufp = c->buf = newbuf;
+		memset(c->buf + c->space, 0, 4*(len2 - c->space));
+		c->space = len2;
+	}
+	
+	len2 = mbsnrtowcs(c->buf+c->pos, (void *)&buf, len, c->space-c->pos, &c->mbs);
+	if (len2 == -1) return 0;
+	c->pos += len2;
+	if (c->pos >= c->len) c->len = c->pos;
+	*c->sizep = c->pos;
+	return len;
+}
+
+static int wms_close(FILE *f)
+{
+	return 0;
+}
+
+FILE *open_wmemstream(wchar_t **bufp, size_t *sizep)
+{
+	FILE *f;
+	struct cookie *c;
+	wchar_t *buf;
+
+	if (!(f=malloc(sizeof *f + sizeof *c))) return 0;
+	if (!(buf=malloc(sizeof *buf))) {
+		free(f);
+		return 0;
+	}
+	memset(f, 0, sizeof *f + sizeof *c);
+	f->cookie = c = (void *)(f+1);
+
+	c->bufp = bufp;
+	c->sizep = sizep;
+	c->pos = c->len = c->space = *sizep = 0;
+	c->buf = *bufp = buf;
+	*buf = 0;
+
+	f->flags = F_NORD;
+	f->fd = -1;
+	f->buf = (void *)(c+1);
+	f->buf_size = 0;
+	f->lbf = EOF;
+	f->write = wms_write;
+	f->seek = wms_seek;
+	f->close = wms_close;
+
+	if (!libc.threaded) f->lock = -1;
+
+	return __ofl_add(f);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/pclose.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/pclose.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/pclose.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "stdio_impl.h"
+#include <errno.h>
+#include <unistd.h>
+
+int pclose(FILE *f)
+{
+	int status, r;
+	pid_t pid = f->pipe_pid;
+	fclose(f);
+	while ((r=__syscall(SYS_wait4, pid, &status, 0, 0)) == -EINTR);
+	if (r<0) return __syscall_ret(r);
+	return status;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/perror.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/perror.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/perror.c	(revision 398)
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "stdio_impl.h"
+
+void perror(const char *msg)
+{
+	FILE *f = stderr;
+	char *errstr = strerror(errno);
+
+	FLOCK(f);
+	
+	if (msg && *msg) {
+		fwrite(msg, strlen(msg), 1, f);
+		fputc(':', f);
+		fputc(' ', f);
+	}
+	fwrite(errstr, strlen(errstr), 1, f);
+	fputc('\n', f);
+
+	FUNLOCK(f);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/popen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/popen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/popen.c	(revision 398)
@@ -0,0 +1,73 @@
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <spawn.h>
+#include "stdio_impl.h"
+#include "syscall.h"
+
+extern char **__environ;
+
+FILE *popen(const char *cmd, const char *mode)
+{
+	int p[2], op, e;
+	pid_t pid;
+	FILE *f;
+	posix_spawn_file_actions_t fa;
+
+	if (*mode == 'r') {
+		op = 0;
+	} else if (*mode == 'w') {
+		op = 1;
+	} else {
+		errno = EINVAL;
+		return 0;
+	}
+	
+	if (pipe2(p, O_CLOEXEC)) return NULL;
+	f = fdopen(p[op], mode);
+	if (!f) {
+		__syscall(SYS_close, p[0]);
+		__syscall(SYS_close, p[1]);
+		return NULL;
+	}
+	FLOCK(f);
+
+	/* If the child's end of the pipe happens to already be on the final
+	 * fd number to which it will be assigned (either 0 or 1), it must
+	 * be moved to a different fd. Otherwise, there is no safe way to
+	 * remove the close-on-exec flag in the child without also creating
+	 * a file descriptor leak race condition in the parent. */
+	if (p[1-op] == 1-op) {
+		int tmp = fcntl(1-op, F_DUPFD_CLOEXEC, 0);
+		if (tmp < 0) {
+			e = errno;
+			goto fail;
+		}
+		__syscall(SYS_close, p[1-op]);
+		p[1-op] = tmp;
+	}
+
+	e = ENOMEM;
+	if (!posix_spawn_file_actions_init(&fa)) {
+		if (!posix_spawn_file_actions_adddup2(&fa, p[1-op], 1-op)) {
+			if (!(e = posix_spawn(&pid, "/bin/sh", &fa, 0,
+			    (char *[]){ "sh", "-c", (char *)cmd, 0 }, __environ))) {
+				posix_spawn_file_actions_destroy(&fa);
+				f->pipe_pid = pid;
+				if (!strchr(mode, 'e'))
+					fcntl(p[op], F_SETFD, 0);
+				__syscall(SYS_close, p[1-op]);
+				FUNLOCK(f);
+				return f;
+			}
+		}
+		posix_spawn_file_actions_destroy(&fa);
+	}
+fail:
+	fclose(f);
+	__syscall(SYS_close, p[1-op]);
+
+	errno = e;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/printf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/printf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/printf.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int printf(const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vfprintf(stdout, fmt, ap);
+	va_end(ap);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putc.c	(revision 398)
@@ -0,0 +1,12 @@
+#include "stdio_impl.h"
+
+int putc(int c, FILE *f)
+{
+	if (f->lock < 0 || !__lockfile(f))
+		return putc_unlocked(c, f);
+	c = putc_unlocked(c, f);
+	__unlockfile(f);
+	return c;
+}
+
+weak_alias(putc, _IO_putc);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putc_unlocked.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putc_unlocked.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putc_unlocked.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+
+int (putc_unlocked)(int c, FILE *f)
+{
+	return putc_unlocked(c, f);
+}
+
+weak_alias(putc_unlocked, fputc_unlocked);
+weak_alias(putc_unlocked, _IO_putc_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putchar.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putchar.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putchar.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int putchar(int c)
+{
+	return fputc(c, stdout);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putchar_unlocked.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putchar_unlocked.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putchar_unlocked.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "stdio_impl.h"
+
+int putchar_unlocked(int c)
+{
+	return putc_unlocked(c, stdout);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/puts.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/puts.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/puts.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "stdio_impl.h"
+
+int puts(const char *s)
+{
+	int r;
+	FLOCK(stdout);
+	r = -(fputs(s, stdout) < 0 || putc_unlocked('\n', stdout) < 0);
+	FUNLOCK(stdout);
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putw.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putw.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putw.c	(revision 398)
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+
+int putw(int x, FILE *f)
+{
+	return (int)fwrite(&x, sizeof x, 1, f)-1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putwc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putwc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putwc.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+
+wint_t putwc(wchar_t c, FILE *f)
+{
+	return fputwc(c, f);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putwchar.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putwchar.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/putwchar.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+
+wint_t putwchar(wchar_t c)
+{
+	return fputwc(c, stdout);
+}
+
+weak_alias(putwchar, putwchar_unlocked);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/remove.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/remove.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/remove.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int remove(const char *path)
+{
+#ifdef SYS_unlink
+	int r = __syscall(SYS_unlink, path);
+#else
+	int r = __syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#endif
+#ifdef SYS_rmdir
+	if (r==-EISDIR) r = __syscall(SYS_rmdir, path);
+#else
+	if (r==-EISDIR) r = __syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#endif
+	return __syscall_ret(r);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/rename.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/rename.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/rename.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int rename(const char *old, const char *new)
+{
+#ifdef SYS_rename
+	return syscall(SYS_rename, old, new);
+#else
+	return syscall(SYS_renameat, AT_FDCWD, old, AT_FDCWD, new);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/rewind.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/rewind.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/rewind.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "stdio_impl.h"
+
+void rewind(FILE *f)
+{
+	FLOCK(f);
+	__fseeko_unlocked(f, 0, SEEK_SET);
+	f->flags &= ~F_ERR;
+	FUNLOCK(f);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/scanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/scanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/scanf.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include "libc.h"
+
+int scanf(const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vscanf(fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(scanf,__isoc99_scanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setbuf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setbuf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setbuf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void setbuf(FILE *restrict f, char *restrict buf)
+{
+	setvbuf(f, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setbuffer.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setbuffer.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setbuffer.c	(revision 398)
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+
+void setbuffer(FILE *f, char *buf, size_t size)
+{
+	setvbuf(f, buf, buf ? _IOFBF : _IONBF, size);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setlinebuf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setlinebuf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setlinebuf.c	(revision 398)
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+
+void setlinebuf(FILE *f)
+{
+	setvbuf(f, 0, _IOLBF, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setvbuf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setvbuf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/setvbuf.c	(revision 398)
@@ -0,0 +1,24 @@
+#include "stdio_impl.h"
+
+/* This function makes no attempt to protect the user from his/her own
+ * stupidity. If called any time but when then ISO C standard specifically
+ * allows it, all hell can and will break loose, especially with threads!
+ *
+ * This implementation ignores all arguments except the buffering type,
+ * and uses the existing buffer allocated alongside the FILE object.
+ * In the case of stderr where the preexisting buffer is length 1, it
+ * is not possible to set line buffering or full buffering. */
+
+int setvbuf(FILE *restrict f, char *restrict buf, int type, size_t size)
+{
+	f->lbf = EOF;
+
+	if (type == _IONBF)
+		f->buf_size = 0;
+	else if (type == _IOLBF)
+		f->lbf = '\n';
+
+	f->flags |= F_SVB;
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/snprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/snprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/snprintf.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsnprintf(s, n, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/sprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/sprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/sprintf.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int sprintf(char *restrict s, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsprintf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/sscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/sscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/sscanf.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include "libc.h"
+
+int sscanf(const char *restrict s, const char *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsscanf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(sscanf,__isoc99_sscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/stderr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/stderr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/stderr.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+
+static unsigned char buf[UNGET];
+static FILE f = {
+	.buf = buf+UNGET,
+	.buf_size = 0,
+	.fd = 2,
+	.flags = F_PERM | F_NORD,
+	.lbf = -1,
+	.write = __stdio_write,
+	.seek = __stdio_seek,
+	.close = __stdio_close,
+	.lock = -1,
+};
+FILE *const stderr = &f;
+FILE *volatile __stderr_used = &f;
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/stdin.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/stdin.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/stdin.c	(revision 398)
@@ -0,0 +1,15 @@
+#include "stdio_impl.h"
+
+static unsigned char buf[BUFSIZ+UNGET];
+static FILE f = {
+	.buf = buf+UNGET,
+	.buf_size = sizeof buf-UNGET,
+	.fd = 0,
+	.flags = F_PERM | F_NOWR,
+	.read = __stdio_read,
+	.seek = __stdio_seek,
+	.close = __stdio_close,
+	.lock = -1,
+};
+FILE *const stdin = &f;
+FILE *volatile __stdin_used = &f;
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/stdout.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/stdout.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/stdout.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+
+static unsigned char buf[BUFSIZ+UNGET];
+static FILE f = {
+	.buf = buf+UNGET,
+	.buf_size = sizeof buf-UNGET,
+	.fd = 1,
+	.flags = F_PERM | F_NORD,
+	.lbf = '\n',
+	.write = __stdout_write,
+	.seek = __stdio_seek,
+	.close = __stdio_close,
+	.lock = -1,
+};
+FILE *const stdout = &f;
+FILE *volatile __stdout_used = &f;
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/swprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/swprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/swprintf.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <stdarg.h>
+#include <wchar.h>
+
+int swprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vswprintf(s, n, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/swscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/swscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/swscanf.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <stdarg.h>
+#include <wchar.h>
+#include "libc.h"
+
+int swscanf(const wchar_t *restrict s, const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vswscanf(s, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(swscanf,__isoc99_swscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/tempnam.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/tempnam.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/tempnam.c	(revision 398)
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <string.h>
+#include "syscall.h"
+
+#define MAXTRIES 100
+
+char *__randname(char *);
+
+char *tempnam(const char *dir, const char *pfx)
+{
+	char s[PATH_MAX];
+	size_t l, dl, pl;
+	int try;
+	int r;
+
+	if (!dir) dir = P_tmpdir;
+	if (!pfx) pfx = "temp";
+
+	dl = strlen(dir);
+	pl = strlen(pfx);
+	l = dl + 1 + pl + 1 + 6;
+
+	if (l >= PATH_MAX) {
+		errno = ENAMETOOLONG;
+		return 0;
+	}
+
+	memcpy(s, dir, dl);
+	s[dl] = '/';
+	memcpy(s+dl+1, pfx, pl);
+	s[dl+1+pl] = '_';
+	s[l] = 0;
+
+	for (try=0; try<MAXTRIES; try++) {
+		__randname(s+l-6);
+#ifdef SYS_lstat
+		r = __syscall(SYS_lstat, s, &(struct stat){0});
+#else
+		r = __syscall(SYS_fstatat, AT_FDCWD, s,
+			&(struct stat){0}, AT_SYMLINK_NOFOLLOW);
+#endif
+		if (r == -ENOENT) return strdup(s);
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/tmpfile.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/tmpfile.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/tmpfile.c	(revision 398)
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include "stdio_impl.h"
+
+#define MAXTRIES 100
+
+char *__randname(char *);
+
+FILE *tmpfile(void)
+{
+	char s[] = "/tmp/tmpfile_XXXXXX";
+	int fd;
+	FILE *f;
+	int try;
+	for (try=0; try<MAXTRIES; try++) {
+		__randname(s+13);
+		fd = sys_open(s, O_RDWR|O_CREAT|O_EXCL, 0600);
+		if (fd >= 0) {
+#ifdef SYS_unlink
+			__syscall(SYS_unlink, s);
+#else
+			__syscall(SYS_unlinkat, AT_FDCWD, s, 0);
+#endif
+			f = __fdopen(fd, "w+");
+			if (!f) __syscall(SYS_close, fd);
+			return f;
+		}
+	}
+	return 0;
+}
+
+LFS64(tmpfile);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/tmpnam.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/tmpnam.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/tmpnam.c	(revision 398)
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <string.h>
+#include "syscall.h"
+
+#define MAXTRIES 100
+
+char *__randname(char *);
+
+char *tmpnam(char *buf)
+{
+	static char internal[L_tmpnam];
+	char s[] = "/tmp/tmpnam_XXXXXX";
+	int try;
+	int r;
+	for (try=0; try<MAXTRIES; try++) {
+		__randname(s+12);
+#ifdef SYS_lstat
+		r = __syscall(SYS_lstat, s, &(struct stat){0});
+#else
+		r = __syscall(SYS_fstatat, AT_FDCWD, s,
+			&(struct stat){0}, AT_SYMLINK_NOFOLLOW);
+#endif
+		if (r == -ENOENT) return strcpy(buf ? buf : internal, s);
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ungetc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ungetc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ungetc.c	(revision 398)
@@ -0,0 +1,20 @@
+#include "stdio_impl.h"
+
+int ungetc(int c, FILE *f)
+{
+	if (c == EOF) return c;
+
+	FLOCK(f);
+
+	if (!f->rpos) __toread(f);
+	if (!f->rpos || f->rpos <= f->buf - UNGET) {
+		FUNLOCK(f);
+		return EOF;
+	}
+
+	*--f->rpos = c;
+	f->flags &= ~F_EOF;
+
+	FUNLOCK(f);
+	return c;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ungetwc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ungetwc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/ungetwc.c	(revision 398)
@@ -0,0 +1,35 @@
+#include "stdio_impl.h"
+#include "locale_impl.h"
+#include <wchar.h>
+#include <limits.h>
+#include <ctype.h>
+#include <string.h>
+
+wint_t ungetwc(wint_t c, FILE *f)
+{
+	unsigned char mbc[MB_LEN_MAX];
+	int l;
+	locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
+
+	FLOCK(f);
+
+	if (f->mode <= 0) fwide(f, 1);
+	*ploc = f->locale;
+
+	if (!f->rpos) __toread(f);
+	if (!f->rpos || c == WEOF || (l = wcrtomb((void *)mbc, c, 0)) < 0 ||
+	    f->rpos < f->buf - UNGET + l) {
+		FUNLOCK(f);
+		*ploc = loc;
+		return WEOF;
+	}
+
+	if (isascii(c)) *--f->rpos = c;
+	else memcpy(f->rpos -= l, mbc, l);
+
+	f->flags &= ~F_EOF;
+
+	FUNLOCK(f);
+	*ploc = loc;
+	return c;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vasprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vasprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vasprintf.c	(revision 398)
@@ -0,0 +1,15 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+int vasprintf(char **s, const char *fmt, va_list ap)
+{
+	va_list ap2;
+	va_copy(ap2, ap);
+	int l = vsnprintf(0, 0, fmt, ap2);
+	va_end(ap2);
+
+	if (l<0 || !(*s=malloc(l+1U))) return -1;
+	return vsnprintf(*s, l+1U, fmt, ap);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vdprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vdprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vdprintf.c	(revision 398)
@@ -0,0 +1,16 @@
+#include "stdio_impl.h"
+
+static size_t wrap_write(FILE *f, const unsigned char *buf, size_t len)
+{
+	return __stdio_write(f, buf, len);
+}
+
+int vdprintf(int fd, const char *restrict fmt, va_list ap)
+{
+	FILE f = {
+		.fd = fd, .lbf = EOF, .write = wrap_write,
+		.buf = (void *)fmt, .buf_size = 0,
+		.lock = -1
+	};
+	return vfprintf(&f, fmt, ap);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfprintf.c	(revision 398)
@@ -0,0 +1,693 @@
+#include "stdio_impl.h"
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <wchar.h>
+#include <inttypes.h>
+#include <math.h>
+#include <float.h>
+
+/* Some useful macros */
+
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+/* Convenient bit representation for modifier flags, which all fall
+ * within 31 codepoints of the space character. */
+
+#define ALT_FORM   (1U<<'#'-' ')
+#define ZERO_PAD   (1U<<'0'-' ')
+#define LEFT_ADJ   (1U<<'-'-' ')
+#define PAD_POS    (1U<<' '-' ')
+#define MARK_POS   (1U<<'+'-' ')
+#define GROUPED    (1U<<'\''-' ')
+
+#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
+
+/* State machine to accept length modifiers + conversion specifiers.
+ * Result is 0 on failure, or an argument type to pop on success. */
+
+enum {
+	BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
+	ZTPRE, JPRE,
+	STOP,
+	PTR, INT, UINT, ULLONG,
+	LONG, ULONG,
+	SHORT, USHORT, CHAR, UCHAR,
+	LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
+	DBL, LDBL,
+	NOARG,
+	MAXSTATE
+};
+
+#define S(x) [(x)-'A']
+
+static const unsigned char states[]['z'-'A'+1] = {
+	{ /* 0: bare types */
+		S('d') = INT, S('i') = INT,
+		S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
+		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
+		S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
+		S('c') = CHAR, S('C') = INT,
+		S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
+		S('m') = NOARG,
+		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
+		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
+	}, { /* 1: l-prefixed */
+		S('d') = LONG, S('i') = LONG,
+		S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
+		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
+		S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
+		S('c') = INT, S('s') = PTR, S('n') = PTR,
+		S('l') = LLPRE,
+	}, { /* 2: ll-prefixed */
+		S('d') = LLONG, S('i') = LLONG,
+		S('o') = ULLONG, S('u') = ULLONG,
+		S('x') = ULLONG, S('X') = ULLONG,
+		S('n') = PTR,
+	}, { /* 3: h-prefixed */
+		S('d') = SHORT, S('i') = SHORT,
+		S('o') = USHORT, S('u') = USHORT,
+		S('x') = USHORT, S('X') = USHORT,
+		S('n') = PTR,
+		S('h') = HHPRE,
+	}, { /* 4: hh-prefixed */
+		S('d') = CHAR, S('i') = CHAR,
+		S('o') = UCHAR, S('u') = UCHAR,
+		S('x') = UCHAR, S('X') = UCHAR,
+		S('n') = PTR,
+	}, { /* 5: L-prefixed */
+		S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
+		S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
+		S('n') = PTR,
+	}, { /* 6: z- or t-prefixed (assumed to be same size) */
+		S('d') = PDIFF, S('i') = PDIFF,
+		S('o') = SIZET, S('u') = SIZET,
+		S('x') = SIZET, S('X') = SIZET,
+		S('n') = PTR,
+	}, { /* 7: j-prefixed */
+		S('d') = IMAX, S('i') = IMAX,
+		S('o') = UMAX, S('u') = UMAX,
+		S('x') = UMAX, S('X') = UMAX,
+		S('n') = PTR,
+	}
+};
+
+#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
+
+union arg
+{
+	uintmax_t i;
+	long double f;
+	void *p;
+};
+
+static void pop_arg(union arg *arg, int type, va_list *ap)
+{
+	switch (type) {
+	       case PTR:	arg->p = va_arg(*ap, void *);
+	break; case INT:	arg->i = va_arg(*ap, int);
+	break; case UINT:	arg->i = va_arg(*ap, unsigned int);
+	break; case LONG:	arg->i = va_arg(*ap, long);
+	break; case ULONG:	arg->i = va_arg(*ap, unsigned long);
+	break; case ULLONG:	arg->i = va_arg(*ap, unsigned long long);
+	break; case SHORT:	arg->i = (short)va_arg(*ap, int);
+	break; case USHORT:	arg->i = (unsigned short)va_arg(*ap, int);
+	break; case CHAR:	arg->i = (signed char)va_arg(*ap, int);
+	break; case UCHAR:	arg->i = (unsigned char)va_arg(*ap, int);
+	break; case LLONG:	arg->i = va_arg(*ap, long long);
+	break; case SIZET:	arg->i = va_arg(*ap, size_t);
+	break; case IMAX:	arg->i = va_arg(*ap, intmax_t);
+	break; case UMAX:	arg->i = va_arg(*ap, uintmax_t);
+	break; case PDIFF:	arg->i = va_arg(*ap, ptrdiff_t);
+	break; case UIPTR:	arg->i = (uintptr_t)va_arg(*ap, void *);
+	break; case DBL:	arg->f = va_arg(*ap, double);
+	break; case LDBL:	arg->f = va_arg(*ap, long double);
+	}
+}
+
+static void out(FILE *f, const char *s, size_t l)
+{
+	if (!(f->flags & F_ERR)) __fwritex((void *)s, l, f);
+}
+
+static void pad(FILE *f, char c, int w, int l, int fl)
+{
+	char pad[256];
+	if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
+	l = w - l;
+	memset(pad, c, l>sizeof pad ? sizeof pad : l);
+	for (; l >= sizeof pad; l -= sizeof pad)
+		out(f, pad, sizeof pad);
+	out(f, pad, l);
+}
+
+static const char xdigits[16] = {
+	"0123456789ABCDEF"
+};
+
+static char *fmt_x(uintmax_t x, char *s, int lower)
+{
+	for (; x; x>>=4) *--s = xdigits[(x&15)]|lower;
+	return s;
+}
+
+static char *fmt_o(uintmax_t x, char *s)
+{
+	for (; x; x>>=3) *--s = '0' + (x&7);
+	return s;
+}
+
+static char *fmt_u(uintmax_t x, char *s)
+{
+	unsigned long y;
+	for (   ; x>ULONG_MAX; x/=10) *--s = '0' + x%10;
+	for (y=x;           y; y/=10) *--s = '0' + y%10;
+	return s;
+}
+
+/* Do not override this check. The floating point printing code below
+ * depends on the float.h constants being right. If they are wrong, it
+ * may overflow the stack. */
+#if LDBL_MANT_DIG == 53
+typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)];
+#endif
+
+static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t)
+{
+	uint32_t big[(LDBL_MANT_DIG+28)/29 + 1          // mantissa expansion
+		+ (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion
+	uint32_t *a, *d, *r, *z;
+	int e2=0, e, i, j, l;
+	char buf[9+LDBL_MANT_DIG/4], *s;
+	const char *prefix="-0X+0X 0X-0x+0x 0x";
+	int pl;
+	char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;
+
+	pl=1;
+	if (signbit(y)) {
+		y=-y;
+	} else if (fl & MARK_POS) {
+		prefix+=3;
+	} else if (fl & PAD_POS) {
+		prefix+=6;
+	} else prefix++, pl=0;
+
+	if (!isfinite(y)) {
+		char *s = (t&32)?"inf":"INF";
+		if (y!=y) s=(t&32)?"nan":"NAN";
+		pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
+		out(f, prefix, pl);
+		out(f, s, 3);
+		pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
+		return MAX(w, 3+pl);
+	}
+
+	y = frexpl(y, &e2) * 2;
+	if (y) e2--;
+
+	if ((t|32)=='a') {
+		long double round = 8.0;
+		int re;
+
+		if (t&32) prefix += 9;
+		pl += 2;
+
+		if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0;
+		else re=LDBL_MANT_DIG/4-1-p;
+
+		if (re) {
+			while (re--) round*=16;
+			if (*prefix=='-') {
+				y=-y;
+				y-=round;
+				y+=round;
+				y=-y;
+			} else {
+				y+=round;
+				y-=round;
+			}
+		}
+
+		estr=fmt_u(e2<0 ? -e2 : e2, ebuf);
+		if (estr==ebuf) *--estr='0';
+		*--estr = (e2<0 ? '-' : '+');
+		*--estr = t+('p'-'a');
+
+		s=buf;
+		do {
+			int x=y;
+			*s++=xdigits[x]|(t&32);
+			y=16*(y-x);
+			if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.';
+		} while (y);
+
+		if (p > INT_MAX-2-(ebuf-estr)-pl)
+			return -1;
+		if (p && s-buf-2 < p)
+			l = (p+2) + (ebuf-estr);
+		else
+			l = (s-buf) + (ebuf-estr);
+
+		pad(f, ' ', w, pl+l, fl);
+		out(f, prefix, pl);
+		pad(f, '0', w, pl+l, fl^ZERO_PAD);
+		out(f, buf, s-buf);
+		pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
+		out(f, estr, ebuf-estr);
+		pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+		return MAX(w, pl+l);
+	}
+	if (p<0) p=6;
+
+	if (y) y *= 0x1p28, e2-=28;
+
+	if (e2<0) a=r=z=big;
+	else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;
+
+	do {
+		*z = y;
+		y = 1000000000*(y-*z++);
+	} while (y);
+
+	while (e2>0) {
+		uint32_t carry=0;
+		int sh=MIN(29,e2);
+		for (d=z-1; d>=a; d--) {
+			uint64_t x = ((uint64_t)*d<<sh)+carry;
+			*d = x % 1000000000;
+			carry = x / 1000000000;
+		}
+		if (carry) *--a = carry;
+		while (z>a && !z[-1]) z--;
+		e2-=sh;
+	}
+	while (e2<0) {
+		uint32_t carry=0, *b;
+		int sh=MIN(9,-e2), need=1+(p+LDBL_MANT_DIG/3U+8)/9;
+		for (d=a; d<z; d++) {
+			uint32_t rm = *d & (1<<sh)-1;
+			*d = (*d>>sh) + carry;
+			carry = (1000000000>>sh) * rm;
+		}
+		if (!*a) a++;
+		if (carry) *z++ = carry;
+		/* Avoid (slow!) computation past requested precision */
+		b = (t|32)=='f' ? r : a;
+		if (z-b > need) z = b+need;
+		e2+=sh;
+	}
+
+	if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
+	else e=0;
+
+	/* Perform rounding: j is precision after the radix (possibly neg) */
+	j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);
+	if (j < 9*(z-r-1)) {
+		uint32_t x;
+		/* We avoid C's broken division of negative numbers */
+		d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP);
+		j += 9*LDBL_MAX_EXP;
+		j %= 9;
+		for (i=10, j++; j<9; i*=10, j++);
+		x = *d % i;
+		/* Are there any significant digits past j? */
+		if (x || d+1!=z) {
+			long double round = 2/LDBL_EPSILON;
+			long double small;
+			if ((*d/i & 1) || (i==1000000000 && d>a && (d[-1]&1)))
+				round += 2;
+			if (x<i/2) small=0x0.8p0;
+			else if (x==i/2 && d+1==z) small=0x1.0p0;
+			else small=0x1.8p0;
+			if (pl && *prefix=='-') round*=-1, small*=-1;
+			*d -= x;
+			/* Decide whether to round by probing round+small */
+			if (round+small != round) {
+				*d = *d + i;
+				while (*d > 999999999) {
+					*d--=0;
+					if (d<a) *--a=0;
+					(*d)++;
+				}
+				for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
+			}
+		}
+		if (z>d+1) z=d+1;
+	}
+	for (; z>a && !z[-1]; z--);
+	
+	if ((t|32)=='g') {
+		if (!p) p++;
+		if (p>e && e>=-4) {
+			t--;
+			p-=e+1;
+		} else {
+			t-=2;
+			p--;
+		}
+		if (!(fl&ALT_FORM)) {
+			/* Count trailing zeros in last place */
+			if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++);
+			else j=9;
+			if ((t|32)=='f')
+				p = MIN(p,MAX(0,9*(z-r-1)-j));
+			else
+				p = MIN(p,MAX(0,9*(z-r-1)+e-j));
+		}
+	}
+	if (p > INT_MAX-1-(p || (fl&ALT_FORM)))
+		return -1;
+	l = 1 + p + (p || (fl&ALT_FORM));
+	if ((t|32)=='f') {
+		if (e > INT_MAX-l) return -1;
+		if (e>0) l+=e;
+	} else {
+		estr=fmt_u(e<0 ? -e : e, ebuf);
+		while(ebuf-estr<2) *--estr='0';
+		*--estr = (e<0 ? '-' : '+');
+		*--estr = t;
+		if (ebuf-estr > INT_MAX-l) return -1;
+		l += ebuf-estr;
+	}
+
+	if (l > INT_MAX-pl) return -1;
+	pad(f, ' ', w, pl+l, fl);
+	out(f, prefix, pl);
+	pad(f, '0', w, pl+l, fl^ZERO_PAD);
+
+	if ((t|32)=='f') {
+		if (a>r) a=r;
+		for (d=a; d<=r; d++) {
+			char *s = fmt_u(*d, buf+9);
+			if (d!=a) while (s>buf) *--s='0';
+			else if (s==buf+9) *--s='0';
+			out(f, s, buf+9-s);
+		}
+		if (p || (fl&ALT_FORM)) out(f, ".", 1);
+		for (; d<z && p>0; d++, p-=9) {
+			char *s = fmt_u(*d, buf+9);
+			while (s>buf) *--s='0';
+			out(f, s, MIN(9,p));
+		}
+		pad(f, '0', p+9, 9, 0);
+	} else {
+		if (z<=a) z=a+1;
+		for (d=a; d<z && p>=0; d++) {
+			char *s = fmt_u(*d, buf+9);
+			if (s==buf+9) *--s='0';
+			if (d!=a) while (s>buf) *--s='0';
+			else {
+				out(f, s++, 1);
+				if (p>0||(fl&ALT_FORM)) out(f, ".", 1);
+			}
+			out(f, s, MIN(buf+9-s, p));
+			p -= buf+9-s;
+		}
+		pad(f, '0', p+18, 18, 0);
+		out(f, estr, ebuf-estr);
+	}
+
+	pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+
+	return MAX(w, pl+l);
+}
+
+static int getint(char **s) {
+	int i;
+	for (i=0; isdigit(**s); (*s)++) {
+		if (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1;
+		else i = 10*i + (**s-'0');
+	}
+	return i;
+}
+
+static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
+{
+	char *a, *z, *s=(char *)fmt;
+	unsigned l10n=0, fl;
+	int w, p, xp;
+	union arg arg;
+	int argpos;
+	unsigned st, ps;
+	int cnt=0, l=0;
+	size_t i;
+	char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];
+	const char *prefix;
+	int t, pl;
+	wchar_t wc[2], *ws;
+	char mb[4];
+
+	for (;;) {
+		/* This error is only specified for snprintf, but since it's
+		 * unspecified for other forms, do the same. Stop immediately
+		 * on overflow; otherwise %n could produce wrong results. */
+		if (l > INT_MAX - cnt) goto overflow;
+
+		/* Update output count, end loop when fmt is exhausted */
+		cnt += l;
+		if (!*s) break;
+
+		/* Handle literal text and %% format specifiers */
+		for (a=s; *s && *s!='%'; s++);
+		for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);
+		if (z-a > INT_MAX-cnt) goto overflow;
+		l = z-a;
+		if (f) out(f, a, l);
+		if (l) continue;
+
+		if (isdigit(s[1]) && s[2]=='$') {
+			l10n=1;
+			argpos = s[1]-'0';
+			s+=3;
+		} else {
+			argpos = -1;
+			s++;
+		}
+
+		/* Read modifier flags */
+		for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
+			fl |= 1U<<*s-' ';
+
+		/* Read field width */
+		if (*s=='*') {
+			if (isdigit(s[1]) && s[2]=='$') {
+				l10n=1;
+				nl_type[s[1]-'0'] = INT;
+				w = nl_arg[s[1]-'0'].i;
+				s+=3;
+			} else if (!l10n) {
+				w = f ? va_arg(*ap, int) : 0;
+				s++;
+			} else goto inval;
+			if (w<0) fl|=LEFT_ADJ, w=-w;
+		} else if ((w=getint(&s))<0) goto overflow;
+
+		/* Read precision */
+		if (*s=='.' && s[1]=='*') {
+			if (isdigit(s[2]) && s[3]=='$') {
+				nl_type[s[2]-'0'] = INT;
+				p = nl_arg[s[2]-'0'].i;
+				s+=4;
+			} else if (!l10n) {
+				p = f ? va_arg(*ap, int) : 0;
+				s+=2;
+			} else goto inval;
+			xp = (p>=0);
+		} else if (*s=='.') {
+			s++;
+			p = getint(&s);
+			xp = 1;
+		} else {
+			p = -1;
+			xp = 0;
+		}
+
+		/* Format specifier state machine */
+		st=0;
+		do {
+			if (OOB(*s)) goto inval;
+			ps=st;
+			st=states[st]S(*s++);
+		} while (st-1<STOP);
+		if (!st) goto inval;
+
+		/* Check validity of argument type (nl/normal) */
+		if (st==NOARG) {
+			if (argpos>=0) goto inval;
+		} else {
+			if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
+			else if (f) pop_arg(&arg, st, ap);
+			else return 0;
+		}
+
+		if (!f) continue;
+
+		z = buf + sizeof(buf);
+		prefix = "-+   0X0x";
+		pl = 0;
+		t = s[-1];
+
+		/* Transform ls,lc -> S,C */
+		if (ps && (t&15)==3) t&=~32;
+
+		/* - and 0 flags are mutually exclusive */
+		if (fl & LEFT_ADJ) fl &= ~ZERO_PAD;
+
+		switch(t) {
+		case 'n':
+			switch(ps) {
+			case BARE: *(int *)arg.p = cnt; break;
+			case LPRE: *(long *)arg.p = cnt; break;
+			case LLPRE: *(long long *)arg.p = cnt; break;
+			case HPRE: *(unsigned short *)arg.p = cnt; break;
+			case HHPRE: *(unsigned char *)arg.p = cnt; break;
+			case ZTPRE: *(size_t *)arg.p = cnt; break;
+			case JPRE: *(uintmax_t *)arg.p = cnt; break;
+			}
+			continue;
+		case 'p':
+			p = MAX(p, 2*sizeof(void*));
+			t = 'x';
+			fl |= ALT_FORM;
+		case 'x': case 'X':
+			a = fmt_x(arg.i, z, t&32);
+			if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2;
+			if (0) {
+		case 'o':
+			a = fmt_o(arg.i, z);
+			if ((fl&ALT_FORM) && p<z-a+1) prefix+=5, pl=1;
+			} if (0) {
+		case 'd': case 'i':
+			pl=1;
+			if (arg.i>INTMAX_MAX) {
+				arg.i=-arg.i;
+			} else if (fl & MARK_POS) {
+				prefix++;
+			} else if (fl & PAD_POS) {
+				prefix+=2;
+			} else pl=0;
+		case 'u':
+			a = fmt_u(arg.i, z);
+			}
+			if (xp && p<0) goto overflow;
+			if (p>=0) fl &= ~ZERO_PAD;
+			if (!arg.i && !p) {
+				a=z;
+				break;
+			}
+			p = MAX(p, z-a + !arg.i);
+			break;
+		case 'c':
+			*(a=z-(p=1))=arg.i;
+			fl &= ~ZERO_PAD;
+			break;
+		case 'm':
+			if (1) a = strerror(errno); else
+		case 's':
+			a = arg.p ? arg.p : "(null)";
+			z = a + strnlen(a, p<0 ? INT_MAX : p);
+			if (p<0 && *z) goto overflow;
+			p = z-a;
+			fl &= ~ZERO_PAD;
+			break;
+		case 'C':
+			wc[0] = arg.i;
+			wc[1] = 0;
+			arg.p = wc;
+			p = -1;
+		case 'S':
+			ws = arg.p;
+			for (i=l=0; i<p && *ws && (l=wctomb(mb, *ws++))>=0 && l<=p-i; i+=l);
+			if (l<0) return -1;
+			if (i > INT_MAX) goto overflow;
+			p = i;
+			pad(f, ' ', w, p, fl);
+			ws = arg.p;
+			for (i=0; i<0U+p && *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l)
+				out(f, mb, l);
+			pad(f, ' ', w, p, fl^LEFT_ADJ);
+			l = w>p ? w : p;
+			continue;
+		case 'e': case 'f': case 'g': case 'a':
+		case 'E': case 'F': case 'G': case 'A':
+			if (xp && p<0) goto overflow;
+			l = fmt_fp(f, arg.f, w, p, fl, t);
+			if (l<0) goto overflow;
+			continue;
+		}
+
+		if (p < z-a) p = z-a;
+		if (p > INT_MAX-pl) goto overflow;
+		if (w < pl+p) w = pl+p;
+		if (w > INT_MAX-cnt) goto overflow;
+
+		pad(f, ' ', w, pl+p, fl);
+		out(f, prefix, pl);
+		pad(f, '0', w, pl+p, fl^ZERO_PAD);
+		pad(f, '0', p, z-a, 0);
+		out(f, a, z-a);
+		pad(f, ' ', w, pl+p, fl^LEFT_ADJ);
+
+		l = w;
+	}
+
+	if (f) return cnt;
+	if (!l10n) return 0;
+
+	for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
+		pop_arg(nl_arg+i, nl_type[i], ap);
+	for (; i<=NL_ARGMAX && !nl_type[i]; i++);
+	if (i<=NL_ARGMAX) goto inval;
+	return 1;
+
+inval:
+	errno = EINVAL;
+	return -1;
+overflow:
+	errno = EOVERFLOW;
+	return -1;
+}
+
+int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)
+{
+	va_list ap2;
+	int nl_type[NL_ARGMAX+1] = {0};
+	union arg nl_arg[NL_ARGMAX+1];
+	unsigned char internal_buf[80], *saved_buf = 0;
+	int olderr;
+	int ret;
+
+	/* the copy allows passing va_list* even if va_list is an array */
+	va_copy(ap2, ap);
+	if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {
+		va_end(ap2);
+		return -1;
+	}
+
+	FLOCK(f);
+	olderr = f->flags & F_ERR;
+	if (f->mode < 1) f->flags &= ~F_ERR;
+	if (!f->buf_size) {
+		saved_buf = f->buf;
+		f->wpos = f->wbase = f->buf = internal_buf;
+		f->buf_size = sizeof internal_buf;
+		f->wend = internal_buf + sizeof internal_buf;
+	}
+	ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);
+	if (saved_buf) {
+		f->write(f, 0, 0);
+		if (!f->wpos) ret = -1;
+		f->buf = saved_buf;
+		f->buf_size = 0;
+		f->wpos = f->wbase = f->wend = 0;
+	}
+	if (f->flags & F_ERR) ret = -1;
+	f->flags |= olderr;
+	FUNLOCK(f);
+	va_end(ap2);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfscanf.c	(revision 398)
@@ -0,0 +1,336 @@
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "stdio_impl.h"
+#include "shgetc.h"
+#include "intscan.h"
+#include "floatscan.h"
+
+#define SIZE_hh -2
+#define SIZE_h  -1
+#define SIZE_def 0
+#define SIZE_l   1
+#define SIZE_L   2
+#define SIZE_ll  3
+
+static void store_int(void *dest, int size, unsigned long long i)
+{
+	if (!dest) return;
+	switch (size) {
+	case SIZE_hh:
+		*(char *)dest = i;
+		break;
+	case SIZE_h:
+		*(short *)dest = i;
+		break;
+	case SIZE_def:
+		*(int *)dest = i;
+		break;
+	case SIZE_l:
+		*(long *)dest = i;
+		break;
+	case SIZE_ll:
+		*(long long *)dest = i;
+		break;
+	}
+}
+
+static void *arg_n(va_list ap, unsigned int n)
+{
+	void *p;
+	unsigned int i;
+	va_list ap2;
+	va_copy(ap2, ap);
+	for (i=n; i>1; i--) va_arg(ap2, void *);
+	p = va_arg(ap2, void *);
+	va_end(ap2);
+	return p;
+}
+
+int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)
+{
+	int width;
+	int size;
+	int alloc;
+	int base;
+	const unsigned char *p;
+	int c, t;
+	char *s;
+	wchar_t *wcs;
+	mbstate_t st;
+	void *dest=NULL;
+	int invert;
+	int matches=0;
+	unsigned long long x;
+	long double y;
+	off_t pos = 0;
+	unsigned char scanset[257];
+	size_t i, k;
+	wchar_t wc;
+
+	FLOCK(f);
+
+	for (p=(const unsigned char *)fmt; *p; p++) {
+
+		alloc = 0;
+
+		if (isspace(*p)) {
+			while (isspace(p[1])) p++;
+			shlim(f, 0);
+			while (isspace(shgetc(f)));
+			shunget(f);
+			pos += shcnt(f);
+			continue;
+		}
+		if (*p != '%' || p[1] == '%') {
+			shlim(f, 0);
+			if (*p == '%') {
+				p++;
+				while (isspace((c=shgetc(f))));
+			} else {
+				c = shgetc(f);
+			}
+			if (c!=*p) {
+				shunget(f);
+				if (c<0) goto input_fail;
+				goto match_fail;
+			}
+			pos += shcnt(f);
+			continue;
+		}
+
+		p++;
+		if (*p=='*') {
+			dest = 0; p++;
+		} else if (isdigit(*p) && p[1]=='$') {
+			dest = arg_n(ap, *p-'0'); p+=2;
+		} else {
+			dest = va_arg(ap, void *);
+		}
+
+		for (width=0; isdigit(*p); p++) {
+			width = 10*width + *p - '0';
+		}
+
+		if (*p=='m') {
+			wcs = 0;
+			s = 0;
+			alloc = !!dest;
+			p++;
+		} else {
+			alloc = 0;
+		}
+
+		size = SIZE_def;
+		switch (*p++) {
+		case 'h':
+			if (*p == 'h') p++, size = SIZE_hh;
+			else size = SIZE_h;
+			break;
+		case 'l':
+			if (*p == 'l') p++, size = SIZE_ll;
+			else size = SIZE_l;
+			break;
+		case 'j':
+			size = SIZE_ll;
+			break;
+		case 'z':
+		case 't':
+			size = SIZE_l;
+			break;
+		case 'L':
+			size = SIZE_L;
+			break;
+		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'a': case 'e': case 'f': case 'g':
+		case 'A': case 'E': case 'F': case 'G': case 'X':
+		case 's': case 'c': case '[':
+		case 'S': case 'C':
+		case 'p': case 'n':
+			p--;
+			break;
+		default:
+			goto fmt_fail;
+		}
+
+		t = *p;
+
+		/* C or S */
+		if ((t&0x2f) == 3) {
+			t |= 32;
+			size = SIZE_l;
+		}
+
+		switch (t) {
+		case 'c':
+			if (width < 1) width = 1;
+		case '[':
+			break;
+		case 'n':
+			store_int(dest, size, pos);
+			/* do not increment match count, etc! */
+			continue;
+		default:
+			shlim(f, 0);
+			while (isspace(shgetc(f)));
+			shunget(f);
+			pos += shcnt(f);
+		}
+
+		shlim(f, width);
+		if (shgetc(f) < 0) goto input_fail;
+		shunget(f);
+
+		switch (t) {
+		case 's':
+		case 'c':
+		case '[':
+			if (t == 'c' || t == 's') {
+				memset(scanset, -1, sizeof scanset);
+				scanset[0] = 0;
+				if (t == 's') {
+					scanset[1+'\t'] = 0;
+					scanset[1+'\n'] = 0;
+					scanset[1+'\v'] = 0;
+					scanset[1+'\f'] = 0;
+					scanset[1+'\r'] = 0;
+					scanset[1+' '] = 0;
+				}
+			} else {
+				if (*++p == '^') p++, invert = 1;
+				else invert = 0;
+				memset(scanset, invert, sizeof scanset);
+				scanset[0] = 0;
+				if (*p == '-') p++, scanset[1+'-'] = 1-invert;
+				else if (*p == ']') p++, scanset[1+']'] = 1-invert;
+				for (; *p != ']'; p++) {
+					if (!*p) goto fmt_fail;
+					if (*p=='-' && p[1] && p[1] != ']')
+						for (c=p++[-1]; c<*p; c++)
+							scanset[1+c] = 1-invert;
+					scanset[1+*p] = 1-invert;
+				}
+			}
+			wcs = 0;
+			s = 0;
+			i = 0;
+			k = t=='c' ? width+1U : 31;
+			if (size == SIZE_l) {
+				if (alloc) {
+					wcs = malloc(k*sizeof(wchar_t));
+					if (!wcs) goto alloc_fail;
+				} else {
+					wcs = dest;
+				}
+				st = (mbstate_t){0};
+				while (scanset[(c=shgetc(f))+1]) {
+					switch (mbrtowc(&wc, &(char){c}, 1, &st)) {
+					case -1:
+						goto input_fail;
+					case -2:
+						continue;
+					}
+					if (wcs) wcs[i++] = wc;
+					if (alloc && i==k) {
+						k+=k+1;
+						wchar_t *tmp = realloc(wcs, k*sizeof(wchar_t));
+						if (!tmp) goto alloc_fail;
+						wcs = tmp;
+					}
+				}
+				if (!mbsinit(&st)) goto input_fail;
+			} else if (alloc) {
+				s = malloc(k);
+				if (!s) goto alloc_fail;
+				while (scanset[(c=shgetc(f))+1]) {
+					s[i++] = c;
+					if (i==k) {
+						k+=k+1;
+						char *tmp = realloc(s, k);
+						if (!tmp) goto alloc_fail;
+						s = tmp;
+					}
+				}
+			} else if ((s = dest)) {
+				while (scanset[(c=shgetc(f))+1])
+					s[i++] = c;
+			} else {
+				while (scanset[(c=shgetc(f))+1]);
+			}
+			shunget(f);
+			if (!shcnt(f)) goto match_fail;
+			if (t == 'c' && shcnt(f) != width) goto match_fail;
+			if (alloc) {
+				if (size == SIZE_l) *(wchar_t **)dest = wcs;
+				else *(char **)dest = s;
+			}
+			if (t != 'c') {
+				if (wcs) wcs[i] = 0;
+				if (s) s[i] = 0;
+			}
+			break;
+		case 'p':
+		case 'X':
+		case 'x':
+			base = 16;
+			goto int_common;
+		case 'o':
+			base = 8;
+			goto int_common;
+		case 'd':
+		case 'u':
+			base = 10;
+			goto int_common;
+		case 'i':
+			base = 0;
+		int_common:
+			x = __intscan(f, base, 0, ULLONG_MAX);
+			if (!shcnt(f)) goto match_fail;
+			if (t=='p' && dest) *(void **)dest = (void *)(uintptr_t)x;
+			else store_int(dest, size, x);
+			break;
+		case 'a': case 'A':
+		case 'e': case 'E':
+		case 'f': case 'F':
+		case 'g': case 'G':
+			y = __floatscan(f, size, 0);
+			if (!shcnt(f)) goto match_fail;
+			if (dest) switch (size) {
+			case SIZE_def:
+				*(float *)dest = y;
+				break;
+			case SIZE_l:
+				*(double *)dest = y;
+				break;
+			case SIZE_L:
+				*(long double *)dest = y;
+				break;
+			}
+			break;
+		}
+
+		pos += shcnt(f);
+		if (dest) matches++;
+	}
+	if (0) {
+fmt_fail:
+alloc_fail:
+input_fail:
+		if (!matches) matches--;
+match_fail:
+		if (alloc) {
+			free(s);
+			free(wcs);
+		}
+	}
+	FUNLOCK(f);
+	return matches;
+}
+
+weak_alias(vfscanf,__isoc99_vfscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfwprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfwprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfwprintf.c	(revision 398)
@@ -0,0 +1,359 @@
+#include "stdio_impl.h"
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <wchar.h>
+#include <inttypes.h>
+
+/* Convenient bit representation for modifier flags, which all fall
+ * within 31 codepoints of the space character. */
+
+#define ALT_FORM   (1U<<'#'-' ')
+#define ZERO_PAD   (1U<<'0'-' ')
+#define LEFT_ADJ   (1U<<'-'-' ')
+#define PAD_POS    (1U<<' '-' ')
+#define MARK_POS   (1U<<'+'-' ')
+#define GROUPED    (1U<<'\''-' ')
+
+#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
+
+/* State machine to accept length modifiers + conversion specifiers.
+ * Result is 0 on failure, or an argument type to pop on success. */
+
+enum {
+	BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
+	ZTPRE, JPRE,
+	STOP,
+	PTR, INT, UINT, ULLONG,
+	LONG, ULONG,
+	SHORT, USHORT, CHAR, UCHAR,
+	LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
+	DBL, LDBL,
+	NOARG,
+	MAXSTATE
+};
+
+#define S(x) [(x)-'A']
+
+static const unsigned char states[]['z'-'A'+1] = {
+	{ /* 0: bare types */
+		S('d') = INT, S('i') = INT,
+		S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
+		S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
+		S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
+		S('c') = CHAR, S('C') = INT,
+		S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
+		S('m') = NOARG,
+		S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
+		S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
+	}, { /* 1: l-prefixed */
+		S('d') = LONG, S('i') = LONG,
+		S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
+		S('c') = INT, S('s') = PTR, S('n') = PTR,
+		S('l') = LLPRE,
+	}, { /* 2: ll-prefixed */
+		S('d') = LLONG, S('i') = LLONG,
+		S('o') = ULLONG, S('u') = ULLONG,
+		S('x') = ULLONG, S('X') = ULLONG,
+		S('n') = PTR,
+	}, { /* 3: h-prefixed */
+		S('d') = SHORT, S('i') = SHORT,
+		S('o') = USHORT, S('u') = USHORT,
+		S('x') = USHORT, S('X') = USHORT,
+		S('n') = PTR,
+		S('h') = HHPRE,
+	}, { /* 4: hh-prefixed */
+		S('d') = CHAR, S('i') = CHAR,
+		S('o') = UCHAR, S('u') = UCHAR,
+		S('x') = UCHAR, S('X') = UCHAR,
+		S('n') = PTR,
+	}, { /* 5: L-prefixed */
+		S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
+		S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
+		S('n') = PTR,
+	}, { /* 6: z- or t-prefixed (assumed to be same size) */
+		S('d') = PDIFF, S('i') = PDIFF,
+		S('o') = SIZET, S('u') = SIZET,
+		S('x') = SIZET, S('X') = SIZET,
+		S('n') = PTR,
+	}, { /* 7: j-prefixed */
+		S('d') = IMAX, S('i') = IMAX,
+		S('o') = UMAX, S('u') = UMAX,
+		S('x') = UMAX, S('X') = UMAX,
+		S('n') = PTR,
+	}
+};
+
+#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
+
+union arg
+{
+	uintmax_t i;
+	long double f;
+	void *p;
+};
+
+static void pop_arg(union arg *arg, int type, va_list *ap)
+{
+	switch (type) {
+	       case PTR:	arg->p = va_arg(*ap, void *);
+	break; case INT:	arg->i = va_arg(*ap, int);
+	break; case UINT:	arg->i = va_arg(*ap, unsigned int);
+	break; case LONG:	arg->i = va_arg(*ap, long);
+	break; case ULONG:	arg->i = va_arg(*ap, unsigned long);
+	break; case ULLONG:	arg->i = va_arg(*ap, unsigned long long);
+	break; case SHORT:	arg->i = (short)va_arg(*ap, int);
+	break; case USHORT:	arg->i = (unsigned short)va_arg(*ap, int);
+	break; case CHAR:	arg->i = (signed char)va_arg(*ap, int);
+	break; case UCHAR:	arg->i = (unsigned char)va_arg(*ap, int);
+	break; case LLONG:	arg->i = va_arg(*ap, long long);
+	break; case SIZET:	arg->i = va_arg(*ap, size_t);
+	break; case IMAX:	arg->i = va_arg(*ap, intmax_t);
+	break; case UMAX:	arg->i = va_arg(*ap, uintmax_t);
+	break; case PDIFF:	arg->i = va_arg(*ap, ptrdiff_t);
+	break; case UIPTR:	arg->i = (uintptr_t)va_arg(*ap, void *);
+	break; case DBL:	arg->f = va_arg(*ap, double);
+	break; case LDBL:	arg->f = va_arg(*ap, long double);
+	}
+}
+
+static void out(FILE *f, const wchar_t *s, size_t l)
+{
+	while (l-- && !(f->flags & F_ERR)) fputwc(*s++, f);
+}
+
+static int getint(wchar_t **s) {
+	int i;
+	for (i=0; iswdigit(**s); (*s)++) {
+		if (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1;
+		else i = 10*i + (**s-'0');
+	}
+	return i;
+}
+
+static const char sizeprefix['y'-'a'] = {
+['a'-'a']='L', ['e'-'a']='L', ['f'-'a']='L', ['g'-'a']='L',
+['d'-'a']='j', ['i'-'a']='j', ['o'-'a']='j', ['u'-'a']='j', ['x'-'a']='j',
+['p'-'a']='j'
+};
+
+static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
+{
+	wchar_t *a, *z, *s=(wchar_t *)fmt;
+	unsigned l10n=0, fl;
+	int w, p, xp;
+	union arg arg;
+	int argpos;
+	unsigned st, ps;
+	int cnt=0, l=0;
+	int i;
+	int t;
+	char *bs;
+	char charfmt[16];
+	wchar_t wc;
+
+	for (;;) {
+		/* This error is only specified for snprintf, but since it's
+		 * unspecified for other forms, do the same. Stop immediately
+		 * on overflow; otherwise %n could produce wrong results. */
+		if (l > INT_MAX - cnt) goto overflow;
+
+		/* Update output count, end loop when fmt is exhausted */
+		cnt += l;
+		if (!*s) break;
+
+		/* Handle literal text and %% format specifiers */
+		for (a=s; *s && *s!='%'; s++);
+		for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);
+		if (z-a > INT_MAX-cnt) goto overflow;
+		l = z-a;
+		if (f) out(f, a, l);
+		if (l) continue;
+
+		if (iswdigit(s[1]) && s[2]=='$') {
+			l10n=1;
+			argpos = s[1]-'0';
+			s+=3;
+		} else {
+			argpos = -1;
+			s++;
+		}
+
+		/* Read modifier flags */
+		for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
+			fl |= 1U<<*s-' ';
+
+		/* Read field width */
+		if (*s=='*') {
+			if (iswdigit(s[1]) && s[2]=='$') {
+				l10n=1;
+				nl_type[s[1]-'0'] = INT;
+				w = nl_arg[s[1]-'0'].i;
+				s+=3;
+			} else if (!l10n) {
+				w = f ? va_arg(*ap, int) : 0;
+				s++;
+			} else goto inval;
+			if (w<0) fl|=LEFT_ADJ, w=-w;
+		} else if ((w=getint(&s))<0) goto overflow;
+
+		/* Read precision */
+		if (*s=='.' && s[1]=='*') {
+			if (isdigit(s[2]) && s[3]=='$') {
+				nl_type[s[2]-'0'] = INT;
+				p = nl_arg[s[2]-'0'].i;
+				s+=4;
+			} else if (!l10n) {
+				p = f ? va_arg(*ap, int) : 0;
+				s+=2;
+			} else goto inval;
+			xp = (p>=0);
+		} else if (*s=='.') {
+			s++;
+			p = getint(&s);
+			xp = 1;
+		} else {
+			p = -1;
+			xp = 0;
+		}
+
+		/* Format specifier state machine */
+		st=0;
+		do {
+			if (OOB(*s)) goto inval;
+			ps=st;
+			st=states[st]S(*s++);
+		} while (st-1<STOP);
+		if (!st) goto inval;
+
+		/* Check validity of argument type (nl/normal) */
+		if (st==NOARG) {
+			if (argpos>=0) goto inval;
+		} else {
+			if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
+			else if (f) pop_arg(&arg, st, ap);
+			else return 0;
+		}
+
+		if (!f) continue;
+		t = s[-1];
+		if (ps && (t&15)==3) t&=~32;
+
+		switch (t) {
+		case 'n':
+			switch(ps) {
+			case BARE: *(int *)arg.p = cnt; break;
+			case LPRE: *(long *)arg.p = cnt; break;
+			case LLPRE: *(long long *)arg.p = cnt; break;
+			case HPRE: *(unsigned short *)arg.p = cnt; break;
+			case HHPRE: *(unsigned char *)arg.p = cnt; break;
+			case ZTPRE: *(size_t *)arg.p = cnt; break;
+			case JPRE: *(uintmax_t *)arg.p = cnt; break;
+			}
+			continue;
+		case 'c':
+			fputwc(btowc(arg.i), f);
+			l = 1;
+			continue;
+		case 'C':
+			fputwc(arg.i, f);
+			l = 1;
+			continue;
+		case 'S':
+			a = arg.p;
+			z = a + wcsnlen(a, p<0 ? INT_MAX : p);
+			if (p<0 && *z) goto overflow;
+			p = z-a;
+			if (w<p) w=p;
+			if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
+			out(f, a, p);
+			if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
+			l=w;
+			continue;
+		case 'm':
+			arg.p = strerror(errno);
+		case 's':
+			if (!arg.p) arg.p = "(null)";
+			bs = arg.p;
+			for (i=l=0; l<(p<0?INT_MAX:p) && (i=mbtowc(&wc, bs, MB_LEN_MAX))>0; bs+=i, l++);
+			if (i<0) return -1;
+			if (p<0 && *bs) goto overflow;
+			p=l;
+			if (w<p) w=p;
+			if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
+			bs = arg.p;
+			while (l--) {
+				i=mbtowc(&wc, bs, MB_LEN_MAX);
+				bs+=i;
+				fputwc(wc, f);
+			}
+			if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
+			l=w;
+			continue;
+		}
+
+		if (xp && p<0) goto overflow;
+		snprintf(charfmt, sizeof charfmt, "%%%s%s%s%s%s*.*%c%c",
+			"#"+!(fl & ALT_FORM),
+			"+"+!(fl & MARK_POS),
+			"-"+!(fl & LEFT_ADJ),
+			" "+!(fl & PAD_POS),
+			"0"+!(fl & ZERO_PAD),
+			sizeprefix[(t|32)-'a'], t);
+
+		switch (t|32) {
+		case 'a': case 'e': case 'f': case 'g':
+			l = fprintf(f, charfmt, w, p, arg.f);
+			break;
+		case 'd': case 'i': case 'o': case 'u': case 'x': case 'p':
+			l = fprintf(f, charfmt, w, p, arg.i);
+			break;
+		}
+	}
+
+	if (f) return cnt;
+	if (!l10n) return 0;
+
+	for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
+		pop_arg(nl_arg+i, nl_type[i], ap);
+	for (; i<=NL_ARGMAX && !nl_type[i]; i++);
+	if (i<=NL_ARGMAX) return -1;
+	return 1;
+
+inval:
+	errno = EINVAL;
+	return -1;
+overflow:
+	errno = EOVERFLOW;
+	return -1;
+}
+
+int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
+{
+	va_list ap2;
+	int nl_type[NL_ARGMAX] = {0};
+	union arg nl_arg[NL_ARGMAX];
+	int olderr;
+	int ret;
+
+	/* the copy allows passing va_list* even if va_list is an array */
+	va_copy(ap2, ap);
+	if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {
+		va_end(ap2);
+		return -1;
+	}
+
+	FLOCK(f);
+	fwide(f, 1);
+	olderr = f->flags & F_ERR;
+	f->flags &= ~F_ERR;
+	ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);
+	if (f->flags & F_ERR) ret = -1;
+	f->flags |= olderr;
+	FUNLOCK(f);
+	va_end(ap2);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfwscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfwscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vfwscanf.c	(revision 398)
@@ -0,0 +1,333 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <limits.h>
+#include <string.h>
+
+#include "stdio_impl.h"
+#include "shgetc.h"
+#include "intscan.h"
+#include "floatscan.h"
+#include "libc.h"
+
+#define SIZE_hh -2
+#define SIZE_h  -1
+#define SIZE_def 0
+#define SIZE_l   1
+#define SIZE_L   2
+#define SIZE_ll  3
+
+static void store_int(void *dest, int size, unsigned long long i)
+{
+	if (!dest) return;
+	switch (size) {
+	case SIZE_hh:
+		*(char *)dest = i;
+		break;
+	case SIZE_h:
+		*(short *)dest = i;
+		break;
+	case SIZE_def:
+		*(int *)dest = i;
+		break;
+	case SIZE_l:
+		*(long *)dest = i;
+		break;
+	case SIZE_ll:
+		*(long long *)dest = i;
+		break;
+	}
+}
+
+static void *arg_n(va_list ap, unsigned int n)
+{
+	void *p;
+	unsigned int i;
+	va_list ap2;
+	va_copy(ap2, ap);
+	for (i=n; i>1; i--) va_arg(ap2, void *);
+	p = va_arg(ap2, void *);
+	va_end(ap2);
+	return p;
+}
+
+static int in_set(const wchar_t *set, int c)
+{
+	int j;
+	const wchar_t *p = set;
+	if (*p == '-') {
+		if (c=='-') return 1;
+		p++;
+	} else if (*p == ']') {
+		if (c==']') return 1;
+		p++;
+	}
+	for (; *p && *p != ']'; p++) {
+		if (*p=='-' && p[1] && p[1] != ']')
+			for (j=p++[-1]; j<*p; j++)
+				if (c==j) return 1;
+		if (c==*p) return 1;
+	}
+	return 0;
+}
+
+#if 1
+#undef getwc
+#define getwc(f) \
+	((f)->rpos < (f)->rend && *(f)->rpos < 128 ? *(f)->rpos++ : (getwc)(f))
+
+#undef ungetwc
+#define ungetwc(c,f) \
+	((f)->rend && (c)<128U ? *--(f)->rpos : ungetwc((c),(f)))
+#endif
+
+int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
+{
+	int width;
+	int size;
+	int alloc;
+	const wchar_t *p;
+	int c, t;
+	char *s;
+	wchar_t *wcs;
+	void *dest=NULL;
+	int invert;
+	int matches=0;
+	off_t pos = 0, cnt;
+	static const char size_pfx[][3] = { "hh", "h", "", "l", "L", "ll" };
+	char tmp[3*sizeof(int)+10];
+	const wchar_t *set;
+	size_t i, k;
+
+	FLOCK(f);
+
+	fwide(f, 1);
+
+	for (p=fmt; *p; p++) {
+
+		alloc = 0;
+
+		if (iswspace(*p)) {
+			while (iswspace(p[1])) p++;
+			while (iswspace((c=getwc(f)))) pos++;
+			ungetwc(c, f);
+			continue;
+		}
+		if (*p != '%' || p[1] == '%') {
+			if (*p == '%') {
+				p++;
+				while (iswspace((c=getwc(f)))) pos++;
+			} else {
+				c = getwc(f);
+			}
+			if (c!=*p) {
+				ungetwc(c, f);
+				if (c<0) goto input_fail;
+				goto match_fail;
+			}
+			pos++;
+			continue;
+		}
+
+		p++;
+		if (*p=='*') {
+			dest = 0; p++;
+		} else if (iswdigit(*p) && p[1]=='$') {
+			dest = arg_n(ap, *p-'0'); p+=2;
+		} else {
+			dest = va_arg(ap, void *);
+		}
+
+		for (width=0; iswdigit(*p); p++) {
+			width = 10*width + *p - '0';
+		}
+
+		if (*p=='m') {
+			wcs = 0;
+			s = 0;
+			alloc = !!dest;
+			p++;
+		} else {
+			alloc = 0;
+		}
+
+		size = SIZE_def;
+		switch (*p++) {
+		case 'h':
+			if (*p == 'h') p++, size = SIZE_hh;
+			else size = SIZE_h;
+			break;
+		case 'l':
+			if (*p == 'l') p++, size = SIZE_ll;
+			else size = SIZE_l;
+			break;
+		case 'j':
+			size = SIZE_ll;
+			break;
+		case 'z':
+		case 't':
+			size = SIZE_l;
+			break;
+		case 'L':
+			size = SIZE_L;
+			break;
+		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'a': case 'e': case 'f': case 'g':
+		case 'A': case 'E': case 'F': case 'G': case 'X':
+		case 's': case 'c': case '[':
+		case 'S': case 'C':
+		case 'p': case 'n':
+			p--;
+			break;
+		default:
+			goto fmt_fail;
+		}
+
+		t = *p;
+
+		/* Transform S,C -> ls,lc */
+		if ((t&0x2f)==3) {
+			size = SIZE_l;
+			t |= 32;
+		}
+
+		if (t != 'n') {
+			if (t != '[' && (t|32) != 'c')
+				while (iswspace((c=getwc(f)))) pos++;
+			else
+				c=getwc(f);
+			if (c < 0) goto input_fail;
+			ungetwc(c, f);
+		}
+
+		switch (t) {
+		case 'n':
+			store_int(dest, size, pos);
+			/* do not increment match count, etc! */
+			continue;
+
+		case 's':
+		case 'c':
+		case '[':
+			if (t == 'c') {
+				if (width<1) width = 1;
+				invert = 1;
+				set = L"";
+			} else if (t == 's') {
+				invert = 1;
+				static const wchar_t spaces[] = {
+					' ', '\t', '\n', '\r', 11, 12,  0x0085,
+					0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,
+					0x2006, 0x2008, 0x2009, 0x200a,
+					0x2028, 0x2029, 0x205f, 0x3000, 0 };
+				set = spaces;
+			} else {
+				if (*++p == '^') p++, invert = 1;
+				else invert = 0;
+				set = p;
+				if (*p==']') p++;
+				while (*p!=']') {
+					if (!*p) goto fmt_fail;
+					p++;
+				}
+			}
+
+			s = (size == SIZE_def) ? dest : 0;
+			wcs = (size == SIZE_l) ? dest : 0;
+
+			int gotmatch = 0;
+
+			if (width < 1) width = -1;
+
+			i = 0;
+			if (alloc) {
+				k = t=='c' ? width+1U : 31;
+				if (size == SIZE_l) {
+					wcs = malloc(k*sizeof(wchar_t));
+					if (!wcs) goto alloc_fail;
+				} else {
+					s = malloc(k);
+					if (!s) goto alloc_fail;
+				}
+			}
+			while (width) {
+				if ((c=getwc(f))<0) break;
+				if (in_set(set, c) == invert)
+					break;
+				if (wcs) {
+					wcs[i++] = c;
+					if (alloc && i==k) {
+						k += k+1;
+						wchar_t *tmp = realloc(wcs, k*sizeof(wchar_t));
+						if (!tmp) goto alloc_fail;
+						wcs = tmp;
+					}
+				} else if (size != SIZE_l) {
+					int l = wctomb(s?s+i:tmp, c);
+					if (l<0) goto input_fail;
+					i += l;
+					if (alloc && i > k-4) {
+						k += k+1;
+						char *tmp = realloc(s, k);
+						if (!tmp) goto alloc_fail;
+						s = tmp;
+					}
+				}
+				pos++;
+				width-=(width>0);
+				gotmatch=1;
+			}
+			if (width) {
+				ungetwc(c, f);
+				if (t == 'c' || !gotmatch) goto match_fail;
+			}
+
+			if (alloc) {
+				if (size == SIZE_l) *(wchar_t **)dest = wcs;
+				else *(char **)dest = s;
+			}
+			if (t != 'c') {
+				if (wcs) wcs[i] = 0;
+				if (s) s[i] = 0;
+			}
+			break;
+
+		case 'd': case 'i': case 'o': case 'u': case 'x':
+		case 'a': case 'e': case 'f': case 'g':
+		case 'A': case 'E': case 'F': case 'G': case 'X':
+		case 'p':
+			if (width < 1) width = 0;
+			snprintf(tmp, sizeof tmp, "%.*s%.0d%s%c%%lln",
+				1+!dest, "%*", width, size_pfx[size+2], t);
+			cnt = 0;
+			if (fscanf(f, tmp, dest?dest:&cnt, &cnt) == -1)
+				goto input_fail;
+			else if (!cnt)
+				goto match_fail;
+			pos += cnt;
+			break;
+		default:
+			goto fmt_fail;
+		}
+
+		if (dest) matches++;
+	}
+	if (0) {
+fmt_fail:
+alloc_fail:
+input_fail:
+		if (!matches) matches--;
+match_fail:
+		if (alloc) {
+			free(s);
+			free(wcs);
+		}
+	}
+	FUNLOCK(f);
+	return matches;
+}
+
+weak_alias(vfwscanf,__isoc99_vfwscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vprintf.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int vprintf(const char *restrict fmt, va_list ap)
+{
+	return vfprintf(stdout, fmt, ap);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vscanf.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include "libc.h"
+
+int vscanf(const char *restrict fmt, va_list ap)
+{
+	return vfscanf(stdin, fmt, ap);
+}
+
+weak_alias(vscanf,__isoc99_vscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vsnprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vsnprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vsnprintf.c	(revision 398)
@@ -0,0 +1,55 @@
+#include "stdio_impl.h"
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+
+struct cookie {
+	char *s;
+	size_t n;
+};
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+static size_t sn_write(FILE *f, const unsigned char *s, size_t l)
+{
+	struct cookie *c = f->cookie;
+	size_t k = MIN(c->n, f->wpos - f->wbase);
+	if (k) {
+		memcpy(c->s, f->wbase, k);
+		c->s += k;
+		c->n -= k;
+	}
+	k = MIN(c->n, l);
+	if (k) {
+		memcpy(c->s, s, k);
+		c->s += k;
+		c->n -= k;
+	}
+	*c->s = 0;
+	f->wpos = f->wbase = f->buf;
+	/* pretend to succeed, even if we discarded extra data */
+	return l;
+}
+
+int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)
+{
+	unsigned char buf[1];
+	char dummy[1];
+	struct cookie c = { .s = n ? s : dummy, .n = n ? n-1 : 0 };
+	FILE f = {
+		.lbf = EOF,
+		.write = sn_write,
+		.lock = -1,
+		.buf = buf,
+		.cookie = &c,
+	};
+
+	if (n > INT_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+
+	*c.s = 0;
+	return vfprintf(&f, fmt, ap);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vsprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vsprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vsprintf.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <limits.h>
+
+int vsprintf(char *restrict s, const char *restrict fmt, va_list ap)
+{
+	return vsnprintf(s, INT_MAX, fmt, ap);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vsscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vsscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vsscanf.c	(revision 398)
@@ -0,0 +1,18 @@
+#include "stdio_impl.h"
+#include "libc.h"
+
+static size_t do_read(FILE *f, unsigned char *buf, size_t len)
+{
+	return __string_read(f, buf, len);
+}
+
+int vsscanf(const char *restrict s, const char *restrict fmt, va_list ap)
+{
+	FILE f = {
+		.buf = (void *)s, .cookie = (void *)s,
+		.read = do_read, .lock = -1
+	};
+	return vfscanf(&f, fmt, ap);
+}
+
+weak_alias(vsscanf,__isoc99_vsscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vswprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vswprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vswprintf.c	(revision 398)
@@ -0,0 +1,60 @@
+#include "stdio_impl.h"
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <wchar.h>
+
+struct cookie {
+	wchar_t *ws;
+	size_t l;
+};
+
+static size_t sw_write(FILE *f, const unsigned char *s, size_t l)
+{
+	size_t l0 = l;
+	int i = 0;
+	struct cookie *c = f->cookie;
+	if (s!=f->wbase && sw_write(f, f->wbase, f->wpos-f->wbase)==-1)
+		return -1;
+	while (c->l && l && (i=mbtowc(c->ws, (void *)s, l))>=0) {
+		s+=i;
+		l-=i;
+		c->l--;
+		c->ws++;
+	}
+	*c->ws = 0;
+	if (i < 0) {
+		f->wpos = f->wbase = f->wend = 0;
+		f->flags |= F_ERR;
+		return i;
+	}
+	f->wend = f->buf + f->buf_size;
+	f->wpos = f->wbase = f->buf;
+	return l0;
+}
+
+int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_list ap)
+{
+	int r;
+	FILE f;
+	unsigned char buf[256];
+	struct cookie c = { s, n-1 };
+
+	memset(&f, 0, sizeof(FILE));
+	f.lbf = EOF;
+	f.write = sw_write;
+	f.buf_size = sizeof buf;
+	f.buf = buf;
+	f.lock = -1;
+	f.cookie = &c;
+	if (!n) {
+		return -1;
+	} else if (n > INT_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+	r = vfwprintf(&f, fmt, ap);
+	sw_write(&f, 0, 0);
+	return r>=n ? -1 : r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vswscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vswscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vswscanf.c	(revision 398)
@@ -0,0 +1,39 @@
+#include "stdio_impl.h"
+#include "libc.h"
+#include <wchar.h>
+
+static size_t wstring_read(FILE *f, unsigned char *buf, size_t len)
+{
+	const wchar_t *src = f->cookie;
+	size_t k;
+
+	if (!src) return 0;
+
+	k = wcsrtombs((void *)f->buf, &src, f->buf_size, 0);
+	if (k==(size_t)-1) {
+		f->rpos = f->rend = 0;
+		return 0;
+	}
+
+	f->rpos = f->buf;
+	f->rend = f->buf + k;
+	f->cookie = (void *)src;
+
+	if (!len || !k) return 0;
+
+	*buf = *f->rpos++;
+	return 1;
+}
+
+int vswscanf(const wchar_t *restrict s, const wchar_t *restrict fmt, va_list ap)
+{
+	unsigned char buf[256];
+	FILE f = {
+		.buf = buf, .buf_size = sizeof buf,
+		.cookie = (void *)s,
+		.read = wstring_read, .lock = -1
+	};
+	return vfwscanf(&f, fmt, ap);
+}
+
+weak_alias(vswscanf,__isoc99_vswscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vwprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vwprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vwprintf.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <wchar.h>
+
+int vwprintf(const wchar_t *restrict fmt, va_list ap)
+{
+	return vfwprintf(stdout, fmt, ap);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vwscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vwscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/vwscanf.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+#include "libc.h"
+
+int vwscanf(const wchar_t *restrict fmt, va_list ap)
+{
+	return vfwscanf(stdin, fmt, ap);
+}
+
+weak_alias(vwscanf,__isoc99_vwscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/wprintf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/wprintf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/wprintf.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+
+int wprintf(const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vwprintf(fmt, ap);
+	va_end(ap);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/wscanf.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/wscanf.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdio/wscanf.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+#include "libc.h"
+
+int wscanf(const wchar_t *restrict fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vwscanf(fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
+weak_alias(wscanf,__isoc99_wscanf);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/abs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/abs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/abs.c	(revision 398)
@@ -0,0 +1,4 @@
+int abs(int a)
+{
+	return a>0 ? a : -a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atof.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atof.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atof.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+double atof(const char *s)
+{
+	return strtod(s, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atoi.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atoi.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atoi.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+int atoi(const char *s)
+{
+	int n=0, neg=0;
+	while (isspace(*s)) s++;
+	switch (*s) {
+	case '-': neg=1;
+	case '+': s++;
+	}
+	/* Compute n as a negative number to avoid overflow on INT_MIN */
+	while (isdigit(*s))
+		n = 10*n - (*s++ - '0');
+	return neg ? n : -n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atol.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atol.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atol.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+long atol(const char *s)
+{
+	long n=0;
+	int neg=0;
+	while (isspace(*s)) s++;
+	switch (*s) {
+	case '-': neg=1;
+	case '+': s++;
+	}
+	/* Compute n as a negative number to avoid overflow on LONG_MIN */
+	while (isdigit(*s))
+		n = 10*n - (*s++ - '0');
+	return neg ? n : -n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atoll.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atoll.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/atoll.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <ctype.h>
+
+long long atoll(const char *s)
+{
+	long long n=0;
+	int neg=0;
+	while (isspace(*s)) s++;
+	switch (*s) {
+	case '-': neg=1;
+	case '+': s++;
+	}
+	/* Compute n as a negative number to avoid overflow on LLONG_MIN */
+	while (isdigit(*s))
+		n = 10*n - (*s++ - '0');
+	return neg ? n : -n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/bsearch.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/bsearch.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/bsearch.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <stdlib.h>
+
+void *bsearch(const void *key, const void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *))
+{
+	void *try;
+	int sign;
+	while (nel > 0) {
+		try = (char *)base + width*(nel/2);
+		sign = cmp(key, try);
+		if (!sign) return try;
+		else if (nel == 1) break;
+		else if (sign < 0)
+			nel /= 2;
+		else {
+			base = try;
+			nel -= nel/2;
+		}
+	}
+	return NULL;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/div.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/div.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/div.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+div_t div(int num, int den)
+{
+	return (div_t){ num/den, num%den };
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/ecvt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/ecvt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/ecvt.c	(revision 398)
@@ -0,0 +1,20 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+
+char *ecvt(double x, int n, int *dp, int *sign)
+{
+	static char buf[16];
+	char tmp[32];
+	int i, j;
+
+	if (n-1U > 15) n = 15;
+	sprintf(tmp, "%.*e", n-1, x);
+	i = *sign = (tmp[0]=='-');
+	for (j=0; tmp[i]!='e'; j+=(tmp[i++]!='.'))
+		buf[j] = tmp[i];
+	buf[j] = 0;
+	*dp = atoi(tmp+i+1)+1;
+
+	return buf;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/fcvt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/fcvt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/fcvt.c	(revision 398)
@@ -0,0 +1,25 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+char *fcvt(double x, int n, int *dp, int *sign)
+{
+	char tmp[1500];
+	int i, lz;
+
+	if (n > 1400U) n = 1400;
+	sprintf(tmp, "%.*f", n, x);
+	i = (tmp[0] == '-');
+	if (tmp[i] == '0') lz = strspn(tmp+i+2, "0");
+	else lz = -(int)strcspn(tmp+i, ".");
+
+	if (n<=lz) {
+		*sign = i;
+		*dp = 1;
+		if (n>14U) n = 14;
+		return "000000000000000"+14-n;
+	}
+
+	return ecvt(x, n-lz, dp, sign);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/gcvt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/gcvt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/gcvt.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+
+char *gcvt(double x, int n, char *b)
+{
+	sprintf(b, "%.*g", n, x);
+	return b;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/imaxabs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/imaxabs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/imaxabs.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <inttypes.h>
+
+intmax_t imaxabs(intmax_t a)
+{
+	return a>0 ? a : -a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/imaxdiv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/imaxdiv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/imaxdiv.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <inttypes.h>
+
+imaxdiv_t imaxdiv(intmax_t num, intmax_t den)
+{
+	return (imaxdiv_t){ num/den, num%den };
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/labs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/labs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/labs.c	(revision 398)
@@ -0,0 +1,4 @@
+long labs(long a)
+{
+	return a>0 ? a : -a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/ldiv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/ldiv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/ldiv.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+ldiv_t ldiv(long num, long den)
+{
+	return (ldiv_t){ num/den, num%den };
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/llabs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/llabs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/llabs.c	(revision 398)
@@ -0,0 +1,4 @@
+long long llabs(long long a)
+{
+	return a>0 ? a : -a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/lldiv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/lldiv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/lldiv.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+lldiv_t lldiv(long long num, long long den)
+{
+	return (lldiv_t){ num/den, num%den };
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/qsort.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/qsort.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/qsort.c	(revision 398)
@@ -0,0 +1,218 @@
+/* Copyright (C) 2011 by Valentin Ochs
+ *
+ * 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.
+ */
+
+/* Minor changes by Rich Felker for integration in musl, 2011-04-27. */
+
+/* Smoothsort, an adaptive variant of Heapsort.  Memory usage: O(1).
+   Run time: Worst case O(n log n), close to O(n) in the mostly-sorted case. */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "atomic.h"
+#define ntz(x) a_ctz_l((x))
+
+typedef int (*cmpfun)(const void *, const void *);
+
+static inline int pntz(size_t p[2]) {
+	int r = ntz(p[0] - 1);
+	if(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) {
+		return r;
+	}
+	return 0;
+}
+
+static void cycle(size_t width, unsigned char* ar[], int n)
+{
+	unsigned char tmp[256];
+	size_t l;
+	int i;
+
+	if(n < 2) {
+		return;
+	}
+
+	ar[n] = tmp;
+	while(width) {
+		l = sizeof(tmp) < width ? sizeof(tmp) : width;
+		memcpy(ar[n], ar[0], l);
+		for(i = 0; i < n; i++) {
+			memcpy(ar[i], ar[i + 1], l);
+			ar[i] += l;
+		}
+		width -= l;
+	}
+}
+
+/* shl() and shr() need n > 0 */
+static inline void shl(size_t p[2], int n)
+{
+	if(n >= 8 * sizeof(size_t)) {
+		n -= 8 * sizeof(size_t);
+		p[1] = p[0];
+		p[0] = 0;
+	}
+	p[1] <<= n;
+	p[1] |= p[0] >> (sizeof(size_t) * 8 - n);
+	p[0] <<= n;
+}
+
+static inline void shr(size_t p[2], int n)
+{
+	if(n >= 8 * sizeof(size_t)) {
+		n -= 8 * sizeof(size_t);
+		p[0] = p[1];
+		p[1] = 0;
+	}
+	p[0] >>= n;
+	p[0] |= p[1] << (sizeof(size_t) * 8 - n);
+	p[1] >>= n;
+}
+
+static void sift(unsigned char *head, size_t width, cmpfun cmp, int pshift, size_t lp[])
+{
+	unsigned char *rt, *lf;
+	unsigned char *ar[14 * sizeof(size_t) + 1];
+	int i = 1;
+
+	ar[0] = head;
+	while(pshift > 1) {
+		rt = head - width;
+		lf = head - width - lp[pshift - 2];
+
+		if((*cmp)(ar[0], lf) >= 0 && (*cmp)(ar[0], rt) >= 0) {
+			break;
+		}
+		if((*cmp)(lf, rt) >= 0) {
+			ar[i++] = lf;
+			head = lf;
+			pshift -= 1;
+		} else {
+			ar[i++] = rt;
+			head = rt;
+			pshift -= 2;
+		}
+	}
+	cycle(width, ar, i);
+}
+
+static void trinkle(unsigned char *head, size_t width, cmpfun cmp, size_t pp[2], int pshift, int trusty, size_t lp[])
+{
+	unsigned char *stepson,
+	              *rt, *lf;
+	size_t p[2];
+	unsigned char *ar[14 * sizeof(size_t) + 1];
+	int i = 1;
+	int trail;
+
+	p[0] = pp[0];
+	p[1] = pp[1];
+
+	ar[0] = head;
+	while(p[0] != 1 || p[1] != 0) {
+		stepson = head - lp[pshift];
+		if((*cmp)(stepson, ar[0]) <= 0) {
+			break;
+		}
+		if(!trusty && pshift > 1) {
+			rt = head - width;
+			lf = head - width - lp[pshift - 2];
+			if((*cmp)(rt, stepson) >= 0 || (*cmp)(lf, stepson) >= 0) {
+				break;
+			}
+		}
+
+		ar[i++] = stepson;
+		head = stepson;
+		trail = pntz(p);
+		shr(p, trail);
+		pshift += trail;
+		trusty = 0;
+	}
+	if(!trusty) {
+		cycle(width, ar, i);
+		sift(head, width, cmp, pshift, lp);
+	}
+}
+
+void qsort(void *base, size_t nel, size_t width, cmpfun cmp)
+{
+	size_t lp[12*sizeof(size_t)];
+	size_t i, size = width * nel;
+	unsigned char *head, *high;
+	size_t p[2] = {1, 0};
+	int pshift = 1;
+	int trail;
+
+	if (!size) return;
+
+	head = base;
+	high = head + size - width;
+
+	/* Precompute Leonardo numbers, scaled by element width */
+	for(lp[0]=lp[1]=width, i=2; (lp[i]=lp[i-2]+lp[i-1]+width) < size; i++);
+
+	while(head < high) {
+		if((p[0] & 3) == 3) {
+			sift(head, width, cmp, pshift, lp);
+			shr(p, 2);
+			pshift += 2;
+		} else {
+			if(lp[pshift - 1] >= high - head) {
+				trinkle(head, width, cmp, p, pshift, 0, lp);
+			} else {
+				sift(head, width, cmp, pshift, lp);
+			}
+			
+			if(pshift == 1) {
+				shl(p, 1);
+				pshift = 0;
+			} else {
+				shl(p, pshift - 1);
+				pshift = 1;
+			}
+		}
+		
+		p[0] |= 1;
+		head += width;
+	}
+
+	trinkle(head, width, cmp, p, pshift, 0, lp);
+
+	while(pshift != 1 || p[0] != 1 || p[1] != 0) {
+		if(pshift <= 1) {
+			trail = pntz(p);
+			shr(p, trail);
+			pshift += trail;
+		} else {
+			shl(p, 2);
+			pshift -= 2;
+			p[0] ^= 7;
+			shr(p, 1);
+			trinkle(head - lp[pshift] - width, width, cmp, p, pshift + 1, 1, lp);
+			shl(p, 1);
+			p[0] |= 1;
+			trinkle(head - width, width, cmp, p, pshift, 1, lp);
+		}
+		head -= width;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/strtod.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/strtod.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/strtod.c	(revision 398)
@@ -0,0 +1,40 @@
+#include <stdlib.h>
+#include "shgetc.h"
+#include "floatscan.h"
+#include "stdio_impl.h"
+#include "libc.h"
+
+static long double strtox(const char *s, char **p, int prec)
+{
+	FILE f = {
+		.buf = (void *)s, .rpos = (void *)s,
+		.rend = (void *)-1, .lock = -1
+	};
+	shlim(&f, 0);
+	long double y = __floatscan(&f, prec, 1);
+	off_t cnt = shcnt(&f);
+	if (p) *p = cnt ? (char *)s + cnt : (char *)s;
+	return y;
+}
+
+float strtof(const char *restrict s, char **restrict p)
+{
+	return strtox(s, p, 0);
+}
+
+double strtod(const char *restrict s, char **restrict p)
+{
+	return strtox(s, p, 1);
+}
+
+long double strtold(const char *restrict s, char **restrict p)
+{
+	return strtox(s, p, 2);
+}
+
+weak_alias(strtof, strtof_l);
+weak_alias(strtod, strtod_l);
+weak_alias(strtold, strtold_l);
+weak_alias(strtof, __strtof_l);
+weak_alias(strtod, __strtod_l);
+weak_alias(strtold, __strtold_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/strtol.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/strtol.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/strtol.c	(revision 398)
@@ -0,0 +1,64 @@
+#include "stdio_impl.h"
+#include "intscan.h"
+#include "shgetc.h"
+#include <inttypes.h>
+#include <limits.h>
+#include <ctype.h>
+#include "libc.h"
+
+static unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim)
+{
+	/* FIXME: use a helper function or macro to setup the FILE */
+	FILE f;
+	f.flags = 0;
+	f.buf = f.rpos = (void *)s;
+	if ((size_t)s > (size_t)-1/2)
+		f.rend = (void *)-1;
+	else
+		f.rend = (unsigned char *)s+(size_t)-1/2;
+	f.lock = -1;
+	shlim(&f, 0);
+	unsigned long long y = __intscan(&f, base, 1, lim);
+	if (p) {
+		size_t cnt = shcnt(&f);
+		*p = (char *)s + cnt;
+	}
+	return y;
+}
+
+unsigned long long strtoull(const char *restrict s, char **restrict p, int base)
+{
+	return strtox(s, p, base, ULLONG_MAX);
+}
+
+long long strtoll(const char *restrict s, char **restrict p, int base)
+{
+	return strtox(s, p, base, LLONG_MIN);
+}
+
+unsigned long strtoul(const char *restrict s, char **restrict p, int base)
+{
+	return strtox(s, p, base, ULONG_MAX);
+}
+
+long strtol(const char *restrict s, char **restrict p, int base)
+{
+	return strtox(s, p, base, 0UL+LONG_MIN);
+}
+
+intmax_t strtoimax(const char *restrict s, char **restrict p, int base)
+{
+	return strtoll(s, p, base);
+}
+
+uintmax_t strtoumax(const char *restrict s, char **restrict p, int base)
+{
+	return strtoull(s, p, base);
+}
+
+weak_alias(strtol, __strtol_internal);
+weak_alias(strtoul, __strtoul_internal);
+weak_alias(strtoll, __strtoll_internal);
+weak_alias(strtoull, __strtoull_internal);
+weak_alias(strtoimax, __strtoimax_internal);
+weak_alias(strtoumax, __strtoumax_internal);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/wcstod.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/wcstod.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/wcstod.c	(revision 398)
@@ -0,0 +1,65 @@
+#include "shgetc.h"
+#include "floatscan.h"
+#include "stdio_impl.h"
+#include <wchar.h>
+#include <wctype.h>
+
+/* This read function heavily cheats. It knows:
+ *  (1) len will always be 1
+ *  (2) non-ascii characters don't matter */
+
+static size_t do_read(FILE *f, unsigned char *buf, size_t len)
+{
+	size_t i;
+	const wchar_t *wcs = f->cookie;
+
+	if (!wcs[0]) wcs=L"@";
+	for (i=0; i<f->buf_size && wcs[i]; i++)
+		f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
+	f->rpos = f->buf;
+	f->rend = f->buf + i;
+	f->cookie = (void *)(wcs+i);
+
+	if (i && len) {
+		*buf = *f->rpos++;
+		return 1;
+	}
+	return 0;
+}
+
+static long double wcstox(const wchar_t *s, wchar_t **p, int prec)
+{
+	wchar_t *t = (wchar_t *)s;
+	unsigned char buf[64];
+	FILE f = {0};
+	f.flags = 0;
+	f.rpos = f.rend = 0;
+	f.buf = buf + 4;
+	f.buf_size = sizeof buf - 4;
+	f.lock = -1;
+	f.read = do_read;
+	while (iswspace(*t)) t++;
+	f.cookie = (void *)t;
+	shlim(&f, 0);
+	long double y = __floatscan(&f, prec, 1);
+	if (p) {
+		size_t cnt = shcnt(&f);
+		*p = cnt ? t + cnt : (wchar_t *)s;
+	}
+	return y;
+}
+
+float wcstof(const wchar_t *restrict s, wchar_t **restrict p)
+{
+	return wcstox(s, p, 0);
+}
+
+double wcstod(const wchar_t *restrict s, wchar_t **restrict p)
+{
+	return wcstox(s, p, 1);
+}
+
+long double wcstold(const wchar_t *restrict s, wchar_t **restrict p)
+{
+	return wcstox(s, p, 2);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/wcstol.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/wcstol.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/stdlib/wcstol.c	(revision 398)
@@ -0,0 +1,82 @@
+#include "stdio_impl.h"
+#include "intscan.h"
+#include "shgetc.h"
+#include <inttypes.h>
+#include <limits.h>
+#include <wctype.h>
+#include <wchar.h>
+
+/* This read function heavily cheats. It knows:
+ *  (1) len will always be 1
+ *  (2) non-ascii characters don't matter */
+
+static size_t do_read(FILE *f, unsigned char *buf, size_t len)
+{
+	size_t i;
+	const wchar_t *wcs = f->cookie;
+
+	if (!wcs[0]) wcs=L"@";
+	for (i=0; i<f->buf_size && wcs[i]; i++)
+		f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
+	f->rpos = f->buf;
+	f->rend = f->buf + i;
+	f->cookie = (void *)(wcs+i);
+
+	if (i && len) {
+		*buf = *f->rpos++;
+		return 1;
+	}
+	return 0;
+}
+
+static unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsigned long long lim)
+{
+	wchar_t *t = (wchar_t *)s;
+	unsigned char buf[64];
+	FILE f = {0};
+	f.flags = 0;
+	f.rpos = f.rend = 0;
+	f.buf = buf + 4;
+	f.buf_size = sizeof buf - 4;
+	f.lock = -1;
+	f.read = do_read;
+	while (iswspace(*t)) t++;
+	f.cookie = (void *)t;
+	shlim(&f, 0);
+	unsigned long long y = __intscan(&f, base, 1, lim);
+	if (p) {
+		size_t cnt = shcnt(&f);
+		*p = cnt ? t + cnt : (wchar_t *)s;
+	}
+	return y;
+}
+
+unsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstox(s, p, base, ULLONG_MAX);
+}
+
+long long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstox(s, p, base, LLONG_MIN);
+}
+
+unsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstox(s, p, base, ULONG_MAX);
+}
+
+long wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstox(s, p, base, 0UL+LONG_MIN);
+}
+
+intmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstoll(s, p, base);
+}
+
+uintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base)
+{
+	return wcstoull(s, p, base);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/bcmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/bcmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/bcmp.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <strings.h>
+
+int bcmp(const void *s1, const void *s2, size_t n)
+{
+	return memcmp(s1, s2, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/bcopy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/bcopy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/bcopy.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <strings.h>
+
+void bcopy(const void *s1, void *s2, size_t n)
+{
+	memmove(s2, s1, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/bzero.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/bzero.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/bzero.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <strings.h>
+
+void bzero(void *s, size_t n)
+{
+	memset(s, 0, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/index.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/index.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/index.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <strings.h>
+
+char *index(const char *s, int c)
+{
+	return strchr(s, c);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memccpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memccpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memccpy.c	(revision 398)
@@ -0,0 +1,31 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+void *memccpy(void *restrict dest, const void *restrict src, int c, size_t n)
+{
+	unsigned char *d = dest;
+	const unsigned char *s = src;
+	size_t *wd, k;
+	const size_t *ws;
+
+	c = (unsigned char)c;
+	if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
+		for (; ((uintptr_t)s & ALIGN) && n && (*d=*s)!=c; n--, s++, d++);
+		if ((uintptr_t)s & ALIGN) goto tail;
+		k = ONES * c;
+		wd=(void *)d; ws=(const void *)s;
+		for (; n>=sizeof(size_t) && !HASZERO(*ws^k);
+		       n-=sizeof(size_t), ws++, wd++) *wd = *ws;
+		d=(void *)wd; s=(const void *)ws;
+	}
+	for (; n && (*d=*s)!=c; n--, s++, d++);
+tail:
+	if (*s==c) return d+1;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memchr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memchr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memchr.c	(revision 398)
@@ -0,0 +1,23 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define SS (sizeof(size_t))
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+void *memchr(const void *src, int c, size_t n)
+{
+	const unsigned char *s = src;
+	c = (unsigned char)c;
+	for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--);
+	if (n && *s != c) {
+		const size_t *w;
+		size_t k = ONES * c;
+		for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS);
+		for (s = (const void *)w; n && *s != c; s++, n--);
+	}
+	return n ? (void *)s : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memcmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memcmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memcmp.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <string.h>
+
+int memcmp(const void *vl, const void *vr, size_t n)
+{
+	const unsigned char *l=vl, *r=vr;
+	for (; n && *l == *r; n--, l++, r++);
+	return n ? *l-*r : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memcpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memcpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memcpy.c	(revision 398)
@@ -0,0 +1,124 @@
+#include <string.h>
+#include <stdint.h>
+#include <endian.h>
+
+void *memcpy(void *restrict dest, const void *restrict src, size_t n)
+{
+	unsigned char *d = dest;
+	const unsigned char *s = src;
+
+#ifdef __GNUC__
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define LS >>
+#define RS <<
+#else
+#define LS <<
+#define RS >>
+#endif
+
+	typedef uint32_t __attribute__((__may_alias__)) u32;
+	uint32_t w, x;
+
+	for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++;
+
+	if ((uintptr_t)d % 4 == 0) {
+		for (; n>=16; s+=16, d+=16, n-=16) {
+			*(u32 *)(d+0) = *(u32 *)(s+0);
+			*(u32 *)(d+4) = *(u32 *)(s+4);
+			*(u32 *)(d+8) = *(u32 *)(s+8);
+			*(u32 *)(d+12) = *(u32 *)(s+12);
+		}
+		if (n&8) {
+			*(u32 *)(d+0) = *(u32 *)(s+0);
+			*(u32 *)(d+4) = *(u32 *)(s+4);
+			d += 8; s += 8;
+		}
+		if (n&4) {
+			*(u32 *)(d+0) = *(u32 *)(s+0);
+			d += 4; s += 4;
+		}
+		if (n&2) {
+			*d++ = *s++; *d++ = *s++;
+		}
+		if (n&1) {
+			*d = *s;
+		}
+		return dest;
+	}
+
+	if (n >= 32) switch ((uintptr_t)d % 4) {
+	case 1:
+		w = *(u32 *)s;
+		*d++ = *s++;
+		*d++ = *s++;
+		*d++ = *s++;
+		n -= 3;
+		for (; n>=17; s+=16, d+=16, n-=16) {
+			x = *(u32 *)(s+1);
+			*(u32 *)(d+0) = (w LS 24) | (x RS 8);
+			w = *(u32 *)(s+5);
+			*(u32 *)(d+4) = (x LS 24) | (w RS 8);
+			x = *(u32 *)(s+9);
+			*(u32 *)(d+8) = (w LS 24) | (x RS 8);
+			w = *(u32 *)(s+13);
+			*(u32 *)(d+12) = (x LS 24) | (w RS 8);
+		}
+		break;
+	case 2:
+		w = *(u32 *)s;
+		*d++ = *s++;
+		*d++ = *s++;
+		n -= 2;
+		for (; n>=18; s+=16, d+=16, n-=16) {
+			x = *(u32 *)(s+2);
+			*(u32 *)(d+0) = (w LS 16) | (x RS 16);
+			w = *(u32 *)(s+6);
+			*(u32 *)(d+4) = (x LS 16) | (w RS 16);
+			x = *(u32 *)(s+10);
+			*(u32 *)(d+8) = (w LS 16) | (x RS 16);
+			w = *(u32 *)(s+14);
+			*(u32 *)(d+12) = (x LS 16) | (w RS 16);
+		}
+		break;
+	case 3:
+		w = *(u32 *)s;
+		*d++ = *s++;
+		n -= 1;
+		for (; n>=19; s+=16, d+=16, n-=16) {
+			x = *(u32 *)(s+3);
+			*(u32 *)(d+0) = (w LS 8) | (x RS 24);
+			w = *(u32 *)(s+7);
+			*(u32 *)(d+4) = (x LS 8) | (w RS 24);
+			x = *(u32 *)(s+11);
+			*(u32 *)(d+8) = (w LS 8) | (x RS 24);
+			w = *(u32 *)(s+15);
+			*(u32 *)(d+12) = (x LS 8) | (w RS 24);
+		}
+		break;
+	}
+	if (n&16) {
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+	}
+	if (n&8) {
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+	}
+	if (n&4) {
+		*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
+	}
+	if (n&2) {
+		*d++ = *s++; *d++ = *s++;
+	}
+	if (n&1) {
+		*d = *s;
+	}
+	return dest;
+#endif
+
+	for (; n; n--) *d++ = *s++;
+	return dest;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memmem.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memmem.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memmem.c	(revision 398)
@@ -0,0 +1,149 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdint.h>
+
+static char *twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+	uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
+	for (h+=2, k-=2; k; k--, hw = hw<<8 | *h++)
+		if (hw == nw) return (char *)h-2;
+	return hw == nw ? (char *)h-2 : 0;
+}
+
+static char *threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
+	for (h+=3, k-=3; k; k--, hw = (hw|*h++)<<8)
+		if (hw == nw) return (char *)h-3;
+	return hw == nw ? (char *)h-3 : 0;
+}
+
+static char *fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
+	for (h+=4, k-=4; k; k--, hw = hw<<8 | *h++)
+		if (hw == nw) return (char *)h-4;
+	return hw == nw ? (char *)h-4 : 0;
+}
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+static char *twoway_memmem(const unsigned char *h, const unsigned char *z, const unsigned char *n, size_t l)
+{
+	size_t i, ip, jp, k, p, ms, p0, mem, mem0;
+	size_t byteset[32 / sizeof(size_t)] = { 0 };
+	size_t shift[256];
+
+	/* Computing length of needle and fill shift table */
+	for (i=0; i<l; i++)
+		BITOP(byteset, n[i], |=), shift[n[i]] = i+1;
+
+	/* Compute maximal suffix */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] > n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	ms = ip;
+	p0 = p;
+
+	/* And with the opposite comparison */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] < n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	if (ip+1 > ms+1) ms = ip;
+	else p = p0;
+
+	/* Periodic needle? */
+	if (memcmp(n, n+p, ms+1)) {
+		mem0 = 0;
+		p = MAX(ms, l-ms-1) + 1;
+	} else mem0 = l-p;
+	mem = 0;
+
+	/* Search loop */
+	for (;;) {
+		/* If remainder of haystack is shorter than needle, done */
+		if (z-h < l) return 0;
+
+		/* Check last byte first; advance by shift on mismatch */
+		if (BITOP(byteset, h[l-1], &)) {
+			k = l-shift[h[l-1]];
+			if (k) {
+				if (mem0 && mem && k < p) k = l-p;
+				h += k;
+				mem = 0;
+				continue;
+			}
+		} else {
+			h += l;
+			mem = 0;
+			continue;
+		}
+
+		/* Compare right half */
+		for (k=MAX(ms+1,mem); k<l && n[k] == h[k]; k++);
+		if (k < l) {
+			h += k-ms;
+			mem = 0;
+			continue;
+		}
+		/* Compare left half */
+		for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+		if (k <= mem) return (char *)h;
+		h += p;
+		mem = mem0;
+	}
+}
+
+void *memmem(const void *h0, size_t k, const void *n0, size_t l)
+{
+	const unsigned char *h = h0, *n = n0;
+
+	/* Return immediately on empty needle */
+	if (!l) return (void *)h;
+
+	/* Return immediately when needle is longer than haystack */
+	if (k<l) return 0;
+
+	/* Use faster algorithms for short needles */
+	h = memchr(h0, *n, k);
+	if (!h || l==1) return (void *)h;
+	k -= h - (const unsigned char *)h0;
+	if (k<l) return 0;
+	if (l==2) return twobyte_memmem(h, k, n);
+	if (l==3) return threebyte_memmem(h, k, n);
+	if (l==4) return fourbyte_memmem(h, k, n);
+
+	return twoway_memmem(h, h+k, n, l);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memmove.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memmove.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memmove.c	(revision 398)
@@ -0,0 +1,36 @@
+#include <string.h>
+#include <stdint.h>
+
+#define WT size_t
+#define WS (sizeof(WT))
+
+void *memmove(void *dest, const void *src, size_t n)
+{
+	char *d = dest;
+	const char *s = src;
+
+	if (d==s) return d;
+	if (s+n <= d || d+n <= s) return memcpy(d, s, n);
+
+	if (d<s) {
+		if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
+			while ((uintptr_t)d % WS) {
+				if (!n--) return dest;
+				*d++ = *s++;
+			}
+			for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s;
+		}
+		for (; n; n--) *d++ = *s++;
+	} else {
+		if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
+			while ((uintptr_t)(d+n) % WS) {
+				if (!n--) return dest;
+				d[n] = s[n];
+			}
+			while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n);
+		}
+		while (n) n--, d[n] = s[n];
+	}
+
+	return dest;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/mempcpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/mempcpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/mempcpy.c	(revision 398)
@@ -0,0 +1,7 @@
+#define _GNU_SOURCE
+#include <string.h>
+
+void *mempcpy(void *dest, const void *src, size_t n)
+{
+	return (char *)memcpy(dest, src, n) + n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memrchr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memrchr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memrchr.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <string.h>
+#include "libc.h"
+
+void *__memrchr(const void *m, int c, size_t n)
+{
+	const unsigned char *s = m;
+	c = (unsigned char)c;
+	while (n--) if (s[n]==c) return (void *)(s+n);
+	return 0;
+}
+
+weak_alias(__memrchr, memrchr);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/memset.c	(revision 398)
@@ -0,0 +1,90 @@
+#include <string.h>
+#include <stdint.h>
+
+void *memset(void *dest, int c, size_t n)
+{
+	unsigned char *s = dest;
+	size_t k;
+
+	/* Fill head and tail with minimal branching. Each
+	 * conditional ensures that all the subsequently used
+	 * offsets are well-defined and in the dest region. */
+
+	if (!n) return dest;
+	s[0] = c;
+	s[n-1] = c;
+	if (n <= 2) return dest;
+	s[1] = c;
+	s[2] = c;
+	s[n-2] = c;
+	s[n-3] = c;
+	if (n <= 6) return dest;
+	s[3] = c;
+	s[n-4] = c;
+	if (n <= 8) return dest;
+
+	/* Advance pointer to align it at a 4-byte boundary,
+	 * and truncate n to a multiple of 4. The previous code
+	 * already took care of any head/tail that get cut off
+	 * by the alignment. */
+
+	k = -(uintptr_t)s & 3;
+	s += k;
+	n -= k;
+	n &= -4;
+
+#ifdef __GNUC__
+	typedef uint32_t __attribute__((__may_alias__)) u32;
+	typedef uint64_t __attribute__((__may_alias__)) u64;
+
+	u32 c32 = ((u32)-1)/255 * (unsigned char)c;
+
+	/* In preparation to copy 32 bytes at a time, aligned on
+	 * an 8-byte bounary, fill head/tail up to 28 bytes each.
+	 * As in the initial byte-based head/tail fill, each
+	 * conditional below ensures that the subsequent offsets
+	 * are valid (e.g. !(n<=24) implies n>=28). */
+
+	*(u32 *)(s+0) = c32;
+	*(u32 *)(s+n-4) = c32;
+	if (n <= 8) return dest;
+	*(u32 *)(s+4) = c32;
+	*(u32 *)(s+8) = c32;
+	*(u32 *)(s+n-12) = c32;
+	*(u32 *)(s+n-8) = c32;
+	if (n <= 24) return dest;
+	*(u32 *)(s+12) = c32;
+	*(u32 *)(s+16) = c32;
+	*(u32 *)(s+20) = c32;
+	*(u32 *)(s+24) = c32;
+	*(u32 *)(s+n-28) = c32;
+	*(u32 *)(s+n-24) = c32;
+	*(u32 *)(s+n-20) = c32;
+	*(u32 *)(s+n-16) = c32;
+
+	/* Align to a multiple of 8 so we can fill 64 bits at a time,
+	 * and avoid writing the same bytes twice as much as is
+	 * practical without introducing additional branching. */
+
+	k = 24 + ((uintptr_t)s & 4);
+	s += k;
+	n -= k;
+
+	/* If this loop is reached, 28 tail bytes have already been
+	 * filled, so any remainder when n drops below 32 can be
+	 * safely ignored. */
+
+	u64 c64 = c32 | ((u64)c32 << 32);
+	for (; n >= 32; n-=32, s+=32) {
+		*(u64 *)(s+0) = c64;
+		*(u64 *)(s+8) = c64;
+		*(u64 *)(s+16) = c64;
+		*(u64 *)(s+24) = c64;
+	}
+#else
+	/* Pure C fallback with no aliasing violations. */
+	for (; n; n--, s++) *s = c;
+#endif
+
+	return dest;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/rindex.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/rindex.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/rindex.c	(revision 398)
@@ -0,0 +1,8 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <strings.h>
+
+char *rindex(const char *s, int c)
+{
+	return strrchr(s, c);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/stpcpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/stpcpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/stpcpy.c	(revision 398)
@@ -0,0 +1,28 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+#include "libc.h"
+
+#define ALIGN (sizeof(size_t))
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+char *__stpcpy(char *restrict d, const char *restrict s)
+{
+	size_t *wd;
+	const size_t *ws;
+
+	if ((uintptr_t)s % ALIGN == (uintptr_t)d % ALIGN) {
+		for (; (uintptr_t)s % ALIGN; s++, d++)
+			if (!(*d=*s)) return d;
+		wd=(void *)d; ws=(const void *)s;
+		for (; !HASZERO(*ws); *wd++ = *ws++);
+		d=(void *)wd; s=(const void *)ws;
+	}
+	for (; (*d=*s); s++, d++);
+
+	return d;
+}
+
+weak_alias(__stpcpy, stpcpy);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/stpncpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/stpncpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/stpncpy.c	(revision 398)
@@ -0,0 +1,31 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+#include "libc.h"
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+char *__stpncpy(char *restrict d, const char *restrict s, size_t n)
+{
+	size_t *wd;
+	const size_t *ws;
+
+	if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
+		for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
+		if (!n || !*s) goto tail;
+		wd=(void *)d; ws=(const void *)s;
+		for (; n>=sizeof(size_t) && !HASZERO(*ws);
+		       n-=sizeof(size_t), ws++, wd++) *wd = *ws;
+		d=(void *)wd; s=(const void *)ws;
+	}
+	for (; n && (*d=*s); n--, s++, d++);
+tail:
+	memset(d, 0, n);
+	return d;
+}
+
+weak_alias(__stpncpy, stpncpy);
+
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcasecmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcasecmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcasecmp.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <strings.h>
+#include <ctype.h>
+#include "libc.h"
+
+int strcasecmp(const char *_l, const char *_r)
+{
+	const unsigned char *l=(void *)_l, *r=(void *)_r;
+	for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++);
+	return tolower(*l) - tolower(*r);
+}
+
+int __strcasecmp_l(const char *l, const char *r, locale_t loc)
+{
+	return strcasecmp(l, r);
+}
+
+weak_alias(__strcasecmp_l, strcasecmp_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcasestr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcasestr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcasestr.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <string.h>
+
+char *strcasestr(const char *h, const char *n)
+{
+	size_t l = strlen(n);
+	for (; *h; h++) if (!strncasecmp(h, n, l)) return (char *)h;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcat.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strcat(char *restrict dest, const char *restrict src)
+{
+	strcpy(dest + strlen(dest), src);
+	return dest;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strchr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strchr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strchr.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <string.h>
+
+char *__strchrnul(const char *, int);
+
+char *strchr(const char *s, int c)
+{
+	char *r = __strchrnul(s, c);
+	return *(unsigned char *)r == (unsigned char)c ? r : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strchrnul.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strchrnul.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strchrnul.c	(revision 398)
@@ -0,0 +1,26 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+#include "libc.h"
+
+#define ALIGN (sizeof(size_t))
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+char *__strchrnul(const char *s, int c)
+{
+	size_t *w, k;
+
+	c = (unsigned char)c;
+	if (!c) return (char *)s + strlen(s);
+
+	for (; (uintptr_t)s % ALIGN; s++)
+		if (!*s || *(unsigned char *)s == c) return (char *)s;
+	k = ONES * c;
+	for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++);
+	for (s = (void *)w; *s && *(unsigned char *)s != c; s++);
+	return (char *)s;
+}
+
+weak_alias(__strchrnul, strchrnul);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcmp.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <string.h>
+
+int strcmp(const char *l, const char *r)
+{
+	for (; *l==*r && *l; l++, r++);
+	return *(unsigned char *)l - *(unsigned char *)r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcpy.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <string.h>
+
+char *__stpcpy(char *, const char *);
+
+char *strcpy(char *restrict dest, const char *restrict src)
+{
+#if 1
+	__stpcpy(dest, src);
+	return dest;
+#else
+	const unsigned char *s = src;
+	unsigned char *d = dest;
+	while ((*d++ = *s++));
+	return dest;
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcspn.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcspn.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strcspn.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <string.h>
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+char *__strchrnul(const char *, int);
+
+size_t strcspn(const char *s, const char *c)
+{
+	const char *a = s;
+	size_t byteset[32/sizeof(size_t)];
+
+	if (!c[0] || !c[1]) return __strchrnul(s, *c)-a;
+
+	memset(byteset, 0, sizeof byteset);
+	for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++);
+	for (; *s && !BITOP(byteset, *(unsigned char *)s, &); s++);
+	return s-a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strdup.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strdup.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strdup.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+#include <string.h>
+#include "libc.h"
+
+char *__strdup(const char *s)
+{
+	size_t l = strlen(s);
+	char *d = malloc(l+1);
+	if (!d) return NULL;
+	return memcpy(d, s, l+1);
+}
+
+weak_alias(__strdup, strdup);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strerror_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strerror_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strerror_r.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <string.h>
+#include <errno.h>
+#include "libc.h"
+
+int strerror_r(int err, char *buf, size_t buflen)
+{
+	char *msg = strerror(err);
+	size_t l = strlen(msg);
+	if (l >= buflen) {
+		if (buflen) {
+			memcpy(buf, msg, buflen-1);
+			buf[buflen-1] = 0;
+		}
+		return ERANGE;
+	}
+	memcpy(buf, msg, l+1);
+	return 0;
+}
+
+weak_alias(strerror_r, __xpg_strerror_r);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strlcat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strlcat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strlcat.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _BSD_SOURCE
+#include <string.h>
+
+size_t strlcat(char *d, const char *s, size_t n)
+{
+	size_t l = strnlen(d, n);
+	if (l == n) return l + strlen(s);
+	return l + strlcpy(d+l, s, n-l);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strlcpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strlcpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strlcpy.c	(revision 398)
@@ -0,0 +1,32 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+#include "libc.h"
+
+#define ALIGN (sizeof(size_t)-1)
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+size_t strlcpy(char *d, const char *s, size_t n)
+{
+	char *d0 = d;
+	size_t *wd;
+	const size_t *ws;
+
+	if (!n--) goto finish;
+	if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
+		for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
+		if (n && *s) {
+			wd=(void *)d; ws=(const void *)s;
+			for (; n>=sizeof(size_t) && !HASZERO(*ws);
+			       n-=sizeof(size_t), ws++, wd++) *wd = *ws;
+			d=(void *)wd; s=(const void *)ws;
+		}
+	}
+	for (; n && (*d=*s); n--, s++, d++);
+	*d = 0;
+finish:
+	return d-d0 + strlen(s);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strlen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strlen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strlen.c	(revision 398)
@@ -0,0 +1,18 @@
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define ALIGN (sizeof(size_t))
+#define ONES ((size_t)-1/UCHAR_MAX)
+#define HIGHS (ONES * (UCHAR_MAX/2+1))
+#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+
+size_t strlen(const char *s)
+{
+	const char *a = s;
+	const size_t *w;
+	for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a;
+	for (w = (const void *)s; !HASZERO(*w); w++);
+	for (s = (const void *)w; *s; s++);
+	return s-a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncasecmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncasecmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncasecmp.c	(revision 398)
@@ -0,0 +1,18 @@
+#include <strings.h>
+#include <ctype.h>
+#include "libc.h"
+
+int strncasecmp(const char *_l, const char *_r, size_t n)
+{
+	const unsigned char *l=(void *)_l, *r=(void *)_r;
+	if (!n--) return 0;
+	for (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--);
+	return tolower(*l) - tolower(*r);
+}
+
+int __strncasecmp_l(const char *l, const char *r, size_t n, locale_t loc)
+{
+	return strncasecmp(l, r, n);
+}
+
+weak_alias(__strncasecmp_l, strncasecmp_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncat.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <string.h>
+
+char *strncat(char *restrict d, const char *restrict s, size_t n)
+{
+	char *a = d;
+	d += strlen(d);
+	while (n && *s) n--, *d++ = *s++;
+	*d++ = 0;
+	return a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncmp.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <string.h>
+
+int strncmp(const char *_l, const char *_r, size_t n)
+{
+	const unsigned char *l=(void *)_l, *r=(void *)_r;
+	if (!n--) return 0;
+	for (; *l && *r && n && *l == *r ; l++, r++, n--);
+	return *l - *r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strncpy.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <string.h>
+
+char *__stpncpy(char *, const char *, size_t);
+
+char *strncpy(char *restrict d, const char *restrict s, size_t n)
+{
+	__stpncpy(d, s, n);
+	return d;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strndup.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strndup.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strndup.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include <string.h>
+
+char *strndup(const char *s, size_t n)
+{
+	size_t l = strnlen(s, n);
+	char *d = malloc(l+1);
+	if (!d) return NULL;
+	memcpy(d, s, l);
+	d[l] = 0;
+	return d;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strnlen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strnlen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strnlen.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <string.h>
+
+size_t strnlen(const char *s, size_t n)
+{
+	const char *p = memchr(s, 0, n);
+	return p ? p-s : n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strpbrk.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strpbrk.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strpbrk.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <string.h>
+
+char *strpbrk(const char *s, const char *b)
+{
+	s += strcspn(s, b);
+	return *s ? (char *)s : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strrchr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strrchr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strrchr.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <string.h>
+
+void *__memrchr(const void *, int, size_t);
+
+char *strrchr(const char *s, int c)
+{
+	return __memrchr(s, c, strlen(s) + 1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strsep.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strsep.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strsep.c	(revision 398)
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <string.h>
+
+char *strsep(char **str, const char *sep)
+{
+	char *s = *str, *end;
+	if (!s) return NULL;
+	end = s + strcspn(s, sep);
+	if (*end) *end++ = 0;
+	else end = 0;
+	*str = end;
+	return s;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strsignal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strsignal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strsignal.c	(revision 398)
@@ -0,0 +1,116 @@
+#include <signal.h>
+#include <string.h>
+#include "locale_impl.h"
+
+#if (SIGHUP == 1) && (SIGINT == 2) && (SIGQUIT == 3) && (SIGILL == 4) \
+ && (SIGTRAP == 5) && (SIGABRT == 6) && (SIGBUS == 7) && (SIGFPE == 8) \
+ && (SIGKILL == 9) && (SIGUSR1 == 10) && (SIGSEGV == 11) && (SIGUSR2 == 12) \
+ && (SIGPIPE == 13) && (SIGALRM == 14) && (SIGTERM == 15) && (SIGSTKFLT == 16) \
+ && (SIGCHLD == 17) && (SIGCONT == 18) && (SIGSTOP == 19) && (SIGTSTP == 20) \
+ && (SIGTTIN == 21) && (SIGTTOU == 22) && (SIGURG == 23) && (SIGXCPU == 24) \
+ && (SIGXFSZ == 25) && (SIGVTALRM == 26) && (SIGPROF == 27) && (SIGWINCH == 28) \
+ && (SIGPOLL == 29) && (SIGPWR == 30) && (SIGSYS == 31)
+
+#define sigmap(x) x
+
+#else
+
+static const char map[] = {
+	[SIGHUP]    = 1,
+	[SIGINT]    = 2,
+	[SIGQUIT]   = 3,
+	[SIGILL]    = 4,
+	[SIGTRAP]   = 5,
+	[SIGABRT]   = 6,
+	[SIGBUS]    = 7,
+	[SIGFPE]    = 8,
+	[SIGKILL]   = 9,
+	[SIGUSR1]   = 10,
+	[SIGSEGV]   = 11,
+	[SIGUSR2]   = 12,
+	[SIGPIPE]   = 13,
+	[SIGALRM]   = 14,
+	[SIGTERM]   = 15,
+	[SIGSTKFLT] = 16,
+	[SIGCHLD]   = 17,
+	[SIGCONT]   = 18,
+	[SIGSTOP]   = 19,
+	[SIGTSTP]   = 20,
+	[SIGTTIN]   = 21,
+	[SIGTTOU]   = 22,
+	[SIGURG]    = 23,
+	[SIGXCPU]   = 24,
+	[SIGXFSZ]   = 25,
+	[SIGVTALRM] = 26,
+	[SIGPROF]   = 27,
+	[SIGWINCH]  = 28,
+	[SIGPOLL]   = 29,
+	[SIGPWR]    = 30,
+	[SIGSYS]    = 31
+};
+
+#define sigmap(x) ((x) >= sizeof map ? (x) : map[(x)])
+
+#endif
+
+static const char strings[] =
+	"Unknown signal\0"
+	"Hangup\0"
+	"Interrupt\0"
+	"Quit\0"
+	"Illegal instruction\0"
+	"Trace/breakpoint trap\0"
+	"Aborted\0"
+	"Bus error\0"
+	"Arithmetic exception\0"
+	"Killed\0"
+	"User defined signal 1\0"
+	"Segmentation fault\0"
+	"User defined signal 2\0"
+	"Broken pipe\0"
+	"Alarm clock\0"
+	"Terminated\0"
+	"Stack fault\0"
+	"Child process status\0"
+	"Continued\0"
+	"Stopped (signal)\0"
+	"Stopped\0"
+	"Stopped (tty input)\0"
+	"Stopped (tty output)\0"
+	"Urgent I/O condition\0"
+	"CPU time limit exceeded\0"
+	"File size limit exceeded\0"
+	"Virtual timer expired\0"
+	"Profiling timer expired\0"
+	"Window changed\0"
+	"I/O possible\0"
+	"Power failure\0"
+	"Bad system call\0"
+	"RT32"
+	"\0RT33\0RT34\0RT35\0RT36\0RT37\0RT38\0RT39\0RT40"
+	"\0RT41\0RT42\0RT43\0RT44\0RT45\0RT46\0RT47\0RT48"
+	"\0RT49\0RT50\0RT51\0RT52\0RT53\0RT54\0RT55\0RT56"
+	"\0RT57\0RT58\0RT59\0RT60\0RT61\0RT62\0RT63\0RT64"
+#if _NSIG > 65
+	"\0RT65\0RT66\0RT67\0RT68\0RT69\0RT70\0RT71\0RT72"
+	"\0RT73\0RT74\0RT75\0RT76\0RT77\0RT78\0RT79\0RT80"
+	"\0RT81\0RT82\0RT83\0RT84\0RT85\0RT86\0RT87\0RT88"
+	"\0RT89\0RT90\0RT91\0RT92\0RT93\0RT94\0RT95\0RT96"
+	"\0RT97\0RT98\0RT99\0RT100\0RT101\0RT102\0RT103\0RT104"
+	"\0RT105\0RT106\0RT107\0RT108\0RT109\0RT110\0RT111\0RT112"
+	"\0RT113\0RT114\0RT115\0RT116\0RT117\0RT118\0RT119\0RT120"
+	"\0RT121\0RT122\0RT123\0RT124\0RT125\0RT126\0RT127\0RT128"
+#endif
+	"";
+
+char *strsignal(int signum)
+{
+	const char *s = strings;
+
+	signum = sigmap(signum);
+	if (signum - 1U >= _NSIG-1) signum = 0;
+
+	for (; signum--; s++) for (; *s; s++);
+
+	return (char *)LCTRANS_CUR(s);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strspn.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strspn.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strspn.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <string.h>
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+size_t strspn(const char *s, const char *c)
+{
+	const char *a = s;
+	size_t byteset[32/sizeof(size_t)] = { 0 };
+
+	if (!c[0]) return 0;
+	if (!c[1]) {
+		for (; *s == *c; s++);
+		return s-a;
+	}
+
+	for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++);
+	for (; *s && BITOP(byteset, *(unsigned char *)s, &); s++);
+	return s-a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strstr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strstr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strstr.c	(revision 398)
@@ -0,0 +1,155 @@
+#include <string.h>
+#include <stdint.h>
+
+static char *twobyte_strstr(const unsigned char *h, const unsigned char *n)
+{
+	uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
+	for (h++; *h && hw != nw; hw = hw<<8 | *++h);
+	return *h ? (char *)h-1 : 0;
+}
+
+static char *threebyte_strstr(const unsigned char *h, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
+	for (h+=2; *h && hw != nw; hw = (hw|*++h)<<8);
+	return *h ? (char *)h-2 : 0;
+}
+
+static char *fourbyte_strstr(const unsigned char *h, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
+	for (h+=3; *h && hw != nw; hw = hw<<8 | *++h);
+	return *h ? (char *)h-3 : 0;
+}
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+static char *twoway_strstr(const unsigned char *h, const unsigned char *n)
+{
+	const unsigned char *z;
+	size_t l, ip, jp, k, p, ms, p0, mem, mem0;
+	size_t byteset[32 / sizeof(size_t)] = { 0 };
+	size_t shift[256];
+
+	/* Computing length of needle and fill shift table */
+	for (l=0; n[l] && h[l]; l++)
+		BITOP(byteset, n[l], |=), shift[n[l]] = l+1;
+	if (n[l]) return 0; /* hit the end of h */
+
+	/* Compute maximal suffix */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] > n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	ms = ip;
+	p0 = p;
+
+	/* And with the opposite comparison */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] < n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	if (ip+1 > ms+1) ms = ip;
+	else p = p0;
+
+	/* Periodic needle? */
+	if (memcmp(n, n+p, ms+1)) {
+		mem0 = 0;
+		p = MAX(ms, l-ms-1) + 1;
+	} else mem0 = l-p;
+	mem = 0;
+
+	/* Initialize incremental end-of-haystack pointer */
+	z = h;
+
+	/* Search loop */
+	for (;;) {
+		/* Update incremental end-of-haystack pointer */
+		if (z-h < l) {
+			/* Fast estimate for MIN(l,63) */
+			size_t grow = l | 63;
+			const unsigned char *z2 = memchr(z, 0, grow);
+			if (z2) {
+				z = z2;
+				if (z-h < l) return 0;
+			} else z += grow;
+		}
+
+		/* Check last byte first; advance by shift on mismatch */
+		if (BITOP(byteset, h[l-1], &)) {
+			k = l-shift[h[l-1]];
+			//printf("adv by %zu (on %c) at [%s] (%zu;l=%zu)\n", k, h[l-1], h, shift[h[l-1]], l);
+			if (k) {
+				if (mem0 && mem && k < p) k = l-p;
+				h += k;
+				mem = 0;
+				continue;
+			}
+		} else {
+			h += l;
+			mem = 0;
+			continue;
+		}
+
+		/* Compare right half */
+		for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
+		if (n[k]) {
+			h += k-ms;
+			mem = 0;
+			continue;
+		}
+		/* Compare left half */
+		for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+		if (k <= mem) return (char *)h;
+		h += p;
+		mem = mem0;
+	}
+}
+
+char *strstr(const char *h, const char *n)
+{
+	/* Return immediately on empty needle */
+	if (!n[0]) return (char *)h;
+
+	/* Use faster algorithms for short needles */
+	h = strchr(h, *n);
+	if (!h || !n[1]) return (char *)h;
+	if (!h[1]) return 0;
+	if (!n[2]) return twobyte_strstr((void *)h, (void *)n);
+	if (!h[2]) return 0;
+	if (!n[3]) return threebyte_strstr((void *)h, (void *)n);
+	if (!h[3]) return 0;
+	if (!n[4]) return fourbyte_strstr((void *)h, (void *)n);
+
+	return twoway_strstr((void *)h, (void *)n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strtok.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strtok.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strtok.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <string.h>
+
+char *strtok(char *restrict s, const char *restrict sep)
+{
+	static char *p;
+	if (!s && !(s = p)) return NULL;
+	s += strspn(s, sep);
+	if (!*s) return p = 0;
+	p = s + strcspn(s, sep);
+	if (*p) *p++ = 0;
+	else p = 0;
+	return s;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strtok_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strtok_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strtok_r.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <string.h>
+
+char *strtok_r(char *restrict s, const char *restrict sep, char **restrict p)
+{
+	if (!s && !(s = *p)) return NULL;
+	s += strspn(s, sep);
+	if (!*s) return *p = 0;
+	*p = s + strcspn(s, sep);
+	if (**p) *(*p)++ = 0;
+	else *p = 0;
+	return s;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strverscmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strverscmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/strverscmp.c	(revision 398)
@@ -0,0 +1,34 @@
+#define _GNU_SOURCE
+#include <ctype.h>
+#include <string.h>
+
+int strverscmp(const char *l0, const char *r0)
+{
+	const unsigned char *l = (const void *)l0;
+	const unsigned char *r = (const void *)r0;
+	size_t i, dp, j;
+	int z = 1;
+
+	/* Find maximal matching prefix and track its maximal digit
+	 * suffix and whether those digits are all zeros. */
+	for (dp=i=0; l[i]==r[i]; i++) {
+		int c = l[i];
+		if (!c) return 0;
+		if (!isdigit(c)) dp=i+1, z=1;
+		else if (c!='0') z=0;
+	}
+
+	if (l[dp]!='0' && r[dp]!='0') {
+		/* If we're not looking at a digit sequence that began
+		 * with a zero, longest digit string is greater. */
+		for (j=i; isdigit(l[j]); j++)
+			if (!isdigit(r[j])) return 1;
+		if (isdigit(r[j])) return -1;
+	} else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) {
+		/* Otherwise, if common prefix of digit sequence is
+		 * all zeros, digits order less than non-digits. */
+		return (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0');
+	}
+
+	return l[i] - r[i];
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/swab.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/swab.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/swab.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <unistd.h>
+
+void swab(const void *restrict _src, void *restrict _dest, ssize_t n)
+{
+	const char *src = _src;
+	char *dest = _dest;
+	for (; n>1; n-=2) {
+		dest[0] = src[1];
+		dest[1] = src[0];
+		dest += 2;
+		src += 2;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcpcpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcpcpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcpcpy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+wchar_t *wcpcpy(wchar_t *restrict d, const wchar_t *restrict s)
+{
+	return wcscpy(d, s) + wcslen(s);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcpncpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcpncpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcpncpy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+wchar_t *wcpncpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
+{
+	return wcsncpy(d, s, n) + wcsnlen(s, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscasecmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscasecmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscasecmp.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <wchar.h>
+#include <wctype.h>
+
+int wcscasecmp(const wchar_t *l, const wchar_t *r)
+{
+	return wcsncasecmp(l, r, -1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscasecmp_l.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscasecmp_l.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscasecmp_l.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+int wcscasecmp_l(const wchar_t *l, const wchar_t *r, locale_t locale)
+{
+	return wcscasecmp(l, r);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscat.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+wchar_t *wcscat(wchar_t *restrict dest, const wchar_t *restrict src)
+{
+	wcscpy(dest + wcslen(dest), src);
+	return dest;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcschr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcschr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcschr.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wcschr(const wchar_t *s, wchar_t c)
+{
+	if (!c) return (wchar_t *)s + wcslen(s);
+	for (; *s && *s != c; s++);
+	return *s ? (wchar_t *)s : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscmp.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+int wcscmp(const wchar_t *l, const wchar_t *r)
+{
+	for (; *l==*r && *l && *r; l++, r++);
+	return *l - *r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscpy.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wcscpy(wchar_t *restrict d, const wchar_t *restrict s)
+{
+	wchar_t *a = d;
+	while ((*d++ = *s++));
+	return a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscspn.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscspn.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcscspn.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <wchar.h>
+
+size_t wcscspn(const wchar_t *s, const wchar_t *c)
+{
+	const wchar_t *a;
+	if (!c[0]) return wcslen(s);
+	if (!c[1]) return (s=wcschr(a=s, *c)) ? s-a : wcslen(a);
+	for (a=s; *s && !wcschr(c, *s); s++);
+	return s-a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsdup.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsdup.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsdup.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <wchar.h>
+#include "libc.h"
+
+wchar_t *wcsdup(const wchar_t *s)
+{
+	size_t l = wcslen(s);
+	wchar_t *d = malloc((l+1)*sizeof(wchar_t));
+	if (!d) return NULL;
+	return wmemcpy(d, s, l+1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcslen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcslen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcslen.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+size_t wcslen(const wchar_t *s)
+{
+	const wchar_t *a;
+	for (a=s; *s; s++);
+	return s-a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncasecmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncasecmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncasecmp.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <wchar.h>
+#include <wctype.h>
+
+int wcsncasecmp(const wchar_t *l, const wchar_t *r, size_t n)
+{
+	if (!n--) return 0;
+	for (; *l && *r && n && (*l == *r || towlower(*l) == towlower(*r)); l++, r++, n--);
+	return towlower(*l) - towlower(*r);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncasecmp_l.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncasecmp_l.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncasecmp_l.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+int wcsncasecmp_l(const wchar_t *l, const wchar_t *r, size_t n, locale_t locale)
+{
+	return wcsncasecmp(l, r, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncat.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <wchar.h>
+
+wchar_t *wcsncat(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
+{
+	wchar_t *a = d;
+	d += wcslen(d);
+	while (n && *s) n--, *d++ = *s++;
+	*d++ = 0;
+	return a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncmp.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+int wcsncmp(const wchar_t *l, const wchar_t *r, size_t n)
+{
+	for (; n && *l==*r && *l && *r; n--, l++, r++);
+	return n ? *l - *r : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsncpy.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <wchar.h>
+
+wchar_t *wcsncpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
+{
+	wchar_t *a = d;
+	while (n && *s) n--, *d++ = *s++;
+	wmemset(d, 0, n);
+	return a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsnlen.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsnlen.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsnlen.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+size_t wcsnlen(const wchar_t *s, size_t n)
+{
+	const wchar_t *z = wmemchr(s, 0, n);
+	if (z) n = z-s;
+	return n;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcspbrk.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcspbrk.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcspbrk.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+wchar_t *wcspbrk(const wchar_t *s, const wchar_t *b)
+{
+	s += wcscspn(s, b);
+	return *s ? (wchar_t *)s : NULL;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsrchr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsrchr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsrchr.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wcsrchr(const wchar_t *s, wchar_t c)
+{
+	const wchar_t *p;
+	for (p=s+wcslen(s); p>=s && *p!=c; p--);
+	return p>=s ? (wchar_t *)p : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsspn.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsspn.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsspn.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+size_t wcsspn(const wchar_t *s, const wchar_t *c)
+{
+	const wchar_t *a;
+	for (a=s; *s && wcschr(c, *s); s++);
+	return s-a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsstr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsstr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcsstr.c	(revision 398)
@@ -0,0 +1,105 @@
+#include <wchar.h>
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+static wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n)
+{
+	const wchar_t *z;
+	size_t l, ip, jp, k, p, ms, p0, mem, mem0;
+
+	/* Computing length of needle */
+	for (l=0; n[l] && h[l]; l++);
+	if (n[l]) return 0; /* hit the end of h */
+
+	/* Compute maximal suffix */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] > n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	ms = ip;
+	p0 = p;
+
+	/* And with the opposite comparison */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] < n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	if (ip+1 > ms+1) ms = ip;
+	else p = p0;
+
+	/* Periodic needle? */
+	if (wmemcmp(n, n+p, ms+1)) {
+		mem0 = 0;
+		p = MAX(ms, l-ms-1) + 1;
+	} else mem0 = l-p;
+	mem = 0;
+
+	/* Initialize incremental end-of-haystack pointer */
+	z = h;
+
+	/* Search loop */
+	for (;;) {
+		/* Update incremental end-of-haystack pointer */
+		if (z-h < l) {
+			/* Fast estimate for MIN(l,63) */
+			size_t grow = l | 63;
+			const wchar_t *z2 = wmemchr(z, 0, grow);
+			if (z2) {
+				z = z2;
+				if (z-h < l) return 0;
+			} else z += grow;
+		}
+
+		/* Compare right half */
+		for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
+		if (n[k]) {
+			h += k-ms;
+			mem = 0;
+			continue;
+		}
+		/* Compare left half */
+		for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+		if (k <= mem) return (wchar_t *)h;
+		h += p;
+		mem = mem0;
+	}
+}
+
+wchar_t *wcsstr(const wchar_t *restrict h, const wchar_t *restrict n)
+{
+	/* Return immediately on empty needle or haystack */
+	if (!n[0]) return (wchar_t *)h;
+	if (!h[0]) return 0;
+
+	/* Use faster algorithms for short needles */
+	h = wcschr(h, *n);
+	if (!h || !n[1]) return (wchar_t *)h;
+	if (!h[1]) return 0;
+
+	return twoway_wcsstr(h, n);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcstok.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcstok.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcstok.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <wchar.h>
+
+wchar_t *wcstok(wchar_t *restrict s, const wchar_t *restrict sep, wchar_t **restrict p)
+{
+	if (!s && !(s = *p)) return NULL;
+	s += wcsspn(s, sep);
+	if (!*s) return *p = 0;
+	*p = s + wcscspn(s, sep);
+	if (**p) *(*p)++ = 0;
+	else *p = 0;
+	return s;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcswcs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcswcs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wcswcs.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <wchar.h>
+
+wchar_t *wcswcs(const wchar_t *haystack, const wchar_t *needle)
+{
+	return wcsstr(haystack, needle);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemchr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemchr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemchr.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)
+{
+	for (; n && *s != c; n--, s++);
+	return n ? (wchar_t *)s : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemcmp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemcmp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemcmp.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <wchar.h>
+
+int wmemcmp(const wchar_t *l, const wchar_t *r, size_t n)
+{
+	for (; n && *l==*r; n--, l++, r++);
+	return n ? *l-*r : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemcpy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemcpy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemcpy.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wmemcpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
+{
+	wchar_t *a = d;
+	while (n--) *d++ = *s++;
+	return a;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemmove.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemmove.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemmove.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <wchar.h>
+
+wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n)
+{
+	wchar_t *d0 = d;
+	if ((size_t)(d-s) < n)
+		while (n--) d[n] = s[n];
+	else
+		while (n--) *d++ = *s++;
+	return d0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemset.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemset.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/string/wmemset.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <wchar.h>
+
+wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n)
+{
+	wchar_t *ret = d;
+	while (n--) *d++ = c;
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/__randname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/__randname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/__randname.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <time.h>
+#include <stdint.h>
+
+int __clock_gettime(clockid_t, struct timespec *);
+
+/* This assumes that a check for the
+   template size has already been made */
+char *__randname(char *template)
+{
+	int i;
+	struct timespec ts;
+	unsigned long r;
+
+	__clock_gettime(CLOCK_REALTIME, &ts);
+	r = ts.tv_nsec*65537 ^ (uintptr_t)&ts / 16 + (uintptr_t)template;
+	for (i=0; i<6; i++, r>>=5)
+		template[i] = 'A'+(r&15)+(r&16)*2;
+
+	return template;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkdtemp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkdtemp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkdtemp.c	(revision 398)
@@ -0,0 +1,25 @@
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+char *__randname(char *);
+
+char *mkdtemp(char *template)
+{
+	size_t l = strlen(template);
+	int retries = 100;
+
+	if (l<6 || memcmp(template+l-6, "XXXXXX", 6)) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	do {
+		__randname(template+l-6);
+		if (!mkdir(template, 0700)) return template;
+	} while (--retries && errno == EEXIST);
+
+	memcpy(template+l-6, "XXXXXX", 6);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkostemp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkostemp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkostemp.c	(revision 398)
@@ -0,0 +1,12 @@
+#define _BSD_SOURCE
+#include <stdlib.h>
+#include "libc.h"
+
+int __mkostemps(char *, int, int);
+
+int mkostemp(char *template, int flags)
+{
+	return __mkostemps(template, 0, flags);
+}
+
+LFS64(mkostemp);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkostemps.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkostemps.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkostemps.c	(revision 398)
@@ -0,0 +1,31 @@
+#define _BSD_SOURCE
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include "libc.h"
+
+char *__randname(char *);
+
+int __mkostemps(char *template, int len, int flags)
+{
+	size_t l = strlen(template);
+	if (l<6 || len>l-6 || memcmp(template+l-len-6, "XXXXXX", 6)) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	flags -= flags & O_ACCMODE;
+	int fd, retries = 100;
+	do {
+		__randname(template+l-len-6);
+		if ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0)
+			return fd;
+	} while (--retries && errno == EEXIST);
+
+	memcpy(template+l-len-6, "XXXXXX", 6);
+	return -1;
+}
+
+weak_alias(__mkostemps, mkostemps);
+weak_alias(__mkostemps, mkostemps64);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkstemp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkstemp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkstemp.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include "libc.h"
+
+int __mkostemps(char *, int, int);
+
+int mkstemp(char *template)
+{
+	return __mkostemps(template, 0, 0);
+}
+
+LFS64(mkstemp);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkstemps.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkstemps.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mkstemps.c	(revision 398)
@@ -0,0 +1,12 @@
+#define _BSD_SOURCE
+#include <stdlib.h>
+#include "libc.h"
+
+int __mkostemps(char *, int, int);
+
+int mkstemps(char *template, int len)
+{
+	return __mkostemps(template, len, 0);
+}
+
+LFS64(mkstemps);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mktemp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mktemp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/temp/mktemp.c	(revision 398)
@@ -0,0 +1,32 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+char *__randname(char *);
+
+char *mktemp(char *template)
+{
+	size_t l = strlen(template);
+	int retries = 100;
+	struct stat st;
+
+	if (l < 6 || memcmp(template+l-6, "XXXXXX", 6)) {
+		errno = EINVAL;
+		*template = 0;
+		return template;
+	}
+
+	do {
+		__randname(template+l-6);
+		if (stat(template, &st)) {
+			if (errno != ENOENT) *template = 0;
+			return template;
+		}
+	} while (--retries);
+
+	*template = 0;
+	errno = EEXIST;
+	return template;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/cfgetospeed.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/cfgetospeed.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/cfgetospeed.c	(revision 398)
@@ -0,0 +1,13 @@
+#define _BSD_SOURCE
+#include <termios.h>
+#include <sys/ioctl.h>
+
+speed_t cfgetospeed(const struct termios *tio)
+{
+	return tio->c_cflag & CBAUD;
+}
+
+speed_t cfgetispeed(const struct termios *tio)
+{
+	return cfgetospeed(tio);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/cfmakeraw.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/cfmakeraw.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/cfmakeraw.c	(revision 398)
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <termios.h>
+
+void cfmakeraw(struct termios *t)
+{
+	t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+	t->c_oflag &= ~OPOST;
+	t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+	t->c_cflag &= ~(CSIZE|PARENB);
+	t->c_cflag |= CS8;
+	t->c_cc[VMIN] = 1;
+	t->c_cc[VTIME] = 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/cfsetospeed.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/cfsetospeed.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/cfsetospeed.c	(revision 398)
@@ -0,0 +1,23 @@
+#define _BSD_SOURCE
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include "libc.h"
+
+int cfsetospeed(struct termios *tio, speed_t speed)
+{
+	if (speed & ~CBAUD) {
+		errno = EINVAL;
+		return -1;
+	}
+	tio->c_cflag &= ~CBAUD;
+	tio->c_cflag |= speed;
+	return 0;
+}
+
+int cfsetispeed(struct termios *tio, speed_t speed)
+{
+	return speed ? cfsetospeed(tio, speed) : 0;
+}
+
+weak_alias(cfsetospeed, cfsetspeed);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcdrain.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcdrain.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcdrain.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+#include "libc.h"
+#include "syscall.h"
+
+int tcdrain(int fd)
+{
+	return syscall_cp(SYS_ioctl, fd, TCSBRK, 1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcflow.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcflow.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcflow.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcflow(int fd, int action)
+{
+	return ioctl(fd, TCXONC, action);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcflush.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcflush.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcflush.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcflush(int fd, int queue)
+{
+	return ioctl(fd, TCFLSH, queue);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcgetattr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcgetattr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcgetattr.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcgetattr(int fd, struct termios *tio)
+{
+	if (ioctl(fd, TCGETS, tio))
+		return -1;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcgetsid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcgetsid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcgetsid.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+pid_t tcgetsid(int fd)
+{
+	int sid;
+	if (ioctl(fd, TIOCGSID, &sid) < 0)
+		return -1;
+	return sid;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcsendbreak.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcsendbreak.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcsendbreak.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcsendbreak(int fd, int dur)
+{
+	/* nonzero duration is implementation-defined, so ignore it */
+	return ioctl(fd, TCSBRK, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcsetattr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcsetattr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/termios/tcsetattr.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+int tcsetattr(int fd, int act, const struct termios *tio)
+{
+	if (act < 0 || act > 2) {
+		errno = EINVAL;
+		return -1;
+	}
+	return ioctl(fd, TCSETS+act, tio);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__futex.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__futex.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__futex.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "futex.h"
+#include "syscall.h"
+
+int __futex(volatile int *addr, int op, int val, void *ts)
+{
+	return syscall(SYS_futex, addr, op, val, ts);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__lock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__lock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__lock.c	(revision 398)
@@ -0,0 +1,15 @@
+#include "pthread_impl.h"
+
+void __lock(volatile int *l)
+{
+	if (libc.threads_minus_1)
+		while (a_swap(l, 1)) __wait(l, l+1, 1, 1);
+}
+
+void __unlock(volatile int *l)
+{
+	if (l[0]) {
+		a_store(l, 0);
+		if (l[1]) __wake(l, 1, 1);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__set_thread_area.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__set_thread_area.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__set_thread_area.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int __set_thread_area(void *p)
+{
+	__asm__ __volatile__ ( "mvtc %0, fintv" : : "r"(p) : "memory" );
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__syscall_cp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__syscall_cp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__syscall_cp.c	(revision 398)
@@ -0,0 +1,21 @@
+#include "pthread_impl.h"
+#include "syscall.h"
+
+__attribute__((__visibility__("hidden")))
+long __syscall_cp_c();
+
+static long sccp(syscall_arg_t nr,
+                 syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
+                 syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
+{
+	return (__syscall_nr)(nr, u, v, w, x, y, z);
+}
+
+weak_alias(sccp, __syscall_cp_c);
+
+long (__syscall_cp)(syscall_arg_t nr,
+                    syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
+                    syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
+{
+	return __syscall_cp_c(nr, u, v, w, x, y, z);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__timedwait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__timedwait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__timedwait.c	(revision 398)
@@ -0,0 +1,46 @@
+#include <pthread.h>
+#include <time.h>
+#include <errno.h>
+#include "futex.h"
+#include "syscall.h"
+#include "pthread_impl.h"
+
+int __pthread_setcancelstate(int, int *);
+int __clock_gettime(clockid_t, struct timespec *);
+
+int __timedwait_cp(volatile int *addr, int val,
+	clockid_t clk, const struct timespec *at, int priv)
+{
+	int r;
+	struct timespec to, *top=0;
+
+	if (priv) priv = FUTEX_PRIVATE;
+
+	if (at) {
+		if (at->tv_nsec >= 1000000000UL) return EINVAL;
+		if (__clock_gettime(clk, &to)) return EINVAL;
+		to.tv_sec = at->tv_sec - to.tv_sec;
+		if ((to.tv_nsec = at->tv_nsec - to.tv_nsec) < 0) {
+			to.tv_sec--;
+			to.tv_nsec += 1000000000;
+		}
+		if (to.tv_sec < 0) return ETIMEDOUT;
+		top = &to;
+	}
+
+	r = -__syscall_cp(SYS_futex, addr, FUTEX_WAIT|priv, val, top);
+	if (r == ENOSYS) r = -__syscall_cp(SYS_futex, addr, FUTEX_WAIT, val, top);
+	if (r != EINTR && r != ETIMEDOUT && r != ECANCELED) r = 0;
+
+	return r;
+}
+
+int __timedwait(volatile int *addr, int val,
+	clockid_t clk, const struct timespec *at, int priv)
+{
+	int cs, r;
+	__pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	r = __timedwait_cp(addr, val, clk, at, priv);
+	__pthread_setcancelstate(cs, 0);
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__tls_get_addr.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__tls_get_addr.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__tls_get_addr.c	(revision 398)
@@ -0,0 +1,16 @@
+#include <stddef.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+__attribute__((__visibility__("hidden")))
+void *__tls_get_new(tls_mod_off_t *);
+
+void *__tls_get_addr(tls_mod_off_t *v)
+{
+	pthread_t self = __pthread_self();
+	if (v[0]<=(size_t)self->dtv[0])
+		return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
+	return __tls_get_new(v);
+}
+
+weak_alias(__tls_get_addr, __tls_get_new);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__unmapself.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__unmapself.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__unmapself.c	(revision 398)
@@ -0,0 +1,29 @@
+#include "pthread_impl.h"
+#include "atomic.h"
+#include "syscall.h"
+/* cheat and reuse CRTJMP macro from dynlink code */
+#include "dynlink.h"
+
+static volatile int lock;
+static void *unmap_base;
+static size_t unmap_size;
+static char shared_stack[256];
+
+static void do_unmap()
+{
+	__syscall(SYS_munmap, unmap_base, unmap_size);
+	__syscall(SYS_exit);
+}
+
+void __unmapself(void *base, size_t size)
+{
+	int tid=__pthread_self()->tid;
+	char *stack = shared_stack + sizeof shared_stack;
+	stack -= (uintptr_t)stack % 16;
+	while (lock || a_cas(&lock, 0, tid))
+		a_spin();
+	__syscall(SYS_set_tid_address, &lock);
+	unmap_base = base;
+	unmap_size = size;
+	CRTJMP(do_unmap, stack);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__wait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__wait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/__wait.c	(revision 398)
@@ -0,0 +1,17 @@
+#include "pthread_impl.h"
+
+void __wait(volatile int *addr, volatile int *waiters, int val, int priv)
+{
+	int spins=100;
+	if (priv) priv = FUTEX_PRIVATE;
+	while (spins-- && (!waiters || !*waiters)) {
+		if (*addr==val) a_spin();
+		else return;
+	}
+	if (waiters) a_inc(waiters);
+	while (*addr==val) {
+		__syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS
+		|| __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);
+	}
+	if (waiters) a_dec(waiters);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/call_once.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/call_once.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/call_once.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <threads.h>
+
+int __pthread_once(once_flag *, void (*)(void));
+
+void call_once(once_flag *flag, void (*func)(void))
+{
+	__pthread_once(flag, func);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/clone.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/clone.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/clone.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <errno.h>
+#include "pthread_impl.h"
+
+int __clone(int (*func)(void *), void *stack, int flags, void *arg, ...)
+{
+	return -ENOSYS;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_broadcast.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_broadcast.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_broadcast.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <threads.h>
+
+int __private_cond_signal(cnd_t *, int);
+
+int cnd_broadcast(cnd_t *c)
+{
+	/* This internal function never fails, and always returns zero,
+	 * which matches the value thrd_success is defined with. */
+	return __private_cond_signal(c, -1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <threads.h>
+
+void cnd_destroy(cnd_t *c)
+{
+	/* For private cv this is a no-op */
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_init.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <threads.h>
+
+int cnd_init(cnd_t *c)
+{
+	*c = (cnd_t){ 0 };
+	return thrd_success;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_signal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_signal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_signal.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <threads.h>
+
+int __private_cond_signal(cnd_t *, int);
+
+int cnd_signal(cnd_t *c)
+{
+	/* This internal function never fails, and always returns zero,
+	 * which matches the value thrd_success is defined with. */
+	return __private_cond_signal(c, 1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_timedwait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_timedwait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_timedwait.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <threads.h>
+#include <errno.h>
+
+int __pthread_cond_timedwait(cnd_t *restrict, mtx_t *restrict, const struct timespec *restrict);
+
+int cnd_timedwait(cnd_t *restrict c, mtx_t *restrict m, const struct timespec *restrict ts)
+{
+	int ret = __pthread_cond_timedwait(c, m, ts);
+	switch (ret) {
+	/* May also return EINVAL or EPERM. */
+	default:        return thrd_error;
+	case 0:         return thrd_success;
+	case ETIMEDOUT: return thrd_timedout;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_wait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_wait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/cnd_wait.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <threads.h>
+
+int cnd_wait(cnd_t *c, mtx_t *m)
+{
+	/* Calling cnd_timedwait with a null pointer is an extension.
+	 * It is convenient here to avoid duplication of the logic
+	 * for return values. */
+	return cnd_timedwait(c, m, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/lock_ptc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/lock_ptc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/lock_ptc.c	(revision 398)
@@ -0,0 +1,18 @@
+#include <pthread.h>
+
+static pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
+
+void __inhibit_ptc()
+{
+	pthread_rwlock_wrlock(&lock);
+}
+
+void __acquire_ptc()
+{
+	pthread_rwlock_rdlock(&lock);
+}
+
+void __release_ptc()
+{
+	pthread_rwlock_unlock(&lock);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_destroy.c	(revision 398)
@@ -0,0 +1,5 @@
+#include <threads.h>
+
+void mtx_destroy(mtx_t *mtx)
+{
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_init.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int mtx_init(mtx_t *m, int type)
+{
+	*m = (mtx_t){
+		._m_type = ((type&mtx_recursive) ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL),
+	};
+	return thrd_success;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_lock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_lock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_lock.c	(revision 398)
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int mtx_lock(mtx_t *m)
+{
+	if (m->_m_type == PTHREAD_MUTEX_NORMAL && !a_cas(&m->_m_lock, 0, EBUSY))
+		return thrd_success;
+	/* Calling mtx_timedlock with a null pointer is an extension.
+	 * It is convenient, here to avoid duplication of the logic
+	 * for return values. */
+	return mtx_timedlock(m, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_timedlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_timedlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_timedlock.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <threads.h>
+#include <errno.h>
+
+int __pthread_mutex_timedlock(mtx_t *restrict, const struct timespec *restrict);
+
+int mtx_timedlock(mtx_t *restrict m, const struct timespec *restrict ts)
+{
+	int ret = __pthread_mutex_timedlock(m, ts);
+	switch (ret) {
+	default:        return thrd_error;
+	case 0:         return thrd_success;
+	case ETIMEDOUT: return thrd_timedout;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_trylock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_trylock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_trylock.c	(revision 398)
@@ -0,0 +1,17 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int __pthread_mutex_trylock(mtx_t *);
+
+int mtx_trylock(mtx_t *m)
+{
+	if (m->_m_type == PTHREAD_MUTEX_NORMAL)
+		return (a_cas(&m->_m_lock, 0, EBUSY) & EBUSY) ? thrd_busy : thrd_success;
+
+	int ret = __pthread_mutex_trylock(m);
+	switch (ret) {
+	default:    return thrd_error;
+	case 0:     return thrd_success;
+	case EBUSY: return thrd_busy;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_unlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_unlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/mtx_unlock.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <threads.h>
+
+int __pthread_mutex_unlock(mtx_t *);
+
+int mtx_unlock(mtx_t *mtx)
+{
+	/* The only cases where pthread_mutex_unlock can return an
+	 * error are undefined behavior for C11 mtx_unlock, so we can
+	 * assume it does not return an error and simply tail call. */
+	return __pthread_mutex_unlock(mtx);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_atfork.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_atfork.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_atfork.c	(revision 398)
@@ -0,0 +1,48 @@
+#include <pthread.h>
+#include "libc.h"
+
+static struct atfork_funcs {
+	void (*prepare)(void);
+	void (*parent)(void);
+	void (*child)(void);
+	struct atfork_funcs *prev, *next;
+} *funcs;
+
+static volatile int lock[2];
+
+void __fork_handler(int who)
+{
+	struct atfork_funcs *p;
+	if (!funcs) return;
+	if (who < 0) {
+		LOCK(lock);
+		for (p=funcs; p; p = p->next) {
+			if (p->prepare) p->prepare();
+			funcs = p;
+		}
+	} else {
+		for (p=funcs; p; p = p->prev) {
+			if (!who && p->parent) p->parent();
+			else if (who && p->child) p->child();
+			funcs = p;
+		}
+		UNLOCK(lock);
+	}
+}
+
+int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
+{
+	struct atfork_funcs *new = malloc(sizeof *new);
+	if (!new) return -1;
+
+	LOCK(lock);
+	new->next = funcs;
+	new->prev = 0;
+	new->prepare = prepare;
+	new->parent = parent;
+	new->child = child;
+	if (funcs) funcs->prev = new;
+	funcs = new;
+	UNLOCK(lock);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_attr_destroy(pthread_attr_t *a)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_get.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_get.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_get.c	(revision 398)
@@ -0,0 +1,98 @@
+#include "pthread_impl.h"
+
+int pthread_attr_getdetachstate(const pthread_attr_t *a, int *state)
+{
+	*state = a->_a_detach;
+	return 0;
+}
+int pthread_attr_getguardsize(const pthread_attr_t *restrict a, size_t *restrict size)
+{
+	*size = a->_a_guardsize;
+	return 0;
+}
+
+int pthread_attr_getinheritsched(const pthread_attr_t *restrict a, int *restrict inherit)
+{
+	*inherit = a->_a_sched;
+	return 0;
+}
+
+int pthread_attr_getschedparam(const pthread_attr_t *restrict a, struct sched_param *restrict param)
+{
+	param->sched_priority = a->_a_prio;
+	return 0;
+}
+
+int pthread_attr_getschedpolicy(const pthread_attr_t *restrict a, int *restrict policy)
+{
+	*policy = a->_a_policy;
+	return 0;
+}
+
+int pthread_attr_getscope(const pthread_attr_t *restrict a, int *restrict scope)
+{
+	*scope = PTHREAD_SCOPE_SYSTEM;
+	return 0;
+}
+
+int pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size)
+{
+	if (!a->_a_stackaddr)
+		return EINVAL;
+	*size = a->_a_stacksize;
+	*addr = (void *)(a->_a_stackaddr - *size);
+	return 0;
+}
+
+int pthread_attr_getstacksize(const pthread_attr_t *restrict a, size_t *restrict size)
+{
+	*size = a->_a_stacksize;
+	return 0;
+}
+
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict a, int *restrict pshared)
+{
+	*pshared = !!a->__attr;
+	return 0;
+}
+
+int pthread_condattr_getclock(const pthread_condattr_t *restrict a, clockid_t *restrict clk)
+{
+	*clk = a->__attr & 0x7fffffff;
+	return 0;
+}
+
+int pthread_condattr_getpshared(const pthread_condattr_t *restrict a, int *restrict pshared)
+{
+	*pshared = a->__attr>>31;
+	return 0;
+}
+
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict a, int *restrict protocol)
+{
+	*protocol = PTHREAD_PRIO_NONE;
+	return 0;
+}
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict a, int *restrict pshared)
+{
+	*pshared = a->__attr / 128U % 2;
+	return 0;
+}
+
+int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict a, int *restrict robust)
+{
+	*robust = a->__attr / 4U % 2;
+	return 0;
+}
+
+int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict a, int *restrict type)
+{
+	*type = a->__attr & 3;
+	return 0;
+}
+
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict a, int *restrict pshared)
+{
+	*pshared = a->__attr[0];
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_init.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_attr_init(pthread_attr_t *a)
+{
+	*a = (pthread_attr_t){0};
+	a->_a_stacksize = DEFAULT_STACK_SIZE;
+	a->_a_guardsize = DEFAULT_GUARD_SIZE;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setdetachstate.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setdetachstate.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setdetachstate.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setdetachstate(pthread_attr_t *a, int state)
+{
+	if (state > 1U) return EINVAL;
+	a->_a_detach = state;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setguardsize.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setguardsize.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setguardsize.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setguardsize(pthread_attr_t *a, size_t size)
+{
+	if (size > SIZE_MAX/8) return EINVAL;
+	a->_a_guardsize = size;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setinheritsched.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setinheritsched.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setinheritsched.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setinheritsched(pthread_attr_t *a, int inherit)
+{
+	if (inherit > 1U) return EINVAL;
+	a->_a_sched = inherit;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setschedparam.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setschedparam.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setschedparam.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setschedparam(pthread_attr_t *restrict a, const struct sched_param *restrict param)
+{
+	a->_a_prio = param->sched_priority;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setschedpolicy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setschedpolicy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setschedpolicy.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setschedpolicy(pthread_attr_t *a, int policy)
+{
+	a->_a_policy = policy;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setscope.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setscope.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setscope.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setscope(pthread_attr_t *a, int scope)
+{
+	switch (scope) {
+	case PTHREAD_SCOPE_SYSTEM:
+		return 0;
+	case PTHREAD_SCOPE_PROCESS:
+		return ENOTSUP;
+	default:
+		return EINVAL;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setstack.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setstack.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setstack.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setstack(pthread_attr_t *a, void *addr, size_t size)
+{
+	if (size-PTHREAD_STACK_MIN > SIZE_MAX/4) return EINVAL;
+	a->_a_stackaddr = (size_t)addr + size;
+	a->_a_stacksize = size;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setstacksize.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setstacksize.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_attr_setstacksize.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_attr_setstacksize(pthread_attr_t *a, size_t size)
+{
+	if (size-PTHREAD_STACK_MIN > SIZE_MAX/4) return EINVAL;
+	a->_a_stackaddr = 0;
+	a->_a_stacksize = size;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrier_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrier_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrier_destroy.c	(revision 398)
@@ -0,0 +1,15 @@
+#include "pthread_impl.h"
+
+int pthread_barrier_destroy(pthread_barrier_t *b)
+{
+	if (b->_b_limit < 0) {
+		if (b->_b_lock) {
+			int v;
+			a_or(&b->_b_lock, INT_MIN);
+			while ((v = b->_b_lock) & INT_MAX)
+				__wait(&b->_b_lock, 0, v, 0);
+		}
+		__vm_wait();
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrier_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrier_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrier_init.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_barrier_init(pthread_barrier_t *restrict b, const pthread_barrierattr_t *restrict a, unsigned count)
+{
+	if (count-1 > INT_MAX-1) return EINVAL;
+	*b = (pthread_barrier_t){ ._b_limit = count-1 | (a?a->__attr:0) };
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrier_wait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrier_wait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrier_wait.c	(revision 398)
@@ -0,0 +1,111 @@
+#include "pthread_impl.h"
+
+static int pshared_barrier_wait(pthread_barrier_t *b)
+{
+	int limit = (b->_b_limit & INT_MAX) + 1;
+	int ret = 0;
+	int v, w;
+
+	if (limit==1) return PTHREAD_BARRIER_SERIAL_THREAD;
+
+	while ((v=a_cas(&b->_b_lock, 0, limit)))
+		__wait(&b->_b_lock, &b->_b_waiters, v, 0);
+
+	/* Wait for <limit> threads to get to the barrier */
+	if (++b->_b_count == limit) {
+		a_store(&b->_b_count, 0);
+		ret = PTHREAD_BARRIER_SERIAL_THREAD;
+		if (b->_b_waiters2) __wake(&b->_b_count, -1, 0);
+	} else {
+		a_store(&b->_b_lock, 0);
+		if (b->_b_waiters) __wake(&b->_b_lock, 1, 0);
+		while ((v=b->_b_count)>0)
+			__wait(&b->_b_count, &b->_b_waiters2, v, 0);
+	}
+
+	__vm_lock();
+
+	/* Ensure all threads have a vm lock before proceeding */
+	if (a_fetch_add(&b->_b_count, -1)==1-limit) {
+		a_store(&b->_b_count, 0);
+		if (b->_b_waiters2) __wake(&b->_b_count, -1, 0);
+	} else {
+		while ((v=b->_b_count))
+			__wait(&b->_b_count, &b->_b_waiters2, v, 0);
+	}
+	
+	/* Perform a recursive unlock suitable for self-sync'd destruction */
+	do {
+		v = b->_b_lock;
+		w = b->_b_waiters;
+	} while (a_cas(&b->_b_lock, v, v==INT_MIN+1 ? 0 : v-1) != v);
+
+	/* Wake a thread waiting to reuse or destroy the barrier */
+	if (v==INT_MIN+1 || (v==1 && w))
+		__wake(&b->_b_lock, 1, 0);
+
+	__vm_unlock();
+
+	return ret;
+}
+
+struct instance
+{
+	volatile int count;
+	volatile int last;
+	volatile int waiters;
+	volatile int finished;
+};
+
+int pthread_barrier_wait(pthread_barrier_t *b)
+{
+	int limit = b->_b_limit;
+	struct instance *inst;
+
+	/* Trivial case: count was set at 1 */
+	if (!limit) return PTHREAD_BARRIER_SERIAL_THREAD;
+
+	/* Process-shared barriers require a separate, inefficient wait */
+	if (limit < 0) return pshared_barrier_wait(b);
+
+	/* Otherwise we need a lock on the barrier object */
+	while (a_swap(&b->_b_lock, 1))
+		__wait(&b->_b_lock, &b->_b_waiters, 1, 1);
+	inst = b->_b_inst;
+
+	/* First thread to enter the barrier becomes the "instance owner" */
+	if (!inst) {
+		struct instance new_inst = { 0 };
+		int spins = 200;
+		b->_b_inst = inst = &new_inst;
+		a_store(&b->_b_lock, 0);
+		if (b->_b_waiters) __wake(&b->_b_lock, 1, 1);
+		while (spins-- && !inst->finished)
+			a_spin();
+		a_inc(&inst->finished);
+		while (inst->finished == 1)
+			__syscall(SYS_futex,&inst->finished,FUTEX_WAIT|FUTEX_PRIVATE,1,0) != -ENOSYS
+			|| __syscall(SYS_futex,&inst->finished,FUTEX_WAIT,1,0);
+		return PTHREAD_BARRIER_SERIAL_THREAD;
+	}
+
+	/* Last thread to enter the barrier wakes all non-instance-owners */
+	if (++inst->count == limit) {
+		b->_b_inst = 0;
+		a_store(&b->_b_lock, 0);
+		if (b->_b_waiters) __wake(&b->_b_lock, 1, 1);
+		a_store(&inst->last, 1);
+		if (inst->waiters)
+			__wake(&inst->last, -1, 1);
+	} else {
+		a_store(&b->_b_lock, 0);
+		if (b->_b_waiters) __wake(&b->_b_lock, 1, 1);
+		__wait(&inst->last, &inst->waiters, 0, 1);
+	}
+
+	/* Last thread to exit the barrier wakes the instance owner */
+	if (a_fetch_add(&inst->count,-1)==1 && a_fetch_add(&inst->finished,1))
+		__wake(&inst->finished, 1, 1);
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrierattr_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrierattr_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrierattr_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_barrierattr_destroy(pthread_barrierattr_t *a)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrierattr_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrierattr_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrierattr_init.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_barrierattr_init(pthread_barrierattr_t *a)
+{
+	*a = (pthread_barrierattr_t){0};
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrierattr_setpshared.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrierattr_setpshared.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_barrierattr_setpshared.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_barrierattr_setpshared(pthread_barrierattr_t *a, int pshared)
+{
+	a->__attr = pshared ? INT_MIN : 0;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cancel.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cancel.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cancel.c	(revision 398)
@@ -0,0 +1,97 @@
+#define _GNU_SOURCE
+#include <string.h>
+#include "pthread_impl.h"
+#include "syscall.h"
+#include "libc.h"
+
+__attribute__((__visibility__("hidden")))
+long __cancel(), __syscall_cp_asm(), __syscall_cp_c();
+
+long __cancel()
+{
+	pthread_t self = __pthread_self();
+	if (self->canceldisable == PTHREAD_CANCEL_ENABLE || self->cancelasync)
+		pthread_exit(PTHREAD_CANCELED);
+	self->canceldisable = PTHREAD_CANCEL_DISABLE;
+	return -ECANCELED;
+}
+
+long __syscall_cp_asm(volatile void *, syscall_arg_t,
+                      syscall_arg_t, syscall_arg_t, syscall_arg_t,
+                      syscall_arg_t, syscall_arg_t, syscall_arg_t);
+
+long __syscall_cp_c(syscall_arg_t nr,
+                    syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
+                    syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
+{
+	pthread_t self;
+	long r;
+	int st;
+
+	if ((st=(self=__pthread_self())->canceldisable)
+	    && (st==PTHREAD_CANCEL_DISABLE || nr==SYS_close))
+		return __syscall_nr(nr, u, v, w, x, y, z);
+
+	r = __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z);
+	if (r==-EINTR && nr!=SYS_close && self->cancel &&
+	    self->canceldisable != PTHREAD_CANCEL_DISABLE)
+		r = __cancel();
+	return r;
+}
+
+static void _sigaddset(sigset_t *set, int sig)
+{
+	unsigned s = sig-1;
+	set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
+}
+
+__attribute__((__visibility__("hidden")))
+extern const char __cp_begin[1], __cp_end[1], __cp_cancel[1];
+
+static void cancel_handler(int sig, siginfo_t *si, void *ctx)
+{
+	pthread_t self = __pthread_self();
+	ucontext_t *uc = ctx;
+	uintptr_t pc = uc->uc_mcontext.MC_PC;
+
+	a_barrier();
+	if (!self->cancel || self->canceldisable == PTHREAD_CANCEL_DISABLE) return;
+
+	_sigaddset(&uc->uc_sigmask, SIGCANCEL);
+
+	if (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) {
+		uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel;
+		return;
+	}
+
+	__syscall(SYS_tkill, self->tid, SIGCANCEL);
+}
+
+void __testcancel()
+{
+	pthread_t self = __pthread_self();
+	if (self->cancel && !self->canceldisable)
+		__cancel();
+}
+
+static void init_cancellation()
+{
+	struct sigaction sa = {
+		.sa_flags = SA_SIGINFO | SA_RESTART,
+		.sa_sigaction = cancel_handler
+	};
+	memset(&sa.sa_mask, -1, _NSIG/8);
+	__libc_sigaction(SIGCANCEL, &sa, 0);
+}
+
+int pthread_cancel(pthread_t t)
+{
+	static int init;
+	if (!init) {
+		init_cancellation();
+		init = 1;
+	}
+	a_store(&t->cancel, 1);
+	if (t == pthread_self() && !t->cancelasync) return 0;
+	return pthread_kill(t, SIGCANCEL);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cleanup_push.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cleanup_push.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cleanup_push.c	(revision 398)
@@ -0,0 +1,20 @@
+#include "pthread_impl.h"
+
+static void dummy(struct __ptcb *cb)
+{
+}
+weak_alias(dummy, __do_cleanup_push);
+weak_alias(dummy, __do_cleanup_pop);
+
+void _pthread_cleanup_push(struct __ptcb *cb, void (*f)(void *), void *x)
+{
+	cb->__f = f;
+	cb->__x = x;
+	__do_cleanup_push(cb);
+}
+
+void _pthread_cleanup_pop(struct __ptcb *cb, int run)
+{
+	__do_cleanup_pop(cb);
+	if (run) cb->__f(cb->__x);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_broadcast.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_broadcast.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_broadcast.c	(revision 398)
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+
+int __private_cond_signal(pthread_cond_t *, int);
+
+int pthread_cond_broadcast(pthread_cond_t *c)
+{
+	if (!c->_c_shared) return __private_cond_signal(c, -1);
+	if (!c->_c_waiters) return 0;
+	a_inc(&c->_c_seq);
+	__wake(&c->_c_seq, -1, 0);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_destroy.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "pthread_impl.h"
+
+int pthread_cond_destroy(pthread_cond_t *c)
+{
+	if (c->_c_shared && c->_c_waiters) {
+		int cnt;
+		a_or(&c->_c_waiters, 0x80000000);
+		a_inc(&c->_c_seq);
+		__wake(&c->_c_seq, -1, 0);
+		while ((cnt = c->_c_waiters) & 0x7fffffff)
+			__wait(&c->_c_waiters, 0, cnt, 0);
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_init.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+
+int pthread_cond_init(pthread_cond_t *restrict c, const pthread_condattr_t *restrict a)
+{
+	*c = (pthread_cond_t){0};
+	if (a) {
+		c->_c_clock = a->__attr & 0x7fffffff;
+		if (a->__attr>>31) c->_c_shared = (void *)-1;
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_signal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_signal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_signal.c	(revision 398)
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+
+int __private_cond_signal(pthread_cond_t *, int);
+
+int pthread_cond_signal(pthread_cond_t *c)
+{
+	if (!c->_c_shared) return __private_cond_signal(c, 1);
+	if (!c->_c_waiters) return 0;
+	a_inc(&c->_c_seq);
+	__wake(&c->_c_seq, 1, 0);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_timedwait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_timedwait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_timedwait.c	(revision 398)
@@ -0,0 +1,214 @@
+#include "pthread_impl.h"
+
+void __pthread_testcancel(void);
+int __pthread_mutex_lock(pthread_mutex_t *);
+int __pthread_mutex_unlock(pthread_mutex_t *);
+int __pthread_setcancelstate(int, int *);
+
+/*
+ * struct waiter
+ *
+ * Waiter objects have automatic storage on the waiting thread, and
+ * are used in building a linked list representing waiters currently
+ * waiting on the condition variable or a group of waiters woken
+ * together by a broadcast or signal; in the case of signal, this is a
+ * degenerate list of one member.
+ *
+ * Waiter lists attached to the condition variable itself are
+ * protected by the lock on the cv. Detached waiter lists are never
+ * modified again, but can only be traversed in reverse order, and are
+ * protected by the "barrier" locks in each node, which are unlocked
+ * in turn to control wake order.
+ *
+ * Since process-shared cond var semantics do not necessarily allow
+ * one thread to see another's automatic storage (they may be in
+ * different processes), the waiter list is not used for the
+ * process-shared case, but the structure is still used to store data
+ * needed by the cancellation cleanup handler.
+ */
+
+struct waiter {
+	struct waiter *prev, *next;
+	volatile int state, barrier;
+	volatile int *notify;
+};
+
+/* Self-synchronized-destruction-safe lock functions */
+
+static inline void lock(volatile int *l)
+{
+	if (a_cas(l, 0, 1)) {
+		a_cas(l, 1, 2);
+		do __wait(l, 0, 2, 1);
+		while (a_cas(l, 0, 2));
+	}
+}
+
+static inline void unlock(volatile int *l)
+{
+	if (a_swap(l, 0)==2)
+		__wake(l, 1, 1);
+}
+
+static inline void unlock_requeue(volatile int *l, volatile int *r, int w)
+{
+	a_store(l, 0);
+	if (w) __wake(l, 1, 1);
+	else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS
+		|| __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r);
+}
+
+enum {
+	WAITING,
+	SIGNALED,
+	LEAVING,
+};
+
+int __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restrict m, const struct timespec *restrict ts)
+{
+	struct waiter node = { 0 };
+	int e, seq, clock = c->_c_clock, cs, shared=0, oldstate, tmp;
+	volatile int *fut;
+
+	if ((m->_m_type&15) && (m->_m_lock&INT_MAX) != __pthread_self()->tid)
+		return EPERM;
+
+	if (ts && ts->tv_nsec >= 1000000000UL)
+		return EINVAL;
+
+	__pthread_testcancel();
+
+	if (c->_c_shared) {
+		shared = 1;
+		fut = &c->_c_seq;
+		seq = c->_c_seq;
+		a_inc(&c->_c_waiters);
+	} else {
+		lock(&c->_c_lock);
+
+		seq = node.barrier = 2;
+		fut = &node.barrier;
+		node.state = WAITING;
+		node.next = c->_c_head;
+		c->_c_head = &node;
+		if (!c->_c_tail) c->_c_tail = &node;
+		else node.next->prev = &node;
+
+		unlock(&c->_c_lock);
+	}
+
+	__pthread_mutex_unlock(m);
+
+	__pthread_setcancelstate(PTHREAD_CANCEL_MASKED, &cs);
+	if (cs == PTHREAD_CANCEL_DISABLE) __pthread_setcancelstate(cs, 0);
+
+	do e = __timedwait_cp(fut, seq, clock, ts, !shared);
+	while (*fut==seq && (!e || e==EINTR));
+	if (e == EINTR) e = 0;
+
+	if (shared) {
+		/* Suppress cancellation if a signal was potentially
+		 * consumed; this is a legitimate form of spurious
+		 * wake even if not. */
+		if (e == ECANCELED && c->_c_seq != seq) e = 0;
+		if (a_fetch_add(&c->_c_waiters, -1) == -0x7fffffff)
+			__wake(&c->_c_waiters, 1, 0);
+		oldstate = WAITING;
+		goto relock;
+	}
+
+	oldstate = a_cas(&node.state, WAITING, LEAVING);
+
+	if (oldstate == WAITING) {
+		/* Access to cv object is valid because this waiter was not
+		 * yet signaled and a new signal/broadcast cannot return
+		 * after seeing a LEAVING waiter without getting notified
+		 * via the futex notify below. */
+
+		lock(&c->_c_lock);
+		
+		if (c->_c_head == &node) c->_c_head = node.next;
+		else if (node.prev) node.prev->next = node.next;
+		if (c->_c_tail == &node) c->_c_tail = node.prev;
+		else if (node.next) node.next->prev = node.prev;
+		
+		unlock(&c->_c_lock);
+
+		if (node.notify) {
+			if (a_fetch_add(node.notify, -1)==1)
+				__wake(node.notify, 1, 1);
+		}
+	} else {
+		/* Lock barrier first to control wake order. */
+		lock(&node.barrier);
+	}
+
+relock:
+	/* Errors locking the mutex override any existing error or
+	 * cancellation, since the caller must see them to know the
+	 * state of the mutex. */
+	if ((tmp = pthread_mutex_lock(m))) e = tmp;
+
+	if (oldstate == WAITING) goto done;
+
+	if (!node.next) a_inc(&m->_m_waiters);
+
+	/* Unlock the barrier that's holding back the next waiter, and
+	 * either wake it or requeue it to the mutex. */
+	if (node.prev)
+		unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & 128);
+	else
+		a_dec(&m->_m_waiters);
+
+	/* Since a signal was consumed, cancellation is not permitted. */
+	if (e == ECANCELED) e = 0;
+
+done:
+	__pthread_setcancelstate(cs, 0);
+
+	if (e == ECANCELED) {
+		__pthread_testcancel();
+		__pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
+	}
+
+	return e;
+}
+
+int __private_cond_signal(pthread_cond_t *c, int n)
+{
+	struct waiter *p, *first=0;
+	volatile int ref = 0;
+	int cur;
+
+	lock(&c->_c_lock);
+	for (p=c->_c_tail; n && p; p=p->prev) {
+		if (a_cas(&p->state, WAITING, SIGNALED) != WAITING) {
+			ref++;
+			p->notify = &ref;
+		} else {
+			n--;
+			if (!first) first=p;
+		}
+	}
+	/* Split the list, leaving any remainder on the cv. */
+	if (p) {
+		if (p->next) p->next->prev = 0;
+		p->next = 0;
+	} else {
+		c->_c_head = 0;
+	}
+	c->_c_tail = p;
+	unlock(&c->_c_lock);
+
+	/* Wait for any waiters in the LEAVING state to remove
+	 * themselves from the list before returning or allowing
+	 * signaled threads to proceed. */
+	while ((cur = ref)) __wait(&ref, 0, cur, 1);
+
+	/* Allow first signaled waiter, if any, to proceed. */
+	if (first) unlock(&first->barrier);
+
+	return 0;
+}
+
+weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_wait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_wait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_cond_wait.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_cond_wait(pthread_cond_t *restrict c, pthread_mutex_t *restrict m)
+{
+	return pthread_cond_timedwait(c, m, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_condattr_destroy(pthread_condattr_t *a)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_init.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_condattr_init(pthread_condattr_t *a)
+{
+	*a = (pthread_condattr_t){0};
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_setclock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_setclock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_setclock.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_condattr_setclock(pthread_condattr_t *a, clockid_t clk)
+{
+	if (clk < 0 || clk-2U < 2) return EINVAL;
+	a->__attr &= 0x80000000;
+	a->__attr |= clk;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_setpshared.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_setpshared.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_condattr_setpshared.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_condattr_setpshared(pthread_condattr_t *a, int pshared)
+{
+	if (pshared > 1U) return EINVAL;
+	a->__attr &= 0x7fffffff;
+	a->__attr |= (unsigned)pshared<<31;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_create.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_create.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_create.c	(revision 398)
@@ -0,0 +1,316 @@
+#define _GNU_SOURCE
+#include "pthread_impl.h"
+#include "stdio_impl.h"
+#include "libc.h"
+#include <sys/mman.h>
+#include <string.h>
+#include <stddef.h>
+
+void *__mmap(void *, size_t, int, int, int, off_t);
+int __munmap(void *, size_t);
+int __mprotect(void *, size_t, int);
+
+static void dummy_0()
+{
+}
+weak_alias(dummy_0, __acquire_ptc);
+weak_alias(dummy_0, __release_ptc);
+weak_alias(dummy_0, __pthread_tsd_run_dtors);
+weak_alias(dummy_0, __do_orphaned_stdio_locks);
+weak_alias(dummy_0, __dl_thread_cleanup);
+
+_Noreturn void __pthread_exit(void *result)
+{
+	pthread_t self = __pthread_self();
+	sigset_t set;
+
+	self->canceldisable = 1;
+	self->cancelasync = 0;
+	self->result = result;
+
+	while (self->cancelbuf) {
+		void (*f)(void *) = self->cancelbuf->__f;
+		void *x = self->cancelbuf->__x;
+		self->cancelbuf = self->cancelbuf->__next;
+		f(x);
+	}
+
+	__pthread_tsd_run_dtors();
+
+	__lock(self->exitlock);
+
+	/* Mark this thread dead before decrementing count */
+	__lock(self->killlock);
+	self->dead = 1;
+
+	/* Block all signals before decrementing the live thread count.
+	 * This is important to ensure that dynamically allocated TLS
+	 * is not under-allocated/over-committed, and possibly for other
+	 * reasons as well. */
+	__block_all_sigs(&set);
+
+	/* Wait to unlock the kill lock, which governs functions like
+	 * pthread_kill which target a thread id, until signals have
+	 * been blocked. This precludes observation of the thread id
+	 * as a live thread (with application code running in it) after
+	 * the thread was reported dead by ESRCH being returned. */
+	__unlock(self->killlock);
+
+	/* It's impossible to determine whether this is "the last thread"
+	 * until performing the atomic decrement, since multiple threads
+	 * could exit at the same time. For the last thread, revert the
+	 * decrement and unblock signals to give the atexit handlers and
+	 * stdio cleanup code a consistent state. */
+	if (a_fetch_add(&libc.threads_minus_1, -1)==0) {
+		libc.threads_minus_1 = 0;
+		__restore_sigs(&set);
+		exit(0);
+	}
+
+	/* Process robust list in userspace to handle non-pshared mutexes
+	 * and the detached thread case where the robust list head will
+	 * be invalid when the kernel would process it. */
+	__vm_lock();
+	volatile void *volatile *rp;
+	while ((rp=self->robust_list.head) && rp != &self->robust_list.head) {
+		pthread_mutex_t *m = (void *)((char *)rp
+			- offsetof(pthread_mutex_t, _m_next));
+		int waiters = m->_m_waiters;
+		int priv = (m->_m_type & 128) ^ 128;
+		self->robust_list.pending = rp;
+		self->robust_list.head = *rp;
+		int cont = a_swap(&m->_m_lock, 0x40000000);
+		self->robust_list.pending = 0;
+		if (cont < 0 || waiters)
+			__wake(&m->_m_lock, 1, priv);
+	}
+	__vm_unlock();
+
+	__do_orphaned_stdio_locks();
+	__dl_thread_cleanup();
+
+	if (self->detached && self->map_base) {
+		/* Detached threads must avoid the kernel clear_child_tid
+		 * feature, since the virtual address will have been
+		 * unmapped and possibly already reused by a new mapping
+		 * at the time the kernel would perform the write. In
+		 * the case of threads that started out detached, the
+		 * initial clone flags are correct, but if the thread was
+		 * detached later (== 2), we need to clear it here. */
+		if (self->detached == 2) __syscall(SYS_set_tid_address, 0);
+
+		/* Robust list will no longer be valid, and was already
+		 * processed above, so unregister it with the kernel. */
+		if (self->robust_list.off)
+			__syscall(SYS_set_robust_list, 0, 3*sizeof(long));
+
+		/* Since __unmapself bypasses the normal munmap code path,
+		 * explicitly wait for vmlock holders first. */
+		__vm_wait();
+
+		/* The following call unmaps the thread's stack mapping
+		 * and then exits without touching the stack. */
+		__unmapself(self->map_base, self->map_size);
+	}
+
+	for (;;) __syscall(SYS_exit, 0);
+}
+
+void __do_cleanup_push(struct __ptcb *cb)
+{
+	struct pthread *self = __pthread_self();
+	cb->__next = self->cancelbuf;
+	self->cancelbuf = cb;
+}
+
+void __do_cleanup_pop(struct __ptcb *cb)
+{
+	__pthread_self()->cancelbuf = cb->__next;
+}
+
+static int start(void *p)
+{
+	pthread_t self = p;
+	/* States for startlock:
+	 * 0 = no need for start sync
+	 * 1 = waiting for parent to do work
+	 * 2 = failure in parent, child must abort
+	 * 3 = success in parent, child must restore sigmask */
+	if (self->startlock[0]) {
+		__wait(self->startlock, 0, 1, 1);
+		if (self->startlock[0] == 2) {
+			self->detached = 2;
+			pthread_exit(0);
+		}
+		__restore_sigs(self->sigmask);
+	}
+	if (self->unblock_cancel)
+		__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
+			SIGPT_SET, 0, _NSIG/8);
+	__pthread_exit(self->start(self->start_arg));
+	return 0;
+}
+
+static int start_c11(void *p)
+{
+	pthread_t self = p;
+	int (*start)(void*) = (int(*)(void*)) self->start;
+	__pthread_exit((void *)(uintptr_t)start(self->start_arg));
+	return 0;
+}
+
+#define ROUND(x) (((x)+PAGE_SIZE-1)&-PAGE_SIZE)
+
+/* pthread_key_create.c overrides this */
+static volatile size_t dummy = 0;
+weak_alias(dummy, __pthread_tsd_size);
+static void *dummy_tsd[1] = { 0 };
+weak_alias(dummy_tsd, __pthread_tsd_main);
+
+volatile int __block_new_threads = 0;
+size_t __default_stacksize = DEFAULT_STACK_SIZE;
+size_t __default_guardsize = DEFAULT_GUARD_SIZE;
+
+static FILE *volatile dummy_file = 0;
+weak_alias(dummy_file, __stdin_used);
+weak_alias(dummy_file, __stdout_used);
+weak_alias(dummy_file, __stderr_used);
+
+static void init_file_lock(FILE *f)
+{
+	if (f && f->lock<0) f->lock = 0;
+}
+
+void *__copy_tls(unsigned char *);
+
+int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp, void *(*entry)(void *), void *restrict arg)
+{
+	int ret, c11 = (attrp == __ATTRP_C11_THREAD);
+	size_t size, guard;
+	struct pthread *self, *new;
+	unsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit;
+	unsigned flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND
+		| CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS
+		| CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_DETACHED;
+	int do_sched = 0;
+	pthread_attr_t attr = { 0 };
+
+	if (!libc.can_do_threads) return ENOSYS;
+	self = __pthread_self();
+	if (!libc.threaded) {
+		for (FILE *f=*__ofl_lock(); f; f=f->next)
+			init_file_lock(f);
+		__ofl_unlock();
+		init_file_lock(__stdin_used);
+		init_file_lock(__stdout_used);
+		init_file_lock(__stderr_used);
+		__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, SIGPT_SET, 0, _NSIG/8);
+		self->tsd = (void **)__pthread_tsd_main;
+		libc.threaded = 1;
+	}
+	if (attrp && !c11) attr = *attrp;
+
+	__acquire_ptc();
+	if (!attrp || c11) {
+		attr._a_stacksize = __default_stacksize;
+		attr._a_guardsize = __default_guardsize;
+	}
+
+	if (__block_new_threads) __wait(&__block_new_threads, 0, 1, 1);
+
+	if (attr._a_stackaddr) {
+		size_t need = libc.tls_size + __pthread_tsd_size;
+		size = attr._a_stacksize;
+		stack = (void *)(attr._a_stackaddr & -16);
+		stack_limit = (void *)(attr._a_stackaddr - size);
+		/* Use application-provided stack for TLS only when
+		 * it does not take more than ~12% or 2k of the
+		 * application's stack space. */
+		if (need < size/8 && need < 2048) {
+			tsd = stack - __pthread_tsd_size;
+			stack = tsd - libc.tls_size;
+			memset(stack, 0, need);
+		} else {
+			size = ROUND(need);
+			guard = 0;
+		}
+	} else {
+		guard = ROUND(attr._a_guardsize);
+		size = guard + ROUND(attr._a_stacksize
+			+ libc.tls_size +  __pthread_tsd_size);
+	}
+
+	if (!tsd) {
+		if (guard) {
+			map = __mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANON, -1, 0);
+			if (map == MAP_FAILED) goto fail;
+			if (__mprotect(map+guard, size-guard, PROT_READ|PROT_WRITE)
+			    && errno != ENOSYS) {
+				__munmap(map, size);
+				goto fail;
+			}
+		} else {
+			map = __mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+			if (map == MAP_FAILED) goto fail;
+		}
+		tsd = map + size - __pthread_tsd_size;
+		if (!stack) {
+			stack = tsd - libc.tls_size;
+			stack_limit = map + guard;
+		}
+	}
+
+	new = __copy_tls(tsd - libc.tls_size);
+	new->map_base = map;
+	new->map_size = size;
+	new->stack = stack;
+	new->stack_size = stack - stack_limit;
+	new->start = entry;
+	new->start_arg = arg;
+	new->self = new;
+	new->tsd = (void *)tsd;
+	new->locale = &libc.global_locale;
+	if (attr._a_detach) {
+		new->detached = 1;
+		flags -= CLONE_CHILD_CLEARTID;
+	}
+	if (attr._a_sched) {
+		do_sched = new->startlock[0] = 1;
+		__block_app_sigs(new->sigmask);
+	}
+	new->robust_list.head = &new->robust_list.head;
+	new->unblock_cancel = self->cancel;
+	new->CANARY = self->CANARY;
+
+	a_inc(&libc.threads_minus_1);
+	ret = __clone((c11 ? start_c11 : start), stack, flags, new, &new->tid, TP_ADJ(new), &new->tid);
+
+	__release_ptc();
+
+	if (do_sched) {
+		__restore_sigs(new->sigmask);
+	}
+
+	if (ret < 0) {
+		a_dec(&libc.threads_minus_1);
+		if (map) __munmap(map, size);
+		return EAGAIN;
+	}
+
+	if (do_sched) {
+		ret = __syscall(SYS_sched_setscheduler, new->tid,
+			attr._a_policy, &attr._a_prio);
+		a_store(new->startlock, ret<0 ? 2 : 3);
+		__wake(new->startlock, 1, 1);
+		if (ret < 0) return -ret;
+	}
+
+	*res = new;
+	return 0;
+fail:
+	__release_ptc();
+	return EAGAIN;
+}
+
+weak_alias(__pthread_exit, pthread_exit);
+weak_alias(__pthread_create, pthread_create);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_detach.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_detach.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_detach.c	(revision 398)
@@ -0,0 +1,18 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int __pthread_join(pthread_t, void **);
+
+static int __pthread_detach(pthread_t t)
+{
+	/* Cannot detach a thread that's already exiting */
+	if (a_swap(t->exitlock, 1))
+		return __pthread_join(t, 0);
+	t->detached = 2;
+	a_store(t->exitlock, 0);
+	__wake(t->exitlock, 1, 1);
+	return 0;
+}
+
+weak_alias(__pthread_detach, pthread_detach);
+weak_alias(__pthread_detach, thrd_detach);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_equal.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_equal.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_equal.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <pthread.h>
+#include <threads.h>
+#include "libc.h"
+
+static int __pthread_equal(pthread_t a, pthread_t b)
+{
+	return a==b;
+}
+
+weak_alias(__pthread_equal, pthread_equal);
+weak_alias(__pthread_equal, thrd_equal);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getattr_np.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getattr_np.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getattr_np.c	(revision 398)
@@ -0,0 +1,23 @@
+#define _GNU_SOURCE
+#include "pthread_impl.h"
+#include "libc.h"
+#include <sys/mman.h>
+
+int pthread_getattr_np(pthread_t t, pthread_attr_t *a)
+{
+	*a = (pthread_attr_t){0};
+	a->_a_detach = !!t->detached;
+	if (t->stack) {
+		a->_a_stackaddr = (uintptr_t)t->stack;
+		a->_a_stacksize = t->stack_size;
+	} else {
+		char *p = (void *)libc.auxv;
+		size_t l = PAGE_SIZE;
+		p += -(uintptr_t)p & PAGE_SIZE-1;
+		a->_a_stackaddr = (uintptr_t)p;
+		while (mremap(p-l-PAGE_SIZE, PAGE_SIZE, 2*PAGE_SIZE, 0)==MAP_FAILED && errno==ENOMEM)
+			l += PAGE_SIZE;
+		a->_a_stacksize = l;
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getconcurrency.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getconcurrency.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getconcurrency.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <pthread.h>
+
+int pthread_getconcurrency()
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getcpuclockid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getcpuclockid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getcpuclockid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_getcpuclockid(pthread_t t, clockid_t *clockid)
+{
+	*clockid = (-t->tid-1)*8U + 6;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getschedparam.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getschedparam.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getschedparam.c	(revision 398)
@@ -0,0 +1,17 @@
+#include "pthread_impl.h"
+
+int pthread_getschedparam(pthread_t t, int *restrict policy, struct sched_param *restrict param)
+{
+	int r;
+	__lock(t->killlock);
+	if (t->dead) {
+		r = ESRCH;
+	} else {
+		r = -__syscall(SYS_sched_getparam, t->tid, param);
+		if (!r) {
+			*policy = __syscall(SYS_sched_getscheduler, t->tid);
+		}
+	}
+	__unlock(t->killlock);
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getspecific.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getspecific.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_getspecific.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+static void *__pthread_getspecific(pthread_key_t k)
+{
+	struct pthread *self = __pthread_self();
+	return self->tsd[k];
+}
+
+weak_alias(__pthread_getspecific, pthread_getspecific);
+weak_alias(__pthread_getspecific, tss_get);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_join.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_join.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_join.c	(revision 398)
@@ -0,0 +1,37 @@
+#include "pthread_impl.h"
+#include <sys/mman.h>
+
+int __munmap(void *, size_t);
+void __pthread_testcancel(void);
+int __pthread_setcancelstate(int, int *);
+
+int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec *at)
+{
+	int tmp, cs, r = 0;
+	__pthread_testcancel();
+	__pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	if (cs == PTHREAD_CANCEL_ENABLE) __pthread_setcancelstate(cs, 0);
+	if (t->detached) a_crash();
+	while ((tmp = t->tid) && r != ETIMEDOUT && r != EINVAL)
+		r = __timedwait_cp(&t->tid, tmp, CLOCK_REALTIME, at, 0);
+	__pthread_setcancelstate(cs, 0);
+	if (r == ETIMEDOUT || r == EINVAL) return r;
+	a_barrier();
+	if (res) *res = t->result;
+	if (t->map_base) __munmap(t->map_base, t->map_size);
+	return 0;
+}
+
+int __pthread_join(pthread_t t, void **res)
+{
+	return __pthread_timedjoin_np(t, res, 0);
+}
+
+int __pthread_tryjoin_np(pthread_t t, void **res)
+{
+	return t->tid ? EBUSY : __pthread_join(t, res);
+}
+
+weak_alias(__pthread_tryjoin_np, pthread_tryjoin_np);
+weak_alias(__pthread_timedjoin_np, pthread_timedjoin_np);
+weak_alias(__pthread_join, pthread_join);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_key_create.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_key_create.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_key_create.c	(revision 398)
@@ -0,0 +1,56 @@
+#include "pthread_impl.h"
+
+volatile size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX;
+void *__pthread_tsd_main[PTHREAD_KEYS_MAX] = { 0 };
+
+static void (*volatile keys[PTHREAD_KEYS_MAX])(void *);
+
+static void nodtor(void *dummy)
+{
+}
+
+int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
+{
+	unsigned i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX;
+	unsigned j = i;
+	pthread_t self = __pthread_self();
+
+	/* This can only happen in the main thread before
+	 * pthread_create has been called. */
+	if (!self->tsd) self->tsd = __pthread_tsd_main;
+
+	if (!dtor) dtor = nodtor;
+	do {
+		if (!a_cas_p(keys+j, 0, (void *)dtor)) {
+			*k = j;
+			return 0;
+		}
+	} while ((j=(j+1)%PTHREAD_KEYS_MAX) != i);
+	return EAGAIN;
+}
+
+int __pthread_key_delete(pthread_key_t k)
+{
+	keys[k] = 0;
+	return 0;
+}
+
+void __pthread_tsd_run_dtors()
+{
+	pthread_t self = __pthread_self();
+	int i, j, not_finished = self->tsd_used;
+	for (j=0; not_finished && j<PTHREAD_DESTRUCTOR_ITERATIONS; j++) {
+		not_finished = 0;
+		for (i=0; i<PTHREAD_KEYS_MAX; i++) {
+			if (self->tsd[i] && keys[i]) {
+				void *tmp = self->tsd[i];
+				self->tsd[i] = 0;
+				keys[i](tmp);
+				not_finished = 1;
+			}
+		}
+	}
+}
+
+weak_alias(__pthread_key_delete, pthread_key_delete);
+weak_alias(__pthread_key_create, pthread_key_create);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_kill.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_kill.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_kill.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+
+int pthread_kill(pthread_t t, int sig)
+{
+	int r;
+	__lock(t->killlock);
+	r = t->dead ? ESRCH : -__syscall(SYS_tkill, t->tid, sig);
+	__unlock(t->killlock);
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_consistent.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_consistent.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_consistent.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_consistent(pthread_mutex_t *m)
+{
+	if (!(m->_m_type & 8)) return EINVAL;
+	if ((m->_m_lock & 0x7fffffff) != __pthread_self()->tid)
+		return EPERM;
+	m->_m_type &= ~8U;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <pthread.h>
+
+int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_getprioceiling.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_getprioceiling.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_getprioceiling.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict m, int *restrict ceiling)
+{
+	return EINVAL;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_init.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_init(pthread_mutex_t *restrict m, const pthread_mutexattr_t *restrict a)
+{
+	*m = (pthread_mutex_t){0};
+	if (a) m->_m_type = a->__attr;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_lock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_lock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_lock.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "pthread_impl.h"
+
+int __pthread_mutex_timedlock(pthread_mutex_t *restrict, const struct timespec *restrict);
+
+int __pthread_mutex_lock(pthread_mutex_t *m)
+{
+	if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL
+	    && !a_cas(&m->_m_lock, 0, EBUSY))
+		return 0;
+
+	return __pthread_mutex_timedlock(m, 0);
+}
+
+weak_alias(__pthread_mutex_lock, pthread_mutex_lock);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_setprioceiling.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_setprioceiling.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_setprioceiling.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_mutex_setprioceiling(pthread_mutex_t *restrict m, int ceiling, int *restrict old)
+{
+	return EINVAL;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_timedlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_timedlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_timedlock.c	(revision 398)
@@ -0,0 +1,34 @@
+#include "pthread_impl.h"
+
+int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec *restrict at)
+{
+	if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL
+	    && !a_cas(&m->_m_lock, 0, EBUSY))
+		return 0;
+
+	int r, t, priv = (m->_m_type & 128) ^ 128;
+
+	r = pthread_mutex_trylock(m);
+	if (r != EBUSY) return r;
+	
+	int spins = 100;
+	while (spins-- && m->_m_lock && !m->_m_waiters) a_spin();
+
+	while ((r=pthread_mutex_trylock(m)) == EBUSY) {
+		if (!(r=m->_m_lock) || ((r&0x40000000) && (m->_m_type&4)))
+			continue;
+		if ((m->_m_type&3) == PTHREAD_MUTEX_ERRORCHECK
+		 && (r&0x7fffffff) == __pthread_self()->tid)
+			return EDEADLK;
+
+		a_inc(&m->_m_waiters);
+		t = r | 0x80000000;
+		a_cas(&m->_m_lock, r, t);
+		r = __timedwait(&m->_m_lock, t, CLOCK_REALTIME, at, priv);
+		a_dec(&m->_m_waiters);
+		if (r && r != EINTR) break;
+	}
+	return r;
+}
+
+weak_alias(__pthread_mutex_timedlock, pthread_mutex_timedlock);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_trylock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_trylock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_trylock.c	(revision 398)
@@ -0,0 +1,58 @@
+#include "pthread_impl.h"
+
+int __pthread_mutex_trylock_owner(pthread_mutex_t *m)
+{
+	int old, own;
+	int type = m->_m_type & 15;
+	pthread_t self = __pthread_self();
+	int tid = self->tid;
+
+	old = m->_m_lock;
+	own = old & 0x7fffffff;
+	if (own == tid && (type&3) == PTHREAD_MUTEX_RECURSIVE) {
+		if ((unsigned)m->_m_count >= INT_MAX) return EAGAIN;
+		m->_m_count++;
+		return 0;
+	}
+	if (own == 0x7fffffff) return ENOTRECOVERABLE;
+
+	if (m->_m_type & 128) {
+		if (!self->robust_list.off) {
+			self->robust_list.off = (char*)&m->_m_lock-(char *)&m->_m_next;
+			__syscall(SYS_set_robust_list, &self->robust_list, 3*sizeof(long));
+		}
+		if (m->_m_waiters) tid |= 0x80000000;
+		self->robust_list.pending = &m->_m_next;
+	}
+
+	if ((own && (!(own & 0x40000000) || !(type & 4)))
+	    || a_cas(&m->_m_lock, old, tid) != old) {
+		self->robust_list.pending = 0;
+		return EBUSY;
+	}
+
+	volatile void *next = self->robust_list.head;
+	m->_m_next = next;
+	m->_m_prev = &self->robust_list.head;
+	if (next != &self->robust_list.head) *(volatile void *volatile *)
+		((char *)next - sizeof(void *)) = &m->_m_next;
+	self->robust_list.head = &m->_m_next;
+	self->robust_list.pending = 0;
+
+	if (own) {
+		m->_m_count = 0;
+		m->_m_type |= 8;
+		return EOWNERDEAD;
+	}
+
+	return 0;
+}
+
+int __pthread_mutex_trylock(pthread_mutex_t *m)
+{
+	if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL)
+		return a_cas(&m->_m_lock, 0, EBUSY) & EBUSY;
+	return __pthread_mutex_trylock_owner(m);
+}
+
+weak_alias(__pthread_mutex_trylock, pthread_mutex_trylock);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_unlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_unlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutex_unlock.c	(revision 398)
@@ -0,0 +1,37 @@
+#include "pthread_impl.h"
+
+int __pthread_mutex_unlock(pthread_mutex_t *m)
+{
+	pthread_t self;
+	int waiters = m->_m_waiters;
+	int cont;
+	int type = m->_m_type & 15;
+	int priv = (m->_m_type & 128) ^ 128;
+
+	if (type != PTHREAD_MUTEX_NORMAL) {
+		self = __pthread_self();
+		if ((m->_m_lock&0x7fffffff) != self->tid)
+			return EPERM;
+		if ((type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count)
+			return m->_m_count--, 0;
+		if (!priv) {
+			self->robust_list.pending = &m->_m_next;
+			__vm_lock();
+		}
+		volatile void *prev = m->_m_prev;
+		volatile void *next = m->_m_next;
+		*(volatile void *volatile *)prev = next;
+		if (next != &self->robust_list.head) *(volatile void *volatile *)
+			((char *)next - sizeof(void *)) = prev;
+	}
+	cont = a_swap(&m->_m_lock, (type & 8) ? 0x7fffffff : 0);
+	if (type != PTHREAD_MUTEX_NORMAL && !priv) {
+		self->robust_list.pending = 0;
+		__vm_unlock();
+	}
+	if (waiters || cont<0)
+		__wake(&m->_m_lock, 1, priv);
+	return 0;
+}
+
+weak_alias(__pthread_mutex_unlock, pthread_mutex_unlock);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t *a)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_init.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_init(pthread_mutexattr_t *a)
+{
+	*a = (pthread_mutexattr_t){0};
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_setprotocol.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_setprotocol.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_setprotocol.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol)
+{
+	if (protocol) return ENOTSUP;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_setpshared.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_setpshared.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_setpshared.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *a, int pshared)
+{
+	if (pshared > 1U) return EINVAL;
+	a->__attr &= ~128U;
+	a->__attr |= pshared<<7;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_setrobust.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_setrobust.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_setrobust.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust)
+{
+	if (robust > 1U) return EINVAL;
+	a->__attr &= ~4;
+	a->__attr |= robust*4;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_settype.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_settype.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_mutexattr_settype.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type)
+{
+	if ((unsigned)type > 2) return EINVAL;
+	a->__attr = (a->__attr & ~3) | type;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_once.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_once.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_once.c	(revision 398)
@@ -0,0 +1,50 @@
+#include "pthread_impl.h"
+
+static void undo(void *control)
+{
+	/* Wake all waiters, since the waiter status is lost when
+	 * resetting control to the initial state. */
+	if (a_swap(control, 0) == 3)
+		__wake(control, -1, 1);
+}
+
+int __pthread_once_full(pthread_once_t *control, void (*init)(void))
+{
+	/* Try to enter initializing state. Four possibilities:
+	 *  0 - we're the first or the other cancelled; run init
+	 *  1 - another thread is running init; wait
+	 *  2 - another thread finished running init; just return
+	 *  3 - another thread is running init, waiters present; wait */
+
+	for (;;) switch (a_cas(control, 0, 1)) {
+	case 0:
+		pthread_cleanup_push(undo, control);
+		init();
+		pthread_cleanup_pop(0);
+
+		if (a_swap(control, 2) == 3)
+			__wake(control, -1, 1);
+		return 0;
+	case 1:
+		/* If this fails, so will __wait. */
+		a_cas(control, 1, 3);
+	case 3:
+		__wait(control, 0, 3, 1);
+		continue;
+	case 2:
+		return 0;
+	}
+}
+
+int __pthread_once(pthread_once_t *control, void (*init)(void))
+{
+	/* Return immediately if init finished before, but ensure that
+	 * effects of the init routine are visible to the caller. */
+	if (*(volatile int *)control == 2) {
+		a_barrier();
+		return 0;
+	}
+	return __pthread_once_full(control, init);
+}
+
+weak_alias(__pthread_once, pthread_once);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_destroy(pthread_rwlock_t *rw)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_init.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_init(pthread_rwlock_t *restrict rw, const pthread_rwlockattr_t *restrict a)
+{
+	*rw = (pthread_rwlock_t){0};
+	if (a) rw->_rw_shared = a->__attr[0]*128;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_rdlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_rdlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_rdlock.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *rw)
+{
+	return pthread_rwlock_timedrdlock(rw, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_timedrdlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_timedrdlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_timedrdlock.c	(revision 398)
@@ -0,0 +1,23 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)
+{
+	int r, t;
+
+	r = pthread_rwlock_tryrdlock(rw);
+	if (r != EBUSY) return r;
+	
+	int spins = 100;
+	while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin();
+
+	while ((r=pthread_rwlock_tryrdlock(rw))==EBUSY) {
+		if (!(r=rw->_rw_lock) || (r&0x7fffffff)!=0x7fffffff) continue;
+		t = r | 0x80000000;
+		a_inc(&rw->_rw_waiters);
+		a_cas(&rw->_rw_lock, r, t);
+		r = __timedwait(&rw->_rw_lock, t, CLOCK_REALTIME, at, rw->_rw_shared^128);
+		a_dec(&rw->_rw_waiters);
+		if (r && r != EINTR) return r;
+	}
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_timedwrlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_timedwrlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_timedwrlock.c	(revision 398)
@@ -0,0 +1,23 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)
+{
+	int r, t;
+	
+	r = pthread_rwlock_trywrlock(rw);
+	if (r != EBUSY) return r;
+	
+	int spins = 100;
+	while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin();
+
+	while ((r=pthread_rwlock_trywrlock(rw))==EBUSY) {
+		if (!(r=rw->_rw_lock)) continue;
+		t = r | 0x80000000;
+		a_inc(&rw->_rw_waiters);
+		a_cas(&rw->_rw_lock, r, t);
+		r = __timedwait(&rw->_rw_lock, t, CLOCK_REALTIME, at, rw->_rw_shared^128);
+		a_dec(&rw->_rw_waiters);
+		if (r && r != EINTR) return r;
+	}
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_tryrdlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_tryrdlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_tryrdlock.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rw)
+{
+	int val, cnt;
+	do {
+		val = rw->_rw_lock;
+		cnt = val & 0x7fffffff;
+		if (cnt == 0x7fffffff) return EBUSY;
+		if (cnt == 0x7ffffffe) return EAGAIN;
+	} while (a_cas(&rw->_rw_lock, val, val+1) != val);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_trywrlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_trywrlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_trywrlock.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rw)
+{
+	if (a_cas(&rw->_rw_lock, 0, 0x7fffffff)) return EBUSY;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_unlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_unlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_unlock.c	(revision 398)
@@ -0,0 +1,18 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_unlock(pthread_rwlock_t *rw)
+{
+	int val, cnt, waiters, new, priv = rw->_rw_shared^128;
+
+	do {
+		val = rw->_rw_lock;
+		cnt = val & 0x7fffffff;
+		waiters = rw->_rw_waiters;
+		new = (cnt == 0x7fffffff || cnt == 1) ? 0 : val-1;
+	} while (a_cas(&rw->_rw_lock, val, new) != val);
+
+	if (!new && (waiters || val<0))
+		__wake(&rw->_rw_lock, cnt, priv);
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_wrlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_wrlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlock_wrlock.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *rw)
+{
+	return pthread_rwlock_timedwrlock(rw, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlockattr_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlockattr_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlockattr_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlockattr_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlockattr_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlockattr_init.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_rwlockattr_init(pthread_rwlockattr_t *a)
+{
+	*a = (pthread_rwlockattr_t){0};
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlockattr_setpshared.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlockattr_setpshared.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_rwlockattr_setpshared.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int pshared)
+{
+	if (pshared > 1U) return EINVAL;
+	a->__attr[0] = pshared;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_self.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_self.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_self.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+#include <threads.h>
+#include "libc.h"
+
+static pthread_t __pthread_self_internal()
+{
+	return __pthread_self();
+}
+
+weak_alias(__pthread_self_internal, pthread_self);
+weak_alias(__pthread_self_internal, thrd_current);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setattr_default_np.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setattr_default_np.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setattr_default_np.c	(revision 398)
@@ -0,0 +1,35 @@
+#include "pthread_impl.h"
+#include <string.h>
+
+extern size_t __default_stacksize;
+extern size_t __default_guardsize;
+
+int pthread_setattr_default_np(const pthread_attr_t *attrp)
+{
+	/* Reject anything in the attr object other than stack/guard size. */
+	pthread_attr_t tmp = *attrp, zero = { 0 };
+	tmp._a_stacksize = 0;
+	tmp._a_guardsize = 0;
+	if (memcmp(&tmp, &zero, sizeof tmp))
+		return EINVAL;
+
+	__inhibit_ptc();
+	if (attrp->_a_stacksize >= __default_stacksize)
+		__default_stacksize = attrp->_a_stacksize;
+	if (attrp->_a_guardsize >= __default_guardsize)
+		__default_guardsize = attrp->_a_guardsize;
+	__release_ptc();
+
+	return 0;
+}
+
+int pthread_getattr_default_np(pthread_attr_t *attrp)
+{
+	__acquire_ptc();
+	*attrp = (pthread_attr_t) {
+		._a_stacksize = __default_stacksize,
+		._a_guardsize = __default_guardsize,
+	};
+	__release_ptc();
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setcancelstate.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setcancelstate.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setcancelstate.c	(revision 398)
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+
+int __pthread_setcancelstate(int new, int *old)
+{
+	if (new > 2U) return EINVAL;
+	struct pthread *self = __pthread_self();
+	if (old) *old = self->canceldisable;
+	self->canceldisable = new;
+	return 0;
+}
+
+weak_alias(__pthread_setcancelstate, pthread_setcancelstate);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setcanceltype.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setcanceltype.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setcanceltype.c	(revision 398)
@@ -0,0 +1,11 @@
+#include "pthread_impl.h"
+
+int pthread_setcanceltype(int new, int *old)
+{
+	struct pthread *self = __pthread_self();
+	if (new > 1U) return EINVAL;
+	if (old) *old = self->cancelasync;
+	self->cancelasync = new;
+	if (new) pthread_testcancel();
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setconcurrency.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setconcurrency.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setconcurrency.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <pthread.h>
+#include <errno.h>
+
+int pthread_setconcurrency(int val)
+{
+	if (val < 0) return EINVAL;
+	if (val > 0) return EAGAIN;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setname_np.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setname_np.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setname_np.c	(revision 398)
@@ -0,0 +1,26 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/prctl.h>
+
+#include "pthread_impl.h"
+
+int pthread_setname_np(pthread_t thread, const char *name)
+{
+	int fd, cs, status = 0;
+	char f[sizeof "/proc/self/task//comm" + 3*sizeof(int)];
+	size_t len;
+
+	if ((len = strnlen(name, 16)) > 15) return ERANGE;
+
+	if (thread == pthread_self())
+		return prctl(PR_SET_NAME, (unsigned long)name, 0UL, 0UL, 0UL) ? errno : 0;
+
+	snprintf(f, sizeof f, "/proc/self/task/%d/comm", thread->tid);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+	if ((fd = open(f, O_WRONLY)) < 0 || write(fd, name, len) < 0) status = errno;
+	if (fd >= 0) close(fd);
+	pthread_setcancelstate(cs, 0);
+	return status;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setschedparam.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setschedparam.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setschedparam.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+
+int pthread_setschedparam(pthread_t t, int policy, const struct sched_param *param)
+{
+	int r;
+	__lock(t->killlock);
+	r = t->dead ? ESRCH : -__syscall(SYS_sched_setscheduler, t->tid, policy, param);
+	__unlock(t->killlock);
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setschedprio.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setschedprio.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setschedprio.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "pthread_impl.h"
+
+int pthread_setschedprio(pthread_t t, int prio)
+{
+	int r;
+	__lock(t->killlock);
+	r = t->dead ? ESRCH : -__syscall(SYS_sched_setparam, t->tid, &prio);
+	__unlock(t->killlock);
+	return r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setspecific.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setspecific.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_setspecific.c	(revision 398)
@@ -0,0 +1,12 @@
+#include "pthread_impl.h"
+
+int pthread_setspecific(pthread_key_t k, const void *x)
+{
+	struct pthread *self = __pthread_self();
+	/* Avoid unnecessary COW */
+	if (self->tsd[k] != x) {
+		self->tsd[k] = (void *)x;
+		self->tsd_used = 1;
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_sigmask.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_sigmask.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_sigmask.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+
+int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
+{
+	int ret;
+	if ((unsigned)how - SIG_BLOCK > 2U) return EINVAL;
+	ret = -__syscall(SYS_rt_sigprocmask, how, set, old, _NSIG/8);
+	if (!ret && old) {
+		if (sizeof old->__bits[0] == 8) {
+			old->__bits[0] &= ~0x380000000ULL;
+		} else {
+			old->__bits[0] &= ~0x80000000UL;
+			old->__bits[1] &= ~0x3UL;
+		}
+	}
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_spin_destroy(pthread_spinlock_t *s)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_init.c	(revision 398)
@@ -0,0 +1,6 @@
+#include "pthread_impl.h"
+
+int pthread_spin_init(pthread_spinlock_t *s, int shared)
+{
+	return *s = 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_lock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_lock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_lock.c	(revision 398)
@@ -0,0 +1,8 @@
+#include "pthread_impl.h"
+#include <errno.h>
+
+int pthread_spin_lock(pthread_spinlock_t *s)
+{
+	while (*(volatile int *)s || a_cas(s, 0, EBUSY)) a_spin();
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_trylock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_trylock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_trylock.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+#include <errno.h>
+
+int pthread_spin_trylock(pthread_spinlock_t *s)
+{
+	return a_cas(s, 0, EBUSY);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_unlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_unlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_spin_unlock.c	(revision 398)
@@ -0,0 +1,7 @@
+#include "pthread_impl.h"
+
+int pthread_spin_unlock(pthread_spinlock_t *s)
+{
+	a_store(s, 0);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_testcancel.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_testcancel.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/pthread_testcancel.c	(revision 398)
@@ -0,0 +1,15 @@
+#include "pthread_impl.h"
+#include "libc.h"
+
+static void dummy()
+{
+}
+
+weak_alias(dummy, __testcancel);
+
+void __pthread_testcancel()
+{
+	__testcancel();
+}
+
+weak_alias(__pthread_testcancel, pthread_testcancel);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_destroy.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_destroy.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_destroy.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <semaphore.h>
+
+int sem_destroy(sem_t *sem)
+{
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_getvalue.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_getvalue.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_getvalue.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <semaphore.h>
+
+int sem_getvalue(sem_t *restrict sem, int *restrict valp)
+{
+	int val = sem->__val[0];
+	*valp = val < 0 ? 0 : val;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_init.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_init.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_init.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <semaphore.h>
+#include <limits.h>
+#include <errno.h>
+
+int sem_init(sem_t *sem, int pshared, unsigned value)
+{
+	if (value > SEM_VALUE_MAX) {
+		errno = EINVAL;
+		return -1;
+	}
+	sem->__val[0] = value;
+	sem->__val[1] = 0;
+	sem->__val[2] = pshared ? 0 : 128;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_open.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_open.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_open.c	(revision 398)
@@ -0,0 +1,175 @@
+#include <semaphore.h>
+#include <sys/mman.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <time.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include "libc.h"
+
+char *__shm_mapname(const char *, char *);
+
+static struct {
+	ino_t ino;
+	sem_t *sem;
+	int refcnt;
+} *semtab;
+static volatile int lock[2];
+
+#define FLAGS (O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK)
+
+sem_t *sem_open(const char *name, int flags, ...)
+{
+	va_list ap;
+	mode_t mode;
+	unsigned value;
+	int fd, i, e, slot, first=1, cnt, cs;
+	sem_t newsem;
+	void *map;
+	char tmp[64];
+	struct timespec ts;
+	struct stat st;
+	char buf[NAME_MAX+10];
+
+	if (!(name = __shm_mapname(name, buf)))
+		return SEM_FAILED;
+
+	LOCK(lock);
+	/* Allocate table if we don't have one yet */
+	if (!semtab && !(semtab = calloc(sizeof *semtab, SEM_NSEMS_MAX))) {
+		UNLOCK(lock);
+		return SEM_FAILED;
+	}
+
+	/* Reserve a slot in case this semaphore is not mapped yet;
+	 * this is necessary because there is no way to handle
+	 * failures after creation of the file. */
+	slot = -1;
+	for (cnt=i=0; i<SEM_NSEMS_MAX; i++) {
+		cnt += semtab[i].refcnt;
+		if (!semtab[i].sem && slot < 0) slot = i;
+	}
+	/* Avoid possibility of overflow later */
+	if (cnt == INT_MAX || slot < 0) {
+		errno = EMFILE;
+		UNLOCK(lock);
+		return SEM_FAILED;
+	}
+	/* Dummy pointer to make a reservation */
+	semtab[slot].sem = (sem_t *)-1;
+	UNLOCK(lock);
+
+	flags &= (O_CREAT|O_EXCL);
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	/* Early failure check for exclusive open; otherwise the case
+	 * where the semaphore already exists is expensive. */
+	if (flags == (O_CREAT|O_EXCL) && access(name, F_OK) == 0) {
+		errno = EEXIST;
+		goto fail;
+	}
+
+	for (;;) {
+		/* If exclusive mode is not requested, try opening an
+		 * existing file first and fall back to creation. */
+		if (flags != (O_CREAT|O_EXCL)) {
+			fd = open(name, FLAGS);
+			if (fd >= 0) {
+				if (fstat(fd, &st) < 0 ||
+				    (map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
+					close(fd);
+					goto fail;
+				}
+				close(fd);
+				break;
+			}
+			if (errno != ENOENT)
+				goto fail;
+		}
+		if (!(flags & O_CREAT))
+			goto fail;
+		if (first) {
+			first = 0;
+			va_start(ap, flags);
+			mode = va_arg(ap, mode_t) & 0666;
+			value = va_arg(ap, unsigned);
+			va_end(ap);
+			if (value > SEM_VALUE_MAX) {
+				errno = EINVAL;
+				goto fail;
+			}
+			sem_init(&newsem, 1, value);
+		}
+		/* Create a temp file with the new semaphore contents
+		 * and attempt to atomically link it as the new name */
+		clock_gettime(CLOCK_REALTIME, &ts);
+		snprintf(tmp, sizeof(tmp), "/dev/shm/tmp-%d", (int)ts.tv_nsec);
+		fd = open(tmp, O_CREAT|O_EXCL|FLAGS, mode);
+		if (fd < 0) {
+			if (errno == EEXIST) continue;
+			goto fail;
+		}
+		if (write(fd, &newsem, sizeof newsem) != sizeof newsem || fstat(fd, &st) < 0 ||
+		    (map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
+			close(fd);
+			unlink(tmp);
+			goto fail;
+		}
+		close(fd);
+		e = link(tmp, name) ? errno : 0;
+		unlink(tmp);
+		if (!e) break;
+		munmap(map, sizeof(sem_t));
+		/* Failure is only fatal when doing an exclusive open;
+		 * otherwise, next iteration will try to open the
+		 * existing file. */
+		if (e != EEXIST || flags == (O_CREAT|O_EXCL))
+			goto fail;
+	}
+
+	/* See if the newly mapped semaphore is already mapped. If
+	 * so, unmap the new mapping and use the existing one. Otherwise,
+	 * add it to the table of mapped semaphores. */
+	LOCK(lock);
+	for (i=0; i<SEM_NSEMS_MAX && semtab[i].ino != st.st_ino; i++);
+	if (i<SEM_NSEMS_MAX) {
+		munmap(map, sizeof(sem_t));
+		semtab[slot].sem = 0;
+		slot = i;
+		map = semtab[i].sem;
+	}
+	semtab[slot].refcnt++;
+	semtab[slot].sem = map;
+	semtab[slot].ino = st.st_ino;
+	UNLOCK(lock);
+	pthread_setcancelstate(cs, 0);
+	return map;
+
+fail:
+	pthread_setcancelstate(cs, 0);
+	LOCK(lock);
+	semtab[slot].sem = 0;
+	UNLOCK(lock);
+	return SEM_FAILED;
+}
+
+int sem_close(sem_t *sem)
+{
+	int i;
+	LOCK(lock);
+	for (i=0; i<SEM_NSEMS_MAX && semtab[i].sem != sem; i++);
+	if (!--semtab[i].refcnt) {
+		semtab[i].sem = 0;
+		semtab[i].ino = 0;
+	}
+	UNLOCK(lock);
+	munmap(sem, sizeof *sem);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_post.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_post.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_post.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <semaphore.h>
+#include "pthread_impl.h"
+
+int sem_post(sem_t *sem)
+{
+	int val, waiters, priv = sem->__val[2];
+	do {
+		val = sem->__val[0];
+		waiters = sem->__val[1];
+		if (val == SEM_VALUE_MAX) {
+			errno = EOVERFLOW;
+			return -1;
+		}
+	} while (a_cas(sem->__val, val, val+1+(val<0)) != val);
+	if (val<0 || waiters) __wake(sem->__val, 1, priv);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_timedwait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_timedwait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_timedwait.c	(revision 398)
@@ -0,0 +1,31 @@
+#include <semaphore.h>
+#include "pthread_impl.h"
+
+static void cleanup(void *p)
+{
+	a_dec(p);
+}
+
+int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at)
+{
+	pthread_testcancel();
+
+	if (!sem_trywait(sem)) return 0;
+
+	int spins = 100;
+	while (spins-- && sem->__val[0] <= 0 && !sem->__val[1]) a_spin();
+
+	while (sem_trywait(sem)) {
+		int r;
+		a_inc(sem->__val+1);
+		a_cas(sem->__val, 0, -1);
+		pthread_cleanup_push(cleanup, (void *)(sem->__val+1));
+		r = __timedwait_cp(sem->__val, -1, CLOCK_REALTIME, at, sem->__val[2]);
+		pthread_cleanup_pop(1);
+		if (r && r != EINTR) {
+			errno = r;
+			return -1;
+		}
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_trywait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_trywait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_trywait.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <semaphore.h>
+#include "pthread_impl.h"
+
+int sem_trywait(sem_t *sem)
+{
+	int val;
+	while ((val=sem->__val[0]) > 0) {
+		int new = val-1-(val==1 && sem->__val[1]);
+		if (a_cas(sem->__val, val, new)==val) return 0;
+	}
+	errno = EAGAIN;
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_unlink.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_unlink.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_unlink.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <semaphore.h>
+#include <sys/mman.h>
+
+int sem_unlink(const char *name)
+{
+	return shm_unlink(name);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_wait.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_wait.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/sem_wait.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <semaphore.h>
+
+int sem_wait(sem_t *sem)
+{
+	return sem_timedwait(sem, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/synccall.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/synccall.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/synccall.c	(revision 398)
@@ -0,0 +1,178 @@
+#include "pthread_impl.h"
+#include <semaphore.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <string.h>
+#include <ctype.h>
+#include "futex.h"
+#include "atomic.h"
+#include "../dirent/__dirent.h"
+
+static struct chain {
+	struct chain *next;
+	int tid;
+	sem_t target_sem, caller_sem;
+} *volatile head;
+
+static volatile int synccall_lock[2];
+static volatile int target_tid;
+static void (*callback)(void *), *context;
+static volatile int dummy = 0;
+weak_alias(dummy, __block_new_threads);
+
+static void handler(int sig)
+{
+	struct chain ch;
+	int old_errno = errno;
+
+	sem_init(&ch.target_sem, 0, 0);
+	sem_init(&ch.caller_sem, 0, 0);
+
+	ch.tid = __syscall(SYS_gettid);
+
+	do ch.next = head;
+	while (a_cas_p(&head, ch.next, &ch) != ch.next);
+
+	if (a_cas(&target_tid, ch.tid, 0) == (ch.tid | 0x80000000))
+		__syscall(SYS_futex, &target_tid, FUTEX_UNLOCK_PI|FUTEX_PRIVATE);
+
+	sem_wait(&ch.target_sem);
+	callback(context);
+	sem_post(&ch.caller_sem);
+	sem_wait(&ch.target_sem);
+
+	errno = old_errno;
+}
+
+void __synccall(void (*func)(void *), void *ctx)
+{
+	sigset_t oldmask;
+	int cs, i, r, pid, self;;
+	DIR dir = {0};
+	struct dirent *de;
+	struct sigaction sa = { .sa_flags = SA_RESTART, .sa_handler = handler };
+	struct chain *cp, *next;
+	struct timespec ts;
+
+	/* Blocking signals in two steps, first only app-level signals
+	 * before taking the lock, then all signals after taking the lock,
+	 * is necessary to achieve AS-safety. Blocking them all first would
+	 * deadlock if multiple threads called __synccall. Waiting to block
+	 * any until after the lock would allow re-entry in the same thread
+	 * with the lock already held. */
+	__block_app_sigs(&oldmask);
+	LOCK(synccall_lock);
+	__block_all_sigs(0);
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	head = 0;
+
+	if (!libc.threaded) goto single_threaded;
+
+	callback = func;
+	context = ctx;
+
+	/* This atomic store ensures that any signaled threads will see the
+	 * above stores, and prevents more than a bounded number of threads,
+	 * those already in pthread_create, from creating new threads until
+	 * the value is cleared to zero again. */
+	a_store(&__block_new_threads, 1);
+
+	/* Block even implementation-internal signals, so that nothing
+	 * interrupts the SIGSYNCCALL handlers. The main possible source
+	 * of trouble is asynchronous cancellation. */
+	memset(&sa.sa_mask, -1, sizeof sa.sa_mask);
+	__libc_sigaction(SIGSYNCCALL, &sa, 0);
+
+	pid = __syscall(SYS_getpid);
+	self = __syscall(SYS_gettid);
+
+	/* Since opendir is not AS-safe, the DIR needs to be setup manually
+	 * in automatic storage. Thankfully this is easy. */
+	dir.fd = open("/proc/self/task", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
+	if (dir.fd < 0) goto out;
+
+	/* Initially send one signal per counted thread. But since we can't
+	 * synchronize with thread creation/exit here, there could be too
+	 * few signals. This initial signaling is just an optimization, not
+	 * part of the logic. */
+	for (i=libc.threads_minus_1; i; i--)
+		__syscall(SYS_kill, pid, SIGSYNCCALL);
+
+	/* Loop scanning the kernel-provided thread list until it shows no
+	 * threads that have not already replied to the signal. */
+	for (;;) {
+		int miss_cnt = 0;
+		while ((de = readdir(&dir))) {
+			if (!isdigit(de->d_name[0])) continue;
+			int tid = atoi(de->d_name);
+			if (tid == self || !tid) continue;
+
+			/* Set the target thread as the PI futex owner before
+			 * checking if it's in the list of caught threads. If it
+			 * adds itself to the list after we check for it, then
+			 * it will see its own tid in the PI futex and perform
+			 * the unlock operation. */
+			a_store(&target_tid, tid);
+
+			/* Thread-already-caught is a success condition. */
+			for (cp = head; cp && cp->tid != tid; cp=cp->next);
+			if (cp) continue;
+
+			r = -__syscall(SYS_tgkill, pid, tid, SIGSYNCCALL);
+
+			/* Target thread exit is a success condition. */
+			if (r == ESRCH) continue;
+
+			/* The FUTEX_LOCK_PI operation is used to loan priority
+			 * to the target thread, which otherwise may be unable
+			 * to run. Timeout is necessary because there is a race
+			 * condition where the tid may be reused by a different
+			 * process. */
+			clock_gettime(CLOCK_REALTIME, &ts);
+			ts.tv_nsec += 10000000;
+			if (ts.tv_nsec >= 1000000000) {
+				ts.tv_sec++;
+				ts.tv_nsec -= 1000000000;
+			}
+			r = -__syscall(SYS_futex, &target_tid,
+				FUTEX_LOCK_PI|FUTEX_PRIVATE, 0, &ts);
+
+			/* Obtaining the lock means the thread responded. ESRCH
+			 * means the target thread exited, which is okay too. */
+			if (!r || r == ESRCH) continue;
+
+			miss_cnt++;
+		}
+		if (!miss_cnt) break;
+		rewinddir(&dir);
+	}
+	close(dir.fd);
+
+	/* Serialize execution of callback in caught threads. */
+	for (cp=head; cp; cp=cp->next) {
+		sem_post(&cp->target_sem);
+		sem_wait(&cp->caller_sem);
+	}
+
+	sa.sa_handler = SIG_IGN;
+	__libc_sigaction(SIGSYNCCALL, &sa, 0);
+
+single_threaded:
+	func(ctx);
+
+	/* Only release the caught threads once all threads, including the
+	 * caller, have returned from the callback function. */
+	for (cp=head; cp; cp=next) {
+		next = cp->next;
+		sem_post(&cp->target_sem);
+	}
+
+out:
+	a_store(&__block_new_threads, 0);
+	__wake(&__block_new_threads, -1, 1);
+
+	pthread_setcancelstate(cs, 0);
+	UNLOCK(synccall_lock);
+	__restore_sigs(&oldmask);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_create.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_create.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_create.c	(revision 398)
@@ -0,0 +1,14 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int __pthread_create(pthread_t *restrict, const pthread_attr_t *restrict, void *(*)(void *), void *restrict);
+
+int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
+{
+	int ret = __pthread_create(thr, __ATTRP_C11_THREAD, (void *(*)(void *))func, arg);
+	switch (ret) {
+	case 0:      return thrd_success;
+	case EAGAIN: return thrd_nomem;
+	default:     return thrd_error;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_exit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_exit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_exit.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+_Noreturn void __pthread_exit(void *);
+
+_Noreturn void thrd_exit(int result)
+{
+	__pthread_exit((void*)(intptr_t)result);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_join.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_join.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_join.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <stdint.h>
+#include <threads.h>
+
+int __pthread_join(thrd_t, void**);
+
+int thrd_join(thrd_t t, int *res)
+{
+        void *pthread_res;
+        __pthread_join(t, &pthread_res);
+        if (res) *res = (int)(intptr_t)pthread_res;
+        return thrd_success;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_sleep.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_sleep.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_sleep.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <threads.h>
+#include <errno.h>
+#include "syscall.h"
+
+int thrd_sleep(const struct timespec *req, struct timespec *rem)
+{
+	int ret = __syscall(SYS_nanosleep, req, rem);
+	switch (ret) {
+	case 0:      return 0;
+	case -EINTR: return -1; /* value specified by C11 */
+	default:     return -2;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_yield.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_yield.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/thrd_yield.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <threads.h>
+#include "syscall.h"
+
+void thrd_yield()
+{
+	__syscall(SYS_sched_yield);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/tss_create.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/tss_create.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/tss_create.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <threads.h>
+
+int __pthread_key_create(tss_t *, void (*)(void *));
+
+int tss_create(tss_t *tss, tss_dtor_t dtor)
+{
+	/* Different error returns are possible. C glues them together into
+	 * just failure notification. Can't be optimized to a tail call,
+	 * unless thrd_error equals EAGAIN. */
+	return __pthread_key_create(tss, dtor) ? thrd_error : thrd_success;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/tss_delete.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/tss_delete.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/tss_delete.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <threads.h>
+
+int __pthread_key_delete(tss_t k);
+
+void tss_delete(tss_t key)
+{
+	__pthread_key_delete(key);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/tss_set.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/tss_set.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/tss_set.c	(revision 398)
@@ -0,0 +1,13 @@
+#include "pthread_impl.h"
+#include <threads.h>
+
+int tss_set(tss_t k, void *x)
+{
+	struct pthread *self = __pthread_self();
+	/* Avoid unnecessary COW */
+	if (self->tsd[k] != x) {
+		self->tsd[k] = x;
+		self->tsd_used = 1;
+	}
+	return thrd_success;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/vmlock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/vmlock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/thread/vmlock.c	(revision 398)
@@ -0,0 +1,21 @@
+#include "pthread_impl.h"
+
+static volatile int vmlock[2];
+
+void __vm_wait()
+{
+	int tmp;
+	while ((tmp=vmlock[0]))
+		__wait(vmlock, vmlock+1, tmp, 1);
+}
+
+void __vm_lock()
+{
+	a_inc(vmlock);
+}
+
+void __vm_unlock()
+{
+	if (a_fetch_add(vmlock, -1)==1 && vmlock[1])
+		__wake(vmlock, -1, 1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__asctime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__asctime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__asctime.c	(revision 398)
@@ -0,0 +1,28 @@
+#include <time.h>
+#include <stdio.h>
+#include <langinfo.h>
+#include "locale_impl.h"
+#include "atomic.h"
+
+const char *__nl_langinfo_l(nl_item, locale_t);
+
+char *__asctime(const struct tm *restrict tm, char *restrict buf)
+{
+	if (snprintf(buf, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+		__nl_langinfo_l(ABDAY_1+tm->tm_wday, C_LOCALE),
+		__nl_langinfo_l(ABMON_1+tm->tm_mon, C_LOCALE),
+		tm->tm_mday, tm->tm_hour,
+		tm->tm_min, tm->tm_sec,
+		1900 + tm->tm_year) >= 26)
+	{
+		/* ISO C requires us to use the above format string,
+		 * even if it will not fit in the buffer. Thus asctime_r
+		 * is _supposed_ to crash if the fields in tm are too large.
+		 * We follow this behavior and crash "gracefully" to warn
+		 * application developers that they may not be so lucky
+		 * on other implementations (e.g. stack smashing..).
+		 */
+		a_crash();
+	}
+	return buf;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__map_file.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__map_file.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__map_file.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include "syscall.h"
+
+void *__mmap(void *, size_t, int, int, int, off_t);
+
+const char unsigned *__map_file(const char *pathname, size_t *size)
+{
+	struct stat st;
+	const unsigned char *map = MAP_FAILED;
+	int fd = __sys_open(pathname, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
+	if (fd < 0) return 0;
+	if (!__syscall(SYS_fstat, fd, &st)) {
+		map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+		*size = st.st_size;
+	}
+	__syscall(SYS_close, fd);
+	return map == MAP_FAILED ? 0 : map;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__month_to_secs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__month_to_secs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__month_to_secs.c	(revision 398)
@@ -0,0 +1,10 @@
+int __month_to_secs(int month, int is_leap)
+{
+	static const int secs_through_month[] = {
+		0, 31*86400, 59*86400, 90*86400,
+		120*86400, 151*86400, 181*86400, 212*86400,
+		243*86400, 273*86400, 304*86400, 334*86400 };
+	int t = secs_through_month[month];
+	if (is_leap && month >= 2) t+=86400;
+	return t;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__secs_to_tm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__secs_to_tm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__secs_to_tm.c	(revision 398)
@@ -0,0 +1,82 @@
+#include "time_impl.h"
+#include <limits.h>
+
+/* 2000-03-01 (mod 400 year, immediately after feb29 */
+#define LEAPOCH (946684800LL + 86400*(31+29))
+
+#define DAYS_PER_400Y (365*400 + 97)
+#define DAYS_PER_100Y (365*100 + 24)
+#define DAYS_PER_4Y   (365*4   + 1)
+
+int __secs_to_tm(long long t, struct tm *tm)
+{
+	long long days, secs, years;
+	int remdays, remsecs, remyears;
+	int qc_cycles, c_cycles, q_cycles;
+	int months;
+	int wday, yday, leap;
+	static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
+
+	/* Reject time_t values whose year would overflow int */
+	if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
+		return -1;
+
+	secs = t - LEAPOCH;
+	days = secs / 86400;
+	remsecs = secs % 86400;
+	if (remsecs < 0) {
+		remsecs += 86400;
+		days--;
+	}
+
+	wday = (3+days)%7;
+	if (wday < 0) wday += 7;
+
+	qc_cycles = days / DAYS_PER_400Y;
+	remdays = days % DAYS_PER_400Y;
+	if (remdays < 0) {
+		remdays += DAYS_PER_400Y;
+		qc_cycles--;
+	}
+
+	c_cycles = remdays / DAYS_PER_100Y;
+	if (c_cycles == 4) c_cycles--;
+	remdays -= c_cycles * DAYS_PER_100Y;
+
+	q_cycles = remdays / DAYS_PER_4Y;
+	if (q_cycles == 25) q_cycles--;
+	remdays -= q_cycles * DAYS_PER_4Y;
+
+	remyears = remdays / 365;
+	if (remyears == 4) remyears--;
+	remdays -= remyears * 365;
+
+	leap = !remyears && (q_cycles || !c_cycles);
+	yday = remdays + 31 + 28 + leap;
+	if (yday >= 365+leap) yday -= 365+leap;
+
+	years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles;
+
+	for (months=0; days_in_month[months] <= remdays; months++)
+		remdays -= days_in_month[months];
+
+	if (months >= 10) {
+		months -= 12;
+		years++;
+	}
+
+	if (years+100 > INT_MAX || years+100 < INT_MIN)
+		return -1;
+
+	tm->tm_year = years + 100;
+	tm->tm_mon = months + 2;
+	tm->tm_mday = remdays + 1;
+	tm->tm_wday = wday;
+	tm->tm_yday = yday;
+
+	tm->tm_hour = remsecs / 3600;
+	tm->tm_min = remsecs / 60 % 60;
+	tm->tm_sec = remsecs % 60;
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__tm_to_secs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__tm_to_secs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__tm_to_secs.c	(revision 398)
@@ -0,0 +1,24 @@
+#include "time_impl.h"
+
+long long __tm_to_secs(const struct tm *tm)
+{
+	int is_leap;
+	long long year = tm->tm_year;
+	int month = tm->tm_mon;
+	if (month >= 12 || month < 0) {
+		int adj = month / 12;
+		month %= 12;
+		if (month < 0) {
+			adj--;
+			month += 12;
+		}
+		year += adj;
+	}
+	long long t = __year_to_secs(year, &is_leap);
+	t += __month_to_secs(month, is_leap);
+	t += 86400LL * (tm->tm_mday-1);
+	t += 3600LL * tm->tm_hour;
+	t += 60LL * tm->tm_min;
+	t += tm->tm_sec;
+	return t;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__tz.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__tz.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__tz.c	(revision 398)
@@ -0,0 +1,421 @@
+#include "time_impl.h"
+#include <stdint.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libc.h"
+
+long  __timezone = 0;
+int   __daylight = 0;
+char *__tzname[2] = { 0, 0 };
+
+weak_alias(__timezone, timezone);
+weak_alias(__daylight, daylight);
+weak_alias(__tzname, tzname);
+
+static char std_name[TZNAME_MAX+1];
+static char dst_name[TZNAME_MAX+1];
+const char __gmt[] = "GMT";
+
+static int dst_off;
+static int r0[5], r1[5];
+
+static const unsigned char *zi, *trans, *index, *types, *abbrevs, *abbrevs_end;
+static size_t map_size;
+
+static char old_tz_buf[32];
+static char *old_tz = old_tz_buf;
+static size_t old_tz_size = sizeof old_tz_buf;
+
+static volatile int lock[2];
+
+static int getint(const char **p)
+{
+	unsigned x;
+	for (x=0; **p-'0'<10U; (*p)++) x = **p-'0' + 10*x;
+	return x;
+}
+
+static int getoff(const char **p)
+{
+	int neg = 0;
+	if (**p == '-') {
+		++*p;
+		neg = 1;
+	} else if (**p == '+') {
+		++*p;
+	}
+	int off = 3600*getint(p);
+	if (**p == ':') {
+		++*p;
+		off += 60*getint(p);
+		if (**p == ':') {
+			++*p;
+			off += getint(p);
+		}
+	}
+	return neg ? -off : off;
+}
+
+static void getrule(const char **p, int rule[5])
+{
+	int r = rule[0] = **p;
+
+	if (r!='M') {
+		if (r=='J') ++*p;
+		else rule[0] = 0;
+		rule[1] = getint(p);
+	} else {
+		++*p; rule[1] = getint(p);
+		++*p; rule[2] = getint(p);
+		++*p; rule[3] = getint(p);
+	}
+
+	if (**p=='/') {
+		++*p;
+		rule[4] = getoff(p);
+	} else {
+		rule[4] = 7200;
+	}
+}
+
+static void getname(char *d, const char **p)
+{
+	int i;
+	if (**p == '<') {
+		++*p;
+		for (i=0; (*p)[i]!='>' && i<TZNAME_MAX; i++)
+			d[i] = (*p)[i];
+		++*p;
+	} else {
+		for (i=0; ((*p)[i]|32)-'a'<26U && i<TZNAME_MAX; i++)
+			d[i] = (*p)[i];
+	}
+	*p += i;
+	d[i] = 0;
+}
+
+#define VEC(...) ((const unsigned char[]){__VA_ARGS__})
+
+static uint32_t zi_read32(const unsigned char *z)
+{
+	return (unsigned)z[0]<<24 | z[1]<<16 | z[2]<<8 | z[3];
+}
+
+static size_t zi_dotprod(const unsigned char *z, const unsigned char *v, size_t n)
+{
+	size_t y;
+	uint32_t x;
+	for (y=0; n; n--, z+=4, v++) {
+		x = zi_read32(z);
+		y += x * *v;
+	}
+	return y;
+}
+
+int __munmap(void *, size_t);
+
+static void do_tzset()
+{
+	char buf[NAME_MAX+25], *pathname=buf+24;
+	const char *try, *s, *p;
+	const unsigned char *map = 0;
+	size_t i;
+	static const char search[] =
+		"/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
+
+	s = getenv("TZ");
+	if (!s) s = "/etc/localtime";
+	if (!*s) s = __gmt;
+
+	if (old_tz && !strcmp(s, old_tz)) return;
+
+	if (zi) __munmap((void *)zi, map_size);
+
+	/* Cache the old value of TZ to check if it has changed. Avoid
+	 * free so as not to pull it into static programs. Growth
+	 * strategy makes it so free would have minimal benefit anyway. */
+	i = strlen(s);
+	if (i > PATH_MAX+1) s = __gmt, i = 3;
+	if (i >= old_tz_size) {
+		old_tz_size *= 2;
+		if (i >= old_tz_size) old_tz_size = i+1;
+		if (old_tz_size > PATH_MAX+2) old_tz_size = PATH_MAX+2;
+		old_tz = malloc(old_tz_size);
+	}
+	if (old_tz) memcpy(old_tz, s, i+1);
+
+	/* Non-suid can use an absolute tzfile pathname or a relative
+	 * pathame beginning with "."; in secure mode, only the
+	 * standard path will be searched. */
+	if (*s == ':' || ((p=strchr(s, '/')) && !memchr(s, ',', p-s))) {
+		if (*s == ':') s++;
+		if (*s == '/' || *s == '.') {
+			if (!libc.secure || !strcmp(s, "/etc/localtime"))
+				map = __map_file(s, &map_size);
+		} else {
+			size_t l = strlen(s);
+			if (l <= NAME_MAX && !strchr(s, '.')) {
+				memcpy(pathname, s, l+1);
+				pathname[l] = 0;
+				for (try=search; !map && *try; try+=l+1) {
+					l = strlen(try);
+					memcpy(pathname-l, try, l);
+					map = __map_file(pathname-l, &map_size);
+				}
+			}
+		}
+		if (!map) s = __gmt;
+	}
+	if (map && (map_size < 44 || memcmp(map, "TZif", 4))) {
+		__munmap((void *)map, map_size);
+		map = 0;
+		s = __gmt;
+	}
+
+	zi = map;
+	if (map) {
+		int scale = 2;
+		if (sizeof(time_t) > 4 && map[4]=='2') {
+			size_t skip = zi_dotprod(zi+20, VEC(1,1,8,5,6,1), 6);
+			trans = zi+skip+44+44;
+			scale++;
+		} else {
+			trans = zi+44;
+		}
+		index = trans + (zi_read32(trans-12) << scale);
+		types = index + zi_read32(trans-12);
+		abbrevs = types + 6*zi_read32(trans-8);
+		abbrevs_end = abbrevs + zi_read32(trans-4);
+		if (zi[map_size-1] == '\n') {
+			for (s = (const char *)zi+map_size-2; *s!='\n'; s--);
+			s++;
+		} else {
+			const unsigned char *p;
+			__tzname[0] = __tzname[1] = 0;
+			__daylight = __timezone = dst_off = 0;
+			for (i=0; i<5; i++) r0[i] = r1[i] = 0;
+			for (p=types; p<abbrevs; p+=6) {
+				if (!p[4] && !__tzname[0]) {
+					__tzname[0] = (char *)abbrevs + p[5];
+					__timezone = -zi_read32(p);
+				}
+				if (p[4] && !__tzname[1]) {
+					__tzname[1] = (char *)abbrevs + p[5];
+					dst_off = -zi_read32(p);
+					__daylight = 1;
+				}
+			}
+			if (!__tzname[0]) __tzname[0] = __tzname[1];
+			if (!__tzname[0]) __tzname[0] = (char *)__gmt;
+			if (!__daylight) {
+				__tzname[1] = __tzname[0];
+				dst_off = __timezone;
+			}
+			return;
+		}
+	}
+
+	if (!s) s = __gmt;
+	getname(std_name, &s);
+	__tzname[0] = std_name;
+	__timezone = getoff(&s);
+	getname(dst_name, &s);
+	__tzname[1] = dst_name;
+	if (dst_name[0]) {
+		__daylight = 1;
+		if (*s == '+' || *s=='-' || *s-'0'<10U)
+			dst_off = getoff(&s);
+		else
+			dst_off = __timezone - 3600;
+	} else {
+		__daylight = 0;
+		dst_off = 0;
+	}
+
+	if (*s == ',') s++, getrule(&s, r0);
+	if (*s == ',') s++, getrule(&s, r1);
+}
+
+/* Search zoneinfo rules to find the one that applies to the given time,
+ * and determine alternate opposite-DST-status rule that may be needed. */
+
+static size_t scan_trans(long long t, int local, size_t *alt)
+{
+	int scale = 3 - (trans == zi+44);
+	uint64_t x;
+	int off = 0;
+
+	size_t a = 0, n = (index-trans)>>scale, m;
+
+	if (!n) {
+		if (alt) *alt = 0;
+		return 0;
+	}
+
+	/* Binary search for 'most-recent rule before t'. */
+	while (n > 1) {
+		m = a + n/2;
+		x = zi_read32(trans + (m<<scale));
+		if (scale == 3) x = x<<32 | zi_read32(trans + (m<<scale) + 4);
+		else x = (int32_t)x;
+		if (local) off = (int32_t)zi_read32(types + 6 * index[m-1]);
+		if (t - off < (int64_t)x) {
+			n /= 2;
+		} else {
+			a = m;
+			n -= n/2;
+		}
+	}
+
+	/* First and last entry are special. First means to use lowest-index
+	 * non-DST type. Last means to apply POSIX-style rule if available. */
+	n = (index-trans)>>scale;
+	if (a == n-1) return -1;
+	if (a == 0) {
+		x = zi_read32(trans + (a<<scale));
+		if (scale == 3) x = x<<32 | zi_read32(trans + (a<<scale) + 4);
+		else x = (int32_t)x;
+		if (local) off = (int32_t)zi_read32(types + 6 * index[a-1]);
+		if (t - off < (int64_t)x) {
+			for (a=0; a<(abbrevs-types)/6; a++) {
+				if (types[6*a+4] != types[4]) break;
+			}
+			if (a == (abbrevs-types)/6) a = 0;
+			if (types[6*a+4]) {
+				*alt = a;
+				return 0;
+			} else {
+				*alt = 0;
+				return a;
+			}
+		}
+	}
+
+	/* Try to find a neighboring opposite-DST-status rule. */
+	if (alt) {
+		if (a && types[6*index[a-1]+4] != types[6*index[a]+4])
+			*alt = index[a-1];
+		else if (a+1<n && types[6*index[a+1]+4] != types[6*index[a]+4])
+			*alt = index[a+1];
+		else
+			*alt = index[a];
+	}
+
+	return index[a];
+}
+
+static int days_in_month(int m, int is_leap)
+{
+	if (m==2) return 28+is_leap;
+	else return 30+((0xad5>>(m-1))&1);
+}
+
+/* Convert a POSIX DST rule plus year to seconds since epoch. */
+
+static long long rule_to_secs(const int *rule, int year)
+{
+	int is_leap;
+	long long t = __year_to_secs(year, &is_leap);
+	int x, m, n, d;
+	if (rule[0]!='M') {
+		x = rule[1];
+		if (rule[0]=='J' && (x < 60 || !is_leap)) x--;
+		t += 86400 * x;
+	} else {
+		m = rule[1];
+		n = rule[2];
+		d = rule[3];
+		t += __month_to_secs(m-1, is_leap);
+		int wday = (int)((t + 4*86400) % (7*86400)) / 86400;
+		int days = d - wday;
+		if (days < 0) days += 7;
+		if (n == 5 && days+28 >= days_in_month(m, is_leap)) n = 4;
+		t += 86400 * (days + 7*(n-1));
+	}
+	t += rule[4];
+	return t;
+}
+
+/* Determine the time zone in effect for a given time in seconds since the
+ * epoch. It can be given in local or universal time. The results will
+ * indicate whether DST is in effect at the queried time, and will give both
+ * the GMT offset for the active zone/DST rule and the opposite DST. This
+ * enables a caller to efficiently adjust for the case where an explicit
+ * DST specification mismatches what would be in effect at the time. */
+
+void __secs_to_zone(long long t, int local, int *isdst, long *offset, long *oppoff, const char **zonename)
+{
+	LOCK(lock);
+
+	do_tzset();
+
+	if (zi) {
+		size_t alt, i = scan_trans(t, local, &alt);
+		if (i != -1) {
+			*isdst = types[6*i+4];
+			*offset = (int32_t)zi_read32(types+6*i);
+			*zonename = (const char *)abbrevs + types[6*i+5];
+			if (oppoff) *oppoff = (int32_t)zi_read32(types+6*alt);
+			UNLOCK(lock);
+			return;
+		}
+	}
+
+	if (!__daylight) goto std;
+
+	/* FIXME: may be broken if DST changes right at year boundary?
+	 * Also, this could be more efficient.*/
+	long long y = t / 31556952 + 70;
+	while (__year_to_secs(y, 0) > t) y--;
+	while (__year_to_secs(y+1, 0) < t) y++;
+
+	long long t0 = rule_to_secs(r0, y);
+	long long t1 = rule_to_secs(r1, y);
+
+	if (!local) {
+		t0 += __timezone;
+		t1 += dst_off;
+	}
+	if (t0 < t1) {
+		if (t >= t0 && t < t1) goto dst;
+		goto std;
+	} else {
+		if (t >= t1 && t < t0) goto std;
+		goto dst;
+	}
+std:
+	*isdst = 0;
+	*offset = -__timezone;
+	if (oppoff) *oppoff = -dst_off;
+	*zonename = __tzname[0];
+	UNLOCK(lock);
+	return;
+dst:
+	*isdst = 1;
+	*offset = -dst_off;
+	if (oppoff) *oppoff = -__timezone;
+	*zonename = __tzname[1];
+	UNLOCK(lock);
+}
+
+void __tzset()
+{
+	LOCK(lock);
+	do_tzset();
+	UNLOCK(lock);
+}
+
+weak_alias(__tzset, tzset);
+
+const char *__tm_to_tzname(const struct tm *tm)
+{
+	const void *p = tm->__tm_zone;
+	LOCK(lock);
+	do_tzset();
+	if (p != __gmt && p != __tzname[0] && p != __tzname[1] &&
+	    (!zi || (uintptr_t)p-(uintptr_t)abbrevs >= abbrevs_end - abbrevs))
+		p = "";
+	UNLOCK(lock);
+	return p;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__year_to_secs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__year_to_secs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/__year_to_secs.c	(revision 398)
@@ -0,0 +1,47 @@
+long long __year_to_secs(long long year, int *is_leap)
+{
+	if (year-2ULL <= 136) {
+		int y = year;
+		int leaps = (y-68)>>2;
+		if (!((y-68)&3)) {
+			leaps--;
+			if (is_leap) *is_leap = 1;
+		} else if (is_leap) *is_leap = 0;
+		return 31536000*(y-70) + 86400*leaps;
+	}
+
+	int cycles, centuries, leaps, rem;
+
+	if (!is_leap) is_leap = &(int){0};
+	cycles = (year-100) / 400;
+	rem = (year-100) % 400;
+	if (rem < 0) {
+		cycles--;
+		rem += 400;
+	}
+	if (!rem) {
+		*is_leap = 1;
+		centuries = 0;
+		leaps = 0;
+	} else {
+		if (rem >= 200) {
+			if (rem >= 300) centuries = 3, rem -= 300;
+			else centuries = 2, rem -= 200;
+		} else {
+			if (rem >= 100) centuries = 1, rem -= 100;
+			else centuries = 0;
+		}
+		if (!rem) {
+			*is_leap = 0;
+			leaps = 0;
+		} else {
+			leaps = rem / 4U;
+			rem %= 4U;
+			*is_leap = !rem;
+		}
+	}
+
+	leaps += 97*cycles + 24*centuries - *is_leap;
+
+	return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/asctime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/asctime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/asctime.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <time.h>
+
+char *__asctime(const struct tm *, char *);
+
+char *asctime(const struct tm *tm)
+{
+	static char buf[26];
+	return __asctime(tm, buf);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/asctime_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/asctime_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/asctime_r.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <time.h>
+
+char *__asctime(const struct tm *restrict, char *restrict);
+
+char *asctime_r(const struct tm *restrict tm, char *restrict buf)
+{
+	return __asctime(tm, buf);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock.c	(revision 398)
@@ -0,0 +1,18 @@
+#include <time.h>
+#include <limits.h>
+
+int __clock_gettime(clockid_t, struct timespec *);
+
+clock_t clock()
+{
+	struct timespec ts;
+
+	if (__clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts))
+		return -1;
+
+	if (ts.tv_sec > LONG_MAX/1000000
+	 || ts.tv_nsec/1000 > LONG_MAX-1000000*ts.tv_sec)
+		return -1;
+
+	return ts.tv_sec*1000000 + ts.tv_nsec/1000;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_getcpuclockid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_getcpuclockid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_getcpuclockid.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+#include "syscall.h"
+
+int clock_getcpuclockid(pid_t pid, clockid_t *clk)
+{
+	struct timespec ts;
+	clockid_t id = (-pid-1)*8U + 2;
+	int ret = __syscall(SYS_clock_getres, id, &ts);
+	if (ret) return -ret;
+	*clk = id;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_getres.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_getres.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_getres.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <time.h>
+#include "syscall.h"
+
+int clock_getres(clockid_t clk, struct timespec *ts)
+{
+	return syscall(SYS_clock_getres, clk, ts);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_gettime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_gettime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_gettime.c	(revision 398)
@@ -0,0 +1,58 @@
+#include <time.h>
+#include <errno.h>
+#include <stdint.h>
+#include "syscall.h"
+#include "libc.h"
+#include "atomic.h"
+
+#ifdef VDSO_CGT_SYM
+
+void *__vdsosym(const char *, const char *);
+
+static void *volatile vdso_func;
+
+static int cgt_init(clockid_t clk, struct timespec *ts)
+{
+	void *p = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM);
+	int (*f)(clockid_t, struct timespec *) =
+		(int (*)(clockid_t, struct timespec *))p;
+	a_cas_p(&vdso_func, (void *)cgt_init, p);
+	return f ? f(clk, ts) : -ENOSYS;
+}
+
+static void *volatile vdso_func = (void *)cgt_init;
+
+#endif
+
+int __clock_gettime(clockid_t clk, struct timespec *ts)
+{
+	int r;
+
+#ifdef VDSO_CGT_SYM
+	int (*f)(clockid_t, struct timespec *) =
+		(int (*)(clockid_t, struct timespec *))vdso_func;
+	if (f) {
+		r = f(clk, ts);
+		if (!r) return r;
+		if (r == -EINVAL) return __syscall_ret(r);
+		/* Fall through on errors other than EINVAL. Some buggy
+		 * vdso implementations return ENOSYS for clocks they
+		 * can't handle, rather than making the syscall. This
+		 * also handles the case where cgt_init fails to find
+		 * a vdso function to use. */
+	}
+#endif
+
+	r = __syscall(SYS_clock_gettime, clk, ts);
+	if (r == -ENOSYS) {
+		if (clk == CLOCK_REALTIME) {
+			__syscall(SYS_gettimeofday, ts, 0);
+			ts->tv_nsec = (int)ts->tv_nsec * 1000;
+			return 0;
+		}
+		r = -EINVAL;
+	}
+	return __syscall_ret(r);
+}
+
+weak_alias(__clock_gettime, clock_gettime);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_nanosleep.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_nanosleep.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_nanosleep.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <time.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+
+int clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)
+{
+	int r = -__syscall_cp(SYS_clock_nanosleep, clk, flags, req, rem);
+	return clk == CLOCK_THREAD_CPUTIME_ID ? EINVAL : r;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_settime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_settime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/clock_settime.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <time.h>
+#include "syscall.h"
+
+int clock_settime(clockid_t clk, const struct timespec *ts)
+{
+	return syscall(SYS_clock_settime, clk, ts);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/ctime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/ctime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/ctime.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <time.h>
+
+char *ctime(const time_t *t)
+{
+	struct tm *tm = localtime(t);
+	if (!tm) return 0;
+	return asctime(tm);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/ctime_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/ctime_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/ctime_r.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <time.h>
+
+char *ctime_r(const time_t *t, char *buf)
+{
+	struct tm tm, *tm_p = localtime_r(t, &tm);
+	return tm_p ? asctime_r(tm_p, buf) : 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/difftime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/difftime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/difftime.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <time.h>
+
+double difftime(time_t t1, time_t t0)
+{
+	return t1-t0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/ftime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/ftime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/ftime.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <sys/timeb.h>
+#include <time.h>
+
+int ftime(struct timeb *tp)
+{
+	struct timespec ts;
+	clock_gettime(CLOCK_REALTIME, &ts);
+	tp->time = ts.tv_sec;
+	tp->millitm = ts.tv_nsec / 1000000;
+	tp->timezone = tp->dstflag = 0;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/getdate.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/getdate.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/getdate.c	(revision 398)
@@ -0,0 +1,46 @@
+#include <time.h>
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int getdate_err;
+
+struct tm *getdate(const char *s)
+{
+	static struct tm tmbuf;
+	struct tm *ret = 0;
+	char *datemsk = getenv("DATEMSK");
+	FILE *f = 0;
+	char fmt[100], *p;
+	int cs;
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DEFERRED, &cs);
+
+	if (!datemsk) {
+		getdate_err = 1;
+		goto out;
+	}
+
+	f = fopen(datemsk, "rbe");
+	if (!f) {
+		if (errno == ENOMEM) getdate_err = 6;
+		else getdate_err = 2;
+		goto out;
+	}
+
+	while (fgets(fmt, sizeof fmt, f)) {
+		p = strptime(s, fmt, &tmbuf);
+		if (p && !*p) {
+			ret = &tmbuf;
+			goto out;
+		}
+	}
+
+	if (ferror(f)) getdate_err = 5;
+	else getdate_err = 7;
+out:
+	if (f) fclose(f);
+	pthread_setcancelstate(cs, 0);
+	return ret;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/gettimeofday.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/gettimeofday.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/gettimeofday.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <time.h>
+#include <sys/time.h>
+#include "syscall.h"
+
+int gettimeofday(struct timeval *restrict tv, void *restrict tz)
+{
+	struct timespec ts;
+	if (!tv) return 0;
+	clock_gettime(CLOCK_REALTIME, &ts);
+	tv->tv_sec = ts.tv_sec;
+	tv->tv_usec = (int)ts.tv_nsec / 1000;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/gmtime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/gmtime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/gmtime.c	(revision 398)
@@ -0,0 +1,10 @@
+#include "time_impl.h"
+#include <errno.h>
+
+struct tm *__gmtime_r(const time_t *restrict, struct tm *restrict);
+
+struct tm *gmtime(const time_t *t)
+{
+	static struct tm tm;
+	return __gmtime_r(t, &tm);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/gmtime_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/gmtime_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/gmtime_r.c	(revision 398)
@@ -0,0 +1,19 @@
+#include "time_impl.h"
+#include <errno.h>
+#include "libc.h"
+
+extern const char __gmt[];
+
+struct tm *__gmtime_r(const time_t *restrict t, struct tm *restrict tm)
+{
+	if (__secs_to_tm(*t, tm) < 0) {
+		errno = EOVERFLOW;
+		return 0;
+	}
+	tm->tm_isdst = 0;
+	tm->__tm_gmtoff = 0;
+	tm->__tm_zone = __gmt;
+	return tm;
+}
+
+weak_alias(__gmtime_r, gmtime_r);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/localtime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/localtime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/localtime.c	(revision 398)
@@ -0,0 +1,9 @@
+#include "time_impl.h"
+
+struct tm *__localtime_r(const time_t *restrict, struct tm *restrict);
+
+struct tm *localtime(const time_t *t)
+{
+	static struct tm tm;
+	return __localtime_r(t, &tm);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/localtime_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/localtime_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/localtime_r.c	(revision 398)
@@ -0,0 +1,21 @@
+#include "time_impl.h"
+#include <errno.h>
+#include "libc.h"
+
+struct tm *__localtime_r(const time_t *restrict t, struct tm *restrict tm)
+{
+	/* Reject time_t values whose year would overflow int because
+	 * __secs_to_zone cannot safely handle them. */
+	if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) {
+		errno = EOVERFLOW;
+		return 0;
+	}
+	__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);
+	if (__secs_to_tm((long long)*t + tm->__tm_gmtoff, tm) < 0) {
+		errno = EOVERFLOW;
+		return 0;
+	}
+	return tm;
+}
+
+weak_alias(__localtime_r, localtime_r);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/mktime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/mktime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/mktime.c	(revision 398)
@@ -0,0 +1,28 @@
+#include "time_impl.h"
+#include <errno.h>
+
+time_t mktime(struct tm *tm)
+{
+	struct tm new;
+	long opp;
+	long long t = __tm_to_secs(tm);
+
+	__secs_to_zone(t, 1, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
+
+	if (tm->tm_isdst>=0 && new.tm_isdst!=tm->tm_isdst)
+		t -= opp - new.__tm_gmtoff;
+
+	t -= new.__tm_gmtoff;
+	if ((time_t)t != t) goto error;
+
+	__secs_to_zone(t, 0, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
+
+	if (__secs_to_tm(t + new.__tm_gmtoff, &new) < 0) goto error;
+
+	*tm = new;
+	return t;
+
+error:
+	errno = EOVERFLOW;
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/nanosleep.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/nanosleep.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/nanosleep.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <time.h>
+#include "syscall.h"
+#include "libc.h"
+
+int nanosleep(const struct timespec *req, struct timespec *rem)
+{
+	return syscall_cp(SYS_nanosleep, req, rem);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/strftime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/strftime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/strftime.c	(revision 398)
@@ -0,0 +1,275 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <langinfo.h>
+#include <locale.h>
+#include <time.h>
+#include <limits.h>
+#include "locale_impl.h"
+#include "libc.h"
+#include "time_impl.h"
+
+const char *__nl_langinfo_l(nl_item, locale_t);
+
+static int is_leap(int y)
+{
+	/* Avoid overflow */
+	if (y>INT_MAX-1900) y -= 2000;
+	y += 1900;
+	return !(y%4) && ((y%100) || !(y%400));
+}
+
+static int week_num(const struct tm *tm)
+{
+	int val = (tm->tm_yday + 7U - (tm->tm_wday+6U)%7) / 7;
+	/* If 1 Jan is just 1-3 days past Monday,
+	 * the previous week is also in this year. */
+	if ((tm->tm_wday + 371U - tm->tm_yday - 2) % 7 <= 2)
+		val++;
+	if (!val) {
+		val = 52;
+		/* If 31 December of prev year a Thursday,
+		 * or Friday of a leap year, then the
+		 * prev year has 53 weeks. */
+		int dec31 = (tm->tm_wday + 7U - tm->tm_yday - 1) % 7;
+		if (dec31 == 4 || (dec31 == 5 && is_leap(tm->tm_year%400-1)))
+			val++;
+	} else if (val == 53) {
+		/* If 1 January is not a Thursday, and not
+		 * a Wednesday of a leap year, then this
+		 * year has only 52 weeks. */
+		int jan1 = (tm->tm_wday + 371U - tm->tm_yday) % 7;
+		if (jan1 != 4 && (jan1 != 3 || !is_leap(tm->tm_year)))
+			val = 1;
+	}
+	return val;
+}
+
+const char *__tm_to_tzname(const struct tm *);
+size_t __strftime_l(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t);
+
+const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc)
+{
+	nl_item item;
+	long long val;
+	const char *fmt = "-";
+	int width = 2;
+
+	switch (f) {
+	case 'a':
+		if (tm->tm_wday > 6U) goto string;
+		item = ABDAY_1 + tm->tm_wday;
+		goto nl_strcat;
+	case 'A':
+		if (tm->tm_wday > 6U) goto string;
+		item = DAY_1 + tm->tm_wday;
+		goto nl_strcat;
+	case 'h':
+	case 'b':
+		if (tm->tm_mon > 11U) goto string;
+		item = ABMON_1 + tm->tm_mon;
+		goto nl_strcat;
+	case 'B':
+		if (tm->tm_mon > 11U) goto string;
+		item = MON_1 + tm->tm_mon;
+		goto nl_strcat;
+	case 'c':
+		item = D_T_FMT;
+		goto nl_strftime;
+	case 'C':
+		val = (1900LL+tm->tm_year) / 100;
+		goto number;
+	case 'd':
+		val = tm->tm_mday;
+		goto number;
+	case 'D':
+		fmt = "%m/%d/%y";
+		goto recu_strftime;
+	case 'e':
+		*l = snprintf(*s, sizeof *s, "%2d", tm->tm_mday);
+		return *s;
+	case 'F':
+		fmt = "%Y-%m-%d";
+		goto recu_strftime;
+	case 'g':
+	case 'G':
+		val = tm->tm_year + 1900LL;
+		if (tm->tm_yday < 3 && week_num(tm) != 1) val--;
+		else if (tm->tm_yday > 360 && week_num(tm) == 1) val++;
+		if (f=='g') val %= 100;
+		else width = 4;
+		goto number;
+	case 'H':
+		val = tm->tm_hour;
+		goto number;
+	case 'I':
+		val = tm->tm_hour;
+		if (!val) val = 12;
+		else if (val > 12) val -= 12;
+		goto number;
+	case 'j':
+		val = tm->tm_yday+1;
+		width = 3;
+		goto number;
+	case 'm':
+		val = tm->tm_mon+1;
+		goto number;
+	case 'M':
+		val = tm->tm_min;
+		goto number;
+	case 'n':
+		*l = 1;
+		return "\n";
+	case 'p':
+		item = tm->tm_hour >= 12 ? PM_STR : AM_STR;
+		goto nl_strcat;
+	case 'r':
+		item = T_FMT_AMPM;
+		goto nl_strftime;
+	case 'R':
+		fmt = "%H:%M";
+		goto recu_strftime;
+	case 's':
+		val = __tm_to_secs(tm) - tm->__tm_gmtoff;
+		width = 1;
+		goto number;
+	case 'S':
+		val = tm->tm_sec;
+		goto number;
+	case 't':
+		*l = 1;
+		return "\t";
+	case 'T':
+		fmt = "%H:%M:%S";
+		goto recu_strftime;
+	case 'u':
+		val = tm->tm_wday ? tm->tm_wday : 7;
+		width = 1;
+		goto number;
+	case 'U':
+		val = (tm->tm_yday + 7U - tm->tm_wday) / 7;
+		goto number;
+	case 'W':
+		val = (tm->tm_yday + 7U - (tm->tm_wday+6U)%7) / 7;
+		goto number;
+	case 'V':
+		val = week_num(tm);
+		goto number;
+	case 'w':
+		val = tm->tm_wday;
+		width = 1;
+		goto number;
+	case 'x':
+		item = D_FMT;
+		goto nl_strftime;
+	case 'X':
+		item = T_FMT;
+		goto nl_strftime;
+	case 'y':
+		val = (tm->tm_year + 1900LL) % 100;
+		if (val < 0) val = -val;
+		goto number;
+	case 'Y':
+		val = tm->tm_year + 1900LL;
+		if (val >= 10000) {
+			*l = snprintf(*s, sizeof *s, "+%lld", val);
+			return *s;
+		}
+		width = 4;
+		goto number;
+	case 'z':
+		if (tm->tm_isdst < 0) {
+			*l = 0;
+			return "";
+		}
+		*l = snprintf(*s, sizeof *s, "%+.2d%.2d",
+			(tm->__tm_gmtoff)/3600,
+			abs(tm->__tm_gmtoff%3600)/60);
+		return *s;
+	case 'Z':
+		if (tm->tm_isdst < 0) {
+			*l = 0;
+			return "";
+		}
+		fmt = __tm_to_tzname(tm);
+		goto string;
+	case '%':
+		*l = 1;
+		return "%";
+	default:
+		return 0;
+	}
+number:
+	*l = snprintf(*s, sizeof *s, "%0*lld", width, val);
+	return *s;
+nl_strcat:
+	fmt = __nl_langinfo_l(item, loc);
+string:
+	*l = strlen(fmt);
+	return fmt;
+nl_strftime:
+	fmt = __nl_langinfo_l(item, loc);
+recu_strftime:
+	*l = __strftime_l(*s, sizeof *s, fmt, tm, loc);
+	if (!*l) return 0;
+	return *s;
+}
+
+size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm, locale_t loc)
+{
+	size_t l, k;
+	char buf[100];
+	char *p;
+	const char *t;
+	int plus;
+	unsigned long width;
+	for (l=0; l<n; f++) {
+		if (!*f) {
+			s[l] = 0;
+			return l;
+		}
+		if (*f != '%') {
+			s[l++] = *f;
+			continue;
+		}
+		f++;
+		if ((plus = (*f == '+'))) f++;
+		width = strtoul(f, &p, 10);
+		if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
+			if (!width && p!=f) width = 1;
+		} else {
+			width = 0;
+		}
+		f = p;
+		if (*f == 'E' || *f == 'O') f++;
+		t = __strftime_fmt_1(&buf, &k, *f, tm, loc);
+		if (!t) break;
+		if (width) {
+			for (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--);
+			width--;
+			if (plus && tm->tm_year >= 10000-1900)
+				s[l++] = '+';
+			else if (tm->tm_year < -1900)
+				s[l++] = '-';
+			else
+				width++;
+			for (; width > k && l < n; width--)
+				s[l++] = '0';
+		}
+		if (k > n-l) k = n-l;
+		memcpy(s+l, t, k);
+		l += k;
+	}
+	if (n) {
+		if (l==n) l=n-1;
+		s[l] = 0;
+	}
+	return 0;
+}
+
+size_t strftime(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm)
+{
+	return __strftime_l(s, n, f, tm, CURRENT_LOCALE);
+}
+
+weak_alias(__strftime_l, strftime_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/strptime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/strptime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/strptime.c	(revision 398)
@@ -0,0 +1,206 @@
+#include <stdlib.h>
+#include <langinfo.h>
+#include <time.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <string.h>
+#include <strings.h>
+
+char *strptime(const char *restrict s, const char *restrict f, struct tm *restrict tm)
+{
+	int i, w, neg, adj, min, range, *dest, dummy;
+	const char *ex;
+	size_t len;
+	int want_century = 0, century = 0, relyear = 0;
+	while (*f) {
+		if (*f != '%') {
+			if (isspace(*f)) for (; *s && isspace(*s); s++);
+			else if (*s != *f) return 0;
+			else s++;
+			f++;
+			continue;
+		}
+		f++;
+		if (*f == '+') f++;
+		if (isdigit(*f)) {
+			char *new_f;
+			w=strtoul(f, &new_f, 10);
+			f = new_f;
+		} else {
+			w=-1;
+		}
+		adj=0;
+		switch (*f++) {
+		case 'a': case 'A':
+			dest = &tm->tm_wday;
+			min = ABDAY_1;
+			range = 7;
+			goto symbolic_range;
+		case 'b': case 'B': case 'h':
+			dest = &tm->tm_mon;
+			min = ABMON_1;
+			range = 12;
+			goto symbolic_range;
+		case 'c':
+			s = strptime(s, nl_langinfo(D_T_FMT), tm);
+			if (!s) return 0;
+			break;
+		case 'C':
+			dest = &century;
+			if (w<0) w=2;
+			want_century |= 2;
+			goto numeric_digits;
+		case 'd': case 'e':
+			dest = &tm->tm_mday;
+			min = 1;
+			range = 31;
+			goto numeric_range;
+		case 'D':
+			s = strptime(s, "%m/%d/%y", tm);
+			if (!s) return 0;
+			break;
+		case 'H':
+			dest = &tm->tm_hour;
+			min = 0;
+			range = 24;
+			goto numeric_range;
+		case 'I':
+			dest = &tm->tm_hour;
+			min = 1;
+			range = 12;
+			goto numeric_range;
+		case 'j':
+			dest = &tm->tm_yday;
+			min = 1;
+			range = 366;
+			adj = 1;
+			goto numeric_range;
+		case 'm':
+			dest = &tm->tm_mon;
+			min = 1;
+			range = 12;
+			adj = 1;
+			goto numeric_range;
+		case 'M':
+			dest = &tm->tm_min;
+			min = 0;
+			range = 60;
+			goto numeric_range;
+		case 'n': case 't':
+			for (; *s && isspace(*s); s++);
+			break;
+		case 'p':
+			ex = nl_langinfo(AM_STR);
+			len = strlen(ex);
+			if (!strncasecmp(s, ex, len)) {
+				tm->tm_hour %= 12;
+				s += len;
+				break;
+			}
+			ex = nl_langinfo(PM_STR);
+			len = strlen(ex);
+			if (!strncasecmp(s, ex, len)) {
+				tm->tm_hour %= 12;
+				tm->tm_hour += 12;
+				s += len;
+				break;
+			}
+			return 0;
+		case 'r':
+			s = strptime(s, nl_langinfo(T_FMT_AMPM), tm);
+			if (!s) return 0;
+			break;
+		case 'R':
+			s = strptime(s, "%H:%M", tm);
+			if (!s) return 0;
+			break;
+		case 'S':
+			dest = &tm->tm_sec;
+			min = 0;
+			range = 61;
+			goto numeric_range;
+		case 'T':
+			s = strptime(s, "%H:%M:%S", tm);
+			if (!s) return 0;
+			break;
+		case 'U':
+		case 'W':
+			/* Throw away result, for now. (FIXME?) */
+			dest = &dummy;
+			min = 0;
+			range = 54;
+			goto numeric_range;
+		case 'w':
+			dest = &tm->tm_wday;
+			min = 0;
+			range = 7;
+			goto numeric_range;
+		case 'x':
+			s = strptime(s, nl_langinfo(D_FMT), tm);
+			if (!s) return 0;
+			break;
+		case 'X':
+			s = strptime(s, nl_langinfo(T_FMT), tm);
+			if (!s) return 0;
+			break;
+		case 'y':
+			dest = &relyear;
+			w = 2;
+			want_century |= 1;
+			goto numeric_digits;
+		case 'Y':
+			dest = &tm->tm_year;
+			if (w<0) w=4;
+			adj = 1900;
+			want_century = 0;
+			goto numeric_digits;
+		case '%':
+			if (*s++ != '%') return 0;
+			break;
+		default:
+			return 0;
+		numeric_range:
+			if (!isdigit(*s)) return 0;
+			*dest = 0;
+			for (i=1; i<=min+range && isdigit(*s); i*=10)
+				*dest = *dest * 10 + *s++ - '0';
+			if (*dest - min >= (unsigned)range) return 0;
+			*dest -= adj;
+			switch((char *)dest - (char *)tm) {
+			case offsetof(struct tm, tm_yday):
+				;
+			}
+			goto update;
+		numeric_digits:
+			neg = 0;
+			if (*s == '+') s++;
+			else if (*s == '-') neg=1, s++;
+			if (!isdigit(*s)) return 0;
+			for (*dest=i=0; i<w && isdigit(*s); i++)
+				*dest = *dest * 10 + *s++ - '0';
+			if (neg) *dest = -*dest;
+			*dest -= adj;
+			goto update;
+		symbolic_range:
+			for (i=2*range-1; i>=0; i--) {
+				ex = nl_langinfo(min+i);
+				len = strlen(ex);
+				if (strncasecmp(s, ex, len)) continue;
+				s += len;
+				*dest = i % range;
+				break;
+			}
+			if (i<0) return 0;
+			goto update;
+		update:
+			//FIXME
+			;
+		}
+	}
+	if (want_century) {
+		tm->tm_year = relyear;
+		if (want_century & 2) tm->tm_year += century * 100 - 1900;
+		else if (tm->tm_year <= 68) tm->tm_year += 100;
+	}
+	return (char *)s;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/time.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/time.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/time.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <time.h>
+#include "syscall.h"
+
+int __clock_gettime(clockid_t, struct timespec *);
+
+time_t time(time_t *t)
+{
+	struct timespec ts;
+	__clock_gettime(CLOCK_REALTIME, &ts);
+	if (t) *t = ts.tv_sec;
+	return ts.tv_sec;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/time_impl.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/time_impl.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/time_impl.h	(revision 398)
@@ -0,0 +1,9 @@
+#include <time.h>
+
+int __days_in_month(int, int);
+int __month_to_secs(int, int);
+long long __year_to_secs(long long, int *);
+long long __tm_to_secs(const struct tm *);
+int __secs_to_tm(long long, struct tm *);
+void __secs_to_zone(long long, int, int *, long *, long *, const char **);
+const unsigned char *__map_file(const char *, size_t *);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timegm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timegm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timegm.c	(revision 398)
@@ -0,0 +1,20 @@
+#define _GNU_SOURCE
+#include "time_impl.h"
+#include <errno.h>
+
+extern const char __gmt[];
+
+time_t timegm(struct tm *tm)
+{
+	struct tm new;
+	long long t = __tm_to_secs(tm);
+	if (__secs_to_tm(t, &new) < 0) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+	*tm = new;
+	tm->tm_isdst = 0;
+	tm->__tm_gmtoff = 0;
+	tm->__tm_zone = __gmt;
+	return t;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_create.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_create.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_create.c	(revision 398)
@@ -0,0 +1,141 @@
+#include <time.h>
+#include <setjmp.h>
+#include "pthread_impl.h"
+
+struct ksigevent {
+	union sigval sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	int sigev_tid;
+};
+
+struct start_args {
+	pthread_barrier_t b;
+	struct sigevent *sev;
+};
+
+static void dummy_1(pthread_t self)
+{
+}
+weak_alias(dummy_1, __pthread_tsd_run_dtors);
+
+void __reset_tls();
+
+static void cleanup_fromsig(void *p)
+{
+	pthread_t self = __pthread_self();
+	__pthread_tsd_run_dtors(self);
+	self->cancel = 0;
+	self->cancelbuf = 0;
+	self->canceldisable = 0;
+	self->cancelasync = 0;
+	self->unblock_cancel = 0;
+	__reset_tls();
+	longjmp(p, 1);
+}
+
+static void timer_handler(int sig, siginfo_t *si, void *ctx)
+{
+	pthread_t self = __pthread_self();
+	jmp_buf jb;
+	void (*notify)(union sigval) = (void (*)(union sigval))self->start;
+	union sigval val = { .sival_ptr = self->start_arg };
+
+	if (!setjmp(jb) && si->si_code == SI_TIMER) {
+		pthread_cleanup_push(cleanup_fromsig, jb);
+		notify(val);
+		pthread_cleanup_pop(1);
+	}
+}
+
+static void install_handler()
+{
+	struct sigaction sa = {
+		.sa_sigaction = timer_handler,
+		.sa_flags = SA_SIGINFO | SA_RESTART
+	};
+	__libc_sigaction(SIGTIMER, &sa, 0);
+}
+
+static void *start(void *arg)
+{
+	pthread_t self = __pthread_self();
+	struct start_args *args = arg;
+	int id;
+
+	/* Reuse no-longer-needed thread structure fields to avoid
+	 * needing the timer address in the signal handler. */
+	self->start = (void *(*)(void *))args->sev->sigev_notify_function;
+	self->start_arg = args->sev->sigev_value.sival_ptr;
+
+	pthread_barrier_wait(&args->b);
+	if ((id = self->timer_id) >= 0) {
+		__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
+			SIGTIMER_SET, 0, _NSIG/8);
+		__wait(&self->timer_id, 0, id, 1);
+		__syscall(SYS_timer_delete, id);
+	}
+	return 0;
+}
+
+int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict res)
+{
+	static pthread_once_t once = PTHREAD_ONCE_INIT;
+	pthread_t td;
+	pthread_attr_t attr;
+	int r;
+	struct start_args args;
+	struct ksigevent ksev, *ksevp=0;
+	int timerid;
+	sigset_t set;
+
+	switch (evp ? evp->sigev_notify : SIGEV_SIGNAL) {
+	case SIGEV_NONE:
+	case SIGEV_SIGNAL:
+		if (evp) {
+			ksev.sigev_value = evp->sigev_value;
+			ksev.sigev_signo = evp->sigev_signo;
+			ksev.sigev_notify = evp->sigev_notify;
+			ksev.sigev_tid = 0;
+			ksevp = &ksev;
+		}
+		if (syscall(SYS_timer_create, clk, ksevp, &timerid) < 0)
+			return -1;
+		*res = (void *)(intptr_t)timerid;
+		break;
+	case SIGEV_THREAD:
+		pthread_once(&once, install_handler);
+		if (evp->sigev_notify_attributes)
+			attr = *evp->sigev_notify_attributes;
+		else
+			pthread_attr_init(&attr);
+		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+		pthread_barrier_init(&args.b, 0, 2);
+		args.sev = evp;
+
+		__block_app_sigs(&set);
+		r = pthread_create(&td, &attr, start, &args);
+		__restore_sigs(&set);
+		if (r) {
+			errno = r;
+			return -1;
+		}
+
+		ksev.sigev_value.sival_ptr = 0;
+		ksev.sigev_signo = SIGTIMER;
+		ksev.sigev_notify = 4; /* SIGEV_THREAD_ID */
+		ksev.sigev_tid = td->tid;
+		if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0)
+			timerid = -1;
+		td->timer_id = timerid;
+		pthread_barrier_wait(&args.b);
+		if (timerid < 0) return -1;
+		*res = (void *)(INTPTR_MIN | (uintptr_t)td>>1);
+		break;
+	default:
+		errno = EINVAL;
+		return -1;
+	}
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_delete.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_delete.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_delete.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <time.h>
+#include <limits.h>
+#include "pthread_impl.h"
+
+int timer_delete(timer_t t)
+{
+	if ((intptr_t)t < 0) {
+		pthread_t td = (void *)((uintptr_t)t << 1);
+		a_store(&td->timer_id, td->timer_id | INT_MIN);
+		__wake(&td->timer_id, 1, 1);
+		return 0;
+	}
+	return __syscall(SYS_timer_delete, t);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_getoverrun.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_getoverrun.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_getoverrun.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <time.h>
+#include <limits.h>
+#include "pthread_impl.h"
+
+int timer_getoverrun(timer_t t)
+{
+	if ((intptr_t)t < 0) {
+		pthread_t td = (void *)((uintptr_t)t << 1);
+		t = (void *)(uintptr_t)(td->timer_id & INT_MAX);
+	}
+	return syscall(SYS_timer_getoverrun, t);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_gettime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_gettime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_gettime.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <time.h>
+#include <limits.h>
+#include "pthread_impl.h"
+
+int timer_gettime(timer_t t, struct itimerspec *val)
+{
+	if ((intptr_t)t < 0) {
+		pthread_t td = (void *)((uintptr_t)t << 1);
+		t = (void *)(uintptr_t)(td->timer_id & INT_MAX);
+	}
+	return syscall(SYS_timer_gettime, t, val);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_settime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_settime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timer_settime.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <time.h>
+#include <limits.h>
+#include "pthread_impl.h"
+
+int timer_settime(timer_t t, int flags, const struct itimerspec *restrict val, struct itimerspec *restrict old)
+{
+	if ((intptr_t)t < 0) {
+		pthread_t td = (void *)((uintptr_t)t << 1);
+		t = (void *)(uintptr_t)(td->timer_id & INT_MAX);
+	}
+	return syscall(SYS_timer_settime, t, flags, val, old);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/times.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/times.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/times.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <sys/times.h>
+#include "syscall.h"
+
+clock_t times(struct tms *tms)
+{
+	return __syscall(SYS_times, tms);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timespec_get.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timespec_get.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/timespec_get.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <time.h>
+
+int __clock_gettime(clockid_t, struct timespec *);
+
+/* There is no other implemented value than TIME_UTC; all other values
+ * are considered erroneous. */
+int timespec_get(struct timespec * ts, int base)
+{
+	if (base != TIME_UTC) return 0;
+	int ret = __clock_gettime(CLOCK_REALTIME, ts);
+	return ret < 0 ? 0 : base;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/utime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/utime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/utime.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <utime.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <fcntl.h>
+
+int utime(const char *path, const struct utimbuf *times)
+{
+	return utimensat(AT_FDCWD, path, times ? ((struct timespec [2]){
+		{ .tv_sec = times->actime }, { .tv_sec = times->modtime }})
+		: 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/wcsftime.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/wcsftime.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/time/wcsftime.c	(revision 398)
@@ -0,0 +1,71 @@
+#include <wchar.h>
+#include <time.h>
+#include <locale.h>
+#include "locale_impl.h"
+#include "libc.h"
+
+const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc);
+
+size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, const struct tm *restrict tm, locale_t loc)
+{
+	size_t l, k;
+	char buf[100];
+	wchar_t wbuf[100];
+	wchar_t *p;
+	const char *t_mb;
+	const wchar_t *t;
+	int plus;
+	unsigned long width;
+	for (l=0; l<n; f++) {
+		if (!*f) {
+			s[l] = 0;
+			return l;
+		}
+		if (*f != '%') {
+			s[l++] = *f;
+			continue;
+		}
+		f++;
+		if ((plus = (*f == '+'))) f++;
+		width = wcstoul(f, &p, 10);
+		if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
+			if (!width && p!=f) width = 1;
+		} else {
+			width = 0;
+		}
+		f = p;
+		if (*f == 'E' || *f == 'O') f++;
+		t_mb = __strftime_fmt_1(&buf, &k, *f, tm, loc);
+		if (!t_mb) break;
+		k = mbstowcs(wbuf, t_mb, sizeof wbuf / sizeof *wbuf);
+		if (k == (size_t)-1) return 0;
+		t = wbuf;
+		if (width) {
+			for (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--);
+			width--;
+			if (plus && tm->tm_year >= 10000-1900)
+				s[l++] = '+';
+			else if (tm->tm_year < -1900)
+				s[l++] = '-';
+			else
+				width++;
+			for (; width > k && l < n; width--)
+				s[l++] = '0';
+		}
+		if (k >= n-l) k = n-l;
+		wmemcpy(s+l, t, k);
+		l += k;
+	}
+	if (n) {
+		if (l==n) l=n-1;
+		s[l] = 0;
+	}
+	return 0;
+}
+
+size_t wcsftime(wchar_t *restrict wcs, size_t n, const wchar_t *restrict f, const struct tm *restrict tm)
+{
+	return __wcsftime_l(wcs, n, f, tm, CURRENT_LOCALE);
+}
+
+weak_alias(__wcsftime_l, wcsftime_l);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/_exit.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/_exit.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/_exit.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include <stdlib.h>
+
+_Noreturn void _exit(int status)
+{
+	_Exit(status);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/access.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/access.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/access.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int access(const char *filename, int amode)
+{
+#ifdef SYS_access
+	return syscall(SYS_access, filename, amode);
+#else
+	return syscall(SYS_faccessat, AT_FDCWD, filename, amode, 0);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/acct.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/acct.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/acct.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int acct(const char *filename)
+{
+	return syscall(SYS_acct, filename);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/alarm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/alarm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/alarm.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include <sys/time.h>
+#include "syscall.h"
+
+unsigned alarm(unsigned seconds)
+{
+	struct itimerval it = { .it_value.tv_sec = seconds };
+	__syscall(SYS_setitimer, ITIMER_REAL, &it, &it);
+	return it.it_value.tv_sec + !!it.it_value.tv_usec;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/chdir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/chdir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/chdir.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int chdir(const char *path)
+{
+	return syscall(SYS_chdir, path);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/chown.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/chown.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/chown.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int chown(const char *path, uid_t uid, gid_t gid)
+{
+#ifdef SYS_chown
+	return syscall(SYS_chown, path, uid, gid);
+#else
+	return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, 0);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/close.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/close.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/close.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <unistd.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+
+static int dummy(int fd)
+{
+	return fd;
+}
+
+weak_alias(dummy, __aio_close);
+
+int close(int fd)
+{
+	fd = __aio_close(fd);
+	int r = __syscall_cp(SYS_close, fd);
+	if (r == -EINTR) r = 0;
+	return __syscall_ret(r);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ctermid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ctermid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ctermid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <string.h>
+
+char *ctermid(char *s)
+{
+	return s ? strcpy(s, "/dev/tty") : "/dev/tty";
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/dup.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/dup.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/dup.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int dup(int fd)
+{
+	return syscall(SYS_dup, fd);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/dup2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/dup2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/dup2.c	(revision 398)
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int dup2(int old, int new)
+{
+	int r;
+#ifdef SYS_dup2
+	while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+#else
+	if (old==new) {
+		r = __syscall(SYS_fcntl, old, F_GETFD);
+		if (r >= 0) return old;
+	} else {
+		while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY);
+	}
+#endif
+	return __syscall_ret(r);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/dup3.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/dup3.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/dup3.c	(revision 398)
@@ -0,0 +1,25 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+#include "libc.h"
+
+int __dup3(int old, int new, int flags)
+{
+	int r;
+#ifdef SYS_dup2
+	if (old==new) return __syscall_ret(-EINVAL);
+	if (flags & O_CLOEXEC) {
+		while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
+		if (r!=-ENOSYS) return __syscall_ret(r);
+	}
+	while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+	if (flags & O_CLOEXEC) __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC);
+#else
+	while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
+#endif
+	return __syscall_ret(r);
+}
+
+weak_alias(__dup3, dup3);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/faccessat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/faccessat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/faccessat.c	(revision 398)
@@ -0,0 +1,63 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+
+struct ctx {
+	int fd;
+	const char *filename;
+	int amode;
+};
+
+static const int errors[] = {
+	0, -EACCES, -ELOOP, -ENAMETOOLONG, -ENOENT, -ENOTDIR,
+	-EROFS, -EBADF, -EINVAL, -ETXTBSY,
+	-EFAULT, -EIO, -ENOMEM,
+	-EBUSY
+};
+
+static int checker(void *p)
+{
+	struct ctx *c = p;
+	int ret;
+	int i;
+	if (__syscall(SYS_setregid, __syscall(SYS_getegid), -1)
+	    || __syscall(SYS_setreuid, __syscall(SYS_geteuid), -1))
+		__syscall(SYS_exit, 1);
+	ret = __syscall(SYS_faccessat, c->fd, c->filename, c->amode, 0);
+	for (i=0; i < sizeof errors/sizeof *errors - 1 && ret!=errors[i]; i++);
+	return i;
+}
+
+int faccessat(int fd, const char *filename, int amode, int flag)
+{
+	if (!flag || (flag==AT_EACCESS && getuid()==geteuid() && getgid()==getegid()))
+		return syscall(SYS_faccessat, fd, filename, amode, flag);
+
+	if (flag != AT_EACCESS)
+		return __syscall_ret(-EINVAL);
+
+	char stack[1024];
+	sigset_t set;
+	pid_t pid;
+	int ret = -EBUSY;
+	struct ctx c = { .fd = fd, .filename = filename, .amode = amode };
+
+	__block_all_sigs(&set);
+	
+	pid = __clone(checker, stack+sizeof stack, 0, &c);
+	if (pid > 0) {
+		int status;
+		do {
+			__syscall(SYS_wait4, pid, &status, __WCLONE, 0);
+		} while (!WIFEXITED(status) && !WIFSIGNALED(status));
+		if (WIFEXITED(status))
+			ret = errors[WEXITSTATUS(status)];
+	}
+
+	__restore_sigs(&set);
+
+	return __syscall_ret(ret);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fchdir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fchdir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fchdir.c	(revision 398)
@@ -0,0 +1,17 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+void __procfdname(char *, unsigned);
+
+int fchdir(int fd)
+{
+	int ret = __syscall(SYS_fchdir, fd);
+	if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
+		return __syscall_ret(ret);
+
+	char buf[15+3*sizeof(int)];
+	__procfdname(buf, fd);
+	return syscall(SYS_chdir, buf);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fchown.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fchown.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fchown.c	(revision 398)
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+void __procfdname(char *, unsigned);
+
+int fchown(int fd, uid_t uid, gid_t gid)
+{
+	int ret = __syscall(SYS_fchown, fd, uid, gid);
+	if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
+		return __syscall_ret(ret);
+
+	char buf[15+3*sizeof(int)];
+	__procfdname(buf, fd);
+#ifdef SYS_chown
+	return syscall(SYS_chown, buf, uid, gid);
+#else
+	return syscall(SYS_fchownat, AT_FDCWD, buf, uid, gid, 0);
+#endif
+
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fchownat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fchownat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fchownat.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag)
+{
+	return syscall(SYS_fchownat, fd, path, uid, gid, flag);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fdatasync.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fdatasync.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fdatasync.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fdatasync(int fd)
+{
+	return syscall_cp(SYS_fdatasync, fd);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fsync.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fsync.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/fsync.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fsync(int fd)
+{
+	return syscall_cp(SYS_fsync, fd);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ftruncate.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ftruncate.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ftruncate.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int ftruncate(int fd, off_t length)
+{
+	return syscall(SYS_ftruncate, fd, __SYSCALL_LL_O(length));
+}
+
+LFS64(ftruncate);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getcwd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getcwd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getcwd.c	(revision 398)
@@ -0,0 +1,19 @@
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include "syscall.h"
+
+char *getcwd(char *buf, size_t size)
+{
+	char tmp[PATH_MAX];
+	if (!buf) {
+		buf = tmp;
+		size = PATH_MAX;
+	} else if (!size) {
+		errno = EINVAL;
+		return 0;
+	}
+	if (syscall(SYS_getcwd, buf, size) < 0) return 0;
+	return buf == tmp ? strdup(buf) : buf;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getegid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getegid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getegid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+gid_t getegid(void)
+{
+	return __syscall(SYS_getegid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/geteuid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/geteuid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/geteuid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+uid_t geteuid(void)
+{
+	return __syscall(SYS_geteuid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getgid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getgid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getgid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+gid_t getgid(void)
+{
+	return __syscall(SYS_getgid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getgroups.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getgroups.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getgroups.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int getgroups(int count, gid_t list[])
+{
+	return syscall(SYS_getgroups, count, list);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/gethostname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/gethostname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/gethostname.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <sys/utsname.h>
+
+int gethostname(char *name, size_t len)
+{
+	size_t i;
+	struct utsname uts;
+	if (uname(&uts)) return -1;
+	if (len > sizeof uts.nodename) len = sizeof uts.nodename;
+	for (i=0; i<len && (name[i] = uts.nodename[i]); i++);
+	if (i==len) name[i-1] = 0;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getlogin.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getlogin.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getlogin.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include <stdlib.h>
+
+char *getlogin(void)
+{
+	return getenv("LOGNAME");
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getlogin_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getlogin_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getlogin_r.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+int getlogin_r(char *name, size_t size)
+{
+	char *logname = getlogin();
+	if (!logname) return ENXIO; /* or...? */
+	if (strlen(logname) >= size) return ERANGE;
+	strcpy(name, logname);
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getpgid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getpgid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getpgid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpgid(pid_t pid)
+{
+	return syscall(SYS_getpgid, pid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getpgrp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getpgrp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getpgrp.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpgrp(void)
+{
+	return __syscall(SYS_getpgid, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getpid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getpid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getpid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpid(void)
+{
+	return __syscall(SYS_getpid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getppid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getppid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getppid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getppid(void)
+{
+	return __syscall(SYS_getppid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getsid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getsid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getsid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getsid(pid_t pid)
+{
+	return syscall(SYS_getsid, pid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getuid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getuid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/getuid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+uid_t getuid(void)
+{
+	return __syscall(SYS_getuid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/isatty.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/isatty.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/isatty.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include "syscall.h"
+
+int isatty(int fd)
+{
+	struct winsize wsz;
+	return !__syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/lchown.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/lchown.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/lchown.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int lchown(const char *path, uid_t uid, gid_t gid)
+{
+#ifdef SYS_lchown
+	return syscall(SYS_lchown, path, uid, gid);
+#else
+	return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/link.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/link.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/link.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int link(const char *existing, const char *new)
+{
+#ifdef SYS_link
+	return syscall(SYS_link, existing, new);
+#else
+	return syscall(SYS_linkat, AT_FDCWD, existing, AT_FDCWD, new, 0);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/linkat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/linkat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/linkat.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int linkat(int fd1, const char *existing, int fd2, const char *new, int flag)
+{
+	return syscall(SYS_linkat, fd1, existing, fd2, new, flag);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/lseek.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/lseek.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/lseek.c	(revision 398)
@@ -0,0 +1,15 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+off_t lseek(int fd, off_t offset, int whence)
+{
+#ifdef SYS__llseek
+	off_t result;
+	return syscall(SYS__llseek, fd, offset>>32, offset, &result, whence) ? -1 : result;
+#else
+	return syscall(SYS_lseek, fd, offset, whence);
+#endif
+}
+
+LFS64(lseek);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/nice.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/nice.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/nice.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <sys/resource.h>
+#include "syscall.h"
+
+int nice(int inc)
+{
+#ifdef SYS_nice
+	return syscall(SYS_nice, inc);
+#else
+	return setpriority(PRIO_PROCESS, 0, getpriority(PRIO_PROCESS, 0)+inc);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pause.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pause.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pause.c	(revision 398)
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <signal.h>
+#include "syscall.h"
+#include "libc.h"
+
+int pause(void)
+{
+#ifdef SYS_pause
+	return syscall_cp(SYS_pause);
+#else
+	return syscall_cp(SYS_ppoll, 0, 0, 0, 0);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pipe.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pipe.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pipe.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int pipe(int fd[2])
+{
+#ifdef SYS_pipe
+	return syscall(SYS_pipe, fd);
+#else
+	return syscall(SYS_pipe2, fd, 0);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pipe2.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pipe2.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pipe2.c	(revision 398)
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int pipe2(int fd[2], int flag)
+{
+	if (!flag) return pipe(fd);
+	int ret = __syscall(SYS_pipe2, fd, flag);
+	if (ret != -ENOSYS) return __syscall_ret(ret);
+	ret = pipe(fd);
+	if (ret) return ret;
+	if (flag & O_CLOEXEC) {
+		__syscall(SYS_fcntl, fd[0], F_SETFD, FD_CLOEXEC);
+		__syscall(SYS_fcntl, fd[1], F_SETFD, FD_CLOEXEC);
+	}
+	if (flag & O_NONBLOCK) {
+		__syscall(SYS_fcntl, fd[0], F_SETFL, O_NONBLOCK);
+		__syscall(SYS_fcntl, fd[1], F_SETFL, O_NONBLOCK);
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/posix_close.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/posix_close.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/posix_close.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+int posix_close(int fd, int flags)
+{
+	return close(fd);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pread.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pread.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pread.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
+{
+	return syscall_cp(SYS_pread, fd, buf, size, __SYSCALL_LL_PRW(ofs));
+}
+
+LFS64(pread);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/preadv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/preadv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/preadv.c	(revision 398)
@@ -0,0 +1,13 @@
+#define _BSD_SOURCE
+#include <sys/uio.h>
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t preadv(int fd, const struct iovec *iov, int count, off_t ofs)
+{
+	return syscall_cp(SYS_preadv, fd, iov, count,
+		(long)(ofs), (long)(ofs>>32));
+}
+
+LFS64(preadv);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pwrite.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pwrite.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pwrite.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs)
+{
+	return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs));
+}
+
+LFS64(pwrite);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pwritev.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pwritev.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/pwritev.c	(revision 398)
@@ -0,0 +1,13 @@
+#define _BSD_SOURCE
+#include <sys/uio.h>
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs)
+{
+	return syscall_cp(SYS_pwritev, fd, iov, count,
+		(long)(ofs), (long)(ofs>>32));
+}
+
+LFS64(pwritev);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/read.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/read.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/read.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t read(int fd, void *buf, size_t count)
+{
+	return syscall_cp(SYS_read, fd, buf, count);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/readlink.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/readlink.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/readlink.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
+{
+#ifdef SYS_readlink
+	return syscall(SYS_readlink, path, buf, bufsize);
+#else
+	return syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/readlinkat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/readlinkat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/readlinkat.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize)
+{
+	return syscall(SYS_readlinkat, fd, path, buf, bufsize);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/readv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/readv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/readv.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/uio.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t readv(int fd, const struct iovec *iov, int count)
+{
+	return syscall_cp(SYS_readv, fd, iov, count);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/renameat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/renameat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/renameat.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include "syscall.h"
+
+int renameat(int oldfd, const char *old, int newfd, const char *new)
+{
+	return syscall(SYS_renameat, oldfd, old, newfd, new);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/rmdir.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/rmdir.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/rmdir.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int rmdir(const char *path)
+{
+#ifdef SYS_rmdir
+	return syscall(SYS_rmdir, path);
+#else
+	return syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setegid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setegid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setegid.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "libc.h"
+#include "syscall.h"
+
+int setegid(gid_t egid)
+{
+	return __setxid(__NR_setresgid, -1, egid, -1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/seteuid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/seteuid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/seteuid.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int seteuid(uid_t euid)
+{
+	return __setxid(__NR_setresuid, -1, euid, -1);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setgid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setgid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setgid.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setgid(gid_t gid)
+{
+	return __setxid(__NR_setgid, gid, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setpgid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setpgid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setpgid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int setpgid(pid_t pid, pid_t pgid)
+{
+	return syscall(SYS_setpgid, pid, pgid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setpgrp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setpgrp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setpgrp.c	(revision 398)
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+pid_t setpgrp(void)
+{
+	return setpgid(0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setregid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setregid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setregid.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setregid(gid_t rgid, gid_t egid)
+{
+	return __setxid(__NR_setregid, rgid, egid, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setresgid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setresgid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setresgid.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid)
+{
+	return __setxid(__NR_setresgid, rgid, egid, sgid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setresuid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setresuid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setresuid.c	(revision 398)
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setresuid(uid_t ruid, uid_t euid, uid_t suid)
+{
+	return __setxid(__NR_setresuid, ruid, euid, suid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setreuid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setreuid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setreuid.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setreuid(uid_t ruid, uid_t euid)
+{
+	return __setxid(__NR_setreuid, ruid, euid, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setsid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setsid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setsid.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t setsid(void)
+{
+	return syscall(SYS_setsid);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setuid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setuid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setuid.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setuid(uid_t uid)
+{
+	return __setxid(__NR_setuid, uid, 0, 0);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setxid.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setxid.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/setxid.c	(revision 398)
@@ -0,0 +1,39 @@
+#include <unistd.h>
+#include <errno.h>
+#include "syscall.h"
+#include "libc.h"
+#include "pthread_impl.h"
+
+struct ctx {
+	int id, eid, sid;
+	int nr, err;
+};
+
+static void do_setxid(void *p)
+{
+	struct ctx *c = p;
+	if (c->err>0) return;
+	int ret = -__syscall_nr(c->nr, c->id, c->eid, c->sid);
+	if (ret && !c->err) {
+		/* If one thread fails to set ids after another has already
+		 * succeeded, forcibly killing the process is the only safe
+		 * thing to do. State is inconsistent and dangerous. Use
+		 * SIGKILL because it is uncatchable. */
+		__block_all_sigs(0);
+		__syscall(SYS_kill, __syscall(SYS_getpid), SIGKILL);
+	}
+	c->err = ret;
+}
+
+int __setxid(int nr, int id, int eid, int sid)
+{
+	/* err is initially nonzero so that failure of the first thread does not
+	 * trigger the safety kill above. */
+	struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid, .err = -1 };
+	__synccall(do_setxid, &c);
+	if (c.err) {
+		if (c.err>0) errno = c.err;
+		return -1;
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/sleep.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/sleep.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/sleep.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include <time.h>
+
+unsigned sleep(unsigned seconds)
+{
+	struct timespec tv = { .tv_sec = seconds, .tv_nsec = 0 };
+	if (nanosleep(&tv, &tv))
+		return tv.tv_sec;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/symlink.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/symlink.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/symlink.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int symlink(const char *existing, const char *new)
+{
+#ifdef SYS_symlink
+	return syscall(SYS_symlink, existing, new);
+#else
+	return syscall(SYS_symlinkat, existing, AT_FDCWD, new);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/symlinkat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/symlinkat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/symlinkat.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int symlinkat(const char *existing, int fd, const char *new)
+{
+	return syscall(SYS_symlinkat, existing, fd, new);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/sync.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/sync.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/sync.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+void sync(void)
+{
+	__syscall(SYS_sync);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/tcgetpgrp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/tcgetpgrp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/tcgetpgrp.c	(revision 398)
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+pid_t tcgetpgrp(int fd)
+{
+	int pgrp;
+	if (ioctl(fd, TIOCGPGRP, &pgrp) < 0)
+		return -1;
+	return pgrp;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/tcsetpgrp.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/tcsetpgrp.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/tcsetpgrp.c	(revision 398)
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcsetpgrp(int fd, pid_t pgrp)
+{
+	int pgrp_int = pgrp;
+	return ioctl(fd, TIOCSPGRP, &pgrp_int);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/truncate.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/truncate.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/truncate.c	(revision 398)
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int truncate(const char *path, off_t length)
+{
+	return syscall(SYS_truncate, path, __SYSCALL_LL_O(length));
+}
+
+LFS64(truncate);
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ttyname.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ttyname.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ttyname.c	(revision 398)
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+
+char *ttyname(int fd)
+{
+	static char buf[TTY_NAME_MAX];
+	int result;
+	if ((result = ttyname_r(fd, buf, sizeof buf))) {
+		errno = result;
+		return NULL;
+	}
+	return buf;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ttyname_r.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ttyname_r.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ttyname_r.c	(revision 398)
@@ -0,0 +1,29 @@
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+void __procfdname(char *, unsigned);
+
+int ttyname_r(int fd, char *name, size_t size)
+{
+	struct stat st1, st2;
+	char procname[sizeof "/proc/self/fd/" + 3*sizeof(int) + 2];
+	ssize_t l;
+
+	if (!isatty(fd)) return ENOTTY;
+
+	__procfdname(procname, fd);
+	l = readlink(procname, name, size);
+
+	if (l < 0) return errno;
+	else if (l == size) return ERANGE;
+
+	name[l] = 0;
+
+	if (stat(name, &st1) || fstat(fd, &st2))
+		return errno;
+	if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
+		return ENODEV;
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ualarm.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ualarm.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/ualarm.c	(revision 398)
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/time.h>
+
+unsigned ualarm(unsigned value, unsigned interval)
+{
+	struct itimerval it = {
+		.it_interval.tv_usec = interval,
+		.it_value.tv_usec = value
+	};
+	setitimer(ITIMER_REAL, &it, &it);
+	return it.it_value.tv_sec*1000000 + it.it_value.tv_usec;
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/unlink.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/unlink.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/unlink.c	(revision 398)
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int unlink(const char *path)
+{
+#ifdef SYS_unlink
+	return syscall(SYS_unlink, path);
+#else
+	return syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#endif
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/unlinkat.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/unlinkat.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/unlinkat.c	(revision 398)
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int unlinkat(int fd, const char *path, int flag)
+{
+	return syscall(SYS_unlinkat, fd, path, flag);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/usleep.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/usleep.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/usleep.c	(revision 398)
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <time.h>
+
+int usleep(unsigned useconds)
+{
+	struct timespec tv = {
+		.tv_sec = useconds/1000000,
+		.tv_nsec = (useconds%1000000)*1000
+	};
+	return nanosleep(&tv, &tv);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/write.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/write.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/write.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t write(int fd, const void *buf, size_t count)
+{
+	return syscall_cp(SYS_write, fd, buf, count);
+}
Index: /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/writev.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/writev.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/musl-1.1.18/src/unistd/writev.c	(revision 398)
@@ -0,0 +1,8 @@
+#include <sys/uio.h>
+#include "syscall.h"
+#include "libc.h"
+
+ssize_t writev(int fd, const struct iovec *iov, int count)
+{
+	return syscall_cp(SYS_writev, fd, iov, count);
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/.project
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/.project	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/.project	(revision 398)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ntshell</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ccsbcs.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ccsbcs.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ccsbcs.c	(revision 398)
@@ -0,0 +1,348 @@
+/*------------------------------------------------------------------------*/
+/* Unicode - Local code bidirectional converter  (C)ChaN, 2015            */
+/* (SBCS code pages)                                                      */
+/*------------------------------------------------------------------------*/
+/*  437   U.S.
+/   720   Arabic
+/   737   Greek
+/   771   KBL
+/   775   Baltic
+/   850   Latin 1
+/   852   Latin 2
+/   855   Cyrillic
+/   857   Turkish
+/   860   Portuguese
+/   861   Icelandic
+/   862   Hebrew
+/   863   Canadian French
+/   864   Arabic
+/   865   Nordic
+/   866   Russian
+/   869   Greek 2
+*/
+
+#include "ff.h"
+
+
+#if FF_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 FF_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, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif FF_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 FF_CODE_PAGE == 771
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP771(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, 0x2558, 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, 0x0104, 0x0105, 0x010C, 0x010D,
+	0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+	0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
+};
+
+#elif FF_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 FF_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 FF_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 FF_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 FF_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 FF_CODE_PAGE == 860
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP860(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
+	0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 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 FF_CODE_PAGE == 861
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP861(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
+	0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 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 FF_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 FF_CODE_PAGE == 863
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP863(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
+	0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
+	0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 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, 0x2219,
+	0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
+};
+
+#elif FF_CODE_PAGE == 864
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP864(0x80-0xFF) to Unicode conversion table */
+	0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
+	0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
+	0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
+	0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,
+	0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,
+	0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,
+	0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
+	0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
+};
+
+#elif FF_CODE_PAGE == 865
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP865(0x80-0xFF) to Unicode conversion table */
+	0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+	0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
+	0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 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 FF_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 FF_CODE_PAGE == 869
+#define _TBLDEF 1
+static
+const WCHAR Tbl[] = {	/*  CP869(0x80-0xFF) to Unicode conversion table */
+	0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
+	0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
+	0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
+	0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,
+	0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,
+	0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,
+	0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
+	0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
+};
+
+#endif
+
+
+#if FF_CODE_PAGE != 65001 && (!_TBLDEF || !FF_USE_LFN)
+#error This file is not needed at current configuration. Remove from the project.
+#endif
+
+
+
+#if FF_CODE_PAGE != 65001
+WCHAR ff_convert (	/* Converted character, Returns zero on error */
+	WCHAR	chr,	/* Character code to be converted */
+	UINT	dir		/* 0: Unicode to OEM code, 1: OEM code to Unicode */
+)
+{
+	WCHAR c;
+
+
+	if (chr < 0x80) {	/* ASCII */
+		c = chr;
+
+	} else {
+		if (dir) {		/* OEM code to Unicode */
+			c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
+
+		} else {		/* Unicode to OEM code */
+			for (c = 0; c < 0x80; c++) {
+				if (chr == Tbl[c]) break;
+			}
+			c = (c + 0x80) & 0xFF;
+		}
+	}
+
+	return c;
+}
+#endif
+
+
+
+WCHAR ff_wtoupper (	/* Returns upper converted character */
+	WCHAR chr		/* Unicode character to be upper converted */
+)
+{
+	static const WCHAR lower[] = {	/* Lower case characters to be converted */
+	/* Latin Supplement */			0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
+	/* Latin Extended-A */			0x101,0x103,0x105,0x107,0x109,0x10B,0x10D,0x10F,0x111,0x113,0x115,0x117,0x119,0x11B,0x11D,0x11F,0x121,0x123,0x125,0x127,0x129,0x12B,0x12D,0x12F,0x131,0x133,0x135,0x137,0x13A,0x13C,0x13E,0x140,0x142,0x144,0x146,0x148,0x14B,0x14D,0x14F,0x151,0x153,0x155,0x157,0x159,0x15B,0x15D,0x15F,0x161,0x163,0x165,0x167,0x169,0x16B,0x16D,0x16F,0x171,0x173,0x175,0x177,0x17A,0x17C,0x17E,
+	/* Latin Extended-B */			0x183,0x185,0x188,0x18C,0x192,0x199,0x1A1,0x1A3,0x1A8,0x1AD,0x1B0,0x1B4,0x1B6,0x1B9,0x1BD,0x1C6,0x1C9,0x1CC,0x1CE,0x1D0,0x1D2,0x1D4,0x1D6,0x1D8,0x1DA,0x1DC,0x1DD,0x1DF,0x1E1,0x1E3,0x1E5,0x1E7,0x1E9,0x1EB,0x1ED,0x1EF,0x1F3,0x1F5,0x1FB,0x1FD,0x1FF,0x201,0x203,0x205,0x207,0x209,0x20B,0x20D,0x20F,0x211,0x213,0x215,0x217,
+	/* Greek, Coptic */				0x3B1,0x3B2,0x3B3,0x3B4,0x3B5,0x3B6,0x3B7,0x3B8,0x3B9,0x3BA,0x3BB,0x3BC,0x3BD,0x3BE,0x3BF,0x3C0,0x3C1,0x3C3,0x3C4,0x3C5,0x3C6,0x3C7,0x3C8,0x3C9,0x3CA,0x3CB,0x3CC,0x3CD,0x3CE,0x3E3,0x3E5,0x3E7,0x3E9,0x3EB,
+	/* Cyrillic */					0x430,0x431,0x432,0x433,0x434,0x435,0x436,0x437,0x438,0x439,0x43A,0x43B,0x43C,0x43D,0x43E,0x43F,0x440,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44A,0x44B,0x44C,0x44D,0x44E,0x44F,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45A,0x45B,0x45C,0x45E,0x45F,0x461,0x463,0x465,0x467,0x469,0x46B,0x46D,0x46F,0x471,0x473,0x475,0x477,0x479,0x47B,0x47D,0x47F,0x481,0x491,0x493,0x495,0x497,0x499,0x49B,0x49D,0x49F,0x4A1,0x4A3,0x4A5,0x4A7,0x4A9,0x4AB,0x4AD,0x4AF,0x4B1,0x4B3,0x4B5,0x4B7,0x4B9,0x4BB,0x4BD,0x4BF,0x4C2,0x4C4,0x4C8,0x4D1,0x4D3,0x4D5,0x4D7,0x4D9,0x4DB,0x4DD,0x4DF,0x4E1,0x4E3,0x4E5,0x4E7,0x4E9,0x4EB,0x4ED,0x4EF,0x4F1,0x4F3,0x4F5,0x4F9,
+	/* Armenian */					0x561,0x562,0x563,0x564,0x565,0x566,0x567,0x568,0x569,0x56A,0x56B,0x56C,0x56D,0x56E,0x56F,0x570,0x571,0x572,0x573,0x574,0x575,0x576,0x577,0x578,0x579,0x57A,0x57B,0x57C,0x57D,0x57E,0x57F,0x580,0x581,0x582,0x583,0x584,0x585,0x586,
+	/* Latin Extended Additional */	0x1E01,0x1E03,0x1E05,0x1E07,0x1E09,0x1E0B,0x1E0D,0x1E0F,0x1E11,0x1E13,0x1E15,0x1E17,0x1E19,0x1E1B,0x1E1D,0x1E1F,0x1E21,0x1E23,0x1E25,0x1E27,0x1E29,0x1E2B,0x1E2D,0x1E2F,0x1E31,0x1E33,0x1E35,0x1E37,0x1E39,0x1E3B,0x1E3D,0x1E3F,0x1E41,0x1E43,0x1E45,0x1E47,0x1E49,0x1E4B,0x1E4D,0x1E4F,0x1E51,0x1E53,0x1E55,0x1E57,0x1E59,0x1E5B,0x1E5D,0x1E5F,0x1E61,0x1E63,0x1E65,0x1E67,0x1E69,0x1E6B,0x1E6D,0x1E6F,0x1E71,0x1E73,0x1E75,0x1E77,0x1E79,0x1E7B,0x1E7D,0x1E7F,0x1E81,0x1E83,0x1E85,0x1E87,0x1E89,0x1E8B,0x1E8D,0x1E8F,0x1E91,0x1E93,0x1E95,0x1E97,0x1E99,0x1E9B,0x1E9D,0x1E9F,0x1EA1,0x1EA3,0x1EA5,0x1EA7,0x1EA9,0x1EAB,0x1EAD,0x1EAF,0x1EB1,0x1EB3,0x1EB5,0x1EB7,0x1EB9,0x1EBB,0x1EBD,0x1EBF,0x1EC1,0x1EC3,0x1EC5,0x1EC7,0x1EC9,0x1ECB,0x1ECD,0x1ECF,0x1ED1,0x1ED3,0x1ED5,0x1ED7,0x1ED9,0x1EDB,0x1EDD,0x1EDF,0x1EE1,0x1EE3,0x1EE5,0x1EE7,0x1EE9,0x1EEB,0x1EED,0x1EEF,0x1EF1,0x1EF3,0x1EF5,0x1EF7,0x1EF9,
+	/* Number forms */				0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,0x2178,0x2179,0x217A,0x217B,0x217C,0x217D,0x217E,0x217F,
+	/* Full-width */				0xFF41,0xFF42,0xFF43,0xFF44,0xFF45,0xFF46,0xFF47,0xFF48,0xFF49,0xFF4A,0xFF4B,0xFF4C,0xFF4D,0xFF4E,0xFF4F,0xFF50,0xFF51,0xFF52,0xFF53,0xFF54,0xFF55,0xFF56,0xFF57,0xFF58,0xFF59,0xFF5A
+	};
+	static const WCHAR upper[] = {	/* Upper case characters correspond to lower[] */
+									0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x178,
+									0x100,0x102,0x104,0x106,0x108,0x10A,0x10C,0x10E,0x110,0x112,0x114,0x116,0x118,0x11A,0x11C,0x11E,0x120,0x122,0x124,0x126,0x128,0x12A,0x12C,0x12E,0x130,0x132,0x134,0x136,0x139,0x13B,0x13D,0x13F,0x141,0x143,0x145,0x147,0x14A,0x14C,0x14E,0x150,0x152,0x154,0x156,0x158,0x15A,0x15C,0x15E,0x160,0x162,0x164,0x166,0x168,0x16A,0x16C,0x16E,0x170,0x172,0x174,0x176,0x179,0x17B,0x17D,
+									0x182,0x184,0x187,0x18B,0x191,0x198,0x1A0,0x1A2,0x1A7,0x1AC,0x1AF,0x1B3,0x1B5,0x1B8,0x1BC,0x1C4,0x1C7,0x1CA,0x1CD,0x1CF,0x1D1,0x1D3,0x1D5,0x1D7,0x1D9,0x1DB,0x18E,0x1DE,0x1E0,0x1E2,0x1E4,0x1E6,0x1E8,0x1EA,0x1EC,0x1EE,0x1F1,0x1F4,0x1FA,0x1FC,0x1FE,0x200,0x202,0x204,0x206,0x208,0x20A,0x20C,0x20E,0x210,0x212,0x214,0x216,
+									0x391,0x392,0x393,0x394,0x395,0x396,0x397,0x398,0x399,0x39A,0x39B,0x39C,0x39D,0x39E,0x39F,0x3A0,0x3A1,0x3A3,0x3A4,0x3A5,0x3A6,0x3A7,0x3A8,0x3A9,0x3AA,0x3AB,0x38C,0x38E,0x38F,0x3E2,0x3E4,0x3E6,0x3E8,0x3EA,
+									0x410,0x411,0x412,0x413,0x414,0x415,0x416,0x417,0x418,0x419,0x41A,0x41B,0x41C,0x41D,0x41E,0x41F,0x420,0x421,0x422,0x423,0x424,0x425,0x426,0x427,0x428,0x429,0x42A,0x42B,0x42C,0x42D,0x42E,0x42F,0x402,0x403,0x404,0x405,0x406,0x407,0x408,0x409,0x40A,0x40B,0x40C,0x40E,0x40F,0x460,0x462,0x464,0x466,0x468,0x46A,0x46C,0x46E,0x470,0x472,0x474,0x476,0x478,0x47A,0x47C,0x47E,0x480,0x490,0x492,0x494,0x496,0x498,0x49A,0x49C,0x49E,0x4A0,0x4A2,0x4A4,0x4A6,0x4A8,0x4AA,0x4AC,0x4AE,0x4B0,0x4B2,0x4B4,0x4B6,0x4B8,0x4BA,0x4BC,0x4BE,0x4C1,0x4C3,0x5C7,0x4D0,0x4D2,0x4D4,0x4D6,0x4D8,0x4DA,0x4DC,0x4DE,0x4E0,0x4E2,0x4E4,0x4E6,0x4E8,0x4EA,0x4EC,0x4EE,0x4F0,0x4F2,0x4F4,0x4F8,
+									0x531,0x532,0x533,0x534,0x535,0x536,0x537,0x538,0x539,0x53A,0x53B,0x53C,0x53D,0x53E,0x53F,0x540,0x541,0x542,0x543,0x544,0x545,0x546,0x547,0x548,0x549,0x54A,0x54B,0x54C,0x54D,0x54E,0x54F,0x550,0x551,0x552,0x553,0x554,0x555,0x556,
+									0x1E00,0x1E02,0x1E04,0x1E06,0x1E08,0x1E0A,0x1E0C,0x1E0E,0x1E10,0x1E12,0x1E14,0x1E16,0x1E18,0x1E1A,0x1E1C,0x1E1E,0x1E20,0x1E22,0x1E24,0x1E26,0x1E28,0x1E2A,0x1E2C,0x1E2E,0x1E30,0x1E32,0x1E34,0x1E36,0x1E38,0x1E3A,0x1E3C,0x1E3E,0x1E40,0x1E42,0x1E44,0x1E46,0x1E48,0x1E4A,0x1E4C,0x1E4E,0x1E50,0x1E52,0x1E54,0x1E56,0x1E58,0x1E5A,0x1E5C,0x1E5E,0x1E60,0x1E62,0x1E64,0x1E66,0x1E68,0x1E6A,0x1E6C,0x1E6E,0x1E70,0x1E72,0x1E74,0x1E76,0x1E78,0x1E7A,0x1E7C,0x1E7E,0x1E80,0x1E82,0x1E84,0x1E86,0x1E88,0x1E8A,0x1E8C,0x1E8E,0x1E90,0x1E92,0x1E94,0x1E96,0x1E98,0x1E9A,0x1E9C,0x1E9E,0x1EA0,0x1EA2,0x1EA4,0x1EA6,0x1EA8,0x1EAA,0x1EAC,0x1EAE,0x1EB0,0x1EB2,0x1EB4,0x1EB6,0x1EB8,0x1EBA,0x1EBC,0x1EBE,0x1EC0,0x1EC2,0x1EC4,0x1EC6,0x1EC8,0x1ECA,0x1ECC,0x1ECE,0x1ED0,0x1ED2,0x1ED4,0x1ED6,0x1ED8,0x1EDA,0x1EDC,0x1EDE,0x1EE0,0x1EE2,0x1EE4,0x1EE6,0x1EE8,0x1EEA,0x1EEC,0x1EEE,0x1EF0,0x1EF2,0x1EF4,0x1EF6,0x1EF8,
+									0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,0x2168,0x2169,0x216A,0x216B,0x216C,0x216D,0x216E,0x216F,
+									0xFF21,0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27,0xFF28,0xFF29,0xFF2A,0xFF2B,0xFF2C,0xFF2D,0xFF2E,0xFF2F,0xFF30,0xFF31,0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,0xFF39,0xFF3A
+	};
+	UINT i, n, hi, li;
+
+
+	if (chr < 0x80) {	/* ASCII characters (acceleration) */
+		if (chr >= 0x61 && chr <= 0x7A) chr -= 0x20;
+
+	} else {			/* Non ASCII characters (table search) */
+		n = 12; li = 0; hi = sizeof lower / sizeof lower[0];
+		do {
+			i = li + (hi - li) / 2;
+			if (chr == lower[i]) break;
+			if (chr > lower[i]) li = i; else hi = i;
+		} while (--n);
+		if (n) chr = upper[i];
+	}
+
+	return chr;
+}
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/diskio.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/diskio.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/diskio.c	(revision 398)
@@ -0,0 +1,137 @@
+/*-----------------------------------------------------------------------*/
+/* PFF - Low level disk control module for Win32        (C)ChaN, 2014    */
+/*-----------------------------------------------------------------------*/
+
+#include <string.h>
+#include "ffconf.h"
+#include "diskio.h"
+
+/*--------------------------------------------------------------------------
+
+   Module Private Functions
+
+---------------------------------------------------------------------------*/
+
+#define MAX_DRIVES	1	/* Max number of physical drives to be used */
+
+extern unsigned char RamDisk[];
+
+typedef struct {
+	DSTATUS	status;
+	WORD sz_sector;
+	DWORD wofs;
+	DWORD wip;
+	DWORD n_sectors;
+} RD_STAT;
+
+static volatile
+RD_STAT Stat[MAX_DRIVES];
+
+static
+BYTE Buffer[SS_RAMDISK];
+
+static
+int get_status(volatile RD_STAT *stat) {
+	stat->sz_sector = SS_RAMDISK;
+	if(stat->sz_sector < FF_MIN_SS || stat->sz_sector > FF_MAX_SS) return 0;
+	stat->n_sectors = SZ_RAMDISK * 1024 / SS_RAMDISK;
+	stat->status = 0;
+	return 1;
+}
+
+/*-----------------------------------------------------------------------*/
+/* Initialize Disk Drive                                                 */
+/*-----------------------------------------------------------------------*/
+DSTATUS ramdisk_initialize (void)
+{
+	DSTATUS sta;
+
+	get_status(&Stat[0]);
+	sta = Stat[0].status;
+	Stat[0].wip = 0;
+
+	return sta;
+}
+
+/*-----------------------------------------------------------------------*/
+/* Get Disk Status                                                       */
+/*-----------------------------------------------------------------------*/
+DSTATUS ramdisk_get_status (void)
+{
+	return Stat[0].status;
+}
+
+/*-----------------------------------------------------------------------*/
+/* Read Partial Sector                                                   */
+/*-----------------------------------------------------------------------*/
+DRESULT ramdisk_read (
+	BYTE* buff,		/* Data read buffer */
+	DWORD sector,	/* Sector number (LBA) */
+	UINT count		/* Number of sectors to read (1..128) */
+)
+{
+	DRESULT res;
+	int dofs;
+
+
+	if(Stat[0].status & STA_NOINIT) return RES_NOTRDY;
+
+	if(sector >= Stat[0].n_sectors || !count || (sector + count) > Stat[0].n_sectors/* || Stat[0].wip*/) {
+		res = RES_PARERR;
+	}
+	else {
+		if(buff) {
+			dofs = sector * Stat[0].sz_sector;
+			memcpy(buff, &RamDisk[dofs], count * Stat[0].sz_sector);
+			res = RES_OK;
+		}
+		else {
+			res = RES_OK;
+		}
+	}
+
+	return res;
+}
+
+/*-----------------------------------------------------------------------*/
+/* Write Partial Sector                                                  */
+/*-----------------------------------------------------------------------*/
+DRESULT ramdisk_write (
+	const BYTE* buff,	/* Pointer to the write data */
+	DWORD sc,			/* Sector number (LBA), Number of bytes to send */
+	UINT count		/* Number of sectors to read (1..128) */
+)
+{
+	DRESULT res;
+	int dofs;
+
+	if(Stat[0].status & STA_NOINIT) return RES_NOTRDY;
+
+	if(!buff) {
+		if(sc) {
+			Stat[0].wip = sc;
+			Stat[0].wofs = 0;
+			memset(Buffer, 0, sizeof Buffer);
+			res = RES_OK;
+		}
+		else {
+			if(Stat[0].wip) {
+				dofs = Stat[0].wip * Stat[0].sz_sector;
+				memcpy(RamDisk + dofs, Buffer, Stat[0].sz_sector);
+				Stat[0].wip = 0;
+				res = RES_OK;
+			}
+			else {
+				res = RES_OK;
+			}
+		}
+	}
+	else {
+		if(Stat[0].wofs + sc > Stat[0].sz_sector) sc = Stat[0].sz_sector - Stat[0].wofs;
+		memcpy(&Buffer[Stat[0].wofs], buff, sc);
+		Stat[0].wofs += sc;
+		res = RES_OK;
+	}
+
+	return res;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/diskio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/diskio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/diskio.h	(revision 398)
@@ -0,0 +1,101 @@
+/*-----------------------------------------------------------------------
+/  Low level disk interface modlue include file   (C)ChaN, 2014
+/-----------------------------------------------------------------------*/
+
+#ifndef _DISKIO_DEFINED
+#define _DISKIO_DEFINED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _USE_WRITE	1	/* 1: Enable disk_write function */
+#define _USE_IOCTL	1	/* 1: Enable disk_ioctl fucntion */
+
+#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 */
+
+DSTATUS disk_initialize (BYTE pdrv);
+DSTATUS disk_status (BYTE pdrv);
+DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
+#if	_USE_WRITE
+DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
+#endif
+#if	_USE_IOCTL
+DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
+#endif
+void disk_timerproc(void);
+
+#define SZ_RAMDISK	1536	/* Size of RAM disk [kB] */
+#define SS_RAMDISK	512		/* Sector size of RAM disk [byte] */
+
+DSTATUS ramdisk_initialize (void);
+DSTATUS ramdisk_get_status (void);
+DRESULT ramdisk_read (BYTE* buff, DWORD sector, UINT count);
+DRESULT ramdisk_write (const BYTE* buff, DWORD sector, UINT count);
+
+/* 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 fucntion */
+
+/* Generic command (Used by FatFs) */
+#define CTRL_SYNC			0	/* Complete pending write process (needed at FF_FS_READONLY == 0) */
+#define GET_SECTOR_COUNT	1	/* Get media size (needed at FF_USE_MKFS == 1) */
+#define GET_SECTOR_SIZE		2	/* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
+#define GET_BLOCK_SIZE		3	/* Get erase block size (needed at FF_USE_MKFS == 1) */
+#define CTRL_TRIM			4	/* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
+
+/* Generic command (Not used by FatFs) */
+#define CTRL_FORMAT			5	/* Create physical format on the media */
+#define CTRL_POWER_IDLE		6	/* Put the device idle state */
+#define CTRL_POWER_OFF		7	/* Put the device off state */
+#define CTRL_LOCK			8	/* Lock media removal */
+#define CTRL_UNLOCK			9	/* Unlock media removal */
+#define CTRL_EJECT			10	/* Eject media */
+
+/* MMC/SDC specific command (Not used by FatFs) */
+#define MMC_GET_TYPE		50	/* Get card type */
+#define MMC_GET_CSD			51	/* Get CSD */
+#define MMC_GET_CID			52	/* Get CID */
+#define MMC_GET_OCR			53	/* Get OCR */
+#define MMC_GET_SDSTAT		54	/* Get SD status */
+
+/* ATA/CF specific command (Not used by FatFs) */
+#define ATA_GET_REV			60	/* Get F/W revision */
+#define ATA_GET_MODEL		61	/* Get model name */
+#define ATA_GET_SN			62	/* Get serial number */
+
+
+/* MMC card type flags (MMC_GET_TYPE) */
+#define CT_MMC		0x01		/* MMC ver 3 */
+#define CT_SD1		0x02		/* SD ver 1 */
+#define CT_SD2		0x04		/* SD ver 2 */
+#define CT_SDC		(CT_SD1|CT_SD2)	/* SD */
+#define CT_BLOCK	0x08		/* Block addressing */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _DISKIO_DEFINED */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ff.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ff.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ff.c	(revision 398)
@@ -0,0 +1,4873 @@
+/*----------------------------------------------------------------------------/
+/  FatFs - FAT file system module  R0.11a                (C)ChaN, 2015        /
+/-----------------------------------------------------------------------------/
+/ FatFs module is a free software that opened under license policy of
+/ following conditions.
+/
+/ Copyright (C) 2015, ChaN, all right reserved.
+/
+/ 1. Redistributions of source code must retain the above copyright notice,
+/    this condition and the following disclaimer.
+/
+/ This software is provided by the copyright holder and contributors "AS IS"
+/ and any warranties related to this software are DISCLAIMED.
+/ The copyright owner or contributors be NOT LIABLE for any damages caused
+/ by use of this software.
+/----------------------------------------------------------------------------*/
+
+
+#include "shellif.h"
+#include "ff.h"			/* Declarations of FatFs API */
+#include "diskio.h"		/* Declarations of disk I/O functions */
+#include <stdio.h>
+
+/*--------------------------------------------------------------------------
+
+   Module Private Definitions
+
+---------------------------------------------------------------------------*/
+
+#if _FATFS != 64180	/* Revision ID */
+#error Wrong include file (ff.h).
+#endif
+
+
+/* Reentrancy related */
+#if FF_FS_REENTRANT
+#if FF_USE_LFN == 1
+#error Static LFN work area cannot be used at thread-safe 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->err = (BYTE)(res); LEAVE_FF(fs, res); }
+
+
+/* Definitions of sector size */
+#if (FF_MAX_SS < FF_MIN_SS) || (FF_MAX_SS != 512 && FF_MAX_SS != 1024 && FF_MAX_SS != 2048 && FF_MAX_SS != 4096) || (FF_MIN_SS != 512 && FF_MIN_SS != 1024 && FF_MIN_SS != 2048 && FF_MIN_SS != 4096)
+#error Wrong sector size configuration
+#endif
+#if FF_MAX_SS == FF_MIN_SS
+#define	SS(fs)	((UINT)FF_MAX_SS)	/* Fixed sector size */
+#else
+#define	SS(fs)	((fs)->ssize)	/* Variable sector size */
+#endif
+
+
+/* Timestamp feature */
+#if FF_FS_NORTC == 1
+#if FF_NORTC_YEAR < 1980 || FF_NORTC_YEAR > 2107 || FF_NORTC_MON < 1 || FF_NORTC_MON > 12 || FF_NORTC_MDAY < 1 || FF_NORTC_MDAY > 31
+#error Invalid FF_FS_NORTC settings
+#endif
+#define GET_FATTIME()	((DWORD)(FF_NORTC_YEAR - 1980) << 25 | (DWORD)FF_NORTC_MON << 21 | (DWORD)FF_NORTC_MDAY << 16)
+#else
+#define GET_FATTIME()	get_fattime()
+#endif
+
+
+/* File access control feature */
+#if FF_FS_LOCK != 0
+#if FF_FS_READONLY
+#error FF_FS_LOCK must be 0 at read-only configuration
+#endif
+typedef struct {
+	FATFS *fs;		/* Object ID 1, volume (NULL:blank entry) */
+	DWORD clu;		/* Object ID 2, directory (0:root) */
+	WORD idx;		/* Object ID 3, directory index */
+	WORD ctr;		/* Object open counter, 0:none, 0x01..0xFF:read mode open count, 0x100:write mode */
+} FILESEM;
+#endif
+
+
+
+/* DBCS code ranges and SBCS upper conversion tables */
+
+#if FF_CODE_PAGE == 932	/* 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 FF_CODE_PAGE == 936	/* Simplified Chinese GBK */
+#define _DF1S	0x81
+#define _DF1E	0xFE
+#define _DS1S	0x40
+#define _DS1E	0x7E
+#define _DS2S	0x80
+#define _DS2E	0xFE
+
+#elif FF_CODE_PAGE == 949	/* 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 FF_CODE_PAGE == 950	/* Traditional Chinese Big5 */
+#define _DF1S	0x81
+#define _DF1E	0xFE
+#define _DS1S	0x40
+#define _DS1E	0x7E
+#define _DS2S	0xA1
+#define _DS2E	0xFE
+
+#elif FF_CODE_PAGE == 437	/* U.S. */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \
+				0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0x41,0x49,0x4F,0x55,0xA5,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, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 720	/* Arabic */
+#define _DF1S	0
+#define _EXCVT {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,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, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 737	/* Greek */
+#define _DF1S	0
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
+				0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
+				0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96, \
+				0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xEF,0xF5,0xF0,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 771	/* KBL */
+#define _DF1S	0
+#define _EXCVT {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,0x9F, \
+				0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
+				0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDC,0xDE,0xDE, \
+				0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 775	/* Baltic */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F, \
+				0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
+				0xA0,0xA1,0xE0,0xA3,0xA3,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, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 850	/* Latin 1 */
+#define _DF1S	0
+#define _EXCVT {0x43,0x55,0x45,0x41,0x41,0x41,0x41,0x43,0x45,0x45,0x45,0x49,0x49,0x49,0x41,0x41, \
+				0x45,0x92,0x92,0x4F,0x4F,0x4F,0x55,0x55,0x59,0x4F,0x55,0x4F,0x9C,0x4F,0x9E,0x9F, \
+				0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
+				0xB0,0xB1,0xB2,0xB3,0xB4,0x41,0x41,0x41,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0x41,0x41,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD1,0xD1,0x45,0x45,0x45,0x49,0x49,0x49,0x49,0xD9,0xDA,0xDB,0xDC,0xDD,0x49,0xDF, \
+				0x4F,0xE1,0x4F,0x4F,0x4F,0x4F,0xE6,0xE8,0xE8,0x55,0x55,0x55,0x59,0x59,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 852	/* Latin 2 */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F, \
+				0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0xAC, \
+				0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF, \
+				0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 855	/* Cyrillic */
+#define _DF1S	0
+#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F, \
+				0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
+				0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF, \
+				0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
+				0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF, \
+				0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 857	/* Turkish */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x49,0x8E,0x8F, \
+				0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
+				0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
+				0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0x49,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 860	/* Portuguese */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x90,0x8F,0x8E,0x91,0x86,0x80,0x89,0x89,0x92,0x8B,0x8C,0x98,0x8E,0x8F, \
+				0x90,0x91,0x92,0x8C,0x99,0xA9,0x96,0x9D,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0x86,0x8B,0x9F,0x96,0xA5,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, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 861	/* Icelandic */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x8B,0x8B,0x8D,0x8E,0x8F, \
+				0x90,0x92,0x92,0x4F,0x99,0x8D,0x55,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
+				0xA4,0xA5,0xA6,0xA7,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, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 862	/* Hebrew */
+#define _DF1S	0
+#define _EXCVT {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,0x9F, \
+				0x41,0x49,0x4F,0x55,0xA5,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, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 863	/* Canadian-French */
+#define _DF1S	0
+#define _EXCVT {0x43,0x55,0x45,0x41,0x41,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x41,0x8F, \
+				0x45,0x45,0x45,0x4F,0x45,0x49,0x55,0x55,0x98,0x4F,0x55,0x9B,0x9C,0x55,0x55,0x9F, \
+				0xA0,0xA1,0x4F,0x55,0xA4,0xA5,0xA6,0xA7,0x49,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, \
+				0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 864	/* Arabic */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x45,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \
+				0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0x41,0x49,0x4F,0x55,0xA5,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, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 865	/* Nordic */
+#define _DF1S	0
+#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F, \
+				0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0x41,0x49,0x4F,0x55,0xA5,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, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, \
+				0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 866	/* Russian */
+#define _DF1S	0
+#define _EXCVT {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,0x9F, \
+				0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, \
+				0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
+				0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
+				0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 869	/* Greek 2 */
+#define _DF1S	0
+#define _EXCVT {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,0x86,0x9C,0x8D,0x8F,0x90, \
+				0x91,0x90,0x92,0x95,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, \
+				0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, \
+				0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xA4,0xA5,0xA6,0xD9,0xDA,0xDB,0xDC,0xA7,0xA8,0xDF, \
+				0xA9,0xAA,0xAC,0xAD,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xCF,0xCF,0xD0,0xEF, \
+				0xF0,0xF1,0xD1,0xD2,0xD3,0xF5,0xD4,0xF7,0xF8,0xF9,0xD5,0x96,0x95,0x98,0xFE,0xFF}
+
+#elif FF_CODE_PAGE == 1	/* ASCII (for only non-LFN cfg) */
+#if FF_USE_LFN
+#error Cannot use LFN feature without valid code page.
+#endif
+#define _DF1S	0
+
+#elif FF_CODE_PAGE == 65001 /* UTF-8 */
+#if FF_LFN_UNICODE
+#error Cannot use LFN_UNICODE feature without valid code page.
+#endif
+#define _DF1S	0
+
+void Utf16_to_Utf8(unsigned char *ret_code, int *ret_size, UINT chr)
+{
+	ret_code[0] = ret_code[1] = ret_code[2] = ret_code[3] = 0;
+
+	if (chr <= 0x7f) {  // ASCII互換
+		ret_code[0] = chr;
+		*ret_size = 1;
+		return;
+	}
+
+	if (chr <= 0x7ff) {
+		ret_code[1] = (0x80 | (chr & 0x3f));
+		ret_code[0] = (0xc0 | (chr >> 6));
+		*ret_size = 2;
+		return;
+	}
+
+	if (chr <= 0xffff) {
+		ret_code[2] = (0x80 | (chr & 0x3f));
+		ret_code[1] = (0x80 | ((chr >> 6) & 0x3f));
+		ret_code[0] = (0xe0 | ((chr >> 12) & 0x0f));
+		*ret_size = 3;
+		return;
+	}
+
+	if (chr <= 0x1fffff) {
+		ret_code[3] = (0x80 | (chr & 0x3f));
+		ret_code[2] = (0x80 | ((chr >> 6) & 0x3f));
+		ret_code[1] = (0x80 | ((chr >> 12) & 0x3f));
+		ret_code[0] = (0xf0 | ((chr >> 18) & 0x07));
+		*ret_size = 4;
+		return;
+	}
+
+	if (chr <= 0x3ffffff) {
+		ret_code[4] = (0x80 | (chr & 0x3f));
+		ret_code[3] = (0x80 | ((chr >> 6) & 0x3f));
+		ret_code[2] = (0x80 | ((chr >> 12) & 0x3f));
+		ret_code[1] = (0x80 | ((chr >> 18) & 0x3f));
+		ret_code[0] = (0xf8 | ((chr >> 24) & 0x03));
+		*ret_size = 5;
+		return;
+	}
+
+	ret_code[5] = (0x80 | (chr & 0x3f));
+	ret_code[4] = (0x80 | ((chr >> 6) & 0x3f));
+	ret_code[3] = (0x80 | ((chr >> 12) & 0x3f));
+	ret_code[2] = (0x80 | ((chr >> 18) & 0x3f));
+	ret_code[1] = (0x80 | ((chr >> 24) & 0x3f));
+	ret_code[0] = (0xfc | ((chr >> 30) & 0x01));
+	*ret_size = 6;
+	return;
+}
+
+//2バイトのUTF-16コードが得られる
+WCHAR Utf8_to_Utf16(const char *src, int *code_size)
+{
+	int i;
+	unsigned int uc = 0;
+	unsigned char len = 0;
+
+	len = 0;
+	if ((src[0] & 0x80) == 0) { uc = src[0] & 0x7F; len = 0; }
+	else if ((src[0] & 0xE0) == 0xC0) { uc = src[0] & 0x1F; len = 1; }
+	else if ((src[0] & 0xF0) == 0xE0) { uc = src[0] & 0x0F; len = 2; }
+	else if ((src[0] & 0xF8) == 0xF0) { uc = src[0] & 0x07; len = 3; }
+	else if ((src[0] & 0xFC) == 0xF8) { uc = src[0] & 0x03; len = 4; }
+	else if ((src[0] & 0xFE) == 0xFC) { uc = src[0] & 0x01; len = 5; }
+
+	i = 1;
+	while ((i <= len) && ((src[i] & 0xC0) == 0x80)) {
+		uc = (uc << 6) | (src[i] & 0x3F);
+		i++;
+	}
+
+	//消費文字数設定
+	*code_size = i;
+
+	//現状、2バイト限定
+	return uc;
+}
+
+#else
+#error Unknown code page
+
+#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		/* Code page is DBCS */
+
+#ifdef _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
+
+#ifdef _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			/* Code page is SBCS */
+
+#define IsDBCS1(c)	0
+#define IsDBCS2(c)	0
+
+#endif /* _DF1S */
+
+
+/* Name status flags */
+#define NSFLAG		11		/* Index of name status byte in fn[] */
+#define NS_LOSS		0x01	/* Out of 8.3 format */
+#define NS_LFN		0x02	/* Force to create LFN entry */
+#define NS_LAST		0x04	/* Last segment */
+#define NS_BODY		0x08	/* Lower case flag (body) */
+#define NS_EXT		0x10	/* Lower case flag (ext) */
+#define NS_DOT		0x20	/* Dot entry */
+
+
+/* FAT sub-type boundaries (Differ from specs but correct for real DOS/Windows) */
+#define MIN_FAT16	4086U	/* Minimum number of clusters of FAT16 */
+#define	MIN_FAT32	65526U	/* Minimum number of clusters of FAT32 */
+
+
+/* FatFs refers the members in the FAT structures as byte array instead of
+/ structure members because the structure is not binary compatible between
+/ different platforms */
+
+#define BS_jmpBoot			0		/* x86 jump instruction (3) */
+#define BS_OEMName			3		/* OEM name (8) */
+#define BPB_BytsPerSec		11		/* Sector size [byte] (2) */
+#define BPB_SecPerClus		13		/* Cluster size [sector] (1) */
+#define BPB_RsvdSecCnt		14		/* Size of reserved area [sector] (2) */
+#define BPB_NumFATs			16		/* Number of FAT copies (1) */
+#define BPB_RootEntCnt		17		/* Number of root directory entries for FAT12/16 (2) */
+#define BPB_TotSec16		19		/* Volume size [sector] (2) */
+#define BPB_Media			21		/* Media descriptor (1) */
+#define BPB_FATSz16			22		/* FAT size [sector] (2) */
+#define BPB_SecPerTrk		24		/* Track size [sector] (2) */
+#define BPB_NumHeads		26		/* Number of heads (2) */
+#define BPB_HiddSec			28		/* Number of special hidden sectors (4) */
+#define BPB_TotSec32		32		/* Volume size [sector] (4) */
+#define BS_DrvNum			36		/* Physical drive number (1) */
+#define BS_NTres			37		/* Error flag (1) */
+#define BS_BootSig			38		/* Extended boot signature (1) */
+#define BS_VolID			39		/* Volume serial number (4) */
+#define BS_VolLab			43		/* Volume label (8) */
+#define BS_FilSysType		54		/* File system type (1) */
+#define BPB_FATSz32			36		/* FAT size [sector] (4) */
+#define BPB_ExtFlags		40		/* Extended flags (2) */
+#define BPB_FSVer			42		/* File system version (2) */
+#define BPB_RootClus		44		/* Root directory first cluster (4) */
+#define BPB_FSInfo			48		/* Offset of FSINFO sector (2) */
+#define BPB_BkBootSec		50		/* Offset of backup boot sector (2) */
+#define BS_DrvNum32			64		/* Physical drive number (1) */
+#define BS_NTres32			65		/* Error flag (1) */
+#define BS_BootSig32		66		/* Extended boot signature (1) */
+#define BS_VolID32			67		/* Volume serial number (4) */
+#define BS_VolLab32			71		/* Volume label (8) */
+#define BS_FilSysType32		82		/* File system type (1) */
+#define	FSI_LeadSig			0		/* FSI: Leading signature (4) */
+#define	FSI_StrucSig		484		/* FSI: Structure signature (4) */
+#define	FSI_Free_Count		488		/* FSI: Number of free clusters (4) */
+#define	FSI_Nxt_Free		492		/* FSI: Last allocated cluster (4) */
+#define MBR_Table			446		/* MBR: Partition table offset (2) */
+#define	SZ_PTE				16		/* MBR: Size of a partition table entry */
+#define BS_55AA				510		/* Signature word (2) */
+
+#define	DIR_Name			0		/* Short file name (11) */
+#define	DIR_Attr			11		/* Attribute (1) */
+#define	DIR_NTres			12		/* Lower case flag (1) */
+#define DIR_CrtTimeTenth	13		/* Created time sub-second (1) */
+#define	DIR_CrtTime			14		/* Created time (2) */
+#define	DIR_CrtDate			16		/* Created date (2) */
+#define DIR_LstAccDate		18		/* Last accessed date (2) */
+#define	DIR_FstClusHI		20		/* Higher 16-bit of first cluster (2) */
+#define	DIR_WrtTime			22		/* Modified time (2) */
+#define	DIR_WrtDate			24		/* Modified date (2) */
+#define	DIR_FstClusLO		26		/* Lower 16-bit of first cluster (2) */
+#define	DIR_FileSize		28		/* File size (4) */
+#define	LDIR_Ord			0		/* LFN entry order and LLE flag (1) */
+#define	LDIR_Attr			11		/* LFN attribute (1) */
+#define	LDIR_Type			12		/* LFN type (1) */
+#define	LDIR_Chksum			13		/* Checksum of corresponding SFN entry */
+#define	LDIR_FstClusLO		26		/* Must be zero (0) */
+#define	SZ_DIRE				32		/* Size of a directory entry */
+#define	LLEF				0x40	/* Last long entry flag in LDIR_Ord */
+#define	DDEM				0xE5	/* Deleted directory entry mark at DIR_Name[0] */
+#define	RDDEM				0x05	/* Replacement of the character collides with DDEM */
+
+
+
+
+/*--------------------------------------------------------------------------
+
+   Module Private Work Area
+
+---------------------------------------------------------------------------*/
+
+/* Remark: Uninitialized variables with static duration are guaranteed
+/  zero/null at start-up. If not, either the linker or start-up routine
+/  being used is not compliance with ANSI-C standard.
+*/
+
+#if FF_VOLUMES < 1 || FF_VOLUMES > 9
+#error Wrong FF_VOLUMES setting
+#endif
+static FATFS *FatFs[FF_VOLUMES];	/* Pointer to the file system objects (logical drives) */
+static WORD Fsid;				/* File system mount ID */
+
+#if FF_FS_RPATH && FF_VOLUMES >= 2
+static BYTE CurrVol;			/* Current drive */
+#endif
+
+#if FF_FS_LOCK != 0
+static FILESEM Files[FF_FS_LOCK];	/* Open object lock semaphores */
+#endif
+
+#if FF_USE_LFN == 0			/* Non LFN feature */
+#define	DEFINE_NAMEBUF		BYTE sfn[12]
+#define INIT_BUF(dobj)		(dobj).fn = sfn
+#define	FREE_BUF()
+#else
+#if FF_MAX_LFN < 12 || FF_MAX_LFN > 255
+#error Wrong FF_MAX_LFN setting
+#endif
+#if FF_USE_LFN == 1			/* LFN feature with static working buffer */
+static WCHAR LfnBuf[FF_MAX_LFN + 1];
+#define	DEFINE_NAMEBUF		BYTE sfn[12]
+#define INIT_BUF(dobj)		{ (dobj).fn = sfn; (dobj).lfn = LfnBuf; }
+#define	FREE_BUF()
+#elif FF_USE_LFN == 2 		/* LFN feature with dynamic working buffer on the stack */
+#define	DEFINE_NAMEBUF		BYTE sfn[12]; WCHAR lbuf[FF_MAX_LFN + 1]
+#define INIT_BUF(dobj)		{ (dobj).fn = sfn; (dobj).lfn = lbuf; }
+#define	FREE_BUF()
+#elif FF_USE_LFN == 3 		/* LFN feature with dynamic working buffer on the heap */
+#define	DEFINE_NAMEBUF		BYTE sfn[12]; WCHAR *lfn
+#define INIT_BUF(dobj)		{ lfn = ff_memalloc((FF_MAX_LFN + 1) * 2); if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); (dobj).lfn = lfn; (dobj).fn = sfn; }
+#define	FREE_BUF()			ff_memfree(lfn)
+#else
+#error Wrong FF_USE_LFN setting
+#endif
+#endif
+
+#ifdef _EXCVT
+static const BYTE ExCvt[] = _EXCVT;	/* Upper conversion table for SBCS extended characters */
+#endif
+
+
+
+
+
+
+/*--------------------------------------------------------------------------
+
+   Module Private Functions
+
+---------------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------*/
+/* String functions                                                      */
+/*-----------------------------------------------------------------------*/
+
+/* Copy memory to memory */
+static
+void mem_cpy (void* dst, const void* src, UINT cnt) {
+	BYTE *d = (BYTE*)dst;
+	const BYTE *s = (const BYTE*)src;
+
+#if FF_WORD_ACCESS == 1
+	while (cnt >= sizeof (int)) {
+		*(int*)d = *(int*)s;
+		d += sizeof (int); s += sizeof (int);
+		cnt -= sizeof (int);
+	}
+#endif
+	while (cnt--)
+		*d++ = *s++;
+}
+
+/* Fill memory */
+static
+void mem_set (void* dst, int val, UINT cnt) {
+	BYTE *d = (BYTE*)dst;
+
+	while (cnt--)
+		*d++ = (BYTE)val;
+}
+
+/* Compare memory to memory */
+static
+int mem_cmp (const void* dst, const void* src, UINT cnt) {
+	const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)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 FF_FS_REENTRANT
+static
+int 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 (fs &&
+		res != FR_NOT_ENABLED &&
+		res != FR_INVALID_DRIVE &&
+		res != FR_INVALID_OBJECT &&
+		res != FR_TIMEOUT) {
+		ff_rel_grant(fs->sobj);
+	}
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* File lock control functions                                           */
+/*-----------------------------------------------------------------------*/
+#if FF_FS_LOCK != 0
+
+static
+FRESULT chk_lock (	/* Check if the file can be accessed */
+	FATFS_DIR* dp,		/* Directory object pointing the file to be checked */
+	int acc			/* Desired access type (0:Read, 1:Write, 2:Delete/Rename) */
+)
+{
+	UINT i, be;
+
+	/* Search file semaphore table */
+	for (i = be = 0; i < FF_FS_LOCK; i++) {
+		if (Files[i].fs) {	/* Existing entry */
+			if (Files[i].fs == dp->fs &&	 	/* Check if the object matched with an open object */
+				Files[i].clu == dp->sclust &&
+				Files[i].idx == dp->index) break;
+		} else {			/* Blank entry */
+			be = 1;
+		}
+	}
+	if (i == FF_FS_LOCK)	/* The object is not opened */
+		return (be || acc == 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES;	/* Is there a blank entry for new object? */
+
+	/* The object has been opened. Reject any open against writing file and all write mode open */
+	return (acc || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK;
+}
+
+
+static
+int enq_lock (void)	/* Check if an entry is available for a new object */
+{
+	UINT i;
+
+	for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ;
+	return (i == FF_FS_LOCK) ? 0 : 1;
+}
+
+
+static
+UINT inc_lock (	/* Increment object open counter and returns its index (0:Internal error) */
+	FATFS_DIR* dp,	/* Directory object pointing the file to register or increment */
+	int acc		/* Desired access (0:Read, 1:Write, 2:Delete/Rename) */
+)
+{
+	UINT i;
+
+
+	for (i = 0; i < FF_FS_LOCK; i++) {	/* Find the object */
+		if (Files[i].fs == dp->fs &&
+			Files[i].clu == dp->sclust &&
+			Files[i].idx == dp->index) break;
+	}
+
+	if (i == FF_FS_LOCK) {				/* Not opened. Register it as new. */
+		for (i = 0; i < FF_FS_LOCK && Files[i].fs; i++) ;
+		if (i == FF_FS_LOCK) return 0;	/* No free entry to register (int err) */
+		Files[i].fs = dp->fs;
+		Files[i].clu = dp->sclust;
+		Files[i].idx = dp->index;
+		Files[i].ctr = 0;
+	}
+
+	if (acc && Files[i].ctr) return 0;	/* Access violation (int err) */
+
+	Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1;	/* Set semaphore value */
+
+	return i + 1;
+}
+
+
+static
+FRESULT dec_lock (	/* Decrement object open counter */
+	UINT i			/* Semaphore index (1..) */
+)
+{
+	WORD n;
+	FRESULT res;
+
+
+	if (--i < FF_FS_LOCK) {	/* Shift index number origin from 0 */
+		n = Files[i].ctr;
+		if (n == 0x100) n = 0;		/* If write mode open, delete the entry */
+		if (n) n--;					/* Decrement read mode open count */
+		Files[i].ctr = n;
+		if (!n) Files[i].fs = 0;	/* Delete the entry if open count gets zero */
+		res = FR_OK;
+	} else {
+		res = FR_INT_ERR;			/* Invalid index nunber */
+	}
+	return res;
+}
+
+
+static
+void clear_lock (	/* Clear lock entries of the volume */
+	FATFS *fs
+)
+{
+	UINT i;
+
+	for (i = 0; i < FF_FS_LOCK; i++) {
+		if (Files[i].fs == fs) Files[i].fs = 0;
+	}
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Move/Flush disk access window in the file system object               */
+/*-----------------------------------------------------------------------*/
+#if !FF_FS_READONLY
+static
+FRESULT sync_window (	/* FR_OK:succeeded, !=0:error */
+	FATFS* fs		/* File system object */
+)
+{
+	DWORD wsect;
+	UINT nf;
+	FRESULT res = FR_OK;
+
+
+	if (fs->wflag) {	/* Write back the sector if it is dirty */
+		wsect = fs->winsect;	/* Current sector number */
+		if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK) {
+			res = FR_DISK_ERR;
+		} else {
+			fs->wflag = 0;
+			if (wsect - fs->fatbase < fs->fsize) {		/* Is it in the FAT area? */
+				for (nf = fs->n_fats; nf >= 2; nf--) {	/* Reflect the change to all FAT copies */
+					wsect += fs->fsize;
+					disk_write(fs->drv, fs->win, wsect, 1);
+				}
+			}
+		}
+	}
+	return res;
+}
+#endif
+
+
+static
+FRESULT move_window (	/* FR_OK(0):succeeded, !=0:error */
+	FATFS* fs,		/* File system object */
+	DWORD sector	/* Sector number to make appearance in the fs->win[] */
+)
+{
+	FRESULT res = FR_OK;
+
+
+	if (sector != fs->winsect) {	/* Window offset changed? */
+#if !FF_FS_READONLY
+		res = sync_window(fs);		/* Write-back changes */
+#endif
+		if (res == FR_OK) {			/* Fill sector window with new data */
+			if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK) {
+				sector = 0xFFFFFFFF;	/* Invalidate window if data is not reliable */
+				res = FR_DISK_ERR;
+			}
+			fs->winsect = sector;
+		}
+	}
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Synchronize file system and strage device                             */
+/*-----------------------------------------------------------------------*/
+#if !FF_FS_READONLY
+static
+FRESULT sync_fs (	/* FR_OK:succeeded, !=0:error */
+	FATFS* fs		/* File system object */
+)
+{
+	FRESULT res;
+
+
+	res = sync_window(fs);
+	if (res == FR_OK) {
+		/* Update FSInfo sector if needed */
+		if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) {
+			/* Create FSInfo structure */
+			mem_set(fs->win, 0, SS(fs));
+			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);
+			/* Write it into the FSInfo sector */
+			fs->winsect = fs->volbase + 1;
+			disk_write(fs->drv, fs->win, fs->winsect, 1);
+			fs->fsi_flag = 0;
+		}
+		/* Make sure that no pending write process in the physical drive */
+		if (disk_ioctl(fs->drv, CTRL_SYNC, 0) != RES_OK)
+			res = FR_DISK_ERR;
+	}
+
+	return res;
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get sector# from cluster#                                             */
+/*-----------------------------------------------------------------------*/
+/* Hidden API for hacks and disk tools */
+
+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->n_fatent - 2) return 0;		/* Invalid cluster# */
+	return clst * fs->csize + fs->database;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT access - Read value of a FAT entry                                */
+/*-----------------------------------------------------------------------*/
+/* Hidden API for hacks and disk tools */
+
+DWORD get_fat (	/* 0xFFFFFFFF:Disk error, 1:Internal error, 2..0x0FFFFFFF:Cluster status */
+	FATFS* fs,	/* File system object */
+	DWORD clst	/* FAT index number (cluster number) to get the value */
+)
+{
+	UINT wc, bc;
+	BYTE *p;
+	DWORD val;
+
+
+	if (clst < 2 || clst >= fs->n_fatent) {	/* Check if in valid range */
+		val = 1;	/* Internal error */
+
+	} else {
+		val = 0xFFFFFFFF;	/* Default value falls on disk error */
+
+		switch (fs->fs_type) {
+		case FS_FAT12 :
+			bc = (UINT)clst; bc += bc / 2;
+			if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break;
+			wc = fs->win[bc++ % SS(fs)];
+			if (move_window(fs, fs->fatbase + (bc / SS(fs))) != FR_OK) break;
+			wc |= fs->win[bc % SS(fs)] << 8;
+			val = clst & 1 ? wc >> 4 : (wc & 0xFFF);
+			break;
+
+		case FS_FAT16 :
+			if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))) != FR_OK) break;
+			p = &fs->win[clst * 2 % SS(fs)];
+			val = LD_WORD(p);
+			break;
+
+		case FS_FAT32 :
+			if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))) != FR_OK) break;
+			p = &fs->win[clst * 4 % SS(fs)];
+			val = LD_DWORD(p) & 0x0FFFFFFF;
+			break;
+
+		default:
+			val = 1;	/* Internal error */
+		}
+	}
+
+	return val;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT access - Change value of a FAT entry                              */
+/*-----------------------------------------------------------------------*/
+/* Hidden API for hacks and disk tools */
+
+#if !FF_FS_READONLY
+FRESULT put_fat (	/* FR_OK(0):succeeded, !=0:error */
+	FATFS* fs,		/* File system object */
+	DWORD clst,		/* FAT index number (cluster number) to be changed */
+	DWORD val		/* New value to be set to the entry */
+)
+{
+	UINT bc;
+	BYTE *p;
+	FRESULT res;
+
+
+	if (clst < 2 || clst >= fs->n_fatent) {	/* Check if in valid range */
+		res = FR_INT_ERR;
+
+	} else {
+		switch (fs->fs_type) {
+		case FS_FAT12 :
+			bc = (UINT)clst; bc += bc / 2;
+			res = move_window(fs, fs->fatbase + (bc / SS(fs)));
+			if (res != FR_OK) break;
+			p = &fs->win[bc++ % SS(fs)];
+			*p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
+			fs->wflag = 1;
+			res = move_window(fs, fs->fatbase + (bc / SS(fs)));
+			if (res != FR_OK) break;
+			p = &fs->win[bc % SS(fs)];
+			*p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
+			fs->wflag = 1;
+			break;
+
+		case FS_FAT16 :
+			res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
+			if (res != FR_OK) break;
+			p = &fs->win[clst * 2 % SS(fs)];
+			ST_WORD(p, (WORD)val);
+			fs->wflag = 1;
+			break;
+
+		case FS_FAT32 :
+			res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
+			if (res != FR_OK) break;
+			p = &fs->win[clst * 4 % SS(fs)];
+			val |= LD_DWORD(p) & 0xF0000000;
+			ST_DWORD(p, val);
+			fs->wflag = 1;
+			break;
+
+		default :
+			res = FR_INT_ERR;
+		}
+	}
+
+	return res;
+}
+#endif /* !FF_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT handling - Remove a cluster chain                                 */
+/*-----------------------------------------------------------------------*/
+#if !FF_FS_READONLY
+static
+FRESULT remove_chain (	/* FR_OK(0):succeeded, !=0:error */
+	FATFS* fs,			/* File system object */
+	DWORD clst			/* Cluster# to remove a chain from */
+)
+{
+	FRESULT res;
+	DWORD nxt;
+#if FF_USE_TRIM
+	DWORD scl = clst, ecl = clst, rt[2];
+#endif
+
+	if (clst < 2 || clst >= fs->n_fatent) {	/* Check if in valid range */
+		res = FR_INT_ERR;
+
+	} else {
+		res = FR_OK;
+		while (clst < fs->n_fatent) {			/* Not a last link? */
+			nxt = get_fat(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_fat(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;
+			}
+#if FF_USE_TRIM
+			if (ecl + 1 == nxt) {	/* Is next cluster contiguous? */
+				ecl = nxt;
+			} else {				/* End of contiguous clusters */ 
+				rt[0] = clust2sect(fs, scl);					/* Start sector */
+				rt[1] = clust2sect(fs, ecl) + fs->csize - 1;	/* End sector */
+				disk_ioctl(fs->drv, CTRL_TRIM, rt);				/* Erase the block */
+				scl = ecl = nxt;
+			}
+#endif
+			clst = nxt;	/* Next cluster */
+		}
+	}
+
+	return res;
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT handling - Stretch or Create a cluster chain                      */
+/*-----------------------------------------------------------------------*/
+#if !FF_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:Create a new chain */
+)
+{
+	DWORD cs, ncl, scl;
+	FRESULT res;
+
+
+	if (clst == 0) {		/* Create a new chain */
+		scl = fs->last_clust;			/* Get suggested start point */
+		if (!scl || scl >= fs->n_fatent) scl = 1;
+	}
+	else {					/* Stretch the current chain */
+		cs = get_fat(fs, clst);			/* Check the cluster status */
+		if (cs < 2) return 1;			/* Invalid value */
+		if (cs == 0xFFFFFFFF) return cs;	/* A disk error occurred */
+		if (cs < fs->n_fatent) return cs;	/* It is already followed by next cluster */
+		scl = clst;
+	}
+
+	ncl = scl;				/* Start cluster */
+	for (;;) {
+		ncl++;							/* Next cluster */
+		if (ncl >= fs->n_fatent) {		/* Check wrap around */
+			ncl = 2;
+			if (ncl > scl) return 0;	/* No free cluster */
+		}
+		cs = get_fat(fs, ncl);			/* Get the cluster status */
+		if (cs == 0) break;				/* Found a free cluster */
+		if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */
+			return cs;
+		if (ncl == scl) return 0;		/* No free cluster */
+	}
+
+	res = put_fat(fs, ncl, 0x0FFFFFFF);	/* Mark the new cluster "last link" */
+	if (res == FR_OK && clst != 0) {
+		res = put_fat(fs, clst, ncl);	/* Link it to the previous one if needed */
+	}
+	if (res == FR_OK) {
+		fs->last_clust = ncl;			/* Update FSINFO */
+		if (fs->free_clust != 0xFFFFFFFF) {
+			fs->free_clust--;
+			fs->fsi_flag |= 1;
+		}
+	} else {
+		ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1;
+	}
+
+	return ncl;		/* Return new cluster number or error code */
+}
+#endif /* !FF_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* FAT handling - Convert offset into cluster with link map table        */
+/*-----------------------------------------------------------------------*/
+
+#if FF_USE_FASTSEEK
+static
+DWORD clmt_clust (	/* <2:Error, >=2:Cluster number */
+	FIL* fp,		/* Pointer to the file object */
+	DWORD ofs		/* File offset to be converted to cluster# */
+)
+{
+	DWORD cl, ncl, *tbl;
+
+
+	tbl = fp->cltbl + 1;	/* Top of CLMT */
+	cl = ofs / SS(fp->fs) / fp->fs->csize;	/* Cluster order from top of the file */
+	for (;;) {
+		ncl = *tbl++;			/* Number of cluters in the fragment */
+		if (!ncl) return 0;		/* End of table? (error) */
+		if (cl < ncl) break;	/* In this fragment? */
+		cl -= ncl; tbl++;		/* Next fragment */
+	}
+	return cl + *tbl;	/* Return the cluster number */
+}
+#endif	/* FF_USE_FASTSEEK */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Set directory index                              */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_sdi (	/* FR_OK(0):succeeded, !=0:error */
+	FATFS_DIR* dp,		/* Pointer to directory object */
+	UINT idx		/* Index of directory table */
+)
+{
+	DWORD clst, sect;
+	UINT ic;
+
+
+	dp->index = (WORD)idx;	/* Current index */
+	clst = dp->sclust;		/* Table start cluster (0:root) */
+	if (clst == 1 || clst >= dp->fs->n_fatent)	/* Check start cluster range */
+		return FR_INT_ERR;
+	if (!clst && dp->fs->fs_type == FS_FAT32)	/* Replace cluster# 0 with root cluster# if in FAT32 */
+		clst = dp->fs->dirbase;
+
+	if (clst == 0) {	/* Static table (root-directory in FAT12/16) */
+		if (idx >= dp->fs->n_rootdir)	/* Is index out of range? */
+			return FR_INT_ERR;
+		sect = dp->fs->dirbase;
+	}
+	else {				/* Dynamic table (root-directory in FAT32 or sub-directory) */
+		ic = SS(dp->fs) / SZ_DIRE * dp->fs->csize;	/* Entries per cluster */
+		while (idx >= ic) {	/* Follow cluster chain */
+			clst = get_fat(dp->fs, clst);				/* Get next cluster */
+			if (clst == 0xFFFFFFFF) return FR_DISK_ERR;	/* Disk error */
+			if (clst < 2 || clst >= dp->fs->n_fatent)	/* Reached to end of table or internal error */
+				return FR_INT_ERR;
+			idx -= ic;
+		}
+		sect = clust2sect(dp->fs, clst);
+	}
+	dp->clust = clst;	/* Current cluster# */
+	if (!sect) return FR_INT_ERR;
+	dp->sect = sect + idx / (SS(dp->fs) / SZ_DIRE);					/* Sector# of the directory entry */
+	dp->dir = dp->fs->win + (idx % (SS(dp->fs) / SZ_DIRE)) * SZ_DIRE;	/* Ptr to the entry in the sector */
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Move directory table index next                  */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_next (	/* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */
+	FATFS_DIR* dp,		/* Pointer to the directory object */
+	int stretch		/* 0: Do not stretch table, 1: Stretch table if needed */
+)
+{
+	DWORD clst;
+	UINT i;
+#if !FF_FS_READONLY
+	UINT c;
+#endif
+
+
+	i = dp->index + 1;
+	if (!(i & 0xFFFF) || !dp->sect)	/* Report EOT when index has reached 65535 */
+		return FR_NO_FILE;
+
+	if (!(i % (SS(dp->fs) / SZ_DIRE))) {	/* Sector changed? */
+		dp->sect++;					/* Next sector */
+
+		if (!dp->clust) {		/* Static table */
+			if (i >= dp->fs->n_rootdir)	/* Report EOT if it reached end of static table */
+				return FR_NO_FILE;
+		}
+		else {					/* Dynamic table */
+			if (((i / (SS(dp->fs) / SZ_DIRE)) & (dp->fs->csize - 1)) == 0) {	/* Cluster changed? */
+				clst = get_fat(dp->fs, dp->clust);				/* Get next cluster */
+				if (clst <= 1) return FR_INT_ERR;
+				if (clst == 0xFFFFFFFF) return FR_DISK_ERR;
+				if (clst >= dp->fs->n_fatent) {					/* If it reached end of dynamic table, */
+#if !FF_FS_READONLY
+					if (!stretch) return FR_NO_FILE;			/* If do not stretch, report EOT */
+					clst = create_chain(dp->fs, dp->clust);		/* Stretch 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 stretched table */
+					if (sync_window(dp->fs)) return FR_DISK_ERR;/* Flush disk access window */
+					mem_set(dp->fs->win, 0, SS(dp->fs));		/* Clear window buffer */
+					dp->fs->winsect = clust2sect(dp->fs, clst);	/* Cluster start sector */
+					for (c = 0; c < dp->fs->csize; c++) {		/* Fill the new cluster with 0 */
+						dp->fs->wflag = 1;
+						if (sync_window(dp->fs)) return FR_DISK_ERR;
+						dp->fs->winsect++;
+					}
+					dp->fs->winsect -= c;						/* Rewind window offset */
+#else
+					if (!stretch) return FR_NO_FILE;			/* If do not stretch, report EOT (this is to suppress warning) */
+					return FR_NO_FILE;							/* Report EOT */
+#endif
+				}
+				dp->clust = clst;				/* Initialize data for new cluster */
+				dp->sect = clust2sect(dp->fs, clst);
+			}
+		}
+	}
+
+	dp->index = (WORD)i;	/* Current index */
+	dp->dir = dp->fs->win + (i % (SS(dp->fs) / SZ_DIRE)) * SZ_DIRE;	/* Current entry in the window */
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Reserve directory entry                          */
+/*-----------------------------------------------------------------------*/
+
+#if !FF_FS_READONLY
+static
+FRESULT dir_alloc (	/* FR_OK(0):succeeded, !=0:error */
+	FATFS_DIR* dp,		/* Pointer to the directory object */
+	UINT nent		/* Number of contiguous entries to allocate (1-21) */
+)
+{
+	FRESULT res;
+	UINT n;
+
+
+	res = dir_sdi(dp, 0);
+	if (res == FR_OK) {
+		n = 0;
+		do {
+			res = move_window(dp->fs, dp->sect);
+			if (res != FR_OK) break;
+			if (dp->dir[0] == DDEM || dp->dir[0] == 0) {	/* Is it a free entry? */
+				if (++n == nent) break;	/* A block of contiguous free entries is found */
+			} else {
+				n = 0;					/* Not a blank entry. Restart to search */
+			}
+			res = dir_next(dp, 1);		/* Next entry with table stretch enabled */
+		} while (res == FR_OK);
+	}
+	if (res == FR_NO_FILE) res = FR_DENIED;	/* No directory entry to allocate */
+	return res;
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Load/Store start cluster number                  */
+/*-----------------------------------------------------------------------*/
+
+static
+DWORD ld_clust (	/* Returns the top cluster value of the SFN entry */
+	FATFS* fs,		/* Pointer to the fs object */
+	const BYTE* dir	/* Pointer to the SFN entry */
+)
+{
+	DWORD cl;
+
+	cl = LD_WORD(dir + DIR_FstClusLO);
+	if (fs->fs_type == FS_FAT32)
+		cl |= (DWORD)LD_WORD(dir + DIR_FstClusHI) << 16;
+
+	return cl;
+}
+
+
+#if !FF_FS_READONLY
+static
+void st_clust (
+	BYTE* dir,	/* Pointer to the SFN entry */
+	DWORD cl	/* Value to be set */
+)
+{
+	ST_WORD(dir + DIR_FstClusLO, cl);
+	ST_WORD(dir + DIR_FstClusHI, cl >> 16);
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry   */
+/*-----------------------------------------------------------------------*/
+#if FF_USE_LFN
+static
+const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30};	/* Offset of LFN characters in the directory entry */
+
+
+static
+int cmp_lfn (			/* 1:matched, 0:not matched */
+	WCHAR* lfnbuf,		/* Pointer to the LFN working buffer to be compared */
+	BYTE* dir			/* Pointer to the directory entry containing the part of LFN */
+)
+{
+	UINT i, s;
+	WCHAR wc, uc;
+
+
+	if (LD_WORD(dir + LDIR_FstClusLO) != 0) return 0;	/* Check LDIR_FstClusLO */
+
+	i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13;	/* Offset in the LFN buffer */
+
+	for (wc = 1, s = 0; s < 13; s++) {		/* Process all characters in the entry */
+		uc = LD_WORD(dir + LfnOfs[s]);		/* Pick an LFN character */
+		if (wc) {
+			if (i >= FF_MAX_LFN || ff_wtoupper(uc) != ff_wtoupper(lfnbuf[i++]))	/* Compare it */
+				return 0;					/* Not matched */
+			wc = uc;
+		} else {
+			if (uc != 0xFFFF) return 0;		/* Check filler */
+		}
+	}
+
+	if ((dir[LDIR_Ord] & LLEF) && wc && lfnbuf[i])	/* Last segment matched but different length */
+		return 0;
+
+	return 1;		/* The part of LFN matched */
+}
+
+
+
+static
+int pick_lfn (			/* 1:succeeded, 0:buffer overflow or invalid LFN entry */
+	WCHAR* lfnbuf,		/* Pointer to the LFN working buffer */
+	BYTE* dir			/* Pointer to the LFN entry */
+)
+{
+	UINT i, s;
+	WCHAR wc, uc;
+
+
+	if (LD_WORD(dir + LDIR_FstClusLO) != 0) return 0;	/* Check LDIR_FstClusLO */
+
+	i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13;	/* Offset in the LFN buffer */
+
+	for (wc = 1, s = 0; s < 13; s++) {		/* Process all characters in the entry */
+		uc = LD_WORD(dir + LfnOfs[s]);		/* Pick an LFN character */
+		if (wc) {
+			if (i >= FF_MAX_LFN) return 0;	/* Buffer overflow? */
+			lfnbuf[i++] = wc = uc;			/* Store it */
+		} else {
+			if (uc != 0xFFFF) return 0;		/* Check filler */
+		}
+	}
+
+	if (dir[LDIR_Ord] & LLEF) {				/* Put terminator if it is the last LFN part */
+		if (i >= FF_MAX_LFN) return 0;		/* Buffer overflow? */
+		lfnbuf[i] = 0;
+	}
+
+	return 1;		/* The part of LFN is valid */
+}
+
+
+#if !FF_FS_READONLY
+static
+void fit_lfn (
+	const WCHAR* lfnbuf,	/* Pointer to the LFN working buffer */
+	BYTE* dir,				/* Pointer to the LFN entry to be processed */
+	BYTE ord,				/* LFN order (1-20) */
+	BYTE sum				/* Checksum of the corresponding SFN */
+)
+{
+	UINT i, s;
+	WCHAR wc;
+
+
+	dir[LDIR_Chksum] = sum;			/* Set checksum */
+	dir[LDIR_Attr] = AM_LFN;		/* Set attribute. LFN entry */
+	dir[LDIR_Type] = 0;
+	ST_WORD(dir + LDIR_FstClusLO, 0);
+
+	i = (ord - 1) * 13;				/* Get offset in the LFN working buffer */
+	s = wc = 0;
+	do {
+		if (wc != 0xFFFF) wc = lfnbuf[i++];	/* Get an effective character */
+		ST_WORD(dir+LfnOfs[s], wc);	/* Put it */
+		if (!wc) wc = 0xFFFF;		/* Padding characters following last character */
+	} while (++s < 13);
+	if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLEF;	/* Bottom LFN part is the start of LFN sequence */
+	dir[LDIR_Ord] = ord;			/* Set the LFN order */
+}
+
+#endif
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Create numbered name                                                  */
+/*-----------------------------------------------------------------------*/
+#if FF_USE_LFN
+static
+void gen_numname (
+	BYTE* dst,			/* Pointer to the buffer to store numbered SFN */
+	const BYTE* src,	/* Pointer to SFN */
+	const WCHAR* lfn,	/* Pointer to LFN */
+	UINT seq			/* Sequence number */
+)
+{
+	BYTE ns[8], c;
+	UINT i, j;
+	WCHAR wc;
+	DWORD sr;
+
+
+	mem_cpy(dst, src, 11);
+
+	if (seq > 5) {	/* On many collisions, generate a hash number instead of sequential number */
+		sr = seq;
+		while (*lfn) {	/* Create a CRC */
+			wc = *lfn++;
+			for (i = 0; i < 16; i++) {
+				sr = (sr << 1) + (wc & 1);
+				wc >>= 1;
+				if (sr & 0x10000) sr ^= 0x11021;
+			}
+		}
+		seq = (UINT)sr;
+	}
+
+	/* itoa (hexdecimal) */
+	i = 7;
+	do {
+		c = (seq % 16) + '0';
+		if (c > '9') c += 7;
+		ns[i--] = c;
+		seq /= 16;
+	} while (seq);
+	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 checksum of an SFN entry                                    */
+/*-----------------------------------------------------------------------*/
+#if FF_USE_LFN
+static
+BYTE sum_sfn (
+	const BYTE* dir		/* Pointer to the SFN entry */
+)
+{
+	BYTE sum = 0;
+	UINT n = 11;
+
+	do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n);
+	return sum;
+}
+#endif
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Directory handling - Find an object in the directory                  */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT dir_find (	/* FR_OK(0):succeeded, !=0:error */
+	FATFS_DIR* dp			/* Pointer to the directory object linked to the file name */
+)
+{
+	FRESULT res;
+	BYTE c, *dir;
+#if FF_USE_LFN
+	BYTE a, ord, sum;
+#endif
+
+	res = dir_sdi(dp, 0);			/* Rewind directory object */
+	if (res != FR_OK) return res;
+
+#if FF_USE_LFN
+	ord = sum = 0xFF; dp->lfn_idx = 0xFFFF;	/* Reset LFN sequence */
+#endif
+	do {
+		res = move_window(dp->fs, dp->sect);
+		if (res != FR_OK) break;
+		dir = dp->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 */
+#if FF_USE_LFN	/* LFN configuration */
+		a = dir[DIR_Attr] & AM_MASK;
+		if (c == DDEM || ((a & AM_VOL) && a != AM_LFN)) {	/* An entry without valid data */
+			ord = 0xFF; dp->lfn_idx = 0xFFFF;	/* Reset LFN sequence */
+		} else {
+			if (a == AM_LFN) {			/* An LFN entry is found */
+				if (dp->lfn) {
+					if (c & LLEF) {		/* Is it start of LFN sequence? */
+						sum = dir[LDIR_Chksum];
+						c &= ~LLEF; ord = c;	/* LFN start order */
+						dp->lfn_idx = dp->index;	/* Start index of LFN */
+					}
+					/* Check validity of the LFN entry and compare it with given name */
+					ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dp->lfn, dir)) ? ord - 1 : 0xFF;
+				}
+			} else {					/* An SFN entry is found */
+				if (!ord && sum == sum_sfn(dir)) break;	/* LFN matched? */
+				if (!(dp->fn[NSFLAG] & NS_LOSS) && !mem_cmp(dir, dp->fn, 11)) break;	/* SFN matched? */
+				ord = 0xFF; dp->lfn_idx = 0xFFFF;	/* Reset LFN sequence */
+			}
+		}
+#else		/* Non LFN configuration */
+		if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dp->fn, 11)) /* Is it a valid entry? */
+			break;
+#endif
+		res = dir_next(dp, 0);		/* Next entry */
+	} while (res == FR_OK);
+
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read an object from the directory                                     */
+/*-----------------------------------------------------------------------*/
+#if FF_FS_MINIMIZE <= 1 || FF_USE_LABEL || FF_FS_RPATH >= 2
+static
+FRESULT dir_read (
+	FATFS_DIR* dp,		/* Pointer to the directory object */
+	int vol			/* Filtered by 0:file/directory or 1:volume label */
+)
+{
+	FRESULT res;
+	BYTE a, c, *dir;
+#if FF_USE_LFN
+	BYTE ord = 0xFF, sum = 0xFF;
+#endif
+
+	res = FR_NO_FILE;
+	while (dp->sect) {
+		res = move_window(dp->fs, dp->sect);
+		if (res != FR_OK) break;
+		dir = dp->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 FF_USE_LFN	/* LFN configuration */
+		if (c == DDEM || (!FF_FS_RPATH && c == '.') || (int)((a & ~AM_ARC) == AM_VOL) != vol) {	/* An entry without valid data */
+			ord = 0xFF;
+		} else {
+			if (a == AM_LFN) {			/* An LFN entry is found */
+				if (c & LLEF) {			/* Is it start of LFN sequence? */
+					sum = dir[LDIR_Chksum];
+					c &= ~LLEF; ord = c;
+					dp->lfn_idx = dp->index;
+				}
+				/* Check LFN validity and capture it */
+				ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dp->lfn, dir)) ? ord - 1 : 0xFF;
+			} else {					/* An SFN entry is found */
+				if (ord || sum != sum_sfn(dir))	/* Is there a valid LFN? */
+					dp->lfn_idx = 0xFFFF;		/* It has no LFN. */
+				break;
+			}
+		}
+#else		/* Non LFN configuration */
+		if (c != DDEM && (FF_FS_RPATH || c != '.') && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol)	/* Is it a valid entry? */
+			break;
+#endif
+		res = dir_next(dp, 0);				/* Next entry */
+		if (res != FR_OK) break;
+	}
+
+	if (res != FR_OK) dp->sect = 0;
+
+	return res;
+}
+#endif	/* FF_FS_MINIMIZE <= 1 || FF_USE_LABEL || FF_FS_RPATH >= 2 */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Register an object to the directory                                   */
+/*-----------------------------------------------------------------------*/
+#if !FF_FS_READONLY
+static
+FRESULT dir_register (	/* FR_OK:succeeded, FR_DENIED:no free entry or too many SFN collision, FR_DISK_ERR:disk error */
+	FATFS_DIR* dp				/* Target directory with object name to be created */
+)
+{
+	FRESULT res;
+#if FF_USE_LFN	/* LFN configuration */
+	UINT n, nent;
+	BYTE sn[12], *fn, sum;
+	WCHAR *lfn;
+
+
+	fn = dp->fn; lfn = dp->lfn;
+	mem_cpy(sn, fn, 12);
+
+	if (FF_FS_RPATH && (sn[NSFLAG] & NS_DOT))		/* Cannot create dot entry */
+		return FR_INVALID_NAME;
+
+	if (sn[NSFLAG] & NS_LOSS) {			/* When LFN is out of 8.3 format, generate a numbered name */
+		fn[NSFLAG] = 0; dp->lfn = 0;			/* Find only SFN */
+		for (n = 1; n < 100; n++) {
+			gen_numname(fn, sn, lfn, n);	/* Generate a numbered name */
+			res = dir_find(dp);				/* 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[NSFLAG] = sn[NSFLAG]; dp->lfn = lfn;
+	}
+
+	if (sn[NSFLAG] & NS_LFN) {			/* When LFN is to be created, allocate entries for an SFN + LFNs. */
+		for (n = 0; lfn[n]; n++) ;
+		nent = (n + 25) / 13;
+	} else {						/* Otherwise allocate an entry for an SFN  */
+		nent = 1;
+	}
+	res = dir_alloc(dp, nent);		/* Allocate entries */
+
+	if (res == FR_OK && --nent) {	/* Set LFN entry if needed */
+		res = dir_sdi(dp, dp->index - nent);
+		if (res == FR_OK) {
+			sum = sum_sfn(dp->fn);	/* Checksum value of the SFN tied to the LFN */
+			do {					/* Store LFN entries in bottom first */
+				res = move_window(dp->fs, dp->sect);
+				if (res != FR_OK) break;
+				fit_lfn(dp->lfn, dp->dir, (BYTE)nent, sum);
+				dp->fs->wflag = 1;
+				res = dir_next(dp, 0);	/* Next entry */
+			} while (res == FR_OK && --nent);
+		}
+	}
+#else	/* Non LFN configuration */
+	res = dir_alloc(dp, 1);		/* Allocate an entry for SFN */
+#endif
+
+	if (res == FR_OK) {				/* Set SFN entry */
+		res = move_window(dp->fs, dp->sect);
+		if (res == FR_OK) {
+			mem_set(dp->dir, 0, SZ_DIRE);	/* Clean the entry */
+			mem_cpy(dp->dir, dp->fn, 11);	/* Put SFN */
+#if FF_USE_LFN
+			dp->dir[DIR_NTres] = dp->fn[NSFLAG] & (NS_BODY | NS_EXT);	/* Put NT flag */
+#endif
+			dp->fs->wflag = 1;
+		}
+	}
+
+	return res;
+}
+#endif /* !FF_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Remove an object from the directory                                   */
+/*-----------------------------------------------------------------------*/
+#if !FF_FS_READONLY && !FF_FS_MINIMIZE
+static
+FRESULT dir_remove (	/* FR_OK:Succeeded, FR_DISK_ERR:A disk error */
+	FATFS_DIR* dp				/* Directory object pointing the entry to be removed */
+)
+{
+	FRESULT res;
+#if FF_USE_LFN	/* LFN configuration */
+	UINT i;
+
+	i = dp->index;	/* SFN index */
+	res = dir_sdi(dp, (dp->lfn_idx == 0xFFFF) ? i : dp->lfn_idx);	/* Goto the SFN or top of the LFN entries */
+	if (res == FR_OK) {
+		do {
+			res = move_window(dp->fs, dp->sect);
+			if (res != FR_OK) break;
+			mem_set(dp->dir, 0, SZ_DIRE);	/* Clear and mark the entry "deleted" */
+			*dp->dir = DDEM;
+			dp->fs->wflag = 1;
+			if (dp->index >= i) break;	/* When reached SFN, all entries of the object has been deleted. */
+			res = dir_next(dp, 0);		/* Next entry */
+		} while (res == FR_OK);
+		if (res == FR_NO_FILE) res = FR_INT_ERR;
+	}
+
+#else			/* Non LFN configuration */
+	res = dir_sdi(dp, dp->index);
+	if (res == FR_OK) {
+		res = move_window(dp->fs, dp->sect);
+		if (res == FR_OK) {
+			mem_set(dp->dir, 0, SZ_DIRE);	/* Clear and mark the entry "deleted" */
+			*dp->dir = DDEM;
+			dp->fs->wflag = 1;
+		}
+	}
+#endif
+
+	return res;
+}
+#endif /* !FF_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get file information from directory entry                             */
+/*-----------------------------------------------------------------------*/
+#if FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2
+static
+void get_fileinfo (		/* No return code */
+	FATFS_DIR* dp,			/* Pointer to the directory object */
+	FILINFO* fno	 	/* Pointer to the file information to be filled */
+)
+{
+	UINT i;
+	TCHAR *p, c;
+	BYTE *dir;
+#if FF_USE_LFN
+	WCHAR w, *lfn;
+#endif
+#if FF_CODE_PAGE == 65001
+	unsigned char utf8_code[6];
+	int code_size;
+#endif
+
+	p = fno->fname;
+	if (dp->sect) {		/* Get SFN */
+		dir = dp->dir;
+		i = 0;
+		while (i < 11) {		/* Copy name body and extension */
+			c = (TCHAR)dir[i++];
+			if (c == ' ') continue;				/* Skip padding spaces */
+			if (c == RDDEM) c = (TCHAR)DDEM;	/* Restore replaced DDEM character */
+			if (i == 9) *p++ = '.';				/* Insert a . if extension is exist */
+#if FF_USE_LFN
+			if (IsUpper(c) && (dir[DIR_NTres] & (i >= 9 ? NS_EXT : NS_BODY)))
+				c += 0x20;			/* To lower */
+#if FF_LFN_UNICODE
+			if (IsDBCS1(c) && i != 8 && i != 11 && IsDBCS2(dir[i]))
+				c = c << 8 | dir[i++];
+			c = ff_convert(c, 1);	/* OEM -> Unicode */
+			if (!c) c = '?';
+#endif
+#endif
+			*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;		/* Terminate SFN string by a \0 */
+
+#if FF_USE_LFN
+	if (fno->lfname) {
+		i = 0; p = fno->lfname;
+		if (dp->sect && fno->lfsize && dp->lfn_idx != 0xFFFF) {	/* Get LFN if available */
+			lfn = dp->lfn;
+			while ((w = *lfn++) != 0) {		/* Get an LFN character */
+#if !FF_LFN_UNICODE
+#if FF_CODE_PAGE == 65001
+				Utf16_to_Utf8(utf8_code, &code_size, w);
+				for (int j = 0; j < code_size - 1; j++) {
+					p[i++] = utf8_code[j];
+				}
+				w = utf8_code[code_size - 1];
+#else
+				w = ff_convert(w, 0);		/* Unicode -> OEM */
+				if (!w) { i = 0; break; }	/* No LFN if it could not be converted */
+				if (_DF1S && w >= 0x100)	/* Put 1st byte if it is a DBC (always false on SBCS cfg) */
+					p[i++] = (TCHAR)(w >> 8);
+#endif
+#endif
+				if (i >= fno->lfsize - 1) { i = 0; break; }	/* No LFN if buffer overflow */
+				p[i++] = (TCHAR)w;
+			}
+		}
+		p[i] = 0;	/* Terminate LFN string by a \0 */
+	}
+#endif
+}
+#endif /* FF_FS_MINIMIZE <= 1 || FF_FS_RPATH >= 2 */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Pattern matching                                                      */
+/*-----------------------------------------------------------------------*/
+#if FF_USE_FIND && FF_FS_MINIMIZE <= 1
+static
+WCHAR get_achar (		/* Get a character and advances ptr 1 or 2 */
+	const TCHAR** ptr	/* Pointer to pointer to the SBCS/DBCS/Unicode string */
+)
+{
+	WCHAR chr;
+
+#if !FF_LFN_UNICODE
+#if FF_CODE_PAGE == 65001
+	int code_size;
+	chr = Utf8_to_Utf16(*ptr, &code_size);
+	(*ptr) += code_size;
+#else
+	chr = (BYTE)*(*ptr)++;					/* Get a byte */
+	if (IsLower(chr)) chr -= 0x20;			/* To upper ASCII char */
+	if (IsDBCS1(chr) && IsDBCS2(**ptr))		/* Get DBC 2nd byte if needed */
+		chr = chr << 8 | (BYTE)*(*ptr)++;
+#endif
+#ifdef _EXCVT
+	if (chr >= 0x80) chr = ExCvt[chr - 0x80];	/* To upper SBCS extended char */
+#endif
+#else
+	chr = ff_wtoupper(*(*ptr)++);			/* Get a word and to upper */
+#endif
+	return chr;
+}
+
+
+static
+int pattern_matching (	/* 0:mismatched, 1:matched */
+	const TCHAR* pat,	/* Matching pattern */
+	const TCHAR* nam,	/* String to be tested */
+	int skip,			/* Number of pre-skip chars (number of ?s) */
+	int inf				/* Infinite search (* specified) */
+)
+{
+	const TCHAR *pp, *np;
+	WCHAR pc, nc;
+	int nm, nx;
+
+
+	while (skip--) {				/* Pre-skip name chars */
+		if (!get_achar(&nam)) return 0;	/* Branch mismatched if less name chars */
+	}
+	if (!*pat && inf) return 1;		/* (short circuit) */
+
+	do {
+		pp = pat; np = nam;			/* Top of pattern and name to match */
+		for (;;) {
+			if (*pp == '?' || *pp == '*') {	/* Wildcard? */
+				nm = nx = 0;
+				do {				/* Analyze the wildcard chars */
+					if (*pp++ == '?') nm++; else nx = 1;
+				} while (*pp == '?' || *pp == '*');
+				if (pattern_matching(pp, np, nm, nx)) return 1;	/* Test new branch (recurs upto number of wildcard blocks in the pattern) */
+				nc = *np; break;	/* Branch mismatched */
+			}
+			pc = get_achar(&pp);	/* Get a pattern char */
+			nc = get_achar(&np);	/* Get a name char */
+			if (pc != nc) break;	/* Branch mismatched? */
+			if (!pc) return 1;		/* Branch matched? (matched at end of both strings) */
+		}
+		get_achar(&nam);			/* nam++ */
+	} while (inf && nc);			/* Retry until end of name if infinite search is specified */
+
+	return 0;
+}
+#endif /* FF_USE_FIND && FF_FS_MINIMIZE <= 1 */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Pick a top segment and create the object name in directory form       */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT create_name (	/* FR_OK: successful, FR_INVALID_NAME: could not create */
+	FATFS_DIR* dp,			/* Pointer to the directory object */
+	const TCHAR** path	/* Pointer to pointer to the segment in the path string */
+)
+{
+#if FF_USE_LFN	/* LFN configuration */
+	BYTE b, cf;
+	WCHAR w, *lfn;
+	UINT i, ni, si, di;
+	const TCHAR *p;
+#if FF_CODE_PAGE == 65001
+	unsigned char utf8_code[6];
+	int code_size;
+#endif
+	/* Create LFN in Unicode */
+	for (p = *path; *p == '/' || *p == '\\'; p++) ;	/* Strip duplicated separator */
+	lfn = dp->lfn;
+	si = di = 0;
+	for (;;) {
+		w = p[si++];					/* Get a character */
+		if (w < ' ' || w == '/' || w == '\\') break;	/* Break on end of segment */
+		if (di >= FF_MAX_LFN)				/* Reject too long name */
+			return FR_INVALID_NAME;
+#if !FF_LFN_UNICODE
+#if FF_CODE_PAGE == 65001
+		w = Utf8_to_Utf16(&p[si - 1], &code_size);
+		si += code_size - 1;
+#else
+		w &= 0xFF;
+		if (IsDBCS1(w)) {				/* Check if it is a DBC 1st byte (always false on SBCS cfg) */
+			b = (BYTE)p[si++];			/* Get 2nd byte */
+			w = (w << 8) + b;			/* Create a DBC */
+			if (!IsDBCS2(b))
+				return FR_INVALID_NAME;	/* Reject invalid sequence */
+		}
+		w = ff_convert(w, 1);			/* Convert ANSI/OEM to Unicode */
+		if (!w) return FR_INVALID_NAME;	/* Reject invalid code */
+#endif
+#endif
+		if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal characters for LFN */
+			return FR_INVALID_NAME;
+		lfn[di++] = w;					/* Store the Unicode character */
+	}
+	*path = &p[si];						/* Return pointer to the next segment */
+	cf = (w < ' ') ? NS_LAST : 0;		/* Set last segment flag if end of path */
+#if FF_FS_RPATH
+	if ((di == 1 && lfn[di - 1] == '.') ||
+		(di == 2 && lfn[di - 1] == '.' && lfn[di - 2] == '.')) {	/* Is this segment a dot entry? */
+		lfn[di] = 0;
+		for (i = 0; i < 11; i++)		/* Create dot name for SFN entry */
+			dp->fn[i] = (i < di) ? '.' : ' ';
+		dp->fn[i] = cf | NS_DOT;		/* This is a dot entry */
+		return FR_OK;
+	}
+#endif
+	while (di) {						/* Snip off trailing spaces and dots if exist */
+		w = lfn[di - 1];
+		if (w != ' ' && w != '.') break;
+		di--;
+	}
+	if (!di) return FR_INVALID_NAME;	/* Reject nul string */
+	lfn[di] = 0;						/* LFN is created */
+
+	/* Create SFN in directory form */
+	mem_set(dp->fn, ' ', 11);
+	for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ;	/* Strip leading spaces and dots */
+	if (si) cf |= NS_LOSS | NS_LFN;
+	while (di && lfn[di - 1] != '.') di--;	/* Find extension (di<=si: no extension) */
+
+	b = i = 0; ni = 8;
+	for (;;) {
+		w = lfn[si++];					/* Get an LFN character */
+		if (!w) break;					/* Break on end of the LFN */
+		if (w == ' ' || (w == '.' && si != di)) {	/* Remove spaces and dots */
+			cf |= NS_LOSS | NS_LFN; continue;
+		}
+
+		if (i >= ni || si == di) {		/* Extension or end of SFN */
+			if (ni == 11) {				/* Long extension */
+				cf |= NS_LOSS | NS_LFN; break;
+			}
+			if (si != di) cf |= NS_LOSS | NS_LFN;	/* Out of 8.3 format */
+			if (si > di) break;			/* No extension */
+			si = di; i = 8; ni = 11;	/* Enter extension section */
+			b <<= 2; continue;
+		}
+
+		if (w >= 0x80) {				/* Non ASCII character */
+#ifdef _EXCVT
+			w = ff_convert(w, 0);		/* Unicode -> OEM code */
+			if (w) w = ExCvt[w - 0x80];	/* Convert extended character to upper (SBCS) */
+#else
+#if FF_CODE_PAGE == 65001
+			Utf16_to_Utf8(utf8_code, &code_size, ff_wtoupper(w));
+#else
+			w = ff_convert(ff_wtoupper(w), 0);	/* Upper converted Unicode -> OEM code */
+#endif
+#endif
+			cf |= NS_LFN;				/* Force create LFN entry */
+		}
+#if FF_CODE_PAGE == 65001
+		else
+			code_size = 1;
+#endif
+
+#if FF_CODE_PAGE == 65001
+		if (code_size > 1) {		/* Is this DBC? (always false at SBCS cfg) */
+			if (i >= ni - 1) {
+				cf |= NS_LOSS | NS_LFN; i = ni; continue;
+			}
+			for (int j = 0; j < code_size; j++) {
+				dp->fn[i++] = (BYTE)utf8_code[j];
+			}
+		}
+		else {						/* SBC */
+			if (!w || chk_chr("+,;=[]", w)) {	/* Replace illegal characters for SFN */
+				w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */
+			}
+			else {
+				if (IsUpper(w)) {		/* ASCII large capital */
+					b |= 2;
+				}
+				else {
+					if (IsLower(w)) {	/* ASCII small capital */
+						b |= 1; w -= 0x20;
+					}
+				}
+			}
+			dp->fn[i++] = (BYTE)w;
+		}
+#else
+		if (_DF1S && w >= 0x100) {		/* Is this DBC? (always false at SBCS cfg) */
+			if (i >= ni - 1) {
+				cf |= NS_LOSS | NS_LFN; i = ni; continue;
+			}
+			dp->fn[i++] = (BYTE)(w >> 8);
+		} else {						/* SBC */
+			if (!w || chk_chr("+,;=[]", w)) {	/* Replace illegal characters for SFN */
+				w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */
+			} else {
+				if (IsUpper(w)) {		/* ASCII large capital */
+					b |= 2;
+				} else {
+					if (IsLower(w)) {	/* ASCII small capital */
+						b |= 1; w -= 0x20;
+					}
+				}
+			}
+		}
+		dp->fn[i++] = (BYTE)w;
+#endif
+	}
+
+	if (dp->fn[0] == DDEM) dp->fn[0] = RDDEM;	/* If the first character collides with DDEM, replace it with RDDEM */
+
+	if (ni == 8) b <<= 2;
+	if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03)	/* Create LFN entry when there are composite capitals */
+		cf |= NS_LFN;
+	if (!(cf & NS_LFN)) {						/* When LFN is in 8.3 format without extended character, NT flags are created */
+		if ((b & 0x03) == 0x01) cf |= NS_EXT;	/* NT flag (Extension has only small capital) */
+		if ((b & 0x0C) == 0x04) cf |= NS_BODY;	/* NT flag (Filename has only small capital) */
+	}
+
+	dp->fn[NSFLAG] = cf;	/* SFN is created */
+
+	return FR_OK;
+
+
+#else	/* Non-LFN configuration */
+	BYTE b, c, d, *sfn;
+	UINT ni, si, i;
+	const char *p;
+
+	/* Create file name in directory form */
+	for (p = *path; *p == '/' || *p == '\\'; p++) ;	/* Skip duplicated separator */
+	sfn = dp->fn;
+	mem_set(sfn, ' ', 11);
+	si = i = b = 0; ni = 8;
+#if FF_FS_RPATH
+	if (p[si] == '.') { /* Is this a dot entry? */
+		for (;;) {
+			c = (BYTE)p[si++];
+			if (c != '.' || si >= 3) break;
+			sfn[i++] = c;
+		}
+		if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME;
+		*path = &p[si];									/* Return pointer to the next segment */
+		sfn[NSFLAG] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT;	/* Set last segment flag if end of path */
+		return FR_OK;
+	}
+#endif
+	for (;;) {
+		c = (BYTE)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) {				/* Extended character? */
+			b |= 3;						/* Eliminate NT flag */
+#ifdef _EXCVT
+			c = ExCvt[c - 0x80];		/* To upper extended characters (SBCS cfg) */
+#else
+#if !_DF1S
+			return FR_INVALID_NAME;		/* Reject extended characters (ASCII cfg) */
+#endif
+#endif
+		}
+		if (IsDBCS1(c)) {				/* Check if it is a DBC 1st byte (always false at SBCS cfg.) */
+			d = (BYTE)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 {						/* SBC */
+			if (chk_chr("\"*+,:;<=>\?[]|\x7F", c))	/* Reject illegal chrs for SFN */
+				return FR_INVALID_NAME;
+			if (IsUpper(c)) {			/* ASCII large capital? */
+				b |= 2;
+			} else {
+				if (IsLower(c)) {		/* ASCII small capital? */
+					b |= 1; c -= 0x20;
+				}
+			}
+			sfn[i++] = c;
+		}
+	}
+	*path = &p[si];						/* Return pointer to the next segment */
+	c = (c <= ' ') ? NS_LAST : 0;		/* Set last segment flag if end of path */
+
+	if (!i) return FR_INVALID_NAME;		/* Reject nul string */
+	if (sfn[0] == DDEM) sfn[0] = RDDEM;	/* When first character collides with DDEM, replace it with RDDEM */
+
+	if (ni == 8) b <<= 2;
+	if ((b & 0x03) == 0x01) c |= NS_EXT;	/* NT flag (Name extension has only small capital) */
+	if ((b & 0x0C) == 0x04) c |= NS_BODY;	/* NT flag (Name body has only small capital) */
+
+	sfn[NSFLAG] = c;		/* Store NT flag, File name is created */
+
+	return FR_OK;
+#endif
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Follow a file path                                                    */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT follow_path (	/* FR_OK(0): successful, !=0: error code */
+	FATFS_DIR* dp,			/* Directory object to return last directory and found object */
+	const TCHAR* path	/* Full-path string to find a file or directory */
+)
+{
+	FRESULT res;
+	BYTE *dir, ns;
+
+
+#if FF_FS_RPATH
+	if (*path == '/' || *path == '\\') {	/* There is a heading separator */
+		path++;	dp->sclust = 0;				/* Strip it and start from the root directory */
+	} else {								/* No heading separator */
+		dp->sclust = dp->fs->cdir;			/* Start from the current directory */
+	}
+#else
+	if (*path == '/' || *path == '\\')		/* Strip heading separator if exist */
+		path++;
+	dp->sclust = 0;							/* Always start from the root directory */
+#endif
+
+	if ((UINT)*path < ' ') {				/* Null path name is the origin directory itself */
+		res = dir_sdi(dp, 0);
+		dp->dir = 0;
+	} else {								/* Follow path */
+		for (;;) {
+			res = create_name(dp, &path);	/* Get a segment name of the path */
+			if (res != FR_OK) break;
+			res = dir_find(dp);				/* Find an object with the sagment name */
+			ns = dp->fn[NSFLAG];
+			if (res != FR_OK) {				/* Failed to find the object */
+				if (res == FR_NO_FILE) {	/* Object is not found */
+					if (FF_FS_RPATH && (ns & NS_DOT)) {	/* If dot entry is not exist, */
+						dp->sclust = 0; dp->dir = 0;	/* it is the root directory and stay there */
+						if (!(ns & NS_LAST)) continue;	/* Continue to follow if not last segment */
+						res = FR_OK;					/* Ended at the root directroy. Function completed. */
+					} else {							/* Could not find the object */
+						if (!(ns & NS_LAST)) res = FR_NO_PATH;	/* Adjust error code if not last segment */
+					}
+				}
+				break;
+			}
+			if (ns & NS_LAST) break;			/* Last segment matched. Function completed. */
+			dir = dp->dir;						/* Follow the sub-directory */
+			if (!(dir[DIR_Attr] & AM_DIR)) {	/* It is not a sub-directory and cannot follow */
+				res = FR_NO_PATH; break;
+			}
+			dp->sclust = ld_clust(dp->fs, dir);
+		}
+	}
+
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get logical drive number from path name                               */
+/*-----------------------------------------------------------------------*/
+
+static
+int get_ldnumber (		/* Returns logical drive number (-1:invalid drive) */
+	const TCHAR** path	/* Pointer to pointer to the path name */
+)
+{
+	const TCHAR *tp, *tt;
+	UINT i;
+	int vol = -1;
+#if FF_STR_VOLUME_ID		/* Find string drive id */
+	static const char* const str[] = {FF_VOLUME_STRS};
+	const char *sp;
+	char c;
+	TCHAR tc;
+#endif
+
+
+	if (*path) {	/* If the pointer is not a null */
+		for (tt = *path; (UINT)*tt >= (FF_USE_LFN ? ' ' : '!') && *tt != ':'; tt++) ;	/* Find ':' in the path */
+		if (*tt == ':') {	/* If a ':' is exist in the path name */
+			tp = *path;
+			i = *tp++ - '0'; 
+			if (i < 10 && tp == tt) {	/* Is there a numeric drive id? */
+				if (i < FF_VOLUMES) {	/* If a drive id is found, get the value and strip it */
+					vol = (int)i;
+					*path = ++tt;
+				}
+			}
+#if FF_STR_VOLUME_ID
+			 else {	/* No numeric drive number, find string drive id */
+				i = 0; tt++;
+				do {
+					sp = str[i]; tp = *path;
+					do {	/* Compare a string drive id with path name */
+						c = *sp++; tc = *tp++;
+						if (IsLower(tc)) tc -= 0x20;
+					} while (c && (TCHAR)c == tc);
+				} while ((c || tp != tt) && ++i < FF_VOLUMES);	/* Repeat for each id until pattern match */
+				if (i < FF_VOLUMES) {	/* If a drive id is found, get the value and strip it */
+					vol = (int)i;
+					*path = tt;
+				}
+			}
+#endif
+			return vol;
+		}
+#if FF_FS_RPATH && FF_VOLUMES >= 2
+		vol = CurrVol;	/* Current drive */
+#else
+		vol = 0;		/* Drive 0 */
+#endif
+	}
+	return vol;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Load a sector and check if it is an FAT boot sector                   */
+/*-----------------------------------------------------------------------*/
+
+static
+BYTE check_fs (	/* 0:Valid FAT-BS, 1:Valid BS but not FAT, 2:Not a BS, 3:Disk error */
+	FATFS* fs,	/* File system object */
+	DWORD sect	/* Sector# (lba) to check if it is an FAT boot record or not */
+)
+{
+	fs->wflag = 0; fs->winsect = 0xFFFFFFFF;	/* Invaidate window */
+	if (move_window(fs, sect) != FR_OK)			/* Load boot record */
+		return 3;
+
+	if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55)	/* Check boot record signature (always placed at offset 510 even if the sector size is >512) */
+		return 2;
+
+	if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146)		/* Check "FAT" string */
+		return 0;
+	if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146)	/* Check "FAT" string */
+		return 0;
+
+	return 1;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Find logical drive and check if the volume is mounted                 */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT find_volume (	/* FR_OK(0): successful, !=0: any error occurred */
+	FATFS** rfs,		/* Pointer to pointer to the found file system object */
+	const TCHAR** path,	/* Pointer to pointer to the path name (drive number) */
+	BYTE wmode			/* !=0: Check write protection for write access */
+)
+{
+	BYTE fmt, *pt;
+	int vol;
+	DSTATUS stat;
+	DWORD bsect, fasize, tsect, sysect, nclst, szbfat, br[4];
+	WORD nrsv;
+	FATFS *fs;
+	UINT i;
+
+
+	/* Get logical drive number from the path name */
+	*rfs = 0;
+	vol = get_ldnumber(path);
+	if (vol < 0) return FR_INVALID_DRIVE;
+
+	/* Check if the file system object is valid or not */
+	fs = FatFs[vol];					/* Get pointer to the file system object */
+	if (!fs) return FR_NOT_ENABLED;		/* Is the file system object available? */
+
+	ENTER_FF(fs);						/* Lock the volume */
+	*rfs = fs;							/* Return pointer to the file system object */
+
+	if (fs->fs_type) {					/* If the volume has been mounted */
+		stat = disk_status(fs->drv);
+		if (!(stat & STA_NOINIT)) {		/* and the physical drive is kept initialized */
+			if (!FF_FS_READONLY && wmode && (stat & STA_PROTECT))	/* Check write protection if needed */
+				return FR_WRITE_PROTECTED;
+			return FR_OK;				/* The file system object is valid */
+		}
+	}
+
+	/* The file system object is not valid. */
+	/* Following code attempts to mount the volume. (analyze BPB and initialize the fs object) */
+
+	fs->fs_type = 0;					/* Clear the file system object */
+	fs->drv = LD2PD(vol);				/* Bind the logical drive and a physical drive */
+	stat = disk_initialize(fs->drv);	/* Initialize the physical drive */
+	if (stat & STA_NOINIT)				/* Check if the initialization succeeded */
+		return FR_NOT_READY;			/* Failed to initialize due to no medium or hard error */
+	if (!FF_FS_READONLY && wmode && (stat & STA_PROTECT))	/* Check disk write protection if needed */
+		return FR_WRITE_PROTECTED;
+#if FF_MAX_SS != FF_MIN_SS						/* Get sector size (multiple sector size cfg only) */
+	if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK
+		|| SS(fs) < FF_MIN_SS || SS(fs) > FF_MAX_SS) return FR_DISK_ERR;
+#endif
+	/* Find an FAT partition on the drive. Supports only generic partitioning, FDISK and SFD. */
+	bsect = 0;
+	fmt = check_fs(fs, bsect);					/* Load sector 0 and check if it is an FAT boot sector as SFD */
+	if (fmt == 1 || (!fmt && (LD2PT(vol)))) {	/* Not an FAT boot sector or forced partition number */
+		for (i = 0; i < 4; i++) {			/* Get partition offset */
+			pt = fs->win + MBR_Table + i * SZ_PTE;
+			br[i] = pt[4] ? LD_DWORD(&pt[8]) : 0;
+		}
+		i = LD2PT(vol);						/* Partition number: 0:auto, 1-4:forced */
+		if (i) i--;
+		do {								/* Find an FAT volume */
+			bsect = br[i];
+			fmt = bsect ? check_fs(fs, bsect) : 2;	/* Check the partition */
+		} while (!LD2PT(vol) && fmt && ++i < 4);
+	}
+	if (fmt == 3) return FR_DISK_ERR;		/* An error occured in the disk I/O layer */
+	if (fmt) return FR_NO_FILESYSTEM;		/* No FAT volume is found */
+
+	/* An FAT volume is found. Following code initializes the file system object */
+
+	if (LD_WORD(fs->win + BPB_BytsPerSec) != SS(fs))	/* (BPB_BytsPerSec must be equal to the physical sector size) */
+		return FR_NO_FILESYSTEM;
+
+	fasize = LD_WORD(fs->win + BPB_FATSz16);			/* Number of sectors per FAT */
+	if (!fasize) fasize = LD_DWORD(fs->win + BPB_FATSz32);
+	fs->fsize = fasize;
+
+	fs->n_fats = fs->win[BPB_NumFATs];					/* Number of FAT copies */
+	if (fs->n_fats != 1 && fs->n_fats != 2)				/* (Must be 1 or 2) */
+		return FR_NO_FILESYSTEM;
+	fasize *= fs->n_fats;								/* Number of sectors for FAT area */
+
+	fs->csize = fs->win[BPB_SecPerClus];				/* Number of sectors per cluster */
+	if (!fs->csize || (fs->csize & (fs->csize - 1)))	/* (Must be power of 2) */
+		return FR_NO_FILESYSTEM;
+
+	fs->n_rootdir = LD_WORD(fs->win + BPB_RootEntCnt);	/* Number of root directory entries */
+	if (fs->n_rootdir % (SS(fs) / SZ_DIRE))				/* (Must be sector aligned) */
+		return FR_NO_FILESYSTEM;
+
+	tsect = LD_WORD(fs->win + BPB_TotSec16);			/* Number of sectors on the volume */
+	if (!tsect) tsect = LD_DWORD(fs->win + BPB_TotSec32);
+
+	nrsv = LD_WORD(fs->win + BPB_RsvdSecCnt);			/* Number of reserved sectors */
+	if (!nrsv) return FR_NO_FILESYSTEM;					/* (Must not be 0) */
+
+	/* Determine the FAT sub type */
+	sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIRE);	/* RSV + FAT + FATFS_DIR */
+	if (tsect < sysect) return FR_NO_FILESYSTEM;		/* (Invalid volume size) */
+	nclst = (tsect - sysect) / fs->csize;				/* Number of clusters */
+	if (!nclst) return FR_NO_FILESYSTEM;				/* (Invalid volume size) */
+	fmt = FS_FAT12;
+	if (nclst >= MIN_FAT16) fmt = FS_FAT16;
+	if (nclst >= MIN_FAT32) fmt = FS_FAT32;
+
+	/* Boundaries and Limits */
+	fs->n_fatent = nclst + 2;							/* Number of FAT entries */
+	fs->volbase = bsect;								/* Volume start sector */
+	fs->fatbase = bsect + nrsv; 						/* FAT start sector */
+	fs->database = bsect + sysect;						/* Data start sector */
+	if (fmt == FS_FAT32) {
+		if (fs->n_rootdir) return FR_NO_FILESYSTEM;		/* (BPB_RootEntCnt must be 0) */
+		fs->dirbase = LD_DWORD(fs->win + BPB_RootClus);	/* Root directory start cluster */
+		szbfat = fs->n_fatent * 4;						/* (Needed FAT size) */
+	} else {
+		if (!fs->n_rootdir)	return FR_NO_FILESYSTEM;	/* (BPB_RootEntCnt must not be 0) */
+		fs->dirbase = fs->fatbase + fasize;				/* Root directory start sector */
+		szbfat = (fmt == FS_FAT16) ?					/* (Needed FAT size) */
+			fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);
+	}
+	if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs))	/* (BPB_FATSz must not be less than the size needed) */
+		return FR_NO_FILESYSTEM;
+
+#if !FF_FS_READONLY
+	/* Initialize cluster allocation information */
+	fs->last_clust = fs->free_clust = 0xFFFFFFFF;
+
+	/* Get fsinfo if available */
+	fs->fsi_flag = 0x80;
+#if (FF_FS_NOFSINFO & 3) != 3
+	if (fmt == FS_FAT32				/* Enable FSINFO only if FAT32 and BPB_FSInfo == 1 */
+		&& LD_WORD(fs->win + BPB_FSInfo) == 1
+		&& move_window(fs, bsect + 1) == FR_OK)
+	{
+		fs->fsi_flag = 0;
+		if (LD_WORD(fs->win + BS_55AA) == 0xAA55	/* Load FSINFO data if available */
+			&& LD_DWORD(fs->win + FSI_LeadSig) == 0x41615252
+			&& LD_DWORD(fs->win + FSI_StrucSig) == 0x61417272)
+		{
+#if (FF_FS_NOFSINFO & 1) == 0
+			fs->free_clust = LD_DWORD(fs->win + FSI_Free_Count);
+#endif
+#if (FF_FS_NOFSINFO & 2) == 0
+			fs->last_clust = LD_DWORD(fs->win + FSI_Nxt_Free);
+#endif
+		}
+	}
+#endif
+#endif
+	fs->fs_type = fmt;	/* FAT sub-type */
+	fs->id = ++Fsid;	/* File system mount ID */
+#if FF_FS_RPATH
+	fs->cdir = 0;		/* Set current directory to root */
+#endif
+#if FF_FS_LOCK != 0			/* Clear file lock semaphores */
+	clear_lock(fs);
+#endif
+
+	return FR_OK;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Check if the file/directory object is valid or not                    */
+/*-----------------------------------------------------------------------*/
+
+static
+FRESULT validate (	/* FR_OK(0): The object is valid, !=0: Invalid */
+	void* obj		/* Pointer to the object FIL/FATFS_DIR to check validity */
+)
+{
+	FIL *fil = (FIL*)obj;	/* Assuming offset of .fs and .id in the FIL/FATFS_DIR structure is identical */
+
+
+	if (!fil || !fil->fs || !fil->fs->fs_type || fil->fs->id != fil->id || (disk_status(fil->fs->drv) & STA_NOINIT))
+		return FR_INVALID_OBJECT;
+
+	ENTER_FF(fil->fs);		/* Lock file system */
+
+	return FR_OK;
+}
+
+
+
+
+/*--------------------------------------------------------------------------
+
+   Public Functions
+
+---------------------------------------------------------------------------*/
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Mount/Unmount a Logical Drive                                         */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_mount (
+	FATFS* fs,			/* Pointer to the file system object (NULL:unmount)*/
+	const TCHAR* path,	/* Logical drive number to be mounted/unmounted */
+	BYTE opt			/* 0:Do not mount (delayed mount), 1:Mount immediately */
+)
+{
+	FATFS *cfs;
+	int vol;
+	FRESULT res;
+	const TCHAR *rp = path;
+
+
+	vol = get_ldnumber(&rp);
+	if (vol < 0) return FR_INVALID_DRIVE;
+	cfs = FatFs[vol];					/* Pointer to fs object */
+
+	if (cfs) {
+#if FF_FS_LOCK != 0
+		clear_lock(cfs);
+#endif
+#if FF_FS_REENTRANT						/* Discard sync object of the current volume */
+		if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR;
+#endif
+		cfs->fs_type = 0;				/* Clear old fs object */
+	}
+
+	if (fs) {
+		fs->fs_type = 0;				/* Clear new fs object */
+#if FF_FS_REENTRANT						/* Create sync object for the new volume */
+		if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;
+#endif
+	}
+	FatFs[vol] = fs;					/* Register new fs object */
+
+	if (!fs || opt != 1) return FR_OK;	/* Do not mount now, it will be mounted later */
+
+	res = find_volume(&fs, &path, 0);	/* Force mounted the volume */
+	LEAVE_FF(fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Open or Create a File                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_open (
+	FIL* fp,			/* Pointer to the blank file object */
+	const TCHAR* path,	/* Pointer to the file name */
+	BYTE mode			/* Access mode and file open mode flags */
+)
+{
+	FRESULT res;
+	FATFS_DIR dj;
+	BYTE *dir;
+	DEFINE_NAMEBUF;
+#if !FF_FS_READONLY
+	DWORD dw, cl;
+#endif
+
+
+	if (!fp) return FR_INVALID_OBJECT;
+	fp->fs = 0;			/* Clear file object */
+
+	/* Get logical drive number */
+#if !FF_FS_READONLY
+	mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW | FA_OPEN_APPEND;
+	res = find_volume(&dj.fs, &path, (BYTE)(mode & ~FA_READ));
+#else
+	mode &= FA_READ;
+	res = find_volume(&dj.fs, &path, 0);
+#endif
+	if (res == FR_OK) {
+		INIT_BUF(dj);
+		res = follow_path(&dj, path);	/* Follow the file path */
+		dir = dj.dir;
+#if !FF_FS_READONLY	/* R/W configuration */
+		if (res == FR_OK) {
+			if (!dir)	/* Default directory itself */
+				res = FR_INVALID_NAME;
+#if FF_FS_LOCK != 0
+			else
+				res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
+#endif
+		}
+		/* Create or Open a file */
+		if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {
+			if (res != FR_OK) {					/* No file, create new */
+				if (res == FR_NO_FILE)			/* There is no file to open, create a new entry */
+#if FF_FS_LOCK != 0
+					res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;
+#else
+					res = dir_register(&dj);
+#endif
+				mode |= FA_CREATE_ALWAYS;		/* File is created */
+				dir = dj.dir;					/* New entry */
+			}
+			else {								/* Any object is already existing */
+				if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) {	/* Cannot overwrite it (R/O or FATFS_DIR) */
+					res = FR_DENIED;
+				} else {
+					if (mode & FA_CREATE_NEW)	/* Cannot create as new file */
+						res = FR_EXIST;
+				}
+			}
+			if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) {	/* Truncate it if overwrite mode */
+				dw = GET_FATTIME();
+				ST_DWORD(dir + DIR_CrtTime, dw);/* Set created time */
+				ST_DWORD(dir + DIR_WrtTime, dw);/* Set modified time */
+				dir[DIR_Attr] = 0;				/* Reset attribute */
+				ST_DWORD(dir + DIR_FileSize, 0);/* Reset file size */
+				cl = ld_clust(dj.fs, dir);		/* Get cluster chain */
+				st_clust(dir, 0);				/* Reset cluster */
+				dj.fs->wflag = 1;
+				if (cl) {						/* Remove the cluster chain if exist */
+					dw = dj.fs->winsect;
+					res = remove_chain(dj.fs, cl);
+					if (res == FR_OK) {
+						dj.fs->last_clust = cl - 1;	/* Reuse the cluster hole */
+						res = move_window(dj.fs, dw);
+					}
+				}
+			}
+		}
+		else {	/* Open an existing file */
+			if (res == FR_OK) {					/* Following succeeded */
+				if (dir[DIR_Attr] & AM_DIR) {	/* It is a directory */
+					res = FR_NO_FILE;
+				} else {
+					if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */
+						res = FR_DENIED;
+				}
+			}
+		}
+		if (res == FR_OK) {
+			if (mode & FA_CREATE_ALWAYS)		/* Set file change flag if created or overwritten */
+				mode |= FA_MODIFIED;
+			fp->dir_sect = dj.fs->winsect;		/* Pointer to the directory entry */
+			fp->dir_ptr = dir;
+#if FF_FS_LOCK != 0
+			fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
+			if (!fp->lockid) res = FR_INT_ERR;
+#endif
+		}
+
+#else				/* R/O configuration */
+		if (res == FR_OK) {					/* Follow succeeded */
+			dir = dj.dir;
+			if (!dir) {						/* Current directory itself */
+				res = FR_INVALID_NAME;
+			} else {
+				if (dir[DIR_Attr] & AM_DIR)	/* It is a directory */
+					res = FR_NO_FILE;
+			}
+		}
+#endif
+		FREE_BUF();
+
+		if (res == FR_OK) {
+			fp->flag = mode;					/* File access mode */
+			fp->err = 0;						/* Clear error flag */
+			fp->sclust = ld_clust(dj.fs, dir);	/* File start cluster */
+			fp->fsize = LD_DWORD(dir + DIR_FileSize);	/* File size */
+			fp->fptr = 0;						/* File pointer */
+			fp->dsect = 0;
+#if FF_USE_FASTSEEK
+			fp->cltbl = 0;						/* Normal seek mode */
+#endif
+			fp->fs = dj.fs;	 					/* Validate file object */
+			fp->id = fp->fs->id;
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* 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 csect, *rbuff = (BYTE*)buff;
+
+
+	*br = 0;	/* Clear read byte counter */
+
+	res = validate(fp);							/* Check validity */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->err)								/* Check error */
+		LEAVE_FF(fp->fs, (FRESULT)fp->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 read */
+		rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
+		if ((fp->fptr % SS(fp->fs)) == 0) {		/* On the sector boundary? */
+			csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));	/* Sector offset in the cluster */
+			if (!csect) {						/* On the cluster boundary? */
+				if (fp->fptr == 0) {			/* On the top of the file? */
+					clst = fp->sclust;			/* Follow from the origin */
+				} else {						/* Middle or end of the file */
+#if FF_USE_FASTSEEK
+					if (fp->cltbl)
+						clst = clmt_clust(fp, fp->fptr);	/* Get cluster# from the CLMT */
+					else
+#endif
+						clst = get_fat(fp->fs, fp->clust);	/* Follow cluster chain on the FAT */
+				}
+				if (clst < 2) ABORT(fp->fs, FR_INT_ERR);
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				fp->clust = clst;				/* Update current cluster */
+			}
+			sect = clust2sect(fp->fs, fp->clust);	/* Get current sector */
+			if (!sect) ABORT(fp->fs, FR_INT_ERR);
+			sect += csect;
+			cc = btr / SS(fp->fs);				/* When remaining bytes >= sector size, */
+			if (cc) {							/* Read maximum contiguous sectors directly */
+				if (csect + cc > fp->fs->csize)	/* Clip at cluster boundary */
+					cc = fp->fs->csize - csect;
+				if (disk_read(fp->fs->drv, rbuff, sect, cc) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2			/* Replace one of the read sectors with cached data if it contains a dirty sector */
+#if FF_FS_TINY
+				if (fp->fs->wflag && fp->fs->winsect - sect < cc)
+					mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs));
+#else
+				if ((fp->flag & FA_DIRTY) && fp->dsect - sect < cc)
+					mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs));
+#endif
+#endif
+				rcnt = SS(fp->fs) * cc;			/* Number of bytes transferred */
+				continue;
+			}
+#if !FF_FS_TINY
+			if (fp->dsect != sect) {			/* Load data sector if not in cache */
+#if !FF_FS_READONLY
+				if (fp->flag & FA_DIRTY) {		/* Write-back dirty sector cache */
+					if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
+						ABORT(fp->fs, FR_DISK_ERR);
+					fp->flag &= ~FA_DIRTY;
+				}
+#endif
+				if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)	/* Fill sector cache */
+					ABORT(fp->fs, FR_DISK_ERR);
+			}
+#endif
+			fp->dsect = sect;
+		}
+		rcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));	/* Get partial sector data from sector buffer */
+		if (rcnt > btr) rcnt = btr;
+#if FF_FS_TINY
+		if (move_window(fp->fs, fp->dsect) != FR_OK)		/* 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 !FF_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 = (const BYTE*)buff;
+	BYTE csect;
+
+
+	*bw = 0;	/* Clear write byte counter */
+
+	res = validate(fp);						/* Check validity */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->err)							/* Check error */
+		LEAVE_FF(fp->fs, (FRESULT)fp->err);
+	if (!(fp->flag & FA_WRITE))				/* Check access mode */
+		LEAVE_FF(fp->fs, FR_DENIED);
+	if (fp->fptr + btw < fp->fptr) btw = 0;	/* File size cannot reach 4GB */
+
+	for ( ;  btw;							/* Repeat until all data written */
+		wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
+		if ((fp->fptr % SS(fp->fs)) == 0) {	/* On the sector boundary? */
+			csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));	/* Sector offset in the cluster */
+			if (!csect) {					/* On the cluster boundary? */
+				if (fp->fptr == 0) {		/* On the top of the file? */
+					clst = fp->sclust;		/* Follow from the origin */
+					if (clst == 0)			/* When no cluster is allocated, */
+						clst = create_chain(fp->fs, 0);	/* Create a new cluster chain */
+				} else {					/* Middle or end of the file */
+#if FF_USE_FASTSEEK
+					if (fp->cltbl)
+						clst = clmt_clust(fp, fp->fptr);	/* Get cluster# from the CLMT */
+					else
+#endif
+						clst = create_chain(fp->fs, fp->clust);	/* Follow or stretch cluster chain on the FAT */
+				}
+				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->clust = clst;			/* Update current cluster */
+				if (fp->sclust == 0) fp->sclust = clst;	/* Set start cluster if the first write */
+			}
+#if FF_FS_TINY
+			if (fp->fs->winsect == fp->dsect && sync_window(fp->fs))	/* Write-back sector cache */
+				ABORT(fp->fs, FR_DISK_ERR);
+#else
+			if (fp->flag & FA_DIRTY) {		/* Write-back sector cache */
+				if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+				fp->flag &= ~FA_DIRTY;
+			}
+#endif
+			sect = clust2sect(fp->fs, fp->clust);	/* Get current sector */
+			if (!sect) ABORT(fp->fs, FR_INT_ERR);
+			sect += csect;
+			cc = btw / SS(fp->fs);			/* When remaining bytes >= sector size, */
+			if (cc) {						/* Write maximum contiguous sectors directly */
+				if (csect + cc > fp->fs->csize)	/* Clip at cluster boundary */
+					cc = fp->fs->csize - csect;
+				if (disk_write(fp->fs->drv, wbuff, sect, cc) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+#if FF_FS_MINIMIZE <= 2
+#if FF_FS_TINY
+				if (fp->fs->winsect - sect < cc) {	/* Refill sector cache if it gets invalidated by the direct write */
+					mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs));
+					fp->fs->wflag = 0;
+				}
+#else
+				if (fp->dsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
+					mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs));
+					fp->flag &= ~FA_DIRTY;
+				}
+#endif
+#endif
+				wcnt = SS(fp->fs) * cc;		/* Number of bytes transferred */
+				continue;
+			}
+#if FF_FS_TINY
+			if (fp->fptr >= fp->fsize) {	/* Avoid silly cache filling at growing edge */
+				if (sync_window(fp->fs)) ABORT(fp->fs, FR_DISK_ERR);
+				fp->fs->winsect = sect;
+			}
+#else
+			if (fp->dsect != sect) {		/* Fill sector cache with file data */
+				if (fp->fptr < fp->fsize &&
+					disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
+						ABORT(fp->fs, FR_DISK_ERR);
+			}
+#endif
+			fp->dsect = sect;
+		}
+		wcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */
+		if (wcnt > btw) wcnt = btw;
+#if FF_FS_TINY
+		if (move_window(fp->fs, fp->dsect) != FR_OK)	/* 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_MODIFIED;						/* Set file change flag */
+
+	LEAVE_FF(fp->fs, FR_OK);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Synchronize the File                                                  */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_sync (
+	FIL* fp		/* Pointer to the file object */
+)
+{
+	FRESULT res;
+	DWORD tm;
+	BYTE *dir;
+
+
+	res = validate(fp);					/* Check validity of the object */
+	if (res == FR_OK) {
+		if (fp->flag & FA_MODIFIED) {	/* Is there any change to the file? */
+#if !FF_FS_TINY
+			if (fp->flag & FA_DIRTY) {	/* Write-back cached data if needed */
+				if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
+					LEAVE_FF(fp->fs, FR_DISK_ERR);
+				fp->flag &= ~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_clust(dir, fp->sclust);					/* Update start cluster */
+				tm = GET_FATTIME();							/* Update modified time */
+				ST_DWORD(dir + DIR_WrtTime, tm);
+				ST_WORD(dir + DIR_LstAccDate, 0);
+				fp->flag &= ~FA_MODIFIED;
+				fp->fs->wflag = 1;
+				res = sync_fs(fp->fs);
+			}
+		}
+	}
+
+	LEAVE_FF(fp->fs, res);
+}
+
+#endif /* !FF_FS_READONLY */
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Close File                                                            */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_close (
+	FIL *fp		/* Pointer to the file object to be closed */
+)
+{
+	FRESULT res;
+
+
+#if !FF_FS_READONLY
+	res = f_sync(fp);					/* Flush cached data */
+	if (res == FR_OK)
+#endif
+	{
+		res = validate(fp);				/* Lock volume */
+		if (res == FR_OK) {
+#if FF_FS_REENTRANT
+			FATFS *fs = fp->fs;
+#endif
+#if FF_FS_LOCK != 0
+			res = dec_lock(fp->lockid);	/* Decrement file open counter */
+			if (res == FR_OK)
+#endif
+				fp->fs = 0;				/* Invalidate file object */
+#if FF_FS_REENTRANT
+			unlock_fs(fs, FR_OK);		/* Unlock volume */
+#endif
+		}
+	}
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change Current Directory or Current Drive, Get Current Directory      */
+/*-----------------------------------------------------------------------*/
+
+#if FF_FS_RPATH >= 1
+#if FF_VOLUMES >= 2
+FRESULT f_chdrive (
+	const TCHAR* path		/* Drive number */
+)
+{
+	int vol;
+
+
+	vol = get_ldnumber(&path);
+	if (vol < 0) return FR_INVALID_DRIVE;
+
+	CurrVol = (BYTE)vol;
+
+	return FR_OK;
+}
+#endif
+
+
+FRESULT f_chdir (
+	const TCHAR* path	/* Pointer to the directory path */
+)
+{
+	FRESULT res;
+	FATFS_DIR dj;
+	DEFINE_NAMEBUF;
+
+
+	/* Get logical drive number */
+	res = find_volume(&dj.fs, &path, 0);
+	if (res == FR_OK) {
+		INIT_BUF(dj);
+		res = follow_path(&dj, path);		/* Follow the path */
+		FREE_BUF();
+		if (res == FR_OK) {					/* Follow completed */
+			if (!dj.dir) {
+				dj.fs->cdir = dj.sclust;	/* Start directory itself */
+			} else {
+				if (dj.dir[DIR_Attr] & AM_DIR)	/* Reached to the directory */
+					dj.fs->cdir = ld_clust(dj.fs, dj.dir);
+				else
+					res = FR_NO_PATH;		/* Reached but a file */
+			}
+		}
+		if (res == FR_NO_FILE) res = FR_NO_PATH;
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+#if FF_FS_RPATH >= 2
+FRESULT f_getcwd (
+	TCHAR* buff,	/* Pointer to the directory path */
+	UINT len		/* Size of path */
+)
+{
+	FRESULT res;
+	FATFS_DIR dj;
+	UINT i, n;
+	DWORD ccl;
+	TCHAR *tp;
+	FILINFO fno;
+	DEFINE_NAMEBUF;
+
+
+	*buff = 0;
+	/* Get logical drive number */
+	res = find_volume(&dj.fs, (const TCHAR**)&buff, 0);	/* Get current volume */
+	if (res == FR_OK) {
+		INIT_BUF(dj);
+		i = len;			/* Bottom of buffer (directory stack base) */
+		dj.sclust = dj.fs->cdir;			/* Start to follow upper directory from current directory */
+		while ((ccl = dj.sclust) != 0) {	/* Repeat while current directory is a sub-directory */
+			res = dir_sdi(&dj, 1);			/* Get parent directory */
+			if (res != FR_OK) break;
+			res = dir_read(&dj, 0);
+			if (res != FR_OK) break;
+			dj.sclust = ld_clust(dj.fs, dj.dir);	/* Goto parent directory */
+			res = dir_sdi(&dj, 0);
+			if (res != FR_OK) break;
+			do {							/* Find the entry links to the child directory */
+				res = dir_read(&dj, 0);
+				if (res != FR_OK) break;
+				if (ccl == ld_clust(dj.fs, dj.dir)) break;	/* Found the entry */
+				res = dir_next(&dj, 0);	
+			} while (res == FR_OK);
+			if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */
+			if (res != FR_OK) break;
+#if FF_USE_LFN
+			fno.lfname = buff;
+			fno.lfsize = i;
+#endif
+			get_fileinfo(&dj, &fno);		/* Get the directory name and push it to the buffer */
+			tp = fno.fname;
+#if FF_USE_LFN
+			if (*buff) tp = buff;
+#endif
+			for (n = 0; tp[n]; n++) ;
+			if (i < n + 3) {
+				res = FR_NOT_ENOUGH_CORE; break;
+			}
+			while (n) buff[--i] = tp[--n];
+			buff[--i] = '/';
+		}
+		tp = buff;
+		if (res == FR_OK) {
+#if FF_VOLUMES >= 2
+			*tp++ = '0' + CurrVol;			/* Put drive number */
+			*tp++ = ':';
+#endif
+			if (i == len) {					/* Root-directory */
+				*tp++ = '/';
+			} else {						/* Sub-directroy */
+				do		/* Add stacked path str */
+					*tp++ = buff[i++];
+				while (i < len);
+			}
+		}
+		*tp = 0;
+		FREE_BUF();
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+#endif /* FF_FS_RPATH >= 2 */
+#endif /* FF_FS_RPATH >= 1 */
+
+
+
+#if FF_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;
+#if FF_USE_FASTSEEK
+	DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;
+#endif
+
+
+	res = validate(fp);					/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->err)						/* Check error */
+		LEAVE_FF(fp->fs, (FRESULT)fp->err);
+
+#if FF_USE_FASTSEEK
+	if (fp->cltbl) {	/* Fast seek */
+		if (ofs == CREATE_LINKMAP) {	/* Create CLMT */
+			tbl = fp->cltbl;
+			tlen = *tbl++; ulen = 2;	/* Given table size and required table size */
+			cl = fp->sclust;			/* Top of the chain */
+			if (cl) {
+				do {
+					/* Get a fragment */
+					tcl = cl; ncl = 0; ulen += 2;	/* Top, length and used items */
+					do {
+						pcl = cl; ncl++;
+						cl = get_fat(fp->fs, cl);
+						if (cl <= 1) ABORT(fp->fs, FR_INT_ERR);
+						if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+					} while (cl == pcl + 1);
+					if (ulen <= tlen) {		/* Store the length and top of the fragment */
+						*tbl++ = ncl; *tbl++ = tcl;
+					}
+				} while (cl < fp->fs->n_fatent);	/* Repeat until end of chain */
+			}
+			*fp->cltbl = ulen;	/* Number of items used */
+			if (ulen <= tlen)
+				*tbl = 0;		/* Terminate table */
+			else
+				res = FR_NOT_ENOUGH_CORE;	/* Given table size is smaller than required */
+
+		} else {						/* Fast seek */
+			if (ofs > fp->fsize)		/* Clip offset at the file size */
+				ofs = fp->fsize;
+			fp->fptr = ofs;				/* Set file pointer */
+			if (ofs) {
+				fp->clust = clmt_clust(fp, ofs - 1);
+				dsc = clust2sect(fp->fs, fp->clust);
+				if (!dsc) ABORT(fp->fs, FR_INT_ERR);
+				dsc += (ofs - 1) / SS(fp->fs) & (fp->fs->csize - 1);
+				if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) {	/* Refill sector cache if needed */
+#if !FF_FS_TINY
+#if !FF_FS_READONLY
+					if (fp->flag & FA_DIRTY) {		/* Write-back dirty sector cache */
+						if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
+							ABORT(fp->fs, FR_DISK_ERR);
+						fp->flag &= ~FA_DIRTY;
+					}
+#endif
+					if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK)	/* Load current sector */
+						ABORT(fp->fs, FR_DISK_ERR);
+#endif
+					fp->dsect = dsc;
+				}
+			}
+		}
+	} else
+#endif
+
+	/* Normal Seek */
+	{
+		if (ofs > fp->fsize					/* In read-only mode, clip offset with the file size */
+#if !FF_FS_READONLY
+			 && !(fp->flag & FA_WRITE)
+#endif
+			) ofs = fp->fsize;
+
+		ifptr = fp->fptr;
+		fp->fptr = nsect = 0;
+		if (ofs) {
+			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->clust;
+			} else {									/* When seek to back cluster, */
+				clst = fp->sclust;						/* start from the first cluster */
+#if !FF_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->sclust = clst;
+				}
+#endif
+				fp->clust = clst;
+			}
+			if (clst != 0) {
+				while (ofs > bcs) {						/* Cluster following loop */
+#if !FF_FS_READONLY
+					if (fp->flag & FA_WRITE) {			/* Check if in write mode or not */
+						clst = create_chain(fp->fs, clst);	/* Force stretch if in write mode */
+						if (clst == 0) {				/* When disk gets full, clip file size */
+							ofs = bcs; break;
+						}
+					} else
+#endif
+						clst = get_fat(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->n_fatent) ABORT(fp->fs, FR_INT_ERR);
+					fp->clust = clst;
+					fp->fptr += bcs;
+					ofs -= bcs;
+				}
+				fp->fptr += ofs;
+				if (ofs % SS(fp->fs)) {
+					nsect = clust2sect(fp->fs, clst);	/* Current sector */
+					if (!nsect) ABORT(fp->fs, FR_INT_ERR);
+					nsect += ofs / SS(fp->fs);
+				}
+			}
+		}
+		if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) {	/* Fill sector cache if needed */
+#if !FF_FS_TINY
+#if !FF_FS_READONLY
+			if (fp->flag & FA_DIRTY) {			/* Write-back dirty sector cache */
+				if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
+					ABORT(fp->fs, FR_DISK_ERR);
+				fp->flag &= ~FA_DIRTY;
+			}
+#endif
+			if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK)	/* Fill sector cache */
+				ABORT(fp->fs, FR_DISK_ERR);
+#endif
+			fp->dsect = nsect;
+		}
+#if !FF_FS_READONLY
+		if (fp->fptr > fp->fsize) {			/* Set file change flag if the file size is extended */
+			fp->fsize = fp->fptr;
+			fp->flag |= FA_MODIFIED;
+		}
+#endif
+	}
+
+	LEAVE_FF(fp->fs, res);
+}
+
+FRESULT f_seek(FIL* fp, DWORD ofs, BYTE mode)
+{
+  switch (mode) {
+  case F_SEEK_SET:
+    return f_lseek((fp), ofs);
+  case F_SEEK_CUR:
+    return f_lseek((fp), (fp)->fptr + ofs);
+  case F_SEEK_END:
+    return f_lseek((fp), (fp)->fsize - ofs);
+  default:
+    return FR_INVALID_PARAMETER;
+  }
+}
+
+#if FF_FS_MINIMIZE <= 1
+/*-----------------------------------------------------------------------*/
+/* Create a Directory Object                                             */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_opendir (
+	FATFS_DIR* dp,			/* Pointer to directory object to create */
+	const TCHAR* path	/* Pointer to the directory path */
+)
+{
+	FRESULT res;
+	FATFS* fs;
+	DEFINE_NAMEBUF;
+
+
+	if (!dp) return FR_INVALID_OBJECT;
+
+	/* Get logical drive number */
+	res = find_volume(&fs, &path, 0);
+	if (res == FR_OK) {
+		dp->fs = fs;
+		INIT_BUF(*dp);
+		res = follow_path(dp, path);			/* Follow the path to the directory */
+		FREE_BUF();
+		if (res == FR_OK) {						/* Follow completed */
+			if (dp->dir) {						/* It is not the origin directory itself */
+				if (dp->dir[DIR_Attr] & AM_DIR)	/* The object is a sub directory */
+					dp->sclust = ld_clust(fs, dp->dir);
+				else							/* The object is a file */
+					res = FR_NO_PATH;
+			}
+			if (res == FR_OK) {
+				dp->id = fs->id;
+				res = dir_sdi(dp, 0);			/* Rewind directory */
+#if FF_FS_LOCK != 0
+				if (res == FR_OK) {
+					if (dp->sclust) {
+						dp->lockid = inc_lock(dp, 0);	/* Lock the sub directory */
+						if (!dp->lockid)
+							res = FR_TOO_MANY_OPEN_FILES;
+					} else {
+						dp->lockid = 0;	/* Root directory need not to be locked */
+					}
+				}
+#endif
+			}
+		}
+		if (res == FR_NO_FILE) res = FR_NO_PATH;
+	}
+	if (res != FR_OK) dp->fs = 0;		/* Invalidate the directory object if function faild */
+
+	LEAVE_FF(fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Close Directory                                                       */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_closedir (
+	FATFS_DIR *dp		/* Pointer to the directory object to be closed */
+)
+{
+	FRESULT res;
+
+
+	res = validate(dp);
+	if (res == FR_OK) {
+#if FF_FS_REENTRANT
+		FATFS *fs = dp->fs;
+#endif
+#if FF_FS_LOCK != 0
+		if (dp->lockid)				/* Decrement sub-directory open counter */
+			res = dec_lock(dp->lockid);
+		if (res == FR_OK)
+#endif
+			dp->fs = 0;				/* Invalidate directory object */
+#if FF_FS_REENTRANT
+		unlock_fs(fs, FR_OK);		/* Unlock volume */
+#endif
+	}
+	return res;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Directory Entries in Sequence                                    */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_readdir (
+	FATFS_DIR* dp,			/* Pointer to the open directory object */
+	FILINFO* fno		/* Pointer to file information to return */
+)
+{
+	FRESULT res;
+	DEFINE_NAMEBUF;
+
+
+	res = validate(dp);						/* Check validity of the object */
+	if (res == FR_OK) {
+		if (!fno) {
+			res = dir_sdi(dp, 0);			/* Rewind the directory object */
+		} else {
+			INIT_BUF(*dp);
+			res = dir_read(dp, 0);			/* Read an item */
+			if (res == FR_NO_FILE) {		/* Reached end of directory */
+				dp->sect = 0;
+				res = FR_OK;
+			}
+			if (res == FR_OK) {				/* A valid entry is found */
+				get_fileinfo(dp, fno);		/* Get the object information */
+				res = dir_next(dp, 0);		/* Increment index for next */
+				if (res == FR_NO_FILE) {
+					dp->sect = 0;
+					res = FR_OK;
+				}
+			}
+			FREE_BUF();
+		}
+	}
+
+	LEAVE_FF(dp->fs, res);
+}
+
+
+
+#if FF_USE_FIND
+/*-----------------------------------------------------------------------*/
+/* Find next file                                                        */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_findnext (
+	FATFS_DIR* dp,		/* Pointer to the open directory object */
+	FILINFO* fno	/* Pointer to the file information structure */
+)
+{
+	FRESULT res;
+
+
+	for (;;) {
+		res = f_readdir(dp, fno);		/* Get a directory item */
+		if (res != FR_OK || !fno || !fno->fname[0]) break;	/* Terminate if any error or end of directory */
+#if FF_USE_LFN
+		if (fno->lfname && pattern_matching(dp->pat, fno->lfname, 0, 0)) break;	/* Test for LFN if exist */
+#endif
+		if (pattern_matching(dp->pat, fno->fname, 0, 0)) break;	/* Test for SFN */
+	}
+	return res;
+
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Find first file                                                       */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_findfirst (
+	FATFS_DIR* dp,				/* Pointer to the blank directory object */
+	FILINFO* fno,			/* Pointer to the file information structure */
+	const TCHAR* path,		/* Pointer to the directory to open */
+	const TCHAR* pattern	/* Pointer to the matching pattern */
+)
+{
+	FRESULT res;
+
+
+	dp->pat = pattern;		/* Save pointer to pattern string */
+	res = f_opendir(dp, path);		/* Open the target directory */
+	if (res == FR_OK)
+		res = f_findnext(dp, fno);	/* Find the first item */
+	return res;
+}
+
+#endif	/* FF_USE_FIND */
+
+
+
+#if FF_FS_MINIMIZE == 0
+/*-----------------------------------------------------------------------*/
+/* Get File Status                                                       */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_stat (
+	const TCHAR* path,	/* Pointer to the file path */
+	FILINFO* fno		/* Pointer to file information to return */
+)
+{
+	FRESULT res;
+	FATFS_DIR dj;
+	DEFINE_NAMEBUF;
+
+
+	/* Get logical drive number */
+	res = find_volume(&dj.fs, &path, 0);
+	if (res == FR_OK) {
+		INIT_BUF(dj);
+		res = follow_path(&dj, path);	/* Follow the file path */
+		if (res == FR_OK) {				/* Follow completed */
+			if (dj.dir) {		/* Found an object */
+				if (fno) get_fileinfo(&dj, fno);
+			} else {			/* It is root directory */
+				res = FR_INVALID_NAME;
+			}
+		}
+		FREE_BUF();
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+#if !FF_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Get Number of Free Clusters                                           */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_getfree (
+	const TCHAR* path,	/* Path name of the logical drive number */
+	DWORD* nclst,		/* Pointer to a variable to return number of free clusters */
+	FATFS** fatfs		/* Pointer to return pointer to corresponding file system object */
+)
+{
+	FRESULT res;
+	FATFS *fs;
+	DWORD nfree, clst, sect, stat;
+	UINT i;
+	BYTE fat, *p;
+
+
+	/* Get logical drive number */
+	res = find_volume(fatfs, &path, 0);
+	fs = *fatfs;
+	if (res == FR_OK) {
+		/* If free_clust is valid, return it without full cluster scan */
+		if (fs->free_clust <= fs->n_fatent - 2) {
+			*nclst = fs->free_clust;
+		} else {
+			/* Get number of free clusters */
+			fat = fs->fs_type;
+			nfree = 0;
+			if (fat == FS_FAT12) {	/* Sector unalighed entries: Search FAT via regular routine. */
+				clst = 2;
+				do {
+					stat = get_fat(fs, clst);
+					if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }
+					if (stat == 1) { res = FR_INT_ERR; break; }
+					if (stat == 0) nfree++;
+				} while (++clst < fs->n_fatent);
+			} else {				/* Sector alighed entries: Accelerate the FAT search. */
+				clst = fs->n_fatent; sect = fs->fatbase;
+				i = 0; p = 0;
+				do {
+					if (!i) {
+						res = move_window(fs, sect++);
+						if (res != FR_OK) break;
+						p = fs->win;
+						i = SS(fs);
+					}
+					if (fat == FS_FAT16) {
+						if (LD_WORD(p) == 0) nfree++;
+						p += 2; i -= 2;
+					} else {
+						if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) nfree++;
+						p += 4; i -= 4;
+					}
+				} while (--clst);
+			}
+			fs->free_clust = nfree;	/* free_clust is valid */
+			fs->fsi_flag |= 1;		/* FSInfo is to be updated */
+			*nclst = nfree;			/* Return the free clusters */
+		}
+	}
+	LEAVE_FF(fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Truncate File                                                         */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_truncate (
+	FIL* fp		/* Pointer to the file object */
+)
+{
+	FRESULT res;
+	DWORD ncl;
+
+
+	res = validate(fp);						/* Check validity of the object */
+	if (res == FR_OK) {
+		if (fp->err) {						/* Check error */
+			res = (FRESULT)fp->err;
+		} else {
+			if (!(fp->flag & FA_WRITE))		/* Check access mode */
+				res = FR_DENIED;
+		}
+	}
+	if (res == FR_OK) {
+		if (fp->fsize > fp->fptr) {
+			fp->fsize = fp->fptr;	/* Set file size to current R/W point */
+			fp->flag |= FA_MODIFIED;
+			if (fp->fptr == 0) {	/* When set file size to zero, remove entire cluster chain */
+				res = remove_chain(fp->fs, fp->sclust);
+				fp->sclust = 0;
+			} else {				/* When truncate a part of the file, remove remaining clusters */
+				ncl = get_fat(fp->fs, fp->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->n_fatent) {
+					res = put_fat(fp->fs, fp->clust, 0x0FFFFFFF);
+					if (res == FR_OK) res = remove_chain(fp->fs, ncl);
+				}
+			}
+#if !FF_FS_TINY
+			if (res == FR_OK && (fp->flag & FA_DIRTY)) {
+				if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
+					res = FR_DISK_ERR;
+				else
+					fp->flag &= ~FA_DIRTY;
+			}
+#endif
+		}
+		if (res != FR_OK) fp->err = (FRESULT)res;
+	}
+
+	LEAVE_FF(fp->fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Delete a File or Directory                                            */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_unlink (
+	const TCHAR* path		/* Pointer to the file or directory path */
+)
+{
+	FRESULT res;
+	FATFS_DIR dj, sdj;
+	BYTE *dir;
+	DWORD dclst = 0;
+	DEFINE_NAMEBUF;
+
+
+	/* Get logical drive number */
+	res = find_volume(&dj.fs, &path, 1);
+	if (res == FR_OK) {
+		INIT_BUF(dj);
+		res = follow_path(&dj, path);		/* Follow the file path */
+		if (FF_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))
+			res = FR_INVALID_NAME;			/* Cannot remove dot entry */
+#if FF_FS_LOCK != 0
+		if (res == FR_OK) res = chk_lock(&dj, 2);	/* Cannot remove open object */
+#endif
+		if (res == FR_OK) {					/* The object is accessible */
+			dir = dj.dir;
+			if (!dir) {
+				res = FR_INVALID_NAME;		/* Cannot remove the origin directory */
+			} else {
+				if (dir[DIR_Attr] & AM_RDO)
+					res = FR_DENIED;		/* Cannot remove R/O object */
+			}
+			if (res == FR_OK) {
+				dclst = ld_clust(dj.fs, dir);
+				if (dclst && (dir[DIR_Attr] & AM_DIR)) {	/* Is it a sub-directory ? */
+#if FF_FS_RPATH
+					if (dclst == dj.fs->cdir) {		 		/* Is it the current directory? */
+						res = FR_DENIED;
+					} else
+#endif
+					{
+						mem_cpy(&sdj, &dj, sizeof (FATFS_DIR));	/* Open the sub-directory */
+						sdj.sclust = dclst;
+						res = dir_sdi(&sdj, 2);
+						if (res == FR_OK) {
+							res = dir_read(&sdj, 0);			/* Read an item (excluding dot entries) */
+							if (res == FR_OK) res = FR_DENIED;	/* Not empty? (cannot remove) */
+							if (res == FR_NO_FILE) res = FR_OK;	/* Empty? (can remove) */
+						}
+					}
+				}
+			}
+			if (res == FR_OK) {
+				res = dir_remove(&dj);		/* Remove the directory entry */
+				if (res == FR_OK && dclst)	/* Remove the cluster chain if exist */
+					res = remove_chain(dj.fs, dclst);
+				if (res == FR_OK) res = sync_fs(dj.fs);
+			}
+		}
+		FREE_BUF();
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Create a Directory                                                    */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_mkdir (
+	const TCHAR* path		/* Pointer to the directory path */
+)
+{
+	FRESULT res;
+	FATFS_DIR dj;
+	BYTE *dir, n;
+	DWORD dsc, dcl, pcl, tm = GET_FATTIME();
+	DEFINE_NAMEBUF;
+
+
+	/* Get logical drive number */
+	res = find_volume(&dj.fs, &path, 1);
+	if (res == FR_OK) {
+		INIT_BUF(dj);
+		res = follow_path(&dj, path);			/* Follow the file path */
+		if (res == FR_OK) res = FR_EXIST;		/* Any object with same name is already existing */
+		if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT))
+			res = FR_INVALID_NAME;
+		if (res == FR_NO_FILE) {				/* Can create a new directory */
+			dcl = create_chain(dj.fs, 0);		/* Allocate a cluster for the new directory table */
+			res = FR_OK;
+			if (dcl == 0) res = FR_DENIED;		/* No space to allocate a new cluster */
+			if (dcl == 1) res = FR_INT_ERR;
+			if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR;
+			if (res == FR_OK)					/* Flush FAT */
+				res = sync_window(dj.fs);
+			if (res == FR_OK) {					/* Initialize the new directory table */
+				dsc = clust2sect(dj.fs, dcl);
+				dir = dj.fs->win;
+				mem_set(dir, 0, SS(dj.fs));
+				mem_set(dir + DIR_Name, ' ', 11);	/* Create "." entry */
+				dir[DIR_Name] = '.';
+				dir[DIR_Attr] = AM_DIR;
+				ST_DWORD(dir + DIR_WrtTime, tm);
+				st_clust(dir, dcl);
+				mem_cpy(dir + SZ_DIRE, dir, SZ_DIRE); 	/* Create ".." entry */
+				dir[SZ_DIRE + 1] = '.'; pcl = dj.sclust;
+				if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase)
+					pcl = 0;
+				st_clust(dir + SZ_DIRE, pcl);
+				for (n = dj.fs->csize; n; n--) {	/* Write dot entries and clear following sectors */
+					dj.fs->winsect = dsc++;
+					dj.fs->wflag = 1;
+					res = sync_window(dj.fs);
+					if (res != FR_OK) break;
+					mem_set(dir, 0, SS(dj.fs));
+				}
+			}
+			if (res == FR_OK) res = dir_register(&dj);	/* Register the object to the directoy */
+			if (res != FR_OK) {
+				remove_chain(dj.fs, dcl);			/* Could not register, remove cluster chain */
+			} else {
+				dir = dj.dir;
+				dir[DIR_Attr] = AM_DIR;				/* Attribute */
+				ST_DWORD(dir + DIR_WrtTime, tm);	/* Created time */
+				st_clust(dir, dcl);					/* Table start cluster */
+				dj.fs->wflag = 1;
+				res = sync_fs(dj.fs);
+			}
+		}
+		FREE_BUF();
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change Attribute                                                      */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_chmod (
+	const TCHAR* path,	/* Pointer to the file path */
+	BYTE attr,			/* Attribute bits */
+	BYTE mask			/* Attribute mask to change */
+)
+{
+	FRESULT res;
+	FATFS_DIR dj;
+	BYTE *dir;
+	DEFINE_NAMEBUF;
+
+
+	res = find_volume(&dj.fs, &path, 1);	/* Get logical drive number */
+	if (res == FR_OK) {
+		INIT_BUF(dj);
+		res = follow_path(&dj, path);		/* Follow the file path */
+		FREE_BUF();
+		if (FF_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))
+			res = FR_INVALID_NAME;
+		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] = (attr & mask) | (dir[DIR_Attr] & (BYTE)~mask);	/* Apply attribute change */
+				dj.fs->wflag = 1;
+				res = sync_fs(dj.fs);
+			}
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Rename File/Directory                                                 */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_rename (
+	const TCHAR* path_old,	/* Pointer to the object to be renamed */
+	const TCHAR* path_new	/* Pointer to the new name */
+)
+{
+	FRESULT res;
+	FATFS_DIR djo, djn;
+	BYTE buf[21], *dir;
+	DWORD dw;
+	DEFINE_NAMEBUF;
+	TCHAR *temp_new_path = 0;
+
+
+	/* Get logical drive number of the source object */
+	res = find_volume(&djo.fs, &path_old, 1);
+	if (res == FR_OK) {
+		djn.fs = djo.fs;
+		INIT_BUF(djo);
+		res = follow_path(&djo, path_old);		/* Check old object */
+		if (FF_FS_RPATH && res == FR_OK && (djo.fn[NSFLAG] & NS_DOT))
+			res = FR_INVALID_NAME;
+#if FF_FS_LOCK != 0
+		if (res == FR_OK) res = chk_lock(&djo, 2);
+#endif
+		if (res == FR_OK) {						/* Old object is found */
+			if (!djo.dir) {						/* Is root dir? */
+				res = FR_NO_FILE;
+			} else {
+				mem_cpy(buf, djo.dir + DIR_Attr, 21);	/* Save information about object except name */
+				mem_cpy(&djn, &djo, sizeof (FATFS_DIR));		/* Duplicate the directory object */
+				if (get_ldnumber(&path_new) >= 0)		/* Snip drive number off and ignore it */
+					res = follow_path(&djn, path_new);	/* and make sure if new object name is not conflicting */
+				else
+					res = FR_INVALID_DRIVE;
+				if (res == FR_OK) {
+					res = FR_EXIST;		/* The new object name is already existing */
+					dir = djn.dir;
+					if (dir[DIR_Attr] & AM_DIR) {	/* The new object is a directory */
+						temp_new_path = (TCHAR *)ff_memalloc((FF_MAX_LFN + 1) * sizeof(WCHAR));
+						snprintf(temp_new_path, FF_MAX_LFN, "%s/%s", path_new, basename((char *)path_old));
+						res = follow_path(&djn, temp_new_path);
+					}
+				}
+				if (res == FR_NO_FILE) { 				/* It is a valid path and no name collision */
+					res = dir_register(&djn);			/* Register the new entry */
+					if (res == FR_OK) {
+/* Start of critical section where any interruption can cause a cross-link */
+						dir = djn.dir;					/* Copy information about object except name */
+						mem_cpy(dir + 13, buf + 2, 19);
+						dir[DIR_Attr] = buf[0] | AM_ARC;
+						djo.fs->wflag = 1;
+						if ((dir[DIR_Attr] & AM_DIR) && djo.sclust != djn.sclust) {	/* Update .. entry in the sub-directory if needed */
+							dw = clust2sect(djo.fs, ld_clust(djo.fs, dir));
+							if (!dw) {
+								res = FR_INT_ERR;
+							} else {
+								res = move_window(djo.fs, dw);
+								dir = djo.fs->win + SZ_DIRE * 1;	/* Ptr to .. entry */
+								if (res == FR_OK && dir[1] == '.') {
+									st_clust(dir, djn.sclust);
+									djo.fs->wflag = 1;
+								}
+							}
+						}
+						if (res == FR_OK) {
+							res = dir_remove(&djo);		/* Remove old entry */
+							if (res == FR_OK)
+								res = sync_fs(djo.fs);
+						}
+/* End of critical section */
+					}
+				}
+			}
+		}
+		FREE_BUF();
+	}
+
+	if (temp_new_path != 0)	ff_memfree(temp_new_path);
+
+	LEAVE_FF(djo.fs, res);
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Change Timestamp                                                      */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_utime (
+	const TCHAR* path,	/* Pointer to the file/directory name */
+	const FILINFO* fno	/* Pointer to the time stamp to be set */
+)
+{
+	FRESULT res;
+	FATFS_DIR dj;
+	BYTE *dir;
+	DEFINE_NAMEBUF;
+
+
+	/* Get logical drive number */
+	res = find_volume(&dj.fs, &path, 1);
+	if (res == FR_OK) {
+		INIT_BUF(dj);
+		res = follow_path(&dj, path);	/* Follow the file path */
+		FREE_BUF();
+		if (FF_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT))
+			res = FR_INVALID_NAME;
+		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_fs(dj.fs);
+			}
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+#endif /* !FF_FS_READONLY */
+#endif /* FF_FS_MINIMIZE == 0 */
+#endif /* FF_FS_MINIMIZE <= 1 */
+#endif /* FF_FS_MINIMIZE <= 2 */
+
+
+
+
+#if FF_USE_LABEL
+/*-----------------------------------------------------------------------*/
+/* Get volume label                                                      */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_getlabel (
+	const TCHAR* path,	/* Path name of the logical drive number */
+	TCHAR* label,		/* Pointer to a buffer to return the volume label */
+	DWORD* vsn			/* Pointer to a variable to return the volume serial number */
+)
+{
+	FRESULT res;
+	FATFS_DIR dj;
+	UINT i, j;
+#if FF_USE_LFN && FF_LFN_UNICODE
+	WCHAR w;
+#endif
+
+
+	/* Get logical drive number */
+	res = find_volume(&dj.fs, &path, 0);
+
+	/* Get volume label */
+	if (res == FR_OK && label) {
+		dj.sclust = 0;					/* Open root directory */
+		res = dir_sdi(&dj, 0);
+		if (res == FR_OK) {
+			res = dir_read(&dj, 1);		/* Get an entry with AM_VOL */
+			if (res == FR_OK) {			/* A volume label is exist */
+#if FF_USE_LFN && FF_LFN_UNICODE
+				i = j = 0;
+				do {
+					w = (i < 11) ? dj.dir[i++] : ' ';
+					if (IsDBCS1(w) && i < 11 && IsDBCS2(dj.dir[i]))
+						w = w << 8 | dj.dir[i++];
+					label[j++] = ff_convert(w, 1);	/* OEM -> Unicode */
+				} while (j < 11);
+#else
+				mem_cpy(label, dj.dir, 11);
+#endif
+				j = 11;
+				do {
+					label[j] = 0;
+					if (!j) break;
+				} while (label[--j] == ' ');
+			}
+			if (res == FR_NO_FILE) {	/* No label, return nul string */
+				label[0] = 0;
+				res = FR_OK;
+			}
+		}
+	}
+
+	/* Get volume serial number */
+	if (res == FR_OK && vsn) {
+		res = move_window(dj.fs, dj.fs->volbase);
+		if (res == FR_OK) {
+			i = dj.fs->fs_type == FS_FAT32 ? BS_VolID32 : BS_VolID;
+			*vsn = LD_DWORD(&dj.fs->win[i]);
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+
+
+#if !FF_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Set volume label                                                      */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_setlabel (
+	const TCHAR* label	/* Pointer to the volume label to set */
+)
+{
+	FRESULT res;
+	FATFS_DIR dj;
+	BYTE vn[11];
+	UINT i, j, sl;
+	WCHAR w;
+	DWORD tm;
+#if FF_CODE_PAGE == 65001
+	int code_size;
+	unsigned char utf8_code[6];
+#endif
+
+	/* Get logical drive number */
+	res = find_volume(&dj.fs, &label, 1);
+	if (res) LEAVE_FF(dj.fs, res);
+
+	/* Create a volume label in directory form */
+	vn[0] = 0;
+	for (sl = 0; label[sl]; sl++) ;				/* Get name length */
+	for ( ; sl && label[sl - 1] == ' '; sl--) ;	/* Remove trailing spaces */
+	if (sl) {	/* Create volume label in directory form */
+		i = j = 0;
+		do {
+#if FF_CODE_PAGE == 65001
+			w = ff_wtoupper(Utf8_to_Utf16(&label[i], &code_size));
+			i += code_size;
+			Utf16_to_Utf8(utf8_code, &code_size, w);
+			if (!w || chk_chr("\"*+,.:;<=>\?[]|\x7F", w) || j >= sizeof(vn) - code_size) /* Reject invalid characters for volume label */
+				LEAVE_FF(dj.fs, FR_INVALID_NAME);
+			for (int k = 0; k < code_size; k++)
+				vn[j++] = utf8_code[k];
+#else
+#if FF_USE_LFN && FF_LFN_UNICODE
+			w = ff_convert(ff_wtoupper(label[i++]), 0);
+#else
+			w = (BYTE)label[i++];
+			if (IsDBCS1(w))
+				w = (j < 10 && i < sl && IsDBCS2(label[i])) ? w << 8 | (BYTE)label[i++] : 0;
+#if FF_USE_LFN
+			w = ff_convert(ff_wtoupper(ff_convert(w, 1)), 0);
+#else
+			if (IsLower(w)) w -= 0x20;			/* To upper ASCII characters */
+#ifdef _EXCVT
+			if (w >= 0x80) w = ExCvt[w - 0x80];	/* To upper extended characters (SBCS cfg) */
+#else
+			if (!_DF1S && w >= 0x80) w = 0;		/* Reject extended characters (ASCII cfg) */
+#endif
+#endif
+#endif
+			if (!w || chk_chr("\"*+,.:;<=>\?[]|\x7F", w) || j >= (UINT)((w >= 0x100) ? 10 : 11)) /* Reject invalid characters for volume label */
+				LEAVE_FF(dj.fs, FR_INVALID_NAME);
+			if (w >= 0x100) vn[j++] = (BYTE)(w >> 8);
+			vn[j++] = (BYTE)w;
+#endif
+		} while (i < sl);
+		while (j < 11) vn[j++] = ' ';	/* Fill remaining name field */
+		if (vn[0] == DDEM) LEAVE_FF(dj.fs, FR_INVALID_NAME);	/* Reject illegal name (heading DDEM) */
+	}
+
+	/* Set volume label */
+	dj.sclust = 0;					/* Open root directory */
+	res = dir_sdi(&dj, 0);
+	if (res == FR_OK) {
+		res = dir_read(&dj, 1);		/* Get an entry with AM_VOL */
+		if (res == FR_OK) {			/* A volume label is found */
+			if (vn[0]) {
+				mem_cpy(dj.dir, vn, 11);	/* Change the volume label name */
+				tm = GET_FATTIME();
+				ST_DWORD(dj.dir + DIR_WrtTime, tm);
+			} else {
+				dj.dir[0] = DDEM;			/* Remove the volume label */
+			}
+			dj.fs->wflag = 1;
+			res = sync_fs(dj.fs);
+		} else {					/* No volume label is found or error */
+			if (res == FR_NO_FILE) {
+				res = FR_OK;
+				if (vn[0]) {				/* Create volume label as new */
+					res = dir_alloc(&dj, 1);	/* Allocate an entry for volume label */
+					if (res == FR_OK) {
+						mem_set(dj.dir, 0, SZ_DIRE);	/* Set volume label */
+						mem_cpy(dj.dir, vn, 11);
+						dj.dir[DIR_Attr] = AM_VOL;
+						tm = GET_FATTIME();
+						ST_DWORD(dj.dir + DIR_WrtTime, tm);
+						dj.fs->wflag = 1;
+						res = sync_fs(dj.fs);
+					}
+				}
+			}
+		}
+	}
+
+	LEAVE_FF(dj.fs, res);
+}
+
+#endif /* !FF_FS_READONLY */
+#endif /* FF_USE_LABEL */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Forward data to the stream directly (available on only tiny cfg)      */
+/*-----------------------------------------------------------------------*/
+#if FF_USE_FORWARD && FF_FS_TINY
+
+FRESULT f_forward (
+	FIL* fp, 						/* Pointer to the file object */
+	UINT (*func)(const BYTE*,UINT),	/* Pointer to the streaming function */
+	UINT btf,						/* Number of bytes to forward */
+	UINT* bf						/* Pointer to number of bytes forwarded */
+)
+{
+	FRESULT res;
+	DWORD remain, clst, sect;
+	UINT rcnt;
+	BYTE csect;
+
+
+	*bf = 0;	/* Clear transfer byte counter */
+
+	res = validate(fp);								/* Check validity of the object */
+	if (res != FR_OK) LEAVE_FF(fp->fs, res);
+	if (fp->err)									/* Check error */
+		LEAVE_FF(fp->fs, (FRESULT)fp->err);
+	if (!(fp->flag & FA_READ))						/* Check access mode */
+		LEAVE_FF(fp->fs, FR_DENIED);
+
+	remain = fp->fsize - fp->fptr;
+	if (btf > remain) btf = (UINT)remain;			/* Truncate btf by remaining bytes */
+
+	for ( ;  btf && (*func)(0, 0);					/* Repeat until all data transferred or stream becomes busy */
+		fp->fptr += rcnt, *bf += rcnt, btf -= rcnt) {
+		csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));	/* Sector offset in the cluster */
+		if ((fp->fptr % SS(fp->fs)) == 0) {			/* On the sector boundary? */
+			if (!csect) {							/* On the cluster boundary? */
+				clst = (fp->fptr == 0) ?			/* On the top of the file? */
+					fp->sclust : get_fat(fp->fs, fp->clust);
+				if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);
+				if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
+				fp->clust = clst;					/* Update current cluster */
+			}
+		}
+		sect = clust2sect(fp->fs, fp->clust);		/* Get current data sector */
+		if (!sect) ABORT(fp->fs, FR_INT_ERR);
+		sect += csect;
+		if (move_window(fp->fs, sect) != FR_OK)		/* 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 > btf) rcnt = btf;
+		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 /* FF_USE_FORWARD */
+
+
+
+#if FF_USE_MKFS && !FF_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Create file system on the logical drive                               */
+/*-----------------------------------------------------------------------*/
+#define N_ROOTDIR	512		/* Number of root directory entries for FAT12/16 */
+#define N_FATS		1		/* Number of FATs (1 or 2) */
+
+
+FRESULT f_mkfs (
+	const TCHAR* path,	/* Logical drive number */
+	BYTE sfd,			/* Partitioning rule 0:FDISK, 1:SFD */
+	UINT au				/* Size of allocation unit in unit of byte or sector */
+)
+{
+	static const WORD vst[] = { 1024,   512,  256,  128,   64,    32,   16,    8,    4,    2,   0};
+	static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512};
+	int vol;
+	BYTE fmt, md, sys, *tbl, pdrv, part;
+	DWORD n_clst, vs, n, wsect;
+	UINT i;
+	DWORD b_vol, b_fat, b_dir, b_data;	/* LBA */
+	DWORD n_vol, n_rsv, n_fat, n_dir;	/* Size */
+	FATFS *fs;
+	DSTATUS stat;
+#if FF_USE_TRIM
+	DWORD eb[2];
+#endif
+
+
+	/* Check mounted drive and clear work area */
+	if (sfd > 1) return FR_INVALID_PARAMETER;
+	vol = get_ldnumber(&path);
+	if (vol < 0) return FR_INVALID_DRIVE;
+	fs = FatFs[vol];
+	if (!fs) return FR_NOT_ENABLED;
+	fs->fs_type = 0;
+	pdrv = LD2PD(vol);	/* Physical drive */
+	part = LD2PT(vol);	/* Partition (0:auto detect, 1-4:get from partition table)*/
+
+	/* Get disk statics */
+	stat = disk_initialize(pdrv);
+	if (stat & STA_NOINIT) return FR_NOT_READY;
+	if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
+#if FF_MAX_SS != FF_MIN_SS		/* Get disk sector size */
+	if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS)
+		return FR_DISK_ERR;
+#endif
+	if (FF_MULTI_PARTITION && part) {
+		/* Get partition information from partition table in the MBR */
+		if (disk_read(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR;
+		if (LD_WORD(fs->win + BS_55AA) != 0xAA55) return FR_MKFS_ABORTED;
+		tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
+		if (!tbl[4]) return FR_MKFS_ABORTED;	/* No partition? */
+		b_vol = LD_DWORD(tbl + 8);	/* Volume start sector */
+		n_vol = LD_DWORD(tbl + 12);	/* Volume size */
+	} else {
+		/* Create a partition in this function */
+		if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128)
+			return FR_DISK_ERR;
+		b_vol = (sfd) ? 0 : 63;		/* Volume start sector */
+		n_vol -= b_vol;				/* Volume size */
+	}
+
+	if (au & (au - 1)) au = 0;
+	if (!au) {						/* AU auto selection */
+		vs = n_vol / (2000 / (SS(fs) / 512));
+		for (i = 0; vs < vst[i]; i++) ;
+		au = cst[i];
+	}
+	if (au >= FF_MIN_SS) au /= SS(fs);	/* Number of sectors per cluster */
+	if (!au) au = 1;
+	if (au > 128) au = 128;
+
+	/* Pre-compute number of clusters and FAT sub-type */
+	n_clst = n_vol / au;
+	fmt = FS_FAT12;
+	if (n_clst >= MIN_FAT16) fmt = FS_FAT16;
+	if (n_clst >= MIN_FAT32) fmt = FS_FAT32;
+
+	/* Determine offset and size of FAT structure */
+	if (fmt == FS_FAT32) {
+		n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs);
+		n_rsv = 32;
+		n_dir = 0;
+	} else {
+		n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4;
+		n_fat = (n_fat + SS(fs) - 1) / SS(fs);
+		n_rsv = 1;
+		n_dir = (DWORD)N_ROOTDIR * SZ_DIRE / SS(fs);
+	}
+	b_fat = b_vol + n_rsv;				/* FAT area start sector */
+	b_dir = b_fat + n_fat * N_FATS;		/* Directory area start sector */
+	b_data = b_dir + n_dir;				/* Data area start sector */
+	if (n_vol < b_data + au - b_vol) return FR_MKFS_ABORTED;	/* Too small volume */
+
+	/* Align data start sector to erase block boundary (for flash memory media) */
+	if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &n) != RES_OK || !n || n > 32768) n = 1;
+	n = (b_data + n - 1) & ~(n - 1);	/* Next nearest erase block from current data start */
+	n = (n - b_data) / N_FATS;
+	if (fmt == FS_FAT32) {		/* FAT32: Move FAT offset */
+		n_rsv += n;
+		b_fat += n;
+	} else {					/* FAT12/16: Expand FAT size */
+		n_fat += n;
+	}
+
+	/* Determine number of clusters and final check of validity of the FAT sub-type */
+	n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au;
+	if (   (fmt == FS_FAT16 && n_clst < MIN_FAT16)
+		|| (fmt == FS_FAT32 && n_clst < MIN_FAT32))
+		return FR_MKFS_ABORTED;
+
+	/* Determine system ID in the partition table */
+	if (fmt == FS_FAT32) {
+		sys = 0x0C;		/* FAT32X */
+	} else {
+		if (fmt == FS_FAT12 && n_vol < 0x10000) {
+			sys = 0x01;	/* FAT12(<65536) */
+		} else {
+			sys = (n_vol < 0x10000) ? 0x04 : 0x06;	/* FAT16(<65536) : FAT12/16(>=65536) */
+		}
+	}
+
+	if (FF_MULTI_PARTITION && part) {
+		/* Update system ID in the partition table */
+		tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE];
+		tbl[4] = sys;
+		if (disk_write(pdrv, fs->win, 0, 1) != RES_OK)	/* Write it to teh MBR */
+			return FR_DISK_ERR;
+		md = 0xF8;
+	} else {
+		if (sfd) {	/* No partition table (SFD) */
+			md = 0xF0;
+		} else {	/* Create partition table (FDISK) */
+			mem_set(fs->win, 0, SS(fs));
+			tbl = fs->win + MBR_Table;	/* Create partition table for single partition in the drive */
+			tbl[1] = 1;						/* Partition start head */
+			tbl[2] = 1;						/* Partition start sector */
+			tbl[3] = 0;						/* Partition start cylinder */
+			tbl[4] = sys;					/* System type */
+			tbl[5] = 254;					/* Partition end head */
+			n = (b_vol + n_vol) / 63 / 255;
+			tbl[6] = (BYTE)(n >> 2 | 63);	/* Partition end sector */
+			tbl[7] = (BYTE)n;				/* End cylinder */
+			ST_DWORD(tbl + 8, 63);			/* Partition start in LBA */
+			ST_DWORD(tbl + 12, n_vol);		/* Partition size in LBA */
+			ST_WORD(fs->win + BS_55AA, 0xAA55);	/* MBR signature */
+			if (disk_write(pdrv, fs->win, 0, 1) != RES_OK)	/* Write it to the MBR */
+				return FR_DISK_ERR;
+			md = 0xF8;
+		}
+	}
+
+	/* Create BPB in the VBR */
+	tbl = fs->win;							/* Clear sector */
+	mem_set(tbl, 0, SS(fs));
+	mem_cpy(tbl, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code, OEM name */
+	i = SS(fs);								/* Sector size */
+	ST_WORD(tbl + BPB_BytsPerSec, i);
+	tbl[BPB_SecPerClus] = (BYTE)au;			/* Sectors per cluster */
+	ST_WORD(tbl + BPB_RsvdSecCnt, n_rsv);	/* Reserved sectors */
+	tbl[BPB_NumFATs] = N_FATS;				/* Number of FATs */
+	i = (fmt == FS_FAT32) ? 0 : N_ROOTDIR;	/* Number of root directory entries */
+	ST_WORD(tbl + BPB_RootEntCnt, i);
+	if (n_vol < 0x10000) {					/* Number of total sectors */
+		ST_WORD(tbl + BPB_TotSec16, n_vol);
+	} else {
+		ST_DWORD(tbl + BPB_TotSec32, n_vol);
+	}
+	tbl[BPB_Media] = md;					/* Media descriptor */
+	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_vol);		/* Hidden sectors */
+	n = GET_FATTIME();						/* Use current time as VSN */
+	if (fmt == FS_FAT32) {
+		ST_DWORD(tbl + BS_VolID32, n);		/* VSN */
+		ST_DWORD(tbl + BPB_FATSz32, n_fat);	/* Number of sectors per FAT */
+		ST_DWORD(tbl + BPB_RootClus, 2);	/* Root directory start cluster (2) */
+		ST_WORD(tbl + BPB_FSInfo, 1);		/* FSINFO record offset (VBR + 1) */
+		ST_WORD(tbl + BPB_BkBootSec, 6);	/* Backup boot record offset (VBR + 6) */
+		tbl[BS_DrvNum32] = 0x80;			/* Drive number */
+		tbl[BS_BootSig32] = 0x29;			/* Extended boot signature */
+		mem_cpy(tbl + BS_VolLab32, "NO NAME    " "FAT32   ", 19);	/* Volume label, FAT signature */
+	} else {
+		ST_DWORD(tbl + BS_VolID, n);		/* VSN */
+		ST_WORD(tbl + BPB_FATSz16, n_fat);	/* Number of sectors 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 label, FAT signature */
+	}
+	ST_WORD(tbl + BS_55AA, 0xAA55);			/* Signature (Offset is fixed here regardless of sector size) */
+	if (disk_write(pdrv, tbl, b_vol, 1) != RES_OK)	/* Write it to the VBR sector */
+		return FR_DISK_ERR;
+	if (fmt == FS_FAT32)					/* Write it to the backup VBR if needed (VBR + 6) */
+		disk_write(pdrv, tbl, b_vol + 6, 1);
+
+	/* Initialize FAT area */
+	wsect = b_fat;
+	for (i = 0; i < N_FATS; i++) {		/* Initialize each FAT copy */
+		mem_set(tbl, 0, SS(fs));			/* 1st sector of the FAT  */
+		n = md;								/* Media descriptor byte */
+		if (fmt != FS_FAT32) {
+			n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00;
+			ST_DWORD(tbl + 0, n);			/* Reserve cluster #0-1 (FAT12/16) */
+		} else {
+			n |= 0xFFFFFF00;
+			ST_DWORD(tbl + 0, n);			/* Reserve cluster #0-1 (FAT32) */
+			ST_DWORD(tbl + 4, 0xFFFFFFFF);
+			ST_DWORD(tbl + 8, 0x0FFFFFFF);	/* Reserve cluster #2 for root directory */
+		}
+		if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
+			return FR_DISK_ERR;
+		mem_set(tbl, 0, SS(fs));			/* Fill following FAT entries with zero */
+		for (n = 1; n < n_fat; n++) {		/* This loop may take a time on FAT32 volume due to many single sector writes */
+			if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
+				return FR_DISK_ERR;
+		}
+	}
+
+	/* Initialize root directory */
+	i = (fmt == FS_FAT32) ? au : (UINT)n_dir;
+	do {
+		if (disk_write(pdrv, tbl, wsect++, 1) != RES_OK)
+			return FR_DISK_ERR;
+	} while (--i);
+
+#if FF_USE_TRIM	/* Erase data area if needed */
+	{
+		eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;
+		disk_ioctl(pdrv, CTRL_TRIM, eb);
+	}
+#endif
+
+	/* Create FSINFO if needed */
+	if (fmt == FS_FAT32) {
+		ST_DWORD(tbl + FSI_LeadSig, 0x41615252);
+		ST_DWORD(tbl + FSI_StrucSig, 0x61417272);
+		ST_DWORD(tbl + FSI_Free_Count, n_clst - 1);	/* Number of free clusters */
+		ST_DWORD(tbl + FSI_Nxt_Free, 2);			/* Last allocated cluster# */
+		ST_WORD(tbl + BS_55AA, 0xAA55);
+		disk_write(pdrv, tbl, b_vol + 1, 1);	/* Write original (VBR + 1) */
+		disk_write(pdrv, tbl, b_vol + 7, 1);	/* Write backup (VBR + 7) */
+	}
+
+	return (disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;
+}
+
+
+
+#if FF_MULTI_PARTITION
+/*-----------------------------------------------------------------------*/
+/* Create partition table on the physical drive                          */
+/*-----------------------------------------------------------------------*/
+
+FRESULT f_fdisk (
+	BYTE pdrv,			/* Physical drive number */
+	const DWORD szt[],	/* Pointer to the size table for each partitions */
+	void* work			/* Pointer to the working buffer */
+)
+{
+	UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl;
+	BYTE s_hd, e_hd, *p, *buf = (BYTE*)work;
+	DSTATUS stat;
+	DWORD sz_disk, sz_part, s_part;
+
+
+	stat = disk_initialize(pdrv);
+	if (stat & STA_NOINIT) return FR_NOT_READY;
+	if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
+	if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR;
+
+	/* Determine CHS in the table regardless of the drive geometry */
+	for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ;
+	if (n == 256) n--;
+	e_hd = n - 1;
+	sz_cyl = 63 * n;
+	tot_cyl = sz_disk / sz_cyl;
+
+	/* Create partition table */
+	mem_set(buf, 0, FF_MAX_SS);
+	p = buf + MBR_Table; b_cyl = 0;
+	for (i = 0; i < 4; i++, p += SZ_PTE) {
+		p_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl;
+		if (!p_cyl) continue;
+		s_part = (DWORD)sz_cyl * b_cyl;
+		sz_part = (DWORD)sz_cyl * p_cyl;
+		if (i == 0) {	/* Exclude first track of cylinder 0 */
+			s_hd = 1;
+			s_part += 63; sz_part -= 63;
+		} else {
+			s_hd = 0;
+		}
+		e_cyl = b_cyl + p_cyl - 1;
+		if (e_cyl >= tot_cyl) return FR_INVALID_PARAMETER;
+
+		/* Set partition table */
+		p[1] = s_hd;						/* Start head */
+		p[2] = (BYTE)((b_cyl >> 2) + 1);	/* Start sector */
+		p[3] = (BYTE)b_cyl;					/* Start cylinder */
+		p[4] = 0x06;						/* System type (temporary setting) */
+		p[5] = e_hd;						/* End head */
+		p[6] = (BYTE)((e_cyl >> 2) + 63);	/* End sector */
+		p[7] = (BYTE)e_cyl;					/* End cylinder */
+		ST_DWORD(p + 8, s_part);			/* Start sector in LBA */
+		ST_DWORD(p + 12, sz_part);			/* Partition size */
+
+		/* Next partition */
+		b_cyl += p_cyl;
+	}
+	ST_WORD(p, 0xAA55);
+
+	/* Write it to the MBR */
+	return (disk_write(pdrv, buf, 0, 1) != RES_OK || disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) ? FR_DISK_ERR : FR_OK;
+}
+
+
+#endif /* FF_MULTI_PARTITION */
+#endif /* FF_USE_MKFS && !FF_FS_READONLY */
+
+
+
+
+#if FF_USE_STRFUNC
+/*-----------------------------------------------------------------------*/
+/* Get a string from the file                                            */
+/*-----------------------------------------------------------------------*/
+
+TCHAR* f_gets (
+	TCHAR* buff,	/* Pointer to the string buffer to read */
+	int len,		/* Size of string buffer (characters) */
+	FIL* fp			/* Pointer to the file object */
+)
+{
+	int n = 0;
+	TCHAR c, *p = buff;
+	BYTE s[2];
+	UINT rc;
+
+
+	while (n < len - 1) {	/* Read characters until buffer gets filled */
+#if FF_USE_LFN && FF_LFN_UNICODE
+#if FF_STRF_ENCODE == 3		/* Read a character in UTF-8 */
+		f_read(fp, s, 1, &rc);
+		if (rc != 1) break;
+		c = s[0];
+		if (c >= 0x80) {
+			if (c < 0xC0) continue;	/* Skip stray trailer */
+			if (c < 0xE0) {			/* Two-byte sequence */
+				f_read(fp, s, 1, &rc);
+				if (rc != 1) break;
+				c = (c & 0x1F) << 6 | (s[0] & 0x3F);
+				if (c < 0x80) c = '?';
+			} else {
+				if (c < 0xF0) {		/* Three-byte sequence */
+					f_read(fp, s, 2, &rc);
+					if (rc != 2) break;
+					c = c << 12 | (s[0] & 0x3F) << 6 | (s[1] & 0x3F);
+					if (c < 0x800) c = '?';
+				} else {			/* Reject four-byte sequence */
+					c = '?';
+				}
+			}
+		}
+#elif FF_STRF_ENCODE == 2		/* Read a character in UTF-16BE */
+		f_read(fp, s, 2, &rc);
+		if (rc != 2) break;
+		c = s[1] + (s[0] << 8);
+#elif FF_STRF_ENCODE == 1		/* Read a character in UTF-16LE */
+		f_read(fp, s, 2, &rc);
+		if (rc != 2) break;
+		c = s[0] + (s[1] << 8);
+#else						/* Read a character in ANSI/OEM */
+		f_read(fp, s, 1, &rc);
+		if (rc != 1) break;
+		c = s[0];
+		if (IsDBCS1(c)) {
+			f_read(fp, s, 1, &rc);
+			if (rc != 1) break;
+			c = (c << 8) + s[0];
+		}
+		c = ff_convert(c, 1);	/* OEM -> Unicode */
+		if (!c) c = '?';
+#endif
+#else						/* Read a character without conversion */
+		f_read(fp, s, 1, &rc);
+		if (rc != 1) break;
+		c = s[0];
+#endif
+		if (FF_USE_STRFUNC == 2 && c == '\r') continue;	/* Strip '\r' */
+		*p++ = c;
+		n++;
+		if (c == '\n') break;		/* Break on EOL */
+	}
+	*p = 0;
+	return n ? buff : 0;			/* When no data read (eof or error), return with error. */
+}
+
+
+
+
+#if !FF_FS_READONLY
+/*-----------------------------------------------------------------------*/
+/* Put a character to the file                                           */
+/*-----------------------------------------------------------------------*/
+
+typedef struct {
+	FIL* fp;
+	int idx, nchr;
+	BYTE buf[64];
+} putbuff;
+
+
+static
+void putc_bfd (
+	putbuff* pb,
+	TCHAR c
+)
+{
+	UINT bw;
+	int i;
+
+
+	if (FF_USE_STRFUNC == 2 && c == '\n')	 /* LF -> CRLF conversion */
+		putc_bfd(pb, '\r');
+
+	i = pb->idx;	/* Buffer write index (-1:error) */
+	if (i < 0) return;
+
+#if FF_USE_LFN && FF_LFN_UNICODE
+#if FF_STRF_ENCODE == 3			/* Write a character in UTF-8 */
+	if (c < 0x80) {				/* 7-bit */
+		pb->buf[i++] = (BYTE)c;
+	} else {
+		if (c < 0x800) {		/* 11-bit */
+			pb->buf[i++] = (BYTE)(0xC0 | c >> 6);
+		} else {				/* 16-bit */
+			pb->buf[i++] = (BYTE)(0xE0 | c >> 12);
+			pb->buf[i++] = (BYTE)(0x80 | (c >> 6 & 0x3F));
+		}
+		pb->buf[i++] = (BYTE)(0x80 | (c & 0x3F));
+	}
+#elif FF_STRF_ENCODE == 2			/* Write a character in UTF-16BE */
+	pb->buf[i++] = (BYTE)(c >> 8);
+	pb->buf[i++] = (BYTE)c;
+#elif FF_STRF_ENCODE == 1			/* Write a character in UTF-16LE */
+	pb->buf[i++] = (BYTE)c;
+	pb->buf[i++] = (BYTE)(c >> 8);
+#else							/* Write a character in ANSI/OEM */
+	c = ff_convert(c, 0);	/* Unicode -> OEM */
+	if (!c) c = '?';
+	if (c >= 0x100)
+		pb->buf[i++] = (BYTE)(c >> 8);
+	pb->buf[i++] = (BYTE)c;
+#endif
+#else							/* Write a character without conversion */
+	pb->buf[i++] = (BYTE)c;
+#endif
+
+	if (i >= (int)(sizeof pb->buf) - 3) {	/* Write buffered characters to the file */
+		f_write(pb->fp, pb->buf, (UINT)i, &bw);
+		i = (bw == (UINT)i) ? 0 : -1;
+	}
+	pb->idx = i;
+	pb->nchr++;
+}
+
+
+
+int f_putc (
+	TCHAR c,	/* A character to be output */
+	FIL* fp		/* Pointer to the file object */
+)
+{
+	putbuff pb;
+	UINT nw;
+
+
+	pb.fp = fp;			/* Initialize output buffer */
+	pb.nchr = pb.idx = 0;
+
+	putc_bfd(&pb, c);	/* Put a character */
+
+	if (   pb.idx >= 0	/* Flush buffered characters to the file */
+		&& f_write(pb.fp, pb.buf, (UINT)pb.idx, &nw) == FR_OK
+		&& (UINT)pb.idx == nw) return pb.nchr;
+	return EOF;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Put a string to the file                                              */
+/*-----------------------------------------------------------------------*/
+
+int f_puts (
+	const TCHAR* str,	/* Pointer to the string to be output */
+	FIL* fp				/* Pointer to the file object */
+)
+{
+	putbuff pb;
+	UINT nw;
+
+
+	pb.fp = fp;				/* Initialize output buffer */
+	pb.nchr = pb.idx = 0;
+
+	while (*str)			/* Put the string */
+		putc_bfd(&pb, *str++);
+
+	if (   pb.idx >= 0		/* Flush buffered characters to the file */
+		&& f_write(pb.fp, pb.buf, (UINT)pb.idx, &nw) == FR_OK
+		&& (UINT)pb.idx == nw) return pb.nchr;
+	return EOF;
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Put a formatted string to the file                                    */
+/*-----------------------------------------------------------------------*/
+
+int f_vprintf (
+	FIL* fp,			/* Pointer to the file object */
+	const TCHAR* fmt,	/* Pointer to the format string */
+	va_list arp			/* Optional arguments... */
+)
+{
+	BYTE f, r;
+	UINT nw, i, j, w;
+	DWORD v;
+	TCHAR c, d, s[16], *p;
+	putbuff pb;
+
+
+	pb.fp = fp;				/* Initialize output buffer */
+	pb.nchr = pb.idx = 0;
+
+	for (;;) {
+		c = *fmt++;
+		if (c == 0) break;			/* End of string */
+		if (c != '%') {				/* Non escape character */
+			putc_bfd(&pb, c);
+			continue;
+		}
+		w = f = 0;
+		c = *fmt++;
+		if (c == '0') {				/* Flag: '0' padding */
+			f = 1; c = *fmt++;
+		} else {
+			if (c == '-') {			/* Flag: left justified */
+				f = 2; c = *fmt++;
+			}
+		}
+		while (IsDigit(c)) {		/* Precision */
+			w = w * 10 + c - '0';
+			c = *fmt++;
+		}
+		if (c == 'l' || c == 'L') {	/* Prefix: Size is long int */
+			f |= 4; c = *fmt++;
+		}
+		if (!c) break;
+		d = c;
+		if (IsLower(d)) d -= 0x20;
+		switch (d) {				/* Type is... */
+		case 'S' :					/* String */
+			p = va_arg(arp, TCHAR*);
+			for (j = 0; p[j]; j++) ;
+			if (!(f & 2)) {
+				while (j++ < w) putc_bfd(&pb, ' ');
+			}
+			while (*p) putc_bfd(&pb, *p++);
+			while (j++ < w) putc_bfd(&pb, ' ');
+			continue;
+		case 'C' :					/* Character */
+			putc_bfd(&pb, (TCHAR)va_arg(arp, int)); continue;
+		case 'B' :					/* Binary */
+			r = 2; break;
+		case 'O' :					/* Octal */
+			r = 8; break;
+		case 'D' :					/* Signed decimal */
+		case 'U' :					/* Unsigned decimal */
+			r = 10; break;
+		case 'X' :					/* Hexdecimal */
+			r = 16; break;
+		default:					/* Unknown type (pass-through) */
+			putc_bfd(&pb, c); continue;
+		}
+
+		/* Get an argument and put it in numeral */
+		v = (f & 4) ? (DWORD)va_arg(arp, long) : ((d == 'D') ? (DWORD)(long)va_arg(arp, int) : (DWORD)va_arg(arp, unsigned int));
+		if (d == 'D' && (v & 0x80000000)) {
+			v = 0 - v;
+			f |= 8;
+		}
+		i = 0;
+		do {
+			d = (TCHAR)(v % r); v /= r;
+			if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
+			s[i++] = d + '0';
+		} while (v && i < sizeof s / sizeof s[0]);
+		if (f & 8) s[i++] = '-';
+		j = i; d = (f & 1) ? '0' : ' ';
+		while (!(f & 2) && j++ < w) putc_bfd(&pb, d);
+		do putc_bfd(&pb, s[--i]); while (i);
+		while (j++ < w) putc_bfd(&pb, d);
+	}
+
+	if (   pb.idx >= 0		/* Flush buffered characters to the file */
+		&& f_write(pb.fp, pb.buf, (UINT)pb.idx, &nw) == FR_OK
+		&& (UINT)pb.idx == nw) return pb.nchr;
+	return EOF;
+}
+
+int f_printf (
+	FIL* fp,			/* Pointer to the file object */
+	const TCHAR* fmt,	/* Pointer to the format string */
+	...					/* Optional arguments... */
+)
+{
+	int ret;
+	va_list arp;
+
+	va_start(arp, fmt);
+	ret = f_vprintf(fp, fmt, arp);
+	va_end(arp);
+	
+	return ret;
+}
+
+#endif /* !FF_FS_READONLY */
+#endif /* FF_USE_STRFUNC */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ff.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ff.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ff.h	(revision 398)
@@ -0,0 +1,360 @@
+/*---------------------------------------------------------------------------/
+/  FatFs - FAT file system module include R0.11a    (C)ChaN, 2015
+/----------------------------------------------------------------------------/
+/ FatFs module is a free software that opened under license policy of
+/ following conditions.
+/
+/ Copyright (C) 2015, ChaN, all right reserved.
+/
+/ 1. Redistributions of source code must retain the above copyright notice,
+/    this condition and the following disclaimer.
+/
+/ This software is provided by the copyright holder and contributors "AS IS"
+/ and any warranties related to this software are DISCLAIMED.
+/ The copyright owner or contributors be NOT LIABLE for any damages caused
+/ by use of this software.
+/---------------------------------------------------------------------------*/
+
+
+#ifndef _FATFS
+#define _FATFS	64180	/* Revision ID */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+#include "integer.h"	/* Basic integer types */
+#include "ffconf.h"		/* FatFs configuration options */
+#include "diskio.h"
+#if _FATFS != FFCONF_DEF
+#error Wrong configuration file (ffconf.h).
+#endif
+
+
+
+/* Definitions of volume management */
+
+#if FF_MULTI_PARTITION		/* Multiple partition configuration */
+typedef struct {
+	BYTE pd;	/* Physical drive number */
+	BYTE pt;	/* Partition: 0:Auto detect, 1-4:Forced partition) */
+} PARTITION;
+extern PARTITION VolToPart[];	/* Volume - Partition resolution table */
+#define LD2PD(vol) (VolToPart[vol].pd)	/* Get physical drive number */
+#define LD2PT(vol) (VolToPart[vol].pt)	/* Get partition index */
+
+#else							/* Single partition configuration */
+#define LD2PD(vol) (BYTE)(vol)	/* Each logical drive is bound to the same physical drive number */
+#define LD2PT(vol) 0			/* Find first valid partition or in SFD */
+
+#endif
+
+
+
+/* Type of path name strings on FatFs API */
+
+#if FF_LFN_UNICODE			/* Unicode string */
+#if !FF_USE_LFN
+#error FF_LFN_UNICODE must be 0 at non-LFN cfg.
+#endif
+#ifndef _INC_TCHAR
+typedef WCHAR TCHAR;
+#define _T(x) L ## x
+#define _TEXT(x) L ## x
+#endif
+
+#else						/* ANSI/OEM string */
+#ifndef _INC_TCHAR
+typedef char TCHAR;
+#define _T(x) x
+#define _TEXT(x) x
+#endif
+
+#endif
+
+
+
+/* File system object structure (FATFS) */
+
+typedef struct {
+	BYTE	fs_type;		/* FAT sub-type (0:Not mounted) */
+	BYTE	drv;			/* Physical drive number */
+	BYTE	csize;			/* Sectors per cluster (1,2,4...128) */
+	BYTE	n_fats;			/* Number of FAT copies (1 or 2) */
+	BYTE	wflag;			/* win[] flag (b0:dirty) */
+	BYTE	fsi_flag;		/* FSINFO flags (b7:disabled, b0:dirty) */
+	WORD	id;				/* File system mount ID */
+	WORD	n_rootdir;		/* Number of root directory entries (FAT12/16) */
+#if FF_MAX_SS != FF_MIN_SS
+	WORD	ssize;			/* Bytes per sector (512, 1024, 2048 or 4096) */
+#endif
+#if FF_FS_REENTRANT
+	FF_SYNC_t	sobj;			/* Identifier of sync object */
+#endif
+#if !FF_FS_READONLY
+	DWORD	last_clust;		/* Last allocated cluster */
+	DWORD	free_clust;		/* Number of free clusters */
+#endif
+#if FF_FS_RPATH
+	DWORD	cdir;			/* Current directory start cluster (0:root) */
+#endif
+	DWORD	n_fatent;		/* Number of FAT entries, = number of clusters + 2 */
+	DWORD	fsize;			/* Sectors per FAT */
+	DWORD	volbase;		/* Volume start sector */
+	DWORD	fatbase;		/* FAT start sector */
+	DWORD	dirbase;		/* Root directory start sector (FAT32:Cluster#) */
+	DWORD	database;		/* Data start sector */
+	DWORD	winsect;		/* Current sector appearing in the win[] */
+	BYTE	win[FF_MAX_SS];	/* Disk access window for Directory, FAT (and file data at tiny cfg) */
+} FATFS;
+
+
+
+/* File object structure (FIL) */
+
+typedef struct {
+	FATFS*	fs;				/* Pointer to the related file system object (**do not change order**) */
+	WORD	id;				/* Owner file system mount ID (**do not change order**) */
+	BYTE	flag;			/* Status flags */
+	BYTE	err;			/* Abort flag (error code) */
+	DWORD	fptr;			/* File read/write pointer (Zeroed on file open) */
+	DWORD	fsize;			/* File size */
+	DWORD	sclust;			/* File start cluster (0:no cluster chain, always 0 when fsize is 0) */
+	DWORD	clust;			/* Current cluster of fpter (not valid when fprt is 0) */
+	DWORD	dsect;			/* Sector number appearing in buf[] (0:invalid) */
+#if !FF_FS_READONLY
+	DWORD	dir_sect;		/* Sector number containing the directory entry */
+	BYTE*	dir_ptr;		/* Pointer to the directory entry in the win[] */
+#endif
+#if FF_USE_FASTSEEK
+	DWORD*	cltbl;			/* Pointer to the cluster link map table (Nulled on file open) */
+#endif
+#if FF_FS_LOCK != 0
+	UINT	lockid;			/* File lock ID origin from 1 (index of file semaphore table Files[]) */
+#endif
+#if !FF_FS_TINY
+	BYTE	buf[FF_MAX_SS];	/* File private data read/write window */
+#endif
+} FIL;
+
+
+
+/* Directory object structure (FATFS_DIR) */
+
+typedef struct __dirstream {
+	FATFS*	fs;				/* Pointer to the owner file system object (**do not change order**) */
+	WORD	id;				/* Owner file system mount ID (**do not change order**) */
+	WORD	index;			/* Current read/write index number */
+	DWORD	sclust;			/* Table start cluster (0:Root dir) */
+	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 FF_FS_LOCK != 0
+	UINT	lockid;			/* File lock ID (index of file semaphore table Files[]) */
+#endif
+#if FF_USE_LFN
+	WCHAR*	lfn;			/* Pointer to the LFN working buffer */
+	WORD	lfn_idx;		/* Last matched LFN index number (0xFFFF:No LFN) */
+#endif
+#if FF_USE_FIND
+	const TCHAR*	pat;	/* Pointer to the name matching pattern */
+#endif
+} FATFS_DIR;
+
+
+
+/* File information structure (FILINFO) */
+
+typedef struct {
+	DWORD	fsize;			/* File size */
+	WORD	fdate;			/* Last modified date */
+	WORD	ftime;			/* Last modified time */
+	BYTE	fattrib;		/* Attribute */
+	TCHAR	fname[13];		/* Short file name (8.3 format) */
+#if FF_USE_LFN
+	TCHAR*	lfname;			/* Pointer to the LFN buffer */
+	UINT 	lfsize;			/* Size of LFN buffer in TCHAR */
+#endif
+} FILINFO;
+
+
+
+/* File function return code (FRESULT) */
+
+typedef enum {
+	FR_OK = 0,				/* (0) Succeeded */
+	FR_DISK_ERR,			/* (1) A hard error occurred in the low level disk I/O layer */
+	FR_INT_ERR,				/* (2) Assertion failed */
+	FR_NOT_READY,			/* (3) The physical drive cannot work */
+	FR_NO_FILE,				/* (4) Could not find the file */
+	FR_NO_PATH,				/* (5) Could not find the path */
+	FR_INVALID_NAME,		/* (6) The path name format is invalid */
+	FR_DENIED,				/* (7) Access denied due to prohibited access or directory full */
+	FR_EXIST,				/* (8) Access denied due to prohibited access */
+	FR_INVALID_OBJECT,		/* (9) The file/directory object is invalid */
+	FR_WRITE_PROTECTED,		/* (10) The physical drive is write protected */
+	FR_INVALID_DRIVE,		/* (11) The logical drive number is invalid */
+	FR_NOT_ENABLED,			/* (12) The volume has no work area */
+	FR_NO_FILESYSTEM,		/* (13) There is no valid FAT volume */
+	FR_MKFS_ABORTED,		/* (14) The f_mkfs() aborted due to any parameter error */
+	FR_TIMEOUT,				/* (15) Could not get a grant to access the volume within defined period */
+	FR_LOCKED,				/* (16) The operation is rejected according to the file sharing policy */
+	FR_NOT_ENOUGH_CORE,		/* (17) LFN working buffer could not be allocated */
+	FR_TOO_MANY_OPEN_FILES,	/* (18) Number of open files > FF_FS_LOCK */
+	FR_INVALID_PARAMETER	/* (19) Given parameter is invalid */
+} FRESULT;
+
+
+
+/*--------------------------------------------------------------*/
+/* FatFs module application interface                           */
+
+FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode);				/* Open or create a file */
+FRESULT f_close (FIL* fp);											/* Close an open file object */
+FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br);			/* Read data from a file */
+FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw);	/* Write data to a file */
+FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf);	/* Forward data to the stream */
+FRESULT f_lseek (FIL* fp, DWORD ofs);								/* Move file pointer of a file object */
+FRESULT f_truncate (FIL* fp);										/* Truncate file */
+FRESULT f_sync (FIL* fp);											/* Flush cached data of a writing file */
+FRESULT f_opendir (FATFS_DIR* dp, const TCHAR* path);						/* Open a directory */
+FRESULT f_closedir (FATFS_DIR* dp);										/* Close an open directory */
+FRESULT f_readdir (FATFS_DIR* dp, FILINFO* fno);							/* Read a directory item */
+FRESULT f_findfirst (FATFS_DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern);	/* Find first file */
+FRESULT f_findnext (FATFS_DIR* dp, FILINFO* fno);							/* Find next file */
+FRESULT f_mkdir (const TCHAR* path);								/* Create a sub directory */
+FRESULT f_unlink (const TCHAR* path);								/* Delete an existing file or directory */
+FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new);	/* Rename/Move a file or directory */
+FRESULT f_stat (const TCHAR* path, FILINFO* fno);					/* Get file status */
+FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask);			/* Change attribute of the file/dir */
+FRESULT f_utime (const TCHAR* path, const FILINFO* fno);			/* Change times-tamp of the file/dir */
+FRESULT f_chdir (const TCHAR* path);								/* Change current directory */
+FRESULT f_chdrive (const TCHAR* path);								/* Change current drive */
+FRESULT f_getcwd (TCHAR* buff, UINT len);							/* Get current directory */
+FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs);	/* Get number of free clusters on the drive */
+FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn);	/* Get volume label */
+FRESULT f_setlabel (const TCHAR* label);							/* Set volume label */
+FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt);			/* Mount/Unmount a logical drive */
+FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au);				/* Create a file system on the volume */
+FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void* work);			/* Divide a physical drive into some partitions */
+int f_putc (TCHAR c, FIL* fp);										/* Put a character to the file */
+int f_puts (const TCHAR* str, FIL* cp);								/* Put a string to the file */
+int f_vprintf (FIL* fp, const TCHAR* str, va_list arg);				/* Put a formatted string to the file */
+int f_printf (FIL* fp, const TCHAR* str, ...);						/* Put a formatted string to the file */
+TCHAR* f_gets (TCHAR* buff, int len, FIL* fp);						/* Get a string from the file */
+
+#define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
+#define f_error(fp) ((fp)->err)
+#define f_tell(fp) ((fp)->fptr)
+#define f_size(fp) ((fp)->fsize)
+#define f_rewind(fp) f_lseek((fp), 0)
+#define f_rewinddir(dp) f_readdir((dp), 0)
+#define f_flush(fp) (FR_OK)
+
+#define F_SEEK_SET 1
+#define F_SEEK_CUR 2
+#define F_SEEK_END 3
+FRESULT f_seek(FIL* fp, DWORD ofs, BYTE mode);
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+
+
+
+
+/*--------------------------------------------------------------*/
+/* Additional user defined functions                            */
+
+/* RTC function */
+#if !FF_FS_READONLY && !FF_FS_NORTC
+DWORD get_fattime (void);
+#endif
+
+/* Unicode support functions */
+#if FF_USE_LFN							/* Unicode - OEM code conversion */
+WCHAR ff_convert (WCHAR chr, UINT dir);	/* OEM-Unicode bidirectional conversion */
+WCHAR ff_wtoupper (WCHAR chr);			/* Unicode upper-case conversion */
+#if FF_USE_LFN == 3						/* Memory functions */
+void* ff_memalloc (UINT msize);			/* Allocate memory block */
+void ff_memfree (void* mblock);			/* Free memory block */
+#endif
+#endif
+
+/* Sync functions */
+#if FF_FS_REENTRANT
+int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj);	/* Create a sync object */
+int ff_req_grant (FF_SYNC_t sobj);				/* Lock sync object */
+void ff_rel_grant (FF_SYNC_t sobj);				/* Unlock sync object */
+int ff_del_syncobj (FF_SYNC_t sobj);				/* Delete a sync object */
+#endif
+
+
+
+
+/*--------------------------------------------------------------*/
+/* Flags and offset address                                     */
+
+
+/* File access control and file status flags (FIL.flag) */
+
+#define	FA_READ				0x01
+#define	FA_OPEN_EXISTING	0x00
+
+#if !FF_FS_READONLY
+#define	FA_WRITE			0x02
+#define	FA_CREATE_NEW		0x04
+#define	FA_CREATE_ALWAYS	0x08
+#define	FA_OPEN_ALWAYS		0x10
+#define	FA_OPEN_APPEND		0x30
+#define FA_MODIFIED			0x20
+#define FA_DIRTY			0x40
+#endif
+
+
+/* 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 */
+
+
+/* Fast seek feature */
+#define CREATE_LINKMAP	0xFFFFFFFF
+
+
+
+/*--------------------------------*/
+/* Multi-byte word access macros  */
+
+#if FF_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
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FATFS */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffarch.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffarch.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffarch.c	(revision 398)
@@ -0,0 +1,396 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2014-2017 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ */
+
+/* 
+ *  サンプルプログラム(1)の本体
+ */
+
+#include "shellif.h"
+#include <kernel.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "t_stdlib.h"
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "target_syssvc.h"
+#include "target_stddef.h"
+#include "kernel_cfg.h"
+#include "diskio.h"
+#include "mmc_rspi.h"
+#include "ff.h"
+#include "ffarch.h"
+#include <stdio.h>
+#include "gpio_api.h"
+#include "rtc_api.h"
+
+enum ffarch_state_t {
+	FFS_IDLE,
+	FFS_RETRY_WAIT,
+	FFS_DISABLE,
+};
+
+enum ffarch_state_t ffarch_state;
+volatile int ffarch_timer;
+int ffarch_retry_count;
+uint8_t mmc_rspi_prev_status;
+
+static void ffarch_initialize();
+
+/*
+ * FatFSタスク
+ */
+void ffarch_task(intptr_t exinf)
+{
+	ER ret, ret2;
+	SYSTIM prev, now;
+	int timer;
+
+	ffarch_initialize();
+
+	ret2 = get_tim(&now);
+	if (ret2 != E_OK){
+		syslog(LOG_NOTICE, "[ffarch] get_tim error: %s",
+			itron_strerror(ret2));
+		return;
+	}
+
+	for(;;){
+		prev = now;
+
+		/* タイマー取得 */
+		timer = ffarch_get_timer();
+
+		/* 待ち */
+		ret = tslp_tsk(timer);
+		if ((ret != E_OK) && (ret != E_TMOUT)) {
+			syslog(LOG_NOTICE, "[ffarch] tslp_tsk error: %s %d",
+				itron_strerror(ret), timer);
+			break;
+		}
+
+		ret2 = get_tim(&now);
+		if (ret2 != E_OK) {
+			syslog(LOG_NOTICE, "[ffarch] get_tim error: %s",
+				itron_strerror(ret2));
+			break;
+		}
+
+		/* 時間経過 */
+		int elapse = now - prev;
+		ffarch_progress(elapse);
+
+		/* タイムアウト処理 */
+		ffarch_timeout();
+	}
+}
+
+FATFS RomDisk;
+
+#define WP() false
+
+typedef struct SD {
+	DSTATUS dst;
+	BYTE type;
+	FATFS FatFs;
+} SD;
+SD Sd;
+
+bool_t romdisk_init();
+bool_t SD_begin();
+
+void ffarch_init(void)
+{
+#ifdef TOPPERS_GRCITRUS
+	ffarch_state = FFS_DISABLE;
+	ffarch_timer = TMO_FEVR;
+	mmc_rspi_prev_status = STA_NODISK;
+#else
+	ffarch_state = FFS_IDLE;
+	ffarch_timer = 0;
+	ffarch_retry_count = 3;
+	mmc_rspi_prev_status = STA_NODISK;
+
+	ffarch_timeout();
+
+	act_tsk(FFARCH_TASK);
+#endif
+	if (romdisk_init()) {
+		syslog(LOG_NOTICE, "ROM disk (0:) OK!");
+	}
+	else {
+		syslog(LOG_NOTICE, "ROM disk (0:) NG!");
+	}
+}
+
+void ffarch_initialize()
+{
+#ifdef TOPPERS_GRCITRUS
+	ffarch_state = FFS_DISABLE;
+	ffarch_timer = TMO_FEVR;
+	mmc_rspi_prev_status = STA_NODISK;
+#else
+	sta_cyc(MMC_RSPI_CYC);
+#endif
+}
+
+bool_t romdisk_init()
+{
+	DSTATUS dst;
+	FRESULT res;
+
+	if (RomDisk.fs_type != 0)
+		return true;
+
+	if ((dst = ramdisk_initialize()) != RES_OK) {
+		return false;
+	}
+
+	if ((res = f_mount(&RomDisk, "0:", 1)) != FR_OK) {
+		return false;
+	}
+
+	return true;
+}
+
+bool_t SD_begin()
+{
+	DSTATUS dst;
+	FRESULT res;
+	BYTE pdrv = 1, type;
+
+	if (Sd.FatFs.fs_type != 0)
+		return true;
+
+	if ((dst = disk_initialize(pdrv)) != RES_OK) {
+		return false;
+	}
+
+	if ((dst = disk_ioctl(pdrv, MMC_GET_TYPE, &type)) != RES_OK) {
+		Sd.dst = dst;
+		Sd.type = 0;
+	}
+	else {
+		Sd.dst = RES_OK;
+		Sd.type = type;
+	}
+
+	if ((res = f_mount(&Sd.FatFs, "1:", 1)) != FR_OK) {
+		return false;
+	}
+
+	return true;
+}
+
+DSTATUS disk_initialize(BYTE pdrv)
+{
+	switch (pdrv) {
+	case 0:
+		return ramdisk_initialize();
+	case 1:
+		return mmc_rspi_initialize();
+	}
+	return STA_NOINIT;
+}
+
+DSTATUS disk_status(BYTE pdrv)
+{
+	switch (pdrv) {
+	case 0:
+		return ramdisk_get_status();
+	case 1:
+		return mmc_rspi_status();
+	}
+	return STA_NOINIT;
+}
+
+DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
+{
+	switch (pdrv) {
+	case 0:
+		return ramdisk_read(buff, sector, count);
+	case 1:
+		return mmc_rspi_read(buff, sector, count);
+	}
+	return RES_PARERR;
+}
+
+DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
+{
+	switch (pdrv) {
+	case 0:
+		return ramdisk_write(buff, sector, count);
+	case 1:
+		return mmc_rspi_write(buff, sector, count);
+	}
+	return RES_PARERR;
+}
+
+DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
+{
+	switch (pdrv) {
+	case 0:
+		return RES_PARERR; /* ramdisk_ioctl(cmd, buff); */
+	case 1:
+		return mmc_rspi_ioctl(cmd, buff);
+	}
+	return RES_PARERR;
+}
+
+void mmc_rspi_status_changed(DSTATUS newst)
+{
+	if (ffarch_state == FFS_IDLE) {
+		mmc_rspi_prev_status = mmc_rspi_status();
+		ffarch_timer = 0;
+		wup_tsk(FFARCH_TASK);
+	}
+}
+
+int ffarch_get_timer(void)
+{
+	return ffarch_timer;
+}
+
+void ffarch_progress(int elapse)
+{
+	if (ffarch_timer != TMO_FEVR) {
+		ffarch_timer -= elapse;
+		if (ffarch_timer < 0) {
+			ffarch_timer = 0;
+		}
+	}
+}
+
+void ffarch_timeout(void)
+{
+	if (ffarch_timer != 0)
+		return;
+
+	switch (ffarch_state) {
+	case FFS_RETRY_WAIT:
+		if (ffarch_retry_count == 0) {
+			syslog(LOG_NOTICE, "SD card (1:) initialize tired...");
+
+			ffarch_state = FFS_IDLE;
+			ffarch_timer = TMO_FEVR;
+			ffarch_retry_count = 3;
+			break;
+		}
+		ffarch_retry_count--;
+		//goto case FFS_IDLE;
+	case FFS_IDLE:
+		/* SDカードが入れられた場合 */
+		if (((mmc_rspi_prev_status & STA_NODISK) != 0) && ((mmc_rspi_status() & STA_NODISK) == 0)) {
+			syslog(LOG_NOTICE, "SD card initializing ...");
+
+			Sd.FatFs.fs_type = 0;
+			if (SD_begin()) {
+				syslog(LOG_NOTICE, "SD card (1:) OK!");
+
+				/* uploadディレクトリを作成しておく */
+				f_mkdir("1:/upload");
+
+				ffarch_state = FFS_IDLE;
+				ffarch_timer = TMO_FEVR;
+				ffarch_retry_count = 3;
+			}
+			else {
+				syslog(LOG_NOTICE, "SD card (1:) NG!");
+				ffarch_state = FFS_RETRY_WAIT;
+				ffarch_timer = 1000 * 1000;
+			}
+		}
+		/* SDカードが抜かれた場合 */
+		else if (((mmc_rspi_prev_status & STA_NODISK) == 0) && ((mmc_rspi_status() & STA_NODISK) != 0)) {
+			syslog(LOG_NOTICE, "SD card unmount");
+
+			f_mount(&Sd.FatFs, "1:", 0);
+			ffarch_state = FFS_IDLE;
+			ffarch_timer = TMO_FEVR;
+			ffarch_retry_count = 3;
+		}
+		mmc_rspi_prev_status = mmc_rspi_status();
+		break;
+	}
+}
+
+int ff_cre_syncobj(BYTE vol, FF_SYNC_t* sobj)
+{
+	return 1;
+}
+
+int ff_req_grant(FF_SYNC_t sobj)
+{
+	ER ret;
+	ret = wai_sem(SEM_FILESYSTEM);
+	return ret == E_OK;
+}
+
+void ff_rel_grant(FF_SYNC_t sobj)
+{
+	sig_sem(SEM_FILESYSTEM);
+}
+
+int ff_del_syncobj(FF_SYNC_t sobj)
+{
+	return 1;
+}
+
+void* ff_memalloc (UINT msize)
+{
+	return malloc(msize);
+}
+
+void ff_memfree (void* mblock)
+{
+	free(mblock);
+}
+
+DWORD get_fattime(void)
+{
+	time_t temp;
+	struct tm _tm;
+
+	temp = rtc_read();
+	gmtime_r(&temp, &_tm);
+
+	return	  ((DWORD)(_tm.tm_year - 1980) << 25)
+		| ((DWORD)_tm.tm_mon << 21)
+		| ((DWORD)_tm.tm_mday << 16)
+		| ((DWORD)_tm.tm_hour << 11)
+		| ((DWORD)_tm.tm_min << 5)
+		| ((DWORD)_tm.tm_sec >> 1);
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffarch.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffarch.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffarch.cfg	(revision 398)
@@ -0,0 +1,44 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include "ffarch.h"
+
+CRE_TSK(FFARCH_TASK, { TA_NULL, 0, ffarch_task, FFARCH_PRIORITY, FFARCH_STACK_SIZE, NULL });
+INCLUDE("mmc_rspi.cfg");
+
+CRE_SEM(SEM_FILESYSTEM, { TA_TPRI, 1, 1 });
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffarch.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffarch.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffarch.h	(revision 398)
@@ -0,0 +1,51 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ */
+
+#ifndef _FFARCH_H_
+#define _FFARCH_H_
+
+#define FFARCH_PRIORITY			5
+#define FFARCH_STACK_SIZE		512
+
+void ffarch_init(void);
+void ffarch_task(intptr_t exinf);
+int ffarch_get_timer(void);
+void ffarch_progress(int elapse);
+void ffarch_timeout(void);
+
+void sdfs_cychdr(intptr_t exinf);
+
+#endif	/* of #ifndef _FFARCH_H_ */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffconf.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffconf.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/ffconf.h	(revision 398)
@@ -0,0 +1,286 @@
+/*---------------------------------------------------------------------------/
+/  FatFs - FAT file system module configuration file  R0.11a (C)ChaN, 2015
+/---------------------------------------------------------------------------*/
+
+#define FFCONF_DEF 64180	/* Revision ID */
+
+#define FFS_DBG			0
+
+/*---------------------------------------------------------------------------/
+/ Function Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_FS_READONLY	0
+/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
+/  Read-only configuration removes writing API functions, f_write(), f_sync(),
+/  f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
+/  and optional writing functions as well. */
+
+
+#define FF_FS_MINIMIZE	0
+/* This option defines minimization level to remove some basic API functions.
+/
+/   0: All basic functions are enabled.
+/   1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
+/      f_truncate() and f_rename() function are removed.
+/   2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
+/   3: f_lseek() function is removed in addition to 2. */
+
+
+#define	FF_USE_STRFUNC	1
+/* This option switches string functions, f_gets(), f_putc(), f_puts() and
+/  f_printf().
+/
+/  0: Disable string functions.
+/  1: Enable without LF-CRLF conversion.
+/  2: Enable with LF-CRLF conversion. */
+
+
+#define FF_USE_FIND		1
+/* This option switches filtered directory read feature and related functions,
+/  f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
+
+
+#define	FF_USE_MKFS		1
+/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
+
+
+#define	FF_USE_FASTSEEK	0
+/* This option switches fast seek feature. (0:Disable or 1:Enable) */
+
+
+#define FF_USE_LABEL		1
+/* This option switches volume label functions, f_getlabel() and f_setlabel().
+/  (0:Disable or 1:Enable) */
+
+
+#define	FF_USE_FORWARD	1
+/* This option switches f_forward() function. (0:Disable or 1:Enable)
+/  To enable it, also FF_FS_TINY need to be set to 1. */
+
+
+/*---------------------------------------------------------------------------/
+/ Locale and Namespace Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_CODE_PAGE 65001
+/* This option specifies the OEM code page to be used on the target system.
+/  Incorrect setting of the code page can cause a file open failure.
+/
+/   1   - ASCII (No extended character. Non-LFN cfg. only)
+/   437 - U.S.
+/   720 - Arabic
+/   737 - Greek
+/   771 - KBL
+/   775 - Baltic
+/   850 - Latin 1
+/   852 - Latin 2
+/   855 - Cyrillic
+/   857 - Turkish
+/   860 - Portuguese
+/   861 - Icelandic
+/   862 - Hebrew
+/   863 - Canadian French
+/   864 - Arabic
+/   865 - Nordic
+/   866 - Russian
+/   869 - Greek 2
+/   932 - Japanese (DBCS)
+/   936 - Simplified Chinese (DBCS)
+/   949 - Korean (DBCS)
+/   950 - Traditional Chinese (DBCS)
+*/
+
+
+#define	FF_USE_LFN	3
+#define	FF_MAX_LFN	255
+/* The FF_USE_LFN option switches the LFN feature.
+/
+/   0: Disable LFN feature. FF_MAX_LFN has no effect.
+/   1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
+/   2: Enable LFN with dynamic working buffer on the STACK.
+/   3: Enable LFN with dynamic working buffer on the HEAP.
+/
+/  When enable the LFN feature, Unicode handling functions (option/unicode.c) must
+/  be added to the project. The LFN working buffer occupies (FF_MAX_LFN + 1) * 2 bytes.
+/  When use stack for the working buffer, take care on stack overflow. When use heap
+/  memory for the working buffer, memory management functions, ff_memalloc() and
+/  ff_memfree(), must be added to the project. */
+
+
+#define	FF_LFN_UNICODE	0
+/* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode)
+/  To use Unicode string for the path name, enable LFN feature and set FF_LFN_UNICODE
+/  to 1. This option also affects behavior of string I/O functions. */
+
+
+#define FF_STRF_ENCODE	3
+/* When FF_LFN_UNICODE is 1, this option selects the character encoding on the file to
+/  be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
+/
+/  0: ANSI/OEM
+/  1: UTF-16LE
+/  2: UTF-16BE
+/  3: UTF-8
+/
+/  When FF_LFN_UNICODE is 0, this option has no effect. */
+
+
+#define FF_LFN_BUF		255
+#define FF_SFN_BUF		12
+/* This set of options defines size of file name members in the FILINFO structure
+/  which is used to read out directory items. These values should be suffcient for
+/  the file names to read. The maximum possible length of the read file name depends
+/  on character encoding. When LFN is not enabled, these options have no effect. */
+
+
+#define FF_FS_RPATH	2
+/* This option configures relative path feature.
+/
+/   0: Disable relative path feature and remove related functions.
+/   1: Enable relative path feature. f_chdir() and f_chdrive() are available.
+/   2: f_getcwd() function is available in addition to 1.
+/
+/  Note that directory items read via f_readdir() are affected by this option. */
+
+
+/*---------------------------------------------------------------------------/
+/ Drive/Volume Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_VOLUMES	4
+/* Number of volumes (logical drives) to be used. */
+
+
+#define FF_STR_VOLUME_ID	0
+#define FF_VOLUME_STRS	"RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
+/* FF_STR_VOLUME_ID option switches string volume ID feature.
+/  When FF_STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
+/  number in the path name. FF_VOLUME_STRS defines the drive ID strings for each
+/  logical drives. Number of items must be equal to FF_VOLUMES. Valid characters for
+/  the drive ID strings are: A-Z and 0-9. */
+
+
+#define	FF_MULTI_PARTITION	0
+/* This option switches multi-partition feature. By default (0), each logical drive
+/  number is bound to the same physical drive number and only an FAT volume found on
+/  the physical drive will be mounted. When multi-partition feature is enabled (1),
+/  each logical drive number is bound to arbitrary physical drive and partition
+/  listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
+
+
+#define	FF_MIN_SS		512
+#define	FF_MAX_SS		512
+/* These options configure the range of sector size to be supported. (512, 1024,
+/  2048 or 4096) Always set both 512 for most systems, all type of memory cards and
+/  harddisk. But a larger value may be required for on-board flash memory and some
+/  type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
+/  to variable sector size and GET_SECTOR_SIZE command must be implemented to the
+/  disk_ioctl() function. */
+
+
+#define	FF_USE_TRIM	0
+/* This option switches ATA-TRIM feature. (0:Disable or 1:Enable)
+/  To enable Trim feature, also CTRL_TRIM command should be implemented to the
+/  disk_ioctl() function. */
+
+
+#define FF_FS_NOFSINFO	0
+/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
+/  option, and f_getfree() function at first time after volume mount will force
+/  a full FAT scan. Bit 1 controls the use of last allocated cluster number.
+/
+/  bit0=0: Use free cluster count in the FSINFO if available.
+/  bit0=1: Do not trust free cluster count in the FSINFO.
+/  bit1=0: Use last allocated cluster number in the FSINFO if available.
+/  bit1=1: Do not trust last allocated cluster number in the FSINFO.
+*/
+
+
+
+/*---------------------------------------------------------------------------/
+/ System Configurations
+/---------------------------------------------------------------------------*/
+
+#define	FF_FS_TINY	1
+/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
+/  At the tiny configuration, size of the file object (FIL) is reduced FF_MAX_SS
+/  bytes. Instead of private sector buffer eliminated from the file object,
+/  common sector buffer in the file system object (FATFS) is used for the file
+/  data transfer. */
+
+
+#define FF_FS_NORTC	0
+#define FF_NORTC_MON	1
+#define FF_NORTC_MDAY	1
+#define FF_NORTC_YEAR	2015
+/* The FF_FS_NORTC option switches timestamp feature. If the system does not have
+/  an RTC function or valid timestamp is not needed, set FF_FS_NORTC to 1 to disable
+/  the timestamp feature. All objects modified by FatFs will have a fixed timestamp
+/  defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR.
+/  When timestamp feature is enabled (FF_FS_NORTC == 0), get_fattime() function need
+/  to be added to the project to read current time form RTC. FF_NORTC_MON,
+/  FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. 
+/  These options have no effect at read-only configuration (FF_FS_READONLY == 1). */
+
+
+#define	FF_FS_LOCK	0
+/* The FF_FS_LOCK option switches file lock feature to control duplicated file open
+/  and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
+/  is 1.
+/
+/  0:  Disable file lock feature. To avoid volume corruption, application program
+/      should avoid illegal open, remove and rename to the open objects.
+/  >0: Enable file lock feature. The value defines how many files/sub-directories
+/      can be opened simultaneously under file lock control. Note that the file
+/      lock feature is independent of re-entrancy. */
+
+
+#define FF_FS_REENTRANT	1
+#define FF_FS_TIMEOUT		1000
+#define	FF_SYNC_t			unsigned int
+/* The FF_FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs
+/  module itself. Note that regardless of this option, file access to different
+/  volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
+/  and f_fdisk() function, are always not re-entrant. Only file/directory access
+/  to the same volume is under control of this feature.
+/
+/   0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
+/   1: Enable re-entrancy. Also user provided synchronization handlers,
+/      ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
+/      function, must be added to the project. Samples are available in
+/      option/syscall.c.
+/
+/  The FF_FS_TIMEOUT defines timeout period in unit of time tick.
+/  The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
+/  SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
+/  included somewhere in the scope of ff.c. */
+
+
+#define FF_WORD_ACCESS	1
+/* The FF_WORD_ACCESS option is an only platform dependent option. It defines
+/  which access method is used to the word data on the FAT volume.
+/
+/   0: Byte-by-byte access. Always compatible with all platforms.
+/   1: Word access. Do not choose this unless under both the following conditions.
+/
+/  * Address misaligned memory access is always allowed to ALL instructions.
+/  * Byte order on the memory is little-endian.
+/
+/  If it is the case, FF_WORD_ACCESS can also be set to 1 to reduce code size.
+/  Following table shows allowable settings of some type of processors.
+/
+/  ARM7TDMI   0   *2          ColdFire   0    *1         V850E      0    *2
+/  Cortex-M3  0   *3          Z80        0/1             V850ES     0/1
+/  Cortex-M0  0   *2          x86        0/1             TLCS-870   0/1
+/  AVR        0/1             RX600(LE)  0/1             TLCS-900   0/1
+/  AVR32      0   *1          RL78       0    *2         R32C       0    *2
+/  PIC18      0/1             SH-2       0    *1         M16C       0/1
+/  PIC24      0   *2          H8S        0    *1         MSP430     0    *2
+/  PIC32      0   *1          H8/300H    0    *1         8051       0/1
+/
+/  *1:Big-endian.
+/  *2:Unaligned memory access is not supported.
+/  *3:Some compilers generate LDM/STM for mem_cpy function.
+*/
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/integer.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/integer.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/integer.h	(revision 398)
@@ -0,0 +1,33 @@
+/*-------------------------------------------*/
+/* Integer type definitions for FatFs module */
+/*-------------------------------------------*/
+
+#ifndef _FF_INTEGER
+#define _FF_INTEGER
+
+#if 0//def _WIN32	/* FatFs development platform */
+
+#include <windows.h>
+#include <tchar.h>
+
+#else			/* Embedded platform */
+#ifndef _WINNT_
+/* This type MUST be 8 bit */
+typedef unsigned char	BYTE;
+
+/* These types MUST be 16 bit */
+typedef short			SHORT;
+typedef unsigned short	WORD;
+typedef unsigned short	WCHAR;
+
+/* These types MUST be 16 bit or 32 bit */
+typedef int				INT;
+typedef unsigned int	UINT;
+
+/* These types MUST be 32 bit */
+typedef long			LONG;
+typedef unsigned long	DWORD;
+#endif
+#endif
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/mmc_rspi.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/mmc_rspi.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/mmc_rspi.c	(revision 398)
@@ -0,0 +1,766 @@
+/*------------------------------------------------------------------------*/
+/* FRK-RX62N: MMCv3/SDv1/SDv2 (SPI mode) Control Module                   */
+/*------------------------------------------------------------------------*/
+/*
+/  Copyright (C) 2014, ChaN, all right reserved.
+/
+/ * This software 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 products UNDER YOUR RESPONSIBILITY.
+/ * Redistributions of source code must retain the above copyright notice.
+/
+/-------------------------------------------------------------------------*/
+
+#include <kernel.h>	/* Platform dependent include file */
+#include "diskio.h"		/* Common include file for ff.c and disk layer */
+#include <sil.h>
+#include <prc_rename.h>
+#include "target_kernel_impl.h"
+#include "mmc_rspi.h"
+#include "kernel_cfg.h"
+#include <t_syslog.h>
+#include <string.h>
+
+static void CS_LOW()
+{
+	sil_wrb_mem(PORTC_PODR_ADDR, sil_reb_mem(PORTC_PODR_ADDR) & ~PORT_PODR_B0_BIT);		/* Set CS# low */
+}
+
+static void CS_HIGH()
+{
+	sil_wrb_mem(PORTC_PODR_ADDR, sil_reb_mem(PORTC_PODR_ADDR) | PORT_PODR_B0_BIT);		/* Set CS# high */
+}
+
+static bool_t WP()
+{
+	return false;
+}
+
+static bool_t INS()
+{
+	return (sil_reb_mem(PORT1_PIDR_ADDR) & PORT_PIDR_B5_BIT) == 0;
+}
+
+static void CTRL_INIT()
+{
+	/* CS=OUT */
+	sil_wrb_mem(PORTC_PDR_ADDR, sil_reb_mem(PORTC_PDR_ADDR) | PORT_PDR_B0_BIT);
+	/* INS=IN */
+	sil_wrb_mem(PORT1_PDR_ADDR, sil_reb_mem(PORT1_PDR_ADDR) & ~PORT_PDR_B5_BIT);
+	/* SPICLK,SPIMOSI=OUT */
+	sil_wrb_mem(PORTC_PDR_ADDR, sil_reb_mem(PORTC_PDR_ADDR) | PORT_PDR_B5_BIT | PORT_PDR_B6_BIT);
+	/* CS,SPICLK,SPIMOSI=HI */
+	sil_wrb_mem(PORTC_PODR_ADDR, sil_reb_mem(PORTC_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PDR_B5_BIT | PORT_PDR_B6_BIT);
+	/* SPIMISO=IN */
+	sil_wrb_mem(PORTC_PDR_ADDR, sil_reb_mem(PORTC_PDR_ADDR) & ~PORT_PDR_B7_BIT);
+	/* SPIMISO=PULLUP */
+	sil_wrb_mem(PORTC_PCR_ADDR, sil_reb_mem(PORTC_PDR_ADDR) | PORT_PDR_B7_BIT);
+	/* CMOSを選択 */
+	sil_wrb_mem(PORTC_ODR0_ADDR, 0x00);
+	/* CMOSを選択 */
+	sil_wrb_mem(PORTC_ODR1_ADDR, 0x00);
+}
+
+#define F_PCLK		48000000UL	/* PCLK frequency (configured by SCKCR.PCK) */
+#define SCLK_FAST	24000000UL	/* SCLK frequency (R/W) */
+#define SCLK_SLOW	375000UL	/* SCLK frequency (Init) */
+
+static void RSPI_ATTACH()
+{
+	/*
+	 * モジュールストップ機能の設定(RSPI0)
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRB_ADDR,
+		sil_rew_mem(SYSTEM_MSTPCRB_ADDR) & ~SYSTEM_MSTPCRB_MSTPB17_BIT);
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* 書込み禁止 */
+
+	/* P15をGPIOとして使用 */
+	sil_wrb_mem(PORT1_PMR_ADDR,
+		sil_reb_mem(PORT1_PMR_ADDR) & ~PORT_PMR_B5_BIT);
+	/* PC0をGPIOとして使用 */
+	sil_wrb_mem(PORTC_PMR_ADDR,
+		sil_reb_mem(PORTC_PMR_ADDR) & ~PORT_PMR_B0_BIT);
+	/* PC5, PC6, PC7を周辺機能として使用 */
+	sil_wrb_mem(PORTC_PMR_ADDR,
+		sil_reb_mem(PORTC_PMR_ADDR) | PORT_PMR_B5_BIT | PORT_PMR_B6_BIT | PORT_PMR_B7_BIT);
+
+	/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+	/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+	/* RSPCKAを選択 */
+	sil_wrb_mem(MPC_PC5PFS_ADDR, 0x0d);
+	/* MOSIAを選択 */
+	sil_wrb_mem(MPC_PC6PFS_ADDR, 0x0d);
+	/* MISOAを選択 */
+	sil_wrb_mem(MPC_PC7PFS_ADDR, 0x0d);
+
+	/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+	sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+}
+
+static void FCLK_FAST()
+{
+	/* RSPI機能を無効化 */
+	sil_wrb_mem(RSPI0_SPCR_ADDR,
+		sil_reb_mem(RSPI0_SPCR_ADDR) & ~RSPI_SPCR_SPE_BIT);
+	/* ビットレート設定 */
+	sil_wrb_mem(RSPI0_SPBR_ADDR, F_PCLK / 2 / SCLK_FAST - 1);
+	/* RSPI機能を有効化 */
+	sil_wrb_mem(RSPI0_SPCR_ADDR,
+		sil_reb_mem(RSPI0_SPCR_ADDR) | RSPI_SPCR_SPE_BIT);
+}
+
+#ifdef SIL_ENDIAN_LITTLE
+#define LDDW(x) rev_endian_uint32(x)	/* Little endian: swap bytes */
+#else
+#define LDDW(x) x		/* Big endian: no swap */
+#endif
+
+
+
+/*--------------------------------------------------------------------------
+
+   Module Private Functions
+
+---------------------------------------------------------------------------*/
+
+/* MMC/SD command */
+#define CMD0	(0)			/* GO_IDLE_STATE */
+#define CMD1	(1)			/* SEND_OP_COND (MMC) */
+#define	ACMD41	(0x80+41)	/* SEND_OP_COND (SDC) */
+#define CMD8	(8)			/* SEND_IF_COND */
+#define CMD9	(9)			/* SEND_CSD */
+#define CMD10	(10)		/* SEND_CID */
+#define CMD12	(12)		/* STOP_TRANSMISSION */
+#define ACMD13	(0x80+13)	/* SD_STATUS (SDC) */
+#define CMD16	(16)		/* SET_BLOCKLEN */
+#define CMD17	(17)		/* READ_SINGLE_BLOCK */
+#define CMD18	(18)		/* READ_MULTIPLE_BLOCK */
+#define CMD23	(23)		/* SET_BLOCK_COUNT (MMC) */
+#define	ACMD23	(0x80+23)	/* SET_WR_BLK_ERASE_COUNT (SDC) */
+#define CMD24	(24)		/* WRITE_BLOCK */
+#define CMD25	(25)		/* WRITE_MULTIPLE_BLOCK */
+#define CMD32	(32)		/* ERASE_ER_BLK_START */
+#define CMD33	(33)		/* ERASE_ER_BLK_END */
+#define CMD38	(38)		/* ERASE */
+#define CMD55	(55)		/* APP_CMD */
+#define CMD58	(58)		/* READ_OCR */
+
+
+
+static volatile
+DSTATUS Stat = STA_NOINIT;	/* Physical drive status */
+
+static volatile
+WORD Timer1, Timer2;	/* 1000Hz decrement timer stopped at zero (driven by disk_timerproc()) */
+
+static
+BYTE CardType;			/* Card type flags */
+
+static
+BYTE CSD[16], CID[16];
+
+static
+uint64_t CardCapacity;
+
+static
+uint32_t CardBlockSize;
+
+/*-----------------------------------------------------------------------*/
+/* Control SPI module                                                    */
+/*-----------------------------------------------------------------------*/
+/* Only these five functions are platform dependent. Any other functions */
+/* are portable to different system.                                     */
+
+/*---------------------------------*/
+/* Enable SPI and MMC/SDC controls */
+/*---------------------------------*/
+static
+void power_on(void)
+{
+	/* Initialize CS/INS/WP port */
+	CTRL_INIT();
+
+	/* Attach RSPI0 module to I/O pads, disable module stop */
+	RSPI_ATTACH();
+
+	/* Initialize RSPI module */
+	sil_wrb_mem(RSPI0_SPCR_ADDR, 0);		/* Stop RSPI module */
+	sil_wrb_mem(RSPI0_SPPCR_ADDR, 0);	/* Fixed idle value, disable loop-back mode */
+	sil_wrb_mem(RSPI0_SPSCR_ADDR, 0);	/* Disable sequence control */
+	sil_wrb_mem(RSPI0_SPDCR_ADDR, 0x20);	/* SPLW=1 */
+	sil_wrh_mem(RSPI0_SPCMD0_ADDR, 0x0700);	/* LSBF=0, SPB=7, BRDV=0, CPOL=0, CPHA=0 */
+	sil_wrb_mem(RSPI0_SPBR_ADDR, F_PCLK / 2 / SCLK_SLOW - 1);	/* Bit rate */
+	sil_wrb_mem(RSPI0_SPCR_ADDR, 0xC9);	/* Start RSPI in master mode */
+
+	ena_int(INTNO_MMC_RSPI_SPRI);
+	ena_int(INTNO_MMC_RSPI_SPTI);
+	ena_int(INTNO_MMC_RSPI_SPII);
+
+	/*sta_cyc(MMC_RSPI_CYC);*/
+}
+
+
+/*---------------------*/
+/*    Disable SPI      */
+/*---------------------*/
+static
+void power_off(void)	/* Disable MMC/SDC interface */
+{
+	/*stp_cyc(MMC_RSPI_CYC);*/
+
+	dis_int(INTNO_MMC_RSPI_SPRI);
+	dis_int(INTNO_MMC_RSPI_SPTI);
+	dis_int(INTNO_MMC_RSPI_SPII);
+
+	sil_wrb_mem(RSPI0_SPCR_ADDR, 0);		/* Stop RSPI module */
+}
+
+
+/*---------------------*/
+/* Send/Receive a byte */
+/*---------------------*/
+static
+BYTE xchg_spi(
+	BYTE dat	/* Data to send */
+	)
+{
+	sil_wrb_mem(RSPI0_SPSR_ADDR, 0xA0);
+	sil_wrw_mem(RSPI0_SPDR_ADDR, dat);			/* Start transmission (lower 8bits) */
+	/*while ((sil_reb_mem(RSPI0_SPSR_ADDR) & RSPI_SPSR_SPRF_BIT) == 0);	/* Wait for end of transfer */
+	if (twai_sem(MMC_RSPI_SEMAPHORE, 1000) != E_OK)
+		return 0;
+	return sil_rew_mem(RSPI0_SPDR_ADDR);			/* Returen received byte (lower 8bits) */
+}
+
+
+/*---------------------*/
+/* Send multiple bytes */
+/*---------------------*/
+static
+void xmit_spi_multi(
+	const BYTE *buff,	/* Pointer to the data */
+	UINT btx			/* Number of bytes to send (multiple of 4) */
+	)
+{
+	const DWORD *lp = (const DWORD*)buff;
+
+	sil_wrh_mem(RSPI0_SPCMD0_ADDR,
+		(sil_reh_mem(RSPI0_SPCMD0_ADDR) & ~RSPI_SPCMD_SPB_MASK) | (3 << RSPI_SPCMD_SPB_OFFSET));	/* Set 32-bit mode */
+
+	do {
+		sil_wrb_mem(RSPI0_SPSR_ADDR, 0xA0);
+		sil_wrw_mem(RSPI0_SPDR_ADDR, LDDW(*lp++));	/* Send four data bytes */
+		/*while ((sil_reb_mem(RSPI0_SPSR_ADDR) & RSPI_SPSR_SPRF_BIT) == 0);	/* Wait for end of transfer */
+		wai_sem(MMC_RSPI_SEMAPHORE);
+		sil_rew_mem(RSPI0_SPDR_ADDR);					/* Discard four received bytes */
+	} while (btx -= 4);					/* Repeat until all data sent */
+
+	sil_wrh_mem(RSPI0_SPCMD0_ADDR,
+		(sil_reh_mem(RSPI0_SPCMD0_ADDR) & ~RSPI_SPCMD_SPB_MASK) | (7 << RSPI_SPCMD_SPB_OFFSET));	/* Set 8-bit mode */
+}
+
+
+/*------------------------*/
+/* Receive multiple bytes */
+/*------------------------*/
+static
+void rcvr_spi_multi(
+	BYTE *buff,		/* Pointer to data buffer */
+	UINT btr		/* Number of bytes to receive (multiple of 4) */
+	)
+{
+	DWORD *lp = (DWORD*)buff;
+
+	sil_wrh_mem(RSPI0_SPCMD0_ADDR,
+		(sil_reh_mem(RSPI0_SPCMD0_ADDR) & ~RSPI_SPCMD_SPB_MASK) | (3 << RSPI_SPCMD_SPB_OFFSET));	/* Set 32-bit mode */
+
+	do {
+		sil_wrb_mem(RSPI0_SPSR_ADDR, 0xA0);
+		sil_wrw_mem(RSPI0_SPDR_ADDR, 0xFFFFFFFF);	/* Send four 0xFFs */
+		/*while ((sil_reb_mem(RSPI0_SPSR_ADDR) & RSPI_SPSR_SPRF_BIT) == 0);	/* Wait for end of transfer */
+		wai_sem(MMC_RSPI_SEMAPHORE);
+		*lp++ = LDDW(sil_rew_mem(RSPI0_SPDR_ADDR));	/* Store four received bytes */
+	} while (btr -= 4);					/* Repeat until all data received */
+
+	sil_wrh_mem(RSPI0_SPCMD0_ADDR,
+		(sil_reh_mem(RSPI0_SPCMD0_ADDR) & ~RSPI_SPCMD_SPB_MASK) | (7 << RSPI_SPCMD_SPB_OFFSET));	/* Set 8-bit mode */
+}
+
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Wait for card ready                                                   */
+/*-----------------------------------------------------------------------*/
+
+static
+int wait_ready(	/* 1:Ready, 0:Timeout */
+	UINT wt			/* Timeout [ms] */
+	)
+{
+	Timer2 = (WORD)wt;
+
+	do {
+		if (xchg_spi(0xFF) == 0xFF) return 1;	/* Card goes ready */
+		/* This loop takes a time. Insert rot_rdq() here for multitask envilonment. */
+	} while (Timer2);	/* Wait until card goes ready or timeout */
+
+	return 0;	/* Timeout occured */
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Deselect card and release SPI                                         */
+/*-----------------------------------------------------------------------*/
+
+static
+void deselect(void)
+{
+	CS_HIGH();		/* Set CS# high */
+	xchg_spi(0xFF);	/* Dummy clock (force DO hi-z for multiple slave SPI) */
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Select card and wait for ready                                        */
+/*-----------------------------------------------------------------------*/
+
+static
+int select(void)	/* 1:OK, 0:Timeout */
+{
+	CS_LOW();		/* Set CS# low */
+	xchg_spi(0xFF);	/* Dummy clock (force DO enabled) */
+
+	if (wait_ready(500)) return 1;	/* Wait for card ready */
+
+	deselect();
+	return 0;	/* Failed to select the card due to timeout */
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Receive a data packet from the MMC                                    */
+/*-----------------------------------------------------------------------*/
+
+static
+int rcvr_datablock(	/* 1:OK, 0:Error */
+	BYTE *buff,			/* Data buffer */
+	UINT btr			/* Data block length (byte) */
+	)
+{
+	BYTE token;
+
+
+	Timer1 = 200;
+	do {							/* Wait for DataStart token in timeout of 200ms */
+		token = xchg_spi(0xFF);
+		/* This loop will take a time. Insert rot_rdq() here for multitask envilonment. */
+	} while ((token == 0xFF) && Timer1);
+	if (token != 0xFE) return 0;	/* Function fails if invalid DataStart token or timeout */
+
+	rcvr_spi_multi(buff, btr);		/* Store trailing data to the buffer */
+	xchg_spi(0xFF); xchg_spi(0xFF);	/* Discard CRC */
+
+	return 1;						/* Function succeeded */
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Send a data packet to the MMC                                         */
+/*-----------------------------------------------------------------------*/
+
+#if _USE_WRITE
+static
+int xmit_datablock(	/* 1:OK, 0:Failed */
+	const BYTE *buff,	/* Ponter to 512 byte data to be sent */
+	BYTE token			/* Token */
+	)
+{
+	BYTE resp;
+
+
+	if (!wait_ready(500)) return 0;		/* Wait for card ready */
+
+	xchg_spi(token);					/* Send token */
+	if (token != 0xFD) {				/* Send data if token is other than StopTran */
+		xmit_spi_multi(buff, 512);		/* Data */
+		xchg_spi(0xFF); xchg_spi(0xFF);	/* Dummy CRC */
+
+		resp = xchg_spi(0xFF);			/* Receive data resp */
+		if ((resp & 0x1F) != 0x05)		/* Function fails if the data packet was not accepted */
+			return 0;
+	}
+	return 1;
+}
+#endif /* _USE_WRITE */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Send a command packet to the MMC                                      */
+/*-----------------------------------------------------------------------*/
+
+static
+BYTE send_cmd(		/* Return value: R1 resp (bit7==1:Failed to send) */
+	BYTE cmd,		/* Command index */
+	DWORD arg		/* Argument */
+	)
+{
+	BYTE n, res;
+
+
+	if (cmd & 0x80) {	/* Send a CMD55 prior to ACMD<n> */
+		cmd &= 0x7F;
+		res = send_cmd(CMD55, 0);
+		if (res > 1) return res;
+	}
+
+	/* Select the card and wait for ready except to stop multiple block read */
+	if (cmd != CMD12) {
+		deselect();
+		if (!select()) return 0xFF;
+	}
+
+	/* Send command packet */
+	xchg_spi(0x40 | cmd);			/* Start + command index */
+	xchg_spi((BYTE)(arg >> 24));	/* Argument[31..24] */
+	xchg_spi((BYTE)(arg >> 16));	/* Argument[23..16] */
+	xchg_spi((BYTE)(arg >> 8));		/* Argument[15..8] */
+	xchg_spi((BYTE)arg);			/* Argument[7..0] */
+	n = 0x01;						/* Dummy CRC + Stop */
+	if (cmd == CMD0) n = 0x95;		/* Valid CRC for CMD0(0) */
+	if (cmd == CMD8) n = 0x87;		/* Valid CRC for CMD8(0x1AA) */
+	xchg_spi(n);
+
+	/* Receive command resp */
+	if (cmd == CMD12) xchg_spi(0xFF);	/* Diacard stuff byte on CMD12 */
+	n = 10;							/* Wait for response (10 bytes max) */
+	do
+		res = xchg_spi(0xFF);
+	while ((res & 0x80) && --n);
+
+	return res;						/* Return received response */
+}
+
+
+
+/*--------------------------------------------------------------------------
+
+   Public Functions
+
+---------------------------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------------------*/
+/* Initialize disk drive                                                 */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS mmc_rspi_initialize()
+{
+	BYTE n, cmd, ty, ocr[4];
+
+	power_on();							/* Initialize RSPI */
+	for (n = 10; n; n--) xchg_spi(0xFF);/* Send 80 dummy clocks */
+
+	ty = 0;
+	if (send_cmd(CMD0, 0) == 1) {			/* Put the card SPI/Idle state */
+		Timer1 = 1000;						/* Initialization timeout = 1 sec */
+		if (send_cmd(CMD8, 0x1AA) == 1) {	/* SDv2? */
+			for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);	/* Get 32 bit return value of R7 resp */
+			if (ocr[2] == 0x01 && ocr[3] == 0xAA) {				/* Is the card supports vcc of 2.7-3.6V? */
+				while (Timer1 && send_cmd(ACMD41, 1UL << 30));	/* Wait for end of initialization with ACMD41(HCS) */
+				if (Timer1 && send_cmd(CMD58, 0) == 0) {		/* Check CCS bit in the OCR */
+					for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
+					ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* Card id SDv2 */
+				}
+			}
+		}
+		else {	/* Not SDv2 card */
+			if (send_cmd(ACMD41, 0) <= 1) {	/* SDv1 or MMC? */
+				ty = CT_SD1; cmd = ACMD41;	/* SDv1 (ACMD41(0)) */
+			}
+			else {
+				ty = CT_MMC; cmd = CMD1;	/* MMCv3 (CMD1(0)) */
+			}
+			while (Timer1 && send_cmd(cmd, 0));		/* Wait for end of initialization */
+			//if (!Timer1 || send_cmd(CMD16, 512) != 0)	/* Set block length: 512 */
+			//	ty = 0;
+		}
+		if (ty) {
+			if (send_cmd(CMD9, 0) == 0		/* READ_CSD */
+				&& rcvr_datablock(CSD, 16)){
+				/* CSD Ver.1.0 */
+				if ((CSD[0] & 0xC0) == 0) {
+					CardBlockSize = 1 << (CSD[5] & 0x0F);
+					CardCapacity = (((CSD[6] & 0x03) << 10) | (CSD[7] << 2) | ((CSD[8] & 0xC0) >> 6)) + 1;
+					CardCapacity *= (((uint64_t)1) << ((((CSD[9] & 0x03) << 1) | (CSD[10] & 0x80) >> 7) + 2));
+					CardCapacity *= (uint64_t)CardBlockSize;
+				}
+				else {
+					CardBlockSize = 512;
+					CardCapacity = ((uint64_t)((((CSD[7] & 0x3F) << 16) | (CSD[8] << 8) | CSD[9]) + 1)) * 512 * 1024;
+				}
+				if (send_cmd(CMD10, 0) != 0		/* READ_CID */
+					|| !rcvr_datablock(CID, 16)) {
+					ty = 0;
+				}
+			}
+			else {
+				ty = 0;
+			}
+		}
+	}
+	CardType = ty;	/* Card type */
+	deselect();
+
+	if (ty) {			/* OK */
+		FCLK_FAST();			/* Set fast clock */
+		Stat &= ~STA_NOINIT;	/* Clear STA_NOINIT flag */
+	}
+	else {			/* Failed */
+		power_off();
+		Stat = STA_NOINIT;
+	}
+
+	return Stat;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Get disk status                                                       */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS mmc_rspi_status()
+{
+	return Stat;	/* Return disk status */
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read sector(s)                                                        */
+/*-----------------------------------------------------------------------*/
+
+DRESULT mmc_rspi_read(
+	BYTE *buff,		/* Pointer to the data buffer to store read data */
+	DWORD sector,	/* Start sector number (LBA) */
+	UINT count		/* Number of sectors to read (1..128) */
+	)
+{
+	if (!count) return RES_PARERR;		/* Check parameter */
+	if (Stat & STA_NOINIT) return RES_NOTRDY;	/* Check if drive is ready */
+
+	if (!(CardType & CT_BLOCK)) sector *= 512;	/* LBA ot BA conversion (byte addressing cards) */
+
+	if (count == 1) {	/* Single sector read */
+		if ((send_cmd(CMD17, sector) == 0)	/* READ_SINGLE_BLOCK */
+			&& rcvr_datablock(buff, 512))
+			count = 0;
+	}
+	else {				/* Multiple sector read */
+		if (send_cmd(CMD18, sector) == 0) {	/* READ_MULTIPLE_BLOCK */
+			do {
+				if (!rcvr_datablock(buff, 512)) break;
+				buff += 512;
+			} while (--count);
+			send_cmd(CMD12, 0);				/* STOP_TRANSMISSION */
+		}
+	}
+	deselect();
+
+	return count ? RES_ERROR : RES_OK;	/* Return result */
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Write sector(s)                                                       */
+/*-----------------------------------------------------------------------*/
+
+#if _USE_WRITE
+DRESULT mmc_rspi_write(
+	const BYTE *buff,	/* Ponter to the data to write */
+	DWORD sector,		/* Start sector number (LBA) */
+	UINT count			/* Number of sectors to write (1..128) */
+	)
+{
+	if (!count) return RES_PARERR;		/* Check parameter */
+	if (Stat & STA_NOINIT) return RES_NOTRDY;	/* Check drive status */
+	if (Stat & STA_PROTECT) return RES_WRPRT;	/* Check write protect */
+
+	if (!(CardType & CT_BLOCK)) sector *= 512;	/* LBA ==> BA conversion (byte addressing cards) */
+
+	if (count == 1) {	/* Single sector write */
+		if ((send_cmd(CMD24, sector) == 0)	/* WRITE_BLOCK */
+			&& xmit_datablock(buff, 0xFE))
+			count = 0;
+	}
+	else {				/* Multiple sector write */
+		if (CardType & CT_SDC) send_cmd(ACMD23, count);
+		if (send_cmd(CMD25, sector) == 0) {	/* WRITE_MULTIPLE_BLOCK */
+			do {
+				if (!xmit_datablock(buff, 0xFC)) break;
+				buff += 512;
+			} while (--count);
+			if (!xmit_datablock(0, 0xFD))	/* STOP_TRAN token */
+				count = 1;
+		}
+	}
+	deselect();
+
+	return count ? RES_ERROR : RES_OK;	/* Return result */
+}
+#endif /* _USE_WRITE */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Miscellaneous drive controls other than data read/write               */
+/*-----------------------------------------------------------------------*/
+
+#if _USE_IOCTL
+DRESULT mmc_rspi_ioctl(
+	BYTE ctrl,		/* Control command code */
+	void *buff		/* Pointer to the conrtol data */
+	)
+{
+	DRESULT res;
+	BYTE n, csd[16], *ptr = buff;
+	DWORD *dp, st, ed;
+
+
+	if (Stat & STA_NOINIT) return RES_NOTRDY;	/* Check if drive is ready */
+
+	res = RES_ERROR;
+
+	switch (ctrl) {
+	case CTRL_SYNC:		/* Wait for end of internal write process of the drive */
+		if (select()) res = RES_OK;
+		break;
+
+	case GET_SECTOR_SIZE:
+		*(WORD*)buff = 512;
+		res = RES_OK;
+		break;
+
+	case GET_SECTOR_COUNT:
+		*(DWORD*)buff = CardCapacity / 512;
+		res = RES_OK;
+		break;
+
+	case GET_BLOCK_SIZE:
+		*(DWORD*)buff = CardBlockSize;
+		res = RES_OK;
+		break;
+
+	case CTRL_TRIM:	/* Erase a block of sectors (used when FF_USE_TRIM == 1) */
+		if (!(CardType & CT_SDC)) break;				/* Check if the card is SDC */
+		if (mmc_rspi_ioctl(MMC_GET_CSD, csd)) break;	/* Get CSD */
+		if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break;	/* Check if sector erase can be applied to the card */
+		dp = buff; st = dp[0]; ed = dp[1];				/* Load sector block */
+		if (!(CardType & CT_BLOCK)) {
+			st *= 512; ed *= 512;
+		}
+		if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000))	/* Erase sector block */
+			res = RES_OK;
+		break;
+
+		/* Following command are not used by FatFs module */
+
+	case MMC_GET_TYPE:		/* Get MMC/SDC type (BYTE) */
+		*ptr = CardType;
+		res = RES_OK;
+		break;
+
+	case MMC_GET_CSD:		/* Read CSD (16 bytes) */
+		memcpy(ptr, CSD, sizeof(CSD));
+		res = RES_OK;
+		break;
+
+	case MMC_GET_CID:		/* Read CID (16 bytes) */
+		memcpy(ptr, CID, sizeof(CID));
+		res = RES_OK;
+		break;
+
+	case MMC_GET_OCR:		/* Read OCR (4 bytes) */
+		if (send_cmd(CMD58, 0) == 0) {	/* READ_OCR */
+			for (n = 4; n; n--) *ptr++ = xchg_spi(0xFF);
+			res = RES_OK;
+		}
+		break;
+
+	case MMC_GET_SDSTAT:	/* Read SD status (64 bytes) */
+		if (send_cmd(ACMD13, 0) == 0) {	/* SD_STATUS */
+			xchg_spi(0xFF);
+			if (rcvr_datablock(ptr, 64))
+				res = RES_OK;
+		}
+		break;
+
+	default:
+		res = RES_PARERR;
+	}
+
+	deselect();
+
+	return res;
+}
+#endif /* _USE_IOCTL */
+
+
+/*-----------------------------------------------------------------------*/
+/* Device timer function                                                 */
+/*-----------------------------------------------------------------------*/
+/* This function must be called from system timer process
+/  in period of 1 ms to generate card control timing.
+*/
+
+void mmc_rspi_cychdr(intptr_t exinf)
+{
+	WORD n;
+	BYTE s;
+
+
+	n = Timer1;						/* 1kHz decrement timer stopped at 0 */
+	if (n) Timer1 = --n;
+	n = Timer2;
+	if (n) Timer2 = --n;
+
+	s = Stat;
+	if (WP())		/* Write protected */
+		s |= STA_PROTECT;
+	else		/* Write enabled */
+		s &= ~STA_PROTECT;
+	if (INS())	/* Card is in socket */
+		s &= ~STA_NODISK;
+	else		/* Socket empty */
+		s |= (STA_NODISK | STA_NOINIT);
+
+	if (Stat != s) {
+		mmc_rspi_status_changed(s);
+		Stat = s;
+	}
+}
+
+void mmc_rspi_spri_handler(void)
+{
+	isig_sem(MMC_RSPI_SEMAPHORE);
+}
+
+void mmc_rspi_spti_handler(void)
+{
+}
+
+void mmc_rspi_spii_handler(void)
+{
+}
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/mmc_rspi.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/mmc_rspi.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/mmc_rspi.cfg	(revision 398)
@@ -0,0 +1,54 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#include "mmc_rspi.h"
+
+/* 割り込みハンドラ */
+
+DEF_INH(INHNO_MMC_RSPI_SPRI, { TA_HLNG, mmc_rspi_spri_handler });
+CFG_INT(INTNO_MMC_RSPI_SPRI, { INTATR_MMC_RSPI_SPRI, INTPRI_MMC_RSPI_SPRI });
+
+DEF_INH(INHNO_MMC_RSPI_SPTI, { TA_HLNG, mmc_rspi_spti_handler });
+CFG_INT(INTNO_MMC_RSPI_SPTI, { INTATR_MMC_RSPI_SPTI, INTPRI_MMC_RSPI_SPTI });
+
+DEF_INH(INHNO_MMC_RSPI_SPII, { TA_HLNG, mmc_rspi_spii_handler });
+CFG_INT(INTNO_MMC_RSPI_SPII, { INTATR_MMC_RSPI_SPII, INTPRI_MMC_RSPI_SPII });
+
+CRE_CYC(MMC_RSPI_CYC, { TA_NULL, { TNFY_HANDLER, 0, mmc_rspi_cychdr }, 1000000, 0 });
+
+CRE_SEM(MMC_RSPI_SEMAPHORE, { TA_TPRI, 0, 1 });
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/mmc_rspi.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/mmc_rspi.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/fatfs/mmc_rspi.h	(revision 398)
@@ -0,0 +1,75 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _MMC_RSPI_H_
+#define _MMC_RSPI_H_
+
+#include "t_stddef.h"
+#include "diskio.h"
+
+#define INHNO_MMC_RSPI_SPRI		INT_RSPI0_SPRI0	/* 受信割り込み */
+#define INTNO_MMC_RSPI_SPRI		INT_RSPI0_SPRI0	/* 受信割り込み */
+#define INTATR_MMC_RSPI_SPRI	(TA_NULL)		/* 割込み属性	*/
+#define INTPRI_MMC_RSPI_SPRI	(-1)			/* 割込み優先度	*/
+
+#define INHNO_MMC_RSPI_SPTI		INT_RSPI0_SPTI0	/* 送信割り込み */
+#define INTNO_MMC_RSPI_SPTI		INT_RSPI0_SPTI0	/* 送信割り込み */
+#define INTATR_MMC_RSPI_SPTI	(TA_NULL)		/* 割込み属性	*/
+#define INTPRI_MMC_RSPI_SPTI	(-1)			/* 割込み優先度	*/
+
+#define INHNO_MMC_RSPI_SPII		INT_RSPI0_SPII0	/* アイドル割り込み */
+#define INTNO_MMC_RSPI_SPII		INT_RSPI0_SPII0	/* アイドル割り込み */
+#define INTATR_MMC_RSPI_SPII	(TA_NULL)		/* 割込み属性	*/
+#define INTPRI_MMC_RSPI_SPII	(-1)			/* 割込み優先度	*/
+
+DSTATUS mmc_rspi_initialize ();
+DSTATUS mmc_rspi_status ();
+DRESULT mmc_rspi_read (BYTE* buff, DWORD sector, UINT count);
+#if	_USE_WRITE
+DRESULT mmc_rspi_write (const BYTE* buff, DWORD sector, UINT count);
+#endif
+#if	_USE_IOCTL
+DRESULT mmc_rspi_ioctl (BYTE cmd, void* buff);
+#endif
+
+void mmc_rspi_spri_handler(void);
+void mmc_rspi_spti_handler(void);
+void mmc_rspi_spii_handler(void);
+void mmc_rspi_cychdr(intptr_t exinf);
+void mmc_rspi_status_changed(DSTATUS newst);
+
+#endif /* _MMC_RSPI_H_ */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntconf.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntconf.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntconf.h	(revision 398)
@@ -0,0 +1,52 @@
+/**
+ * @file ntconf.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 NTCONF_H
+#define NTCONF_H
+
+/**
+ * @note
+ * This file provides internal definitions for inner modules.
+ */
+
+/**
+ * @brief Maximum length for the editor module.
+ */
+#define NTCONF_EDITOR_MAXLEN    (256)
+
+/**
+ * @brief Maximum depth for the history module.
+ */
+#define NTCONF_HISTORY_DEPTH    (8)
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntint.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntint.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntint.h	(revision 398)
@@ -0,0 +1,55 @@
+/**
+ * @file ntint.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 NTINT_H
+#define NTINT_H
+
+/**
+ * @note
+ * This file provides integer definitions.
+ * You can use #include <stdint.h> if your tool chain have the header.
+ */
+
+#if 1
+#   include <stdint.h>
+#else
+    typedef unsigned char uint8_t;
+    typedef unsigned short uint16_t;
+    typedef unsigned int uint32_t;
+    typedef char int8_t;
+    typedef short int16_t;
+    typedef int int32_t;
+    typedef unsigned int size_t;
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntlibc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntlibc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntlibc.c	(revision 398)
@@ -0,0 +1,337 @@
+/**
+ * @file ntlibc.c
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 "ntlibc.h"
+
+int ntlibc_strlen(const char *s)
+{
+	const char *p = s;
+	int cnt = 0;
+	while (*p) {
+		cnt++;
+		p++;
+	}
+	return cnt;
+}
+
+char *ntlibc_strcpy(char *des, const char *src)
+{
+	char *d = des;
+	const char *s = src;
+	while (*s) {
+		*d = *s;
+		d++;
+		s++;
+	}
+	*d = '\0';
+	return des;
+}
+
+int ntlibc_strlcpy(char *des, const char *src, int n)
+{
+	char *d = des, *e = &des[n];
+	const char *s = src;
+	while (*s && d < e) {
+		*d = *s;
+		d++;
+		s++;
+	}
+	*d++ = '\0';
+	return (int)d - (int)des;
+}
+
+char *ntlibc_strcat(char *des, const char *src)
+{
+	char *d = des;
+	const char *s = src;
+	while (*d) {
+		d++;
+	}
+	while (*s) {
+		*d = *s;
+		d++;
+		s++;
+	}
+	*d = '\0';
+	return des;
+}
+
+int ntlibc_strlcat(char *des, const char *src, int n)
+{
+	char *d = des, *e = &des[n];
+	const char *s = src;
+	while (*d && d < e) {
+		d++;
+	}
+	while (*s && d < e) {
+		*d = *s;
+		d++;
+		s++;
+	}
+	*d++ = '\0';
+	return (int)d - (int)des;
+}
+#ifdef _MSC_VER
+int strlcat(char *des, const char *src, int n)
+{
+	return ntlibc_strlcat(des, src, n);
+}
+#endif
+int ntlibc_strcmp(const char *s1, const char *s2)
+{
+	char *p1 = (char *)s1;
+	char *p2 = (char *)s2;
+	while (*p1 || *p2) {
+		if (*p1 != *p2) {
+			return (*p1 < *p2) ? -1 : 1;
+		}
+		p1++;
+		p2++;
+	}
+	if (*p1 == *p2) {
+		return 0;
+	}
+	else {
+		return (*p1 < *p2) ? -1 : 1;
+	}
+}
+
+int ntlibc_stricmp(const char *s1, const char *s2)
+{
+	char *p1 = (char *)s1;
+	char *p2 = (char *)s2;
+	while (*p1 || *p2) {
+		if (ntlibc_toupper(*p1) != ntlibc_toupper(*p2)) {
+			return (*p1 < *p2) ? -1 : 1;
+		}
+		p1++;
+		p2++;
+	}
+	if (*p1 == *p2) {
+		return 0;
+	}
+	else {
+		return (*p1 < *p2) ? -1 : 1;
+	}
+}
+
+int ntlibc_strncmp(const char *s1, const char *s2, int n)
+{
+	char *p1 = (char *)s1;
+	char *p2 = (char *)s2;
+	int len = 0;
+	while (*p1 || *p2) {
+		if (n <= len) {
+			break;
+		}
+		if (*p1 != *p2) {
+			return (*p1 < *p2) ? -1 : 1;
+		}
+		p1++;
+		p2++;
+		len++;
+	}
+	return 0;
+}
+
+int ntlibc_isdigit(int c)
+{
+	if (('0' <= c) && (c <= '9')) {
+		return 1;
+	}
+	return 0;
+}
+
+int ntlibc_isalpha(int c)
+{
+	if (('A' <= c) && (c <= 'Z')) {
+		return 1;
+	}
+	if (('a' <= c) && (c <= 'z')) {
+		return 1;
+	}
+	return 0;
+}
+
+int ntlibc_iscntrl(int c)
+{
+	if (c == 0x07) { return 0; }
+	if (c == 0x08) { return 0; }
+	if (c == 0x09) { return 0; }
+	if (c == 0x0a) { return 0; }
+	if (c == 0x0b) { return 0; }
+	if (c == 0x0c) { return 0; }
+	if (c == 0x0d) { return 0; }
+	if ((0x00 <= c) && (c <= 0x1f)) {
+		return 1;
+	}
+	return 0;
+}
+
+int ntlibc_toupper(int c)
+{
+	if (('a' <= c) && (c <= 'z')) {
+		int diff = 'a' - 'A';
+		return c - diff;
+	}
+	return c;
+}
+
+int ntlibc_tolower(int c)
+{
+	if (('A' <= c) && (c <= 'Z')) {
+		int diff = 'a' - 'A';
+		return c + diff;
+	}
+	return c;
+}
+
+int ntlibc_atoi(const char *nptr)
+{
+	int cnt;
+	int num = 0;
+	int ofs = 0;
+	int sign = 0;
+	int scnt = 0;
+	char *p = (char *)nptr;
+	while (*p != '\0') {
+		if (!ntlibc_isdigit(*p)) {
+			if (*p == ' ') {
+				ofs++;
+			}
+			if (*p == '+') {
+				sign = 0;
+				ofs++;
+				if (scnt++ > 0) {
+					return 0;
+				}
+			}
+			if (*p == '-') {
+				sign = 1;
+				ofs++;
+				if (scnt++ > 0) {
+					return 0;
+				}
+			}
+		}
+		p++;
+	}
+	for (cnt = ofs; (nptr[cnt] >= '0') && (nptr[cnt] <= '9'); cnt++) {
+		num = 10 * num + (nptr[cnt] - '0');
+	}
+	if (sign) {
+		return -num;
+	}
+	else {
+		return num;
+	}
+}
+
+unsigned long ntlibc_strtoul(const char *__restrict nptr, char **__restrict endptr, int base)
+{
+	int cnt;
+	int num = 0;
+	int ofs = 0;
+	int sign = 0;
+	int scnt = 0;
+	char *p = (char *)nptr;
+	while (*p != '\0') {
+		if (!ntlibc_isdigit(*p)) {
+			if (*p == ' ') {
+				ofs++;
+			}
+			if (*p == '+') {
+				sign = 0;
+				ofs++;
+				if (scnt++ > 0) {
+					*endptr = p;
+					break;
+				}
+			}
+			if (*p == '-') {
+				sign = 1;
+				ofs++;
+				if (scnt++ > 0) {
+					*endptr = p;
+					break;
+				}
+			}
+			*endptr = p;
+			break;
+		}
+		p++;
+	}
+	for (cnt = ofs; (nptr[cnt] >= '0') && (nptr[cnt] <= '9'); cnt++) {
+		num = 10 * num + (nptr[cnt] - '0');
+	}
+	if (sign) {
+		return -num;
+	}
+	else {
+		return num;
+	}
+}
+
+char *ntlibc_strchr(const char *s, int c)
+{
+	char *p = (char *)s;
+	for (;;) {
+		if (*p == c) {
+			return p;
+		}
+		if (!*p)
+			break;
+		p++;
+	}
+	return 0;
+}
+
+char *ntlibc_utoa(unsigned int value, char *s, int radix)
+{
+	char *s1 = s;
+	char *s2 = s;
+
+	do {
+		*s2++ = "0123456789abcdefghijklmnopqrstuvwxyz"[value % radix];
+		value /= radix;
+	} while (value > 0);
+
+	*s2-- = '\0';
+
+	while (s1 < s2) {
+		char c = *s1;
+		*s1++ = *s2;
+		*s2-- = c;
+	}
+
+	return s;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntlibc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntlibc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntlibc.h	(revision 398)
@@ -0,0 +1,63 @@
+/**
+ * @file ntlibc.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 NTLIBC_H
+#define NTLIBC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ntlibc_strlen(const char *s);
+char *ntlibc_strcpy(char *des, const char *src);
+int ntlibc_strlcpy(char *des, const char *src, int n);
+char *ntlibc_strcat(char *des, const char *src);
+int ntlibc_strlcat(char *des, const char *src, int n);
+int ntlibc_strcmp(const char *s1, const char *s2);
+int ntlibc_stricmp(const char *s1, const char *s2);
+int ntlibc_strncmp(const char *s1, const char *s2, int n);
+int ntlibc_isdigit(int c);
+int ntlibc_isalpha(int c);
+int ntlibc_iscntrl(int c);
+int ntlibc_toupper(int c);
+int ntlibc_tolower(int c);
+int ntlibc_atoi(const char *nptr);
+unsigned long ntlibc_strtoul(const char *__restrict nptr, char **__restrict endptr, int base);
+char *ntlibc_strchr(const char *s, int c);
+char *ntlibc_utoa(unsigned int value, char *s, int radix);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntshell.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntshell.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntshell.c	(revision 398)
@@ -0,0 +1,684 @@
+/**
+ * @file ntshell.c
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 <string.h>
+#include "ntshell.h"
+#include "core/ntlibc.h"
+
+int ntshell_exit;
+
+#define VERSION_MAJOR   (0) /**< Major number. */
+#define VERSION_MINOR   (3) /**< Minor number. */
+#define VERSION_RELEASE (1) /**< Release number. */
+
+/**
+ * @brief Initialization code.
+ */
+#define INITCODE    (0x4367)
+
+/**
+ * @brief Unused variable wrapper.
+ *
+ * @param N A variable.
+ */
+#define UNUSED_VARIABLE(N)  do { (void)(N); } while (0)
+
+/**
+ * @brief Index number of the suggestion.
+ *
+ * @param HANDLE A pointer of the handle.
+ */
+#define SUGGEST_INDEX(HANDLE)   ((HANDLE)->suggest_index)
+
+/**
+ * @brief Source text string of the suggestion.
+ *
+ * @param HANDLE A pointer of the handle.
+ */
+#define SUGGEST_SOURCE(HANDLE)  ((HANDLE)->suggest_source)
+
+/**
+ * @brief Get the text editor.
+ *
+ * @param HANDLE A pointer of the handle.
+ */
+#define GET_EDITOR(HANDLE)      (&((HANDLE)->editor))
+
+/**
+ * @brief Get the text history.
+ *
+ * @param HANDLE A pointer of the handle.
+ */
+#define GET_HISTORY(HANDLE)     (&((HANDLE)->history))
+
+/**
+ * @brief Read from the serial port.
+ *
+ * @param HANDLE A pointer of the handle.
+ * @param BUF A pointer to the buffer.
+ * @param CNT Read length.
+ *
+ * @return The number of bytes read.
+ */
+#define SERIAL_READ(HANDLE, BUF, CNT)   ((HANDLE)->func_read(BUF, CNT, (HANDLE)->extobj))
+
+/**
+ * @brief Write to the serial port.
+ *
+ * @param HANDLE A pointer of the handle.
+ * @param BUF A pointer to the buffer.
+ * @param CNT Write length.
+ *
+ * @return The number of bytes written.
+ */
+#define SERIAL_WRITE(HANDLE, BUF, CNT)  ((HANDLE)->func_write(BUF, CNT, (HANDLE)->extobj))
+
+/**
+ * @brief Write the prompt to the serial port.
+ *
+ * @param HANDLE A pointer of the handle.
+ */
+#define PROMPT_WRITE(HANDLE)            SERIAL_WRITE((HANDLE), (HANDLE)->prompt, strlen((HANDLE)->prompt))
+
+/**
+ * @brief Write the newline to the serial port.
+ *
+ * @param HANDLE A pointer of the handle.
+ */
+#define PROMPT_NEWLINE(HANDLE)          SERIAL_WRITE((HANDLE), NTSHELL_PROMPT_NEWLINE, strlen(NTSHELL_PROMPT_NEWLINE))
+
+/**
+ * @brief Call the user callback function.
+ *
+ * @param HANDLE A pointer of the handle.
+ * @param TEXT A text string for the callback function.
+ */
+#define CALLBACK(HANDLE, TEXT)          ((HANDLE)->func_callback((TEXT), (HANDLE)->extobj))
+
+#define VTSEND_ERASE_LINE(HANDLE)       (vtsend_erase_line(&((HANDLE)->vtsend)))
+#define VTSEND_CURSOR_HEAD(HANDLE)      (vtsend_cursor_backward(&((HANDLE)->vtsend), 80))
+#define VTSEND_CURSOR_PREV(HANDLE)      (vtsend_cursor_backward(&((HANDLE)->vtsend), 1))
+#define VTSEND_CURSOR_PREVS(HANDLE,n)   (vtsend_cursor_backward(&((HANDLE)->vtsend), n))
+#define VTSEND_CURSOR_NEXT(HANDLE)      (vtsend_cursor_forward(&((HANDLE)->vtsend), 1))
+
+/**
+ * @brief Search a previous input text on the history module.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_history_prev(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	if (text_history_read_point_prev(GET_HISTORY(ntshell))) {
+		char txt[TEXTHISTORY_MAXLEN];
+		int n = text_history_read(GET_HISTORY(ntshell), &txt[0], sizeof(txt));
+		if (0 < n) {
+			VTSEND_ERASE_LINE(ntshell);
+			VTSEND_CURSOR_HEAD(ntshell);
+			PROMPT_WRITE(ntshell);
+			SERIAL_WRITE(ntshell, txt, n);
+			text_editor_set_text(GET_EDITOR(ntshell), txt);
+		}
+	}
+}
+
+/**
+ * @brief Search a next input text on the history module.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_history_next(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	if (text_history_read_point_next(GET_HISTORY(ntshell))) {
+		char txt[TEXTHISTORY_MAXLEN];
+		int n = text_history_read(GET_HISTORY(ntshell), &txt[0], sizeof(txt));
+		if (0 < n) {
+			VTSEND_ERASE_LINE(ntshell);
+			VTSEND_CURSOR_HEAD(ntshell);
+			PROMPT_WRITE(ntshell);
+			SERIAL_WRITE(ntshell, txt, n);
+			text_editor_set_text(GET_EDITOR(ntshell), txt);
+		}
+	}
+}
+
+/**
+ * @brief Move the cursor to left.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_cursor_left(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	if (text_editor_cursor_left(GET_EDITOR(ntshell))) {
+		VTSEND_CURSOR_PREV(ntshell);
+	}
+}
+
+/**
+ * @brief Move the cursor to right.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_cursor_right(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	if (text_editor_cursor_right(GET_EDITOR(ntshell))) {
+		VTSEND_CURSOR_NEXT(ntshell);
+	}
+}
+
+/**
+ * @brief Process for the enter action.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_enter(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	char txt[TEXTEDITOR_MAXLEN];
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	text_editor_get_text(GET_EDITOR(ntshell), &txt[0], sizeof(txt));
+	text_editor_clear(GET_EDITOR(ntshell));
+	text_history_write(GET_HISTORY(ntshell), txt);
+	PROMPT_NEWLINE(ntshell);
+	CALLBACK(ntshell, txt);
+	PROMPT_WRITE(ntshell);
+}
+
+/**
+ * @brief Process for the cancel action.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @note
+ * The CTRL+C operation in the general OS uses a signal.
+ * In this cancel action, It simulate only the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_cancel(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	text_editor_clear(GET_EDITOR(ntshell));
+	SERIAL_WRITE(ntshell, "^C", 2);
+	PROMPT_NEWLINE(ntshell);
+	PROMPT_WRITE(ntshell);
+}
+
+/**
+ * @brief Process for the insert action.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_insert(ntshell_t *ntshell, vtrecv_action_t action, unsigned int ch)
+{
+	char utf8[6];
+	int len8;
+
+	UNUSED_VARIABLE(action);
+
+	/*
+	 * Reject the suggestion index number if an input action occurred.
+	 */
+	SUGGEST_INDEX(ntshell) = -1;
+
+	/*
+	 * Insert the input character using the logical text editor.
+	 * Update the view.
+	 */
+	if ((len8 = text_editor_insert(GET_EDITOR(ntshell), ch, utf8)) > 0) {
+		char txt[TEXTEDITOR_MAXLEN];
+		int len = text_editor_get_text(GET_EDITOR(ntshell), &txt[0], sizeof(txt));
+		int pos = text_editor_cursor_get_position(GET_EDITOR(ntshell));
+		int n = len - pos;
+		SERIAL_WRITE(ntshell, utf8, len8);
+		if (n > 0) {
+			int i;
+			SERIAL_WRITE(ntshell, txt + pos, len - pos);
+			for (i = 0; i < n; i++) {
+				VTSEND_CURSOR_PREV(ntshell);
+			}
+		}
+	}
+}
+
+/**
+ * @brief Process for the backspace action.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_backspace(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	int bs_char_num;
+
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	bs_char_num = text_editor_backspace(GET_EDITOR(ntshell));
+	if (bs_char_num) {
+		char txt[TEXTEDITOR_MAXLEN];
+		int len = text_editor_get_text(GET_EDITOR(ntshell), &txt[0], sizeof(txt));
+		int pos = text_editor_cursor_get_position(GET_EDITOR(ntshell));
+		int n = len - pos;
+		VTSEND_CURSOR_PREV(ntshell);
+		if (n > 0) {
+			int i;
+			SERIAL_WRITE(ntshell, txt + pos, n);
+			SERIAL_WRITE(ntshell, " ", 1);
+			for (i = 0; i < n + 1; i++) {
+				VTSEND_CURSOR_PREV(ntshell);
+			}
+		}
+		else {
+			SERIAL_WRITE(ntshell, " ", 1);
+			VTSEND_CURSOR_PREVS(ntshell, bs_char_num);
+			SERIAL_WRITE(ntshell, " ", 1);
+			VTSEND_CURSOR_PREV(ntshell);
+		}
+	}
+}
+
+/**
+ * @brief Process for the delete action.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_delete(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	if (text_editor_delete(GET_EDITOR(ntshell))) {
+		char txt[TEXTEDITOR_MAXLEN];
+		int len = text_editor_get_text(GET_EDITOR(ntshell), &txt[0], sizeof(txt));
+		int pos = text_editor_cursor_get_position(GET_EDITOR(ntshell));
+		int n = len - pos;
+		if (n > 0) {
+			int i;
+			SERIAL_WRITE(ntshell, txt + pos, n);
+			SERIAL_WRITE(ntshell, " ", 1);
+			for (i = 0; i < n + 1; i++) {
+				VTSEND_CURSOR_PREV(ntshell);
+			}
+		}
+		else {
+			SERIAL_WRITE(ntshell, " ", 1);
+			VTSEND_CURSOR_PREV(ntshell);
+		}
+	}
+}
+
+/**
+ * @brief Process for the suggestion action.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_suggest(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	char buf[TEXTEDITOR_MAXLEN];
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	if (SUGGEST_INDEX(ntshell) < 0) {
+		/*
+		 * Enter the input suggestion mode.
+		 * Get the suggested text string with the current text string.
+		 */
+		if (text_editor_get_text(
+			GET_EDITOR(ntshell),
+			SUGGEST_SOURCE(ntshell),
+			sizeof(SUGGEST_SOURCE(ntshell))) > 0) {
+			SUGGEST_INDEX(ntshell) = 0;
+			if (text_history_find(
+				GET_HISTORY(ntshell),
+				SUGGEST_INDEX(ntshell),
+				SUGGEST_SOURCE(ntshell),
+				buf,
+				sizeof(buf)) == 0) {
+				/*
+				 * Found the suggestion.
+				 */
+				int n = strlen((const char *)buf);
+				VTSEND_ERASE_LINE(ntshell);
+				VTSEND_CURSOR_HEAD(ntshell);
+				PROMPT_WRITE(ntshell);
+				SERIAL_WRITE(ntshell, buf, n);
+				text_editor_set_text(GET_EDITOR(ntshell), buf);
+			}
+			else {
+				/*
+				 * Not found the suggestion.
+				 */
+				SUGGEST_INDEX(ntshell) = -1;
+			}
+		}
+	}
+	else {
+		/*
+		 * Already the input suggestion mode.
+		 * Search the next suggestion text string.
+		 */
+		SUGGEST_INDEX(ntshell) = SUGGEST_INDEX(ntshell) + 1;
+		if (text_history_find(
+			GET_HISTORY(ntshell),
+			SUGGEST_INDEX(ntshell),
+			SUGGEST_SOURCE(ntshell),
+			buf,
+			sizeof(buf)) == 0) {
+			/*
+			 * Found the suggestion.
+			 */
+			int n = strlen((const char *)buf);
+			VTSEND_ERASE_LINE(ntshell);
+			VTSEND_CURSOR_HEAD(ntshell);
+			PROMPT_WRITE(ntshell);
+			SERIAL_WRITE(ntshell, buf, n);
+			text_editor_set_text(GET_EDITOR(ntshell), buf);
+		}
+		else {
+			/*
+			 * Not found the suggestion.
+			 * Recall the previous input text string.
+			 */
+			int n = strlen(SUGGEST_SOURCE(ntshell));
+			VTSEND_ERASE_LINE(ntshell);
+			VTSEND_CURSOR_HEAD(ntshell);
+			PROMPT_WRITE(ntshell);
+			SERIAL_WRITE(ntshell, SUGGEST_SOURCE(ntshell), n);
+			text_editor_set_text(GET_EDITOR(ntshell), SUGGEST_SOURCE(ntshell));
+			SUGGEST_INDEX(ntshell) = -1;
+		}
+	}
+}
+
+/**
+ * @brief Move the cursor to the head of the line.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_cursor_head(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	VTSEND_CURSOR_HEAD(ntshell);
+	PROMPT_WRITE(ntshell);
+	text_editor_cursor_head(GET_EDITOR(ntshell));
+}
+
+/**
+ * @brief Move the cursor to the tail of the line.
+ * @details This function change the state of the logical text editor and the view.
+ *
+ * @param ntshell A handler of the NT-Shell.
+ * @param action An action.
+ * @param ch A input character.
+ */
+static void actfunc_cursor_tail(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch)
+{
+	char buf[TEXTEDITOR_MAXLEN];
+	int len;
+	UNUSED_VARIABLE(action);
+	UNUSED_VARIABLE(ch);
+	text_editor_get_text(GET_EDITOR(ntshell), buf, sizeof(buf));
+	len = strlen((const char *)buf);
+	VTSEND_CURSOR_HEAD(ntshell);
+	PROMPT_WRITE(ntshell);
+	SERIAL_WRITE(ntshell, buf, len);
+	text_editor_cursor_tail(GET_EDITOR(ntshell));
+}
+
+/**
+ * @brief The data structure of the action table.
+ * @details
+ * The action consists from the state and the input character.
+ * This definition also have the callback function.
+ */
+typedef struct {
+	vtrecv_action_t action;
+	unsigned char ch;
+	void(*func)(ntshell_t *ntshell, vtrecv_action_t action, unsigned char ch);
+} ntshell_action_table_t;
+
+/**
+ * @brief Process function table for the actions.
+ * @details
+ * The action codes depends on the virtual terminals.
+ * So you should check some virtual terminal softwares and the environments.
+ *
+ * <table>
+ *   <th>
+ *     <td>Platform</td>
+ *     <td>Tools</td>
+ *   </th>
+ *   <tr>
+ *     <td>Windows</td>
+ *     <td>Hyper Terminal, Poderossa, TeraTerm</td>
+ *   </tr>
+ *   <tr>
+ *     <td>Linux</td>
+ *     <td>minicom, screen, kermit</td>
+ *   </tr>
+ * </table>
+ */
+static const ntshell_action_table_t action_table[] = {
+	{VTRECV_ACTION_EXECUTE, 0x01, actfunc_cursor_head},
+	{VTRECV_ACTION_EXECUTE, 0x02, actfunc_cursor_left},
+	{VTRECV_ACTION_EXECUTE, 0x03, actfunc_cancel},
+	{VTRECV_ACTION_EXECUTE, 0x04, actfunc_delete},
+	{VTRECV_ACTION_EXECUTE, 0x05, actfunc_cursor_tail},
+	{VTRECV_ACTION_EXECUTE, 0x06, actfunc_cursor_right},
+	{VTRECV_ACTION_EXECUTE, 0x08, actfunc_backspace},
+	{VTRECV_ACTION_EXECUTE, 0x09, actfunc_suggest},
+	{VTRECV_ACTION_EXECUTE, 0x0d, actfunc_enter},
+	{VTRECV_ACTION_EXECUTE, 0x0e, actfunc_history_next},
+	{VTRECV_ACTION_EXECUTE, 0x10, actfunc_history_prev},
+	{VTRECV_ACTION_CSI_DISPATCH, 0x41, actfunc_history_prev},
+	{VTRECV_ACTION_CSI_DISPATCH, 0x42, actfunc_history_next},
+	{VTRECV_ACTION_CSI_DISPATCH, 0x43, actfunc_cursor_right},
+	{VTRECV_ACTION_CSI_DISPATCH, 0x44, actfunc_cursor_left},
+	{VTRECV_ACTION_CSI_DISPATCH, 0x7e, actfunc_delete},
+	{VTRECV_ACTION_PRINT, 0x7f, actfunc_backspace},
+};
+
+/**
+ * @brief The callback function for the vtrecv module.
+ *
+ * @param vtrecv The vtrecv.
+ * @param action An action.
+ * @param ch A character.
+ */
+void vtrecv_callback(vtrecv_t *vtrecv, vtrecv_action_t action, unsigned int ch)
+{
+	ntshell_action_table_t *p;
+	int i;
+	const int ACTTBLSIZ = sizeof(action_table) / sizeof(action_table[0]);
+
+	/*
+	 * Search the process function for the control codes.
+	 */
+	p = (ntshell_action_table_t *)action_table;
+	for (i = 0; i < ACTTBLSIZ; i++) {
+		if ((p->action == action) && (p->ch == ch)) {
+			p->func(vtrecv->user_data, action, ch);
+			return;
+		}
+		p++;
+	}
+
+	/*
+	 * A general character is the input character.
+	 */
+	if (VTRECV_ACTION_PRINT == action) {
+		actfunc_insert(vtrecv->user_data, action, ch);
+		return;
+	}
+
+	/*
+	 * Other cases, there is no defined process function for the input codes.
+	 * If you need to support the input action, you should update the action table.
+	 */
+}
+
+/**
+ * @brief Initialize the NT-Shell.
+ *
+ * @param p A pointer to the handler of NT-Shell.
+ * @param func_read Serial read function.
+ * @param func_write Serial write function.
+ * @param func_callback Callback function.
+ * @param extobj An external object for the callback function.
+ */
+void ntshell_init(ntshell_t *p,
+	NTSHELL_SERIAL_READ func_read,
+	NTSHELL_SERIAL_WRITE func_write,
+	NTSHELL_USER_CALLBACK func_callback,
+	void *extobj)
+{
+	/*
+	 * The vtrecv module provides a pointer interface to an external object.
+	 * NT-Shell uses the text editor, text history, read function, write function with the pointer interface.
+	 */
+	p->func_read = func_read;
+	p->func_write = func_write;
+	p->func_callback = func_callback;
+	p->extobj = extobj;
+	strcpy(p->prompt, NTSHELL_PROMPT_DEFAULT);
+
+	p->vtrecv.user_data = p;
+
+	/*
+	 * Initialize the modules.
+	 */
+	vtsend_init(&(p->vtsend), func_write, extobj);
+	vtrecv_init(&(p->vtrecv), vtrecv_callback);
+	text_editor_init(GET_EDITOR(p));
+	text_history_init(GET_HISTORY(p));
+	SUGGEST_INDEX(p) = -1;
+
+	/*
+	 * Set the initialization code.
+	 */
+	p->initcode = INITCODE;
+}
+
+/**
+ * @brief Execute the NT-Shell.
+ * @details Never return from this function.
+ *
+ * @param p A pointer to the handler of the NT-Shell.
+ */
+void ntshell_execute(ntshell_t *p)
+{
+	/*
+	 * Check the initialization code.
+	 */
+	if (p->initcode != INITCODE) {
+		return;
+	}
+
+	/*
+	 * User input loop.
+	 */
+	PROMPT_WRITE(p);
+	while (ntshell_exit == 0) {
+		unsigned char ch;
+		SERIAL_READ(p, (char *)&ch, sizeof(ch));
+		vtrecv_execute(&(p->vtrecv), &ch, sizeof(ch));
+	}
+}
+
+/**
+ * @brief Set up the prompt of the NT-Shell.
+ *
+ * @param p A pointer to the handler of the NT-Shell.
+ * @param prompt A text string.
+ */
+void ntshell_set_prompt(ntshell_t *p, const char *prompt)
+{
+	/*
+	 * Check the initialization code.
+	 */
+	if (p->initcode != INITCODE) {
+		return;
+	}
+
+	strcpy(p->prompt, prompt);
+}
+
+/**
+ * @brief Get the version.
+ *
+ * @param major Major number.
+ * @param minor Minor number.
+ * @param release Release number.
+ */
+void ntshell_version(int *major, int *minor, int *release)
+{
+	*major = VERSION_MAJOR;
+	*minor = VERSION_MINOR;
+	*release = VERSION_RELEASE;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntshell.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntshell.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/ntshell.h	(revision 398)
@@ -0,0 +1,90 @@
+/**
+ * @file ntshell.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 NTSHELL_H
+#define NTSHELL_H
+
+#include "vtrecv.h"
+#include "vtsend.h"
+#include "text_editor.h"
+#include "text_history.h"
+
+#define NTSHELL_PROMPT_MAXLEN   (32)
+#define NTSHELL_PROMPT_DEFAULT  ">"
+#define NTSHELL_PROMPT_NEWLINE  "\r\n"
+
+typedef int (*NTSHELL_SERIAL_READ)(char *buf, int cnt, void *extobj);
+typedef int (*NTSHELL_SERIAL_WRITE)(const char *buf, int cnt, void *extobj);
+typedef int (*NTSHELL_USER_CALLBACK)(const char *text, void *extobj);
+
+/**
+ * @brief The handler of NT-Shell.
+ * @details
+ * The best way to provide a handler, We should hide the implementation from the library users.
+ * But some small embedded environments can not use memory allocation dynamically.
+ * So this implementation open the fields of the handler in this header.
+ * You can use this handler on the stacks.
+ */
+typedef struct {
+    unsigned int initcode;  /**< Initialization flag. */
+    vtsend_t vtsend;        /**< The handler of vtsend. */
+    vtrecv_t vtrecv;        /**< The handler of vtrecv. */
+    text_editor_t editor;   /**< The handler of text_editor. */
+    text_history_t history; /**< The handler of text_history. */
+    int suggest_index;
+    char suggest_source[TEXTEDITOR_MAXLEN];
+    NTSHELL_SERIAL_READ func_read;
+    NTSHELL_SERIAL_WRITE func_write;
+    NTSHELL_USER_CALLBACK func_callback;
+    void *extobj;
+    char prompt[NTSHELL_PROMPT_MAXLEN];
+} ntshell_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void ntshell_init(ntshell_t *p,
+    NTSHELL_SERIAL_READ func_read,
+    NTSHELL_SERIAL_WRITE func_write,
+    NTSHELL_USER_CALLBACK func_callback,
+    void *extobj);
+void ntshell_execute(ntshell_t *p);
+void ntshell_set_prompt(ntshell_t *p, const char *prompt);
+void ntshell_version(int *major, int *minor, int *release);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_editor.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_editor.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_editor.c	(revision 398)
@@ -0,0 +1,345 @@
+/**
+ * @file text_editor.c
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 "text_editor.h"
+
+/**
+ * @brief Initialize the text editor module.
+ *
+ * @param p A pointer to the text editor handler.
+ */
+void text_editor_init(text_editor_t *p)
+{
+	p->pos = 0;
+	p->len = 0;
+	p->buffer[p->len] = '\0';
+}
+
+/**
+ * @brief Insert a character.
+ *
+ * @param p A pointer to the text editor handler.
+ * @param c A character.
+ */
+int text_editor_insert(text_editor_t *p, unsigned int ch, char *utf8)
+{
+	int len;
+
+	if (ch < 0x80) {
+		utf8[0] = ch & 0x7F;
+		len = 1;
+	}
+	else if (ch < 0x00000800) {
+		utf8[1] = (0x80 | (ch & 0x3F));
+		utf8[0] = (0xC0 | (ch >> 6));
+		len = 2;
+	}
+	else if (ch < 0x00010000) {
+		utf8[2] = (0x80 | (ch & 0x3F));
+		utf8[1] = (0x80 | ((ch >> 6) & 0x3F));
+		utf8[0] = (0xE0 | (ch >> 12));
+		len = 3;
+	}
+	else if (ch < 0x00200000) {
+		utf8[3] = (0x80 | (ch & 0x3F));
+		utf8[2] = (0x80 | ((ch >> 6) & 0x3F));
+		utf8[1] = (0x80 | ((ch >> 12) & 0x3F));
+		utf8[0] = (0xF0 | (ch >> 18));
+		len = 4;
+	}
+	else if (ch < 0x04000000) {
+		utf8[4] = (0x80 | (ch & 0x3F));
+		utf8[3] = (0x80 | ((ch >> 6) & 0x3F));
+		utf8[2] = (0x80 | ((ch >> 12) & 0x3F));
+		utf8[1] = (0x80 | ((ch >> 18) & 0x3F));
+		utf8[0] = (0xF8 | (ch >> 24));
+		len = 5;
+	}
+	else if (ch < 0x80000000) {
+		utf8[5] = (0x80 | (ch & 0x3F));
+		utf8[4] = (0x80 | ((ch >> 6) & 0x3F));
+		utf8[3] = (0x80 | ((ch >> 12) & 0x3F));
+		utf8[2] = (0x80 | ((ch >> 18) & 0x3F));
+		utf8[1] = (0x80 | ((ch >> 24) & 0x3F));
+		utf8[0] = (0xFC | (ch >> 30));
+		len = 6;
+	}
+	else {
+		return 0;
+	}
+
+	if (p->len >= (int)sizeof(p->buffer) - len)
+		return 0;
+
+	int n = p->len - p->pos + len;
+	char *src = p->buffer + p->len + 0;
+	char *des = p->buffer + p->len + len;
+	for (int i = 0; i < n; i++) {
+		*des = *src;
+		des--;
+		src--;
+	}
+
+	for (int i = 0; i < len; i++) {
+		p->buffer[p->pos] = utf8[i];
+		p->pos++;
+		p->len++;
+	}
+	p->buffer[p->len] = '\0';
+	return len;
+}
+
+/**
+* @brief count bytes of a deleted character by backspace.
+*
+* @param str A pointer to the text.
+* @param pos The end of the text.
+*/
+int bs_char_count(char *str, int pos)
+{
+	int num = 1, local_pos = pos;
+	char *c;
+
+	while (1) {
+		c = str + local_pos;
+
+		if ((*c & 0x80) != 0x80)
+			return num;
+
+		if (((*c & 0xE0) == 0xC0) && (num == 2)) {
+			return num;
+		}
+		else if (((*c & 0xF0) == 0xE0) && (num == 3)) {
+			return num;
+		}
+		else if (((*c & 0xF8) == 0xF0) && (num == 4)) {
+			return num;
+		}
+		else if (((*c & 0xFC) == 0xF8) && (num == 5)) {
+			return num;
+		}
+		else if (((*c & 0xFE) == 0xFC) && (num == 6)) {
+			return num;
+		}
+		else {
+			if (local_pos > 0) {
+				local_pos--;
+				num++;
+			}
+			else
+				return 0;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * @brief Delete a character.
+ *
+ * @param p A pointer to the text editor handler.
+ */
+int text_editor_backspace(text_editor_t *p)
+{
+	int bs_char_num;
+
+	if (0 < p->pos) {
+		int n = p->len - p->pos;
+		int i;
+		char *src = p->buffer + p->pos - 0;
+		char *des = p->buffer + p->pos - 1;
+
+		bs_char_num = bs_char_count(p->buffer, p->pos - 1);
+		p->pos -= bs_char_num;
+		p->len -= bs_char_num;
+
+		for (i = 0; i < n; i++) {
+			*des = *src;
+			des++;
+			src++;
+		}
+		*(p->buffer + p->len) = '\0';
+		return (bs_char_num > 2 ? 2 : 1);
+	}
+	return 0;
+}
+
+/**
+ * @brief Delete a character.
+ *
+ * @param p A pointer to the text editor handler.
+ */
+int text_editor_delete(text_editor_t *p)
+{
+	if (p->pos < p->len) {
+		int n = p->len - p->pos - 1;
+		int i;
+		char *src = p->buffer + p->pos + 1;
+		char *des = p->buffer + p->pos + 0;
+		p->len--;
+		for (i = 0; i < n; i++) {
+			*des = *src;
+			des++;
+			src++;
+		}
+		*(p->buffer + p->len) = '\0';
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * @brief Get the cursor position.
+ *
+ * @param p A pointer to the text editor handler.
+ */
+int text_editor_cursor_get_position(text_editor_t *p)
+{
+	return p->pos;
+}
+
+/**
+ * @brief Move to the cursor to the head of the line.
+ *
+ * @param p A pointer to the text editor handler.
+ */
+int text_editor_cursor_head(text_editor_t *p)
+{
+	if (0 < p->pos) {
+		p->pos = 0;
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * @brief Move to the cursor to the tail of the line.
+ *
+ * @param p A pointer to the text editor handler.
+ */
+int text_editor_cursor_tail(text_editor_t *p)
+{
+	if (p->pos < p->len) {
+		p->pos = p->len;
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * @brief Move to the cursor to left.
+ *
+ * @param p A pointer to the text editor handler.
+ */
+int text_editor_cursor_left(text_editor_t *p)
+{
+	if (0 < p->pos) {
+		p->pos--;
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * @brief Move to the cursor to right.
+ *
+ * @param p A pointer to the text editor handler.
+ */
+int text_editor_cursor_right(text_editor_t *p)
+{
+	if (p->pos < p->len) {
+		p->pos++;
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * @brief Set the edit line.
+ *
+ * @param p A pointer to the text editor handler.
+ * @param buf A text string.
+ */
+int text_editor_set_text(text_editor_t *p, char *buf)
+{
+	char *src = buf;
+	char *des = p->buffer;
+	int n = 0;
+	while (*src) {
+		*des = *src;
+		des++;
+		src++;
+		n++;
+		if ((int)sizeof(p->buffer) <= n - 1) {
+			break;
+		}
+	}
+	*des = '\0';
+	p->len = n;
+	p->pos = p->len;
+	return n;
+}
+
+/**
+ * @brief Get the edit line.
+ *
+ * @param p A pointer to the text editor handler.
+ * @param buf A text string.
+ * @param siz Size of the text string buffer.
+ */
+int text_editor_get_text(text_editor_t *p, char *buf, int siz)
+{
+	char *src = p->buffer;
+	char *des = buf;
+	int n = 0;
+	while (*src) {
+		*des++ = *src++;
+		n++;
+		if (siz <= n) {
+			break;
+		}
+	}
+	*des = '\0';
+	return n;
+}
+
+/**
+ * @brief Clear the text string.
+ *
+ * @param p A pointer to the text editor handler.
+ */
+void text_editor_clear(text_editor_t *p)
+{
+	p->pos = 0;
+	p->len = 0;
+	p->buffer[p->len] = '\0';
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_editor.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_editor.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_editor.h	(revision 398)
@@ -0,0 +1,74 @@
+/**
+ * @file text_editor.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 TEXT_EDITOR_H
+#define TEXT_EDITOR_H
+
+#include "ntconf.h"
+
+/**
+ * @brief Maximum length of the text string.
+ */
+#define TEXTEDITOR_MAXLEN   (NTCONF_EDITOR_MAXLEN)
+
+/**
+ * @brief Text editor handler.
+ */
+typedef struct {
+    char buffer[TEXTEDITOR_MAXLEN]; /**< Buffer for the text string. */
+    int pos;                        /**< Position of the logical cursor. */
+    int len;                        /**< Length of the text string. */
+} text_editor_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void text_editor_init(text_editor_t *p);
+int text_editor_insert(text_editor_t *p, unsigned int ch, char *utf8);
+int text_editor_backspace(text_editor_t *p);
+int text_editor_delete(text_editor_t *p);
+int text_editor_cursor_get_position(text_editor_t *p);
+int text_editor_cursor_head(text_editor_t *p);
+int text_editor_cursor_tail(text_editor_t *p);
+int text_editor_cursor_left(text_editor_t *p);
+int text_editor_cursor_right(text_editor_t *p);
+int text_editor_set_text(text_editor_t *p, char *buf);
+int text_editor_get_text(text_editor_t *p, char *buf, int siz);
+void text_editor_clear(text_editor_t *p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_history.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_history.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_history.c	(revision 398)
@@ -0,0 +1,170 @@
+/**
+ * @file text_history.c
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 <string.h>
+#include "text_history.h"
+#include "core/ntlibc.h"
+
+/**
+ * @brief Initialize this module.
+ *
+ * @param p A pointer to the handler.
+ */
+void text_history_init(text_history_t *p)
+{
+	int i;
+	p->rp = 0;
+	p->wp = 0;
+	for (i = 0; i < (int)sizeof(p->history); i++) {
+		p->history[i] = 0;
+	}
+}
+
+/**
+ * @brief Write to the history.
+ *
+ * @param p A pointer to the handler.
+ * @param buf A pointer to the buffer.
+ */
+int text_history_write(text_history_t *p, char *buf)
+{
+	char *sp = p->history + (TEXTHISTORY_MAXLEN * p->wp);
+	if (buf[0] == '\0') {
+		return 0;
+	}
+	while (*buf) {
+		*sp = *buf;
+		sp++;
+		buf++;
+	}
+	*sp = '\0';
+	p->wp = (p->wp + 1) % TEXTHISTORY_DEPTH;
+	p->rp = p->wp;
+	return 1;
+}
+
+/**
+ * @brief Read from the history.
+ *
+ * @param p A pointer to the handler.
+ * @param buf A pointer to the buffer.
+ * @param siz A size of the buffer.
+ */
+int text_history_read(text_history_t *p, char *buf, const int siz)
+{
+	char *sp = p->history + (TEXTHISTORY_MAXLEN * p->rp);
+	int n = 0;
+	while (*sp) {
+		*buf = *sp;
+		buf++;
+		sp++;
+		n++;
+		if (siz - 1 <= n) {
+			break;
+		}
+	}
+	*buf = '\0';
+	return n;
+}
+
+/**
+ * @brief Change the pointing location to the next.
+ *
+ * @param p A pointer to the handler.
+ */
+int text_history_read_point_next(text_history_t *p)
+{
+	int n = (p->rp + 1) % TEXTHISTORY_DEPTH;
+	if (n != p->wp) {
+		p->rp = n;
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * @brief Change the pointing location to the previous.
+ *
+ * @param p A pointer to the handler.
+ */
+int text_history_read_point_prev(text_history_t *p)
+{
+	int n = (p->rp == 0) ? (TEXTHISTORY_DEPTH - 1) : (p->rp - 1);
+	if (n != p->wp) {
+		char *sp = p->history + (TEXTHISTORY_MAXLEN * n);
+		if (*sp != '\0') {
+			p->rp = n;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/**
+ * @brief Find the given text string from the text history.
+ *
+ * @param p A pointer to the handler.
+ * @param index An index number of the history.
+ * @param text The target text string.
+ * @param buf A pointer to the buffer.
+ * @param siz A size of the buffer.
+ *
+ * @retval 0 Success.
+ * @retval !0 Failure.
+ */
+int text_history_find(text_history_t *p,
+	const int index, const char *text,
+	char *buf, const int siz)
+{
+	const int text_len = strlen((const char *)text);
+	int found = 0;
+	int i;
+	for (i = 0; i < TEXTHISTORY_DEPTH; i++) {
+		int target = (p->rp + i) % TEXTHISTORY_DEPTH;
+		char *txtp = p->history + (TEXTHISTORY_MAXLEN * target);
+		const int target_len = strlen((const char *)txtp);
+		int comp_len = (target_len < text_len) ? target_len : text_len;
+		if ((ntlibc_strncmp(
+			(const char *)txtp,
+			(const char *)text, comp_len) == 0) && (comp_len > 0)) {
+			if (found == index) {
+				if (siz <= strlen(txtp)) {
+					return -1;
+				}
+				strcpy((char *)buf, (char *)txtp);
+				return 0;
+			}
+			found++;
+		}
+	}
+	return -1;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_history.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_history.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/text_history.h	(revision 398)
@@ -0,0 +1,84 @@
+/**
+ * @file text_history.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 TEXT_HISTORY_H
+#define TEXT_HISTORY_H
+
+#include "ntconf.h"
+
+/**
+ * @brief Maximum length per a history.
+ */
+#define TEXTHISTORY_MAXLEN  (NTCONF_EDITOR_MAXLEN)
+
+/**
+ * @brief Depth of the history.
+ */
+#define TEXTHISTORY_DEPTH   (NTCONF_HISTORY_DEPTH)
+
+/**
+ * @brief Structure of the text history module.
+ */
+typedef struct {
+    /**
+     * @brief History buffer.
+     */
+    char history[TEXTHISTORY_MAXLEN * TEXTHISTORY_DEPTH];
+
+    /**
+     * @brief Read pointer.
+     */
+    int rp;
+
+    /**
+     * @brief Write pointer.
+     */
+    int wp;
+} text_history_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void text_history_init(text_history_t *p);
+int text_history_write(text_history_t *p, char *buf);
+int text_history_read(text_history_t *p, char *buf, const int siz);
+int text_history_read_point_next(text_history_t *p);
+int text_history_read_point_prev(text_history_t *p);
+int text_history_find(text_history_t *p, const int index, const char *text, char *buf, const int siz);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtrecv.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtrecv.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtrecv.c	(revision 398)
@@ -0,0 +1,2881 @@
+/**
+ * @file vtrecv.c
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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.
+ */
+
+/*
+ * @note
+ * An implementation of Paul Williams' DEC compatible state machine parser.
+ * This code is in the public domain.
+ *
+ * @author Joshua Haberman <joshua@reverberate.org>
+ * @author Shinichiro Nakamura : Modified for Natural Tiny Shell (NT-Shell)
+ */
+
+#include "vtrecv.h"
+
+static state_change_t GET_STATE_TABLE(const int state, const int ch);
+static vtrecv_action_t GET_ENTRY_ACTIONS(const int state);
+static vtrecv_action_t GET_EXIT_ACTIONS(const int state);
+
+#if (USE_ORIGINAL_LUT==1)
+static const state_change_t STATE_TABLE[14][256] = {
+	{	/* VTRECV_STATE_CSI_ENTRY = 0 */
+		/*0  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*1  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*2  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*3  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*4  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*5  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*6  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*7  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*8  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*9  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*10 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*11 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*12 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*13 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*14 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*15 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*16 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*17 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*18 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*19 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*20 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*21 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*22 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*23 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*29 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*30 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*31 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*32 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*33 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*34 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*35 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*36 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*37 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*38 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*39 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*40 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*41 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*42 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*43 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*44 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*45 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*46 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*47 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*48 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*49 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*50 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*51 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*52 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*53 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*54 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*55 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*56 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*57 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*58 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*59 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4),
+		/*60 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_PARAM << 4),
+		/*61 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_PARAM << 4),
+		/*62 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_PARAM << 4),
+		/*63 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_PARAM << 4),
+		/*64 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*65 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*66 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*67 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*68 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*69 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*70 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*71 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*72 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*73 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*74 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*75 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*76 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*77 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*78 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*79 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*80 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*81 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*82 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*83 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*84 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*85 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*86 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*87 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*88 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*89 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*90 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*91 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*92 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*93 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*94 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*95 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*96 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*97 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*98 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*99 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*100*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*101*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*102*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*103*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*104*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*105*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*106*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*107*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*108*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*109*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*110*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*111*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*112*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*113*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*114*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*115*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*116*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*117*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*118*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*119*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*120*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*121*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*122*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*123*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*124*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*125*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*126*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_CSI_IGNORE = 1 */
+		/*0  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*1  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*2  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*3  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*4  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*5  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*6  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*7  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*8  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*9  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*10 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*11 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*12 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*13 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*14 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*15 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*16 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*17 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*18 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*19 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*20 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*21 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*22 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*23 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*29 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*30 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*31 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*32 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*33 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*34 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*35 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*36 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*37 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*38 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*39 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*40 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*41 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*42 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*43 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*44 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*45 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*46 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*47 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*48 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*49 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*50 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*51 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*52 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*53 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*54 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*55 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*56 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*57 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*58 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*59 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*60 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*61 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*62 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*63 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*64 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*65 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*66 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*67 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*68 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*69 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*70 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*71 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*72 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*73 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*74 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*75 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*76 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*77 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*78 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*79 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*80 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*81 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*82 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*83 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*84 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*85 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*86 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*87 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*88 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*89 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*90 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*91 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*92 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*93 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*94 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*95 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*96 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*97 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*98 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*99 */  0 | (VTRECV_STATE_GROUND << 4),
+		/*100*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*101*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*102*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*103*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*104*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*105*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*106*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*107*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*108*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*109*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*110*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*111*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*112*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*113*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*114*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*115*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*116*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*117*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*118*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*119*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*120*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*121*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*122*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*123*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*124*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*125*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*126*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_CSI_INTERMEDIATE = 2 */
+		/*0  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*1  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*2  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*3  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*4  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*5  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*6  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*7  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*8  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*9  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*10 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*11 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*12 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*13 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*14 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*15 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*16 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*17 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*18 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*19 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*20 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*21 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*22 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*23 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*29 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*30 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*31 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*32 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*33 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*34 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*35 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*36 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*37 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*38 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*39 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*40 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*41 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*42 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*43 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*44 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*45 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*46 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*47 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*48 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*49 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*50 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*51 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*52 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*53 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*54 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*55 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*56 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*57 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*58 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*59 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*60 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*61 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*62 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*63 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*64 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*65 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*66 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*67 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*68 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*69 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*70 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*71 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*72 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*73 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*74 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*75 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*76 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*77 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*78 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*79 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*80 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*81 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*82 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*83 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*84 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*85 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*86 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*87 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*88 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*89 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*90 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*91 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*92 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*93 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*94 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*95 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*96 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*97 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*98 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*99 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*100*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*101*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*102*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*103*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*104*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*105*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*106*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*107*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*108*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*109*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*110*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*111*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*112*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*113*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*114*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*115*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*116*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*117*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*118*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*119*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*120*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*121*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*122*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*123*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*124*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*125*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*126*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_CSI_PARAM = 3 */
+		/*0  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*1  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*2  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*3  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*4  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*5  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*6  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*7  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*8  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*9  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*10 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*11 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*12 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*13 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*14 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*15 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*16 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*17 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*18 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*19 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*20 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*21 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*22 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*23 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*29 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*30 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*31 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*32 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*33 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*34 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*35 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*36 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*37 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*38 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*39 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*40 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*41 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*42 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*43 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*44 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*45 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*46 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*47 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4),
+		/*48 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*49 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*50 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*51 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*52 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*53 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*54 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*55 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*56 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*57 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*58 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*59 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*60 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*61 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*62 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*63 */  0 | (VTRECV_STATE_CSI_IGNORE << 4),
+		/*64 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*65 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*66 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*67 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*68 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*69 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*70 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*71 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*72 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*73 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*74 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*75 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*76 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*77 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*78 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*79 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*80 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*81 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*82 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*83 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*84 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*85 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*86 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*87 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*88 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*89 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*90 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*91 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*92 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*93 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*94 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*95 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*96 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*97 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*98 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*99 */  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*100*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*101*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*102*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*103*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*104*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*105*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*106*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*107*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*108*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*109*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*110*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*111*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*112*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*113*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*114*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*115*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*116*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*117*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*118*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*119*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*120*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*121*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*122*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*123*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*124*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*125*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*126*/  VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_DCS_ENTRY = 4 */
+		/*0  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*1  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*2  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*3  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*4  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*5  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*6  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*7  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*8  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*9  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*10 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*11 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*12 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*13 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*14 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*15 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*16 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*17 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*18 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*19 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*20 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*21 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*22 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*23 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*29 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*30 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*31 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*32 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*33 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*34 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*35 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*36 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*37 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*38 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*39 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*40 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*41 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*42 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*43 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*44 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*45 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*46 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*47 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*48 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*49 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*50 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*51 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*52 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*53 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*54 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*55 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*56 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*57 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*58 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*59 */  VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4),
+		/*60 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_PARAM << 4),
+		/*61 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_PARAM << 4),
+		/*62 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_PARAM << 4),
+		/*63 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_PARAM << 4),
+		/*64 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*65 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*66 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*67 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*68 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*69 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*70 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*71 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*72 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*73 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*74 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*75 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*76 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*77 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*78 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*79 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*80 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*81 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*82 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*83 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*84 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*85 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*86 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*87 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*88 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*89 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*90 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*91 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*92 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*93 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*94 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*95 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*96 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*97 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*98 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*99 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*100*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*101*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*102*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*103*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*104*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*105*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*106*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*107*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*108*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*109*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*110*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*111*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*112*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*113*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*114*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*115*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*116*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*117*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*118*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*119*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*120*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*121*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*122*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*123*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*124*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*125*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*126*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_DCS_IGNORE = 5 */
+		/*0  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*1  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*2  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*3  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*4  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*5  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*6  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*7  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*8  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*9  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*10 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*11 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*12 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*13 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*14 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*15 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*16 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*17 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*18 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*19 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*20 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*21 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*22 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*23 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*29 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*30 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*31 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*32 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*33 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*34 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*35 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*36 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*37 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*38 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*39 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*40 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*41 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*42 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*43 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*44 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*45 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*46 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*47 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*48 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*49 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*50 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*51 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*52 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*53 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*54 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*55 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*56 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*57 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*58 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*59 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*60 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*61 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*62 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*63 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*64 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*65 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*66 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*67 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*68 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*69 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*70 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*71 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*72 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*73 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*74 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*75 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*76 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*77 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*78 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*79 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*80 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*81 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*82 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*83 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*84 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*85 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*86 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*87 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*88 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*89 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*90 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*91 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*92 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*93 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*94 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*95 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*96 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*97 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*98 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*99 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*100*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*101*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*102*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*103*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*104*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*105*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*106*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*107*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*108*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*109*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*110*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*111*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*112*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*113*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*114*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*115*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*116*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*117*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*118*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*119*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*120*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*121*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*122*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*123*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*124*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*125*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*126*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_DCS_INTERMEDIATE = 6 */
+		/*0  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*1  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*2  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*3  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*4  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*5  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*6  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*7  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*8  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*9  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*10 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*11 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*12 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*13 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*14 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*15 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*16 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*17 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*18 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*19 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*20 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*21 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*22 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*23 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*29 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*30 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*31 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*32 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*33 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*34 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*35 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*36 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*37 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*38 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*39 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*40 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*41 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*42 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*43 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*44 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*45 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*46 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*47 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*48 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*49 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*50 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*51 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*52 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*53 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*54 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*55 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*56 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*57 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*58 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*59 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*60 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*61 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*62 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*63 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*64 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*65 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*66 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*67 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*68 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*69 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*70 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*71 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*72 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*73 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*74 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*75 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*76 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*77 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*78 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*79 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*80 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*81 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*82 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*83 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*84 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*85 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*86 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*87 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*88 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*89 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*90 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*91 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*92 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*93 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*94 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*95 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*96 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*97 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*98 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*99 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*100*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*101*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*102*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*103*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*104*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*105*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*106*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*107*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*108*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*109*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*110*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*111*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*112*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*113*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*114*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*115*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*116*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*117*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*118*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*119*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*120*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*121*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*122*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*123*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*124*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*125*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*126*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_DCS_PARAM = 7 */
+		/*0  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*1  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*2  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*3  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*4  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*5  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*6  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*7  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*8  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*9  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*10 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*11 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*12 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*13 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*14 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*15 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*16 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*17 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*18 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*19 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*20 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*21 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*22 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*23 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*29 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*30 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*31 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*32 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*33 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*34 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*35 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*36 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*37 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*38 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*39 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*40 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*41 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*42 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*43 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*44 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*45 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*46 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*47 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4),
+		/*48 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*49 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*50 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*51 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*52 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*53 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*54 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*55 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*56 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*57 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*58 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*59 */  VTRECV_ACTION_PARAM | (0 << 4),
+		/*60 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*61 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*62 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*63 */  0 | (VTRECV_STATE_DCS_IGNORE << 4),
+		/*64 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*65 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*66 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*67 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*68 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*69 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*70 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*71 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*72 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*73 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*74 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*75 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*76 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*77 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*78 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*79 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*80 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*81 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*82 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*83 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*84 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*85 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*86 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*87 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*88 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*89 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*90 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*91 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*92 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*93 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*94 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*95 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*96 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*97 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*98 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*99 */  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*100*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*101*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*102*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*103*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*104*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*105*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*106*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*107*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*108*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*109*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*110*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*111*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*112*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*113*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*114*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*115*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*116*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*117*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*118*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*119*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*120*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*121*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*122*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*123*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*124*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*125*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*126*/  0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_DCS_PASSTHROUGH = 8 */
+		/*0  */  VTRECV_ACTION_PUT | (0 << 4),
+		/*1  */  VTRECV_ACTION_PUT | (0 << 4),
+		/*2  */  VTRECV_ACTION_PUT | (0 << 4),
+		/*3  */  VTRECV_ACTION_PUT | (0 << 4),
+		/*4  */  VTRECV_ACTION_PUT | (0 << 4),
+		/*5  */  VTRECV_ACTION_PUT | (0 << 4),
+		/*6  */  VTRECV_ACTION_PUT | (0 << 4),
+		/*7  */  VTRECV_ACTION_PUT | (0 << 4),
+		/*8  */  VTRECV_ACTION_PUT | (0 << 4),
+		/*9  */  VTRECV_ACTION_PUT | (0 << 4),
+		/*10 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*11 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*12 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*13 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*14 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*15 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*16 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*17 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*18 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*19 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*20 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*21 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*22 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*23 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*29 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*30 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*31 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*32 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*33 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*34 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*35 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*36 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*37 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*38 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*39 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*40 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*41 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*42 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*43 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*44 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*45 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*46 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*47 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*48 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*49 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*50 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*51 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*52 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*53 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*54 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*55 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*56 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*57 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*58 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*59 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*60 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*61 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*62 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*63 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*64 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*65 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*66 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*67 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*68 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*69 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*70 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*71 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*72 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*73 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*74 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*75 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*76 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*77 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*78 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*79 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*80 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*81 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*82 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*83 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*84 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*85 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*86 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*87 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*88 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*89 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*90 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*91 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*92 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*93 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*94 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*95 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*96 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*97 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*98 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*99 */  VTRECV_ACTION_PUT | (0 << 4),
+		/*100*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*101*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*102*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*103*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*104*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*105*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*106*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*107*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*108*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*109*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*110*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*111*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*112*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*113*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*114*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*115*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*116*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*117*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*118*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*119*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*120*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*121*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*122*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*123*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*124*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*125*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*126*/  VTRECV_ACTION_PUT | (0 << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_ESCAPE = 9 */
+		/*0  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*1  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*2  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*3  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*4  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*5  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*6  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*7  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*8  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*9  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*10 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*11 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*12 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*13 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*14 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*15 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*16 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*17 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*18 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*19 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*20 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*21 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*22 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*23 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*29 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*30 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*31 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*32 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*33 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*34 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*35 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*36 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*37 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*38 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*39 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*40 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*41 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*42 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*43 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*44 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*45 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*46 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*47 */  VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4),
+		/*48 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*49 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*50 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*51 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*52 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*53 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*54 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*55 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*56 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*57 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*58 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*59 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*60 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*61 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*62 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*63 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*64 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*65 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*66 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*67 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*68 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*69 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*70 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*71 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*72 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*73 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*74 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*75 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*76 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*77 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*78 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*79 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*80 */  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*81 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*82 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*83 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*84 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*85 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*86 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*87 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*88 */  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*89 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*90 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*91 */  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*92 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*93 */  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*94 */  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*95 */  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*96 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*97 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*98 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*99 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*100*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*101*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*102*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*103*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*104*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*105*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*106*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*107*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*108*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*109*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*110*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*111*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*112*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*113*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*114*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*115*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*116*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*117*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*118*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*119*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*120*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*121*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*122*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*123*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*124*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*125*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*126*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_ESCAPE_INTERMEDIATE = 10 */
+		/*0  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*1  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*2  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*3  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*4  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*5  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*6  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*7  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*8  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*9  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*10 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*11 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*12 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*13 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*14 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*15 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*16 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*17 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*18 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*19 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*20 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*21 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*22 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*23 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*29 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*30 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*31 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*32 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*33 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*34 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*35 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*36 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*37 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*38 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*39 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*40 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*41 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*42 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*43 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*44 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*45 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*46 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*47 */  VTRECV_ACTION_COLLECT | (0 << 4),
+		/*48 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*49 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*50 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*51 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*52 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*53 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*54 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*55 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*56 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*57 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*58 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*59 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*60 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*61 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*62 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*63 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*64 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*65 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*66 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*67 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*68 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*69 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*70 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*71 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*72 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*73 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*74 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*75 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*76 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*77 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*78 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*79 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*80 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*81 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*82 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*83 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*84 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*85 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*86 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*87 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*88 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*89 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*90 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*91 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*92 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*93 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*94 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*95 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*96 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*97 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*98 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*99 */  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*100*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*101*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*102*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*103*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*104*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*105*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*106*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*107*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*108*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*109*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*110*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*111*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*112*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*113*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*114*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*115*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*116*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*117*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*118*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*119*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*120*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*121*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*122*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*123*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*124*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*125*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*126*/  VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_GROUND = 11 */
+		/*0  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*1  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*2  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*3  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*4  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*5  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*6  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*7  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*8  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*9  */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*10 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*11 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*12 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*13 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*14 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*15 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*16 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*17 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*18 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*19 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*20 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*21 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*22 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*23 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*29 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*30 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*31 */  VTRECV_ACTION_EXECUTE | (0 << 4),
+		/*32 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*33 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*34 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*35 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*36 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*37 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*38 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*39 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*40 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*41 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*42 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*43 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*44 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*45 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*46 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*47 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*48 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*49 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*50 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*51 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*52 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*53 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*54 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*55 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*56 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*57 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*58 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*59 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*60 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*61 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*62 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*63 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*64 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*65 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*66 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*67 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*68 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*69 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*70 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*71 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*72 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*73 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*74 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*75 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*76 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*77 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*78 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*79 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*80 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*81 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*82 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*83 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*84 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*85 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*86 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*87 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*88 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*89 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*90 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*91 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*92 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*93 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*94 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*95 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*96 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*97 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*98 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*99 */  VTRECV_ACTION_PRINT | (0 << 4),
+		/*100*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*101*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*102*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*103*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*104*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*105*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*106*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*107*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*108*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*109*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*110*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*111*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*112*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*113*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*114*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*115*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*116*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*117*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*118*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*119*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*120*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*121*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*122*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*123*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*124*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*125*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*126*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*127*/  VTRECV_ACTION_PRINT | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_OSC_STRING = 12 */
+		/*0  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*1  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*2  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*3  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*4  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*5  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*6  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*7  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*8  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*9  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*10 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*11 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*12 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*13 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*14 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*15 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*16 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*17 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*18 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*19 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*20 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*21 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*22 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*23 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*29 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*30 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*31 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*32 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*33 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*34 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*35 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*36 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*37 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*38 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*39 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*40 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*41 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*42 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*43 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*44 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*45 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*46 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*47 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*48 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*49 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*50 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*51 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*52 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*53 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*54 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*55 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*56 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*57 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*58 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*59 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*60 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*61 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*62 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*63 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*64 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*65 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*66 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*67 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*68 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*69 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*70 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*71 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*72 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*73 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*74 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*75 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*76 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*77 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*78 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*79 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*80 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*81 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*82 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*83 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*84 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*85 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*86 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*87 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*88 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*89 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*90 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*91 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*92 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*93 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*94 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*95 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*96 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*97 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*98 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*99 */  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*100*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*101*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*102*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*103*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*104*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*105*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*106*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*107*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*108*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*109*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*110*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*111*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*112*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*113*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*114*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*115*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*116*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*117*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*118*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*119*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*120*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*121*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*122*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*123*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*124*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*125*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*126*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*127*/  VTRECV_ACTION_OSC_PUT | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+	{	/* VTRECV_STATE_SOS_PM_APC_STRING = 13 */
+		/*0  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*1  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*2  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*3  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*4  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*5  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*6  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*7  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*8  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*9  */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*10 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*11 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*12 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*13 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*14 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*15 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*16 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*17 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*18 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*19 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*20 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*21 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*22 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*23 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*24 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*25 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*26 */  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*27 */  0 | (VTRECV_STATE_ESCAPE << 4),
+		/*28 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*29 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*30 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*31 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*32 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*33 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*34 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*35 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*36 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*37 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*38 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*39 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*40 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*41 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*42 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*43 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*44 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*45 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*46 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*47 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*48 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*49 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*50 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*51 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*52 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*53 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*54 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*55 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*56 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*57 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*58 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*59 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*60 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*61 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*62 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*63 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*64 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*65 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*66 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*67 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*68 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*69 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*70 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*71 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*72 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*73 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*74 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*75 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*76 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*77 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*78 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*79 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*80 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*81 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*82 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*83 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*84 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*85 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*86 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*87 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*88 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*89 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*90 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*91 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*92 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*93 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*94 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*95 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*96 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*97 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*98 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*99 */  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*100*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*101*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*102*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*103*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*104*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*105*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*106*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*107*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*108*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*109*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*110*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*111*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*112*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*113*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*114*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*115*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*116*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*117*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*118*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*119*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*120*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*121*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*122*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*123*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*124*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*125*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*126*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*127*/  VTRECV_ACTION_IGNORE | (0 << 4),
+		/*128*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*129*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*130*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*131*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*132*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*133*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*134*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*135*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*136*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*137*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*138*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*139*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*140*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*141*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*142*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*143*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*144*/  0 | (VTRECV_STATE_DCS_ENTRY << 4),
+		/*145*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*146*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*147*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*148*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*149*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*150*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*151*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*152*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*153*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*154*/  VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4),
+		/*155*/  0 | (VTRECV_STATE_CSI_ENTRY << 4),
+		/*156*/  0 | (VTRECV_STATE_GROUND << 4),
+		/*157*/  0 | (VTRECV_STATE_OSC_STRING << 4),
+		/*158*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+		/*159*/  0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4),
+	},
+};
+#else
+typedef struct
+{
+	int state;
+	unsigned char code_start;
+	unsigned char code_end;
+	state_change_t state_change;
+} state_table_t;
+
+static const state_table_t table[] = {
+	/*
+	 */
+	{  VTRECV_STATE_CSI_ENTRY,   0,  23, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  25,  25, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  28,  31, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  32,  47, VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  48,  57, VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  58,  58, 0 | (VTRECV_STATE_CSI_IGNORE << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  59,  59, VTRECV_ACTION_PARAM | (VTRECV_STATE_CSI_PARAM << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  60,  63, VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_PARAM << 4) },
+	{  VTRECV_STATE_CSI_ENTRY,  64, 126, VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_ENTRY, 127, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_CSI_ENTRY, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_ENTRY, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_CSI_ENTRY, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_ENTRY, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_CSI_ENTRY, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_ENTRY, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_CSI_ENTRY, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_ENTRY, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_CSI_ENTRY, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_CSI_IGNORE,   0,  23, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_IGNORE,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_IGNORE,  25,  25, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_IGNORE,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_IGNORE,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_CSI_IGNORE,  28,  31, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_IGNORE,  32,  63, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_CSI_IGNORE,  64, 126, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_IGNORE, 127, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_CSI_IGNORE, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_IGNORE, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_CSI_IGNORE, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_IGNORE, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_CSI_IGNORE, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_IGNORE, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_CSI_IGNORE, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_IGNORE, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_CSI_IGNORE, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_CSI_INTERMEDIATE,   0,  23, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE,  25,  25, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE,  28,  31, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE,  32,  47, VTRECV_ACTION_COLLECT | (0 << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE,  48,  63, 0 | (VTRECV_STATE_CSI_IGNORE << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE,  64, 126, VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE, 127, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_CSI_INTERMEDIATE, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_CSI_PARAM,   0,  23, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  25,  25, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  28,  31, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  32,  47, VTRECV_ACTION_COLLECT | (VTRECV_STATE_CSI_INTERMEDIATE << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  48,  57, VTRECV_ACTION_PARAM | (0 << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  58,  58, 0 | (VTRECV_STATE_CSI_IGNORE << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  59,  59, VTRECV_ACTION_PARAM | (0 << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  60,  63, 0 | (VTRECV_STATE_CSI_IGNORE << 4) },
+	{  VTRECV_STATE_CSI_PARAM,  64, 126, VTRECV_ACTION_CSI_DISPATCH | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_PARAM, 127, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_CSI_PARAM, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_PARAM, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_CSI_PARAM, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_PARAM, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_CSI_PARAM, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_PARAM, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_CSI_PARAM, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_CSI_PARAM, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_CSI_PARAM, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_DCS_ENTRY,   0,  23, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  25,  25, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  28,  31, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  32,  47, VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  48,  57, VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  58,  58, 0 | (VTRECV_STATE_DCS_IGNORE << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  59,  59, VTRECV_ACTION_PARAM | (VTRECV_STATE_DCS_PARAM << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  60,  63, VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_PARAM << 4) },
+	{  VTRECV_STATE_DCS_ENTRY,  64, 126, 0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4) },
+	{  VTRECV_STATE_DCS_ENTRY, 127, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_ENTRY, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_ENTRY, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_DCS_ENTRY, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_ENTRY, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_DCS_ENTRY, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_ENTRY, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_DCS_ENTRY, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_ENTRY, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_DCS_ENTRY, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_DCS_IGNORE,   0,  23, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_IGNORE,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_IGNORE,  25,  25, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_IGNORE,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_IGNORE,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_DCS_IGNORE,  28, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_IGNORE, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_IGNORE, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_DCS_IGNORE, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_IGNORE, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_DCS_IGNORE, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_IGNORE, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_DCS_IGNORE, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_IGNORE, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_DCS_IGNORE, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_DCS_INTERMEDIATE,   0,  23, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE,  25,  25, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE,  28,  31, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE,  32,  47, VTRECV_ACTION_COLLECT | (0 << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE,  48,  63, 0 | (VTRECV_STATE_DCS_IGNORE << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE,  64, 126, 0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE, 127, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_DCS_INTERMEDIATE, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_DCS_PARAM,   0,  23, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  25,  25, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  28,  31, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  32,  47, VTRECV_ACTION_COLLECT | (VTRECV_STATE_DCS_INTERMEDIATE << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  48,  57, VTRECV_ACTION_PARAM | (0 << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  58,  58, 0 | (VTRECV_STATE_DCS_IGNORE << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  59,  59, VTRECV_ACTION_PARAM | (0 << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  60,  63, 0 | (VTRECV_STATE_DCS_IGNORE << 4) },
+	{  VTRECV_STATE_DCS_PARAM,  64, 126, 0 | (VTRECV_STATE_DCS_PASSTHROUGH << 4) },
+	{  VTRECV_STATE_DCS_PARAM, 127, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_PARAM, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PARAM, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_DCS_PARAM, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PARAM, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_DCS_PARAM, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PARAM, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_DCS_PARAM, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PARAM, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_DCS_PARAM, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_DCS_PASSTHROUGH,   0,  23, VTRECV_ACTION_PUT | (0 << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH,  25,  25, VTRECV_ACTION_PUT | (0 << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH,  28, 126, VTRECV_ACTION_PUT | (0 << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH, 127, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_DCS_PASSTHROUGH, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_ESCAPE,   0,  23, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_ESCAPE,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE,  25,  25, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_ESCAPE,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_ESCAPE,  28,  31, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_ESCAPE,  32,  47, VTRECV_ACTION_COLLECT | (VTRECV_STATE_ESCAPE_INTERMEDIATE << 4) },
+	{  VTRECV_STATE_ESCAPE,  48,  79, VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE,  80,  80, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_ESCAPE,  81,  87, VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE,  88,  88, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_ESCAPE,  89,  90, VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE,  91,  91, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_ESCAPE,  92,  92, VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE,  93,  93, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_ESCAPE,  94,  95, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_ESCAPE,  96, 126, VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE, 127, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_ESCAPE, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_ESCAPE, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_ESCAPE, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_ESCAPE, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_ESCAPE, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE,   0,  23, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE,  25,  25, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE,  28,  31, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE,  32,  47, VTRECV_ACTION_COLLECT | (0 << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE,  48, 126, VTRECV_ACTION_ESC_DISPATCH | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE, 127, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_ESCAPE_INTERMEDIATE, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_GROUND,   0,  23, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_GROUND,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_GROUND,  25,  25, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_GROUND,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_GROUND,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_GROUND,  28,  31, VTRECV_ACTION_EXECUTE | (0 << 4) },
+	{  VTRECV_STATE_GROUND,  32, 127, VTRECV_ACTION_PRINT | (0 << 4) },
+	{  VTRECV_STATE_GROUND, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_GROUND, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_GROUND, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_GROUND, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_GROUND, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_GROUND, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_GROUND, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_GROUND, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_GROUND, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_OSC_STRING,   0,  23, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_OSC_STRING,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_OSC_STRING,  25,  25, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_OSC_STRING,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_OSC_STRING,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_OSC_STRING,  28,  31, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_OSC_STRING,  32, 127, VTRECV_ACTION_OSC_PUT | (0 << 4) },
+	{  VTRECV_STATE_OSC_STRING, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_OSC_STRING, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_OSC_STRING, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_OSC_STRING, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_OSC_STRING, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_OSC_STRING, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_OSC_STRING, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_OSC_STRING, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_OSC_STRING, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	/*
+	 */
+	{  VTRECV_STATE_SOS_PM_APC_STRING,   0,  23, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING,  24,  24, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING,  25,  25, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING,  26,  26, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING,  27,  27, 0 | (VTRECV_STATE_ESCAPE << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING,  28, 127, VTRECV_ACTION_IGNORE | (0 << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING, 128, 143, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING, 144, 144, 0 | (VTRECV_STATE_DCS_ENTRY << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING, 145, 151, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING, 152, 152, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING, 153, 154, VTRECV_ACTION_EXECUTE | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING, 155, 155, 0 | (VTRECV_STATE_CSI_ENTRY << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING, 156, 156, 0 | (VTRECV_STATE_GROUND << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING, 157, 157, 0 | (VTRECV_STATE_OSC_STRING << 4) },
+	{  VTRECV_STATE_SOS_PM_APC_STRING, 158, 159, 0 | (VTRECV_STATE_SOS_PM_APC_STRING << 4) },
+};
+#endif
+
+static const vtrecv_action_t ENTRY_ACTIONS[] = {
+   VTRECV_ACTION_CLEAR, /* CSI_ENTRY */
+   0  /* none for CSI_IGNORE */,
+   0  /* none for CSI_INTERMEDIATE */,
+   0  /* none for CSI_PARAM */,
+   VTRECV_ACTION_CLEAR, /* DCS_ENTRY */
+   0  /* none for DCS_IGNORE */,
+   0  /* none for DCS_INTERMEDIATE */,
+   0  /* none for DCS_PARAM */,
+   VTRECV_ACTION_HOOK, /* DCS_PASSTHROUGH */
+   VTRECV_ACTION_CLEAR, /* ESCAPE */
+   0  /* none for ESCAPE_INTERMEDIATE */,
+   0  /* none for GROUND */,
+   VTRECV_ACTION_OSC_START, /* OSC_STRING */
+   0  /* none for SOS_PM_APC_STRING */,
+};
+
+static const vtrecv_action_t EXIT_ACTIONS[] = {
+   0  /* none for CSI_ENTRY */,
+   0  /* none for CSI_IGNORE */,
+   0  /* none for CSI_INTERMEDIATE */,
+   0  /* none for CSI_PARAM */,
+   0  /* none for DCS_ENTRY */,
+   0  /* none for DCS_IGNORE */,
+   0  /* none for DCS_INTERMEDIATE */,
+   0  /* none for DCS_PARAM */,
+   VTRECV_ACTION_UNHOOK, /* DCS_PASSTHROUGH */
+   0  /* none for ESCAPE */,
+   0  /* none for ESCAPE_INTERMEDIATE */,
+   0  /* none for GROUND */,
+   VTRECV_ACTION_OSC_END, /* OSC_STRING */
+   0  /* none for SOS_PM_APC_STRING */,
+};
+
+state_change_t GET_STATE_TABLE(const int state, const int ch)
+{
+	if ((state == VTRECV_STATE_GROUND) && (((ch >= 32) && (ch <= 127)) || (ch >= 160))) {
+		return VTRECV_ACTION_PRINT | (0 << 4);
+	}
+#if (USE_ORIGINAL_LUT==1)
+	/*
+	 * テーブル参照による実現。
+	 * 固定時間で動作するが、コードサイズは比較的大きい。
+	 */
+	return STATE_TABLE[state - 1][ch];
+#else
+	/*
+	 * プログラムによる線形探索バージョン。
+	 * テーブルの後方にあるデータになるほど動作は遅い。
+	 * コードサイズはテーブル参照よりも小さい。
+	 */
+	const int N = sizeof(table) / sizeof(table[0]);
+	const state_table_t *tp = &table[0];
+	int i;
+	for (i = 0; i < N; i++) {
+		if (tp->state == state) {
+			if ((tp->code_start <= ch) && (ch <= tp->code_end)) {
+				return tp->state_change;
+			}
+		}
+		tp++;
+	}
+	return 0;
+#endif
+}
+
+vtrecv_action_t GET_ENTRY_ACTIONS(const int state)
+{
+	return ENTRY_ACTIONS[state];
+}
+
+vtrecv_action_t GET_EXIT_ACTIONS(const int state)
+{
+	return EXIT_ACTIONS[state];
+}
+
+void vtrecv_init(vtrecv_t *parser, vtrecv_callback_t cb)
+{
+	parser->utf8_state = 0;
+	parser->ch = 0;
+	parser->state = VTRECV_STATE_GROUND;
+	parser->num_intermediate_chars = 0;
+	parser->num_params = 0;
+	parser->ignore_flagged = 0;
+	parser->cb = cb;
+}
+
+static void do_action(vtrecv_t *parser, vtrecv_action_t action, unsigned int ch)
+{
+	/* Some actions we handle internally (like parsing parameters), others
+	 * we hand to our client for processing */
+
+	switch (action) {
+	case VTRECV_ACTION_PRINT:
+	case VTRECV_ACTION_EXECUTE:
+	case VTRECV_ACTION_HOOK:
+	case VTRECV_ACTION_PUT:
+	case VTRECV_ACTION_OSC_START:
+	case VTRECV_ACTION_OSC_PUT:
+	case VTRECV_ACTION_OSC_END:
+	case VTRECV_ACTION_UNHOOK:
+	case VTRECV_ACTION_CSI_DISPATCH:
+	case VTRECV_ACTION_ESC_DISPATCH:
+		parser->cb(parser, action, ch);
+		break;
+
+	case VTRECV_ACTION_IGNORE:
+		/* do nothing */
+		break;
+
+	case VTRECV_ACTION_COLLECT:
+	{
+		/* Append the character to the intermediate params */
+		if (parser->num_intermediate_chars + 1 > MAX_INTERMEDIATE_CHARS) {
+			parser->ignore_flagged = 1;
+		}
+		else {
+			parser->intermediate_chars[parser->num_intermediate_chars++] = ch;
+		}
+
+		break;
+	}
+
+	case VTRECV_ACTION_PARAM:
+	{
+		/* process the param character */
+		if (ch == ';') {
+			parser->num_params += 1;
+			parser->params[parser->num_params - 1] = 0;
+		}
+		else {
+			/* the character is a digit */
+			int current_param;
+
+			if (parser->num_params == 0) {
+				parser->num_params = 1;
+				parser->params[0] = 0;
+			}
+
+			current_param = parser->num_params - 1;
+			parser->params[current_param] *= 10;
+			parser->params[current_param] += (ch - '0');
+		}
+
+		break;
+	}
+
+	case VTRECV_ACTION_CLEAR:
+		parser->num_intermediate_chars = 0;
+		parser->num_params = 0;
+		parser->ignore_flagged = 0;
+		break;
+
+	default:
+		parser->cb(parser, VTRECV_ACTION_ERROR, 0);
+		break;
+	}
+}
+
+static void do_state_change(vtrecv_t *parser, state_change_t change, unsigned int ch)
+{
+	/* A state change is an action and/or a new state to transition to. */
+
+	vtrecv_state_t new_state = STATE(change);
+	vtrecv_action_t action = ACTION(change);
+
+	if (new_state) {
+		/*
+		 * Perform up to three actions:
+		 *   1. the exit action of the old state
+		 *   2. the action associated with the transition
+		 *   3. the entry action of the new state
+		 */
+
+		vtrecv_action_t exit_action = GET_EXIT_ACTIONS(parser->state - 1);
+		vtrecv_action_t entry_action = GET_ENTRY_ACTIONS(new_state - 1);
+
+		if (exit_action) {
+			do_action(parser, exit_action, 0);
+		}
+
+		if (action) {
+			do_action(parser, action, ch);
+		}
+
+		if (entry_action) {
+			do_action(parser, entry_action, 0);
+		}
+
+		parser->state = new_state;
+	}
+	else {
+		do_action(parser, action, ch);
+	}
+}
+
+void vtrecv_execute(vtrecv_t *parser, unsigned char *data, int len)
+{
+	int i;
+	for (i = 0; i < len; i++) {
+		unsigned char c = data[i];
+		/* UTF-8 => UNICODE */
+		switch (parser->utf8_state) {
+		case 0:
+			if (c <= 0x7F) {
+				parser->ch = c;
+				break;
+			}
+			else if ((c & 0xE0) == 0xC0) {
+				parser->ch = (c & 0x1F) << 6;
+				parser->utf8_state = 1;
+				continue;
+			}
+			else if ((c & 0xF0) == 0xE0) {
+				parser->ch = (c & 0x0F) << 12;
+				parser->utf8_state = 2;
+				continue;
+			}
+			else if ((c & 0xF8) == 0xF0) {
+				parser->ch = (c & 0x07) << 18;
+				parser->utf8_state = 3;
+				continue;
+			}
+			else if ((c & 0xFC) == 0xF8) {
+				parser->ch = (c & 0x03) << 24;
+				parser->utf8_state = 4;
+				continue;
+			}
+			else if ((c & 0xFE) == 0xFC) {
+				parser->ch = (c & 0x01) << 30;
+				parser->utf8_state = 5;
+				continue;
+			}
+			else if (c == 0xFF) {
+				return;
+			}
+		default:
+			if ((c & 0xC0) == 0x80) {
+				parser->utf8_state--;
+				parser->ch |= (c & 0x3F) << (6 * parser->utf8_state);
+				if (parser->utf8_state != 0)
+					continue;
+			}
+			/* UTF-8 Error */
+			else {
+				i--;
+				parser->utf8_state = 0;
+			}
+			break;
+		}
+		state_change_t change = GET_STATE_TABLE(parser->state, parser->ch);
+		do_state_change(parser, change, parser->ch);
+		parser->ch = 0;
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtrecv.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtrecv.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtrecv.h	(revision 398)
@@ -0,0 +1,132 @@
+/**
+ * @file vtrecv.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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.
+ */
+
+/*
+ * @note
+ * An implementation of Paul Williams' DEC compatible state machine parser.
+ * This code is in the public domain.
+ *
+ * @author Joshua Haberman <joshua@reverberate.org>
+ * @author Shinichiro Nakamura : Modified for Natural Tiny Shell (NT-Shell)
+ */
+
+#ifndef VTRECV_H
+#define VTRECV_H
+
+/**
+ * @brief オリジナルに含まれるLUTを使うかどうかを決定する。
+ * @details
+ * オリジナルでは、シーケンスの遷移をテーブル参照で実装してあった。
+ * 15のステートで取りうる256パターンの入力を全網羅するテーブルである。
+ * これは3840個のテーブルデータを持つことになる。
+ *
+ * テーブル参照はメモリに対してリニアアクセス可能なプロセッサにおいて
+ * 固定時間で動作する。テーブル参照のメリットは固定時間での処理である。
+ *
+ * 一方、新たに実装した方法は、重複するデータが多数存在する事に着目した
+ * もので、区間毎に適用するシーケンスを定義したテーブルを用いる。
+ * これはテーブルを線形探索するため後方にあるデータになるほど動作は遅い。
+ * しかし、コードサイズはオリジナルの全網羅形式のテーブルよりも小さい。
+ *
+ * @retval 0 使わない。
+ * @retval 1 使う。
+ */
+#define USE_ORIGINAL_LUT (0)
+
+#define MAX_INTERMEDIATE_CHARS 2
+#define ACTION(state_change) (vtrecv_action_t)((state_change & 0x0F) >> 0)
+#define STATE(state_change)  (vtrecv_state_t)((state_change & 0xF0) >> 4)
+
+typedef enum {
+	VTRECV_STATE_CSI_ENTRY = 1,
+	VTRECV_STATE_CSI_IGNORE = 2,
+	VTRECV_STATE_CSI_INTERMEDIATE = 3,
+	VTRECV_STATE_CSI_PARAM = 4,
+	VTRECV_STATE_DCS_ENTRY = 5,
+	VTRECV_STATE_DCS_IGNORE = 6,
+	VTRECV_STATE_DCS_INTERMEDIATE = 7,
+	VTRECV_STATE_DCS_PARAM = 8,
+	VTRECV_STATE_DCS_PASSTHROUGH = 9,
+	VTRECV_STATE_ESCAPE = 10,
+	VTRECV_STATE_ESCAPE_INTERMEDIATE = 11,
+	VTRECV_STATE_GROUND = 12,
+	VTRECV_STATE_OSC_STRING = 13,
+	VTRECV_STATE_SOS_PM_APC_STRING = 14,
+} vtrecv_state_t;
+
+typedef enum {
+	VTRECV_ACTION_CLEAR = 1,
+	VTRECV_ACTION_COLLECT = 2,
+	VTRECV_ACTION_CSI_DISPATCH = 3,
+	VTRECV_ACTION_ESC_DISPATCH = 4,
+	VTRECV_ACTION_EXECUTE = 5,
+	VTRECV_ACTION_HOOK = 6,
+	VTRECV_ACTION_IGNORE = 7,
+	VTRECV_ACTION_OSC_END = 8,
+	VTRECV_ACTION_OSC_PUT = 9,
+	VTRECV_ACTION_OSC_START = 10,
+	VTRECV_ACTION_PARAM = 11,
+	VTRECV_ACTION_PRINT = 12,
+	VTRECV_ACTION_PUT = 13,
+	VTRECV_ACTION_UNHOOK = 14,
+	VTRECV_ACTION_ERROR = 15,
+} vtrecv_action_t;
+
+typedef unsigned char state_change_t;
+struct vtrecv;
+typedef void (*vtrecv_callback_t)(struct vtrecv*, vtrecv_action_t, unsigned int);
+typedef struct vtrecv {
+	int                utf8_state;
+	unsigned int       ch;
+	vtrecv_state_t     state;
+	vtrecv_callback_t  cb;
+	unsigned char      intermediate_chars[MAX_INTERMEDIATE_CHARS+1];
+	int                num_intermediate_chars;
+	char               ignore_flagged;
+	int                params[16];
+	int                num_params;
+	void*              user_data;
+} vtrecv_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void vtrecv_init(vtrecv_t *parser, vtrecv_callback_t cb);
+void vtrecv_execute(vtrecv_t *parser, unsigned char *data, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtsend.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtsend.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtsend.c	(revision 398)
@@ -0,0 +1,270 @@
+/**
+ * @file vtsend.c
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 "vtsend.h"
+
+#define ESC (0x1B)
+#define UART_WRITE(P, BUF, SIZ)   (P)->uart_write(BUF, SIZ, (P)->extobj)
+
+int vtsend_init(vtsend_t *p, VTSEND_SERIAL_WRITE uart_write, void *extobj)
+{
+	p->uart_write = uart_write;
+	p->extobj = extobj;
+	return 0;
+}
+
+int vtsend_cursor_position(vtsend_t *p, const int column, const int line)
+{
+	char buf[8];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '0' + (line / 10);
+	buf[3] = '0' + (line % 10);
+	buf[4] = ';';
+	buf[5] = '0' + (column / 10);
+	buf[6] = '0' + (column % 10);
+	buf[7] = 'H';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_cursor_up(vtsend_t *p, const int n)
+{
+	char buf[5];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '0' + (n / 10);
+	buf[3] = '0' + (n % 10);
+	buf[4] = 'A';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_cursor_down(vtsend_t *p, const int n)
+{
+	char buf[5];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '0' + (n / 10);
+	buf[3] = '0' + (n % 10);
+	buf[4] = 'B';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_cursor_forward(vtsend_t *p, const int n)
+{
+	char buf[5];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '0' + (n / 10);
+	buf[3] = '0' + (n % 10);
+	buf[4] = 'C';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_cursor_backward(vtsend_t *p, const int n)
+{
+	char buf[5];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '0' + (n / 10);
+	buf[3] = '0' + (n % 10);
+	buf[4] = 'D';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_cursor_position_save(vtsend_t *p)
+{
+	char buf[3];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = 's';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_cursor_position_restore(vtsend_t *p)
+{
+	char buf[3];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = 'u';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_erase_display(vtsend_t *p)
+{
+	char buf[4];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '2';
+	buf[3] = 'J';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_erase_line(vtsend_t *p)
+{
+	char buf[4];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '2';
+	buf[3] = 'K';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_set_color_foreground(vtsend_t *p, const int color)
+{
+	char buf[5];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '0' + ((30 + color) / 10);
+	buf[3] = '0' + ((30 + color) % 10);
+	buf[4] = 'm';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_set_color_background(vtsend_t *p, const int color)
+{
+	char buf[5];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '0' + ((40 + color) / 10);
+	buf[3] = '0' + ((40 + color) % 10);
+	buf[4] = 'm';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_set_attribute(vtsend_t *p, const int attr)
+{
+	char buf[5];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '0' + ((attr) / 10);
+	buf[3] = '0' + ((attr) % 10);
+	buf[4] = 'm';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_set_scroll_region(vtsend_t *p, const int top, const int bottom)
+{
+	char buf[8];
+	buf[0] = ESC;
+	buf[1] = '[';
+	buf[2] = '0' + (top / 10);
+	buf[3] = '0' + (top % 10);
+	buf[4] = ';';
+	buf[5] = '0' + (bottom / 10);
+	buf[6] = '0' + (bottom % 10);
+	buf[7] = 'r';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_set_cursor(vtsend_t *p, const int visible)
+{
+	if (visible) {
+		char buf[6];
+		buf[0] = ESC;
+		buf[1] = '[';
+		buf[2] = '?';
+		buf[3] = '2';
+		buf[4] = '5';
+		buf[5] = 'h';
+		UART_WRITE(p, buf, sizeof(buf));
+	}
+	else {
+		char buf[6];
+		buf[0] = ESC;
+		buf[1] = '[';
+		buf[2] = '?';
+		buf[3] = '2';
+		buf[4] = '5';
+		buf[5] = 'l';
+		UART_WRITE(p, buf, sizeof(buf));
+	}
+	return 0;
+}
+
+int vtsend_reset(vtsend_t *p)
+{
+	char buf[2];
+	buf[0] = ESC;
+	buf[1] = 'c';
+	UART_WRITE(p, buf, sizeof(buf));
+	return 0;
+}
+
+int vtsend_draw_box(
+	vtsend_t *p,
+	const int x1, const int y1, const int x2, const int y2)
+{
+	int i;
+
+	vtsend_cursor_position(p, x1, y1);
+	for (i = x1; i <= x2; i++) {
+		UART_WRITE(p, " ", 1);
+	}
+	vtsend_cursor_position(p, x1, y2);
+	for (i = x1; i <= x2; i++) {
+		UART_WRITE(p, " ", 1);
+	}
+	for (i = y1; i <= y2; i++) {
+		vtsend_cursor_position(p, x1, i);
+		UART_WRITE(p, " ", 1);
+		vtsend_cursor_position(p, x2, i);
+		UART_WRITE(p, " ", 1);
+	}
+	return 0;
+}
+
+int vtsend_fill_box(
+	vtsend_t *p,
+	const int x1, const int y1, const int x2, const int y2)
+{
+	int i, j;
+	for (i = y1; i <= y2; i++) {
+		vtsend_cursor_position(p, x1, i);
+		for (j = x1; j <= x2; j++) {
+			UART_WRITE(p, " ", 1);
+		}
+	}
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtsend.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtsend.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/core/vtsend.h	(revision 398)
@@ -0,0 +1,92 @@
+/**
+ * @file vtsend.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 VTSEND_H
+#define VTSEND_H
+
+#define VTSEND_COLOR_BLACK      (0)
+#define VTSEND_COLOR_RED        (1)
+#define VTSEND_COLOR_GREEN      (2)
+#define VTSEND_COLOR_YELLOW     (3)
+#define VTSEND_COLOR_BLUE       (4)
+#define VTSEND_COLOR_MAGENTA    (5)
+#define VTSEND_COLOR_CYAN       (6)
+#define VTSEND_COLOR_WHITE      (7)
+
+#define VTSEND_ATTR_OFF             (0)
+#define VTSEND_ATTR_BOLD_ON         (1)
+#define VTSEND_ATTR_UNDERSCORE      (4)
+#define VTSEND_ATTR_BLINK_ON        (5)
+#define VTSEND_ATTR_REVERSE         (7)
+#define VTSEND_ATTR_CONCEALED_ON    (8)
+
+typedef int (*VTSEND_SERIAL_WRITE)(const char *buf, const int siz, void *extobj);
+
+typedef struct {
+    VTSEND_SERIAL_WRITE uart_write;
+    void *extobj;
+} vtsend_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int vtsend_init(vtsend_t *p, VTSEND_SERIAL_WRITE uart_write, void *extobj);
+int vtsend_cursor_position(vtsend_t *p, const int column, const int line);
+int vtsend_cursor_up(vtsend_t *p, const int n);
+int vtsend_cursor_down(vtsend_t *p, const int n);
+int vtsend_cursor_forward(vtsend_t *p, const int n);
+int vtsend_cursor_backward(vtsend_t *p, const int n);
+int vtsend_cursor_position_save(vtsend_t *p);
+int vtsend_cursor_position_restore(vtsend_t *p);
+int vtsend_erase_display(vtsend_t *p);
+int vtsend_erase_line(vtsend_t *p);
+int vtsend_set_color_foreground(vtsend_t *p, const int color);
+int vtsend_set_color_background(vtsend_t *p, const int color);
+int vtsend_set_attribute(vtsend_t *p, const int attr);
+int vtsend_set_scroll_region(vtsend_t *p, const int top, const int bottom);
+int vtsend_set_cursor(vtsend_t *p, const int visible);
+int vtsend_reset(vtsend_t *p);
+
+int vtsend_draw_box(
+        vtsend_t *p,
+        const int x1, const int y1, const int x2, const int y2);
+int vtsend_fill_box(
+        vtsend_t *p,
+        const int x1, const int y1, const int x2, const int y2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/usrcmd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/usrcmd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/usrcmd.c	(revision 398)
@@ -0,0 +1,730 @@
+/**
+ * @file usrcmd.c
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 "shellif.h"
+#include <kernel.h>
+#include <string.h>
+#include <stdlib.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include "syssvc/syslog.h"
+#include "target_syssvc.h"
+#include "kernel_cfg.h"
+#include "main.h"
+#include "ffarch.h"
+#include "ff.h"
+#include "usrcmd.h"
+#include "core/ntshell.h"
+#include "core/ntlibc.h"
+#include <stdio.h>
+#include <getopt.h>
+
+extern int ntshell_exit;
+
+void put_rc(const char *func, FRESULT rc)
+{
+	const char *p =
+		"OK\0DISK_ERR\0INT_ERR\0NOT_READY\0NO_FILE\0NO_PATH\0INVALID_NAME\0"
+		"DENIED\0EXIST\0INVALID_OBJECT\0WRITE_PROTECTED\0INVALID_DRIVE\0"
+		"NOT_ENABLED\0NO_FILE_SYSTEM\0MKFS_ABORTED\0TIMEOUT\0LOCKED\0"
+		"NOT_ENOUGH_CORE\0TOO_MANY_OPEN_FILES\0";
+	FRESULT i;
+
+	for (i = 0; i != rc && *p; i++) {
+		while (*p++);
+	}
+	printf("%s() =>%u FR_%s\n", func, (UINT)rc, p);
+}
+
+void put_drc(const char *func, DRESULT rc)
+{
+	const char *p =
+		"Successful\0R/W Error\0Write Protected\0Not Ready\0Invalid Parameter\0";
+	DRESULT i;
+
+	for (i = 0; i != rc && *p; i++) {
+		while (*p++);
+	}
+	printf("%s() =>%u %s\n", func, (UINT)rc, p);
+}
+
+char *basename(char *s)
+{
+	size_t i, j;
+	if (!s || !*s) return ".";
+	i = strlen(s) - 1;
+	for (j = 0; j <= i; j++) if (s[j] == ':') { s = &s[j + 1]; i -= j; break; }
+	for (; i&&s[i] == '/'; i--) s[i] = 0;
+	for (; i&&s[i - 1] != '/'; i--);
+	return s + i;
+}
+
+char *dirname(char *_s)
+{
+	char *s = _s;
+	size_t i, j;
+	if (!s || !*s) return ".";
+	i = strlen(s) - 1;
+	for (j = 0; j <= i; j++) if (s[j] == ':') { s = &s[j + 1]; i -= j; break; }
+	for (; s[i] == '/'; i--) if (!i) return (s == _s) ? "/" : _s;
+	for (; s[i] != '/'; i--) if (!i) return (s == _s) ? "." : _s;
+	for (; s[i] == '/'; i--) if (!i) { if (s == _s) return "/"; else break; }
+	s[i + 1] = 0;
+	return _s;
+}
+
+int usrcmd_cd(int argc, char **argv)
+{
+	FRESULT res;
+
+	if (argc == 2) {
+		if ((res = f_chdir(argv[1])) != FR_OK) {
+			put_rc("f_chdir", res);
+			return 0;
+		}
+		if ((res = f_chdrive(argv[1]) != FR_OK)) {
+			put_rc("f_chdrive", res);
+			return 0;
+		}
+	}
+
+	char path[256];
+	if ((res = f_getcwd(path, sizeof(path))) != FR_OK) {
+		put_rc("f_getcwd", res);
+		return 0;
+	}
+
+	ntlibc_strlcat(path, "\n", sizeof(path));
+	printf(path);
+
+	return 0;
+}
+
+#define LS_ALL	0x01
+#define LS_LONG	0x02
+/* lsコマンド 1行表示 */
+void print_one_list(FILINFO *fno, BYTE list_option)
+{
+	char *fn;
+
+#if FF_USE_LFN
+	fn = *fno->lfname ? fno->lfname : fno->fname;
+#else
+	fn = fno->fname;
+#endif
+	if (!(list_option & LS_ALL)) {
+		if ((fno->fattrib & AM_HID) || (fn[0] == '.'))
+			return;
+	}
+
+	if (list_option & LS_LONG) {
+		printf("%c%c%c%c%c %04d/%02d/%02d %02d:%02d:%02d ",
+			(fno->fattrib & AM_DIR) ? 'd' : '-',
+			(fno->fattrib & AM_RDO) ? 'r' : '-',
+			(fno->fattrib & AM_HID) ? 'h' : '-',
+			(fno->fattrib & AM_SYS) ? 's' : '-',
+			(fno->fattrib & AM_ARC) ? 'a' : '-',
+			((fno->fdate & 0xFE00) >> 9) + 1980,
+			((fno->fdate & 0x01E0) >> 5),
+			( fno->fdate & 0x001F),
+			((fno->ftime & 0xF800) >> 11),
+			((fno->ftime & 0x07E0) >> 5),
+			( fno->ftime & 0x001F));
+
+		if (fno->fattrib & AM_DIR) {                    /* It is a directory */
+			printf("%10s ", " ");
+		}
+		else {
+			printf("%10lu ", fno->fsize);
+		}
+	}
+
+	if (fno->fattrib & AM_DIR) {                    /* It is a directory */
+		printf("\x1B[32m%s\x1B[0m\n", fn);
+	}
+	else {
+		printf("%s\n", fn);
+	}
+}
+
+#define LFN_BUF_SIZE (FF_MAX_LFN + 1)
+/* lsコマンド dir内 表示 */
+void print_ls(char *path_p, char *pattern_p, BYTE list_option)
+{
+	FRESULT res;
+	FILINFO fno;
+	FATFS_DIR dir;
+	char *fn;   /* This function assumes non-Unicode configuration */
+
+	if ((pattern_p != NULL) && (pattern_p[0] == '\0'))
+		pattern_p = NULL;
+
+	char *path_backup = NULL;
+	path_backup = ff_memalloc(LFN_BUF_SIZE);
+	if (path_backup == NULL) {
+		printf("ff_memalloc err.\n");
+		return;
+	}
+
+#if FF_USE_LFN
+	char *lfn = NULL;
+	lfn = ff_memalloc(LFN_BUF_SIZE);
+	if (lfn == NULL) {
+		printf("ff_memalloc err.\n");
+		ff_memfree(path_backup);
+		return;
+	}
+	fno.lfname = lfn;
+	fno.lfsize = LFN_BUF_SIZE;
+#endif
+
+	if ((path_p != NULL) && (pattern_p == NULL)) {
+		if ((res = f_opendir(&dir, path_p)) != FR_OK)
+			put_rc("f_opendir", res);
+		res = f_readdir(&dir, &fno);
+	}
+	else {
+		res = f_findfirst(&dir, &fno, path_p, pattern_p);
+	}
+
+	while ((res == FR_OK) && (fno.fname[0] != 0)) {
+		if (pattern_p != NULL && (fno.fattrib & AM_DIR) && ((fno.fname[0] == '.') ? (pattern_p[0] == '.') : 1)) {/* FATFS_DIR とパターンマッチしている場合は FATFS_DIR 内部を ls する */
+#if FF_USE_LFN
+			fn = *fno.lfname ? fno.lfname : fno.fname;
+#else
+			fn = fno->fname;
+#endif
+			if ((res = f_getcwd(path_backup, LFN_BUF_SIZE)) != FR_OK) {
+				put_rc("f_getcwd", res);
+			}
+
+			if ((res = f_chdrive(path_p)) != FR_OK) {
+				put_rc("f_chdrive", res);
+			}
+
+			if ((res = f_chdir(path_p)) != FR_OK) {
+				put_rc("f_chdir", res);
+			}
+
+			printf("\n%s/%s:\n", path_p, fn);
+
+			print_ls(fn, NULL, list_option);
+
+			printf("\n");
+
+			if ((res = f_chdrive(path_backup)) != FR_OK) {
+				put_rc("f_chdrive", res);
+			}
+
+			if ((res = f_chdir(path_backup)) != FR_OK) {
+				put_rc("f_chdir", res);
+			}
+		}
+		else {
+			print_one_list(&fno, list_option);
+		}
+
+		if (pattern_p == NULL)
+			res = f_readdir(&dir, &fno);	/* all */
+		else
+			res = f_findnext(&dir, &fno);	/* pattern matching */
+	}
+
+	f_closedir(&dir);
+
+	if (lfn			!= NULL) ff_memfree(lfn);
+	if (path_backup != NULL) ff_memfree(path_backup);
+}
+
+int usrcmd_ls(int argc, char **argv)
+{
+	char *pattern_p = NULL, *basename_p = NULL, *dirname_p = NULL;
+	char default_pattern[FF_MAX_LFN] = "";
+	int c;
+	BYTE list_option = 0;
+
+	while ((c = getopt(argc, argv, "al")) != -1) {
+		switch (c) {
+		case 'a':
+			list_option |= LS_ALL;
+			break;
+		case 'l':
+			list_option |= LS_LONG;
+			break;
+		default:
+			break;
+		}
+	}
+	pattern_p = *(argv + optind);
+
+	if (pattern_p != NULL)
+		ntlibc_strlcpy(default_pattern, pattern_p, sizeof(default_pattern));
+	basename_p = basename(pattern_p);
+	dirname_p = dirname(default_pattern);
+	if (((dirname_p[0] == '/') && (basename_p[0] == '/')) ||
+		(!ntlibc_strncmp(dirname_p, ".", strlen(dirname_p)) && !ntlibc_strncmp(basename_p, ".", strlen(basename_p))))
+	{
+		basename_p = NULL;
+	}
+	print_ls(dirname_p, basename_p, list_option);
+
+	return 0;
+}
+
+int usrcmd_cp(int argc, char **argv)
+{
+	char *src_str_p = NULL, *dst_str_p = NULL;
+	unsigned char i;
+	FRESULT res;
+	FILINFO fno;
+	FIL src_fp, dst_fp;
+	size_t read_size, write_size;
+	char *lfn = NULL, *local_buff = NULL, *dst_mod_str_p = NULL;
+	char *src_basename_p;
+
+	if (argc < 2)
+		return 0;
+
+	/* 引数チェック */
+	for (i = 1; i < argc; i++) {
+		if (argv[i][0] == '-')
+			continue;
+		if (argv[i][0] != '\0') {
+			if (src_str_p == NULL)
+				src_str_p = &argv[i][0];
+			else {
+				dst_str_p = &argv[i][0];
+				break;
+			}
+		}
+	}
+	if ((src_str_p == NULL) || (dst_str_p == NULL))
+		return 0;
+
+#if FF_USE_LFN
+	/* LFN buffer alloc */
+	lfn = ff_memalloc(LFN_BUF_SIZE);
+	if (lfn == NULL) {
+		printf("alloc err.\n");
+		goto cp_end;
+	}
+	fno.lfname = lfn;
+	fno.lfsize = LFN_BUF_SIZE;
+#endif
+
+	/* copy buffer alloc */
+	local_buff = ff_memalloc(64);
+	if (local_buff == NULL) {
+		printf("alloc err.\n");
+		goto cp_end;
+	}
+
+	/*************/
+	/* src check */
+	/*************/
+	res = f_stat(src_str_p, &fno);
+	if (res != FR_OK) {
+		if (res == FR_NO_FILE)
+			printf("src no file.\n");
+		else
+			printf("src stat err(%d).\n", res);
+		goto cp_end;
+	}
+	if (fno.fattrib & AM_DIR) {	/* src is dir */
+		/*******************************************************/	/* from dir */ /* 未実装 */
+	}
+	else {						/* src is file */
+		res = f_open(&src_fp, src_str_p, (FA_OPEN_EXISTING | FA_READ));
+		if (res != FR_OK) {
+			printf("src open err(%d).\n", res);
+			goto cp_end;
+		}
+	}
+
+	/*************/
+	/* dst check */
+	/*************/
+	res = f_stat(dst_str_p, &fno);
+	if (res != FR_NO_FILE) {
+		if (res == FR_OK) {
+			if (fno.fattrib & AM_DIR) {	/* dst is dir */
+				src_basename_p = basename(src_str_p);
+				dst_mod_str_p = ff_memalloc(LFN_BUF_SIZE);
+				if (dst_mod_str_p == NULL) {
+					printf("alloc err.\n");
+					goto cp_end;
+				}
+				snprintf(dst_mod_str_p, LFN_BUF_SIZE, "%s/%s\0", dst_str_p, src_basename_p);
+				dst_str_p = dst_mod_str_p;
+			}
+			else {
+				printf("dst file exists.\n");
+				goto cp_end_1;
+			}
+		}
+		else {
+			printf("src stat err(%d).\n", res);
+			goto cp_end_1;
+		}
+	}
+	res = f_open(&dst_fp, dst_str_p, (FA_CREATE_NEW | FA_WRITE));
+	if (res != FR_OK) {
+		printf("dst open err(%d).\n", res);
+		goto cp_end_1;
+	}
+
+	/********/
+	/* copy */
+	/********/
+	do {
+		/* read from src */
+		res = f_read(&src_fp, local_buff, sizeof(local_buff), &read_size);
+		if (res != FR_OK) {
+			printf("src read err(%d).\n", res);
+			goto cp_end_2;
+		}
+
+		/* write to dst */
+		res = f_write(&dst_fp, local_buff, read_size, &write_size);
+		if (res != FR_OK) {
+			printf("dst write err(%d).\n", res);
+			goto cp_end_2;
+		}
+		if (read_size != write_size) {
+			printf("dst write err(disk full).\n");
+			goto cp_end_2;
+		}
+	} while (read_size == sizeof(local_buff));
+
+cp_end_2:
+	f_close(&dst_fp);
+cp_end_1:
+	f_close(&src_fp);
+cp_end:
+	if(dst_mod_str_p != NULL) ff_memfree(dst_mod_str_p);
+	if(local_buff	 != NULL) ff_memfree(local_buff);
+	if(lfn			 != NULL) ff_memfree(lfn);
+
+	return 0;
+}
+
+int usrcmd_rm(int argc, char **argv)
+{
+	FRESULT res;
+
+	if (argc == 2) {
+		if ((res = f_unlink(argv[1])) != FR_OK) {
+			put_rc("f_unlink", res);
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
+int usrcmd_mv(int argc, char **argv)
+{
+	FRESULT res;
+
+	if (argc == 3) {
+		if ((res = f_rename(argv[1], argv[2])) != FR_OK) {
+			put_rc("f_rename", res);
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
+int usrcmd_mkdir(int argc, char **argv)
+{
+	FRESULT res;
+
+	if (argc == 2) {
+		if ((res = f_mkdir(argv[1])) != FR_OK) {
+			put_rc("f_mkdir", res);
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
+#define HEXDUMP_EXTRA_FOR_UTF8 3 /* need extra buffer size */
+#define CCOLOR_RESET	0
+#define CCOLOR_BLACK	30
+#define CCOLOR_RED		31
+#define CCOLOR_GREEN	32
+#define CCOLOR_YELLOW	33
+#define CCOLOR_BLUE		34
+#define CCOLOR_MAGENTA	35
+#define CCOLOR_CYAN		36
+#define CCOLOR_WHITE	37
+enum {
+	HEXDUMP_OPT_DEFAULT = 1 << 0,
+	HEXDUMP_OPT_UTF8 = 1 << 1,
+};
+
+int usrcmd_hexdump(int argc, char **argv)
+{
+	FRESULT res;
+	FIL fsrc;
+	char data[16 + 1 + HEXDUMP_EXTRA_FOR_UTF8];
+	char ascii[sizeof("\x1B[31m0\x1B[0m\x1B[31m1\x1B[0m\x1B[31m2\x1B[0m\x1B[31m3\x1B[0m\x1B[31m4\x1B[0m\x1B[31m5\x1B[0m\x1B[31m6\x1B[0m\x1B[31m7\x1B[0m\x1B[31m8\x1B[0m\x1B[31m9\x1B[0m\x1B[31ma\x1B[0m\x1B[31mb\x1B[0m\x1B[31mc\x1B[0m\x1B[31md\x1B[0m\x1B[31me\x1B[0m\x1B[31mf\x1B[0m") + HEXDUMP_EXTRA_FOR_UTF8];
+	char line[sizeof("00000000: 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 : \n") + sizeof(ascii)];
+	TCHAR *filename_p = NULL;
+	int op, option_flag = HEXDUMP_OPT_DEFAULT;
+	char *option_ptr, *option_endptr, ccolor, utf8_done_flg, utf8_odd_bytes = 0;
+	unsigned int op_offset = 0, op_size = 0, op_end = 0;
+
+	while ((op = getopt(argc, argv, "hduos0123456789xX")) != -1) {
+		switch (op) {
+		case 'h': /* help */
+			printf(" hexdump [OPTION] file\n");
+			printf("  -h : help\n");
+			printf("  -d : print all byte with convert and color [in character area] (default)\n");
+			printf("  -u : try print UTF-8 code [in character area]\n");
+			printf("  -oOFFSET : print start offset address from top\n");
+			printf("  -sSIZE   : print size\n");
+			break;
+		case 'd': /* print one byte character [in character area] (default) */
+			option_flag |= HEXDUMP_OPT_DEFAULT;
+			break;
+		case 'u': /* try print UTF-8 code [in character area] */
+			option_flag |= HEXDUMP_OPT_UTF8;
+			break;
+		case 'o': /* print start offset address from top */
+			option_ptr = *(argv + optind);
+			op_offset = ntlibc_strtoul(&option_ptr[2], &option_endptr, 0);
+			break;
+		case 's': /* print size */
+			option_ptr = *(argv + optind);
+			op_size = ntlibc_strtoul(&option_ptr[2], &option_endptr, 0);
+			break;
+		default:
+			break;
+		}
+	}
+	filename_p = *(argv + optind);
+	if (filename_p == NULL)
+		return 0;
+
+	if ((res = f_open(&fsrc, filename_p, FA_OPEN_EXISTING | FA_READ)) != FR_OK) {
+		put_rc("f_open", res);
+		return 0;
+	}
+
+	/* position adjusting */
+	if (op_offset >= fsrc.fsize) {
+		printf("error : input offset is bigger than file size(0x%lX).\n", fsrc.fsize);
+		return 0;
+	}
+	op_end = op_offset + op_size;
+	if ((op_size == 0) || (op_end >= fsrc.fsize))
+		op_end = fsrc.fsize;
+	f_lseek(&fsrc, op_offset);
+
+	for (int i = op_offset; i < op_end; i += 16) {
+		ascii[0] = '\0';
+		line[0] = '\0';
+		char *pos = line;
+		int rst = sizeof(line);
+		int len = snprintf(pos, rst, "%08X: ", i);
+		pos += len;
+		rst -= len;
+
+		UINT br = 0;
+		if ((res = f_read(&fsrc, data, 16 + HEXDUMP_EXTRA_FOR_UTF8, &br)) != FR_OK) {
+			put_rc("f_read", res);
+			f_close(&fsrc);
+			return 0;
+		}
+		data[br] = '\0';
+		f_lseek(&fsrc, i + 16);
+		if (br > 16) br = 16;
+
+		char *apos = ascii;
+		int arst = sizeof(ascii);
+		for (int j = 0; j < br; j++) {
+			char c = data[j];
+			if (j != 7)
+				len = snprintf(pos, rst, "%02X ", c);
+			else
+				len = snprintf(pos, rst, "%02X-", c);
+			pos += len;
+			rst -= len;
+
+			len = 0;
+			utf8_done_flg = 0;
+			ccolor = CCOLOR_RESET;
+
+			if (c < 0x20) {
+				ccolor = CCOLOR_RED;
+				c = c + 0x40;
+			}
+			else {
+				if (option_flag & HEXDUMP_OPT_UTF8) { /* try UTF-8 */
+					/* check character code */
+					int bf_utf8_bytes, af_utf8_bytes;
+					unsigned char utf8_code[4];
+					WCHAR utf16_code;
+
+					utf16_code = Utf8_to_Utf16(&data[j], &bf_utf8_bytes);       /* try UTF-8 -> UTF-16 */
+					Utf16_to_Utf8(utf8_code, &af_utf8_bytes, (UINT)utf16_code); /* try UTF-16 -> UTF-8 */
+					if ((af_utf8_bytes <= 3 && bf_utf8_bytes == af_utf8_bytes) &&
+						!memcmp(&data[j], utf8_code, af_utf8_bytes)) { /* size & code match */
+						utf8_done_flg = 1;
+						for (int k = 1; k < af_utf8_bytes; k++) { /* pos */
+							if (j + k >= 16)
+								break;
+							if (j + k != 7)
+								len = snprintf(pos, rst, "%02X ", data[j + k]);
+							else
+								len = snprintf(pos, rst, "%02X-", data[j + k]);
+							pos += len;
+							rst -= len;
+						}
+						memcpy(apos, &data[j], af_utf8_bytes); /* apos */
+						apos[af_utf8_bytes] = 0;
+						len = af_utf8_bytes;
+						j += af_utf8_bytes - 1;
+						if (af_utf8_bytes > 1) {
+							utf8_odd_bytes = j < 15 ? af_utf8_bytes - 2 : af_utf8_bytes - 1;
+						}
+					}
+				}
+			}
+
+			if (utf8_odd_bytes > 0 && j < 15) {
+				apos += len;
+				arst -= len;
+				len = snprintf(apos, arst, "\x1B[%dm%c\x1B[0m", CCOLOR_RESET, ' ');
+				utf8_odd_bytes--;
+			}
+			else if (utf8_done_flg == 0) {
+				if (c >= 0x80 && c < 0x9F) {
+					ccolor = CCOLOR_RED;
+					c = c - 0x60;
+				}
+				else if (c >= 0xA0 && c < 0xDF) {
+					ccolor = CCOLOR_GREEN;
+					c = c - 0x60;
+				}
+				else if (c >= 0xE0 && c < 0xFF) {
+					ccolor = CCOLOR_GREEN;
+					c = c - 0xC0;
+				}
+				else if (c == 0x7F || c == 0x9F || c == 0xDF || c == 0xFF) {
+					ccolor = CCOLOR_CYAN;
+					c = '?';
+				}
+				len = snprintf(apos, arst, "\x1B[%dm%c\x1B[0m", ccolor, c);
+			}
+
+			apos += len;
+			arst -= len;
+		}
+
+		for (int j = br; j < 16; j++) {
+			if (j != 7)
+				len = snprintf(pos, rst, "   ");
+			else
+				len = snprintf(pos, rst, "  -");
+			pos += len;
+			rst -= len;
+		}
+
+		len = snprintf(pos, rst, ": %s\n", ascii);
+		pos += len;
+		rst -= len;
+
+		puts(line);
+	}
+
+	f_close(&fsrc);
+	return 0;
+}
+
+int usrcmd_date(int argc, char **argv)
+{
+	int ret;
+	struct timespec tp;
+	char buf[30];
+
+	ret = clock_gettime(CLOCK_REALTIME, &tp);
+	if (ret != 0) {
+		printf("clock_gettime error %d", ret);
+		return 0;
+	}
+
+	memset(buf, 0, sizeof(buf));
+	if (ctime_r(&tp.tv_sec, buf) == NULL) {
+		printf("ctime_r error");
+		return 0;
+	}
+
+	/* 改行コードの削除 */
+	ret = ntlibc_strlen(buf);
+	buf[ret - 1] = '\0';
+
+	printf("%s .%09ld\n", buf, tp.tv_nsec);
+	return 0;
+}
+
+int usrcmd_info(int argc, char **argv)
+{
+	if (argc != 2) {
+		printf("info sys\n");
+		printf("info ver\n");
+		return 0;
+	}
+	if (strcmp(argv[1], "sys") == 0) {
+		printf(TARGET_NAME" Monitor\n");
+		return 0;
+	}
+	if (strcmp(argv[1], "ver") == 0) {
+		int mj, mn, bd;
+		ntshell_version(&mj, &mn, &bd);
+		printf("Version %d.%d.%d\n", mj, mn, bd);
+		return 0;
+	}
+	printf("Unknown sub command found\n");
+	return -1;
+}
+
+int usrcmd_exit(int argc, char **argv)
+{
+	ntshell_exit = 1;
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/usrcmd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/usrcmd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/usrcmd.h	(revision 398)
@@ -0,0 +1,59 @@
+/**
+ * @file usrcmd.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 USRCMD_H
+#define USRCMD_H
+
+typedef int(*USRCMDFUNC)(int argc, char **argv);
+
+typedef struct
+{
+	const char *cmd;
+	const char *desc;
+	USRCMDFUNC func;
+} cmd_table_t;
+
+int usrcmd_cd(int argc, char **argv);
+int usrcmd_ls(int argc, char **argv);
+int usrcmd_cp(int argc, char **argv);
+int usrcmd_rm(int argc, char **argv);
+int usrcmd_mv(int argc, char **argv);
+int usrcmd_mkdir(int argc, char **argv);
+int usrcmd_hexdump(int argc, char **argv);
+int usrcmd_date(int argc, char **argv);
+
+int usrcmd_help(int argc, char **argv);
+int usrcmd_info(int argc, char **argv);
+int usrcmd_exit(int argc, char **argv);
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntopt.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntopt.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntopt.c	(revision 398)
@@ -0,0 +1,161 @@
+/**
+ * @file ntopt.c
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 <string.h>
+#include "ntopt.h"
+
+ /**
+  * @brief Is the character delimiter?
+  * @param c The character.
+  * @retval true It's a delimiter.
+  * @retval false It's not a delimiter.
+  */
+#define IS_DELIM(c) \
+    (((c) == '\r') || ((c) == '\n') || ((c) == '\t') || ((c) == '\0') || ((c) == ' '))
+
+static int ntopt_get_count(const char *str);
+static char *ntopt_get_text(
+	const char *str, const int n, char *buf, int siz, int *len);
+
+/**
+ * @brief Get the sentence count of the given text string.
+ * @param str A text string.
+ * @return Count of the given sentence.
+ */
+static int ntopt_get_count(const char *str)
+{
+	int cnt = 0;
+	int wc = 0;
+	char *p = (char *)str;
+	while (*p) {
+		if (!IS_DELIM(*p)) {
+			wc++;
+			if (wc == 1) {
+				cnt++;
+			}
+		}
+		else {
+			wc = 0;
+		}
+		p++;
+	}
+	return cnt;
+}
+
+/**
+ * @brief Get the sentence of the given text string.
+ * @param str A text string.
+ * @param n Index number. (0 to ntopt-get_count(str) - 1)
+ * @param buf The pointer to a stored buffer.
+ * @param siz The size of the stored buffer.
+ * @param len The stored string length.
+ * @retval !NULL Success. The pointer to the buffer.
+ * @retval NULL Failure.
+ */
+static char *ntopt_get_text(
+	const char *str, const int n, char *buf, int siz, int *len)
+{
+	int cnt = 0;
+	int wc = 0;
+	char *p = (char *)str;
+	*len = 0;
+	while (*p) {
+		if (!IS_DELIM(*p)) {
+			wc++;
+			if (wc == 1) {
+				if (cnt == n) {
+					char *des = buf;
+					int cc = 0;
+					while (!IS_DELIM(*p)) {
+						cc++;
+						if (siz <= cc) {
+							break;
+						}
+						*des = *p;
+						des++;
+						p++;
+					}
+					*des = '\0';
+					*len = cc;
+					return buf;
+				}
+				cnt++;
+			}
+		}
+		else {
+			wc = 0;
+		}
+		p++;
+	}
+	return (char *)0;
+}
+
+/**
+ * @brief Parse the given text string.
+ * @param str A text string.
+ * @param func The callback function.
+ * @param extobj An external object for the callback function.
+ * @return The return value from the callback.
+ */
+int ntopt_parse(const char *str, NTOPT_CALLBACK func, void *extobj)
+{
+	int argc;
+	char argv[NTOPT_TEXT_MAXLEN];
+	char *argvp[1 + NTOPT_TEXT_MAXARGS];
+	int i;
+	int total;
+	char *p;
+
+	argc = ntopt_get_count(str);
+	if (NTOPT_TEXT_MAXARGS <= argc) {
+		argc = NTOPT_TEXT_MAXARGS;
+	}
+
+	memset(argvp, 0, sizeof(argvp));
+	total = 0;
+	p = &argv[0];
+	for (i = 0; i < argc; i++) {
+		int len;
+		argvp[i + 1] = ntopt_get_text(
+			str, i, p, NTOPT_TEXT_MAXLEN - total, &len);
+		if (total + len + 1 < NTOPT_TEXT_MAXLEN) {
+			p += len + 1;
+			total += len + 1;
+		}
+		else {
+			break;
+		}
+	}
+	argvp[0] = (char *)argc;
+
+	return func((long *)&argvp[0], extobj);
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntopt.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntopt.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntopt.h	(revision 398)
@@ -0,0 +1,70 @@
+/**
+ * @file ntopt.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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 NTOPT_H
+#define NTOPT_H
+
+#include "core/ntconf.h"
+
+/**
+ * @brief The text maximum length.
+ */
+#define NTOPT_TEXT_MAXLEN   (NTCONF_EDITOR_MAXLEN)
+
+/**
+ * @brief The text maximum arguments.
+ */
+#define NTOPT_TEXT_MAXARGS  (NTCONF_EDITOR_MAXLEN / 2)
+
+/**
+ * @brief The callback function.
+ *
+ * @param argc The number of the parameters.
+ * @param argv The pointer to the parameters.
+ * @param extobj The external object.
+ *
+ * @return A return value.
+ */
+typedef int (*NTOPT_CALLBACK)(long *args, void *extobj);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ntopt_parse(const char *str, NTOPT_CALLBACK func, void *extobj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntstdio.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntstdio.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntstdio.c	(revision 398)
@@ -0,0 +1,421 @@
+/**
+ * @file ntstdio.c
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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.
+ */
+
+/*------------------------------------------------------------------------/
+/  Universal string handler for user console interface
+/-------------------------------------------------------------------------/
+/
+/  Copyright (C) 2011, ChaN, all right reserved.
+/
+/ * This software 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 products UNDER YOUR RESPONSIBILITY.
+/ * Redistributions of source code must retain the above copyright notice.
+/
+/-------------------------------------------------------------------------*/
+
+#include <stdarg.h>
+#include "ntstdio.h"
+
+#define FLAG_ZERO_PADDED    (1 << 0)
+#define FLAG_LEFT_JUSTIFIED (1 << 1)
+#define FLAG_SIZE_LONG_INT  (1 << 2)
+#define FLAG_SIGNED_DECIMAL (1 << 3)
+#define FLAG_SIZE_HALF_INT  (1 << 4)
+
+/*
+ * ntstdio_printf("%d", 1234);            "1234"
+ * ntstdio_printf("%6d,%3d%%", -200, 5);  "  -200,  5%"
+ * ntstdio_printf("%-6u", 100);           "100   "
+ * ntstdio_printf("%ld", 12345678L);      "12345678"
+ * ntstdio_printf("%04x", 0xA3);          "00a3"
+ * ntstdio_printf("%08LX", 0x123ABC);     "00123ABC"
+ * ntstdio_printf("%016b", 0x550F);       "0101010100001111"
+ * ntstdio_printf("%s", "String");        "String"
+ * ntstdio_printf("%-4s", "abc");         "abc "
+ * ntstdio_printf("%4s", "abc");          " abc"
+ * ntstdio_printf("%c", 'a');             "a"
+ * ntstdio_printf("%f", 10.0);            <ntstdio_printf lacks floating point support>
+ */
+
+static int xvprintf(ntstdio_t *handle, const char *fmt, va_list arp)
+{
+	unsigned int i, j;
+	unsigned int flag, radix, width;
+	unsigned long value;
+	char s[16], c, d, *p;
+
+	while (1) {
+		/*
+		 * Get a character.
+		 */
+		c = *fmt++;
+		if (!c) {
+			/*
+			 * End of the format.
+			 */
+			break;
+		}
+		if (c != '%') {
+			/*
+			 * Pass through it if not a % sequense
+			 */
+			ntstdio_putc(handle, c);
+			continue;
+		}
+
+		/*
+		 * Reset the flag.
+		 */
+		flag = 0;
+
+		/*
+		 * Get the first character of the sequense.
+		 */
+		c = *fmt++;
+		if (c == '0') {
+			flag = FLAG_ZERO_PADDED;
+			c = *fmt++;
+		}
+		else {
+			if (c == '-') {
+				flag = FLAG_LEFT_JUSTIFIED;
+				c = *fmt++;
+			}
+		}
+		/*
+		 * Calculate the minimum width.
+		 */
+		for (width = 0; (c >= '0') && (c <= '9'); c = *fmt++) {
+			width = (width * 10) + (c - '0');
+		}
+		if ((c == 'l') || (c == 'L')) {
+			flag |= FLAG_SIZE_LONG_INT;
+			c = *fmt++;
+		}
+		else if (c == 'h') {	/* Prefix: Size is short int */
+			flag |= FLAG_SIZE_HALF_INT;
+			c = *fmt++;
+		}
+		if (!c) {
+			/*
+			 * End of the format.
+			 */
+			break;
+		}
+		d = c;
+		if (d >= 'a') {
+			d -= 0x20;
+		}
+		/* Type is... */
+		switch (d) {
+		case 'S':
+			/* String */
+			p = va_arg(arp, char*);
+			for (j = 0; p[j]; j++) {
+			}
+			while (!(flag & FLAG_LEFT_JUSTIFIED) && (j++ < width)) {
+				ntstdio_putc(handle, ' ');
+			}
+			ntstdio_puts(handle, p);
+			while (j++ < width) {
+				ntstdio_putc(handle, ' ');
+			}
+			continue;
+		case 'C':
+			/* Character */
+			ntstdio_putc(handle, (char)va_arg(arp, int));
+			continue;
+		case 'B':
+			/* Binary */
+			radix = 2;
+			break;
+		case 'O':
+			/* Octal */
+			radix = 8;
+			break;
+		case 'D':
+			/* Signed decimal */
+			radix = 10;
+			break;
+		case 'U':
+			/* Unsigned decimal */
+			radix = 10;
+			break;
+		case 'X':
+			/* Hexdecimal */
+			radix = 16;
+			break;
+		default:
+			/* Unknown type (passthrough) */
+			ntstdio_putc(handle, c);
+			continue;
+		}
+
+		/*
+		 * Get an argument and put it in numeral.
+		 */
+		value = (flag & FLAG_SIZE_LONG_INT) ? va_arg(arp, long)
+			: (flag & FLAG_SIZE_HALF_INT) ? ((d == 'D') ? (long)((short)va_arg(arp, int)) : (long)((unsigned short)va_arg(arp, unsigned int)))
+				: ((d == 'D') ? (long)va_arg(arp, int) : (long)va_arg(arp, unsigned int));
+		if ((d == 'D') && (value & 0x80000000)) {
+			value = 0 - value;
+			flag |= FLAG_SIGNED_DECIMAL;
+		}
+		i = 0;
+		do {
+			d = (char)(value % radix);
+			value /= radix;
+			if (d > 9) {
+				d += (c == 'x') ? 0x27 : 0x07;
+			}
+			s[i++] = d + '0';
+		} while (value && (i < sizeof(s)));
+		if (flag & FLAG_SIGNED_DECIMAL) {
+			s[i++] = '-';
+		}
+		j = i;
+		d = (flag & FLAG_ZERO_PADDED) ? '0' : ' ';
+		while (!(flag & FLAG_LEFT_JUSTIFIED) && (j++ < width)) {
+			ntstdio_putc(handle, d);
+		}
+		do {
+			ntstdio_putc(handle, s[--i]);
+		} while (i);
+		while (j++ < width) {
+			ntstdio_putc(handle, ' ');
+		}
+	}
+
+	return handle->pos;
+}
+
+void ntstdio_init(ntstdio_t *handle, unsigned int option, NTSTDIO_XI xi, NTSTDIO_XO xo)
+{
+	handle->xi = xi;
+	handle->xo = xo;
+	handle->pos = 0;
+	handle->option = option;
+}
+
+static void _putc(ntstdio_t *handle, char c)
+{
+	if (handle->xo) {
+		handle->xo(handle, (unsigned char)c);
+	}
+	handle->pos++;
+}
+
+void ntstdio_putc(ntstdio_t *handle, char c)
+{
+	if ((handle->option & NTSTDIO_OPTION_LF_CRLF) && (c == '\n')) {
+		_putc(handle, '\r');
+		_putc(handle, '\n');
+	}
+	else{
+		_putc(handle, c);
+	}
+}
+
+void ntstdio_puts(ntstdio_t *handle, const char *str)
+{
+	while (*str) {
+		ntstdio_putc(handle, *str++);
+	}
+}
+
+void ntstdio_fputs(ntstdio_t *handle, NTSTDIO_XO xo, const char *str)
+{
+	NTSTDIO_XO pf;
+
+	/* Save current output device */
+	pf = handle->xo;
+	/* Switch output to specified device */
+	handle->xo = xo;
+
+	while (*str) {
+		ntstdio_putc(handle, *str++);
+	}
+
+	/* Restore output device */
+	handle->xo = pf;
+}
+
+int ntstdio_printf(ntstdio_t *handle, const char *fmt, ...)
+{
+	int result;
+	va_list arp;
+	va_start(arp, fmt);
+	result = xvprintf(handle, fmt, arp);
+	va_end(arp);
+	return result;
+}
+
+struct put_buf_t {
+	char *outptr;
+	int len;
+};
+
+static void put_buf(struct ntstdio_t *handle, unsigned char c)
+{
+	struct put_buf_t *put_buf = (struct put_buf_t *)handle->exinf;
+	if ((handle->pos + 1) >= put_buf->len)
+		return;
+	put_buf->outptr[handle->pos] = (char)c;
+	handle->pos++;
+}
+
+int ntstdio_snprintf(char *buf, int len, const char *fmt, ...)
+{
+	int result;
+	ntstdio_t handle;
+	struct put_buf_t exinf;
+	va_list arp;
+	/* Switch destination for memory */
+	handle.xo = put_buf;
+	handle.option = 0;
+	handle.pos = 0;
+	handle.exinf = &exinf;
+	exinf.outptr = buf;
+	exinf.len = len;
+
+	va_start(arp, fmt);
+	result = xvprintf(&handle, fmt, arp);
+	va_end(arp);
+
+	/* Terminate output string with a \0 */
+	buf[handle.pos] = '\0';
+	return result;
+}
+
+int ntstdio_fprintf(ntstdio_t *handle, NTSTDIO_XO xo, const char *fmt, ...)
+{
+	int result;
+	va_list arp;
+	NTSTDIO_XO pf;
+
+	/* Save current output device */
+	pf = handle->xo;
+	/* Switch output to specified device */
+	handle->xo = xo;
+
+	va_start(arp, fmt);
+	result = xvprintf(handle, fmt, arp);
+	va_end(arp);
+
+	/* Restore output device */
+	handle->xo = pf;
+	return result;
+}
+
+int ntstdio_getc(ntstdio_t *handle)
+{
+	extern void shell_exit(int cd);
+
+	int c = handle->xi(handle);
+	if (handle->option & NTSTDIO_OPTION_LF_CR) {
+		if (c == '\r')
+			c = '\n';
+	}
+	if (handle->option & NTSTDIO_OPTION_CANON) {
+		if (c == 0x03)
+			shell_exit(-1);
+	}
+	if (handle->option & NTSTDIO_OPTION_LINE_ECHO) {
+		ntstdio_putc(handle, c);
+	}
+	return c;
+}
+
+/* 0:End of stream, 1:A line arrived */
+int ntstdio_gets(ntstdio_t *handle, char *buf, int len)
+{
+	int c, i;
+
+	if (!handle->xi) {
+		/* No input function specified */
+		return 0;
+	}
+
+	i = 0;
+	for (;;) {
+		/* Get a char from the incoming stream */
+		c = handle->xi(handle);
+		if (!c) {
+			/* End of stream */
+			return 0;
+		}
+		if (c == '\r') {
+			/* End of line */
+			break;
+		}
+		if ((c == '\b') && i) {
+			/* Back space */
+			i--;
+			if (handle->option & NTSTDIO_OPTION_LINE_ECHO) {
+				ntstdio_putc(handle, c);
+			}
+			continue;
+		}
+		if ((c >= ' ') && (i < len - 1)) {
+			/* Visible chars */
+			buf[i++] = c;
+			if (handle->option & NTSTDIO_OPTION_LINE_ECHO) {
+				ntstdio_putc(handle, c);
+			}
+		}
+	}
+	buf[i] = 0;
+	/* Terminate with a \0 */
+	if (handle->option & NTSTDIO_OPTION_LINE_ECHO) {
+		ntstdio_putc(handle, '\n');
+	}
+	return 1;
+}
+
+/* 0:End of stream, 1:A line arrived */
+int ntstdio_fgets(ntstdio_t *handle, NTSTDIO_XI xi, char *buf, int len)
+{
+	NTSTDIO_XI pf;
+	int n;
+
+	/* Save current input device */
+	pf = handle->xi;
+	/* Switch input to specified device */
+	handle->xi = xi;
+	/* Get a line */
+	n = ntstdio_gets(handle, buf, len);
+	/* Restore input device */
+	handle->xi = pf;
+
+	return n;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntstdio.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntstdio.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/ntshell/util/ntstdio.h	(revision 398)
@@ -0,0 +1,95 @@
+/**
+ * @file ntstdio.h
+ * @author CuBeatSystems
+ * @author Shinichiro Nakamura
+ * @copyright
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell) Version 0.3.1
+ * ===============================================================
+ * Copyright (c) 2010-2016 Shinichiro Nakamura
+ *
+ * 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.
+ */
+
+/*------------------------------------------------------------------------/
+/  Universal string handler for user console interface
+/-------------------------------------------------------------------------/
+/
+/  Copyright (C) 2011, ChaN, all right reserved.
+/
+/ * This software 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 products UNDER YOUR RESPONSIBILITY.
+/ * Redistributions of source code must retain the above copyright notice.
+/
+/-------------------------------------------------------------------------*/
+
+#ifndef NTSTDIO_H
+#define NTSTDIO_H
+
+/**
+ * 1: Convert \n ==> \r\n in the output char.
+ */
+#define NTSTDIO_OPTION_LF_CRLF      (1 << 0)
+
+/**
+ * 1: Echo back input chars in ntstdio_gets function.
+ */
+#define NTSTDIO_OPTION_LINE_ECHO    (1 << 1)
+
+/**
+ * 1: canonical mode.
+ */
+#define NTSTDIO_OPTION_CANON        (1 << 2)
+
+/**
+ * 1: Convert \r ==> \n in ntstdio_getc function.
+ */
+#define NTSTDIO_OPTION_LF_CR        (1 << 3)
+
+struct ntstdio_t;
+typedef unsigned char (*NTSTDIO_XI)(struct ntstdio_t *handle);
+typedef void (*NTSTDIO_XO)(struct ntstdio_t *handle, unsigned char c);
+
+typedef struct ntstdio_t {
+	NTSTDIO_XI xi;
+	NTSTDIO_XO xo;
+	int pos;
+	unsigned int option;
+	void *exinf;
+} ntstdio_t;
+
+void ntstdio_init(ntstdio_t *handle, unsigned int option, NTSTDIO_XI xi, NTSTDIO_XO xo);
+
+void ntstdio_putc(ntstdio_t *handle, char c);
+void ntstdio_puts(ntstdio_t *handle, const char *str);
+void ntstdio_fputs(ntstdio_t *handle, NTSTDIO_XO xo, const char *str);
+int ntstdio_printf(ntstdio_t *handle, const char *fmt, ...);
+int ntstdio_snprintf(char *buf, int len, const char *fmt, ...);
+int ntstdio_fprintf(ntstdio_t *handle, NTSTDIO_XO xo, const char *fmt, ...);
+
+int ntstdio_getc(ntstdio_t *handle);
+int ntstdio_gets(ntstdio_t *handle, char *buf, int len);
+int ntstdio_fgets(ntstdio_t *handle, NTSTDIO_XI xi, char *buf, int len);
+
+#endif
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/ca-bundle.crt
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/ca-bundle.crt	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/ca-bundle.crt	(revision 398)
@@ -0,0 +1,116 @@
+## 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)
+
+DigiCert Baltimore Root
+=======================
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
+DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
+ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
+VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
+mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
+IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
+mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
+XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
+dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
+jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
+BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
+DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
+9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
+jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
+Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
+ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
+R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
+-----END CERTIFICATE-----
+
+DigiCert Global Root CA
+=======================
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
+
+D-TRUST Root Class 3 CA 2 2009
+==============================
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
+ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
+HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
+UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
+tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
+ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
+lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
+/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
+A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
+dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
+MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
+cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
+L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
+BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
+acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
+o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
+zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
+PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
+Johw1+qRzT65ysCQblrGXnRl11z+o+I=
+-----END CERTIFICATE-----
+
+WoSign
+======
+-----BEGIN CERTIFICATE-----
+MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBV
+MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV
+BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw
+MTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX
+b1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvcqN
+rLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1U
+fcIiePyOCbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcScc
+f+Hb0v1naMQFXQoOXXDX2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2
+ZjC1vt7tj/id07sBMOby8w7gLJKA84X5KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4M
+x1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR+ScPewavVIMYe+HdVHpR
+aG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ezEC8wQjch
+zDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDar
+uHqklWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221K
+mYo0SLwX3OSACCK28jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvA
+Sh0JWzko/amrzgD5LkhLJuYwTKVYyrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWv
+HYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0CAwEAAaNCMEAwDgYDVR0PAQH/
+BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R8bNLtwYgFP6H
+EtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1
+LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJ
+MuYhOZO9sxXqT2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2e
+JXLOC62qx1ViC777Y7NhRCOjy+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VN
+g64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC2nz4SNAzqfkHx5Xh9T71XXG68pWp
+dIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes5cVAWubXbHssw1ab
+R80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/EaEQ
+PkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGce
+xGATVdVhmVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+
+J7x6v+Db9NpSvd4MVHAxkUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMl
+OtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGikpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWT
+ee5Ehr7XHuQe+w==
+-----END CERTIFICATE-----
Index: /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/ca-cert.pem
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/ca-cert.pem	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/ca-cert.pem	(revision 398)
@@ -0,0 +1,87 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            b7:b6:90:33:66:1b:6b:23
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.wolfssl.com/emailAddress=info@wolfssl.com
+        Validity
+            Not Before: Aug 11 20:07:37 2016 GMT
+            Not After : May  8 20:07:37 2019 GMT
+        Subject: C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.wolfssl.com/emailAddress=info@wolfssl.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:bf:0c:ca:2d:14:b2:1e:84:42:5b:cd:38:1f:4a:
+                    f2:4d:75:10:f1:b6:35:9f:df:ca:7d:03:98:d3:ac:
+                    de:03:66:ee:2a:f1:d8:b0:7d:6e:07:54:0b:10:98:
+                    21:4d:80:cb:12:20:e7:cc:4f:de:45:7d:c9:72:77:
+                    32:ea:ca:90:bb:69:52:10:03:2f:a8:f3:95:c5:f1:
+                    8b:62:56:1b:ef:67:6f:a4:10:41:95:ad:0a:9b:e3:
+                    a5:c0:b0:d2:70:76:50:30:5b:a8:e8:08:2c:7c:ed:
+                    a7:a2:7a:8d:38:29:1c:ac:c7:ed:f2:7c:95:b0:95:
+                    82:7d:49:5c:38:cd:77:25:ef:bd:80:75:53:94:3c:
+                    3d:ca:63:5b:9f:15:b5:d3:1d:13:2f:19:d1:3c:db:
+                    76:3a:cc:b8:7d:c9:e5:c2:d7:da:40:6f:d8:21:dc:
+                    73:1b:42:2d:53:9c:fe:1a:fc:7d:ab:7a:36:3f:98:
+                    de:84:7c:05:67:ce:6a:14:38:87:a9:f1:8c:b5:68:
+                    cb:68:7f:71:20:2b:f5:a0:63:f5:56:2f:a3:26:d2:
+                    b7:6f:b1:5a:17:d7:38:99:08:fe:93:58:6f:fe:c3:
+                    13:49:08:16:0b:a7:4d:67:00:52:31:67:23:4e:98:
+                    ed:51:45:1d:b9:04:d9:0b:ec:d8:28:b3:4b:bd:ed:
+                    36:79
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5
+            X509v3 Authority Key Identifier: 
+                keyid:27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5
+                DirName:/C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
+                serial:B7:B6:90:33:66:1B:6B:23
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha256WithRSAEncryption
+         0e:93:48:44:4a:72:96:60:71:25:82:a9:2c:ca:60:5b:f2:88:
+         3e:cf:11:74:5a:11:4a:dc:d9:d8:f6:58:2c:05:d3:56:d9:e9:
+         8f:37:ef:8e:3e:3b:ff:22:36:00:ca:d8:e2:96:3f:a7:d1:ed:
+         1f:de:7a:b0:d7:8f:36:bd:41:55:1e:d4:b9:86:3b:87:25:69:
+         35:60:48:d6:e4:5a:94:ce:a2:fa:70:38:36:c4:85:b4:4b:23:
+         fe:71:9e:2f:db:06:c7:b5:9c:21:f0:3e:7c:eb:91:f8:5c:09:
+         fd:84:43:a4:b3:4e:04:0c:22:31:71:6a:48:c8:ab:bb:e8:ce:
+         fa:67:15:1a:3a:82:98:43:33:b5:0e:1f:1e:89:f8:37:de:1b:
+         e6:b5:a0:f4:a2:8b:b7:1c:90:ba:98:6d:94:21:08:80:5d:f3:
+         bf:66:ad:c9:72:28:7a:6a:48:ee:cf:63:69:31:8c:c5:8e:66:
+         da:4b:78:65:e8:03:3a:4b:f8:cc:42:54:d3:52:5c:2d:04:ae:
+         26:87:e1:7e:40:cb:45:41:16:4b:6e:a3:2e:4a:76:bd:29:7f:
+         1c:53:37:06:ad:e9:5b:6a:d6:b7:4e:94:a2:7c:e8:ac:4e:a6:
+         50:3e:2b:32:9e:68:42:1b:e4:59:67:61:ea:c7:9a:51:9c:1c:
+         55:a3:77:76
+-----BEGIN CERTIFICATE-----
+MIIEqjCCA5KgAwIBAgIJALe2kDNmG2sjMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYD
+VQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjERMA8G
+A1UECgwIU2F3dG9vdGgxEzARBgNVBAsMCkNvbnN1bHRpbmcxGDAWBgNVBAMMD3d3
+dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTAe
+Fw0xNjA4MTEyMDA3MzdaFw0xOTA1MDgyMDA3MzdaMIGUMQswCQYDVQQGEwJVUzEQ
+MA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjERMA8GA1UECgwIU2F3
+dG9vdGgxEzARBgNVBAsMCkNvbnN1bHRpbmcxGDAWBgNVBAMMD3d3dy53b2xmc3Ns
+LmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAL8Myi0Ush6EQlvNOB9K8k11EPG2NZ/fyn0D
+mNOs3gNm7irx2LB9bgdUCxCYIU2AyxIg58xP3kV9yXJ3MurKkLtpUhADL6jzlcXx
+i2JWG+9nb6QQQZWtCpvjpcCw0nB2UDBbqOgILHztp6J6jTgpHKzH7fJ8lbCVgn1J
+XDjNdyXvvYB1U5Q8PcpjW58VtdMdEy8Z0TzbdjrMuH3J5cLX2kBv2CHccxtCLVOc
+/hr8fat6Nj+Y3oR8BWfOahQ4h6nxjLVoy2h/cSAr9aBj9VYvoybSt2+xWhfXOJkI
+/pNYb/7DE0kIFgunTWcAUjFnI06Y7VFFHbkE2Qvs2CizS73tNnkCAwEAAaOB/DCB
++TAdBgNVHQ4EFgQUJ45nEXTDJh0/7TNjs6TYHTDl6NUwgckGA1UdIwSBwTCBvoAU
+J45nEXTDJh0/7TNjs6TYHTDl6NWhgZqkgZcwgZQxCzAJBgNVBAYTAlVTMRAwDgYD
+VQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMREwDwYDVQQKDAhTYXd0b290
+aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29t
+MR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tggkAt7aQM2YbayMwDAYD
+VR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEADpNIREpylmBxJYKpLMpgW/KI
+Ps8RdFoRStzZ2PZYLAXTVtnpjzfvjj47/yI2AMrY4pY/p9HtH956sNePNr1BVR7U
+uYY7hyVpNWBI1uRalM6i+nA4NsSFtEsj/nGeL9sGx7WcIfA+fOuR+FwJ/YRDpLNO
+BAwiMXFqSMiru+jO+mcVGjqCmEMztQ4fHon4N94b5rWg9KKLtxyQuphtlCEIgF3z
+v2atyXIoempI7s9jaTGMxY5m2kt4ZegDOkv4zEJU01JcLQSuJofhfkDLRUEWS26j
+Lkp2vSl/HFM3Bq3pW2rWt06UonzorE6mUD4rMp5oQhvkWWdh6seaUZwcVaN3dg==
+-----END CERTIFICATE-----
Index: /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/client-cert.pem
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/client-cert.pem	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/client-cert.pem	(revision 398)
@@ -0,0 +1,88 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            b9:bc:90:ed:ad:aa:0a:8c
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=US, ST=Montana, L=Bozeman, O=wolfSSL_2048, OU=Programming-2048, CN=www.wolfssl.com/emailAddress=info@wolfssl.com
+        Validity
+            Not Before: Aug 11 20:07:37 2016 GMT
+            Not After : May  8 20:07:37 2019 GMT
+        Subject: C=US, ST=Montana, L=Bozeman, O=wolfSSL_2048, OU=Programming-2048, CN=www.wolfssl.com/emailAddress=info@wolfssl.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c3:03:d1:2b:fe:39:a4:32:45:3b:53:c8:84:2b:
+                    2a:7c:74:9a:bd:aa:2a:52:07:47:d6:a6:36:b2:07:
+                    32:8e:d0:ba:69:7b:c6:c3:44:9e:d4:81:48:fd:2d:
+                    68:a2:8b:67:bb:a1:75:c8:36:2c:4a:d2:1b:f7:8b:
+                    ba:cf:0d:f9:ef:ec:f1:81:1e:7b:9b:03:47:9a:bf:
+                    65:cc:7f:65:24:69:a6:e8:14:89:5b:e4:34:f7:c5:
+                    b0:14:93:f5:67:7b:3a:7a:78:e1:01:56:56:91:a6:
+                    13:42:8d:d2:3c:40:9c:4c:ef:d1:86:df:37:51:1b:
+                    0c:a1:3b:f5:f1:a3:4a:35:e4:e1:ce:96:df:1b:7e:
+                    bf:4e:97:d0:10:e8:a8:08:30:81:af:20:0b:43:14:
+                    c5:74:67:b4:32:82:6f:8d:86:c2:88:40:99:36:83:
+                    ba:1e:40:72:22:17:d7:52:65:24:73:b0:ce:ef:19:
+                    cd:ae:ff:78:6c:7b:c0:12:03:d4:4e:72:0d:50:6d:
+                    3b:a3:3b:a3:99:5e:9d:c8:d9:0c:85:b3:d9:8a:d9:
+                    54:26:db:6d:fa:ac:bb:ff:25:4c:c4:d1:79:f4:71:
+                    d3:86:40:18:13:b0:63:b5:72:4e:30:c4:97:84:86:
+                    2d:56:2f:d7:15:f7:7f:c0:ae:f5:fc:5b:e5:fb:a1:
+                    ba:d3
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                33:D8:45:66:D7:68:87:18:7E:54:0D:70:27:91:C7:26:D7:85:65:C0
+            X509v3 Authority Key Identifier: 
+                keyid:33:D8:45:66:D7:68:87:18:7E:54:0D:70:27:91:C7:26:D7:85:65:C0
+                DirName:/C=US/ST=Montana/L=Bozeman/O=wolfSSL_2048/OU=Programming-2048/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
+                serial:B9:BC:90:ED:AD:AA:0A:8C
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha256WithRSAEncryption
+         33:85:08:b4:58:0e:a2:00:03:74:de:77:fb:d1:2b:76:9c:97:
+         90:20:21:a2:e8:2e:22:50:26:04:76:ba:5b:47:79:e5:52:f7:
+         c4:0d:79:ff:62:3f:05:7c:c3:08:6c:e0:b7:81:d0:ce:c6:c9:
+         46:b9:8e:4b:5f:56:79:4b:13:b6:d1:6b:66:4b:ce:00:0d:e3:
+         76:5e:fb:cb:b5:5d:12:31:05:f1:bb:39:f6:86:90:ca:92:56:
+         a4:a0:75:21:b6:1d:4c:96:c3:45:eb:5a:91:94:32:d3:59:b8:
+         c9:73:1f:03:a9:81:63:e0:43:c0:1e:c8:65:be:3b:a7:53:c3:
+         44:ff:b3:fb:47:84:a8:b6:9d:00:d5:6b:ae:87:f8:bb:35:b2:
+         6c:66:0b:11:ee:6f:fe:12:ed:59:79:f1:3e:f2:d3:61:27:8b:
+         95:7e:99:75:8d:a4:9f:34:85:f1:25:4d:48:1e:9b:6b:70:f6:
+         66:cc:56:b1:a3:02:52:8a:7c:aa:af:07:da:97:c6:0c:a5:8f:
+         ed:cb:f5:d8:04:5d:97:0a:5d:5a:2b:49:f5:bd:93:e5:23:9b:
+         99:b5:0c:ff:0c:7e:38:82:b2:6e:ab:8a:c9:a7:45:ab:d6:d7:
+         93:35:70:07:7e:c8:3d:a5:fe:33:8f:d9:85:c0:c7:5a:02:e4:
+         7c:d6:35:9e
+-----BEGIN CERTIFICATE-----
+MIIEyjCCA7KgAwIBAgIJALm8kO2tqgqMMA0GCSqGSIb3DQEBCwUAMIGeMQswCQYD
+VQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjEVMBMG
+A1UECgwMd29sZlNTTF8yMDQ4MRkwFwYDVQQLDBBQcm9ncmFtbWluZy0yMDQ4MRgw
+FgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29s
+ZnNzbC5jb20wHhcNMTYwODExMjAwNzM3WhcNMTkwNTA4MjAwNzM3WjCBnjELMAkG
+A1UEBhMCVVMxEDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFTAT
+BgNVBAoMDHdvbGZTU0xfMjA0ODEZMBcGA1UECwwQUHJvZ3JhbW1pbmctMjA0ODEY
+MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdv
+bGZzc2wuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwwPRK/45
+pDJFO1PIhCsqfHSavaoqUgdH1qY2sgcyjtC6aXvGw0Se1IFI/S1oootnu6F1yDYs
+StIb94u6zw357+zxgR57mwNHmr9lzH9lJGmm6BSJW+Q098WwFJP1Z3s6enjhAVZW
+kaYTQo3SPECcTO/Rht83URsMoTv18aNKNeThzpbfG36/TpfQEOioCDCBryALQxTF
+dGe0MoJvjYbCiECZNoO6HkByIhfXUmUkc7DO7xnNrv94bHvAEgPUTnINUG07ozuj
+mV6dyNkMhbPZitlUJttt+qy7/yVMxNF59HHThkAYE7BjtXJOMMSXhIYtVi/XFfd/
+wK71/Fvl+6G60wIDAQABo4IBBzCCAQMwHQYDVR0OBBYEFDPYRWbXaIcYflQNcCeR
+xybXhWXAMIHTBgNVHSMEgcswgciAFDPYRWbXaIcYflQNcCeRxybXhWXAoYGkpIGh
+MIGeMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96
+ZW1hbjEVMBMGA1UECgwMd29sZlNTTF8yMDQ4MRkwFwYDVQQLDBBQcm9ncmFtbWlu
+Zy0yMDQ4MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEW
+EGluZm9Ad29sZnNzbC5jb22CCQC5vJDtraoKjDAMBgNVHRMEBTADAQH/MA0GCSqG
+SIb3DQEBCwUAA4IBAQAzhQi0WA6iAAN03nf70St2nJeQICGi6C4iUCYEdrpbR3nl
+UvfEDXn/Yj8FfMMIbOC3gdDOxslGuY5LX1Z5SxO20WtmS84ADeN2XvvLtV0SMQXx
+uzn2hpDKklakoHUhth1MlsNF61qRlDLTWbjJcx8DqYFj4EPAHshlvjunU8NE/7P7
+R4Sotp0A1Wuuh/i7NbJsZgsR7m/+Eu1ZefE+8tNhJ4uVfpl1jaSfNIXxJU1IHptr
+cPZmzFaxowJSinyqrwfal8YMpY/ty/XYBF2XCl1aK0n1vZPlI5uZtQz/DH44grJu
+q4rJp0Wr1teTNXAHfsg9pf4zj9mFwMdaAuR81jWe
+-----END CERTIFICATE-----
Index: /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/client-key.pem
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/client-key.pem	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/certs/client-key.pem	(revision 398)
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAwwPRK/45pDJFO1PIhCsqfHSavaoqUgdH1qY2sgcyjtC6aXvG
+w0Se1IFI/S1oootnu6F1yDYsStIb94u6zw357+zxgR57mwNHmr9lzH9lJGmm6BSJ
+W+Q098WwFJP1Z3s6enjhAVZWkaYTQo3SPECcTO/Rht83URsMoTv18aNKNeThzpbf
+G36/TpfQEOioCDCBryALQxTFdGe0MoJvjYbCiECZNoO6HkByIhfXUmUkc7DO7xnN
+rv94bHvAEgPUTnINUG07ozujmV6dyNkMhbPZitlUJttt+qy7/yVMxNF59HHThkAY
+E7BjtXJOMMSXhIYtVi/XFfd/wK71/Fvl+6G60wIDAQABAoIBAQCi5thfEHFkCJ4u
+bdFtHoXSCrGMR84sUWqgEp5T3pFMHW3qWXvyd6rZxtmKq9jhFuRjJv+1bBNZuOOl
+yHIXLgyfb+VZP3ZvSbERwlouFikN3reO3EDVou7gHqH0vpfbhmOWFM2YCWAtMHac
+PM3miO5HknkLWgDiXl8RfH35CLcgBokqXf0AqyLh8LO8JKleJg4fAC3+IZpTW23T
+K6uUgmhDNtj2L8Yi/LVBXQ0zYOqkfX7oS1WRVtNcV48flBcvqt7pnqj0z4pMjqDk
+VnOyz0+GxWk88yQgi1yWDPprEjuaZ8HfxpaypdWSDZsJQmgkEEXUUOQXOUjQNYuU
+bRHej8pZAoGBAOokp/lpM+lx3FJ9iCEoL0neunIW6cxHeogNlFeEWBY6gbA/os+m
+bB6wBikAj+d3dqzbysfZXps/JpBSrvw4kAAUu7QPWJTnL2p+HE9BIdQxWR9OihqN
+p1dsItjl9H4yphDLZKVVA4emJwWMw9e2J7JNujDaR49U0z2LhI2UmFilAoGBANU4
+G8OPxZMMRwtvNZLFsI1GyJIYj/WACvfvof6AubUqusoYsF2lB9CTjdicBBzUYo6m
+JoEB/86KKmM0NUCqbYDeiSNqV02ebq2TTlaQC22dc4sMric93k7wqsVseGdslFKc
+N2dsLe+7r9+mkDzER8+Nlp6YqbSfxaZQ3LPw+3QXAoGAXoMJYr26fKK/QnT1fBzS
+ackEDYV+Pj0kEsMYe/Mp818OdmxZdeRBhGmdMvPNIquwNbpKsjzl2Vi2Yk9d3uWe
+CspTsiz3nrNrClt5ZexukU6SIPb8/Bbt03YM4ux/smkTa3gOWkZktF63JaBadTpL
+78c8Pvf9JrggxJkKmnO+wxkCgYEAukSTFKw0GTtfkWCs97TWgQU2UVM96GXcry7c
+YT7Jfbh/h/A7mwOCKTfOck4R1bHBDAegmZFKjX/sec/xObXphexi99p9vGRNIjwO
+8tZR9YfYmcARIF0PKf1b4q7ZHNkhVm38hNBf7RAVHBgh58Q9S9fQnmqVzyLJA3ue
+42AB/C8CgYAR0EvPG2e5nxB1R4ZlrjHCxjCsWQZQ2Q+1cAb38NPIYnyo2m72IT/T
+f1/qiqs/2Spe81HSwjA34y2jdQ0eTSE01VdwXIm/cuxKbmjVzRh0M06MOkWP5pZA
+62P5GYY6Ud2JS7Dz+Z9dKJU4vjWrylznk1M0oUVdEzllQkahn831vw==
+-----END RSA PRIVATE KEY-----
Index: /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/etc/hosts
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/etc/hosts	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/etc/hosts	(revision 398)
@@ -0,0 +1,1 @@
+127.0.0.1 localhost.localdomain localhost
Index: /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/etc/services
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/etc/services	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/rom_fs/etc/services	(revision 398)
@@ -0,0 +1,1 @@
+echonet	3061/udp
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/echonet_app_config.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/echonet_app_config.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/echonet_app_config.h	(revision 398)
@@ -0,0 +1,94 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2016 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _ECHONET_APP_CONFIG_H_
+#define _ECHONET_APP_CONFIG_H_
+
+#define ECHONET_TASK_STACK_SIZE	1024	/* ECNL UDPタスク用スタック領域のサイズ */
+
+#define ECHONET_API_DATAQUEUE_COUNT 5		/* ECHONET Lite API用データキュー */
+#define ECHONET_SVC_DATAQUEUE_COUNT 5		/* ECHONET Lite サービス処理タスク用データキュー */
+#define ECHONET_UDP_DATAQUEUE_COUNT 5		/* ECHONET Lite UDP通信処理用データキュー */
+
+/*
+ * サービス処理タスクに追加の処理を挿入したい場合に定義する
+ *
+ * タイムアウト値を返す
+ * TMO echonet_task_get_timer();
+ * #define ECHONET_TASK_GET_TIMER echonet_task_get_timer
+ *
+ * タイマーの時間を進める
+ * void echonet_task_progress(TMO interval);
+ * #define ECHONET_TASK_PROGRESS(interval) echonet_task_progress(interval)
+ *
+ * タイムアウト処理（のための呼び出し）
+ * void echonet_task_timeout();
+ * #define ECHONET_TASK_TIMEOUT echonet_task_timeout()
+ */
+
+/*
+ * ＵＤＰ通信タスクに追加の処理を挿入したい場合に定義する
+ *
+ * タイムアウト値を返す
+ * TMO echonet_udp_task_get_timer();
+ * #define ECHONET_UDP_TASK_GET_TIMER echonet_udp_task_get_timer
+ *
+ * タイマーの時間を進める
+ * void echonet_udp_task_progress(TMO interval);
+ * #define ECHONET_UDP_TASK_PROGRESS(interval) echonet_udp_task_progress(interval)
+ *
+ * タイムアウト処理（のための呼び出し）
+ * void echonet_udp_task_timeout();
+ * #define ECHONET_UDP_TASK_TIMEOUT echonet_udp_task_timeout()
+ */
+
+/* デバッグ出力有効化設定するときに定義 */
+/* #define ECN_DBG_PUT_ENA */
+
+/* デバッグ出力(CARP)有効化設定するときに定義 */
+/* #define ECN_CAP_PUT_ENA */
+
+/* syslog空き待ち有効化設定するときに定義 */
+/* #define ECN_DBG_WAI_ENA */
+
+/* 標準のecn_data_prop_setを使わないときに定義 */
+/* #define ECN_USER_DATA_PROP_SET */
+
+/* 標準のecn_data_prop_getを使わないときに定義 */
+/* #define ECN_USER_DATA_PROP_GET */
+
+#endif /* _ECHONET_APP_CONFIG_H_ */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/fdtable.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/fdtable.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/fdtable.c	(revision 398)
@@ -0,0 +1,513 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2017 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+#include "shellif.h"
+#include <stdint.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "target_syssvc.h"
+#include "fdtable.h"
+#include "kernel_cfg.h"
+#include <string.h>
+#include "util/ntstdio.h"
+#include "hal/serial_api.h"
+
+#ifdef _DEBUG
+static const char THIS_FILE[] = __FILE__;
+#endif
+
+extern IO_TYPE IO_TYPE_STDIN;
+extern IO_TYPE IO_TYPE_STDOUT;
+extern IO_TYPE IO_TYPE_STDERR;
+
+static struct SHELL_FILE fd_table[8 * sizeof(FLGPTN)] = {
+	{ STDIN_FILENO, &IO_TYPE_STDIN, 0 },
+	{ STDOUT_FILENO, &IO_TYPE_STDOUT, 0 },
+	{ STDERR_FILENO, &IO_TYPE_STDERR, 0 },
+};
+#define fd_table_count (sizeof(fd_table) / sizeof(fd_table[0]))
+
+struct SHELL_FILE *new_fp(IO_TYPE *type, int id, int writable)
+{
+	struct SHELL_FILE *fp = NULL;
+	ER ret;
+
+	ret = wai_sem(SEM_FILEDESC);
+	if (ret < 0) {
+		syslog(LOG_ERROR, "wai_sem => %d", ret);
+	}
+
+	for (int fd = 3; fd < fd_table_count; fd++) {
+		fp = &fd_table[fd];
+		if (fp->type != NULL)
+			continue;
+
+		memset(fp, 0, sizeof(struct SHELL_FILE));
+		fp->fd = fd;
+		fp->type = type;
+		fp->handle = id;
+		fp->writable = writable;
+		break;
+	}
+
+	ret = sig_sem(SEM_FILEDESC);
+	if (ret < 0) {
+		syslog(LOG_ERROR, "sig_sem => %d", ret);
+	}
+
+	if (fp != NULL) {
+		FLGPTN flgptn = 0;
+
+		FD_SET(fp->fd, (fd_set *)&flgptn);
+
+		ret = clr_flg(FLG_SELECT_WAIT, ~flgptn);
+		if (ret != E_OK) {
+			syslog(LOG_ERROR, "clr_flg => %d", ret);
+		}
+	}
+
+	return fp;
+}
+
+struct SHELL_FILE *id_to_fd(IO_TYPE *type, int id)
+{
+	struct SHELL_FILE *fp = NULL;
+	ER ret;
+
+	ret = wai_sem(SEM_FILEDESC);
+	if (ret < 0) {
+		syslog(LOG_ERROR, "wai_sem => %d", ret);
+	}
+
+	for (int fd = 3; fd < fd_table_count; fd++) {
+		fp = &fd_table[fd];
+		if ((fp->type == type) && (fp->handle == id))
+			break;
+	}
+
+	ret = sig_sem(SEM_FILEDESC);
+	if (ret < 0) {
+		syslog(LOG_ERROR, "sig_sem => %d", ret);
+	}
+
+	return fp;
+}
+
+int delete_fd_by_id(IO_TYPE *type, int id)
+{
+	struct SHELL_FILE *fp = id_to_fd(type, id);
+	if (fp == NULL)
+		return -EBADF;
+
+	return delete_fp(fp);
+}
+
+int delete_fp(struct SHELL_FILE *fp)
+{
+	ER ret;
+
+	fp->type->delete(fp);
+
+	ret = wai_sem(SEM_FILEDESC);
+	if (ret < 0) {
+		syslog(LOG_ERROR, "wai_sem => %d", ret);
+	}
+
+	memset(fp, 0, sizeof(struct SHELL_FILE));
+
+	ret = sig_sem(SEM_FILEDESC);
+	if (ret < 0) {
+		syslog(LOG_ERROR, "sig_sem => %d", ret);
+	}
+
+	return 0;
+}
+
+struct SHELL_FILE *fd_to_fp(int fd)
+{
+	if ((fd < 0) || (fd >= fd_table_count))
+		return NULL;
+	return &fd_table[fd];
+}
+
+void memand(void *dst, void *src, size_t len)
+{
+	uint8_t *d = (uint8_t *)dst;
+	uint8_t *s = (uint8_t *)src;
+	uint8_t *e = &s[len];
+
+	while (s < e) {
+		*d++ &= *s++;
+	}
+}
+
+struct fd_events {
+	int count;
+	fd_set readfds;
+	fd_set writefds;
+	fd_set errorfds;
+};
+
+ER shell_get_evts(struct fd_events *evts, TMO tmout);
+
+#define TMO_MAX INT_MAX
+
+int shell_select(int n, fd_set *__restrict rfds, fd_set *__restrict wfds, fd_set *__restrict efds, struct timeval *__restrict tv)
+{
+	ER ret;
+	TMO tmout = TMO_FEVR;
+	struct fd_events evts;
+
+	if (tv != NULL) {
+		if (tv->tv_sec < (TMO_MAX / 1000000))
+			tmout = tv->tv_sec * 1000000 + tv->tv_usec;
+		else
+			tmout = TMO_MAX;
+	}
+
+	if (rfds != NULL)
+		memcpy(&evts.readfds, rfds, sizeof(fd_set));
+	else
+		memset(&evts.readfds, 0, sizeof(fd_set));
+	if (wfds != NULL)
+		memcpy(&evts.writefds, wfds, sizeof(fd_set));
+	else
+		memset(&evts.writefds, 0, sizeof(fd_set));
+	if (efds != NULL)
+		memcpy(&evts.errorfds, efds, sizeof(fd_set));
+	else
+		memset(&evts.errorfds, 0, sizeof(fd_set));
+	evts.count = 0;
+
+	ret = shell_get_evts(&evts, tmout);
+	if (ret == E_OK) {
+		if (rfds != NULL)
+			memand(rfds, &evts.readfds, sizeof(fd_set));
+		if (wfds != NULL)
+			memand(wfds, &evts.writefds, sizeof(fd_set));
+		if (efds != NULL)
+			memand(efds, &evts.errorfds, sizeof(fd_set));
+		return evts.count;
+	}
+	if (ret == E_TMOUT) {
+		if (rfds != NULL)
+			memset(rfds, 0, sizeof(fd_set));
+		if (wfds != NULL)
+			memset(wfds, 0, sizeof(fd_set));
+		if (efds != NULL)
+			memset(efds, 0, sizeof(fd_set));
+		return 0;
+	}
+
+	return -EBADF;
+}
+
+int shell_poll(struct pollfd *fds, nfds_t nfds, int timeout)
+{
+	ER ret;
+	TMO tmout;
+	struct fd_events evts;
+
+	if(timeout < 0)
+		tmout = TMO_FEVR;
+	else if (timeout < (TMO_MAX / 1000))
+		tmout = timeout * 1000;
+	else
+		tmout = TMO_MAX;
+
+	memset(&evts, 0, sizeof(evts));
+
+	for (int i = 0; i < nfds; i++) {
+		struct pollfd *pfd = &fds[i];
+		int fd = pfd->fd;
+		if ((fd < 0) || (fd >= fd_table_count))
+			continue;
+
+		if (pfd->events & POLLIN)
+			FD_SET(fd, &evts.readfds);
+		if (pfd->events & POLLOUT)
+			FD_SET(fd, &evts.writefds);
+		if (pfd->events & POLLERR)
+			FD_SET(fd, &evts.errorfds);
+		pfd->revents = 0;
+	}
+
+	ret = shell_get_evts(&evts, tmout);
+	if (ret == E_OK) {
+		int result = 0;
+		for (int i = 0; i < nfds; i++) {
+			struct pollfd *pfd = &fds[i];
+			int fd = pfd->fd;
+			if ((fd < 0) || (fd >= fd_table_count))
+				continue;
+
+			if (FD_ISSET(fd, &evts.readfds))
+				pfd->revents |= POLLIN;
+			if (FD_ISSET(fd, &evts.writefds))
+				pfd->revents |= POLLOUT;
+			if (FD_ISSET(fd, &evts.errorfds))
+				pfd->revents |= POLLERR;
+			if (pfd->revents != 0)
+				result++;
+		}
+		return result;
+	}
+	if (ret == E_TMOUT) {
+		return 0;
+	}
+
+	return -EBADF;
+}
+
+ER shell_get_evts(struct fd_events *evts, TMO tmout)
+{
+	int count;
+	SYSTIM prev, now;
+	FLGPTN flgptn;
+
+	get_tim(&prev);
+
+	for (;;) {
+		ER ret;
+		FLGPTN waitptn, readfds = 0, writefds = 0;
+		struct SHELL_FILE *fp = NULL;
+
+#ifndef NTSHELL_NO_SOCKET
+		waitptn = *((FLGPTN *)&evts->errorfds);
+#else
+		waitptn = *((FLGPTN *)&evts->readfds) | *((FLGPTN *)&evts->errorfds);
+#endif
+		count = 0;
+		for (int fd = 0; fd < fd_table_count; fd++) {
+			fp = &fd_table[fd];
+
+			if (FD_ISSET(fd, &evts->readfds)) {
+				if (fp->type->readable(fp)) {
+					FD_SET(fd, (fd_set *)&readfds);
+					count++;
+					if (fp->readevt_w == fp->readevt_r) fp->readevt_r--;
+				}
+				else {
+					FD_SET(fd, (fd_set *)&waitptn);
+				}
+			}
+
+			if (FD_ISSET(fd, &evts->writefds)) {
+				if (fp->type->writable(fp)) {
+					FD_SET(fd, (fd_set *)&writefds);
+					count++;
+					if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_r--;
+				}
+				else {
+					FD_SET(fd, (fd_set *)&waitptn);
+				}
+			}
+		}
+		memset(evts, 0, sizeof(*evts));
+
+		if (waitptn == 0) {
+			memcpy(&evts->readfds, &readfds, sizeof(evts->readfds));
+			memcpy(&evts->writefds, &writefds, sizeof(evts->writefds));
+			evts->count = count;
+			return E_OK;
+		}
+		else if ((readfds | writefds) != 0) {
+			set_flg(FLG_SELECT_WAIT, (readfds | writefds));
+		}
+
+		/* イベント待ち */
+		flgptn = 0;
+		ret = twai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn, tmout);
+		if (ret != E_OK) {
+			if (ret != E_TMOUT) {
+				syslog(LOG_ERROR, "twai_flg => %d", ret);
+				return ret;
+			}
+		}
+
+		if (flgptn != 0) {
+			flgptn &= waitptn;
+
+			/* 受け取ったフラグのみクリア */
+			ret = clr_flg(FLG_SELECT_WAIT, ~flgptn);
+			if (ret != E_OK) {
+				syslog(LOG_ERROR, "clr_flg => %d", ret);
+			}
+		}
+
+		count = 0;
+		for (int fd = 0; fd < fd_table_count; fd++) {
+			fp = &fd_table[fd];
+
+			if (fp->readevt_w != fp->readevt_r) {
+				fp->readevt_r++;
+				if (FD_ISSET(fd, (fd_set *)&waitptn))
+					FD_SET(fd, &evts->readfds);
+				count++;
+			}
+			if (fp->writeevt_w != fp->writeevt_r) {
+				fp->writeevt_r++;
+				if (FD_ISSET(fd, (fd_set *)&waitptn))
+					FD_SET(fd, &evts->writefds);
+				count++;
+			}
+			if (fp->errorevt_w != fp->errorevt_r) {
+				fp->errorevt_r++;
+				if (FD_ISSET(fd, (fd_set *)&waitptn))
+					FD_SET(fd, &evts->errorfds);
+				count++;
+			}
+		}
+
+		if ((flgptn == 0) || (count > 0))
+			break;
+
+		get_tim(&now);
+
+		SYSTIM elapse = now - prev;
+		if (elapse > tmout) {
+			flgptn = 0;
+			break;
+		}
+
+		prev = now;
+		tmout -= elapse;
+	}
+
+	evts->count = count;
+
+	return (flgptn == 0) ? E_TMOUT : E_OK;
+}
+
+void clean_fd()
+{
+	struct SHELL_FILE *fp = NULL;
+	for (int fd = 3; fd < fd_table_count; fd++) {
+		fp = &fd_table[fd];
+		if ((fp->type == 0) || (fp->fd == 0))
+			continue;
+
+		fp->type->close(fp);
+
+		delete_fp(fp);
+	}
+}
+
+int shell_ioctl(int fd, int request, void *arg)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	return fp->type->ioctl(fp, request, arg);
+}
+
+#ifdef NTSHELL_NO_SOCKET
+
+int shell_socket(int family, int type, int protocol)
+{
+	return -ENOMEM;
+}
+
+int shell_bind(int fd, const struct sockaddr *addr, socklen_t len)
+{
+	return -ENOMEM;
+}
+
+int shell_listen(int fd, int backlog)
+{
+	return -ENOMEM;
+}
+
+int shell_connect(int fd, const struct sockaddr *addr, socklen_t len)
+{
+	return -ENOMEM;
+}
+
+int shell_accept(int fd, struct sockaddr *__restrict addr, socklen_t *__restrict len)
+{
+	return -ENOMEM;
+}
+
+ssize_t shell_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
+{
+	return -ENOMEM;
+}
+
+ssize_t shell_sendmsg(int fd, const struct msghdr *msg, int flags)
+{
+	return -ENOMEM;
+}
+
+ssize_t shell_recvfrom(int fd, void *__restrict buf, size_t len, int flags, struct sockaddr *__restrict addr, socklen_t *__restrict alen)
+{
+	return -ENOMEM;
+}
+
+ssize_t shell_recvmsg(int fd, struct msghdr *msg, int flags)
+{
+	return -ENOMEM;
+}
+
+int shell_shutdown(int fd, int how)
+{
+	return -ENOMEM;
+}
+
+int shell_getsockopt(int fd, int level, int optname, void *optval, socklen_t *__restrict optlen)
+{
+	return -ENOMEM;
+}
+
+int shell_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
+{
+	return -ENOMEM;
+}
+
+int shell_getpeername(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
+{
+	return -ENOMEM;
+}
+
+int shell_getsockname(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
+{
+	return -ENOMEM;
+}
+#endif
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/fdtable.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/fdtable.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/fdtable.h	(revision 398)
@@ -0,0 +1,85 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2017 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+#ifndef SOCKET_STUB_H
+#define SOCKET_STUB_H
+
+typedef const struct io_type_s IO_TYPE;
+
+struct SHELL_FILE {
+	int fd;
+	IO_TYPE *type;
+	int handle;
+	int readevt_r;
+	int readevt_w;
+	int writeevt_r;
+	int writeevt_w;
+	int writable;
+	int errorevt_r;
+	int errorevt_w;
+	void *exinf;
+};
+
+struct io_type_s {
+	int (*close)(struct SHELL_FILE *);
+	size_t (*read)(struct SHELL_FILE *, unsigned char *, size_t);
+	size_t (*write)(struct SHELL_FILE *, const unsigned char *, size_t);
+	off_t (*seek)(struct SHELL_FILE *, off_t, int);
+	int (*ioctl)(struct SHELL_FILE *, int, void *);
+	bool_t (*readable)(struct SHELL_FILE *);
+	bool_t (*writable)(struct SHELL_FILE *);
+	void (*delete)(struct SHELL_FILE *);
+};
+
+#ifndef bool
+#define bool int
+#endif
+#ifndef true
+#define true 1
+#endif
+#ifndef false
+#define false 0
+#endif
+
+struct SHELL_FILE *new_fp(IO_TYPE *type, int id, int writable);
+int delete_fd_by_id(IO_TYPE *type, int id);
+struct SHELL_FILE *fd_to_fp(int fd);
+struct SHELL_FILE *id_to_fd(IO_TYPE *type, int id);
+
+int delete_fp(struct SHELL_FILE *fp);
+void clean_fd();
+
+#endif // !SOCKET_STUB_H
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/io_stub.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/io_stub.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/io_stub.c	(revision 398)
@@ -0,0 +1,650 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ *
+ *  Copyright (C) 2017 Cores Co., Ltd. Japan
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+#include "shellif.h"
+#include <stdint.h>
+#include "ff.h"
+#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 "fdtable.h"
+#include "util/ntstdio.h"
+#include "usrcmd.h"
+#include "core/ntlibc.h"
+#include "kernel_cfg.h"
+#include "target_syssvc.h"
+
+struct SHELL_DIR {
+	FATFS_DIR dir;
+	struct dirent dirent;
+};
+
+int fresult2errno(FRESULT res)
+{
+	switch (res) {
+	case FR_INVALID_OBJECT:
+		return -EINVAL;
+	case FR_TOO_MANY_OPEN_FILES:
+		return -ENOMEM;
+	case FR_NO_FILE:
+	case FR_NO_PATH:
+	case FR_INVALID_DRIVE:
+	case FR_INVALID_NAME:
+		return -ENOENT;
+	case FR_DISK_ERR:
+	case FR_NO_FILESYSTEM:
+	case FR_NOT_ENABLED:
+		return -ENODEV;
+	case FR_WRITE_PROTECTED:
+	case FR_DENIED:
+		return -EACCES;
+	case FR_EXIST:
+		return -EEXIST;
+	case FR_INT_ERR:
+	default:
+		return -EIO;
+	}
+}
+
+static int file_close(struct SHELL_FILE *fp);
+static size_t file_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
+static size_t file_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
+static off_t file_seek(struct SHELL_FILE *fp, off_t ofs, int org);
+static int file_ioctl(struct SHELL_FILE *fp, int req, void *arg);
+static bool_t file_readable(struct SHELL_FILE *fp);
+static bool_t file_writable(struct SHELL_FILE *fp);
+static void file_delete(struct SHELL_FILE *fp);
+
+static int dir_close(struct SHELL_FILE *fp);
+static size_t dir_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
+static size_t dir_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
+static off_t dir_seek(struct SHELL_FILE *fp, off_t ofs, int org);
+static int dir_ioctl(struct SHELL_FILE *fp, int req, void *arg);
+static bool_t dir_readable(struct SHELL_FILE *fp);
+static bool_t dir_writable(struct SHELL_FILE *fp);
+static void dir_delete(struct SHELL_FILE *fp);
+
+IO_TYPE IO_TYPE_FILE = { file_close, file_read, file_write, file_seek, file_ioctl, file_readable, file_writable, file_delete };
+IO_TYPE IO_TYPE_DIR = { dir_close, dir_read, dir_write, dir_seek, dir_ioctl, dir_readable, dir_writable, dir_delete };
+
+int shell_open(const char *path, int flags, void *arg)
+{
+	FRESULT res;
+	struct SHELL_FILE *fp;
+
+	if (flags & O_DIRECTORY) {
+		fp = new_fp(&IO_TYPE_DIR, 0, 0);
+		if (fp == NULL)
+			return -ENOMEM;
+
+		fp->exinf = malloc(sizeof(struct SHELL_DIR));
+		memset(fp->exinf, 0, sizeof(struct SHELL_DIR));
+
+		FATFS_DIR *dir = &((struct SHELL_DIR *)fp->exinf)->dir;
+		FRESULT res;
+		if ((res = f_opendir(dir, path)) != FR_OK) {
+			delete_fp(fp);
+			return fresult2errno(res);
+		}
+		return 0;
+	}
+
+	fp = new_fp(&IO_TYPE_FILE, 0, 1);
+	if (fp == NULL)
+		return -ENOMEM;
+
+	fp->exinf = malloc(sizeof(FIL));
+	memset(fp->exinf, 0, sizeof(FIL));
+
+	BYTE fmd = 0;
+	switch (flags & O_ACCMODE) {
+	case O_RDONLY:
+		fmd = FA_READ;
+		break;
+	case O_WRONLY:
+		fmd = FA_WRITE;
+		break;
+	default:
+		fmd = FA_READ | FA_WRITE;
+		break;
+	}
+	/* ファイルを作成 */
+	if (flags & O_CREAT) {
+		/* 既存の内容は消す */
+		if (flags & O_TRUNC) {
+			fmd |= FA_CREATE_ALWAYS;
+		}
+		/* 新規作成の保障 */
+		else if (flags & O_EXCL) {
+			fmd |= FA_CREATE_NEW;
+		}
+		else {
+			fmd |= FA_OPEN_ALWAYS;
+		}
+	}
+	/* ある場合は開く */
+	else {
+		/* 既存の内容は消す */
+		if (flags & O_TRUNC) {
+			fmd |= FA_CREATE_ALWAYS;
+		}
+	}
+
+	if ((res = f_open((FIL *)fp->exinf, path, fmd)) == FR_OK) {
+		fp->handle = fp->fd;
+		return fp->fd;
+	}
+
+	delete_fp(fp);
+	return fresult2errno(res);
+}
+
+int file_close(struct SHELL_FILE *fp)
+{
+	FRESULT res;
+
+	if ((res = f_close((FIL *)fp->exinf)) == FR_OK) {
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+size_t file_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
+{
+	unsigned int ret = 0;
+	FRESULT res;
+
+	if ((res = f_read((FIL *)fp->exinf, data, len, &ret)) != FR_OK)
+		return -EIO;
+
+	return ret;
+}
+
+size_t file_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
+{
+	unsigned int ret = 0;
+	FRESULT res;
+
+	if ((res = f_write((FIL *)fp->exinf, data, len, &ret)) != FR_OK)
+		return -EIO;
+
+	return ret;
+}
+
+off_t file_seek(struct SHELL_FILE *fp, off_t ptr, int dir)
+{
+	switch (dir) {
+	case SEEK_SET:
+		dir = F_SEEK_SET;
+		break;
+	case SEEK_CUR:
+		dir = F_SEEK_CUR;
+		break;
+	case SEEK_END:
+		dir = F_SEEK_END;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	FRESULT res;
+	if ((res = f_seek((FIL *)fp->exinf, ptr, dir)) != FR_OK)
+		return -EIO;
+
+	return ((FIL *)fp->exinf)->fptr;
+}
+
+int file_ioctl(struct SHELL_FILE *fp, int req, void *arg)
+{
+	DRESULT res;
+
+	if ((res = disk_ioctl(((FIL *)fp->exinf)->fs->drv, req, arg) != RES_OK))
+		return -EINVAL;
+
+	return 0;
+}
+
+bool_t file_readable(struct SHELL_FILE *fp)
+{
+	return fp->readevt_w != fp->readevt_r;
+}
+
+bool_t file_writable(struct SHELL_FILE *fp)
+{
+	return fp->writable && (fp->writeevt_w == fp->writeevt_r);
+}
+
+void file_delete(struct SHELL_FILE *fp)
+{
+	free((FIL *)fp->exinf);
+	fp->exinf = NULL;
+}
+
+int shell_close(int fd)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	int ret = fp->type->close(fp);
+
+	delete_fp(fp);
+
+	return ret;
+}
+
+ssize_t shell_read(int fd, void *data, size_t len)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	return fp->type->read(fp, (unsigned char *)data, len);
+}
+
+int shell_readv(int fd, const struct iovec *iov, int iovcnt)
+{
+	int result = 0;
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	const struct iovec *end = &iov[iovcnt];
+	for (; iov < end; iov++) {
+		result += fp->type->read(fp, (unsigned char *)iov->iov_base, iov->iov_len);
+	}
+
+	return result;
+}
+
+ssize_t shell_write(int fd, const void *data, size_t len)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	return fp->type->write(fp, (unsigned char *)data, len);
+}
+
+int shell_writev(int fd, const struct iovec *iov, int iovcnt)
+{
+	int result = 0;
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	const struct iovec *end = &iov[iovcnt];
+	for (; iov < end; iov++) {
+		result += fp->type->write(fp, (unsigned char *)iov->iov_base, iov->iov_len);
+	}
+
+	return result;
+}
+
+int shell_llseek(int fd, off_t ptr, off_t *result, int dir)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	off_t ret = fp->type->seek(fp, ptr, dir);
+	if (ret < 0)
+		return ret;
+
+	*result = ret;
+	return 0;
+}
+
+int shell_fstat(int fd, struct stat * st)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	memset(st, 0, sizeof(*st));
+	st->st_mode = S_IFCHR;
+	//st->st_blksize = 1024;
+	return 0;
+}
+
+int shell_fsync(int fd)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+	return -EIO;
+}
+
+int shell_ftruncate(int fd, off_t length)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	FRESULT res;
+	if ((res = f_truncate((FIL *)fp->exinf)) != FR_OK)
+		return fresult2errno(res);
+
+	return 0;
+}
+
+int shell_fcntl(int fd, int cmd, void *arg)
+{
+	return shell_ioctl(fd, cmd, arg);
+}
+
+int shell_stat(const char *__restrict path, struct stat *__restrict st)
+{
+	FILINFO fi;
+	FRESULT ret;
+#if FF_USE_LFN
+	static char lfn[FF_MAX_LFN + 1];   /* Buffer to store the LFN */
+	fi.lfname = lfn;
+	fi.lfsize = sizeof lfn;
+#endif
+	if (strcmp(path, ".") == 0) {
+		char cwd[FF_MAX_LFN];
+		if ((ret = f_getcwd(cwd, sizeof(cwd))) != FR_OK) {
+			return fresult2errno(ret);
+		}
+		int l = strlen(cwd);
+		// ルートディレクトリの場合
+		if (cwd[l - 2] == ':' && cwd[l - 1] == '/') {
+			st->st_size = 0;
+			st->st_mtim.tv_nsec = 0;
+			st->st_mtim.tv_sec = 0;
+			st->st_mode = S_IFDIR;
+			return 0;
+		}
+		if ((ret = f_stat(cwd, &fi)) != FR_OK) {
+			return fresult2errno(ret);
+		}
+	}
+	else if ((ret = f_stat(path, &fi)) != FR_OK) {
+		return fresult2errno(ret);
+	}
+
+	st->st_size = fi.fsize;
+	st->st_mtim.tv_nsec = 0;
+	st->st_mtim.tv_sec = fi.fdate + fi.ftime;
+	st->st_mode = (S_IRUSR | S_IRGRP | S_IROTH);
+	st->st_mode |= (fi.fattrib & AM_RDO) ? 0 : (S_IWUSR | S_IWGRP | S_IWOTH);
+	st->st_mode |= (fi.fattrib & (AM_DIR | AM_VOL)) ? S_IFDIR : S_IFREG;
+
+	return 0;
+}
+
+int shell_lstat(const char *__restrict path, struct stat *__restrict st)
+{
+	return shell_stat(path, st);
+}
+
+int shell_link(const char *a, const char *b)
+{
+	return -EPERM;
+}
+
+int shell_unlink(const char *path)
+{
+	FRESULT res;
+
+	if ((res = f_unlink(path)) != FR_OK)
+		return -EIO;
+
+	return 0;
+}
+
+int shell_rmdir(const char *path)
+{
+	FRESULT res;
+
+	if ((res = f_unlink(path)) != FR_OK)
+		return -EIO;
+
+	return 0;
+}
+
+int shell_rename(const char *oldpath, const char *newpath)
+{
+	FRESULT res;
+
+	if ((res = f_rename(oldpath, newpath)) != FR_OK)
+		return fresult2errno(res);
+	return 0;
+}
+
+#define S_IREAD S_IRUSR
+#define S_IWRITE S_IWUSR
+
+int shell_mkdir(const char *path, mode_t mode)
+{
+	FRESULT res;
+
+	if ((res = f_mkdir(path)) != FR_OK)
+		return fresult2errno(res);
+
+	BYTE attr = 0;
+	BYTE mask = AM_RDO | AM_SYS; // AM_ARC, AM_HID
+
+	if (mode & S_IREAD) {
+		if ((mode & S_IWRITE) == 0) {
+			attr |= AM_RDO;
+		}
+	}
+	else {
+		attr |= AM_SYS;
+	}
+
+	if ((res = f_chmod(path, attr, mask)) != FR_OK) {
+		return fresult2errno(res);
+	}
+
+	return 0;
+}
+
+int shell_chmod(const char *path, mode_t mode)
+{
+	FRESULT res;
+	BYTE attr = 0;
+	BYTE mask = AM_RDO | AM_SYS; // AM_ARC, AM_HID
+
+	if (mode & S_IREAD) {
+		if ((mode & S_IWRITE) == 0) {
+			attr |= AM_RDO;
+		}
+	}
+	else {
+		attr |= AM_SYS;
+	}
+
+	if ((res = f_chmod(path, attr, mask)) != FR_OK) {
+		return fresult2errno(res);
+	}
+
+	return 0;
+}
+
+char *shell_getcwd(char *buf, size_t size)
+{
+	FRESULT ret;
+	if ((ret = f_getcwd(buf, size)) != FR_OK) {
+		return NULL;
+	}
+
+	return buf;
+}
+
+int shell_chdir(const char *path)
+{
+	FRESULT res;
+	if ((res = f_chdir(path)) != FR_OK) {
+		return fresult2errno(res);
+	}
+
+	return 0;
+}
+
+int shell_chroot(const char *path)
+{
+	shell_abort();
+	return -EPERM;
+}
+
+int dir_close(struct SHELL_FILE *fp)
+{
+	FRESULT res;
+	if ((res = f_closedir(&((struct SHELL_DIR *)fp->exinf)->dir)) != FR_OK) {
+		return fresult2errno(res);
+	}
+
+	return 0;
+}
+
+int shell_getdents(int fd, struct dirent *de, size_t len)
+{
+	if (len < sizeof(struct dirent))
+		return -EINVAL;
+
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	FILINFO fno;
+#if FF_USE_LFN
+	static char lfn[FF_MAX_LFN + 1];   /* Buffer to store the LFN */
+	fno.lfname = lfn;
+	fno.lfsize = sizeof lfn;
+#endif
+	FRESULT res;
+	if ((res = f_readdir(&((struct SHELL_DIR *)fp->exinf)->dir, &fno)) != FR_OK || fno.fname[0] == '\0') {
+		return fresult2errno(res);
+	}
+
+	memset(de, 0, sizeof(*de));
+#if FF_USE_LFN
+	ntlibc_strlcpy(de->d_name, *fno.lfname ? fno.lfname : fno.fname, sizeof(de->d_name));
+#else
+	ntlibc_strlcpy(de->d_name, fno.fname, sizeof(de->d_name));
+#endif
+
+	return 0;
+}
+
+size_t dir_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
+{
+	return -EPERM;
+}
+
+size_t dir_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
+{
+	return -EPERM;
+}
+
+off_t dir_seek(struct SHELL_FILE *fp, off_t ptr, int dir)
+{
+	FRESULT res;
+
+	if (dir != SEEK_SET)
+		return -EINVAL;
+
+	if (ptr == 0) {
+		if ((res = f_rewinddir(&((struct SHELL_DIR *)fp->exinf)->dir)) != FR_OK) {
+			return fresult2errno(res);
+		}
+	}
+	else {
+		FILINFO fno;
+#if FF_USE_LFN
+		static char lfn[FF_MAX_LFN + 1];   /* Buffer to store the LFN */
+		fno.lfname = lfn;
+		fno.lfsize = sizeof lfn;
+#endif
+		if ((res = f_rewinddir(&((struct SHELL_DIR *)fp->exinf)->dir)) != FR_OK) {
+			return fresult2errno(res);
+		}
+
+		for (int i = 0; i < ptr; i++) {
+			if ((res = f_readdir(&((struct SHELL_DIR *)fp->exinf)->dir, &fno)) != FR_OK || fno.fname[0] == '\0') {
+				return fresult2errno(res);
+			}
+		}
+	}
+
+	return ptr;
+}
+
+int dir_ioctl(struct SHELL_FILE *fp, int req, void *arg)
+{
+	return -EINVAL;
+}
+
+bool_t dir_readable(struct SHELL_FILE *fp)
+{
+	return fp->readevt_w != fp->readevt_r;
+}
+
+bool_t dir_writable(struct SHELL_FILE *fp)
+{
+	return false;
+}
+
+void dir_delete(struct SHELL_FILE *fp)
+{
+	free((struct SHELL_DIR *)fp->exinf);
+	fp->exinf = NULL;
+}
+
+pid_t shell_getpid(void)
+{
+	return 1;
+}
+
+int shell_access(const char *path, int mode)
+{
+	struct stat st;
+	int ret;
+
+	ret = shell_stat(path, &st);
+	if (ret != 0)
+		return ret;
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/net_misc.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/net_misc.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/net_misc.c	(revision 398)
@@ -0,0 +1,146 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2018 Cores Co., Ltd. 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 <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+#include "netapp/dhcp4_cli.h"
+#include "netapp/dhcp4_cli_var.h"
+#include "ntp_cli.h"
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+#include <stdio.h>
+
+T_DHCP4_CLI_CONTEXT *dhcp4_cli_initialize(ID tskid, ID cepid);
+int dhcp4_cli_get_timer(T_DHCP4_CLI_CONTEXT *ct);
+void dhcp4_cli_progress(T_DHCP4_CLI_CONTEXT *ct, int elapse);
+void dhcp4_cli_wakeup(T_DHCP4_CLI_CONTEXT *ct);
+void dhcp4_cli_timeout(T_DHCP4_CLI_CONTEXT *ct);
+
+int net_misc_get_timer(T_DHCP4_CLI_CONTEXT *ct, T_NTP_CLI_CONTEXT *nc)
+{
+	int timer = dhcp4_cli_get_timer(ct);
+
+	if ((nc->timer != TMO_FEVR) && ((timer == TMO_FEVR) || (timer > nc->timer))) {
+		timer = nc->timer;
+	}
+
+	return timer;
+}
+
+extern T_NTP_CLI_CONTEXT ntp_cli;
+
+/*
+ *  DHCP, NTP クライアント タスク
+ */
+
+void
+net_misc_task (intptr_t exinf)
+{
+	T_DHCP4_CLI_CONTEXT *ct;
+	T_NTP_CLI_CONTEXT *nc = &ntp_cli;
+	ER		error = E_OK, ret;
+	SYSTIM		prev, time;
+	int timer;
+
+	get_tid(&nc->tskid);
+	syslog(LOG_NOTICE, "[NET MISC:%d,%d] started.", nc->tskid, (ID)exinf);
+
+	/* 初期化 */
+	ct = dhcp4_cli_initialize(nc->tskid, UDP4_DHCP_CLI_CEPID);
+	ntp_cli_initialize(nc, NTP_CLI_CEPID);
+
+	ret = get_tim(&time);
+	if (ret != E_OK) {
+		syslog(LOG_NOTICE, "[NET MISC,%d] get_tim error: %7lu,%s",
+			nc->cepid, time / SYSTIM_HZ, itron_strerror(ret));
+		return;
+	}
+
+	while (true) {
+		prev = time;
+
+		/* タイマー取得 */
+		timer = net_misc_get_timer(ct, nc);
+
+		/* 待ち */
+		error = tslp_tsk(timer);
+		if ((error != E_OK) && (error != E_TMOUT)) {
+			syslog(LOG_NOTICE, "[NET MISC,%d] tslp_tsk error: %s %d",
+				nc->cepid, itron_strerror(error), timer);
+			break;
+		}
+
+		ret = get_tim(&time);
+		if (ret != E_OK) {
+			syslog(LOG_NOTICE, "[NET MISC,%d] get_tim error: %s",
+				nc->cepid, itron_strerror(ret));
+			break;
+		}
+
+		/* 時間経過 */
+		int elapse = time - prev;
+		dhcp4_cli_progress(ct, elapse);
+		ntp_cli_progress(nc, elapse);
+
+		/* 起こされた場合 */
+		if (error == E_OK) {
+			dhcp4_cli_wakeup(ct);
+			ntp_cli_wakeup(nc);
+		}
+
+		/* タイムアウト処理 */
+		dhcp4_cli_timeout(ct);
+		ntp_cli_timeout(nc);
+	}
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/net_misc.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/net_misc.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/net_misc.cfg	(revision 398)
@@ -0,0 +1,65 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2018 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  DHCP, NTP クライアントのシステムコンフィギュレーションファイル
+ */
+
+/* セマフォ */
+
+CRE_SEM(SEM_DHCP4_CLI_LOCK,	{ TA_TPRI, 1, 1 });
+
+/* 送受信バッファ */
+
+CRE_MPF(MPF_DHCP4_CLI_MSG, {
+	TA_TFIFO,
+	NUM_MPF_DHCP4_CLI_MSG,
+	sizeof(T_DHCP4_CLI_MSG),
+	NULL,
+	NULL
+	});
+
+/* タスク */
+
+CRE_TSK(NET_MISC_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	net_misc_task,
+	NET_MISC_MAIN_PRIORITY,
+	NET_MISC_STACK_SIZE,
+	NULL
+	});
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/net_misc.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/net_misc.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/net_misc.h	(revision 398)
@@ -0,0 +1,53 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2018 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _NET_MISC_H_
+#define _NET_MISC_H_
+
+/* スタックサイズ */
+
+#define NET_MISC_STACK_SIZE	2048		/* NTP クライアントタスク（IPv4）のスタックサイズ	*/
+
+/* 優先度 */
+
+#define NET_MISC_MAIN_PRIORITY	5		/* NTP クライアントタスク（IPv4）の優先度		*/
+
+/* タスク */
+
+extern void	net_misc_task(intptr_t exinf);
+
+#endif	/* of #ifndef _NET_MISC_H_ */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/netcmd.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/netcmd.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/netcmd.c	(revision 398)
@@ -0,0 +1,670 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+#include "shellif.h"
+#include <kernel.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <string.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include <tinet_config.h>
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+#include <tinet_nic_defs.h>
+#include <tinet_cfg.h>
+#include <netinet/in_var.h>
+#include <net/ethernet.h>
+#include <net/if6_var.h>
+#include <net/net.h>
+#include <net/if_var.h>
+#include <netinet/udp_var.h>
+#include <netapp/netapp_var.h>
+#include <netapp/netapp.h>
+#include <netapp/dhcp4_cli.h>
+#include <netapp/resolver.h>
+#include "core/ntlibc.h"
+#include <stdio.h>
+#include "ntp_cli.h"
+#include "kernel_cfg.h"
+
+#if defined(SUPPORT_INET6)
+#define DEFAULT_API_PROTO	API_PROTO_IPV6
+#else
+#define DEFAULT_API_PROTO	API_PROTO_IPV4
+#endif
+extern void ping6(T_IN6_ADDR *addr, uint_t tmo, uint_t len);
+extern void ping4(T_IN4_ADDR *addr, uint_t tmo, uint_t len);
+
+/*
+ *  str_num -- cons_printf の数値変換
+ */
+
+static void
+str_chr(char *text, int *pos, int size, char c)
+{
+	if (*pos >= size)
+		return;
+	text[*pos] = c;
+	*pos = *pos + 1;
+}
+
+/*
+ *  str_num -- cons_printf の数値変換
+ */
+
+static int
+str_num(char *text, int *pos, int size, ulong_t 	val, int radix,
+         const char *radchar, int width, bool_t minus, char padchar)
+{
+	char	digits[24];
+	int	ix, pad, pchars;
+	bool_t	left;
+
+	if (width < 0) {
+		width = -width;
+		left = true;
+	}
+	else
+		left = false;
+
+	ix = 0;
+	do {
+		digits[ix ++] = radchar[val % radix];
+		val /= radix;
+	} while (val != 0);
+
+	if (minus)
+		digits[ix ++] = '-';
+
+	if (width > ix)
+		pchars = width;
+	else
+		pchars = ix;
+
+	pad = ix;
+	if (!left)	/* 右詰め */
+		for ( ; pad < width; pad ++)
+			str_chr(text, pos, size, padchar);
+
+	while (ix -- > 0)
+		str_chr(text, pos, size, digits[ix]);
+
+	if (left)	/* 左詰め */
+		for ( ; pad < width; pad ++)
+			str_chr(text, pos, size, padchar);
+
+	return pchars;
+}
+
+/*
+ *  str_ipv4addr -- IPv4 アドレス出力
+ */
+
+int
+str_ipv4addr (char *text, int size, T_IN4_ADDR *addr, int width)
+{
+	int len = 3, pos = 0;	/* 3 は '.' の文字数 */
+
+	len += str_num(text, &pos, size, (*addr >> 24) & 0xff, 10, radhex, 0, false, ' '); 
+	str_chr(text, &pos, size, '.');
+	len += str_num(text, &pos, size, (*addr >> 16) & 0xff, 10, radhex, 0, false, ' '); 
+	str_chr(text, &pos, size, '.');
+	len += str_num(text, &pos, size, (*addr >>  8) & 0xff, 10, radhex, 0, false, ' '); 
+	str_chr(text, &pos, size, '.');
+	len += str_num(text, &pos, size,  *addr        & 0xff, 10, radhex, 0, false, ' '); 
+
+	for ( ; len < width; len ++)
+		str_chr(text, &pos, size, ' ');
+
+	return len;
+}
+
+/*
+ *  ipv6addr -- IPv6 アドレス出力
+ */
+
+int
+str_ipv6addr (char *text, int size, const T_IN6_ADDR *addr, int width)
+{
+	int	len = 0, ix, len6, pos = 0;
+	bool_t	omit = false, zero = false;
+
+	if (addr == NULL || IN6_IS_ADDR_UNSPECIFIED(addr)) {
+		str_chr(text, &pos, size, '0');
+		str_chr(text, &pos, size, ':');
+		str_chr(text, &pos, size, ':');
+		str_chr(text, &pos, size, '0');
+		len = 4;
+	}
+	else {
+		if (in6_is_addr_ipv4mapped(addr))
+			len6 = sizeof(T_IN6_ADDR) / 2 - 2;
+		else
+			len6 = sizeof(T_IN6_ADDR) / 2;
+		for (ix = 0; ix < len6; ix ++) {
+			if (omit) {
+				len += str_num(text, &pos, size, ntohs(addr->s6_addr16[ix]), 16, radhex, 0, false, ' '); 
+				if (ix < 7) {
+					str_chr(text, &pos, size, ':');
+					len ++;
+				}
+			}
+			else if (ix > 0 && ix < 7 && addr->s6_addr16[ix] == 0)
+				zero = true;
+			else {
+				if (zero) {
+					omit = true;
+					str_chr(text, &pos, size, ':');
+					len ++;
+				}
+				len += str_num(text, &pos, size, ntohs(addr->s6_addr16[ix]), 16, radhex, 0, false, ' '); 
+				if (ix < 7) {
+					str_chr(text, &pos, size, ':');
+					len ++;
+				}
+			}
+		}
+
+		if (len6 == sizeof(T_IN6_ADDR) / 2 - 2) {
+			T_IN4_ADDR ip4addr;
+
+			ip4addr = ntohl(addr->s6_addr32[3]);
+			len += str_ipv4addr(&text[len], size - len, &ip4addr, 0);
+		}
+
+		for ( ; len < width; len ++)
+			str_chr(text, &pos, size, ' ');
+	}
+	return len;
+}
+
+/*
+ *  str_macaddr -- MAC アドレス出力
+ */
+
+int
+str_macaddr (char *text, int size, uint8_t *mac, int width)
+{
+	int oct, len, pos = 0;
+
+	for (oct = 5; oct -- > 0; ) {
+		str_num(text, &pos, size, *mac ++, 16, radhex, 2, false, '0'); 
+		str_chr(text, &pos, size, ':');
+	}
+	str_num(text, &pos, size, *mac, 16, radhex, 2, false, '0'); 
+
+	for (len = 17; len < width; len ++)
+		str_chr(text, &pos, size, ' ');
+
+	return len;
+}
+
+int usrcmd_ping(int argc, char **argv)
+{
+	int tmo = 3, size = 64;
+	char apip = DEFAULT_API_PROTO;
+	char *line = argv[1];
+#if defined(SUPPORT_INET6)
+	T_IN6_ADDR	addr;
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	addr4;
+#endif
+#else
+	T_IN4_ADDR	addr;
+#endif
+	static const char i6rlp_pmtu_str1[] = " FF1E::1:2 1 1452";
+	static const char i6rlp_pmtu_str2[] = " FF1E::1:2 1 1352";
+	static const char i6rlp_pmtu_str3[] = " fe80::0200:00ff:fe00:0100 1 2";
+
+	if (apip == '1')
+		ntlibc_strcpy(line, i6rlp_pmtu_str1);
+	else if (apip == '2')
+		ntlibc_strcpy(line, i6rlp_pmtu_str2);
+	else if (apip == '3')
+		ntlibc_strcpy(line, i6rlp_pmtu_str3);
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+	if (argc <= 2)
+		return 0;
+
+	if ('0' <= *line && *line <= '9') {
+		if (*line == '6')
+			apip = API_PROTO_IPV6;
+		if (*line == '4')
+			apip = API_PROTO_IPV4;
+		line++;
+	}
+
+	line = argv[2];
+#else
+	if (argc <= 1)
+		return 0;
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
+		printf("[PING] unknown host.\n");
+		return 0;
+	}
+
+	if (argc > 2) {
+		line = argv[2];
+		if ('0' <= *line && *line <= '9')
+			line = get_int(&tmo, line);
+
+		if (argc > 3) {
+			line = argv[3];
+			if ('0' <= *line && *line <= '9')
+				line = get_int(&size, line);
+		}
+	}
+
+#if defined(SUPPORT_INET6)
+#if defined(SUPPORT_INET4)
+	if (apip == API_PROTO_IPV6) {
+		printf("[PING6] size: %d, tmo: %d, host: %s\n", size, tmo, ipv62str(NULL, &addr));
+		ping6(&addr, (uint_t)tmo, (uint_t)size);
+	}
+	else {
+		addr4 = ntohl(addr.s6_addr32[3]);
+		printf("[PING4] size: %d, tmo: %d, host: %s\n", size, tmo, ip2str(NULL, &addr4));
+		ping4(&addr4, (uint_t)tmo, (uint_t)size);
+	}
+#else /* of #if defined(SUPPORT_INET4) */
+	printf("[PING6] size: %d, tmo: %d, host: %s\n", size, tmo, ipv62str(NULL, &addr));
+	ping6(&addr, (uint_t)tmo, (uint_t)size);
+#endif	/* of #if defined(SUPPORT_INET4) */
+#else	/* of #if defined(SUPPORT_INET6) */
+	printf("[PING4] size: %d, tmo: %d, host: %s\n", size, tmo, ip2str(NULL, &addr));
+	ping4(&addr, (uint_t)tmo, (uint_t)size);
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+	return 0;
+}
+
+static void dhcp4c_info()
+{
+	T_IN4_ADDR svaddr;
+	SYSTIM bind_start;
+	ER ret;
+	uint32_t expire, renew, rebind;
+	char temp[30];
+	int pos;
+
+	if ((ret = dhcp4c_get_info(&svaddr, &expire, &renew, &rebind, &bind_start)) == E_OK) {
+		pos = str_ipv4addr(temp, sizeof(temp), &svaddr, 0);
+		temp[pos] = '\0';
+		printf("DHCPv4 server: %s,\n", temp);
+		printf("  Renew:       %u:%02u:%02u,\n",
+			renew / 3600, (renew / 60) % 60, renew % 60);
+		printf("  Rebind:      %u:%02u:%02u, Expire:   %u:%02u:%02u.\n",
+			rebind / 3600, (rebind / 60) % 60, rebind % 60,
+			expire / 3600, (expire / 60) % 60, expire % 60);
+	}
+	else if (ret == E_OBJ)
+		printf("DHCPv4 server: not available.\n");
+}
+
+int usrcmd_dhcp4c(int argc, char **argv)
+{
+	ER ret;
+
+	if (argc < 2)
+		return 0;
+
+	if (ntlibc_strcmp(argv[1], "rel") == 0) {
+		ret = dhcp4c_rel_info();
+		printf("dhcp4c_rel_info %d\n", ret);
+	}
+	else if (ntlibc_strcmp(argv[1], "renew") == 0) {
+		ret = dhcp4c_renew_info();
+		printf("dhcp4c_renew_info %d\n", ret);
+	}
+	else {
+		dhcp4c_info();
+	}
+
+	return 0;
+}
+
+/*
+*  s_show_dns_domain_name -- DNS のドメイン名を表示する。
+*/
+
+static uint_t
+s_show_dns_domain_name(uint8_t *hdr, uint_t offset)
+{
+	uint8_t	*ptr;
+	uint_t	c;
+
+	ptr = hdr + offset;
+	while (*ptr) {
+		if ((*ptr & DNS_MSG_COMP_MARK) == DNS_MSG_COMP_MARK) {
+			s_show_dns_domain_name(hdr, (*ptr & ~DNS_MSG_COMP_MARK) << 8 | *(ptr + 1));
+			ptr += 2;
+			break;
+		}
+		else {
+			for (c = 1; c <= *ptr; c++)
+				printf("%c", *(ptr + c));
+			ptr += *ptr + 1;
+			if (*ptr)
+				printf(".");
+		}
+	}
+	return ptr - hdr;
+}
+
+/*
+ *  show_dns_soa -- DNS の SOA RDATA を表示する。
+ */
+
+static ER_UINT
+show_dns_soa(uint8_t *msg, ER_UINT length, uint_t offset)
+{
+	T_RSLV_SOA	soa;
+	ER_UINT		error;
+	uint_t		rn_offset;
+
+	if ((error = dns_analyze_soa(&soa, offset, msg, length)) < 0)
+		return error;
+
+	printf("    mname:   ");
+	rn_offset = s_show_dns_domain_name(msg, offset);
+	putchar('\n');
+	printf("    rname:   ");
+	s_show_dns_domain_name(msg, rn_offset);
+	putchar('\n');
+
+	printf("    serial:  %d\n", soa.serial);
+	printf("    refresh: %d\n", soa.refresh);
+	printf("    retry:   %d\n", soa.retry);
+	printf("    expirel: %d\n", soa.expire);
+	printf("    minimum: %d\n", soa.minimum);
+
+	return E_OK;
+}
+
+/*
+ *  show_dns_qdsection -- DNS の Question セクションを表示する。
+ */
+
+static ER_UINT
+show_dns_qdsection(uint8_t *msg, ER_UINT length, T_RSLV_DNS_MSG *rslv)
+{
+	T_RSLV_QD	qd;
+	ER_UINT		offset, error;
+	int		scount;
+
+	printf("question   section: %d\n", rslv->dns_hdr.qdcount);
+	offset = rslv->qd_offset;
+	for (scount = 1; scount <= rslv->dns_hdr.qdcount; scount++) {
+		if ((error = dns_analyze_qd(&qd, offset, msg, length)) < 0)
+			return error;
+
+		printf("%2d: ", scount);
+		s_show_dns_domain_name(msg, offset);
+		printf("\n    type: %-4s, class: %2s\n", dns_strtype(qd.type), dns_strclass(qd.class));
+		offset = error;
+	}
+
+	return E_OK;
+}
+
+/*
+ *  show_dns_section -- DNS の各セクションを表示する。
+ */
+
+static ER_UINT
+show_dns_section(uint8_t *msg, ER_UINT length, uint_t scount, uint_t offset, char *title)
+{
+	T_RSLV_RR	rr;
+	T_IN4_ADDR	in4_addr;
+	ER_UINT		error;
+	int		count, dcount, col;
+	T_IN6_ADDR	in6_addr;
+	char temp[30];
+	int pos;
+
+	printf("%10s section: %d\n", title, scount);
+	for (count = 1; count <= scount; count++) {
+		if ((error = dns_analyze_rr(&rr, offset, msg, length)) < 0)
+			return error;
+
+		printf("%2d: ", count);
+		s_show_dns_domain_name(msg, offset);
+		printf("\n    type: %-4s, class: %2s, TTL: %2d, len: %3d, offset: 0x%02x\n",
+			dns_strtype(rr.type), dns_strclass(rr.class), rr.ttl, rr.rdlength, rr.rdata_offset);
+
+		switch (rr.type) {
+		case DNS_TYPE_A:
+			memcpy((void*)&in4_addr, (void*)(msg + rr.rdata_offset), sizeof(in4_addr));
+			in4_addr = ntohl(in4_addr);
+			pos = str_ipv4addr(temp, sizeof(temp), &in4_addr, 0);
+			temp[pos] = '\0';
+			printf("    IPv4 addr: %s\n", temp);
+			break;
+		case DNS_TYPE_NS:
+			printf("    host: ");
+			s_show_dns_domain_name(msg, rr.rdata_offset);
+			putchar('\n');
+			break;
+		case DNS_TYPE_CNAME:
+			printf("    host: ");
+			s_show_dns_domain_name(msg, rr.rdata_offset);
+			putchar('\n');
+			break;
+		case DNS_TYPE_SOA:
+			show_dns_soa(msg, length, rr.rdata_offset);
+			break;
+		case DNS_TYPE_PTR:
+			printf("     PTR: ");
+			s_show_dns_domain_name(msg, rr.rdata_offset);
+			putchar('\n');
+			break;
+		case DNS_TYPE_AAAA:
+			memcpy((void*)&in6_addr, (void*)(msg + rr.rdata_offset), sizeof(in6_addr));
+			pos = str_ipv6addr(temp, sizeof(temp), &in6_addr, 0);
+			temp[pos] = '\0';
+			printf("    IPv6 addr: %s\n", temp);
+			break;
+		default:
+			printf("    data: ");
+			col = 32;
+			for (dcount = 0; dcount < rr.rdlength; dcount++) {
+				printf("%02x", *(msg + rr.rdata_offset + dcount));
+				if (--col == 0) {
+					printf("\n          ");
+					col = 32;
+				}
+			}
+			putchar('\n');
+			break;
+		}
+	}
+
+	return E_OK;
+}
+/*
+ *  dns_info -- DNS 情報の表示
+ */
+
+static void dns_info()
+{
+#if defined(SUPPORT_INET6)
+	T_IN6_ADDR	in6_addr;
+#endif
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	in4_addr;
+#endif
+	char temp[30];
+	int pos;
+
+#if defined(SUPPORT_INET6)
+
+	printf("domain name:     %s\n", dns_in6_get_dname());
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+	printf("domain name:     %s\n", dns_in4_get_dname());
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET6)
+	dns_in6_get_addr(&in6_addr);
+	printf("IPv6 DNS server: ");
+	if (IN6_IS_ADDR_UNSPECIFIED(&in6_addr))
+		printf("not available.\n");
+	else {
+		pos = str_ipv6addr(temp, sizeof(temp), &in6_addr, 0);
+		temp[pos] = '\0';
+		printf("%s.\n", temp);
+	}
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+	dns_in4_get_addr(&in4_addr);
+	printf("IPv4 DNS server: ");
+	if (in4_addr == IPV4_ADDRANY)
+		printf("not available.\n");
+	else {
+		pos = str_ipv4addr(temp, sizeof(temp), &in4_addr, 0);
+		temp[pos] = '\0';
+		printf("%s.\n", temp);
+	}
+#endif	/* of #if defined(SUPPORT_INET4) */
+}
+
+/*
+ *  name_lookup -- ホスト名－IP アドレス変換
+ */
+
+const char *rcode_str[] = {
+	"no error",
+	"format error",
+	"server error",
+	"name error",
+	"not implement",
+	"refused",
+};
+
+int usrcmd_dnsc(int argc, char **argv)
+{
+	char *line = argv[1];
+	static char hostname[DBG_LINE_SIZE + 1];
+
+	T_RSLV_DNS_MSG	rslv;
+	ER_UINT		length, offset;
+	ER		error;
+	uint_t		flags = 0;
+	uint8_t 	*msg;
+
+	if (ntlibc_strcmp(line, "info") == 0) {
+		dns_info();
+		return 0;
+	}
+
+	/* コマンドのオプションを設定する。*/
+	line = skip_blanks(resolv_options(&flags, line, DEFAULT_API_PROTO));
+	if ((flags & (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) == 0) {
+		printf("DNS server not available.\n");
+		return 0;
+	}
+
+	/* 照会するホスト名・IP アドレスを解析する。*/
+	resolv_hoststr(&flags, hostname, sizeof(hostname), line);
+
+	/* 正引きでも逆引きでもプロトコル上は正引きを指定する。*/
+	flags |= DNS_LUP_OPCODE_FORWARD;
+
+	/* IPv6 アドレス、または IPv4 アドレスが指定された時は、照会タイプは PTR に設定する。*/
+	if (((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_IPV6) ||
+		((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_IPV4))
+		flags = (flags & ~DNS_LUP_FLAGS_QTYPE_MASK) | DNS_LUP_FLAGS_QTYPE_PTR;
+
+	if ((error = tget_mpf(MPF_RSLV_SRBUF, (void*)&msg, TMO_FEVR)) != E_OK) {
+		printf("get buffer error: %s.\n", itron_strerror(error));
+		return 0;
+	}
+
+	if ((length = dns_lookup_host(flags | DNS_LUP_FLAGS_MSG, line, msg, DNS_UDP_MSG_LENGTH, &rslv)) < 0) {
+		//printf("error: %s.\n", itron_strerror(length));
+		goto err_ret;
+	}
+
+	dly_tsk(1 * 1000);
+	printf("DNS header: flags: ");
+	if (rslv.dns_hdr.code & (DNS_QR_RESPONSE | DNS_AUTHORITATIVE |
+		DNS_TRUN_CATION | DNS_RECURSION_DESIRED | DNS_RECURSION_AVAILABLE)) {
+		printf((rslv.dns_hdr.code & DNS_QR_RESPONSE) ? "QR," : "");
+		printf((rslv.dns_hdr.code & DNS_AUTHORITATIVE) ? "AA," : "");
+		printf((rslv.dns_hdr.code & DNS_TRUN_CATION) ? "TC," : "");
+		printf((rslv.dns_hdr.code & DNS_RECURSION_DESIRED) ? "RD," : "");
+		printf((rslv.dns_hdr.code & DNS_RECURSION_AVAILABLE) ? "RA," : "");
+		printf(" ");
+	}
+	printf("opcode: ");
+	printf((rslv.dns_hdr.code & DNS_OPCODE_REVERSE) ? "RV" : "FW");
+	printf((rslv.dns_hdr.code & DNS_OPCODE_STATUS) ? ",ST" : "");
+	printf(", rcode: %s.\n",
+		(rslv.dns_hdr.code & DNS_RCODE_MASK) > DNS_RCODE_REFUSED
+		? "6" : rcode_str[rslv.dns_hdr.code & DNS_RCODE_MASK]);
+
+	if ((offset = show_dns_qdsection(msg, length, &rslv)) < 0) {
+		printf("msg error: %s.\n", itron_strerror(offset));
+	}
+	if ((offset = show_dns_section(msg, length, rslv.dns_hdr.ancount, rslv.an_offset, "answer")) < 0) {
+		printf("msg error: %s.\n", itron_strerror(offset));
+	}
+	if ((offset = show_dns_section(msg, length, rslv.dns_hdr.nscount, rslv.ns_offset, "authority")) < 0) {
+		printf("msg error: %s.\n", itron_strerror(offset));
+	}
+	if ((offset = show_dns_section(msg, length, rslv.dns_hdr.arcount, rslv.ar_offset, "additional")) < 0) {
+		printf("msg error: %s.\n", itron_strerror(offset));
+	}
+
+err_ret:
+	if ((error = rel_mpf(MPF_RSLV_SRBUF, msg)) != E_OK)
+		printf("release buffer error: %s.\n", itron_strerror(error));
+	return 0;
+}
+
+int usrcmd_ntpc(int argc, char **argv)
+{
+	ntp_cli_execute();
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/netcmd.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/netcmd.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/netcmd.h	(revision 398)
@@ -0,0 +1,49 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2018 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+#ifndef NETCMD_H
+#define NETCMD_H
+
+int str_ipv4addr(char *text, int size, T_IN4_ADDR *addr, int width);
+int str_ipv6addr(char *text, int size, const T_IN6_ADDR *addr, int width);
+int str_macaddr(char *text, int size, uint8_t *mac, int width);
+
+int usrcmd_ping(int argc, char **argv);
+int usrcmd_dhcp4c(int argc, char **argv);
+int usrcmd_dnsc(int argc, char **argv);
+int usrcmd_ntpc(int argc, char **argv);
+
+#endif /* NETCMD_H */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/ntp_cli.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/ntp_cli.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/ntp_cli.c	(revision 398)
@@ -0,0 +1,564 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2018 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  NTP クライアント
+ */
+
+#include <string.h>
+#include <string.h>
+#include <time.h>
+
+#if defined(TARGET_KERNEL_ASP)
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include <stdio.h>
+
+#endif	/* of #if defined(TARGET_KERNEL_ASP) */
+
+#if defined(TARGET_KERNEL_JSP)
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #if defined(TARGET_KERNEL_JSP) */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include "ntp_cli.h"
+
+/* NTP サーバのポート番号 */
+
+#define NTP_SRV_PORTNO		UINT_C(123)
+
+/* NTP サーバのURL */
+
+#define NTP_SRV_URL		"ntp.nict.jp"
+
+/* 送信間隔 */
+
+#define SLP_ITV		(60*SYSTIM_HZ)
+
+/* 関数 */
+
+void ntp_cli_update_time(T_NTP_CLI_CONTEXT *nc);
+ER ntp_cli_time_synchronization(T_NTP_CLI_CONTEXT *nc, ntp_mode_t mode);
+void ntp_cli_read_time(T_NTP_CLI_CONTEXT *nc, struct timespec *tp);
+void ntp_cli_write_time(T_NTP_CLI_CONTEXT *nc, struct timespec *tp);
+void ntp_cli_read_data(T_NTP_CLI_CONTEXT *nc);
+
+/*
+ *  全域変数
+ */
+
+T_NTP_CLI_CONTEXT ntp_cli;
+
+/* UNIX:1970/1/1 - NTP:1900/1/1 */
+#define TIME_OFS (25567ll * 24 * 60 * 60)
+
+void set_systime_to_ntptime(struct timespec *tp, T_NTP_TIMESTAMP *timestamp)
+{
+	timestamp->integer = htonl((uint32_t)(tp->tv_sec + TIME_OFS));
+	timestamp->fraction = htonl((((unsigned long long)tp->tv_nsec) << 32) / 1000000000ll);
+}
+
+void set_ntptime_to_systime(struct timespec *tp, T_NTP_TIMESTAMP *timestamp)
+{
+	tp->tv_sec = ntohl(timestamp->integer) - TIME_OFS;
+	tp->tv_nsec = ((unsigned long long)(ntohl(timestamp->fraction) * 1000000000ll)) >> 32;
+}
+
+void add_timestamp(T_NTP_TIMESTAMP *dst, T_NTP_TIMESTAMP *a, T_NTP_TIMESTAMP *b)
+{
+	uint32_t ai = ntohl(a->integer);
+	uint32_t af = ntohl(a->fraction);
+	uint32_t bi = ntohl(b->integer);
+	uint32_t bf = ntohl(b->fraction);
+	uint32_t f = af + bf;
+	uint32_t o = ((f < af) || (f < bf)) ? 1u : 0;
+	uint32_t i = ai + bi + o;
+	dst->integer = htonl(i);
+	dst->fraction = htonl(f);
+}
+
+void sub_timestamp(T_NTP_TIMESTAMP *dst, T_NTP_TIMESTAMP *a, T_NTP_TIMESTAMP *b)
+{
+	uint32_t ai = ntohl(a->integer);
+	uint32_t af = ntohl(a->fraction);
+	uint32_t bi = ntohl(b->integer);
+	uint32_t bf = ntohl(b->fraction);
+	uint32_t o = (af < bf) ? 1u : 0u;
+	uint32_t f = af - bf;
+	uint32_t i = ai - bi - o;
+	dst->integer = htonl(i);
+	dst->fraction = htonl(f);
+}
+
+void div2_timestamp(T_NTP_TIMESTAMP *a)
+{
+	uint32_t ai = ntohl(a->integer);
+	uint32_t af = ntohl(a->fraction);
+
+	if ((ai & 1) != 0) {
+		ai >>= 1;
+		af >>= 1;
+		af |= 0x80000000u;
+	}
+	else {
+		ai >>= 1;
+		af >>= 1;
+	}
+
+	a->integer = htonl(ai);
+	a->fraction = htonl(af);
+}
+
+#define NTP_POLL_ASYNC 10		// 1024秒毎に時刻問い合わせ
+#define NTP_POLL_NORMAL 16		// 65536秒毎に時刻問い合わせ
+
+void ntp_cli_initialize(T_NTP_CLI_CONTEXT *nc, ID cepid)
+{
+	nc->cepid = cepid;
+	nc->state = NTP_CLI_STATE_ASYNC;
+	nc->timer = TMO_FEVR;
+	nc->snd_rmt.portno = NTP_SRV_PORTNO;
+	nc->snd_rmt.ipaddr = IPV4_ADDRANY;
+	nc->rcv_rmt.portno = 0;
+	nc->rcv_rmt.ipaddr = IPV4_ADDRANY;
+}
+
+void ntp_cli_execute()
+{
+	ntp_cli.exe_flag = 1;
+	syscall(wup_tsk(ntp_cli.tskid));
+}
+
+void ntp_cli_wakeup(T_NTP_CLI_CONTEXT *nc)
+{
+	int rcv_flag = nc->rcv_flag;
+	nc->rcv_flag = 0;
+
+	if (rcv_flag > 0) {
+		ntp_cli_read_data(nc);
+		return;
+	}
+
+	if (nc->exe_flag != 0) {
+		nc->exe_flag = 0;
+
+		nc->state = NTP_CLI_STATE_ASYNC;
+		nc->timer = 0;
+	}
+}
+
+void ntp_cli_read_data(T_NTP_CLI_CONTEXT *nc)
+{
+	struct timespec tp;
+	T_NTP_MSG *ntp = &nc->ntp_msg;
+
+	// NTP時刻応答の場合
+	if ((ntp->mode == NTP_MODE_SERVER) || (ntp->mode == NTP_MODE_BROADCAST)) {
+		switch (nc->state) {
+		case NTP_CLI_STATE_RESOLVE_ADDR:
+		case NTP_CLI_STATE_ASYNC:
+			break;
+		case NTP_CLI_STATE_REQUEST:
+			// サーバーからの応答時刻を取得
+			memcpy(&nc->receive_timestamp, &ntp->receive_timestamp, sizeof(nc->receive_timestamp));
+			memcpy(&nc->transmit_timestamp, &ntp->transmit_timestamp, sizeof(nc->transmit_timestamp));
+
+			// 現在時刻取得
+			ntp_cli_read_time(nc, &tp);
+
+			// NTP参照時刻に現在時刻を設定
+			set_systime_to_ntptime(&tp, &nc->recv_resp_timestamp);
+
+			// 時刻を更新
+			ntp_cli_update_time(nc);
+
+			nc->state = NTP_CLI_STATE_SYNC;
+			nc->poll = NTP_POLL_NORMAL;
+			nc->timer = (1 << nc->poll) * 1000 * 1000;
+			break;
+		case NTP_CLI_STATE_SYNC:
+			break;
+		}
+	}
+	// NTP時刻要求の場合
+	else if (ntp->mode == NTP_MODE_CLIENT) {
+		// 現在時刻取得
+		ntp_cli_read_time(nc, &tp);
+
+		// NTP受信・送信時刻に現在時刻を設定
+		set_systime_to_ntptime(&tp, &nc->receive_timestamp);
+		set_systime_to_ntptime(&tp, &nc->transmit_timestamp);
+
+		// NTPパケット送信
+		ntp_cli_time_synchronization(nc, NTP_MODE_SERVER);
+	}
+}
+
+void ntp_cli_update_time(T_NTP_CLI_CONTEXT *nc)
+{
+	struct timespec tp;
+	T_NTP_TIMESTAMP dt1, dt2, ofs;
+
+	sub_timestamp(&dt1, &nc->receive_timestamp, &nc->originate_timestamp);
+	sub_timestamp(&dt2, &nc->recv_resp_timestamp, &nc->transmit_timestamp);
+	sub_timestamp(&ofs, &dt1, &dt2);
+	div2_timestamp(&ofs);
+
+	// 差が大きい場合はサーバーの送信時間を設定
+	if (ntohl(ofs.integer) > 2) {
+		memcpy(&nc->reference_timestamp, &nc->transmit_timestamp, sizeof(nc->transmit_timestamp));
+	}
+	else {
+		add_timestamp(&nc->reference_timestamp, &nc->recv_resp_timestamp, &ofs);
+	}
+
+	set_ntptime_to_systime(&tp, &nc->reference_timestamp);
+
+	ntp_cli_write_time(nc, &tp);
+
+	nc->buf[0] = '\0';
+#ifdef __NEED_struct_timespec
+	if (ctime_r(&tp.tv_sec, nc->buf) != NULL)
+#else
+	if (ctime_s(nc->buf, sizeof(nc->buf), &tp.tv_sec) == 0)
+#endif
+	{
+		/* 改行コードの削除 */
+		int len = strnlen(nc->buf, sizeof(nc->buf) - 1);
+		nc->buf[len - 1] = '\0';
+	}
+	else {
+		nc->buf[0] = '\0';
+	}
+
+	syslog(LOG_NOTICE, "[NTP CLI,%d] recv time: %s .%09u",
+		nc->cepid, nc->buf, tp.tv_nsec);
+}
+
+int ntp_cli_get_timer(T_NTP_CLI_CONTEXT *nc)
+{
+	return nc->timer;
+}
+
+void ntp_cli_progress(T_NTP_CLI_CONTEXT *nc, TMO elapse)
+{
+	if (nc->timer <= 0)
+		return;
+
+	nc->timer -= elapse;
+	if (nc->timer < 0)
+		nc->timer = 0;
+}
+
+void ntp_cli_timeout(T_NTP_CLI_CONTEXT *nc)
+{
+	struct timespec tp;
+	char *line;
+
+	if (nc->timer != 0)
+		return;
+
+	switch (nc->state) {
+	case NTP_CLI_STATE_ASYNC:
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+		line = lookup_ipaddr(&nc->ipaddr6, NTP_SRV_URL, API_PROTO_IPV4);
+		if (line == NULL || !in6_is_addr_ipv4mapped(&nc->ipaddr6)) {
+			syslog(LOG_NOTICE, "[NTP CLI,%d] sleep %d.%03u[s], unknown host.",
+				nc->cepid, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			nc->timer = SLP_ITV;
+			break;
+		}
+		nc->snd_rmt.ipaddr = ntohl(nc->ipaddr6.s6_addr32[3]);
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+		if ((line = lookup_ipaddr(&nc->snd_rmt.ipaddr, NTP_SRV_URL, DEFAULT_API_PROTO)) == NULL) {
+			syslog(LOG_NOTICE, "[NTP CLI,%d] sleep %d.%03u[s], unknown host.",
+				nc->cepid, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			nc->timer = SLP_ITV;
+			break;
+		}
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+		nc->state = NTP_CLI_STATE_RESOLVE_ADDR;
+		nc->timer = 1000;
+		/* through */
+	case NTP_CLI_STATE_RESOLVE_ADDR:
+		// 現在時刻取得
+		ntp_cli_read_time(nc, &tp);
+
+		// NTP開始時刻に現在時刻を設定
+		set_systime_to_ntptime(&tp, &nc->originate_timestamp);
+		memset(&nc->receive_timestamp, 0, sizeof(nc->receive_timestamp));
+		memset(&nc->transmit_timestamp, 0, sizeof(nc->transmit_timestamp));
+
+		// NTPパケット送信
+		ntp_cli_time_synchronization(nc, NTP_MODE_CLIENT);
+
+		// NTP応答待ちに遷移、500msでリトライ
+		nc->retry = 0;
+		nc->state = NTP_CLI_STATE_REQUEST;
+		nc->timer = 500 * 1000;
+		break;
+	case NTP_CLI_STATE_REQUEST:
+		nc->retry++;
+		if (nc->retry > 3) {
+			nc->state = NTP_CLI_STATE_ASYNC;
+			nc->poll = NTP_POLL_ASYNC;
+			nc->timer = (1 << nc->poll) * 1000 * 1000;  // 1024秒後に時刻同期
+			break;
+		}
+		// 現在時刻取得
+		ntp_cli_read_time(nc, &tp);
+
+		// NTP開始時刻に現在時刻を設定
+		set_systime_to_ntptime(&tp, &nc->originate_timestamp);
+		memset(&nc->receive_timestamp, 0, sizeof(nc->receive_timestamp));
+		memset(&nc->transmit_timestamp, 0, sizeof(nc->transmit_timestamp));
+
+		// NTPパケット送信
+		ntp_cli_time_synchronization(nc, NTP_MODE_CLIENT);
+
+		// NTP応答待ちに遷移、500msでリトライ
+		nc->state = NTP_CLI_STATE_REQUEST;
+		nc->timer = 500 * 1000;
+		break;
+	case NTP_CLI_STATE_SYNC:
+		// 現在時刻取得
+		ntp_cli_read_time(nc, &tp);
+
+		// NTP開始時刻に現在時刻を設定
+		set_systime_to_ntptime(&tp, &nc->originate_timestamp);
+		memset(&nc->receive_timestamp, 0, sizeof(nc->receive_timestamp));
+		memset(&nc->transmit_timestamp, 0, sizeof(nc->transmit_timestamp));
+
+		// NTPパケット送信
+		ntp_cli_time_synchronization(nc, NTP_MODE_CLIENT);
+
+		// NTP応答待ちに遷移、500msでリトライ
+		nc->state = NTP_CLI_STATE_REQUEST;
+		nc->timer = 500 * 1000;
+		break;
+	}
+}
+
+ER ntp_cli_time_synchronization(T_NTP_CLI_CONTEXT *nc, ntp_mode_t mode)
+{
+	ER_UINT	len = sizeof(nc->ntp_msg);
+	T_NTP_MSG *ntp = &nc->ntp_msg;
+	ER error;
+
+	memset(ntp, 0, len);
+
+	ntp->leap_indicator = 0;
+	ntp->version_number = 4;
+	ntp->mode = mode;
+	ntp->stratum = (mode == NTP_MODE_CLIENT) ? 2 : 1;
+	ntp->poll = nc->poll;
+	ntp->precision = 0xfa;   // 精度は10^-6(1μs)
+	ntp->root_delay = htonl(0);
+	ntp->root_dispersion = htonl(0);
+	// 同期のための外部的な手段のないサブネット
+	ntp->reference_identifier[0] = 'L';
+	ntp->reference_identifier[1] = 'O';
+	ntp->reference_identifier[2] = 'C';
+	ntp->reference_identifier[3] = 'L';
+	// 参照タイムスタンプ
+	memcpy(&ntp->reference_timestamp, &nc->reference_timestamp, sizeof(ntp->reference_timestamp));
+	// 開始タイムスタンプ
+	memcpy(&ntp->originate_timestamp, &nc->originate_timestamp, sizeof(ntp->originate_timestamp));
+	// 受信タイムスタンプ
+	memcpy(&ntp->receive_timestamp, &nc->receive_timestamp, sizeof(ntp->receive_timestamp));
+	// 送信タイムスタンプ
+	memcpy(&ntp->transmit_timestamp, &nc->transmit_timestamp, sizeof(ntp->transmit_timestamp));
+	// 鍵識別子
+	ntp->key_identifier[0] = 0x08;
+	ntp->key_identifier[1] = 0x18;
+	ntp->key_identifier[2] = 0x00;
+	ntp->key_identifier[3] = 0x00;
+
+	if ((error = udp_snd_dat(nc->cepid, &nc->snd_rmt, ntp, len, TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[NTP CLI,%d] udp_snd_dat error: %s",
+			nc->cepid, itron_strerror(error));
+		return error;
+	}
+	else
+		syslog(LOG_DEBUG, "[NTP CLI,%d] udp_snd_dat: to: %s.%d",
+			nc->cepid, ip2str(NULL, &nc->snd_rmt.ipaddr), nc->snd_rmt.portno);
+
+	return E_OK;
+}
+
+void ntp_cli_read_time(T_NTP_CLI_CONTEXT *nc, struct timespec *tp)
+{
+	SYSTIM time;
+	ER ret;
+
+	ret = get_tim(&time);
+	if (ret != E_OK) {
+		syslog(LOG_NOTICE, "[NTP CLI,%d] get_tim error: %s",
+			nc->cepid, itron_strerror(ret));
+		tp->tv_sec = 0;
+		tp->tv_nsec = 0;
+		return;
+	}
+
+	tp->tv_sec = time / 1000000ll;
+	tp->tv_nsec = (time % 1000000ll) * 1000ll;
+}
+
+void ntp_cli_write_time(T_NTP_CLI_CONTEXT *nc, struct timespec *tp)
+{
+	SYSTIM time;
+	ER ret;
+
+	time = (tp->tv_sec * 1000000ll) + (tp->tv_nsec / 1000ll);
+
+	ret = set_tim(time);
+	if (ret != E_OK) {
+		syslog(LOG_NOTICE, "[NTP CLI,%d] set_tim error: %s",
+			nc->cepid, itron_strerror(ret));
+	}
+}
+
+/*
+ *  ノンブロッキングコールのコールバック関数
+ */
+
+ER
+callback_nblk_ntp_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	T_NTP_CLI_CONTEXT *nc = &ntp_cli;
+	ER_UINT len;
+
+	len = *(ER_UINT*)p_parblk;
+	if (len < 0 && len != E_RLWAI) {
+		/* E_RLWAI 以外で、0 以下の場合は、エラーを意味している。*/
+		syslog(LOG_NOTICE, "[NTP CLI,%d] callback error: %s, fncd: %s", nc->cepid,
+			itron_strerror(len), in_strtfn(fncd));
+	}
+	else {
+		if (fncd == TEV_UDP_RCV_DAT) {
+			if ((len = udp_rcv_dat(nc->cepid, &nc->rcv_rmt, &nc->ntp_msg, len, TMO_POL)) < 0)
+			{
+				syslog(LOG_NOTICE, "[NTP CLI,%d] udp_rcv_dat error: %s", nc->cepid,
+					itron_strerror(len));
+			}
+			else
+				syslog(LOG_DEBUG, "[NTP CLI,%d] udp_rcv_dat len: %d", nc->cepid, len);
+
+			if (len >= sizeof(nc->ntp_msg))
+				nc->rcv_flag = len;
+			else
+				nc->rcv_flag = 0;
+		}
+		syscall(wup_tsk(nc->tskid));
+	}
+
+	return E_OK;
+}
+
+#ifdef NTP_CLI_TASK
+
+/*
+ *  NTP クライアント送信タスク
+ */
+
+void
+ntp_cli_task (intptr_t exinf)
+{
+	T_NTP_CLI_CONTEXT *nc = &ntp_cli;
+	ER		error, ret;
+	SYSTIM		prev, time;
+	int timer;
+
+	get_tid(&nc->tskid);
+	syslog(LOG_NOTICE, "[NTP CLI:%d,%d] started.", nc->tskid, (ID)exinf);
+
+	/* 初期化 */
+	ntp_cli_initialize(nc, (ID)exinf);
+
+	ret = get_tim(&time);
+	if (ret != E_OK) {
+		syslog(LOG_NOTICE, "[NTP CLI,%d] get_tim error: %7lu,%s",
+			nc->cepid, time / SYSTIM_HZ, itron_strerror(ret));
+		return;
+	}
+
+	while (true) {
+		prev = time;
+
+		/* タイマー取得 */
+		timer = ntp_cli_get_timer(nc);
+
+		/* 待ち */
+		error = tslp_tsk(timer);
+		if ((error != E_OK) && (error != E_TMOUT)) {
+			syslog(LOG_NOTICE, "[NTP CLI,%d] tslp_tsk error: %s %d",
+				nc->cepid, itron_strerror(error), timer);
+			break;
+		}
+
+		ret = get_tim(&time);
+		if (ret != E_OK) {
+			syslog(LOG_NOTICE, "[NTP CLI,%d] get_tim error: %s",
+				nc->cepid, itron_strerror(ret));
+			break;
+		}
+
+		/* 時間経過 */
+		ntp_cli_progress(nc, time - prev);
+
+		/* 起こされた場合 */
+		if (error == E_OK) {
+			ntp_cli_wakeup(nc);
+		}
+
+		/* タイムアウト処理 */
+		ntp_cli_timeout(nc);
+	}
+}
+
+#endif
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/ntp_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/ntp_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/ntp_cli.cfg	(revision 398)
@@ -0,0 +1,51 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2018 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  NTP クライアントのシステムコンフィギュレーションファイル
+ */
+
+/* タスク */
+
+CRE_TSK(NTP_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	NTP_CLI_CEPID,
+	ntp_cli_task,
+	NTP_CLI_MAIN_PRIORITY,
+	NTP_CLI_STACK_SIZE,
+	NULL
+	});
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/ntp_cli.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/ntp_cli.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/ntp_cli.h	(revision 398)
@@ -0,0 +1,132 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2018 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _NTP_CLI_H_
+#define _NTP_CLI_H_
+
+/* スタックサイズ */
+
+#define NTP_CLI_STACK_SIZE	1024		/* NTP クライアントタスク（IPv4）のスタックサイズ	*/
+
+/* 優先度 */
+
+#define NTP_CLI_MAIN_PRIORITY	5		/* NTP クライアントタスク（IPv4）の優先度		*/
+
+/* タスク */
+
+extern void	ntp_cli_task(intptr_t exinf);
+
+/* NTPタイムスタンプ */
+typedef struct ntp_timestamp {
+	uint32_t integer;
+	uint32_t fraction;
+} __attribute__((packed)) T_NTP_TIMESTAMP;
+
+/* NTPパケット */
+typedef struct ntp_msg {
+	uint8_t mode : 3;
+	uint8_t version_number : 3;
+	uint8_t leap_indicator : 2;
+	uint8_t stratum;
+	uint8_t poll;
+	uint8_t precision;
+	uint32_t root_delay;
+	uint32_t root_dispersion;
+	uint8_t reference_identifier[4];
+	T_NTP_TIMESTAMP reference_timestamp;
+	T_NTP_TIMESTAMP originate_timestamp;
+	T_NTP_TIMESTAMP receive_timestamp;
+	T_NTP_TIMESTAMP transmit_timestamp;
+	uint8_t key_identifier[4];
+	uint8_t message_digest[16];
+} __attribute__((packed)) T_NTP_MSG;
+
+typedef enum ntp_mode {
+	NTP_MODE_RESERVED,
+	NTP_MODE_SYMMETRIC_ACTIVE,
+	NTP_MODE_SYMMETRIC_PASSIVE,
+	NTP_MODE_CLIENT,
+	NTP_MODE_SERVER,
+	NTP_MODE_BROADCAST,
+	NTP_MODE_NTP_CONTROL_MESSAGE,
+	NTP_MODE_RESERVED_FOR_PRIVATE_USER
+} ntp_mode_t;
+
+/* NTPクライアント状態 */
+typedef enum ntp_cli_state {
+	NTP_CLI_STATE_ASYNC,
+	NTP_CLI_STATE_RESOLVE_ADDR,
+	NTP_CLI_STATE_REQUEST,
+	NTP_CLI_STATE_SYNC,
+} ntp_cli_state_t;
+
+typedef struct ntp_cli {
+	ntp_cli_state_t state;
+	int timer;
+	int retry;
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+	T_IN6_ADDR	ipaddr6;
+#endif
+	uint16_t portno;
+	ID tskid;
+	ID cepid;
+	T_NTP_MSG ntp_msg;
+	T_IPV4EP snd_rmt;
+	T_IPV4EP rcv_rmt;
+	uint8_t poll;
+	T_NTP_TIMESTAMP reference_timestamp;
+	T_NTP_TIMESTAMP originate_timestamp;
+	T_NTP_TIMESTAMP receive_timestamp;
+	T_NTP_TIMESTAMP transmit_timestamp;
+	T_NTP_TIMESTAMP recv_resp_timestamp;
+	char buf[30];
+	int rcv_flag;
+	int exe_flag;
+} T_NTP_CLI_CONTEXT;
+
+/* 関数 */
+
+void ntp_cli_initialize(T_NTP_CLI_CONTEXT *nc, ID cepid);
+int ntp_cli_get_timer(T_NTP_CLI_CONTEXT *nc);
+void ntp_cli_progress(T_NTP_CLI_CONTEXT *nc, TMO elapse);
+void ntp_cli_wakeup(T_NTP_CLI_CONTEXT *nc);
+void ntp_cli_timeout(T_NTP_CLI_CONTEXT *nc);
+ER callback_nblk_ntp_cli(ID cepid, FN fncd, void *p_parblk);
+
+void ntp_cli_execute();
+
+#endif	/* of #ifndef _NTP_CLI_H_ */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell.cdl	(revision 398)
@@ -0,0 +1,79 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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$
+ */
+
+import_C("target_syssvc.h");
+
+/*
+ *  タスクのスタックサイズのデフォルト
+ */
+const size_t DefaultTaskStackSize = 1024;		/* スタックサイズ（1KB）*/
+
+/*
+ *  システムログタスクのスタックサイズの定義
+ */
+const size_t LogTaskStackSize = DefaultTaskStackSize;
+
+/*
+ *  カーネル起動メッセージに関する定義
+ */
+const char *const BannerTargetName = C_EXP("TARGET_NAME");		/* ターゲット名 */
+const char *const BannerCopyrightNotice = "";			/* 著作権表示 */
+
+/*
+ *  ターゲット依存のセルタイプの定義
+ */
+import("syssvc/tPutLogSIOPort.cdl");
+import("tSIOPortNTShell.cdl");
+
+/*
+ *  シリアルインタフェースドライバのターゲット依存部の組み上げ記述
+ */
+cell tSIOPortNTShell SIOPortTarget1 {
+};
+
+/*
+ *  低レベル出力の組み上げ記述
+ */
+cell tPutLogSIOPort PutLogTarget {
+	/* SIOドライバとの結合 */
+	cSIOPort = SIOPortTarget1.eSIOPort;
+};
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell_main.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell_main.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell_main.c	(revision 398)
@@ -0,0 +1,417 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2014-2017 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  サンプルプログラム(1)の本体
+ */
+
+#include "shellif.h"
+#include <kernel.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include <setjmp.h>
+#include <string.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "target_syssvc.h"
+#include "target_serial.h"
+#include "kernel_cfg.h"
+#include "ffarch.h"
+#include "ff.h"
+#include "core/ntshell.h"
+#include "core/ntlibc.h"
+#include "util/ntstdio.h"
+#include "usrcmd.h"
+#include "util/ntopt.h"
+#include "ntshell_main.h"
+#include "fdtable.h"
+
+char command[NTOPT_TEXT_MAXLEN];
+
+extern uint8_t mac_addr[6];
+const struct utsname host_name = {
+	"TOPPERS/ASP3",
+	TARGET_NAME,
+	"3.2.0",
+	"3.2.0",
+	TARGET_NAME,
+	"toppers.jp"
+};
+
+int shell_uname(struct utsname *uts)
+{
+	memcpy(uts, &host_name, sizeof(host_name));
+	return 0;
+}
+
+void stdio_open(ID portid);
+static int usrcmd_ntopt_callback(long *args, void *extobj);
+
+int ntshell_exit_code;
+volatile int ntshell_state;
+jmp_buf process_exit;
+
+void ntshell_task_init(ID portid)
+{
+	stdio_open(portid);
+}
+
+/*
+ *  ntshellタスク
+ */
+void ntshell_task(intptr_t exinf)
+{
+	ntshell_state = 1;
+
+	if (setjmp(process_exit) == 0) {
+		ntshell_exit_code = ntopt_parse(command, usrcmd_ntopt_callback, NULL);
+	}
+
+	fflush(stdout);
+	clean_fd();
+
+	ntshell_state = 2;
+}
+
+void ntshell_change_netif_link(uint8_t link_up, uint8_t up)
+{
+	FLGPTN flgptn;
+	T_RTSK rtsk;
+	ER ret;
+
+	ret = ref_tsk(NTSHELL_TASK, &rtsk);
+	if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
+		return;
+
+	FD_SET(0, (fd_set *)&flgptn);
+
+	set_flg(FLG_SELECT_WAIT, flgptn);
+}
+
+static int usrcmd_ntopt_callback(long *args, void *extobj)
+{
+	const cmd_table_t *p = cmd_table_info.table;
+	int result = 0;
+	int found = 0;
+
+	if (*args == 0)
+		return result;
+
+	if (strcmp((const char *)args[1], "help") == 0) {
+		found = 1;
+		result = usrcmd_help(args[0], (char **)&args[1]);
+	}
+	else for (int i = 0; i < cmd_table_info.count; i++) {
+		if (strcmp((const char *)args[1], p->cmd) == 0) {
+			found = 1;
+			result = p->func(args[0], (char **)&args[1]);
+			break;
+		}
+		p++;
+	}
+
+	if ((found == 0) && (((const char *)args[1])[0] != '\0'))
+		printf("Unknown command found.\n");
+
+	return result;
+}
+
+int usrcmd_help(int argc, char **argv)
+{
+	const cmd_table_t *p = cmd_table_info.table;
+	for (int i = 0; i < cmd_table_info.count; i++) {
+		fwrite(p->cmd, strlen(p->cmd), 1, stdout);
+		fwrite("\t:", strlen("\t:"), 1, stdout);
+		puts(p->desc);
+		p++;
+	}
+	return 0;
+}
+
+void shell_abort()
+{
+	ntshell_exit_code = -1;
+	longjmp(process_exit, 1);
+}
+
+void shell_exit(int exitcd)
+{
+	ntshell_exit_code = exitcd;
+	longjmp(process_exit, 1);
+}
+
+void shell_exit_group(int exitcd)
+{
+	ntshell_exit_code = exitcd;
+	longjmp(process_exit, 1);
+}
+
+int execute_command(int wait)
+{
+	T_RTSK rtsk;
+	ER ret;
+
+	ret = ter_tsk(NTSHELL_TASK);
+	if ((ret != E_OK) && (ret != E_OBJ)) {
+		syslog(LOG_ERROR, "ter_tsk => %d", ret);
+	}
+
+	tslp_tsk(100000);
+
+	clean_fd();
+
+	ntshell_state = 0;
+	ret = act_tsk(NTSHELL_TASK);
+	if (ret != E_OK) {
+		syslog(LOG_ERROR, "act_tsk => %d", ret);
+	}
+
+	if (wait == 0)
+		return 0;
+
+	do {
+		tslp_tsk(100000);
+
+		ret = ref_tsk(NTSHELL_TASK, &rtsk);
+		if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
+			ntshell_state = 3;
+	} while(ntshell_state == 1);
+
+	return ntshell_exit_code;
+}
+
+int cmd_execute(const char *text, void *extobj)
+{
+	ntlibc_strlcpy(command, text, sizeof(command));
+	return execute_command(1);
+}
+
+int shell_clock_getres(clockid_t clk_id, struct timespec *res)
+{
+	if ((clk_id != CLOCK_REALTIME) && (clk_id != CLOCK_MONOTONIC))
+		return -EINVAL;
+
+	memset(&res->tv_sec, 0xFF, sizeof(res->tv_sec));
+	res->tv_nsec = 0;
+
+	return 0;
+}
+
+int shell_clock_gettime(clockid_t clk_id, struct timespec *tp)
+{
+	SYSTIM now = 0;
+
+	if ((clk_id != CLOCK_REALTIME) && (clk_id != CLOCK_MONOTONIC))
+		return -EINVAL;
+
+	get_tim(&now);
+	tp->tv_sec = now / 1000000;
+	tp->tv_nsec = (now % 1000000) * 1000;
+
+	return 0;
+}
+
+int shell_clock_settime(clockid_t clk_id, const struct timespec *tp)
+{
+	if ((clk_id != CLOCK_REALTIME) && (clk_id != CLOCK_MONOTONIC))
+		return -EINVAL;
+
+	SYSTIM time;
+	ER ret;
+
+	time = (tp->tv_sec * 1000000ll) + (tp->tv_nsec / 1000ll);
+
+	ret = set_tim(time);
+	if (ret != E_OK) {
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+sigset_t g_sigmask;
+
+int shell_sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
+{
+	if (old != NULL)
+		memcpy(old, &g_sigmask, sizeof(sigset_t));
+
+	switch (how) {
+	case SIG_BLOCK:
+		for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
+			g_sigmask.__bits[i] |= set->__bits[i];
+		}
+		break;
+	case SIG_UNBLOCK:
+		for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
+			g_sigmask.__bits[i] &= ~set->__bits[i];
+		}
+		break;
+	case SIG_SETMASK:
+		memcpy(&g_sigmask, set, sizeof(sigset_t));
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+// musl-1.1.18\src\internal\ksigaction.h
+struct k_sigaction {
+	void(*handler)(int);
+	unsigned long flags;
+	void(*restorer)(void);
+	unsigned mask[2];
+};
+
+struct k_sigaction sigtable[7];
+
+int shell_sigaction(int sig, const struct k_sigaction *__restrict sa,
+	struct k_sigaction *__restrict old, size_t size)
+{
+	struct k_sigaction *sat;
+
+	switch(sig){
+	case SIGALRM:
+		sat = &sigtable[0];
+		break;
+	case SIGFPE:
+		sat = &sigtable[1];
+		break;
+	case SIGILL:
+		sat = &sigtable[2];
+		break;
+	case SIGSEGV:
+		sat = &sigtable[3];
+		break;
+	case SIGBUS:
+		sat = &sigtable[4];
+		break;
+	case SIGABRT:
+		sat = &sigtable[5];
+		break;
+	case SIGPIPE:
+		sat = &sigtable[6];
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (old != NULL)
+		memcpy(old, sat, offsetof(struct k_sigaction, mask) + size);
+
+	memcpy(sat, sa, offsetof(struct k_sigaction, mask) + size);
+
+	return 0;
+}
+
+int shell_madvise(void *a, size_t b, int c)
+{
+	return 0;
+}
+
+int shell_gettid()
+{
+	ID tskid;
+	ER ret;
+
+	ret = get_tid(&tskid);
+	if (ret != E_OK)
+		return -1;
+
+	return tskid;
+}
+
+int shell_tkill(int tid, int sig)
+{
+	if ((tid == NTSHELL_TASK) && (sig == SIGABRT)) {
+		shell_abort();
+	}
+
+	no_implement("tkill");
+	return -1;
+}
+
+int shell_kill(int pid, int sig)
+{
+	DebugBreak();
+	return -1;
+}
+
+int shell_gettimeofday(struct timeval *tv, void *tzvp)
+{
+	SYSTIM time;
+	if (!tv) return 0;
+	get_tim(&time);
+	tv->tv_sec = time / 1000000;
+	tv->tv_usec = time - (tv->tv_sec * 1000000);
+	return 0;
+}
+
+int shell_nanosleep(const struct timespec *req, struct timespec *rem)
+{
+	ER ret;
+	TMO tmo;
+	SYSTIM prev, now, diff;
+
+	if ((req == NULL) || (req->tv_nsec < 0) || (req->tv_nsec >= 1000000000))
+		return -EINVAL;
+
+	get_tim(&prev);
+
+	tmo = req->tv_sec * 1000000 + req->tv_nsec / 1000;
+	ret = tslp_tsk(tmo);
+	if (ret == E_OK) {
+		if (rem != NULL) {
+			get_tim(&now);
+			diff = now - prev;
+			rem->tv_sec = diff / 1000000ll;
+			rem->tv_nsec = (diff - (rem->tv_sec * 1000000ll)) * 1000ll;
+		}
+		return 0;
+	}
+	else if (ret == E_TMOUT) {
+		if (rem != NULL) {
+			rem->tv_sec = 0;
+			rem->tv_nsec = 0;
+		}
+		return 0;
+	}
+
+	return -EFAULT;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell_main.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell_main.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell_main.cfg	(revision 398)
@@ -0,0 +1,47 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2014-2016 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ntshellのシステムコンフィギュレーションファイル
+ */
+#include "ntshell_main.h"
+
+ATT_INI({ TA_NULL, 0, sys_init });
+
+CRE_TSK(NTSHELL_TASK, { TA_NULL, 0, ntshell_task, NTSHELL_PRIORITY, NTSHELL_STACK_SIZE, NULL });
+CRE_FLG(FLG_SELECT_WAIT, { TA_WMUL, 0x00 });
+CRE_SEM(SEM_FILEDESC, { TA_TPRI, 1, 1 });
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell_main.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell_main.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/ntshell_main.h	(revision 398)
@@ -0,0 +1,100 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2014-2017 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _NTSHELL_MAIN_H_
+#define _NTSHELL_MAIN_H_
+
+/*
+ *		ntshellタスクのヘッダファイル
+ */
+
+/*
+ *  ターゲット依存の定義
+ */
+#include <kernel.h>
+
+#include "usrcmd.h"
+#include "core/ntshell.h"
+
+/*
+ *  各タスクの優先度の定義
+ */
+
+#define NTSHELL_PRIORITY	8		/* ntshellタスクの優先度 */
+
+#define NTSHELL_STACK_SIZE	10240	/* ntshellタスクのスタック領域のサイズ */
+
+#define NUM_NTSHELL_DATAQUEUE	1	/* ntshellタスクで待ち受けているデータキューのサイズ */
+
+/*
+ *  関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef struct
+{
+	const cmd_table_t *table;
+	int count;
+} cmd_table_info_t;
+
+extern cmd_table_info_t cmd_table_info;
+
+extern PRI main_task_priority;
+
+/* ntshellの初期化 */
+void sys_init(intptr_t exinf);
+
+/* ntshellタスク初期化 */
+void ntshell_task_init(ID portid);
+
+/* ntshellタスク */
+void ntshell_task(intptr_t exinf);
+
+/* 開始 */
+void ntshell_change_netif_link(uint8_t link_up, uint8_t up);
+
+/* コマンド実行 */
+int cmd_execute(const char *text, void *extobj);
+
+/* 
+ * ノンブロッキングコールのコールバック関数
+ */
+extern ER socket_udp_callback(ID cepid, FN fncd, void *p_parblk);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif	/* of #ifndef _NTSHELL_MAIN_H_ */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/route_cfg.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/route_cfg.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/route_cfg.c	(revision 398)
@@ -0,0 +1,96 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  ルーティング表
+ */
+
+#include <kernel.h>
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+/* IPv6 に関する定義 */
+
+#ifdef _IP6_CFG
+
+#if NUM_IN6_ROUTE_ENTRY > 0
+
+T_IN6_RTENTRY routing6_tbl[NUM_IN6_ROUTE_ENTRY];
+
+#endif	/* of #if NUM_IN6_ROUTE_ENTRY > 0 */
+
+#endif	/* of #ifdef _IP6_CFG */
+
+/* IPv4 に関する定義 */
+
+#ifdef _IP4_CFG
+
+#ifdef SUPPORT_LOOP
+
+T_IN4_RTENTRY routing4_tbl[NUM_IN4_ROUTE_ENTRY] = {
+	{ 0, 0, 0 },
+	};
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+#ifdef SUPPORT_PPP
+
+T_IN4_RTENTRY routing4_tbl[NUM_IN4_ROUTE_ENTRY] = {
+	{ 0, 0, 0 },
+	};
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_ETHER
+
+T_IN4_RTENTRY routing4_tbl[NUM_IN4_ROUTE_ENTRY] = {
+
+	/* 異なる LAN、default gateway による間接配送	*/
+	{ 0,			0,			IPV4_ADDR_DEFAULT_GW	},
+
+	/* 同一 LAN 内、直接配送				*/
+	{ IPV4_ADDR_LOCAL &
+	  IPV4_ADDR_LOCAL_MASK,	IPV4_ADDR_LOCAL_MASK,	0			},
+
+	/* 同一 LAN 内へのブロードキャスト、直接配送	*/
+	{ 0xffffffff,		0xffffffff,		0			},
+
+	};
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+#endif	/* of #ifdef _IP4_CFG */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/shellif.h
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/shellif.h	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/shellif.h	(revision 398)
@@ -0,0 +1,314 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2017 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+#ifndef SHELLIF_H
+#define SHELLIF_H
+
+#ifdef _MSC_VER
+#undef NULL
+#endif
+
+#define __NEED_off_t
+#define __NEED_ssize_t
+#define __NEED_size_t
+#define __NEED_mode_t
+#define __NEED_dev_t
+#define __NEED_pid_t
+#define __NEED_gid_t
+#define __NEED_uid_t
+#define __NEED_socklen_t
+#define __NEED_nlink_t
+#define __NEED_blksize_t
+#define __NEED_blkcnt_t
+#define __NEED_ino_t
+#define __NEED_time_t
+#define __NEED_suseconds_t
+#define __NEED_struct_timeval
+#define __NEED_struct_timespec
+#define __NEED_struct_iovec
+#define __NEED_clockid_t
+#define __NEED_socklen_t
+#define __NEED_sa_family_t
+#define __NEED_sigset_t
+
+#ifndef _MSC_VER
+#include <bits/alltypes.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 32
+
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <time.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/utsname.h>
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#else
+#include "../musl-1.1.18/include/bits/alltypes.h"
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 32
+
+#include "../musl-1.1.18/include/bits/fcntl.h"
+#include "../musl-1.1.18/include/bits/termios.h"
+#include "../musl-1.1.18/include/bits/stat.h"
+#include "../musl-1.1.18/include/sys/select.h"
+#include "../musl-1.1.18/include/time.h"
+#include "../musl-1.1.18/include/signal.h"
+#include "../musl-1.1.18/include/stdio.h"
+#include "../musl-1.1.18/include/sys/utsname.h"
+#include "../musl-1.1.18/include/dirent.h"
+#include "../musl-1.1.18/include/bits/ioctl.h"
+#include "../musl-1.1.18/include/fcntl.h"
+#include "../musl-1.1.18/include/bits/errno.h"
+#include "../musl-1.1.18/include/sys/socket.h"
+#endif
+
+#include <stddef.h>
+#include <stdarg.h>
+
+#if !defined(_MSC_VER) && !defined(__c2__)
+//#define DebugBreak()	asm("brk")
+#define DebugBreak()	while (true)
+#else
+#ifdef _MSC_VER
+void _stdcall DebugBreak();
+#else
+void __attribute__((stdcall)) DebugBreak();
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// time.h
+#define CLOCK_REALTIME 0
+int shell_nanosleep(const struct timespec *req, struct timespec *rem);
+
+// dirent.h
+typedef struct __dirstream FATFS_DIR;
+
+int shell_getdents(int, struct dirent *, size_t);
+// pool.h
+typedef unsigned long nfds_t;
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+int shell_poll(struct pollfd *, nfds_t, int);
+
+#define POLLIN     0x001
+#define POLLOUT    0x004
+#define POLLERR    0x008
+
+// stropts.h
+int shell_ioctl(int, int, void *);
+// unistd.h
+#define STDIN_FILENO  0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+int shell_rmdir(const char *);
+int shell_ftruncate(int, off_t);
+int shell_chdir(const char *);
+char *shell_getcwd(char *, size_t);
+int shell_chroot(const char *);
+int shell_close(int);
+int shell_llseek(int, off_t, off_t *, int);
+int shell_fsync(int);
+ssize_t shell_read(int, void *, size_t);
+int shell_readv(int fd, const struct iovec *iov, int iovcnt);
+ssize_t shell_write(int, const void *, size_t);
+int shell_writev(int fd, const struct iovec *iov, int iovcnt);
+int shell_link(const char *, const char *);
+int shell_unlink(const char *);
+pid_t shell_getpid(void);
+int shell_access(const char *path, int mode);
+// signal.h
+int shell_sigprocmask(int how, const sigset_t *__restrict set, sigset_t *__restrict old);
+struct k_sigaction;
+int shell_sigaction(int sig, const struct k_sigaction *__restrict sa,
+	struct k_sigaction *__restrict old, size_t size);
+// socket.h
+int shell_socket(int, int, int);
+int shell_connect(int, const struct sockaddr *, socklen_t);
+ssize_t shell_sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t);
+ssize_t shell_sendmsg(int, const struct msghdr *, int);
+int shell_bind(int, const struct sockaddr *, socklen_t);
+int shell_listen(int, int);
+int shell_accept(int, struct sockaddr *__restrict, socklen_t *__restrict);
+ssize_t shell_recvfrom(int, void *__restrict, size_t, int, struct sockaddr *__restrict, socklen_t *__restrict);
+ssize_t shell_recvmsg(int, struct msghdr *, int);
+int shell_getsockopt(int, int, int, void *__restrict, socklen_t *__restrict);
+int shell_setsockopt(int, int, int, const void *, socklen_t);
+int shell_shutdown(int, int);
+int shell_getpeername(int fd, struct sockaddr *__restrict addr, socklen_t *__restrict len);
+int shell_getsockname(int fd, struct sockaddr *__restrict addr, socklen_t *__restrict len);
+// select.h
+int shell_select(int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, struct timeval *__restrict);
+// syslog.h
+void vsyslog (int, const char *, va_list);
+// fcntl.h
+int shell_open(const char *, int, void *arg);
+int shell_fcntl(int fd, int cmd, void *arg);
+// stdio.h
+int shell_rename(const char *, const char *);
+// stat.h
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFREG 0100000
+
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IROTH 0004
+#define S_IWOTH 0002
+
+int shell_chmod(const char *, mode_t);
+int shell_mkdir(const char *, mode_t);
+int shell_stat(const char *__restrict, struct stat *__restrict);
+int shell_fstat(int, struct stat *);
+int shell_lstat(const char *__restrict, struct stat *__restrict);
+
+int shell_clock_getres(clockid_t clk_id, struct timespec *res);
+int shell_clock_gettime(clockid_t clk_id, struct timespec *tp);
+int shell_clock_settime(clockid_t clk_id, const struct timespec *tp);
+int shell_gettimeofday(struct timeval *tp, void * tzvp);
+
+void shell_abort();
+void shell_exit(int exitcd);
+void shell_exit_group(int exitcd);
+int shell_kill(int pid, int sig);
+
+void *shell_brk(void *addr);
+void *shell_mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset);
+// sys/mman.h
+int shell_mprotect(void *addr, size_t len, int prot);
+// TODO
+int shell_clone(int, int);
+int shell_dup2(int, int);
+int shell_execve(const char *, char *const [], char *const []);
+int shell_faccessat(int, const char *, int, int);
+int shell_fchmodat(int, const char *, mode_t, int);
+int shell_flock(int, int);
+int shell_fork();
+int shell_futex(volatile int *, int, int, void *);
+int shell_futimesat(int, const char *, struct timeval *);
+int shell_getegid();
+int shell_geteuid();
+int shell_getgid();
+int shell_gettid();
+int shell_getuid();
+int shell_madvise(void *, size_t, int);
+int shell_mremap(void *, size_t, size_t, int, void *);
+int shell_munmap(void *, size_t);
+int shell_pipe(int [2]);
+int shell_pipe2(int [2], int);
+int shell_ppoll(struct pollfd *, nfds_t, const struct timespec *,const sigset_t *);
+int shell_pselect6(int, fd_set *__restrict, fd_set *__restrict,
+	fd_set *__restrict, const struct timespec *__restrict, const sigset_t *__restrict);
+int shell_setpgid(pid_t, pid_t);
+int shell_setsid();
+int shell_symlink(const char *, const char *);
+int shell_tkill(int, int);
+int shell_umask(mode_t);
+int shell_uname(struct utsname *);
+int shell_utimensat(int, const char *, const struct timespec [2], int);
+int shell_utimes(const char *, struct timeval *);
+// sys/resource.h
+struct rusage;
+int shell_wait4(pid_t, int *, int, struct rusage *);
+// ↑↑↑musl
+
+// arduino.h
+int SD_begin();
+
+char *basename(char *);
+
+struct regs_t {
+	long a;
+	long b;
+	long c;
+	long d;
+	long e;
+	long f;
+	long n;
+};
+
+long no_implement(const char *text);
+void __mbedcall_cp_asm();
+
+#include "ff.h"
+WCHAR Utf8_to_Utf16(const char *, int *); /* in ff.c */
+void Utf16_to_Utf8(unsigned char *, int *, UINT); /* in ff.c */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int Kernel_StartExternal(int argc, char **argv);
+#ifdef __cplusplus
+}
+#endif
+
+void *malloc(size_t size);
+void *calloc(size_t size, size_t count);
+void *realloc(void *ptr, size_t size);
+void free(void *ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SHELLIF_H */
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/socket_stub.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/socket_stub.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/socket_stub.c	(revision 398)
@@ -0,0 +1,2211 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2017 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+#include "shellif.h"
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <string.h>
+#include <sil.h>
+#include "syssvc/syslog.h"
+#include <tinet_defs.h>
+#include <tinet_config.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+#include <tinet_nic_defs.h>
+#include <tinet_cfg.h>
+#include <netinet/in_var.h>
+#include <net/ethernet.h>
+#include <net/if6_var.h>
+#include <net/net.h>
+#include <net/if_var.h>
+#include <netinet/udp_var.h>
+#include <net/net_buf.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netapp/resolver.h>
+#include "fdtable.h"
+#include "kernel_cfg.h"
+
+#ifdef _DEBUG
+static const char THIS_FILE[] = __FILE__;
+#endif
+
+#define SOCKET_TIMEOUT 2000000
+#define TCP_SOCKET_BUF_SIZE 512
+
+struct addrinfo {
+	int ai_flags;
+	int ai_family;
+	int ai_socktype;
+	int ai_protocol;
+	socklen_t ai_addrlen;
+	struct sockaddr *ai_addr;
+	char *ai_canonname;
+	struct addrinfo *ai_next;
+};
+
+typedef uint16_t in_port_t;
+typedef uint32_t in_addr_t;
+struct in_addr { in_addr_t s_addr; };
+
+struct sockaddr_in {
+	sa_family_t sin_family;
+	in_port_t sin_port;
+	struct in_addr sin_addr;
+	uint8_t sin_zero[8];
+};
+
+struct in6_addr
+{
+	union {
+		uint8_t __s6_addr[16];
+		uint16_t __s6_addr16[8];
+		uint32_t __s6_addr32[4];
+	} __in6_union;
+};
+//#define s6_addr __in6_union.__s6_addr
+//#define s6_addr16 __in6_union.__s6_addr16
+//#define s6_addr32 __in6_union.__s6_addr32
+
+struct sockaddr_in6
+{
+	sa_family_t     sin6_family;
+	in_port_t       sin6_port;
+	uint32_t        sin6_flowinfo;
+	struct in6_addr sin6_addr;
+	uint32_t        sin6_scope_id;
+};
+
+typedef struct socket_t {
+	int family;
+	int type;
+	int protocol;
+	int cepid;
+	int repid;
+	int backlog;
+	unsigned int flags;
+	union {
+		struct sockaddr_in laddr4;
+		struct sockaddr_in6 laddr6;
+	};
+	union {
+		struct sockaddr_in raddr4;
+		struct sockaddr_in6 raddr6;
+	};
+	int buf_size;
+	unsigned char *buf;
+	void *input;
+	int len;
+} socket_t;
+
+#define tcp6_cre_cep tcp_cre_cep
+#define tcp6_del_cep tcp_del_cep
+#define tcp6_del_rep tcp_del_rep
+#define tcp6_sht_cep tcp_sht_cep
+#define tcp6_cls_cep tcp_cls_cep
+#define tcp6_snd_oob tcp_snd_oob
+#define tcp6_snd_dat tcp_snd_dat
+#define tcp6_rcv_oob tcp_rcv_oob
+#define tcp6_rcv_buf tcp_rcv_buf
+#define tcp6_rel_buf tcp_rel_buf
+#define tcp6_get_opt tcp_get_opt
+#define tcp6_set_opt tcp_set_opt
+
+#ifndef SUPPORT_INET6
+
+ER	tcp6_cre_rep (ID repid, T_TCP6_CREP *pk_crep) { return E_SYS; }
+ER	tcp6_acp_cep (ID cepid, ID repid, T_IPV6EP *p_dstaddr, TMO tmout) { return E_SYS; }
+ER	tcp6_con_cep (ID cepid, T_IPV6EP *p_myaddr, T_IPV6EP *p_dstaddr, TMO tmout) { return E_SYS; }
+
+ER	udp6_cre_cep (ID cepid, T_UDP6_CCEP *pk_ccep) { return E_SYS; }
+ER	udp6_del_cep (ID cepid) { return E_SYS; }
+ER_UINT	udp6_snd_dat (ID cepid, T_IPV6EP *p_dstaddr, void *data, int_t len, TMO tmout) { return E_SYS; }
+ER_UINT	udp6_rcv_dat (ID cepid, T_IPV6EP *p_dstaddr, void *data, int_t len, TMO tmout) { return E_SYS; }
+ER	udp6_set_opt (ID cepid, int_t optname, void *optval, int_t optlen) { return E_SYS; }
+ER	udp6_get_opt (ID cepid, int_t optname, void *optval, int_t optlen) { return E_SYS; }
+
+const T_IN6_ADDR *in6_get_ifaddr (int_t index) { return NULL; }
+
+#endif
+
+ER socket_tcp_callback(ID cepid, FN fncd, void *p_parblk);
+ER socket_tcp6_callback(ID cepid, FN fncd, void *p_parblk);
+ER socket_udp_callback(ID cepid, FN fncd, void *p_parblk);
+ER socket_udp6_callback(ID cepid, FN fncd, void *p_parblk);
+
+static int tcp_fd_close(struct SHELL_FILE *fp);
+static size_t tcp_fd_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
+static size_t tcp_fd_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
+static off_t tcp_fd_seek(struct SHELL_FILE *fp, off_t ofs, int org);
+static int tcp_fd_ioctl(struct SHELL_FILE *fp, int req, void *arg);
+static bool_t tcp_fd_readable(struct SHELL_FILE *fp);
+static bool_t tcp_fd_writable(struct SHELL_FILE *fp);
+static void tcp_fd_delete(struct SHELL_FILE *fp);
+
+static int udp_fd_close(struct SHELL_FILE *fp);
+static size_t udp_fd_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
+static size_t udp_fd_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
+static off_t udp_fd_seek(struct SHELL_FILE *fp, off_t ofs, int org);
+static int udp_fd_ioctl(struct SHELL_FILE *fp, int req, void *arg);
+static bool_t udp_fd_readable(struct SHELL_FILE *fp);
+static bool_t udp_fd_writable(struct SHELL_FILE *fp);
+static void udp_fd_delete(struct SHELL_FILE *fp);
+
+IO_TYPE IO_TYPE_TCP = { tcp_fd_close, tcp_fd_read, tcp_fd_write, tcp_fd_seek, tcp_fd_ioctl, tcp_fd_readable, tcp_fd_writable, tcp_fd_delete };
+IO_TYPE IO_TYPE_UDP = { udp_fd_close, udp_fd_read, udp_fd_write, udp_fd_seek, udp_fd_ioctl, udp_fd_readable, udp_fd_writable, udp_fd_delete };
+
+typedef struct id_table_t {
+	int used;
+	ID id;
+} id_table_t;
+
+id_table_t tcp_repid_table[] = {
+	{0, USR_TCP_REP1}, {0, USR_TCP_REP2}, {0, USR_TCP_REP3}, {0, USR_TCP_REP4}
+};
+#define tcp_repid_table_count (sizeof(tcp_repid_table) / sizeof(tcp_repid_table[0]))
+
+id_table_t tcp_cepid_table[] = {
+	{0, USR_TCP_CEP1}, {0, USR_TCP_CEP2}, {0, USR_TCP_CEP3}, {0, USR_TCP_CEP4},
+#ifndef TOPPERS_GRSAKURA
+	{0, USR_TCP_CEP5}, {0, USR_TCP_CEP6}, {0, USR_TCP_CEP7}, {0, USR_TCP_CEP8}
+#endif
+};
+#define tcp_cepid_table_count (sizeof(tcp_cepid_table) / sizeof(tcp_cepid_table[0]))
+
+#ifdef SUPPORT_INET6
+
+id_table_t tcp6_repid_table[] = {
+	{0, USR_TCP6_REP1}, {0, USR_TCP6_REP2}, {0, USR_TCP6_REP3}, {0, USR_TCP6_REP4}
+};
+#define tcp6_repid_table_count (sizeof(tcp6_repid_table) / sizeof(tcp6_repid_table[0]))
+
+id_table_t tcp6_cepid_table[] = {
+	{0, USR_TCP6_CEP1}, {0, USR_TCP6_CEP2}, {0, USR_TCP6_CEP3}, {0, USR_TCP6_CEP4},
+#ifndef TOPPERS_GRSAKURA
+	{0, USR_TCP6_CEP5}, {0, USR_TCP6_CEP6}, {0, USR_TCP6_CEP7}, {0, USR_TCP6_CEP8}
+#endif
+};
+#define tcp6_cepid_table_count (sizeof(tcp6_cepid_table) / sizeof(tcp6_cepid_table[0]))
+
+#else
+
+#define tcp6_repid_table NULL
+#define tcp6_repid_table_count 0
+
+#define tcp6_cepid_table NULL
+#define tcp6_cepid_table_count 0
+
+#endif
+
+id_table_t udp_cepid_table[] = {
+	{0, USR_UDP_CEP1}, {0, USR_UDP_CEP2}, {0, USR_UDP_CEP3}, {0, USR_UDP_CEP4}
+};
+#define udp_cepid_table_count (sizeof(udp_cepid_table) / sizeof(udp_cepid_table[0]))
+
+#ifdef SUPPORT_INET6
+
+id_table_t udp6_cepid_table[] = {
+	{0, USR_UDP6_CEP1}, {0, USR_UDP6_CEP2}, {0, USR_UDP6_CEP3}, {0, USR_UDP6_CEP4}
+};
+#define udp6_cepid_table_count (sizeof(udp6_cepid_table) / sizeof(udp6_cepid_table[0]))
+
+#else
+
+#define udp6_cepid_table NULL
+#define udp6_cepid_table_count 0
+
+#endif
+
+void addrcpy(void *_dst, const void *_src, int len)
+{
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
+	memcpy(_dst, _src, len);
+#else
+	uint8_t *dst = (uint8_t *)_dst, *src = &((uint8_t *)_src)[len];
+	while (src != _src)
+		*dst++ = *--src;
+#endif
+}
+
+ID new_id(id_table_t *table, int count)
+{
+	for (int i = 0; i < count; i++) {
+		id_table_t *item = &table[i];
+		if (item->used != 0)
+			continue;
+
+		item->used = 1;
+		return item->id;
+}
+
+	return -ENOMEM;
+}
+
+int delete_id(id_table_t *table, int count, ID id)
+{
+	for (int i = 0; i < count; i++) {
+		id_table_t *item = &table[i];
+		if ((item->used == 0) || (item->id != id))
+			continue;
+
+		item->used = 0;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+typedef struct SHELL_FILE SOCKET;
+
+int shell_socket(int family, int type, int protocol)
+{
+	SOCKET *fp;
+	unsigned int flags;
+
+	switch (family) {
+	case AF_INET:
+	case AF_INET6:
+		break;
+	default:
+		return -EAFNOSUPPORT;
+	}
+
+	flags = type & (SOCK_CLOEXEC|SOCK_NONBLOCK);
+	type &= ~flags;
+
+	switch (type) {
+	case SOCK_STREAM:
+		fp = new_fp(&IO_TYPE_TCP, 0, 0);
+		if (fp == NULL)
+			return -ENOMEM;
+
+		fp->exinf = malloc(sizeof(socket_t));
+		memset(fp->exinf, 0, sizeof(socket_t));
+		break;
+	case SOCK_DGRAM:
+		fp = new_fp(&IO_TYPE_UDP, 0, 1);
+		if (fp == NULL)
+			return -ENOMEM;
+
+		fp->exinf = malloc(sizeof(socket_t));
+		memset(fp->exinf, 0, sizeof(socket_t));
+		break;
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	socket_t *socket = (socket_t *)fp->exinf;
+	socket->family = family;
+	socket->type = type;
+	socket->protocol = protocol;
+	socket->flags = flags;
+
+	return fp->fd;
+}
+
+int shell_bind(int fd, const struct sockaddr *addr, socklen_t len)
+{
+	SOCKET *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+	socket_t *socket = (socket_t *)fp->exinf;
+	if (socket->family != addr->sa_family)
+		return -EINVAL;
+
+	ER ret;
+	switch (addr->sa_family) {
+	case AF_INET: {
+		if (len < 8) {
+			return -EINVAL;
+		}
+		struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
+		memcpy(&socket->laddr4, addr, len);
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			ID cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
+			if (cepid < 0)
+				return -ENOMEM;
+
+			socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
+			socket->buf = malloc(socket->buf_size);
+#ifdef _DEBUG
+			memset(socket->buf, 0, socket->buf_size);
+#endif
+			T_TCP_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp_callback };
+			ret = tcp_cre_cep(cepid, &ccep);
+			if (ret != E_OK) {
+				delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
+				return -ENOMEM;
+			}
+			fp->handle = cepid;
+			socket->cepid = cepid;
+			break;
+		}
+		case SOCK_DGRAM: {
+			ID cepid = new_id(udp_cepid_table, udp_cepid_table_count);
+			if (cepid < 0)
+				return -ENOMEM;
+
+			T_UDP_CCEP ccep = { 0, {ntohl(addr_in->sin_addr.s_addr), ntohs(addr_in->sin_port)}, (FP)socket_udp_callback };
+			ret = udp_cre_cep(cepid, &ccep);
+			if (ret != E_OK) {
+				delete_id(udp_cepid_table, udp_cepid_table_count, cepid);
+				return -ENOMEM;
+			}
+			fp->handle = cepid;
+			socket->cepid = cepid;
+			break;
+		}
+		default:
+			return -ENOPROTOOPT;
+		}
+		break;
+	}
+	case AF_INET6: {
+		if (len < 20) {
+			return -EINVAL;
+		}
+		struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
+		memcpy(&socket->laddr6, addr, len);
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			ID cepid = new_id(tcp6_cepid_table, tcp6_cepid_table_count);
+			if (cepid < 0)
+				return -ENOMEM;
+
+			socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
+			socket->buf = malloc(socket->buf_size);
+#ifdef _DEBUG
+			memset(socket->buf, 0, socket->buf_size);
+#endif
+			T_TCP6_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp6_callback };
+			ret = tcp6_cre_cep(cepid, &ccep);
+			if (ret != E_OK) {
+				delete_id(tcp6_cepid_table, tcp6_cepid_table_count, cepid);
+				return -ENOMEM;
+			}
+			fp->handle = cepid;
+			socket->cepid = cepid;
+			break;
+		}
+		case SOCK_DGRAM: {
+			ID cepid = new_id(udp6_cepid_table, udp6_cepid_table_count);
+			if (cepid < 0)
+				return -ENOMEM;
+
+			T_UDP6_CCEP ccep = { 0, { { ntohl(addr_in6->sin6_addr.__in6_union.__s6_addr) }, ntohs(addr_in6->sin6_port)}, (FP)socket_udp6_callback };
+			ret = udp6_cre_cep(cepid, &ccep);
+			if (ret != E_OK) {
+				delete_id(udp6_cepid_table, udp6_cepid_table_count, cepid);
+				return -ENOMEM;
+			}
+			fp->handle = cepid;
+			socket->cepid = cepid;
+			break;
+		}
+		default:
+			return -ENOPROTOOPT;
+		}
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	return 0;
+}
+
+int shell_listen(int fd, int backlog)
+{
+	SOCKET *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+	socket_t *socket = (socket_t *)fp->exinf;
+	if (socket->type != SOCK_STREAM)
+		return -EINVAL;
+
+	socket->backlog = backlog;
+
+	ER ret;
+	switch (socket->family) {
+	case AF_INET: {
+		ID repid = new_id(tcp_repid_table, tcp_repid_table_count);
+		if (repid < 0)
+			return -ENOMEM;
+
+		struct sockaddr_in *laddr = &socket->laddr4;
+		T_TCP_CREP crep = { 0, {ntohl(laddr->sin_addr.s_addr), ntohs(laddr->sin_port)} };
+		ret = tcp_cre_rep(repid, &crep);
+		if (ret != E_OK) {
+			delete_id(tcp_repid_table, tcp_repid_table_count, repid);
+			return -ENOMEM;
+		}
+		socket->repid = repid;
+		break;
+	}
+	case AF_INET6: {
+		ID repid = new_id(tcp6_repid_table, tcp6_repid_table_count);
+		if (repid < 0)
+			return -ENOMEM;
+
+		struct sockaddr_in6 *laddr = &socket->laddr6;
+		T_TCP6_CREP crep = { 0, { { ntohl(laddr->sin6_addr.__in6_union.__s6_addr) }, ntohs(laddr->sin6_port)} };
+		ret = tcp6_cre_rep(repid, &crep);
+		if (ret != E_OK) {
+			delete_id(tcp6_repid_table, tcp6_repid_table_count, repid);
+			return -ENOMEM;
+		}
+		socket->repid = repid;
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	return 0;
+}
+
+int shell_connect(int fd, const struct sockaddr *addr, socklen_t alen)
+{
+	SOCKET *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+	socket_t *socket = (socket_t *)fp->exinf;
+	if (socket->type != SOCK_STREAM)
+		return -EINVAL;
+
+	ER ret;
+	switch (socket->family) {
+	case AF_INET: {
+		if (alen < sizeof(struct sockaddr_in)) {
+			return -EINVAL;
+		}
+		if (socket->cepid == 0) {
+			ID cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
+			if (cepid < 0)
+				return -ENOMEM;
+
+			socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
+			socket->buf = malloc(socket->buf_size);
+#ifdef _DEBUG
+			memset(socket->buf, 0, socket->buf_size);
+#endif
+			T_TCP_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp_callback };
+			ret = tcp_cre_cep(cepid, &ccep);
+			if (ret != E_OK) {
+				delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
+				return -ENOMEM;
+			}
+			fp->handle = cepid;
+			fp->writable = 1;
+			socket->cepid = cepid;
+		}
+		struct sockaddr_in *laddr = &socket->laddr4;
+		struct sockaddr_in *raddr = &socket->raddr4;
+		memcpy(raddr, addr, sizeof(struct sockaddr_in));
+		T_IPV4EP lep = { ntohl(laddr->sin_addr.s_addr), ntohs(laddr->sin_port) };
+		T_IPV4EP rep = { ntohl(raddr->sin_addr.s_addr), ntohs(raddr->sin_port) };
+		ret = tcp_con_cep(socket->cepid, &lep, &rep, SOCKET_TIMEOUT);
+		if (ret == E_TMOUT) {
+			return -ETIMEDOUT;
+		}
+		else if (ret < 0) {
+			return -EHOSTUNREACH;
+		}
+		break;
+	}
+	case AF_INET6: {
+		if (alen < sizeof(struct sockaddr_in6)) {
+			return -EINVAL;
+		}
+		if (socket->cepid == 0) {
+			ID cepid = new_id(tcp6_cepid_table, tcp6_cepid_table_count);
+			if (cepid < 0)
+				return -ENOMEM;
+
+			socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
+			socket->buf = malloc(socket->buf_size);
+#ifdef _DEBUG
+			memset(socket->buf, 0, socket->buf_size);
+#endif
+			T_TCP6_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp6_callback };
+			ret = tcp6_cre_cep(cepid, &ccep);
+			if (ret != E_OK) {
+				delete_id(tcp6_cepid_table, tcp6_cepid_table_count, cepid);
+				return -ENOMEM;
+			}
+			fp->handle = cepid;
+			fp->writable = 1;
+			socket->cepid = cepid;
+		}
+		struct sockaddr_in6 *laddr = &socket->laddr6;
+		struct sockaddr_in6 *raddr = &socket->raddr6;
+		memcpy(raddr, addr, sizeof(struct sockaddr_in6));
+		T_IPV6EP lep;
+		addrcpy(&lep.ipaddr, &laddr->sin6_addr, 16);
+		lep.portno = ntohs(laddr->sin6_port);
+		T_IPV6EP rep;
+		addrcpy(&rep.ipaddr, &raddr->sin6_addr, 16);
+		rep.portno = ntohs(raddr->sin6_port);
+		ret = tcp6_con_cep(socket->cepid, &lep, &rep, SOCKET_TIMEOUT);
+		if (ret == E_TMOUT) {
+			return -ETIMEDOUT;
+		}
+		else if (ret < 0) {
+			return -EHOSTUNREACH;
+		}
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	if (fp->writeevt_w != fp->writeevt_r) fp->writeevt_r++;
+
+	return 0;
+}
+
+int shell_accept(int fd, struct sockaddr *__restrict addr, socklen_t *__restrict alen)
+{
+	SOCKET *lfp = fd_to_fp(fd);
+	if (lfp == NULL)
+		return -EBADF;
+	if (((socket_t *)lfp->exinf)->type != SOCK_STREAM)
+		return -EINVAL;
+
+	SOCKET *fp = new_fp(&IO_TYPE_TCP, 0, 0);
+	if (fp == NULL)
+		return -ENOMEM;
+
+	fp->exinf = malloc(sizeof(socket_t));
+	memset(fp->exinf, 0, sizeof(socket_t));
+
+	memcpy(fp->exinf, lfp->exinf, offsetof(socket_t, buf_size));
+
+	ER ret;
+	socket_t *socket = (socket_t *)fp->exinf;
+	switch (socket->family) {
+	case AF_INET: {
+		ID cepid;
+		if (socket->cepid == 0) {
+			cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
+			if (cepid < 0)
+				return -ENOMEM;
+
+			socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
+			socket->buf = malloc(socket->buf_size);
+#ifdef _DEBUG
+			memset(socket->buf, 0, socket->buf_size);
+#endif
+			T_TCP_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp_callback };
+			ret = tcp_cre_cep(cepid, &ccep);
+			if (ret != E_OK) {
+				delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
+				return -ENOMEM;
+			}
+			fp->handle = cepid;
+			fp->writable = 1;
+			socket->cepid = cepid;
+		}
+		else {
+			cepid = ((socket_t *)lfp->exinf)->cepid;
+			fp->handle = cepid;
+			fp->writable = 1;
+			lfp->handle = tmax_tcp_cepid + ((socket_t *)lfp->exinf)->repid;
+			((socket_t *)lfp->exinf)->cepid = 0;
+			((socket_t *)lfp->exinf)->buf_size = 0;
+			((socket_t *)lfp->exinf)->buf = 0;
+		}
+		T_IPV4EP rep = { 0, 0 };
+		ret = tcp_acp_cep(socket->cepid, socket->repid, &rep, TMO_FEVR);
+		if (ret < 0) {
+			return -ENOMEM;
+		}
+		struct sockaddr_in *raddr = &socket->raddr4;
+		memset(raddr, 0, sizeof(struct sockaddr_in));
+		raddr->sin_family = AF_INET;
+		raddr->sin_port = htons(rep.portno);
+		raddr->sin_addr.s_addr = htonl(rep.ipaddr);
+
+		if (addr != NULL && alen != NULL) {
+			int sz = *alen;
+			if (sz < sizeof(struct sockaddr_in)) {
+				return -EINVAL;
+			}
+			struct sockaddr_in *raddr = &socket->raddr4;
+			if (sz > sizeof(struct sockaddr_in))
+				sz = sizeof(struct sockaddr_in);
+			memcpy(addr, raddr, sz);
+			*alen = sz;
+		}
+		break;
+	}
+	case AF_INET6: {
+		ID cepid;
+		if (socket->cepid == 0) {
+			cepid = new_id(tcp6_cepid_table, tcp6_cepid_table_count);
+			if (cepid < 0)
+				return -ENOMEM;
+
+			socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
+			socket->buf = malloc(socket->buf_size);
+#ifdef _DEBUG
+			memset(socket->buf, 0, socket->buf_size);
+#endif
+			T_TCP6_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp6_callback };
+			ret = tcp6_cre_cep(cepid, &ccep);
+			if (ret != E_OK) {
+				delete_id(tcp6_cepid_table, tcp6_cepid_table_count, cepid);
+				return -ENOMEM;
+			}
+			fp->handle = cepid;
+			fp->writable = 1;
+			socket->cepid = cepid;
+		}
+		else {
+			cepid = ((socket_t *)lfp->exinf)->cepid;
+			fp->handle = cepid;
+			fp->writable = 1;
+			lfp->handle = tmax_tcp6_cepid + ((socket_t *)lfp->exinf)->repid;
+			((socket_t *)lfp->exinf)->cepid = 0;
+			((socket_t *)lfp->exinf)->buf_size = 0;
+			((socket_t *)lfp->exinf)->buf = 0;
+		}
+		T_IPV6EP rep = { { 0 }, 0 };
+		ret = tcp6_acp_cep(socket->cepid, socket->repid, &rep, TMO_FEVR);
+		if (ret < 0) {
+			return -ENOMEM;
+		}
+		struct sockaddr_in6 *raddr = &socket->raddr6;
+		memset(raddr, 0, sizeof(struct sockaddr_in6));
+		raddr->sin6_family = AF_INET;
+		raddr->sin6_port = htons(rep.portno);
+		addrcpy(&raddr->sin6_addr, &rep.ipaddr, 16);
+
+		if (addr != NULL && alen != NULL) {
+			int sz = *alen;
+			if (sz < sizeof(struct sockaddr_in6)) {
+				return -EINVAL;
+			}
+			struct sockaddr_in6 *raddr = &socket->raddr6;
+			if (sz > sizeof(struct sockaddr_in6))
+				sz = sizeof(struct sockaddr_in6);
+			memcpy(addr, raddr, sz);
+			*alen = sz;
+		}
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	if (fp->writeevt_w != fp->writeevt_r) fp->writeevt_r++;
+
+	return fp->fd;
+}
+
+ssize_t shell_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
+{
+	SOCKET *fp = fd_to_fp(fd);
+	if (fp == NULL) {
+		return -EBADF;
+	}
+
+	int ret = 0;
+	socket_t *socket = (socket_t *)fp->exinf;
+	switch (socket->family) {
+	case AF_INET: {
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			if ((addr != NULL) || (alen != 0)) {
+				return -EISCONN;
+			}
+
+			if (flags & MSG_OOB) {
+				ret = tcp_snd_oob(socket->cepid, (void *)buf, len, SOCKET_TIMEOUT);
+				if (ret < 0) {
+					return -ECOMM;
+				}
+			}
+			else {
+				int temp = len;
+				for (;;) {
+					ret = tcp_snd_dat(socket->cepid, (void *)buf, len, SOCKET_TIMEOUT);
+					if (ret < 0) {
+						return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
+					}
+					len -= ret;
+					if (len <= 0)
+						break;
+					buf = (const void *)&((uint8_t *)buf)[ret];
+				} 
+				ret = temp;
+			}
+			break;
+		}
+		case SOCK_DGRAM: {
+			if ((addr == NULL) || (alen < sizeof(struct sockaddr_in))) {
+				return -EINVAL;
+			}
+			struct sockaddr_in *raddr = &socket->raddr4;
+			memcpy(raddr, addr, sizeof(struct sockaddr_in));
+			T_IPV4EP rep = { ntohl(raddr->sin_addr.s_addr), ntohs(raddr->sin_port) };
+			ret = udp_snd_dat(socket->cepid, &rep, (void *)buf, len,
+				(socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
+			if (ret < 0) {
+				return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	case AF_INET6: {
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			if ((addr != NULL) || (alen != 0)) {
+				return -EISCONN;
+			}
+
+			if (flags & MSG_OOB) {
+				ret = tcp6_snd_oob(socket->cepid, (void *)buf, len, SOCKET_TIMEOUT);
+				if (ret < 0) {
+					return -ECOMM;
+				}
+			}
+			else {
+				int temp = len;
+				for (;;) {
+					ret = tcp6_snd_dat(socket->cepid, (void *)buf, len, SOCKET_TIMEOUT);
+					if (ret < 0) {
+						return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
+					}
+					len -= ret;
+					if (len <= 0)
+						break;
+					buf = (const void *)&((uint8_t *)buf)[ret];
+				}
+				ret = temp;
+			}
+			break;
+		}
+		case SOCK_DGRAM: {
+			if ((addr == NULL) || (alen < sizeof(struct sockaddr_in6))) {
+				return -EINVAL;
+			}
+			struct sockaddr_in6 *raddr = &socket->raddr6;
+			memcpy(raddr, addr, sizeof(struct sockaddr_in6));
+			T_IPV6EP rep;
+			addrcpy(&rep.ipaddr, &raddr->sin6_addr, 16);
+			rep.portno = ntohs(raddr->sin6_port);
+			ret = udp6_snd_dat(socket->cepid, &rep, (void *)buf, len,
+				(socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
+			if (ret < 0) {
+				return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	if (fp->writeevt_w != fp->writeevt_r) fp->writeevt_r++;
+
+	return ret;
+}
+
+ssize_t shell_sendmsg(int fd, const struct msghdr *msg, int flags)
+{
+	no_implement("sendmsg\n");
+	return -ENOSYS;
+}
+
+ssize_t shell_recvfrom(int fd, void *__restrict buf, size_t len, int flags, struct sockaddr *__restrict addr, socklen_t *__restrict alen)
+{
+	SOCKET *fp = fd_to_fp(fd);
+	if (fp == NULL) {
+		return -EBADF;
+	}
+
+	int ret = 0;
+	socket_t *socket = (socket_t *)fp->exinf;
+	switch (socket->family) {
+	case AF_INET: {
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			if (flags & MSG_OOB) {
+				ret = tcp_rcv_oob(socket->cepid, buf, len);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "tcp_rcv_oob => %d", ret);
+					return -ECOMM;
+				}
+			}
+			else {
+				int rsz, tmp;
+				if (socket->input == NULL) {
+					ret = wai_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "wai_sem => %d", ret);
+					}
+					socket->len = 0;
+					ret = sig_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "sig_sem => %d", ret);
+					}
+					ret = tcp_rcv_buf(socket->cepid, &socket->input,
+						(socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
+					if (ret < 0) {
+						if ((socket->flags & O_NONBLOCK) == 0)
+							syslog(LOG_ERROR, "tcp_rcv_buf => %d", ret);
+						return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
+					}
+					rsz = ret;
+				}
+				else
+					rsz = socket->len;
+				tmp = rsz;
+				if (rsz > len)
+					rsz = len;
+				if (rsz >= 0) {
+					memcpy(buf, socket->input, rsz);
+					ret = wai_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "wai_sem => %d", ret);
+					}
+					socket->len = tmp - rsz;
+					ret = sig_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "sig_sem => %d", ret);
+					}
+					if (tmp - rsz == 0) {
+						socket->input = NULL;
+					}
+					else
+						socket->input = (void *)&((uint8_t *)socket->input)[rsz];
+					ret = tcp_rel_buf(socket->cepid, rsz);
+					if ((ret != E_OBJ) && (ret < 0)) {
+						syslog(LOG_ERROR, "tcp_rel_buf => %d", ret);
+						//return -ECOMM;
+					}
+				}
+				ret = rsz;
+			}
+			break;
+		}
+		case SOCK_DGRAM: {
+			struct sockaddr_in *raddr = &socket->raddr4;
+			int rsz;
+			ret = wai_sem(SEM_FILEDESC);
+			if (ret < 0) {
+				syslog(LOG_ERROR, "wai_sem => %d", ret);
+			}
+			T_NET_BUF *input = socket->input;
+			if (input == NULL) {
+				ret = sig_sem(SEM_FILEDESC);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "sig_sem => %d", ret);
+				}
+
+				T_IPV4EP rep = { 0, 0 };
+				ret = udp_rcv_dat(socket->cepid, &rep, buf, len,
+					(socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
+				if (ret < 0) {
+					if ((socket->flags & O_NONBLOCK) == 0)
+						syslog(LOG_ERROR, "udp_rcv_buf => %d", ret);
+					return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
+				}
+				rsz = ret;
+				if ((addr != NULL) && (alen != NULL)) {
+					ret = wai_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "wai_sem => %d", ret);
+					}
+					int sz = *alen;
+					memset(raddr, 0, sizeof(struct sockaddr_in));
+					raddr->sin_family = AF_INET;
+					raddr->sin_port = htons(rep.portno);
+					raddr->sin_addr.s_addr = htonl(rep.ipaddr);
+					if (sz > sizeof(struct sockaddr_in))
+						sz = sizeof(struct sockaddr_in);
+					memcpy(addr, raddr, sz);
+					*alen = sz;
+					ret = sig_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "sig_sem => %d", ret);
+					}
+				}
+			}
+			else {
+				rsz = socket->len;
+				void *pbuf = socket->buf;
+				socket->input = NULL;
+				socket->len = 0;
+				socket->buf = NULL;
+				if ((addr != NULL) && (alen != NULL)) {
+					int sz = *alen;
+					if (sz > sizeof(struct sockaddr_in))
+						sz = sizeof(struct sockaddr_in);
+					memcpy(addr, raddr, sz);
+					*alen = sz;
+				}
+				ret = sig_sem(SEM_FILEDESC);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "sig_sem => %d", ret);
+				}
+				if (rsz > len)
+					rsz = len;
+				memcpy(buf, pbuf, rsz);
+				ret = rel_net_buf(input);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "rel_net_buf => %d", ret);
+					//return -ECOMM;
+				}
+			}
+			ret = rsz;
+		}
+		}
+		break;
+	}
+	case AF_INET6: {
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			if (flags & MSG_OOB) {
+				ret = tcp6_rcv_oob(socket->cepid, buf, len);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "tcp6_rcv_oob => %d", ret);
+					return -ECOMM;
+				}
+			}
+			else {
+				int rsz, tmp;
+				if (socket->input == NULL) {
+					ret = wai_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "wai_sem => %d", ret);
+					}
+					socket->len = 0;
+					ret = sig_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "sig_sem => %d", ret);
+					}
+					ret = tcp6_rcv_buf(socket->cepid, &socket->input,
+						(socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
+					if (ret < 0) {
+						if ((socket->flags & O_NONBLOCK) == 0)
+							syslog(LOG_ERROR, "tcp6_rcv_buf => %d", ret);
+						return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
+					}
+					rsz = ret;
+				}
+				else
+					rsz = socket->len;
+				tmp = rsz;
+				if (rsz > len)
+					rsz = len;
+				if (rsz >= 0) {
+					memcpy(buf, socket->input, rsz);
+					ret = wai_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "wai_sem => %d", ret);
+					}
+					socket->len = tmp - rsz;
+					ret = sig_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "sig_sem => %d", ret);
+					}
+					if (tmp - rsz == 0) {
+						socket->input = NULL;
+					}
+					else
+						socket->input = (void *)&((uint8_t *)socket->input)[rsz];
+					ret = tcp6_rel_buf(socket->cepid, rsz);
+					if ((ret != E_OBJ) && (ret < 0)) {
+						syslog(LOG_ERROR, "tcp6_rel_buf => %d", ret);
+						//return -ECOMM;
+					}
+				}
+				ret = rsz;
+			}
+			break;
+		}
+		case SOCK_DGRAM: {
+			struct sockaddr_in6 *raddr = &socket->raddr6;
+			int rsz;
+			ret = wai_sem(SEM_FILEDESC);
+			if (ret < 0) {
+				syslog(LOG_ERROR, "wai_sem => %d", ret);
+			}
+			T_NET_BUF *input = socket->input;
+			if (input == NULL) {
+				ret = sig_sem(SEM_FILEDESC);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "sig_sem => %d", ret);
+				}
+
+				T_IPV6EP rep = { { 0 }, 0 };
+				ret = udp6_rcv_dat(socket->cepid, &rep, buf, len,
+					(socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
+				if (ret < 0) {
+					if ((socket->flags & O_NONBLOCK) == 0)
+						syslog(LOG_ERROR, "udp6_rcv_buf => %d", ret);
+					return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
+				}
+				rsz = ret;
+				if ((addr != NULL) && (alen != NULL)) {
+					ret = wai_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "wai_sem => %d", ret);
+					}
+					int sz = *alen;
+					memset(raddr, 0, sizeof(struct sockaddr_in6));
+					raddr->sin6_family = AF_INET;
+					raddr->sin6_port = htons(rep.portno);
+					addrcpy(&raddr->sin6_addr, &rep.ipaddr, 16);
+					if (sz > sizeof(struct sockaddr_in6))
+						sz = sizeof(struct sockaddr_in6);
+					memcpy(addr, raddr, sz);
+					*alen = sz;
+					ret = sig_sem(SEM_FILEDESC);
+					if (ret < 0) {
+						syslog(LOG_ERROR, "sig_sem => %d", ret);
+					}
+				}
+			}
+			else {
+				rsz = socket->len;
+				void *pbuf = socket->buf;
+				socket->input = NULL;
+				socket->len = 0;
+				socket->buf = NULL;
+				if ((addr != NULL) && (alen != NULL)) {
+					int sz = *alen;
+					if (sz > sizeof(struct sockaddr_in6))
+						sz = sizeof(struct sockaddr_in6);
+					memcpy(addr, raddr, sz);
+					*alen = sz;
+				}
+				ret = sig_sem(SEM_FILEDESC);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "sig_sem => %d", ret);
+				}
+				if (rsz > len)
+					rsz = len;
+				memcpy(buf, pbuf, rsz);
+				ret = rel_net_buf(input);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "rel_net_buf => %d", ret);
+					//return -ECOMM;
+				}
+			}
+			ret = rsz;
+		}
+		}
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	if (fp->readevt_w != fp->readevt_r) fp->readevt_r++;
+
+	return ret;
+}
+
+ssize_t shell_recvmsg(int fd, struct msghdr *msg, int flags)
+{
+	no_implement("recvmsg\n");
+	return -ENOSYS;
+}
+
+int shell_shutdown(int fd, int how)
+{
+	SOCKET *fp = fd_to_fp(fd);
+	if (fp == NULL) {
+		return -EBADF;
+	}
+
+	ER ret;
+	socket_t *socket = (socket_t *)fp->exinf;
+	switch (socket->family) {
+	case AF_INET: {
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			ret = tcp_sht_cep(socket->cepid);
+			if (ret < 0) {
+				return -ECOMM;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	case AF_INET6: {
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			ret = tcp6_sht_cep(socket->cepid);
+			if (ret < 0) {
+				return -ECOMM;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	return 0;
+}
+
+int shell_getsockopt(int fd, int level, int optname, void *optval, socklen_t *__restrict optlen)
+{
+	SOCKET *fp = fd_to_fp(fd);
+	if (fp == NULL) {
+		return -EBADF;
+	}
+
+	ER ret;
+	socket_t *socket = (socket_t *)fp->exinf;
+	switch (socket->family) {
+	case AF_INET: {
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			switch (level) {
+			case SOL_SOCKET:
+				switch (optname) {
+				case SO_REUSEADDR:
+					if (socket->flags & SO_REUSEADDR) {
+						*(bool *)optval = true;
+					}
+					else {
+						*(bool *)optval = false;
+					}
+					break;
+				case SO_KEEPALIVE:
+					if (socket->flags & SO_KEEPALIVE) {
+						*(bool *)optval = true;
+					}
+					else {
+						*(bool *)optval = false;
+					}
+					break;
+				case SO_ERROR:
+					*(int *)optval = 0;
+					break;
+				default:
+					return -EINVAL;
+				}
+				break;
+			case IPPROTO_TCP:
+				ret = tcp_get_opt(socket->cepid, optname, (void *)optval, *optlen);
+				if (ret < 0) {
+					return -EINVAL;
+				}
+				*optlen = ret;
+				break;
+			default:
+				return -EINVAL;
+			}
+			break;
+		}
+		case SOCK_DGRAM: {
+			switch (level) {
+			case IPPROTO_UDP:
+				ret = udp_get_opt(socket->cepid, optname, (void *)optval, *optlen);
+				if (ret < 0) {
+					return -EINVAL;
+				}
+				*optlen = ret;
+				break;
+			default:
+				return -EINVAL;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	case AF_INET6: {
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			switch (level) {
+			case SOL_SOCKET:
+				switch (optname) {
+				case SO_REUSEADDR:
+					if (socket->flags & SO_REUSEADDR) {
+						*(bool *)optval = true;
+					}
+					else {
+						*(bool *)optval = false;
+					}
+					break;
+				case SO_KEEPALIVE:
+					if (socket->flags & SO_KEEPALIVE) {
+						*(bool *)optval = true;
+					}
+					else {
+						*(bool *)optval = false;
+					}
+					break;
+				case SO_ERROR:
+					*(int *)optval = 0;
+					break;
+				default:
+					return -EINVAL;
+				}
+				break;
+			case IPPROTO_TCP:
+				ret = tcp6_get_opt(socket->cepid, optname, (void *)optval, *optlen);
+				if (ret < 0) {
+					return -EINVAL;
+				}
+				*optlen = ret;
+				break;
+			default:
+				return -EINVAL;
+			}
+			break;
+		}
+		case SOCK_DGRAM: {
+			switch (level) {
+			case IPPROTO_UDP:
+				ret = udp6_get_opt(socket->cepid, optname, (void *)optval, *optlen);
+				if (ret < 0) {
+					return -EINVAL;
+				}
+				*optlen = ret;
+				break;
+			default:
+				return -EINVAL;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	return 0;
+}
+
+int shell_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
+{
+	SOCKET *fp = fd_to_fp(fd);
+	if (fp == NULL) {
+		return -EBADF;
+	}
+
+	ER ret;
+	socket_t *socket = (socket_t *)fp->exinf;
+	switch (socket->family) {
+	case AF_INET: {
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			switch (level){
+			case SOL_SOCKET:
+				switch (optname) {
+				case SO_REUSEADDR:
+					if (*(bool *)optval) {
+						socket->flags |= SO_REUSEADDR;
+					}
+					else {
+						socket->flags &= ~SO_REUSEADDR;
+					}
+					break;
+				case SO_KEEPALIVE:
+					if (*(bool *)optval) {
+						socket->flags |= SO_KEEPALIVE;
+					}
+					else {
+						socket->flags &= ~SO_KEEPALIVE;
+					}
+					break;
+				default:
+					return -EINVAL;
+				}
+				break;
+			case IPPROTO_TCP:
+				ret = tcp_set_opt(socket->cepid, optname, (void *)optval, optlen);
+				if (ret < 0) {
+					return -EINVAL;
+				}
+				break;
+			default:
+				return -EINVAL;
+			}
+			break;
+		}
+		case SOCK_DGRAM: {
+			switch (level){
+			case IPPROTO_UDP:
+				ret = udp_set_opt(socket->cepid, optname, (void *)optval, optlen);
+				if (ret < 0) {
+					return -EINVAL;
+				}
+				break;
+			default:
+				return -EINVAL;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	case AF_INET6: {
+		switch (socket->type) {
+		case SOCK_STREAM: {
+			switch (level){
+			case SOL_SOCKET:
+				switch (optname) {
+				case SO_REUSEADDR:
+					if (*(bool *)optval) {
+						socket->flags |= SO_REUSEADDR;
+					}
+					else {
+						socket->flags &= ~SO_REUSEADDR;
+					}
+					break;
+				case SO_KEEPALIVE:
+					if (*(bool *)optval) {
+						socket->flags |= SO_KEEPALIVE;
+					}
+					else {
+						socket->flags &= ~SO_KEEPALIVE;
+					}
+					break;
+				default:
+					return -EINVAL;
+				}
+				break;
+			case IPPROTO_TCP:
+				ret = tcp6_set_opt(socket->cepid, optname, (void *)optval, optlen);
+				if (ret < 0) {
+					return -EINVAL;
+				}
+				break;
+			default:
+				return -EINVAL;
+			}
+			break;
+		}
+		case SOCK_DGRAM: {
+			switch (level){
+			case IPPROTO_UDP:
+				ret = udp6_set_opt(socket->cepid, optname, (void *)optval, optlen);
+				if (ret < 0) {
+					return -EINVAL;
+				}
+				break;
+			default:
+				return -EINVAL;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	return 0;
+}
+
+int shell_getpeername(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
+{
+	SOCKET *fp = fd_to_fp(fd);
+	if (fp == NULL) {
+		return -EBADF;
+	}
+	if (len == NULL) {
+		return -EINVAL;
+	}
+
+	socklen_t size = *len;
+	socket_t *socket = (socket_t *)fp->exinf;
+	switch (socket->family) {
+	case AF_INET: {
+		struct sockaddr_in *raddr = &socket->raddr4;
+		*len = sizeof(struct sockaddr_in);
+		if (size > sizeof(struct sockaddr_in))
+			size = sizeof(struct sockaddr_in);
+		memcpy(addr, raddr, size);
+		break;
+	}
+	case AF_INET6: {
+		struct sockaddr_in6 *raddr = &socket->raddr6;
+		*len = sizeof(struct sockaddr_in6);
+		if (size > sizeof(struct sockaddr_in6))
+			size = sizeof(struct sockaddr_in6);
+		memcpy(addr, raddr, size);
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	return 0;
+}
+
+int shell_getsockname(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
+{
+	SOCKET *fp = fd_to_fp(fd);
+	if (fp == NULL) {
+		return -EBADF;
+	}
+	if (len == NULL) {
+		return -EINVAL;
+	}
+
+	socklen_t size = *len;
+	socket_t *socket = (socket_t *)fp->exinf;
+	switch (socket->family) {
+	case AF_INET: {
+		const T_IN4_ADDR *laddr4 = in4_get_ifaddr(0);
+		struct sockaddr_in laddr;
+		laddr.sin_family = AF_INET;
+		laddr.sin_addr.s_addr = htonl(*laddr4);
+		laddr.sin_port = socket->laddr4.sin_port;
+		memset(&laddr.sin_zero, 0, sizeof(laddr.sin_zero));
+		*len = sizeof(struct sockaddr_in);
+		if (size > sizeof(struct sockaddr_in))
+			size = sizeof(struct sockaddr_in);
+		memcpy(addr, &laddr, size);
+		break;
+	}
+	case AF_INET6: {
+		const T_IN6_ADDR *laddr6 = in6_get_ifaddr(0);
+		struct sockaddr_in6 laddr;
+		laddr.sin6_family = AF_INET;
+		addrcpy(&laddr.sin6_addr, laddr6, 16);
+		laddr.sin6_port = socket->laddr6.sin6_port;
+		*len = sizeof(struct sockaddr_in6);
+		if (size > sizeof(struct sockaddr_in6))
+			size = sizeof(struct sockaddr_in6);
+		memcpy(addr, &laddr, size);
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	return 0;
+}
+
+int tcp_fd_close(struct SHELL_FILE *fp)
+{
+	ER ret, ret2;
+
+	socket_t *socket = (socket_t *)fp->exinf;
+	switch (socket->family) {
+	case AF_INET: {
+		if (socket->cepid != 0) {
+			ID cepid = socket->cepid;
+			ret = tcp_sht_cep(cepid);
+			if (ret < 0) {
+				//return -1;
+			}
+			ret = tcp_cls_cep(cepid, (socket->repid != 0) ? 0 : SOCKET_TIMEOUT);
+			ret2 = tcp_del_cep(cepid);
+			//delete_fd_by_id(&IO_TYPE_TCP, cepid);
+			delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
+			if ((ret < 0) || (ret2 < 0)) {
+				return (ret == E_TMOUT) ? -ETIMEDOUT : -EIO;
+			}
+		}
+		else if (socket->repid != 0) {
+			ID repid = socket->repid;
+			ret = tcp_del_rep(repid);
+			//delete_fd_by_id(&IO_TYPE_TCP, tmax_tcp_cepid + repid);
+			delete_id(tcp_repid_table, tcp_repid_table_count, repid);
+			if (ret < 0) {
+				return -EINVAL;
+			}
+		}
+		else {
+			return -EINVAL;
+		}
+		break;
+	}
+	case AF_INET6: {
+		if (socket->cepid != 0) {
+			ID cepid = socket->cepid;
+			ret = tcp6_sht_cep(cepid);
+			if (ret < 0) {
+				//return -1;
+			}
+			ret = tcp6_cls_cep(cepid, (socket->repid != 0) ? 0 : SOCKET_TIMEOUT);
+			ret2 = tcp6_del_cep(cepid);
+			//delete_fd_by_id(&IO_TYPE_TCP, cepid);
+			delete_id(tcp6_cepid_table, tcp6_cepid_table_count, cepid);
+			if ((ret < 0) || (ret2 < 0)) {
+				return (ret == E_TMOUT) ? -ETIMEDOUT : -EIO;
+			}
+		}
+		else if (socket->repid != 0) {
+			ID repid = socket->repid;
+			ret = tcp6_del_rep(repid);
+			//delete_fd_by_id(&IO_TYPE_TCP, tmax_tcp6_cepid + repid);
+			delete_id(tcp6_repid_table, tcp6_repid_table_count, repid);
+			if (ret < 0) {
+				return -EINVAL;
+			}
+		}
+		else {
+			return -EINVAL;
+		}
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	return 0;
+}
+
+size_t tcp_fd_read(struct SHELL_FILE *fp, unsigned char *dst, size_t dstsz)
+{
+	return shell_recvfrom(fp->fd, dst, dstsz, 0, NULL, NULL);
+}
+
+size_t tcp_fd_write(struct SHELL_FILE *fp, const unsigned char *src, size_t srcsz)
+{
+	return shell_sendto(fp->fd, src, srcsz, 0, NULL, 0);
+}
+
+off_t tcp_fd_seek(struct SHELL_FILE *fp, off_t ofs, int org)
+{
+	return -EPERM;
+}
+
+int tcp_fd_ioctl(struct SHELL_FILE *fp, int req, void *arg)
+{
+	socket_t *socket = (socket_t *)fp->exinf;
+
+	switch (req) {
+	case F_GETFL:
+		return socket->flags;
+	case F_SETFL:
+		socket->flags = (unsigned int)arg;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+bool_t tcp_fd_readable(struct SHELL_FILE *fp)
+{
+	ER ret;
+
+	socket_t *socket = (socket_t *)fp->exinf;
+	if (socket->cepid != 0) {
+		if (socket->len == 0) {
+			ret = tcp_rcv_buf(socket->cepid, &socket->input, TMO_NBLK);
+			if ((ret != E_WBLK) && (ret != E_OBJ) && (ret < 0)) {
+				syslog(LOG_ERROR, "tcp_rcv_buf => %d", ret);
+				//return ret;
+			}
+			if (ret > 0) {
+				ret = wai_sem(SEM_FILEDESC);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "wai_sem => %d", ret);
+				}
+				socket->len += ret;
+				ret = sig_sem(SEM_FILEDESC);
+				if (ret < 0) {
+					syslog(LOG_ERROR, "sig_sem => %d", ret);
+				}
+			}
+		}
+		else ret = 1;
+		if (ret > 0) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+bool_t tcp_fd_writable(struct SHELL_FILE *fp)
+{
+	//socket_t *socket = (socket_t *)fp->exinf;
+
+	return /*fp->writable &&*/ (fp->writeevt_w == fp->writeevt_r);
+}
+
+void tcp_fd_delete(struct SHELL_FILE *fp)
+{
+	socket_t *socket = (socket_t *)fp->exinf;
+	free(socket->buf);
+	socket->buf = NULL;
+	free(fp->exinf);
+	fp->exinf = NULL;
+}
+
+ER socket_tcp_callback(ID cepid, FN fncd, void *p_parblk)
+{
+	struct SHELL_FILE *fp = id_to_fd(&IO_TYPE_TCP, cepid);
+	FLGPTN flgptn = 0;
+	ER ret;
+	int len;
+
+	if (fp == NULL)
+		return E_PAR;
+
+	socket_t *socket = (socket_t *)fp->exinf;
+	int fd = fp->fd;
+	FD_SET(fd, (fd_set *)&flgptn);
+
+	switch (fncd) {
+	case TFN_TCP_RCV_BUF:
+		len = *(int *)p_parblk;
+		if ((len <= 0) || (fp->exinf == NULL))
+			return E_OK;
+
+		ret = wai_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "wai_sem => %d", ret);
+		}
+		socket->len += len;
+		ret = sig_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "sig_sem => %d", ret);
+		}
+
+		if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_TCP_RCV_DAT:
+		len = *(int *)p_parblk;
+		if ((len <= 0) || (fp->exinf == NULL))
+			return E_OK;
+
+		ret = wai_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "wai_sem => %d", ret);
+		}
+		socket->len += len;
+		ret = sig_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "sig_sem => %d", ret);
+		}
+
+		if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_TCP_SND_DAT:
+		if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_TCP_CAN_CEP:
+		if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_TCP_DEL_REP:
+		delete_fd_by_id(&IO_TYPE_TCP, tmax_tcp_cepid + cepid);
+		return E_OK;
+
+	case TFN_TCP_DEL_CEP:
+		delete_fd_by_id(&IO_TYPE_TCP, cepid);
+		return E_OK;
+
+	default:
+		return E_OK;
+	}
+}
+
+ER socket_tcp6_callback(ID cepid, FN fncd, void *p_parblk)
+{
+	struct SHELL_FILE *fp = id_to_fd(&IO_TYPE_TCP, cepid);
+	FLGPTN flgptn = 0;
+	ER ret;
+	int len;
+
+	if (fp == NULL)
+		return E_PAR;
+
+	socket_t *socket = (socket_t *)fp->exinf;
+	int fd = fp->fd;
+	FD_SET(fd, (fd_set *)&flgptn);
+
+	switch (fncd) {
+	case TFN_TCP_RCV_BUF:
+		len = *(int *)p_parblk;
+		if ((len <= 0) || (fp->exinf == NULL))
+			return E_OK;
+
+		ret = wai_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "wai_sem => %d", ret);
+		}
+		socket->len += len;
+		ret = sig_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "sig_sem => %d", ret);
+		}
+
+		if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_TCP_RCV_DAT:
+		len = *(int *)p_parblk;
+		if ((len <= 0) || (fp->exinf == NULL))
+			return E_OK;
+
+		ret = wai_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "wai_sem => %d", ret);
+		}
+		socket->len += len;
+		ret = sig_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "sig_sem => %d", ret);
+		}
+
+		if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_TCP_SND_DAT:
+		if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_TCP_CAN_CEP:
+		if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_TCP_DEL_REP:
+		delete_fd_by_id(&IO_TYPE_TCP, tmax_tcp_cepid + cepid);
+		return E_OK;
+
+	case TFN_TCP_DEL_CEP:
+		delete_fd_by_id(&IO_TYPE_TCP, cepid);
+		return E_OK;
+
+	default:
+		return E_OK;
+	}
+}
+
+int udp_fd_close(struct SHELL_FILE *fp)
+{
+	ER ret;
+	ID cepid;
+
+	socket_t *socket = (socket_t *)fp->exinf;
+	switch (socket->family) {
+	case AF_INET: {
+		cepid = socket->cepid;
+		ret = udp_del_cep(cepid);
+		//delete_fd_by_id(&IO_TYPE_UDP, cepid);
+		delete_id(udp_cepid_table, udp_cepid_table_count, cepid);
+		if (ret < 0) {
+			return -EINVAL;
+		}
+		break;
+	}
+	case AF_INET6: {
+		cepid = socket->cepid;
+		ret = udp6_del_cep(cepid);
+		//delete_fd_by_id(&IO_TYPE_UDP, cepid);
+		delete_id(udp6_cepid_table, udp6_cepid_table_count, cepid);
+		if (ret < 0) {
+			return -EINVAL;
+		}
+		break;
+	}
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	return 0;
+}
+
+size_t udp_fd_read(struct SHELL_FILE *fp, unsigned char *dst, size_t dstsz)
+{
+	return shell_recvfrom(fp->fd, dst, dstsz, 0, NULL, NULL);
+}
+
+size_t udp_fd_write(struct SHELL_FILE *fp, const unsigned char *src, size_t srcsz)
+{
+	return shell_sendto(fp->fd, src, srcsz, 0, NULL, 0);
+}
+
+off_t udp_fd_seek(struct SHELL_FILE *fp, off_t ofs, int org)
+{
+	return -EPERM;
+}
+
+int udp_fd_ioctl(struct SHELL_FILE *fp, int req, void *arg)
+{
+	return -EINVAL;
+}
+
+bool_t udp_fd_readable(struct SHELL_FILE *fp)
+{
+	socket_t *socket = (socket_t *)fp->exinf;
+	if (socket->cepid != 0) {
+		if (socket->input != NULL) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+bool_t udp_fd_writable(struct SHELL_FILE *fp)
+{
+	//socket_t *socket = (socket_t *)fp->exinf;
+
+	return fp->writable && (fp->writeevt_w == fp->writeevt_r);
+}
+
+void udp_fd_delete(struct SHELL_FILE *fp)
+{
+	//socket_t *socket = (socket_t *)fp->exinf;
+	//free(socket->buf);
+	//socket->buf = NULL;
+	free(fp->exinf);
+	fp->exinf = NULL;
+}
+
+ER socket_udp_callback(ID cepid, FN fncd, void *p_parblk)
+{
+	struct SHELL_FILE *fp = id_to_fd(&IO_TYPE_UDP, cepid);
+	FLGPTN flgptn = 0;
+	int len;
+
+	if (fp == NULL)
+		return E_PAR;
+
+	int fd = fp->fd;
+	FD_SET(fd, (fd_set *)&flgptn);
+
+	switch (fncd) {
+	case TEV_UDP_RCV_DAT:
+	{
+		T_UDP_RCV_DAT_PARA *udppara = (T_UDP_RCV_DAT_PARA *)p_parblk;
+		len = udppara->len;
+		if ((len <= 0) || (fp->exinf == NULL))
+			return E_OK;
+
+		ER ret = wai_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "wai_sem => %d", ret);
+		}
+		socket_t *socket = (socket_t *)fp->exinf;
+		socket->len = len;
+		if (socket->input != NULL) {
+			ret = rel_net_buf(socket->input);
+			if (ret < 0) {
+				syslog(LOG_ERROR, "rel_net_buf => %d", ret);
+			}
+		}
+		socket->input = udppara->input;
+		socket->buf = GET_UDP_SDU(udppara->input, udppara->off);
+		memset(&socket->raddr4, 0, sizeof(struct sockaddr_in));
+		socket->raddr4.sin_family = AF_INET;
+		socket->raddr4.sin_port = htons(udppara->rep4.portno);
+		socket->raddr4.sin_addr.s_addr = htonl(udppara->rep4.ipaddr);
+		udppara->input->flags |= NB_FLG_NOREL_IFOUT;
+		ret = sig_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "sig_sem => %d", ret);
+		}
+
+		if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+	}
+	case TFN_UDP_CRE_CEP:
+		return E_OK;
+
+	case TFN_UDP_RCV_DAT:
+		len = *(int *)p_parblk;
+		if ((len <= 0) || (fp->exinf == NULL))
+			return E_OK;
+
+		if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_UDP_SND_DAT:
+		if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_UDP_CAN_CEP:
+		if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_UDP_DEL_CEP:
+		delete_fd_by_id(&IO_TYPE_UDP, cepid);
+		return E_OK;
+
+	default:
+		return E_OK;
+	}
+}
+
+ER socket_udp6_callback(ID cepid, FN fncd, void *p_parblk)
+{
+	struct SHELL_FILE *fp = id_to_fd(&IO_TYPE_UDP, cepid);
+	FLGPTN flgptn = 0;
+	int len;
+
+	if (fp == NULL)
+		return E_PAR;
+
+	int fd = fp->fd;
+	FD_SET(fd, (fd_set *)&flgptn);
+
+	switch (fncd) {
+	case TEV_UDP_RCV_DAT:
+	{
+		T_UDP_RCV_DAT_PARA *udppara = (T_UDP_RCV_DAT_PARA *)p_parblk;
+		len = udppara->len;
+		if ((len <= 0) || (fp->exinf == NULL))
+			return E_OK;
+
+		ER ret = wai_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "wai_sem => %d", ret);
+		}
+		socket_t *socket = (socket_t *)fp->exinf;
+		socket->len = len;
+		if (socket->input != NULL) {
+			ret = rel_net_buf(socket->input);
+			if (ret < 0) {
+				syslog(LOG_ERROR, "rel_net_buf => %d", ret);
+			}
+		}
+		socket->input = udppara->input;
+		socket->buf = GET_UDP_SDU(udppara->input, udppara->off);
+		memset(&socket->raddr6, 0, sizeof(struct sockaddr_in6));
+		socket->raddr6.sin6_family = AF_INET;
+		socket->raddr6.sin6_port = htons(udppara->rep6.portno);
+		addrcpy(&socket->raddr6.sin6_addr, &udppara->rep6.ipaddr, 16);
+		udppara->input->flags |= NB_FLG_NOREL_IFOUT;
+		ret = sig_sem(SEM_FILEDESC);
+		if (ret < 0) {
+			syslog(LOG_ERROR, "sig_sem => %d", ret);
+		}
+
+		if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+	}
+	case TFN_UDP_CRE_CEP:
+		return E_OK;
+
+	case TFN_UDP_RCV_DAT:
+		len = *(int *)p_parblk;
+		if ((len <= 0) || (fp->exinf == NULL))
+			return E_OK;
+
+		if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_UDP_SND_DAT:
+		if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_UDP_CAN_CEP:
+		if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
+
+		set_flg(FLG_SELECT_WAIT, flgptn);
+		return E_OK;
+
+	case TFN_UDP_DEL_CEP:
+		delete_fd_by_id(&IO_TYPE_UDP, cepid);
+		return E_OK;
+
+	default:
+		return E_OK;
+	}
+}
+
+#ifndef TCP_CFG_EXTENTIONS
+ER tcp_cre_rep(ID repid, T_TCP_CREP *pk_crep)
+{
+	syslog(LOG_ERROR, "tcp_cre_rep not implement");
+	shell_abort();
+	return E_SYS;
+}
+
+ER tcp_cre_cep(ID cepid, T_TCP_CCEP *pk_ccep)
+{
+	syslog(LOG_ERROR, "tcp_cre_cep not implement");
+	shell_abort();
+	return E_SYS;
+}
+#endif
+
+#ifndef UDP_CFG_EXTENTIONS
+ER udp_cre_cep(ID cepid, T_UDP_CCEP *pk_ccep)
+{
+	syslog(LOG_ERROR, "udp_cre_cep not implement");
+	shell_abort();
+	return E_SYS;
+}
+#endif
+
+#ifndef TCP_CFG_EXTENTIONS
+ER_UINT tcp_snd_oob(ID cepid, void *data, int_t len, TMO tmout)
+{
+	syslog(LOG_ERROR, "tcp_snd_oob not implement");
+	shell_abort();
+	return E_SYS;
+}
+
+ER_UINT tcp_rcv_oob(ID cepid, void *data, int_t len)
+{
+	syslog(LOG_ERROR, "tcp_rcv_oob not implement");
+	shell_abort();
+	return E_SYS;
+}
+
+ER tcp_set_opt(ID cepid, int_t optname, void *optval, int_t optlen)
+{
+	syslog(LOG_ERROR, "tcp_set_opt not implement");
+	shell_abort();
+	return E_SYS;
+}
+
+ER tcp_get_opt(ID cepid, int_t optname, void *optval, int_t optlen)
+{
+	syslog(LOG_ERROR, "tcp_get_opt not implement");
+	shell_abort();
+	return E_SYS;
+}
+#endif
+
+#ifndef UDP_CFG_EXTENTIONS
+ER udp_get_opt(ID cepid, int_t optname, void *optval, int_t optlen)
+{
+	syslog(LOG_ERROR, "udp_get_opt not implement");
+	shell_abort();
+	return E_SYS;
+}
+
+ER udp_set_opt(ID cepid, int_t optname, void *optval, int_t optlen)
+{
+	syslog(LOG_ERROR, "udp_set_opt not implement");
+	shell_abort();
+	return E_SYS;
+}
+#endif
+
+// musl-1.1.18/network/lookup.h
+struct address {
+	int family;
+	unsigned scopeid;
+	uint8_t addr[16];
+	int sortkey;
+};
+
+#define MAXNS 3
+
+struct resolvconf {
+	struct address ns[MAXNS];
+	unsigned nns, attempts, ndots;
+	unsigned timeout;
+};
+
+// musl-1.1.18/network/resolvconf.c
+int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
+{
+	int nns = 0;
+
+	conf->ndots = 1;
+	conf->timeout = 5;
+	conf->attempts = 2;
+	if (search) *search = 0;
+
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	in4_addr;
+	conf->ns[nns].family = AF_INET;
+	conf->ns[nns].scopeid = 0;
+	dns_in4_get_addr(&in4_addr);
+	*(uint32_t *)conf->ns[nns].addr = ntohl(in4_addr);
+	nns++;
+#endif
+
+#if defined(SUPPORT_INET6)
+	conf->ns[nns].family = AF_INET6;
+	conf->ns[nns].scopeid = 0;
+	dns_in6_get_addr((T_IN6_ADDR *)conf->ns[nns].addr);
+	nns++;
+#endif
+	conf->nns = nns;
+
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/stdio_stub.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/stdio_stub.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/stdio_stub.c	(revision 398)
@@ -0,0 +1,629 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2017-2019 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+#include "shellif.h"
+#include <stdint.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <sil.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "target_syssvc.h"
+#include "target_serial.h"
+#include "fdtable.h"
+#include "kernel_cfg.h"
+#include <string.h>
+#include <errno.h>
+#include "util/ntstdio.h"
+#include "hal/serial_api.h"
+#include "target_rename.h"
+#include "target_kernel_impl.h"
+#include "syssvc/siofd.h"
+
+#ifdef _DEBUG
+static const char THIS_FILE[] = __FILE__;
+#endif
+
+static unsigned char stdio_xi(struct ntstdio_t *handle);
+static void stdio_xo(struct ntstdio_t *handle, unsigned char c);
+static void stdio_serial_irq_handler(uint32_t id, SerialIrq event);
+
+static int stdio_close(struct SHELL_FILE *fp);
+static size_t stdio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
+static size_t stdio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
+static void stdio_delete(struct SHELL_FILE *fp);
+
+static unsigned char sio_xi(struct ntstdio_t *handle);
+static void sio_xo(struct ntstdio_t *handle, unsigned char c);
+static void sio_serial_irq_handler(uint32_t id, SerialIrq event);
+
+static int sio_close(struct SHELL_FILE *fp);
+static size_t sio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
+static size_t sio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
+static off_t sio_seek(struct SHELL_FILE *fp, off_t ofs, int org);
+static int sio_ioctl(struct SHELL_FILE *fp, int req, void *arg);
+static bool_t sio_readable(struct SHELL_FILE *fp);
+static bool_t sio_writable(struct SHELL_FILE *fp);
+static void sio_delete(struct SHELL_FILE *fp);
+
+IO_TYPE IO_TYPE_STDIN = { stdio_close, sio_read, stdio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, stdio_delete };
+IO_TYPE IO_TYPE_STDOUT = { stdio_close, stdio_read, sio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, stdio_delete };
+IO_TYPE IO_TYPE_STDERR = { stdio_close, stdio_read, sio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, stdio_delete };
+IO_TYPE IO_TYPE_SIO = { sio_close, sio_read, sio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, sio_delete };
+
+#define STDIO_UART_BUF_SZ 256
+
+typedef struct stdio_sio_t {
+	serial_t serial;
+	ntstdio_t ntstdio;
+	struct SHELL_FILE *fp;
+	unsigned char tx_buf[STDIO_UART_BUF_SZ];
+	int tx_pos_w;
+	int tx_pos_r;
+	unsigned char rx_buf[STDIO_UART_BUF_SZ];
+	int rx_pos_w;
+	int rx_pos_r;
+} stdio_sio_t;
+
+stdio_sio_t stdio_sio;
+
+void sys_init(intptr_t exinf)
+{
+	serial_t *serial = &stdio_sio.serial;
+	ntstdio_t *ntstdio = &stdio_sio.ntstdio;
+
+	serial_init(serial, STDIO_UART_TX, STDIO_UART_RX);
+	serial_baud(serial, UART_BAUDRATE);
+	serial_format(serial, 8, ParityNone, 1);
+
+	ntstdio_init(ntstdio, NTSTDIO_OPTION_LINE_ECHO | NTSTDIO_OPTION_CANON | NTSTDIO_OPTION_LF_CRLF | NTSTDIO_OPTION_LF_CR, stdio_xi, stdio_xo);
+	ntstdio->exinf = (void *)&stdio_sio;
+
+	struct SHELL_FILE *fp;
+
+	fp = fd_to_fp(STDIN_FILENO);
+	fp->handle = SIO_PORTID;
+	fp->exinf = (void *)ntstdio;
+
+	fp = fd_to_fp(STDOUT_FILENO);
+	fp->handle = SIO_PORTID;
+	fp->exinf = (void *)ntstdio;
+
+	fp = fd_to_fp(STDERR_FILENO);
+	fp->handle = SIO_PORTID;
+	fp->exinf = (void *)ntstdio;
+
+	serial_irq_handler(&stdio_sio.serial, stdio_serial_irq_handler, 0);
+
+	serial_irq_set(serial, RxIrq, true);
+}
+
+ID serial_portid;
+
+void stdio_open(ID portid)
+{
+	struct SHELL_FILE *fp;
+
+	serial_portid = portid;
+	serial_ctl_por(portid, IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
+
+	fp = fd_to_fp(STDIN_FILENO);
+	fp->handle = portid;
+
+	fp = fd_to_fp(STDOUT_FILENO);
+	fp->handle = portid;
+
+	fp = fd_to_fp(STDERR_FILENO);
+	fp->handle = portid;
+}
+
+int stdio_close(struct SHELL_FILE *fp)
+{
+	return -EPERM;
+}
+
+size_t stdio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
+{
+	return -EPERM;
+}
+
+size_t stdio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
+{
+	return -EPERM;
+}
+
+void stdio_delete(struct SHELL_FILE *fp)
+{
+}
+
+int sio_close(struct SHELL_FILE *fp)
+{
+	return -EPERM;
+}
+
+size_t sio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
+{
+	int i = 0;
+	while (i < len) {
+		int c = ntstdio_getc((struct ntstdio_t *)fp->exinf);
+		data[i++] = c;
+		if ((c == EOF) || (c == '\n'))
+			break;
+	}
+	return i;
+}
+
+size_t sio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
+{
+	for (int i = 0; i < len; i++) {
+		ntstdio_putc((struct ntstdio_t *)fp->exinf, data[i]);
+	}
+	return len;
+}
+
+off_t sio_seek(struct SHELL_FILE *fp, off_t ofs, int org)
+{
+	return -EPERM;
+}
+
+int sio_tcgetattr(struct SHELL_FILE *fp, struct termios *termios)
+{
+	ntstdio_t *ntstdio = (ntstdio_t *)fp->exinf;
+
+	memset(termios, 0, sizeof(*termios));
+
+	if (ntstdio->option & NTSTDIO_OPTION_LINE_ECHO) {
+		termios->c_lflag |= ECHO;
+	}
+	else {
+		termios->c_lflag &= ~ECHO;
+	}
+	if (ntstdio->option & NTSTDIO_OPTION_CANON) {
+		termios->c_lflag |= ICANON;
+	}
+	else {
+		termios->c_lflag &= ~ICANON;
+	}
+	if (ntstdio->option & NTSTDIO_OPTION_LF_CR) {
+		termios->c_iflag |= INLCR;
+	}
+	else {
+		termios->c_iflag &= ~INLCR;
+	}
+	if (ntstdio->option & NTSTDIO_OPTION_LF_CRLF) {
+		termios->c_oflag |= ONLCR;
+	}
+	else {
+		termios->c_oflag &= ~ONLCR;
+	}
+
+	return 0;
+}
+
+int sio_tcsetattr(struct SHELL_FILE *fp, int optional_actions, const struct termios *termios)
+{
+	ntstdio_t *ntstdio = (ntstdio_t *)fp->exinf;
+
+	if (optional_actions == TCSANOW) {
+		if (termios->c_lflag & ECHO) {
+			ntstdio->option |= NTSTDIO_OPTION_LINE_ECHO;
+		}
+		else {
+			ntstdio->option &= ~NTSTDIO_OPTION_LINE_ECHO;
+		}
+		if (termios->c_lflag & ICANON) {
+			ntstdio->option |= NTSTDIO_OPTION_CANON;
+		}
+		else {
+			ntstdio->option &= ~NTSTDIO_OPTION_CANON;
+		}
+		if (termios->c_iflag & INLCR) {
+			ntstdio->option |= NTSTDIO_OPTION_LF_CR;
+		}
+		else {
+			ntstdio->option &= ~NTSTDIO_OPTION_LF_CR;
+		}
+		if (termios->c_oflag & ONLCR) {
+			ntstdio->option |= NTSTDIO_OPTION_LF_CRLF;
+		}
+		else {
+			ntstdio->option &= ~NTSTDIO_OPTION_LF_CRLF;
+		}
+		return 0;
+	}
+
+	//shell_abort();
+	return 0;
+}
+
+int sio_ioctl(struct SHELL_FILE *fp, int request, void *arg)
+{
+	if ((fp == NULL) || (fp->type != &IO_TYPE_SIO))
+		return -EBADF;
+
+	switch (request) {
+	case TIOCGWINSZ:
+		return 0;
+	case TCGETS:
+		return sio_tcgetattr(fp, (struct termios *)arg);
+	case TCSETS + TCSANOW:
+	case TCSETS + TCSADRAIN:
+	case TCSETS + TCSAFLUSH:
+		return sio_tcsetattr(fp, request - TCSETS, (const struct termios *)arg);
+	}
+
+	return -EINVAL;
+}
+
+bool_t sio_readable(struct SHELL_FILE *fp)
+{
+	return fp->readevt_w != fp->readevt_r;
+}
+
+bool_t sio_writable(struct SHELL_FILE *fp)
+{
+	return fp->writable && (fp->writeevt_w == fp->writeevt_r);
+}
+
+void sio_delete(struct SHELL_FILE *fp)
+{
+	free((stdio_sio_t *)((struct ntstdio_t *)fp->exinf)->exinf);
+	((struct ntstdio_t *)fp->exinf)->exinf = NULL;
+	free((struct ntstdio_t *)fp->exinf);
+	fp->exinf = NULL;
+}
+
+static unsigned char ntstdio_xi(struct ntstdio_t *handle, struct SHELL_FILE *fp)
+{
+	stdio_sio_t *uart = (stdio_sio_t *)handle->exinf;
+	ER ret;
+	unsigned char c;
+
+	bool_t lock = sense_lock();
+	if (lock)
+		unl_cpu();
+
+	while (uart->rx_pos_w == uart->rx_pos_r) {
+		FLGPTN flgptn = 0, waitptn = 0;
+		FD_SET(fp->fd, (fd_set *)&waitptn);
+
+		ret = wai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn);
+		if (ret != E_OK) {
+			if (lock)
+				loc_cpu();
+			syslog(LOG_ERROR, "wai_flg => %d", ret);
+			return 0;
+		}
+
+		ret = clr_flg(FLG_SELECT_WAIT, ~(flgptn & waitptn));
+		if (ret != E_OK) {
+			syslog(LOG_ERROR, "clr_flg => %d", ret);
+		}
+	}
+
+	if (lock)
+		unl_cpu();
+
+	if (fp->readevt_w != fp->readevt_r) fp->readevt_r++;
+
+	c = uart->rx_buf[uart->rx_pos_r++];
+	if (uart->rx_pos_r >= sizeof(uart->rx_buf))
+		uart->rx_pos_r = 0;
+
+	return c;
+}
+
+extern volatile int ntshell_state;
+extern ID serial_portid;
+
+static void serial_rx_irq_handler(int fd)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	stdio_sio_t *uart = (stdio_sio_t *)((struct ntstdio_t *)fp->exinf)->exinf;
+	serial_t *serial = (serial_t *)&uart->serial;
+
+	if (serial_readable(serial)) {
+		unsigned char c = (unsigned char)serial_getc(serial);
+
+		if (ntshell_state == 1) {
+			ER ret;
+			FLGPTN flgptn = 0;
+
+			uart->rx_buf[uart->rx_pos_w++] = c;
+			if (uart->rx_pos_w >= sizeof(uart->rx_buf))
+				uart->rx_pos_w = 0;
+
+			if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
+
+			FD_SET(fd, (fd_set *)&flgptn);
+
+			ret = set_flg(FLG_SELECT_WAIT, flgptn);
+			if (ret != E_OK) {
+				syslog(LOG_ERROR, "set_flg => %d", ret);
+			}
+		}
+		else
+			sio_isr_rcv(fp->handle, c);
+	}
+}
+
+static void ntstdio_xo(struct ntstdio_t *handle, struct SHELL_FILE *fp, unsigned char c)
+{
+	stdio_sio_t *uart = (stdio_sio_t *)handle->exinf;
+	serial_t *serial = (serial_t *)&uart->serial;
+	ER ret;
+
+	// タスクコンテキストでない場合
+	if (sense_context()) {
+		// 送信可能になるまで待ち
+		while (!serial_writable(serial));
+		// 送信する
+		serial_putc(serial, c);
+		return;
+	}
+
+	// 送信バッファが空で
+	if (uart->tx_pos_w == uart->tx_pos_r) {
+		// 送信可能なら
+		if (serial_writable(serial)) {
+			// 送信する
+			serial_putc(serial, c);
+			return;
+		}
+	}
+
+	// 送信バッファに追加する
+	uart->tx_buf[uart->tx_pos_w++] = c;
+	if (uart->tx_pos_w >= sizeof(uart->tx_buf))
+		uart->tx_pos_w = 0;
+
+	// 送信可能になったら割り込みをもらうよう設定
+	serial_irq_set(serial, TxIrq, true);
+
+	bool_t lock = sense_lock();
+	if (lock)
+		unl_cpu();
+
+	do {
+		FLGPTN flgptn = 0, waitptn = 0;
+		FD_SET(fp->fd, (fd_set *)&waitptn);
+
+		ret = wai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn);
+		if (ret != E_OK) {
+			syslog(LOG_ERROR, "wai_flg => %d", ret);
+			break;
+		}
+
+		ret = clr_flg(FLG_SELECT_WAIT, ~(flgptn & waitptn));
+		if (ret != E_OK) {
+			syslog(LOG_ERROR, "clr_flg => %d", ret);
+		}
+	} while (fp->writeevt_w == fp->writeevt_r);
+
+	fp->writeevt_r++;
+
+	if (lock)
+		loc_cpu();
+}
+
+static void serial_tx_irq_handler(int fd)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	stdio_sio_t *uart = (stdio_sio_t *)((struct ntstdio_t *)fp->exinf)->exinf;
+	serial_t *serial = (serial_t *)&uart->serial;
+	ER ret;
+	unsigned char c;
+
+	if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
+
+	FLGPTN flgptn = 0;
+	FD_SET(fd, (fd_set *)&flgptn);
+
+	ret = set_flg(FLG_SELECT_WAIT, flgptn);
+	if (ret != E_OK) {
+		syslog(LOG_ERROR, "set_flg => %d", ret);
+	}
+
+	// 送信バッファが空なら
+	if (uart->tx_pos_w == uart->tx_pos_r) {
+		// SIOドライバの送信
+		sio_isr_snd(fp->handle);
+		// やっぱり送信バッファが空なら
+		if (uart->tx_pos_w == uart->tx_pos_r) {
+			// 送信割り込み停止
+			serial_irq_set(serial, TxIrq, false);
+			return;
+		}
+	}
+
+	c = uart->tx_buf[uart->tx_pos_r++];
+	if (uart->tx_pos_r >= sizeof(uart->tx_buf))
+		uart->tx_pos_r = 0;
+
+	// 送信する
+	serial_putc(serial, c);
+}
+
+void stdio_serial_irq_handler(uint32_t id, SerialIrq event)
+{
+	switch (event) {
+	case RxIrq:
+		serial_rx_irq_handler(STDIN_FILENO);
+		break;
+	case TxIrq:
+		serial_tx_irq_handler(STDOUT_FILENO);
+		break;
+	}
+}
+
+void sio_serial_irq_handler(uint32_t id, SerialIrq event)
+{
+	struct SHELL_FILE *fp = fd_to_fp(id);
+	if ((fp == NULL) || (fp->type != &IO_TYPE_SIO))
+		return;
+
+	switch (event) {
+	case RxIrq:
+		serial_rx_irq_handler(id);
+		break;
+	case TxIrq:
+		serial_tx_irq_handler(id);
+		break;
+	}
+}
+
+unsigned char stdio_xi(struct ntstdio_t *handle)
+{
+	return ntstdio_xi(handle, fd_to_fp(STDIN_FILENO));
+}
+
+void stdio_xo(struct ntstdio_t *handle, unsigned char c)
+{
+	ntstdio_xo(handle, fd_to_fp(STDOUT_FILENO), c);
+}
+
+unsigned char sio_xi(struct ntstdio_t *handle)
+{
+	return ntstdio_xi(handle, ((stdio_sio_t *)handle->exinf)->fp);
+}
+
+void sio_xo(struct ntstdio_t *handle, unsigned char c)
+{
+	ntstdio_xo(handle, ((stdio_sio_t *)handle->exinf)->fp, c);
+}
+
+int siofd_open(const char *path, int flags, ...)
+{
+	return -1;
+}
+
+int siofd_close(int fd)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if ((fp == NULL) || (fp->type != &IO_TYPE_SIO)) {
+		errno = EBADF;
+		return -1;
+	}
+
+	errno = sio_close(fp);
+	if (errno != 0)
+		return 1;
+	return 0;
+}
+
+ssize_t siofd_read(int fd, void *data, size_t len)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_SIO))) {
+		errno = EBADF;
+		return -1;
+	}
+	char *pos, *end;
+
+	for (pos = (char *)data, end = &pos[len]; pos < end; pos++) {
+		*pos = ntstdio_xi((struct ntstdio_t *)fp->exinf, fp);
+	}
+
+	return pos - (char *)data;
+}
+
+ssize_t siofd_write(int fd, const void *data, size_t len)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if ((fp == NULL) || ((fp->type != &IO_TYPE_STDOUT) && (fp->type != &IO_TYPE_STDERR)
+		&& (fp->type != &IO_TYPE_SIO))) {
+		errno = EBADF;
+		return -1;
+	}
+	const char *pos, *end;
+
+	for (pos = (const char *)data, end = &pos[len]; pos < end; pos++) {
+		ntstdio_xo((struct ntstdio_t *)fp->exinf, fp, *pos);
+	}
+
+	return pos - (char *)data;
+}
+
+int siofd_tcsetattr(int fd, int act, const struct termios *tio)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_STDOUT)
+		&& (fp->type != &IO_TYPE_STDERR) && (fp->type != &IO_TYPE_SIO))) {
+		errno = EBADF;
+		return -1;
+	}
+
+	errno = sio_tcsetattr(fp, act, tio);
+	if (errno != 0)
+		return 1;
+	return 0;
+}
+
+int siofd_tcgetattr(int fd, struct termios *tio)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_STDOUT)
+		&& (fp->type != &IO_TYPE_STDERR) && (fp->type != &IO_TYPE_SIO))) {
+		errno = EBADF;
+		return -1;
+	}
+
+	errno = sio_tcgetattr(fp, tio);
+	if (errno != 0)
+		return 1;
+	return 0;
+}
+
+int siofd_fcntl(int fd, int cmd, ...)
+{
+	struct SHELL_FILE *fp = fd_to_fp(fd);
+	if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_STDOUT)
+		&& (fp->type != &IO_TYPE_STDERR) && (fp->type != &IO_TYPE_SIO))) {
+		errno = EBADF;
+		return -1;
+	}
+	void *arg;
+	va_list ap;
+	va_start(ap, cmd);
+	arg = va_arg(ap, void *);
+	va_end(ap);
+
+	errno = sio_ioctl(fp, cmd, arg);
+	if (errno != 0)
+		return 1;
+	return 0;
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/syscall.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/syscall.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/syscall.c	(revision 398)
@@ -0,0 +1,498 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ *
+ *  Copyright (C) 2018 Cores Co., Ltd. Japan
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+#include "bits/syscall.h"
+#include "shellif.h"
+#include <t_syslog.h>
+
+void *thread_area;
+void *tid_address;
+
+long no_implement(const char *text)
+{
+	syslog(LOG_ERROR, text);
+	DebugBreak();
+	return -ENOSYS;
+}
+
+long __syscall_nr(long n, ...)
+{
+	long ret = -ENOSYS;
+	va_list ap;
+
+	va_start(ap, n);
+
+	switch (n) {
+	case __NR_setresgid:
+		no_implement("setresgid");
+		break;
+	case __NR_setresuid:
+		no_implement("setresuid");
+		break;
+	case __NR_setgid:
+		no_implement("setgid");
+		break;
+	case __NR_setregid:
+		no_implement("setregid");
+		break;
+	case __NR_setreuid:
+		no_implement("setreuid");
+		break;
+	case __NR_setuid:
+		no_implement("setuid");
+		break;
+	default:
+		no_implement("syscall");
+		break;
+	}
+
+	va_end(ap);
+
+	return ret;
+}
+
+long SYS__llseek(long a, long b, long c, long d, long e) {
+	return shell_llseek((int)a, ((off_t)b << 32) | (off_t)c, (off_t *)d, (int)e);
+}
+
+long SYS__newselect(long a, long b, long c, long d, long e) {
+	return shell_select((int)a, (fd_set *)b, (fd_set *)c, (fd_set *)d, (struct timeval *)e);
+}
+
+long SYS_accept(long a, long b, long c) {
+	return shell_accept((int)a, (struct sockaddr *)b, (socklen_t *)c);
+}
+
+long SYS_access(long a, long b) {
+	return shell_access((const char *)a, (int)b);
+}
+
+long SYS_bind(long a, long b, long c) {
+	return shell_bind((int)a, (const struct sockaddr *)b, (socklen_t)c);
+}
+
+long SYS_brk(long a) {
+	return (long)shell_brk((void *)a);
+}
+
+long SYS_chdir(long a) {
+	return shell_chdir((const char *)a);
+}
+
+long SYS_chmod(long a, long b) {
+	return shell_chmod((const char *)a, (mode_t)b);
+}
+
+long SYS_chroot(long a) {
+	return shell_chroot((const char *)a);
+}
+
+long SYS_clock_getres(long a, long b) {
+	return shell_clock_getres((clockid_t)a, (struct timespec *)b);
+}
+
+long SYS_clock_gettime(long a, long b) {
+	return shell_clock_gettime((clockid_t)a, (struct timespec *)b);
+}
+
+long SYS_clock_settime(long a, long b) {
+	return shell_clock_settime((clockid_t)a, (const struct timespec *)b);
+}
+
+long SYS_close(long a) {
+	return shell_close((int)a);
+}
+
+long SYS_connect(long a, long b, long c) {
+	return shell_connect((int)a, (const struct sockaddr *)b, (socklen_t)c);
+}
+
+long SYS_exit(long a) {
+	shell_exit((int)a);
+	return 0;
+}
+
+long SYS_exit_group(long a) {
+	shell_exit_group((int)a);
+	return 0;
+}
+
+long SYS_fcntl64(long a, long b, long c) {
+	return shell_fcntl((int)a, (int)b, (void *)c);
+}
+
+long SYS_fdatasync() {
+	return no_implement("fdatasync\n");
+}
+
+long SYS_fstat64(long a, long b) {
+	return shell_fstat((int)a, (struct stat *)b);
+}
+
+long SYS_fsync(long a) {
+	return shell_fsync((int)a);
+}
+
+long SYS_ftruncate64(long a, long b, long c) {
+	return shell_ftruncate((int)a, ((off_t)b << 32) | (off_t)c);
+}
+
+long SYS_futex() {
+	int futex(int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3);
+	return no_implement("futex\n");
+}
+
+long SYS_futimesat() {
+	return no_implement("futimesat\n");
+}
+
+long SYS_getcwd(long a, long b) {
+	return (long)shell_getcwd((char *)a, (size_t)b);
+}
+
+long SYS_getdents64(long a, long b, long c) {
+	return shell_getdents((int)a, (struct dirent *)b, (size_t)c);
+}
+
+long SYS_getpeername(long a, long b, long c) {
+	return shell_getpeername((int)a, (struct sockaddr *)b, (socklen_t *)c);
+}
+
+long SYS_getsockname(long a, long b, long c) {
+	return shell_getsockname((int)a, (struct sockaddr *)b, (socklen_t *)c);
+}
+
+long SYS_getpid() {
+	return shell_getpid();
+}
+
+long SYS_getsockopt(long a, long b, long c, long d, long e) {
+	return shell_getsockopt((int)a, (int)b, (int)c, (void *)d, (socklen_t *)e);
+}
+
+long SYS_gettid() {
+	return shell_gettid();
+}
+
+long SYS_gettimeofday(long a, long b) {
+	return shell_gettimeofday((struct timeval *)a, (void *)b);
+}
+
+long SYS_getuid32() {
+	return no_implement("getuid\n");
+}
+
+long SYS_ioctl(long a, long b, long c) {
+	return shell_ioctl((int)a, (int)b, (void *)c);
+}
+
+long SYS_kill(long a, long b) {
+	return shell_kill((int)a, (int)b);
+}
+
+long SYS_link(long a, long b) {
+	return shell_link((const char *)a, (const char *)b);
+}
+
+long SYS_listen(long a, long b) {
+	return shell_listen((int)a, (int)b);
+}
+
+long SYS_lstat64(long a, long b) {
+	return shell_lstat((const char *__restrict)a, (struct stat *__restrict)b);
+}
+
+long SYS_madvise(long a, long b, long c) {
+	return shell_madvise((void *)a, (size_t)b, (int)c);
+}
+
+long SYS_mkdir(long a, long b) {
+	return shell_mkdir((const char *)a, (mode_t)b);
+}
+
+long SYS_mmap2(long a, long b, long c, long d, long e, long f, long g) {
+	return (int)shell_mmap2((void *)a, (size_t)b, (int)c, (int)d, (int)e, ((off_t)f << 32) | (off_t)g);
+}
+
+long SYS_mprotect(long a, long b, long c) {
+	return shell_mprotect((void *)a, (size_t)b, (int)c);
+}
+
+long SYS_munmap() {
+	return no_implement("munmap\n");
+}
+
+long SYS_open(long a, long b, long c) {
+	return shell_open((const char *)a, (int)b, (void *)c);
+}
+
+long SYS_poll(long a, long b, long c) {
+	return shell_poll((struct pollfd *)a, (nfds_t)b, (int)c);
+}
+
+long SYS_pread64() {
+	return no_implement("pread64\n");
+}
+
+long SYS_pwrite64() {
+	return no_implement("pwrite64\n");
+}
+
+long SYS_read(long a, long b, long c) {
+	return shell_read((int)a, (void *)b, (size_t)c);
+}
+
+long SYS_readv(long a, long b, long c) {
+	return shell_readv((int)a, (const struct iovec *)b, (int)c);
+}
+
+long SYS_recv(long a, long b, long c, long d) {
+	return shell_recvfrom((int)a, (void *)b, (size_t)c, (int)d, NULL, NULL);
+}
+
+long SYS_recvfrom(long a, long b, long c, long d, long e, long f) {
+	return shell_recvfrom(a, (void *)b, (size_t)c, (int)d, (struct sockaddr *)e, (socklen_t *)f);
+}
+
+long SYS_recvmsg(long a, long b, long c) {
+	return shell_recvmsg((int)a, (struct msghdr *)b, (size_t)c);
+}
+
+long SYS_rename(long a, long b) {
+	return shell_rename((const char *)a, (const char *)b);
+}
+
+long SYS_rmdir(long a) {
+	return shell_rmdir((const char *)a);
+}
+
+long SYS_rt_sigaction(long a, long b, long c, long d) {
+	return shell_sigaction((int)a, (const struct k_sigaction *)b, (struct k_sigaction *)c, (size_t)d);
+}
+
+long SYS_rt_sigprocmask(long a, long b, long c) {
+	return shell_sigprocmask((int)a, (const sigset_t *)b, (sigset_t *)c);
+}
+
+long SYS_rt_sigqueueinfo() {
+	return no_implement("rt_sigqueueinfo\n");
+}
+
+long SYS_send(long a, long b, long c, long d) {
+	return shell_sendto((int)a, (const void *)b, (size_t)c, (int)d, NULL, 0);
+}
+
+long SYS_sendmsg(long a, long b, long c) {
+	return shell_sendmsg((int)a, (const struct msghdr *)b, (size_t)c);
+}
+
+long SYS_sendto(long a, long b, long c, long d, long e, long f) {
+	return shell_sendto(a, (const void *)b, (size_t)c, (int)d, (const struct sockaddr *)e, (socklen_t)f);
+}
+
+long SYS_setsockopt(long a, long b, long c, long d, long e) {
+	return shell_setsockopt((int)a, (int)b, (int)c, (const void *)d, (socklen_t)e);
+}
+
+long SYS_shutdown(long a, long b) {
+	return shell_shutdown((int)a, (int)b);
+}
+
+long SYS_sched_setscheduler() {
+	return no_implement("sched_setscheduler\n");
+}
+
+long SYS_set_robust_list() {
+	return no_implement("set_robust_list\n");
+}
+
+#ifdef SYS_set_thread_area
+long SYS_set_thread_area(long a) {
+	thread_area = (void *)a;
+	return 0;
+}
+#endif
+
+long SYS_set_tid_address(long a) {
+	tid_address = (void *)a;
+	return 0;
+}
+
+long SYS_socket(long a, long b, long c) {
+	return shell_socket((int)a, (int)b, (int)c);
+}
+
+long SYS_stat64(long a, long b) {
+	return shell_stat((const char *)a, (struct stat *)b);
+}
+
+long SYS_tkill(long a, long b) {
+	return shell_tkill((int)a, (int)b);
+}
+
+long SYS_uname(long a) {
+	return shell_uname((struct utsname *)a);
+}
+
+long SYS_unlink(long a) {
+	return shell_unlink((const char *)a);
+}
+
+long SYS_utimensat() {
+	return no_implement("utimensat\n");
+}
+
+long SYS_utimes() {
+	return no_implement("utimes\n");
+}
+
+long SYS_write(long a, long b, long c) {
+	return shell_write((int)a, (const void *)b, (size_t)c);
+}
+
+long SYS_writev(long a, long b, long c) {
+	return shell_writev((int)a, (const struct iovec *)b, (size_t)c);
+}
+
+long SYS_nanosleep(long a, long b)
+{
+	return shell_nanosleep((const struct timespec *)a, (struct timespec *)b);
+}
+
+long SYS_dup()
+{
+	return no_implement("dup\n");
+}
+
+long SYS_dup2()
+{
+	return no_implement("dup2\n");
+}
+
+long SYS_pipe()
+{
+	return no_implement("pipe\n");
+}
+
+long SYS_readlink()
+{
+	return no_implement("readlink\n");
+}
+
+long SYS_symlink()
+{
+	return no_implement("symlink\n");
+}
+
+long SYS_umask()
+{
+	return no_implement("umask\n");
+}
+
+long SYS_execve()
+{
+	return no_implement("execve\n");
+}
+
+long SYS_fork()
+{
+	return no_implement("fork\n");
+}
+
+long SYS_wait4()
+{
+	return no_implement("wait4\n");
+}
+
+long SYS_socketpair()
+{
+	return no_implement("socketpair\n");
+}
+
+long SYS_flock()
+{
+	return no_implement("flock\n");
+}
+
+long SYS_fchdir()
+{
+	return no_implement("fchdir\n");
+}
+
+long SYS_getegid32()
+{
+	return no_implement("getegid32\n");
+}
+
+long SYS_geteuid32()
+{
+	return no_implement("geteuid32\n");
+}
+
+long SYS_getgid32()
+{
+	return no_implement("getgid32\n");
+}
+
+long SYS_pipe2()
+{
+	return no_implement("pipe2\n");
+}
+
+long SYS_setgid32()
+{
+	return no_implement("setgid32\n");
+}
+
+long SYS_setpgid()
+{
+	return no_implement("setpgid\n");
+}
+
+long SYS_setsid()
+{
+	return no_implement("setsid\n");
+}
+
+long SYS_setuid32()
+{
+	return no_implement("setuid32\n");
+}
+
+long SYS_tgkill()
+{
+	return no_implement("tgkill\n");
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/tSIOPortNTShell.cdl
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/tSIOPortNTShell.cdl	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/tSIOPortNTShell.cdl	(revision 398)
@@ -0,0 +1,119 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2015 by Ushio Laboratory
+ *              Graduate School of Engineering Science, Osaka Univ., JAPAN
+ *  Copyright (C) 2015,2016 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$
+ */
+
+/*
+ *		シリアルインタフェースドライバのターゲット依存部（NTShell用）
+ *		のコンポーネント記述
+ */
+
+/*
+ *  NTShell に関する定義
+ */
+import_C("termios.h");
+
+/*
+ *  SIOドライバの本体のセルタイプ
+ */
+celltype tSIOPortNTShellMain {
+	/*
+	 *  シリアルインタフェースドライバとの結合
+	 */
+	entry				sSIOPort		eSIOPort;
+	[optional] call		siSIOCBR		ciSIOCBR;
+
+	/*
+	 *  終了処理ルーチン
+	 */
+	entry	sRoutineBody	eTerminate;
+
+	attr {
+		const char	*path;				/* パス名 */
+	};
+
+	var {
+		bool_t			opened = false;	/* オープン済みフラグ */
+		struct termios	saved_term;		/* 元の端末制御情報 */
+		int_t			read_fd;		/* 読出し用ファイルディスクリプタ */
+		bool_t			rcv_flag;		/* 受信文字バッファ有効フラグ */
+		char			rcv_buf;		/* 受信文字バッファ */
+		bool_t			rcv_rdy;		/* 受信通知コールバック許可フラグ */
+		int_t			write_fd;		/* 書込み用ファイルディスクリプタ */
+		bool_t			snd_flag;		/* 送信文字バッファ有効フラグ */
+		char			snd_buf;		/* 送信文字バッファ */
+		bool_t			snd_rdy;		/* 送信通知コールバック許可フラグ */
+	};
+};
+
+/*
+ *  SIOドライバ（複合コンポーネント）のセルタイプ
+ */
+[active]
+composite tSIOPortNTShell {
+	/*
+	 *  シリアルインタフェースドライバとの結合
+	 */
+	entry				sSIOPort	eSIOPort;
+	[optional] call		siSIOCBR	ciSIOCBR;
+
+	/*
+	 *  属性の定義
+	 */
+	attr {
+		const char	*path = C_EXP("NULL");		/* パス名 */
+	};
+
+	/*
+	 *  SIOドライバの本体
+	 */
+	cell tSIOPortNTShellMain SIOPortMain {
+		path     = composite.path;
+		ciSIOCBR => composite.ciSIOCBR;
+	};
+	composite.eSIOPort => SIOPortMain.eSIOPort;
+
+	/*
+	 *  SIOドライバの終了処理ルーチン
+	 */
+	cell tTerminateRoutine TerminateSIO {
+		cTerminateRoutineBody = SIOPortMain.eTerminate;
+	};
+};
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/tSIOPortNTShellMain.c
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/tSIOPortNTShellMain.c	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/tSIOPortNTShellMain.c	(revision 398)
@@ -0,0 +1,255 @@
+/*
+ *  TOPPERS/ASP Kernel
+ *      Toyohashi Open Platform for Embedded Real-Time Systems/
+ *      Advanced Standard Profile Kernel
+ * 
+ *  Copyright (C) 2006-2018 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$
+ */
+
+/*
+ *		シリアルインタフェースドライバのターゲット依存部（NTShell用）
+ */
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <errno.h> 
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "tSIOPortNTShellMain_tecsgen.h"
+#include "syssvc/siofd.h"
+ 
+/*
+ *  SIOポートのオープン
+ */
+void
+eSIOPort_open(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	int_t	fd;
+	struct	termios term;
+
+	if (!VAR_opened) {
+		/*
+		 *  既にオープンしている場合は、二重にオープンしない．
+		 */
+		if (ATTR_path != NULL) {
+			fd = siofd_open(ATTR_path, O_RDWR, 0777);
+			assert(fd >= 0);
+			VAR_read_fd = fd;
+			VAR_write_fd = fd;
+		}
+		else {
+			fd = STDIN_FILENO;				/* 標準入出力を使う */
+			VAR_read_fd = STDIN_FILENO;
+			VAR_write_fd = STDOUT_FILENO;
+		}
+		siofd_fcntl(fd, F_SETOWN, getpid());
+		siofd_fcntl(fd, F_SETFL, (O_NONBLOCK | O_ASYNC));
+
+		siofd_tcgetattr(fd, &VAR_saved_term);
+		term = VAR_saved_term;
+		term.c_lflag &= ~(ECHO | ICANON);
+		siofd_tcsetattr(fd, TCSAFLUSH, &term);
+
+		VAR_rcv_flag = false;
+		VAR_rcv_rdy = false;
+		VAR_snd_flag = false;
+		VAR_snd_rdy = false;
+		VAR_opened = true;
+	}
+}
+
+/*
+ *  SIOポートのクローズ
+ */
+void
+eSIOPort_close(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	int_t	fd;
+
+	if (VAR_opened) {
+		fd = VAR_read_fd;
+		siofd_tcsetattr(fd, TCSAFLUSH, &VAR_saved_term);
+		siofd_fcntl(fd, F_SETFL, 0);
+
+		if (ATTR_path != NULL) {
+			siofd_close(VAR_read_fd);
+		}
+		VAR_opened = false;
+	}
+}
+
+/*
+ *  SIOポートへの文字送信
+ */
+bool_t
+eSIOPort_putChar(CELLIDX idx, char c)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	int_t	n;
+
+	if (!VAR_snd_flag) {
+		if ((n = siofd_write(VAR_write_fd, &c, 1)) > 0) {
+			return(true);
+		}
+		else {
+			assert(n < 0 && errno == EAGAIN);
+			VAR_snd_flag = true;
+			VAR_snd_buf = c;
+			return(true);
+		}
+	}
+	else {
+		return(false);
+	}
+}
+
+/*
+ *  SIOポートからの文字受信
+ */
+int_t
+eSIOPort_getChar(CELLIDX idx)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	char	c;
+	int_t	n;
+
+	if (VAR_rcv_flag) {
+		VAR_rcv_flag = false;
+		return((int_t)(uint8_t)(VAR_rcv_buf));
+	}
+	else if ((n = siofd_read(VAR_read_fd, &c, 1)) > 0) {
+		return((int_t)(uint8_t) c);
+	}
+	else {
+		assert(n < 0 && errno == EAGAIN);
+		return(-1);
+	}
+}
+
+/*
+ *  SIOポートからのコールバックの許可
+ */
+void
+eSIOPort_enableCBR(CELLIDX idx, uint_t cbrtn)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	switch (cbrtn) {
+	case SIOSendReady:
+		VAR_snd_rdy = true;
+		break;
+	case SIOReceiveReady:
+		VAR_rcv_rdy = true;
+		break;
+	}
+}
+
+/*
+ *  SIOポートからのコールバックの禁止
+ */
+void
+eSIOPort_disableCBR(CELLIDX idx, uint_t cbrtn)
+{
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	switch (cbrtn) {
+	case SIOSendReady:
+		VAR_snd_rdy = false;
+		break;
+	case SIOReceiveReady:
+		VAR_rcv_rdy = false;
+		break;
+	}
+}
+
+/*
+ *  SIOの割込みサービスルーチン
+ */
+bool_t
+sio_isr_snd(ID siopid)
+{
+	if (!(1 <= siopid && siopid <= tSIOPortNTShellMain_N_CELL))
+		return false;
+	CELLIDX idx = &tSIOPortNTShellMain_CB_tab[siopid - 1];
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+	int_t	n;
+
+	if (VAR_snd_flag) {
+		if ((n = siofd_write(VAR_write_fd, &(VAR_snd_buf), 1)) > 0) {
+			VAR_snd_flag = false;
+			if (VAR_snd_rdy) {
+				ciSIOCBR_readySend();
+				return VAR_snd_rdy;
+			}
+		}
+	}
+
+	return false;
+}
+
+/*
+ *  SIOの割込みサービスルーチン
+ */
+bool_t
+sio_isr_rcv(ID siopid, char c)
+{
+	if (!(1 <= siopid && siopid <= tSIOPortNTShellMain_N_CELL))
+		return false;
+	CELLIDX idx = &tSIOPortNTShellMain_CB_tab[siopid - 1];
+	CELLCB	*p_cellcb = GET_CELLCB(idx);
+
+	if (!VAR_rcv_flag) {
+		VAR_rcv_buf = c;
+		VAR_rcv_flag = true;
+		if (VAR_rcv_rdy) {
+			ciSIOCBR_readyReceive();
+			return VAR_rcv_rdy;
+		}
+	}
+
+	return false;
+}
+
+/*
+ *  SIOドライバの終了処理
+ */
+void
+eTerminate_main(CELLIDX idx)
+{
+	eSIOPort_close(idx);
+}
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/tinet_main.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/tinet_main.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/tinet_main.cfg	(revision 398)
@@ -0,0 +1,95 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ * 
+ *  Copyright (C) 2014 Cores Co., Ltd. Japan
+ * 
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ * 
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ネットワーク対応 main.c プログラムの TCP/IP コンフィギュレーションファイル
+ */
+
+#include "main.h"
+
+/* Socket用 通信端点 */
+
+#ifdef SUPPORT_INET4
+
+VRID_TCP_REP (USR_TCP_REP1);
+VRID_TCP_REP (USR_TCP_REP2);
+VRID_TCP_REP (USR_TCP_REP3);
+VRID_TCP_REP (USR_TCP_REP4);
+
+VRID_TCP_CEP (USR_TCP_CEP1);
+VRID_TCP_CEP (USR_TCP_CEP2);
+VRID_TCP_CEP (USR_TCP_CEP3);
+VRID_TCP_CEP (USR_TCP_CEP4);
+#ifndef TOPPERS_GRSAKURA
+VRID_TCP_CEP (USR_TCP_CEP5);
+VRID_TCP_CEP (USR_TCP_CEP6);
+VRID_TCP_CEP (USR_TCP_CEP7);
+VRID_TCP_CEP (USR_TCP_CEP8);
+#endif
+
+VRID_UDP_CEP (USR_UDP_CEP1);
+VRID_UDP_CEP (USR_UDP_CEP2);
+VRID_UDP_CEP (USR_UDP_CEP3);
+VRID_UDP_CEP (USR_UDP_CEP4);
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#ifdef SUPPORT_INET6
+
+VRID_TCP6_REP (USR_TCP6_REP1);
+VRID_TCP6_REP (USR_TCP6_REP2);
+VRID_TCP6_REP (USR_TCP6_REP3);
+VRID_TCP6_REP (USR_TCP6_REP4);
+
+VRID_TCP6_CEP (USR_TCP6_CEP1);
+VRID_TCP6_CEP (USR_TCP6_CEP2);
+VRID_TCP6_CEP (USR_TCP6_CEP3);
+VRID_TCP6_CEP (USR_TCP6_CEP4);
+#ifndef TOPPERS_GRSAKURA
+VRID_TCP6_CEP (USR_TCP6_CEP5);
+VRID_TCP6_CEP (USR_TCP6_CEP6);
+VRID_TCP6_CEP (USR_TCP6_CEP7);
+VRID_TCP6_CEP (USR_TCP6_CEP8);
+#endif
+
+VRID_UDP6_CEP (USR_UDP6_CEP1);
+VRID_UDP6_CEP (USR_UDP6_CEP2);
+VRID_UDP6_CEP (USR_UDP6_CEP3);
+VRID_UDP6_CEP (USR_UDP6_CEP4);
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
Index: /azure_iot_hub_mbedtls/trunk/ntshell/src/tinet_ntp_cli.cfg
===================================================================
--- /azure_iot_hub_mbedtls/trunk/ntshell/src/tinet_ntp_cli.cfg	(revision 398)
+++ /azure_iot_hub_mbedtls/trunk/ntshell/src/tinet_ntp_cli.cfg	(revision 398)
@@ -0,0 +1,45 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
+ *  によって公表されている GNU General Public License の Version 2 に記
+ *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
+ *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
+ *  利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次の条件を満たすこと．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
+ *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
+ *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  NTP クライアント
+ *  TCP/IP コンフィギュレーションファイル
+ */
+
+/* UDP 通信端点 */
+
+UDP_CRE_CEP (NTP_CLI_CEPID, {
+	0,
+	{ IPV4_ADDRANY, UDP_PORTANY },
+	callback_nblk_ntp_cli
+	} );
